From b52ff57056d62db2aa710faae9e687a1c711c8f3 Mon Sep 17 00:00:00 2001 From: Fathi Boudra Date: Mon, 13 Jan 2020 17:14:38 +0200 Subject: Add a .gitreview file for convenience Signed-off-by: Fathi Boudra Change-Id: I2683da5071466ba3c81f0bd6f3bf51163971feab --- .gitreview | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .gitreview diff --git a/.gitreview b/.gitreview new file mode 100644 index 000000000..36f25485b --- /dev/null +++ b/.gitreview @@ -0,0 +1,4 @@ +[gerrit] +host=review.trustedfirmware.org +port=29418 +project=TF-A/trusted-firmware-a -- cgit v1.2.3 From c367b75e8517f76182e196548ee098e27ef3a2c5 Mon Sep 17 00:00:00 2001 From: Madhukar Pappireddy Date: Mon, 27 Jan 2020 15:32:15 -0600 Subject: Changes necessary to support SEPARATE_NOBITS_REGION feature Since BL31 PROGBITS and BL31 NOBITS sections are going to be in non-adjacent memory regions, potentially far from each other, some fixes are needed to support it completely. 1. adr instruction only allows computing the effective address of a location only within 1MB range of the PC. However, adrp instruction together with an add permits position independent address of any location with 4GB range of PC. 2. Since BL31 _RW_END_ marks the end of BL31 image, care must be taken that it is aligned to page size since we map this memory region in BL31 using xlat_v2 lib utils which mandate alignment of image size to page granularity. Change-Id: I3451cc030d03cb2032db3cc088f0c0e2c84bffda Signed-off-by: Madhukar Pappireddy --- bl31/aarch64/bl31_entrypoint.S | 14 +++++++++----- bl31/aarch64/runtime_exceptions.S | 5 +++-- bl31/bl31.ld.S | 3 ++- lib/el3_runtime/aarch64/cpu_data.S | 5 +++-- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/bl31/aarch64/bl31_entrypoint.S b/bl31/aarch64/bl31_entrypoint.S index 665a05e88..2d672dd12 100644 --- a/bl31/aarch64/bl31_entrypoint.S +++ b/bl31/aarch64/bl31_entrypoint.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -110,13 +110,17 @@ func bl31_entrypoint * caches and participate in coherency. * -------------------------------------------------------------------- */ - adr x0, __DATA_START__ - adr x1, __DATA_END__ + adrp x0, __DATA_START__ + add x0, x0, :lo12:__DATA_START__ + adrp x1, __DATA_END__ + add x1, x1, :lo12:__DATA_END__ sub x1, x1, x0 bl clean_dcache_range - adr x0, __BSS_START__ - adr x1, __BSS_END__ + 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 clean_dcache_range diff --git a/bl31/aarch64/runtime_exceptions.S b/bl31/aarch64/runtime_exceptions.S index 7f739a9aa..5b3738868 100644 --- a/bl31/aarch64/runtime_exceptions.S +++ b/bl31/aarch64/runtime_exceptions.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -414,7 +414,8 @@ smc_handler64: orr x16, x16, x15, lsl #FUNCID_OEN_WIDTH /* Load descriptor index from array of indices */ - adr x14, rt_svc_descs_indices + adrp x14, rt_svc_descs_indices + add x14, x14, :lo12:rt_svc_descs_indices ldrb w15, [x14, x16] /* Any index greater than 127 is invalid. Check bit 7. */ diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S index 42227f0f3..86fe23608 100644 --- a/bl31/bl31.ld.S +++ b/bl31/bl31.ld.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -208,6 +208,7 @@ SECTIONS * Define a linker symbol to mark end of the RW memory area for this * image. */ + . = ALIGN(PAGE_SIZE); __RW_END__ = .; __BL31_END__ = .; diff --git a/lib/el3_runtime/aarch64/cpu_data.S b/lib/el3_runtime/aarch64/cpu_data.S index 2edf22559..2392d6b90 100644 --- a/lib/el3_runtime/aarch64/cpu_data.S +++ b/lib/el3_runtime/aarch64/cpu_data.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -41,7 +41,8 @@ endfunc init_cpu_data_ptr func _cpu_data_by_index mov_imm x1, CPU_DATA_SIZE mul x0, x0, x1 - adr x1, percpu_data + adrp x1, percpu_data + add x1, x1, :lo12:percpu_data add x0, x0, x1 ret endfunc _cpu_data_by_index -- cgit v1.2.3 From 0c1f197aa12ba19046671c4741be03aa54a90866 Mon Sep 17 00:00:00 2001 From: Madhukar Pappireddy Date: Mon, 27 Jan 2020 15:38:26 -0600 Subject: plat/arm: Add support for SEPARATE_NOBITS_REGION In order to support SEPARATE_NOBITS_REGION for Arm platforms, we need to load BL31 PROGBITS into secure DRAM space and BL31 NOBITS into SRAM. Hence mandate the build to require that ARM_BL31_IN_DRAM is enabled as well. Naturally with SEPARATE_NOBITS_REGION enabled, the BL31 initialization code cannot be reclaimed to be used for runtime data such as secondary cpu stacks. Memory map for BL31 NOBITS region also has to be created. Change-Id: Ibbc8c9499a32e63fd0957a6e254608fbf6fa90c9 Signed-off-by: Madhukar Pappireddy --- include/plat/arm/common/arm_def.h | 12 ++++++++++-- plat/arm/common/arm_bl31_setup.c | 13 ++++++++++++- plat/arm/common/arm_common.mk | 19 ++++++++++++++++++- 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index b419c853e..5bd53f3b5 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -395,13 +395,21 @@ /******************************************************************************* * BL31 specific defines. ******************************************************************************/ -#if ARM_BL31_IN_DRAM +#if ARM_BL31_IN_DRAM || SEPARATE_NOBITS_REGION /* * Put BL31 at the bottom of TZC secured DRAM */ #define BL31_BASE ARM_AP_TZC_DRAM1_BASE #define BL31_LIMIT (ARM_AP_TZC_DRAM1_BASE + \ PLAT_ARM_MAX_BL31_SIZE) +/* + * For SEPARATE_NOBITS_REGION, BL31 PROGBITS are loaded in TZC secured DRAM. + * And BL31 NOBITS are loaded in Trusted SRAM such that BL2 is overwritten. + */ +#if SEPARATE_NOBITS_REGION +#define BL31_NOBITS_BASE BL2_BASE +#define BL31_NOBITS_LIMIT BL2_LIMIT +#endif /* SEPARATE_NOBITS_REGION */ #elif (RESET_TO_BL31) /* Ensure Position Independent support (PIE) is enabled for this config.*/ # if !ENABLE_PIE diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c index 939885f98..7a3ca7177 100644 --- a/plat/arm/common/arm_bl31_setup.c +++ b/plat/arm/common/arm_bl31_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -56,6 +56,14 @@ IMPORT_SYM(unsigned long, __INIT_CODE_END__, BL_INIT_CODE_END); MT_CODE | MT_SECURE) #endif +#if SEPARATE_NOBITS_REGION +#define MAP_BL31_NOBITS MAP_REGION_FLAT( \ + BL31_NOBITS_BASE, \ + BL31_NOBITS_LIMIT \ + - BL31_NOBITS_BASE, \ + MT_MEMORY | MT_RW | MT_SECURE) + +#endif /******************************************************************************* * Return a pointer to the 'entry_point_info' structure of the next image for the * security state specified. BL33 corresponds to the non-secure image type @@ -294,6 +302,9 @@ void __init arm_bl31_plat_arch_setup(void) MAP_BL31_TOTAL, #if RECLAIM_INIT_CODE MAP_BL_INIT_CODE, +#endif +#if SEPARATE_NOBITS_REGION + MAP_BL31_NOBITS, #endif ARM_MAP_BL_RO, #if USE_ROMLIB diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index 9d4f05e9e..ab33e1ded 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -125,6 +125,23 @@ ENABLE_PMF := 1 # mapping the former as executable and the latter as execute-never. SEPARATE_CODE_AND_RODATA := 1 +# On ARM platforms, disable SEPARATE_NOBITS_REGION by default. Both PROGBITS +# and NOBITS sections of BL31 image are adjacent to each other and loaded +# into Trusted SRAM. +SEPARATE_NOBITS_REGION := 0 + +# In order to support SEPARATE_NOBITS_REGION for Arm platforms, we need to load +# BL31 PROGBITS into secure DRAM space and BL31 NOBITS into SRAM. Hence mandate +# the build to require that ARM_BL31_IN_DRAM is enabled as well. +ifeq ($(SEPARATE_NOBITS_REGION),1) + ifneq ($(ARM_BL31_IN_DRAM),1) + $(error For SEPARATE_NOBITS_REGION, ARM_BL31_IN_DRAM must be enabled) + endif + ifneq ($(RECLAIM_INIT_CODE),0) + $(error For SEPARATE_NOBITS_REGION, RECLAIM_INIT_CODE cannot be supported) + endif +endif + # Disable ARM Cryptocell by default ARM_CRYPTOCELL_INTEG := 0 $(eval $(call assert_boolean,ARM_CRYPTOCELL_INTEG)) -- cgit v1.2.3 From 2a1e0866776160045b2ccf13b5aef8e92fc9a145 Mon Sep 17 00:00:00 2001 From: Hadi Asyrafi Date: Tue, 14 Jan 2020 10:51:31 +0800 Subject: intel: agilex: Enable uboot BL31 loading This patch enables uboot's spl entrypoint to BL31 and also handles secondary cpus state during cold boot. Signed-off-by: Hadi Asyrafi Change-Id: Ib70ec91a3ad09a568cb66e7c1e23a2b3e460746c --- plat/intel/soc/agilex/bl31_plat_setup.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/plat/intel/soc/agilex/bl31_plat_setup.c b/plat/intel/soc/agilex/bl31_plat_setup.c index 375483dd4..13099b40f 100644 --- a/plat/intel/soc/agilex/bl31_plat_setup.c +++ b/plat/intel/soc/agilex/bl31_plat_setup.c @@ -11,8 +11,10 @@ #include #include #include +#include #include +#include "socfpga_private.h" static entry_point_info_t bl32_image_ep_info; static entry_point_info_t bl33_image_ep_info; @@ -44,23 +46,33 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, void *from_bl2 = (void *) arg0; bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2; - assert(params_from_bl2 != NULL); - assert(params_from_bl2->h.type == PARAM_BL_PARAMS); - assert(params_from_bl2->h.version >= VERSION_2); /* * Copy BL32 (if populated by BL31) and BL33 entry point information. * They are stored in Secure RAM, in BL31's address space. */ - bl_params_node_t *bl_params = params_from_bl2->head; + if (params_from_bl2->h.type == PARAM_BL_PARAMS && + params_from_bl2->h.version >= VERSION_2) { + + bl_params_node_t *bl_params = params_from_bl2->head; + + while (bl_params) { + if (bl_params->image_id == BL33_IMAGE_ID) + bl33_image_ep_info = *bl_params->ep_info; - while (bl_params) { - if (bl_params->image_id == BL33_IMAGE_ID) - bl33_image_ep_info = *bl_params->ep_info; + bl_params = bl_params->next_params_info; + } + } else { + struct socfpga_bl31_params *arg_from_bl2 = + (struct socfpga_bl31_params *) from_bl2; - bl_params = bl_params->next_params_info; + assert(arg_from_bl2->h.type == PARAM_BL31); + assert(arg_from_bl2->h.version >= VERSION_1); + + bl32_image_ep_info = *arg_from_bl2->bl32_ep_info; + bl33_image_ep_info = *arg_from_bl2->bl33_ep_info; } SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); } @@ -91,6 +103,10 @@ void bl31_platform_setup(void) gicv2_distif_init(); gicv2_pcpu_distif_init(); gicv2_cpuif_enable(); + + /* Signal secondary CPUs to jump to BL31 (BL2 = U-boot SPL) */ + mmio_write_64(PLAT_CPU_RELEASE_ADDR, + (uint64_t)plat_secondary_cpus_bl31_entry); } const mmap_region_t plat_agilex_mmap[] = { -- cgit v1.2.3 From 70d0d759ad0ada27178dfbc6ba7dd5a5cd1fef26 Mon Sep 17 00:00:00 2001 From: Tejas Patel Date: Wed, 29 Jan 2020 22:06:12 -0800 Subject: plat: xilinx: zynqmp: Use ARRAY_SIZE wherever possible To find result count use ARRAY_SIZE for better readability. Signed-off-by: Tejas Patel Signed-off-by: Jolly Shah Change-Id: I97201de4d43024e59fa78bd61937c86d47724ab5 --- plat/xilinx/zynqmp/pm_service/pm_svc_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c index 98dbe7d6e..3f4f0691e 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c +++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c @@ -423,7 +423,7 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, { uint32_t result[4] = {0}; - pm_get_callbackdata(result, (sizeof(result)/sizeof(uint32_t))); + pm_get_callbackdata(result, ARRAY_SIZE(result)); SMC_RET2(handle, (uint64_t)result[0] | ((uint64_t)result[1] << 32), (uint64_t)result[2] | ((uint64_t)result[3] << 32)); -- cgit v1.2.3 From 932f8b477b16cbaa712c3aefbd2e75a26750df86 Mon Sep 17 00:00:00 2001 From: Tejas Patel Date: Wed, 29 Jan 2020 22:09:55 -0800 Subject: xilinx: versal: Pass result count to pm_get_callbackdata() pm_get_callbackdata() expect result count and not total bytes of result. Correct it by passing result count to pm_get_callbackdata(). Signed-off-by: Tejas Patel Signed-off-by: Jolly Shah Change-Id: I01ce0002f7a753e81ea9fe65edde8420a13ed51a --- plat/xilinx/versal/pm_service/pm_svc_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plat/xilinx/versal/pm_service/pm_svc_main.c b/plat/xilinx/versal/pm_service/pm_svc_main.c index a3a9f4316..45b280370 100644 --- a/plat/xilinx/versal/pm_service/pm_svc_main.c +++ b/plat/xilinx/versal/pm_service/pm_svc_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Xilinx, Inc. All rights reserved. + * Copyright (c) 2019-2020, Xilinx, Inc. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -165,7 +165,7 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, { uint32_t result[4] = {0}; - pm_get_callbackdata(result, sizeof(result)); + pm_get_callbackdata(result, ARRAY_SIZE(result)); SMC_RET2(handle, (uint64_t)result[0] | ((uint64_t)result[1] << 32), (uint64_t)result[2] | ((uint64_t)result[3] << 32)); -- cgit v1.2.3 From 81646055138ed431ca155382ccf7c286f4d52e7f Mon Sep 17 00:00:00 2001 From: Grzegorz Jaszczyk Date: Fri, 18 Aug 2017 16:42:12 +0200 Subject: plat: marvell: armada: add support for loading MG CM3 images In order to access MG SRAM, the amb bridge needs to be configured which is done in bl2 platform init. For MG CM3, the image is only loaded to its SRAM and the CM3 itself is left in reset. It is because the next stage bootloader (e.g. u-boot) will trigger action which will take it out of reset when needed. This can happen e.g. when appropriate device-tree setup (which has enabled 802.3 auto-neg) will be chosen. In other cases the MG CM3 should not be running. Change-Id: I816ea14e3a7174eace068ec44e3cc09998d0337e Signed-off-by: Grzegorz Jaszczyk --- drivers/marvell/mochi/cp110_setup.c | 6 ++--- include/drivers/marvell/mochi/cp110_setup.h | 1 + plat/marvell/a8k/common/mss/mss_a8k.mk | 3 ++- plat/marvell/a8k/common/mss/mss_bl2_setup.c | 6 +++++ plat/marvell/common/mss/mss_scp_bootloader.c | 37 ++++++++++++++++++++++++---- 5 files changed, 44 insertions(+), 9 deletions(-) diff --git a/drivers/marvell/mochi/cp110_setup.c b/drivers/marvell/mochi/cp110_setup.c index b4b4e0c82..7186f9857 100644 --- a/drivers/marvell/mochi/cp110_setup.c +++ b/drivers/marvell/mochi/cp110_setup.c @@ -303,7 +303,7 @@ static void cp110_axi_attr_init(uintptr_t base) DOMAIN_SYSTEM_SHAREABLE); } -static void amb_bridge_init(uintptr_t base) +void cp110_amb_init(uintptr_t base) { uint32_t reg; @@ -399,7 +399,7 @@ void cp110_init(uintptr_t cp110_base, uint32_t stream_id) cp110_stream_id_init(cp110_base, stream_id); /* Open AMB bridge for comphy for CP0 & CP1*/ - amb_bridge_init(cp110_base); + cp110_amb_init(cp110_base); /* Reset RTC if needed */ cp110_rtc_init(cp110_base); @@ -411,7 +411,7 @@ void cp110_ble_init(uintptr_t cp110_base) #if PCI_EP_SUPPORT INFO("%s: Initialize CPx - base = %lx\n", __func__, cp110_base); - amb_bridge_init(cp110_base); + cp110_amb_init(cp110_base); /* Configure PCIe clock */ cp110_pcie_clk_cfg(cp110_base); diff --git a/include/drivers/marvell/mochi/cp110_setup.h b/include/drivers/marvell/mochi/cp110_setup.h index 3686257d3..f8cd26b12 100644 --- a/include/drivers/marvell/mochi/cp110_setup.h +++ b/include/drivers/marvell/mochi/cp110_setup.h @@ -51,5 +51,6 @@ static inline uint32_t cp110_rev_id_get(uintptr_t base) void cp110_init(uintptr_t cp110_base, uint32_t stream_id); void cp110_ble_init(uintptr_t cp110_base); +void cp110_amb_init(uintptr_t base); #endif /* CP110_SETUP_H */ diff --git a/plat/marvell/a8k/common/mss/mss_a8k.mk b/plat/marvell/a8k/common/mss/mss_a8k.mk index 58f23d8dd..efd03c5a2 100644 --- a/plat/marvell/a8k/common/mss/mss_a8k.mk +++ b/plat/marvell/a8k/common/mss/mss_a8k.mk @@ -8,7 +8,8 @@ PLAT_MARVELL := plat/marvell A8K_MSS_SOURCE := $(PLAT_MARVELL)/a8k/common/mss -BL2_SOURCES += $(A8K_MSS_SOURCE)/mss_bl2_setup.c +BL2_SOURCES += $(A8K_MSS_SOURCE)/mss_bl2_setup.c \ + $(MARVELL_MOCHI_DRV) BL31_SOURCES += $(A8K_MSS_SOURCE)/mss_pm_ipc.c diff --git a/plat/marvell/a8k/common/mss/mss_bl2_setup.c b/plat/marvell/a8k/common/mss/mss_bl2_setup.c index 728ee54a0..09b8446fa 100644 --- a/plat/marvell/a8k/common/mss/mss_bl2_setup.c +++ b/plat/marvell/a8k/common/mss/mss_bl2_setup.c @@ -74,6 +74,12 @@ static int bl2_plat_mmap_init(void) /* Set the default target id to PIDI */ mmio_write_32(MVEBU_IO_WIN_BASE(MVEBU_AP0) + IOW_GCR_OFFSET, PIDI_TID); + /* Open AMB bridge required for MG access */ + cp110_amb_init(MVEBU_CP_REGS_BASE(0)); + + if (CP_COUNT == 2) + cp110_amb_init(MVEBU_CP_REGS_BASE(1)); + return 0; } diff --git a/plat/marvell/common/mss/mss_scp_bootloader.c b/plat/marvell/common/mss/mss_scp_bootloader.c index 7e442c615..2f1c46f47 100644 --- a/plat/marvell/common/mss/mss_scp_bootloader.c +++ b/plat/marvell/common/mss/mss_scp_bootloader.c @@ -42,6 +42,8 @@ #define MSS_HANDSHAKE_TIMEOUT 50 +#define MG_CM3_SRAM_BASE(CP) (MVEBU_CP_REGS_BASE(CP) + 0x100000) + static int mss_check_image_ready(volatile struct mss_pm_ctrl_block *mss_pm_crtl) { int timeout = MSS_HANDSHAKE_TIMEOUT; @@ -59,6 +61,28 @@ static int mss_check_image_ready(volatile struct mss_pm_ctrl_block *mss_pm_crtl) return 0; } +static int mg_image_load(uintptr_t src_addr, uint32_t size, uintptr_t mg_regs) +{ + if (size > MG_SRAM_SIZE) { + ERROR("image is too big to fit into MG CM3 memory\n"); + return 1; + } + + NOTICE("Loading MG image from address 0x%lx Size 0x%x to MG at 0x%lx\n", + src_addr, size, mg_regs); + + /* Copy image to MG CM3 SRAM */ + memcpy((void *)mg_regs, (void *)src_addr, size); + + /* + * Don't release MG CM3 from reset - it will be done by next step + * bootloader (e.g. U-Boot), when appriopriate device-tree setup (which + * has enabeld 802.3. auto-neg) will be choosen. + */ + + return 0; +} + static int mss_image_load(uint32_t src_addr, uint32_t size, uintptr_t mss_regs) { uint32_t i, loop_num, timeout; @@ -225,12 +249,15 @@ static int load_img_to_cm3(enum cm3_t cm3_type, } break; case MG_CP0: - /* TODO: */ - NOTICE("Load image to CP0 MG not supported\n"); - break; case MG_CP1: - /* TODO: */ - NOTICE("Load image to CP1 MG not supported\n"); + cp_index = cm3_type - MG_CP0; + NOTICE("Load image to CP%d MG\n", cp_index); + ret = mg_image_load(single_img, image_size, + MG_CM3_SRAM_BASE(cp_index)); + if (ret != 0) { + ERROR("SCP Image load failed\n"); + return -1; + } break; default: ERROR("SCP_BL2 wrong img format (cm3_type=%d)\n", cm3_type); -- cgit v1.2.3 From 621146d851d474359f7d577b83a5424d1682f622 Mon Sep 17 00:00:00 2001 From: Grzegorz Jaszczyk Date: Thu, 4 Apr 2019 14:38:55 +0200 Subject: plat: marvell: armada: scp_bl2: allow loading up to 8 images Extend possible images to 8, additionaly add another type which will be used with platform containing up to 3 CPs. Change-Id: Ib68092d11af9801e344d02de839f53127e056e46 Signed-off-by: Grzegorz Jaszczyk --- plat/marvell/common/mss/mss_scp_bl2_format.h | 3 ++- plat/marvell/common/mss/mss_scp_bootloader.c | 8 +++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/plat/marvell/common/mss/mss_scp_bl2_format.h b/plat/marvell/common/mss/mss_scp_bl2_format.h index 7cf8d3201..7150f0a06 100644 --- a/plat/marvell/common/mss/mss_scp_bl2_format.h +++ b/plat/marvell/common/mss/mss_scp_bl2_format.h @@ -8,7 +8,7 @@ #ifndef MSS_SCP_BL2_FORMAT_H #define MSS_SCP_BL2_FORMAT_H -#define MAX_NR_OF_FILES 5 +#define MAX_NR_OF_FILES 8 #define FILE_MAGIC 0xddd01ff #define HEADER_VERSION 0x1 @@ -31,6 +31,7 @@ enum cm3_t { MSS_CP3, MG_CP0, MG_CP1, + MG_CP2, }; typedef struct img_header { diff --git a/plat/marvell/common/mss/mss_scp_bootloader.c b/plat/marvell/common/mss/mss_scp_bootloader.c index 2f1c46f47..4473d81e1 100644 --- a/plat/marvell/common/mss/mss_scp_bootloader.c +++ b/plat/marvell/common/mss/mss_scp_bootloader.c @@ -250,7 +250,13 @@ static int load_img_to_cm3(enum cm3_t cm3_type, break; case MG_CP0: case MG_CP1: + case MG_CP2: cp_index = cm3_type - MG_CP0; + if (bl2_plat_get_cp_count(0) <= cp_index) { + NOTICE("Skipping MG CP%d related image\n", + cp_index); + break; + } NOTICE("Load image to CP%d MG\n", cp_index); ret = mg_image_load(single_img, image_size, MG_CM3_SRAM_BASE(cp_index)); @@ -288,7 +294,7 @@ static int split_and_load_bl2_image(void *image) } if (file_hdr->nr_of_imgs > MAX_NR_OF_FILES) { - ERROR("SCP_BL2 concatenated image contains to many images\n"); + ERROR("SCP_BL2 concatenated image contains too many images\n"); return -1; } -- cgit v1.2.3 From 5f1803f90ff27bf1199f1446581b32fb2468cede Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Tue, 15 May 2018 11:24:59 -0700 Subject: Tegra: per-SoC DRAM base values Tegra194 supports upto 64GB of DRAM, whereas the previous SoCs support upto 32GB DRAM. This patch moves the common DRAM base/end macros to individual Tegra SoC headers to fix this anomaly. Change-Id: I1a9f386b67c2311baab289e726d95cef6954071b Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/include/t132/tegra_def.h | 7 +++++++ plat/nvidia/tegra/include/t186/tegra_def.h | 7 +++++++ plat/nvidia/tegra/include/t194/tegra_def.h | 6 ++++++ plat/nvidia/tegra/include/t210/tegra_def.h | 7 +++++++ plat/nvidia/tegra/include/tegra_private.h | 6 ------ 5 files changed, 27 insertions(+), 6 deletions(-) diff --git a/plat/nvidia/tegra/include/t132/tegra_def.h b/plat/nvidia/tegra/include/t132/tegra_def.h index dfed2aa60..8e6c1fd2b 100644 --- a/plat/nvidia/tegra/include/t132/tegra_def.h +++ b/plat/nvidia/tegra/include/t132/tegra_def.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -110,4 +111,10 @@ #define TEGRA_TZRAM_BASE U(0x7C010000) #define TEGRA_TZRAM_SIZE U(0x10000) +/******************************************************************************* + * Tegra DRAM memory base address + ******************************************************************************/ +#define TEGRA_DRAM_BASE ULL(0x80000000) +#define TEGRA_DRAM_END ULL(0x27FFFFFFF) + #endif /* TEGRA_DEF_H */ diff --git a/plat/nvidia/tegra/include/t186/tegra_def.h b/plat/nvidia/tegra/include/t186/tegra_def.h index da050a895..f2a2334ef 100644 --- a/plat/nvidia/tegra/include/t186/tegra_def.h +++ b/plat/nvidia/tegra/include/t186/tegra_def.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -279,4 +280,10 @@ #define TEGRA_TZRAM_BASE U(0x30000000) #define TEGRA_TZRAM_SIZE U(0x40000) +/******************************************************************************* + * Tegra DRAM memory base address + ******************************************************************************/ +#define TEGRA_DRAM_BASE ULL(0x80000000) +#define TEGRA_DRAM_END ULL(0x27FFFFFFF) + #endif /* TEGRA_DEF_H */ diff --git a/plat/nvidia/tegra/include/t194/tegra_def.h b/plat/nvidia/tegra/include/t194/tegra_def.h index df1d65630..a58ae9d93 100644 --- a/plat/nvidia/tegra/include/t194/tegra_def.h +++ b/plat/nvidia/tegra/include/t194/tegra_def.h @@ -256,6 +256,12 @@ #define TEGRA_GPCDMA_RST_SET_REG_OFFSET U(0x6A0004) #define TEGRA_GPCDMA_RST_CLR_REG_OFFSET U(0x6A0008) +/******************************************************************************* + * Tegra DRAM memory base address + ******************************************************************************/ +#define TEGRA_DRAM_BASE ULL(0x80000000) +#define TEGRA_DRAM_END ULL(0xFFFFFFFFF) + /******************************************************************************* * XUSB STREAMIDs ******************************************************************************/ diff --git a/plat/nvidia/tegra/include/t210/tegra_def.h b/plat/nvidia/tegra/include/t210/tegra_def.h index bbcfdc5c1..4a39aa1fb 100644 --- a/plat/nvidia/tegra/include/t210/tegra_def.h +++ b/plat/nvidia/tegra/include/t210/tegra_def.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -268,4 +269,10 @@ #define TEGRA_TZRAM_CARVEOUT_BASE U(0x7C04C000) #define TEGRA_TZRAM_CARVEOUT_SIZE U(0x4000) +/******************************************************************************* + * Tegra DRAM memory base address + ******************************************************************************/ +#define TEGRA_DRAM_BASE ULL(0x80000000) +#define TEGRA_DRAM_END ULL(0x27FFFFFFF) + #endif /* TEGRA_DEF_H */ diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h index 761acdea5..5087cc52d 100644 --- a/plat/nvidia/tegra/include/tegra_private.h +++ b/plat/nvidia/tegra/include/tegra_private.h @@ -17,12 +17,6 @@ #include -/******************************************************************************* - * Tegra DRAM memory base address - ******************************************************************************/ -#define TEGRA_DRAM_BASE ULL(0x80000000) -#define TEGRA_DRAM_END ULL(0x27FFFFFFF) - /******************************************************************************* * Implementation defined ACTLR_EL1 bit definitions ******************************************************************************/ -- cgit v1.2.3 From 39171cd0337be4c9bea14eb8f7f6cc583ea29ea4 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Thu, 17 May 2018 09:36:38 -0700 Subject: Tegra: remove weakly defined platform setup handlers This patch converts the weakly defined platform setup handlers into actual platform specific handlers to improve code coverage numbers and some MISRA defects. The weakly defined handlers never get executed thus resulting in lower coverage - function, function calls, statements, branches and pairs. Change-Id: I02f450f66b5754a90d934df4d76eb91459fca5f9 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/tegra_bl31_setup.c | 32 +--------------------------- plat/nvidia/tegra/soc/t132/plat_setup.c | 33 +++++++++++++++++++++++++++++ plat/nvidia/tegra/soc/t186/plat_setup.c | 9 ++++++++ plat/nvidia/tegra/soc/t210/plat_setup.c | 20 +++++++++++++++++ 4 files changed, 63 insertions(+), 31 deletions(-) diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c index cbe3377b0..8a49e232d 100644 --- a/plat/nvidia/tegra/common/tegra_bl31_setup.c +++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c @@ -64,35 +64,6 @@ static aapcs64_params_t bl32_args; ******************************************************************************/ extern uint64_t ns_image_entrypoint; -/******************************************************************************* - * The following platform setup functions are weakly defined. They - * provide typical implementations that will be overridden by a SoC. - ******************************************************************************/ -#pragma weak plat_early_platform_setup -#pragma weak plat_get_bl31_params -#pragma weak plat_get_bl31_plat_params -#pragma weak plat_late_platform_setup - -void plat_early_platform_setup(void) -{ - ; /* do nothing */ -} - -struct tegra_bl31_params *plat_get_bl31_params(void) -{ - return NULL; -} - -plat_params_from_bl2_t *plat_get_bl31_plat_params(void) -{ - return NULL; -} - -void plat_late_platform_setup(void) -{ - ; /* do nothing */ -} - /******************************************************************************* * Return a pointer to the 'entry_point_info' structure of the next image for * security state specified. BL33 corresponds to the non-secure image type @@ -137,8 +108,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, /* * For RESET_TO_BL31 systems, BL31 is the first bootloader to run so * there's no argument to relay from a previous bootloader. Platforms - * might use custom ways to get arguments, so provide handlers which - * they can override. + * might use custom ways to get arguments. */ if (arg_from_bl2 == NULL) { arg_from_bl2 = plat_get_bl31_params(); diff --git a/plat/nvidia/tegra/soc/t132/plat_setup.c b/plat/nvidia/tegra/soc/t132/plat_setup.c index df6267897..2f54dd525 100644 --- a/plat/nvidia/tegra/soc/t132/plat_setup.c +++ b/plat/nvidia/tegra/soc/t132/plat_setup.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -121,3 +122,35 @@ void plat_gic_setup(void) tegra_gic_setup(NULL, 0); tegra_gic_init(); } + +/******************************************************************************* + * Return pointer to the BL31 params from previous bootloader + ******************************************************************************/ +struct tegra_bl31_params *plat_get_bl31_params(void) +{ + return NULL; +} + +/******************************************************************************* + * Return pointer to the BL31 platform params from previous bootloader + ******************************************************************************/ +plat_params_from_bl2_t *plat_get_bl31_plat_params(void) +{ + return NULL; +} + +/******************************************************************************* + * Handler for early platform setup + ******************************************************************************/ +void plat_early_platform_setup(void) +{ + ; /* do nothing */ +} + +/******************************************************************************* + * Handler for late platform setup + ******************************************************************************/ +void plat_late_platform_setup(void) +{ + ; /* do nothing */ +} diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c index 1018caa94..7e18b5c42 100644 --- a/plat/nvidia/tegra/soc/t186/plat_setup.c +++ b/plat/nvidia/tegra/soc/t186/plat_setup.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -193,6 +194,14 @@ void plat_early_platform_setup(void) } } +/******************************************************************************* + * Handler for late platform setup + ******************************************************************************/ +void plat_late_platform_setup(void) +{ + ; /* do nothing */ +} + /* Secure IRQs for Tegra186 */ static const interrupt_prop_t tegra186_interrupt_props[] = { INTR_PROP_DESC(TEGRA186_TOP_WDT_IRQ, GIC_HIGHEST_SEC_PRIORITY, diff --git a/plat/nvidia/tegra/soc/t210/plat_setup.c b/plat/nvidia/tegra/soc/t210/plat_setup.c index bfa818419..da1f1b33e 100644 --- a/plat/nvidia/tegra/soc/t210/plat_setup.c +++ b/plat/nvidia/tegra/soc/t210/plat_setup.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -140,6 +141,22 @@ void plat_enable_console(int32_t id) } } +/******************************************************************************* + * Return pointer to the BL31 params from previous bootloader + ******************************************************************************/ +struct tegra_bl31_params *plat_get_bl31_params(void) +{ + return NULL; +} + +/******************************************************************************* + * Return pointer to the BL31 platform params from previous bootloader + ******************************************************************************/ +plat_params_from_bl2_t *plat_get_bl31_plat_params(void) +{ + return NULL; +} + /******************************************************************************* * Handler for early platform setup ******************************************************************************/ @@ -168,6 +185,9 @@ static const interrupt_prop_t tegra210_interrupt_props[] = { GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE), }; +/******************************************************************************* + * Handler for late platform setup + ******************************************************************************/ void plat_late_platform_setup(void) { const plat_params_from_bl2_t *plat_params = bl31_get_plat_params(); -- cgit v1.2.3 From e44f86ef2b01a71e78ce959d3dcfa354cf259c0f Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Thu, 17 May 2018 10:10:25 -0700 Subject: Tegra: remove weakly defined PSCI platform handlers This patch removes all the weakly defined PSCI handlers defined per-platform, to improve code coverage numbers and reduce MISRA defects. Change-Id: I0f9c0caa0a6071d0360d07454b19dcc7340da8c2 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/tegra_pm.c | 92 +------------------------ plat/nvidia/tegra/include/tegra_private.h | 2 + plat/nvidia/tegra/soc/t132/plat_psci_handlers.c | 47 +++++++++++++ plat/nvidia/tegra/soc/t186/plat_psci_handlers.c | 12 ++++ plat/nvidia/tegra/soc/t194/plat_psci_handlers.c | 5 ++ plat/nvidia/tegra/soc/t210/plat_psci_handlers.c | 18 +++++ 6 files changed, 85 insertions(+), 91 deletions(-) diff --git a/plat/nvidia/tegra/common/tegra_pm.c b/plat/nvidia/tegra/common/tegra_pm.c index 39dc42c5b..d0d2827e8 100644 --- a/plat/nvidia/tegra/common/tegra_pm.c +++ b/plat/nvidia/tegra/common/tegra_pm.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -27,97 +28,6 @@ extern uint64_t tegra_bl31_phys_base; extern uint64_t tegra_sec_entry_point; -/* - * The following platform setup functions are weakly defined. They - * provide typical implementations that will be overridden by a SoC. - */ -#pragma weak tegra_soc_pwr_domain_suspend_pwrdown_early -#pragma weak tegra_soc_cpu_standby -#pragma weak tegra_soc_pwr_domain_suspend -#pragma weak tegra_soc_pwr_domain_on -#pragma weak tegra_soc_pwr_domain_off -#pragma weak tegra_soc_pwr_domain_on_finish -#pragma weak tegra_soc_pwr_domain_power_down_wfi -#pragma weak tegra_soc_prepare_system_reset -#pragma weak tegra_soc_prepare_system_off -#pragma weak tegra_soc_get_target_pwr_state - -int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state) -{ - return PSCI_E_NOT_SUPPORTED; -} - -int32_t tegra_soc_cpu_standby(plat_local_state_t cpu_state) -{ - (void)cpu_state; - return PSCI_E_SUCCESS; -} - -int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) -{ - (void)target_state; - return PSCI_E_NOT_SUPPORTED; -} - -int32_t tegra_soc_pwr_domain_on(u_register_t mpidr) -{ - (void)mpidr; - return PSCI_E_SUCCESS; -} - -int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state) -{ - (void)target_state; - return PSCI_E_SUCCESS; -} - -int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state) -{ - (void)target_state; - return PSCI_E_SUCCESS; -} - -int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state) -{ - (void)target_state; - return PSCI_E_SUCCESS; -} - -int32_t tegra_soc_prepare_system_reset(void) -{ - return PSCI_E_SUCCESS; -} - -__dead2 void tegra_soc_prepare_system_off(void) -{ - ERROR("Tegra System Off: operation not handled.\n"); - panic(); -} - -plat_local_state_t tegra_soc_get_target_pwr_state(uint32_t lvl, - const plat_local_state_t *states, - uint32_t ncpu) -{ - plat_local_state_t target = PLAT_MAX_OFF_STATE, temp; - uint32_t num_cpu = ncpu; - const plat_local_state_t *local_state = states; - - (void)lvl; - - assert(ncpu != 0U); - - do { - temp = *local_state; - if ((temp < target)) { - target = temp; - } - --num_cpu; - local_state++; - } while (num_cpu != 0U); - - return target; -} - /******************************************************************************* * This handler is called by the PSCI implementation during the `SYSTEM_SUSPEND` * call to get the `power_state` parameter. This allows the platform to encode diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h index 5087cc52d..b419d94e5 100644 --- a/plat/nvidia/tegra/include/tegra_private.h +++ b/plat/nvidia/tegra/include/tegra_private.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -100,6 +101,7 @@ int32_t tegra_soc_pwr_domain_on(u_register_t mpidr); int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state); int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state); int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state); +int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state); int32_t tegra_soc_prepare_system_reset(void); __dead2 void tegra_soc_prepare_system_off(void); plat_local_state_t tegra_soc_get_target_pwr_state(uint32_t lvl, diff --git a/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c index bd3f46fcc..584031204 100644 --- a/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -35,6 +36,30 @@ static int cpu_powergate_mask[PLATFORM_MAX_CPUS_PER_CLUSTER]; +plat_local_state_t tegra_soc_get_target_pwr_state(uint32_t lvl, + const plat_local_state_t *states, + uint32_t ncpu) +{ + plat_local_state_t target = PLAT_MAX_OFF_STATE, temp; + uint32_t num_cpu = ncpu; + const plat_local_state_t *local_state = states; + + (void)lvl; + + assert(ncpu != 0U); + + do { + temp = *local_state; + if ((temp < target)) { + target = temp; + } + --num_cpu; + local_state++; + } while (num_cpu != 0U); + + return target; +} + int32_t tegra_soc_validate_power_state(unsigned int power_state, psci_power_state_t *req_state) { @@ -112,6 +137,12 @@ int tegra_soc_pwr_domain_off(const psci_power_state_t *target_state) return PSCI_E_SUCCESS; } +int32_t tegra_soc_cpu_standby(plat_local_state_t cpu_state) +{ + (void)cpu_state; + return PSCI_E_SUCCESS; +} + int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) { uint64_t val; @@ -139,6 +170,16 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) return PSCI_E_SUCCESS; } +int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state) +{ + return PSCI_E_NOT_SUPPORTED; +} + +int tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state) +{ + return PSCI_E_SUCCESS; +} + int tegra_soc_prepare_system_reset(void) { /* @@ -154,3 +195,9 @@ int tegra_soc_prepare_system_reset(void) return PSCI_E_SUCCESS; } + +__dead2 void tegra_soc_prepare_system_off(void) +{ + ERROR("Tegra System Off: operation not handled.\n"); + panic(); +} diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c index 11394c0ce..2000e53fd 100644 --- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -83,6 +84,12 @@ int32_t tegra_soc_validate_power_state(uint32_t power_state, return ret; } +int32_t tegra_soc_cpu_standby(plat_local_state_t cpu_state) +{ + (void)cpu_state; + return PSCI_E_SUCCESS; +} + int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) { const plat_local_state_t *pwr_domain_state; @@ -289,6 +296,11 @@ int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_sta return PSCI_E_SUCCESS; } +int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state) +{ + return PSCI_E_NOT_SUPPORTED; +} + int32_t tegra_soc_pwr_domain_on(u_register_t mpidr) { int32_t ret = PSCI_E_SUCCESS; diff --git a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c index cc8be128a..518eb25de 100644 --- a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c @@ -342,6 +342,11 @@ int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_sta return PSCI_E_SUCCESS; } +int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state) +{ + return PSCI_E_NOT_SUPPORTED; +} + int32_t tegra_soc_pwr_domain_on(u_register_t mpidr) { uint64_t target_cpu = mpidr & MPIDR_CPU_MASK; diff --git a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c index 12241c2f3..bbbfcf5bf 100644 --- a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -184,6 +185,12 @@ plat_local_state_t tegra_soc_get_target_pwr_state(unsigned int lvl, return target; } +int32_t tegra_soc_cpu_standby(plat_local_state_t cpu_state) +{ + (void)cpu_state; + return PSCI_E_SUCCESS; +} + int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) { u_register_t mpidr = read_mpidr(); @@ -412,6 +419,11 @@ int tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state) return PSCI_E_SUCCESS; } +int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state) +{ + return PSCI_E_NOT_SUPPORTED; +} + int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state) { const plat_params_from_bl2_t *plat_params = bl31_get_plat_params(); @@ -569,3 +581,9 @@ int tegra_soc_prepare_system_reset(void) return PSCI_E_SUCCESS; } + +__dead2 void tegra_soc_prepare_system_off(void) +{ + ERROR("Tegra System Off: operation not handled.\n"); + panic(); +} -- cgit v1.2.3 From ba37943d2d0adc4fa901707535b5b9b1c8c633d0 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Thu, 17 May 2018 10:14:30 -0700 Subject: Tegra: remove weakly defined per-platform SiP handler This patch removes the weakly defined per-platform SiP handler as all platforms implement this handler, defeating the need for a weak definition. Change-Id: Id4c7e69163d2635de1813f5a385ac874253a8da9 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/tegra_sip_calls.c | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/plat/nvidia/tegra/common/tegra_sip_calls.c b/plat/nvidia/tegra/common/tegra_sip_calls.c index b8ba09562..1d48cc01b 100644 --- a/plat/nvidia/tegra/common/tegra_sip_calls.c +++ b/plat/nvidia/tegra/common/tegra_sip_calls.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -25,32 +26,6 @@ #define TEGRA_SIP_FIQ_NS_ENTRYPOINT 0x82000005 #define TEGRA_SIP_FIQ_NS_GET_CONTEXT 0x82000006 -/******************************************************************************* - * SoC specific SiP handler - ******************************************************************************/ -#pragma weak plat_sip_handler -int32_t plat_sip_handler(uint32_t smc_fid, - uint64_t x1, - uint64_t x2, - uint64_t x3, - uint64_t x4, - const void *cookie, - void *handle, - uint64_t flags) -{ - /* unused parameters */ - (void)smc_fid; - (void)x1; - (void)x2; - (void)x3; - (void)x4; - (void)cookie; - (void)handle; - (void)flags; - - return -ENOTSUP; -} - /******************************************************************************* * This function is responsible for handling all SiP calls ******************************************************************************/ -- cgit v1.2.3 From f561a17967af5b467d32342b95ac6bb1bc25f679 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Thu, 17 May 2018 10:42:18 -0700 Subject: Tegra: memctrl_v2: remove weakly defined TZDRAM setup handler This patch removes the per-platform, weakly defined TZDRAM setup handler, as all affected platforms implement the actual handler. Change-Id: I95d04b2a771bc5d673e56b097d45c493fa388ee8 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c index 2f31906d8..c2ef981ee 100644 --- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c +++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. - * Copyright (c) 2019, NVIDIA Corporation. All rights reserved. + * Copyright (c) 2019-2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -26,17 +26,6 @@ static uint64_t video_mem_base; static uint64_t video_mem_size_mb; -/* - * The following platform setup functions are weakly defined. They - * provide typical implementations that will be overridden by a SoC. - */ -#pragma weak plat_memctrl_tzdram_setup - -void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes) -{ - ; /* do nothing */ -} - /* * Init Memory controller during boot. */ -- cgit v1.2.3 From 57c539f9299666d8015d6d12f6293cbb0419308e Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Thu, 17 May 2018 11:10:13 -0700 Subject: Tegra: compile PMC driver for Tegra132/Tegra210 platforms The PMC driver is used only by Tegra210 and Tegra132 platforms. This patch removes pmc.c from the common makefile and moves it to the platform specific makefiles. As a result, the PMC code from common code has been moved to Tegra132 and Tegra210 platform ports. Change-Id: Ia157f70e776b3eff3c12eb8f0f02d30102670a98 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/tegra_common.mk | 1 - plat/nvidia/tegra/common/tegra_pm.c | 8 ++++---- plat/nvidia/tegra/soc/t132/plat_psci_handlers.c | 5 +++++ plat/nvidia/tegra/soc/t132/platform_t132.mk | 2 ++ plat/nvidia/tegra/soc/t210/plat_psci_handlers.c | 5 +++++ plat/nvidia/tegra/soc/t210/platform_t210.mk | 2 ++ 6 files changed, 18 insertions(+), 5 deletions(-) diff --git a/plat/nvidia/tegra/common/tegra_common.mk b/plat/nvidia/tegra/common/tegra_common.mk index 34b5638ec..50c9592f1 100644 --- a/plat/nvidia/tegra/common/tegra_common.mk +++ b/plat/nvidia/tegra/common/tegra_common.mk @@ -25,7 +25,6 @@ BL31_SOURCES += drivers/delay_timer/delay_timer.c \ plat/common/aarch64/crash_console_helpers.S \ ${TEGRA_GICv2_SOURCES} \ ${COMMON_DIR}/aarch64/tegra_helpers.S \ - ${COMMON_DIR}/drivers/pmc/pmc.c \ ${COMMON_DIR}/lib/debug/profiler.c \ ${COMMON_DIR}/tegra_bl31_setup.c \ ${COMMON_DIR}/tegra_delay_timer.c \ diff --git a/plat/nvidia/tegra/common/tegra_pm.c b/plat/nvidia/tegra/common/tegra_pm.c index d0d2827e8..1f59f30aa 100644 --- a/plat/nvidia/tegra/common/tegra_pm.c +++ b/plat/nvidia/tegra/common/tegra_pm.c @@ -221,10 +221,10 @@ __dead2 void tegra_system_reset(void) /* per-SoC system reset handler */ (void)tegra_soc_prepare_system_reset(); - /* - * Program the PMC in order to restart the system. - */ - tegra_pmc_system_reset(); + /* wait for the system to reset */ + for (;;) { + ; + } } /******************************************************************************* diff --git a/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c index 584031204..0e2edf096 100644 --- a/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c @@ -193,6 +193,11 @@ int tegra_soc_prepare_system_reset(void) /* Wait 1 ms to make sure clock source/device logic is stabilized. */ mdelay(1); + /* + * Program the PMC in order to restart the system. + */ + tegra_pmc_system_reset(); + return PSCI_E_SUCCESS; } diff --git a/plat/nvidia/tegra/soc/t132/platform_t132.mk b/plat/nvidia/tegra/soc/t132/platform_t132.mk index bb7b7ee66..183e1889c 100644 --- a/plat/nvidia/tegra/soc/t132/platform_t132.mk +++ b/plat/nvidia/tegra/soc/t132/platform_t132.mk @@ -1,5 +1,6 @@ # # Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2020, NVIDIA Corporation. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -23,6 +24,7 @@ BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \ lib/cpus/aarch64/denver.S \ ${COMMON_DIR}/drivers/flowctrl/flowctrl.c \ ${COMMON_DIR}/drivers/memctrl/memctrl_v1.c \ + ${COMMON_DIR}/drivers/pmc/pmc.c \ ${SOC_DIR}/plat_psci_handlers.c \ ${SOC_DIR}/plat_sip_calls.c \ ${SOC_DIR}/plat_setup.c \ diff --git a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c index bbbfcf5bf..4ef9558ee 100644 --- a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c @@ -579,6 +579,11 @@ int tegra_soc_prepare_system_reset(void) /* Wait 1 ms to make sure clock source/device logic is stabilized. */ mdelay(1); + /* + * Program the PMC in order to restart the system. + */ + tegra_pmc_system_reset(); + return PSCI_E_SUCCESS; } diff --git a/plat/nvidia/tegra/soc/t210/platform_t210.mk b/plat/nvidia/tegra/soc/t210/platform_t210.mk index a11aef4dd..4f2db5386 100644 --- a/plat/nvidia/tegra/soc/t210/platform_t210.mk +++ b/plat/nvidia/tegra/soc/t210/platform_t210.mk @@ -1,5 +1,6 @@ # # Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2020, NVIDIA Corporation. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -33,6 +34,7 @@ BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \ ${COMMON_DIR}/drivers/bpmp/bpmp.c \ ${COMMON_DIR}/drivers/flowctrl/flowctrl.c \ ${COMMON_DIR}/drivers/memctrl/memctrl_v1.c \ + ${COMMON_DIR}/drivers/pmc/pmc.c \ ${SOC_DIR}/plat_psci_handlers.c \ ${SOC_DIR}/plat_setup.c \ ${SOC_DIR}/drivers/se/security_engine.c \ -- cgit v1.2.3 From 8d4107f0833723b49f88ed56a6c751eebc5c6696 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Fri, 25 May 2018 15:22:58 -0700 Subject: Tegra194: se: fix multiple MISRA issues This patch fixes violations for the following MISRA rules * Rule 8.4 "A compatible declaration shall be visible when an object or function with external linkage is defined" * Rule 10.1 "Operands shall not be of an inappropriate essential type" * Rule 10.6 "Both operands of an operator in which the usual arithmetic conversions are perdormed shall have the same essential type category" * Rule 17.7 "The value returned by a function having non-void return type shall be used" Change-Id: I171ac8340de729fd7be928fa0c0694e9bb8569f0 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/soc/t194/drivers/se/se.c | 17 ++++++++++++----- plat/nvidia/tegra/soc/t194/drivers/se/se_private.h | 4 ++-- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/plat/nvidia/tegra/soc/t194/drivers/se/se.c b/plat/nvidia/tegra/soc/t194/drivers/se/se.c index 3a2e959d0..a3b338940 100644 --- a/plat/nvidia/tegra/soc/t194/drivers/se/se.c +++ b/plat/nvidia/tegra/soc/t194/drivers/se/se.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include "se_private.h" @@ -54,7 +55,7 @@ static bool tegra_se_is_operation_complete(void) */ do { val = tegra_se_read_32(CTX_SAVE_AUTO_STATUS); - se_is_busy = !!(val & CTX_SAVE_AUTO_SE_BUSY); + se_is_busy = ((val & CTX_SAVE_AUTO_SE_BUSY) != 0U); /* sleep until SE finishes */ if (se_is_busy) { @@ -186,7 +187,8 @@ int32_t tegra_se_suspend(void) assert(tegra_bpmp_ipc_init() == 0); /* Enable SE clock before SE context save */ - tegra_bpmp_ipc_enable_clock(TEGRA_CLK_SE); + ret = tegra_bpmp_ipc_enable_clock(TEGRA_CLK_SE); + assert(ret == 0); /* save SE registers */ se_regs[0] = mmio_read_32(TEGRA_SE0_BASE + SE0_MUTEX_WATCHDOG_NS_LIMIT); @@ -201,7 +203,8 @@ int32_t tegra_se_suspend(void) } /* Disable SE clock after SE context save */ - tegra_bpmp_ipc_disable_clock(TEGRA_CLK_SE); + ret = tegra_bpmp_ipc_disable_clock(TEGRA_CLK_SE); + assert(ret == 0); return ret; } @@ -211,11 +214,14 @@ int32_t tegra_se_suspend(void) */ void tegra_se_resume(void) { + int32_t ret = 0; + /* initialise communication channel with BPMP */ assert(tegra_bpmp_ipc_init() == 0); /* Enable SE clock before SE context restore */ - tegra_bpmp_ipc_enable_clock(TEGRA_CLK_SE); + ret = tegra_bpmp_ipc_enable_clock(TEGRA_CLK_SE); + assert(ret == 0); /* * When TZ takes over after System Resume, TZ should first reconfigure @@ -229,5 +235,6 @@ void tegra_se_resume(void) mmio_write_32(TEGRA_PKA1_BASE + PKA1_MUTEX_WATCHDOG_NS_LIMIT, se_regs[3]); /* Disable SE clock after SE context restore */ - tegra_bpmp_ipc_disable_clock(TEGRA_CLK_SE); + ret = tegra_bpmp_ipc_disable_clock(TEGRA_CLK_SE); + assert(ret == 0); } diff --git a/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h b/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h index a2c5d1c38..577217b8e 100644 --- a/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h +++ b/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h @@ -74,12 +74,12 @@ static inline uint32_t tegra_se_read_32(uint32_t offset) { - return mmio_read_32(TEGRA_SE0_BASE + offset); + return mmio_read_32((uint32_t)(TEGRA_SE0_BASE + offset)); } static inline void tegra_se_write_32(uint32_t offset, uint32_t val) { - mmio_write_32(TEGRA_SE0_BASE + offset, val); + mmio_write_32((uint32_t)(TEGRA_SE0_BASE + offset), val); } #endif /* SE_PRIVATE_H */ -- cgit v1.2.3 From 64aa08fb169bb5fa4b3c160fcc47e8dade4d7cac Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Fri, 25 May 2018 14:34:53 -0700 Subject: Tegra: bpmp: fix multiple MISRA issues This patch fixes violations for the following MISRA rules * Rule 5.7 "A tag name shall be a unique identifier" * Rule 10.1 "Operands shall not be of an inappropriate essential type" * Rule 10.3 "The value of an expression shall not be assigned to an object with a narrower essential type or of a different essential type category" * Rule 10.4 "Both operands of an operator in which the usual arithmetic conversions are performed shall have the same essential type category" * Rule 20.7 "Expressions resulting from the expansion of macro parameters shall be enclosed in parentheses" * Rule 21.1 "#define and #undef shall not be used on a reserved identifier or reserved macro name" Change-Id: I83cbe659c2d72e76dd4759959870b57c58adafdf Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c | 4 ++-- plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h | 30 ++++++++++++------------ plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h | 17 +++++++------- 3 files changed, 25 insertions(+), 26 deletions(-) diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c index ae899c424..eaf96751c 100644 --- a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c +++ b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c @@ -316,7 +316,7 @@ int tegra_bpmp_ipc_enable_clock(uint32_t clk_id) /* prepare the MRQ_CLK command */ req.cmd_and_id = make_mrq_clk_cmd(CMD_CLK_ENABLE, clk_id); - ret = tegra_bpmp_ipc_send_req_atomic(MRQ_CLK, &req, sizeof(req), + ret = tegra_bpmp_ipc_send_req_atomic(MRQ_CLK, &req, (uint32_t)sizeof(req), NULL, 0); if (ret != 0) { ERROR("%s: failed for module %d with error %d\n", __func__, @@ -339,7 +339,7 @@ int tegra_bpmp_ipc_disable_clock(uint32_t clk_id) /* prepare the MRQ_CLK command */ req.cmd_and_id = make_mrq_clk_cmd(CMD_CLK_DISABLE, clk_id); - ret = tegra_bpmp_ipc_send_req_atomic(MRQ_CLK, &req, sizeof(req), + ret = tegra_bpmp_ipc_send_req_atomic(MRQ_CLK, &req, (uint32_t)sizeof(req), NULL, 0); if (ret != 0) { ERROR("%s: failed for module %d with error %d\n", __func__, diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h index 7059c3701..d85b906b8 100644 --- a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h +++ b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h @@ -1,17 +1,17 @@ /* - * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ -#ifndef INTF_H -#define INTF_H +#ifndef BPMP_INTF_H +#define BPMP_INTF_H /** * Flags used in IPC req */ #define FLAG_DO_ACK (U(1) << 0) -#define FLAG_RING_DOORBELL (U(1) << 1) +#define FLAG_RING_DOORBELL (U(1) << 1) /* Bit 1 is designated for CCPlex in secure world */ #define HSP_MASTER_CCPLEX_BIT (U(1) << 1) @@ -77,16 +77,16 @@ struct __attribute__((packed)) mrq_reset_request { * */ enum { - CMD_CLK_GET_RATE = 1, - CMD_CLK_SET_RATE = 2, - CMD_CLK_ROUND_RATE = 3, - CMD_CLK_GET_PARENT = 4, - CMD_CLK_SET_PARENT = 5, - CMD_CLK_IS_ENABLED = 6, - CMD_CLK_ENABLE = 7, - CMD_CLK_DISABLE = 8, - CMD_CLK_GET_ALL_INFO = 14, - CMD_CLK_GET_MAX_CLK_ID = 15, + CMD_CLK_GET_RATE = U(1), + CMD_CLK_SET_RATE = U(2), + CMD_CLK_ROUND_RATE = U(3), + CMD_CLK_GET_PARENT = U(4), + CMD_CLK_SET_PARENT = U(5), + CMD_CLK_IS_ENABLED = U(6), + CMD_CLK_ENABLE = U(7), + CMD_CLK_DISABLE = U(8), + CMD_CLK_GET_ALL_INFO = U(14), + CMD_CLK_GET_MAX_CLK_ID = U(15), CMD_CLK_MAX, }; @@ -124,4 +124,4 @@ struct mrq_clk_request { */ #define make_mrq_clk_cmd(cmd, id) (((cmd) << 24) | (id & 0xFFFFFF)) -#endif /* INTF_H */ +#endif /* BPMP_INTF_H */ diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h b/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h index 42e6a1f7c..1b318213b 100644 --- a/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h +++ b/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h @@ -1,11 +1,11 @@ /* - * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2017-2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ -#ifndef IVC_H -#define IVC_H +#ifndef BPMP_IVC_H +#define BPMP_IVC_H #include #include @@ -15,22 +15,21 @@ #define IVC_CHHDR_TX_FIELDS U(16) #define IVC_CHHDR_RX_FIELDS U(16) -struct ivc; struct ivc_channel_header; -/* callback handler for notify on receiving a response */ -typedef void (* ivc_notify_function)(const struct ivc *); - struct ivc { struct ivc_channel_header *rx_channel; struct ivc_channel_header *tx_channel; uint32_t w_pos; uint32_t r_pos; - ivc_notify_function notify; + void (*notify)(const struct ivc *); uint32_t nframes; uint32_t frame_size; }; +/* callback handler for notify on receiving a response */ +typedef void (* ivc_notify_function)(const struct ivc *); + int32_t tegra_ivc_init(struct ivc *ivc, uintptr_t rx_base, uintptr_t tx_base, uint32_t nframes, uint32_t frame_size, ivc_notify_function notify); @@ -48,4 +47,4 @@ bool tegra_ivc_tx_empty(const struct ivc *ivc); bool tegra_ivc_can_write(const struct ivc *ivc); bool tegra_ivc_can_read(const struct ivc *ivc); -#endif /* IVC_H */ +#endif /* BPMP_IVC_H */ -- cgit v1.2.3 From 4a232d5b40ca4f9a0f5f00bf4652aa077c5ba6a7 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Fri, 25 May 2018 16:17:53 -0700 Subject: Tegra194: mce: fix multiple MISRA issues This patch fixes violations of the following MISRA rules * Rule 8.5 "An external object or function shall be declared once in one and only one file" * Rule 10.3 "The value of an expression shall not be assigned to an object with a narrower essential type or of a different esential type category" Change-Id: I4314cd4fea0a4adc6665868dd31e619b4f367e14 Signed-off-by: Varun Wadekar --- .../tegra/soc/t194/drivers/include/mce_private.h | 1 - .../tegra/soc/t194/drivers/include/t194_nvg.h | 460 ++++++++++----------- plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c | 12 +- 3 files changed, 237 insertions(+), 236 deletions(-) diff --git a/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h b/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h index 1fe3aad39..682574467 100644 --- a/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h +++ b/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h @@ -54,7 +54,6 @@ int32_t nvg_is_sc7_allowed(void); int32_t nvg_online_core(uint32_t core); int32_t nvg_update_ccplex_gsc(uint32_t gsc_idx); int32_t nvg_enter_cstate(uint32_t state, uint32_t wake_time); -int32_t nvg_roc_clean_cache_trbits(void); void nvg_enable_strict_checking_mode(void); void nvg_system_shutdown(void); void nvg_system_reboot(void); diff --git a/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h b/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h index ccc46655a..9ccb82382 100644 --- a/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h +++ b/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h @@ -19,123 +19,124 @@ * occur when there is only new functionality. */ enum { - TEGRA_NVG_VERSION_MAJOR = 6, - TEGRA_NVG_VERSION_MINOR = 6 + TEGRA_NVG_VERSION_MAJOR = U(6), + TEGRA_NVG_VERSION_MINOR = U(6) }; typedef enum { - TEGRA_NVG_CHANNEL_VERSION = 0, - TEGRA_NVG_CHANNEL_POWER_PERF = 1, - TEGRA_NVG_CHANNEL_POWER_MODES = 2, - TEGRA_NVG_CHANNEL_WAKE_TIME = 3, - TEGRA_NVG_CHANNEL_CSTATE_INFO = 4, - TEGRA_NVG_CHANNEL_CROSSOVER_C6_LOWER_BOUND = 5, - TEGRA_NVG_CHANNEL_CROSSOVER_CC6_LOWER_BOUND = 6, - TEGRA_NVG_CHANNEL_CROSSOVER_CG7_LOWER_BOUND = 8, - TEGRA_NVG_CHANNEL_CSTATE_STAT_QUERY_REQUEST = 10, - TEGRA_NVG_CHANNEL_CSTATE_STAT_QUERY_VALUE = 11, - TEGRA_NVG_CHANNEL_NUM_CORES = 20, - TEGRA_NVG_CHANNEL_UNIQUE_LOGICAL_ID = 21, - TEGRA_NVG_CHANNEL_LOGICAL_TO_PHYSICAL_MAPPING = 22, - TEGRA_NVG_CHANNEL_LOGICAL_TO_MPIDR = 23, - TEGRA_NVG_CHANNEL_SHUTDOWN = 42, - TEGRA_NVG_CHANNEL_IS_SC7_ALLOWED = 43, - TEGRA_NVG_CHANNEL_ONLINE_CORE = 44, - TEGRA_NVG_CHANNEL_CC3_CTRL = 45, - TEGRA_NVG_CHANNEL_CCPLEX_CACHE_CONTROL = 49, - TEGRA_NVG_CHANNEL_UPDATE_CCPLEX_GSC = 50, - TEGRA_NVG_CHANNEL_HSM_ERROR_CTRL = 53, - TEGRA_NVG_CHANNEL_SECURITY_CONFIG = 54, - TEGRA_NVG_CHANNEL_DEBUG_CONFIG = 55, - TEGRA_NVG_CHANNEL_DDA_SNOC_MCF = 56, - TEGRA_NVG_CHANNEL_DDA_MCF_ORD1 = 57, - TEGRA_NVG_CHANNEL_DDA_MCF_ORD2 = 58, - TEGRA_NVG_CHANNEL_DDA_MCF_ORD3 = 59, - TEGRA_NVG_CHANNEL_DDA_MCF_ISO = 60, - TEGRA_NVG_CHANNEL_DDA_MCF_SISO = 61, - TEGRA_NVG_CHANNEL_DDA_MCF_NISO = 62, - TEGRA_NVG_CHANNEL_DDA_MCF_NISO_REMOTE = 63, - TEGRA_NVG_CHANNEL_DDA_L3CTRL_ISO = 64, - TEGRA_NVG_CHANNEL_DDA_L3CTRL_SISO = 65, - TEGRA_NVG_CHANNEL_DDA_L3CTRL_NISO = 66, - TEGRA_NVG_CHANNEL_DDA_L3CTRL_NISO_REMOTE = 67, - TEGRA_NVG_CHANNEL_DDA_L3CTRL_L3FILL = 68, - TEGRA_NVG_CHANNEL_DDA_L3CTRL_L3WR = 69, - TEGRA_NVG_CHANNEL_DDA_L3CTRL_RSP_L3RD_DMA = 70, - TEGRA_NVG_CHANNEL_DDA_L3CTRL_RSP_MCFRD_DMA = 71, - TEGRA_NVG_CHANNEL_DDA_L3CTRL_GLOBAL = 72, - TEGRA_NVG_CHANNEL_DDA_L3CTRL_LL = 73, - TEGRA_NVG_CHANNEL_DDA_L3CTRL_L3D = 74, - TEGRA_NVG_CHANNEL_DDA_L3CTRL_FCM_RD = 75, - TEGRA_NVG_CHANNEL_DDA_L3CTRL_FCM_WR = 76, - TEGRA_NVG_CHANNEL_DDA_SNOC_GLOBAL_CTRL = 77, - TEGRA_NVG_CHANNEL_DDA_SNOC_CLIENT_REQ_CTRL = 78, - TEGRA_NVG_CHANNEL_DDA_SNOC_CLIENT_REPLENTISH_CTRL = 79, + TEGRA_NVG_CHANNEL_VERSION = U(0), + TEGRA_NVG_CHANNEL_POWER_PERF = U(1), + TEGRA_NVG_CHANNEL_POWER_MODES = U(2), + TEGRA_NVG_CHANNEL_WAKE_TIME = U(3), + TEGRA_NVG_CHANNEL_CSTATE_INFO = U(4), + TEGRA_NVG_CHANNEL_CROSSOVER_C6_LOWER_BOUND = U(5), + TEGRA_NVG_CHANNEL_CROSSOVER_CC6_LOWER_BOUND = U(6), + TEGRA_NVG_CHANNEL_CROSSOVER_CG7_LOWER_BOUND = U(8), + TEGRA_NVG_CHANNEL_CSTATE_STAT_QUERY_REQUEST = U(10), + TEGRA_NVG_CHANNEL_CSTATE_STAT_QUERY_VALUE = U(11), + TEGRA_NVG_CHANNEL_NUM_CORES = U(20), + TEGRA_NVG_CHANNEL_UNIQUE_LOGICAL_ID = U(21), + TEGRA_NVG_CHANNEL_LOGICAL_TO_PHYSICAL_MAPPING = U(22), + TEGRA_NVG_CHANNEL_LOGICAL_TO_MPIDR = U(23), + TEGRA_NVG_CHANNEL_SHUTDOWN = U(42), + TEGRA_NVG_CHANNEL_IS_SC7_ALLOWED = U(43), + TEGRA_NVG_CHANNEL_ONLINE_CORE = U(44), + TEGRA_NVG_CHANNEL_CC3_CTRL = U(45), + TEGRA_NVG_CHANNEL_CCPLEX_CACHE_CONTROL = U(49), + TEGRA_NVG_CHANNEL_UPDATE_CCPLEX_GSC = U(50), + TEGRA_NVG_CHANNEL_HSM_ERROR_CTRL = U(53), + TEGRA_NVG_CHANNEL_SECURITY_CONFIG = U(54), + TEGRA_NVG_CHANNEL_DEBUG_CONFIG = U(55), + TEGRA_NVG_CHANNEL_DDA_SNOC_MCF = U(56), + TEGRA_NVG_CHANNEL_DDA_MCF_ORD1 = U(57), + TEGRA_NVG_CHANNEL_DDA_MCF_ORD2 = U(58), + TEGRA_NVG_CHANNEL_DDA_MCF_ORD3 = U(59), + TEGRA_NVG_CHANNEL_DDA_MCF_ISO = U(60), + TEGRA_NVG_CHANNEL_DDA_MCF_SISO = U(61), + TEGRA_NVG_CHANNEL_DDA_MCF_NISO = U(62), + TEGRA_NVG_CHANNEL_DDA_MCF_NISO_REMOTE = U(63), + TEGRA_NVG_CHANNEL_DDA_L3CTRL_ISO = U(64), + TEGRA_NVG_CHANNEL_DDA_L3CTRL_SISO = U(65), + TEGRA_NVG_CHANNEL_DDA_L3CTRL_NISO = U(66), + TEGRA_NVG_CHANNEL_DDA_L3CTRL_NISO_REMOTE = U(67), + TEGRA_NVG_CHANNEL_DDA_L3CTRL_L3FILL = U(68), + TEGRA_NVG_CHANNEL_DDA_L3CTRL_L3WR = U(69), + TEGRA_NVG_CHANNEL_DDA_L3CTRL_RSP_L3RD_DMA = U(70), + TEGRA_NVG_CHANNEL_DDA_L3CTRL_RSP_MCFRD_DMA = U(71), + TEGRA_NVG_CHANNEL_DDA_L3CTRL_GLOBAL = U(72), + TEGRA_NVG_CHANNEL_DDA_L3CTRL_LL = U(73), + TEGRA_NVG_CHANNEL_DDA_L3CTRL_L3D = U(74), + TEGRA_NVG_CHANNEL_DDA_L3CTRL_FCM_RD = U(75), + TEGRA_NVG_CHANNEL_DDA_L3CTRL_FCM_WR = U(76), + TEGRA_NVG_CHANNEL_DDA_SNOC_GLOBAL_CTRL = U(77), + TEGRA_NVG_CHANNEL_DDA_SNOC_CLIENT_REQ_CTRL = U(78), + TEGRA_NVG_CHANNEL_DDA_SNOC_CLIENT_REPLENTISH_CTRL = U(79), TEGRA_NVG_CHANNEL_LAST_INDEX } tegra_nvg_channel_id_t; typedef enum { - NVG_STAT_QUERY_SC7_ENTRIES = 1, - NVG_STAT_QUERY_CC6_ENTRIES = 6, - NVG_STAT_QUERY_CG7_ENTRIES = 7, - NVG_STAT_QUERY_C6_ENTRIES = 10, - NVG_STAT_QUERY_C7_ENTRIES = 14, - NVG_STAT_QUERY_SC7_RESIDENCY_SUM = 32, - NVG_STAT_QUERY_CC6_RESIDENCY_SUM = 41, - NVG_STAT_QUERY_CG7_RESIDENCY_SUM = 46, - NVG_STAT_QUERY_C6_RESIDENCY_SUM = 51, - NVG_STAT_QUERY_C7_RESIDENCY_SUM = 56, - NVG_STAT_QUERY_SC7_ENTRY_TIME_SUM = 60, - NVG_STAT_QUERY_CC6_ENTRY_TIME_SUM = 61, - NVG_STAT_QUERY_CG7_ENTRY_TIME_SUM = 62, - NVG_STAT_QUERY_C6_ENTRY_TIME_SUM = 63, - NVG_STAT_QUERY_C7_ENTRY_TIME_SUM = 64, - NVG_STAT_QUERY_SC7_EXIT_TIME_SUM = 70, - NVG_STAT_QUERY_CC6_EXIT_TIME_SUM = 71, - NVG_STAT_QUERY_CG7_EXIT_TIME_SUM = 72, - NVG_STAT_QUERY_C6_EXIT_TIME_SUM = 73, - NVG_STAT_QUERY_C7_EXIT_TIME_SUM = 74, - NVG_STAT_QUERY_SC7_ENTRY_LAST = 80, - NVG_STAT_QUERY_CC6_ENTRY_LAST = 81, - NVG_STAT_QUERY_CG7_ENTRY_LAST = 82, - NVG_STAT_QUERY_C6_ENTRY_LAST = 83, - NVG_STAT_QUERY_C7_ENTRY_LAST = 84, - NVG_STAT_QUERY_SC7_EXIT_LAST = 90, - NVG_STAT_QUERY_CC6_EXIT_LAST = 91, - NVG_STAT_QUERY_CG7_EXIT_LAST = 92, - NVG_STAT_QUERY_C6_EXIT_LAST = 93, - NVG_STAT_QUERY_C7_EXIT_LAST = 94 + NVG_STAT_QUERY_SC7_ENTRIES = U(1), + NVG_STAT_QUERY_CC6_ENTRIES = U(6), + NVG_STAT_QUERY_CG7_ENTRIES = U(7), + NVG_STAT_QUERY_C6_ENTRIES = U(10), + NVG_STAT_QUERY_C7_ENTRIES = U(14), + NVG_STAT_QUERY_SC7_RESIDENCY_SUM = U(32), + NVG_STAT_QUERY_CC6_RESIDENCY_SUM = U(41), + NVG_STAT_QUERY_CG7_RESIDENCY_SUM = U(46), + NVG_STAT_QUERY_C6_RESIDENCY_SUM = U(51), + NVG_STAT_QUERY_C7_RESIDENCY_SUM = U(56), + NVG_STAT_QUERY_SC7_ENTRY_TIME_SUM = U(60), + NVG_STAT_QUERY_CC6_ENTRY_TIME_SUM = U(61), + NVG_STAT_QUERY_CG7_ENTRY_TIME_SUM = U(62), + NVG_STAT_QUERY_C6_ENTRY_TIME_SUM = U(63), + NVG_STAT_QUERY_C7_ENTRY_TIME_SUM = U(64), + NVG_STAT_QUERY_SC7_EXIT_TIME_SUM = U(70), + NVG_STAT_QUERY_CC6_EXIT_TIME_SUM = U(71), + NVG_STAT_QUERY_CG7_EXIT_TIME_SUM = U(72), + NVG_STAT_QUERY_C6_EXIT_TIME_SUM = U(73), + NVG_STAT_QUERY_C7_EXIT_TIME_SUM = U(74), + NVG_STAT_QUERY_SC7_ENTRY_LAST = U(80), + NVG_STAT_QUERY_CC6_ENTRY_LAST = U(81), + NVG_STAT_QUERY_CG7_ENTRY_LAST = U(82), + NVG_STAT_QUERY_C6_ENTRY_LAST = U(83), + NVG_STAT_QUERY_C7_ENTRY_LAST = U(84), + NVG_STAT_QUERY_SC7_EXIT_LAST = U(90), + NVG_STAT_QUERY_CC6_EXIT_LAST = U(91), + NVG_STAT_QUERY_CG7_EXIT_LAST = U(92), + NVG_STAT_QUERY_C6_EXIT_LAST = U(93), + NVG_STAT_QUERY_C7_EXIT_LAST = U(94) + } tegra_nvg_stat_query_t; typedef enum { - TEGRA_NVG_CORE_C0 = 0, - TEGRA_NVG_CORE_C1 = 1, - TEGRA_NVG_CORE_C6 = 6, - TEGRA_NVG_CORE_C7 = 7, - TEGRA_NVG_CORE_WARMRSTREQ = 8 + TEGRA_NVG_CORE_C0 = U(0), + TEGRA_NVG_CORE_C1 = U(1), + TEGRA_NVG_CORE_C6 = U(6), + TEGRA_NVG_CORE_C7 = U(7), + TEGRA_NVG_CORE_WARMRSTREQ = U(8) } tegra_nvg_core_sleep_state_t; typedef enum { - TEGRA_NVG_SHUTDOWN = 0U, - TEGRA_NVG_REBOOT = 1U + TEGRA_NVG_SHUTDOWN = U(0), + TEGRA_NVG_REBOOT = U(1) } tegra_nvg_shutdown_reboot_state_t; typedef enum { - TEGRA_NVG_CLUSTER_CC0 = 0, - TEGRA_NVG_CLUSTER_AUTO_CC1 = 1, - TEGRA_NVG_CLUSTER_CC6 = 6 + TEGRA_NVG_CLUSTER_CC0 = U(0), + TEGRA_NVG_CLUSTER_AUTO_CC1 = U(1), + TEGRA_NVG_CLUSTER_CC6 = U(6) } tegra_nvg_cluster_sleep_state_t; typedef enum { - TEGRA_NVG_CG_CG0 = 0, - TEGRA_NVG_CG_CG7 = 7 + TEGRA_NVG_CG_CG0 = U(0), + TEGRA_NVG_CG_CG7 = U(7) } tegra_nvg_cluster_group_sleep_state_t; typedef enum { - TEGRA_NVG_SYSTEM_SC0 = 0, - TEGRA_NVG_SYSTEM_SC7 = 7, - TEGRA_NVG_SYSTEM_SC8 = 8 + TEGRA_NVG_SYSTEM_SC0 = U(0), + TEGRA_NVG_SYSTEM_SC7 = U(7), + TEGRA_NVG_SYSTEM_SC8 = U(8) } tegra_nvg_system_sleep_state_t; // --------------------------------------------------------------------------- @@ -145,95 +146,95 @@ typedef enum { typedef union { uint64_t flat; struct nvg_version_channel_t { - uint32_t minor_version : 32; - uint32_t major_version : 32; + uint32_t minor_version : U(32); + uint32_t major_version : U(32); } bits; } nvg_version_data_t; typedef union { uint64_t flat; struct nvg_power_perf_channel_t { - uint32_t perf_per_watt : 1; - uint32_t reserved_31_1 : 31; - uint32_t reserved_63_32 : 32; + uint32_t perf_per_watt : U(1); + uint32_t reserved_31_1 : U(31); + uint32_t reserved_63_32 : U(32); } bits; } nvg_power_perf_channel_t; typedef union { uint64_t flat; struct nvg_power_modes_channel_t { - uint32_t low_battery : 1; - uint32_t reserved_1_1 : 1; - uint32_t battery_save : 1; - uint32_t reserved_31_3 : 29; - uint32_t reserved_63_32 : 32; + uint32_t low_battery : U(1); + uint32_t reserved_1_1 : U(1); + uint32_t battery_save : U(1); + uint32_t reserved_31_3 : U(29); + uint32_t reserved_63_32 : U(32); } bits; } nvg_power_modes_channel_t; typedef union nvg_channel_1_data_u { uint64_t flat; struct nvg_channel_1_data_s { - uint32_t perf_per_watt_mode : 1; - uint32_t reserved_31_1 : 31; - uint32_t reserved_63_32 : 32; + uint32_t perf_per_watt_mode : U(1); + uint32_t reserved_31_1 : U(31); + uint32_t reserved_63_32 : U(32); } bits; } nvg_channel_1_data_t; typedef union { uint64_t flat; struct nvg_ccplex_cache_control_channel_t { - uint32_t gpu_ways : 5; - uint32_t reserved_7_5 : 3; - uint32_t gpu_only_ways : 5; - uint32_t reserved_31_13 : 19; - uint32_t reserved_63_32 : 32; + uint32_t gpu_ways : U(5); + uint32_t reserved_7_5 : U(3); + uint32_t gpu_only_ways : U(5); + uint32_t reserved_31_13 : U(19); + uint32_t reserved_63_32 : U(32); } bits; } nvg_ccplex_cache_control_channel_t; typedef union nvg_channel_2_data_u { uint64_t flat; struct nvg_channel_2_data_s { - uint32_t reserved_1_0 : 2; - uint32_t battery_saver_mode : 1; - uint32_t reserved_31_3 : 29; - uint32_t reserved_63_32 : 32; + uint32_t reserved_1_0 : U(2); + uint32_t battery_saver_mode : U(1); + uint32_t reserved_31_3 : U(29); + uint32_t reserved_63_32 : U(32); } bits; } nvg_channel_2_data_t; typedef union { uint64_t flat; struct nvg_wake_time_channel_t { - uint32_t wake_time : 32; - uint32_t reserved_63_32 : 32; + uint32_t wake_time : U(32); + uint32_t reserved_63_32 : U(32); } bits; } nvg_wake_time_channel_t; typedef union { uint64_t flat; struct nvg_cstate_info_channel_t { - uint32_t cluster_state : 3; - uint32_t reserved_6_3 : 4; - uint32_t update_cluster : 1; - uint32_t cg_cstate : 3; - uint32_t reserved_14_11 : 4; - uint32_t update_cg : 1; - uint32_t system_cstate : 4; - uint32_t reserved_22_20 : 3; - uint32_t update_system : 1; - uint32_t reserved_30_24 : 7; - uint32_t update_wake_mask : 1; + uint32_t cluster_state : U(3); + uint32_t reserved_6_3 : U(4); + uint32_t update_cluster : U(1); + uint32_t cg_cstate : U(3); + uint32_t reserved_14_11 : U(4); + uint32_t update_cg : U(1); + uint32_t system_cstate : U(4); + uint32_t reserved_22_20 : U(3); + uint32_t update_system : U(1); + uint32_t reserved_30_24 : U(7); + uint32_t update_wake_mask : U(1); union { - uint32_t flat : 32; + uint32_t flat : U(32); struct { - uint32_t vfiq : 1; - uint32_t virq : 1; - uint32_t fiq : 1; - uint32_t irq : 1; - uint32_t serror : 1; - uint32_t reserved_10_5 : 6; - uint32_t fiqout : 1; - uint32_t irqout : 1; - uint32_t reserved_31_13 : 19; + uint32_t vfiq : U(1); + uint32_t virq : U(1); + uint32_t fiq : U(1); + uint32_t irq : U(1); + uint32_t serror : U(1); + uint32_t reserved_10_5 : U(6); + uint32_t fiqout : U(1); + uint32_t irqout : U(1); + uint32_t reserved_31_13 : U(19); } carmel; } wake_mask; } bits; @@ -242,183 +243,182 @@ typedef union { typedef union { uint64_t flat; struct nvg_lower_bound_channel_t { - uint32_t crossover_value : 32; - uint32_t reserved_63_32 : 32; + uint32_t crossover_value : U(32); + uint32_t reserved_63_32 : U(32); } bits; } nvg_lower_bound_channel_t; typedef union { uint64_t flat; struct nvg_cstate_stat_query_channel_t { - uint32_t unit_id : 4; - uint32_t reserved_15_4 : 12; - uint32_t stat_id : 16; - uint32_t reserved_63_32 : 32; + uint32_t unit_id : U(4); + uint32_t reserved_15_4 : U(12); + uint32_t stat_id : U(16); + uint32_t reserved_63_32 : U(32); } bits; } nvg_cstate_stat_query_channel_t; typedef union { uint64_t flat; struct nvg_num_cores_channel_t { - uint32_t num_cores : 4; - uint32_t reserved_31_4 : 28; - uint32_t reserved_63_32 : 32; + uint32_t num_cores : U(4); + uint32_t reserved_31_4 : U(28); + uint32_t reserved_63_32 : U(32); } bits; } nvg_num_cores_channel_t; typedef union { uint64_t flat; struct nvg_unique_logical_id_channel_t { - uint32_t unique_core_id : 3; - uint32_t reserved_31_3 : 29; - uint32_t reserved_63_32 : 32; + uint32_t unique_core_id : U(3); + uint32_t reserved_31_3 : U(29); + uint32_t reserved_63_32 : U(32); } bits; } nvg_unique_logical_id_channel_t; typedef union { uint64_t flat; struct nvg_logical_to_physical_mappings_channel_t { - uint32_t lcore0_pcore_id : 4; - uint32_t lcore1_pcore_id : 4; - uint32_t lcore2_pcore_id : 4; - uint32_t lcore3_pcore_id : 4; - uint32_t lcore4_pcore_id : 4; - uint32_t lcore5_pcore_id : 4; - uint32_t lcore6_pcore_id : 4; - uint32_t lcore7_pcore_id : 4; - uint32_t reserved_63_32 : 32; + uint32_t lcore0_pcore_id : U(4); + uint32_t lcore1_pcore_id : U(4); + uint32_t lcore2_pcore_id : U(4); + uint32_t lcore3_pcore_id : U(4); + uint32_t lcore4_pcore_id : U(4); + uint32_t lcore5_pcore_id : U(4); + uint32_t lcore6_pcore_id : U(4); + uint32_t lcore7_pcore_id : U(4); + uint32_t reserved_63_32 : U(32); } bits; } nvg_logical_to_physical_mappings_channel_t; typedef union { uint64_t flat; struct nvg_logical_to_mpidr_channel_write_t { - uint32_t lcore_id : 3; - uint32_t reserved_31_3 : 29; - uint32_t reserved_63_32 : 32; + uint32_t lcore_id : U(3); + uint32_t reserved_31_3 : U(29); + uint32_t reserved_63_32 : U(32); } write; struct nvg_logical_to_mpidr_channel_read_t { - uint32_t mpidr : 32; - uint32_t reserved_63_32 : 32; + uint32_t mpidr : U(32); + uint32_t reserved_63_32 : U(32); } read; } nvg_logical_to_mpidr_channel_t; typedef union { uint64_t flat; struct nvg_is_sc7_allowed_channel_t { - uint32_t is_sc7_allowed : 1; - uint32_t reserved_31_1 : 31; - uint32_t reserved_63_32 : 32; + uint32_t is_sc7_allowed : U(1); + uint32_t reserved_31_1 : U(31); + uint32_t reserved_63_32 : U(32); } bits; } nvg_is_sc7_allowed_channel_t; typedef union { uint64_t flat; struct nvg_core_online_channel_t { - uint32_t core_id : 4; - uint32_t reserved_31_4 : 28; - uint32_t reserved_63_32 : 32; + uint32_t core_id : U(4); + uint32_t reserved_31_4 : U(28); + uint32_t reserved_63_32 : U(32); } bits; } nvg_core_online_channel_t; typedef union { uint64_t flat; struct nvg_cc3_control_channel_t { - uint32_t freq_req : 9; - uint32_t reserved_30_9 : 22; - uint32_t enable : 1; - uint32_t reserved_63_32 : 32; + uint32_t freq_req : U(9); + uint32_t reserved_30_9 : U(22); + uint32_t enable : U(1); + uint32_t reserved_63_32 : U(32); } bits; } nvg_cc3_control_channel_t; typedef enum { - TEGRA_NVG_CHANNEL_UPDATE_GSC_ALL = 0, - TEGRA_NVG_CHANNEL_UPDATE_GSC_NVDEC = 1, - TEGRA_NVG_CHANNEL_UPDATE_GSC_WPR1 = 2, - TEGRA_NVG_CHANNEL_UPDATE_GSC_WPR2 = 3, - TEGRA_NVG_CHANNEL_UPDATE_GSC_TSECA = 4, - TEGRA_NVG_CHANNEL_UPDATE_GSC_TSECB = 5, - TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP = 6, - TEGRA_NVG_CHANNEL_UPDATE_GSC_APE = 7, - TEGRA_NVG_CHANNEL_UPDATE_GSC_SPE = 8, - TEGRA_NVG_CHANNEL_UPDATE_GSC_SCE = 9, - TEGRA_NVG_CHANNEL_UPDATE_GSC_APR = 10, - TEGRA_NVG_CHANNEL_UPDATE_GSC_TZRAM = 11, - TEGRA_NVG_CHANNEL_UPDATE_GSC_IPC_SE_TSEC = 12, - TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP_TO_RCE = 13, - TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP_TO_MCE = 14, - TEGRA_NVG_CHANNEL_UPDATE_GSC_SE_SC7 = 15, - TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP_TO_SPE = 16, - TEGRA_NVG_CHANNEL_UPDATE_GSC_RCE = 17, - TEGRA_NVG_CHANNEL_UPDATE_GSC_CPU_TZ_TO_BPMP = 18, - TEGRA_NVG_CHANNEL_UPDATE_GSC_VM_ENCR1 = 19, - TEGRA_NVG_CHANNEL_UPDATE_GSC_CPU_NS_TO_BPMP = 20, - TEGRA_NVG_CHANNEL_UPDATE_GSC_OEM_SC7 = 21, - TEGRA_NVG_CHANNEL_UPDATE_GSC_IPC_SE_SPE_SCE_BPMP = 22, - TEGRA_NVG_CHANNEL_UPDATE_GSC_SC7_RESUME_FW = 23, - TEGRA_NVG_CHANNEL_UPDATE_GSC_CAMERA_TASKLIST = 24, - TEGRA_NVG_CHANNEL_UPDATE_GSC_XUSB = 25, - TEGRA_NVG_CHANNEL_UPDATE_GSC_CV = 26, - TEGRA_NVG_CHANNEL_UPDATE_GSC_VM_ENCR2 = 27, - TEGRA_NVG_CHANNEL_UPDATE_GSC_HYPERVISOR_SW = 28, - TEGRA_NVG_CHANNEL_UPDATE_GSC_SMMU_PAGETABLES = 29, - TEGRA_NVG_CHANNEL_UPDATE_GSC_30 = 30, - TEGRA_NVG_CHANNEL_UPDATE_GSC_31 = 31, - TEGRA_NVG_CHANNEL_UPDATE_GSC_TZ_DRAM = 32, - TEGRA_NVG_CHANNEL_UPDATE_GSC_NVLINK = 33, - TEGRA_NVG_CHANNEL_UPDATE_GSC_SBS = 34, - TEGRA_NVG_CHANNEL_UPDATE_GSC_VPR = 35, + TEGRA_NVG_CHANNEL_UPDATE_GSC_ALL = U(0), + TEGRA_NVG_CHANNEL_UPDATE_GSC_NVDEC = U(1), + TEGRA_NVG_CHANNEL_UPDATE_GSC_WPR1 = U(2), + TEGRA_NVG_CHANNEL_UPDATE_GSC_WPR2 = U(3), + TEGRA_NVG_CHANNEL_UPDATE_GSC_TSECA = U(4), + TEGRA_NVG_CHANNEL_UPDATE_GSC_TSECB = U(5), + TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP = U(6), + TEGRA_NVG_CHANNEL_UPDATE_GSC_APE = U(7), + TEGRA_NVG_CHANNEL_UPDATE_GSC_SPE = U(8), + TEGRA_NVG_CHANNEL_UPDATE_GSC_SCE = U(9), + TEGRA_NVG_CHANNEL_UPDATE_GSC_APR = U(10), + TEGRA_NVG_CHANNEL_UPDATE_GSC_TZRAM = U(11), + TEGRA_NVG_CHANNEL_UPDATE_GSC_IPC_SE_TSEC = U(12), + TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP_TO_RCE = U(13), + TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP_TO_MCE = U(14), + TEGRA_NVG_CHANNEL_UPDATE_GSC_SE_SC7 = U(15), + TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP_TO_SPE = U(16), + TEGRA_NVG_CHANNEL_UPDATE_GSC_RCE = U(17), + TEGRA_NVG_CHANNEL_UPDATE_GSC_CPU_TZ_TO_BPMP = U(18), + TEGRA_NVG_CHANNEL_UPDATE_GSC_VM_ENCR1 = U(19), + TEGRA_NVG_CHANNEL_UPDATE_GSC_CPU_NS_TO_BPMP = U(20), + TEGRA_NVG_CHANNEL_UPDATE_GSC_OEM_SC7 = U(21), + TEGRA_NVG_CHANNEL_UPDATE_GSC_IPC_SE_SPE_SCE_BPMP = U(22), + TEGRA_NVG_CHANNEL_UPDATE_GSC_SC7_RESUME_FW = U(23), + TEGRA_NVG_CHANNEL_UPDATE_GSC_CAMERA_TASKLIST = U(24), + TEGRA_NVG_CHANNEL_UPDATE_GSC_XUSB = U(25), + TEGRA_NVG_CHANNEL_UPDATE_GSC_CV = U(26), + TEGRA_NVG_CHANNEL_UPDATE_GSC_VM_ENCR2 = U(27), + TEGRA_NVG_CHANNEL_UPDATE_GSC_HYPERVISOR_SW = U(28), + TEGRA_NVG_CHANNEL_UPDATE_GSC_SMMU_PAGETABLES = U(29), + TEGRA_NVG_CHANNEL_UPDATE_GSC_30 = U(30), + TEGRA_NVG_CHANNEL_UPDATE_GSC_31 = U(31), + TEGRA_NVG_CHANNEL_UPDATE_GSC_TZ_DRAM = U(32), + TEGRA_NVG_CHANNEL_UPDATE_GSC_NVLINK = U(33), + TEGRA_NVG_CHANNEL_UPDATE_GSC_SBS = U(34), + TEGRA_NVG_CHANNEL_UPDATE_GSC_VPR = U(35), TEGRA_NVG_CHANNEL_UPDATE_GSC_LAST_INDEX } tegra_nvg_channel_update_gsc_gsc_enum_t; typedef union { uint64_t flat; struct nvg_update_ccplex_gsc_channel_t { - uint32_t gsc_enum : 16; - uint32_t reserved_31_16 : 16; - uint32_t reserved_63_32 : 32; + uint32_t gsc_enum : U(16); + uint32_t reserved_31_16 : U(16); + uint32_t reserved_63_32 : U(32); } bits; } nvg_update_ccplex_gsc_channel_t; typedef union { uint64_t flat; struct nvg_security_config_channel_t { - uint32_t strict_checking_enabled : 1; - uint32_t strict_checking_locked : 1; - uint32_t reserved_31_2 : 30; - uint32_t reserved_63_32 : 32; + uint32_t strict_checking_enabled : U(1); + uint32_t strict_checking_locked : U(1); + uint32_t reserved_31_2 : U(30); + uint32_t reserved_63_32 : U(32); } bits; } nvg_security_config_t; typedef union { uint64_t flat; struct nvg_shutdown_channel_t { - uint32_t reboot : 1; - uint32_t reserved_31_1 : 31; - uint32_t reserved_63_32 : 32; + uint32_t reboot : U(1); + uint32_t reserved_31_1 : U(31); + uint32_t reserved_63_32 : U(32); } bits; } nvg_shutdown_t; typedef union { uint64_t flat; struct nvg_debug_config_channel_t { - uint32_t enter_debug_state_on_mca : 1; - uint32_t reserved_31_1 : 31; - uint32_t reserved_63_32 : 32; + uint32_t enter_debug_state_on_mca : U(1); + uint32_t reserved_31_1 : U(31); + uint32_t reserved_63_32 : U(32); } bits; } nvg_debug_config_t; typedef union { uint64_t flat; struct nvg_hsm_error_ctrl_channel_t { - uint32_t uncorr : 1; - uint32_t corr : 1; - uint32_t reserved_31_2 : 30; - uint32_t reserved_63_32 : 32; + uint32_t uncorr : U(1); + uint32_t corr : U(1); + uint32_t reserved_31_2 : U(30); + uint32_t reserved_63_32 : U(32); } bits; } nvg_hsm_error_ctrl_channel_t; extern nvg_debug_config_t nvg_debug_config; -#endif - +#endif /* T194_NVG_H */ diff --git a/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c b/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c index 1012cdf11..ef740a143 100644 --- a/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c +++ b/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c @@ -15,8 +15,8 @@ #include #include -#define ID_AFR0_EL1_CACHE_OPS_SHIFT 12 -#define ID_AFR0_EL1_CACHE_OPS_MASK 0xFU +#define ID_AFR0_EL1_CACHE_OPS_SHIFT U(12) +#define ID_AFR0_EL1_CACHE_OPS_MASK U(0xF) /* * Reports the major and minor version of this interface. * @@ -209,7 +209,7 @@ void nvg_enable_strict_checking_mode(void) uint64_t params = (uint64_t)(STRICT_CHECKING_ENABLED_SET | STRICT_CHECKING_LOCKED_SET); - nvg_set_request_data(TEGRA_NVG_CHANNEL_SECURITY_CONFIG, params); + nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_SECURITY_CONFIG, params); } #endif @@ -221,7 +221,8 @@ void nvg_enable_strict_checking_mode(void) void nvg_system_reboot(void) { /* issue command for reboot */ - nvg_set_request_data(TEGRA_NVG_CHANNEL_SHUTDOWN, TEGRA_NVG_REBOOT); + nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_SHUTDOWN, + (uint64_t)TEGRA_NVG_REBOOT); } /* @@ -232,5 +233,6 @@ void nvg_system_reboot(void) void nvg_system_shutdown(void) { /* issue command for shutdown */ - nvg_set_request_data(TEGRA_NVG_CHANNEL_SHUTDOWN, TEGRA_NVG_SHUTDOWN); + nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_SHUTDOWN, + (uint64_t)TEGRA_NVG_SHUTDOWN); } -- cgit v1.2.3 From 8ad1e475df8e752bb200aa107690da942ce56121 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Wed, 6 Jun 2018 17:26:10 -0700 Subject: Tegra194: remove support for simulated system suspend This patch removes support for simulated system suspend for Tegra194 platforms as we have actual silicon platforms that support this feature now. Change-Id: I9ed1b002886fed7bbc3d890a82d6cad67e900bae Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/soc/t194/plat_psci_handlers.c | 72 +++++++------------------ plat/nvidia/tegra/soc/t194/plat_sip_calls.c | 21 +------- 2 files changed, 20 insertions(+), 73 deletions(-) diff --git a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c index 518eb25de..144e41885 100644 --- a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c @@ -44,14 +44,6 @@ static struct t19x_psci_percpu_data { uint32_t wake_time; } __aligned(CACHE_WRITEBACK_GRANULE) t19x_percpu_data[PLATFORM_CORE_COUNT]; -/* - * tegra_fake_system_suspend acts as a boolean var controlling whether - * we are going to take fake system suspend code or normal system suspend code - * path. This variable is set inside the sip call handlers, when the kernel - * requests an SIP call to set the suspend debug flags. - */ -bool tegra_fake_system_suspend; - int32_t tegra_soc_validate_power_state(uint32_t power_state, psci_power_state_t *req_state) { @@ -171,30 +163,27 @@ int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) assert(ret == 0); } - if (!tegra_fake_system_suspend) { + /* Prepare for system suspend */ + mce_update_cstate_info(&sc7_cstate_info); - /* Prepare for system suspend */ - mce_update_cstate_info(&sc7_cstate_info); - - do { - val = (uint32_t)mce_command_handler( - (uint32_t)MCE_CMD_IS_SC7_ALLOWED, - (uint32_t)TEGRA_NVG_CORE_C7, - MCE_CORE_SLEEP_TIME_INFINITE, - 0U); - } while (val == 0U); - - /* Instruct the MCE to enter system suspend state */ - ret = mce_command_handler( - (uint64_t)MCE_CMD_ENTER_CSTATE, - (uint64_t)TEGRA_NVG_CORE_C7, + do { + val = (uint32_t)mce_command_handler( + (uint32_t)MCE_CMD_IS_SC7_ALLOWED, + (uint32_t)TEGRA_NVG_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0U); - assert(ret == 0); - - /* set system suspend state for house-keeping */ - tegra194_set_system_suspend_entry(); - } + } while (val == 0U); + + /* Instruct the MCE to enter system suspend state */ + ret = mce_command_handler( + (uint64_t)MCE_CMD_ENTER_CSTATE, + (uint64_t)TEGRA_NVG_CORE_C7, + MCE_CORE_SLEEP_TIME_INFINITE, + 0U); + assert(ret == 0); + + /* set system suspend state for house-keeping */ + tegra194_set_system_suspend_entry(); } else { ; /* do nothing */ } @@ -301,7 +290,6 @@ int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_sta uint8_t stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL] & TEGRA194_STATE_ID_MASK; uint64_t val; - u_register_t ns_sctlr_el1; if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) { /* @@ -313,30 +301,6 @@ int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_sta tegra194_get_cpu_reset_handler_size(); memcpy((void *)(uintptr_t)val, (void *)(uintptr_t)BL31_BASE, (uintptr_t)&__BL31_END__ - (uintptr_t)BL31_BASE); - - /* - * In fake suspend mode, ensure that the loopback procedure - * towards system suspend exit is started, instead of calling - * WFI. This is done by disabling both MMU's of EL1 & El3 - * and calling tegra_secure_entrypoint(). - */ - if (tegra_fake_system_suspend) { - - /* - * Disable EL1's MMU. - */ - ns_sctlr_el1 = read_sctlr_el1(); - ns_sctlr_el1 &= (~((u_register_t)SCTLR_M_BIT)); - write_sctlr_el1(ns_sctlr_el1); - - /* - * Disable MMU to power up the CPU in a "clean" - * state - */ - disable_mmu_el3(); - tegra_secure_entrypoint(); - panic(); - } } return PSCI_E_SUCCESS; diff --git a/plat/nvidia/tegra/soc/t194/plat_sip_calls.c b/plat/nvidia/tegra/soc/t194/plat_sip_calls.c index 8873358cd..33694a16d 100644 --- a/plat/nvidia/tegra/soc/t194/plat_sip_calls.c +++ b/plat/nvidia/tegra/soc/t194/plat_sip_calls.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -18,12 +18,9 @@ #include #include -extern bool tegra_fake_system_suspend; - /******************************************************************************* * Tegra194 SiP SMCs ******************************************************************************/ -#define TEGRA_SIP_ENABLE_FAKE_SYSTEM_SUSPEND 0xC2FFFE03U /******************************************************************************* * This function is responsible for handling all T194 SiP calls @@ -39,25 +36,11 @@ int32_t plat_sip_handler(uint32_t smc_fid, { int32_t ret = -ENOTSUP; + (void)smc_fid; (void)x1; (void)x4; (void)cookie; (void)flags; - if (smc_fid == TEGRA_SIP_ENABLE_FAKE_SYSTEM_SUSPEND) { - /* - * System suspend mode is set if the platform ATF is - * running on VDK and there is a debug SIP call. This mode - * ensures that the debug path is exercised, instead of - * regular code path to suit the pre-silicon platform needs. - * This includes replacing the call to WFI, with calls to - * system suspend exit procedures. - */ - if (tegra_platform_is_virt_dev_kit()) { - tegra_fake_system_suspend = true; - ret = 0; - } - } - return ret; } -- cgit v1.2.3 From 029b45d1d41b24bf4d1fa99a4c95f04cea517e1a Mon Sep 17 00:00:00 2001 From: Pritesh Raithatha Date: Thu, 31 May 2018 12:06:15 +0530 Subject: Tegra186: memctrl: lock stream id security config Tegra186 is in production so lock stream id security configs for all the clients. Change-Id: I64bdd5a9f12319a543291bfdbbfc1559d7a44113 Signed-off-by: Pritesh Raithatha --- plat/nvidia/tegra/soc/t186/plat_memctrl.c | 88 +++++++++++++++---------------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/plat/nvidia/tegra/soc/t186/plat_memctrl.c b/plat/nvidia/tegra/soc/t186/plat_memctrl.c index df943969e..4ca5e77ad 100644 --- a/plat/nvidia/tegra/soc/t186/plat_memctrl.c +++ b/plat/nvidia/tegra/soc/t186/plat_memctrl.c @@ -95,71 +95,71 @@ const static uint32_t tegra186_streamid_override_regs[] = { ******************************************************************************/ const static mc_streamid_security_cfg_t tegra186_streamid_sec_cfgs[] = { mc_make_sec_cfg(SCEW, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(AFIR, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(AFIW, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(NVDISPLAYR1, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(AFIR, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(AFIW, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(NVDISPLAYR1, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(XUSB_DEVR, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(VICSRD1, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(NVENCSWR, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(TSECSRDB, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(VICSRD1, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(NVENCSWR, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(TSECSRDB, NON_SECURE, NO_OVERRIDE, DISABLE), mc_make_sec_cfg(AXISW, SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(SDMMCWAB, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(AONDMAW, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(SDMMCWAB, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(AONDMAW, NON_SECURE, NO_OVERRIDE, DISABLE), mc_make_sec_cfg(GPUSWR2, SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(SATAW, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(UFSHCW, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(SDMMCR, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(SATAW, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(UFSHCW, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(SDMMCR, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(SCEDMAW, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(UFSHCR, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(SDMMCWAA, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(SESWR, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(MPCORER, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(PTCR, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(UFSHCR, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(SDMMCWAA, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(SESWR, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(MPCORER, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(PTCR, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(BPMPW, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(ETRW, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(ETRW, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(GPUSRD, SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(VICSWR, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(VICSWR, NON_SECURE, NO_OVERRIDE, DISABLE), mc_make_sec_cfg(SCEDMAR, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(HDAW, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(HDAW, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(ISPWA, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(EQOSW, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(EQOSW, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(XUSB_HOSTW, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(TSECSWR, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(SDMMCRAA, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(TSECSWR, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(SDMMCRAA, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(VIW, NON_SECURE, OVERRIDE, ENABLE), mc_make_sec_cfg(AXISR, SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(SDMMCW, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(SDMMCW, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(BPMPDMAW, NON_SECURE, NO_OVERRIDE, DISABLE), mc_make_sec_cfg(ISPRA, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(NVDECSWR, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(NVDECSWR, NON_SECURE, NO_OVERRIDE, DISABLE), mc_make_sec_cfg(XUSB_DEVW, NON_SECURE, OVERRIDE, ENABLE), mc_make_sec_cfg(NVDECSRD, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(MPCOREW, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(NVDISPLAYR, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(MPCOREW, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(NVDISPLAYR, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(BPMPDMAR, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(NVJPGSWR, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(NVJPGSWR, NON_SECURE, NO_OVERRIDE, DISABLE), mc_make_sec_cfg(NVDECSRD1, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(TSECSRD, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(NVJPGSRD, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(SDMMCWA, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(TSECSRD, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(NVJPGSRD, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(SDMMCWA, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(SCER, NON_SECURE, NO_OVERRIDE, DISABLE), mc_make_sec_cfg(XUSB_HOSTR, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(VICSRD, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(AONDMAR, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(AONW, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(SDMMCRA, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(HOST1XDMAR, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(EQOSR, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(SATAR, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(VICSRD, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(AONDMAR, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(AONW, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(SDMMCRA, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(HOST1XDMAR, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(EQOSR, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(SATAR, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(BPMPR, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(HDAR, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(SDMMCRAB, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(ETRR, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(AONR, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(SESRD, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(NVENCSRD, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(HDAR, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(SDMMCRAB, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(ETRR, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(AONR, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(SESRD, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(NVENCSRD, NON_SECURE, NO_OVERRIDE, DISABLE), mc_make_sec_cfg(GPUSWR, SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(TSECSWRB, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(TSECSWRB, NON_SECURE, NO_OVERRIDE, DISABLE), mc_make_sec_cfg(ISPWB, NON_SECURE, OVERRIDE, ENABLE), mc_make_sec_cfg(GPUSRD2, SECURE, NO_OVERRIDE, DISABLE), mc_make_sec_cfg(APEDMAW, NON_SECURE, NO_OVERRIDE, DISABLE), -- cgit v1.2.3 From 77fc46971eb7d83ac66071aca7c684e626e8a2f1 Mon Sep 17 00:00:00 2001 From: Hadi Asyrafi Date: Mon, 30 Dec 2019 16:00:30 +0800 Subject: intel: Change boot source selection Platform handoff structure no longer includes boot source selection. Hence, those settings can now be configured through socfpga_plat_def.h. Signed-off-by: Hadi Asyrafi Change-Id: If7ec6a03bb25156a6670ebf8f77105c370b553f6 --- plat/intel/soc/agilex/bl2_plat_setup.c | 3 +-- plat/intel/soc/agilex/include/socfpga_plat_def.h | 1 + plat/intel/soc/common/include/socfpga_handoff.h | 1 - plat/intel/soc/stratix10/bl2_plat_setup.c | 3 +-- plat/intel/soc/stratix10/include/socfpga_plat_def.h | 3 ++- 5 files changed, 5 insertions(+), 6 deletions(-) diff --git a/plat/intel/soc/agilex/bl2_plat_setup.c b/plat/intel/soc/agilex/bl2_plat_setup.c index 9587d4859..f32820777 100644 --- a/plat/intel/soc/agilex/bl2_plat_setup.c +++ b/plat/intel/soc/agilex/bl2_plat_setup.c @@ -46,7 +46,7 @@ const mmap_region_t agilex_plat_mmap[] = { {0}, }; -boot_source_type boot_source; +boot_source_type boot_source = BOOT_SOURCE; void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1, u_register_t x2, u_register_t x4) @@ -59,7 +59,6 @@ void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1, if (socfpga_get_handoff(&reverse_handoff_ptr)) return; config_pinmux(&reverse_handoff_ptr); - boot_source = reverse_handoff_ptr.boot_source; config_clkmgr_handoff(&reverse_handoff_ptr); enable_nonsecure_access(); diff --git a/plat/intel/soc/agilex/include/socfpga_plat_def.h b/plat/intel/soc/agilex/include/socfpga_plat_def.h index b4e09210f..6c9d81ceb 100644 --- a/plat/intel/soc/agilex/include/socfpga_plat_def.h +++ b/plat/intel/soc/agilex/include/socfpga_plat_def.h @@ -12,6 +12,7 @@ /* Platform Setting */ #define PLATFORM_MODEL PLAT_SOCFPGA_AGILEX +#define BOOT_SOURCE BOOT_SOURCE_SDMMC /* Register Mapping */ #define SOCFPGA_MMC_REG_BASE 0xff808000 diff --git a/plat/intel/soc/common/include/socfpga_handoff.h b/plat/intel/soc/common/include/socfpga_handoff.h index 889d13767..ba0f7f377 100644 --- a/plat/intel/soc/common/include/socfpga_handoff.h +++ b/plat/intel/soc/common/include/socfpga_handoff.h @@ -125,7 +125,6 @@ typedef struct handoff_t { uint32_t misc_magic; uint32_t misc_length; uint32_t _pad_0x618_0x620[2]; - uint32_t boot_source; } handoff; int verify_handoff_image(handoff *hoff_ptr, handoff *reverse_hoff_ptr); diff --git a/plat/intel/soc/stratix10/bl2_plat_setup.c b/plat/intel/soc/stratix10/bl2_plat_setup.c index 7d183db0d..78ca253e7 100644 --- a/plat/intel/soc/stratix10/bl2_plat_setup.c +++ b/plat/intel/soc/stratix10/bl2_plat_setup.c @@ -45,7 +45,7 @@ const mmap_region_t plat_stratix10_mmap[] = { {0}, }; -boot_source_type boot_source; +boot_source_type boot_source = BOOT_SOURCE; void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1, u_register_t x2, u_register_t x4) @@ -58,7 +58,6 @@ void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1, if (socfpga_get_handoff(&reverse_handoff_ptr)) return; config_pinmux(&reverse_handoff_ptr); - boot_source = reverse_handoff_ptr.boot_source; config_clkmgr_handoff(&reverse_handoff_ptr); enable_nonsecure_access(); diff --git a/plat/intel/soc/stratix10/include/socfpga_plat_def.h b/plat/intel/soc/stratix10/include/socfpga_plat_def.h index 9dc51514c..a2bd57b08 100644 --- a/plat/intel/soc/stratix10/include/socfpga_plat_def.h +++ b/plat/intel/soc/stratix10/include/socfpga_plat_def.h @@ -10,7 +10,8 @@ #include /* Platform Setting */ -#define PLATFORM_MODEL PLAT_SOCFPGA_STRATIX10 +#define PLATFORM_MODEL PLAT_SOCFPGA_STRATIX10 +#define BOOT_SOURCE BOOT_SOURCE_SDMMC /* Register Mapping */ #define SOCFPGA_MMC_REG_BASE 0xff808000 -- cgit v1.2.3 From 8d52e16b45f1d4fbb16ea3a512e9bd56666e4f8e Mon Sep 17 00:00:00 2001 From: Imre Kis Date: Mon, 3 Feb 2020 14:48:21 +0100 Subject: doc: Remove backquotes from external hyperlinks Since Sphinx 2.3.0 backquotes are replaced to \textasciigrave{} during building latexpdf. Using this element in a \sphinxhref{} breaks the build. In order to avoid this error backquotes must not be used in external hyperlinks. Signed-off-by: Imre Kis Change-Id: Ie3cf454427e3d5a7b7f9829b42be45aebda7f0dd --- docs/components/exception-handling.rst | 4 ++-- docs/getting_started/build-options.rst | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/components/exception-handling.rst b/docs/components/exception-handling.rst index 3f386854f..e330a62a4 100644 --- a/docs/components/exception-handling.rst +++ b/docs/components/exception-handling.rst @@ -467,7 +467,7 @@ SMCs from Non-secure world are synchronous exceptions, and are mechanisms for Non-secure world to request Secure services. They're broadly classified as *Fast* or *Yielding* (see `SMCCC`__). -.. __: `http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html` +.. __: http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html - *Fast* SMCs are atomic from the caller's point of view. I.e., they return to the caller only when the Secure world has finished serving the request. @@ -621,6 +621,6 @@ The |EHF| has the following limitations: -------------- -*Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.* +*Copyright (c) 2018-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 diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 2f44fe817..e9747afbe 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -310,8 +310,8 @@ Common build options EL1 for handling. The default value of this option is ``0``, which means the Group 0 interrupts are assumed to be handled by Secure EL1. - .. __: `platform-interrupt-controller-API.rst` - .. __: `interrupt-framework-design.rst` + .. __: platform-interrupt-controller-API.rst + .. __: interrupt-framework-design.rst - ``HANDLE_EA_EL3_FIRST``: When set to ``1``, External Aborts and SError Interrupts will be always trapped in EL3 i.e. in BL31 at runtime. When set to @@ -657,4 +657,4 @@ commands can be used: -------------- -*Copyright (c) 2019, Arm Limited. All rights reserved.* +*Copyright (c) 2019-2020, Arm Limited. All rights reserved.* -- cgit v1.2.3 From a416325bc135fde6c38ef5b2433ee60c20ef6278 Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Mon, 3 Feb 2020 15:58:16 +0100 Subject: BL2: Print ID of images we fail loading When Trusted Boot is enabled, images are loaded and authenticated following up the root of trust. This means that between the initial console message saying that an image is being loaded, and the final one where it says that it failed to load it, BL2 may print several messages about other images on the chain of trust being loaded, thus it is not always clear which image we failed loading at the end of the day. Change-Id: I3b189ec9d12c2a6203d16c8dbbb4fc117639c3c1 Signed-off-by: Sandrine Bailleux --- bl2/bl2_image_load_v2.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bl2/bl2_image_load_v2.c b/bl2/bl2_image_load_v2.c index dd53e1d2b..1fbdbabac 100644 --- a/bl2/bl2_image_load_v2.c +++ b/bl2/bl2_image_load_v2.c @@ -68,7 +68,8 @@ struct entry_point_info *bl2_load_images(void) err = load_auth_image(bl2_node_info->image_id, bl2_node_info->image_info); if (err) { - ERROR("BL2: Failed to load image (%i)\n", err); + ERROR("BL2: Failed to load image id %d (%i)\n", + bl2_node_info->image_id, err); plat_error_handler(err); } } else { -- cgit v1.2.3 From 47939f67252edc6295268dfebff24b5450eaba85 Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Mon, 6 Jan 2020 15:45:22 +0100 Subject: coverity: debugfs devfip remove comparisons to LONG_MAX CID 353228: Integer handling issues (CONSTANT_EXPRESSION_RESULT) The checks on size and offset_address in get_entry always resolve to false provided those fields are long long int and cannot be greater than LONG_MAX. Signed-off-by: Olivier Deprez Change-Id: I0fac485a39ac4a40ae8c0d25a706ad74c795e130 --- lib/debugfs/devfip.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/debugfs/devfip.c b/lib/debugfs/devfip.c index 5581b219f..fc14e707e 100644 --- a/lib/debugfs/devfip.c +++ b/lib/debugfs/devfip.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Arm Limited. All rights reserved. + * Copyright (c) 2019-2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -103,10 +103,6 @@ static int get_entry(chan_t *c, struct fip_entry *entry) return -1; } - if ((entry->size > LONG_MAX) || (entry->offset_address > LONG_MAX)) { - return -1; - } - if (entry->size == 0) { return 0; } -- cgit v1.2.3 From e6937287e4963e0e729dd19d08f44c52c5483382 Mon Sep 17 00:00:00 2001 From: Zelalem Date: Mon, 3 Feb 2020 14:56:42 -0600 Subject: Coverity: remove unnecessary header file includes This patch removes unnecessary header file includes discovered by Coverity HFA option. Change-Id: I2827c37c1c24866c87db0e206e681900545925d4 Signed-off-by: Zelalem --- bl1/tbbr/tbbr_img_desc.c | 3 +-- bl31/bl31_context_mgmt.c | 3 +-- drivers/arm/ccn/ccn.c | 3 +-- drivers/arm/gic/v2/gicv2_helpers.c | 3 +-- drivers/auth/img_parser_mod.c | 3 +-- lib/cpus/errata_report.c | 3 +-- lib/el3_runtime/aarch32/context_mgmt.c | 4 +--- lib/el3_runtime/aarch64/context_mgmt.c | 2 -- lib/optee/optee_utils.c | 5 +---- plat/arm/board/fvp/fvp_bl2_setup.c | 4 +--- plat/arm/board/fvp/fvp_err.c | 3 +-- plat/arm/board/fvp/fvp_pm.c | 4 +--- plat/arm/board/juno/juno_err.c | 3 +-- plat/arm/common/aarch32/arm_bl2_mem_params_desc.c | 3 +-- plat/arm/common/aarch64/arm_bl2_mem_params_desc.c | 3 +-- plat/arm/common/aarch64/execution_state_switch.c | 3 +-- plat/arm/common/arm_bl31_setup.c | 3 +-- plat/arm/common/arm_common.c | 1 - plat/arm/common/arm_dyn_cfg_helpers.c | 3 +-- plat/arm/common/arm_nor_psci_mem_protect.c | 3 +-- plat/arm/common/arm_pm.c | 3 +-- plat/arm/common/sp_min/arm_sp_min_setup.c | 3 +-- plat/arm/css/common/css_pm.c | 4 +--- plat/common/plat_bl_common.c | 3 +-- 24 files changed, 22 insertions(+), 53 deletions(-) diff --git a/bl1/tbbr/tbbr_img_desc.c b/bl1/tbbr/tbbr_img_desc.c index e8df73d47..48367126c 100644 --- a/bl1/tbbr/tbbr_img_desc.c +++ b/bl1/tbbr/tbbr_img_desc.c @@ -1,12 +1,11 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include -#include #include #include diff --git a/bl31/bl31_context_mgmt.c b/bl31/bl31_context_mgmt.c index d41979fa7..9175ee35d 100644 --- a/bl31/bl31_context_mgmt.c +++ b/bl31/bl31_context_mgmt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,7 +11,6 @@ #include #include #include -#include /******************************************************************************* * This function returns a pointer to the most recent 'cpu_context' structure diff --git a/drivers/arm/ccn/ccn.c b/drivers/arm/ccn/ccn.c index d0c5abc7c..5b13250bc 100644 --- a/drivers/arm/ccn/ccn.c +++ b/drivers/arm/ccn/ccn.c @@ -1,11 +1,10 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include -#include #include #include diff --git a/drivers/arm/gic/v2/gicv2_helpers.c b/drivers/arm/gic/v2/gicv2_helpers.c index 6739a782c..751316c03 100644 --- a/drivers/arm/gic/v2/gicv2_helpers.c +++ b/drivers/arm/gic/v2/gicv2_helpers.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,7 +7,6 @@ #include #include -#include #include #include #include diff --git a/drivers/auth/img_parser_mod.c b/drivers/auth/img_parser_mod.c index c4688f867..535695d82 100644 --- a/drivers/auth/img_parser_mod.c +++ b/drivers/auth/img_parser_mod.c @@ -1,11 +1,10 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include -#include #include #include #include diff --git a/lib/cpus/errata_report.c b/lib/cpus/errata_report.c index f43b2176d..5d1e3c5cc 100644 --- a/lib/cpus/errata_report.c +++ b/lib/cpus/errata_report.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -14,7 +14,6 @@ #include #include #include -#include #ifdef IMAGE_BL1 # define BL_STRING "BL1" diff --git a/lib/el3_runtime/aarch32/context_mgmt.c b/lib/el3_runtime/aarch32/context_mgmt.c index 73d1e354d..2443001b8 100644 --- a/lib/el3_runtime/aarch32/context_mgmt.c +++ b/lib/el3_runtime/aarch32/context_mgmt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -17,8 +17,6 @@ #include #include #include -#include -#include /******************************************************************************* * Context management library initialisation routine. This library is used by diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c index dc4717abe..546e39e16 100644 --- a/lib/el3_runtime/aarch64/context_mgmt.c +++ b/lib/el3_runtime/aarch64/context_mgmt.c @@ -23,8 +23,6 @@ #include #include #include -#include -#include /******************************************************************************* diff --git a/lib/optee/optee_utils.c b/lib/optee/optee_utils.c index 2a407939b..0ad108242 100644 --- a/lib/optee/optee_utils.c +++ b/lib/optee/optee_utils.c @@ -1,15 +1,12 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include -#include -#include #include -#include #include /* diff --git a/plat/arm/board/fvp/fvp_bl2_setup.c b/plat/arm/board/fvp/fvp_bl2_setup.c index 89636d18a..43b137481 100644 --- a/plat/arm/board/fvp/fvp_bl2_setup.c +++ b/plat/arm/board/fvp/fvp_bl2_setup.c @@ -1,12 +1,10 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include -#include -#include #include #include #include diff --git a/plat/arm/board/fvp/fvp_err.c b/plat/arm/board/fvp/fvp_err.c index 2437cd474..62ac882b0 100644 --- a/plat/arm/board/fvp/fvp_err.c +++ b/plat/arm/board/fvp/fvp_err.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Arm Limited. All rights reserved. + * Copyright (c) 2019-2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -10,7 +10,6 @@ #include #include #include -#include #include /* diff --git a/plat/arm/board/fvp/fvp_pm.c b/plat/arm/board/fvp/fvp_pm.c index 0a62543fa..c47d83779 100644 --- a/plat/arm/board/fvp/fvp_pm.c +++ b/plat/arm/board/fvp/fvp_pm.c @@ -1,11 +1,10 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include -#include #include #include @@ -16,7 +15,6 @@ #include #include #include -#include #include #include "fvp_private.h" diff --git a/plat/arm/board/juno/juno_err.c b/plat/arm/board/juno/juno_err.c index 961bfda17..60699cc73 100644 --- a/plat/arm/board/juno/juno_err.c +++ b/plat/arm/board/juno/juno_err.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,7 +9,6 @@ #include #include #include -#include #include /* diff --git a/plat/arm/common/aarch32/arm_bl2_mem_params_desc.c b/plat/arm/common/aarch32/arm_bl2_mem_params_desc.c index 7aeeb2aed..78360b06c 100644 --- a/plat/arm/common/aarch32/arm_bl2_mem_params_desc.c +++ b/plat/arm/common/aarch32/arm_bl2_mem_params_desc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -8,7 +8,6 @@ #include #include -#include /******************************************************************************* * Following descriptor provides BL image/ep information that gets used 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 0514b3994..6a8943d5d 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-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -8,7 +8,6 @@ #include #include -#include /******************************************************************************* * Following descriptor provides BL image/ep information that gets used diff --git a/plat/arm/common/aarch64/execution_state_switch.c b/plat/arm/common/aarch64/execution_state_switch.c index 8835fa135..bed929a9c 100644 --- a/plat/arm/common/aarch64/execution_state_switch.c +++ b/plat/arm/common/aarch64/execution_state_switch.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -12,7 +12,6 @@ #include #include #include -#include #include #include diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c index 939885f98..466f535f2 100644 --- a/plat/arm/common/arm_bl31_setup.c +++ b/plat/arm/common/arm_bl31_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c index 255e6b421..d1e9620de 100644 --- a/plat/arm/common/arm_common.c +++ b/plat/arm/common/arm_common.c @@ -16,7 +16,6 @@ #include #include #include -#include /* Weak definitions may be overridden in specific ARM standard platform */ #pragma weak plat_get_ns_image_entrypoint diff --git a/plat/arm/common/arm_dyn_cfg_helpers.c b/plat/arm/common/arm_dyn_cfg_helpers.c index 36d37f8f6..daf0f0a63 100644 --- a/plat/arm/common/arm_dyn_cfg_helpers.c +++ b/plat/arm/common/arm_dyn_cfg_helpers.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -8,7 +8,6 @@ #include -#include #include #include #include diff --git a/plat/arm/common/arm_nor_psci_mem_protect.c b/plat/arm/common/arm_nor_psci_mem_protect.c index b9181eb4c..1fa234d79 100644 --- a/plat/arm/common/arm_nor_psci_mem_protect.c +++ b/plat/arm/common/arm_nor_psci_mem_protect.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,7 +9,6 @@ #include #include #include -#include #include #include diff --git a/plat/arm/common/arm_pm.c b/plat/arm/common/arm_pm.c index c95f4523c..5434c9457 100644 --- a/plat/arm/common/arm_pm.c +++ b/plat/arm/common/arm_pm.c @@ -1,11 +1,10 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include -#include #include diff --git a/plat/arm/common/sp_min/arm_sp_min_setup.c b/plat/arm/common/sp_min/arm_sp_min_setup.c index bb69914ae..0cc746b10 100644 --- a/plat/arm/common/sp_min/arm_sp_min_setup.c +++ b/plat/arm/common/sp_min/arm_sp_min_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include diff --git a/plat/arm/css/common/css_pm.c b/plat/arm/css/common/css_pm.c index 01c674f82..af69c6fb4 100644 --- a/plat/arm/css/common/css_pm.c +++ b/plat/arm/css/common/css_pm.c @@ -1,11 +1,10 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include -#include #include @@ -15,7 +14,6 @@ #include #include #include -#include /* Allow CSS platforms to override `plat_arm_psci_pm_ops` */ #pragma weak plat_arm_psci_pm_ops diff --git a/plat/common/plat_bl_common.c b/plat/common/plat_bl_common.c index b46656c7a..6070db235 100644 --- a/plat/common/plat_bl_common.c +++ b/plat/common/plat_bl_common.c @@ -1,11 +1,10 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include -#include #include #include -- cgit v1.2.3 From e1f97d9c520819297c2b0f9c019a2cbcd9706375 Mon Sep 17 00:00:00 2001 From: Hadi Asyrafi Date: Tue, 17 Dec 2019 19:22:17 +0800 Subject: intel: Extend SiP service to support mailbox's RSU Introduce support for RSU that can be initiated through SMC calls. Added features as below: - RSU status - RSU update - RSU HPS notify - RSU get sub-partition Signed-off-by: Hadi Asyrafi Change-Id: I78d5a07688e43da99f03d77dfd45ffb4a78f2e4c --- plat/intel/soc/agilex/bl31_plat_setup.c | 3 ++ plat/intel/soc/common/include/socfpga_mailbox.h | 35 +++++++++++--- plat/intel/soc/common/soc/socfpga_mailbox.c | 49 +++++++++++++++++++ plat/intel/soc/common/socfpga_psci.c | 7 ++- plat/intel/soc/common/socfpga_sip_svc.c | 63 +++++++++++++++++++++++++ plat/intel/soc/stratix10/bl31_plat_setup.c | 3 ++ 6 files changed, 152 insertions(+), 8 deletions(-) diff --git a/plat/intel/soc/agilex/bl31_plat_setup.c b/plat/intel/soc/agilex/bl31_plat_setup.c index 13099b40f..4b1144095 100644 --- a/plat/intel/soc/agilex/bl31_plat_setup.c +++ b/plat/intel/soc/agilex/bl31_plat_setup.c @@ -14,6 +14,7 @@ #include #include +#include "socfpga_mailbox.h" #include "socfpga_private.h" static entry_point_info_t bl32_image_ep_info; @@ -107,6 +108,8 @@ void bl31_platform_setup(void) /* Signal secondary CPUs to jump to BL31 (BL2 = U-boot SPL) */ mmio_write_64(PLAT_CPU_RELEASE_ADDR, (uint64_t)plat_secondary_cpus_bl31_entry); + + mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL); } const mmap_region_t plat_agilex_mmap[] = { diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h index c4b9e5967..38f46963a 100644 --- a/plat/intel/soc/common/include/socfpga_mailbox.h +++ b/plat/intel/soc/common/include/socfpga_mailbox.h @@ -73,6 +73,29 @@ /* Mailbox REBOOT commands */ #define MBOX_CMD_REBOOT_HPS 71 +/* Mailbox RSU commands */ +#define MBOX_GET_SUBPARTITION_TABLE 90 +#define MBOX_RSU_STATUS 91 +#define MBOX_RSU_UPDATE 92 + +/* Mailbox RSU macros */ +#define RSU_VERSION_ACMF BIT(8) +#define RSU_VERSION_ACMF_MASK 0xff00 + +/* HPS stage notify command */ +#define MBOX_HPS_STAGE_NOTIFY 93 + +/* Execution states for HPS_STAGE_NOTIFY */ +#define HPS_EXECUTION_STATE_FSBL 0 +#define HPS_EXECUTION_STATE_SSBL 1 +#define HPS_EXECUTION_STATE_OS 2 + +/* Mailbox reconfiguration commands */ +#define MBOX_CONFIG_STATUS 4 +#define MBOX_RECONFIG 6 +#define MBOX_RECONFIG_DATA 8 +#define MBOX_RECONFIG_STATUS 9 + /* Generic error handling */ #define MBOX_TIMEOUT -2047 #define MBOX_NO_RESPONSE -2 @@ -98,13 +121,6 @@ #define MBOX_CFGSTAT_STATE_ERROR_BOOT_INFO 0xf0000007 #define MBOX_CFGSTAT_STATE_ERROR_QSPI_ERROR 0xf0000008 -/* Mailbox reconfiguration commands */ -#define MBOX_CONFIG_STATUS 4 -#define MBOX_RECONFIG 6 -#define MBOX_RECONFIG_DATA 8 -#define MBOX_RECONFIG_STATUS 9 - - void mailbox_set_int(int interrupt_input); int mailbox_init(void); void mailbox_set_qspi_close(void); @@ -122,4 +138,9 @@ void mailbox_clear_response(void); uint32_t intel_mailbox_get_config_status(uint32_t cmd); int intel_mailbox_is_fpga_not_ready(void); +int mailbox_rsu_get_spt_offset(uint32_t *resp_buf, uint32_t resp_buf_len); +int mailbox_rsu_status(uint32_t *resp_buf, uint32_t resp_buf_len); +int mailbox_rsu_update(uint32_t *flash_offset); +int mailbox_hps_stage_notify(uint32_t execution_stage); + #endif /* SOCFPGA_MBOX_H */ diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c index 8d7c1d663..673c2d56e 100644 --- a/plat/intel/soc/common/soc/socfpga_mailbox.c +++ b/plat/intel/soc/common/soc/socfpga_mailbox.c @@ -267,6 +267,55 @@ void mailbox_reset_cold(void) mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_REBOOT_HPS, 0, 0, 0, NULL, 0); } +int mailbox_rsu_get_spt_offset(uint32_t *resp_buf, uint32_t resp_buf_len) +{ + return mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_SUBPARTITION_TABLE, + NULL, 0, 0, (uint32_t *)resp_buf, + resp_buf_len); +} + +struct rsu_status_info { + uint64_t current_image; + uint64_t fail_image; + uint32_t state; + uint32_t version; + uint32_t error_location; + uint32_t error_details; + uint32_t retry_counter; +}; + +int mailbox_rsu_status(uint32_t *resp_buf, uint32_t resp_buf_len) +{ + int ret; + struct rsu_status_info *info = (struct rsu_status_info *)resp_buf; + + info->retry_counter = ~0; + + ret = mailbox_send_cmd(MBOX_JOB_ID, MBOX_RSU_STATUS, NULL, 0, 0, + (uint32_t *)resp_buf, resp_buf_len); + + if (ret < 0) + return ret; + + if (info->retry_counter != ~0) + if (!(info->version & RSU_VERSION_ACMF_MASK)) + info->version |= RSU_VERSION_ACMF; + + return ret; +} + +int mailbox_rsu_update(uint32_t *flash_offset) +{ + return mailbox_send_cmd(MBOX_JOB_ID, MBOX_RSU_UPDATE, + (uint32_t *)flash_offset, 2, 0, NULL, 0); +} + +int mailbox_hps_stage_notify(uint32_t execution_stage) +{ + return mailbox_send_cmd(MBOX_JOB_ID, MBOX_HPS_STAGE_NOTIFY, + &execution_stage, 1, 0, NULL, 0); +} + int mailbox_init(void) { int status = 0; diff --git a/plat/intel/soc/common/socfpga_psci.c b/plat/intel/soc/common/socfpga_psci.c index d8a6c1980..d27ab9f96 100644 --- a/plat/intel/soc/common/socfpga_psci.c +++ b/plat/intel/soc/common/socfpga_psci.c @@ -130,9 +130,14 @@ static void __dead2 socfpga_system_off(void) panic(); } +extern uint64_t intel_rsu_update_address; + static void __dead2 socfpga_system_reset(void) { - mailbox_reset_cold(); + if (intel_rsu_update_address) + mailbox_rsu_update((uint32_t *)&intel_rsu_update_address); + else + mailbox_reset_cold(); while (1) wfi(); diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c index 41dae9e76..620126ea7 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -365,6 +365,41 @@ uint32_t intel_secure_reg_update(uint64_t reg_addr, uint32_t mask, return INTEL_SIP_SMC_STATUS_ERROR; } +/* Intel Remote System Update (RSU) services */ +uint64_t intel_rsu_update_address; + +static uint32_t intel_rsu_status(uint64_t *respbuf, uint32_t respbuf_sz) +{ + if (mailbox_rsu_status((uint32_t *)respbuf, respbuf_sz) < 0) + return INTEL_SIP_SMC_STATUS_ERROR; + + return INTEL_SIP_SMC_STATUS_OK; +} + +static uint32_t intel_rsu_update(uint64_t update_address) +{ + intel_rsu_update_address = update_address; + return INTEL_SIP_SMC_STATUS_OK; +} + +static uint32_t intel_rsu_notify(uint64_t execution_stage) +{ + if (mailbox_hps_stage_notify((uint32_t)execution_stage) < 0) + return INTEL_SIP_SMC_STATUS_ERROR; + + return INTEL_SIP_SMC_STATUS_OK; +} + +static uint32_t intel_rsu_retry_counter(uint32_t *respbuf, uint32_t respbuf_sz, + uint32_t *ret_stat) +{ + if (mailbox_rsu_status((uint32_t *)respbuf, respbuf_sz) < 0) + return INTEL_SIP_SMC_STATUS_ERROR; + + *ret_stat = respbuf[8]; + return INTEL_SIP_SMC_STATUS_OK; +} + /* * This function is responsible for handling all SiP calls from the NS world */ @@ -381,6 +416,7 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, uint32_t val = 0; uint32_t status = INTEL_SIP_SMC_STATUS_OK; uint32_t completed_addr[3]; + uint64_t rsu_respbuf[9]; uint32_t count = 0; switch (smc_fid) { @@ -446,6 +482,33 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, (uint32_t)x3, &val); SMC_RET3(handle, status, val, x1); + case INTEL_SIP_SMC_RSU_STATUS: + status = intel_rsu_status(rsu_respbuf, + ARRAY_SIZE(rsu_respbuf)); + if (status) { + SMC_RET1(handle, status); + } else { + SMC_RET4(handle, rsu_respbuf[0], rsu_respbuf[1], + rsu_respbuf[2], rsu_respbuf[3]); + } + + case INTEL_SIP_SMC_RSU_UPDATE: + status = intel_rsu_update(x1); + SMC_RET1(handle, status); + + case INTEL_SIP_SMC_RSU_NOTIFY: + status = intel_rsu_notify(x1); + SMC_RET1(handle, status); + + case INTEL_SIP_SMC_RSU_RETRY_COUNTER: + status = intel_rsu_retry_counter((uint32_t *)rsu_respbuf, + ARRAY_SIZE(rsu_respbuf), &val); + if (status) { + SMC_RET1(handle, status); + } else { + SMC_RET2(handle, status, val); + } + default: return socfpga_sip_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags); diff --git a/plat/intel/soc/stratix10/bl31_plat_setup.c b/plat/intel/soc/stratix10/bl31_plat_setup.c index 29f57c467..4c3123815 100644 --- a/plat/intel/soc/stratix10/bl31_plat_setup.c +++ b/plat/intel/soc/stratix10/bl31_plat_setup.c @@ -16,6 +16,7 @@ #include #include +#include "socfpga_mailbox.h" #include "socfpga_private.h" #include "socfpga_reset_manager.h" #include "socfpga_system_manager.h" @@ -115,6 +116,8 @@ void bl31_platform_setup(void) /* Signal secondary CPUs to jump to BL31 (BL2 = U-boot SPL) */ mmio_write_64(PLAT_CPU_RELEASE_ADDR, (uint64_t)plat_secondary_cpus_bl31_entry); + + mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL); } const mmap_region_t plat_stratix10_mmap[] = { -- cgit v1.2.3 From 0c5d62ad7fdf9aacd4cc3fedb3bcd8fd5c2b2400 Mon Sep 17 00:00:00 2001 From: Hadi Asyrafi Date: Tue, 17 Dec 2019 19:30:41 +0800 Subject: intel: Introduce SMC support for mailbox command This update allows normal world to send mailbox commands through SMC Signed-off-by: Hadi Asyrafi Change-Id: I587bea06422da90e5907d586495cd9e3bde900f6 --- plat/intel/soc/common/include/socfpga_sip_svc.h | 1 + plat/intel/soc/common/socfpga_sip_svc.c | 30 +++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h index 6bb41f31b..2b1d9837c 100644 --- a/plat/intel/soc/common/include/socfpga_sip_svc.h +++ b/plat/intel/soc/common/include/socfpga_sip_svc.h @@ -28,6 +28,7 @@ #define INTEL_SIP_LEGACY_SMC_ECC_DBE 0xC200000D #define INTEL_SIP_SMC_RSU_NOTIFY 0xC200000E #define INTEL_SIP_SMC_RSU_RETRY_COUNTER 0xC200000F +#define INTEL_SIP_SMC_MBOX_SEND_CMD 0xC200001E /* FPGA config helpers */ #define INTEL_SIP_SMC_FPGA_CONFIG_ADDR 0x400000 diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c index 620126ea7..b4fe6d638 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -400,6 +400,26 @@ static uint32_t intel_rsu_retry_counter(uint32_t *respbuf, uint32_t respbuf_sz, return INTEL_SIP_SMC_STATUS_OK; } +/* Mailbox services */ +static uint32_t intel_mbox_send_cmd(uint32_t cmd, uint32_t *args, int len, + int urgent, uint32_t *response, + int resp_len, int *mbox_status, + int *len_in_resp) +{ + int status = mailbox_send_cmd(MBOX_JOB_ID, cmd, args, len, urgent, + response, resp_len); + + if (status < 0) { + *len_in_resp = 0; + *mbox_status = -status; + return INTEL_SIP_SMC_STATUS_ERROR; + } + + *mbox_status = 0; + *len_in_resp = status; + return INTEL_SIP_SMC_STATUS_OK; +} + /* * This function is responsible for handling all SiP calls from the NS world */ @@ -418,6 +438,8 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, uint32_t completed_addr[3]; uint64_t rsu_respbuf[9]; uint32_t count = 0; + u_register_t x5, x6; + int mbox_status, len_in_resp; switch (smc_fid) { case SIP_SVC_UID: @@ -509,6 +531,14 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, SMC_RET2(handle, status, val); } + case INTEL_SIP_SMC_MBOX_SEND_CMD: + x5 = SMC_GET_GP(handle, CTX_GPREG_X5); + x6 = SMC_GET_GP(handle, CTX_GPREG_X6); + status = intel_mbox_send_cmd(x1, (uint32_t *)x2, x3, x4, + (uint32_t *)x5, x6, &mbox_status, + &len_in_resp); + SMC_RET4(handle, status, mbox_status, x5, len_in_resp); + default: return socfpga_sip_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags); -- cgit v1.2.3 From d8b225a1a6d3d4bf7bf51fbd731413f76f6b8073 Mon Sep 17 00:00:00 2001 From: Achin Gupta Date: Fri, 11 Oct 2019 14:32:02 +0100 Subject: SPMD: add SPCI Beta 0 specification header file This patch adds a header file with defines based on the SPCI Beta 0 spec. It will be used by the SPM dispatcher component which will be introduced in subsequent patches. Signed-off-by: Achin Gupta Signed-off-by: Artsem Artsemenka Change-Id: Ia8a196cd85ebc14731f24801698d0a49a97b6063 --- include/services/spci_svc.h | 139 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 include/services/spci_svc.h diff --git a/include/services/spci_svc.h b/include/services/spci_svc.h new file mode 100644 index 000000000..49ba40858 --- /dev/null +++ b/include/services/spci_svc.h @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2019, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SPCI_SVC_H +#define SPCI_SVC_H + +#include +#include +#include + +/* SPCI error codes. */ +#define SPCI_ERROR_NOT_SUPPORTED -1 +#define SPCI_ERROR_INVALID_PARAMETER -2 +#define SPCI_ERROR_NO_MEMORY -3 +#define SPCI_ERROR_BUSY -4 +#define SPCI_ERROR_INTERRUPTED -5 +#define SPCI_ERROR_DENIED -6 +#define SPCI_ERROR_RETRY -7 + +/* The macros below are used to identify SPCI calls from the SMC function ID */ +#define SPCI_FNUM_MIN_VALUE U(0x60) +#define SPCI_FNUM_MAX_VALUE U(0x7f) +#define is_spci_fid(fid) __extension__ ({ \ + __typeof__(fid) _fid = (fid); \ + ((GET_SMC_NUM(_fid) >= SPCI_FNUM_MIN_VALUE) && \ + (GET_SMC_NUM(_fid) <= SPCI_FNUM_MAX_VALUE)); }) + +/* SPCI_VERSION helpers */ +#define SPCI_VERSION_MAJOR U(0) +#define SPCI_VERSION_MAJOR_SHIFT 16 +#define SPCI_VERSION_MAJOR_MASK U(0x7FFF) +#define SPCI_VERSION_MINOR U(9) +#define SPCI_VERSION_MINOR_SHIFT 0 +#define SPCI_VERSION_MINOR_MASK U(0xFFFF) + +#define MAKE_SPCI_VERSION(major, minor) \ + ((((major) & SPCI_VERSION_MAJOR_MASK) << SPCI_VERSION_MAJOR_SHIFT) | \ + (((minor) & SPCI_VERSION_MINOR_MASK) << SPCI_VERSION_MINOR_SHIFT)) +#define SPCI_VERSION_COMPILED MAKE_SPCI_VERSION(SPCI_VERSION_MAJOR, \ + SPCI_VERSION_MINOR) + +/* SPCI_MSG_SEND helpers */ +#define SPCI_MSG_SEND_ATTRS_BLK_SHIFT U(0) +#define SPCI_MSG_SEND_ATTRS_BLK_MASK U(0x1) +#define SPCI_MSG_SEND_ATTRS_BLK U(0) +#define SPCI_MSG_SEND_ATTRS_BLK_NOT U(1) +#define SPCI_MSG_SEND_ATTRS(blk) \ + (((blk) & SPCI_MSG_SEND_ATTRS_BLK_MASK) \ + << SPCI_MSG_SEND_ATTRS_BLK_SHIFT) + +/* Get SPCI fastcall std FID from function number */ +#define SPCI_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)) + +/* SPCI function numbers */ +#define SPCI_FNUM_ERROR U(0x60) +#define SPCI_FNUM_SUCCESS U(0x61) +#define SPCI_FNUM_INTERRUPT U(0x62) +#define SPCI_FNUM_VERSION U(0x63) +#define SPCI_FNUM_FEATURES U(0x64) +#define SPCI_FNUM_RX_RELEASE U(0x65) +#define SPCI_FNUM_RXTX_MAP U(0x66) +#define SPCI_FNUM_RXTX_UNMAP U(0x67) +#define SPCI_FNUM_PARTITION_INFO_GET U(0x68) +#define SPCI_FNUM_ID_GET U(0x69) +#define SPCI_FNUM_MSG_POLL U(0x6A) +#define SPCI_FNUM_MSG_WAIT U(0x6B) +#define SPCI_FNUM_MSG_YIELD U(0x6C) +#define SPCI_FNUM_MSG_RUN U(0x6D) +#define SPCI_FNUM_MSG_SEND U(0x6E) +#define SPCI_FNUM_MSG_SEND_DIRECT_REQ U(0x6F) +#define SPCI_FNUM_MSG_SEND_DIRECT_RESP U(0x70) +#define SPCI_FNUM_MEM_DONATE U(0x71) +#define SPCI_FNUM_MEM_LEND U(0x72) +#define SPCI_FNUM_MEM_SHARE U(0x73) +#define SPCI_FNUM_MEM_RETRIEVE_REQ U(0x74) +#define SPCI_FNUM_MEM_RETRIEVE_RESP U(0x75) +#define SPCI_FNUM_MEM_RELINQUISH U(0x76) +#define SPCI_FNUM_MEM_RECLAIM U(0x77) + +/* SPCI SMC32 FIDs */ +#define SPCI_ERROR SPCI_FID(SMC_32, SPCI_FNUM_ERROR) +#define SPCI_SUCCESS_SMC32 SPCI_FID(SMC_32, SPCI_FNUM_SUCCESS) +#define SPCI_INTERRUPT SPCI_FID(SMC_32, SPCI_FNUM_INTERRUPT) +#define SPCI_VERSION SPCI_FID(SMC_32, SPCI_FNUM_VERSION) +#define SPCI_FEATURES SPCI_FID(SMC_32, SPCI_FNUM_FEATURES) +#define SPCI_RX_RELEASE SPCI_FID(SMC_32, SPCI_FNUM_RX_RELEASE) +#define SPCI_RXTX_MAP_SMC32 SPCI_FID(SMC_32, SPCI_FNUM_RXTX_MAP) +#define SPCI_RXTX_UNMAP SPCI_FID(SMC_32, SPCI_FNUM_RXTX_UNMAP) +#define SPCI_PARTITION_INFO_GET SPCI_FID(SMC_32, SPCI_FNUM_PARTITION_INFO_GET) +#define SPCI_ID_GET SPCI_FID(SMC_32, SPCI_FNUM_ID_GET) +#define SPCI_MSG_POLL SPCI_FID(SMC_32, SPCI_FNUM_MSG_POLL) +#define SPCI_MSG_WAIT SPCI_FID(SMC_32, SPCI_FNUM_MSG_WAIT) +#define SPCI_MSG_YIELD SPCI_FID(SMC_32, SPCI_FNUM_MSG_YIELD) +#define SPCI_MSG_RUN SPCI_FID(SMC_32, SPCI_FNUM_MSG_RUN) +#define SPCI_MSG_SEND SPCI_FID(SMC_32, SPCI_FNUM_MSG_SEND) +#define SPCI_MSG_SEND_DIRECT_REQ_SMC32 \ + SPCI_FID(SMC_32, SPCI_FNUM_MSG_SEND_DIRECT_REQ) +#define SPCI_MSG_SEND_DIRECT_RESP_SMC32 \ + SPCI_FID(SMC_32, SPCI_FNUM_MSG_SEND_DIRECT_RESP) +#define SPCI_MEM_DONATE_SMC32 SPCI_FID(SMC_32, SPCI_FNUM_MEM_DONATE) +#define SPCI_MEM_LEND_SMC32 SPCI_FID(SMC_32, SPCI_FNUM_MEM_LEND) +#define SPCI_MEM_SHARE_SMC32 SPCI_FID(SMC_32, SPCI_FNUM_MEM_SHARE) +#define SPCI_MEM_RETRIEVE_REQ_SMC32 \ + SPCI_FID(SMC_32, SPCI_FNUM_MEM_RETRIEVE_REQ) +#define SPCI_MEM_RETRIEVE_RESP SPCI_FID(SMC_32, SPCI_FNUM_MEM_RETRIEVE_RESP) +#define SPCI_MEM_RELINQUISH SPCI_FID(SMC_32, SPCI_FNUM_MEM_RELINQUISH) +#define SPCI_MEM_RECLAIM SPCI_FID(SMC_32, SPCI_FNUM_MEM_RECLAIM) + +/* SPCI SMC64 FIDs */ +#define SPCI_SUCCESS_SMC64 SPCI_FID(SMC_64, SPCI_FNUM_SUCCESS) +#define SPCI_RXTX_MAP_SMC64 SPCI_FID(SMC_64, SPCI_FNUM_RXTX_MAP) +#define SPCI_MSG_SEND_DIRECT_REQ_SMC64 \ + SPCI_FID(SMC_64, SPCI_FNUM_MSG_SEND_DIRECT_REQ) +#define SPCI_MSG_SEND_DIRECT_RESP_SMC64 \ + SPCI_FID(SMC_64, SPCI_FNUM_MSG_SEND_DIRECT_RESP) +#define SPCI_MEM_DONATE_SMC64 SPCI_FID(SMC_64, SPCI_FNUM_MEM_DONATE) +#define SPCI_MEM_LEND_SMC64 SPCI_FID(SMC_64, SPCI_FNUM_MEM_LEND) +#define SPCI_MEM_SHARE_SMC64 SPCI_FID(SMC_64, SPCI_FNUM_MEM_SHARE) +#define SPCI_MEM_RETRIEVE_REQ_SMC64 \ + SPCI_FID(SMC_64, SPCI_FNUM_MEM_RETRIEVE_REQ) + +/* + * Reserve a special value for traffic targeted to the Hypervisor or SPM. + */ +#define SPCI_TARGET_INFO_MBZ U(0x0) + +/* + * Reserve a special value for MBZ parameters. + */ +#define SPCI_PARAM_MBZ U(0x0) + +#endif /* SPCI_SVC_H */ -- cgit v1.2.3 From bf14df1e97dcda6d0776fc7e86fa5e46c523f19a Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Wed, 5 Feb 2020 11:00:33 -0800 Subject: Tegra194: mce: declare nvg_roc_clean_cache_trbits() This patch adds the nvg_roc_clean_cache_trbits() function prototype to mce_private.h to fix compilation failures seen with the Tegra194 builds. Change-Id: I313556f6799792fc0141afb5822cc157db80bc47 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h | 1 + 1 file changed, 1 insertion(+) diff --git a/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h b/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h index 682574467..1fe3aad39 100644 --- a/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h +++ b/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h @@ -54,6 +54,7 @@ int32_t nvg_is_sc7_allowed(void); int32_t nvg_online_core(uint32_t core); int32_t nvg_update_ccplex_gsc(uint32_t gsc_idx); int32_t nvg_enter_cstate(uint32_t state, uint32_t wake_time); +int32_t nvg_roc_clean_cache_trbits(void); void nvg_enable_strict_checking_mode(void); void nvg_system_shutdown(void); void nvg_system_reboot(void); -- cgit v1.2.3 From 466bb285c6985027c75a230e39f2ae246fd07971 Mon Sep 17 00:00:00 2001 From: Zelalem Date: Wed, 5 Feb 2020 14:12:39 -0600 Subject: coverity: Fix MISRA null pointer violations Fix code that violates the MISRA rule: MISRA C-2012 Rule 11.9: Literal "0" shall not be used as null pointer constant. The fix explicitly checks whether a pointer is NULL. Change-Id: Ibc318dc0f464982be9a34783f24ccd1d44800551 Signed-off-by: Zelalem --- bl1/aarch64/bl1_context_mgmt.c | 4 ++-- bl1/bl1_main.c | 8 ++++---- bl2/bl2_image_load_v2.c | 14 +++++++------- common/desc_image_load.c | 12 ++++++------ drivers/console/multi_console.c | 8 ++++---- lib/utils/mem_region.c | 6 +++--- plat/arm/common/arm_bl2_setup.c | 4 ++-- 7 files changed, 28 insertions(+), 28 deletions(-) diff --git a/bl1/aarch64/bl1_context_mgmt.c b/bl1/aarch64/bl1_context_mgmt.c index 8be8830a3..210c35842 100644 --- a/bl1/aarch64/bl1_context_mgmt.c +++ b/bl1/aarch64/bl1_context_mgmt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -69,7 +69,7 @@ void bl1_prepare_next_image(unsigned int image_id) 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)) + 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. */ diff --git a/bl1/bl1_main.c b/bl1/bl1_main.c index cd6fe7d5e..bff8d22f5 100644 --- a/bl1/bl1_main.c +++ b/bl1/bl1_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -26,7 +26,7 @@ /* BL1 Service UUID */ DEFINE_SVC_UUID2(bl1_svc_uid, - 0xd46739fd, 0xcb72, 0x9a4d, 0xb5, 0x75, + U(0xd46739fd), 0xcb72, 0x9a4d, 0xb5, 0x75, 0x67, 0x15, 0xd6, 0xf4, 0xbb, 0x4a); static void bl1_load_bl2(void); @@ -172,7 +172,7 @@ static void bl1_load_bl2(void) /* Get the image descriptor */ image_desc = bl1_plat_get_image_desc(BL2_IMAGE_ID); - assert(image_desc); + assert(image_desc != NULL); /* Get the image info */ image_info = &image_desc->image_info; @@ -276,7 +276,7 @@ register_t bl1_smc_wrapper(uint32_t smc_fid, { register_t x1, x2, x3, x4; - assert(handle); + assert(handle != NULL); get_smc_params_from_ctx(handle, x1, x2, x3, x4); return bl1_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags); diff --git a/bl2/bl2_image_load_v2.c b/bl2/bl2_image_load_v2.c index 1fbdbabac..81d4b2bcc 100644 --- a/bl2/bl2_image_load_v2.c +++ b/bl2/bl2_image_load_v2.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -35,13 +35,13 @@ struct entry_point_info *bl2_load_images(void) * Get information about the images to load. */ bl2_load_info = plat_get_bl_image_load_info(); - assert(bl2_load_info); - assert(bl2_load_info->head); + assert(bl2_load_info != NULL); + assert(bl2_load_info->head != NULL); assert(bl2_load_info->h.type == PARAM_BL_LOAD_INFO); assert(bl2_load_info->h.version >= VERSION_2); bl2_node_info = bl2_load_info->head; - while (bl2_node_info) { + while (bl2_node_info != NULL) { /* * Perform platform setup before loading the image, * if indicated in the image attributes AND if NOT @@ -91,11 +91,11 @@ struct entry_point_info *bl2_load_images(void) * Get information to pass to the next image. */ bl2_to_next_bl_params = plat_get_next_bl_params(); - assert(bl2_to_next_bl_params); - assert(bl2_to_next_bl_params->head); + assert(bl2_to_next_bl_params != NULL); + assert(bl2_to_next_bl_params->head != NULL); assert(bl2_to_next_bl_params->h.type == PARAM_BL_PARAMS); assert(bl2_to_next_bl_params->h.version >= VERSION_2); - assert(bl2_to_next_bl_params->head->ep_info); + assert(bl2_to_next_bl_params->head->ep_info != NULL); /* Populate arg0 for the next BL image if not already provided */ if (bl2_to_next_bl_params->head->ep_info->args.arg0 == (u_register_t)0) diff --git a/common/desc_image_load.c b/common/desc_image_load.c index f2e8f6054..b4835978b 100644 --- a/common/desc_image_load.c +++ b/common/desc_image_load.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -301,9 +301,9 @@ void bl31_params_parse_helper(u_register_t param, image_info_t *bl33_image_info; } *v1 = (void *)(uintptr_t)param; assert(v1->h.type == PARAM_BL31); - if (bl32_ep_info_out) + if (bl32_ep_info_out != NULL) *bl32_ep_info_out = *v1->bl32_ep_info; - if (bl33_ep_info_out) + if (bl33_ep_info_out != NULL) *bl33_ep_info_out = *v1->bl33_ep_info; return; } @@ -311,12 +311,12 @@ void bl31_params_parse_helper(u_register_t param, assert(v2->h.version == PARAM_VERSION_2); assert(v2->h.type == PARAM_BL_PARAMS); - for (node = v2->head; node; node = node->next_params_info) { + for (node = v2->head; node != NULL; node = node->next_params_info) { if (node->image_id == BL32_IMAGE_ID) - if (bl32_ep_info_out) + if (bl32_ep_info_out != NULL) *bl32_ep_info_out = *node->ep_info; if (node->image_id == BL33_IMAGE_ID) - if (bl33_ep_info_out) + if (bl33_ep_info_out != NULL) *bl33_ep_info_out = *node->ep_info; } } diff --git a/drivers/console/multi_console.c b/drivers/console/multi_console.c index 215f49517..0665f202f 100644 --- a/drivers/console/multi_console.c +++ b/drivers/console/multi_console.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -90,7 +90,7 @@ int console_putc(int c) console_t *console; for (console = console_list; console != NULL; console = console->next) - if ((console->flags & console_state) && console->putc) { + if ((console->flags & console_state) && (console->putc != NULL)) { int ret = do_putc(c, console); if ((err == ERROR_NO_VALID_CONSOLE) || (ret < err)) err = ret; @@ -107,7 +107,7 @@ int console_getc(void) do { /* Keep polling while at least one console works correctly. */ for (console = console_list; console != NULL; console = console->next) - if ((console->flags & console_state) && console->getc) { + if ((console->flags & console_state) && (console->getc != NULL)) { int ret = console->getc(console); if (ret >= 0) return ret; @@ -125,7 +125,7 @@ int console_flush(void) console_t *console; for (console = console_list; console != NULL; console = console->next) - if ((console->flags & console_state) && console->flush) { + if ((console->flags & console_state) && (console->flush != NULL)) { int ret = console->flush(console); if ((err == ERROR_NO_VALID_CONSOLE) || (ret < err)) err = ret; diff --git a/lib/utils/mem_region.c b/lib/utils/mem_region.c index 08bccf64b..6bd78ba82 100644 --- a/lib/utils/mem_region.c +++ b/lib/utils/mem_region.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -32,7 +32,7 @@ void clear_mem_regions(mem_region_t *tbl, size_t nregions) { size_t i; - assert(tbl); + assert(tbl != NULL); assert(nregions > 0); for (i = 0; i < nregions; i++) { @@ -114,7 +114,7 @@ int mem_region_in_array_chk(mem_region_t *tbl, size_t nregions, uintptr_t region_start, region_end, start, end; size_t i; - assert(tbl); + assert(tbl != NULL); assert(nbytes > 0); assert(!check_uptr_overflow(addr, nbytes-1)); diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c index cdf87ca55..9adb1ea5e 100644 --- a/plat/arm/common/arm_bl2_setup.c +++ b/plat/arm/common/arm_bl2_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -150,7 +150,7 @@ int arm_bl2_handle_post_image_load(unsigned int image_id) bl_mem_params_node_t *pager_mem_params = NULL; bl_mem_params_node_t *paged_mem_params = NULL; #endif - assert(bl_mem_params); + assert(bl_mem_params != NULL); switch (image_id) { #ifdef __aarch64__ -- cgit v1.2.3 From afd241e71d76470478039388a358d0176491734f Mon Sep 17 00:00:00 2001 From: Carlo Caione Date: Fri, 24 Jan 2020 16:20:15 +0100 Subject: amlogic: axg: Add support for the A113D (AXG) platform Introduce the preliminary support for the Amlogic A113D (AXG) SoC. This port is a minimal implementation of BL31 capable of booting mainline U-Boot, Linux and chainloading BL32 (ATOS). Tested on a A113D board. Signed-off-by: Carlo Caione Change-Id: Ic4548fa2f7c48d61b485b2a6517ec36c53c20809 --- docs/about/maintainers.rst | 8 ++ docs/plat/meson-axg.rst | 26 +++++ plat/amlogic/axg/axg_bl31_setup.c | 159 ++++++++++++++++++++++++++++++ plat/amlogic/axg/axg_common.c | 115 ++++++++++++++++++++++ plat/amlogic/axg/axg_def.h | 129 +++++++++++++++++++++++++ plat/amlogic/axg/axg_pm.c | 166 ++++++++++++++++++++++++++++++++ plat/amlogic/axg/include/platform_def.h | 66 +++++++++++++ plat/amlogic/axg/platform.mk | 91 +++++++++++++++++ 8 files changed, 760 insertions(+) create mode 100644 docs/plat/meson-axg.rst create mode 100644 plat/amlogic/axg/axg_bl31_setup.c create mode 100644 plat/amlogic/axg/axg_common.c create mode 100644 plat/amlogic/axg/axg_def.h create mode 100644 plat/amlogic/axg/axg_pm.c create mode 100644 plat/amlogic/axg/include/platform_def.h create mode 100644 plat/amlogic/axg/platform.mk diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst index d9d7f84fd..802dafcd8 100644 --- a/docs/about/maintainers.rst +++ b/docs/about/maintainers.rst @@ -64,6 +64,14 @@ Amlogic Meson S905X2 (G12A) platform port :F: drivers/amlogic/g12a :F: plat/amlogic/g12a/ +Amlogic Meson A113D (AXG) platform port +----------------------------------------- +:M: Carlo Caione +:G: `carlocaione`_ +:F: docs/plat/meson-axg.rst +:F: drivers/amlogic/axg +:F: plat/amlogic/axg/ + Armv7-A architecture port ------------------------- :M: Etienne Carriere diff --git a/docs/plat/meson-axg.rst b/docs/plat/meson-axg.rst new file mode 100644 index 000000000..8a623bd37 --- /dev/null +++ b/docs/plat/meson-axg.rst @@ -0,0 +1,26 @@ +Amlogic Meson A113D (AXG) +=========================== + +The Amlogic Meson A113D is a SoC with a quad core Arm Cortex-A53 running at +~1.2GHz. It also contains a Cortex-M3 used as SCP. + +This port is a minimal implementation of BL31 capable of booting mainline U-Boot +and Linux: + +- SCPI support. +- Basic PSCI support (CPU_ON, CPU_OFF, SYSTEM_RESET, SYSTEM_OFF). Note that CPU0 + can't be turned off, so there is a workaround to hide this from the caller. +- GICv2 driver set up. +- Basic SIP services (read efuse data, enable/disable JTAG). + +In order to build it: + +.. code:: shell + + CROSS_COMPILE=aarch64-none-elf- make DEBUG=1 PLAT=axg [SPD=opteed] + +This port has been tested on a A113D board. After building it, follow the +instructions in the `U-Boot repository`_, replacing the mentioned **bl31.img** +by the one built from this port. + +.. _U-Boot repository: https://github.com/u-boot/u-boot/blob/master/board/amlogic/s400/README diff --git a/plat/amlogic/axg/axg_bl31_setup.c b/plat/amlogic/axg/axg_bl31_setup.c new file mode 100644 index 000000000..9240462e0 --- /dev/null +++ b/plat/amlogic/axg/axg_bl31_setup.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "aml_private.h" + +/* + * Placeholder variables for copying the arguments that have been passed to + * BL31 from BL2. + */ +static entry_point_info_t bl32_image_ep_info; +static entry_point_info_t bl33_image_ep_info; +static image_info_t bl30_image_info; +static image_info_t bl301_image_info; + +/******************************************************************************* + * Return a pointer to the 'entry_point_info' structure of the next image for + * the security state specified. BL33 corresponds to the non-secure image type + * while BL32 corresponds to the secure image type. A NULL pointer is returned + * if the image does not exist. + ******************************************************************************/ +entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) +{ + entry_point_info_t *next_image_info; + + next_image_info = (type == NON_SECURE) ? + &bl33_image_ep_info : &bl32_image_ep_info; + + /* None of the images can have 0x0 as the entrypoint. */ + if (next_image_info->pc != 0U) + return next_image_info; + + return NULL; +} + +/******************************************************************************* + * Perform any BL31 early platform setup. Here is an opportunity to copy + * parameters passed by the calling EL (S-EL1 in BL2 & S-EL3 in BL1) before + * they are lost (potentially). This needs to be done before the MMU is + * initialized so that the memory layout can be used while creating page + * tables. BL2 has flushed this information to memory, so we are guaranteed + * to pick up good data. + ******************************************************************************/ +struct axg_bl31_param { + param_header_t h; + image_info_t *bl31_image_info; + entry_point_info_t *bl32_ep_info; + image_info_t *bl32_image_info; + entry_point_info_t *bl33_ep_info; + image_info_t *bl33_image_info; + image_info_t *scp_image_info[]; +}; + +void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, + u_register_t arg2, u_register_t arg3) +{ + struct axg_bl31_param *from_bl2; + + /* Initialize the console to provide early debug support */ + aml_console_init(); + + from_bl2 = (struct axg_bl31_param *)arg0; + + /* Check params passed from BL2 are not NULL. */ + assert(from_bl2 != NULL); + assert(from_bl2->h.type == PARAM_BL31); + assert(from_bl2->h.version >= VERSION_1); + + /* + * Copy BL32 and BL33 entry point information. It is stored in Secure + * RAM, in BL2's address space. + */ + bl32_image_ep_info = *from_bl2->bl32_ep_info; + bl33_image_ep_info = *from_bl2->bl33_ep_info; + + if (bl33_image_ep_info.pc == 0U) { + ERROR("BL31: BL33 entrypoint not obtained from BL2\n"); + panic(); + } + + bl30_image_info = *from_bl2->scp_image_info[0]; + bl301_image_info = *from_bl2->scp_image_info[1]; +} + +void bl31_plat_arch_setup(void) +{ + aml_setup_page_tables(); + + enable_mmu_el3(0); +} + +static inline bool axg_scp_ready(void) +{ + return AML_AO_RTI_SCP_IS_READY(mmio_read_32(AML_AO_RTI_SCP_STAT)); +} + +static inline void axg_scp_boot(void) +{ + aml_scpi_upload_scp_fw(bl30_image_info.image_base, + bl30_image_info.image_size, 0); + aml_scpi_upload_scp_fw(bl301_image_info.image_base, + bl301_image_info.image_size, 1); + while (!axg_scp_ready()) + ; +} + +/******************************************************************************* + * GICv2 driver setup information + ******************************************************************************/ +static const interrupt_prop_t axg_interrupt_props[] = { + INTR_PROP_DESC(IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL) +}; + +static const gicv2_driver_data_t axg_gic_data = { + .gicd_base = AML_GICD_BASE, + .gicc_base = AML_GICC_BASE, + .interrupt_props = axg_interrupt_props, + .interrupt_props_num = ARRAY_SIZE(axg_interrupt_props) +}; + +void bl31_platform_setup(void) +{ + aml_mhu_secure_init(); + + gicv2_driver_init(&axg_gic_data); + gicv2_distif_init(); + gicv2_pcpu_distif_init(); + gicv2_cpuif_enable(); + + axg_scp_boot(); +} diff --git a/plat/amlogic/axg/axg_common.c b/plat/amlogic/axg/axg_common.c new file mode 100644 index 000000000..870daf459 --- /dev/null +++ b/plat/amlogic/axg/axg_common.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/******************************************************************************* + * Platform memory map regions + ******************************************************************************/ +#define MAP_NSDRAM0 MAP_REGION_FLAT(AML_NSDRAM0_BASE, \ + AML_NSDRAM0_SIZE, \ + MT_MEMORY | MT_RW | MT_NS) + +#define MAP_NS_SHARE_MEM MAP_REGION_FLAT(AML_NS_SHARE_MEM_BASE, \ + AML_NS_SHARE_MEM_SIZE, \ + MT_MEMORY | MT_RW | MT_NS) + +#define MAP_SEC_SHARE_MEM MAP_REGION_FLAT(AML_SEC_SHARE_MEM_BASE, \ + AML_SEC_SHARE_MEM_SIZE, \ + MT_MEMORY | MT_RW | MT_SECURE) + +#define MAP_SEC_DEVICE0 MAP_REGION_FLAT(AML_SEC_DEVICE0_BASE, \ + AML_SEC_DEVICE0_SIZE, \ + MT_DEVICE | MT_RW) + +#define MAP_GIC_DEVICE MAP_REGION_FLAT(AML_GIC_DEVICE_BASE, \ + AML_GIC_DEVICE_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#define MAP_SEC_DEVICE1 MAP_REGION_FLAT(AML_SEC_DEVICE1_BASE, \ + AML_SEC_DEVICE1_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#define MAP_SEC_DEVICE2 MAP_REGION_FLAT(AML_SEC_DEVICE2_BASE, \ + AML_SEC_DEVICE2_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#define MAP_TZRAM MAP_REGION_FLAT(AML_TZRAM_BASE, \ + AML_TZRAM_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +static const mmap_region_t axg_mmap[] = { + MAP_NSDRAM0, + MAP_NS_SHARE_MEM, + MAP_SEC_SHARE_MEM, + MAP_SEC_DEVICE0, + MAP_GIC_DEVICE, + MAP_SEC_DEVICE1, + MAP_SEC_DEVICE2, + MAP_TZRAM, + {0} +}; + +/******************************************************************************* + * Per-image regions + ******************************************************************************/ +#define MAP_BL31 MAP_REGION_FLAT(BL31_BASE, \ + BL31_END - BL31_BASE, \ + MT_MEMORY | MT_RW | MT_SECURE) + +#define MAP_BL_CODE MAP_REGION_FLAT(BL_CODE_BASE, \ + BL_CODE_END - BL_CODE_BASE, \ + MT_CODE | MT_SECURE) + +#define MAP_BL_RO_DATA MAP_REGION_FLAT(BL_RO_DATA_BASE, \ + BL_RO_DATA_END - BL_RO_DATA_BASE, \ + MT_RO_DATA | MT_SECURE) + +#define MAP_BL_COHERENT MAP_REGION_FLAT(BL_COHERENT_RAM_BASE, \ + BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +/******************************************************************************* + * Function that sets up the translation tables. + ******************************************************************************/ +void aml_setup_page_tables(void) +{ +#if IMAGE_BL31 + const mmap_region_t axg_bl_mmap[] = { + MAP_BL31, + MAP_BL_CODE, + MAP_BL_RO_DATA, +#if USE_COHERENT_MEM + MAP_BL_COHERENT, +#endif + {0} + }; +#endif + + mmap_add(axg_bl_mmap); + + mmap_add(axg_mmap); + + init_xlat_tables(); +} + +/******************************************************************************* + * Function that returns the system counter frequency + ******************************************************************************/ +unsigned int plat_get_syscnt_freq2(void) +{ + mmio_clrbits_32(AML_SYS_CPU_CFG7, PLAT_SYS_CPU_CFG7); + mmio_clrbits_32(AML_AO_TIMESTAMP_CNTL, PLAT_AO_TIMESTAMP_CNTL); + + return AML_OSC24M_CLK_IN_HZ; +} diff --git a/plat/amlogic/axg/axg_def.h b/plat/amlogic/axg/axg_def.h new file mode 100644 index 000000000..d90681afd --- /dev/null +++ b/plat/amlogic/axg/axg_def.h @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef AXG_DEF_H +#define AXG_DEF_H + +#include + +/******************************************************************************* + * System oscillator + ******************************************************************************/ +#define AML_OSC24M_CLK_IN_HZ ULL(24000000) /* 24 MHz */ + +/******************************************************************************* + * Memory regions + ******************************************************************************/ +#define AML_NS_SHARE_MEM_BASE UL(0x05000000) +#define AML_NS_SHARE_MEM_SIZE UL(0x00100000) + +#define AML_SEC_SHARE_MEM_BASE UL(0x05200000) +#define AML_SEC_SHARE_MEM_SIZE UL(0x00100000) + +#define AML_GIC_DEVICE_BASE UL(0xFFC00000) +#define AML_GIC_DEVICE_SIZE UL(0x00008000) + +#define AML_NSDRAM0_BASE UL(0x01000000) +#define AML_NSDRAM0_SIZE UL(0x0F000000) + +#define BL31_BASE UL(0x05100000) +#define BL31_SIZE UL(0x00100000) +#define BL31_LIMIT (BL31_BASE + BL31_SIZE) + +/* Shared memory used for SMC services */ +#define AML_SHARE_MEM_INPUT_BASE UL(0x050FE000) +#define AML_SHARE_MEM_OUTPUT_BASE UL(0x050FF000) + +#define AML_SEC_DEVICE0_BASE UL(0xFFD00000) +#define AML_SEC_DEVICE0_SIZE UL(0x00026000) + +#define AML_SEC_DEVICE1_BASE UL(0xFF800000) +#define AML_SEC_DEVICE1_SIZE UL(0x0000A000) + +#define AML_SEC_DEVICE2_BASE UL(0xFF620000) +#define AML_SEC_DEVICE2_SIZE UL(0x00028000) + +#define AML_TZRAM_BASE UL(0xFFFC0000) +#define AML_TZRAM_SIZE UL(0x00020000) + +/* Mailboxes */ +#define AML_MHU_SECURE_SCP_TO_AP_PAYLOAD UL(0xFFFD3800) +#define AML_MHU_SECURE_AP_TO_SCP_PAYLOAD UL(0xFFFD3A00) +#define AML_PSCI_MAILBOX_BASE UL(0xFFFD3F00) + +/******************************************************************************* + * GIC-400 and interrupt handling related constants + ******************************************************************************/ +#define AML_GICD_BASE UL(0xFFC01000) +#define AML_GICC_BASE UL(0xFFC02000) + +#define IRQ_SEC_PHY_TIMER 29 + +#define IRQ_SEC_SGI_0 8 +#define IRQ_SEC_SGI_1 9 +#define IRQ_SEC_SGI_2 10 +#define IRQ_SEC_SGI_3 11 +#define IRQ_SEC_SGI_4 12 +#define IRQ_SEC_SGI_5 13 +#define IRQ_SEC_SGI_6 14 +#define IRQ_SEC_SGI_7 15 +#define IRQ_SEC_SGI_8 16 + +/******************************************************************************* + * UART definitions + ******************************************************************************/ +#define AML_UART0_AO_BASE UL(0xFF803000) +#define AML_UART0_AO_CLK_IN_HZ AML_OSC24M_CLK_IN_HZ +#define AML_UART_BAUDRATE U(115200) + +/******************************************************************************* + * Memory-mapped I/O Registers + ******************************************************************************/ +#define AML_AO_TIMESTAMP_CNTL UL(0xFF8000B4) + +#define AML_SYS_CPU_CFG7 UL(0xFF634664) + +#define AML_AO_RTI_STATUS_REG3 UL(0xFF80001C) +#define AML_AO_RTI_SCP_STAT UL(0xFF80023C) +#define AML_AO_RTI_SCP_READY_OFF U(0x14) +#define AML_A0_RTI_SCP_READY_MASK U(3) +#define AML_AO_RTI_SCP_IS_READY(v) \ + ((((v) >> AML_AO_RTI_SCP_READY_OFF) & \ + AML_A0_RTI_SCP_READY_MASK) == AML_A0_RTI_SCP_READY_MASK) + +#define AML_HIU_MAILBOX_SET_0 UL(0xFF63C404) +#define AML_HIU_MAILBOX_STAT_0 UL(0xFF63C408) +#define AML_HIU_MAILBOX_CLR_0 UL(0xFF63C40C) +#define AML_HIU_MAILBOX_SET_3 UL(0xFF63C428) +#define AML_HIU_MAILBOX_STAT_3 UL(0xFF63C42C) +#define AML_HIU_MAILBOX_CLR_3 UL(0xFF63C430) + +#define AML_SHA_DMA_BASE UL(0xFF63E000) +#define AML_SHA_DMA_DESC (AML_SHA_DMA_BASE + 0x08) +#define AML_SHA_DMA_STATUS (AML_SHA_DMA_BASE + 0x28) + +/******************************************************************************* + * System Monitor Call IDs and arguments + ******************************************************************************/ +#define AML_SM_GET_SHARE_MEM_INPUT_BASE U(0x82000020) +#define AML_SM_GET_SHARE_MEM_OUTPUT_BASE U(0x82000021) + +#define AML_SM_EFUSE_READ U(0x82000030) +#define AML_SM_EFUSE_USER_MAX U(0x82000033) + +#define AML_SM_JTAG_ON U(0x82000040) +#define AML_SM_JTAG_OFF U(0x82000041) +#define AML_SM_GET_CHIP_ID U(0x82000044) + +#define AML_JTAG_STATE_ON U(0) +#define AML_JTAG_STATE_OFF U(1) + +#define AML_JTAG_M3_AO U(0) +#define AML_JTAG_M3_EE U(1) +#define AML_JTAG_A53_AO U(2) +#define AML_JTAG_A53_EE U(3) + +#endif /* AXG_DEF_H */ diff --git a/plat/amlogic/axg/axg_pm.c b/plat/amlogic/axg/axg_pm.c new file mode 100644 index 000000000..e67f263a4 --- /dev/null +++ b/plat/amlogic/axg/axg_pm.c @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "aml_private.h" + +#define SCPI_POWER_ON 0 +#define SCPI_POWER_RETENTION 1 +#define SCPI_POWER_OFF 3 + +#define SCPI_SYSTEM_SHUTDOWN 0 +#define SCPI_SYSTEM_REBOOT 1 + +static uintptr_t axg_sec_entrypoint; + +static void axg_pm_set_reset_addr(u_register_t mpidr, uint64_t value) +{ + unsigned int core = plat_calc_core_pos(mpidr); + uintptr_t cpu_mailbox_addr = AML_PSCI_MAILBOX_BASE + (core << 4); + + mmio_write_64(cpu_mailbox_addr, value); +} + +static void axg_pm_reset(u_register_t mpidr, uint32_t value) +{ + unsigned int core = plat_calc_core_pos(mpidr); + uintptr_t cpu_mailbox_addr = AML_PSCI_MAILBOX_BASE + (core << 4) + 8; + + mmio_write_32(cpu_mailbox_addr, value); +} + +static void __dead2 axg_system_reset(void) +{ + u_register_t mpidr = read_mpidr_el1(); + int ret; + + INFO("BL31: PSCI_SYSTEM_RESET\n"); + + ret = aml_scpi_sys_power_state(SCPI_SYSTEM_REBOOT); + if (ret != 0) { + ERROR("BL31: PSCI_SYSTEM_RESET: SCP error: %i\n", ret); + panic(); + } + + axg_pm_reset(mpidr, 0); + + wfi(); + + ERROR("BL31: PSCI_SYSTEM_RESET: Operation not handled\n"); + panic(); +} + +static void __dead2 axg_system_off(void) +{ + u_register_t mpidr = read_mpidr_el1(); + int ret; + + INFO("BL31: PSCI_SYSTEM_OFF\n"); + + ret = aml_scpi_sys_power_state(SCPI_SYSTEM_SHUTDOWN); + if (ret != 0) { + ERROR("BL31: PSCI_SYSTEM_OFF: SCP error %i\n", ret); + panic(); + } + + axg_pm_set_reset_addr(mpidr, 0); + axg_pm_reset(mpidr, 0); + + dmbsy(); + wfi(); + + ERROR("BL31: PSCI_SYSTEM_OFF: Operation not handled\n"); + panic(); +} + +static int32_t axg_pwr_domain_on(u_register_t mpidr) +{ + axg_pm_set_reset_addr(mpidr, axg_sec_entrypoint); + aml_scpi_set_css_power_state(mpidr, + SCPI_POWER_ON, SCPI_POWER_ON, SCPI_POWER_ON); + dmbsy(); + sev(); + + return PSCI_E_SUCCESS; +} + +static void axg_pwr_domain_on_finish(const psci_power_state_t *target_state) +{ + assert(target_state->pwr_domain_state[MPIDR_AFFLVL0] == + PLAT_LOCAL_STATE_OFF); + + gicv2_pcpu_distif_init(); + gicv2_cpuif_enable(); + + axg_pm_set_reset_addr(read_mpidr_el1(), 0); +} + +static void axg_pwr_domain_off(const psci_power_state_t *target_state) +{ + u_register_t mpidr = read_mpidr_el1(); + uint32_t system_state = SCPI_POWER_ON; + uint32_t cluster_state = SCPI_POWER_ON; + + assert(target_state->pwr_domain_state[MPIDR_AFFLVL0] == + PLAT_LOCAL_STATE_OFF); + + axg_pm_reset(mpidr, -1); + + gicv2_cpuif_disable(); + + if (target_state->pwr_domain_state[MPIDR_AFFLVL2] == + PLAT_LOCAL_STATE_OFF) + system_state = SCPI_POWER_OFF; + + if (target_state->pwr_domain_state[MPIDR_AFFLVL1] == + PLAT_LOCAL_STATE_OFF) + cluster_state = SCPI_POWER_OFF; + + + aml_scpi_set_css_power_state(mpidr, + SCPI_POWER_OFF, cluster_state, + system_state); +} + +static void __dead2 axg_pwr_domain_pwr_down_wfi(const psci_power_state_t + *target_state) +{ + dsbsy(); + axg_pm_reset(read_mpidr_el1(), 0); + + for (;;) + wfi(); +} + +/******************************************************************************* + * Platform handlers and setup function. + ******************************************************************************/ +static const plat_psci_ops_t axg_ops = { + .pwr_domain_on = axg_pwr_domain_on, + .pwr_domain_on_finish = axg_pwr_domain_on_finish, + .pwr_domain_off = axg_pwr_domain_off, + .pwr_domain_pwr_down_wfi = axg_pwr_domain_pwr_down_wfi, + .system_off = axg_system_off, + .system_reset = axg_system_reset +}; + +int plat_setup_psci_ops(uintptr_t sec_entrypoint, + const plat_psci_ops_t **psci_ops) +{ + axg_sec_entrypoint = sec_entrypoint; + *psci_ops = &axg_ops; + return 0; +} diff --git a/plat/amlogic/axg/include/platform_def.h b/plat/amlogic/axg/include/platform_def.h new file mode 100644 index 000000000..a47cf7348 --- /dev/null +++ b/plat/amlogic/axg/include/platform_def.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +#include +#include + +#include "../axg_def.h" + +#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64" +#define PLATFORM_LINKER_ARCH aarch64 + +#define PLATFORM_STACK_SIZE UL(0x1000) + +#define PLATFORM_MAX_CPUS_PER_CLUSTER U(4) +#define PLATFORM_CLUSTER_COUNT U(1) +#define PLATFORM_CLUSTER0_CORE_COUNT PLATFORM_MAX_CPUS_PER_CLUSTER +#define PLATFORM_CORE_COUNT PLATFORM_CLUSTER0_CORE_COUNT + +#define AML_PRIMARY_CPU U(0) + +#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL1 +#define PLAT_NUM_PWR_DOMAINS (PLATFORM_CLUSTER_COUNT + \ + PLATFORM_CORE_COUNT) + +#define PLAT_MAX_RET_STATE U(1) +#define PLAT_MAX_OFF_STATE U(2) + +#define PLAT_SYS_CPU_CFG7 (U(1) << 25) +#define PLAT_AO_TIMESTAMP_CNTL U(0x1ff) + +/* Local power state for power domains in Run state. */ +#define PLAT_LOCAL_STATE_RUN U(0) +/* Local power state for retention. Valid only for CPU power domains */ +#define PLAT_LOCAL_STATE_RET U(1) +/* Local power state for power-down. Valid for CPU and cluster power domains. */ +#define PLAT_LOCAL_STATE_OFF U(2) + +/* + * Macros used to parse state information from State-ID if it is using the + * recommended encoding for State-ID. + */ +#define PLAT_LOCAL_PSTATE_WIDTH U(4) +#define PLAT_LOCAL_PSTATE_MASK ((U(1) << PLAT_LOCAL_PSTATE_WIDTH) - 1) + +/* + * 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_SHIFT U(6) +#define CACHE_WRITEBACK_GRANULE (U(1) << CACHE_WRITEBACK_SHIFT) + +/* Memory-related defines */ +#define PLAT_PHY_ADDR_SPACE_SIZE (ULL(1) << 32) +#define PLAT_VIRT_ADDR_SPACE_SIZE (ULL(1) << 32) + +#define MAX_MMAP_REGIONS 16 +#define MAX_XLAT_TABLES 8 + +#endif /* PLATFORM_DEF_H */ diff --git a/plat/amlogic/axg/platform.mk b/plat/amlogic/axg/platform.mk new file mode 100644 index 000000000..463662ea1 --- /dev/null +++ b/plat/amlogic/axg/platform.mk @@ -0,0 +1,91 @@ +# +# Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +include lib/xlat_tables_v2/xlat_tables.mk + +AML_PLAT := plat/amlogic +AML_PLAT_SOC := ${AML_PLAT}/${PLAT} +AML_PLAT_COMMON := ${AML_PLAT}/common + +DOIMAGEPATH ?= tools/amlogic +DOIMAGETOOL ?= ${DOIMAGEPATH}/doimage + +PLAT_INCLUDES := -Iinclude/drivers/amlogic/ \ + -I${AML_PLAT_SOC}/include \ + -I${AML_PLAT_COMMON}/include + +GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ + drivers/arm/gic/v2/gicv2_main.c \ + drivers/arm/gic/v2/gicv2_helpers.c \ + plat/common/plat_gicv2.c + +BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \ + plat/common/plat_psci_common.c \ + drivers/amlogic/console/aarch64/meson_console.S \ + ${AML_PLAT_SOC}/${PLAT}_bl31_setup.c \ + ${AML_PLAT_SOC}/${PLAT}_pm.c \ + ${AML_PLAT_SOC}/${PLAT}_common.c \ + ${AML_PLAT_COMMON}/aarch64/aml_helpers.S \ + ${AML_PLAT_COMMON}/aml_efuse.c \ + ${AML_PLAT_COMMON}/aml_mhu.c \ + ${AML_PLAT_COMMON}/aml_scpi.c \ + ${AML_PLAT_COMMON}/aml_sip_svc.c \ + ${AML_PLAT_COMMON}/aml_thermal.c \ + ${AML_PLAT_COMMON}/aml_topology.c \ + ${AML_PLAT_COMMON}/aml_console.c \ + drivers/amlogic/crypto/sha_dma.c \ + ${XLAT_TABLES_LIB_SRCS} \ + ${GIC_SOURCES} + +# Tune compiler for Cortex-A53 +ifeq ($(notdir $(CC)),armclang) + TF_CFLAGS_aarch64 += -mcpu=cortex-a53 +else ifneq ($(findstring clang,$(notdir $(CC))),) + TF_CFLAGS_aarch64 += -mcpu=cortex-a53 +else + TF_CFLAGS_aarch64 += -mtune=cortex-a53 +endif + +# Build config flags +# ------------------ + +# Enable all errata workarounds for Cortex-A53 +ERRATA_A53_855873 := 1 +ERRATA_A53_819472 := 1 +ERRATA_A53_824069 := 1 +ERRATA_A53_827319 := 1 + +WORKAROUND_CVE_2017_5715 := 0 + +# Have different sections for code and rodata +SEPARATE_CODE_AND_RODATA := 1 + +# Use Coherent memory +USE_COHERENT_MEM := 1 + +# Verify build config +# ------------------- + +ifneq (${RESET_TO_BL31}, 0) + $(error Error: ${PLAT} needs RESET_TO_BL31=0) +endif + +ifeq (${ARCH},aarch32) + $(error Error: AArch32 not supported on ${PLAT}) +endif + +all: ${BUILD_PLAT}/bl31.img +distclean realclean clean: cleanimage + +cleanimage: + ${Q}${MAKE} -C ${DOIMAGEPATH} clean + +${DOIMAGETOOL}: + ${Q}${MAKE} -C ${DOIMAGEPATH} + +${BUILD_PLAT}/bl31.img: ${BUILD_PLAT}/bl31.bin ${DOIMAGETOOL} + ${DOIMAGETOOL} ${BUILD_PLAT}/bl31.bin ${BUILD_PLAT}/bl31.img + -- cgit v1.2.3 From 72d2535afde2df0d9edd851dad425d8fabf6d449 Mon Sep 17 00:00:00 2001 From: Carlo Caione Date: Mon, 27 Jan 2020 16:03:28 +0100 Subject: amlogic: axg: Add a build flag when using ATOS as BL32 BL2 is unconditionally setting 0 (OPTEE_AARCH64) in arg0 even when the BL32 image is 32bit (OPTEE_AARCH32). This is causing the boot to hang when ATOS (32bit Amlogic BL32 binary-only TEE OS) is used. Since we are not aware of any Amlogic platform shipping a 64bit version of ATOS we can hardcode OPTEE_AARCH32 / MODE_RW_32 when using ATOS. Signed-off-by: Carlo Caione Change-Id: Iaea47cf6dc48bf8a646056761f02fb81b41c78a3 --- docs/plat/meson-axg.rst | 1 + plat/amlogic/axg/axg_bl31_setup.c | 11 +++++++++++ plat/amlogic/axg/platform.mk | 4 ++++ 3 files changed, 16 insertions(+) diff --git a/docs/plat/meson-axg.rst b/docs/plat/meson-axg.rst index 8a623bd37..1e4b2c207 100644 --- a/docs/plat/meson-axg.rst +++ b/docs/plat/meson-axg.rst @@ -18,6 +18,7 @@ In order to build it: .. code:: shell CROSS_COMPILE=aarch64-none-elf- make DEBUG=1 PLAT=axg [SPD=opteed] + [AML_USE_ATOS=1 when using ATOS as BL32] This port has been tested on a A113D board. After building it, follow the instructions in the `U-Boot repository`_, replacing the mentioned **bl31.img** diff --git a/plat/amlogic/axg/axg_bl31_setup.c b/plat/amlogic/axg/axg_bl31_setup.c index 9240462e0..8cc9d69f4 100644 --- a/plat/amlogic/axg/axg_bl31_setup.c +++ b/plat/amlogic/axg/axg_bl31_setup.c @@ -84,6 +84,17 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, bl32_image_ep_info = *from_bl2->bl32_ep_info; bl33_image_ep_info = *from_bl2->bl33_ep_info; +#if AML_USE_ATOS + /* + * BL2 is unconditionally setting 0 (OPTEE_AARCH64) in arg0 even when + * the BL32 image is 32bit (OPTEE_AARCH32). This is causing the boot to + * hang when ATOS (32bit Amlogic BL32 binary-only TEE OS) is used. + * + * Hardcode to OPTEE_AARCH32 / MODE_RW_32. + */ + bl32_image_ep_info.args.arg0 = MODE_RW_32; +#endif + if (bl33_image_ep_info.pc == 0U) { ERROR("BL31: BL33 entrypoint not obtained from BL2\n"); panic(); diff --git a/plat/amlogic/axg/platform.mk b/plat/amlogic/axg/platform.mk index 463662ea1..3560b0cd1 100644 --- a/plat/amlogic/axg/platform.mk +++ b/plat/amlogic/axg/platform.mk @@ -66,6 +66,10 @@ SEPARATE_CODE_AND_RODATA := 1 # Use Coherent memory USE_COHERENT_MEM := 1 +AML_USE_ATOS := 0 +$(eval $(call assert_boolean,AML_USE_ATOS)) +$(eval $(call add_define,AML_USE_ATOS)) + # Verify build config # ------------------- -- cgit v1.2.3 From e63f5d129fadf520f42110d9a16c4192cba48784 Mon Sep 17 00:00:00 2001 From: Paul Beesley Date: Thu, 16 May 2019 13:33:18 +0100 Subject: doc: Split and expand coding style documentation This patch expands the coding style documentation, splitting it into two documents: the core style rules and extended guidelines. Note that it does not redefine or change the coding style (aside from section 4.6.2) - generally, it is only documenting the existing style in more detail. The aim is for the coding style to be more readable and, in turn, for it to be followed by more people. We can use this as a more concrete reference when discussing the accepted style with external contributors. Change-Id: I87405ace9a879d7f81e6b0b91b93ca69535e50ff Signed-off-by: Paul Beesley Signed-off-by: Petre-Ionut Tudor --- docs/getting_started/porting-guide.rst | 15 +- docs/process/coding-guidelines.rst | 515 ++++++++++++--------------------- docs/process/coding-style.rst | 468 ++++++++++++++++++++++++++++++ docs/process/contributing.rst | 4 +- docs/process/index.rst | 1 + docs/process/security-hardening.rst | 26 +- 6 files changed, 698 insertions(+), 331 deletions(-) create mode 100644 docs/process/coding-style.rst diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst index bb1471752..e8357b385 100644 --- a/docs/getting_started/porting-guide.rst +++ b/docs/getting_started/porting-guide.rst @@ -2763,6 +2763,19 @@ build system. to ``no``. If any of the options ``EL3_PAYLOAD_BASE`` or ``PRELOADED_BL33_BASE`` are used, this flag will be set to ``no`` automatically. +Platform include paths +---------------------- + +Platforms are allowed to add more include paths to be passed to the compiler. +The ``PLAT_INCLUDES`` variable is used for this purpose. This is needed in +particular for the file ``platform_def.h``. + +Example: + +.. code:: c + + PLAT_INCLUDES += -Iinclude/plat/myplat/include + C Library --------- @@ -2844,7 +2857,7 @@ amount of open resources per driver. -------------- -*Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.* +*Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.* .. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf .. _Arm Generic Interrupt Controller version 2.0 (GICv2): http://infocenter.arm.com/help/topic/com.arm.doc.ihi0048b/index.html diff --git a/docs/process/coding-guidelines.rst b/docs/process/coding-guidelines.rst index cb8b89245..f7d53a97e 100644 --- a/docs/process/coding-guidelines.rst +++ b/docs/process/coding-guidelines.rst @@ -1,232 +1,126 @@ -Coding Style & Guidelines -========================= +Coding Guidelines +================= -The following sections contain TF coding guidelines. They are continually -evolving and should not be considered "set in stone". Feel free to question them -and provide feedback. +This document provides some additional guidelines to consider when writing +|TF-A| code. These are not intended to be strictly-enforced rules like the +contents of the :ref:`Coding Style`. -Some of the guidelines may also apply to other codebases. +Automatic Editor Configuration +------------------------------ -.. note:: - The existing TF codebase does not necessarily comply with all the - below guidelines but the intent is for it to do so eventually. - -Checkpatch overrides --------------------- - -Some checkpatch warnings in the TF codebase are deliberately ignored. These -include: - -- ``**WARNING: line over 80 characters**``: Although the codebase should - generally conform to the 80 character limit this is overly restrictive in some - cases. - -- ``**WARNING: Use of volatile is usually wrong``: see - `Why the “volatile” type class should not be used`_ . Although this document - contains some very useful information, there are several legitimate uses of - the volatile keyword within the TF codebase. - -Headers and inclusion ---------------------- - -Header guards -^^^^^^^^^^^^^ - -For a header file called "some_driver.h" the style used by the Trusted Firmware -is: - -.. code:: c - - #ifndef SOME_DRIVER_H - #define SOME_DRIVER_H - -
- - #endif /* SOME_DRIVER_H */ +Many of the rules given below (such as indentation size, use of tabs, and +newlines) can be set automatically using the `EditorConfig`_ configuration file +in the root of the repository: ``.editorconfig``. With a supported editor, the +rules set out in this file can be automatically applied when you are editing +files in the |TF-A| repository. -Include statement ordering -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -All header files that are included by a source file must use the following, -grouped ordering. This is to improve readability (by making it easier to quickly -read through the list of headers) and maintainability. - -#. *System* includes: Header files from the standard *C* library, such as - ``stddef.h`` and ``string.h``. - -#. *Project* includes: Header files under the ``include/`` directory within TF - are *project* includes. - -#. *Platform* includes: Header files relating to a single, specific platform, - and which are located under the ``plat/`` directory within TF, - are *platform* includes. - -Within each group, ``#include`` statements must be in alphabetical order, -taking both the file and directory names into account. - -Groups must be separated by a single blank line for clarity. - -The example below illustrates the ordering rules using some contrived header -file names; this type of name reuse should be otherwise avoided. - -.. code:: c - - #include - - #include - #include - #include - #include - - #include "./a_header.h" - -Include statement variants -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Two variants of the ``#include`` directive are acceptable in the TF codebase. -Correct use of the two styles improves readability by suggesting the location -of the included header and reducing ambiguity in cases where generic and -platform-specific headers share a name. - -For header files that are in the same directory as the source file that is -including them, use the ``"..."`` variant. - -For header files that are **not** in the same directory as the source file that -is including them, use the ``<...>`` variant. - -Example (bl1_fwu.c): - -.. code:: c +Several editors include built-in support for EditorConfig files, and many others +support its functionality through plugins. - #include - #include - #include +Use of the EditorConfig file is suggested but is not required. - #include "bl1_private.h" -Platform include paths -^^^^^^^^^^^^^^^^^^^^^^ - -Platforms are allowed to add more include paths to be passed to the compiler. -The ``PLAT_INCLUDES`` variable is used for this purpose. This is needed in -particular for the file ``platform_def.h``. - -Example: - -.. code:: c - - PLAT_INCLUDES += -Iinclude/plat/myplat/include +Automatic Compliance Checking +----------------------------- -Types and typedefs ------------------- +To assist with coding style compliance, the project Makefile contains two +targets which both utilise the `checkpatch.pl` script that ships with the Linux +source tree. The project also defines certain *checkpatch* options in the +``.checkpatch.conf`` file in the top-level directory. -Use of built-in *C* and *libc* data types -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. note:: + Checkpatch errors will gate upstream merging of pull requests. + Checkpatch warnings will not gate merging but should be reviewed and fixed if + possible. -The TF codebase should be kept as portable as possible, especially since both -64-bit and 32-bit platforms are supported. To help with this, the following data -type usage guidelines should be followed: +To check the entire source tree, you must first download copies of +``checkpatch.pl``, ``spelling.txt`` and ``const_structs.checkpatch`` available +in the `Linux master tree`_ *scripts* directory, then set the ``CHECKPATCH`` +environment variable to point to ``checkpatch.pl`` (with the other 2 files in +the same directory) and build the `checkcodebase` target: -- Where possible, use the built-in *C* data types for variable storage (for - example, ``char``, ``int``, ``long long``, etc) instead of the standard *C99* - types. Most code is typically only concerned with the minimum size of the - data stored, which the built-in *C* types guarantee. - -- Avoid using the exact-size standard *C99* types in general (for example, - ``uint16_t``, ``uint32_t``, ``uint64_t``, etc) since they can prevent the - compiler from making optimizations. There are legitimate uses for them, - for example to represent data of a known structure. When using them in struct - definitions, consider how padding in the struct will work across architectures. - For example, extra padding may be introduced in AArch32 systems if a struct - member crosses a 32-bit boundary. +.. code:: shell -- Use ``int`` as the default integer type - it's likely to be the fastest on all - systems. Also this can be assumed to be 32-bit as a consequence of the - `Procedure Call Standard for the Arm Architecture`_ and the `Procedure Call - Standard for the Arm 64-bit Architecture`_ . + make CHECKPATCH=/linux/scripts/checkpatch.pl checkcodebase -- Avoid use of ``short`` as this may end up being slower than ``int`` in some - systems. If a variable must be exactly 16-bit, use ``int16_t`` or - ``uint16_t``. +To just check the style on the files that differ between your local branch and +the remote master, use: -- Avoid use of ``long``. This is guaranteed to be at least 32-bit but, given - that `int` is 32-bit on Arm platforms, there is no use for it. For integers of - at least 64-bit, use ``long long``. +.. code:: shell -- Use ``char`` for storing text. Use ``uint8_t`` for storing other 8-bit data. + make CHECKPATCH=/linux/scripts/checkpatch.pl checkpatch -- Use ``unsigned`` for integers that can never be negative (counts, - indices, sizes, etc). TF intends to comply with MISRA "essential type" coding - rules (10.X), where signed and unsigned types are considered different - essential types. Choosing the correct type will aid this. MISRA static - analysers will pick up any implicit signed/unsigned conversions that may lead - to unexpected behaviour. +If you wish to check your patch against something other than the remote master, +set the ``BASE_COMMIT`` variable to your desired branch. By default, +``BASE_COMMIT`` is set to ``origin/master``. -- For pointer types: +Ignored Checkpatch Warnings +^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - If an argument in a function declaration is pointing to a known type then - simply use a pointer to that type (for example: ``struct my_struct *``). +Some checkpatch warnings in the TF codebase are deliberately ignored. These +include: - - If a variable (including an argument in a function declaration) is pointing - to a general, memory-mapped address, an array of pointers or another - structure that is likely to require pointer arithmetic then use - ``uintptr_t``. This will reduce the amount of casting required in the code. - Avoid using ``unsigned long`` or ``unsigned long long`` for this purpose; it - may work but is less portable. +- ``**WARNING: line over 80 characters**``: Although the codebase should + generally conform to the 80 character limit this is overly restrictive in some + cases. - - For other pointer arguments in a function declaration, use ``void *``. This - includes pointers to types that are abstracted away from the known API and - pointers to arbitrary data. This allows the calling function to pass a - pointer argument to the function without any explicit casting (the cast to - ``void *`` is implicit). The function implementation can then do the - appropriate casting to a specific type. +- ``**WARNING: Use of volatile is usually wrong``: see + `Why the “volatile” type class should not be used`_ . Although this document + contains some very useful information, there are several legimate uses of the + volatile keyword within the TF codebase. - - Use ``ptrdiff_t`` to compare the difference between 2 pointers. +Performance considerations +-------------------------- -- Use ``size_t`` when storing the ``sizeof()`` something. +Avoid printf and use logging macros +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- Use ``ssize_t`` when returning the ``sizeof()`` something from a function that - can also return an error code; the signed type allows for a negative return - code in case of error. This practice should be used sparingly. +``debug.h`` provides logging macros (for example, ``WARN`` and ``ERROR``) +which wrap ``tf_log`` and which allow the logging call to be compiled-out +depending on the ``make`` command. Use these macros to avoid print statements +being compiled unconditionally into the binary. -- Use ``u_register_t`` when it's important to store the contents of a register - in its native size (32-bit in AArch32 and 64-bit in AArch64). This is not a - standard *C99* type but is widely available in libc implementations, - including the FreeBSD version included with the TF codebase. Where possible, - cast the variable to a more appropriate type before interpreting the data. For - example, the following struct in ``ep_info.h`` could use this type to minimize - the storage required for the set of registers: +Each logging macro has a numerical log level: .. code:: c - typedef struct aapcs64_params { - u_register_t arg0; - u_register_t arg1; - u_register_t arg2; - u_register_t arg3; - u_register_t arg4; - u_register_t arg5; - u_register_t arg6; - u_register_t arg7; - } aapcs64_params_t; + #define LOG_LEVEL_NONE 0 + #define LOG_LEVEL_ERROR 10 + #define LOG_LEVEL_NOTICE 20 + #define LOG_LEVEL_WARNING 30 + #define LOG_LEVEL_INFO 40 + #define LOG_LEVEL_VERBOSE 50 -If some code wants to operate on ``arg0`` and knows that it represents a 32-bit -unsigned integer on all systems, cast it to ``unsigned int``. +By default, all logging statements with a log level ``<= LOG_LEVEL_INFO`` will +be compiled into debug builds and all statements with a log level +``<= LOG_LEVEL_NOTICE`` will be compiled into release builds. This can be +overridden from the command line or by the platform makefile (although it may be +necessary to clean the build directory first). For example, to enable +``VERBOSE`` logging on FVP: -These guidelines should be updated if additional types are needed. +``make PLAT=fvp LOG_LEVEL=50 all`` -Avoid anonymous typedefs of structs/enums in headers -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Use const data where possible +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -For example, the following definition: +For example, the following code: .. code:: c - typedef struct { + struct my_struct { int arg1; int arg2; - } my_struct_t; + }; + void init(struct my_struct *ptr); + + void main(void) + { + struct my_struct x; + x.arg1 = 1; + x.arg2 = 2; + init(&x); + } is better written as: @@ -237,31 +131,18 @@ is better written as: int arg2; }; -This allows function declarations in other header files that depend on the -struct/enum to forward declare the struct/enum instead of including the -entire header: - -.. code:: c - - #include - void my_func(my_struct_t *arg); - -instead of: - -.. code:: c - - struct my_struct; - void my_func(struct my_struct *arg); - -Some TF definitions use both a struct/enum name **and** a typedef name. This -is discouraged for new definitions as it makes it difficult for TF to comply -with MISRA rule 8.3, which states that "All declarations of an object or -function shall use the same names and type qualifiers". + void init(const struct my_struct *ptr); -The Linux coding standards also discourage new typedefs and checkpatch emits -a warning for this. + void main(void) + { + const struct my_struct x = { 1, 2 }; + init(&x); + } -Existing typedefs will be retained for compatibility. +This allows the linker to put the data in a read-only data section instead of a +writeable data section, which may result in a smaller and faster binary. Note +that this may require dependent functions (``init()`` in the above example) to +have ``const`` arguments, assuming they don't need to modify the data. Libc functions that are banned or to be used with caution --------------------------------------------------------- @@ -410,14 +291,14 @@ error. This situation should be handled in one of the following ways: then emit an ``ERROR`` message and call the platform-specific function ``plat_error_handler()``. -Cases 1 and 2 are subtly different. A platform may implement ``plat_panic_handler`` -and ``plat_error_handler`` in the same way (for example, by waiting for a secure -watchdog to time-out or by invoking an interface on the platform's power -controller to reset the platform). However, ``plat_error_handler`` may take -additional action for some errors (for example, it may set a flag so the -platform resets into a different mode). Also, ``plat_panic_handler()`` may -implement additional debug functionality (for example, invoking a hardware -breakpoint). +Cases 1 and 2 are subtly different. A platform may implement +``plat_panic_handler`` and ``plat_error_handler`` in the same way (for example, +by waiting for a secure watchdog to time-out or by invoking an interface on the +platform's power controller to reset the platform). However, +``plat_error_handler`` may take additional action for some errors (for example, +it may set a flag so the platform resets into a different mode). Also, +``plat_panic_handler()`` may implement additional debug functionality (for +example, invoking a hardware breakpoint). Examples of unexpected unrecoverable errors: @@ -456,131 +337,115 @@ Examples: - Secure world is waiting for a hardware response that is critical for continued operation. -Security considerations ------------------------ - -Part of the security of a platform is handling errors correctly, as described in -the previous section. There are several other security considerations covered in -this section. - -Do not leak secrets to the normal world -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The secure world **must not** leak secrets to the normal world, for example in -response to an SMC. - -Handling Denial of Service attacks -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Use of built-in *C* and *libc* data types +----------------------------------------- -The secure world **should never** crash or become unusable due to receiving too -many normal world requests (a *Denial of Service* or *DoS* attack). It should -have a mechanism for throttling or ignoring normal world requests. +The |TF-A| codebase should be kept as portable as possible, especially since +both 64-bit and 32-bit platforms are supported. To help with this, the following +data type usage guidelines should be followed: -Performance considerations --------------------------- +- Where possible, use the built-in *C* data types for variable storage (for + example, ``char``, ``int``, ``long long``, etc) instead of the standard *C99* + types. Most code is typically only concerned with the minimum size of the + data stored, which the built-in *C* types guarantee. -Avoid printf and use logging macros -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +- Avoid using the exact-size standard *C99* types in general (for example, + ``uint16_t``, ``uint32_t``, ``uint64_t``, etc) since they can prevent the + compiler from making optimizations. There are legitimate uses for them, + for example to represent data of a known structure. When using them in struct + definitions, consider how padding in the struct will work across architectures. + For example, extra padding may be introduced in |AArch32| systems if a struct + member crosses a 32-bit boundary. -``debug.h`` provides logging macros (for example, ``WARN`` and ``ERROR``) -which wrap ``tf_log`` and which allow the logging call to be compiled-out -depending on the ``make`` command. Use these macros to avoid print statements -being compiled unconditionally into the binary. +- Use ``int`` as the default integer type - it's likely to be the fastest on all + systems. Also this can be assumed to be 32-bit as a consequence of the + `Procedure Call Standard for the Arm Architecture`_ and the `Procedure Call + Standard for the Arm 64-bit Architecture`_ . -Each logging macro has a numerical log level: +- Avoid use of ``short`` as this may end up being slower than ``int`` in some + systems. If a variable must be exactly 16-bit, use ``int16_t`` or + ``uint16_t``. -.. code:: c +- Avoid use of ``long``. This is guaranteed to be at least 32-bit but, given + that `int` is 32-bit on Arm platforms, there is no use for it. For integers of + at least 64-bit, use ``long long``. - #define LOG_LEVEL_NONE 0 - #define LOG_LEVEL_ERROR 10 - #define LOG_LEVEL_NOTICE 20 - #define LOG_LEVEL_WARNING 30 - #define LOG_LEVEL_INFO 40 - #define LOG_LEVEL_VERBOSE 50 +- Use ``char`` for storing text. Use ``uint8_t`` for storing other 8-bit data. +- Use ``unsigned`` for integers that can never be negative (counts, + indices, sizes, etc). TF intends to comply with MISRA "essential type" coding + rules (10.X), where signed and unsigned types are considered different + essential types. Choosing the correct type will aid this. MISRA static + analysers will pick up any implicit signed/unsigned conversions that may lead + to unexpected behaviour. -By default, all logging statements with a log level ``<= LOG_LEVEL_INFO`` will -be compiled into debug builds and all statements with a log level -``<= LOG_LEVEL_NOTICE`` will be compiled into release builds. This can be -overridden from the command line or by the platform makefile (although it may be -necessary to clean the build directory first). For example, to enable -``VERBOSE`` logging on FVP: +- For pointer types: -``make PLAT=fvp LOG_LEVEL=50 all`` + - If an argument in a function declaration is pointing to a known type then + simply use a pointer to that type (for example: ``struct my_struct *``). -Use const data where possible -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + - If a variable (including an argument in a function declaration) is pointing + to a general, memory-mapped address, an array of pointers or another + structure that is likely to require pointer arithmetic then use + ``uintptr_t``. This will reduce the amount of casting required in the code. + Avoid using ``unsigned long`` or ``unsigned long long`` for this purpose; it + may work but is less portable. -For example, the following code: + - For other pointer arguments in a function declaration, use ``void *``. This + includes pointers to types that are abstracted away from the known API and + pointers to arbitrary data. This allows the calling function to pass a + pointer argument to the function without any explicit casting (the cast to + ``void *`` is implicit). The function implementation can then do the + appropriate casting to a specific type. -.. code:: c + - Avoid pointer arithmetic generally (as this violates MISRA C 2012 rule + 18.4) and especially on void pointers (as this is only supported via + language extensions and is considered non-standard). In TF-A, setting the + ``W`` build flag to ``W=3`` enables the *-Wpointer-arith* compiler flag and + this will emit warnings where pointer arithmetic is used. - struct my_struct { - int arg1; - int arg2; - }; + - Use ``ptrdiff_t`` to compare the difference between 2 pointers. - void init(struct my_struct *ptr); +- Use ``size_t`` when storing the ``sizeof()`` something. - void main(void) - { - struct my_struct x; - x.arg1 = 1; - x.arg2 = 2; - init(&x); - } +- Use ``ssize_t`` when returning the ``sizeof()`` something from a function that + can also return an error code; the signed type allows for a negative return + code in case of error. This practice should be used sparingly. -is better written as: +- Use ``u_register_t`` when it's important to store the contents of a register + in its native size (32-bit in |AArch32| and 64-bit in |AArch64|). This is not a + standard *C99* type but is widely available in libc implementations, + including the FreeBSD version included with the TF codebase. Where possible, + cast the variable to a more appropriate type before interpreting the data. For + example, the following struct in ``ep_info.h`` could use this type to minimize + the storage required for the set of registers: .. code:: c - struct my_struct { - int arg1; - int arg2; - }; - - void init(const struct my_struct *ptr); - - void main(void) - { - const struct my_struct x = { 1, 2 }; - init(&x); - } - -This allows the linker to put the data in a read-only data section instead of a -writeable data section, which may result in a smaller and faster binary. Note -that this may require dependent functions (``init()`` in the above example) to -have ``const`` arguments, assuming they don't need to modify the data. - -Library and driver code ------------------------ - -TF library code (under ``lib/`` and ``include/lib``) is any code that provides a -reusable interface to other code, potentially even to code outside of TF. - -In some systems drivers must conform to a specific driver framework to provide -services to the rest of the system. TF has no driver framework and the -distinction between a driver and library is somewhat subjective. + typedef struct aapcs64_params { + u_register_t arg0; + u_register_t arg1; + u_register_t arg2; + u_register_t arg3; + u_register_t arg4; + u_register_t arg5; + u_register_t arg6; + u_register_t arg7; + } aapcs64_params_t; -A driver (under ``drivers/`` and ``include/drivers/``) is defined as code that -interfaces with hardware via a memory mapped interface. +If some code wants to operate on ``arg0`` and knows that it represents a 32-bit +unsigned integer on all systems, cast it to ``unsigned int``. -Some drivers (for example, the Arm CCI driver in ``include/drivers/arm/cci.h``) -provide a general purpose API to that specific hardware. Other drivers (for -example, the Arm PL011 console driver in ``drivers/arm/pl011/pl011_console.S``) -provide a specific hardware implementation of a more abstract library API. In -the latter case there may potentially be multiple drivers for the same hardware -device. +These guidelines should be updated if additional types are needed. -Neither libraries nor drivers should depend on platform-specific code. If they -require platform-specific data (for example, a base address) to operate then -they should provide an initialization function that takes the platform-specific -data as arguments. +-------------- -TF common code (under ``common/`` and ``include/common/``) is code that is re-used -by other generic (non-platform-specific) TF code. It is effectively internal -library code. +*Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.* +.. _`Linux master tree`: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/ +.. _`Procedure Call Standard for the Arm Architecture`: https://developer.arm.com/docs/ihi0042/latest/ +.. _`Procedure Call Standard for the Arm 64-bit Architecture`: https://developer.arm.com/docs/ihi0055/latest/ +.. _`EditorConfig`: http://editorconfig.org/ .. _`Why the “volatile” type class should not be used`: https://www.kernel.org/doc/html/latest/process/volatile-considered-harmful.html -.. _`Procedure Call Standard for the Arm Architecture`: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042f/IHI0042F_aapcs.pdf -.. _`Procedure Call Standard for the Arm 64-bit Architecture`: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf +.. _`MISRA C:2012 Guidelines`: https://www.misra.org.uk/Activities/MISRAC/tabid/160/Default.aspx +.. _`a spreadsheet`: https://developer.trustedfirmware.org/file/download/lamajxif3w7c4mpjeoo5/PHID-FILE-fp7c7acszn6vliqomyhn/MISRA-and-TF-Analysis-v1.3.ods diff --git a/docs/process/coding-style.rst b/docs/process/coding-style.rst new file mode 100644 index 000000000..fd1984d30 --- /dev/null +++ b/docs/process/coding-style.rst @@ -0,0 +1,468 @@ +Coding Style +============ + +The following sections outline the |TF-A| coding style for *C* code. The style +is based on the `Linux kernel coding style`_, with a few modifications. + +The style should not be considered *set in stone*. Feel free to provide feedback +and suggestions. + +.. note:: + You will almost certainly find code in the |TF-A| repository that does not + follow the style. The intent is for all code to do so eventually. + +File Encoding +------------- + +The source code must use the **UTF-8** character encoding. Comments and +documentation may use non-ASCII characters when required (e.g. Greek letters +used for units) but code itself is still limited to ASCII characters. + +Newlines must be in **Unix** style, which means that only the Line Feed (``LF``) +character is used to break a line and reset to the first column. + +Language +-------- + +The primary language for comments and naming must be International English. In +cases where there is a conflict between the American English and British English +spellings of a word, the American English spelling is used. + +Exceptions are made when referring directly to something that does not use +international style, such as the name of a company. In these cases the existing +name should be used as-is. + +C Language Standard +------------------- + +The C language mode used for TF-A is *GNU99*. This is the "GNU dialect of ISO +C99", which implies the *ISO C99* standard with GNU extensions. + +Both GCC and Clang compiler toolchains have support for *GNU99* mode, though +Clang does lack support for a small number of GNU extensions. These +missing extensions are rarely used, however, and should not pose a problem. + +MISRA Compliance +---------------- + +TF-A attempts to comply with the `MISRA C:2012 Guidelines`_. Coverity +Static Analysis is used to regularly generate a report of current MISRA defects +and to prevent the addition of new ones. + +It is not possible for the project to follow all MISRA guidelines. We maintain +`a spreadsheet`_ that lists all rules and directives and whether we aim to +comply with them or not. A rationale is given for each deviation. + +.. note:: + Enforcing a rule does not mean that the codebase is free of defects + of that rule, only that they would ideally be removed. + +.. note:: + Third-party libraries are not considered in our MISRA analysis and we do not + intend to modify them to make them MISRA compliant. + +Indentation +----------- + +Use **tabs** for indentation. The use of spaces for indentation is forbidden +except in the case where a term is being indented to a boundary that cannot be +achieved using tabs alone. + +Tab spacing should be set to **8 characters**. + +Trailing whitespace is not allowed and must be trimmed. + +Spacing +------- + +Single spacing should be used around most operators, including: + +- Arithmetic operators (``+``, ``-``, ``/``, ``*``) +- Assignment operators (``=``, ``+=``, etc) +- Boolean operators (``&&``, ``||``) +- Comparison operators (``<``, ``>``, ``==``, etc) + +A space should also be used to separate parentheses and braces when they are not +already separated by a newline, such as for the ``if`` statement in the +following example: + +.. code:: c + + int function_foo(bool bar) + { + if (bar) { + function_baz(); + } + } + +Note that there is no space between the name of a function and the following +parentheses. + +Control statements (``if``, ``for``, ``switch``, ``while``, etc) must be +separated from the following open paranthesis by a single space. The previous +example illustrates this for an ``if`` statement. + +Line Length +----------- + +Line length *should* be at most **80 characters**. This limit does not include +non-printing characters such as the line feed. + +This rule is a *should*, not a must, and it is acceptable to exceed the limit +**slightly** where the readability of the code would otherwise be significantly +reduced. Use your judgement in these cases. + +Blank Lines +----------- + +Functions are usually separated by a single blank line. In certain cases it is +acceptable to use additional blank lines for clarity, if required. + +The file must end with a single newline character. Many editors have the option +to insert this automatically and to trim multiple blank lines at the end of the +file. + +Braces +------ + +Opening Brace Placement +^^^^^^^^^^^^^^^^^^^^^^^ + +Braces follow the **Kernighan and Ritchie (K&R)** style, where the opening brace +is **not** placed on a new line. + +Example for a ``while`` loop: + +.. code:: c + + while (condition) { + foo(); + bar(); + } + +This style applies to all blocks except for functions which, following the Linux +style, **do** place the opening brace on a new line. + +Example for a function: + +.. code:: c + + int my_function(void) + { + int a; + + a = 1; + return a; + } + +Conditional Statement Bodies +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Where conditional statements (such as ``if``, ``for``, ``while`` and ``do``) are +used, braces must be placed around the statements that form the body of the +conditional. This is the case regardless of the number of statements in the +body. + +.. note:: + This is a notable departure from the Linux coding style that has been + adopted to follow MISRA guidelines more closely and to help prevent errors. + +For example, use the following style: + +.. code:: c + + if (condition) { + foo++; + } + +instead of omitting the optional braces around a single statement: + +.. code:: c + + /* This is violating MISRA C 2012: Rule 15.6 */ + if (condition) + foo++; + +The reason for this is to prevent accidental changes to control flow when +modifying the body of the conditional. For example, at a quick glance it is easy +to think that the value of ``bar`` is only incremented if ``condition`` +evaluates to ``true`` but this is not the case - ``bar`` will always be +incremented regardless of the condition evaluation. If the developer forgets to +add braces around the conditional body when adding the ``bar++;`` statement then +the program execution will not proceed as intended. + +.. code:: c + + /* This is violating MISRA C 2012: Rule 15.6 */ + if (condition) + foo++; + bar++; + +Naming +------ + +Functions +^^^^^^^^^ + +Use lowercase for function names, separating multiple words with an underscore +character (``_``). This is sometimes referred to as *Snake Case*. An example is +given below: + +.. code:: c + + void bl2_arch_setup(void) + { + ... + } + +Local Variables and Parameters +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Local variables and function parameters use the same format as function names: +lowercase with underscore separation between multiple words. An example is +given below: + +.. code:: c + + static void set_scr_el3_from_rm(uint32_t type, + uint32_t interrupt_type_flags, + uint32_t security_state) + { + uint32_t flag, bit_pos; + + ... + + } + +Preprocessor Macros +^^^^^^^^^^^^^^^^^^^ + +Identifiers that are defined using preprocessor macros are written in all +uppercase text. + +.. code:: c + + #define BUFFER_SIZE_BYTES 64 + +Function Attributes +------------------- + +Place any function attributes after the function type and before the function +name. + +.. code:: c + + void __init plat_arm_interconnect_init(void); + +Alignment +--------- + +Alignment should be performed primarily with tabs, adding spaces if required to +achieve a granularity that is smaller than the tab size. For example, with a tab +size of eight columns it would be necessary to use one tab character and two +spaces to indent text by ten columns. + +Switch Statement Alignment +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +When using ``switch`` statements, align each ``case`` statement with the +``switch`` so that they are in the same column. + +.. code:: c + + switch (condition) { + case A: + foo(); + case B: + bar(); + default: + baz(); + } + +Pointer Alignment +^^^^^^^^^^^^^^^^^ + +The reference and dereference operators (ampersand and *pointer star*) must be +aligned with the name of the object on which they are operating, as opposed to +the type of the object. + +.. code:: c + + uint8_t *foo; + + foo = &bar; + + +Comments +-------- + +The general rule for comments is that the double-slash style of comment (``//``) +is not allowed. Examples of the allowed comment formats are shown below: + +.. code:: c + + /* + * This example illustrates the first allowed style for multi-line comments. + * + * Blank lines within multi-lines are allowed when they add clarity or when + * they separate multiple contexts. + * + */ + +.. code:: c + + /************************************************************************** + * This is the second allowed style for multi-line comments. + * + * In this style, the first and last lines use asterisks that run the full + * width of the comment at its widest point. + * + * This style can be used for additional emphasis. + * + *************************************************************************/ + +.. code:: c + + /* Single line comments can use this format */ + +.. code:: c + + /*************************************************************************** + * This alternative single-line comment style can also be used for emphasis. + **************************************************************************/ + +Headers and inclusion +--------------------- + +Header guards +^^^^^^^^^^^^^ + +For a header file called "some_driver.h" the style used by |TF-A| is: + +.. code:: c + + #ifndef SOME_DRIVER_H + #define SOME_DRIVER_H + +
+ + #endif /* SOME_DRIVER_H */ + +Include statement ordering +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +All header files that are included by a source file must use the following, +grouped ordering. This is to improve readability (by making it easier to quickly +read through the list of headers) and maintainability. + +#. *System* includes: Header files from the standard *C* library, such as + ``stddef.h`` and ``string.h``. + +#. *Project* includes: Header files under the ``include/`` directory within + |TF-A| are *project* includes. + +#. *Platform* includes: Header files relating to a single, specific platform, + and which are located under the ``plat/`` directory within + |TF-A|, are *platform* includes. + +Within each group, ``#include`` statements must be in alphabetical order, +taking both the file and directory names into account. + +Groups must be separated by a single blank line for clarity. + +The example below illustrates the ordering rules using some contrived header +file names; this type of name reuse should be otherwise avoided. + +.. code:: c + + #include + + #include + #include + #include + #include + + #include "a_header.h" + +Include statement variants +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Two variants of the ``#include`` directive are acceptable in the |TF-A| +codebase. Correct use of the two styles improves readability by suggesting the +location of the included header and reducing ambiguity in cases where generic +and platform-specific headers share a name. + +For header files that are in the same directory as the source file that is +including them, use the ``"..."`` variant. + +For header files that are **not** in the same directory as the source file that +is including them, use the ``<...>`` variant. + +Example (bl1_fwu.c): + +.. code:: c + + #include + #include + #include + + #include "bl1_private.h" + +Typedefs +-------- + +Avoid anonymous typedefs of structs/enums in headers +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +For example, the following definition: + +.. code:: c + + typedef struct { + int arg1; + int arg2; + } my_struct_t; + + +is better written as: + +.. code:: c + + struct my_struct { + int arg1; + int arg2; + }; + +This allows function declarations in other header files that depend on the +struct/enum to forward declare the struct/enum instead of including the +entire header: + +.. code:: c + + struct my_struct; + void my_func(struct my_struct *arg); + +instead of: + +.. code:: c + + #include + void my_func(my_struct_t *arg); + +Some TF definitions use both a struct/enum name **and** a typedef name. This +is discouraged for new definitions as it makes it difficult for TF to comply +with MISRA rule 8.3, which states that "All declarations of an object or +function shall use the same names and type qualifiers". + +The Linux coding standards also discourage new typedefs and checkpatch emits +a warning for this. + +Existing typedefs will be retained for compatibility. + +-------------- + +*Copyright (c) 2020, Arm Limited. All rights reserved.* + +.. _`Linux kernel coding style`: https://www.kernel.org/doc/html/latest/process/coding-style.html +.. _`MISRA C:2012 Guidelines`: https://www.misra.org.uk/Activities/MISRAC/tabid/160/Default.aspx +.. _`a spreadsheet`: https://developer.trustedfirmware.org/file/download/lamajxif3w7c4mpjeoo5/PHID-FILE-fp7c7acszn6vliqomyhn/MISRA-and-TF-Analysis-v1.3.ods diff --git a/docs/process/contributing.rst b/docs/process/contributing.rst index f569fcbe7..68c494baa 100644 --- a/docs/process/contributing.rst +++ b/docs/process/contributing.rst @@ -23,7 +23,7 @@ Making Changes - Make commits of logical units. See these general `Git guidelines`_ for contributing to a project. -- Follow the :ref:`Coding Style & Guidelines`. +- Follow the :ref:`Coding Style` and :ref:`Coding Guidelines`. - Use the checkpatch.pl script provided with the Linux source tree. A Makefile target is provided for convenience. @@ -128,7 +128,7 @@ Binary Components -------------- -*Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.* +*Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.* .. _developer.trustedfirmware.org: https://developer.trustedfirmware.org .. _issue: https://developer.trustedfirmware.org/project/board/1/ diff --git a/docs/process/index.rst b/docs/process/index.rst index 9c12de82f..1cb535405 100644 --- a/docs/process/index.rst +++ b/docs/process/index.rst @@ -8,6 +8,7 @@ Processes & Policies security platform-compatibility-policy + coding-style coding-guidelines contributing faq diff --git a/docs/process/security-hardening.rst b/docs/process/security-hardening.rst index a18a79203..43a572125 100644 --- a/docs/process/security-hardening.rst +++ b/docs/process/security-hardening.rst @@ -1,10 +1,30 @@ -Security hardening -================== +Secure Development Guidelines +============================= This page contains guidance on what to check for additional security measures, including build options that can be modified to improve security or catch issues early in development. +Security considerations +----------------------- + +Part of the security of a platform is handling errors correctly, as described in +the previous section. There are several other security considerations covered in +this section. + +Do not leak secrets to the normal world +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The secure world **must not** leak secrets to the normal world, for example in +response to an SMC. + +Handling Denial of Service attacks +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The secure world **should never** crash or become unusable due to receiving too +many normal world requests (a *Denial of Service* or *DoS* attack). It should +have a mechanism for throttling or ignoring normal world requests. + Build options ------------- @@ -53,4 +73,4 @@ Several build options can be used to check for security issues. Refer to the -------------- -*Copyright (c) 2019, Arm Limited. All rights reserved.* +*Copyright (c) 2019-2020, Arm Limited. All rights reserved.* -- cgit v1.2.3 From 64271c74050de5e50db0f965c0bc8cd37fc7b7f3 Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Fri, 17 Jan 2020 16:10:45 +0000 Subject: fvp: Slightly Bump the stack size for bl1 and bl2 Stack usage reaches 90% with some configuration. Bump slightly the stack size to prevent a stack-overflow. Change-Id: I44ce8b12906586a42f152b7677785fcdc5e78ae1 Signed-off-by: Louis Mayencourt --- plat/arm/board/fvp/include/platform_def.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h index c2b7b98d4..602ea6def 100644 --- a/plat/arm/board/fvp/include/platform_def.h +++ b/plat/arm/board/fvp/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -139,13 +139,13 @@ # if TRUSTED_BOARD_BOOT # define PLATFORM_STACK_SIZE UL(0x1000) # else -# define PLATFORM_STACK_SIZE UL(0x440) +# define PLATFORM_STACK_SIZE UL(0x500) # endif #elif defined(IMAGE_BL2) # if TRUSTED_BOARD_BOOT # define PLATFORM_STACK_SIZE UL(0x1000) # else -# define PLATFORM_STACK_SIZE UL(0x400) +# define PLATFORM_STACK_SIZE UL(0x440) # endif #elif defined(IMAGE_BL2U) # define PLATFORM_STACK_SIZE UL(0x400) -- cgit v1.2.3 From a6ffddec33be0f10382f0f66eacafb03492c8141 Mon Sep 17 00:00:00 2001 From: Max Shvetsov Date: Fri, 6 Dec 2019 11:50:12 +0000 Subject: Adds option to read ROTPK from registers for FVP Enables usage of ARM_ROTPK_LOCATION=regs for FVP board. Removes hard-coded developer keys. Instead, setting ARM_ROTPK_LOCATION=devel_* takes keys from default directory. In case of ROT_KEY specified - generates a new hash and replaces the original. Note: Juno board was tested by original feature author and was not tested for this patch since we don't have access to the private key. Juno implementation was moved to board-specific file without changing functionality. It is not known whether byte-swapping is still needed for this platform. Change-Id: I0fdbaca0415cdcd78f3a388551c2e478c01ed986 Signed-off-by: Max Shvetsov --- docs/design/trusted-board-boot-build.rst | 21 ++- docs/getting_started/build-options.rst | 5 +- docs/plat/arm/arm-build-options.rst | 11 +- include/plat/arm/common/arm_def.h | 6 + include/plat/arm/common/plat_arm.h | 17 +- plat/arm/board/common/board_arm_trusted_boot.c | 204 ++++++++++-------------- plat/arm/board/common/board_common.mk | 85 ++++++---- plat/arm/board/common/rotpk/arm_dev_rotpk.S | 26 +++ plat/arm/board/fvp/fvp_trusted_boot.c | 23 ++- plat/arm/board/fvp/platform.mk | 8 +- plat/arm/board/juno/juno_trusted_boot.c | 126 +++++++++++++++ plat/arm/board/juno/platform.mk | 7 +- plat/arm/board/rde1edge/platform.mk | 5 + plat/arm/board/rde1edge/rde1edge_trusted_boot.c | 26 +++ plat/arm/board/rdn1edge/platform.mk | 5 + plat/arm/board/rdn1edge/rdn1edge_trusted_boot.c | 26 +++ plat/arm/board/sgi575/platform.mk | 5 + plat/arm/board/sgi575/sgi575_trusted_boot.c | 26 +++ plat/arm/board/sgm775/platform.mk | 7 +- plat/arm/board/sgm775/sgm775_trusted_boot.c | 26 +++ 20 files changed, 487 insertions(+), 178 deletions(-) create mode 100644 plat/arm/board/common/rotpk/arm_dev_rotpk.S create mode 100644 plat/arm/board/juno/juno_trusted_boot.c create mode 100644 plat/arm/board/rde1edge/rde1edge_trusted_boot.c create mode 100644 plat/arm/board/rdn1edge/rdn1edge_trusted_boot.c create mode 100644 plat/arm/board/sgi575/sgi575_trusted_boot.c create mode 100644 plat/arm/board/sgm775/sgm775_trusted_boot.c diff --git a/docs/design/trusted-board-boot-build.rst b/docs/design/trusted-board-boot-build.rst index 202524316..f5c8bc98c 100644 --- a/docs/design/trusted-board-boot-build.rst +++ b/docs/design/trusted-board-boot-build.rst @@ -33,7 +33,7 @@ images with support for these features: - ``GENERATE_COT=1`` In the case of Arm platforms, the location of the ROTPK hash must also be - specified at build time. Two locations are currently supported (see + specified at build time. The following locations are currently supported (see ``ARM_ROTPK_LOCATION`` build option): - ``ARM_ROTPK_LOCATION=regs``: the ROTPK hash is obtained from the Trusted @@ -41,17 +41,16 @@ images with support for these features: registers are read-only. On FVP Base and Cortex models, the registers are read-only, but the value can be specified using the command line option ``bp.trusted_key_storage.public_key`` when launching the model. - On both Juno and FVP models, the default value corresponds to an - ECDSA-SECP256R1 public key hash, whose private part is not currently - available. + On Juno board, the default value corresponds to an ECDSA-SECP256R1 public + key hash, whose private part is not currently available. - - ``ARM_ROTPK_LOCATION=devel_rsa``: use the ROTPK hash that is hardcoded - in the Arm platform port. The private/public RSA key pair may be - found in ``plat/arm/board/common/rotpk``. + - ``ARM_ROTPK_LOCATION=devel_rsa``: use the default hash located in + plat/arm/board/common/rotpk/arm_rotpk_rsa_sha256.bin. Enforce generation + of the new hash if ROT_KEY is specified. - - ``ARM_ROTPK_LOCATION=devel_ecdsa``: use the ROTPK hash that is hardcoded - in the Arm platform port. The private/public ECDSA key pair may be - found in ``plat/arm/board/common/rotpk``. + - ``ARM_ROTPK_LOCATION=devel_ecdsa``: use the default hash located in + plat/arm/board/common/rotpk/arm_rotpk_ecdsa_sha256.bin. Enforce generation + of the new hash if ROT_KEY is specified. Example of command line using RSA development keys: @@ -108,7 +107,7 @@ images with support for these features: -------------- -*Copyright (c) 2019, Arm Limited. All rights reserved.* +*Copyright (c) 2019-2020, Arm Limited. All rights reserved.* .. _mbed TLS Repository: https://github.com/ARMmbed/mbedtls.git .. _mbed TLS Security Center: https://tls.mbed.org/security diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 2f44fe817..13d7058e4 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -468,7 +468,8 @@ Common build options entrypoint) or 1 (CPU reset to SP_MIN entrypoint). The default value is 0. - ``ROT_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the - file that contains the ROT private key in PEM format. If ``SAVE_KEYS=1``, this + file that contains the ROT private key in PEM format and enforces public key + hash generation. If ``SAVE_KEYS=1``, this file name will be used to save the key. - ``SAVE_KEYS``: This option is used when ``GENERATE_COT=1``. It tells the @@ -657,4 +658,4 @@ commands can be used: -------------- -*Copyright (c) 2019, Arm Limited. All rights reserved.* +*Copyright (c) 2019-2020, Arm Limited. All rights reserved.* diff --git a/docs/plat/arm/arm-build-options.rst b/docs/plat/arm/arm-build-options.rst index d24ad231d..a6f3796b9 100644 --- a/docs/plat/arm/arm-build-options.rst +++ b/docs/plat/arm/arm-build-options.rst @@ -57,8 +57,7 @@ Arm Platform Build Options ``ARM_ROTPK_LOCATION`` are: - ``regs`` : return the ROTPK hash stored in the Trusted root-key storage - registers. The private key corresponding to this ROTPK hash is not - currently available. + registers. - ``devel_rsa`` : return a development public key hash embedded in the BL1 and BL2 binaries. This hash has been obtained from the RSA public key ``arm_rotpk_rsa.der``, located in ``plat/arm/board/common/rotpk``. To use @@ -70,6 +69,12 @@ Arm Platform Build Options use this option, ``arm_rotprivk_ecdsa.pem`` must be specified as ``ROT_KEY`` when creating the certificates. +- ``ARM_ROTPK_HASH``: used when ``ARM_ROTPK_LOCATION=devel_*``. Specifies the + location of the ROTPK hash. Not expected to be a build option. This defaults to + ``plat/arm/board/common/rotpk/*_sha256.bin`` depending on the specified algorithm. + Providing ``ROT_KEY`` enforces generation of the hash from the ``ROT_KEY`` and + overwrites the default hash file. + - ``ARM_TSP_RAM_LOCATION``: location of the TSP binary. Options: - ``tsram`` : Trusted SRAM (default option when TBB is not enabled) @@ -111,4 +116,4 @@ Arm CSS Platform-Specific Build Options -------------- -*Copyright (c) 2019, Arm Limited. All rights reserved.* +*Copyright (c) 2019-2020, Arm Limited. All rights reserved.* diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index 5bd53f3b5..c825bf4dc 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -18,6 +18,12 @@ * Definitions common to all ARM standard platforms *****************************************************************************/ +/* + * Root of trust key hash lengths + */ +#define ARM_ROTPK_HEADER_LEN 19 +#define ARM_ROTPK_HASH_LEN 32 + /* Special value used to verify platform parameters from BL2 to BL31 */ #define ARM_BL31_PLAT_PARAM_VAL ULL(0x0f1e2d3c4b5a6978) diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index 02feec708..32dc9f93d 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -142,6 +142,11 @@ void arm_setup_romlib(void); #define STATE_SW_E_PARAM (-2) #define STATE_SW_E_DENIED (-3) +/* plat_get_rotpk_info() flags */ +#define ARM_ROTPK_REGS_ID 1 +#define ARM_ROTPK_DEVEL_RSA_ID 2 +#define ARM_ROTPK_DEVEL_ECDSA_ID 3 + /* IO storage utility functions */ void arm_io_setup(void); @@ -255,9 +260,17 @@ int plat_arm_bl1_fwu_needed(void); __dead2 void plat_arm_error_handler(int err); /* - * Optional function in ARM standard platforms + * Optional functions in ARM standard platforms */ void plat_arm_override_gicr_frames(const uintptr_t *plat_gicr_frames); +int arm_get_rotpk_info(void **key_ptr, unsigned int *key_len, + unsigned int *flags); +int arm_get_rotpk_info_regs(void **key_ptr, unsigned int *key_len, + unsigned int *flags); +int arm_get_rotpk_info_cc(void **key_ptr, unsigned int *key_len, + unsigned int *flags); +int arm_get_rotpk_info_dev(void **key_ptr, unsigned int *key_len, + unsigned int *flags); #if ARM_PLAT_MT unsigned int plat_arm_get_cpu_pe_count(u_register_t mpidr); diff --git a/plat/arm/board/common/board_arm_trusted_boot.c b/plat/arm/board/common/board_arm_trusted_boot.c index c71e932a0..3c19230bd 100644 --- a/plat/arm/board/common/board_arm_trusted_boot.c +++ b/plat/arm/board/common/board_arm_trusted_boot.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -8,130 +8,61 @@ #include #include +#include +#include +#include #include +#include +#include #include -#include #include +#include -/* SHA256 algorithm */ -#define SHA256_BYTES 32 - -/* ROTPK locations */ -#define ARM_ROTPK_REGS_ID 1 -#define ARM_ROTPK_DEVEL_RSA_ID 2 -#define ARM_ROTPK_DEVEL_ECDSA_ID 3 - -static const unsigned char rotpk_hash_hdr[] = \ - "\x30\x31\x30\x0D\x06\x09\x60\x86\x48" \ - "\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20"; -static const unsigned int rotpk_hash_hdr_len = sizeof(rotpk_hash_hdr) - 1; -static unsigned char rotpk_hash_der[sizeof(rotpk_hash_hdr) - 1 + SHA256_BYTES]; -/* Use the cryptocell variants if Cryptocell is present */ #if !ARM_CRYPTOCELL_INTEG #if !ARM_ROTPK_LOCATION_ID #error "ARM_ROTPK_LOCATION_ID not defined" #endif +#endif /* Weak definition may be overridden in specific platform */ #pragma weak plat_get_nv_ctr #pragma weak plat_set_nv_ctr -#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) -static const unsigned char arm_devel_rotpk_hash[] = \ - "\xB0\xF3\x82\x09\x12\x97\xD8\x3A" \ - "\x37\x7A\x72\x47\x1B\xEC\x32\x73" \ - "\xE9\x92\x32\xE2\x49\x59\xF6\x5E" \ - "\x8B\x4A\x4A\x46\xD8\x22\x9A\xDA"; -#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) -static const unsigned char arm_devel_rotpk_hash[] = \ - "\x2E\x40\xBF\x6E\xF9\x12\xBB\x98" \ - "\x31\x71\x09\x0E\x1E\x15\x3D\x0B" \ - "\xFD\xD1\xCC\x69\x4A\x98\xEB\x8B" \ - "\xA0\xB0\x20\x86\x4E\x6C\x07\x17"; -#endif +extern unsigned char arm_rotpk_header[], arm_rotpk_hash_end[]; + +static unsigned char rotpk_hash_der[ARM_ROTPK_HEADER_LEN + ARM_ROTPK_HASH_LEN]; /* - * 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 - * } + * Return the ROTPK hash stored in dedicated registers. */ -int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, +int arm_get_rotpk_info_regs(void **key_ptr, unsigned int *key_len, unsigned int *flags) { uint8_t *dst; + uint32_t *src, tmp; + unsigned int words, i; assert(key_ptr != NULL); assert(key_len != NULL); assert(flags != NULL); /* Copy the DER header */ - memcpy(rotpk_hash_der, rotpk_hash_hdr, rotpk_hash_hdr_len); - dst = (uint8_t *)&rotpk_hash_der[rotpk_hash_hdr_len]; -#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) \ - || (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) - memcpy(dst, arm_devel_rotpk_hash, SHA256_BYTES); -#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID) - uint32_t *src, tmp; - unsigned int words, i; + memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN); + dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HEADER_LEN]; + + words = ARM_ROTPK_HASH_LEN >> 2; - /* - * Append the hash from Trusted Root-Key Storage registers. The hash has - * not been written linearly into the registers, so we have to do a bit - * of byte swapping: - * - * 0x00 0x04 0x08 0x0C 0x10 0x14 0x18 0x1C - * +---------------------------------------------------------------+ - * | Reg0 | Reg1 | Reg2 | Reg3 | Reg4 | Reg5 | Reg6 | Reg7 | - * +---------------------------------------------------------------+ - * | ... ... | | ... ... | - * | +--------------------+ | +-------+ - * | | | | - * +----------------------------+ +----------------------------+ - * | | | | - * +-------+ | +--------------------+ | - * | | | | - * v v v v - * +---------------------------------------------------------------+ - * | | | - * +---------------------------------------------------------------+ - * 0 15 16 31 - * - * Additionally, we have to access the registers in 32-bit words - */ - words = SHA256_BYTES >> 3; - - /* Swap bytes 0-15 (first four registers) */ src = (uint32_t *)TZ_PUB_KEY_HASH_BASE; for (i = 0 ; i < words ; i++) { tmp = src[words - 1 - i]; /* Words are read in little endian */ - *dst++ = (uint8_t)((tmp >> 24) & 0xFF); - *dst++ = (uint8_t)((tmp >> 16) & 0xFF); - *dst++ = (uint8_t)((tmp >> 8) & 0xFF); *dst++ = (uint8_t)(tmp & 0xFF); - } - - /* Swap bytes 16-31 (last four registers) */ - src = (uint32_t *)(TZ_PUB_KEY_HASH_BASE + SHA256_BYTES / 2); - for (i = 0 ; i < words ; i++) { - tmp = src[words - 1 - i]; - *dst++ = (uint8_t)((tmp >> 24) & 0xFF); - *dst++ = (uint8_t)((tmp >> 16) & 0xFF); *dst++ = (uint8_t)((tmp >> 8) & 0xFF); - *dst++ = (uint8_t)(tmp & 0xFF); + *dst++ = (uint8_t)((tmp >> 16) & 0xFF); + *dst++ = (uint8_t)((tmp >> 24) & 0xFF); } -#endif /* (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) \ - || (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) */ *key_ptr = (void *)rotpk_hash_der; *key_len = (unsigned int)sizeof(rotpk_hash_der); @@ -139,6 +70,65 @@ int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, return 0; } +#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \ + (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) +/* + * Return development ROTPK hash generated from ROT_KEY. + */ +int arm_get_rotpk_info_dev(void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ + *key_ptr = arm_rotpk_header; + *key_len = arm_rotpk_hash_end - arm_rotpk_header; + *flags = ROTPK_IS_HASH; + return 0; +} +#endif + +#if ARM_CRYPTOCELL_INTEG +/* + * Return ROTPK hash from CryptoCell. + */ +int arm_get_rotpk_info_cc(void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ + unsigned char *dst; + + assert(key_ptr != NULL); + assert(key_len != NULL); + assert(flags != NULL); + + /* Copy the DER header */ + memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN); + dst = &rotpk_hash_der[ARM_ROTPK_HEADER_LEN]; + *key_ptr = rotpk_hash_der; + *key_len = sizeof(rotpk_hash_der); + return cc_get_rotpk_hash(dst, ARM_ROTPK_HASH_LEN, flags); +} +#endif + +/* + * Wraper function for most Arm platforms to get ROTPK hash. + */ +int arm_get_rotpk_info(void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ +#if ARM_CRYPTOCELL_INTEG + return arm_get_rotpk_info_cc(key_ptr, key_len, flags); +#else + +#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \ + (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) + return arm_get_rotpk_info_dev(key_ptr, key_len, flags); +#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID) + return arm_get_rotpk_info_regs(key_ptr, key_len, flags); +#else + return 1; +#endif + +#endif /* ARM_CRYPTOCELL_INTEG */ +} + /* * Return the non-volatile counter value stored in the platform. The cookie * will contain the OID of the counter in the certificate. @@ -179,37 +169,3 @@ int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr) { return 1; } -#else /* ARM_CRYPTOCELL_INTEG */ - -#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) -{ - unsigned char *dst; - - assert(key_ptr != NULL); - assert(key_len != NULL); - assert(flags != NULL); - - /* Copy the DER header */ - memcpy(rotpk_hash_der, rotpk_hash_hdr, rotpk_hash_hdr_len); - dst = &rotpk_hash_der[rotpk_hash_hdr_len]; - *key_ptr = rotpk_hash_der; - *key_len = sizeof(rotpk_hash_der); - return cc_get_rotpk_hash(dst, SHA256_BYTES, flags); -} -#endif /* ARM_CRYPTOCELL_INTEG */ diff --git a/plat/arm/board/common/board_common.mk b/plat/arm/board/common/board_common.mk index b98dfd48b..da6343045 100644 --- a/plat/arm/board/common/board_common.mk +++ b/plat/arm/board/common/board_common.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -12,31 +12,60 @@ BL1_SOURCES += drivers/cfi/v2m/v2m_flash.c BL2_SOURCES += drivers/cfi/v2m/v2m_flash.c ifneq (${TRUSTED_BOARD_BOOT},0) - ifneq (${ARM_CRYPTOCELL_INTEG}, 1) - # ROTPK hash location - ifeq (${ARM_ROTPK_LOCATION}, regs) - ARM_ROTPK_LOCATION_ID = ARM_ROTPK_REGS_ID - else ifeq (${ARM_ROTPK_LOCATION}, devel_rsa) - KEY_ALG := rsa - ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_RSA_ID - else ifeq (${ARM_ROTPK_LOCATION}, devel_ecdsa) - KEY_ALG := ecdsa - ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_ECDSA_ID - else - $(error "Unsupported ARM_ROTPK_LOCATION value") - endif - $(eval $(call add_define,ARM_ROTPK_LOCATION_ID)) - - # Certificate NV-Counters. Use values corresponding to tied off values in - # ARM development platforms - TFW_NVCTR_VAL ?= 31 - NTFW_NVCTR_VAL ?= 223 - else - # Certificate NV-Counters when CryptoCell is integrated. For development - # platforms we set the counter to first valid value. - TFW_NVCTR_VAL ?= 0 - NTFW_NVCTR_VAL ?= 0 - endif - BL1_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c - BL2_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c +ifneq (${ARM_CRYPTOCELL_INTEG}, 1) +# ROTPK hash location +ifeq (${ARM_ROTPK_LOCATION}, regs) + ARM_ROTPK_LOCATION_ID = ARM_ROTPK_REGS_ID +else ifeq (${ARM_ROTPK_LOCATION}, devel_rsa) + KEY_ALG := rsa + ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_RSA_ID + ARM_ROTPK_HASH = plat/arm/board/common/rotpk/arm_rotpk_rsa_sha256.bin +$(eval $(call add_define_val,ARM_ROTPK_HASH,'"$(ARM_ROTPK_HASH)"')) +$(BUILD_PLAT)/bl2/arm_dev_rotpk.o : $(ARM_ROTPK_HASH) +$(warning Development keys support for FVP is deprecated. Use `regs` \ +option instead) +else ifeq (${ARM_ROTPK_LOCATION}, devel_ecdsa) + KEY_ALG := ecdsa + ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_ECDSA_ID + ARM_ROTPK_HASH = plat/arm/board/common/rotpk/arm_rotpk_ecdsa_sha256.bin +$(eval $(call add_define_val,ARM_ROTPK_HASH,'"$(ARM_ROTPK_HASH)"')) +$(BUILD_PLAT)/bl2/arm_dev_rotpk.o : $(ARM_ROTPK_HASH) +$(warning Development keys support for FVP is deprecated. Use `regs` \ +option instead) +else + $(error "Unsupported ARM_ROTPK_LOCATION value") +endif + +$(eval $(call add_define,ARM_ROTPK_LOCATION_ID)) + +# Force generation of the new hash if ROT_KEY is specified +ifdef ROT_KEY + HASH_PREREQUISITES = $(ROT_KEY) FORCE +FORCE: +else + HASH_PREREQUISITES = $(ROT_KEY) +endif + +$(ARM_ROTPK_HASH) : $(HASH_PREREQUISITES) +ifndef ROT_KEY + $(error Cannot generate hash: no ROT_KEY defined) +endif + openssl rsa -in $< -pubout -outform DER | openssl dgst \ + -sha256 -binary > $@ + +# Certificate NV-Counters. Use values corresponding to tied off values in +# ARM development platforms +TFW_NVCTR_VAL ?= 31 +NTFW_NVCTR_VAL ?= 223 +else +# Certificate NV-Counters when CryptoCell is integrated. For development +# platforms we set the counter to first valid value. +TFW_NVCTR_VAL ?= 0 +NTFW_NVCTR_VAL ?= 0 +endif +BL1_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c \ + plat/arm/board/common/rotpk/arm_dev_rotpk.S +BL2_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c \ + plat/arm/board/common/rotpk/arm_dev_rotpk.S + endif diff --git a/plat/arm/board/common/rotpk/arm_dev_rotpk.S b/plat/arm/board/common/rotpk/arm_dev_rotpk.S new file mode 100644 index 000000000..80f2192e4 --- /dev/null +++ b/plat/arm/board/common/rotpk/arm_dev_rotpk.S @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "plat/arm/common/arm_def.h" + + .global arm_rotpk_header + .global arm_rotpk_header_end + .section .rodata.arm_rotpk_hash, "a" + +arm_rotpk_header: + .byte 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48 + .byte 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 +arm_rotpk_header_len: + +#ifdef ARM_ROTPK_HASH + .global arm_rotpk_hash_end + .incbin ARM_ROTPK_HASH +arm_rotpk_hash_end: +#endif + +.if ARM_ROTPK_HEADER_LEN != arm_rotpk_header_len - arm_rotpk_header +.error "Invalid ROTPK header length." +.endif diff --git a/plat/arm/board/fvp/fvp_trusted_boot.c b/plat/arm/board/fvp/fvp_trusted_boot.c index dc5076435..a09b80e10 100644 --- a/plat/arm/board/fvp/fvp_trusted_boot.c +++ b/plat/arm/board/fvp/fvp_trusted_boot.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,11 +9,30 @@ #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(key_ptr, key_len, flags); +} + /* * Store a new non-volatile counter value. * diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 97a326c09..6fb34c48a 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -139,7 +139,6 @@ BL1_SOURCES += drivers/arm/smmu/smmu_v3.c \ plat/arm/board/fvp/fvp_bl1_setup.c \ plat/arm/board/fvp/fvp_err.c \ plat/arm/board/fvp/fvp_io_storage.c \ - plat/arm/board/fvp/fvp_trusted_boot.c \ ${FVP_CPU_LIBS} \ ${FVP_INTERCONNECT_SOURCES} @@ -158,7 +157,6 @@ BL2_SOURCES += drivers/arm/sp805/sp805.c \ plat/arm/board/fvp/fvp_bl2_setup.c \ plat/arm/board/fvp/fvp_err.c \ plat/arm/board/fvp/fvp_io_storage.c \ - plat/arm/board/fvp/fvp_trusted_boot.c \ plat/arm/common/arm_nor_psci_mem_protect.c \ ${FVP_SECURITY_SOURCES} @@ -302,8 +300,10 @@ 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/fvp_trusted_boot.c +BL2_SOURCES += plat/arm/board/fvp/fvp_trusted_boot.c # FVP being a development platform, enable capability to disable Authentication # dynamically if TRUSTED_BOARD_BOOT is set. -ifeq (${TRUSTED_BOARD_BOOT}, 1) - DYN_DISABLE_AUTH := 1 +DYN_DISABLE_AUTH := 1 endif diff --git a/plat/arm/board/juno/juno_trusted_boot.c b/plat/arm/board/juno/juno_trusted_boot.c new file mode 100644 index 000000000..25a74705d --- /dev/null +++ b/plat/arm/board/juno/juno_trusted_boot.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2019-2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include +#include +#include +#include + +#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID) + +static unsigned char rotpk_hash_der[ARM_ROTPK_HEADER_LEN + ARM_ROTPK_HASH_LEN]; + +extern unsigned char arm_rotpk_header[]; + +/* + * Return the ROTPK hash stored in the registers of Juno board. + */ +static int juno_get_rotpk_info_regs(void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ + uint8_t *dst; + uint32_t *src, tmp; + unsigned int words, i; + + assert(key_ptr != NULL); + assert(key_len != NULL); + assert(flags != NULL); + + /* Copy the DER header */ + memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN); + dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HEADER_LEN]; + + + /* + * Append the hash from Trusted Root-Key Storage registers. The hash has + * not been written linearly into the registers, so we have to do a bit + * of byte swapping: + * + * 0x00 0x04 0x08 0x0C 0x10 0x14 0x18 0x1C + * +---------------------------------------------------------------+ + * | Reg0 | Reg1 | Reg2 | Reg3 | Reg4 | Reg5 | Reg6 | Reg7 | + * +---------------------------------------------------------------+ + * | ... ... | | ... ... | + * | +--------------------+ | +-------+ + * | | | | + * +----------------------------+ +----------------------------+ + * | | | | + * +-------+ | +--------------------+ | + * | | | | + * v v v v + * +---------------------------------------------------------------+ + * | | | + * +---------------------------------------------------------------+ + * 0 15 16 31 + * + * Additionally, we have to access the registers in 32-bit words + */ + words = ARM_ROTPK_HASH_LEN >> 3; + + /* Swap bytes 0-15 (first four registers) */ + src = (uint32_t *)TZ_PUB_KEY_HASH_BASE; + for (i = 0 ; i < words ; i++) { + tmp = src[words - 1 - i]; + /* Words are read in little endian */ + *dst++ = (uint8_t)((tmp >> 24) & 0xFF); + *dst++ = (uint8_t)((tmp >> 16) & 0xFF); + *dst++ = (uint8_t)((tmp >> 8) & 0xFF); + *dst++ = (uint8_t)(tmp & 0xFF); + } + + /* Swap bytes 16-31 (last four registers) */ + src = (uint32_t *)(TZ_PUB_KEY_HASH_BASE + ARM_ROTPK_HASH_LEN / 2); + for (i = 0 ; i < words ; i++) { + tmp = src[words - 1 - i]; + *dst++ = (uint8_t)((tmp >> 24) & 0xFF); + *dst++ = (uint8_t)((tmp >> 16) & 0xFF); + *dst++ = (uint8_t)((tmp >> 8) & 0xFF); + *dst++ = (uint8_t)(tmp & 0xFF); + } + + *key_ptr = (void *)rotpk_hash_der; + *key_len = (unsigned int)sizeof(rotpk_hash_der); + *flags = ROTPK_IS_HASH; + return 0; +} + +#endif + +/* + * 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) +{ +#if ARM_CRYPTOCELL_INTEG + return arm_get_rotpk_info_cc(key_ptr, key_len, flags); +#else + +#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \ + (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) + return arm_get_rotpk_info_dev(key_ptr, key_len, flags); +#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID) + return juno_get_rotpk_info_regs(key_ptr, key_len, flags); +#else + return 1; +#endif + +#endif /* ARM_CRYPTOCELL_INTEG */ +} diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk index bd6bae536..a85ad5376 100644 --- a/plat/arm/board/juno/platform.mk +++ b/plat/arm/board/juno/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -91,6 +91,11 @@ ifeq (${CSS_USE_SCMI_SDS_DRIVER},1) BL1_SOURCES += drivers/arm/css/sds/sds.c endif +ifeq (${TRUSTED_BOARD_BOOT}, 1) +BL1_SOURCES += plat/arm/board/juno/juno_trusted_boot.c +BL2_SOURCES += plat/arm/board/juno/juno_trusted_boot.c +endif + endif ifneq (${RESET_TO_BL31},0) diff --git a/plat/arm/board/rde1edge/platform.mk b/plat/arm/board/rde1edge/platform.mk index 43c37ffc1..13a3de3de 100644 --- a/plat/arm/board/rde1edge/platform.mk +++ b/plat/arm/board/rde1edge/platform.mk @@ -29,6 +29,11 @@ BL31_SOURCES += ${SGI_CPU_SOURCES} \ lib/utils/mem_region.c \ plat/arm/common/arm_nor_psci_mem_protect.c +ifeq (${TRUSTED_BOARD_BOOT}, 1) +BL1_SOURCES += ${RDE1EDGE_BASE}/rde1edge_trusted_boot.c +BL2_SOURCES += ${RDE1EDGE_BASE}/rde1edge_trusted_boot.c +endif + # Add the FDT_SOURCES and options for Dynamic Config FDT_SOURCES += ${RDE1EDGE_BASE}/fdts/${PLAT}_tb_fw_config.dts TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb diff --git a/plat/arm/board/rde1edge/rde1edge_trusted_boot.c b/plat/arm/board/rde1edge/rde1edge_trusted_boot.c new file mode 100644 index 000000000..c271f7f2d --- /dev/null +++ b/plat/arm/board/rde1edge/rde1edge_trusted_boot.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#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(key_ptr, key_len, flags); +} diff --git a/plat/arm/board/rdn1edge/platform.mk b/plat/arm/board/rdn1edge/platform.mk index ca1e95eaf..84a21b9b6 100644 --- a/plat/arm/board/rdn1edge/platform.mk +++ b/plat/arm/board/rdn1edge/platform.mk @@ -29,6 +29,11 @@ BL31_SOURCES += ${SGI_CPU_SOURCES} \ lib/utils/mem_region.c \ plat/arm/common/arm_nor_psci_mem_protect.c +ifeq (${TRUSTED_BOARD_BOOT}, 1) +BL1_SOURCES += ${RDN1EDGE_BASE}/rdn1edge_trusted_boot.c +BL2_SOURCES += ${RDN1EDGE_BASE}/rdn1edge_trusted_boot.c +endif + # Add the FDT_SOURCES and options for Dynamic Config FDT_SOURCES += ${RDN1EDGE_BASE}/fdts/${PLAT}_tb_fw_config.dts TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb diff --git a/plat/arm/board/rdn1edge/rdn1edge_trusted_boot.c b/plat/arm/board/rdn1edge/rdn1edge_trusted_boot.c new file mode 100644 index 000000000..c271f7f2d --- /dev/null +++ b/plat/arm/board/rdn1edge/rdn1edge_trusted_boot.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#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(key_ptr, key_len, flags); +} diff --git a/plat/arm/board/sgi575/platform.mk b/plat/arm/board/sgi575/platform.mk index ce2717fe0..c6b2d41f6 100644 --- a/plat/arm/board/sgi575/platform.mk +++ b/plat/arm/board/sgi575/platform.mk @@ -29,6 +29,11 @@ BL31_SOURCES += ${SGI_CPU_SOURCES} \ lib/utils/mem_region.c \ plat/arm/common/arm_nor_psci_mem_protect.c +ifeq (${TRUSTED_BOARD_BOOT}, 1) +BL1_SOURCES += ${SGI575_BASE}/sgi575_trusted_boot.c +BL2_SOURCES += ${SGI575_BASE}/sgi575_trusted_boot.c +endif + # Add the FDT_SOURCES and options for Dynamic Config FDT_SOURCES += ${SGI575_BASE}/fdts/${PLAT}_tb_fw_config.dts TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb diff --git a/plat/arm/board/sgi575/sgi575_trusted_boot.c b/plat/arm/board/sgi575/sgi575_trusted_boot.c new file mode 100644 index 000000000..c271f7f2d --- /dev/null +++ b/plat/arm/board/sgi575/sgi575_trusted_boot.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#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(key_ptr, key_len, flags); +} diff --git a/plat/arm/board/sgm775/platform.mk b/plat/arm/board/sgm775/platform.mk index 7a843c369..f096ca53d 100644 --- a/plat/arm/board/sgm775/platform.mk +++ b/plat/arm/board/sgm775/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -21,3 +21,8 @@ BL2_SOURCES += lib/utils/mem_region.c \ BL31_SOURCES += drivers/cfi/v2m/v2m_flash.c \ lib/utils/mem_region.c \ plat/arm/common/arm_nor_psci_mem_protect.c + +ifeq (${TRUSTED_BOARD_BOOT}, 1) +BL1_SOURCES += ${SGM775_BASE}/sgm775_trusted_boot.c +BL2_SOURCES += ${SGM775_BASE}/sgm775_trusted_boot.c +endif diff --git a/plat/arm/board/sgm775/sgm775_trusted_boot.c b/plat/arm/board/sgm775/sgm775_trusted_boot.c new file mode 100644 index 000000000..c271f7f2d --- /dev/null +++ b/plat/arm/board/sgm775/sgm775_trusted_boot.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#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(key_ptr, key_len, flags); +} -- cgit v1.2.3 From 1a87db5d117d15b17ab234b9c5a4102f6fb39f5e Mon Sep 17 00:00:00 2001 From: "Abdul Halim, Muhammad Hadi Asyrafi" Date: Thu, 6 Feb 2020 19:18:41 +0800 Subject: intel: Include address range check for SiP Mailbox This patch modify current address range checker in SiP driver to also accept input size. Also, include said checker for SiP mailbox send command to ensure referenced argument is within expected address. Signed-off-by: Abdul Halim, Muhammad Hadi Asyrafi Change-Id: Ie0c3cac4c3d1a6ea0194602d9aa3541f5d9a3367 --- plat/intel/soc/common/socfpga_sip_svc.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c index b4fe6d638..5b600e5ea 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -252,12 +252,16 @@ static bool is_fpga_config_buffer_full(void) return true; } -static bool is_address_in_ddr_range(uint64_t addr) +static bool is_address_in_ddr_range(uint64_t addr, uint64_t size) { - if (addr >= DRAM_BASE && addr <= DRAM_BASE + DRAM_SIZE) - return true; + if (size > (UINT64_MAX - addr)) + return false; + if (addr < DRAM_BASE) + return false; + if (addr + size > DRAM_BASE + DRAM_SIZE) + return false; - return false; + return true; } static uint32_t intel_fpga_config_write(uint64_t mem, uint64_t size) @@ -266,8 +270,7 @@ static uint32_t intel_fpga_config_write(uint64_t mem, uint64_t size) intel_fpga_sdm_write_all(); - if (!is_address_in_ddr_range(mem) || - !is_address_in_ddr_range(mem + size) || + if (!is_address_in_ddr_range(mem, size) || is_fpga_config_buffer_full()) return INTEL_SIP_SMC_STATUS_REJECTED; @@ -406,11 +409,16 @@ static uint32_t intel_mbox_send_cmd(uint32_t cmd, uint32_t *args, int len, int resp_len, int *mbox_status, int *len_in_resp) { + *len_in_resp = 0; + *mbox_status = 0; + + if (!is_address_in_ddr_range((uint64_t)args, sizeof(uint32_t) * len)) + return INTEL_SIP_SMC_STATUS_REJECTED; + int status = mailbox_send_cmd(MBOX_JOB_ID, cmd, args, len, urgent, response, resp_len); if (status < 0) { - *len_in_resp = 0; *mbox_status = -status; return INTEL_SIP_SMC_STATUS_ERROR; } -- cgit v1.2.3 From e7a5403358bca60a82e6c6d54608f1e2adb83a09 Mon Sep 17 00:00:00 2001 From: Jerome Forissier Date: Fri, 7 Feb 2020 11:13:46 +0100 Subject: qemu: define ARMV7_SUPPORTS_VFP Commit 8f73663b5963 ("plat/arm: Support for Cortex A5 in FVP Versatile Express platform") has conditioned the enabling of the Advanced SIMD and floating point features to platforms that have: (ARM_ARCH_MAJOR > 7) || defined(ARMV7_SUPPORTS_VFP) QEMU does support VFP so it should set ARMV7_SUPPORTS_VFP. Signed-off-by: Jerome Forissier Change-Id: I3bab7c2ed04766d0628c14094557b2751f60a428 --- plat/qemu/qemu/platform.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/plat/qemu/qemu/platform.mk b/plat/qemu/qemu/platform.mk index b95bf5a51..bc10569ba 100644 --- a/plat/qemu/qemu/platform.mk +++ b/plat/qemu/qemu/platform.mk @@ -15,6 +15,7 @@ ifeq (${ARM_ARCH_MAJOR},7) MARCH32_DIRECTIVE := -mcpu=cortex-a15 $(eval $(call add_define,ARMV7_SUPPORTS_LARGE_PAGE_ADDRESSING)) $(eval $(call add_define,ARMV7_SUPPORTS_GENERIC_TIMER)) +$(eval $(call add_define,ARMV7_SUPPORTS_VFP)) # Qemu expects a BL32 boot stage. NEED_BL32 := yes endif # ARMv7 -- cgit v1.2.3 From ab1981db9ea793accf1279446b9f7666a3be04ca Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Thu, 8 Aug 2019 12:03:26 +0100 Subject: fconf: initial commit Introduce the Firmware CONfiguration Framework (fconf). The fconf is an abstraction layer for platform specific data, allowing a "property" to be queried and a value retrieved without the requesting entity knowing what backing store is being used to hold the data. The default backing store used is C structure. If another backing store has to be used, the platform integrator needs to provide a "populate()" function to fill the corresponding C structure. The "populate()" function must be registered to the fconf framework with the "FCONF_REGISTER_POPULATOR()". This ensures that the function would be called inside the "fconf_populate()" function. A two level macro is used as getter: - the first macro takes 3 parameters and converts it to a function call: FCONF_GET_PROPERTY(a,b,c) -> a__b_getter(c). - the second level defines a__b_getter(c) to the matching C structure, variable, array, function, etc.. Ex: Get a Chain of trust property: 1) FCONF_GET_PROPERY(tbbr, cot, BL2_id) -> tbbr__cot_getter(BL2_id) 2) tbbr__cot_getter(BL2_id) -> cot_desc_ptr[BL2_id] Change-Id: Id394001353ed295bc680c3f543af0cf8da549469 Signed-off-by: Louis Mayencourt --- bl2/bl2.ld.S | 12 ++++++++- drivers/auth/auth_mod.c | 8 +++--- include/lib/fconf/fconf.h | 47 +++++++++++++++++++++++++++++++++++ include/lib/fconf/fconf_tbbr_getter.h | 15 +++++++++++ lib/fconf/fconf.c | 40 +++++++++++++++++++++++++++++ lib/fconf/fconf.mk | 11 ++++++++ plat/arm/common/arm_common.mk | 5 +++- 7 files changed, 132 insertions(+), 6 deletions(-) create mode 100644 include/lib/fconf/fconf.h create mode 100644 include/lib/fconf/fconf_tbbr_getter.h create mode 100644 lib/fconf/fconf.c create mode 100644 lib/fconf/fconf.mk diff --git a/bl2/bl2.ld.S b/bl2/bl2.ld.S index 6230562ed..c1338e22d 100644 --- a/bl2/bl2.ld.S +++ b/bl2/bl2.ld.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -46,6 +46,11 @@ SECTIONS __RODATA_START__ = .; *(SORT_BY_ALIGNMENT(.rodata*)) + . = ALIGN(8); + __FCONF_POPULATOR_START__ = .; + KEEP(*(.fconf_populator)) + __FCONF_POPULATOR_END__ = .; + /* Ensure 8-byte alignment for descriptors and ensure inclusion */ . = ALIGN(8); __PARSER_LIB_DESCS_START__ = .; @@ -62,6 +67,11 @@ SECTIONS *(SORT_BY_ALIGNMENT(.text*)) *(SORT_BY_ALIGNMENT(.rodata*)) + . = ALIGN(8); + __FCONF_POPULATOR_START__ = .; + KEEP(*(.fconf_populator)) + __FCONF_POPULATOR_END__ = .; + /* Ensure 8-byte alignment for descriptors and ensure inclusion */ . = ALIGN(8); __PARSER_LIB_DESCS_START__ = .; diff --git a/drivers/auth/auth_mod.c b/drivers/auth/auth_mod.c index 3fb2d1a48..91ee1bea9 100644 --- a/drivers/auth/auth_mod.c +++ b/drivers/auth/auth_mod.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -16,6 +16,7 @@ #include #include #include +#include #include /* ASN.1 tags */ @@ -302,9 +303,8 @@ int auth_mod_get_parent_id(unsigned int img_id, unsigned int *parent_id) const auth_img_desc_t *img_desc = NULL; assert(parent_id != NULL); - /* Get the image descriptor */ - img_desc = cot_desc_ptr[img_id]; + img_desc = FCONF_GET_PROPERTY(tbbr, cot, img_id); /* Check if the image has no parent (ROT) */ if (img_desc->parent == NULL) { @@ -353,7 +353,7 @@ int auth_mod_verify_img(unsigned int img_id, int rc, i; /* Get the image descriptor from the chain of trust */ - img_desc = cot_desc_ptr[img_id]; + img_desc = FCONF_GET_PROPERTY(tbbr, cot, img_id); /* Ask the parser to check the image integrity */ rc = img_parser_check_integrity(img_desc->img_type, img_ptr, img_len); diff --git a/include/lib/fconf/fconf.h b/include/lib/fconf/fconf.h new file mode 100644 index 000000000..c5f10d267 --- /dev/null +++ b/include/lib/fconf/fconf.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2019-2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FCONF_H +#define FCONF_H + +#include + +/* Public API */ +#define FCONF_GET_PROPERTY(a, b, c) a##__##b##_getter(c) + +#define FCONF_REGISTER_POPULATOR(name, callback) \ + __attribute__((used, section(".fconf_populator"))) \ + const struct fconf_populator name##__populator = { \ + .info = #name, \ + .populate = callback \ + }; + +/* + * Populator callback + * + * This structure are used by the fconf_populate function and should only be + * defined by the FCONF_REGISTER_POPULATOR macro. + */ +struct fconf_populator { + /* Description of the data loaded by the callback */ + const char *info; + + /* Callback used by fconf_populate function with a provided config dtb. + * Return 0 on success, err_code < 0 otherwise. + */ + int (*populate)(uintptr_t config); +}; + +/* Top level populate function + * + * This function takes a configuration dtb and calls all the registered + * populator callback with it. + * + * Panic on error. + */ +void fconf_populate(uintptr_t config); + +#endif /* FCONF_H */ diff --git a/include/lib/fconf/fconf_tbbr_getter.h b/include/lib/fconf/fconf_tbbr_getter.h new file mode 100644 index 000000000..fb81e7bea --- /dev/null +++ b/include/lib/fconf/fconf_tbbr_getter.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2019-2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FCONF_TBBR_GETTER_H +#define FCONF_TBBR_GETTER_H + +#include + +/* TBBR related getter */ +#define tbbr__cot_getter(id) cot_desc_ptr[id] + +#endif /* FCONF_TBBR_GETTER_H */ diff --git a/lib/fconf/fconf.c b/lib/fconf/fconf.c new file mode 100644 index 000000000..387e758d2 --- /dev/null +++ b/lib/fconf/fconf.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2019-2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include + +void fconf_populate(uintptr_t config) +{ + assert(config != 0UL); + + /* Check if the pointer to DTB is correct */ + if (fdt_check_header((void *)config) != 0) { + ERROR("FCONF: Invalid DTB file passed for FW_CONFIG\n"); + panic(); + } + + INFO("FCONF: Reading firmware configuration file from: 0x%lx\n", config); + + /* Go through all registered populate functions */ + IMPORT_SYM(struct fconf_populator *, __FCONF_POPULATOR_START__, start); + IMPORT_SYM(struct fconf_populator *, __FCONF_POPULATOR_END__, end); + const struct fconf_populator *populator; + + for (populator = start; populator != end; populator++) { + assert((populator->info != NULL) && (populator->populate != NULL)); + + INFO("FCONF: Reading firmware configuration information for: %s\n", populator->info); + if (populator->populate(config) != 0) { + /* TODO: handle property miss */ + panic(); + } + } +} diff --git a/lib/fconf/fconf.mk b/lib/fconf/fconf.mk new file mode 100644 index 000000000..0813c73cc --- /dev/null +++ b/lib/fconf/fconf.mk @@ -0,0 +1,11 @@ +# +# Copyright (c) 2019-2020, ARM Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# Add Firmware Configuration files +FCONF_SOURCES := lib/fconf/fconf.c + +BL1_SOURCES += ${FCONF_SOURCES} +BL2_SOURCES += ${FCONF_SOURCES} diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index 9f4bc2107..abf2f914e 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -198,6 +198,9 @@ BL2_SOURCES += drivers/delay_timer/delay_timer.c \ plat/arm/common/arm_err.c \ plat/arm/common/arm_io_storage.c +# Firmware Configuration Framework sources +include lib/fconf/fconf.mk + # Add `libfdt` and Arm common helpers required for Dynamic Config include lib/libfdt/libfdt.mk @@ -270,7 +273,7 @@ ifneq (${TRUSTED_BOARD_BOOT},0) # Include common TBB sources AUTH_SOURCES := drivers/auth/auth_mod.c \ drivers/auth/crypto_mod.c \ - drivers/auth/img_parser_mod.c \ + drivers/auth/img_parser_mod.c # Include the selected chain of trust sources. ifeq (${COT},tbbr) -- cgit v1.2.3 From 3b5ea741fd92088c9e005d3508b73e50f1d5daf7 Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Thu, 17 Oct 2019 14:46:51 +0100 Subject: fconf: Load config dtb from bl1 Move the loading of the dtb from arm_dym_cfg to fconf. The new loading function is not associated to arm platform anymore, and can be moved to bl_main if wanted. Change-Id: I847d07eaba36d31d9d3ed9eba8e58666ea1ba563 Signed-off-by: Louis Mayencourt --- include/lib/fconf/fconf.h | 3 ++ include/plat/arm/common/plat_arm.h | 1 - lib/fconf/fconf.c | 39 +++++++++++++++++++++++++ plat/arm/board/a5ds/platform.mk | 5 +++- plat/arm/board/fvp_ve/platform.mk | 5 +++- plat/arm/common/arm_bl1_setup.c | 8 ++++-- plat/arm/common/arm_dyn_cfg.c | 59 +------------------------------------- 7 files changed, 57 insertions(+), 63 deletions(-) diff --git a/include/lib/fconf/fconf.h b/include/lib/fconf/fconf.h index c5f10d267..5a5837f45 100644 --- a/include/lib/fconf/fconf.h +++ b/include/lib/fconf/fconf.h @@ -35,6 +35,9 @@ struct fconf_populator { int (*populate)(uintptr_t config); }; +/* Load firmware configuration dtb */ +void fconf_load_config(void); + /* Top level populate function * * This function takes a configuration dtb and calls all the registered diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index 32dc9f93d..ec0f37988 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -225,7 +225,6 @@ void arm_sp_min_plat_runtime_setup(void); int arm_io_is_toc_valid(void); /* Utility functions for Dynamic Config */ -void arm_load_tb_fw_config(void); void arm_bl2_set_tb_cfg_addr(void *dtb); void arm_bl2_dyn_cfg_init(void); void arm_bl1_set_mbedtls_heap(void); diff --git a/lib/fconf/fconf.c b/lib/fconf/fconf.c index 387e758d2..7e0b00b08 100644 --- a/lib/fconf/fconf.c +++ b/lib/fconf/fconf.c @@ -9,8 +9,47 @@ #include #include #include +#include #include +static uintptr_t tb_fw_cfg_dtb; +static size_t tb_fw_cfg_dtb_size; + +void fconf_load_config(void) +{ + int err; + image_desc_t *desc; + + image_info_t arm_tb_fw_info = { + .h.type = (uint8_t)PARAM_IMAGE_BINARY, + .h.version = (uint8_t)VERSION_2, + .h.size = (uint16_t)sizeof(image_info_t), + .h.attr = 0, + .image_base = ARM_TB_FW_CONFIG_BASE, + .image_max_size = (uint32_t) + (ARM_TB_FW_CONFIG_LIMIT - ARM_TB_FW_CONFIG_BASE) + }; + + VERBOSE("FCONF: Loading FW_CONFIG\n"); + err = load_auth_image(TB_FW_CONFIG_ID, &arm_tb_fw_info); + if (err != 0) { + /* Return if FW_CONFIG is not loaded */ + VERBOSE("Failed to load FW_CONFIG\n"); + return; + } + + /* At this point we know that a DTB is indeed available */ + tb_fw_cfg_dtb = arm_tb_fw_info.image_base; + tb_fw_cfg_dtb_size = (size_t)arm_tb_fw_info.image_size; + + /* The BL2 ep_info arg0 is modified to point to FW_CONFIG */ + desc = bl1_plat_get_image_desc(BL2_IMAGE_ID); + assert(desc != NULL); + desc->ep_info.args.arg0 = tb_fw_cfg_dtb; + + INFO("FCONF: FW_CONFIG loaded at address = 0x%lx\n", tb_fw_cfg_dtb); +} + void fconf_populate(uintptr_t config) { assert(config != 0UL); diff --git a/plat/arm/board/a5ds/platform.mk b/plat/arm/board/a5ds/platform.mk index d42b2bfa8..ac3973ae0 100644 --- a/plat/arm/board/a5ds/platform.mk +++ b/plat/arm/board/a5ds/platform.mk @@ -1,9 +1,12 @@ # -# Copyright (c) 2019, Arm Limited. All rights reserved. +# Copyright (c) 2019-2020, Arm Limited. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # +# Firmware Configuration Framework sources +include lib/fconf/fconf.mk + # 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 4d21f4ba0..51c03151d 100644 --- a/plat/arm/board/fvp_ve/platform.mk +++ b/plat/arm/board/fvp_ve/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2019, Arm Limited. All rights reserved. +# Copyright (c) 2019-2020, Arm Limited. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -116,6 +116,9 @@ else PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS} endif +# Firmware Configuration Framework sources +include lib/fconf/fconf.mk + # Add `libfdt` and Arm common helpers required for Dynamic Config include lib/libfdt/libfdt.mk diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c index b19a7c39c..bf4d7bd5c 100644 --- a/plat/arm/common/arm_bl1_setup.c +++ b/plat/arm/common/arm_bl1_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -143,7 +144,10 @@ void arm_bl1_platform_setup(void) { /* Initialise the IO layer and register platform IO devices */ plat_arm_io_setup(); - arm_load_tb_fw_config(); + + /* Load fw config */ + fconf_load_config(); + #if TRUSTED_BOARD_BOOT /* Share the Mbed TLS heap info with other images */ arm_bl1_set_mbedtls_heap(); diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c index e6c5a7361..fa251c8ce 100644 --- a/plat/arm/common/arm_dyn_cfg.c +++ b/plat/arm/common/arm_dyn_cfg.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -115,63 +115,6 @@ void arm_bl1_set_mbedtls_heap(void) #endif /* TRUSTED_BOARD_BOOT */ -/* - * Helper function to load TB_FW_CONFIG and populate the load information to - * arg0 of BL2 entrypoint info. - */ -void arm_load_tb_fw_config(void) -{ - int err; - uintptr_t config_base = 0UL; - image_desc_t *desc; - - image_desc_t arm_tb_fw_info = { - .image_id = TB_FW_CONFIG_ID, - SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY, - VERSION_2, image_info_t, 0), - .image_info.image_base = ARM_TB_FW_CONFIG_BASE, - .image_info.image_max_size = - ARM_TB_FW_CONFIG_LIMIT - ARM_TB_FW_CONFIG_BASE - }; - - VERBOSE("BL1: Loading TB_FW_CONFIG\n"); - err = load_auth_image(TB_FW_CONFIG_ID, &arm_tb_fw_info.image_info); - if (err != 0) { - /* Return if TB_FW_CONFIG is not loaded */ - VERBOSE("Failed to load TB_FW_CONFIG\n"); - return; - } - - /* At this point we know that a DTB is indeed available */ - config_base = arm_tb_fw_info.image_info.image_base; - tb_fw_cfg_dtb = (void *)config_base; - - /* The BL2 ep_info arg0 is modified to point to TB_FW_CONFIG */ - desc = bl1_plat_get_image_desc(BL2_IMAGE_ID); - assert(desc != NULL); - desc->ep_info.args.arg0 = config_base; - - INFO("BL1: TB_FW_CONFIG loaded at address = 0x%lx\n", config_base); - -#if TRUSTED_BOARD_BOOT && defined(DYN_DISABLE_AUTH) - int tb_fw_node; - uint32_t disable_auth = 0; - - err = arm_dyn_tb_fw_cfg_init((void *)config_base, &tb_fw_node); - if (err < 0) { - ERROR("Invalid TB_FW_CONFIG loaded\n"); - panic(); - } - - err = arm_dyn_get_disable_auth((void *)config_base, tb_fw_node, &disable_auth); - if (err < 0) - return; - - if (disable_auth == 1) - dyn_disable_auth(); -#endif -} - /* * BL2 utility function to set the address of TB_FW_CONFIG passed from BL1. */ -- cgit v1.2.3 From 9814bfc1bfc4868a8505d3756aceea5ad41a8c64 Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Thu, 17 Oct 2019 15:14:25 +0100 Subject: fconf: Populate properties from dtb during bl2 setup Use the dtb provided by bl1 as configuration file for fconf. Change-Id: I3f466ad9b7047e1a361d94e71ac6d693e31496d9 Signed-off-by: Louis Mayencourt --- include/lib/fconf/fconf.h | 11 +++++++++++ lib/fconf/fconf.c | 22 ++++++++++++++-------- plat/arm/common/arm_bl2_setup.c | 11 +++++++---- 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/include/lib/fconf/fconf.h b/include/lib/fconf/fconf.h index 5a5837f45..f58ff5710 100644 --- a/include/lib/fconf/fconf.h +++ b/include/lib/fconf/fconf.h @@ -47,4 +47,15 @@ void fconf_load_config(void); */ void fconf_populate(uintptr_t config); +/* FCONF specific getter */ +#define fconf__dtb_getter(prop) fconf_dtb_info.prop + +/* Structure used to locally keep a reference to the config dtb. */ +struct fconf_dtb_info_t { + uintptr_t base_addr; + size_t size; +}; + +extern struct fconf_dtb_info_t fconf_dtb_info; + #endif /* FCONF_H */ diff --git a/lib/fconf/fconf.c b/lib/fconf/fconf.c index 7e0b00b08..2ca1bdc77 100644 --- a/lib/fconf/fconf.c +++ b/lib/fconf/fconf.c @@ -7,18 +7,17 @@ #include #include +#include #include #include #include #include -static uintptr_t tb_fw_cfg_dtb; -static size_t tb_fw_cfg_dtb_size; +struct fconf_dtb_info_t fconf_dtb_info; void fconf_load_config(void) { int err; - image_desc_t *desc; image_info_t arm_tb_fw_info = { .h.type = (uint8_t)PARAM_IMAGE_BINARY, @@ -27,7 +26,7 @@ void fconf_load_config(void) .h.attr = 0, .image_base = ARM_TB_FW_CONFIG_BASE, .image_max_size = (uint32_t) - (ARM_TB_FW_CONFIG_LIMIT - ARM_TB_FW_CONFIG_BASE) + (ARM_TB_FW_CONFIG_LIMIT - ARM_TB_FW_CONFIG_BASE) }; VERBOSE("FCONF: Loading FW_CONFIG\n"); @@ -39,15 +38,19 @@ void fconf_load_config(void) } /* At this point we know that a DTB is indeed available */ - tb_fw_cfg_dtb = arm_tb_fw_info.image_base; - tb_fw_cfg_dtb_size = (size_t)arm_tb_fw_info.image_size; + fconf_dtb_info.base_addr = arm_tb_fw_info.image_base; + fconf_dtb_info.size = (size_t)arm_tb_fw_info.image_size; + +#if !BL2_AT_EL3 + image_desc_t *desc; /* The BL2 ep_info arg0 is modified to point to FW_CONFIG */ desc = bl1_plat_get_image_desc(BL2_IMAGE_ID); assert(desc != NULL); - desc->ep_info.args.arg0 = tb_fw_cfg_dtb; + desc->ep_info.args.arg0 = arm_tb_fw_info.image_base; +#endif - INFO("FCONF: FW_CONFIG loaded at address = 0x%lx\n", tb_fw_cfg_dtb); + INFO("FCONF: FW_CONFIG loaded at address = 0x%lx\n", arm_tb_fw_info.image_base); } void fconf_populate(uintptr_t config) @@ -76,4 +79,7 @@ void fconf_populate(uintptr_t config) panic(); } } + + /* save local pointer to the config dtb */ + fconf_dtb_info.base_addr = config; } diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c index cdf87ca55..5f83bccde 100644 --- a/plat/arm/common/arm_bl2_setup.c +++ b/plat/arm/common/arm_bl2_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -14,6 +14,7 @@ #include #include #include +#include #ifdef SPD_opteed #include #endif @@ -58,11 +59,13 @@ void arm_bl2_early_platform_setup(uintptr_t tb_fw_config, /* Setup the BL2 memory layout */ bl2_tzram_layout = *mem_layout; + /* Fill the properties struct with the info from the config dtb */ + if (tb_fw_config != 0U) { + fconf_populate(tb_fw_config); + } + /* Initialise the IO layer and register platform IO devices */ plat_arm_io_setup(); - - if (tb_fw_config != 0U) - arm_bl2_set_tb_cfg_addr((void *)tb_fw_config); } void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) -- cgit v1.2.3 From 25ac87940cd3db8036f967d01653c0db64e4c136 Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Tue, 17 Dec 2019 13:17:25 +0000 Subject: fconf: Add dynamic config DTBs info as property This patch introduces a better separation between the trusted-boot related properties, and the dynamic configuration DTBs loading information. The dynamic configuration DTBs properties are moved to a new node: `dtb-registry`. All the sub-nodes present will be provided to the dynamic config framework to be loaded. The node currently only contains the already defined configuration DTBs, but can be extended for future features if necessary. The dynamic config framework is modified to use the abstraction provided by the fconf framework, instead of directly accessing the DTBs. The trusted-boot properties are kept under the "arm,tb_fw" compatible string, but in a separate `tb_fw-config` node. The `tb_fw-config` property of the `dtb-registry` node simply points to the load address of `fw_config`, as the `tb_fw-config` is currently part of the same DTB. Change-Id: Iceb6c4c2cb92b692b6e28dbdc9fb060f1c46de82 Signed-off-by: Louis Mayencourt --- include/lib/fconf/fconf_dyn_cfg_getter.h | 24 ++++++ include/plat/arm/common/arm_dyn_cfg_helpers.h | 4 +- include/plat/arm/common/plat_arm.h | 1 - lib/fconf/fconf.c | 2 +- lib/fconf/fconf.mk | 3 +- lib/fconf/fconf_dyn_cfg_getter.c | 95 ++++++++++++++++++++++ plat/arm/board/a5ds/fdts/a5ds_fw_config.dts | 35 ++++++++ plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts | 18 ---- plat/arm/board/a5ds/platform.mk | 4 +- plat/arm/board/fvp/fdts/fvp_fw_config.dts | 71 ++++++++++++++++ plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts | 41 ---------- plat/arm/board/fvp/jmptbl.i | 2 + plat/arm/board/fvp/platform.mk | 4 +- plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts | 35 ++++++++ plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts | 18 ---- plat/arm/board/fvp_ve/platform.mk | 4 +- plat/arm/board/juno/fdts/juno_fw_config.dts | 40 +++++++++ plat/arm/board/juno/fdts/juno_tb_fw_config.dts | 25 ------ plat/arm/board/juno/jmptbl.i | 2 + plat/arm/board/juno/platform.mk | 4 +- plat/arm/common/arm_dyn_cfg.c | 72 ++++++++-------- plat/arm/common/arm_dyn_cfg_helpers.c | 77 ------------------ 22 files changed, 354 insertions(+), 227 deletions(-) create mode 100644 include/lib/fconf/fconf_dyn_cfg_getter.h create mode 100644 lib/fconf/fconf_dyn_cfg_getter.c create mode 100644 plat/arm/board/a5ds/fdts/a5ds_fw_config.dts delete mode 100644 plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts create mode 100644 plat/arm/board/fvp/fdts/fvp_fw_config.dts delete mode 100644 plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts create mode 100644 plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts delete mode 100644 plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts create mode 100644 plat/arm/board/juno/fdts/juno_fw_config.dts delete mode 100644 plat/arm/board/juno/fdts/juno_tb_fw_config.dts diff --git a/include/lib/fconf/fconf_dyn_cfg_getter.h b/include/lib/fconf/fconf_dyn_cfg_getter.h new file mode 100644 index 000000000..0fda8c9b2 --- /dev/null +++ b/include/lib/fconf/fconf_dyn_cfg_getter.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2019-2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FCONF_DYN_CFG_GETTER_H +#define FCONF_DYN_CFG_GETTER_H + +#include + +/* Dynamic configuration related getter */ +#define dyn_cfg__dtb_getter(id) dyn_cfg_dtb_info_getter(id) + +struct dyn_cfg_dtb_info_t { + uintptr_t config_addr; + size_t config_max_size; + unsigned int config_id; +}; + +struct dyn_cfg_dtb_info_t *dyn_cfg_dtb_info_getter(unsigned int config_id); +int fconf_populate_dtb_registry(uintptr_t config); + +#endif /* FCONF_DYN_CFG_GETTER_H */ diff --git a/include/plat/arm/common/arm_dyn_cfg_helpers.h b/include/plat/arm/common/arm_dyn_cfg_helpers.h index 3ad6d5468..9fb31317c 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, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -10,8 +10,6 @@ #include /* Function declarations */ -int arm_dyn_get_config_load_info(void *dtb, int node, unsigned int config_id, - uint64_t *config_addr, uint32_t *config_size); int arm_dyn_tb_fw_cfg_init(void *dtb, int *node); int arm_dyn_get_disable_auth(void *dtb, int node, uint32_t *disable_auth); int arm_get_dtb_mbedtls_heap_info(void *dtb, void **heap_addr, diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index ec0f37988..129ceca66 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -225,7 +225,6 @@ void arm_sp_min_plat_runtime_setup(void); int arm_io_is_toc_valid(void); /* Utility functions for Dynamic Config */ -void arm_bl2_set_tb_cfg_addr(void *dtb); void arm_bl2_dyn_cfg_init(void); void arm_bl1_set_mbedtls_heap(void); int arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size); diff --git a/lib/fconf/fconf.c b/lib/fconf/fconf.c index 2ca1bdc77..a6da56b00 100644 --- a/lib/fconf/fconf.c +++ b/lib/fconf/fconf.c @@ -18,7 +18,7 @@ struct fconf_dtb_info_t fconf_dtb_info; void fconf_load_config(void) { int err; - + /* fconf FW_CONFIG and TB_FW_CONFIG are currently the same DTB */ image_info_t arm_tb_fw_info = { .h.type = (uint8_t)PARAM_IMAGE_BINARY, .h.version = (uint8_t)VERSION_2, diff --git a/lib/fconf/fconf.mk b/lib/fconf/fconf.mk index 0813c73cc..703196949 100644 --- a/lib/fconf/fconf.mk +++ b/lib/fconf/fconf.mk @@ -5,7 +5,8 @@ # # Add Firmware Configuration files -FCONF_SOURCES := lib/fconf/fconf.c +FCONF_SOURCES := lib/fconf/fconf.c \ + lib/fconf/fconf_dyn_cfg_getter.c BL1_SOURCES += ${FCONF_SOURCES} BL2_SOURCES += ${FCONF_SOURCES} diff --git a/lib/fconf/fconf_dyn_cfg_getter.c b/lib/fconf/fconf_dyn_cfg_getter.c new file mode 100644 index 000000000..d313a5618 --- /dev/null +++ b/lib/fconf/fconf_dyn_cfg_getter.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2019-2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include +#include + +/* We currently use TB_FW, SOC_FW, TOS_FW, NS_fw and HW configs */ +#define MAX_DTB_INFO U(5) + +static struct dyn_cfg_dtb_info_t dtb_infos[MAX_DTB_INFO]; +static OBJECT_POOL_ARRAY(dtb_info_pool, dtb_infos); + +struct dyn_cfg_dtb_info_t *dyn_cfg_dtb_info_getter(unsigned int config_id) +{ + unsigned int index; + struct dyn_cfg_dtb_info_t *info; + + /* Positions index to the proper config-id */ + for (index = 0; index < MAX_DTB_INFO; index++) { + if (dtb_infos[index].config_id == config_id) { + info = &dtb_infos[index]; + break; + } + } + + if (index == MAX_DTB_INFO) { + WARN("FCONF: Invalid config id %u\n", config_id); + info = NULL; + } + + return info; +} + +int fconf_populate_dtb_registry(uintptr_t config) +{ + int rc; + int node, child; + struct dyn_cfg_dtb_info_t *dtb_info; + + /* As libfdt use void *, we can't avoid this cast */ + const void *dtb = (void *)config; + + /* Find the node offset point to "arm,dyn_cfg-dtb_registry" compatible property */ + const char *compatible_str = "arm,dyn_cfg-dtb_registry"; + 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; + } + + fdt_for_each_subnode(child, dtb, node) { + dtb_info = pool_alloc(&dtb_info_pool); + + /* Read configuration dtb information */ + rc = fdtw_read_cells(dtb, child, "load-address", 2, &dtb_info->config_addr); + if (rc < 0) { + ERROR("FCONF: Incomplete configuration property in dtb-registry.\n"); + return rc; + } + + rc = fdtw_read_cells(dtb, child, "max-size", 1, &dtb_info->config_max_size); + if (rc < 0) { + ERROR("FCONF: Incomplete configuration property in dtb-registry.\n"); + return rc; + } + + rc = fdtw_read_cells(dtb, child, "id", 1, &dtb_info->config_id); + if (rc < 0) { + ERROR("FCONF: Incomplete configuration property in dtb-registry.\n"); + return rc; + } + + VERBOSE("FCONF: dyn_cfg.dtb_registry cell found with:\n"); + VERBOSE("\tload-address = %lx\n", dtb_info->config_addr); + VERBOSE("\tmax-size = 0x%zx\n", dtb_info->config_max_size); + VERBOSE("\tconfig-id = %u\n", dtb_info->config_id); + } + + if ((child < 0) && (child != -FDT_ERR_NOTFOUND)) { + ERROR("%d: fdt_for_each_subnode(): %d\n", __LINE__, node); + return child; + } + + return 0; +} + +FCONF_REGISTER_POPULATOR(dyn_cfg, fconf_populate_dtb_registry); diff --git a/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts b/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts new file mode 100644 index 000000000..2f2d265c5 --- /dev/null +++ b/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2019-2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +/dts-v1/; + +/ { + dtb-registry { + compatible = "arm,dyn_cfg-dtb_registry"; + + /* tb_fw_config is temporarily contained in this dtb */ + tb_fw-config { + load-address = <0x0 0x2001010>; + max-size = <0x200>; + id = ; + }; + + hw-config { + load-address = <0x0 0x83000000>; + max-size = <0x01000000>; + id = ; + }; + }; + + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + }; +}; diff --git a/plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts b/plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts deleted file mode 100644 index 7b3aa1144..000000000 --- a/plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) 2019-2020, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/dts-v1/; - -/ { - /* Platform Config */ - plat_arm_bl2 { - compatible = "arm,tb_fw"; - hw_config_addr = <0x0 0x83000000>; - hw_config_max_size = <0x01000000>; - /* Disable authentication for development */ - disable_auth = <0x0>; - }; -}; diff --git a/plat/arm/board/a5ds/platform.mk b/plat/arm/board/a5ds/platform.mk index ac3973ae0..719884217 100644 --- a/plat/arm/board/a5ds/platform.mk +++ b/plat/arm/board/a5ds/platform.mk @@ -70,7 +70,7 @@ BL2_SOURCES += lib/aarch32/arm32_aeabi_divmod.c \ # Add the FDT_SOURCES and options for Dynamic Config (only for Unix env) ifdef UNIX_MK -FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/a5ds_tb_fw_config.dtb +FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/a5ds_fw_config.dtb # Add the TB_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config)) @@ -80,7 +80,7 @@ $(eval FVP_HW_CONFIG := ${BUILD_PLAT}/$(patsubst %.dts,%.dtb, \ # Add the HW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${FVP_HW_CONFIG},--hw-config)) -FDT_SOURCES += plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts \ +FDT_SOURCES += plat/arm/board/a5ds/fdts/a5ds_fw_config.dts \ ${FVP_HW_CONFIG_DTS} endif diff --git a/plat/arm/board/fvp/fdts/fvp_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_fw_config.dts new file mode 100644 index 000000000..ff83db361 --- /dev/null +++ b/plat/arm/board/fvp/fdts/fvp_fw_config.dts @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2019-2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +/dts-v1/; + +/ { + dtb-registry { + compatible = "arm,dyn_cfg-dtb_registry"; + + /* tb_fw_config is temporarily contained on this dtb */ + tb_fw-config { + load-address = <0x0 0x4001010>; + max-size = <0x200>; + id = ; + }; + + hw-config { + load-address = <0x0 0x82000000>; + max-size = <0x01000000>; + id = ; + }; + + /* + * Load SoC and TOS firmware configs at the base of + * non shared SRAM. The runtime checks ensure we don't + * overlap BL2, BL31 or BL32. The NT firmware config + * is loaded at base of DRAM. + */ + soc_fw-config { + load-address = <0x0 0x04001000>; + max-size = <0x200>; + id = ; + }; + + tos_fw-config { + load-address = <0x0 0x04001200>; + max-size = <0x200>; + id = ; + }; + + nt_fw-config { + load-address = <0x0 0x80000000>; + max-size = <0x200>; + id = ; + }; + }; + + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + + /* + * The following two entries are placeholders for Mbed TLS + * heap information. The default values don't matter since + * they will be overwritten by BL1. + * In case of having shared Mbed TLS heap between BL1 and BL2, + * BL1 will populate these two properties with the respective + * info about the shared heap. This info will be available for + * BL2 in order to locate and re-use the heap. + */ + mbedtls_heap_addr = <0x0 0x0>; + mbedtls_heap_size = <0x0>; + }; +}; diff --git a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts deleted file mode 100644 index ce589385c..000000000 --- a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/dts-v1/; - -/ { - /* Platform Config */ - plat_arm_bl2 { - compatible = "arm,tb_fw"; - hw_config_addr = <0x0 0x82000000>; - hw_config_max_size = <0x01000000>; - /* Disable authentication for development */ - disable_auth = <0x0>; - /* - * Load SoC and TOS firmware configs at the base of - * non shared SRAM. The runtime checks ensure we don't - * overlap BL2, BL31 or BL32. The NT firmware config - * is loaded at base of DRAM. - */ - soc_fw_config_addr = <0x0 0x04001000>; - soc_fw_config_max_size = <0x200>; - tos_fw_config_addr = <0x0 0x04001200>; - tos_fw_config_max_size = <0x200>; - nt_fw_config_addr = <0x0 0x80000000>; - nt_fw_config_max_size = <0x200>; - /* - * The following two entries are placeholders for Mbed TLS - * heap information. The default values don't matter since - * they will be overwritten by BL1. - * In case of having shared Mbed TLS heap between BL1 and BL2, - * BL1 will populate these two properties with the respective - * info about the shared heap. This info will be available for - * BL2 in order to locate and re-use the heap. - */ - mbedtls_heap_addr = <0x0 0x0>; - mbedtls_heap_size = <0x0>; - }; -}; diff --git a/plat/arm/board/fvp/jmptbl.i b/plat/arm/board/fvp/jmptbl.i index 6ccdd283f..b1b9ed463 100644 --- a/plat/arm/board/fvp/jmptbl.i +++ b/plat/arm/board/fvp/jmptbl.i @@ -20,6 +20,8 @@ fdt fdt_setprop_inplace fdt fdt_check_header fdt fdt_node_offset_by_compatible fdt fdt_setprop_inplace_namelen_partial +fdt fdt_first_subnode +fdt fdt_next_subnode mbedtls mbedtls_asn1_get_alg mbedtls mbedtls_asn1_get_alg_null mbedtls mbedtls_asn1_get_bitstring_null diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 6fb34c48a..f46f8e211 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -205,12 +205,12 @@ endif ifdef UNIX_MK FVP_HW_CONFIG_DTS := fdts/${FVP_DT_PREFIX}.dts FDT_SOURCES += $(addprefix plat/arm/board/fvp/fdts/, \ - ${PLAT}_tb_fw_config.dts \ + ${PLAT}_fw_config.dts \ ${PLAT}_soc_fw_config.dts \ ${PLAT}_nt_fw_config.dts \ ) -FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb +FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb FVP_SOC_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_soc_fw_config.dtb FVP_NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb diff --git a/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts b/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts new file mode 100644 index 000000000..147c8f366 --- /dev/null +++ b/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2019-2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +/dts-v1/; + +/ { + dtb-registry { + compatible = "arm,dyn_cfg-dtb_registry"; + + /* tb_fw_config is temporarily contained on this dtb */ + tb_fw-config { + load-address = <0x0 0x80001010>; + max-size = <0x200>; + id = ; + }; + + hw-config { + load-address = <0x0 0x82000000>; + max-size = <0x01000000>; + id = ; + }; + }; + + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + }; +}; diff --git a/plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts b/plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts deleted file mode 100644 index 9ab2d9656..000000000 --- a/plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) 2019, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/dts-v1/; - -/ { - /* Platform Config */ - plat_arm_bl2 { - compatible = "arm,tb_fw"; - hw_config_addr = <0x0 0x82000000>; - hw_config_max_size = <0x01000000>; - /* Disable authentication for development */ - disable_auth = <0x0>; - }; -}; diff --git a/plat/arm/board/fvp_ve/platform.mk b/plat/arm/board/fvp_ve/platform.mk index 51c03151d..7883719b0 100644 --- a/plat/arm/board/fvp_ve/platform.mk +++ b/plat/arm/board/fvp_ve/platform.mk @@ -72,9 +72,9 @@ BL2_SOURCES += plat/arm/board/fvp_ve/fvp_ve_bl2_setup.c \ # Add the FDT_SOURCES and options for Dynamic Config (only for Unix env) ifdef UNIX_MK -FDT_SOURCES += plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts +FDT_SOURCES += plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts -FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/fvp_ve_tb_fw_config.dtb +FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/fvp_ve_fw_config.dtb # Add the TB_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config)) diff --git a/plat/arm/board/juno/fdts/juno_fw_config.dts b/plat/arm/board/juno/fdts/juno_fw_config.dts new file mode 100644 index 000000000..cab6f2bf4 --- /dev/null +++ b/plat/arm/board/juno/fdts/juno_fw_config.dts @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2019-2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +/dts-v1/; + +/ { + dtb-registry { + compatible = "arm,dyn_cfg-dtb_registry"; + + /* tb_fw_config is temporarily contained on this dtb */ + tb_fw-config { + load-address = <0x0 0x4001010>; + max-size = <0x200>; + id = ; + }; + }; + + tb_fw-config { + /* Platform Config */ + compatible = "arm,tb_fw"; + /* Disable authentication for development */ + disable_auth = <0x0>; + /* + * The following two entries are placeholders for Mbed TLS + * heap information. The default values don't matter since + * they will be overwritten by BL1. + * In case of having shared Mbed TLS heap between BL1 and BL2, + * BL1 will populate these two properties with the respective + * info about the shared heap. This info will be available for + * BL2 in order to locate and re-use the heap. + */ + mbedtls_heap_addr = <0x0 0x0>; + mbedtls_heap_size = <0x0>; + }; +}; diff --git a/plat/arm/board/juno/fdts/juno_tb_fw_config.dts b/plat/arm/board/juno/fdts/juno_tb_fw_config.dts deleted file mode 100644 index a8ab6c5f9..000000000 --- a/plat/arm/board/juno/fdts/juno_tb_fw_config.dts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/dts-v1/; - -/ { - /* Platform Config */ - compatible = "arm,tb_fw"; - /* Disable authentication for development */ - disable_auth = <0x0>; - /* - * The following two entries are placeholders for Mbed TLS - * heap information. The default values don't matter since - * they will be overwritten by BL1. - * In case of having shared Mbed TLS heap between BL1 and BL2, - * BL1 will populate these two properties with the respective - * info about the shared heap. This info will be available for - * BL2 in order to locate and re-use the heap. - */ - mbedtls_heap_addr = <0x0 0x0>; - mbedtls_heap_size = <0x0>; -}; diff --git a/plat/arm/board/juno/jmptbl.i b/plat/arm/board/juno/jmptbl.i index 6ccdd283f..b1b9ed463 100644 --- a/plat/arm/board/juno/jmptbl.i +++ b/plat/arm/board/juno/jmptbl.i @@ -20,6 +20,8 @@ fdt fdt_setprop_inplace fdt fdt_check_header fdt fdt_node_offset_by_compatible fdt fdt_setprop_inplace_namelen_partial +fdt fdt_first_subnode +fdt fdt_next_subnode mbedtls mbedtls_asn1_get_alg mbedtls mbedtls_asn1_get_alg_null mbedtls mbedtls_asn1_get_bitstring_null diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk index a85ad5376..27650d266 100644 --- a/plat/arm/board/juno/platform.mk +++ b/plat/arm/board/juno/platform.mk @@ -156,8 +156,8 @@ else endif # Add the FDT_SOURCES and options for Dynamic Config -FDT_SOURCES += plat/arm/board/juno/fdts/${PLAT}_tb_fw_config.dts -TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb +FDT_SOURCES += plat/arm/board/juno/fdts/${PLAT}_fw_config.dts +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb # Add the TB_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c index fa251c8ce..402fd93da 100644 --- a/plat/arm/common/arm_dyn_cfg.c +++ b/plat/arm/common/arm_dyn_cfg.c @@ -16,13 +16,12 @@ #if TRUSTED_BOARD_BOOT #include #endif +#include +#include #include #include #include -/* Variable to store the address to TB_FW_CONFIG passed from BL1 */ -static void *tb_fw_cfg_dtb; - #if TRUSTED_BOARD_BOOT static void *mbedtls_heap_addr; @@ -58,6 +57,10 @@ int arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size) #elif defined(IMAGE_BL2) int err; + void *tb_fw_cfg_dtb; + + /* fconf FW_CONFIG and TB_FW_CONFIG are currently the same DTB*/ + tb_fw_cfg_dtb = (void *)FCONF_GET_PROPERTY(fconf, dtb, base_addr); /* If in BL2, retrieve the already allocated heap's info from DTB */ if (tb_fw_cfg_dtb != NULL) { @@ -83,6 +86,7 @@ int arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size) void arm_bl1_set_mbedtls_heap(void) { int err; + uintptr_t tb_fw_cfg_dtb; /* * If tb_fw_cfg_dtb==NULL then DTB is not present for the current @@ -96,8 +100,15 @@ void arm_bl1_set_mbedtls_heap(void) * information, we would need to call plat_get_mbedtls_heap to retrieve * the default heap's address and size. */ - if ((tb_fw_cfg_dtb != NULL) && (mbedtls_heap_addr != NULL)) { - err = arm_set_dtb_mbedtls_heap_info(tb_fw_cfg_dtb, + + /* fconf FW_CONFIG and TB_FW_CONFIG are currently the same DTB*/ + tb_fw_cfg_dtb = FCONF_GET_PROPERTY(fconf, dtb, base_addr); + + if ((tb_fw_cfg_dtb != 0UL) && (mbedtls_heap_addr != NULL)) { + /* As libfdt use void *, we can't avoid this cast */ + void *dtb = (void *)tb_fw_cfg_dtb; + + err = arm_set_dtb_mbedtls_heap_info(dtb, mbedtls_heap_addr, mbedtls_heap_size); if (err < 0) { ERROR("BL1: unable to write shared Mbed TLS heap information to DTB\n"); @@ -108,22 +119,12 @@ void arm_bl1_set_mbedtls_heap(void) * images. It's critical because BL2 won't be able to proceed * without the heap info. */ - flush_dcache_range((uintptr_t)tb_fw_cfg_dtb, - fdt_totalsize(tb_fw_cfg_dtb)); + flush_dcache_range(tb_fw_cfg_dtb, fdt_totalsize(dtb)); } } #endif /* TRUSTED_BOARD_BOOT */ -/* - * BL2 utility function to set the address of TB_FW_CONFIG passed from BL1. - */ -void arm_bl2_set_tb_cfg_addr(void *dtb) -{ - assert(dtb != NULL); - tb_fw_cfg_dtb = dtb; -} - /* * BL2 utility function to initialize dynamic configuration specified by * TB_FW_CONFIG. Populate the bl_mem_params_node_t of other FW_CONFIGs if @@ -131,11 +132,10 @@ void arm_bl2_set_tb_cfg_addr(void *dtb) */ void arm_bl2_dyn_cfg_init(void) { - int err = 0, tb_fw_node; unsigned int i; bl_mem_params_node_t *cfg_mem_params = NULL; - uint64_t image_base; - uint32_t image_size; + uintptr_t image_base; + size_t image_size; const unsigned int config_ids[] = { HW_CONFIG_ID, SOC_FW_CONFIG_ID, @@ -146,16 +146,7 @@ void arm_bl2_dyn_cfg_init(void) #endif }; - if (tb_fw_cfg_dtb == NULL) { - VERBOSE("No TB_FW_CONFIG specified\n"); - return; - } - - err = arm_dyn_tb_fw_cfg_init(tb_fw_cfg_dtb, &tb_fw_node); - if (err < 0) { - ERROR("Invalid TB_FW_CONFIG passed from BL1\n"); - panic(); - } + const struct dyn_cfg_dtb_info_t *dtb_info; /* Iterate through all the fw config IDs */ for (i = 0; i < ARRAY_SIZE(config_ids); i++) { @@ -166,14 +157,16 @@ void arm_bl2_dyn_cfg_init(void) continue; } - err = arm_dyn_get_config_load_info(tb_fw_cfg_dtb, tb_fw_node, - config_ids[i], &image_base, &image_size); - if (err < 0) { + dtb_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, config_ids[i]); + if (dtb_info == NULL) { VERBOSE("Couldn't find config_id %d load info in TB_FW_CONFIG\n", config_ids[i]); continue; } + image_base = dtb_info->config_addr; + image_size = dtb_info->config_max_size; + /* * Do some runtime checks on the load addresses of soc_fw_config, * tos_fw_config, nt_fw_config. This is not a comprehensive check @@ -205,8 +198,8 @@ void arm_bl2_dyn_cfg_init(void) } - cfg_mem_params->image_info.image_base = (uintptr_t)image_base; - cfg_mem_params->image_info.image_max_size = image_size; + cfg_mem_params->image_info.image_base = image_base; + cfg_mem_params->image_info.image_max_size = (uint32_t)image_size; /* * Remove the IMAGE_ATTRIB_SKIP_LOADING attribute from @@ -217,6 +210,17 @@ void arm_bl2_dyn_cfg_init(void) #if TRUSTED_BOARD_BOOT && defined(DYN_DISABLE_AUTH) uint32_t disable_auth = 0; + void *tb_fw_cfg_dtb; + int err, tb_fw_node; + + dtb_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID); + tb_fw_cfg_dtb = (void *)dtb_info->config_addr; + + err = arm_dyn_tb_fw_cfg_init(tb_fw_cfg_dtb, &tb_fw_node); + if (err < 0) { + ERROR("Invalid TB_FW_CONFIG passed from BL1\n"); + panic(); + } err = arm_dyn_get_disable_auth(tb_fw_cfg_dtb, tb_fw_node, &disable_auth); diff --git a/plat/arm/common/arm_dyn_cfg_helpers.c b/plat/arm/common/arm_dyn_cfg_helpers.c index daf0f0a63..ac6c99d2b 100644 --- a/plat/arm/common/arm_dyn_cfg_helpers.c +++ b/plat/arm/common/arm_dyn_cfg_helpers.c @@ -15,83 +15,6 @@ #define DTB_PROP_MBEDTLS_HEAP_ADDR "mbedtls_heap_addr" #define DTB_PROP_MBEDTLS_HEAP_SIZE "mbedtls_heap_size" -typedef struct config_load_info_prop { - unsigned int config_id; - const char *config_addr; - const char *config_max_size; -} config_load_info_prop_t; - -static const config_load_info_prop_t prop_names[] = { - {HW_CONFIG_ID, "hw_config_addr", "hw_config_max_size"}, - {SOC_FW_CONFIG_ID, "soc_fw_config_addr", "soc_fw_config_max_size"}, - {TOS_FW_CONFIG_ID, "tos_fw_config_addr", "tos_fw_config_max_size"}, - {NT_FW_CONFIG_ID, "nt_fw_config_addr", "nt_fw_config_max_size"} -}; - -/******************************************************************************* - * Helper to read the load information corresponding to the `config_id` in - * TB_FW_CONFIG. This function expects the following properties to be defined : - * _addr size : 2 cells - * _max_size size : 1 cell - * - * Arguments: - * void *dtb - pointer to the TB_FW_CONFIG in memory - * int node - The node offset to appropriate node in the - * DTB. - * unsigned int config_id - The configuration id - * uint64_t *config_addr - Returns the `config` load address if read - * is successful. - * uint32_t *config_size - Returns the `config` size if read is - * successful. - * - * Returns 0 on success and -1 on error. - ******************************************************************************/ -int arm_dyn_get_config_load_info(void *dtb, int node, unsigned int config_id, - uint64_t *config_addr, uint32_t *config_size) -{ - int err; - unsigned int i; - - assert(dtb != NULL); - assert(config_addr != NULL); - assert(config_size != NULL); - - for (i = 0; i < ARRAY_SIZE(prop_names); i++) { - if (prop_names[i].config_id == config_id) - break; - } - - if (i == ARRAY_SIZE(prop_names)) { - WARN("Invalid config id %d\n", config_id); - return -1; - } - - /* Check if the pointer to DT is correct */ - assert(fdt_check_header(dtb) == 0); - - /* Assert the node offset point to "arm,tb_fw" compatible property */ - assert(node == fdt_node_offset_by_compatible(dtb, -1, "arm,tb_fw")); - - err = fdtw_read_cells(dtb, node, prop_names[i].config_addr, 2, - (void *) config_addr); - if (err < 0) { - WARN("Read cell failed for %s\n", prop_names[i].config_addr); - return -1; - } - - err = fdtw_read_cells(dtb, node, prop_names[i].config_max_size, 1, - (void *) config_size); - if (err < 0) { - WARN("Read cell failed for %s\n", prop_names[i].config_max_size); - return -1; - } - - VERBOSE("Dyn cfg: Read config_id %d load info from TB_FW_CONFIG 0x%llx 0x%x\n", - config_id, (unsigned long long)*config_addr, *config_size); - - return 0; -} - /******************************************************************************* * Helper to read the `disable_auth` property in config DTB. This function * expects the following properties to be present in the config DTB. -- cgit v1.2.3 From ce8528411a95d4e988844d5d16b5af2828f9f407 Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Mon, 30 Sep 2019 10:57:24 +0100 Subject: fconf: Add TBBR disable_authentication property Use fconf to retrieve the `disable_authentication` property. Move this access from arm dynamic configuration to bl common. Change-Id: Ibf184a5c6245d04839222f5457cf5e651f252b86 Signed-off-by: Louis Mayencourt --- common/bl_common.c | 2 +- include/lib/fconf/fconf_tbbr_getter.h | 10 +++++ include/plat/arm/common/arm_dyn_cfg_helpers.h | 1 - lib/fconf/fconf_tbbr_getter.c | 56 +++++++++++++++++++++++++++ plat/arm/common/arm_common.mk | 3 +- plat/arm/common/arm_dyn_cfg.c | 23 ----------- plat/arm/common/arm_dyn_cfg_helpers.c | 45 --------------------- 7 files changed, 69 insertions(+), 71 deletions(-) create mode 100644 lib/fconf/fconf_tbbr_getter.c diff --git a/common/bl_common.c b/common/bl_common.c index b74225b13..2fcb5385d 100644 --- a/common/bl_common.c +++ b/common/bl_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ diff --git a/include/lib/fconf/fconf_tbbr_getter.h b/include/lib/fconf/fconf_tbbr_getter.h index fb81e7bea..32e1b6594 100644 --- a/include/lib/fconf/fconf_tbbr_getter.h +++ b/include/lib/fconf/fconf_tbbr_getter.h @@ -12,4 +12,14 @@ /* TBBR related getter */ #define tbbr__cot_getter(id) cot_desc_ptr[id] +#define tbbr__dyn_config_getter(id) tbbr_dyn_config.id + +struct tbbr_dyn_config_t { + uint32_t disable_auth; +}; + +extern struct tbbr_dyn_config_t tbbr_dyn_config; + +int fconf_populate_tbbr_dyn_config(uintptr_t config); + #endif /* FCONF_TBBR_GETTER_H */ diff --git a/include/plat/arm/common/arm_dyn_cfg_helpers.h b/include/plat/arm/common/arm_dyn_cfg_helpers.h index 9fb31317c..61f876f82 100644 --- a/include/plat/arm/common/arm_dyn_cfg_helpers.h +++ b/include/plat/arm/common/arm_dyn_cfg_helpers.h @@ -11,7 +11,6 @@ /* Function declarations */ int arm_dyn_tb_fw_cfg_init(void *dtb, int *node); -int arm_dyn_get_disable_auth(void *dtb, int node, uint32_t *disable_auth); int arm_get_dtb_mbedtls_heap_info(void *dtb, void **heap_addr, size_t *heap_size); int arm_set_dtb_mbedtls_heap_info(void *dtb, void *heap_addr, diff --git a/lib/fconf/fconf_tbbr_getter.c b/lib/fconf/fconf_tbbr_getter.c new file mode 100644 index 000000000..29f67caec --- /dev/null +++ b/lib/fconf/fconf_tbbr_getter.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2019-2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include + +#include +#include +#include +#include +#include + +struct tbbr_dyn_config_t tbbr_dyn_config; + +int fconf_populate_tbbr_dyn_config(uintptr_t config) +{ + int err; + int node; + + /* As libfdt use void *, we can't avoid this cast */ + const void *dtb = (void *)config; + + /* Assert the node offset point to "arm,tb_fw" compatible property */ + const char *compatible_str = "arm,tb_fw"; + 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 disable_auth cell and read the value */ + err = fdtw_read_cells(dtb, node, "disable_auth", 1, &tbbr_dyn_config.disable_auth); + if (err < 0) { + WARN("FCONF: Read cell failed for `disable_auth`\n"); + return err; + } + + /* Check if the value is boolean */ + if ((tbbr_dyn_config.disable_auth != 0U) && (tbbr_dyn_config.disable_auth != 1U)) { + WARN("Invalid value for `disable_auth` cell %d\n", tbbr_dyn_config.disable_auth); + return -1; + } + +#if defined(DYN_DISABLE_AUTH) + if (tbbr_dyn_config.disable_auth == 1) + dyn_disable_auth(); +#endif + + VERBOSE("FCONF:tbbr.disable_auth cell found with value = %d\n", + tbbr_dyn_config.disable_auth); + + return 0; +} + +FCONF_REGISTER_POPULATOR(tbbr, fconf_populate_tbbr_dyn_config); diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index abf2f914e..ceff6e2bb 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -273,7 +273,8 @@ ifneq (${TRUSTED_BOARD_BOOT},0) # Include common TBB sources AUTH_SOURCES := drivers/auth/auth_mod.c \ drivers/auth/crypto_mod.c \ - drivers/auth/img_parser_mod.c + drivers/auth/img_parser_mod.c \ + lib/fconf/fconf_tbbr_getter.c # Include the selected chain of trust sources. ifeq (${COT},tbbr) diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c index 402fd93da..d373dedc8 100644 --- a/plat/arm/common/arm_dyn_cfg.c +++ b/plat/arm/common/arm_dyn_cfg.c @@ -207,27 +207,4 @@ void arm_bl2_dyn_cfg_init(void) */ cfg_mem_params->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING; } - -#if TRUSTED_BOARD_BOOT && defined(DYN_DISABLE_AUTH) - uint32_t disable_auth = 0; - void *tb_fw_cfg_dtb; - int err, tb_fw_node; - - dtb_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID); - tb_fw_cfg_dtb = (void *)dtb_info->config_addr; - - err = arm_dyn_tb_fw_cfg_init(tb_fw_cfg_dtb, &tb_fw_node); - if (err < 0) { - ERROR("Invalid TB_FW_CONFIG passed from BL1\n"); - panic(); - } - - err = arm_dyn_get_disable_auth(tb_fw_cfg_dtb, tb_fw_node, - &disable_auth); - if (err < 0) - return; - - if (disable_auth == 1) - dyn_disable_auth(); -#endif } diff --git a/plat/arm/common/arm_dyn_cfg_helpers.c b/plat/arm/common/arm_dyn_cfg_helpers.c index ac6c99d2b..db6f26073 100644 --- a/plat/arm/common/arm_dyn_cfg_helpers.c +++ b/plat/arm/common/arm_dyn_cfg_helpers.c @@ -15,51 +15,6 @@ #define DTB_PROP_MBEDTLS_HEAP_ADDR "mbedtls_heap_addr" #define DTB_PROP_MBEDTLS_HEAP_SIZE "mbedtls_heap_size" -/******************************************************************************* - * Helper to read the `disable_auth` property in config DTB. This function - * expects the following properties to be present in the config DTB. - * name : disable_auth size : 1 cell - * - * Arguments: - * void *dtb - pointer to the TB_FW_CONFIG in memory - * int node - The node offset to appropriate node in the - * DTB. - * uint64_t *disable_auth - The value of `disable_auth` property on - * successful read. Must be 0 or 1. - * - * Returns 0 on success and -1 on error. - ******************************************************************************/ -int arm_dyn_get_disable_auth(void *dtb, int node, uint32_t *disable_auth) -{ - int err; - - assert(dtb != NULL); - assert(disable_auth != NULL); - - /* Check if the pointer to DT is correct */ - assert(fdt_check_header(dtb) == 0); - - /* Assert the node offset point to "arm,tb_fw" compatible property */ - assert(node == fdt_node_offset_by_compatible(dtb, -1, "arm,tb_fw")); - - /* Locate the disable_auth cell and read the value */ - err = fdtw_read_cells(dtb, node, "disable_auth", 1, disable_auth); - if (err < 0) { - WARN("Read cell failed for `disable_auth`\n"); - return -1; - } - - /* Check if the value is boolean */ - if ((*disable_auth != 0U) && (*disable_auth != 1U)) { - WARN("Invalid value for `disable_auth` cell %d\n", *disable_auth); - return -1; - } - - VERBOSE("Dyn cfg: `disable_auth` cell found with value = %d\n", - *disable_auth); - return 0; -} - /******************************************************************************* * Validate the tb_fw_config is a valid DTB file and returns the node offset * to "arm,tb_fw" property. -- cgit v1.2.3 From 6c9723176019cb5327d5be0e952583809b714f5f Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Tue, 1 Oct 2019 10:45:14 +0100 Subject: fconf: Add mbedtls shared heap as property Use the firmware configuration framework in arm dynamic configuration to retrieve mbedtls heap information between bl1 and bl2. For this, a new fconf getter is added to expose the device tree base address and size. Change-Id: Ifa5ac9366ae100e2cdd1f4c8e85fc591b170f4b6 Signed-off-by: Louis Mayencourt --- include/lib/fconf/fconf_tbbr_getter.h | 2 ++ include/plat/arm/common/arm_dyn_cfg_helpers.h | 2 -- lib/fconf/fconf_tbbr_getter.c | 19 +++++++++++++ plat/arm/common/arm_dyn_cfg.c | 21 +++----------- plat/arm/common/arm_dyn_cfg_helpers.c | 41 --------------------------- 5 files changed, 25 insertions(+), 60 deletions(-) diff --git a/include/lib/fconf/fconf_tbbr_getter.h b/include/lib/fconf/fconf_tbbr_getter.h index 32e1b6594..eddc0c4b5 100644 --- a/include/lib/fconf/fconf_tbbr_getter.h +++ b/include/lib/fconf/fconf_tbbr_getter.h @@ -16,6 +16,8 @@ struct tbbr_dyn_config_t { uint32_t disable_auth; + void *mbedtls_heap_addr; + size_t mbedtls_heap_size; }; 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 61f876f82..2dc94abe3 100644 --- a/include/plat/arm/common/arm_dyn_cfg_helpers.h +++ b/include/plat/arm/common/arm_dyn_cfg_helpers.h @@ -11,8 +11,6 @@ /* Function declarations */ int arm_dyn_tb_fw_cfg_init(void *dtb, int *node); -int arm_get_dtb_mbedtls_heap_info(void *dtb, void **heap_addr, - size_t *heap_size); int arm_set_dtb_mbedtls_heap_info(void *dtb, void *heap_addr, size_t heap_size); diff --git a/lib/fconf/fconf_tbbr_getter.c b/lib/fconf/fconf_tbbr_getter.c index 29f67caec..c6df9c876 100644 --- a/lib/fconf/fconf_tbbr_getter.c +++ b/lib/fconf/fconf_tbbr_getter.c @@ -47,8 +47,27 @@ int fconf_populate_tbbr_dyn_config(uintptr_t config) dyn_disable_auth(); #endif + /* Retrieve the Mbed TLS heap details from the DTB */ + err = fdtw_read_cells(dtb, node, + "mbedtls_heap_addr", 2, &tbbr_dyn_config.mbedtls_heap_addr); + if (err < 0) { + ERROR("FCONF: Read cell failed for mbedtls_heap\n"); + return err; + } + + err = fdtw_read_cells(dtb, node, + "mbedtls_heap_size", 1, &tbbr_dyn_config.mbedtls_heap_size); + if (err < 0) { + ERROR("FCONF: Read cell failed for mbedtls_heap\n"); + return err; + } + VERBOSE("FCONF:tbbr.disable_auth cell found with value = %d\n", tbbr_dyn_config.disable_auth); + VERBOSE("FCONF:tbbr.mbedtls_heap_addr cell found with value = %p\n", + tbbr_dyn_config.mbedtls_heap_addr); + VERBOSE("FCONF:tbbr.mbedtls_heap_size cell found with value = %zu\n", + tbbr_dyn_config.mbedtls_heap_size); return 0; } diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c index d373dedc8..b9361a479 100644 --- a/plat/arm/common/arm_dyn_cfg.c +++ b/plat/arm/common/arm_dyn_cfg.c @@ -18,6 +18,7 @@ #endif #include #include +#include #include #include #include @@ -56,24 +57,10 @@ int arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size) #elif defined(IMAGE_BL2) - int err; - void *tb_fw_cfg_dtb; - - /* fconf FW_CONFIG and TB_FW_CONFIG are currently the same DTB*/ - tb_fw_cfg_dtb = (void *)FCONF_GET_PROPERTY(fconf, dtb, base_addr); - /* If in BL2, retrieve the already allocated heap's info from DTB */ - if (tb_fw_cfg_dtb != NULL) { - err = arm_get_dtb_mbedtls_heap_info(tb_fw_cfg_dtb, heap_addr, - heap_size); - if (err < 0) { - ERROR("BL2: unable to retrieve shared Mbed TLS heap information from DTB\n"); - panic(); - } - } else { - ERROR("BL2: DTB missing, cannot get Mbed TLS heap\n"); - panic(); - } + *heap_addr = FCONF_GET_PROPERTY(tbbr, dyn_config, mbedtls_heap_addr); + *heap_size = FCONF_GET_PROPERTY(tbbr, dyn_config, mbedtls_heap_size); + #endif return 0; diff --git a/plat/arm/common/arm_dyn_cfg_helpers.c b/plat/arm/common/arm_dyn_cfg_helpers.c index db6f26073..909c4a671 100644 --- a/plat/arm/common/arm_dyn_cfg_helpers.c +++ b/plat/arm/common/arm_dyn_cfg_helpers.c @@ -46,47 +46,6 @@ int arm_dyn_tb_fw_cfg_init(void *dtb, int *node) return 0; } -/* - * Reads and returns the Mbed TLS shared heap information from the DTB. - * This function is supposed to be called *only* when a DTB is present. - * This function is supposed to be called only by BL2. - * - * Returns: - * 0 = success - * -1 = error. In this case the values of heap_addr, heap_size should be - * considered as garbage by the caller. - */ -int arm_get_dtb_mbedtls_heap_info(void *dtb, void **heap_addr, - size_t *heap_size) -{ - int err, dtb_root; - - /* Verify the DTB is valid and get the root node */ - err = arm_dyn_tb_fw_cfg_init(dtb, &dtb_root); - if (err < 0) { - ERROR("Invalid TB_FW_CONFIG. Cannot retrieve Mbed TLS heap information from DTB\n"); - return -1; - } - - /* Retrieve the Mbed TLS heap details from the DTB */ - err = fdtw_read_cells(dtb, dtb_root, - DTB_PROP_MBEDTLS_HEAP_ADDR, 2, heap_addr); - if (err < 0) { - ERROR("Error while reading %s from DTB\n", - DTB_PROP_MBEDTLS_HEAP_ADDR); - return -1; - } - err = fdtw_read_cells(dtb, dtb_root, - DTB_PROP_MBEDTLS_HEAP_SIZE, 1, heap_size); - if (err < 0) { - ERROR("Error while reading %s from DTB\n", - DTB_PROP_MBEDTLS_HEAP_SIZE); - return -1; - } - return 0; -} - - /* * This function writes the Mbed TLS heap address and size in the DTB. When it * is called, it is guaranteed that a DTB is available. However it is not -- cgit v1.2.3 From 0a6e7e3b76fa0e6aea6a40c69ad7d4ea8be720d8 Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Thu, 24 Oct 2019 15:18:46 +0100 Subject: fconf: Move platform io policies into fconf Use the firmware configuration framework to store the io_policies information inside the configuration device tree instead of the static structure in the code base. The io_policies required by BL1 can't be inside the dtb, as this one is loaded by BL1, and only available at BL2. This change currently only applies to FVP platform. Change-Id: Ic9c1ac3931a4a136aa36f7f58f66d3764c1bfca1 Signed-off-by: Louis Mayencourt --- Makefile | 2 + docs/getting_started/build-options.rst | 5 + include/drivers/io/io_storage.h | 4 +- include/plat/arm/common/arm_fconf_getter.h | 24 +++++ include/plat/arm/common/arm_fconf_io_storage.h | 19 ++++ include/tools_share/uuid.h | 7 +- make_helpers/defaults.mk | 3 + plat/arm/board/fvp/fdts/fvp_fw_config.dts | 25 +++++ plat/arm/board/fvp/platform.mk | 5 + plat/arm/common/arm_common.mk | 12 ++- plat/arm/common/arm_fconf_io_storage.c | 142 ++++++++++++++++++++++++ plat/arm/common/fconf/arm_fconf_io.c | 143 +++++++++++++++++++++++++ 12 files changed, 386 insertions(+), 5 deletions(-) create mode 100644 include/plat/arm/common/arm_fconf_getter.h create mode 100644 include/plat/arm/common/arm_fconf_io_storage.h create mode 100644 plat/arm/common/arm_fconf_io_storage.c create mode 100644 plat/arm/common/fconf/arm_fconf_io.c diff --git a/Makefile b/Makefile index 5167d2e53..42921edc5 100644 --- a/Makefile +++ b/Makefile @@ -777,6 +777,7 @@ $(eval $(call assert_boolean,SPM_MM)) $(eval $(call assert_boolean,TRUSTED_BOARD_BOOT)) $(eval $(call assert_boolean,USE_COHERENT_MEM)) $(eval $(call assert_boolean,USE_DEBUGFS)) +$(eval $(call assert_boolean,USE_FCONF_BASED_IO)) $(eval $(call assert_boolean,USE_ROMLIB)) $(eval $(call assert_boolean,USE_TBBR_DEFS)) $(eval $(call assert_boolean,WARMBOOT_ENABLE_DCACHE_EARLY)) @@ -845,6 +846,7 @@ $(eval $(call add_define,SPM_MM)) $(eval $(call add_define,TRUSTED_BOARD_BOOT)) $(eval $(call add_define,USE_COHERENT_MEM)) $(eval $(call add_define,USE_DEBUGFS)) +$(eval $(call add_define,USE_FCONF_BASED_IO)) $(eval $(call add_define,USE_ROMLIB)) $(eval $(call add_define,USE_TBBR_DEFS)) $(eval $(call add_define,WARMBOOT_ENABLE_DCACHE_EARLY)) diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index ca305355b..c1787a802 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -578,6 +578,11 @@ Common build options exposing a virtual filesystem interface through BL31 as a SiP SMC function. Default is 0. +- ``USE_FCONF_BASED_IO``: This flag determines whether to use IO based on the + firmware configuration framework. This allows moving the io_policies into a + configuration device tree, instead of static structure in the code base. + + - ``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 reduces SRAM usage. Refer to :ref:`Library at ROM` for further details. Default diff --git a/include/drivers/io/io_storage.h b/include/drivers/io/io_storage.h index 0e6ffd619..a301ad563 100644 --- a/include/drivers/io/io_storage.h +++ b/include/drivers/io/io_storage.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -53,7 +53,7 @@ typedef struct io_file_spec { /* UUID specification - used to refer to data accessed using UUIDs (i.e. FIP * images) */ typedef struct io_uuid_spec { - const uuid_t uuid; + uuid_t uuid; } io_uuid_spec_t; /* Block specification - used to refer to data on a device supporting diff --git a/include/plat/arm/common/arm_fconf_getter.h b/include/plat/arm/common/arm_fconf_getter.h new file mode 100644 index 000000000..28913a43f --- /dev/null +++ b/include/plat/arm/common/arm_fconf_getter.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2019-2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef ARM_FCONF_GETTER +#define ARM_FCONF_GETTER + +#include + +/* ARM io policies */ +#define arm__io_policies_getter(id) &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_arm_io_policies(uintptr_t config); + +#endif /* ARM_FCONF_GETTER */ diff --git a/include/plat/arm/common/arm_fconf_io_storage.h b/include/plat/arm/common/arm_fconf_io_storage.h new file mode 100644 index 000000000..02ee66c35 --- /dev/null +++ b/include/plat/arm/common/arm_fconf_io_storage.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef ARM_FCONF_IO_STORAGE_H +#define ARM_FCONF_IO_STORAGE_H + +#include + +/* IO devices handle */ +extern uintptr_t memmap_dev_handle; +extern uintptr_t fip_dev_handle; + +/* Function declarations */ +int open_fip(const uintptr_t spec); +int open_memmap(const uintptr_t spec); + +#endif /* ARM_FCONF_IO_STORAGE_H */ diff --git a/include/tools_share/uuid.h b/include/tools_share/uuid.h index 7d0043206..36be9ed37 100644 --- a/include/tools_share/uuid.h +++ b/include/tools_share/uuid.h @@ -27,7 +27,7 @@ */ /* - * Portions copyright (c) 2014, ARM Limited and Contributors. + * Portions copyright (c) 2014-2020, ARM Limited and Contributors. * All rights reserved. */ @@ -56,6 +56,11 @@ struct uuid { uint8_t node[_UUID_NODE_LEN]; }; +union uuid_helper_t { + struct uuid uuid_struct; + uint32_t word[4]; +}; + /* XXX namespace pollution? */ typedef struct uuid uuid_t; diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index fff336cd2..e8e990d45 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -201,6 +201,9 @@ USE_COHERENT_MEM := 1 # Build option to add debugfs support USE_DEBUGFS := 0 +# Build option to fconf based io +USE_FCONF_BASED_IO := 0 + # Build option to choose whether Trusted Firmware uses library at ROM USE_ROMLIB := 0 diff --git a/plat/arm/board/fvp/fdts/fvp_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_fw_config.dts index ff83db361..d0f60331d 100644 --- a/plat/arm/board/fvp/fdts/fvp_fw_config.dts +++ b/plat/arm/board/fvp/fdts/fvp_fw_config.dts @@ -68,4 +68,29 @@ mbedtls_heap_addr = <0x0 0x0>; mbedtls_heap_size = <0x0>; }; + + arm-io_policies { + fip-handles { + compatible = "arm,io-fip-handle"; + scp_bl2_uuid = <0x3dfd6697 0x49e8be89 0xa1785dae 0x13826040>; + bl31_uuid = <0x6d08d447 0x4698fe4c 0x5029959b 0x005abdcb>; + bl32_uuid = <0x89e1d005 0x4713dc53 0xa502b8d 0x383e7a4b>; + bl32_extra1_uuid = <0x9bc2700b 0x40785a2a 0x560a659f 0x88827382>; + bl32_extra2_uuid = <0xb17ba88e 0x4d3fa2cf 0xbbe7fd85 0xd92002a5>; + bl33_uuid = <0xa7eed0d6 0x4bd5eafc 0x34998297 0xe4b634f2>; + hw_cfg_uuid = <0xd9f1b808 0x4993cfc9 0xbc6f62a9 0xcc65726b>; + soc_fw_cfg_uuid = <0x4b817999 0x46fb7603 0x268d8e8c 0xe059787f>; + tos_fw_cfg_uuid = <0x1a7c2526 0x477fc6db 0xc4c4968d 0x218024b0>; + nt_fw_cfg_uuid = <0x1598da28 0x447ee893 0xaf1a66ac 0xf9501580>; + t_key_cert_uuid = <0x90e87e82 0x11e460f8 0x7a77b4a1 0x4cf9b421>; + scp_fw_key_uuid = <0xa1214202 0x11e460f8 0x3cf39b8d 0x14a0150e>; + soc_fw_key_uuid = <0xccbeb88a 0x11e460f9 0x48ebd09a 0xf8dcd822>; + tos_fw_key_cert_uuid = <0x3d67794 0x11e460fb 0x10b7dd85 0x4ee8c5b>; + nt_fw_key_cert_uuid = <0x2a83d58a 0x11e460fb 0x30dfaf8a 0x5998c4bb>; + scp_fw_content_cert_uuid = <0x046fbe44 0x11e4635e 0xd8738bb2 0x5696aeea>; + soc_fw_content_cert_uuid = <0x200cb2e2 0x11e4635e 0xccabe89c 0x66b62bf9>; + tos_fw_content_cert_uuid = <0x11449fa4 0x11e4635e 0x53f2887 0x3df32a72>; + nt_fw_content_cert_uuid = <0xf3c1c48e 0x11e4635d 0xee87a9a7 0xa73fb240>; + }; + }; }; diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index f46f8e211..9d7d768ce 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -10,6 +10,11 @@ FVP_USE_GIC_DRIVER := FVP_GICV3 # Use the SP804 timer instead of the generic one FVP_USE_SP804_TIMER := 0 +# Use fconf based io for FVP +ifeq ($(BL2_AT_EL3), 0) +USE_FCONF_BASED_IO := 1 +endif + # Default cluster count for FVP FVP_CLUSTER_COUNT := 2 diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index ceff6e2bb..a4d365e9a 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -177,12 +177,20 @@ include lib/xlat_tables_v2/xlat_tables.mk PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS} endif +ifeq (${USE_FCONF_BASED_IO}, 0) +ARM_IO_SOURCES += plat/arm/common/arm_io_storage.c +else +ARM_IO_SOURCES += plat/arm/common/arm_fconf_io_storage.c \ + plat/arm/common/fconf/arm_fconf_io.c +endif + BL1_SOURCES += drivers/io/io_fip.c \ drivers/io/io_memmap.c \ drivers/io/io_storage.c \ plat/arm/common/arm_bl1_setup.c \ plat/arm/common/arm_err.c \ - plat/arm/common/arm_io_storage.c + ${ARM_IO_SOURCES} + ifdef EL3_PAYLOAD_BASE # Need the plat_arm_program_trusted_mailbox() function to release secondary CPUs from # their holding pen @@ -196,7 +204,7 @@ BL2_SOURCES += drivers/delay_timer/delay_timer.c \ drivers/io/io_storage.c \ plat/arm/common/arm_bl2_setup.c \ plat/arm/common/arm_err.c \ - plat/arm/common/arm_io_storage.c + ${ARM_IO_SOURCES} # Firmware Configuration Framework sources include lib/fconf/fconf.mk diff --git a/plat/arm/common/arm_fconf_io_storage.c b/plat/arm/common/arm_fconf_io_storage.c new file mode 100644 index 000000000..afc8dbe47 --- /dev/null +++ b/plat/arm/common/arm_fconf_io_storage.c @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2015-2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* IO devices */ +static const io_dev_connector_t *fip_dev_con; +uintptr_t fip_dev_handle; +static const io_dev_connector_t *memmap_dev_con; +uintptr_t memmap_dev_handle; + +/* Weak definitions may be overridden in specific ARM standard platform */ +#pragma weak plat_arm_io_setup +#pragma weak plat_arm_get_alt_image_source + +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; +} + +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; +} + +void arm_io_setup(void) +{ + int io_result; + + io_result = register_io_dev_fip(&fip_dev_con); + assert(io_result == 0); + + io_result = register_io_dev_memmap(&memmap_dev_con); + assert(io_result == 0); + + /* Open connections to devices and cache the handles */ + io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, + &fip_dev_handle); + assert(io_result == 0); + + io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, + &memmap_dev_handle); + assert(io_result == 0); + + /* Ignore improbable errors in release builds */ + (void)io_result; +} + +void plat_arm_io_setup(void) +{ + arm_io_setup(); +} + +int plat_arm_get_alt_image_source( + unsigned int image_id __unused, + uintptr_t *dev_handle __unused, + uintptr_t *image_spec __unused) +{ + /* By default do not try an alternative */ + return -ENOENT; +} + +/* 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 result; + const struct plat_io_policy *policy; + + assert(image_id < MAX_NUMBER_IDS); + + policy = FCONF_GET_PROPERTY(arm, io_policies, image_id); + result = policy->check(policy->image_spec); + if (result == 0) { + *image_spec = policy->image_spec; + *dev_handle = *(policy->dev_handle); + } else { + VERBOSE("Trying alternative IO\n"); + result = plat_arm_get_alt_image_source(image_id, dev_handle, + image_spec); + } + + return result; +} + +/* + * See if a Firmware Image Package is available, + * by checking if TOC is valid or not. + */ +int arm_io_is_toc_valid(void) +{ + int result; + + result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); + + if (result == 0) { + return 1UL; + } else { + return 0UL; + } +} diff --git a/plat/arm/common/fconf/arm_fconf_io.c b/plat/arm/common/fconf/arm_fconf_io.c new file mode 100644 index 000000000..3c0586fd0 --- /dev/null +++ b/plat/arm/common/fconf/arm_fconf_io.c @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2019-2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +const io_block_spec_t fip_block_spec = { + .offset = PLAT_ARM_FIP_BASE, + .length = PLAT_ARM_FIP_MAX_SIZE +}; + +const io_uuid_spec_t arm_uuid_spec[MAX_NUMBER_IDS] = { + [BL2_IMAGE_ID] = {UUID_TRUSTED_BOOT_FIRMWARE_BL2}, + [TB_FW_CONFIG_ID] = {UUID_TB_FW_CONFIG}, +#if TRUSTED_BOARD_BOOT + [TRUSTED_BOOT_FW_CERT_ID] = {UUID_TRUSTED_BOOT_FW_CERT}, +#endif /* TRUSTED_BOARD_BOOT */ +}; + +/* By default, ARM platforms load images from the FIP */ +struct plat_io_policy policies[MAX_NUMBER_IDS] = { + [FIP_IMAGE_ID] = { + &memmap_dev_handle, + (uintptr_t)&fip_block_spec, + open_memmap + }, + [BL2_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[BL2_IMAGE_ID], + open_fip + }, + [TB_FW_CONFIG_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[TB_FW_CONFIG_ID], + open_fip + }, +#if TRUSTED_BOARD_BOOT + [TRUSTED_BOOT_FW_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[TRUSTED_BOOT_FW_CERT_ID], + open_fip + }, +#endif /* TRUSTED_BOARD_BOOT */ +}; + +#ifdef IMAGE_BL2 + +#if TRUSTED_BOARD_BOOT +#define FCONF_ARM_IO_UUID_NUMBER 19 +#else +#define FCONF_ARM_IO_UUID_NUMBER 10 +#endif + +static io_uuid_spec_t fconf_arm_uuids[FCONF_ARM_IO_UUID_NUMBER]; +static OBJECT_POOL_ARRAY(fconf_arm_uuids_pool, fconf_arm_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_ARM_IO_UUID_NUMBER] = { + {SCP_BL2_IMAGE_ID, "scp_bl2_uuid"}, + {BL31_IMAGE_ID, "bl31_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"}, + {SOC_FW_CONFIG_ID, "soc_fw_cfg_uuid"}, + {TOS_FW_CONFIG_ID, "tos_fw_cfg_uuid"}, + {NT_FW_CONFIG_ID, "nt_fw_cfg_uuid"}, +#if TRUSTED_BOARD_BOOT + {TRUSTED_KEY_CERT_ID, "t_key_cert_uuid"}, + {SCP_FW_KEY_CERT_ID, "scp_fw_key_uuid"}, + {SOC_FW_KEY_CERT_ID, "soc_fw_key_uuid"}, + {TRUSTED_OS_FW_KEY_CERT_ID, "tos_fw_key_cert_uuid"}, + {NON_TRUSTED_FW_KEY_CERT_ID, "nt_fw_key_cert_uuid"}, + {SCP_FW_CONTENT_CERT_ID, "scp_fw_content_cert_uuid"}, + {SOC_FW_CONTENT_CERT_ID, "soc_fw_content_cert_uuid"}, + {TRUSTED_OS_FW_CONTENT_CERT_ID, "tos_fw_content_cert_uuid"}, + {NON_TRUSTED_FW_CONTENT_CERT_ID, "nt_fw_content_cert_uuid"}, +#endif /* TRUSTED_BOARD_BOOT */ +}; + +int fconf_populate_arm_io_policies(uintptr_t config) +{ + int err, node; + unsigned int i; + + union uuid_helper_t uuid_helper; + io_uuid_spec_t *uuid_ptr; + + /* As libfdt uses void *, we can't avoid this cast */ + const void *dtb = (void *)config; + + /* Assert the node offset point to "arm,io-fip-handle" compatible property */ + const char *compatible_str = "arm,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 = 0; i < FCONF_ARM_IO_UUID_NUMBER; i++) { + uuid_ptr = pool_alloc(&fconf_arm_uuids_pool); + err = fdtw_read_array(dtb, node, load_info[i].name, 4, &uuid_helper.word); + if (err < 0) { + WARN("FCONF: Read cell failed for %s\n", load_info[i].name); + return err; + } + + VERBOSE("FCONF: arm-io_policies.%s cell found with value = 0x%x 0x%x 0x%x 0x%x\n", + load_info[i].name, + uuid_helper.word[0], uuid_helper.word[1], + uuid_helper.word[2], uuid_helper.word[3]); + + 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(arm_io, fconf_populate_arm_io_policies); + +#endif /* IMAGE_BL2 */ -- cgit v1.2.3 From 326150b9862c7ee359dd5c189c8c6e10622551d6 Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Fri, 8 Nov 2019 15:09:15 +0000 Subject: fconf: Add documentation Change-Id: I606f9491fb6deebc6845c5b9d7db88fc5c895bd9 Signed-off-by: Louis Mayencourt --- docs/components/fconf.rst | 85 ++++++++++++++++++++++ docs/components/index.rst | 1 + docs/global_substitutions.txt | 2 + docs/glossary.rst | 6 ++ .../diagrams/plantuml/fconf_bl1_load_config.puml | 52 +++++++++++++ .../diagrams/plantuml/fconf_bl2_populate.puml | 41 +++++++++++ 6 files changed, 187 insertions(+) create mode 100644 docs/components/fconf.rst create mode 100644 docs/resources/diagrams/plantuml/fconf_bl1_load_config.puml create mode 100644 docs/resources/diagrams/plantuml/fconf_bl2_populate.puml diff --git a/docs/components/fconf.rst b/docs/components/fconf.rst new file mode 100644 index 000000000..cec3cebe4 --- /dev/null +++ b/docs/components/fconf.rst @@ -0,0 +1,85 @@ +Firmware Configuration Framework +================================ + +This document provides an overview of the |FCONF| framework. + +Introduction +~~~~~~~~~~~~ + +The Firmware CONfiguration Framework (|FCONF|) is an abstraction layer for +platform specific data, allowing a "property" to be queried and a value +retrieved without the requesting entity knowing what backing store is being used +to hold the data. + +It is used to bridge new and old ways of providing platform-specific data. +Today, information like the Chain of Trust is held within several, nested +platform-defined tables. In the future, it may be provided as part of a device +blob, along with the rest of the information about images to load. +Introducing this abstraction layer will make migration easier and will preserve +functionality for platforms that cannot / don't want to use device tree. + +Accessing properties +~~~~~~~~~~~~~~~~~~~~ + +Properties defined in the |FCONF| are grouped around namespaces and +sub-namespaces: a.b.property. +Examples namespace can be: + +- (|TBBR|) Chain of Trust data: tbbr.cot.trusted_boot_fw_cert +- (|TBBR|) dynamic configuration info: tbbr.dyn_config.disable_auth +- Arm io policies: arm.io_policies.bl2_image + +Properties can be accessed with the ``FCONF_GET_PROPERTY(a,b,property)`` macro. + +Defining properties +~~~~~~~~~~~~~~~~~~~ + +Properties composing the |FCONF| have to be stored in C structures. If another +backing store is wanted to be used, the platform has to provide a ``populate()`` +function to fill the corresponding C structure. + +The ``populate()`` function must be registered to the |FCONF| framework with +the ``FCONF_REGISTER_POPULATOR()`` macro. This ensures that the function would +be called inside the generic ``fconf_populate()`` function during +initialization. + +:: + + int fconf_populate_tbbr_dyn_config(uintptr_t config) + { + /* read dtb and fill tbbr_dyn_config struct */ + } + + FCONF_REGISTER_POPULATOR(fconf_populate_tbbr_dyn_config); + +Then, a wrapper has to be provided to match the ``FCONF_GET_PROPERTY()`` macro: + +:: + + /* generic getter */ + #define FCONF_GET_PROPERTY(a,b,property) a##__##b##_getter(property) + + /* my specific getter */ + #define tbbr__dyn_config_getter(id) tbbr_dyn_config.id + +This second level wrapper can be used to remap the ``FCONF_GET_PROPERTY()`` to +anything appropriate: structure, array, function, etc.. + +Loading the property device tree +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``fconf_load_config()`` must be called to load the device tree containing +the properties' values. This must be done after the io layer is initialized, as +the |DTB| is stored on an external device (FIP). + +.. uml:: ../resources/diagrams/plantuml/fconf_bl1_load_config.puml + +Populating the properties +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Once a valid device tree is available, the ``fconf_populate(config)`` function +can be used to fill the C data structure with the data from the config |DTB|. +This function will call all the ``populate()`` callbacks which have been +registered with ``FCONF_REGISTER_POPULATOR()``. + +.. uml:: ../resources/diagrams/plantuml/fconf_bl2_populate.puml diff --git a/docs/components/index.rst b/docs/components/index.rst index f1904c004..6a6b1b0d5 100644 --- a/docs/components/index.rst +++ b/docs/components/index.rst @@ -9,6 +9,7 @@ Components spd/index arm-sip-service exception-handling + fconf firmware-update platform-interrupt-controller-API ras diff --git a/docs/global_substitutions.txt b/docs/global_substitutions.txt index 491b160e6..4dda1dcd4 100644 --- a/docs/global_substitutions.txt +++ b/docs/global_substitutions.txt @@ -6,11 +6,13 @@ .. |COT| replace:: :term:`COT` .. |CSS| replace:: :term:`CSS` .. |CVE| replace:: :term:`CVE` +.. |DTB| replace:: :term:`DTB` .. |DS-5| replace:: :term:`DS-5` .. |DSU| replace:: :term:`DSU` .. |DT| replace:: :term:`DT` .. |EL| replace:: :term:`EL` .. |EHF| replace:: :term:`EHF` +.. |FCONF| replace:: :term:`FCONF` .. |FDT| replace:: :term:`FDT` .. |FIP| replace:: :term:`FIP` .. |FVP| replace:: :term:`FVP` diff --git a/docs/glossary.rst b/docs/glossary.rst index 2f19df59c..3da30b02a 100644 --- a/docs/glossary.rst +++ b/docs/glossary.rst @@ -42,12 +42,18 @@ You can find additional definitions in the `Arm Glossary`_. DT Device Tree + DTB + Device Tree Blob + EL Exception Level EHF Exception Handling Framework + FCONF + Firmware Configuration Framework + FDT Flattened Device Tree diff --git a/docs/resources/diagrams/plantuml/fconf_bl1_load_config.puml b/docs/resources/diagrams/plantuml/fconf_bl1_load_config.puml new file mode 100644 index 000000000..c36e54423 --- /dev/null +++ b/docs/resources/diagrams/plantuml/fconf_bl1_load_config.puml @@ -0,0 +1,52 @@ +@startuml + +box "BL1 common code" + participant bl1_main + participant bl_common +end box + +box "arm platform code" #LightBlue + participant fvp_bl1_setup + participant arm_bl1_setup + participant arm_io_storage +end box + +box "platform common code" + participant plat_bl1_common + participant fconf +end box + +bl1_main -> fvp_bl1_setup : bl1_platform_setup() +fvp_bl1_setup -> arm_bl1_setup : arm_bl1_platform_setup() +arm_bl1_setup -> arm_io_storage : plat_arm_io_setup() +note over arm_io_storage : register and setup fip +arm_bl1_setup -> fconf : fconf_load_config() +activate fconf + note over fconf + create and populate an + image_desc_t for TB_FW_CONFIG + end note + fconf -> bl_common : load_auth_image(TB_FW_CONFIG_ID, &image_info) + activate bl_common + note over bl_common + load and auth image from fip + with info from plat_io_policy + end note + bl_common -> arm_io_storage + arm_io_storage -> fconf: FCONF_GET_PROPERTY(arm, arm_io_policies, tb_fw_cfg) + note over fconf: use staticaly defined policies in bl1 + fconf <- bl_common : image_info + deactivate bl_common + note over fconf : get tb_fw_config_dtb from image_info + fconf -> plat_bl1_common : bl1_plat_get_image_desc(BL2_IMAGE_ID) + fconf <- plat_bl1_common : BL2_IMAGE_DESC + note over fconf + set ep_info.args.arg0 of BL2_IMAGE_DESC + to TB_FW_CONFIG base address + end note +arm_bl1_setup <- fconf +deactivate fconf + +== load & auth, prepare and jump to BL2 == + +@enduml diff --git a/docs/resources/diagrams/plantuml/fconf_bl2_populate.puml b/docs/resources/diagrams/plantuml/fconf_bl2_populate.puml new file mode 100644 index 000000000..98a3ff19b --- /dev/null +++ b/docs/resources/diagrams/plantuml/fconf_bl2_populate.puml @@ -0,0 +1,41 @@ +@startuml + +box "BL2 common code" + participant bl2_entrypoint + participant bl2_main +end box + +box "platform common code" + participant fconf + participant fconf_tbbr_getter +end box + +box "arm platform code" #LightBlue + participant arm_bl2_setup + participant arm_io_storage + participant arm_fconf_io +end box + +== bl2 setup == +bl2_entrypoint -> bl2_main : bl2_setup() +bl2_main -> arm_bl2_setup : bl2_early_platform_setup2(\n\t arg0, arg1, arg2, arg3) +note over arm_bl2_setup + arg0 = tb_fw_config + arg1 = mem_layout +end note +arm_bl2_setup -> arm_bl2_setup : arm_bl2_early_platform_setup(\n\t tb_fw_config, mem_layout) +activate arm_bl2_setup + arm_bl2_setup -> fconf: fconf_polulate(tb_fw_config) + activate fconf + fconf -> fconf_tbbr_getter: fconf_populate_tbbr_dyn_config(uintptr_t dtb) + note over fconf_tbbr_getter: read tbbr propeties from dtb + fconf -> arm_fconf_io: fconf_populate_arm_io_policies(uintptr_t dtb) + note over arm_fconf_io: read arm io propeties from dtb + deactivate fconf + arm_bl2_setup -> arm_io_storage : plat_arm_io_setup() + note over arm_io_storage: use populated properties +deactivate arm_bl2_setup + +== bl2 main == + +@enduml -- cgit v1.2.3 From d6dcbcad1897fcb2ca3c6c56c034f44f0274a5bf Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Wed, 29 Jan 2020 11:42:31 +0000 Subject: MISRA fix: Use boolean essential type Change the return type of "arm_io_is_toc_valid()" and "plat_arm_bl1_fwu_needed()" to bool, to match function behavior. Change-Id: I503fba211219a241cb263149ef36ca14e3362a1c Signed-off-by: Louis Mayencourt --- include/plat/arm/common/plat_arm.h | 5 +++-- plat/arm/board/juno/juno_bl1_setup.c | 12 ++++-------- plat/arm/common/arm_bl1_setup.c | 9 +++------ plat/arm/common/arm_fconf_io_storage.c | 12 ++---------- plat/arm/common/arm_io_storage.c | 10 +++------- 5 files changed, 15 insertions(+), 33 deletions(-) diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index 129ceca66..4751314f2 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -6,6 +6,7 @@ #ifndef PLAT_ARM_H #define PLAT_ARM_H +#include #include #include @@ -222,7 +223,7 @@ void arm_sp_min_early_platform_setup(void *from_bl2, uintptr_t tos_fw_config, void arm_sp_min_plat_runtime_setup(void); /* FIP TOC validity check */ -int arm_io_is_toc_valid(void); +bool arm_io_is_toc_valid(void); /* Utility functions for Dynamic Config */ void arm_bl2_dyn_cfg_init(void); @@ -254,7 +255,7 @@ void plat_arm_interconnect_init(void); void plat_arm_interconnect_enter_coherency(void); void plat_arm_interconnect_exit_coherency(void); void plat_arm_program_trusted_mailbox(uintptr_t address); -int plat_arm_bl1_fwu_needed(void); +bool plat_arm_bl1_fwu_needed(void); __dead2 void plat_arm_error_handler(int err); /* diff --git a/plat/arm/board/juno/juno_bl1_setup.c b/plat/arm/board/juno/juno_bl1_setup.c index 89398d686..25a27da07 100644 --- a/plat/arm/board/juno/juno_bl1_setup.c +++ b/plat/arm/board/juno/juno_bl1_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -60,17 +60,13 @@ static int is_watchdog_reset(void) * The following function checks if Firmware update is needed, * by checking if TOC in FIP image is valid or watchdog reset happened. ******************************************************************************/ -int plat_arm_bl1_fwu_needed(void) +bool plat_arm_bl1_fwu_needed(void) { const int32_t *nv_flags_ptr = (const int32_t *)V2M_SYS_NVFLAGS_ADDR; /* Check if TOC is invalid or watchdog reset happened. */ - if ((arm_io_is_toc_valid() != 1) || - (((*nv_flags_ptr == -EAUTH) || (*nv_flags_ptr == -ENOENT)) - && is_watchdog_reset())) - return 1; - - return 0; + return (!arm_io_is_toc_valid() || (((*nv_flags_ptr == -EAUTH) || + (*nv_flags_ptr == -ENOENT)) && is_watchdog_reset())); } /******************************************************************************* diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c index bf4d7bd5c..c2f49c211 100644 --- a/plat/arm/common/arm_bl1_setup.c +++ b/plat/arm/common/arm_bl1_setup.c @@ -188,9 +188,9 @@ void bl1_plat_prepare_exit(entry_point_info_t *ep_info) * On Arm platforms, the FWU process is triggered when the FIP image has * been tampered with. */ -int plat_arm_bl1_fwu_needed(void) +bool plat_arm_bl1_fwu_needed(void) { - return (arm_io_is_toc_valid() != 1); + return !arm_io_is_toc_valid(); } /******************************************************************************* @@ -199,8 +199,5 @@ int plat_arm_bl1_fwu_needed(void) ******************************************************************************/ unsigned int bl1_plat_get_next_image_id(void) { - if (plat_arm_bl1_fwu_needed() != 0) - return NS_BL1U_IMAGE_ID; - - return BL2_IMAGE_ID; + return plat_arm_bl1_fwu_needed() ? NS_BL1U_IMAGE_ID : BL2_IMAGE_ID; } diff --git a/plat/arm/common/arm_fconf_io_storage.c b/plat/arm/common/arm_fconf_io_storage.c index afc8dbe47..6bbdb3cf2 100644 --- a/plat/arm/common/arm_fconf_io_storage.c +++ b/plat/arm/common/arm_fconf_io_storage.c @@ -128,15 +128,7 @@ int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, * See if a Firmware Image Package is available, * by checking if TOC is valid or not. */ -int arm_io_is_toc_valid(void) +bool arm_io_is_toc_valid(void) { - int result; - - result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); - - if (result == 0) { - return 1UL; - } else { - return 0UL; - } + return (io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID) == 0); } diff --git a/plat/arm/common/arm_io_storage.c b/plat/arm/common/arm_io_storage.c index fc1eb490e..60d19b24e 100644 --- a/plat/arm/common/arm_io_storage.c +++ b/plat/arm/common/arm_io_storage.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -357,12 +357,8 @@ int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, * See if a Firmware Image Package is available, * by checking if TOC is valid or not. */ -int arm_io_is_toc_valid(void) +bool arm_io_is_toc_valid(void) { - int result; - - result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); - - return (result == 0); + return (io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID) == 0); } -- cgit v1.2.3 From 97399821256653115c9d6b5d3233934aa7689c0c Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Wed, 29 Jan 2020 14:43:06 +0000 Subject: arm-io: Panic in case of io setup failure Currently, an IO setup failure will be ignored on arm platform release build. Change this to panic instead. Change-Id: I027a045bce2422b0a0fc4ff9e9d4c6e7bf5d2f98 Signed-off-by: Louis Mayencourt --- include/plat/arm/common/plat_arm.h | 2 +- plat/arm/board/fvp/fvp_io_storage.c | 18 +++++++++++------- plat/arm/common/arm_fconf_io_storage.c | 25 +++++++++++++++++-------- plat/arm/common/arm_io_storage.c | 25 +++++++++++++++++-------- 4 files changed, 46 insertions(+), 24 deletions(-) diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index 4751314f2..025a64fa2 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -149,7 +149,7 @@ void arm_setup_romlib(void); #define ARM_ROTPK_DEVEL_ECDSA_ID 3 /* IO storage utility functions */ -void arm_io_setup(void); +int arm_io_setup(void); /* Security utility functions */ void arm_tzc400_setup(const arm_tzc_regions_info_t *tzc_regions); diff --git a/plat/arm/board/fvp/fvp_io_storage.c b/plat/arm/board/fvp/fvp_io_storage.c index 9c4c1d574..109d32150 100644 --- a/plat/arm/board/fvp/fvp_io_storage.c +++ b/plat/arm/board/fvp/fvp_io_storage.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -120,18 +120,22 @@ void plat_arm_io_setup(void) { int io_result; - arm_io_setup(); + 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); - assert(io_result == 0); + 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); - assert(io_result == 0); - - /* Ignore improbable errors in release builds */ - (void)io_result; + if (io_result < 0) { + panic(); + } } /* diff --git a/plat/arm/common/arm_fconf_io_storage.c b/plat/arm/common/arm_fconf_io_storage.c index 6bbdb3cf2..341622a0b 100644 --- a/plat/arm/common/arm_fconf_io_storage.c +++ b/plat/arm/common/arm_fconf_io_storage.c @@ -63,32 +63,41 @@ int open_memmap(const uintptr_t spec) return result; } -void arm_io_setup(void) +int arm_io_setup(void) { int io_result; io_result = register_io_dev_fip(&fip_dev_con); - assert(io_result == 0); + if (io_result < 0) { + return io_result; + } io_result = register_io_dev_memmap(&memmap_dev_con); - assert(io_result == 0); + if (io_result < 0) { + return io_result; + } /* Open connections to devices and cache the handles */ io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, &fip_dev_handle); - assert(io_result == 0); + if (io_result < 0) { + return io_result; + } io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, &memmap_dev_handle); - assert(io_result == 0); - /* Ignore improbable errors in release builds */ - (void)io_result; + return io_result; } void plat_arm_io_setup(void) { - arm_io_setup(); + int err; + + err = arm_io_setup(); + if (err < 0) { + panic(); + } } int plat_arm_get_alt_image_source( diff --git a/plat/arm/common/arm_io_storage.c b/plat/arm/common/arm_io_storage.c index 60d19b24e..f5d8a414d 100644 --- a/plat/arm/common/arm_io_storage.c +++ b/plat/arm/common/arm_io_storage.c @@ -292,32 +292,41 @@ static int open_memmap(const uintptr_t spec) } -void arm_io_setup(void) +int arm_io_setup(void) { int io_result; io_result = register_io_dev_fip(&fip_dev_con); - assert(io_result == 0); + if (io_result < 0) { + return io_result; + } io_result = register_io_dev_memmap(&memmap_dev_con); - assert(io_result == 0); + if (io_result < 0) { + return io_result; + } /* Open connections to devices and cache the handles */ io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, &fip_dev_handle); - assert(io_result == 0); + if (io_result < 0) { + return io_result; + } io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, &memmap_dev_handle); - assert(io_result == 0); - /* Ignore improbable errors in release builds */ - (void)io_result; + return io_result; } void plat_arm_io_setup(void) { - arm_io_setup(); + int err; + + err = arm_io_setup(); + if (err < 0) { + panic(); + } } int plat_arm_get_alt_image_source( -- cgit v1.2.3 From c7d4a2178b4f97d7d6eedce28ab63e5833cdd11b Mon Sep 17 00:00:00 2001 From: Vijayenthiran Subramaniam Date: Mon, 23 Sep 2019 19:32:32 +0530 Subject: plat/arm/sgi: move bl31_platform_setup to board file For SGI-575 and RD platforms, move bl31_platform_setup handler to individual board files to allow the platforms to perform board specific bl31 setup. Change-Id: Ia44bccc0a7f40a155b33909bcb438a0909b20d42 Signed-off-by: Vijayenthiran Subramaniam --- plat/arm/board/rde1edge/rde1edge_plat.c | 8 +++++++- plat/arm/board/rdn1edge/rdn1edge_plat.c | 8 +++++++- plat/arm/board/sgi575/sgi575_plat.c | 9 +++++++-- plat/arm/css/sgi/include/sgi_plat.h | 13 +++++++++++++ plat/arm/css/sgi/sgi_bl31_setup.c | 4 ++-- 5 files changed, 36 insertions(+), 6 deletions(-) create mode 100644 plat/arm/css/sgi/include/sgi_plat.h diff --git a/plat/arm/board/rde1edge/rde1edge_plat.c b/plat/arm/board/rde1edge/rde1edge_plat.c index a1b8d621d..9eccbc43b 100644 --- a/plat/arm/board/rde1edge/rde1edge_plat.c +++ b/plat/arm/board/rde1edge/rde1edge_plat.c @@ -1,10 +1,11 @@ /* - * Copyright (c) 2018, Arm Limited. All rights reserved. + * Copyright (c) 2018-2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include +#include unsigned int plat_arm_sgi_get_platform_id(void) { @@ -16,3 +17,8 @@ unsigned int plat_arm_sgi_get_config_id(void) { return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET); } + +void bl31_platform_setup(void) +{ + sgi_bl31_common_platform_setup(); +} diff --git a/plat/arm/board/rdn1edge/rdn1edge_plat.c b/plat/arm/board/rdn1edge/rdn1edge_plat.c index 3b7e5ee4e..6f4c83c1d 100644 --- a/plat/arm/board/rdn1edge/rdn1edge_plat.c +++ b/plat/arm/board/rdn1edge/rdn1edge_plat.c @@ -1,10 +1,11 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include +#include unsigned int plat_arm_sgi_get_platform_id(void) { @@ -16,3 +17,8 @@ unsigned int plat_arm_sgi_get_config_id(void) { return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET); } + +void bl31_platform_setup(void) +{ + sgi_bl31_common_platform_setup(); +} diff --git a/plat/arm/board/sgi575/sgi575_plat.c b/plat/arm/board/sgi575/sgi575_plat.c index 0d3fd16ab..ab4964a7d 100644 --- a/plat/arm/board/sgi575/sgi575_plat.c +++ b/plat/arm/board/sgi575/sgi575_plat.c @@ -1,11 +1,11 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include - +#include #include unsigned int plat_arm_sgi_get_platform_id(void) @@ -18,3 +18,8 @@ unsigned int plat_arm_sgi_get_config_id(void) return (mmio_read_32(SSC_VERSION) >> SSC_VERSION_CONFIG_SHIFT) & SSC_VERSION_CONFIG_MASK; } + +void bl31_platform_setup(void) +{ + sgi_bl31_common_platform_setup(); +} diff --git a/plat/arm/css/sgi/include/sgi_plat.h b/plat/arm/css/sgi/include/sgi_plat.h new file mode 100644 index 000000000..a5fbded3c --- /dev/null +++ b/plat/arm/css/sgi/include/sgi_plat.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SGI_PLAT_H +#define SGI_PLAT_H + +/* BL31 platform setup common to all SGI based platforms */ +void sgi_bl31_common_platform_setup(void); + +#endif /* SGI_PLAT_H */ diff --git a/plat/arm/css/sgi/sgi_bl31_setup.c b/plat/arm/css/sgi/sgi_bl31_setup.c index ba050d5f1..a2caf7c41 100644 --- a/plat/arm/css/sgi/sgi_bl31_setup.c +++ b/plat/arm/css/sgi/sgi_bl31_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -55,7 +55,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3); } -void bl31_platform_setup(void) +void sgi_bl31_common_platform_setup(void) { arm_bl31_platform_setup(); -- cgit v1.2.3 From 6daeec709441158b59a3010dd04aec102cb5a16a Mon Sep 17 00:00:00 2001 From: Vijayenthiran Subramaniam Date: Tue, 22 Oct 2019 15:46:14 +0530 Subject: plat/arm/sgi: add chip_id and multi_chip_mode to platform variant info Multi-chip platforms have two or more identical chips connected using a high speed coherent link. In order to identify such platforms, add chip_id and multi_chip_mode information in the platform variant info structure. The values of these two new elements is populated during boot. Change-Id: Ie6e89cb33b3f0f408814f6239cd06647053e23ed Signed-off-by: Vijayenthiran Subramaniam --- include/plat/arm/css/common/css_def.h | 6 +++++- plat/arm/board/rde1edge/rde1edge_plat.c | 5 +++++ plat/arm/board/rdn1edge/rdn1edge_plat.c | 6 ++++++ plat/arm/board/sgi575/sgi575_plat.c | 5 +++++ plat/arm/css/sgi/include/sgi_variant.h | 5 +++++ plat/arm/css/sgi/sgi_bl31_setup.c | 1 + 6 files changed, 27 insertions(+), 1 deletion(-) diff --git a/include/plat/arm/css/common/css_def.h b/include/plat/arm/css/common/css_def.h index 2adf11d66..7b6148445 100644 --- a/include/plat/arm/css/common/css_def.h +++ b/include/plat/arm/css/common/css_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -29,6 +29,10 @@ #define SID_REG_BASE 0x2a4a0000 #define SID_SYSTEM_ID_OFFSET 0x40 #define SID_SYSTEM_CFG_OFFSET 0x70 +#define SID_NODE_ID_OFFSET 0x60 +#define SID_CHIP_ID_MASK 0xFF +#define SID_MULTI_CHIP_MODE_MASK 0x100 +#define SID_MULTI_CHIP_MODE_SHIFT 8 /* The slave_bootsecure controls access to GPU, DMC and CS. */ #define CSS_NIC400_SLAVE_BOOTSECURE 8 diff --git a/plat/arm/board/rde1edge/rde1edge_plat.c b/plat/arm/board/rde1edge/rde1edge_plat.c index 9eccbc43b..44d818aec 100644 --- a/plat/arm/board/rde1edge/rde1edge_plat.c +++ b/plat/arm/board/rde1edge/rde1edge_plat.c @@ -18,6 +18,11 @@ unsigned int plat_arm_sgi_get_config_id(void) return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET); } +unsigned int plat_arm_sgi_get_multi_chip_mode(void) +{ + return 0; +} + void bl31_platform_setup(void) { sgi_bl31_common_platform_setup(); diff --git a/plat/arm/board/rdn1edge/rdn1edge_plat.c b/plat/arm/board/rdn1edge/rdn1edge_plat.c index 6f4c83c1d..f7c7e9b5c 100644 --- a/plat/arm/board/rdn1edge/rdn1edge_plat.c +++ b/plat/arm/board/rdn1edge/rdn1edge_plat.c @@ -18,6 +18,12 @@ unsigned int plat_arm_sgi_get_config_id(void) return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET); } +unsigned int plat_arm_sgi_get_multi_chip_mode(void) +{ + return (mmio_read_32(SID_REG_BASE + SID_NODE_ID_OFFSET) & + SID_MULTI_CHIP_MODE_MASK) >> SID_MULTI_CHIP_MODE_SHIFT; +} + void bl31_platform_setup(void) { sgi_bl31_common_platform_setup(); diff --git a/plat/arm/board/sgi575/sgi575_plat.c b/plat/arm/board/sgi575/sgi575_plat.c index ab4964a7d..dc294e6a8 100644 --- a/plat/arm/board/sgi575/sgi575_plat.c +++ b/plat/arm/board/sgi575/sgi575_plat.c @@ -19,6 +19,11 @@ unsigned int plat_arm_sgi_get_config_id(void) & SSC_VERSION_CONFIG_MASK; } +unsigned int plat_arm_sgi_get_multi_chip_mode(void) +{ + return 0; +} + void bl31_platform_setup(void) { sgi_bl31_common_platform_setup(); diff --git a/plat/arm/css/sgi/include/sgi_variant.h b/plat/arm/css/sgi/include/sgi_variant.h index c75f2132b..b7a1e4a53 100644 --- a/plat/arm/css/sgi/include/sgi_variant.h +++ b/plat/arm/css/sgi/include/sgi_variant.h @@ -18,6 +18,8 @@ typedef struct sgi_platform_info { unsigned int platform_id; /* Part Number of the platform */ unsigned int config_id; /* Config Id of the platform */ + unsigned int chip_id; /* Chip Id or Node number */ + unsigned int multi_chip_mode; /* Multi-chip mode availability */ } sgi_platform_info_t; extern sgi_platform_info_t sgi_plat_info; @@ -28,4 +30,7 @@ unsigned int plat_arm_sgi_get_platform_id(void); /* returns the configuration id of the platform */ unsigned int plat_arm_sgi_get_config_id(void); +/* returns true if operating in multi-chip configuration */ +unsigned int plat_arm_sgi_get_multi_chip_mode(void); + #endif /* SGI_VARIANT_H */ diff --git a/plat/arm/css/sgi/sgi_bl31_setup.c b/plat/arm/css/sgi/sgi_bl31_setup.c index a2caf7c41..2ff66ac75 100644 --- a/plat/arm/css/sgi/sgi_bl31_setup.c +++ b/plat/arm/css/sgi/sgi_bl31_setup.c @@ -51,6 +51,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, { sgi_plat_info.platform_id = plat_arm_sgi_get_platform_id(); sgi_plat_info.config_id = plat_arm_sgi_get_config_id(); + sgi_plat_info.multi_chip_mode = plat_arm_sgi_get_multi_chip_mode(); arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3); } -- cgit v1.2.3 From e485415386534fd40e474707c7d61240ab7dde0c Mon Sep 17 00:00:00 2001 From: Vijayenthiran Subramaniam Date: Mon, 28 Oct 2019 14:49:48 +0530 Subject: plat/arm/sgi: add macros for remote chip device region Some of the Reference Design platforms like RD-N1-Edge can operate in multi-chip configuration wherein two or more SoCs are connected through a high speed coherent CCIX link. For the RD platforms, the remote chip address space is at the offset of 4TB per chip. In order for the primary chip to access the device memory region on the remote chip, the required memory region entries need to be added as mmap entry. This patch adds macros related to the remote chip device memory region. Change-Id: I833810b96f1a0e7c3c289ac32597b6ba03344c80 Signed-off-by: Vijayenthiran Subramaniam --- plat/arm/css/sgi/include/sgi_base_platform_def.h | 29 +++++++++++++++++++++++- 1 file changed, 28 insertions(+), 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 e21457304..84f8d1eab 100644 --- a/plat/arm/css/sgi/include/sgi_base_platform_def.h +++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -23,6 +23,9 @@ #define PLAT_ARM_TRUSTED_SRAM_SIZE 0x00040000 /* 256 KB */ +/* Remote chip address offset (4TB per chip) */ +#define CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) ((ULL(1) << 42) * (n)) + /* * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the * plat_arm_mmap array defined for each BL stage. @@ -129,6 +132,30 @@ CSS_SGI_DEVICE_SIZE, \ MT_DEVICE | MT_RW | MT_SECURE) +#define ARM_MAP_SHARED_RAM_REMOTE_CHIP(n) \ + MAP_REGION_FLAT( \ + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) + \ + ARM_SHARED_RAM_BASE, \ + ARM_SHARED_RAM_SIZE, \ + MT_MEMORY | MT_RW | MT_SECURE \ + ) + +#define CSS_SGI_MAP_DEVICE_REMOTE_CHIP(n) \ + MAP_REGION_FLAT( \ + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) + \ + CSS_SGI_DEVICE_BASE, \ + CSS_SGI_DEVICE_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE \ + ) + +#define SOC_CSS_MAP_DEVICE_REMOTE_CHIP(n) \ + MAP_REGION_FLAT( \ + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) + \ + SOC_CSS_DEVICE_BASE, \ + SOC_CSS_DEVICE_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE \ + ) + /* GIC related constants */ #define PLAT_ARM_GICD_BASE 0x30000000 #define PLAT_ARM_GICC_BASE 0x2C000000 -- cgit v1.2.3 From 80151c27bda3b39ccfc17dc1d25d4a18ab2840c5 Mon Sep 17 00:00:00 2001 From: Vijayenthiran Subramaniam Date: Tue, 29 Oct 2019 15:56:41 +0530 Subject: plat/arm/sgi: include AFF3 affinity in core position calculation AFF3 bits of MPIDR corresponds to Chip-Id in Arm multi-chip platforms. For calculating linear core position of CPU cores from slave chips, AFF3 bits has to be used. Update `plat_arm_calc_core_pos` assembly function to include AFF3 bits in calculation. Change-Id: I4af2bd82ab8e31e18bc61de22705a73893954260 Signed-off-by: Vijayenthiran Subramaniam --- plat/arm/css/sgi/aarch64/sgi_helper.S | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/plat/arm/css/sgi/aarch64/sgi_helper.S b/plat/arm/css/sgi/aarch64/sgi_helper.S index b80903d06..04bfb7771 100644 --- a/plat/arm/css/sgi/aarch64/sgi_helper.S +++ b/plat/arm/css/sgi/aarch64/sgi_helper.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -18,19 +18,22 @@ * unsigned int plat_arm_calc_core_pos(u_register_t mpidr) * * Helper function to calculate the core position. + * (ChipId * PLAT_ARM_CLUSTER_COUNT * + * CSS_SGI_MAX_CPUS_PER_CLUSTER * CSS_SGI_MAX_PE_PER_CPU) + * (ClusterId * CSS_SGI_MAX_CPUS_PER_CLUSTER * CSS_SGI_MAX_PE_PER_CPU) + * (CPUId * CSS_SGI_MAX_PE_PER_CPU) + * ThreadId * * which can be simplified as: * - * ((ClusterId * CSS_SGI_MAX_CPUS_PER_CLUSTER + CPUId) * - * CSS_SGI_MAX_PE_PER_CPU) + ThreadId + * ((((ChipId * PLAT_ARM_CLUSTER_COUNT) + ClusterId) * + * CSS_SGI_MAX_CPUS_PER_CLUSTER) + CPUId) * CSS_SGI_MAX_PE_PER_CPU + + * ThreadId * ------------------------------------------------------ */ func plat_arm_calc_core_pos - mov x3, x0 + mov x4, x0 /* * The MT bit in MPIDR is always set for SGI platforms @@ -38,15 +41,18 @@ func plat_arm_calc_core_pos */ /* 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 + ubfx x0, x4, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS + ubfx x1, x4, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS + ubfx x2, x4, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS + ubfx x3, x4, #MPIDR_AFF3_SHIFT, #MPIDR_AFFINITY_BITS /* Compute linear position */ + mov x4, #PLAT_ARM_CLUSTER_COUNT + madd x2, x3, x4, x2 mov x4, #CSS_SGI_MAX_CPUS_PER_CLUSTER madd x1, x2, x4, x1 - mov x5, #CSS_SGI_MAX_PE_PER_CPU - madd x0, x1, x5, x0 + mov x4, #CSS_SGI_MAX_PE_PER_CPU + madd x0, x1, x4, x0 ret endfunc plat_arm_calc_core_pos -- cgit v1.2.3 From f893160690725fe79c8eb63fd90a945cc0374d90 Mon Sep 17 00:00:00 2001 From: Aditya Angadi Date: Tue, 31 Dec 2019 10:14:32 +0530 Subject: drivers/mhu: derive doorbell base address In order to allow the MHUv2 driver to be usable with multiple MHUv2 controllers, use the base address of the controller from the platform information instead of the MHUV2_BASE_ADDR macro. Change-Id: I4dbab87b929fb0568935e6c8b339ce67937f8cd1 Signed-off-by: Aditya Angadi --- drivers/arm/css/mhu/css_mhu_doorbell.c | 10 ++++++---- include/drivers/arm/css/css_mhu_doorbell.h | 12 ++++++------ plat/arm/board/juno/include/platform_def.h | 3 +-- plat/arm/board/n1sdp/include/platform_def.h | 3 +-- plat/arm/board/rde1edge/include/platform_def.h | 3 +-- plat/arm/board/rdn1edge/include/platform_def.h | 3 +-- plat/arm/board/sgi575/include/platform_def.h | 3 +-- plat/arm/css/sgm/include/sgm_base_platform_def.h | 3 +-- plat/socionext/synquacer/include/platform_def.h | 3 +-- 9 files changed, 19 insertions(+), 24 deletions(-) diff --git a/drivers/arm/css/mhu/css_mhu_doorbell.c b/drivers/arm/css/mhu/css_mhu_doorbell.c index 885874272..c51f3b1d7 100644 --- a/drivers/arm/css/mhu/css_mhu_doorbell.c +++ b/drivers/arm/css/mhu/css_mhu_doorbell.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -20,11 +20,13 @@ void mhu_ring_doorbell(struct scmi_channel_plat_info *plat_info) void mhuv2_ring_doorbell(struct scmi_channel_plat_info *plat_info) { + uintptr_t mhuv2_base = plat_info->db_reg_addr & MHU_V2_FRAME_BASE_MASK; + /* wake receiver */ - MHU_V2_ACCESS_REQUEST(MHUV2_BASE_ADDR); + MHU_V2_ACCESS_REQUEST(mhuv2_base); /* wait for receiver to acknowledge its ready */ - while (MHU_V2_IS_ACCESS_READY(MHUV2_BASE_ADDR) == 0) + while (MHU_V2_IS_ACCESS_READY(mhuv2_base) == 0) ; MHU_RING_DOORBELL(plat_info->db_reg_addr, @@ -32,7 +34,7 @@ void mhuv2_ring_doorbell(struct scmi_channel_plat_info *plat_info) plat_info->db_preserve_mask); /* clear the access request for the receiver */ - MHU_V2_CLEAR_REQUEST(MHUV2_BASE_ADDR); + MHU_V2_CLEAR_REQUEST(mhuv2_base); return; } diff --git a/include/drivers/arm/css/css_mhu_doorbell.h b/include/drivers/arm/css/css_mhu_doorbell.h index e6f7a1bd1..88302fd7b 100644 --- a/include/drivers/arm/css/css_mhu_doorbell.h +++ b/include/drivers/arm/css/css_mhu_doorbell.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,13 +11,13 @@ #include -/* MHUv2 Base Address */ -#define MHUV2_BASE_ADDR PLAT_MHUV2_BASE +/* MHUv2 Frame Base Mask */ +#define MHU_V2_FRAME_BASE_MASK UL(~0xFFF) /* MHUv2 Control Registers Offsets */ -#define MHU_V2_MSG_NO_CAP_OFFSET 0xF80 -#define MHU_V2_ACCESS_REQ_OFFSET 0xF88 -#define MHU_V2_ACCESS_READY_OFFSET 0xF8C +#define MHU_V2_MSG_NO_CAP_OFFSET UL(0xF80) +#define MHU_V2_ACCESS_REQ_OFFSET UL(0xF88) +#define MHU_V2_ACCESS_READY_OFFSET UL(0xF8C) #define SENDER_REG_STAT(_channel) (0x20 * (_channel)) #define SENDER_REG_SET(_channel) ((0x20 * (_channel)) + 0xC) diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h index 16bb33d7e..998e0e3d2 100644 --- a/plat/arm/board/juno/include/platform_def.h +++ b/plat/arm/board/juno/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -224,7 +224,6 @@ /* MHU related constants */ #define PLAT_CSS_MHU_BASE UL(0x2b1f0000) -#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE /* * Base address of the first memory region used for communication between AP diff --git a/plat/arm/board/n1sdp/include/platform_def.h b/plat/arm/board/n1sdp/include/platform_def.h index 6a309e8e1..e8b892145 100644 --- a/plat/arm/board/n1sdp/include/platform_def.h +++ b/plat/arm/board/n1sdp/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -90,7 +90,6 @@ #define PLAT_ARM_NSTIMER_FRAME_ID 0 #define PLAT_CSS_MHU_BASE 0x45000000 -#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE #define PLAT_MAX_PWR_LVL 2 #define PLAT_ARM_G1S_IRQS ARM_G1S_IRQS, \ diff --git a/plat/arm/board/rde1edge/include/platform_def.h b/plat/arm/board/rde1edge/include/platform_def.h index 2be3f8852..abb36018c 100644 --- a/plat/arm/board/rde1edge/include/platform_def.h +++ b/plat/arm/board/rde1edge/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, Arm Limited. All rights reserved. + * Copyright (c) 2018-2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -16,7 +16,6 @@ #define CSS_SGI_MAX_PE_PER_CPU U(2) #define PLAT_CSS_MHU_BASE UL(0x45400000) -#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE /* Base address of DMC-620 instances */ #define RDE1EDGE_DMC620_BASE0 UL(0x4e000000) diff --git a/plat/arm/board/rdn1edge/include/platform_def.h b/plat/arm/board/rdn1edge/include/platform_def.h index c635faa44..a00df7d73 100644 --- a/plat/arm/board/rdn1edge/include/platform_def.h +++ b/plat/arm/board/rdn1edge/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -16,7 +16,6 @@ #define CSS_SGI_MAX_PE_PER_CPU U(1) #define PLAT_CSS_MHU_BASE UL(0x45400000) -#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE /* Base address of DMC-620 instances */ #define RDN1EDGE_DMC620_BASE0 UL(0x4e000000) diff --git a/plat/arm/board/sgi575/include/platform_def.h b/plat/arm/board/sgi575/include/platform_def.h index fd59e5277..25d24c5b0 100644 --- a/plat/arm/board/sgi575/include/platform_def.h +++ b/plat/arm/board/sgi575/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -16,7 +16,6 @@ #define CSS_SGI_MAX_PE_PER_CPU U(1) #define PLAT_CSS_MHU_BASE UL(0x45000000) -#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE /* Base address of DMC-620 instances */ #define SGI575_DMC620_BASE0 UL(0x4e000000) diff --git a/plat/arm/css/sgm/include/sgm_base_platform_def.h b/plat/arm/css/sgm/include/sgm_base_platform_def.h index 24bbed513..9cb642cfa 100644 --- a/plat/arm/css/sgm/include/sgm_base_platform_def.h +++ b/plat/arm/css/sgm/include/sgm_base_platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -86,7 +86,6 @@ /* MHU related constants */ #define PLAT_CSS_MHU_BASE 0x2b1f0000 -#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE #define PLAT_ARM_TRUSTED_ROM_BASE 0x00000000 #define PLAT_ARM_TRUSTED_ROM_SIZE 0x00080000 diff --git a/plat/socionext/synquacer/include/platform_def.h b/plat/socionext/synquacer/include/platform_def.h index 7158bfaf3..b87ac3fd6 100644 --- a/plat/socionext/synquacer/include/platform_def.h +++ b/plat/socionext/synquacer/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -80,7 +80,6 @@ #define DRAMINFO_BASE 0x2E00FFC0 #define PLAT_SQ_MHU_BASE 0x45000000 -#define PLAT_MHUV2_BASE 0xFFFFFFFF /* MHUV2 is not supported */ #define PLAT_SQ_SCP_COM_SHARED_MEM_BASE 0x45400000 #define SCPI_CMD_GET_DRAMINFO 0x1 -- cgit v1.2.3 From 31e703f99574a5a1edeadde611b031c422d5987c Mon Sep 17 00:00:00 2001 From: Aditya Angadi Date: Tue, 31 Dec 2019 14:23:53 +0530 Subject: drivers/arm/scmi: allow use of multiple SCMI channels On systems that have multiple platform components that can interpret the SCMI messages, there is a need to support multiple SCMI channels (one each to those platform components). Extend the existing SCMI interface that currently supports only a single SCMI channel to support multiple SCMI channels. Change-Id: Ice4062475b903aef3b5e5bc37df364c9778a62c5 Signed-off-by: Aditya Angadi --- drivers/arm/css/scp/css_pm_scmi.c | 140 +++++++++++++++-------- include/drivers/arm/css/scmi.h | 4 +- include/plat/arm/css/common/css_pm.h | 13 ++- plat/arm/board/juno/include/platform_def.h | 3 + plat/arm/board/juno/juno_topology.c | 4 +- plat/arm/board/n1sdp/include/platform_def.h | 3 + plat/arm/board/n1sdp/n1sdp_bl31_setup.c | 4 +- plat/arm/css/sgi/include/sgi_base_platform_def.h | 3 + plat/arm/css/sgi/sgi_bl31_setup.c | 2 +- plat/arm/css/sgm/include/sgm_base_platform_def.h | 3 + plat/arm/css/sgm/sgm_bl31_setup.c | 4 +- 11 files changed, 125 insertions(+), 58 deletions(-) diff --git a/drivers/arm/css/scp/css_pm_scmi.c b/drivers/arm/css/scp/css_pm_scmi.c index b945cda78..097d2eb2b 100644 --- a/drivers/arm/css/scp/css_pm_scmi.c +++ b/drivers/arm/css/scp/css_pm_scmi.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -63,16 +63,44 @@ typedef enum { } scmi_power_state_t; /* - * The global handle for invoking the SCMI driver APIs after the driver + * The global handles for invoking the SCMI driver APIs after the driver * has been initialized. */ -static void *scmi_handle; +static void *scmi_handles[PLAT_ARM_SCMI_CHANNEL_COUNT]; -/* The SCMI channel global object */ -static scmi_channel_t channel; +/* The global SCMI channels array */ +static scmi_channel_t scmi_channels[PLAT_ARM_SCMI_CHANNEL_COUNT]; +/* + * Channel ID for the default SCMI channel. + * The default channel is used to issue SYSTEM level SCMI requests and is + * initialized to the channel which has the boot cpu as its resource. + */ +static uint32_t default_scmi_channel_id; + +/* + * TODO: Allow use of channel specific lock instead of using a single lock for + * all the channels. + */ ARM_SCMI_INSTANTIATE_LOCK; +/* + * Function to obtain the SCMI Domain ID and SCMI Channel number from the linear + * core position. The SCMI Channel number is encoded in the upper 16 bits and + * the Domain ID is encoded in the lower 16 bits in each entry of the mapping + * array exported by the platform. + */ +static void css_scp_core_pos_to_scmi_channel(unsigned int core_pos, + unsigned int *scmi_domain_id, unsigned int *scmi_channel_id) +{ + unsigned int composite_id; + + composite_id = plat_css_core_pos_to_scmi_dmn_id_map[core_pos]; + + *scmi_channel_id = GET_SCMI_CHANNEL_ID(composite_id); + *scmi_domain_id = GET_SCMI_DOMAIN_ID(composite_id); +} + /* * Helper function to suspend a CPU power domain and its parent power domains * if applicable. @@ -87,10 +115,10 @@ void css_scp_suspend(const struct psci_power_state *target_state) /* Check if power down at system power domain level is requested */ if (css_system_pwr_state(target_state) == ARM_LOCAL_STATE_OFF) { - /* Issue SCMI command for SYSTEM_SUSPEND */ - ret = scmi_sys_pwr_state_set(scmi_handle, - SCMI_SYS_PWR_FORCEFUL_REQ, - SCMI_SYS_PWR_SUSPEND); + /* Issue SCMI command for SYSTEM_SUSPEND on all SCMI channels */ + ret = scmi_sys_pwr_state_set( + scmi_handles[default_scmi_channel_id], + SCMI_SYS_PWR_FORCEFUL_REQ, SCMI_SYS_PWR_SUSPEND); if (ret != SCMI_E_SUCCESS) { ERROR("SCMI system power domain suspend return 0x%x unexpected\n", ret); @@ -99,7 +127,7 @@ void css_scp_suspend(const struct psci_power_state *target_state) return; } #if !HW_ASSISTED_COHERENCY - unsigned int lvl; + unsigned int lvl, channel_id, domain_id; uint32_t scmi_pwr_state = 0; /* * If we reach here, then assert that power down at system power domain @@ -127,9 +155,10 @@ void css_scp_suspend(const struct psci_power_state *target_state) SCMI_SET_PWR_STATE_MAX_PWR_LVL(scmi_pwr_state, lvl - 1); - ret = scmi_pwr_state_set(scmi_handle, - plat_css_core_pos_to_scmi_dmn_id_map[plat_my_core_pos()], - scmi_pwr_state); + css_scp_core_pos_to_scmi_channel(plat_my_core_pos(), + &domain_id, &channel_id); + ret = scmi_pwr_state_set(scmi_handles[channel_id], + domain_id, scmi_pwr_state); if (ret != SCMI_E_SUCCESS) { ERROR("SCMI set power state command return 0x%x unexpected\n", @@ -145,7 +174,7 @@ void css_scp_suspend(const struct psci_power_state *target_state) */ void css_scp_off(const struct psci_power_state *target_state) { - unsigned int lvl = 0; + unsigned int lvl = 0, channel_id, domain_id; int ret; uint32_t scmi_pwr_state = 0; @@ -168,10 +197,10 @@ void css_scp_off(const struct psci_power_state *target_state) SCMI_SET_PWR_STATE_MAX_PWR_LVL(scmi_pwr_state, lvl - 1); - ret = scmi_pwr_state_set(scmi_handle, - plat_css_core_pos_to_scmi_dmn_id_map[plat_my_core_pos()], - scmi_pwr_state); - + css_scp_core_pos_to_scmi_channel(plat_my_core_pos(), + &domain_id, &channel_id); + ret = scmi_pwr_state_set(scmi_handles[channel_id], + domain_id, scmi_pwr_state); if (ret != SCMI_E_QUEUED && ret != SCMI_E_SUCCESS) { ERROR("SCMI set power state command return 0x%x unexpected\n", ret); @@ -185,8 +214,8 @@ void css_scp_off(const struct psci_power_state *target_state) */ void css_scp_on(u_register_t mpidr) { - unsigned int lvl = 0; - int core_pos, ret; + unsigned int lvl = 0, channel_id, core_pos, domain_id; + int ret; uint32_t scmi_pwr_state = 0; for (; lvl <= PLAT_MAX_PWR_LVL; lvl++) @@ -196,13 +225,12 @@ void css_scp_on(u_register_t mpidr) SCMI_SET_PWR_STATE_MAX_PWR_LVL(scmi_pwr_state, lvl - 1); core_pos = plat_core_pos_by_mpidr(mpidr); - assert((core_pos >= 0) && - (((unsigned int)core_pos) < PLATFORM_CORE_COUNT)); - - ret = scmi_pwr_state_set(scmi_handle, - plat_css_core_pos_to_scmi_dmn_id_map[core_pos], - scmi_pwr_state); + assert(core_pos >= 0 && (core_pos < PLATFORM_CORE_COUNT)); + css_scp_core_pos_to_scmi_channel(core_pos, &domain_id, + &channel_id); + ret = scmi_pwr_state_set(scmi_handles[channel_id], + domain_id, scmi_pwr_state); if (ret != SCMI_E_QUEUED && ret != SCMI_E_SUCCESS) { ERROR("SCMI set power state command return 0x%x unexpected\n", ret); @@ -216,8 +244,9 @@ void css_scp_on(u_register_t mpidr) */ int css_scp_get_power_state(u_register_t mpidr, unsigned int power_level) { - int ret, cpu_idx; + int ret; uint32_t scmi_pwr_state = 0, lvl_state; + unsigned int channel_id, cpu_idx, domain_id; /* We don't support get power state at the system power domain level */ if ((power_level > PLAT_MAX_PWR_LVL) || @@ -230,9 +259,9 @@ int css_scp_get_power_state(u_register_t mpidr, unsigned int power_level) cpu_idx = plat_core_pos_by_mpidr(mpidr); assert(cpu_idx > -1); - ret = scmi_pwr_state_get(scmi_handle, - plat_css_core_pos_to_scmi_dmn_id_map[cpu_idx], - &scmi_pwr_state); + css_scp_core_pos_to_scmi_channel(cpu_idx, &domain_id, &channel_id); + ret = scmi_pwr_state_get(scmi_handles[channel_id], + domain_id, &scmi_pwr_state); if (ret != SCMI_E_SUCCESS) { WARN("SCMI get power state command return 0x%x unexpected\n", @@ -271,7 +300,7 @@ void __dead2 css_scp_system_off(int state) * Issue SCMI command. First issue a graceful * request and if that fails force the request. */ - ret = scmi_sys_pwr_state_set(scmi_handle, + ret = scmi_sys_pwr_state_set(scmi_handles[default_scmi_channel_id], SCMI_SYS_PWR_FORCEFUL_REQ, state); @@ -325,17 +354,28 @@ static int scmi_ap_core_init(scmi_channel_t *ch) void __init plat_arm_pwrc_setup(void) { - channel.info = plat_css_get_scmi_info(); - channel.lock = ARM_SCMI_LOCK_GET_INSTANCE; - scmi_handle = scmi_init(&channel); - if (scmi_handle == NULL) { - ERROR("SCMI Initialization failed\n"); - panic(); - } - if (scmi_ap_core_init(&channel) < 0) { - ERROR("SCMI AP core protocol initialization failed\n"); - panic(); + unsigned int composite_id, idx; + + for (idx = 0; idx < PLAT_ARM_SCMI_CHANNEL_COUNT; idx++) { + INFO("Initializing 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; + scmi_handles[idx] = scmi_init(&scmi_channels[idx]); + + if (scmi_handles[idx] == NULL) { + ERROR("SCMI Initialization failed on channel %d\n", idx); + panic(); + } + + if (scmi_ap_core_init(&scmi_channels[idx]) < 0) { + ERROR("SCMI AP core protocol initialization failed\n"); + panic(); + } } + + composite_id = plat_css_core_pos_to_scmi_dmn_id_map[plat_my_core_pos()]; + default_scmi_channel_id = GET_SCMI_CHANNEL_ID(composite_id); } /****************************************************************************** @@ -347,6 +387,7 @@ const plat_psci_ops_t *css_scmi_override_pm_ops(plat_psci_ops_t *ops) { uint32_t msg_attr; int ret; + void *scmi_handle = scmi_handles[default_scmi_channel_id]; assert(scmi_handle); @@ -411,14 +452,17 @@ int css_system_reset2(int is_vendor, int reset_type, u_register_t cookie) #if PROGRAMMABLE_RESET_ADDRESS void plat_arm_program_trusted_mailbox(uintptr_t address) { - int ret; + int ret, i; - assert(scmi_handle); - ret = scmi_ap_core_set_reset_addr(scmi_handle, address, - SCMI_AP_CORE_LOCK_ATTR); - if (ret != SCMI_E_SUCCESS) { - ERROR("CSS: Failed to program reset address: %d\n", ret); - panic(); + for (i = 0; i < PLAT_ARM_SCMI_CHANNEL_COUNT; i++) { + assert(scmi_handles[i]); + + ret = scmi_ap_core_set_reset_addr(scmi_handles[i], address, + SCMI_AP_CORE_LOCK_ATTR); + if (ret != SCMI_E_SUCCESS) { + ERROR("CSS: Failed to program reset address: %d\n", ret); + panic(); + } } } #endif diff --git a/include/drivers/arm/css/scmi.h b/include/drivers/arm/css/scmi.h index 1f8dc6cce..e8a2863a9 100644 --- a/include/drivers/arm/css/scmi.h +++ b/include/drivers/arm/css/scmi.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -162,7 +162,7 @@ int scmi_ap_core_set_reset_addr(void *p, uint64_t reset_addr, uint32_t attr); int scmi_ap_core_get_reset_addr(void *p, uint64_t *reset_addr, uint32_t *attr); /* API to get the platform specific SCMI channel information. */ -scmi_channel_plat_info_t *plat_css_get_scmi_info(void); +scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id); /* API to override default PSCI callbacks for platforms that support SCMI. */ const plat_psci_ops_t *css_scmi_override_pm_ops(plat_psci_ops_t *ops); diff --git a/include/plat/arm/css/common/css_pm.h b/include/plat/arm/css/common/css_pm.h index 93f86162e..e5357f50b 100644 --- a/include/plat/arm/css/common/css_pm.h +++ b/include/plat/arm/css/common/css_pm.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -44,4 +44,15 @@ int css_node_hw_state(u_register_t mpidr, unsigned int power_level); */ extern const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[]; +#define SCMI_DOMAIN_ID_MASK U(0xFFFF) +#define SCMI_CHANNEL_ID_MASK U(0xFFFF) +#define SCMI_CHANNEL_ID_SHIFT U(16) + +#define SET_SCMI_CHANNEL_ID(n) (((n) & SCMI_CHANNEL_ID_MASK) << \ + SCMI_CHANNEL_ID_SHIFT) +#define SET_SCMI_DOMAIN_ID(n) ((n) & SCMI_DOMAIN_ID_MASK) +#define GET_SCMI_CHANNEL_ID(n) (((n) >> SCMI_CHANNEL_ID_SHIFT) & \ + SCMI_CHANNEL_ID_MASK) +#define GET_SCMI_DOMAIN_ID(n) ((n) & SCMI_DOMAIN_ID_MASK) + #endif /* CSS_PM_H */ diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h index 998e0e3d2..eddd7e570 100644 --- a/plat/arm/board/juno/include/platform_def.h +++ b/plat/arm/board/juno/include/platform_def.h @@ -300,4 +300,7 @@ #define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) #endif +/* Number of SCMI channels on the platform */ +#define PLAT_ARM_SCMI_CHANNEL_COUNT U(1) + #endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/juno/juno_topology.c b/plat/arm/board/juno/juno_topology.c index 052ab9f8a..075f512c3 100644 --- a/plat/arm/board/juno/juno_topology.c +++ b/plat/arm/board/juno/juno_topology.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -20,7 +20,7 @@ static scmi_channel_plat_info_t juno_scmi_plat_info = { .ring_doorbell = &mhu_ring_doorbell, }; -scmi_channel_plat_info_t *plat_css_get_scmi_info(void) +scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id) { return &juno_scmi_plat_info; } diff --git a/plat/arm/board/n1sdp/include/platform_def.h b/plat/arm/board/n1sdp/include/platform_def.h index e8b892145..cc07852c2 100644 --- a/plat/arm/board/n1sdp/include/platform_def.h +++ b/plat/arm/board/n1sdp/include/platform_def.h @@ -143,4 +143,7 @@ #define SBSA_SECURE_WDOG_BASE UL(0x2A480000) #define SBSA_SECURE_WDOG_TIMEOUT UL(100) +/* Number of SCMI channels on the platform */ +#define PLAT_ARM_SCMI_CHANNEL_COUNT U(1) + #endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c index b150b8959..136287a8d 100644 --- a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c +++ b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -74,7 +74,7 @@ static uintptr_t n1sdp_multichip_gicr_frames[3] = { 0 }; -scmi_channel_plat_info_t *plat_css_get_scmi_info() +scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id) { return &n1sdp_scmi_plat_info; } 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 84f8d1eab..cc5ead844 100644 --- a/plat/arm/css/sgi/include/sgi_base_platform_def.h +++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h @@ -239,4 +239,7 @@ #define SBSA_SECURE_WDOG_BASE UL(0x2A480000) #define SBSA_SECURE_WDOG_TIMEOUT UL(100) +/* Number of SCMI channels on the platform */ +#define PLAT_ARM_SCMI_CHANNEL_COUNT CSS_SGI_CHIP_COUNT + #endif /* SGI_BASE_PLATFORM_DEF_H */ diff --git a/plat/arm/css/sgi/sgi_bl31_setup.c b/plat/arm/css/sgi/sgi_bl31_setup.c index 2ff66ac75..3d2d933af 100644 --- a/plat/arm/css/sgi/sgi_bl31_setup.c +++ b/plat/arm/css/sgi/sgi_bl31_setup.c @@ -36,7 +36,7 @@ static scmi_channel_plat_info_t rd_n1e1_edge_scmi_plat_info = { .ring_doorbell = &mhuv2_ring_doorbell, }; -scmi_channel_plat_info_t *plat_css_get_scmi_info(void) +scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id) { if (sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM) return &rd_n1e1_edge_scmi_plat_info; diff --git a/plat/arm/css/sgm/include/sgm_base_platform_def.h b/plat/arm/css/sgm/include/sgm_base_platform_def.h index 9cb642cfa..90511ac6a 100644 --- a/plat/arm/css/sgm/include/sgm_base_platform_def.h +++ b/plat/arm/css/sgm/include/sgm_base_platform_def.h @@ -238,4 +238,7 @@ /* System power domain level */ #define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL2 +/* Number of SCMI channels on the platform */ +#define PLAT_ARM_SCMI_CHANNEL_COUNT U(1) + #endif /* SGM_BASE_PLATFORM_DEF_H */ diff --git a/plat/arm/css/sgm/sgm_bl31_setup.c b/plat/arm/css/sgm/sgm_bl31_setup.c index 7e92ac835..907e9fdac 100644 --- a/plat/arm/css/sgm/sgm_bl31_setup.c +++ b/plat/arm/css/sgm/sgm_bl31_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -20,7 +20,7 @@ static scmi_channel_plat_info_t sgm775_scmi_plat_info = { .ring_doorbell = &mhu_ring_doorbell, }; -scmi_channel_plat_info_t *plat_css_get_scmi_info() +scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id) { return &sgm775_scmi_plat_info; } -- cgit v1.2.3 From 2d4b719cc6f79312f32515fb2aa5304ca155eceb Mon Sep 17 00:00:00 2001 From: Vijayenthiran Subramaniam Date: Mon, 28 Oct 2019 14:49:48 +0530 Subject: board/rdn1edge: add support for dual-chip configuration RD-N1-Edge based platforms can operate in dual-chip configuration wherein two rdn1edge SoCs are connected through a high speed coherent CCIX link. This patch adds a function to check if the RD-N1-Edge platform is operating in multi-chip mode by reading the SID register's NODE_ID value. If operating in multi-chip mode, initialize GIC-600 multi-chip operation by overriding the default GICR frames with array of GICR frames and setting the chip 0 as routing table owner. The address space of the second RD-N1-Edge chip (chip 1) starts from the address 4TB. So increase the physical and virtual address space size to 43 bits to accommodate the multi-chip configuration. If the multi-chip mode configuration is detected, dynamically add mmap entry for the peripherals memory region of the second RD-N1-Edge SoC. This is required to let the BL31 platform setup stage to configure the devices in the second chip. PLATFORM_CORE_COUNT macro is set to be multiple of CSS_SGI_CHIP_COUNT and topology changes are added to represent the dual-chip configuration. In order the build the dual-chip platform, CSS_SGI_CHIP_COUNT macro should be set to 2: export CROSS_COMPILE= make PLAT=rdn1edge CSS_SGI_CHIP_COUNT=2 ARCH=aarch64 all Change-Id: I576cdaf71f0b0e41b9a9181fa4feb7091f8c7bb4 Signed-off-by: Aditya Angadi Signed-off-by: Vijayenthiran Subramaniam --- plat/arm/board/rdn1edge/include/platform_def.h | 7 ++- plat/arm/board/rdn1edge/platform.mk | 10 ++-- plat/arm/board/rdn1edge/rdn1edge_plat.c | 67 ++++++++++++++++++++++++ plat/arm/board/rdn1edge/rdn1edge_topology.c | 26 ++++++++- plat/arm/css/sgi/include/sgi_base_platform_def.h | 9 ++-- plat/arm/css/sgi/sgi_bl31_setup.c | 44 ++++++++++++++-- 6 files changed, 149 insertions(+), 14 deletions(-) diff --git a/plat/arm/board/rdn1edge/include/platform_def.h b/plat/arm/board/rdn1edge/include/platform_def.h index a00df7d73..46555f248 100644 --- a/plat/arm/board/rdn1edge/include/platform_def.h +++ b/plat/arm/board/rdn1edge/include/platform_def.h @@ -26,12 +26,15 @@ #define PLAT_MAX_PWR_LVL ARM_PWR_LVL1 +/* Virtual address used by dynamic mem_protect for chunk_base */ +#define PLAT_ARM_MEM_PROTEC_VA_FRAME UL(0xc0000000) + /* * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes */ #ifdef __aarch64__ -#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 36) -#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 36) +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 43) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 43) #else #define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) #define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) diff --git a/plat/arm/board/rdn1edge/platform.mk b/plat/arm/board/rdn1edge/platform.mk index 90e933850..04f70f3f2 100644 --- a/plat/arm/board/rdn1edge/platform.mk +++ b/plat/arm/board/rdn1edge/platform.mk @@ -26,6 +26,7 @@ BL31_SOURCES += ${SGI_CPU_SOURCES} \ ${RDN1EDGE_BASE}/rdn1edge_plat.c \ ${RDN1EDGE_BASE}/rdn1edge_topology.c \ drivers/cfi/v2m/v2m_flash.c \ + drivers/arm/gic/v3/gic600_multichip.c \ lib/utils/mem_region.c \ plat/arm/common/arm_nor_psci_mem_protect.c @@ -34,6 +35,9 @@ BL1_SOURCES += ${RDN1EDGE_BASE}/rdn1edge_trusted_boot.c BL2_SOURCES += ${RDN1EDGE_BASE}/rdn1edge_trusted_boot.c endif +# Enable dynamic addition of MMAP regions in BL31 +BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 + # Add the FDT_SOURCES and options for Dynamic Config FDT_SOURCES += ${RDN1EDGE_BASE}/fdts/${PLAT}_tb_fw_config.dts TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb @@ -47,9 +51,9 @@ NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb # Add the NT_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config)) -ifneq ($(CSS_SGI_CHIP_COUNT),1) - $(error "Chip count for RDN1Edge should be 1, currently set to \ - ${CSS_SGI_CHIP_COUNT}.") +ifneq ($(CSS_SGI_CHIP_COUNT),$(filter $(CSS_SGI_CHIP_COUNT),1 2)) + $(error "Chip count for RDN1Edge platform should either 1 or 2, currently \ + set to ${CSS_SGI_CHIP_COUNT}.") endif override CTX_INCLUDE_AARCH32_REGS := 0 diff --git a/plat/arm/board/rdn1edge/rdn1edge_plat.c b/plat/arm/board/rdn1edge/rdn1edge_plat.c index f7c7e9b5c..f62c6f402 100644 --- a/plat/arm/board/rdn1edge/rdn1edge_plat.c +++ b/plat/arm/board/rdn1edge/rdn1edge_plat.c @@ -4,9 +4,42 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include +#include +#include #include +#include #include +#if defined(IMAGE_BL31) +static const mmap_region_t rdn1edge_dynamic_mmap[] = { + ARM_MAP_SHARED_RAM_REMOTE_CHIP(1), + CSS_SGI_MAP_DEVICE_REMOTE_CHIP(1), + SOC_CSS_MAP_DEVICE_REMOTE_CHIP(1) +}; + +static struct gic600_multichip_data rdn1e1_multichip_data __init = { + .rt_owner_base = PLAT_ARM_GICD_BASE, + .rt_owner = 0, + .chip_count = CSS_SGI_CHIP_COUNT, + .chip_addrs = { + PLAT_ARM_GICD_BASE >> 16, + (PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1)) >> 16 + }, + .spi_ids = { + {32, 255}, + {0, 0} + } +}; + +static uintptr_t rdn1e1_multichip_gicr_frames[] = { + PLAT_ARM_GICR_BASE, /* Chip 0's GICR Base */ + PLAT_ARM_GICR_BASE + + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1), /* Chip 1's GICR BASE */ + UL(0) /* Zero Termination */ +}; +#endif /* IMAGE_BL31 */ + unsigned int plat_arm_sgi_get_platform_id(void) { return mmio_read_32(SID_REG_BASE + SID_SYSTEM_ID_OFFSET) @@ -24,7 +57,41 @@ unsigned int plat_arm_sgi_get_multi_chip_mode(void) SID_MULTI_CHIP_MODE_MASK) >> SID_MULTI_CHIP_MODE_SHIFT; } +/* + * IMAGE_BL31 macro is added to build bl31_platform_setup function only for BL31 + * because PLAT_XLAT_TABLES_DYNAMIC macro is set to build only for BL31 and not + * for other stages. + */ +#if defined(IMAGE_BL31) void bl31_platform_setup(void) { + int i, ret; + + if (plat_arm_sgi_get_multi_chip_mode() == 0 && CSS_SGI_CHIP_COUNT > 1) { + ERROR("Chip Count is set to %d but multi-chip mode not enabled\n", + CSS_SGI_CHIP_COUNT); + panic(); + } else if (plat_arm_sgi_get_multi_chip_mode() == 1 && + CSS_SGI_CHIP_COUNT > 1) { + INFO("Enabling support for multi-chip in RD-N1-Edge\n"); + + for (i = 0; i < ARRAY_SIZE(rdn1edge_dynamic_mmap); i++) { + ret = mmap_add_dynamic_region( + rdn1edge_dynamic_mmap[i].base_pa, + rdn1edge_dynamic_mmap[i].base_va, + rdn1edge_dynamic_mmap[i].size, + rdn1edge_dynamic_mmap[i].attr + ); + if (ret != 0) { + ERROR("Failed to add dynamic mmap entry\n"); + panic(); + } + } + + plat_arm_override_gicr_frames(rdn1e1_multichip_gicr_frames); + gic600_multichip_init(&rdn1e1_multichip_data); + } + sgi_bl31_common_platform_setup(); } +#endif /* IMAGE_BL31 */ diff --git a/plat/arm/board/rdn1edge/rdn1edge_topology.c b/plat/arm/board/rdn1edge/rdn1edge_topology.c index 687ae3595..5bbea6998 100644 --- a/plat/arm/board/rdn1edge/rdn1edge_topology.c +++ b/plat/arm/board/rdn1edge/rdn1edge_topology.c @@ -5,14 +5,19 @@ */ #include +#include /****************************************************************************** * The power domain tree descriptor. ******************************************************************************/ static const unsigned char rdn1edge_pd_tree_desc[] = { - PLAT_ARM_CLUSTER_COUNT, + (PLAT_ARM_CLUSTER_COUNT) * (CSS_SGI_CHIP_COUNT), + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, +#if (CSS_SGI_CHIP_COUNT > 1) CSS_SGI_MAX_CPUS_PER_CLUSTER, CSS_SGI_MAX_CPUS_PER_CLUSTER +#endif }; /******************************************************************************* @@ -28,5 +33,22 @@ const unsigned char *plat_get_power_domain_tree_desc(void) * to the SCMI power domain ID implemented by SCP. ******************************************************************************/ const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = { - 0, 1, 2, 3, 4, 5, 6, 7 + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x0)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x1)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x2)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x3)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x4)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x5)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x6)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x7)), +#if (CSS_SGI_CHIP_COUNT > 1) + (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x0)), + (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x1)), + (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x2)), + (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x3)), + (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x4)), + (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x5)), + (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x6)), + (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x7)), +#endif }; 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 cc5ead844..7eb3d3c6d 100644 --- a/plat/arm/css/sgi/include/sgi_base_platform_def.h +++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h @@ -17,8 +17,9 @@ #include #include -#define PLATFORM_CORE_COUNT (PLAT_ARM_CLUSTER_COUNT * \ - CSS_SGI_MAX_CPUS_PER_CLUSTER * \ +#define PLATFORM_CORE_COUNT (CSS_SGI_CHIP_COUNT * \ + PLAT_ARM_CLUSTER_COUNT * \ + CSS_SGI_MAX_CPUS_PER_CLUSTER * \ CSS_SGI_MAX_PE_PER_CPU) #define PLAT_ARM_TRUSTED_SRAM_SIZE 0x00040000 /* 256 KB */ @@ -38,14 +39,14 @@ # define PLAT_SP_IMAGE_MAX_XLAT_TABLES 10 # else # define PLAT_ARM_MMAP_ENTRIES 8 -# define MAX_XLAT_TABLES 5 +# define MAX_XLAT_TABLES 8 # endif #elif defined(IMAGE_BL32) # define PLAT_ARM_MMAP_ENTRIES 8 # define MAX_XLAT_TABLES 5 #elif !USE_ROMLIB # define PLAT_ARM_MMAP_ENTRIES 11 -# define MAX_XLAT_TABLES 5 +# define MAX_XLAT_TABLES 7 #else # define PLAT_ARM_MMAP_ENTRIES 12 # define MAX_XLAT_TABLES 6 diff --git a/plat/arm/css/sgi/sgi_bl31_setup.c b/plat/arm/css/sgi/sgi_bl31_setup.c index 3d2d933af..f5d0f417c 100644 --- a/plat/arm/css/sgi/sgi_bl31_setup.c +++ b/plat/arm/css/sgi/sgi_bl31_setup.c @@ -28,18 +28,56 @@ static scmi_channel_plat_info_t sgi575_scmi_plat_info = { .ring_doorbell = &mhu_ring_doorbell, }; -static scmi_channel_plat_info_t rd_n1e1_edge_scmi_plat_info = { +static scmi_channel_plat_info_t rd_n1e1_edge_scmi_plat_info[] = { + { .scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE, .db_reg_addr = PLAT_CSS_MHU_BASE + SENDER_REG_SET(0), .db_preserve_mask = 0xfffffffe, .db_modify_mask = 0x1, .ring_doorbell = &mhuv2_ring_doorbell, + }, + #if (CSS_SGI_CHIP_COUNT > 1) + { + .scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE + + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1), + .db_reg_addr = PLAT_CSS_MHU_BASE + + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1) + SENDER_REG_SET(0), + .db_preserve_mask = 0xfffffffe, + .db_modify_mask = 0x1, + .ring_doorbell = &mhuv2_ring_doorbell, + }, + #endif + #if (CSS_SGI_CHIP_COUNT > 2) + { + .scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE + + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(2), + .db_reg_addr = PLAT_CSS_MHU_BASE + + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(2) + SENDER_REG_SET(0), + .db_preserve_mask = 0xfffffffe, + .db_modify_mask = 0x1, + .ring_doorbell = &mhuv2_ring_doorbell, + }, + #endif + #if (CSS_SGI_CHIP_COUNT > 3) + { + .scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE + + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(3), + .db_reg_addr = PLAT_CSS_MHU_BASE + + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(3) + SENDER_REG_SET(0), + .db_preserve_mask = 0xfffffffe, + .db_modify_mask = 0x1, + .ring_doorbell = &mhuv2_ring_doorbell, + }, + #endif }; scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id) { - if (sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM) - return &rd_n1e1_edge_scmi_plat_info; + if (sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM) { + if (channel_id >= sizeof(rd_n1e1_edge_scmi_plat_info)) + panic(); + return &rd_n1e1_edge_scmi_plat_info[channel_id]; + } else if (sgi_plat_info.platform_id == SGI575_SSC_VER_PART_NUM) return &sgi575_scmi_plat_info; else -- cgit v1.2.3 From 2bd5dcb91dd247635500c5d3b9ae6e43cb89caa4 Mon Sep 17 00:00:00 2001 From: Vijayenthiran Subramaniam Date: Wed, 30 Oct 2019 12:52:25 +0530 Subject: platform/arm/sgi: add multi-chip mode parameter in HW_CONFIG dts Include multi-chip-mode parameter in HW_CONFIG dts to let next stage of boot firmware know about the multi-chip operation mode. Change-Id: Ic7535c2280fd57180ad14aa0ae277cf0c4d1337b Signed-off-by: Vijayenthiran Subramaniam --- plat/arm/board/rde1edge/fdts/rde1edge_nt_fw_config.dts | 3 ++- plat/arm/board/rdn1edge/fdts/rdn1edge_nt_fw_config.dts | 3 ++- plat/arm/board/sgi575/fdts/sgi575_nt_fw_config.dts | 3 ++- plat/arm/css/sgi/sgi_image_load.c | 9 ++++++++- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/plat/arm/board/rde1edge/fdts/rde1edge_nt_fw_config.dts b/plat/arm/board/rde1edge/fdts/rde1edge_nt_fw_config.dts index 41769217a..0af821e15 100644 --- a/plat/arm/board/rde1edge/fdts/rde1edge_nt_fw_config.dts +++ b/plat/arm/board/rde1edge/fdts/rde1edge_nt_fw_config.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, Arm Limited. All rights reserved. + * Copyright (c) 2018-2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -17,6 +17,7 @@ system-id { platform-id = <0x0>; config-id = <0x0>; + multi-chip-mode = <0x0>; }; }; diff --git a/plat/arm/board/rdn1edge/fdts/rdn1edge_nt_fw_config.dts b/plat/arm/board/rdn1edge/fdts/rdn1edge_nt_fw_config.dts index fff587476..68366c5ca 100644 --- a/plat/arm/board/rdn1edge/fdts/rdn1edge_nt_fw_config.dts +++ b/plat/arm/board/rdn1edge/fdts/rdn1edge_nt_fw_config.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -17,5 +17,6 @@ system-id { platform-id = <0x0>; config-id = <0x0>; + multi-chip-mode = <0x0>; }; }; diff --git a/plat/arm/board/sgi575/fdts/sgi575_nt_fw_config.dts b/plat/arm/board/sgi575/fdts/sgi575_nt_fw_config.dts index 1e1ea14b0..260247a0d 100644 --- a/plat/arm/board/sgi575/fdts/sgi575_nt_fw_config.dts +++ b/plat/arm/board/sgi575/fdts/sgi575_nt_fw_config.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -17,5 +17,6 @@ system-id { platform-id = <0x0>; config-id = <0x0>; + multi-chip-mode = <0x0>; }; }; diff --git a/plat/arm/css/sgi/sgi_image_load.c b/plat/arm/css/sgi/sgi_image_load.c index a2f10dcc7..09f3b728d 100644 --- a/plat/arm/css/sgi/sgi_image_load.c +++ b/plat/arm/css/sgi/sgi_image_load.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -62,6 +62,13 @@ static int plat_sgi_append_config_node(void) return -1; } + platcfg = plat_arm_sgi_get_multi_chip_mode(); + err = fdt_setprop_u32(fdt, nodeoffset, "multi-chip-mode", platcfg); + if (err < 0) { + ERROR("Failed to set multi-chip-mode\n"); + return -1; + } + flush_dcache_range((uintptr_t)fdt, mem_params->image_info.image_size); return 0; -- cgit v1.2.3 From 4d37aa76fdc53095f27b455f486013bdde10e0af Mon Sep 17 00:00:00 2001 From: Vijayenthiran Subramaniam Date: Thu, 26 Dec 2019 17:45:58 +0530 Subject: plat/arm/sgi: introduce number of chips macro Introduce macro 'CSS_SGI_CHIP_COUNT' to allow Arm CSS platforms with multi-chip support to define number of chiplets on the platform. By default, this flag is set to 1 and does not affect the existing single chip platforms. For multi-chip platforms, override the default value of CSS_SGI_CHIP_COUNT with the number of chiplets supported on the platform. As an example, the command below sets the number of chiplets to two on the RD-N1-Edge multi-chip platform: export CROSS_COMPILE= make PLAT=rdn1edge CSS_SGI_CHIP_COUNT=2 ARCH=aarch64 all Change-Id: If364dc36bd34b30cc356f74b3e97633933e6c8ee Signed-off-by: Vijayenthiran Subramaniam --- docs/plat/arm/arm-build-options.rst | 5 +++++ plat/arm/board/rde1edge/platform.mk | 5 +++++ plat/arm/board/rdn1edge/platform.mk | 5 +++++ plat/arm/board/sgi575/platform.mk | 5 +++++ plat/arm/css/sgi/sgi-common.mk | 4 ++++ 5 files changed, 24 insertions(+) diff --git a/docs/plat/arm/arm-build-options.rst b/docs/plat/arm/arm-build-options.rst index a6f3796b9..9622de65d 100644 --- a/docs/plat/arm/arm-build-options.rst +++ b/docs/plat/arm/arm-build-options.rst @@ -114,6 +114,11 @@ Arm CSS Platform-Specific Build Options management operations and for SCP RAM Firmware transfer. If this option is set to 1, then SCMI/SDS drivers will be used. Default is 0. + - ``CSS_SGI_CHIP_COUNT``: Configures the number of chips on a SGI/RD platform + which supports multi-chip operation. If ``CSS_SGI_CHIP_COUNT`` is set to any + valid value greater than 1, the platform code performs required configuration + to support multi-chip operation. + -------------- *Copyright (c) 2019-2020, Arm Limited. All rights reserved.* diff --git a/plat/arm/board/rde1edge/platform.mk b/plat/arm/board/rde1edge/platform.mk index 13a3de3de..88aa634b8 100644 --- a/plat/arm/board/rde1edge/platform.mk +++ b/plat/arm/board/rde1edge/platform.mk @@ -47,4 +47,9 @@ NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb # Add the NT_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config)) +ifneq ($(CSS_SGI_CHIP_COUNT),1) + $(error "Chip count for RDE1Edge should be 1, currently set to \ + ${CSS_SGI_CHIP_COUNT}.") +endif + override CTX_INCLUDE_AARCH32_REGS := 0 diff --git a/plat/arm/board/rdn1edge/platform.mk b/plat/arm/board/rdn1edge/platform.mk index 84a21b9b6..90e933850 100644 --- a/plat/arm/board/rdn1edge/platform.mk +++ b/plat/arm/board/rdn1edge/platform.mk @@ -47,4 +47,9 @@ NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb # Add the NT_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config)) +ifneq ($(CSS_SGI_CHIP_COUNT),1) + $(error "Chip count for RDN1Edge should be 1, currently set to \ + ${CSS_SGI_CHIP_COUNT}.") +endif + override CTX_INCLUDE_AARCH32_REGS := 0 diff --git a/plat/arm/board/sgi575/platform.mk b/plat/arm/board/sgi575/platform.mk index c6b2d41f6..76cc4e2c2 100644 --- a/plat/arm/board/sgi575/platform.mk +++ b/plat/arm/board/sgi575/platform.mk @@ -46,3 +46,8 @@ NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb # Add the NT_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config)) + +ifneq ($(CSS_SGI_CHIP_COUNT),1) + $(error "Chip count for SGI575 should be 1, currently set to \ + ${CSS_SGI_CHIP_COUNT}.") +endif diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/css/sgi/sgi-common.mk index 71601118f..40a7fd8a3 100644 --- a/plat/arm/css/sgi/sgi-common.mk +++ b/plat/arm/css/sgi/sgi-common.mk @@ -16,6 +16,8 @@ EL3_EXCEPTION_HANDLING := 0 HANDLE_EA_EL3_FIRST := 0 +CSS_SGI_CHIP_COUNT := 1 + INTERCONNECT_SOURCES := ${CSS_ENT_BASE}/sgi_interconnect.c PLAT_INCLUDES += -I${CSS_ENT_BASE}/include @@ -52,6 +54,8 @@ endif $(eval $(call add_define,SGI_PLAT)) +$(eval $(call add_define,CSS_SGI_CHIP_COUNT)) + override CSS_LOAD_SCP_IMAGES := 0 override NEED_BL2U := no override ARM_BL31_IN_DRAM := 1 -- cgit v1.2.3 From fe2293df83641d1b14d1df1ab7cb60ab4a19bfc7 Mon Sep 17 00:00:00 2001 From: Vijayenthiran Subramaniam Date: Mon, 3 Feb 2020 12:14:01 +0530 Subject: plat/arm/sgi: move GIC related constants to board files In preparation for adding support for Reference Design platforms which have different base addresses for GIC Distributor or Redistributor, move GIC related base addresses to individual platform definition files. Change-Id: Iecf52b4392a30b86905e1cd047c0ff87d59d0191 Signed-off-by: Vijayenthiran Subramaniam --- plat/arm/board/rde1edge/include/platform_def.h | 5 +++++ plat/arm/board/rdn1edge/include/platform_def.h | 5 +++++ plat/arm/board/sgi575/include/platform_def.h | 5 +++++ plat/arm/css/sgi/include/sgi_base_platform_def.h | 5 ----- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/plat/arm/board/rde1edge/include/platform_def.h b/plat/arm/board/rde1edge/include/platform_def.h index abb36018c..3fb640972 100644 --- a/plat/arm/board/rde1edge/include/platform_def.h +++ b/plat/arm/board/rde1edge/include/platform_def.h @@ -36,4 +36,9 @@ #define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) #endif +/* GIC related constants */ +#define PLAT_ARM_GICD_BASE UL(0x30000000) +#define PLAT_ARM_GICC_BASE UL(0x2C000000) +#define PLAT_ARM_GICR_BASE UL(0x300C0000) + #endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/rdn1edge/include/platform_def.h b/plat/arm/board/rdn1edge/include/platform_def.h index 46555f248..ab63e23ec 100644 --- a/plat/arm/board/rdn1edge/include/platform_def.h +++ b/plat/arm/board/rdn1edge/include/platform_def.h @@ -40,4 +40,9 @@ #define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) #endif +/* GIC related constants */ +#define PLAT_ARM_GICD_BASE UL(0x30000000) +#define PLAT_ARM_GICC_BASE UL(0x2C000000) +#define PLAT_ARM_GICR_BASE UL(0x300C0000) + #endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/sgi575/include/platform_def.h b/plat/arm/board/sgi575/include/platform_def.h index 25d24c5b0..95986cf4a 100644 --- a/plat/arm/board/sgi575/include/platform_def.h +++ b/plat/arm/board/sgi575/include/platform_def.h @@ -37,4 +37,9 @@ #define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) #endif +/* GIC related constants */ +#define PLAT_ARM_GICD_BASE UL(0x30000000) +#define PLAT_ARM_GICC_BASE UL(0x2C000000) +#define PLAT_ARM_GICR_BASE UL(0x300C0000) + #endif /* PLATFORM_DEF_H */ 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 7eb3d3c6d..4986378e9 100644 --- a/plat/arm/css/sgi/include/sgi_base_platform_def.h +++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h @@ -157,11 +157,6 @@ MT_DEVICE | MT_RW | MT_SECURE \ ) -/* GIC related constants */ -#define PLAT_ARM_GICD_BASE 0x30000000 -#define PLAT_ARM_GICC_BASE 0x2C000000 -#define PLAT_ARM_GICR_BASE 0x300C0000 - /* Map the secure region for access from S-EL0 */ #define PLAT_ARM_SECURE_MAP_DEVICE MAP_REGION_FLAT( \ SOC_CSS_DEVICE_BASE, \ -- cgit v1.2.3 From 4e950109378255632cd49091af68fed8335f5726 Mon Sep 17 00:00:00 2001 From: Vijayenthiran Subramaniam Date: Wed, 29 Jan 2020 22:00:59 +0530 Subject: board/rde1edge: fix incorrect topology tree description RD-E1-Edge platform consists of two clusters with eight CPUs each and two processing elements (PE) per CPU. Commit a9fbf13e049e (plat/arm/sgi: move topology information to board folder) defined the RD-E1-Edge topology tree to have two clusters with eight CPUs each but PE per CPU entries were not added. This patch fixes the topology tree accordingly. Change-Id: I7f97f0013be60e5d51c214fce3962e246bae8a0b Signed-off-by: Vijayenthiran Subramaniam --- plat/arm/board/rde1edge/rde1edge_topology.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/plat/arm/board/rde1edge/rde1edge_topology.c b/plat/arm/board/rde1edge/rde1edge_topology.c index 0b56f208a..a16283e45 100644 --- a/plat/arm/board/rde1edge/rde1edge_topology.c +++ b/plat/arm/board/rde1edge/rde1edge_topology.c @@ -7,12 +7,15 @@ #include /****************************************************************************** - * The power domain tree descriptor. + * The power domain tree descriptor. RD-E1-Edge platform consists of two + * clusters with eight CPUs in each cluster. The CPUs are multi-threaded with + * two threads per CPU. ******************************************************************************/ static const unsigned char rde1edge_pd_tree_desc[] = { + CSS_SGI_CHIP_COUNT, PLAT_ARM_CLUSTER_COUNT, - CSS_SGI_MAX_CPUS_PER_CLUSTER, - CSS_SGI_MAX_CPUS_PER_CLUSTER + CSS_SGI_MAX_CPUS_PER_CLUSTER * CSS_SGI_MAX_PE_PER_CPU, + CSS_SGI_MAX_CPUS_PER_CLUSTER * CSS_SGI_MAX_PE_PER_CPU }; /****************************************************************************** -- cgit v1.2.3 From 2103a73bf224f046784a2f0aeaaefd3f96110acf Mon Sep 17 00:00:00 2001 From: Aditya Angadi Date: Sun, 21 Jul 2019 22:13:45 +0530 Subject: plat/arm: add board support for rd-daniel platform Add the initial board support for RD-Daniel Config-M platform. Change-Id: I36df16c745bfe4bc817e275ad4722e5de57733cd Signed-off-by: Jagadeesh Ujja Signed-off-by: Aditya Angadi --- .../board/rddaniel/fdts/rddaniel_nt_fw_config.dts | 22 ++++++++ .../board/rddaniel/fdts/rddaniel_tb_fw_config.dts | 26 +++++++++ plat/arm/board/rddaniel/include/platform_def.h | 40 ++++++++++++++ plat/arm/board/rddaniel/platform.mk | 43 +++++++++++++++ plat/arm/board/rddaniel/rddaniel_err.c | 17 ++++++ plat/arm/board/rddaniel/rddaniel_plat.c | 30 +++++++++++ plat/arm/board/rddaniel/rddaniel_security.c | 12 +++++ plat/arm/board/rddaniel/rddaniel_topology.c | 62 ++++++++++++++++++++++ plat/arm/css/sgi/include/sgi_variant.h | 7 ++- plat/arm/css/sgi/sgi_bl31_setup.c | 13 +++-- 10 files changed, 266 insertions(+), 6 deletions(-) create mode 100644 plat/arm/board/rddaniel/fdts/rddaniel_nt_fw_config.dts create mode 100644 plat/arm/board/rddaniel/fdts/rddaniel_tb_fw_config.dts create mode 100644 plat/arm/board/rddaniel/include/platform_def.h create mode 100644 plat/arm/board/rddaniel/platform.mk create mode 100644 plat/arm/board/rddaniel/rddaniel_err.c create mode 100644 plat/arm/board/rddaniel/rddaniel_plat.c create mode 100644 plat/arm/board/rddaniel/rddaniel_security.c create mode 100644 plat/arm/board/rddaniel/rddaniel_topology.c diff --git a/plat/arm/board/rddaniel/fdts/rddaniel_nt_fw_config.dts b/plat/arm/board/rddaniel/fdts/rddaniel_nt_fw_config.dts new file mode 100644 index 000000000..4d4580d68 --- /dev/null +++ b/plat/arm/board/rddaniel/fdts/rddaniel_nt_fw_config.dts @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; +/ { + /* compatible string */ + compatible = "arm,rd-daniel"; + + /* + * Place holder for system-id node with default values. The + * value of platform-id and config-id will be set to the + * correct values during the BL2 stage of boot. + */ + system-id { + platform-id = <0x0>; + config-id = <0x0>; + multi-chip-mode = <0x0>; + }; +}; diff --git a/plat/arm/board/rddaniel/fdts/rddaniel_tb_fw_config.dts b/plat/arm/board/rddaniel/fdts/rddaniel_tb_fw_config.dts new file mode 100644 index 000000000..9acec137e --- /dev/null +++ b/plat/arm/board/rddaniel/fdts/rddaniel_tb_fw_config.dts @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +/ { + /* Platform Config */ + compatible = "arm,tb_fw"; + nt_fw_config_addr = <0x0 0xFEF00000>; + nt_fw_config_max_size = <0x0100000>; + + /* + * The following two entries are placeholders for Mbed TLS + * heap information. The default values don't matter since + * they will be overwritten by BL1. + * In case of having shared Mbed TLS heap between BL1 and BL2, + * BL1 will populate these two properties with the respective + * info about the shared heap. This info will be available for + * BL2 in order to locate and re-use the heap. + */ + mbedtls_heap_addr = <0x0 0x0>; + mbedtls_heap_size = <0x0>; +}; diff --git a/plat/arm/board/rddaniel/include/platform_def.h b/plat/arm/board/rddaniel/include/platform_def.h new file mode 100644 index 000000000..516360278 --- /dev/null +++ b/plat/arm/board/rddaniel/include/platform_def.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +#include + +#include + +#define PLAT_ARM_CLUSTER_COUNT U(16) +#define CSS_SGI_MAX_CPUS_PER_CLUSTER U(1) +#define CSS_SGI_MAX_PE_PER_CPU U(1) + +#define PLAT_CSS_MHU_BASE UL(0x45400000) +#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE + +#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL2 +#define PLAT_MAX_PWR_LVL ARM_PWR_LVL1 + +/* + * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes + */ +#ifdef __aarch64__ +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 42) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 42) +#else +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) +#endif + +/* GIC related constants */ +#define PLAT_ARM_GICD_BASE UL(0x30000000) +#define PLAT_ARM_GICC_BASE UL(0x2C000000) +#define PLAT_ARM_GICR_BASE UL(0x30140000) + +#endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/rddaniel/platform.mk b/plat/arm/board/rddaniel/platform.mk new file mode 100644 index 000000000..67f57779a --- /dev/null +++ b/plat/arm/board/rddaniel/platform.mk @@ -0,0 +1,43 @@ +# Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +include plat/arm/css/sgi/sgi-common.mk + +RDDANIEL_BASE = plat/arm/board/rddaniel + +PLAT_INCLUDES += -I${RDDANIEL_BASE}/include/ + +SGI_CPU_SOURCES := lib/cpus/aarch64/neoverse_zeus.S + +BL1_SOURCES += ${SGI_CPU_SOURCES} \ + ${RDDANIEL_BASE}/rddaniel_err.c + +BL2_SOURCES += ${RDDANIEL_BASE}/rddaniel_plat.c \ + ${RDDANIEL_BASE}/rddaniel_security.c \ + ${RDDANIEL_BASE}/rddaniel_err.c \ + lib/utils/mem_region.c \ + plat/arm/common/arm_nor_psci_mem_protect.c + +BL31_SOURCES += ${SGI_CPU_SOURCES} \ + ${RDDANIEL_BASE}/rddaniel_plat.c \ + ${RDDANIEL_BASE}/rddaniel_topology.c \ + drivers/cfi/v2m/v2m_flash.c \ + lib/utils/mem_region.c \ + plat/arm/common/arm_nor_psci_mem_protect.c + +# Add the FDT_SOURCES and options for Dynamic Config +FDT_SOURCES += ${RDDANIEL_BASE}/fdts/${PLAT}_tb_fw_config.dts +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb + +# Add the TB_FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) + +FDT_SOURCES += ${RDDANIEL_BASE}/fdts/${PLAT}_nt_fw_config.dts +NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb + +# Add the NT_FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config)) + +override CTX_INCLUDE_AARCH32_REGS := 0 diff --git a/plat/arm/board/rddaniel/rddaniel_err.c b/plat/arm/board/rddaniel/rddaniel_err.c new file mode 100644 index 000000000..5e1094219 --- /dev/null +++ b/plat/arm/board/rddaniel/rddaniel_err.c @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +/* + * rddaniel error handler + */ +void __dead2 plat_arm_error_handler(int err) +{ + while (1) { + wfi(); + } +} diff --git a/plat/arm/board/rddaniel/rddaniel_plat.c b/plat/arm/board/rddaniel/rddaniel_plat.c new file mode 100644 index 000000000..ab5251e51 --- /dev/null +++ b/plat/arm/board/rddaniel/rddaniel_plat.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +unsigned int plat_arm_sgi_get_platform_id(void) +{ + return mmio_read_32(SID_REG_BASE + SID_SYSTEM_ID_OFFSET) + & SID_SYSTEM_ID_PART_NUM_MASK; +} + +unsigned int plat_arm_sgi_get_config_id(void) +{ + return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET); +} + +unsigned int plat_arm_sgi_get_multi_chip_mode(void) +{ + return (mmio_read_32(SID_REG_BASE + SID_NODE_ID_OFFSET) & + SID_MULTI_CHIP_MODE_MASK) >> SID_MULTI_CHIP_MODE_SHIFT; +} + +void bl31_platform_setup(void) +{ + sgi_bl31_common_platform_setup(); +} diff --git a/plat/arm/board/rddaniel/rddaniel_security.c b/plat/arm/board/rddaniel/rddaniel_security.c new file mode 100644 index 000000000..6aa38c822 --- /dev/null +++ b/plat/arm/board/rddaniel/rddaniel_security.c @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +/* Initialize the secure environment */ +void plat_arm_security_setup(void) +{ +} diff --git a/plat/arm/board/rddaniel/rddaniel_topology.c b/plat/arm/board/rddaniel/rddaniel_topology.c new file mode 100644 index 000000000..55f5e04da --- /dev/null +++ b/plat/arm/board/rddaniel/rddaniel_topology.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +/****************************************************************************** + * The power domain tree descriptor. + ******************************************************************************/ +const unsigned char rd_daniel_pd_tree_desc[] = { + PLAT_ARM_CLUSTER_COUNT, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER +}; + +/******************************************************************************* + * This function returns the topology tree information. + ******************************************************************************/ +const unsigned char *plat_get_power_domain_tree_desc(void) +{ + return rd_daniel_pd_tree_desc; +} + +/******************************************************************************* + * The array mapping platform core position (implemented by plat_my_core_pos()) + * to the SCMI power domain ID implemented by SCP. + ******************************************************************************/ +const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = { + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x0)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x1)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x2)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x3)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x4)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x5)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x6)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x7)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x8)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x9)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xA)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xB)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xC)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xD)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xE)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xF)) +}; diff --git a/plat/arm/css/sgi/include/sgi_variant.h b/plat/arm/css/sgi/include/sgi_variant.h index b7a1e4a53..f4c5300d0 100644 --- a/plat/arm/css/sgi/include/sgi_variant.h +++ b/plat/arm/css/sgi/include/sgi_variant.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -8,12 +8,15 @@ #define SGI_VARIANT_H /* SSC_VERSION values for SGI575 */ -#define SGI575_SSC_VER_PART_NUM 0x0783 +#define SGI575_SSC_VER_PART_NUM 0x0783 /* SID Version values for RD-N1E1-Edge */ #define RD_N1E1_EDGE_SID_VER_PART_NUM 0x0786 #define RD_E1_EDGE_CONFIG_ID 0x2 +/* SID Version values for RD-Daniel */ +#define RD_DANIEL_SID_VER_PART_NUM 0x078a + /* Structure containing SGI platform variant information */ typedef struct sgi_platform_info { unsigned int platform_id; /* Part Number of the platform */ diff --git a/plat/arm/css/sgi/sgi_bl31_setup.c b/plat/arm/css/sgi/sgi_bl31_setup.c index f5d0f417c..fcb7e1f9f 100644 --- a/plat/arm/css/sgi/sgi_bl31_setup.c +++ b/plat/arm/css/sgi/sgi_bl31_setup.c @@ -73,7 +73,8 @@ static scmi_channel_plat_info_t rd_n1e1_edge_scmi_plat_info[] = { scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id) { - if (sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM) { + if (sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM || + sgi_plat_info.platform_id == RD_DANIEL_SID_VER_PART_NUM) { if (channel_id >= sizeof(rd_n1e1_edge_scmi_plat_info)) panic(); return &rd_n1e1_edge_scmi_plat_info[channel_id]; @@ -105,9 +106,13 @@ void sgi_bl31_common_platform_setup(void) const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops) { - /* For RD-E1-Edge platform only CPU ON/OFF is supported */ - if ((sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM) && - (sgi_plat_info.config_id == RD_E1_EDGE_CONFIG_ID)) { + /* + * For RD-E1-Edge and RD-Daniel platforms, only CPU power ON/OFF + * PSCI platform callbacks are supported. + */ + if (((sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM) && + (sgi_plat_info.config_id == RD_E1_EDGE_CONFIG_ID)) || + (sgi_plat_info.platform_id == RD_DANIEL_SID_VER_PART_NUM)) { ops->cpu_standby = NULL; ops->system_off = NULL; ops->system_reset = NULL; -- cgit v1.2.3 From 68c76088d3b79753a15dc7ef9e296cd6fa9150aa Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Thu, 6 Feb 2020 17:11:03 +0000 Subject: Make PAC demangling more generic At the moment, address demangling is only used by the backtrace functionality. However, at some point, other parts of the TF-A codebase may want to use it. The 'demangle_address' function is replaced with a single XPACI instruction which is also added in 'do_crash_reporting()'. Signed-off-by: Alexei Fedorov Change-Id: I4424dcd54d5bf0a5f9b2a0a84c4e565eec7329ec --- bl31/aarch64/crash_reporting.S | 7 ++++- common/backtrace/backtrace.c | 49 +++------------------------------- docs/getting_started/build-options.rst | 2 +- include/arch/aarch64/arch_helpers.h | 14 +++++++++- 4 files changed, 23 insertions(+), 49 deletions(-) diff --git a/bl31/aarch64/crash_reporting.S b/bl31/aarch64/crash_reporting.S index f2c12961d..97db2a167 100644 --- a/bl31/aarch64/crash_reporting.S +++ b/bl31/aarch64/crash_reporting.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -244,6 +244,11 @@ func do_crash_reporting mrs x0, tpidr_el3 /* report x30 first from the crash buf */ ldr x4, [x0, #REGSZ * 7] + +#if ENABLE_PAUTH + /* Demangle address */ + xpaci x4 +#endif bl asm_print_hex bl asm_print_newline /* Load the crash buf address */ diff --git a/common/backtrace/backtrace.c b/common/backtrace/backtrace.c index 506d4a482..907117f36 100644 --- a/common/backtrace/backtrace.c +++ b/common/backtrace/backtrace.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -37,47 +37,6 @@ struct frame_record { uintptr_t return_addr; }; -/* - * Strip the Pointer Authentication Code (PAC) from the address to retrieve the - * original one. - * - * The PAC field is stored on the high bits of the address and defined as: - * - PAC field = Xn[54:bottom_PAC_bit], when address tagging is used. - * - PAC field = Xn[63:56, 54:bottom_PAC_bit], without address tagging. - * - * With bottom_PAC_bit = 64 - TCR_ELx.TnSZ - */ -#if ENABLE_PAUTH -static uintptr_t demangle_address(uintptr_t addr) -{ - unsigned int el, t0sz, bottom_pac_bit; - uint64_t tcr, pac_mask; - - /* - * Different virtual address space size can be defined for each EL. - * Ensure that we use the proper one by reading the corresponding - * TCR_ELx register. - */ - el = get_current_el(); - - if (el == 3U) { - tcr = read_tcr_el3(); - } else if (el == 2U) { - tcr = read_tcr_el2(); - } else { - tcr = read_tcr_el1(); - } - - /* T0SZ = TCR_ELx[5:0] */ - t0sz = tcr & 0x1f; - bottom_pac_bit = 64 - t0sz; - pac_mask = (1ULL << bottom_pac_bit) - 1; - - /* demangle the address with the computed mask */ - return (addr & pac_mask); -} -#endif /* ENABLE_PAUTH */ - static const char *get_el_str(unsigned int el) { if (el == 3U) { @@ -104,9 +63,8 @@ static bool is_address_readable(uintptr_t addr) * stack contains a PAC. It must be stripped to retrieve the return * address. */ - addr = demangle_address(addr); + xpaci(addr); #endif - if (el == 3U) { ats1e3r(addr); } else if (el == 2U) { @@ -257,9 +215,8 @@ static void unwind_stack(struct frame_record *fr, uintptr_t current_pc, * the stack contains a PAC. It must be stripped to retrieve the * return address. */ - call_site = demangle_address(call_site); + xpaci(call_site); #endif - /* * If the address is invalid it means that the frame record is * probably corrupted. diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 2f44fe817..fa83b4f54 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -189,7 +189,7 @@ Common build options that is only required for the assertion and does not fit in the assertion itself. -- ``ENABLE_BACKTRACE``: This option controls whether to enables backtrace +- ``ENABLE_BACKTRACE``: This option controls whether to enable backtrace dumps or not. It is supported in both AArch64 and AArch32. However, in AArch32 the format of the frame records are not defined in the AAPCS and they are defined by the implementation. This implementation of backtrace only diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h index c60f2e8f7..240c1fbda 100644 --- a/include/arch/aarch64/arch_helpers.h +++ b/include/arch/aarch64/arch_helpers.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -69,6 +69,13 @@ static inline void _op(void) \ __asm__ (#_op); \ } +/* Define function for system instruction with register parameter */ +#define DEFINE_SYSOP_PARAM_FUNC(_op) \ +static inline void _op(uint64_t v) \ +{ \ + __asm__ (#_op " %0" : : "r" (v)); \ +} + /* Define function for system instruction with type specifier */ #define DEFINE_SYSOP_TYPE_FUNC(_op, _type) \ static inline void _op ## _type(void) \ @@ -211,6 +218,11 @@ DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s1e1r) DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s1e2r) DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s1e3r) +/******************************************************************************* + * Strip Pointer Authentication Code + ******************************************************************************/ +DEFINE_SYSOP_PARAM_FUNC(xpaci) + void flush_dcache_range(uintptr_t addr, size_t size); void clean_dcache_range(uintptr_t addr, size_t size); void inv_dcache_range(uintptr_t addr, size_t size); -- cgit v1.2.3 From 3977a825642dcd0368c934f7fd86f80f6a1c7c53 Mon Sep 17 00:00:00 2001 From: Manish Pandey Date: Tue, 7 Jan 2020 17:05:28 +0000 Subject: SPM: modify sptool to generate individual SP blobs Currently sptool generates a single blob containing all the Secure Partitions, with latest SPM implementation, it is desirable to have individual blobs for each Secure Partition. It allows to leverage packaging and parsing of SP on existing FIP framework. It also allows SP packages coming from different sources. This patch modifies sptool so that it takes number of SP payload pairs as input and generates number of SP blobs instead of a single blob. Each SP blob can optionally have its own header containing offsets and sizes of different payloads along with a SP magic number and version. It is also associated in FIP with a UUID, provided by SP owner. Usage example: sptool -i sp1.bin:sp1.dtb -o sp1.pkg -i sp2.bin:sp2.dtb -o sp2.pkg ... Signed-off-by: Manish Pandey Change-Id: Ie2db8e601fa1d4182d0a1d22e78e9533dce231bc --- include/tools_share/sptool.h | 26 ++-- tools/sptool/sptool.c | 292 +++++++++++++++++++++++-------------------- 2 files changed, 170 insertions(+), 148 deletions(-) diff --git a/include/tools_share/sptool.h b/include/tools_share/sptool.h index 67a2cf093..53668e09c 100644 --- a/include/tools_share/sptool.h +++ b/include/tools_share/sptool.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Arm Limited. All rights reserved. + * Copyright (c) 2018-2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,21 +9,17 @@ #include -/* Header for a secure partition package. There is one per package. */ -struct sp_pkg_header { - uint64_t version; - uint64_t number_of_sp; -}; +/* 4 Byte magic name "SPKG" */ +#define SECURE_PARTITION_MAGIC 0x474B5053 -/* - * Entry descriptor in a secure partition package. Each entry comprises a - * secure partition and its resource description. - */ -struct sp_pkg_entry { - uint64_t sp_offset; - uint64_t sp_size; - uint64_t rd_offset; - uint64_t rd_size; +/* Header for a secure partition package. */ +struct sp_pkg_header { + uint32_t magic; + uint32_t version; + uint32_t pm_offset; + uint32_t pm_size; + uint32_t img_offset; + uint32_t img_size; }; #endif /* SPTOOL_H */ diff --git a/tools/sptool/sptool.c b/tools/sptool/sptool.c index a33b66446..38baa2cd9 100644 --- a/tools/sptool/sptool.c +++ b/tools/sptool/sptool.c @@ -1,10 +1,11 @@ /* - * Copyright (c) 2018, Arm Limited. All rights reserved. + * Copyright (c) 2018-2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include +#include #include #include #include @@ -16,25 +17,26 @@ #define PAGE_SIZE 4096 /* - * Linked list of entries describing entries in the secure - * partition package. + * Entry describing Secure Partition package. */ -struct sp_entry_info { +struct sp_pkg_info { /* Location of the files in the host's RAM. */ - void *sp_data, *rd_data; + void *img_data, *pm_data; /* Size of the files. */ - uint64_t sp_size, rd_size; + uint32_t img_size, pm_size; /* Location of the binary files inside the package output file */ - uint64_t sp_offset, rd_offset; - - struct sp_entry_info *next; + uint32_t img_offset, pm_offset; }; -static struct sp_entry_info *sp_info_head; - -static uint64_t sp_count; +/* + * List of input provided by user + */ +struct arg_list { + char *usr_input; + struct arg_list *next; +}; /* Align an address to a power-of-two boundary. */ static unsigned int align_to(unsigned int address, unsigned int boundary) @@ -89,26 +91,61 @@ static void xfseek(FILE *fp, long offset, int whence) } } -static void cleanup(void) +/* + * Free SP package structure + */ +static void cleanup(struct sp_pkg_info *sp) { - struct sp_entry_info *sp = sp_info_head; - while (sp != NULL) { - struct sp_entry_info *next = sp->next; - - if (sp->sp_data != NULL) - free(sp->sp_data); + if (sp != NULL) { + if (sp->img_data != NULL) { + free(sp->img_data); + } - if (sp->rd_data != NULL) - free(sp->rd_data); + if (sp->pm_data != NULL) { + free(sp->pm_data); + } free(sp); - sp = next; } +} - sp_count = 0; - sp_info_head = NULL; +/* + * Free argument list structure + */ +static void freelist(struct arg_list *head) +{ + struct arg_list *tmp; + + while (head != NULL) { + tmp = head; + head = head->next; + free(tmp); + } +} + +/* + * Append user inputs in argument list structure + */ +static void append_user_input(struct arg_list **head, char *args) +{ + struct arg_list *tmp = *head; + + if (tmp == NULL) { + tmp = xzalloc(sizeof(struct arg_list), + "Failed to allocate arg_list struct"); + tmp->usr_input = args; + *head = tmp; + } else { + while (tmp->next != NULL) { + tmp = tmp->next; + } + tmp->next = xzalloc(sizeof(struct arg_list), + "Failed to allocate arg_list struct"); + tmp = tmp->next; + tmp->usr_input = args; + } } /* @@ -116,7 +153,7 @@ static void cleanup(void) * load the file into it. Fill 'size' with the file size. Exit the program on * error. */ -static void load_file(const char *path, void **ptr, uint64_t *size) +static void load_file(const char *path, void **ptr, uint32_t *size) { FILE *f = fopen(path, "rb"); if (f == NULL) { @@ -147,59 +184,40 @@ static void load_file(const char *path, void **ptr, uint64_t *size) fclose(f); } -static void load_sp_rd(char *path) +/* + * Parse the string containing input payloads and fill in the + * SP Package data structure. + */ +static void load_sp_pm(char *path, struct sp_pkg_info **sp_out) { + struct sp_pkg_info *sp_pkg; + char *split_mark = strstr(path, ":"); *split_mark = '\0'; char *sp_path = path; - char *rd_path = split_mark + 1; - - struct sp_entry_info *sp; - - if (sp_info_head == NULL) { - sp_info_head = xzalloc(sizeof(struct sp_entry_info), - "Failed to allocate sp_entry_info struct"); - - sp = sp_info_head; - } else { - sp = sp_info_head; - - while (sp->next != NULL) { - sp = sp->next; - } - - sp->next = xzalloc(sizeof(struct sp_entry_info), - "Failed to allocate sp_entry_info struct"); + char *pm_path = split_mark + 1; - sp = sp->next; - } + sp_pkg = xzalloc(sizeof(struct sp_pkg_info), + "Failed to allocate sp_pkg_info struct"); - load_file(sp_path, &sp->sp_data, &sp->sp_size); - printf("Loaded image file %s (%lu bytes)\n", sp_path, sp->sp_size); + load_file(pm_path, &sp_pkg->pm_data, &sp_pkg->pm_size); + printf("\nLoaded SP Manifest file %s (%u bytes)\n", pm_path, sp_pkg->pm_size); - load_file(rd_path, &sp->rd_data, &sp->rd_size); - printf("Loaded RD file %s (%lu bytes)\n", rd_path, sp->rd_size); + load_file(sp_path, &sp_pkg->img_data, &sp_pkg->img_size); + printf("Loaded SP Image file %s (%u bytes)\n", sp_path, sp_pkg->img_size); - sp_count++; + *sp_out = sp_pkg; } -static void output_write(const char *path) +/* + * Write SP package data structure into output file. + */ +static void output_write(const char *path, struct sp_pkg_info *sp, bool header) { - struct sp_entry_info *sp; - - if (sp_count == 0) { - fprintf(stderr, "error: At least one SP must be provided.\n"); - exit(1); - } - - /* The layout of the structs is specified in the header file sptool.h */ - - printf("Writing %lu partitions to output file.\n", sp_count); - - unsigned int header_size = (sizeof(struct sp_pkg_header) * 8) - + (sizeof(struct sp_pkg_entry) * 8 * sp_count); + struct sp_pkg_header sp_header_info; + unsigned int file_ptr = 0; FILE *f = fopen(path, "wb"); if (f == NULL) { @@ -207,70 +225,46 @@ static void output_write(const char *path) exit(1); } - unsigned int file_ptr = align_to(header_size, PAGE_SIZE); - - /* First, save all partition images aligned to page boundaries */ - - sp = sp_info_head; - - for (uint64_t i = 0; i < sp_count; i++) { - xfseek(f, file_ptr, SEEK_SET); - - printf("Writing image %lu to offset 0x%x (0x%lx bytes)\n", - i, file_ptr, sp->sp_size); - - sp->sp_offset = file_ptr; - xfwrite(sp->sp_data, sp->sp_size, f); - file_ptr = align_to(file_ptr + sp->sp_size, PAGE_SIZE); - sp = sp->next; + /* Reserve Header size */ + if (header) { + file_ptr = sizeof(struct sp_pkg_header); } - /* Now, save resource description blobs aligned to 8 bytes */ + /* Save partition manifest */ + xfseek(f, file_ptr, SEEK_SET); + printf("Writing SP Manifest at offset 0x%x (%u bytes)\n", + file_ptr, sp->pm_size); - sp = sp_info_head; - - for (uint64_t i = 0; i < sp_count; i++) { - xfseek(f, file_ptr, SEEK_SET); - - printf("Writing RD blob %lu to offset 0x%x (0x%lx bytes)\n", - i, file_ptr, sp->rd_size); - - sp->rd_offset = file_ptr; - xfwrite(sp->rd_data, sp->rd_size, f); - file_ptr = align_to(file_ptr + sp->rd_size, 8); - sp = sp->next; - } + sp->pm_offset = file_ptr; + xfwrite(sp->pm_data, sp->pm_size, f); - /* Finally, write header */ + /* Save partition image aligned to Page size */ + file_ptr = align_to((sp->pm_offset + sp->pm_size), PAGE_SIZE); + xfseek(f, file_ptr, SEEK_SET); + printf("Writing SP Image at offset 0x%x (%u bytes)\n", + file_ptr, sp->img_size); - uint64_t version = 0x1; - uint64_t sp_num = sp_count; + sp->img_offset = file_ptr; + xfwrite(sp->img_data, sp->img_size, f); - xfseek(f, 0, SEEK_SET); + /* Finally, write header, if needed */ + if (header) { + sp_header_info.magic = SECURE_PARTITION_MAGIC; + sp_header_info.version = 0x1; + sp_header_info.img_offset = sp->img_offset; + sp_header_info.img_size = sp->img_size; + sp_header_info.pm_offset = sp->pm_offset; + sp_header_info.pm_size = sp->pm_size; - xfwrite(&version, sizeof(uint64_t), f); - xfwrite(&sp_num, sizeof(uint64_t), f); + xfseek(f, 0, SEEK_SET); - sp = sp_info_head; + printf("Writing package header\n"); - for (unsigned int i = 0; i < sp_count; i++) { - - uint64_t sp_offset, sp_size, rd_offset, rd_size; - - sp_offset = sp->sp_offset; - sp_size = align_to(sp->sp_size, PAGE_SIZE); - rd_offset = sp->rd_offset; - rd_size = sp->rd_size; - - xfwrite(&sp_offset, sizeof(uint64_t), f); - xfwrite(&sp_size, sizeof(uint64_t), f); - xfwrite(&rd_offset, sizeof(uint64_t), f); - xfwrite(&rd_size, sizeof(uint64_t), f); - - sp = sp->next; + xfwrite(&sp_header_info, sizeof(struct sp_pkg_header), f); } /* All information has been written now */ + printf("\nsptool: Built Secure Partition blob %s\n", path); fclose(f); } @@ -286,30 +280,51 @@ static void usage(void) #endif printf(" []\n\n"); - printf("This tool takes as inputs several image binary files and the\n" - "resource description blobs as input and generates a package\n" - "file that contains them.\n\n"); + printf("This tool takes as input set of image binary files and the\n" + "partition manifest blobs as input and generates set of\n" + "output package files\n" + "Usage example: sptool -i sp1.bin:sp1.dtb -o sp1.pkg\n" + " -i sp2.bin:sp2.dtb -o sp2.pkg ...\n\n"); printf("Commands supported:\n"); printf(" -o Set output file path.\n"); - printf(" -i Add Secure Partition image and Resource\n" - " Description blob (specified in two paths\n" + printf(" -i Add Secure Partition image and\n" + " Manifest blob (specified in two paths\n" " separated by a colon).\n"); + printf(" -n Generate package without header\n"); printf(" -h Show this message.\n"); exit(1); } int main(int argc, char *argv[]) { + struct sp_pkg_info *sp_pkg = NULL; + struct arg_list *in_head = NULL; + struct arg_list *out_head = NULL; + struct arg_list *in_list = NULL; + struct arg_list *out_list = NULL; + unsigned int match_counter = 0; + bool need_header = true; + int ch; - const char *outname = NULL; - while ((ch = getopt(argc, argv, "hi:o:")) != -1) { + if (argc <= 1) { + fprintf(stderr, "error: File paths must be provided.\n\n"); + usage(); + return 1; + } + + while ((ch = getopt(argc, argv, "hni:o:")) != -1) { switch (ch) { case 'i': - load_sp_rd(optarg); + append_user_input(&in_head, optarg); + match_counter++; break; case 'o': - outname = optarg; + append_user_input(&out_head, optarg); + match_counter--; + break; + case 'n': + need_header = false; break; case 'h': default: @@ -317,18 +332,29 @@ int main(int argc, char *argv[]) } } - argc -= optind; - argv += optind; - - if (outname == NULL) { - fprintf(stderr, "error: An output file path must be provided.\n\n"); + if (match_counter) { + fprintf(stderr, "error: Input/Output count mismatch.\n\n"); + freelist(in_head); + freelist(out_head); usage(); return 1; } - output_write(outname); + in_list = in_head; + out_list = out_head; + while (in_list != NULL) { + load_sp_pm(in_list->usr_input, &sp_pkg); + output_write(out_list->usr_input, sp_pkg, need_header); + in_list = in_list->next; + out_list = out_list->next; + } + + argc -= optind; + argv += optind; - cleanup(); + cleanup(sp_pkg); + freelist(in_head); + freelist(out_head); return 0; } -- cgit v1.2.3 From 0cb64d01d934cf9b8368a8afea839c7a9bd9a701 Mon Sep 17 00:00:00 2001 From: Achin Gupta Date: Fri, 11 Oct 2019 14:54:48 +0100 Subject: SPMD: add support for an example SPM core manifest This patch repurposes the TOS FW configuration file as the manifest for the SPM core component which will reside at the secure EL adjacent to EL3. The SPM dispatcher component will use the manifest to determine how the core component must be initialised. Routines and data structure to parse the manifest have also been added. Signed-off-by: Achin Gupta Signed-off-by: Artsem Artsemenka Change-Id: Id94f8ece43b4e05609f0a1d364708a912f6203cb --- common/desc_image_load.c | 18 +++- include/plat/common/platform.h | 11 ++- include/services/spm_core_manifest.h | 55 ++++++++++++ plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts | 19 ++++ plat/arm/board/fvp/platform.mk | 8 ++ plat/arm/common/arm_dyn_cfg.c | 6 +- plat/common/plat_spmd_manifest.c | 124 ++++++++++++++++++++++++++ 7 files changed, 233 insertions(+), 8 deletions(-) create mode 100644 include/services/spm_core_manifest.h create mode 100644 plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts create mode 100644 plat/common/plat_spmd_manifest.c diff --git a/common/desc_image_load.c b/common/desc_image_load.c index f2e8f6054..c8dd403ff 100644 --- a/common/desc_image_load.c +++ b/common/desc_image_load.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -215,6 +215,9 @@ void populate_next_bl_params_config(bl_params_t *bl2_to_next_bl_params) bl_params_node_t *params_node; unsigned int fw_config_id; uintptr_t hw_config_base = 0, fw_config_base; +#if defined(SPD_spmd) + uint32_t fw_config_size = 0; +#endif bl_mem_params_node_t *mem_params; assert(bl2_to_next_bl_params != NULL); @@ -249,10 +252,14 @@ void populate_next_bl_params_config(bl_params_t *bl2_to_next_bl_params) if (fw_config_id != INVALID_IMAGE_ID) { mem_params = get_bl_mem_params_node(fw_config_id); - if (mem_params != NULL) + if (mem_params != NULL) { fw_config_base = mem_params->image_info.image_base; +#if defined(SPD_spmd) + fw_config_size = + mem_params->image_info.image_size; +#endif + } } - /* * Pass hw and tb_fw config addresses to next images. NOTE - for * EL3 runtime images (BL31 for AArch64 and BL32 for AArch32), @@ -273,6 +280,11 @@ void populate_next_bl_params_config(bl_params_t *bl2_to_next_bl_params) if (params_node->ep_info->args.arg1 == 0U) params_node->ep_info->args.arg1 = hw_config_base; +#if defined(SPD_spmd) + if (params_node->ep_info->args.arg2 == 0U) + params_node->ep_info->args.arg2 = + fw_config_size; +#endif } } } diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h index 332cfca8d..f5bd298c5 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -10,6 +10,9 @@ #include #include +#if defined(SPD_spmd) + #include +#endif /******************************************************************************* * Forward declarations @@ -272,7 +275,11 @@ const struct spm_mm_boot_info *plat_get_secure_partition_boot_info( int plat_spm_sp_rd_load(struct sp_res_desc *rd, const void *ptr, size_t size); int plat_spm_sp_get_next_address(void **sp_base, size_t *sp_size, void **rd_base, size_t *rd_size); - +#if defined(SPD_spmd) +int plat_spm_core_manifest_load(spmc_manifest_sect_attribute_t *manifest, + const void *ptr, + size_t size); +#endif /******************************************************************************* * Mandatory BL image load functions(may be overridden). ******************************************************************************/ diff --git a/include/services/spm_core_manifest.h b/include/services/spm_core_manifest.h new file mode 100644 index 000000000..06ecc1391 --- /dev/null +++ b/include/services/spm_core_manifest.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SPMC_MANIFEST_H +#define SPMC_MANIFEST_H + +#include + +/******************************************************************************* + * Attribute Section + ******************************************************************************/ + +typedef struct spm_core_manifest_sect_attribute { + /* + * SPCI version (mandatory). + */ + uint32_t major_version; + uint32_t minor_version; + + /* + * Run-Time Exception Level (mandatory): + * - 1: SEL1 + * - 2: SEL2 + */ + uint32_t runtime_el; + + /* + * Run-Time Execution state (optional): + * - 0: AArch64 (default) + * - 1: AArch32 + */ + uint32_t exec_state; + + /* + * Address of binary image containing SPM core in bytes (optional). + */ + uint64_t load_address; + + /* + * Offset from the base of the partition's binary image to the entry + * point of the partition. + */ + uint64_t entrypoint; + + /* + * Size of binary image containing SPM core in bytes (mandatory). + */ + uint32_t binary_size; + +} spmc_manifest_sect_attribute_t; + +#endif /* SPMC_MANIFEST_H */ diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts new file mode 100644 index 000000000..e1c106f1e --- /dev/null +++ b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +/dts-v1/; + +/ { + compatible = "spci-core-manifest-1.0"; + + attribute { + maj_ver = <0x0>; + min_ver = <0x9>; + runtime_el = <0x1>; + exec_state = <0x0>; + load_address = <0x0 0x6000000>; + entrypoint = <0x0 0x6000000>; + }; +}; diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 97a326c09..dcc55d869 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -224,6 +224,14 @@ FVP_TOS_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tsp_fw_config.dtb $(eval $(call TOOL_ADD_PAYLOAD,${FVP_TOS_FW_CONFIG},--tos-fw-config)) endif +ifeq (${SPD},spmd) +FDT_SOURCES += plat/arm/board/fvp/fdts/${PLAT}_spmc_manifest.dts +FVP_TOS_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_spmc_manifest.dtb + +# Add the TOS_FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TOS_FW_CONFIG},--tos-fw-config)) +endif + # Add the TB_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config)) # Add the SOC_FW_CONFIG to FIP and specify the same to certtool diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c index e6c5a7361..fdc3ef394 100644 --- a/plat/arm/common/arm_dyn_cfg.c +++ b/plat/arm/common/arm_dyn_cfg.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -197,8 +197,8 @@ void arm_bl2_dyn_cfg_init(void) HW_CONFIG_ID, SOC_FW_CONFIG_ID, NT_FW_CONFIG_ID, -#ifdef SPD_tspd - /* Currently tos_fw_config is only present for TSP */ +#if defined(SPD_tspd) || defined(SPD_spmd) + /* tos_fw_config is only present for TSPD/SPMD */ TOS_FW_CONFIG_ID #endif }; diff --git a/plat/common/plat_spmd_manifest.c b/plat/common/plat_spmd_manifest.c new file mode 100644 index 000000000..4c789795e --- /dev/null +++ b/plat/common/plat_spmd_manifest.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +/******************************************************************************* + * Attribute section handler + ******************************************************************************/ +static int manifest_parse_attribute(spmc_manifest_sect_attribute_t *attr, + const void *fdt, + int node) +{ + int rc = 0; + + assert(attr && fdt); + + rc = fdtw_read_cells(fdt, node, "maj_ver", 1, &attr->major_version); + if (rc) { + ERROR("Missing SPCI major version in SPM core manifest.\n"); + return -ENOENT; + } + + rc = fdtw_read_cells(fdt, node, "min_ver", 1, &attr->minor_version); + if (rc) { + ERROR("Missing SPCI minor version in SPM core manifest.\n"); + return -ENOENT; + } + + rc = fdtw_read_cells(fdt, node, "runtime_el", 1, &attr->runtime_el); + if (rc) { + ERROR("Missing SPM core runtime EL in manifest.\n"); + return -ENOENT; + } + + rc = fdtw_read_cells(fdt, node, "exec_state", 1, &attr->exec_state); + if (rc) + NOTICE("Execution state not specified in SPM core manifest.\n"); + + rc = fdtw_read_cells(fdt, node, "binary_size", 1, &attr->binary_size); + if (rc) + NOTICE("Binary size not specified in SPM core manifest.\n"); + + rc = fdtw_read_cells(fdt, node, "load_address", 2, &attr->load_address); + if (rc) + NOTICE("Load address not specified in SPM core manifest.\n"); + + rc = fdtw_read_cells(fdt, node, "entrypoint", 2, &attr->entrypoint); + if (rc) + NOTICE("Entrypoint not specified in SPM core manifest.\n"); + + VERBOSE("SPM core manifest attribute section:\n"); + VERBOSE(" version: %x.%x\n", attr->major_version, attr->minor_version); + VERBOSE(" runtime_el: 0x%x\n", attr->runtime_el); + 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); + + return 0; +} + +/******************************************************************************* + * Root node handler + ******************************************************************************/ +static int manifest_parse_root(spmc_manifest_sect_attribute_t *manifest, + const void *fdt, + int root) +{ + int node; + char *str; + + str = "attribute"; + node = fdt_subnode_offset_namelen(fdt, root, str, strlen(str)); + if (node < 0) { + ERROR("Root node doesn't contain subnode '%s'\n", str); + return -ENOENT; + } + + return manifest_parse_attribute(manifest, fdt, node); +} + +/******************************************************************************* + * Platform handler to parse a SPM core manifest. + ******************************************************************************/ +int plat_spm_core_manifest_load(spmc_manifest_sect_attribute_t *manifest, + const void *ptr, + size_t size) +{ + int rc; + int root_node; + + assert(manifest != NULL); + assert(ptr != NULL); + + INFO("Reading SPM core manifest at address %p\n", ptr); + + rc = fdt_check_header(ptr); + if (rc != 0) { + ERROR("Wrong format for SPM core manifest (%d).\n", rc); + return -EINVAL; + } + + INFO("Reading SPM core manifest at address %p\n", ptr); + + root_node = fdt_node_offset_by_compatible(ptr, -1, + "arm,spci-core-manifest-1.0"); + if (root_node < 0) { + ERROR("Unrecognized SPM core manifest\n"); + return -ENOENT; + } + + INFO("Reading SPM core manifest at address %p\n", ptr); + return manifest_parse_root(manifest, ptr, root_node); +} -- cgit v1.2.3 From 64758c97eec6b646faae15ccc4f3dad64a3a968d Mon Sep 17 00:00:00 2001 From: Achin Gupta Date: Fri, 11 Oct 2019 15:15:19 +0100 Subject: SPMD: add support to run BL32 in TDRAM and BL31 in secure DRAM on Arm FVP This patch reserves and maps the Trusted DRAM for SPM core execution. It also configures the TrustZone address space controller to run BL31 in secure DRAM. Signed-off-by: Achin Gupta Signed-off-by: Artsem Artsemenka Change-Id: I7e1bb3bbc61a0fec6a9cb595964ff553620c21dc --- include/plat/arm/common/arm_def.h | 18 ++++++++++++++++-- plat/arm/board/fvp/fvp_common.c | 3 +++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index 5bd53f3b5..54fd16925 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -223,6 +223,14 @@ ARM_EL3_TZC_DRAM1_SIZE, \ MT_MEMORY | MT_RW | MT_SECURE) +#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) +#endif + + /* * Mapping for the BL1 RW region. This mapping is needed by BL2 in order to * share the Mbed TLS heap. Since the heap is allocated inside BL1, it resides @@ -471,6 +479,12 @@ # define BL32_BASE (ARM_AP_TZC_DRAM1_BASE + ULL(0x200000)) # define BL32_LIMIT (ARM_AP_TZC_DRAM1_BASE + \ ARM_AP_TZC_DRAM1_SIZE) +# elif defined(SPD_spmd) +# define TSP_SEC_MEM_BASE (ARM_AP_TZC_DRAM1_BASE + ULL(0x200000)) +# define TSP_SEC_MEM_SIZE (ARM_AP_TZC_DRAM1_SIZE - ULL(0x200000)) +# define BL32_BASE PLAT_ARM_TRUSTED_DRAM_BASE +# define BL32_LIMIT (PLAT_ARM_TRUSTED_DRAM_BASE \ + + (UL(1) << 21)) # elif ARM_BL31_IN_DRAM # define TSP_SEC_MEM_BASE (ARM_AP_TZC_DRAM1_BASE + \ PLAT_ARM_MAX_BL31_SIZE) @@ -505,12 +519,12 @@ /* * BL32 is mandatory in AArch32. In AArch64, undefine BL32_BASE if there is no - * SPD and no SPM, as they are the only ones that can be used as BL32. + * SPD and no SPM-MM, as they are the only ones that can be used as BL32. */ #if defined(__aarch64__) && !JUNO_AARCH32_EL3_RUNTIME # if defined(SPD_none) && !SPM_MM # undef BL32_BASE -# endif /* defined(SPD_none) && !SPM_MM*/ +# endif /* defined(SPD_none) && !SPM_MM */ #endif /* defined(__aarch64__) && !JUNO_AARCH32_EL3_RUNTIME */ /******************************************************************************* diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c index ffaa93de4..2c880fc30 100644 --- a/plat/arm/board/fvp/fvp_common.c +++ b/plat/arm/board/fvp/fvp_common.c @@ -86,6 +86,9 @@ const mmap_region_t plat_arm_mmap[] = { #ifdef __aarch64__ ARM_MAP_DRAM2, #endif +#if defined(SPD_spmd) + ARM_MAP_TRUSTED_DRAM, +#endif #ifdef SPD_tspd ARM_MAP_TSP_SEC_MEM, #endif -- cgit v1.2.3 From bdd2596d42f1e96f0135be23d2bd936cc7eb30e5 Mon Sep 17 00:00:00 2001 From: Achin Gupta Date: Fri, 11 Oct 2019 15:41:16 +0100 Subject: SPMD: add SPM dispatcher based upon SPCI Beta 0 spec This patch adds a rudimentary SPM dispatcher component in EL3. It does the following: - Consumes the TOS_FW_CONFIG to determine properties of the SPM core component - Initialises the SPM core component which resides in the BL32 image - Implements a handler for SPCI calls from either security state. Some basic validation is done for each call but in most cases it is simply forwarded as-is to the "other" security state. Signed-off-by: Achin Gupta Signed-off-by: Artsem Artsemenka Change-Id: I7d116814557f7255f4f4ebb797d1619d4fbab590 --- include/services/spmd_svc.h | 25 ++ services/std_svc/spmd/aarch64/spmd_helpers.S | 73 ++++ services/std_svc/spmd/spmd.mk | 21 ++ services/std_svc/spmd/spmd_main.c | 487 +++++++++++++++++++++++++++ services/std_svc/spmd/spmd_private.h | 78 +++++ 5 files changed, 684 insertions(+) create mode 100644 include/services/spmd_svc.h create mode 100644 services/std_svc/spmd/aarch64/spmd_helpers.S create mode 100644 services/std_svc/spmd/spmd.mk create mode 100644 services/std_svc/spmd/spmd_main.c create mode 100644 services/std_svc/spmd/spmd_private.h diff --git a/include/services/spmd_svc.h b/include/services/spmd_svc.h new file mode 100644 index 000000000..6e4caf266 --- /dev/null +++ b/include/services/spmd_svc.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SPMD_SVC_H +#define SPMD_SVC_H + +#ifndef __ASSEMBLER__ +#include +#include + +int32_t spmd_setup(void); +uint64_t spmd_smc_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 /* SPMD_SVC_H */ diff --git a/services/std_svc/spmd/aarch64/spmd_helpers.S b/services/std_svc/spmd/aarch64/spmd_helpers.S new file mode 100644 index 000000000..d7bffca24 --- /dev/null +++ b/services/std_svc/spmd/aarch64/spmd_helpers.S @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include "../spmd_private.h" + + .global spmd_spm_core_enter + .global spmd_spm_core_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 spmd_spm_core_enter + /* Make space for the registers that we're going to save */ + mov x3, sp + str x3, [x0, #0] + sub sp, sp, #SPMD_C_RT_CTX_SIZE + + /* Save callee-saved registers on to the stack */ + stp x19, x20, [sp, #SPMD_C_RT_CTX_X19] + stp x21, x22, [sp, #SPMD_C_RT_CTX_X21] + stp x23, x24, [sp, #SPMD_C_RT_CTX_X23] + stp x25, x26, [sp, #SPMD_C_RT_CTX_X25] + stp x27, x28, [sp, #SPMD_C_RT_CTX_X27] + stp x29, x30, [sp, #SPMD_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 spmd_spm_core_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 spmd_spm_core_exit + /* Restore the previous stack */ + mov sp, x0 + + /* Restore callee-saved registers on to the stack */ + ldp x19, x20, [x0, #(SPMD_C_RT_CTX_X19 - SPMD_C_RT_CTX_SIZE)] + ldp x21, x22, [x0, #(SPMD_C_RT_CTX_X21 - SPMD_C_RT_CTX_SIZE)] + ldp x23, x24, [x0, #(SPMD_C_RT_CTX_X23 - SPMD_C_RT_CTX_SIZE)] + ldp x25, x26, [x0, #(SPMD_C_RT_CTX_X25 - SPMD_C_RT_CTX_SIZE)] + ldp x27, x28, [x0, #(SPMD_C_RT_CTX_X27 - SPMD_C_RT_CTX_SIZE)] + ldp x29, x30, [x0, #(SPMD_C_RT_CTX_X29 - SPMD_C_RT_CTX_SIZE)] + + /* --------------------------------------------------------------------- + * This should take us back to the instruction after the call to the + * last spm_secure_partition_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 spmd_spm_core_exit diff --git a/services/std_svc/spmd/spmd.mk b/services/std_svc/spmd/spmd.mk new file mode 100644 index 000000000..38d43f167 --- /dev/null +++ b/services/std_svc/spmd/spmd.mk @@ -0,0 +1,21 @@ +# +# Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +ifneq (${ARCH},aarch64) + $(error "Error: SPMD is only supported on aarch64.") +endif + +SPMD_SOURCES += $(addprefix services/std_svc/spmd/, \ + ${ARCH}/spmd_helpers.S \ + spmd_main.c) + +# Let the top-level Makefile know that we intend to include a BL32 image +NEED_BL32 := yes + +# Enable dynamic memory mapping +# The SPMD component maps the SPMC DTB within BL31 virtual space. +PLAT_XLAT_TABLES_DYNAMIC := 1 +$(eval $(call add_define,PLAT_XLAT_TABLES_DYNAMIC)) diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c new file mode 100644 index 000000000..677f63968 --- /dev/null +++ b/services/std_svc/spmd/spmd_main.c @@ -0,0 +1,487 @@ +/* + * Copyright (c) 2020, 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 "spmd_private.h" + +/******************************************************************************* + * SPM Core context information. + ******************************************************************************/ +spmd_spm_core_context_t spm_core_context[PLATFORM_CORE_COUNT]; + +/******************************************************************************* + * SPM Core attribute information read from its manifest. + ******************************************************************************/ +spmc_manifest_sect_attribute_t spmc_attrs; + +/******************************************************************************* + * This function takes an SP context pointer and performs a synchronous entry + * into it. + ******************************************************************************/ +uint64_t spmd_spm_core_sync_entry(spmd_spm_core_context_t *spmc_ctx) +{ + uint64_t rc; + + assert(spmc_ctx != NULL); + + cm_set_context(&(spmc_ctx->cpu_ctx), SECURE); + + /* Restore the context assigned above */ + cm_el1_sysregs_context_restore(SECURE); + cm_set_next_eret_context(SECURE); + + /* Invalidate TLBs at EL1. */ + tlbivmalle1(); + dsbish(); + + /* Enter Secure Partition */ + rc = spmd_spm_core_enter(&spmc_ctx->c_rt_ctx); + + /* Save secure state */ + cm_el1_sysregs_context_save(SECURE); + + return rc; +} + +/******************************************************************************* + * This function returns to the place where spm_sp_synchronous_entry() was + * called originally. + ******************************************************************************/ +__dead2 void spmd_spm_core_sync_exit(uint64_t rc) +{ + spmd_spm_core_context_t *ctx = &spm_core_context[plat_my_core_pos()]; + + /* Get context of the SP in use by this CPU. */ + assert(cm_get_context(SECURE) == &(ctx->cpu_ctx)); + + /* + * The SPMD must have initiated the original request through a + * synchronous entry into SPMC. Jump back to the original C runtime + * context with the value of rc in x0; + */ + spmd_spm_core_exit(ctx->c_rt_ctx, rc); + + panic(); +} + +/******************************************************************************* + * Jump to the SPM core for the first time. + ******************************************************************************/ +static int32_t spmd_init(void) +{ + uint64_t rc = 0; + spmd_spm_core_context_t *ctx = &spm_core_context[plat_my_core_pos()]; + + INFO("SPM Core init start.\n"); + ctx->state = SPMC_STATE_RESET; + + rc = spmd_spm_core_sync_entry(ctx); + if (rc) { + ERROR("SPMC initialisation failed 0x%llx\n", rc); + panic(); + } + + ctx->state = SPMC_STATE_IDLE; + INFO("SPM Core init end.\n"); + + return 1; +} + +/******************************************************************************* + * Initialize context of SPM core. + ******************************************************************************/ +int32_t spmd_setup(void) +{ + int rc; + void *rd_base; + size_t rd_size; + entry_point_info_t *spmc_ep_info; + uintptr_t rd_base_align; + uintptr_t rd_size_align; + uint32_t ep_attr; + + spmc_ep_info = bl31_plat_get_next_image_ep_info(SECURE); + if (!spmc_ep_info) { + WARN("No SPM core image provided by BL2 boot loader, Booting " + "device without SP initialization. SMC`s destined for SPM " + "core will return SMC_UNK\n"); + return 1; + } + + /* Under no circumstances will this parameter be 0 */ + assert(spmc_ep_info->pc != 0U); + + /* + * Check if BL32 ep_info has a reference to 'tos_fw_config'. This will + * be used as a manifest for the SPM core at the next lower EL/mode. + */ + if (spmc_ep_info->args.arg0 == 0U || spmc_ep_info->args.arg2 == 0U) { + ERROR("Invalid or absent SPM core manifest\n"); + panic(); + } + + /* Obtain whereabouts of SPM core manifest */ + rd_base = (void *) spmc_ep_info->args.arg0; + rd_size = spmc_ep_info->args.arg2; + + rd_base_align = page_align((uintptr_t) rd_base, DOWN); + rd_size_align = page_align((uintptr_t) rd_size, UP); + + /* Map the manifest in the SPMD translation regime first */ + VERBOSE("SPM core manifest base : 0x%lx\n", rd_base_align); + VERBOSE("SPM core manifest size : 0x%lx\n", rd_size_align); + rc = mmap_add_dynamic_region((unsigned long long) rd_base_align, + (uintptr_t) rd_base_align, + rd_size_align, + MT_RO_DATA); + if (rc < 0) { + ERROR("Error while mapping SPM core manifest (%d).\n", rc); + panic(); + } + + /* Load the SPM core manifest */ + rc = plat_spm_core_manifest_load(&spmc_attrs, rd_base, rd_size); + if (rc < 0) { + WARN("No or invalid SPM core manifest image provided by BL2 " + "boot loader. "); + goto error; + } + + /* + * Ensure that the SPM core version is compatible with the SPM + * dispatcher version + */ + if ((spmc_attrs.major_version != SPCI_VERSION_MAJOR) || + (spmc_attrs.minor_version > SPCI_VERSION_MINOR)) { + WARN("Unsupported SPCI version (%x.%x) specified in SPM core " + "manifest image provided by BL2 boot loader.\n", + spmc_attrs.major_version, spmc_attrs.minor_version); + goto error; + } + + INFO("SPCI version (%x.%x).\n", spmc_attrs.major_version, + spmc_attrs.minor_version); + + /* Validate the SPM core runtime EL */ + if ((spmc_attrs.runtime_el != MODE_EL1) && + (spmc_attrs.runtime_el != MODE_EL2)) { + WARN("Unsupported SPM core run time EL%x specified in " + "manifest image provided by BL2 boot loader.\n", + spmc_attrs.runtime_el); + goto error; + } + + INFO("SPM core run time EL%x.\n", spmc_attrs.runtime_el); + + /* Validate the SPM core execution state */ + if ((spmc_attrs.exec_state != MODE_RW_64) && + (spmc_attrs.exec_state != MODE_RW_32)) { + WARN("Unsupported SPM core execution state %x specified in " + "manifest image provided by BL2 boot loader.\n", + spmc_attrs.exec_state); + goto error; + } + + INFO("SPM core execution state %x.\n", spmc_attrs.exec_state); + + /* Ensure manifest has not requested S-EL2 in AArch32 state */ + if ((spmc_attrs.exec_state == MODE_RW_32) && + (spmc_attrs.runtime_el == MODE_EL2)) { + WARN("Invalid combination of SPM core execution state (%x) " + "and run time EL (%x).\n", spmc_attrs.exec_state, + spmc_attrs.runtime_el); + goto error; + } + + /* + * Check if S-EL2 is supported on this system if S-EL2 + * is required for SPM + */ + if (spmc_attrs.runtime_el == MODE_EL2) { + uint64_t sel2 = read_id_aa64pfr0_el1(); + + sel2 >>= ID_AA64PFR0_SEL2_SHIFT; + sel2 &= ID_AA64PFR0_SEL2_MASK; + + if (!sel2) { + WARN("SPM core run time EL: S-EL%x is not supported " + "but specified in manifest image provided by " + "BL2 boot loader.\n", spmc_attrs.runtime_el); + goto error; + } + } + + /* Initialise an entrypoint to set up the CPU context */ + ep_attr = SECURE | EP_ST_ENABLE; + if (read_sctlr_el3() & SCTLR_EE_BIT) + ep_attr |= EP_EE_BIG; + SET_PARAM_HEAD(spmc_ep_info, PARAM_EP, VERSION_1, ep_attr); + assert(spmc_ep_info->pc == BL32_BASE); + + /* + * Populate SPSR for SPM core based upon validated parameters from the + * manifest + */ + if (spmc_attrs.exec_state == MODE_RW_32) { + spmc_ep_info->spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM, + SPSR_E_LITTLE, + DAIF_FIQ_BIT | + DAIF_IRQ_BIT | + DAIF_ABT_BIT); + } else { + spmc_ep_info->spsr = SPSR_64(spmc_attrs.runtime_el, + MODE_SP_ELX, + DISABLE_ALL_EXCEPTIONS); + } + + /* Initialise SPM core context with this entry point information */ + cm_setup_context(&(spm_core_context[plat_my_core_pos()].cpu_ctx), + spmc_ep_info); + + INFO("SPM core setup done.\n"); + + /* Register init function for deferred init. */ + bl31_register_bl32_init(&spmd_init); + + return 0; + +error: + WARN("Booting device without SPM initialization. " + "SPCI SMCs destined for SPM core will return " + "ENOTSUPPORTED\n"); + + rc = mmap_remove_dynamic_region(rd_base_align, rd_size_align); + if (rc < 0) { + ERROR("Error while unmapping SPM core manifest (%d).\n", + rc); + panic(); + } + + return 1; +} + +/******************************************************************************* + * This function handles all SMCs in the range reserved for SPCI. Each call is + * either forwarded to the other security state or handled by the SPM dispatcher + ******************************************************************************/ +uint64_t spmd_smc_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 in_sstate; + uint32_t out_sstate; + int32_t ret; + spmd_spm_core_context_t *ctx = &spm_core_context[plat_my_core_pos()]; + + /* Determine which security state this SMC originated from */ + if (is_caller_secure(flags)) { + in_sstate = SECURE; + out_sstate = NON_SECURE; + } else { + in_sstate = NON_SECURE; + out_sstate = SECURE; + } + + INFO("SPM: 0x%x, 0x%llx, 0x%llx, 0x%llx, 0x%llx, " + "0x%llx, 0x%llx, 0x%llx\n", + 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 SPCI_ERROR: + /* + * Check if this is the first invocation of this interface on + * this CPU. If so, then indicate that the SPM core initialised + * unsuccessfully. + */ + if ((in_sstate == SECURE) && (ctx->state == SPMC_STATE_RESET)) + spmd_spm_core_sync_exit(x2); + + /* Save incoming security state */ + cm_el1_sysregs_context_save(in_sstate); + + /* Restore outgoing security state */ + cm_el1_sysregs_context_restore(out_sstate); + cm_set_next_eret_context(out_sstate); + + SMC_RET8(cm_get_context(out_sstate), 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)); + break; /* not reached */ + + case SPCI_VERSION: + /* + * TODO: This is an optimization that the version information + * provided by the SPM core manifest is returned by the SPM + * dispatcher. It might be a better idea to simply forward this + * call to the SPM core and wash our hands completely. + */ + ret = MAKE_SPCI_VERSION(spmc_attrs.major_version, + spmc_attrs.minor_version); + SMC_RET8(handle, SPCI_SUCCESS_SMC32, SPCI_TARGET_INFO_MBZ, ret, + SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, + SPCI_PARAM_MBZ, SPCI_PARAM_MBZ); + break; /* not reached */ + + case SPCI_FEATURES: + /* + * This is an optional interface. Do the minimal checks and + * forward to SPM core which will handle it if implemented. + */ + + /* + * Check if w1 holds a valid SPCI fid. This is an + * optimization. + */ + if (!is_spci_fid(x1)) + SMC_RET8(handle, SPCI_ERROR, + SPCI_TARGET_INFO_MBZ, SPCI_ERROR_NOT_SUPPORTED, + SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, + SPCI_PARAM_MBZ, SPCI_PARAM_MBZ); + + /* Forward SMC from Normal world to the SPM core */ + if (in_sstate == NON_SECURE) { + /* Save incoming security state */ + cm_el1_sysregs_context_save(in_sstate); + + /* Restore outgoing security state */ + cm_el1_sysregs_context_restore(out_sstate); + cm_set_next_eret_context(out_sstate); + + SMC_RET8(cm_get_context(out_sstate), 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)); + } else { + /* + * Return success if call was from secure world i.e. all + * SPCI functions are supported. This is essentially a + * nop. + */ + SMC_RET8(handle, SPCI_SUCCESS_SMC32, 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)); + } + break; /* not reached */ + + case SPCI_RX_RELEASE: + case SPCI_RXTX_MAP_SMC32: + case SPCI_RXTX_MAP_SMC64: + case SPCI_RXTX_UNMAP: + case SPCI_MSG_RUN: + /* This interface must be invoked only by the Normal world */ + if (in_sstate == SECURE) { + SMC_RET8(handle, SPCI_ERROR, + SPCI_TARGET_INFO_MBZ, SPCI_ERROR_NOT_SUPPORTED, + SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, + SPCI_PARAM_MBZ, SPCI_PARAM_MBZ); + } + + /* Fall through to forward the call to the other world */ + + case SPCI_PARTITION_INFO_GET: + case SPCI_MSG_SEND: + case SPCI_MSG_SEND_DIRECT_REQ_SMC32: + case SPCI_MSG_SEND_DIRECT_REQ_SMC64: + case SPCI_MSG_SEND_DIRECT_RESP_SMC32: + case SPCI_MSG_SEND_DIRECT_RESP_SMC64: + case SPCI_MEM_DONATE_SMC32: + case SPCI_MEM_DONATE_SMC64: + case SPCI_MEM_LEND_SMC32: + case SPCI_MEM_LEND_SMC64: + case SPCI_MEM_SHARE_SMC32: + case SPCI_MEM_SHARE_SMC64: + case SPCI_MEM_RETRIEVE_REQ_SMC32: + case SPCI_MEM_RETRIEVE_REQ_SMC64: + case SPCI_MEM_RETRIEVE_RESP: + case SPCI_MEM_RELINQUISH: + case SPCI_MEM_RECLAIM: + case SPCI_SUCCESS_SMC32: + case SPCI_SUCCESS_SMC64: + /* + * TODO: Assume that no requests originate from EL3 at the + * moment. This will change if a SP service is required in + * response to secure interrupts targeted to EL3. Until then + * simply forward the call to the Normal world. + */ + + /* Save incoming security state */ + cm_el1_sysregs_context_save(in_sstate); + + /* Restore outgoing security state */ + cm_el1_sysregs_context_restore(out_sstate); + cm_set_next_eret_context(out_sstate); + + SMC_RET8(cm_get_context(out_sstate), 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)); + break; /* not reached */ + + case SPCI_MSG_WAIT: + /* + * Check if this is the first invocation of this interface on + * this CPU from the Secure world. If so, then indicate that the + * SPM core initialised successfully. + */ + if ((in_sstate == SECURE) && (ctx->state == SPMC_STATE_RESET)) { + spmd_spm_core_sync_exit(0); + } + + /* Intentional fall-through */ + + case SPCI_MSG_YIELD: + /* This interface must be invoked only by the Secure world */ + if (in_sstate == NON_SECURE) { + SMC_RET8(handle, SPCI_ERROR, + SPCI_TARGET_INFO_MBZ, SPCI_ERROR_NOT_SUPPORTED, + SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, + SPCI_PARAM_MBZ, SPCI_PARAM_MBZ); + } + + /* Save incoming security state */ + cm_el1_sysregs_context_save(in_sstate); + + /* Restore outgoing security state */ + cm_el1_sysregs_context_restore(out_sstate); + cm_set_next_eret_context(out_sstate); + + SMC_RET8(cm_get_context(out_sstate), 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)); + break; /* not reached */ + + default: + WARN("SPM: Unsupported call 0x%08x\n", smc_fid); + SMC_RET8(handle, SPCI_ERROR, + SPCI_TARGET_INFO_MBZ, SPCI_ERROR_NOT_SUPPORTED, + SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, + SPCI_PARAM_MBZ, SPCI_PARAM_MBZ); + } +} diff --git a/services/std_svc/spmd/spmd_private.h b/services/std_svc/spmd/spmd_private.h new file mode 100644 index 000000000..61b479a8b --- /dev/null +++ b/services/std_svc/spmd/spmd_private.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SPMD_PRIVATE_H +#define SPMD_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 SPMD_C_RT_CTX_X19 0x0 +#define SPMD_C_RT_CTX_X20 0x8 +#define SPMD_C_RT_CTX_X21 0x10 +#define SPMD_C_RT_CTX_X22 0x18 +#define SPMD_C_RT_CTX_X23 0x20 +#define SPMD_C_RT_CTX_X24 0x28 +#define SPMD_C_RT_CTX_X25 0x30 +#define SPMD_C_RT_CTX_X26 0x38 +#define SPMD_C_RT_CTX_X27 0x40 +#define SPMD_C_RT_CTX_X28 0x48 +#define SPMD_C_RT_CTX_X29 0x50 +#define SPMD_C_RT_CTX_X30 0x58 + +#define SPMD_C_RT_CTX_SIZE 0x60 +#define SPMD_C_RT_CTX_ENTRIES (SPMD_C_RT_CTX_SIZE >> DWORD_SHIFT) + +#ifndef __ASSEMBLER__ +#include +#include + +/* + * Convert a function no. in a FID to a bit position. All function nos. are + * between 0 and 0x1f + */ +#define SPCI_FNO_TO_BIT_POS(_fid) (1 << ((_fid) & U(0x1f))) + +typedef enum spmc_state { + SPMC_STATE_RESET = 0, + SPMC_STATE_IDLE +} spmc_state_t; + +/* + * Data structure used by the SPM dispatcher (SPMD) in EL3 to track context of + * the SPM core (SPMC) at the next lower EL. + */ +typedef struct spmd_spm_core_context { + uint64_t c_rt_ctx; + cpu_context_t cpu_ctx; + spmc_state_t state; +} spmd_spm_core_context_t; + +/* + * Data structure used by the SPM dispatcher (SPMD) in EL3 to track sequence of + * SPCI calls from lower ELs. + * + * next_smc_bit_map: Per-cpu bit map of SMCs from each world that are expected + * next. + */ +typedef struct spmd_spci_context { + uint32_t next_smc_bit_map[2]; +} spmd_spci_context_t; + +/* Functions used to enter/exit a Secure Partition synchronously */ +uint64_t spmd_spm_core_sync_entry(spmd_spm_core_context_t *ctx); +__dead2 void spmd_spm_core_sync_exit(uint64_t rc); + +/* Assembly helpers */ +uint64_t spmd_spm_core_enter(uint64_t *c_rt_ctx); +void __dead2 spmd_spm_core_exit(uint64_t c_rt_ctx, uint64_t ret); + +#endif /* __ASSEMBLER__ */ + +#endif /* SPMD_PRIVATE_H */ -- cgit v1.2.3 From 2a7b403de55705de7354cf4077064ef857c31ce2 Mon Sep 17 00:00:00 2001 From: Achin Gupta Date: Fri, 11 Oct 2019 15:49:00 +0100 Subject: SPMD: hook SPMD into standard services framework This patch adds support to initialise the SPM dispatcher as a standard secure service. It also registers a handler for SPCI SMCs exported by the SPM dispatcher. Signed-off-by: Achin Gupta Signed-off-by: Artsem Artsemenka Change-Id: I2183adf826d08ff3fee9aee75f021021162b6477 --- services/std_svc/std_svc_setup.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/services/std_svc/std_svc_setup.c b/services/std_svc/std_svc_setup.c index 7787a2fa2..895fd292f 100644 --- a/services/std_svc/std_svc_setup.c +++ b/services/std_svc/std_svc_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -51,6 +52,12 @@ static int32_t std_svc_setup(void) } #endif +#if defined(SPD_spmd) + if (spmd_setup() != 0) { + ret = 1; + } +#endif + #if SDEI_SUPPORT /* SDEI initialisation */ sdei_init(); @@ -114,6 +121,17 @@ static uintptr_t std_svc_smc_handler(uint32_t smc_fid, } #endif +#if defined(SPD_spmd) + /* + * Dispatch SPCI calls to the SPCI SMC handler implemented by the SPM + * dispatcher and return its return value + */ + if (is_spci_fid(smc_fid)) { + return spmd_smc_handler(smc_fid, x1, x2, x3, x4, cookie, + handle, flags); + } +#endif + #if SDEI_SUPPORT if (is_sdei_fid(smc_fid)) { return sdei_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, -- cgit v1.2.3 From c3fb00d93ee734e60dea4f13f7f7a80eadb9cfa9 Mon Sep 17 00:00:00 2001 From: Achin Gupta Date: Fri, 11 Oct 2019 15:50:43 +0100 Subject: SPMD: enable SPM dispatcher support This patch adds support to the build system to include support for the SPM dispatcher when the SPD configuration option is spmd. Signed-off-by: Achin Gupta Signed-off-by: Artsem Artsemenka Change-Id: Ic1ae50ecd7403fcbcf1d318abdbd6ebdc642f732 --- Makefile | 15 ++++++++++++--- bl31/bl31.mk | 1 + plat/arm/common/arm_common.mk | 7 +++++++ 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 5167d2e53..0d8ddd8e1 100644 --- a/Makefile +++ b/Makefile @@ -418,11 +418,20 @@ ifdef EL3_PAYLOAD_BASE $(warning "SPD and EL3_PAYLOAD_BASE are incompatible build options.") $(warning "The SPD and its BL32 companion will be present but ignored.") endif - # We expect to locate an spd.mk under the specified SPD directory - SPD_MAKE := $(wildcard services/spd/${SPD}/${SPD}.mk) + ifeq (${SPD},spmd) + # SPMD is located in std_svc directory + SPD_DIR := std_svc + else + # All other SPDs in spd directory + SPD_DIR := spd + endif + + # We expect to locate an spd.mk under the specified SPD directory + SPD_MAKE := $(wildcard services/${SPD_DIR}/${SPD}/${SPD}.mk) + ifeq (${SPD_MAKE},) - $(error Error: No services/spd/${SPD}/${SPD}.mk located) + $(error Error: No services/${SPD_DIR}/${SPD}/${SPD}.mk located) endif $(info Including ${SPD_MAKE}) include ${SPD_MAKE} diff --git a/bl31/bl31.mk b/bl31/bl31.mk index 58909e84a..0948e94e0 100644 --- a/bl31/bl31.mk +++ b/bl31/bl31.mk @@ -31,6 +31,7 @@ BL31_SOURCES += bl31/bl31_main.c \ services/arm_arch_svc/arm_arch_svc_setup.c \ services/std_svc/std_svc_setup.c \ ${PSCI_LIB_SOURCES} \ + ${SPMD_SOURCES} \ ${SPM_SOURCES} diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index 9f4bc2107..d2578b777 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -265,6 +265,13 @@ PLAT_BL_COMMON_SOURCES += plat/arm/common/aarch64/arm_pauth.c \ lib/extensions/pauth/pauth_helpers.S endif +ifeq (${SPD},spmd) +BL31_SOURCES += plat/common/plat_spmd_manifest.c \ + common/fdt_wrappers.c \ + ${LIBFDT_SRCS} + +endif + ifneq (${TRUSTED_BOARD_BOOT},0) # Include common TBB sources -- cgit v1.2.3 From 698e231d928752e7877bfd5482c0fca6509108cc Mon Sep 17 00:00:00 2001 From: Max Shvetsov Date: Tue, 11 Feb 2020 12:41:08 +0000 Subject: Fixes ROTPK hash generation for ECDSA encryption Forced hash generation used to always generate hash via RSA encryption. This patch changes encryption based on ARM_ROTPK_LOCATION. Also removes setting KEY_ALG based on ARM_ROTPL_LOCATION - there is no relation between these two. Signed-off-by: Max Shvetsov Change-Id: Id727d2ed06176a243719fd0adfa0cae26c325005 --- plat/arm/board/common/board_common.mk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plat/arm/board/common/board_common.mk b/plat/arm/board/common/board_common.mk index da6343045..459156b2a 100644 --- a/plat/arm/board/common/board_common.mk +++ b/plat/arm/board/common/board_common.mk @@ -17,7 +17,7 @@ ifneq (${ARM_CRYPTOCELL_INTEG}, 1) ifeq (${ARM_ROTPK_LOCATION}, regs) ARM_ROTPK_LOCATION_ID = ARM_ROTPK_REGS_ID else ifeq (${ARM_ROTPK_LOCATION}, devel_rsa) - KEY_ALG := rsa + CRYPTO_ALG=rsa ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_RSA_ID ARM_ROTPK_HASH = plat/arm/board/common/rotpk/arm_rotpk_rsa_sha256.bin $(eval $(call add_define_val,ARM_ROTPK_HASH,'"$(ARM_ROTPK_HASH)"')) @@ -25,7 +25,7 @@ $(BUILD_PLAT)/bl2/arm_dev_rotpk.o : $(ARM_ROTPK_HASH) $(warning Development keys support for FVP is deprecated. Use `regs` \ option instead) else ifeq (${ARM_ROTPK_LOCATION}, devel_ecdsa) - KEY_ALG := ecdsa + CRYPTO_ALG=ec ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_ECDSA_ID ARM_ROTPK_HASH = plat/arm/board/common/rotpk/arm_rotpk_ecdsa_sha256.bin $(eval $(call add_define_val,ARM_ROTPK_HASH,'"$(ARM_ROTPK_HASH)"')) @@ -50,7 +50,7 @@ $(ARM_ROTPK_HASH) : $(HASH_PREREQUISITES) ifndef ROT_KEY $(error Cannot generate hash: no ROT_KEY defined) endif - openssl rsa -in $< -pubout -outform DER | openssl dgst \ + openssl ${CRYPTO_ALG} -in $< -pubout -outform DER | openssl dgst \ -sha256 -binary > $@ # Certificate NV-Counters. Use values corresponding to tied off values in -- cgit v1.2.3 From 070dcbf53236a0cdf0487692feefd914ac5f4a42 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 3 Feb 2020 19:30:11 +0900 Subject: uniphier: make eMMC controller base address configurable The next SoC supports the same eMMC controller, but the register base will be changed. Make it configurable. Change-Id: I00cb5531bc3d8d49357ad5e922cdd3d785355edf Signed-off-by: Masahiro Yamada --- plat/socionext/uniphier/uniphier.h | 3 ++- plat/socionext/uniphier/uniphier_emmc.c | 35 ++++++++++++++++++++------- plat/socionext/uniphier/uniphier_io_storage.c | 4 +-- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/plat/socionext/uniphier/uniphier.h b/plat/socionext/uniphier/uniphier.h index 9deb3163b..8d5aa86ac 100644 --- a/plat/socionext/uniphier/uniphier.h +++ b/plat/socionext/uniphier/uniphier.h @@ -38,7 +38,8 @@ unsigned int uniphier_get_boot_master(unsigned int soc); void uniphier_console_setup(void); struct io_block_dev_spec; -int uniphier_emmc_init(struct io_block_dev_spec **block_dev_spec); +int uniphier_emmc_init(unsigned int soc, + struct io_block_dev_spec **block_dev_spec); int uniphier_nand_init(struct io_block_dev_spec **block_dev_spec); int uniphier_usb_init(unsigned int soc, struct io_block_dev_spec **block_dev_spec); diff --git a/plat/socionext/uniphier/uniphier_emmc.c b/plat/socionext/uniphier/uniphier_emmc.c index 538a7f097..b3d23cbed 100644 --- a/plat/socionext/uniphier/uniphier_emmc.c +++ b/plat/socionext/uniphier/uniphier_emmc.c @@ -87,7 +87,12 @@ struct uniphier_mmc_cmd { unsigned int is_data; }; -static bool uniphier_emmc_block_addressing; +struct uniphier_emmc_host { + uintptr_t base; + bool is_block_addressing; +}; + +static struct uniphier_emmc_host uniphier_emmc_host; static int uniphier_emmc_send_cmd(uintptr_t host_base, struct uniphier_mmc_cmd *cmd) @@ -214,15 +219,15 @@ static int uniphier_emmc_load_image(uintptr_t host_base, static size_t uniphier_emmc_read(int lba, uintptr_t buf, size_t size) { - uintptr_t host_base = 0x5a000200; int ret; inv_dcache_range(buf, size); - if (!uniphier_emmc_block_addressing) + if (!uniphier_emmc_host.is_block_addressing) lba *= 512; - ret = uniphier_emmc_load_image(host_base, lba, buf, size / 512); + ret = uniphier_emmc_load_image(uniphier_emmc_host.base, + lba, buf, size / 512); inv_dcache_range(buf, size); @@ -236,10 +241,10 @@ static struct io_block_dev_spec uniphier_emmc_dev_spec = { .block_size = 512, }; -static int uniphier_emmc_hw_init(void) +static int uniphier_emmc_hw_init(struct uniphier_emmc_host *host) { - uintptr_t host_base = 0x5a000200; struct uniphier_mmc_cmd cmd = {0}; + uintptr_t host_base = uniphier_emmc_host.base; int ret; /* @@ -258,7 +263,7 @@ static int uniphier_emmc_hw_init(void) ; ret = uniphier_emmc_check_device_size(host_base, - &uniphier_emmc_block_addressing); + &uniphier_emmc_host.is_block_addressing); if (ret) return ret; @@ -277,11 +282,23 @@ static int uniphier_emmc_hw_init(void) return 0; } -int uniphier_emmc_init(struct io_block_dev_spec **block_dev_spec) +static const uintptr_t uniphier_emmc_base[] = { + [UNIPHIER_SOC_LD11] = 0x5a000200, + [UNIPHIER_SOC_LD20] = 0x5a000200, + [UNIPHIER_SOC_PXS3] = 0x5a000200, +}; + +int uniphier_emmc_init(unsigned int soc, + struct io_block_dev_spec **block_dev_spec) { int ret; - ret = uniphier_emmc_hw_init(); + assert(soc < ARRAY_SIZE(uniphier_emmc_base)); + uniphier_emmc_host.base = uniphier_emmc_base[soc]; + if (uniphier_emmc_host.base == 0UL) + return -ENOTSUP; + + ret = uniphier_emmc_hw_init(&uniphier_emmc_host); if (ret) return ret; diff --git a/plat/socionext/uniphier/uniphier_io_storage.c b/plat/socionext/uniphier/uniphier_io_storage.c index 89c8718b4..b2e2c5515 100644 --- a/plat/socionext/uniphier/uniphier_io_storage.c +++ b/plat/socionext/uniphier/uniphier_io_storage.c @@ -249,12 +249,12 @@ static int uniphier_io_fip_setup(void) return io_dev_open(uniphier_fip_dev_con, 0, &uniphier_fip_dev_handle); } -static int uniphier_io_emmc_setup(unsigned int soc_id, size_t buffer_offset) +static int uniphier_io_emmc_setup(unsigned int soc, size_t buffer_offset) { struct io_block_dev_spec *block_dev_spec; int ret; - ret = uniphier_emmc_init(&block_dev_spec); + ret = uniphier_emmc_init(soc, &block_dev_spec); if (ret) return ret; -- cgit v1.2.3 From bda9cd70a702b652de318b369ef7b55202fbf49b Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 3 Feb 2020 19:30:27 +0900 Subject: uniphier: make NAND controller base address configurable The next SoC does not support the NAND controller, but make the base address configurable for consistency and future proof. Change-Id: I776e43ff2b0408577919b0b72849c3e1e5ce0758 Signed-off-by: Masahiro Yamada --- plat/socionext/uniphier/uniphier.h | 3 ++- plat/socionext/uniphier/uniphier_io_storage.c | 4 ++-- plat/socionext/uniphier/uniphier_nand.c | 18 +++++++++++++++--- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/plat/socionext/uniphier/uniphier.h b/plat/socionext/uniphier/uniphier.h index 8d5aa86ac..808b850d6 100644 --- a/plat/socionext/uniphier/uniphier.h +++ b/plat/socionext/uniphier/uniphier.h @@ -40,7 +40,8 @@ void uniphier_console_setup(void); struct io_block_dev_spec; int uniphier_emmc_init(unsigned int soc, struct io_block_dev_spec **block_dev_spec); -int uniphier_nand_init(struct io_block_dev_spec **block_dev_spec); +int uniphier_nand_init(unsigned int soc, + struct io_block_dev_spec **block_dev_spec); int uniphier_usb_init(unsigned int soc, struct io_block_dev_spec **block_dev_spec); diff --git a/plat/socionext/uniphier/uniphier_io_storage.c b/plat/socionext/uniphier/uniphier_io_storage.c index b2e2c5515..96180f159 100644 --- a/plat/socionext/uniphier/uniphier_io_storage.c +++ b/plat/socionext/uniphier/uniphier_io_storage.c @@ -261,12 +261,12 @@ static int uniphier_io_emmc_setup(unsigned int soc, size_t buffer_offset) return uniphier_io_block_setup(0x20000, block_dev_spec, buffer_offset); } -static int uniphier_io_nand_setup(unsigned int soc_id, size_t buffer_offset) +static int uniphier_io_nand_setup(unsigned int soc, size_t buffer_offset) { struct io_block_dev_spec *block_dev_spec; int ret; - ret = uniphier_nand_init(&block_dev_spec); + ret = uniphier_nand_init(soc, &block_dev_spec); if (ret) return ret; diff --git a/plat/socionext/uniphier/uniphier_nand.c b/plat/socionext/uniphier/uniphier_nand.c index 3925177ed..71cb96c0a 100644 --- a/plat/socionext/uniphier/uniphier_nand.c +++ b/plat/socionext/uniphier/uniphier_nand.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include #include #include @@ -237,8 +238,7 @@ static int uniphier_nand_hw_init(struct uniphier_nand *nand) for (i = 0; i < ARRAY_SIZE(nand->bbt); i++) nand->bbt[i] = UNIPHIER_NAND_BBT_UNKNOWN; - nand->host_base = 0x68000000; - nand->reg_base = 0x68100000; + nand->reg_base = nand->host_base + 0x100000; nand->pages_per_block = mmio_read_32(nand->reg_base + DENALI_PAGES_PER_BLOCK); @@ -255,10 +255,22 @@ static int uniphier_nand_hw_init(struct uniphier_nand *nand) return 0; } -int uniphier_nand_init(struct io_block_dev_spec **block_dev_spec) +static const uintptr_t uniphier_nand_base[] = { + [UNIPHIER_SOC_LD11] = 0x68000000, + [UNIPHIER_SOC_LD20] = 0x68000000, + [UNIPHIER_SOC_PXS3] = 0x68000000, +}; + +int uniphier_nand_init(unsigned int soc, + struct io_block_dev_spec **block_dev_spec) { int ret; + assert(soc < ARRAY_SIZE(uniphier_nand_base)); + uniphier_nand.host_base = uniphier_nand_base[soc]; + if (!uniphier_nand.host_base) + return -ENOTSUP; + ret = uniphier_nand_hw_init(&uniphier_nand); if (ret) return ret; -- cgit v1.2.3 From 2d431df8b5ef2e6f751c95dd3f4d8610d29d3379 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 3 Feb 2020 19:33:35 +0900 Subject: uniphier: make pinmon base address configurable The register base will be changed in the next SoC. Make it configurable. Change-Id: I9fbb6bdd1cf06207618742d4ad7970d911c9bc26 Signed-off-by: Masahiro Yamada --- plat/socionext/uniphier/uniphier_boot_device.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/plat/socionext/uniphier/uniphier_boot_device.c b/plat/socionext/uniphier/uniphier_boot_device.c index 517ec96a4..36a9908be 100644 --- a/plat/socionext/uniphier/uniphier_boot_device.c +++ b/plat/socionext/uniphier/uniphier_boot_device.c @@ -13,8 +13,14 @@ #include "uniphier.h" -#define UNIPHIER_PINMON0 0x5f900100 -#define UNIPHIER_PINMON2 0x5f900108 +#define UNIPHIER_PINMON0 0x0 +#define UNIPHIER_PINMON2 0x8 + +static const uintptr_t uniphier_pinmon_base[] = { + [UNIPHIER_SOC_LD11] = 0x5f900100, + [UNIPHIER_SOC_LD20] = 0x5f900100, + [UNIPHIER_SOC_PXS3] = 0x5f900100, +}; static bool uniphier_ld11_is_usb_boot(uint32_t pinmon) { @@ -28,7 +34,8 @@ static bool uniphier_ld20_is_usb_boot(uint32_t pinmon) static bool uniphier_pxs3_is_usb_boot(uint32_t pinmon) { - uint32_t pinmon2 = mmio_read_32(UNIPHIER_PINMON2); + uintptr_t pinmon_base = uniphier_pinmon_base[UNIPHIER_SOC_PXS3]; + uint32_t pinmon2 = mmio_read_32(pinmon_base + UNIPHIER_PINMON2); return !!(pinmon2 & BIT(31)); } @@ -133,12 +140,16 @@ static const struct uniphier_boot_device_info uniphier_boot_device_info[] = { unsigned int uniphier_get_boot_device(unsigned int soc) { const struct uniphier_boot_device_info *info; + uintptr_t pinmon_base; uint32_t pinmon; assert(soc < ARRAY_SIZE(uniphier_boot_device_info)); info = &uniphier_boot_device_info[soc]; - pinmon = mmio_read_32(UNIPHIER_PINMON0); + assert(soc < ARRAY_SIZE(uniphier_boot_device_info)); + pinmon_base = uniphier_pinmon_base[soc]; + + pinmon = mmio_read_32(pinmon_base + UNIPHIER_PINMON0); if (info->have_boot_swap && !(pinmon & BIT(29))) return UNIPHIER_BOOT_DEVICE_NOR; @@ -163,7 +174,12 @@ unsigned int uniphier_get_boot_master(unsigned int soc) assert(soc < ARRAY_SIZE(uniphier_have_onchip_scp)); if (uniphier_have_onchip_scp[soc]) { - if (mmio_read_32(UNIPHIER_PINMON0) & BIT(27)) + uintptr_t pinmon_base; + + assert(soc < ARRAY_SIZE(uniphier_boot_device_info)); + pinmon_base = uniphier_pinmon_base[soc]; + + if (mmio_read_32(pinmon_base + UNIPHIER_PINMON0) & BIT(27)) return UNIPHIER_BOOT_MASTER_THIS; else return UNIPHIER_BOOT_MASTER_SCP; -- cgit v1.2.3 From 4511322f6e8de02d84cc23460dc874f679f088e8 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 3 Feb 2020 19:45:16 +0900 Subject: uniphier: make UART base address configurable The next SoC supports the same UART, but the register base will be changed. Make it configurable. Change-Id: Ida5c9151b2f3554afd15555b22838437eef443f7 Signed-off-by: Masahiro Yamada --- plat/socionext/uniphier/tsp/uniphier_tsp_setup.c | 11 +++++++++- plat/socionext/uniphier/uniphier.h | 2 +- plat/socionext/uniphier/uniphier_bl2_setup.c | 18 +++++++--------- plat/socionext/uniphier/uniphier_bl31_setup.c | 19 +++++++---------- plat/socionext/uniphier/uniphier_console_setup.c | 27 +++++++++++++++++------- 5 files changed, 46 insertions(+), 31 deletions(-) diff --git a/plat/socionext/uniphier/tsp/uniphier_tsp_setup.c b/plat/socionext/uniphier/tsp/uniphier_tsp_setup.c index 4f58b683c..5ea6e9474 100644 --- a/plat/socionext/uniphier/tsp/uniphier_tsp_setup.c +++ b/plat/socionext/uniphier/tsp/uniphier_tsp_setup.c @@ -4,16 +4,25 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include + #include #include #include +#include #include "../uniphier.h" +static unsigned int uniphier_soc = UNIPHIER_SOC_UNKNOWN; + void tsp_early_platform_setup(void) { - uniphier_console_setup(); + uniphier_soc = uniphier_get_soc_id(); + if (uniphier_soc == UNIPHIER_SOC_UNKNOWN) + plat_error_handler(-ENOTSUP); + + uniphier_console_setup(uniphier_soc); } void tsp_platform_setup(void) diff --git a/plat/socionext/uniphier/uniphier.h b/plat/socionext/uniphier/uniphier.h index 808b850d6..f8aa65ab7 100644 --- a/plat/socionext/uniphier/uniphier.h +++ b/plat/socionext/uniphier/uniphier.h @@ -35,7 +35,7 @@ unsigned int uniphier_get_boot_master(unsigned int soc); #define UNIPHIER_BOOT_MASTER_SCP 1 #define UNIPHIER_BOOT_MASTER_EXT 2 -void uniphier_console_setup(void); +void uniphier_console_setup(unsigned int soc); struct io_block_dev_spec; int uniphier_emmc_init(unsigned int soc, diff --git a/plat/socionext/uniphier/uniphier_bl2_setup.c b/plat/socionext/uniphier/uniphier_bl2_setup.c index 11d837cf4..9c8d2daad 100644 --- a/plat/socionext/uniphier/uniphier_bl2_setup.c +++ b/plat/socionext/uniphier/uniphier_bl2_setup.c @@ -25,17 +25,21 @@ #define UNIPHIER_IMAGE_BUF_SIZE 0x00100000UL static uintptr_t uniphier_mem_base = UNIPHIER_MEM_BASE; +static unsigned int uniphier_soc = UNIPHIER_SOC_UNKNOWN; static int uniphier_bl2_kick_scp; void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1, u_register_t x2, u_register_t x3) { - uniphier_console_setup(); + uniphier_soc = uniphier_get_soc_id(); + if (uniphier_soc == UNIPHIER_SOC_UNKNOWN) + plat_error_handler(-ENOTSUP); + + uniphier_console_setup(uniphier_soc); } void bl2_el3_plat_arch_setup(void) { - unsigned int soc; int skip_scp = 0; int ret; @@ -45,19 +49,13 @@ void bl2_el3_plat_arch_setup(void) /* add relocation offset (run-time-address - link-address) */ uniphier_mem_base += BL_CODE_BASE - BL2_BASE; - soc = uniphier_get_soc_id(); - if (soc == UNIPHIER_SOC_UNKNOWN) { - ERROR("unsupported SoC\n"); - plat_error_handler(-ENOTSUP); - } - - ret = uniphier_io_setup(soc, uniphier_mem_base); + ret = uniphier_io_setup(uniphier_soc, uniphier_mem_base); if (ret) { ERROR("failed to setup io devices\n"); plat_error_handler(ret); } - switch (uniphier_get_boot_master(soc)) { + switch (uniphier_get_boot_master(uniphier_soc)) { case UNIPHIER_BOOT_MASTER_THIS: INFO("Booting from this SoC\n"); skip_scp = 1; diff --git a/plat/socionext/uniphier/uniphier_bl31_setup.c b/plat/socionext/uniphier/uniphier_bl31_setup.c index 47f2378bc..a25d6b751 100644 --- a/plat/socionext/uniphier/uniphier_bl31_setup.c +++ b/plat/socionext/uniphier/uniphier_bl31_setup.c @@ -21,6 +21,7 @@ static entry_point_info_t bl32_image_ep_info; static entry_point_info_t bl33_image_ep_info; +static unsigned int uniphier_soc = UNIPHIER_SOC_UNKNOWN; entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) { @@ -37,7 +38,11 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, bl_params_node_t *bl_params = ((bl_params_t *)from_bl2)->head; - uniphier_console_setup(); + uniphier_soc = uniphier_get_soc_id(); + if (uniphier_soc == UNIPHIER_SOC_UNKNOWN) + plat_error_handler(-ENOTSUP); + + uniphier_console_setup(uniphier_soc); while (bl_params) { if (bl_params->image_id == BL32_IMAGE_ID) @@ -57,19 +62,11 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, void bl31_platform_setup(void) { - unsigned int soc; - - soc = uniphier_get_soc_id(); - if (soc == UNIPHIER_SOC_UNKNOWN) { - ERROR("unsupported SoC\n"); - plat_error_handler(-ENOTSUP); - } - - uniphier_cci_init(soc); + uniphier_cci_init(uniphier_soc); uniphier_cci_enable(); /* Initialize the GIC driver, cpu and distributor interfaces */ - uniphier_gic_driver_init(soc); + uniphier_gic_driver_init(uniphier_soc); uniphier_gic_init(); /* Enable and initialize the System level generic timer */ diff --git a/plat/socionext/uniphier/uniphier_console_setup.c b/plat/socionext/uniphier/uniphier_console_setup.c index 64ee79714..1851e4da5 100644 --- a/plat/socionext/uniphier/uniphier_console_setup.c +++ b/plat/socionext/uniphier/uniphier_console_setup.c @@ -1,9 +1,11 @@ /* - * Copyright (c) 2019, Socionext Inc. All rights reserved. + * Copyright (c) 2019-2020, Socionext Inc. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ +#include + #include #include #include @@ -12,9 +14,8 @@ #include "uniphier.h" #include "uniphier_console.h" -#define UNIPHIER_UART_BASE 0x54006800 -#define UNIPHIER_UART_END 0x54006c00 #define UNIPHIER_UART_OFFSET 0x100 +#define UNIPHIER_UART_NR_PORTS 4 struct uniphier_console { struct console console; @@ -40,16 +41,26 @@ static struct uniphier_console uniphier_console = { }, }; +static const uintptr_t uniphier_uart_base[] = { + [UNIPHIER_SOC_LD11] = 0x54006800, + [UNIPHIER_SOC_LD20] = 0x54006800, + [UNIPHIER_SOC_PXS3] = 0x54006800, +}; + /* * There are 4 UART ports available on this platform. By default, we want to * use the same one as used in the previous firmware stage. */ -static uintptr_t uniphier_console_get_base(void) +static uintptr_t uniphier_console_get_base(unsigned int soc) { - uintptr_t base = UNIPHIER_UART_BASE; + uintptr_t base, end; uint32_t div; - while (base < UNIPHIER_UART_END) { + assert(soc < ARRAY_SIZE(uniphier_uart_base)); + base = uniphier_uart_base[soc]; + end = base + UNIPHIER_UART_OFFSET * UNIPHIER_UART_NR_PORTS; + + while (base < end) { div = mmio_read_32(base + UNIPHIER_UART_DLR); if (div) return base; @@ -66,11 +77,11 @@ static void uniphier_console_init(uintptr_t base) UNIPHIER_UART_LCR_WLEN8 << 8); } -void uniphier_console_setup(void) +void uniphier_console_setup(unsigned int soc) { uintptr_t base; - base = uniphier_console_get_base(); + base = uniphier_console_get_base(soc); if (!base) plat_error_handler(-EINVAL); -- cgit v1.2.3 From 43bbac27dcdd5f128d020e131b81e92358515dbc Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 28 Jan 2020 21:14:28 +0900 Subject: uniphier: change the return value type of .is_usb_boot() to bool This is boolean logic, so "bool" is more suitable. Change-Id: I439c5099770600a65b8f58390a4c621c2ee487a5 Signed-off-by: Masahiro Yamada --- plat/socionext/uniphier/uniphier_boot_device.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plat/socionext/uniphier/uniphier_boot_device.c b/plat/socionext/uniphier/uniphier_boot_device.c index 462c0859c..ce9caa985 100644 --- a/plat/socionext/uniphier/uniphier_boot_device.c +++ b/plat/socionext/uniphier/uniphier_boot_device.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -16,17 +16,17 @@ #define UNIPHIER_PINMON0 0x5f900100 #define UNIPHIER_PINMON2 0x5f900108 -static int uniphier_ld11_is_usb_boot(uint32_t pinmon) +static bool uniphier_ld11_is_usb_boot(uint32_t pinmon) { return !!(~pinmon & 0x00000080); } -static int uniphier_ld20_is_usb_boot(uint32_t pinmon) +static bool uniphier_ld20_is_usb_boot(uint32_t pinmon) { return !!(~pinmon & 0x00000780); } -static int uniphier_pxs3_is_usb_boot(uint32_t pinmon) +static bool uniphier_pxs3_is_usb_boot(uint32_t pinmon) { uint32_t pinmon2 = mmio_read_32(UNIPHIER_PINMON2); @@ -106,7 +106,7 @@ static unsigned int uniphier_pxs3_get_boot_device(uint32_t pinmon) } struct uniphier_boot_device_info { - int (*is_usb_boot)(uint32_t pinmon); + bool (*is_usb_boot)(uint32_t pinmon); unsigned int (*get_boot_device)(uint32_t pinmon); }; -- cgit v1.2.3 From 8d538f3df3c4c6ecbba26571bff121f4fef0bc3b Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 3 Feb 2020 19:45:37 +0900 Subject: uniphier: make counter control base address configurable The register base will be changed in the next SoC. Make it configurable. Change-Id: I4a7cf85fe50e4d71db58a3372a71774e43193bd3 Signed-off-by: Masahiro Yamada --- plat/socionext/uniphier/uniphier_bl31_setup.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/plat/socionext/uniphier/uniphier_bl31_setup.c b/plat/socionext/uniphier/uniphier_bl31_setup.c index a25d6b751..dac08fb54 100644 --- a/plat/socionext/uniphier/uniphier_bl31_setup.c +++ b/plat/socionext/uniphier/uniphier_bl31_setup.c @@ -58,10 +58,16 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, panic(); } -#define UNIPHIER_SYS_CNTCTL_BASE 0x60E00000 +static const uintptr_t uniphier_cntctl_base[] = { + [UNIPHIER_SOC_LD11] = 0x60e00000, + [UNIPHIER_SOC_LD20] = 0x60e00000, + [UNIPHIER_SOC_PXS3] = 0x60e00000, +}; void bl31_platform_setup(void) { + uintptr_t cntctl_base; + uniphier_cci_init(uniphier_soc); uniphier_cci_enable(); @@ -69,9 +75,11 @@ void bl31_platform_setup(void) uniphier_gic_driver_init(uniphier_soc); uniphier_gic_init(); + assert(uniphier_soc < ARRAY_SIZE(uniphier_cntctl_base)); + cntctl_base = uniphier_cntctl_base[uniphier_soc]; + /* Enable and initialize the System level generic timer */ - mmio_write_32(UNIPHIER_SYS_CNTCTL_BASE + CNTCR_OFF, - CNTCR_FCREQ(0U) | CNTCR_EN); + mmio_write_32(cntctl_base + CNTCR_OFF, CNTCR_FCREQ(0U) | CNTCR_EN); } void bl31_plat_arch_setup(void) -- cgit v1.2.3 From 1046c1cae27afa0b207373424d6ac3829140daba Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 3 Feb 2020 18:40:37 +0900 Subject: uniphier: change block_addressing flag to bool The flag, uniphier_emmc_block_addressing, is boolean logic, so "bool' is more suitable. uniphier_emmc_is_over_2gb() is not boolean - it returns 1 / 0 depending on the card density, or a negative value on failure. Rename it to make it less confusing. Change-Id: Ia646b1929147b644e0df07c46b54ab80548bc3bd Signed-off-by: Masahiro Yamada --- plat/socionext/uniphier/uniphier_emmc.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/plat/socionext/uniphier/uniphier_emmc.c b/plat/socionext/uniphier/uniphier_emmc.c index d666ba781..538a7f097 100644 --- a/plat/socionext/uniphier/uniphier_emmc.c +++ b/plat/socionext/uniphier/uniphier_emmc.c @@ -87,7 +87,7 @@ struct uniphier_mmc_cmd { unsigned int is_data; }; -static int uniphier_emmc_block_addressing; +static bool uniphier_emmc_block_addressing; static int uniphier_emmc_send_cmd(uintptr_t host_base, struct uniphier_mmc_cmd *cmd) @@ -157,7 +157,8 @@ static int uniphier_emmc_switch_part(uintptr_t host_base, int part_num) return uniphier_emmc_send_cmd(host_base, &cmd); } -static int uniphier_emmc_is_over_2gb(uintptr_t host_base) +static int uniphier_emmc_check_device_size(uintptr_t host_base, + bool *is_block_addressing) { struct uniphier_mmc_cmd cmd = {0}; uint32_t csd40, csd72; /* CSD[71:40], CSD[103:72] */ @@ -174,7 +175,10 @@ static int uniphier_emmc_is_over_2gb(uintptr_t host_base) csd40 = mmio_read_32(host_base + SDHCI_RESPONSE + 4); csd72 = mmio_read_32(host_base + SDHCI_RESPONSE + 8); - return !(~csd40 & 0xffc00380) && !(~csd72 & 0x3); + /* C_SIZE == 0xfff && C_SIZE_MULT == 0x7 ? */ + *is_block_addressing = !(~csd40 & 0xffc00380) && !(~csd72 & 0x3); + + return 0; } static int uniphier_emmc_load_image(uintptr_t host_base, @@ -253,12 +257,11 @@ static int uniphier_emmc_hw_init(void) while (mmio_read_8(host_base + SDHCI_SOFTWARE_RESET)) ; - ret = uniphier_emmc_is_over_2gb(host_base); - if (ret < 0) + ret = uniphier_emmc_check_device_size(host_base, + &uniphier_emmc_block_addressing); + if (ret) return ret; - uniphier_emmc_block_addressing = ret; - cmd.cmdarg = UNIPHIER_EMMC_RCA << 16; /* select card again */ -- cgit v1.2.3 From eea5b880ee995afce0814fb11eb50de1a35abefb Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 3 Feb 2020 19:46:00 +0900 Subject: uniphier: make PSCI related base address configurable The register base address will be changed in the next SoC. Make it configurable. Change-Id: Ibe07bd9db128b0f7e629916cb6ae21ba7984eca9 Signed-off-by: Masahiro Yamada --- plat/socionext/uniphier/uniphier.h | 2 + plat/socionext/uniphier/uniphier_bl31_setup.c | 2 + plat/socionext/uniphier/uniphier_psci.c | 68 ++++++++++++++++++--------- 3 files changed, 51 insertions(+), 21 deletions(-) diff --git a/plat/socionext/uniphier/uniphier.h b/plat/socionext/uniphier/uniphier.h index f8aa65ab7..b26bd65d2 100644 --- a/plat/socionext/uniphier/uniphier.h +++ b/plat/socionext/uniphier/uniphier.h @@ -69,6 +69,8 @@ void uniphier_gic_cpuif_enable(void); void uniphier_gic_cpuif_disable(void); void uniphier_gic_pcpu_init(void); +void uniphier_psci_init(unsigned int soc); + unsigned int uniphier_calc_core_pos(u_register_t mpidr); #endif /* UNIPHIER_H */ diff --git a/plat/socionext/uniphier/uniphier_bl31_setup.c b/plat/socionext/uniphier/uniphier_bl31_setup.c index dac08fb54..15ceed4bb 100644 --- a/plat/socionext/uniphier/uniphier_bl31_setup.c +++ b/plat/socionext/uniphier/uniphier_bl31_setup.c @@ -80,6 +80,8 @@ void bl31_platform_setup(void) /* Enable and initialize the System level generic timer */ mmio_write_32(cntctl_base + CNTCR_OFF, CNTCR_FCREQ(0U) | CNTCR_EN); + + uniphier_psci_init(uniphier_soc); } void bl31_plat_arch_setup(void) diff --git a/plat/socionext/uniphier/uniphier_psci.c b/plat/socionext/uniphier/uniphier_psci.c index 2acc87440..a371705b1 100644 --- a/plat/socionext/uniphier/uniphier_psci.c +++ b/plat/socionext/uniphier/uniphier_psci.c @@ -1,9 +1,11 @@ /* - * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ +#include + #include #include #include @@ -12,15 +14,18 @@ #include "uniphier.h" -#define UNIPHIER_ROM_RSV0 0x59801200 +#define UNIPHIER_ROM_RSV0 0x0 -#define UNIPHIER_SLFRSTSEL 0x61843010 +#define UNIPHIER_SLFRSTSEL 0x10 #define UNIPHIER_SLFRSTSEL_MASK GENMASK(1, 0) -#define UNIPHIER_SLFRSTCTL 0x61843014 +#define UNIPHIER_SLFRSTCTL 0x14 #define UNIPHIER_SLFRSTCTL_RST BIT(0) #define MPIDR_AFFINITY_INVALID ((u_register_t)-1) +static uintptr_t uniphier_rom_rsv_base; +static uintptr_t uniphier_slfrst_base; + uintptr_t uniphier_sec_entrypoint; void uniphier_warmboot_entrypoint(void); @@ -34,7 +39,7 @@ static int uniphier_psci_pwr_domain_on(u_register_t mpidr) flush_dcache_range((uint64_t)&uniphier_holding_pen_release, sizeof(uniphier_holding_pen_release)); - mmio_write_64(UNIPHIER_ROM_RSV0, + mmio_write_64(uniphier_rom_rsv_base + UNIPHIER_ROM_RSV0, (uint64_t)&uniphier_warmboot_entrypoint); sev(); @@ -71,8 +76,10 @@ static void __dead2 uniphier_psci_pwr_domain_pwr_down_wfi( static void uniphier_self_system_reset(void) { - mmio_clrbits_32(UNIPHIER_SLFRSTSEL, UNIPHIER_SLFRSTSEL_MASK); - mmio_setbits_32(UNIPHIER_SLFRSTCTL, UNIPHIER_SLFRSTCTL_RST); + mmio_clrbits_32(uniphier_slfrst_base + UNIPHIER_SLFRSTSEL, + UNIPHIER_SLFRSTSEL_MASK); + mmio_setbits_32(uniphier_slfrst_base + UNIPHIER_SLFRSTCTL, + UNIPHIER_SLFRSTCTL_RST); } static void __dead2 uniphier_psci_system_off(void) @@ -114,13 +121,40 @@ static const struct plat_psci_ops uniphier_psci_ops = { int plat_setup_psci_ops(uintptr_t sec_entrypoint, const struct plat_psci_ops **psci_ops) { - unsigned int soc; + uniphier_sec_entrypoint = sec_entrypoint; + flush_dcache_range((uint64_t)&uniphier_sec_entrypoint, + sizeof(uniphier_sec_entrypoint)); - soc = uniphier_get_soc_id(); - if (soc == UNIPHIER_SOC_UNKNOWN) { - ERROR("unsupported SoC\n"); - return -ENOTSUP; - } + *psci_ops = &uniphier_psci_ops; + + return 0; +} + +struct uniphier_psci_ctrl_base { + uintptr_t rom_rsv_base; + uintptr_t slfrst_base; +}; + +static const struct uniphier_psci_ctrl_base uniphier_psci_ctrl_base[] = { + [UNIPHIER_SOC_LD11] = { + .rom_rsv_base = 0x59801200, + .slfrst_base = 0x61843000, + }, + [UNIPHIER_SOC_LD20] = { + .rom_rsv_base = 0x59801200, + .slfrst_base = 0x61843000, + }, + [UNIPHIER_SOC_PXS3] = { + .rom_rsv_base = 0x59801200, + .slfrst_base = 0x61843000, + }, +}; + +void uniphier_psci_init(unsigned int soc) +{ + assert(soc < ARRAY_SIZE(uniphier_psci_ctrl_base)); + uniphier_rom_rsv_base = uniphier_psci_ctrl_base[soc].rom_rsv_base; + uniphier_slfrst_base = uniphier_psci_ctrl_base[soc].slfrst_base; if (uniphier_get_boot_master(soc) == UNIPHIER_BOOT_MASTER_SCP) { uniphier_psci_scp_mode = uniphier_scp_is_running(); @@ -130,12 +164,4 @@ int plat_setup_psci_ops(uintptr_t sec_entrypoint, if (uniphier_psci_scp_mode) uniphier_scp_open_com(); } - - uniphier_sec_entrypoint = sec_entrypoint; - flush_dcache_range((uint64_t)&uniphier_sec_entrypoint, - sizeof(uniphier_sec_entrypoint)); - - *psci_ops = &uniphier_psci_ops; - - return 0; } -- cgit v1.2.3 From 2cb260053d49cb4e925b46afd2f511639dd64b70 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 3 Feb 2020 19:28:13 +0900 Subject: uniphier: extend boot device detection for future SoCs The next SoC will have: - No boot swap - SD boot - No USB boot Add new fields to handle this. Change-Id: I772395f2c5dfc612e575b0cbd0657a5fa9611c25 Signed-off-by: Masahiro Yamada --- plat/socionext/uniphier/uniphier.h | 3 ++- plat/socionext/uniphier/uniphier_boot_device.c | 12 ++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/plat/socionext/uniphier/uniphier.h b/plat/socionext/uniphier/uniphier.h index 729dc5caa..9deb3163b 100644 --- a/plat/socionext/uniphier/uniphier.h +++ b/plat/socionext/uniphier/uniphier.h @@ -25,7 +25,8 @@ unsigned int uniphier_get_boot_device(unsigned int soc); #define UNIPHIER_BOOT_DEVICE_EMMC 0 #define UNIPHIER_BOOT_DEVICE_NAND 1 #define UNIPHIER_BOOT_DEVICE_NOR 2 -#define UNIPHIER_BOOT_DEVICE_USB 3 +#define UNIPHIER_BOOT_DEVICE_SD 3 +#define UNIPHIER_BOOT_DEVICE_USB 4 #define UNIPHIER_BOOT_DEVICE_RSV 0xffffffff unsigned int uniphier_get_boot_master(unsigned int soc); diff --git a/plat/socionext/uniphier/uniphier_boot_device.c b/plat/socionext/uniphier/uniphier_boot_device.c index ce9caa985..517ec96a4 100644 --- a/plat/socionext/uniphier/uniphier_boot_device.c +++ b/plat/socionext/uniphier/uniphier_boot_device.c @@ -106,20 +106,25 @@ static unsigned int uniphier_pxs3_get_boot_device(uint32_t pinmon) } struct uniphier_boot_device_info { + bool have_boot_swap; + bool (*is_sd_boot)(uint32_t pinmon); bool (*is_usb_boot)(uint32_t pinmon); unsigned int (*get_boot_device)(uint32_t pinmon); }; static const struct uniphier_boot_device_info uniphier_boot_device_info[] = { [UNIPHIER_SOC_LD11] = { + .have_boot_swap = true, .is_usb_boot = uniphier_ld11_is_usb_boot, .get_boot_device = uniphier_ld11_get_boot_device, }, [UNIPHIER_SOC_LD20] = { + .have_boot_swap = true, .is_usb_boot = uniphier_ld20_is_usb_boot, .get_boot_device = uniphier_ld11_get_boot_device, }, [UNIPHIER_SOC_PXS3] = { + .have_boot_swap = true, .is_usb_boot = uniphier_pxs3_is_usb_boot, .get_boot_device = uniphier_pxs3_get_boot_device, }, @@ -135,10 +140,13 @@ unsigned int uniphier_get_boot_device(unsigned int soc) pinmon = mmio_read_32(UNIPHIER_PINMON0); - if (!(pinmon & BIT(29))) + if (info->have_boot_swap && !(pinmon & BIT(29))) return UNIPHIER_BOOT_DEVICE_NOR; - if (info->is_usb_boot(pinmon)) + if (info->is_sd_boot && info->is_sd_boot(pinmon)) + return UNIPHIER_BOOT_DEVICE_SD; + + if (info->is_usb_boot && info->is_usb_boot(pinmon)) return UNIPHIER_BOOT_DEVICE_USB; return info->get_boot_device(pinmon); -- cgit v1.2.3 From eba319be6c64cbe1280b49e14c30de68ed0020ab Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 3 Feb 2020 19:46:15 +0900 Subject: uniphier: make I/O register region configurable The I/O register region will be changed in the next SoC. Make it configurable. Change-Id: Iec0cbd1ef2d0703ebc7c3d3082edd73791bbfec9 Signed-off-by: Masahiro Yamada --- plat/socionext/uniphier/tsp/uniphier_tsp_setup.c | 2 +- plat/socionext/uniphier/uniphier.h | 2 +- plat/socionext/uniphier/uniphier_bl2_setup.c | 2 +- plat/socionext/uniphier/uniphier_bl31_setup.c | 2 +- plat/socionext/uniphier/uniphier_xlat_setup.c | 33 ++++++++++++++++++++---- 5 files changed, 32 insertions(+), 9 deletions(-) diff --git a/plat/socionext/uniphier/tsp/uniphier_tsp_setup.c b/plat/socionext/uniphier/tsp/uniphier_tsp_setup.c index 5ea6e9474..091a6f7a9 100644 --- a/plat/socionext/uniphier/tsp/uniphier_tsp_setup.c +++ b/plat/socionext/uniphier/tsp/uniphier_tsp_setup.c @@ -31,6 +31,6 @@ void tsp_platform_setup(void) void tsp_plat_arch_setup(void) { - uniphier_mmap_setup(); + uniphier_mmap_setup(uniphier_soc); enable_mmu_el1(0); } diff --git a/plat/socionext/uniphier/uniphier.h b/plat/socionext/uniphier/uniphier.h index b26bd65d2..ee520ad23 100644 --- a/plat/socionext/uniphier/uniphier.h +++ b/plat/socionext/uniphier/uniphier.h @@ -57,7 +57,7 @@ void uniphier_scp_open_com(void); void uniphier_scp_system_off(void); void uniphier_scp_system_reset(void); -void uniphier_mmap_setup(void); +void uniphier_mmap_setup(unsigned int soc); void uniphier_cci_init(unsigned int soc); void uniphier_cci_enable(void); diff --git a/plat/socionext/uniphier/uniphier_bl2_setup.c b/plat/socionext/uniphier/uniphier_bl2_setup.c index 9c8d2daad..7a7f78681 100644 --- a/plat/socionext/uniphier/uniphier_bl2_setup.c +++ b/plat/socionext/uniphier/uniphier_bl2_setup.c @@ -43,7 +43,7 @@ void bl2_el3_plat_arch_setup(void) int skip_scp = 0; int ret; - uniphier_mmap_setup(); + uniphier_mmap_setup(uniphier_soc); enable_mmu_el3(0); /* add relocation offset (run-time-address - link-address) */ diff --git a/plat/socionext/uniphier/uniphier_bl31_setup.c b/plat/socionext/uniphier/uniphier_bl31_setup.c index 15ceed4bb..f2f0b298a 100644 --- a/plat/socionext/uniphier/uniphier_bl31_setup.c +++ b/plat/socionext/uniphier/uniphier_bl31_setup.c @@ -86,6 +86,6 @@ void bl31_platform_setup(void) void bl31_plat_arch_setup(void) { - uniphier_mmap_setup(); + uniphier_mmap_setup(uniphier_soc); enable_mmu_el3(0); } diff --git a/plat/socionext/uniphier/uniphier_xlat_setup.c b/plat/socionext/uniphier/uniphier_xlat_setup.c index 18d2f9e93..66c7834f5 100644 --- a/plat/socionext/uniphier/uniphier_xlat_setup.c +++ b/plat/socionext/uniphier/uniphier_xlat_setup.c @@ -4,15 +4,36 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include + #include #include #include -#define UNIPHIER_REG_REGION_BASE 0x50000000ULL -#define UNIPHIER_REG_REGION_SIZE 0x20000000ULL +#include "uniphier.h" + +struct uniphier_reg_region { + uintptr_t base; + size_t size; +}; + +static const struct uniphier_reg_region uniphier_reg_region[] = { + [UNIPHIER_SOC_LD11] = { + .base = 0x50000000UL, + .size = 0x20000000UL, + }, + [UNIPHIER_SOC_LD20] = { + .base = 0x50000000UL, + .size = 0x20000000UL, + }, + [UNIPHIER_SOC_PXS3] = { + .base = 0x50000000UL, + .size = 0x20000000UL, + }, +}; -void uniphier_mmap_setup(void) +void uniphier_mmap_setup(unsigned int soc) { VERBOSE("Trusted RAM seen by this BL image: %p - %p\n", (void *)BL_CODE_BASE, (void *)BL_END); @@ -35,8 +56,10 @@ void uniphier_mmap_setup(void) MT_DEVICE | MT_RW | MT_SECURE); /* register region */ - mmap_add_region(UNIPHIER_REG_REGION_BASE, UNIPHIER_REG_REGION_BASE, - UNIPHIER_REG_REGION_SIZE, + assert(soc < ARRAY_SIZE(uniphier_reg_region)); + mmap_add_region(uniphier_reg_region[soc].base, + uniphier_reg_region[soc].base, + uniphier_reg_region[soc].size, MT_DEVICE | MT_RW | MT_SECURE); init_xlat_tables(); -- cgit v1.2.3 From 8eaffdf70b7754c25229d182b2c3b10daa2ed8cd Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 3 Feb 2020 19:46:26 +0900 Subject: uniphier: make on-chip SRAM region configurable The on-chip SRAM region will be changed in the next SoC. Make it configurable. Also, split the mmap code into a new helper function so that it can be re-used for another boot mode. Change-Id: I89f40432bf852a58ebc9be5d9dec4136b8dc010b Signed-off-by: Masahiro Yamada --- plat/socionext/uniphier/uniphier_io_storage.c | 33 +++++++++++++++++++++------ 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/plat/socionext/uniphier/uniphier_io_storage.c b/plat/socionext/uniphier/uniphier_io_storage.c index 96180f159..e89c8358c 100644 --- a/plat/socionext/uniphier/uniphier_io_storage.c +++ b/plat/socionext/uniphier/uniphier_io_storage.c @@ -23,7 +23,6 @@ #define UNIPHIER_ROM_REGION_BASE 0x00000000ULL #define UNIPHIER_ROM_REGION_SIZE 0x10000000ULL -#define UNIPHIER_OCM_REGION_BASE 0x30000000ULL #define UNIPHIER_OCM_REGION_SIZE 0x00040000ULL #define UNIPHIER_BLOCK_BUF_OFFSET 0x04200000UL @@ -278,12 +277,20 @@ static int uniphier_io_nor_setup(unsigned int soc_id, size_t buffer_offset) return uniphier_io_memmap_setup(0x70000); } -static int uniphier_io_usb_setup(unsigned int soc_id, size_t buffer_offset) +static const uintptr_t uniphier_ocm_base[] = { + [UNIPHIER_SOC_LD11] = 0x30000000, + [UNIPHIER_SOC_LD20] = 0x30000000, + [UNIPHIER_SOC_PXS3] = 0x30000000, +}; + +static int uniphier_io_rom_api_setup(unsigned int soc) { - struct io_block_dev_spec *block_dev_spec; + uintptr_t ocm_base; int ret; - /* use ROM API for loading images from USB storage */ + assert(soc < ARRAY_SIZE(uniphier_ocm_base)); + ocm_base = uniphier_ocm_base[soc]; + ret = mmap_add_dynamic_region(UNIPHIER_ROM_REGION_BASE, UNIPHIER_ROM_REGION_BASE, UNIPHIER_ROM_REGION_SIZE, @@ -296,14 +303,26 @@ static int uniphier_io_usb_setup(unsigned int soc_id, size_t buffer_offset) * load functions provided by the ROM use this memory region as a work * area, but do not cater to cache coherency. */ - ret = mmap_add_dynamic_region(UNIPHIER_OCM_REGION_BASE, - UNIPHIER_OCM_REGION_BASE, + ret = mmap_add_dynamic_region(ocm_base, ocm_base, UNIPHIER_OCM_REGION_SIZE, MT_DEVICE | MT_RW | MT_SECURE); if (ret) return ret; - ret = uniphier_usb_init(soc_id, &block_dev_spec); + return 0; +} + +static int uniphier_io_usb_setup(unsigned int soc, size_t buffer_offset) +{ + struct io_block_dev_spec *block_dev_spec; + int ret; + + /* use ROM API for loading images from USB storage */ + ret = uniphier_io_rom_api_setup(soc); + if (ret) + return ret; + + ret = uniphier_usb_init(soc, &block_dev_spec); if (ret) return ret; -- cgit v1.2.3 From 97600cb586af32ddbe164aca61a0c6a61e115bbe Mon Sep 17 00:00:00 2001 From: Jacky Bai Date: Fri, 29 Nov 2019 10:25:42 +0800 Subject: plat: imx8m: Fix the rdc memory region slot's offset Each memory region slot occupies 16bypte space, so correct the the offset of config register address. Change-Id: Ief8f21bb8ada78b5663768ee1e40f9e0eae57165 Signed-off-by: Jacky Bai --- plat/imx/imx8m/include/imx_rdc.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plat/imx/imx8m/include/imx_rdc.h b/plat/imx/imx8m/include/imx_rdc.h index 6be8550da..e25b0e6d4 100644 --- a/plat/imx/imx8m/include/imx_rdc.h +++ b/plat/imx/imx8m/include/imx_rdc.h @@ -13,9 +13,9 @@ #define MDAn(x) (IMX_RDC_BASE + 0x200 + (x) * 4) #define PDAPn(x) (IMX_RDC_BASE + 0x400 + (x) * 4) -#define MRSAn(x) (IMX_RDC_BASE + 0x800 + (x) * 4) -#define MREAn(x) (IMX_RDC_BASE + 0x804 + (x) * 4) -#define MRCn(x) (IMX_RDC_BASE + 0x808 + (x) * 4) +#define MRSAn(x) (IMX_RDC_BASE + 0x800 + (x) * 0x10) +#define MREAn(x) (IMX_RDC_BASE + 0x804 + (x) * 0x10) +#define MRCn(x) (IMX_RDC_BASE + 0x808 + (x) * 0x10) #define LCK BIT(31) #define SREQ BIT(30) -- cgit v1.2.3 From 3ac82b258eb106be97e34915b7e72ca54175b281 Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Fri, 7 Feb 2020 16:54:36 +0100 Subject: doc: debugfs remove references section and add topic to components index Signed-off-by: Olivier Deprez Change-Id: I8c2e6dc98f2f30a81f4f80cc0ca1232fed7a53c9 --- docs/components/debugfs-design.rst | 23 ++++++++--------------- docs/components/index.rst | 1 + 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/docs/components/debugfs-design.rst b/docs/components/debugfs-design.rst index 06916f3d9..8ce1ba6a7 100644 --- a/docs/components/debugfs-design.rst +++ b/docs/components/debugfs-design.rst @@ -15,8 +15,9 @@ Virtual filesystem ------------------ The core functionality lies in a virtual file system based on a 9p file server -interface (`Notes on the Plan 9 Kernel Source`_). The implementation permits -exposing virtual files, firmware drivers, and file blobs. +interface (`Notes on the Plan 9 Kernel Source`_ and +`Linux 9p remote filesystem protocol`_). +The implementation permits exposing virtual files, firmware drivers, and file blobs. Namespace ~~~~~~~~~ @@ -77,10 +78,10 @@ SMC interface ------------- The communication with the 9p layer in BL31 is made through an SMC conduit -(`SMC Calling Convention PDD`_), using a specific SiP Function Id. An NS shared -buffer is used to pass path string parameters, or e.g. to exchange data on a -read operation. Refer to `ARM SiP Services`_ for a description of the SMC -interface. +(`SMC Calling Convention PDD`_), using a specific SiP Function Id. An NS +shared buffer is used to pass path string parameters, or e.g. to exchange +data on a read operation. Refer to `ARM SiP Services`_ for a description +of the SMC interface. Security considerations ----------------------- @@ -114,17 +115,9 @@ The SMC interface is accessible from an NS environment, that is: - a Linux kernel driver running at NS-EL1 - a Linux userspace application through the kernel driver -References ----------- - -.. [#] `SMC Calling Convention PDD`_ -.. [#] `Notes on the Plan 9 Kernel Source`_ -.. [#] `Linux 9p remote filesystem protocol`_ -.. [#] `ARM SiP Services`_ - -------------- -*Copyright (c) 2019, Arm Limited and Contributors. All rights reserved.* +*Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.* .. _SMC Calling Convention PDD: http://infocenter.arm.com/help/topic/com.arm.doc.den0028b/ .. _Notes on the Plan 9 Kernel Source: http://lsub.org/who/nemo/9.pdf diff --git a/docs/components/index.rst b/docs/components/index.rst index f1904c004..84425831b 100644 --- a/docs/components/index.rst +++ b/docs/components/index.rst @@ -8,6 +8,7 @@ Components spd/index arm-sip-service + debugfs-design exception-handling firmware-update platform-interrupt-controller-API -- cgit v1.2.3 From 62c9be71d6b6356e021e3640000e4e30f4cbb3e5 Mon Sep 17 00:00:00 2001 From: Petre-Ionut Tudor Date: Fri, 27 Sep 2019 15:13:21 +0100 Subject: Update docs with PMU security information This patch adds information on the PMU configuration registers and security considerations related to the PMU. Signed-off-by: Petre-Ionut Tudor Change-Id: I36b15060b9830a77d3f47f293c0a6dafa3c581fb --- docs/design/firmware-design.rst | 4 +- docs/perf/index.rst | 3 +- docs/perf/performance-monitoring-unit.rst | 158 ++++++++++++++++++++++++++++++ docs/process/security-hardening.rst | 99 +++++++++++++++++++ 4 files changed, 261 insertions(+), 3 deletions(-) create mode 100644 docs/perf/performance-monitoring-unit.rst diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst index 5fc1335b3..d0d6ef697 100644 --- a/docs/design/firmware-design.rst +++ b/docs/design/firmware-design.rst @@ -2696,13 +2696,13 @@ kernel at boot time. These can be found in the ``fdts`` directory. -------------- -*Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.* +*Copyright (c) 2013-2020, 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: http://infocenter.arm.com/help/topic/com.arm.doc.den0028b/ARM_DEN0028B_SMC_Calling_Convention.pdf .. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf .. _Power State Coordination Interface PDD: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf -.. _Arm ARM: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0487a.e/index.html +.. _Arm ARM: https://developer.arm.com/docs/ddi0487/latest .. _SMC Calling Convention PDD: http://infocenter.arm.com/help/topic/com.arm.doc.den0028b/ARM_DEN0028B_SMC_Calling_Convention.pdf .. _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 diff --git a/docs/perf/index.rst b/docs/perf/index.rst index 0f49b4810..1482b80f6 100644 --- a/docs/perf/index.rst +++ b/docs/perf/index.rst @@ -8,7 +8,8 @@ Performance & Testing psci-performance-juno tsp + performance-monitoring-unit -------------- -*Copyright (c) 2019, Arm Limited. All rights reserved.* +*Copyright (c) 2019-2020, Arm Limited. All rights reserved.* diff --git a/docs/perf/performance-monitoring-unit.rst b/docs/perf/performance-monitoring-unit.rst new file mode 100644 index 000000000..5dd1af5fc --- /dev/null +++ b/docs/perf/performance-monitoring-unit.rst @@ -0,0 +1,158 @@ +Performance Monitoring Unit +=========================== + +The Performance Monitoring Unit (PMU) allows recording of architectural and +microarchitectural events for profiling purposes. + +This document gives an overview of the PMU counter configuration to assist with +implementation and to complement the PMU security guidelines given in the +:ref:`Secure Development Guidelines` document. + +.. note:: + This section applies to Armv8-A implementations which have version 3 + of the Performance Monitors Extension (PMUv3). + +PMU Counters +------------ + +The PMU makes 32 counters available at all privilege levels: + +- 31 programmable event counters: ``PMEVCNTR``, where ``n`` is ``0`` to + ``30``. +- A dedicated cycle counter: ``PMCCNTR``. + +Architectural mappings +~~~~~~~~~~~~~~~~~~~~~~ + ++--------------+---------+----------------------------+ +| Counters | State | System Register Name | ++==============+=========+============================+ +| | AArch64 | ``PMEVCNTR_EL0[63*:0]`` | +| Programmable +---------+----------------------------+ +| | AArch32 | ``PMEVCNTR[31:0]`` | ++--------------+---------+----------------------------+ +| | AArch64 | ``PMCCNTR_EL0[63:0]`` | +| Cycle +---------+----------------------------+ +| | AArch32 | ``PMCCNTR[63:0]`` | ++--------------+---------+----------------------------+ + +.. note:: + Bits [63:32] are only available if ARMv8.5-PMU is implemented. Refer to the + `Arm ARM`_ for a detailed description of ARMv8.5-PMU features. + +Configuring the PMU for counting events +--------------------------------------- + +Each programmable counter has an associated register, ``PMEVTYPER`` which +configures it. The cycle counter has the ``PMCCFILTR_EL0`` register, which has +an identical function and bit field layout as ``PMEVTYPER``. In addition, +the counters are enabled (permitted to increment) via the ``PMCNTENSET`` and +``PMCR`` registers. These can be accessed at all privilege levels. + +Architectural mappings +~~~~~~~~~~~~~~~~~~~~~~ + ++-----------------------------+------------------------+ +| AArch64 | AArch32 | ++=============================+========================+ +| ``PMEVTYPER_EL0[63*:0]`` | ``PMEVTYPER[31:0]`` | ++-----------------------------+------------------------+ +| ``PMCCFILTR_EL0[63*:0]`` | ``PMCCFILTR[31:0]`` | ++-----------------------------+------------------------+ +| ``PMCNTENSET_EL0[63*:0]`` | ``PMCNTENSET[31:0]`` | ++-----------------------------+------------------------+ +| ``PMCR_EL0[63*:0]`` | ``PMCR[31:0]`` | ++-----------------------------+------------------------+ + +.. note:: + Bits [63:32] are reserved. + +Relevant register fields +~~~~~~~~~~~~~~~~~~~~~~~~ + +For ``PMEVTYPER_EL0``/``PMEVTYPER`` and ``PMCCFILTR_EL0/PMCCFILTR``, the +most important fields are: + +- ``P``: + + - Bit 31. + - If set to ``0``, will increment the associated ``PMEVCNTR`` at EL1. + +- ``NSK``: + + - Bit 29. + - If equal to the ``P`` bit it enables the associated ``PMEVCNTR`` at + Non-secure EL1. + - Reserved if EL3 not implemented. + +- ``NSH``: + + - Bit 27. + - If set to ``1``, will increment the associated ``PMEVCNTR`` at EL2. + - Reserved if EL2 not implemented. + +- ``SH``: + + - Bit 24. + - If different to the ``NSH`` bit it enables the associated ``PMEVCNTR`` + at Secure EL2. + - Reserved if Secure EL2 not implemented. + +- ``M``: + + - Bit 26. + - If equal to the ``P`` bit it enables the associated ``PMEVCNTR`` at + EL3. + +- ``evtCount[15:10]``: + + - Extension to ``evtCount[9:0]``. Reserved unless ARMv8.1-PMU implemented. + +- ``evtCount[9:0]``: + + - The event number that the associated ``PMEVCNTR`` will count. + +For ``PMCNTENSET_EL0``/``PMCNTENSET``, the most important fields are: + +- ``P[30:0]``: + + - Setting bit ``P[n]`` to ``1`` enables counter ``PMEVCNTR``. + - The effects of ``PMEVTYPER`` are applied on top of this. + In other words, the counter will not increment at any privilege level or + security state unless it is enabled here. + +- ``C``: + + - Bit 31. + - If set to ``1`` enables the cycle counter ``PMCCNTR``. + +For ``PMCR``/``PMCR_EL0``, the most important fields are: + +- ``DP``: + + - Bit 5. + - If set to ``1`` it disables the cycle counter ``PMCCNTR`` where event + counting (by ``PMEVCNTR``) is prohibited (e.g. EL2 and the Secure + world). + - If set to ``0``, ``PMCCNTR`` will not be affected by this bit and + therefore will be able to count where the programmable counters are + prohibited. + +- ``E``: + + - Bit 0. + - Enables/disables counting altogether. + - The effects of ``PMCNTENSET`` and ``PMCR.DP`` are applied on top of this. + In other words, if this bit is ``0`` then no counters will increment + regardless of how the other PMU system registers or bit fields are + configured. + +.. rubric:: References + +- `Arm ARM`_ + +-------------- + +*Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.* + +.. _Arm ARM: https://developer.arm.com/docs/ddi0487/latest diff --git a/docs/process/security-hardening.rst b/docs/process/security-hardening.rst index 43a572125..507046f2e 100644 --- a/docs/process/security-hardening.rst +++ b/docs/process/security-hardening.rst @@ -25,6 +25,99 @@ The secure world **should never** crash or become unusable due to receiving too many normal world requests (a *Denial of Service* or *DoS* attack). It should have a mechanism for throttling or ignoring normal world requests. +Preventing Secure-world timing information leakage via PMU counters +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The Secure world needs to implement some defenses to prevent the Non-secure +world from making it leak timing information. In general, higher privilege +levels must defend from those below when the PMU is treated as an attack +vector. + +Refer to the :ref:`Performance Monitoring Unit` guide for detailed information +on the PMU registers. + +Timing leakage attacks from the Non-secure world +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Since the Non-secure world has access to the ``PMCR`` register, it can +configure the PMU to increment counters at any exception level and in both +Secure and Non-secure state. Thus, it attempts to leak timing information from +the Secure world. + +Shown below is an example of such a configuration: + +- ``PMEVTYPER0_EL0`` and ``PMCCFILTR_EL0``: + + - Set ``P`` to ``0``. + - Set ``NSK`` to ``1``. + - Set ``M`` to ``0``. + - Set ``NSH`` to ``0``. + - Set ``SH`` to ``1``. + +- ``PMCNTENSET_EL0``: + + - Set ``P[0]`` to ``1``. + - Set ``C`` to ``1``. + +- ``PMCR_EL0``: + + - Set ``DP`` to ``0``. + - Set ``E`` to ``1``. + +This configuration instructs ``PMEVCNTR0_EL0`` and ``PMCCNTR_EL0`` to increment +at Secure EL1, Secure EL2 (if implemented) and EL3. + +Since the Non-secure world has fine-grained control over where (at which +exception levels) it instructs counters to increment, obtaining event counts +would allow it to carry out side-channel timing attacks against the Secure +world. Examples include Spectre, Meltdown, as well as extracting secrets from +cryptographic algorithms with data-dependent variations in their execution +time. + +Secure world mitigation strategies +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``MDCR_EL3`` register allows EL3 to configure the PMU (among other things). +The `Arm ARM`_ details all of the bit fields in this register, but for the PMU +there are two bits which determine the permissions of the counters: + +- ``SPME`` for the programmable counters. +- ``SCCD`` for the cycle counter. + +Depending on the implemented features, the Secure world can prohibit counting +in AArch64 state via the following: + +- ARMv8.2-Debug not implemented: + + - Prohibit general event counters and the cycle counter: + ``MDCR_EL3.SPME == 0 && PMCR_EL0.DP == 1 && !ExternalSecureNoninvasiveDebugEnabled()``. + + - ``MDCR_EL3.SPME`` resets to ``0``, so by default general events should + not be counted in the Secure world. + - The ``PMCR_EL0.DP`` bit therefore needs to be set to ``1`` when EL3 is + entered and ``PMCR_EL0`` needs to be saved and restored in EL3. + - ``ExternalSecureNoninvasiveDebugEnabled()`` is an authentication + interface which is implementation-defined unless ARMv8.4-Debug is + implemented. The `Arm ARM`_ has detailed information on this topic. + + - The only other way is to disable the ``PMCR_EL0.E`` bit upon entering + EL3, which disables counting altogether. + +- ARMv8.2-Debug implemented: + + - Prohibit general event counters: ``MDCR_EL3.SPME == 0``. + - Prohibit cycle counter: ``MDCR_EL3.SPME == 0 && PMCR_EL0.DP == 1``. + ``PMCR_EL0`` therefore needs to be saved and restored in EL3. + +- ARMv8.5-PMU implemented: + + - Prohibit general event counters: as in ARMv8.2-Debug. + - Prohibit cycle counter: ``MDCR_EL3.SCCD == 1`` + +In Aarch32 execution state the ``MDCR_EL3`` alias is the ``SDCR`` register, +which has some of the bit fields of ``MDCR_EL3``, most importantly the ``SPME`` +and ``SCCD`` bits. + Build options ------------- @@ -71,6 +164,12 @@ Several build options can be used to check for security issues. Refer to the NB: The ``Werror`` flag is enabled by default in TF-A and can be disabled by setting the ``E`` build flag to 0. +.. rubric:: References + +- `Arm ARM`_ + -------------- *Copyright (c) 2019-2020, Arm Limited. All rights reserved.* + +.. _Arm ARM: https://developer.arm.com/docs/ddi0487/latest -- cgit v1.2.3 From 3c6fcf117afd9ad0ceecbd200676065cf5748101 Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Wed, 12 Feb 2020 09:26:09 +0000 Subject: fconf: Move remaining arm platform to fconf Change-Id: I011256ca60672a00b711c3f5725211be64bbc2b2 Signed-off-by: Louis Mayencourt --- .../arm/board/rddaniel/fdts/rddaniel_fw_config.dts | 47 ++++++++++++++++++++++ .../board/rddaniel/fdts/rddaniel_tb_fw_config.dts | 26 ------------ plat/arm/board/rddaniel/platform.mk | 4 +- .../arm/board/rde1edge/fdts/rde1edge_fw_config.dts | 47 ++++++++++++++++++++++ .../board/rde1edge/fdts/rde1edge_tb_fw_config.dts | 25 ------------ plat/arm/board/rde1edge/platform.mk | 4 +- .../arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts | 47 ++++++++++++++++++++++ .../board/rdn1edge/fdts/rdn1edge_tb_fw_config.dts | 25 ------------ plat/arm/board/rdn1edge/platform.mk | 4 +- plat/arm/board/sgi575/fdts/sgi575_fw_config.dts | 47 ++++++++++++++++++++++ plat/arm/board/sgi575/fdts/sgi575_tb_fw_config.dts | 25 ------------ plat/arm/board/sgi575/platform.mk | 4 +- plat/arm/board/sgm775/fdts/sgm775_fw_config.dts | 35 ++++++++++++++++ plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts | 16 -------- plat/arm/board/sgm775/platform.mk | 2 +- 15 files changed, 232 insertions(+), 126 deletions(-) create mode 100644 plat/arm/board/rddaniel/fdts/rddaniel_fw_config.dts delete mode 100644 plat/arm/board/rddaniel/fdts/rddaniel_tb_fw_config.dts create mode 100644 plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts delete mode 100644 plat/arm/board/rde1edge/fdts/rde1edge_tb_fw_config.dts create mode 100644 plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts delete mode 100644 plat/arm/board/rdn1edge/fdts/rdn1edge_tb_fw_config.dts create mode 100644 plat/arm/board/sgi575/fdts/sgi575_fw_config.dts delete mode 100644 plat/arm/board/sgi575/fdts/sgi575_tb_fw_config.dts create mode 100644 plat/arm/board/sgm775/fdts/sgm775_fw_config.dts delete mode 100644 plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts diff --git a/plat/arm/board/rddaniel/fdts/rddaniel_fw_config.dts b/plat/arm/board/rddaniel/fdts/rddaniel_fw_config.dts new file mode 100644 index 000000000..81e4cc12d --- /dev/null +++ b/plat/arm/board/rddaniel/fdts/rddaniel_fw_config.dts @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +/dts-v1/; + +/ { + dtb-registry { + compatible = "arm,dyn_cfg-dtb_registry"; + + /* tb_fw_config is temporarily contained on this dtb */ + tb_fw-config { + load-address = <0x0 0x4001010>; + max-size = <0x200>; + id = ; + }; + + nt_fw-config { + load-address = <0x0 0xFEF00000>; + max-size = <0x0100000>; + id = ; + }; + }; + + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + + /* + * The following two entries are placeholders for Mbed TLS + * heap information. The default values don't matter since + * they will be overwritten by BL1. + * In case of having shared Mbed TLS heap between BL1 and BL2, + * BL1 will populate these two properties with the respective + * info about the shared heap. This info will be available for + * BL2 in order to locate and re-use the heap. + */ + mbedtls_heap_addr = <0x0 0x0>; + mbedtls_heap_size = <0x0>; + }; +}; diff --git a/plat/arm/board/rddaniel/fdts/rddaniel_tb_fw_config.dts b/plat/arm/board/rddaniel/fdts/rddaniel_tb_fw_config.dts deleted file mode 100644 index 9acec137e..000000000 --- a/plat/arm/board/rddaniel/fdts/rddaniel_tb_fw_config.dts +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/dts-v1/; - -/ { - /* Platform Config */ - compatible = "arm,tb_fw"; - nt_fw_config_addr = <0x0 0xFEF00000>; - nt_fw_config_max_size = <0x0100000>; - - /* - * The following two entries are placeholders for Mbed TLS - * heap information. The default values don't matter since - * they will be overwritten by BL1. - * In case of having shared Mbed TLS heap between BL1 and BL2, - * BL1 will populate these two properties with the respective - * info about the shared heap. This info will be available for - * BL2 in order to locate and re-use the heap. - */ - mbedtls_heap_addr = <0x0 0x0>; - mbedtls_heap_size = <0x0>; -}; diff --git a/plat/arm/board/rddaniel/platform.mk b/plat/arm/board/rddaniel/platform.mk index 67f57779a..c7e3c7dd8 100644 --- a/plat/arm/board/rddaniel/platform.mk +++ b/plat/arm/board/rddaniel/platform.mk @@ -28,8 +28,8 @@ BL31_SOURCES += ${SGI_CPU_SOURCES} \ plat/arm/common/arm_nor_psci_mem_protect.c # Add the FDT_SOURCES and options for Dynamic Config -FDT_SOURCES += ${RDDANIEL_BASE}/fdts/${PLAT}_tb_fw_config.dts -TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb +FDT_SOURCES += ${RDDANIEL_BASE}/fdts/${PLAT}_fw_config.dts +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb # Add the TB_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) diff --git a/plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts b/plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts new file mode 100644 index 000000000..2719ab415 --- /dev/null +++ b/plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2019-2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +/dts-v1/; + +/ { + dtb-registry { + compatible = "arm,dyn_cfg-dtb_registry"; + + /* tb_fw_config is temporarily contained on this dtb */ + tb_fw-config { + load-address = <0x0 0x4001010>; + max-size = <0x200>; + id = ; + }; + + nt_fw-config { + load-address = <0x0 0xFEF00000>; + max-size = <0x0100000>; + id = ; + }; + }; + + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + + /* + * The following two entries are placeholders for Mbed TLS + * heap information. The default values don't matter since + * they will be overwritten by BL1. + * In case of having shared Mbed TLS heap between BL1 and BL2, + * BL1 will populate these two properties with the respective + * info about the shared heap. This info will be available for + * BL2 in order to locate and re-use the heap. + */ + mbedtls_heap_addr = <0x0 0x0>; + mbedtls_heap_size = <0x0>; + }; +}; diff --git a/plat/arm/board/rde1edge/fdts/rde1edge_tb_fw_config.dts b/plat/arm/board/rde1edge/fdts/rde1edge_tb_fw_config.dts deleted file mode 100644 index 766dc00f5..000000000 --- a/plat/arm/board/rde1edge/fdts/rde1edge_tb_fw_config.dts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2018, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/dts-v1/; - -/ { - /* Platform Config */ - compatible = "arm,tb_fw"; - nt_fw_config_addr = <0x0 0xFEF00000>; - nt_fw_config_max_size = <0x0100000>; - /* - * The following two entries are placeholders for Mbed TLS - * heap information. The default values don't matter since - * they will be overwritten by BL1. - * In case of having shared Mbed TLS heap between BL1 and BL2, - * BL1 will populate these two properties with the respective - * info about the shared heap. This info will be available for - * BL2 in order to locate and re-use the heap. - */ - mbedtls_heap_addr = <0x0 0x0>; - mbedtls_heap_size = <0x0>; -}; diff --git a/plat/arm/board/rde1edge/platform.mk b/plat/arm/board/rde1edge/platform.mk index 88aa634b8..1a4dd17d1 100644 --- a/plat/arm/board/rde1edge/platform.mk +++ b/plat/arm/board/rde1edge/platform.mk @@ -35,8 +35,8 @@ BL2_SOURCES += ${RDE1EDGE_BASE}/rde1edge_trusted_boot.c endif # Add the FDT_SOURCES and options for Dynamic Config -FDT_SOURCES += ${RDE1EDGE_BASE}/fdts/${PLAT}_tb_fw_config.dts -TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb +FDT_SOURCES += ${RDE1EDGE_BASE}/fdts/${PLAT}_fw_config.dts +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb # Add the TB_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) diff --git a/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts b/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts new file mode 100644 index 000000000..ba74b75bc --- /dev/null +++ b/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +/dts-v1/; +/ { + dtb-registry { + compatible = "arm,dyn_cfg-dtb_registry"; + + /* tb_fw_config is temporarily contained on this dtb */ + tb_fw-config { + load-address = <0x0 0x80001010>; + max-size = <0x200>; + id = ; + }; + + nt_fw-config { + load-address = <0x0 0xFEF00000>; + max-size = <0x0100000>; + id = ; + }; + }; + + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + + /* + * The following two entries are placeholders for Mbed TLS + * heap information. The default values don't matter since + * they will be overwritten by BL1. + * In case of having shared Mbed TLS heap between BL1 and BL2, + * BL1 will populate these two properties with the respective + * info about the shared heap. This info will be available for + * BL2 in order to locate and re-use the heap. + */ + mbedtls_heap_addr = <0x0 0x0>; + mbedtls_heap_size = <0x0>; + }; +}; + diff --git a/plat/arm/board/rdn1edge/fdts/rdn1edge_tb_fw_config.dts b/plat/arm/board/rdn1edge/fdts/rdn1edge_tb_fw_config.dts deleted file mode 100644 index b14d7adca..000000000 --- a/plat/arm/board/rdn1edge/fdts/rdn1edge_tb_fw_config.dts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/dts-v1/; - -/ { - /* Platform Config */ - compatible = "arm,tb_fw"; - nt_fw_config_addr = <0x0 0xFEF00000>; - nt_fw_config_max_size = <0x0100000>; - /* - * The following two entries are placeholders for Mbed TLS - * heap information. The default values don't matter since - * they will be overwritten by BL1. - * In case of having shared Mbed TLS heap between BL1 and BL2, - * BL1 will populate these two properties with the respective - * info about the shared heap. This info will be available for - * BL2 in order to locate and re-use the heap. - */ - mbedtls_heap_addr = <0x0 0x0>; - mbedtls_heap_size = <0x0>; -}; diff --git a/plat/arm/board/rdn1edge/platform.mk b/plat/arm/board/rdn1edge/platform.mk index 04f70f3f2..99bb71d79 100644 --- a/plat/arm/board/rdn1edge/platform.mk +++ b/plat/arm/board/rdn1edge/platform.mk @@ -39,8 +39,8 @@ endif BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 # Add the FDT_SOURCES and options for Dynamic Config -FDT_SOURCES += ${RDN1EDGE_BASE}/fdts/${PLAT}_tb_fw_config.dts -TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb +FDT_SOURCES += ${RDN1EDGE_BASE}/fdts/${PLAT}_fw_config.dts +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb # Add the TB_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) diff --git a/plat/arm/board/sgi575/fdts/sgi575_fw_config.dts b/plat/arm/board/sgi575/fdts/sgi575_fw_config.dts new file mode 100644 index 000000000..605cc08b7 --- /dev/null +++ b/plat/arm/board/sgi575/fdts/sgi575_fw_config.dts @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +/dts-v1/; + +/ { + dtb-registry { + compatible = "arm,dyn_cfg-dtb_registry"; + + /* tb_fw_config is temporarily contained on this dtb */ + tb_fw-config { + load-address = <0x0 0x4001010>; + max-size = <0x200>; + id = ; + }; + + nt_fw-config { + load-address = <0x0 0xFEF00000>; + max-size = <0x0100000>; + id = ; + }; + }; + + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + + /* + * The following two entries are placeholders for Mbed TLS + * heap information. The default values don't matter since + * they will be overwritten by BL1. + * In case of having shared Mbed TLS heap between BL1 and BL2, + * BL1 will populate these two properties with the respective + * info about the shared heap. This info will be available for + * BL2 in order to locate and re-use the heap. + */ + mbedtls_heap_addr = <0x0 0x0>; + mbedtls_heap_size = <0x0>; + }; +}; diff --git a/plat/arm/board/sgi575/fdts/sgi575_tb_fw_config.dts b/plat/arm/board/sgi575/fdts/sgi575_tb_fw_config.dts deleted file mode 100644 index b14d7adca..000000000 --- a/plat/arm/board/sgi575/fdts/sgi575_tb_fw_config.dts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/dts-v1/; - -/ { - /* Platform Config */ - compatible = "arm,tb_fw"; - nt_fw_config_addr = <0x0 0xFEF00000>; - nt_fw_config_max_size = <0x0100000>; - /* - * The following two entries are placeholders for Mbed TLS - * heap information. The default values don't matter since - * they will be overwritten by BL1. - * In case of having shared Mbed TLS heap between BL1 and BL2, - * BL1 will populate these two properties with the respective - * info about the shared heap. This info will be available for - * BL2 in order to locate and re-use the heap. - */ - mbedtls_heap_addr = <0x0 0x0>; - mbedtls_heap_size = <0x0>; -}; diff --git a/plat/arm/board/sgi575/platform.mk b/plat/arm/board/sgi575/platform.mk index 76cc4e2c2..d91f829ee 100644 --- a/plat/arm/board/sgi575/platform.mk +++ b/plat/arm/board/sgi575/platform.mk @@ -35,8 +35,8 @@ BL2_SOURCES += ${SGI575_BASE}/sgi575_trusted_boot.c endif # Add the FDT_SOURCES and options for Dynamic Config -FDT_SOURCES += ${SGI575_BASE}/fdts/${PLAT}_tb_fw_config.dts -TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb +FDT_SOURCES += ${SGI575_BASE}/fdts/${PLAT}_fw_config.dts +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb # Add the TB_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) diff --git a/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts b/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts new file mode 100644 index 000000000..a0d0ea90e --- /dev/null +++ b/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +/dts-v1/; + +/ { + dtb-registry { + compatible = "arm,dyn_cfg-dtb_registry"; + + /* tb_fw_config is temporarily contained on this dtb */ + tb_fw-config { + load-address = <0x0 0x4001010>; + max-size = <0x200>; + id = ; + }; + + hw-config { + load-address = <0x0 0x83000000>; + max-size = <0x01000000>; + id = ; + }; + }; + + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + }; +}; diff --git a/plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts b/plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts deleted file mode 100644 index 95025493b..000000000 --- a/plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/dts-v1/; - -/ { - /* Platform Config */ - plat_arm_bl2 { - compatible = "arm,tb_fw"; - hw_config_addr = <0x0 0x83000000>; - hw_config_max_size = <0x01000000>; - }; -}; diff --git a/plat/arm/board/sgm775/platform.mk b/plat/arm/board/sgm775/platform.mk index f096ca53d..355b9ee2c 100644 --- a/plat/arm/board/sgm775/platform.mk +++ b/plat/arm/board/sgm775/platform.mk @@ -8,7 +8,7 @@ include plat/arm/css/sgm/sgm-common.mk SGM775_BASE= plat/arm/board/sgm775 -FDT_SOURCES += ${SGM775_BASE}/fdts/sgm775_tb_fw_config.dts +FDT_SOURCES += ${SGM775_BASE}/fdts/sgm775_fw_config.dts PLAT_INCLUDES +=-I${SGM775_BASE}/include/ -- cgit v1.2.3 From eff737c1d973b859a2973fc5a4692620c9d90a06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= Date: Tue, 4 Feb 2020 15:50:24 -0800 Subject: Fix clang build if CC is not in the path. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If CC points to clang the linker was set to ld.lld. Copy the diectory name from CC is it has one. Change-Id: I50aef5dddee4d2540b12b6d4e68068ad004446f7 Signed-off-by: Arve Hjønnevåg --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 7e416784b..547b5843f 100644 --- a/Makefile +++ b/Makefile @@ -207,9 +207,10 @@ AS = $(CC) -c -x assembler-with-cpp $(TF_CFLAGS_$(ARCH)) CPP = $(CC) -E $(TF_CFLAGS_$(ARCH)) PP = $(CC) -E $(TF_CFLAGS_$(ARCH)) else ifneq ($(findstring clang,$(notdir $(CC))),) +CLANG_CCDIR = $(if $(filter-out ./,$(dir $(CC))),$(dir $(CC)),) TF_CFLAGS_aarch32 = $(target32-directive) $(march32-directive) TF_CFLAGS_aarch64 = -target aarch64-elf $(march64-directive) -LD = ld.lld +LD = $(CLANG_CCDIR)ld.lld ifeq (, $(shell which $(LD))) $(error "No $(LD) in PATH, make sure it is installed or set LD to a different linker") endif -- cgit v1.2.3 From f01428b1cc910c0828958e58f814280e9ec21fd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= Date: Wed, 11 Apr 2018 16:10:53 -0700 Subject: trusty: Allow getting trusty memsize from BL32_MEM_SIZE instead of TSP_SEC_MEM_SIZE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some platforms define BL32_MEM_SIZE instead of TSP_SEC_MEM_SIZE, but the meaning is the same. Change-Id: I93d96dca442e653435cae6a165b1955efe2d2b75 Signed-off-by: Arve Hjønnevåg --- services/spd/trusty/trusty.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/services/spd/trusty/trusty.c b/services/spd/trusty/trusty.c index d6c092cb7..092ffa8eb 100644 --- a/services/spd/trusty/trusty.c +++ b/services/spd/trusty/trusty.c @@ -390,6 +390,10 @@ static const spd_pm_ops_t trusty_pm = { void plat_trusty_set_boot_args(aapcs64_params_t *args); +#if !defined(TSP_SEC_MEM_SIZE) && defined(BL32_MEM_SIZE) +#define TSP_SEC_MEM_SIZE BL32_MEM_SIZE +#endif + #ifdef TSP_SEC_MEM_SIZE #pragma weak plat_trusty_set_boot_args void plat_trusty_set_boot_args(aapcs64_params_t *args) -- cgit v1.2.3 From 471e8fa7d17ce2140cbcec7f4f61d2f1749b447f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= Date: Wed, 11 Apr 2018 16:09:35 -0700 Subject: trusty: Allow gic base to be specified with GICD_BASE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some platforms define GICD_BASE instead of PLAT_ARM_GICD_BASE but the meaning is the same. Change-Id: I1bb04bb49fdab055b365b1d70a4d48d2058e49df Signed-off-by: Arve Hjønnevåg --- services/spd/trusty/generic-arm64-smcall.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/services/spd/trusty/generic-arm64-smcall.c b/services/spd/trusty/generic-arm64-smcall.c index dfc3e71b7..3ffc13dcf 100644 --- a/services/spd/trusty/generic-arm64-smcall.c +++ b/services/spd/trusty/generic-arm64-smcall.c @@ -12,6 +12,15 @@ #include "generic-arm64-smcall.h" +#ifndef PLAT_ARM_GICD_BASE +#ifdef GICD_BASE +#define PLAT_ARM_GICD_BASE GICD_BASE +#define PLAT_ARM_GICC_BASE GICC_BASE +#else +#error PLAT_ARM_GICD_BASE or GICD_BASE must be defined +#endif +#endif + int trusty_disable_serial_debug; struct dputc_state { -- cgit v1.2.3 From 76776c2c67c2f12ac97b118bef5e0477cbb00b13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= Date: Fri, 15 Nov 2019 14:25:43 -0800 Subject: trusty: generic-arm64-smcall: Support gicr address MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add SMC_GET_GIC_BASE_GICR option to SMC_FC_GET_REG_BASE and SMC_FC64_GET_REG_BASE calls for returning the base address of the gic redistributor added in gic version 3. Bug: 122357256 Change-Id: Ia7c287040656515bab262588163e0c5fc8f13a21 Signed-off-by: Arve Hjønnevåg --- services/spd/trusty/generic-arm64-smcall.c | 14 ++++++++++++-- services/spd/trusty/generic-arm64-smcall.h | 1 + 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/services/spd/trusty/generic-arm64-smcall.c b/services/spd/trusty/generic-arm64-smcall.c index 3ffc13dcf..5c3a62849 100644 --- a/services/spd/trusty/generic-arm64-smcall.c +++ b/services/spd/trusty/generic-arm64-smcall.c @@ -16,11 +16,18 @@ #ifdef GICD_BASE #define PLAT_ARM_GICD_BASE GICD_BASE #define PLAT_ARM_GICC_BASE GICC_BASE +#ifdef GICR_BASE +#define PLAT_ARM_GICR_BASE GICR_BASE +#endif #else #error PLAT_ARM_GICD_BASE or GICD_BASE must be defined #endif #endif +#ifndef PLAT_ARM_GICR_BASE +#define PLAT_ARM_GICR_BASE SMC_UNK +#endif + int trusty_disable_serial_debug; struct dputc_state { @@ -57,12 +64,15 @@ static void trusty_dputc(char ch, int secure) static uint64_t trusty_get_reg_base(uint32_t reg) { switch (reg) { - case 0: + case SMC_GET_GIC_BASE_GICD: return PLAT_ARM_GICD_BASE; - case 1: + case SMC_GET_GIC_BASE_GICC: return PLAT_ARM_GICC_BASE; + case SMC_GET_GIC_BASE_GICR: + return PLAT_ARM_GICR_BASE; + default: NOTICE("%s(0x%x) unknown reg\n", __func__, reg); return SMC_UNK; diff --git a/services/spd/trusty/generic-arm64-smcall.h b/services/spd/trusty/generic-arm64-smcall.h index 06efc722f..ac0346924 100644 --- a/services/spd/trusty/generic-arm64-smcall.h +++ b/services/spd/trusty/generic-arm64-smcall.h @@ -23,5 +23,6 @@ */ #define SMC_GET_GIC_BASE_GICD 0 #define SMC_GET_GIC_BASE_GICC 1 +#define SMC_GET_GIC_BASE_GICR 2 #define SMC_FC_GET_REG_BASE SMC_FASTCALL_NR(SMC_ENTITY_PLATFORM_MONITOR, 0x1) #define SMC_FC64_GET_REG_BASE SMC_FASTCALL64_NR(SMC_ENTITY_PLATFORM_MONITOR, 0x1) -- cgit v1.2.3 From 412865907699c67d16274e3e474969eebf83e99c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= Date: Fri, 7 Feb 2020 14:12:35 -0800 Subject: Fix boot failures on some builds linked with ld.lld. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pad the .rodata section to 16 bytes as ld.lld does not apply the ALIGN statement on the .data section to the LMA. Fixes boot failure on builds where the .rodata section happens to not be 16 bytes aligned. Change-Id: I4e95678f73d8b326c5fc749dc7d0ce84e2d603f5 Signed-off-by: Arve Hjønnevåg --- bl1/bl1.ld.S | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/bl1/bl1.ld.S b/bl1/bl1.ld.S index 877af8e01..b20859b5b 100644 --- a/bl1/bl1.ld.S +++ b/bl1/bl1.ld.S @@ -65,8 +65,13 @@ SECTIONS * No need to pad out the .rodata section to a page boundary. Next is * the .data section, which can mapped in ROM with the same memory * attributes as the .rodata section. + * + * Pad out to 16 bytes though as .data section needs to be 16 byte + * aligned and lld does not align the LMA to the aligment specified + * on the .data section. */ __RODATA_END__ = .; + . = ALIGN(16); } >ROM #else ro . : { @@ -92,6 +97,13 @@ SECTIONS *(.vectors) __RO_END__ = .; + + /* + * Pad out to 16 bytes as .data section needs to be 16 byte aligned and + * lld does not align the LMA to the aligment specified on the .data + * section. + */ + . = ALIGN(16); } >ROM #endif -- cgit v1.2.3 From 98367c8061c103159475ecf5beba48da597c84bf Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sun, 21 Oct 2018 12:44:24 -0500 Subject: arm/css/scpi: Don't panic if the SCP fails to respond Instead, pass back the error to the calling function. This allows platform code to fall back to another PSCI implementation if scpi_wait_ready() or a later SCPI command fails. Signed-off-by: Samuel Holland Change-Id: Ib4411e63c2512857f09ffffe1c405358dddeb4a6 --- drivers/arm/css/scpi/css_scpi.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/arm/css/scpi/css_scpi.c b/drivers/arm/css/scpi/css_scpi.c index c56b7c41b..416356bf2 100644 --- a/drivers/arm/css/scpi/css_scpi.c +++ b/drivers/arm/css/scpi/css_scpi.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -51,7 +51,7 @@ static void scpi_secure_message_send(size_t payload_size) mhu_secure_message_send(SCPI_MHU_SLOT_ID); } -static void scpi_secure_message_receive(scpi_cmd_t *cmd) +static int scpi_secure_message_receive(scpi_cmd_t *cmd) { uint32_t mhu_status; @@ -63,7 +63,7 @@ static void scpi_secure_message_receive(scpi_cmd_t *cmd) if (mhu_status != (1 << SCPI_MHU_SLOT_ID)) { ERROR("MHU: Unexpected protocol (MHU status: 0x%x)\n", mhu_status); - panic(); + return -1; } /* @@ -74,6 +74,8 @@ static void scpi_secure_message_receive(scpi_cmd_t *cmd) dmbld(); memcpy(cmd, (void *) SCPI_SHARED_MEM_SCP_TO_AP, sizeof(*cmd)); + + return 0; } static void scpi_secure_message_end(void) @@ -84,14 +86,19 @@ static void scpi_secure_message_end(void) int scpi_wait_ready(void) { scpi_cmd_t scpi_cmd; + int rc; VERBOSE("Waiting for SCP_READY command...\n"); /* Get a message from the SCP */ scpi_secure_message_start(); - scpi_secure_message_receive(&scpi_cmd); + rc = scpi_secure_message_receive(&scpi_cmd); scpi_secure_message_end(); + /* If no message was received, don't send a response */ + if (rc != 0) + return rc; + /* We are expecting 'SCP Ready', produce correct error if it's not */ scpi_status_t status = SCP_OK; if (scpi_cmd.id != SCPI_CMD_SCP_READY) { @@ -209,7 +216,8 @@ int scpi_get_css_power_state(unsigned int mpidr, unsigned int *cpu_state_p, * Send message and wait for SCP's response */ scpi_secure_message_send(0); - scpi_secure_message_receive(&response); + if (scpi_secure_message_receive(&response) != 0) + goto exit; if (response.status != SCP_OK) goto exit; @@ -254,7 +262,9 @@ uint32_t scpi_sys_power_state(scpi_system_state_t system_state) *payload_addr = system_state & 0xff; scpi_secure_message_send(sizeof(*payload_addr)); - scpi_secure_message_receive(&response); + /* If no response is received, fill in an error status */ + if (scpi_secure_message_receive(&response) != 0) + response.status = SCP_E_TIMEOUT; scpi_secure_message_end(); -- cgit v1.2.3 From ae3fe6e3e6119663d59831ca6cb39fc66c8ae4f3 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sun, 17 Feb 2019 15:10:36 -0600 Subject: allwinner: Adjust SRAM A2 base to include the ARISC vectors The ARISC vector area consists of 0x4000 bytes before the beginning of usable SRAM. Still, it is technically a part of SRAM A2, so include it in the memory definition. This avoids the confusing practice of subtracting from the beginning of the SRAM region when referencing the ARISC vectors. Signed-off-by: Samuel Holland Change-Id: Iae89e01aeab93560159562692e03e88306e2a1bf --- plat/allwinner/common/include/platform_def.h | 2 +- plat/allwinner/common/sunxi_common.c | 2 +- plat/allwinner/sun50i_a64/include/sunxi_mmap.h | 6 +++--- plat/allwinner/sun50i_h6/include/sunxi_mmap.h | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/plat/allwinner/common/include/platform_def.h b/plat/allwinner/common/include/platform_def.h index 32a7c0408..6f2274473 100644 --- a/plat/allwinner/common/include/platform_def.h +++ b/plat/allwinner/common/include/platform_def.h @@ -13,7 +13,7 @@ #include -#define BL31_BASE SUNXI_SRAM_A2_BASE +#define BL31_BASE (SUNXI_SRAM_A2_BASE + 0x4000) #define BL31_LIMIT (SUNXI_SRAM_A2_BASE + SUNXI_SRAM_A2_SIZE) /* Overwrite U-Boot SPL, but reserve the first page for the SPL header. */ diff --git a/plat/allwinner/common/sunxi_common.c b/plat/allwinner/common/sunxi_common.c index 3759c285e..45e415460 100644 --- a/plat/allwinner/common/sunxi_common.c +++ b/plat/allwinner/common/sunxi_common.c @@ -175,7 +175,7 @@ DEFINE_BAKERY_LOCK(arisc_lock); */ void sunxi_execute_arisc_code(uint32_t *code, size_t size, uint16_t param) { - uintptr_t arisc_reset_vec = SUNXI_SRAM_A2_BASE - 0x4000 + 0x100; + uintptr_t arisc_reset_vec = SUNXI_SRAM_A2_BASE + 0x100; do { bakery_lock_get(&arisc_lock); diff --git a/plat/allwinner/sun50i_a64/include/sunxi_mmap.h b/plat/allwinner/sun50i_a64/include/sunxi_mmap.h index db4409118..9d2542fce 100644 --- a/plat/allwinner/sun50i_a64/include/sunxi_mmap.h +++ b/plat/allwinner/sun50i_a64/include/sunxi_mmap.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -14,8 +14,8 @@ #define SUNXI_SRAM_SIZE 0x00044000 #define SUNXI_SRAM_A1_BASE 0x00010000 #define SUNXI_SRAM_A1_SIZE 0x00008000 -#define SUNXI_SRAM_A2_BASE 0x00044000 -#define SUNXI_SRAM_A2_SIZE 0x00010000 +#define SUNXI_SRAM_A2_BASE 0x00040000 +#define SUNXI_SRAM_A2_SIZE 0x00014000 #define SUNXI_SRAM_C_BASE 0x00018000 #define SUNXI_SRAM_C_SIZE 0x0001c000 #define SUNXI_DEV_BASE 0x01000000 diff --git a/plat/allwinner/sun50i_h6/include/sunxi_mmap.h b/plat/allwinner/sun50i_h6/include/sunxi_mmap.h index f36491a8a..0e204d0f0 100644 --- a/plat/allwinner/sun50i_h6/include/sunxi_mmap.h +++ b/plat/allwinner/sun50i_h6/include/sunxi_mmap.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -14,8 +14,8 @@ #define SUNXI_SRAM_SIZE 0x000f8000 #define SUNXI_SRAM_A1_BASE 0x00020000 #define SUNXI_SRAM_A1_SIZE 0x00008000 -#define SUNXI_SRAM_A2_BASE 0x00104000 -#define SUNXI_SRAM_A2_SIZE 0x00014000 +#define SUNXI_SRAM_A2_BASE 0x00100000 +#define SUNXI_SRAM_A2_SIZE 0x00018000 #define SUNXI_SRAM_C_BASE 0x00028000 #define SUNXI_SRAM_C_SIZE 0x0001e000 #define SUNXI_DEV_BASE 0x01000000 -- cgit v1.2.3 From 57b3663239fbe4deeecfbc9388691dc694649f3c Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sun, 29 Dec 2019 12:22:55 -0600 Subject: allwinner: Reserve and map space for the SCP firmware The SCP firmware is allocated the last 16KiB of SRAM A2. This includes the SCPI shared memory area, which must be mapped as MT_DEVICE to prevent problems with cache coherency between the AP CPUs and the SCP. For simplicity, map the whole SCP region as MT_DEVICE. Signed-off-by: Samuel Holland Change-Id: Ie39eb5ff281b8898a3c1d9748dc08755f528e2f8 --- plat/allwinner/common/include/platform_def.h | 9 +++++++-- plat/allwinner/common/sunxi_common.c | 2 ++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/plat/allwinner/common/include/platform_def.h b/plat/allwinner/common/include/platform_def.h index 6f2274473..1b660e151 100644 --- a/plat/allwinner/common/include/platform_def.h +++ b/plat/allwinner/common/include/platform_def.h @@ -14,7 +14,12 @@ #include #define BL31_BASE (SUNXI_SRAM_A2_BASE + 0x4000) -#define BL31_LIMIT (SUNXI_SRAM_A2_BASE + SUNXI_SRAM_A2_SIZE) +#define BL31_LIMIT (SUNXI_SRAM_A2_BASE + \ + SUNXI_SRAM_A2_SIZE - SUNXI_SCP_SIZE) + +/* The SCP firmware is allocated the last 16KiB of SRAM A2. */ +#define SUNXI_SCP_BASE BL31_LIMIT +#define SUNXI_SCP_SIZE 0x4000 /* Overwrite U-Boot SPL, but reserve the first page for the SPL header. */ #define BL31_NOBITS_BASE (SUNXI_SRAM_A1_BASE + 0x1000) @@ -51,7 +56,7 @@ #define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER_COUNT * \ PLATFORM_MAX_CPUS_PER_CLUSTER) #define PLATFORM_MAX_CPUS_PER_CLUSTER U(4) -#define PLATFORM_MMAP_REGIONS 4 +#define PLATFORM_MMAP_REGIONS 5 #define PLATFORM_STACK_SIZE (0x1000 / PLATFORM_CORE_COUNT) #ifndef SPD_none diff --git a/plat/allwinner/common/sunxi_common.c b/plat/allwinner/common/sunxi_common.c index 45e415460..0ca18adc3 100644 --- a/plat/allwinner/common/sunxi_common.c +++ b/plat/allwinner/common/sunxi_common.c @@ -21,6 +21,8 @@ static const mmap_region_t sunxi_mmap[PLATFORM_MMAP_REGIONS + 1] = { MAP_REGION_FLAT(SUNXI_SRAM_BASE, SUNXI_SRAM_SIZE, MT_RW_DATA | MT_SECURE), + MAP_REGION_FLAT(SUNXI_SCP_BASE, SUNXI_SCP_SIZE, + MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER), MAP_REGION_FLAT(SUNXI_DEV_BASE, SUNXI_DEV_SIZE, MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER), MAP_REGION(SUNXI_DRAM_BASE, SUNXI_DRAM_VIRT_BASE, SUNXI_DRAM_SEC_SIZE, -- cgit v1.2.3 From 50cabf6d22d1060012fe9c545832b2216a755ece Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sun, 21 Oct 2018 12:24:16 -0500 Subject: allwinner: Add a msgbox driver for use with SCPI The function names follow the naming convention used by the existing ARM SCPI client. Signed-off-by: Samuel Holland Change-Id: I543bae7d46e206eb405dbedfcf7aeba88a12ca48 --- drivers/allwinner/sunxi_msgbox.c | 95 +++++++++++++++++++++++++++++++ plat/allwinner/common/allwinner-common.mk | 1 + 2 files changed, 96 insertions(+) create mode 100644 drivers/allwinner/sunxi_msgbox.c diff --git a/drivers/allwinner/sunxi_msgbox.c b/drivers/allwinner/sunxi_msgbox.c new file mode 100644 index 000000000..cc4a6ffcb --- /dev/null +++ b/drivers/allwinner/sunxi_msgbox.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include +#include +#include + +#include + +#define REMOTE_IRQ_EN_REG 0x0040 +#define REMOTE_IRQ_STAT_REG 0x0050 +#define LOCAL_IRQ_EN_REG 0x0060 +#define LOCAL_IRQ_STAT_REG 0x0070 + +#define RX_IRQ(n) BIT(0 + 2 * (n)) +#define TX_IRQ(n) BIT(1 + 2 * (n)) + +#define FIFO_STAT_REG(n) (0x0100 + 0x4 * (n)) +#define FIFO_STAT_MASK GENMASK(0, 0) + +#define MSG_STAT_REG(n) (0x0140 + 0x4 * (n)) +#define MSG_STAT_MASK GENMASK(2, 0) + +#define MSG_DATA_REG(n) (0x0180 + 0x4 * (n)) + +#define RX_CHAN 1 +#define TX_CHAN 0 + +#define MHU_MAX_SLOT_ID 31 + +#define MHU_TIMEOUT_DELAY 10 +#define MHU_TIMEOUT_ITERS 10000 + +static DEFINE_BAKERY_LOCK(mhu_secure_message_lock); + +static bool sunxi_msgbox_last_tx_done(unsigned int chan) +{ + uint32_t stat = mmio_read_32(SUNXI_MSGBOX_BASE + REMOTE_IRQ_STAT_REG); + + return (stat & RX_IRQ(chan)) == 0U; +} + +static bool sunxi_msgbox_peek_data(unsigned int chan) +{ + uint32_t stat = mmio_read_32(SUNXI_MSGBOX_BASE + MSG_STAT_REG(chan)); + + return (stat & MSG_STAT_MASK) != 0U; +} + +void mhu_secure_message_start(unsigned int slot_id __unused) +{ + uint32_t timeout = MHU_TIMEOUT_ITERS; + + bakery_lock_get(&mhu_secure_message_lock); + + /* Wait for all previous messages to be acknowledged. */ + while (!sunxi_msgbox_last_tx_done(TX_CHAN) && --timeout) + udelay(MHU_TIMEOUT_DELAY); +} + +void mhu_secure_message_send(unsigned int slot_id) +{ + mmio_write_32(SUNXI_MSGBOX_BASE + MSG_DATA_REG(TX_CHAN), BIT(slot_id)); +} + +uint32_t mhu_secure_message_wait(void) +{ + uint32_t timeout = MHU_TIMEOUT_ITERS; + uint32_t msg = 0; + + /* Wait for a message from the SCP. */ + while (!sunxi_msgbox_peek_data(RX_CHAN) && --timeout) + udelay(MHU_TIMEOUT_DELAY); + + /* Return the most recent message in the FIFO. */ + while (sunxi_msgbox_peek_data(RX_CHAN)) + msg = mmio_read_32(SUNXI_MSGBOX_BASE + MSG_DATA_REG(RX_CHAN)); + + return msg; +} + +void mhu_secure_message_end(unsigned int slot_id) +{ + /* Acknowledge a response by clearing the IRQ status. */ + mmio_write_32(SUNXI_MSGBOX_BASE + LOCAL_IRQ_STAT_REG, RX_IRQ(RX_CHAN)); + + bakery_lock_release(&mhu_secure_message_lock); +} diff --git a/plat/allwinner/common/allwinner-common.mk b/plat/allwinner/common/allwinner-common.mk index 98bcf3e22..83a7992b3 100644 --- a/plat/allwinner/common/allwinner-common.mk +++ b/plat/allwinner/common/allwinner-common.mk @@ -20,6 +20,7 @@ PLAT_BL_COMMON_SOURCES := drivers/ti/uart/${ARCH}/16550_console.S \ ${AW_PLAT}/common/sunxi_common.c BL31_SOURCES += drivers/allwinner/axp/common.c \ + drivers/allwinner/sunxi_msgbox.c \ drivers/arm/gic/common/gic_common.c \ drivers/arm/gic/v2/gicv2_helpers.c \ drivers/arm/gic/v2/gicv2_main.c \ -- cgit v1.2.3 From e382c88e2a26995099bb931d49e754dcaebc5593 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sun, 21 Oct 2018 12:41:03 -0500 Subject: allwinner: Implement PSCI system suspend using SCPI If an SCP firmware is present and able to communicate via SCPI, then use that to implement CPU and system power state transitions, including CPU hotplug and system suspend. Otherwise, fall back to the existing CPU power control implementation. The last 16 KiB of SRAM A2 are reserved for the SCP firmware, and the SCPI shared memory is at the very end of this region (and therefore the end of SRAM A2). BL31 continues to start at the beginning of SRAM A2 (not counting the ARISC exception vector area) and fills up to the beginning of the SCP firmware. Because the SCP firmware is not loaded adjacent to the ARISC exception vector area, the jump instructions used for exception handling cannot be included in the SCP firmware image, and must be initialized here before turning on the SCP. Signed-off-by: Samuel Holland Change-Id: I37b9b9636f94d4125230423726f3ac5e9cdb551c --- plat/allwinner/common/allwinner-common.mk | 1 + plat/allwinner/common/include/platform_def.h | 3 + plat/allwinner/common/sunxi_pm.c | 210 +++++++++++++++++++++++++-- 3 files changed, 202 insertions(+), 12 deletions(-) diff --git a/plat/allwinner/common/allwinner-common.mk b/plat/allwinner/common/allwinner-common.mk index 83a7992b3..e60ebc6f2 100644 --- a/plat/allwinner/common/allwinner-common.mk +++ b/plat/allwinner/common/allwinner-common.mk @@ -21,6 +21,7 @@ PLAT_BL_COMMON_SOURCES := drivers/ti/uart/${ARCH}/16550_console.S \ BL31_SOURCES += drivers/allwinner/axp/common.c \ drivers/allwinner/sunxi_msgbox.c \ + drivers/arm/css/scpi/css_scpi.c \ drivers/arm/gic/common/gic_common.c \ drivers/arm/gic/v2/gicv2_helpers.c \ drivers/arm/gic/v2/gicv2_main.c \ diff --git a/plat/allwinner/common/include/platform_def.h b/plat/allwinner/common/include/platform_def.h index 1b660e151..975cc48d5 100644 --- a/plat/allwinner/common/include/platform_def.h +++ b/plat/allwinner/common/include/platform_def.h @@ -40,6 +40,9 @@ #define MAX_MMAP_REGIONS (3 + PLATFORM_MMAP_REGIONS) #define MAX_XLAT_TABLES 1 +#define PLAT_CSS_SCP_COM_SHARED_MEM_BASE \ + (SUNXI_SRAM_A2_BASE + SUNXI_SRAM_A2_SIZE - 0x200) + #define PLAT_MAX_PWR_LVL_STATES U(2) #define PLAT_MAX_RET_STATE U(1) #define PLAT_MAX_OFF_STATE U(2) diff --git a/plat/allwinner/common/sunxi_pm.c b/plat/allwinner/common/sunxi_pm.c index 9b074d2ac..e0fa5b3ec 100644 --- a/plat/allwinner/common/sunxi_pm.c +++ b/plat/allwinner/common/sunxi_pm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -17,6 +18,7 @@ #include #include +#include #include #include @@ -24,25 +26,88 @@ #define SUNXI_WDOG0_CFG_REG (SUNXI_R_WDOG_BASE + 0x0014) #define SUNXI_WDOG0_MODE_REG (SUNXI_R_WDOG_BASE + 0x0018) -#define mpidr_is_valid(mpidr) ( \ - MPIDR_AFFLVL3_VAL(mpidr) == 0 && \ - MPIDR_AFFLVL2_VAL(mpidr) == 0 && \ - MPIDR_AFFLVL1_VAL(mpidr) < PLATFORM_CLUSTER_COUNT && \ - MPIDR_AFFLVL0_VAL(mpidr) < PLATFORM_MAX_CPUS_PER_CLUSTER) +#define CPU_PWR_LVL MPIDR_AFFLVL0 +#define CLUSTER_PWR_LVL MPIDR_AFFLVL1 +#define SYSTEM_PWR_LVL MPIDR_AFFLVL2 + +#define CPU_PWR_STATE(state) \ + ((state)->pwr_domain_state[CPU_PWR_LVL]) +#define CLUSTER_PWR_STATE(state) \ + ((state)->pwr_domain_state[CLUSTER_PWR_LVL]) +#define SYSTEM_PWR_STATE(state) \ + ((state)->pwr_domain_state[SYSTEM_PWR_LVL]) + +#define mpidr_is_valid(mpidr) (plat_core_pos_by_mpidr(mpidr) >= 0) + +/* + * The addresses for the SCP exception vectors are defined in the or1k + * architecture specification. + */ +#define OR1K_VEC_FIRST 0x01 +#define OR1K_VEC_LAST 0x0e +#define OR1K_VEC_ADDR(n) (0x100 * (n)) + +/* + * This magic value is the little-endian representation of the or1k + * instruction "l.mfspr r2, r0, 0x12", which is guaranteed to be the + * first instruction in the SCP firmware. + */ +#define SCP_FIRMWARE_MAGIC 0xb4400012 + +static bool scpi_available; + +static inline scpi_power_state_t scpi_map_state(plat_local_state_t psci_state) +{ + if (is_local_state_run(psci_state)) + return scpi_power_on; + if (is_local_state_retn(psci_state)) + return scpi_power_retention; + return scpi_power_off; +} + +static void sunxi_cpu_standby(plat_local_state_t cpu_state) +{ + u_register_t scr = read_scr_el3(); + + assert(is_local_state_retn(cpu_state)); + + write_scr_el3(scr | SCR_IRQ_BIT); + wfi(); + write_scr_el3(scr); +} static int sunxi_pwr_domain_on(u_register_t mpidr) { if (mpidr_is_valid(mpidr) == 0) return PSCI_E_INTERN_FAIL; - sunxi_cpu_on(mpidr); + if (scpi_available) { + scpi_set_css_power_state(mpidr, + scpi_power_on, + scpi_power_on, + scpi_power_on); + } else { + sunxi_cpu_on(mpidr); + } return PSCI_E_SUCCESS; } static void sunxi_pwr_domain_off(const psci_power_state_t *target_state) { - gicv2_cpuif_disable(); + plat_local_state_t cpu_pwr_state = CPU_PWR_STATE(target_state); + plat_local_state_t cluster_pwr_state = CLUSTER_PWR_STATE(target_state); + plat_local_state_t system_pwr_state = SYSTEM_PWR_STATE(target_state); + + if (is_local_state_off(cpu_pwr_state)) + gicv2_cpuif_disable(); + + if (scpi_available) { + scpi_set_css_power_state(read_mpidr(), + scpi_map_state(cpu_pwr_state), + scpi_map_state(cluster_pwr_state), + scpi_map_state(system_pwr_state)); + } } static void __dead2 sunxi_pwr_down_wfi(const psci_power_state_t *target_state) @@ -55,12 +120,26 @@ static void __dead2 sunxi_pwr_down_wfi(const psci_power_state_t *target_state) static void sunxi_pwr_domain_on_finish(const psci_power_state_t *target_state) { - gicv2_pcpu_distif_init(); - gicv2_cpuif_enable(); + if (is_local_state_off(SYSTEM_PWR_STATE(target_state))) + gicv2_distif_init(); + if (is_local_state_off(CPU_PWR_STATE(target_state))) { + gicv2_pcpu_distif_init(); + gicv2_cpuif_enable(); + } } static void __dead2 sunxi_system_off(void) { + gicv2_cpuif_disable(); + + if (scpi_available) { + /* Send the power down request to the SCP */ + uint32_t ret = scpi_sys_power_state(scpi_system_shutdown); + + if (ret != SCP_OK) + ERROR("PSCI: SCPI %s failed: %d\n", "shutdown", ret); + } + /* Turn off all secondary CPUs */ sunxi_disable_secondary_cpus(read_mpidr()); @@ -74,6 +153,16 @@ static void __dead2 sunxi_system_off(void) static void __dead2 sunxi_system_reset(void) { + gicv2_cpuif_disable(); + + if (scpi_available) { + /* Send the system reset request to the SCP */ + uint32_t ret = scpi_sys_power_state(scpi_system_reboot); + + if (ret != SCP_OK) + ERROR("PSCI: SCPI %s failed: %d\n", "reboot", ret); + } + /* Reset the whole system when the watchdog times out */ mmio_write_32(SUNXI_WDOG0_CFG_REG, 1); /* Enable the watchdog with the shortest timeout (0.5 seconds) */ @@ -86,6 +175,40 @@ static void __dead2 sunxi_system_reset(void) panic(); } +static int sunxi_validate_power_state(unsigned int power_state, + psci_power_state_t *req_state) +{ + unsigned int power_level = psci_get_pstate_pwrlvl(power_state); + unsigned int type = psci_get_pstate_type(power_state); + + assert(req_state != NULL); + + if (power_level > PLAT_MAX_PWR_LVL) + return PSCI_E_INVALID_PARAMS; + + if (type == PSTATE_TYPE_STANDBY) { + /* Only one retention power state is supported. */ + if (psci_get_pstate_id(power_state) > 0) + return PSCI_E_INVALID_PARAMS; + /* The SoC cannot be suspended without losing state */ + if (power_level == SYSTEM_PWR_LVL) + return PSCI_E_INVALID_PARAMS; + for (unsigned int i = 0; i <= power_level; ++i) + req_state->pwr_domain_state[i] = PLAT_MAX_RET_STATE; + } else { + /* Only one off power state is supported. */ + if (psci_get_pstate_id(power_state) > 0) + return PSCI_E_INVALID_PARAMS; + for (unsigned int i = 0; i <= power_level; ++i) + req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE; + } + /* Higher power domain levels should all remain running */ + for (unsigned int i = power_level + 1; i <= PLAT_MAX_PWR_LVL; ++i) + req_state->pwr_domain_state[i] = PSCI_LOCAL_STATE_RUN; + + return PSCI_E_SUCCESS; +} + static int sunxi_validate_ns_entrypoint(uintptr_t ns_entrypoint) { /* The non-secure entry point must be in DRAM */ @@ -95,13 +218,45 @@ static int sunxi_validate_ns_entrypoint(uintptr_t ns_entrypoint) return PSCI_E_INVALID_ADDRESS; } +static void sunxi_get_sys_suspend_power_state(psci_power_state_t *req_state) +{ + assert(req_state); + + for (unsigned int i = 0; i <= PLAT_MAX_PWR_LVL; ++i) + req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE; +} + +static int sunxi_get_node_hw_state(u_register_t mpidr, + unsigned int power_level) +{ + unsigned int cluster_state, cpu_state; + unsigned int cpu = MPIDR_AFFLVL0_VAL(mpidr); + + /* SoC power level (always on if PSCI works). */ + if (power_level == SYSTEM_PWR_LVL) + return HW_ON; + if (scpi_get_css_power_state(mpidr, &cpu_state, &cluster_state)) + return PSCI_E_NOT_SUPPORTED; + /* Cluster power level (full power state available). */ + if (power_level == CLUSTER_PWR_LVL) { + if (cluster_state == scpi_power_on) + return HW_ON; + if (cluster_state == scpi_power_retention) + return HW_STANDBY; + return HW_OFF; + } + /* CPU power level (one bit boolean for on or off). */ + return ((cpu_state & BIT(cpu)) != 0) ? HW_ON : HW_OFF; +} + static plat_psci_ops_t sunxi_psci_ops = { + .cpu_standby = sunxi_cpu_standby, .pwr_domain_on = sunxi_pwr_domain_on, .pwr_domain_off = sunxi_pwr_domain_off, - .pwr_domain_pwr_down_wfi = sunxi_pwr_down_wfi, .pwr_domain_on_finish = sunxi_pwr_domain_on_finish, .system_off = sunxi_system_off, .system_reset = sunxi_system_reset, + .validate_power_state = sunxi_validate_power_state, .validate_ns_entrypoint = sunxi_validate_ns_entrypoint, }; @@ -110,13 +265,44 @@ int plat_setup_psci_ops(uintptr_t sec_entrypoint, { assert(psci_ops); - for (int cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu += 1) { + /* Program all CPU entry points. */ + for (unsigned int cpu = 0; cpu < PLATFORM_CORE_COUNT; ++cpu) { mmio_write_32(SUNXI_CPUCFG_RVBAR_LO_REG(cpu), sec_entrypoint & 0xffffffff); mmio_write_32(SUNXI_CPUCFG_RVBAR_HI_REG(cpu), sec_entrypoint >> 32); } + /* Check for a valid SCP firmware, and boot the SCP if found. */ + if (mmio_read_32(SUNXI_SCP_BASE) == SCP_FIRMWARE_MAGIC) { + /* Program SCP exception vectors to the firmware entrypoint. */ + for (unsigned int i = OR1K_VEC_FIRST; i <= OR1K_VEC_LAST; ++i) { + uint32_t vector = SUNXI_SRAM_A2_BASE + OR1K_VEC_ADDR(i); + uint32_t offset = SUNXI_SCP_BASE - vector; + + mmio_write_32(vector, offset >> 2); + clean_dcache_range(vector, sizeof(uint32_t)); + } + /* Take the SCP out of reset. */ + mmio_setbits_32(SUNXI_R_CPUCFG_BASE, BIT(0)); + /* Wait for the SCP firmware to boot. */ + if (scpi_wait_ready() == 0) + scpi_available = true; + } + + NOTICE("PSCI: System suspend is %s\n", + scpi_available ? "available via SCPI" : "unavailable"); + if (scpi_available) { + /* Suspend is only available via SCPI. */ + sunxi_psci_ops.pwr_domain_suspend = sunxi_pwr_domain_off; + sunxi_psci_ops.pwr_domain_suspend_finish = sunxi_pwr_domain_on_finish; + sunxi_psci_ops.get_sys_suspend_power_state = sunxi_get_sys_suspend_power_state; + sunxi_psci_ops.get_node_hw_state = sunxi_get_node_hw_state; + } else { + /* This is only needed when SCPI is unavailable. */ + sunxi_psci_ops.pwr_domain_pwr_down_wfi = sunxi_pwr_down_wfi; + } + *psci_ops = &sunxi_psci_ops; return 0; -- cgit v1.2.3 From 7f0daaa97110efc6a077241227d6fa9db29a7808 Mon Sep 17 00:00:00 2001 From: Morten Borup Petersen Date: Wed, 29 Jan 2020 16:44:17 +0000 Subject: corstone700: adding support for stack protector for the FVP Adding support for generating a semi-random number required for enabling building TF-A with stack protector support. TF-A for corstone-700 may now be built using ENABLE_STACK_PROTECTOR=all Change-Id: I03e1be1a8d4e4a822cf286f3b9ad4da4337ca765 Signed-off-by: Abdellatif El Khlifi --- .../corstone700/corstone700_stack_protector.c | 35 ++++++++++++++++++++++ .../board/corstone700/sp_min/sp_min-corstone700.mk | 8 ++++- 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 plat/arm/board/corstone700/corstone700_stack_protector.c diff --git a/plat/arm/board/corstone700/corstone700_stack_protector.c b/plat/arm/board/corstone700/corstone700_stack_protector.c new file mode 100644 index 000000000..6fd09da5b --- /dev/null +++ b/plat/arm/board/corstone700/corstone700_stack_protector.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include + +static uint32_t plat_generate_random_number(void) +{ + uintptr_t return_addr = (uintptr_t)__builtin_return_address(0U); + uintptr_t frame_addr = (uintptr_t)__builtin_frame_address(0U); + uint64_t cntpct = read_cntpct_el0(); + + /* Generate 32-bit pattern: saving the 2 least significant bytes + * in random_lo and random_hi + */ + uint16_t random_lo = (uint16_t)( + (((uint64_t)return_addr) << 13) ^ frame_addr ^ cntpct + ); + + uint16_t random_hi = (uint16_t)( + (((uint64_t)frame_addr) << 15) ^ return_addr ^ cntpct + ); + + return (((uint32_t)random_hi) << 16) | random_lo; +} + +u_register_t plat_get_stack_protector_canary(void) +{ + return plat_generate_random_number(); /* a 32-bit pattern is returned */ +} diff --git a/plat/arm/board/corstone700/sp_min/sp_min-corstone700.mk b/plat/arm/board/corstone700/sp_min/sp_min-corstone700.mk index 57e1ec3e4..acee6c39c 100644 --- a/plat/arm/board/corstone700/sp_min/sp_min-corstone700.mk +++ b/plat/arm/board/corstone700/sp_min/sp_min-corstone700.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2019, Arm Limited and Contributors. All rights reserved. +# Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -15,4 +15,10 @@ BL32_SOURCES += drivers/cfi/v2m/v2m_flash.c \ plat/arm/board/corstone700/sp_min/corstone700_sp_min_setup.c \ ${CORSTONE700_GIC_SOURCES} +ifneq (${ENABLE_STACK_PROTECTOR},0) + ifneq (${ENABLE_STACK_PROTECTOR},none) + BL32_SOURCES += plat/arm/board/corstone700/corstone700_stack_protector.c + endif +endif + include plat/arm/common/sp_min/arm_sp_min.mk -- cgit v1.2.3 From 0ad5b318f7e8e7ff35b5e607e3d11c31efeb3872 Mon Sep 17 00:00:00 2001 From: Madhukar Pappireddy Date: Thu, 13 Feb 2020 15:36:50 -0600 Subject: Fix topology description of cpus for DynamIQ based FVP DynamIQ based designs have upto 8 CPUs in each cluster. This patch fixes the device tree node which describes the topology of the CPU for DynamIQ FVP Model. Change-Id: I7146bc79029ce38314026d4853e5b6406863725c Signed-off-by: Madhukar Pappireddy --- fdts/fvp-base-gicv3-psci-common.dtsi | 2 +- fdts/fvp-base-gicv3-psci-dynamiq-2t.dts | 2 +- fdts/fvp-base-gicv3-psci-dynamiq-common.dtsi | 40 ++++++++++++++++++++++++++++ fdts/fvp-base-gicv3-psci-dynamiq.dts | 2 +- 4 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 fdts/fvp-base-gicv3-psci-dynamiq-common.dtsi diff --git a/fdts/fvp-base-gicv3-psci-common.dtsi b/fdts/fvp-base-gicv3-psci-common.dtsi index 94ed67d55..5b0470d89 100644 --- a/fdts/fvp-base-gicv3-psci-common.dtsi +++ b/fdts/fvp-base-gicv3-psci-common.dtsi @@ -39,7 +39,7 @@ #address-cells = <2>; #size-cells = <0>; - cpu-map { + CPU_MAP:cpu-map { cluster0 { core0 { cpu = <&CPU0>; diff --git a/fdts/fvp-base-gicv3-psci-dynamiq-2t.dts b/fdts/fvp-base-gicv3-psci-dynamiq-2t.dts index 48269a065..daa2e66ce 100644 --- a/fdts/fvp-base-gicv3-psci-dynamiq-2t.dts +++ b/fdts/fvp-base-gicv3-psci-dynamiq-2t.dts @@ -6,7 +6,7 @@ /dts-v1/; -#include "fvp-base-gicv3-psci-common.dtsi" +#include "fvp-base-gicv3-psci-dynamiq-common.dtsi" &CPU0 { reg = <0x0 0x0>; diff --git a/fdts/fvp-base-gicv3-psci-dynamiq-common.dtsi b/fdts/fvp-base-gicv3-psci-dynamiq-common.dtsi new file mode 100644 index 000000000..f3f768417 --- /dev/null +++ b/fdts/fvp-base-gicv3-psci-dynamiq-common.dtsi @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +#include "fvp-base-gicv3-psci-common.dtsi" + +/* DynamIQ based designs have upto 8 CPUs in each cluster */ + +&CPU_MAP { + cluster0 { + core0 { + cpu = <&CPU0>; + }; + core1 { + cpu = <&CPU1>; + }; + core2 { + cpu = <&CPU2>; + }; + core3 { + cpu = <&CPU3>; + }; + core4 { + cpu = <&CPU4>; + }; + core5 { + cpu = <&CPU5>; + }; + core6 { + cpu = <&CPU6>; + }; + core7 { + cpu = <&CPU7>; + }; + }; +}; diff --git a/fdts/fvp-base-gicv3-psci-dynamiq.dts b/fdts/fvp-base-gicv3-psci-dynamiq.dts index 51c7acacf..b8b044500 100644 --- a/fdts/fvp-base-gicv3-psci-dynamiq.dts +++ b/fdts/fvp-base-gicv3-psci-dynamiq.dts @@ -6,7 +6,7 @@ /dts-v1/; -#include "fvp-base-gicv3-psci-common.dtsi" +#include "fvp-base-gicv3-psci-dynamiq-common.dtsi" &CPU0 { reg = <0x0 0x0>; -- cgit v1.2.3 From 95d3c46a2f0db93003bebf5dc3d5568e940a773f Mon Sep 17 00:00:00 2001 From: Xi Chen Date: Fri, 14 Feb 2020 10:57:14 +0800 Subject: mediatek: mt8183: protect 4GB~8GB dram memory The offset there is the virtual address space on the bus side (1-9GB for 8GB RAM), and that emi_mpu_set_region_protection will translate to the physical memory space (0-8GB). 8GB is 33-bit (the memory bus width is 33-bit on this platform), so 0x23FFFFFFFUL-EMI_PHY_OFFSET = 0x1_FFFF_FFFF. Change-Id: I7be4759ed7546f7e15a5868b6f08988928c34075 Signed-off-by: Xi Chen --- plat/mediatek/mt8183/drivers/emi_mpu/emi_mpu.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/plat/mediatek/mt8183/drivers/emi_mpu/emi_mpu.c b/plat/mediatek/mt8183/drivers/emi_mpu/emi_mpu.c index 64d854885..56d2ce26c 100644 --- a/plat/mediatek/mt8183/drivers/emi_mpu/emi_mpu.c +++ b/plat/mediatek/mt8183/drivers/emi_mpu/emi_mpu.c @@ -138,15 +138,9 @@ void emi_mpu_init(void) (FORBIDDEN << 6)); emi_mpu_set_region_protection(0x52900000UL, 0x5FFFFFFFUL, 2, (FORBIDDEN << 3 | FORBIDDEN << 6)); - emi_mpu_set_region_protection(0x60000000UL, 0x7FFFFFFFUL, 3, + emi_mpu_set_region_protection(0x60000000UL, 0xFFFFFFFFUL, 3, (FORBIDDEN << 3 | FORBIDDEN << 6)); - emi_mpu_set_region_protection(0x80000000UL, 0x9FFFFFFFUL, 4, - (FORBIDDEN << 3 | FORBIDDEN << 6)); - emi_mpu_set_region_protection(0xA0000000UL, 0xBFFFFFFFUL, 5, - (FORBIDDEN << 3 | FORBIDDEN << 6)); - emi_mpu_set_region_protection(0xC0000000UL, 0xDFFFFFFFUL, 6, - (FORBIDDEN << 3 | FORBIDDEN << 6)); - emi_mpu_set_region_protection(0xE0000000UL, 0xFFFFFFFFUL, 7, + emi_mpu_set_region_protection(0x100000000UL, 0x23FFFFFFFUL, 4, (FORBIDDEN << 3 | FORBIDDEN << 6)); dump_emi_mpu_regions(); } -- cgit v1.2.3 From b890b36d1d8649f67b8524162d32b7b5f4fc4351 Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Thu, 13 Feb 2020 08:21:34 +0000 Subject: tools: Small improvement to print_memory_map script This patch: - Add the __COHERENT_RAM_START__ and __COHERENT_RAM_END__ symbols. - Improve how the symbols are found with a regex. - Add a build option to revert the memory layout output. Change-Id: I54ec660261431bc98d78acb0f80e3d95bc5397ac Signed-off-by: Louis Mayencourt --- Makefile | 3 ++- docs/getting_started/build-options.rst | 5 +++++ tools/memory/print_memory_map.py | 31 +++++++++++++++++++++---------- 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index 7e416784b..8b6052dc3 100644 --- a/Makefile +++ b/Makefile @@ -770,6 +770,7 @@ $(eval $(call assert_boolean,GENERATE_COT)) $(eval $(call assert_boolean,GICV2_G0_FOR_EL3)) $(eval $(call assert_boolean,HANDLE_EA_EL3_FIRST)) $(eval $(call assert_boolean,HW_ASSISTED_COHERENCY)) +$(eval $(call assert_boolean,INVERTED_MEMMAP)) $(eval $(call assert_boolean,MEASURED_BOOT)) $(eval $(call assert_boolean,NS_TIMER_SWITCH)) $(eval $(call assert_boolean,OVERRIDE_LIBC)) @@ -1088,7 +1089,7 @@ romlib.bin: libraries # Call print_memory_map tool memmap: all - ${Q}${PYTHON} $(PRINT_MEMORY_MAP) $(BUILD_PLAT) + ${Q}${PYTHON} ${PRINT_MEMORY_MAP} ${BUILD_PLAT} ${INVERTED_MEMMAP} doc: @echo " BUILD DOCUMENTATION" diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 8854a7989..d79e9f521 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -340,6 +340,11 @@ Common build options translation library (xlat tables v2) must be used; version 1 of translation library is not supported. +- ``INVERTED_MEMMAP``: memmap tool print by default lower addresses at the + bottom, higher addresses at the top. This buid flag can be set to '1' to + invert this behavior. Lower addresses will be printed at the top and higher + addresses at the bottom. + - ``JUNO_AARCH32_EL3_RUNTIME``: This build flag enables you to execute EL3 runtime software in AArch32 mode, which is required to run AArch32 on Juno. By default this flag is set to '0'. Enabling this flag builds BL1 and BL2 in diff --git a/tools/memory/print_memory_map.py b/tools/memory/print_memory_map.py index 35cccd38c..8a84018e7 100755 --- a/tools/memory/print_memory_map.py +++ b/tools/memory/print_memory_map.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (c) 2019, Arm Limited. All rights reserved. +# Copyright (c) 2019-2020, Arm Limited. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -22,6 +22,7 @@ blx_symbols = ['__BL1_RAM_START__', '__BL1_RAM_END__', '__DATA_START__', '__DATA_END__', '__STACKS_START__', '__STACKS_END__', '__BSS_END', + '__COHERENT_RAM_START__', '__COHERENT_RAM_END__', ] # Regex to extract address from map file @@ -31,8 +32,11 @@ address_pattern = re.compile(r"\b0x\w*") address_list = [] # Get the directory from command line or use a default one +inverted_print = True if len(sys.argv) >= 2: build_dir = sys.argv[1] + if len(sys.argv) >= 3: + inverted_print = sys.argv[2] == '0' else: build_dir = 'build/fvp/debug' @@ -43,7 +47,10 @@ for image in bl_images: with open (file_path, 'rt') as mapfile: for line in mapfile: for symbol in blx_symbols: - if line.find(symbol) > 0 and line.find("ASSERT") < 0: + # Regex to find symbol definition + line_pattern = re.compile(r"\b0x\w*\s*" + symbol + "\s= .") + match = line_pattern.search(line) + if match: # Extract address from line match = address_pattern.search(line) if match: @@ -52,17 +59,21 @@ for image in bl_images: # Sort by address address_list.sort(key=operator.itemgetter(0)) +# Invert list for lower address at bottom +if inverted_print: + address_list = reversed(address_list) + # Generate memory view -print('{:-^87}'.format('Memory Map from: ' + build_dir)) -for address in reversed(address_list): +print('{:-^93}'.format('Memory Map from: ' + build_dir)) +for address in address_list: if "bl1" in address[2]: - print(address[0], '+{:-^20}+ |{:^20}| |{:^20}|'.format(address[1], '', '')) + print(address[0], '+{:-^22}+ |{:^22}| |{:^22}|'.format(address[1], '', '')) elif "bl2" in address[2]: - print(address[0], '|{:^20}| +{:-^20}+ |{:^20}|'.format('', address[1], '')) + print(address[0], '|{:^22}| +{:-^22}+ |{:^22}|'.format('', address[1], '')) elif "bl31" in address[2]: - print(address[0], '|{:^20}| |{:^20}| +{:-^20}+'.format('', '', address[1])) + print(address[0], '|{:^22}| |{:^22}| +{:-^22}+'.format('', '', address[1])) else: - print(address[0], '|{:^20}| |{:^20}| +{:-^20}+'.format('', '', address[1])) + print(address[0], '|{:^22}| |{:^22}| +{:-^22}+'.format('', '', address[1])) -print('{:^20}{:_^20} {:_^20} {:_^20}'.format('', '', '', '')) -print('{:^20}{:^20} {:^20} {:^20}'.format('address', 'bl1', 'bl2', 'bl31')) +print('{:^20}{:_^22} {:_^22} {:_^22}'.format('', '', '', '')) +print('{:^20}{:^22} {:^22} {:^22}'.format('address', 'bl1', 'bl2', 'bl31')) -- cgit v1.2.3 From 13856f3779668f5b33b13261b2bcd194a7d1a097 Mon Sep 17 00:00:00 2001 From: Toshiyuki Ogasahara Date: Fri, 13 Dec 2019 14:43:52 +0900 Subject: rcar_gen3: plat: Change fixed destination address of BL31 and BL32 This patch changes the destination address of BL31 and BL32 From fixed address for getting from the each certificates. Signed-off-by: Toshiyuki Ogasahara Signed-off-by: Yoshifumi Hosoya Signed-off-by: Marek Vasut # upstream rework Change-Id: Ide11776feff25e6fdd55ab28503a15b658b2e0d5 --- plat/renesas/rcar/bl2_plat_setup.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/plat/renesas/rcar/bl2_plat_setup.c b/plat/renesas/rcar/bl2_plat_setup.c index 578892eb3..891096724 100644 --- a/plat/renesas/rcar/bl2_plat_setup.c +++ b/plat/renesas/rcar/bl2_plat_setup.c @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include #include #include @@ -33,6 +35,7 @@ #endif #include "io_common.h" +#include "io_rcar.h" #include "qos_init.h" #include "rcar_def.h" #include "rcar_private.h" @@ -382,10 +385,28 @@ cold_boot: return 0; } +static uint64_t rcar_get_dest_addr_from_cert(uint32_t certid, uintptr_t *dest) +{ + uint32_t cert, len; + int ret; + + ret = rcar_get_certificate(certid, &cert); + if (ret) { + ERROR("%s : cert file load error", __func__); + return 1; + } + + rcar_read_certificate((uint64_t) cert, &len, dest); + + return 0; +} + int bl2_plat_handle_post_image_load(unsigned int image_id) { static bl2_to_bl31_params_mem_t *params; bl_mem_params_node_t *bl_mem_params; + uintptr_t dest; + int ret; if (!params) { params = (bl2_to_bl31_params_mem_t *) PARAMS_BASE; @@ -396,8 +417,17 @@ int bl2_plat_handle_post_image_load(unsigned int image_id) switch (image_id) { case BL31_IMAGE_ID: + ret = rcar_get_dest_addr_from_cert(SOC_FW_CONTENT_CERT_ID, + &dest); + if (!ret) + bl_mem_params->image_info.image_base = dest; break; case BL32_IMAGE_ID: + ret = rcar_get_dest_addr_from_cert(TRUSTED_OS_FW_CONTENT_CERT_ID, + &dest); + if (!ret) + bl_mem_params->image_info.image_base = dest; + memcpy(¶ms->bl32_ep_info, &bl_mem_params->ep_info, sizeof(entry_point_info_t)); break; -- cgit v1.2.3 From 2701a058361fe6ab367b35e3cca2c4aa5a325c49 Mon Sep 17 00:00:00 2001 From: Toshiyuki Ogasahara Date: Fri, 13 Dec 2019 14:50:30 +0900 Subject: rcar_gen3: plat: Update IPL and Secure Monitor Rev.2.0.5 Signed-off-by: Toshiyuki Ogasahara Signed-off-by: Yoshifumi Hosoya Signed-off-by: Marek Vasut # upstream update Change-Id: I8ef32a67f7984d8bcfcc3655988b559efa6e65ab --- plat/renesas/rcar/include/rcar_version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plat/renesas/rcar/include/rcar_version.h b/plat/renesas/rcar/include/rcar_version.h index 2d400e064..93ce54cfa 100644 --- a/plat/renesas/rcar/include/rcar_version.h +++ b/plat/renesas/rcar/include/rcar_version.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,7 +9,7 @@ #include -#define VERSION_OF_RENESAS "2.0.4" +#define VERSION_OF_RENESAS "2.0.5" #define VERSION_OF_RENESAS_MAXLEN (128) extern const uint8_t version_of_renesas[VERSION_OF_RENESAS_MAXLEN]; -- cgit v1.2.3 From ba63b5c93e8116f919c85bfb437b32b7c6b1a7cc Mon Sep 17 00:00:00 2001 From: Chiaki Fujii Date: Wed, 18 Sep 2019 13:10:00 +0900 Subject: rcar_gen3: drivers: ddr: Update DDR setting for H3, M3, M3N [IPL/DDR] - Update H3, M3, M3N DDR setting rev.0.38. Signed-off-by: Chiaki Fujii Signed-off-by: Marek Vasut # upstream update Change-Id: I49cf8f778b849a6ee97bc9f6948c45b07dc467b1 --- drivers/renesas/rcar/ddr/ddr_b/boot_init_dram.c | 77 +++++++++++----------- .../renesas/rcar/ddr/ddr_b/boot_init_dram_config.c | 11 +++- .../renesas/rcar/ddr/ddr_b/boot_init_dram_regdef.h | 6 +- 3 files changed, 48 insertions(+), 46 deletions(-) diff --git a/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram.c b/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram.c index 1d6e83a2c..77a07f72a 100644 --- a/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram.c +++ b/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, Renesas Electronics Corporation. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -2383,37 +2383,6 @@ static void dbsc_regset_post(void) mmio_write_32(DBSC_DBRFCNF1, 0x00080000 | (data_l & 0x0000ffff)); mmio_write_32(DBSC_DBRFCNF2, 0x00010000 | DBSC_REFINTS); -#ifdef DDR_BACKUPMODE - if (ddr_backup == DRAM_BOOT_STATUS_WARM) { -#ifdef DDR_BACKUPMODE_HALF /* for Half channel(ch0,1 only) */ - DEBUG(" DEBUG_MESS : DDR_BACKUPMODE_HALF ", 1); - send_dbcmd(0x08040001); - wait_dbcmd(); - send_dbcmd(0x0A040001); - wait_dbcmd(); - send_dbcmd(0x04040010); - wait_dbcmd(); - - if (prr_product == PRR_PRODUCT_H3) { - send_dbcmd(0x08140001); - wait_dbcmd(); - send_dbcmd(0x0A140001); - wait_dbcmd(); - send_dbcmd(0x04140010); - wait_dbcmd(); - } -#else /* DDR_BACKUPMODE_HALF //for All channels */ - send_dbcmd(0x08840001); - wait_dbcmd(); - send_dbcmd(0x0A840001); - wait_dbcmd(); - - send_dbcmd(0x04840010); - wait_dbcmd(); -#endif /* DDR_BACKUPMODE_HALF */ - } -#endif /* DDR_BACKUPMODE */ - #if RCAR_REWT_TRAINING != 0 /* Periodic-WriteDQ Training seeting */ if (((prr_product == PRR_PRODUCT_H3) && @@ -2422,12 +2391,7 @@ static void dbsc_regset_post(void) (prr_cut == PRR_PRODUCT_10))) { /* non : H3 Ver.1.x/M3-W Ver.1.0 not support */ } else { - /* - * H3 Ver.2.0 or later/M3-W Ver.1.1 or - * later/M3-N/V3H -> Periodic-WriteDQ Training seeting - */ - - /* Periodic WriteDQ Training seeting */ + /* H3 Ver.2.0 or later/M3-W Ver.1.1 or later/M3-N/V3H */ mmio_write_32(DBSC_DBDFIPMSTRCNF, 0x00000000); ddr_setval_ach_as(_reg_PHY_WDQLVL_PATT, 0x04); @@ -2440,7 +2404,6 @@ static void dbsc_regset_post(void) _reg_PI_WDQLVL_CS_MAP)); ddr_setval_ach(_reg_PI_LONG_COUNT_MASK, 0x1f); ddr_setval_ach(_reg_PI_WDQLVL_VREF_EN, 0x00); - ddr_setval_ach(_reg_PI_WDQLVL_INTERVAL, 0x0100); ddr_setval_ach(_reg_PI_WDQLVL_ROTATE, 0x01); ddr_setval_ach(_reg_PI_TREF_F0, 0x0000); ddr_setval_ach(_reg_PI_TREF_F1, 0x0000); @@ -2458,8 +2421,10 @@ static void dbsc_regset_post(void) mmio_write_32(DBSC_DBDFIPMSTRCNF, 0x00000011); } #endif /* RCAR_REWT_TRAINING */ - /* periodic dram zqcal and phy ctrl update enable */ + /* periodic dram zqcal enable */ mmio_write_32(DBSC_DBCALCNF, 0x01000010); + + /* periodic phy ctrl update enable */ if (((prr_product == PRR_PRODUCT_H3) && (prr_cut <= PRR_PRODUCT_11)) || ((prr_product == PRR_PRODUCT_M3) && @@ -2477,7 +2442,36 @@ static void dbsc_regset_post(void) #endif /* RCAR_DRAM_SPLIT == 2 */ } +#ifdef DDR_BACKUPMODE + /* SRX */ + if (ddr_backup == DRAM_BOOT_STATUS_WARM) { +#ifdef DDR_BACKUPMODE_HALF /* for Half channel(ch0, 1 only) */ + NOTICE("BL2: [DEBUG_MESS] DDR_BACKUPMODE_HALF\n"); + send_dbcmd(0x0A040001); + if (Prr_Product == PRR_PRODUCT_H3) + send_dbcmd(0x0A140001); +#else /* DDR_BACKUPMODE_HALF */ /* for All channels */ + send_dbcmd(0x0A840001); +#endif /* DDR_BACKUPMODE_HALF */ + } +#endif /* DDR_BACKUPMODE */ + + /* set Auto Refresh */ mmio_write_32(DBSC_DBRFEN, 0x00000001); + +#if RCAR_REWT_TRAINING != 0 + /* Periodic WriteDQ Traning */ + if (((prr_product == PRR_PRODUCT_H3) && + (prr_cut <= PRR_PRODUCT_11)) || + ((prr_product == PRR_PRODUCT_M3) && + (prr_cut == PRR_PRODUCT_10))) { + /* non : H3 Ver.1.x/M3-W Ver.1.0 not support */ + } else { + /* H3 Ver.2.0 or later/M3-W Ver.1.1 or later/M3-N/V3H */ + ddr_setval_ach(_reg_PI_WDQLVL_INTERVAL, 0x0100); + } +#endif /* RCAR_REWT_TRAINING */ + /* dram access enable */ mmio_write_32(DBSC_DBACEN, 0x00000001); @@ -3026,6 +3020,9 @@ static uint32_t init_ddr(void) return INITDRAM_ERR_O; MSG_LF(__func__ ":5\n"); + /* Dummy PDE */ + send_dbcmd(0x08840000); + /* PDX */ send_dbcmd(0x08840001); diff --git a/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_config.c b/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_config.c index f8caade27..878f5ec43 100644 --- a/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_config.c +++ b/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_config.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, Renesas Electronics Corporation. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -1571,8 +1571,13 @@ void boardcnf_get_ddr_mbps(uint32_t brd, uint32_t *mbps, uint32_t *div) { uint32_t md; - md = (mmio_read_32(RST_MODEMR) >> 17) & 0x5; - md = (md | (md >> 1)) & 0x3; + if (prr_product == PRR_PRODUCT_V3H) { + md = (mmio_read_32(RST_MODEMR) >> 19) & 0x1; + md = (md | (md << 1)) & 0x3; /* 0 or 3 */ + } else { + md = (mmio_read_32(RST_MODEMR) >> 17) & 0x5; + md = (md | (md >> 1)) & 0x3; + } switch (md) { case 0x0: *mbps = 3200; diff --git a/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_regdef.h b/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_regdef.h index 5047e5cc2..870b357f3 100644 --- a/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_regdef.h +++ b/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_regdef.h @@ -1,11 +1,11 @@ /* - * Copyright (c) 2015-2019, Renesas Electronics Corporation. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ -#define RCAR_DDR_VERSION "rev.0.37" +#define RCAR_DDR_VERSION "rev.0.38" #define DRAM_CH_CNT 0x04 #define SLICE_CNT 0x04 #define CS_CNT 0x02 @@ -22,7 +22,7 @@ /* for ddr deisity setting */ #define DBMEMCONF_REG(d3, row, bank, col, dw) \ - ((d3) << 30 | ((row) << 24) | ((bank) << 16) | ((col) << 8) | (dw)) + (((d3) << 30) | ((row) << 24) | ((bank) << 16) | ((col) << 8) | (dw)) #define DBMEMCONF_REGD(density) \ (DBMEMCONF_REG((density) % 2, ((density) + 1) / \ -- cgit v1.2.3 From 0fdfe245f14859c4100233fdd32dea42ca8816c4 Mon Sep 17 00:00:00 2001 From: Yusuke Goda Date: Thu, 28 Nov 2019 13:30:58 +0900 Subject: rcar_gen3: drivers: board: Add new board revision for M3ULCB Board Revision[2:0] 3'b000 Rev1.0 3'b011 Rev3.0 [New] Signed-off-by: Yusuke Goda Signed-off-by: Marek Vasut # upstream update Change-Id: Ie4f3ac83cc20120ede21052f7452327049565e60 --- drivers/renesas/rcar/board/board.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/renesas/rcar/board/board.c b/drivers/renesas/rcar/board/board.c index df17802aa..cd194ff9f 100644 --- a/drivers/renesas/rcar/board/board.c +++ b/drivers/renesas/rcar/board/board.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights * reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -33,7 +33,7 @@ #define SXS_ID { 0x10U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU } #define SX_ID { 0x10U, 0x11U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU } #define SKP_ID { 0x10U, 0x10U, 0x20U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU } -#define SK_ID { 0x10U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU } +#define SK_ID { 0x10U, 0x30U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU } #define EB4_ID { 0x10U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU } #define EB_ID { 0x10U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU } #define DR_ID { 0x10U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU } -- cgit v1.2.3 From 1f420077b6c5e1c0e6396ec61363b1f8effbeb4e Mon Sep 17 00:00:00 2001 From: Chiaki Fujii Date: Fri, 6 Dec 2019 19:33:34 +0900 Subject: rcar_gen3: drivers: ddr: Update DDR setting for H3, M3, M3N [IPL/DDR] - Update H3, M3, M3N DDR setting rev.0.39. Signed-off-by: Chiaki Fujii Signed-off-by: Marek Vasut # upstream update Change-Id: I0dbf8091f9de9bb6d2d4f94007a5813fff14789f --- drivers/renesas/rcar/ddr/ddr_b/boot_init_dram.c | 75 ++++++++++++++++------ .../renesas/rcar/ddr/ddr_b/boot_init_dram_config.c | 9 ++- .../renesas/rcar/ddr/ddr_b/boot_init_dram_regdef.h | 2 +- drivers/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3n.h | 4 +- 4 files changed, 65 insertions(+), 25 deletions(-) diff --git a/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram.c b/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram.c index 77a07f72a..1234fb667 100644 --- a/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram.c +++ b/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram.c @@ -510,6 +510,14 @@ static void send_dbcmd(uint32_t cmd) dsb_sev(); } +static void dbwait_loop(uint32_t wait_loop) +{ + uint32_t i; + + for (i = 0; i < wait_loop; i++) + wait_dbcmd(); +} + /* DDRPHY register access (raw) */ static uint32_t reg_ddrphy_read(uint32_t phyno, uint32_t regadd) { @@ -866,6 +874,7 @@ struct _jedec_spec1 { uint8_t WL; uint8_t nwr; uint8_t nrtp; + uint8_t odtlon; uint8_t MR1; uint8_t MR2; }; @@ -877,21 +886,21 @@ struct _jedec_spec1 { #define JS1_MR2(f) (0x00 | ((f) << 3) | (f)) const struct _jedec_spec1 js1[JS1_FREQ_TBL_NUM] = { /* 533.333Mbps */ - { 800, 6, 6, 4, 6, 8, JS1_MR1(0), JS1_MR2(0) | 0x40 }, + { 800, 6, 6, 4, 6, 8, 0, JS1_MR1(0), JS1_MR2(0) | 0x40 }, /* 1066.666Mbps */ - { 1600, 10, 12, 8, 10, 8, JS1_MR1(1), JS1_MR2(1) | 0x40 }, + { 1600, 10, 12, 8, 10, 8, 0, JS1_MR1(1), JS1_MR2(1) | 0x40 }, /* 1600.000Mbps */ - { 2400, 14, 16, 12, 16, 8, JS1_MR1(2), JS1_MR2(2) | 0x40 }, + { 2400, 14, 16, 12, 16, 8, 6, JS1_MR1(2), JS1_MR2(2) | 0x40 }, /* 2133.333Mbps */ - { 3200, 20, 22, 10, 20, 8, JS1_MR1(3), JS1_MR2(3) }, + { 3200, 20, 22, 10, 20, 8, 4, JS1_MR1(3), JS1_MR2(3) }, /* 2666.666Mbps */ - { 4000, 24, 28, 12, 24, 10, JS1_MR1(4), JS1_MR2(4) }, + { 4000, 24, 28, 12, 24, 10, 4, JS1_MR1(4), JS1_MR2(4) }, /* 3200.000Mbps */ - { 4800, 28, 32, 14, 30, 12, JS1_MR1(5), JS1_MR2(5) }, + { 4800, 28, 32, 14, 30, 12, 6, JS1_MR1(5), JS1_MR2(5) }, /* 3733.333Mbps */ - { 5600, 32, 36, 16, 34, 14, JS1_MR1(6), JS1_MR2(6) }, + { 5600, 32, 36, 16, 34, 14, 6, JS1_MR1(6), JS1_MR2(6) }, /* 4266.666Mbps */ - { 6400, 36, 40, 18, 40, 16, JS1_MR1(7), JS1_MR2(7) } + { 6400, 36, 40, 18, 40, 16, 8, JS1_MR1(7), JS1_MR2(7) } }; struct _jedec_spec2 { @@ -921,7 +930,8 @@ struct _jedec_spec2 { #define js2_tzqcalns 19 #define js2_tzqlat 20 #define js2_tiedly 21 -#define JS2_TBLCNT 22 +#define js2_tODTon_min 22 +#define JS2_TBLCNT 23 #define js2_trcpb (JS2_TBLCNT) #define js2_trcab (JS2_TBLCNT + 1) @@ -954,7 +964,8 @@ const struct _jedec_spec2 jedec_spec2[2][JS2_TBLCNT] = { /*tMRD*/ {14000, 10}, /*tZQCALns*/ {1000 * 10, 0}, /*tZQLAT*/ {30000, 10}, -/*tIEdly*/ {12500, 0} +/*tIEdly*/ {12500, 0}, +/*tODTon_min*/ {1500, 0} }, { /*tSR */ {15000, 3}, /*tXP */ {7500, 3}, @@ -977,7 +988,8 @@ const struct _jedec_spec2 jedec_spec2[2][JS2_TBLCNT] = { /*tMRD*/ {14000, 10}, /*tZQCALns*/ {1000 * 10, 0}, /*tZQLAT*/ {30000, 10}, -/*tIEdly*/ {12500, 0} +/*tIEdly*/ {12500, 0}, +/*tODTon_min*/ {1500, 0} } }; @@ -1452,7 +1464,7 @@ static void ddrtbl_load(void) if ((prr_product == PRR_PRODUCT_M3N) || (prr_product == PRR_PRODUCT_V3H)) { ddrtbl_setval(_cnf_DDR_PHY_SLICE_REGSET, - _reg_PHY_RDDATA_EN_OE_DLY, dataS); + _reg_PHY_RDDATA_EN_OE_DLY, dataS - 2); } ddrtbl_setval(_cnf_DDR_PI_REGSET, _reg_PI_RDLAT_ADJ_F1, RL - dataS); @@ -1498,9 +1510,10 @@ static void ddrtbl_load(void) /* DDRPHY INT START */ if ((prr_product == PRR_PRODUCT_H3) && (prr_cut <= PRR_PRODUCT_11)) { - /* non */ + /* non */ } else { regif_pll_wa(); + dbwait_loop(5); } /* FREQ_SEL_MULTICAST & PER_CS_TRAINING_MULTICAST SET (for safety) */ @@ -2067,12 +2080,18 @@ static void dbsc_regset(void) /* DBTR9.TRDPR : tRTP */ mmio_write_32(DBSC_DBTR(9), js2[js2_trtp]); - /* DBTR10.TWR : nwr */ - mmio_write_32(DBSC_DBTR(10), js1[js1_ind].nwr); + /* DBTR10.TWR : nWR + 1 */ + mmio_write_32(DBSC_DBTR(10), js1[js1_ind].nwr + 1); - /* DBTR11.TRDWR : RL + tDQSCK + BL/2 + Rounddown(tRPST) - WL + tWPRE */ + /* + * DBTR11.TRDWR : RL + BL / 2 + Rounddown(tRPST) + PHY_ODTLoff - + * odtlon + tDQSCK - tODTon,min + + * PCB delay (out+in) + tPHY_ODToff + */ mmio_write_32(DBSC_DBTR(11), - RL + js2[js2_tdqsck] + (16 / 2) + 1 - WL + 2 + 2); + RL + (16 / 2) + 1 + 2 - js1[js1_ind].odtlon + + js2[js2_tdqsck] - js2[js2_tODTon_min] + + _f_scale(ddr_mbps, ddr_mbpsdiv, 1300, 0)); /* DBTR12.TWRRD : WL + 1 + BL/2 + tWTR */ data_l = WL + 1 + (16 / 2) + js2[js2_twtr]; @@ -2338,10 +2357,23 @@ static void dbsc_regset_post(void) } } if ((prr_product == PRR_PRODUCT_H3) && (prr_cut > PRR_PRODUCT_11)) { +#if RCAR_DRAM_SPLIT == 2 + if (board_cnf->phyvalid == 0x05) { + mmio_write_32(DBSC_DBTR(24), + (rdlat_max << 24) + (rdlat_min << 16) + + mmio_read_32(DBSC_DBTR(24))); + } else { + mmio_write_32(DBSC_DBTR(24), + ((rdlat_max * 2 - rdlat_min + 4) << 24) + + ((rdlat_min + 2) << 16) + + mmio_read_32(DBSC_DBTR(24))); + } +#else /*RCAR_DRAM_SPLIT == 2 */ mmio_write_32(DBSC_DBTR(24), ((rdlat_max * 2 - rdlat_min + 4) << 24) + ((rdlat_min + 2) << 16) + mmio_read_32(DBSC_DBTR(24))); +#endif /*RCAR_DRAM_SPLIT == 2 */ } else { mmio_write_32(DBSC_DBTR(24), ((rdlat_max + 2) << 24) + @@ -3474,10 +3506,13 @@ static uint32_t wdqdm_man(void) { uint32_t err, retry_cnt; const uint32_t retry_max = 0x10; - uint32_t ch, ddr_csn, mr14_bkup[4][4]; + uint32_t datal, ch, ddr_csn, mr14_bkup[4][4]; + + datal = RL + js2[js2_tdqsck] + (16 / 2) + 1 - WL + 2 + 2 + 19; + if ((mmio_read_32(DBSC_DBTR(11)) & 0xFF) > datal) + datal = mmio_read_32(DBSC_DBTR(11)) & 0xFF; + ddr_setval_ach(_reg_PI_TDFI_WDQLVL_RW, datal); - ddr_setval_ach(_reg_PI_TDFI_WDQLVL_RW, - (mmio_read_32(DBSC_DBTR(11)) & 0xFF) + 19); if (((prr_product == PRR_PRODUCT_H3) && (prr_cut > PRR_PRODUCT_11)) || (prr_product == PRR_PRODUCT_M3N) || (prr_product == PRR_PRODUCT_V3H)) { diff --git a/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_config.c b/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_config.c index 878f5ec43..de126de86 100644 --- a/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_config.c +++ b/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_config.c @@ -1727,8 +1727,13 @@ static uint32_t _board_judge(void) #endif } } else if (prr_product == PRR_PRODUCT_M3) { - /* RENESAS Starter Kit(M3-W/SIP 8Gbit 1rank) board */ - brd = 3; + if (prr_cut >= PRR_PRODUCT_30) { + /* RENESAS Starter Kit (M3-W Ver.3.0/SIP) */ + brd = 18; + } else { + /* RENESAS Starter Kit(M3-W/SIP 8Gbit 1rank) board */ + brd = 3; + } } else { /* RENESAS Starter Kit(M3-N/SIP) board */ brd = 11; diff --git a/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_regdef.h b/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_regdef.h index 870b357f3..dc153a67f 100644 --- a/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_regdef.h +++ b/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_regdef.h @@ -5,7 +5,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#define RCAR_DDR_VERSION "rev.0.38" +#define RCAR_DDR_VERSION "rev.0.39" #define DRAM_CH_CNT 0x04 #define SLICE_CNT 0x04 #define CS_CNT 0x02 diff --git a/drivers/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3n.h b/drivers/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3n.h index 8d80842fd..fb3032dee 100644 --- a/drivers/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3n.h +++ b/drivers/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3n.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, Renesas Electronics Corporation. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -116,7 +116,7 @@ static const uint32_t DDR_PHY_SLICE_REGSET_M3N[DDR_PHY_SLICE_REGSET_NUM_M3N] = { /*0859*/ 0x00000200, /*085a*/ 0x00000004, /*085b*/ 0x4041a151, - /*085c*/ 0x0141c0a0, + /*085c*/ 0x0141a0a0, /*085d*/ 0x0000c0c0, /*085e*/ 0x0e0c000e, /*085f*/ 0x10001000, -- cgit v1.2.3 From cc4e7ad49e5a288dff9236a57aca3858548d26aa Mon Sep 17 00:00:00 2001 From: Chiaki Fujii Date: Thu, 26 Dec 2019 12:57:40 +0900 Subject: rcar_gen3: drivers: ddr: Update DDR setting for H3, M3, M3N [IPL/DDR] - Update H3, M3, M3N DDR setting rev.0.40. Signed-off-by: Chiaki Fujii Signed-off-by: Marek Vasut # upstream update Change-Id: If675796a2314e769602af21bf5cc6b10962d4f29 --- drivers/renesas/rcar/ddr/ddr_b/boot_init_dram.c | 4 ++-- drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_regdef.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram.c b/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram.c index 1234fb667..ac83c9a10 100644 --- a/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram.c +++ b/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram.c @@ -2080,8 +2080,8 @@ static void dbsc_regset(void) /* DBTR9.TRDPR : tRTP */ mmio_write_32(DBSC_DBTR(9), js2[js2_trtp]); - /* DBTR10.TWR : nWR + 1 */ - mmio_write_32(DBSC_DBTR(10), js1[js1_ind].nwr + 1); + /* DBTR10.TWR : nWR */ + mmio_write_32(DBSC_DBTR(10), js1[js1_ind].nwr); /* * DBTR11.TRDWR : RL + BL / 2 + Rounddown(tRPST) + PHY_ODTLoff - diff --git a/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_regdef.h b/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_regdef.h index dc153a67f..56363eb99 100644 --- a/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_regdef.h +++ b/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_regdef.h @@ -5,7 +5,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#define RCAR_DDR_VERSION "rev.0.39" +#define RCAR_DDR_VERSION "rev.0.40" #define DRAM_CH_CNT 0x04 #define SLICE_CNT 0x04 #define CS_CNT 0x02 -- cgit v1.2.3 From 03360b3c0e5b0c5a6c2c0609cb9953d688b7052e Mon Sep 17 00:00:00 2001 From: Yoshifumi Hosoya Date: Fri, 7 Feb 2020 11:23:33 +0900 Subject: rcar_gen3: plat: Update IPL and Secure Monitor Rev.2.0.6 Signed-off-by: Yoshifumi Hosoya Signed-off-by: Marek Vasut # upstream update Change-Id: I70c3d873b1d05075257034aee5e19c754be911e0 --- plat/renesas/rcar/include/rcar_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/renesas/rcar/include/rcar_version.h b/plat/renesas/rcar/include/rcar_version.h index 93ce54cfa..5130ad274 100644 --- a/plat/renesas/rcar/include/rcar_version.h +++ b/plat/renesas/rcar/include/rcar_version.h @@ -9,7 +9,7 @@ #include -#define VERSION_OF_RENESAS "2.0.5" +#define VERSION_OF_RENESAS "2.0.6" #define VERSION_OF_RENESAS_MAXLEN (128) extern const uint8_t version_of_renesas[VERSION_OF_RENESAS_MAXLEN]; -- cgit v1.2.3 From 3b87c4b656d2e526f7177cb617d7c6744aed155d Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 9 Feb 2020 11:57:24 +0100 Subject: rcar_gen3: plat: Minor coding style fix for rcar_version.h Use space after #define consistently, drop useless parenthesis, no functional change. Signed-off-by: Marek Vasut Change-Id: I72846d8672cab09b128e3118f4b7042a5a9c0df5 --- plat/renesas/rcar/include/rcar_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/renesas/rcar/include/rcar_version.h b/plat/renesas/rcar/include/rcar_version.h index 5130ad274..67cbd71ab 100644 --- a/plat/renesas/rcar/include/rcar_version.h +++ b/plat/renesas/rcar/include/rcar_version.h @@ -10,7 +10,7 @@ #include #define VERSION_OF_RENESAS "2.0.6" -#define VERSION_OF_RENESAS_MAXLEN (128) +#define VERSION_OF_RENESAS_MAXLEN 128 extern const uint8_t version_of_renesas[VERSION_OF_RENESAS_MAXLEN]; -- cgit v1.2.3 From 11a0a46a899fcc3b1fdb214b382f3d7495d88eca Mon Sep 17 00:00:00 2001 From: XiaoDong Huang Date: Thu, 13 Feb 2020 14:11:31 +0800 Subject: rockchip: fix definition of struct param_ddr_usage In extreme cases, the number of secure regions is one more than non-secure regions. So array "s_base" and "s_top"s size in struct param_ddr_usage need to be adjust to "DDR_REGION_NR_MAX + 1". Signed-off-by: XiaoDong Huang Change-Id: Ifc09da2c8f8afa1aebcc78f8fbc21ac95abdece2 --- plat/rockchip/common/drivers/parameter/ddr_parameter.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plat/rockchip/common/drivers/parameter/ddr_parameter.h b/plat/rockchip/common/drivers/parameter/ddr_parameter.h index 61349c44c..25c93a191 100644 --- a/plat/rockchip/common/drivers/parameter/ddr_parameter.h +++ b/plat/rockchip/common/drivers/parameter/ddr_parameter.h @@ -35,8 +35,8 @@ struct param_ddr_usage { uint64_t ns_top[DDR_REGION_NR_MAX]; uint32_t s_nr; - uint64_t s_base[DDR_REGION_NR_MAX]; - uint64_t s_top[DDR_REGION_NR_MAX]; + uint64_t s_base[DDR_REGION_NR_MAX + 1]; + uint64_t s_top[DDR_REGION_NR_MAX + 1]; }; struct param_ddr_usage ddr_region_usage_parse(uint64_t addr, uint64_t max_mb); -- cgit v1.2.3 From c6fe43b726f16e45863a409e0a94d0c816b33f70 Mon Sep 17 00:00:00 2001 From: Khandelwal Date: Wed, 29 Jan 2020 16:51:42 +0000 Subject: Corstone700: add support for mhuv2 in arm TF-A Note: This patch implements in-band messaging protocol only. ARM has launched a next version of MHU i.e. MHUv2 with its latest subsystems. The main change is that the MHUv2 is now a distributed IP with different peripheral views (registers) for the sender and receiver. Another main difference is that MHUv1 duplex channels are now split into simplex/half duplex in MHUv2. MHUv2 has a configurable number of communication channels. There is a capability register (MSG_NO_CAP) to find out how many channels are available in a system. The register offsets have also changed for STAT, SET & CLEAR registers from 0x0, 0x8 & 0x10 in MHUv1 to 0x0, 0xC & 0x8 in MHUv2 respectively. 0x0 0x4 0x8 0xC 0x1F ------------------------....----- | STAT | | | SET | | | ------------------------....----- Transmit Channel 0x0 0x4 0x8 0xC 0x1F ------------------------....----- | STAT | | CLR | | | | ------------------------....----- Receive Channel The MHU controller can request the receiver to wake-up and once the request is removed, the receiver may go back to sleep, but the MHU itself does not actively put a receiver to sleep. So, in order to wake-up the receiver when the sender wants to send data, the sender has to set ACCESS_REQUEST register first in order to wake-up receiver, state of which can be detected using ACCESS_READY register. ACCESS_REQUEST has an offset of 0xF88 & ACCESS_READY has an offset of 0xF8C and are accessible only on any sender channel. This patch adds necessary changes in a new file required to support the latest MHUv2 controller. This patch also needs an update in DT binding for ARM MHUv2 as we need a second register base (tx base) which would be used as the send channel base. Change-Id: I1455e08b3d88671a191c558790c503eabe07a8e6 Signed-off-by: Tushar Khandelwal --- plat/arm/board/corstone700/corstone700_plat.c | 5 +- plat/arm/board/corstone700/drivers/mhu/mhu.c | 117 ++++++++++++++++++++++ plat/arm/board/corstone700/drivers/mhu/mhu.h | 37 +++++++ plat/arm/board/corstone700/include/platform_def.h | 6 +- plat/arm/board/corstone700/platform.mk | 17 ++-- 5 files changed, 173 insertions(+), 9 deletions(-) create mode 100644 plat/arm/board/corstone700/drivers/mhu/mhu.c create mode 100644 plat/arm/board/corstone700/drivers/mhu/mhu.h diff --git a/plat/arm/board/corstone700/corstone700_plat.c b/plat/arm/board/corstone700/corstone700_plat.c index cee6fd618..e2ade7098 100644 --- a/plat/arm/board/corstone700/corstone700_plat.c +++ b/plat/arm/board/corstone700/corstone700_plat.c @@ -1,10 +1,12 @@ /* - * Copyright (c) 2019, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include + +#include #include #include #include @@ -26,6 +28,7 @@ const mmap_region_t plat_arm_mmap[] = { */ void __init plat_arm_pwrc_setup(void) { + mhu_secure_init(); } unsigned int plat_get_syscnt_freq2(void) diff --git a/plat/arm/board/corstone700/drivers/mhu/mhu.c b/plat/arm/board/corstone700/drivers/mhu/mhu.c new file mode 100644 index 000000000..2231d1173 --- /dev/null +++ b/plat/arm/board/corstone700/drivers/mhu/mhu.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2019-2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include +#include + +#include "mhu.h" +#include +#include + +ARM_INSTANTIATE_LOCK; + +#pragma weak plat_arm_pwrc_setup + +/* + * Slot 31 is reserved because the MHU hardware uses this register bit to + * indicate a non-secure access attempt. The total number of available slots is + * therefore 31 [30:0]. + */ +#define MHU_MAX_SLOT_ID 30 + +void mhu_secure_message_start(uintptr_t address, unsigned int slot_id) +{ + unsigned int intr_stat_check; + uint64_t timeout_cnt; + volatile uint8_t expiration; + + assert(slot_id <= MHU_MAX_SLOT_ID); + arm_lock_get(); + + /* + * Make sure any previous command has finished + * and polling timeout not expired + */ + + timeout_cnt = timeout_init_us(MHU_POLL_INTR_STAT_TIMEOUT); + + do { + intr_stat_check = (mmio_read_32(address + CPU_INTR_S_STAT) & + (1 << slot_id)); + + expiration = timeout_elapsed(timeout_cnt); + + } while ((intr_stat_check != 0U) && (expiration == 0U)); + + /* + * Note: No risk of timer overflows while waiting + * for the timeout expiration. + * According to Armv8 TRM: System counter roll-over + * time of not less than 40 years + */ +} + +void mhu_secure_message_send(uintptr_t address, + unsigned int slot_id, + unsigned int message) +{ + unsigned char access_ready; + uint64_t timeout_cnt; + volatile uint8_t expiration; + + assert(slot_id <= MHU_MAX_SLOT_ID); + assert((mmio_read_32(address + CPU_INTR_S_STAT) & + (1 << slot_id)) == 0U); + + MHU_V2_ACCESS_REQUEST(address); + + timeout_cnt = timeout_init_us(MHU_POLL_INTR_STAT_TIMEOUT); + + do { + access_ready = MHU_V2_IS_ACCESS_READY(address); + expiration = timeout_elapsed(timeout_cnt); + + } while ((access_ready == 0U) && (expiration == 0U)); + + /* + * Note: No risk of timer overflows while waiting + * for the timeout expiration. + * According to Armv8 TRM: System counter roll-over + * time of not less than 40 years + */ + + mmio_write_32(address + CPU_INTR_S_SET, message); +} + +void mhu_secure_message_end(uintptr_t address, unsigned int slot_id) +{ + assert(slot_id <= MHU_MAX_SLOT_ID); + /* + * Clear any response we got by writing one in the relevant slot bit to + * the CLEAR register + */ + MHU_V2_CLEAR_REQUEST(address); + + arm_lock_release(); +} + +void __init mhu_secure_init(void) +{ + arm_lock_init(); + + /* + * The STAT register resets to zero. Ensure it is in the expected state, + * as a stale or garbage value would make us think it's a message we've + * already sent. + */ + + assert(mmio_read_32(PLAT_SDK700_MHU0_SEND + CPU_INTR_S_STAT) == 0); +} diff --git a/plat/arm/board/corstone700/drivers/mhu/mhu.h b/plat/arm/board/corstone700/drivers/mhu/mhu.h new file mode 100644 index 000000000..3808746e9 --- /dev/null +++ b/plat/arm/board/corstone700/drivers/mhu/mhu.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2019-2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MHU_H +#define MHU_H + +#define MHU_POLL_INTR_STAT_TIMEOUT 50000 /*timeout value in us*/ + +/* CPU MHU secure channel registers */ +#define CPU_INTR_S_STAT 0x00 +#define CPU_INTR_S_SET 0x0C + +/* MHUv2 Control Registers Offsets */ +#define MHU_V2_MSG_CFG_OFFSET 0xF80 +#define MHU_V2_ACCESS_REQ_OFFSET 0xF88 +#define MHU_V2_ACCESS_READY_OFFSET 0xF8C + +#define MHU_V2_ACCESS_REQUEST(addr) \ + mmio_write_32((addr) + MHU_V2_ACCESS_REQ_OFFSET, 0x1) + +#define MHU_V2_CLEAR_REQUEST(addr) \ + mmio_write_32((addr) + MHU_V2_ACCESS_REQ_OFFSET, 0x0) + +#define MHU_V2_IS_ACCESS_READY(addr) \ + (mmio_read_32((addr) + MHU_V2_ACCESS_READY_OFFSET) & 0x1) + +void mhu_secure_message_start(uintptr_t address, unsigned int slot_id); +void mhu_secure_message_send(uintptr_t address, + unsigned int slot_id, + unsigned int message); +void mhu_secure_message_end(uintptr_t address, unsigned int slot_id); +void mhu_secure_init(void); + +#endif /* MHU_H */ diff --git a/plat/arm/board/corstone700/include/platform_def.h b/plat/arm/board/corstone700/include/platform_def.h index 8dff3ec3f..85a3731a5 100644 --- a/plat/arm/board/corstone700/include/platform_def.h +++ b/plat/arm/board/corstone700/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -88,6 +88,10 @@ #define PLAT_ARM_GICD_BASE 0x1C010000 #define PLAT_ARM_GICC_BASE 0x1C02F000 +/* MHUv2 Secure Channel receiver and sender */ +#define PLAT_SDK700_MHU0_SEND 0x1B800000 +#define PLAT_SDK700_MHU0_RECV 0x1B810000 + /* Timer/watchdog related constants */ #define ARM_SYS_CNTCTL_BASE UL(0x1a200000) #define ARM_SYS_CNTREAD_BASE UL(0x1a210000) diff --git a/plat/arm/board/corstone700/platform.mk b/plat/arm/board/corstone700/platform.mk index bff3589eb..a4d4f2227 100644 --- a/plat/arm/board/corstone700/platform.mk +++ b/plat/arm/board/corstone700/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2019, Arm Limited and Contributors. All rights reserved. +# Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -11,16 +11,19 @@ BL32_SOURCES += plat/arm/common/aarch32/arm_helpers.S \ plat/arm/common/arm_common.c \ lib/xlat_tables/aarch32/xlat_tables.c \ lib/xlat_tables/xlat_tables_common.c \ - ${CORSTONE700_CPU_LIBS} + ${CORSTONE700_CPU_LIBS} \ + plat/arm/board/corstone700/drivers/mhu/mhu.c -PLAT_INCLUDES := -Iplat/arm/board/corstone700/include +PLAT_INCLUDES := -Iplat/arm/board/corstone700/include \ + -Iinclude/plat/arm/common \ + -Iplat/arm/board/corstone700/drivers/mhu NEED_BL32 := yes -CORSTONE700_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v2/gicv2_main.c \ - drivers/arm/gic/v2/gicv2_helpers.c \ - plat/common/plat_gicv2.c \ +CORSTONE700_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ + drivers/arm/gic/v2/gicv2_main.c \ + drivers/arm/gic/v2/gicv2_helpers.c \ + plat/common/plat_gicv2.c \ plat/arm/common/arm_gicv2.c # BL1/BL2 Image not a part of the capsule Image for Corstone700 -- cgit v1.2.3 From 93cf1f6454b9ba5b1a5946acd3bae9618f1512d6 Mon Sep 17 00:00:00 2001 From: Avinash Mehta Date: Thu, 11 Jul 2019 16:23:43 +0100 Subject: corstone700: clean-up as per coding style guide Running checkpatch.pl on the codebase and making required changes Change-Id: I7d3f8764cef632ab2a6d3c355c68f590440b85b8 Signed-off-by: Avinash Mehta Signed-off-by: Abdellatif El Khlifi --- plat/arm/board/corstone700/corstone700_topology.c | 6 +- plat/arm/board/corstone700/include/platform_def.h | 90 ++++++++++++----------- 2 files changed, 49 insertions(+), 47 deletions(-) diff --git a/plat/arm/board/corstone700/corstone700_topology.c b/plat/arm/board/corstone700/corstone700_topology.c index d9445e0c5..904f5ab3a 100644 --- a/plat/arm/board/corstone700/corstone700_topology.c +++ b/plat/arm/board/corstone700/corstone700_topology.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -8,8 +8,8 @@ #include /* The Corstone700 power domain tree descriptor */ -static unsigned char corstone700_power_domain_tree_desc - [PLAT_ARM_CLUSTER_COUNT + 2]; +static unsigned char corstone700_power_domain_tree_desc[PLAT_ARM_CLUSTER_COUNT + + 2]; /******************************************************************************* * This function dynamically constructs the topology according to * CLUSTER_COUNT and returns it. diff --git a/plat/arm/board/corstone700/include/platform_def.h b/plat/arm/board/corstone700/include/platform_def.h index 85a3731a5..636190700 100644 --- a/plat/arm/board/corstone700/include/platform_def.h +++ b/plat/arm/board/corstone700/include/platform_def.h @@ -17,12 +17,14 @@ #define CORSTONE700_CLUSTER_COUNT U(1) #define CORSTONE700_MAX_CPUS_PER_CLUSTER U(4) #define CORSTONE700_MAX_PE_PER_CPU U(1) -#define CORSTONE700_CORE_COUNT (CORSTONE700_CLUSTER_COUNT * \ - CORSTONE700_MAX_CPUS_PER_CLUSTER * \ - CORSTONE700_MAX_PE_PER_CPU) -#define PLATFORM_CORE_COUNT CORSTONE700_CORE_COUNT + #define PLAT_ARM_CLUSTER_COUNT CORSTONE700_CLUSTER_COUNT +#define PLATFORM_CORE_COUNT (PLAT_ARM_CLUSTER_COUNT * \ + CORSTONE700_MAX_CPUS_PER_CLUSTER * \ + CORSTONE700_MAX_PE_PER_CPU) + + /* UART related constants */ #define PLAT_ARM_BOOT_UART_BASE 0x1a510000 #define PLAT_ARM_BOOT_UART_CLK_IN_HZ V2M_IOFPGA_UART0_CLK_IN_HZ @@ -85,12 +87,12 @@ ARM_BL_REGIONS) /* GIC related constants */ -#define PLAT_ARM_GICD_BASE 0x1C010000 -#define PLAT_ARM_GICC_BASE 0x1C02F000 +#define PLAT_ARM_GICD_BASE 0x1C010000 +#define PLAT_ARM_GICC_BASE 0x1C02F000 /* MHUv2 Secure Channel receiver and sender */ -#define PLAT_SDK700_MHU0_SEND 0x1B800000 -#define PLAT_SDK700_MHU0_RECV 0x1B810000 +#define PLAT_SDK700_MHU0_SEND 0x1B800000 +#define PLAT_SDK700_MHU0_RECV 0x1B810000 /* Timer/watchdog related constants */ #define ARM_SYS_CNTCTL_BASE UL(0x1a200000) @@ -105,46 +107,46 @@ * Macros mapping the MPIDR Affinity levels to ARM Platform Power levels. The * power levels have a 1:1 mapping with the MPIDR affinity levels. */ -#define ARM_PWR_LVL0 MPIDR_AFFLVL0 -#define ARM_PWR_LVL1 MPIDR_AFFLVL1 -#define ARM_PWR_LVL2 MPIDR_AFFLVL2 +#define ARM_PWR_LVL0 MPIDR_AFFLVL0 +#define ARM_PWR_LVL1 MPIDR_AFFLVL1 +#define ARM_PWR_LVL2 MPIDR_AFFLVL2 /* * Macros for local power states in ARM platforms encoded by State-ID field * within the power-state parameter. */ /* Local power state for power domains in Run state. */ -#define ARM_LOCAL_STATE_RUN U(0) +#define ARM_LOCAL_STATE_RUN U(0) /* Local power state for retention. Valid only for CPU power domains */ -#define ARM_LOCAL_STATE_RET U(1) +#define ARM_LOCAL_STATE_RET U(1) /* Local power state for OFF/power-down. Valid for CPU and cluster * power domains */ -#define ARM_LOCAL_STATE_OFF U(2) +#define ARM_LOCAL_STATE_OFF U(2) -#define PLAT_ARM_TRUSTED_MAILBOX_BASE ARM_TRUSTED_SRAM_BASE -#define PLAT_ARM_NSTIMER_FRAME_ID U(1) +#define PLAT_ARM_TRUSTED_MAILBOX_BASE ARM_TRUSTED_SRAM_BASE +#define PLAT_ARM_NSTIMER_FRAME_ID U(1) -#define PLAT_ARM_NS_IMAGE_OFFSET (ARM_DRAM1_BASE + UL(0x8000000)) +#define PLAT_ARM_NS_IMAGE_OFFSET (ARM_DRAM1_BASE + UL(0x8000000)) -#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) -#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) /* * 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 1 +#define PLAT_MAX_RET_STATE 1 /* * This macro defines the deepest power down states possible. Any state ID * higher than this is invalid. */ -#define PLAT_MAX_OFF_STATE 2 +#define PLAT_MAX_OFF_STATE 2 -#define PLATFORM_STACK_SIZE UL(0x440) +#define PLATFORM_STACK_SIZE UL(0x440) -#define ARM_MAP_SHARED_RAM MAP_REGION_FLAT( \ +#define ARM_MAP_SHARED_RAM MAP_REGION_FLAT( \ ARM_SHARED_RAM_BASE, \ ARM_SHARED_RAM_SIZE, \ MT_DEVICE | MT_RW | MT_SECURE) @@ -174,21 +176,21 @@ #define CORSTONE700_DEVICE_BASE (0x1A000000) #define CORSTONE700_DEVICE_SIZE (0x26000000) -#define CORSTONE700_MAP_DEVICE MAP_REGION_FLAT( \ - CORSTONE700_DEVICE_BASE, \ - CORSTONE700_DEVICE_SIZE, \ - MT_DEVICE | MT_RW | MT_SECURE) - -#define ARM_IRQ_SEC_PHY_TIMER 29 - -#define ARM_IRQ_SEC_SGI_0 8 -#define ARM_IRQ_SEC_SGI_1 9 -#define ARM_IRQ_SEC_SGI_2 10 -#define ARM_IRQ_SEC_SGI_3 11 -#define ARM_IRQ_SEC_SGI_4 12 -#define ARM_IRQ_SEC_SGI_5 13 -#define ARM_IRQ_SEC_SGI_6 14 -#define ARM_IRQ_SEC_SGI_7 15 +#define CORSTONE700_MAP_DEVICE MAP_REGION_FLAT( \ + CORSTONE700_DEVICE_BASE,\ + CORSTONE700_DEVICE_SIZE,\ + MT_DEVICE | MT_RW | MT_SECURE) + +#define ARM_IRQ_SEC_PHY_TIMER 29 + +#define ARM_IRQ_SEC_SGI_0 8 +#define ARM_IRQ_SEC_SGI_1 9 +#define ARM_IRQ_SEC_SGI_2 10 +#define ARM_IRQ_SEC_SGI_3 11 +#define ARM_IRQ_SEC_SGI_4 12 +#define ARM_IRQ_SEC_SGI_5 13 +#define ARM_IRQ_SEC_SGI_6 14 +#define ARM_IRQ_SEC_SGI_7 15 /* * Define a list of Group 1 Secure and Group 0 interrupt properties as per GICv3 @@ -196,7 +198,7 @@ * as Group 0 interrupts. */ #define ARM_G1S_IRQ_PROPS(grp) \ - INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, \ + INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, \ (grp), GIC_INTR_CFG_LEVEL), \ INTR_PROP_DESC(ARM_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, \ (grp), GIC_INTR_CFG_EDGE), \ @@ -221,11 +223,11 @@ * as Group 0 interrupts. */ #define PLAT_ARM_G1S_IRQ_PROPS(grp) \ - ARM_G1S_IRQ_PROPS(grp), \ - INTR_PROP_DESC(CORSTONE700_IRQ_TZ_WDOG, \ - GIC_HIGHEST_SEC_PRIORITY, (grp), GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(CORSTONE700_IRQ_SEC_SYS_TIMER, \ - GIC_HIGHEST_SEC_PRIORITY, (grp), GIC_INTR_CFG_LEVEL) \ + ARM_G1S_IRQ_PROPS(grp), \ + INTR_PROP_DESC(CORSTONE700_IRQ_TZ_WDOG, GIC_HIGHEST_SEC_PRIORITY, \ + (grp), GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(CORSTONE700_IRQ_SEC_SYS_TIMER, \ + GIC_HIGHEST_SEC_PRIORITY, (grp), GIC_INTR_CFG_LEVEL) #define PLAT_ARM_G0_IRQ_PROPS(grp) ARM_G0_IRQ_PROPS(grp) -- cgit v1.2.3 From 6aa138ded5e684894cd146fc1bb85df304529b46 Mon Sep 17 00:00:00 2001 From: Vishnu Banavath Date: Wed, 7 Aug 2019 10:49:05 +0100 Subject: corstone700: set UART clocks to 32MHz Adding support for 32MHz UART clock and selecting it as the default UART clock Change-Id: I9541eaff70424e85a3b5ee4820ca0e7efb040d2c Signed-off-by: Vishnu Banavath Signed-off-by: Abdellatif El Khlifi --- fdts/corstone700.dts | 17 ++++++++++++----- plat/arm/board/corstone700/include/platform_def.h | 13 +++++++++++++ 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/fdts/corstone700.dts b/fdts/corstone700.dts index 16cf41227..8c3bd0c05 100644 --- a/fdts/corstone700.dts +++ b/fdts/corstone700.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -68,14 +68,21 @@ clock-output-names = "smclk"; }; + uartclk: uartclk { + /* UART clock - 32MHz */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32000000>; + clock-output-names = "uartclk"; + }; serial0: uart@1a510000 { compatible = "arm,pl011", "arm,primecell"; reg = <0x1a510000 0x1000>; interrupt-parent = <&gic>; interrupts = <0 19 4>; - clocks = <&refclk100mhz>, <&smbclk>; - clock-names = "apb_pclk", "smclk"; + clocks = <&uartclk>, <&refclk100mhz>; + clock-names = "uartclk", "apb_pclk"; }; serial1: uart@1a520000 { @@ -83,8 +90,8 @@ reg = <0x1a520000 0x1000>; interrupt-parent = <&gic>; interrupts = <0 20 4>; - clocks = <&refclk100mhz>, <&smbclk>; - clock-names = "apb_pclk", "smclk"; + clocks = <&uartclk>, <&refclk100mhz>; + clock-names = "uartclk", "apb_pclk"; }; timer { diff --git a/plat/arm/board/corstone700/include/platform_def.h b/plat/arm/board/corstone700/include/platform_def.h index 636190700..0fb74e442 100644 --- a/plat/arm/board/corstone700/include/platform_def.h +++ b/plat/arm/board/corstone700/include/platform_def.h @@ -9,10 +9,23 @@ #include #include + #include #include #include +/* PL011 UART related constants */ +#ifdef V2M_IOFPGA_UART0_CLK_IN_HZ +#undef V2M_IOFPGA_UART0_CLK_IN_HZ +#endif + +#ifdef V2M_IOFPGA_UART1_CLK_IN_HZ +#undef V2M_IOFPGA_UART1_CLK_IN_HZ +#endif + +#define V2M_IOFPGA_UART0_CLK_IN_HZ 32000000 +#define V2M_IOFPGA_UART1_CLK_IN_HZ 32000000 + /* Core/Cluster/Thread counts for Corstone700 */ #define CORSTONE700_CLUSTER_COUNT U(1) #define CORSTONE700_MAX_CPUS_PER_CLUSTER U(4) -- cgit v1.2.3 From 495599cd0a56143f9e5159f354b5718ac84e7431 Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Mon, 17 Feb 2020 13:41:59 +0100 Subject: TBBR: Reduce size of ECDSA key buffers The TBBR implementation extracts public keys from certificates and stores them in static buffers. DER-encoded ECDSA keys are only 91 bytes each but were each allocated 294 bytes instead. Reducing the size of these buffers saves 609 bytes of BSS in BL2 (294 - 91 = 203 bytes for each of the 3 key buffers in use). Also add a comment claryfing that key buffers are tailored on RSA key sizes when both ECDSA and RSA keys are used. Change-Id: Iad332856e7af1f9814418d012fba3e1e9399f72a Signed-off-by: Sandrine Bailleux --- drivers/auth/tbbr/tbbr_cot.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/auth/tbbr/tbbr_cot.c b/drivers/auth/tbbr/tbbr_cot.c index 6dd4ae252..2f1f451b1 100644 --- a/drivers/auth/tbbr/tbbr_cot.c +++ b/drivers/auth/tbbr/tbbr_cot.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -18,7 +18,12 @@ /* - * Maximum key and hash sizes (in DER format) + * Maximum key and hash sizes (in DER format). + * + * Both RSA and ECDSA keys may be used at the same time. In this case, the key + * buffers must be big enough to hold either. As RSA keys are bigger than ECDSA + * ones for all key sizes we support, they impose the minimum size of these + * buffers. */ #if TF_MBEDTLS_USE_RSA #if TF_MBEDTLS_KEY_SIZE == 1024 @@ -32,8 +37,8 @@ #else #error "Invalid value for TF_MBEDTLS_KEY_SIZE" #endif -#else -#define PK_DER_LEN 294 +#else /* Only using ECDSA keys. */ +#define PK_DER_LEN 91 #endif #define HASH_DER_LEN 83 -- cgit v1.2.3 From 0b4e59211bf78db96b9f6a87869f623ea2810ebc Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Mon, 17 Feb 2020 16:26:05 +0100 Subject: TBBR: Reduce size of hash buffers when possible The TBBR implementation extracts hashes from certificates and stores them in static buffers. TF-A supports 3 variants of SHA right now: SHA-256, SHA-384 and SHA-512. When support for SHA-512 was added in commit 9a3088a5f509084e60d9c55bf53985c5ec4ca821 ("tbbr: Add build flag HASH_ALG to let the user to select the SHA"), the hash buffers got unconditionally increased from 51 to 83 bytes each. We can reduce that space if we're using SHA-256 or SHA-384. This saves some BSS space in both BL1 and BL2: - BL1 with SHA-256: saving 168 bytes. - BL1 with SHA-384: saving 80 bytes. - BL2 with SHA-256: saving 384 bytes. - BL2 with SHA-384: saving 192 bytes. Change-Id: I0d02e5dc5f0162e82339c768609c9766cfe7e2bd Signed-off-by: Sandrine Bailleux --- drivers/auth/tbbr/tbbr_cot.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/auth/tbbr/tbbr_cot.c b/drivers/auth/tbbr/tbbr_cot.c index 2f1f451b1..6f00b180c 100644 --- a/drivers/auth/tbbr/tbbr_cot.c +++ b/drivers/auth/tbbr/tbbr_cot.c @@ -41,7 +41,15 @@ #define PK_DER_LEN 91 #endif +#if TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA256 +#define HASH_DER_LEN 51 +#elif TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA384 +#define HASH_DER_LEN 67 +#elif TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA512 #define HASH_DER_LEN 83 +#else +#error "Invalid value for TF_MBEDTLS_HASH_ALG_ID" +#endif /* * The platform must allocate buffers to store the authentication parameters -- cgit v1.2.3 From 6227cca9e8bbcb322dc0caa0da94b9a3628385ed Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Mon, 17 Feb 2020 13:38:35 +0000 Subject: FVP: Fix BL31 load address and image size for RESET_TO_BL31=1 When TF-A is built with RESET_TO_BL31=1 option, BL31 is the first image to be run and should have all the memory allocated to it except for the memory reserved for Shared RAM at the start of Trusted SRAM. This patch fixes FVP BL31 load address and its image size for RESET_TO_BL31=1 option. BL31 startup address should be set to 0x400_1000 and its maximum image size to the size of Trusted SRAM minus the first 4KB of shared memory. Loading BL31 at 0x0402_0000 as it is currently stated in '\docs\plat\arm\fvp\index.rst' causes EL3 exception when the image size gets increased (i.e. building with LOG_LEVEL=50) but doesn't exceed 0x3B000 not causing build error. Change-Id: Ie450baaf247f1577112f8d143b24e76c39d33e91 Signed-off-by: Alexei Fedorov --- docs/plat/arm/fvp/index.rst | 18 +++++++++--------- plat/arm/board/fvp/include/platform_def.h | 6 ++++++ 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/docs/plat/arm/fvp/index.rst b/docs/plat/arm/fvp/index.rst index 37010e1a5..40e966117 100644 --- a/docs/plat/arm/fvp/index.rst +++ b/docs/plat/arm/fvp/index.rst @@ -277,15 +277,15 @@ And the FVP binary can be run with the following command: -C cluster0.NUM_CORES=4 \ -C cluster1.NUM_CORES=4 \ -C cache_state_modelled=1 \ - -C cluster0.cpu0.RVBAR=0x04020000 \ - -C cluster0.cpu1.RVBAR=0x04020000 \ - -C cluster0.cpu2.RVBAR=0x04020000 \ - -C cluster0.cpu3.RVBAR=0x04020000 \ - -C cluster1.cpu0.RVBAR=0x04020000 \ - -C cluster1.cpu1.RVBAR=0x04020000 \ - -C cluster1.cpu2.RVBAR=0x04020000 \ - -C cluster1.cpu3.RVBAR=0x04020000 \ - --data cluster0.cpu0="/bl31.bin"@0x04020000 \ + -C cluster0.cpu0.RVBAR=0x04001000 \ + -C cluster0.cpu1.RVBAR=0x04001000 \ + -C cluster0.cpu2.RVBAR=0x04001000 \ + -C cluster0.cpu3.RVBAR=0x04001000 \ + -C cluster1.cpu0.RVBAR=0x04001000 \ + -C cluster1.cpu1.RVBAR=0x04001000 \ + -C cluster1.cpu2.RVBAR=0x04001000 \ + -C cluster1.cpu3.RVBAR=0x04001000 \ + --data cluster0.cpu0="/bl31.bin"@0x04001000 \ --data cluster0.cpu0="/"@0x82000000 \ --data cluster0.cpu0="/"@0x80080000 \ --data cluster0.cpu0="/"@0x84000000 diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h index 602ea6def..bfe207a29 100644 --- a/plat/arm/board/fvp/include/platform_def.h +++ b/plat/arm/board/fvp/include/platform_def.h @@ -116,12 +116,18 @@ # define PLAT_ARM_MAX_BL2_SIZE (UL(0x11000) - FVP_BL2_ROMLIB_OPTIMIZATION) #endif +#if RESET_TO_BL31 +/* Size of Trusted SRAM - the first 4KB of shared memory */ +#define PLAT_ARM_MAX_BL31_SIZE (PLAT_ARM_TRUSTED_SRAM_SIZE - \ + ARM_SHARED_RAM_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(0x3B000) +#endif /* RESET_TO_BL31 */ #ifndef __aarch64__ /* -- cgit v1.2.3 From f4744720a00c130bbc46e7cf22af46a3526ee550 Mon Sep 17 00:00:00 2001 From: Jimmy Brisson Date: Mon, 9 Dec 2019 14:02:22 -0600 Subject: Add CPULib for Klein Core Change-Id: I686fd623b8264c85434853a2a26ecd71e9eeac01 Signed-off-by: Jimmy Brisson --- include/lib/cpus/aarch64/cortex_klein.h | 23 ++++++++++ lib/cpus/aarch64/cortex_klein.S | 77 +++++++++++++++++++++++++++++++++ plat/arm/board/fvp/platform.mk | 1 + 3 files changed, 101 insertions(+) create mode 100644 include/lib/cpus/aarch64/cortex_klein.h create mode 100644 lib/cpus/aarch64/cortex_klein.S diff --git a/include/lib/cpus/aarch64/cortex_klein.h b/include/lib/cpus/aarch64/cortex_klein.h new file mode 100644 index 000000000..729b3bf0a --- /dev/null +++ b/include/lib/cpus/aarch64/cortex_klein.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CORTEX_KLEIN_H +#define CORTEX_KLEIN_H + +#define CORTEX_KLEIN_MIDR U(0x410FD460) + +/******************************************************************************* + * CPU Extended Control register specific definitions + ******************************************************************************/ +#define CORTEX_KLEIN_CPUECTLR_EL1 S3_0_C15_C1_4 + +/******************************************************************************* + * CPU Power Control register specific definitions + ******************************************************************************/ +#define CORTEX_KLEIN_CPUPWRCTLR_EL1 S3_0_C15_C2_7 +#define CORTEX_KLEIN_CPUPWRCTLR_EL1_CORE_PWRDN_BIT U(1) + +#endif /* CORTEX_KLEIN_H */ diff --git a/lib/cpus/aarch64/cortex_klein.S b/lib/cpus/aarch64/cortex_klein.S new file mode 100644 index 000000000..d3a8ab481 --- /dev/null +++ b/lib/cpus/aarch64/cortex_klein.S @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2020, 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 Klein must be compiled with HW_ASSISTED_COHERENCY enabled" +#endif + +/* 64-bit only core */ +#if CTX_INCLUDE_AARCH32_REGS == 1 +#error "Cortex Klein supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0" +#endif + + /* ---------------------------------------------------- + * HW will do the cache maintenance while powering down + * ---------------------------------------------------- + */ +func cortex_klein_core_pwr_dwn + /* --------------------------------------------------- + * Enable CPU power down bit in power control register + * --------------------------------------------------- + */ + mrs x0, CORTEX_KLEIN_CPUPWRCTLR_EL1 + orr x0, x0, #CORTEX_KLEIN_CPUPWRCTLR_EL1_CORE_PWRDN_BIT + msr CORTEX_KLEIN_CPUPWRCTLR_EL1, x0 + isb + ret +endfunc cortex_klein_core_pwr_dwn + + /* + * Errata printing function for Cortex Klein. Must follow AAPCS. + */ +#if REPORT_ERRATA +func cortex_klein_errata_report + ret +endfunc cortex_klein_errata_report +#endif + +func cortex_klein_reset_func + /* Disable speculative loads */ + msr SSBS, xzr + isb + ret +endfunc cortex_klein_reset_func + + /* --------------------------------------------- + * This function provides Cortex-Klein 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_klein_regs, "aS" +cortex_klein_regs: /* The ascii list of register names to be reported */ + .asciz "cpuectlr_el1", "" + +func cortex_klein_cpu_reg_dump + adr x6, cortex_klein_regs + mrs x8, CORTEX_KLEIN_CPUECTLR_EL1 + ret +endfunc cortex_klein_cpu_reg_dump + +declare_cpu_ops cortex_klein, CORTEX_KLEIN_MIDR, \ + cortex_klein_reset_func, \ + cortex_klein_core_pwr_dwn diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 60374352a..65dc5457f 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -122,6 +122,7 @@ else lib/cpus/aarch64/neoverse_zeus.S \ lib/cpus/aarch64/cortex_hercules.S \ lib/cpus/aarch64/cortex_hercules_ae.S \ + lib/cpus/aarch64/cortex_klein.S \ lib/cpus/aarch64/cortex_a65.S \ lib/cpus/aarch64/cortex_a65ae.S endif -- cgit v1.2.3 From da3b47e925a9a524538f9e471a20327b8112f75b Mon Sep 17 00:00:00 2001 From: Jimmy Brisson Date: Wed, 8 Jan 2020 13:52:51 -0600 Subject: Add Matterhorn CPU lib Also update copyright statements Change-Id: Iba0305522ac0f2ddc4da99127fd773f340e67300 Signed-off-by: Jimmy Brisson --- include/lib/cpus/aarch64/cortex_matterhorn.h | 23 +++++++++ lib/cpus/aarch64/cortex_matterhorn.S | 77 ++++++++++++++++++++++++++++ plat/arm/board/fvp/platform.mk | 1 + 3 files changed, 101 insertions(+) create mode 100644 include/lib/cpus/aarch64/cortex_matterhorn.h create mode 100644 lib/cpus/aarch64/cortex_matterhorn.S diff --git a/include/lib/cpus/aarch64/cortex_matterhorn.h b/include/lib/cpus/aarch64/cortex_matterhorn.h new file mode 100644 index 000000000..018553359 --- /dev/null +++ b/include/lib/cpus/aarch64/cortex_matterhorn.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CORTEX_MATTERHORN_H +#define CORTEX_MATTERHORN_H + +#define CORTEX_MATTERHORN_MIDR U(0x410FD470) + +/******************************************************************************* + * CPU Extended Control register specific definitions + ******************************************************************************/ +#define CORTEX_MATTERHORN_CPUECTLR_EL1 S3_0_C15_C1_4 + +/******************************************************************************* + * CPU Power Control register specific definitions + ******************************************************************************/ +#define CORTEX_MATTERHORN_CPUPWRCTLR_EL1 S3_0_C15_C2_7 +#define CORTEX_MATTERHORN_CPUPWRCTLR_EL1_CORE_PWRDN_BIT U(1) + +#endif /* CORTEX_MATTERHORN_H */ diff --git a/lib/cpus/aarch64/cortex_matterhorn.S b/lib/cpus/aarch64/cortex_matterhorn.S new file mode 100644 index 000000000..4156f3cf8 --- /dev/null +++ b/lib/cpus/aarch64/cortex_matterhorn.S @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2020, 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 Matterhorn must be compiled with HW_ASSISTED_COHERENCY enabled" +#endif + +/* 64-bit only core */ +#if CTX_INCLUDE_AARCH32_REGS == 1 +#error "Cortex Matterhorn supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0" +#endif + + /* ---------------------------------------------------- + * HW will do the cache maintenance while powering down + * ---------------------------------------------------- + */ +func cortex_matterhorn_core_pwr_dwn + /* --------------------------------------------------- + * Enable CPU power down bit in power control register + * --------------------------------------------------- + */ + mrs x0, CORTEX_MATTERHORN_CPUPWRCTLR_EL1 + orr x0, x0, #CORTEX_MATTERHORN_CPUPWRCTLR_EL1_CORE_PWRDN_BIT + msr CORTEX_MATTERHORN_CPUPWRCTLR_EL1, x0 + isb + ret +endfunc cortex_matterhorn_core_pwr_dwn + + /* + * Errata printing function for Cortex Matterhorn. Must follow AAPCS. + */ +#if REPORT_ERRATA +func cortex_matterhorn_errata_report + ret +endfunc cortex_matterhorn_errata_report +#endif + +func cortex_matterhorn_reset_func + /* Disable speculative loads */ + msr SSBS, xzr + isb + ret +endfunc cortex_matterhorn_reset_func + + /* --------------------------------------------- + * This function provides Cortex-Matterhorn 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_matterhorn_regs, "aS" +cortex_matterhorn_regs: /* The ascii list of register names to be reported */ + .asciz "cpuectlr_el1", "" + +func cortex_matterhorn_cpu_reg_dump + adr x6, cortex_matterhorn_regs + mrs x8, CORTEX_MATTERHORN_CPUECTLR_EL1 + ret +endfunc cortex_matterhorn_cpu_reg_dump + +declare_cpu_ops cortex_matterhorn, CORTEX_MATTERHORN_MIDR, \ + cortex_matterhorn_reset_func, \ + cortex_matterhorn_core_pwr_dwn diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 65dc5457f..4176968f8 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -123,6 +123,7 @@ else lib/cpus/aarch64/cortex_hercules.S \ lib/cpus/aarch64/cortex_hercules_ae.S \ lib/cpus/aarch64/cortex_klein.S \ + lib/cpus/aarch64/cortex_matterhorn.S \ lib/cpus/aarch64/cortex_a65.S \ lib/cpus/aarch64/cortex_a65ae.S endif -- cgit v1.2.3 From 2fe75a2de087ec23162c5fd25ba439bd330ea50c Mon Sep 17 00:00:00 2001 From: Zelalem Date: Wed, 12 Feb 2020 10:37:03 -0600 Subject: coverity: fix MISRA violations Fixes for the following MISRA violations: - Missing explicit parentheses on sub-expression - An identifier or macro name beginning with an underscore, shall not be declared - Type mismatch in BL1 SMC handlers and tspd_main.c Change-Id: I7a92abf260da95acb0846b27c2997b59b059efc4 Signed-off-by: Zelalem --- bl1/bl1_fwu.c | 14 +++++++------- bl1/bl1_main.c | 14 +++++++------- bl1/bl1_private.h | 12 ++++++------ drivers/cfi/v2m/v2m_flash.c | 4 ++-- include/bl1/bl1.h | 14 +++++++------- include/lib/el3_runtime/aarch32/context.h | 8 ++++---- include/lib/el3_runtime/aarch64/context.h | 8 ++++---- lib/psci/psci_common.c | 4 ++-- services/spd/tspd/tspd_main.c | 4 ++-- 9 files changed, 41 insertions(+), 41 deletions(-) diff --git a/bl1/bl1_fwu.c b/bl1/bl1_fwu.c index 48f08d2ca..42a3ded5b 100644 --- a/bl1/bl1_fwu.c +++ b/bl1/bl1_fwu.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -55,11 +55,11 @@ static unsigned int sec_exec_image_id = INVALID_IMAGE_ID; /******************************************************************************* * Top level handler for servicing FWU SMCs. ******************************************************************************/ -register_t bl1_fwu_smc_handler(unsigned int smc_fid, - register_t x1, - register_t x2, - register_t x3, - register_t x4, +u_register_t bl1_fwu_smc_handler(unsigned int smc_fid, + u_register_t x1, + u_register_t x2, + u_register_t x3, + u_register_t x4, void *cookie, void *handle, unsigned int flags) @@ -76,7 +76,7 @@ register_t bl1_fwu_smc_handler(unsigned int smc_fid, SMC_RET1(handle, bl1_fwu_image_execute(x1, &handle, flags)); case FWU_SMC_IMAGE_RESUME: - SMC_RET1(handle, bl1_fwu_image_resume(x1, &handle, flags)); + SMC_RET1(handle, bl1_fwu_image_resume((register_t)x1, &handle, flags)); case FWU_SMC_SEC_IMAGE_DONE: SMC_RET1(handle, bl1_fwu_sec_image_done(&handle, flags)); diff --git a/bl1/bl1_main.c b/bl1/bl1_main.c index bff8d22f5..e11ead608 100644 --- a/bl1/bl1_main.c +++ b/bl1/bl1_main.c @@ -226,11 +226,11 @@ void print_debug_loop_message(void) /******************************************************************************* * Top level handler for servicing BL1 SMCs. ******************************************************************************/ -register_t bl1_smc_handler(unsigned int smc_fid, - register_t x1, - register_t x2, - register_t x3, - register_t x4, +u_register_t bl1_smc_handler(unsigned int smc_fid, + u_register_t x1, + u_register_t x2, + u_register_t x3, + u_register_t x4, void *cookie, void *handle, unsigned int flags) @@ -269,12 +269,12 @@ register_t bl1_smc_handler(unsigned int smc_fid, * BL1 SMC wrapper. This function is only used in AArch32 mode to ensure ABI * compliance when invoking bl1_smc_handler. ******************************************************************************/ -register_t bl1_smc_wrapper(uint32_t smc_fid, +u_register_t bl1_smc_wrapper(uint32_t smc_fid, void *cookie, void *handle, unsigned int flags) { - register_t x1, x2, x3, x4; + u_register_t x1, x2, x3, x4; assert(handle != NULL); diff --git a/bl1/bl1_private.h b/bl1/bl1_private.h index 927c7b8a2..2cfeeea28 100644 --- a/bl1/bl1_private.h +++ b/bl1/bl1_private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -19,11 +19,11 @@ void bl1_arch_next_el_setup(void); void bl1_prepare_next_image(unsigned int image_id); -register_t bl1_fwu_smc_handler(unsigned int smc_fid, - register_t x1, - register_t x2, - register_t x3, - register_t x4, +u_register_t bl1_fwu_smc_handler(unsigned int smc_fid, + u_register_t x1, + u_register_t x2, + u_register_t x3, + u_register_t x4, void *cookie, void *handle, unsigned int flags); diff --git a/drivers/cfi/v2m/v2m_flash.c b/drivers/cfi/v2m/v2m_flash.c index aadafbce2..669018919 100644 --- a/drivers/cfi/v2m/v2m_flash.c +++ b/drivers/cfi/v2m/v2m_flash.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -27,7 +27,7 @@ #define DWS_WORD_LOCK_RETRIES 1000 /* Helper macro to detect end of command */ -#define NOR_CMD_END (NOR_DWS | NOR_DWS << 16l) +#define NOR_CMD_END (NOR_DWS | (NOR_DWS << 16l)) /* Helper macros to access two flash banks in parallel */ #define NOR_2X16(d) ((d << 16) | (d & 0xffff)) diff --git a/include/bl1/bl1.h b/include/bl1/bl1.h index d81f43404..e6447f25b 100644 --- a/include/bl1/bl1.h +++ b/include/bl1/bl1.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -67,16 +67,16 @@ struct entry_point_info; -register_t bl1_smc_wrapper(uint32_t smc_fid, +u_register_t bl1_smc_wrapper(uint32_t smc_fid, void *cookie, void *handle, unsigned int flags); -register_t bl1_smc_handler(unsigned int smc_fid, - register_t x1, - register_t x2, - register_t x3, - register_t x4, +u_register_t bl1_smc_handler(unsigned int smc_fid, + u_register_t x1, + u_register_t x2, + u_register_t x3, + u_register_t x4, void *cookie, void *handle, unsigned int flags); diff --git a/include/lib/el3_runtime/aarch32/context.h b/include/lib/el3_runtime/aarch32/context.h index c5567c974..5604c8e50 100644 --- a/include/lib/el3_runtime/aarch32/context.h +++ b/include/lib/el3_runtime/aarch32/context.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -37,7 +37,7 @@ #define WORD_SHIFT U(2) #define DEFINE_REG_STRUCT(name, num_regs) \ typedef struct name { \ - uint32_t _regs[num_regs]; \ + uint32_t ctx_regs[num_regs]; \ } __aligned(8) name##_t /* Constants to determine the size of individual context structures */ @@ -47,8 +47,8 @@ DEFINE_REG_STRUCT(regs, CTX_REG_ALL); #undef CTX_REG_ALL -#define read_ctx_reg(ctx, offset) ((ctx)->_regs[offset >> WORD_SHIFT]) -#define write_ctx_reg(ctx, offset, val) (((ctx)->_regs[offset >> WORD_SHIFT]) \ +#define read_ctx_reg(ctx, offset) ((ctx)->ctx_regs[offset >> WORD_SHIFT]) +#define write_ctx_reg(ctx, offset, val) (((ctx)->ctx_regs[offset >> WORD_SHIFT]) \ = val) typedef struct cpu_context { regs_t regs_ctx; diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h index 7a1f3a3a8..4158c023e 100644 --- a/include/lib/el3_runtime/aarch64/context.h +++ b/include/lib/el3_runtime/aarch64/context.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -230,7 +230,7 @@ #define DWORD_SHIFT U(3) #define DEFINE_REG_STRUCT(name, num_regs) \ typedef struct name { \ - uint64_t _regs[num_regs]; \ + uint64_t ctx_regs[num_regs]; \ } __aligned(16) name##_t /* Constants to determine the size of individual context structures */ @@ -288,8 +288,8 @@ DEFINE_REG_STRUCT(pauth, CTX_PAUTH_REGS_ALL); * Macros to access members of any of the above structures using their * offsets */ -#define read_ctx_reg(ctx, offset) ((ctx)->_regs[(offset) >> DWORD_SHIFT]) -#define write_ctx_reg(ctx, offset, val) (((ctx)->_regs[(offset) >> DWORD_SHIFT]) \ +#define read_ctx_reg(ctx, offset) ((ctx)->ctx_regs[(offset) >> DWORD_SHIFT]) +#define write_ctx_reg(ctx, offset, val) (((ctx)->ctx_regs[(offset) >> DWORD_SHIFT]) \ = (uint64_t) (val)) /* diff --git a/lib/psci/psci_common.c b/lib/psci/psci_common.c index 5ab15c6ee..cced2761f 100644 --- a/lib/psci/psci_common.c +++ b/lib/psci/psci_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -601,7 +601,7 @@ void psci_release_pwr_domain_locks(unsigned int end_pwrlvl, unsigned int level; /* Unlock top down. No unlocking required for level 0. */ - for (level = end_pwrlvl; level >= PSCI_CPU_PWR_LVL + 1U; level--) { + for (level = end_pwrlvl; level >= (PSCI_CPU_PWR_LVL + 1U); level--) { parent_idx = parent_nodes[level - 1U]; psci_lock_release(&psci_non_cpu_pd_nodes[parent_idx]); } diff --git a/services/spd/tspd/tspd_main.c b/services/spd/tspd/tspd_main.c index f2067244e..b0cbf625d 100644 --- a/services/spd/tspd/tspd_main.c +++ b/services/spd/tspd/tspd_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -126,7 +126,7 @@ static uint64_t tspd_sel1_interrupt_handler(uint32_t id, * interrupt handling. */ if (get_yield_smc_active_flag(tsp_ctx->state)) { - tsp_ctx->saved_spsr_el3 = SMC_GET_EL3(&tsp_ctx->cpu_ctx, + tsp_ctx->saved_spsr_el3 = (uint32_t)SMC_GET_EL3(&tsp_ctx->cpu_ctx, CTX_SPSR_EL3); tsp_ctx->saved_elr_el3 = SMC_GET_EL3(&tsp_ctx->cpu_ctx, CTX_ELR_EL3); -- cgit v1.2.3 From d983b7a167c07d4d5ae1fd856274d54b4599ae03 Mon Sep 17 00:00:00 2001 From: Rui Silva Date: Wed, 9 Oct 2019 12:54:30 +0100 Subject: corstone700: fdts: using DDR memory and XIP rootfs This patch allows to use DDR address in memory node because on FPGA we typically use DDR instead of shared RAM. This patch also modifies the kernel arguments to allow the rootfs to be mounted from a direct mapping of the QSPI NOR flash using the physmap driver in the kernel. This allows to support CRAMFS XIP. Change-Id: I4e2bc6a1f48449c7f60e00f5f1a698df8cb2ba89 Signed-off-by: Vishnu Banavath Signed-off-by: Abdellatif El Khlifi --- fdts/corstone700.dts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/fdts/corstone700.dts b/fdts/corstone700.dts index 8c3bd0c05..c13d3b23e 100644 --- a/fdts/corstone700.dts +++ b/fdts/corstone700.dts @@ -14,9 +14,10 @@ #size-cells = <1>; chosen { - bootargs = "console=ttyAMA0 root=/dev/vda2 rw loglevel=9"; - linux,initrd-start = <0x02a00000>; - linux,initrd-end = <0x04000000>; + bootargs = "console=ttyAMA0 \ + root=mtd:physmap-flash.0 \ + ro \ + loglevel=9"; }; cpus { @@ -32,9 +33,9 @@ }; - memory@2000000 { + memory@80000000 { device_type = "memory"; - reg = <0x02000000 0x02000000>; + reg = <0x80000000 0x80000000>; }; gic: interrupt-controller@1c000000 { -- cgit v1.2.3 From 8c7b944adbf1211d8b60bc6618c17ca959514b10 Mon Sep 17 00:00:00 2001 From: Vijayenthiran Subramaniam Date: Sat, 8 Feb 2020 21:27:30 +0530 Subject: build_macros: add create sequence helper function Add `CREATE_SEQ` function to generate sequence of numbers starting from 1 to allow easy comparison of a user defined macro with non-zero positive numbers. Change-Id: Ibcb336a223d958154b1007d08c428fbaf1e48664 Signed-off-by: Vijayenthiran Subramaniam --- make_helpers/build_macros.mk | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk index 1fa26cc2b..b6925d3b1 100644 --- a/make_helpers/build_macros.mk +++ b/make_helpers/build_macros.mk @@ -67,6 +67,17 @@ $(foreach d,$(0-9),$(eval __numeric := $(subst $(d),,$(__numeric)))) $(if $(__numeric),$(error $(1) must be numeric)) endef +# CREATE_SEQ is a recursive function to create sequence of numbers from 1 to +# $(2) and assign the sequence to $(1) +define CREATE_SEQ +$(if $(word $(2), $($(1))),\ + $(eval $(1) += $(words $($(1))))\ + $(eval $(1) := $(filter-out 0,$($(1)))),\ + $(eval $(1) += $(words $($(1))))\ + $(call CREATE_SEQ,$(1),$(2))\ +) +endef + # IMG_LINKERFILE defines the linker script corresponding to a BL stage # $(1) = BL stage (2, 30, 31, 32, 33) define IMG_LINKERFILE -- cgit v1.2.3 From 9b229b4495d04dff46dea0e8e8fabd7f2c6ba753 Mon Sep 17 00:00:00 2001 From: Vijayenthiran Subramaniam Date: Wed, 12 Feb 2020 13:26:33 +0530 Subject: board/rdn1edge: use CREATE_SEQ helper macro to compare chip count Use CREATE_SEQ helper macro to create sequence of valid chip counts instead of manually creating the sequence. This allows a scalable approach to increase the valid chip count sequence in the future. Change-Id: I5ca7a00460325c156b9e9e52b2bf656a2e43f82d Signed-off-by: Vijayenthiran Subramaniam --- plat/arm/board/rdn1edge/platform.mk | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plat/arm/board/rdn1edge/platform.mk b/plat/arm/board/rdn1edge/platform.mk index 99bb71d79..135676d43 100644 --- a/plat/arm/board/rdn1edge/platform.mk +++ b/plat/arm/board/rdn1edge/platform.mk @@ -51,8 +51,9 @@ NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb # Add the NT_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config)) -ifneq ($(CSS_SGI_CHIP_COUNT),$(filter $(CSS_SGI_CHIP_COUNT),1 2)) - $(error "Chip count for RDN1Edge platform should either 1 or 2, currently \ +$(eval $(call CREATE_SEQ,SEQ,2)) +ifneq ($(CSS_SGI_CHIP_COUNT),$(filter $(CSS_SGI_CHIP_COUNT),$(SEQ))) + $(error "Chip count for RDN1Edge platform should be one of $(SEQ), currently \ set to ${CSS_SGI_CHIP_COUNT}.") endif -- cgit v1.2.3 From 96318f828f5def96251747b33747d01d82e4e5d3 Mon Sep 17 00:00:00 2001 From: Suyash Pathak Date: Thu, 6 Feb 2020 11:51:54 +0530 Subject: plat/arm: allow boards to define PLAT_ARM_TZC_FILTERS A TZC400 can have upto 4 filters and the number of filters instantiated within a TZC400 is platform dependent. So allow platforms to define the value of PLAT_ARM_TZC_FILTERS by moving the existing Juno specific definition of PLAT_ARM_TZC_FILTERS to Juno board definitions. Change-Id: I67a63d7336595bbfdce3163f9a9473e15e266f40 Signed-off-by: Suyash Pathak --- include/plat/arm/css/common/css_def.h | 3 --- plat/arm/board/juno/include/platform_def.h | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/plat/arm/css/common/css_def.h b/include/plat/arm/css/common/css_def.h index 7b6148445..d59935266 100644 --- a/include/plat/arm/css/common/css_def.h +++ b/include/plat/arm/css/common/css_def.h @@ -189,9 +189,6 @@ /* Load address of Non-Secure Image for CSS platform ports */ #define PLAT_ARM_NS_IMAGE_BASE U(0xE0000000) -/* TZC related constants */ -#define PLAT_ARM_TZC_FILTERS TZC_400_REGION_ATTR_FILTER_BIT_ALL - /* * Parsing of CPU and Cluster states, as returned by 'Get CSS Power State' SCP * command diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h index eddd7e570..56e7b566d 100644 --- a/plat/arm/board/juno/include/platform_def.h +++ b/plat/arm/board/juno/include/platform_def.h @@ -212,6 +212,9 @@ TZC_REGION_ACCESS_RDWR(TZC400_NSAID_GPU) | \ TZC_REGION_ACCESS_RDWR(TZC400_NSAID_CORESIGHT)) +/* TZC related constants */ +#define PLAT_ARM_TZC_FILTERS TZC_400_REGION_ATTR_FILTER_BIT_ALL + /* * Required ARM CSS based platform porting definitions */ -- cgit v1.2.3 From 86f297a3e1549624716ccf678f7f80d0141e5834 Mon Sep 17 00:00:00 2001 From: Suyash Pathak Date: Wed, 12 Feb 2020 10:36:20 +0530 Subject: plat/arm: allow boards to specify second DRAM Base address The base address for second DRAM varies across different platforms. So allow platforms to define second DRAM by moving Juno/SGM-775 specific definition of second DRAM base address to Juno/SGM-775 board definition respectively, SGI/RD specific definition of DRAM 2 base address to SGI board definition. Change-Id: I0ecd3a2bd600b6c7019c7f06f8c452952bd07cae Signed-off-by: Suyash Pathak --- include/plat/arm/board/common/board_css_def.h | 9 +-------- plat/arm/board/juno/include/platform_def.h | 3 +++ plat/arm/board/sgm775/include/platform_def.h | 5 ++++- plat/arm/css/sgi/include/sgi_base_platform_def.h | 3 +++ 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/include/plat/arm/board/common/board_css_def.h b/include/plat/arm/board/common/board_css_def.h index 4637b6785..b79e0d572 100644 --- a/include/plat/arm/board/common/board_css_def.h +++ b/include/plat/arm/board/common/board_css_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -50,13 +50,6 @@ #define PLAT_ARM_NVM_BASE V2M_FLASH0_BASE #define PLAT_ARM_NVM_SIZE (V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE) -/* - * Required platform porting definitions common to all ARM CSS-based - * development platforms - */ -#define PLAT_ARM_DRAM2_BASE ULL(0x880000000) -#define PLAT_ARM_DRAM2_SIZE ULL(0x180000000) - /* UART related constants */ #define PLAT_ARM_BOOT_UART_BASE SOC_CSS_UART0_BASE #define PLAT_ARM_BOOT_UART_CLK_IN_HZ SOC_CSS_UART0_CLK_IN_HZ diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h index 56e7b566d..cfac80182 100644 --- a/plat/arm/board/juno/include/platform_def.h +++ b/plat/arm/board/juno/include/platform_def.h @@ -50,6 +50,9 @@ #define NSRAM_BASE UL(0x2e000000) #define NSRAM_SIZE UL(0x00008000) /* 32KB */ +#define PLAT_ARM_DRAM2_BASE ULL(0x880000000) +#define PLAT_ARM_DRAM2_SIZE ULL(0x180000000) + /* virtual address used by dynamic mem_protect for chunk_base */ #define PLAT_ARM_MEM_PROTEC_VA_FRAME UL(0xc0000000) diff --git a/plat/arm/board/sgm775/include/platform_def.h b/plat/arm/board/sgm775/include/platform_def.h index d165ff9ed..e83cd5764 100644 --- a/plat/arm/board/sgm775/include/platform_def.h +++ b/plat/arm/board/sgm775/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -12,6 +12,9 @@ #define PLAT_MAX_CPUS_PER_CLUSTER U(8) #define PLAT_MAX_PE_PER_CPU U(1) +#define PLAT_ARM_DRAM2_BASE ULL(0x880000000) +#define PLAT_ARM_DRAM2_SIZE ULL(0x180000000) + /* * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes */ 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 4986378e9..9a482d0c0 100644 --- a/plat/arm/css/sgi/include/sgi_base_platform_def.h +++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h @@ -123,6 +123,9 @@ #define PLAT_ARM_NSRAM_BASE 0x06000000 #define PLAT_ARM_NSRAM_SIZE 0x00080000 /* 512KB */ +#define PLAT_ARM_DRAM2_BASE ULL(0x8080000000) +#define PLAT_ARM_DRAM2_SIZE ULL(0x180000000) + #define PLAT_ARM_G1S_IRQ_PROPS(grp) CSS_G1S_IRQ_PROPS(grp) #define PLAT_ARM_G0_IRQ_PROPS(grp) ARM_G0_IRQ_PROPS(grp) -- cgit v1.2.3 From 4ed16765187158eab9587d0b1eea13a82aed040f Mon Sep 17 00:00:00 2001 From: Suyash Pathak Date: Tue, 4 Feb 2020 13:55:20 +0530 Subject: plat/arm/tzc: add support to configure multiple tzc400 For platforms that have two or more TZC400 controllers instantiated, allow the TZC400 driver to be usable with all those instances. This is achieved by allowing 'arm_tzc400_setup' function to accept the base address of the TZC400 controller. Change-Id: I4add470e6ddb58432cd066145e644112400ab924 Signed-off-by: Suyash Pathak --- include/plat/arm/common/plat_arm.h | 3 ++- plat/arm/board/fvp/fvp_security.c | 4 ++-- plat/arm/board/juno/juno_security.c | 6 +++--- plat/arm/common/arm_tzc400.c | 9 +++++---- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index 025a64fa2..ac70e7560 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -152,7 +152,8 @@ void arm_setup_romlib(void); int arm_io_setup(void); /* Security utility functions */ -void arm_tzc400_setup(const arm_tzc_regions_info_t *tzc_regions); +void arm_tzc400_setup(uintptr_t tzc_base, + const arm_tzc_regions_info_t *tzc_regions); struct tzc_dmc500_driver_data; void arm_tzc_dmc500_setup(struct tzc_dmc500_driver_data *plat_driver_data, const arm_tzc_regions_info_t *tzc_regions); diff --git a/plat/arm/board/fvp/fvp_security.c b/plat/arm/board/fvp/fvp_security.c index 80ec2171b..937f09f6e 100644 --- a/plat/arm/board/fvp/fvp_security.c +++ b/plat/arm/board/fvp/fvp_security.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -22,5 +22,5 @@ void plat_arm_security_setup(void) */ if ((get_arm_config()->flags & ARM_CONFIG_HAS_TZC) != 0U) - arm_tzc400_setup(NULL); + arm_tzc400_setup(PLAT_ARM_TZC_BASE, NULL); } diff --git a/plat/arm/board/juno/juno_security.c b/plat/arm/board/juno/juno_security.c index 32823e01c..1e64c029d 100644 --- a/plat/arm/board/juno/juno_security.c +++ b/plat/arm/board/juno/juno_security.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -127,13 +127,13 @@ void plat_arm_security_setup(void) init_debug_cfg(); /* Initialize the TrustZone Controller */ #ifdef JUNO_TZMP1 - arm_tzc400_setup(juno_tzmp1_tzc_regions); + arm_tzc400_setup(PLAT_ARM_TZC_BASE, juno_tzmp1_tzc_regions); INFO("TZC protected shared memory base address for TZMP usecase: %p\n", (void *)JUNO_AP_TZC_SHARE_DRAM1_BASE); INFO("TZC protected shared memory end address for TZMP usecase: %p\n", (void *)JUNO_AP_TZC_SHARE_DRAM1_END); #else - arm_tzc400_setup(NULL); + arm_tzc400_setup(PLAT_ARM_TZC_BASE, NULL); #endif /* Do ARM CSS internal NIC setup */ css_init_nic400(); diff --git a/plat/arm/common/arm_tzc400.c b/plat/arm/common/arm_tzc400.c index 34e650f19..370ef0a86 100644 --- a/plat/arm/common/arm_tzc400.c +++ b/plat/arm/common/arm_tzc400.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -19,7 +19,8 @@ * When booting an EL3 payload, this is simplified: we configure region 0 with * secure access only and do not enable any other region. ******************************************************************************/ -void arm_tzc400_setup(const arm_tzc_regions_info_t *tzc_regions) +void arm_tzc400_setup(uintptr_t tzc_base, + const arm_tzc_regions_info_t *tzc_regions) { #ifndef EL3_PAYLOAD_BASE unsigned int region_index = 1U; @@ -32,7 +33,7 @@ void arm_tzc400_setup(const arm_tzc_regions_info_t *tzc_regions) INFO("Configuring TrustZone Controller\n"); - tzc400_init(PLAT_ARM_TZC_BASE); + tzc400_init(tzc_base); /* Disable filters. */ tzc400_disable_filters(); @@ -74,5 +75,5 @@ void arm_tzc400_setup(const arm_tzc_regions_info_t *tzc_regions) void plat_arm_security_setup(void) { - arm_tzc400_setup(NULL); + arm_tzc400_setup(PLAT_ARM_TZC_BASE, NULL); } -- cgit v1.2.3 From 4bbb3a541647cf8729c1ffd7792e8eb6d0669830 Mon Sep 17 00:00:00 2001 From: Suyash Pathak Date: Wed, 12 Feb 2020 10:08:55 +0530 Subject: board/rddaniel: intialize tzc400 controllers A TZC400 controller is placed inline on DRAM channels and regulates the secure and non-secure accesses to both secure and non-secure regions of the DRAM memory. Configure each of the TZC controllers accordingly. Change-Id: I75f6d13591a7fe9e50ce15c793e35a8018041815 Signed-off-by: Suyash Pathak --- plat/arm/board/rddaniel/include/platform_def.h | 15 +++++++++++++++ plat/arm/board/rddaniel/platform.mk | 2 ++ plat/arm/board/rddaniel/rddaniel_security.c | 10 ++++++++++ 3 files changed, 27 insertions(+) diff --git a/plat/arm/board/rddaniel/include/platform_def.h b/plat/arm/board/rddaniel/include/platform_def.h index 516360278..790ed696b 100644 --- a/plat/arm/board/rddaniel/include/platform_def.h +++ b/plat/arm/board/rddaniel/include/platform_def.h @@ -21,6 +21,21 @@ #define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL2 #define PLAT_MAX_PWR_LVL ARM_PWR_LVL1 +/* TZC Related Constants */ +#define PLAT_ARM_TZC_BASE UL(0x21830000) +#define PLAT_ARM_TZC_FILTERS TZC_400_REGION_ATTR_FILTER_BIT(0) + +#define TZC400_OFFSET UL(0x1000000) +#define TZC400_COUNT 4 + +#define TZC400_BASE(n) (PLAT_ARM_TZC_BASE + \ + (n * TZC400_OFFSET)) + +#define TZC_NSAID_ALL_AP U(0) + +#define PLAT_ARM_TZC_NS_DEV_ACCESS \ + (TZC_REGION_ACCESS_RDWR(TZC_NSAID_ALL_AP)) + /* * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes */ diff --git a/plat/arm/board/rddaniel/platform.mk b/plat/arm/board/rddaniel/platform.mk index c7e3c7dd8..ca2647418 100644 --- a/plat/arm/board/rddaniel/platform.mk +++ b/plat/arm/board/rddaniel/platform.mk @@ -18,6 +18,8 @@ BL2_SOURCES += ${RDDANIEL_BASE}/rddaniel_plat.c \ ${RDDANIEL_BASE}/rddaniel_security.c \ ${RDDANIEL_BASE}/rddaniel_err.c \ lib/utils/mem_region.c \ + drivers/arm/tzc/tzc400.c \ + plat/arm/common/arm_tzc400.c \ plat/arm/common/arm_nor_psci_mem_protect.c BL31_SOURCES += ${SGI_CPU_SOURCES} \ diff --git a/plat/arm/board/rddaniel/rddaniel_security.c b/plat/arm/board/rddaniel/rddaniel_security.c index 6aa38c822..1247db860 100644 --- a/plat/arm/board/rddaniel/rddaniel_security.c +++ b/plat/arm/board/rddaniel/rddaniel_security.c @@ -4,9 +4,19 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include #include +static const arm_tzc_regions_info_t tzc_regions[] = { + ARM_TZC_REGIONS_DEF, + {} +}; + /* Initialize the secure environment */ void plat_arm_security_setup(void) { + int i; + + for (i = 0; i < TZC400_COUNT; i++) + arm_tzc400_setup(TZC400_BASE(i), tzc_regions); } -- cgit v1.2.3 From a62b47b87a6dfb3137de51c2dc920cda0001a7b3 Mon Sep 17 00:00:00 2001 From: "Abdul Halim, Muhammad Hadi Asyrafi" Date: Tue, 11 Feb 2020 20:17:05 +0800 Subject: intel: Fix Coverity Scan Defects Fix mailbox driver incompatible cast bug and control flow issue that was flagged by Coverity Scan. Signed-off-by: Abdul Halim, Muhammad Hadi Asyrafi Change-Id: I3f34e98d24e40139d31cf7d5b9b973cd2d981065 --- plat/intel/soc/common/include/socfpga_mailbox.h | 10 +++++----- plat/intel/soc/common/soc/socfpga_mailbox.c | 20 ++++++++++---------- plat/intel/soc/common/socfpga_psci.c | 2 +- plat/intel/soc/common/socfpga_sip_svc.c | 10 +++++----- 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h index 38f46963a..7d725b0ad 100644 --- a/plat/intel/soc/common/include/socfpga_mailbox.h +++ b/plat/intel/soc/common/include/socfpga_mailbox.h @@ -126,21 +126,21 @@ int mailbox_init(void); void mailbox_set_qspi_close(void); void mailbox_set_qspi_open(void); void mailbox_set_qspi_direct(void); -int mailbox_send_cmd(int job_id, unsigned int cmd, uint32_t *args, +int mailbox_send_cmd(int job_id, unsigned int cmd, uint64_t *args, int len, int urgent, uint32_t *response, int resp_len); -int mailbox_send_cmd_async(int job_id, unsigned int cmd, uint32_t *args, +int mailbox_send_cmd_async(int job_id, unsigned int cmd, uint64_t *args, int len, int urgent); int mailbox_read_response(int job_id, uint32_t *response, int resp_len); int mailbox_get_qspi_clock(void); void mailbox_reset_cold(void); void mailbox_clear_response(void); -uint32_t intel_mailbox_get_config_status(uint32_t cmd); +int intel_mailbox_get_config_status(uint32_t cmd); int intel_mailbox_is_fpga_not_ready(void); int mailbox_rsu_get_spt_offset(uint32_t *resp_buf, uint32_t resp_buf_len); int mailbox_rsu_status(uint32_t *resp_buf, uint32_t resp_buf_len); -int mailbox_rsu_update(uint32_t *flash_offset); -int mailbox_hps_stage_notify(uint32_t execution_stage); +int mailbox_rsu_update(uint64_t *flash_offset); +int mailbox_hps_stage_notify(uint64_t execution_stage); #endif /* SOCFPGA_MBOX_H */ diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c index 673c2d56e..8ce40a742 100644 --- a/plat/intel/soc/common/soc/socfpga_mailbox.c +++ b/plat/intel/soc/common/soc/socfpga_mailbox.c @@ -11,7 +11,7 @@ #include "socfpga_mailbox.h" #include "socfpga_sip_svc.h" -static int fill_mailbox_circular_buffer(uint32_t header_cmd, uint32_t *args, +static int fill_mailbox_circular_buffer(uint32_t header_cmd, uint64_t *args, int len) { uint32_t cmd_free_offset; @@ -167,7 +167,7 @@ int mailbox_poll_response(int job_id, int urgent, uint32_t *response, } } -int mailbox_send_cmd_async(int job_id, unsigned int cmd, uint32_t *args, +int mailbox_send_cmd_async(int job_id, unsigned int cmd, uint64_t *args, int len, int urgent) { if (urgent) @@ -184,7 +184,7 @@ int mailbox_send_cmd_async(int job_id, unsigned int cmd, uint32_t *args, return 0; } -int mailbox_send_cmd(int job_id, unsigned int cmd, uint32_t *args, +int mailbox_send_cmd(int job_id, unsigned int cmd, uint64_t *args, int len, int urgent, uint32_t *response, int resp_len) { int status = 0; @@ -252,7 +252,7 @@ int mailbox_get_qspi_clock(void) void mailbox_qspi_set_cs(int device_select) { - uint32_t cs_setting = device_select; + uint64_t cs_setting = device_select; /* QSPI device select settings at 31:28 */ cs_setting = (cs_setting << 28); @@ -304,13 +304,13 @@ int mailbox_rsu_status(uint32_t *resp_buf, uint32_t resp_buf_len) return ret; } -int mailbox_rsu_update(uint32_t *flash_offset) +int mailbox_rsu_update(uint64_t *flash_offset) { return mailbox_send_cmd(MBOX_JOB_ID, MBOX_RSU_UPDATE, - (uint32_t *)flash_offset, 2, 0, NULL, 0); + flash_offset, 2, 0, NULL, 0); } -int mailbox_hps_stage_notify(uint32_t execution_stage) +int mailbox_hps_stage_notify(uint64_t execution_stage) { return mailbox_send_cmd(MBOX_JOB_ID, MBOX_HPS_STAGE_NOTIFY, &execution_stage, 1, 0, NULL, 0); @@ -336,10 +336,10 @@ int mailbox_init(void) return 0; } -uint32_t intel_mailbox_get_config_status(uint32_t cmd) +int intel_mailbox_get_config_status(uint32_t cmd) { - uint32_t status, res; - uint32_t response[6]; + int status; + uint32_t res, response[6]; status = mailbox_send_cmd(1, cmd, NULL, 0, 0, response, sizeof(response) / sizeof(response[0])); diff --git a/plat/intel/soc/common/socfpga_psci.c b/plat/intel/soc/common/socfpga_psci.c index d27ab9f96..d48fb5dd0 100644 --- a/plat/intel/soc/common/socfpga_psci.c +++ b/plat/intel/soc/common/socfpga_psci.c @@ -135,7 +135,7 @@ extern uint64_t intel_rsu_update_address; static void __dead2 socfpga_system_reset(void) { if (intel_rsu_update_address) - mailbox_rsu_update((uint32_t *)&intel_rsu_update_address); + mailbox_rsu_update(&intel_rsu_update_address); else mailbox_reset_cold(); diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c index 5b600e5ea..1c3d45bee 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -61,7 +61,7 @@ struct fpga_config_info fpga_config_buffers[FPGA_CONFIG_BUFFER_SIZE]; static int intel_fpga_sdm_write_buffer(struct fpga_config_info *buffer) { - uint32_t args[3]; + uint64_t args[3]; while (max_blocks > 0 && buffer->size > buffer->size_written) { args[0] = (1<<8); @@ -256,7 +256,7 @@ static bool is_address_in_ddr_range(uint64_t addr, uint64_t size) { if (size > (UINT64_MAX - addr)) return false; - if (addr < DRAM_BASE) + if (addr < BL31_LIMIT) return false; if (addr + size > DRAM_BASE + DRAM_SIZE) return false; @@ -387,7 +387,7 @@ static uint32_t intel_rsu_update(uint64_t update_address) static uint32_t intel_rsu_notify(uint64_t execution_stage) { - if (mailbox_hps_stage_notify((uint32_t)execution_stage) < 0) + if (mailbox_hps_stage_notify(execution_stage) < 0) return INTEL_SIP_SMC_STATUS_ERROR; return INTEL_SIP_SMC_STATUS_OK; @@ -404,7 +404,7 @@ static uint32_t intel_rsu_retry_counter(uint32_t *respbuf, uint32_t respbuf_sz, } /* Mailbox services */ -static uint32_t intel_mbox_send_cmd(uint32_t cmd, uint32_t *args, int len, +static uint32_t intel_mbox_send_cmd(uint32_t cmd, uint64_t *args, int len, int urgent, uint32_t *response, int resp_len, int *mbox_status, int *len_in_resp) @@ -542,7 +542,7 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, case INTEL_SIP_SMC_MBOX_SEND_CMD: x5 = SMC_GET_GP(handle, CTX_GPREG_X5); x6 = SMC_GET_GP(handle, CTX_GPREG_X6); - status = intel_mbox_send_cmd(x1, (uint32_t *)x2, x3, x4, + status = intel_mbox_send_cmd(x1, (uint64_t *)x2, x3, x4, (uint32_t *)x5, x6, &mbox_status, &len_in_resp); SMC_RET4(handle, status, mbox_status, x5, len_in_resp); -- cgit v1.2.3 From af10d224865d8af1045ac22e19e55d04f75b3830 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Wed, 19 Feb 2020 13:36:50 +0000 Subject: Use consistent SMCCC error code Removed duplicate error code present for SMCCC and used proper error code for "SMCCC_ARCH_WORKAROUND_2" call. Signed-off-by: Manish V Badarkhe Change-Id: I76fc7c88095f78a7e2c3d205838f8eaf3132ed5c --- include/services/arm_arch_svc.h | 2 -- services/arm_arch_svc/arm_arch_svc_setup.c | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/include/services/arm_arch_svc.h b/include/services/arm_arch_svc.h index 23c6f5660..1cb2038c6 100644 --- a/include/services/arm_arch_svc.h +++ b/include/services/arm_arch_svc.h @@ -12,6 +12,4 @@ #define SMCCC_ARCH_WORKAROUND_1 U(0x80008000) #define SMCCC_ARCH_WORKAROUND_2 U(0x80007FFF) -#define SMCCC_ARCH_NOT_REQUIRED -2 - #endif /* ARM_ARCH_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 1fc7827b4..6dac56ec8 100644 --- a/services/arm_arch_svc/arm_arch_svc_setup.c +++ b/services/arm_arch_svc/arm_arch_svc_setup.c @@ -66,7 +66,7 @@ static int32_t smccc_arch_features(u_register_t arg) return 0; #else /* Either the CPUs are unaffected or permanently mitigated */ - return SMCCC_ARCH_NOT_REQUIRED; + return SMC_ARCH_CALL_NOT_REQUIRED; #endif } #endif -- cgit v1.2.3 From cd0ea1842f7ef5f3c8ccc3205cc0f3840f573f64 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Tue, 12 Jun 2018 16:49:12 -0700 Subject: cpus: higher performance non-cacheable load forwarding The CPUACTLR_EL1 register on Cortex-A57 CPUs supports a bit to enable non-cacheable streaming enhancement. Platforms can set this bit only if their memory system meets the requirement that cache line fill requests from the Cortex-A57 processor are atomic. This patch adds support to enable higher performance non-cacheable load forwarding for such platforms. Platforms must enable this support by setting the 'A57_ENABLE_NONCACHEABLE_LOAD_FWD' flag from their makefiles. This flag is disabled by default. Change-Id: Ib27e55dd68d11a50962c0bbc5b89072208b4bac5 Signed-off-by: Varun Wadekar --- docs/design/cpu-specific-build-macros.rst | 7 +++++++ include/lib/cpus/aarch64/cortex_a57.h | 2 ++ lib/cpus/aarch64/cortex_a57.S | 12 ++++++++++++ lib/cpus/cpu-ops.mk | 9 +++++++++ 4 files changed, 30 insertions(+) diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst index f3096b418..258f73d0b 100644 --- a/docs/design/cpu-specific-build-macros.rst +++ b/docs/design/cpu-specific-build-macros.rst @@ -324,6 +324,13 @@ architecture that can be enabled by the platform as desired. as recommended in section "4.7 Non-Temporal Loads/Stores" of the `Cortex-A57 Software Optimization Guide`_. +- ''A57_ENABLE_NON_CACHEABLE_LOAD_FWD'': This flag enables non-cacheable + streaming enhancement feature for Cortex-A57 CPUs. Platforms can set + this bit only if their memory system meets the requirement that cache + line fill requests from the Cortex-A57 processor are atomic. Each + Cortex-A57 based platform must make its own decision on whether to use + the optimization. This flag is disabled by default. + - ``NEOVERSE_N1_EXTERNAL_LLC``: This flag indicates that an external last level cache(LLC) is present in the system, and that the DataSource field on the master CHI interface indicates when data is returned from the LLC. diff --git a/include/lib/cpus/aarch64/cortex_a57.h b/include/lib/cpus/aarch64/cortex_a57.h index 102ff60c3..dc40e31ad 100644 --- a/include/lib/cpus/aarch64/cortex_a57.h +++ b/include/lib/cpus/aarch64/cortex_a57.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -54,6 +55,7 @@ #define CORTEX_A57_CPUACTLR_EL1_FORCE_FPSCR_FLUSH (ULL(1) << 38) #define CORTEX_A57_CPUACTLR_EL1_DIS_INSTR_PREFETCH (ULL(1) << 32) #define CORTEX_A57_CPUACTLR_EL1_DIS_STREAMING (ULL(3) << 27) +#define CORTEX_A57_CPUACTLR_EL1_EN_NC_LOAD_FWD (ULL(1) << 24) #define CORTEX_A57_CPUACTLR_EL1_DIS_L1_STREAMING (ULL(3) << 25) #define CORTEX_A57_CPUACTLR_EL1_DIS_INDIRECT_PREDICTOR (ULL(1) << 4) diff --git a/lib/cpus/aarch64/cortex_a57.S b/lib/cpus/aarch64/cortex_a57.S index dd03c0f02..3fee4704e 100644 --- a/lib/cpus/aarch64/cortex_a57.S +++ b/lib/cpus/aarch64/cortex_a57.S @@ -1,5 +1,6 @@ /* * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -469,6 +470,17 @@ func cortex_a57_reset_func dsb sy #endif +#if A57_ENABLE_NONCACHEABLE_LOAD_FWD + /* --------------------------------------------- + * Enable higher performance non-cacheable load + * forwarding + * --------------------------------------------- + */ + mrs x0, CORTEX_A57_CPUACTLR_EL1 + orr x0, x0, #CORTEX_A57_CPUACTLR_EL1_EN_NC_LOAD_FWD + msr CORTEX_A57_CPUACTLR_EL1, x0 +#endif + /* --------------------------------------------- * Enable the SMP bit. * --------------------------------------------- diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk index e3bfc2f2e..3c0c9cd13 100644 --- a/lib/cpus/cpu-ops.mk +++ b/lib/cpus/cpu-ops.mk @@ -1,5 +1,6 @@ # # Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2020, NVIDIA Corporation. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -16,6 +17,10 @@ A53_DISABLE_NON_TEMPORAL_HINT ?=1 # It is enabled by default. A57_DISABLE_NON_TEMPORAL_HINT ?=1 +# Flag to enable higher performance non-cacheable load forwarding. +# It is disabled by default. +A57_ENABLE_NONCACHEABLE_LOAD_FWD ?= 0 + WORKAROUND_CVE_2017_5715 ?=1 WORKAROUND_CVE_2018_3639 ?=1 DYNAMIC_WORKAROUND_CVE_2018_3639 ?=0 @@ -24,6 +29,10 @@ DYNAMIC_WORKAROUND_CVE_2018_3639 ?=0 # By default internal NEOVERSE_N1_EXTERNAL_LLC ?=0 +# Process A57_ENABLE_NONCACHEABLE_LOAD_FWD flag +$(eval $(call assert_boolean,A57_ENABLE_NONCACHEABLE_LOAD_FWD)) +$(eval $(call add_define,A57_ENABLE_NONCACHEABLE_LOAD_FWD)) + # Process SKIP_A57_L1_FLUSH_PWR_DWN flag $(eval $(call assert_boolean,SKIP_A57_L1_FLUSH_PWR_DWN)) $(eval $(call add_define,SKIP_A57_L1_FLUSH_PWR_DWN)) -- cgit v1.2.3 From 8baa16f820a5b2e79f067025c1fdb6419f475cd4 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Tue, 12 Jun 2018 16:54:55 -0700 Subject: Tegra210: enable higher performance non-cacheable load forwarding This patch enables higher performance non-cacheable load forwarding for Tegra210 platforms. Change-Id: I11d0ffc09aca97d37386f283f2fbd2483d51fd28 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/soc/t210/platform_t210.mk | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plat/nvidia/tegra/soc/t210/platform_t210.mk b/plat/nvidia/tegra/soc/t210/platform_t210.mk index 4f2db5386..0d27bcdc5 100644 --- a/plat/nvidia/tegra/soc/t210/platform_t210.mk +++ b/plat/nvidia/tegra/soc/t210/platform_t210.mk @@ -57,3 +57,6 @@ ERRATA_A53_855873 := 1 # Skip L1 $ flush when powering down Cortex-A57 CPUs SKIP_A57_L1_FLUSH_PWR_DWN := 1 + +# Enable higher performance Non-cacheable load forwarding +A57_ENABLE_NONCACHEABLE_LOAD_FWD := 1 -- cgit v1.2.3 From 103ea3f44ca0818157c063d56701d9d0b8629a0d Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Tue, 12 Jun 2018 16:55:06 -0700 Subject: Tegra186: enable higher performance non-cacheable load forwarding This patch enables higher performance non-cacheable load forwarding for Tegra186 platforms. Change-Id: Ifceb304bfbd805f415bb6205c9679602ecb47b53 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/soc/t186/platform_t186.mk | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plat/nvidia/tegra/soc/t186/platform_t186.mk b/plat/nvidia/tegra/soc/t186/platform_t186.mk index fe158536c..a11a77bf5 100644 --- a/plat/nvidia/tegra/soc/t186/platform_t186.mk +++ b/plat/nvidia/tegra/soc/t186/platform_t186.mk @@ -1,5 +1,6 @@ # # Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2020, NVIDIA Corporation. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -64,3 +65,6 @@ ERRATA_A57_826977 := 1 ERRATA_A57_828024 := 1 ERRATA_A57_829520 := 1 ERRATA_A57_833471 := 1 + +# Enable higher performance Non-cacheable load forwarding +A57_ENABLE_NONCACHEABLE_LOAD_FWD := 1 -- cgit v1.2.3 From b20a8b92f959496de1c9816832be1d7d6a0fe983 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Wed, 13 Jun 2018 14:54:01 -0700 Subject: Tegra: macro for legacy WDT FIQ handling This patch adds the macro to enable legacy FIQ handling to the common Tegra makefile. The default value of this macro is '0'. Platforms that need this support should enable it from their makefiles. This patch also helps fix violation of Rule 20.9. Rule 20.9 "All identifiers used in the controlling expression of #if of #elif preprocessing directives shall be #define'd before evaluation" Change-Id: I4f0c9917c044b5b1967fb5e79542cd3bf6e91f18 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/platform.mk | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/plat/nvidia/tegra/platform.mk b/plat/nvidia/tegra/platform.mk index 0917d8701..9ff1aae82 100644 --- a/plat/nvidia/tegra/platform.mk +++ b/plat/nvidia/tegra/platform.mk @@ -1,5 +1,6 @@ # # Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2020, NVIDIA Corporation. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -37,9 +38,15 @@ WARMBOOT_ENABLE_DCACHE_EARLY := 1 # remove the standard libc OVERRIDE_LIBC := 1 +# Flag to enable WDT FIQ interrupt handling for Tegra SoCs +# prior to Tegra186 +ENABLE_WDT_LEGACY_FIQ_HANDLING ?= 0 + include plat/nvidia/tegra/common/tegra_common.mk include ${SOC_DIR}/platform_${TARGET_SOC}.mk +$(eval $(call add_define,ENABLE_WDT_LEGACY_FIQ_HANDLING)) + # modify BUILD_PLAT to point to SoC specific build directory BUILD_PLAT := ${BUILD_BASE}/${PLAT}/${TARGET_SOC}/${BUILD_TYPE} -- cgit v1.2.3 From 3414bad8f96285cbb0968c8389c8f8fdabba8cbf Mon Sep 17 00:00:00 2001 From: kalyani chidambaram Date: Tue, 19 Jun 2018 15:56:01 -0700 Subject: Tegra210: resume PMC hardware block for all platforms The PMC hardware block resume handler was called for Tegra210 platforms, only if the sc7entry-fw was present on the device. This would cause problems for devices that do not support this firmware. This patch fixes this logic and resumes the PMC block even if the sc7entry-fw is not present on the device. Change-Id: I6f0eb7878126f624ea98392f583ed45a231d27db Signed-off-by: Kalyani Chidambaram --- plat/nvidia/tegra/soc/t210/plat_psci_handlers.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c index 4ef9558ee..295a9a9ce 100644 --- a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c @@ -533,10 +533,11 @@ int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state) tegra_fc_lock_active_cluster(); /* - * Resume PMC hardware block for Tegra210 platforms supporting sc7entry-fw - */ - if (!tegra_chipid_is_t210_b01() && (plat_params->sc7entry_fw_base != 0U)) + * Resume PMC hardware block for Tegra210 platforms + */ + if (!tegra_chipid_is_t210_b01()) { tegra_pmc_resume(); + } return PSCI_E_SUCCESS; } -- cgit v1.2.3 From 56e7d6a716eb40967d9c7e599e7b2995ccbcfff7 Mon Sep 17 00:00:00 2001 From: Pritesh Raithatha Date: Wed, 6 Jun 2018 11:02:55 +0530 Subject: Tegra194: memctrl: lock mc stream id security config This patch locks most of the stream id security config registers as per HW guidance. This patch keeps the stream id configs unlocked for the following clients, to allow some platforms to still function, until they make the transition to the latest guidance. - ISPRA - ISPFALR - ISPFALW - ISPWA - ISPWA1 - ISPWB - XUSB_DEVR - XUSB_DEVW - XUSB_HOSTR - XUSB_HOSTW - VIW - VIFALR - VIFALW Change-Id: I66192b228a0a237035938f498babc0325764d5df Signed-off-by: Pritesh Raithatha --- plat/nvidia/tegra/soc/t194/plat_memctrl.c | 218 +++++++++++++++--------------- 1 file changed, 109 insertions(+), 109 deletions(-) diff --git a/plat/nvidia/tegra/soc/t194/plat_memctrl.c b/plat/nvidia/tegra/soc/t194/plat_memctrl.c index bb1dd6706..2208b85e7 100644 --- a/plat/nvidia/tegra/soc/t194/plat_memctrl.c +++ b/plat/nvidia/tegra/soc/t194/plat_memctrl.c @@ -145,13 +145,13 @@ const static uint32_t tegra194_streamid_override_regs[] = { * Array to hold the security configs for stream IDs ******************************************************************************/ const static mc_streamid_security_cfg_t tegra194_streamid_sec_cfgs[] = { - mc_make_sec_cfg(HDAR, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(HOST1XDMAR, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(NVENCSRD, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(SATAR, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(NVENCSWR, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(HDAW, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(SATAW, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(HDAR, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(HOST1XDMAR, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(NVENCSRD, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(SATAR, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(NVENCSWR, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(HDAW, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(SATAW, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(ISPRA, NON_SECURE, NO_OVERRIDE, ENABLE), mc_make_sec_cfg(ISPFALR, NON_SECURE, NO_OVERRIDE, ENABLE), mc_make_sec_cfg(ISPWA, NON_SECURE, NO_OVERRIDE, ENABLE), @@ -160,115 +160,115 @@ const static mc_streamid_security_cfg_t tegra194_streamid_sec_cfgs[] = { mc_make_sec_cfg(XUSB_HOSTW, NON_SECURE, NO_OVERRIDE, ENABLE), mc_make_sec_cfg(XUSB_DEVR, NON_SECURE, NO_OVERRIDE, ENABLE), mc_make_sec_cfg(XUSB_DEVW, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(TSECSRD, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(TSECSWR, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(SDMMCRA, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(SDMMCR, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(SDMMCRAB, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(SDMMCWA, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(SDMMCW, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(SDMMCWAB, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(VICSRD, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(VICSWR, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(TSECSRD, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(TSECSWR, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(SDMMCRA, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(SDMMCR, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(SDMMCRAB, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(SDMMCWA, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(SDMMCW, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(SDMMCWAB, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(VICSRD, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(VICSWR, NON_SECURE, NO_OVERRIDE, DISABLE), mc_make_sec_cfg(VIW, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(NVDECSRD, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(NVDECSWR, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(APER, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(APEW, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(NVJPGSRD, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(NVJPGSWR, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(SESRD, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(SESWR, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(AXIAPR, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(AXIAPW, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(ETRR, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(ETRW, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(TSECSRDB, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(TSECSWRB, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(NVDECSRD, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(NVDECSWR, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(APER, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(APEW, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(NVJPGSRD, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(NVJPGSWR, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(SESRD, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(SESWR, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(AXIAPR, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(AXIAPW, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(ETRR, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(ETRW, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(TSECSRDB, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(TSECSWRB, NON_SECURE, NO_OVERRIDE, DISABLE), mc_make_sec_cfg(AXISR, SECURE, NO_OVERRIDE, DISABLE), mc_make_sec_cfg(AXISW, SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(EQOSR, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(EQOSW, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(UFSHCR, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(UFSHCW, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(NVDISPLAYR, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(BPMPR, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(BPMPW, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(BPMPDMAR, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(BPMPDMAW, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(AONR, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(AONW, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(AONDMAR, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(AONDMAW, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(SCER, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(SCEW, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(SCEDMAR, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(SCEDMAW, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(APEDMAR, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(APEDMAW, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(NVDISPLAYR1, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(VICSRD1, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(NVDECSRD1, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(EQOSR, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(EQOSW, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(UFSHCR, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(UFSHCW, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(NVDISPLAYR, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(BPMPR, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(BPMPW, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(BPMPDMAR, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(BPMPDMAW, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(AONR, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(AONW, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(AONDMAR, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(AONDMAW, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(SCER, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(SCEW, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(SCEDMAR, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(SCEDMAW, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(APEDMAR, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(APEDMAW, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(NVDISPLAYR1, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(VICSRD1, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(NVDECSRD1, NON_SECURE, NO_OVERRIDE, DISABLE), mc_make_sec_cfg(VIFALR, NON_SECURE, NO_OVERRIDE, ENABLE), mc_make_sec_cfg(VIFALW, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(DLA0RDA, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(DLA0FALRDB, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(DLA0WRA, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(DLA0FALWRB, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(DLA1RDA, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(DLA1FALRDB, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(DLA1WRA, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(DLA1FALWRB, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(PVA0RDA, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(PVA0RDB, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(PVA0RDC, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(PVA0WRA, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(PVA0WRB, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(PVA0WRC, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(PVA1RDA, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(PVA1RDB, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(PVA1RDC, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(PVA1WRA, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(PVA1WRB, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(PVA1WRC, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(RCER, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(RCEW, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(RCEDMAR, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(RCEDMAW, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(NVENC1SRD, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(NVENC1SWR, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(PCIE0R, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(PCIE0W, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(PCIE1R, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(PCIE1W, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(PCIE2AR, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(PCIE2AW, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(PCIE3R, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(PCIE3W, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(PCIE4R, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(PCIE4W, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(PCIE5R, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(PCIE5W, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(DLA0RDA, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(DLA0FALRDB, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(DLA0WRA, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(DLA0FALWRB, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(DLA1RDA, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(DLA1FALRDB, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(DLA1WRA, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(DLA1FALWRB, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(PVA0RDA, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(PVA0RDB, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(PVA0RDC, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(PVA0WRA, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(PVA0WRB, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(PVA0WRC, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(PVA1RDA, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(PVA1RDB, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(PVA1RDC, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(PVA1WRA, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(PVA1WRB, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(PVA1WRC, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(RCER, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(RCEW, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(RCEDMAR, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(RCEDMAW, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(NVENC1SRD, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(NVENC1SWR, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(PCIE0R, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(PCIE0W, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(PCIE1R, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(PCIE1W, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(PCIE2AR, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(PCIE2AW, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(PCIE3R, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(PCIE3W, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(PCIE4R, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(PCIE4W, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(PCIE5R, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(PCIE5W, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(ISPFALW, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(DLA0RDA1, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(DLA1RDA1, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(PVA0RDA1, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(PVA0RDB1, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(PVA1RDA1, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(PVA1RDB1, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(PCIE5R1, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(NVENCSRD1, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(NVENC1SRD1, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(DLA0RDA1, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(DLA1RDA1, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(PVA0RDA1, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(PVA0RDB1, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(PVA1RDA1, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(PVA1RDB1, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(PCIE5R1, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(NVENCSRD1, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(NVENC1SRD1, NON_SECURE, NO_OVERRIDE, DISABLE), mc_make_sec_cfg(ISPRA1, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(PCIE0R1, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(MIU0R, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(MIU0W, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(MIU1R, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(MIU1W, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(MIU2R, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(MIU2W, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(MIU3R, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(MIU3W, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(PCIE0R1, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(MIU0R, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(MIU0W, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(MIU1R, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(MIU1W, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(MIU2R, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(MIU2W, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(MIU3R, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(MIU3W, NON_SECURE, OVERRIDE, DISABLE) }; /* To be called by common memctrl_v2.c */ -- cgit v1.2.3 From d4b29105f4d4d11f4bd0f64a7ff9a49c897d804e Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Thu, 13 Feb 2020 13:07:12 -0800 Subject: include: move MHZ_TICKS_PER_SEC to utils_def.h This patch moves the MHZ_TICKS_PER_SEC macro to utils_def.h for other platforms to use. Signed-off-by: Varun Wadekar Change-Id: I6c4dc733f548d73cfdb3515ec9ad89a9efaf4407 --- drivers/delay_timer/generic_delay_timer.c | 5 ++--- include/lib/utils_def.h | 6 ++++++ plat/common/plat_psci_common.c | 5 ++--- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/delay_timer/generic_delay_timer.c b/drivers/delay_timer/generic_delay_timer.c index 3d0a11f59..ca522e05a 100644 --- a/drivers/delay_timer/generic_delay_timer.c +++ b/drivers/delay_timer/generic_delay_timer.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -12,11 +13,9 @@ #include #include #include +#include #include -/* Ticks elapsed in one second by a signal of 1 MHz */ -#define MHZ_TICKS_PER_SEC 1000000 - static timer_ops_t ops; static uint32_t get_timer_value(void) diff --git a/include/lib/utils_def.h b/include/lib/utils_def.h index 23f59bdc3..09ae3999d 100644 --- a/include/lib/utils_def.h +++ b/include/lib/utils_def.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -157,4 +158,9 @@ # define SPECULATION_SAFE_VALUE(var) var #endif +/* + * Ticks elapsed in one second with a signal of 1 MHz + */ +#define MHZ_TICKS_PER_SEC U(1000000) + #endif /* UTILS_DEF_H */ diff --git a/plat/common/plat_psci_common.c b/plat/common/plat_psci_common.c index 80ed8198b..bed8890a7 100644 --- a/plat/common/plat_psci_common.c +++ b/plat/common/plat_psci_common.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,6 +10,7 @@ #include #include #include +#include #include #if ENABLE_PSCI_STAT && ENABLE_PMF @@ -16,9 +18,6 @@ #pragma weak plat_psci_stat_accounting_stop #pragma weak plat_psci_stat_get_residency -/* Ticks elapsed in one second by a signal of 1 MHz */ -#define MHZ_TICKS_PER_SEC 1000000U - /* Maximum time-stamp value read from architectural counters */ #ifdef __aarch64__ #define MAX_TS UINT64_MAX -- cgit v1.2.3 From dd4f0885a0aad2af6d873c00ac5b49e166c5e339 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Mon, 18 Jun 2018 16:15:51 -0700 Subject: Tegra: delay_timer: support for physical secure timer This patch modifies the delay timer driver to switch to the ARM secure physical timer instead of using Tegra's on-chip uS timer. The secure timer is not accessible to the NS world and so eliminates an important attack vector, where the Tegra timer source gets switched off from the NS world leading to a DoS attack for the trusted world. This timer is shared with the S-EL1 layer for now, but later patches will mark it as exclusive to the EL3 exception mode. Change-Id: I2c00f8cb4c48b25578971c626c314603906ad7cc Signed-off-by: Varun Wadekar --- include/arch/aarch64/arch.h | 5 +++ plat/nvidia/tegra/common/tegra_delay_timer.c | 46 ++++++++++++++++++++++------ 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index 1fcd0f9ba..1faddbedc 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -597,6 +598,10 @@ #define CNTP_CTL_IMASK_MASK U(1) #define CNTP_CTL_ISTATUS_MASK U(1) +/* Physical timer control macros */ +#define CNTP_CTL_ENABLE_BIT (U(1) << CNTP_CTL_ENABLE_SHIFT) +#define CNTP_CTL_IMASK_BIT (U(1) << CNTP_CTL_IMASK_SHIFT) + /* Exception Syndrome register bits and bobs */ #define ESR_EC_SHIFT U(26) #define ESR_EC_MASK U(0x3f) diff --git a/plat/nvidia/tegra/common/tegra_delay_timer.c b/plat/nvidia/tegra/common/tegra_delay_timer.c index 63dcf410c..cfd9a15e3 100644 --- a/plat/nvidia/tegra/common/tegra_delay_timer.c +++ b/plat/nvidia/tegra/common/tegra_delay_timer.c @@ -1,31 +1,59 @@ /* * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ +#include + #include #include +#include +#include #include #include -static uint32_t tegra_timerus_get_value(void) +static uint32_t tegra_timer_get_value(void) { - return mmio_read_32(TEGRA_TMRUS_BASE); + /* enable cntps_tval_el1 timer, mask interrupt */ + write_cntps_ctl_el1(CNTP_CTL_IMASK_BIT | CNTP_CTL_ENABLE_BIT); + + /* + * Generic delay timer implementation expects the timer to be a down + * counter. We apply bitwise NOT operator to the tick values returned + * by read_cntps_tval_el1() to simulate the down counter. The value is + * clipped from 64 to 32 bits. + */ + return (uint32_t)(~read_cntps_tval_el1()); } /* - * Initialise the on-chip free rolling us counter as the delay - * timer. + * Initialise the architecture provided counter as the delay timer. */ void tegra_delay_timer_init(void) { - static const timer_ops_t tegra_timer_ops = { - .get_timer_value = tegra_timerus_get_value, - .clk_mult = 1, - .clk_div = 1, - }; + static timer_ops_t tegra_timer_ops; + + /* Value in ticks */ + uint32_t multiplier = MHZ_TICKS_PER_SEC; + + /* Value in ticks per second (Hz) */ + uint32_t divider = plat_get_syscnt_freq2(); + + /* Reduce multiplier and divider by dividing them repeatedly by 10 */ + while (((multiplier % 10U) == 0U) && ((divider % 10U) == 0U)) { + multiplier /= 10U; + divider /= 10U; + } + + /* enable cntps_tval_el1 timer, mask interrupt */ + write_cntps_ctl_el1(CNTP_CTL_IMASK_BIT | CNTP_CTL_ENABLE_BIT); + /* register the timer */ + tegra_timer_ops.get_timer_value = tegra_timer_get_value; + tegra_timer_ops.clk_mult = multiplier; + tegra_timer_ops.clk_div = divider; timer_init(&tegra_timer_ops); } -- cgit v1.2.3 From 37f760241e75bbfa5c4043f9e451fc0ce7ed42f7 Mon Sep 17 00:00:00 2001 From: kalyani chidambaram Date: Mon, 9 Apr 2018 15:18:02 -0700 Subject: Tegra210: secure PMC hardware block This patch sets the "secure" bit to mark the PMC hardware block as accessible only from the secure world. This setting must be programmed during cold boot and System Resume. The sc7entry-fw, running on the COP, needs access to the PMC block to enter System Suspend state, so "unlock" the PMC block before passing control to the COP. Change-Id: I00e39a49ae6b9f8c8eafe0cf7ff63fe6a67fdccf Signed-off-by: kalyani chidambaram --- plat/nvidia/tegra/soc/t210/plat_psci_handlers.c | 13 ++++++++++++- plat/nvidia/tegra/soc/t210/plat_setup.c | 7 +++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c index 295a9a9ce..832b8d647 100644 --- a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c @@ -394,6 +394,15 @@ int tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state) */ tegra_reset_all_dma_masters(); + /* + * Mark PMC as accessible to the non-secure world + * to allow the COP to execute System Suspend + * sequence + */ + val = mmio_read_32(TEGRA_MISC_BASE + APB_SLAVE_SECURITY_ENABLE); + val &= ~PMC_SECURITY_EN_BIT; + mmio_write_32(TEGRA_MISC_BASE + APB_SLAVE_SECURITY_ENABLE, val); + /* clean up IRAM of any cruft */ zeromem((void *)(uintptr_t)TEGRA_IRAM_BASE, TEGRA_IRAM_A_SIZE); @@ -480,12 +489,14 @@ int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state) tegra_bpmp_resume(); } - /* sc7entry-fw is part of TZDRAM area */ if (plat_params->sc7entry_fw_base != 0U) { + /* sc7entry-fw is part of TZDRAM area */ offset = plat_params->tzdram_base - plat_params->sc7entry_fw_base; tegra_memctrl_tzdram_setup(plat_params->sc7entry_fw_base, plat_params->tzdram_size + offset); + } + if (!tegra_chipid_is_t210_b01()) { /* restrict PMC access to secure world */ val = mmio_read_32(TEGRA_MISC_BASE + APB_SLAVE_SECURITY_ENABLE); val |= PMC_SECURITY_EN_BIT; diff --git a/plat/nvidia/tegra/soc/t210/plat_setup.c b/plat/nvidia/tegra/soc/t210/plat_setup.c index da1f1b33e..c4bd58e33 100644 --- a/plat/nvidia/tegra/soc/t210/plat_setup.c +++ b/plat/nvidia/tegra/soc/t210/plat_setup.c @@ -236,6 +236,13 @@ void plat_late_platform_setup(void) val |= PMC_SECURITY_EN_BIT; mmio_write_32(TEGRA_MISC_BASE + APB_SLAVE_SECURITY_ENABLE, val); } + + if (!tegra_chipid_is_t210_b01()) { + /* restrict PMC access to secure world */ + val = mmio_read_32(TEGRA_MISC_BASE + APB_SLAVE_SECURITY_ENABLE); + val |= PMC_SECURITY_EN_BIT; + mmio_write_32(TEGRA_MISC_BASE + APB_SLAVE_SECURITY_ENABLE, val); + } } /******************************************************************************* -- cgit v1.2.3 From ee21281a5f738f00eeb2a17a775035bae70245ce Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Wed, 20 Jun 2018 13:43:43 -0700 Subject: Tegra: common: improve cyclomatic complexity Code complexity is a good indication of maintainability versus testability of a piece of software. ISO26262 introduces the following thresholds: complexity < 10 is accepted 10 <= complexity < 20 has to be justified complexity >= 20 cannot be accepted Rationale is that number of test cases to fully test a piece of software can (depending on the coverage metrics) grow exponentially with the number of branches in the software. This patch removes redundant conditionals from 'bl31_early_platform_setup' handler to reduce the McCabe Cyclomatic Complexity for this function. Change-Id: Ifb628e33269b388f9323639cd97db761a7e049c4 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/tegra_bl31_setup.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c index 8a49e232d..e8283517d 100644 --- a/plat/nvidia/tegra/common/tegra_bl31_setup.c +++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -102,7 +103,6 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, struct tegra_bl31_params *arg_from_bl2 = (struct tegra_bl31_params *) arg0; plat_params_from_bl2_t *plat_params = (plat_params_from_bl2_t *)arg1; image_info_t bl32_img_info = { {0} }; - uint64_t tzdram_start, tzdram_end, bl32_start, bl32_end; int32_t ret; /* @@ -163,20 +163,17 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, * location to store the boot profiler logs. Sanity check the * address and initialise the profiler library, if it looks ok. */ - if (plat_params->boot_profiler_shmem_base != 0ULL) { + ret = bl31_check_ns_address(plat_params->boot_profiler_shmem_base, + PROFILER_SIZE_BYTES); + if (ret == (int32_t)0) { - ret = bl31_check_ns_address(plat_params->boot_profiler_shmem_base, - PROFILER_SIZE_BYTES); - if (ret == (int32_t)0) { + /* store the membase for the profiler lib */ + plat_bl31_params_from_bl2.boot_profiler_shmem_base = + plat_params->boot_profiler_shmem_base; - /* store the membase for the profiler lib */ - plat_bl31_params_from_bl2.boot_profiler_shmem_base = - plat_params->boot_profiler_shmem_base; - - /* initialise the profiler library */ - boot_profiler_init(plat_params->boot_profiler_shmem_base, - TEGRA_TMRUS_BASE); - } + /* initialise the profiler library */ + boot_profiler_init(plat_params->boot_profiler_shmem_base, + TEGRA_TMRUS_BASE); } /* @@ -205,6 +202,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, */ if (arg_from_bl2->bl32_image_info != NULL) { + uint64_t tzdram_start, tzdram_end, bl32_start, bl32_end; bl32_img_info = *arg_from_bl2->bl32_image_info; /* Relocate BL32 if it resides outside of the TZDRAM */ -- cgit v1.2.3 From 6f47acdb3bd8784b8c2fbdeb399ebefb496807a7 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Wed, 20 Jun 2018 14:30:59 -0700 Subject: Tegra: platform handler to relocate BL32 image This patch provides platforms an opportunity to relocate the BL32 image, during cold boot. Tegra186 platforms, for example, relocate BL32 images to TZDRAM memory as the previous bootloader relies on BL31 to do so. Change-Id: Ibb864901e43aca5bf55d8c79e918b598c12e8a28 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/tegra_bl31_setup.c | 41 ++++------------------------- plat/nvidia/tegra/include/tegra_private.h | 1 + plat/nvidia/tegra/platform.mk | 4 +++ plat/nvidia/tegra/soc/t186/plat_setup.c | 40 ++++++++++++++++++++++++++++ plat/nvidia/tegra/soc/t186/platform_t186.mk | 2 ++ 5 files changed, 52 insertions(+), 36 deletions(-) diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c index e8283517d..46686c368 100644 --- a/plat/nvidia/tegra/common/tegra_bl31_setup.c +++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c @@ -35,8 +35,6 @@ /* length of Trusty's input parameters (in bytes) */ #define TRUSTY_PARAMS_LEN_BYTES (4096*2) -extern void memcpy16(void *dest, const void *src, unsigned int length); - /******************************************************************************* * Declarations of linker defined symbols which will help us find the layout * of trusted SRAM @@ -102,7 +100,6 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, { struct tegra_bl31_params *arg_from_bl2 = (struct tegra_bl31_params *) arg0; plat_params_from_bl2_t *plat_params = (plat_params_from_bl2_t *)arg1; - image_info_t bl32_img_info = { {0} }; int32_t ret; /* @@ -195,42 +192,14 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, tegra_memctrl_tzdram_setup(plat_bl31_params_from_bl2.tzdram_base, (uint32_t)plat_bl31_params_from_bl2.tzdram_size); +#if RELOCATE_BL32_IMAGE /* * The previous bootloader might not have placed the BL32 image - * inside the TZDRAM. We check the BL32 image info to find out - * the base/PC values and relocate the image if necessary. + * inside the TZDRAM. Platform handler to allow relocation of BL32 + * image to TZDRAM memory. This behavior might change per platform. */ - if (arg_from_bl2->bl32_image_info != NULL) { - - uint64_t tzdram_start, tzdram_end, bl32_start, bl32_end; - bl32_img_info = *arg_from_bl2->bl32_image_info; - - /* Relocate BL32 if it resides outside of the TZDRAM */ - tzdram_start = plat_bl31_params_from_bl2.tzdram_base; - tzdram_end = plat_bl31_params_from_bl2.tzdram_base + - plat_bl31_params_from_bl2.tzdram_size; - bl32_start = bl32_img_info.image_base; - bl32_end = bl32_img_info.image_base + bl32_img_info.image_size; - - assert(tzdram_end > tzdram_start); - assert(bl32_end > bl32_start); - assert(bl32_image_ep_info.pc > tzdram_start); - assert(bl32_image_ep_info.pc < tzdram_end); - - /* relocate BL32 */ - if ((bl32_start >= tzdram_end) || (bl32_end <= tzdram_start)) { - - INFO("Relocate BL32 to TZDRAM\n"); - - (void)memcpy16((void *)(uintptr_t)bl32_image_ep_info.pc, - (void *)(uintptr_t)bl32_start, - bl32_img_info.image_size); - - /* clean up non-secure intermediate buffer */ - zeromem((void *)(uintptr_t)bl32_start, - bl32_img_info.image_size); - } - } + plat_relocate_bl32_image(arg_from_bl2->bl32_image_info); +#endif /* * Add timestamp for platform early setup exit. diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h index b419d94e5..c6ecc0e7b 100644 --- a/plat/nvidia/tegra/include/tegra_private.h +++ b/plat/nvidia/tegra/include/tegra_private.h @@ -77,6 +77,7 @@ struct tegra_bl31_params *plat_get_bl31_params(void); plat_params_from_bl2_t *plat_get_bl31_plat_params(void); void plat_early_platform_setup(void); void plat_late_platform_setup(void); +void plat_relocate_bl32_image(const image_info_t *bl32_img_info); /* Declarations for plat_secondary.c */ void plat_secondary_setup(void); diff --git a/plat/nvidia/tegra/platform.mk b/plat/nvidia/tegra/platform.mk index 9ff1aae82..d0ed5d57a 100644 --- a/plat/nvidia/tegra/platform.mk +++ b/plat/nvidia/tegra/platform.mk @@ -42,10 +42,14 @@ OVERRIDE_LIBC := 1 # prior to Tegra186 ENABLE_WDT_LEGACY_FIQ_HANDLING ?= 0 +# Flag to allow relocation of BL32 image to TZDRAM during boot +RELOCATE_BL32_IMAGE ?= 0 + include plat/nvidia/tegra/common/tegra_common.mk include ${SOC_DIR}/platform_${TARGET_SOC}.mk $(eval $(call add_define,ENABLE_WDT_LEGACY_FIQ_HANDLING)) +$(eval $(call add_define,RELOCATE_BL32_IMAGE)) # modify BUILD_PLAT to point to SoC specific build directory BUILD_PLAT := ${BUILD_BASE}/${PLAT}/${TARGET_SOC}/${BUILD_TYPE} diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c index 7e18b5c42..8bf8382a6 100644 --- a/plat/nvidia/tegra/soc/t186/plat_setup.c +++ b/plat/nvidia/tegra/soc/t186/plat_setup.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -20,6 +21,7 @@ #include #include #include +#include #include #include @@ -28,6 +30,8 @@ #include #include +extern void memcpy16(void *dest, const void *src, unsigned int length); + /******************************************************************************* * Tegra186 CPU numbers in cluster #0 ******************************************************************************* @@ -286,3 +290,39 @@ int32_t plat_core_pos_by_mpidr(u_register_t mpidr) return ret; } + +void plat_relocate_bl32_image(const image_info_t *bl32_img_info) +{ + const plat_params_from_bl2_t *plat_bl31_params = plat_get_bl31_plat_params(); + const entry_point_info_t *bl32_ep_info = bl31_plat_get_next_image_ep_info(SECURE); + uint64_t tzdram_start, tzdram_end, bl32_start, bl32_end; + + if ((bl32_img_info != NULL) && (bl32_ep_info != NULL)) { + + /* Relocate BL32 if it resides outside of the TZDRAM */ + tzdram_start = plat_bl31_params->tzdram_base; + tzdram_end = plat_bl31_params->tzdram_base + + plat_bl31_params->tzdram_size; + bl32_start = bl32_img_info->image_base; + bl32_end = bl32_img_info->image_base + bl32_img_info->image_size; + + assert(tzdram_end > tzdram_start); + assert(bl32_end > bl32_start); + assert(bl32_ep_info->pc > tzdram_start); + assert(bl32_ep_info->pc < tzdram_end); + + /* relocate BL32 */ + if ((bl32_start >= tzdram_end) || (bl32_end <= tzdram_start)) { + + INFO("Relocate BL32 to TZDRAM\n"); + + (void)memcpy16((void *)(uintptr_t)bl32_ep_info->pc, + (void *)(uintptr_t)bl32_start, + bl32_img_info->image_size); + + /* clean up non-secure intermediate buffer */ + zeromem((void *)(uintptr_t)bl32_start, + bl32_img_info->image_size); + } + } +} diff --git a/plat/nvidia/tegra/soc/t186/platform_t186.mk b/plat/nvidia/tegra/soc/t186/platform_t186.mk index a11a77bf5..197e4c6ba 100644 --- a/plat/nvidia/tegra/soc/t186/platform_t186.mk +++ b/plat/nvidia/tegra/soc/t186/platform_t186.mk @@ -18,6 +18,8 @@ PROGRAMMABLE_RESET_ADDRESS := 1 COLD_BOOT_SINGLE_CPU := 1 +RELOCATE_BL32_IMAGE := 1 + # platform settings TZDRAM_BASE := 0x30000000 $(eval $(call add_define,TZDRAM_BASE)) -- cgit v1.2.3 From 21368290b451b347da56e5aba6ac1bc621e3009b Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Wed, 20 Jun 2018 16:12:50 -0700 Subject: Tegra: bpmp_ipc: improve cyclomatic complexity Code complexity is a good indication of maintainability versus testability of a piece of software. ISO26262 introduces the following thresholds: complexity < 10 is accepted 10 <= complexity < 20 has to be justified complexity >= 20 cannot be accepted Rationale is that number of test cases to fully test a piece of software can (depending on the coverage metrics) grow exponentially with the number of branches in the software. This patch removes redundant conditionals from 'ipc_send_req_atomic' handler to reduce the McCabe Cyclomatic Complexity for this function Change-Id: I20fef79a771301e1c824aea72a45ff83f97591d5 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c | 55 +++++++++++------------- 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c index eaf96751c..2e90d2547 100644 --- a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c +++ b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c @@ -175,44 +175,39 @@ static int32_t tegra_bpmp_ipc_send_req_atomic(uint32_t mrq, void *p_out, if ((p_out == NULL) || (size_out > IVC_DATA_SZ_BYTES) || (frame == NULL)) { ERROR("%s: invalid parameters, exiting\n", __func__); - ret = -EINVAL; + return -EINVAL; } - if (ret == 0) { - - /* prepare the command frame */ - frame->mrq = mrq; - frame->flags = FLAG_DO_ACK; - p_fdata = frame->data; - (void)memcpy(p_fdata, p_out, (size_t)size_out); + /* prepare the command frame */ + frame->mrq = mrq; + frame->flags = FLAG_DO_ACK; + p_fdata = frame->data; + (void)memcpy(p_fdata, p_out, (size_t)size_out); - /* signal the slave */ - tegra_bpmp_signal_slave(); + /* signal the slave */ + tegra_bpmp_signal_slave(); - /* wait for slave to ack */ - ret = tegra_bpmp_wait_for_slave_ack(); - if (ret != 0) { - ERROR("failed waiting for the slave to ack\n"); - } + /* wait for slave to ack */ + ret = tegra_bpmp_wait_for_slave_ack(); + if (ret < 0) { + ERROR("%s: wait for slave failed (%d)\n", __func__, ret); + return ret; + } - /* retrieve the response frame */ - if ((size_in <= IVC_DATA_SZ_BYTES) && (p_in != NULL) && - (ret == 0)) { + /* retrieve the response frame */ + if ((size_in <= IVC_DATA_SZ_BYTES) && (p_in != NULL)) { - f_in = tegra_bpmp_get_cur_in_frame(); - if (f_in != NULL) { - ERROR("Failed to get next input frame!\n"); - } else { - (void)memcpy(p_in, p_fdata, (size_t)size_in); - } + f_in = tegra_bpmp_get_cur_in_frame(); + if (f_in != NULL) { + ERROR("Failed to get next input frame!\n"); + } else { + (void)memcpy(p_in, p_fdata, (size_t)size_in); } + } - if (ret == 0) { - ret = tegra_bpmp_free_master(); - if (ret != 0) { - ERROR("Failed to free master\n"); - } - } + ret = tegra_bpmp_free_master(); + if (ret < 0) { + ERROR("%s: free master failed (%d)\n", __func__, ret); } return ret; -- cgit v1.2.3 From 5d52aea89d53c2ecf5b88731e8d52ed684dbe302 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Tue, 26 Jun 2018 16:07:50 -0700 Subject: Tegra: handler to check support for System Suspend Tegra210 SoCs need the sc7entry-fw to enter System Suspend mode, but there might be certain boards that do not have this firmware blob. To stop the NS world from issuing System suspend entry commands on such devices, we ned to disable System Suspend from the PSCI "features". This patch removes the System suspend handler from the Tegra PSCI ops, so that the framework will disable support for "System Suspend" from the PSCI "features". Original change by: kalyani chidambaram Change-Id: Ie029f82f55990a8b3a6debb73e95e0e218bfd1f5 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/tegra_pm.c | 10 +++++++++- plat/nvidia/tegra/include/tegra_private.h | 2 ++ plat/nvidia/tegra/soc/t132/plat_setup.c | 8 ++++++++ plat/nvidia/tegra/soc/t186/plat_setup.c | 13 ++++++++++++- plat/nvidia/tegra/soc/t194/plat_setup.c | 11 +++++++++++ plat/nvidia/tegra/soc/t210/plat_setup.c | 18 ++++++++++++++++++ 6 files changed, 60 insertions(+), 2 deletions(-) diff --git a/plat/nvidia/tegra/common/tegra_pm.c b/plat/nvidia/tegra/common/tegra_pm.c index 1f59f30aa..5ec6f849e 100644 --- a/plat/nvidia/tegra/common/tegra_pm.c +++ b/plat/nvidia/tegra/common/tegra_pm.c @@ -259,7 +259,7 @@ int32_t tegra_validate_ns_entrypoint(uintptr_t entrypoint) /******************************************************************************* * Export the platform handlers to enable psci to invoke them ******************************************************************************/ -static const plat_psci_ops_t tegra_plat_psci_ops = { +static plat_psci_ops_t tegra_plat_psci_ops = { .cpu_standby = tegra_cpu_standby, .pwr_domain_on = tegra_pwr_domain_on, .pwr_domain_off = tegra_pwr_domain_off, @@ -295,6 +295,14 @@ int plat_setup_psci_ops(uintptr_t sec_entrypoint, */ (void)tegra_soc_pwr_domain_on_finish(&target_state); + /* + * Disable System Suspend if the platform does not + * support it + */ + if (!plat_supports_system_suspend()) { + tegra_plat_psci_ops.get_sys_suspend_power_state = NULL; + } + /* * Initialize PSCI ops struct */ diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h index c6ecc0e7b..ad3cee4b4 100644 --- a/plat/nvidia/tegra/include/tegra_private.h +++ b/plat/nvidia/tegra/include/tegra_private.h @@ -9,6 +9,7 @@ #define TEGRA_PRIVATE_H #include +#include #include #include @@ -78,6 +79,7 @@ plat_params_from_bl2_t *plat_get_bl31_plat_params(void); void plat_early_platform_setup(void); void plat_late_platform_setup(void); void plat_relocate_bl32_image(const image_info_t *bl32_img_info); +bool plat_supports_system_suspend(void); /* Declarations for plat_secondary.c */ void plat_secondary_setup(void); diff --git a/plat/nvidia/tegra/soc/t132/plat_setup.c b/plat/nvidia/tegra/soc/t132/plat_setup.c index 2f54dd525..4bfc2de0e 100644 --- a/plat/nvidia/tegra/soc/t132/plat_setup.c +++ b/plat/nvidia/tegra/soc/t132/plat_setup.c @@ -154,3 +154,11 @@ void plat_late_platform_setup(void) { ; /* do nothing */ } + +/******************************************************************************* + * Handler to indicate support for System Suspend + ******************************************************************************/ +bool plat_supports_system_suspend(void) +{ + return true; +} diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c index 8bf8382a6..06a328427 100644 --- a/plat/nvidia/tegra/soc/t186/plat_setup.c +++ b/plat/nvidia/tegra/soc/t186/plat_setup.c @@ -291,13 +291,16 @@ int32_t plat_core_pos_by_mpidr(u_register_t mpidr) return ret; } +/******************************************************************************* + * Handler to relocate BL32 image to TZDRAM + ******************************************************************************/ void plat_relocate_bl32_image(const image_info_t *bl32_img_info) { const plat_params_from_bl2_t *plat_bl31_params = plat_get_bl31_plat_params(); const entry_point_info_t *bl32_ep_info = bl31_plat_get_next_image_ep_info(SECURE); uint64_t tzdram_start, tzdram_end, bl32_start, bl32_end; - if ((bl32_img_info != NULL) && (bl32_ep_info != NULL)) { + if ((bl32_img_info != NULL) && (bl32_ep_info != NULL)) { /* Relocate BL32 if it resides outside of the TZDRAM */ tzdram_start = plat_bl31_params->tzdram_base; @@ -326,3 +329,11 @@ void plat_relocate_bl32_image(const image_info_t *bl32_img_info) } } } + +/******************************************************************************* + * Handler to indicate support for System Suspend + ******************************************************************************/ +bool plat_supports_system_suspend(void) +{ + return true; +} diff --git a/plat/nvidia/tegra/soc/t194/plat_setup.c b/plat/nvidia/tegra/soc/t194/plat_setup.c index 912dcc6f9..3640ade0a 100644 --- a/plat/nvidia/tegra/soc/t194/plat_setup.c +++ b/plat/nvidia/tegra/soc/t194/plat_setup.c @@ -304,6 +304,9 @@ plat_params_from_bl2_t *plat_get_bl31_plat_params(void) return (plat_params_from_bl2_t *)(uintptr_t)val; } +/******************************************************************************* + * Handler for late platform setup + ******************************************************************************/ void plat_late_platform_setup(void) { #if ENABLE_STRICT_CHECKING_MODE @@ -314,3 +317,11 @@ void plat_late_platform_setup(void) mce_enable_strict_checking(); #endif } + +/******************************************************************************* + * Handler to indicate support for System Suspend + ******************************************************************************/ +bool plat_supports_system_suspend(void) +{ + return true; +} diff --git a/plat/nvidia/tegra/soc/t210/plat_setup.c b/plat/nvidia/tegra/soc/t210/plat_setup.c index c4bd58e33..c32772de8 100644 --- a/plat/nvidia/tegra/soc/t210/plat_setup.c +++ b/plat/nvidia/tegra/soc/t210/plat_setup.c @@ -262,3 +262,21 @@ void plat_gic_setup(void) */ tegra_fc_enable_fiq_to_ccplex_routing(); } +/******************************************************************************* + * Handler to indicate support for System Suspend + ******************************************************************************/ +bool plat_supports_system_suspend(void) +{ + const plat_params_from_bl2_t *plat_params = bl31_get_plat_params(); + + /* + * sc7entry-fw is only supported by Tegra210 SoCs. + */ + if (!tegra_chipid_is_t210_b01() && (plat_params->sc7entry_fw_base != 0U)) { + return true; + } else if (tegra_chipid_is_t210_b01()) { + return true; + } else { + return false; + } +} -- cgit v1.2.3 From 8a47fe4375234120b041f55e578d051453514e67 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Tue, 19 Jun 2018 17:07:08 -0700 Subject: Tegra: spe: uninit console on a timeout There are chances a denial-of-service attack, if an attacker removes the SPE firmware from the system. The console driver would end up waiting for the firmware to respond indefinitely. The console driver must detect such scenarios and uninit the interface as a result. This patch adds a timeout to the interaction with the SPE firmware and uninits the interface if it times out. Change-Id: I06f27a858baed25711d41105b4110865f1a01727 Signed-off-by: Varun Wadekar --- .../tegra/common/drivers/spe/shared_console.S | 37 ++++++++++++++++------ 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/plat/nvidia/tegra/common/drivers/spe/shared_console.S b/plat/nvidia/tegra/common/drivers/spe/shared_console.S index a3e110ec9..0be34e417 100644 --- a/plat/nvidia/tegra/common/drivers/spe/shared_console.S +++ b/plat/nvidia/tegra/common/drivers/spe/shared_console.S @@ -1,5 +1,6 @@ /* * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -10,6 +11,7 @@ #define CONSOLE_FLUSH_DATA_TO_PORT (1 << 26) #define CONSOLE_RING_DOORBELL (1 << 31) #define CONSOLE_IS_BUSY (1 << 31) +#define CONSOLE_TIMEOUT 0xC000 /* approx. 50 ms */ #define CONSOLE_WRITE (CONSOLE_RING_DOORBELL | CONSOLE_FLUSH_DATA_TO_PORT) /* @@ -30,6 +32,20 @@ .globl console_spe_flush .globl console_spe_register +.macro check_if_console_is_ready base, tmp1, tmp2, label + /* wait until spe is ready or timeout expires */ + mrs \tmp2, cntps_tval_el1 +1: ldr \tmp1, [\base] + and \tmp1, \tmp1, #CONSOLE_IS_BUSY + cbz \tmp1, 2f + mrs \tmp1, cntps_tval_el1 + sub \tmp1, \tmp2, \tmp1 + cmp \tmp1, #CONSOLE_TIMEOUT + b.lt 1b + b \label +2: +.endm + /* ------------------------------------------------- * int console_spe_register(uintptr_t baseaddr, * uint32_t clock, uint32_t baud, @@ -46,6 +62,12 @@ * ------------------------------------------------- */ func console_spe_register + /* Check the input base address */ + cbz x0, register_fail + + /* Dont use clock or baud rate, so ok to overwrite them */ + check_if_console_is_ready x0, x1, x2, register_fail + cbz x3, register_fail str x0, [x3, #CONSOLE_T_DRVDATA] mov x0, x3 @@ -63,7 +85,7 @@ endfunc console_spe_register * In : w0 - character to be printed * x1 - console base address * Out : return -1 on error else return character. - * Clobber list : x2 + * Clobber list : x2, x3 * -------------------------------------------------------- */ func console_spe_core_putc @@ -72,12 +94,9 @@ func console_spe_core_putc /* Prepend '\r' to '\n' */ cmp w0, #0xA - b.ne 2f + b.ne not_eol - /* wait until spe is ready */ -1: ldr w2, [x1] - and w2, w2, #CONSOLE_IS_BUSY - cbnz w2, 1b + check_if_console_is_ready x1, x2, x3, putc_error /* spe is ready */ mov w2, #0xD /* '\r' */ @@ -86,10 +105,8 @@ func console_spe_core_putc orr w2, w2, w3 str w2, [x1] - /* wait until spe is ready */ -2: ldr w2, [x1] - and w2, w2, #CONSOLE_IS_BUSY - cbnz w2, 2b +not_eol: + check_if_console_is_ready x1, x2, x3, putc_error /* spe is ready */ mov w2, w0 -- cgit v1.2.3 From ce2b1ec6f0da35e20424c0a886d3d24dfded7189 Mon Sep 17 00:00:00 2001 From: Manish Pandey Date: Tue, 14 Jan 2020 11:52:05 +0000 Subject: SPMD: generate and add Secure Partition blobs into FIP Till now TF-A allows limited number of external images to be made part of FIP. With SPM coming along, there may exist multiple SP packages which need to be inserted into FIP. To achieve this we need a more scalable approach to feed SP packages to FIP. This patch introduces changes in build system to generate and add SP packages into FIP based on information provided by platform. Platform provides information in form of JSON which contains layout description of available Secure Partitions. JSON parser script is invoked by build system early on and generates a makefile which updates FIP, SPTOOL and FDT arguments which will be used by build system later on for final packaging. "SP_LAYOUT_FILE" passed as a build argument and can be outside of TF-A tree. This option will be used only when SPD=spmd. For each SP, generated makefile will have following entries - FDT_SOURCES += sp1.dts - SPTOOL_ARGS += -i sp1.img:sp1.dtb -o sp1.pkg - FIP_ARGS += --blob uuid=XXXX-XXX...,file=SP1.pkg Signed-off-by: Manish Pandey Change-Id: Ib6a9c064400caa3cd825d9886008a3af67741af7 --- Makefile | 26 ++++++++- docs/getting_started/build-options.rst | 5 ++ tools/sptool/sp_mk_generator.py | 100 +++++++++++++++++++++++++++++++++ 3 files changed, 130 insertions(+), 1 deletion(-) create mode 100755 tools/sptool/sp_mk_generator.py diff --git a/Makefile b/Makefile index 547b5843f..11b0753c4 100644 --- a/Makefile +++ b/Makefile @@ -701,6 +701,7 @@ FIPTOOL ?= ${FIPTOOLPATH}/fiptool${BIN_EXT} # Variables for use with sptool SPTOOLPATH ?= tools/sptool SPTOOL ?= ${SPTOOLPATH}/sptool${BIN_EXT} +SP_MK_GEN ?= ${SPTOOLPATH}/sp_mk_generator.py # Variables for use with ROMLIB ROMLIBPATH ?= lib/romlib @@ -889,11 +890,22 @@ ifneq ($(findstring armlink,$(notdir $(LD))),) $(eval $(call add_define,USE_ARM_LINK)) endif +# Generate and include sp_gen.mk if SPD is spmd and SP_LAYOUT_FILE is defined +ifdef SP_LAYOUT_FILE +ifeq (${SPD},spmd) + -include $(BUILD_PLAT)/sp_gen.mk + FIP_DEPS += sp + NEED_SP_PKG := yes +else + $(error "SP_LAYOUT_FILE will be used only if SPD=spmd") +endif +endif + ################################################################################ # Build targets ################################################################################ -.PHONY: all msg_start clean realclean distclean cscope locate-checkpatch checkcodebase checkpatch fiptool sptool fip fwu_fip certtool dtbs memmap doc +.PHONY: all msg_start clean realclean distclean cscope locate-checkpatch checkcodebase checkpatch fiptool sptool fip sp fwu_fip certtool dtbs memmap doc .SUFFIXES: all: msg_start @@ -971,6 +983,17 @@ ifeq (${NEED_FDT},yes) $(eval $(call MAKE_DTBS,$(BUILD_PLAT)/fdts,$(FDT_SOURCES))) endif +# Add Secure Partition packages +ifeq (${NEED_SP_PKG},yes) +$(BUILD_PLAT)/sp_gen.mk: ${SP_MK_GEN} ${SP_LAYOUT_FILE} | ${BUILD_PLAT} + ${Q}${PYTHON} "$<" "$@" $(filter-out $<,$^) $(BUILD_PLAT) +sp: $(SPTOOL) $(DTBS) $(BUILD_PLAT)/sp_gen.mk + ${Q}$(SPTOOL) $(SPTOOL_ARGS) + @${ECHO_BLANK_LINE} + @echo "Built SP Images successfully" + @${ECHO_BLANK_LINE} +endif + locate-checkpatch: ifndef CHECKPATCH $(error "Please set CHECKPATCH to point to the Linux checkpatch.pl file, eg: CHECKPATCH=../linux/scripts/checkpatch.pl") @@ -1132,6 +1155,7 @@ help: @echo " distclean Remove all build artifacts for all platforms" @echo " certtool Build the Certificate generation tool" @echo " fiptool Build the Firmware Image Package (FIP) creation tool" + @echo " sp Build the Secure Partition Packages" @echo " sptool Build the Secure Partition Package creation tool" @echo " dtbs Build the Device Tree Blobs (if required for the platform)" @echo " memmap Print the memory map of the built binaries" diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 8854a7989..7ee34c985 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -522,6 +522,11 @@ Common build options - ``SPM_MM`` : Boolean option to enable the Management Mode (MM)-based Secure Partition Manager (SPM) implementation. The default value is ``0``. +- ``SP_LAYOUT_FILE``: Platform provided path to JSON file containing the + description of secure partitions. Build system will parse this file and + package all secure partition blobs in FIP. This file not necessarily be + part of TF-A tree. Only avaialbe when ``SPD=spmd``. + - ``SP_MIN_WITH_SECURE_FIQ``: Boolean flag to indicate the SP_MIN handles secure interrupts (caught through the FIQ line). Platforms can enable this directive if they need to handle such interruption. When enabled, diff --git a/tools/sptool/sp_mk_generator.py b/tools/sptool/sp_mk_generator.py new file mode 100755 index 000000000..6b6fa1914 --- /dev/null +++ b/tools/sptool/sp_mk_generator.py @@ -0,0 +1,100 @@ +#!/usr/bin/python3 +# Copyright (c) 2020, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause + +""" +This script is invoked by Make system and generates secure partition makefile. +It expects platform provided secure partition layout file which contains list +of Secure Partition Images and Partition manifests(PM). +Layout file can exist outside of TF-A tree and the paths of Image and PM files +must be relative to it. + +This script parses the layout file and generates a make file which updates +FDT_SOURCES, FIP_ARGS and SPTOOL_ARGS which are used in later build steps. +This script also gets SP "uuid" from parsing its PM and converting it to a +standard format. + +param1: Generated mk file "sp_gen.mk" +param2: "SP_LAYOUT_FILE", json file containing platform provided information +param3: plat out directory + +Generated "sp_gen.mk" file contains triplet of following information for each +Secure Partition entry + FDT_SOURCES += sp1.dts + SPTOOL_ARGS += -i sp1.bin:sp1.dtb -o sp1.pkg + FIP_ARGS += --blob uuid=XXXXX-XXX...,file=sp1.pkg + +A typical SP_LAYOUT_FILE file will look like +{ + "SP1" : { + "image": "sp1.bin", + "pm": "test/sp1.dts" + }, + + "SP2" : { + "image": "sp2.bin", + "pm": "test/sp2.dts" + } + + ... +} + +""" + +import getopt +import json +import os +import re +import sys +import uuid + +with open(sys.argv[2],'r') as in_file: + data = json.load(in_file) +json_file = os.path.abspath(sys.argv[2]) +json_dir = os.path.dirname(json_file) +gen_file = sys.argv[1] +out_dir = sys.argv[3][2:] +dtb_dir = out_dir + "/fdts/" +print(dtb_dir) + +with open(gen_file, 'w') as out_file: + for key in data.keys(): + + """ + Append FDT_SOURCES + """ + dts = os.path.join(json_dir, data[key]['pm']) + dtb = dtb_dir + os.path.basename(data[key]['pm'][:-1] + "b") + out_file.write("FDT_SOURCES += " + dts + "\n") + + """ + Update SPTOOL_ARGS + """ + dst = out_dir + "/" + key + ".pkg" + src = [ json_dir + "/" + data[key]['image'] , dtb ] + out_file.write("SPTOOL_ARGS += -i " + ":".join(src) + " -o " + dst + "\n") + + """ + Extract uuid from partition manifest + """ + pm_file = open(dts) + key = "uuid" + + for line in pm_file: + if key in line: + uuid_hex = re.findall(r'\<(.+?)\>', line)[0]; + + # 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) + + """ + Append FIP_ARGS + """ + out_file.write("FIP_ARGS += --blob uuid=" + uuid_std + ",file=" + dst + "\n") + out_file.write("\n") -- cgit v1.2.3 From 30f310052672d2500479989846380d050033cd44 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Tue, 28 Jan 2020 11:45:38 +0100 Subject: el3_entrypoint_common: avoid overwriting arg3 At each BL entry point, the registers r9 to r12 are used to save info from the previous BL parameters put in r0 to r3. But zeromem uses r12, leading to a corruption of arg3. Therefore this change copies r12 to r7 before zeromem() call and restores r12 afterwards. It may be better to save it in r7 in el3_arch_init_common and not at the entrypoint as r7 could be used in other functions, especially platform ones. This is a fix for Task T661. Change-Id: Icc11990c69b5d4c542d08aca1a77b1f754b61a53 Signed-off-by: Yann Gautier --- include/arch/aarch32/el3_common_macros.S | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/include/arch/aarch32/el3_common_macros.S b/include/arch/aarch32/el3_common_macros.S index 7559de446..4fd746d5a 100644 --- a/include/arch/aarch32/el3_common_macros.S +++ b/include/arch/aarch32/el3_common_macros.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -329,6 +329,11 @@ bl inv_dcache_range #endif + /* + * zeromem uses r12 whereas it is used to save previous BL arg3, + * save it in r7 + */ + mov r7, r12 ldr r0, =__BSS_START__ ldr r1, =__BSS_SIZE__ bl zeromem @@ -339,6 +344,9 @@ bl zeromem #endif + /* Restore r12 */ + mov r12, r7 + #if defined(IMAGE_BL1) || (defined(IMAGE_BL2) && BL2_AT_EL3 && BL2_IN_XIP_MEM) /* ----------------------------------------------------- * Copy data from ROM to RAM. -- cgit v1.2.3 From e9cf1bcc4544f966c979f875f539556cb70f1367 Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Mon, 12 Mar 2018 13:26:49 -0700 Subject: mt8173: Add support for new watchdog SMC This patch adds support for a new SMC that can be used to control the watchdog. This allows for a cleaner separation of responsibilities where all watchdog operations have to go through Trusted Firmware and we could no longer have kernel and firmware poking concurrently at the same register block. Signed-off-by: Julius Werner Signed-off-by: Evan Benn Change-Id: I4844a3559d5c956a53a74a61dd5bc2956f0cce7b --- plat/mediatek/mt8173/drivers/wdt/wdt.c | 115 ++++++++++++++++++++++++++ plat/mediatek/mt8173/drivers/wdt/wdt.h | 20 +++++ plat/mediatek/mt8173/include/mt8173_def.h | 12 --- plat/mediatek/mt8173/include/plat_sip_calls.h | 3 +- plat/mediatek/mt8173/plat_pm.c | 9 +- plat/mediatek/mt8173/plat_sip_calls.c | 4 + plat/mediatek/mt8173/platform.mk | 2 + 7 files changed, 147 insertions(+), 18 deletions(-) create mode 100644 plat/mediatek/mt8173/drivers/wdt/wdt.c create mode 100644 plat/mediatek/mt8173/drivers/wdt/wdt.h diff --git a/plat/mediatek/mt8173/drivers/wdt/wdt.c b/plat/mediatek/mt8173/drivers/wdt/wdt.c new file mode 100644 index 000000000..40f57eed2 --- /dev/null +++ b/plat/mediatek/mt8173/drivers/wdt/wdt.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2020, Google LLC. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include + +#define WDT_BASE (RGU_BASE + 0) +#define WDT_MODE (WDT_BASE + 0x00) +#define WDT_LENGTH (WDT_BASE + 0x04) +#define WDT_RESTART (WDT_BASE + 0x08) +#define WDT_SWRST (WDT_BASE + 0x14) + +#define WDT_MODE_DUAL_MODE 0x40 +#define WDT_MODE_IRQ 0x8 +#define WDT_MODE_KEY 0x22000000 +#define WDT_MODE_EXTEN 0x4 +#define WDT_MODE_EN 0x1 +#define WDT_LENGTH_KEY 0x8 +#define WDT_RESTART_KEY 0x1971 +#define WDT_SWRST_KEY 0x1209 + + +#define WDT_MIN_TIMEOUT 1 +#define WDT_MAX_TIMEOUT 31 + +enum smcwd_call { + SMCWD_INFO = 0, + SMCWD_SET_TIMEOUT = 1, + SMCWD_ENABLE = 2, + SMCWD_PET = 3, +}; + +static int wdt_enabled_before_suspend; + +/* + * We expect the WDT registers to be correctly initialized by BL2 firmware + * (which may be board specific), so we do not reinitialize them here. + */ + +void wdt_trigger_reset(void) +{ + mmio_write_32(WDT_SWRST, WDT_SWRST_KEY); +} + +void wdt_pet(void) +{ + mmio_write_32(WDT_RESTART, WDT_RESTART_KEY); +} + +int wdt_set_timeout(uint32_t timeout) +{ + /* One tick here equals 512 32KHz ticks. 512 / 32000 * 125 / 2 = 1 */ + uint32_t ticks = timeout * 125 / 2; + + if (timeout < WDT_MIN_TIMEOUT || timeout > WDT_MAX_TIMEOUT) + return PSCI_E_INVALID_PARAMS; + + mmio_write_32(WDT_LENGTH, ticks << 5 | WDT_LENGTH_KEY); + + return PSCI_E_SUCCESS; +} + +void wdt_set_enable(int enable) +{ + if (enable) + wdt_pet(); + mmio_clrsetbits_32(WDT_MODE, WDT_MODE_EN, + WDT_MODE_KEY | (enable ? WDT_MODE_EN : 0)); +} + +void wdt_suspend(void) +{ + wdt_enabled_before_suspend = mmio_read_32(WDT_MODE) & WDT_MODE_EN; + if (wdt_enabled_before_suspend) + wdt_set_enable(0); +} + +void wdt_resume(void) +{ + if (wdt_enabled_before_suspend) + wdt_set_enable(1); +} + +uint64_t wdt_smc_handler(uint32_t x1, + uint32_t x2, + void *handle) +{ + int ret; + + switch (x1) { + case SMCWD_INFO: + SMC_RET3(handle, PSCI_E_SUCCESS, + WDT_MIN_TIMEOUT, WDT_MAX_TIMEOUT); + case SMCWD_SET_TIMEOUT: + ret = wdt_set_timeout(x2); + SMC_RET1(handle, ret); + case SMCWD_ENABLE: + wdt_set_enable(x2 > 0); + SMC_RET1(handle, PSCI_E_SUCCESS); + case SMCWD_PET: + wdt_pet(); + SMC_RET1(handle, PSCI_E_SUCCESS); + default: + ERROR("Unimplemented SMCWD call (%d)\n", x1); + SMC_RET1(handle, PSCI_E_NOT_SUPPORTED); + } +} diff --git a/plat/mediatek/mt8173/drivers/wdt/wdt.h b/plat/mediatek/mt8173/drivers/wdt/wdt.h new file mode 100644 index 000000000..7262a5717 --- /dev/null +++ b/plat/mediatek/mt8173/drivers/wdt/wdt.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2020, Google LLC. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef WDT_H +#define WDT_H + +#include "stdint.h" + +void wdt_pet(void); +void wdt_resume(void); +void wdt_set_enable(int enable); +int wdt_set_timeout(uint32_t timeout); +uint64_t wdt_smc_handler(uint32_t x1, uint32_t x2, void *handle); +void wdt_suspend(void); +void wdt_trigger_reset(void); + +#endif /* WDT_H */ diff --git a/plat/mediatek/mt8173/include/mt8173_def.h b/plat/mediatek/mt8173/include/mt8173_def.h index 58962f03d..378b4da55 100644 --- a/plat/mediatek/mt8173/include/mt8173_def.h +++ b/plat/mediatek/mt8173/include/mt8173_def.h @@ -80,18 +80,6 @@ #define PLAT_MT_CCI_CLUSTER0_SL_IFACE_IX 4 #define PLAT_MT_CCI_CLUSTER1_SL_IFACE_IX 3 -/******************************************************************************* - * WDT related constants - ******************************************************************************/ -#define MTK_WDT_BASE (RGU_BASE + 0) -#define MTK_WDT_SWRST (MTK_WDT_BASE + 0x0014) - -#define MTK_WDT_MODE_DUAL_MODE 0x0040 -#define MTK_WDT_MODE_IRQ 0x0008 -#define MTK_WDT_MODE_KEY 0x22000000 -#define MTK_WDT_MODE_EXTEN 0x0004 -#define MTK_WDT_SWRST_KEY 0x1209 - /* FIQ platform related define */ #define MT_IRQ_SEC_SGI_0 8 #define MT_IRQ_SEC_SGI_1 9 diff --git a/plat/mediatek/mt8173/include/plat_sip_calls.h b/plat/mediatek/mt8173/include/plat_sip_calls.h index 88202cc55..ce9951a67 100644 --- a/plat/mediatek/mt8173/include/plat_sip_calls.h +++ b/plat/mediatek/mt8173/include/plat_sip_calls.h @@ -10,7 +10,7 @@ /******************************************************************************* * Plat SiP function constants ******************************************************************************/ -#define MTK_PLAT_SIP_NUM_CALLS 6 +#define MTK_PLAT_SIP_NUM_CALLS 7 #define MTK_SIP_PWR_ON_MTCMOS 0x82000402 #define MTK_SIP_PWR_OFF_MTCMOS 0x82000403 @@ -18,5 +18,6 @@ #define MTK_SIP_SET_HDCP_KEY_NUM 0x82000405 #define MTK_SIP_CLR_HDCP_KEY 0x82000406 #define MTK_SIP_SET_HDCP_KEY_EX 0x82000407 +#define MTK_SIP_SMC_WATCHDOG 0x82003D06 #endif /* PLAT_SIP_CALLS_H */ diff --git a/plat/mediatek/mt8173/plat_pm.c b/plat/mediatek/mt8173/plat_pm.c index 67f1c731b..e72a3434e 100644 --- a/plat/mediatek/mt8173/plat_pm.c +++ b/plat/mediatek/mt8173/plat_pm.c @@ -27,6 +27,7 @@ #include #include #include +#include #define MTK_PWR_LVL0 0 #define MTK_PWR_LVL1 1 @@ -350,6 +351,7 @@ static void plat_power_domain_suspend(const psci_power_state_t *state) } if (MTK_SYSTEM_PWR_STATE(state) == MTK_LOCAL_STATE_OFF) { + wdt_suspend(); disable_scu(mpidr); generic_timer_backup(); spm_system_suspend(); @@ -409,6 +411,7 @@ static void plat_power_domain_suspend_finish(const psci_power_state_t *state) plat_arm_gic_init(); spm_system_suspend_finish(); enable_scu(mpidr); + wdt_resume(); } /* Perform the common cluster specific operations */ @@ -455,11 +458,7 @@ static void __dead2 plat_system_reset(void) /* Write the System Configuration Control Register */ INFO("MTK System Reset\n"); - mmio_clrsetbits_32(MTK_WDT_BASE, - (MTK_WDT_MODE_DUAL_MODE | MTK_WDT_MODE_IRQ), - MTK_WDT_MODE_KEY); - mmio_setbits_32(MTK_WDT_BASE, (MTK_WDT_MODE_KEY | MTK_WDT_MODE_EXTEN)); - mmio_setbits_32(MTK_WDT_SWRST, MTK_WDT_SWRST_KEY); + wdt_trigger_reset(); wfi(); ERROR("MTK System Reset: operation not handled.\n"); diff --git a/plat/mediatek/mt8173/plat_sip_calls.c b/plat/mediatek/mt8173/plat_sip_calls.c index 102feb22a..da9b91dd6 100644 --- a/plat/mediatek/mt8173/plat_sip_calls.c +++ b/plat/mediatek/mt8173/plat_sip_calls.c @@ -12,6 +12,7 @@ #include #include #include +#include /* Authorized secure register list */ enum { @@ -102,6 +103,9 @@ uint64_t mediatek_plat_sip_handler(uint32_t smc_fid, ret = crypt_clear_hdcp_key(); SMC_RET1(handle, ret); + case MTK_SIP_SMC_WATCHDOG: + return wdt_smc_handler(x1, x2, handle); + default: ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid); break; diff --git a/plat/mediatek/mt8173/platform.mk b/plat/mediatek/mt8173/platform.mk index a66c49bb4..f62802cb9 100644 --- a/plat/mediatek/mt8173/platform.mk +++ b/plat/mediatek/mt8173/platform.mk @@ -15,6 +15,7 @@ PLAT_INCLUDES := -I${MTK_PLAT}/common/ \ -I${MTK_PLAT_SOC}/drivers/rtc/ \ -I${MTK_PLAT_SOC}/drivers/spm/ \ -I${MTK_PLAT_SOC}/drivers/timer/ \ + -I${MTK_PLAT_SOC}/drivers/wdt/ \ -I${MTK_PLAT_SOC}/include/ PLAT_BL_COMMON_SOURCES := lib/xlat_tables/xlat_tables_common.c \ @@ -50,6 +51,7 @@ BL31_SOURCES += common/desc_image_load.c \ ${MTK_PLAT_SOC}/drivers/spm/spm_mcdi.c \ ${MTK_PLAT_SOC}/drivers/spm/spm_suspend.c \ ${MTK_PLAT_SOC}/drivers/timer/mt_cpuxgpt.c \ + ${MTK_PLAT_SOC}/drivers/wdt/wdt.c \ ${MTK_PLAT_SOC}/plat_pm.c \ ${MTK_PLAT_SOC}/plat_sip_calls.c \ ${MTK_PLAT_SOC}/plat_topology.c \ -- cgit v1.2.3 From 5ab8b7170e2ba6649cc856778a517c0c686c653a Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Thu, 6 Feb 2020 14:59:14 +0100 Subject: Introduce a new "dualroot" chain of trust This new chain of trust defines 2 independent signing domains: 1) One for the silicon firmware (BL1, BL2, BL31) and optionally the Trusted OS. It is rooted in the Silicon ROTPK, just as in the TBBR CoT. 2) One for the Normal World Bootloader (BL33). It is rooted in a new key called Platform ROTPK, or PROTPK for short. In terms of certificates chain, - Signing domain 1) is similar to what TBBR advocates (see page 21 of the TBBR specification), except that the Non-Trusted World Public Key has been removed from the Trusted Key Certificate. - Signing domain 2) only contains the Non-Trusted World Content certificate, which provides the hash of the Non-Trusted World Bootloader. Compared to the TBBR CoT, there's no Non-Trusted World Key certificate for simplicity. Change-Id: I62f1e952522d84470acc360cf5ee63e4c4b0b4d9 Signed-off-by: Sandrine Bailleux --- drivers/auth/dualroot/cot.c | 814 +++++++++++++++++++++++++++++++++++++ include/tools_share/dualroot_oid.h | 19 + 2 files changed, 833 insertions(+) create mode 100644 drivers/auth/dualroot/cot.c create mode 100644 include/tools_share/dualroot_oid.h diff --git a/drivers/auth/dualroot/cot.c b/drivers/auth/dualroot/cot.c new file mode 100644 index 000000000..eb0b020d7 --- /dev/null +++ b/drivers/auth/dualroot/cot.c @@ -0,0 +1,814 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include + +#include +#include +#include + +/* + * TODO: Remove dependency on mbedTLS. The chain of trust should be agnostic of + * the specific cryptographic library in use. +*/ +/* + * Maximum key and hash sizes (in DER format). + * + * Both RSA and ECDSA keys may be used at the same time. In this case, the key + * buffers must be big enough to hold either. As RSA keys are bigger than ECDSA + * ones for all key sizes we support, they impose the minimum size of these + * buffers. + */ +#if TF_MBEDTLS_USE_RSA +#if TF_MBEDTLS_KEY_SIZE == 1024 +#define PK_DER_LEN 162 +#elif TF_MBEDTLS_KEY_SIZE == 2048 +#define PK_DER_LEN 294 +#elif TF_MBEDTLS_KEY_SIZE == 3072 +#define PK_DER_LEN 422 +#elif TF_MBEDTLS_KEY_SIZE == 4096 +#define PK_DER_LEN 550 +#else +#error "Invalid value for TF_MBEDTLS_KEY_SIZE" +#endif +#else /* Only using ECDSA keys. */ +#define PK_DER_LEN 91 +#endif + +#if TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA256 +#define HASH_DER_LEN 51 +#elif TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA384 +#define HASH_DER_LEN 67 +#elif TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA512 +#define HASH_DER_LEN 83 +#else +#error "Invalid value for TF_MBEDTLS_HASH_ALG_ID" +#endif + +/* + * Allocate static buffers to store the authentication parameters extracted from + * the certificates. + */ +static unsigned char tb_fw_hash_buf[HASH_DER_LEN]; +static unsigned char tb_fw_config_hash_buf[HASH_DER_LEN]; +static unsigned char hw_config_hash_buf[HASH_DER_LEN]; +static unsigned char scp_fw_hash_buf[HASH_DER_LEN]; +static unsigned char nt_world_bl_hash_buf[HASH_DER_LEN]; + +#ifdef IMAGE_BL2 +static unsigned char soc_fw_hash_buf[HASH_DER_LEN]; +static unsigned char tos_fw_hash_buf[HASH_DER_LEN]; +static unsigned char tos_fw_extra1_hash_buf[HASH_DER_LEN]; +static unsigned char tos_fw_extra2_hash_buf[HASH_DER_LEN]; +static unsigned char soc_fw_config_hash_buf[HASH_DER_LEN]; +static unsigned char tos_fw_config_hash_buf[HASH_DER_LEN]; +static unsigned char nt_fw_config_hash_buf[HASH_DER_LEN]; + +static unsigned char trusted_world_pk_buf[PK_DER_LEN]; +static unsigned char content_pk_buf[PK_DER_LEN]; +#endif + +/* + * Parameter type descriptors. + */ +static auth_param_type_desc_t trusted_nv_ctr = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_NV_CTR, TRUSTED_FW_NVCOUNTER_OID); +static auth_param_type_desc_t subject_pk = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_PUB_KEY, 0); +static auth_param_type_desc_t sig = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_SIG, 0); +static auth_param_type_desc_t sig_alg = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_SIG_ALG, 0); +static auth_param_type_desc_t raw_data = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_RAW_DATA, 0); + +static auth_param_type_desc_t tb_fw_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, TRUSTED_BOOT_FW_HASH_OID); +static auth_param_type_desc_t tb_fw_config_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, TRUSTED_BOOT_FW_CONFIG_HASH_OID); +static auth_param_type_desc_t hw_config_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, HW_CONFIG_HASH_OID); +#ifdef IMAGE_BL1 +static auth_param_type_desc_t scp_bl2u_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SCP_FWU_CFG_HASH_OID); +static auth_param_type_desc_t bl2u_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, AP_FWU_CFG_HASH_OID); +static auth_param_type_desc_t ns_bl2u_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, FWU_HASH_OID); +#endif /* IMAGE_BL1 */ + +#ifdef IMAGE_BL2 +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 scp_fw_content_pk = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_PUB_KEY, SCP_FW_CONTENT_CERT_PK_OID); +static auth_param_type_desc_t soc_fw_content_pk = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_PUB_KEY, SOC_FW_CONTENT_CERT_PK_OID); +static auth_param_type_desc_t tos_fw_content_pk = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_PUB_KEY, TRUSTED_OS_FW_CONTENT_CERT_PK_OID); +static auth_param_type_desc_t prot_pk = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_PUB_KEY, PROT_PK_OID); + +static auth_param_type_desc_t scp_fw_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SCP_FW_HASH_OID); +static auth_param_type_desc_t soc_fw_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SOC_AP_FW_HASH_OID); +static auth_param_type_desc_t soc_fw_config_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SOC_FW_CONFIG_HASH_OID); +static auth_param_type_desc_t tos_fw_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, TRUSTED_OS_FW_HASH_OID); +static auth_param_type_desc_t tos_fw_config_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, TRUSTED_OS_FW_CONFIG_HASH_OID); +static auth_param_type_desc_t tos_fw_extra1_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, TRUSTED_OS_FW_EXTRA1_HASH_OID); +static auth_param_type_desc_t tos_fw_extra2_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, TRUSTED_OS_FW_EXTRA2_HASH_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); +#endif /* IMAGE_BL2 */ + + +/* BL2 */ +static const auth_img_desc_t trusted_boot_fw_cert = { + .img_id = TRUSTED_BOOT_FW_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 = &tb_fw_hash, + .data = { + .ptr = (void *)tb_fw_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [1] = { + .type_desc = &tb_fw_config_hash, + .data = { + .ptr = (void *)tb_fw_config_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [2] = { + .type_desc = &hw_config_hash, + .data = { + .ptr = (void *)hw_config_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + } + } +}; + +#ifdef IMAGE_BL1 +static const auth_img_desc_t bl2_image = { + .img_id = BL2_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &trusted_boot_fw_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &tb_fw_hash + } + } + } +}; +#endif /* IMAGE_BL1 */ + +/* HW Config */ +static const auth_img_desc_t hw_config = { + .img_id = HW_CONFIG_ID, + .img_type = IMG_RAW, + .parent = &trusted_boot_fw_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &hw_config_hash + } + } + } +}; + +/* TB FW Config */ +#ifdef IMAGE_BL1 +static const auth_img_desc_t tb_fw_config = { + .img_id = TB_FW_CONFIG_ID, + .img_type = IMG_RAW, + .parent = &trusted_boot_fw_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &tb_fw_config_hash + } + } + } +}; +#endif /* IMAGE_BL1 */ + +#ifdef IMAGE_BL2 +/* 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 + } + }, + } +}; + +/* SCP Firmware */ +static const auth_img_desc_t scp_fw_key_cert = { + .img_id = SCP_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 = &trusted_world_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 = &scp_fw_content_pk, + .data = { + .ptr = (void *)content_pk_buf, + .len = (unsigned int)PK_DER_LEN + } + } + } +}; + +static const auth_img_desc_t scp_fw_content_cert = { + .img_id = SCP_FW_CONTENT_CERT_ID, + .img_type = IMG_CERT, + .parent = &scp_fw_key_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &scp_fw_content_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 = &scp_fw_hash, + .data = { + .ptr = (void *)scp_fw_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + } + } +}; + +static const auth_img_desc_t scp_bl2_image = { + .img_id = SCP_BL2_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &scp_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 = &scp_fw_hash + } + } + } +}; + +/* SoC Firmware */ +static const auth_img_desc_t soc_fw_key_cert = { + .img_id = SOC_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 = &trusted_world_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 = &soc_fw_content_pk, + .data = { + .ptr = (void *)content_pk_buf, + .len = (unsigned int)PK_DER_LEN + } + } + } +}; + +static const auth_img_desc_t soc_fw_content_cert = { + .img_id = SOC_FW_CONTENT_CERT_ID, + .img_type = IMG_CERT, + .parent = &soc_fw_key_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &soc_fw_content_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 = &soc_fw_hash, + .data = { + .ptr = (void *)soc_fw_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [1] = { + .type_desc = &soc_fw_config_hash, + .data = { + .ptr = (void *)soc_fw_config_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + } + } +}; + +static const auth_img_desc_t bl31_image = { + .img_id = BL31_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &soc_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 = &soc_fw_hash + } + } + } +}; + +/* SOC FW Config */ +static const auth_img_desc_t soc_fw_config = { + .img_id = SOC_FW_CONFIG_ID, + .img_type = IMG_RAW, + .parent = &soc_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 = &soc_fw_config_hash + } + } + } +}; + +/* Trusted OS Firmware */ +static const auth_img_desc_t trusted_os_fw_key_cert = { + .img_id = TRUSTED_OS_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 = &trusted_world_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 = &tos_fw_content_pk, + .data = { + .ptr = (void *)content_pk_buf, + .len = (unsigned int)PK_DER_LEN + } + } + } +}; + +static const auth_img_desc_t trusted_os_fw_content_cert = { + .img_id = TRUSTED_OS_FW_CONTENT_CERT_ID, + .img_type = IMG_CERT, + .parent = &trusted_os_fw_key_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &tos_fw_content_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 = &tos_fw_hash, + .data = { + .ptr = (void *)tos_fw_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [1] = { + .type_desc = &tos_fw_extra1_hash, + .data = { + .ptr = (void *)tos_fw_extra1_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [2] = { + .type_desc = &tos_fw_extra2_hash, + .data = { + .ptr = (void *)tos_fw_extra2_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [3] = { + .type_desc = &tos_fw_config_hash, + .data = { + .ptr = (void *)tos_fw_config_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + } + } +}; + +static const auth_img_desc_t bl32_image = { + .img_id = BL32_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &trusted_os_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 = &tos_fw_hash + } + } + } +}; + +static const auth_img_desc_t bl32_extra1_image = { + .img_id = BL32_EXTRA1_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &trusted_os_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 = &tos_fw_extra1_hash + } + } + } +}; + +static const auth_img_desc_t bl32_extra2_image = { + .img_id = BL32_EXTRA2_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &trusted_os_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 = &tos_fw_extra2_hash + } + } + } +}; + +/* TOS FW Config */ +static const auth_img_desc_t tos_fw_config = { + .img_id = TOS_FW_CONFIG_ID, + .img_type = IMG_RAW, + .parent = &trusted_os_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 = &tos_fw_config_hash + } + } + } +}; + +/* Non-Trusted Firmware */ +static const auth_img_desc_t non_trusted_fw_content_cert = { + .img_id = NON_TRUSTED_FW_CONTENT_CERT_ID, + .img_type = IMG_CERT, + .parent = NULL, /* Root certificate. */ + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &prot_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 + } + } + } +}; + +/* NT FW Config */ +static const auth_img_desc_t nt_fw_config = { + .img_id = NT_FW_CONFIG_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_fw_config_hash + } + } + } +}; + +#else /* IMAGE_BL2 */ + +/* FWU auth descriptor */ +static const auth_img_desc_t fwu_cert = { + .img_id = FWU_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 + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &scp_bl2u_hash, + .data = { + .ptr = (void *)scp_fw_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [1] = { + .type_desc = &bl2u_hash, + .data = { + .ptr = (void *)tb_fw_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [2] = { + .type_desc = &ns_bl2u_hash, + .data = { + .ptr = (void *)nt_world_bl_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + } + } +}; + +/* SCP_BL2U */ +static const auth_img_desc_t scp_bl2u_image = { + .img_id = SCP_BL2U_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &fwu_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &scp_bl2u_hash + } + } + } +}; + +/* BL2U */ +static const auth_img_desc_t bl2u_image = { + .img_id = BL2U_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &fwu_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &bl2u_hash + } + } + } +}; + +/* NS_BL2U */ +static const auth_img_desc_t ns_bl2u_image = { + .img_id = NS_BL2U_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &fwu_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &ns_bl2u_hash + } + } + } +}; +#endif /* IMAGE_BL2 */ + +/* + * Chain of trust definition + */ +#ifdef IMAGE_BL1 +static const auth_img_desc_t * const cot_desc[] = { + [TRUSTED_BOOT_FW_CERT_ID] = &trusted_boot_fw_cert, + [BL2_IMAGE_ID] = &bl2_image, + [HW_CONFIG_ID] = &hw_config, + [TB_FW_CONFIG_ID] = &tb_fw_config, + [FWU_CERT_ID] = &fwu_cert, + [SCP_BL2U_IMAGE_ID] = &scp_bl2u_image, + [BL2U_IMAGE_ID] = &bl2u_image, + [NS_BL2U_IMAGE_ID] = &ns_bl2u_image +}; +#else /* IMAGE_BL2 */ +static const auth_img_desc_t * const cot_desc[] = { + [TRUSTED_BOOT_FW_CERT_ID] = &trusted_boot_fw_cert, + [HW_CONFIG_ID] = &hw_config, + [TRUSTED_KEY_CERT_ID] = &trusted_key_cert, + [SCP_FW_KEY_CERT_ID] = &scp_fw_key_cert, + [SCP_FW_CONTENT_CERT_ID] = &scp_fw_content_cert, + [SCP_BL2_IMAGE_ID] = &scp_bl2_image, + [SOC_FW_KEY_CERT_ID] = &soc_fw_key_cert, + [SOC_FW_CONTENT_CERT_ID] = &soc_fw_content_cert, + [BL31_IMAGE_ID] = &bl31_image, + [SOC_FW_CONFIG_ID] = &soc_fw_config, + [TRUSTED_OS_FW_KEY_CERT_ID] = &trusted_os_fw_key_cert, + [TRUSTED_OS_FW_CONTENT_CERT_ID] = &trusted_os_fw_content_cert, + [BL32_IMAGE_ID] = &bl32_image, + [BL32_EXTRA1_IMAGE_ID] = &bl32_extra1_image, + [BL32_EXTRA2_IMAGE_ID] = &bl32_extra2_image, + [TOS_FW_CONFIG_ID] = &tos_fw_config, + [NON_TRUSTED_FW_CONTENT_CERT_ID] = &non_trusted_fw_content_cert, + [BL33_IMAGE_ID] = &bl33_image, + [NT_FW_CONFIG_ID] = &nt_fw_config, +}; +#endif + +/* Register the CoT in the authentication module */ +REGISTER_COT(cot_desc); diff --git a/include/tools_share/dualroot_oid.h b/include/tools_share/dualroot_oid.h new file mode 100644 index 000000000..3e88a6d22 --- /dev/null +++ b/include/tools_share/dualroot_oid.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef DUALROOT_OID_H +#define DUALROOT_OID_H + +/* Reuse the Object IDs defined by TBBR for certificate extensions. */ +#include "tbbr_oid.h" + +/* + * Platform root-of-trust public key. + * Arbitrary value that does not conflict with any of the TBBR reserved OIDs. + */ +#define PROT_PK_OID "1.3.6.1.4.1.4128.2100.1102" + +#endif /* DUALROOT_OID_H */ -- cgit v1.2.3 From a9d5c273c17662bc1b43eafb5a24bb93377c16ae Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Fri, 10 Jan 2020 14:32:30 +0100 Subject: cert_create: Define the dualroot CoT Selection of the chain of trust is done through the COT build option: > make COT=dualroot Change-Id: Id87c7a5116bdd13bdb29645ecf31d111ad094c1e Signed-off-by: Sandrine Bailleux --- tools/cert_create/Makefile | 2 + tools/cert_create/include/dualroot/cot.h | 70 +++++ tools/cert_create/src/dualroot/cot.c | 453 +++++++++++++++++++++++++++++++ tools/cert_create/src/dualroot/cot.mk | 10 + 4 files changed, 535 insertions(+) create mode 100644 tools/cert_create/include/dualroot/cot.h create mode 100644 tools/cert_create/src/dualroot/cot.c create mode 100644 tools/cert_create/src/dualroot/cot.mk diff --git a/tools/cert_create/Makefile b/tools/cert_create/Makefile index eff929ef0..19f736f07 100644 --- a/tools/cert_create/Makefile +++ b/tools/cert_create/Makefile @@ -27,6 +27,8 @@ OBJECTS := src/cert.o \ # Chain of trust. ifeq (${COT},tbbr) include src/tbbr/tbbr.mk +else ifeq (${COT},dualroot) + include src/dualroot/cot.mk else $(error Unknown chain of trust ${COT}) endif diff --git a/tools/cert_create/include/dualroot/cot.h b/tools/cert_create/include/dualroot/cot.h new file mode 100644 index 000000000..570120682 --- /dev/null +++ b/tools/cert_create/include/dualroot/cot.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef DUALROOT_COT_H +#define DUALROOT_COT_H + +/* Certificates. */ +enum { + /* Certificates owned by the silicon provider. */ + TRUSTED_BOOT_FW_CERT, + TRUSTED_KEY_CERT, + SCP_FW_KEY_CERT, + SCP_FW_CONTENT_CERT, + SOC_FW_KEY_CERT, + SOC_FW_CONTENT_CERT, + TRUSTED_OS_FW_KEY_CERT, + TRUSTED_OS_FW_CONTENT_CERT, + FWU_CERT, + + /* Certificates owned by the platform owner. */ + NON_TRUSTED_FW_CONTENT_CERT, +}; + +/* Certificate extensions. */ +enum { + /* Extensions used in certificates owned by the silicon provider. */ + TRUSTED_FW_NVCOUNTER_EXT, + TRUSTED_BOOT_FW_HASH_EXT, + TRUSTED_BOOT_FW_CONFIG_HASH_EXT, + HW_CONFIG_HASH_EXT, + TRUSTED_WORLD_PK_EXT, + SCP_FW_CONTENT_CERT_PK_EXT, + SCP_FW_HASH_EXT, + SOC_FW_CONTENT_CERT_PK_EXT, + SOC_AP_FW_HASH_EXT, + SOC_FW_CONFIG_HASH_EXT, + TRUSTED_OS_FW_CONTENT_CERT_PK_EXT, + TRUSTED_OS_FW_HASH_EXT, + TRUSTED_OS_FW_EXTRA1_HASH_EXT, + TRUSTED_OS_FW_EXTRA2_HASH_EXT, + TRUSTED_OS_FW_CONFIG_HASH_EXT, + SCP_FWU_CFG_HASH_EXT, + AP_FWU_CFG_HASH_EXT, + FWU_HASH_EXT, + + /* Extensions used in certificates owned by the platform owner. */ + PROT_PK_EXT, + NON_TRUSTED_FW_NVCOUNTER_EXT, + NON_TRUSTED_FW_CONTENT_CERT_PK_EXT, + NON_TRUSTED_WORLD_BOOTLOADER_HASH_EXT, + NON_TRUSTED_FW_CONFIG_HASH_EXT, +}; + +/* Keys. */ +enum { + /* Keys owned by the silicon provider. */ + ROT_KEY, + TRUSTED_WORLD_KEY, + SCP_FW_CONTENT_CERT_KEY, + SOC_FW_CONTENT_CERT_KEY, + TRUSTED_OS_FW_CONTENT_CERT_KEY, + + /* Keys owned by the platform owner. */ + PROT_KEY, +}; + +#endif /* DUALROOT_COT_H */ diff --git a/tools/cert_create/src/dualroot/cot.c b/tools/cert_create/src/dualroot/cot.c new file mode 100644 index 000000000..8117ffc16 --- /dev/null +++ b/tools/cert_create/src/dualroot/cot.c @@ -0,0 +1,453 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include "cert.h" +#include "ext.h" +#include "key.h" + +#include "dualroot/cot.h" + +/* + * Certificates used in the chain of trust. + * + * All certificates are self-signed so the issuer certificate field points to + * itself. + */ +static cert_t cot_certs[] = { + [TRUSTED_BOOT_FW_CERT] = { + .id = TRUSTED_BOOT_FW_CERT, + .opt = "tb-fw-cert", + .help_msg = "Trusted Boot FW Certificate (output file)", + .cn = "Trusted Boot FW Certificate", + .key = ROT_KEY, + .issuer = TRUSTED_BOOT_FW_CERT, + .ext = { + TRUSTED_FW_NVCOUNTER_EXT, + TRUSTED_BOOT_FW_HASH_EXT, + TRUSTED_BOOT_FW_CONFIG_HASH_EXT, + HW_CONFIG_HASH_EXT + }, + .num_ext = 4 + }, + + [TRUSTED_KEY_CERT] = { + .id = TRUSTED_KEY_CERT, + .opt = "trusted-key-cert", + .help_msg = "Trusted Key Certificate (output file)", + .cn = "Trusted Key Certificate", + .key = ROT_KEY, + .issuer = TRUSTED_KEY_CERT, + .ext = { + TRUSTED_FW_NVCOUNTER_EXT, + TRUSTED_WORLD_PK_EXT, + }, + .num_ext = 2 + }, + + [SCP_FW_KEY_CERT] = { + .id = SCP_FW_KEY_CERT, + .opt = "scp-fw-key-cert", + .help_msg = "SCP Firmware Key Certificate (output file)", + .cn = "SCP Firmware Key Certificate", + .key = TRUSTED_WORLD_KEY, + .issuer = SCP_FW_KEY_CERT, + .ext = { + TRUSTED_FW_NVCOUNTER_EXT, + SCP_FW_CONTENT_CERT_PK_EXT + }, + .num_ext = 2 + }, + + [SCP_FW_CONTENT_CERT] = { + .id = SCP_FW_CONTENT_CERT, + .opt = "scp-fw-cert", + .help_msg = "SCP Firmware Content Certificate (output file)", + .cn = "SCP Firmware Content Certificate", + .key = SCP_FW_CONTENT_CERT_KEY, + .issuer = SCP_FW_CONTENT_CERT, + .ext = { + TRUSTED_FW_NVCOUNTER_EXT, + SCP_FW_HASH_EXT + }, + .num_ext = 2 + }, + + [SOC_FW_KEY_CERT] = { + .id = SOC_FW_KEY_CERT, + .opt = "soc-fw-key-cert", + .help_msg = "SoC Firmware Key Certificate (output file)", + .cn = "SoC Firmware Key Certificate", + .key = TRUSTED_WORLD_KEY, + .issuer = SOC_FW_KEY_CERT, + .ext = { + TRUSTED_FW_NVCOUNTER_EXT, + SOC_FW_CONTENT_CERT_PK_EXT + }, + .num_ext = 2 + }, + + [SOC_FW_CONTENT_CERT] = { + .id = SOC_FW_CONTENT_CERT, + .opt = "soc-fw-cert", + .help_msg = "SoC Firmware Content Certificate (output file)", + .cn = "SoC Firmware Content Certificate", + .key = SOC_FW_CONTENT_CERT_KEY, + .issuer = SOC_FW_CONTENT_CERT, + .ext = { + TRUSTED_FW_NVCOUNTER_EXT, + SOC_AP_FW_HASH_EXT, + SOC_FW_CONFIG_HASH_EXT, + }, + .num_ext = 3 + }, + + [TRUSTED_OS_FW_KEY_CERT] = { + .id = TRUSTED_OS_FW_KEY_CERT, + .opt = "tos-fw-key-cert", + .help_msg = "Trusted OS Firmware Key Certificate (output file)", + .cn = "Trusted OS Firmware Key Certificate", + .key = TRUSTED_WORLD_KEY, + .issuer = TRUSTED_OS_FW_KEY_CERT, + .ext = { + TRUSTED_FW_NVCOUNTER_EXT, + TRUSTED_OS_FW_CONTENT_CERT_PK_EXT + }, + .num_ext = 2 + }, + + [TRUSTED_OS_FW_CONTENT_CERT] = { + .id = TRUSTED_OS_FW_CONTENT_CERT, + .opt = "tos-fw-cert", + .help_msg = "Trusted OS Firmware Content Certificate (output file)", + .cn = "Trusted OS Firmware Content Certificate", + .key = TRUSTED_OS_FW_CONTENT_CERT_KEY, + .issuer = TRUSTED_OS_FW_CONTENT_CERT, + .ext = { + TRUSTED_FW_NVCOUNTER_EXT, + TRUSTED_OS_FW_HASH_EXT, + TRUSTED_OS_FW_EXTRA1_HASH_EXT, + TRUSTED_OS_FW_EXTRA2_HASH_EXT, + TRUSTED_OS_FW_CONFIG_HASH_EXT, + }, + .num_ext = 5 + }, + + [FWU_CERT] = { + .id = FWU_CERT, + .opt = "fwu-cert", + .help_msg = "Firmware Update Certificate (output file)", + .cn = "Firmware Update Certificate", + .key = ROT_KEY, + .issuer = FWU_CERT, + .ext = { + SCP_FWU_CFG_HASH_EXT, + AP_FWU_CFG_HASH_EXT, + FWU_HASH_EXT + }, + .num_ext = 3 + }, + + [NON_TRUSTED_FW_CONTENT_CERT] = { + .id = NON_TRUSTED_FW_CONTENT_CERT, + .opt = "nt-fw-cert", + .help_msg = "Non-Trusted Firmware Content Certificate (output file)", + .cn = "Non-Trusted Firmware Content Certificate", + .key = PROT_KEY, + .issuer = NON_TRUSTED_FW_CONTENT_CERT, + .ext = { + NON_TRUSTED_FW_NVCOUNTER_EXT, + NON_TRUSTED_WORLD_BOOTLOADER_HASH_EXT, + NON_TRUSTED_FW_CONFIG_HASH_EXT, + PROT_PK_EXT, + }, + .num_ext = 4 + }, +}; + +REGISTER_COT(cot_certs); + + +/* Certificate extensions. */ +static ext_t cot_ext[] = { + [TRUSTED_FW_NVCOUNTER_EXT] = { + .oid = TRUSTED_FW_NVCOUNTER_OID, + .opt = "tfw-nvctr", + .help_msg = "Trusted Firmware Non-Volatile counter value", + .sn = "TrustedWorldNVCounter", + .ln = "Trusted World Non-Volatile counter", + .asn1_type = V_ASN1_INTEGER, + .type = EXT_TYPE_NVCOUNTER, + .attr.nvctr_type = NVCTR_TYPE_TFW + }, + + [TRUSTED_BOOT_FW_HASH_EXT] = { + .oid = TRUSTED_BOOT_FW_HASH_OID, + .opt = "tb-fw", + .help_msg = "Trusted Boot Firmware image file", + .sn = "TrustedBootFirmwareHash", + .ln = "Trusted Boot Firmware hash (SHA256)", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_HASH + }, + + [TRUSTED_BOOT_FW_CONFIG_HASH_EXT] = { + .oid = TRUSTED_BOOT_FW_CONFIG_HASH_OID, + .opt = "tb-fw-config", + .help_msg = "Trusted Boot Firmware Config file", + .sn = "TrustedBootFirmwareConfigHash", + .ln = "Trusted Boot Firmware Config hash", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_HASH, + .optional = 1 + }, + + [HW_CONFIG_HASH_EXT] = { + .oid = HW_CONFIG_HASH_OID, + .opt = "hw-config", + .help_msg = "HW Config file", + .sn = "HWConfigHash", + .ln = "HW Config hash", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_HASH, + .optional = 1 + }, + + [TRUSTED_WORLD_PK_EXT] = { + .oid = TRUSTED_WORLD_PK_OID, + .sn = "TrustedWorldPublicKey", + .ln = "Trusted World Public Key", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_PKEY, + .attr.key = TRUSTED_WORLD_KEY + }, + + [SCP_FW_CONTENT_CERT_PK_EXT] = { + .oid = SCP_FW_CONTENT_CERT_PK_OID, + .sn = "SCPFirmwareContentCertPK", + .ln = "SCP Firmware content certificate public key", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_PKEY, + .attr.key = SCP_FW_CONTENT_CERT_KEY + }, + + [SCP_FW_HASH_EXT] = { + .oid = SCP_FW_HASH_OID, + .opt = "scp-fw", + .help_msg = "SCP Firmware image file", + .sn = "SCPFirmwareHash", + .ln = "SCP Firmware hash (SHA256)", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_HASH + }, + + [SOC_FW_CONTENT_CERT_PK_EXT] = { + .oid = SOC_FW_CONTENT_CERT_PK_OID, + .sn = "SoCFirmwareContentCertPK", + .ln = "SoC Firmware content certificate public key", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_PKEY, + .attr.key = SOC_FW_CONTENT_CERT_KEY + }, + + [SOC_AP_FW_HASH_EXT] = { + .oid = SOC_AP_FW_HASH_OID, + .opt = "soc-fw", + .help_msg = "SoC AP Firmware image file", + .sn = "SoCAPFirmwareHash", + .ln = "SoC AP Firmware hash (SHA256)", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_HASH + }, + + [SOC_FW_CONFIG_HASH_EXT] = { + .oid = SOC_FW_CONFIG_HASH_OID, + .opt = "soc-fw-config", + .help_msg = "SoC Firmware Config file", + .sn = "SocFirmwareConfigHash", + .ln = "SoC Firmware Config hash", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_HASH, + .optional = 1 + }, + + [TRUSTED_OS_FW_CONTENT_CERT_PK_EXT] = { + .oid = TRUSTED_OS_FW_CONTENT_CERT_PK_OID, + .sn = "TrustedOSFirmwareContentCertPK", + .ln = "Trusted OS Firmware content certificate public key", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_PKEY, + .attr.key = TRUSTED_OS_FW_CONTENT_CERT_KEY + }, + + [TRUSTED_OS_FW_HASH_EXT] = { + .oid = TRUSTED_OS_FW_HASH_OID, + .opt = "tos-fw", + .help_msg = "Trusted OS image file", + .sn = "TrustedOSHash", + .ln = "Trusted OS hash (SHA256)", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_HASH + }, + + [TRUSTED_OS_FW_EXTRA1_HASH_EXT] = { + .oid = TRUSTED_OS_FW_EXTRA1_HASH_OID, + .opt = "tos-fw-extra1", + .help_msg = "Trusted OS Extra1 image file", + .sn = "TrustedOSExtra1Hash", + .ln = "Trusted OS Extra1 hash (SHA256)", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_HASH, + .optional = 1 + }, + + [TRUSTED_OS_FW_EXTRA2_HASH_EXT] = { + .oid = TRUSTED_OS_FW_EXTRA2_HASH_OID, + .opt = "tos-fw-extra2", + .help_msg = "Trusted OS Extra2 image file", + .sn = "TrustedOSExtra2Hash", + .ln = "Trusted OS Extra2 hash (SHA256)", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_HASH, + .optional = 1 + }, + + [TRUSTED_OS_FW_CONFIG_HASH_EXT] = { + .oid = TRUSTED_OS_FW_CONFIG_HASH_OID, + .opt = "tos-fw-config", + .help_msg = "Trusted OS Firmware Config file", + .sn = "TrustedOSFirmwareConfigHash", + .ln = "Trusted OS Firmware Config hash", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_HASH, + .optional = 1 + }, + + [SCP_FWU_CFG_HASH_EXT] = { + .oid = SCP_FWU_CFG_HASH_OID, + .opt = "scp-fwu-cfg", + .help_msg = "SCP Firmware Update Config image file", + .sn = "SCPFWUpdateConfig", + .ln = "SCP Firmware Update Config hash (SHA256)", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_HASH, + .optional = 1 + }, + + [AP_FWU_CFG_HASH_EXT] = { + .oid = AP_FWU_CFG_HASH_OID, + .opt = "ap-fwu-cfg", + .help_msg = "AP Firmware Update Config image file", + .sn = "APFWUpdateConfig", + .ln = "AP Firmware Update Config hash (SHA256)", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_HASH, + .optional = 1 + }, + + [FWU_HASH_EXT] = { + .oid = FWU_HASH_OID, + .opt = "fwu", + .help_msg = "Firmware Updater image file", + .sn = "FWUpdaterHash", + .ln = "Firmware Updater hash (SHA256)", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_HASH, + .optional = 1 + }, + + [PROT_PK_EXT] = { + .oid = PROT_PK_OID, + .sn = "PlatformRoTKey", + .ln = "Platform Root of Trust Public Key", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_PKEY, + .attr.key = PROT_KEY + }, + + [NON_TRUSTED_FW_NVCOUNTER_EXT] = { + .oid = NON_TRUSTED_FW_NVCOUNTER_OID, + .opt = "ntfw-nvctr", + .help_msg = "Non-Trusted Firmware Non-Volatile counter value", + .sn = "NormalWorldNVCounter", + .ln = "Non-Trusted Firmware Non-Volatile counter", + .asn1_type = V_ASN1_INTEGER, + .type = EXT_TYPE_NVCOUNTER, + .attr.nvctr_type = NVCTR_TYPE_NTFW + }, + + [NON_TRUSTED_WORLD_BOOTLOADER_HASH_EXT] = { + .oid = NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID, + .opt = "nt-fw", + .help_msg = "Non-Trusted World Bootloader image file", + .sn = "NonTrustedWorldBootloaderHash", + .ln = "Non-Trusted World hash (SHA256)", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_HASH + }, + + [NON_TRUSTED_FW_CONFIG_HASH_EXT] = { + .oid = NON_TRUSTED_FW_CONFIG_HASH_OID, + .opt = "nt-fw-config", + .help_msg = "Non Trusted OS Firmware Config file", + .sn = "NonTrustedOSFirmwareConfigHash", + .ln = "Non-Trusted OS Firmware Config hash", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_HASH, + .optional = 1 + }, +}; + +REGISTER_EXTENSIONS(cot_ext); + + +/* Keys used to establish the chain of trust. */ +static key_t cot_keys[] = { + [ROT_KEY] = { + .id = ROT_KEY, + .opt = "rot-key", + .help_msg = "Root Of Trust key (input/output file)", + .desc = "Root Of Trust key" + }, + + [TRUSTED_WORLD_KEY] = { + .id = TRUSTED_WORLD_KEY, + .opt = "trusted-world-key", + .help_msg = "Trusted World key (input/output file)", + .desc = "Trusted World key" + }, + + [SCP_FW_CONTENT_CERT_KEY] = { + .id = SCP_FW_CONTENT_CERT_KEY, + .opt = "scp-fw-key", + .help_msg = "SCP Firmware Content Certificate key (input/output file)", + .desc = "SCP Firmware Content Certificate key" + }, + + [SOC_FW_CONTENT_CERT_KEY] = { + .id = SOC_FW_CONTENT_CERT_KEY, + .opt = "soc-fw-key", + .help_msg = "SoC Firmware Content Certificate key (input/output file)", + .desc = "SoC Firmware Content Certificate key" + }, + + [TRUSTED_OS_FW_CONTENT_CERT_KEY] = { + .id = TRUSTED_OS_FW_CONTENT_CERT_KEY, + .opt = "tos-fw-key", + .help_msg = "Trusted OS Firmware Content Certificate key (input/output file)", + .desc = "Trusted OS Firmware Content Certificate key" + }, + + [PROT_KEY] = { + .id = PROT_KEY, + .opt = "prot-key", + .help_msg = "Platform Root of Trust key", + .desc = "Platform Root of Trust key" + }, +}; + +REGISTER_KEYS(cot_keys); diff --git a/tools/cert_create/src/dualroot/cot.mk b/tools/cert_create/src/dualroot/cot.mk new file mode 100644 index 000000000..a572484d7 --- /dev/null +++ b/tools/cert_create/src/dualroot/cot.mk @@ -0,0 +1,10 @@ +# +# Copyright (c) 2020, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +PLAT_MSG := Dual root of trust +PLAT_INCLUDE := ../../include/tools_share + +OBJECTS += src/dualroot/cot.o -- cgit v1.2.3 From 53b985a0d1f688e9b9815717e7c591c7ec254d69 Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Mon, 3 Feb 2020 14:57:53 +0100 Subject: Build system: Changes to drive cert_create for dualroot CoT The build system needs to drive the cert_create tool in a slightly different manner when using the dualroot chain of trust. - It needs to pass it the platform root of trust key file. - It must not try to generate the Non-Trusted Firmware Key Certificate, which is not part of the dualroot CoT. Change-Id: Ibcc821c5735765523730f861ae8230208f41302b Signed-off-by: Sandrine Bailleux --- make_helpers/tbbr/tbbr_tools.mk | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/make_helpers/tbbr/tbbr_tools.mk b/make_helpers/tbbr/tbbr_tools.mk index 9c47cc7c4..f0adfe1ce 100644 --- a/make_helpers/tbbr/tbbr_tools.mk +++ b/make_helpers/tbbr/tbbr_tools.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -23,6 +23,7 @@ # KEY_ALG # KEY_SIZE # ROT_KEY +# PROT_KEY # TRUSTED_WORLD_KEY # NON_TRUSTED_WORLD_KEY # SCP_BL2_KEY @@ -57,6 +58,7 @@ $(if ${KEY_SIZE},$(eval $(call CERT_ADD_CMD_OPT,${KEY_SIZE},--key-size))) $(if ${HASH_ALG},$(eval $(call CERT_ADD_CMD_OPT,${HASH_ALG},--hash-alg))) $(if ${ROT_KEY},$(eval $(call CERT_ADD_CMD_OPT,${ROT_KEY},--rot-key))) $(if ${ROT_KEY},$(eval $(call CERT_ADD_CMD_OPT,${ROT_KEY},--rot-key,FWU_))) +$(if ${PROT_KEY},$(eval $(call CERT_ADD_CMD_OPT,${PROT_KEY},--prot-key))) $(if ${TRUSTED_WORLD_KEY},$(eval $(call CERT_ADD_CMD_OPT,${TRUSTED_WORLD_KEY},--trusted-world-key))) $(if ${NON_TRUSTED_WORLD_KEY},$(eval $(call CERT_ADD_CMD_OPT,${NON_TRUSTED_WORLD_KEY},--non-trusted-world-key))) @@ -93,5 +95,7 @@ endif ifneq (${BL33},) $(if ${BL33_KEY},$(eval $(call CERT_ADD_CMD_OPT,${BL33_KEY},--nt-fw-key))) $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/nt_fw_content.crt,--nt-fw-cert)) +ifneq (${COT},dualroot) $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/nt_fw_key.crt,--nt-fw-key-cert)) endif +endif -- cgit v1.2.3 From 32e26c067a21ae1dda62f63055b6c4264dbb45d0 Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Wed, 5 Feb 2020 17:15:12 +0100 Subject: plat/arm: Provide some PROTK files for development When using the new dualroot chain of trust, a new root of trust key is needed to authenticate the images belonging to the platform owner. Provide a development one to deploy this on Arm platforms. Change-Id: I481145e09aa564822d474cb47d38ec211dd24efd Signed-off-by: Sandrine Bailleux --- plat/arm/board/common/protpk/README | 14 +++++++++++ plat/arm/board/common/protpk/arm_dev_protpk.S | 18 +++++++++++++++ .../board/common/protpk/arm_protpk_rsa_sha256.bin | 1 + plat/arm/board/common/protpk/arm_protprivk_rsa.pem | 27 ++++++++++++++++++++++ 4 files changed, 60 insertions(+) create mode 100644 plat/arm/board/common/protpk/README create mode 100644 plat/arm/board/common/protpk/arm_dev_protpk.S create mode 100644 plat/arm/board/common/protpk/arm_protpk_rsa_sha256.bin create mode 100644 plat/arm/board/common/protpk/arm_protprivk_rsa.pem diff --git a/plat/arm/board/common/protpk/README b/plat/arm/board/common/protpk/README new file mode 100644 index 000000000..3aca180d2 --- /dev/null +++ b/plat/arm/board/common/protpk/README @@ -0,0 +1,14 @@ +This directory contains some development keys to be used as the platform +root-of-trust key. + +* arm_protprivk_rsa.pem is a 2K RSA private key in PEM format. It has been + generated using the openssl command line tool: + + openssl genrsa 2048 > arm_protprivk_rsa.pem + +* arm_protpk_rsa_sha256.bin is the SHA-256 hash of the DER-encoded public key + associated with the above private key. It has been generated using the openssl + command line tool: + + openssl rsa -in arm_protprivk_rsa.pem -pubout -outform DER | \ + openssl dgst -sha256 -binary > arm_protpk_rsa_sha256.bin diff --git a/plat/arm/board/common/protpk/arm_dev_protpk.S b/plat/arm/board/common/protpk/arm_dev_protpk.S new file mode 100644 index 000000000..2688cbbb1 --- /dev/null +++ b/plat/arm/board/common/protpk/arm_dev_protpk.S @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + + .global arm_protpk_hash + .global arm_protpk_hash_end + + .section .rodata.arm_protpk_hash, "a" + +arm_protpk_hash: + /* DER header. */ + .byte 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48 + .byte 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 + /* Key hash. */ + .incbin ARM_PROTPK_HASH +arm_protpk_hash_end: diff --git a/plat/arm/board/common/protpk/arm_protpk_rsa_sha256.bin b/plat/arm/board/common/protpk/arm_protpk_rsa_sha256.bin new file mode 100644 index 000000000..587da6605 --- /dev/null +++ b/plat/arm/board/common/protpk/arm_protpk_rsa_sha256.bin @@ -0,0 +1 @@ +6{W*`tve׷ PK{9 \ No newline at end of file diff --git a/plat/arm/board/common/protpk/arm_protprivk_rsa.pem b/plat/arm/board/common/protpk/arm_protprivk_rsa.pem new file mode 100644 index 000000000..eeaad9e28 --- /dev/null +++ b/plat/arm/board/common/protpk/arm_protprivk_rsa.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAzR0h/Z4Up17wfuRlYrUWseGDmlGKpl1PflGiYbyVmI7PwTTp +y/T77EiljGp52suLWntHsc0lee50pW16DU2c5bVfmyofau3GjJ1Yqw5XFAahr6eM +/0mkN8utrevvcRT9CP07D+zdhb/WlRUAnedqr/AUHU8BXS+Bxe8P0Z0Z7+DKjYZp +thzXxsjKM02BFFzNwyVrlyBFDkW/53A4M+dpmuWDjAGCJH88W/u0LdmLcii11IzD +/Ofz8Jxc/ZhqL+9FFK4qU+AJp8yXAnACSB46DlNltJrode0y5tmPhtS37ZF7EFb8 +UZWwZVgtuQyuyz9RYUS6jtiGuq6s8GlRwjTe7wIDAQABAoIBAFoWIYeyln+sQxR4 +W88umfkmgxaUGcFX2kIwuJEUst9+WeERzF24C62LeqphWYOvQlVLMAH3iC41fSXr +H2AYZoC9WHBd386nAD1iHj+C3Nv+zaTIgjTdszKOUonAxjl0bm40SmyELAdCaoyv +3MV9jm4Xk74LpR24b9bvWJNH3MxttH9hiYS+n0IzeTXDfO8GrNvHh92zx+jo8yMm +Khhu+TDC9jA2pHpJcF/0EXxYMhwYiQT16nnHb+xMgS4JpalQhvVK01s4VYGHRoFk +K6xh4TIS336LDLyalrGsPlfNfEdx+DimShDIfBUx9Jp3Pp11TUQUz4rhIHB9WdfG +b6bV4wECgYEA+cgPS2TQ7XQ1RJq1S7OGePtBXvnoH226KwGS6Fey8838tLxbblim +MU+EOYs3O66V6U2YpzmIakXo8030k8thY+jKbZl3l0m/hMuPOG66hfE5i7dYsiP4 +atok5wFiNeNYYjHMEayzk53MhG8EOh36msAO7ohKmenONUBA7pk6yTkCgYEA0jhk +HPshwi+wKkx+JLTnuoEgx40tkRgSF2xBqKssMTasaQmX8qG+w9CEs0R8nZCI70Vc +tXSFcidjdkHUVE2WsygIFuS1tbsAnpaxtn3E6rjie30X/Z280+TV0HjR0EMETmwl +ShC5lZ0oP3LpEZfjbR5qs2kFW4MOxA7tjQVaMWcCgYEA5ZbVMBifzdMl70RA5i9C +qEtSQAl3KgRCvar5rKSHsX+iC0Kiy9+iCusq/3WONEZ6NvMDIJpKYFyYDaOW7o5f +m2TrRChu+1lnN5mfsGBfBCTBH0JMvZlAin6ussLb0eqBX+ijyY8zlLjTttsQSJcr +tThZwTj3UVfOGbZQuL+RgEkCgYBXO3U3nXI9vUIx2zoBC1yZRNoQVGITMlTXiWGZ +lyYoadKTZ5q44Sti4BUguounaoGYIEU/OtHhM70PJnPwY53kS/lHXrKUbbvtEwU9 +f+UFraC1s4wP/rOLjgq3jlsqO5T+4dt7Z4NLNUKtSYazeT6zWgrW1f6WIcUv0C38 +9bqegwKBgFCK3Oa5ibL5sPaPQ/1UfdeW4JVuu6A4JhHS7r+cVLsmcrvE1Qv7Wcvw +B5aqXeqLu2dtIN8/f++3tzccs9LXKY/fh72D4TVjfrqOSSZoGTH9l4U5NXbqWM3I +skkAYb2bMST/d1qSyYesgXVNAlaQHRh3vEz8x853nJ3v9OFj8/rW +-----END RSA PRIVATE KEY----- -- cgit v1.2.3 From 1035a70625e322427853c161308b5960c42bb961 Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Thu, 6 Feb 2020 14:59:33 +0100 Subject: plat/arm: Add support for dualroot CoT - Use the development PROTPK if using the dualroot CoT. Note that unlike the ROTPK, the PROTPK key hash file is not generated from the key file, instead it has to be provided. This might be enhanced in the future. - Define a CoT build flag for the platform code to provide different implementations where needed. Change-Id: Iaaf25183b94e77a99a5d8d875831d90c102a97ea Signed-off-by: Sandrine Bailleux --- plat/arm/board/common/board_common.mk | 21 +++++++++++++++++++++ plat/arm/common/arm_common.mk | 2 ++ 2 files changed, 23 insertions(+) diff --git a/plat/arm/board/common/board_common.mk b/plat/arm/board/common/board_common.mk index 459156b2a..1885a600a 100644 --- a/plat/arm/board/common/board_common.mk +++ b/plat/arm/board/common/board_common.mk @@ -68,4 +68,25 @@ BL1_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c \ BL2_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c \ plat/arm/board/common/rotpk/arm_dev_rotpk.S +# Allows platform code to provide implementation variants depending on the +# selected chain of trust. +$(eval $(call add_define,ARM_COT_${COT})) + +ifeq (${COT},dualroot) +# Platform Root of Trust key files. +ARM_PROT_KEY := plat/arm/board/common/protpk/arm_protprivk_rsa.pem +ARM_PROTPK_HASH := plat/arm/board/common/protpk/arm_protpk_rsa_sha256.bin + +# Provide the private key to cert_create tool. It needs it to sign the images. +PROT_KEY := ${ARM_PROT_KEY} + +$(eval $(call add_define_val,ARM_PROTPK_HASH,'"$(ARM_PROTPK_HASH)"')) + +BL1_SOURCES += plat/arm/board/common/protpk/arm_dev_protpk.S +BL2_SOURCES += plat/arm/board/common/protpk/arm_dev_protpk.S + +$(BUILD_PLAT)/bl1/arm_dev_protpk.o: $(ARM_PROTPK_HASH) +$(BUILD_PLAT)/bl2/arm_dev_protpk.o: $(ARM_PROTPK_HASH) +endif + endif diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index 17058d1a5..3521780a5 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -294,6 +294,8 @@ ifneq (${TRUSTED_BOARD_BOOT},0) # Include the selected chain of trust sources. ifeq (${COT},tbbr) AUTH_SOURCES += drivers/auth/tbbr/tbbr_cot.c + else ifeq (${COT},dualroot) + AUTH_SOURCES += drivers/auth/dualroot/cot.c else $(error Unknown chain of trust ${COT}) endif -- cgit v1.2.3 From 88005701ece84522f419d8176460f7e9d9ea7240 Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Thu, 6 Feb 2020 14:34:44 +0100 Subject: plat/arm: Pass cookie argument down to arm_get_rotpk_info() The cookie will be leveraged in the next commit. Change-Id: Ie8bad275d856d84c27466461cf815529dd860446 Signed-off-by: Sandrine Bailleux --- include/plat/arm/common/plat_arm.h | 2 +- plat/arm/board/common/board_arm_trusted_boot.c | 2 +- plat/arm/board/fvp/fvp_trusted_boot.c | 2 +- plat/arm/board/rde1edge/rde1edge_trusted_boot.c | 2 +- plat/arm/board/rdn1edge/rdn1edge_trusted_boot.c | 2 +- plat/arm/board/sgi575/sgi575_trusted_boot.c | 2 +- plat/arm/board/sgm775/sgm775_trusted_boot.c | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index 025a64fa2..45c099f1b 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -262,7 +262,7 @@ __dead2 void plat_arm_error_handler(int err); * Optional functions in ARM standard platforms */ void plat_arm_override_gicr_frames(const uintptr_t *plat_gicr_frames); -int arm_get_rotpk_info(void **key_ptr, unsigned int *key_len, +int arm_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, unsigned int *flags); int arm_get_rotpk_info_regs(void **key_ptr, unsigned int *key_len, unsigned int *flags); diff --git a/plat/arm/board/common/board_arm_trusted_boot.c b/plat/arm/board/common/board_arm_trusted_boot.c index 3c19230bd..e3651f5f4 100644 --- a/plat/arm/board/common/board_arm_trusted_boot.c +++ b/plat/arm/board/common/board_arm_trusted_boot.c @@ -110,7 +110,7 @@ int arm_get_rotpk_info_cc(void **key_ptr, unsigned int *key_len, /* * Wraper function for most Arm platforms to get ROTPK hash. */ -int arm_get_rotpk_info(void **key_ptr, unsigned int *key_len, +int arm_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, unsigned int *flags) { #if ARM_CRYPTOCELL_INTEG diff --git a/plat/arm/board/fvp/fvp_trusted_boot.c b/plat/arm/board/fvp/fvp_trusted_boot.c index a09b80e10..8825198a1 100644 --- a/plat/arm/board/fvp/fvp_trusted_boot.c +++ b/plat/arm/board/fvp/fvp_trusted_boot.c @@ -30,7 +30,7 @@ int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, unsigned int *flags) { - return arm_get_rotpk_info(key_ptr, key_len, flags); + return arm_get_rotpk_info(cookie, key_ptr, key_len, flags); } /* diff --git a/plat/arm/board/rde1edge/rde1edge_trusted_boot.c b/plat/arm/board/rde1edge/rde1edge_trusted_boot.c index c271f7f2d..4592b8fba 100644 --- a/plat/arm/board/rde1edge/rde1edge_trusted_boot.c +++ b/plat/arm/board/rde1edge/rde1edge_trusted_boot.c @@ -22,5 +22,5 @@ int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, unsigned int *flags) { - return arm_get_rotpk_info(key_ptr, key_len, flags); + return arm_get_rotpk_info(cookie, key_ptr, key_len, flags); } diff --git a/plat/arm/board/rdn1edge/rdn1edge_trusted_boot.c b/plat/arm/board/rdn1edge/rdn1edge_trusted_boot.c index c271f7f2d..4592b8fba 100644 --- a/plat/arm/board/rdn1edge/rdn1edge_trusted_boot.c +++ b/plat/arm/board/rdn1edge/rdn1edge_trusted_boot.c @@ -22,5 +22,5 @@ int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, unsigned int *flags) { - return arm_get_rotpk_info(key_ptr, key_len, flags); + return arm_get_rotpk_info(cookie, key_ptr, key_len, flags); } diff --git a/plat/arm/board/sgi575/sgi575_trusted_boot.c b/plat/arm/board/sgi575/sgi575_trusted_boot.c index c271f7f2d..4592b8fba 100644 --- a/plat/arm/board/sgi575/sgi575_trusted_boot.c +++ b/plat/arm/board/sgi575/sgi575_trusted_boot.c @@ -22,5 +22,5 @@ int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, unsigned int *flags) { - return arm_get_rotpk_info(key_ptr, key_len, flags); + return arm_get_rotpk_info(cookie, key_ptr, key_len, flags); } diff --git a/plat/arm/board/sgm775/sgm775_trusted_boot.c b/plat/arm/board/sgm775/sgm775_trusted_boot.c index c271f7f2d..4592b8fba 100644 --- a/plat/arm/board/sgm775/sgm775_trusted_boot.c +++ b/plat/arm/board/sgm775/sgm775_trusted_boot.c @@ -22,5 +22,5 @@ int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, unsigned int *flags) { - return arm_get_rotpk_info(key_ptr, key_len, flags); + return arm_get_rotpk_info(cookie, key_ptr, key_len, flags); } -- cgit v1.2.3 From d25625cac10579f71e808b2500edaab4c12afeda Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Wed, 5 Feb 2020 16:33:37 +0100 Subject: plat/arm: Retrieve the right ROTPK when using the dualroot CoT The dualroot chain of trust involves 2 root-of-trust public keys: - The classic ROTPK. - The platform ROTPK (a.k.a. PROTPK). Use the cookie argument as a key ID for plat_get_rotpk_info() to return the appropriate one. This only applies if we are using the dualroot CoT ; if using the TBBR one, the behaviour is unchanged. Change-Id: I400707a87ec01afd5922b68db31d652d787f79bd Signed-off-by: Sandrine Bailleux --- plat/arm/board/common/board_arm_trusted_boot.c | 48 +++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/plat/arm/board/common/board_arm_trusted_boot.c b/plat/arm/board/common/board_arm_trusted_boot.c index e3651f5f4..38cbba9e9 100644 --- a/plat/arm/board/common/board_arm_trusted_boot.c +++ b/plat/arm/board/common/board_arm_trusted_boot.c @@ -16,8 +16,12 @@ #include #include #include -#include +#if defined(ARM_COT_tbbr) +#include +#elif defined(ARM_COT_dualroot) +#include +#endif #if !ARM_CRYPTOCELL_INTEG #if !ARM_ROTPK_LOCATION_ID @@ -108,10 +112,10 @@ int arm_get_rotpk_info_cc(void **key_ptr, unsigned int *key_len, #endif /* - * Wraper function for most Arm platforms to get ROTPK hash. + * Wrapper function for most Arm platforms to get ROTPK hash. */ -int arm_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, - unsigned int *flags) +static int get_rotpk_info(void **key_ptr, unsigned int *key_len, + unsigned int *flags) { #if ARM_CRYPTOCELL_INTEG return arm_get_rotpk_info_cc(key_ptr, key_len, flags); @@ -125,10 +129,44 @@ int arm_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, #else return 1; #endif - #endif /* ARM_CRYPTOCELL_INTEG */ } +#if defined(ARM_COT_tbbr) + +int arm_get_rotpk_info(void *cookie __unused, void **key_ptr, + unsigned int *key_len, unsigned int *flags) +{ + return get_rotpk_info(key_ptr, key_len, flags); +} + +#elif defined(ARM_COT_dualroot) + +int arm_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ + /* + * Return the right root of trust key hash based on the cookie value: + * - NULL means the primary ROTPK. + * - Otherwise, interpret cookie as the OID of the certificate + * extension containing the key. + */ + if (cookie == NULL) { + return get_rotpk_info(key_ptr, key_len, flags); + } else if (strcmp(cookie, PROT_PK_OID) == 0) { + extern unsigned char arm_protpk_hash[]; + extern unsigned char arm_protpk_hash_end[]; + *key_ptr = arm_protpk_hash; + *key_len = arm_protpk_hash_end - arm_protpk_hash; + *flags = ROTPK_IS_HASH; + return 0; + } else { + /* Invalid key ID. */ + return 1; + } +} +#endif + /* * Return the non-volatile counter value stored in the platform. The cookie * will contain the OID of the counter in the certificate. -- cgit v1.2.3 From 60e8f3cfd5910c59c9a573ce05bd61091336b09a Mon Sep 17 00:00:00 2001 From: Petre-Ionut Tudor Date: Thu, 7 Nov 2019 15:18:03 +0000 Subject: Read-only xlat tables for BL31 memory This patch introduces a build flag which allows the xlat tables to be mapped in a read-only region within BL31 memory. It makes it much harder for someone who has acquired the ability to write to arbitrary secure memory addresses to gain control of the translation tables. The memory attributes of the descriptors describing the tables themselves are changed to read-only secure data. This change happens at the end of BL31 runtime setup. Until this point, the tables have read-write permissions. This gives a window of opportunity for changes to be made to the tables with the MMU on (e.g. reclaiming init code). No changes can be made to the tables with the MMU turned on from this point onwards. This change is also enabled for sp_min and tspd. To make all this possible, the base table was moved to .rodata. The penalty we pay is that now .rodata must be aligned to the size of the base table (512B alignment). Still, this is better than putting the base table with the higher level tables in the xlat_table section, as that would cost us a full 4KB page. Changing the tables from read-write to read-only cannot be done with the MMU on, as the break-before-make sequence would invalidate the descriptor which resolves the level 3 page table where that very descriptor is located. This would make the translation required for writing the changes impossible, generating an MMU fault. The caches are also flushed. Signed-off-by: Petre-Ionut Tudor Change-Id: Ibe5de307e6dc94c67d6186139ac3973516430466 --- Makefile | 8 +++ include/lib/xlat_tables/xlat_tables_v2.h | 12 +++- include/lib/xlat_tables/xlat_tables_v2_helpers.h | 62 +++++++++++++++++-- include/plat/arm/common/plat_arm.h | 5 ++ lib/aarch64/cache_helpers.S | 6 +- lib/xlat_tables_v2/ro_xlat_tables.mk | 37 +++++++++++ lib/xlat_tables_v2/xlat_tables.mk | 6 +- lib/xlat_tables_v2/xlat_tables_context.c | 78 +++++++++++++++++++++++- make_helpers/defaults.mk | 7 +++ plat/arm/board/fvp/platform.mk | 13 +++- plat/arm/board/juno/platform.mk | 8 +++ plat/arm/common/arm_bl31_setup.c | 5 ++ plat/arm/common/arm_common.c | 20 ++++++ plat/arm/common/sp_min/arm_sp_min_setup.c | 4 ++ plat/arm/common/tsp/arm_tsp_setup.c | 6 +- 15 files changed, 264 insertions(+), 13 deletions(-) create mode 100644 lib/xlat_tables_v2/ro_xlat_tables.mk diff --git a/Makefile b/Makefile index 547b5843f..5e865417f 100644 --- a/Makefile +++ b/Makefile @@ -621,6 +621,12 @@ ifeq ($(MEASURED_BOOT),1) endif endif +ifeq (${ARM_XLAT_TABLES_LIB_V1}, 1) + ifeq (${ALLOW_RO_XLAT_TABLES}, 1) + $(error "ALLOW_RO_XLAT_TABLES requires translation tables library v2") + endif +endif + ################################################################################ # Process platform overrideable behaviour ################################################################################ @@ -747,6 +753,7 @@ endif # Build options checks ################################################################################ +$(eval $(call assert_boolean,ALLOW_RO_XLAT_TABLES)) $(eval $(call assert_boolean,COLD_BOOT_SINGLE_CPU)) $(eval $(call assert_boolean,CREATE_KEYS)) $(eval $(call assert_boolean,CTX_INCLUDE_AARCH32_REGS)) @@ -814,6 +821,7 @@ endif # platform to overwrite the default options ################################################################################ +$(eval $(call add_define,ALLOW_RO_XLAT_TABLES)) $(eval $(call add_define,ARM_ARCH_MAJOR)) $(eval $(call add_define,ARM_ARCH_MINOR)) $(eval $(call add_define,COLD_BOOT_SINGLE_CPU)) diff --git a/include/lib/xlat_tables/xlat_tables_v2.h b/include/lib/xlat_tables/xlat_tables_v2.h index 0e099987e..a80fab073 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-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -345,6 +345,16 @@ int xlat_change_mem_attributes_ctx(const xlat_ctx_t *ctx, uintptr_t base_va, size_t size, uint32_t attr); int xlat_change_mem_attributes(uintptr_t base_va, size_t size, uint32_t attr); +#if PLAT_RO_XLAT_TABLES +/* + * Change the memory attributes of the memory region encompassing the higher + * level translation tables to secure read-only data. + * + * Return 0 on success, a negative error code on error. + */ +int xlat_make_tables_readonly(void); +#endif + /* * Query the memory attributes of a memory page in a set of translation tables. * diff --git a/include/lib/xlat_tables/xlat_tables_v2_helpers.h b/include/lib/xlat_tables/xlat_tables_v2_helpers.h index b17b71a87..c88fa4dd5 100644 --- a/include/lib/xlat_tables/xlat_tables_v2_helpers.h +++ b/include/lib/xlat_tables/xlat_tables_v2_helpers.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -70,6 +70,9 @@ struct xlat_ctx { */ uint64_t (*tables)[XLAT_TABLE_ENTRIES]; int tables_num; +#if PLAT_RO_XLAT_TABLES + bool readonly_tables; +#endif /* * Keep track of how many regions are mapped in each table. The base * table can't be unmapped so it isn't needed to keep track of it. @@ -122,6 +125,14 @@ struct xlat_ctx { /* do nothing */ #endif /* PLAT_XLAT_TABLES_DYNAMIC */ +#if PLAT_RO_XLAT_TABLES +#define XLAT_CTX_INIT_TABLE_ATTR() \ + .readonly_tables = false, +#else +#define XLAT_CTX_INIT_TABLE_ATTR() + /* do nothing */ +#endif + #define REGISTER_XLAT_CONTEXT_FULL_SPEC(_ctx_name, _mmap_count, \ _xlat_tables_count, _virt_addr_space_size, \ _phy_addr_space_size, _xlat_regime, _section_name)\ @@ -142,22 +153,63 @@ struct xlat_ctx { XLAT_ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count) \ \ static xlat_ctx_t _ctx_name##_xlat_ctx = { \ - .va_max_address = (_virt_addr_space_size) - 1UL, \ .pa_max_address = (_phy_addr_space_size) - 1ULL, \ + .va_max_address = (_virt_addr_space_size) - 1UL, \ .mmap = _ctx_name##_mmap, \ .mmap_num = (_mmap_count), \ - .base_level = GET_XLAT_TABLE_LEVEL_BASE(_virt_addr_space_size),\ + .tables = _ctx_name##_xlat_tables, \ + .tables_num = _xlat_tables_count, \ + XLAT_CTX_INIT_TABLE_ATTR() \ + XLAT_REGISTER_DYNMAP_STRUCT(_ctx_name) \ + .next_table = 0, \ .base_table = _ctx_name##_base_xlat_table, \ .base_table_entries = \ GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size),\ + .max_pa = 0U, \ + .max_va = 0U, \ + .base_level = GET_XLAT_TABLE_LEVEL_BASE(_virt_addr_space_size),\ + .initialized = false, \ + .xlat_regime = (_xlat_regime) \ + } + +#define REGISTER_XLAT_CONTEXT_RO_BASE_TABLE(_ctx_name, _mmap_count, \ + _xlat_tables_count, _virt_addr_space_size, \ + _phy_addr_space_size, _xlat_regime, _section_name)\ + CASSERT(CHECK_PHY_ADDR_SPACE_SIZE(_phy_addr_space_size), \ + assert_invalid_physical_addr_space_sizefor_##_ctx_name);\ + \ + static mmap_region_t _ctx_name##_mmap[_mmap_count + 1]; \ + \ + static uint64_t _ctx_name##_xlat_tables[_xlat_tables_count] \ + [XLAT_TABLE_ENTRIES] \ + __aligned(XLAT_TABLE_SIZE) __section(_section_name); \ + \ + static uint64_t _ctx_name##_base_xlat_table \ + [GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size)] \ + __aligned(GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size)\ + * sizeof(uint64_t)) \ + __section(".rodata"); \ + \ + XLAT_ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count) \ + \ + static xlat_ctx_t _ctx_name##_xlat_ctx = { \ + .pa_max_address = (_phy_addr_space_size) - 1ULL, \ + .va_max_address = (_virt_addr_space_size) - 1UL, \ + .mmap = _ctx_name##_mmap, \ + .mmap_num = (_mmap_count), \ .tables = _ctx_name##_xlat_tables, \ .tables_num = _xlat_tables_count, \ + XLAT_CTX_INIT_TABLE_ATTR() \ XLAT_REGISTER_DYNMAP_STRUCT(_ctx_name) \ - .xlat_regime = (_xlat_regime), \ + .next_table = 0, \ + .base_table = _ctx_name##_base_xlat_table, \ + .base_table_entries = \ + GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size),\ .max_pa = 0U, \ .max_va = 0U, \ - .next_table = 0, \ + .base_level = GET_XLAT_TABLE_LEVEL_BASE(_virt_addr_space_size),\ .initialized = false, \ + .xlat_regime = (_xlat_regime) \ } #endif /*__ASSEMBLER__*/ diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index 025a64fa2..862e73af1 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -236,6 +236,11 @@ int arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size); */ void arm_free_init_memory(void); +/* + * Make the higher level translation tables read-only + */ +void arm_xlat_make_tables_readonly(void); + /* * Mandatory functions required in ARM standard platforms */ diff --git a/lib/aarch64/cache_helpers.S b/lib/aarch64/cache_helpers.S index 9ef8ca79b..de9c8e4f0 100644 --- a/lib/aarch64/cache_helpers.S +++ b/lib/aarch64/cache_helpers.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -30,7 +30,7 @@ loop_\op: dc \op, x0 add x0, x0, x2 cmp x0, x1 - b.lo loop_\op + b.lo loop_\op dsb sy exit_loop_\op: ret @@ -140,7 +140,7 @@ loop3_\_op: level_done: add x10, x10, #2 // increment cache number cmp x3, x10 - b.hi loop1 + b.hi loop1 msr csselr_el1, xzr // select cache level 0 in csselr dsb sy // barrier to complete final cache operation isb diff --git a/lib/xlat_tables_v2/ro_xlat_tables.mk b/lib/xlat_tables_v2/ro_xlat_tables.mk new file mode 100644 index 000000000..7991e1afd --- /dev/null +++ b/lib/xlat_tables_v2/ro_xlat_tables.mk @@ -0,0 +1,37 @@ +# +# Copyright (c) 2020, 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) + ifeq (${RESET_TO_SP_MIN},1) + $(error "RESET_TO_SP_MIN requires functionality from the dynamic \ + translation library and is incompatible with \ + ALLOW_RO_XLAT_TABLES.") + endif +else # if AArch64 + ifeq (${PLAT},tegra) + $(error "Tegra requires functionality from the dynamic translation \ + library and is incompatible with ALLOW_RO_XLAT_TABLES.") + endif + ifeq (${RESET_TO_BL31},1) + $(error "RESET_TO_BL31 requires functionality from the dynamic \ + translation library and is incompatible with \ + ALLOW_RO_XLAT_TABLES.") + endif + ifeq (${SPD},trusty) + $(error "Trusty requires functionality from the dynamic translation \ + library and is incompatible with ALLOW_RO_XLAT_TABLES.") + endif + ifeq (${SPM_MM},1) + $(error "SPM_MM requires functionality to change memory region \ + attributes, which is not possible once the translation tables \ + have been made read-only.") + endif +endif diff --git a/lib/xlat_tables_v2/xlat_tables.mk b/lib/xlat_tables_v2/xlat_tables.mk index c946315bf..bcc3e68d8 100644 --- a/lib/xlat_tables_v2/xlat_tables.mk +++ b/lib/xlat_tables_v2/xlat_tables.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -13,3 +13,7 @@ XLAT_TABLES_LIB_SRCS := $(addprefix lib/xlat_tables_v2/, \ XLAT_TABLES_LIB_V2 := 1 $(eval $(call add_define,XLAT_TABLES_LIB_V2)) + +ifeq (${ALLOW_RO_XLAT_TABLES}, 1) + include lib/xlat_tables_v2/ro_xlat_tables.mk +endif diff --git a/lib/xlat_tables_v2/xlat_tables_context.c b/lib/xlat_tables_v2/xlat_tables_context.c index f4b64b33f..adca57875 100644 --- a/lib/xlat_tables_v2/xlat_tables_context.c +++ b/lib/xlat_tables_v2/xlat_tables_context.c @@ -1,9 +1,10 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ +#include #include #include @@ -24,8 +25,14 @@ uint64_t mmu_cfg_params[MMU_CFG_PARAM_MAX]; * Allocate and initialise the default translation context for the BL image * currently executing. */ +#if PLAT_RO_XLAT_TABLES +REGISTER_XLAT_CONTEXT_RO_BASE_TABLE(tf, MAX_MMAP_REGIONS, MAX_XLAT_TABLES, + PLAT_VIRT_ADDR_SPACE_SIZE, PLAT_PHY_ADDR_SPACE_SIZE, + EL_REGIME_INVALID, "xlat_table"); +#else REGISTER_XLAT_CONTEXT(tf, MAX_MMAP_REGIONS, MAX_XLAT_TABLES, PLAT_VIRT_ADDR_SPACE_SIZE, PLAT_PHY_ADDR_SPACE_SIZE); +#endif void mmap_add_region(unsigned long long base_pa, uintptr_t base_va, size_t size, unsigned int attr) @@ -119,6 +126,75 @@ int xlat_change_mem_attributes(uintptr_t base_va, size_t size, uint32_t attr) return xlat_change_mem_attributes_ctx(&tf_xlat_ctx, base_va, size, attr); } +#if PLAT_RO_XLAT_TABLES +/* Change the memory attributes of the descriptors which resolve the address + * range that belongs to the translation tables themselves, which are by default + * mapped as part of read-write data in the BL image's memory. + * + * Since the translation tables map themselves via these level 3 (page) + * descriptors, any change applied to them with the MMU on would introduce a + * chicken and egg problem because of the break-before-make sequence. + * Eventually, it would reach the descriptor that resolves the very table it + * belongs to and the invalidation (break step) would cause the subsequent write + * (make step) to it to generate an MMU fault. Therefore, the MMU is disabled + * before making the change. + * + * No assumption is made about what data this function needs, therefore all the + * caches are flushed in order to ensure coherency. A future optimization would + * be to only flush the required data to main memory. + */ +int xlat_make_tables_readonly(void) +{ + assert(tf_xlat_ctx.initialized == true); +#ifdef __aarch64__ + if (tf_xlat_ctx.xlat_regime == EL1_EL0_REGIME) { + disable_mmu_el1(); + } else if (tf_xlat_ctx.xlat_regime == EL3_REGIME) { + disable_mmu_el3(); + } else { + assert(tf_xlat_ctx.xlat_regime == EL2_REGIME); + return -1; + } + + /* Flush all caches. */ + dcsw_op_all(DCCISW); +#else /* !__aarch64__ */ + assert(tf_xlat_ctx.xlat_regime == EL1_EL0_REGIME); + /* On AArch32, we flush the caches before disabling the MMU. The reason + * for this is that the dcsw_op_all AArch32 function pushes some + * registers onto the stack under the assumption that it is writing to + * cache, which is not true with the MMU off. This would result in the + * stack becoming corrupted and a wrong/junk value for the LR being + * restored at the end of the routine. + */ + dcsw_op_all(DC_OP_CISW); + disable_mmu_secure(); +#endif + + int rc = xlat_change_mem_attributes_ctx(&tf_xlat_ctx, + (uintptr_t)tf_xlat_ctx.tables, + tf_xlat_ctx.tables_num * XLAT_TABLE_SIZE, + MT_RO_DATA | MT_SECURE); + +#ifdef __aarch64__ + if (tf_xlat_ctx.xlat_regime == EL1_EL0_REGIME) { + enable_mmu_el1(0U); + } else { + assert(tf_xlat_ctx.xlat_regime == EL3_REGIME); + enable_mmu_el3(0U); + } +#else /* !__aarch64__ */ + enable_mmu_svc_mon(0U); +#endif + + if (rc == 0) { + tf_xlat_ctx.readonly_tables = true; + } + + return rc; +} +#endif /* PLAT_RO_XLAT_TABLES */ + /* * If dynamic allocation of new regions is disabled then by the time we call the * function enabling the MMU, we'll have registered all the memory regions to diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index e8e990d45..60958a1d1 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -207,6 +207,13 @@ USE_FCONF_BASED_IO := 0 # Build option to choose whether Trusted Firmware uses library at ROM USE_ROMLIB := 0 +# Build option to choose whether the xlat tables of BL images can be read-only. +# Note that this only serves as a higher level option to PLAT_RO_XLAT_TABLES, +# which is the per BL-image option that actually enables the read-only tables +# API. The reason for having this additional option is to have a common high +# level makefile where we can check for incompatible features/build options. +ALLOW_RO_XLAT_TABLES := 0 + # Chain of trust. COT := tbbr diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 4176968f8..05c11ce52 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -292,7 +292,7 @@ ifeq (${ARCH},aarch32) ifeq (${RESET_TO_SP_MIN},1) BL32_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 endif -else # if AArch64 +else # AArch64 ifeq (${RESET_TO_BL31},1) BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 endif @@ -301,6 +301,17 @@ else # if AArch64 endif endif +ifeq (${ALLOW_RO_XLAT_TABLES}, 1) + ifeq (${ARCH},aarch32) + BL32_CFLAGS += -DPLAT_RO_XLAT_TABLES=1 + else # AArch64 + BL31_CFLAGS += -DPLAT_RO_XLAT_TABLES=1 + ifeq (${SPD},tspd) + BL32_CFLAGS += -DPLAT_RO_XLAT_TABLES=1 + endif + endif +endif + ifeq (${USE_DEBUGFS},1) BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 endif diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk index 27650d266..f07c1b163 100644 --- a/plat/arm/board/juno/platform.mk +++ b/plat/arm/board/juno/platform.mk @@ -155,6 +155,14 @@ else endif endif +ifeq (${ALLOW_RO_XLAT_TABLES}, 1) + ifeq (${JUNO_AARCH32_EL3_RUNTIME}, 1) + BL32_CFLAGS += -DPLAT_RO_XLAT_TABLES=1 + else + BL31_CFLAGS += -DPLAT_RO_XLAT_TABLES=1 + endif +endif + # Add the FDT_SOURCES and options for Dynamic Config FDT_SOURCES += plat/arm/board/juno/fdts/${PLAT}_fw_config.dts TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c index c135d7f2d..85535c11a 100644 --- a/plat/arm/common/arm_bl31_setup.c +++ b/plat/arm/common/arm_bl31_setup.c @@ -256,9 +256,14 @@ void arm_bl31_plat_runtime_setup(void) /* Initialize the runtime console */ arm_console_runtime_init(); + #if RECLAIM_INIT_CODE arm_free_init_memory(); #endif + +#if PLAT_RO_XLAT_TABLES + arm_xlat_make_tables_readonly(); +#endif } #if RECLAIM_INIT_CODE diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c index d1e9620de..d1eee08d1 100644 --- a/plat/arm/common/arm_common.c +++ b/plat/arm/common/arm_common.c @@ -25,6 +25,26 @@ * conflicts with the definition in plat/common. */ #pragma weak plat_get_syscnt_freq2 +/******************************************************************************* + * Changes the memory attributes for the region of mapped memory where the BL + * image's translation tables are located such that the tables will have + * read-only permissions. + ******************************************************************************/ +#if PLAT_RO_XLAT_TABLES +void arm_xlat_make_tables_readonly(void) +{ + int rc = xlat_make_tables_readonly(); + + if (rc != 0) { + ERROR("Failed to make translation tables read-only at EL%u.\n", + get_current_el()); + panic(); + } + + INFO("Translation tables are now read-only at EL%u.\n", + get_current_el()); +} +#endif void arm_setup_romlib(void) { diff --git a/plat/arm/common/sp_min/arm_sp_min_setup.c b/plat/arm/common/sp_min/arm_sp_min_setup.c index 0cc746b10..cbbdfa21b 100644 --- a/plat/arm/common/sp_min/arm_sp_min_setup.c +++ b/plat/arm/common/sp_min/arm_sp_min_setup.c @@ -167,6 +167,10 @@ void arm_sp_min_plat_runtime_setup(void) { /* Initialize the runtime console */ arm_console_runtime_init(); + +#if PLAT_RO_XLAT_TABLES + arm_xlat_make_tables_readonly(); +#endif } /******************************************************************************* diff --git a/plat/arm/common/tsp/arm_tsp_setup.c b/plat/arm/common/tsp/arm_tsp_setup.c index aefdf89c7..5dd964de2 100644 --- a/plat/arm/common/tsp/arm_tsp_setup.c +++ b/plat/arm/common/tsp/arm_tsp_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -79,4 +79,8 @@ void tsp_plat_arch_setup(void) setup_page_tables(bl_regions, plat_arm_get_mmap()); enable_mmu_el1(0); + +#if PLAT_RO_XLAT_TABLES + arm_xlat_make_tables_readonly(); +#endif } -- cgit v1.2.3 From d603fd3033c0ef31ee5fc1eccdcfbe77eaf53690 Mon Sep 17 00:00:00 2001 From: "Tien Hock, Loh" Date: Wed, 2 Oct 2019 13:49:25 +0800 Subject: intel: Enable EMAC PHY in Intel FPGA platform This initializes the EMAC PHY in both Stratix 10 and Agilex, without this, EMAC PHY wouldn't work correctly. Change-Id: I7e6b9e88fd9ef472884fcf648e6001fcb7549ae6 Signed-off-by: Abdul Halim, Muhammad Hadi Asyrafi --- plat/intel/soc/agilex/bl2_plat_setup.c | 6 ++-- plat/intel/soc/agilex/platform.mk | 5 +-- plat/intel/soc/common/include/platform_def.h | 12 +++++-- plat/intel/soc/common/include/socfpga_emac.h | 24 ++++++++++++++ .../soc/common/include/socfpga_system_manager.h | 5 +++ plat/intel/soc/common/soc/socfpga_emac.c | 38 ++++++++++++++++++++++ plat/intel/soc/stratix10/bl2_plat_setup.c | 6 ++-- plat/intel/soc/stratix10/platform.mk | 5 +-- 8 files changed, 91 insertions(+), 10 deletions(-) create mode 100644 plat/intel/soc/common/include/socfpga_emac.h create mode 100644 plat/intel/soc/common/soc/socfpga_emac.c diff --git a/plat/intel/soc/agilex/bl2_plat_setup.c b/plat/intel/soc/agilex/bl2_plat_setup.c index f32820777..a46c1a732 100644 --- a/plat/intel/soc/agilex/bl2_plat_setup.c +++ b/plat/intel/soc/agilex/bl2_plat_setup.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. - * Copyright (c) 2019, Intel Corporation. All rights reserved. + * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Intel Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -20,6 +20,7 @@ #include "agilex_pinmux.h" #include "ccu/ncore_ccu.h" #include "qspi/cadence_qspi.h" +#include "socfpga_emac.h" #include "socfpga_handoff.h" #include "socfpga_mailbox.h" #include "socfpga_private.h" @@ -72,6 +73,7 @@ void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1, socfpga_delay_timer_init(); init_ncore_ccu(); + socfpga_emac_init(); init_hard_memory_controller(); mailbox_init(); diff --git a/plat/intel/soc/agilex/platform.mk b/plat/intel/soc/agilex/platform.mk index f47c3f113..0a91c23dd 100644 --- a/plat/intel/soc/agilex/platform.mk +++ b/plat/intel/soc/agilex/platform.mk @@ -1,6 +1,6 @@ # -# Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. -# Copyright (c) 2019, Intel Corporation. All rights reserved. +# Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2019-2020, Intel Corporation. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -42,6 +42,7 @@ BL2_SOURCES += \ plat/intel/soc/common/socfpga_delay_timer.c \ plat/intel/soc/common/socfpga_image_load.c \ plat/intel/soc/common/socfpga_storage.c \ + plat/intel/soc/common/soc/socfpga_emac.c \ plat/intel/soc/common/soc/socfpga_handoff.c \ plat/intel/soc/common/soc/socfpga_mailbox.c \ plat/intel/soc/common/soc/socfpga_reset_manager.c \ diff --git a/plat/intel/soc/common/include/platform_def.h b/plat/intel/soc/common/include/platform_def.h index 8a681e69d..046d13880 100644 --- a/plat/intel/soc/common/include/platform_def.h +++ b/plat/intel/soc/common/include/platform_def.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. - * Copyright (c) 2019, Intel Corporation. All rights reserved. + * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Intel Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -168,6 +168,14 @@ #define PLAT_BAUDRATE (115200) #define PLAT_UART_CLOCK (100000000) +/******************************************************************************* + * PHY related constants + ******************************************************************************/ + +#define EMAC0_PHY_MODE PHY_INTERFACE_MODE_RGMII +#define EMAC1_PHY_MODE PHY_INTERFACE_MODE_RGMII +#define EMAC2_PHY_MODE PHY_INTERFACE_MODE_RGMII + /******************************************************************************* * System counter frequency related constants ******************************************************************************/ diff --git a/plat/intel/soc/common/include/socfpga_emac.h b/plat/intel/soc/common/include/socfpga_emac.h new file mode 100644 index 000000000..5b98006a3 --- /dev/null +++ b/plat/intel/soc/common/include/socfpga_emac.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2020, Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SOCFPGA_EMAC_H +#define SOCFPGA_EMAC_H + +/* EMAC PHY Mode */ + +#define PHY_INTERFACE_MODE_GMII_MII 0 +#define PHY_INTERFACE_MODE_RGMII 1 +#define PHY_INTERFACE_MODE_RMII 2 +#define PHY_INTERFACE_MODE_RESET 3 + +/* Mask Definitions */ + +#define PHY_INTF_SEL_MSK 0x3 +#define FPGAINTF_EN_3_EMAC_MSK(x) (1 << (x * 8)) + +void socfpga_emac_init(void); + +#endif /* SOCFPGA_EMAC_H */ diff --git a/plat/intel/soc/common/include/socfpga_system_manager.h b/plat/intel/soc/common/include/socfpga_system_manager.h index 68e30b894..76565bc93 100644 --- a/plat/intel/soc/common/include/socfpga_system_manager.h +++ b/plat/intel/soc/common/include/socfpga_system_manager.h @@ -13,6 +13,11 @@ #define SOCFPGA_SYSMGR_SDMMC 0x28 +#define SOCFPGA_SYSMGR_EMAC_0 0x44 +#define SOCFPGA_SYSMGR_EMAC_1 0x48 +#define SOCFPGA_SYSMGR_EMAC_2 0x4c +#define SOCFPGA_SYSMGR_FPGAINTF_EN_3 0x70 + #define SOCFPGA_SYSMGR_NOC_TIMEOUT 0xc0 #define SOCFPGA_SYSMGR_NOC_IDLEREQ_SET 0xc4 #define SOCFPGA_SYSMGR_NOC_IDLEREQ_CLR 0xc8 diff --git a/plat/intel/soc/common/soc/socfpga_emac.c b/plat/intel/soc/common/soc/socfpga_emac.c new file mode 100644 index 000000000..cacfd53c4 --- /dev/null +++ b/plat/intel/soc/common/soc/socfpga_emac.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2020, Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include "socfpga_emac.h" +#include "socfpga_reset_manager.h" +#include "socfpga_system_manager.h" + +void socfpga_emac_init(void) +{ + mmio_setbits_32(SOCFPGA_RSTMGR(PER0MODRST), + RSTMGR_PER0MODRST_EMAC0 | + RSTMGR_PER0MODRST_EMAC1 | + RSTMGR_PER0MODRST_EMAC2); + + mmio_clrsetbits_32(SOCFPGA_SYSMGR(EMAC_0), + PHY_INTF_SEL_MSK, EMAC0_PHY_MODE); + mmio_clrsetbits_32(SOCFPGA_SYSMGR(EMAC_1), + PHY_INTF_SEL_MSK, EMAC1_PHY_MODE); + mmio_clrsetbits_32(SOCFPGA_SYSMGR(EMAC_2), + PHY_INTF_SEL_MSK, EMAC2_PHY_MODE); + + mmio_clrbits_32(SOCFPGA_SYSMGR(FPGAINTF_EN_3), + FPGAINTF_EN_3_EMAC_MSK(0) | + FPGAINTF_EN_3_EMAC_MSK(1) | + FPGAINTF_EN_3_EMAC_MSK(2)); + + mmio_clrbits_32(SOCFPGA_RSTMGR(PER0MODRST), + RSTMGR_PER0MODRST_EMAC0 | + RSTMGR_PER0MODRST_EMAC1 | + RSTMGR_PER0MODRST_EMAC2); +} + diff --git a/plat/intel/soc/stratix10/bl2_plat_setup.c b/plat/intel/soc/stratix10/bl2_plat_setup.c index 78ca253e7..1f03f1e63 100644 --- a/plat/intel/soc/stratix10/bl2_plat_setup.c +++ b/plat/intel/soc/stratix10/bl2_plat_setup.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. - * Copyright (c) 2019, Intel Corporation. All rights reserved. + * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Intel Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -16,6 +16,7 @@ #include #include "qspi/cadence_qspi.h" +#include "socfpga_emac.h" #include "socfpga_handoff.h" #include "socfpga_mailbox.h" #include "socfpga_private.h" @@ -69,6 +70,7 @@ void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1, console_16550_register(PLAT_UART0_BASE, get_uart_clk(), PLAT_BAUDRATE, &console); + socfpga_emac_init(); socfpga_delay_timer_init(); init_hard_memory_controller(); mailbox_init(); diff --git a/plat/intel/soc/stratix10/platform.mk b/plat/intel/soc/stratix10/platform.mk index efbab24b3..112317b7b 100644 --- a/plat/intel/soc/stratix10/platform.mk +++ b/plat/intel/soc/stratix10/platform.mk @@ -1,6 +1,6 @@ # -# Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. -# Copyright (c) 2019, Intel Corporation. All rights reserved. +# Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2019-2020, Intel Corporation. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -42,6 +42,7 @@ BL2_SOURCES += \ plat/intel/soc/common/socfpga_delay_timer.c \ plat/intel/soc/common/socfpga_image_load.c \ plat/intel/soc/common/socfpga_storage.c \ + plat/intel/soc/common/soc/socfpga_emac.c \ plat/intel/soc/common/soc/socfpga_handoff.c \ plat/intel/soc/common/soc/socfpga_mailbox.c \ plat/intel/soc/common/soc/socfpga_reset_manager.c \ -- cgit v1.2.3 From ea9b9627767e61396f885a1d64b07dcb25872db6 Mon Sep 17 00:00:00 2001 From: "Abdul Halim, Muhammad Hadi Asyrafi" Date: Tue, 25 Feb 2020 16:28:10 +0800 Subject: intel: Fix argument type for mailbox driver This patch comes as fixes for 'intel: Fix Coverity Scan Defects' patch. Revert changing argument type from uint32_t to uint64_t to fix incompatible cast issue. Fix said bug by using intermediate uint32_t array as a more appropriate solution. Signed-off-by: Abdul Halim, Muhammad Hadi Asyrafi Change-Id: I344cdabd432cf0a0389b225c934b35d12f4c631d --- plat/intel/soc/common/include/socfpga_mailbox.h | 8 ++++---- plat/intel/soc/common/soc/socfpga_mailbox.c | 12 ++++++------ plat/intel/soc/common/socfpga_psci.c | 7 ++++++- plat/intel/soc/common/socfpga_sip_svc.c | 8 ++++---- 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h index 7d725b0ad..3c56d15bf 100644 --- a/plat/intel/soc/common/include/socfpga_mailbox.h +++ b/plat/intel/soc/common/include/socfpga_mailbox.h @@ -126,9 +126,9 @@ int mailbox_init(void); void mailbox_set_qspi_close(void); void mailbox_set_qspi_open(void); void mailbox_set_qspi_direct(void); -int mailbox_send_cmd(int job_id, unsigned int cmd, uint64_t *args, +int mailbox_send_cmd(int job_id, unsigned int cmd, uint32_t *args, int len, int urgent, uint32_t *response, int resp_len); -int mailbox_send_cmd_async(int job_id, unsigned int cmd, uint64_t *args, +int mailbox_send_cmd_async(int job_id, unsigned int cmd, uint32_t *args, int len, int urgent); int mailbox_read_response(int job_id, uint32_t *response, int resp_len); int mailbox_get_qspi_clock(void); @@ -140,7 +140,7 @@ int intel_mailbox_is_fpga_not_ready(void); int mailbox_rsu_get_spt_offset(uint32_t *resp_buf, uint32_t resp_buf_len); int mailbox_rsu_status(uint32_t *resp_buf, uint32_t resp_buf_len); -int mailbox_rsu_update(uint64_t *flash_offset); -int mailbox_hps_stage_notify(uint64_t execution_stage); +int mailbox_rsu_update(uint32_t *flash_offset); +int mailbox_hps_stage_notify(uint32_t execution_stage); #endif /* SOCFPGA_MBOX_H */ diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c index 8ce40a742..d066f27b5 100644 --- a/plat/intel/soc/common/soc/socfpga_mailbox.c +++ b/plat/intel/soc/common/soc/socfpga_mailbox.c @@ -11,7 +11,7 @@ #include "socfpga_mailbox.h" #include "socfpga_sip_svc.h" -static int fill_mailbox_circular_buffer(uint32_t header_cmd, uint64_t *args, +static int fill_mailbox_circular_buffer(uint32_t header_cmd, uint32_t *args, int len) { uint32_t cmd_free_offset; @@ -167,7 +167,7 @@ int mailbox_poll_response(int job_id, int urgent, uint32_t *response, } } -int mailbox_send_cmd_async(int job_id, unsigned int cmd, uint64_t *args, +int mailbox_send_cmd_async(int job_id, unsigned int cmd, uint32_t *args, int len, int urgent) { if (urgent) @@ -184,7 +184,7 @@ int mailbox_send_cmd_async(int job_id, unsigned int cmd, uint64_t *args, return 0; } -int mailbox_send_cmd(int job_id, unsigned int cmd, uint64_t *args, +int mailbox_send_cmd(int job_id, unsigned int cmd, uint32_t *args, int len, int urgent, uint32_t *response, int resp_len) { int status = 0; @@ -252,7 +252,7 @@ int mailbox_get_qspi_clock(void) void mailbox_qspi_set_cs(int device_select) { - uint64_t cs_setting = device_select; + uint32_t cs_setting = device_select; /* QSPI device select settings at 31:28 */ cs_setting = (cs_setting << 28); @@ -304,13 +304,13 @@ int mailbox_rsu_status(uint32_t *resp_buf, uint32_t resp_buf_len) return ret; } -int mailbox_rsu_update(uint64_t *flash_offset) +int mailbox_rsu_update(uint32_t *flash_offset) { return mailbox_send_cmd(MBOX_JOB_ID, MBOX_RSU_UPDATE, flash_offset, 2, 0, NULL, 0); } -int mailbox_hps_stage_notify(uint64_t execution_stage) +int mailbox_hps_stage_notify(uint32_t execution_stage) { return mailbox_send_cmd(MBOX_JOB_ID, MBOX_HPS_STAGE_NOTIFY, &execution_stage, 1, 0, NULL, 0); diff --git a/plat/intel/soc/common/socfpga_psci.c b/plat/intel/soc/common/socfpga_psci.c index d48fb5dd0..4b57b8f31 100644 --- a/plat/intel/soc/common/socfpga_psci.c +++ b/plat/intel/soc/common/socfpga_psci.c @@ -134,8 +134,13 @@ extern uint64_t intel_rsu_update_address; static void __dead2 socfpga_system_reset(void) { + uint32_t addr_buf[2]; + + memcpy(addr_buf, &intel_rsu_update_address, + sizeof(intel_rsu_update_address)); + if (intel_rsu_update_address) - mailbox_rsu_update(&intel_rsu_update_address); + mailbox_rsu_update(addr_buf); else mailbox_reset_cold(); diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c index 1c3d45bee..c1052ade2 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -61,7 +61,7 @@ struct fpga_config_info fpga_config_buffers[FPGA_CONFIG_BUFFER_SIZE]; static int intel_fpga_sdm_write_buffer(struct fpga_config_info *buffer) { - uint64_t args[3]; + uint32_t args[3]; while (max_blocks > 0 && buffer->size > buffer->size_written) { args[0] = (1<<8); @@ -385,7 +385,7 @@ static uint32_t intel_rsu_update(uint64_t update_address) return INTEL_SIP_SMC_STATUS_OK; } -static uint32_t intel_rsu_notify(uint64_t execution_stage) +static uint32_t intel_rsu_notify(uint32_t execution_stage) { if (mailbox_hps_stage_notify(execution_stage) < 0) return INTEL_SIP_SMC_STATUS_ERROR; @@ -404,7 +404,7 @@ static uint32_t intel_rsu_retry_counter(uint32_t *respbuf, uint32_t respbuf_sz, } /* Mailbox services */ -static uint32_t intel_mbox_send_cmd(uint32_t cmd, uint64_t *args, int len, +static uint32_t intel_mbox_send_cmd(uint32_t cmd, uint32_t *args, int len, int urgent, uint32_t *response, int resp_len, int *mbox_status, int *len_in_resp) @@ -542,7 +542,7 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, case INTEL_SIP_SMC_MBOX_SEND_CMD: x5 = SMC_GET_GP(handle, CTX_GPREG_X5); x6 = SMC_GET_GP(handle, CTX_GPREG_X6); - status = intel_mbox_send_cmd(x1, (uint64_t *)x2, x3, x4, + status = intel_mbox_send_cmd(x1, (uint32_t *)x2, x3, x4, (uint32_t *)x5, x6, &mbox_status, &len_in_resp); SMC_RET4(handle, status, mbox_status, x5, len_in_resp); -- cgit v1.2.3 From d7873bcd541b99a816c4ea6f1cce66858641f6fc Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Sat, 25 Jan 2020 00:58:35 +0000 Subject: imx: Use generic console_t data structure Since now the generic console_t structure holds the UART base address as well, let's use that generic location and drop the UART driver specific data structure at all. Change-Id: I058f793e4024fa7291e432f5be374a77faf16f36 Signed-off-by: Andre Przywara --- drivers/imx/uart/imx_uart.h | 7 +------ plat/imx/common/include/imx8_lpuart.h | 7 +------ plat/imx/common/include/imx_uart.h | 7 +------ plat/imx/imx7/common/imx7_bl2_el3_common.c | 4 ++-- plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c | 4 ++-- plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c | 2 +- plat/imx/imx8qm/imx8qm_bl31_setup.c | 2 +- plat/imx/imx8qx/imx8qx_bl31_setup.c | 2 +- 8 files changed, 10 insertions(+), 25 deletions(-) diff --git a/drivers/imx/uart/imx_uart.h b/drivers/imx/uart/imx_uart.h index 4f6d3de2e..a13302484 100644 --- a/drivers/imx/uart/imx_uart.h +++ b/drivers/imx/uart/imx_uart.h @@ -154,15 +154,10 @@ #ifndef __ASSEMBLER__ -typedef struct { - console_t console; - uintptr_t base; -} console_imx_uart_t; - int console_imx_uart_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud, - console_imx_uart_t *console); + console_t *console); #endif /*__ASSEMBLER__*/ #endif /* IMX_UART_H */ diff --git a/plat/imx/common/include/imx8_lpuart.h b/plat/imx/common/include/imx8_lpuart.h index 0ea284fdf..26470e040 100644 --- a/plat/imx/common/include/imx8_lpuart.h +++ b/plat/imx/common/include/imx8_lpuart.h @@ -54,13 +54,8 @@ #include -typedef struct { - console_t console; - uintptr_t base; -} console_lpuart_t; - int console_lpuart_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud, - console_lpuart_t *console); + console_t *console); #endif /*__ASSEMBLER__*/ #endif /* IMX8_LPUART_H */ diff --git a/plat/imx/common/include/imx_uart.h b/plat/imx/common/include/imx_uart.h index cc1b5318e..6c4d62f57 100644 --- a/plat/imx/common/include/imx_uart.h +++ b/plat/imx/common/include/imx_uart.h @@ -11,13 +11,8 @@ #ifndef __ASSEMBLER__ -typedef struct { - console_t console; - uintptr_t base; -} console_uart_t; - int console_imx_uart_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud, - console_uart_t *console); + console_t *console); #endif /*__ASSEMBLER__*/ #endif /* IMX_UART_H */ diff --git a/plat/imx/imx7/common/imx7_bl2_el3_common.c b/plat/imx/imx7/common/imx7_bl2_el3_common.c index a1e2aafd4..7f156e306 100644 --- a/plat/imx/imx7/common/imx7_bl2_el3_common.c +++ b/plat/imx/imx7/common/imx7_bl2_el3_common.c @@ -150,7 +150,7 @@ static void imx7_setup_wdog_clocks(void) void bl2_el3_early_platform_setup(u_register_t arg1, u_register_t arg2, u_register_t arg3, u_register_t arg4) { - static console_imx_uart_t console; + static console_t console; int console_scope = CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME; /* Initialize common components */ @@ -170,7 +170,7 @@ void bl2_el3_early_platform_setup(u_register_t arg1, u_register_t arg2, PLAT_IMX7_BOOT_UART_CLK_IN_HZ, PLAT_IMX7_CONSOLE_BAUDRATE, &console); - console_set_scope(&console.console, console_scope); + console_set_scope(&console, console_scope); /* Open handles to persistent storage */ plat_imx7_io_setup(); diff --git a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c index 4c5f4f0d1..40110d778 100644 --- a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c +++ b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c @@ -97,7 +97,7 @@ void bl31_tzc380_setup(void) void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { - static console_uart_t console; + static console_t console; int i; /* Enable CSU NS access permission */ @@ -114,7 +114,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, console_imx_uart_register(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ, IMX_CONSOLE_BAUDRATE, &console); /* This console is only used for boot stage */ - console_set_scope(&console.console, CONSOLE_FLAG_BOOT); + console_set_scope(&console, CONSOLE_FLAG_BOOT); /* * tell BL3-1 where the non-secure software image is located diff --git a/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c b/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c index a347389a2..05b59705f 100644 --- a/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c +++ b/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c @@ -133,7 +133,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, imx8m_caam_init(); #if DEBUG_CONSOLE - static console_uart_t console; + static console_t console; console_imx_uart_register(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ, IMX_CONSOLE_BAUDRATE, &console); diff --git a/plat/imx/imx8qm/imx8qm_bl31_setup.c b/plat/imx/imx8qm/imx8qm_bl31_setup.c index 9232cbc2d..cffb140fb 100644 --- a/plat/imx/imx8qm/imx8qm_bl31_setup.c +++ b/plat/imx/imx8qm/imx8qm_bl31_setup.c @@ -295,7 +295,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { #if DEBUG_CONSOLE - static console_lpuart_t console; + static console_t console; #endif if (sc_ipc_open(&ipc_handle, SC_IPC_BASE) != SC_ERR_NONE) panic(); diff --git a/plat/imx/imx8qx/imx8qx_bl31_setup.c b/plat/imx/imx8qx/imx8qx_bl31_setup.c index 58c82ce60..97d222787 100644 --- a/plat/imx/imx8qx/imx8qx_bl31_setup.c +++ b/plat/imx/imx8qx/imx8qx_bl31_setup.c @@ -255,7 +255,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { #if DEBUG_CONSOLE - static console_lpuart_t console; + static console_t console; #endif if (sc_ipc_open(&ipc_handle, SC_IPC_BASE) != SC_ERR_NONE) panic(); -- cgit v1.2.3 From 98964f0523d6c5dc5ee8e6bb8212ffc7df5efe14 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Sat, 25 Jan 2020 00:58:35 +0000 Subject: 16550: Use generic console_t data structure Since now the generic console_t structure holds the UART base address as well, let's use that generic location and drop the UART driver specific data structure at all. Change-Id: I5c2fe3b6a667acf80c808cfec4a64059a2c9c25f Signed-off-by: Andre Przywara --- drivers/ti/uart/aarch32/16550_console.S | 18 +++++++++--------- drivers/ti/uart/aarch64/16550_console.S | 18 +++++++++--------- include/drivers/ti/uart/uart_16550.h | 9 +-------- plat/allwinner/common/sunxi_bl31_setup.c | 2 +- plat/intel/soc/agilex/bl2_plat_setup.c | 2 +- plat/intel/soc/agilex/bl31_plat_setup.c | 2 +- plat/intel/soc/stratix10/bl2_plat_setup.c | 2 +- plat/intel/soc/stratix10/bl31_plat_setup.c | 2 +- plat/marvell/common/marvell_console.c | 14 ++++++-------- plat/mediatek/mt8173/bl31_plat_setup.c | 2 +- plat/mediatek/mt8183/bl31_plat_setup.c | 2 +- plat/nvidia/tegra/soc/t132/plat_setup.c | 4 ++-- plat/nvidia/tegra/soc/t186/plat_setup.c | 4 ++-- plat/nvidia/tegra/soc/t194/plat_setup.c | 2 +- plat/nvidia/tegra/soc/t210/plat_setup.c | 4 ++-- plat/rockchip/common/bl31_plat_setup.c | 2 +- plat/rockchip/common/sp_min_plat_setup.c | 2 +- plat/rpi/common/rpi3_common.c | 4 ++-- plat/ti/k3/common/k3_console.c | 2 +- 19 files changed, 44 insertions(+), 53 deletions(-) diff --git a/drivers/ti/uart/aarch32/16550_console.S b/drivers/ti/uart/aarch32/16550_console.S index 5cd9b30cd..bc0b3ab1c 100644 --- a/drivers/ti/uart/aarch32/16550_console.S +++ b/drivers/ti/uart/aarch32/16550_console.S @@ -91,7 +91,7 @@ endfunc console_16550_core_init /* ------------------------------------------------------- * int console_16550_register(uintptr_t baseaddr, * uint32_t clock, uint32_t baud, - * console_16550_t *console); + * console_t *console); * Function to initialize and register a new 16550 * console. Storage passed in for the console struct * *must* be persistent (i.e. not from the stack). @@ -101,7 +101,7 @@ endfunc console_16550_core_init * In: r0 - UART register base address * r1 - UART clock in Hz * r2 - Baud rate (ignored if r1 is 0) - * r3 - pointer to empty console_16550_t struct + * r3 - pointer to empty console_t struct * Out: return 1 on success, 0 on error * Clobber list : r0, r1, r2 * ------------------------------------------------------- @@ -111,7 +111,7 @@ func console_16550_register mov r4, r3 cmp r4, #0 beq register_fail - str r0, [r4, #CONSOLE_T_16550_BASE] + str r0, [r4, #CONSOLE_T_BASE] /* A clock rate of zero means to skip the initialisation. */ cmp r1, #0 @@ -167,7 +167,7 @@ func console_16550_core_putc endfunc console_16550_core_putc /* -------------------------------------------------------- - * int console_16550_putc(int c, console_16550_t *console) + * int console_16550_putc(int c, console_t *console) * Function to output a character over the console. It * returns the character printed on success or -1 on error. * In : r0 - character to be printed @@ -181,7 +181,7 @@ func console_16550_putc cmp r1, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr r1, [r1, #CONSOLE_T_16550_BASE] + ldr r1, [r1, #CONSOLE_T_BASE] b console_16550_core_putc endfunc console_16550_putc @@ -213,7 +213,7 @@ no_char: endfunc console_16550_core_getc /* --------------------------------------------- - * int console_16550_getc(console_16550_t *console) + * int console_16550_getc(console_t *console) * Function to get a character from the console. * It returns the character grabbed on success * or -1 on if no character is available. @@ -227,7 +227,7 @@ func console_16550_getc cmp r0, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr r0, [r0, #CONSOLE_T_16550_BASE] + ldr r0, [r0, #CONSOLE_T_BASE] b console_16550_core_getc endfunc console_16550_getc @@ -257,7 +257,7 @@ func console_16550_core_flush endfunc console_16550_core_flush /* --------------------------------------------- - * int console_16550_flush(console_pl011_t *console) + * int console_16550_flush(console_t *console) * Function to force a write of all buffered * data that hasn't been output. * In : r0 - pointer to console_t structure @@ -270,6 +270,6 @@ func console_16550_flush cmp r0, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr r0, [r0, #CONSOLE_T_16550_BASE] + ldr r0, [r0, #CONSOLE_T_BASE] b console_16550_core_flush endfunc console_16550_flush diff --git a/drivers/ti/uart/aarch64/16550_console.S b/drivers/ti/uart/aarch64/16550_console.S index 80c1b8646..064022798 100644 --- a/drivers/ti/uart/aarch64/16550_console.S +++ b/drivers/ti/uart/aarch64/16550_console.S @@ -88,7 +88,7 @@ endfunc console_16550_core_init /* ----------------------------------------------- * int console_16550_register(uintptr_t baseaddr, * uint32_t clock, uint32_t baud, - * console_16550_t *console); + * console_t *console); * Function to initialize and register a new 16550 * console. Storage passed in for the console struct * *must* be persistent (i.e. not from the stack). @@ -98,7 +98,7 @@ endfunc console_16550_core_init * In: x0 - UART register base address * w1 - UART clock in Hz * w2 - Baud rate (ignored if w1 is 0) - * x3 - pointer to empty console_16550_t struct + * x3 - pointer to empty console_t struct * Out: return 1 on success, 0 on error * Clobber list : x0, x1, x2, x6, x7, x14 * ----------------------------------------------- @@ -107,7 +107,7 @@ func console_16550_register mov x7, x30 mov x6, x3 cbz x6, register_fail - str x0, [x6, #CONSOLE_T_16550_BASE] + str x0, [x6, #CONSOLE_T_BASE] /* A clock rate of zero means to skip the initialisation. */ cbz w1, register_16550 @@ -161,7 +161,7 @@ func console_16550_core_putc endfunc console_16550_core_putc /* -------------------------------------------------------- - * int console_16550_putc(int c, console_16550_t *console) + * int console_16550_putc(int c, console_t *console) * Function to output a character over the console. It * returns the character printed on success or -1 on error. * In : w0 - character to be printed @@ -175,7 +175,7 @@ func console_16550_putc cmp x1, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr x1, [x1, #CONSOLE_T_16550_BASE] + ldr x1, [x1, #CONSOLE_T_BASE] b console_16550_core_putc endfunc console_16550_putc @@ -206,7 +206,7 @@ no_char: endfunc console_16550_core_getc /* --------------------------------------------- - * int console_16550_getc(console_16550_t *console) + * int console_16550_getc(console_t *console) * Function to get a character from the console. * It returns the character grabbed on success * or -1 on if no character is available. @@ -220,7 +220,7 @@ func console_16550_getc cmp x1, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr x0, [x0, #CONSOLE_T_16550_BASE] + ldr x0, [x0, #CONSOLE_T_BASE] b console_16550_core_getc endfunc console_16550_getc @@ -250,7 +250,7 @@ func console_16550_core_flush endfunc console_16550_core_flush /* --------------------------------------------- - * int console_16550_flush(console_pl011_t *console) + * int console_16550_flush(console_t *console) * Function to force a write of all buffered * data that hasn't been output. * In : x0 - pointer to console_t structure @@ -263,6 +263,6 @@ func console_16550_flush cmp x0, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr x0, [x0, #CONSOLE_T_16550_BASE] + ldr x0, [x0, #CONSOLE_T_BASE] b console_16550_core_flush endfunc console_16550_flush diff --git a/include/drivers/ti/uart/uart_16550.h b/include/drivers/ti/uart/uart_16550.h index 2b95fa33a..bddd9970c 100644 --- a/include/drivers/ti/uart/uart_16550.h +++ b/include/drivers/ti/uart/uart_16550.h @@ -71,17 +71,10 @@ #define UARTLSR_RDR_BIT (0) /* Rx Data Ready Bit */ #define UARTLSR_RDR (1 << UARTLSR_RDR_BIT) /* Rx Data Ready */ -#define CONSOLE_T_16550_BASE CONSOLE_T_DRVDATA - #ifndef __ASSEMBLER__ #include -typedef struct { - console_t console; - uintptr_t base; -} console_16550_t; - /* * Initialize a new 16550 console instance and register it with the console * framework. The |console| pointer must point to storage that will be valid @@ -94,7 +87,7 @@ typedef struct { * case as well. */ int console_16550_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud, - console_16550_t *console); + console_t *console); #endif /*__ASSEMBLER__*/ diff --git a/plat/allwinner/common/sunxi_bl31_setup.c b/plat/allwinner/common/sunxi_bl31_setup.c index a24527c5d..e836a345b 100644 --- a/plat/allwinner/common/sunxi_bl31_setup.c +++ b/plat/allwinner/common/sunxi_bl31_setup.c @@ -28,7 +28,7 @@ static entry_point_info_t bl32_image_ep_info; static entry_point_info_t bl33_image_ep_info; -static console_16550_t console; +static console_t console; static const gicv2_driver_data_t sunxi_gic_data = { .gicd_base = SUNXI_GICD_BASE, diff --git a/plat/intel/soc/agilex/bl2_plat_setup.c b/plat/intel/soc/agilex/bl2_plat_setup.c index f32820777..468b356b5 100644 --- a/plat/intel/soc/agilex/bl2_plat_setup.c +++ b/plat/intel/soc/agilex/bl2_plat_setup.c @@ -51,7 +51,7 @@ boot_source_type boot_source = BOOT_SOURCE; void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1, u_register_t x2, u_register_t x4) { - static console_16550_t console; + static console_t console; handoff reverse_handoff_ptr; generic_delay_timer_init(); diff --git a/plat/intel/soc/agilex/bl31_plat_setup.c b/plat/intel/soc/agilex/bl31_plat_setup.c index 4b1144095..6f32aff4a 100644 --- a/plat/intel/soc/agilex/bl31_plat_setup.c +++ b/plat/intel/soc/agilex/bl31_plat_setup.c @@ -37,7 +37,7 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { - static console_16550_t console; + static console_t console; console_16550_register(PLAT_UART0_BASE, PLAT_UART_CLOCK, PLAT_BAUDRATE, &console); diff --git a/plat/intel/soc/stratix10/bl2_plat_setup.c b/plat/intel/soc/stratix10/bl2_plat_setup.c index 78ca253e7..d0c8e4c7b 100644 --- a/plat/intel/soc/stratix10/bl2_plat_setup.c +++ b/plat/intel/soc/stratix10/bl2_plat_setup.c @@ -50,7 +50,7 @@ boot_source_type boot_source = BOOT_SOURCE; void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1, u_register_t x2, u_register_t x4) { - static console_16550_t console; + static console_t console; handoff reverse_handoff_ptr; generic_delay_timer_init(); diff --git a/plat/intel/soc/stratix10/bl31_plat_setup.c b/plat/intel/soc/stratix10/bl31_plat_setup.c index 4c3123815..5813c8f8c 100644 --- a/plat/intel/soc/stratix10/bl31_plat_setup.c +++ b/plat/intel/soc/stratix10/bl31_plat_setup.c @@ -45,7 +45,7 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { - static console_16550_t console; + static console_t console; console_16550_register(PLAT_UART0_BASE, PLAT_UART_CLOCK, PLAT_BAUDRATE, &console); diff --git a/plat/marvell/common/marvell_console.c b/plat/marvell/common/marvell_console.c index 22c5eb3af..33931afda 100644 --- a/plat/marvell/common/marvell_console.c +++ b/plat/marvell/common/marvell_console.c @@ -20,8 +20,8 @@ static console_a3700_t marvell_runtime_console; #else #include -static console_16550_t marvell_boot_console; -static console_16550_t marvell_runtime_console; +static console_t marvell_boot_console; +static console_t marvell_runtime_console; #endif /******************************************************************************* @@ -50,15 +50,14 @@ void marvell_console_boot_init(void) panic(); } - console_set_scope(&marvell_boot_console.console, - CONSOLE_FLAG_BOOT); + console_set_scope(&marvell_boot_console, CONSOLE_FLAG_BOOT); } void marvell_console_boot_end(void) { (void)console_flush(); - (void)console_unregister(&marvell_boot_console.console); + (void)console_unregister(&marvell_boot_console); } /* Initialize the runtime console */ @@ -77,13 +76,12 @@ void marvell_console_runtime_init(void) if (rc == 0) panic(); - console_set_scope(&marvell_runtime_console.console, - CONSOLE_FLAG_RUNTIME); + console_set_scope(&marvell_runtime_console, CONSOLE_FLAG_RUNTIME); } void marvell_console_runtime_end(void) { (void)console_flush(); - (void)console_unregister(&marvell_runtime_console.console); + (void)console_unregister(&marvell_runtime_console); } diff --git a/plat/mediatek/mt8173/bl31_plat_setup.c b/plat/mediatek/mt8173/bl31_plat_setup.c index 73a479b50..bd7d0b0ee 100644 --- a/plat/mediatek/mt8173/bl31_plat_setup.c +++ b/plat/mediatek/mt8173/bl31_plat_setup.c @@ -100,7 +100,7 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { - static console_16550_t console; + static console_t console; console_16550_register(MT8173_UART0_BASE, MT8173_UART_CLOCK, MT8173_BAUDRATE, &console); diff --git a/plat/mediatek/mt8183/bl31_plat_setup.c b/plat/mediatek/mt8183/bl31_plat_setup.c index 8204d7717..e96b4ad0c 100644 --- a/plat/mediatek/mt8183/bl31_plat_setup.c +++ b/plat/mediatek/mt8183/bl31_plat_setup.c @@ -112,7 +112,7 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { - static console_16550_t console; + static console_t console; params_early_setup(arg1); diff --git a/plat/nvidia/tegra/soc/t132/plat_setup.c b/plat/nvidia/tegra/soc/t132/plat_setup.c index 4bfc2de0e..43acdd642 100644 --- a/plat/nvidia/tegra/soc/t132/plat_setup.c +++ b/plat/nvidia/tegra/soc/t132/plat_setup.c @@ -92,7 +92,7 @@ static uint32_t tegra132_uart_addresses[TEGRA132_MAX_UART_PORTS + 1] = { ******************************************************************************/ void plat_enable_console(int32_t id) { - static console_16550_t uart_console; + static console_t uart_console; uint32_t console_clock; if ((id > 0) && (id < TEGRA132_MAX_UART_PORTS)) { @@ -109,7 +109,7 @@ void plat_enable_console(int32_t id) console_clock, TEGRA_CONSOLE_BAUDRATE, &uart_console); - console_set_scope(&uart_console.console, CONSOLE_FLAG_BOOT | + console_set_scope(&uart_console, CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH); } } diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c index 06a328427..7028bfc5d 100644 --- a/plat/nvidia/tegra/soc/t186/plat_setup.c +++ b/plat/nvidia/tegra/soc/t186/plat_setup.c @@ -150,7 +150,7 @@ static uint32_t tegra186_uart_addresses[TEGRA186_MAX_UART_PORTS + 1] = { ******************************************************************************/ void plat_enable_console(int32_t id) { - static console_16550_t uart_console; + static console_t uart_console; uint32_t console_clock; if ((id > 0) && (id < TEGRA186_MAX_UART_PORTS)) { @@ -167,7 +167,7 @@ void plat_enable_console(int32_t id) console_clock, TEGRA_CONSOLE_BAUDRATE, &uart_console); - console_set_scope(&uart_console.console, CONSOLE_FLAG_BOOT | + console_set_scope(&uart_console, CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH); } } diff --git a/plat/nvidia/tegra/soc/t194/plat_setup.c b/plat/nvidia/tegra/soc/t194/plat_setup.c index 3640ade0a..7f2b00d1b 100644 --- a/plat/nvidia/tegra/soc/t194/plat_setup.c +++ b/plat/nvidia/tegra/soc/t194/plat_setup.c @@ -174,7 +174,7 @@ void plat_enable_console(int32_t id) CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH); } #else - static console_16550_t uart_console; + static console_t uart_console; if ((id > 0) && (id < TEGRA194_MAX_UART_PORTS)) { /* diff --git a/plat/nvidia/tegra/soc/t210/plat_setup.c b/plat/nvidia/tegra/soc/t210/plat_setup.c index c32772de8..7afbe0d9a 100644 --- a/plat/nvidia/tegra/soc/t210/plat_setup.c +++ b/plat/nvidia/tegra/soc/t210/plat_setup.c @@ -119,7 +119,7 @@ static uint32_t tegra210_uart_addresses[TEGRA210_MAX_UART_PORTS + 1] = { ******************************************************************************/ void plat_enable_console(int32_t id) { - static console_16550_t uart_console; + static console_t uart_console; uint32_t console_clock; if ((id > 0) && (id < TEGRA210_MAX_UART_PORTS)) { @@ -136,7 +136,7 @@ void plat_enable_console(int32_t id) console_clock, TEGRA_CONSOLE_BAUDRATE, &uart_console); - console_set_scope(&uart_console.console, CONSOLE_FLAG_BOOT | + console_set_scope(&uart_console, CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH); } } diff --git a/plat/rockchip/common/bl31_plat_setup.c b/plat/rockchip/common/bl31_plat_setup.c index c4a03592e..98ef415c9 100644 --- a/plat/rockchip/common/bl31_plat_setup.c +++ b/plat/rockchip/common/bl31_plat_setup.c @@ -57,7 +57,7 @@ void params_early_setup(u_register_t plat_param_from_bl2) void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { - static console_16550_t console; + static console_t console; params_early_setup(arg1); diff --git a/plat/rockchip/common/sp_min_plat_setup.c b/plat/rockchip/common/sp_min_plat_setup.c index 6d15075f2..0237b167f 100644 --- a/plat/rockchip/common/sp_min_plat_setup.c +++ b/plat/rockchip/common/sp_min_plat_setup.c @@ -52,7 +52,7 @@ unsigned int plat_is_my_cpu_primary(void); void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { - static console_16550_t console; + static console_t console; params_early_setup(arg1); diff --git a/plat/rpi/common/rpi3_common.c b/plat/rpi/common/rpi3_common.c index ff3369427..27281f2ba 100644 --- a/plat/rpi/common/rpi3_common.c +++ b/plat/rpi/common/rpi3_common.c @@ -102,7 +102,7 @@ static const mmap_region_t plat_rpi3_mmap[] = { /******************************************************************************* * Function that sets up the console ******************************************************************************/ -static console_16550_t rpi3_console; +static console_t rpi3_console; void rpi3_console_init(unsigned int base_clk_rate) { @@ -123,7 +123,7 @@ void rpi3_console_init(unsigned int base_clk_rate) panic(); } - console_set_scope(&rpi3_console.console, console_scope); + console_set_scope(&rpi3_console, console_scope); } /******************************************************************************* diff --git a/plat/ti/k3/common/k3_console.c b/plat/ti/k3/common/k3_console.c index ba0ddacec..8c44c17e2 100644 --- a/plat/ti/k3/common/k3_console.c +++ b/plat/ti/k3/common/k3_console.c @@ -13,7 +13,7 @@ void bl31_console_setup(void) { - static console_16550_t console; + static console_t console; /* Initialize the console to provide early debug support */ console_16550_register(K3_USART_BASE, K3_USART_CLK_SPEED, -- cgit v1.2.3 From 3968bc08abb3f43a03175ec7d30b797f253c0caa Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Sat, 25 Jan 2020 00:58:35 +0000 Subject: a3700: Use generic console_t data structure Since now the generic console_t structure holds the UART base address as well, let's use that generic location and drop the UART driver specific data structure at all. Change-Id: I89c3ab2ed85ab941d8b38ced48474feb4aaa8b7e Signed-off-by: Andre Przywara --- drivers/marvell/uart/a3700_console.S | 18 +++++++++--------- include/drivers/marvell/uart/a3700_console.h | 9 +-------- plat/marvell/common/marvell_console.c | 4 ++-- 3 files changed, 12 insertions(+), 19 deletions(-) diff --git a/drivers/marvell/uart/a3700_console.S b/drivers/marvell/uart/a3700_console.S index da1ce351c..ecd494ca7 100644 --- a/drivers/marvell/uart/a3700_console.S +++ b/drivers/marvell/uart/a3700_console.S @@ -110,7 +110,7 @@ endfunc console_a3700_core_init .globl console_a3700_register /* ----------------------------------------------- - * int console_a3700_register(console_16550_t *console, + * int console_a3700_register(console_t *console, uintptr_t base, uint32_t clk, uint32_t baud) * Function to initialize and register a new a3700 * console. Storage passed in for the console struct @@ -118,7 +118,7 @@ endfunc console_a3700_core_init * In: x0 - UART register base address * w1 - UART clock in Hz * w2 - Baud rate - * x3 - pointer to empty console_a3700_t struct + * x3 - pointer to empty console_t struct * Out: return 1 on success, 0 on error * Clobber list : x0, x1, x2, x6, x7, x14 * ----------------------------------------------- @@ -127,7 +127,7 @@ func console_a3700_register mov x7, x30 mov x6, x3 cbz x6, register_fail - str x0, [x6, #CONSOLE_T_A3700_BASE] + str x0, [x6, #CONSOLE_T_BASE] bl console_a3700_core_init cbz x0, register_fail @@ -178,7 +178,7 @@ putc_error: endfunc console_a3700_core_putc /* -------------------------------------------------------- - * int console_a3700_putc(int c, console_a3700_t *console) + * int console_a3700_putc(int c, console_t *console) * Function to output a character over the console. It * returns the character printed on success or -1 on error. * In : w0 - character to be printed @@ -188,7 +188,7 @@ endfunc console_a3700_core_putc * -------------------------------------------------------- */ func console_a3700_putc - ldr x1, [x1, #CONSOLE_T_A3700_BASE] + ldr x1, [x1, #CONSOLE_T_BASE] b console_a3700_core_putc endfunc console_a3700_putc @@ -208,7 +208,7 @@ func console_a3700_core_getc endfunc console_a3700_core_getc /* --------------------------------------------- - * int console_a3700_getc(console_a3700_t *console) + * int console_a3700_getc(console_t *console) * Function to get a character from the console. * It returns the character grabbed on success * or -1 on if no character is available. @@ -218,7 +218,7 @@ endfunc console_a3700_core_getc * --------------------------------------------- */ func console_a3700_getc - ldr x0, [x0, #CONSOLE_T_A3700_BASE] + ldr x0, [x0, #CONSOLE_T_BASE] b console_a3700_core_getc endfunc console_a3700_getc @@ -237,7 +237,7 @@ func console_a3700_core_flush endfunc console_a3700_core_flush /* --------------------------------------------- - * int console_a3700_flush(console_a3700_t *console) + * int console_a3700_flush(console_t *console) * Function to force a write of all buffered * data that hasn't been output. * In : x0 - pointer to console_t structure @@ -246,7 +246,7 @@ endfunc console_a3700_core_flush * --------------------------------------------- */ func console_a3700_flush - ldr x0, [x0, #CONSOLE_T_A3700_BASE] + ldr x0, [x0, #CONSOLE_T_BASE] b console_a3700_core_flush endfunc console_a3700_flush diff --git a/include/drivers/marvell/uart/a3700_console.h b/include/drivers/marvell/uart/a3700_console.h index 517f01a8f..5e3ab0515 100644 --- a/include/drivers/marvell/uart/a3700_console.h +++ b/include/drivers/marvell/uart/a3700_console.h @@ -54,17 +54,10 @@ #define UART_CTRL_TXFIFO_RESET (1 << 15) #define UARTLSR_TXFIFOEMPTY (1 << 6) -#define CONSOLE_T_A3700_BASE CONSOLE_T_DRVDATA - #ifndef __ASSEMBLER__ #include -typedef struct { - console_t console; - uintptr_t base; -} console_a3700_t; - /* * Initialize a new a3700 console instance and register it with the console * framework. The |console| pointer must point to storage that will be valid @@ -72,7 +65,7 @@ typedef struct { * Its contents will be reinitialized from scratch. */ int console_a3700_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud, - console_a3700_t *console); + console_t *console); #endif /*__ASSEMBLER__*/ diff --git a/plat/marvell/common/marvell_console.c b/plat/marvell/common/marvell_console.c index 33931afda..b57b84f3f 100644 --- a/plat/marvell/common/marvell_console.c +++ b/plat/marvell/common/marvell_console.c @@ -15,8 +15,8 @@ #ifdef PLAT_a3700 #include -static console_a3700_t marvell_boot_console; -static console_a3700_t marvell_runtime_console; +static console_t marvell_boot_console; +static console_t marvell_runtime_console; #else #include -- cgit v1.2.3 From c01ee06b53451d8792958b30b8ebce3e0e930359 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Sat, 25 Jan 2020 00:58:35 +0000 Subject: rcar: Use generic console_t data structure Since now the generic console_t structure holds the UART base address as well, let's use that generic location and drop the UART driver specific data structure at all. Change-Id: I836e26ff1771abf21fd460d0ee40e90a452e9b43 Signed-off-by: Andre Przywara --- drivers/renesas/rcar/console/rcar_console.S | 10 +++++----- drivers/renesas/rcar/scif/scif.S | 6 +++--- include/drivers/renesas/rcar/console/console.h | 9 +-------- plat/renesas/rcar/rcar_common.c | 8 ++++---- 4 files changed, 13 insertions(+), 20 deletions(-) diff --git a/drivers/renesas/rcar/console/rcar_console.S b/drivers/renesas/rcar/console/rcar_console.S index 859efeceb..4d006b703 100644 --- a/drivers/renesas/rcar/console/rcar_console.S +++ b/drivers/renesas/rcar/console/rcar_console.S @@ -20,14 +20,14 @@ /* ----------------------------------------------- * int console_rcar_register( * uintptr_t base, uint32_t clk, uint32_t baud, - * console_rcar_t *console) + * console_t *console) * Function to initialize and register a new rcar * console. Storage passed in for the console struct * *must* be persistent (i.e. not from the stack). * In: x0 - UART register base address * w1 - UART clock in Hz * w2 - Baud rate - * x3 - pointer to empty console_rcar_t struct + * x3 - pointer to empty console_t struct * Out: return 1 on success, 0 on error * Clobber list : x0, x1, x2, x6, x7, x14 * ----------------------------------------------- @@ -36,7 +36,7 @@ func console_rcar_register mov x7, x30 mov x6, x3 cbz x6, register_fail - str x0, [x6, #CONSOLE_T_RCAR_BASE] + str x0, [x6, #CONSOLE_T_BASE] bl rcar_log_init cbz x0, register_fail @@ -68,11 +68,11 @@ func console_rcar_init endfunc console_rcar_init /* -------------------------------------------------------- - * int console_rcar_putc(int c, console_rcar_t *console) + * int console_rcar_putc(int c, console_t *console) * Function to output a character over the console. It * returns the character printed on success or -1 on error. * In : w0 - character to be printed - * x1 - pointer to console_rcar_t structure + * x1 - pointer to console_t structure * Out : return -1 on error else return character. * Clobber list : x2 * -------------------------------------------------------- diff --git a/drivers/renesas/rcar/scif/scif.S b/drivers/renesas/rcar/scif/scif.S index 8309bb26e..064aba471 100644 --- a/drivers/renesas/rcar/scif/scif.S +++ b/drivers/renesas/rcar/scif/scif.S @@ -126,14 +126,14 @@ /* ----------------------------------------------- * int console_rcar_register( * uintptr_t base, uint32_t clk, uint32_t baud, - * console_rcar_t *console) + * console_t *console) * Function to initialize and register a new rcar * console. Storage passed in for the console struct * *must* be persistent (i.e. not from the stack). * In: x0 - UART register base address * w1 - UART clock in Hz * w2 - Baud rate - * x3 - pointer to empty console_rcar_t struct + * x3 - pointer to empty console_t struct * Out: return 1 on success, 0 on error * Clobber list : x0, x1, x2, x6, x7, x14 * ----------------------------------------------- @@ -142,7 +142,7 @@ func console_rcar_register mov x7, x30 mov x6, x3 cbz x6, register_fail - str x0, [x6, #CONSOLE_T_RCAR_BASE] + str x0, [x6, #CONSOLE_T_BASE] bl console_rcar_init diff --git a/include/drivers/renesas/rcar/console/console.h b/include/drivers/renesas/rcar/console/console.h index 0e4ed8f35..7d5b5d3ce 100644 --- a/include/drivers/renesas/rcar/console/console.h +++ b/include/drivers/renesas/rcar/console/console.h @@ -7,17 +7,10 @@ #ifndef RCAR_PRINTF_H #define RCAR_PRINTF_H -#define CONSOLE_T_RCAR_BASE CONSOLE_T_DRVDATA - #ifndef __ASSEMBLER__ #include -typedef struct { - console_t console; - uintptr_t base; -} console_rcar_t; - /* * Initialize a new rcar console instance and register it with the console * framework. The |console| pointer must point to storage that will be valid @@ -25,7 +18,7 @@ typedef struct { * Its contents will be reinitialized from scratch. */ int console_rcar_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud, - console_rcar_t *console); + console_t *console); #endif /*__ASSEMBLER__*/ diff --git a/plat/renesas/rcar/rcar_common.c b/plat/renesas/rcar/rcar_common.c index 4ea753f2d..dec7229b3 100644 --- a/plat/renesas/rcar/rcar_common.c +++ b/plat/renesas/rcar/rcar_common.c @@ -70,8 +70,8 @@ void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie, #include -static console_rcar_t rcar_boot_console; -static console_rcar_t rcar_runtime_console; +static console_t rcar_boot_console; +static console_t rcar_runtime_console; void rcar_console_boot_init(void) { @@ -81,7 +81,7 @@ void rcar_console_boot_init(void) if (!ret) panic(); - console_set_scope(&rcar_boot_console.console, CONSOLE_FLAG_BOOT); + console_set_scope(&rcar_boot_console, CONSOLE_FLAG_BOOT); } void rcar_console_boot_end(void) @@ -96,7 +96,7 @@ void rcar_console_runtime_init(void) if (!ret) panic(); - console_set_scope(&rcar_boot_console.console, CONSOLE_FLAG_RUNTIME); + console_set_scope(&rcar_boot_console, CONSOLE_FLAG_RUNTIME); } void rcar_console_runtime_end(void) -- cgit v1.2.3 From c10db6deb1867d79c843391b29866a8119bc85b3 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Sat, 25 Jan 2020 00:58:35 +0000 Subject: stm32: Use generic console_t data structure Since now the generic console_t structure holds the UART base address as well, let's use that generic location and drop the UART driver specific data structure at all. Change-Id: Iea6ca26ff4903c33f0fad27fec96fdbabd4e0a91 Signed-off-by: Andre Przywara --- drivers/st/uart/aarch32/stm32_console.S | 14 +++++++------- include/drivers/st/stm32_console.h | 9 +-------- plat/st/stm32mp1/bl2_plat_setup.c | 4 ++-- plat/st/stm32mp1/sp_min/sp_min_setup.c | 4 ++-- 4 files changed, 12 insertions(+), 19 deletions(-) diff --git a/drivers/st/uart/aarch32/stm32_console.S b/drivers/st/uart/aarch32/stm32_console.S index ca3c1f618..0ed37d1bd 100644 --- a/drivers/st/uart/aarch32/stm32_console.S +++ b/drivers/st/uart/aarch32/stm32_console.S @@ -91,14 +91,14 @@ endfunc console_stm32_core_init /* ------------------------------------------------------- * int console_stm32_register(uintptr_t baseaddr, * uint32_t clock, uint32_t baud, - * struct console_stm32 *console); + * console_t *console); * Function to initialize and register a new STM32 * console. Storage passed in for the console struct * *must* be persistent (i.e. not from the stack). * In: r0 - UART register base address * r1 - UART clock in Hz * r2 - Baud rate - * r3 - pointer to empty console_stm32 struct + * r3 - pointer to empty console_t struct * Out: return 1 on success, 0 on error * Clobber list : r0, r1, r2 * ------------------------------------------------------- @@ -108,7 +108,7 @@ func console_stm32_register mov r4, r3 cmp r4, #0 beq register_fail - str r0, [r4, #CONSOLE_T_STM32_BASE] + str r0, [r4, #CONSOLE_T_BASE] bl console_stm32_core_init cmp r0, #0 @@ -157,7 +157,7 @@ putc_error: endfunc console_stm32_core_putc /* ------------------------------------------------------------ - * int console_stm32_putc(int c, struct console_stm32 *console) + * int console_stm32_putc(int c, console_t *console) * Function to output a character over the console. It * returns the character printed on success or -1 on error. * In: r0 - character to be printed @@ -171,7 +171,7 @@ func console_stm32_putc cmp r1, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr r1, [r1, #CONSOLE_T_STM32_BASE] + ldr r1, [r1, #CONSOLE_T_BASE] b console_stm32_core_putc endfunc console_stm32_putc @@ -219,7 +219,7 @@ flush_error: endfunc console_stm32_core_flush /* ------------------------------------------------------ - * int console_stm32_flush(struct console_stm32 *console) + * int console_stm32_flush(console_t *console) * Function to force a write of all buffered * data that hasn't been output. * In : r0 - pointer to console_t structure @@ -232,6 +232,6 @@ func console_stm32_flush cmp r0, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr r0, [r0, #CONSOLE_T_STM32_BASE] + ldr r0, [r0, #CONSOLE_T_BASE] b console_stm32_core_flush endfunc console_stm32_flush diff --git a/include/drivers/st/stm32_console.h b/include/drivers/st/stm32_console.h index a2ad87cb5..8d9187d2a 100644 --- a/include/drivers/st/stm32_console.h +++ b/include/drivers/st/stm32_console.h @@ -9,17 +9,10 @@ #include -#define CONSOLE_T_STM32_BASE CONSOLE_T_DRVDATA - #ifndef __ASSEMBLER__ #include -struct console_stm32 { - console_t console; - uintptr_t base; -}; - /* * Initialize a new STM32 console instance and register it with the console * framework. The |console| pointer must point to storage that will be valid @@ -27,7 +20,7 @@ struct console_stm32 { * Its contents will be reinitialized from scratch. */ int console_stm32_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud, - struct console_stm32 *console); + console_t *console); #endif /*__ASSEMBLER__*/ diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c index d9e29b4e8..024dbe076 100644 --- a/plat/st/stm32mp1/bl2_plat_setup.c +++ b/plat/st/stm32mp1/bl2_plat_setup.c @@ -31,7 +31,7 @@ #include #include -static struct console_stm32 console; +static console_t console; static struct stm32mp_auth_ops stm32mp1_auth_ops; static void print_reset_reason(void) @@ -273,7 +273,7 @@ void bl2_el3_plat_arch_setup(void) panic(); } - console_set_scope(&console.console, CONSOLE_FLAG_BOOT | + console_set_scope(&console, CONSOLE_FLAG_BOOT | CONSOLE_FLAG_CRASH | CONSOLE_FLAG_TRANSLATE_CRLF); stm32mp_print_cpuinfo(); diff --git a/plat/st/stm32mp1/sp_min/sp_min_setup.c b/plat/st/stm32mp1/sp_min/sp_min_setup.c index e10dfbfc0..4e74c275d 100644 --- a/plat/st/stm32mp1/sp_min/sp_min_setup.c +++ b/plat/st/stm32mp1/sp_min/sp_min_setup.c @@ -35,7 +35,7 @@ ******************************************************************************/ static entry_point_info_t bl33_image_ep_info; -static struct console_stm32 console; +static console_t console; /******************************************************************************* * Interrupt handler for FIQ (secure IRQ) @@ -142,7 +142,7 @@ void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1, #ifdef DEBUG console_flags |= CONSOLE_FLAG_RUNTIME; #endif - console_set_scope(&console.console, console_flags); + console_set_scope(&console, console_flags); } } -- cgit v1.2.3 From 9536a25e03e554afbb273583f24ca44c6ad889fd Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Sat, 25 Jan 2020 00:58:35 +0000 Subject: LS 16550: Use generic console_t data structure Since now the generic console_t structure holds the UART base address as well, let's use that generic location and drop the UART driver specific data structure at all. Change-Id: Ifd6aff1064ba1c3c029cdd8a83f715f7a9976db5 Signed-off-by: Andre Przywara --- plat/layerscape/common/aarch64/ls_console.S | 18 +++++++++--------- plat/layerscape/common/include/ls_16550.h | 9 +-------- plat/layerscape/common/ls_bl1_setup.c | 2 +- plat/layerscape/common/ls_bl2_setup.c | 2 +- plat/layerscape/common/ls_bl31_setup.c | 4 ++-- plat/layerscape/common/tsp/ls_tsp_setup.c | 2 +- plat/nvidia/tegra/soc/t194/plat_setup.c | 4 ++-- 7 files changed, 17 insertions(+), 24 deletions(-) diff --git a/plat/layerscape/common/aarch64/ls_console.S b/plat/layerscape/common/aarch64/ls_console.S index f8948b4ab..c1bd3f731 100644 --- a/plat/layerscape/common/aarch64/ls_console.S +++ b/plat/layerscape/common/aarch64/ls_console.S @@ -81,7 +81,7 @@ endfunc console_ls_16550_core_init .globl console_ls_16550_register /* ----------------------------------------------- - * int console_ls_16550_register(console_ls_16550_t *console, + * int console_ls_16550_register(console_t *console, * uintptr_t base, uint32_t clk, uint32_t baud) * Function to initialize and register a new 16550 * console. Storage passed in for the console struct @@ -89,7 +89,7 @@ endfunc console_ls_16550_core_init * In: x0 - UART register base address * w1 - UART clock in Hz * w2 - Baud rate - * x3 - pointer to empty console_ls_16550_t struct + * x3 - pointer to empty console_t struct * Out: return 1 on success, 0 on error * Clobber list : x0, x1, x2, x6, x7, x14 * ----------------------------------------------- @@ -98,7 +98,7 @@ func console_ls_16550_register mov x7, x30 mov x6, x3 cbz x6, register_fail - str x0, [x6, #CONSOLE_T_16550_BASE] + str x0, [x6, #CONSOLE_T_BASE] bl console_ls_16550_core_init cbz x0, register_fail @@ -150,7 +150,7 @@ func console_ls_16550_core_putc endfunc console_ls_16550_core_putc /* -------------------------------------------------------- - * int console_16550_putc(int c, console_ls_16550_t *console) + * int console_16550_putc(int c, console_t *console) * Function to output a character over the console. It * returns the character printed on success or -1 on error. * In : w0 - character to be printed @@ -164,7 +164,7 @@ func console_ls_16550_putc cmp x1, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr x1, [x1, #CONSOLE_T_16550_BASE] + ldr x1, [x1, #CONSOLE_T_BASE] b console_ls_16550_core_putc endfunc console_ls_16550_putc @@ -195,7 +195,7 @@ no_char: endfunc console_ls_16550_core_getc /* --------------------------------------------- - * int console_ls_16550_getc(console_ls_16550_t *console) + * int console_ls_16550_getc(console_t *console) * Function to get a character from the console. * It returns the character grabbed on success * or -1 on if no character is available. @@ -209,7 +209,7 @@ func console_ls_16550_getc cmp x1, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr x0, [x0, #CONSOLE_T_16550_BASE] + ldr x0, [x0, #CONSOLE_T_BASE] b console_ls_16550_core_getc endfunc console_ls_16550_getc @@ -239,7 +239,7 @@ func console_ls_16550_core_flush endfunc console_ls_16550_core_flush /* --------------------------------------------- - * int console_ls_16550_flush(console_ls_16550_t *console) + * int console_ls_16550_flush(console_t *console) * Function to force a write of all buffered * data that hasn't been output. * In : x0 - pointer to console_t structure @@ -252,6 +252,6 @@ func console_ls_16550_flush cmp x0, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr x0, [x0, #CONSOLE_T_16550_BASE] + ldr x0, [x0, #CONSOLE_T_BASE] b console_ls_16550_core_flush endfunc console_ls_16550_flush diff --git a/plat/layerscape/common/include/ls_16550.h b/plat/layerscape/common/include/ls_16550.h index cb4514f3f..95a64ad34 100644 --- a/plat/layerscape/common/include/ls_16550.h +++ b/plat/layerscape/common/include/ls_16550.h @@ -61,17 +61,10 @@ #define UARTLSR_OVRF (1 << 2) /* Rx Overrun Error */ #define UARTLSR_RDR (1 << 2) /* Rx Data Ready */ -#define CONSOLE_T_16550_BASE CONSOLE_T_DRVDATA - #ifndef __ASSEMBLER__ #include -typedef struct { - console_t console; - uintptr_t base; -} console_ls_16550_t; - /* * Initialize a new 16550 console instance and register it with the console * framework. The |console| pointer must point to storage that will be valid @@ -79,7 +72,7 @@ typedef struct { * Its contents will be reinitialized from scratch. */ int console_ls_16550_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud, - console_ls_16550_t *console); + console_t *console); #endif /*__ASSEMBLER__*/ diff --git a/plat/layerscape/common/ls_bl1_setup.c b/plat/layerscape/common/ls_bl1_setup.c index fff065efd..fa69be2e6 100644 --- a/plat/layerscape/common/ls_bl1_setup.c +++ b/plat/layerscape/common/ls_bl1_setup.c @@ -23,7 +23,7 @@ meminfo_t *bl1_plat_sec_mem_layout(void) ******************************************************************************/ void ls_bl1_early_platform_setup(void) { - static console_ls_16550_t console; + static console_t console; #if !LS1043_DISABLE_TRUSTED_WDOG /* TODO: Enable watchdog */ diff --git a/plat/layerscape/common/ls_bl2_setup.c b/plat/layerscape/common/ls_bl2_setup.c index 35f42e1fb..6ca66bd47 100644 --- a/plat/layerscape/common/ls_bl2_setup.c +++ b/plat/layerscape/common/ls_bl2_setup.c @@ -23,7 +23,7 @@ static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE); ******************************************************************************/ void ls_bl2_early_platform_setup(meminfo_t *mem_layout) { - static console_ls_16550_t console; + static console_t console; /* Initialize the console to provide early debug support */ console_ls_16550_register(LS_TF_UART_BASE, LS_TF_UART_CLOCK, diff --git a/plat/layerscape/common/ls_bl31_setup.c b/plat/layerscape/common/ls_bl31_setup.c index 03e580768..7a91aef81 100644 --- a/plat/layerscape/common/ls_bl31_setup.c +++ b/plat/layerscape/common/ls_bl31_setup.c @@ -67,7 +67,7 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) void ls_bl31_early_platform_setup(void *from_bl2, void *plat_params_from_bl2) { - static console_ls_16550_t console; + static console_t console; /* Initialize the console to provide early debug support */ console_ls_16550_register(LS_TF_UART_BASE, LS_TF_UART_CLOCK, @@ -182,7 +182,7 @@ void ls_bl31_platform_setup(void) ******************************************************************************/ void ls_bl31_plat_runtime_setup(void) { - static console_ls_16550_t console; + static console_t console; /* Initialize the runtime console */ console_ls_16550_register(PLAT_LS1043_UART_BASE, PLAT_LS1043_UART_CLOCK, diff --git a/plat/layerscape/common/tsp/ls_tsp_setup.c b/plat/layerscape/common/tsp/ls_tsp_setup.c index f3b60276c..969d0b83b 100644 --- a/plat/layerscape/common/tsp/ls_tsp_setup.c +++ b/plat/layerscape/common/tsp/ls_tsp_setup.c @@ -30,7 +30,7 @@ gicv2_driver_data_t ls_gic_data = { ******************************************************************************/ void ls_tsp_early_platform_setup(void) { - static console_ls_16550_t console; + static console_t console; /* * Initialize a different console than already in use to display * messages from TSP diff --git a/plat/nvidia/tegra/soc/t194/plat_setup.c b/plat/nvidia/tegra/soc/t194/plat_setup.c index 7f2b00d1b..b9d5dfe23 100644 --- a/plat/nvidia/tegra/soc/t194/plat_setup.c +++ b/plat/nvidia/tegra/soc/t194/plat_setup.c @@ -170,7 +170,7 @@ void plat_enable_console(int32_t id) console_clock, TEGRA_CONSOLE_BAUDRATE, &spe_console); - console_set_scope(&spe_console.console, CONSOLE_FLAG_BOOT | + console_set_scope(&spe_console, CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH); } #else @@ -190,7 +190,7 @@ void plat_enable_console(int32_t id) console_clock, TEGRA_CONSOLE_BAUDRATE, &uart_console); - console_set_scope(&uart_console.console, CONSOLE_FLAG_BOOT | + console_set_scope(&uart_console, CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH); } #endif -- cgit v1.2.3 From 78b40dce6403e1f2c79e860aa1cdffb88a73b6e3 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Sat, 25 Jan 2020 00:58:35 +0000 Subject: cdns: Use generic console_t data structure Since now the generic console_t structure holds the UART base address as well, let's use that generic location and drop the UART driver specific data structure at all. Change-Id: I9f8b55414ab7965e431e3e86d182eabd511f32a4 Signed-off-by: Andre Przywara --- drivers/cadence/uart/aarch64/cdns_console.S | 18 +++++++++--------- include/drivers/cadence/cdns_uart.h | 9 +-------- plat/xilinx/zynqmp/bl31_zynqmp_setup.c | 4 ++-- plat/xilinx/zynqmp/tsp/tsp_plat_setup.c | 4 ++-- 4 files changed, 14 insertions(+), 21 deletions(-) diff --git a/drivers/cadence/uart/aarch64/cdns_console.S b/drivers/cadence/uart/aarch64/cdns_console.S index ecd0c478d..8e5d6a1aa 100644 --- a/drivers/cadence/uart/aarch64/cdns_console.S +++ b/drivers/cadence/uart/aarch64/cdns_console.S @@ -56,14 +56,14 @@ endfunc console_cdns_core_init /* ----------------------------------------------- * int console_cdns_register(uintptr_t baseaddr, * uint32_t clock, uint32_t baud, - * console_cdns_t *console); + * console_t *console); * Function to initialize and register a new CDNS * console. Storage passed in for the console struct * *must* be persistent (i.e. not from the stack). * In: x0 - UART register base address * w1 - UART clock in Hz * w2 - Baud rate - * x3 - pointer to empty console_16550_t struct + * x3 - pointer to empty console_t struct * Out: return 1 on success, 0 on error * Clobber list : x0, x1, x2, x6, x7, x14 * ----------------------------------------------- @@ -72,7 +72,7 @@ func console_cdns_register mov x7, x30 mov x6, x3 cbz x6, register_fail - str x0, [x6, #CONSOLE_T_CDNS_BASE] + str x0, [x6, #CONSOLE_T_BASE] bl console_cdns_core_init cbz x0, register_fail @@ -119,7 +119,7 @@ func console_cdns_core_putc endfunc console_cdns_core_putc /* -------------------------------------------------------- - * int console_cdns_putc(int c, console_cdns_t *cdns) + * int console_cdns_putc(int c, console_t *cdns) * Function to output a character over the console. It * returns the character printed on success or -1 on error. * In : w0 - character to be printed @@ -133,7 +133,7 @@ func console_cdns_putc cmp x1, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr x1, [x1, #CONSOLE_T_CDNS_BASE] + ldr x1, [x1, #CONSOLE_T_BASE] b console_cdns_core_putc endfunc console_cdns_putc @@ -165,7 +165,7 @@ no_char: endfunc console_cdns_core_getc /* --------------------------------------------- - * int console_cdns_getc(console_cdns_t *console) + * int console_cdns_getc(console_t *console) * Function to get a character from the console. * It returns the character grabbed on success * or -1 if no character is available. @@ -179,7 +179,7 @@ func console_cdns_getc cmp x0, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr x0, [x0, #CONSOLE_T_CDNS_BASE] + ldr x0, [x0, #CONSOLE_T_BASE] b console_cdns_core_getc endfunc console_cdns_getc @@ -203,7 +203,7 @@ func console_cdns_core_flush endfunc console_cdns_core_flush /* --------------------------------------------- - * int console_cdns_flush(console_pl011_t *console) + * int console_cdns_flush(console_t *console) * Function to force a write of all buffered * data that hasn't been output. * In : x0 - pointer to console_t structure @@ -216,6 +216,6 @@ func console_cdns_flush cmp x0, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr x0, [x0, #CONSOLE_T_CDNS_BASE] + ldr x0, [x0, #CONSOLE_T_BASE] b console_cdns_core_flush endfunc console_cdns_flush diff --git a/include/drivers/cadence/cdns_uart.h b/include/drivers/cadence/cdns_uart.h index 64a062ca1..46ba4663e 100644 --- a/include/drivers/cadence/cdns_uart.h +++ b/include/drivers/cadence/cdns_uart.h @@ -25,17 +25,10 @@ #define R_UART_TX 0x30 #define R_UART_RX 0x30 -#define CONSOLE_T_CDNS_BASE CONSOLE_T_DRVDATA - #ifndef __ASSEMBLER__ #include -typedef struct { - console_t console; - uintptr_t base; -} console_cdns_t; - /* * Initialize a new Cadence console instance and register it with the console * framework. The |console| pointer must point to storage that will be valid @@ -43,7 +36,7 @@ typedef struct { * Its contents will be reinitialized from scratch. */ int console_cdns_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud, - console_cdns_t *console); + console_t *console); #endif /*__ASSEMBLER__*/ diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c index 6e0e811d4..b6d8770cc 100644 --- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c +++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c @@ -62,12 +62,12 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, { uint64_t atf_handoff_addr; /* Register the console to provide early debug support */ - static console_cdns_t bl31_boot_console; + static console_t bl31_boot_console; (void)console_cdns_register(ZYNQMP_UART_BASE, zynqmp_get_uart_clk(), ZYNQMP_UART_BAUDRATE, &bl31_boot_console); - console_set_scope(&bl31_boot_console.console, + console_set_scope(&bl31_boot_console, CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_BOOT); /* Initialize the platform config for future decision making */ diff --git a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c b/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c index 7f0ac74cf..5e770f75c 100644 --- a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c +++ b/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c @@ -21,12 +21,12 @@ void tsp_early_platform_setup(void) * Register a different console than already in use to display * messages from TSP */ - static console_cdns_t tsp_boot_console; + static console_t tsp_boot_console; (void)console_cdns_register(ZYNQMP_UART_BASE, zynqmp_get_uart_clk(), ZYNQMP_UART_BAUDRATE, &tsp_boot_console); - console_set_scope(&tsp_boot_console.console, + console_set_scope(&tsp_boot_console, CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_BOOT); /* Initialize the platform config for future decision making */ -- cgit v1.2.3 From 7b8fe2de31222ef6cbbd1968b7d3fd5a9e38c499 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Sat, 25 Jan 2020 00:58:35 +0000 Subject: spe: Use generic console_t data structure Since now the generic console_t structure holds the UART base address as well, let's use that generic location and drop the UART driver specific data structure at all. Change-Id: I75dbfafb67849833b3f7b5047e237651e3f553cd Signed-off-by: Andre Przywara --- plat/nvidia/tegra/common/drivers/spe/shared_console.S | 10 +++++----- plat/nvidia/tegra/include/drivers/spe.h | 7 +------ plat/nvidia/tegra/soc/t194/plat_setup.c | 2 +- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/plat/nvidia/tegra/common/drivers/spe/shared_console.S b/plat/nvidia/tegra/common/drivers/spe/shared_console.S index 0be34e417..c783373dd 100644 --- a/plat/nvidia/tegra/common/drivers/spe/shared_console.S +++ b/plat/nvidia/tegra/common/drivers/spe/shared_console.S @@ -49,14 +49,14 @@ /* ------------------------------------------------- * int console_spe_register(uintptr_t baseaddr, * uint32_t clock, uint32_t baud, - * console_spe_t *console); + * console_t *console); * Function to initialize and register a new spe * console. Storage passed in for the console struct * *must* be persistent (i.e. not from the stack). * In: x0 - UART register base address * w1 - UART clock in Hz * w2 - Baud rate - * x3 - pointer to empty console_spe_t struct + * x3 - pointer to empty console_t struct * Out: return 1 on success, 0 on error * Clobber list : x0, x1, x2, x6, x7, x14 * ------------------------------------------------- @@ -122,7 +122,7 @@ putc_error: endfunc console_spe_core_putc /* -------------------------------------------------------- - * int console_spe_putc(int c, console_spe_t *console) + * int console_spe_putc(int c, console_t *console) * Function to output a character over the console. It * returns the character printed on success or -1 on error. * In : w0 - character to be printed @@ -137,7 +137,7 @@ func console_spe_putc endfunc console_spe_putc /* --------------------------------------------- - * int console_spe_getc(console_spe_t *console) + * int console_spe_getc(console_t *console) * Function to get a character from the console. * It returns the character grabbed on success * or -1 if no character is available. @@ -174,7 +174,7 @@ flush_error: endfunc console_spe_core_flush /* --------------------------------------------- - * int console_spe_flush(console_spe_t *console) + * int console_spe_flush(console_t *console) * Function to force a write of all buffered * data that hasn't been output. * In : x0 - pointer to console_t structure diff --git a/plat/nvidia/tegra/include/drivers/spe.h b/plat/nvidia/tegra/include/drivers/spe.h index 0d6d69d10..e0f871408 100644 --- a/plat/nvidia/tegra/include/drivers/spe.h +++ b/plat/nvidia/tegra/include/drivers/spe.h @@ -11,11 +11,6 @@ #include -typedef struct { - console_t console; - uintptr_t base; -} console_spe_t; - /* * Initialize a new spe console instance and register it with the console * framework. The |console| pointer must point to storage that will be valid @@ -23,6 +18,6 @@ typedef struct { * Its contents will be reinitialized from scratch. */ int console_spe_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud, - console_spe_t *console); + console_t *console); #endif /* SPE_H */ diff --git a/plat/nvidia/tegra/soc/t194/plat_setup.c b/plat/nvidia/tegra/soc/t194/plat_setup.c index b9d5dfe23..235fba43c 100644 --- a/plat/nvidia/tegra/soc/t194/plat_setup.c +++ b/plat/nvidia/tegra/soc/t194/plat_setup.c @@ -163,7 +163,7 @@ void plat_enable_console(int32_t id) uint32_t console_clock = 0U; #if ENABLE_CONSOLE_SPE - static console_spe_t spe_console; + static console_t spe_console; if (id == TEGRA_CONSOLE_SPE_ID) { (void)console_spe_register(TEGRA_CONSOLE_SPE_BASE, -- cgit v1.2.3 From e8ada80a8496806c1f17ccbc6e2beec99d37f6c4 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Sat, 25 Jan 2020 00:58:35 +0000 Subject: skeletton: Use generic console_t data structure Since now the generic console_t structure holds the UART base address as well, let's use that generic location and drop the UART driver specific data structure at all. Change-Id: I347849424782333149e5912a25cc0ab9d277a201 Signed-off-by: Andre Przywara --- drivers/console/aarch32/skeleton_console.S | 8 ++++---- drivers/console/aarch64/skeleton_console.S | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/console/aarch32/skeleton_console.S b/drivers/console/aarch32/skeleton_console.S index 45ad13927..c594f7edf 100644 --- a/drivers/console/aarch32/skeleton_console.S +++ b/drivers/console/aarch32/skeleton_console.S @@ -50,7 +50,7 @@ func console_xxx_register * by later console callback (e.g. putc). * Example: */ - str r1, [r0, #CONSOLE_T_XXX_BASE] + str r1, [r0, #CONSOLE_T_BASE] str r2, [r0, #CONSOLE_T_XXX_SOME_OTHER_VALUE] /* @@ -87,7 +87,7 @@ func console_xxx_putc * console_xxx_t structure pointed to by r1. * Example: */ - ldr r1, [r1, #CONSOLE_T_XXX_BASE] + ldr r1, [r1, #CONSOLE_T_BASE] /* * Write r0 to hardware. @@ -125,7 +125,7 @@ func console_xxx_getc * console_xxx_t structure pointed to by r0. * Example: */ - ldr r1, [r0, #CONSOLE_T_XXX_BASE] + ldr r1, [r0, #CONSOLE_T_BASE] /* * Try to read character into r0 from hardware. @@ -159,7 +159,7 @@ func console_xxx_flush * console_xxx_t structure pointed to by r0. * Example: */ - ldr r1, [r0, #CONSOLE_T_XXX_BASE] + ldr r1, [r0, #CONSOLE_T_BASE] /* * Flush all remaining output from hardware FIFOs. Do not return until diff --git a/drivers/console/aarch64/skeleton_console.S b/drivers/console/aarch64/skeleton_console.S index 957ed83a9..9a8586775 100644 --- a/drivers/console/aarch64/skeleton_console.S +++ b/drivers/console/aarch64/skeleton_console.S @@ -50,7 +50,7 @@ func console_xxx_register * by later console callback (e.g. putc). * Example: */ - str x1, [x0, #CONSOLE_T_XXX_BASE] + str x1, [x0, #CONSOLE_T_BASE] str x2, [x0, #CONSOLE_T_XXX_SOME_OTHER_VALUE] /* @@ -87,7 +87,7 @@ func console_xxx_putc * console_xxx_t structure pointed to by x1. * Example: */ - ldr x1, [x1, #CONSOLE_T_XXX_BASE] + ldr x1, [x1, #CONSOLE_T_BASE] /* * Write w0 to hardware. @@ -125,7 +125,7 @@ func console_xxx_getc * console_xxx_t structure pointed to by x0. * Example: */ - ldr x1, [x0, #CONSOLE_T_XXX_BASE] + ldr x1, [x0, #CONSOLE_T_BASE] /* * Try to read character into w0 from hardware. @@ -159,7 +159,7 @@ func console_xxx_flush * console_xxx_t structure pointed to by x0. * Example: */ - ldr x1, [x0, #CONSOLE_T_XXX_BASE] + ldr x1, [x0, #CONSOLE_T_BASE] /* * Flush all remaining output from hardware FIFOs. Do not return until -- cgit v1.2.3 From af1e8fda23bd59a2c07be125f98517b2547ce412 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Sat, 25 Jan 2020 00:58:35 +0000 Subject: uniphier: Use generic console_t data structure Since now the generic console_t structure holds the UART base address as well, let's use that generic location and drop the UART driver specific data structure at all. Change-Id: Ia9d996bb45ff3a7f1b240f12fd75805b48a048e9 Signed-off-by: Andre Przywara --- plat/socionext/uniphier/uniphier_console.S | 6 +++--- plat/socionext/uniphier/uniphier_console_setup.c | 25 +++++++++--------------- 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/plat/socionext/uniphier/uniphier_console.S b/plat/socionext/uniphier/uniphier_console.S index 1113c6e81..f3dde0cc1 100644 --- a/plat/socionext/uniphier/uniphier_console.S +++ b/plat/socionext/uniphier/uniphier_console.S @@ -17,7 +17,7 @@ */ .globl uniphier_console_putc func uniphier_console_putc - ldr x1, [x1, #CONSOLE_T_DRVDATA] + ldr x1, [x1, #CONSOLE_T_BASE] /* Wait until the transmitter FIFO gets empty */ 0: ldr w2, [x1, #UNIPHIER_UART_LSR] @@ -36,7 +36,7 @@ endfunc uniphier_console_putc */ .globl uniphier_console_getc func uniphier_console_getc - ldr x0, [x0, #CONSOLE_T_DRVDATA] + ldr x0, [x0, #CONSOLE_T_BASE] ldr w1, [x0, #UNIPHIER_UART_LSR] tbz w1, #UNIPHIER_UART_LSR_DR_BIT, 0f @@ -55,7 +55,7 @@ endfunc uniphier_console_getc */ .global uniphier_console_flush func uniphier_console_flush - ldr x0, [x0, #CONSOLE_T_DRVDATA] + ldr x0, [x0, #CONSOLE_T_BASE] /* wait until the transmitter gets empty */ 0: ldr w1, [x0, #UNIPHIER_UART_LSR] diff --git a/plat/socionext/uniphier/uniphier_console_setup.c b/plat/socionext/uniphier/uniphier_console_setup.c index 1851e4da5..e2ae8bf28 100644 --- a/plat/socionext/uniphier/uniphier_console_setup.c +++ b/plat/socionext/uniphier/uniphier_console_setup.c @@ -17,28 +17,21 @@ #define UNIPHIER_UART_OFFSET 0x100 #define UNIPHIER_UART_NR_PORTS 4 -struct uniphier_console { - struct console console; - uintptr_t base; -}; - /* These callbacks are implemented in assembly to use crash_console_helpers.S */ int uniphier_console_putc(int character, struct console *console); int uniphier_console_getc(struct console *console); int uniphier_console_flush(struct console *console); -static struct uniphier_console uniphier_console = { - .console = { - .flags = CONSOLE_FLAG_BOOT | +static console_t uniphier_console = { + .flags = CONSOLE_FLAG_BOOT | #if DEBUG - CONSOLE_FLAG_RUNTIME | + CONSOLE_FLAG_RUNTIME | #endif - CONSOLE_FLAG_CRASH | - CONSOLE_FLAG_TRANSLATE_CRLF, - .putc = uniphier_console_putc, - .getc = uniphier_console_getc, - .flush = uniphier_console_flush, - }, + CONSOLE_FLAG_CRASH | + CONSOLE_FLAG_TRANSLATE_CRLF, + .putc = uniphier_console_putc, + .getc = uniphier_console_getc, + .flush = uniphier_console_flush, }; static const uintptr_t uniphier_uart_base[] = { @@ -86,7 +79,7 @@ void uniphier_console_setup(unsigned int soc) plat_error_handler(-EINVAL); uniphier_console.base = base; - console_register(&uniphier_console.console); + console_register(&uniphier_console); /* * The hardware might be still printing characters queued up in the -- cgit v1.2.3 From ac71344e9eca1f7d1e0ce4a67aca776470639b1c Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Sat, 25 Jan 2020 00:54:38 +0000 Subject: console: Integrate UART base address in generic console_t *All* UART drivers in TF-A are storing their base address as a uintptr_t pointer in the first location of the UART specific driver data. Since the base address is a pretty natural and generic data item, we should integrate this into the generic console_t structure. That will not only allow to remove a lot of seemingly UART specific data structures, but also enables to simplify runtime choices between different UARTs, since they can share the same pointer. This patch just adds the new member, the existing data structures will be handled on a per-UART base in follow-up patches. Change-Id: I59ce49471ccc8f3b870f2cfd8a72ebfd0cb14d12 Signed-off-by: Andre Przywara --- include/drivers/console.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/drivers/console.h b/include/drivers/console.h index a4859d80f..761816ac7 100644 --- a/include/drivers/console.h +++ b/include/drivers/console.h @@ -14,7 +14,8 @@ #define CONSOLE_T_PUTC (U(2) * REGSZ) #define CONSOLE_T_GETC (U(3) * REGSZ) #define CONSOLE_T_FLUSH (U(4) * REGSZ) -#define CONSOLE_T_DRVDATA (U(5) * REGSZ) +#define CONSOLE_T_BASE (U(5) * REGSZ) +#define CONSOLE_T_DRVDATA (U(6) * REGSZ) #define CONSOLE_FLAG_BOOT (U(1) << 0) #define CONSOLE_FLAG_RUNTIME (U(1) << 1) @@ -43,6 +44,7 @@ typedef struct console { int (*const putc)(int character, struct console *console); int (*const getc)(struct console *console); int (*const flush)(struct console *console); + uintptr_t base; /* Additional private driver data may follow here. */ } console_t; -- cgit v1.2.3 From 489e298744fa668bd46661237f81cd9ba05e3b4e Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Sat, 25 Jan 2020 00:58:35 +0000 Subject: meson: Use generic console_t data structure Since now the generic console_t structure holds the UART base address as well, let's use that generic location and drop the UART driver specific data structure at all. Change-Id: I07a07677153d3671ced776671e4f107824d3df16 Signed-off-by: Andre Przywara --- drivers/amlogic/console/aarch64/meson_console.S | 18 +++++++++--------- include/drivers/amlogic/meson_console.h | 9 +-------- plat/amlogic/common/aml_console.c | 4 ++-- 3 files changed, 12 insertions(+), 19 deletions(-) diff --git a/drivers/amlogic/console/aarch64/meson_console.S b/drivers/amlogic/console/aarch64/meson_console.S index e645cbab8..39c2545e7 100644 --- a/drivers/amlogic/console/aarch64/meson_console.S +++ b/drivers/amlogic/console/aarch64/meson_console.S @@ -46,14 +46,14 @@ /* ----------------------------------------------- * int console_meson_register(uintptr_t base, * uint32_t clk, uint32_t baud, - * console_meson_t *console); + * console_t *console); * Function to initialize and register a new MESON * console. Storage passed in for the console struct * *must* be persistent (i.e. not from the stack). * In: x0 - UART register base address * w1 - UART clock in Hz * w2 - Baud rate - * x3 - pointer to empty console_meson_t struct + * x3 - pointer to empty console_t struct * Out: return 1 on success, 0 on error * Clobber list : x0, x1, x2, x6, x7, x14 * ----------------------------------------------- @@ -62,7 +62,7 @@ func console_meson_register mov x7, x30 mov x6, x3 cbz x6, register_fail - str x0, [x6, #CONSOLE_T_MESON_BASE] + str x0, [x6, #CONSOLE_T_BASE] bl console_meson_init cbz x0, register_fail @@ -128,7 +128,7 @@ init_fail: endfunc console_meson_init /* -------------------------------------------------------- - * int console_meson_putc(int c, console_meson_t *console) + * int console_meson_putc(int c, console_t *console) * Function to output a character over the console. It * returns the character printed on success or -1 on error. * In : w0 - character to be printed @@ -142,7 +142,7 @@ func console_meson_putc cmp x1, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr x1, [x1, #CONSOLE_T_MESON_BASE] + ldr x1, [x1, #CONSOLE_T_BASE] b console_meson_core_putc endfunc console_meson_putc @@ -179,7 +179,7 @@ func console_meson_core_putc endfunc console_meson_core_putc /* --------------------------------------------- - * int console_meson_getc(console_meson_t *console) + * int console_meson_getc(console_t *console) * Function to get a character from the console. * It returns the character grabbed on success * or -1 if no character is available. @@ -193,7 +193,7 @@ func console_meson_getc cmp x0, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr x0, [x0, #CONSOLE_T_MESON_BASE] + ldr x0, [x0, #CONSOLE_T_BASE] b console_meson_core_getc endfunc console_meson_getc @@ -224,7 +224,7 @@ func console_meson_core_getc endfunc console_meson_core_getc /* --------------------------------------------- - * int console_meson_flush(console_meson_t *console) + * int console_meson_flush(console_t *console) * Function to force a write of all buffered * data that hasn't been output. * In : x0 - pointer to console_t structure @@ -237,7 +237,7 @@ func console_meson_flush cmp x0, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr x0, [x0, #CONSOLE_T_MESON_BASE] + ldr x0, [x0, #CONSOLE_T_BASE] b console_meson_core_flush endfunc console_meson_flush diff --git a/include/drivers/amlogic/meson_console.h b/include/drivers/amlogic/meson_console.h index 70e3b0bd4..8d52d794b 100644 --- a/include/drivers/amlogic/meson_console.h +++ b/include/drivers/amlogic/meson_console.h @@ -9,17 +9,10 @@ #include -#define CONSOLE_T_MESON_BASE CONSOLE_T_DRVDATA - #ifndef __ASSEMBLER__ #include -typedef struct { - console_t console; - uintptr_t base; -} console_meson_t; - /* * Initialize a new meson console instance and register it with the console * framework. The |console| pointer must point to storage that will be valid @@ -30,7 +23,7 @@ typedef struct { * order to make this function future-proof. */ int console_meson_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud, - console_meson_t *console); + console_t *console); #endif /*__ASSEMBLER__*/ diff --git a/plat/amlogic/common/aml_console.c b/plat/amlogic/common/aml_console.c index 352279b6c..e21d707a0 100644 --- a/plat/amlogic/common/aml_console.c +++ b/plat/amlogic/common/aml_console.c @@ -11,7 +11,7 @@ /******************************************************************************* * Function that sets up the console ******************************************************************************/ -static console_meson_t aml_console; +static console_t aml_console; void aml_console_init(void) { @@ -28,6 +28,6 @@ void aml_console_init(void) panic(); } - console_set_scope(&aml_console.console, + console_set_scope(&aml_console, CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME); } -- cgit v1.2.3 From f695e1e01a995e66f9f5be5430fef3b7920082f2 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Sat, 25 Jan 2020 00:58:35 +0000 Subject: pl011: Use generic console_t data structure Since now the generic console_t structure holds the UART base address as well, let's use that generic location and drop the UART driver specific data structure at all. Change-Id: I7a23327394d142af4b293ea7ccd90b843c54587c Signed-off-by: Andre Przywara --- drivers/arm/pl011/aarch32/pl011_console.S | 18 +++++++++--------- drivers/arm/pl011/aarch64/pl011_console.S | 18 +++++++++--------- include/drivers/arm/pl011.h | 9 +-------- plat/arm/common/arm_console.c | 10 +++++----- plat/arm/common/tsp/arm_tsp_setup.c | 4 ++-- plat/hisilicon/hikey/hikey_bl1_setup.c | 2 +- plat/hisilicon/hikey/hikey_bl2_setup.c | 2 +- plat/hisilicon/hikey/hikey_bl31_setup.c | 2 +- plat/hisilicon/hikey960/hikey960_bl1_setup.c | 2 +- plat/hisilicon/hikey960/hikey960_bl2_setup.c | 2 +- plat/hisilicon/hikey960/hikey960_bl31_setup.c | 2 +- plat/hisilicon/hikey960/hikey960_pm.c | 2 +- plat/hisilicon/poplar/bl1_plat_setup.c | 2 +- plat/hisilicon/poplar/bl2_plat_setup.c | 2 +- plat/hisilicon/poplar/bl31_plat_setup.c | 2 +- plat/qemu/common/qemu_console.c | 4 ++-- plat/socionext/synquacer/sq_bl31_setup.c | 5 ++--- plat/xilinx/versal/bl31_versal_setup.c | 4 ++-- 18 files changed, 42 insertions(+), 50 deletions(-) diff --git a/drivers/arm/pl011/aarch32/pl011_console.S b/drivers/arm/pl011/aarch32/pl011_console.S index 05c8250dc..93045f03d 100644 --- a/drivers/arm/pl011/aarch32/pl011_console.S +++ b/drivers/arm/pl011/aarch32/pl011_console.S @@ -91,14 +91,14 @@ endfunc console_pl011_core_init /* ------------------------------------------------------- * int console_pl011_register(uintptr_t baseaddr, * uint32_t clock, uint32_t baud, - * console_pl011_t *console); + * console_t *console); * Function to initialize and register a new PL011 * console. Storage passed in for the console struct * *must* be persistent (i.e. not from the stack). * In: r0 - UART register base address * r1 - UART clock in Hz * r2 - Baud rate - * r3 - pointer to empty console_pl011_t struct + * r3 - pointer to empty console_t struct * Out: return 1 on success, 0 on error * Clobber list : r0, r1, r2 * ------------------------------------------------------- @@ -108,7 +108,7 @@ func console_pl011_register mov r4, r3 cmp r4, #0 beq register_fail - str r0, [r4, #CONSOLE_T_PL011_BASE] + str r0, [r4, #CONSOLE_T_BASE] bl console_pl011_core_init cmp r0, #0 @@ -159,7 +159,7 @@ putc_error: endfunc console_pl011_core_putc /* -------------------------------------------------------- - * int console_pl011_putc(int c, console_pl011_t *console) + * int console_pl011_putc(int c, console_t *console) * Function to output a character over the console. It * returns the character printed on success or -1 on error. * In: r0 - character to be printed @@ -173,7 +173,7 @@ func console_pl011_putc cmp r1, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr r1, [r1, #CONSOLE_T_PL011_BASE] + ldr r1, [r1, #CONSOLE_T_BASE] b console_pl011_core_putc endfunc console_pl011_putc @@ -203,7 +203,7 @@ getc_error: endfunc console_pl011_core_getc /* ------------------------------------------------ - * int console_pl011_getc(console_pl011_t *console) + * int console_pl011_getc(console_t *console) * Function to get a character from the console. * It returns the character grabbed on success * or -1 if no character is available. @@ -217,7 +217,7 @@ func console_pl011_getc cmp r0, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr r0, [r0, #CONSOLE_T_PL011_BASE] + ldr r0, [r0, #CONSOLE_T_BASE] b console_pl011_core_getc endfunc console_pl011_getc @@ -248,7 +248,7 @@ flush_error: endfunc console_pl011_core_flush /* --------------------------------------------- - * int console_pl011_flush(console_pl011_t *console) + * int console_pl011_flush(console_t *console) * Function to force a write of all buffered * data that hasn't been output. * In : r0 - pointer to console_t structure @@ -261,6 +261,6 @@ func console_pl011_flush cmp r0, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr r0, [r0, #CONSOLE_T_PL011_BASE] + ldr r0, [r0, #CONSOLE_T_BASE] b console_pl011_core_flush endfunc console_pl011_flush diff --git a/drivers/arm/pl011/aarch64/pl011_console.S b/drivers/arm/pl011/aarch64/pl011_console.S index 04de99fbc..3a2a3cdb4 100644 --- a/drivers/arm/pl011/aarch64/pl011_console.S +++ b/drivers/arm/pl011/aarch64/pl011_console.S @@ -80,14 +80,14 @@ endfunc console_pl011_core_init /* ----------------------------------------------- * int console_pl011_register(uintptr_t baseaddr, * uint32_t clock, uint32_t baud, - * console_pl011_t *console); + * console_t *console); * Function to initialize and register a new PL011 * console. Storage passed in for the console struct * *must* be persistent (i.e. not from the stack). * In: x0 - UART register base address * w1 - UART clock in Hz * w2 - Baud rate - * x3 - pointer to empty console_pl011_t struct + * x3 - pointer to empty console_t struct * Out: return 1 on success, 0 on error * Clobber list : x0, x1, x2, x6, x7, x14 * ----------------------------------------------- @@ -96,7 +96,7 @@ func console_pl011_register mov x7, x30 mov x6, x3 cbz x6, register_fail - str x0, [x6, #CONSOLE_T_PL011_BASE] + str x0, [x6, #CONSOLE_T_BASE] bl console_pl011_core_init cbz x0, register_fail @@ -143,7 +143,7 @@ func console_pl011_core_putc endfunc console_pl011_core_putc /* -------------------------------------------------------- - * int console_pl011_putc(int c, console_pl011_t *console) + * int console_pl011_putc(int c, console_t *console) * Function to output a character over the console. It * returns the character printed on success or -1 on error. * In : w0 - character to be printed @@ -157,7 +157,7 @@ func console_pl011_putc cmp x1, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr x1, [x1, #CONSOLE_T_PL011_BASE] + ldr x1, [x1, #CONSOLE_T_BASE] b console_pl011_core_putc endfunc console_pl011_putc @@ -189,7 +189,7 @@ no_char: endfunc console_pl011_core_getc /* --------------------------------------------- - * int console_pl011_getc(console_pl011_t *console) + * int console_pl011_getc(console_t *console) * Function to get a character from the console. * It returns the character grabbed on success * or -1 if no character is available. @@ -203,7 +203,7 @@ func console_pl011_getc cmp x0, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr x0, [x0, #CONSOLE_T_PL011_BASE] + ldr x0, [x0, #CONSOLE_T_BASE] b console_pl011_core_getc endfunc console_pl011_getc @@ -231,7 +231,7 @@ func console_pl011_core_flush endfunc console_pl011_core_flush /* --------------------------------------------- - * int console_pl011_flush(console_pl011_t *console) + * int console_pl011_flush(console_t *console) * Function to force a write of all buffered * data that hasn't been output. * In : x0 - pointer to console_t structure @@ -244,6 +244,6 @@ func console_pl011_flush cmp x0, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr x0, [x0, #CONSOLE_T_PL011_BASE] + ldr x0, [x0, #CONSOLE_T_BASE] b console_pl011_core_flush endfunc console_pl011_flush diff --git a/include/drivers/arm/pl011.h b/include/drivers/arm/pl011.h index 8733d1964..ebc664348 100644 --- a/include/drivers/arm/pl011.h +++ b/include/drivers/arm/pl011.h @@ -81,17 +81,10 @@ #endif /* !PL011_GENERIC_UART */ -#define CONSOLE_T_PL011_BASE CONSOLE_T_DRVDATA - #ifndef __ASSEMBLER__ #include -typedef struct { - console_t console; - uintptr_t base; -} console_pl011_t; - /* * Initialize a new PL011 console instance and register it with the console * framework. The |console| pointer must point to storage that will be valid @@ -99,7 +92,7 @@ typedef struct { * Its contents will be reinitialized from scratch. */ int console_pl011_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud, - console_pl011_t *console); + console_t *console); #endif /*__ASSEMBLER__*/ diff --git a/plat/arm/common/arm_console.c b/plat/arm/common/arm_console.c index 123811d71..0cac5d999 100644 --- a/plat/arm/common/arm_console.c +++ b/plat/arm/common/arm_console.c @@ -16,8 +16,8 @@ /******************************************************************************* * Functions that set up the console ******************************************************************************/ -static console_pl011_t arm_boot_console; -static console_pl011_t arm_runtime_console; +static console_t arm_boot_console; +static console_t arm_runtime_console; /* Initialize the console to provide early debug support */ void __init arm_console_boot_init(void) @@ -35,13 +35,13 @@ void __init arm_console_boot_init(void) panic(); } - console_set_scope(&arm_boot_console.console, CONSOLE_FLAG_BOOT); + console_set_scope(&arm_boot_console, CONSOLE_FLAG_BOOT); } void arm_console_boot_end(void) { (void)console_flush(); - (void)console_unregister(&arm_boot_console.console); + (void)console_unregister(&arm_boot_console); } /* Initialize the runtime console */ @@ -54,7 +54,7 @@ void arm_console_runtime_init(void) if (rc == 0) panic(); - console_set_scope(&arm_runtime_console.console, CONSOLE_FLAG_RUNTIME); + console_set_scope(&arm_runtime_console, CONSOLE_FLAG_RUNTIME); } void arm_console_runtime_end(void) diff --git a/plat/arm/common/tsp/arm_tsp_setup.c b/plat/arm/common/tsp/arm_tsp_setup.c index aefdf89c7..ee1df6c3e 100644 --- a/plat/arm/common/tsp/arm_tsp_setup.c +++ b/plat/arm/common/tsp/arm_tsp_setup.c @@ -28,7 +28,7 @@ /******************************************************************************* * Initialize the UART ******************************************************************************/ -static console_pl011_t arm_tsp_runtime_console; +static console_t arm_tsp_runtime_console; void arm_tsp_early_platform_setup(void) { @@ -43,7 +43,7 @@ void arm_tsp_early_platform_setup(void) if (rc == 0) panic(); - console_set_scope(&arm_tsp_runtime_console.console, + console_set_scope(&arm_tsp_runtime_console, CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME); } diff --git a/plat/hisilicon/hikey/hikey_bl1_setup.c b/plat/hisilicon/hikey/hikey_bl1_setup.c index a97d76320..86e4fd637 100644 --- a/plat/hisilicon/hikey/hikey_bl1_setup.c +++ b/plat/hisilicon/hikey/hikey_bl1_setup.c @@ -26,7 +26,7 @@ /* Data structure which holds the extents of the trusted RAM for BL1 */ static meminfo_t bl1_tzram_layout; -static console_pl011_t console; +static console_t console; enum { BOOT_NORMAL = 0, diff --git a/plat/hisilicon/hikey/hikey_bl2_setup.c b/plat/hisilicon/hikey/hikey_bl2_setup.c index 96136ec12..feb7f8a46 100644 --- a/plat/hisilicon/hikey/hikey_bl2_setup.c +++ b/plat/hisilicon/hikey/hikey_bl2_setup.c @@ -32,7 +32,7 @@ #define BL2_RW_BASE (BL_CODE_END) static meminfo_t bl2_el3_tzram_layout; -static console_pl011_t console; +static console_t console; enum { BOOT_MODE_RECOVERY = 0, diff --git a/plat/hisilicon/hikey/hikey_bl31_setup.c b/plat/hisilicon/hikey/hikey_bl31_setup.c index 0326e9f3d..7d008e741 100644 --- a/plat/hisilicon/hikey/hikey_bl31_setup.c +++ b/plat/hisilicon/hikey/hikey_bl31_setup.c @@ -27,7 +27,7 @@ static entry_point_info_t bl32_ep_info; static entry_point_info_t bl33_ep_info; -static console_pl011_t console; +static console_t console; /****************************************************************************** * On a GICv2 system, the Group 1 secure interrupts are treated as Group 0 diff --git a/plat/hisilicon/hikey960/hikey960_bl1_setup.c b/plat/hisilicon/hikey960/hikey960_bl1_setup.c index 4a7036cfc..0a2d062a5 100644 --- a/plat/hisilicon/hikey960/hikey960_bl1_setup.c +++ b/plat/hisilicon/hikey960/hikey960_bl1_setup.c @@ -41,7 +41,7 @@ enum { /* Data structure which holds the extents of the trusted RAM for BL1 */ static meminfo_t bl1_tzram_layout; -static console_pl011_t console; +static console_t console; /****************************************************************************** * On a GICv2 system, the Group 1 secure interrupts are treated as Group 0 diff --git a/plat/hisilicon/hikey960/hikey960_bl2_setup.c b/plat/hisilicon/hikey960/hikey960_bl2_setup.c index 35d76921d..c1c2a8c59 100644 --- a/plat/hisilicon/hikey960/hikey960_bl2_setup.c +++ b/plat/hisilicon/hikey960/hikey960_bl2_setup.c @@ -32,7 +32,7 @@ #define BL2_RW_BASE (BL_CODE_END) static meminfo_t bl2_el3_tzram_layout; -static console_pl011_t console; +static console_t console; extern int load_lpm3(void); enum { diff --git a/plat/hisilicon/hikey960/hikey960_bl31_setup.c b/plat/hisilicon/hikey960/hikey960_bl31_setup.c index 9383265ec..d3b4e4f68 100644 --- a/plat/hisilicon/hikey960/hikey960_bl31_setup.c +++ b/plat/hisilicon/hikey960/hikey960_bl31_setup.c @@ -29,7 +29,7 @@ static entry_point_info_t bl32_ep_info; static entry_point_info_t bl33_ep_info; -static console_pl011_t console; +static console_t console; /****************************************************************************** * On a GICv2 system, the Group 1 secure interrupts are treated as Group 0 diff --git a/plat/hisilicon/hikey960/hikey960_pm.c b/plat/hisilicon/hikey960/hikey960_pm.c index ede893ecb..9f96fc398 100644 --- a/plat/hisilicon/hikey960/hikey960_pm.c +++ b/plat/hisilicon/hikey960/hikey960_pm.c @@ -33,7 +33,7 @@ #define AXI_CONF_BASE 0x820 static unsigned int uart_base; -static console_pl011_t console; +static console_t console; static uintptr_t hikey960_sec_entrypoint; static void hikey960_pwr_domain_standby(plat_local_state_t cpu_state) diff --git a/plat/hisilicon/poplar/bl1_plat_setup.c b/plat/hisilicon/poplar/bl1_plat_setup.c index 08ad67c59..047ba6291 100644 --- a/plat/hisilicon/poplar/bl1_plat_setup.c +++ b/plat/hisilicon/poplar/bl1_plat_setup.c @@ -28,7 +28,7 @@ /* Data structure which holds the extents of the trusted RAM for BL1 */ static meminfo_t bl1_tzram_layout; static meminfo_t bl2_tzram_layout; -static console_pl011_t console; +static console_t console; /* * Cannot use default weak implementation in bl1_main.c because BL1 RW data is diff --git a/plat/hisilicon/poplar/bl2_plat_setup.c b/plat/hisilicon/poplar/bl2_plat_setup.c index cc9d9754e..482935c4a 100644 --- a/plat/hisilicon/poplar/bl2_plat_setup.c +++ b/plat/hisilicon/poplar/bl2_plat_setup.c @@ -25,7 +25,7 @@ #include "plat_private.h" static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE); -static console_pl011_t console; +static console_t console; /******************************************************************************* * Transfer SCP_BL2 from Trusted RAM using the SCP Download protocol. diff --git a/plat/hisilicon/poplar/bl31_plat_setup.c b/plat/hisilicon/poplar/bl31_plat_setup.c index 981ef376b..a4e17cabc 100644 --- a/plat/hisilicon/poplar/bl31_plat_setup.c +++ b/plat/hisilicon/poplar/bl31_plat_setup.c @@ -29,7 +29,7 @@ static entry_point_info_t bl32_image_ep_info; static entry_point_info_t bl33_image_ep_info; -static console_pl011_t console; +static console_t console; static void hisi_tzpc_sec_init(void) { diff --git a/plat/qemu/common/qemu_console.c b/plat/qemu/common/qemu_console.c index fec182892..1f00f8a72 100644 --- a/plat/qemu/common/qemu_console.c +++ b/plat/qemu/common/qemu_console.c @@ -9,7 +9,7 @@ #include #include -static console_pl011_t console; +static console_t console; void qemu_console_init(void) { @@ -17,7 +17,7 @@ void qemu_console_init(void) PLAT_QEMU_BOOT_UART_CLK_IN_HZ, PLAT_QEMU_CONSOLE_BAUDRATE, &console); - console_set_scope(&console.console, CONSOLE_FLAG_BOOT | + console_set_scope(&console, CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME); } diff --git a/plat/socionext/synquacer/sq_bl31_setup.c b/plat/socionext/synquacer/sq_bl31_setup.c index b86402179..9723ef9f0 100644 --- a/plat/socionext/synquacer/sq_bl31_setup.c +++ b/plat/socionext/synquacer/sq_bl31_setup.c @@ -16,7 +16,7 @@ #include #include -static console_pl011_t console; +static console_t console; static entry_point_info_t bl32_image_ep_info; static entry_point_info_t bl33_image_ep_info; @@ -69,8 +69,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, PLAT_SQ_BOOT_UART_CLK_IN_HZ, SQ_CONSOLE_BAUDRATE, &console); - console_set_scope(&console.console, CONSOLE_FLAG_BOOT | - CONSOLE_FLAG_RUNTIME); + console_set_scope(&console, CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME); /* There are no parameters from BL2 if BL31 is a reset vector */ assert(arg0 == 0U); diff --git a/plat/xilinx/versal/bl31_versal_setup.c b/plat/xilinx/versal/bl31_versal_setup.c index a5cf05e9a..03b7fbbb4 100644 --- a/plat/xilinx/versal/bl31_versal_setup.c +++ b/plat/xilinx/versal/bl31_versal_setup.c @@ -22,7 +22,7 @@ static entry_point_info_t bl32_image_ep_info; static entry_point_info_t bl33_image_ep_info; -static console_pl011_t versal_runtime_console; +static console_t versal_runtime_console; /* * Return a pointer to the 'entry_point_info' structure of the next image for @@ -71,7 +71,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, if (rc == 0) panic(); - console_set_scope(&versal_runtime_console.console, CONSOLE_FLAG_BOOT | + console_set_scope(&versal_runtime_console, CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME); /* Initialize the platform config for future decision making */ -- cgit v1.2.3 From e21a788ee197ec66f6b8552e2274297bf4a095a8 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Sat, 25 Jan 2020 01:07:19 +0000 Subject: coreboot: Use generic base address Since now the generic console_t structure holds the UART base address as well, let's use that generic location for the coreboot memory console. This removes the base member from the coreboot specific data structure, but keeps the struct console_cbmc_t and its size member. Change-Id: I7f1dffd41392ba3fe5c07090aea761a42313fb5b Signed-off-by: Andre Przywara --- drivers/coreboot/cbmem_console/aarch64/cbmem_console.S | 6 +++--- include/drivers/coreboot/cbmem_console.h | 4 +--- lib/coreboot/coreboot_table.c | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/coreboot/cbmem_console/aarch64/cbmem_console.S b/drivers/coreboot/cbmem_console/aarch64/cbmem_console.S index fd04c2e7e..a4a7bf8f3 100644 --- a/drivers/coreboot/cbmem_console/aarch64/cbmem_console.S +++ b/drivers/coreboot/cbmem_console/aarch64/cbmem_console.S @@ -35,7 +35,7 @@ * ----------------------------------------------- */ func console_cbmc_register - str x0, [x1, #CONSOLE_T_CBMC_BASE] + str x0, [x1, #CONSOLE_T_BASE] ldr w2, [x0] str w2, [x1, #CONSOLE_T_CBMC_SIZE] mov x0, x1 @@ -54,7 +54,7 @@ endfunc console_cbmc_register */ func console_cbmc_putc ldr w2, [x1, #CONSOLE_T_CBMC_SIZE] - ldr x1, [x1, #CONSOLE_T_CBMC_BASE] + ldr x1, [x1, #CONSOLE_T_BASE] add x1, x1, #8 /* keep address of body in x1 */ ldr w16, [x1, #-4] /* load cursor (one u32 before body) */ @@ -93,7 +93,7 @@ endfunc console_cbmc_putc func console_cbmc_flush mov x5, x30 ldr x1, [x0, #CONSOLE_T_CBMC_SIZE] - ldr x0, [x0, #CONSOLE_T_CBMC_BASE] + ldr x0, [x0, #CONSOLE_T_BASE] add x1, x1, #8 /* add size of console header */ bl clean_dcache_range /* (clobbers x2 and x3) */ mov x0, #0 diff --git a/include/drivers/coreboot/cbmem_console.h b/include/drivers/coreboot/cbmem_console.h index 40c90e6bb..30b39f14d 100644 --- a/include/drivers/coreboot/cbmem_console.h +++ b/include/drivers/coreboot/cbmem_console.h @@ -9,14 +9,12 @@ #include -#define CONSOLE_T_CBMC_BASE CONSOLE_T_DRVDATA -#define CONSOLE_T_CBMC_SIZE (CONSOLE_T_DRVDATA + REGSZ) +#define CONSOLE_T_CBMC_SIZE CONSOLE_T_DRVDATA #ifndef __ASSEMBLER__ typedef struct { console_t console; - uintptr_t base; uint32_t size; } console_cbmc_t; diff --git a/lib/coreboot/coreboot_table.c b/lib/coreboot/coreboot_table.c index 63bdc6359..253fac2ac 100644 --- a/lib/coreboot/coreboot_table.c +++ b/lib/coreboot/coreboot_table.c @@ -75,7 +75,7 @@ static void expand_and_mmap(uintptr_t baseaddr, size_t size) static void setup_cbmem_console(uintptr_t baseaddr) { static console_cbmc_t console; - assert(!console.base); /* should only have one CBMEM console */ + assert(!console.console.base); /* should only have one CBMEM console */ /* CBMEM console structure stores its size in first header field. */ uint32_t size = *(uint32_t *)baseaddr; -- cgit v1.2.3 From 7db9a0b9df68fbc2772dcf8c1b59506a7329c637 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Sat, 25 Jan 2020 23:55:08 +0000 Subject: marvell: Consolidate console register calls Now that different UARTs share the same console_t struct, we can simplify the console selection for the Marvell platforms: We share the same console_t pointers, just change the name of the console register functions, depending on the selected platform. Change-Id: I6fe3e49fd7f208a9b3372c5deef43236a12867bc Signed-off-by: Andre Przywara --- plat/marvell/common/marvell_console.c | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/plat/marvell/common/marvell_console.c b/plat/marvell/common/marvell_console.c index b57b84f3f..17166618a 100644 --- a/plat/marvell/common/marvell_console.c +++ b/plat/marvell/common/marvell_console.c @@ -14,15 +14,14 @@ #ifdef PLAT_a3700 #include - -static console_t marvell_boot_console; -static console_t marvell_runtime_console; +#define console_marvell_register console_a3700_register #else #include +#define console_marvell_register console_16550_register +#endif static console_t marvell_boot_console; static console_t marvell_runtime_console; -#endif /******************************************************************************* * Functions that set up the console @@ -32,15 +31,10 @@ static console_t marvell_runtime_console; void marvell_console_boot_init(void) { int rc = -#ifdef PLAT_a3700 - console_a3700_register( -#else - console_16550_register( -#endif - PLAT_MARVELL_BOOT_UART_BASE, - PLAT_MARVELL_BOOT_UART_CLK_IN_HZ, - MARVELL_CONSOLE_BAUDRATE, - &marvell_boot_console); + console_marvell_register(PLAT_MARVELL_BOOT_UART_BASE, + PLAT_MARVELL_BOOT_UART_CLK_IN_HZ, + MARVELL_CONSOLE_BAUDRATE, + &marvell_boot_console); if (rc == 0) { /* * The crash console doesn't use the multi console API, it uses @@ -64,15 +58,10 @@ void marvell_console_boot_end(void) void marvell_console_runtime_init(void) { int rc = -#ifdef PLAT_a3700 - console_a3700_register( -#else - console_16550_register( -#endif - PLAT_MARVELL_BOOT_UART_BASE, - PLAT_MARVELL_BOOT_UART_CLK_IN_HZ, - MARVELL_CONSOLE_BAUDRATE, - &marvell_runtime_console); + console_marvell_register(PLAT_MARVELL_BOOT_UART_BASE, + PLAT_MARVELL_BOOT_UART_CLK_IN_HZ, + MARVELL_CONSOLE_BAUDRATE, + &marvell_runtime_console); if (rc == 0) panic(); -- cgit v1.2.3 From 17abf9472910ffbed2ceaf1fb56157c01898b9d8 Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Tue, 25 Feb 2020 10:49:00 +0100 Subject: stm32mp1: platform.mk: use PHONY for the appropriate targets Currently, building TF-A for STM32MP1 triggers a full rebuild, avoid this by removing the .PHONY: specification for the final image and replace it by specifying PHONYness for the targets that don't actually produce file output. This will come in handy in follow-up commits, when implicit rules are introduced, as implicit rule search is skipped for .PHONY targets. Change-Id: Ib9966479032b081a54123b99f889760e85639f19 Fixes: f74cbc93a ("stm32mp1: Link BL2, BL32 and DTB in one binary") Signed-off-by: Ahmad Fatoum --- 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 b86287b66..02c338086 100644 --- a/plat/st/stm32mp1/platform.mk +++ b/plat/st/stm32mp1/platform.mk @@ -164,7 +164,7 @@ BL2_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 STM32IMAGEPATH ?= tools/stm32image STM32IMAGE ?= ${STM32IMAGEPATH}/stm32image${BIN_EXT} -.PHONY: ${STM32_TF_STM32} +.PHONY: check_dtc_version stm32image clean_stm32image .SUFFIXES: all: check_dtc_version ${STM32_TF_STM32} stm32image -- cgit v1.2.3 From fc4fdf71e2bcc70b338541948093c3093ccbeafd Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Wed, 29 Jan 2020 18:08:43 +0100 Subject: stm32mp1: platform.mk: generate linker script with fixed name The linker script has no board-specific information that necessitates it having a name derived from the board name. Give it a fixed name, so we can later reuse the same linker script for multiple boards. Change-Id: Ie6650f00389f4ab8577ae82a36c620af9c64101e Signed-off-by: Ahmad Fatoum --- 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 02c338086..f71016b55 100644 --- a/plat/st/stm32mp1/platform.mk +++ b/plat/st/stm32mp1/platform.mk @@ -153,7 +153,7 @@ STM32_DT_BASENAME := $(DTB_FILE_NAME:.dtb=) STM32_TF_STM32 := ${BUILD_PLAT}/tf-a-${STM32_DT_BASENAME}.stm32 STM32_TF_BINARY := $(STM32_TF_STM32:.stm32=.bin) STM32_TF_MAPFILE := $(STM32_TF_STM32:.stm32=.map) -STM32_TF_LINKERFILE := $(STM32_TF_STM32:.stm32=.ld) +STM32_TF_LINKERFILE := ${BUILD_PLAT}/stm32mp1.ld STM32_TF_ELF := $(STM32_TF_STM32:.stm32=.elf) STM32_TF_DTBFILE := ${BUILD_PLAT}/fdts/${DTB_FILE_NAME} STM32_TF_OBJS := ${BUILD_PLAT}/stm32mp1.o -- cgit v1.2.3 From 1a0b5a57af1cb9422e742f4aef7d8f5dafe3d040 Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Wed, 29 Jan 2020 18:13:51 +0100 Subject: stm32mp1: platform.mk: derive map file name from target name Doing this allows us in the next commit to use implicit rules (%-patterns) to cover all the images we generate during a stm32mp1 build. Change-Id: Ibde59d10ccce42566f82820117d7fd0d77345e6c Signed-off-by: Ahmad Fatoum --- plat/st/stm32mp1/platform.mk | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk index f71016b55..9106240b8 100644 --- a/plat/st/stm32mp1/platform.mk +++ b/plat/st/stm32mp1/platform.mk @@ -152,7 +152,6 @@ STM32_TF_ELF_LDFLAGS := --hash-style=gnu --as-needed STM32_DT_BASENAME := $(DTB_FILE_NAME:.dtb=) STM32_TF_STM32 := ${BUILD_PLAT}/tf-a-${STM32_DT_BASENAME}.stm32 STM32_TF_BINARY := $(STM32_TF_STM32:.stm32=.bin) -STM32_TF_MAPFILE := $(STM32_TF_STM32:.stm32=.map) STM32_TF_LINKERFILE := ${BUILD_PLAT}/stm32mp1.ld STM32_TF_ELF := $(STM32_TF_STM32:.stm32=.elf) STM32_TF_DTBFILE := ${BUILD_PLAT}/fdts/${DTB_FILE_NAME} @@ -206,7 +205,7 @@ ${STM32_TF_LINKERFILE}: plat/st/stm32mp1/stm32mp1.ld.S ${BUILD_PLAT} ${STM32_TF_ELF}: ${STM32_TF_OBJS} ${STM32_TF_LINKERFILE} @echo " LDS $<" - ${Q}${LD} -o $@ ${STM32_TF_ELF_LDFLAGS} -Map=${STM32_TF_MAPFILE} --script ${STM32_TF_LINKERFILE} ${STM32_TF_OBJS} + ${Q}${LD} -o $@ ${STM32_TF_ELF_LDFLAGS} -Map=$(@:.elf=.map) --script ${STM32_TF_LINKERFILE} ${STM32_TF_OBJS} ${STM32_TF_BINARY}: ${STM32_TF_ELF} ${Q}${OC} -O binary ${STM32_TF_ELF} $@ @@ -217,7 +216,7 @@ ${STM32_TF_BINARY}: ${STM32_TF_ELF} ${STM32_TF_STM32}: stm32image ${STM32_TF_BINARY} @echo @echo "Generated $@" - $(eval LOADADDR = $(shell cat ${STM32_TF_MAPFILE} | grep RAM | awk '{print $$2}')) - $(eval ENTRY = $(shell cat ${STM32_TF_MAPFILE} | grep "__BL2_IMAGE_START" | awk '{print $$1}')) + $(eval LOADADDR = $(shell cat $(@:.stm32=.map) | grep RAM | awk '{print $$2}')) + $(eval ENTRY = $(shell cat $(@:.stm32=.map) | grep "__BL2_IMAGE_START" | awk '{print $$1}')) ${STM32IMAGE} -s ${STM32_TF_BINARY} -d $@ -l $(LOADADDR) -e ${ENTRY} -v ${STM32_TF_VERSION} @echo -- cgit v1.2.3 From a3db33fd52e4f4409f746d34e95b8ae5a55d491b Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Wed, 29 Jan 2020 18:21:28 +0100 Subject: stm32mp1: platform.mk: migrate to implicit rules Board Support for the stm32mp1 platform is contained in the device tree, so if we remove hardcoding of board name from the Makefile, we can build the intermediary objects once and generate one new tf-a-*.stm32 binary for every device tree specified. All in one go. Prepare for this by employing implicit rules. Change-Id: I5a022a89eb12696cd8cee7bf28ac6be54849901f Signed-off-by: Ahmad Fatoum --- plat/st/stm32mp1/platform.mk | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk index 9106240b8..d68fa258c 100644 --- a/plat/st/stm32mp1/platform.mk +++ b/plat/st/stm32mp1/platform.mk @@ -151,11 +151,7 @@ endif STM32_TF_ELF_LDFLAGS := --hash-style=gnu --as-needed STM32_DT_BASENAME := $(DTB_FILE_NAME:.dtb=) STM32_TF_STM32 := ${BUILD_PLAT}/tf-a-${STM32_DT_BASENAME}.stm32 -STM32_TF_BINARY := $(STM32_TF_STM32:.stm32=.bin) STM32_TF_LINKERFILE := ${BUILD_PLAT}/stm32mp1.ld -STM32_TF_ELF := $(STM32_TF_STM32:.stm32=.elf) -STM32_TF_DTBFILE := ${BUILD_PLAT}/fdts/${DTB_FILE_NAME} -STM32_TF_OBJS := ${BUILD_PLAT}/stm32mp1.o BL2_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 @@ -191,32 +187,32 @@ check_dtc_version: fi -${STM32_TF_OBJS}: plat/st/stm32mp1/stm32mp1.S bl2 ${BL32_DEP} ${STM32_TF_DTBFILE} - @echo " AS $<" +${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} \ ${BL32_PATH} \ -DBL2_BIN_PATH=\"${BUILD_PLAT}/bl2.bin\" \ - -DDTB_BIN_PATH=\"${STM32_TF_DTBFILE}\" \ + -DDTB_BIN_PATH=\"$<\" \ -c plat/st/stm32mp1/stm32mp1.S -o $@ ${STM32_TF_LINKERFILE}: plat/st/stm32mp1/stm32mp1.ld.S ${BUILD_PLAT} @echo " LDS $<" ${Q}${AS} ${ASFLAGS} ${TF_CFLAGS} -P -E $< -o $@ -${STM32_TF_ELF}: ${STM32_TF_OBJS} ${STM32_TF_LINKERFILE} +tf-a-%.elf: stm32mp1-%.o ${STM32_TF_LINKERFILE} @echo " LDS $<" - ${Q}${LD} -o $@ ${STM32_TF_ELF_LDFLAGS} -Map=$(@:.elf=.map) --script ${STM32_TF_LINKERFILE} ${STM32_TF_OBJS} + ${Q}${LD} -o $@ ${STM32_TF_ELF_LDFLAGS} -Map=$(@:.elf=.map) --script ${STM32_TF_LINKERFILE} $< -${STM32_TF_BINARY}: ${STM32_TF_ELF} - ${Q}${OC} -O binary ${STM32_TF_ELF} $@ +tf-a-%.bin: tf-a-%.elf + ${Q}${OC} -O binary $< $@ @echo @echo "Built $@ successfully" @echo -${STM32_TF_STM32}: stm32image ${STM32_TF_BINARY} +tf-a-%.stm32: tf-a-%.bin stm32image @echo @echo "Generated $@" $(eval LOADADDR = $(shell cat $(@:.stm32=.map) | grep RAM | awk '{print $$2}')) $(eval ENTRY = $(shell cat $(@:.stm32=.map) | grep "__BL2_IMAGE_START" | awk '{print $$1}')) - ${STM32IMAGE} -s ${STM32_TF_BINARY} -d $@ -l $(LOADADDR) -e ${ENTRY} -v ${STM32_TF_VERSION} + ${STM32IMAGE} -s $< -d $@ -l $(LOADADDR) -e ${ENTRY} -v ${STM32_TF_VERSION} @echo -- cgit v1.2.3 From e772a6d1864af79372b593ad20ee1c7599d2cfa2 Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Wed, 29 Jan 2020 18:55:55 +0100 Subject: stm32mp1: platform.mk: support generating multiple images in one build Board Support for the stm32mp1 platform is contained in the device tree, so if we remove hardcoding of board name from the Makefile, we can build the intermediary objects once and generate one new tf-a-*.stm32 binary for every device tree specified. All in one go. With implicit rules implemented, we only need to change the top level target to support multi-image builds on the stm32mp1. Change-Id: I4cae7d32a4c03a3c29c559dc5332e002223902c1 Signed-off-by: Ahmad Fatoum --- plat/st/stm32mp1/platform.mk | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk index d68fa258c..bd1a16bf7 100644 --- a/plat/st/stm32mp1/platform.mk +++ b/plat/st/stm32mp1/platform.mk @@ -149,8 +149,7 @@ endif # Macros and rules to build TF binary STM32_TF_ELF_LDFLAGS := --hash-style=gnu --as-needed -STM32_DT_BASENAME := $(DTB_FILE_NAME:.dtb=) -STM32_TF_STM32 := ${BUILD_PLAT}/tf-a-${STM32_DT_BASENAME}.stm32 +STM32_TF_STM32 := $(addprefix ${BUILD_PLAT}/tf-a-, $(patsubst %.dtb,%.stm32,$(DTB_FILE_NAME))) STM32_TF_LINKERFILE := ${BUILD_PLAT}/stm32mp1.ld BL2_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 -- cgit v1.2.3 From b3c431f35b45bdd284fd041785bdf28b32049c1a Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Mon, 24 Feb 2020 10:39:31 +0000 Subject: FVP: Fix incorrect GIC mapping This patch fixes incorrect setting for DEVICE1_SIZE for FVP platforms with more than 8 PEs. The current value of 0x200000 supports only 8 PEs and causes exception for FVP platforms with the greater number of PEs, e.g. FVP_Base_Cortex_A65AEx8 with 16 PEs in one cluster. Change-Id: Ie6391509fe6eeafb8ba779303636cd762e7d21b2 Signed-off-by: Alexei Fedorov --- plat/arm/board/fvp/fvp_def.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/plat/arm/board/fvp/fvp_def.h b/plat/arm/board/fvp/fvp_def.h index 347ba2e1e..909b68717 100644 --- a/plat/arm/board/fvp/fvp_def.h +++ b/plat/arm/board/fvp/fvp_def.h @@ -52,8 +52,10 @@ #define DEVICE1_BASE UL(0x2e000000) #define DEVICE1_SIZE UL(0x1A00000) #else -#define DEVICE1_BASE UL(0x2f000000) -#define DEVICE1_SIZE UL(0x200000) +/* GICv2 and GICv3 mapping: GICD + CORE_COUNT * 128KB */ +#define DEVICE1_BASE BASE_GICD_BASE +#define DEVICE1_SIZE ((BASE_GICR_BASE - BASE_GICD_BASE) + \ + (PLATFORM_CORE_COUNT * 0x20000)) #define NSRAM_BASE UL(0x2e000000) #define NSRAM_SIZE UL(0x10000) #endif @@ -110,7 +112,7 @@ #define FVP_SP810_CTRL_TIM3_OV BIT_32(22) /******************************************************************************* - * GIC-400 & interrupt handling related constants + * GIC & interrupt handling related constants ******************************************************************************/ /* VE compatible GIC memory map */ #define VE_GICD_BASE UL(0x2c001000) @@ -128,7 +130,6 @@ #define FVP_IRQ_TZ_WDOG 56 #define FVP_IRQ_SEC_SYS_TIMER 57 - /******************************************************************************* * TrustZone address space controller related constants ******************************************************************************/ -- cgit v1.2.3 From dd53cfe19fdc80af47ca53da8d45e3599b337323 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 3 Feb 2020 19:46:40 +0900 Subject: uniphier: prepare uniphier_soc_info() for next SoC The revision register address will be changed in the next SoC. The LSI revision is needed in order to know where the revision register is located, but you need to read out the revision register for that. This is impossible. We need to know the revision register address by other means. Use BL_CODE_BASE, where the base address of the TF image that is currently running. If it is bigger than 0x80000000 (i.e. the DRAM base is 0x80000000), we assume it is a legacy SoC. Change-Id: I9d7f4325fe2085a8a1ab5310025e5948da611256 Signed-off-by: Masahiro Yamada --- plat/socionext/uniphier/uniphier_soc_info.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/plat/socionext/uniphier/uniphier_soc_info.c b/plat/socionext/uniphier/uniphier_soc_info.c index 377532deb..0e7a2d11a 100644 --- a/plat/socionext/uniphier/uniphier_soc_info.c +++ b/plat/socionext/uniphier/uniphier_soc_info.c @@ -4,18 +4,25 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include #include #include "uniphier.h" -#define UNIPHIER_REVISION 0x5f800000 +#define UNIPHIER_REVISION 0x5f800000UL +#define UNIPHIER_REVISION_NEW 0x1f800000UL static unsigned int uniphier_get_revision_field(unsigned int mask, unsigned int shift) { - uint32_t revision = mmio_read_32(UNIPHIER_REVISION); + uintptr_t reg; - return (revision >> shift) & mask; + if (BL_CODE_BASE >= 0x80000000UL) + reg = UNIPHIER_REVISION; + else + reg = UNIPHIER_REVISION_NEW; + + return (mmio_read_32(reg) >> shift) & mask; } unsigned int uniphier_get_soc_type(void) -- cgit v1.2.3 From e718e61b8ef7b38bcc20f3f51ecad4fb5b57c126 Mon Sep 17 00:00:00 2001 From: Imre Kis Date: Tue, 17 Dec 2019 18:06:26 +0100 Subject: Modify multithreaded dts file of DynamIQ FVPs The dts file now contains a CPU map that precisely describes the topology including thread nodes. The map was also extended to have 16 PEs to be able to test multithreaded FVPs with 8 cores in the same cluster. Signed-off-by: Imre Kis Change-Id: If39559b05d20bfd68d0ecf830ddcbc5233b288a0 --- fdts/fvp-base-gicv3-psci-dynamiq-2t.dts | 191 ++++++++++++++++++++++++++++---- 1 file changed, 169 insertions(+), 22 deletions(-) diff --git a/fdts/fvp-base-gicv3-psci-dynamiq-2t.dts b/fdts/fvp-base-gicv3-psci-dynamiq-2t.dts index daa2e66ce..6e63b4351 100644 --- a/fdts/fvp-base-gicv3-psci-dynamiq-2t.dts +++ b/fdts/fvp-base-gicv3-psci-dynamiq-2t.dts @@ -8,34 +8,181 @@ #include "fvp-base-gicv3-psci-dynamiq-common.dtsi" -&CPU0 { - reg = <0x0 0x0>; -}; +&CPU_MAP { + /delete-node/ cluster0; -&CPU1 { - reg = <0x0 0x1>; + cluster0 { + core0 { + thread0 { + cpu = <&CPU0>; + }; + thread1 { + cpu = <&CPU1>; + }; + }; + core1 { + thread0 { + cpu = <&CPU2>; + }; + thread1 { + cpu = <&CPU3>; + }; + }; + core2 { + thread0 { + cpu = <&CPU4>; + }; + thread1 { + cpu = <&CPU5>; + }; + }; + core3 { + thread0 { + cpu = <&CPU6>; + }; + thread1 { + cpu = <&CPU7>; + }; + }; + core4 { + thread0 { + cpu = <&CPU8>; + }; + thread1 { + cpu = <&CPU9>; + }; + }; + core5 { + thread0 { + cpu = <&CPU10>; + }; + thread1 { + cpu = <&CPU11>; + }; + }; + core6 { + thread0 { + cpu = <&CPU12>; + }; + thread1 { + cpu = <&CPU13>; + }; + }; + core7 { + thread0 { + cpu = <&CPU14>; + }; + thread1 { + cpu = <&CPU15>; + }; + }; + }; }; -&CPU2 { - reg = <0x0 0x100>; -}; +/ { + cpus { + CPU0:cpu@0 { + reg = <0x0 0x0>; + }; -&CPU3 { - reg = <0x0 0x101>; -}; + CPU1:cpu@1 { + reg = <0x0 0x1>; + }; -&CPU4 { - reg = <0x0 0x200>; -}; + CPU2:cpu@2 { + reg = <0x0 0x100>; + }; -&CPU5 { - reg = <0x0 0x201>; -}; + CPU3:cpu@3 { + reg = <0x0 0x101>; + }; -&CPU6 { - reg = <0x0 0x300>; -}; + CPU4:cpu@100 { + reg = <0x0 0x200>; + }; + + CPU5:cpu@101 { + reg = <0x0 0x201>; + }; + + CPU6:cpu@102 { + reg = <0x0 0x300>; + }; + + CPU7:cpu@103 { + reg = <0x0 0x301>; + }; + + CPU8:cpu@200 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x400>; + enable-method = "psci"; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + next-level-cache = <&L2_0>; + }; + + CPU9:cpu@201 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x401>; + enable-method = "psci"; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + next-level-cache = <&L2_0>; + }; + + CPU10:cpu@202 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x500>; + enable-method = "psci"; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + next-level-cache = <&L2_0>; + }; + + CPU11:cpu@203 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x501>; + enable-method = "psci"; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + next-level-cache = <&L2_0>; + }; + + CPU12:cpu@300 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x600>; + enable-method = "psci"; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + next-level-cache = <&L2_0>; + }; + + CPU13:cpu@301 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x601>; + enable-method = "psci"; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + next-level-cache = <&L2_0>; + }; + + CPU14:cpu@302 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x700>; + enable-method = "psci"; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + next-level-cache = <&L2_0>; + }; -&CPU7 { - reg = <0x0 0x301>; + CPU15:cpu@303 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x701>; + enable-method = "psci"; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + next-level-cache = <&L2_0>; + }; + }; }; -- cgit v1.2.3 From 5a97479bbd9750abfa9bc819bdc30c3f9f51e31c Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Wed, 26 Feb 2020 13:49:09 +0000 Subject: change-log: Add fconf entry Change-Id: I6686f172d0c24f6c457a39cdf4debcbf05475540 Signed-off-by: Louis Mayencourt --- docs/change-log-upcoming.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/change-log-upcoming.rst b/docs/change-log-upcoming.rst index 14280cbf7..c4e8bb0d8 100644 --- a/docs/change-log-upcoming.rst +++ b/docs/change-log-upcoming.rst @@ -33,6 +33,7 @@ New Features - Libraries - Example: "Introduce BTI support in Library at ROM (romlib)" + - Add Firmware Configuration Framework (fconf). - New Platforms Support - Example: "qemu/qemu_sbsa: New platform support added for QEMU SBSA platform" -- cgit v1.2.3 From e58901d4bc9507f0d7060a71509cb6bb78b3a947 Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Wed, 26 Feb 2020 15:52:23 +0100 Subject: amlogic/axg: Add documentation page to the index It is needed to make it appear in the table of contents. Right now, all Amlogic documentation pages appear under the "Platform ports" section, except the AXG one. Change-Id: Ibcfc3b156888d2a9574953578978b629e185c708 Signed-off-by: Sandrine Bailleux --- docs/plat/index.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/plat/index.rst b/docs/plat/index.rst index 63d29a9be..a6ef1884b 100644 --- a/docs/plat/index.rst +++ b/docs/plat/index.rst @@ -9,6 +9,7 @@ Platform Ports allwinner arm/index + meson-axg meson-gxbb meson-gxl meson-g12a @@ -53,4 +54,4 @@ documentation associated with them. -------------- -*Copyright (c) 2019, Arm Limited. All rights reserved.* +*Copyright (c) 2019-2020, Arm Limited. All rights reserved.* -- cgit v1.2.3 From 548957478eca2cca98a11ae4450ec1781ca920b0 Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Wed, 26 Feb 2020 16:57:05 +0100 Subject: Update pathnames in maintainers.rst file The maintainers.rst file lists files and directories that each contributor looks after in the TF-A source tree. As files and directories move around over time, some pathnames had become invalid. Fix them, either by updating the path if it has just moved, or deleting it altogether if it doesn't seem to exist anymore. Change-Id: Idb6ff4d8d0b593138d4f555ec206abcf68b0064f Signed-off-by: Sandrine Bailleux --- docs/about/maintainers.rst | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst index 802dafcd8..2bf5eb7ba 100644 --- a/docs/about/maintainers.rst +++ b/docs/about/maintainers.rst @@ -53,7 +53,6 @@ Amlogic Meson S905x (GXL) platform port :M: Remi Pommarel :G: `remi-triplefault`_ :F: docs/plat/meson-gxl.rst -:F: drivers/amlogic/gxl :F: plat/amlogic/gxl/ Amlogic Meson S905X2 (G12A) platform port @@ -61,7 +60,6 @@ Amlogic Meson S905X2 (G12A) platform port :M: Carlo Caione :G: `carlocaione`_ :F: docs/plat/meson-g12a.rst -:F: drivers/amlogic/g12a :F: plat/amlogic/g12a/ Amlogic Meson A113D (AXG) platform port @@ -69,7 +67,6 @@ Amlogic Meson A113D (AXG) platform port :M: Carlo Caione :G: `carlocaione`_ :F: docs/plat/meson-axg.rst -:F: drivers/amlogic/axg :F: plat/amlogic/axg/ Armv7-A architecture port @@ -152,7 +149,7 @@ Marvell platform ports and SoC drivers -------------------------------------- :M: Konstantin Porotchkin :G: `kostapr`_ -:F: docs/marvell/ +:F: docs/plat/marvell/ :F: plat/marvell/ :F: drivers/marvell/ :F: tools/marvell/ @@ -197,14 +194,14 @@ NXP i.MX8M platform port ------------------------ :M: Jacky Bai :G: `JackyBai`_ -:F: doc/plat/imx8m.rst +:F: docs/plat/imx8m.rst :F: plat/imx/imx8m/ OP-TEE dispatcher ----------------- :M: Jens Wiklander :G: `jenswi-linaro`_ -:F: docs/spd/optee-dispatcher.rst +:F: docs/components/spd/optee-dispatcher.rst :F: services/spd/opteed/ QEMU platform port @@ -219,7 +216,7 @@ Raspberry Pi 3 platform port :M: Ying-Chun Liu (PaulLiu) :G: `grandpaul`_ :F: docs/plat/rpi3.rst -:F: plat/rpi3/ +:F: plat/rpi/rpi3/ :F: drivers/rpi3/ :F: include/drivers/rpi3/ @@ -273,8 +270,8 @@ TLK/Trusty secure payloads -------------------------- :M: Varun Wadekar :G: `vwadekar`_ -:F: docs/spd/tlk-dispatcher.rst -:F: docs/spd/trusty-dispatcher.rst +:F: docs/components/spd/tlk-dispatcher.rst +:F: docs/components/spd/trusty-dispatcher.rst :F: include/bl32/payloads/tlk.h :F: services/spd/tlkd/ :F: services/spd/trusty/ -- cgit v1.2.3 From d7db9a6a047c84d3aca0fe7240368d65e66567a4 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 27 Feb 2020 12:16:32 +0900 Subject: Build: fix 'BL stage' comment for build macros The MAKE_BL macro is invoked for 1, 2, 2u, 31, 32. Fix the comments. Change-Id: I35dd25cc2ea13885c184fb9c8229a322b33f7e71 Signed-off-by: Masahiro Yamada --- make_helpers/build_macros.mk | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk index b6925d3b1..032e42c15 100644 --- a/make_helpers/build_macros.mk +++ b/make_helpers/build_macros.mk @@ -79,32 +79,32 @@ $(if $(word $(2), $($(1))),\ endef # IMG_LINKERFILE defines the linker script corresponding to a BL stage -# $(1) = BL stage (2, 30, 31, 32, 33) +# $(1) = BL stage (1, 2, 2u, 31, 32) define IMG_LINKERFILE ${BUILD_DIR}/bl$(1).ld endef # IMG_MAPFILE defines the output file describing the memory map corresponding # to a BL stage -# $(1) = BL stage (2, 30, 31, 32, 33) +# $(1) = BL stage (1, 2, 2u, 31, 32) define IMG_MAPFILE ${BUILD_DIR}/bl$(1).map endef # IMG_ELF defines the elf file corresponding to a BL stage -# $(1) = BL stage (2, 30, 31, 32, 33) +# $(1) = BL stage (1, 2, 2u, 31, 32) define IMG_ELF ${BUILD_DIR}/bl$(1).elf endef # IMG_DUMP defines the symbols dump file corresponding to a BL stage -# $(1) = BL stage (2, 30, 31, 32, 33) +# $(1) = BL stage (1, 2, 2u, 31, 32) define IMG_DUMP ${BUILD_DIR}/bl$(1).dump endef # IMG_BIN defines the default image file corresponding to a BL stage -# $(1) = BL stage (2, 30, 31, 32, 33) +# $(1) = BL stage (1, 2, 2u, 31, 32) define IMG_BIN ${BUILD_PLAT}/bl$(1).bin endef @@ -237,7 +237,7 @@ endef # MAKE_C builds a C source file and generates the dependency file # $(1) = output directory # $(2) = source file (%.c) -# $(3) = BL stage (2, 2u, 30, 31, 32, 33) +# $(3) = BL stage (1, 2, 2u, 31, 32) define MAKE_C $(eval OBJ := $(1)/$(patsubst %.c,%.o,$(notdir $(2)))) @@ -257,7 +257,7 @@ endef # MAKE_S builds an assembly source file and generates the dependency file # $(1) = output directory # $(2) = assembly file (%.S) -# $(3) = BL stage (2, 2u, 30, 31, 32, 33) +# $(3) = BL stage (1, 2, 2u, 31, 32) define MAKE_S $(eval OBJ := $(1)/$(patsubst %.S,%.o,$(notdir $(2)))) @@ -276,7 +276,7 @@ endef # MAKE_LD generate the linker script using the C preprocessor # $(1) = output linker script # $(2) = input template -# $(3) = BL stage (2, 2u, 30, 31, 32, 33) +# $(3) = BL stage (1, 2, 2u, 31, 32) define MAKE_LD $(eval DEP := $(1).d) @@ -310,7 +310,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 (2, 30, 31, 32, 33) +# $(3) = BL stage (1, 2, 2u, 31, 32) define MAKE_OBJS $(eval C_OBJS := $(filter %.c,$(2))) $(eval REMAIN := $(filter-out %.c,$(2))) @@ -387,7 +387,7 @@ endef # MAKE_BL macro defines the targets and options to build each BL image. # Arguments: -# $(1) = BL stage (2, 2u, 30, 31, 32, 33) +# $(1) = BL stage (1, 2, 2u, 31, 32) # $(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) define MAKE_BL -- cgit v1.2.3 From 960896eb897b606a017b52abb7e0f527a0e66aeb Mon Sep 17 00:00:00 2001 From: "Abdul Halim, Muhammad Hadi Asyrafi" Date: Thu, 27 Feb 2020 10:23:48 +0800 Subject: intel: Update RSU driver return code Modify RSU driver error code for backward-compatibility with Linux RSU driver Signed-off-by: Abdul Halim, Muhammad Hadi Asyrafi Change-Id: Ib9e38d4017efe35d3aceeee27dce451fbd429fb5 --- plat/intel/soc/common/include/socfpga_sip_svc.h | 4 +++- plat/intel/soc/common/socfpga_sip_svc.c | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h index 2b1d9837c..19a52f7b9 100644 --- a/plat/intel/soc/common/include/socfpga_sip_svc.h +++ b/plat/intel/soc/common/include/socfpga_sip_svc.h @@ -10,9 +10,11 @@ /* SiP status response */ #define INTEL_SIP_SMC_STATUS_OK 0 -#define INTEL_SIP_SMC_STATUS_ERROR 0x4 #define INTEL_SIP_SMC_STATUS_BUSY 0x1 #define INTEL_SIP_SMC_STATUS_REJECTED 0x2 +#define INTEL_SIP_SMC_STATUS_ERROR 0x4 +#define INTEL_SIP_SMC_RSU_ERROR 0x7 + /* SMC SiP service function identifier */ #define INTEL_SIP_SMC_FPGA_CONFIG_START 0xC2000001 diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c index 1c3d45bee..b15fa3d52 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -374,7 +374,7 @@ uint64_t intel_rsu_update_address; static uint32_t intel_rsu_status(uint64_t *respbuf, uint32_t respbuf_sz) { if (mailbox_rsu_status((uint32_t *)respbuf, respbuf_sz) < 0) - return INTEL_SIP_SMC_STATUS_ERROR; + return INTEL_SIP_SMC_RSU_ERROR; return INTEL_SIP_SMC_STATUS_OK; } @@ -388,7 +388,7 @@ static uint32_t intel_rsu_update(uint64_t update_address) static uint32_t intel_rsu_notify(uint64_t execution_stage) { if (mailbox_hps_stage_notify(execution_stage) < 0) - return INTEL_SIP_SMC_STATUS_ERROR; + return INTEL_SIP_SMC_RSU_ERROR; return INTEL_SIP_SMC_STATUS_OK; } @@ -397,7 +397,7 @@ static uint32_t intel_rsu_retry_counter(uint32_t *respbuf, uint32_t respbuf_sz, uint32_t *ret_stat) { if (mailbox_rsu_status((uint32_t *)respbuf, respbuf_sz) < 0) - return INTEL_SIP_SMC_STATUS_ERROR; + return INTEL_SIP_SMC_RSU_ERROR; *ret_stat = respbuf[8]; return INTEL_SIP_SMC_STATUS_OK; -- cgit v1.2.3 From 4ebdbc70836313087667d4c27cfc4bc13e95c48b Mon Sep 17 00:00:00 2001 From: Imre Kis Date: Thu, 27 Feb 2020 15:05:03 +0100 Subject: Add Cortex-A65/AE to the supported FVP list Cortex-A65x4 and Cortex-A65AEx8 is now included in the list of the supported Arm Fixed Virtual Platforms. Signed-off-by: Imre Kis Change-Id: Ibfcaec11bc75549d60455e96858d79b679e71e5e --- docs/plat/arm/fvp/index.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/plat/arm/fvp/index.rst b/docs/plat/arm/fvp/index.rst index 40e966117..169b6f366 100644 --- a/docs/plat/arm/fvp/index.rst +++ b/docs/plat/arm/fvp/index.rst @@ -26,6 +26,8 @@ Arm FVPs without shifted affinities, and that do not support threaded CPU cores - ``FVP_Base_Cortex-A57x2-A53x4`` - ``FVP_Base_Cortex-A57x4-A53x4`` - ``FVP_Base_Cortex-A57x4`` +- ``FVP_Base_Cortex-A65x4`` (Version 11.9 build 41) +- ``FVP_Base_Cortex-A65AEx8`` (Version 11.9 build 41) - ``FVP_Base_Cortex-A72x4-A53x4`` - ``FVP_Base_Cortex-A72x4`` - ``FVP_Base_Cortex-A73x4-A53x4`` @@ -628,7 +630,7 @@ boot Linux with 4 CPUs using the AArch32 build of TF-A. -------------- -*Copyright (c) 2019, Arm Limited. All rights reserved.* +*Copyright (c) 2019-2020, Arm Limited. All rights reserved.* .. _TB_FW_CONFIG for FVP: ../plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts .. _Arm's website: `FVP models`_ -- cgit v1.2.3 From 845db72261658ec8f1f3c10b0f7408b19fb91a7e Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Mon, 24 Feb 2020 14:37:25 +0000 Subject: fconf: Fix misra issues MISRA C-2012 Rule 20.7: Macro parameter expands into an expression without being wrapped by parentheses. MISRA C-2012 Rule 12.1: Missing explicit parentheses on sub-expression. MISRA C-2012 Rule 18.4: Essential type of the left hand operand is not the same as that of the right operand. Include does not provide any needed symbols. Change-Id: Ie1c6451cfbc8f519146c28b2cf15c50b1f36adc8 Signed-off-by: Louis Mayencourt --- include/lib/fconf/fconf.h | 6 +++--- include/lib/object_pool.h | 6 +++--- plat/arm/common/arm_dyn_cfg.c | 1 - plat/arm/common/arm_fconf_io_storage.c | 1 - plat/arm/common/fconf/arm_fconf_io.c | 4 ++-- 5 files changed, 8 insertions(+), 10 deletions(-) diff --git a/include/lib/fconf/fconf.h b/include/lib/fconf/fconf.h index f58ff5710..0401e5c06 100644 --- a/include/lib/fconf/fconf.h +++ b/include/lib/fconf/fconf.h @@ -14,9 +14,9 @@ #define FCONF_REGISTER_POPULATOR(name, callback) \ __attribute__((used, section(".fconf_populator"))) \ - const struct fconf_populator name##__populator = { \ - .info = #name, \ - .populate = callback \ + const struct fconf_populator (name##__populator) = { \ + .info = (#name), \ + .populate = (callback) \ }; /* diff --git a/include/lib/object_pool.h b/include/lib/object_pool.h index 0f85331a8..66e8c4780 100644 --- a/include/lib/object_pool.h +++ b/include/lib/object_pool.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -56,13 +56,13 @@ struct object_pool { */ static inline void *pool_alloc_n(struct object_pool *pool, size_t count) { - if (pool->used + count > pool->capacity) { + if ((pool->used + count) > pool->capacity) { ERROR("Cannot allocate %zu objects out of pool (%zu objects left).\n", count, pool->capacity - pool->used); panic(); } - void *obj = (char *)(pool->objects) + pool->obj_size * pool->used; + void *obj = (char *)(pool->objects) + (pool->obj_size * pool->used); pool->used += count; return obj; } diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c index 443d40fe8..df7530733 100644 --- a/plat/arm/common/arm_dyn_cfg.c +++ b/plat/arm/common/arm_dyn_cfg.c @@ -21,7 +21,6 @@ #include #include #include -#include #if TRUSTED_BOARD_BOOT diff --git a/plat/arm/common/arm_fconf_io_storage.c b/plat/arm/common/arm_fconf_io_storage.c index 341622a0b..6fcfbd6fb 100644 --- a/plat/arm/common/arm_fconf_io_storage.c +++ b/plat/arm/common/arm_fconf_io_storage.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include diff --git a/plat/arm/common/fconf/arm_fconf_io.c b/plat/arm/common/fconf/arm_fconf_io.c index 3c0586fd0..cfcddc2b2 100644 --- a/plat/arm/common/fconf/arm_fconf_io.c +++ b/plat/arm/common/fconf/arm_fconf_io.c @@ -59,9 +59,9 @@ struct plat_io_policy policies[MAX_NUMBER_IDS] = { #ifdef IMAGE_BL2 #if TRUSTED_BOARD_BOOT -#define FCONF_ARM_IO_UUID_NUMBER 19 +#define FCONF_ARM_IO_UUID_NUMBER U(19) #else -#define FCONF_ARM_IO_UUID_NUMBER 10 +#define FCONF_ARM_IO_UUID_NUMBER U(10) #endif static io_uuid_spec_t fconf_arm_uuids[FCONF_ARM_IO_UUID_NUMBER]; -- cgit v1.2.3 From 6bc243825f561e87ef7af7f51b218c6b0dab9b78 Mon Sep 17 00:00:00 2001 From: Madhukar Pappireddy Date: Wed, 26 Feb 2020 12:37:05 -0600 Subject: aarch32: stop speculative execution past exception returns aarch32 CPUs speculatively execute instructions following a ERET as if it was not a jump instruction. This could lead to cache-based side channel vulnerabilities. The software fix is to place barrier instructions following ERET. The counterpart patch for aarch64 is merged: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/commit/?id=f461fe346b728d0e88142fd7b8f2816415af18bc Change-Id: I2aa3105bee0b92238f389830b3a3b8650f33af3d Signed-off-by: Madhukar Pappireddy --- bl1/aarch32/bl1_exceptions.S | 2 +- bl2/aarch32/bl2_el3_entrypoint.S | 2 +- include/arch/aarch32/asm_macros.S | 15 ++++++++++++++- include/arch/aarch32/smccc_macros.S | 2 +- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/bl1/aarch32/bl1_exceptions.S b/bl1/aarch32/bl1_exceptions.S index f2af9ab5b..493d2ca4e 100644 --- a/bl1/aarch32/bl1_exceptions.S +++ b/bl1/aarch32/bl1_exceptions.S @@ -80,7 +80,7 @@ debug_loop: add r8, r8, #ENTRY_POINT_INFO_ARGS_OFFSET ldm r8, {r0, r1, r2, r3} - eret + exception_return endfunc bl1_aarch32_smc_handler /* ----------------------------------------------------- diff --git a/bl2/aarch32/bl2_el3_entrypoint.S b/bl2/aarch32/bl2_el3_entrypoint.S index 9b4da6b13..2e851e61a 100644 --- a/bl2/aarch32/bl2_el3_entrypoint.S +++ b/bl2/aarch32/bl2_el3_entrypoint.S @@ -87,5 +87,5 @@ func bl2_run_next_image add r8, r8, #ENTRY_POINT_INFO_ARGS_OFFSET ldm r8, {r0, r1, r2, r3} - eret + exception_return endfunc bl2_run_next_image diff --git a/include/arch/aarch32/asm_macros.S b/include/arch/aarch32/asm_macros.S index 8cfa21231..ea1636e24 100644 --- a/include/arch/aarch32/asm_macros.S +++ b/include/arch/aarch32/asm_macros.S @@ -95,11 +95,24 @@ #if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION) /* + * Macro for mitigating against speculative execution. * ARMv7 cores without Virtualization extension do not support the * eret instruction. */ - .macro eret + .macro exception_return movs pc, lr + dsb nsh + isb + .endm + +#else + /* + * Macro for mitigating against speculative execution beyond ERET. + */ + .macro exception_return + eret + dsb nsh + isb .endm #endif diff --git a/include/arch/aarch32/smccc_macros.S b/include/arch/aarch32/smccc_macros.S index 4ec229218..ea7835a42 100644 --- a/include/arch/aarch32/smccc_macros.S +++ b/include/arch/aarch32/smccc_macros.S @@ -235,7 +235,7 @@ /* Restore the rest of the general purpose registers */ ldm r0, {r0-r12} - eret + exception_return .endm #endif /* SMCCC_MACROS_S */ -- cgit v1.2.3 From 28f39f02ade1bd3ae86c8a472d01873ba0cdacb7 Mon Sep 17 00:00:00 2001 From: Max Shvetsov Date: Tue, 25 Feb 2020 13:56:19 +0000 Subject: SPMD: save/restore EL2 system registers. NOTE: Not all EL-2 system registers are saved/restored. This subset includes registers recognized by ARMv8.0 Change-Id: I9993c7d78d8f5f8e72d1c6c8d6fd871283aa3ce0 Signed-off-by: Jose Marinho Signed-off-by: Olivier Deprez Signed-off-by: Artsem Artsemenka Signed-off-by: Max Shvetsov --- Makefile | 61 ++--- include/arch/aarch64/arch.h | 27 +++ include/lib/el3_runtime/aarch64/context.h | 99 +++++++- include/lib/el3_runtime/context_mgmt.h | 5 + lib/el3_runtime/aarch64/context.S | 391 +++++++++++++++++++++++++++++- lib/el3_runtime/aarch64/context_mgmt.c | 46 ++++ make_helpers/defaults.mk | 5 + services/std_svc/spmd/spmd_main.c | 10 + 8 files changed, 608 insertions(+), 36 deletions(-) diff --git a/Makefile b/Makefile index 03f9fc6d8..a84c413b8 100644 --- a/Makefile +++ b/Makefile @@ -412,40 +412,45 @@ INCLUDE_TBBR_MK := 1 ################################################################################ ifneq (${SPD},none) -ifeq (${ARCH},aarch32) + ifeq (${ARCH},aarch32) $(error "Error: SPD is incompatible with AArch32.") -endif -ifdef EL3_PAYLOAD_BASE + endif + + ifdef EL3_PAYLOAD_BASE $(warning "SPD and EL3_PAYLOAD_BASE are incompatible build options.") $(warning "The SPD and its BL32 companion will be present but ignored.") -endif - ifeq (${SPD},spmd) - # SPMD is located in std_svc directory - SPD_DIR := std_svc - else - # All other SPDs in spd directory - SPD_DIR := spd - endif - - # We expect to locate an spd.mk under the specified SPD directory - SPD_MAKE := $(wildcard services/${SPD_DIR}/${SPD}/${SPD}.mk) + endif + ifeq (${SPD},spmd) + # SPMD is located in std_svc directory + SPD_DIR := std_svc - ifeq (${SPD_MAKE},) - $(error Error: No services/${SPD_DIR}/${SPD}/${SPD}.mk located) + ifeq ($(CTX_INCLUDE_EL2_REGS),0) + $(error spmd requires CTX_INCLUDE_EL2_REGS option) endif - $(info Including ${SPD_MAKE}) - include ${SPD_MAKE} + else + # All other SPDs in spd directory + SPD_DIR := spd + endif + + # We expect to locate an spd.mk under the specified SPD directory + SPD_MAKE := $(wildcard services/${SPD_DIR}/${SPD}/${SPD}.mk) + + ifeq (${SPD_MAKE},) + $(error Error: No services/${SPD_DIR}/${SPD}/${SPD}.mk located) + endif + $(info Including ${SPD_MAKE}) + include ${SPD_MAKE} - # If there's BL32 companion for the chosen SPD, we expect that the SPD's - # Makefile would set NEED_BL32 to "yes". In this case, the build system - # supports two mutually exclusive options: - # * BL32 is built from source: then BL32_SOURCES must contain the list - # of source files to build BL32 - # * BL32 is a prebuilt binary: then BL32 must point to the image file - # that will be included in the FIP - # If both BL32_SOURCES and BL32 are defined, the binary takes precedence - # over the sources. + # If there's BL32 companion for the chosen SPD, we expect that the SPD's + # Makefile would set NEED_BL32 to "yes". In this case, the build system + # supports two mutually exclusive options: + # * BL32 is built from source: then BL32_SOURCES must contain the list + # of source files to build BL32 + # * BL32 is a prebuilt binary: then BL32 must point to the image file + # that will be included in the FIP + # If both BL32_SOURCES and BL32 are defined, the binary takes precedence + # over the sources. endif ################################################################################ @@ -761,6 +766,7 @@ $(eval $(call assert_boolean,CTX_INCLUDE_AARCH32_REGS)) $(eval $(call assert_boolean,CTX_INCLUDE_FPREGS)) $(eval $(call assert_boolean,CTX_INCLUDE_PAUTH_REGS)) $(eval $(call assert_boolean,CTX_INCLUDE_MTE_REGS)) +$(eval $(call assert_boolean,CTX_INCLUDE_EL2_REGS)) $(eval $(call assert_boolean,DEBUG)) $(eval $(call assert_boolean,DYN_DISABLE_AUTH)) $(eval $(call assert_boolean,EL3_EXCEPTION_HANDLING)) @@ -832,6 +838,7 @@ $(eval $(call add_define,CTX_INCLUDE_FPREGS)) $(eval $(call add_define,CTX_INCLUDE_PAUTH_REGS)) $(eval $(call add_define,EL3_EXCEPTION_HANDLING)) $(eval $(call add_define,CTX_INCLUDE_MTE_REGS)) +$(eval $(call add_define,CTX_INCLUDE_EL2_REGS)) $(eval $(call add_define,ENABLE_AMU)) $(eval $(call add_define,ENABLE_ASSERTIONS)) $(eval $(call add_define,ENABLE_BTI)) diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index 1faddbedc..d5939971e 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -96,6 +96,33 @@ #define ICC_EOIR1_EL1 S3_0_c12_c12_1 #define ICC_SGI0R_EL1 S3_0_c12_c11_7 +/******************************************************************************* + * Definitions for EL2 system registers for save/restore routine + ******************************************************************************/ + +#define CNTPOFF_EL2 S3_4_C14_C0_6 +#define HAFGRTR_EL2 S3_4_C3_C1_6 +#define HDFGRTR_EL2 S3_4_C3_C1_4 +#define HDFGWTR_EL2 S3_4_C3_C1_5 +#define HFGITR_EL2 S3_4_C1_C1_6 +#define HFGRTR_EL2 S3_4_C1_C1_4 +#define HFGWTR_EL2 S3_4_C1_C1_5 +#define ICH_EISR_EL2 S3_4_C12_C11_3 +#define ICH_ELRSR_EL2 S3_4_C12_C11_5 +#define ICH_HCR_EL2 S3_4_C12_C11_0 +#define ICH_MISR_EL2 S3_4_C12_C11_2 +#define ICH_VMCR_EL2 S3_4_C12_C11_7 +#define ICH_VTR_EL2 S3_4_C12_C11_1 +#define MPAMVPM0_EL2 S3_4_C10_C5_0 +#define MPAMVPM1_EL2 S3_4_C10_C5_1 +#define MPAMVPM2_EL2 S3_4_C10_C5_2 +#define MPAMVPM3_EL2 S3_4_C10_C5_3 +#define MPAMVPM4_EL2 S3_4_C10_C5_4 +#define MPAMVPM5_EL2 S3_4_C10_C5_5 +#define MPAMVPM6_EL2 S3_4_C10_C5_6 +#define MPAMVPM7_EL2 S3_4_C10_C5_7 +#define MPAMVPMV_EL2 S3_4_C10_C4_1 + /******************************************************************************* * Generic timer memory mapped registers & offsets ******************************************************************************/ diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h index 4158c023e..6559b60a3 100644 --- a/include/lib/el3_runtime/aarch64/context.h +++ b/include/lib/el3_runtime/aarch64/context.h @@ -135,10 +135,88 @@ #define CTX_MTE_REGS_END CTX_TIMER_SYSREGS_END #endif /* CTX_INCLUDE_MTE_REGS */ +/* + * S-EL2 register set + */ + +#if CTX_INCLUDE_EL2_REGS +/* For later discussion + * ICH_AP0R_EL2 + * ICH_AP1R_EL2 + * AMEVCNTVOFF0_EL2 + * AMEVCNTVOFF1_EL2 + * ICH_LR_EL2 + */ +#define CTX_ACTLR_EL2 (CTX_MTE_REGS_END + U(0x0)) +#define CTX_AFSR0_EL2 (CTX_MTE_REGS_END + U(0x8)) +#define CTX_AFSR1_EL2 (CTX_MTE_REGS_END + U(0x10)) +#define CTX_AMAIR_EL2 (CTX_MTE_REGS_END + U(0x18)) +#define CTX_CNTHCTL_EL2 (CTX_MTE_REGS_END + U(0x20)) +#define CTX_CNTHP_CTL_EL2 (CTX_MTE_REGS_END + U(0x28)) +#define CTX_CNTHP_CVAL_EL2 (CTX_MTE_REGS_END + U(0x30)) +#define CTX_CNTHP_TVAL_EL2 (CTX_MTE_REGS_END + U(0x38)) +#define CTX_CNTPOFF_EL2 (CTX_MTE_REGS_END + U(0x40)) +#define CTX_CNTVOFF_EL2 (CTX_MTE_REGS_END + U(0x48)) +#define CTX_CPTR_EL2 (CTX_MTE_REGS_END + U(0x50)) +#define CTX_DBGVCR32_EL2 (CTX_MTE_REGS_END + U(0x58)) +#define CTX_ELR_EL2 (CTX_MTE_REGS_END + U(0x60)) +#define CTX_ESR_EL2 (CTX_MTE_REGS_END + U(0x68)) +#define CTX_FAR_EL2 (CTX_MTE_REGS_END + U(0x70)) +#define CTX_FPEXC32_EL2 (CTX_MTE_REGS_END + U(0x78)) +#define CTX_HACR_EL2 (CTX_MTE_REGS_END + U(0x80)) +#define CTX_HAFGRTR_EL2 (CTX_MTE_REGS_END + U(0x88)) +#define CTX_HCR_EL2 (CTX_MTE_REGS_END + U(0x90)) +#define CTX_HDFGRTR_EL2 (CTX_MTE_REGS_END + U(0x98)) +#define CTX_HDFGWTR_EL2 (CTX_MTE_REGS_END + U(0xA0)) +#define CTX_HFGITR_EL2 (CTX_MTE_REGS_END + U(0xA8)) +#define CTX_HFGRTR_EL2 (CTX_MTE_REGS_END + U(0xB0)) +#define CTX_HFGWTR_EL2 (CTX_MTE_REGS_END + U(0xB8)) +#define CTX_HPFAR_EL2 (CTX_MTE_REGS_END + U(0xC0)) +#define CTX_HSTR_EL2 (CTX_MTE_REGS_END + U(0xC8)) +#define CTX_ICC_SRE_EL2 (CTX_MTE_REGS_END + U(0xD0)) +#define CTX_ICH_EISR_EL2 (CTX_MTE_REGS_END + U(0xD8)) +#define CTX_ICH_ELRSR_EL2 (CTX_MTE_REGS_END + U(0xE0)) +#define CTX_ICH_HCR_EL2 (CTX_MTE_REGS_END + U(0xE8)) +#define CTX_ICH_MISR_EL2 (CTX_MTE_REGS_END + U(0xF0)) +#define CTX_ICH_VMCR_EL2 (CTX_MTE_REGS_END + U(0xF8)) +#define CTX_ICH_VTR_EL2 (CTX_MTE_REGS_END + U(0x100)) +#define CTX_MAIR_EL2 (CTX_MTE_REGS_END + U(0x108)) +#define CTX_MDCR_EL2 (CTX_MTE_REGS_END + U(0x110)) +#define CTX_MPAM2_EL2 (CTX_MTE_REGS_END + U(0x118)) +#define CTX_MPAMHCR_EL2 (CTX_MTE_REGS_END + U(0x120)) +#define CTX_MPAMVPM0_EL2 (CTX_MTE_REGS_END + U(0x128)) +#define CTX_MPAMVPM1_EL2 (CTX_MTE_REGS_END + U(0x130)) +#define CTX_MPAMVPM2_EL2 (CTX_MTE_REGS_END + U(0x138)) +#define CTX_MPAMVPM3_EL2 (CTX_MTE_REGS_END + U(0x140)) +#define CTX_MPAMVPM4_EL2 (CTX_MTE_REGS_END + U(0x148)) +#define CTX_MPAMVPM5_EL2 (CTX_MTE_REGS_END + U(0x150)) +#define CTX_MPAMVPM6_EL2 (CTX_MTE_REGS_END + U(0x158)) +#define CTX_MPAMVPM7_EL2 (CTX_MTE_REGS_END + U(0x160)) +#define CTX_MPAMVPMV_EL2 (CTX_MTE_REGS_END + U(0x168)) +#define CTX_RMR_EL2 (CTX_MTE_REGS_END + U(0x170)) +#define CTX_SCTLR_EL2 (CTX_MTE_REGS_END + U(0x178)) +#define CTX_SPSR_EL2 (CTX_MTE_REGS_END + U(0x180)) +#define CTX_SP_EL2 (CTX_MTE_REGS_END + U(0x188)) +#define CTX_TCR_EL2 (CTX_MTE_REGS_END + U(0x190)) +#define CTX_TPIDR_EL2 (CTX_MTE_REGS_END + U(0x198)) +#define CTX_TTBR0_EL2 (CTX_MTE_REGS_END + U(0x1A0)) +#define CTX_VBAR_EL2 (CTX_MTE_REGS_END + U(0x1A8)) +#define CTX_VMPIDR_EL2 (CTX_MTE_REGS_END + U(0x1B0)) +#define CTX_VPIDR_EL2 (CTX_MTE_REGS_END + U(0x1B8)) +#define CTX_VTCR_EL2 (CTX_MTE_REGS_END + U(0x1C0)) +#define CTX_VTTBR_EL2 (CTX_MTE_REGS_END + U(0x1C8)) +#define CTX_ZCR_EL2 (CTX_MTE_REGS_END + U(0x1B0)) + +/* Align to the next 16 byte boundary */ +#define CTX_EL2_REGS_END (CTX_MTE_REGS_END + U(0x1C0)) +#else +#define CTX_EL2_REGS_END CTX_MTE_REGS_END +#endif /* CTX_INCLUDE_EL2_REGS */ + /* * End of system registers. */ -#define CTX_SYSREGS_END CTX_MTE_REGS_END +#define CTX_SYSREGS_END CTX_EL2_REGS_END /******************************************************************************* * Constants that allow assembler code to access members of and the 'fp_regs' @@ -255,11 +333,10 @@ DEFINE_REG_STRUCT(gp_regs, CTX_GPREG_ALL); /* - * AArch64 EL1 system register context structure for preserving the - * architectural state during switches from one security state to - * another in EL1. + * AArch64 EL1/EL2 system register context structure for preserving the + * architectural state during world switches. */ -DEFINE_REG_STRUCT(el1_sys_regs, CTX_SYSREG_ALL); +DEFINE_REG_STRUCT(sys_regs, CTX_SYSREG_ALL); /* * AArch64 floating point register context structure for preserving @@ -304,7 +381,7 @@ DEFINE_REG_STRUCT(pauth, CTX_PAUTH_REGS_ALL); typedef struct cpu_context { gp_regs_t gpregs_ctx; el3_state_t el3state_ctx; - el1_sys_regs_t sysregs_ctx; + sys_regs_t sysregs_ctx; #if CTX_INCLUDE_FPREGS fp_regs_t fpregs_ctx; #endif @@ -387,8 +464,14 @@ CASSERT(CTX_PAUTH_REGS_OFFSET == __builtin_offsetof(cpu_context_t, pauth_ctx), \ /******************************************************************************* * Function prototypes ******************************************************************************/ -void el1_sysregs_context_save(el1_sys_regs_t *regs); -void el1_sysregs_context_restore(el1_sys_regs_t *regs); +void el1_sysregs_context_save(sys_regs_t *regs); +void el1_sysregs_context_restore(sys_regs_t *regs); + +#if CTX_INCLUDE_EL2_REGS +void el2_sysregs_context_save(sys_regs_t *regs); +void el2_sysregs_context_restore(sys_regs_t *regs); +#endif + #if CTX_INCLUDE_FPREGS void fpregs_context_save(fp_regs_t *regs); void fpregs_context_restore(fp_regs_t *regs); diff --git a/include/lib/el3_runtime/context_mgmt.h b/include/lib/el3_runtime/context_mgmt.h index 17955e3a8..b36cd3d70 100644 --- a/include/lib/el3_runtime/context_mgmt.h +++ b/include/lib/el3_runtime/context_mgmt.h @@ -36,6 +36,11 @@ void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep); void cm_prepare_el3_exit(uint32_t security_state); #ifdef __aarch64__ +#if CTX_INCLUDE_EL2_REGS +void cm_el2_sysregs_context_save(uint32_t security_state); +void cm_el2_sysregs_context_restore(uint32_t security_state); +#endif + void cm_el1_sysregs_context_save(uint32_t security_state); void cm_el1_sysregs_context_restore(uint32_t security_state); void cm_set_elr_el3(uint32_t security_state, uintptr_t entrypoint); diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S index 9bd25bac9..bcc7eef9e 100644 --- a/lib/el3_runtime/aarch64/context.S +++ b/lib/el3_runtime/aarch64/context.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,6 +9,11 @@ #include #include +#if CTX_INCLUDE_EL2_REGS + .global el2_sysregs_context_save + .global el2_sysregs_context_restore +#endif + .global el1_sysregs_context_save .global el1_sysregs_context_restore #if CTX_INCLUDE_FPREGS @@ -19,6 +24,390 @@ .global restore_gp_pmcr_pauth_regs .global el3_exit +#if CTX_INCLUDE_EL2_REGS + +/* ----------------------------------------------------- + * The following function strictly follows the AArch64 + * PCS to use x9-x17 (temporary caller-saved registers) + * to save EL1 system register context. It assumes that + * 'x0' is pointing to a 'el1_sys_regs' structure where + * the register context will be saved. + * ----------------------------------------------------- + */ +func el2_sysregs_context_save + + mrs x9, actlr_el2 + str x9, [x0, #CTX_ACTLR_EL2] + + mrs x9, afsr0_el2 + str x9, [x0, #CTX_AFSR0_EL2] + + mrs x9, afsr1_el2 + str x9, [x0, #CTX_AFSR1_EL2] + + mrs x9, amair_el2 + str x9, [x0, #CTX_AMAIR_EL2] + + mrs x9, cnthctl_el2 + str x9, [x0, #CTX_CNTHCTL_EL2] + + mrs x9, cnthp_ctl_el2 + str x9, [x0, #CTX_CNTHP_CTL_EL2] + + mrs x9, cnthp_cval_el2 + str x9, [x0, #CTX_CNTHP_CVAL_EL2] + + mrs x9, cnthp_tval_el2 + str x9, [x0, #CTX_CNTHP_TVAL_EL2] + + mrs x9, CNTPOFF_EL2 + str x9, [x0, #CTX_CNTPOFF_EL2] + + mrs x9, cntvoff_el2 + str x9, [x0, #CTX_CNTVOFF_EL2] + + mrs x9, cptr_el2 + str x9, [x0, #CTX_CPTR_EL2] + + mrs x9, dbgvcr32_el2 + str x9, [x0, #CTX_DBGVCR32_EL2] + + mrs x9, elr_el2 + str x9, [x0, #CTX_ELR_EL2] + + mrs x9, esr_el2 + str x9, [x0, #CTX_ESR_EL2] + + mrs x9, far_el2 + str x9, [x0, #CTX_FAR_EL2] + + mrs x9, fpexc32_el2 + str x9, [x0, #CTX_FPEXC32_EL2] + + mrs x9, hacr_el2 + str x9, [x0, #CTX_HACR_EL2] + + mrs x9, HAFGRTR_EL2 + str x9, [x0, #CTX_HAFGRTR_EL2] + + mrs x9, hcr_el2 + str x9, [x0, #CTX_HCR_EL2] + + mrs x9, HDFGRTR_EL2 + str x9, [x0, #CTX_HDFGRTR_EL2] + + mrs x9, HDFGWTR_EL2 + str x9, [x0, #CTX_HDFGWTR_EL2] + + mrs x9, HFGITR_EL2 + str x9, [x0, #CTX_HFGITR_EL2] + + mrs x9, HFGRTR_EL2 + str x9, [x0, #CTX_HFGRTR_EL2] + + mrs x9, HFGWTR_EL2 + str x9, [x0, #CTX_HFGWTR_EL2] + + mrs x9, hpfar_el2 + str x9, [x0, #CTX_HPFAR_EL2] + + mrs x9, hstr_el2 + str x9, [x0, #CTX_HSTR_EL2] + + mrs x9, ICC_SRE_EL2 + str x9, [x0, #CTX_ICC_SRE_EL2] + + mrs x9, ICH_EISR_EL2 + str x9, [x0, #CTX_ICH_EISR_EL2] + + mrs x9, ICH_ELRSR_EL2 + str x9, [x0, #CTX_ICH_ELRSR_EL2] + + mrs x9, ICH_HCR_EL2 + str x9, [x0, #CTX_ICH_HCR_EL2] + + mrs x9, ICH_MISR_EL2 + str x9, [x0, #CTX_ICH_MISR_EL2] + + mrs x9, ICH_VMCR_EL2 + str x9, [x0, #CTX_ICH_VMCR_EL2] + + mrs x9, ICH_VTR_EL2 + str x9, [x0, #CTX_ICH_VTR_EL2] + + mrs x9, mair_el2 + str x9, [x0, #CTX_MAIR_EL2] + + mrs x9, mdcr_el2 + str x9, [x0, #CTX_MDCR_EL2] + + mrs x9, MPAM2_EL2 + str x9, [x0, #CTX_MPAM2_EL2] + + mrs x9, MPAMHCR_EL2 + str x9, [x0, #CTX_MPAMHCR_EL2] + + mrs x9, MPAMVPM0_EL2 + str x9, [x0, #CTX_MPAMVPM0_EL2] + + mrs x9, MPAMVPM1_EL2 + str x9, [x0, #CTX_MPAMVPM1_EL2] + + mrs x9, MPAMVPM2_EL2 + str x9, [x0, #CTX_MPAMVPM2_EL2] + + mrs x9, MPAMVPM3_EL2 + str x9, [x0, #CTX_MPAMVPM3_EL2] + + mrs x9, MPAMVPM4_EL2 + str x9, [x0, #CTX_MPAMVPM4_EL2] + + mrs x9, MPAMVPM5_EL2 + str x9, [x0, #CTX_MPAMVPM5_EL2] + + mrs x9, MPAMVPM6_EL2 + str x9, [x0, #CTX_MPAMVPM6_EL2] + + mrs x9, MPAMVPM7_EL2 + str x9, [x0, #CTX_MPAMVPM7_EL2] + + mrs x9, MPAMVPMV_EL2 + str x9, [x0, #CTX_MPAMVPMV_EL2] + + mrs x9, rmr_el2 + str x9, [x0, #CTX_RMR_EL2] + + mrs x9, sctlr_el2 + str x9, [x0, #CTX_SCTLR_EL2] + + mrs x9, spsr_el2 + str x9, [x0, #CTX_SPSR_EL2] + + mrs x9, sp_el2 + str x9, [x0, #CTX_SP_EL2] + + mrs x9, tcr_el2 + str x9, [x0, #CTX_TCR_EL2] + + mrs x9, tpidr_el2 + str x9, [x0, #CTX_TPIDR_EL2] + + mrs x9, ttbr0_el2 + str x9, [x0, #CTX_TTBR0_EL2] + + mrs x9, vbar_el2 + str x9, [x0, #CTX_VBAR_EL2] + + mrs x9, vmpidr_el2 + str x9, [x0, #CTX_VMPIDR_EL2] + + mrs x9, vpidr_el2 + str x9, [x0, #CTX_VPIDR_EL2] + + mrs x9, vtcr_el2 + str x9, [x0, #CTX_VTCR_EL2] + + mrs x9, vttbr_el2 + str x9, [x0, #CTX_VTTBR_EL2] + + mrs x9, ZCR_EL2 + str x9, [x0, #CTX_ZCR_EL2] + + ret +endfunc el2_sysregs_context_save + +/* ----------------------------------------------------- + * The following function strictly follows the AArch64 + * PCS to use x9-x17 (temporary caller-saved registers) + * to restore EL1 system register context. It assumes + * that 'x0' is pointing to a 'el1_sys_regs' structure + * from where the register context will be restored + * ----------------------------------------------------- + */ +func el2_sysregs_context_restore + + ldr x9, [x0, #CTX_ACTLR_EL2] + msr actlr_el2, x9 + + ldr x9, [x0, #CTX_AFSR0_EL2] + msr afsr0_el2, x9 + + ldr x9, [x0, #CTX_AFSR1_EL2] + msr afsr1_el2, x9 + + ldr x9, [x0, #CTX_AMAIR_EL2] + msr amair_el2, x9 + + ldr x9, [x0, #CTX_CNTHCTL_EL2] + msr cnthctl_el2, x9 + + ldr x9, [x0, #CTX_CNTHP_CTL_EL2] + msr cnthp_ctl_el2, x9 + + ldr x9, [x0, #CTX_CNTHP_CVAL_EL2] + msr cnthp_cval_el2, x9 + + ldr x9, [x0, #CTX_CNTHP_TVAL_EL2] + msr cnthp_tval_el2, x9 + + ldr x9, [x0, #CTX_CNTPOFF_EL2] + msr CNTPOFF_EL2, x9 + + ldr x9, [x0, #CTX_CNTVOFF_EL2] + msr cntvoff_el2, x9 + + ldr x9, [x0, #CTX_CPTR_EL2] + msr cptr_el2, x9 + + ldr x9, [x0, #CTX_DBGVCR32_EL2] + msr dbgvcr32_el2, x9 + + ldr x9, [x0, #CTX_ELR_EL2] + msr elr_el2, x9 + + ldr x9, [x0, #CTX_ESR_EL2] + msr esr_el2, x9 + + ldr x9, [x0, #CTX_FAR_EL2] + msr far_el2, x9 + + ldr x9, [x0, #CTX_FPEXC32_EL2] + msr fpexc32_el2, x9 + + ldr x9, [x0, #CTX_HACR_EL2] + msr hacr_el2, x9 + + ldr x9, [x0, #CTX_HAFGRTR_EL2] + msr HAFGRTR_EL2, x9 + + ldr x9, [x0, #CTX_HCR_EL2] + msr hcr_el2, x9 + + ldr x9, [x0, #CTX_HDFGRTR_EL2] + msr HDFGRTR_EL2, x9 + + ldr x9, [x0, #CTX_HDFGWTR_EL2] + msr HDFGWTR_EL2, x9 + + ldr x9, [x0, #CTX_HFGITR_EL2] + msr HFGITR_EL2, x9 + + ldr x9, [x0, #CTX_HFGRTR_EL2] + msr HFGRTR_EL2, x9 + + ldr x9, [x0, #CTX_HFGWTR_EL2] + msr HFGWTR_EL2, x9 + + ldr x9, [x0, #CTX_HPFAR_EL2] + msr hpfar_el2, x9 + + ldr x9, [x0, #CTX_HSTR_EL2] + msr hstr_el2, x9 + + ldr x9, [x0, #CTX_ICC_SRE_EL2] + msr ICC_SRE_EL2, x9 + + ldr x9, [x0, #CTX_ICH_EISR_EL2] + msr ICH_EISR_EL2, x9 + + ldr x9, [x0, #CTX_ICH_ELRSR_EL2] + msr ICH_ELRSR_EL2, x9 + + ldr x9, [x0, #CTX_ICH_HCR_EL2] + msr ICH_HCR_EL2, x9 + + ldr x9, [x0, #CTX_ICH_MISR_EL2] + msr ICH_MISR_EL2, x9 + + ldr x9, [x0, #CTX_ICH_VMCR_EL2] + msr ICH_VMCR_EL2, x9 + + ldr x9, [x0, #CTX_ICH_VTR_EL2] + msr ICH_VTR_EL2, x9 + + ldr x9, [x0, #CTX_MAIR_EL2] + msr mair_el2, x9 + + ldr x9, [x0, #CTX_MDCR_EL2] + msr mdcr_el2, x9 + + ldr x9, [x0, #CTX_MPAM2_EL2] + msr MPAM2_EL2, x9 + + ldr x9, [x0, #CTX_MPAMHCR_EL2] + msr MPAMHCR_EL2, x9 + + ldr x9, [x0, #CTX_MPAMVPM0_EL2] + msr MPAMVPM0_EL2, x9 + + ldr x9, [x0, #CTX_MPAMVPM1_EL2] + msr MPAMVPM1_EL2, x9 + + ldr x9, [x0, #CTX_MPAMVPM2_EL2] + msr MPAMVPM2_EL2, x9 + + ldr x9, [x0, #CTX_MPAMVPM3_EL2] + msr MPAMVPM3_EL2, x9 + + ldr x9, [x0, #CTX_MPAMVPM4_EL2] + msr MPAMVPM4_EL2, x9 + + ldr x9, [x0, #CTX_MPAMVPM5_EL2] + msr MPAMVPM5_EL2, x9 + + ldr x9, [x0, #CTX_MPAMVPM6_EL2] + msr MPAMVPM6_EL2, x9 + + ldr x9, [x0, #CTX_MPAMVPM7_EL2] + msr MPAMVPM7_EL2, x9 + + ldr x9, [x0, #CTX_MPAMVPMV_EL2] + msr MPAMVPMV_EL2, x9 + + ldr x9, [x0, #CTX_RMR_EL2] + msr rmr_el2, x9 + + ldr x9, [x0, #CTX_SCTLR_EL2] + msr sctlr_el2, x9 + + ldr x9, [x0, #CTX_SPSR_EL2] + msr spsr_el2, x9 + + ldr x9, [x0, #CTX_SP_EL2] + msr sp_el2, x9 + + ldr x9, [x0, #CTX_TCR_EL2] + msr tcr_el2, x9 + + ldr x9, [x0, #CTX_TPIDR_EL2] + msr tpidr_el2, x9 + + ldr x9, [x0, #CTX_TTBR0_EL2] + msr ttbr0_el2, x9 + + ldr x9, [x0, #CTX_VBAR_EL2] + msr vbar_el2, x9 + + ldr x9, [x0, #CTX_VMPIDR_EL2] + msr vmpidr_el2, x9 + + ldr x9, [x0, #CTX_VPIDR_EL2] + msr vpidr_el2, x9 + + ldr x9, [x0, #CTX_VTCR_EL2] + msr vtcr_el2, x9 + + ldr x9, [x0, #CTX_VTTBR_EL2] + msr vttbr_el2, x9 + + ldr x9, [x0, #CTX_ZCR_EL2] + msr ZCR_EL2, x9 + + ret +endfunc el2_sysregs_context_restore + +#endif /* CTX_INCLUDE_EL2_REGS */ + /* ------------------------------------------------------------------ * The following function strictly follows the AArch64 PCS to use * x9-x17 (temporary caller-saved registers) to save EL1 system diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c index 546e39e16..f59bcfcd9 100644 --- a/lib/el3_runtime/aarch64/context_mgmt.c +++ b/lib/el3_runtime/aarch64/context_mgmt.c @@ -530,6 +530,52 @@ void cm_prepare_el3_exit(uint32_t security_state) cm_set_next_eret_context(security_state); } +#if CTX_INCLUDE_EL2_REGS +/******************************************************************************* + * Save EL2 sysreg context + ******************************************************************************/ +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 + * S-EL2 context if S-EL2 is enabled. + */ + if ((security_state == NON_SECURE) || + ((scr_el3 & SCR_EEL2_BIT) != 0U)) { + cpu_context_t *ctx; + + ctx = cm_get_context(security_state); + assert(ctx != NULL); + + el2_sysregs_context_save(get_sysregs_ctx(ctx)); + } +} + +/******************************************************************************* + * Restore EL2 sysreg context + ******************************************************************************/ +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 + * S-EL2 context if S-EL2 is enabled. + */ + if ((security_state == NON_SECURE) || + ((scr_el3 & SCR_EEL2_BIT) != 0U)) { + cpu_context_t *ctx; + + ctx = cm_get_context(security_state); + assert(ctx != NULL); + + el2_sysregs_context_restore(get_sysregs_ctx(ctx)); + } +} +#endif /* CTX_INCLUDE_EL2_REGS */ + /******************************************************************************* * The next four functions are used by runtime services to save and restore * EL1 context on the 'cpu_context' structure for the specified security diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index 60958a1d1..8e1f273a3 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -262,3 +262,8 @@ USE_SPINLOCK_CAS := 0 # Enable Link Time Optimization ENABLE_LTO := 0 + +# Build flag to include EL2 registers in cpu context save and restore during +# S-EL2 firmware entry/exit. This flag is to be used with SPD=spmd option. +# Default is 0. +CTX_INCLUDE_EL2_REGS := 0 diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c index 677f63968..110719020 100644 --- a/services/std_svc/spmd/spmd_main.c +++ b/services/std_svc/spmd/spmd_main.c @@ -49,6 +49,7 @@ uint64_t spmd_spm_core_sync_entry(spmd_spm_core_context_t *spmc_ctx) /* Restore the context assigned above */ cm_el1_sysregs_context_restore(SECURE); + cm_el2_sysregs_context_restore(SECURE); cm_set_next_eret_context(SECURE); /* Invalidate TLBs at EL1. */ @@ -60,6 +61,7 @@ uint64_t spmd_spm_core_sync_entry(spmd_spm_core_context_t *spmc_ctx) /* Save secure state */ cm_el1_sysregs_context_save(SECURE); + cm_el2_sysregs_context_save(SECURE); return rc; } @@ -321,9 +323,11 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, /* Save incoming security state */ cm_el1_sysregs_context_save(in_sstate); + cm_el2_sysregs_context_save(in_sstate); /* Restore outgoing security state */ cm_el1_sysregs_context_restore(out_sstate); + cm_el2_sysregs_context_restore(out_sstate); cm_set_next_eret_context(out_sstate); SMC_RET8(cm_get_context(out_sstate), smc_fid, x1, x2, x3, x4, @@ -366,9 +370,11 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, if (in_sstate == NON_SECURE) { /* Save incoming security state */ cm_el1_sysregs_context_save(in_sstate); + cm_el2_sysregs_context_save(in_sstate); /* Restore outgoing security state */ cm_el1_sysregs_context_restore(out_sstate); + cm_el2_sysregs_context_restore(out_sstate); cm_set_next_eret_context(out_sstate); SMC_RET8(cm_get_context(out_sstate), smc_fid, @@ -432,9 +438,11 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, /* Save incoming security state */ cm_el1_sysregs_context_save(in_sstate); + cm_el2_sysregs_context_save(in_sstate); /* Restore outgoing security state */ cm_el1_sysregs_context_restore(out_sstate); + cm_el2_sysregs_context_restore(out_sstate); cm_set_next_eret_context(out_sstate); SMC_RET8(cm_get_context(out_sstate), smc_fid, x1, x2, x3, x4, @@ -466,9 +474,11 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, /* Save incoming security state */ cm_el1_sysregs_context_save(in_sstate); + cm_el2_sysregs_context_save(in_sstate); /* Restore outgoing security state */ cm_el1_sysregs_context_restore(out_sstate); + cm_el2_sysregs_context_restore(out_sstate); cm_set_next_eret_context(out_sstate); SMC_RET8(cm_get_context(out_sstate), smc_fid, x1, x2, x3, x4, -- cgit v1.2.3 From 51d4e227a0f236d25456b18f037acc2ad9aebcbd Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Mon, 2 Mar 2020 13:09:22 +0100 Subject: doc: Fix variables names in TBBR CoT documentation In commit 516beb585c23056820a854b12c77a6f62cbc5c8b ("TBB: apply TBBR naming convention to certificates and extensions"), some of the variables used in the TBBR chain of trust got renamed but the documentation did not get properly updated everywhere to reflect these changes. Change-Id: Ie8e2146882c2d3538c5b8c968d1bdaf5ea2a6e53 Signed-off-by: Sandrine Bailleux --- docs/design/auth-framework.rst | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/design/auth-framework.rst b/docs/design/auth-framework.rst index 93f691b7b..ae7739140 100644 --- a/docs/design/auth-framework.rst +++ b/docs/design/auth-framework.rst @@ -621,7 +621,7 @@ The TBBR CoT The CoT can be found in ``drivers/auth/tbbr/tbbr_cot.c``. This CoT consists of an array of pointers to image descriptors and it is registered in the framework -using the macro ``REGISTER_COT(cot_desc)``, where 'cot_desc' must be the name +using the macro ``REGISTER_COT(cot_desc)``, where ``cot_desc`` must be the name of the array (passing a pointer or any other type of indirection will cause the registration process to fail). @@ -870,32 +870,32 @@ Once the signature has been checked and the certificate authenticated, the Trusted World public key needs to be extracted from the certificate. A new entry is created in the ``authenticated_data`` array for that purpose. In that entry, the corresponding parameter descriptor must be specified along with the buffer -address to store the parameter value. In this case, the ``tz_world_pk`` descriptor -is used to extract the public key from an x509v3 extension with OID +address to store the parameter value. In this case, the ``trusted_world_pk`` +descriptor is used to extract the public key from an x509v3 extension with OID ``TRUSTED_WORLD_PK_OID``. The BL31 key certificate will use this descriptor as parameter in the signature authentication method. The key is stored in the -``plat_tz_world_pk_buf`` buffer. +``trusted_world_pk_buf`` buffer. The **BL31 Key certificate** is authenticated by checking its digital signature using the Trusted World public key obtained previously from the Trusted Key certificate. In the image descriptor, we specify a single authentication method -by signature whose public key is the ``tz_world_pk``. Once this certificate has -been authenticated, we have to extract the BL31 public key, stored in the -extension specified by ``bl31_content_pk``. This key will be copied to the -``plat_content_pk`` buffer. +by signature whose public key is the ``trusted_world_pk``. Once this certificate +has been authenticated, we have to extract the BL31 public key, stored in the +extension specified by ``soc_fw_content_pk``. This key will be copied to the +``content_pk_buf`` buffer. The **BL31 certificate** is authenticated by checking its digital signature using the BL31 public key obtained previously from the BL31 Key certificate. -We specify the authentication method using ``bl31_content_pk`` as public key. +We specify the authentication method using ``soc_fw_content_pk`` as public key. After authentication, we need to extract the BL31 hash, stored in the extension -specified by ``bl31_hash``. This hash will be copied to the ``plat_bl31_hash_buf`` -buffer. +specified by ``soc_fw_hash``. This hash will be copied to the +``soc_fw_hash_buf`` buffer. The **BL31 image** is authenticated by calculating its hash and matching it with the hash obtained from the BL31 certificate. The image descriptor contains a single authentication method by hash. The parameters to the hash method are -the reference hash, ``bl31_hash``, and the data to be hashed. In this case, it is -the whole image, so we specify ``raw_data``. +the reference hash, ``soc_fw_hash``, and the data to be hashed. In this case, +it is the whole image, so we specify ``raw_data``. The image parser library ~~~~~~~~~~~~~~~~~~~~~~~~ @@ -965,6 +965,6 @@ The mbedTLS library algorithm support is configured by both the -------------- -*Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved.* +*Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.* .. _TBBR-Client specification: https://developer.arm.com/docs/den0006/latest/trusted-board-boot-requirements-client-tbbr-client-armv8-a -- cgit v1.2.3 From cfde1870ca713f2a89a80df80badd5805304103e Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Mon, 2 Mar 2020 22:15:08 +0800 Subject: hikey960: Enable system power off callback On Hikey960 if outputs GPIO176 low level, it can tell PMIC to power off the whole board. To avoid resetting the board and stay off, it also requires the SW2201's three switches 1/2/3 need to be all set to 0. Since current code doesn't contain complete GPIO modules and misses to support GPIO176. This patch adds all known GPIO modules and initialize GPIO in BL31, and adds system power off callback to use GPIO176 for PMIC power off operation. Change-Id: Ia88859b8b7c87c061420ef75f0de3e2768667bb0 Signed-off-by: Leo Yan --- plat/hisilicon/hikey960/hikey960_bl31_setup.c | 1 + plat/hisilicon/hikey960/hikey960_bl_common.c | 7 +++++++ plat/hisilicon/hikey960/hikey960_pm.c | 10 +++++++++- plat/hisilicon/hikey960/include/hi3660.h | 7 +++++++ plat/hisilicon/hikey960/platform.mk | 5 ++++- 5 files changed, 28 insertions(+), 2 deletions(-) diff --git a/plat/hisilicon/hikey960/hikey960_bl31_setup.c b/plat/hisilicon/hikey960/hikey960_bl31_setup.c index d3b4e4f68..f5f8ffed0 100644 --- a/plat/hisilicon/hikey960/hikey960_bl31_setup.c +++ b/plat/hisilicon/hikey960/hikey960_bl31_setup.c @@ -166,6 +166,7 @@ void bl31_platform_setup(void) hikey960_edma_init(); hikey960_iomcu_dma_init(); + hikey960_gpio_init(); hisi_ipc_init(); } diff --git a/plat/hisilicon/hikey960/hikey960_bl_common.c b/plat/hisilicon/hikey960/hikey960_bl_common.c index 89adccb2b..3c4a164ff 100644 --- a/plat/hisilicon/hikey960/hikey960_bl_common.c +++ b/plat/hisilicon/hikey960/hikey960_bl_common.c @@ -466,6 +466,13 @@ void hikey960_gpio_init(void) pl061_gpio_register(GPIO19_BASE, 19); pl061_gpio_register(GPIO20_BASE, 20); pl061_gpio_register(GPIO21_BASE, 21); + pl061_gpio_register(GPIO22_BASE, 22); + pl061_gpio_register(GPIO23_BASE, 23); + pl061_gpio_register(GPIO24_BASE, 24); + pl061_gpio_register(GPIO25_BASE, 25); + pl061_gpio_register(GPIO26_BASE, 26); + pl061_gpio_register(GPIO27_BASE, 27); + pl061_gpio_register(GPIO28_BASE, 28); /* PCIE_PERST_N output low */ gpio_set_direction(89, GPIO_DIR_OUT); diff --git a/plat/hisilicon/hikey960/hikey960_pm.c b/plat/hisilicon/hikey960/hikey960_pm.c index 9f96fc398..f836508d5 100644 --- a/plat/hisilicon/hikey960/hikey960_pm.c +++ b/plat/hisilicon/hikey960/hikey960_pm.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -116,6 +117,13 @@ void hikey960_pwr_domain_off(const psci_power_state_t *target_state) } } +static void __dead2 hikey960_system_off(void) +{ + gpio_set_direction(176, GPIO_DIR_OUT); + gpio_set_value(176, GPIO_LEVEL_LOW); + panic(); +} + static void __dead2 hikey960_system_reset(void) { dsb(); @@ -293,7 +301,7 @@ static const plat_psci_ops_t hikey960_psci_ops = { .pwr_domain_off = hikey960_pwr_domain_off, .pwr_domain_suspend = hikey960_pwr_domain_suspend, .pwr_domain_suspend_finish = hikey960_pwr_domain_suspend_finish, - .system_off = NULL, + .system_off = hikey960_system_off, .system_reset = hikey960_system_reset, .validate_power_state = hikey960_validate_power_state, .validate_ns_entrypoint = hikey960_validate_ns_entrypoint, diff --git a/plat/hisilicon/hikey960/include/hi3660.h b/plat/hisilicon/hikey960/include/hi3660.h index 7cc1ee0b8..17b495f21 100644 --- a/plat/hisilicon/hikey960/include/hi3660.h +++ b/plat/hisilicon/hikey960/include/hi3660.h @@ -260,6 +260,13 @@ #define GPIO17_BASE UL(0xE8A1C000) #define GPIO20_BASE UL(0xE8A1F000) #define GPIO21_BASE UL(0xE8A20000) +#define GPIO22_BASE UL(0xFFF0B000) +#define GPIO23_BASE UL(0xFFF0C000) +#define GPIO24_BASE UL(0xFFF0D000) +#define GPIO25_BASE UL(0xFFF0E000) +#define GPIO26_BASE UL(0xFFF0F000) +#define GPIO27_BASE UL(0xFFF10000) +#define GPIO28_BASE UL(0xFFF1D000) #define TZC_REG_BASE 0xE8A21000 #define TZC_STAT0_REG (TZC_REG_BASE + 0x800) diff --git a/plat/hisilicon/hikey960/platform.mk b/plat/hisilicon/hikey960/platform.mk index 6cb53c7b6..8ebabebc9 100644 --- a/plat/hisilicon/hikey960/platform.mk +++ b/plat/hisilicon/hikey960/platform.mk @@ -19,7 +19,7 @@ endif CRASH_CONSOLE_BASE := PL011_UART6_BASE COLD_BOOT_SINGLE_CPU := 1 -PLAT_PL061_MAX_GPIOS := 176 +PLAT_PL061_MAX_GPIOS := 232 PROGRAMMABLE_RESET_ADDRESS := 1 ENABLE_SVE_FOR_NS := 0 PLAT_PARTITION_BLOCK_SIZE := 4096 @@ -95,12 +95,15 @@ BL2_SOURCES += lib/optee/optee_utils.c endif BL31_SOURCES += drivers/arm/cci/cci.c \ + drivers/arm/pl061/pl061_gpio.c \ + drivers/gpio/gpio.c \ lib/cpus/aarch64/cortex_a53.S \ lib/cpus/aarch64/cortex_a72.S \ lib/cpus/aarch64/cortex_a73.S \ plat/common/plat_psci_common.c \ plat/hisilicon/hikey960/aarch64/hikey960_helpers.S \ plat/hisilicon/hikey960/hikey960_bl31_setup.c \ + plat/hisilicon/hikey960/hikey960_bl_common.c \ plat/hisilicon/hikey960/hikey960_pm.c \ plat/hisilicon/hikey960/hikey960_topology.c \ plat/hisilicon/hikey960/drivers/pwrc/hisi_pwrc.c \ -- cgit v1.2.3 From 7cd64d19c9325af87d003a3277028cffd982a2b6 Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Thu, 23 Jan 2020 11:24:33 +0100 Subject: fconf: Add Secure Partitions information as property Use the firmware configuration framework to retrieve information about Secure Partitions to facilitate loading them into memory. To load a SP image we need UUID look-up into FIP and the load address where it needs to be loaded in memory. This patch introduces a SP populator function which gets UUID and load address from firmware config device tree and updates its C data structure. Change-Id: I17faec41803df9a76712dcc8b67cadb1c9daf8cd Signed-off-by: Olivier Deprez Signed-off-by: Manish Pandey --- include/export/common/tbbr/tbbr_img_def_exp.h | 5 ++ include/plat/arm/common/fconf_arm_sp_getter.h | 26 +++++++++ plat/arm/common/arm_common.mk | 3 + plat/arm/common/fconf/arm_fconf_sp.c | 84 +++++++++++++++++++++++++++ 4 files changed, 118 insertions(+) create mode 100644 include/plat/arm/common/fconf_arm_sp_getter.h create mode 100644 plat/arm/common/fconf/arm_fconf_sp.c diff --git a/include/export/common/tbbr/tbbr_img_def_exp.h b/include/export/common/tbbr/tbbr_img_def_exp.h index ff0d16c73..360255413 100644 --- a/include/export/common/tbbr/tbbr_img_def_exp.h +++ b/include/export/common/tbbr/tbbr_img_def_exp.h @@ -86,6 +86,11 @@ #define STM32_IMAGE_ID U(29) /* Define size of the array */ +#if defined(SPD_spmd) +#define MAX_SP_IDS U(8) +#define MAX_NUMBER_IDS MAX_SP_IDS + U(30) +#else #define MAX_NUMBER_IDS U(30) +#endif #endif /* ARM_TRUSTED_FIRMWARE_EXPORT_COMMON_TBBR_TBBR_IMG_DEF_EXP_H */ diff --git a/include/plat/arm/common/fconf_arm_sp_getter.h b/include/plat/arm/common/fconf_arm_sp_getter.h new file mode 100644 index 000000000..57fd92edf --- /dev/null +++ b/include/plat/arm/common/fconf_arm_sp_getter.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FCONF_ARM_SP_GETTER_H +#define FCONF_ARM_SP_GETTER_H + +#include +#include + +/* arm_sp getter */ +#define arm__sp_getter(prop) arm_sp.prop + +struct arm_sp_t { + unsigned int number_of_sp; + union uuid_helper_t uuids[MAX_SP_IDS]; + uintptr_t load_addr[MAX_SP_IDS]; +}; + +int fconf_populate_arm_sp(uintptr_t config); + +extern struct arm_sp_t arm_sp; + +#endif /* FCONF_ARM_SP_GETTER_H */ diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index 17058d1a5..4fb85fbee 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -182,6 +182,9 @@ ARM_IO_SOURCES += plat/arm/common/arm_io_storage.c else ARM_IO_SOURCES += plat/arm/common/arm_fconf_io_storage.c \ plat/arm/common/fconf/arm_fconf_io.c +ifeq (${SPD},spmd) +ARM_IO_SOURCES += plat/arm/common/fconf/arm_fconf_sp.c +endif endif BL1_SOURCES += drivers/io/io_fip.c \ diff --git a/plat/arm/common/fconf/arm_fconf_sp.c b/plat/arm/common/fconf/arm_fconf_sp.c new file mode 100644 index 000000000..0e5cfff95 --- /dev/null +++ b/plat/arm/common/fconf/arm_fconf_sp.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef IMAGE_BL2 + +struct arm_sp_t arm_sp; + +int fconf_populate_arm_sp(uintptr_t config) +{ + int sp_node, node, err; + union uuid_helper_t uuid_helper; + + /* As libfdt use void *, we can't avoid this cast */ + const void *dtb = (void *)config; + + /* Assert the node offset point to "arm,sp" compatible property */ + const char *compatible_str = "arm,sp"; + + node = fdt_node_offset_by_compatible(dtb, -1, compatible_str); + if (node < 0) { + ERROR("FCONF: Can't find %s in dtb\n", compatible_str); + return node; + } + + fdt_for_each_subnode(sp_node, dtb, node) { + err = fdtw_read_array(dtb, sp_node, "uuid", 4, + &uuid_helper.word); + if (err < 0) { + ERROR("FCONF: cannot read SP uuid\n"); + return -1; + } + + arm_sp.uuids[arm_sp.number_of_sp] = uuid_helper; + + err = fdtw_read_cells(dtb, sp_node, "load-address", 1, + &arm_sp.load_addr[arm_sp.number_of_sp]); + if (err < 0) { + ERROR("FCONF: cannot read SP load address\n"); + return -1; + } + + VERBOSE("FCONF: %s UUID %x-%x-%x-%x load_addr=%lx\n", + __func__, + uuid_helper.word[0], + uuid_helper.word[1], + uuid_helper.word[2], + uuid_helper.word[3], + arm_sp.load_addr[arm_sp.number_of_sp]); + + arm_sp.number_of_sp++; + + if (arm_sp.number_of_sp >= MAX_SP_IDS) { + ERROR("FCONF: reached max number of SPs\n"); + return -1; + } + } + + if ((sp_node < 0) && (sp_node != -FDT_ERR_NOTFOUND)) { + ERROR("%d: fdt_for_each_subnode(): %d\n", __LINE__, node); + return sp_node; + } + + return 0; +} + +FCONF_REGISTER_POPULATOR(arm_sp, fconf_populate_arm_sp); + +#endif /* IMAGE_BL2 */ -- cgit v1.2.3 From 8f066f6167f47a29a46e66d1210f5afbf94a8c40 Mon Sep 17 00:00:00 2001 From: Manish Pandey Date: Tue, 18 Feb 2020 13:08:14 +0000 Subject: fvp: add Cactus/Ivy Secure Partition information Add load address and UUID in fw config dts for Cactus and Ivy which are example SP's in tf-test repository. For prototype purpose these information is added manually but later on it will be updated at compile time from SP layout file and SP manifests provided by platform. Change-Id: I41f485e0245d882c7b514bad41fae34036597ce4 Signed-off-by: Manish Pandey --- plat/arm/board/fvp/fdts/fvp_fw_config.dts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/plat/arm/board/fvp/fdts/fvp_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_fw_config.dts index d0f60331d..9a4a05799 100644 --- a/plat/arm/board/fvp/fdts/fvp_fw_config.dts +++ b/plat/arm/board/fvp/fdts/fvp_fw_config.dts @@ -69,6 +69,12 @@ mbedtls_heap_size = <0x0>; }; + /* + * Though TF-A is UUID RFC 4122 compliant meaning fields are stored in + * network order (big endian), UUID's mentioned in this file are are + * stored in machine order (little endian). + * This will be fixed in future. + */ arm-io_policies { fip-handles { compatible = "arm,io-fip-handle"; @@ -93,4 +99,17 @@ nt_fw_content_cert_uuid = <0xf3c1c48e 0x11e4635d 0xee87a9a7 0xa73fb240>; }; }; + + secure-partitions { + compatible = "arm,sp"; + cactus { + uuid = <0x1e67b5b4 0xe14f904a 0x13fb1fb8 0xcbdae1da>; + load-address = <0x7000000>; + }; + + ivy { + uuid = <0x092358d1 0xb94723f0 0x64447c82 0xc88f57f5>; + load-address = <0x7100000>; + }; + }; }; -- cgit v1.2.3 From 2825946e92c0bb14482a1a23e2304aed95e72718 Mon Sep 17 00:00:00 2001 From: Max Shvetsov Date: Mon, 17 Feb 2020 16:15:47 +0000 Subject: SPMD: Adds partially supported EL2 registers. This patch adds EL2 registers that are supported up to ARMv8.6. ARM_ARCH_MINOR has to specified to enable save/restore routine. Note: Following registers are still not covered in save/restore. * AMEVCNTVOFF0_EL2 * AMEVCNTVOFF1_EL2 * ICH_AP0R_EL2 * ICH_AP1R_EL2 * ICH_LR_EL2 Change-Id: I4813f3243e56e21cb297b31ef549a4b38d4876e1 Signed-off-by: Max Shvetsov --- include/arch/aarch64/arch.h | 7 +- include/lib/el3_runtime/aarch64/context.h | 213 +++++++----- lib/el3_runtime/aarch64/context.S | 527 +++++++++++++++--------------- lib/el3_runtime/aarch64/context_mgmt.c | 14 +- services/spd/trusty/trusty.c | 6 +- services/std_svc/spm_mm/spm_mm_setup.c | 16 +- 6 files changed, 413 insertions(+), 370 deletions(-) diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index d5939971e..b0c265047 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -107,12 +107,8 @@ #define HFGITR_EL2 S3_4_C1_C1_6 #define HFGRTR_EL2 S3_4_C1_C1_4 #define HFGWTR_EL2 S3_4_C1_C1_5 -#define ICH_EISR_EL2 S3_4_C12_C11_3 -#define ICH_ELRSR_EL2 S3_4_C12_C11_5 #define ICH_HCR_EL2 S3_4_C12_C11_0 -#define ICH_MISR_EL2 S3_4_C12_C11_2 #define ICH_VMCR_EL2 S3_4_C12_C11_7 -#define ICH_VTR_EL2 S3_4_C12_C11_1 #define MPAMVPM0_EL2 S3_4_C10_C5_0 #define MPAMVPM1_EL2 S3_4_C10_C5_1 #define MPAMVPM2_EL2 S3_4_C10_C5_2 @@ -122,6 +118,9 @@ #define MPAMVPM6_EL2 S3_4_C10_C5_6 #define MPAMVPM7_EL2 S3_4_C10_C5_7 #define MPAMVPMV_EL2 S3_4_C10_C4_1 +#define TRFCR_EL2 S3_4_C1_C2_1 +#define PMSCR_EL2 S3_4_C9_C9_0 +#define TFSR_EL2 S3_4_C5_C6_0 /******************************************************************************* * Generic timer memory mapped registers & offsets diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h index 6559b60a3..e061950c8 100644 --- a/include/lib/el3_runtime/aarch64/context.h +++ b/include/lib/el3_runtime/aarch64/context.h @@ -68,7 +68,7 @@ * registers are only 32-bits wide but are stored as 64-bit values for * convenience ******************************************************************************/ -#define CTX_SYSREGS_OFFSET (CTX_EL3STATE_OFFSET + CTX_EL3STATE_END) +#define CTX_EL1_SYSREGS_OFFSET (CTX_EL3STATE_OFFSET + CTX_EL3STATE_END) #define CTX_SPSR_EL1 U(0x0) #define CTX_ELR_EL1 U(0x8) #define CTX_SCTLR_EL1 U(0x10) @@ -136,7 +136,12 @@ #endif /* CTX_INCLUDE_MTE_REGS */ /* - * S-EL2 register set + * End of system registers. + */ +#define CTX_EL1_SYSREGS_END CTX_MTE_REGS_END + +/* + * EL2 register set */ #if CTX_INCLUDE_EL2_REGS @@ -147,82 +152,104 @@ * AMEVCNTVOFF1_EL2 * ICH_LR_EL2 */ -#define CTX_ACTLR_EL2 (CTX_MTE_REGS_END + U(0x0)) -#define CTX_AFSR0_EL2 (CTX_MTE_REGS_END + U(0x8)) -#define CTX_AFSR1_EL2 (CTX_MTE_REGS_END + U(0x10)) -#define CTX_AMAIR_EL2 (CTX_MTE_REGS_END + U(0x18)) -#define CTX_CNTHCTL_EL2 (CTX_MTE_REGS_END + U(0x20)) -#define CTX_CNTHP_CTL_EL2 (CTX_MTE_REGS_END + U(0x28)) -#define CTX_CNTHP_CVAL_EL2 (CTX_MTE_REGS_END + U(0x30)) -#define CTX_CNTHP_TVAL_EL2 (CTX_MTE_REGS_END + U(0x38)) -#define CTX_CNTPOFF_EL2 (CTX_MTE_REGS_END + U(0x40)) -#define CTX_CNTVOFF_EL2 (CTX_MTE_REGS_END + U(0x48)) -#define CTX_CPTR_EL2 (CTX_MTE_REGS_END + U(0x50)) -#define CTX_DBGVCR32_EL2 (CTX_MTE_REGS_END + U(0x58)) -#define CTX_ELR_EL2 (CTX_MTE_REGS_END + U(0x60)) -#define CTX_ESR_EL2 (CTX_MTE_REGS_END + U(0x68)) -#define CTX_FAR_EL2 (CTX_MTE_REGS_END + U(0x70)) -#define CTX_FPEXC32_EL2 (CTX_MTE_REGS_END + U(0x78)) -#define CTX_HACR_EL2 (CTX_MTE_REGS_END + U(0x80)) -#define CTX_HAFGRTR_EL2 (CTX_MTE_REGS_END + U(0x88)) -#define CTX_HCR_EL2 (CTX_MTE_REGS_END + U(0x90)) -#define CTX_HDFGRTR_EL2 (CTX_MTE_REGS_END + U(0x98)) -#define CTX_HDFGWTR_EL2 (CTX_MTE_REGS_END + U(0xA0)) -#define CTX_HFGITR_EL2 (CTX_MTE_REGS_END + U(0xA8)) -#define CTX_HFGRTR_EL2 (CTX_MTE_REGS_END + U(0xB0)) -#define CTX_HFGWTR_EL2 (CTX_MTE_REGS_END + U(0xB8)) -#define CTX_HPFAR_EL2 (CTX_MTE_REGS_END + U(0xC0)) -#define CTX_HSTR_EL2 (CTX_MTE_REGS_END + U(0xC8)) -#define CTX_ICC_SRE_EL2 (CTX_MTE_REGS_END + U(0xD0)) -#define CTX_ICH_EISR_EL2 (CTX_MTE_REGS_END + U(0xD8)) -#define CTX_ICH_ELRSR_EL2 (CTX_MTE_REGS_END + U(0xE0)) -#define CTX_ICH_HCR_EL2 (CTX_MTE_REGS_END + U(0xE8)) -#define CTX_ICH_MISR_EL2 (CTX_MTE_REGS_END + U(0xF0)) -#define CTX_ICH_VMCR_EL2 (CTX_MTE_REGS_END + U(0xF8)) -#define CTX_ICH_VTR_EL2 (CTX_MTE_REGS_END + U(0x100)) -#define CTX_MAIR_EL2 (CTX_MTE_REGS_END + U(0x108)) -#define CTX_MDCR_EL2 (CTX_MTE_REGS_END + U(0x110)) -#define CTX_MPAM2_EL2 (CTX_MTE_REGS_END + U(0x118)) -#define CTX_MPAMHCR_EL2 (CTX_MTE_REGS_END + U(0x120)) -#define CTX_MPAMVPM0_EL2 (CTX_MTE_REGS_END + U(0x128)) -#define CTX_MPAMVPM1_EL2 (CTX_MTE_REGS_END + U(0x130)) -#define CTX_MPAMVPM2_EL2 (CTX_MTE_REGS_END + U(0x138)) -#define CTX_MPAMVPM3_EL2 (CTX_MTE_REGS_END + U(0x140)) -#define CTX_MPAMVPM4_EL2 (CTX_MTE_REGS_END + U(0x148)) -#define CTX_MPAMVPM5_EL2 (CTX_MTE_REGS_END + U(0x150)) -#define CTX_MPAMVPM6_EL2 (CTX_MTE_REGS_END + U(0x158)) -#define CTX_MPAMVPM7_EL2 (CTX_MTE_REGS_END + U(0x160)) -#define CTX_MPAMVPMV_EL2 (CTX_MTE_REGS_END + U(0x168)) -#define CTX_RMR_EL2 (CTX_MTE_REGS_END + U(0x170)) -#define CTX_SCTLR_EL2 (CTX_MTE_REGS_END + U(0x178)) -#define CTX_SPSR_EL2 (CTX_MTE_REGS_END + U(0x180)) -#define CTX_SP_EL2 (CTX_MTE_REGS_END + U(0x188)) -#define CTX_TCR_EL2 (CTX_MTE_REGS_END + U(0x190)) -#define CTX_TPIDR_EL2 (CTX_MTE_REGS_END + U(0x198)) -#define CTX_TTBR0_EL2 (CTX_MTE_REGS_END + U(0x1A0)) -#define CTX_VBAR_EL2 (CTX_MTE_REGS_END + U(0x1A8)) -#define CTX_VMPIDR_EL2 (CTX_MTE_REGS_END + U(0x1B0)) -#define CTX_VPIDR_EL2 (CTX_MTE_REGS_END + U(0x1B8)) -#define CTX_VTCR_EL2 (CTX_MTE_REGS_END + U(0x1C0)) -#define CTX_VTTBR_EL2 (CTX_MTE_REGS_END + U(0x1C8)) -#define CTX_ZCR_EL2 (CTX_MTE_REGS_END + U(0x1B0)) - +#define CTX_EL2_SYSREGS_OFFSET (CTX_EL1_SYSREGS_OFFSET + CTX_EL1_SYSREGS_END) + +#define CTX_ACTLR_EL2 U(0x0) +#define CTX_AFSR0_EL2 U(0x8) +#define CTX_AFSR1_EL2 U(0x10) +#define CTX_AMAIR_EL2 U(0x18) +#define CTX_CNTHCTL_EL2 U(0x20) +#define CTX_CNTHP_CTL_EL2 U(0x28) +#define CTX_CNTHP_CVAL_EL2 U(0x30) +#define CTX_CNTHP_TVAL_EL2 U(0x38) +#define CTX_CNTVOFF_EL2 U(0x40) +#define CTX_CPTR_EL2 U(0x48) +#define CTX_DBGVCR32_EL2 U(0x50) +#define CTX_ELR_EL2 U(0x58) +#define CTX_ESR_EL2 U(0x60) +#define CTX_FAR_EL2 U(0x68) +#define CTX_FPEXC32_EL2 U(0x70) +#define CTX_HACR_EL2 U(0x78) +#define CTX_HCR_EL2 U(0x80) +#define CTX_HPFAR_EL2 U(0x88) +#define CTX_HSTR_EL2 U(0x90) +#define CTX_ICC_SRE_EL2 U(0x98) +#define CTX_ICH_HCR_EL2 U(0xa0) +#define CTX_ICH_VMCR_EL2 U(0xa8) +#define CTX_MAIR_EL2 U(0xb0) +#define CTX_MDCR_EL2 U(0xb8) +#define CTX_PMSCR_EL2 U(0xc0) +#define CTX_SCTLR_EL2 U(0xc8) +#define CTX_SPSR_EL2 U(0xd0) +#define CTX_SP_EL2 U(0xd8) +#define CTX_TCR_EL2 U(0xe0) +#define CTX_TRFCR_EL2 U(0xe8) +#define CTX_TTBR0_EL2 U(0xf0) +#define CTX_VBAR_EL2 U(0xf8) +#define CTX_VMPIDR_EL2 U(0x100) +#define CTX_VPIDR_EL2 U(0x108) +#define CTX_VTCR_EL2 U(0x110) +#define CTX_VTTBR_EL2 U(0x118) + +// Only if MTE registers in use +#define CTX_TFSR_EL2 U(0x120) + +// Only if ENABLE_MPAM_FOR_LOWER_ELS==1 +#define CTX_MPAM2_EL2 U(0x128) +#define CTX_MPAMHCR_EL2 U(0x130) +#define CTX_MPAMVPM0_EL2 U(0x138) +#define CTX_MPAMVPM1_EL2 U(0x140) +#define CTX_MPAMVPM2_EL2 U(0x148) +#define CTX_MPAMVPM3_EL2 U(0x150) +#define CTX_MPAMVPM4_EL2 U(0x158) +#define CTX_MPAMVPM5_EL2 U(0x160) +#define CTX_MPAMVPM6_EL2 U(0x168) +#define CTX_MPAMVPM7_EL2 U(0x170) +#define CTX_MPAMVPMV_EL2 U(0x178) + +// Starting with Armv8.6 +#define CTX_HAFGRTR_EL2 U(0x180) +#define CTX_HDFGRTR_EL2 U(0x188) +#define CTX_HDFGWTR_EL2 U(0x190) +#define CTX_HFGITR_EL2 U(0x198) +#define CTX_HFGRTR_EL2 U(0x1a0) +#define CTX_HFGWTR_EL2 U(0x1a8) +#define CTX_CNTPOFF_EL2 U(0x1b0) + +// Starting with Armv8.4 +#define CTX_CNTHPS_CTL_EL2 U(0x1b8) +#define CTX_CNTHPS_CVAL_EL2 U(0x1c0) +#define CTX_CNTHPS_TVAL_EL2 U(0x1c8) +#define CTX_CNTHVS_CTL_EL2 U(0x1d0) +#define CTX_CNTHVS_CVAL_EL2 U(0x1d8) +#define CTX_CNTHVS_TVAL_EL2 U(0x1e0) +#define CTX_CNTHV_CTL_EL2 U(0x1e8) +#define CTX_CNTHV_CVAL_EL2 U(0x1f0) +#define CTX_CNTHV_TVAL_EL2 U(0x1f8) +#define CTX_CONTEXTIDR_EL2 U(0x200) +#define CTX_SDER32_EL2 U(0x208) +#define CTX_TTBR1_EL2 U(0x210) +#define CTX_VDISR_EL2 U(0x218) +#define CTX_VNCR_EL2 U(0x220) +#define CTX_VSESR_EL2 U(0x228) +#define CTX_VSTCR_EL2 U(0x230) +#define CTX_VSTTBR_EL2 U(0x238) + +// Starting with Armv8.5 +#define CTX_SCXTNUM_EL2 U(0x240) /* Align to the next 16 byte boundary */ -#define CTX_EL2_REGS_END (CTX_MTE_REGS_END + U(0x1C0)) -#else -#define CTX_EL2_REGS_END CTX_MTE_REGS_END +#define CTX_EL2_SYSREGS_END U(0x250) #endif /* CTX_INCLUDE_EL2_REGS */ -/* - * End of system registers. - */ -#define CTX_SYSREGS_END CTX_EL2_REGS_END - /******************************************************************************* * Constants that allow assembler code to access members of and the 'fp_regs' * structure at their correct offsets. ******************************************************************************/ -#define CTX_FPREGS_OFFSET (CTX_SYSREGS_OFFSET + CTX_SYSREGS_END) +#if CTX_INCLUDE_EL2_REGS +# define CTX_FPREGS_OFFSET (CTX_EL2_SYSREGS_OFFSET + CTX_EL2_SYSREGS_END) +#else +# define CTX_FPREGS_OFFSET (CTX_EL1_SYSREGS_OFFSET + CTX_EL1_SYSREGS_END) +#endif #if CTX_INCLUDE_FPREGS #define CTX_FP_Q0 U(0x0) #define CTX_FP_Q1 U(0x10) @@ -313,7 +340,10 @@ /* Constants to determine the size of individual context structures */ #define CTX_GPREG_ALL (CTX_GPREGS_END >> DWORD_SHIFT) -#define CTX_SYSREG_ALL (CTX_SYSREGS_END >> DWORD_SHIFT) +#define CTX_EL1_SYSREGS_ALL (CTX_EL1_SYSREGS_END >> DWORD_SHIFT) +#if CTX_INCLUDE_EL2_REGS +# define CTX_EL2_SYSREGS_ALL (CTX_EL2_SYSREGS_END >> DWORD_SHIFT) +#endif #if CTX_INCLUDE_FPREGS # define CTX_FPREG_ALL (CTX_FPREGS_END >> DWORD_SHIFT) #endif @@ -333,10 +363,19 @@ DEFINE_REG_STRUCT(gp_regs, CTX_GPREG_ALL); /* - * AArch64 EL1/EL2 system register context structure for preserving the + * AArch64 EL1 system register context structure for preserving the * architectural state during world switches. */ -DEFINE_REG_STRUCT(sys_regs, CTX_SYSREG_ALL); +DEFINE_REG_STRUCT(el1_sysregs, CTX_EL1_SYSREGS_ALL); + + +/* + * AArch64 EL2 system register context structure for preserving the + * architectural state during world switches. + */ +#if CTX_INCLUDE_EL2_REGS +DEFINE_REG_STRUCT(el2_sysregs, CTX_EL2_SYSREGS_ALL); +#endif /* * AArch64 floating point register context structure for preserving @@ -381,7 +420,10 @@ DEFINE_REG_STRUCT(pauth, CTX_PAUTH_REGS_ALL); typedef struct cpu_context { gp_regs_t gpregs_ctx; el3_state_t el3state_ctx; - sys_regs_t sysregs_ctx; + el1_sysregs_t el1_sysregs_ctx; +#if CTX_INCLUDE_EL2_REGS + el2_sysregs_t el2_sysregs_ctx; +#endif #if CTX_INCLUDE_FPREGS fp_regs_t fpregs_ctx; #endif @@ -396,7 +438,10 @@ typedef struct cpu_context { #if CTX_INCLUDE_FPREGS # define get_fpregs_ctx(h) (&((cpu_context_t *) h)->fpregs_ctx) #endif -#define get_sysregs_ctx(h) (&((cpu_context_t *) h)->sysregs_ctx) +#define get_el1_sysregs_ctx(h) (&((cpu_context_t *) h)->el1_sysregs_ctx) +#if CTX_INCLUDE_EL2_REGS +# define get_el2_sysregs_ctx(h) (&((cpu_context_t *) h)->el2_sysregs_ctx) +#endif #define get_gpregs_ctx(h) (&((cpu_context_t *) h)->gpregs_ctx) #define get_cve_2018_3639_ctx(h) (&((cpu_context_t *) h)->cve_2018_3639_ctx) #if CTX_INCLUDE_PAUTH_REGS @@ -410,8 +455,12 @@ typedef struct cpu_context { */ CASSERT(CTX_GPREGS_OFFSET == __builtin_offsetof(cpu_context_t, gpregs_ctx), \ assert_core_context_gp_offset_mismatch); -CASSERT(CTX_SYSREGS_OFFSET == __builtin_offsetof(cpu_context_t, sysregs_ctx), \ - assert_core_context_sys_offset_mismatch); +CASSERT(CTX_EL1_SYSREGS_OFFSET == __builtin_offsetof(cpu_context_t, el1_sysregs_ctx), \ + assert_core_context_el1_sys_offset_mismatch); +#if CTX_INCLUDE_EL2_REGS +CASSERT(CTX_EL2_SYSREGS_OFFSET == __builtin_offsetof(cpu_context_t, el2_sysregs_ctx), \ + assert_core_context_el2_sys_offset_mismatch); +#endif #if CTX_INCLUDE_FPREGS CASSERT(CTX_FPREGS_OFFSET == __builtin_offsetof(cpu_context_t, fpregs_ctx), \ assert_core_context_fp_offset_mismatch); @@ -464,12 +513,12 @@ CASSERT(CTX_PAUTH_REGS_OFFSET == __builtin_offsetof(cpu_context_t, pauth_ctx), \ /******************************************************************************* * Function prototypes ******************************************************************************/ -void el1_sysregs_context_save(sys_regs_t *regs); -void el1_sysregs_context_restore(sys_regs_t *regs); +void el1_sysregs_context_save(el1_sysregs_t *regs); +void el1_sysregs_context_restore(el1_sysregs_t *regs); #if CTX_INCLUDE_EL2_REGS -void el2_sysregs_context_save(sys_regs_t *regs); -void el2_sysregs_context_restore(sys_regs_t *regs); +void el2_sysregs_context_save(el2_sysregs_t *regs); +void el2_sysregs_context_restore(el2_sysregs_t *regs); #endif #if CTX_INCLUDE_FPREGS diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S index bcc7eef9e..30ad7b7d1 100644 --- a/lib/el3_runtime/aarch64/context.S +++ b/lib/el3_runtime/aarch64/context.S @@ -29,189 +29,187 @@ /* ----------------------------------------------------- * The following function strictly follows the AArch64 * PCS to use x9-x17 (temporary caller-saved registers) - * to save EL1 system register context. It assumes that - * 'x0' is pointing to a 'el1_sys_regs' structure where + * to save EL2 system register context. It assumes that + * 'x0' is pointing to a 'el2_sys_regs' structure where * the register context will be saved. + * + * The following registers are not added. + * AMEVCNTVOFF0_EL2 + * AMEVCNTVOFF1_EL2 + * ICH_AP0R_EL2 + * ICH_AP1R_EL2 + * ICH_LR_EL2 * ----------------------------------------------------- */ -func el2_sysregs_context_save +func el2_sysregs_context_save mrs x9, actlr_el2 - str x9, [x0, #CTX_ACTLR_EL2] - - mrs x9, afsr0_el2 - str x9, [x0, #CTX_AFSR0_EL2] - - mrs x9, afsr1_el2 - str x9, [x0, #CTX_AFSR1_EL2] - - mrs x9, amair_el2 - str x9, [x0, #CTX_AMAIR_EL2] - - mrs x9, cnthctl_el2 - str x9, [x0, #CTX_CNTHCTL_EL2] - - mrs x9, cnthp_ctl_el2 - str x9, [x0, #CTX_CNTHP_CTL_EL2] + mrs x10, afsr0_el2 + stp x9, x10, [x0, #CTX_ACTLR_EL2] - mrs x9, cnthp_cval_el2 - str x9, [x0, #CTX_CNTHP_CVAL_EL2] + mrs x11, afsr1_el2 + mrs x12, amair_el2 + stp x11, x12, [x0, #CTX_AFSR1_EL2] - mrs x9, cnthp_tval_el2 - str x9, [x0, #CTX_CNTHP_TVAL_EL2] + mrs x13, cnthctl_el2 + mrs x14, cnthp_ctl_el2 + stp x13, x14, [x0, #CTX_CNTHCTL_EL2] - mrs x9, CNTPOFF_EL2 - str x9, [x0, #CTX_CNTPOFF_EL2] - - mrs x9, cntvoff_el2 - str x9, [x0, #CTX_CNTVOFF_EL2] + mrs x15, cnthp_cval_el2 + mrs x16, cnthp_tval_el2 + stp x15, x16, [x0, #CTX_CNTHP_CVAL_EL2] + mrs x17, cntvoff_el2 mrs x9, cptr_el2 - str x9, [x0, #CTX_CPTR_EL2] - - mrs x9, dbgvcr32_el2 - str x9, [x0, #CTX_DBGVCR32_EL2] - - mrs x9, elr_el2 - str x9, [x0, #CTX_ELR_EL2] - - mrs x9, esr_el2 - str x9, [x0, #CTX_ESR_EL2] + stp x17, x9, [x0, #CTX_CNTVOFF_EL2] - mrs x9, far_el2 - str x9, [x0, #CTX_FAR_EL2] + mrs x10, dbgvcr32_el2 + mrs x11, elr_el2 + stp x10, x11, [x0, #CTX_DBGVCR32_EL2] - mrs x9, fpexc32_el2 - str x9, [x0, #CTX_FPEXC32_EL2] + mrs x14, esr_el2 + mrs x15, far_el2 + stp x14, x15, [x0, #CTX_ESR_EL2] - mrs x9, hacr_el2 - str x9, [x0, #CTX_HACR_EL2] - - mrs x9, HAFGRTR_EL2 - str x9, [x0, #CTX_HAFGRTR_EL2] + mrs x16, fpexc32_el2 + mrs x17, hacr_el2 + stp x16, x17, [x0, #CTX_FPEXC32_EL2] mrs x9, hcr_el2 - str x9, [x0, #CTX_HCR_EL2] - - mrs x9, HDFGRTR_EL2 - str x9, [x0, #CTX_HDFGRTR_EL2] - - mrs x9, HDFGWTR_EL2 - str x9, [x0, #CTX_HDFGWTR_EL2] - - mrs x9, HFGITR_EL2 - str x9, [x0, #CTX_HFGITR_EL2] + mrs x10, hpfar_el2 + stp x9, x10, [x0, #CTX_HCR_EL2] - mrs x9, HFGRTR_EL2 - str x9, [x0, #CTX_HFGRTR_EL2] + mrs x11, hstr_el2 + mrs x12, ICC_SRE_EL2 + stp x11, x12, [x0, #CTX_HSTR_EL2] - mrs x9, HFGWTR_EL2 - str x9, [x0, #CTX_HFGWTR_EL2] + mrs x13, ICH_HCR_EL2 + mrs x14, ICH_VMCR_EL2 + stp x13, x14, [x0, #CTX_ICH_HCR_EL2] - mrs x9, hpfar_el2 - str x9, [x0, #CTX_HPFAR_EL2] + mrs x15, mair_el2 + mrs x16, mdcr_el2 + stp x15, x16, [x0, #CTX_MAIR_EL2] - mrs x9, hstr_el2 - str x9, [x0, #CTX_HSTR_EL2] - - mrs x9, ICC_SRE_EL2 - str x9, [x0, #CTX_ICC_SRE_EL2] - - mrs x9, ICH_EISR_EL2 - str x9, [x0, #CTX_ICH_EISR_EL2] - - mrs x9, ICH_ELRSR_EL2 - str x9, [x0, #CTX_ICH_ELRSR_EL2] + mrs x17, PMSCR_EL2 + mrs x9, sctlr_el2 + stp x17, x9, [x0, #CTX_PMSCR_EL2] - mrs x9, ICH_HCR_EL2 - str x9, [x0, #CTX_ICH_HCR_EL2] + mrs x10, spsr_el2 + mrs x11, sp_el2 + stp x10, x11, [x0, #CTX_SPSR_EL2] - mrs x9, ICH_MISR_EL2 - str x9, [x0, #CTX_ICH_MISR_EL2] + mrs x12, tcr_el2 + mrs x13, TRFCR_EL2 + stp x12, x13, [x0, #CTX_TCR_EL2] - mrs x9, ICH_VMCR_EL2 - str x9, [x0, #CTX_ICH_VMCR_EL2] + mrs x14, ttbr0_el2 + mrs x15, vbar_el2 + stp x14, x15, [x0, #CTX_TTBR0_EL2] - mrs x9, ICH_VTR_EL2 - str x9, [x0, #CTX_ICH_VTR_EL2] + mrs x16, vmpidr_el2 + mrs x17, vpidr_el2 + stp x16, x17, [x0, #CTX_VMPIDR_EL2] - mrs x9, mair_el2 - str x9, [x0, #CTX_MAIR_EL2] + mrs x9, vtcr_el2 + mrs x10, vttbr_el2 + stp x9, x10, [x0, #CTX_VTCR_EL2] - mrs x9, mdcr_el2 - str x9, [x0, #CTX_MDCR_EL2] +#if CTX_INCLUDE_MTE_REGS + mrs x11, TFSR_EL2 + str x11, [x0, #CTX_TFSR_EL2] +#endif +#if ENABLE_MPAM_FOR_LOWER_ELS mrs x9, MPAM2_EL2 - str x9, [x0, #CTX_MPAM2_EL2] + mrs x10, MPAMHCR_EL2 + stp x9, x10, [x0, #CTX_MPAM2_EL2] - mrs x9, MPAMHCR_EL2 - str x9, [x0, #CTX_MPAMHCR_EL2] + mrs x11, MPAMVPM0_EL2 + mrs x12, MPAMVPM1_EL2 + stp x11, x12, [x0, #CTX_MPAMVPM0_EL2] - mrs x9, MPAMVPM0_EL2 - str x9, [x0, #CTX_MPAMVPM0_EL2] + mrs x13, MPAMVPM2_EL2 + mrs x14, MPAMVPM3_EL2 + stp x13, x14, [x0, #CTX_MPAMVPM2_EL2] - mrs x9, MPAMVPM1_EL2 - str x9, [x0, #CTX_MPAMVPM1_EL2] + mrs x15, MPAMVPM4_EL2 + mrs x16, MPAMVPM5_EL2 + stp x15, x16, [x0, #CTX_MPAMVPM4_EL2] - mrs x9, MPAMVPM2_EL2 - str x9, [x0, #CTX_MPAMVPM2_EL2] + mrs x17, MPAMVPM6_EL2 + mrs x9, MPAMVPM7_EL2 + stp x17, x9, [x0, #CTX_MPAMVPM6_EL2] - mrs x9, MPAMVPM3_EL2 - str x9, [x0, #CTX_MPAMVPM3_EL2] + mrs x10, MPAMVPMV_EL2 + str x10, [x0, #CTX_MPAMVPMV_EL2] +#endif - mrs x9, MPAMVPM4_EL2 - str x9, [x0, #CTX_MPAMVPM4_EL2] - mrs x9, MPAMVPM5_EL2 - str x9, [x0, #CTX_MPAMVPM5_EL2] +#if ARM_ARCH_AT_LEAST(8, 6) + mrs x11, HAFGRTR_EL2 + mrs x12, HDFGRTR_EL2 + stp x11, x12, [x0, #CTX_HAFGRTR_EL2] - mrs x9, MPAMVPM6_EL2 - str x9, [x0, #CTX_MPAMVPM6_EL2] + mrs x13, HDFGWTR_EL2 + mrs x14, HFGITR_EL2 + stp x13, x14, [x0, #CTX_HDFGWTR_EL2] - mrs x9, MPAMVPM7_EL2 - str x9, [x0, #CTX_MPAMVPM7_EL2] + mrs x15, HFGRTR_EL2 + mrs x16, HFGWTR_EL2 + stp x15, x16, [x0, #CTX_HFGRTR_EL2] - mrs x9, MPAMVPMV_EL2 - str x9, [x0, #CTX_MPAMVPMV_EL2] + mrs x17, CNTPOFF_EL2 + str x17, [x0, #CTX_CNTPOFF_EL2] +#endif - mrs x9, rmr_el2 - str x9, [x0, #CTX_RMR_EL2] +#if ARM_ARCH_AT_LEAST(8, 4) + mrs x9, cnthps_ctl_el2 + mrs x10, cnthps_cval_el2 + stp x9, x10, [x0, #CTX_CNTHPS_CTL_EL2] - mrs x9, sctlr_el2 - str x9, [x0, #CTX_SCTLR_EL2] + mrs x11, cnthps_tval_el2 + mrs x12, cnthvs_ctl_el2 + stp x11, x12, [x0, #CTX_CNTHPS_TVAL_EL2] - mrs x9, spsr_el2 - str x9, [x0, #CTX_SPSR_EL2] + mrs x13, cnthvs_cval_el2 + mrs x14, cnthvs_tval_el2 + stp x13, x14, [x0, #CTX_CNTHVS_CVAL_EL2] - mrs x9, sp_el2 - str x9, [x0, #CTX_SP_EL2] + mrs x15, cnthv_ctl_el2 + mrs x16, cnthv_cval_el2 + stp x15, x16, [x0, #CTX_CNTHV_CTL_EL2] - mrs x9, tcr_el2 - str x9, [x0, #CTX_TCR_EL2] + mrs x17, cnthv_tval_el2 + mrs x9, contextidr_el2 + stp x17, x9, [x0, #CTX_CNTHV_TVAL_EL2] - mrs x9, tpidr_el2 - str x9, [x0, #CTX_TPIDR_EL2] + mrs x10, sder32_el2 + str x10, [x0, #CTX_SDER32_EL2] - mrs x9, ttbr0_el2 - str x9, [x0, #CTX_TTBR0_EL2] + mrs x11, ttbr1_el2 + str x11, [x0, #CTX_TTBR1_EL2] - mrs x9, vbar_el2 - str x9, [x0, #CTX_VBAR_EL2] + mrs x12, vdisr_el2 + str x12, [x0, #CTX_VDISR_EL2] - mrs x9, vmpidr_el2 - str x9, [x0, #CTX_VMPIDR_EL2] + mrs x13, vncr_el2 + str x13, [x0, #CTX_VNCR_EL2] - mrs x9, vpidr_el2 - str x9, [x0, #CTX_VPIDR_EL2] + mrs x14, vsesr_el2 + str x14, [x0, #CTX_VSESR_EL2] - mrs x9, vtcr_el2 - str x9, [x0, #CTX_VTCR_EL2] + mrs x15, vstcr_el2 + str x15, [x0, #CTX_VSTCR_EL2] - mrs x9, vttbr_el2 - str x9, [x0, #CTX_VTTBR_EL2] + mrs x16, vsttbr_el2 + str x16, [x0, #CTX_VSTTBR_EL2] +#endif - mrs x9, ZCR_EL2 - str x9, [x0, #CTX_ZCR_EL2] +#if ARM_ARCH_AT_LEAST(8, 5) + mrs x17, scxtnum_el2 + str x17, [x0, #CTX_SCXTNUM_EL2] +#endif ret endfunc el2_sysregs_context_save @@ -219,189 +217,186 @@ endfunc el2_sysregs_context_save /* ----------------------------------------------------- * The following function strictly follows the AArch64 * PCS to use x9-x17 (temporary caller-saved registers) - * to restore EL1 system register context. It assumes - * that 'x0' is pointing to a 'el1_sys_regs' structure + * to restore EL2 system register context. It assumes + * that 'x0' is pointing to a 'el2_sys_regs' structure * from where the register context will be restored + + * The following registers are not restored + * AMEVCNTVOFF0_EL2 + * AMEVCNTVOFF1_EL2 + * ICH_AP0R_EL2 + * ICH_AP1R_EL2 + * ICH_LR_EL2 * ----------------------------------------------------- */ func el2_sysregs_context_restore - ldr x9, [x0, #CTX_ACTLR_EL2] + ldp x9, x10, [x0, #CTX_ACTLR_EL2] msr actlr_el2, x9 + msr afsr0_el2, x10 - ldr x9, [x0, #CTX_AFSR0_EL2] - msr afsr0_el2, x9 - - ldr x9, [x0, #CTX_AFSR1_EL2] - msr afsr1_el2, x9 - - ldr x9, [x0, #CTX_AMAIR_EL2] - msr amair_el2, x9 - - ldr x9, [x0, #CTX_CNTHCTL_EL2] - msr cnthctl_el2, x9 + ldp x11, x12, [x0, #CTX_AFSR1_EL2] + msr afsr1_el2, x11 + msr amair_el2, x12 - ldr x9, [x0, #CTX_CNTHP_CTL_EL2] - msr cnthp_ctl_el2, x9 + ldp x13, x14, [x0, #CTX_CNTHCTL_EL2] + msr cnthctl_el2, x13 + msr cnthp_ctl_el2, x14 - ldr x9, [x0, #CTX_CNTHP_CVAL_EL2] - msr cnthp_cval_el2, x9 + ldp x15, x16, [x0, #CTX_CNTHP_CVAL_EL2] + msr cnthp_cval_el2, x15 + msr cnthp_tval_el2, x16 - ldr x9, [x0, #CTX_CNTHP_TVAL_EL2] - msr cnthp_tval_el2, x9 - - ldr x9, [x0, #CTX_CNTPOFF_EL2] - msr CNTPOFF_EL2, x9 - - ldr x9, [x0, #CTX_CNTVOFF_EL2] - msr cntvoff_el2, x9 - - ldr x9, [x0, #CTX_CPTR_EL2] + ldp x17, x9, [x0, #CTX_CNTVOFF_EL2] + msr cntvoff_el2, x17 msr cptr_el2, x9 - ldr x9, [x0, #CTX_DBGVCR32_EL2] - msr dbgvcr32_el2, x9 - - ldr x9, [x0, #CTX_ELR_EL2] - msr elr_el2, x9 + ldp x10, x11, [x0, #CTX_DBGVCR32_EL2] + msr dbgvcr32_el2, x10 + msr elr_el2, x11 - ldr x9, [x0, #CTX_ESR_EL2] - msr esr_el2, x9 + ldp x14, x15, [x0, #CTX_ESR_EL2] + msr esr_el2, x14 + msr far_el2, x15 - ldr x9, [x0, #CTX_FAR_EL2] - msr far_el2, x9 + ldp x16, x17, [x0, #CTX_FPEXC32_EL2] + msr fpexc32_el2, x16 + msr hacr_el2, x17 - ldr x9, [x0, #CTX_FPEXC32_EL2] - msr fpexc32_el2, x9 - - ldr x9, [x0, #CTX_HACR_EL2] - msr hacr_el2, x9 - - ldr x9, [x0, #CTX_HAFGRTR_EL2] - msr HAFGRTR_EL2, x9 - - ldr x9, [x0, #CTX_HCR_EL2] + ldp x9, x10, [x0, #CTX_HCR_EL2] msr hcr_el2, x9 + msr hpfar_el2, x10 - ldr x9, [x0, #CTX_HDFGRTR_EL2] - msr HDFGRTR_EL2, x9 - - ldr x9, [x0, #CTX_HDFGWTR_EL2] - msr HDFGWTR_EL2, x9 - - ldr x9, [x0, #CTX_HFGITR_EL2] - msr HFGITR_EL2, x9 - - ldr x9, [x0, #CTX_HFGRTR_EL2] - msr HFGRTR_EL2, x9 - - ldr x9, [x0, #CTX_HFGWTR_EL2] - msr HFGWTR_EL2, x9 + ldp x11, x12, [x0, #CTX_HSTR_EL2] + msr hstr_el2, x11 + msr ICC_SRE_EL2, x12 - ldr x9, [x0, #CTX_HPFAR_EL2] - msr hpfar_el2, x9 + ldp x13, x14, [x0, #CTX_ICH_HCR_EL2] + msr ICH_HCR_EL2, x13 + msr ICH_VMCR_EL2, x14 - ldr x9, [x0, #CTX_HSTR_EL2] - msr hstr_el2, x9 + ldp x15, x16, [x0, #CTX_MAIR_EL2] + msr mair_el2, x15 + msr mdcr_el2, x16 - ldr x9, [x0, #CTX_ICC_SRE_EL2] - msr ICC_SRE_EL2, x9 - - ldr x9, [x0, #CTX_ICH_EISR_EL2] - msr ICH_EISR_EL2, x9 - - ldr x9, [x0, #CTX_ICH_ELRSR_EL2] - msr ICH_ELRSR_EL2, x9 + ldp x17, x9, [x0, #CTX_PMSCR_EL2] + msr PMSCR_EL2, x17 + msr sctlr_el2, x9 - ldr x9, [x0, #CTX_ICH_HCR_EL2] - msr ICH_HCR_EL2, x9 + ldp x10, x11, [x0, #CTX_SPSR_EL2] + msr spsr_el2, x10 + msr sp_el2, x11 - ldr x9, [x0, #CTX_ICH_MISR_EL2] - msr ICH_MISR_EL2, x9 + ldp x12, x13, [x0, #CTX_TCR_EL2] + msr tcr_el2, x12 + msr TRFCR_EL2, x13 - ldr x9, [x0, #CTX_ICH_VMCR_EL2] - msr ICH_VMCR_EL2, x9 + ldp x14, x15, [x0, #CTX_TTBR0_EL2] + msr ttbr0_el2, x14 + msr vbar_el2, x15 - ldr x9, [x0, #CTX_ICH_VTR_EL2] - msr ICH_VTR_EL2, x9 + ldp x16, x17, [x0, #CTX_VMPIDR_EL2] + msr vmpidr_el2, x16 + msr vpidr_el2, x17 - ldr x9, [x0, #CTX_MAIR_EL2] - msr mair_el2, x9 + ldp x9, x10, [x0, #CTX_VTCR_EL2] + msr vtcr_el2, x9 + msr vttbr_el2, x10 - ldr x9, [x0, #CTX_MDCR_EL2] - msr mdcr_el2, x9 +#if CTX_INCLUDE_MTE_REGS + ldr x11, [x0, #CTX_TFSR_EL2] + msr TFSR_EL2, x11 +#endif - ldr x9, [x0, #CTX_MPAM2_EL2] +#if ENABLE_MPAM_FOR_LOWER_ELS + ldp x9, x10, [x0, #CTX_MPAM2_EL2] msr MPAM2_EL2, x9 + msr MPAMHCR_EL2, x10 - ldr x9, [x0, #CTX_MPAMHCR_EL2] - msr MPAMHCR_EL2, x9 + ldp x11, x12, [x0, #CTX_MPAMVPM0_EL2] + msr MPAMVPM0_EL2, x11 + msr MPAMVPM1_EL2, x12 - ldr x9, [x0, #CTX_MPAMVPM0_EL2] - msr MPAMVPM0_EL2, x9 + ldp x13, x14, [x0, #CTX_MPAMVPM2_EL2] + msr MPAMVPM2_EL2, x13 + msr MPAMVPM3_EL2, x14 - ldr x9, [x0, #CTX_MPAMVPM1_EL2] - msr MPAMVPM1_EL2, x9 + ldp x15, x16, [x0, #CTX_MPAMVPM4_EL2] + msr MPAMVPM4_EL2, x15 + msr MPAMVPM5_EL2, x16 - ldr x9, [x0, #CTX_MPAMVPM2_EL2] - msr MPAMVPM2_EL2, x9 - - ldr x9, [x0, #CTX_MPAMVPM3_EL2] - msr MPAMVPM3_EL2, x9 + ldp x17, x9, [x0, #CTX_MPAMVPM6_EL2] + msr MPAMVPM6_EL2, x17 + msr MPAMVPM7_EL2, x9 - ldr x9, [x0, #CTX_MPAMVPM4_EL2] - msr MPAMVPM4_EL2, x9 + ldr x10, [x0, #CTX_MPAMVPMV_EL2] + msr MPAMVPMV_EL2, x10 +#endif - ldr x9, [x0, #CTX_MPAMVPM5_EL2] - msr MPAMVPM5_EL2, x9 +#if ARM_ARCH_AT_LEAST(8, 6) + ldp x11, x12, [x0, #CTX_HAFGRTR_EL2] + msr HAFGRTR_EL2, x11 + msr HDFGRTR_EL2, x12 - ldr x9, [x0, #CTX_MPAMVPM6_EL2] - msr MPAMVPM6_EL2, x9 + ldp x13, x14, [x0, #CTX_HDFGWTR_EL2] + msr HDFGWTR_EL2, x13 + msr HFGITR_EL2, x14 - ldr x9, [x0, #CTX_MPAMVPM7_EL2] - msr MPAMVPM7_EL2, x9 + ldp x15, x16, [x0, #CTX_HFGRTR_EL2] + msr HFGRTR_EL2, x15 + msr HFGWTR_EL2, x16 - ldr x9, [x0, #CTX_MPAMVPMV_EL2] - msr MPAMVPMV_EL2, x9 + ldr x17, [x0, #CTX_CNTPOFF_EL2] + msr CNTPOFF_EL2, x17 +#endif - ldr x9, [x0, #CTX_RMR_EL2] - msr rmr_el2, x9 +#if ARM_ARCH_AT_LEAST(8, 4) + ldp x9, x10, [x0, #CTX_CNTHPS_CTL_EL2] + msr cnthps_ctl_el2, x9 + msr cnthps_cval_el2, x10 - ldr x9, [x0, #CTX_SCTLR_EL2] - msr sctlr_el2, x9 + ldp x11, x12, [x0, #CTX_CNTHPS_TVAL_EL2] + msr cnthps_tval_el2, x11 + msr cnthvs_ctl_el2, x12 - ldr x9, [x0, #CTX_SPSR_EL2] - msr spsr_el2, x9 + ldp x13, x14, [x0, #CTX_CNTHVS_CVAL_EL2] + msr cnthvs_cval_el2, x13 + msr cnthvs_tval_el2, x14 - ldr x9, [x0, #CTX_SP_EL2] - msr sp_el2, x9 + ldp x15, x16, [x0, #CTX_CNTHV_CTL_EL2] + msr cnthv_ctl_el2, x15 + msr cnthv_cval_el2, x16 - ldr x9, [x0, #CTX_TCR_EL2] - msr tcr_el2, x9 + ldp x17, x9, [x0, #CTX_CNTHV_TVAL_EL2] + msr cnthv_tval_el2, x17 + msr contextidr_el2, x9 - ldr x9, [x0, #CTX_TPIDR_EL2] - msr tpidr_el2, x9 + ldr x10, [x0, #CTX_SDER32_EL2] + msr sder32_el2, x10 - ldr x9, [x0, #CTX_TTBR0_EL2] - msr ttbr0_el2, x9 + ldr x11, [x0, #CTX_TTBR1_EL2] + msr ttbr1_el2, x11 - ldr x9, [x0, #CTX_VBAR_EL2] - msr vbar_el2, x9 + ldr x12, [x0, #CTX_VDISR_EL2] + msr vdisr_el2, x12 - ldr x9, [x0, #CTX_VMPIDR_EL2] - msr vmpidr_el2, x9 + ldr x13, [x0, #CTX_VNCR_EL2] + msr vncr_el2, x13 - ldr x9, [x0, #CTX_VPIDR_EL2] - msr vpidr_el2, x9 + ldr x14, [x0, #CTX_VSESR_EL2] + msr vsesr_el2, x14 - ldr x9, [x0, #CTX_VTCR_EL2] - msr vtcr_el2, x9 + ldr x15, [x0, #CTX_VSTCR_EL2] + msr vstcr_el2, x15 - ldr x9, [x0, #CTX_VTTBR_EL2] - msr vttbr_el2, x9 + ldr x16, [x0, #CTX_VSTTBR_EL2] + msr vsttbr_el2, x16 +#endif - ldr x9, [x0, #CTX_ZCR_EL2] - msr ZCR_EL2, x9 +#if ARM_ARCH_AT_LEAST(8, 5) + ldr x17, [x0, #CTX_SCXTNUM_EL2] + msr scxtnum_el2, x17 +#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 f59bcfcd9..0314a8511 100644 --- a/lib/el3_runtime/aarch64/context_mgmt.c +++ b/lib/el3_runtime/aarch64/context_mgmt.c @@ -234,7 +234,7 @@ void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep) * and other EL2 registers are set up by cm_prepare_ns_entry() as they * are not part of the stored cpu_context. */ - write_ctx_reg(get_sysregs_ctx(ctx), CTX_SCTLR_EL1, sctlr_elx); + write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_SCTLR_EL1, sctlr_elx); /* * Base the context ACTLR_EL1 on the current value, as it is @@ -244,7 +244,7 @@ void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep) * be zero. */ actlr_elx = read_actlr_el1(); - write_ctx_reg((get_sysregs_ctx(ctx)), (CTX_ACTLR_EL1), (actlr_elx)); + write_ctx_reg((get_el1_sysregs_ctx(ctx)), (CTX_ACTLR_EL1), (actlr_elx)); /* * Populate EL3 state so that we've the right context @@ -336,7 +336,7 @@ void cm_prepare_el3_exit(uint32_t security_state) CTX_SCR_EL3); if ((scr_el3 & SCR_HCE_BIT) != 0U) { /* Use SCTLR_EL1.EE value to initialise sctlr_el2 */ - sctlr_elx = read_ctx_reg(get_sysregs_ctx(ctx), + sctlr_elx = read_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_SCTLR_EL1); sctlr_elx &= SCTLR_EE_BIT; sctlr_elx |= SCTLR_EL2_RES1; @@ -549,7 +549,7 @@ void cm_el2_sysregs_context_save(uint32_t security_state) ctx = cm_get_context(security_state); assert(ctx != NULL); - el2_sysregs_context_save(get_sysregs_ctx(ctx)); + el2_sysregs_context_save(get_el2_sysregs_ctx(ctx)); } } @@ -571,7 +571,7 @@ void cm_el2_sysregs_context_restore(uint32_t security_state) ctx = cm_get_context(security_state); assert(ctx != NULL); - el2_sysregs_context_restore(get_sysregs_ctx(ctx)); + el2_sysregs_context_restore(get_el2_sysregs_ctx(ctx)); } } #endif /* CTX_INCLUDE_EL2_REGS */ @@ -588,7 +588,7 @@ void cm_el1_sysregs_context_save(uint32_t security_state) ctx = cm_get_context(security_state); assert(ctx != NULL); - el1_sysregs_context_save(get_sysregs_ctx(ctx)); + el1_sysregs_context_save(get_el1_sysregs_ctx(ctx)); #if IMAGE_BL31 if (security_state == SECURE) @@ -605,7 +605,7 @@ void cm_el1_sysregs_context_restore(uint32_t security_state) ctx = cm_get_context(security_state); assert(ctx != NULL); - el1_sysregs_context_restore(get_sysregs_ctx(ctx)); + el1_sysregs_context_restore(get_el1_sysregs_ctx(ctx)); #if IMAGE_BL31 if (security_state == SECURE) diff --git a/services/spd/trusty/trusty.c b/services/spd/trusty/trusty.c index 092ffa8eb..ba2f4a6e4 100644 --- a/services/spd/trusty/trusty.c +++ b/services/spd/trusty/trusty.c @@ -150,9 +150,9 @@ static uint64_t trusty_fiq_handler(uint32_t id, (void)memcpy(&ctx->fiq_gpregs, get_gpregs_ctx(handle), sizeof(ctx->fiq_gpregs)); ctx->fiq_pc = SMC_GET_EL3(handle, CTX_ELR_EL3); ctx->fiq_cpsr = SMC_GET_EL3(handle, CTX_SPSR_EL3); - ctx->fiq_sp_el1 = read_ctx_reg(get_sysregs_ctx(handle), CTX_SP_EL1); + ctx->fiq_sp_el1 = read_ctx_reg(get_el1_sysregs_ctx(handle), CTX_SP_EL1); - write_ctx_reg(get_sysregs_ctx(handle), CTX_SP_EL1, ctx->fiq_handler_sp); + write_ctx_reg(get_el1_sysregs_ctx(handle), CTX_SP_EL1, ctx->fiq_handler_sp); cm_set_elr_spsr_el3(NON_SECURE, ctx->fiq_handler_pc, (uint32_t)ctx->fiq_handler_cpsr); SMC_RET0(handle); @@ -211,7 +211,7 @@ static uint64_t trusty_fiq_exit(void *handle, uint64_t x1, uint64_t x2, uint64_t */ (void)memcpy(get_gpregs_ctx(handle), &ctx->fiq_gpregs, sizeof(ctx->fiq_gpregs)); ctx->fiq_handler_active = 0; - write_ctx_reg(get_sysregs_ctx(handle), CTX_SP_EL1, ctx->fiq_sp_el1); + write_ctx_reg(get_el1_sysregs_ctx(handle), CTX_SP_EL1, ctx->fiq_sp_el1); cm_set_elr_spsr_el3(NON_SECURE, ctx->fiq_pc, (uint32_t)ctx->fiq_cpsr); SMC_RET0(handle); diff --git a/services/std_svc/spm_mm/spm_mm_setup.c b/services/std_svc/spm_mm/spm_mm_setup.c index ccb2f9058..468e5b3af 100644 --- a/services/std_svc/spm_mm/spm_mm_setup.c +++ b/services/std_svc/spm_mm/spm_mm_setup.c @@ -116,17 +116,17 @@ void spm_sp_setup(sp_context_t *sp_ctx) xlat_ctx->pa_max_address, xlat_ctx->va_max_address, EL1_EL0_REGIME); - write_ctx_reg(get_sysregs_ctx(ctx), CTX_MAIR_EL1, + write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_MAIR_EL1, mmu_cfg_params[MMU_CFG_MAIR]); - write_ctx_reg(get_sysregs_ctx(ctx), CTX_TCR_EL1, + write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_TCR_EL1, mmu_cfg_params[MMU_CFG_TCR]); - write_ctx_reg(get_sysregs_ctx(ctx), CTX_TTBR0_EL1, + write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_TTBR0_EL1, mmu_cfg_params[MMU_CFG_TTBR0]); /* Setup SCTLR_EL1 */ - u_register_t sctlr_el1 = read_ctx_reg(get_sysregs_ctx(ctx), CTX_SCTLR_EL1); + u_register_t sctlr_el1 = read_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_SCTLR_EL1); sctlr_el1 |= /*SCTLR_EL1_RES1 |*/ @@ -160,7 +160,7 @@ void spm_sp_setup(sp_context_t *sp_ctx) SCTLR_UMA_BIT ); - write_ctx_reg(get_sysregs_ctx(ctx), CTX_SCTLR_EL1, sctlr_el1); + write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_SCTLR_EL1, sctlr_el1); /* * Setup other system registers @@ -168,10 +168,10 @@ void spm_sp_setup(sp_context_t *sp_ctx) */ /* Shim Exception Vector Base Address */ - write_ctx_reg(get_sysregs_ctx(ctx), CTX_VBAR_EL1, + write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_VBAR_EL1, SPM_SHIM_EXCEPTIONS_PTR); - write_ctx_reg(get_sysregs_ctx(ctx), CTX_CNTKCTL_EL1, + write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_CNTKCTL_EL1, EL0PTEN_BIT | EL0VTEN_BIT | EL0PCTEN_BIT | EL0VCTEN_BIT); /* @@ -181,7 +181,7 @@ void spm_sp_setup(sp_context_t *sp_ctx) * TTA: Enable access to trace registers. * ZEN (v8.2): Trap SVE instructions and access to SVE registers. */ - write_ctx_reg(get_sysregs_ctx(ctx), CTX_CPACR_EL1, + write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_CPACR_EL1, CPACR_EL1_FPEN(CPACR_EL1_FP_TRAP_NONE)); /* -- cgit v1.2.3 From e0f924a52925c8e2baf20d3c04b29234d948ea51 Mon Sep 17 00:00:00 2001 From: Max Shvetsov Date: Fri, 24 Jan 2020 13:48:53 +0000 Subject: SPMD: [tegra] rename el1_sys_regs structure to sys_regs Renamed the structure according to a SPMD refactoring introduced in since this structure is used to service both EL1 and EL2 as opposed to serving only EL1. Change-Id: I23b7c089e53f617157a4b4e6443acce50d85c3b5 Signed-off-by: Max Shvetsov --- plat/nvidia/tegra/common/tegra_fiq_glue.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plat/nvidia/tegra/common/tegra_fiq_glue.c b/plat/nvidia/tegra/common/tegra_fiq_glue.c index 60b559556..8e198ae76 100644 --- a/plat/nvidia/tegra/common/tegra_fiq_glue.c +++ b/plat/nvidia/tegra/common/tegra_fiq_glue.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -155,7 +155,7 @@ int32_t tegra_fiq_get_intr_context(void) { cpu_context_t *ctx = cm_get_context(NON_SECURE); gp_regs_t *gpregs_ctx = get_gpregs_ctx(ctx); - const el1_sys_regs_t *el1state_ctx = get_sysregs_ctx(ctx); + const el1_sysregs_t *el1state_ctx = get_el1_sysregs_ctx(ctx); uint32_t cpu = plat_my_core_pos(); uint64_t val; -- cgit v1.2.3 From 0f14d02f8fdc23aae7da452cbb18a92eba1feda2 Mon Sep 17 00:00:00 2001 From: Max Shvetsov Date: Thu, 27 Feb 2020 14:54:21 +0000 Subject: SPMD: SPMC init, SMC handler cosmetic changes Change-Id: I8881d489994aea667e3dd59932ab4123f511d6ba Signed-off-by: Artsem Artsemenka Signed-off-by: Max Shvetsov --- include/services/spmd_svc.h | 2 +- services/std_svc/spmd/spmd_main.c | 300 ++++++++++++++++++++------------------ 2 files changed, 162 insertions(+), 140 deletions(-) diff --git a/include/services/spmd_svc.h b/include/services/spmd_svc.h index 6e4caf266..a766dcf8f 100644 --- a/include/services/spmd_svc.h +++ b/include/services/spmd_svc.h @@ -11,7 +11,7 @@ #include #include -int32_t spmd_setup(void); +int spmd_setup(void); uint64_t spmd_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c index 110719020..50c32fc83 100644 --- a/services/std_svc/spmd/spmd_main.c +++ b/services/std_svc/spmd/spmd_main.c @@ -33,7 +33,24 @@ spmd_spm_core_context_t spm_core_context[PLATFORM_CORE_COUNT]; /******************************************************************************* * SPM Core attribute information read from its manifest. ******************************************************************************/ -spmc_manifest_sect_attribute_t spmc_attrs; +static spmc_manifest_sect_attribute_t spmc_attrs; + +/******************************************************************************* + * SPM Core entry point information. Discovered on the primary core and reused + * on secondary cores. + ******************************************************************************/ +static entry_point_info_t *spmc_ep_info; + +/******************************************************************************* + * Static function declaration. + ******************************************************************************/ +static int32_t spmd_init(void); +static int spmd_spmc_init(void *rd_base, size_t rd_size); +static uint64_t spmd_spci_error_return(void *handle, int error_code); +static uint64_t spmd_smc_forward(uint32_t smc_fid, uint32_t in_sstate, + uint32_t out_sstate, uint64_t x1, + uint64_t x2, uint64_t x3, uint64_t x4, + void *handle); /******************************************************************************* * This function takes an SP context pointer and performs a synchronous entry @@ -111,63 +128,21 @@ static int32_t spmd_init(void) } /******************************************************************************* - * Initialize context of SPM core. + * Load SPMC manifest, init SPMC. ******************************************************************************/ -int32_t spmd_setup(void) +static int spmd_spmc_init(void *rd_base, size_t rd_size) { int rc; - void *rd_base; - size_t rd_size; - entry_point_info_t *spmc_ep_info; - uintptr_t rd_base_align; - uintptr_t rd_size_align; uint32_t ep_attr; - - spmc_ep_info = bl31_plat_get_next_image_ep_info(SECURE); - if (!spmc_ep_info) { - WARN("No SPM core image provided by BL2 boot loader, Booting " - "device without SP initialization. SMC`s destined for SPM " - "core will return SMC_UNK\n"); - return 1; - } - - /* Under no circumstances will this parameter be 0 */ - assert(spmc_ep_info->pc != 0U); - - /* - * Check if BL32 ep_info has a reference to 'tos_fw_config'. This will - * be used as a manifest for the SPM core at the next lower EL/mode. - */ - if (spmc_ep_info->args.arg0 == 0U || spmc_ep_info->args.arg2 == 0U) { - ERROR("Invalid or absent SPM core manifest\n"); - panic(); - } - - /* Obtain whereabouts of SPM core manifest */ - rd_base = (void *) spmc_ep_info->args.arg0; - rd_size = spmc_ep_info->args.arg2; - - rd_base_align = page_align((uintptr_t) rd_base, DOWN); - rd_size_align = page_align((uintptr_t) rd_size, UP); - - /* Map the manifest in the SPMD translation regime first */ - VERBOSE("SPM core manifest base : 0x%lx\n", rd_base_align); - VERBOSE("SPM core manifest size : 0x%lx\n", rd_size_align); - rc = mmap_add_dynamic_region((unsigned long long) rd_base_align, - (uintptr_t) rd_base_align, - rd_size_align, - MT_RO_DATA); - if (rc < 0) { - ERROR("Error while mapping SPM core manifest (%d).\n", rc); - panic(); - } + unsigned int linear_id = plat_my_core_pos(); + spmd_spm_core_context_t *spm_ctx = &spm_core_context[linear_id]; /* Load the SPM core manifest */ rc = plat_spm_core_manifest_load(&spmc_attrs, rd_base, rd_size); - if (rc < 0) { + if (rc != 0) { WARN("No or invalid SPM core manifest image provided by BL2 " "boot loader. "); - goto error; + return 1; } /* @@ -179,7 +154,7 @@ int32_t spmd_setup(void) WARN("Unsupported SPCI version (%x.%x) specified in SPM core " "manifest image provided by BL2 boot loader.\n", spmc_attrs.major_version, spmc_attrs.minor_version); - goto error; + return 1; } INFO("SPCI version (%x.%x).\n", spmc_attrs.major_version, @@ -191,7 +166,7 @@ int32_t spmd_setup(void) WARN("Unsupported SPM core run time EL%x specified in " "manifest image provided by BL2 boot loader.\n", spmc_attrs.runtime_el); - goto error; + return 1; } INFO("SPM core run time EL%x.\n", spmc_attrs.runtime_el); @@ -202,7 +177,7 @@ int32_t spmd_setup(void) WARN("Unsupported SPM core execution state %x specified in " "manifest image provided by BL2 boot loader.\n", spmc_attrs.exec_state); - goto error; + return 1; } INFO("SPM core execution state %x.\n", spmc_attrs.exec_state); @@ -213,7 +188,7 @@ int32_t spmd_setup(void) WARN("Invalid combination of SPM core execution state (%x) " "and run time EL (%x).\n", spmc_attrs.exec_state, spmc_attrs.runtime_el); - goto error; + return 1; } /* @@ -230,14 +205,16 @@ int32_t spmd_setup(void) WARN("SPM core run time EL: S-EL%x is not supported " "but specified in manifest image provided by " "BL2 boot loader.\n", spmc_attrs.runtime_el); - goto error; + return 1; } } /* Initialise an entrypoint to set up the CPU context */ ep_attr = SECURE | EP_ST_ENABLE; - if (read_sctlr_el3() & SCTLR_EE_BIT) + if (read_sctlr_el3() & SCTLR_EE_BIT) { ep_attr |= EP_EE_BIG; + } + SET_PARAM_HEAD(spmc_ep_info, PARAM_EP, VERSION_1, ep_attr); assert(spmc_ep_info->pc == BL32_BASE); @@ -258,8 +235,10 @@ int32_t spmd_setup(void) } /* Initialise SPM core context with this entry point information */ - cm_setup_context(&(spm_core_context[plat_my_core_pos()].cpu_ctx), - spmc_ep_info); + cm_setup_context(&spm_ctx->cpu_ctx, spmc_ep_info); + + /* Reuse PSCI affinity states to mark this SPMC context as off */ + spm_ctx->state = AFF_STATE_OFF; INFO("SPM core setup done.\n"); @@ -267,20 +246,113 @@ int32_t spmd_setup(void) bl31_register_bl32_init(&spmd_init); return 0; +} -error: - WARN("Booting device without SPM initialization. " - "SPCI SMCs destined for SPM core will return " - "ENOTSUPPORTED\n"); +/******************************************************************************* + * Initialize context of SPM core. + ******************************************************************************/ +int spmd_setup(void) +{ + int rc; + void *rd_base; + size_t rd_size; + uintptr_t rd_base_align; + uintptr_t rd_size_align; - rc = mmap_remove_dynamic_region(rd_base_align, rd_size_align); - if (rc < 0) { - ERROR("Error while unmapping SPM core manifest (%d).\n", - rc); + spmc_ep_info = bl31_plat_get_next_image_ep_info(SECURE); + if (!spmc_ep_info) { + WARN("No SPM core image provided by BL2 boot loader, Booting " + "device without SP initialization. SMC`s destined for SPM " + "core will return SMC_UNK\n"); + return 1; + } + + /* Under no circumstances will this parameter be 0 */ + assert(spmc_ep_info->pc != 0U); + + /* + * Check if BL32 ep_info has a reference to 'tos_fw_config'. This will + * be used as a manifest for the SPM core at the next lower EL/mode. + */ + if (spmc_ep_info->args.arg0 == 0U || spmc_ep_info->args.arg2 == 0U) { + ERROR("Invalid or absent SPM core manifest\n"); panic(); } - return 1; + /* Obtain whereabouts of SPM core manifest */ + rd_base = (void *) spmc_ep_info->args.arg0; + rd_size = spmc_ep_info->args.arg2; + + rd_base_align = page_align((uintptr_t) rd_base, DOWN); + rd_size_align = page_align((uintptr_t) rd_size, UP); + + /* Map the manifest in the SPMD translation regime first */ + VERBOSE("SPM core manifest base : 0x%lx\n", rd_base_align); + VERBOSE("SPM core manifest size : 0x%lx\n", rd_size_align); + rc = mmap_add_dynamic_region((unsigned long long) rd_base_align, + (uintptr_t) rd_base_align, + rd_size_align, + MT_RO_DATA); + if (rc != 0) { + ERROR("Error while mapping SPM core manifest (%d).\n", rc); + panic(); + } + + /* Load manifest, init SPMC */ + rc = spmd_spmc_init(rd_base, rd_size); + if (rc != 0) { + int mmap_rc; + + WARN("Booting device without SPM initialization. " + "SPCI SMCs destined for SPM core will return " + "ENOTSUPPORTED\n"); + + mmap_rc = mmap_remove_dynamic_region(rd_base_align, + rd_size_align); + if (mmap_rc != 0) { + ERROR("Error while unmapping SPM core manifest (%d).\n", + mmap_rc); + panic(); + } + + return rc; + } + + return 0; +} + +/******************************************************************************* + * Forward SMC to the other security state + ******************************************************************************/ +static uint64_t spmd_smc_forward(uint32_t smc_fid, uint32_t in_sstate, + uint32_t out_sstate, uint64_t x1, + uint64_t x2, uint64_t x3, uint64_t x4, + void *handle) +{ + /* Save incoming security state */ + cm_el1_sysregs_context_save(in_sstate); + cm_el2_sysregs_context_save(in_sstate); + + /* Restore outgoing security state */ + cm_el1_sysregs_context_restore(out_sstate); + cm_el2_sysregs_context_restore(out_sstate); + cm_set_next_eret_context(out_sstate); + + SMC_RET8(cm_get_context(out_sstate), 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)); +} + +/******************************************************************************* + * Return SPCI_ERROR with specified error code + ******************************************************************************/ +static uint64_t spmd_spci_error_return(void *handle, int error_code) +{ + SMC_RET8(handle, SPCI_ERROR, + SPCI_TARGET_INFO_MBZ, error_code, + SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, + SPCI_PARAM_MBZ, SPCI_PARAM_MBZ); } /******************************************************************************* @@ -318,22 +390,13 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, * this CPU. If so, then indicate that the SPM core initialised * unsuccessfully. */ - if ((in_sstate == SECURE) && (ctx->state == SPMC_STATE_RESET)) + if ((in_sstate == SECURE) && + (ctx->state == SPMC_STATE_RESET)) { spmd_spm_core_sync_exit(x2); + } - /* Save incoming security state */ - cm_el1_sysregs_context_save(in_sstate); - cm_el2_sysregs_context_save(in_sstate); - - /* Restore outgoing security state */ - cm_el1_sysregs_context_restore(out_sstate); - cm_el2_sysregs_context_restore(out_sstate); - cm_set_next_eret_context(out_sstate); - - SMC_RET8(cm_get_context(out_sstate), 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)); + return spmd_smc_forward(smc_fid, in_sstate, out_sstate, + x1, x2, x3, x4, handle); break; /* not reached */ case SPCI_VERSION: @@ -357,31 +420,18 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, */ /* - * Check if w1 holds a valid SPCI fid. This is an + * Check if x1 holds a valid SPCI fid. This is an * optimization. */ - if (!is_spci_fid(x1)) - SMC_RET8(handle, SPCI_ERROR, - SPCI_TARGET_INFO_MBZ, SPCI_ERROR_NOT_SUPPORTED, - SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, - SPCI_PARAM_MBZ, SPCI_PARAM_MBZ); + if (!is_spci_fid(x1)) { + return spmd_spci_error_return(handle, + SPCI_ERROR_NOT_SUPPORTED); + } /* Forward SMC from Normal world to the SPM core */ if (in_sstate == NON_SECURE) { - /* Save incoming security state */ - cm_el1_sysregs_context_save(in_sstate); - cm_el2_sysregs_context_save(in_sstate); - - /* Restore outgoing security state */ - cm_el1_sysregs_context_restore(out_sstate); - cm_el2_sysregs_context_restore(out_sstate); - cm_set_next_eret_context(out_sstate); - - SMC_RET8(cm_get_context(out_sstate), 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)); + return spmd_smc_forward(smc_fid, in_sstate, out_sstate, + x1, x2, x3, x4, handle); } else { /* * Return success if call was from secure world i.e. all @@ -393,6 +443,7 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, SMC_GET_GP(handle, CTX_GPREG_X6), SMC_GET_GP(handle, CTX_GPREG_X7)); } + break; /* not reached */ case SPCI_RX_RELEASE: @@ -402,10 +453,8 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, case SPCI_MSG_RUN: /* This interface must be invoked only by the Normal world */ if (in_sstate == SECURE) { - SMC_RET8(handle, SPCI_ERROR, - SPCI_TARGET_INFO_MBZ, SPCI_ERROR_NOT_SUPPORTED, - SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, - SPCI_PARAM_MBZ, SPCI_PARAM_MBZ); + return spmd_spci_error_return(handle, + SPCI_ERROR_NOT_SUPPORTED); } /* Fall through to forward the call to the other world */ @@ -436,19 +485,8 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, * simply forward the call to the Normal world. */ - /* Save incoming security state */ - cm_el1_sysregs_context_save(in_sstate); - cm_el2_sysregs_context_save(in_sstate); - - /* Restore outgoing security state */ - cm_el1_sysregs_context_restore(out_sstate); - cm_el2_sysregs_context_restore(out_sstate); - cm_set_next_eret_context(out_sstate); - - SMC_RET8(cm_get_context(out_sstate), 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)); + return spmd_smc_forward(smc_fid, in_sstate, out_sstate, + x1, x2, x3, x4, handle); break; /* not reached */ case SPCI_MSG_WAIT: @@ -461,37 +499,21 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, spmd_spm_core_sync_exit(0); } - /* Intentional fall-through */ + /* Fall through to forward the call to the other world */ case SPCI_MSG_YIELD: /* This interface must be invoked only by the Secure world */ if (in_sstate == NON_SECURE) { - SMC_RET8(handle, SPCI_ERROR, - SPCI_TARGET_INFO_MBZ, SPCI_ERROR_NOT_SUPPORTED, - SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, - SPCI_PARAM_MBZ, SPCI_PARAM_MBZ); + return spmd_spci_error_return(handle, + SPCI_ERROR_NOT_SUPPORTED); } - /* Save incoming security state */ - cm_el1_sysregs_context_save(in_sstate); - cm_el2_sysregs_context_save(in_sstate); - - /* Restore outgoing security state */ - cm_el1_sysregs_context_restore(out_sstate); - cm_el2_sysregs_context_restore(out_sstate); - cm_set_next_eret_context(out_sstate); - - SMC_RET8(cm_get_context(out_sstate), 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)); + return spmd_smc_forward(smc_fid, in_sstate, out_sstate, + x1, x2, x3, x4, handle); break; /* not reached */ default: WARN("SPM: Unsupported call 0x%08x\n", smc_fid); - SMC_RET8(handle, SPCI_ERROR, - SPCI_TARGET_INFO_MBZ, SPCI_ERROR_NOT_SUPPORTED, - SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, - SPCI_PARAM_MBZ, SPCI_PARAM_MBZ); + return spmd_spci_error_return(handle, SPCI_ERROR_NOT_SUPPORTED); } } -- cgit v1.2.3 From 93ff138b59d493fe93ba7fee99e9f1d0f1acb361 Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Mon, 23 Dec 2019 16:21:12 +0100 Subject: SPMD: smc handler qualify secure origin using booleans Change-Id: Icc8f73660453a2cbb2241583684b615d5d1af9d4 Signed-off-by: Olivier Deprez --- services/std_svc/spmd/spmd_main.c | 61 +++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 34 deletions(-) diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c index 50c32fc83..f49d23610 100644 --- a/services/std_svc/spmd/spmd_main.c +++ b/services/std_svc/spmd/spmd_main.c @@ -47,10 +47,9 @@ static entry_point_info_t *spmc_ep_info; static int32_t spmd_init(void); static int spmd_spmc_init(void *rd_base, size_t rd_size); static uint64_t spmd_spci_error_return(void *handle, int error_code); -static uint64_t spmd_smc_forward(uint32_t smc_fid, uint32_t in_sstate, - uint32_t out_sstate, uint64_t x1, - uint64_t x2, uint64_t x3, uint64_t x4, - void *handle); +static uint64_t spmd_smc_forward(uint32_t smc_fid, bool secure_origin, + uint64_t x1, uint64_t x2, uint64_t x3, + uint64_t x4, void *handle); /******************************************************************************* * This function takes an SP context pointer and performs a synchronous entry @@ -324,21 +323,23 @@ int spmd_setup(void) /******************************************************************************* * Forward SMC to the other security state ******************************************************************************/ -static uint64_t spmd_smc_forward(uint32_t smc_fid, uint32_t in_sstate, - uint32_t out_sstate, uint64_t x1, - uint64_t x2, uint64_t x3, uint64_t x4, - void *handle) +static uint64_t spmd_smc_forward(uint32_t smc_fid, bool secure_origin, + uint64_t x1, uint64_t x2, uint64_t x3, + uint64_t x4, void *handle) { + uint32_t secure_state_in = (secure_origin) ? SECURE : NON_SECURE; + uint32_t secure_state_out = (!secure_origin) ? SECURE : NON_SECURE; + /* Save incoming security state */ - cm_el1_sysregs_context_save(in_sstate); - cm_el2_sysregs_context_save(in_sstate); + cm_el1_sysregs_context_save(secure_state_in); + cm_el2_sysregs_context_save(secure_state_in); /* Restore outgoing security state */ - cm_el1_sysregs_context_restore(out_sstate); - cm_el2_sysregs_context_restore(out_sstate); - cm_set_next_eret_context(out_sstate); + cm_el1_sysregs_context_restore(secure_state_out); + cm_el2_sysregs_context_restore(secure_state_out); + cm_set_next_eret_context(secure_state_out); - SMC_RET8(cm_get_context(out_sstate), smc_fid, x1, x2, x3, x4, + SMC_RET8(cm_get_context(secure_state_out), 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)); @@ -363,19 +364,12 @@ uint64_t spmd_smc_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 in_sstate; - uint32_t out_sstate; - int32_t ret; spmd_spm_core_context_t *ctx = &spm_core_context[plat_my_core_pos()]; + bool secure_origin; + int32_t ret; /* Determine which security state this SMC originated from */ - if (is_caller_secure(flags)) { - in_sstate = SECURE; - out_sstate = NON_SECURE; - } else { - in_sstate = NON_SECURE; - out_sstate = SECURE; - } + secure_origin = is_caller_secure(flags); INFO("SPM: 0x%x, 0x%llx, 0x%llx, 0x%llx, 0x%llx, " "0x%llx, 0x%llx, 0x%llx\n", @@ -390,12 +384,11 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, * this CPU. If so, then indicate that the SPM core initialised * unsuccessfully. */ - if ((in_sstate == SECURE) && - (ctx->state == SPMC_STATE_RESET)) { + if (secure_origin && (ctx->state == SPMC_STATE_RESET)) { spmd_spm_core_sync_exit(x2); } - return spmd_smc_forward(smc_fid, in_sstate, out_sstate, + return spmd_smc_forward(smc_fid, secure_origin, x1, x2, x3, x4, handle); break; /* not reached */ @@ -429,8 +422,8 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, } /* Forward SMC from Normal world to the SPM core */ - if (in_sstate == NON_SECURE) { - return spmd_smc_forward(smc_fid, in_sstate, out_sstate, + if (!secure_origin) { + return spmd_smc_forward(smc_fid, secure_origin, x1, x2, x3, x4, handle); } else { /* @@ -452,7 +445,7 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, case SPCI_RXTX_UNMAP: case SPCI_MSG_RUN: /* This interface must be invoked only by the Normal world */ - if (in_sstate == SECURE) { + if (secure_origin) { return spmd_spci_error_return(handle, SPCI_ERROR_NOT_SUPPORTED); } @@ -485,7 +478,7 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, * simply forward the call to the Normal world. */ - return spmd_smc_forward(smc_fid, in_sstate, out_sstate, + return spmd_smc_forward(smc_fid, secure_origin, x1, x2, x3, x4, handle); break; /* not reached */ @@ -495,7 +488,7 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, * this CPU from the Secure world. If so, then indicate that the * SPM core initialised successfully. */ - if ((in_sstate == SECURE) && (ctx->state == SPMC_STATE_RESET)) { + if (secure_origin && (ctx->state == SPMC_STATE_RESET)) { spmd_spm_core_sync_exit(0); } @@ -503,12 +496,12 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, case SPCI_MSG_YIELD: /* This interface must be invoked only by the Secure world */ - if (in_sstate == NON_SECURE) { + if (!secure_origin) { return spmd_spci_error_return(handle, SPCI_ERROR_NOT_SUPPORTED); } - return spmd_smc_forward(smc_fid, in_sstate, out_sstate, + return spmd_smc_forward(smc_fid, secure_origin, x1, x2, x3, x4, handle); break; /* not reached */ -- cgit v1.2.3 From 033039f8e5ad0ff231261e316f27bf22bc5713a2 Mon Sep 17 00:00:00 2001 From: Max Shvetsov Date: Tue, 25 Feb 2020 13:55:00 +0000 Subject: SPMD: add command line parameter to run SPM at S-EL2 or S-EL1 Added SPMD_SPM_AT_SEL2 build command line parameter. Set to 1 to run SPM at S-EL2. Set to 0 to run SPM at S-EL1 (pre-v8.4 or S-EL2 is disabled). Removed runtime EL from SPM core manifest. Change-Id: Icb4f5ea4c800f266880db1d410d63fe27a1171c0 Signed-off-by: Artsem Artsemenka Signed-off-by: Max Shvetsov --- Makefile | 9 +++- include/services/spm_core_manifest.h | 7 --- make_helpers/defaults.mk | 3 ++ plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts | 1 - plat/common/plat_spmd_manifest.c | 7 --- services/std_svc/spmd/spmd_main.c | 61 +++++++++++++-------------- 6 files changed, 39 insertions(+), 49 deletions(-) diff --git a/Makefile b/Makefile index a84c413b8..f3cb9be6b 100644 --- a/Makefile +++ b/Makefile @@ -422,11 +422,14 @@ ifneq (${SPD},none) endif ifeq (${SPD},spmd) + $(warning "SPMD is an experimental feature") # SPMD is located in std_svc directory SPD_DIR := std_svc - ifeq ($(CTX_INCLUDE_EL2_REGS),0) - $(error spmd requires CTX_INCLUDE_EL2_REGS option) + ifeq ($(SPMD_SPM_AT_SEL2),1) + ifeq ($(CTX_INCLUDE_EL2_REGS),0) + $(error SPMD with SPM at S-EL2 requires CTX_INCLUDE_EL2_REGS option) + endif endif else # All other SPDs in spd directory @@ -799,6 +802,7 @@ $(eval $(call assert_boolean,SEPARATE_CODE_AND_RODATA)) $(eval $(call assert_boolean,SEPARATE_NOBITS_REGION)) $(eval $(call assert_boolean,SPIN_ON_BL1_EXIT)) $(eval $(call assert_boolean,SPM_MM)) +$(eval $(call assert_boolean,SPMD_SPM_AT_SEL2)) $(eval $(call assert_boolean,TRUSTED_BOARD_BOOT)) $(eval $(call assert_boolean,USE_COHERENT_MEM)) $(eval $(call assert_boolean,USE_DEBUGFS)) @@ -870,6 +874,7 @@ $(eval $(call add_define,RECLAIM_INIT_CODE)) $(eval $(call add_define,SPD_${SPD})) $(eval $(call add_define,SPIN_ON_BL1_EXIT)) $(eval $(call add_define,SPM_MM)) +$(eval $(call add_define,SPMD_SPM_AT_SEL2)) $(eval $(call add_define,TRUSTED_BOARD_BOOT)) $(eval $(call add_define,USE_COHERENT_MEM)) $(eval $(call add_define,USE_DEBUGFS)) diff --git a/include/services/spm_core_manifest.h b/include/services/spm_core_manifest.h index 06ecc1391..78748826d 100644 --- a/include/services/spm_core_manifest.h +++ b/include/services/spm_core_manifest.h @@ -20,13 +20,6 @@ typedef struct spm_core_manifest_sect_attribute { uint32_t major_version; uint32_t minor_version; - /* - * Run-Time Exception Level (mandatory): - * - 1: SEL1 - * - 2: SEL2 - */ - uint32_t runtime_el; - /* * Run-Time Execution state (optional): * - 0: AArch64 (default) diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index 8e1f273a3..9273469e2 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -188,6 +188,9 @@ SPD := none # Enable the Management Mode (MM)-based Secure Partition Manager implementation SPM_MM := 0 +# Use SPM at S-EL2 as a default config for SPMD +SPMD_SPM_AT_SEL2 := 1 + # Flag to introduce an infinite loop in BL1 just before it exits into the next # image. This is meant to help debugging the post-BL2 phase. SPIN_ON_BL1_EXIT := 0 diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts index e1c106f1e..c94a209fd 100644 --- a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts +++ b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts @@ -11,7 +11,6 @@ attribute { maj_ver = <0x0>; min_ver = <0x9>; - runtime_el = <0x1>; exec_state = <0x0>; load_address = <0x0 0x6000000>; entrypoint = <0x0 0x6000000>; diff --git a/plat/common/plat_spmd_manifest.c b/plat/common/plat_spmd_manifest.c index 4c789795e..9c3dc7177 100644 --- a/plat/common/plat_spmd_manifest.c +++ b/plat/common/plat_spmd_manifest.c @@ -37,12 +37,6 @@ static int manifest_parse_attribute(spmc_manifest_sect_attribute_t *attr, return -ENOENT; } - rc = fdtw_read_cells(fdt, node, "runtime_el", 1, &attr->runtime_el); - if (rc) { - ERROR("Missing SPM core runtime EL in manifest.\n"); - return -ENOENT; - } - rc = fdtw_read_cells(fdt, node, "exec_state", 1, &attr->exec_state); if (rc) NOTICE("Execution state not specified in SPM core manifest.\n"); @@ -61,7 +55,6 @@ static int manifest_parse_attribute(spmc_manifest_sect_attribute_t *attr, VERBOSE("SPM core manifest attribute section:\n"); VERBOSE(" version: %x.%x\n", attr->major_version, attr->minor_version); - VERBOSE(" runtime_el: 0x%x\n", attr->runtime_el); 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); diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c index f49d23610..2cdf4f5ff 100644 --- a/services/std_svc/spmd/spmd_main.c +++ b/services/std_svc/spmd/spmd_main.c @@ -65,19 +65,19 @@ uint64_t spmd_spm_core_sync_entry(spmd_spm_core_context_t *spmc_ctx) /* Restore the context assigned above */ cm_el1_sysregs_context_restore(SECURE); +#if SPMD_SPM_AT_SEL2 cm_el2_sysregs_context_restore(SECURE); +#endif cm_set_next_eret_context(SECURE); - /* Invalidate TLBs at EL1. */ - tlbivmalle1(); - dsbish(); - - /* Enter Secure Partition */ + /* Enter SPMC */ rc = spmd_spm_core_enter(&spmc_ctx->c_rt_ctx); /* Save secure state */ cm_el1_sysregs_context_save(SECURE); +#if SPMD_SPM_AT_SEL2 cm_el2_sysregs_context_save(SECURE); +#endif return rc; } @@ -159,16 +159,8 @@ static int spmd_spmc_init(void *rd_base, size_t rd_size) INFO("SPCI version (%x.%x).\n", spmc_attrs.major_version, spmc_attrs.minor_version); - /* Validate the SPM core runtime EL */ - if ((spmc_attrs.runtime_el != MODE_EL1) && - (spmc_attrs.runtime_el != MODE_EL2)) { - WARN("Unsupported SPM core run time EL%x specified in " - "manifest image provided by BL2 boot loader.\n", - spmc_attrs.runtime_el); - return 1; - } - - INFO("SPM core run time EL%x.\n", spmc_attrs.runtime_el); + INFO("SPM core run time EL%x.\n", + SPMD_SPM_AT_SEL2 ? MODE_EL2 : MODE_EL1); /* Validate the SPM core execution state */ if ((spmc_attrs.exec_state != MODE_RW_64) && @@ -181,12 +173,10 @@ static int spmd_spmc_init(void *rd_base, size_t rd_size) INFO("SPM core execution state %x.\n", spmc_attrs.exec_state); - /* Ensure manifest has not requested S-EL2 in AArch32 state */ - if ((spmc_attrs.exec_state == MODE_RW_32) && - (spmc_attrs.runtime_el == MODE_EL2)) { - WARN("Invalid combination of SPM core execution state (%x) " - "and run time EL (%x).\n", spmc_attrs.exec_state, - spmc_attrs.runtime_el); +#if SPMD_SPM_AT_SEL2 + /* Ensure manifest has not requested AArch32 state in S-EL2 */ + if (spmc_attrs.exec_state == MODE_RW_32) { + WARN("AArch32 state at S-EL2 is not supported.\n"); return 1; } @@ -194,19 +184,16 @@ static int spmd_spmc_init(void *rd_base, size_t rd_size) * Check if S-EL2 is supported on this system if S-EL2 * is required for SPM */ - if (spmc_attrs.runtime_el == MODE_EL2) { - uint64_t sel2 = read_id_aa64pfr0_el1(); + uint64_t sel2 = read_id_aa64pfr0_el1(); - sel2 >>= ID_AA64PFR0_SEL2_SHIFT; - sel2 &= ID_AA64PFR0_SEL2_MASK; + sel2 >>= ID_AA64PFR0_SEL2_SHIFT; + sel2 &= ID_AA64PFR0_SEL2_MASK; - if (!sel2) { - WARN("SPM core run time EL: S-EL%x is not supported " - "but specified in manifest image provided by " - "BL2 boot loader.\n", spmc_attrs.runtime_el); - return 1; - } + if (!sel2) { + WARN("SPM core run time S-EL2 is not supported."); + return 1; } +#endif /* SPMD_SPM_AT_SEL2 */ /* Initialise an entrypoint to set up the CPU context */ ep_attr = SECURE | EP_ST_ENABLE; @@ -228,7 +215,13 @@ static int spmd_spmc_init(void *rd_base, size_t rd_size) DAIF_IRQ_BIT | DAIF_ABT_BIT); } else { - spmc_ep_info->spsr = SPSR_64(spmc_attrs.runtime_el, + +#if SPMD_SPM_AT_SEL2 + static const uint32_t runtime_el = MODE_EL2; +#else + static const uint32_t runtime_el = MODE_EL1; +#endif + spmc_ep_info->spsr = SPSR_64(runtime_el, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); } @@ -332,11 +325,15 @@ static uint64_t spmd_smc_forward(uint32_t smc_fid, bool secure_origin, /* Save incoming security state */ cm_el1_sysregs_context_save(secure_state_in); +#if SPMD_SPM_AT_SEL2 cm_el2_sysregs_context_save(secure_state_in); +#endif /* Restore outgoing security state */ cm_el1_sysregs_context_restore(secure_state_out); +#if SPMD_SPM_AT_SEL2 cm_el2_sysregs_context_restore(secure_state_out); +#endif cm_set_next_eret_context(secure_state_out); SMC_RET8(cm_get_context(secure_state_out), smc_fid, x1, x2, x3, x4, -- cgit v1.2.3 From cb3b534457f38c302ebef9f0b2555ffa8c549b65 Mon Sep 17 00:00:00 2001 From: Manish Pandey Date: Tue, 25 Feb 2020 11:38:19 +0000 Subject: SPMD: loading Secure Partition payloads This patch implements loading of Secure Partition packages using existing framework of loading other bl images. The current framework uses a statically defined array to store all the possible image types and at run time generates a link list and traverse through it to load different images. To load SPs, a new array of fixed size is introduced which will be dynamically populated based on number of SPs available in the system and it will be appended to the loadable images list. Change-Id: I8309f63595f2a71b28a73b922d20ccba9c4f6ae4 Signed-off-by: Manish Pandey --- include/plat/arm/common/fconf_arm_sp_getter.h | 4 ++ plat/arm/common/arm_bl2_setup.c | 7 ++++ plat/arm/common/arm_image_load.c | 55 ++++++++++++++++++++++++++- plat/arm/common/fconf/arm_fconf_sp.c | 37 ++++++++++++++---- 4 files changed, 95 insertions(+), 8 deletions(-) diff --git a/include/plat/arm/common/fconf_arm_sp_getter.h b/include/plat/arm/common/fconf_arm_sp_getter.h index 57fd92edf..38c30fbf9 100644 --- a/include/plat/arm/common/fconf_arm_sp_getter.h +++ b/include/plat/arm/common/fconf_arm_sp_getter.h @@ -13,6 +13,8 @@ /* arm_sp getter */ #define arm__sp_getter(prop) arm_sp.prop +#define ARM_SP_MAX_SIZE U(0x10000) + struct arm_sp_t { unsigned int number_of_sp; union uuid_helper_t uuids[MAX_SP_IDS]; @@ -23,4 +25,6 @@ int fconf_populate_arm_sp(uintptr_t config); extern struct arm_sp_t arm_sp; +extern bl_mem_params_node_t sp_mem_params_descs[MAX_SP_IDS]; + #endif /* FCONF_ARM_SP_GETTER_H */ diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c index dd392085d..136e65a1f 100644 --- a/plat/arm/common/arm_bl2_setup.c +++ b/plat/arm/common/arm_bl2_setup.c @@ -205,6 +205,13 @@ 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) + /* For Secure Partitions we don't need post processing */ + if ((image_id >= (MAX_NUMBER_IDS - MAX_SP_IDS)) && + (image_id < MAX_NUMBER_IDS)) { + return 0; + } +#endif return arm_bl2_handle_post_image_load(image_id); } diff --git a/plat/arm/common/arm_image_load.c b/plat/arm/common/arm_image_load.c index 2faaa76c4..593199d46 100644 --- a/plat/arm/common/arm_image_load.c +++ b/plat/arm/common/arm_image_load.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,6 +7,9 @@ #include #include #include +#if defined(SPD_spmd) +#include +#endif #include #include @@ -29,12 +32,62 @@ void plat_flush_next_bl_params(void) next_bl_params_cpy_ptr); } +#if defined(SPD_spmd) +/******************************************************************************* + * This function appends Secure Partitions to list of loadable images. + ******************************************************************************/ +void plat_add_sp_images_load_info(struct bl_load_info *load_info) +{ + bl_load_info_node_t *node_info = load_info->head; + unsigned int index = 0; + + if (sp_mem_params_descs[index].image_id == 0) { + ERROR("No Secure Partition Image available\n"); + return; + } + + /* Traverse through the bl images list */ + do { + node_info = node_info->next_load_info; + } while (node_info->next_load_info != NULL); + + for (; index < MAX_SP_IDS; index++) { + /* Populate the image information */ + node_info->image_id = sp_mem_params_descs[index].image_id; + node_info->image_info = &sp_mem_params_descs[index].image_info; + + if ((index + 1U) == MAX_SP_IDS) { + INFO("Reached Max number of SPs\n"); + return; + } + + if (sp_mem_params_descs[index + 1U].image_id == 0) { + return; + } + + node_info->next_load_info = + &sp_mem_params_descs[index + 1U].load_node_mem; + node_info = node_info->next_load_info; + + } +} +#endif + /******************************************************************************* * This function returns the list of loadable images. ******************************************************************************/ struct bl_load_info *plat_get_bl_image_load_info(void) { +#if defined(SPD_spmd) + bl_load_info_t *bl_load_info; + + bl_load_info = get_bl_load_info_from_mem_params_desc(); + plat_add_sp_images_load_info(bl_load_info); + + return bl_load_info; +#else return get_bl_load_info_from_mem_params_desc(); +#endif } /******************************************************************************* diff --git a/plat/arm/common/fconf/arm_fconf_sp.c b/plat/arm/common/fconf/arm_fconf_sp.c index 0e5cfff95..bb88aff6f 100644 --- a/plat/arm/common/fconf/arm_fconf_sp.c +++ b/plat/arm/common/fconf/arm_fconf_sp.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -19,12 +20,16 @@ #ifdef IMAGE_BL2 +bl_mem_params_node_t sp_mem_params_descs[MAX_SP_IDS]; + struct arm_sp_t arm_sp; int fconf_populate_arm_sp(uintptr_t config) { int sp_node, node, err; union uuid_helper_t uuid_helper; + unsigned int index = 0; + const unsigned int sp_start_index = MAX_NUMBER_IDS - MAX_SP_IDS; /* As libfdt use void *, we can't avoid this cast */ const void *dtb = (void *)config; @@ -46,10 +51,10 @@ int fconf_populate_arm_sp(uintptr_t config) return -1; } - arm_sp.uuids[arm_sp.number_of_sp] = uuid_helper; + arm_sp.uuids[index] = uuid_helper; err = fdtw_read_cells(dtb, sp_node, "load-address", 1, - &arm_sp.load_addr[arm_sp.number_of_sp]); + &arm_sp.load_addr[index]); if (err < 0) { ERROR("FCONF: cannot read SP load address\n"); return -1; @@ -61,11 +66,28 @@ int fconf_populate_arm_sp(uintptr_t config) uuid_helper.word[1], uuid_helper.word[2], uuid_helper.word[3], - arm_sp.load_addr[arm_sp.number_of_sp]); - - arm_sp.number_of_sp++; - - if (arm_sp.number_of_sp >= MAX_SP_IDS) { + arm_sp.load_addr[index]); + + /* Add SP information in mem param descriptor */ + sp_mem_params_descs[index].image_id = sp_start_index + index; + SET_PARAM_HEAD(&sp_mem_params_descs[index].image_info, + PARAM_IMAGE_BINARY, VERSION_2, 0); + sp_mem_params_descs[index].image_info.image_max_size = + ARM_SP_MAX_SIZE; + sp_mem_params_descs[index].next_handoff_image_id = + INVALID_IMAGE_ID; + sp_mem_params_descs[index].image_info.image_base = + arm_sp.load_addr[index]; + + /* Add SP information in IO policies structure */ + policies[sp_start_index + index].image_spec = + (uintptr_t)&arm_sp.uuids[index]; + policies[sp_start_index + index].dev_handle = &fip_dev_handle; + policies[sp_start_index + index].check = open_fip; + + index++; + + if (index >= MAX_SP_IDS) { ERROR("FCONF: reached max number of SPs\n"); return -1; } @@ -76,6 +98,7 @@ int fconf_populate_arm_sp(uintptr_t config) return sp_node; } + arm_sp.number_of_sp = index; return 0; } -- cgit v1.2.3 From c84cbf41f4a6448646cf92055ca037875fe01bc3 Mon Sep 17 00:00:00 2001 From: Vishnu Banavath Date: Wed, 4 Mar 2020 12:13:08 +0000 Subject: fdts: a5ds: add ethernet node in devicetree This change is to add ethernet and voltage regulator nodes into a5ds devicetree. Change-Id: If9ed67040d54e76af1813c9f99835f51f617e9df Signed-off-by: Vishnu Banavath --- fdts/a5ds.dts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/fdts/a5ds.dts b/fdts/a5ds.dts index 31d635ac8..7334c4559 100644 --- a/fdts/a5ds.dts +++ b/fdts/a5ds.dts @@ -136,4 +136,23 @@ reg = <0x1a050000 0x1000>; }; }; + v2m_fixed_3v3: fixed-regulator-0 { + compatible = "regulator-fixed"; + regulator-name = "3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + ethernet@4020000 { + compatible = "smsc,lan9220", "smsc,lan9115"; + reg = <0x40200000 0x10000>; + interrupt-parent = <&gic>; + interrupts = <0 43 0xf04>; + reg-io-width = <4>; + phy-mode = "mii"; + smsc,irq-active-high; + vdd33a-supply = <&v2m_fixed_3v3>; + vddvario-supply = <&v2m_fixed_3v3>; + }; }; -- cgit v1.2.3 From 9e7e98671d66a6048bbdcfaa1e8a68f4a2f97224 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Wed, 4 Mar 2020 13:47:13 -0800 Subject: Tegra: spe: use CONSOLE_T_BASE to save MMIO base address Commit ac71344e9eca1f7d1e0ce4a67aca776470639b1c moved the base address for the MMIO aperture of the console inside the console_t struct. As a result, the driver should now save the MMIO base address to console_t at offset marked by the CONSOLE_T_BASE macro. This patch updates the SPE console driver to use the CONSOLE_T_BASE macro to save/access the MMIO base address. Signed-off-by: Varun Wadekar Change-Id: I42afc2608372687832932269108ed642f218fd40 --- plat/nvidia/tegra/common/drivers/spe/shared_console.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plat/nvidia/tegra/common/drivers/spe/shared_console.S b/plat/nvidia/tegra/common/drivers/spe/shared_console.S index c783373dd..6df73ec24 100644 --- a/plat/nvidia/tegra/common/drivers/spe/shared_console.S +++ b/plat/nvidia/tegra/common/drivers/spe/shared_console.S @@ -69,7 +69,7 @@ func console_spe_register check_if_console_is_ready x0, x1, x2, register_fail cbz x3, register_fail - str x0, [x3, #CONSOLE_T_DRVDATA] + str x0, [x3, #CONSOLE_T_BASE] mov x0, x3 finish_console_register spe putc=1, getc=1, flush=1 @@ -132,7 +132,7 @@ endfunc console_spe_core_putc * -------------------------------------------------------- */ func console_spe_putc - ldr x1, [x1, #CONSOLE_T_DRVDATA] + ldr x1, [x1, #CONSOLE_T_BASE] b console_spe_core_putc endfunc console_spe_putc @@ -183,6 +183,6 @@ endfunc console_spe_core_flush * --------------------------------------------- */ func console_spe_flush - ldr x0, [x0, #CONSOLE_T_DRVDATA] + ldr x0, [x0, #CONSOLE_T_BASE] b console_spe_core_flush endfunc console_spe_flush -- cgit v1.2.3 From 6627de53203516daaa7958751ecbd45d3c4d634a Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 5 Mar 2020 13:56:56 +0000 Subject: imx: console: Use CONSOLE_T_BASE for UART base address Since commit ac71344e9eca we have the UART base address in the generic console_t structure. For most platforms the platform-specific struct console is gone, so we *must* use the embedded base address, since there is no storage behind the generic console_t anymore. Replace the usage of CONSOLE_T_DRVDATA with CONSOLE_T_BASE to fix this. Change-Id: I6d2ab0bc2c845c71f98b9dd64d89eef3252f4591 Reported-by: Varun Wadekar Signed-off-by: Andre Przywara --- plat/imx/common/aarch32/imx_uart_console.S | 8 ++++---- plat/imx/common/imx_uart_console.S | 6 +++--- plat/imx/common/lpuart_console.S | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/plat/imx/common/aarch32/imx_uart_console.S b/plat/imx/common/aarch32/imx_uart_console.S index 1c729b1d7..1a1229aab 100644 --- a/plat/imx/common/aarch32/imx_uart_console.S +++ b/plat/imx/common/aarch32/imx_uart_console.S @@ -20,7 +20,7 @@ func console_imx_uart_register mov r4, r3 cmp r4, #0 beq register_fail - str r0, [r4, #CONSOLE_T_DRVDATA] + str r0, [r4, #CONSOLE_T_BASE] bl console_imx_uart_core_init cmp r0, #0 @@ -35,16 +35,16 @@ register_fail: endfunc console_imx_uart_register func console_imx_uart_putc - ldr r1, [r1, #CONSOLE_T_DRVDATA] + ldr r1, [r1, #CONSOLE_T_BASE] b console_imx_uart_core_putc endfunc console_imx_uart_putc func console_imx_uart_getc - ldr r0, [r0, #CONSOLE_T_DRVDATA] + ldr r0, [r0, #CONSOLE_T_BASE] b console_imx_uart_core_getc endfunc console_imx_uart_getc func console_imx_uart_flush - ldr r0, [r0, #CONSOLE_T_DRVDATA] + ldr r0, [r0, #CONSOLE_T_BASE] b console_imx_uart_core_flush endfunc console_imx_uart_flush diff --git a/plat/imx/common/imx_uart_console.S b/plat/imx/common/imx_uart_console.S index 3bdeea26c..0cb4fb870 100644 --- a/plat/imx/common/imx_uart_console.S +++ b/plat/imx/common/imx_uart_console.S @@ -25,7 +25,7 @@ func console_imx_uart_register mov x7, x30 mov x6, x3 cbz x6, register_fail - str x0, [x6, #CONSOLE_T_DRVDATA] + str x0, [x6, #CONSOLE_T_BASE] bl console_imx_uart_init cbz x0, register_fail @@ -44,7 +44,7 @@ func console_imx_uart_init endfunc console_imx_uart_init func console_imx_uart_putc - ldr x1, [x1, #CONSOLE_T_DRVDATA] + ldr x1, [x1, #CONSOLE_T_BASE] cbz x1, putc_error /* Prepare '\r' to '\n' */ @@ -68,7 +68,7 @@ putc_error: endfunc console_imx_uart_putc func console_imx_uart_getc - ldr x0, [x0, #CONSOLE_T_DRVDATA] + ldr x0, [x0, #CONSOLE_T_BASE] cbz x0, getc_error 1: ldr w1, [x0, #UTS] diff --git a/plat/imx/common/lpuart_console.S b/plat/imx/common/lpuart_console.S index d8dac2cea..98b358807 100644 --- a/plat/imx/common/lpuart_console.S +++ b/plat/imx/common/lpuart_console.S @@ -20,7 +20,7 @@ func console_lpuart_register mov x7, x30 mov x6, x3 cbz x6, register_fail - str x0, [x6, #CONSOLE_T_DRVDATA] + str x0, [x6, #CONSOLE_T_BASE] bl console_lpuart_init cbz x0, register_fail @@ -39,7 +39,7 @@ func console_lpuart_init endfunc console_lpuart_init func console_lpuart_putc - ldr x1, [x1, #CONSOLE_T_DRVDATA] + ldr x1, [x1, #CONSOLE_T_BASE] cbz x1, putc_error /* Prepare '\r' to '\n' */ cmp w0, #0xA @@ -62,7 +62,7 @@ putc_error: endfunc console_lpuart_putc func console_lpuart_getc - ldr x0, [x0, #CONSOLE_T_DRVDATA] + ldr x0, [x0, #CONSOLE_T_BASE] cbz x0, getc_error /* Check if the receive FIFO state */ ret -- cgit v1.2.3 From cc7f89de5ade45aba6c595f5c3b764e4b99e1584 Mon Sep 17 00:00:00 2001 From: Manish Pandey Date: Tue, 3 Mar 2020 17:12:10 +0000 Subject: driver/arm/css: minor bug fix The cpu index was wrongly checked causing it to assert always. Since this code path is exercised only during TF test "NODE_HW_STAT", which queries Power state from SCP, this bug was not detected earlier. Change-Id: Ia25cef4c0aa23ed08092df39134937a2601c21ac Signed-off-by: Manish Pandey --- drivers/arm/css/scp/css_pm_scmi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/arm/css/scp/css_pm_scmi.c b/drivers/arm/css/scp/css_pm_scmi.c index 097d2eb2b..aeb7eda30 100644 --- a/drivers/arm/css/scp/css_pm_scmi.c +++ b/drivers/arm/css/scp/css_pm_scmi.c @@ -224,8 +224,8 @@ void css_scp_on(u_register_t mpidr) SCMI_SET_PWR_STATE_MAX_PWR_LVL(scmi_pwr_state, lvl - 1); - core_pos = plat_core_pos_by_mpidr(mpidr); - assert(core_pos >= 0 && (core_pos < PLATFORM_CORE_COUNT)); + core_pos = (unsigned int)plat_core_pos_by_mpidr(mpidr); + assert(core_pos < PLATFORM_CORE_COUNT); css_scp_core_pos_to_scmi_channel(core_pos, &domain_id, &channel_id); @@ -256,8 +256,8 @@ int css_scp_get_power_state(u_register_t mpidr, unsigned int power_level) return PSCI_E_INVALID_PARAMS; } - cpu_idx = plat_core_pos_by_mpidr(mpidr); - assert(cpu_idx > -1); + cpu_idx = (unsigned int)plat_core_pos_by_mpidr(mpidr); + assert(cpu_idx < PLATFORM_CORE_COUNT); css_scp_core_pos_to_scmi_channel(cpu_idx, &domain_id, &channel_id); ret = scmi_pwr_state_get(scmi_handles[channel_id], -- cgit v1.2.3 From 60a23af2e57931161169c2981bf19af3847c533c Mon Sep 17 00:00:00 2001 From: Igor Opaniuk Date: Thu, 5 Mar 2020 22:10:41 +0200 Subject: plat: imx8mm: provide uart base as build option Some boards (f.e. Verdin i.MX8M Mini) use different UART base address for serial debug output, so make this value configurable (as a build option). Signed-off-by: Igor Opaniuk Change-Id: I988492ccecbc3f64a5153b381c4a97b8a0181f52 --- plat/imx/imx8m/imx8mm/include/platform_def.h | 1 - plat/imx/imx8m/imx8mm/platform.mk | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/plat/imx/imx8m/imx8mm/include/platform_def.h b/plat/imx/imx8m/imx8mm/include/platform_def.h index 56caab7ce..f25ceb034 100644 --- a/plat/imx/imx8m/imx8mm/include/platform_def.h +++ b/plat/imx/imx8m/imx8mm/include/platform_def.h @@ -47,7 +47,6 @@ #define HAB_RVT_BASE U(0x00000900) /* HAB_RVT for i.MX8MM */ -#define IMX_BOOT_UART_BASE U(0x30890000) #define IMX_BOOT_UART_CLK_IN_HZ 24000000 /* Select 24MHz oscillator */ #define PLAT_CRASH_UART_BASE IMX_BOOT_UART_BASE diff --git a/plat/imx/imx8m/imx8mm/platform.mk b/plat/imx/imx8m/imx8mm/platform.mk index c0cb6c2a5..e28f73952 100644 --- a/plat/imx/imx8m/imx8mm/platform.mk +++ b/plat/imx/imx8m/imx8mm/platform.mk @@ -51,3 +51,6 @@ $(eval $(call add_define,BL32_BASE)) BL32_SIZE ?= 0x2000000 $(eval $(call add_define,BL32_SIZE)) + +IMX_BOOT_UART_BASE ?= 0x30890000 +$(eval $(call add_define,IMX_BOOT_UART_BASE)) -- cgit v1.2.3 From 7cda17bb0f92db39d123a4f2a1732c9978556453 Mon Sep 17 00:00:00 2001 From: Sumit Garg Date: Fri, 15 Nov 2019 10:43:00 +0530 Subject: drivers: crypto: Add authenticated decryption framework Add framework for autheticated decryption of data. Currently this patch optionally imports mbedtls library as a backend if build option "DECRYPTION_SUPPORT = aes_gcm" is set to perform authenticated decryption using AES-GCM algorithm. Signed-off-by: Sumit Garg Change-Id: I2966f0e79033151012bf4ffc66f484cd949e7271 --- Makefile | 11 ++- docs/getting_started/build-options.rst | 6 ++ drivers/auth/crypto_mod.c | 32 +++++++ drivers/auth/cryptocell/712/cryptocell_crypto.c | 2 +- drivers/auth/mbedtls/mbedtls_common.mk | 12 ++- drivers/auth/mbedtls/mbedtls_crypto.c | 117 +++++++++++++++++++++++- include/drivers/auth/crypto_mod.h | 34 ++++++- include/drivers/auth/mbedtls/mbedtls_config.h | 6 ++ include/plat/common/platform.h | 9 ++ make_helpers/defaults.mk | 3 + 10 files changed, 223 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index f3cb9be6b..f7ae5ea50 100644 --- a/Makefile +++ b/Makefile @@ -623,7 +623,7 @@ endif ifeq ($(MEASURED_BOOT),1) ifneq (${TRUSTED_BOARD_BOOT},1) - $(error MEASURED_BOOT requires TRUSTED_BOARD_BOOT=1") + $(error MEASURED_BOOT requires TRUSTED_BOARD_BOOT=1) else $(info MEASURED_BOOT is an experimental feature) endif @@ -635,6 +635,14 @@ ifeq (${ARM_XLAT_TABLES_LIB_V1}, 1) endif 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 + ################################################################################ # Process platform overrideable behaviour ################################################################################ @@ -843,6 +851,7 @@ $(eval $(call add_define,CTX_INCLUDE_PAUTH_REGS)) $(eval $(call add_define,EL3_EXCEPTION_HANDLING)) $(eval $(call add_define,CTX_INCLUDE_MTE_REGS)) $(eval $(call add_define,CTX_INCLUDE_EL2_REGS)) +$(eval $(call add_define,DECRYPTION_SUPPORT_${DECRYPTION_SUPPORT})) $(eval $(call add_define,ENABLE_AMU)) $(eval $(call add_define,ENABLE_ASSERTIONS)) $(eval $(call add_define,ENABLE_BTI)) diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index da5dcbf89..af4895efc 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -160,6 +160,12 @@ Common build options - ``DEBUG``: Chooses between a debug and release build. It can take either 0 (release) or 1 (debug) as values. 0 is the default. +- ``DECRYPTION_SUPPORT``: This build flag enables the user to select the + 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. + - ``DISABLE_BIN_GENERATION``: Boolean option to disable the generation of the binary image. If set to 1, then only the ELF image is built. 0 is the default. diff --git a/drivers/auth/crypto_mod.c b/drivers/auth/crypto_mod.c index 110c5045f..c63ff080f 100644 --- a/drivers/auth/crypto_mod.c +++ b/drivers/auth/crypto_mod.c @@ -124,3 +124,35 @@ int crypto_mod_calc_hash(unsigned int alg, void *data_ptr, return crypto_lib_desc.calc_hash(alg, data_ptr, data_len, output); } #endif /* MEASURED_BOOT */ + +/* + * Authenticated decryption of data + * + * Parameters: + * + * dec_algo: authenticated decryption algorithm + * data_ptr, len: data to be decrypted (inout param) + * key, key_len, key_flags: symmetric decryption key + * iv, iv_len: initialization vector + * tag, tag_len: authentication tag + */ +int crypto_mod_auth_decrypt(enum crypto_dec_algo dec_algo, void *data_ptr, + size_t len, const void *key, unsigned int key_len, + unsigned int key_flags, const void *iv, + unsigned int iv_len, const void *tag, + unsigned int tag_len) +{ + assert(crypto_lib_desc.auth_decrypt != NULL); + assert(data_ptr != NULL); + assert(len != 0U); + assert(key != NULL); + assert(key_len != 0U); + assert(iv != NULL); + assert((iv_len != 0U) && (iv_len <= CRYPTO_MAX_IV_SIZE)); + assert(tag != NULL); + assert((tag_len != 0U) && (tag_len <= CRYPTO_MAX_TAG_SIZE)); + + return crypto_lib_desc.auth_decrypt(dec_algo, data_ptr, len, key, + key_len, key_flags, iv, iv_len, tag, + tag_len); +} diff --git a/drivers/auth/cryptocell/712/cryptocell_crypto.c b/drivers/auth/cryptocell/712/cryptocell_crypto.c index 25eb6bcb6..cf4317534 100644 --- a/drivers/auth/cryptocell/712/cryptocell_crypto.c +++ b/drivers/auth/cryptocell/712/cryptocell_crypto.c @@ -301,5 +301,5 @@ static int verify_hash(void *data_ptr, unsigned int data_len, /* * Register crypto library descriptor */ -REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash); +REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL); diff --git a/drivers/auth/mbedtls/mbedtls_common.mk b/drivers/auth/mbedtls/mbedtls_common.mk index 4b8301541..044b368bc 100644 --- a/drivers/auth/mbedtls/mbedtls_common.mk +++ b/drivers/auth/mbedtls/mbedtls_common.mk @@ -23,13 +23,17 @@ MBEDTLS_SOURCES += drivers/auth/mbedtls/mbedtls_common.c LIBMBEDTLS_SRCS := $(addprefix ${MBEDTLS_DIR}/library/, \ + aes.c \ asn1parse.c \ asn1write.c \ + cipher.c \ + cipher_wrap.c \ memory_buffer_alloc.c \ oid.c \ platform.c \ platform_util.c \ bignum.c \ + gcm.c \ md.c \ md_wrap.c \ pk.c \ @@ -87,11 +91,17 @@ else $(error "TF_MBEDTLS_KEY_ALG=${TF_MBEDTLS_KEY_ALG} not supported on mbed TLS") endif +ifeq (${DECRYPTION_SUPPORT}, aes_gcm) + TF_MBEDTLS_USE_AES_GCM := 1 +else + TF_MBEDTLS_USE_AES_GCM := 0 +endif + # Needs to be set to drive mbed TLS configuration correctly $(eval $(call add_define,TF_MBEDTLS_KEY_ALG_ID)) $(eval $(call add_define,TF_MBEDTLS_KEY_SIZE)) $(eval $(call add_define,TF_MBEDTLS_HASH_ALG_ID)) - +$(eval $(call add_define,TF_MBEDTLS_USE_AES_GCM)) $(eval $(call MAKE_LIB,mbedtls)) diff --git a/drivers/auth/mbedtls/mbedtls_crypto.c b/drivers/auth/mbedtls/mbedtls_crypto.c index 04fbc648b..2a9801497 100644 --- a/drivers/auth/mbedtls/mbedtls_crypto.c +++ b/drivers/auth/mbedtls/mbedtls_crypto.c @@ -4,10 +4,12 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include #include #include /* mbed TLS headers */ +#include #include #include #include @@ -17,6 +19,7 @@ #include #include #include +#include #define LIB_NAME "mbed TLS" @@ -226,11 +229,121 @@ int calc_hash(unsigned int alg, void *data_ptr, } #endif /* MEASURED_BOOT */ +#if TF_MBEDTLS_USE_AES_GCM +/* + * Stack based buffer allocation for decryption operation. It could + * be configured to balance stack usage vs execution speed. + */ +#define DEC_OP_BUF_SIZE 128 + +static int aes_gcm_decrypt(void *data_ptr, size_t len, const void *key, + unsigned int key_len, const void *iv, + unsigned int iv_len, const void *tag, + unsigned int tag_len) +{ + mbedtls_gcm_context ctx; + mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES; + unsigned char buf[DEC_OP_BUF_SIZE]; + unsigned char tag_buf[CRYPTO_MAX_TAG_SIZE]; + unsigned char *pt = data_ptr; + size_t dec_len; + int diff, i, rc; + + mbedtls_gcm_init(&ctx); + + rc = mbedtls_gcm_setkey(&ctx, cipher, key, key_len * 8); + if (rc != 0) { + rc = CRYPTO_ERR_DECRYPTION; + goto exit_gcm; + } + + rc = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT, iv, iv_len, NULL, 0); + if (rc != 0) { + rc = CRYPTO_ERR_DECRYPTION; + goto exit_gcm; + } + + while (len > 0) { + dec_len = MIN(sizeof(buf), len); + + rc = mbedtls_gcm_update(&ctx, dec_len, pt, buf); + if (rc != 0) { + rc = CRYPTO_ERR_DECRYPTION; + goto exit_gcm; + } + + memcpy(pt, buf, dec_len); + pt += dec_len; + len -= dec_len; + } + + rc = mbedtls_gcm_finish(&ctx, tag_buf, sizeof(tag_buf)); + if (rc != 0) { + rc = CRYPTO_ERR_DECRYPTION; + goto exit_gcm; + } + + /* Check tag in "constant-time" */ + for (diff = 0, i = 0; i < tag_len; i++) + diff |= ((const unsigned char *)tag)[i] ^ tag_buf[i]; + + if (diff != 0) { + rc = CRYPTO_ERR_DECRYPTION; + goto exit_gcm; + } + + /* GCM decryption success */ + rc = CRYPTO_SUCCESS; + +exit_gcm: + mbedtls_gcm_free(&ctx); + return rc; +} + +/* + * Authenticated decryption of an image + */ +static int auth_decrypt(enum crypto_dec_algo dec_algo, void *data_ptr, + size_t len, const void *key, unsigned int key_len, + unsigned int key_flags, const void *iv, + unsigned int iv_len, const void *tag, + unsigned int tag_len) +{ + int rc; + + assert((key_flags & ENC_KEY_IS_IDENTIFIER) == 0); + + switch (dec_algo) { + case CRYPTO_GCM_DECRYPT: + rc = aes_gcm_decrypt(data_ptr, len, key, key_len, iv, iv_len, + tag, tag_len); + if (rc != 0) + return rc; + break; + default: + return CRYPTO_ERR_DECRYPTION; + } + + return CRYPTO_SUCCESS; +} +#endif /* TF_MBEDTLS_USE_AES_GCM */ + /* * Register crypto library descriptor */ #if MEASURED_BOOT -REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash); +#if TF_MBEDTLS_USE_AES_GCM +REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash, + auth_decrypt); +#else +REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash, + NULL); +#endif +#else /* MEASURED_BOOT */ +#if TF_MBEDTLS_USE_AES_GCM +REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, + auth_decrypt); #else -REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash); +REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL); +#endif #endif /* MEASURED_BOOT */ diff --git a/include/drivers/auth/crypto_mod.h b/include/drivers/auth/crypto_mod.h index f211035d7..71cf67306 100644 --- a/include/drivers/auth/crypto_mod.h +++ b/include/drivers/auth/crypto_mod.h @@ -13,9 +13,18 @@ enum crypto_ret_value { CRYPTO_ERR_INIT, CRYPTO_ERR_HASH, CRYPTO_ERR_SIGNATURE, + CRYPTO_ERR_DECRYPTION, CRYPTO_ERR_UNKNOWN }; +#define CRYPTO_MAX_IV_SIZE 16U +#define CRYPTO_MAX_TAG_SIZE 16U + +/* Decryption algorithm */ +enum crypto_dec_algo { + CRYPTO_GCM_DECRYPT = 0 +}; + /* * Cryptographic library descriptor */ @@ -44,6 +53,15 @@ typedef struct crypto_lib_desc_s { unsigned int data_len, unsigned char *output); #endif /* MEASURED_BOOT */ + /* + * Authenticated decryption. Return one of the + * 'enum crypto_ret_value' options. + */ + int (*auth_decrypt)(enum crypto_dec_algo dec_algo, void *data_ptr, + size_t len, const void *key, unsigned int key_len, + unsigned int key_flags, const void *iv, + unsigned int iv_len, const void *tag, + unsigned int tag_len); } crypto_lib_desc_t; /* Public functions */ @@ -54,6 +72,11 @@ int crypto_mod_verify_signature(void *data_ptr, unsigned int data_len, void *pk_ptr, unsigned int pk_len); int crypto_mod_verify_hash(void *data_ptr, unsigned int data_len, void *digest_info_ptr, unsigned int digest_info_len); +int crypto_mod_auth_decrypt(enum crypto_dec_algo dec_algo, void *data_ptr, + size_t len, const void *key, unsigned int key_len, + unsigned int key_flags, const void *iv, + unsigned int iv_len, const void *tag, + unsigned int tag_len); #if MEASURED_BOOT int crypto_mod_calc_hash(unsigned int alg, void *data_ptr, @@ -61,21 +84,24 @@ int crypto_mod_calc_hash(unsigned int alg, void *data_ptr, /* Macro to register a cryptographic library */ #define REGISTER_CRYPTO_LIB(_name, _init, _verify_signature, _verify_hash, \ - _calc_hash) \ + _calc_hash, _auth_decrypt) \ const crypto_lib_desc_t crypto_lib_desc = { \ .name = _name, \ .init = _init, \ .verify_signature = _verify_signature, \ .verify_hash = _verify_hash, \ - .calc_hash = _calc_hash \ + .calc_hash = _calc_hash, \ + .auth_decrypt = _auth_decrypt \ } #else -#define REGISTER_CRYPTO_LIB(_name, _init, _verify_signature, _verify_hash) \ +#define REGISTER_CRYPTO_LIB(_name, _init, _verify_signature, _verify_hash, \ + _auth_decrypt) \ const crypto_lib_desc_t crypto_lib_desc = { \ .name = _name, \ .init = _init, \ .verify_signature = _verify_signature, \ - .verify_hash = _verify_hash \ + .verify_hash = _verify_hash, \ + .auth_decrypt = _auth_decrypt \ } #endif /* MEASURED_BOOT */ diff --git a/include/drivers/auth/mbedtls/mbedtls_config.h b/include/drivers/auth/mbedtls/mbedtls_config.h index 6e179bbd1..dc00da7d6 100644 --- a/include/drivers/auth/mbedtls/mbedtls_config.h +++ b/include/drivers/auth/mbedtls/mbedtls_config.h @@ -79,6 +79,12 @@ #define MBEDTLS_X509_USE_C #define MBEDTLS_X509_CRT_PARSE_C +#if TF_MBEDTLS_USE_AES_GCM +#define MBEDTLS_AES_C +#define MBEDTLS_CIPHER_C +#define MBEDTLS_GCM_C +#endif + /* MPI / BIGNUM options */ #define MBEDTLS_MPI_WINDOW_SIZE 2 diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h index f5bd298c5..06b334d70 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.h @@ -36,6 +36,15 @@ struct sp_res_desc; ROTPK is not deployed */ #define ROTPK_NOT_DEPLOYED (1 << 1) +/******************************************************************************* + * plat_get_enc_key_info() flags + ******************************************************************************/ +/* + * Flag used to notify caller that information provided in key buffer is an + * identifier rather than an actual key. + */ +#define ENC_KEY_IS_IDENTIFIER (1 << 0) + /******************************************************************************* * Function declarations ******************************************************************************/ diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index 9273469e2..012760733 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -65,6 +65,9 @@ CTX_INCLUDE_PAUTH_REGS := 0 # Debug build DEBUG := 0 +# By default disable authenticated decryption support. +DECRYPTION_SUPPORT := none + # Build platform DEFAULT_PLAT := fvp -- cgit v1.2.3 From 2be57b8658b1206a8fb8a2cfbbd9b15cae4b354d Mon Sep 17 00:00:00 2001 From: Sumit Garg Date: Fri, 15 Nov 2019 15:34:55 +0530 Subject: TBB: Add an IO abstraction layer to load encrypted firmwares TBBR spec advocates for optional encryption of firmwares (see optional requirement: R060_TBBR_FUNCTION). So add an IO abstaction layer to support firmware decryption that can be stacked above any underlying IO/ packaging layer like FIP etc. It aims to provide a framework to load any encrypted IO payload. Also, add plat_get_enc_key_info() to be implemented in a platform specific manner as handling of encryption key may vary from one platform to another. Signed-off-by: Sumit Garg Change-Id: I9892e0ddf00ebecb8981301dbfa41ea23e078b03 --- drivers/io/io_encrypted.c | 244 ++++++++++++++++++++++++++ include/drivers/io/io_encrypted.h | 15 ++ include/drivers/io/io_storage.h | 1 + include/export/common/tbbr/tbbr_img_def_exp.h | 7 +- include/plat/common/platform.h | 4 + include/tools_share/firmware_encrypted.h | 42 +++++ plat/common/plat_bl_common.c | 27 +++ 7 files changed, 338 insertions(+), 2 deletions(-) create mode 100644 drivers/io/io_encrypted.c create mode 100644 include/drivers/io/io_encrypted.h create mode 100644 include/tools_share/firmware_encrypted.h diff --git a/drivers/io/io_encrypted.c b/drivers/io/io_encrypted.c new file mode 100644 index 000000000..744ca8356 --- /dev/null +++ b/drivers/io/io_encrypted.c @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2020, Linaro Limited. All rights reserved. + * Author: Sumit Garg + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static uintptr_t backend_dev_handle; +static uintptr_t backend_dev_spec; +static uintptr_t backend_handle; +static uintptr_t backend_image_spec; + +static io_dev_info_t enc_dev_info; + +/* Encrypted firmware driver functions */ +static int enc_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info); +static int enc_file_open(io_dev_info_t *dev_info, const uintptr_t spec, + io_entity_t *entity); +static int enc_file_len(io_entity_t *entity, size_t *length); +static int enc_file_read(io_entity_t *entity, uintptr_t buffer, size_t length, + size_t *length_read); +static int enc_file_close(io_entity_t *entity); +static int enc_dev_init(io_dev_info_t *dev_info, const uintptr_t init_params); +static int enc_dev_close(io_dev_info_t *dev_info); + +static inline int is_valid_header(struct fw_enc_hdr *header) +{ + if (header->magic == ENC_HEADER_MAGIC) + return 1; + else + return 0; +} + +static io_type_t device_type_enc(void) +{ + return IO_TYPE_ENCRYPTED; +} + +static const io_dev_connector_t enc_dev_connector = { + .dev_open = enc_dev_open +}; + +static const io_dev_funcs_t enc_dev_funcs = { + .type = device_type_enc, + .open = enc_file_open, + .seek = NULL, + .size = enc_file_len, + .read = enc_file_read, + .write = NULL, + .close = enc_file_close, + .dev_init = enc_dev_init, + .dev_close = enc_dev_close, +}; + +static int enc_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info) +{ + assert(dev_info != NULL); + + enc_dev_info.funcs = &enc_dev_funcs; + *dev_info = &enc_dev_info; + + return 0; +} + +static int enc_dev_init(io_dev_info_t *dev_info, const uintptr_t init_params) +{ + int result; + unsigned int image_id = (unsigned int)init_params; + + /* Obtain a reference to the image by querying the platform layer */ + result = plat_get_image_source(image_id, &backend_dev_handle, + &backend_dev_spec); + if (result != 0) { + WARN("Failed to obtain reference to image id=%u (%i)\n", + image_id, result); + return -ENOENT; + } + + return result; +} + +static int enc_dev_close(io_dev_info_t *dev_info) +{ + backend_dev_handle = (uintptr_t)NULL; + backend_dev_spec = (uintptr_t)NULL; + + return 0; +} + +static int enc_file_open(io_dev_info_t *dev_info, const uintptr_t spec, + io_entity_t *entity) +{ + int result; + + assert(spec != 0); + assert(entity != NULL); + + backend_image_spec = spec; + + result = io_open(backend_dev_handle, backend_image_spec, + &backend_handle); + if (result != 0) { + WARN("Failed to open backend device (%i)\n", result); + result = -ENOENT; + } + + return result; +} + +static int enc_file_len(io_entity_t *entity, size_t *length) +{ + int result; + + assert(entity != NULL); + assert(length != NULL); + + result = io_size(backend_handle, length); + if (result != 0) { + WARN("Failed to read blob length (%i)\n", result); + return -ENOENT; + } + + /* + * Encryption header is attached at the beginning of the encrypted file + * and is not considered a part of the payload. + */ + if (*length < sizeof(struct fw_enc_hdr)) + return -EIO; + + *length -= sizeof(struct fw_enc_hdr); + + return result; +} + +static int enc_file_read(io_entity_t *entity, uintptr_t buffer, size_t length, + size_t *length_read) +{ + int result; + struct fw_enc_hdr header; + enum fw_enc_status_t fw_enc_status; + size_t bytes_read; + uint8_t key[ENC_MAX_KEY_SIZE]; + size_t key_len = sizeof(key); + unsigned int key_flags = 0; + const io_uuid_spec_t *uuid_spec = (io_uuid_spec_t *)backend_image_spec; + + assert(entity != NULL); + assert(length_read != NULL); + + result = io_read(backend_handle, (uintptr_t)&header, sizeof(header), + &bytes_read); + if (result != 0) { + WARN("Failed to read encryption header (%i)\n", result); + return -ENOENT; + } + + if (!is_valid_header(&header)) { + WARN("Encryption header check failed.\n"); + return -ENOENT; + } + + VERBOSE("Encryption header looks OK.\n"); + fw_enc_status = header.flags & FW_ENC_STATUS_FLAG_MASK; + + if ((header.iv_len > ENC_MAX_IV_SIZE) || + (header.tag_len > ENC_MAX_TAG_SIZE)) { + WARN("Incorrect IV or tag length\n"); + return -ENOENT; + } + + result = io_read(backend_handle, buffer, length, &bytes_read); + if (result != 0) { + WARN("Failed to read encrypted payload (%i)\n", result); + return -ENOENT; + } + + *length_read = bytes_read; + + result = plat_get_enc_key_info(fw_enc_status, key, &key_len, &key_flags, + (uint8_t *)&uuid_spec->uuid, + sizeof(uuid_t)); + if (result != 0) { + WARN("Failed to obtain encryption key (%i)\n", result); + return -ENOENT; + } + + result = crypto_mod_auth_decrypt(header.dec_algo, + (void *)buffer, *length_read, key, + key_len, key_flags, header.iv, + header.iv_len, header.tag, + header.tag_len); + memset(key, 0, key_len); + + if (result != 0) { + ERROR("File decryption failed (%i)\n", result); + return -ENOENT; + } + + return result; +} + +static int enc_file_close(io_entity_t *entity) +{ + io_close(backend_handle); + + backend_image_spec = (uintptr_t)NULL; + entity->info = 0; + + return 0; +} + +/* Exported functions */ + +/* Register the Encrypted Firmware driver with the IO abstraction */ +int register_io_dev_enc(const io_dev_connector_t **dev_con) +{ + int result; + + assert(dev_con != NULL); + + result = io_register_device(&enc_dev_info); + if (result == 0) + *dev_con = &enc_dev_connector; + + return result; +} diff --git a/include/drivers/io/io_encrypted.h b/include/drivers/io/io_encrypted.h new file mode 100644 index 000000000..9dcf061b4 --- /dev/null +++ b/include/drivers/io/io_encrypted.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2020, Linaro Limited. All rights reserved. + * Author: Sumit Garg + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef IO_ENCRYPTED_H +#define IO_ENCRYPTED_H + +struct io_dev_connector; + +int register_io_dev_enc(const struct io_dev_connector **dev_con); + +#endif /* IO_ENCRYPTED_H */ diff --git a/include/drivers/io/io_storage.h b/include/drivers/io/io_storage.h index a301ad563..f2d641c2d 100644 --- a/include/drivers/io/io_storage.h +++ b/include/drivers/io/io_storage.h @@ -25,6 +25,7 @@ typedef enum { IO_TYPE_MTD, IO_TYPE_MMC, IO_TYPE_STM32IMAGE, + IO_TYPE_ENCRYPTED, IO_TYPE_MAX } io_type_t; diff --git a/include/export/common/tbbr/tbbr_img_def_exp.h b/include/export/common/tbbr/tbbr_img_def_exp.h index 360255413..89dbc58fe 100644 --- a/include/export/common/tbbr/tbbr_img_def_exp.h +++ b/include/export/common/tbbr/tbbr_img_def_exp.h @@ -85,12 +85,15 @@ /* Binary with STM32 header */ #define STM32_IMAGE_ID U(29) +/* Encrypted image identifier */ +#define ENC_IMAGE_ID U(30) + /* Define size of the array */ #if defined(SPD_spmd) #define MAX_SP_IDS U(8) -#define MAX_NUMBER_IDS MAX_SP_IDS + U(30) +#define MAX_NUMBER_IDS MAX_SP_IDS + U(31) #else -#define MAX_NUMBER_IDS U(30) +#define MAX_NUMBER_IDS U(31) #endif #endif /* ARM_TRUSTED_FIRMWARE_EXPORT_COMMON_TBBR_TBBR_IMG_DEF_EXP_H */ diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h index 06b334d70..5b5ebb973 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.h @@ -27,6 +27,7 @@ struct bl_params; struct mmap_region; struct spm_mm_boot_info; struct sp_res_desc; +enum fw_enc_status_t; /******************************************************************************* * plat_get_rotpk_info() flags @@ -274,6 +275,9 @@ int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr); int plat_set_nv_ctr2(void *cookie, const struct auth_img_desc_s *img_desc, unsigned int nv_ctr); int get_mbedtls_heap_helper(void **heap_addr, size_t *heap_size); +int plat_get_enc_key_info(enum fw_enc_status_t fw_enc_status, uint8_t *key, + size_t *key_len, unsigned int *flags, + const uint8_t *img_id, size_t img_id_len); /******************************************************************************* * Secure Partitions functions diff --git a/include/tools_share/firmware_encrypted.h b/include/tools_share/firmware_encrypted.h new file mode 100644 index 000000000..7ca634f5e --- /dev/null +++ b/include/tools_share/firmware_encrypted.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2020, Linaro Limited. All rights reserved. + * Author: Sumit Garg + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FIRMWARE_ENCRYPTED_H +#define FIRMWARE_ENCRYPTED_H + +#include + +/* This is used as a signature to validate the encryption header */ +#define ENC_HEADER_MAGIC 0xAA640001U + +/* Firmware encryption status flag mask */ +#define FW_ENC_STATUS_FLAG_MASK 0x1 + +/* + * SSK: Secret Symmetric Key + * BSSK: Binding Secret Symmetric Key + */ +enum fw_enc_status_t { + FW_ENC_WITH_SSK = 0, + FW_ENC_WITH_BSSK = 1, +}; + +#define ENC_MAX_IV_SIZE 16U +#define ENC_MAX_TAG_SIZE 16U +#define ENC_MAX_KEY_SIZE 32U + +struct fw_enc_hdr { + uint32_t magic; + uint16_t dec_algo; + uint16_t flags; + uint16_t iv_len; + uint16_t tag_len; + uint8_t iv[ENC_MAX_IV_SIZE]; + uint8_t tag[ENC_MAX_TAG_SIZE]; +}; + +#endif /* FIRMWARE_ENCRYPTED_H */ diff --git a/plat/common/plat_bl_common.c b/plat/common/plat_bl_common.c index 6070db235..de6c1d176 100644 --- a/plat/common/plat_bl_common.c +++ b/plat/common/plat_bl_common.c @@ -11,6 +11,7 @@ #include #include #include +#include /* * The following platform functions are weakly defined. The Platforms @@ -22,6 +23,7 @@ #pragma weak bl2_plat_handle_pre_image_load #pragma weak bl2_plat_handle_post_image_load #pragma weak plat_try_next_boot_source +#pragma weak plat_get_enc_key_info void bl2_el3_plat_prepare_exit(void) { @@ -52,6 +54,31 @@ int plat_try_next_boot_source(void) return 0; } +/* + * Weak implementation to provide dummy decryption key only for test purposes, + * platforms must override this API for any real world firmware encryption + * use-case. + */ +int plat_get_enc_key_info(enum fw_enc_status_t fw_enc_status, uint8_t *key, + size_t *key_len, unsigned int *flags, + const uint8_t *img_id, size_t img_id_len) +{ +#define DUMMY_FIP_ENC_KEY { 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, \ + 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, \ + 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, \ + 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef } + + const uint8_t dummy_key[] = DUMMY_FIP_ENC_KEY; + + assert(*key_len >= sizeof(dummy_key)); + + *key_len = sizeof(dummy_key); + memcpy(key, dummy_key, *key_len); + *flags = 0; + + return 0; +} + /* * Set up the page tables for the generic and platform-specific memory regions. * The size of the Trusted SRAM seen by the BL image must be specified as well -- cgit v1.2.3 From 90aa901fc1154d2b12aa8d838ef71be47ba3cd07 Mon Sep 17 00:00:00 2001 From: Sumit Garg Date: Mon, 11 Nov 2019 18:46:36 +0530 Subject: tools: Add firmware authenticated encryption tool Add firmware authenticated encryption tool which utilizes OpenSSL library to encrypt firmwares using a key provided via cmdline. Currently this tool supports AES-GCM as an authenticated encryption algorithm. Signed-off-by: Sumit Garg Change-Id: I60e296af1b98f1912a19d5f91066be7ea85836e4 --- Makefile | 18 ++- tools/encrypt_fw/Makefile | 65 +++++++++++ tools/encrypt_fw/include/cmd_opt.h | 32 ++++++ tools/encrypt_fw/include/debug.h | 59 ++++++++++ tools/encrypt_fw/include/encrypt.h | 19 ++++ tools/encrypt_fw/src/cmd_opt.c | 59 ++++++++++ tools/encrypt_fw/src/encrypt.c | 167 +++++++++++++++++++++++++++ tools/encrypt_fw/src/main.c | 224 +++++++++++++++++++++++++++++++++++++ 8 files changed, 642 insertions(+), 1 deletion(-) create mode 100644 tools/encrypt_fw/Makefile create mode 100644 tools/encrypt_fw/include/cmd_opt.h create mode 100644 tools/encrypt_fw/include/debug.h create mode 100644 tools/encrypt_fw/include/encrypt.h create mode 100644 tools/encrypt_fw/src/cmd_opt.c create mode 100644 tools/encrypt_fw/src/encrypt.c create mode 100644 tools/encrypt_fw/src/main.c diff --git a/Makefile b/Makefile index f7ae5ea50..8f50d7c8d 100644 --- a/Makefile +++ b/Makefile @@ -716,6 +716,10 @@ include lib/stack_protector/stack_protector.mk CRTTOOLPATH ?= tools/cert_create CRTTOOL ?= ${CRTTOOLPATH}/cert_create${BIN_EXT} +# Variables for use with Firmware Encryption Tool +ENCTOOLPATH ?= tools/encrypt_fw +ENCTOOL ?= ${ENCTOOLPATH}/encrypt_fw${BIN_EXT} + # Variables for use with Firmware Image Package FIPTOOLPATH ?= tools/fiptool FIPTOOL ?= ${FIPTOOLPATH}/fiptool${BIN_EXT} @@ -935,7 +939,7 @@ endif # Build targets ################################################################################ -.PHONY: all msg_start clean realclean distclean cscope locate-checkpatch checkcodebase checkpatch fiptool sptool fip sp fwu_fip certtool dtbs memmap doc +.PHONY: all msg_start clean realclean distclean cscope locate-checkpatch checkcodebase checkpatch fiptool sptool fip sp fwu_fip certtool dtbs memmap doc enctool .SUFFIXES: all: msg_start @@ -1038,6 +1042,7 @@ clean: $(call SHELL_REMOVE_DIR,${BUILD_PLAT}) ${Q}${MAKE} --no-print-directory -C ${FIPTOOLPATH} clean ${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH} clean + ${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${ENCTOOLPATH} clean ${Q}${MAKE} --no-print-directory -C ${ROMLIBPATH} clean realclean distclean: @@ -1047,6 +1052,7 @@ realclean distclean: ${Q}${MAKE} --no-print-directory -C ${FIPTOOLPATH} clean ${Q}${MAKE} --no-print-directory -C ${SPTOOLPATH} clean ${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH} clean + ${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${ENCTOOLPATH} realclean ${Q}${MAKE} --no-print-directory -C ${ROMLIBPATH} clean checkcodebase: locate-checkpatch @@ -1148,6 +1154,15 @@ doc: @echo " BUILD DOCUMENTATION" ${Q}${MAKE} --no-print-directory -C ${DOCS_PATH} html +enctool: ${ENCTOOL} + +.PHONY: ${ENCTOOL} +${ENCTOOL}: + ${Q}${MAKE} PLAT=${PLAT} BUILD_INFO=0 --no-print-directory -C ${ENCTOOLPATH} + @${ECHO_BLANK_LINE} + @echo "Built $@ successfully" + @${ECHO_BLANK_LINE} + cscope: @echo " CSCOPE" ${Q}find ${CURDIR} -name "*.[chsS]" > cscope.files @@ -1184,6 +1199,7 @@ help: @echo " cscope Generate cscope index" @echo " distclean Remove all build artifacts for all platforms" @echo " certtool Build the Certificate generation tool" + @echo " enctool Build the Firmware encryption tool" @echo " fiptool Build the Firmware Image Package (FIP) creation tool" @echo " sp Build the Secure Partition Packages" @echo " sptool Build the Secure Partition Package creation tool" diff --git a/tools/encrypt_fw/Makefile b/tools/encrypt_fw/Makefile new file mode 100644 index 000000000..cb81d0b2e --- /dev/null +++ b/tools/encrypt_fw/Makefile @@ -0,0 +1,65 @@ +# +# Copyright (c) 2019, Linaro Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +PROJECT := encrypt_fw +V ?= 0 +BUILD_INFO ?= 1 +DEBUG := 0 +BINARY := ${PROJECT}${BIN_EXT} +OPENSSL_DIR := /usr + +OBJECTS := src/encrypt.o \ + src/cmd_opt.o \ + src/main.o + +HOSTCCFLAGS := -Wall -std=c99 + +MAKE_HELPERS_DIRECTORY := ../../make_helpers/ +include ${MAKE_HELPERS_DIRECTORY}build_macros.mk +include ${MAKE_HELPERS_DIRECTORY}build_env.mk + +ifeq (${DEBUG},1) + HOSTCCFLAGS += -g -O0 -DDEBUG -DLOG_LEVEL=40 +else +ifeq (${BUILD_INFO},1) + HOSTCCFLAGS += -O2 -DLOG_LEVEL=20 +else + HOSTCCFLAGS += -O2 -DLOG_LEVEL=10 +endif +endif +ifeq (${V},0) + Q := @ +else + Q := +endif + +# Make soft links and include from local directory otherwise wrong headers +# could get pulled in from firmware tree. +INC_DIR := -I ./include -I ../../include/tools_share -I ${OPENSSL_DIR}/include +LIB_DIR := -L ${OPENSSL_DIR}/lib +LIB := -lssl -lcrypto + +HOSTCC ?= gcc + +.PHONY: all clean realclean + +all: clean ${BINARY} + +${BINARY}: ${OBJECTS} Makefile + @echo " HOSTLD $@" + @echo 'const char build_msg[] = "Built : "__TIME__", "__DATE__;' | \ + ${HOSTCC} -c ${HOSTCCFLAGS} -xc - -o src/build_msg.o + ${Q}${HOSTCC} src/build_msg.o ${OBJECTS} ${LIB_DIR} ${LIB} -o $@ + +%.o: %.c + @echo " HOSTCC $<" + ${Q}${HOSTCC} -c ${HOSTCCFLAGS} ${INC_DIR} $< -o $@ + +clean: + $(call SHELL_DELETE_ALL, src/build_msg.o ${OBJECTS}) + +realclean: clean + $(call SHELL_DELETE,${BINARY}) diff --git a/tools/encrypt_fw/include/cmd_opt.h b/tools/encrypt_fw/include/cmd_opt.h new file mode 100644 index 000000000..bd7d31f03 --- /dev/null +++ b/tools/encrypt_fw/include/cmd_opt.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2019, Linaro Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CMD_OPT_H +#define CMD_OPT_H + +#include + +#define CMD_OPT_MAX_NUM 64 + +/* Supported long command line option types */ +enum { + CMD_OPT_FW +}; + +/* Structure to define a command line option */ +typedef struct cmd_opt_s { + struct option long_opt; + const char *help_msg; +} cmd_opt_t; + +/* Exported API*/ +void cmd_opt_add(const cmd_opt_t *cmd_opt); +const struct option *cmd_opt_get_array(void); +const char *cmd_opt_get_name(int idx); +const char *cmd_opt_get_help_msg(int idx); + +#endif /* CMD_OPT_H */ diff --git a/tools/encrypt_fw/include/debug.h b/tools/encrypt_fw/include/debug.h new file mode 100644 index 000000000..ee8f1f517 --- /dev/null +++ b/tools/encrypt_fw/include/debug.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef DEBUG_H +#define DEBUG_H + +#include + +/* The log output macros print output to the console. These macros produce + * compiled log output only if the LOG_LEVEL defined in the makefile (or the + * make command line) is greater or equal than the level required for that + * type of log output. + * The format expected is the same as for printf(). For example: + * INFO("Info %s.\n", "message") -> INFO: Info message. + * WARN("Warning %s.\n", "message") -> WARNING: Warning message. + */ + +#define LOG_LEVEL_NONE 0 +#define LOG_LEVEL_ERROR 10 +#define LOG_LEVEL_NOTICE 20 +#define LOG_LEVEL_WARNING 30 +#define LOG_LEVEL_INFO 40 +#define LOG_LEVEL_VERBOSE 50 + + +#if LOG_LEVEL >= LOG_LEVEL_NOTICE +# define NOTICE(...) printf("NOTICE: " __VA_ARGS__) +#else +# define NOTICE(...) +#endif + +#if LOG_LEVEL >= LOG_LEVEL_ERROR +# define ERROR(...) printf("ERROR: " __VA_ARGS__) +#else +# define ERROR(...) +#endif + +#if LOG_LEVEL >= LOG_LEVEL_WARNING +# define WARN(...) printf("WARNING: " __VA_ARGS__) +#else +# define WARN(...) +#endif + +#if LOG_LEVEL >= LOG_LEVEL_INFO +# define INFO(...) printf("INFO: " __VA_ARGS__) +#else +# define INFO(...) +#endif + +#if LOG_LEVEL >= LOG_LEVEL_VERBOSE +# define VERBOSE(...) printf("VERBOSE: " __VA_ARGS__) +#else +# define VERBOSE(...) +#endif + +#endif /* DEBUG_H */ diff --git a/tools/encrypt_fw/include/encrypt.h b/tools/encrypt_fw/include/encrypt.h new file mode 100644 index 000000000..25d301170 --- /dev/null +++ b/tools/encrypt_fw/include/encrypt.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2019, Linaro Limited. All rights reserved. + * Author: Sumit Garg + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef ENCRYPT_H +#define ENCRYPT_H + +/* Supported key algorithms */ +enum { + KEY_ALG_GCM /* AES-GCM (default) */ +}; + +int encrypt_file(unsigned short fw_enc_status, int enc_alg, char *key_string, + char *nonce_string, const char *ip_name, const char *op_name); + +#endif /* ENCRYPT_H */ diff --git a/tools/encrypt_fw/src/cmd_opt.c b/tools/encrypt_fw/src/cmd_opt.c new file mode 100644 index 000000000..64180d1f5 --- /dev/null +++ b/tools/encrypt_fw/src/cmd_opt.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include "debug.h" + +/* Command line options */ +static struct option long_opt[CMD_OPT_MAX_NUM+1]; +static const char *help_msg[CMD_OPT_MAX_NUM+1]; +static int num_reg_opt; + +void cmd_opt_add(const cmd_opt_t *cmd_opt) +{ + assert(cmd_opt != NULL); + + if (num_reg_opt >= CMD_OPT_MAX_NUM) { + ERROR("Out of memory. Please increase CMD_OPT_MAX_NUM\n"); + exit(1); + } + + long_opt[num_reg_opt].name = cmd_opt->long_opt.name; + long_opt[num_reg_opt].has_arg = cmd_opt->long_opt.has_arg; + long_opt[num_reg_opt].flag = 0; + long_opt[num_reg_opt].val = cmd_opt->long_opt.val; + + help_msg[num_reg_opt] = cmd_opt->help_msg; + + num_reg_opt++; +} + +const struct option *cmd_opt_get_array(void) +{ + return long_opt; +} + +const char *cmd_opt_get_name(int idx) +{ + if (idx >= num_reg_opt) { + return NULL; + } + + return long_opt[idx].name; +} + +const char *cmd_opt_get_help_msg(int idx) +{ + if (idx >= num_reg_opt) { + return NULL; + } + + return help_msg[idx]; +} diff --git a/tools/encrypt_fw/src/encrypt.c b/tools/encrypt_fw/src/encrypt.c new file mode 100644 index 000000000..18a514cb9 --- /dev/null +++ b/tools/encrypt_fw/src/encrypt.c @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2019, Linaro Limited. All rights reserved. + * Author: Sumit Garg + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include "debug.h" +#include "encrypt.h" + +#define BUFFER_SIZE 256 +#define IV_SIZE 12 +#define IV_STRING_SIZE 24 +#define TAG_SIZE 16 +#define KEY_SIZE 32 +#define KEY_STRING_SIZE 64 + +static int gcm_encrypt(unsigned short fw_enc_status, char *key_string, + char *nonce_string, const char *ip_name, + const char *op_name) +{ + FILE *ip_file; + FILE *op_file; + EVP_CIPHER_CTX *ctx; + unsigned char data[BUFFER_SIZE], enc_data[BUFFER_SIZE]; + unsigned char key[KEY_SIZE], iv[IV_SIZE], tag[TAG_SIZE]; + int bytes, enc_len = 0, i, j, ret = 0; + struct fw_enc_hdr header; + + memset(&header, 0, sizeof(struct fw_enc_hdr)); + + if (strlen(key_string) != KEY_STRING_SIZE) { + ERROR("Unsupported key size: %lu\n", strlen(key_string)); + return -1; + } + + for (i = 0, j = 0; i < KEY_SIZE; i++, j += 2) { + if (sscanf(&key_string[j], "%02hhx", &key[i]) != 1) { + ERROR("Incorrect key format\n"); + return -1; + } + } + + if (strlen(nonce_string) != IV_STRING_SIZE) { + ERROR("Unsupported IV size: %lu\n", strlen(nonce_string)); + return -1; + } + + for (i = 0, j = 0; i < IV_SIZE; i++, j += 2) { + if (sscanf(&nonce_string[j], "%02hhx", &iv[i]) != 1) { + ERROR("Incorrect IV format\n"); + return -1; + } + } + + ip_file = fopen(ip_name, "rb"); + if (ip_file == NULL) { + ERROR("Cannot read %s\n", ip_name); + return -1; + } + + op_file = fopen(op_name, "wb"); + if (op_file == NULL) { + ERROR("Cannot write %s\n", op_name); + fclose(ip_file); + return -1; + } + + ret = fseek(op_file, sizeof(struct fw_enc_hdr), SEEK_SET); + if (ret) { + ERROR("fseek failed\n"); + goto out_file; + } + + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) { + ERROR("EVP_CIPHER_CTX_new failed\n"); + ret = -1; + goto out_file; + } + + ret = EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL); + if (ret != 1) { + ERROR("EVP_EncryptInit_ex failed\n"); + ret = -1; + goto out; + } + + ret = EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv); + if (ret != 1) { + ERROR("EVP_EncryptInit_ex failed\n"); + goto out; + } + + while ((bytes = fread(data, 1, BUFFER_SIZE, ip_file)) != 0) { + ret = EVP_EncryptUpdate(ctx, enc_data, &enc_len, data, bytes); + if (ret != 1) { + ERROR("EVP_EncryptUpdate failed\n"); + ret = -1; + goto out; + } + + fwrite(enc_data, 1, enc_len, op_file); + } + + ret = EVP_EncryptFinal_ex(ctx, enc_data, &enc_len); + if (ret != 1) { + ERROR("EVP_EncryptFinal_ex failed\n"); + ret = -1; + goto out; + } + + ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, TAG_SIZE, tag); + if (ret != 1) { + ERROR("EVP_CIPHER_CTX_ctrl failed\n"); + ret = -1; + goto out; + } + + header.magic = ENC_HEADER_MAGIC; + header.flags |= fw_enc_status & FW_ENC_STATUS_FLAG_MASK; + header.dec_algo = KEY_ALG_GCM; + header.iv_len = IV_SIZE; + header.tag_len = TAG_SIZE; + memcpy(header.iv, iv, IV_SIZE); + memcpy(header.tag, tag, TAG_SIZE); + + ret = fseek(op_file, 0, SEEK_SET); + if (ret) { + ERROR("fseek failed\n"); + goto out; + } + + fwrite(&header, 1, sizeof(struct fw_enc_hdr), op_file); + +out: + EVP_CIPHER_CTX_free(ctx); + +out_file: + fclose(ip_file); + fclose(op_file); + + /* + * EVP_* APIs returns 1 as success but enctool considers + * 0 as success. + */ + if (ret == 1) + ret = 0; + + return ret; +} + +int encrypt_file(unsigned short fw_enc_status, int enc_alg, char *key_string, + char *nonce_string, const char *ip_name, const char *op_name) +{ + switch (enc_alg) { + case KEY_ALG_GCM: + return gcm_encrypt(fw_enc_status, key_string, nonce_string, + ip_name, op_name); + default: + return -1; + } +} diff --git a/tools/encrypt_fw/src/main.c b/tools/encrypt_fw/src/main.c new file mode 100644 index 000000000..39b7af761 --- /dev/null +++ b/tools/encrypt_fw/src/main.c @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2019, Linaro Limited. All rights reserved. + * Author: Sumit Garg + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "cmd_opt.h" +#include "debug.h" +#include "encrypt.h" +#include "firmware_encrypted.h" + +#define NUM_ELEM(x) ((sizeof(x)) / (sizeof(x[0]))) +#define HELP_OPT_MAX_LEN 128 + +/* Global options */ + +/* Info messages created in the Makefile */ +extern const char build_msg[]; + +static char *key_algs_str[] = { + [KEY_ALG_GCM] = "gcm", +}; + +static void print_help(const char *cmd, const struct option *long_opt) +{ + int rem, i = 0; + const struct option *opt; + char line[HELP_OPT_MAX_LEN]; + char *p; + + assert(cmd != NULL); + assert(long_opt != NULL); + + printf("\n\n"); + printf("The firmware encryption tool loads the binary image and\n" + "outputs encrypted binary image using an encryption key\n" + "provided as an input hex string.\n"); + printf("\n"); + printf("Usage:\n"); + printf("\t%s [OPTIONS]\n\n", cmd); + + printf("Available options:\n"); + opt = long_opt; + while (opt->name) { + p = line; + rem = HELP_OPT_MAX_LEN; + if (isalpha(opt->val)) { + /* Short format */ + sprintf(p, "-%c,", (char)opt->val); + p += 3; + rem -= 3; + } + snprintf(p, rem, "--%s %s", opt->name, + (opt->has_arg == required_argument) ? "" : ""); + printf("\t%-32s %s\n", line, cmd_opt_get_help_msg(i)); + opt++; + i++; + } + printf("\n"); +} + +static int get_key_alg(const char *key_alg_str) +{ + int i; + + for (i = 0 ; i < NUM_ELEM(key_algs_str) ; i++) { + if (strcmp(key_alg_str, key_algs_str[i]) == 0) { + return i; + } + } + + return -1; +} + +static void parse_fw_enc_status_flag(const char *arg, + unsigned short *fw_enc_status) +{ + unsigned long flag; + char *endptr; + + flag = strtoul(arg, &endptr, 16); + if (*endptr != '\0' || flag > FW_ENC_WITH_BSSK) { + ERROR("Invalid fw_enc_status flag '%s'\n", arg); + exit(1); + } + + *fw_enc_status = flag & FW_ENC_STATUS_FLAG_MASK; +} + +/* Common command line options */ +static const cmd_opt_t common_cmd_opt[] = { + { + { "help", no_argument, NULL, 'h' }, + "Print this message and exit" + }, + { + { "fw-enc-status", required_argument, NULL, 'f' }, + "Firmware encryption status flag (with SSK=0 or BSSK=1)." + }, + { + { "key-alg", required_argument, NULL, 'a' }, + "Encryption key algorithm: 'gcm' (default)" + }, + { + { "key", required_argument, NULL, 'k' }, + "Encryption key (for supported algorithm)." + }, + { + { "nonce", required_argument, NULL, 'n' }, + "Nonce or Initialization Vector (for supported algorithm)." + }, + { + { "in", required_argument, NULL, 'i' }, + "Input filename to be encrypted." + }, + { + { "out", required_argument, NULL, 'o' }, + "Encrypted output filename." + }, +}; + +int main(int argc, char *argv[]) +{ + int i, key_alg, ret; + int c, opt_idx = 0; + const struct option *cmd_opt; + char *key = NULL; + char *nonce = NULL; + char *in_fn = NULL; + char *out_fn = NULL; + unsigned short fw_enc_status = 0; + + NOTICE("Firmware Encryption Tool: %s\n", build_msg); + + /* Set default options */ + key_alg = KEY_ALG_GCM; + + /* Add common command line options */ + for (i = 0; i < NUM_ELEM(common_cmd_opt); i++) { + cmd_opt_add(&common_cmd_opt[i]); + } + + /* Get the command line options populated during the initialization */ + cmd_opt = cmd_opt_get_array(); + + while (1) { + /* getopt_long stores the option index here. */ + c = getopt_long(argc, argv, "a:f:hi:k:n:o:", cmd_opt, &opt_idx); + + /* Detect the end of the options. */ + if (c == -1) { + break; + } + + switch (c) { + case 'a': + key_alg = get_key_alg(optarg); + if (key_alg < 0) { + ERROR("Invalid key algorithm '%s'\n", optarg); + exit(1); + } + break; + case 'f': + parse_fw_enc_status_flag(optarg, &fw_enc_status); + break; + case 'k': + key = optarg; + break; + case 'i': + in_fn = optarg; + break; + case 'o': + out_fn = optarg; + break; + case 'n': + nonce = optarg; + break; + case 'h': + print_help(argv[0], cmd_opt); + exit(0); + case '?': + default: + print_help(argv[0], cmd_opt); + exit(1); + } + } + + if (!key) { + ERROR("Key must not be NULL\n"); + exit(1); + } + + if (!nonce) { + ERROR("Nonce must not be NULL\n"); + exit(1); + } + + if (!in_fn) { + ERROR("Input filename must not be NULL\n"); + exit(1); + } + + if (!out_fn) { + ERROR("Output filename must not be NULL\n"); + exit(1); + } + + ret = encrypt_file(fw_enc_status, key_alg, key, nonce, in_fn, out_fn); + + CRYPTO_cleanup_all_ex_data(); + + return ret; +} -- cgit v1.2.3 From c6ba9b4547b58d16b5e0f4ec331ff4422b1f1d66 Mon Sep 17 00:00:00 2001 From: Sumit Garg Date: Thu, 14 Nov 2019 16:33:45 +0530 Subject: Makefile: Add support to optionally encrypt BL31 and BL32 Following build flags have been added to support optional firmware encryption: - FW_ENC_STATUS: Top level firmware's encryption numeric flag, values: 0: Encryption is done with Secret Symmetric Key (SSK) which is common for a class of devices. 1: Encryption is done with Binding Secret Symmetric Key (BSSK) which is unique per device. - ENC_KEY: A 32-byte (256-bit) symmetric key in hex string format. It could be SSK or BSSK depending on FW_ENC_STATUS flag. - ENC_NONCE: A 12-byte (96-bit) encryption nonce or Initialization Vector (IV) in hex string format. - ENCRYPT_BL31: Binary flag to enable encryption of BL31 firmware. - ENCRYPT_BL32: Binary flag to enable encryption of Secure BL32 payload. Similar flags can be added to encrypt other firmwares as well depending on use-cases. Signed-off-by: Sumit Garg Change-Id: I94374d6830ad5908df557f63823e58383d8ad670 --- Makefile | 23 ++++++++++++++++++++++ make_helpers/build_macros.mk | 45 +++++++++++++++++++++++++++++++++++++++++--- make_helpers/defaults.mk | 15 +++++++++++++++ 3 files changed, 80 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 8f50d7c8d..3d5b39502 100644 --- a/Makefile +++ b/Makefile @@ -159,6 +159,14 @@ else endif endif +ifneq (${DECRYPTION_SUPPORT},none) +ENC_ARGS += -f ${FW_ENC_STATUS} +ENC_ARGS += -k ${ENC_KEY} +ENC_ARGS += -n ${ENC_NONCE} +FIP_DEPS += enctool +FWU_FIP_DEPS += enctool +endif + ################################################################################ # Toolchain ################################################################################ @@ -826,10 +834,13 @@ $(eval $(call assert_boolean,BL2_AT_EL3)) $(eval $(call assert_boolean,BL2_IN_XIP_MEM)) $(eval $(call assert_boolean,BL2_INV_DCACHE)) $(eval $(call assert_boolean,USE_SPINLOCK_CAS)) +$(eval $(call assert_boolean,ENCRYPT_BL31)) +$(eval $(call assert_boolean,ENCRYPT_BL32)) $(eval $(call assert_numeric,ARM_ARCH_MAJOR)) $(eval $(call assert_numeric,ARM_ARCH_MINOR)) $(eval $(call assert_numeric,BRANCH_PROTECTION)) +$(eval $(call assert_numeric,FW_ENC_STATUS)) ifdef KEY_SIZE $(eval $(call assert_numeric,KEY_SIZE)) @@ -867,6 +878,8 @@ $(eval $(call add_define,ENABLE_PSCI_STAT)) $(eval $(call add_define,ENABLE_RUNTIME_INSTRUMENTATION)) $(eval $(call add_define,ENABLE_SPE_FOR_LOWER_ELS)) $(eval $(call add_define,ENABLE_SVE_FOR_NS)) +$(eval $(call add_define,ENCRYPT_BL31)) +$(eval $(call add_define,ENCRYPT_BL32)) $(eval $(call add_define,ERROR_DEPRECATED)) $(eval $(call add_define,FAULT_INJECTION_SUPPORT)) $(eval $(call add_define,GICV2_G0_FOR_EL3)) @@ -987,9 +1000,14 @@ endif ifeq (${NEED_BL31},yes) BL31_SOURCES += ${SPD_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)))) +else $(if ${BL31}, $(eval $(call TOOL_ADD_IMG,bl31,--soc-fw)),\ $(eval $(call MAKE_BL,31,soc-fw))) endif +endif # If a BL32 image is needed but neither BL32 nor BL32_SOURCES is defined, the # build system will call TOOL_ADD_IMG to print a warning message and abort the @@ -998,9 +1016,14 @@ ifeq (${NEED_BL32},yes) BUILD_BL32 := $(if $(BL32),,$(if $(BL32_SOURCES),1)) +ifneq (${DECRYPTION_SUPPORT},none) +$(if ${BUILD_BL32}, $(eval $(call MAKE_BL,32,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)),\ $(eval $(call TOOL_ADD_IMG,bl32,--tos-fw))) endif +endif # Add the BL33 image if required by the platform ifeq (${NEED_BL33},yes) diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk index 032e42c15..20a36fe08 100644 --- a/make_helpers/build_macros.mk +++ b/make_helpers/build_macros.mk @@ -109,6 +109,22 @@ define IMG_BIN ${BUILD_PLAT}/bl$(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) +define IMG_ENC_BIN + ${BUILD_PLAT}/bl$(1)_enc.bin +endef + +# ENCRYPT_FW invokes enctool to encrypt firmware binary +# $(1) = input firmware binary +# $(2) = output encrypted firmware binary +define ENCRYPT_FW +$(2): $(1) enctool + $$(ECHO) " ENC $$<" + $$(Q)$$(ENCTOOL) $$(ENC_ARGS) -i $$< -o $$@ +endef + # TOOL_ADD_PAYLOAD appends the command line arguments required by fiptool to # package a new payload and/or by cert_create to generate certificate. # Optionally, it adds the dependency on this payload @@ -116,11 +132,17 @@ endef # $(2) = command line option for the specified payload (i.e. --soc-fw) # $(3) = tool target dependency (optional) (ex. build/fvp/release/bl31.bin) # $(4) = FIP prefix (optional) (if FWU_, target is fwu_fip instead of fip) +# $(5) = encrypted payload (optional) (ex. build/fvp/release/bl31_enc.bin) define TOOL_ADD_PAYLOAD +ifneq ($(5),) + $(4)FIP_ARGS += $(2) $(5) + $(if $(3),$(4)CRT_DEPS += $(1)) +else $(4)FIP_ARGS += $(2) $(1) + $(if $(3),$(4)CRT_DEPS += $(3)) +endif $(if $(3),$(4)FIP_DEPS += $(3)) $(4)CRT_ARGS += $(2) $(1) - $(if $(3),$(4)CRT_DEPS += $(3)) endef # TOOL_ADD_IMG_PAYLOAD works like TOOL_ADD_PAYLOAD, but applies image filters @@ -130,6 +152,7 @@ endef # $(3) = command line option for the specified payload (ex. --soc-fw) # $(4) = tool target dependency (optional) (ex. build/fvp/release/bl31.bin) # $(5) = FIP prefix (optional) (if FWU_, target is fwu_fip instead of fip) +# $(6) = encrypted payload (optional) (ex. build/fvp/release/bl31_enc.bin) define TOOL_ADD_IMG_PAYLOAD @@ -143,10 +166,10 @@ $(call $(PRE_TOOL_FILTER)_RULE,$(PROCESSED_PATH),$(2)) $(PROCESSED_PATH): $(4) -$(call TOOL_ADD_PAYLOAD,$(PROCESSED_PATH),$(3),$(PROCESSED_PATH),$(5)) +$(call TOOL_ADD_PAYLOAD,$(PROCESSED_PATH),$(3),$(PROCESSED_PATH),$(5),$(6)) else -$(call TOOL_ADD_PAYLOAD,$(2),$(3),$(4),$(5)) +$(call TOOL_ADD_PAYLOAD,$(2),$(3),$(4),$(5),$(6)) endif endef @@ -164,6 +187,7 @@ endef # $(1) = image_type (scp_bl2, bl33, etc.) # $(2) = command line option for fiptool (--scp-fw, --nt-fw, etc) # $(3) = FIP prefix (optional) (if FWU_, target is fwu_fip instead of fip) +# $(4) = Image encryption flag (optional) (0, 1) # Example: # $(eval $(call TOOL_ADD_IMG,bl33,--nt-fw)) define TOOL_ADD_IMG @@ -173,7 +197,14 @@ define TOOL_ADD_IMG $(3)CRT_DEPS += check_$(1) $(3)FIP_DEPS += check_$(1) +ifeq ($(4),1) + $(eval ENC_BIN := ${BUILD_PLAT}/$(1)_enc.bin) + $(call ENCRYPT_FW,$(value $(_V)),$(ENC_BIN)) + $(call TOOL_ADD_IMG_PAYLOAD,$(1),$(value $(_V)),$(2),$(ENC_BIN),$(3), \ + $(ENC_BIN)) +else $(call TOOL_ADD_IMG_PAYLOAD,$(1),$(value $(_V)),$(2),,$(3)) +endif .PHONY: check_$(1) check_$(1): @@ -390,6 +421,7 @@ endef # $(1) = BL stage (1, 2, 2u, 31, 32) # $(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)) @@ -400,6 +432,7 @@ define MAKE_BL $(eval ELF := $(call IMG_ELF,$(1))) $(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)) # We use sort only to get a list of unique object directory names. @@ -480,7 +513,13 @@ endif all: bl$(1) +ifeq ($(4),1) +$(call ENCRYPT_FW,$(BIN),$(ENC_BIN)) +$(if $(2),$(call TOOL_ADD_IMG_PAYLOAD,bl$(1),$(BIN),--$(2),$(ENC_BIN),$(3), \ + $(ENC_BIN))) +else $(if $(2),$(call TOOL_ADD_IMG_PAYLOAD,bl$(1),$(BIN),--$(2),$(BIN),$(3))) +endif endef diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index 012760733..03322db19 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -109,6 +109,18 @@ ENABLE_BTI := 0 # Use BRANCH_PROTECTION to enable PAUTH. ENABLE_PAUTH := 0 +# By default BL31 encryption disabled +ENCRYPT_BL31 := 0 + +# By default BL32 encryption disabled +ENCRYPT_BL32 := 0 + +# Default dummy firmware encryption key +ENC_KEY := 1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef + +# Default dummy nonce for firmware encryption +ENC_NONCE := 1234567890abcdef12345678 + # Build flag to treat usage of deprecated platform and framework APIs as error. ERROR_DEPRECATED := 0 @@ -124,6 +136,9 @@ FIP_NAME := fip.bin # Default FWU_FIP file name FWU_FIP_NAME := fwu_fip.bin +# By default firmware encryption with SSK +FW_ENC_STATUS := 0 + # For Chain of Trust GENERATE_COT := 0 -- cgit v1.2.3 From a886bbeceb0daf7b0a8436c9fdff6c679e9d7532 Mon Sep 17 00:00:00 2001 From: Sumit Garg Date: Thu, 14 Nov 2019 17:34:09 +0530 Subject: qemu: Update flash address map to keep FIP in secure FLASH0 Secure FLASH0 memory map looks like: - Offset: 0 to 256K -> bl1.bin - Offset: 256K to 4.25M -> fip.bin FLASH1 is normally used via UEFI/edk2 to keep varstore. Signed-off-by: Sumit Garg Change-Id: I6883f556c22d6a5d3fa3846c703bebc2abe36765 --- plat/qemu/qemu/include/platform_def.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plat/qemu/qemu/include/platform_def.h b/plat/qemu/qemu/include/platform_def.h index cce992ff9..4abd77ebc 100644 --- a/plat/qemu/qemu/include/platform_def.h +++ b/plat/qemu/qemu/include/platform_def.h @@ -196,8 +196,8 @@ #define QEMU_FLASH1_BASE 0x04000000 #define QEMU_FLASH1_SIZE 0x04000000 -#define PLAT_QEMU_FIP_BASE QEMU_FLASH1_BASE -#define PLAT_QEMU_FIP_MAX_SIZE QEMU_FLASH1_SIZE +#define PLAT_QEMU_FIP_BASE 0x00040000 +#define PLAT_QEMU_FIP_MAX_SIZE 0x00400000 #define DEVICE0_BASE 0x08000000 #define DEVICE0_SIZE 0x01000000 -- cgit v1.2.3 From 518577627e5c7f009094eb0ef8fdc24a200d2ffb Mon Sep 17 00:00:00 2001 From: Sumit Garg Date: Thu, 14 Nov 2019 17:34:56 +0530 Subject: qemu: Support optional encryption of BL31 and BL32 images Enable encryption IO layer to be stacked above FIP IO layer for optional encryption of Bl31 and BL32 images in case ENCRYPT_BL31 or ENCRYPT_BL32 build flag is set. Signed-off-by: Sumit Garg Change-Id: I24cba64728861e833abffc3d5d9807599c49feb6 --- plat/qemu/common/qemu_io_storage.c | 71 +++++++++++++++++++++++++++++++++-- plat/qemu/qemu/include/platform_def.h | 2 +- plat/qemu/qemu/platform.mk | 13 +++++++ 3 files changed, 82 insertions(+), 4 deletions(-) diff --git a/plat/qemu/common/qemu_io_storage.c b/plat/qemu/common/qemu_io_storage.c index 0e81cd199..1107e443f 100644 --- a/plat/qemu/common/qemu_io_storage.c +++ b/plat/qemu/common/qemu_io_storage.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -47,6 +48,10 @@ static const io_dev_connector_t *memmap_dev_con; static uintptr_t memmap_dev_handle; static const io_dev_connector_t *sh_dev_con; static uintptr_t sh_dev_handle; +#ifndef DECRYPTION_SUPPORT_none +static const io_dev_connector_t *enc_dev_con; +static uintptr_t enc_dev_handle; +#endif static const io_block_spec_t fip_block_spec = { .offset = PLAT_QEMU_FIP_BASE, @@ -172,10 +177,11 @@ static const io_file_spec_t sh_file_spec[] = { #endif /* TRUSTED_BOARD_BOOT */ }; - - static int open_fip(const uintptr_t spec); static int open_memmap(const uintptr_t spec); +#ifndef DECRYPTION_SUPPORT_none +static int open_enc_fip(const uintptr_t spec); +#endif struct plat_io_policy { uintptr_t *dev_handle; @@ -190,16 +196,46 @@ static const struct plat_io_policy policies[] = { (uintptr_t)&fip_block_spec, open_memmap }, + [ENC_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)NULL, + open_fip + }, [BL2_IMAGE_ID] = { &fip_dev_handle, (uintptr_t)&bl2_uuid_spec, open_fip }, +#if ENCRYPT_BL31 && !defined(DECRYPTION_SUPPORT_none) + [BL31_IMAGE_ID] = { + &enc_dev_handle, + (uintptr_t)&bl31_uuid_spec, + open_enc_fip + }, +#else [BL31_IMAGE_ID] = { &fip_dev_handle, (uintptr_t)&bl31_uuid_spec, open_fip }, +#endif +#if ENCRYPT_BL32 && !defined(DECRYPTION_SUPPORT_none) + [BL32_IMAGE_ID] = { + &enc_dev_handle, + (uintptr_t)&bl32_uuid_spec, + open_enc_fip + }, + [BL32_EXTRA1_IMAGE_ID] = { + &enc_dev_handle, + (uintptr_t)&bl32_extra1_uuid_spec, + open_enc_fip + }, + [BL32_EXTRA2_IMAGE_ID] = { + &enc_dev_handle, + (uintptr_t)&bl32_extra2_uuid_spec, + open_enc_fip + }, +#else [BL32_IMAGE_ID] = { &fip_dev_handle, (uintptr_t)&bl32_uuid_spec, @@ -215,6 +251,7 @@ static const struct plat_io_policy policies[] = { (uintptr_t)&bl32_extra2_uuid_spec, open_fip }, +#endif [BL33_IMAGE_ID] = { &fip_dev_handle, (uintptr_t)&bl33_uuid_spec, @@ -271,7 +308,7 @@ static int open_fip(const uintptr_t spec) /* See if a Firmware Image Package is available */ result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); - if (result == 0) { + if (result == 0 && spec != (uintptr_t)NULL) { result = io_open(fip_dev_handle, spec, &local_image_handle); if (result == 0) { VERBOSE("Using FIP\n"); @@ -281,6 +318,25 @@ static int open_fip(const uintptr_t spec) return result; } +#ifndef DECRYPTION_SUPPORT_none +static int open_enc_fip(const uintptr_t spec) +{ + int result; + uintptr_t local_image_handle; + + /* See if an encrypted FIP is available */ + result = io_dev_init(enc_dev_handle, (uintptr_t)ENC_IMAGE_ID); + if (result == 0) { + result = io_open(enc_dev_handle, spec, &local_image_handle); + if (result == 0) { + VERBOSE("Using encrypted FIP\n"); + io_close(local_image_handle); + } + } + return result; +} +#endif + static int open_memmap(const uintptr_t spec) { int result; @@ -333,6 +389,15 @@ void plat_qemu_io_setup(void) &memmap_dev_handle); assert(io_result == 0); +#ifndef DECRYPTION_SUPPORT_none + io_result = register_io_dev_enc(&enc_dev_con); + assert(io_result == 0); + + io_result = io_dev_open(enc_dev_con, (uintptr_t)NULL, + &enc_dev_handle); + assert(io_result == 0); +#endif + /* Register the additional IO devices on this platform */ io_result = register_io_dev_sh(&sh_dev_con); assert(io_result == 0); diff --git a/plat/qemu/qemu/include/platform_def.h b/plat/qemu/qemu/include/platform_def.h index 4abd77ebc..ed4b748af 100644 --- a/plat/qemu/qemu/include/platform_def.h +++ b/plat/qemu/qemu/include/platform_def.h @@ -172,7 +172,7 @@ #define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) #define MAX_MMAP_REGIONS 11 #define MAX_XLAT_TABLES 6 -#define MAX_IO_DEVICES 3 +#define MAX_IO_DEVICES 4 #define MAX_IO_HANDLES 4 /* diff --git a/plat/qemu/qemu/platform.mk b/plat/qemu/qemu/platform.mk index bc10569ba..928d69a71 100644 --- a/plat/qemu/qemu/platform.mk +++ b/plat/qemu/qemu/platform.mk @@ -128,6 +128,11 @@ ifeq ($(add-lib-optee),yes) BL2_SOURCES += lib/optee/optee_utils.c endif +ifneq (${DECRYPTION_SUPPORT},none) +BL1_SOURCES += drivers/io/io_encrypted.c +BL2_SOURCES += drivers/io/io_encrypted.c +endif + QEMU_GICV2_SOURCES := drivers/arm/gic/v2/gicv2_helpers.c \ drivers/arm/gic/v2/gicv2_main.c \ drivers/arm/gic/common/gic_common.c \ @@ -165,11 +170,19 @@ endif # Add the build options to pack Trusted OS Extra1 and Trusted OS Extra2 images # in the FIP if the platform requires. ifneq ($(BL32_EXTRA1),) +ifneq (${DECRYPTION_SUPPORT},none) +$(eval $(call TOOL_ADD_IMG,bl32_extra1,--tos-fw-extra1,,$(ENCRYPT_BL32))) +else $(eval $(call TOOL_ADD_IMG,bl32_extra1,--tos-fw-extra1)) endif +endif ifneq ($(BL32_EXTRA2),) +ifneq (${DECRYPTION_SUPPORT},none) +$(eval $(call TOOL_ADD_IMG,bl32_extra2,--tos-fw-extra2,,$(ENCRYPT_BL32))) +else $(eval $(call TOOL_ADD_IMG,bl32_extra2,--tos-fw-extra2)) endif +endif SEPARATE_CODE_AND_RODATA := 1 ENABLE_STACK_PROTECTOR := 0 -- cgit v1.2.3 From 548654bc0313019ad9c6141734af0ef01b659163 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 6 Mar 2020 20:11:23 +0900 Subject: uniphier: shrink UNIPHIER_ROM_REGION_SIZE Currently, the ROM region is needlessly too large. The on-chip SRAM region of the next SoC will start from 0x04000000, and this will cause the region overlap. Mapping 0x04000000 for the ROM is enough. Change-Id: I85ce0bb1120ebff2e3bc7fd13dc0fd15dfff5ff6 Signed-off-by: Masahiro Yamada --- plat/socionext/uniphier/uniphier_io_storage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/socionext/uniphier/uniphier_io_storage.c b/plat/socionext/uniphier/uniphier_io_storage.c index e89c8358c..77d1eaf00 100644 --- a/plat/socionext/uniphier/uniphier_io_storage.c +++ b/plat/socionext/uniphier/uniphier_io_storage.c @@ -21,7 +21,7 @@ #include "uniphier.h" #define UNIPHIER_ROM_REGION_BASE 0x00000000ULL -#define UNIPHIER_ROM_REGION_SIZE 0x10000000ULL +#define UNIPHIER_ROM_REGION_SIZE 0x04000000ULL #define UNIPHIER_OCM_REGION_SIZE 0x00040000ULL -- cgit v1.2.3 From b4292bc65eafcd36ad72d4301c12461184579bb6 Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Tue, 3 Mar 2020 13:31:58 +0000 Subject: Fix crash dump for lower EL This patch provides a fix for incorrect crash dump data for lower EL when TF-A is built with HANDLE_EA_EL3_FIRST=1 option which enables routing of External Aborts and SErrors to EL3. Change-Id: I9d5e6775e6aad21db5b78362da6c3a3d897df977 Signed-off-by: Alexei Fedorov --- bl31/aarch64/crash_reporting.S | 130 +++++++++++++++++++++++++--- common/aarch64/debug.S | 24 +++++- common/backtrace/backtrace.c | 2 +- docs/design/firmware-design.rst | 175 +++++++++++++++++++++----------------- include/arch/aarch64/arch.h | 6 +- include/common/debug.h | 3 +- plat/common/aarch64/plat_common.c | 28 +++++- 7 files changed, 269 insertions(+), 99 deletions(-) diff --git a/bl31/aarch64/crash_reporting.S b/bl31/aarch64/crash_reporting.S index 97db2a167..d56b513b8 100644 --- a/bl31/aarch64/crash_reporting.S +++ b/bl31/aarch64/crash_reporting.S @@ -16,6 +16,7 @@ .globl report_unhandled_exception .globl report_unhandled_interrupt .globl el3_panic + .globl elx_panic #if CRASH_REPORTING @@ -59,7 +60,11 @@ panic_msg: excpt_msg: .asciz "Unhandled Exception in EL3.\nx30" intr_excpt_msg: - .asciz "Unhandled Interrupt Exception in EL3.\nx30" + .ascii "Unhandled Interrupt Exception in EL3.\n" +x30_msg: + .asciz "x30" +excpt_msg_el: + .asciz "Unhandled Exception from EL" /* * Helper function to print from crash buf. @@ -170,7 +175,6 @@ func report_unhandled_exception b do_crash_reporting endfunc report_unhandled_exception - /* ----------------------------------------------------- * This function allows to report a crash (if crash * reporting is enabled) when an unhandled interrupt @@ -187,6 +191,112 @@ func report_unhandled_interrupt b do_crash_reporting endfunc report_unhandled_interrupt + /* ----------------------------------------------------- + * This function allows to report a crash from the lower + * exception level (if crash reporting is enabled) when + * panic() is invoked from C Runtime. + * It prints the CPU state via the crash console making + * use of 'cpu_context' structure where general purpose + * registers are saved and the crash buf. + * This function will not return. + * + * x0: Exception level + * ----------------------------------------------------- + */ +func elx_panic + msr spsel, #MODE_SP_ELX + mov x8, x0 + + /* Print the crash message */ + adr x4, excpt_msg_el + bl asm_print_str + + /* Print exception level */ + add x0, x8, #'0' + bl plat_crash_console_putc + bl asm_print_newline + + /* Report x0 - x29 values stored in 'gpregs_ctx' structure */ + /* Store the ascii list pointer in x6 */ + adr x6, gp_regs + add x7, sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0 + +print_next: + ldrb w4, [x6] + /* Test whether we are at end of list */ + cbz w4, print_x30 + mov x4, x6 + /* asm_print_str updates x4 to point to next entry in list */ + bl asm_print_str + /* x0 = number of symbols printed + 1 */ + sub x0, x4, x6 + /* Update x6 with the updated list pointer */ + mov x6, x4 + bl print_alignment + ldr x4, [x7], #REGSZ + bl asm_print_hex + bl asm_print_newline + b print_next + +print_x30: + adr x4, x30_msg + bl asm_print_str + + /* Print spaces to align "x30" string */ + mov x0, #4 + bl print_alignment + + /* Report x30 */ + ldr x4, [x7] + + /* ---------------------------------------------------------------- + * Different virtual address space size can be defined for each EL. + * Ensure that we use the proper one by reading the corresponding + * TCR_ELx register. + * ---------------------------------------------------------------- + */ + cmp x8, #MODE_EL2 + b.lt from_el1 /* EL1 */ + mrs x2, sctlr_el2 + mrs x1, tcr_el2 + + /* ---------------------------------------------------------------- + * Check if pointer authentication is enabled at the specified EL. + * If it isn't, we can then skip stripping a PAC code. + * ---------------------------------------------------------------- + */ +test_pauth: + tst x2, #(SCTLR_EnIA_BIT | SCTLR_EnIB_BIT) + b.eq no_pauth + + /* Demangle address */ + and x1, x1, #0x3F /* T0SZ = TCR_ELx[5:0] */ + sub x1, x1, #64 + neg x1, x1 /* bottom_pac_bit = 64 - T0SZ */ + mov x2, #-1 + lsl x2, x2, x1 + bic x4, x4, x2 + +no_pauth: + bl asm_print_hex + bl asm_print_newline + + /* tpidr_el3 contains the address to cpu_data structure */ + mrs x0, tpidr_el3 + /* Calculate the Crash buffer offset in cpu_data */ + add x0, x0, #CPU_DATA_CRASH_BUF_OFFSET + /* Store crash buffer address in tpidr_el3 */ + msr tpidr_el3, x0 + + /* Print the rest of crash dump */ + b print_el3_sys_regs + +from_el1: + mrs x2, sctlr_el1 + mrs x1, tcr_el1 + b test_pauth +endfunc elx_panic + /* ----------------------------------------------------- * This function allows to report a crash (if crash * reporting is enabled) when panic() is invoked from @@ -200,9 +310,7 @@ func el3_panic prepare_crash_buf_save_x0_x1 adr x0, panic_msg mov sp, x0 - /* This call will not return */ - b do_crash_reporting -endfunc el3_panic + /* Fall through to 'do_crash_reporting' */ /* ------------------------------------------------------------ * The common crash reporting functionality. It requires x0 @@ -223,7 +331,7 @@ endfunc el3_panic * the crash buf to the crash console. * ------------------------------------------------------------ */ -func do_crash_reporting +do_crash_reporting: /* Retrieve the crash buf from tpidr_el3 */ mrs x0, tpidr_el3 /* Store x2 - x6, x30 in the crash buffer */ @@ -240,9 +348,9 @@ func do_crash_reporting /* Print spaces to align "x30" string */ mov x0, #4 bl print_alignment - /* load the crash buf address */ + /* Load the crash buf address */ mrs x0, tpidr_el3 - /* report x30 first from the crash buf */ + /* Report x30 first from the crash buf */ ldr x4, [x0, #REGSZ * 7] #if ENABLE_PAUTH @@ -256,7 +364,7 @@ func do_crash_reporting /* Now mov x7 into crash buf */ str x7, [x0, #REGSZ * 7] - /* Report x0 - x29 values stored in crash buf*/ + /* Report x0 - x29 values stored in crash buf */ /* Store the ascii list pointer in x6 */ adr x6, gp_regs /* Print x0 to x7 from the crash buf */ @@ -279,6 +387,7 @@ func do_crash_reporting bl size_controlled_print /* Print the el3 sys registers */ +print_el3_sys_regs: adr x6, el3_sys_regs mrs x8, scr_el3 mrs x9, sctlr_el3 @@ -354,7 +463,7 @@ func do_crash_reporting /* Done reporting */ no_ret plat_panic_handler -endfunc do_crash_reporting +endfunc el3_panic #else /* CRASH_REPORTING */ func report_unhandled_exception @@ -363,7 +472,6 @@ report_unhandled_interrupt: endfunc report_unhandled_exception #endif /* CRASH_REPORTING */ - func crash_panic no_ret plat_panic_handler endfunc crash_panic diff --git a/common/aarch64/debug.S b/common/aarch64/debug.S index e6e329853..7db24396e 100644 --- a/common/aarch64/debug.S +++ b/common/aarch64/debug.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -156,16 +156,32 @@ endfunc asm_print_newline /* This is for the non el3 BL stages to compile through */ .weak el3_panic + .weak elx_panic func do_panic #if CRASH_REPORTING str x0, [sp, #-0x10]! mrs x0, currentel - ubfx x0, x0, #2, #2 - cmp x0, #0x3 + ubfx x0, x0, #MODE_EL_SHIFT, #MODE_EL_WIDTH + cmp x0, #MODE_EL3 +#if !HANDLE_EA_EL3_FIRST ldr x0, [sp], #0x10 b.eq el3_panic -#endif +#else + b.ne to_panic_common + + /* Check EL the exception taken from */ + mrs x0, spsr_el3 + ubfx x0, x0, #SPSR_EL_SHIFT, #SPSR_EL_WIDTH + cmp x0, #MODE_EL3 + b.ne elx_panic + ldr x0, [sp], #0x10 + b el3_panic + +to_panic_common: + ldr x0, [sp], #0x10 +#endif /* HANDLE_EA_EL3_FIRST */ +#endif /* CRASH_REPORTING */ panic_common: /* diff --git a/common/backtrace/backtrace.c b/common/backtrace/backtrace.c index 907117f36..ef575006f 100644 --- a/common/backtrace/backtrace.c +++ b/common/backtrace/backtrace.c @@ -37,7 +37,7 @@ struct frame_record { uintptr_t return_addr; }; -static const char *get_el_str(unsigned int el) +const char *get_el_str(unsigned int el) { if (el == 3U) { return "EL3"; diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst index d0d6ef697..8297dc785 100644 --- a/docs/design/firmware-design.rst +++ b/docs/design/firmware-design.rst @@ -1177,83 +1177,104 @@ The sample crash output is shown below. :: - x0 :0x000000004F00007C - x1 :0x0000000007FFFFFF - x2 :0x0000000004014D50 - x3 :0x0000000000000000 - x4 :0x0000000088007998 - x5 :0x00000000001343AC - x6 :0x0000000000000016 - x7 :0x00000000000B8A38 - x8 :0x00000000001343AC - x9 :0x00000000000101A8 - x10 :0x0000000000000002 - x11 :0x000000000000011C - x12 :0x00000000FEFDC644 - x13 :0x00000000FED93FFC - x14 :0x0000000000247950 - x15 :0x00000000000007A2 - x16 :0x00000000000007A4 - x17 :0x0000000000247950 - x18 :0x0000000000000000 - x19 :0x00000000FFFFFFFF - x20 :0x0000000004014D50 - x21 :0x000000000400A38C - x22 :0x0000000000247950 - x23 :0x0000000000000010 - x24 :0x0000000000000024 - x25 :0x00000000FEFDC868 - x26 :0x00000000FEFDC86A - x27 :0x00000000019EDEDC - x28 :0x000000000A7CFDAA - x29 :0x0000000004010780 - x30 :0x000000000400F004 - scr_el3 :0x0000000000000D3D - sctlr_el3 :0x0000000000C8181F - cptr_el3 :0x0000000000000000 - tcr_el3 :0x0000000080803520 - daif :0x00000000000003C0 - mair_el3 :0x00000000000004FF - spsr_el3 :0x00000000800003CC - elr_el3 :0x000000000400C0CC - ttbr0_el3 :0x00000000040172A0 - esr_el3 :0x0000000096000210 - sp_el3 :0x0000000004014D50 - far_el3 :0x000000004F00007C - spsr_el1 :0x0000000000000000 - elr_el1 :0x0000000000000000 - spsr_abt :0x0000000000000000 - spsr_und :0x0000000000000000 - spsr_irq :0x0000000000000000 - spsr_fiq :0x0000000000000000 - sctlr_el1 :0x0000000030C81807 - actlr_el1 :0x0000000000000000 - cpacr_el1 :0x0000000000300000 - csselr_el1 :0x0000000000000002 - sp_el1 :0x0000000004028800 - esr_el1 :0x0000000000000000 - ttbr0_el1 :0x000000000402C200 - ttbr1_el1 :0x0000000000000000 - mair_el1 :0x00000000000004FF - amair_el1 :0x0000000000000000 - tcr_el1 :0x0000000000003520 - tpidr_el1 :0x0000000000000000 - tpidr_el0 :0x0000000000000000 - tpidrro_el0 :0x0000000000000000 - dacr32_el2 :0x0000000000000000 - ifsr32_el2 :0x0000000000000000 - par_el1 :0x0000000000000000 - far_el1 :0x0000000000000000 - afsr0_el1 :0x0000000000000000 - afsr1_el1 :0x0000000000000000 - contextidr_el1 :0x0000000000000000 - vbar_el1 :0x0000000004027000 - cntp_ctl_el0 :0x0000000000000000 - cntp_cval_el0 :0x0000000000000000 - cntv_ctl_el0 :0x0000000000000000 - cntv_cval_el0 :0x0000000000000000 - cntkctl_el1 :0x0000000000000000 - sp_el0 :0x0000000004010780 + x0 = 0x000000002a4a0000 + x1 = 0x0000000000000001 + x2 = 0x0000000000000002 + x3 = 0x0000000000000003 + x4 = 0x0000000000000004 + x5 = 0x0000000000000005 + x6 = 0x0000000000000006 + x7 = 0x0000000000000007 + x8 = 0x0000000000000008 + x9 = 0x0000000000000009 + x10 = 0x0000000000000010 + x11 = 0x0000000000000011 + x12 = 0x0000000000000012 + x13 = 0x0000000000000013 + x14 = 0x0000000000000014 + x15 = 0x0000000000000015 + x16 = 0x0000000000000016 + x17 = 0x0000000000000017 + x18 = 0x0000000000000018 + x19 = 0x0000000000000019 + x20 = 0x0000000000000020 + x21 = 0x0000000000000021 + x22 = 0x0000000000000022 + x23 = 0x0000000000000023 + x24 = 0x0000000000000024 + x25 = 0x0000000000000025 + x26 = 0x0000000000000026 + x27 = 0x0000000000000027 + x28 = 0x0000000000000028 + x29 = 0x0000000000000029 + x30 = 0x0000000088000b78 + scr_el3 = 0x000000000003073d + sctlr_el3 = 0x00000000b0cd183f + cptr_el3 = 0x0000000000000000 + tcr_el3 = 0x000000008080351c + daif = 0x00000000000002c0 + mair_el3 = 0x00000000004404ff + spsr_el3 = 0x0000000060000349 + elr_el3 = 0x0000000088000114 + ttbr0_el3 = 0x0000000004018201 + esr_el3 = 0x00000000be000000 + far_el3 = 0x0000000000000000 + spsr_el1 = 0x0000000000000000 + elr_el1 = 0x0000000000000000 + spsr_abt = 0x0000000000000000 + spsr_und = 0x0000000000000000 + spsr_irq = 0x0000000000000000 + spsr_fiq = 0x0000000000000000 + sctlr_el1 = 0x0000000030d00800 + actlr_el1 = 0x0000000000000000 + cpacr_el1 = 0x0000000000000000 + csselr_el1 = 0x0000000000000000 + sp_el1 = 0x0000000000000000 + esr_el1 = 0x0000000000000000 + ttbr0_el1 = 0x0000000000000000 + ttbr1_el1 = 0x0000000000000000 + mair_el1 = 0x0000000000000000 + amair_el1 = 0x0000000000000000 + tcr_el1 = 0x0000000000000000 + tpidr_el1 = 0x0000000000000000 + tpidr_el0 = 0x0000000000000000 + tpidrro_el0 = 0x0000000000000000 + par_el1 = 0x0000000000000000 + mpidr_el1 = 0x0000000080000000 + afsr0_el1 = 0x0000000000000000 + afsr1_el1 = 0x0000000000000000 + contextidr_el1 = 0x0000000000000000 + vbar_el1 = 0x0000000000000000 + cntp_ctl_el0 = 0x0000000000000000 + cntp_cval_el0 = 0x0000000000000000 + cntv_ctl_el0 = 0x0000000000000000 + cntv_cval_el0 = 0x0000000000000000 + cntkctl_el1 = 0x0000000000000000 + sp_el0 = 0x0000000004014940 + isr_el1 = 0x0000000000000000 + dacr32_el2 = 0x0000000000000000 + ifsr32_el2 = 0x0000000000000000 + icc_hppir0_el1 = 0x00000000000003ff + icc_hppir1_el1 = 0x00000000000003ff + icc_ctlr_el3 = 0x0000000000080400 + gicd_ispendr regs (Offsets 0x200-0x278) + Offset Value + 0x200: 0x0000000000000000 + 0x208: 0x0000000000000000 + 0x210: 0x0000000000000000 + 0x218: 0x0000000000000000 + 0x220: 0x0000000000000000 + 0x228: 0x0000000000000000 + 0x230: 0x0000000000000000 + 0x238: 0x0000000000000000 + 0x240: 0x0000000000000000 + 0x248: 0x0000000000000000 + 0x250: 0x0000000000000000 + 0x258: 0x0000000000000000 + 0x260: 0x0000000000000000 + 0x268: 0x0000000000000000 + 0x270: 0x0000000000000000 + 0x278: 0x0000000000000000 Guidelines for Reset Handlers ----------------------------- diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index b0c265047..2b2c11652 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -452,6 +452,9 @@ #define SPSR_M_AARCH64 U(0x0) #define SPSR_M_AARCH32 U(0x1) +#define SPSR_EL_SHIFT U(2) +#define SPSR_EL_WIDTH U(2) + #define SPSR_SSBS_BIT_AARCH64 BIT_64(12) #define SPSR_SSBS_BIT_AARCH32 BIT_64(23) @@ -557,6 +560,7 @@ #define MODE_EL_SHIFT U(0x2) #define MODE_EL_MASK U(0x3) +#define MODE_EL_WIDTH U(0x2) #define MODE_EL3 U(0x3) #define MODE_EL2 U(0x2) #define MODE_EL1 U(0x1) diff --git a/include/common/debug.h b/include/common/debug.h index 245e69865..9aef15b51 100644 --- a/include/common/debug.h +++ b/include/common/debug.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -91,6 +91,7 @@ #if ENABLE_BACKTRACE void backtrace(const char *cookie); +const char *get_el_str(unsigned int el); #else #define backtrace(x) #endif diff --git a/plat/common/aarch64/plat_common.c b/plat/common/aarch64/plat_common.c index f8d312952..63871d9e5 100644 --- a/plat/common/aarch64/plat_common.c +++ b/plat/common/aarch64/plat_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -64,6 +64,18 @@ int plat_sdei_validate_entry_point(uintptr_t ep, unsigned int client_mode) } #endif +#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 */ + /* RAS functions common to AArch64 ARM platforms */ void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie, void *handle, uint64_t flags) @@ -74,9 +86,17 @@ void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie, if (handled != 0) return; #endif + unsigned int level = (unsigned int)GET_EL(read_spsr_el3()); - ERROR("Unhandled External Abort received on 0x%lx at EL3!\n", - read_mpidr_el1()); - ERROR(" exception reason=%u syndrome=0x%llx\n", ea_reason, syndrome); + 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); +#if HANDLE_EA_EL3_FIRST + /* Skip backtrace for lower EL */ + if (level != MODE_EL3) { + (void)console_flush(); + do_panic(); + } +#endif panic(); } -- cgit v1.2.3 From a16bc84560efdbfcd242e6c708992624a76ec7cd Mon Sep 17 00:00:00 2001 From: Manish Pandey Date: Fri, 6 Mar 2020 14:36:25 +0000 Subject: TSP: corrected log information In CPU resume function, CPU suspend count was printed instead of CPU resume count. Signed-off-by: Manish Pandey Change-Id: I0c081dc03a4ccfb2129687f690667c5ceed00a5f --- bl32/tsp/tsp_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bl32/tsp/tsp_main.c b/bl32/tsp/tsp_main.c index e1d961cc6..9da2f9af9 100644 --- a/bl32/tsp/tsp_main.c +++ b/bl32/tsp/tsp_main.c @@ -273,11 +273,11 @@ tsp_args_t *tsp_cpu_resume_main(uint64_t max_off_pwrlvl, spin_lock(&console_lock); INFO("TSP: cpu 0x%lx resumed. maximum off power level %lld\n", read_mpidr(), max_off_pwrlvl); - INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu suspend requests\n", + INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu resume requests\n", read_mpidr(), tsp_stats[linear_id].smc_count, tsp_stats[linear_id].eret_count, - tsp_stats[linear_id].cpu_suspend_count); + tsp_stats[linear_id].cpu_resume_count); spin_unlock(&console_lock); #endif /* Indicate to the SPD that we have completed this request */ -- cgit v1.2.3 From d439cea9e8dc500008804f5667b30f332bf4fcbf Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Fri, 29 Jun 2018 13:34:51 -0700 Subject: locks: bakery: add a DMB to the 'read_cache_op' macro ARM has a weak memory ordering model. This means that without explicit barriers, memory accesses can be observed differently than program order. In this case, the cache invalidate instruction can be observed after the subsequent read to address. To solve this, a DMB instruction is required between the cache invalidate and the read. This ensures that the cache invalidate completes before all memory accesses in program order after the DMB. This patch updates the 'read_cache_op' macro to issue a DMB after the cache invalidate instruction to fix this anomaly. Change-Id: Iac9a90d228c57ba8bcdca7e409ea6719546ab441 Signed-off-by: Varun Wadekar --- lib/locks/bakery/bakery_lock_normal.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/locks/bakery/bakery_lock_normal.c b/lib/locks/bakery/bakery_lock_normal.c index caced8f46..0605fceb9 100644 --- a/lib/locks/bakery/bakery_lock_normal.c +++ b/lib/locks/bakery/bakery_lock_normal.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -77,6 +78,8 @@ static inline void read_cache_op(uintptr_t addr, bool cached) { if (cached) dccivac(addr); + + dmbish(); } /* Helper function to check if the lock is acquired */ -- cgit v1.2.3 From 93ee27998020f3580ba5da075d6c9b1e9ab14263 Mon Sep 17 00:00:00 2001 From: Madhukar Pappireddy Date: Thu, 5 Mar 2020 18:18:40 -0600 Subject: Necessary fix in drivers to upgrade to mbedtls-2.18.0 Include x509.h header file explicitly. Update docs. Change-Id: If2e52c2cd3056654406b7b6779b67eea5cc04a48 Signed-off-by: Madhukar Pappireddy --- docs/getting_started/prerequisites.rst | 2 +- drivers/auth/cryptocell/712/cryptocell_crypto.c | 3 ++- drivers/auth/mbedtls/mbedtls_crypto.c | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/getting_started/prerequisites.rst b/docs/getting_started/prerequisites.rst index 3e0c8fff2..13e25cd0e 100644 --- a/docs/getting_started/prerequisites.rst +++ b/docs/getting_started/prerequisites.rst @@ -60,7 +60,7 @@ supporting tools: The following libraries are required for Trusted Board Boot support: -- mbed TLS == 2.16.2 (tag: ``mbedtls-2.16.2``) +- mbed TLS == 2.18.0 (tag: ``mbedtls-2.18.0``) These tools are optional: diff --git a/drivers/auth/cryptocell/712/cryptocell_crypto.c b/drivers/auth/cryptocell/712/cryptocell_crypto.c index 25eb6bcb6..9112c927c 100644 --- a/drivers/auth/cryptocell/712/cryptocell_crypto.c +++ b/drivers/auth/cryptocell/712/cryptocell_crypto.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -22,6 +22,7 @@ #include #include +#include #define LIB_NAME "CryptoCell 712 SBROM" #define RSA_SALT_LEN 32 diff --git a/drivers/auth/mbedtls/mbedtls_crypto.c b/drivers/auth/mbedtls/mbedtls_crypto.c index 04fbc648b..4c6dc0fcc 100644 --- a/drivers/auth/mbedtls/mbedtls_crypto.c +++ b/drivers/auth/mbedtls/mbedtls_crypto.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include -- cgit v1.2.3 From f97062a5c728e7959de4a0454f9912cc03ad2172 Mon Sep 17 00:00:00 2001 From: Sumit Garg Date: Fri, 15 Nov 2019 18:47:53 +0530 Subject: docs: Update docs with firmware encryption feature Update documentation with optional firmware encryption feature. Signed-off-by: Sumit Garg Change-Id: I26691b18e1ee52a73090954260f26f2865c4e05a --- docs/change-log-upcoming.rst | 1 + docs/design/auth-framework.rst | 10 +++++++++- docs/design/trusted-board-boot.rst | 28 ++++++++++++++++++++++++++++ docs/getting_started/build-options.rst | 28 ++++++++++++++++++++++++++++ docs/getting_started/porting-guide.rst | 29 +++++++++++++++++++++++++++++ docs/getting_started/tools-build.rst | 27 +++++++++++++++++++++++++++ 6 files changed, 122 insertions(+), 1 deletion(-) diff --git a/docs/change-log-upcoming.rst b/docs/change-log-upcoming.rst index c4e8bb0d8..15f39de63 100644 --- a/docs/change-log-upcoming.rst +++ b/docs/change-log-upcoming.rst @@ -46,6 +46,7 @@ New Features - Security - Example: "UBSAN support and handlers" + - Add support for optional firmware encryption feature (experimental). - Tools - Example: "fiptool: Add support to build fiptool on Windows." diff --git a/docs/design/auth-framework.rst b/docs/design/auth-framework.rst index ae7739140..1a53e2292 100644 --- a/docs/design/auth-framework.rst +++ b/docs/design/auth-framework.rst @@ -934,7 +934,7 @@ i.e. verify a hash or a digital signature. Arm platforms will use a library based on mbed TLS, which can be found in ``drivers/auth/mbedtls/mbedtls_crypto.c``. This library is registered in the authentication framework using the macro ``REGISTER_CRYPTO_LIB()`` and exports -three functions: +four functions: .. code:: c @@ -945,6 +945,11 @@ three functions: void *pk_ptr, unsigned int pk_len); int verify_hash(void *data_ptr, unsigned int data_len, void *digest_info_ptr, unsigned int digest_info_len); + int auth_decrypt(enum crypto_dec_algo dec_algo, void *data_ptr, + size_t len, const void *key, unsigned int key_len, + unsigned int key_flags, const void *iv, + unsigned int iv_len, const void *tag, + unsigned int tag_len) The mbedTLS library algorithm support is configured by both the ``TF_MBEDTLS_KEY_ALG`` and ``TF_MBEDTLS_KEY_SIZE`` variables. @@ -957,6 +962,9 @@ The mbedTLS library algorithm support is configured by both the - ``TF_MBEDTLS_KEY_SIZE`` sets the supported RSA key size for TFA. Valid values include 1024, 2048, 3072 and 4096. +- ``TF_MBEDTLS_USE_AES_GCM`` enables the authenticated decryption support based + on AES-GCM algorithm. Valid values are 0 and 1. + .. note:: If code size is a concern, the build option ``MBEDTLS_SHA256_SMALLER`` can be defined in the platform Makefile. It will make mbed TLS use an diff --git a/docs/design/trusted-board-boot.rst b/docs/design/trusted-board-boot.rst index 49e8adb98..4802c97f3 100644 --- a/docs/design/trusted-board-boot.rst +++ b/docs/design/trusted-board-boot.rst @@ -229,6 +229,34 @@ library that is required is given in the :ref:`Prerequisites` document. Instructions for building and using the tool can be found at :ref:`tools_build_cert_create`. +Authenticated Encryption Framework +---------------------------------- + +The authenticated encryption framework included in TF-A provides support to +implement the optional firmware encryption feature. This feature can be +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 +------------------------ + +The ``encrypt_fw`` tool is built and runs on the host machine as part of the +TF-A build process when ``DECRYPTION_SUPPORT != none``. It takes the plain +firmware image as input and generates the encrypted firmware image which can +then be passed as input to the ``fiptool`` utility for creating the FIP. + +The encrypted firmwares are also stored individually in the output build +directory. + +The tool resides in the ``tools/encrypt_fw`` directory. It uses OpenSSL SSL +library version 1.0.1 or later to do authenticated encryption operation. +Instructions for building and using the tool can be found in the +:ref:`tools_build_enctool`. + -------------- *Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved.* diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index af4895efc..f138feb4c 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -263,6 +263,22 @@ Common build options platform hook needs to be implemented. The value is passed as the last 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. + +- ``ENCRYPT_BL32``: Binary flag to enable encryption of Secure BL32 payload. + This flag depends on ``DECRYPTION_SUPPORT`` build flag which is marked as + experimental. + +- ``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. + +- ``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. + - ``ERROR_DEPRECATED``: This option decides whether to treat the usage of deprecated platform APIs, helper functions or drivers within Trusted Firmware as error. It can take the value 1 (flag the use of deprecated @@ -287,6 +303,18 @@ Common build options - ``FWU_FIP_NAME``: This is an optional build option which specifies the FWU FIP filename for the ``fwu_fip`` target. Default is ``fwu_fip.bin``. +- ``FW_ENC_STATUS``: Top level firmware's encryption numeric flag, values: + + :: + + 0: Encryption is done with Secret Symmetric Key (SSK) which is common + for a class of devices. + 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. + - ``GENERATE_COT``: Boolean flag used to build and execute the ``cert_create`` tool to create certificates as per the Chain of Trust described in :ref:`Trusted Board Boot`. The build system then calls ``fiptool`` to diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst index e8357b385..d634d2e70 100644 --- a/docs/getting_started/porting-guide.rst +++ b/docs/getting_started/porting-guide.rst @@ -872,6 +872,35 @@ twice. On success the function should return 0 and a negative error code otherwise. +Function : plat_get_enc_key_info() [when FW_ENC_STATUS == 0 or 1] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Arguments : enum fw_enc_status_t fw_enc_status, uint8_t *key, + size_t *key_len, unsigned int *flags, const uint8_t *img_id, + size_t img_id_len + Return : int + +This function provides a symmetric key (either SSK or BSSK depending on +fw_enc_status) which is invoked during runtime decryption of encrypted +firmware images. `plat/common/plat_bl_common.c` provides a dummy weak +implementation for testing purposes which must be overridden by the platform +trying to implement a real world firmware encryption use-case. + +It also allows the platform to pass symmetric key identifier rather than +actual symmetric key which is useful in cases where the crypto backend provides +secure storage for the symmetric key. So in this case ``ENC_KEY_IS_IDENTIFIER`` +flag must be set in ``flags``. + +In addition to above a platform may also choose to provide an image specific +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. + Common optional modifications ----------------------------- diff --git a/docs/getting_started/tools-build.rst b/docs/getting_started/tools-build.rst index bb707cb7c..c050f5851 100644 --- a/docs/getting_started/tools-build.rst +++ b/docs/getting_started/tools-build.rst @@ -135,6 +135,33 @@ verbose. The following command should be used to obtain help about the tool: ./tools/cert_create/cert_create -h +.. _tools_build_enctool: + +Building the Firmware Encryption Tool +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``encrypt_fw`` tool is built as part of the TF-A build process when the +``fip`` make target is specified, DECRYPTION_SUPPORT and TBB are enabled, but +it can also be built separately with the following command: + +.. code:: shell + + make PLAT= [DEBUG=1] [V=1] enctool + +``DEBUG=1`` builds the tool in debug mode. ``V=1`` makes the build process more +verbose. The following command should be used to obtain help about the tool: + +.. code:: shell + + ./tools/encrypt_fw/encrypt_fw -h + +Note that the enctool in its current implementation only supports encryption +key to be provided in plain format. A typical implementation can very well +extend this tool to support custom techniques to protect encryption key. + +Also, a user may choose to provide encryption key or nonce as an input file +via using ``cat `` instead of a hex string. + -------------- *Copyright (c) 2019, Arm Limited. All rights reserved.* -- cgit v1.2.3 From 4ebbea9592ab37fc62217d0ac62fa13a3e063527 Mon Sep 17 00:00:00 2001 From: Sumit Garg Date: Fri, 15 Nov 2019 20:16:58 +0530 Subject: docs: qemu: Add instructions to boot using FIP image Update qemu documentation with instructions to boot using FIP image. Also, add option to build TF-A with TBBR and firmware encryption enabled. Signed-off-by: Sumit Garg Change-Id: Ib3af485d413cd595352034c82c2268d7f4cb120a --- docs/plat/qemu.rst | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/docs/plat/qemu.rst b/docs/plat/qemu.rst index 88196bc93..afa32c11b 100644 --- a/docs/plat/qemu.rst +++ b/docs/plat/qemu.rst @@ -21,11 +21,13 @@ Current limitations: - Only cold boot is supported - No build instructions for QEMU\_EFI.fd and rootfs-arm64.cpio.gz -- No instructions for how to load a BL32 (Secure Payload) ``QEMU_EFI.fd`` can be dowloaded from http://snapshots.linaro.org/components/kernel/leg-virt-tianocore-edk2-upstream/latest/QEMU-KERNEL-AARCH64/RELEASE_GCC5/QEMU_EFI.fd +Booting via semi-hosting option +------------------------------- + Boot binaries, except BL1, are primarily loaded via semi-hosting so all binaries has to reside in the same directory as QEMU is started from. This is conveniently achieved with symlinks the local names as: @@ -50,3 +52,52 @@ To start (QEMU v4.1.0): -append "console=ttyAMA0,38400 keep_bootcon root=/dev/vda2" \ -initrd rootfs-arm64.cpio.gz -smp 2 -m 1024 -bios bl1.bin \ -d unimp -semihosting-config enable,target=native + +Booting via flash based firmwares +--------------------------------- + +Boot firmwares are loaded via secure FLASH0 device so ``bl1.bin`` and +``fip.bin`` should be concatenated to create a ``flash.bin`` that is flashed +onto secure FLASH0. + +- ``bl32.bin`` -> BL32 (``tee-header_v2.bin``) +- ``bl32_extra1.bin`` -> BL32 Extra1 (``tee-pager_v2.bin``) +- ``bl32_extra2.bin`` -> BL32 Extra2 (``tee-pageable_v2.bin``) +- ``bl33.bin`` -> BL33 (``QEMU_EFI.fd``) +- ``Image`` -> linux/arch/arm64/boot/Image + +To build: + +.. code:: shell + + make CROSS_COMPILE=aarch64-linux-gnu- PLAT=qemu BL32=bl32.bin \ + BL32_EXTRA1=bl32_extra1.bin BL32_EXTRA2=bl32_extra2.bin \ + BL33=bl33.bin BL32_RAM_LOCATION=tdram SPD=opteed all fip + +To build with TBBR enabled, BL31 and BL32 encrypted with test key: + +.. code:: shell + + make CROSS_COMPILE=aarch64-linux-gnu- PLAT=qemu BL32=bl32.bin \ + BL32_EXTRA1=bl32_extra1.bin BL32_EXTRA2=bl32_extra2.bin \ + BL33=bl33.bin BL32_RAM_LOCATION=tdram SPD=opteed all fip \ + MBEDTLS_DIR= TRUSTED_BOARD_BOOT=1 \ + GENERATE_COT=1 DECRYPTION_SUPPORT=aes_gcm FW_ENC_STATUS=0 \ + ENCRYPT_BL31=1 ENCRYPT_BL32=1 + +To build flash.bin: + +.. code:: shell + + dd if=build/qemu/release/bl1.bin of=flash.bin bs=4096 conv=notrunc + dd if=build/qemu/release/fip.bin of=flash.bin seek=64 bs=4096 conv=notrunc + +To start (QEMU v2.6.0): + +.. code:: shell + + qemu-system-aarch64 -nographic -machine virt,secure=on -cpu cortex-a57 \ + -kernel Image -no-acpi \ + -append 'console=ttyAMA0,38400 keep_bootcon root=/dev/vda2' \ + -initrd rootfs-arm64.cpio.gz -smp 2 -m 1024 -bios flash.bin \ + -d unimp -- cgit v1.2.3 From e6c0da159b885bf5858f81d522f6f9a35b25de87 Mon Sep 17 00:00:00 2001 From: Kalyani Chidambaram Date: Mon, 8 Oct 2018 17:01:01 -0700 Subject: cpus: denver: fixup register used to store return address The denver_enable_dco and denver_disable_dco use register X3 to store the return address. But X3 gets over-written by other functions, downstream. This patch stores the return address to X18 instead, to fix this anomaly. Change-Id: Ic40bfc1d9abaa7b90348843b9ecd09521bb4ee7b Signed-off-by: Kalyani Chidambaram --- lib/cpus/aarch64/denver.S | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/cpus/aarch64/denver.S b/lib/cpus/aarch64/denver.S index c377b28b4..e260f8d28 100644 --- a/lib/cpus/aarch64/denver.S +++ b/lib/cpus/aarch64/denver.S @@ -156,12 +156,12 @@ endfunc denver_disable_ext_debug * ---------------------------------------------------- */ func denver_enable_dco - mov x3, x30 + mov x18, x30 bl plat_my_core_pos mov x1, #1 lsl x1, x1, x0 msr s3_0_c15_c0_2, x1 - mov x30, x3 + mov x30, x18 ret endfunc denver_enable_dco @@ -171,7 +171,7 @@ endfunc denver_enable_dco */ func denver_disable_dco - mov x3, x30 + mov x18, x30 /* turn off background work */ bl plat_my_core_pos @@ -188,7 +188,7 @@ func denver_disable_dco and x2, x2, x1 cbnz x2, 1b - mov x30, x3 + mov x30, x18 ret endfunc denver_disable_dco -- cgit v1.2.3 From b1481cff46d2724f483cc9fe12d59202c082e8ab Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Thu, 7 Jun 2018 11:21:02 -0700 Subject: Tegra: disable CPUACTLR access from lower exception levels This patch resets the macros to update the CPUACTLR_ELx to make them generic for all exception levels. Change-Id: I33e9b860efb543934b654a2f5d775135df7f1aa6 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/aarch64/tegra_helpers.S | 34 +++++++++--------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S index 13ca6aaa2..7cba3a449 100644 --- a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S +++ b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -18,21 +19,16 @@ /******************************************************************************* * Implementation defined ACTLR_EL3 bit definitions ******************************************************************************/ -#define ACTLR_EL3_L2ACTLR_BIT (U(1) << 6) -#define ACTLR_EL3_L2ECTLR_BIT (U(1) << 5) -#define ACTLR_EL3_L2CTLR_BIT (U(1) << 4) -#define ACTLR_EL3_CPUECTLR_BIT (U(1) << 1) -#define ACTLR_EL3_CPUACTLR_BIT (U(1) << 0) -#define ACTLR_EL3_ENABLE_ALL_MASK (ACTLR_EL3_L2ACTLR_BIT | \ - ACTLR_EL3_L2ECTLR_BIT | \ - ACTLR_EL3_L2CTLR_BIT | \ - ACTLR_EL3_CPUECTLR_BIT | \ - ACTLR_EL3_CPUACTLR_BIT) -#define ACTLR_EL3_ENABLE_ALL_ACCESS (ACTLR_EL3_L2ACTLR_BIT | \ - ACTLR_EL3_L2ECTLR_BIT | \ - ACTLR_EL3_L2CTLR_BIT | \ - ACTLR_EL3_CPUECTLR_BIT | \ - ACTLR_EL3_CPUACTLR_BIT) +#define ACTLR_ELx_L2ACTLR_BIT (U(1) << 6) +#define ACTLR_ELx_L2ECTLR_BIT (U(1) << 5) +#define ACTLR_ELx_L2CTLR_BIT (U(1) << 4) +#define ACTLR_ELx_CPUECTLR_BIT (U(1) << 1) +#define ACTLR_ELx_CPUACTLR_BIT (U(1) << 0) +#define ACTLR_ELx_ENABLE_ALL_ACCESS (ACTLR_ELx_L2ACTLR_BIT | \ + ACTLR_ELx_L2ECTLR_BIT | \ + ACTLR_ELx_L2CTLR_BIT | \ + ACTLR_ELx_CPUECTLR_BIT | \ + ACTLR_ELx_CPUACTLR_BIT) /* Global functions */ .globl plat_is_my_cpu_primary @@ -93,15 +89,11 @@ * ------------------------------------------------------- */ mrs x0, actlr_el3 - mov x1, #ACTLR_EL3_ENABLE_ALL_MASK - bic x0, x0, x1 - mov x1, #ACTLR_EL3_ENABLE_ALL_ACCESS + mov x1, #ACTLR_ELx_ENABLE_ALL_ACCESS orr x0, x0, x1 msr actlr_el3, x0 mrs x0, actlr_el2 - mov x1, #ACTLR_EL3_ENABLE_ALL_MASK - bic x0, x0, x1 - mov x1, #ACTLR_EL3_ENABLE_ALL_ACCESS + mov x1, #ACTLR_ELx_ENABLE_ALL_ACCESS orr x0, x0, x1 msr actlr_el2, x0 isb -- cgit v1.2.3 From 24902fae2427399901be96a594da0420a0c82a7e Mon Sep 17 00:00:00 2001 From: kalyani chidambaram Date: Tue, 19 Jun 2018 13:34:39 -0700 Subject: Tegra210: update the PMC blacklisted registers Update the list to include PMC registers that the NS world cannot access even with smc calls. Change-Id: I588179b56ebc0c29200b55e6d61535fd3a7a3b7e Signed-off-by: kalyani chidambaram --- plat/nvidia/tegra/include/drivers/pmc.h | 33 ++++++++++++++++-------- plat/nvidia/tegra/soc/t210/plat_sip_calls.c | 39 ++++++++++++++++------------- 2 files changed, 44 insertions(+), 28 deletions(-) diff --git a/plat/nvidia/tegra/include/drivers/pmc.h b/plat/nvidia/tegra/include/drivers/pmc.h index 32252a28b..8752b84c6 100644 --- a/plat/nvidia/tegra/include/drivers/pmc.h +++ b/plat/nvidia/tegra/include/drivers/pmc.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -18,27 +19,37 @@ #define PMC_DPD_ENABLE_0 U(0x24) #define PMC_PWRGATE_STATUS U(0x38) #define PMC_PWRGATE_TOGGLE U(0x30) -#define PMC_SECURE_SCRATCH0 U(0xb0) -#define PMC_SECURE_SCRATCH5 U(0xc4) +#define PMC_SCRATCH1 U(0x54) #define PMC_CRYPTO_OP_0 U(0xf4) #define PMC_TOGGLE_START U(0x100) +#define PMC_SCRATCH31 U(0x118) +#define PMC_SCRATCH32 U(0x11C) +#define PMC_SCRATCH33 U(0x120) #define PMC_SCRATCH39 U(0x138) +#define PMC_SCRATCH40 U(0x13C) #define PMC_SCRATCH41 U(0x140) -#define PMC_SECURE_SCRATCH6 U(0x224) -#define PMC_SECURE_SCRATCH7 U(0x228) -#define PMC_SECURE_DISABLE2 U(0x2c4) +#define PMC_SCRATCH42 U(0x144) +#define PMC_SCRATCH43 U(0x22C) +#define PMC_SCRATCH44 U(0x230) +#define PMC_SCRATCH45 U(0x234) +#define PMC_SCRATCH46 U(0x238) +#define PMC_SCRATCH47 U(0x23C) +#define PMC_SCRATCH48 U(0x240) +#define PMC_SCRATCH50 U(0x248) +#define PMC_SCRATCH51 U(0x24C) +#define PMC_TSC_MULT_0 U(0x2B4) +#define PMC_STICKY_BIT U(0x2C0) +#define PMC_SECURE_DISABLE2 U(0x2C4) #define PMC_SECURE_DISABLE2_WRITE22_ON (U(1) << 28) -#define PMC_SECURE_SCRATCH8 U(0x300) -#define PMC_SECURE_SCRATCH79 U(0x41c) #define PMC_FUSE_CONTROL_0 U(0x450) -#define PMC_SECURE_SCRATCH22 U(0x338) -#define PMC_SECURE_DISABLE3 U(0x2d8) +#define PMC_SECURE_DISABLE3 U(0x2D8) #define PMC_SECURE_DISABLE3_WRITE34_ON (U(1) << 20) #define PMC_SECURE_DISABLE3_WRITE35_ON (U(1) << 22) +#define PMC_SECURE_SCRATCH22 U(0x338) #define PMC_SECURE_SCRATCH34 U(0x368) #define PMC_SECURE_SCRATCH35 U(0x36c) -#define PMC_SECURE_SCRATCH80 U(0xa98) -#define PMC_SECURE_SCRATCH119 U(0xb34) +#define PMC_SCRATCH56 U(0x600) +#define PMC_SCRATCH57 U(0x604) #define PMC_SCRATCH201 U(0x844) static inline uint32_t tegra_pmc_read_32(uint32_t off) diff --git a/plat/nvidia/tegra/soc/t210/plat_sip_calls.c b/plat/nvidia/tegra/soc/t210/plat_sip_calls.c index 7e0f5c1d8..7d26fe795 100644 --- a/plat/nvidia/tegra/soc/t210/plat_sip_calls.c +++ b/plat/nvidia/tegra/soc/t210/plat_sip_calls.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -50,24 +51,32 @@ int plat_sip_handler(uint32_t smc_fid, if (!ns) SMC_RET1(handle, SMC_UNK); - switch (smc_fid) { - case TEGRA_SIP_PMC_COMMANDS: - + if (smc_fid == TEGRA_SIP_PMC_COMMANDS) { /* check the address is within PMC range and is 4byte aligned */ if ((x2 >= TEGRA_PMC_SIZE) || (x2 & 0x3)) return -EINVAL; - /* pmc_secure_scratch registers are not accessible */ - if (((x2 >= PMC_SECURE_SCRATCH0) && (x2 <= PMC_SECURE_SCRATCH5)) || - ((x2 >= PMC_SECURE_SCRATCH6) && (x2 <= PMC_SECURE_SCRATCH7)) || - ((x2 >= PMC_SECURE_SCRATCH8) && (x2 <= PMC_SECURE_SCRATCH79)) || - ((x2 >= PMC_SECURE_SCRATCH80) && (x2 <= PMC_SECURE_SCRATCH119))) - return -EFAULT; - + switch (x2) { + /* Black listed PMC registers */ + case PMC_SCRATCH1: + case PMC_SCRATCH31 ... PMC_SCRATCH33: + case PMC_SCRATCH40: + case PMC_SCRATCH42: + case PMC_SCRATCH43 ... PMC_SCRATCH48: + case PMC_SCRATCH50 ... PMC_SCRATCH51: + case PMC_SCRATCH56 ... PMC_SCRATCH57: /* PMC secure-only registers are not accessible */ - if ((x2 == PMC_DPD_ENABLE_0) || (x2 == PMC_FUSE_CONTROL_0) || - (x2 == PMC_CRYPTO_OP_0)) + case PMC_DPD_ENABLE_0: + case PMC_FUSE_CONTROL_0: + case PMC_CRYPTO_OP_0: + case PMC_TSC_MULT_0: + case PMC_STICKY_BIT: + ERROR("%s: error offset=0x%llx\n", __func__, x2); return -EFAULT; + default: + /* Valid register */ + break; + } /* Perform PMC read/write */ if (x1 == PMC_READ) { @@ -78,13 +87,9 @@ int plat_sip_handler(uint32_t smc_fid, } else { return -EINVAL; } - - break; - - default: + } else { ERROR("%s: unsupported function ID\n", __func__); return -ENOTSUP; } - return 0; } -- cgit v1.2.3 From 41554fb2ebbbabbf1e79e2d9cacbfa2dd6124927 Mon Sep 17 00:00:00 2001 From: Harvey Hsieh Date: Tue, 10 Apr 2018 18:16:51 +0800 Subject: Tegra210: SE: add context save support Tegra210B01 SoCs support atomic context save for the two SE hardware engines. Tegra210 SoCs have support for only one SE engine and support a software based save/restore mechanism instead. This patch updates the SE driver to make this change. Change-Id: Ia5e5ed75d0fe011f17809684bbc2ed2338925946 Signed-off-by: Harvey Hsieh --- plat/nvidia/tegra/include/t210/tegra_def.h | 3 + plat/nvidia/tegra/soc/t210/drivers/se/se_private.h | 6 +- .../tegra/soc/t210/drivers/se/security_engine.c | 124 ++++++++++----------- plat/nvidia/tegra/soc/t210/plat_psci_handlers.c | 9 +- plat/nvidia/tegra/soc/t210/plat_setup.c | 4 +- 5 files changed, 70 insertions(+), 76 deletions(-) diff --git a/plat/nvidia/tegra/include/t210/tegra_def.h b/plat/nvidia/tegra/include/t210/tegra_def.h index 4a39aa1fb..e8bce5e05 100644 --- a/plat/nvidia/tegra/include/t210/tegra_def.h +++ b/plat/nvidia/tegra/include/t210/tegra_def.h @@ -144,6 +144,9 @@ #define SE_CLK_ENB_BIT (U(1) << 31) #define TEGRA_CLK_OUT_ENB_W U(0x364) #define ENTROPY_RESET_BIT (U(1) << 21) +#define TEGRA_CLK_RST_CTL_CLK_SRC_SE U(0x42C) +#define SE_CLK_SRC_MASK (U(7) << 29) +#define SE_CLK_SRC_CLK_M (U(6) << 29) #define TEGRA_RST_DEV_SET_V U(0x430) #define SE_RESET_BIT (U(1) << 31) #define HDA_RESET_BIT (U(1) << 29) diff --git a/plat/nvidia/tegra/soc/t210/drivers/se/se_private.h b/plat/nvidia/tegra/soc/t210/drivers/se/se_private.h index 352107d2c..c44b0fc46 100644 --- a/plat/nvidia/tegra/soc/t210/drivers/se/se_private.h +++ b/plat/nvidia/tegra/soc/t210/drivers/se/se_private.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. - * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -15,6 +15,9 @@ * PMC registers */ +/* SC7 context save scratch register for T210 */ +#define PMC_SCRATCH43_REG_OFFSET U(0x22C) + /* Secure scratch registers */ #define PMC_SECURE_SCRATCH4_OFFSET 0xC0U #define PMC_SECURE_SCRATCH5_OFFSET 0xC4U @@ -435,6 +438,7 @@ ((x) & ((0x1U) << SE_TZRAM_OP_REQ_SHIFT)) /* SE Interrupt */ +#define SE_INT_ENABLE_REG_OFFSET U(0xC) #define SE_INT_STATUS_REG_OFFSET 0x10U #define SE_INT_OP_DONE_SHIFT 4 #define SE_INT_OP_DONE_CLEAR \ diff --git a/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c b/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c index d5e049126..635018dbc 100644 --- a/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c +++ b/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. - * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -20,8 +20,8 @@ * Constants and Macros ******************************************************************************/ -#define TIMEOUT_100MS 100U // Timeout in 100ms -#define RNG_AES_KEY_INDEX 1 +#define TIMEOUT_100MS 100U /* Timeout in 100ms */ +#define RNG_AES_KEY_INDEX 1 /******************************************************************************* * Data structure and global variables @@ -68,14 +68,12 @@ * #--------------------------------# */ -/* Known pattern data */ -static const uint32_t se_ctx_known_pattern_data[SE_CTX_KNOWN_PATTERN_SIZE_WORDS] = { +/* Known pattern data for T210 */ +static const uint8_t se_ctx_known_pattern_data[SE_CTX_KNOWN_PATTERN_SIZE] = { /* 128 bit AES block */ - 0x0C0D0E0F, - 0x08090A0B, - 0x04050607, - 0x00010203, -}; + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + }; /* SE input and output linked list buffers */ static tegra_se_io_lst_t se1_src_ll_buf; @@ -85,6 +83,9 @@ static tegra_se_io_lst_t se1_dst_ll_buf; static tegra_se_io_lst_t se2_src_ll_buf; static tegra_se_io_lst_t se2_dst_ll_buf; +/* SE1 context buffer, 132 blocks */ +static __aligned(64) uint8_t se1_ctx_buf[SE_CTX_DRBG_BUFER_SIZE]; + /* SE1 security engine device handle */ static tegra_se_dev_t se_dev_1 = { .se_num = 1, @@ -97,10 +98,10 @@ static tegra_se_dev_t se_dev_1 = { /* Setup DST buffers for SE operations */ .dst_ll_buf = &se1_dst_ll_buf, /* Setup context save destination */ - .ctx_save_buf = (uint32_t *)(TEGRA_TZRAM_CARVEOUT_BASE), + .ctx_save_buf = (uint32_t *)&se1_ctx_buf }; -/* SE2 security engine device handle */ +/* SE2 security engine device handle (T210B01 only) */ static tegra_se_dev_t se_dev_2 = { .se_num = 2, /* Setup base address for se */ @@ -112,7 +113,7 @@ static tegra_se_dev_t se_dev_2 = { /* Setup DST buffers for SE operations */ .dst_ll_buf = &se2_dst_ll_buf, /* Setup context save destination */ - .ctx_save_buf = (uint32_t *)(TEGRA_TZRAM_CARVEOUT_BASE + 0x1000), + .ctx_save_buf = (uint32_t *)(TEGRA_TZRAM_CARVEOUT_BASE + 0x1000) }; static bool ecid_valid; @@ -201,18 +202,6 @@ static int32_t tegra_se_operation_complete(const tegra_se_dev_t *se_dev) return ret; } -/* - * Returns true if the SE engine is configured to perform SE context save in - * hardware. - */ -static inline bool tegra_se_atomic_save_enabled(const tegra_se_dev_t *se_dev) -{ - uint32_t val; - - val = tegra_se_read_32(se_dev, SE_CTX_SAVE_AUTO_REG_OFFSET); - return (SE_CTX_SAVE_AUTO_ENABLE(val) == SE_CTX_SAVE_AUTO_EN); -} - /* * Wait for SE engine to be idle and clear pending interrupts before * starting the next SE operation. @@ -223,6 +212,9 @@ static int32_t tegra_se_operation_prepare(const tegra_se_dev_t *se_dev) uint32_t val = 0; uint32_t timeout; + /* disable SE interrupt to prevent interrupt issued by SE operation */ + tegra_se_write_32(se_dev, SE_INT_ENABLE_REG_OFFSET, 0U); + /* Wait for previous operation to finish */ val = tegra_se_read_32(se_dev, SE_STATUS_OFFSET); for (timeout = 0; (val != 0U) && (timeout < TIMEOUT_100MS); timeout++) { @@ -629,19 +621,19 @@ static int tegra_se_lp_rsakeytable_context_save(tegra_se_dev_t *se_dev) { uint32_t val = 0; int ret = 0; - /* First the modulus and then the exponent must be + /* For T210, First the modulus and then exponent must be * encrypted and saved. This is repeated for SLOT 0 * and SLOT 1. Hence the order: - * SLOT 0 exponent : RSA_KEY_INDEX : 0 * SLOT 0 modulus : RSA_KEY_INDEX : 1 - * SLOT 1 exponent : RSA_KEY_INDEX : 2 + * SLOT 0 exponent : RSA_KEY_INDEX : 0 * SLOT 1 modulus : RSA_KEY_INDEX : 3 + * SLOT 1 exponent : RSA_KEY_INDEX : 2 */ const unsigned int key_index_mod[TEGRA_SE_RSA_KEYSLOT_COUNT][2] = { /* RSA key slot 0 */ - {SE_RSA_KEY_INDEX_SLOT0_EXP, SE_RSA_KEY_INDEX_SLOT0_MOD}, + {SE_RSA_KEY_INDEX_SLOT0_MOD, SE_RSA_KEY_INDEX_SLOT0_EXP}, /* RSA key slot 1 */ - {SE_RSA_KEY_INDEX_SLOT1_EXP, SE_RSA_KEY_INDEX_SLOT1_MOD}, + {SE_RSA_KEY_INDEX_SLOT1_MOD, SE_RSA_KEY_INDEX_SLOT1_EXP}, }; se_dev->dst_ll_buf->last_buff_num = 0; @@ -876,8 +868,8 @@ static int tegra_se_context_save_sw(tegra_se_dev_t *se_dev) /* Write lp context buffer address into PMC scratch register */ if (se_dev->se_num == 1) { - /* SE context address */ - mmio_write_32((uint64_t)TEGRA_PMC_BASE + PMC_SECURE_SCRATCH117_OFFSET, + /* SE context address, support T210 only */ + mmio_write_32((uint64_t)TEGRA_PMC_BASE + PMC_SCRATCH43_REG_OFFSET, ((uint64_t)(se_dev->ctx_save_buf))); } else if (se_dev->se_num == 2) { /* SE2 & PKA1 context address */ @@ -909,7 +901,10 @@ void tegra_se_init(void) /* Generate random SRK to initialize DRBG */ tegra_se_generate_srk(&se_dev_1); - tegra_se_generate_srk(&se_dev_2); + + if (tegra_chipid_is_t210_b01()) { + tegra_se_generate_srk(&se_dev_2); + } /* determine if ECID is valid */ val = mmio_read_32(TEGRA_FUSE_BASE + FUSE_JTAG_SECUREID_VALID); @@ -932,6 +927,18 @@ static void tegra_se_enable_clocks(void) val &= ~ENTROPY_RESET_BIT; mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEVICES_W, val); + if (!tegra_chipid_is_t210_b01()) { + + /* + * T210 SE clock source is turned off in kernel, to simplify + * SE clock source setting, we switch SE clock source to + * CLK_M, SE_CLK_DIVISOR = 0. T210 B01 SE clock source is + * always on, so don't need this setting. + */ + mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_RST_CTL_CLK_SRC_SE, + SE_CLK_SRC_CLK_M); + } + /* Enable SE clock */ val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_V); val |= SE_CLK_ENB_BIT; @@ -975,43 +982,25 @@ int32_t tegra_se_suspend(void) tegra_se_enable_clocks(); - if (tegra_se_atomic_save_enabled(&se_dev_2) && - tegra_se_atomic_save_enabled(&se_dev_1)) { - /* Atomic context save se2 and pka1 */ + if (tegra_chipid_is_t210_b01()) { + /* It is T210 B01, Atomic context save se2 and pka1 */ INFO("%s: SE2/PKA1 atomic context save\n", __func__); - if (ret == 0) { - ret = tegra_se_context_save_atomic(&se_dev_2); - } - - /* Atomic context save se */ - if (ret == 0) { - INFO("%s: SE1 atomic context save\n", __func__); - ret = tegra_se_context_save_atomic(&se_dev_1); + ret = tegra_se_context_save_atomic(&se_dev_2); + if (ret != 0) { + ERROR("%s: SE2 ctx save failed (%d)\n", __func__, ret); } - if (ret == 0) { - INFO("%s: SE atomic context save done\n", __func__); - } - } else if (!tegra_se_atomic_save_enabled(&se_dev_2) && - !tegra_se_atomic_save_enabled(&se_dev_1)) { - /* SW context save se2 and pka1 */ - INFO("%s: SE2/PKA1 legacy(SW) context save\n", __func__); - if (ret == 0) { - ret = tegra_se_context_save_sw(&se_dev_2); - } - - /* SW context save se */ - if (ret == 0) { - INFO("%s: SE1 legacy(SW) context save\n", __func__); - ret = tegra_se_context_save_sw(&se_dev_1); - } - - if (ret == 0) { - INFO("%s: SE SW context save done\n", __func__); + ret = tegra_se_context_save_atomic(&se_dev_1); + if (ret != 0) { + ERROR("%s: SE1 ctx save failed (%d)\n", __func__, ret); } } else { - ERROR("%s: One SE set for atomic CTX save, the other is not\n", - __func__); + /* It is T210, SW context save se */ + INFO("%s: SE1 legacy(SW) context save\n", __func__); + ret = tegra_se_context_save_sw(&se_dev_1); + if (ret != 0) { + ERROR("%s: SE1 ctx save failed (%d)\n", __func__, ret); + } } tegra_se_disable_clocks(); @@ -1080,5 +1069,8 @@ static void tegra_se_warm_boot_resume(const tegra_se_dev_t *se_dev) void tegra_se_resume(void) { tegra_se_warm_boot_resume(&se_dev_1); - tegra_se_warm_boot_resume(&se_dev_2); + + if (tegra_chipid_is_t210_b01()) { + tegra_se_warm_boot_resume(&se_dev_2); + } } diff --git a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c index 832b8d647..f29e624ea 100644 --- a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c @@ -210,12 +210,9 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) assert((stateid_afflvl1 == PLAT_MAX_OFF_STATE) || (stateid_afflvl1 == PSTATE_ID_SOC_POWERDN)); - if (tegra_chipid_is_t210_b01()) { - - /* Suspend se/se2 and pka1 */ - if (tegra_se_suspend() != 0) { - ret = PSCI_E_INTERN_FAIL; - } + /* Suspend se/se2 and pka1 for T210 B01 and se for T210 */ + if (tegra_se_suspend() != 0) { + ret = PSCI_E_INTERN_FAIL; } } else if (stateid_afflvl1 == PSTATE_ID_CLUSTER_IDLE) { diff --git a/plat/nvidia/tegra/soc/t210/plat_setup.c b/plat/nvidia/tegra/soc/t210/plat_setup.c index 7afbe0d9a..933e925ec 100644 --- a/plat/nvidia/tegra/soc/t210/plat_setup.c +++ b/plat/nvidia/tegra/soc/t210/plat_setup.c @@ -174,9 +174,7 @@ void plat_early_platform_setup(void) } /* Initialize security engine driver */ - if (tegra_chipid_is_t210_b01()) { - tegra_se_init(); - } + tegra_se_init(); } /* Secure IRQs for Tegra186 */ -- cgit v1.2.3 From f617868678c230a080df4061b17a40b19a3bd048 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Fri, 6 Jul 2018 10:39:32 -0700 Subject: Tegra: fiq_glue: remove bakery locks from interrupt handler This patch removes usage of bakery_locks from the FIQ handler, as it creates unnecessary dependency whenever the watchdog timer interrupt fires. All operations inside the interrupt handler are 'reads', so no need for serialization. Change-Id: I3f675e610e4dabc5b1435fdd24bc28e424f5a8e4 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/tegra_fiq_glue.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/plat/nvidia/tegra/common/tegra_fiq_glue.c b/plat/nvidia/tegra/common/tegra_fiq_glue.c index 8e198ae76..dee99fb13 100644 --- a/plat/nvidia/tegra/common/tegra_fiq_glue.c +++ b/plat/nvidia/tegra/common/tegra_fiq_glue.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -12,7 +13,6 @@ #include #include #include -#include #include #include @@ -25,8 +25,6 @@ /* Legacy FIQ used by earlier Tegra platforms */ #define LEGACY_FIQ_PPI_WDT 28U -static DEFINE_BAKERY_LOCK(tegra_fiq_lock); - /******************************************************************************* * Static variables ******************************************************************************/ @@ -57,8 +55,6 @@ static uint64_t tegra_fiq_interrupt_handler(uint32_t id, */ irq = plat_ic_get_pending_interrupt_id(); - bakery_lock_get(&tegra_fiq_lock); - /* * Jump to NS world only if the NS world's FIQ handler has * been registered @@ -107,8 +103,6 @@ static uint64_t tegra_fiq_interrupt_handler(uint32_t id, plat_ic_end_of_interrupt(irq); } - bakery_lock_release(&tegra_fiq_lock); - return 0; } -- cgit v1.2.3 From 4b74f6d24cfc5739a9698b240b038006aa77f6a7 Mon Sep 17 00:00:00 2001 From: Stefan Kristiansson Date: Tue, 24 Apr 2018 16:02:17 +0300 Subject: Tegra194: memctrl: remove support to reconfigure MSS As bpmp-fw is running at the same time as ATF, and the mss client reconfiguration sequence involves performing a hot flush resets on bpmp, there is a chance that bpmp-fw is trying to perform accesses while the hot flush is active. Therefore, the mss client reconfigure has been moved to System Suspend resume fw and bootloader, and it can be removed from here. Change-Id: I34019ad12abea9681f5e180af6bc86f2c4c6fc74 Signed-off-by: Stefan Kristiansson --- plat/nvidia/tegra/soc/t194/plat_memctrl.c | 410 +----------------------------- 1 file changed, 1 insertion(+), 409 deletions(-) diff --git a/plat/nvidia/tegra/soc/t194/plat_memctrl.c b/plat/nvidia/tegra/soc/t194/plat_memctrl.c index 2208b85e7..8a946da56 100644 --- a/plat/nvidia/tegra/soc/t194/plat_memctrl.c +++ b/plat/nvidia/tegra/soc/t194/plat_memctrl.c @@ -271,413 +271,6 @@ const static mc_streamid_security_cfg_t tegra194_streamid_sec_cfgs[] = { mc_make_sec_cfg(MIU3W, NON_SECURE, OVERRIDE, DISABLE) }; -/* To be called by common memctrl_v2.c */ -static void tegra194_memctrl_reconfig_mss_clients(void) -{ - uint32_t reg_val, wdata_0, wdata_1, wdata_2; - - wdata_0 = MC_CLIENT_HOTRESET_CTRL0_HC_FLUSH_ENB | - MC_CLIENT_HOTRESET_CTRL0_SATA_FLUSH_ENB | - MC_CLIENT_HOTRESET_CTRL0_VIC_FLUSH_ENB | - MC_CLIENT_HOTRESET_CTRL0_XUSB_HOST_FLUSH_ENB | - MC_CLIENT_HOTRESET_CTRL0_XUSB_DEV_FLUSH_ENB | - MC_CLIENT_HOTRESET_CTRL0_TSEC_FLUSH_ENB | - MC_CLIENT_HOTRESET_CTRL0_SDMMC3A_FLUSH_ENB; - if (tegra_platform_is_silicon()) { - wdata_0 |= MC_CLIENT_HOTRESET_CTRL0_SDMMC1A_FLUSH_ENB; - } - - tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL0, wdata_0); - - /* Wait for HOTRESET STATUS to indicate FLUSH_DONE */ - do { - reg_val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS0); - } while ((reg_val & wdata_0) != wdata_0); - - wdata_1 = MC_CLIENT_HOTRESET_CTRL1_SDMMC4A_FLUSH_ENB | - MC_CLIENT_HOTRESET_CTRL1_SE_FLUSH_ENB | - MC_CLIENT_HOTRESET_CTRL1_ETR_FLUSH_ENB | - MC_CLIENT_HOTRESET_CTRL1_TSECB_FLUSH_ENB| - MC_CLIENT_HOTRESET_CTRL1_AXIS_FLUSH_ENB | - MC_CLIENT_HOTRESET_CTRL1_UFSHC_FLUSH_ENB | - MC_CLIENT_HOTRESET_CTRL1_NVDISPLAY_FLUSH_ENB | - MC_CLIENT_HOTRESET_CTRL1_BPMP_FLUSH_ENB | - MC_CLIENT_HOTRESET_CTRL1_AON_FLUSH_ENB | - MC_CLIENT_HOTRESET_CTRL1_SCE_FLUSH_ENB | - MC_CLIENT_HOTRESET_CTRL1_VIFAL_FLUSH_ENB; - if (tegra_platform_is_silicon()) { - wdata_1 |= MC_CLIENT_HOTRESET_CTRL1_APE_FLUSH_ENB | - MC_CLIENT_HOTRESET_CTRL1_EQOS_FLUSH_ENB | - MC_CLIENT_HOTRESET_CTRL1_RCE_FLUSH_ENB; - } - tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL1, wdata_1); - /* Wait for HOTRESET STATUS to indicate FLUSH_DONE */ - do { - reg_val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS1); - } while ((reg_val & wdata_1) != wdata_1); - - wdata_2 = MC_CLIENT_HOTRESET_CTRL2_PCIE_FLUSH_ENB | - MC_CLIENT_HOTRESET_CTRL2_AONDMA_FLUSH_ENB | - MC_CLIENT_HOTRESET_CTRL2_BPMPDMA_FLUSH_ENB | - MC_CLIENT_HOTRESET_CTRL2_SCEDMA_FLUSH_ENB; - if (tegra_platform_is_silicon()) { - wdata_2 |= MC_CLIENT_HOTRESET_CTRL2_RCEDMA_FLUSH_ENB | - MC_CLIENT_HOTRESET_CTRL2_PCIE_FLUSH_ENB | - MC_CLIENT_HOTRESET_CTRL2_PCIE5A_FLUSH_ENB | - MC_CLIENT_HOTRESET_CTRL2_PCIE3A_FLUSH_ENB | - MC_CLIENT_HOTRESET_CTRL2_PCIE3_FLUSH_ENB | - MC_CLIENT_HOTRESET_CTRL2_PCIE0A_FLUSH_ENB | - MC_CLIENT_HOTRESET_CTRL2_PCIE0A2_FLUSH_ENB | - MC_CLIENT_HOTRESET_CTRL2_PCIE4A_FLUSH_ENB; - } - tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL2, wdata_2); - /* Wait for HOTRESET STATUS to indicate FLUSH_DONE */ - do { - reg_val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS2); - } while ((reg_val & wdata_2) != wdata_2); - - /* - * Change MEMTYPE_OVERRIDE from SO_DEV -> PASSTHRU for boot and - * strongly ordered MSS clients. - * - * MC clients with default SO_DEV override still enabled at TSA: - * EQOSW, SATAW, XUSB_DEVW, XUSB_HOSTW, PCIe0w, PCIe1w, PCIe2w, - * PCIe3w, PCIe4w and PCIe5w. - */ - mc_set_tsa_w_passthrough(AONDMAW); - mc_set_tsa_w_passthrough(AONW); - mc_set_tsa_w_passthrough(APEDMAW); - mc_set_tsa_w_passthrough(APEW); - mc_set_tsa_w_passthrough(AXISW); - mc_set_tsa_w_passthrough(BPMPDMAW); - mc_set_tsa_w_passthrough(BPMPW); - mc_set_tsa_w_passthrough(EQOSW); - mc_set_tsa_w_passthrough(ETRW); - mc_set_tsa_w_passthrough(RCEDMAW); - mc_set_tsa_w_passthrough(RCEW); - mc_set_tsa_w_passthrough(SCEDMAW); - mc_set_tsa_w_passthrough(SCEW); - mc_set_tsa_w_passthrough(SDMMCW); - mc_set_tsa_w_passthrough(SDMMCWA); - mc_set_tsa_w_passthrough(SDMMCWAB); - mc_set_tsa_w_passthrough(SESWR); - mc_set_tsa_w_passthrough(TSECSWR); - mc_set_tsa_w_passthrough(TSECSWRB); - mc_set_tsa_w_passthrough(UFSHCW); - mc_set_tsa_w_passthrough(VICSWR); - mc_set_tsa_w_passthrough(VIFALW); - /* - * set HUB2 as SO_DEV_HUBID - */ - reg_val = tsa_read_32(PCIE0W); - mc_set_tsa_hub2(reg_val, PCIE0W); - reg_val = tsa_read_32(PCIE1W); - mc_set_tsa_hub2(reg_val, PCIE1W); - reg_val = tsa_read_32(PCIE2AW); - mc_set_tsa_hub2(reg_val, PCIE2AW); - reg_val = tsa_read_32(PCIE3W); - mc_set_tsa_hub2(reg_val, PCIE3W); - reg_val = tsa_read_32(PCIE4W); - mc_set_tsa_hub2(reg_val, PCIE4W); - reg_val = tsa_read_32(SATAW); - mc_set_tsa_hub2(reg_val, SATAW); - reg_val = tsa_read_32(XUSB_DEVW); - mc_set_tsa_hub2(reg_val, XUSB_DEVW); - reg_val = tsa_read_32(XUSB_HOSTW); - mc_set_tsa_hub2(reg_val, XUSB_HOSTW); - - /* - * Hw Bug: 200385660, 200394107 - * PCIE datapath hangs when there are more than 28 outstanding - * requests on data backbone for x1 controller. This is seen - * on third party PCIE IP, C1 - PCIE1W, C2 - PCIE2AW and C3 - PCIE3W. - * - * Setting Reorder depth limit, 16 which is < 28. - */ - mc_set_tsa_depth_limit(REORDER_DEPTH_LIMIT, PCIE1W); - mc_set_tsa_depth_limit(REORDER_DEPTH_LIMIT, PCIE2AW); - mc_set_tsa_depth_limit(REORDER_DEPTH_LIMIT, PCIE3W); - - /* Ordered MC Clients on Xavier are EQOS, SATA, XUSB, PCIe1 and PCIe3 - * ISO clients(DISP, VI, EQOS) should never snoop caches and - * don't need ROC/PCFIFO ordering. - * ISO clients(EQOS) that need ordering should use PCFIFO ordering - * and bypass ROC ordering by using FORCE_NON_COHERENT path. - * FORCE_NON_COHERENT/FORCE_COHERENT config take precedence - * over SMMU attributes. - * Force all Normal memory transactions from ISO and non-ISO to be - * non-coherent(bypass ROC, avoid cache snoop to avoid perf hit). - * Force the SO_DEV transactions from ordered ISO clients(EQOS) to - * non-coherent path and enable MC PCFIFO interlock for ordering. - * Force the SO_DEV transactions from ordered non-ISO clients (PCIe, - * XUSB, SATA) to coherent so that the transactions are - * ordered by ROC. - * PCFIFO ensure write ordering. - * Read after Write ordering is maintained/enforced by MC clients. - * Clients that need PCIe type write ordering must - * go through ROC ordering. - * Ordering enable for Read clients is not necessary. - * R5's and A9 would get necessary ordering from AXI and - * don't need ROC ordering enable: - * - MMIO ordering is through dev mapping and MMIO - * accesses bypass SMMU. - * - Normal memory is accessed through SMMU and ordering is - * ensured by client and AXI. - * - Ack point for Normal memory is WCAM in MC. - * - MMIO's can be early acked and AXI ensures dev memory ordering, - * Client ensures read/write direction change ordering. - * - See Bug 200312466 for more details. - */ - mc_set_txn_override(AONDMAR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(AONDMAW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(AONR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(AONW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(APEDMAR, CGID_TAG_ADR, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(APEDMAW, CGID_TAG_ADR, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(APER, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(APEW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(AXISR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(AXISW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(BPMPDMAR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(BPMPDMAW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(BPMPR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(BPMPW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(EQOSR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(EQOSW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(ETRR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(ETRW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(HOST1XDMAR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(MPCORER, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); - mc_set_txn_override(MPCOREW, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); - mc_set_txn_override(NVDISPLAYR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(NVDISPLAYR1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(PCIE0R, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); - mc_set_txn_override(PCIE0R1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); - mc_set_txn_override(PCIE0W, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); - mc_set_txn_override(PCIE1R, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); - mc_set_txn_override(PCIE1W, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); - if (tegra_platform_is_silicon()) { - mc_set_txn_override(PCIE2AR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); - mc_set_txn_override(PCIE2AW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); - mc_set_txn_override(PCIE3R, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); - mc_set_txn_override(PCIE3W, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); - mc_set_txn_override(PCIE4R, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); - mc_set_txn_override(PCIE4W, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); - mc_set_txn_override(PCIE5R, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); - mc_set_txn_override(PCIE5W, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); - mc_set_txn_override(PCIE5R1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); - } - mc_set_txn_override(PTCR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(RCEDMAR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(RCEDMAW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(RCER, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(RCEW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(SATAR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); - mc_set_txn_override(SATAW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); - mc_set_txn_override(SCEDMAR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(SCEDMAW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(SCER, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(SCEW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(SDMMCR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(SDMMCRAB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(SDMMCRA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(SDMMCW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(SDMMCWA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(SDMMCWAB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - /* - * TO DO: make SESRD/WR FORCE_COHERENT once SE+TZ with SMMU is enabled. - */ - mc_set_txn_override(SESRD, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); - mc_set_txn_override(SESWR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); - mc_set_txn_override(TSECSRD, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(TSECSRDB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(TSECSWR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(TSECSWRB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(UFSHCR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(UFSHCW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(VICSRD, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(VICSRD1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(VICSWR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(VIFALR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(VIFALW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(XUSB_DEVR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); - mc_set_txn_override(XUSB_DEVW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); - mc_set_txn_override(XUSB_HOSTR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); - mc_set_txn_override(XUSB_HOSTW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); - mc_set_txn_override(AXIAPR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(AXIAPW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(DLA0FALRDB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(DLA0FALWRB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(DLA0RDA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(DLA0RDA1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(DLA0WRA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(DLA1FALRDB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(DLA1FALWRB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(DLA1RDA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(DLA1RDA1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(DLA1WRA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(HDAR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(HDAW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(ISPFALR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(ISPFALW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(ISPRA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(ISPRA1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(ISPWA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(ISPWB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(NVDEC1SRD, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(NVDEC1SRD1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(NVDEC1SWR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(NVDECSRD, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(NVDECSRD1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(NVDECSWR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(NVENC1SRD, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(NVENC1SRD1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(NVENC1SWR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(NVENCSRD, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(NVENCSRD1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(NVENCSWR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(NVJPGSRD, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(NVJPGSWR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(PVA0RDA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(PVA0RDA1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(PVA0RDB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(PVA0RDB1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(PVA0RDC, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(PVA0WRA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(PVA0WRB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(PVA0WRC, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(PVA1RDA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(PVA1RDA1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(PVA1RDB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(PVA1RDB1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(PVA1RDC, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(PVA1WRA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(PVA1WRB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(PVA1WRC, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); - mc_set_txn_override(VIW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - - if (tegra_platform_is_silicon()) { - mc_set_txn_override(MIU0R, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); - mc_set_txn_override(MIU0W, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); - mc_set_txn_override(MIU1R, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); - mc_set_txn_override(MIU1W, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); - mc_set_txn_override(MIU2R, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); - mc_set_txn_override(MIU2W, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); - mc_set_txn_override(MIU3R, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); - mc_set_txn_override(MIU3W, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); - mc_set_txn_override(MIU4R, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); - mc_set_txn_override(MIU4W, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); - mc_set_txn_override(MIU5R, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); - mc_set_txn_override(MIU5W, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); - mc_set_txn_override(MIU6R, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); - mc_set_txn_override(MIU6W, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); - mc_set_txn_override(MIU7R, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); - mc_set_txn_override(MIU7W, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); - } - - /* - * At this point, ordering can occur at SCF. So, remove PCFIFO's - * control over ordering requests. - * - * Change PCFIFO_*_ORDERED_CLIENT from ORDERED -> UNORDERED for - * boot and strongly ordered MSS clients - */ - reg_val = MC_PCFIFO_CLIENT_CONFIG2_RESET_VAL & - mc_set_pcfifo_unordered_boot_so_mss(2, XUSB_HOSTW) & - mc_set_pcfifo_unordered_boot_so_mss(2, TSECSWR); - tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG2, reg_val); - - reg_val = MC_PCFIFO_CLIENT_CONFIG3_RESET_VAL & - mc_set_pcfifo_unordered_boot_so_mss(3, SDMMCWA) & - mc_set_pcfifo_unordered_boot_so_mss(3, SDMMCW) & - mc_set_pcfifo_unordered_boot_so_mss(3, SDMMCWAB) & - mc_set_pcfifo_unordered_boot_so_mss(3, VICSWR) & - mc_set_pcfifo_unordered_boot_so_mss(3, APEW); - tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG3, reg_val); - - reg_val = MC_PCFIFO_CLIENT_CONFIG4_RESET_VAL & - mc_set_pcfifo_unordered_boot_so_mss(4, SESWR) & - mc_set_pcfifo_unordered_boot_so_mss(4, ETRW) & - mc_set_pcfifo_unordered_boot_so_mss(4, TSECSWRB) & - mc_set_pcfifo_unordered_boot_so_mss(4, AXISW) & - mc_set_pcfifo_unordered_boot_so_mss(4, UFSHCW) & - mc_set_pcfifo_unordered_boot_so_mss(4, BPMPW) & - mc_set_pcfifo_unordered_boot_so_mss(4, BPMPDMAW) & - mc_set_pcfifo_unordered_boot_so_mss(4, AONW) & - mc_set_pcfifo_unordered_boot_so_mss(4, AONDMAW) & - mc_set_pcfifo_unordered_boot_so_mss(4, SCEW) & - mc_set_pcfifo_unordered_boot_so_mss(4, SCEDMAW); - /* EQOSW has PCFIFO order enabled. */ - reg_val |= mc_set_pcfifo_unordered_boot_so_mss(4, EQOSW); - tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG4, reg_val); - - reg_val = MC_PCFIFO_CLIENT_CONFIG5_RESET_VAL & - mc_set_pcfifo_unordered_boot_so_mss(5, APEDMAW) & - mc_set_pcfifo_unordered_boot_so_mss(5, VIFALW); - tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG5, reg_val); - - reg_val = MC_PCFIFO_CLIENT_CONFIG6_RESET_VAL & - mc_set_pcfifo_unordered_boot_so_mss(6, RCEW) & - mc_set_pcfifo_unordered_boot_so_mss(6, RCEDMAW) & - mc_set_pcfifo_unordered_boot_so_mss(6, PCIE0W); - tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG6, reg_val); - - reg_val = MC_PCFIFO_CLIENT_CONFIG7_RESET_VAL & - mc_set_pcfifo_unordered_boot_so_mss(7, PCIE4W) & - mc_set_pcfifo_unordered_boot_so_mss(7, PCIE5W); - tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG7, reg_val); - - /* Set Order Id only for the clients having non zero order id */ - reg_val = mc_client_order_id(MC_CLIENT_ORDER_ID_9_RESET_VAL, 9, XUSB_HOSTW); - tegra_mc_write_32(MC_CLIENT_ORDER_ID_9, reg_val); - - reg_val = mc_client_order_id(MC_CLIENT_ORDER_ID_27_RESET_VAL, 27, PCIE0W); - tegra_mc_write_32(MC_CLIENT_ORDER_ID_27, reg_val); - - reg_val = mc_client_order_id(MC_CLIENT_ORDER_ID_28_RESET_VAL, 28, PCIE4W); - reg_val = mc_client_order_id(reg_val, 28, PCIE5W); - tegra_mc_write_32(MC_CLIENT_ORDER_ID_28, reg_val); - - /* - * Set VC Id only for the clients having different reset values like - * SDMMCRAB, SDMMCWAB, SESRD, SESWR, TSECSRD,TSECSRDB, TSECSWR and - * TSECSWRB clients - */ - reg_val = mc_hub_vc_id(MC_HUB_PC_VC_ID_0_RESET_VAL, 0, APB); - tegra_mc_write_32(MC_HUB_PC_VC_ID_0, reg_val); - - /* SDMMCRAB and SDMMCWAB clients */ - reg_val = mc_hub_vc_id(MC_HUB_PC_VC_ID_2_RESET_VAL, 2, SD); - tegra_mc_write_32(MC_HUB_PC_VC_ID_2, reg_val); - - reg_val = mc_hub_vc_id(MC_HUB_PC_VC_ID_4_RESET_VAL, 4, NIC); - tegra_mc_write_32(MC_HUB_PC_VC_ID_4, reg_val); - - reg_val = mc_hub_vc_id(MC_HUB_PC_VC_ID_12_RESET_VAL, 12, UFSHCPC2); - tegra_mc_write_32(MC_HUB_PC_VC_ID_12, reg_val); - - wdata_0 = MC_CLIENT_HOTRESET_CTRL0_RESET_VAL; - tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL0, wdata_0); - - wdata_1 = MC_CLIENT_HOTRESET_CTRL1_RESET_VAL; - tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL1, wdata_1); - - wdata_2 = MC_CLIENT_HOTRESET_CTRL2_RESET_VAL; - tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL2, wdata_2); - - reg_val = MC_COALESCE_CTRL_COALESCER_ENABLE; - tegra_mc_write_32(MC_COALESCE_CTRL, reg_val); - - /* - * WAR to hardware bug 1953865: Coalescer must be disabled - * for PVA0RDC and PVA1RDC interfaces. - */ - reg_val = tegra_mc_read_32(MC_COALESCE_CONFIG_6_0); - reg_val &= ~(MC_COALESCE_CONFIG_6_0_PVA0RDC_COALESCER_ENABLED | - MC_COALESCE_CONFIG_6_0_PVA1RDC_COALESCER_ENABLED); - tegra_mc_write_32(MC_COALESCE_CONFIG_6_0, reg_val); -} - /******************************************************************************* * Struct to hold the memory controller settings ******************************************************************************/ @@ -685,8 +278,7 @@ static tegra_mc_settings_t tegra194_mc_settings = { .streamid_override_cfg = tegra194_streamid_override_regs, .num_streamid_override_cfgs = (uint32_t)ARRAY_SIZE(tegra194_streamid_override_regs), .streamid_security_cfg = tegra194_streamid_sec_cfgs, - .num_streamid_security_cfgs = (uint32_t)ARRAY_SIZE(tegra194_streamid_sec_cfgs), - .reconfig_mss_clients = tegra194_memctrl_reconfig_mss_clients + .num_streamid_security_cfgs = (uint32_t)ARRAY_SIZE(tegra194_streamid_sec_cfgs) }; /******************************************************************************* -- cgit v1.2.3 From a69a30ff238822539104ffc304696cd796685557 Mon Sep 17 00:00:00 2001 From: Pravin Date: Fri, 11 May 2018 15:14:19 +0530 Subject: Tegra194: memctrl: add support for MIU4 and MIU5 This patch adds support for memqual miu 4,5. The MEMQUAL engine has miu0 to miu7 in which miu6 and miu7 is hardwired to bypass SMMU. So only miu0 to miu5 support is provided. Change-Id: Ib350334eec521e65f395f1c3205e2cdaf464ebea Signed-off-by: Pravin --- plat/nvidia/tegra/soc/t194/plat_memctrl.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/plat/nvidia/tegra/soc/t194/plat_memctrl.c b/plat/nvidia/tegra/soc/t194/plat_memctrl.c index 8a946da56..d5f72b614 100644 --- a/plat/nvidia/tegra/soc/t194/plat_memctrl.c +++ b/plat/nvidia/tegra/soc/t194/plat_memctrl.c @@ -138,7 +138,11 @@ const static uint32_t tegra194_streamid_override_regs[] = { MC_STREAMID_OVERRIDE_CFG_MIU2R, MC_STREAMID_OVERRIDE_CFG_MIU2W, MC_STREAMID_OVERRIDE_CFG_MIU3R, - MC_STREAMID_OVERRIDE_CFG_MIU3W + MC_STREAMID_OVERRIDE_CFG_MIU3W, + MC_STREAMID_OVERRIDE_CFG_MIU4R, + MC_STREAMID_OVERRIDE_CFG_MIU4W, + MC_STREAMID_OVERRIDE_CFG_MIU5R, + MC_STREAMID_OVERRIDE_CFG_MIU5W }; /******************************************************************************* @@ -268,7 +272,11 @@ const static mc_streamid_security_cfg_t tegra194_streamid_sec_cfgs[] = { mc_make_sec_cfg(MIU2R, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(MIU2W, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(MIU3R, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(MIU3W, NON_SECURE, OVERRIDE, DISABLE) + mc_make_sec_cfg(MIU3W, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(MIU4R, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(MIU4W, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(MIU5R, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(MIU5W, NON_SECURE, OVERRIDE, DISABLE) }; /******************************************************************************* -- cgit v1.2.3 From be85f0f7f765d442b1d0889314f3f6b4acab43d1 Mon Sep 17 00:00:00 2001 From: Mithun Maragiri Date: Fri, 20 Jul 2018 14:41:33 -0700 Subject: Tegra210: disable ERRATA_A57_829520 ERRATA_A57_829520 disables "indirect branch prediction" for EL1 on cpu reset, leading to 15% drop in CPU performance with coremark benchmarks. Tegra210 already has a hardware fix for ARM BUG#829520,so this errata is not needed. This patch disables the errata to get increased performance numbers. Change-Id: I0b42e8badd19a8101f6a55d80eb2d953597d3c20 Signed-off-by: Mithun Maragiri --- plat/nvidia/tegra/soc/t210/platform_t210.mk | 1 - 1 file changed, 1 deletion(-) diff --git a/plat/nvidia/tegra/soc/t210/platform_t210.mk b/plat/nvidia/tegra/soc/t210/platform_t210.mk index 0d27bcdc5..ba827a073 100644 --- a/plat/nvidia/tegra/soc/t210/platform_t210.mk +++ b/plat/nvidia/tegra/soc/t210/platform_t210.mk @@ -46,7 +46,6 @@ A57_DISABLE_NON_TEMPORAL_HINT := 1 ERRATA_A57_826974 := 1 ERRATA_A57_826977 := 1 ERRATA_A57_828024 := 1 -ERRATA_A57_829520 := 1 ERRATA_A57_833471 := 1 # Enable workarounds for selected Cortex-A53 erratas. -- cgit v1.2.3 From 3827aa8ad2e2aa018e6a9f3fa28583ee5b4f8870 Mon Sep 17 00:00:00 2001 From: Jeetesh Burman Date: Thu, 31 May 2018 14:15:30 +0530 Subject: Tegra186: add support for bpmp_ipc driver This patch enables the bpmp-ipc driver for Tegra186 platforms, to ask BPMP firmware to toggle SE clock. Change-Id: Ie63587346c4d9b7e54767dbee17d0139fa2818ae Signed-off-by: Jeetesh Burman --- plat/nvidia/tegra/include/t186/tegra_def.h | 15 +++++++++++++++ plat/nvidia/tegra/soc/t186/plat_setup.c | 6 ++++++ plat/nvidia/tegra/soc/t186/platform_t186.mk | 6 ++++-- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/plat/nvidia/tegra/include/t186/tegra_def.h b/plat/nvidia/tegra/include/t186/tegra_def.h index f2a2334ef..f60f0b8ab 100644 --- a/plat/nvidia/tegra/include/t186/tegra_def.h +++ b/plat/nvidia/tegra/include/t186/tegra_def.h @@ -212,6 +212,14 @@ #define TEGRA_RNG1_BASE U(0x03AE0000) #define RNG_MUTEX_WATCHDOG_NS_LIMIT U(0xFE0) +/******************************************************************************* + * Tegra HSP doorbell #0 constants + ******************************************************************************/ +#define TEGRA_HSP_DBELL_BASE U(0x03C90000) +#define HSP_DBELL_1_ENABLE U(0x104) +#define HSP_DBELL_3_TRIGGER U(0x300) +#define HSP_DBELL_3_ENABLE U(0x304) + /******************************************************************************* * Tegra Clock and Reset Controller constants ******************************************************************************/ @@ -280,6 +288,13 @@ #define TEGRA_TZRAM_BASE U(0x30000000) #define TEGRA_TZRAM_SIZE U(0x40000) +/******************************************************************************* + * Tegra CCPLEX-BPMP IPC constants + ******************************************************************************/ +#define TEGRA_BPMP_IPC_TX_PHYS_BASE U(0x3004C000) +#define TEGRA_BPMP_IPC_RX_PHYS_BASE U(0x3004D000) +#define TEGRA_BPMP_IPC_CH_MAP_SIZE U(0x1000) /* 4KB */ + /******************************************************************************* * Tegra DRAM memory base address ******************************************************************************/ diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c index 7028bfc5d..e5d0d0133 100644 --- a/plat/nvidia/tegra/soc/t186/plat_setup.c +++ b/plat/nvidia/tegra/soc/t186/plat_setup.c @@ -106,6 +106,12 @@ static const mmap_region_t tegra_mmap[] = { MT_DEVICE | MT_RW | MT_SECURE), MAP_REGION_FLAT(TEGRA_SMMU0_BASE, 0x1000000U, /* 64KB */ MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(TEGRA_HSP_DBELL_BASE, 0x10000U, /* 64KB */ + MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(TEGRA_BPMP_IPC_TX_PHYS_BASE, TEGRA_BPMP_IPC_CH_MAP_SIZE, /* 4KB */ + MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(TEGRA_BPMP_IPC_RX_PHYS_BASE, TEGRA_BPMP_IPC_CH_MAP_SIZE, /* 4KB */ + MT_DEVICE | MT_RW | MT_SECURE), {0} }; diff --git a/plat/nvidia/tegra/soc/t186/platform_t186.mk b/plat/nvidia/tegra/soc/t186/platform_t186.mk index 197e4c6ba..9bb6959bd 100644 --- a/plat/nvidia/tegra/soc/t186/platform_t186.mk +++ b/plat/nvidia/tegra/soc/t186/platform_t186.mk @@ -30,10 +30,10 @@ $(eval $(call add_define,PLATFORM_CLUSTER_COUNT)) PLATFORM_MAX_CPUS_PER_CLUSTER := 4 $(eval $(call add_define,PLATFORM_MAX_CPUS_PER_CLUSTER)) -MAX_XLAT_TABLES := 24 +MAX_XLAT_TABLES := 25 $(eval $(call add_define,MAX_XLAT_TABLES)) -MAX_MMAP_REGIONS := 25 +MAX_MMAP_REGIONS := 27 $(eval $(call add_define,MAX_MMAP_REGIONS)) # platform files @@ -42,6 +42,8 @@ PLAT_INCLUDES += -I${SOC_DIR}/drivers/include BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \ lib/cpus/aarch64/denver.S \ lib/cpus/aarch64/cortex_a57.S \ + ${COMMON_DIR}/drivers/bpmp_ipc/intf.c \ + ${COMMON_DIR}/drivers/bpmp_ipc/ivc.c \ ${COMMON_DIR}/drivers/gpcdma/gpcdma.c \ ${COMMON_DIR}/drivers/memctrl/memctrl_v2.c \ ${COMMON_DIR}/drivers/smmu/smmu.c \ -- cgit v1.2.3 From 4eed9c8480c67bd4558c6763204c04fe9b812fae Mon Sep 17 00:00:00 2001 From: Jeetesh Burman Date: Thu, 19 Jul 2018 13:07:23 +0530 Subject: Tegra186: add SE support to generate SHA256 of TZRAM The BL3-1 firmware code is stored in TZSRAM on Tegra186 platforms. This memory loses power when we enter System Suspend and so its contents are stored to TZDRAM, before entry. This opens up an attack vector where the TZDRAM contents might be tampered with when we are in the System Suspend mode. To mitigate this attack the SE engine calculates the hash of entire TZSRAM and stores it in PMC scratch, before we copy data to TZDRAM. The WB0 code will validate the TZDRAM and match the hash with the one in PMC scratch. This patch adds driver for the SE engine, with APIs to calculate the hash and store SE SHA256 hash-result to PMC scratch registers. Change-Id: Ib487d5629225d3d99bd35d44f0402d6d3cf27ddf Signed-off-by: Jeetesh Burman --- .../nvidia/tegra/include/drivers/security_engine.h | 3 +- plat/nvidia/tegra/include/t186/tegra_def.h | 10 + plat/nvidia/tegra/soc/t186/drivers/se/se.c | 278 +++++++++++++++++++++ plat/nvidia/tegra/soc/t186/drivers/se/se_private.h | 100 ++++++++ plat/nvidia/tegra/soc/t186/plat_psci_handlers.c | 35 ++- plat/nvidia/tegra/soc/t186/platform_t186.mk | 1 + 6 files changed, 425 insertions(+), 2 deletions(-) create mode 100644 plat/nvidia/tegra/soc/t186/drivers/se/se.c create mode 100644 plat/nvidia/tegra/soc/t186/drivers/se/se_private.h diff --git a/plat/nvidia/tegra/include/drivers/security_engine.h b/plat/nvidia/tegra/include/drivers/security_engine.h index 8a249249b..5ae625793 100644 --- a/plat/nvidia/tegra/include/drivers/security_engine.h +++ b/plat/nvidia/tegra/include/drivers/security_engine.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. - * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -55,5 +55,6 @@ void tegra_se_init(void); int tegra_se_suspend(void); void tegra_se_resume(void); int tegra_se_save_tzram(void); +int32_t tegra_se_save_sha256_hash(uint64_t bl31_base, uint32_t src_len_inbyte); #endif /* SECURITY_ENGINE_H */ diff --git a/plat/nvidia/tegra/include/t186/tegra_def.h b/plat/nvidia/tegra/include/t186/tegra_def.h index f60f0b8ab..3d037e134 100644 --- a/plat/nvidia/tegra/include/t186/tegra_def.h +++ b/plat/nvidia/tegra/include/t186/tegra_def.h @@ -246,6 +246,7 @@ * Tegra scratch registers constants ******************************************************************************/ #define TEGRA_SCRATCH_BASE U(0x0C390000) +#define SECURE_SCRATCH_RSV0_HI U(0x654) #define SECURE_SCRATCH_RSV1_LO U(0x658) #define SECURE_SCRATCH_RSV1_HI U(0x65C) #define SECURE_SCRATCH_RSV6 U(0x680) @@ -255,6 +256,15 @@ #define SECURE_SCRATCH_RSV53_HI U(0x7FC) #define SECURE_SCRATCH_RSV55_LO U(0x808) #define SECURE_SCRATCH_RSV55_HI U(0x80C) +#define SECURE_SCRATCH_RSV63_LO U(0x848) +#define SECURE_SCRATCH_RSV63_HI U(0x84C) +#define SECURE_SCRATCH_RSV64_LO U(0x850) +#define SECURE_SCRATCH_RSV64_HI U(0x854) +#define SECURE_SCRATCH_RSV65_LO U(0x858) +#define SECURE_SCRATCH_RSV65_HI U(0x85c) +#define SECURE_SCRATCH_RSV66_LO U(0x860) +#define SECURE_SCRATCH_RSV66_HI U(0x864) +#define SECURE_SCRATCH_RSV68_LO U(0x870) #define SCRATCH_RESET_VECTOR_LO SECURE_SCRATCH_RSV1_LO #define SCRATCH_RESET_VECTOR_HI SECURE_SCRATCH_RSV1_HI diff --git a/plat/nvidia/tegra/soc/t186/drivers/se/se.c b/plat/nvidia/tegra/soc/t186/drivers/se/se.c new file mode 100644 index 000000000..dfb9de882 --- /dev/null +++ b/plat/nvidia/tegra/soc/t186/drivers/se/se.c @@ -0,0 +1,278 @@ +/* + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "se_private.h" + +/******************************************************************************* + * Constants and Macros + ******************************************************************************/ +#define SE0_MAX_BUSY_TIMEOUT_MS U(100) /* 100ms */ +#define BYTES_IN_WORD U(4) +#define SHA256_MAX_HASH_RESULT U(7) +#define SHA256_DST_SIZE U(32) +#define SHA_FIRST_OP U(1) +#define MAX_SHA_ENGINE_CHUNK_SIZE U(0xFFFFFF) +#define SHA256_MSG_LENGTH_ONETIME U(0xffff) + +/* + * Check that SE operation has completed after kickoff + * This function is invoked after an SE operation has been started, + * and it checks the following conditions: + * 1. SE0_INT_STATUS = SE0_OP_DONE + * 2. SE0_STATUS = IDLE + * 3. SE0_ERR_STATUS is clean. + */ +static int32_t tegra_se_operation_complete(void) +{ + uint32_t val = 0U; + + /* Read SE0 interrupt register to ensure H/W operation complete */ + val = tegra_se_read_32(SE0_INT_STATUS_REG_OFFSET); + if (SE0_INT_OP_DONE(val) == SE0_INT_OP_DONE_CLEAR) { + ERROR("%s: Engine busy state too many times! val = 0x%x\n", + __func__, val); + return -ETIMEDOUT; + } + + /* Read SE0 status idle to ensure H/W operation complete */ + val = tegra_se_read_32(SE0_SHA_STATUS_0); + if (val != SE0_SHA_STATUS_IDLE) { + ERROR("%s: Idle state timeout! val = 0x%x\n", __func__, + val); + return -ETIMEDOUT; + } + + /* Ensure that no errors are thrown during operation */ + val = tegra_se_read_32(SE0_ERR_STATUS_REG_OFFSET); + if (val != SE0_ERR_STATUS_CLEAR) { + ERROR("%s: Error during SE operation! val = 0x%x", + __func__, val); + return -ENOTSUP; + } + + return 0; +} + +/* + * Security engine primitive normal operations + */ +static int32_t tegra_se_start_normal_operation(uint64_t src_addr, + uint32_t nbytes, uint32_t last_buf, uint32_t src_len_inbytes) +{ + int32_t ret = 0; + uint32_t val = 0U; + uint32_t src_in_lo; + uint32_t src_in_msb; + uint32_t src_in_hi; + + if ((src_addr == 0UL) || (nbytes == 0U)) + return -EINVAL; + + src_in_lo = (uint32_t)src_addr; + src_in_msb = ((uint32_t)(src_addr >> 32U) & 0xffU); + src_in_hi = ((src_in_msb << SE0_IN_HI_ADDR_HI_0_MSB_SHIFT) | + (nbytes & 0xffffffU)); + + /* set SRC_IN_ADDR_LO and SRC_IN_ADDR_HI*/ + tegra_se_write_32(SE0_IN_ADDR, src_in_lo); + tegra_se_write_32(SE0_IN_HI_ADDR_HI, src_in_hi); + + val = tegra_se_read_32(SE0_INT_STATUS_REG_OFFSET); + if (val > 0U) { + tegra_se_write_32(SE0_INT_STATUS_REG_OFFSET, 0x00000U); + } + + /* Enable SHA interrupt for SE0 Operation */ + tegra_se_write_32(SE0_SHA_INT_ENABLE, 0x1aU); + + /* flush to DRAM for SE to use the updated contents */ + flush_dcache_range(src_addr, src_len_inbytes); + + /* Start SHA256 operation */ + if (last_buf == 1U) { + tegra_se_write_32(SE0_OPERATION_REG_OFFSET, SE0_OP_START | + SE0_UNIT_OPERATION_PKT_LASTBUF_FIELD); + } else { + tegra_se_write_32(SE0_OPERATION_REG_OFFSET, SE0_OP_START); + } + + /* Wait for SE-operation to finish */ + udelay(SE0_MAX_BUSY_TIMEOUT_MS * 100U); + + /* Check SE0 operation status */ + ret = tegra_se_operation_complete(); + if (ret != 0) { + ERROR("SE operation complete Failed! 0x%x", ret); + return ret; + } + + return 0; +} + +static int32_t tegra_se_calculate_sha256_hash(uint64_t src_addr, + uint32_t src_len_inbyte) +{ + uint32_t val, last_buf, i; + int32_t ret = 0; + uint32_t operations; + uint64_t src_len_inbits; + uint32_t len_bits_msb; + uint32_t len_bits_lsb; + uint32_t number_of_operations, max_bytes, bytes_left, remaining_bytes; + + if (src_len_inbyte > MAX_SHA_ENGINE_CHUNK_SIZE) { + ERROR("SHA input chunk size too big: 0x%x\n", src_len_inbyte); + return -EINVAL; + } + + if (src_addr == 0UL) { + return -EINVAL; + } + + /* number of bytes per operation */ + max_bytes = SHA256_HASH_SIZE_BYTES * SHA256_MSG_LENGTH_ONETIME; + + src_len_inbits = src_len_inbyte * 8U; + len_bits_msb = (uint32_t)(src_len_inbits >> 32U); + len_bits_lsb = (uint32_t)(src_len_inbits & 0xFFFFFFFF); + + /* program SE0_CONFIG for SHA256 operation */ + val = SE0_CONFIG_ENC_ALG_SHA | SE0_CONFIG_ENC_MODE_SHA256 | + SE0_CONFIG_DEC_ALG_NOP | SE0_CONFIG_DST_HASHREG; + tegra_se_write_32(SE0_SHA_CONFIG, val); + + /* set SE0_SHA_MSG_LENGTH registers */ + tegra_se_write_32(SE0_SHA_MSG_LENGTH_0, len_bits_lsb); + tegra_se_write_32(SE0_SHA_MSG_LEFT_0, len_bits_lsb); + tegra_se_write_32(SE0_SHA_MSG_LENGTH_1, len_bits_msb); + + /* zero out unused SE0_SHA_MSG_LENGTH and SE0_SHA_MSG_LEFT */ + tegra_se_write_32(SE0_SHA_MSG_LENGTH_2, 0U); + tegra_se_write_32(SE0_SHA_MSG_LENGTH_3, 0U); + tegra_se_write_32(SE0_SHA_MSG_LEFT_1, 0U); + tegra_se_write_32(SE0_SHA_MSG_LEFT_2, 0U); + tegra_se_write_32(SE0_SHA_MSG_LEFT_3, 0U); + + number_of_operations = src_len_inbyte / max_bytes; + remaining_bytes = src_len_inbyte % max_bytes; + if (remaining_bytes > 0U) { + number_of_operations += 1U; + } + + /* + * 1. Operations == 1: program SE0_SHA_TASK register to initiate SHA256 + * hash generation by setting + * 1(SE0_SHA_CONFIG_HW_INIT_HASH) to SE0_SHA_TASK + * and start SHA256-normal operation. + * 2. 1 < Operations < number_of_operations: program SE0_SHA_TASK to + * 0(SE0_SHA_CONFIG_HW_INIT_HASH_DISABLE) to load + * intermediate SHA256 digest result from + * HASH_RESULT register to continue SHA256 + * generation and start SHA256-normal operation. + * 3. Operations == number_of_operations: continue with step 2 and set + * max_bytes to bytes_left to process final + * hash-result generation and + * start SHA256-normal operation. + */ + bytes_left = src_len_inbyte; + for (operations = 1U; operations <= number_of_operations; + operations++) { + if (operations == SHA_FIRST_OP) { + val = SE0_SHA_CONFIG_HW_INIT_HASH; + } else { + /* Load intermediate SHA digest result to + * SHA:HASH_RESULT(0..7) to continue the SHA + * calculation and tell the SHA engine to use it. + */ + for (i = 0U; (i / BYTES_IN_WORD) <= + SHA256_MAX_HASH_RESULT; i += BYTES_IN_WORD) { + val = tegra_se_read_32(SE0_SHA_HASH_RESULT_0 + + i); + tegra_se_write_32(SE0_SHA_HASH_RESULT_0 + i, + val); + } + val = SE0_SHA_CONFIG_HW_INIT_HASH_DISABLE; + if (len_bits_lsb <= (max_bytes * 8U)) { + len_bits_lsb = (remaining_bytes * 8U); + } else { + len_bits_lsb -= (max_bytes * 8U); + } + tegra_se_write_32(SE0_SHA_MSG_LEFT_0, len_bits_lsb); + } + tegra_se_write_32(SE0_SHA_TASK_CONFIG, val); + + max_bytes = (SHA256_HASH_SIZE_BYTES * + SHA256_MSG_LENGTH_ONETIME); + if (bytes_left < max_bytes) { + max_bytes = bytes_left; + last_buf = 1U; + } else { + bytes_left = bytes_left - max_bytes; + last_buf = 0U; + } + /* start operation */ + ret = tegra_se_start_normal_operation(src_addr, max_bytes, + last_buf, src_len_inbyte); + if (ret != 0) { + ERROR("Error during SE operation! 0x%x", ret); + return -EINVAL; + } + } + + return ret; +} + +/* + * Handler to generate SHA256 and save SHA256 hash to PMC-Scratch register. + */ +int32_t tegra_se_save_sha256_hash(uint64_t bl31_base, uint32_t src_len_inbyte) +{ + int32_t ret = 0; + uint32_t val = 0U, hash_offset = 0U, scratch_offset = 0U, security; + + /* + * Set SE_SOFT_SETTINGS=SE_SECURE to prevent NS process to change SE + * registers. + */ + security = tegra_se_read_32(SE0_SECURITY); + tegra_se_write_32(SE0_SECURITY, security | SE0_SECURITY_SE_SOFT_SETTING); + + ret = tegra_se_calculate_sha256_hash(bl31_base, src_len_inbyte); + if (ret != 0L) { + ERROR("%s: SHA256 generation failed\n", __func__); + return ret; + } + + /* + * Reset SE_SECURE to previous value. + */ + tegra_se_write_32(SE0_SECURITY, security); + + /* read SHA256_HASH_RESULT and save to PMC Scratch registers */ + scratch_offset = SECURE_SCRATCH_TZDRAM_SHA256_HASH_START; + while (scratch_offset <= SECURE_SCRATCH_TZDRAM_SHA256_HASH_END) { + + val = tegra_se_read_32(SE0_SHA_HASH_RESULT_0 + hash_offset); + mmio_write_32(TEGRA_SCRATCH_BASE + scratch_offset, val); + + hash_offset += BYTES_IN_WORD; + scratch_offset += BYTES_IN_WORD; + } + + return ret; +} + diff --git a/plat/nvidia/tegra/soc/t186/drivers/se/se_private.h b/plat/nvidia/tegra/soc/t186/drivers/se/se_private.h new file mode 100644 index 000000000..7aa0dd691 --- /dev/null +++ b/plat/nvidia/tegra/soc/t186/drivers/se/se_private.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SE_PRIVATE_H +#define SE_PRIVATE_H + +#include + +/* SE0 security register */ +#define SE0_SECURITY U(0x18) +#define SE0_SECURITY_SE_SOFT_SETTING (((uint32_t)1) << 16U) + +/* SE0 config register */ +#define SE0_SHA_CONFIG U(0x104) +#define SE0_SHA_TASK_CONFIG U(0x108) +#define SE0_SHA_CONFIG_HW_INIT_HASH ((1U) << 0U) +#define SE0_SHA_CONFIG_HW_INIT_HASH_DISABLE U(0) + +#define SE0_CONFIG_ENC_ALG_SHIFT U(12) +#define SE0_CONFIG_ENC_ALG_SHA \ + (((uint32_t)3) << SE0_CONFIG_ENC_ALG_SHIFT) +#define SE0_CONFIG_DEC_ALG_SHIFT U(8) +#define SE0_CONFIG_DEC_ALG_NOP \ + (((uint32_t)0) << SE0_CONFIG_DEC_ALG_SHIFT) +#define SE0_CONFIG_DST_SHIFT U(2) +#define SE0_CONFIG_DST_HASHREG \ + (((uint32_t)1) << SE0_CONFIG_DST_SHIFT) +#define SHA256_HASH_SIZE_BYTES U(256) + +#define SE0_CONFIG_ENC_MODE_SHIFT U(24) +#define SE0_CONFIG_ENC_MODE_SHA256 \ + (((uint32_t)5) << SE0_CONFIG_ENC_MODE_SHIFT) + +/* SHA input message length */ +#define SE0_SHA_MSG_LENGTH_0 U(0x11c) +#define SE0_SHA_MSG_LENGTH_1 U(0x120) +#define SE0_SHA_MSG_LENGTH_2 U(0x124) +#define SE0_SHA_MSG_LENGTH_3 U(0x128) + +/* SHA input message left */ +#define SE0_SHA_MSG_LEFT_0 U(0x12c) +#define SE0_SHA_MSG_LEFT_1 U(0x130) +#define SE0_SHA_MSG_LEFT_2 U(0x134) +#define SE0_SHA_MSG_LEFT_3 U(0x138) + +/* SE Hash Result */ +#define SE0_SHA_HASH_RESULT_0 U(0x13c) + +/* SE OPERATION */ +#define SE0_OPERATION_REG_OFFSET U(0x17c) +#define SE0_UNIT_OPERATION_PKT_LASTBUF_SHIFT U(16) +#define SE0_UNIT_OPERATION_PKT_LASTBUF_FIELD \ + (((uint32_t)0x1) << SE0_UNIT_OPERATION_PKT_LASTBUF_SHIFT) +#define SE0_OPERATION_SHIFT U(0) +#define SE0_OP_START \ + (((uint32_t)0x1) << SE0_OPERATION_SHIFT) + +/* SE Interrupt */ +#define SE0_SHA_INT_ENABLE U(0x180) + +#define SE0_INT_STATUS_REG_OFFSET U(0x184) +#define SE0_INT_OP_DONE_SHIFT U(4) +#define SE0_INT_OP_DONE_CLEAR \ + (((uint32_t)0) << SE0_INT_OP_DONE_SHIFT) +#define SE0_INT_OP_DONE(x) \ + ((x) & (((uint32_t)0x1) << SE0_INT_OP_DONE_SHIFT)) + +/* SE SHA status */ +#define SE0_SHA_STATUS_0 U(0x188) +#define SE0_SHA_STATUS_IDLE U(0) + +/* SE error status */ +#define SE0_ERR_STATUS_REG_OFFSET U(0x18c) +#define SE0_ERR_STATUS_CLEAR U(0) +#define SE0_IN_ADDR U(0x10c) +#define SE0_IN_HI_ADDR_HI U(0x110) +#define SE0_IN_HI_ADDR_HI_0_MSB_SHIFT U(24) + +/* SE error status */ +#define SECURE_SCRATCH_TZDRAM_SHA256_HASH_START SECURE_SCRATCH_RSV63_LO +#define SECURE_SCRATCH_TZDRAM_SHA256_HASH_END SECURE_SCRATCH_RSV66_HI + +/******************************************************************************* + * Inline functions definition + ******************************************************************************/ + +static inline uint32_t tegra_se_read_32(uint32_t offset) +{ + return mmio_read_32((uint32_t)(TEGRA_SE0_BASE + offset)); +} + +static inline void tegra_se_write_32(uint32_t offset, uint32_t val) +{ + mmio_write_32(((uint32_t)(TEGRA_SE0_BASE + offset)), val); +} + +#endif /* SE_PRIVATE_H */ diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c index 2000e53fd..a0879cc0d 100644 --- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c @@ -6,6 +6,7 @@ */ #include +#include #include #include @@ -19,9 +20,10 @@ #include #include +#include #include +#include #include -#include #include #include #include @@ -280,8 +282,33 @@ int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_sta uint8_t stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL] & TEGRA186_STATE_ID_MASK; uint64_t val; + uint64_t src_len_in_bytes = (uint64_t)(((uintptr_t)(&__BL31_END__) - + (uintptr_t)BL31_BASE)); + int32_t ret; if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) { + val = params_from_bl2->tzdram_base + + tegra186_get_cpu_reset_handler_size(); + + /* Initialise communication channel with BPMP */ + assert(tegra_bpmp_ipc_init() == 0); + + /* Enable SE clock */ + ret = tegra_bpmp_ipc_enable_clock(TEGRA_CLK_SE); + if (ret != 0) { + ERROR("Failed to enable clock\n"); + return ret; + } + + /* + * Generate/save SHA256 of ATF during SC7 entry + */ + if (tegra_se_save_sha256_hash(BL31_BASE, + (uint32_t)src_len_in_bytes) != 0) { + ERROR("Hash calculation failed. Reboot\n"); + (void)tegra_soc_prepare_system_reset(); + } + /* * The TZRAM loses power when we enter system suspend. To * allow graceful exit from system suspend, we need to copy @@ -291,6 +318,12 @@ int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_sta tegra186_get_cpu_reset_handler_size(); memcpy16((void *)(uintptr_t)val, (void *)(uintptr_t)BL31_BASE, (uintptr_t)BL31_END - (uintptr_t)BL31_BASE); + + ret = tegra_bpmp_ipc_disable_clock(TEGRA_CLK_SE); + if (ret != 0) { + ERROR("Failed to disable clock\n"); + return ret; + } } return PSCI_E_SUCCESS; diff --git a/plat/nvidia/tegra/soc/t186/platform_t186.mk b/plat/nvidia/tegra/soc/t186/platform_t186.mk index 9bb6959bd..d79155f31 100644 --- a/plat/nvidia/tegra/soc/t186/platform_t186.mk +++ b/plat/nvidia/tegra/soc/t186/platform_t186.mk @@ -51,6 +51,7 @@ BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \ ${SOC_DIR}/drivers/mce/ari.c \ ${SOC_DIR}/drivers/mce/nvg.c \ ${SOC_DIR}/drivers/mce/aarch64/nvg_helpers.S \ + $(SOC_DIR)/drivers/se/se.c \ ${SOC_DIR}/plat_memctrl.c \ ${SOC_DIR}/plat_psci_handlers.c \ ${SOC_DIR}/plat_setup.c \ -- cgit v1.2.3 From 7d74487c2afb0d9c69ab6c640060bdf711929edc Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Thu, 28 Jun 2018 11:03:41 -0700 Subject: Tegra186: store TZDRAM base/size to scratch registers This patch saves the TZDRAM base and size values to secure scratch registers, for the WB0. The WB0 reads these values and uses them to verify integrity of the TZDRAM aperture. Change-Id: Ic70914cb958249f06cb58025a24d13734a85e16e Signed-off-by: Jeetesh Burman Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/soc/t186/plat_memctrl.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/plat/nvidia/tegra/soc/t186/plat_memctrl.c b/plat/nvidia/tegra/soc/t186/plat_memctrl.c index 4ca5e77ad..a97496bd1 100644 --- a/plat/nvidia/tegra/soc/t186/plat_memctrl.c +++ b/plat/nvidia/tegra/soc/t186/plat_memctrl.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -10,7 +11,11 @@ #include #include #include +#include #include +#include + +extern uint64_t tegra_bl31_phys_base; /******************************************************************************* * Array to hold stream_id override config register offsets @@ -540,6 +545,13 @@ tegra_mc_settings_t *tegra_get_mc_settings(void) void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes) { uint32_t val; + uint64_t src_base_tzdram; + const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); + uint64_t src_len_in_bytes = BL31_END - BL31_START; + + /* base address of BL3-1 source in TZDRAM */ + src_base_tzdram = params_from_bl2->tzdram_base + + tegra186_get_cpu_reset_handler_size(); /* * Setup the Memory controller to allow only secure accesses to @@ -568,6 +580,15 @@ void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes) val = tegra_mc_read_32(MC_SECURITY_CFG3_0) & MC_SECURITY_BOM_HI_MASK; mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_TZDRAM_ADDR_HI, val); + /* + * save tzdram_addr_lo and ATF-size, this would be used in SC7-RF to + * generate SHA256. + */ + mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV68_LO, + (uint32_t)src_base_tzdram); + mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV0_HI, + (uint32_t)src_len_in_bytes); + /* * MCE propagates the security configuration values across the * CCPLEX. -- cgit v1.2.3 From 6e19bd563db0bca61c4d05f2e4ffd5110ca3b0a2 Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Fri, 21 Feb 2020 10:17:26 +0000 Subject: TF-A GICv3 driver: Separate GICD and GICR accessor functions This patch provides separation of GICD, GICR accessor functions and adds new macros for GICv3 registers access as a preparation for GICv3.1 and GICv4 support. NOTE: Platforms need to modify to include both 'gicdv3_helpers.c' and 'gicrv3_helpers.c' instead of the single helper file previously. Change-Id: I1641bd6d217d6eb7d1228be3c4177b2d556da60a Signed-off-by: Alexei Fedorov --- drivers/arm/gic/v3/gicdv3_helpers.c | 58 +++++++ drivers/arm/gic/v3/gicrv3_helpers.c | 215 +++++++++++++++++++++++++ drivers/arm/gic/v3/gicv3_helpers.c | 258 ------------------------------ drivers/arm/gic/v3/gicv3_private.h | 149 ++++++++++++++--- include/drivers/arm/gicv3.h | 6 +- plat/arm/board/fvp/platform.mk | 2 + plat/arm/board/n1sdp/platform.mk | 4 +- plat/arm/css/sgi/sgi-common.mk | 4 +- plat/arm/css/sgm/sgm-common.mk | 4 +- plat/imx/imx8m/imx8mm/platform.mk | 4 +- plat/imx/imx8m/imx8mq/platform.mk | 4 +- plat/imx/imx8qm/platform.mk | 4 +- plat/imx/imx8qx/platform.mk | 4 +- plat/marvell/a3700/common/a3700_common.mk | 2 + plat/mediatek/mt8183/platform.mk | 2 + plat/qemu/qemu/platform.mk | 4 +- plat/qemu/qemu_sbsa/platform.mk | 2 + plat/rockchip/rk3399/platform.mk | 4 +- plat/socionext/synquacer/platform.mk | 4 +- plat/socionext/uniphier/platform.mk | 2 + plat/ti/k3/common/plat_common.mk | 4 +- plat/xilinx/versal/platform.mk | 2 + 22 files changed, 444 insertions(+), 298 deletions(-) create mode 100644 drivers/arm/gic/v3/gicdv3_helpers.c create mode 100644 drivers/arm/gic/v3/gicrv3_helpers.c diff --git a/drivers/arm/gic/v3/gicdv3_helpers.c b/drivers/arm/gic/v3/gicdv3_helpers.c new file mode 100644 index 000000000..3f5ff45fc --- /dev/null +++ b/drivers/arm/gic/v3/gicdv3_helpers.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include "gicv3_private.h" + +/******************************************************************************* + * GIC Distributor interface accessors for bit operations + ******************************************************************************/ + +/* + * Accessor to read the GIC Distributor IGRPMODR corresponding to the + * interrupt `id`, 32 interrupt IDs at a time. + */ +uint32_t gicd_read_igrpmodr(uintptr_t base, unsigned int id) +{ + return GICD_READ(IGRPMODR, base, id); +} + +/* + * Accessor to write the GIC Distributor IGRPMODR corresponding to the + * interrupt `id`, 32 interrupt IDs at a time. + */ +void gicd_write_igrpmodr(uintptr_t base, unsigned int id, uint32_t val) +{ + GICD_WRITE(IGRPMODR, base, id, val); +} + +/* + * Accessor to get the bit corresponding to interrupt ID + * in GIC Distributor IGRPMODR. + */ +unsigned int gicd_get_igrpmodr(uintptr_t base, unsigned int id) +{ + return GICD_GET_BIT(IGRPMODR, base, id); +} + +/* + * Accessor to set the bit corresponding to interrupt ID + * in GIC Distributor IGRPMODR. + */ +void gicd_set_igrpmodr(uintptr_t base, unsigned int id) +{ + GICD_SET_BIT(IGRPMODR, base, id); +} + +/* + * Accessor to clear the bit corresponding to interrupt ID + * in GIC Distributor IGRPMODR. + */ +void gicd_clr_igrpmodr(uintptr_t base, unsigned int id) +{ + GICD_CLR_BIT(IGRPMODR, base, id); +} diff --git a/drivers/arm/gic/v3/gicrv3_helpers.c b/drivers/arm/gic/v3/gicrv3_helpers.c new file mode 100644 index 000000000..294acda5a --- /dev/null +++ b/drivers/arm/gic/v3/gicrv3_helpers.c @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include "gicv3_private.h" + +/******************************************************************************* + * GIC Redistributor functions + * Note: The raw register values correspond to multiple interrupt IDs and + * the number of interrupt IDs involved depends on the register accessed. + ******************************************************************************/ + +/* + * Accessor to read the GIC Redistributor IPRIORITYR corresponding to the + * interrupt `id`, 4 interrupts IDs at a time. + */ +unsigned int gicr_read_ipriorityr(uintptr_t base, unsigned int id) +{ + unsigned int n = id >> IPRIORITYR_SHIFT; + + return mmio_read_32(base + GICR_IPRIORITYR + (n << 2)); +} + +/* + * Accessor to write the GIC Redistributor IPRIORITYR corresponding to the + * interrupt `id`, 4 interrupts IDs at a time. + */ +void gicr_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val) +{ + unsigned int n = id >> IPRIORITYR_SHIFT; + + mmio_write_32(base + GICR_IPRIORITYR + (n << 2), val); +} + +/* + * Accessor to set the byte corresponding to interrupt ID + * in GIC Redistributor IPRIORITYR. + */ +void gicr_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri) +{ + GICR_WRITE_8(IPRIORITYR, base, id, pri & GIC_PRI_MASK); +} + +/* + * Accessor to get the bit corresponding to interrupt ID + * from GIC Redistributor IGROUPR0. + */ +unsigned int gicr_get_igroupr0(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U); + unsigned int reg_val = gicr_read_igroupr0(base); + + return (reg_val >> bit_num) & 0x1U; +} + +/* + * Accessor to set the bit corresponding to interrupt ID + * in GIC Redistributor IGROUPR0. + */ +void gicr_set_igroupr0(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U); + unsigned int reg_val = gicr_read_igroupr0(base); + + gicr_write_igroupr0(base, reg_val | (1U << bit_num)); +} + +/* + * Accessor to clear the bit corresponding to interrupt ID + * in GIC Redistributor IGROUPR0. + */ +void gicr_clr_igroupr0(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U); + unsigned int reg_val = gicr_read_igroupr0(base); + + gicr_write_igroupr0(base, reg_val & ~(1U << bit_num)); +} + +/* + * Accessor to get the bit corresponding to interrupt ID + * from GIC Redistributor IGRPMODR0. + */ +unsigned int gicr_get_igrpmodr0(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U); + unsigned int reg_val = gicr_read_igrpmodr0(base); + + return (reg_val >> bit_num) & 0x1U; +} + +/* + * Accessor to set the bit corresponding to interrupt ID + * in GIC Redistributor IGRPMODR0. + */ +void gicr_set_igrpmodr0(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U); + unsigned int reg_val = gicr_read_igrpmodr0(base); + + gicr_write_igrpmodr0(base, reg_val | (1U << bit_num)); +} + +/* + * Accessor to clear the bit corresponding to interrupt ID + * in GIC Redistributor IGRPMODR0. + */ +void gicr_clr_igrpmodr0(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U); + unsigned int reg_val = gicr_read_igrpmodr0(base); + + gicr_write_igrpmodr0(base, reg_val & ~(1U << bit_num)); +} + +/* + * Accessor to set the bit corresponding to interrupt ID + * in GIC Redistributor ISENABLER0. + */ +void gicr_set_isenabler0(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << ISENABLER_SHIFT) - 1U); + + gicr_write_isenabler0(base, (1U << bit_num)); +} + +/* + * Accessor to set the bit corresponding to interrupt ID in GIC Redistributor + * ICENABLER0. + */ +void gicr_set_icenabler0(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << ICENABLER_SHIFT) - 1U); + + gicr_write_icenabler0(base, (1U << bit_num)); +} + +/* + * Accessor to set the bit corresponding to interrupt ID in GIC Redistributor + * ISACTIVER0. + */ +unsigned int gicr_get_isactiver0(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << ISACTIVER_SHIFT) - 1U); + unsigned int reg_val = gicr_read_isactiver0(base); + + return (reg_val >> bit_num) & 0x1U; +} + +/* + * Accessor to clear the bit corresponding to interrupt ID in GIC Redistributor + * ICPENDRR0. + */ +void gicr_set_icpendr0(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << ICPENDR_SHIFT) - 1U); + + gicr_write_icpendr0(base, (1U << bit_num)); +} + +/* + * Accessor to set the bit corresponding to interrupt ID in GIC Redistributor + * ISPENDR0. + */ +void gicr_set_ispendr0(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << ISPENDR_SHIFT) - 1U); + + gicr_write_ispendr0(base, (1U << bit_num)); +} + +/* + * Accessor to set the bit fields corresponding to interrupt ID + * in GIC Redistributor ICFGR0. + */ +void gicr_set_icfgr0(uintptr_t base, unsigned int id, unsigned int cfg) +{ + /* Interrupt configuration is a 2-bit field */ + unsigned int bit_num = id & ((1U << ICFGR_SHIFT) - 1U); + unsigned int bit_shift = bit_num << 1U; + + uint32_t reg_val = gicr_read_icfgr0(base); + + /* Clear the field, and insert required configuration */ + reg_val &= ~(GIC_CFG_MASK << bit_shift); + reg_val |= ((cfg & GIC_CFG_MASK) << bit_shift); + + gicr_write_icfgr0(base, reg_val); +} + +/* + * Accessor to set the bit fields corresponding to interrupt ID + * in GIC Redistributor ICFGR1. + */ +void gicr_set_icfgr1(uintptr_t base, unsigned int id, unsigned int cfg) +{ + /* Interrupt configuration is a 2-bit field */ + unsigned int bit_num = id & ((1U << ICFGR_SHIFT) - 1U); + unsigned int bit_shift = bit_num << 1U; + + uint32_t reg_val = gicr_read_icfgr1(base); + + /* Clear the field, and insert required configuration */ + reg_val &= ~(GIC_CFG_MASK << bit_shift); + reg_val |= ((cfg & GIC_CFG_MASK) << bit_shift); + + gicr_write_icfgr1(base, reg_val); +} diff --git a/drivers/arm/gic/v3/gicv3_helpers.c b/drivers/arm/gic/v3/gicv3_helpers.c index 710532e3c..d5aaf9696 100644 --- a/drivers/arm/gic/v3/gicv3_helpers.c +++ b/drivers/arm/gic/v3/gicv3_helpers.c @@ -15,263 +15,6 @@ #include "../common/gic_common_private.h" #include "gicv3_private.h" -/* - * Accessor to read the GIC Distributor IGRPMODR corresponding to the - * interrupt `id`, 32 interrupt IDs at a time. - */ -unsigned int gicd_read_igrpmodr(uintptr_t base, unsigned int id) -{ - unsigned int n = id >> IGRPMODR_SHIFT; - - return mmio_read_32(base + GICD_IGRPMODR + (n << 2)); -} - -/* - * Accessor to write the GIC Distributor IGRPMODR corresponding to the - * interrupt `id`, 32 interrupt IDs at a time. - */ -void gicd_write_igrpmodr(uintptr_t base, unsigned int id, unsigned int val) -{ - unsigned int n = id >> IGRPMODR_SHIFT; - - mmio_write_32(base + GICD_IGRPMODR + (n << 2), val); -} - -/* - * Accessor to get the bit corresponding to interrupt ID - * in GIC Distributor IGRPMODR. - */ -unsigned int gicd_get_igrpmodr(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U); - unsigned int reg_val = gicd_read_igrpmodr(base, id); - - return (reg_val >> bit_num) & 0x1U; -} - -/* - * Accessor to set the bit corresponding to interrupt ID - * in GIC Distributor IGRPMODR. - */ -void gicd_set_igrpmodr(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U); - unsigned int reg_val = gicd_read_igrpmodr(base, id); - - gicd_write_igrpmodr(base, id, reg_val | (1U << bit_num)); -} - -/* - * Accessor to clear the bit corresponding to interrupt ID - * in GIC Distributor IGRPMODR. - */ -void gicd_clr_igrpmodr(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U); - unsigned int reg_val = gicd_read_igrpmodr(base, id); - - gicd_write_igrpmodr(base, id, reg_val & ~(1U << bit_num)); -} - -/* - * Accessor to read the GIC Re-distributor IPRIORITYR corresponding to the - * interrupt `id`, 4 interrupts IDs at a time. - */ -unsigned int gicr_read_ipriorityr(uintptr_t base, unsigned int id) -{ - unsigned int n = id >> IPRIORITYR_SHIFT; - - return mmio_read_32(base + GICR_IPRIORITYR + (n << 2)); -} - -/* - * Accessor to write the GIC Re-distributor IPRIORITYR corresponding to the - * interrupt `id`, 4 interrupts IDs at a time. - */ -void gicr_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val) -{ - unsigned int n = id >> IPRIORITYR_SHIFT; - - mmio_write_32(base + GICR_IPRIORITYR + (n << 2), val); -} - -/* - * Accessor to get the bit corresponding to interrupt ID - * from GIC Re-distributor IGROUPR0. - */ -unsigned int gicr_get_igroupr0(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U); - unsigned int reg_val = gicr_read_igroupr0(base); - - return (reg_val >> bit_num) & 0x1U; -} - -/* - * Accessor to set the bit corresponding to interrupt ID - * in GIC Re-distributor IGROUPR0. - */ -void gicr_set_igroupr0(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U); - unsigned int reg_val = gicr_read_igroupr0(base); - - gicr_write_igroupr0(base, reg_val | (1U << bit_num)); -} - -/* - * Accessor to clear the bit corresponding to interrupt ID - * in GIC Re-distributor IGROUPR0. - */ -void gicr_clr_igroupr0(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U); - unsigned int reg_val = gicr_read_igroupr0(base); - - gicr_write_igroupr0(base, reg_val & ~(1U << bit_num)); -} - -/* - * Accessor to get the bit corresponding to interrupt ID - * from GIC Re-distributor IGRPMODR0. - */ -unsigned int gicr_get_igrpmodr0(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U); - unsigned int reg_val = gicr_read_igrpmodr0(base); - - return (reg_val >> bit_num) & 0x1U; -} - -/* - * Accessor to set the bit corresponding to interrupt ID - * in GIC Re-distributor IGRPMODR0. - */ -void gicr_set_igrpmodr0(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U); - unsigned int reg_val = gicr_read_igrpmodr0(base); - - gicr_write_igrpmodr0(base, reg_val | (1U << bit_num)); -} - -/* - * Accessor to clear the bit corresponding to interrupt ID - * in GIC Re-distributor IGRPMODR0. - */ -void gicr_clr_igrpmodr0(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U); - unsigned int reg_val = gicr_read_igrpmodr0(base); - - gicr_write_igrpmodr0(base, reg_val & ~(1U << bit_num)); -} - -/* - * Accessor to set the bit corresponding to interrupt ID - * in GIC Re-distributor ISENABLER0. - */ -void gicr_set_isenabler0(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << ISENABLER_SHIFT) - 1U); - - gicr_write_isenabler0(base, (1U << bit_num)); -} - -/* - * Accessor to set the bit corresponding to interrupt ID in GIC Re-distributor - * ICENABLER0. - */ -void gicr_set_icenabler0(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << ICENABLER_SHIFT) - 1U); - - gicr_write_icenabler0(base, (1U << bit_num)); -} - -/* - * Accessor to set the bit corresponding to interrupt ID in GIC Re-distributor - * ISACTIVER0. - */ -unsigned int gicr_get_isactiver0(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << ISACTIVER_SHIFT) - 1U); - unsigned int reg_val = gicr_read_isactiver0(base); - - return (reg_val >> bit_num) & 0x1U; -} - -/* - * Accessor to clear the bit corresponding to interrupt ID in GIC Re-distributor - * ICPENDRR0. - */ -void gicr_set_icpendr0(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << ICPENDR_SHIFT) - 1U); - - gicr_write_icpendr0(base, (1U << bit_num)); -} - -/* - * Accessor to set the bit corresponding to interrupt ID in GIC Re-distributor - * ISPENDR0. - */ -void gicr_set_ispendr0(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << ISPENDR_SHIFT) - 1U); - - gicr_write_ispendr0(base, (1U << bit_num)); -} - -/* - * Accessor to set the byte corresponding to interrupt ID - * in GIC Re-distributor IPRIORITYR. - */ -void gicr_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri) -{ - uint8_t val = pri & GIC_PRI_MASK; - - mmio_write_8(base + GICR_IPRIORITYR + id, val); -} - -/* - * Accessor to set the bit fields corresponding to interrupt ID - * in GIC Re-distributor ICFGR0. - */ -void gicr_set_icfgr0(uintptr_t base, unsigned int id, unsigned int cfg) -{ - /* Interrupt configuration is a 2-bit field */ - unsigned int bit_num = id & ((1U << ICFGR_SHIFT) - 1U); - unsigned int bit_shift = bit_num << 1U; - - uint32_t reg_val = gicr_read_icfgr0(base); - - /* Clear the field, and insert required configuration */ - reg_val &= ~(GIC_CFG_MASK << bit_shift); - reg_val |= ((cfg & GIC_CFG_MASK) << bit_shift); - - gicr_write_icfgr0(base, reg_val); -} - -/* - * Accessor to set the bit fields corresponding to interrupt ID - * in GIC Re-distributor ICFGR1. - */ -void gicr_set_icfgr1(uintptr_t base, unsigned int id, unsigned int cfg) -{ - /* Interrupt configuration is a 2-bit field */ - unsigned int bit_num = id & ((1U << ICFGR_SHIFT) - 1U); - unsigned int bit_shift = bit_num << 1U; - - uint32_t reg_val = gicr_read_icfgr1(base); - - /* Clear the field, and insert required configuration */ - reg_val &= ~(GIC_CFG_MASK << bit_shift); - reg_val |= ((cfg & GIC_CFG_MASK) << bit_shift); - - gicr_write_icfgr1(base, reg_val); -} - /****************************************************************************** * This function marks the core as awake in the re-distributor and * ensures that the interface is active. @@ -292,7 +35,6 @@ void gicv3_rdistif_mark_core_awake(uintptr_t gicr_base) ; } - /****************************************************************************** * This function marks the core as asleep in the re-distributor and ensures * that the interface is quiescent. diff --git a/drivers/arm/gic/v3/gicv3_private.h b/drivers/arm/gic/v3/gicv3_private.h index 327a9a149..dae01cb1e 100644 --- a/drivers/arm/gic/v3/gicv3_private.h +++ b/drivers/arm/gic/v3/gicv3_private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -24,6 +24,100 @@ #define RWP_TRUE U(1) #define RWP_FALSE U(0) +/* Calculate GIC register bit number corresponding to its interrupt ID */ +#define BIT_NUM(REG, id) \ + ((id) & ((1U << REG##_SHIFT) - 1U)) + +/* Calculate 8-bit GICD register offset corresponding to its interrupt ID */ +#define GICD_OFFSET_8(REG, id) \ + GICD_##REG + (id) + +/* Calculate 32-bit GICD register offset corresponding to its interrupt ID */ +#define GICD_OFFSET(REG, id) \ + GICD_##REG + (((id) >> REG##_SHIFT) << 2) + +/* Calculate 64-bit GICD register offset corresponding to its interrupt ID */ +#define GICD_OFFSET_64(REG, id) \ + GICD_##REG + (((id) >> REG##_SHIFT) << 3) + +/* Read 32-bit GIC Distributor register corresponding to its interrupt ID */ +#define GICD_READ(REG, base, id) \ + mmio_read_32((base) + GICD_OFFSET(REG, (id))) + +/* Read 64-bit GIC Distributor register corresponding to its interrupt ID */ +#define GICD_READ_64(REG, base, id) \ + mmio_read_64((base) + GICD_OFFSET_64(REG, (id))) + +/* Write to 64-bit GIC Distributor register corresponding to its interrupt ID */ +#define GICD_WRITE_64(REG, base, id, val) \ + mmio_write_64((base) + GICD_OFFSET_64(REG, (id)), (val)) + +/* Write to 32-bit GIC Distributor register corresponding to its interrupt ID */ +#define GICD_WRITE(REG, base, id, val) \ + mmio_write_32((base) + GICD_OFFSET(REG, (id)), (val)) + +/* Write to 8-bit GIC Distributor register corresponding to its interrupt ID */ +#define GICD_WRITE_8(REG, base, id, val) \ + mmio_write_8((base) + GICD_OFFSET_8(REG, (id)), (val)) + +/* + * Bit operations on GIC Distributor register corresponding + * to its interrupt ID + */ +/* Get bit in GIC Distributor register */ +#define GICD_GET_BIT(REG, base, id) \ + ((mmio_read_32((base) + GICD_OFFSET(REG, (id))) >> \ + BIT_NUM(REG, (id))) & 1U) + +/* Set bit in GIC Distributor register */ +#define GICD_SET_BIT(REG, base, id) \ + mmio_setbits_32((base) + GICD_OFFSET(REG, (id)), \ + ((uint32_t)1 << BIT_NUM(REG, (id)))) + +/* Clear bit in GIC Distributor register */ +#define GICD_CLR_BIT(REG, base, id) \ + mmio_clrbits_32((base) + GICD_OFFSET(REG, (id)), \ + ((uint32_t)1 << BIT_NUM(REG, (id)))) + +/* Write bit in GIC Distributor register */ +#define GICD_WRITE_BIT(REG, base, id) \ + mmio_write_32((base) + GICD_OFFSET(REG, (id)), \ + ((uint32_t)1 << BIT_NUM(REG, (id)))) + +/* + * Calculate GICv3 GICR register offset + */ +#define GICR_OFFSET(REG, id) \ + GICR_##REG + (((id) >> REG##_SHIFT) << 2) + +/* Write to GIC Redistributor register corresponding to its interrupt ID */ +#define GICR_WRITE_8(REG, base, id, val) \ + mmio_write_8((base) + GICR_##REG + (id), (val)) + +/* + * Bit operations on GIC Redistributor register + * corresponding to its interrupt ID + */ +/* Get bit in GIC Redistributor register */ +#define GICR_GET_BIT(REG, base, id) \ + ((mmio_read_32((base) + GICR_OFFSET(REG, (id))) >> \ + BIT_NUM(REG, (id))) & 1U) + +/* Write bit in GIC Redistributor register */ +#define GICR_WRITE_BIT(REG, base, id) \ + mmio_write_32((base) + GICR_OFFSET(REG, (id)), \ + ((uint32_t)1 << BIT_NUM(REG, (id)))) + +/* Set bit in GIC Redistributor register */ +#define GICR_SET_BIT(REG, base, id) \ + mmio_setbits_32((base) + GICR_OFFSET(REG, (id)), \ + ((uint32_t)1 << BIT_NUM(REG, (id)))) + +/* Clear bit in GIC Redistributor register */ +#define GICR_CLR_BIT(REG, base, id) \ + mmio_clrbits_32((base) + GICR_OFFSET(REG, (id)), \ + ((uint32_t)1 << BIT_NUM(REG, (id)))) + /* * Macro to convert an mpidr to a value suitable for programming into a * GICD_IROUTER. Bits[31:24] in the MPIDR are cleared as they are not relevant @@ -63,9 +157,9 @@ extern const gicv3_driver_data_t *gicv3_driver_data; * Note: The raw register values correspond to multiple interrupt IDs and * the number of interrupt IDs involved depends on the register accessed. ******************************************************************************/ -unsigned int gicd_read_igrpmodr(uintptr_t base, unsigned int id); +uint32_t gicd_read_igrpmodr(uintptr_t base, unsigned int id); unsigned int gicr_read_ipriorityr(uintptr_t base, unsigned int id); -void gicd_write_igrpmodr(uintptr_t base, unsigned int id, unsigned int val); +void gicd_write_igrpmodr(uintptr_t base, unsigned int id, uint32_t val); void gicr_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val); /******************************************************************************* @@ -121,27 +215,27 @@ void gicv3_rdistif_mark_core_asleep(uintptr_t gicr_base); */ static inline void gicd_wait_for_pending_write(uintptr_t gicd_base) { - while ((gicd_read_ctlr(gicd_base) & GICD_CTLR_RWP_BIT) != 0U) - ; + while ((gicd_read_ctlr(gicd_base) & GICD_CTLR_RWP_BIT) != 0U) { + } } -static inline unsigned int gicd_read_pidr2(uintptr_t base) +static inline uint32_t gicd_read_pidr2(uintptr_t base) { return mmio_read_32(base + GICD_PIDR2_GICV3); } -static inline unsigned long long gicd_read_irouter(uintptr_t base, unsigned int id) +static inline uint64_t gicd_read_irouter(uintptr_t base, unsigned int id) { assert(id >= MIN_SPI_ID); - return mmio_read_64(base + GICD_IROUTER + (id << 3)); + return GICD_READ_64(IROUTER, base, id); } static inline void gicd_write_irouter(uintptr_t base, unsigned int id, - unsigned long long affinity) + uint64_t affinity) { assert(id >= MIN_SPI_ID); - mmio_write_64(base + GICD_IROUTER + (id << 3), affinity); + GICD_WRITE_64(IROUTER, base, id, affinity); } static inline void gicd_clr_ctlr(uintptr_t base, @@ -149,8 +243,9 @@ static inline void gicd_clr_ctlr(uintptr_t base, unsigned int rwp) { gicd_write_ctlr(base, gicd_read_ctlr(base) & ~bitmap); - if (rwp != 0U) + if (rwp != 0U) { gicd_wait_for_pending_write(base); + } } static inline void gicd_set_ctlr(uintptr_t base, @@ -158,8 +253,9 @@ static inline void gicd_set_ctlr(uintptr_t base, unsigned int rwp) { gicd_write_ctlr(base, gicd_read_ctlr(base) | bitmap); - if (rwp != 0U) + if (rwp != 0U) { gicd_wait_for_pending_write(base); + } } /******************************************************************************* @@ -175,17 +271,17 @@ static inline void gicr_write_ctlr(uintptr_t base, uint32_t val) mmio_write_32(base + GICR_CTLR, val); } -static inline unsigned long long gicr_read_typer(uintptr_t base) +static inline uint64_t gicr_read_typer(uintptr_t base) { return mmio_read_64(base + GICR_TYPER); } -static inline unsigned int gicr_read_waker(uintptr_t base) +static inline uint32_t gicr_read_waker(uintptr_t base) { return mmio_read_32(base + GICR_WAKER); } -static inline void gicr_write_waker(uintptr_t base, unsigned int val) +static inline void gicr_write_waker(uintptr_t base, uint32_t val) { mmio_write_32(base + GICR_WAKER, val); } @@ -199,14 +295,14 @@ static inline void gicr_write_waker(uintptr_t base, unsigned int val) */ static inline void gicr_wait_for_pending_write(uintptr_t gicr_base) { - while ((gicr_read_ctlr(gicr_base) & GICR_CTLR_RWP_BIT) != 0U) - ; + while ((gicr_read_ctlr(gicr_base) & GICR_CTLR_RWP_BIT) != 0U) { + } } static inline void gicr_wait_for_upstream_pending_write(uintptr_t gicr_base) { - while ((gicr_read_ctlr(gicr_base) & GICR_CTLR_UWP_BIT) != 0U) - ; + while ((gicr_read_ctlr(gicr_base) & GICR_CTLR_UWP_BIT) != 0U) { + } } /* Private implementation of Distributor power control hooks */ @@ -214,7 +310,7 @@ void arm_gicv3_distif_pre_save(unsigned int rdist_proc_num); void arm_gicv3_distif_post_restore(unsigned int rdist_proc_num); /******************************************************************************* - * GIC Re-distributor functions for accessing entire registers. + * GIC Redistributor functions for accessing entire registers. * Note: The raw register values correspond to multiple interrupt IDs and * the number of interrupt IDs involved depends on the register accessed. ******************************************************************************/ @@ -341,7 +437,7 @@ static inline uint32_t gits_read_ctlr(uintptr_t base) return mmio_read_32(base + GITS_CTLR); } -static inline void gits_write_ctlr(uintptr_t base, unsigned int val) +static inline void gits_write_ctlr(uintptr_t base, uint32_t val) { mmio_write_32(base + GITS_CTLR, val); } @@ -366,13 +462,15 @@ static inline void gits_write_cwriter(uintptr_t base, uint64_t val) mmio_write_64(base + GITS_CWRITER, val); } -static inline uint64_t gits_read_baser(uintptr_t base, unsigned int its_table_id) +static inline uint64_t gits_read_baser(uintptr_t base, + unsigned int its_table_id) { assert(its_table_id < 8U); return mmio_read_64(base + GITS_BASER + (8U * its_table_id)); } -static inline void gits_write_baser(uintptr_t base, unsigned int its_table_id, uint64_t val) +static inline void gits_write_baser(uintptr_t base, unsigned int its_table_id, + uint64_t val) { assert(its_table_id < 8U); mmio_write_64(base + GITS_BASER + (8U * its_table_id), val); @@ -384,9 +482,8 @@ static inline void gits_write_baser(uintptr_t base, unsigned int its_table_id, u static inline void gits_wait_for_quiescent_bit(uintptr_t gits_base) { assert((gits_read_ctlr(gits_base) & GITS_CTLR_ENABLED_BIT) == 0U); - while ((gits_read_ctlr(gits_base) & GITS_CTLR_QUIESCENT_BIT) == 0U) - ; + while ((gits_read_ctlr(gits_base) & GITS_CTLR_QUIESCENT_BIT) == 0U) { + } } - #endif /* GICV3_PRIVATE_H */ diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h index c4f42d04d..e6339bcfe 100644 --- a/include/drivers/arm/gicv3.h +++ b/include/drivers/arm/gicv3.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -32,7 +32,7 @@ #define GICD_SETSPI_NSR U(0x40) #define GICD_CLRSPI_NSR U(0x48) #define GICD_SETSPI_SR U(0x50) -#define GICD_CLRSPI_SR U(0x50) +#define GICD_CLRSPI_SR U(0x58) #define GICD_IGRPMODR U(0xd00) /* * GICD_IROUTER register is at 0x6000 + 8n, where n is the interrupt id and @@ -79,7 +79,7 @@ #define NUM_OF_DIST_REGS 30 /******************************************************************************* - * GICv3 Re-distributor interface registers & constants + * GICv3 Redistributor interface registers & constants ******************************************************************************/ #define GICR_PCPUBASE_SHIFT 0x11 #define GICR_SGIBASE_OFFSET U(65536) /* 64 KB */ diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 05c11ce52..c32b3028e 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -56,6 +56,8 @@ $(eval $(call add_define,FVP_INTERCONNECT_DRIVER)) FVP_GICV3_SOURCES := drivers/arm/gic/common/gic_common.c \ drivers/arm/gic/v3/gicv3_main.c \ drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gicdv3_helpers.c \ + drivers/arm/gic/v3/gicrv3_helpers.c \ plat/common/plat_gicv3.c \ plat/arm/common/arm_gicv3.c diff --git a/plat/arm/board/n1sdp/platform.mk b/plat/arm/board/n1sdp/platform.mk index 8816670dc..da780a3eb 100644 --- a/plat/arm/board/n1sdp/platform.mk +++ b/plat/arm/board/n1sdp/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -18,6 +18,8 @@ N1SDP_CPU_SOURCES := lib/cpus/aarch64/neoverse_n1.S N1SDP_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ drivers/arm/gic/v3/gicv3_main.c \ drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gicdv3_helpers.c \ + drivers/arm/gic/v3/gicrv3_helpers.c \ drivers/arm/gic/v3/gic600_multichip.c \ plat/common/plat_gicv3.c \ plat/arm/common/arm_gicv3.c \ diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/css/sgi/sgi-common.mk index 40a7fd8a3..ea5a56356 100644 --- a/plat/arm/css/sgi/sgi-common.mk +++ b/plat/arm/css/sgi/sgi-common.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -25,6 +25,8 @@ PLAT_INCLUDES += -I${CSS_ENT_BASE}/include ENT_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ drivers/arm/gic/v3/gicv3_main.c \ drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gicdv3_helpers.c \ + drivers/arm/gic/v3/gicrv3_helpers.c \ plat/common/plat_gicv3.c \ plat/arm/common/arm_gicv3.c \ drivers/arm/gic/v3/gic600.c diff --git a/plat/arm/css/sgm/sgm-common.mk b/plat/arm/css/sgm/sgm-common.mk index ac34450a7..49fc7176a 100644 --- a/plat/arm/css/sgm/sgm-common.mk +++ b/plat/arm/css/sgm/sgm-common.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -25,6 +25,8 @@ INTERCONNECT_SOURCES := ${CSS_SGM_BASE}/sgm_interconnect.c SGM_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ drivers/arm/gic/v3/gicv3_main.c \ drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gicdv3_helpers.c \ + drivers/arm/gic/v3/gicrv3_helpers.c \ plat/common/plat_gicv3.c \ plat/arm/common/arm_gicv3.c \ drivers/arm/gic/v3/gic600.c \ diff --git a/plat/imx/imx8m/imx8mm/platform.mk b/plat/imx/imx8m/imx8mm/platform.mk index c0cb6c2a5..1ff576dbe 100644 --- a/plat/imx/imx8m/imx8mm/platform.mk +++ b/plat/imx/imx8m/imx8mm/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -9,6 +9,8 @@ PLAT_INCLUDES := -Iplat/imx/common/include \ -Iplat/imx/imx8m/imx8mm/include IMX_GIC_SOURCES := drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gicdv3_helpers.c \ + drivers/arm/gic/v3/gicrv3_helpers.c \ drivers/arm/gic/v3/arm_gicv3_common.c \ drivers/arm/gic/v3/gic500.c \ drivers/arm/gic/v3/gicv3_main.c \ diff --git a/plat/imx/imx8m/imx8mq/platform.mk b/plat/imx/imx8m/imx8mq/platform.mk index 80ebe4062..e419f05c9 100644 --- a/plat/imx/imx8m/imx8mq/platform.mk +++ b/plat/imx/imx8m/imx8mq/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -9,6 +9,8 @@ PLAT_INCLUDES := -Iplat/imx/common/include \ -Iplat/imx/imx8m/imx8mq/include IMX_GIC_SOURCES := drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gicdv3_helpers.c \ + drivers/arm/gic/v3/gicrv3_helpers.c \ drivers/arm/gic/v3/arm_gicv3_common.c \ drivers/arm/gic/v3/gic500.c \ drivers/arm/gic/v3/gicv3_main.c \ diff --git a/plat/imx/imx8qm/platform.mk b/plat/imx/imx8qm/platform.mk index 3a772e51a..5ba9c3f7b 100644 --- a/plat/imx/imx8qm/platform.mk +++ b/plat/imx/imx8qm/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -8,6 +8,8 @@ PLAT_INCLUDES := -Iplat/imx/imx8qm/include \ -Iplat/imx/common/include \ IMX_GIC_SOURCES := drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gicdv3_helpers.c \ + drivers/arm/gic/v3/gicrv3_helpers.c \ drivers/arm/gic/v3/arm_gicv3_common.c \ drivers/arm/gic/v3/gic500.c \ drivers/arm/gic/v3/gicv3_main.c \ diff --git a/plat/imx/imx8qx/platform.mk b/plat/imx/imx8qx/platform.mk index d5629d124..5e8ba063c 100644 --- a/plat/imx/imx8qx/platform.mk +++ b/plat/imx/imx8qx/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -8,6 +8,8 @@ PLAT_INCLUDES := -Iplat/imx/imx8qx/include \ -Iplat/imx/common/include \ IMX_GIC_SOURCES := drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gicdv3_helpers.c \ + drivers/arm/gic/v3/gicrv3_helpers.c \ drivers/arm/gic/v3/arm_gicv3_common.c \ drivers/arm/gic/v3/gic500.c \ drivers/arm/gic/v3/gicv3_main.c \ diff --git a/plat/marvell/a3700/common/a3700_common.mk b/plat/marvell/a3700/common/a3700_common.mk index 1e2756734..fd2b7ed79 100644 --- a/plat/marvell/a3700/common/a3700_common.mk +++ b/plat/marvell/a3700/common/a3700_common.mk @@ -81,6 +81,8 @@ $(eval $(call add_define,USE_CCI)) MARVELL_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ drivers/arm/gic/v3/gicv3_main.c \ drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gicdv3_helpers.c \ + drivers/arm/gic/v3/gicrv3_helpers.c \ drivers/arm/gic/v3/arm_gicv3_common.c \ plat/common/plat_gicv3.c \ drivers/arm/gic/v3/gic500.c diff --git a/plat/mediatek/mt8183/platform.mk b/plat/mediatek/mt8183/platform.mk index 597e18b90..59ffe5dc0 100644 --- a/plat/mediatek/mt8183/platform.mk +++ b/plat/mediatek/mt8183/platform.mk @@ -31,6 +31,8 @@ BL31_SOURCES += common/desc_image_load.c \ drivers/arm/gic/common/gic_common.c \ drivers/arm/gic/v3/arm_gicv3_common.c \ drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gicdv3_helpers.c \ + drivers/arm/gic/v3/gicrv3_helpers.c \ drivers/arm/gic/v3/gic500.c \ drivers/arm/gic/v3/gicv3_main.c \ drivers/delay_timer/delay_timer.c \ diff --git a/plat/qemu/qemu/platform.mk b/plat/qemu/qemu/platform.mk index 928d69a71..6aa198c33 100644 --- a/plat/qemu/qemu/platform.mk +++ b/plat/qemu/qemu/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -140,6 +140,8 @@ QEMU_GICV2_SOURCES := drivers/arm/gic/v2/gicv2_helpers.c \ ${PLAT_QEMU_COMMON_PATH}/qemu_gicv2.c QEMU_GICV3_SOURCES := drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gicdv3_helpers.c \ + drivers/arm/gic/v3/gicrv3_helpers.c \ drivers/arm/gic/v3/gicv3_main.c \ drivers/arm/gic/common/gic_common.c \ plat/common/plat_gicv3.c \ diff --git a/plat/qemu/qemu_sbsa/platform.mk b/plat/qemu/qemu_sbsa/platform.mk index 51832d0ff..6ad3d8bbf 100644 --- a/plat/qemu/qemu_sbsa/platform.mk +++ b/plat/qemu/qemu_sbsa/platform.mk @@ -63,6 +63,8 @@ BL2_SOURCES += ${PLAT_QEMU_COMMON_PATH}/qemu_bl2_mem_params_desc.c \ endif QEMU_GIC_SOURCES := drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gicdv3_helpers.c \ + drivers/arm/gic/v3/gicrv3_helpers.c \ drivers/arm/gic/v3/gicv3_main.c \ drivers/arm/gic/common/gic_common.c \ plat/common/plat_gicv3.c \ diff --git a/plat/rockchip/rk3399/platform.mk b/plat/rockchip/rk3399/platform.mk index 5a23d3c71..0dc1840c9 100644 --- a/plat/rockchip/rk3399/platform.mk +++ b/plat/rockchip/rk3399/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -29,6 +29,8 @@ RK_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ drivers/arm/gic/v3/gic500.c \ drivers/arm/gic/v3/gicv3_main.c \ drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gicdv3_helpers.c \ + drivers/arm/gic/v3/gicrv3_helpers.c \ plat/common/plat_gicv3.c \ ${RK_PLAT}/common/rockchip_gicv3.c diff --git a/plat/socionext/synquacer/platform.mk b/plat/socionext/synquacer/platform.mk index ab1f69e68..0d9071b32 100644 --- a/plat/socionext/synquacer/platform.mk +++ b/plat/socionext/synquacer/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -33,6 +33,8 @@ PLAT_BL_COMMON_SOURCES += $(PLAT_PATH)/sq_helpers.S \ BL31_SOURCES += drivers/arm/ccn/ccn.c \ drivers/arm/gic/common/gic_common.c \ drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gicdv3_helpers.c \ + drivers/arm/gic/v3/gicrv3_helpers.c \ drivers/arm/gic/v3/gicv3_main.c \ lib/cpus/aarch64/cortex_a53.S \ plat/common/plat_gicv3.c \ diff --git a/plat/socionext/uniphier/platform.mk b/plat/socionext/uniphier/platform.mk index 8e96b68bb..a014f528f 100644 --- a/plat/socionext/uniphier/platform.mk +++ b/plat/socionext/uniphier/platform.mk @@ -58,6 +58,8 @@ BL2_SOURCES += common/desc_image_load.c \ BL31_SOURCES += drivers/arm/cci/cci.c \ drivers/arm/gic/common/gic_common.c \ drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gicdv3_helpers.c \ + drivers/arm/gic/v3/gicrv3_helpers.c \ drivers/arm/gic/v3/gicv3_main.c \ lib/cpus/aarch64/cortex_a53.S \ lib/cpus/aarch64/cortex_a72.S \ diff --git a/plat/ti/k3/common/plat_common.mk b/plat/ti/k3/common/plat_common.mk index 7956497ae..587b44bc3 100644 --- a/plat/ti/k3/common/plat_common.mk +++ b/plat/ti/k3/common/plat_common.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -57,6 +57,8 @@ K3_GIC_SOURCES += \ drivers/arm/gic/common/gic_common.c \ drivers/arm/gic/v3/gicv3_main.c \ drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gicdv3_helpers.c \ + drivers/arm/gic/v3/gicrv3_helpers.c \ plat/common/plat_gicv3.c \ ${PLAT_PATH}/common/k3_gicv3.c \ diff --git a/plat/xilinx/versal/platform.mk b/plat/xilinx/versal/platform.mk index 1e231cce8..5d7fd697f 100644 --- a/plat/xilinx/versal/platform.mk +++ b/plat/xilinx/versal/platform.mk @@ -52,6 +52,8 @@ PLAT_BL_COMMON_SOURCES := lib/xlat_tables/xlat_tables_common.c \ drivers/arm/gic/v3/gic500.c \ drivers/arm/gic/v3/gicv3_main.c \ drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gicdv3_helpers.c \ + drivers/arm/gic/v3/gicrv3_helpers.c \ drivers/arm/pl011/aarch64/pl011_console.S \ plat/common/aarch64/crash_console_helpers.S \ plat/arm/common/arm_cci.c \ -- cgit v1.2.3 From 363830df1c28e240ed1132c6ce41f4a4b3efb8d8 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 6 Mar 2020 19:21:26 +0900 Subject: xlat_tables_v2: merge REGISTER_XLAT_CONTEXT_{FULL_SPEC,RO_BASE_TABLE} xlat_tables_v2_helpers.h defines two quite similar macros, REGISTER_XLAT_CONTEXT_FULL_SPEC and REGISTER_XLAT_CONTEXT_RO_BASE_TABLE. Only the difference is the section of _ctx_name##_base_xlat_table. Parameterize it and unify these two macros. The base xlat table goes into the .bss section by default. If PLAT_RO_XLAT_TABLES is defined, it goes into the .rodata section. Change-Id: I8b02f4da98f0c272e348a200cebd89f479099c55 Signed-off-by: Masahiro Yamada --- include/lib/xlat_tables/xlat_tables_v2.h | 14 ++++++-- include/lib/xlat_tables/xlat_tables_v2_helpers.h | 46 +++--------------------- lib/xlat_tables_v2/xlat_tables_context.c | 11 +++--- 3 files changed, 21 insertions(+), 50 deletions(-) diff --git a/include/lib/xlat_tables/xlat_tables_v2.h b/include/lib/xlat_tables/xlat_tables_v2.h index a80fab073..ab311f4cb 100644 --- a/include/lib/xlat_tables/xlat_tables_v2.h +++ b/include/lib/xlat_tables/xlat_tables_v2.h @@ -164,14 +164,20 @@ typedef struct xlat_ctx xlat_ctx_t; * Would typically be PLAT_VIRT_ADDR_SPACE_SIZE * (resp. PLAT_PHY_ADDR_SPACE_SIZE) for the translation context describing the * BL image currently executing. + + * _base_table_section: + * Specify the name of the section where the base translation tables have to + * be placed by the linker. */ #define REGISTER_XLAT_CONTEXT(_ctx_name, _mmap_count, _xlat_tables_count, \ - _virt_addr_space_size, _phy_addr_space_size) \ + _virt_addr_space_size, _phy_addr_space_size, \ + _base_table_section) \ REGISTER_XLAT_CONTEXT_FULL_SPEC(_ctx_name, (_mmap_count), \ (_xlat_tables_count), \ (_virt_addr_space_size), \ (_phy_addr_space_size), \ - EL_REGIME_INVALID, "xlat_table") + EL_REGIME_INVALID, \ + "xlat_table", (_base_table_section)) /* * Same as REGISTER_XLAT_CONTEXT plus the additional parameters: @@ -191,7 +197,9 @@ typedef struct xlat_ctx xlat_ctx_t; (_xlat_tables_count), \ (_virt_addr_space_size), \ (_phy_addr_space_size), \ - (_xlat_regime), (_section_name)) + (_xlat_regime), \ + (_section_name), ".bss" \ +) /****************************************************************************** * Generic translation table APIs. diff --git a/include/lib/xlat_tables/xlat_tables_v2_helpers.h b/include/lib/xlat_tables/xlat_tables_v2_helpers.h index c88fa4dd5..4a72391a1 100644 --- a/include/lib/xlat_tables/xlat_tables_v2_helpers.h +++ b/include/lib/xlat_tables/xlat_tables_v2_helpers.h @@ -135,7 +135,8 @@ struct xlat_ctx { #define REGISTER_XLAT_CONTEXT_FULL_SPEC(_ctx_name, _mmap_count, \ _xlat_tables_count, _virt_addr_space_size, \ - _phy_addr_space_size, _xlat_regime, _section_name)\ + _phy_addr_space_size, _xlat_regime, \ + _table_section, _base_table_section) \ CASSERT(CHECK_PHY_ADDR_SPACE_SIZE(_phy_addr_space_size), \ assert_invalid_physical_addr_space_sizefor_##_ctx_name);\ \ @@ -143,52 +144,13 @@ struct xlat_ctx { \ static uint64_t _ctx_name##_xlat_tables[_xlat_tables_count] \ [XLAT_TABLE_ENTRIES] \ - __aligned(XLAT_TABLE_SIZE) __section(_section_name); \ - \ - static uint64_t _ctx_name##_base_xlat_table \ - [GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size)] \ - __aligned(GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size)\ - * sizeof(uint64_t)); \ - \ - XLAT_ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count) \ - \ - static xlat_ctx_t _ctx_name##_xlat_ctx = { \ - .pa_max_address = (_phy_addr_space_size) - 1ULL, \ - .va_max_address = (_virt_addr_space_size) - 1UL, \ - .mmap = _ctx_name##_mmap, \ - .mmap_num = (_mmap_count), \ - .tables = _ctx_name##_xlat_tables, \ - .tables_num = _xlat_tables_count, \ - XLAT_CTX_INIT_TABLE_ATTR() \ - XLAT_REGISTER_DYNMAP_STRUCT(_ctx_name) \ - .next_table = 0, \ - .base_table = _ctx_name##_base_xlat_table, \ - .base_table_entries = \ - GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size),\ - .max_pa = 0U, \ - .max_va = 0U, \ - .base_level = GET_XLAT_TABLE_LEVEL_BASE(_virt_addr_space_size),\ - .initialized = false, \ - .xlat_regime = (_xlat_regime) \ - } - -#define REGISTER_XLAT_CONTEXT_RO_BASE_TABLE(_ctx_name, _mmap_count, \ - _xlat_tables_count, _virt_addr_space_size, \ - _phy_addr_space_size, _xlat_regime, _section_name)\ - CASSERT(CHECK_PHY_ADDR_SPACE_SIZE(_phy_addr_space_size), \ - assert_invalid_physical_addr_space_sizefor_##_ctx_name);\ - \ - static mmap_region_t _ctx_name##_mmap[_mmap_count + 1]; \ - \ - static uint64_t _ctx_name##_xlat_tables[_xlat_tables_count] \ - [XLAT_TABLE_ENTRIES] \ - __aligned(XLAT_TABLE_SIZE) __section(_section_name); \ + __aligned(XLAT_TABLE_SIZE) __section(_table_section); \ \ static uint64_t _ctx_name##_base_xlat_table \ [GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size)] \ __aligned(GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size)\ * sizeof(uint64_t)) \ - __section(".rodata"); \ + __section(_base_table_section); \ \ XLAT_ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count) \ \ diff --git a/lib/xlat_tables_v2/xlat_tables_context.c b/lib/xlat_tables_v2/xlat_tables_context.c index adca57875..a1c974ec0 100644 --- a/lib/xlat_tables_v2/xlat_tables_context.c +++ b/lib/xlat_tables_v2/xlat_tables_context.c @@ -26,14 +26,15 @@ uint64_t mmu_cfg_params[MMU_CFG_PARAM_MAX]; * currently executing. */ #if PLAT_RO_XLAT_TABLES -REGISTER_XLAT_CONTEXT_RO_BASE_TABLE(tf, MAX_MMAP_REGIONS, MAX_XLAT_TABLES, - PLAT_VIRT_ADDR_SPACE_SIZE, PLAT_PHY_ADDR_SPACE_SIZE, - EL_REGIME_INVALID, "xlat_table"); +#define BASE_XLAT_TABLE_SECTION ".rodata" #else -REGISTER_XLAT_CONTEXT(tf, MAX_MMAP_REGIONS, MAX_XLAT_TABLES, - PLAT_VIRT_ADDR_SPACE_SIZE, PLAT_PHY_ADDR_SPACE_SIZE); +#define BASE_XLAT_TABLE_SECTION ".bss" #endif +REGISTER_XLAT_CONTEXT(tf, MAX_MMAP_REGIONS, MAX_XLAT_TABLES, + PLAT_VIRT_ADDR_SPACE_SIZE, PLAT_PHY_ADDR_SPACE_SIZE, + BASE_XLAT_TABLE_SECTION); + void mmap_add_region(unsigned long long base_pa, uintptr_t base_va, size_t size, unsigned int attr) { -- cgit v1.2.3 From e28224583e86bebf39375b327995c9333f6b7966 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 9 Mar 2020 17:39:27 +0900 Subject: xlat_tables_v2: use ARRAY_SIZE in REGISTER_XLAT_CONTEXT_FULL_SPEC With this, it is clearer that .base_table_entries and .tables_num are the array size of .base_table and .tables, respectively. Change-Id: I634e65aba835ab9908cc3919355df6bc6e18d42a Signed-off-by: Masahiro Yamada --- include/lib/xlat_tables/xlat_tables_v2_helpers.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/lib/xlat_tables/xlat_tables_v2_helpers.h b/include/lib/xlat_tables/xlat_tables_v2_helpers.h index 4a72391a1..62f853d18 100644 --- a/include/lib/xlat_tables/xlat_tables_v2_helpers.h +++ b/include/lib/xlat_tables/xlat_tables_v2_helpers.h @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -160,13 +161,13 @@ struct xlat_ctx { .mmap = _ctx_name##_mmap, \ .mmap_num = (_mmap_count), \ .tables = _ctx_name##_xlat_tables, \ - .tables_num = _xlat_tables_count, \ + .tables_num = ARRAY_SIZE(_ctx_name##_xlat_tables), \ XLAT_CTX_INIT_TABLE_ATTR() \ XLAT_REGISTER_DYNMAP_STRUCT(_ctx_name) \ .next_table = 0, \ .base_table = _ctx_name##_base_xlat_table, \ .base_table_entries = \ - GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size),\ + ARRAY_SIZE(_ctx_name##_base_xlat_table), \ .max_pa = 0U, \ .max_va = 0U, \ .base_level = GET_XLAT_TABLE_LEVEL_BASE(_virt_addr_space_size),\ -- cgit v1.2.3 From 665e71b8ea28162ec7737c1411bca3ea89e5957e Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 9 Mar 2020 17:39:48 +0900 Subject: Factor xlat_table sections in linker scripts out into a header file TF-A has so many linker scripts, at least one linker script for each BL image, and some platforms have their own ones. They duplicate quite similar code (and comments). When we add some changes to linker scripts, we end up with touching so many files. This is not nice in the maintainability perspective. When you look at Linux kernel, the common code is macrofied in include/asm-generic/vmlinux.lds.h, which is included from each arch linker script, arch/*/kernel/vmlinux.lds.S TF-A can follow this approach. Let's factor out the common code into include/common/bl_common.ld.h As a start point, this commit factors out the xlat_table section. Change-Id: Ifa369e9b48e8e12702535d721cc2a16d12397895 Signed-off-by: Masahiro Yamada --- bl1/bl1.ld.S | 13 +++---------- bl2/bl2.ld.S | 11 ++--------- bl2/bl2_el3.ld.S | 13 +++---------- bl2u/bl2u.ld.S | 13 +++---------- bl31/bl31.ld.S | 11 ++--------- bl32/sp_min/sp_min.ld.S | 13 +++---------- bl32/tsp/tsp.ld.S | 11 ++--------- include/common/bl_common.ld.h | 21 +++++++++++++++++++++ plat/mediatek/mt6795/bl31.ld.S | 13 +++---------- 9 files changed, 42 insertions(+), 77 deletions(-) create mode 100644 include/common/bl_common.ld.h diff --git a/bl1/bl1.ld.S b/bl1/bl1.ld.S index b20859b5b..e65ab9004 100644 --- a/bl1/bl1.ld.S +++ b/bl1/bl1.ld.S @@ -1,11 +1,12 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include +#include #include OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT) @@ -148,15 +149,7 @@ SECTIONS __BSS_END__ = .; } >RAM - /* - * The xlat_table section is for full, aligned page tables (4K). - * Removing them from .bss avoids forcing 4K alignment on - * the .bss section. The tables are initialized to zero by the translation - * tables library. - */ - xlat_table (NOLOAD) : { - *(xlat_table) - } >RAM + XLAT_TABLE_SECTION >RAM #if USE_COHERENT_MEM /* diff --git a/bl2/bl2.ld.S b/bl2/bl2.ld.S index c1338e22d..d08b046e9 100644 --- a/bl2/bl2.ld.S +++ b/bl2/bl2.ld.S @@ -6,6 +6,7 @@ #include +#include #include OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT) @@ -125,15 +126,7 @@ SECTIONS __BSS_END__ = .; } >RAM - /* - * The xlat_table section is for full, aligned page tables (4K). - * Removing them from .bss avoids forcing 4K alignment on - * the .bss section. The tables are initialized to zero by the translation - * tables library. - */ - xlat_table (NOLOAD) : { - *(xlat_table) - } >RAM + XLAT_TABLE_SECTION >RAM #if USE_COHERENT_MEM /* diff --git a/bl2/bl2_el3.ld.S b/bl2/bl2_el3.ld.S index b6570ee3e..a72818c99 100644 --- a/bl2/bl2_el3.ld.S +++ b/bl2/bl2_el3.ld.S @@ -1,11 +1,12 @@ /* - * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include +#include #include OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT) @@ -188,15 +189,7 @@ SECTIONS __BSS_END__ = .; } >RAM - /* - * The xlat_table section is for full, aligned page tables (4K). - * Removing them from .bss avoids forcing 4K alignment on - * the .bss section. The tables are initialized to zero by the translation - * tables library. - */ - xlat_table (NOLOAD) : { - *(xlat_table) - } >RAM + XLAT_TABLE_SECTION >RAM #if USE_COHERENT_MEM /* diff --git a/bl2u/bl2u.ld.S b/bl2u/bl2u.ld.S index 8d257cee9..96545a3ab 100644 --- a/bl2u/bl2u.ld.S +++ b/bl2u/bl2u.ld.S @@ -1,11 +1,12 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include +#include #include OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT) @@ -102,15 +103,7 @@ SECTIONS __BSS_END__ = .; } >RAM - /* - * The xlat_table section is for full, aligned page tables (4K). - * Removing them from .bss avoids forcing 4K alignment on - * the .bss section. The tables are initialized to zero by the translation - * tables library. - */ - xlat_table (NOLOAD) : { - *(xlat_table) - } >RAM + XLAT_TABLE_SECTION >RAM #if USE_COHERENT_MEM /* diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S index 4a1c5f310..e0138acbb 100644 --- a/bl31/bl31.ld.S +++ b/bl31/bl31.ld.S @@ -6,6 +6,7 @@ #include +#include #include OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT) @@ -287,15 +288,7 @@ SECTIONS __BSS_END__ = .; } >NOBITS - /* - * The xlat_table section is for full, aligned page tables (4K). - * Removing them from .bss avoids forcing 4K alignment on - * the .bss section. The tables are initialized to zero by the translation - * tables library. - */ - xlat_table (NOLOAD) : { - *(xlat_table) - } >NOBITS + XLAT_TABLE_SECTION >NOBITS #if USE_COHERENT_MEM /* diff --git a/bl32/sp_min/sp_min.ld.S b/bl32/sp_min/sp_min.ld.S index 6997a7fdb..3b1ca1b58 100644 --- a/bl32/sp_min/sp_min.ld.S +++ b/bl32/sp_min/sp_min.ld.S @@ -1,11 +1,12 @@ /* - * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include +#include #include OUTPUT_FORMAT(elf32-littlearm) @@ -196,15 +197,7 @@ SECTIONS __BSS_END__ = .; } >RAM - /* - * The xlat_table section is for full, aligned page tables (4K). - * Removing them from .bss avoids forcing 4K alignment on - * the .bss section. The tables are initialized to zero by the translation - * tables library. - */ - xlat_table (NOLOAD) : { - *(xlat_table) - } >RAM + XLAT_TABLE_SECTION >RAM __BSS_SIZE__ = SIZEOF(.bss); diff --git a/bl32/tsp/tsp.ld.S b/bl32/tsp/tsp.ld.S index 592e24557..da60c63a7 100644 --- a/bl32/tsp/tsp.ld.S +++ b/bl32/tsp/tsp.ld.S @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include #include #include @@ -125,15 +126,7 @@ SECTIONS __BSS_END__ = .; } >RAM - /* - * The xlat_table section is for full, aligned page tables (4K). - * Removing them from .bss avoids forcing 4K alignment on - * the .bss section. The tables are initialized to zero by the translation - * tables library. - */ - xlat_table (NOLOAD) : { - *(xlat_table) - } >RAM + XLAT_TABLE_SECTION >RAM #if USE_COHERENT_MEM /* diff --git a/include/common/bl_common.ld.h b/include/common/bl_common.ld.h new file mode 100644 index 000000000..32c54b4d2 --- /dev/null +++ b/include/common/bl_common.ld.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef BL_COMMON_LD_H +#define BL_COMMON_LD_H + +/* + * The xlat_table section is for full, aligned page tables (4K). + * Removing them from .bss avoids forcing 4K alignment on + * the .bss section. The tables are initialized to zero by the translation + * tables library. + */ +#define XLAT_TABLE_SECTION \ + xlat_table (NOLOAD) : { \ + *(xlat_table) \ + } + +#endif /* BL_COMMON_LD_H */ diff --git a/plat/mediatek/mt6795/bl31.ld.S b/plat/mediatek/mt6795/bl31.ld.S index cf68b711e..0fd38664c 100644 --- a/plat/mediatek/mt6795/bl31.ld.S +++ b/plat/mediatek/mt6795/bl31.ld.S @@ -1,9 +1,10 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ +#include #include #include @@ -131,15 +132,7 @@ SECTIONS ASSERT(. <= BL31_LIMIT, "BL3-1 image has exceeded its limit.") - /* - * The xlat_table section is for full, aligned page tables (4K). - * Removing them from .bss avoids forcing 4K alignment on - * the .bss section. The tables are initialized to zero by the translation - * tables library. - */ - xlat_table (NOLOAD) : { - *(xlat_table) - } >RAM2 + XLAT_TABLE_SECTION >RAM2 #if USE_COHERENT_MEM /* -- cgit v1.2.3 From 7f91e592de2d96aca21c758e898084a4c2e78aaa Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Wed, 11 Mar 2020 09:46:20 +0100 Subject: Changelog: Add dualroot CoT entries Change-Id: I60df17764b5170be6bc932808e8890fe1bb0b50f Signed-off-by: Sandrine Bailleux --- docs/change-log-upcoming.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/change-log-upcoming.rst b/docs/change-log-upcoming.rst index 15f39de63..f86280f76 100644 --- a/docs/change-log-upcoming.rst +++ b/docs/change-log-upcoming.rst @@ -24,6 +24,8 @@ New Features - 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``). - CPU Support - Example: "cortex-a55: Workaround for erratum 1221012" @@ -40,6 +42,7 @@ New Features - Platforms - Example: "arm/common: Introduce wrapper functions to setup secure watchdog" + - plat/arm: Add support for the new `dualroot` chain of trust. - PSCI - Example: "Adding new optional PSCI hook ``pwr_domain_on_finish_late``" @@ -47,6 +50,7 @@ New Features - Security - Example: "UBSAN support and handlers" - Add support for optional firmware encryption feature (experimental). + - Introduce a new `dualroot` chain of trust. - Tools - Example: "fiptool: Add support to build fiptool on Windows." -- cgit v1.2.3 From 303b6d069a09d0c246fc1c4d7bda9a339d166d62 Mon Sep 17 00:00:00 2001 From: Chandni Cherukuri Date: Thu, 5 Mar 2020 11:49:57 +0530 Subject: n1sdp: Enable the NEOVERSE_N1_EXTERNAL_LLC flag Since N1SDP has a system level cache which is an external LLC enable the NEOVERSE_N1_EXTERNAL_LLC flag. Change-Id: Idb34274e61e7fd9db5485862a0caa497f3e290c7 Signed-off-by: Chandni Cherukuri --- plat/arm/board/n1sdp/platform.mk | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plat/arm/board/n1sdp/platform.mk b/plat/arm/board/n1sdp/platform.mk index 8816670dc..f86d4208c 100644 --- a/plat/arm/board/n1sdp/platform.mk +++ b/plat/arm/board/n1sdp/platform.mk @@ -63,6 +63,9 @@ HW_ASSISTED_COHERENCY := 1 # When building for systems with hardware-assisted coherency, there's no need to # use USE_COHERENT_MEM. Require that USE_COHERENT_MEM must be set to 0 too. USE_COHERENT_MEM := 0 + +# Enable the flag since N1SDP has a system level cache +NEOVERSE_N1_EXTERNAL_LLC := 1 include plat/arm/common/arm_common.mk include plat/arm/css/common/css_common.mk include plat/arm/board/common/board_common.mk -- cgit v1.2.3 From 4ea9e587615cf150410901e52aedd07a94c0f224 Mon Sep 17 00:00:00 2001 From: Vijayenthiran Subramaniam Date: Wed, 11 Mar 2020 15:05:49 +0530 Subject: plat/arm/sgi: mark remote chip shared ram as non-cacheable Shared RAM region in the remote chip's memory is used as one of the mailbox region (SCMI payload area) through which the AP core on the local chip and SCP core on the remote chip exchange SCMI protocol message during the initialization. Mark this region as non-cacheable in the MMAP entry to prevent local AP core from reading stale data from the cache. Change-Id: I7e9dc5fbcc3b40e9bcff5499f15abd2aadaed385 Signed-off-by: Vijayenthiran Subramaniam --- 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 9a482d0c0..305fcf66b 100644 --- a/plat/arm/css/sgi/include/sgi_base_platform_def.h +++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h @@ -141,7 +141,7 @@ CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) + \ ARM_SHARED_RAM_BASE, \ ARM_SHARED_RAM_SIZE, \ - MT_MEMORY | MT_RW | MT_SECURE \ + MT_NON_CACHEABLE | MT_RW | MT_SECURE \ ) #define CSS_SGI_MAP_DEVICE_REMOTE_CHIP(n) \ -- cgit v1.2.3 From 6a7b3ce7edcdceb664c56f19280d14b8f442cba4 Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Mon, 9 Mar 2020 16:43:25 +0000 Subject: fconf: Add namespace guidance inside documentation Change-Id: I50707d1836c7f5e4ef162c00256624a1f278baef Signed-off-by: Louis Mayencourt --- docs/components/fconf.rst | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/docs/components/fconf.rst b/docs/components/fconf.rst index cec3cebe4..0e0f0756f 100644 --- a/docs/components/fconf.rst +++ b/docs/components/fconf.rst @@ -83,3 +83,30 @@ This function will call all the ``populate()`` callbacks which have been registered with ``FCONF_REGISTER_POPULATOR()``. .. uml:: ../resources/diagrams/plantuml/fconf_bl2_populate.puml + +Namespace guidance +~~~~~~~~~~~~~~~~~~ + +As mentioned above, properties are logically grouped around namespaces and +sub-namespaces. The following concepts should be considered when adding new +properties/namespaces. +The framework differentiates two types of properties: + - Properties used inside common code. + - Properties used inside platform specific code. + +The first category applies to properties being part of the firmware and shared +across multiple platforms. They should be globally accessible and defined +inside the ``lib/fconf`` directory. The namespace must be chosen to reflect the +feature/data abstracted. +Example: + - |TBBR| related properties: tbbr.cot.bl2_id + - Dynamic configuration information: dyn_cfg.dtb_info.hw_config_id + +The second category should represent the majority of the properties defined +within the framework: Platform specific properties. They must be accessed only +within the platform API and are defined only inside the platform scope. The +namespace must contain the platform name under which the properties defined +belong. +Example: + - Arm io framework: arm.io_policies.bl31_id + -- cgit v1.2.3 From 74601490c551fdf4113b6579b035eb95bb65e5ad Mon Sep 17 00:00:00 2001 From: Balint Dobszay Date: Wed, 13 Nov 2019 12:48:00 +0100 Subject: CMake buildsystem design document Change-Id: I9b69f2731b0d43ead4cacfa9844c6137c57f5aec Signed-off-by: Balint Dobszay --- docs/design_documents/cmake_framework.rst | 165 +++++++++++++++++++++ docs/design_documents/index.rst | 13 ++ docs/index.rst | 3 +- .../diagrams/cmake_framework_structure.png | Bin 0 -> 73277 bytes .../diagrams/cmake_framework_workflow.png | Bin 0 -> 49898 bytes 5 files changed, 180 insertions(+), 1 deletion(-) create mode 100644 docs/design_documents/cmake_framework.rst create mode 100644 docs/design_documents/index.rst create mode 100644 docs/resources/diagrams/cmake_framework_structure.png create mode 100644 docs/resources/diagrams/cmake_framework_workflow.png diff --git a/docs/design_documents/cmake_framework.rst b/docs/design_documents/cmake_framework.rst new file mode 100644 index 000000000..d88942e82 --- /dev/null +++ b/docs/design_documents/cmake_framework.rst @@ -0,0 +1,165 @@ +TF-A CMake buildsystem +====================== + +:Author: Balint Dobszay +:Organization: Arm Limited +:Contact: Balint Dobszay +:Status: Accepted + +.. contents:: Table of Contents + +Abstract +-------- +This document presents a proposal for a new buildsystem for TF-A using CMake, +and as part of this a reusable CMake framework for embedded projects. For a +summary about the proposal, please see the `Phabricator wiki page +`_. As +mentioned there, the proposal consists of two phases. The subject of this +document is the first phase only. + +Introduction +------------ +The current Makefile based buildsystem of TF-A has become complicated and hard +to maintain, there is a need for a new, more flexible solution. The proposal is +to use CMake language for the new buildsystem. The main reasons of this decision +are the following: + +* It is a well-established, mature tool, widely accepted by open-source + projects. +* TF-M is already using CMake, reducing fragmentation for tf.org projects can be + beneficial. +* CMake has various advantages over Make, e.g.: + + * Host and target system agnostic project. + * CMake project is scalable, supports project modularization. + * Supports software integration. + * Out-of-the-box support for integration with several tools (e.g. project + generation for various IDEs, integration with cppcheck, etc). + +Of course there are drawbacks too: + +* Language is problematic (e.g. variable scope). +* Not embedded approach. + +To overcome these and other problems, we need to create workarounds for some +tasks, wrap CMake functions, etc. Since this functionality can be useful in +other embedded projects too, it is beneficial to collect the new code into a +reusable framework and store this in a separate repository. The following +diagram provides an overview of the framework structure: + +|Framework structure| + +Main features +------------- + +Structured configuration description +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +In the current Makefile system the build configuration description, validation, +processing, and the target creation, source file description are mixed and +spread across several files. One of the goals of the framework is to organize +this. + +The framework provides a solution to describe the input build parameters, flags, +macros, etc. in a structured way. It contains two utilities for this purpose: + +* Map: simple key-value pair implementation. +* Group: collection of related maps. + +The related parameters shall be packed into a group (or "setting group"). The +setting groups shall be defined and filled with content in config files. +Currently the config files are created and edited manually, but later a +configuration management tool (e.g. Kconfig) shall be used to generate these +files. Therefore, the framework does not contain parameter validation and +conflict checking, these shall be handled by the configuration tool. + +Target description +^^^^^^^^^^^^^^^^^^ +The framework provides an API called STGT ('simple target') to describe the +targets, i.e. what is the build output, what source files are used, what +libraries are linked, etc. The API wraps the CMake target functions, and also +extends the built-in functionality, it can use the setting groups described in +the previous section. A group can be applied onto a target, i.e. a collection of +macros, flags, etc. can be applied onto the given output executable/library. +This provides a more granular way than the current Makefile system where most of +these are global and applied onto each target. + +Compiler abstraction +^^^^^^^^^^^^^^^^^^^^ +Apart from the built-in CMake usage of the compiler, there are some common tasks +that CMake does not solve (e.g. preprocessing a file). For these tasks the +framework uses wrapper functions instead of direct calls to the compiler. This +way it is not tied to one specific compiler. + +External tools +^^^^^^^^^^^^^^ +In the TF-A buildsystem some external tools are used, e.g. fiptool for image +generation or dtc for device tree compilation. These tools have to be found +and/or built by the framework. For this, the CMake find_package functionality is +used, any other necessary tools can be added later. + +Workflow +-------- +The following diagram demonstrates the development workflow using the framework: + +|Framework workflow| + +The process can be split into two main phases: + +In the provisioning phase, first we have to obtain the necessary resources, i.e. +clone the code repository and other dependencies. Next we have to do the +configuration, preferably using a config tool like KConfig. + +In the development phase first we run CMake, which will generate the buildsystem +using the selected generator backend (currently only the Makefile generator is +supported). After this we run the selected build tool which in turn calls the +compiler, linker, packaging tool, etc. Finally we can run and debug the output +executables. + +Usually during development only the steps in this second phase have to be +repeated, while the provisioning phase needs to be done only once (or rarely). + +Example +------- +This is a short example for the basic framework usage. + +First, we create a setting group called *mem_conf* and fill it with several +parameters. It is worth noting the difference between *CONFIG* and *DEFINE* +types: the former is only a CMake domain option, the latter is only a C language +macro. + +Next, we create a target called *fw1* and add the *mem_conf* setting group to +it. This means that all source and header files used by the target will have all +the parameters declared in the setting group. Then we set the target type to +executable, and add some source files. Since the target has the parameters from +the settings group, we can use it for conditionally adding source files. E.g. +*dram_controller.c* will only be added if MEM_TYPE equals dram. + +.. code-block:: cmake + + group_new(NAME mem_conf) + group_add(NAME mem_conf TYPE DEFINE KEY MEM_SIZE VAL 1024) + group_add(NAME mem_conf TYPE CONFIG DEFINE KEY MEM_TYPE VAL dram) + group_add(NAME mem_conf TYPE CFLAG KEY -Os) + + stgt_create(NAME fw1) + stgt_add_setting(NAME fw1 GROUPS mem_conf) + stgt_set_target(NAME fw1 TYPE exe) + + stgt_add_src(NAME fw1 SRC + ${CMAKE_SOURCE_DIR}/main.c + ) + + stgt_add_src_cond(NAME fw1 KEY MEM_TYPE VAL dram SRC + ${CMAKE_SOURCE_DIR}/dram_controller.c + ) + +.. |Framework structure| image:: + ../resources/diagrams/cmake_framework_structure.png + :width: 75 % + +.. |Framework workflow| image:: + ../resources/diagrams/cmake_framework_workflow.png + +-------------- + +*Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.* diff --git a/docs/design_documents/index.rst b/docs/design_documents/index.rst new file mode 100644 index 000000000..187510a64 --- /dev/null +++ b/docs/design_documents/index.rst @@ -0,0 +1,13 @@ +Design Documents +================ + +.. toctree:: + :maxdepth: 1 + :caption: Contents + :numbered: + + cmake_framework + +-------------- + +*Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.* diff --git a/docs/index.rst b/docs/index.rst index 5088bfd87..7413edd1b 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -14,6 +14,7 @@ Trusted Firmware-A Documentation plat/index perf/index security_advisories/index + design_documents/index change-log change-log-upcoming glossary @@ -82,7 +83,7 @@ have previously been raised against the software. -------------- -*Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.* +*Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.* .. _Armv7-A and Armv8-A: https://developer.arm.com/products/architecture/a-profile .. _Secure Monitor: http://www.arm.com/products/processors/technologies/trustzone/tee-smc.php diff --git a/docs/resources/diagrams/cmake_framework_structure.png b/docs/resources/diagrams/cmake_framework_structure.png new file mode 100644 index 000000000..6006f1c30 Binary files /dev/null and b/docs/resources/diagrams/cmake_framework_structure.png differ diff --git a/docs/resources/diagrams/cmake_framework_workflow.png b/docs/resources/diagrams/cmake_framework_workflow.png new file mode 100644 index 000000000..7311529c4 Binary files /dev/null and b/docs/resources/diagrams/cmake_framework_workflow.png differ -- cgit v1.2.3 From 25d740c45e14d42c9284ab1788a8d7b516608ece Mon Sep 17 00:00:00 2001 From: Madhukar Pappireddy Date: Fri, 6 Dec 2019 15:46:42 -0600 Subject: fconf: enhancements to firmware configuration framework A populate() function essentially captures the value of a property, defined by a platform, into a fconf related c structure. Such a callback is usually platform specific and is associated to a specific configuration source. For example, a populate() function which captures the hardware topology of the platform can only parse HW_CONFIG DTB. Hence each populator function must be registered with a specific 'config_type' identifier. It broadly represents a logical grouping of configuration properties which is usually a device tree source file. Example: > TB_FW: properties related to trusted firmware such as IO policies, base address of other DTBs, mbedtls heap info etc. > HW_CONFIG: properties related to hardware configuration of the SoC such as topology, GIC controller, PSCI hooks, CPU ID etc. This patch modifies FCONF_REGISTER_POPULATOR macro and fconf_populate() to register and invoke the appropriate callbacks selectively based on configuration type. Change-Id: I6f63b1fd7a8729c6c9137d5b63270af1857bb44a Signed-off-by: Madhukar Pappireddy --- include/lib/fconf/fconf.h | 12 ++++++++++-- lib/fconf/fconf.c | 16 +++++++++------- lib/fconf/fconf_dyn_cfg_getter.c | 2 +- lib/fconf/fconf_tbbr_getter.c | 2 +- plat/arm/common/arm_bl2_setup.c | 2 +- plat/arm/common/fconf/arm_fconf_io.c | 2 +- plat/arm/common/fconf/arm_fconf_sp.c | 2 +- 7 files changed, 24 insertions(+), 14 deletions(-) diff --git a/include/lib/fconf/fconf.h b/include/lib/fconf/fconf.h index 0401e5c06..09d2b59aa 100644 --- a/include/lib/fconf/fconf.h +++ b/include/lib/fconf/fconf.h @@ -12,9 +12,16 @@ /* Public API */ #define FCONF_GET_PROPERTY(a, b, c) a##__##b##_getter(c) -#define FCONF_REGISTER_POPULATOR(name, callback) \ +/* + * This macro takes three arguments: + * config: Configuration identifier + * name: property namespace + * callback: populate() function + */ +#define FCONF_REGISTER_POPULATOR(config, name, callback) \ __attribute__((used, section(".fconf_populator"))) \ const struct fconf_populator (name##__populator) = { \ + .config_type = (#config), \ .info = (#name), \ .populate = (callback) \ }; @@ -27,6 +34,7 @@ */ struct fconf_populator { /* Description of the data loaded by the callback */ + const char *config_type; const char *info; /* Callback used by fconf_populate function with a provided config dtb. @@ -45,7 +53,7 @@ void fconf_load_config(void); * * Panic on error. */ -void fconf_populate(uintptr_t config); +void fconf_populate(const char *config_type, uintptr_t config); /* FCONF specific getter */ #define fconf__dtb_getter(prop) fconf_dtb_info.prop diff --git a/lib/fconf/fconf.c b/lib/fconf/fconf.c index a6da56b00..9ce46354d 100644 --- a/lib/fconf/fconf.c +++ b/lib/fconf/fconf.c @@ -53,17 +53,17 @@ void fconf_load_config(void) INFO("FCONF: FW_CONFIG loaded at address = 0x%lx\n", arm_tb_fw_info.image_base); } -void fconf_populate(uintptr_t config) +void fconf_populate(const char *config_type, uintptr_t config) { assert(config != 0UL); /* Check if the pointer to DTB is correct */ if (fdt_check_header((void *)config) != 0) { - ERROR("FCONF: Invalid DTB file passed for FW_CONFIG\n"); + ERROR("FCONF: Invalid DTB file passed for %s\n", config_type); panic(); } - INFO("FCONF: Reading firmware configuration file from: 0x%lx\n", config); + INFO("FCONF: Reading %s firmware configuration file from: 0x%lx\n", config_type, config); /* Go through all registered populate functions */ IMPORT_SYM(struct fconf_populator *, __FCONF_POPULATOR_START__, start); @@ -73,10 +73,12 @@ void fconf_populate(uintptr_t config) for (populator = start; populator != end; populator++) { assert((populator->info != NULL) && (populator->populate != NULL)); - INFO("FCONF: Reading firmware configuration information for: %s\n", populator->info); - if (populator->populate(config) != 0) { - /* TODO: handle property miss */ - panic(); + if (strcmp(populator->config_type, config_type) == 0) { + INFO("FCONF: Reading firmware configuration information for: %s\n", populator->info); + if (populator->populate(config) != 0) { + /* TODO: handle property miss */ + panic(); + } } } diff --git a/lib/fconf/fconf_dyn_cfg_getter.c b/lib/fconf/fconf_dyn_cfg_getter.c index d313a5618..317d3e5d3 100644 --- a/lib/fconf/fconf_dyn_cfg_getter.c +++ b/lib/fconf/fconf_dyn_cfg_getter.c @@ -92,4 +92,4 @@ int fconf_populate_dtb_registry(uintptr_t config) return 0; } -FCONF_REGISTER_POPULATOR(dyn_cfg, fconf_populate_dtb_registry); +FCONF_REGISTER_POPULATOR(TB_FW, dyn_cfg, fconf_populate_dtb_registry); diff --git a/lib/fconf/fconf_tbbr_getter.c b/lib/fconf/fconf_tbbr_getter.c index c6df9c876..a4d61d8cd 100644 --- a/lib/fconf/fconf_tbbr_getter.c +++ b/lib/fconf/fconf_tbbr_getter.c @@ -72,4 +72,4 @@ int fconf_populate_tbbr_dyn_config(uintptr_t config) return 0; } -FCONF_REGISTER_POPULATOR(tbbr, fconf_populate_tbbr_dyn_config); +FCONF_REGISTER_POPULATOR(TB_FW, tbbr, fconf_populate_tbbr_dyn_config); diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c index 136e65a1f..d9fc84e8c 100644 --- a/plat/arm/common/arm_bl2_setup.c +++ b/plat/arm/common/arm_bl2_setup.c @@ -61,7 +61,7 @@ void arm_bl2_early_platform_setup(uintptr_t tb_fw_config, /* Fill the properties struct with the info from the config dtb */ if (tb_fw_config != 0U) { - fconf_populate(tb_fw_config); + fconf_populate("TB_FW", tb_fw_config); } /* Initialise the IO layer and register platform IO devices */ diff --git a/plat/arm/common/fconf/arm_fconf_io.c b/plat/arm/common/fconf/arm_fconf_io.c index cfcddc2b2..017af79a5 100644 --- a/plat/arm/common/fconf/arm_fconf_io.c +++ b/plat/arm/common/fconf/arm_fconf_io.c @@ -138,6 +138,6 @@ int fconf_populate_arm_io_policies(uintptr_t config) return 0; } -FCONF_REGISTER_POPULATOR(arm_io, fconf_populate_arm_io_policies); +FCONF_REGISTER_POPULATOR(TB_FW, arm_io, fconf_populate_arm_io_policies); #endif /* IMAGE_BL2 */ diff --git a/plat/arm/common/fconf/arm_fconf_sp.c b/plat/arm/common/fconf/arm_fconf_sp.c index bb88aff6f..9b6fa9b1f 100644 --- a/plat/arm/common/fconf/arm_fconf_sp.c +++ b/plat/arm/common/fconf/arm_fconf_sp.c @@ -102,6 +102,6 @@ int fconf_populate_arm_sp(uintptr_t config) return 0; } -FCONF_REGISTER_POPULATOR(arm_sp, fconf_populate_arm_sp); +FCONF_REGISTER_POPULATOR(TB_FW, arm_sp, fconf_populate_arm_sp); #endif /* IMAGE_BL2 */ -- cgit v1.2.3 From ccfb5c81349c3a10ac78741e598e80e416a811c3 Mon Sep 17 00:00:00 2001 From: Madhukar Pappireddy Date: Tue, 10 Mar 2020 18:04:59 -0500 Subject: Use Speculation Barrier instruction for v8.5 cores Change-Id: Ie1018bfbae2fe95c699e58648665baa75e862000 Signed-off-by: Madhukar Pappireddy --- include/arch/aarch32/asm_macros.S | 5 +++++ include/arch/aarch64/asm_macros.S | 7 ++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/include/arch/aarch32/asm_macros.S b/include/arch/aarch32/asm_macros.S index ea1636e24..f75da0ce6 100644 --- a/include/arch/aarch32/asm_macros.S +++ b/include/arch/aarch32/asm_macros.S @@ -108,11 +108,16 @@ #else /* * Macro for mitigating against speculative execution beyond ERET. + * If possible use Speculation Barrier instruction defined in ARMv8.5 */ .macro exception_return eret +#if ARM_ARCH_AT_LEAST(8, 5) + sb +#else dsb nsh isb +#endif .endm #endif diff --git a/include/arch/aarch64/asm_macros.S b/include/arch/aarch64/asm_macros.S index a7d5a3dd6..cbb9f0be8 100644 --- a/include/arch/aarch64/asm_macros.S +++ b/include/arch/aarch64/asm_macros.S @@ -220,11 +220,16 @@ /* * Macro for mitigating against speculative execution beyond ERET. + * If possible use Speculation Barrier instruction defined in ARMv8.5 */ .macro exception_return eret - dsb nsh +#if ARM_ARCH_AT_LEAST(8, 5) + sb +#else + dsb nsh isb +#endif .endm #endif /* ASM_MACROS_S */ -- cgit v1.2.3 From 26d1e0c330981505315408c2537b87854d15d720 Mon Sep 17 00:00:00 2001 From: Madhukar Pappireddy Date: Mon, 27 Jan 2020 13:37:51 -0600 Subject: fconf: necessary modifications to support fconf in BL31 & SP_MIN Necessary infrastructure added to integrate fconf framework in BL31 & SP_MIN. Created few populator() functions which parse HW_CONFIG device tree and registered them with fconf framework. Many of the changes are only applicable for fvp platform. This patch: 1. Adds necessary symbols and sections in BL31, SP_MIN linker script 2. Adds necessary memory map entry for translation in BL31, SP_MIN 3. Creates an abstraction layer for hardware configuration based on fconf framework 4. Adds necessary changes to build flow (makefiles) 5. Minimal callback to read hw_config dtb for capturing properties related to GIC(interrupt-controller node) 6. updates the fconf documentation Change-Id: Ib6292071f674ef093962b9e8ba0d322b7bf919af Signed-off-by: Madhukar Pappireddy --- Makefile | 5 ++- bl31/bl31.ld.S | 10 +++++ bl32/sp_min/sp_min.ld.S | 12 ++++- docs/components/fconf.rst | 40 ++++++++++++----- include/plat/arm/common/plat_arm.h | 1 + plat/arm/board/fvp/fconf/fconf_hw_config_getter.c | 52 ++++++++++++++++++++++ plat/arm/board/fvp/fvp_bl31_setup.c | 26 ++++++++++- plat/arm/board/fvp/fvp_common.c | 6 ++- .../arm/board/fvp/include/fconf_hw_config_getter.h | 24 ++++++++++ plat/arm/board/fvp/include/platform_def.h | 6 +-- plat/arm/board/fvp/platform.mk | 6 +++ plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c | 29 +++++++++++- plat/arm/board/fvp/sp_min/sp_min-fvp.mk | 8 +++- plat/arm/common/sp_min/arm_sp_min_setup.c | 7 ++- 14 files changed, 210 insertions(+), 22 deletions(-) create mode 100644 plat/arm/board/fvp/fconf/fconf_hw_config_getter.c create mode 100644 plat/arm/board/fvp/include/fconf_hw_config_getter.h diff --git a/Makefile b/Makefile index 3d5b39502..47a544dcf 100644 --- a/Makefile +++ b/Makefile @@ -1000,6 +1000,8 @@ endif ifeq (${NEED_BL31},yes) BL31_SOURCES += ${SPD_SOURCES} +# Sort BL31 source files to remove duplicates +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)))) @@ -1013,7 +1015,8 @@ endif # build system will call TOOL_ADD_IMG to print a warning message and abort the # process. Note that the dependency on BL32 applies to the FIP only. ifeq (${NEED_BL32},yes) - +# Sort BL32 source files to remove duplicates +BL32_SOURCES := $(sort ${BL32_SOURCES}) BUILD_BL32 := $(if $(BL32),,$(if $(BL32_SOURCES),1)) ifneq (${DECRYPTION_SUPPORT},none) diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S index 4a1c5f310..fce9eb266 100644 --- a/bl31/bl31.ld.S +++ b/bl31/bl31.ld.S @@ -54,6 +54,11 @@ SECTIONS KEEP(*(rt_svc_descs)) __RT_SVC_DESCS_END__ = .; + . = ALIGN(8); + __FCONF_POPULATOR_START__ = .; + KEEP(*(.fconf_populator)) + __FCONF_POPULATOR_END__ = .; + #if ENABLE_PMF /* Ensure 8-byte alignment for descriptors and ensure inclusion */ . = ALIGN(8); @@ -101,6 +106,11 @@ SECTIONS KEEP(*(rt_svc_descs)) __RT_SVC_DESCS_END__ = .; + . = ALIGN(8); + __FCONF_POPULATOR_START__ = .; + KEEP(*(.fconf_populator)) + __FCONF_POPULATOR_END__ = .; + #if ENABLE_PMF /* Ensure 8-byte alignment for descriptors and ensure inclusion */ . = ALIGN(8); diff --git a/bl32/sp_min/sp_min.ld.S b/bl32/sp_min/sp_min.ld.S index 6997a7fdb..3231f9aec 100644 --- a/bl32/sp_min/sp_min.ld.S +++ b/bl32/sp_min/sp_min.ld.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -55,6 +55,11 @@ SECTIONS KEEP(*(rt_svc_descs)) __RT_SVC_DESCS_END__ = .; + . = ALIGN(8); + __FCONF_POPULATOR_START__ = .; + KEEP(*(.fconf_populator)) + __FCONF_POPULATOR_END__ = .; + #if ENABLE_PMF /* Ensure 4-byte alignment for descriptors and ensure inclusion */ . = ALIGN(4); @@ -92,6 +97,11 @@ SECTIONS KEEP(*(rt_svc_descs)) __RT_SVC_DESCS_END__ = .; + . = ALIGN(8); + __FCONF_POPULATOR_START__ = .; + KEEP(*(.fconf_populator)) + __FCONF_POPULATOR_END__ = .; + /* * Ensure 4-byte alignment for cpu_ops so that its fields are also * aligned. Also ensure cpu_ops inclusion. diff --git a/docs/components/fconf.rst b/docs/components/fconf.rst index cec3cebe4..4ea1f5ba0 100644 --- a/docs/components/fconf.rst +++ b/docs/components/fconf.rst @@ -28,29 +28,45 @@ Examples namespace can be: - (|TBBR|) Chain of Trust data: tbbr.cot.trusted_boot_fw_cert - (|TBBR|) dynamic configuration info: tbbr.dyn_config.disable_auth - Arm io policies: arm.io_policies.bl2_image +- GICv3 properties: hw_config.gicv3_config.gicr_base Properties can be accessed with the ``FCONF_GET_PROPERTY(a,b,property)`` macro. Defining properties ~~~~~~~~~~~~~~~~~~~ -Properties composing the |FCONF| have to be stored in C structures. If another -backing store is wanted to be used, the platform has to provide a ``populate()`` -function to fill the corresponding C structure. - -The ``populate()`` function must be registered to the |FCONF| framework with -the ``FCONF_REGISTER_POPULATOR()`` macro. This ensures that the function would -be called inside the generic ``fconf_populate()`` function during +Properties composing the |FCONF| have to be stored in C structures. If +properties originate from a different backend source such as a device tree, +then the platform has to provide a ``populate()`` function which essentially +captures the property and stores them into a corresponding |FCONF| based C +structure. + +Such a ``populate()`` function is usually platform specific and is associated +with a specific backend source. For example, a populator function which +captures the hardware topology of the platform from the HW_CONFIG device tree. +Hence each ``populate()`` function must be registered with a specific +``config_type`` identifier. It broadly represents a logical grouping of +configuration properties which is usually a device tree file. + +Example: + - TB_FW: properties related to trusted firmware such as IO policies, + base address of other DTBs, mbedtls heap info etc. + - HW_CONFIG: properties related to hardware configuration of the SoC + such as topology, GIC controller, PSCI hooks, CPU ID etc. + +Hence the ``populate()`` callback must be registered to the (|FCONF|) framework +with the ``FCONF_REGISTER_POPULATOR()`` macro. This ensures that the function +would be called inside the generic ``fconf_populate()`` function during initialization. :: - int fconf_populate_tbbr_dyn_config(uintptr_t config) + int fconf_populate_topology(uintptr_t config) { - /* read dtb and fill tbbr_dyn_config struct */ + /* read hw config dtb and fill soc_topology struct */ } - FCONF_REGISTER_POPULATOR(fconf_populate_tbbr_dyn_config); + FCONF_REGISTER_POPULATOR(HW_CONFIG, topology, fconf_populate_topology); Then, a wrapper has to be provided to match the ``FCONF_GET_PROPERTY()`` macro: @@ -60,7 +76,7 @@ Then, a wrapper has to be provided to match the ``FCONF_GET_PROPERTY()`` macro: #define FCONF_GET_PROPERTY(a,b,property) a##__##b##_getter(property) /* my specific getter */ - #define tbbr__dyn_config_getter(id) tbbr_dyn_config.id + #define hw_config__topology_getter(prop) soc_topology.prop This second level wrapper can be used to remap the ``FCONF_GET_PROPERTY()`` to anything appropriate: structure, array, function, etc.. @@ -80,6 +96,6 @@ Populating the properties Once a valid device tree is available, the ``fconf_populate(config)`` function can be used to fill the C data structure with the data from the config |DTB|. This function will call all the ``populate()`` callbacks which have been -registered with ``FCONF_REGISTER_POPULATOR()``. +registered with ``FCONF_REGISTER_POPULATOR()`` as described above. .. uml:: ../resources/diagrams/plantuml/fconf_bl2_populate.puml diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index babde41fe..6c2925afa 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -222,6 +222,7 @@ void arm_tsp_early_platform_setup(void); void arm_sp_min_early_platform_setup(void *from_bl2, uintptr_t tos_fw_config, uintptr_t hw_config, void *plat_params_from_bl2); void arm_sp_min_plat_runtime_setup(void); +void arm_sp_min_plat_arch_setup(void); /* FIP TOC validity check */ bool arm_io_is_toc_valid(void); diff --git a/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c new file mode 100644 index 000000000..1a1d0566f --- /dev/null +++ b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include + +struct gicv3_config_t gicv3_config; + +int fconf_populate_gicv3_config(uintptr_t config) +{ + int err; + int node; + int addr[20]; + + /* Necessary to work with libfdt APIs */ + const void *hw_config_dtb = (const void *)config; + + /* + * Find the offset of the node containing "arm,gic-v3" compatible property. + * Populating fconf strucutures dynamically is not supported for legacy + * systems which use GICv2 IP. Simply skip extracting GIC properties. + */ + node = fdt_node_offset_by_compatible(hw_config_dtb, -1, "arm,gic-v3"); + if (node < 0) { + WARN("FCONF: Unable to locate node with arm,gic-v3 compatible property\n"); + return 0; + } + /* Read the reg cell holding base address of GIC controller modules + A sample reg cell array is shown here: + reg = <0x0 0x2f000000 0 0x10000>, // GICD + <0x0 0x2f100000 0 0x200000>, // GICR + <0x0 0x2c000000 0 0x2000>, // GICC + <0x0 0x2c010000 0 0x2000>, // GICH + <0x0 0x2c02f000 0 0x2000>; // GICV + */ + + err = fdtw_read_array(hw_config_dtb, node, "reg", 20, &addr); + if (err < 0) { + ERROR("FCONF: Failed to read reg property of GIC node\n"); + } + return err; +} + + +FCONF_REGISTER_POPULATOR(HW_CONFIG, gicv3_config, fconf_populate_gicv3_config); diff --git a/plat/arm/board/fvp/fvp_bl31_setup.c b/plat/arm/board/fvp/fvp_bl31_setup.c index 8627c5ef0..dc7bfa2dc 100644 --- a/plat/arm/board/fvp/fvp_bl31_setup.c +++ b/plat/arm/board/fvp/fvp_bl31_setup.c @@ -1,16 +1,21 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ +#include +#include #include +#include #include #include #include #include "fvp_private.h" +uintptr_t hw_config_dtb; + void __init bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { @@ -40,4 +45,23 @@ void __init bl31_early_platform_setup2(u_register_t arg0, /* On FVP RevC, initialize SMMUv3 */ if ((arm_config.flags & ARM_CONFIG_FVP_HAS_SMMUV3) != 0U) smmuv3_init(PLAT_FVP_SMMUV3_BASE); + + hw_config_dtb = arg2; +} + +void __init bl31_plat_arch_setup(void) +{ + arm_bl31_plat_arch_setup(); + + /* + * For RESET_TO_BL31 systems, BL31 is the first bootloader to run. + * So there is no BL2 to load the HW_CONFIG dtb into memory before + * control is passed to BL31. + */ +#if !RESET_TO_BL31 && !BL2_AT_EL3 + assert(hw_config_dtb != 0U); + + INFO("BL31 FCONF: HW_CONFIG address = %p\n", (void *)hw_config_dtb); + fconf_populate("HW_CONFIG", hw_config_dtb); +#endif } diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c index 2c880fc30..33f3067f3 100644 --- a/plat/arm/board/fvp/fvp_common.c +++ b/plat/arm/board/fvp/fvp_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -134,6 +134,8 @@ const mmap_region_t plat_arm_mmap[] = { #if SPM_MM ARM_SPM_BUF_EL3_MMAP, #endif + /* Required by fconf APIs to read HW_CONFIG dtb loaded into DRAM */ + ARM_MAP_NS_DRAM1, {0} }; @@ -160,6 +162,8 @@ const mmap_region_t plat_arm_mmap[] = { V2M_MAP_IOFPGA, MAP_DEVICE0, MAP_DEVICE1, + /* Required by fconf APIs to read HW_CONFIG dtb loaded into DRAM */ + ARM_MAP_NS_DRAM1, {0} }; #endif diff --git a/plat/arm/board/fvp/include/fconf_hw_config_getter.h b/plat/arm/board/fvp/include/fconf_hw_config_getter.h new file mode 100644 index 000000000..cc1576e18 --- /dev/null +++ b/plat/arm/board/fvp/include/fconf_hw_config_getter.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FCONF_HW_CONFIG_GETTER_H +#define FCONF_HW_CONFIG_GETTER_H + +#include + +/* Hardware Config related getter */ +#define hw_config__gicv3_config_getter(prop) gicv3_config.prop + +struct gicv3_config_t { + void *gicd_base; + void *gicr_base; +}; + +int fconf_populate_gicv3_config(uintptr_t config); + +extern struct gicv3_config_t gicv3_config; + +#endif /* FCONF_HW_CONFIG_GETTER_H */ diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h index bfe207a29..69d49bab4 100644 --- a/plat/arm/board/fvp/include/platform_def.h +++ b/plat/arm/board/fvp/include/platform_def.h @@ -63,12 +63,12 @@ */ #if defined(IMAGE_BL31) # if SPM_MM -# define PLAT_ARM_MMAP_ENTRIES 9 +# define PLAT_ARM_MMAP_ENTRIES 10 # define MAX_XLAT_TABLES 9 # define PLAT_SP_IMAGE_MMAP_REGIONS 30 # define PLAT_SP_IMAGE_MAX_XLAT_TABLES 10 # else -# define PLAT_ARM_MMAP_ENTRIES 8 +# define PLAT_ARM_MMAP_ENTRIES 9 # if USE_DEBUGFS # define MAX_XLAT_TABLES 6 # else @@ -76,7 +76,7 @@ # endif # endif #elif defined(IMAGE_BL32) -# define PLAT_ARM_MMAP_ENTRIES 8 +# define PLAT_ARM_MMAP_ENTRIES 9 # define MAX_XLAT_TABLES 5 #elif !USE_ROMLIB # define PLAT_ARM_MMAP_ENTRIES 11 diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 05c11ce52..fc644302d 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -202,6 +202,12 @@ BL31_SOURCES += drivers/arm/fvp/fvp_pwrc.c \ ${FVP_INTERCONNECT_SOURCES} \ ${FVP_SECURITY_SOURCES} +# Support for fconf in BL31 +# Added separately from the above list for better readability +BL31_SOURCES += common/fdt_wrappers.c \ + lib/fconf/fconf.c \ + plat/arm/board/fvp/fconf/fconf_hw_config_getter.c + ifeq (${FVP_USE_SP804_TIMER},1) BL31_SOURCES += drivers/arm/sp804/sp804_delay_timer.c else diff --git a/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c b/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c index 88c91e6fe..763b42afb 100644 --- a/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c +++ b/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c @@ -1,13 +1,20 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ +#include + +#include +#include +#include #include #include "../fvp_private.h" +uintptr_t hw_config_dtb; + void plat_arm_sp_min_early_platform_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { @@ -30,4 +37,24 @@ void plat_arm_sp_min_early_platform_setup(u_register_t arg0, u_register_t arg1, * FVP PSCI code will enable coherency for other clusters. */ fvp_interconnect_enable(); + + hw_config_dtb = arg2; +} + +void sp_min_plat_arch_setup(void) +{ + arm_sp_min_plat_arch_setup(); + + /* + * For RESET_TO_SP_MIN systems, SP_MIN(BL32) is the first bootloader + * to run. So there is no BL2 to load the HW_CONFIG dtb into memory + * before control is passed to SP_MIN. + * Also, BL2 skips loading HW_CONFIG dtb for BL2_AT_EL3 builds. + */ +#if !RESET_TO_SP_MIN && !BL2_AT_EL3 + assert(hw_config_dtb != 0U); + + INFO("SP_MIN FCONF: HW_CONFIG address = %p\n", (void *)hw_config_dtb); + fconf_populate("HW_CONFIG", hw_config_dtb); +#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 0250a5f1a..520a70f99 100644 --- a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk +++ b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -18,4 +18,10 @@ BL32_SOURCES += drivers/arm/fvp/fvp_pwrc.c \ ${FVP_INTERCONNECT_SOURCES} \ ${FVP_SECURITY_SOURCES} +# Support for fconf in SP_MIN(BL32) +# Added separately from the above list for better readability +BL32_SOURCES += common/fdt_wrappers.c \ + lib/fconf/fconf.c \ + plat/arm/board/fvp/fconf/fconf_hw_config_getter.c + include plat/arm/common/sp_min/arm_sp_min.mk diff --git a/plat/arm/common/sp_min/arm_sp_min_setup.c b/plat/arm/common/sp_min/arm_sp_min_setup.c index cbbdfa21b..2904ad942 100644 --- a/plat/arm/common/sp_min/arm_sp_min_setup.c +++ b/plat/arm/common/sp_min/arm_sp_min_setup.c @@ -217,7 +217,7 @@ void sp_min_plat_runtime_setup(void) * Perform the very early platform specific architectural setup here. At the * moment this only initializes the MMU ******************************************************************************/ -void sp_min_plat_arch_setup(void) +void arm_sp_min_plat_arch_setup(void) { const mmap_region_t bl_regions[] = { MAP_BL_SP_MIN_TOTAL, @@ -232,3 +232,8 @@ void sp_min_plat_arch_setup(void) enable_mmu_svc_mon(0); } + +void sp_min_plat_arch_setup(void) +{ + arm_sp_min_plat_arch_setup(); +} -- cgit v1.2.3 From 4682461ded0ba15826022ca9e049e19602845e8a Mon Sep 17 00:00:00 2001 From: Madhukar Pappireddy Date: Fri, 27 Dec 2019 12:02:34 -0600 Subject: fconf: Extract topology node properties from HW_CONFIG dtb Create, register( and implicitly invoke) fconf_populate_topology() function which extracts the topology related properties from dtb into the newly created fconf based configuration structure 'soc_topology'. Appropriate libfdt APIs are added to jmptbl.i file for use with USE_ROMLIB build feature. A new property which describes the power domain levels is added to the HW_CONFIG device tree source files. This patch also fixes a minor bug in the common device tree file fvp-base-gicv3-psci-dynamiq-common.dtsi As this file includes fvp-base-gicv3-psci-common.dtsi, it is necessary to delete all previous cluster node definitons because DynamIQ based models have upto 8 CPUs in each cluster. If not deleted, the final dts would have an inaccurate description of SoC topology, i.e., cluster0 with 8 or more core nodes and cluster1 with 4 core nodes. Change-Id: I9eb406da3ba4732008a66c01afec7c9fa8ef59bf Signed-off-by: Madhukar Pappireddy --- fdts/fvp-base-gicv2-psci-aarch32.dts | 1 + fdts/fvp-base-gicv2-psci.dts | 1 + fdts/fvp-base-gicv3-psci-aarch32-common.dtsi | 1 + fdts/fvp-base-gicv3-psci-common.dtsi | 1 + fdts/fvp-base-gicv3-psci-dynamiq-common.dtsi | 3 + fdts/fvp-foundation-gicv2-psci.dts | 1 + fdts/fvp-foundation-gicv3-psci.dts | 1 + plat/arm/board/fvp/fconf/fconf_hw_config_getter.c | 116 +++++++++++++++++++++ .../arm/board/fvp/include/fconf_hw_config_getter.h | 11 ++ plat/arm/board/fvp/jmptbl.i | 2 + 10 files changed, 138 insertions(+) diff --git a/fdts/fvp-base-gicv2-psci-aarch32.dts b/fdts/fvp-base-gicv2-psci-aarch32.dts index e71a39519..fcef927b3 100644 --- a/fdts/fvp-base-gicv2-psci-aarch32.dts +++ b/fdts/fvp-base-gicv2-psci-aarch32.dts @@ -35,6 +35,7 @@ cpu_on = <0x84000003>; sys_poweroff = <0x84000008>; sys_reset = <0x84000009>; + max-pwr-lvl = <2>; }; cpus { diff --git a/fdts/fvp-base-gicv2-psci.dts b/fdts/fvp-base-gicv2-psci.dts index c9c9d9594..1e0a81c3c 100644 --- a/fdts/fvp-base-gicv2-psci.dts +++ b/fdts/fvp-base-gicv2-psci.dts @@ -35,6 +35,7 @@ cpu_on = <0xc4000003>; sys_poweroff = <0x84000008>; sys_reset = <0x84000009>; + max-pwr-lvl = <2>; }; cpus { diff --git a/fdts/fvp-base-gicv3-psci-aarch32-common.dtsi b/fdts/fvp-base-gicv3-psci-aarch32-common.dtsi index f9809db8b..a28a4a537 100644 --- a/fdts/fvp-base-gicv3-psci-aarch32-common.dtsi +++ b/fdts/fvp-base-gicv3-psci-aarch32-common.dtsi @@ -33,6 +33,7 @@ cpu_on = <0x84000003>; sys_poweroff = <0x84000008>; sys_reset = <0x84000009>; + max-pwr-lvl = <2>; }; cpus { diff --git a/fdts/fvp-base-gicv3-psci-common.dtsi b/fdts/fvp-base-gicv3-psci-common.dtsi index 5b0470d89..fb73f6053 100644 --- a/fdts/fvp-base-gicv3-psci-common.dtsi +++ b/fdts/fvp-base-gicv3-psci-common.dtsi @@ -33,6 +33,7 @@ cpu_on = <0xc4000003>; sys_poweroff = <0x84000008>; sys_reset = <0x84000009>; + max-pwr-lvl = <2>; }; cpus { diff --git a/fdts/fvp-base-gicv3-psci-dynamiq-common.dtsi b/fdts/fvp-base-gicv3-psci-dynamiq-common.dtsi index f3f768417..4bed36ff4 100644 --- a/fdts/fvp-base-gicv3-psci-dynamiq-common.dtsi +++ b/fdts/fvp-base-gicv3-psci-dynamiq-common.dtsi @@ -11,6 +11,9 @@ /* DynamIQ based designs have upto 8 CPUs in each cluster */ &CPU_MAP { + /delete-node/ cluster0; + /delete-node/ cluster1; + cluster0 { core0 { cpu = <&CPU0>; diff --git a/fdts/fvp-foundation-gicv2-psci.dts b/fdts/fvp-foundation-gicv2-psci.dts index b6da90549..3a204cb24 100644 --- a/fdts/fvp-foundation-gicv2-psci.dts +++ b/fdts/fvp-foundation-gicv2-psci.dts @@ -35,6 +35,7 @@ cpu_on = <0xc4000003>; sys_poweroff = <0x84000008>; sys_reset = <0x84000009>; + max-pwr-lvl = <2>; }; cpus { diff --git a/fdts/fvp-foundation-gicv3-psci.dts b/fdts/fvp-foundation-gicv3-psci.dts index 81071e255..d85305afe 100644 --- a/fdts/fvp-foundation-gicv3-psci.dts +++ b/fdts/fvp-foundation-gicv3-psci.dts @@ -35,6 +35,7 @@ cpu_on = <0xc4000003>; sys_poweroff = <0x84000008>; sys_reset = <0x84000009>; + max-pwr-lvl = <2>; }; cpus { 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 1a1d0566f..2952cde80 100644 --- a/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c +++ b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c @@ -12,6 +12,7 @@ #include struct gicv3_config_t gicv3_config; +struct hw_topology_t soc_topology; int fconf_populate_gicv3_config(uintptr_t config) { @@ -48,5 +49,120 @@ int fconf_populate_gicv3_config(uintptr_t config) return err; } +int fconf_populate_topology(uintptr_t config) +{ + int err, node, cluster_node, core_node, thread_node, max_pwr_lvl = 0; + uint32_t cluster_count = 0, max_cpu_per_cluster = 0, total_cpu_count = 0; + + /* Necessary to work with libfdt APIs */ + const void *hw_config_dtb = (const void *)config; + + /* Find the offset of the node containing "arm,psci-1.0" compatible property */ + node = fdt_node_offset_by_compatible(hw_config_dtb, -1, "arm,psci-1.0"); + if (node < 0) { + ERROR("FCONF: Unable to locate node with arm,psci-1.0 compatible property\n"); + return node; + } + + err = fdtw_read_cells(hw_config_dtb, node, "max-pwr-lvl", 1, &max_pwr_lvl); + if (err < 0) { + /* + * Some legacy FVP dts may not have this property. Assign the default + * value. + */ + WARN("FCONF: Could not locate max-pwr-lvl property\n"); + max_pwr_lvl = 2; + } + + assert((uint32_t)max_pwr_lvl <= MPIDR_AFFLVL2); + + /* Find the offset of the "cpus" node */ + node = fdt_path_offset(hw_config_dtb, "/cpus"); + if (node < 0) { + ERROR("FCONF: Node '%s' not found in hardware configuration dtb\n", "cpus"); + return node; + } + + /* A typical cpu-map node in a device tree is shown here for reference + cpu-map { + cluster0 { + core0 { + cpu = <&CPU0>; + }; + core1 { + cpu = <&CPU1>; + }; + }; + + cluster1 { + core0 { + cpu = <&CPU2>; + }; + core1 { + cpu = <&CPU3>; + }; + }; + }; + */ + + /* Locate the cpu-map child node */ + node = fdt_subnode_offset(hw_config_dtb, node, "cpu-map"); + if (node < 0) { + ERROR("FCONF: Node '%s' not found in hardware configuration dtb\n", "cpu-map"); + return node; + } + + uint32_t cpus_per_cluster[PLAT_ARM_CLUSTER_COUNT] = {0}; + + /* Iterate through cluster nodes */ + fdt_for_each_subnode(cluster_node, hw_config_dtb, node) { + assert(cluster_count < PLAT_ARM_CLUSTER_COUNT); + + /* Iterate through core nodes */ + fdt_for_each_subnode(core_node, hw_config_dtb, cluster_node) { + /* core nodes may have child nodes i.e., "thread" nodes */ + if (fdt_first_subnode(hw_config_dtb, core_node) < 0) { + cpus_per_cluster[cluster_count]++; + } else { + /* Multi-threaded CPU description is found in dtb */ + fdt_for_each_subnode(thread_node, hw_config_dtb, core_node) { + cpus_per_cluster[cluster_count]++; + } + + /* Since in some dtbs, core nodes may not have thread node, + * no need to error if even one child node is not found. + */ + } + } + + /* Ensure every cluster node has at least 1 child node */ + if (cpus_per_cluster[cluster_count] < 1U) { + ERROR("FCONF: Unable to locate the core node in cluster %d\n", cluster_count); + return -1; + } + + INFO("CLUSTER ID: %d cpu-count: %d\n", cluster_count, cpus_per_cluster[cluster_count]); + + /* Find the maximum number of cpus in any cluster */ + max_cpu_per_cluster = MAX(max_cpu_per_cluster, cpus_per_cluster[cluster_count]); + total_cpu_count += cpus_per_cluster[cluster_count]; + cluster_count++; + } + + + /* At least one cluster node is expected in hardware configuration dtb */ + if (cluster_count < 1U) { + ERROR("FCONF: Unable to locate the cluster node in cpu-map node\n"); + return -1; + } + + soc_topology.plat_max_pwr_level = (uint32_t)max_pwr_lvl; + soc_topology.plat_cluster_count = cluster_count; + soc_topology.cluster_cpu_count = max_cpu_per_cluster; + soc_topology.plat_cpu_count = total_cpu_count; + + return 0; +} FCONF_REGISTER_POPULATOR(HW_CONFIG, gicv3_config, fconf_populate_gicv3_config); +FCONF_REGISTER_POPULATOR(HW_CONFIG, topology, fconf_populate_topology); diff --git a/plat/arm/board/fvp/include/fconf_hw_config_getter.h b/plat/arm/board/fvp/include/fconf_hw_config_getter.h index cc1576e18..cab832f68 100644 --- a/plat/arm/board/fvp/include/fconf_hw_config_getter.h +++ b/plat/arm/board/fvp/include/fconf_hw_config_getter.h @@ -12,13 +12,24 @@ /* Hardware Config related getter */ #define hw_config__gicv3_config_getter(prop) gicv3_config.prop +#define hw_config__topology_getter(prop) soc_topology.prop + struct gicv3_config_t { void *gicd_base; void *gicr_base; }; +struct hw_topology_t { + uint32_t plat_cluster_count; + uint32_t cluster_cpu_count; + uint32_t plat_cpu_count; + uint32_t plat_max_pwr_level; +}; + int fconf_populate_gicv3_config(uintptr_t config); +int fconf_populate_topology(uintptr_t config); extern struct gicv3_config_t gicv3_config; +extern struct hw_topology_t soc_topology; #endif /* FCONF_HW_CONFIG_GETTER_H */ diff --git a/plat/arm/board/fvp/jmptbl.i b/plat/arm/board/fvp/jmptbl.i index b1b9ed463..0c93d0aab 100644 --- a/plat/arm/board/fvp/jmptbl.i +++ b/plat/arm/board/fvp/jmptbl.i @@ -22,6 +22,8 @@ fdt fdt_node_offset_by_compatible fdt fdt_setprop_inplace_namelen_partial fdt fdt_first_subnode fdt fdt_next_subnode +fdt fdt_path_offset +fdt fdt_subnode_offset mbedtls mbedtls_asn1_get_alg mbedtls mbedtls_asn1_get_alg_null mbedtls mbedtls_asn1_get_bitstring_null -- cgit v1.2.3 From 6dbe1c8f4dfa58c56bd4f729e2cc0066a1f2b885 Mon Sep 17 00:00:00 2001 From: kalyani chidambaram Date: Tue, 24 Jul 2018 13:58:27 -0700 Subject: Tegra194: fix warnings for extra parentheses armclang displays warnings for extra parentheses, leading to build failures as warnings are treated as errors. This patch removes the extra parentheses to fix this issue. Change-Id: Id2fd6a3086590436eecabc55502f40752a018131 Signed-off-by: Kalyani Chidambaram --- plat/nvidia/tegra/soc/t194/plat_psci_handlers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c index 144e41885..8920a9f0f 100644 --- a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c @@ -135,7 +135,7 @@ int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL] & TEGRA194_STATE_ID_MASK; - if ((stateid_afflvl0 == PSTATE_ID_CORE_POWERDN)) { + if (stateid_afflvl0 == PSTATE_ID_CORE_POWERDN) { /* Enter CPU powerdown */ (void)mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE, -- cgit v1.2.3 From 2ac7b223878502d5e05fa53f1846d7c4564ea526 Mon Sep 17 00:00:00 2001 From: Jeetesh Burman Date: Fri, 6 Jul 2018 19:58:30 +0530 Subject: Tegra194: store TZDRAM base/size to scratch registers This patch saves the TZDRAM base and size values to secure scratch registers, for the WB0. The WB0 reads these values and uses them to verify integrity of the TZDRAM aperture. Change-Id: I2f5fd11c87804d20e2698de33be977991c9f6f33 Signed-off-by: Jeetesh Burman --- plat/nvidia/tegra/include/t194/tegra_def.h | 2 ++ plat/nvidia/tegra/soc/t194/plat_secondary.c | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/plat/nvidia/tegra/include/t194/tegra_def.h b/plat/nvidia/tegra/include/t194/tegra_def.h index a58ae9d93..853b6536f 100644 --- a/plat/nvidia/tegra/include/t194/tegra_def.h +++ b/plat/nvidia/tegra/include/t194/tegra_def.h @@ -197,6 +197,8 @@ * Tegra scratch registers constants ******************************************************************************/ #define TEGRA_SCRATCH_BASE U(0x0C390000) +#define SECURE_SCRATCH_RSV72_LO U(0x2A4) +#define SECURE_SCRATCH_RSV72_HI U(0x2A8) #define SECURE_SCRATCH_RSV75 U(0x2BC) #define SECURE_SCRATCH_RSV81_LO U(0x2EC) #define SECURE_SCRATCH_RSV81_HI U(0x2F0) diff --git a/plat/nvidia/tegra/soc/t194/plat_secondary.c b/plat/nvidia/tegra/soc/t194/plat_secondary.c index c397c91ba..0882142a1 100644 --- a/plat/nvidia/tegra/soc/t194/plat_secondary.c +++ b/plat/nvidia/tegra/soc/t194/plat_secondary.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -13,6 +13,8 @@ #include #include +extern uint64_t tegra_bl31_phys_base; + #define MISCREG_AA64_RST_LOW 0x2004U #define MISCREG_AA64_RST_HIGH 0x2008U @@ -25,10 +27,14 @@ void plat_secondary_setup(void) { uint32_t addr_low, addr_high; plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); - uint64_t cpu_reset_handler_base, cpu_reset_handler_size; + uint64_t cpu_reset_handler_base, cpu_reset_handler_size, tzdram_addr; + uint64_t src_len_bytes = BL_END - tegra_bl31_phys_base; INFO("Setting up secondary CPU boot\n"); + tzdram_addr = params_from_bl2->tzdram_base + + tegra194_get_cpu_reset_handler_size(); + /* * The BL31 code resides in the TZSRAM which loses state * when we enter System Suspend. Copy the wakeup trampoline @@ -53,4 +59,8 @@ void plat_secondary_setup(void) addr_low); mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_HI, addr_high); + mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV72_LO, + (uint32_t)tzdram_addr); + mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV72_HI, + (uint32_t)src_len_bytes); } -- cgit v1.2.3 From 029dd14e72c0a7147ef326ae5cd24d77546b2094 Mon Sep 17 00:00:00 2001 From: Jeetesh Burman Date: Fri, 6 Jul 2018 20:03:38 +0530 Subject: Tegra194: add SE support to generate SHA256 of TZRAM The BL3-1 firmware code is stored in TZSRAM on Tegra194 platforms. This memory loses power when we enter System Suspend and so its contents are stored to TZDRAM, before entry. This opens up an attack vector where the TZDRAM contents might be tampered with when we are in the System Suspend mode. To mitigate this attack the SE engine calculates the hash of entire TZSRAM and stores it in PMC scratch, before we copy data to TZDRAM. The WB0 code will validate the TZDRAM and match the hash with the one in PMC scratch. This patch adds driver for the SE engine, with APIs to calculate the hash and store to PMC scratch registers. Change-Id: I04cc0eb7f54c69d64b6c34fc2ff62e4cfbdd43b2 Signed-off-by: Jeetesh Burman --- plat/nvidia/tegra/include/t194/tegra_def.h | 8 + plat/nvidia/tegra/soc/t194/drivers/include/se.h | 2 + plat/nvidia/tegra/soc/t194/drivers/se/se.c | 272 +++++++++++++++++++++ plat/nvidia/tegra/soc/t194/drivers/se/se_private.h | 82 ++++++- plat/nvidia/tegra/soc/t194/plat_psci_handlers.c | 35 ++- 5 files changed, 396 insertions(+), 3 deletions(-) diff --git a/plat/nvidia/tegra/include/t194/tegra_def.h b/plat/nvidia/tegra/include/t194/tegra_def.h index 853b6536f..e262c6a9b 100644 --- a/plat/nvidia/tegra/include/t194/tegra_def.h +++ b/plat/nvidia/tegra/include/t194/tegra_def.h @@ -197,6 +197,14 @@ * Tegra scratch registers constants ******************************************************************************/ #define TEGRA_SCRATCH_BASE U(0x0C390000) +#define SECURE_SCRATCH_RSV68_LO U(0x284) +#define SECURE_SCRATCH_RSV68_HI U(0x288) +#define SECURE_SCRATCH_RSV69_LO U(0x28C) +#define SECURE_SCRATCH_RSV69_HI U(0x290) +#define SECURE_SCRATCH_RSV70_LO U(0x294) +#define SECURE_SCRATCH_RSV70_HI U(0x298) +#define SECURE_SCRATCH_RSV71_LO U(0x29C) +#define SECURE_SCRATCH_RSV71_HI U(0x2A0) #define SECURE_SCRATCH_RSV72_LO U(0x2A4) #define SECURE_SCRATCH_RSV72_HI U(0x2A8) #define SECURE_SCRATCH_RSV75 U(0x2BC) diff --git a/plat/nvidia/tegra/soc/t194/drivers/include/se.h b/plat/nvidia/tegra/soc/t194/drivers/include/se.h index e7cf88d05..7de55a74d 100644 --- a/plat/nvidia/tegra/soc/t194/drivers/include/se.h +++ b/plat/nvidia/tegra/soc/t194/drivers/include/se.h @@ -7,6 +7,8 @@ #ifndef SE_H #define SE_H +int32_t tegra_se_calculate_save_sha256(uint64_t src_addr, + uint32_t src_len_inbyte); int32_t tegra_se_suspend(void); void tegra_se_resume(void); diff --git a/plat/nvidia/tegra/soc/t194/drivers/se/se.c b/plat/nvidia/tegra/soc/t194/drivers/se/se.c index a3b338940..0069e3f3b 100644 --- a/plat/nvidia/tegra/soc/t194/drivers/se/se.c +++ b/plat/nvidia/tegra/soc/t194/drivers/se/se.c @@ -28,6 +28,14 @@ #define MAX_TIMEOUT_MS U(100) /* Timeout in 100ms */ #define NUM_SE_REGS_TO_SAVE U(4) +#define SE0_MAX_BUSY_TIMEOUT_MS U(100) /* 100ms Timeout Expired */ +#define BYTES_IN_WORD U(4) +#define SHA256_MAX_HASH_RESULT U(7) +#define SHA256_DST_SIZE U(32) +#define SHA_FIRST_OP U(1) +#define MAX_SHA_ENGINE_CHUNK_SIZE U(0xFFFFFF) +#define SHA256_MSG_LENGTH_ONETIME U(0xFFFF) + /******************************************************************************* * Data structure and global variables ******************************************************************************/ @@ -175,6 +183,270 @@ static int32_t tegra_se_save_context(void) return ret; } +/* + * Check that SE operation has completed after kickoff + * This function is invoked after an SE operation has been started, + * and it checks the following conditions: + * 1. SE0_INT_STATUS = SE0_OP_DONE + * 2. SE0_STATUS = IDLE + * 3. SE0_ERR_STATUS is clean. + */ +static int32_t tegra_se_sha256_hash_operation_complete(void) +{ + uint32_t val = 0U; + + /* Poll the SE interrupt register to ensure H/W operation complete */ + val = tegra_se_read_32(SE0_INT_STATUS_REG_OFFSET); + while (SE0_INT_OP_DONE(val) == SE0_INT_OP_DONE_CLEAR) { + val = tegra_se_read_32(SE0_INT_STATUS_REG_OFFSET); + if (SE0_INT_OP_DONE(val) != SE0_INT_OP_DONE_CLEAR) { + break; + } + } + + /* Poll the SE status idle to ensure H/W operation complete */ + val = tegra_se_read_32(SE0_SHA_STATUS_0); + while (val != SE0_SHA_STATUS_IDLE) { + val = tegra_se_read_32(SE0_SHA_STATUS_0); + if (val == SE0_SHA_STATUS_IDLE) { + break; + } + } + + /* Ensure that no errors are thrown during operation */ + val = tegra_se_read_32(SE0_ERR_STATUS_REG_OFFSET); + if (val != 0U) { + ERROR("%s: error during SE operation! 0x%x", __func__, + val); + return -ENOTSUP; + } + + return 0; +} + +/* + * Security engine primitive normal operations + */ +static int32_t tegra_se_start_normal_operation(uint64_t src_addr, + uint32_t nbytes, uint32_t last_buf, uint32_t src_len_inbytes) +{ + uint32_t val = 0U; + uint32_t src_in_lo; + uint32_t src_in_msb; + uint32_t src_in_hi; + int32_t ret = 0; + + if ((src_addr == 0ULL) || (nbytes == 0U)) + return -EINVAL; + + src_in_lo = (uint32_t)src_addr; + src_in_msb = (uint32_t)((src_addr >> 32U) & 0xFFU); + src_in_hi = ((src_in_msb << SE0_IN_HI_ADDR_HI_0_MSB_SHIFT) | + (nbytes & MAX_SHA_ENGINE_CHUNK_SIZE)); + + /* set SRC_IN_ADDR_LO and SRC_IN_ADDR_HI*/ + tegra_se_write_32(SE0_IN_ADDR, src_in_lo); + tegra_se_write_32(SE0_IN_HI_ADDR_HI, src_in_hi); + + val = tegra_se_read_32(SE0_INT_STATUS_REG_OFFSET); + if (val > 0U) { + tegra_se_write_32(SE0_INT_STATUS_REG_OFFSET, 0x0U); + } + + /* Enable SHA interrupt for SE0 Operation */ + tegra_se_write_32(SE0_SHA_INT_ENABLE, 0x1aU); + + /* flush to DRAM for SE to use the updated contents */ + flush_dcache_range(src_addr, src_len_inbytes); + + /* Start SHA256 operation */ + if (last_buf == 1U) { + tegra_se_write_32(SE0_OPERATION_REG_OFFSET, SE0_OP_START | + SE0_UNIT_OPERATION_PKT_LASTBUF_FIELD); + } else { + tegra_se_write_32(SE0_OPERATION_REG_OFFSET, SE0_OP_START); + } + + return ret; +} + +static int32_t tegra_se_calculate_sha256_hash(uint64_t src_addr, + uint32_t src_len_inbyte) +{ + uint32_t val, last_buf, i; + int32_t ret = 0; + uint32_t operations; + uint64_t src_len_inbits; + uint32_t len_bits_msb; + uint32_t len_bits_lsb; + uint32_t number_of_operations, max_bytes, bytes_left, remaining_bytes; + + if (src_len_inbyte > MAX_SHA_ENGINE_CHUNK_SIZE) { + ERROR("SHA input chunk size too big: 0x%x\n", src_len_inbyte); + return -EINVAL; + } + + if (src_addr == 0ULL) { + return -EINVAL; + } + + /* number of bytes per operation */ + max_bytes = (SHA256_HASH_SIZE_BYTES * SHA256_MSG_LENGTH_ONETIME); + + src_len_inbits = (uint32_t)(src_len_inbyte * 8U); + len_bits_msb = (uint32_t)(src_len_inbits >> 32U); + len_bits_lsb = (uint32_t)src_len_inbits; + + /* program SE0_CONFIG for SHA256 operation */ + val = (uint32_t)(SE0_CONFIG_ENC_ALG_SHA | SE0_CONFIG_ENC_MODE_SHA256 | + SE0_CONFIG_DEC_ALG_NOP | SE0_CONFIG_DST_HASHREG); + tegra_se_write_32(SE0_SHA_CONFIG, val); + + /* set SE0_SHA_MSG_LENGTH registers */ + tegra_se_write_32(SE0_SHA_MSG_LENGTH_0, len_bits_lsb); + tegra_se_write_32(SE0_SHA_MSG_LEFT_0, len_bits_lsb); + tegra_se_write_32(SE0_SHA_MSG_LENGTH_1, len_bits_msb); + + /* zero out unused SE0_SHA_MSG_LENGTH and SE0_SHA_MSG_LEFT */ + tegra_se_write_32(SE0_SHA_MSG_LENGTH_2, 0U); + tegra_se_write_32(SE0_SHA_MSG_LENGTH_3, 0U); + tegra_se_write_32(SE0_SHA_MSG_LEFT_1, 0U); + tegra_se_write_32(SE0_SHA_MSG_LEFT_2, 0U); + tegra_se_write_32(SE0_SHA_MSG_LEFT_3, 0U); + + number_of_operations = (src_len_inbyte / max_bytes); + remaining_bytes = (src_len_inbyte % max_bytes); + if (remaining_bytes > 0U) { + number_of_operations += 1U; + } + + /* + * 1. Operations == 1: program SE0_SHA_TASK register to initiate SHA256 + * hash generation by setting + * 1(SE0_SHA_CONFIG_HW_INIT_HASH) to SE0_SHA_TASK + * and start SHA256-normal operation. + * 2. 1 < Operations < number_of_operations: program SE0_SHA_TASK to + * 0(SE0_SHA_CONFIG_HW_INIT_HASH_DISABLE) to load + * intermediate SHA256 digest result from + * HASH_RESULT register to continue SHA256 + * generation and start SHA256-normal operation. + * 3. Operations == number_of_operations: continue with step 2 and set + * max_bytes to bytes_left to process final + * hash-result generation and start SHA256-normal + * operation. + */ + bytes_left = src_len_inbyte; + for (operations = 1U; operations <= number_of_operations; + operations++) { + if (operations == SHA_FIRST_OP) { + val = SE0_SHA_CONFIG_HW_INIT_HASH; + } else { + /* Load intermediate SHA digest result to + * SHA:HASH_RESULT(0..7) to continue the SHA + * calculation and tell the SHA engine to use it. + */ + for (i = 0U; (i / BYTES_IN_WORD) <= + SHA256_MAX_HASH_RESULT; i += BYTES_IN_WORD) { + val = tegra_se_read_32(SE0_SHA_HASH_RESULT_0 + + i); + tegra_se_write_32(SE0_SHA_HASH_RESULT_0 + i, + val); + } + val = SE0_SHA_CONFIG_HW_INIT_HASH_DISABLE; + if (len_bits_lsb <= (max_bytes * 8U)) { + len_bits_lsb = (remaining_bytes * 8U); + } else { + len_bits_lsb -= (max_bytes * 8U); + } + tegra_se_write_32(SE0_SHA_MSG_LEFT_0, len_bits_lsb); + } + tegra_se_write_32(SE0_SHA_TASK_CONFIG, val); + + max_bytes = (SHA256_HASH_SIZE_BYTES * + SHA256_MSG_LENGTH_ONETIME); + if (bytes_left < max_bytes) { + max_bytes = bytes_left; + last_buf = 1U; + } else { + bytes_left = bytes_left - max_bytes; + last_buf = 0U; + } + /* start operation */ + ret = tegra_se_start_normal_operation(src_addr, max_bytes, + last_buf, src_len_inbyte); + if (ret != 0) { + ERROR("Error during SE operation! 0x%x", ret); + return -EINVAL; + } + } + + return ret; +} + +static int32_t tegra_se_save_sha256_pmc_scratch(void) +{ + uint32_t val = 0U, hash_offset = 0U, scratch_offset = 0U; + int32_t ret; + + /* Check SE0 operation status */ + ret = tegra_se_sha256_hash_operation_complete(); + if (ret != 0) { + ERROR("SE operation complete Failed! 0x%x", ret); + return ret; + } + + for (scratch_offset = SECURE_SCRATCH_TZDRAM_SHA256_HASH_START; + scratch_offset <= SECURE_SCRATCH_TZDRAM_SHA256_HASH_END; + scratch_offset += BYTES_IN_WORD) { + val = tegra_se_read_32(SE0_SHA_HASH_RESULT_0 + hash_offset); + mmio_write_32((uint32_t)(TEGRA_SCRATCH_BASE + scratch_offset), + val); + hash_offset += BYTES_IN_WORD; + } + return 0; +} + +/* + * Handler to generate SHA256 and save HASH-result to pmc-scratch register + */ +int32_t tegra_se_calculate_save_sha256(uint64_t src_addr, + uint32_t src_len_inbyte) +{ + uint32_t security; + int32_t val = 0; + + /* Set SE_SOFT_SETTINGS=SE_SECURE to prevent NS process to change SE + * registers. + */ + security = tegra_se_read_32(SE0_SECURITY); + tegra_se_write_32(SE0_SECURITY, security | SE0_SECURITY_SE_SOFT_SETTING); + + /* Bootrom enable IN_ID bit in SE0_SHA_GSCID_0 register during SC7-exit, causing + * SE0 ignores SE0 operation, and therefore failure of 2nd iteration of SC7 cycle. + */ + tegra_se_write_32(SE0_SHA_GSCID_0, 0x0U); + + /* Calculate SHA256 of BL31 */ + val = tegra_se_calculate_sha256_hash(src_addr, src_len_inbyte); + if (val != 0) { + ERROR("%s: SHA256 generation failed\n", __func__); + return val; + } + + /* + * Reset SE_SECURE to previous value. + */ + tegra_se_write_32(SE0_SECURITY, security); + + /* copy sha256_dst to PMC Scratch register */ + val = tegra_se_save_sha256_pmc_scratch(); + if (val != 0) { + ERROR("%s: SE0 status Error.\n", __func__); + } + + return val; +} + /* * Handler to power down the SE hardware blocks - SE, RNG1 and PKA1. This * needs to be called only during System Suspend. diff --git a/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h b/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h index 577217b8e..fc118aaa1 100644 --- a/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h +++ b/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h @@ -9,6 +9,86 @@ #define SE_PRIVATE_H #include +#include + +/* SE0 security register */ +#define SE0_SECURITY U(0x18) +#define SE0_SECURITY_SE_SOFT_SETTING (((uint32_t)1) << 16U) + +/* SE0 SHA GSCID register */ +#define SE0_SHA_GSCID_0 U(0x100) + +/* SE0 config register */ +#define SE0_SHA_CONFIG U(0x104) +#define SE0_SHA_TASK_CONFIG U(0x108) +#define SE0_SHA_CONFIG_HW_INIT_HASH (((uint32_t)1) << 0U) +#define SE0_SHA_CONFIG_HW_INIT_HASH_DISABLE U(0) + +#define SE0_CONFIG_ENC_ALG_SHIFT U(12) +#define SE0_CONFIG_ENC_ALG_SHA \ + (((uint32_t)3) << SE0_CONFIG_ENC_ALG_SHIFT) +#define SE0_CONFIG_DEC_ALG_SHIFT U(8) +#define SE0_CONFIG_DEC_ALG_NOP \ + (((uint32_t)0) << SE0_CONFIG_DEC_ALG_SHIFT) +#define SE0_CONFIG_DST_SHIFT U(2) +#define SE0_CONFIG_DST_HASHREG \ + (((uint32_t)1) << SE0_CONFIG_DST_SHIFT) +#define SHA256_HASH_SIZE_BYTES U(256) + +#define SE0_CONFIG_ENC_MODE_SHIFT U(24) +#define SE0_CONFIG_ENC_MODE_SHA256 \ + (((uint32_t)5) << SE0_CONFIG_ENC_MODE_SHIFT) + +/* SHA input message length */ +#define SE0_IN_ADDR U(0x10c) +#define SE0_IN_HI_ADDR_HI U(0x110) +#define SE0_IN_HI_ADDR_HI_0_MSB_SHIFT U(24) + +/* SHA input message length */ +#define SE0_SHA_MSG_LENGTH_0 U(0x11c) +#define SE0_SHA_MSG_LENGTH_1 U(0x120) +#define SE0_SHA_MSG_LENGTH_2 U(0x124) +#define SE0_SHA_MSG_LENGTH_3 U(0x128) + +/* SHA input message left */ +#define SE0_SHA_MSG_LEFT_0 U(0x12c) +#define SE0_SHA_MSG_LEFT_1 U(0x130) +#define SE0_SHA_MSG_LEFT_2 U(0x134) +#define SE0_SHA_MSG_LEFT_3 U(0x138) + +/* SE HASH-RESULT */ +#define SE0_SHA_HASH_RESULT_0 U(0x13c) + +/* SE OPERATION */ +#define SE0_OPERATION_REG_OFFSET U(0x17c) +#define SE0_UNIT_OPERATION_PKT_LASTBUF_SHIFT U(16) +#define SE0_UNIT_OPERATION_PKT_LASTBUF_FIELD \ + ((uint32_t)0x1 << SE0_UNIT_OPERATION_PKT_LASTBUF_SHIFT) +#define SE0_OPERATION_SHIFT U(0) +#define SE0_OP_START \ + (((uint32_t)0x1) << SE0_OPERATION_SHIFT) + +/* SE Interrupt */ +#define SE0_SHA_INT_ENABLE U(0x180) + +#define SE0_INT_STATUS_REG_OFFSET U(0x184) +#define SE0_INT_OP_DONE_SHIFT U(4) +#define SE0_INT_OP_DONE_CLEAR \ + (((uint32_t)0U) << SE0_INT_OP_DONE_SHIFT) +#define SE0_INT_OP_DONE(x) \ + ((x) & (((uint32_t)0x1U) << SE0_INT_OP_DONE_SHIFT)) + +/* SE SHA Status */ +#define SE0_SHA_STATUS_0 U(0x188) +#define SE0_SHA_STATUS_IDLE U(0) + +/* SE error status */ +#define SE0_ERR_STATUS_REG_OFFSET U(0x18c) +#define SE0_ERR_STATUS_CLEAR U(0) + +/* SE error status */ +#define SECURE_SCRATCH_TZDRAM_SHA256_HASH_START SECURE_SCRATCH_RSV68_LO +#define SECURE_SCRATCH_TZDRAM_SHA256_HASH_END SECURE_SCRATCH_RSV71_HI /* SE0_INT_ENABLE_0 */ #define SE0_INT_ENABLE U(0x88) @@ -20,7 +100,7 @@ /* SE0_SHA_INT_STATUS_0 */ #define SHA_INT_STATUS U(0x184) -#define SHA_SE_OP_DONE (U(1) << 4) +#define SHA_SE_OP_DONE (U(1) << 4) /* SE0_SHA_ERR_STATUS_0 */ #define SHA_ERR_STATUS U(0x18C) diff --git a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c index 8920a9f0f..7af3b325d 100644 --- a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c @@ -10,9 +10,11 @@ #include #include +#include #include #include #include +#include #include #include #include @@ -289,9 +291,34 @@ int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_sta plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); uint8_t stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL] & TEGRA194_STATE_ID_MASK; + uint64_t src_len_in_bytes = (uintptr_t)&__BL31_END__ - (uintptr_t)BL31_BASE; uint64_t val; + int32_t ret = PSCI_E_SUCCESS; if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) { + val = params_from_bl2->tzdram_base + + tegra194_get_cpu_reset_handler_size(); + + /* initialise communication channel with BPMP */ + ret = tegra_bpmp_ipc_init(); + assert(ret == 0); + + /* Enable SE clock before SE context save */ + ret = tegra_bpmp_ipc_enable_clock(TEGRA_CLK_SE); + assert(ret == 0); + + /* + * It is very unlikely that the BL31 image would be + * bigger than 2^32 bytes + */ + assert(src_len_in_bytes < UINT32_MAX); + + if (tegra_se_calculate_save_sha256(BL31_BASE, + (uint32_t)src_len_in_bytes) != 0) { + ERROR("Hash calculation failed. Reboot\n"); + (void)tegra_soc_prepare_system_reset(); + } + /* * The TZRAM loses power when we enter system suspend. To * allow graceful exit from system suspend, we need to copy @@ -300,10 +327,14 @@ int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_sta val = params_from_bl2->tzdram_base + tegra194_get_cpu_reset_handler_size(); memcpy((void *)(uintptr_t)val, (void *)(uintptr_t)BL31_BASE, - (uintptr_t)&__BL31_END__ - (uintptr_t)BL31_BASE); + src_len_in_bytes); + + /* Disable SE clock after SE context save */ + ret = tegra_bpmp_ipc_disable_clock(TEGRA_CLK_SE); + assert(ret == 0); } - return PSCI_E_SUCCESS; + return ret; } int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state) -- cgit v1.2.3 From de3fd9b3bbfbf6c15adbd9f32c0e10637700c191 Mon Sep 17 00:00:00 2001 From: Pritesh Raithatha Date: Thu, 23 Aug 2018 11:47:23 +0530 Subject: Tegra194: memctrl: lock some more MC SID security configs The platform code already contains the initial set of MC SID security configs to be locked during boot. This patch adds some more configs to the list. Since the reset value of these registers is already as per expectations, there is no need to change it. MC SID security configs - PTCR, - MIU6R, MIU6W, MIU7R, MIU7W, - MPCORER, MPCOREW, - NVDEC1SRD, NVDEC1SRD1, NVDEC1SWR. Change-Id: Ia9a1f6a6b6d34fb2787298651f7a4792a40b88ab Signed-off-by: Pritesh Raithatha --- plat/nvidia/tegra/soc/t194/plat_memctrl.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/plat/nvidia/tegra/soc/t194/plat_memctrl.c b/plat/nvidia/tegra/soc/t194/plat_memctrl.c index d5f72b614..f56084cbe 100644 --- a/plat/nvidia/tegra/soc/t194/plat_memctrl.c +++ b/plat/nvidia/tegra/soc/t194/plat_memctrl.c @@ -15,12 +15,15 @@ * Array to hold stream_id override config register offsets ******************************************************************************/ const static uint32_t tegra194_streamid_override_regs[] = { + MC_STREAMID_OVERRIDE_CFG_PTCR, MC_STREAMID_OVERRIDE_CFG_HDAR, MC_STREAMID_OVERRIDE_CFG_HOST1XDMAR, MC_STREAMID_OVERRIDE_CFG_NVENCSRD, MC_STREAMID_OVERRIDE_CFG_SATAR, + MC_STREAMID_OVERRIDE_CFG_MPCORER, MC_STREAMID_OVERRIDE_CFG_NVENCSWR, MC_STREAMID_OVERRIDE_CFG_HDAW, + MC_STREAMID_OVERRIDE_CFG_MPCOREW, MC_STREAMID_OVERRIDE_CFG_SATAW, MC_STREAMID_OVERRIDE_CFG_ISPRA, MC_STREAMID_OVERRIDE_CFG_ISPFALR, @@ -131,6 +134,9 @@ const static uint32_t tegra194_streamid_override_regs[] = { MC_STREAMID_OVERRIDE_CFG_NVENC1SRD1, MC_STREAMID_OVERRIDE_CFG_ISPRA1, MC_STREAMID_OVERRIDE_CFG_PCIE0R1, + MC_STREAMID_OVERRIDE_CFG_NVDEC1SRD, + MC_STREAMID_OVERRIDE_CFG_NVDEC1SRD1, + MC_STREAMID_OVERRIDE_CFG_NVDEC1SWR, MC_STREAMID_OVERRIDE_CFG_MIU0R, MC_STREAMID_OVERRIDE_CFG_MIU0W, MC_STREAMID_OVERRIDE_CFG_MIU1R, @@ -142,19 +148,26 @@ const static uint32_t tegra194_streamid_override_regs[] = { MC_STREAMID_OVERRIDE_CFG_MIU4R, MC_STREAMID_OVERRIDE_CFG_MIU4W, MC_STREAMID_OVERRIDE_CFG_MIU5R, - MC_STREAMID_OVERRIDE_CFG_MIU5W + MC_STREAMID_OVERRIDE_CFG_MIU5W, + MC_STREAMID_OVERRIDE_CFG_MIU6R, + MC_STREAMID_OVERRIDE_CFG_MIU6W, + MC_STREAMID_OVERRIDE_CFG_MIU7R, + MC_STREAMID_OVERRIDE_CFG_MIU7W }; /******************************************************************************* * Array to hold the security configs for stream IDs ******************************************************************************/ const static mc_streamid_security_cfg_t tegra194_streamid_sec_cfgs[] = { + mc_make_sec_cfg(PTCR, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(HDAR, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(HOST1XDMAR, NON_SECURE, NO_OVERRIDE, DISABLE), mc_make_sec_cfg(NVENCSRD, NON_SECURE, NO_OVERRIDE, DISABLE), mc_make_sec_cfg(SATAR, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(MPCORER, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(NVENCSWR, NON_SECURE, NO_OVERRIDE, DISABLE), mc_make_sec_cfg(HDAW, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(MPCOREW, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(SATAW, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(ISPRA, NON_SECURE, NO_OVERRIDE, ENABLE), mc_make_sec_cfg(ISPFALR, NON_SECURE, NO_OVERRIDE, ENABLE), @@ -265,6 +278,9 @@ const static mc_streamid_security_cfg_t tegra194_streamid_sec_cfgs[] = { mc_make_sec_cfg(NVENC1SRD1, NON_SECURE, NO_OVERRIDE, DISABLE), mc_make_sec_cfg(ISPRA1, NON_SECURE, NO_OVERRIDE, ENABLE), mc_make_sec_cfg(PCIE0R1, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(NVDEC1SRD, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(NVDEC1SRD1, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(NVDEC1SWR, NON_SECURE, NO_OVERRIDE, DISABLE), mc_make_sec_cfg(MIU0R, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(MIU0W, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(MIU1R, NON_SECURE, OVERRIDE, DISABLE), @@ -276,7 +292,11 @@ const static mc_streamid_security_cfg_t tegra194_streamid_sec_cfgs[] = { mc_make_sec_cfg(MIU4R, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(MIU4W, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(MIU5R, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(MIU5W, NON_SECURE, OVERRIDE, DISABLE) + mc_make_sec_cfg(MIU5W, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(MIU6R, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(MIU6W, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(MIU7R, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(MIU7W, NON_SECURE, OVERRIDE, DISABLE) }; /******************************************************************************* -- cgit v1.2.3 From e904448006b03385c69802d080c4d568b914d828 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Thu, 13 Sep 2018 08:47:43 -0700 Subject: Tegra: bpmp: fixup TEGRA_CLK_SE values for Tegra186/Tegra194 This patch fixes the SE clock ID being used for Tegra186 and Tegra194 SoCs. Previous assumption, that both SoCs use the same clock ID, was incorrect. Change-Id: I1ef0da5547ff2e14151b53968cad9cc78fee63bd Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/include/drivers/bpmp_ipc.h | 5 ----- plat/nvidia/tegra/include/t186/tegra_def.h | 6 ++++++ plat/nvidia/tegra/include/t194/tegra_def.h | 6 ++++++ plat/nvidia/tegra/soc/t186/plat_psci_handlers.c | 4 ++-- plat/nvidia/tegra/soc/t194/drivers/se/se.c | 8 ++++---- plat/nvidia/tegra/soc/t194/plat_psci_handlers.c | 4 ++-- 6 files changed, 20 insertions(+), 13 deletions(-) diff --git a/plat/nvidia/tegra/include/drivers/bpmp_ipc.h b/plat/nvidia/tegra/include/drivers/bpmp_ipc.h index a0d02c949..401a07a24 100644 --- a/plat/nvidia/tegra/include/drivers/bpmp_ipc.h +++ b/plat/nvidia/tegra/include/drivers/bpmp_ipc.h @@ -18,11 +18,6 @@ #define TEGRA_RESET_ID_XUSB_PADCTL U(114) #define TEGRA_RESET_ID_GPCDMA U(70) -/** - * Clock identifier for the SE device - */ -#define TEGRA_CLK_SE U(124) - /** * Function to initialise the IPC with the bpmp */ diff --git a/plat/nvidia/tegra/include/t186/tegra_def.h b/plat/nvidia/tegra/include/t186/tegra_def.h index 3d037e134..56157e2de 100644 --- a/plat/nvidia/tegra/include/t186/tegra_def.h +++ b/plat/nvidia/tegra/include/t186/tegra_def.h @@ -72,6 +72,12 @@ #define TEGRA186_SEC_IRQ_TARGET_MASK U(0xF3) /* 4 A57 - 2 Denver */ +/******************************************************************************* + * Clock identifier for the SE device + ******************************************************************************/ +#define TEGRA186_CLK_SE U(103) +#define TEGRA_CLK_SE TEGRA186_CLK_SE + /******************************************************************************* * Tegra Miscellanous register constants ******************************************************************************/ diff --git a/plat/nvidia/tegra/include/t194/tegra_def.h b/plat/nvidia/tegra/include/t194/tegra_def.h index e262c6a9b..7fd97785e 100644 --- a/plat/nvidia/tegra/include/t194/tegra_def.h +++ b/plat/nvidia/tegra/include/t194/tegra_def.h @@ -42,6 +42,12 @@ #define TEGRA194_SEC_IRQ_TARGET_MASK U(0xFF) /* 8 Carmel */ +/******************************************************************************* + * Clock identifier for the SE device + ******************************************************************************/ +#define TEGRA194_CLK_SE U(124) +#define TEGRA_CLK_SE TEGRA194_CLK_SE + /******************************************************************************* * Tegra Miscellanous register constants ******************************************************************************/ diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c index a0879cc0d..f034bdb87 100644 --- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c @@ -294,7 +294,7 @@ int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_sta assert(tegra_bpmp_ipc_init() == 0); /* Enable SE clock */ - ret = tegra_bpmp_ipc_enable_clock(TEGRA_CLK_SE); + ret = tegra_bpmp_ipc_enable_clock(TEGRA186_CLK_SE); if (ret != 0) { ERROR("Failed to enable clock\n"); return ret; @@ -319,7 +319,7 @@ int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_sta memcpy16((void *)(uintptr_t)val, (void *)(uintptr_t)BL31_BASE, (uintptr_t)BL31_END - (uintptr_t)BL31_BASE); - ret = tegra_bpmp_ipc_disable_clock(TEGRA_CLK_SE); + ret = tegra_bpmp_ipc_disable_clock(TEGRA186_CLK_SE); if (ret != 0) { ERROR("Failed to disable clock\n"); return ret; diff --git a/plat/nvidia/tegra/soc/t194/drivers/se/se.c b/plat/nvidia/tegra/soc/t194/drivers/se/se.c index 0069e3f3b..ccdc94d13 100644 --- a/plat/nvidia/tegra/soc/t194/drivers/se/se.c +++ b/plat/nvidia/tegra/soc/t194/drivers/se/se.c @@ -459,7 +459,7 @@ int32_t tegra_se_suspend(void) assert(tegra_bpmp_ipc_init() == 0); /* Enable SE clock before SE context save */ - ret = tegra_bpmp_ipc_enable_clock(TEGRA_CLK_SE); + ret = tegra_bpmp_ipc_enable_clock(TEGRA194_CLK_SE); assert(ret == 0); /* save SE registers */ @@ -475,7 +475,7 @@ int32_t tegra_se_suspend(void) } /* Disable SE clock after SE context save */ - ret = tegra_bpmp_ipc_disable_clock(TEGRA_CLK_SE); + ret = tegra_bpmp_ipc_disable_clock(TEGRA194_CLK_SE); assert(ret == 0); return ret; @@ -492,7 +492,7 @@ void tegra_se_resume(void) assert(tegra_bpmp_ipc_init() == 0); /* Enable SE clock before SE context restore */ - ret = tegra_bpmp_ipc_enable_clock(TEGRA_CLK_SE); + ret = tegra_bpmp_ipc_enable_clock(TEGRA194_CLK_SE); assert(ret == 0); /* @@ -507,6 +507,6 @@ void tegra_se_resume(void) mmio_write_32(TEGRA_PKA1_BASE + PKA1_MUTEX_WATCHDOG_NS_LIMIT, se_regs[3]); /* Disable SE clock after SE context restore */ - ret = tegra_bpmp_ipc_disable_clock(TEGRA_CLK_SE); + ret = tegra_bpmp_ipc_disable_clock(TEGRA194_CLK_SE); assert(ret == 0); } diff --git a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c index 7af3b325d..3c91af4bc 100644 --- a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c @@ -304,7 +304,7 @@ int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_sta assert(ret == 0); /* Enable SE clock before SE context save */ - ret = tegra_bpmp_ipc_enable_clock(TEGRA_CLK_SE); + ret = tegra_bpmp_ipc_enable_clock(TEGRA194_CLK_SE); assert(ret == 0); /* @@ -330,7 +330,7 @@ int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_sta src_len_in_bytes); /* Disable SE clock after SE context save */ - ret = tegra_bpmp_ipc_disable_clock(TEGRA_CLK_SE); + ret = tegra_bpmp_ipc_disable_clock(TEGRA194_CLK_SE); assert(ret == 0); } -- cgit v1.2.3 From a391d4942a4d34f5293a66e171682f6ca8d0010e Mon Sep 17 00:00:00 2001 From: Pritesh Raithatha Date: Fri, 3 Aug 2018 15:48:15 +0530 Subject: Tegra: smmu: remove context save sequence SMMU and MC registers are saved as part of the System Suspend sequence. The register list includes some NS world SMMU registers that need to be saved by NS world software instead. All that remains as a result are the MC registers. This patch moves code to MC file as a result and renames all the variables and defines to use the MC prefix instead of SMMU. The Tegra186 and Tegra194 platform ports are updated to provide the MC context register list to the parent driver. The memory required for context save is reduced due to removal of the SMMU registers. Change-Id: I83a05079039f52f9ce91c938ada6cd6dfd9c843f Signed-off-by: Pritesh Raithatha --- .../tegra/common/drivers/memctrl/memctrl_v2.c | 53 ++ plat/nvidia/tegra/common/drivers/smmu/smmu.c | 64 +- plat/nvidia/tegra/include/drivers/memctrl_v2.h | 43 ++ plat/nvidia/tegra/include/drivers/smmu.h | 815 +-------------------- plat/nvidia/tegra/include/t186/tegra186_private.h | 4 +- plat/nvidia/tegra/include/t186/tegra_def.h | 4 +- plat/nvidia/tegra/include/t194/tegra194_private.h | 2 +- plat/nvidia/tegra/include/t194/tegra_def.h | 4 +- plat/nvidia/tegra/soc/t186/plat_memctrl.c | 166 +++++ plat/nvidia/tegra/soc/t186/plat_psci_handlers.c | 11 +- plat/nvidia/tegra/soc/t186/plat_smmu.c | 166 +---- plat/nvidia/tegra/soc/t186/plat_trampoline.S | 23 +- plat/nvidia/tegra/soc/t194/plat_memctrl.c | 271 ++++++- plat/nvidia/tegra/soc/t194/plat_psci_handlers.c | 11 +- plat/nvidia/tegra/soc/t194/plat_smmu.c | 271 ------- plat/nvidia/tegra/soc/t194/plat_trampoline.S | 21 +- 16 files changed, 578 insertions(+), 1351 deletions(-) diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c index c2ef981ee..a53f66078 100644 --- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c +++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c @@ -21,6 +21,7 @@ #include #include #include +#include /* Video Memory base and size (live values) */ static uint64_t video_mem_base; @@ -223,6 +224,58 @@ void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes) mce_update_gsc_tzram(); } +/* + * Save MC settings before "System Suspend" to TZDRAM + */ +void tegra_mc_save_context(uint64_t mc_ctx_addr) +{ + const tegra_mc_settings_t *plat_mc_settings = tegra_get_mc_settings(); + uint32_t i, num_entries = 0; + mc_regs_t *mc_ctx_regs; + const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); + uint64_t tzdram_base = params_from_bl2->tzdram_base; + uint64_t tzdram_end = tzdram_base + params_from_bl2->tzdram_size; + + assert((mc_ctx_addr >= tzdram_base) && (mc_ctx_addr <= tzdram_end)); + + /* get MC context table */ + mc_ctx_regs = plat_mc_settings->get_mc_system_suspend_ctx(); + assert(mc_ctx_regs != NULL); + + /* + * mc_ctx_regs[0].val contains the size of the context table minus + * the last entry. Sanity check the table size before we start with + * the context save operation. + */ + while (mc_ctx_regs[num_entries].reg != 0xFFFFFFFFU) { + num_entries++; + } + + /* panic if the sizes do not match */ + if (num_entries != mc_ctx_regs[0].val) { + ERROR("MC context size mismatch!"); + panic(); + } + + /* save MC register values */ + for (i = 1U; i < num_entries; i++) { + mc_ctx_regs[i].val = mmio_read_32(mc_ctx_regs[i].reg); + } + + /* increment by 1 to take care of the last entry */ + num_entries++; + + /* Save MC config settings */ + (void)memcpy((void *)mc_ctx_addr, mc_ctx_regs, + sizeof(mc_regs_t) * num_entries); + + /* save the MC table address */ + mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_MC_TABLE_ADDR_LO, + (uint32_t)mc_ctx_addr); + mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_MC_TABLE_ADDR_HI, + (uint32_t)(mc_ctx_addr >> 32)); +} + static void tegra_lock_videomem_nonoverlap(uint64_t phys_base, uint64_t size_in_bytes) { diff --git a/plat/nvidia/tegra/common/drivers/smmu/smmu.c b/plat/nvidia/tegra/common/drivers/smmu/smmu.c index 8c1b899f7..cc07d6549 100644 --- a/plat/nvidia/tegra/common/drivers/smmu/smmu.c +++ b/plat/nvidia/tegra/common/drivers/smmu/smmu.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -71,67 +72,8 @@ static void tegra_smmu_write_32(uint32_t smmu_id, #endif } -/* - * Save SMMU settings before "System Suspend" to TZDRAM - */ -void tegra_smmu_save_context(uint64_t smmu_ctx_addr) -{ - uint32_t i, num_entries = 0; - smmu_regs_t *smmu_ctx_regs; - const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); - uint64_t tzdram_base = params_from_bl2->tzdram_base; - uint64_t tzdram_end = tzdram_base + params_from_bl2->tzdram_size; - uint32_t reg_id1, pgshift, cb_size; - - /* sanity check SMMU settings c*/ - reg_id1 = mmio_read_32((TEGRA_SMMU0_BASE + SMMU_GNSR0_IDR1)); - pgshift = ((reg_id1 & ID1_PAGESIZE) != 0U) ? 16U : 12U; - cb_size = ((uint32_t)2 << pgshift) * \ - ((uint32_t)1 << (((reg_id1 >> ID1_NUMPAGENDXB_SHIFT) & ID1_NUMPAGENDXB_MASK) + 1U)); - - assert(!((pgshift != PGSHIFT) || (cb_size != CB_SIZE))); - assert((smmu_ctx_addr >= tzdram_base) && (smmu_ctx_addr <= tzdram_end)); - - /* get SMMU context table */ - smmu_ctx_regs = plat_get_smmu_ctx(); - assert(smmu_ctx_regs != NULL); - - /* - * smmu_ctx_regs[0].val contains the size of the context table minus - * the last entry. Sanity check the table size before we start with - * the context save operation. - */ - while ((smmu_ctx_regs[num_entries].reg != 0xFFFFFFFFU)) { - num_entries++; - } - - /* panic if the sizes do not match */ - if (num_entries != smmu_ctx_regs[0].val) { - ERROR("SMMU context size mismatch!"); - panic(); - } - - /* save SMMU register values */ - for (i = 1U; i < num_entries; i++) { - smmu_ctx_regs[i].val = mmio_read_32(smmu_ctx_regs[i].reg); - } - - /* increment by 1 to take care of the last entry */ - num_entries++; - - /* Save SMMU config settings */ - (void)memcpy16((uint8_t *)smmu_ctx_addr, (uint8_t *)smmu_ctx_regs, - (sizeof(smmu_regs_t) * num_entries)); - - /* save the SMMU table address */ - mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SMMU_TABLE_ADDR_LO, - (uint32_t)smmu_ctx_addr); - mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SMMU_TABLE_ADDR_HI, - (uint32_t)(smmu_ctx_addr >> 32)); -} - -#define SMMU_NUM_CONTEXTS 64 -#define SMMU_CONTEXT_BANK_MAX_IDX 64 +#define SMMU_NUM_CONTEXTS 64U +#define SMMU_CONTEXT_BANK_MAX_IDX 64U /* * Init SMMU during boot or "System Suspend" exit diff --git a/plat/nvidia/tegra/include/drivers/memctrl_v2.h b/plat/nvidia/tegra/include/drivers/memctrl_v2.h index a4085e247..509fe32bb 100644 --- a/plat/nvidia/tegra/include/drivers/memctrl_v2.h +++ b/plat/nvidia/tegra/include/drivers/memctrl_v2.h @@ -84,6 +84,41 @@ typedef struct mc_streamid_security_cfg { .override_enable = OVERRIDE_ ## access \ } +typedef struct mc_regs { + uint32_t reg; + uint32_t val; +} mc_regs_t; + +#define mc_make_sid_override_cfg(name) \ + { \ + .reg = TEGRA_MC_STREAMID_BASE + MC_STREAMID_OVERRIDE_CFG_ ## name, \ + .val = 0x00000000U, \ + } + +#define mc_make_sid_security_cfg(name) \ + { \ + .reg = TEGRA_MC_STREAMID_BASE + MC_STREAMID_OVERRIDE_TO_SECURITY_CFG(MC_STREAMID_OVERRIDE_CFG_ ## name), \ + .val = 0x00000000U, \ + } + +#define mc_smmu_bypass_cfg \ + { \ + .reg = TEGRA_MC_BASE + MC_SMMU_BYPASS_CONFIG, \ + .val = 0x00000000U, \ + } + +#define _START_OF_TABLE_ \ + { \ + .reg = 0xCAFE05C7U, \ + .val = 0x00000000U, \ + } + +#define _END_OF_TABLE_ \ + { \ + .reg = 0xFFFFFFFFU, \ + .val = 0xFFFFFFFFU, \ + } + /******************************************************************************* * Structure to hold Memory Controller's Configuration settings ******************************************************************************/ @@ -96,6 +131,7 @@ typedef struct tegra_mc_settings { uint32_t num_txn_override_cfgs; void (*reconfig_mss_clients)(void); void (*set_txn_overrides)(void); + mc_regs_t* (*get_mc_system_suspend_ctx)(void); } tegra_mc_settings_t; static inline uint32_t tegra_mc_read_32(uint32_t off) @@ -165,6 +201,13 @@ static inline void tegra_mc_streamid_write_32(uint32_t off, uint32_t val) ******************************************************************************/ tegra_mc_settings_t *tegra_get_mc_settings(void); +/******************************************************************************* + * Handler to save MC settings before "System Suspend" to TZDRAM + * + * Implemented by Tegra common memctrl_v2 driver under common/drivers/memctrl + ******************************************************************************/ +void tegra_mc_save_context(uint64_t mc_ctx_addr); + /******************************************************************************* * Handler to program the scratch registers with TZDRAM settings for the * resume firmware. diff --git a/plat/nvidia/tegra/include/drivers/smmu.h b/plat/nvidia/tegra/include/drivers/smmu.h index 424a91aea..417208e3c 100644 --- a/plat/nvidia/tegra/include/drivers/smmu.h +++ b/plat/nvidia/tegra/include/drivers/smmu.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -12,566 +13,7 @@ #include #include -/******************************************************************************* - * SMMU Register constants - ******************************************************************************/ -#define SMMU_CBn_SCTLR (0x0U) -#define SMMU_CBn_SCTLR_STAGE2 (0x0U) #define SMMU_CBn_ACTLR (0x4U) -#define SMMU_CBn_RESUME (0x8U) -#define SMMU_CBn_TCR2 (0x10U) -#define SMMU_CBn_TTBR0_LO (0x20U) -#define SMMU_CBn_TTBR0_HI (0x24U) -#define SMMU_CBn_TTBR1_LO (0x28U) -#define SMMU_CBn_TTBR1_HI (0x2cU) -#define SMMU_CBn_TCR_LPAE (0x30U) -#define SMMU_CBn_TCR (0x30U) -#define SMMU_CBn_TCR_EAE_1 (0x30U) -#define SMMU_CBn_TCR (0x30U) -#define SMMU_CBn_CONTEXTIDR (0x34U) -#define SMMU_CBn_CONTEXTIDR_EAE_1 (0x34U) -#define SMMU_CBn_PRRR_MAIR0 (0x38U) -#define SMMU_CBn_NMRR_MAIR1 (0x3cU) -#define SMMU_CBn_SMMU_CBn_PAR (0x50U) -#define SMMU_CBn_SMMU_CBn_PAR0 (0x50U) -#define SMMU_CBn_SMMU_CBn_PAR1 (0x54U) -/* SMMU_CBn_SMMU_CBn_PAR0_Fault (0x50U) */ -/* SMMU_CBn_SMMU_CBn_PAR0_Fault (0x54U) */ -#define SMMU_CBn_FSR (0x58U) -#define SMMU_CBn_FSRRESTORE (0x5cU) -#define SMMU_CBn_FAR_LO (0x60U) -#define SMMU_CBn_FAR_HI (0x64U) -#define SMMU_CBn_FSYNR0 (0x68U) -#define SMMU_CBn_IPAFAR_LO (0x70U) -#define SMMU_CBn_IPAFAR_HI (0x74U) -#define SMMU_CBn_TLBIVA_LO (0x600U) -#define SMMU_CBn_TLBIVA_HI (0x604U) -#define SMMU_CBn_TLBIVA_AARCH_32 (0x600U) -#define SMMU_CBn_TLBIVAA_LO (0x608U) -#define SMMU_CBn_TLBIVAA_HI (0x60cU) -#define SMMU_CBn_TLBIVAA_AARCH_32 (0x608U) -#define SMMU_CBn_TLBIASID (0x610U) -#define SMMU_CBn_TLBIALL (0x618U) -#define SMMU_CBn_TLBIVAL_LO (0x620U) -#define SMMU_CBn_TLBIVAL_HI (0x624U) -#define SMMU_CBn_TLBIVAL_AARCH_32 (0x618U) -#define SMMU_CBn_TLBIVAAL_LO (0x628U) -#define SMMU_CBn_TLBIVAAL_HI (0x62cU) -#define SMMU_CBn_TLBIVAAL_AARCH_32 (0x628U) -#define SMMU_CBn_TLBIIPAS2_LO (0x630U) -#define SMMU_CBn_TLBIIPAS2_HI (0x634U) -#define SMMU_CBn_TLBIIPAS2L_LO (0x638U) -#define SMMU_CBn_TLBIIPAS2L_HI (0x63cU) -#define SMMU_CBn_TLBSYNC (0x7f0U) -#define SMMU_CBn_TLBSTATUS (0x7f4U) -#define SMMU_CBn_ATSR (0x800U) -#define SMMU_CBn_PMEVCNTR0 (0xe00U) -#define SMMU_CBn_PMEVCNTR1 (0xe04U) -#define SMMU_CBn_PMEVCNTR2 (0xe08U) -#define SMMU_CBn_PMEVCNTR3 (0xe0cU) -#define SMMU_CBn_PMEVTYPER0 (0xe80U) -#define SMMU_CBn_PMEVTYPER1 (0xe84U) -#define SMMU_CBn_PMEVTYPER2 (0xe88U) -#define SMMU_CBn_PMEVTYPER3 (0xe8cU) -#define SMMU_CBn_PMCFGR (0xf00U) -#define SMMU_CBn_PMCR (0xf04U) -#define SMMU_CBn_PMCEID (0xf20U) -#define SMMU_CBn_PMCNTENSE (0xf40U) -#define SMMU_CBn_PMCNTENCLR (0xf44U) -#define SMMU_CBn_PMCNTENSET (0xf48U) -#define SMMU_CBn_PMINTENCLR (0xf4cU) -#define SMMU_CBn_PMOVSCLR (0xf50U) -#define SMMU_CBn_PMOVSSET (0xf58U) -#define SMMU_CBn_PMAUTHSTATUS (0xfb8U) -#define SMMU_GNSR0_CR0 (0x0U) -#define SMMU_GNSR0_CR2 (0x8U) -#define SMMU_GNSR0_ACR (0x10U) -#define SMMU_GNSR0_IDR0 (0x20U) -#define SMMU_GNSR0_IDR1 (0x24U) -#define SMMU_GNSR0_IDR2 (0x28U) -#define SMMU_GNSR0_IDR7 (0x3cU) -#define SMMU_GNSR0_GFAR_LO (0x40U) -#define SMMU_GNSR0_GFAR_HI (0x44U) -#define SMMU_GNSR0_GFSR (0x48U) -#define SMMU_GNSR0_GFSRRESTORE (0x4cU) -#define SMMU_GNSR0_GFSYNR0 (0x50U) -#define SMMU_GNSR0_GFSYNR1 (0x54U) -#define SMMU_GNSR0_GFSYNR1_v2 (0x54U) -#define SMMU_GNSR0_TLBIVMID (0x64U) -#define SMMU_GNSR0_TLBIALLNSNH (0x68U) -#define SMMU_GNSR0_TLBIALLH (0x6cU) -#define SMMU_GNSR0_TLBGSYNC (0x70U) -#define SMMU_GNSR0_TLBGSTATUS (0x74U) -#define SMMU_GNSR0_TLBIVAH_LO (0x78U) -#define SMMU_GNSR0_TLBIVALH64_LO (0xb0U) -#define SMMU_GNSR0_TLBIVALH64_HI (0xb4U) -#define SMMU_GNSR0_TLBIVMIDS1 (0xb8U) -#define SMMU_GNSR0_TLBIVAH64_LO (0xc0U) -#define SMMU_GNSR0_TLBIVAH64_HI (0xc4U) -#define SMMU_GNSR0_SMR0 (0x800U) -#define SMMU_GNSR0_SMRn (0x800U) -#define SMMU_GNSR0_SMR1 (0x804U) -#define SMMU_GNSR0_SMR2 (0x808U) -#define SMMU_GNSR0_SMR3 (0x80cU) -#define SMMU_GNSR0_SMR4 (0x810U) -#define SMMU_GNSR0_SMR5 (0x814U) -#define SMMU_GNSR0_SMR6 (0x818U) -#define SMMU_GNSR0_SMR7 (0x81cU) -#define SMMU_GNSR0_SMR8 (0x820U) -#define SMMU_GNSR0_SMR9 (0x824U) -#define SMMU_GNSR0_SMR10 (0x828U) -#define SMMU_GNSR0_SMR11 (0x82cU) -#define SMMU_GNSR0_SMR12 (0x830U) -#define SMMU_GNSR0_SMR13 (0x834U) -#define SMMU_GNSR0_SMR14 (0x838U) -#define SMMU_GNSR0_SMR15 (0x83cU) -#define SMMU_GNSR0_SMR16 (0x840U) -#define SMMU_GNSR0_SMR17 (0x844U) -#define SMMU_GNSR0_SMR18 (0x848U) -#define SMMU_GNSR0_SMR19 (0x84cU) -#define SMMU_GNSR0_SMR20 (0x850U) -#define SMMU_GNSR0_SMR21 (0x854U) -#define SMMU_GNSR0_SMR22 (0x858U) -#define SMMU_GNSR0_SMR23 (0x85cU) -#define SMMU_GNSR0_SMR24 (0x860U) -#define SMMU_GNSR0_SMR25 (0x864U) -#define SMMU_GNSR0_SMR26 (0x868U) -#define SMMU_GNSR0_SMR27 (0x86cU) -#define SMMU_GNSR0_SMR28 (0x870U) -#define SMMU_GNSR0_SMR29 (0x874U) -#define SMMU_GNSR0_SMR30 (0x878U) -#define SMMU_GNSR0_SMR31 (0x87cU) -#define SMMU_GNSR0_SMR32 (0x880U) -#define SMMU_GNSR0_SMR33 (0x884U) -#define SMMU_GNSR0_SMR34 (0x888U) -#define SMMU_GNSR0_SMR35 (0x88cU) -#define SMMU_GNSR0_SMR36 (0x890U) -#define SMMU_GNSR0_SMR37 (0x894U) -#define SMMU_GNSR0_SMR38 (0x898U) -#define SMMU_GNSR0_SMR39 (0x89cU) -#define SMMU_GNSR0_SMR40 (0x8a0U) -#define SMMU_GNSR0_SMR41 (0x8a4U) -#define SMMU_GNSR0_SMR42 (0x8a8U) -#define SMMU_GNSR0_SMR43 (0x8acU) -#define SMMU_GNSR0_SMR44 (0x8b0U) -#define SMMU_GNSR0_SMR45 (0x8b4U) -#define SMMU_GNSR0_SMR46 (0x8b8U) -#define SMMU_GNSR0_SMR47 (0x8bcU) -#define SMMU_GNSR0_SMR48 (0x8c0U) -#define SMMU_GNSR0_SMR49 (0x8c4U) -#define SMMU_GNSR0_SMR50 (0x8c8U) -#define SMMU_GNSR0_SMR51 (0x8ccU) -#define SMMU_GNSR0_SMR52 (0x8d0U) -#define SMMU_GNSR0_SMR53 (0x8d4U) -#define SMMU_GNSR0_SMR54 (0x8d8U) -#define SMMU_GNSR0_SMR55 (0x8dcU) -#define SMMU_GNSR0_SMR56 (0x8e0U) -#define SMMU_GNSR0_SMR57 (0x8e4U) -#define SMMU_GNSR0_SMR58 (0x8e8U) -#define SMMU_GNSR0_SMR59 (0x8ecU) -#define SMMU_GNSR0_SMR60 (0x8f0U) -#define SMMU_GNSR0_SMR61 (0x8f4U) -#define SMMU_GNSR0_SMR62 (0x8f8U) -#define SMMU_GNSR0_SMR63 (0x8fcU) -#define SMMU_GNSR0_SMR64 (0x900U) -#define SMMU_GNSR0_SMR65 (0x904U) -#define SMMU_GNSR0_SMR66 (0x908U) -#define SMMU_GNSR0_SMR67 (0x90cU) -#define SMMU_GNSR0_SMR68 (0x910U) -#define SMMU_GNSR0_SMR69 (0x914U) -#define SMMU_GNSR0_SMR70 (0x918U) -#define SMMU_GNSR0_SMR71 (0x91cU) -#define SMMU_GNSR0_SMR72 (0x920U) -#define SMMU_GNSR0_SMR73 (0x924U) -#define SMMU_GNSR0_SMR74 (0x928U) -#define SMMU_GNSR0_SMR75 (0x92cU) -#define SMMU_GNSR0_SMR76 (0x930U) -#define SMMU_GNSR0_SMR77 (0x934U) -#define SMMU_GNSR0_SMR78 (0x938U) -#define SMMU_GNSR0_SMR79 (0x93cU) -#define SMMU_GNSR0_SMR80 (0x940U) -#define SMMU_GNSR0_SMR81 (0x944U) -#define SMMU_GNSR0_SMR82 (0x948U) -#define SMMU_GNSR0_SMR83 (0x94cU) -#define SMMU_GNSR0_SMR84 (0x950U) -#define SMMU_GNSR0_SMR85 (0x954U) -#define SMMU_GNSR0_SMR86 (0x958U) -#define SMMU_GNSR0_SMR87 (0x95cU) -#define SMMU_GNSR0_SMR88 (0x960U) -#define SMMU_GNSR0_SMR89 (0x964U) -#define SMMU_GNSR0_SMR90 (0x968U) -#define SMMU_GNSR0_SMR91 (0x96cU) -#define SMMU_GNSR0_SMR92 (0x970U) -#define SMMU_GNSR0_SMR93 (0x974U) -#define SMMU_GNSR0_SMR94 (0x978U) -#define SMMU_GNSR0_SMR95 (0x97cU) -#define SMMU_GNSR0_SMR96 (0x980U) -#define SMMU_GNSR0_SMR97 (0x984U) -#define SMMU_GNSR0_SMR98 (0x988U) -#define SMMU_GNSR0_SMR99 (0x98cU) -#define SMMU_GNSR0_SMR100 (0x990U) -#define SMMU_GNSR0_SMR101 (0x994U) -#define SMMU_GNSR0_SMR102 (0x998U) -#define SMMU_GNSR0_SMR103 (0x99cU) -#define SMMU_GNSR0_SMR104 (0x9a0U) -#define SMMU_GNSR0_SMR105 (0x9a4U) -#define SMMU_GNSR0_SMR106 (0x9a8U) -#define SMMU_GNSR0_SMR107 (0x9acU) -#define SMMU_GNSR0_SMR108 (0x9b0U) -#define SMMU_GNSR0_SMR109 (0x9b4U) -#define SMMU_GNSR0_SMR110 (0x9b8U) -#define SMMU_GNSR0_SMR111 (0x9bcU) -#define SMMU_GNSR0_SMR112 (0x9c0U) -#define SMMU_GNSR0_SMR113 (0x9c4U) -#define SMMU_GNSR0_SMR114 (0x9c8U) -#define SMMU_GNSR0_SMR115 (0x9ccU) -#define SMMU_GNSR0_SMR116 (0x9d0U) -#define SMMU_GNSR0_SMR117 (0x9d4U) -#define SMMU_GNSR0_SMR118 (0x9d8U) -#define SMMU_GNSR0_SMR119 (0x9dcU) -#define SMMU_GNSR0_SMR120 (0x9e0U) -#define SMMU_GNSR0_SMR121 (0x9e4U) -#define SMMU_GNSR0_SMR122 (0x9e8U) -#define SMMU_GNSR0_SMR123 (0x9ecU) -#define SMMU_GNSR0_SMR124 (0x9f0U) -#define SMMU_GNSR0_SMR125 (0x9f4U) -#define SMMU_GNSR0_SMR126 (0x9f8U) -#define SMMU_GNSR0_SMR127 (0x9fcU) -#define SMMU_GNSR0_S2CR0 (0xc00U) -#define SMMU_GNSR0_S2CRn (0xc00U) -#define SMMU_GNSR0_S2CRn (0xc00U) -#define SMMU_GNSR0_S2CR1 (0xc04U) -#define SMMU_GNSR0_S2CR2 (0xc08U) -#define SMMU_GNSR0_S2CR3 (0xc0cU) -#define SMMU_GNSR0_S2CR4 (0xc10U) -#define SMMU_GNSR0_S2CR5 (0xc14U) -#define SMMU_GNSR0_S2CR6 (0xc18U) -#define SMMU_GNSR0_S2CR7 (0xc1cU) -#define SMMU_GNSR0_S2CR8 (0xc20U) -#define SMMU_GNSR0_S2CR9 (0xc24U) -#define SMMU_GNSR0_S2CR10 (0xc28U) -#define SMMU_GNSR0_S2CR11 (0xc2cU) -#define SMMU_GNSR0_S2CR12 (0xc30U) -#define SMMU_GNSR0_S2CR13 (0xc34U) -#define SMMU_GNSR0_S2CR14 (0xc38U) -#define SMMU_GNSR0_S2CR15 (0xc3cU) -#define SMMU_GNSR0_S2CR16 (0xc40U) -#define SMMU_GNSR0_S2CR17 (0xc44U) -#define SMMU_GNSR0_S2CR18 (0xc48U) -#define SMMU_GNSR0_S2CR19 (0xc4cU) -#define SMMU_GNSR0_S2CR20 (0xc50U) -#define SMMU_GNSR0_S2CR21 (0xc54U) -#define SMMU_GNSR0_S2CR22 (0xc58U) -#define SMMU_GNSR0_S2CR23 (0xc5cU) -#define SMMU_GNSR0_S2CR24 (0xc60U) -#define SMMU_GNSR0_S2CR25 (0xc64U) -#define SMMU_GNSR0_S2CR26 (0xc68U) -#define SMMU_GNSR0_S2CR27 (0xc6cU) -#define SMMU_GNSR0_S2CR28 (0xc70U) -#define SMMU_GNSR0_S2CR29 (0xc74U) -#define SMMU_GNSR0_S2CR30 (0xc78U) -#define SMMU_GNSR0_S2CR31 (0xc7cU) -#define SMMU_GNSR0_S2CR32 (0xc80U) -#define SMMU_GNSR0_S2CR33 (0xc84U) -#define SMMU_GNSR0_S2CR34 (0xc88U) -#define SMMU_GNSR0_S2CR35 (0xc8cU) -#define SMMU_GNSR0_S2CR36 (0xc90U) -#define SMMU_GNSR0_S2CR37 (0xc94U) -#define SMMU_GNSR0_S2CR38 (0xc98U) -#define SMMU_GNSR0_S2CR39 (0xc9cU) -#define SMMU_GNSR0_S2CR40 (0xca0U) -#define SMMU_GNSR0_S2CR41 (0xca4U) -#define SMMU_GNSR0_S2CR42 (0xca8U) -#define SMMU_GNSR0_S2CR43 (0xcacU) -#define SMMU_GNSR0_S2CR44 (0xcb0U) -#define SMMU_GNSR0_S2CR45 (0xcb4U) -#define SMMU_GNSR0_S2CR46 (0xcb8U) -#define SMMU_GNSR0_S2CR47 (0xcbcU) -#define SMMU_GNSR0_S2CR48 (0xcc0U) -#define SMMU_GNSR0_S2CR49 (0xcc4U) -#define SMMU_GNSR0_S2CR50 (0xcc8U) -#define SMMU_GNSR0_S2CR51 (0xcccU) -#define SMMU_GNSR0_S2CR52 (0xcd0U) -#define SMMU_GNSR0_S2CR53 (0xcd4U) -#define SMMU_GNSR0_S2CR54 (0xcd8U) -#define SMMU_GNSR0_S2CR55 (0xcdcU) -#define SMMU_GNSR0_S2CR56 (0xce0U) -#define SMMU_GNSR0_S2CR57 (0xce4U) -#define SMMU_GNSR0_S2CR58 (0xce8U) -#define SMMU_GNSR0_S2CR59 (0xcecU) -#define SMMU_GNSR0_S2CR60 (0xcf0U) -#define SMMU_GNSR0_S2CR61 (0xcf4U) -#define SMMU_GNSR0_S2CR62 (0xcf8U) -#define SMMU_GNSR0_S2CR63 (0xcfcU) -#define SMMU_GNSR0_S2CR64 (0xd00U) -#define SMMU_GNSR0_S2CR65 (0xd04U) -#define SMMU_GNSR0_S2CR66 (0xd08U) -#define SMMU_GNSR0_S2CR67 (0xd0cU) -#define SMMU_GNSR0_S2CR68 (0xd10U) -#define SMMU_GNSR0_S2CR69 (0xd14U) -#define SMMU_GNSR0_S2CR70 (0xd18U) -#define SMMU_GNSR0_S2CR71 (0xd1cU) -#define SMMU_GNSR0_S2CR72 (0xd20U) -#define SMMU_GNSR0_S2CR73 (0xd24U) -#define SMMU_GNSR0_S2CR74 (0xd28U) -#define SMMU_GNSR0_S2CR75 (0xd2cU) -#define SMMU_GNSR0_S2CR76 (0xd30U) -#define SMMU_GNSR0_S2CR77 (0xd34U) -#define SMMU_GNSR0_S2CR78 (0xd38U) -#define SMMU_GNSR0_S2CR79 (0xd3cU) -#define SMMU_GNSR0_S2CR80 (0xd40U) -#define SMMU_GNSR0_S2CR81 (0xd44U) -#define SMMU_GNSR0_S2CR82 (0xd48U) -#define SMMU_GNSR0_S2CR83 (0xd4cU) -#define SMMU_GNSR0_S2CR84 (0xd50U) -#define SMMU_GNSR0_S2CR85 (0xd54U) -#define SMMU_GNSR0_S2CR86 (0xd58U) -#define SMMU_GNSR0_S2CR87 (0xd5cU) -#define SMMU_GNSR0_S2CR88 (0xd60U) -#define SMMU_GNSR0_S2CR89 (0xd64U) -#define SMMU_GNSR0_S2CR90 (0xd68U) -#define SMMU_GNSR0_S2CR91 (0xd6cU) -#define SMMU_GNSR0_S2CR92 (0xd70U) -#define SMMU_GNSR0_S2CR93 (0xd74U) -#define SMMU_GNSR0_S2CR94 (0xd78U) -#define SMMU_GNSR0_S2CR95 (0xd7cU) -#define SMMU_GNSR0_S2CR96 (0xd80U) -#define SMMU_GNSR0_S2CR97 (0xd84U) -#define SMMU_GNSR0_S2CR98 (0xd88U) -#define SMMU_GNSR0_S2CR99 (0xd8cU) -#define SMMU_GNSR0_S2CR100 (0xd90U) -#define SMMU_GNSR0_S2CR101 (0xd94U) -#define SMMU_GNSR0_S2CR102 (0xd98U) -#define SMMU_GNSR0_S2CR103 (0xd9cU) -#define SMMU_GNSR0_S2CR104 (0xda0U) -#define SMMU_GNSR0_S2CR105 (0xda4U) -#define SMMU_GNSR0_S2CR106 (0xda8U) -#define SMMU_GNSR0_S2CR107 (0xdacU) -#define SMMU_GNSR0_S2CR108 (0xdb0U) -#define SMMU_GNSR0_S2CR109 (0xdb4U) -#define SMMU_GNSR0_S2CR110 (0xdb8U) -#define SMMU_GNSR0_S2CR111 (0xdbcU) -#define SMMU_GNSR0_S2CR112 (0xdc0U) -#define SMMU_GNSR0_S2CR113 (0xdc4U) -#define SMMU_GNSR0_S2CR114 (0xdc8U) -#define SMMU_GNSR0_S2CR115 (0xdccU) -#define SMMU_GNSR0_S2CR116 (0xdd0U) -#define SMMU_GNSR0_S2CR117 (0xdd4U) -#define SMMU_GNSR0_S2CR118 (0xdd8U) -#define SMMU_GNSR0_S2CR119 (0xddcU) -#define SMMU_GNSR0_S2CR120 (0xde0U) -#define SMMU_GNSR0_S2CR121 (0xde4U) -#define SMMU_GNSR0_S2CR122 (0xde8U) -#define SMMU_GNSR0_S2CR123 (0xdecU) -#define SMMU_GNSR0_S2CR124 (0xdf0U) -#define SMMU_GNSR0_S2CR125 (0xdf4U) -#define SMMU_GNSR0_S2CR126 (0xdf8U) -#define SMMU_GNSR0_S2CR127 (0xdfcU) -#define SMMU_GNSR0_PIDR0 (0xfe0U) -#define SMMU_GNSR0_PIDR1 (0xfe4U) -#define SMMU_GNSR0_PIDR2 (0xfe8U) -#define SMMU_GNSR0_PIDR3 (0xfecU) -#define SMMU_GNSR0_PIDR4 (0xfd0U) -#define SMMU_GNSR0_PIDR5 (0xfd4U) -#define SMMU_GNSR0_PIDR6 (0xfd8U) -#define SMMU_GNSR0_PIDR7 (0xfdcU) -#define SMMU_GNSR0_CIDR0 (0xff0U) -#define SMMU_GNSR0_CIDR1 (0xff4U) -#define SMMU_GNSR0_CIDR2 (0xff8U) -#define SMMU_GNSR0_CIDR3 (0xffcU) -#define SMMU_GNSR1_CBAR0 (0x0U) -#define SMMU_GNSR1_CBARn (0x0U) -#define SMMU_GNSR1_CBFRSYNRA0 (0x400U) -#define SMMU_GNSR1_CBA2R0 (0x800U) -#define SMMU_GNSR1_CBAR1 (0x4U) -#define SMMU_GNSR1_CBFRSYNRA1 (0x404U) -#define SMMU_GNSR1_CBA2R1 (0x804U) -#define SMMU_GNSR1_CBAR2 (0x8U) -#define SMMU_GNSR1_CBFRSYNRA2 (0x408U) -#define SMMU_GNSR1_CBA2R2 (0x808U) -#define SMMU_GNSR1_CBAR3 (0xcU) -#define SMMU_GNSR1_CBFRSYNRA3 (0x40cU) -#define SMMU_GNSR1_CBA2R3 (0x80cU) -#define SMMU_GNSR1_CBAR4 (0x10U) -#define SMMU_GNSR1_CBFRSYNRA4 (0x410U) -#define SMMU_GNSR1_CBA2R4 (0x810U) -#define SMMU_GNSR1_CBAR5 (0x14U) -#define SMMU_GNSR1_CBFRSYNRA5 (0x414U) -#define SMMU_GNSR1_CBA2R5 (0x814U) -#define SMMU_GNSR1_CBAR6 (0x18U) -#define SMMU_GNSR1_CBFRSYNRA6 (0x418U) -#define SMMU_GNSR1_CBA2R6 (0x818U) -#define SMMU_GNSR1_CBAR7 (0x1cU) -#define SMMU_GNSR1_CBFRSYNRA7 (0x41cU) -#define SMMU_GNSR1_CBA2R7 (0x81cU) -#define SMMU_GNSR1_CBAR8 (0x20U) -#define SMMU_GNSR1_CBFRSYNRA8 (0x420U) -#define SMMU_GNSR1_CBA2R8 (0x820U) -#define SMMU_GNSR1_CBAR9 (0x24U) -#define SMMU_GNSR1_CBFRSYNRA9 (0x424U) -#define SMMU_GNSR1_CBA2R9 (0x824U) -#define SMMU_GNSR1_CBAR10 (0x28U) -#define SMMU_GNSR1_CBFRSYNRA10 (0x428U) -#define SMMU_GNSR1_CBA2R10 (0x828U) -#define SMMU_GNSR1_CBAR11 (0x2cU) -#define SMMU_GNSR1_CBFRSYNRA11 (0x42cU) -#define SMMU_GNSR1_CBA2R11 (0x82cU) -#define SMMU_GNSR1_CBAR12 (0x30U) -#define SMMU_GNSR1_CBFRSYNRA12 (0x430U) -#define SMMU_GNSR1_CBA2R12 (0x830U) -#define SMMU_GNSR1_CBAR13 (0x34U) -#define SMMU_GNSR1_CBFRSYNRA13 (0x434U) -#define SMMU_GNSR1_CBA2R13 (0x834U) -#define SMMU_GNSR1_CBAR14 (0x38U) -#define SMMU_GNSR1_CBFRSYNRA14 (0x438U) -#define SMMU_GNSR1_CBA2R14 (0x838U) -#define SMMU_GNSR1_CBAR15 (0x3cU) -#define SMMU_GNSR1_CBFRSYNRA15 (0x43cU) -#define SMMU_GNSR1_CBA2R15 (0x83cU) -#define SMMU_GNSR1_CBAR16 (0x40U) -#define SMMU_GNSR1_CBFRSYNRA16 (0x440U) -#define SMMU_GNSR1_CBA2R16 (0x840U) -#define SMMU_GNSR1_CBAR17 (0x44U) -#define SMMU_GNSR1_CBFRSYNRA17 (0x444U) -#define SMMU_GNSR1_CBA2R17 (0x844U) -#define SMMU_GNSR1_CBAR18 (0x48U) -#define SMMU_GNSR1_CBFRSYNRA18 (0x448U) -#define SMMU_GNSR1_CBA2R18 (0x848U) -#define SMMU_GNSR1_CBAR19 (0x4cU) -#define SMMU_GNSR1_CBFRSYNRA19 (0x44cU) -#define SMMU_GNSR1_CBA2R19 (0x84cU) -#define SMMU_GNSR1_CBAR20 (0x50U) -#define SMMU_GNSR1_CBFRSYNRA20 (0x450U) -#define SMMU_GNSR1_CBA2R20 (0x850U) -#define SMMU_GNSR1_CBAR21 (0x54U) -#define SMMU_GNSR1_CBFRSYNRA21 (0x454U) -#define SMMU_GNSR1_CBA2R21 (0x854U) -#define SMMU_GNSR1_CBAR22 (0x58U) -#define SMMU_GNSR1_CBFRSYNRA22 (0x458U) -#define SMMU_GNSR1_CBA2R22 (0x858U) -#define SMMU_GNSR1_CBAR23 (0x5cU) -#define SMMU_GNSR1_CBFRSYNRA23 (0x45cU) -#define SMMU_GNSR1_CBA2R23 (0x85cU) -#define SMMU_GNSR1_CBAR24 (0x60U) -#define SMMU_GNSR1_CBFRSYNRA24 (0x460U) -#define SMMU_GNSR1_CBA2R24 (0x860U) -#define SMMU_GNSR1_CBAR25 (0x64U) -#define SMMU_GNSR1_CBFRSYNRA25 (0x464U) -#define SMMU_GNSR1_CBA2R25 (0x864U) -#define SMMU_GNSR1_CBAR26 (0x68U) -#define SMMU_GNSR1_CBFRSYNRA26 (0x468U) -#define SMMU_GNSR1_CBA2R26 (0x868U) -#define SMMU_GNSR1_CBAR27 (0x6cU) -#define SMMU_GNSR1_CBFRSYNRA27 (0x46cU) -#define SMMU_GNSR1_CBA2R27 (0x86cU) -#define SMMU_GNSR1_CBAR28 (0x70U) -#define SMMU_GNSR1_CBFRSYNRA28 (0x470U) -#define SMMU_GNSR1_CBA2R28 (0x870U) -#define SMMU_GNSR1_CBAR29 (0x74U) -#define SMMU_GNSR1_CBFRSYNRA29 (0x474U) -#define SMMU_GNSR1_CBA2R29 (0x874U) -#define SMMU_GNSR1_CBAR30 (0x78U) -#define SMMU_GNSR1_CBFRSYNRA30 (0x478U) -#define SMMU_GNSR1_CBA2R30 (0x878U) -#define SMMU_GNSR1_CBAR31 (0x7cU) -#define SMMU_GNSR1_CBFRSYNRA31 (0x47cU) -#define SMMU_GNSR1_CBA2R31 (0x87cU) -#define SMMU_GNSR1_CBAR32 (0x80U) -#define SMMU_GNSR1_CBFRSYNRA32 (0x480U) -#define SMMU_GNSR1_CBA2R32 (0x880U) -#define SMMU_GNSR1_CBAR33 (0x84U) -#define SMMU_GNSR1_CBFRSYNRA33 (0x484U) -#define SMMU_GNSR1_CBA2R33 (0x884U) -#define SMMU_GNSR1_CBAR34 (0x88U) -#define SMMU_GNSR1_CBFRSYNRA34 (0x488U) -#define SMMU_GNSR1_CBA2R34 (0x888U) -#define SMMU_GNSR1_CBAR35 (0x8cU) -#define SMMU_GNSR1_CBFRSYNRA35 (0x48cU) -#define SMMU_GNSR1_CBA2R35 (0x88cU) -#define SMMU_GNSR1_CBAR36 (0x90U) -#define SMMU_GNSR1_CBFRSYNRA36 (0x490U) -#define SMMU_GNSR1_CBA2R36 (0x890U) -#define SMMU_GNSR1_CBAR37 (0x94U) -#define SMMU_GNSR1_CBFRSYNRA37 (0x494U) -#define SMMU_GNSR1_CBA2R37 (0x894U) -#define SMMU_GNSR1_CBAR38 (0x98U) -#define SMMU_GNSR1_CBFRSYNRA38 (0x498U) -#define SMMU_GNSR1_CBA2R38 (0x898U) -#define SMMU_GNSR1_CBAR39 (0x9cU) -#define SMMU_GNSR1_CBFRSYNRA39 (0x49cU) -#define SMMU_GNSR1_CBA2R39 (0x89cU) -#define SMMU_GNSR1_CBAR40 (0xa0U) -#define SMMU_GNSR1_CBFRSYNRA40 (0x4a0U) -#define SMMU_GNSR1_CBA2R40 (0x8a0U) -#define SMMU_GNSR1_CBAR41 (0xa4U) -#define SMMU_GNSR1_CBFRSYNRA41 (0x4a4U) -#define SMMU_GNSR1_CBA2R41 (0x8a4U) -#define SMMU_GNSR1_CBAR42 (0xa8U) -#define SMMU_GNSR1_CBFRSYNRA42 (0x4a8U) -#define SMMU_GNSR1_CBA2R42 (0x8a8U) -#define SMMU_GNSR1_CBAR43 (0xacU) -#define SMMU_GNSR1_CBFRSYNRA43 (0x4acU) -#define SMMU_GNSR1_CBA2R43 (0x8acU) -#define SMMU_GNSR1_CBAR44 (0xb0U) -#define SMMU_GNSR1_CBFRSYNRA44 (0x4b0U) -#define SMMU_GNSR1_CBA2R44 (0x8b0U) -#define SMMU_GNSR1_CBAR45 (0xb4U) -#define SMMU_GNSR1_CBFRSYNRA45 (0x4b4U) -#define SMMU_GNSR1_CBA2R45 (0x8b4U) -#define SMMU_GNSR1_CBAR46 (0xb8U) -#define SMMU_GNSR1_CBFRSYNRA46 (0x4b8U) -#define SMMU_GNSR1_CBA2R46 (0x8b8U) -#define SMMU_GNSR1_CBAR47 (0xbcU) -#define SMMU_GNSR1_CBFRSYNRA47 (0x4bcU) -#define SMMU_GNSR1_CBA2R47 (0x8bcU) -#define SMMU_GNSR1_CBAR48 (0xc0U) -#define SMMU_GNSR1_CBFRSYNRA48 (0x4c0U) -#define SMMU_GNSR1_CBA2R48 (0x8c0U) -#define SMMU_GNSR1_CBAR49 (0xc4U) -#define SMMU_GNSR1_CBFRSYNRA49 (0x4c4U) -#define SMMU_GNSR1_CBA2R49 (0x8c4U) -#define SMMU_GNSR1_CBAR50 (0xc8U) -#define SMMU_GNSR1_CBFRSYNRA50 (0x4c8U) -#define SMMU_GNSR1_CBA2R50 (0x8c8U) -#define SMMU_GNSR1_CBAR51 (0xccU) -#define SMMU_GNSR1_CBFRSYNRA51 (0x4ccU) -#define SMMU_GNSR1_CBA2R51 (0x8ccU) -#define SMMU_GNSR1_CBAR52 (0xd0U) -#define SMMU_GNSR1_CBFRSYNRA52 (0x4d0U) -#define SMMU_GNSR1_CBA2R52 (0x8d0U) -#define SMMU_GNSR1_CBAR53 (0xd4U) -#define SMMU_GNSR1_CBFRSYNRA53 (0x4d4U) -#define SMMU_GNSR1_CBA2R53 (0x8d4U) -#define SMMU_GNSR1_CBAR54 (0xd8U) -#define SMMU_GNSR1_CBFRSYNRA54 (0x4d8U) -#define SMMU_GNSR1_CBA2R54 (0x8d8U) -#define SMMU_GNSR1_CBAR55 (0xdcU) -#define SMMU_GNSR1_CBFRSYNRA55 (0x4dcU) -#define SMMU_GNSR1_CBA2R55 (0x8dcU) -#define SMMU_GNSR1_CBAR56 (0xe0U) -#define SMMU_GNSR1_CBFRSYNRA56 (0x4e0U) -#define SMMU_GNSR1_CBA2R56 (0x8e0U) -#define SMMU_GNSR1_CBAR57 (0xe4U) -#define SMMU_GNSR1_CBFRSYNRA57 (0x4e4U) -#define SMMU_GNSR1_CBA2R57 (0x8e4U) -#define SMMU_GNSR1_CBAR58 (0xe8U) -#define SMMU_GNSR1_CBFRSYNRA58 (0x4e8U) -#define SMMU_GNSR1_CBA2R58 (0x8e8U) -#define SMMU_GNSR1_CBAR59 (0xecU) -#define SMMU_GNSR1_CBFRSYNRA59 (0x4ecU) -#define SMMU_GNSR1_CBA2R59 (0x8ecU) -#define SMMU_GNSR1_CBAR60 (0xf0U) -#define SMMU_GNSR1_CBFRSYNRA60 (0x4f0U) -#define SMMU_GNSR1_CBA2R60 (0x8f0U) -#define SMMU_GNSR1_CBAR61 (0xf4U) -#define SMMU_GNSR1_CBFRSYNRA61 (0x4f4U) -#define SMMU_GNSR1_CBA2R61 (0x8f4U) -#define SMMU_GNSR1_CBAR62 (0xf8U) -#define SMMU_GNSR1_CBFRSYNRA62 (0x4f8U) -#define SMMU_GNSR1_CBA2R62 (0x8f8U) -#define SMMU_GNSR1_CBAR63 (0xfcU) -#define SMMU_GNSR1_CBFRSYNRA63 (0x4fcU) -#define SMMU_GNSR1_CBA2R63 (0x8fcU) /******************************************************************************* * SMMU Global Secure Aux. Configuration Register @@ -588,262 +30,7 @@ ******************************************************************************/ #define SMMU_CBn_ACTLR_CPRE_BIT (1ULL << 1U) -/******************************************************************************* - * SMMU configuration constants - ******************************************************************************/ -#define ID1_PAGESIZE (1U << 31U) -#define ID1_NUMPAGENDXB_SHIFT 28U -#define ID1_NUMPAGENDXB_MASK 7U -#define ID1_NUMS2CB_SHIFT 16U -#define ID1_NUMS2CB_MASK 0xffU -#define ID1_NUMCB_SHIFT 0U -#define ID1_NUMCB_MASK 0xffU -#define PGSHIFT 16U -#define CB_SIZE 0x800000U - -typedef struct smmu_regs { - uint32_t reg; - uint32_t val; -} smmu_regs_t; - -#define mc_make_sid_override_cfg(name) \ - { \ - .reg = TEGRA_MC_STREAMID_BASE + MC_STREAMID_OVERRIDE_CFG_ ## name, \ - .val = 0x00000000U, \ - } - -#define mc_make_sid_security_cfg(name) \ - { \ - .reg = TEGRA_MC_STREAMID_BASE + MC_STREAMID_OVERRIDE_TO_SECURITY_CFG(MC_STREAMID_OVERRIDE_CFG_ ## name), \ - .val = 0x00000000U, \ - } - -#define smmu_make_gnsr0_sec_cfg(base_addr, name) \ - { \ - .reg = base_addr + SMMU_GNSR0_ ## name, \ - .val = 0x00000000U, \ - } - -/* - * On ARM-SMMU, conditional offset to access secure aliases of non-secure registers - * is 0x400. So, add it to register address - */ -#define smmu_make_gnsr0_nsec_cfg(base_addr, name) \ - { \ - .reg = base_addr + 0x400U + SMMU_GNSR0_ ## name, \ - .val = 0x00000000U, \ - } - -#define smmu_make_gnsr0_smr_cfg(base_addr, n) \ - { \ - .reg = base_addr + SMMU_GNSR0_SMR ## n, \ - .val = 0x00000000U, \ - } - -#define smmu_make_gnsr0_s2cr_cfg(base_addr, n) \ - { \ - .reg = base_addr + SMMU_GNSR0_S2CR ## n, \ - .val = 0x00000000U, \ - } - -#define smmu_make_gnsr1_cbar_cfg(base_addr, n) \ - { \ - .reg = base_addr + (1U << PGSHIFT) + SMMU_GNSR1_CBAR ## n, \ - .val = 0x00000000U, \ - } - -#define smmu_make_gnsr1_cba2r_cfg(base_addr, n) \ - { \ - .reg = base_addr + (1U << PGSHIFT) + SMMU_GNSR1_CBA2R ## n, \ - .val = 0x00000000U, \ - } - -#define smmu_make_cb_cfg(base_addr, name, n) \ - { \ - .reg = base_addr + (CB_SIZE >> 1) + (n * (1 << PGSHIFT)) \ - + SMMU_CBn_ ## name, \ - .val = 0x00000000U, \ - } - -#define smmu_make_smrg_group(base_addr, n) \ - smmu_make_gnsr0_smr_cfg(base_addr, n), \ - smmu_make_gnsr0_s2cr_cfg(base_addr, n), \ - smmu_make_gnsr1_cbar_cfg(base_addr, n), \ - smmu_make_gnsr1_cba2r_cfg(base_addr, n) /* don't put "," here. */ - -#define smmu_make_cb_group(base_addr, n) \ - smmu_make_cb_cfg(base_addr, SCTLR, n), \ - smmu_make_cb_cfg(base_addr, TCR2, n), \ - smmu_make_cb_cfg(base_addr, TTBR0_LO, n), \ - smmu_make_cb_cfg(base_addr, TTBR0_HI, n), \ - smmu_make_cb_cfg(base_addr, TCR, n), \ - smmu_make_cb_cfg(base_addr, PRRR_MAIR0, n),\ - smmu_make_cb_cfg(base_addr, FSR, n), \ - smmu_make_cb_cfg(base_addr, FAR_LO, n), \ - smmu_make_cb_cfg(base_addr, FAR_HI, n), \ - smmu_make_cb_cfg(base_addr, FSYNR0, n) /* don't put "," here. */ - -#define smmu_make_cfg(base_addr) \ - smmu_make_gnsr0_nsec_cfg(base_addr, CR0), \ - smmu_make_gnsr0_sec_cfg(base_addr, IDR0), \ - smmu_make_gnsr0_sec_cfg(base_addr, IDR1), \ - smmu_make_gnsr0_sec_cfg(base_addr, IDR2), \ - smmu_make_gnsr0_nsec_cfg(base_addr, GFSR), \ - smmu_make_gnsr0_nsec_cfg(base_addr, GFSYNR0), \ - smmu_make_gnsr0_nsec_cfg(base_addr, GFSYNR1), \ - smmu_make_gnsr0_nsec_cfg(base_addr, TLBGSTATUS),\ - smmu_make_gnsr0_nsec_cfg(base_addr, PIDR2), \ - smmu_make_smrg_group(base_addr, 0), \ - smmu_make_smrg_group(base_addr, 1), \ - smmu_make_smrg_group(base_addr, 2), \ - smmu_make_smrg_group(base_addr, 3), \ - smmu_make_smrg_group(base_addr, 4), \ - smmu_make_smrg_group(base_addr, 5), \ - smmu_make_smrg_group(base_addr, 6), \ - smmu_make_smrg_group(base_addr, 7), \ - smmu_make_smrg_group(base_addr, 8), \ - smmu_make_smrg_group(base_addr, 9), \ - smmu_make_smrg_group(base_addr, 10), \ - smmu_make_smrg_group(base_addr, 11), \ - smmu_make_smrg_group(base_addr, 12), \ - smmu_make_smrg_group(base_addr, 13), \ - smmu_make_smrg_group(base_addr, 14), \ - smmu_make_smrg_group(base_addr, 15), \ - smmu_make_smrg_group(base_addr, 16), \ - smmu_make_smrg_group(base_addr, 17), \ - smmu_make_smrg_group(base_addr, 18), \ - smmu_make_smrg_group(base_addr, 19), \ - smmu_make_smrg_group(base_addr, 20), \ - smmu_make_smrg_group(base_addr, 21), \ - smmu_make_smrg_group(base_addr, 22), \ - smmu_make_smrg_group(base_addr, 23), \ - smmu_make_smrg_group(base_addr, 24), \ - smmu_make_smrg_group(base_addr, 25), \ - smmu_make_smrg_group(base_addr, 26), \ - smmu_make_smrg_group(base_addr, 27), \ - smmu_make_smrg_group(base_addr, 28), \ - smmu_make_smrg_group(base_addr, 29), \ - smmu_make_smrg_group(base_addr, 30), \ - smmu_make_smrg_group(base_addr, 31), \ - smmu_make_smrg_group(base_addr, 32), \ - smmu_make_smrg_group(base_addr, 33), \ - smmu_make_smrg_group(base_addr, 34), \ - smmu_make_smrg_group(base_addr, 35), \ - smmu_make_smrg_group(base_addr, 36), \ - smmu_make_smrg_group(base_addr, 37), \ - smmu_make_smrg_group(base_addr, 38), \ - smmu_make_smrg_group(base_addr, 39), \ - smmu_make_smrg_group(base_addr, 40), \ - smmu_make_smrg_group(base_addr, 41), \ - smmu_make_smrg_group(base_addr, 42), \ - smmu_make_smrg_group(base_addr, 43), \ - smmu_make_smrg_group(base_addr, 44), \ - smmu_make_smrg_group(base_addr, 45), \ - smmu_make_smrg_group(base_addr, 46), \ - smmu_make_smrg_group(base_addr, 47), \ - smmu_make_smrg_group(base_addr, 48), \ - smmu_make_smrg_group(base_addr, 49), \ - smmu_make_smrg_group(base_addr, 50), \ - smmu_make_smrg_group(base_addr, 51), \ - smmu_make_smrg_group(base_addr, 52), \ - smmu_make_smrg_group(base_addr, 53), \ - smmu_make_smrg_group(base_addr, 54), \ - smmu_make_smrg_group(base_addr, 55), \ - smmu_make_smrg_group(base_addr, 56), \ - smmu_make_smrg_group(base_addr, 57), \ - smmu_make_smrg_group(base_addr, 58), \ - smmu_make_smrg_group(base_addr, 59), \ - smmu_make_smrg_group(base_addr, 60), \ - smmu_make_smrg_group(base_addr, 61), \ - smmu_make_smrg_group(base_addr, 62), \ - smmu_make_smrg_group(base_addr, 63), \ - smmu_make_cb_group(base_addr, 0), \ - smmu_make_cb_group(base_addr, 1), \ - smmu_make_cb_group(base_addr, 2), \ - smmu_make_cb_group(base_addr, 3), \ - smmu_make_cb_group(base_addr, 4), \ - smmu_make_cb_group(base_addr, 5), \ - smmu_make_cb_group(base_addr, 6), \ - smmu_make_cb_group(base_addr, 7), \ - smmu_make_cb_group(base_addr, 8), \ - smmu_make_cb_group(base_addr, 9), \ - smmu_make_cb_group(base_addr, 10), \ - smmu_make_cb_group(base_addr, 11), \ - smmu_make_cb_group(base_addr, 12), \ - smmu_make_cb_group(base_addr, 13), \ - smmu_make_cb_group(base_addr, 14), \ - smmu_make_cb_group(base_addr, 15), \ - smmu_make_cb_group(base_addr, 16), \ - smmu_make_cb_group(base_addr, 17), \ - smmu_make_cb_group(base_addr, 18), \ - smmu_make_cb_group(base_addr, 19), \ - smmu_make_cb_group(base_addr, 20), \ - smmu_make_cb_group(base_addr, 21), \ - smmu_make_cb_group(base_addr, 22), \ - smmu_make_cb_group(base_addr, 23), \ - smmu_make_cb_group(base_addr, 24), \ - smmu_make_cb_group(base_addr, 25), \ - smmu_make_cb_group(base_addr, 26), \ - smmu_make_cb_group(base_addr, 27), \ - smmu_make_cb_group(base_addr, 28), \ - smmu_make_cb_group(base_addr, 29), \ - smmu_make_cb_group(base_addr, 30), \ - smmu_make_cb_group(base_addr, 31), \ - smmu_make_cb_group(base_addr, 32), \ - smmu_make_cb_group(base_addr, 33), \ - smmu_make_cb_group(base_addr, 34), \ - smmu_make_cb_group(base_addr, 35), \ - smmu_make_cb_group(base_addr, 36), \ - smmu_make_cb_group(base_addr, 37), \ - smmu_make_cb_group(base_addr, 38), \ - smmu_make_cb_group(base_addr, 39), \ - smmu_make_cb_group(base_addr, 40), \ - smmu_make_cb_group(base_addr, 41), \ - smmu_make_cb_group(base_addr, 42), \ - smmu_make_cb_group(base_addr, 43), \ - smmu_make_cb_group(base_addr, 44), \ - smmu_make_cb_group(base_addr, 45), \ - smmu_make_cb_group(base_addr, 46), \ - smmu_make_cb_group(base_addr, 47), \ - smmu_make_cb_group(base_addr, 48), \ - smmu_make_cb_group(base_addr, 49), \ - smmu_make_cb_group(base_addr, 50), \ - smmu_make_cb_group(base_addr, 51), \ - smmu_make_cb_group(base_addr, 52), \ - smmu_make_cb_group(base_addr, 53), \ - smmu_make_cb_group(base_addr, 54), \ - smmu_make_cb_group(base_addr, 55), \ - smmu_make_cb_group(base_addr, 56), \ - smmu_make_cb_group(base_addr, 57), \ - smmu_make_cb_group(base_addr, 58), \ - smmu_make_cb_group(base_addr, 59), \ - smmu_make_cb_group(base_addr, 60), \ - smmu_make_cb_group(base_addr, 61), \ - smmu_make_cb_group(base_addr, 62), \ - smmu_make_cb_group(base_addr, 63) /* don't put "," here. */ - -#define smmu_bypass_cfg \ - { \ - .reg = TEGRA_MC_BASE + MC_SMMU_BYPASS_CONFIG, \ - .val = 0x00000000U, \ - } - -#define _START_OF_TABLE_ \ - { \ - .reg = 0xCAFE05C7U, \ - .val = 0x00000000U, \ - } - -#define _END_OF_TABLE_ \ - { \ - .reg = 0xFFFFFFFFU, \ - .val = 0xFFFFFFFFU, \ - } - - void tegra_smmu_init(void); -void tegra_smmu_save_context(uint64_t smmu_ctx_addr); -smmu_regs_t *plat_get_smmu_ctx(void); uint32_t plat_get_num_smmu_devices(void); #endif /* SMMU_H */ diff --git a/plat/nvidia/tegra/include/t186/tegra186_private.h b/plat/nvidia/tegra/include/t186/tegra186_private.h index 9e2c02b4b..60174ab54 100644 --- a/plat/nvidia/tegra/include/t186/tegra186_private.h +++ b/plat/nvidia/tegra/include/t186/tegra186_private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -10,7 +10,7 @@ void tegra186_cpu_reset_handler(void); uint64_t tegra186_get_cpu_reset_handler_base(void); uint64_t tegra186_get_cpu_reset_handler_size(void); -uint64_t tegra186_get_smmu_ctx_offset(void); +uint64_t tegra186_get_mc_ctx_offset(void); void tegra186_set_system_suspend_entry(void); #endif /* TEGRA186_PRIVATE_H */ diff --git a/plat/nvidia/tegra/include/t186/tegra_def.h b/plat/nvidia/tegra/include/t186/tegra_def.h index 56157e2de..1da9b4639 100644 --- a/plat/nvidia/tegra/include/t186/tegra_def.h +++ b/plat/nvidia/tegra/include/t186/tegra_def.h @@ -275,8 +275,8 @@ #define SCRATCH_RESET_VECTOR_LO SECURE_SCRATCH_RSV1_LO #define SCRATCH_RESET_VECTOR_HI SECURE_SCRATCH_RSV1_HI #define SCRATCH_SECURE_BOOTP_FCFG SECURE_SCRATCH_RSV6 -#define SCRATCH_SMMU_TABLE_ADDR_LO SECURE_SCRATCH_RSV11_LO -#define SCRATCH_SMMU_TABLE_ADDR_HI SECURE_SCRATCH_RSV11_HI +#define SCRATCH_MC_TABLE_ADDR_LO SECURE_SCRATCH_RSV11_LO +#define SCRATCH_MC_TABLE_ADDR_HI SECURE_SCRATCH_RSV11_HI #define SCRATCH_BL31_PARAMS_ADDR SECURE_SCRATCH_RSV53_LO #define SCRATCH_BL31_PLAT_PARAMS_ADDR SECURE_SCRATCH_RSV53_HI #define SCRATCH_TZDRAM_ADDR_LO SECURE_SCRATCH_RSV55_LO diff --git a/plat/nvidia/tegra/include/t194/tegra194_private.h b/plat/nvidia/tegra/include/t194/tegra194_private.h index 8f1deb2a3..c5a51e951 100644 --- a/plat/nvidia/tegra/include/t194/tegra194_private.h +++ b/plat/nvidia/tegra/include/t194/tegra194_private.h @@ -10,7 +10,7 @@ void tegra194_cpu_reset_handler(void); uint64_t tegra194_get_cpu_reset_handler_base(void); uint64_t tegra194_get_cpu_reset_handler_size(void); -uint64_t tegra194_get_smmu_ctx_offset(void); +uint64_t tegra194_get_mc_ctx_offset(void); void tegra194_set_system_suspend_entry(void); #endif /* TEGRA194_PRIVATE_H */ diff --git a/plat/nvidia/tegra/include/t194/tegra_def.h b/plat/nvidia/tegra/include/t194/tegra_def.h index 7fd97785e..dc0644514 100644 --- a/plat/nvidia/tegra/include/t194/tegra_def.h +++ b/plat/nvidia/tegra/include/t194/tegra_def.h @@ -231,8 +231,8 @@ #define SCRATCH_BL31_PLAT_PARAMS_HI_ADDR_SHIFT U(16) #define SCRATCH_BL31_PLAT_PARAMS_LO_ADDR SECURE_SCRATCH_RSV81_HI #define SCRATCH_SECURE_BOOTP_FCFG SECURE_SCRATCH_RSV97 -#define SCRATCH_SMMU_TABLE_ADDR_LO SECURE_SCRATCH_RSV99_LO -#define SCRATCH_SMMU_TABLE_ADDR_HI SECURE_SCRATCH_RSV99_HI +#define SCRATCH_MC_TABLE_ADDR_LO SECURE_SCRATCH_RSV99_LO +#define SCRATCH_MC_TABLE_ADDR_HI SECURE_SCRATCH_RSV99_HI #define SCRATCH_RESET_VECTOR_LO SECURE_SCRATCH_RSV109_LO #define SCRATCH_RESET_VECTOR_HI SECURE_SCRATCH_RSV109_HI diff --git a/plat/nvidia/tegra/soc/t186/plat_memctrl.c b/plat/nvidia/tegra/soc/t186/plat_memctrl.c index a97496bd1..09377bb09 100644 --- a/plat/nvidia/tegra/soc/t186/plat_memctrl.c +++ b/plat/nvidia/tegra/soc/t186/plat_memctrl.c @@ -516,6 +516,171 @@ static void tegra186_memctrl_set_overrides(void) } } + +/******************************************************************************* + * Array to hold MC context for Tegra186 + ******************************************************************************/ +static __attribute__((aligned(16))) mc_regs_t tegra186_mc_context[] = { + _START_OF_TABLE_, + mc_make_sid_security_cfg(SCEW), + mc_make_sid_security_cfg(AFIR), + mc_make_sid_security_cfg(NVDISPLAYR1), + mc_make_sid_security_cfg(XUSB_DEVR), + mc_make_sid_security_cfg(VICSRD1), + mc_make_sid_security_cfg(NVENCSWR), + mc_make_sid_security_cfg(TSECSRDB), + mc_make_sid_security_cfg(AXISW), + mc_make_sid_security_cfg(SDMMCWAB), + mc_make_sid_security_cfg(AONDMAW), + mc_make_sid_security_cfg(GPUSWR2), + mc_make_sid_security_cfg(SATAW), + mc_make_sid_security_cfg(UFSHCW), + mc_make_sid_security_cfg(AFIW), + mc_make_sid_security_cfg(SDMMCR), + mc_make_sid_security_cfg(SCEDMAW), + mc_make_sid_security_cfg(UFSHCR), + mc_make_sid_security_cfg(SDMMCWAA), + mc_make_sid_security_cfg(APEDMAW), + mc_make_sid_security_cfg(SESWR), + mc_make_sid_security_cfg(MPCORER), + mc_make_sid_security_cfg(PTCR), + mc_make_sid_security_cfg(BPMPW), + mc_make_sid_security_cfg(ETRW), + mc_make_sid_security_cfg(GPUSRD), + mc_make_sid_security_cfg(VICSWR), + mc_make_sid_security_cfg(SCEDMAR), + mc_make_sid_security_cfg(HDAW), + mc_make_sid_security_cfg(ISPWA), + mc_make_sid_security_cfg(EQOSW), + mc_make_sid_security_cfg(XUSB_HOSTW), + mc_make_sid_security_cfg(TSECSWR), + mc_make_sid_security_cfg(SDMMCRAA), + mc_make_sid_security_cfg(APER), + mc_make_sid_security_cfg(VIW), + mc_make_sid_security_cfg(APEW), + mc_make_sid_security_cfg(AXISR), + mc_make_sid_security_cfg(SDMMCW), + mc_make_sid_security_cfg(BPMPDMAW), + mc_make_sid_security_cfg(ISPRA), + mc_make_sid_security_cfg(NVDECSWR), + mc_make_sid_security_cfg(XUSB_DEVW), + mc_make_sid_security_cfg(NVDECSRD), + mc_make_sid_security_cfg(MPCOREW), + mc_make_sid_security_cfg(NVDISPLAYR), + mc_make_sid_security_cfg(BPMPDMAR), + mc_make_sid_security_cfg(NVJPGSWR), + mc_make_sid_security_cfg(NVDECSRD1), + mc_make_sid_security_cfg(TSECSRD), + mc_make_sid_security_cfg(NVJPGSRD), + mc_make_sid_security_cfg(SDMMCWA), + mc_make_sid_security_cfg(SCER), + mc_make_sid_security_cfg(XUSB_HOSTR), + mc_make_sid_security_cfg(VICSRD), + mc_make_sid_security_cfg(AONDMAR), + mc_make_sid_security_cfg(AONW), + mc_make_sid_security_cfg(SDMMCRA), + mc_make_sid_security_cfg(HOST1XDMAR), + mc_make_sid_security_cfg(EQOSR), + mc_make_sid_security_cfg(SATAR), + mc_make_sid_security_cfg(BPMPR), + mc_make_sid_security_cfg(HDAR), + mc_make_sid_security_cfg(SDMMCRAB), + mc_make_sid_security_cfg(ETRR), + mc_make_sid_security_cfg(AONR), + mc_make_sid_security_cfg(APEDMAR), + mc_make_sid_security_cfg(SESRD), + mc_make_sid_security_cfg(NVENCSRD), + mc_make_sid_security_cfg(GPUSWR), + mc_make_sid_security_cfg(TSECSWRB), + mc_make_sid_security_cfg(ISPWB), + mc_make_sid_security_cfg(GPUSRD2), + mc_make_sid_override_cfg(APER), + mc_make_sid_override_cfg(VICSRD), + mc_make_sid_override_cfg(NVENCSRD), + mc_make_sid_override_cfg(NVJPGSWR), + mc_make_sid_override_cfg(AONW), + mc_make_sid_override_cfg(BPMPR), + mc_make_sid_override_cfg(BPMPW), + mc_make_sid_override_cfg(HDAW), + mc_make_sid_override_cfg(NVDISPLAYR1), + mc_make_sid_override_cfg(APEDMAR), + mc_make_sid_override_cfg(AFIR), + mc_make_sid_override_cfg(AXISR), + mc_make_sid_override_cfg(VICSRD1), + mc_make_sid_override_cfg(TSECSRD), + mc_make_sid_override_cfg(BPMPDMAW), + mc_make_sid_override_cfg(MPCOREW), + mc_make_sid_override_cfg(XUSB_HOSTR), + mc_make_sid_override_cfg(GPUSWR), + mc_make_sid_override_cfg(XUSB_DEVR), + mc_make_sid_override_cfg(UFSHCW), + mc_make_sid_override_cfg(XUSB_HOSTW), + mc_make_sid_override_cfg(SDMMCWAB), + mc_make_sid_override_cfg(SATAW), + mc_make_sid_override_cfg(SCEDMAR), + mc_make_sid_override_cfg(HOST1XDMAR), + mc_make_sid_override_cfg(SDMMCWA), + mc_make_sid_override_cfg(APEDMAW), + mc_make_sid_override_cfg(SESWR), + mc_make_sid_override_cfg(AXISW), + mc_make_sid_override_cfg(AONDMAW), + mc_make_sid_override_cfg(TSECSWRB), + mc_make_sid_override_cfg(MPCORER), + mc_make_sid_override_cfg(ISPWB), + mc_make_sid_override_cfg(AONR), + mc_make_sid_override_cfg(BPMPDMAR), + mc_make_sid_override_cfg(HDAR), + mc_make_sid_override_cfg(SDMMCRA), + mc_make_sid_override_cfg(ETRW), + mc_make_sid_override_cfg(GPUSWR2), + mc_make_sid_override_cfg(EQOSR), + mc_make_sid_override_cfg(TSECSWR), + mc_make_sid_override_cfg(ETRR), + mc_make_sid_override_cfg(NVDECSRD), + mc_make_sid_override_cfg(TSECSRDB), + mc_make_sid_override_cfg(SDMMCRAA), + mc_make_sid_override_cfg(NVDECSRD1), + mc_make_sid_override_cfg(SDMMCR), + mc_make_sid_override_cfg(NVJPGSRD), + mc_make_sid_override_cfg(SCEDMAW), + mc_make_sid_override_cfg(SDMMCWAA), + mc_make_sid_override_cfg(APEW), + mc_make_sid_override_cfg(AONDMAR), + mc_make_sid_override_cfg(PTCR), + mc_make_sid_override_cfg(SCER), + mc_make_sid_override_cfg(ISPRA), + mc_make_sid_override_cfg(ISPWA), + mc_make_sid_override_cfg(VICSWR), + mc_make_sid_override_cfg(SESRD), + mc_make_sid_override_cfg(SDMMCW), + mc_make_sid_override_cfg(SDMMCRAB), + mc_make_sid_override_cfg(EQOSW), + mc_make_sid_override_cfg(GPUSRD2), + mc_make_sid_override_cfg(SCEW), + mc_make_sid_override_cfg(GPUSRD), + mc_make_sid_override_cfg(NVDECSWR), + mc_make_sid_override_cfg(XUSB_DEVW), + mc_make_sid_override_cfg(SATAR), + mc_make_sid_override_cfg(NVDISPLAYR), + mc_make_sid_override_cfg(VIW), + mc_make_sid_override_cfg(UFSHCR), + mc_make_sid_override_cfg(NVENCSWR), + mc_make_sid_override_cfg(AFIW), + mc_smmu_bypass_cfg, /* TBU settings */ + _END_OF_TABLE_, +}; + +/******************************************************************************* + * Handler to return the pointer to the MC's context struct + ******************************************************************************/ +static mc_regs_t *tegra186_get_mc_system_suspend_ctx(void) +{ + /* index of _END_OF_TABLE_ */ + tegra186_mc_context[0].val = (uint32_t)(ARRAY_SIZE(tegra186_mc_context)) - 1U; + + return tegra186_mc_context; +} + /******************************************************************************* * Struct to hold the memory controller settings ******************************************************************************/ @@ -528,6 +693,7 @@ static tegra_mc_settings_t tegra186_mc_settings = { .num_txn_override_cfgs = (uint32_t)ARRAY_SIZE(tegra186_txn_override_cfgs), .reconfig_mss_clients = tegra186_memctrl_reconfig_mss_clients, .set_txn_overrides = tegra186_memctrl_set_overrides, + .get_mc_system_suspend_ctx = tegra186_get_mc_system_suspend_ctx, }; /******************************************************************************* diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c index f034bdb87..179dd9654 100644 --- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -99,7 +100,7 @@ int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) uint32_t cpu = plat_my_core_pos(); const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); mce_cstate_info_t cstate_info = { 0 }; - uint64_t smmu_ctx_base; + uint64_t mc_ctx_base; uint32_t val; /* get the state ID */ @@ -132,10 +133,10 @@ int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) val = mmio_read_32(TEGRA_MISC_BASE + MISCREG_PFCFG); mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SECURE_BOOTP_FCFG, val); - /* save SMMU context to TZDRAM */ - smmu_ctx_base = params_from_bl2->tzdram_base + - tegra186_get_smmu_ctx_offset(); - tegra_smmu_save_context((uintptr_t)smmu_ctx_base); + /* save MC context to TZDRAM */ + mc_ctx_base = params_from_bl2->tzdram_base + + tegra186_get_mc_ctx_offset(); + tegra_mc_save_context((uintptr_t)mc_ctx_base); /* Prepare for system suspend */ cstate_info.cluster = (uint32_t)TEGRA_ARI_CLUSTER_CC7; diff --git a/plat/nvidia/tegra/soc/t186/plat_smmu.c b/plat/nvidia/tegra/soc/t186/plat_smmu.c index b4a7fe596..f1bc235e8 100644 --- a/plat/nvidia/tegra/soc/t186/plat_smmu.c +++ b/plat/nvidia/tegra/soc/t186/plat_smmu.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -12,171 +13,6 @@ #define MAX_NUM_SMMU_DEVICES U(1) -/******************************************************************************* - * Array to hold SMMU context for Tegra186 - ******************************************************************************/ -static __attribute__((aligned(16))) smmu_regs_t tegra186_smmu_context[] = { - _START_OF_TABLE_, - mc_make_sid_security_cfg(SCEW), - mc_make_sid_security_cfg(AFIR), - mc_make_sid_security_cfg(NVDISPLAYR1), - mc_make_sid_security_cfg(XUSB_DEVR), - mc_make_sid_security_cfg(VICSRD1), - mc_make_sid_security_cfg(NVENCSWR), - mc_make_sid_security_cfg(TSECSRDB), - mc_make_sid_security_cfg(AXISW), - mc_make_sid_security_cfg(SDMMCWAB), - mc_make_sid_security_cfg(AONDMAW), - mc_make_sid_security_cfg(GPUSWR2), - mc_make_sid_security_cfg(SATAW), - mc_make_sid_security_cfg(UFSHCW), - mc_make_sid_security_cfg(AFIW), - mc_make_sid_security_cfg(SDMMCR), - mc_make_sid_security_cfg(SCEDMAW), - mc_make_sid_security_cfg(UFSHCR), - mc_make_sid_security_cfg(SDMMCWAA), - mc_make_sid_security_cfg(APEDMAW), - mc_make_sid_security_cfg(SESWR), - mc_make_sid_security_cfg(MPCORER), - mc_make_sid_security_cfg(PTCR), - mc_make_sid_security_cfg(BPMPW), - mc_make_sid_security_cfg(ETRW), - mc_make_sid_security_cfg(GPUSRD), - mc_make_sid_security_cfg(VICSWR), - mc_make_sid_security_cfg(SCEDMAR), - mc_make_sid_security_cfg(HDAW), - mc_make_sid_security_cfg(ISPWA), - mc_make_sid_security_cfg(EQOSW), - mc_make_sid_security_cfg(XUSB_HOSTW), - mc_make_sid_security_cfg(TSECSWR), - mc_make_sid_security_cfg(SDMMCRAA), - mc_make_sid_security_cfg(APER), - mc_make_sid_security_cfg(VIW), - mc_make_sid_security_cfg(APEW), - mc_make_sid_security_cfg(AXISR), - mc_make_sid_security_cfg(SDMMCW), - mc_make_sid_security_cfg(BPMPDMAW), - mc_make_sid_security_cfg(ISPRA), - mc_make_sid_security_cfg(NVDECSWR), - mc_make_sid_security_cfg(XUSB_DEVW), - mc_make_sid_security_cfg(NVDECSRD), - mc_make_sid_security_cfg(MPCOREW), - mc_make_sid_security_cfg(NVDISPLAYR), - mc_make_sid_security_cfg(BPMPDMAR), - mc_make_sid_security_cfg(NVJPGSWR), - mc_make_sid_security_cfg(NVDECSRD1), - mc_make_sid_security_cfg(TSECSRD), - mc_make_sid_security_cfg(NVJPGSRD), - mc_make_sid_security_cfg(SDMMCWA), - mc_make_sid_security_cfg(SCER), - mc_make_sid_security_cfg(XUSB_HOSTR), - mc_make_sid_security_cfg(VICSRD), - mc_make_sid_security_cfg(AONDMAR), - mc_make_sid_security_cfg(AONW), - mc_make_sid_security_cfg(SDMMCRA), - mc_make_sid_security_cfg(HOST1XDMAR), - mc_make_sid_security_cfg(EQOSR), - mc_make_sid_security_cfg(SATAR), - mc_make_sid_security_cfg(BPMPR), - mc_make_sid_security_cfg(HDAR), - mc_make_sid_security_cfg(SDMMCRAB), - mc_make_sid_security_cfg(ETRR), - mc_make_sid_security_cfg(AONR), - mc_make_sid_security_cfg(APEDMAR), - mc_make_sid_security_cfg(SESRD), - mc_make_sid_security_cfg(NVENCSRD), - mc_make_sid_security_cfg(GPUSWR), - mc_make_sid_security_cfg(TSECSWRB), - mc_make_sid_security_cfg(ISPWB), - mc_make_sid_security_cfg(GPUSRD2), - mc_make_sid_override_cfg(APER), - mc_make_sid_override_cfg(VICSRD), - mc_make_sid_override_cfg(NVENCSRD), - mc_make_sid_override_cfg(NVJPGSWR), - mc_make_sid_override_cfg(AONW), - mc_make_sid_override_cfg(BPMPR), - mc_make_sid_override_cfg(BPMPW), - mc_make_sid_override_cfg(HDAW), - mc_make_sid_override_cfg(NVDISPLAYR1), - mc_make_sid_override_cfg(APEDMAR), - mc_make_sid_override_cfg(AFIR), - mc_make_sid_override_cfg(AXISR), - mc_make_sid_override_cfg(VICSRD1), - mc_make_sid_override_cfg(TSECSRD), - mc_make_sid_override_cfg(BPMPDMAW), - mc_make_sid_override_cfg(MPCOREW), - mc_make_sid_override_cfg(XUSB_HOSTR), - mc_make_sid_override_cfg(GPUSWR), - mc_make_sid_override_cfg(XUSB_DEVR), - mc_make_sid_override_cfg(UFSHCW), - mc_make_sid_override_cfg(XUSB_HOSTW), - mc_make_sid_override_cfg(SDMMCWAB), - mc_make_sid_override_cfg(SATAW), - mc_make_sid_override_cfg(SCEDMAR), - mc_make_sid_override_cfg(HOST1XDMAR), - mc_make_sid_override_cfg(SDMMCWA), - mc_make_sid_override_cfg(APEDMAW), - mc_make_sid_override_cfg(SESWR), - mc_make_sid_override_cfg(AXISW), - mc_make_sid_override_cfg(AONDMAW), - mc_make_sid_override_cfg(TSECSWRB), - mc_make_sid_override_cfg(MPCORER), - mc_make_sid_override_cfg(ISPWB), - mc_make_sid_override_cfg(AONR), - mc_make_sid_override_cfg(BPMPDMAR), - mc_make_sid_override_cfg(HDAR), - mc_make_sid_override_cfg(SDMMCRA), - mc_make_sid_override_cfg(ETRW), - mc_make_sid_override_cfg(GPUSWR2), - mc_make_sid_override_cfg(EQOSR), - mc_make_sid_override_cfg(TSECSWR), - mc_make_sid_override_cfg(ETRR), - mc_make_sid_override_cfg(NVDECSRD), - mc_make_sid_override_cfg(TSECSRDB), - mc_make_sid_override_cfg(SDMMCRAA), - mc_make_sid_override_cfg(NVDECSRD1), - mc_make_sid_override_cfg(SDMMCR), - mc_make_sid_override_cfg(NVJPGSRD), - mc_make_sid_override_cfg(SCEDMAW), - mc_make_sid_override_cfg(SDMMCWAA), - mc_make_sid_override_cfg(APEW), - mc_make_sid_override_cfg(AONDMAR), - mc_make_sid_override_cfg(PTCR), - mc_make_sid_override_cfg(SCER), - mc_make_sid_override_cfg(ISPRA), - mc_make_sid_override_cfg(ISPWA), - mc_make_sid_override_cfg(VICSWR), - mc_make_sid_override_cfg(SESRD), - mc_make_sid_override_cfg(SDMMCW), - mc_make_sid_override_cfg(SDMMCRAB), - mc_make_sid_override_cfg(EQOSW), - mc_make_sid_override_cfg(GPUSRD2), - mc_make_sid_override_cfg(SCEW), - mc_make_sid_override_cfg(GPUSRD), - mc_make_sid_override_cfg(NVDECSWR), - mc_make_sid_override_cfg(XUSB_DEVW), - mc_make_sid_override_cfg(SATAR), - mc_make_sid_override_cfg(NVDISPLAYR), - mc_make_sid_override_cfg(VIW), - mc_make_sid_override_cfg(UFSHCR), - mc_make_sid_override_cfg(NVENCSWR), - mc_make_sid_override_cfg(AFIW), - smmu_make_cfg(TEGRA_SMMU0_BASE), - smmu_bypass_cfg, /* TBU settings */ - _END_OF_TABLE_, -}; - -/******************************************************************************* - * Handler to return the pointer to the SMMU's context struct - ******************************************************************************/ -smmu_regs_t *plat_get_smmu_ctx(void) -{ - /* index of _END_OF_TABLE_ */ - tegra186_smmu_context[0].val = (uint32_t)(ARRAY_SIZE(tegra186_smmu_context)) - 1U; - - return tegra186_smmu_context; -} - /******************************************************************************* * Handler to return the support SMMU devices number ******************************************************************************/ diff --git a/plat/nvidia/tegra/soc/t186/plat_trampoline.S b/plat/nvidia/tegra/soc/t186/plat_trampoline.S index db692349e..818c24b49 100644 --- a/plat/nvidia/tegra/soc/t186/plat_trampoline.S +++ b/plat/nvidia/tegra/soc/t186/plat_trampoline.S @@ -1,5 +1,6 @@ /* * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -13,7 +14,7 @@ #define TEGRA186_STATE_SYSTEM_SUSPEND 0x5C7 #define TEGRA186_STATE_SYSTEM_RESUME 0x600D -#define TEGRA186_SMMU_CTX_SIZE 0x420 +#define TEGRA186_MC_CTX_SIZE 0x93 .globl tegra186_cpu_reset_handler @@ -69,8 +70,8 @@ endfunc tegra186_cpu_reset_handler * * 0x000: secure world's entrypoint * 0x008: BL31 size (RO + RW) - * 0x00C: SMMU context start - * 0x42C: SMMU context end + * 0x00C: MC context start + * 0x42C: MC context end */ .align 4 @@ -85,9 +86,9 @@ __tegra186_system_suspend_state: .quad 0 .align 4 - .globl __tegra186_smmu_context -__tegra186_smmu_context: - .rept TEGRA186_SMMU_CTX_SIZE + .globl __tegra186_mc_context +__tegra186_mc_context: + .rept TEGRA186_MC_CTX_SIZE .quad 0 .endr .size __tegra186_cpu_reset_handler_data, \ @@ -99,7 +100,7 @@ __tegra186_cpu_reset_handler_end: .globl tegra186_get_cpu_reset_handler_size .globl tegra186_get_cpu_reset_handler_base - .globl tegra186_get_smmu_ctx_offset + .globl tegra186_get_mc_ctx_offset .globl tegra186_set_system_suspend_entry /* return size of the CPU reset handler */ @@ -116,13 +117,13 @@ func tegra186_get_cpu_reset_handler_base ret endfunc tegra186_get_cpu_reset_handler_base -/* return the size of the SMMU context */ -func tegra186_get_smmu_ctx_offset - adr x0, __tegra186_smmu_context +/* return the size of the MC context */ +func tegra186_get_mc_ctx_offset + adr x0, __tegra186_mc_context adr x1, tegra186_cpu_reset_handler sub x0, x0, x1 ret -endfunc tegra186_get_smmu_ctx_offset +endfunc tegra186_get_mc_ctx_offset /* set system suspend state before SC7 entry */ func tegra186_set_system_suspend_entry diff --git a/plat/nvidia/tegra/soc/t194/plat_memctrl.c b/plat/nvidia/tegra/soc/t194/plat_memctrl.c index f56084cbe..2d5f8e3c6 100644 --- a/plat/nvidia/tegra/soc/t194/plat_memctrl.c +++ b/plat/nvidia/tegra/soc/t194/plat_memctrl.c @@ -299,6 +299,274 @@ const static mc_streamid_security_cfg_t tegra194_streamid_sec_cfgs[] = { mc_make_sec_cfg(MIU7W, NON_SECURE, OVERRIDE, DISABLE) }; +/******************************************************************************* + * Array to hold MC context for Tegra194 + ******************************************************************************/ +static __attribute__((aligned(16))) mc_regs_t tegra194_mc_context[] = { + _START_OF_TABLE_, + mc_make_sid_security_cfg(HDAR), + mc_make_sid_security_cfg(HOST1XDMAR), + mc_make_sid_security_cfg(NVENCSRD), + mc_make_sid_security_cfg(SATAR), + mc_make_sid_security_cfg(NVENCSWR), + mc_make_sid_security_cfg(HDAW), + mc_make_sid_security_cfg(SATAW), + mc_make_sid_security_cfg(ISPRA), + mc_make_sid_security_cfg(ISPFALR), + mc_make_sid_security_cfg(ISPWA), + mc_make_sid_security_cfg(ISPWB), + mc_make_sid_security_cfg(XUSB_HOSTR), + mc_make_sid_security_cfg(XUSB_HOSTW), + mc_make_sid_security_cfg(XUSB_DEVR), + mc_make_sid_security_cfg(XUSB_DEVW), + mc_make_sid_security_cfg(TSECSRD), + mc_make_sid_security_cfg(TSECSWR), + mc_make_sid_security_cfg(SDMMCRA), + mc_make_sid_security_cfg(SDMMCR), + mc_make_sid_security_cfg(SDMMCRAB), + mc_make_sid_security_cfg(SDMMCWA), + mc_make_sid_security_cfg(SDMMCW), + mc_make_sid_security_cfg(SDMMCWAB), + mc_make_sid_security_cfg(VICSRD), + mc_make_sid_security_cfg(VICSWR), + mc_make_sid_security_cfg(VIW), + mc_make_sid_security_cfg(NVDECSRD), + mc_make_sid_security_cfg(NVDECSWR), + mc_make_sid_security_cfg(APER), + mc_make_sid_security_cfg(APEW), + mc_make_sid_security_cfg(NVJPGSRD), + mc_make_sid_security_cfg(NVJPGSWR), + mc_make_sid_security_cfg(SESRD), + mc_make_sid_security_cfg(SESWR), + mc_make_sid_security_cfg(AXIAPR), + mc_make_sid_security_cfg(AXIAPW), + mc_make_sid_security_cfg(ETRR), + mc_make_sid_security_cfg(ETRW), + mc_make_sid_security_cfg(TSECSRDB), + mc_make_sid_security_cfg(TSECSWRB), + mc_make_sid_security_cfg(AXISR), + mc_make_sid_security_cfg(AXISW), + mc_make_sid_security_cfg(EQOSR), + mc_make_sid_security_cfg(EQOSW), + mc_make_sid_security_cfg(UFSHCR), + mc_make_sid_security_cfg(UFSHCW), + mc_make_sid_security_cfg(NVDISPLAYR), + mc_make_sid_security_cfg(BPMPR), + mc_make_sid_security_cfg(BPMPW), + mc_make_sid_security_cfg(BPMPDMAR), + mc_make_sid_security_cfg(BPMPDMAW), + mc_make_sid_security_cfg(AONR), + mc_make_sid_security_cfg(AONW), + mc_make_sid_security_cfg(AONDMAR), + mc_make_sid_security_cfg(AONDMAW), + mc_make_sid_security_cfg(SCER), + mc_make_sid_security_cfg(SCEW), + mc_make_sid_security_cfg(SCEDMAR), + mc_make_sid_security_cfg(SCEDMAW), + mc_make_sid_security_cfg(APEDMAR), + mc_make_sid_security_cfg(APEDMAW), + mc_make_sid_security_cfg(NVDISPLAYR1), + mc_make_sid_security_cfg(VICSRD1), + mc_make_sid_security_cfg(NVDECSRD1), + mc_make_sid_security_cfg(VIFALR), + mc_make_sid_security_cfg(VIFALW), + mc_make_sid_security_cfg(DLA0RDA), + mc_make_sid_security_cfg(DLA0FALRDB), + mc_make_sid_security_cfg(DLA0WRA), + mc_make_sid_security_cfg(DLA0FALWRB), + mc_make_sid_security_cfg(DLA1RDA), + mc_make_sid_security_cfg(DLA1FALRDB), + mc_make_sid_security_cfg(DLA1WRA), + mc_make_sid_security_cfg(DLA1FALWRB), + mc_make_sid_security_cfg(PVA0RDA), + mc_make_sid_security_cfg(PVA0RDB), + mc_make_sid_security_cfg(PVA0RDC), + mc_make_sid_security_cfg(PVA0WRA), + mc_make_sid_security_cfg(PVA0WRB), + mc_make_sid_security_cfg(PVA0WRC), + mc_make_sid_security_cfg(PVA1RDA), + mc_make_sid_security_cfg(PVA1RDB), + mc_make_sid_security_cfg(PVA1RDC), + mc_make_sid_security_cfg(PVA1WRA), + mc_make_sid_security_cfg(PVA1WRB), + mc_make_sid_security_cfg(PVA1WRC), + mc_make_sid_security_cfg(RCER), + mc_make_sid_security_cfg(RCEW), + mc_make_sid_security_cfg(RCEDMAR), + mc_make_sid_security_cfg(RCEDMAW), + mc_make_sid_security_cfg(NVENC1SRD), + mc_make_sid_security_cfg(NVENC1SWR), + mc_make_sid_security_cfg(PCIE0R), + mc_make_sid_security_cfg(PCIE0W), + mc_make_sid_security_cfg(PCIE1R), + mc_make_sid_security_cfg(PCIE1W), + mc_make_sid_security_cfg(PCIE2AR), + mc_make_sid_security_cfg(PCIE2AW), + mc_make_sid_security_cfg(PCIE3R), + mc_make_sid_security_cfg(PCIE3W), + mc_make_sid_security_cfg(PCIE4R), + mc_make_sid_security_cfg(PCIE4W), + mc_make_sid_security_cfg(PCIE5R), + mc_make_sid_security_cfg(PCIE5W), + mc_make_sid_security_cfg(ISPFALW), + mc_make_sid_security_cfg(DLA0RDA1), + mc_make_sid_security_cfg(DLA1RDA1), + mc_make_sid_security_cfg(PVA0RDA1), + mc_make_sid_security_cfg(PVA0RDB1), + mc_make_sid_security_cfg(PVA1RDA1), + mc_make_sid_security_cfg(PVA1RDB1), + mc_make_sid_security_cfg(PCIE5R1), + mc_make_sid_security_cfg(NVENCSRD1), + mc_make_sid_security_cfg(NVENC1SRD1), + mc_make_sid_security_cfg(ISPRA1), + mc_make_sid_security_cfg(PCIE0R1), + mc_make_sid_security_cfg(MIU0R), + mc_make_sid_security_cfg(MIU0W), + mc_make_sid_security_cfg(MIU1R), + mc_make_sid_security_cfg(MIU1W), + mc_make_sid_security_cfg(MIU2R), + mc_make_sid_security_cfg(MIU2W), + mc_make_sid_security_cfg(MIU3R), + mc_make_sid_security_cfg(MIU3W), + mc_make_sid_override_cfg(HDAR), + mc_make_sid_override_cfg(HOST1XDMAR), + mc_make_sid_override_cfg(NVENCSRD), + mc_make_sid_override_cfg(SATAR), + mc_make_sid_override_cfg(NVENCSWR), + mc_make_sid_override_cfg(HDAW), + mc_make_sid_override_cfg(SATAW), + mc_make_sid_override_cfg(ISPRA), + mc_make_sid_override_cfg(ISPFALR), + mc_make_sid_override_cfg(ISPWA), + mc_make_sid_override_cfg(ISPWB), + mc_make_sid_override_cfg(XUSB_HOSTR), + mc_make_sid_override_cfg(XUSB_HOSTW), + mc_make_sid_override_cfg(XUSB_DEVR), + mc_make_sid_override_cfg(XUSB_DEVW), + mc_make_sid_override_cfg(TSECSRD), + mc_make_sid_override_cfg(TSECSWR), + mc_make_sid_override_cfg(SDMMCRA), + mc_make_sid_override_cfg(SDMMCR), + mc_make_sid_override_cfg(SDMMCRAB), + mc_make_sid_override_cfg(SDMMCWA), + mc_make_sid_override_cfg(SDMMCW), + mc_make_sid_override_cfg(SDMMCWAB), + mc_make_sid_override_cfg(VICSRD), + mc_make_sid_override_cfg(VICSWR), + mc_make_sid_override_cfg(VIW), + mc_make_sid_override_cfg(NVDECSRD), + mc_make_sid_override_cfg(NVDECSWR), + mc_make_sid_override_cfg(APER), + mc_make_sid_override_cfg(APEW), + mc_make_sid_override_cfg(NVJPGSRD), + mc_make_sid_override_cfg(NVJPGSWR), + mc_make_sid_override_cfg(SESRD), + mc_make_sid_override_cfg(SESWR), + mc_make_sid_override_cfg(AXIAPR), + mc_make_sid_override_cfg(AXIAPW), + mc_make_sid_override_cfg(ETRR), + mc_make_sid_override_cfg(ETRW), + mc_make_sid_override_cfg(TSECSRDB), + mc_make_sid_override_cfg(TSECSWRB), + mc_make_sid_override_cfg(AXISR), + mc_make_sid_override_cfg(AXISW), + mc_make_sid_override_cfg(EQOSR), + mc_make_sid_override_cfg(EQOSW), + mc_make_sid_override_cfg(UFSHCR), + mc_make_sid_override_cfg(UFSHCW), + mc_make_sid_override_cfg(NVDISPLAYR), + mc_make_sid_override_cfg(BPMPR), + mc_make_sid_override_cfg(BPMPW), + mc_make_sid_override_cfg(BPMPDMAR), + mc_make_sid_override_cfg(BPMPDMAW), + mc_make_sid_override_cfg(AONR), + mc_make_sid_override_cfg(AONW), + mc_make_sid_override_cfg(AONDMAR), + mc_make_sid_override_cfg(AONDMAW), + mc_make_sid_override_cfg(SCER), + mc_make_sid_override_cfg(SCEW), + mc_make_sid_override_cfg(SCEDMAR), + mc_make_sid_override_cfg(SCEDMAW), + mc_make_sid_override_cfg(APEDMAR), + mc_make_sid_override_cfg(APEDMAW), + mc_make_sid_override_cfg(NVDISPLAYR1), + mc_make_sid_override_cfg(VICSRD1), + mc_make_sid_override_cfg(NVDECSRD1), + mc_make_sid_override_cfg(VIFALR), + mc_make_sid_override_cfg(VIFALW), + mc_make_sid_override_cfg(DLA0RDA), + mc_make_sid_override_cfg(DLA0FALRDB), + mc_make_sid_override_cfg(DLA0WRA), + mc_make_sid_override_cfg(DLA0FALWRB), + mc_make_sid_override_cfg(DLA1RDA), + mc_make_sid_override_cfg(DLA1FALRDB), + mc_make_sid_override_cfg(DLA1WRA), + mc_make_sid_override_cfg(DLA1FALWRB), + mc_make_sid_override_cfg(PVA0RDA), + mc_make_sid_override_cfg(PVA0RDB), + mc_make_sid_override_cfg(PVA0RDC), + mc_make_sid_override_cfg(PVA0WRA), + mc_make_sid_override_cfg(PVA0WRB), + mc_make_sid_override_cfg(PVA0WRC), + mc_make_sid_override_cfg(PVA1RDA), + mc_make_sid_override_cfg(PVA1RDB), + mc_make_sid_override_cfg(PVA1RDC), + mc_make_sid_override_cfg(PVA1WRA), + mc_make_sid_override_cfg(PVA1WRB), + mc_make_sid_override_cfg(PVA1WRC), + mc_make_sid_override_cfg(RCER), + mc_make_sid_override_cfg(RCEW), + mc_make_sid_override_cfg(RCEDMAR), + mc_make_sid_override_cfg(RCEDMAW), + mc_make_sid_override_cfg(NVENC1SRD), + mc_make_sid_override_cfg(NVENC1SWR), + mc_make_sid_override_cfg(PCIE0R), + mc_make_sid_override_cfg(PCIE0W), + mc_make_sid_override_cfg(PCIE1R), + mc_make_sid_override_cfg(PCIE1W), + mc_make_sid_override_cfg(PCIE2AR), + mc_make_sid_override_cfg(PCIE2AW), + mc_make_sid_override_cfg(PCIE3R), + mc_make_sid_override_cfg(PCIE3W), + mc_make_sid_override_cfg(PCIE4R), + mc_make_sid_override_cfg(PCIE4W), + mc_make_sid_override_cfg(PCIE5R), + mc_make_sid_override_cfg(PCIE5W), + mc_make_sid_override_cfg(ISPFALW), + mc_make_sid_override_cfg(DLA0RDA1), + mc_make_sid_override_cfg(DLA1RDA1), + mc_make_sid_override_cfg(PVA0RDA1), + mc_make_sid_override_cfg(PVA0RDB1), + mc_make_sid_override_cfg(PVA1RDA1), + mc_make_sid_override_cfg(PVA1RDB1), + mc_make_sid_override_cfg(PCIE5R1), + mc_make_sid_override_cfg(NVENCSRD1), + mc_make_sid_override_cfg(NVENC1SRD1), + mc_make_sid_override_cfg(ISPRA1), + mc_make_sid_override_cfg(PCIE0R1), + mc_make_sid_override_cfg(MIU0R), + mc_make_sid_override_cfg(MIU0W), + mc_make_sid_override_cfg(MIU1R), + mc_make_sid_override_cfg(MIU1W), + mc_make_sid_override_cfg(MIU2R), + mc_make_sid_override_cfg(MIU2W), + mc_make_sid_override_cfg(MIU3R), + mc_make_sid_override_cfg(MIU3W), + mc_smmu_bypass_cfg, /* TBU settings */ + _END_OF_TABLE_, +}; + +/******************************************************************************* + * Handler to return the pointer to the MC's context struct + ******************************************************************************/ +static mc_regs_t *tegra194_get_mc_system_suspend_ctx(void) +{ + /* index of _END_OF_TABLE_ */ + tegra194_mc_context[0].val = (uint32_t)ARRAY_SIZE(tegra194_mc_context) - 1U; + + return tegra194_mc_context; +} + /******************************************************************************* * Struct to hold the memory controller settings ******************************************************************************/ @@ -306,7 +574,8 @@ static tegra_mc_settings_t tegra194_mc_settings = { .streamid_override_cfg = tegra194_streamid_override_regs, .num_streamid_override_cfgs = (uint32_t)ARRAY_SIZE(tegra194_streamid_override_regs), .streamid_security_cfg = tegra194_streamid_sec_cfgs, - .num_streamid_security_cfgs = (uint32_t)ARRAY_SIZE(tegra194_streamid_sec_cfgs) + .num_streamid_security_cfgs = (uint32_t)ARRAY_SIZE(tegra194_streamid_sec_cfgs), + .get_mc_system_suspend_ctx = tegra194_get_mc_system_suspend_ctx }; /******************************************************************************* diff --git a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c index 3c91af4bc..d92025b8b 100644 --- a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -118,7 +119,7 @@ int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) const plat_local_state_t *pwr_domain_state; uint8_t stateid_afflvl0, stateid_afflvl2; plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); - uint64_t smmu_ctx_base; + uint64_t mc_ctx_base; uint32_t val; mce_cstate_info_t sc7_cstate_info = { .cluster = (uint32_t)TEGRA_NVG_CLUSTER_CC6, @@ -151,10 +152,10 @@ int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) val = mmio_read_32(TEGRA_MISC_BASE + MISCREG_PFCFG); mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SECURE_BOOTP_FCFG, val); - /* save SMMU context */ - smmu_ctx_base = params_from_bl2->tzdram_base + - tegra194_get_smmu_ctx_offset(); - tegra_smmu_save_context((uintptr_t)smmu_ctx_base); + /* save MC context */ + mc_ctx_base = params_from_bl2->tzdram_base + + tegra194_get_mc_ctx_offset(); + tegra_mc_save_context((uintptr_t)mc_ctx_base); /* * Suspend SE, RNG1 and PKA1 only on silcon and fpga, diff --git a/plat/nvidia/tegra/soc/t194/plat_smmu.c b/plat/nvidia/tegra/soc/t194/plat_smmu.c index 3b4a3803c..310e95104 100644 --- a/plat/nvidia/tegra/soc/t194/plat_smmu.c +++ b/plat/nvidia/tegra/soc/t194/plat_smmu.c @@ -8,7 +8,6 @@ #include #include #include -#include #define BOARD_SYSTEM_FPGA_BASE U(1) #define BASE_CONFIG_SMMU_DEVICES U(2) @@ -19,276 +18,6 @@ static uint32_t tegra_misc_read_32(uint32_t off) return mmio_read_32((uintptr_t)TEGRA_MISC_BASE + off); } -/******************************************************************************* - * Array to hold SMMU context for Tegra194 - ******************************************************************************/ -static __attribute__((aligned(16))) smmu_regs_t tegra194_smmu_context[] = { - _START_OF_TABLE_, - mc_make_sid_security_cfg(HDAR), - mc_make_sid_security_cfg(HOST1XDMAR), - mc_make_sid_security_cfg(NVENCSRD), - mc_make_sid_security_cfg(SATAR), - mc_make_sid_security_cfg(NVENCSWR), - mc_make_sid_security_cfg(HDAW), - mc_make_sid_security_cfg(SATAW), - mc_make_sid_security_cfg(ISPRA), - mc_make_sid_security_cfg(ISPFALR), - mc_make_sid_security_cfg(ISPWA), - mc_make_sid_security_cfg(ISPWB), - mc_make_sid_security_cfg(XUSB_HOSTR), - mc_make_sid_security_cfg(XUSB_HOSTW), - mc_make_sid_security_cfg(XUSB_DEVR), - mc_make_sid_security_cfg(XUSB_DEVW), - mc_make_sid_security_cfg(TSECSRD), - mc_make_sid_security_cfg(TSECSWR), - mc_make_sid_security_cfg(SDMMCRA), - mc_make_sid_security_cfg(SDMMCR), - mc_make_sid_security_cfg(SDMMCRAB), - mc_make_sid_security_cfg(SDMMCWA), - mc_make_sid_security_cfg(SDMMCW), - mc_make_sid_security_cfg(SDMMCWAB), - mc_make_sid_security_cfg(VICSRD), - mc_make_sid_security_cfg(VICSWR), - mc_make_sid_security_cfg(VIW), - mc_make_sid_security_cfg(NVDECSRD), - mc_make_sid_security_cfg(NVDECSWR), - mc_make_sid_security_cfg(APER), - mc_make_sid_security_cfg(APEW), - mc_make_sid_security_cfg(NVJPGSRD), - mc_make_sid_security_cfg(NVJPGSWR), - mc_make_sid_security_cfg(SESRD), - mc_make_sid_security_cfg(SESWR), - mc_make_sid_security_cfg(AXIAPR), - mc_make_sid_security_cfg(AXIAPW), - mc_make_sid_security_cfg(ETRR), - mc_make_sid_security_cfg(ETRW), - mc_make_sid_security_cfg(TSECSRDB), - mc_make_sid_security_cfg(TSECSWRB), - mc_make_sid_security_cfg(AXISR), - mc_make_sid_security_cfg(AXISW), - mc_make_sid_security_cfg(EQOSR), - mc_make_sid_security_cfg(EQOSW), - mc_make_sid_security_cfg(UFSHCR), - mc_make_sid_security_cfg(UFSHCW), - mc_make_sid_security_cfg(NVDISPLAYR), - mc_make_sid_security_cfg(BPMPR), - mc_make_sid_security_cfg(BPMPW), - mc_make_sid_security_cfg(BPMPDMAR), - mc_make_sid_security_cfg(BPMPDMAW), - mc_make_sid_security_cfg(AONR), - mc_make_sid_security_cfg(AONW), - mc_make_sid_security_cfg(AONDMAR), - mc_make_sid_security_cfg(AONDMAW), - mc_make_sid_security_cfg(SCER), - mc_make_sid_security_cfg(SCEW), - mc_make_sid_security_cfg(SCEDMAR), - mc_make_sid_security_cfg(SCEDMAW), - mc_make_sid_security_cfg(APEDMAR), - mc_make_sid_security_cfg(APEDMAW), - mc_make_sid_security_cfg(NVDISPLAYR1), - mc_make_sid_security_cfg(VICSRD1), - mc_make_sid_security_cfg(NVDECSRD1), - mc_make_sid_security_cfg(VIFALR), - mc_make_sid_security_cfg(VIFALW), - mc_make_sid_security_cfg(DLA0RDA), - mc_make_sid_security_cfg(DLA0FALRDB), - mc_make_sid_security_cfg(DLA0WRA), - mc_make_sid_security_cfg(DLA0FALWRB), - mc_make_sid_security_cfg(DLA1RDA), - mc_make_sid_security_cfg(DLA1FALRDB), - mc_make_sid_security_cfg(DLA1WRA), - mc_make_sid_security_cfg(DLA1FALWRB), - mc_make_sid_security_cfg(PVA0RDA), - mc_make_sid_security_cfg(PVA0RDB), - mc_make_sid_security_cfg(PVA0RDC), - mc_make_sid_security_cfg(PVA0WRA), - mc_make_sid_security_cfg(PVA0WRB), - mc_make_sid_security_cfg(PVA0WRC), - mc_make_sid_security_cfg(PVA1RDA), - mc_make_sid_security_cfg(PVA1RDB), - mc_make_sid_security_cfg(PVA1RDC), - mc_make_sid_security_cfg(PVA1WRA), - mc_make_sid_security_cfg(PVA1WRB), - mc_make_sid_security_cfg(PVA1WRC), - mc_make_sid_security_cfg(RCER), - mc_make_sid_security_cfg(RCEW), - mc_make_sid_security_cfg(RCEDMAR), - mc_make_sid_security_cfg(RCEDMAW), - mc_make_sid_security_cfg(NVENC1SRD), - mc_make_sid_security_cfg(NVENC1SWR), - mc_make_sid_security_cfg(PCIE0R), - mc_make_sid_security_cfg(PCIE0W), - mc_make_sid_security_cfg(PCIE1R), - mc_make_sid_security_cfg(PCIE1W), - mc_make_sid_security_cfg(PCIE2AR), - mc_make_sid_security_cfg(PCIE2AW), - mc_make_sid_security_cfg(PCIE3R), - mc_make_sid_security_cfg(PCIE3W), - mc_make_sid_security_cfg(PCIE4R), - mc_make_sid_security_cfg(PCIE4W), - mc_make_sid_security_cfg(PCIE5R), - mc_make_sid_security_cfg(PCIE5W), - mc_make_sid_security_cfg(ISPFALW), - mc_make_sid_security_cfg(DLA0RDA1), - mc_make_sid_security_cfg(DLA1RDA1), - mc_make_sid_security_cfg(PVA0RDA1), - mc_make_sid_security_cfg(PVA0RDB1), - mc_make_sid_security_cfg(PVA1RDA1), - mc_make_sid_security_cfg(PVA1RDB1), - mc_make_sid_security_cfg(PCIE5R1), - mc_make_sid_security_cfg(NVENCSRD1), - mc_make_sid_security_cfg(NVENC1SRD1), - mc_make_sid_security_cfg(ISPRA1), - mc_make_sid_security_cfg(PCIE0R1), - mc_make_sid_security_cfg(MIU0R), - mc_make_sid_security_cfg(MIU0W), - mc_make_sid_security_cfg(MIU1R), - mc_make_sid_security_cfg(MIU1W), - mc_make_sid_security_cfg(MIU2R), - mc_make_sid_security_cfg(MIU2W), - mc_make_sid_security_cfg(MIU3R), - mc_make_sid_security_cfg(MIU3W), - mc_make_sid_override_cfg(HDAR), - mc_make_sid_override_cfg(HOST1XDMAR), - mc_make_sid_override_cfg(NVENCSRD), - mc_make_sid_override_cfg(SATAR), - mc_make_sid_override_cfg(NVENCSWR), - mc_make_sid_override_cfg(HDAW), - mc_make_sid_override_cfg(SATAW), - mc_make_sid_override_cfg(ISPRA), - mc_make_sid_override_cfg(ISPFALR), - mc_make_sid_override_cfg(ISPWA), - mc_make_sid_override_cfg(ISPWB), - mc_make_sid_override_cfg(XUSB_HOSTR), - mc_make_sid_override_cfg(XUSB_HOSTW), - mc_make_sid_override_cfg(XUSB_DEVR), - mc_make_sid_override_cfg(XUSB_DEVW), - mc_make_sid_override_cfg(TSECSRD), - mc_make_sid_override_cfg(TSECSWR), - mc_make_sid_override_cfg(SDMMCRA), - mc_make_sid_override_cfg(SDMMCR), - mc_make_sid_override_cfg(SDMMCRAB), - mc_make_sid_override_cfg(SDMMCWA), - mc_make_sid_override_cfg(SDMMCW), - mc_make_sid_override_cfg(SDMMCWAB), - mc_make_sid_override_cfg(VICSRD), - mc_make_sid_override_cfg(VICSWR), - mc_make_sid_override_cfg(VIW), - mc_make_sid_override_cfg(NVDECSRD), - mc_make_sid_override_cfg(NVDECSWR), - mc_make_sid_override_cfg(APER), - mc_make_sid_override_cfg(APEW), - mc_make_sid_override_cfg(NVJPGSRD), - mc_make_sid_override_cfg(NVJPGSWR), - mc_make_sid_override_cfg(SESRD), - mc_make_sid_override_cfg(SESWR), - mc_make_sid_override_cfg(AXIAPR), - mc_make_sid_override_cfg(AXIAPW), - mc_make_sid_override_cfg(ETRR), - mc_make_sid_override_cfg(ETRW), - mc_make_sid_override_cfg(TSECSRDB), - mc_make_sid_override_cfg(TSECSWRB), - mc_make_sid_override_cfg(AXISR), - mc_make_sid_override_cfg(AXISW), - mc_make_sid_override_cfg(EQOSR), - mc_make_sid_override_cfg(EQOSW), - mc_make_sid_override_cfg(UFSHCR), - mc_make_sid_override_cfg(UFSHCW), - mc_make_sid_override_cfg(NVDISPLAYR), - mc_make_sid_override_cfg(BPMPR), - mc_make_sid_override_cfg(BPMPW), - mc_make_sid_override_cfg(BPMPDMAR), - mc_make_sid_override_cfg(BPMPDMAW), - mc_make_sid_override_cfg(AONR), - mc_make_sid_override_cfg(AONW), - mc_make_sid_override_cfg(AONDMAR), - mc_make_sid_override_cfg(AONDMAW), - mc_make_sid_override_cfg(SCER), - mc_make_sid_override_cfg(SCEW), - mc_make_sid_override_cfg(SCEDMAR), - mc_make_sid_override_cfg(SCEDMAW), - mc_make_sid_override_cfg(APEDMAR), - mc_make_sid_override_cfg(APEDMAW), - mc_make_sid_override_cfg(NVDISPLAYR1), - mc_make_sid_override_cfg(VICSRD1), - mc_make_sid_override_cfg(NVDECSRD1), - mc_make_sid_override_cfg(VIFALR), - mc_make_sid_override_cfg(VIFALW), - mc_make_sid_override_cfg(DLA0RDA), - mc_make_sid_override_cfg(DLA0FALRDB), - mc_make_sid_override_cfg(DLA0WRA), - mc_make_sid_override_cfg(DLA0FALWRB), - mc_make_sid_override_cfg(DLA1RDA), - mc_make_sid_override_cfg(DLA1FALRDB), - mc_make_sid_override_cfg(DLA1WRA), - mc_make_sid_override_cfg(DLA1FALWRB), - mc_make_sid_override_cfg(PVA0RDA), - mc_make_sid_override_cfg(PVA0RDB), - mc_make_sid_override_cfg(PVA0RDC), - mc_make_sid_override_cfg(PVA0WRA), - mc_make_sid_override_cfg(PVA0WRB), - mc_make_sid_override_cfg(PVA0WRC), - mc_make_sid_override_cfg(PVA1RDA), - mc_make_sid_override_cfg(PVA1RDB), - mc_make_sid_override_cfg(PVA1RDC), - mc_make_sid_override_cfg(PVA1WRA), - mc_make_sid_override_cfg(PVA1WRB), - mc_make_sid_override_cfg(PVA1WRC), - mc_make_sid_override_cfg(RCER), - mc_make_sid_override_cfg(RCEW), - mc_make_sid_override_cfg(RCEDMAR), - mc_make_sid_override_cfg(RCEDMAW), - mc_make_sid_override_cfg(NVENC1SRD), - mc_make_sid_override_cfg(NVENC1SWR), - mc_make_sid_override_cfg(PCIE0R), - mc_make_sid_override_cfg(PCIE0W), - mc_make_sid_override_cfg(PCIE1R), - mc_make_sid_override_cfg(PCIE1W), - mc_make_sid_override_cfg(PCIE2AR), - mc_make_sid_override_cfg(PCIE2AW), - mc_make_sid_override_cfg(PCIE3R), - mc_make_sid_override_cfg(PCIE3W), - mc_make_sid_override_cfg(PCIE4R), - mc_make_sid_override_cfg(PCIE4W), - mc_make_sid_override_cfg(PCIE5R), - mc_make_sid_override_cfg(PCIE5W), - mc_make_sid_override_cfg(ISPFALW), - mc_make_sid_override_cfg(DLA0RDA1), - mc_make_sid_override_cfg(DLA1RDA1), - mc_make_sid_override_cfg(PVA0RDA1), - mc_make_sid_override_cfg(PVA0RDB1), - mc_make_sid_override_cfg(PVA1RDA1), - mc_make_sid_override_cfg(PVA1RDB1), - mc_make_sid_override_cfg(PCIE5R1), - mc_make_sid_override_cfg(NVENCSRD1), - mc_make_sid_override_cfg(NVENC1SRD1), - mc_make_sid_override_cfg(ISPRA1), - mc_make_sid_override_cfg(PCIE0R1), - mc_make_sid_override_cfg(MIU0R), - mc_make_sid_override_cfg(MIU0W), - mc_make_sid_override_cfg(MIU1R), - mc_make_sid_override_cfg(MIU1W), - mc_make_sid_override_cfg(MIU2R), - mc_make_sid_override_cfg(MIU2W), - mc_make_sid_override_cfg(MIU3R), - mc_make_sid_override_cfg(MIU3W), - smmu_make_cfg(TEGRA_SMMU0_BASE), - smmu_make_cfg(TEGRA_SMMU2_BASE), - smmu_bypass_cfg, /* TBU settings */ - _END_OF_TABLE_, -}; - -/******************************************************************************* - * Handler to return the pointer to the SMMU's context struct - ******************************************************************************/ -smmu_regs_t *plat_get_smmu_ctx(void) -{ - /* index of _END_OF_TABLE_ */ - tegra194_smmu_context[0].val = (uint32_t)ARRAY_SIZE(tegra194_smmu_context) - 1U; - - return tegra194_smmu_context; -} - /******************************************************************************* * Handler to return the support SMMU devices number ******************************************************************************/ diff --git a/plat/nvidia/tegra/soc/t194/plat_trampoline.S b/plat/nvidia/tegra/soc/t194/plat_trampoline.S index 540c2019c..819920f02 100644 --- a/plat/nvidia/tegra/soc/t194/plat_trampoline.S +++ b/plat/nvidia/tegra/soc/t194/plat_trampoline.S @@ -12,7 +12,7 @@ #define TEGRA194_STATE_SYSTEM_SUSPEND 0x5C7 #define TEGRA194_STATE_SYSTEM_RESUME 0x600D -#define TEGRA194_SMMU_CTX_SIZE 0x80D +#define TEGRA194_MC_CTX_SIZE 0xFB .align 4 .globl tegra194_cpu_reset_handler @@ -69,8 +69,8 @@ endfunc tegra194_cpu_reset_handler * * 0x0000: secure world's entrypoint * 0x0008: BL31 size (RO + RW) - * 0x0010: SMMU context start - * 0x2490: SMMU context end + * 0x0010: MC context start + * 0x2490: MC context end */ .align 4 @@ -79,14 +79,13 @@ endfunc tegra194_cpu_reset_handler __tegra194_cpu_reset_handler_data: .quad tegra_secure_entrypoint .quad __BL31_END__ - BL31_BASE - .globl __tegra194_system_suspend_state __tegra194_system_suspend_state: .quad 0 .align 4 -__tegra194_smmu_context: - .rept TEGRA194_SMMU_CTX_SIZE +__tegra194_mc_context: + .rept TEGRA194_MC_CTX_SIZE .quad 0 .endr .size __tegra194_cpu_reset_handler_data, \ @@ -98,7 +97,7 @@ __tegra194_cpu_reset_handler_end: .globl tegra194_get_cpu_reset_handler_size .globl tegra194_get_cpu_reset_handler_base - .globl tegra194_get_smmu_ctx_offset + .globl tegra194_get_mc_ctx_offset .globl tegra194_set_system_suspend_entry /* return size of the CPU reset handler */ @@ -115,13 +114,13 @@ func tegra194_get_cpu_reset_handler_base ret endfunc tegra194_get_cpu_reset_handler_base -/* return the size of the SMMU context */ -func tegra194_get_smmu_ctx_offset - adr x0, __tegra194_smmu_context +/* return the size of the MC context */ +func tegra194_get_mc_ctx_offset + adr x0, __tegra194_mc_context adr x1, tegra194_cpu_reset_handler sub x0, x0, x1 ret -endfunc tegra194_get_smmu_ctx_offset +endfunc tegra194_get_mc_ctx_offset /* set system suspend state before SC7 entry */ func tegra194_set_system_suspend_entry -- cgit v1.2.3 From 91dd7edd31c6626214c1198f60043067bba42f7c Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Mon, 10 Dec 2018 13:20:49 -0800 Subject: Tegra: smmu: export handlers to read/write SMMU registers This patch exports the SMMU register read/write handlers for platforms. Change-Id: If92f0d3ce820e4997c090b48be7614407bb582da Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/drivers/smmu/smmu.c | 54 -------------------------- plat/nvidia/tegra/include/drivers/smmu.h | 57 +++++++++++++++++++++++++++- 2 files changed, 56 insertions(+), 55 deletions(-) diff --git a/plat/nvidia/tegra/common/drivers/smmu/smmu.c b/plat/nvidia/tegra/common/drivers/smmu/smmu.c index cc07d6549..a4a4354e8 100644 --- a/plat/nvidia/tegra/common/drivers/smmu/smmu.c +++ b/plat/nvidia/tegra/common/drivers/smmu/smmu.c @@ -18,60 +18,6 @@ extern void memcpy16(void *dest, const void *src, unsigned int length); -/* SMMU IDs currently supported by the driver */ -enum { - TEGRA_SMMU0 = 0U, - TEGRA_SMMU1, - TEGRA_SMMU2 -}; - -static uint32_t tegra_smmu_read_32(uint32_t smmu_id, uint32_t off) -{ - uint32_t ret = 0U; - -#if defined(TEGRA_SMMU0_BASE) - if (smmu_id == TEGRA_SMMU0) { - ret = mmio_read_32(TEGRA_SMMU0_BASE + (uint64_t)off); - } -#endif - -#if defined(TEGRA_SMMU1_BASE) - if (smmu_id == TEGRA_SMMU1) { - ret = mmio_read_32(TEGRA_SMMU1_BASE + (uint64_t)off); - } -#endif - -#if defined(TEGRA_SMMU2_BASE) - if (smmu_id == TEGRA_SMMU2) { - ret = mmio_read_32(TEGRA_SMMU2_BASE + (uint64_t)off); - } -#endif - - return ret; -} - -static void tegra_smmu_write_32(uint32_t smmu_id, - uint32_t off, uint32_t val) -{ -#if defined(TEGRA_SMMU0_BASE) - if (smmu_id == TEGRA_SMMU0) { - mmio_write_32(TEGRA_SMMU0_BASE + (uint64_t)off, val); - } -#endif - -#if defined(TEGRA_SMMU1_BASE) - if (smmu_id == TEGRA_SMMU1) { - mmio_write_32(TEGRA_SMMU1_BASE + (uint64_t)off, val); - } -#endif - -#if defined(TEGRA_SMMU2_BASE) - if (smmu_id == TEGRA_SMMU2) { - mmio_write_32(TEGRA_SMMU2_BASE + (uint64_t)off, val); - } -#endif -} - #define SMMU_NUM_CONTEXTS 64U #define SMMU_CONTEXT_BANK_MAX_IDX 64U diff --git a/plat/nvidia/tegra/include/drivers/smmu.h b/plat/nvidia/tegra/include/drivers/smmu.h index 417208e3c..601864fb5 100644 --- a/plat/nvidia/tegra/include/drivers/smmu.h +++ b/plat/nvidia/tegra/include/drivers/smmu.h @@ -23,13 +23,68 @@ #define SMMU_GSR0_PGSIZE_SHIFT 16U #define SMMU_GSR0_PGSIZE_4K (0U << SMMU_GSR0_PGSIZE_SHIFT) #define SMMU_GSR0_PGSIZE_64K (1U << SMMU_GSR0_PGSIZE_SHIFT) -#define SMMU_ACR_CACHE_LOCK_ENABLE_BIT (1U << 26) +#define SMMU_ACR_CACHE_LOCK_ENABLE_BIT (1ULL << 26U) +#define SMMU_GSR0_PER (0x20200U) /******************************************************************************* * SMMU Global Aux. Control Register ******************************************************************************/ #define SMMU_CBn_ACTLR_CPRE_BIT (1ULL << 1U) +/* SMMU IDs currently supported by the driver */ +enum { + TEGRA_SMMU0 = 0U, + TEGRA_SMMU1 = 1U, + TEGRA_SMMU2 = 2U +}; + +static inline uint32_t tegra_smmu_read_32(uint32_t smmu_id, uint32_t off) +{ + uint32_t ret = 0U; + +#if defined(TEGRA_SMMU0_BASE) + if (smmu_id == TEGRA_SMMU0) { + ret = mmio_read_32(TEGRA_SMMU0_BASE + (uint64_t)off); + } +#endif + +#if defined(TEGRA_SMMU1_BASE) + if (smmu_id == TEGRA_SMMU1) { + ret = mmio_read_32(TEGRA_SMMU1_BASE + (uint64_t)off); + } +#endif + +#if defined(TEGRA_SMMU2_BASE) + if (smmu_id == TEGRA_SMMU2) { + ret = mmio_read_32(TEGRA_SMMU2_BASE + (uint64_t)off); + } +#endif + + return ret; +} + +static inline void tegra_smmu_write_32(uint32_t smmu_id, + uint32_t off, uint32_t val) +{ +#if defined(TEGRA_SMMU0_BASE) + if (smmu_id == TEGRA_SMMU0) { + mmio_write_32(TEGRA_SMMU0_BASE + (uint64_t)off, val); + } +#endif + +#if defined(TEGRA_SMMU1_BASE) + if (smmu_id == TEGRA_SMMU1) { + mmio_write_32(TEGRA_SMMU1_BASE + (uint64_t)off, val); + } +#endif + +#if defined(TEGRA_SMMU2_BASE) + if (smmu_id == TEGRA_SMMU2) { + mmio_write_32(TEGRA_SMMU2_BASE + (uint64_t)off, val); + } +#endif +} + void tegra_smmu_init(void); uint32_t plat_get_num_smmu_devices(void); -- cgit v1.2.3 From d205cda6fdd3b2c44f3983fe0f6ada1573d5e85c Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Fri, 10 Aug 2018 09:55:25 -0700 Subject: spd: tlkd: secure timer interrupt handler This patch adds an interrupt handler for TLK. On receiving an interrupt, the source of the interrupt is determined and the interrupt is marked complete. The IRQ number is passed to TLK along with a special SMC function ID. TLK issues an SMC to notify completion of the interrupt handler in the S-EL1 world. Change-Id: I76f28cee6537245c5e448d2078f86312219cea1a Signed-off-by: Varun Wadekar --- include/bl32/payloads/tlk.h | 2 + services/spd/tlkd/tlkd_main.c | 89 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 90 insertions(+), 1 deletion(-) diff --git a/include/bl32/payloads/tlk.h b/include/bl32/payloads/tlk.h index ce8e3e890..fe6f3528b 100644 --- a/include/bl32/payloads/tlk.h +++ b/include/bl32/payloads/tlk.h @@ -27,6 +27,7 @@ #define TLK_SYSTEM_SUSPEND TLK_TOS_YIELD_FID(0xE001) #define TLK_SYSTEM_RESUME TLK_TOS_YIELD_FID(0xE002) #define TLK_SYSTEM_OFF TLK_TOS_YIELD_FID(0xE003) +#define TLK_IRQ_FIRED TLK_TOS_YIELD_FID(0xE004) /* * SMC function IDs that TLK uses to signal various forms of completions @@ -39,6 +40,7 @@ #define TLK_SUSPEND_DONE (0x32000005 | (ULL(1) << 31)) #define TLK_RESUME_DONE (0x32000006 | (ULL(1) << 31)) #define TLK_SYSTEM_OFF_DONE (0x32000007 | (ULL(1) << 31)) +#define TLK_IRQ_DONE (0x32000008 | (ULL(1) << 31)) /* * Trusted Application specific function IDs diff --git a/services/spd/tlkd/tlkd_main.c b/services/spd/tlkd/tlkd_main.c index 3cfc52db4..32ae8ecc9 100644 --- a/services/spd/tlkd/tlkd_main.c +++ b/services/spd/tlkd/tlkd_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -14,6 +14,7 @@ * responsible for initialising and maintaining communication with the SP. ******************************************************************************/ #include +#include #include #include @@ -48,6 +49,50 @@ DEFINE_SVC_UUID2(tlk_uuid, static int32_t tlkd_init(void); +/******************************************************************************* + * Secure Payload Dispatcher's timer interrupt handler + ******************************************************************************/ +static uint64_t tlkd_interrupt_handler(uint32_t id, + uint32_t flags, + void *handle, + void *cookie) +{ + cpu_context_t *s_cpu_context; + int irq = plat_ic_get_pending_interrupt_id(); + + /* acknowledge the interrupt and mark it complete */ + (void)plat_ic_acknowledge_interrupt(); + plat_ic_end_of_interrupt(irq); + + /* + * Disable the routing of NS interrupts from secure world to + * EL3 while interrupted on this core. + */ + disable_intr_rm_local(INTR_TYPE_S_EL1, SECURE); + + /* Check the security state when the exception was generated */ + assert(get_interrupt_src_ss(flags) == NON_SECURE); + assert(handle == cm_get_context(NON_SECURE)); + + /* Save non-secure state */ + cm_el1_sysregs_context_save(NON_SECURE); + + /* Get a reference to the secure context */ + s_cpu_context = cm_get_context(SECURE); + assert(s_cpu_context); + + /* + * Restore non-secure state. There is no need to save the + * secure system register context since the SP was supposed + * to preserve it during S-EL1 interrupt handling. + */ + cm_el1_sysregs_context_restore(SECURE); + cm_set_next_eret_context(SECURE); + + /* Provide the IRQ number to the SPD */ + SMC_RET4(s_cpu_context, (uint32_t)TLK_IRQ_FIRED, 0, (uint32_t)irq, 0); +} + /******************************************************************************* * Secure Payload Dispatcher setup. The SPD finds out the SP entrypoint and type * (aarch32/aarch64) if not already known and initialises the context for entry @@ -56,6 +101,8 @@ static int32_t tlkd_init(void); static int32_t tlkd_setup(void) { entry_point_info_t *tlk_ep_info; + uint32_t flags; + int32_t ret; /* * Get information about the Secure Payload (BL32) image. Its @@ -86,6 +133,18 @@ static int32_t tlkd_setup(void) tlk_ep_info->pc, &tlk_ctx); + /* get a list of all S-EL1 IRQs from the platform */ + + /* register interrupt handler */ + flags = 0; + set_interrupt_rm_flag(flags, NON_SECURE); + ret = register_interrupt_type_handler(INTR_TYPE_S_EL1, + tlkd_interrupt_handler, + flags); + if (ret != 0) { + ERROR("failed to register tlkd interrupt handler (%d)\n", ret); + } + /* * All TLK SPD initialization done. Now register our init function * with BL31 for deferred invocation @@ -384,6 +443,34 @@ static uintptr_t tlkd_smc_handler(uint32_t smc_fid, tlkd_synchronous_sp_exit(&tlk_ctx, x1); break; + /* + * This function ID is used by SP to indicate that it has completed + * handling the secure interrupt. + */ + case TLK_IRQ_DONE: + + if (ns) + SMC_RET1(handle, SMC_UNK); + + assert(handle == cm_get_context(SECURE)); + + /* save secure world context */ + cm_el1_sysregs_context_save(SECURE); + + /* Get a reference to the non-secure context */ + ns_cpu_context = cm_get_context(NON_SECURE); + assert(ns_cpu_context); + + /* + * Restore non-secure state. There is no need to save the + * secure system register context since the SP was supposed + * to preserve it during S-EL1 interrupt handling. + */ + cm_el1_sysregs_context_restore(NON_SECURE); + cm_set_next_eret_context(NON_SECURE); + + SMC_RET0(ns_cpu_context); + /* * Return the number of service function IDs implemented to * provide service to non-secure -- cgit v1.2.3 From f8827c60c743e0812fac847d125fcd1e1ee69ca0 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Fri, 10 Aug 2018 10:17:31 -0700 Subject: Tegra210: support for secure physical timer This patch enables on-chip timer1 interrupts for Tegra210 platforms. Change-Id: Ic7417dc0e69264d7c28aa012fe2322cd30838f3e Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/include/t210/tegra_def.h | 5 +++++ plat/nvidia/tegra/soc/t210/plat_setup.c | 2 ++ 2 files changed, 7 insertions(+) diff --git a/plat/nvidia/tegra/include/t210/tegra_def.h b/plat/nvidia/tegra/include/t210/tegra_def.h index e8bce5e05..f3013a8a5 100644 --- a/plat/nvidia/tegra/include/t210/tegra_def.h +++ b/plat/nvidia/tegra/include/t210/tegra_def.h @@ -43,6 +43,11 @@ ******************************************************************************/ #define SC7ENTRY_FW_HEADER_SIZE_BYTES U(0x400) +/******************************************************************************* + * Counter-timer physical secure timer PPI + ******************************************************************************/ +#define TEGRA210_TIMER1_IRQ 32 + /******************************************************************************* * iRAM memory constants ******************************************************************************/ diff --git a/plat/nvidia/tegra/soc/t210/plat_setup.c b/plat/nvidia/tegra/soc/t210/plat_setup.c index 933e925ec..6d014bf2c 100644 --- a/plat/nvidia/tegra/soc/t210/plat_setup.c +++ b/plat/nvidia/tegra/soc/t210/plat_setup.c @@ -179,6 +179,8 @@ void plat_early_platform_setup(void) /* Secure IRQs for Tegra186 */ static const interrupt_prop_t tegra210_interrupt_props[] = { + INTR_PROP_DESC(TEGRA210_TIMER1_IRQ, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE), INTR_PROP_DESC(TEGRA210_WDT_CPU_LEGACY_FIQ, GIC_HIGHEST_SEC_PRIORITY, GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE), }; -- cgit v1.2.3 From b8dbf073748161db0173546ab18f8f793866f5e5 Mon Sep 17 00:00:00 2001 From: Kalyani Chidambaram Date: Fri, 21 Sep 2018 10:36:59 -0700 Subject: Tegra210: Remove "unsupported func ID" error msg The platform sip is reporting a "unsupported function ID" if the smc function id is not pmc command. When actually the smc function id could be specific to the tegra sip handler. This patch removes the error reported. Change-Id: Ia3c8545d345746c5eea6d75b9e6957ca23ae9ca3 Signed-off-by: Kalyani Chidambaram --- plat/nvidia/tegra/soc/t210/plat_sip_calls.c | 1 - 1 file changed, 1 deletion(-) diff --git a/plat/nvidia/tegra/soc/t210/plat_sip_calls.c b/plat/nvidia/tegra/soc/t210/plat_sip_calls.c index 7d26fe795..904f8d62e 100644 --- a/plat/nvidia/tegra/soc/t210/plat_sip_calls.c +++ b/plat/nvidia/tegra/soc/t210/plat_sip_calls.c @@ -88,7 +88,6 @@ int plat_sip_handler(uint32_t smc_fid, return -EINVAL; } } else { - ERROR("%s: unsupported function ID\n", __func__); return -ENOTSUP; } return 0; -- cgit v1.2.3 From 6138ffbc12f840c44cb214d9d04270c7badc87f9 Mon Sep 17 00:00:00 2001 From: Madhukar Pappireddy Date: Fri, 21 Feb 2020 14:01:44 -0600 Subject: plat/arm/fvp: populate pwr domain descriptor dynamically The motivation behind this patch and following patches is to extract information about the platform in runtime rather than depending on compile time macros such as FVP_CLUSTER_COUNT. This partially enables us to use a single binary for a family of platforms which all have similar hardware capabilities but differ in configurations. we populate the data structure describing the power domain hierarchy of the platform dynamically by querying the number of clusters and cpus using fconf getter APIs. Compile time macro such as FVP_CLUSTER_COUNT is still needed as it determines the size of related data structures. Note that the cpu-map node in HW_CONFIG dts represents a logical hierarchy of power domains of CPU. However, in reality, the power domains may not have been physically built in such hierarchy. Change-Id: Ibcbb5ca7b2c969f8ad03ab2eab289725245af7a9 Signed-off-by: Madhukar Pappireddy --- plat/arm/board/fvp/fvp_topology.c | 46 ++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/plat/arm/board/fvp/fvp_topology.c b/plat/arm/board/fvp/fvp_topology.c index 24e79b4d4..80cfbd5ce 100644 --- a/plat/arm/board/fvp/fvp_topology.c +++ b/plat/arm/board/fvp/fvp_topology.c @@ -1,18 +1,21 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ -#include +#include #include #include +#include #include #include #include #include +#include + /* The FVP power domain tree descriptor */ static unsigned char fvp_power_domain_tree_desc[FVP_CLUSTER_COUNT + 2]; @@ -21,24 +24,47 @@ CASSERT(((FVP_CLUSTER_COUNT > 0) && (FVP_CLUSTER_COUNT <= 256)), assert_invalid_fvp_cluster_count); /******************************************************************************* - * This function dynamically constructs the topology according to - * FVP_CLUSTER_COUNT and returns it. + * This function dynamically constructs the topology according to cpu-map node + * in HW_CONFIG dtb and returns it. ******************************************************************************/ const unsigned char *plat_get_power_domain_tree_desc(void) { - int i; + unsigned int i; + uint32_t cluster_count, cpus_per_cluster; + + /* + * fconf APIs are not supported for RESET_TO_SP_MIN, RESET_TO_BL31 and + * BL2_AT_EL3 systems. + */ +#if RESET_TO_SP_MIN || RESET_TO_BL31 || BL2_AT_EL3 + cluster_count = FVP_CLUSTER_COUNT; + cpus_per_cluster = FVP_MAX_CPUS_PER_CLUSTER * FVP_MAX_PE_PER_CPU; +#else + cluster_count = FCONF_GET_PROPERTY(hw_config, topology, plat_cluster_count); + cpus_per_cluster = FCONF_GET_PROPERTY(hw_config, topology, cluster_cpu_count); + /* Several FVP Models use the same blanket dts. Ex: FVP_Base_Cortex-A65x4 + * and FVP_Base_Cortex-A65AEx8 both use same dts but have different number of + * CPUs in the cluster, as reflected by build flags FVP_MAX_CPUS_PER_CLUSTER. + * Take the minimum of two to ensure PSCI functions do not exceed the size of + * the PSCI data structures allocated at build time. + */ + cpus_per_cluster = MIN(cpus_per_cluster, + (uint32_t)(FVP_MAX_CPUS_PER_CLUSTER * FVP_MAX_PE_PER_CPU)); + +#endif + + assert(cluster_count > 0U); + assert(cpus_per_cluster > 0U); /* * The highest level is the system level. The next level is constituted * by clusters and then cores in clusters. */ fvp_power_domain_tree_desc[0] = 1; - fvp_power_domain_tree_desc[1] = FVP_CLUSTER_COUNT; - - for (i = 0; i < FVP_CLUSTER_COUNT; i++) - fvp_power_domain_tree_desc[i + 2] = - FVP_MAX_CPUS_PER_CLUSTER * FVP_MAX_PE_PER_CPU; + fvp_power_domain_tree_desc[1] = (unsigned char)cluster_count; + for (i = 0; i < cluster_count; i++) + fvp_power_domain_tree_desc[i + 2] = (unsigned char)cpus_per_cluster; return fvp_power_domain_tree_desc; } -- cgit v1.2.3 From 01efae04954cd14abf60f9d9c82fe825528ef4a4 Mon Sep 17 00:00:00 2001 From: Aditya Angadi Date: Thu, 12 Mar 2020 10:56:18 +0530 Subject: board/rddaniel: add NSAID sources for TZC400 driver Add CLCD, HDLCD, PCI and VIRTIO devices as source interfaces for TZC filter unit to enable DMA for these devices. Change-Id: Ifad2e56b18605311936e03cfcccda573cac7e60a Signed-off-by: Aditya Angadi --- plat/arm/board/rddaniel/include/platform_def.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/plat/arm/board/rddaniel/include/platform_def.h b/plat/arm/board/rddaniel/include/platform_def.h index 790ed696b..a118ca38a 100644 --- a/plat/arm/board/rddaniel/include/platform_def.h +++ b/plat/arm/board/rddaniel/include/platform_def.h @@ -32,9 +32,19 @@ (n * TZC400_OFFSET)) #define TZC_NSAID_ALL_AP U(0) +#define TZC_NSAID_PCI U(1) +#define TZC_NSAID_HDLCD0 U(2) +#define TZC_NSAID_CLCD U(7) +#define TZC_NSAID_AP U(9) +#define TZC_NSAID_VIRTIO U(15) #define PLAT_ARM_TZC_NS_DEV_ACCESS \ - (TZC_REGION_ACCESS_RDWR(TZC_NSAID_ALL_AP)) + (TZC_REGION_ACCESS_RDWR(TZC_NSAID_ALL_AP)) | \ + (TZC_REGION_ACCESS_RDWR(TZC_NSAID_HDLCD0)) | \ + (TZC_REGION_ACCESS_RDWR(TZC_NSAID_PCI)) | \ + (TZC_REGION_ACCESS_RDWR(TZC_NSAID_AP)) | \ + (TZC_REGION_ACCESS_RDWR(TZC_NSAID_CLCD)) | \ + (TZC_REGION_ACCESS_RDWR(TZC_NSAID_VIRTIO)) /* * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes -- cgit v1.2.3 From ddc93cbaa42bba08afd5041822a386876518446b Mon Sep 17 00:00:00 2001 From: Chris Kay Date: Thu, 12 Mar 2020 13:50:26 +0000 Subject: juno/sgm: Maximize space allocated to SCP_BL2 To accommodate the increasing size of the SCP_BL2 binary, the base address of the memory region allocated to SCP_BL2 has been moved downwards from its current (mostly) arbitrary address to the beginning of the non-shared trusted SRAM. Change-Id: I086a3765bf3ea88f45525223d765dc0dbad6b434 Signed-off-by: Chris Kay --- docs/design/firmware-design.rst | 4 ++-- plat/arm/board/juno/include/platform_def.h | 14 +++++--------- plat/arm/css/sgm/include/sgm_base_platform_def.h | 14 +++++--------- 3 files changed, 12 insertions(+), 20 deletions(-) diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst index 8297dc785..8e9dc38e4 100644 --- a/docs/design/firmware-design.rst +++ b/docs/design/firmware-design.rst @@ -1859,7 +1859,7 @@ BL image during boot. | BL2 | <<<<<<<<<<<<< | | |----------| <<<<<<<<<<<<< |----------------| | SCP_BL2 | <<<<<<<<<<<<< | BL31 PROGBITS | - |----------| <<<<<<<<<<<<< |----------------| + | | <<<<<<<<<<<<< |----------------| | | <<<<<<<<<<<<< | BL32 | | | +----------------+ | | @@ -1896,7 +1896,7 @@ BL image during boot. | BL2 | <<<<<<<<<<<<< | | |----------| <<<<<<<<<<<<< |----------------| | SCP_BL2 | <<<<<<<<<<<<< | BL31 PROGBITS | - |----------| +----------------+ + | | +----------------+ 0x04001000 +----------+ | MHU | 0x04000000 +----------+ diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h index cfac80182..b44639528 100644 --- a/plat/arm/board/juno/include/platform_def.h +++ b/plat/arm/board/juno/include/platform_def.h @@ -249,16 +249,12 @@ #endif /* - * PLAT_CSS_MAX_SCP_BL2_SIZE is calculated using the current - * SCP_BL2 size plus a little space for growth. + * SCP_BL2 uses up whatever remaining space is available as it is loaded before + * anything else in this memory region and is handed over to the SCP before + * BL31 is loaded over the top. */ -#define PLAT_CSS_MAX_SCP_BL2_SIZE UL(0x14000) - -/* - * PLAT_CSS_MAX_SCP_BL2U_SIZE is calculated using the current - * SCP_BL2U size plus a little space for growth. - */ -#define PLAT_CSS_MAX_SCP_BL2U_SIZE UL(0x14000) +#define PLAT_CSS_MAX_SCP_BL2_SIZE (SCP_BL2_LIMIT - ARM_TB_FW_CONFIG_LIMIT) +#define PLAT_CSS_MAX_SCP_BL2U_SIZE PLAT_CSS_MAX_SCP_BL2_SIZE #define PLAT_ARM_G1S_IRQ_PROPS(grp) \ CSS_G1S_IRQ_PROPS(grp), \ diff --git a/plat/arm/css/sgm/include/sgm_base_platform_def.h b/plat/arm/css/sgm/include/sgm_base_platform_def.h index 90511ac6a..0ac0c2b3c 100644 --- a/plat/arm/css/sgm/include/sgm_base_platform_def.h +++ b/plat/arm/css/sgm/include/sgm_base_platform_def.h @@ -133,16 +133,12 @@ #endif /* - * PLAT_CSS_MAX_SCP_BL2_SIZE is calculated using the current - * SCP_BL2 size plus a little space for growth. + * SCP_BL2 uses up whatever remaining space is available as it is loaded before + * anything else in this memory region and is handed over to the SCP before + * BL31 is loaded over the top. */ -#define PLAT_CSS_MAX_SCP_BL2_SIZE 0x15000 - -/* - * PLAT_CSS_MAX_SCP_BL2U_SIZE is calculated using the current - * SCP_BL2U size plus a little space for growth. - */ -#define PLAT_CSS_MAX_SCP_BL2U_SIZE 0x15000 +#define PLAT_CSS_MAX_SCP_BL2_SIZE (SCP_BL2_LIMIT - ARM_TB_FW_CONFIG_LIMIT) +#define PLAT_CSS_MAX_SCP_BL2U_SIZE PLAT_CSS_MAX_SCP_BL2_SIZE /* * Most platform porting definitions provided by included headers -- cgit v1.2.3 From 316c5cc6a2d6beb9c3d1d06b85d2e81c1f76a78f Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Tue, 3 Mar 2020 13:00:10 +0100 Subject: Update cryptographic algorithms in TBBR doc The TBBR documentation has been written along with an early implementation of the code. At that time, the range of supported encryption and hash algorithms was failry limited. Since then, support for other algorithms has been added in TF-A but the documentation has not been updated. Instead of listing them all, which would clutter this document while still leaving it at risk of going stale in the future, remove specific references to the original algorithms and point the reader at the relevant comprehensive document for further details. Change-Id: I29dc50bc1d53b728091a1fbaa1c3970fb999f7d5 Signed-off-by: Sandrine Bailleux --- docs/design/trusted-board-boot.rst | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/docs/design/trusted-board-boot.rst b/docs/design/trusted-board-boot.rst index 4802c97f3..96cf24c0b 100644 --- a/docs/design/trusted-board-boot.rst +++ b/docs/design/trusted-board-boot.rst @@ -19,7 +19,9 @@ A Chain of Trust (CoT) starts with a set of implicitly trusted components. On the Arm development platforms, these components are: - A SHA-256 hash of the Root of Trust Public Key (ROTPK). It is stored in the - trusted root-key storage registers. + trusted root-key storage registers. Alternatively, a development ROTPK might + be used and its hash embedded into the BL1 and BL2 images (only for + development purposes). - The BL1 image, on the assumption that it resides in ROM so cannot be tampered with. @@ -32,17 +34,17 @@ essential information to establish the CoT. In the TBB CoT all certificates are self-signed. There is no need for a Certificate Authority (CA) because the CoT is not established by verifying the validity of a certificate's issuer but by the content of the certificate -extensions. To sign the certificates, the PKCS#1 SHA-256 with RSA Encryption -signature scheme is used with a RSA key length of 2048 bits. Future version of -TF-A will support additional cryptographic algorithms. +extensions. To sign the certificates, different signature schemes are available, +please refer to the :ref:`Build Options` for more details. The certificates are categorised as "Key" and "Content" certificates. Key certificates are used to verify public keys which have been used to sign content certificates. Content certificates are used to store the hash of a boot loader image. An image can be authenticated by calculating its hash and matching it -with the hash extracted from the content certificate. The SHA-256 function is -used to calculate all hashes. The public keys and hashes are included as -non-standard extension fields in the `X.509 v3`_ certificates. +with the hash extracted from the content certificate. Various hash algorithms +are supported to calculate all hashes, please refer to the :ref:`Build Options` +for more details.. The public keys and hashes are included as non-standard +extension fields in the `X.509 v3`_ certificates. The keys used to establish the CoT are: @@ -63,10 +65,10 @@ The keys used to establish the CoT are: non secure world image (BL33). The public part is stored in one of the extension fields in the trusted world certificate. -- **BL3-X keys** +- **BL3X keys** For each of SCP_BL2, BL31, BL32 and BL33, the private part is used to - sign the content certificate for the BL3-X image. The public part is stored + sign the content certificate for the BL3X image. The public part is stored in one of the extension fields in the corresponding key certificate. The following images are included in the CoT: @@ -219,8 +221,7 @@ certificates (in DER format) required to establish the CoT. New keys can be generated by the tool in case they are not provided. The certificates are then passed as inputs to the ``fiptool`` utility for creating the FIP. -The certificates are also stored individually in the in the output build -directory. +The certificates are also stored individually in the output build directory. The tool resides in the ``tools/cert_create`` directory. It uses the OpenSSL SSL library version to generate the X.509 certificates. The specific version of the @@ -259,7 +260,7 @@ Instructions for building and using the tool can be found in the -------------- -*Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved.* +*Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved.* .. _X.509 v3: https://tools.ietf.org/rfc/rfc5280.txt .. _Trusted Board Boot Requirements (TBBR): https://developer.arm.com/docs/den0006/latest/trusted-board-boot-requirements-client-tbbr-client-armv8-a -- cgit v1.2.3 From d935b95161959d79521b83e2887ab44947208ea9 Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Tue, 3 Mar 2020 13:03:36 +0100 Subject: Mention COT build option in trusted-board-boot-build.rst Since commit 3bff910dc16ad5ed97d470064b25481d3674732b ("Introduce COT build option"), it is now possible to select a different Chain of Trust than the TBBR-Client one. Make a few adjustments in the documentation to reflect that. Also make some minor improvements (fixing typos, better formatting, ...) along the way. Change-Id: I3bbadc441557e1e13311b6fd053fdab6b10b1ba2 Signed-off-by: Sandrine Bailleux --- docs/design/trusted-board-boot-build.rst | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/docs/design/trusted-board-boot-build.rst b/docs/design/trusted-board-boot-build.rst index f5c8bc98c..dd61b61f5 100644 --- a/docs/design/trusted-board-boot-build.rst +++ b/docs/design/trusted-board-boot-build.rst @@ -32,25 +32,28 @@ images with support for these features: - ``TRUSTED_BOARD_BOOT=1`` - ``GENERATE_COT=1`` + By default, this will use the Chain of Trust described in the TBBR-client + document. To select a different one, use the ``COT`` build option. + In the case of Arm platforms, the location of the ROTPK hash must also be specified at build time. The following locations are currently supported (see ``ARM_ROTPK_LOCATION`` build option): - ``ARM_ROTPK_LOCATION=regs``: the ROTPK hash is obtained from the Trusted - root-key storage registers present in the platform. On Juno, this + root-key storage registers present in the platform. On Juno, these registers are read-only. On FVP Base and Cortex models, the registers - are read-only, but the value can be specified using the command line + are also read-only, but the value can be specified using the command line option ``bp.trusted_key_storage.public_key`` when launching the model. On Juno board, the default value corresponds to an ECDSA-SECP256R1 public key hash, whose private part is not currently available. - ``ARM_ROTPK_LOCATION=devel_rsa``: use the default hash located in - plat/arm/board/common/rotpk/arm_rotpk_rsa_sha256.bin. Enforce generation - of the new hash if ROT_KEY is specified. + ``plat/arm/board/common/rotpk/arm_rotpk_rsa_sha256.bin``. Enforce + generation of the new hash if ``ROT_KEY`` is specified. - ``ARM_ROTPK_LOCATION=devel_ecdsa``: use the default hash located in - plat/arm/board/common/rotpk/arm_rotpk_ecdsa_sha256.bin. Enforce generation - of the new hash if ROT_KEY is specified. + ``plat/arm/board/common/rotpk/arm_rotpk_ecdsa_sha256.bin``. Enforce + generation of the new hash if ``ROT_KEY`` is specified. Example of command line using RSA development keys: @@ -64,9 +67,8 @@ images with support for these features: all fip The result of this build will be the bl1.bin and the fip.bin binaries. This - FIP will include the certificates corresponding to the Chain of Trust - described in the TBBR-client document. These certificates can also be found - in the output build directory. + FIP will include the certificates corresponding to the selected Chain of + Trust. These certificates can also be found in the output build directory. #. The optional FWU_FIP contains any additional images to be loaded from Non-Volatile storage during the :ref:`Firmware Update (FWU)` process. To build the @@ -102,8 +104,8 @@ images with support for these features: The result of this build will be bl1.bin, fip.bin and fwu_fip.bin binaries. Both the FIP and FWU_FIP will include the certificates corresponding to the - Chain of Trust described in the TBBR-client document. These certificates - can also be found in the output build directory. + selected Chain of Trust. These certificates can also be found in the output + build directory. -------------- -- cgit v1.2.3 From ac03ac5ebb081678261a52dec4472931c48523e3 Mon Sep 17 00:00:00 2001 From: Max Shvetsov Date: Thu, 12 Mar 2020 15:16:40 +0000 Subject: SPMD: Add support for SPCI_ID_GET This patch introduces the `SPCI_ID_GET` interface which will return the ID of the calling SPCI component. Returns 0 for requests from the non-secure world and the SPCI component ID as specified in the manifest for secure world requests. Change-Id: Icf81eb1d0e1d7d5c521571e04972b6e2d356e0d1 Signed-off-by: Max Shvetsov Signed-off-by: Marc Bonnici --- include/services/spm_core_manifest.h | 5 +++++ plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts | 1 + plat/common/plat_spmd_manifest.c | 7 +++++++ services/std_svc/spmd/spmd_main.c | 30 +++++++++++++++++++++++++++ services/std_svc/spmd/spmd_private.h | 9 ++++++++ 5 files changed, 52 insertions(+) diff --git a/include/services/spm_core_manifest.h b/include/services/spm_core_manifest.h index 78748826d..71e6cfbe4 100644 --- a/include/services/spm_core_manifest.h +++ b/include/services/spm_core_manifest.h @@ -43,6 +43,11 @@ typedef struct spm_core_manifest_sect_attribute { */ uint32_t binary_size; + /* + * ID of the SPMD (mandatory) + */ + uint16_t spmc_id; + } spmc_manifest_sect_attribute_t; #endif /* SPMC_MANIFEST_H */ diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts index c94a209fd..db3fb5510 100644 --- a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts +++ b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts @@ -9,6 +9,7 @@ compatible = "spci-core-manifest-1.0"; attribute { + spmc_id = <0x8000>; maj_ver = <0x0>; min_ver = <0x9>; exec_state = <0x0>; diff --git a/plat/common/plat_spmd_manifest.c b/plat/common/plat_spmd_manifest.c index 9c3dc7177..f0aa27cfb 100644 --- a/plat/common/plat_spmd_manifest.c +++ b/plat/common/plat_spmd_manifest.c @@ -37,6 +37,12 @@ static int manifest_parse_attribute(spmc_manifest_sect_attribute_t *attr, return -ENOENT; } + rc = fdtw_read_cells(fdt, node, "spmc_id", 1, &attr->spmc_id); + if (rc) { + ERROR("Missing SPMC ID in manifest.\n"); + return -ENOENT; + } + rc = fdtw_read_cells(fdt, node, "exec_state", 1, &attr->exec_state); if (rc) NOTICE("Execution state not specified in SPM core manifest.\n"); @@ -55,6 +61,7 @@ static int manifest_parse_attribute(spmc_manifest_sect_attribute_t *attr, VERBOSE("SPM core manifest attribute section:\n"); VERBOSE(" version: %x.%x\n", attr->major_version, attr->minor_version); + VERBOSE(" spmc_id: %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); diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c index 2cdf4f5ff..a3e1a2d57 100644 --- a/services/std_svc/spmd/spmd_main.c +++ b/services/std_svc/spmd/spmd_main.c @@ -162,6 +162,16 @@ static int spmd_spmc_init(void *rd_base, size_t rd_size) INFO("SPM core run time EL%x.\n", SPMD_SPM_AT_SEL2 ? MODE_EL2 : MODE_EL1); + /* Validate the SPMC ID, Ensure high bit is set */ + if (!(spmc_attrs.spmc_id >> SPMC_SECURE_ID_SHIFT) & + SPMC_SECURE_ID_MASK) { + WARN("Invalid ID (0x%x) for SPMC.\n", + spmc_attrs.spmc_id); + return 1; + } + + INFO("SPMC ID %x.\n", spmc_attrs.spmc_id); + /* Validate the SPM core execution state */ if ((spmc_attrs.exec_state != MODE_RW_64) && (spmc_attrs.exec_state != MODE_RW_32)) { @@ -436,6 +446,26 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, break; /* not reached */ + case SPCI_ID_GET: + /* + * Returns the ID of the calling SPCI component. + */ + if (!secure_origin) { + SMC_RET8(handle, SPCI_SUCCESS_SMC32, + SPCI_TARGET_INFO_MBZ, SPCI_NS_ENDPOINT_ID, + SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, + SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, + SPCI_PARAM_MBZ); + } else { + SMC_RET8(handle, SPCI_SUCCESS_SMC32, + SPCI_TARGET_INFO_MBZ, spmc_attrs.spmc_id, + SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, + SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, + SPCI_PARAM_MBZ); + } + + break; /* not reached */ + case SPCI_RX_RELEASE: case SPCI_RXTX_MAP_SMC32: case SPCI_RXTX_MAP_SMC64: diff --git a/services/std_svc/spmd/spmd_private.h b/services/std_svc/spmd/spmd_private.h index 61b479a8b..0ad35c7c1 100644 --- a/services/std_svc/spmd/spmd_private.h +++ b/services/std_svc/spmd/spmd_private.h @@ -54,6 +54,15 @@ typedef struct spmd_spm_core_context { spmc_state_t state; } spmd_spm_core_context_t; +/* + * Reserve ID for NS physical SPCI Endpoint. + */ +#define SPCI_NS_ENDPOINT_ID U(0) + +/* Mask and shift to check valid secure SPCI Endpoint ID. */ +#define SPMC_SECURE_ID_MASK 0x1 +#define SPMC_SECURE_ID_SHIFT 15 + /* * Data structure used by the SPM dispatcher (SPMD) in EL3 to track sequence of * SPCI calls from lower ELs. -- cgit v1.2.3 From 2fc18a25f55c0462650bb70915ec9ce66b479d8c Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Mon, 2 Mar 2020 14:56:58 +0000 Subject: plat/sgi: Bump bl1 RW limit Increase bl1 RW limit to allow future development. Change-Id: I3159b36dbaca798b4c4374c1415cd033d6586388 Signed-off-by: Louis Mayencourt --- 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 9a482d0c0..242a0e995 100644 --- a/plat/arm/css/sgi/include/sgi_base_platform_def.h +++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h @@ -56,7 +56,7 @@ * 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 0xB000 +#define PLAT_ARM_MAX_BL1_RW_SIZE 0xC000 /* * PLAT_ARM_MAX_ROMLIB_RW_SIZE is define to use a full page -- cgit v1.2.3 From 3888c2d4daf192fd41c74112deac00e939dc106f Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Sat, 14 Mar 2020 10:24:41 +0800 Subject: docs: remove uefi-tools in hikey and hikey960 Since uefi-tools isn't used any more in hikey and hikey960, update the documents. Signed-off-by: Haojian Zhuang Change-Id: I0843d27610e241d442e58b6cd71967998730a35d --- docs/plat/hikey.rst | 24 ++++-------------------- docs/plat/hikey960.rst | 20 ++++---------------- 2 files changed, 8 insertions(+), 36 deletions(-) diff --git a/docs/plat/hikey.rst b/docs/plat/hikey.rst index 372d38867..6c488b827 100644 --- a/docs/plat/hikey.rst +++ b/docs/plat/hikey.rst @@ -26,9 +26,6 @@ Code Locations - l-loader: `link `__ -- uefi-tools: - `link `__ - - atf-fastboot: `link `__ @@ -45,7 +42,6 @@ Build Procedure git clone https://github.com/96boards-hikey/edk2 -b testing/hikey960_v2.5 git clone https://github.com/96boards-hikey/OpenPlatformPkg -b testing/hikey960_v1.3.4 git clone https://github.com/96boards-hikey/l-loader -b testing/hikey960_v1.2 - git clone https://git.linaro.org/uefi/uefi-tools git clone https://github.com/96boards-hikey/atf-fastboot - Create the symbol link to OpenPlatformPkg in edk2. @@ -57,13 +53,12 @@ Build Procedure - Prepare AARCH64 && AARCH32 toolchain. Prepare python. -- If your hikey hardware is built by CircuitCo, update *uefi-tools/platform.config* first. *(optional)* - **Uncomment the below sentence. Otherwise, UEFI can't output messages on serial +- If your hikey hardware is built by CircuitCo, update *OpenPlatformPkg/Platforms/Hisilicon/HiKey/HiKey.dsc* first. *(optional)* console on hikey.** .. code:: shell - BUILDFLAGS=-DSERIAL_BASE=0xF8015000 + DEFINE SERIAL_BASE=0xF8015000 If your hikey hardware is built by LeMaker, nothing to do. @@ -71,19 +66,8 @@ Build Procedure .. code:: shell - BUILD_OPTION=DEBUG - export AARCH64_TOOLCHAIN=GCC5 - export UEFI_TOOLS_DIR=${BUILD_PATH}/uefi-tools - export EDK2_DIR=${BUILD_PATH}/edk2 - EDK2_OUTPUT_DIR=${EDK2_DIR}/Build/HiKey/${BUILD_OPTION}_${AARCH64_TOOLCHAIN} - # Build fastboot for Trusted Firmware-A. It's used for recovery mode. - cd ${BUILD_PATH}/atf-fastboot - CROSS_COMPILE=aarch64-linux-gnu- make PLAT=hikey DEBUG=1 - # Convert DEBUG/RELEASE to debug/release - FASTBOOT_BUILD_OPTION=$(echo ${BUILD_OPTION} | tr '[A-Z]' '[a-z]') - cd ${EDK2_DIR} - # Build UEFI & Trusted Firmware-A - ${UEFI_TOOLS_DIR}/uefi-build.sh -b ${BUILD_OPTION} -a ../arm-trusted-firmware -s ../optee_os hikey + cd {BUILD_PATH}/arm-trusted-firmware + sh ../l-loader/build_uefi.sh hikey - Generate l-loader.bin and partition table for aosp. The eMMC capacity is either 8GB or 4GB. Just change "aosp-8g" to "linux-8g" for debian. diff --git a/docs/plat/hikey960.rst b/docs/plat/hikey960.rst index 3d42a77c5..982c2c854 100644 --- a/docs/plat/hikey960.rst +++ b/docs/plat/hikey960.rst @@ -26,9 +26,6 @@ Code Locations - l-loader: `link `__ -- uefi-tools: - `link `__ - Build Procedure ~~~~~~~~~~~~~~~ @@ -42,7 +39,6 @@ Build Procedure git clone https://github.com/96boards-hikey/edk2 -b testing/hikey960_v2.5 git clone https://github.com/96boards-hikey/OpenPlatformPkg -b testing/hikey960_v1.3.4 git clone https://github.com/96boards-hikey/l-loader -b testing/hikey960_v1.2 - git clone https://git.linaro.org/uefi/uefi-tools - Create the symbol link to OpenPlatformPkg in edk2. @@ -53,13 +49,11 @@ Build Procedure - Prepare AARCH64 toolchain. -- If your hikey960 hardware is v1, update *uefi-tools/platform.config* first. *(optional)* - **Uncomment the below sentence. Otherwise, UEFI can't output messages on serial - console on hikey960 v1.** +- If your hikey960 hardware is v1, update *OpenPlatformPkg/Platforms/Hisilicon/HiKey960/HiKey960.dsc* first. *(optional)* .. code:: shell - BUILDFLAGS=-DSERIAL_BASE=0xFDF05000 + DEFINE SERIAL_BASE=0xFDF05000 If your hikey960 hardware is v2 or newer, nothing to do. @@ -67,14 +61,8 @@ Build Procedure .. code:: shell - BUILD_OPTION=DEBUG - export AARCH64_TOOLCHAIN=GCC5 - export UEFI_TOOLS_DIR=${BUILD_PATH}/uefi-tools - export EDK2_DIR=${BUILD_PATH}/edk2 - EDK2_OUTPUT_DIR=${EDK2_DIR}/Build/HiKey960/${BUILD_OPTION}_${AARCH64_TOOLCHAIN} - cd ${EDK2_DIR} - # Build UEFI & Trusted Firmware-A - ${UEFI_TOOLS_DIR}/uefi-build.sh -b ${BUILD_OPTION} -a ../arm-trusted-firmware -s ../optee_os hikey960 + cd {BUILD_PATH}/arm-trusted-firmware + sh ../l-loader/build_uefi.sh hikey960 - Generate l-loader.bin and partition table. *Make sure that you're using the sgdisk in the l-loader directory.* -- cgit v1.2.3 From a6de824f7e3352ba6507bca37dbf671a16a3ec93 Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Fri, 28 Feb 2020 16:57:30 +0000 Subject: fconf: Clean Arm IO Merge the previously introduced arm_fconf_io_storage into arm_io_storage. This removes the duplicate io_policies and functions definition. This patch: - replace arm_io_storage.c with the content of arm_fconf_io_storage.c - rename the USE_FCONF_BASED_IO option into ARM_IO_IN_DTB. - use the ARM_IO_IN_DTB option to compile out io_policies moved in dtb. - propagate DEFINES when parsing dts. - use ARM_IO_IN_DTB to include or not uuid nodes in fw_config dtb. - set the ARM_IO_IN_DTB to 0 by default for fvp. This ensure that the behavior of fvp stays the same as it was before the introduction of fconf. Change-Id: Ia774a96d1d3a2bccad29f7ce2e2b4c21b26c080e Signed-off-by: Louis Mayencourt --- Makefile | 7 +- docs/getting_started/build-options.rst | 4 +- lib/fconf/fconf.c | 2 +- make_helpers/defaults.mk | 2 +- plat/arm/board/a5ds/platform.mk | 2 + plat/arm/board/fvp/fdts/fvp_fw_config.dts | 2 + plat/arm/board/fvp/platform.mk | 5 - plat/arm/board/fvp_ve/platform.mk | 2 + plat/arm/common/arm_common.mk | 6 +- plat/arm/common/arm_fconf_io_storage.c | 142 ----------------- plat/arm/common/arm_io_storage.c | 253 ++---------------------------- plat/arm/common/fconf/arm_fconf_io.c | 124 +++++++++++++++ 12 files changed, 150 insertions(+), 401 deletions(-) delete mode 100644 plat/arm/common/arm_fconf_io_storage.c diff --git a/Makefile b/Makefile index 47a544dcf..609600a98 100644 --- a/Makefile +++ b/Makefile @@ -364,7 +364,8 @@ endif endif DTC_FLAGS += -I dts -O dtb -DTC_CPPFLAGS += -P -nostdinc -Iinclude -Ifdts -undef -x assembler-with-cpp +DTC_CPPFLAGS += -P -nostdinc -Iinclude -Ifdts -undef \ + -x assembler-with-cpp $(DEFINES) ################################################################################ # Common sources and include directories @@ -826,7 +827,7 @@ $(eval $(call assert_boolean,SPMD_SPM_AT_SEL2)) $(eval $(call assert_boolean,TRUSTED_BOARD_BOOT)) $(eval $(call assert_boolean,USE_COHERENT_MEM)) $(eval $(call assert_boolean,USE_DEBUGFS)) -$(eval $(call assert_boolean,USE_FCONF_BASED_IO)) +$(eval $(call assert_boolean,ARM_IO_IN_DTB)) $(eval $(call assert_boolean,USE_ROMLIB)) $(eval $(call assert_boolean,USE_TBBR_DEFS)) $(eval $(call assert_boolean,WARMBOOT_ENABLE_DCACHE_EARLY)) @@ -904,7 +905,7 @@ $(eval $(call add_define,SPMD_SPM_AT_SEL2)) $(eval $(call add_define,TRUSTED_BOARD_BOOT)) $(eval $(call add_define,USE_COHERENT_MEM)) $(eval $(call add_define,USE_DEBUGFS)) -$(eval $(call add_define,USE_FCONF_BASED_IO)) +$(eval $(call add_define,ARM_IO_IN_DTB)) $(eval $(call add_define,USE_ROMLIB)) $(eval $(call add_define,USE_TBBR_DEFS)) $(eval $(call add_define,WARMBOOT_ENABLE_DCACHE_EARLY)) diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index f138feb4c..e53f71471 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -622,8 +622,8 @@ Common build options exposing a virtual filesystem interface through BL31 as a SiP SMC function. Default is 0. -- ``USE_FCONF_BASED_IO``: This flag determines whether to use IO based on the - firmware configuration framework. This allows moving the io_policies into a +- ``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. diff --git a/lib/fconf/fconf.c b/lib/fconf/fconf.c index 9ce46354d..3007273ae 100644 --- a/lib/fconf/fconf.c +++ b/lib/fconf/fconf.c @@ -33,7 +33,7 @@ void fconf_load_config(void) err = load_auth_image(TB_FW_CONFIG_ID, &arm_tb_fw_info); if (err != 0) { /* Return if FW_CONFIG is not loaded */ - VERBOSE("Failed to load FW_CONFIG\n"); + WARN("Failed to load FW_CONFIG\n"); return; } diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index 03322db19..4e968e2d3 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -223,7 +223,7 @@ USE_COHERENT_MEM := 1 USE_DEBUGFS := 0 # Build option to fconf based io -USE_FCONF_BASED_IO := 0 +ARM_IO_IN_DTB := 0 # Build option to choose whether Trusted Firmware uses library at ROM USE_ROMLIB := 0 diff --git a/plat/arm/board/a5ds/platform.mk b/plat/arm/board/a5ds/platform.mk index 719884217..3a4d5e56d 100644 --- a/plat/arm/board/a5ds/platform.mk +++ b/plat/arm/board/a5ds/platform.mk @@ -41,6 +41,7 @@ BL1_SOURCES += drivers/io/io_fip.c \ plat/arm/common/arm_err.c \ plat/arm/board/a5ds/a5ds_err.c \ plat/arm/common/arm_io_storage.c \ + plat/arm/common/fconf/arm_fconf_io.c \ plat/arm/board/a5ds/${ARCH}/a5ds_helpers.S \ plat/arm/board/a5ds/a5ds_bl1_setup.c \ lib/aarch32/arm32_aeabi_divmod.c \ @@ -61,6 +62,7 @@ BL2_SOURCES += lib/aarch32/arm32_aeabi_divmod.c \ plat/arm/common/arm_err.c \ plat/arm/board/a5ds/a5ds_err.c \ plat/arm/common/arm_io_storage.c \ + plat/arm/common/fconf/arm_fconf_io.c \ plat/arm/common/${ARCH}/arm_bl2_mem_params_desc.c \ plat/arm/common/arm_image_load.c \ common/desc_image_load.c \ diff --git a/plat/arm/board/fvp/fdts/fvp_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_fw_config.dts index 9a4a05799..2bb6c3628 100644 --- a/plat/arm/board/fvp/fdts/fvp_fw_config.dts +++ b/plat/arm/board/fvp/fdts/fvp_fw_config.dts @@ -75,6 +75,7 @@ * stored in machine order (little endian). * This will be fixed in future. */ +#if ARM_IO_IN_DTB arm-io_policies { fip-handles { compatible = "arm,io-fip-handle"; @@ -99,6 +100,7 @@ nt_fw_content_cert_uuid = <0xf3c1c48e 0x11e4635d 0xee87a9a7 0xa73fb240>; }; }; +#endif /* ARM_IO_IN_DTB */ secure-partitions { compatible = "arm,sp"; diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index ca35697e0..3255e996e 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -10,11 +10,6 @@ FVP_USE_GIC_DRIVER := FVP_GICV3 # Use the SP804 timer instead of the generic one FVP_USE_SP804_TIMER := 0 -# Use fconf based io for FVP -ifeq ($(BL2_AT_EL3), 0) -USE_FCONF_BASED_IO := 1 -endif - # Default cluster count for FVP FVP_CLUSTER_COUNT := 2 diff --git a/plat/arm/board/fvp_ve/platform.mk b/plat/arm/board/fvp_ve/platform.mk index 7883719b0..9ada86bf1 100644 --- a/plat/arm/board/fvp_ve/platform.mk +++ b/plat/arm/board/fvp_ve/platform.mk @@ -42,6 +42,7 @@ BL1_SOURCES += drivers/arm/sp805/sp805.c \ plat/arm/common/arm_err.c \ plat/arm/board/fvp_ve/fvp_ve_err.c \ plat/arm/common/arm_io_storage.c \ + plat/arm/common/fconf/arm_fconf_io.c \ drivers/cfi/v2m/v2m_flash.c \ plat/arm/board/fvp_ve/${ARCH}/fvp_ve_helpers.S \ plat/arm/board/fvp_ve/fvp_ve_bl1_setup.c \ @@ -63,6 +64,7 @@ BL2_SOURCES += plat/arm/board/fvp_ve/fvp_ve_bl2_setup.c \ plat/arm/common/arm_err.c \ plat/arm/board/fvp_ve/fvp_ve_err.c \ plat/arm/common/arm_io_storage.c \ + plat/arm/common/fconf/arm_fconf_io.c \ plat/arm/common/${ARCH}/arm_bl2_mem_params_desc.c \ plat/arm/common/arm_image_load.c \ common/desc_image_load.c \ diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index 65f6bf3c3..8368d34c8 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -177,15 +177,11 @@ include lib/xlat_tables_v2/xlat_tables.mk PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS} endif -ifeq (${USE_FCONF_BASED_IO}, 0) -ARM_IO_SOURCES += plat/arm/common/arm_io_storage.c -else -ARM_IO_SOURCES += plat/arm/common/arm_fconf_io_storage.c \ +ARM_IO_SOURCES += plat/arm/common/arm_io_storage.c \ plat/arm/common/fconf/arm_fconf_io.c ifeq (${SPD},spmd) ARM_IO_SOURCES += plat/arm/common/fconf/arm_fconf_sp.c endif -endif BL1_SOURCES += drivers/io/io_fip.c \ drivers/io/io_memmap.c \ diff --git a/plat/arm/common/arm_fconf_io_storage.c b/plat/arm/common/arm_fconf_io_storage.c deleted file mode 100644 index 6fcfbd6fb..000000000 --- a/plat/arm/common/arm_fconf_io_storage.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2015-2020, ARM Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -/* IO devices */ -static const io_dev_connector_t *fip_dev_con; -uintptr_t fip_dev_handle; -static const io_dev_connector_t *memmap_dev_con; -uintptr_t memmap_dev_handle; - -/* Weak definitions may be overridden in specific ARM standard platform */ -#pragma weak plat_arm_io_setup -#pragma weak plat_arm_get_alt_image_source - -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; -} - -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; -} - -int arm_io_setup(void) -{ - int io_result; - - io_result = register_io_dev_fip(&fip_dev_con); - if (io_result < 0) { - return io_result; - } - - io_result = register_io_dev_memmap(&memmap_dev_con); - if (io_result < 0) { - return io_result; - } - - /* Open connections to devices and cache the handles */ - io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, - &fip_dev_handle); - if (io_result < 0) { - return io_result; - } - - io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, - &memmap_dev_handle); - - return io_result; -} - -void plat_arm_io_setup(void) -{ - int err; - - err = arm_io_setup(); - if (err < 0) { - panic(); - } -} - -int plat_arm_get_alt_image_source( - unsigned int image_id __unused, - uintptr_t *dev_handle __unused, - uintptr_t *image_spec __unused) -{ - /* By default do not try an alternative */ - return -ENOENT; -} - -/* 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 result; - const struct plat_io_policy *policy; - - assert(image_id < MAX_NUMBER_IDS); - - policy = FCONF_GET_PROPERTY(arm, io_policies, image_id); - result = policy->check(policy->image_spec); - if (result == 0) { - *image_spec = policy->image_spec; - *dev_handle = *(policy->dev_handle); - } else { - VERBOSE("Trying alternative IO\n"); - result = plat_arm_get_alt_image_source(image_id, dev_handle, - image_spec); - } - - return result; -} - -/* - * See if a Firmware Image Package is available, - * by checking if TOC is valid or not. - */ -bool arm_io_is_toc_valid(void) -{ - return (io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID) == 0); -} diff --git a/plat/arm/common/arm_io_storage.c b/plat/arm/common/arm_io_storage.c index f5d8a414d..6fcfbd6fb 100644 --- a/plat/arm/common/arm_io_storage.c +++ b/plat/arm/common/arm_io_storage.c @@ -1,13 +1,10 @@ /* - * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include -#include - -#include #include #include @@ -15,249 +12,24 @@ #include #include #include + +#include +#include #include #include -#include +#include /* IO devices */ static const io_dev_connector_t *fip_dev_con; -static uintptr_t fip_dev_handle; +uintptr_t fip_dev_handle; 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 = PLAT_ARM_FIP_BASE, - .length = PLAT_ARM_FIP_MAX_SIZE -}; - -static const io_uuid_spec_t bl2_uuid_spec = { - .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2, -}; - -static const io_uuid_spec_t scp_bl2_uuid_spec = { - .uuid = UUID_SCP_FIRMWARE_SCP_BL2, -}; - -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, -}; - -static const io_uuid_spec_t tb_fw_config_uuid_spec = { - .uuid = UUID_TB_FW_CONFIG, -}; - -static const io_uuid_spec_t hw_config_uuid_spec = { - .uuid = UUID_HW_CONFIG, -}; - -static const io_uuid_spec_t soc_fw_config_uuid_spec = { - .uuid = UUID_SOC_FW_CONFIG, -}; - -static const io_uuid_spec_t tos_fw_config_uuid_spec = { - .uuid = UUID_TOS_FW_CONFIG, -}; - -static const io_uuid_spec_t nt_fw_config_uuid_spec = { - .uuid = UUID_NT_FW_CONFIG, -}; - -#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 scp_fw_key_cert_uuid_spec = { - .uuid = UUID_SCP_FW_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 nt_fw_key_cert_uuid_spec = { - .uuid = UUID_NON_TRUSTED_FW_KEY_CERT, -}; - -static const io_uuid_spec_t scp_fw_cert_uuid_spec = { - .uuid = UUID_SCP_FW_CONTENT_CERT, -}; - -static const io_uuid_spec_t soc_fw_cert_uuid_spec = { - .uuid = UUID_SOC_FW_CONTENT_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_cert_uuid_spec = { - .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT, -}; -#endif /* TRUSTED_BOARD_BOOT */ - - -static int open_fip(const uintptr_t spec); -static int open_memmap(const uintptr_t spec); - -struct plat_io_policy { - uintptr_t *dev_handle; - uintptr_t image_spec; - int (*check)(const uintptr_t spec); -}; - -/* By default, ARM platforms load images from the FIP */ -static const struct plat_io_policy policies[] = { - [FIP_IMAGE_ID] = { - &memmap_dev_handle, - (uintptr_t)&fip_block_spec, - open_memmap - }, - [BL2_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&bl2_uuid_spec, - open_fip - }, - [SCP_BL2_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&scp_bl2_uuid_spec, - open_fip - }, - [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 - }, - [TB_FW_CONFIG_ID] = { - &fip_dev_handle, - (uintptr_t)&tb_fw_config_uuid_spec, - open_fip - }, - [HW_CONFIG_ID] = { - &fip_dev_handle, - (uintptr_t)&hw_config_uuid_spec, - open_fip - }, - [SOC_FW_CONFIG_ID] = { - &fip_dev_handle, - (uintptr_t)&soc_fw_config_uuid_spec, - open_fip - }, - [TOS_FW_CONFIG_ID] = { - &fip_dev_handle, - (uintptr_t)&tos_fw_config_uuid_spec, - open_fip - }, - [NT_FW_CONFIG_ID] = { - &fip_dev_handle, - (uintptr_t)&nt_fw_config_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 - }, - [SCP_FW_KEY_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&scp_fw_key_cert_uuid_spec, - open_fip - }, - [SOC_FW_KEY_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&soc_fw_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 - }, - [SCP_FW_CONTENT_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&scp_fw_cert_uuid_spec, - open_fip - }, - [SOC_FW_CONTENT_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&soc_fw_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 */ -}; - +uintptr_t memmap_dev_handle; /* Weak definitions may be overridden in specific ARM standard platform */ #pragma weak plat_arm_io_setup #pragma weak plat_arm_get_alt_image_source - -static int open_fip(const uintptr_t spec) +int open_fip(const uintptr_t spec) { int result; uintptr_t local_image_handle; @@ -274,8 +46,7 @@ static int open_fip(const uintptr_t spec) return result; } - -static int open_memmap(const uintptr_t spec) +int open_memmap(const uintptr_t spec) { int result; uintptr_t local_image_handle; @@ -291,7 +62,6 @@ static int open_memmap(const uintptr_t spec) return result; } - int arm_io_setup(void) { int io_result; @@ -346,9 +116,9 @@ int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, int result; const struct plat_io_policy *policy; - assert(image_id < ARRAY_SIZE(policies)); + assert(image_id < MAX_NUMBER_IDS); - policy = &policies[image_id]; + policy = FCONF_GET_PROPERTY(arm, io_policies, image_id); result = policy->check(policy->image_spec); if (result == 0) { *image_spec = policy->image_spec; @@ -370,4 +140,3 @@ bool arm_io_is_toc_valid(void) { return (io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID) == 0); } - diff --git a/plat/arm/common/fconf/arm_fconf_io.c b/plat/arm/common/fconf/arm_fconf_io.c index 017af79a5..6ebc467ed 100644 --- a/plat/arm/common/fconf/arm_fconf_io.c +++ b/plat/arm/common/fconf/arm_fconf_io.c @@ -25,8 +25,31 @@ const io_block_spec_t fip_block_spec = { const io_uuid_spec_t arm_uuid_spec[MAX_NUMBER_IDS] = { [BL2_IMAGE_ID] = {UUID_TRUSTED_BOOT_FIRMWARE_BL2}, [TB_FW_CONFIG_ID] = {UUID_TB_FW_CONFIG}, +#if !ARM_IO_IN_DTB + [SCP_BL2_IMAGE_ID] = {UUID_SCP_FIRMWARE_SCP_BL2}, + [BL31_IMAGE_ID] = {UUID_EL3_RUNTIME_FIRMWARE_BL31}, + [BL32_IMAGE_ID] = {UUID_SECURE_PAYLOAD_BL32}, + [BL32_EXTRA1_IMAGE_ID] = {UUID_SECURE_PAYLOAD_BL32_EXTRA1}, + [BL32_EXTRA2_IMAGE_ID] = {UUID_SECURE_PAYLOAD_BL32_EXTRA2}, + [BL33_IMAGE_ID] = {UUID_NON_TRUSTED_FIRMWARE_BL33}, + [HW_CONFIG_ID] = {UUID_HW_CONFIG}, + [SOC_FW_CONFIG_ID] = {UUID_SOC_FW_CONFIG}, + [TOS_FW_CONFIG_ID] = {UUID_TOS_FW_CONFIG}, + [NT_FW_CONFIG_ID] = {UUID_NT_FW_CONFIG}, +#endif /* ARM_IO_IN_DTB */ #if TRUSTED_BOARD_BOOT [TRUSTED_BOOT_FW_CERT_ID] = {UUID_TRUSTED_BOOT_FW_CERT}, +#if !ARM_IO_IN_DTB + [TRUSTED_KEY_CERT_ID] = {UUID_TRUSTED_KEY_CERT}, + [SCP_FW_KEY_CERT_ID] = {UUID_SCP_FW_KEY_CERT}, + [SOC_FW_KEY_CERT_ID] = {UUID_SOC_FW_KEY_CERT}, + [TRUSTED_OS_FW_KEY_CERT_ID] = {UUID_TRUSTED_OS_FW_KEY_CERT}, + [NON_TRUSTED_FW_KEY_CERT_ID] = {UUID_NON_TRUSTED_FW_KEY_CERT}, + [SCP_FW_CONTENT_CERT_ID] = {UUID_SCP_FW_CONTENT_CERT}, + [SOC_FW_CONTENT_CERT_ID] = {UUID_SOC_FW_CONTENT_CERT}, + [TRUSTED_OS_FW_CONTENT_CERT_ID] = {UUID_TRUSTED_OS_FW_CONTENT_CERT}, + [NON_TRUSTED_FW_CONTENT_CERT_ID] = {UUID_NON_TRUSTED_FW_CONTENT_CERT}, +#endif /* ARM_IO_IN_DTB */ #endif /* TRUSTED_BOARD_BOOT */ }; @@ -47,12 +70,111 @@ struct plat_io_policy policies[MAX_NUMBER_IDS] = { (uintptr_t)&arm_uuid_spec[TB_FW_CONFIG_ID], open_fip }, +#if !ARM_IO_IN_DTB + [SCP_BL2_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[SCP_BL2_IMAGE_ID], + open_fip + }, + [BL31_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[BL31_IMAGE_ID], + open_fip + }, + [BL32_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[BL32_IMAGE_ID], + open_fip + }, + [BL32_EXTRA1_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[BL32_EXTRA1_IMAGE_ID], + open_fip + }, + [BL32_EXTRA2_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[BL32_EXTRA2_IMAGE_ID], + open_fip + }, + [BL33_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[BL33_IMAGE_ID], + open_fip + }, + [HW_CONFIG_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[HW_CONFIG_ID], + open_fip + }, + [SOC_FW_CONFIG_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[SOC_FW_CONFIG_ID], + open_fip + }, + [TOS_FW_CONFIG_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[TOS_FW_CONFIG_ID], + open_fip + }, + [NT_FW_CONFIG_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[NT_FW_CONFIG_ID], + open_fip + }, +#endif /* ARM_IO_IN_DTB */ #if TRUSTED_BOARD_BOOT [TRUSTED_BOOT_FW_CERT_ID] = { &fip_dev_handle, (uintptr_t)&arm_uuid_spec[TRUSTED_BOOT_FW_CERT_ID], open_fip }, +#if !ARM_IO_IN_DTB + [TRUSTED_KEY_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[TRUSTED_KEY_CERT_ID], + open_fip + }, + [SCP_FW_KEY_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[SCP_FW_KEY_CERT_ID], + open_fip + }, + [SOC_FW_KEY_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[SOC_FW_KEY_CERT_ID], + open_fip + }, + [TRUSTED_OS_FW_KEY_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[TRUSTED_OS_FW_KEY_CERT_ID], + open_fip + }, + [NON_TRUSTED_FW_KEY_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[NON_TRUSTED_FW_KEY_CERT_ID], + open_fip + }, + [SCP_FW_CONTENT_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[SCP_FW_CONTENT_CERT_ID], + open_fip + }, + [SOC_FW_CONTENT_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[SOC_FW_CONTENT_CERT_ID], + open_fip + }, + [TRUSTED_OS_FW_CONTENT_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[TRUSTED_OS_FW_CONTENT_CERT_ID], + open_fip + }, + [NON_TRUSTED_FW_CONTENT_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[NON_TRUSTED_FW_CONTENT_CERT_ID], + open_fip + }, +#endif /* ARM_IO_IN_DTB */ #endif /* TRUSTED_BOARD_BOOT */ }; @@ -138,6 +260,8 @@ int fconf_populate_arm_io_policies(uintptr_t config) return 0; } +#if ARM_IO_IN_DTB FCONF_REGISTER_POPULATOR(TB_FW, arm_io, fconf_populate_arm_io_policies); +#endif /* ARM_IO_IN_DTB */ #endif /* IMAGE_BL2 */ -- cgit v1.2.3 From 965c07815f1b1e90ef1f817090265fd870529257 Mon Sep 17 00:00:00 2001 From: Igor Opaniuk Date: Mon, 16 Mar 2020 22:49:16 +0200 Subject: plat: imx: imx8_iomux: fix shift-overflow errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes shift overflow errors, when compiled with CONSOLE_DEBUG support: plat/imx/common/include/imx8_iomux.h:11:35: error: result of ‘1 << 31’ requires 33 bits to represent, but ‘int’ only has 32 bits [-Werror=shift-overflow=] Signed-off-by: Igor Opaniuk Change-Id: I0488e22c30314ba27caabc5c767164baa1e8004c --- plat/imx/common/include/imx8_iomux.h | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/plat/imx/common/include/imx8_iomux.h b/plat/imx/common/include/imx8_iomux.h index 0e93d9800..264c295bb 100644 --- a/plat/imx/common/include/imx8_iomux.h +++ b/plat/imx/common/include/imx8_iomux.h @@ -7,19 +7,19 @@ #ifndef IMX8_IOMUX_H #define IMX8_IOMUX_H -#define PADRING_IFMUX_EN_SHIFT 31 -#define PADRING_IFMUX_EN_MASK (1 << PADRING_IFMUX_EN_SHIFT) -#define PADRING_GP_EN_SHIFT 30 -#define PADRING_GP_EN_MASK (1 << PADRING_GP_EN_SHIFT) -#define PADRING_IFMUX_SHIFT 27 -#define PADRING_IFMUX_MASK (0x7 << PADRING_IFMUX_SHIFT) -#define PADRING_CONFIG_SHIFT 25 -#define PADRING_CONFIG_MASK (0x3 << PADRING_CONFIG_SHIFT) -#define PADRING_LPCONFIG_SHIFT 23 -#define PADRING_LPCONFIG_MASK (0x3 << PADRING_LPCONFIG_SHIFT) -#define PADRING_PULL_SHIFT 5 -#define PADRING_PULL_MASK (0x3 << PADRING_PULL_SHIFT) -#define PADRING_DSE_SHIFT 0 -#define PADRING_DSE_MASK (0x7 << PADRING_DSE_SHIFT) +#define PADRING_IFMUX_EN_SHIFT U(31) +#define PADRING_IFMUX_EN_MASK (U(0x1) << PADRING_IFMUX_EN_SHIFT) +#define PADRING_GP_EN_SHIFT U(30) +#define PADRING_GP_EN_MASK (U(0x1) << PADRING_GP_EN_SHIFT) +#define PADRING_IFMUX_SHIFT U(27) +#define PADRING_IFMUX_MASK (U(0x7) << PADRING_IFMUX_SHIFT) +#define PADRING_CONFIG_SHIFT U(25) +#define PADRING_CONFIG_MASK (U(0x3) << PADRING_CONFIG_SHIFT) +#define PADRING_LPCONFIG_SHIFT U(23) +#define PADRING_LPCONFIG_MASK (U(0x3) << PADRING_LPCONFIG_SHIFT) +#define PADRING_PULL_SHIFT U(5) +#define PADRING_PULL_MASK (U(0x3) << PADRING_PULL_SHIFT) +#define PADRING_DSE_SHIFT U(0) +#define PADRING_DSE_MASK (U(0x7) << PADRING_DSE_SHIFT) #endif /* IMX8_IOMUX_H */ -- cgit v1.2.3 From fc1596b34761104f9384766d49286938b1dff622 Mon Sep 17 00:00:00 2001 From: Igor Opaniuk Date: Mon, 16 Mar 2020 22:55:42 +0200 Subject: plat: imx: imx8qm: provide debug uart num as build param This removes hardcoded iomux/clk/addr configuration for debug uart, provides possibility (as a workaround, till that information isn't provided via DT) to set this configuration during compile time via IMX_DEBUG_UART build flag. Usage: $ make PLAT=imx8qm IMX_DEBUG_UART=1 bl31 Signed-off-by: Igor Opaniuk Change-Id: Ib5f5dd81ba0c8ad2b2dc5647ec75629072f511c5 --- plat/imx/imx8qm/imx8qm_bl31_setup.c | 33 +++++++++++++++++++++++++-------- plat/imx/imx8qm/include/platform_def.h | 11 ++++++++++- plat/imx/imx8qm/platform.mk | 6 ++++++ 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/plat/imx/imx8qm/imx8qm_bl31_setup.c b/plat/imx/imx8qm/imx8qm_bl31_setup.c index cffb140fb..4ca6a5db4 100644 --- a/plat/imx/imx8qm/imx8qm_bl31_setup.c +++ b/plat/imx/imx8qm/imx8qm_bl31_setup.c @@ -44,6 +44,22 @@ static entry_point_info_t bl33_image_ep_info; (SC_PAD_28FDSOI_DSE_DV_LOW << PADRING_DSE_SHIFT) | \ (SC_PAD_28FDSOI_PS_PD << PADRING_PULL_SHIFT)) +#if defined(IMX_USE_UART0) +#define IMX_RES_UART SC_R_UART_0 +#define IMX_PAD_UART_RX SC_P_UART0_RX +#define IMX_PAD_UART_TX SC_P_UART0_TX +#define IMX_PAD_UART_RTS_B SC_P_UART0_RTS_B +#define IMX_PAD_UART_CTS_B SC_P_UART0_CTS_B +#elif defined(IMX_USE_UART1) +#define IMX_RES_UART SC_R_UART_1 +#define IMX_PAD_UART_RX SC_P_UART1_RX +#define IMX_PAD_UART_TX SC_P_UART1_TX +#define IMX_PAD_UART_RTS_B SC_P_UART1_RTS_B +#define IMX_PAD_UART_CTS_B SC_P_UART1_CTS_B +#else +#error "Provide proper UART number in IMX_DEBUG_UART" +#endif + const static int imx8qm_cci_map[] = { CLUSTER0_CCI_SLVAE_IFACE, CLUSTER1_CCI_SLVAE_IFACE @@ -79,7 +95,7 @@ static void lpuart32_serial_setbrg(unsigned int base, int baudrate) if (baudrate == 0) panic(); - sc_pm_get_clock_rate(ipc_handle, SC_R_UART_0, 2, &rate); + sc_pm_get_clock_rate(ipc_handle, IMX_RES_UART, 2, &rate); baud_diff = baudrate; osr = 0; @@ -301,16 +317,17 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, panic(); #if DEBUG_CONSOLE_A53 - sc_pm_set_resource_power_mode(ipc_handle, SC_R_UART_0, SC_PM_PW_MODE_ON); + sc_pm_set_resource_power_mode(ipc_handle, IMX_RES_UART, + SC_PM_PW_MODE_ON); sc_pm_clock_rate_t rate = 80000000; - sc_pm_set_clock_rate(ipc_handle, SC_R_UART_0, 2, &rate); - sc_pm_clock_enable(ipc_handle, SC_R_UART_0, 2, true, false); + sc_pm_set_clock_rate(ipc_handle, IMX_RES_UART, 2, &rate); + sc_pm_clock_enable(ipc_handle, IMX_RES_UART, 2, true, false); /* configure UART pads */ - sc_pad_set(ipc_handle, SC_P_UART0_RX, UART_PAD_CTRL); - sc_pad_set(ipc_handle, SC_P_UART0_TX, UART_PAD_CTRL); - sc_pad_set(ipc_handle, SC_P_UART0_RTS_B, UART_PAD_CTRL); - sc_pad_set(ipc_handle, SC_P_UART0_CTS_B, UART_PAD_CTRL); + sc_pad_set(ipc_handle, IMX_PAD_UART_RX, UART_PAD_CTRL); + sc_pad_set(ipc_handle, IMX_PAD_UART_TX, UART_PAD_CTRL); + sc_pad_set(ipc_handle, IMX_PAD_UART_RTS_B, UART_PAD_CTRL); + sc_pad_set(ipc_handle, IMX_PAD_UART_CTS_B, UART_PAD_CTRL); lpuart32_serial_init(IMX_BOOT_UART_BASE); #endif diff --git a/plat/imx/imx8qm/include/platform_def.h b/plat/imx/imx8qm/include/platform_def.h index b54943da0..da5288beb 100644 --- a/plat/imx/imx8qm/include/platform_def.h +++ b/plat/imx/imx8qm/include/platform_def.h @@ -40,12 +40,22 @@ #define PLAT_CCI_BASE 0x52090000 #define CLUSTER0_CCI_SLVAE_IFACE 3 #define CLUSTER1_CCI_SLVAE_IFACE 4 + +/* UART */ +#if defined(IMX_USE_UART0) #define IMX_BOOT_UART_BASE 0x5a060000 +#elif defined(IMX_USE_UART1) +#define IMX_BOOT_UART_BASE 0x5a070000 +#else +#error "Provide proper UART number in IMX_DEBUG_UART" +#endif + #define IMX_BOOT_UART_BAUDRATE 115200 #define IMX_BOOT_UART_CLK_IN_HZ 24000000 #define PLAT_CRASH_UART_BASE IMX_BOOT_UART_BASE #define PLAT__CRASH_UART_CLK_IN_HZ 24000000 #define IMX_CONSOLE_BAUDRATE 115200 + #define SC_IPC_BASE 0x5d1b0000 #define IMX_GPT_LPCG_BASE 0x5d540000 #define IMX_GPT_BASE 0x5d140000 @@ -64,7 +74,6 @@ #define MAX_XLAT_TABLES 8 #define MAX_MMAP_REGIONS 12 -#define DEBUG_CONSOLE 0 #define DEBUG_CONSOLE_A53 0 #endif /* PLATFORM_DEF_H */ diff --git a/plat/imx/imx8qm/platform.mk b/plat/imx/imx8qm/platform.mk index 5ba9c3f7b..20ee05be9 100644 --- a/plat/imx/imx8qm/platform.mk +++ b/plat/imx/imx8qm/platform.mk @@ -43,3 +43,9 @@ ERRATA_A72_859971 := 1 ERRATA_A53_835769 := 1 ERRATA_A53_843419 := 1 ERRATA_A53_855873 := 1 + +IMX_DEBUG_UART ?= 0 +$(eval $(call add_define,IMX_USE_UART${IMX_DEBUG_UART})) + +DEBUG_CONSOLE ?= 0 +$(eval $(call add_define,DEBUG_CONSOLE)) -- cgit v1.2.3 From 98a69dfd4a6fdd17b4e1cf7382d38bc6b26291a7 Mon Sep 17 00:00:00 2001 From: Igor Opaniuk Date: Mon, 16 Mar 2020 23:07:16 +0200 Subject: plat: imx: imx8qm: apply clk/pinmux configuration for DEBUG_CONSOLE Having DEBUG_CONSOLE enabled without enabling DEBUG_CONSOLE_A53 doesn't make sense (since UART pinmux/clock configuration is applied for UART only when DEBUG_CONSOLE_A53 is enabled). Enable DEBUG_CONSOLE_A53 if DEBUG_CONSOLE is enabled. Signed-off-by: Igor Opaniuk Change-Id: I8ca411d5544658b9bcc39e5340ec042c51088b96 --- plat/imx/imx8qm/include/platform_def.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/imx/imx8qm/include/platform_def.h b/plat/imx/imx8qm/include/platform_def.h index da5288beb..671c77f76 100644 --- a/plat/imx/imx8qm/include/platform_def.h +++ b/plat/imx/imx8qm/include/platform_def.h @@ -74,6 +74,6 @@ #define MAX_XLAT_TABLES 8 #define MAX_MMAP_REGIONS 12 -#define DEBUG_CONSOLE_A53 0 +#define DEBUG_CONSOLE_A53 DEBUG_CONSOLE #endif /* PLATFORM_DEF_H */ -- cgit v1.2.3 From 0e753437e75b68476b524d32c7e9db7f28d2ad85 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Sat, 22 Feb 2020 08:43:00 +0000 Subject: Implement SMCCC_ARCH_SOC_ID SMC call Implemented SMCCC_ARCH_SOC_ID call in order to get below SOC information: 1. SOC revision 2. SOC version Implementation done using below SMCCC specification document: https://developer.arm.com/docs/den0028/c Signed-off-by: Manish V Badarkhe Change-Id: Ie0595f1c345a6429a6fb4a7f05534a0ca9c9a48b --- docs/getting_started/porting-guide.rst | 29 +++++++++++++++++++++++++++++ include/plat/arm/common/plat_arm.h | 9 +++++++++ include/plat/common/platform.h | 10 ++++++++++ include/services/arm_arch_svc.h | 6 +++++- plat/arm/common/arm_common.c | 22 ++++++++++++++++++++++ plat/common/plat_bl_common.c | 13 +++++++++++++ services/arm_arch_svc/arm_arch_svc_setup.c | 17 +++++++++++++---- 7 files changed, 101 insertions(+), 5 deletions(-) diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst index d634d2e70..d6572f507 100644 --- a/docs/getting_started/porting-guide.rst +++ b/docs/getting_started/porting-guide.rst @@ -1116,6 +1116,35 @@ can override the common implementation to define a different prefix string for the log output. The implementation should be robust to future changes that increase the number of log levels. +Function : plat_get_soc_version() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : int32_t + +This function returns soc version which mainly consist of below fields + +:: + + soc_version[30:24] = JEP-106 continuation code for the SiP + soc_version[23:16] = JEP-106 identification code with parity bit for the SiP + +Function : plat_get_soc_revision() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : int32_t + +This function returns soc revision in below format + +:: + + soc_revision[0:30] = SOC revision of specific SOC + Modifications specific to a Boot Loader stage --------------------------------------------- diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index 6c2925afa..a84047aac 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -148,6 +148,12 @@ void arm_setup_romlib(void); #define ARM_ROTPK_DEVEL_RSA_ID 2 #define ARM_ROTPK_DEVEL_ECDSA_ID 3 +/* Defines used to retrieve ARM SOC revision */ +#define ARM_SOC_CONTINUATION_CODE U(0x4) +#define ARM_SOC_IDENTIFICATION_CODE U(0x3B) +#define ARM_SOC_CONTINUATION_SHIFT U(24) +#define ARM_SOC_IDENTIFICATION_SHIFT U(16) + /* IO storage utility functions */ int arm_io_setup(void); @@ -323,4 +329,7 @@ extern const unsigned int arm_pm_idle_states[]; void plat_arm_secure_wdt_start(void); void plat_arm_secure_wdt_stop(void); +/* Get SOC-ID of ARM platform */ +uint32_t plat_arm_get_soc_id(void); + #endif /* PLAT_ARM_H */ diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h index 5b5ebb973..e4431d2f0 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.h @@ -322,4 +322,14 @@ void plat_flush_next_bl_params(void); */ unsigned int platform_core_pos_helper(unsigned long mpidr); +/* + * Optional function to get SOC version + */ +int32_t plat_get_soc_version(void); + +/* + * Optional function to get SOC revision + */ +int32_t plat_get_soc_revision(void); + #endif /* PLATFORM_H */ diff --git a/include/services/arm_arch_svc.h b/include/services/arm_arch_svc.h index 1cb2038c6..5bbd8bb6c 100644 --- a/include/services/arm_arch_svc.h +++ b/include/services/arm_arch_svc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,7 +9,11 @@ #define SMCCC_VERSION U(0x80000000) #define SMCCC_ARCH_FEATURES U(0x80000001) +#define SMCCC_ARCH_SOC_ID U(0x80000002) #define SMCCC_ARCH_WORKAROUND_1 U(0x80008000) #define SMCCC_ARCH_WORKAROUND_2 U(0x80007FFF) +#define SMCCC_GET_SOC_VERSION U(0) +#define SMCCC_GET_SOC_REVISION U(1) + #endif /* ARM_ARCH_SVC_H */ diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c index d1eee08d1..60c777ed8 100644 --- a/plat/arm/common/arm_common.c +++ b/plat/arm/common/arm_common.c @@ -25,6 +25,9 @@ * conflicts with the definition in plat/common. */ #pragma weak plat_get_syscnt_freq2 +/* Get ARM SOC-ID */ +#pragma weak plat_arm_get_soc_id + /******************************************************************************* * Changes the memory attributes for the region of mapped memory where the BL * image's translation tables are located such that the tables will have @@ -231,3 +234,22 @@ int plat_sdei_validate_entry_point(uintptr_t ep, unsigned int client_mode) return arm_validate_ns_entrypoint(pa); } #endif + +/* + * Weak function to get ARM platform SOC-ID, Always return SOC-ID=0 + * ToDo: Get proper SOC-ID for every ARM platform and define this + * function separately for every ARM platform. + */ +uint32_t plat_arm_get_soc_id(void) +{ + return 0U; +} + +/* 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) + | plat_arm_get_soc_id()); +} diff --git a/plat/common/plat_bl_common.c b/plat/common/plat_bl_common.c index de6c1d176..d38fc6f75 100644 --- a/plat/common/plat_bl_common.c +++ b/plat/common/plat_bl_common.c @@ -11,6 +11,7 @@ #include #include #include +#include #include /* @@ -24,6 +25,18 @@ #pragma weak bl2_plat_handle_post_image_load #pragma weak plat_try_next_boot_source #pragma weak plat_get_enc_key_info +#pragma weak plat_get_soc_version +#pragma weak plat_get_soc_revision + +int32_t plat_get_soc_version(void) +{ + return SMC_ARCH_CALL_NOT_SUPPORTED; +} + +int32_t plat_get_soc_revision(void) +{ + return SMC_ARCH_CALL_NOT_SUPPORTED; +} void bl2_el3_plat_prepare_exit(void) { diff --git a/services/arm_arch_svc/arm_arch_svc_setup.c b/services/arm_arch_svc/arm_arch_svc_setup.c index 6dac56ec8..ba539309d 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-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -12,18 +12,27 @@ #include #include #include +#include static int32_t smccc_version(void) { return MAKE_SMCCC_VERSION(SMCCC_MAJOR_VERSION, SMCCC_MINOR_VERSION); } -static int32_t smccc_arch_features(u_register_t arg) +static int32_t smccc_arch_features(u_register_t arg1, u_register_t arg2) { - switch (arg) { + switch (arg1) { case SMCCC_VERSION: case SMCCC_ARCH_FEATURES: return SMC_OK; + case SMCCC_ARCH_SOC_ID: + if (arg2 == SMCCC_GET_SOC_REVISION) { + return plat_get_soc_revision(); + } + if (arg2 == SMCCC_GET_SOC_VERSION) { + return plat_get_soc_version(); + } + return SMC_ARCH_CALL_INVAL_PARAM; #if WORKAROUND_CVE_2017_5715 case SMCCC_ARCH_WORKAROUND_1: if (check_wa_cve_2017_5715() == ERRATA_NOT_APPLIES) @@ -94,7 +103,7 @@ static uintptr_t arm_arch_svc_smc_handler(uint32_t smc_fid, case SMCCC_VERSION: SMC_RET1(handle, smccc_version()); case SMCCC_ARCH_FEATURES: - SMC_RET1(handle, smccc_arch_features(x1)); + SMC_RET1(handle, smccc_arch_features(x1, x2)); #if WORKAROUND_CVE_2017_5715 case SMCCC_ARCH_WORKAROUND_1: /* -- cgit v1.2.3 From 0d92745e101b95a19c34dd6e2d1eccc2d9fcb629 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Wed, 11 Mar 2020 16:10:40 +0000 Subject: rpi3: gpio: Simplify GPIO setup There is really no reason to use and pass around a struct when its only member is the (fixed) base address. Remove the struct and just use the base address on its own inside the GPIO driver. Then set the base address automatically. This simplifies GPIO setup for users, which now don't need to deal with zeroing a struct and setting the base address anymore. Change-Id: I3060f7859e3f8ef9a24cc8fb38307b5da943f127 Signed-off-by: Andre Przywara --- drivers/rpi3/gpio/rpi3_gpio.c | 12 +++--------- include/drivers/rpi3/gpio/rpi3_gpio.h | 6 +----- plat/rpi/rpi3/rpi3_bl2_setup.c | 13 +------------ 3 files changed, 5 insertions(+), 26 deletions(-) diff --git a/drivers/rpi3/gpio/rpi3_gpio.c b/drivers/rpi3/gpio/rpi3_gpio.c index b39808ff7..f938f563f 100644 --- a/drivers/rpi3/gpio/rpi3_gpio.c +++ b/drivers/rpi3/gpio/rpi3_gpio.c @@ -11,7 +11,7 @@ #include #include -static struct rpi3_gpio_params rpi3_gpio_params; +static uintptr_t reg_base; static int rpi3_gpio_get_direction(int gpio); static void rpi3_gpio_set_direction(int gpio, int direction); @@ -43,7 +43,6 @@ static const gpio_ops_t rpi3_gpio_ops = { int rpi3_gpio_get_select(int gpio) { int ret; - uintptr_t reg_base = rpi3_gpio_params.reg_base; int regN = gpio / 10; int shift = 3 * (gpio % 10); uintptr_t reg_sel = reg_base + RPI3_GPIO_GPFSEL(regN); @@ -69,7 +68,6 @@ int rpi3_gpio_get_select(int gpio) */ void rpi3_gpio_set_select(int gpio, int fsel) { - uintptr_t reg_base = rpi3_gpio_params.reg_base; int regN = gpio / 10; int shift = 3 * (gpio % 10); uintptr_t reg_sel = reg_base + RPI3_GPIO_GPFSEL(regN); @@ -106,7 +104,6 @@ static void rpi3_gpio_set_direction(int gpio, int direction) static int rpi3_gpio_get_value(int gpio) { - uintptr_t reg_base = rpi3_gpio_params.reg_base; int regN = gpio / 32; int shift = gpio % 32; uintptr_t reg_lev = reg_base + RPI3_GPIO_GPLEV(regN); @@ -119,7 +116,6 @@ static int rpi3_gpio_get_value(int gpio) static void rpi3_gpio_set_value(int gpio, int value) { - uintptr_t reg_base = rpi3_gpio_params.reg_base; int regN = gpio / 32; int shift = gpio % 32; uintptr_t reg_set = reg_base + RPI3_GPIO_GPSET(regN); @@ -137,7 +133,6 @@ static void rpi3_gpio_set_value(int gpio, int value) static void rpi3_gpio_set_pull(int gpio, int pull) { - uintptr_t reg_base = rpi3_gpio_params.reg_base; int regN = gpio / 32; int shift = gpio % 32; uintptr_t reg_pud = reg_base + RPI3_GPIO_GPPUD; @@ -161,9 +156,8 @@ static void rpi3_gpio_set_pull(int gpio, int pull) mmio_write_32(reg_pud, 0x0); } -void rpi3_gpio_init(struct rpi3_gpio_params *params) +void rpi3_gpio_init(void) { - assert(params != 0); - memcpy(&rpi3_gpio_params, params, sizeof(struct rpi3_gpio_params)); + reg_base = RPI3_GPIO_BASE; gpio_init(&rpi3_gpio_ops); } diff --git a/include/drivers/rpi3/gpio/rpi3_gpio.h b/include/drivers/rpi3/gpio/rpi3_gpio.h index 159a2e08b..7bb3ee25b 100644 --- a/include/drivers/rpi3/gpio/rpi3_gpio.h +++ b/include/drivers/rpi3/gpio/rpi3_gpio.h @@ -11,11 +11,7 @@ #include #include -struct rpi3_gpio_params { - uintptr_t reg_base; -}; - -void rpi3_gpio_init(struct rpi3_gpio_params *params); +void rpi3_gpio_init(void); int rpi3_gpio_get_select(int gpio); void rpi3_gpio_set_select(int gpio, int fsel); diff --git a/plat/rpi/rpi3/rpi3_bl2_setup.c b/plat/rpi/rpi3/rpi3_bl2_setup.c index 44827c63a..d64235ad2 100644 --- a/plat/rpi/rpi3/rpi3_bl2_setup.c +++ b/plat/rpi/rpi3/rpi3_bl2_setup.c @@ -24,17 +24,6 @@ /* Data structure which holds the extents of the trusted SRAM for BL2 */ static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE); -/* rpi3 GPIO setup function. */ -static void rpi3_gpio_setup(void) -{ - struct rpi3_gpio_params params; - - memset(¶ms, 0, sizeof(struct rpi3_gpio_params)); - params.reg_base = RPI3_GPIO_BASE; - - rpi3_gpio_init(¶ms); -} - /* Data structure which holds the MMC info */ static struct mmc_device_info mmc_info; @@ -68,7 +57,7 @@ void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, generic_delay_timer_init(); /* Setup GPIO driver */ - rpi3_gpio_setup(); + rpi3_gpio_init(); /* Setup the BL2 memory layout */ bl2_tzram_layout = *mem_layout; -- cgit v1.2.3 From 795aefe5e80494018c731cea69e2284140f4abbb Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Tue, 10 Mar 2020 12:33:16 +0000 Subject: rpi3: console: Use same "clock-less" setup scheme as RPi4 In the wake of the upcoming unification of the console setup code between RPi3 and RPi4, extend the "clock-less" setup scheme to the RPi3. This avoid programming any clocks or baud rate registers, which makes the port more robust against GPU firmware changes. Signed-off-by: Andre Przywara Change-Id: Ida83a963bb18a878997e9cbd55f8ceac6a2e1c1f --- plat/rpi/common/include/rpi_shared.h | 2 +- plat/rpi/common/rpi3_common.c | 19 +++++++++++-------- plat/rpi/rpi3/aarch64/plat_helpers.S | 12 +++++------- plat/rpi/rpi3/include/platform_def.h | 5 ++--- plat/rpi/rpi3/include/rpi_hw.h | 1 - plat/rpi/rpi3/rpi3_bl1_setup.c | 2 +- plat/rpi/rpi3/rpi3_bl2_setup.c | 2 +- plat/rpi/rpi3/rpi3_bl31_setup.c | 2 +- plat/rpi/rpi4/aarch64/plat_helpers.S | 8 +++----- plat/rpi/rpi4/include/platform_def.h | 4 ++-- plat/rpi/rpi4/include/rpi_hw.h | 4 ++-- plat/rpi/rpi4/rpi4_bl31_setup.c | 10 ++-------- 12 files changed, 31 insertions(+), 40 deletions(-) diff --git a/plat/rpi/common/include/rpi_shared.h b/plat/rpi/common/include/rpi_shared.h index de8357162..686343892 100644 --- a/plat/rpi/common/include/rpi_shared.h +++ b/plat/rpi/common/include/rpi_shared.h @@ -14,7 +14,7 @@ ******************************************************************************/ /* Utility functions */ -void rpi3_console_init(unsigned int base_clk_rate); +void rpi3_console_init(void); void rpi3_setup_page_tables(uintptr_t total_base, size_t total_size, uintptr_t code_start, uintptr_t code_limit, uintptr_t rodata_start, uintptr_t rodata_limit diff --git a/plat/rpi/common/rpi3_common.c b/plat/rpi/common/rpi3_common.c index 27281f2ba..ba81ddb5a 100644 --- a/plat/rpi/common/rpi3_common.c +++ b/plat/rpi/common/rpi3_common.c @@ -104,16 +104,19 @@ static const mmap_region_t plat_rpi3_mmap[] = { ******************************************************************************/ static console_t rpi3_console; -void rpi3_console_init(unsigned int base_clk_rate) +void rpi3_console_init(void) { int console_scope = CONSOLE_FLAG_BOOT; -#if RPI3_RUNTIME_UART != -1 - console_scope |= CONSOLE_FLAG_RUNTIME; -#endif - int rc = console_16550_register(PLAT_RPI3_UART_BASE, - base_clk_rate, - PLAT_RPI3_UART_BAUDRATE, - &rpi3_console); + int rc; + + if (RPI3_RUNTIME_UART != -1) + console_scope |= CONSOLE_FLAG_RUNTIME; + + rc = console_16550_register(PLAT_RPI_MINI_UART_BASE, + 0, + PLAT_RPI_UART_BAUDRATE, + &rpi3_console); + if (rc == 0) { /* * The crash console doesn't use the multi console API, it uses diff --git a/plat/rpi/rpi3/aarch64/plat_helpers.S b/plat/rpi/rpi3/aarch64/plat_helpers.S index 24278bdf6..ab925b6c0 100644 --- a/plat/rpi/rpi3/aarch64/plat_helpers.S +++ b/plat/rpi/rpi3/aarch64/plat_helpers.S @@ -9,8 +9,6 @@ #include #include -#include "../include/rpi_hw.h" - .globl plat_crash_console_flush .globl plat_crash_console_init .globl plat_crash_console_putc @@ -133,9 +131,9 @@ endfunc platform_mem_init * --------------------------------------------- */ func plat_crash_console_init - mov_imm x0, PLAT_RPI3_UART_BASE - mov_imm x1, PLAT_RPI3_UART_CLK_IN_HZ - mov_imm x2, PLAT_RPI3_UART_BAUDRATE + mov_imm x0, PLAT_RPI_MINI_UART_BASE + mov x1, xzr + mov x2, xzr b console_16550_core_init endfunc plat_crash_console_init @@ -147,7 +145,7 @@ endfunc plat_crash_console_init * --------------------------------------------- */ func plat_crash_console_putc - mov_imm x1, PLAT_RPI3_UART_BASE + mov_imm x1, PLAT_RPI_MINI_UART_BASE b console_16550_core_putc endfunc plat_crash_console_putc @@ -160,6 +158,6 @@ endfunc plat_crash_console_putc * --------------------------------------------- */ func plat_crash_console_flush - mov_imm x0, PLAT_RPI3_UART_BASE + mov_imm x0, PLAT_RPI_MINI_UART_BASE b console_16550_core_flush endfunc plat_crash_console_flush diff --git a/plat/rpi/rpi3/include/platform_def.h b/plat/rpi/rpi3/include/platform_def.h index e308f70a6..854da8f2e 100644 --- a/plat/rpi/rpi3/include/platform_def.h +++ b/plat/rpi/rpi3/include/platform_def.h @@ -249,9 +249,8 @@ /* * Serial-related constants. */ -#define PLAT_RPI3_UART_BASE RPI3_MINI_UART_BASE -#define PLAT_RPI3_UART_CLK_IN_HZ RPI3_MINI_UART_CLK_IN_HZ -#define PLAT_RPI3_UART_BAUDRATE ULL(115200) +#define PLAT_RPI_MINI_UART_BASE RPI3_MINI_UART_BASE +#define PLAT_RPI_UART_BAUDRATE ULL(115200) /* * System counter diff --git a/plat/rpi/rpi3/include/rpi_hw.h b/plat/rpi/rpi3/include/rpi_hw.h index 01d5b4a0f..60ecf0d78 100644 --- a/plat/rpi/rpi3/include/rpi_hw.h +++ b/plat/rpi/rpi3/include/rpi_hw.h @@ -81,7 +81,6 @@ */ #define RPI3_IO_MINI_UART_OFFSET ULL(0x00215040) #define RPI3_MINI_UART_BASE (RPI_IO_BASE + RPI3_IO_MINI_UART_OFFSET) -#define RPI3_MINI_UART_CLK_IN_HZ ULL(500000000) /* * GPIO controller diff --git a/plat/rpi/rpi3/rpi3_bl1_setup.c b/plat/rpi/rpi3/rpi3_bl1_setup.c index dcce76e47..3ac30e0f0 100644 --- a/plat/rpi/rpi3/rpi3_bl1_setup.c +++ b/plat/rpi/rpi3/rpi3_bl1_setup.c @@ -35,7 +35,7 @@ void bl1_early_platform_setup(void) 0x80000000); /* Initialize the console to provide early debug support */ - rpi3_console_init(PLAT_RPI3_UART_CLK_IN_HZ); + rpi3_console_init(); /* Allow BL1 to see the whole Trusted RAM */ bl1_tzram_layout.total_base = BL_RAM_BASE; diff --git a/plat/rpi/rpi3/rpi3_bl2_setup.c b/plat/rpi/rpi3/rpi3_bl2_setup.c index d64235ad2..db7181794 100644 --- a/plat/rpi/rpi3/rpi3_bl2_setup.c +++ b/plat/rpi/rpi3/rpi3_bl2_setup.c @@ -51,7 +51,7 @@ void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, meminfo_t *mem_layout = (meminfo_t *) arg1; /* Initialize the console to provide early debug support */ - rpi3_console_init(PLAT_RPI3_UART_CLK_IN_HZ); + rpi3_console_init(); /* Enable arch timer */ generic_delay_timer_init(); diff --git a/plat/rpi/rpi3/rpi3_bl31_setup.c b/plat/rpi/rpi3/rpi3_bl31_setup.c index 24a56139b..59157536b 100644 --- a/plat/rpi/rpi3/rpi3_bl31_setup.c +++ b/plat/rpi/rpi3/rpi3_bl31_setup.c @@ -72,7 +72,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, { /* Initialize the console to provide early debug support */ - rpi3_console_init(PLAT_RPI3_UART_CLK_IN_HZ); + rpi3_console_init(); /* * In debug builds, a special value is passed in 'arg1' to verify diff --git a/plat/rpi/rpi4/aarch64/plat_helpers.S b/plat/rpi/rpi4/aarch64/plat_helpers.S index 083c30e71..fac1b2075 100644 --- a/plat/rpi/rpi4/aarch64/plat_helpers.S +++ b/plat/rpi/rpi4/aarch64/plat_helpers.S @@ -10,8 +10,6 @@ #include #include -#include "../include/rpi_hw.h" - .globl plat_crash_console_flush .globl plat_crash_console_init .globl plat_crash_console_putc @@ -135,7 +133,7 @@ endfunc platform_mem_init * --------------------------------------------- */ func plat_crash_console_init - mov_imm x0, PLAT_RPI3_UART_BASE + mov_imm x0, PLAT_RPI_MINI_UART_BASE mov x1, xzr mov x2, xzr b console_16550_core_init @@ -149,7 +147,7 @@ endfunc plat_crash_console_init * --------------------------------------------- */ func plat_crash_console_putc - mov_imm x1, PLAT_RPI3_UART_BASE + mov_imm x1, PLAT_RPI_MINI_UART_BASE b console_16550_core_putc endfunc plat_crash_console_putc @@ -162,7 +160,7 @@ endfunc plat_crash_console_putc * --------------------------------------------- */ func plat_crash_console_flush - mov_imm x0, PLAT_RPI3_UART_BASE + mov_imm x0, PLAT_RPI_MINI_UART_BASE b console_16550_core_flush endfunc plat_crash_console_flush diff --git a/plat/rpi/rpi4/include/platform_def.h b/plat/rpi/rpi4/include/platform_def.h index a9ecdba20..e5d5aba6c 100644 --- a/plat/rpi/rpi4/include/platform_def.h +++ b/plat/rpi/rpi4/include/platform_def.h @@ -126,8 +126,8 @@ /* * Serial-related constants. */ -#define PLAT_RPI3_UART_BASE RPI3_MINI_UART_BASE -#define PLAT_RPI3_UART_BAUDRATE ULL(115200) +#define PLAT_RPI_MINI_UART_BASE RPI4_MINI_UART_BASE +#define PLAT_RPI_UART_BAUDRATE ULL(115200) /* * System counter diff --git a/plat/rpi/rpi4/include/rpi_hw.h b/plat/rpi/rpi4/include/rpi_hw.h index b1dd4e92e..e46b0deb0 100644 --- a/plat/rpi/rpi4/include/rpi_hw.h +++ b/plat/rpi/rpi4/include/rpi_hw.h @@ -79,8 +79,8 @@ /* * Serial port (called 'Mini UART' in the Broadcom documentation). */ -#define RPI3_IO_MINI_UART_OFFSET ULL(0x00215040) -#define RPI3_MINI_UART_BASE (RPI_IO_BASE + RPI3_IO_MINI_UART_OFFSET) +#define RPI4_IO_MINI_UART_OFFSET ULL(0x00215040) +#define RPI4_MINI_UART_BASE (RPI_IO_BASE + RPI4_IO_MINI_UART_OFFSET) /* * GPIO controller diff --git a/plat/rpi/rpi4/rpi4_bl31_setup.c b/plat/rpi/rpi4/rpi4_bl31_setup.c index 9e3b53979..0a49d81b2 100644 --- a/plat/rpi/rpi4/rpi4_bl31_setup.c +++ b/plat/rpi/rpi4/rpi4_bl31_setup.c @@ -132,14 +132,8 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, /* Early GPU firmware revisions need a little break here. */ ldelay(100000); - /* - * Initialize the console to provide early debug support. - * We rely on the GPU firmware to have initialised the UART correctly, - * as the baud base clock rate differs across GPU firmware revisions. - * Providing a base clock of 0 lets the 16550 UART init routine skip - * the initial enablement and baud rate setup. - */ - rpi3_console_init(0); + /* Initialize the console to provide early debug support. */ + rpi3_console_init(); bl33_image_ep_info.pc = plat_get_ns_image_entrypoint(); bl33_image_ep_info.spsr = rpi3_get_spsr_for_bl33_entry(); -- cgit v1.2.3 From 5e6d821cb3b32fc6eadb38c25a96f8efe217efba Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Tue, 10 Mar 2020 12:34:56 +0000 Subject: rpi: Allow using PL011 UART for RPi3/RPi4 The Broadcom 283x SoCs feature multiple UARTs: the mostly used "Mini-UART", which is an 8250 compatible IP, and at least one PL011. While the 8250 is usually used for serial console purposes, it suffers from a design flaw, where its clock depends on the VPU clock, which can change at runtime. This will reliably mess up the baud rate. To avoid this problem, people might choose to use the PL011 UART for the serial console, which is pin-mux'ed to the very same GPIO pins. This can be done by adding "miniuart-bt" to the "dtoverlay=" line in config.txt. To prepare for this situation, use the newly gained freedom of sharing one console_t pointer across different UART drivers, to introduce the option of choosing the PL011 for the console. This is for now hard-coded to choose the Mini-UART by default. A follow-up patch will introduce automatic detection. Signed-off-by: Andre Przywara Change-Id: I8cf2522151e09ff4ff94a6d396aec6fc4b091a05 --- plat/rpi/common/rpi3_common.c | 20 ++++++++++++++++---- plat/rpi/rpi3/include/platform_def.h | 2 ++ plat/rpi/rpi3/include/rpi_hw.h | 7 ++++++- plat/rpi/rpi3/platform.mk | 1 + plat/rpi/rpi4/include/platform_def.h | 2 ++ plat/rpi/rpi4/include/rpi_hw.h | 7 ++++++- plat/rpi/rpi4/platform.mk | 1 + 7 files changed, 34 insertions(+), 6 deletions(-) diff --git a/plat/rpi/common/rpi3_common.c b/plat/rpi/common/rpi3_common.c index ba81ddb5a..8fc357a78 100644 --- a/plat/rpi/common/rpi3_common.c +++ b/plat/rpi/common/rpi3_common.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -104,6 +105,11 @@ static const mmap_region_t plat_rpi3_mmap[] = { ******************************************************************************/ static console_t rpi3_console; +static bool rpi3_use_mini_uart(void) +{ + return true; +} + void rpi3_console_init(void) { int console_scope = CONSOLE_FLAG_BOOT; @@ -112,10 +118,16 @@ void rpi3_console_init(void) if (RPI3_RUNTIME_UART != -1) console_scope |= CONSOLE_FLAG_RUNTIME; - rc = console_16550_register(PLAT_RPI_MINI_UART_BASE, - 0, - PLAT_RPI_UART_BAUDRATE, - &rpi3_console); + if (rpi3_use_mini_uart()) + rc = console_16550_register(PLAT_RPI_MINI_UART_BASE, + 0, + PLAT_RPI_UART_BAUDRATE, + &rpi3_console); + else + rc = console_pl011_register(PLAT_RPI_PL011_UART_BASE, + PLAT_RPI_PL011_UART_CLOCK, + PLAT_RPI_UART_BAUDRATE, + &rpi3_console); if (rc == 0) { /* diff --git a/plat/rpi/rpi3/include/platform_def.h b/plat/rpi/rpi3/include/platform_def.h index 854da8f2e..9cacd9915 100644 --- a/plat/rpi/rpi3/include/platform_def.h +++ b/plat/rpi/rpi3/include/platform_def.h @@ -250,6 +250,8 @@ * Serial-related constants. */ #define PLAT_RPI_MINI_UART_BASE RPI3_MINI_UART_BASE +#define PLAT_RPI_PL011_UART_BASE RPI3_PL011_UART_BASE +#define PLAT_RPI_PL011_UART_CLOCK RPI3_PL011_UART_CLOCK #define PLAT_RPI_UART_BAUDRATE ULL(115200) /* diff --git a/plat/rpi/rpi3/include/rpi_hw.h b/plat/rpi/rpi3/include/rpi_hw.h index 60ecf0d78..2aecab379 100644 --- a/plat/rpi/rpi3/include/rpi_hw.h +++ b/plat/rpi/rpi3/include/rpi_hw.h @@ -77,10 +77,15 @@ #define RPI3_RNG_INT_MASK_DISABLE U(0x1) /* - * Serial port (called 'Mini UART' in the BCM docucmentation). + * Serial ports: + * 'Mini UART' in the BCM docucmentation is the 8250 compatible UART. + * There is also a PL011 UART, multiplexed to the same pins. */ #define RPI3_IO_MINI_UART_OFFSET ULL(0x00215040) #define RPI3_MINI_UART_BASE (RPI_IO_BASE + RPI3_IO_MINI_UART_OFFSET) +#define RPI3_IO_PL011_UART_OFFSET ULL(0x00201000) +#define RPI3_PL011_UART_BASE (RPI_IO_BASE + RPI3_IO_PL011_UART_OFFSET) +#define RPI3_PL011_UART_CLOCK ULL(48000000) /* * GPIO controller diff --git a/plat/rpi/rpi3/platform.mk b/plat/rpi/rpi3/platform.mk index a21a7709a..e454ce37e 100644 --- a/plat/rpi/rpi3/platform.mk +++ b/plat/rpi/rpi3/platform.mk @@ -11,6 +11,7 @@ PLAT_INCLUDES := -Iplat/rpi/common/include \ -Iplat/rpi/rpi3/include PLAT_BL_COMMON_SOURCES := drivers/ti/uart/aarch64/16550_console.S \ + drivers/arm/pl011/aarch64/pl011_console.S \ plat/rpi/common/rpi3_common.c \ ${XLAT_TABLES_LIB_SRCS} diff --git a/plat/rpi/rpi4/include/platform_def.h b/plat/rpi/rpi4/include/platform_def.h index e5d5aba6c..6f6bbbe7a 100644 --- a/plat/rpi/rpi4/include/platform_def.h +++ b/plat/rpi/rpi4/include/platform_def.h @@ -127,6 +127,8 @@ * Serial-related constants. */ #define PLAT_RPI_MINI_UART_BASE RPI4_MINI_UART_BASE +#define PLAT_RPI_PL011_UART_BASE RPI4_PL011_UART_BASE +#define PLAT_RPI_PL011_UART_CLOCK RPI4_PL011_UART_CLOCK #define PLAT_RPI_UART_BAUDRATE ULL(115200) /* diff --git a/plat/rpi/rpi4/include/rpi_hw.h b/plat/rpi/rpi4/include/rpi_hw.h index e46b0deb0..718510610 100644 --- a/plat/rpi/rpi4/include/rpi_hw.h +++ b/plat/rpi/rpi4/include/rpi_hw.h @@ -77,10 +77,15 @@ #define RPI3_RNG_INT_MASK_DISABLE U(0x1) /* - * Serial port (called 'Mini UART' in the Broadcom documentation). + * Serial ports: + * 'Mini UART' in the BCM docucmentation is the 8250 compatible UART. + * There is also a PL011 UART, multiplexed to the same pins. */ #define RPI4_IO_MINI_UART_OFFSET ULL(0x00215040) #define RPI4_MINI_UART_BASE (RPI_IO_BASE + RPI4_IO_MINI_UART_OFFSET) +#define RPI4_IO_PL011_UART_OFFSET ULL(0x00201000) +#define RPI4_PL011_UART_BASE (RPI_IO_BASE + RPI4_IO_PL011_UART_OFFSET) +#define RPI4_PL011_UART_CLOCK ULL(48000000) /* * GPIO controller diff --git a/plat/rpi/rpi4/platform.mk b/plat/rpi/rpi4/platform.mk index 2038021a0..28fcda8b0 100644 --- a/plat/rpi/rpi4/platform.mk +++ b/plat/rpi/rpi4/platform.mk @@ -11,6 +11,7 @@ PLAT_INCLUDES := -Iplat/rpi/common/include \ -Iplat/rpi/rpi4/include PLAT_BL_COMMON_SOURCES := drivers/ti/uart/aarch64/16550_console.S \ + drivers/arm/pl011/aarch64/pl011_console.S \ plat/rpi/common/rpi3_common.c \ ${XLAT_TABLES_LIB_SRCS} -- cgit v1.2.3 From 29e8c460664c88dc3834813d94785fbf6e27b8d1 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Wed, 11 Mar 2020 16:33:53 +0000 Subject: rpi3: build: Include GPIO driver in all BL stages So far the Raspberry Pi 3 build needs the GPIO driver just for BL2. Upcoming changes will require some GPIO code in BL1 and BL31 also, so move those driver files into the common source section. This does not affect BL31 code size at all, and bl1.bin just increases by 144 bytes, but doesn't affect the padded binary size at all. Signed-off-by: Andre Przywara Change-Id: I7639746dc241c1e69099d85d2671c65fa0108555 --- plat/rpi/rpi3/platform.mk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plat/rpi/rpi3/platform.mk b/plat/rpi/rpi3/platform.mk index e454ce37e..a5b8904d5 100644 --- a/plat/rpi/rpi3/platform.mk +++ b/plat/rpi/rpi3/platform.mk @@ -12,6 +12,9 @@ PLAT_INCLUDES := -Iplat/rpi/common/include \ PLAT_BL_COMMON_SOURCES := drivers/ti/uart/aarch64/16550_console.S \ drivers/arm/pl011/aarch64/pl011_console.S \ + drivers/gpio/gpio.c \ + drivers/delay_timer/delay_timer.c \ + drivers/rpi3/gpio/rpi3_gpio.c \ plat/rpi/common/rpi3_common.c \ ${XLAT_TABLES_LIB_SRCS} @@ -30,10 +33,7 @@ BL2_SOURCES += common/desc_image_load.c \ drivers/io/io_fip.c \ drivers/io/io_memmap.c \ drivers/io/io_storage.c \ - drivers/gpio/gpio.c \ - drivers/delay_timer/delay_timer.c \ drivers/delay_timer/generic_delay_timer.c \ - drivers/rpi3/gpio/rpi3_gpio.c \ drivers/io/io_block.c \ drivers/mmc/mmc.c \ drivers/rpi3/sdhost/rpi3_sdhost.c \ -- cgit v1.2.3 From 9cc3fa1b8ae31c18fd3a6070b782b3384590523e Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Wed, 11 Mar 2020 15:18:03 +0000 Subject: rpi: console: Autodetect Mini-UART vs. PL011 configuration The Raspberry Pi has two different UART devices pin-muxed to GPIO 14&15: One ARM PL011 one and the 8250 compatible "Mini-UART". A dtoverlay parameter in config.txt will tell the firmware to switch between the two: it will setup the right clocks and will configure the pinmuxes accordingly. To autodetect the user's choice, we read the pinmux register and check its setting: ALT5 (0x2) means the Mini-UART is used, ALT0 (0x4) points to the PL011. Based on that we select the UART driver to initialise. This will allow console output in any case. Change-Id: I620d3ce68de6c6576599f2a405636020e1fd1376 Signed-off-by: Andre Przywara --- plat/rpi/common/rpi3_common.c | 6 +++++- plat/rpi/rpi4/platform.mk | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/plat/rpi/common/rpi3_common.c b/plat/rpi/common/rpi3_common.c index 8fc357a78..ef88bf10e 100644 --- a/plat/rpi/common/rpi3_common.c +++ b/plat/rpi/common/rpi3_common.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -105,9 +106,10 @@ static const mmap_region_t plat_rpi3_mmap[] = { ******************************************************************************/ static console_t rpi3_console; + static bool rpi3_use_mini_uart(void) { - return true; + return rpi3_gpio_get_select(14) == RPI3_GPIO_FUNC_ALT5; } void rpi3_console_init(void) @@ -118,6 +120,8 @@ void rpi3_console_init(void) if (RPI3_RUNTIME_UART != -1) console_scope |= CONSOLE_FLAG_RUNTIME; + rpi3_gpio_init(); + if (rpi3_use_mini_uart()) rc = console_16550_register(PLAT_RPI_MINI_UART_BASE, 0, diff --git a/plat/rpi/rpi4/platform.mk b/plat/rpi/rpi4/platform.mk index 28fcda8b0..49e78dfed 100644 --- a/plat/rpi/rpi4/platform.mk +++ b/plat/rpi/rpi4/platform.mk @@ -21,6 +21,9 @@ BL31_SOURCES += lib/cpus/aarch64/cortex_a72.S \ drivers/arm/gic/common/gic_common.c \ drivers/arm/gic/v2/gicv2_helpers.c \ drivers/arm/gic/v2/gicv2_main.c \ + drivers/delay_timer/delay_timer.c \ + drivers/gpio/gpio.c \ + drivers/rpi3/gpio/rpi3_gpio.c \ plat/common/plat_gicv2.c \ plat/rpi/rpi4/rpi4_bl31_setup.c \ plat/rpi/common/rpi3_pm.c \ -- cgit v1.2.3 From 9aaae8e6711362f218cef3ea6f52c9df93c137f6 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Fri, 24 Jan 2020 10:46:17 +0000 Subject: rpi: docs: Update maintainers file to new RPi directory scheme With the addition of the Raspberry Pi 4 port the directory structure changed a bit, also the new port didn't have a separate entry. Add a new entry for the RPi4 port and adjust the path names. Signed-off-by: Andre Przywara Change-Id: I04b60e729a19bb0cc3dd6ce6899ec6480356b1f1 --- docs/about/maintainers.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst index 2bf5eb7ba..9e55e60e0 100644 --- a/docs/about/maintainers.rst +++ b/docs/about/maintainers.rst @@ -217,6 +217,17 @@ Raspberry Pi 3 platform port :G: `grandpaul`_ :F: docs/plat/rpi3.rst :F: plat/rpi/rpi3/ +:F: plat/rpi/common/ +:F: drivers/rpi3/ +:F: include/drivers/rpi3/ + +Raspberry Pi 4 platform port +---------------------------- +:M: Andre Przywara +:G: `Andre-ARM`_ +:F: docs/plat/rpi4.rst +:F: plat/rpi/rpi4/ +:F: plat/rpi/common/ :F: drivers/rpi3/ :F: include/drivers/rpi3/ -- cgit v1.2.3 From 493545b3c03979f23a4d97e8191d1081b3ac9171 Mon Sep 17 00:00:00 2001 From: Madhukar Pappireddy Date: Fri, 13 Mar 2020 13:00:17 -0500 Subject: FVP: In BL31/SP_MIN, map only the needed DRAM region statically Rather than creating entry in plat_arm_mmap array to map the entire DRAM region in BL31/SP_MIN, only map a smaller region holding HW_CONFIG DTB. Consequently, an increase in number of sub-translation tables(level-2 and level-3) i.e., MAX_XLAT_TABLES is necessary to map the new region in memory. In order to accommodate the increased code size in BL31 i.e., PROGBITS, the max size of BL31 image is increased by 0x1000(4K). Change-Id: I540b8ee550588e22a3a9fb218183d2ab8061c851 Signed-off-by: Madhukar Pappireddy --- plat/arm/board/fvp/fvp_common.c | 4 ++-- plat/arm/board/fvp/include/platform_def.h | 15 +++++++++++---- plat/arm/board/fvp/platform.mk | 2 ++ plat/arm/board/fvp/sp_min/sp_min-fvp.mk | 2 ++ 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c index 33f3067f3..c5fae56d7 100644 --- a/plat/arm/board/fvp/fvp_common.c +++ b/plat/arm/board/fvp/fvp_common.c @@ -135,7 +135,7 @@ const mmap_region_t plat_arm_mmap[] = { ARM_SPM_BUF_EL3_MMAP, #endif /* Required by fconf APIs to read HW_CONFIG dtb loaded into DRAM */ - ARM_MAP_NS_DRAM1, + ARM_DTB_DRAM_NS, {0} }; @@ -163,7 +163,7 @@ const mmap_region_t plat_arm_mmap[] = { MAP_DEVICE0, MAP_DEVICE1, /* Required by fconf APIs to read HW_CONFIG dtb loaded into DRAM */ - ARM_MAP_NS_DRAM1, + ARM_DTB_DRAM_NS, {0} }; #endif diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h index 69d49bab4..1f569c250 100644 --- a/plat/arm/board/fvp/include/platform_def.h +++ b/plat/arm/board/fvp/include/platform_def.h @@ -52,6 +52,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) + +#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 */ @@ -70,14 +77,14 @@ # else # define PLAT_ARM_MMAP_ENTRIES 9 # if USE_DEBUGFS -# define MAX_XLAT_TABLES 6 +# define MAX_XLAT_TABLES 8 # else -# define MAX_XLAT_TABLES 5 +# define MAX_XLAT_TABLES 7 # endif # endif #elif defined(IMAGE_BL32) # define PLAT_ARM_MMAP_ENTRIES 9 -# define MAX_XLAT_TABLES 5 +# define MAX_XLAT_TABLES 6 #elif !USE_ROMLIB # define PLAT_ARM_MMAP_ENTRIES 11 # define MAX_XLAT_TABLES 5 @@ -126,7 +133,7 @@ * calculated using the current BL31 PROGBITS debug size plus the sizes of * BL2 and BL1-RW */ -#define PLAT_ARM_MAX_BL31_SIZE UL(0x3B000) +#define PLAT_ARM_MAX_BL31_SIZE UL(0x3E000) #endif /* RESET_TO_BL31 */ #ifndef __aarch64__ diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index fc644302d..e55620424 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -204,9 +204,11 @@ 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 \ plat/arm/board/fvp/fconf/fconf_hw_config_getter.c +endif ifeq (${FVP_USE_SP804_TIMER},1) BL31_SOURCES += drivers/arm/sp804/sp804_delay_timer.c 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 520a70f99..36bf441ab 100644 --- a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk +++ b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk @@ -20,8 +20,10 @@ 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 \ plat/arm/board/fvp/fconf/fconf_hw_config_getter.c +endif include plat/arm/common/sp_min/arm_sp_min.mk -- cgit v1.2.3 From 0be136d293c6cec9da1c116e5b2ae353a21b9c49 Mon Sep 17 00:00:00 2001 From: Kalyani Chidambaram Date: Wed, 19 Sep 2018 15:51:46 -0700 Subject: Tegra194: Update t194_nvg.h to v6.7 This patch updates the t194_nvg.h header file received from the CPU team to v6.7. Change-Id: I5d25dfc60448e14b7085250946bd002fcb80a774 Signed-off-by: Kalyani Chidambaram --- .../tegra/soc/t194/drivers/include/t194_nvg.h | 37 ++++++++++++---------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h b/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h index 9ccb82382..7a68a4303 100644 --- a/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h +++ b/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h @@ -7,6 +7,8 @@ #ifndef T194_NVG_H #define T194_NVG_H +#include + /** * t194_nvg.h - Header for the NVIDIA Generic interface (NVG). * Official documentation for this interface is included as part @@ -20,7 +22,7 @@ */ enum { TEGRA_NVG_VERSION_MAJOR = U(6), - TEGRA_NVG_VERSION_MINOR = U(6) + TEGRA_NVG_VERSION_MINOR = U(7) }; typedef enum { @@ -71,6 +73,9 @@ typedef enum { TEGRA_NVG_CHANNEL_DDA_SNOC_GLOBAL_CTRL = U(77), TEGRA_NVG_CHANNEL_DDA_SNOC_CLIENT_REQ_CTRL = U(78), TEGRA_NVG_CHANNEL_DDA_SNOC_CLIENT_REPLENTISH_CTRL = U(79), + TEGRA_NVG_CHANNEL_RT_SAFE_MASK = U(80), + TEGRA_NVG_CHANNEL_RT_WINDOW_US = U(81), + TEGRA_NVG_CHANNEL_RT_FWD_PROGRESS_US = U(82), TEGRA_NVG_CHANNEL_LAST_INDEX } tegra_nvg_channel_id_t; @@ -153,7 +158,7 @@ typedef union { typedef union { uint64_t flat; - struct nvg_power_perf_channel_t { + struct { uint32_t perf_per_watt : U(1); uint32_t reserved_31_1 : U(31); uint32_t reserved_63_32 : U(32); @@ -162,7 +167,7 @@ typedef union { typedef union { uint64_t flat; - struct nvg_power_modes_channel_t { + struct { uint32_t low_battery : U(1); uint32_t reserved_1_1 : U(1); uint32_t battery_save : U(1); @@ -182,7 +187,7 @@ typedef union nvg_channel_1_data_u { typedef union { uint64_t flat; - struct nvg_ccplex_cache_control_channel_t { + struct { uint32_t gpu_ways : U(5); uint32_t reserved_7_5 : U(3); uint32_t gpu_only_ways : U(5); @@ -203,7 +208,7 @@ typedef union nvg_channel_2_data_u { typedef union { uint64_t flat; - struct nvg_wake_time_channel_t { + struct { uint32_t wake_time : U(32); uint32_t reserved_63_32 : U(32); } bits; @@ -211,7 +216,7 @@ typedef union { typedef union { uint64_t flat; - struct nvg_cstate_info_channel_t { + struct { uint32_t cluster_state : U(3); uint32_t reserved_6_3 : U(4); uint32_t update_cluster : U(1); @@ -242,7 +247,7 @@ typedef union { typedef union { uint64_t flat; - struct nvg_lower_bound_channel_t { + struct { uint32_t crossover_value : U(32); uint32_t reserved_63_32 : U(32); } bits; @@ -250,7 +255,7 @@ typedef union { typedef union { uint64_t flat; - struct nvg_cstate_stat_query_channel_t { + struct { uint32_t unit_id : U(4); uint32_t reserved_15_4 : U(12); uint32_t stat_id : U(16); @@ -260,7 +265,7 @@ typedef union { typedef union { uint64_t flat; - struct nvg_num_cores_channel_t { + struct { uint32_t num_cores : U(4); uint32_t reserved_31_4 : U(28); uint32_t reserved_63_32 : U(32); @@ -269,7 +274,7 @@ typedef union { typedef union { uint64_t flat; - struct nvg_unique_logical_id_channel_t { + struct { uint32_t unique_core_id : U(3); uint32_t reserved_31_3 : U(29); uint32_t reserved_63_32 : U(32); @@ -278,7 +283,7 @@ typedef union { typedef union { uint64_t flat; - struct nvg_logical_to_physical_mappings_channel_t { + struct { uint32_t lcore0_pcore_id : U(4); uint32_t lcore1_pcore_id : U(4); uint32_t lcore2_pcore_id : U(4); @@ -306,7 +311,7 @@ typedef union { typedef union { uint64_t flat; - struct nvg_is_sc7_allowed_channel_t { + struct { uint32_t is_sc7_allowed : U(1); uint32_t reserved_31_1 : U(31); uint32_t reserved_63_32 : U(32); @@ -315,7 +320,7 @@ typedef union { typedef union { uint64_t flat; - struct nvg_core_online_channel_t { + struct { uint32_t core_id : U(4); uint32_t reserved_31_4 : U(28); uint32_t reserved_63_32 : U(32); @@ -324,7 +329,7 @@ typedef union { typedef union { uint64_t flat; - struct nvg_cc3_control_channel_t { + struct { uint32_t freq_req : U(9); uint32_t reserved_30_9 : U(22); uint32_t enable : U(1); @@ -374,7 +379,7 @@ typedef enum { typedef union { uint64_t flat; - struct nvg_update_ccplex_gsc_channel_t { + struct { uint32_t gsc_enum : U(16); uint32_t reserved_31_16 : U(16); uint32_t reserved_63_32 : U(32); @@ -411,7 +416,7 @@ typedef union { typedef union { uint64_t flat; - struct nvg_hsm_error_ctrl_channel_t { + struct { uint32_t uncorr : U(1); uint32_t corr : U(1); uint32_t reserved_31_2 : U(30); -- cgit v1.2.3 From 3bab03eb4ba00e021fc3e89c8f41c3e00cfb8dda Mon Sep 17 00:00:00 2001 From: Kalyani Chidambaram Date: Wed, 3 Oct 2018 17:00:17 -0700 Subject: Tegra: aarch64: calculate core position from one place This patch updates 'plat_my_core_pos' handler to call 'plat_core_pos_from_mpidr' instead of implementing the same logic at two places. Change-Id: I1e56adaa10dc2fe3440e5507e0e260d8932e6657 Signed-off-by: Kalyani Chidambaram --- plat/nvidia/tegra/common/aarch64/tegra_helpers.S | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S index 7cba3a449..b6622c7f1 100644 --- a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S +++ b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S @@ -140,17 +140,14 @@ endfunc plat_is_my_cpu_primary * unsigned int plat_my_core_pos(void); * * result: CorePos = CoreId + (ClusterId * cpus per cluster) + * Registers clobbered: x0, x8 * ---------------------------------------------------------- */ func plat_my_core_pos + mov x8, x30 mrs x0, mpidr_el1 - and x1, x0, #MPIDR_CPU_MASK - and x0, x0, #MPIDR_CLUSTER_MASK - lsr x0, x0, #MPIDR_AFFINITY_BITS - mov x2, #PLATFORM_MAX_CPUS_PER_CLUSTER - mul x0, x0, x2 - add x0, x1, x0 - ret + bl plat_core_pos_by_mpidr + ret x8 endfunc plat_my_core_pos /* ----------------------------------------------------- -- cgit v1.2.3 From d55b8f6a89591b8784026b5c818e3cacd8a01f90 Mon Sep 17 00:00:00 2001 From: Kalyani Chidambaram Date: Wed, 12 Sep 2018 14:59:08 -0700 Subject: Tegra194: enable dual execution for EL2 and EL3 This patch enables dual execution optimized translations for EL2 and EL3 CPU exception levels. Change-Id: I28fe98bb05687400f247e94adf44a1f3a85c38b1 Signed-off-by: Varun Wadekar --- include/lib/cpus/aarch64/denver.h | 5 +++++ plat/nvidia/tegra/include/tegra_private.h | 2 ++ plat/nvidia/tegra/soc/t194/plat_psci_handlers.c | 26 +++++++++++++++++++------ plat/nvidia/tegra/soc/t194/plat_setup.c | 21 ++++++++++++++++++++ 4 files changed, 48 insertions(+), 6 deletions(-) diff --git a/include/lib/cpus/aarch64/denver.h b/include/lib/cpus/aarch64/denver.h index 02657a0fb..b98abdf4d 100644 --- a/include/lib/cpus/aarch64/denver.h +++ b/include/lib/cpus/aarch64/denver.h @@ -34,6 +34,11 @@ #define DENVER_CPU_PMSTATE_C7 U(0x7) #define DENVER_CPU_PMSTATE_MASK U(0xF) +/* ACTRL_ELx bits to enable dual execution*/ +#define DENVER_CPU_ENABLE_DUAL_EXEC_EL2 (ULL(1) << 9) +#define DENVER_CPU_ENABLE_DUAL_EXEC_EL3 (ULL(1) << 9) +#define DENVER_CPU_ENABLE_DUAL_EXEC_EL1 (U(1) << 4) + #ifndef __ASSEMBLER__ /* Disable Dynamic Code Optimisation */ diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h index ad3cee4b4..f72c9cf3c 100644 --- a/plat/nvidia/tegra/include/tegra_private.h +++ b/plat/nvidia/tegra/include/tegra_private.h @@ -47,6 +47,8 @@ typedef struct plat_params_from_bl2 { uint64_t sc7entry_fw_size; /* System Suspend Entry Firmware base address */ uint64_t sc7entry_fw_base; + /* Enable dual execution */ + uint8_t enable_ccplex_lock_step; } plat_params_from_bl2_t; /******************************************************************************* diff --git a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c index d92025b8b..bd8200456 100644 --- a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c @@ -368,7 +368,11 @@ int32_t tegra_soc_pwr_domain_on(u_register_t mpidr) int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state) { + const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); + uint8_t enable_ccplex_lock_step = params_from_bl2->enable_ccplex_lock_step; uint8_t stateid_afflvl2 = target_state->pwr_domain_state[PLAT_MAX_PWR_LVL]; + cpu_context_t *ctx = cm_get_context(NON_SECURE); + uint64_t actlr_elx; /* * Reset power state info for CPUs when onlining, we set @@ -446,13 +450,23 @@ int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state) mmio_write_32(TEGRA_XUSB_PADCTL_BASE + XUSB_PADCTL_DEV_AXI_STREAMID_PF_0, TEGRA_SID_XUSB_DEV); } + } - /* - * Reset power state info for the last core doing SC7 - * entry and exit, we set deepest power state as CC7 - * and SC7 for SC7 entry which may not be requested by - * non-secure SW which controls idle states. - */ + /* + * Enable dual execution optimized translations for all ELx. + */ + if (enable_ccplex_lock_step != 0U) { + actlr_elx = read_actlr_el3(); + actlr_elx |= DENVER_CPU_ENABLE_DUAL_EXEC_EL3; + write_actlr_el3(actlr_elx); + + actlr_elx = read_actlr_el2(); + actlr_elx |= DENVER_CPU_ENABLE_DUAL_EXEC_EL2; + write_actlr_el2(actlr_elx); + + actlr_elx = read_actlr_el1(); + actlr_elx |= DENVER_CPU_ENABLE_DUAL_EXEC_EL1; + write_actlr_el1(actlr_elx); } return PSCI_E_SUCCESS; diff --git a/plat/nvidia/tegra/soc/t194/plat_setup.c b/plat/nvidia/tegra/soc/t194/plat_setup.c index 235fba43c..82555403e 100644 --- a/plat/nvidia/tegra/soc/t194/plat_setup.c +++ b/plat/nvidia/tegra/soc/t194/plat_setup.c @@ -201,6 +201,10 @@ void plat_enable_console(int32_t id) ******************************************************************************/ void plat_early_platform_setup(void) { + const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); + uint8_t enable_ccplex_lock_step = params_from_bl2->enable_ccplex_lock_step; + uint64_t actlr_elx; + /* sanity check MCE firmware compatibility */ mce_verify_firmware_version(); @@ -250,6 +254,23 @@ void plat_early_platform_setup(void) mmio_write_32(TEGRA_XUSB_PADCTL_BASE + XUSB_PADCTL_DEV_AXI_STREAMID_PF_0, TEGRA_SID_XUSB_DEV); } + + /* + * Enable dual execution optimized translations for all ELx. + */ + if (enable_ccplex_lock_step != 0U) { + actlr_elx = read_actlr_el3(); + actlr_elx |= DENVER_CPU_ENABLE_DUAL_EXEC_EL3; + write_actlr_el3(actlr_elx); + + actlr_elx = read_actlr_el2(); + actlr_elx |= DENVER_CPU_ENABLE_DUAL_EXEC_EL2; + write_actlr_el2(actlr_elx); + + actlr_elx = read_actlr_el1(); + actlr_elx |= DENVER_CPU_ENABLE_DUAL_EXEC_EL1; + write_actlr_el1(actlr_elx); + } } /* Secure IRQs for Tegra194 */ -- cgit v1.2.3 From a1e12ded4fec1809c116f81e1b7f0c07de35c1e3 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Tue, 16 Oct 2018 15:39:55 -0700 Subject: spd: trusty: disable error messages seen during boot Platforms that do not support Trusty, usually see error messages from the Trusty SPD, during boot. This can be interpreted as a boot failure. This patch lowers the logging level for those error messages to avoid confusion. Change-Id: I931baa2c6db0de1aee17383039bc29ed229a1f25 Signed-off-by: Varun Wadekar --- services/spd/trusty/trusty.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/spd/trusty/trusty.c b/services/spd/trusty/trusty.c index ba2f4a6e4..b10da7679 100644 --- a/services/spd/trusty/trusty.c +++ b/services/spd/trusty/trusty.c @@ -413,7 +413,7 @@ static int32_t trusty_setup(void) /* Get trusty's entry point info */ ep_info = bl31_plat_get_next_image_ep_info(SECURE); if (ep_info == NULL) { - INFO("Trusty image missing.\n"); + VERBOSE("Trusty image missing.\n"); return -1; } @@ -466,7 +466,7 @@ static int32_t trusty_setup(void) trusty_fiq_handler, flags); if (ret != 0) { - ERROR("trusty: failed to register fiq handler, ret = %d\n", ret); + VERBOSE("trusty: failed to register fiq handler, ret = %d\n", ret); } if (aarch32) { -- cgit v1.2.3 From 61c418ba751eb38b599e162393dfac501ca912b8 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Tue, 16 Oct 2018 16:05:41 -0700 Subject: Tegra: increase platform assert logging level to VERBOSE This patch increases the assert logging level for all Tegra platforms to VERBOSE, to print the actual assertion condition to the console, improving debuggability. Change-Id: If3399bde63fa4261522cab984cc9c49cd2073358 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/platform.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/nvidia/tegra/platform.mk b/plat/nvidia/tegra/platform.mk index d0ed5d57a..14b99130c 100644 --- a/plat/nvidia/tegra/platform.mk +++ b/plat/nvidia/tegra/platform.mk @@ -13,7 +13,7 @@ $(eval $(call add_define,CRASH_REPORTING)) # enable assert() for release/debug builds ENABLE_ASSERTIONS := 1 -PLAT_LOG_LEVEL_ASSERT := 40 +PLAT_LOG_LEVEL_ASSERT := 50 $(eval $(call add_define,PLAT_LOG_LEVEL_ASSERT)) # enable dynamic memory mapping -- cgit v1.2.3 From 35aa1c1e51b62467ac31958983a67ef0d5646acb Mon Sep 17 00:00:00 2001 From: Leo He Date: Thu, 12 Jul 2018 17:36:12 +0800 Subject: Tegra210: SE: switch SE clock source to CLK_M In SE suspend, switch SE clock source to CLK_M, to make sure SE clock is on when saving SE context Change-Id: I57c559825a3ec8e0cc35f7a389afc458a5eed0cb Signed-off-by: Leo He Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c b/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c index 635018dbc..48608583d 100644 --- a/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c +++ b/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c @@ -927,17 +927,12 @@ static void tegra_se_enable_clocks(void) val &= ~ENTROPY_RESET_BIT; mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEVICES_W, val); - if (!tegra_chipid_is_t210_b01()) { - - /* - * T210 SE clock source is turned off in kernel, to simplify - * SE clock source setting, we switch SE clock source to - * CLK_M, SE_CLK_DIVISOR = 0. T210 B01 SE clock source is - * always on, so don't need this setting. - */ - mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_RST_CTL_CLK_SRC_SE, - SE_CLK_SRC_CLK_M); - } + /* + * Switch SE clock source to CLK_M, to make sure SE clock + * is on when saving SE context + */ + mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_RST_CTL_CLK_SRC_SE, + SE_CLK_SRC_CLK_M); /* Enable SE clock */ val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_V); -- cgit v1.2.3 From 8336c94dc4c7b25d34bb6f3c5008720746407dad Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Thu, 9 Aug 2018 15:11:23 -0700 Subject: Tegra186: disable PROGRAMMABLE_RESET_ADDRESS This patch disables the code to program reset vector for secondary CPUs to a different entry point, than cold boot. The cold boot entry point has the ability to differentiate between a cold boot and a warm boot, that is controlled by the PROGRAMMABLE_RESET_ADDRESS macro. By reusing the same entry point, we can lock the CPU reset vector during cold boot. Change-Id: Iad400841d57c139469e1d29b5d467197e11958c4 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/include/t186/tegra186_private.h | 1 - plat/nvidia/tegra/soc/t186/plat_psci_handlers.c | 3 -- plat/nvidia/tegra/soc/t186/plat_secondary.c | 11 +------ plat/nvidia/tegra/soc/t186/plat_trampoline.S | 40 ----------------------- plat/nvidia/tegra/soc/t186/platform_t186.mk | 2 +- 5 files changed, 2 insertions(+), 55 deletions(-) diff --git a/plat/nvidia/tegra/include/t186/tegra186_private.h b/plat/nvidia/tegra/include/t186/tegra186_private.h index 60174ab54..b3fdc2c38 100644 --- a/plat/nvidia/tegra/include/t186/tegra186_private.h +++ b/plat/nvidia/tegra/include/t186/tegra186_private.h @@ -11,6 +11,5 @@ void tegra186_cpu_reset_handler(void); uint64_t tegra186_get_cpu_reset_handler_base(void); uint64_t tegra186_get_cpu_reset_handler_size(void); uint64_t tegra186_get_mc_ctx_offset(void); -void tegra186_set_system_suspend_entry(void); #endif /* TEGRA186_PRIVATE_H */ diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c index 179dd9654..4316c985b 100644 --- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c @@ -158,9 +158,6 @@ int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) (void)mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE, (uint64_t)TEGRA_ARI_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0U); - /* set system suspend state for house-keeping */ - tegra186_set_system_suspend_entry(); - } else { ; /* do nothing */ } diff --git a/plat/nvidia/tegra/soc/t186/plat_secondary.c b/plat/nvidia/tegra/soc/t186/plat_secondary.c index 16508093e..8417374ad 100644 --- a/plat/nvidia/tegra/soc/t186/plat_secondary.c +++ b/plat/nvidia/tegra/soc/t186/plat_secondary.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -15,9 +16,6 @@ #include #include -#define MISCREG_AA64_RST_LOW 0x2004U -#define MISCREG_AA64_RST_HIGH 0x2008U - #define SCRATCH_SECURE_RSV1_SCRATCH_0 0x658U #define SCRATCH_SECURE_RSV1_SCRATCH_1 0x65CU @@ -51,16 +49,9 @@ void plat_secondary_setup(void) addr_low = (uint32_t)params_from_bl2->tzdram_base | CPU_RESET_MODE_AA64; addr_high = (uint32_t)((params_from_bl2->tzdram_base >> 32U) & 0x7ffU); - /* write lower 32 bits first, then the upper 11 bits */ - mmio_write_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_LOW, addr_low); - mmio_write_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_HIGH, addr_high); - /* save reset vector to be used during SYSTEM_SUSPEND exit */ mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_LO, addr_low); mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_HI, addr_high); - - /* update reset vector address to the CCPLEX */ - (void)mce_update_reset_vector(); } diff --git a/plat/nvidia/tegra/soc/t186/plat_trampoline.S b/plat/nvidia/tegra/soc/t186/plat_trampoline.S index 818c24b49..adb39f572 100644 --- a/plat/nvidia/tegra/soc/t186/plat_trampoline.S +++ b/plat/nvidia/tegra/soc/t186/plat_trampoline.S @@ -12,31 +12,12 @@ #include #include -#define TEGRA186_STATE_SYSTEM_SUSPEND 0x5C7 -#define TEGRA186_STATE_SYSTEM_RESUME 0x600D #define TEGRA186_MC_CTX_SIZE 0x93 .globl tegra186_cpu_reset_handler /* CPU reset handler routine */ func tegra186_cpu_reset_handler _align=4 - /* check if we are exiting system suspend state */ - adr x0, __tegra186_system_suspend_state - ldr x1, [x0] - mov x2, #TEGRA186_STATE_SYSTEM_SUSPEND - lsl x2, x2, #16 - add x2, x2, #TEGRA186_STATE_SYSTEM_SUSPEND - cmp x1, x2 - bne boot_cpu - - /* set system resume state */ - mov x1, #TEGRA186_STATE_SYSTEM_RESUME - lsl x1, x1, #16 - mov x2, #TEGRA186_STATE_SYSTEM_RESUME - add x1, x1, x2 - str x1, [x0] - dsb sy - /* prepare to relocate to TZSRAM */ mov x0, #BL31_BASE adr x1, __tegra186_cpu_reset_handler_end @@ -101,7 +82,6 @@ __tegra186_cpu_reset_handler_end: .globl tegra186_get_cpu_reset_handler_size .globl tegra186_get_cpu_reset_handler_base .globl tegra186_get_mc_ctx_offset - .globl tegra186_set_system_suspend_entry /* return size of the CPU reset handler */ func tegra186_get_cpu_reset_handler_size @@ -124,23 +104,3 @@ func tegra186_get_mc_ctx_offset sub x0, x0, x1 ret endfunc tegra186_get_mc_ctx_offset - -/* set system suspend state before SC7 entry */ -func tegra186_set_system_suspend_entry - mov x0, #TEGRA_MC_BASE - mov x3, #MC_SECURITY_CFG3_0 - ldr w1, [x0, x3] - lsl x1, x1, #32 - mov x3, #MC_SECURITY_CFG0_0 - ldr w2, [x0, x3] - orr x3, x1, x2 /* TZDRAM base */ - adr x0, __tegra186_system_suspend_state - adr x1, tegra186_cpu_reset_handler - sub x2, x0, x1 /* offset in TZDRAM */ - mov x0, #TEGRA186_STATE_SYSTEM_SUSPEND - lsl x0, x0, #16 - add x0, x0, #TEGRA186_STATE_SYSTEM_SUSPEND - str x0, [x3, x2] /* set value in TZDRAM */ - dsb sy - ret -endfunc tegra186_set_system_suspend_entry diff --git a/plat/nvidia/tegra/soc/t186/platform_t186.mk b/plat/nvidia/tegra/soc/t186/platform_t186.mk index d79155f31..c17dab2bd 100644 --- a/plat/nvidia/tegra/soc/t186/platform_t186.mk +++ b/plat/nvidia/tegra/soc/t186/platform_t186.mk @@ -14,7 +14,7 @@ $(eval $(call add_define,ENABLE_CHIP_VERIFICATION_HARNESS)) RESET_TO_BL31 := 1 -PROGRAMMABLE_RESET_ADDRESS := 1 +PROGRAMMABLE_RESET_ADDRESS := 0 COLD_BOOT_SINGLE_CPU := 1 -- cgit v1.2.3 From 2139c9c8bfb23bbefdfa0f7086dddf1a2f14870f Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Fri, 9 Nov 2018 09:08:16 -0800 Subject: Tegra186: system resume from TZSRAM memory TZSRAM loses power during System suspend, so the entire contents are copied to TZDRAM before Sysem Suspend entry. The warmboot code verifies and restores the contents to TZSRAM during System Resume. This patch removes the code that sets up CPU vector to point to TZSRAM during System Resume as a result. The trampoline code can also be completely removed as a result. Change-Id: I2830eb1db16efef3dfd96c4e3afc41a307588ca1 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/include/t186/tegra186_private.h | 5 +- plat/nvidia/tegra/soc/t186/drivers/se/se.c | 1 - plat/nvidia/tegra/soc/t186/plat_memctrl.c | 18 +---- plat/nvidia/tegra/soc/t186/plat_psci_handlers.c | 16 +++-- plat/nvidia/tegra/soc/t186/plat_secondary.c | 20 +----- plat/nvidia/tegra/soc/t186/plat_trampoline.S | 83 +++-------------------- 6 files changed, 25 insertions(+), 118 deletions(-) diff --git a/plat/nvidia/tegra/include/t186/tegra186_private.h b/plat/nvidia/tegra/include/t186/tegra186_private.h index b3fdc2c38..4514e1477 100644 --- a/plat/nvidia/tegra/include/t186/tegra186_private.h +++ b/plat/nvidia/tegra/include/t186/tegra186_private.h @@ -7,9 +7,6 @@ #ifndef TEGRA186_PRIVATE_H #define TEGRA186_PRIVATE_H -void tegra186_cpu_reset_handler(void); -uint64_t tegra186_get_cpu_reset_handler_base(void); -uint64_t tegra186_get_cpu_reset_handler_size(void); -uint64_t tegra186_get_mc_ctx_offset(void); +uint64_t tegra186_get_mc_ctx_size(void); #endif /* TEGRA186_PRIVATE_H */ diff --git a/plat/nvidia/tegra/soc/t186/drivers/se/se.c b/plat/nvidia/tegra/soc/t186/drivers/se/se.c index dfb9de882..25f8cd028 100644 --- a/plat/nvidia/tegra/soc/t186/drivers/se/se.c +++ b/plat/nvidia/tegra/soc/t186/drivers/se/se.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include "se_private.h" diff --git a/plat/nvidia/tegra/soc/t186/plat_memctrl.c b/plat/nvidia/tegra/soc/t186/plat_memctrl.c index 09377bb09..7ff7e77d9 100644 --- a/plat/nvidia/tegra/soc/t186/plat_memctrl.c +++ b/plat/nvidia/tegra/soc/t186/plat_memctrl.c @@ -10,8 +10,8 @@ #include #include -#include #include +#include #include #include @@ -711,13 +711,6 @@ tegra_mc_settings_t *tegra_get_mc_settings(void) void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes) { uint32_t val; - uint64_t src_base_tzdram; - const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); - uint64_t src_len_in_bytes = BL31_END - BL31_START; - - /* base address of BL3-1 source in TZDRAM */ - src_base_tzdram = params_from_bl2->tzdram_base + - tegra186_get_cpu_reset_handler_size(); /* * Setup the Memory controller to allow only secure accesses to @@ -746,15 +739,6 @@ void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes) val = tegra_mc_read_32(MC_SECURITY_CFG3_0) & MC_SECURITY_BOM_HI_MASK; mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_TZDRAM_ADDR_HI, val); - /* - * save tzdram_addr_lo and ATF-size, this would be used in SC7-RF to - * generate SHA256. - */ - mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV68_LO, - (uint32_t)src_base_tzdram); - mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV0_HI, - (uint32_t)src_len_in_bytes); - /* * MCE propagates the security configuration values across the * CCPLEX. diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c index 4316c985b..6f58427b3 100644 --- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c @@ -134,8 +134,7 @@ int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SECURE_BOOTP_FCFG, val); /* save MC context to TZDRAM */ - mc_ctx_base = params_from_bl2->tzdram_base + - tegra186_get_mc_ctx_offset(); + mc_ctx_base = params_from_bl2->tzdram_base; tegra_mc_save_context((uintptr_t)mc_ctx_base); /* Prepare for system suspend */ @@ -286,7 +285,7 @@ int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_sta if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) { val = params_from_bl2->tzdram_base + - tegra186_get_cpu_reset_handler_size(); + tegra186_get_mc_ctx_size(); /* Initialise communication channel with BPMP */ assert(tegra_bpmp_ipc_init() == 0); @@ -313,10 +312,19 @@ int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_sta * BL3-1 over to TZDRAM. */ val = params_from_bl2->tzdram_base + - tegra186_get_cpu_reset_handler_size(); + tegra186_get_mc_ctx_size(); memcpy16((void *)(uintptr_t)val, (void *)(uintptr_t)BL31_BASE, (uintptr_t)BL31_END - (uintptr_t)BL31_BASE); + /* + * Save code base and size; this would be used by SC7-RF to + * verify binary + */ + mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV68_LO, + (uint32_t)val); + mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV0_HI, + (uint32_t)src_len_in_bytes); + ret = tegra_bpmp_ipc_disable_clock(TEGRA186_CLK_SE); if (ret != 0) { ERROR("Failed to disable clock\n"); diff --git a/plat/nvidia/tegra/soc/t186/plat_secondary.c b/plat/nvidia/tegra/soc/t186/plat_secondary.c index 8417374ad..fbb550af9 100644 --- a/plat/nvidia/tegra/soc/t186/plat_secondary.c +++ b/plat/nvidia/tegra/soc/t186/plat_secondary.c @@ -12,7 +12,6 @@ #include #include -#include #include #include @@ -21,33 +20,18 @@ #define CPU_RESET_MODE_AA64 1U -extern void memcpy16(void *dest, const void *src, unsigned int length); - /******************************************************************************* * Setup secondary CPU vectors ******************************************************************************/ void plat_secondary_setup(void) { uint32_t addr_low, addr_high; - const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); - uint64_t cpu_reset_handler_base, cpu_reset_handler_size; INFO("Setting up secondary CPU boot\n"); - /* - * The BL31 code resides in the TZSRAM which loses state - * when we enter System Suspend. Copy the wakeup trampoline - * code to TZDRAM to help us exit from System Suspend. - */ - cpu_reset_handler_base = tegra186_get_cpu_reset_handler_base(); - cpu_reset_handler_size = tegra186_get_cpu_reset_handler_size(); - (void)memcpy16((void *)(uintptr_t)params_from_bl2->tzdram_base, - (const void *)(uintptr_t)cpu_reset_handler_base, - cpu_reset_handler_size); - /* TZDRAM base will be used as the "resume" address */ - addr_low = (uint32_t)params_from_bl2->tzdram_base | CPU_RESET_MODE_AA64; - addr_high = (uint32_t)((params_from_bl2->tzdram_base >> 32U) & 0x7ffU); + addr_low = (uintptr_t)&tegra_secure_entrypoint | CPU_RESET_MODE_AA64; + addr_high = (uintptr_t)(((uintptr_t)&tegra_secure_entrypoint >> 32U) & 0x7ffU); /* save reset vector to be used during SYSTEM_SUSPEND exit */ mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_LO, diff --git a/plat/nvidia/tegra/soc/t186/plat_trampoline.S b/plat/nvidia/tegra/soc/t186/plat_trampoline.S index adb39f572..2fc2046d0 100644 --- a/plat/nvidia/tegra/soc/t186/plat_trampoline.S +++ b/plat/nvidia/tegra/soc/t186/plat_trampoline.S @@ -14,93 +14,28 @@ #define TEGRA186_MC_CTX_SIZE 0x93 - .globl tegra186_cpu_reset_handler - -/* CPU reset handler routine */ -func tegra186_cpu_reset_handler _align=4 - /* prepare to relocate to TZSRAM */ - mov x0, #BL31_BASE - adr x1, __tegra186_cpu_reset_handler_end - adr x2, __tegra186_cpu_reset_handler_data - ldr x2, [x2, #8] - - /* memcpy16 */ -m_loop16: - cmp x2, #16 - b.lt m_loop1 - ldp x3, x4, [x1], #16 - stp x3, x4, [x0], #16 - sub x2, x2, #16 - b m_loop16 - /* copy byte per byte */ -m_loop1: - cbz x2, boot_cpu - ldrb w3, [x1], #1 - strb w3, [x0], #1 - subs x2, x2, #1 - b.ne m_loop1 - -boot_cpu: - adr x0, __tegra186_cpu_reset_handler_data - ldr x0, [x0] - br x0 -endfunc tegra186_cpu_reset_handler + .globl tegra186_get_mc_ctx_size /* - * Tegra186 reset data (offset 0x0 - 0x430) + * Tegra186 reset data (offset 0x0 - 0x420) * - * 0x000: secure world's entrypoint - * 0x008: BL31 size (RO + RW) - * 0x00C: MC context start - * 0x42C: MC context end + * 0x000: MC context start + * 0x420: MC context end */ .align 4 - .type __tegra186_cpu_reset_handler_data, %object - .globl __tegra186_cpu_reset_handler_data -__tegra186_cpu_reset_handler_data: - .quad tegra_secure_entrypoint - .quad __BL31_END__ - BL31_BASE - - .globl __tegra186_system_suspend_state -__tegra186_system_suspend_state: - .quad 0 - - .align 4 - .globl __tegra186_mc_context __tegra186_mc_context: .rept TEGRA186_MC_CTX_SIZE .quad 0 .endr - .size __tegra186_cpu_reset_handler_data, \ - . - __tegra186_cpu_reset_handler_data .align 4 - .globl __tegra186_cpu_reset_handler_end -__tegra186_cpu_reset_handler_end: - - .globl tegra186_get_cpu_reset_handler_size - .globl tegra186_get_cpu_reset_handler_base - .globl tegra186_get_mc_ctx_offset - -/* return size of the CPU reset handler */ -func tegra186_get_cpu_reset_handler_size - adr x0, __tegra186_cpu_reset_handler_end - adr x1, tegra186_cpu_reset_handler - sub x0, x0, x1 - ret -endfunc tegra186_get_cpu_reset_handler_size - -/* return the start address of the CPU reset handler */ -func tegra186_get_cpu_reset_handler_base - adr x0, tegra186_cpu_reset_handler - ret -endfunc tegra186_get_cpu_reset_handler_base +__tegra186_mc_context_end: /* return the size of the MC context */ -func tegra186_get_mc_ctx_offset - adr x0, __tegra186_mc_context - adr x1, tegra186_cpu_reset_handler +func tegra186_get_mc_ctx_size + adr x0, __tegra186_mc_context_end + adr x1, __tegra186_mc_context sub x0, x0, x1 ret -endfunc tegra186_get_mc_ctx_offset +endfunc tegra186_get_mc_ctx_size -- cgit v1.2.3 From 0600cf63006688e221e183f1fa480c6ec5975ceb Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Mon, 5 Nov 2018 15:12:55 -0800 Subject: tlkd: remove system off/reset handlers TLK does not participate in the system off/reset process and so has no use for the SYSTEM_OFF/RESET notifications. This patch removes the system off/reset handlers as a result. Change-Id: Icf1430b1400cea88000e6d54426eb604a43cbe6c Signed-off-by: Varun Wadekar --- include/bl32/payloads/tlk.h | 3 +-- services/spd/tlkd/tlkd_main.c | 2 +- services/spd/tlkd/tlkd_pm.c | 26 +------------------------- 3 files changed, 3 insertions(+), 28 deletions(-) diff --git a/include/bl32/payloads/tlk.h b/include/bl32/payloads/tlk.h index fe6f3528b..5162d1340 100644 --- a/include/bl32/payloads/tlk.h +++ b/include/bl32/payloads/tlk.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -26,7 +27,6 @@ #define TLK_RESUME_FID TLK_TOS_YIELD_FID(0x100) #define TLK_SYSTEM_SUSPEND TLK_TOS_YIELD_FID(0xE001) #define TLK_SYSTEM_RESUME TLK_TOS_YIELD_FID(0xE002) -#define TLK_SYSTEM_OFF TLK_TOS_YIELD_FID(0xE003) #define TLK_IRQ_FIRED TLK_TOS_YIELD_FID(0xE004) /* @@ -39,7 +39,6 @@ #define TLK_VA_TRANSLATE (0x32000004 | (ULL(1) << 31)) #define TLK_SUSPEND_DONE (0x32000005 | (ULL(1) << 31)) #define TLK_RESUME_DONE (0x32000006 | (ULL(1) << 31)) -#define TLK_SYSTEM_OFF_DONE (0x32000007 | (ULL(1) << 31)) #define TLK_IRQ_DONE (0x32000008 | (ULL(1) << 31)) /* diff --git a/services/spd/tlkd/tlkd_main.c b/services/spd/tlkd/tlkd_main.c index 32ae8ecc9..481bb69e3 100644 --- a/services/spd/tlkd/tlkd_main.c +++ b/services/spd/tlkd/tlkd_main.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -429,7 +430,6 @@ static uintptr_t tlkd_smc_handler(uint32_t smc_fid, */ case TLK_SUSPEND_DONE: case TLK_RESUME_DONE: - case TLK_SYSTEM_OFF_DONE: if (ns) SMC_RET1(handle, SMC_UNK); diff --git a/services/spd/tlkd/tlkd_pm.c b/services/spd/tlkd/tlkd_pm.c index 7d1959bce..ed5bf7761 100644 --- a/services/spd/tlkd/tlkd_pm.c +++ b/services/spd/tlkd/tlkd_pm.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -97,29 +98,6 @@ static void cpu_resume_handler(u_register_t suspend_level) panic(); } -/******************************************************************************* - * System is about to be reset. Inform the SP to allow any book-keeping - ******************************************************************************/ -static void system_off_handler(void) -{ - int cpu = read_mpidr() & MPIDR_CPU_MASK; - gp_regs_t *gp_regs; - - /* TLK runs only on CPU0 */ - if (cpu != 0) - return; - - /* pass system off/reset events to TLK */ - gp_regs = get_gpregs_ctx(&tlk_ctx.cpu_ctx); - write_ctx_reg(gp_regs, CTX_GPREG_X0, TLK_SYSTEM_OFF); - - /* - * Enter the SP. We do not care about the return value because we - * must continue with the shutdown anyway. - */ - (void)tlkd_synchronous_sp_entry(&tlk_ctx); -} - /******************************************************************************* * Structure populated by the Dispatcher to be given a chance to perform any * bookkeeping before PSCI executes a power mgmt. operation. @@ -128,6 +106,4 @@ const spd_pm_ops_t tlkd_pm_ops = { .svc_migrate_info = cpu_migrate_info, .svc_suspend = cpu_suspend_handler, .svc_suspend_finish = cpu_resume_handler, - .svc_system_off = system_off_handler, - .svc_system_reset = system_off_handler }; -- cgit v1.2.3 From 89121c2764a2f550932826e38a16fd0480038f9e Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Thu, 15 Nov 2018 20:44:40 -0800 Subject: Tegra194: reset power state info for CPUs We set deepest power state when offlining a core but that may not be requested by non-secure sw which controls idle states. It will re-init this info from non-secure software when the core come online. This patch resets the power state in the non-secure world context to allow it to start with a clean slate. Change-Id: Iafd92cb2a49571aa6eeb9580beaaff4ba55a87dc Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/soc/t194/plat_psci_handlers.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c index bd8200456..ce5815b46 100644 --- a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c @@ -381,6 +381,10 @@ int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state) * will re-init this info from non-secure software when the * core come online. */ + actlr_elx = read_ctx_reg((get_el1_sysregs_ctx(ctx)), (CTX_ACTLR_EL1)); + actlr_elx &= ~DENVER_CPU_PMSTATE_MASK; + actlr_elx |= DENVER_CPU_PMSTATE_C1; + write_ctx_reg((get_el1_sysregs_ctx(ctx)), (CTX_ACTLR_EL1), (actlr_elx)); /* * Check if we are exiting from deep sleep and restore SE -- cgit v1.2.3 From 0ac1bf7218d5b7146a4cd9a2ec93ef1e3c7b6728 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Tue, 27 Nov 2018 15:47:26 -0800 Subject: Tegra: assembly version of the 'plat_core_pos_by_mpidr' handler The 'plat_core_pos_by_mpidr' handler gets called very early during boot and the compiler generated code overwrites the caller's registers. This patch converts the 'plat_core_pos_by_mpidr' handler into an assembly function and uses registers x0-x3, to fix this anomaly. Change-Id: I8d974e007a0bad039defaf77b11a180d899ead3c Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/aarch64/tegra_helpers.S | 37 ++++++++++++++++++ plat/nvidia/tegra/common/tegra_common.mk | 3 +- plat/nvidia/tegra/common/tegra_topology.c | 48 ------------------------ 3 files changed, 38 insertions(+), 50 deletions(-) delete mode 100644 plat/nvidia/tegra/common/tegra_topology.c diff --git a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S index b6622c7f1..5f01416d8 100644 --- a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S +++ b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S @@ -39,6 +39,7 @@ .globl plat_crash_console_init .globl plat_crash_console_putc .globl plat_crash_console_flush + .weak plat_core_pos_by_mpidr .globl tegra_secure_entrypoint .globl plat_reset_handler @@ -270,6 +271,42 @@ _end: mov x0, x20 ret endfunc plat_reset_handler + /* ------------------------------------------------------ + * int32_t plat_core_pos_by_mpidr(u_register_t mpidr) + * + * This function implements a part of the critical + * interface between the psci generic layer and the + * platform that allows the former to query the platform + * to convert an MPIDR to a unique linear index. An error + * code (-1) is returned in case the MPIDR is invalid. + * + * Clobbers: x0-x3 + * ------------------------------------------------------ + */ +func plat_core_pos_by_mpidr + lsr x1, x0, #MPIDR_AFF0_SHIFT + and x1, x1, #MPIDR_AFFLVL_MASK /* core id */ + lsr x2, x0, #MPIDR_AFF1_SHIFT + and x2, x2, #MPIDR_AFFLVL_MASK /* cluster id */ + + /* core_id >= PLATFORM_MAX_CPUS_PER_CLUSTER */ + mov x0, #-1 + cmp x1, #(PLATFORM_MAX_CPUS_PER_CLUSTER - 1) + b.gt 1f + + /* cluster_id >= PLATFORM_CLUSTER_COUNT */ + cmp x2, #(PLATFORM_CLUSTER_COUNT - 1) + b.gt 1f + + /* CorePos = CoreId + (ClusterId * cpus per cluster) */ + mov x3, #PLATFORM_MAX_CPUS_PER_CLUSTER + mul x3, x3, x2 + add x0, x1, x3 + +1: + ret +endfunc plat_core_pos_by_mpidr + /* ---------------------------------------- * Secure entrypoint function for CPU boot * ---------------------------------------- diff --git a/plat/nvidia/tegra/common/tegra_common.mk b/plat/nvidia/tegra/common/tegra_common.mk index 50c9592f1..66d037fdf 100644 --- a/plat/nvidia/tegra/common/tegra_common.mk +++ b/plat/nvidia/tegra/common/tegra_common.mk @@ -32,5 +32,4 @@ BL31_SOURCES += drivers/delay_timer/delay_timer.c \ ${COMMON_DIR}/tegra_io_storage.c \ ${COMMON_DIR}/tegra_platform.c \ ${COMMON_DIR}/tegra_pm.c \ - ${COMMON_DIR}/tegra_sip_calls.c \ - ${COMMON_DIR}/tegra_topology.c + ${COMMON_DIR}/tegra_sip_calls.c diff --git a/plat/nvidia/tegra/common/tegra_topology.c b/plat/nvidia/tegra/common/tegra_topology.c deleted file mode 100644 index 205b05165..000000000 --- a/plat/nvidia/tegra/common/tegra_topology.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include -#include -#include - -#pragma weak plat_core_pos_by_mpidr - -/******************************************************************************* - * This function implements a part of the critical interface between the psci - * generic layer and the platform that allows the former to query the platform - * to convert an MPIDR to a unique linear index. An error code (-1) is returned - * in case the MPIDR is invalid. - ******************************************************************************/ -int32_t plat_core_pos_by_mpidr(u_register_t mpidr) -{ - u_register_t cluster_id, cpu_id; - int32_t result; - - cluster_id = (mpidr >> (u_register_t)MPIDR_AFF1_SHIFT) & - (u_register_t)MPIDR_AFFLVL_MASK; - cpu_id = (mpidr >> (u_register_t)MPIDR_AFF0_SHIFT) & - (u_register_t)MPIDR_AFFLVL_MASK; - - /* CorePos = CoreId + (ClusterId * cpus per cluster) */ - result = (int32_t)cpu_id + ((int32_t)cluster_id * - PLATFORM_MAX_CPUS_PER_CLUSTER); - - if (cluster_id >= (u_register_t)PLATFORM_CLUSTER_COUNT) { - result = PSCI_E_NOT_PRESENT; - } - - /* - * Validate cpu_id by checking whether it represents a CPU in - * one of the two clusters present on the platform. - */ - if (cpu_id >= (u_register_t)PLATFORM_MAX_CPUS_PER_CLUSTER) { - result = PSCI_E_NOT_PRESENT; - } - - return result; -} -- cgit v1.2.3 From 3d5ed6dee2d9a8dfbba160193b27f064dc1754e7 Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Fri, 28 Feb 2020 12:12:08 +0100 Subject: spmc: manifest changes to support two sample cactus secure partitions When using the SPM Dispatcher, the SPMC sits as a BL32 component (BL32_IMAGE_ID). The SPMC manifest is passed as the TOS fw config component (TOS_FW_CONFIG_ID). It defines platform specific attributes (memory range and physical CPU layout) as well as the attributes for each secure partition (mostly load address). This manifest is passed to the SPMC on boot up. An SP package contains the SP dtb in the SPCI defined partition manifest format. As the SPMC manifest was enriched it needs an increase of tos_fw-config max-size in fvp_fw_config dts. Signed-off-by: Olivier Deprez Change-Id: Ia1dce00c6c4cbaa118fa56617980d32e2956a94e --- plat/arm/board/fvp/fdts/fvp_fw_config.dts | 2 +- plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts | 50 ++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/plat/arm/board/fvp/fdts/fvp_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_fw_config.dts index 9a4a05799..2f7832642 100644 --- a/plat/arm/board/fvp/fdts/fvp_fw_config.dts +++ b/plat/arm/board/fvp/fdts/fvp_fw_config.dts @@ -39,7 +39,7 @@ tos_fw-config { load-address = <0x0 0x04001200>; - max-size = <0x200>; + max-size = <0x1000>; id = ; }; diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts index db3fb5510..79c4c07f6 100644 --- a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts +++ b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts @@ -6,7 +6,7 @@ /dts-v1/; / { - compatible = "spci-core-manifest-1.0"; + compatible = "arm,spci-core-manifest-1.0"; attribute { spmc_id = <0x8000>; @@ -16,4 +16,52 @@ load_address = <0x0 0x6000000>; entrypoint = <0x0 0x6000000>; }; + + chosen { + linux,initrd-start = <0>; + linux,initrd-end = <0>; + }; + + hypervisor { + compatible = "hafnium,hafnium"; + vm1 { + is_spci_partition; + debug_name = "cactus-primary"; + load-addr = <0x7000000>; + }; + vm2 { + is_spci_partition; + debug_name = "cactus-secondary"; + load-addr = <0x7100000>; + vcpu_count = <2>; + mem_size = <1048576>; + }; + }; + + cpus { + #address-cells = <0x2>; + #size-cells = <0x0>; + + cpu-map { + cluster0 { + core0 { + cpu = <0x2>; + }; + }; + }; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x0>; + enable-method = "psci"; + next-level-cache = <0xc>; + phandle = <0x2>; + }; + }; + + memory@60000000 { + device_type = "memory"; + reg = <0x6000000 0x2000000>; /* Trusted DRAM */ + }; }; -- cgit v1.2.3 From 161dbc436424a4522a49b1e5cbac9e7bf84015f4 Mon Sep 17 00:00:00 2001 From: Manish Pandey Date: Thu, 19 Mar 2020 21:06:18 +0000 Subject: fvp: use two instances of Cactus at S-EL1 To demonstrate communication between SP's two instances of Cactus at S-EL1 has been used. This patch replaces Ivy SP with cactus-secondary SP which aligns with changes in tf-a-tests repository. Signed-off-by: Manish Pandey Change-Id: Iee84f1f7f023b7c4f23fbc13682a42614a7f3707 --- plat/arm/board/fvp/fdts/fvp_fw_config.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plat/arm/board/fvp/fdts/fvp_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_fw_config.dts index 9a4a05799..adbfb9609 100644 --- a/plat/arm/board/fvp/fdts/fvp_fw_config.dts +++ b/plat/arm/board/fvp/fdts/fvp_fw_config.dts @@ -102,12 +102,12 @@ secure-partitions { compatible = "arm,sp"; - cactus { + cactus-primary { uuid = <0x1e67b5b4 0xe14f904a 0x13fb1fb8 0xcbdae1da>; load-address = <0x7000000>; }; - ivy { + cactus-secondary { uuid = <0x092358d1 0xb94723f0 0x64447c82 0xc88f57f5>; load-address = <0x7100000>; }; -- cgit v1.2.3 From ae7b922d87597ecde226be632633f11a17ccba20 Mon Sep 17 00:00:00 2001 From: Madhukar Pappireddy Date: Fri, 20 Mar 2020 01:46:21 -0500 Subject: Bug fix: Protect TSP prints with lock CPUs use console to print debug/info messages. This critical section must be guarded by locks to avoid overlaps in messages from multiple CPUs. Change-Id: I786bf90072c1ed73c4f53d8c950979d95255e67e Signed-off-by: Madhukar Pappireddy --- bl32/tsp/tsp_main.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bl32/tsp/tsp_main.c b/bl32/tsp/tsp_main.c index 9da2f9af9..e9478380c 100644 --- a/bl32/tsp/tsp_main.c +++ b/bl32/tsp/tsp_main.c @@ -371,12 +371,16 @@ tsp_args_t *tsp_smc_handler(uint64_t func, tsp_stats[linear_id].smc_count++; tsp_stats[linear_id].eret_count++; +#if LOG_LEVEL >= LOG_LEVEL_INFO + spin_lock(&console_lock); INFO("TSP: cpu 0x%lx received %s smc 0x%llx\n", read_mpidr(), ((func >> 31) & 1) == 1 ? "fast" : "yielding", func); INFO("TSP: cpu 0x%lx: %d smcs, %d erets\n", read_mpidr(), tsp_stats[linear_id].smc_count, tsp_stats[linear_id].eret_count); + spin_unlock(&console_lock); +#endif /* Render secure services and obtain results here */ results[0] = arg1; -- cgit v1.2.3 From 76a7fc23c1e2f434abb1762fcdbab1f91517c29b Mon Sep 17 00:00:00 2001 From: Madhukar Pappireddy Date: Fri, 20 Mar 2020 01:32:32 -0500 Subject: Changelog updates for recent commits Change-Id: I09191a51dd9ee673c54b422ba4eb35c46c6dc30e Signed-off-by: Madhukar Pappireddy --- docs/change-log-upcoming.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/change-log-upcoming.rst b/docs/change-log-upcoming.rst index f86280f76..3abc5cc68 100644 --- a/docs/change-log-upcoming.rst +++ b/docs/change-log-upcoming.rst @@ -29,6 +29,7 @@ New Features - CPU Support - Example: "cortex-a55: Workaround for erratum 1221012" + - Use Speculation Barrier instruction for v8.5+ cores - Drivers - Example: "console: Allow the console to register multiple times" @@ -43,6 +44,8 @@ New Features - Platforms - Example: "arm/common: Introduce wrapper functions to setup secure watchdog" - plat/arm: Add support for the new `dualroot` chain of trust. + - plat/arm/fvp: Add support for fconf in BL31 and SP_MIN. Populate power + domain desciptor dynamically by leveraging fconf APIs. - PSCI - Example: "Adding new optional PSCI hook ``pwr_domain_on_finish_late``" @@ -51,6 +54,7 @@ New Features - Example: "UBSAN support and handlers" - Add support for optional firmware encryption feature (experimental). - Introduce a new `dualroot` chain of trust. + - aarch32: stop speculative execution past exception returns. - Tools - Example: "fiptool: Add support to build fiptool on Windows." -- cgit v1.2.3 From 7f164a83a9d9cade9917f448c629d85913ff10c6 Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Fri, 20 Mar 2020 14:22:05 +0100 Subject: context: TPIDR_EL2 register not saved/restored TPIDR_EL2 is missing from the EL2 state register save/restore sequence. This patch adds it to the context save restore routines. Signed-off-by: Olivier Deprez Change-Id: I35fc5ee82f97b72bcedac57c791312e7b3a45251 --- include/lib/el3_runtime/aarch64/context.h | 6 ++++-- lib/el3_runtime/aarch64/context.S | 18 ++++++++++++------ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h index e061950c8..0029658ac 100644 --- a/include/lib/el3_runtime/aarch64/context.h +++ b/include/lib/el3_runtime/aarch64/context.h @@ -183,7 +183,7 @@ #define CTX_SPSR_EL2 U(0xd0) #define CTX_SP_EL2 U(0xd8) #define CTX_TCR_EL2 U(0xe0) -#define CTX_TRFCR_EL2 U(0xe8) +#define CTX_TPIDR_EL2 U(0xe8) #define CTX_TTBR0_EL2 U(0xf0) #define CTX_VBAR_EL2 U(0xf8) #define CTX_VMPIDR_EL2 U(0x100) @@ -234,11 +234,13 @@ #define CTX_VSESR_EL2 U(0x228) #define CTX_VSTCR_EL2 U(0x230) #define CTX_VSTTBR_EL2 U(0x238) +#define CTX_TRFCR_EL2 U(0x240) // Starting with Armv8.5 -#define CTX_SCXTNUM_EL2 U(0x240) +#define CTX_SCXTNUM_EL2 U(0x248) /* Align to the next 16 byte boundary */ #define CTX_EL2_SYSREGS_END U(0x250) + #endif /* CTX_INCLUDE_EL2_REGS */ /******************************************************************************* diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S index 30ad7b7d1..221f33e06 100644 --- a/lib/el3_runtime/aarch64/context.S +++ b/lib/el3_runtime/aarch64/context.S @@ -100,7 +100,7 @@ func el2_sysregs_context_save stp x10, x11, [x0, #CTX_SPSR_EL2] mrs x12, tcr_el2 - mrs x13, TRFCR_EL2 + mrs x13, tpidr_el2 stp x12, x13, [x0, #CTX_TCR_EL2] mrs x14, ttbr0_el2 @@ -204,11 +204,14 @@ func el2_sysregs_context_save mrs x16, vsttbr_el2 str x16, [x0, #CTX_VSTTBR_EL2] + + mrs x17, TRFCR_EL2 + str x17, [x0, #CTX_TRFCR_EL2] #endif #if ARM_ARCH_AT_LEAST(8, 5) - mrs x17, scxtnum_el2 - str x17, [x0, #CTX_SCXTNUM_EL2] + mrs x9, scxtnum_el2 + str x9, [x0, #CTX_SCXTNUM_EL2] #endif ret @@ -289,7 +292,7 @@ func el2_sysregs_context_restore ldp x12, x13, [x0, #CTX_TCR_EL2] msr tcr_el2, x12 - msr TRFCR_EL2, x13 + msr tpidr_el2, x13 ldp x14, x15, [x0, #CTX_TTBR0_EL2] msr ttbr0_el2, x14 @@ -391,11 +394,14 @@ func el2_sysregs_context_restore ldr x16, [x0, #CTX_VSTTBR_EL2] msr vsttbr_el2, x16 + + ldr x17, [x0, #CTX_TRFCR_EL2] + msr TRFCR_EL2, x17 #endif #if ARM_ARCH_AT_LEAST(8, 5) - ldr x17, [x0, #CTX_SCXTNUM_EL2] - msr scxtnum_el2, x17 + ldr x9, [x0, #CTX_SCXTNUM_EL2] + msr scxtnum_el2, x9 #endif ret -- cgit v1.2.3 From 2bf1085d58c3c934be1873f758ddce626601297a Mon Sep 17 00:00:00 2001 From: Kalyani Chidambaram Date: Wed, 19 Dec 2018 11:06:14 -0800 Subject: Tegra: remove support for SEPARATE_CODE_AND_RODATA=0 Tegra platforms will not be supporting SEPARATE_CODE_AND_RODATA=0. This patch uses the common macros provided by bl_common.h as a result and adds a check to assert if SEPARATE_CODE_AND_RODATA set is not set to '1'. Change-Id: I376ea60c00ad69cb855d89418bdb80623f14800e Signed-off-by: Kalyani Chidambaram --- plat/nvidia/tegra/common/tegra_bl31_setup.c | 17 +++++------------ plat/nvidia/tegra/include/platform_def.h | 8 ++++++++ 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c index 46686c368..05890772e 100644 --- a/plat/nvidia/tegra/common/tegra_bl31_setup.c +++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c @@ -39,15 +39,8 @@ * Declarations of linker defined symbols which will help us find the layout * of trusted SRAM ******************************************************************************/ - IMPORT_SYM(uint64_t, __RW_START__, BL31_RW_START); -static const uint64_t BL31_RW_END = BL_END; -static const uint64_t BL31_RODATA_BASE = BL_RO_DATA_BASE; -static const uint64_t BL31_RODATA_END = BL_RO_DATA_END; -static const uint64_t TEXT_START = BL_CODE_BASE; -static const uint64_t TEXT_END = BL_CODE_END; - extern uint64_t tegra_bl31_phys_base; static entry_point_info_t bl33_image_ep_info, bl32_image_ep_info; @@ -314,11 +307,11 @@ void bl31_plat_runtime_setup(void) void bl31_plat_arch_setup(void) { uint64_t rw_start = BL31_RW_START; - uint64_t rw_size = BL31_RW_END - BL31_RW_START; - uint64_t rodata_start = BL31_RODATA_BASE; - uint64_t rodata_size = BL31_RODATA_END - BL31_RODATA_BASE; - uint64_t code_base = TEXT_START; - uint64_t code_size = TEXT_END - TEXT_START; + uint64_t rw_size = BL_END - BL31_RW_START; + uint64_t rodata_start = BL_RO_DATA_BASE; + uint64_t rodata_size = BL_RO_DATA_END - BL_RO_DATA_BASE; + uint64_t code_base = BL_CODE_BASE; + uint64_t code_size = BL_CODE_END - BL_CODE_BASE; const mmap_region_t *plat_mmio_map = NULL; #if USE_COHERENT_MEM uint32_t coh_start, coh_size; diff --git a/plat/nvidia/tegra/include/platform_def.h b/plat/nvidia/tegra/include/platform_def.h index eb55def4a..817f480a2 100644 --- a/plat/nvidia/tegra/include/platform_def.h +++ b/plat/nvidia/tegra/include/platform_def.h @@ -12,6 +12,13 @@ #include +/******************************************************************************* + * Check and error if SEPARATE_CODE_AND_RODATA is not set to 1 + ******************************************************************************/ +#if !SEPARATE_CODE_AND_RODATA +#error "SEPARATE_CODE_AND_RODATA should be set to 1" +#endif + /* * Platform binary types for linking */ @@ -72,4 +79,5 @@ #define MAX_IO_DEVICES U(0) #define MAX_IO_HANDLES U(0) + #endif /* PLATFORM_DEF_H */ -- cgit v1.2.3 From a5bfcad8518f84beb250ea697b71e5fc7c0cf3a5 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Fri, 21 Dec 2018 10:53:53 -0800 Subject: Tegra: include missing stdbool.h This patch includes the missing stdbool.h header from flowctrl.h and bpmp_ivc.c files. Change-Id: If60d19142b1cb8ae663fbdbdf1ffe45cbbdbc1b2 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.c | 1 + plat/nvidia/tegra/include/drivers/flowctrl.h | 3 +++ 2 files changed, 4 insertions(+) diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.c b/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.c index 57daf6aeb..d964fc001 100644 --- a/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.c +++ b/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include diff --git a/plat/nvidia/tegra/include/drivers/flowctrl.h b/plat/nvidia/tegra/include/drivers/flowctrl.h index 54336b044..e5ab600b4 100644 --- a/plat/nvidia/tegra/include/drivers/flowctrl.h +++ b/plat/nvidia/tegra/include/drivers/flowctrl.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,6 +10,8 @@ #include +#include + #include #define FLOWCTRL_HALT_CPU0_EVENTS (0x0U) -- cgit v1.2.3 From 42080d489231614a19865c5b6b962e55e94c6f5a Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Fri, 21 Dec 2018 10:55:42 -0800 Subject: Tegra: remove circular dependency with common_def.h This patch stops including common_def.h from platform_def.h to fix a circular depoendency between them. This means platform_def.h now has to define the linker macros: * PLATFORM_LINKER_FORMAT * PLATFORM_LINKER_ARCH Change-Id: Icd540b1bd32fb37e0e455e9146c8b7f4b314e012 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/include/platform_def.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/plat/nvidia/tegra/include/platform_def.h b/plat/nvidia/tegra/include/platform_def.h index 817f480a2..8a8a0d268 100644 --- a/plat/nvidia/tegra/include/platform_def.h +++ b/plat/nvidia/tegra/include/platform_def.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -25,6 +26,12 @@ #define PLATFORM_LINKER_FORMAT "elf64-littleaarch64" #define PLATFORM_LINKER_ARCH aarch64 +/* + * Platform binary types for linking + */ +#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64" +#define PLATFORM_LINKER_ARCH aarch64 + /******************************************************************************* * Generic platform constants ******************************************************************************/ -- cgit v1.2.3 From aba5dddc62c5db79e0bcc033376a98db84665a33 Mon Sep 17 00:00:00 2001 From: Kalyani Chidambaram Date: Tue, 18 Dec 2018 13:51:18 -0800 Subject: Tegra: remove support for USE_COHERENT_MEM This patch removes the support for 'USE_COHERENT_MEM' as Tegra platforms no longer support the feature. Change-Id: If1c80fc4e5974412572b3bc1fdf9e70b1ee5d4ec Signed-off-by: Kalyani Chidambaram --- plat/nvidia/tegra/common/tegra_bl31_setup.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c index 05890772e..269afb196 100644 --- a/plat/nvidia/tegra/common/tegra_bl31_setup.c +++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c @@ -313,9 +313,6 @@ void bl31_plat_arch_setup(void) uint64_t code_base = BL_CODE_BASE; uint64_t code_size = BL_CODE_END - BL_CODE_BASE; const mmap_region_t *plat_mmio_map = NULL; -#if USE_COHERENT_MEM - uint32_t coh_start, coh_size; -#endif const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); /* @@ -342,15 +339,6 @@ void bl31_plat_arch_setup(void) code_size, MT_CODE | MT_SECURE); -#if USE_COHERENT_MEM - coh_start = total_base + (BL_COHERENT_RAM_BASE - BL31_RO_BASE); - coh_size = BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE; - - mmap_add_region(coh_start, coh_start, - coh_size, - (uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE); -#endif - /* map TZDRAM used by BL31 as coherent memory */ if (TEGRA_TZRAM_BASE == tegra_bl31_phys_base) { mmap_add_region(params_from_bl2->tzdram_base, -- cgit v1.2.3 From 9b51aa87a741ebabe02de758bd3a83712ddc44a4 Mon Sep 17 00:00:00 2001 From: Ken Chang Date: Fri, 28 Dec 2018 08:44:12 +0800 Subject: Tegra: memctrl: map video memory as uncached Memmap video memory as uncached normal memory by adding flag 'MT_NON_CACHEABLE' in mmap_add_dynamic_region(). This improves the time taken for clearing the non-overlapping video memory: test conditions: 32MB memory size, EMC running at 1866MHz, t186 1) without MT_NON_CACHEABLE: 30ms ~ 40ms <3>[ 133.852885] vpr-heap: update vpr base to 0x00000000c6000000, size=e000000 <3>[ 133.860471] _tegra_set_vpr_params[120]: begin <3>[ 133.896481] _tegra_set_vpr_params[123]: end <3>[ 133.908944] vpr-heap: update vpr base to 0x00000000c6000000, size=c000000 <3>[ 133.916397] _tegra_set_vpr_params[120]: begin <3>[ 133.956369] _tegra_set_vpr_params[123]: end <3>[ 133.970394] vpr-heap: update vpr base to 0x00000000c6000000, size=a000000 <3>[ 133.977934] _tegra_set_vpr_params[120]: begin <3>[ 134.013874] _tegra_set_vpr_params[123]: end <3>[ 134.025666] vpr-heap: update vpr base to 0x00000000c6000000, size=8000000 <3>[ 134.033512] _tegra_set_vpr_params[120]: begin <3>[ 134.065996] _tegra_set_vpr_params[123]: end <3>[ 134.075465] vpr-heap: update vpr base to 0x00000000c6000000, size=6000000 <3>[ 134.082923] _tegra_set_vpr_params[120]: begin <3>[ 134.113119] _tegra_set_vpr_params[123]: end <3>[ 134.123448] vpr-heap: update vpr base to 0x00000000c6000000, size=4000000 <3>[ 134.130790] _tegra_set_vpr_params[120]: begin <3>[ 134.162523] _tegra_set_vpr_params[123]: end <3>[ 134.172413] vpr-heap: update vpr base to 0x00000000c6000000, size=2000000 <3>[ 134.179772] _tegra_set_vpr_params[120]: begin <3>[ 134.209142] _tegra_set_vpr_params[123]: end 2) with MT_NON_CACHEABLE: 10ms ~ 18ms <3>[ 102.108702] vpr-heap: update vpr base to 0x00000000c6000000, size=e000000 <3>[ 102.116296] _tegra_set_vpr_params[120]: begin <3>[ 102.134272] _tegra_set_vpr_params[123]: end <3>[ 102.145839] vpr-heap: update vpr base to 0x00000000c6000000, size=c000000 <3>[ 102.153226] _tegra_set_vpr_params[120]: begin <3>[ 102.164201] _tegra_set_vpr_params[123]: end <3>[ 102.172275] vpr-heap: update vpr base to 0x00000000c6000000, size=a000000 <3>[ 102.179638] _tegra_set_vpr_params[120]: begin <3>[ 102.190342] _tegra_set_vpr_params[123]: end <3>[ 102.197524] vpr-heap: update vpr base to 0x00000000c6000000, size=8000000 <3>[ 102.205085] _tegra_set_vpr_params[120]: begin <3>[ 102.216112] _tegra_set_vpr_params[123]: end <3>[ 102.224080] vpr-heap: update vpr base to 0x00000000c6000000, size=6000000 <3>[ 102.231387] _tegra_set_vpr_params[120]: begin <3>[ 102.241775] _tegra_set_vpr_params[123]: end <3>[ 102.248825] vpr-heap: update vpr base to 0x00000000c6000000, size=4000000 <3>[ 102.256069] _tegra_set_vpr_params[120]: begin <3>[ 102.266368] _tegra_set_vpr_params[123]: end <3>[ 102.273400] vpr-heap: update vpr base to 0x00000000c6000000, size=2000000 <3>[ 102.280672] _tegra_set_vpr_params[120]: begin <3>[ 102.290929] _tegra_set_vpr_params[123]: end Change-Id: I5f604064ce7b8b73ea9ad5860156ae5e2c6cc42a Signed-off-by: Ken Chang --- plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c | 5 +++-- plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c index 92fa273b5..c3f95db4d 100644 --- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c +++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -117,7 +117,8 @@ static void tegra_clear_videomem(uintptr_t non_overlap_area_start, ret = mmap_add_dynamic_region(non_overlap_area_start, /* PA */ non_overlap_area_start, /* VA */ non_overlap_area_size, /* size */ - MT_NS | MT_RW | MT_EXECUTE_NEVER); /* attrs */ + MT_NS | MT_RW | MT_EXECUTE_NEVER | + MT_NON_CACHEABLE); /* attrs */ assert(ret == 0); zeromem((void *)non_overlap_area_start, non_overlap_area_size); diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c index a53f66078..2d91cb290 100644 --- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c +++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c @@ -348,7 +348,8 @@ static void tegra_clear_videomem(uintptr_t non_overlap_area_start, ret = mmap_add_dynamic_region(non_overlap_area_start, /* PA */ non_overlap_area_start, /* VA */ non_overlap_area_size, /* size */ - MT_NS | MT_RW | MT_EXECUTE_NEVER); /* attrs */ + MT_NS | MT_RW | MT_EXECUTE_NEVER | + MT_NON_CACHEABLE); /* attrs */ assert(ret == 0); zero_normalmem((void *)non_overlap_area_start, non_overlap_area_size); -- cgit v1.2.3 From 8f0e22d56092ff104ddfe7cbb86c003261bfdb67 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Mon, 10 Dec 2018 13:28:25 -0800 Subject: Tegra194: SiP function ID to read SMMU_PER registers This patch introduces SiP function ID, 0xC200FF00, to read SMMU_PER error records from all supported SMMU blocks. The register values are passed over to the client via CPU registers X1 - X3, where X1 = SMMU_PER[instance #1] | SMMU_PER[instance #0] X2 = SMMU_PER[instance #3] | SMMU_PER[instance #2] X3 = SMMU_PER[instance #5] | SMMU_PER[instance #4] Change-Id: Id56263f558838ad05f6021f8432e618e99e190fc Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/soc/t194/plat_sip_calls.c | 36 +++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/plat/nvidia/tegra/soc/t194/plat_sip_calls.c b/plat/nvidia/tegra/soc/t194/plat_sip_calls.c index 33694a16d..884762de7 100644 --- a/plat/nvidia/tegra/soc/t194/plat_sip_calls.c +++ b/plat/nvidia/tegra/soc/t194/plat_sip_calls.c @@ -16,11 +16,13 @@ #include #include #include +#include #include /******************************************************************************* * Tegra194 SiP SMCs ******************************************************************************/ +#define TEGRA_SIP_GET_SMMU_PER 0xC200FF00U /******************************************************************************* * This function is responsible for handling all T194 SiP calls @@ -34,13 +36,43 @@ int32_t plat_sip_handler(uint32_t smc_fid, void *handle, uint64_t flags) { - int32_t ret = -ENOTSUP; + int32_t ret = 0; + uint32_t i, smmu_per[6] = {0}; + uint32_t num_smmu_devices = plat_get_num_smmu_devices(); + uint64_t per[3] = {0ULL}; - (void)smc_fid; (void)x1; (void)x4; (void)cookie; (void)flags; + switch (smc_fid) { + case TEGRA_SIP_GET_SMMU_PER: + + /* make sure we dont go past the array length */ + assert(num_smmu_devices <= ARRAY_SIZE(smmu_per)); + + /* read all supported SMMU_PER records */ + for (i = 0U; i < num_smmu_devices; i++) { + smmu_per[i] = tegra_smmu_read_32(i, SMMU_GSR0_PER); + } + + /* pack results into 3 64bit variables. */ + per[0] = smmu_per[0] | ((uint64_t)smmu_per[1] << 32U); + per[1] = smmu_per[2] | ((uint64_t)smmu_per[3] << 32U); + per[2] = smmu_per[4] | ((uint64_t)smmu_per[5] << 32U); + + /* provide the results via X1-X3 CPU registers */ + write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X1, per[0]); + write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X2, per[1]); + write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X3, per[2]); + + break; + + default: + ret = -ENOTSUP; + break; + } + return ret; } -- cgit v1.2.3 From ebe076da237878822fb6e335dda00d3cb03853d1 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Mon, 28 Jan 2019 17:00:32 -0800 Subject: Tegra210: rename ENABLE_WDT_LEGACY_FIQ_HANDLING macro This patch renames 'ENABLE_WDT_LEGACY_FIQ_HANDLING' macro to 'ENABLE_TEGRA_WDT_LEGACY_FIQ_HANDLING', to indicate that this is a Tegra feature. Change-Id: I5c4431e662223ee80efbfd5ec2513f8b1cadfc50 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/platform.mk | 4 ++-- plat/nvidia/tegra/soc/t210/platform_t210.mk | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/plat/nvidia/tegra/platform.mk b/plat/nvidia/tegra/platform.mk index 14b99130c..87588202c 100644 --- a/plat/nvidia/tegra/platform.mk +++ b/plat/nvidia/tegra/platform.mk @@ -40,7 +40,7 @@ OVERRIDE_LIBC := 1 # Flag to enable WDT FIQ interrupt handling for Tegra SoCs # prior to Tegra186 -ENABLE_WDT_LEGACY_FIQ_HANDLING ?= 0 +ENABLE_TEGRA_WDT_LEGACY_FIQ_HANDLING ?= 0 # Flag to allow relocation of BL32 image to TZDRAM during boot RELOCATE_BL32_IMAGE ?= 0 @@ -48,7 +48,7 @@ RELOCATE_BL32_IMAGE ?= 0 include plat/nvidia/tegra/common/tegra_common.mk include ${SOC_DIR}/platform_${TARGET_SOC}.mk -$(eval $(call add_define,ENABLE_WDT_LEGACY_FIQ_HANDLING)) +$(eval $(call add_define,ENABLE_TEGRA_WDT_LEGACY_FIQ_HANDLING)) $(eval $(call add_define,RELOCATE_BL32_IMAGE)) # modify BUILD_PLAT to point to SoC specific build directory diff --git a/plat/nvidia/tegra/soc/t210/platform_t210.mk b/plat/nvidia/tegra/soc/t210/platform_t210.mk index ba827a073..a5662be02 100644 --- a/plat/nvidia/tegra/soc/t210/platform_t210.mk +++ b/plat/nvidia/tegra/soc/t210/platform_t210.mk @@ -23,8 +23,7 @@ $(eval $(call add_define,MAX_XLAT_TABLES)) MAX_MMAP_REGIONS := 16 $(eval $(call add_define,MAX_MMAP_REGIONS)) -ENABLE_WDT_LEGACY_FIQ_HANDLING := 1 -$(eval $(call add_define,ENABLE_WDT_LEGACY_FIQ_HANDLING)) +ENABLE_TEGRA_WDT_LEGACY_FIQ_HANDLING := 1 PLAT_INCLUDES += -I${SOC_DIR}/drivers/se -- cgit v1.2.3 From eeb1b5e36849b0de529ba220ed20c3146e6584b6 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Thu, 17 Jan 2019 16:36:23 -0800 Subject: Tegra: include platform headers from individual makefiles This patch modifies PLAT_INCLUDES to include individual Tegra SoC headers from the platform's makefile. Change-Id: If5248667f4e58ac18727d37a18fbba8e53f2d7b5 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/tegra_common.mk | 3 +-- plat/nvidia/tegra/soc/t132/platform_t132.mk | 3 +++ plat/nvidia/tegra/soc/t186/platform_t186.mk | 3 ++- plat/nvidia/tegra/soc/t194/platform_t194.mk | 3 ++- plat/nvidia/tegra/soc/t210/platform_t210.mk | 3 ++- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/plat/nvidia/tegra/common/tegra_common.mk b/plat/nvidia/tegra/common/tegra_common.mk index 66d037fdf..c946a7597 100644 --- a/plat/nvidia/tegra/common/tegra_common.mk +++ b/plat/nvidia/tegra/common/tegra_common.mk @@ -6,8 +6,7 @@ PLAT_INCLUDES := -Iplat/nvidia/tegra/include/drivers \ -Iplat/nvidia/tegra/include/lib \ - -Iplat/nvidia/tegra/include \ - -Iplat/nvidia/tegra/include/${TARGET_SOC} + -Iplat/nvidia/tegra/include include lib/xlat_tables_v2/xlat_tables.mk PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS} diff --git a/plat/nvidia/tegra/soc/t132/platform_t132.mk b/plat/nvidia/tegra/soc/t132/platform_t132.mk index 183e1889c..16bd0ead2 100644 --- a/plat/nvidia/tegra/soc/t132/platform_t132.mk +++ b/plat/nvidia/tegra/soc/t132/platform_t132.mk @@ -20,6 +20,9 @@ $(eval $(call add_define,MAX_XLAT_TABLES)) MAX_MMAP_REGIONS := 8 $(eval $(call add_define,MAX_MMAP_REGIONS)) +# platform files +PLAT_INCLUDES += -Iplat/nvidia/tegra/include/t132 + BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \ lib/cpus/aarch64/denver.S \ ${COMMON_DIR}/drivers/flowctrl/flowctrl.c \ diff --git a/plat/nvidia/tegra/soc/t186/platform_t186.mk b/plat/nvidia/tegra/soc/t186/platform_t186.mk index c17dab2bd..a5341236d 100644 --- a/plat/nvidia/tegra/soc/t186/platform_t186.mk +++ b/plat/nvidia/tegra/soc/t186/platform_t186.mk @@ -37,7 +37,8 @@ MAX_MMAP_REGIONS := 27 $(eval $(call add_define,MAX_MMAP_REGIONS)) # platform files -PLAT_INCLUDES += -I${SOC_DIR}/drivers/include +PLAT_INCLUDES += -Iplat/nvidia/tegra/include/t186 \ + -I${SOC_DIR}/drivers/include BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \ lib/cpus/aarch64/denver.S \ diff --git a/plat/nvidia/tegra/soc/t194/platform_t194.mk b/plat/nvidia/tegra/soc/t194/platform_t194.mk index 78766fcbe..9ee9138b4 100644 --- a/plat/nvidia/tegra/soc/t194/platform_t194.mk +++ b/plat/nvidia/tegra/soc/t194/platform_t194.mk @@ -37,7 +37,8 @@ MAX_MMAP_REGIONS := 30 $(eval $(call add_define,MAX_MMAP_REGIONS)) # platform files -PLAT_INCLUDES += -I${SOC_DIR}/drivers/include +PLAT_INCLUDES += -Iplat/nvidia/tegra/include/t194 \ + -I${SOC_DIR}/drivers/include BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \ lib/cpus/aarch64/denver.S \ diff --git a/plat/nvidia/tegra/soc/t210/platform_t210.mk b/plat/nvidia/tegra/soc/t210/platform_t210.mk index a5662be02..14e3324a8 100644 --- a/plat/nvidia/tegra/soc/t210/platform_t210.mk +++ b/plat/nvidia/tegra/soc/t210/platform_t210.mk @@ -25,7 +25,8 @@ $(eval $(call add_define,MAX_MMAP_REGIONS)) ENABLE_TEGRA_WDT_LEGACY_FIQ_HANDLING := 1 -PLAT_INCLUDES += -I${SOC_DIR}/drivers/se +PLAT_INCLUDES += -Iplat/nvidia/tegra/include/t210 \ + -I${SOC_DIR}/drivers/se BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \ lib/cpus/aarch64/cortex_a53.S \ -- cgit v1.2.3 From 713769515f66add17f2a874311619a9874d088ae Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Wed, 23 Jan 2019 16:54:12 -0800 Subject: Tegra: memctrl_v2: remove support to secure TZSRAM This patch removes support to secure the on-chip TZSRAM memory for Tegra186 and Tegra194 platforms as the previous bootloader does that for them. Change-Id: I50c7b7f9694285fe31135ada09baed1cfedaaf07 Signed-off-by: Varun Wadekar --- .../tegra/common/drivers/memctrl/memctrl_v2.c | 64 +--------------------- plat/nvidia/tegra/include/drivers/mce.h | 3 +- plat/nvidia/tegra/soc/t186/drivers/mce/mce.c | 9 +-- plat/nvidia/tegra/soc/t194/drivers/mce/mce.c | 19 ------- 4 files changed, 3 insertions(+), 92 deletions(-) diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c index 2d91cb290..5555f5df3 100644 --- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c +++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c @@ -159,69 +159,7 @@ void tegra_memctrl_tzdram_setup(uint64_t phys_base, uint32_t size_in_bytes) */ void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes) { - uint32_t index; - uint32_t total_128kb_blocks = size_in_bytes >> 17; - uint32_t residual_4kb_blocks = (size_in_bytes & (uint32_t)0x1FFFF) >> 12; - uint32_t val; - - INFO("Configuring TrustZone SRAM Memory Carveout\n"); - - /* - * Reset the access configuration registers to restrict access - * to the TZRAM aperture - */ - for (index = MC_TZRAM_CLIENT_ACCESS0_CFG0; - index < ((uint32_t)MC_TZRAM_CARVEOUT_CFG + (uint32_t)MC_GSC_CONFIG_REGS_SIZE); - index += 4U) { - tegra_mc_write_32(index, 0); - } - - /* - * Enable CPU access configuration registers to access the TZRAM aperture - */ - if (!tegra_chipid_is_t186()) { - val = tegra_mc_read_32(MC_TZRAM_CLIENT_ACCESS1_CFG0); - val |= TZRAM_ALLOW_MPCORER | TZRAM_ALLOW_MPCOREW; - tegra_mc_write_32(MC_TZRAM_CLIENT_ACCESS1_CFG0, val); - } - - /* - * Set the TZRAM base. TZRAM base must be 4k aligned, at least. - */ - assert((phys_base & (uint64_t)0xFFF) == 0U); - tegra_mc_write_32(MC_TZRAM_BASE_LO, (uint32_t)phys_base); - tegra_mc_write_32(MC_TZRAM_BASE_HI, - (uint32_t)(phys_base >> 32) & MC_GSC_BASE_HI_MASK); - - /* - * Set the TZRAM size - * - * total size = (number of 128KB blocks) + (number of remaining 4KB - * blocks) - * - */ - val = (residual_4kb_blocks << MC_GSC_SIZE_RANGE_4KB_SHIFT) | - total_128kb_blocks; - tegra_mc_write_32(MC_TZRAM_SIZE, val); - - /* - * Lock the configuration settings by disabling TZ-only lock - * and locking the configuration against any future changes - * at all. - */ - val = tegra_mc_read_32(MC_TZRAM_CARVEOUT_CFG); - val &= (uint32_t)~MC_GSC_ENABLE_TZ_LOCK_BIT; - val |= MC_GSC_LOCK_CFG_SETTINGS_BIT; - if (!tegra_chipid_is_t186()) { - val |= MC_GSC_ENABLE_CPU_SECURE_BIT; - } - tegra_mc_write_32(MC_TZRAM_CARVEOUT_CFG, val); - - /* - * MCE propagates the security configuration values across the - * CCPLEX. - */ - mce_update_gsc_tzram(); + ; /* do nothing */ } /* diff --git a/plat/nvidia/tegra/include/drivers/mce.h b/plat/nvidia/tegra/include/drivers/mce.h index 4470b6b8b..5f1bb4f28 100644 --- a/plat/nvidia/tegra/include/drivers/mce.h +++ b/plat/nvidia/tegra/include/drivers/mce.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -69,7 +69,6 @@ int mce_command_handler(uint64_t cmd, uint64_t arg0, uint64_t arg1, int mce_update_reset_vector(void); int mce_update_gsc_videomem(void); int mce_update_gsc_tzdram(void); -int mce_update_gsc_tzram(void); __dead2 void mce_enter_ccplex_state(uint32_t state_idx); void mce_update_cstate_info(const mce_cstate_info_t *cstate); void mce_verify_firmware_version(void); diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c b/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c index 9e42b2bcb..54d3b2ccd 100644 --- a/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c +++ b/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -385,14 +386,6 @@ int32_t mce_update_gsc_tzdram(void) return mce_update_ccplex_gsc(TEGRA_ARI_GSC_TZ_DRAM_IDX); } -/******************************************************************************* - * Handler to update carveout values for TZ SysRAM aperture - ******************************************************************************/ -int32_t mce_update_gsc_tzram(void) -{ - return mce_update_ccplex_gsc(TEGRA_ARI_GSC_TZRAM); -} - /******************************************************************************* * Handler to shutdown/reset the entire system ******************************************************************************/ diff --git a/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c b/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c index 00c671bcc..7edd7a09e 100644 --- a/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c +++ b/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c @@ -115,25 +115,6 @@ int32_t mce_update_gsc_tzdram(void) return ret; } -/******************************************************************************* - * Handler to update carveout values for TZ SysRAM aperture - ******************************************************************************/ -int32_t mce_update_gsc_tzram(void) -{ - int32_t ret; - - /* - * MCE firmware is not running on simulation platforms. - */ - if (mce_firmware_not_supported()) { - ret = -EINVAL; - } else { - ret = nvg_update_ccplex_gsc((uint32_t)TEGRA_NVG_CHANNEL_UPDATE_GSC_TZRAM); - } - - return ret; -} - /******************************************************************************* * Handler to issue the UPDATE_CSTATE_INFO request ******************************************************************************/ -- cgit v1.2.3 From 36e263753694fbe881110c85701e8245f5538491 Mon Sep 17 00:00:00 2001 From: Pritesh Raithatha Date: Mon, 7 Jan 2019 12:02:09 +0530 Subject: Tegra: memctrl: cleanup streamid override registers Streamid override registers are passed to memctrl to program bypass streamid for all the registers. There is no reason to bypass SMMU for any of the client so need to remove register list and do not set streamid_override_cfg. Some Tegra186 platforms don't boot due to SDMMC failure so keep SDMMC bypass as of now. Will revisit once these issues are fixed. Change-Id: I3f67e2a0e1b53160e2218f3acace7da45532f934 Signed-off-by: Pritesh Raithatha --- plat/nvidia/tegra/soc/t186/plat_memctrl.c | 64 ------------- plat/nvidia/tegra/soc/t194/plat_memctrl.c | 146 ------------------------------ 2 files changed, 210 deletions(-) diff --git a/plat/nvidia/tegra/soc/t186/plat_memctrl.c b/plat/nvidia/tegra/soc/t186/plat_memctrl.c index 7ff7e77d9..4eb68e44a 100644 --- a/plat/nvidia/tegra/soc/t186/plat_memctrl.c +++ b/plat/nvidia/tegra/soc/t186/plat_memctrl.c @@ -21,29 +21,6 @@ extern uint64_t tegra_bl31_phys_base; * Array to hold stream_id override config register offsets ******************************************************************************/ const static uint32_t tegra186_streamid_override_regs[] = { - MC_STREAMID_OVERRIDE_CFG_PTCR, - MC_STREAMID_OVERRIDE_CFG_AFIR, - MC_STREAMID_OVERRIDE_CFG_HDAR, - MC_STREAMID_OVERRIDE_CFG_HOST1XDMAR, - MC_STREAMID_OVERRIDE_CFG_NVENCSRD, - MC_STREAMID_OVERRIDE_CFG_SATAR, - MC_STREAMID_OVERRIDE_CFG_MPCORER, - MC_STREAMID_OVERRIDE_CFG_NVENCSWR, - MC_STREAMID_OVERRIDE_CFG_AFIW, - MC_STREAMID_OVERRIDE_CFG_HDAW, - MC_STREAMID_OVERRIDE_CFG_MPCOREW, - MC_STREAMID_OVERRIDE_CFG_SATAW, - MC_STREAMID_OVERRIDE_CFG_ISPRA, - MC_STREAMID_OVERRIDE_CFG_ISPWA, - MC_STREAMID_OVERRIDE_CFG_ISPWB, - MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTR, - MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTW, - MC_STREAMID_OVERRIDE_CFG_XUSB_DEVR, - MC_STREAMID_OVERRIDE_CFG_XUSB_DEVW, - MC_STREAMID_OVERRIDE_CFG_TSECSRD, - MC_STREAMID_OVERRIDE_CFG_TSECSWR, - MC_STREAMID_OVERRIDE_CFG_GPUSRD, - MC_STREAMID_OVERRIDE_CFG_GPUSWR, MC_STREAMID_OVERRIDE_CFG_SDMMCRA, MC_STREAMID_OVERRIDE_CFG_SDMMCRAA, MC_STREAMID_OVERRIDE_CFG_SDMMCR, @@ -52,47 +29,6 @@ const static uint32_t tegra186_streamid_override_regs[] = { MC_STREAMID_OVERRIDE_CFG_SDMMCWAA, MC_STREAMID_OVERRIDE_CFG_SDMMCW, MC_STREAMID_OVERRIDE_CFG_SDMMCWAB, - MC_STREAMID_OVERRIDE_CFG_VICSRD, - MC_STREAMID_OVERRIDE_CFG_VICSWR, - MC_STREAMID_OVERRIDE_CFG_VIW, - MC_STREAMID_OVERRIDE_CFG_NVDECSRD, - MC_STREAMID_OVERRIDE_CFG_NVDECSWR, - MC_STREAMID_OVERRIDE_CFG_APER, - MC_STREAMID_OVERRIDE_CFG_APEW, - MC_STREAMID_OVERRIDE_CFG_NVJPGSRD, - MC_STREAMID_OVERRIDE_CFG_NVJPGSWR, - MC_STREAMID_OVERRIDE_CFG_SESRD, - MC_STREAMID_OVERRIDE_CFG_SESWR, - MC_STREAMID_OVERRIDE_CFG_ETRR, - MC_STREAMID_OVERRIDE_CFG_ETRW, - MC_STREAMID_OVERRIDE_CFG_TSECSRDB, - MC_STREAMID_OVERRIDE_CFG_TSECSWRB, - MC_STREAMID_OVERRIDE_CFG_GPUSRD2, - MC_STREAMID_OVERRIDE_CFG_GPUSWR2, - MC_STREAMID_OVERRIDE_CFG_AXISR, - MC_STREAMID_OVERRIDE_CFG_AXISW, - MC_STREAMID_OVERRIDE_CFG_EQOSR, - MC_STREAMID_OVERRIDE_CFG_EQOSW, - MC_STREAMID_OVERRIDE_CFG_UFSHCR, - MC_STREAMID_OVERRIDE_CFG_UFSHCW, - MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR, - MC_STREAMID_OVERRIDE_CFG_BPMPR, - MC_STREAMID_OVERRIDE_CFG_BPMPW, - MC_STREAMID_OVERRIDE_CFG_BPMPDMAR, - MC_STREAMID_OVERRIDE_CFG_BPMPDMAW, - MC_STREAMID_OVERRIDE_CFG_AONR, - MC_STREAMID_OVERRIDE_CFG_AONW, - MC_STREAMID_OVERRIDE_CFG_AONDMAR, - MC_STREAMID_OVERRIDE_CFG_AONDMAW, - MC_STREAMID_OVERRIDE_CFG_SCER, - MC_STREAMID_OVERRIDE_CFG_SCEW, - MC_STREAMID_OVERRIDE_CFG_SCEDMAR, - MC_STREAMID_OVERRIDE_CFG_SCEDMAW, - MC_STREAMID_OVERRIDE_CFG_APEDMAR, - MC_STREAMID_OVERRIDE_CFG_APEDMAW, - MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR1, - MC_STREAMID_OVERRIDE_CFG_VICSRD1, - MC_STREAMID_OVERRIDE_CFG_NVDECSRD1 }; /******************************************************************************* diff --git a/plat/nvidia/tegra/soc/t194/plat_memctrl.c b/plat/nvidia/tegra/soc/t194/plat_memctrl.c index 2d5f8e3c6..9a4d22e68 100644 --- a/plat/nvidia/tegra/soc/t194/plat_memctrl.c +++ b/plat/nvidia/tegra/soc/t194/plat_memctrl.c @@ -11,150 +11,6 @@ #include #include -/******************************************************************************* - * Array to hold stream_id override config register offsets - ******************************************************************************/ -const static uint32_t tegra194_streamid_override_regs[] = { - MC_STREAMID_OVERRIDE_CFG_PTCR, - MC_STREAMID_OVERRIDE_CFG_HDAR, - MC_STREAMID_OVERRIDE_CFG_HOST1XDMAR, - MC_STREAMID_OVERRIDE_CFG_NVENCSRD, - MC_STREAMID_OVERRIDE_CFG_SATAR, - MC_STREAMID_OVERRIDE_CFG_MPCORER, - MC_STREAMID_OVERRIDE_CFG_NVENCSWR, - MC_STREAMID_OVERRIDE_CFG_HDAW, - MC_STREAMID_OVERRIDE_CFG_MPCOREW, - MC_STREAMID_OVERRIDE_CFG_SATAW, - MC_STREAMID_OVERRIDE_CFG_ISPRA, - MC_STREAMID_OVERRIDE_CFG_ISPFALR, - MC_STREAMID_OVERRIDE_CFG_ISPWA, - MC_STREAMID_OVERRIDE_CFG_ISPWB, - MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTR, - MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTW, - MC_STREAMID_OVERRIDE_CFG_XUSB_DEVR, - MC_STREAMID_OVERRIDE_CFG_XUSB_DEVW, - MC_STREAMID_OVERRIDE_CFG_TSECSRD, - MC_STREAMID_OVERRIDE_CFG_TSECSWR, - MC_STREAMID_OVERRIDE_CFG_SDMMCRA, - MC_STREAMID_OVERRIDE_CFG_SDMMCR, - MC_STREAMID_OVERRIDE_CFG_SDMMCRAB, - MC_STREAMID_OVERRIDE_CFG_SDMMCWA, - MC_STREAMID_OVERRIDE_CFG_SDMMCW, - MC_STREAMID_OVERRIDE_CFG_SDMMCWAB, - MC_STREAMID_OVERRIDE_CFG_VICSRD, - MC_STREAMID_OVERRIDE_CFG_VICSWR, - MC_STREAMID_OVERRIDE_CFG_VIW, - MC_STREAMID_OVERRIDE_CFG_NVDECSRD, - MC_STREAMID_OVERRIDE_CFG_NVDECSWR, - MC_STREAMID_OVERRIDE_CFG_APER, - MC_STREAMID_OVERRIDE_CFG_APEW, - MC_STREAMID_OVERRIDE_CFG_NVJPGSRD, - MC_STREAMID_OVERRIDE_CFG_NVJPGSWR, - MC_STREAMID_OVERRIDE_CFG_SESRD, - MC_STREAMID_OVERRIDE_CFG_SESWR, - MC_STREAMID_OVERRIDE_CFG_AXIAPR, - MC_STREAMID_OVERRIDE_CFG_AXIAPW, - MC_STREAMID_OVERRIDE_CFG_ETRR, - MC_STREAMID_OVERRIDE_CFG_ETRW, - MC_STREAMID_OVERRIDE_CFG_TSECSRDB, - MC_STREAMID_OVERRIDE_CFG_TSECSWRB, - MC_STREAMID_OVERRIDE_CFG_AXISR, - MC_STREAMID_OVERRIDE_CFG_AXISW, - MC_STREAMID_OVERRIDE_CFG_EQOSR, - MC_STREAMID_OVERRIDE_CFG_EQOSW, - MC_STREAMID_OVERRIDE_CFG_UFSHCR, - MC_STREAMID_OVERRIDE_CFG_UFSHCW, - MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR, - MC_STREAMID_OVERRIDE_CFG_BPMPR, - MC_STREAMID_OVERRIDE_CFG_BPMPW, - MC_STREAMID_OVERRIDE_CFG_BPMPDMAR, - MC_STREAMID_OVERRIDE_CFG_BPMPDMAW, - MC_STREAMID_OVERRIDE_CFG_AONR, - MC_STREAMID_OVERRIDE_CFG_AONW, - MC_STREAMID_OVERRIDE_CFG_AONDMAR, - MC_STREAMID_OVERRIDE_CFG_AONDMAW, - MC_STREAMID_OVERRIDE_CFG_SCER, - MC_STREAMID_OVERRIDE_CFG_SCEW, - MC_STREAMID_OVERRIDE_CFG_SCEDMAR, - MC_STREAMID_OVERRIDE_CFG_SCEDMAW, - MC_STREAMID_OVERRIDE_CFG_APEDMAR, - MC_STREAMID_OVERRIDE_CFG_APEDMAW, - MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR1, - MC_STREAMID_OVERRIDE_CFG_VICSRD1, - MC_STREAMID_OVERRIDE_CFG_NVDECSRD1, - MC_STREAMID_OVERRIDE_CFG_VIFALR, - MC_STREAMID_OVERRIDE_CFG_VIFALW, - MC_STREAMID_OVERRIDE_CFG_DLA0RDA, - MC_STREAMID_OVERRIDE_CFG_DLA0FALRDB, - MC_STREAMID_OVERRIDE_CFG_DLA0WRA, - MC_STREAMID_OVERRIDE_CFG_DLA0FALWRB, - MC_STREAMID_OVERRIDE_CFG_DLA1RDA, - MC_STREAMID_OVERRIDE_CFG_DLA1FALRDB, - MC_STREAMID_OVERRIDE_CFG_DLA1WRA, - MC_STREAMID_OVERRIDE_CFG_DLA1FALWRB, - MC_STREAMID_OVERRIDE_CFG_PVA0RDA, - MC_STREAMID_OVERRIDE_CFG_PVA0RDB, - MC_STREAMID_OVERRIDE_CFG_PVA0RDC, - MC_STREAMID_OVERRIDE_CFG_PVA0WRA, - MC_STREAMID_OVERRIDE_CFG_PVA0WRB, - MC_STREAMID_OVERRIDE_CFG_PVA0WRC, - MC_STREAMID_OVERRIDE_CFG_PVA1RDA, - MC_STREAMID_OVERRIDE_CFG_PVA1RDB, - MC_STREAMID_OVERRIDE_CFG_PVA1RDC, - MC_STREAMID_OVERRIDE_CFG_PVA1WRA, - MC_STREAMID_OVERRIDE_CFG_PVA1WRB, - MC_STREAMID_OVERRIDE_CFG_PVA1WRC, - MC_STREAMID_OVERRIDE_CFG_RCER, - MC_STREAMID_OVERRIDE_CFG_RCEW, - MC_STREAMID_OVERRIDE_CFG_RCEDMAR, - MC_STREAMID_OVERRIDE_CFG_RCEDMAW, - MC_STREAMID_OVERRIDE_CFG_NVENC1SRD, - MC_STREAMID_OVERRIDE_CFG_NVENC1SWR, - MC_STREAMID_OVERRIDE_CFG_PCIE0R, - MC_STREAMID_OVERRIDE_CFG_PCIE0W, - MC_STREAMID_OVERRIDE_CFG_PCIE1R, - MC_STREAMID_OVERRIDE_CFG_PCIE1W, - MC_STREAMID_OVERRIDE_CFG_PCIE2AR, - MC_STREAMID_OVERRIDE_CFG_PCIE2AW, - MC_STREAMID_OVERRIDE_CFG_PCIE3R, - MC_STREAMID_OVERRIDE_CFG_PCIE3W, - MC_STREAMID_OVERRIDE_CFG_PCIE4R, - MC_STREAMID_OVERRIDE_CFG_PCIE4W, - MC_STREAMID_OVERRIDE_CFG_PCIE5R, - MC_STREAMID_OVERRIDE_CFG_PCIE5W, - MC_STREAMID_OVERRIDE_CFG_ISPFALW, - MC_STREAMID_OVERRIDE_CFG_DLA0RDA1, - MC_STREAMID_OVERRIDE_CFG_DLA1RDA1, - MC_STREAMID_OVERRIDE_CFG_PVA0RDA1, - MC_STREAMID_OVERRIDE_CFG_PVA0RDB1, - MC_STREAMID_OVERRIDE_CFG_PVA1RDA1, - MC_STREAMID_OVERRIDE_CFG_PVA1RDB1, - MC_STREAMID_OVERRIDE_CFG_PCIE5R1, - MC_STREAMID_OVERRIDE_CFG_NVENCSRD1, - MC_STREAMID_OVERRIDE_CFG_NVENC1SRD1, - MC_STREAMID_OVERRIDE_CFG_ISPRA1, - MC_STREAMID_OVERRIDE_CFG_PCIE0R1, - MC_STREAMID_OVERRIDE_CFG_NVDEC1SRD, - MC_STREAMID_OVERRIDE_CFG_NVDEC1SRD1, - MC_STREAMID_OVERRIDE_CFG_NVDEC1SWR, - MC_STREAMID_OVERRIDE_CFG_MIU0R, - MC_STREAMID_OVERRIDE_CFG_MIU0W, - MC_STREAMID_OVERRIDE_CFG_MIU1R, - MC_STREAMID_OVERRIDE_CFG_MIU1W, - MC_STREAMID_OVERRIDE_CFG_MIU2R, - MC_STREAMID_OVERRIDE_CFG_MIU2W, - MC_STREAMID_OVERRIDE_CFG_MIU3R, - MC_STREAMID_OVERRIDE_CFG_MIU3W, - MC_STREAMID_OVERRIDE_CFG_MIU4R, - MC_STREAMID_OVERRIDE_CFG_MIU4W, - MC_STREAMID_OVERRIDE_CFG_MIU5R, - MC_STREAMID_OVERRIDE_CFG_MIU5W, - MC_STREAMID_OVERRIDE_CFG_MIU6R, - MC_STREAMID_OVERRIDE_CFG_MIU6W, - MC_STREAMID_OVERRIDE_CFG_MIU7R, - MC_STREAMID_OVERRIDE_CFG_MIU7W -}; - /******************************************************************************* * Array to hold the security configs for stream IDs ******************************************************************************/ @@ -571,8 +427,6 @@ static mc_regs_t *tegra194_get_mc_system_suspend_ctx(void) * Struct to hold the memory controller settings ******************************************************************************/ static tegra_mc_settings_t tegra194_mc_settings = { - .streamid_override_cfg = tegra194_streamid_override_regs, - .num_streamid_override_cfgs = (uint32_t)ARRAY_SIZE(tegra194_streamid_override_regs), .streamid_security_cfg = tegra194_streamid_sec_cfgs, .num_streamid_security_cfgs = (uint32_t)ARRAY_SIZE(tegra194_streamid_sec_cfgs), .get_mc_system_suspend_ctx = tegra194_get_mc_system_suspend_ctx -- cgit v1.2.3 From a45c3e9d81c0c8f3ab4a1724bf2f7373464f021e Mon Sep 17 00:00:00 2001 From: sumitg Date: Fri, 8 Feb 2019 16:14:06 +0530 Subject: Tegra210: trigger CPU0 hotplug power on using FC Hotplug poweron is not working for boot CPU as it's being triggerred using PMC and not with Flow Controller. This is happening because "cpu_powergate_mask" is only getting set for non-boot CPU's as the boot CPU's first bootup follows different code path. The patch is marking a CPU as ON within "cpu_powergate_mask" when turning its power domain on during power on. This will ensure only first bootup on all CPU's is using PMC and subsequent hotplug poweron will be using Flow Controller. Change-Id: Ie9e86e6f9a777d41508a93d2ce286f31307932c2 Signed-off-by: sumitg --- plat/nvidia/tegra/soc/t210/plat_psci_handlers.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c index f29e624ea..7f73ea506 100644 --- a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c @@ -533,6 +533,13 @@ int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state) } } + /* + * Mark this CPU as ON in the cpu_powergate_mask[], + * so that we use Flow Controller for all subsequent + * power ups. + */ + cpu_powergate_mask[plat_my_core_pos()] = 1; + /* * T210 has a dedicated ARMv7 boot and power mgmt processor, BPMP. It's * used for power management and boot purposes. Inform the BPMP that @@ -561,7 +568,6 @@ int tegra_soc_pwr_domain_on(u_register_t mpidr) /* Turn on CPU using flow controller or PMC */ if (cpu_powergate_mask[cpu] == 0) { tegra_pmc_cpu_on(cpu); - cpu_powergate_mask[cpu] = 1; } else { tegra_fc_cpu_on(cpu); } -- cgit v1.2.3 From bd0c2f8d99533f2fa497444e7b8c52ac0a3d76cd Mon Sep 17 00:00:00 2001 From: Mustafa Yigit Bilgen Date: Mon, 3 Dec 2018 15:53:38 -0800 Subject: spd: tlkd: support new TLK SMCs for RPMB service This patch adds support to handle following TLK SMCs: {TLK_SET_BL_VERSION, TLK_LOCK_BL_INTERFACE, TLK_BL_RPMB_SERVICE} These SMCs need to be supported in ATF in order to forward them to TLK. Otherwise, these functionalities won't work. Brief: TLK_SET_BL_VERSION: This SMC is issued by the bootloader to supply its version to TLK. TLK can use this to prevent rollback attacks. TLK_LOCK_BL_INTERFACE: This SMC is issued by bootloader before handing off execution to the OS. This allows preventing sensitive SMCs being used by the OS. TLK_BL_RPMB_SERVICE: bootloader issues this SMC to sign or verify RPMB frames. Tested by: Tests TLK can receive the new SMCs issued by bootloader Change-Id: I57c2d189a5f7a77cea26c3f8921866f2a6f0f944 Signed-off-by: Mustafa Yigit Bilgen --- include/bl32/payloads/tlk.h | 3 +++ services/spd/tlkd/tlkd_main.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/include/bl32/payloads/tlk.h b/include/bl32/payloads/tlk.h index 5162d1340..290f32923 100644 --- a/include/bl32/payloads/tlk.h +++ b/include/bl32/payloads/tlk.h @@ -24,6 +24,9 @@ #define TLK_SS_REGISTER_HANDLER TLK_TOS_YIELD_FID(0x3) #define TLK_REGISTER_NS_DRAM_RANGES TLK_TOS_YIELD_FID(0x4) #define TLK_SET_ROOT_OF_TRUST TLK_TOS_YIELD_FID(0x5) +#define TLK_SET_BL_VERSION TLK_TOS_YIELD_FID(0x6) +#define TLK_LOCK_BL_INTERFACE TLK_TOS_YIELD_FID(0x7) +#define TLK_BL_RPMB_SERVICE TLK_TOS_YIELD_FID(0x8) #define TLK_RESUME_FID TLK_TOS_YIELD_FID(0x100) #define TLK_SYSTEM_SUSPEND TLK_TOS_YIELD_FID(0xE001) #define TLK_SYSTEM_RESUME TLK_TOS_YIELD_FID(0xE002) diff --git a/services/spd/tlkd/tlkd_main.c b/services/spd/tlkd/tlkd_main.c index 481bb69e3..ecac43522 100644 --- a/services/spd/tlkd/tlkd_main.c +++ b/services/spd/tlkd/tlkd_main.c @@ -272,6 +272,9 @@ static uintptr_t tlkd_smc_handler(uint32_t smc_fid, case TLK_TA_LAUNCH_OP: case TLK_TA_SEND_EVENT: case TLK_RESUME_FID: + case TLK_SET_BL_VERSION: + case TLK_LOCK_BL_INTERFACE: + case TLK_BL_RPMB_SERVICE: if (!ns) SMC_RET1(handle, SMC_UNK); -- cgit v1.2.3 From 7644e2aa6ecd110e213bdb422c2df0ce6290c0a0 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Fri, 5 Oct 2018 11:24:54 -0700 Subject: Tegra: gicv2: initialize target masks This patch initializes the target masks in the GICv2 driver data, for all PEs. This will allow platforms to set the PE target for SPIs. Change-Id: I7bf2ad79c04c2555ab310acba17823fb157327a3 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/tegra_gicv2.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/plat/nvidia/tegra/common/tegra_gicv2.c b/plat/nvidia/tegra/common/tegra_gicv2.c index 293df8d4f..012107e3b 100644 --- a/plat/nvidia/tegra/common/tegra_gicv2.c +++ b/plat/nvidia/tegra/common/tegra_gicv2.c @@ -1,20 +1,23 @@ /* * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include - #include #include #include #include +#include #include #include +static unsigned int tegra_target_masks[PLATFORM_CORE_COUNT]; + /****************************************************************************** * Tegra common helper to setup the GICv2 driver data. *****************************************************************************/ @@ -33,6 +36,8 @@ void tegra_gic_setup(const interrupt_prop_t *interrupt_props, tegra_gic_data.gicc_base = TEGRA_GICC_BASE; tegra_gic_data.interrupt_props = interrupt_props; tegra_gic_data.interrupt_props_num = interrupt_props_num; + tegra_gic_data.target_masks = tegra_target_masks; + tegra_gic_data.target_masks_num = ARRAY_SIZE(tegra_target_masks); gicv2_driver_init(&tegra_gic_data); } @@ -43,6 +48,7 @@ void tegra_gic_init(void) { gicv2_distif_init(); gicv2_pcpu_distif_init(); + gicv2_set_pe_target_mask(plat_my_core_pos()); gicv2_cpuif_enable(); } @@ -61,5 +67,6 @@ void tegra_gic_cpuif_deactivate(void) void tegra_gic_pcpu_init(void) { gicv2_pcpu_distif_init(); + gicv2_set_pe_target_mask(plat_my_core_pos()); gicv2_cpuif_enable(); } -- cgit v1.2.3 From 9aaa8882eb62034d88eef30171ad1af01ca47b7b Mon Sep 17 00:00:00 2001 From: Anthony Zhou Date: Mon, 11 Mar 2019 15:50:32 +0800 Subject: Tegra194: move cluster and CPU counter to header file. MISRA rules request that the cluster and CPU counter be unsigned values and have a suffix 'U'. If the define located in the makefile, this cannot be done. This patch moves the PLATFORM_CLUSTER_COUNT and PLATFORM_MAX_CPUS_PER_CLUSTER macros to tegra_def.h as a result. Change-Id: I9ef0beb29485729de204b4ffbb5241b039690e5a Signed-off-by: Anthony Zhou --- plat/nvidia/tegra/include/platform_def.h | 2 +- plat/nvidia/tegra/include/t194/tegra_def.h | 6 ++++++ plat/nvidia/tegra/soc/t194/platform_t194.mk | 6 ------ 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/plat/nvidia/tegra/include/platform_def.h b/plat/nvidia/tegra/include/platform_def.h index 8a8a0d268..91a24ca7e 100644 --- a/plat/nvidia/tegra/include/platform_def.h +++ b/plat/nvidia/tegra/include/platform_def.h @@ -47,7 +47,7 @@ #define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER_COUNT * \ PLATFORM_MAX_CPUS_PER_CLUSTER) #define PLAT_NUM_PWR_DOMAINS (PLATFORM_CORE_COUNT + \ - PLATFORM_CLUSTER_COUNT + 1) + PLATFORM_CLUSTER_COUNT + U(1)) /******************************************************************************* * Platform console related constants diff --git a/plat/nvidia/tegra/include/t194/tegra_def.h b/plat/nvidia/tegra/include/t194/tegra_def.h index dc0644514..e39f9cad6 100644 --- a/plat/nvidia/tegra/include/t194/tegra_def.h +++ b/plat/nvidia/tegra/include/t194/tegra_def.h @@ -9,6 +9,12 @@ #include +/******************************************************************************* + * Chip specific cluster and cpu numbers + ******************************************************************************/ +#define PLATFORM_CLUSTER_COUNT U(4) +#define PLATFORM_MAX_CPUS_PER_CLUSTER U(2) + /******************************************************************************* * Chip specific page table and MMU setup constants ******************************************************************************/ diff --git a/plat/nvidia/tegra/soc/t194/platform_t194.mk b/plat/nvidia/tegra/soc/t194/platform_t194.mk index 9ee9138b4..c02128ccc 100644 --- a/plat/nvidia/tegra/soc/t194/platform_t194.mk +++ b/plat/nvidia/tegra/soc/t194/platform_t194.mk @@ -24,12 +24,6 @@ COLD_BOOT_SINGLE_CPU := 1 TZDRAM_BASE := 0x40000000 $(eval $(call add_define,TZDRAM_BASE)) -PLATFORM_CLUSTER_COUNT := 4 -$(eval $(call add_define,PLATFORM_CLUSTER_COUNT)) - -PLATFORM_MAX_CPUS_PER_CLUSTER := 2 -$(eval $(call add_define,PLATFORM_MAX_CPUS_PER_CLUSTER)) - MAX_XLAT_TABLES := 25 $(eval $(call add_define,MAX_XLAT_TABLES)) -- cgit v1.2.3 From 2a3dd384599dc3e092a1aa1e2a3757482a158bc3 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Sat, 21 Mar 2020 18:49:33 -0700 Subject: Tegra: fixup GIC init from the 'on_finish' handler Commit e9e19fb2fe684a740afc4820b3ee4cc38ad67d70 accidentally removed the GIC init routine required to initialze the distributor on system resume. This patch fixes this anomaly and initializes the distributor on system resume. Signed-off-by: Varun Wadekar Change-Id: I3fdc694404faa509952f2d90b1f16541165e583e --- plat/nvidia/tegra/common/tegra_pm.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/plat/nvidia/tegra/common/tegra_pm.c b/plat/nvidia/tegra/common/tegra_pm.c index 5ec6f849e..0430048e2 100644 --- a/plat/nvidia/tegra/common/tegra_pm.c +++ b/plat/nvidia/tegra/common/tegra_pm.c @@ -151,17 +151,19 @@ void tegra_pwr_domain_on_finish(const psci_power_state_t *target_state) { const plat_params_from_bl2_t *plat_params; - /* - * Initialize the GIC cpu and distributor interfaces - */ - tegra_gic_pcpu_init(); - /* * Check if we are exiting from deep sleep. */ if (target_state->pwr_domain_state[PLAT_MAX_PWR_LVL] == PSTATE_ID_SOC_POWERDN) { + /* + * On entering System Suspend state, the GIC loses power + * completely. Initialize the GIC global distributor and + * GIC cpu interfaces. + */ + tegra_gic_init(); + /* Restart console output. */ console_switch_state(CONSOLE_FLAG_RUNTIME); @@ -183,6 +185,11 @@ void tegra_pwr_domain_on_finish(const psci_power_state_t *target_state) * access */ tegra_memctrl_tzram_setup(TEGRA_TZRAM_BASE, TEGRA_TZRAM_SIZE); + } else { + /* + * Initialize the GIC cpu and distributor interfaces + */ + tegra_gic_pcpu_init(); } /* -- cgit v1.2.3 From 5fac0d3228923875ec5acfbc676ffe50e7ec2c05 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Tue, 17 Mar 2020 00:07:31 +0000 Subject: allwinner: H6: Fix GPIO and CCU memory map addresses The base address for both the GPIO and the clock unit of the H6 memory map have been typo-ed. Fix them to match the Linux DT and the manual. The H6 code use neither of them, so this doesn't change or fix anything in the real world, but should be corrected anyway. The issue was found and reported by Github user "armlabs". Change-Id: Ic6fdfb732ce1cfc54cbb927718035624a06a9e08 Signed-off-by: Andre Przywara --- plat/allwinner/sun50i_h6/include/sunxi_mmap.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plat/allwinner/sun50i_h6/include/sunxi_mmap.h b/plat/allwinner/sun50i_h6/include/sunxi_mmap.h index 0e204d0f0..702db770f 100644 --- a/plat/allwinner/sun50i_h6/include/sunxi_mmap.h +++ b/plat/allwinner/sun50i_h6/include/sunxi_mmap.h @@ -29,9 +29,9 @@ #define SUNXI_SID_BASE 0x03006000 #define SUNXI_DMA_BASE 0x03002000 #define SUNXI_MSGBOX_BASE 0x03003000 -#define SUNXI_CCU_BASE 0x03010000 +#define SUNXI_CCU_BASE 0x03001000 #define SUNXI_CCU_SEC_SWITCH_REG (SUNXI_CCU_BASE + 0xf00) -#define SUNXI_PIO_BASE 0x030b0000 +#define SUNXI_PIO_BASE 0x0300b000 #define SUNXI_TIMER_BASE 0x03009000 #define SUNXI_WDOG_BASE 0x030090a0 #define SUNXI_THS_BASE 0x05070400 -- cgit v1.2.3 From 79c70ccb4ab1efa7258853968d27724750f137e5 Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Fri, 29 Nov 2019 15:05:14 +0000 Subject: spm: Add spci manifest binding document The manifest binding document defines the expected properties and their formats to represent a partition manifest in device tree. Change-Id: I5eb250c7b89e0d828e1fcfce32b121e4081879ec Signed-off-by: Louis Mayencourt --- docs/components/spci-manifest-binding.rst | 239 ++++++++++++++++++++++++++++++ 1 file changed, 239 insertions(+) create mode 100644 docs/components/spci-manifest-binding.rst diff --git a/docs/components/spci-manifest-binding.rst b/docs/components/spci-manifest-binding.rst new file mode 100644 index 000000000..66cca643b --- /dev/null +++ b/docs/components/spci-manifest-binding.rst @@ -0,0 +1,239 @@ +SPCI manifest binding to device tree +==================================== + +This document defines the nodes and properties used to define a partition, +according to the SPCI specification. + +Version 1.0 +----------- + +spci-manifest-partition +^^^^^^^^^^^^^^^^^^^^^^^ + +- compatible [mandatory] + - value type: + - Must be the string "arm,spci-manifest-X.Y" which specifies the major and + minor versions fo the device tree binding for the SPCI manifest represented + by this node. The minor number is incremented if the binding changes in a + backwards compatible manner. + - X is an integer representing the major version number of this document. + - Y is an integer representing the minor version number of this document. + +- spci-version [mandatory] + - value type: + - Must be two 16 bits values (X, Y), concatenated as 31:16 -> X, + 15:0 -> Y, where: + - X is the major version of PSA-FF-A expected by the partition at the SPCI + instance it will execute. + - Y is the minor version of PSA-FF-A expected by the partition at the SPCI + instance it will execute. + +- uuid [mandatory] + - value type: + - An array consisting of 4 values, identifying the UUID of the service + implemented by this partition. The UUID format is described in RFC 4122. + UUID can be shared by multiple instances of partitions that offer the same + service For example: + - If there are multiple instances of a Trusted OS, then the UUID can be + shared by all instances. + - The TEE driver in the HLOS can use the UUID with the + SPCI_PARTITION_INFO_GET interface to determine the: + - Number of Trusted OSs + - The partition ID of each instance of the Trusted OS + +- id + - value type: + - Pre-allocated partition ID. + +- auxiliary-id + - value type: + - Pre-allocated ID that could be used in memory management transactions. + +- description + - value type: + - Name of the partition e.g. for debugging purposes. + +- execution-ctx-count [mandatory] + - value type: + - Number of vCPUs that a VM or SP wants to instantiate. + - In the absence of virtualization, this is the number of execution + contexts that a partition implements. + - If value of this field = 1 and number of PEs > 1 then the partition is + treated as UP & migrate capable. + - If the value of this field > 1 then the partition is treated as a MP + capable partition irrespective of the number of PEs. + +- exception-level [mandatory] + - value type: + - The target exception level for the partition: + - 0x0: EL1 + - 0x1: S_EL0 + - 0x2: S_EL1 + - 0x3: EL2 + - 0x4: Supervisor mode + - 0x5: Secure User mode + +- execution-state [mandatory] + - value type: + - The target execution state of the partition: + - 0: AArch64 + - 1: AArch32 + +- load-address + - value type: + - Physical base address of the partition in memory. Absence of this field + indicates that the partition is position independent and can be loaded at + any address chosen at boot time. + +- entrypoint-offset + - value type: + - Offset from the base of the partition's binary image to the entry point of + the partition. Absence of this field indicates that the entry point is at + offset 0x0 from the base of the partition's binary. + +- xlat-granule [mandatory] + - value type: + - Translation granule used with the partition: + - 0x0: 4k + - 0x1: 16k + - 0x2: 32k + +- boot-order + - value type: + - A unique number amongst all partitions that specifies if this partition + must be booted before others. The partition with the smaller number will be + booted first. + +- rx-tx-buffer + - value type: "memory-regions" node + - Specific "memory-regions" nodes that describe the RX/TX buffers expected + by the partition. + The "compatible" must be the string "arm,spci-manifest-rx_tx-buffer". + +- messaging-method [mandatory] + - value type: + - Specifies which messaging methods are supported by the partition: + - 0x0: direct messaging method + - 0x1: indirect messaging method + - 0x2: both direct and indirect messaging methods + +- has-primary-scheduler + - value type: + - Presence of this field indicates that the partition implements the primary + scheduler. If so, run-time EL must be EL1. + +- run-time-model + - value type: + - Run time model that the SPM must enforce for this SP: + - 0x0: Run to completion + - 0x1: Preemptible + +- time-slice-mem + - value type: + - Presence of this field indicates that the partition doesn't expect the + partition manager to time slice long running memory management functions. + +- gp-register-num + - value type: + - Presence of this field indicates that the partition expects the + spci_init_info structure to be passed in via the specified general purpose + register. + The field specifies the general purpose register number but not its width. + The width is derived from the partition's execution state, as specified in + the partition properties. For example, if the number value is 1 then the + general-purpose register used will be x1 in AArch64 state and w1 in AArch32 + state. + +- stream-endpoint-ids + - value type: + - List of tuples, identifying the IDs this partition is acting as + proxy for. + +memory-regions +-------------- + +- compatible [mandatory] + - value type: + - Must be the string "arm,spci-manifest-memory-regions". + +- description + - value type: + - Name of the memory region e.g. for debugging purposes. + +- pages-count [mandatory] + - value type: + - Count of pages of memory region as a multiple of the translation granule + size + +- attributes [mandatory] + - value type: + - ?? TO DEFINE + +- base-address + - value type: + - Base address of the region. The address must be aligned to the translation + granule size. + The address given may be a Physical Address (PA), Virtual Address (VA), or + Intermediate Physical Address (IPA). Refer to the SPCI specification for + more information on the restrictions around the address type. + If the base address is omitted then the partition manager must map a memory + region of the specified size into the partition's translation regime and + then communicate the region properties (including the base address chosen + by the partition manager) to the partition. + +device-regions +-------------- + +- compatible [mandatory] + - value type: + - Must be the string "arm,spci-manifest-device-regions". + +- description + - value type: + - Name of the device region e.g. for debugging purposes. + +- reg [mandatory] + - value type: + - A (address, num-pages) pair describing the device, where: + - address: The physical base address value of the device MMIO + region. + - num-pages: The number of pages of the region. The total size of + the region is this value multiplied by the translation granule size. + +- attributes [mandatory] + - value type: + - ?? TO DEFINE + +- smmu-id + - value type: + - On systems with multiple System Memory Management Units (SMMUs) this + identifier is used to inform the partition manager which SMMU the device is + upstream of. If the field is omitted then it is assumed that the device is + not upstream of any SMMU. + +- stream-ids [mandatory] + - value type: + - A list of (id, mem-manage) pair, where: + - id: A unique value amongst all devices assigned to the partition. + - mem-manage: A value used in memory management operations. + +- interrupts [mandatory] + - value type: + - A list of (id, attributes) pair describing the device interrupts, where: + - id: The interrupt IDs. + - attributes: A ?? TO DEFINE value, + containing the attributes for each interrupt ID: + - Interrupt type: SPI, PPI, SGI + - Interrupt configuration: Edge triggered, Level triggered + - Interrupt security state: Secure, Non-secure + - Interrupt priority value + - Target execution context/vCPU for each SPI + +- exclusive-access + - value type: + - Presence of this field implies that this endpoint must be granted exclusive + access and ownership of this devices's MMIO region. + +-------------- + +*Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.* -- cgit v1.2.3 From 30617cca3f084c0b4746f957275a936715defb2f Mon Sep 17 00:00:00 2001 From: Igor Opaniuk Date: Mon, 23 Mar 2020 17:21:05 +0200 Subject: plat: imx: imx8qx: provide debug uart num as build param 1. This removes hardcoded iomux/clk/addr configuration for debug uart, provides possibility (as a workaround, till that information isn't provided via DT) to set this configuration during compile time via IMX_DEBUG_UART build flag. Also for Colibri i.MX8QXP different pinmux configuration is applied for UART3, FLEXCAN2_RX/TX pads are muxed to ADMA_UART3_RX/TX. 2. Having DEBUG_CONSOLE enabled without enabling DEBUG_CONSOLE_A35 doesn't make sense (since UART pinmux/clock configuration is applied for UART only when DEBUG_CONSOLE_A35 is enabled. Check similar commit for i.MX8QM 98a69dfd4a("plat: imx: imx8qm: apply clk/pinmux configuration for DEBUG_CONSOLE")). Usage: $ make PLAT=imx8qx IMX_DEBUG_UART=3 DEBUG_CONSOLE=1 bl31 Signed-off-by: Igor Opaniuk Change-Id: I5d04939b2e8ee1a5f4b2f3c6241977d3c6e91760 --- plat/imx/imx8qx/imx8qx_bl31_setup.c | 45 +++++++++++++++++++++++++++++----- plat/imx/imx8qx/include/platform_def.h | 12 ++++++--- plat/imx/imx8qx/platform.mk | 6 +++++ 3 files changed, 54 insertions(+), 9 deletions(-) diff --git a/plat/imx/imx8qx/imx8qx_bl31_setup.c b/plat/imx/imx8qx/imx8qx_bl31_setup.c index 97d222787..3ff540017 100644 --- a/plat/imx/imx8qx/imx8qx_bl31_setup.c +++ b/plat/imx/imx8qx/imx8qx_bl31_setup.c @@ -38,11 +38,43 @@ IMPORT_SYM(unsigned long, __RW_START__, BL31_RW_START); static entry_point_info_t bl32_image_ep_info; static entry_point_info_t bl33_image_ep_info; +/* Default configuration for i.MX8QM/QXP MEK */ +#if defined(IMX_USE_UART0) #define UART_PAD_CTRL (PADRING_IFMUX_EN_MASK | PADRING_GP_EN_MASK | \ (SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | \ (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \ (SC_PAD_28FDSOI_DSE_DV_LOW << PADRING_DSE_SHIFT) | \ (SC_PAD_28FDSOI_PS_PD << PADRING_PULL_SHIFT)) +#define IMX_RES_UART SC_R_UART_0 +#define IMX_PAD_UART_RX SC_P_UART0_RX +#define IMX_PAD_UART_TX SC_P_UART0_TX + +/* + * On Toradex Colibri i.MX8QXP UART3 on the FLEXCAN2. + * Use custom pad control for this + */ +#elif defined(IMX_USE_UART3) +/* + * FLEXCAN2_RX/TX pads are muxed to ADMA_UART3_RX/TX, + * For ref: + * 000b - ADMA_FLEXCAN2_RX + * 001b - ADMA_SAI3_RXD + * 010b - ADMA_UART3_RX + * 011b - ADMA_SAI1_RXFS + * 100b - LSIO_GPIO1_IO19 + */ +#define UART_PAD_CTRL (PADRING_IFMUX_EN_MASK | PADRING_GP_EN_MASK | \ + (SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | \ + (2U << PADRING_IFMUX_SHIFT) | \ + (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \ + (SC_PAD_28FDSOI_DSE_DV_LOW << PADRING_DSE_SHIFT) | \ + (SC_PAD_28FDSOI_PS_PD << PADRING_PULL_SHIFT)) +#define IMX_RES_UART SC_R_UART_3 +#define IMX_PAD_UART_RX SC_P_FLEXCAN2_RX +#define IMX_PAD_UART_TX SC_P_FLEXCAN2_TX +#else +#error "Provide proper UART configuration in IMX_DEBUG_UART" +#endif static const mmap_region_t imx_mmap[] = { MAP_REGION_FLAT(IMX_REG_BASE, IMX_REG_SIZE, MT_DEVICE | MT_RW), @@ -74,7 +106,7 @@ static void lpuart32_serial_setbrg(unsigned int base, int baudrate) if (baudrate == 0) panic(); - sc_pm_get_clock_rate(ipc_handle, SC_R_UART_0, 2, &rate); + sc_pm_get_clock_rate(ipc_handle, IMX_RES_UART, 2, &rate); baud_diff = baudrate; osr = 0; @@ -261,14 +293,15 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, panic(); #if DEBUG_CONSOLE_A35 - sc_pm_set_resource_power_mode(ipc_handle, SC_R_UART_0, SC_PM_PW_MODE_ON); + sc_pm_set_resource_power_mode(ipc_handle, IMX_RES_UART, + SC_PM_PW_MODE_ON); sc_pm_clock_rate_t rate = 80000000; - sc_pm_set_clock_rate(ipc_handle, SC_R_UART_0, 2, &rate); - sc_pm_clock_enable(ipc_handle, SC_R_UART_0, 2, true, false); + sc_pm_set_clock_rate(ipc_handle, IMX_RES_UART, 2, &rate); + sc_pm_clock_enable(ipc_handle, IMX_RES_UART, 2, true, false); /* Configure UART pads */ - sc_pad_set(ipc_handle, SC_P_UART0_RX, UART_PAD_CTRL); - sc_pad_set(ipc_handle, SC_P_UART0_TX, UART_PAD_CTRL); + sc_pad_set(ipc_handle, IMX_PAD_UART_RX, UART_PAD_CTRL); + sc_pad_set(ipc_handle, IMX_PAD_UART_TX, UART_PAD_CTRL); lpuart32_serial_init(IMX_BOOT_UART_BASE); #endif diff --git a/plat/imx/imx8qx/include/platform_def.h b/plat/imx/imx8qx/include/platform_def.h index 41475ffeb..b880e1bc7 100644 --- a/plat/imx/imx8qx/include/platform_def.h +++ b/plat/imx/imx8qx/include/platform_def.h @@ -38,7 +38,15 @@ #define PLAT_GICD_BASE 0x51a00000 #define PLAT_GICR_BASE 0x51b00000 + +#if defined(IMX_USE_UART0) #define IMX_BOOT_UART_BASE 0x5a060000 +#elif defined(IMX_USE_UART3) +#define IMX_BOOT_UART_BASE 0x5a090000 +#else +#error "Provide proper UART configuration in IMX_DEBUG_UART" +#endif + #define IMX_BOOT_UART_BAUDRATE 115200 #define IMX_BOOT_UART_CLK_IN_HZ 24000000 #define PLAT_CRASH_UART_BASE IMX_BOOT_UART_BASE @@ -55,8 +63,6 @@ /* non-secure u-boot base */ #define PLAT_NS_IMAGE_OFFSET 0x80020000 - -#define DEBUG_CONSOLE 0 -#define DEBUG_CONSOLE_A35 0 +#define DEBUG_CONSOLE_A35 DEBUG_CONSOLE #endif /* PLATFORM_DEF_H */ diff --git a/plat/imx/imx8qx/platform.mk b/plat/imx/imx8qx/platform.mk index 5e8ba063c..a8233303d 100644 --- a/plat/imx/imx8qx/platform.mk +++ b/plat/imx/imx8qx/platform.mk @@ -35,3 +35,9 @@ include plat/imx/common/sci/sci_api.mk USE_COHERENT_MEM := 1 RESET_TO_BL31 := 1 + +IMX_DEBUG_UART ?= 0 +$(eval $(call add_define,IMX_USE_UART${IMX_DEBUG_UART})) + +DEBUG_CONSOLE ?= 0 +$(eval $(call add_define,DEBUG_CONSOLE)) -- cgit v1.2.3 From 9d22d310804a73bc08e1cfcf9bbcfd77f8b5a799 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Wed, 11 Mar 2020 17:09:21 +0100 Subject: spi: stm32_qspi: correct static analysis issues Sparse issue: drivers/st/spi/stm32_qspi.c:445:5: warning: symbol 'stm32_qspi_init' was not declared. Should it be static? Cppcheck issue: [drivers/st/spi/stm32_qspi.c:175] -> [drivers/st/spi/stm32_qspi.c:187]: (style) Variable 'len' is reassigned a value before the old one has been used. [drivers/st/spi/stm32_qspi.c:178]: (style) The scope of the variable 'timeout' can be reduced. Change-Id: I575fb50766355a6717cbd193fc4a80ff1923014c Signed-off-by: Yann Gautier --- drivers/st/spi/stm32_qspi.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/st/spi/stm32_qspi.c b/drivers/st/spi/stm32_qspi.c index 188d2ff80..c5e4ea86e 100644 --- a/drivers/st/spi/stm32_qspi.c +++ b/drivers/st/spi/stm32_qspi.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, STMicroelectronics - All Rights Reserved + * Copyright (c) 2019-2020, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -172,9 +173,8 @@ static void stm32_qspi_write_fifo(uint8_t *val, uintptr_t addr) static int stm32_qspi_poll(const struct spi_mem_op *op) { void (*fifo)(uint8_t *val, uintptr_t addr); - uint32_t len = op->data.nbytes; + uint32_t len; uint8_t *buf; - uint64_t timeout; if (op->data.dir == SPI_MEM_DATA_IN) { fifo = stm32_qspi_read_fifo; @@ -185,7 +185,8 @@ static int stm32_qspi_poll(const struct spi_mem_op *op) buf = (uint8_t *)op->data.buf; for (len = op->data.nbytes; len != 0U; len--) { - timeout = timeout_init_us(QSPI_FIFO_TIMEOUT_US); + uint64_t timeout = timeout_init_us(QSPI_FIFO_TIMEOUT_US); + while ((mmio_read_32(qspi_base() + QSPI_SR) & QSPI_SR_FTF) == 0U) { if (timeout_elapsed(timeout)) { -- cgit v1.2.3 From 498f2936e0b1821df6ca86e32b3b0edf532d3976 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Wed, 11 Mar 2020 17:16:49 +0100 Subject: raw_nand: correct static analysis tool warning Correct the following warning given by sparse tool: include/drivers/raw_nand.h:158:3: warning: symbol '__packed' was not declared. Should it be static? Change-Id: I03bd9a8aee5cdc5212ce5225be8033f1a6e92bd9 Signed-off-by: Yann Gautier --- include/drivers/raw_nand.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/drivers/raw_nand.h b/include/drivers/raw_nand.h index 18e4b73da..9018f0242 100644 --- a/include/drivers/raw_nand.h +++ b/include/drivers/raw_nand.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, STMicroelectronics - All Rights Reserved + * Copyright (c) 2019-2020, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,6 +7,7 @@ #ifndef DRIVERS_RAW_NAND_H #define DRIVERS_RAW_NAND_H +#include #include #include -- cgit v1.2.3 From cd4941def34a58f5a753ef061c3ed631c93e260d Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Wed, 11 Mar 2020 17:17:51 +0100 Subject: plat/st: correct static analysis tool warning Correct the following sparse warnings: plat/st/common/stm32mp_dt.c:103:5: warning: symbol 'fdt_get_node_parent_address_cells' was not declared. Should it be static? plat/st/common/stm32mp_dt.c:123:5: warning: symbol 'fdt_get_node_parent_size_cells' was not declared. Should it be static? As those 2 functions are only used by assert(), put them under ENABLE_ASSERTIONS flag. Change-Id: Iad721f12128df83a3de3f53e7920a9c1dce64c56 Signed-off-by: Yann Gautier --- plat/st/common/stm32mp_dt.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/plat/st/common/stm32mp_dt.c b/plat/st/common/stm32mp_dt.c index 4fa796f0c..a8119aec6 100644 --- a/plat/st/common/stm32mp_dt.c +++ b/plat/st/common/stm32mp_dt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -92,6 +92,7 @@ uint8_t fdt_get_status(int node) return status; } +#if ENABLE_ASSERTIONS /******************************************************************************* * This function returns the address cells from the node parent. * Returns: @@ -100,7 +101,7 @@ uint8_t fdt_get_status(int node) * - a default value if undefined #address-cells property as per libfdt * implementation. ******************************************************************************/ -int fdt_get_node_parent_address_cells(int node) +static int fdt_get_node_parent_address_cells(int node) { int parent; @@ -120,7 +121,7 @@ int fdt_get_node_parent_address_cells(int node) * - a default value if undefined #size-cells property as per libfdt * implementation. ******************************************************************************/ -int fdt_get_node_parent_size_cells(int node) +static int fdt_get_node_parent_size_cells(int node) { int parent; @@ -131,6 +132,7 @@ int fdt_get_node_parent_size_cells(int node) return fdt_size_cells(fdt, parent); } +#endif /******************************************************************************* * This function reads a value of a node property (generic use of fdt -- cgit v1.2.3 From 9fe181c6a6cbbe01f7b385d038e209120fde1e94 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Wed, 18 Mar 2020 14:07:55 +0100 Subject: nand: stm32_fmc2_nand: correct xor_ecc.val assigned value The variable is wrongly set to 0L, whereas it is an unsigned int, it should then be 0U. Change-Id: I0b164c0ea598ec8a503f1693da2f3789f59da238 Signed-off-by: Yann Gautier --- drivers/st/fmc/stm32_fmc2_nand.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/st/fmc/stm32_fmc2_nand.c b/drivers/st/fmc/stm32_fmc2_nand.c index b694fff6b..d2d7e06b7 100644 --- a/drivers/st/fmc/stm32_fmc2_nand.c +++ b/drivers/st/fmc/stm32_fmc2_nand.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, STMicroelectronics - All Rights Reserved + * Copyright (c) 2019-2020, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ @@ -365,7 +365,7 @@ static int stm32_fmc2_ham_correct(uint8_t *buffer, uint8_t *eccbuffer, xor_ecc_2b = ecc[1] ^ eccbuffer[1]; xor_ecc_3b = ecc[2] ^ eccbuffer[2]; - xor_ecc.val = 0L; + xor_ecc.val = 0U; xor_ecc.bytes[2] = xor_ecc_3b; xor_ecc.bytes[1] = xor_ecc_2b; xor_ecc.bytes[0] = xor_ecc_1b; -- cgit v1.2.3 From e9d1e5afbd0d95ffc0f8da0eafe5edbb84c30943 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Wed, 18 Mar 2020 14:35:27 +0100 Subject: plat/st: correctly check pwr-regulators node This warning was issued by cppcheck in our downstream code: [plat/st/common/stm32mp_dt.c:629] -> [plat/st/common/stm32mp_dt.c:634]: (warning) Identical condition 'node<0', second condition is always false The second test has to check variable pwr_regulators_node. Change-Id: I4a20c4a3ac0ef0639c2df36309d90a61c02b511f Signed-off-by: Yann Gautier --- plat/st/common/stm32mp_dt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/st/common/stm32mp_dt.c b/plat/st/common/stm32mp_dt.c index a8119aec6..acb323cf2 100644 --- a/plat/st/common/stm32mp_dt.c +++ b/plat/st/common/stm32mp_dt.c @@ -469,7 +469,7 @@ uint32_t dt_get_pwr_vdd_voltage(void) } pwr_regulators_node = fdt_subnode_offset(fdt, node, "pwr-regulators"); - if (node < 0) { + if (pwr_regulators_node < 0) { INFO("%s: Cannot read pwr-regulators node in DT\n", __func__); return 0; } -- cgit v1.2.3 From 95433894307ab5b9330625a547a3f9ca509368e5 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Wed, 18 Mar 2020 14:50:50 +0100 Subject: io: io_stm32image: correct possible NULL pointer dereference This issue was found with cppcheck in our downstream code: [drivers/st/io/io_stm32image.c:234] -> [drivers/st/io/io_stm32image.c:244]: (warning) Either the condition 'buffer!=0U' is redundant or there is possible null pointer dereference: local_buffer. Change-Id: Ieb615b7e485dc93bbeeed4cd8bf845eb84c14ac9 Signed-off-by: Yann Gautier --- drivers/st/io/io_stm32image.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/st/io/io_stm32image.c b/drivers/st/io/io_stm32image.c index 413521b1e..3e377cd48 100644 --- a/drivers/st/io/io_stm32image.c +++ b/drivers/st/io/io_stm32image.c @@ -247,7 +247,7 @@ static int stm32image_partition_read(io_entity_t *entity, uintptr_t buffer, size_t length, size_t *length_read) { int result; - uint8_t *local_buffer = (uint8_t *)buffer; + uint8_t *local_buffer; boot_api_image_header_t *header = (boot_api_image_header_t *)first_lba_buffer; @@ -255,6 +255,7 @@ static int stm32image_partition_read(io_entity_t *entity, uintptr_t buffer, assert(buffer != 0U); assert(length_read != NULL); + local_buffer = (uint8_t *)buffer; *length_read = 0U; while (*length_read == 0U) { -- cgit v1.2.3 From c33ff1985eb64f0e74db4d519ff71617dd7d5381 Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Thu, 19 Mar 2020 09:27:11 +0100 Subject: spmd: skip loading of secure partitions on pre-v8.4 platforms When SPD=spmd and SPMD_SPM_AT_SEL2=0, that is SPMC sits at S-EL1 then there is no need for TF-A to load secure partitions individually. In this configuration, SPMC handles secure partition loading at S-EL1/EL0 levels. Signed-off-by: Olivier Deprez Signed-off-by: Manish Pandey Change-Id: I06a0d88a4811274a8c347ce57b56bb5f64e345df --- Makefile | 9 +++++++-- plat/arm/common/arm_bl2_setup.c | 2 +- plat/arm/common/arm_common.mk | 4 +++- plat/arm/common/arm_image_load.c | 6 +++--- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 47a544dcf..289fc00b5 100644 --- a/Makefile +++ b/Makefile @@ -938,13 +938,18 @@ $(eval $(call add_define,USE_ARM_LINK)) endif # Generate and include sp_gen.mk if SPD is spmd and SP_LAYOUT_FILE is defined -ifdef SP_LAYOUT_FILE 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 NEED_SP_PKG := yes else - $(error "SP_LAYOUT_FILE will be used only if SPD=spmd") + ifeq (${SPMD_SPM_AT_SEL2},1) + $(error "SPMD with SPM at S-EL2 require SP_LAYOUT_FILE") + endif endif endif diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c index d9fc84e8c..6c3f64fb6 100644 --- a/plat/arm/common/arm_bl2_setup.c +++ b/plat/arm/common/arm_bl2_setup.c @@ -205,7 +205,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) +#if defined(SPD_spmd) && SPMD_SPM_AT_SEL2 /* 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 65f6bf3c3..deecb3a0f 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -183,7 +183,9 @@ else ARM_IO_SOURCES += plat/arm/common/arm_fconf_io_storage.c \ plat/arm/common/fconf/arm_fconf_io.c ifeq (${SPD},spmd) -ARM_IO_SOURCES += plat/arm/common/fconf/arm_fconf_sp.c + ifeq (${SPMD_SPM_AT_SEL2},1) + ARM_IO_SOURCES += plat/arm/common/fconf/arm_fconf_sp.c + endif endif endif diff --git a/plat/arm/common/arm_image_load.c b/plat/arm/common/arm_image_load.c index 593199d46..ed7f1f5a5 100644 --- a/plat/arm/common/arm_image_load.c +++ b/plat/arm/common/arm_image_load.c @@ -32,11 +32,11 @@ void plat_flush_next_bl_params(void) next_bl_params_cpy_ptr); } -#if defined(SPD_spmd) +#if defined(SPD_spmd) && SPMD_SPM_AT_SEL2 /******************************************************************************* * This function appends Secure Partitions to list of loadable images. ******************************************************************************/ -void plat_add_sp_images_load_info(struct bl_load_info *load_info) +static void plat_add_sp_images_load_info(struct bl_load_info *load_info) { bl_load_info_node_t *node_info = load_info->head; unsigned int index = 0; @@ -78,7 +78,7 @@ 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) +#if defined(SPD_spmd) && SPMD_SPM_AT_SEL2 bl_load_info_t *bl_load_info; bl_load_info = get_bl_load_info_from_mem_params_desc(); -- cgit v1.2.3 From 3d1cac96c02c20edf1edbe66aa41bf6be3bf196e Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Sun, 22 Mar 2020 15:58:02 -0700 Subject: Tegra194: se: increase max. operation timeout to 1 second This patch increases the maximum timeout value for SE operation completion to 1 second. This takes care of some corner cases where an operation might take more time than the previous timeout value of 100ms. Signed-off-by: Varun Wadekar Change-Id: I0012448ba372a8bb0e156df7dfe49d7de6d21a68 --- plat/nvidia/tegra/soc/t194/drivers/se/se.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/plat/nvidia/tegra/soc/t194/drivers/se/se.c b/plat/nvidia/tegra/soc/t194/drivers/se/se.c index ccdc94d13..31b0e2678 100644 --- a/plat/nvidia/tegra/soc/t194/drivers/se/se.c +++ b/plat/nvidia/tegra/soc/t194/drivers/se/se.c @@ -23,12 +23,11 @@ /******************************************************************************* * Constants and Macros ******************************************************************************/ -#define ERR_STATUS_SW_CLEAR U(0xFFFFFFFF) -#define INT_STATUS_SW_CLEAR U(0xFFFFFFFF) -#define MAX_TIMEOUT_MS U(100) /* Timeout in 100ms */ -#define NUM_SE_REGS_TO_SAVE U(4) +#define ERR_STATUS_SW_CLEAR U(0xFFFFFFFF) +#define INT_STATUS_SW_CLEAR U(0xFFFFFFFF) +#define MAX_TIMEOUT_MS U(1000) /* Max. timeout of 1s */ +#define NUM_SE_REGS_TO_SAVE U(4) -#define SE0_MAX_BUSY_TIMEOUT_MS U(100) /* 100ms Timeout Expired */ #define BYTES_IN_WORD U(4) #define SHA256_MAX_HASH_RESULT U(7) #define SHA256_DST_SIZE U(32) -- cgit v1.2.3 From e515c1ddad99941bec3e562c072924f4c38885f4 Mon Sep 17 00:00:00 2001 From: Abdellatif El Khlifi Date: Tue, 24 Mar 2020 11:04:17 +0000 Subject: corstone700: updating the kernel arguments to support initramfs In the context of enabling initramfs this change makes the kernel arguments compatible with the initramfs requirements Change-Id: Ifa955a5790ae1398fd8ad9ca1c8272f019c121a6 Signed-off-by: Abdellatif El Khlifi --- fdts/corstone700.dts | 2 -- 1 file changed, 2 deletions(-) diff --git a/fdts/corstone700.dts b/fdts/corstone700.dts index c13d3b23e..851f5e625 100644 --- a/fdts/corstone700.dts +++ b/fdts/corstone700.dts @@ -15,8 +15,6 @@ chosen { bootargs = "console=ttyAMA0 \ - root=mtd:physmap-flash.0 \ - ro \ loglevel=9"; }; -- cgit v1.2.3 From 4c4a1327ae5efc360a98f6be6839ac3652d63fb2 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Sun, 22 Mar 2020 04:23:24 +0000 Subject: Fix 'tautological-constant-compare' error Fixed below 'tautological-constant-compare' error when building the source code with latest clang compiler . plat/common/plat_psci_common.c:36:2: error: converting the result of '<<' to a boolean always evaluates to true [-Werror,-Wtautological-constant-compare] PMF_STORE_ENABLE) ^ include/lib/pmf/pmf.h:28:29: note: expanded from macro 'PMF_STORE_ENABLE' PMF_STORE_ENABLE (1 << 0) This error is observed beacuse of CASSERT placed in "PMF_DEFINE_CAPTURE_TIMESTAMP" which do below stuff: CASSERT(_flags, select_proper_config); where _flags = PMF_STORE_ENABLE (1 << 0) which always results true. Signed-off-by: Manish V Badarkhe Change-Id: Ifa82ea202496a23fdf1d27ea1798d1f1b583a021 --- include/lib/pmf/pmf_helpers.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/lib/pmf/pmf_helpers.h b/include/lib/pmf/pmf_helpers.h index db38e556a..cfb27f7dc 100644 --- a/include/lib/pmf/pmf_helpers.h +++ b/include/lib/pmf/pmf_helpers.h @@ -173,7 +173,7 @@ typedef struct pmf_svc_desc { unsigned int tid, \ unsigned long long ts) \ { \ - CASSERT(_flags, select_proper_config); \ + CASSERT(_flags != 0, select_proper_config); \ PMF_VALIDATE_TID(_name, tid); \ uintptr_t base_addr = (uintptr_t) pmf_ts_mem_ ## _name; \ if (((_flags) & PMF_STORE_ENABLE) != 0) \ @@ -185,7 +185,7 @@ typedef struct pmf_svc_desc { unsigned int tid, \ unsigned long long ts) \ { \ - CASSERT(_flags, select_proper_config); \ + CASSERT(_flags != 0, select_proper_config); \ PMF_VALIDATE_TID(_name, tid); \ uintptr_t base_addr = (uintptr_t) pmf_ts_mem_ ## _name; \ if (((_flags) & PMF_STORE_ENABLE) != 0) \ -- cgit v1.2.3 From 0ab496458b4cf55fa4116007506d8f38884bd31f Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Fri, 20 Mar 2020 18:38:55 +0000 Subject: FVP: Add BL2 hash calculation in BL1 This patch provides support for measured boot by adding calculation of BL2 image hash in BL1 and writing these data in TB_FW_CONFIG DTB. Change-Id: Ic074a7ed19b14956719c271c805b35d147b7cec1 Signed-off-by: Alexei Fedorov --- Makefile | 4 ++ drivers/auth/mbedtls/mbedtls_common.mk | 18 +++++++- include/plat/arm/common/arm_dyn_cfg_helpers.h | 4 ++ include/plat/arm/common/plat_arm.h | 5 +++ plat/arm/board/fvp/fdts/fvp_fw_config.dts | 13 ++++++ plat/arm/board/fvp/fvp_bl1_setup.c | 54 +++++++++++++++++++++++- plat/arm/common/arm_dyn_cfg.c | 59 ++++++++++++++++++++++++++- plat/arm/common/arm_dyn_cfg_helpers.c | 38 +++++++++++++++-- 8 files changed, 187 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index 8049a189d..a1702beaa 100644 --- a/Makefile +++ b/Makefile @@ -367,6 +367,10 @@ DTC_FLAGS += -I dts -O dtb DTC_CPPFLAGS += -P -nostdinc -Iinclude -Ifdts -undef \ -x assembler-with-cpp $(DEFINES) +ifeq ($(MEASURED_BOOT),1) +DTC_CPPFLAGS += -DMEASURED_BOOT -DBL2_HASH_SIZE=${TCG_DIGEST_SIZE} +endif + ################################################################################ # Common sources and include directories ################################################################################ diff --git a/drivers/auth/mbedtls/mbedtls_common.mk b/drivers/auth/mbedtls/mbedtls_common.mk index 044b368bc..564a4c932 100644 --- a/drivers/auth/mbedtls/mbedtls_common.mk +++ b/drivers/auth/mbedtls/mbedtls_common.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -75,10 +75,19 @@ endif ifeq (${HASH_ALG}, sha384) TF_MBEDTLS_HASH_ALG_ID := TF_MBEDTLS_SHA384 + MBEDTLS_MD_ID := MBEDTLS_MD_SHA384 + TPM_ALG_ID := TPM_ALG_SHA384 + TCG_DIGEST_SIZE := 48 else ifeq (${HASH_ALG}, sha512) - TF_MBEDTLS_HASH_ALG_ID := TF_MBEDTLS_SHA512 + TF_MBEDTLS_HASH_ALG_ID := TF_MBEDTLS_SHA512 + MBEDTLS_MD_ID := MBEDTLS_MD_SHA512 + TPM_ALG_ID := TPM_ALG_SHA512 + TCG_DIGEST_SIZE := 64 else TF_MBEDTLS_HASH_ALG_ID := TF_MBEDTLS_SHA256 + MBEDTLS_MD_ID := MBEDTLS_MD_SHA256 + TPM_ALG_ID := TPM_ALG_SHA256 + TCG_DIGEST_SIZE := 32 endif ifeq (${TF_MBEDTLS_KEY_ALG},ecdsa) @@ -103,6 +112,11 @@ $(eval $(call add_define,TF_MBEDTLS_KEY_SIZE)) $(eval $(call add_define,TF_MBEDTLS_HASH_ALG_ID)) $(eval $(call add_define,TF_MBEDTLS_USE_AES_GCM)) +# Set definitions for measured boot driver +$(eval $(call add_define,MBEDTLS_MD_ID)) +$(eval $(call add_define,TPM_ALG_ID)) +$(eval $(call add_define,TCG_DIGEST_SIZE)) + $(eval $(call MAKE_LIB,mbedtls)) endif diff --git a/include/plat/arm/common/arm_dyn_cfg_helpers.h b/include/plat/arm/common/arm_dyn_cfg_helpers.h index 2dc94abe3..34bf07c0d 100644 --- a/include/plat/arm/common/arm_dyn_cfg_helpers.h +++ b/include/plat/arm/common/arm_dyn_cfg_helpers.h @@ -14,4 +14,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 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 a84047aac..83d4c20ec 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -238,6 +238,11 @@ void arm_bl2_dyn_cfg_init(void); 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(image_desc_t *image_desc); +#endif + /* * Free the memory storing initialization code only used during an images boot * time so it can be reclaimed for runtime data diff --git a/plat/arm/board/fvp/fdts/fvp_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_fw_config.dts index 704bf29cd..98ea85760 100644 --- a/plat/arm/board/fvp/fdts/fvp_fw_config.dts +++ b/plat/arm/board/fvp/fdts/fvp_fw_config.dts @@ -67,6 +67,19 @@ */ 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 8f6170daa..d13cc81f3 100644 --- a/plat/arm/board/fvp/fvp_bl1_setup.c +++ b/plat/arm/board/fvp/fvp_bl1_setup.c @@ -1,9 +1,12 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ +#include + +#include #include #include #include @@ -64,3 +67,52 @@ __dead2 void bl1_plat_fwu_done(void *client_cookie, void *reserved) while (1) wfi(); } + +#if MEASURED_BOOT +/* + * 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 */ + arm_bl1_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 */ diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c index df7530733..ffa2a64d8 100644 --- a/plat/arm/common/arm_dyn_cfg.c +++ b/plat/arm/common/arm_dyn_cfg.c @@ -15,6 +15,10 @@ #include #if TRUSTED_BOARD_BOOT #include +#if MEASURED_BOOT +#include +#include +#endif #endif #include #include @@ -87,7 +91,7 @@ void arm_bl1_set_mbedtls_heap(void) * the default heap's address and size. */ - /* fconf FW_CONFIG and TB_FW_CONFIG are currently the same DTB*/ + /* fconf FW_CONFIG and TB_FW_CONFIG are currently the same DTB */ tb_fw_cfg_dtb = FCONF_GET_PROPERTY(fconf, dtb, base_addr); if ((tb_fw_cfg_dtb != 0UL) && (mbedtls_heap_addr != NULL)) { @@ -100,15 +104,68 @@ void arm_bl1_set_mbedtls_heap(void) ERROR("BL1: unable to write shared Mbed TLS heap information to DTB\n"); panic(); } +#if !MEASURED_BOOT /* * 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. + * + * 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. */ flush_dcache_range(tb_fw_cfg_dtb, fdt_totalsize(dtb)); +#endif /* !MEASURED_BOOT */ } } +#if MEASURED_BOOT +/* + * Puts the BL2 hash data to TB_FW_CONFIG DTB. + * Executed only from BL1. + */ +void arm_bl1_set_bl2_hash(image_desc_t *image_desc) +{ + unsigned char hash_data[MBEDTLS_MD_MAX_SIZE]; + image_info_t image_info = image_desc->image_info; + uintptr_t tb_fw_cfg_dtb; + int err; + + /* fconf FW_CONFIG and TB_FW_CONFIG are currently the same DTB */ + tb_fw_cfg_dtb = FCONF_GET_PROPERTY(fconf, dtb, base_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("BL1: unable to calculate BL2 hash\n"); + panic(); + } + + err = arm_set_bl2_hash_info((void *)tb_fw_cfg_dtb, hash_data); + if (err < 0) { + ERROR("BL1: unable to write BL2 hash data 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)); +} +#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 909c4a671..f110e3bb6 100644 --- a/plat/arm/common/arm_dyn_cfg_helpers.c +++ b/plat/arm/common/arm_dyn_cfg_helpers.c @@ -15,6 +15,12 @@ #define DTB_PROP_MBEDTLS_HEAP_ADDR "mbedtls_heap_addr" #define DTB_PROP_MBEDTLS_HEAP_SIZE "mbedtls_heap_size" +#if MEASURED_BOOT +#define DTB_PROP_BL2_HASH_DATA "bl2_hash_data" + +static int dtb_root = -1; +#endif /* MEASURED_BOOT */ + /******************************************************************************* * Validate the tb_fw_config is a valid DTB file and returns the node offset * to "arm,tb_fw" property. @@ -57,17 +63,18 @@ int arm_dyn_tb_fw_cfg_init(void *dtb, int *node) * * Returns: * 0 = success - * 1 = error + * -1 = error */ int arm_set_dtb_mbedtls_heap_info(void *dtb, void *heap_addr, size_t heap_size) { - int err, dtb_root; - +#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. */ - err = arm_dyn_tb_fw_cfg_init(dtb, &dtb_root); + int err = arm_dyn_tb_fw_cfg_init(dtb, &dtb_root); if (err < 0) { ERROR("Invalid TB_FW_CONFIG loaded. Unable to get root node\n"); return -1; @@ -98,3 +105,26 @@ int arm_set_dtb_mbedtls_heap_info(void *dtb, void *heap_addr, size_t heap_size) return 0; } + +#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); +} +#endif /* MEASURED_BOOT */ -- cgit v1.2.3 From 78707ef85d79832467fdcde65a9e71b890fbd224 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Wed, 25 Mar 2020 16:19:39 -0700 Subject: Tegra186: increase memory mapped regions This patch increases MAX_MMAP_REGIONS to 30 to accommodate the additional dynamic memory mapped region, during Trusty boot. Signed-off-by: Varun Wadekar Change-Id: I461186a3aff5040f14715b87502fc5f1db3bea6e --- plat/nvidia/tegra/soc/t186/platform_t186.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/nvidia/tegra/soc/t186/platform_t186.mk b/plat/nvidia/tegra/soc/t186/platform_t186.mk index a5341236d..d320aac2f 100644 --- a/plat/nvidia/tegra/soc/t186/platform_t186.mk +++ b/plat/nvidia/tegra/soc/t186/platform_t186.mk @@ -33,7 +33,7 @@ $(eval $(call add_define,PLATFORM_MAX_CPUS_PER_CLUSTER)) MAX_XLAT_TABLES := 25 $(eval $(call add_define,MAX_XLAT_TABLES)) -MAX_MMAP_REGIONS := 27 +MAX_MMAP_REGIONS := 30 $(eval $(call add_define,MAX_MMAP_REGIONS)) # platform files -- cgit v1.2.3 From 22193a3ed8a47a9ac509c415f434daab712600bf Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Thu, 26 Mar 2020 10:10:52 +0100 Subject: changelog: add debugfs functionality Signed-off-by: Olivier Deprez Change-Id: Icf8160536c249c754b3dfac6f8f49ca7ad3bb0de --- docs/change-log-upcoming.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/change-log-upcoming.rst b/docs/change-log-upcoming.rst index f86280f76..14d21f0cc 100644 --- a/docs/change-log-upcoming.rst +++ b/docs/change-log-upcoming.rst @@ -36,6 +36,7 @@ New Features - Libraries - Example: "Introduce BTI support in Library at ROM (romlib)" - Add Firmware Configuration Framework (fconf). + - Add DebugFS functionality - New Platforms Support - Example: "qemu/qemu_sbsa: New platform support added for QEMU SBSA platform" -- cgit v1.2.3 From 62c170700bc200f2d41c4801f9b31e356261c1ef Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Thu, 26 Mar 2020 11:16:46 +0100 Subject: changelog: introduce SPMD, add secure partition loading and tooling Signed-off-by: Olivier Deprez Change-Id: I250c3aa199d4e5efa68aa32bf5a1694835be56b7 --- docs/change-log-upcoming.rst | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docs/change-log-upcoming.rst b/docs/change-log-upcoming.rst index 14d21f0cc..72dfb50e8 100644 --- a/docs/change-log-upcoming.rst +++ b/docs/change-log-upcoming.rst @@ -20,12 +20,23 @@ 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). - Example: "Add support for Branch Target Identification (BTI)" +- BL-specific + - Enhanced BL2 bootloader flow to load secure partitions based on firmware + configuration data (fconf). + - 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). - CPU Support - Example: "cortex-a55: Workaround for erratum 1221012" @@ -53,6 +64,9 @@ New Features - Add support for optional firmware encryption feature (experimental). - Introduce a new `dualroot` chain of trust. +- SPCI + - Introduced the SPM Dispatcher (SPMD) component as a new standard service. + - Tools - Example: "fiptool: Add support to build fiptool on Windows." @@ -85,6 +99,7 @@ Changed - Example: "Refactor SPSR initialisation code" - Tools + - sptool updated to accomodate building secure partition packages. - Example: "cert_create: Remove RSA PKCS#1 v1.5 support" -- cgit v1.2.3 From 2b06610c9beaa3396721fd7a813450a9537c87c0 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Thu, 26 Mar 2020 14:20:27 +0000 Subject: Fix warnings in porting-guide.rst Fix below warnings appeared in porting-guide.rst WARNING: Title underline too short. Change-Id: Ibc0eba0da72a53a5f9b61c49a8bf7a10b17bc3b8 Signed-off-by: Manish V Badarkhe --- docs/getting_started/porting-guide.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst index d6572f507..2d17f122a 100644 --- a/docs/getting_started/porting-guide.rst +++ b/docs/getting_started/porting-guide.rst @@ -1117,7 +1117,7 @@ the log output. The implementation should be robust to future changes that increase the number of log levels. Function : plat_get_soc_version() -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :: @@ -1132,7 +1132,7 @@ This function returns soc version which mainly consist of below fields soc_version[23:16] = JEP-106 identification code with parity bit for the SiP Function : plat_get_soc_revision() -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :: -- cgit v1.2.3 From e6cc3ccfc2efa1c9732da34c74f8d2bcc5e25a5a Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Wed, 26 Feb 2020 13:39:44 +0100 Subject: stm32mp1: add a function to get non-secure DDR size This function gets the DDR size from DT, and withdraws (if defined) the sizes of secure DDR and shared memory areas. This function also checks DT values fits the default DDR range. This non-secure memory is available for BL33 and non-secure OS. Change-Id: I162ae5e990a0f9b6b7d07e539de029f1d61a391b Signed-off-by: Yann Gautier --- plat/st/stm32mp1/include/stm32mp1_private.h | 3 ++- plat/st/stm32mp1/stm32mp1_def.h | 5 ++++- plat/st/stm32mp1/stm32mp1_private.c | 23 ++++++++++++++++++++++- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/plat/st/stm32mp1/include/stm32mp1_private.h b/plat/st/stm32mp1/include/stm32mp1_private.h index e38fca012..2da64acbc 100644 --- a/plat/st/stm32mp1/include/stm32mp1_private.h +++ b/plat/st/stm32mp1/include/stm32mp1_private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -21,4 +21,5 @@ void stm32mp1_syscfg_init(void); void stm32mp1_syscfg_enable_io_compensation(void); void stm32mp1_syscfg_disable_io_compensation(void); +uint32_t stm32mp_get_ddr_ns_size(void); #endif /* STM32MP1_PRIVATE_H */ diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h index 5dc520625..fc776ae8b 100644 --- a/plat/st/stm32mp1/stm32mp1_def.h +++ b/plat/st/stm32mp1/stm32mp1_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -62,6 +62,9 @@ #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 */ diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c index e2dcd2af7..ac4519575 100644 --- a/plat/st/stm32mp1/stm32mp1_private.c +++ b/plat/st/stm32mp1/stm32mp1_private.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -365,3 +365,24 @@ uint32_t stm32_iwdg_shadow_update(uint32_t iwdg_inst, uint32_t flags) return BSEC_OK; } #endif + +/* Get the non-secure DDR size */ +uint32_t stm32mp_get_ddr_ns_size(void) +{ + static uint32_t ddr_ns_size; + uint32_t ddr_size; + + if (ddr_ns_size != 0U) { + return ddr_ns_size; + } + + ddr_size = dt_get_ddr_size(); + if ((ddr_size <= (STM32MP_DDR_S_SIZE + STM32MP_DDR_SHMEM_SIZE)) || + (ddr_size > STM32MP_DDR_MAX_SIZE)) { + panic(); + } + + ddr_ns_size = ddr_size - (STM32MP_DDR_S_SIZE + STM32MP_DDR_SHMEM_SIZE); + + return ddr_ns_size; +} -- cgit v1.2.3 From 84686ba3475d1b6d2aa6c506a378d79cb5b38014 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Fri, 10 Jan 2020 18:18:59 +0100 Subject: stm32mp1: dynamically map DDR later and non-cacheable during its test A speculative accesses to DDR could be done whereas it was not reachable and could lead to bus stall. To correct this the dynamic mapping in MMU is used. A first mapping is done for DDR tests with MT_NON_CACHEABLE attribute, once DDR access is setup. It is then unmapped and a new mapping DDR is done with cacheable attribute (through MT_MEMORY) to speed-up BL33 (or OP-TEE) load. The disabling of cache during DDR tests is also removed, as now useless. A call to new functions stm32mp_{,un}map_ddr_non_cacheable() is done instead. PLAT_XLAT_TABLES_DYNAMIC is activated globally as used in BL2 and BL32. BL33 max size is also updated to take into account the secure and shared memory areas. Those are used in OP-TEE case. Change-Id: I22c48b4a48255ee264991c34ecbb15bfe87e67c3 Signed-off-by: Yann Gautier --- drivers/st/ddr/stm32mp1_ram.c | 11 +++++++---- plat/st/common/include/stm32mp_common.h | 6 +++++- plat/st/common/stm32mp_common.c | 16 +++++++++++++++- plat/st/stm32mp1/bl2_plat_setup.c | 34 +++++++++++++++++---------------- plat/st/stm32mp1/plat_image_load.c | 11 ++++++++++- plat/st/stm32mp1/platform.mk | 7 +++++-- 6 files changed, 60 insertions(+), 25 deletions(-) diff --git a/drivers/st/ddr/stm32mp1_ram.c b/drivers/st/ddr/stm32mp1_ram.c index 4ae55fcc7..40cd4554f 100644 --- a/drivers/st/ddr/stm32mp1_ram.c +++ b/drivers/st/ddr/stm32mp1_ram.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2019, STMicroelectronics - All Rights Reserved + * Copyright (C) 2018-2020, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ @@ -250,8 +250,9 @@ static int stm32mp1_ddr_setup(void) VERBOSE("%s : ram size(%x, %x)\n", __func__, (uint32_t)priv->info.base, (uint32_t)priv->info.size); - write_sctlr(read_sctlr() & ~SCTLR_C_BIT); - dcsw_op_all(DC_OP_CISW); + if (stm32mp_map_ddr_non_cacheable() != 0) { + panic(); + } uret = ddr_test_data_bus(); if (uret != 0U) { @@ -274,7 +275,9 @@ static int stm32mp1_ddr_setup(void) panic(); } - write_sctlr(read_sctlr() | SCTLR_C_BIT); + if (stm32mp_unmap_ddr() != 0) { + panic(); + } return 0; } diff --git a/plat/st/common/include/stm32mp_common.h b/plat/st/common/include/stm32mp_common.h index 4f8567979..27ddab0c8 100644 --- a/plat/st/common/include/stm32mp_common.h +++ b/plat/st/common/include/stm32mp_common.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2019, STMicroelectronics - All Rights Reserved + * Copyright (C) 2018-2020, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ @@ -87,4 +87,8 @@ void stm32mp_io_setup(void); */ int stm32mp_check_header(boot_api_image_header_t *header, uintptr_t buffer); +/* Functions to map DDR in MMU with non-cacheable attribute, and unmap it */ +int stm32mp_map_ddr_non_cacheable(void); +int stm32mp_unmap_ddr(void); + #endif /* STM32MP_COMMON_H */ diff --git a/plat/st/common/stm32mp_common.c b/plat/st/common/stm32mp_common.c index afa87f487..9af156457 100644 --- a/plat/st/common/stm32mp_common.c +++ b/plat/st/common/stm32mp_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -12,6 +12,7 @@ #include #include #include +#include #include uintptr_t plat_get_ns_image_entrypoint(void) @@ -151,3 +152,16 @@ int stm32mp_check_header(boot_api_image_header_t *header, uintptr_t buffer) return 0; } + +int stm32mp_map_ddr_non_cacheable(void) +{ + return mmap_add_dynamic_region(STM32MP_DDR_BASE, STM32MP_DDR_BASE, + STM32MP_DDR_MAX_SIZE, + MT_NON_CACHEABLE | MT_RW | MT_NS); +} + +int stm32mp_unmap_ddr(void) +{ + return mmap_remove_dynamic_region(STM32MP_DDR_BASE, + STM32MP_DDR_MAX_SIZE); +} diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c index 024dbe076..4a77cd94b 100644 --- a/plat/st/stm32mp1/bl2_plat_setup.c +++ b/plat/st/stm32mp1/bl2_plat_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -130,6 +130,7 @@ void bl2_el3_early_platform_setup(u_register_t arg0, void bl2_platform_setup(void) { int ret; + uint32_t ddr_ns_size; if (dt_pmic_status() > 0) { initialize_pmic(); @@ -141,8 +142,24 @@ void bl2_platform_setup(void) panic(); } + ddr_ns_size = stm32mp_get_ddr_ns_size(); + assert(ddr_ns_size > 0U); + + /* Map non secure DDR for BL33 load, now with cacheable attribute */ + ret = mmap_add_dynamic_region(STM32MP_DDR_BASE, STM32MP_DDR_BASE, + ddr_ns_size, MT_MEMORY | MT_RW | MT_NS); + assert(ret == 0); + #ifdef AARCH32_SP_OPTEE INFO("BL2 runs OP-TEE setup\n"); + + /* Map secure DDR for OP-TEE paged area */ + ret = mmap_add_dynamic_region(STM32MP_DDR_BASE + ddr_ns_size, + STM32MP_DDR_BASE + ddr_ns_size, + STM32MP_DDR_S_SIZE, + MT_MEMORY | MT_RW | MT_SECURE); + assert(ret == 0); + /* Initialize tzc400 after DDR initialization */ stm32mp1_security_setup(); #else @@ -166,14 +183,6 @@ void bl2_el3_plat_arch_setup(void) MT_CODE | MT_SECURE); #ifdef AARCH32_SP_OPTEE - /* OP-TEE image needs post load processing: keep RAM read/write */ - mmap_add_region(STM32MP_DDR_BASE + dt_get_ddr_size() - - STM32MP_DDR_S_SIZE - STM32MP_DDR_SHMEM_SIZE, - STM32MP_DDR_BASE + dt_get_ddr_size() - - STM32MP_DDR_S_SIZE - STM32MP_DDR_SHMEM_SIZE, - STM32MP_DDR_S_SIZE, - MT_MEMORY | MT_RW | MT_SECURE); - mmap_add_region(STM32MP_OPTEE_BASE, STM32MP_OPTEE_BASE, STM32MP_OPTEE_SIZE, MT_MEMORY | MT_RW | MT_SECURE); @@ -182,14 +191,7 @@ void bl2_el3_plat_arch_setup(void) mmap_add_region(BL32_BASE, BL32_BASE, BL32_LIMIT - BL32_BASE, MT_MEMORY | MT_RO | MT_SECURE); - #endif - /* Map non secure DDR for BL33 load and DDR training area restore */ - mmap_add_region(STM32MP_DDR_BASE, - STM32MP_DDR_BASE, - STM32MP_DDR_MAX_SIZE, - MT_MEMORY | MT_RW | MT_NS); - /* Prevent corruption of preloaded Device Tree */ mmap_add_region(DTB_BASE, DTB_BASE, DTB_LIMIT - DTB_BASE, diff --git a/plat/st/stm32mp1/plat_image_load.c b/plat/st/stm32mp1/plat_image_load.c index a52db6cac..6d7af741a 100644 --- a/plat/st/stm32mp1/plat_image_load.c +++ b/plat/st/stm32mp1/plat_image_load.c @@ -1,9 +1,11 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ +#include + #include #include @@ -21,6 +23,13 @@ void plat_flush_next_bl_params(void) ******************************************************************************/ bl_load_info_t *plat_get_bl_image_load_info(void) { + 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; + return get_bl_load_info_from_mem_params_desc(); } diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk index bd1a16bf7..5ce7a9c4f 100644 --- a/plat/st/stm32mp1/platform.mk +++ b/plat/st/stm32mp1/platform.mk @@ -11,6 +11,11 @@ USE_COHERENT_MEM := 0 STM32_TF_VERSION ?= 0 +# Enable dynamic memory mapping +PLAT_XLAT_TABLES_DYNAMIC := 1 +$(eval $(call assert_boolean,PLAT_XLAT_TABLES_DYNAMIC)) +$(eval $(call add_define,PLAT_XLAT_TABLES_DYNAMIC)) + # Not needed for Cortex-A7 WORKAROUND_CVE_2017_5715:= 0 @@ -152,8 +157,6 @@ STM32_TF_ELF_LDFLAGS := --hash-style=gnu --as-needed STM32_TF_STM32 := $(addprefix ${BUILD_PLAT}/tf-a-, $(patsubst %.dtb,%.stm32,$(DTB_FILE_NAME))) STM32_TF_LINKERFILE := ${BUILD_PLAT}/stm32mp1.ld -BL2_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 - # Variables for use with stm32image STM32IMAGEPATH ?= tools/stm32image STM32IMAGE ?= ${STM32IMAGEPATH}/stm32image${BIN_EXT} -- cgit v1.2.3 From 9c52e69fb4916166ee67f671268c138d6005b9a3 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Tue, 17 Dec 2019 17:11:10 +0100 Subject: stm32mp1: set XN attribute for some areas in BL2 DTB and BL32 area should not be set as executable in MMU during BL2 execution, hence set those areas as MT_RO_DATA. Change-Id: I87c47a1e7fda761e541ec98a5b294588384d31db Signed-off-by: Yann Gautier --- plat/st/stm32mp1/bl2_plat_setup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c index 4a77cd94b..bb9582c7e 100644 --- a/plat/st/stm32mp1/bl2_plat_setup.c +++ b/plat/st/stm32mp1/bl2_plat_setup.c @@ -190,12 +190,12 @@ void bl2_el3_plat_arch_setup(void) /* Prevent corruption of preloaded BL32 */ mmap_add_region(BL32_BASE, BL32_BASE, BL32_LIMIT - BL32_BASE, - MT_MEMORY | MT_RO | MT_SECURE); + MT_RO_DATA | MT_SECURE); #endif /* Prevent corruption of preloaded Device Tree */ mmap_add_region(DTB_BASE, DTB_BASE, DTB_LIMIT - DTB_BASE, - MT_MEMORY | MT_RO | MT_SECURE); + MT_RO_DATA | MT_SECURE); configure_mmu(); -- cgit v1.2.3 From 5813e6edbc81c9cb0959007cbd86e30c7c87c46c Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Wed, 26 Feb 2020 13:36:07 +0100 Subject: stm32mp1: use stm32mp_get_ddr_ns_size() function Instead of using dt_get_ddr_size() and withdrawing the secure and shared memory areas, use stm32mp_get_ddr_ns_size() function. Change-Id: I5608fd7873589ea0e1262ba7d2ee3e52b53d9a7d Signed-off-by: Yann Gautier --- plat/st/stm32mp1/bl2_plat_setup.c | 3 +-- plat/st/stm32mp1/stm32mp1_security.c | 27 ++++++++------------------- 2 files changed, 9 insertions(+), 21 deletions(-) diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c index bb9582c7e..652765ce1 100644 --- a/plat/st/stm32mp1/bl2_plat_setup.c +++ b/plat/st/stm32mp1/bl2_plat_setup.c @@ -353,8 +353,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(paged_mem_params != NULL); paged_mem_params->image_info.image_base = STM32MP_DDR_BASE + - (dt_get_ddr_size() - STM32MP_DDR_S_SIZE - - STM32MP_DDR_SHMEM_SIZE); + stm32mp_get_ddr_ns_size(); paged_mem_params->image_info.image_max_size = STM32MP_DDR_S_SIZE; diff --git a/plat/st/stm32mp1/stm32mp1_security.c b/plat/st/stm32mp1/stm32mp1_security.c index 61db2e7c7..3a29ba966 100644 --- a/plat/st/stm32mp1/stm32mp1_security.c +++ b/plat/st/stm32mp1/stm32mp1_security.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -35,29 +35,30 @@ static void init_tzc400(void) { unsigned long long region_base, region_top; unsigned long long ddr_base = STM32MP_DDR_BASE; - unsigned long long ddr_size = (unsigned long long)dt_get_ddr_size(); - unsigned long long ddr_top = ddr_base + (ddr_size - 1U); + unsigned long long ddr_ns_size = + (unsigned long long)stm32mp_get_ddr_ns_size(); + unsigned long long ddr_ns_top = ddr_base + (ddr_ns_size - 1U); tzc400_init(STM32MP1_TZC_BASE); tzc400_disable_filters(); -#ifdef AARCH32_SP_OPTEE /* * Region 1 set to cover all non-secure DRAM at 0xC000_0000. Apply the * same configuration to all filters in the TZC. */ region_base = ddr_base; - region_top = ddr_top - STM32MP_DDR_S_SIZE - STM32MP_DDR_SHMEM_SIZE; + region_top = ddr_ns_top; tzc400_configure_region(STM32MP1_FILTER_BIT_ALL, 1, region_base, region_top, TZC_REGION_S_NONE, TZC_REGION_NSEC_ALL_ACCESS_RDWR); +#ifdef AARCH32_SP_OPTEE /* Region 2 set to cover all secure DRAM. */ region_base = region_top + 1U; - region_top = ddr_top - STM32MP_DDR_SHMEM_SIZE; + region_top += STM32MP_DDR_S_SIZE; tzc400_configure_region(STM32MP1_FILTER_BIT_ALL, 2, region_base, region_top, @@ -66,24 +67,12 @@ static void init_tzc400(void) /* Region 3 set to cover non-secure shared memory DRAM. */ region_base = region_top + 1U; - region_top = ddr_top; + region_top += STM32MP_DDR_SHMEM_SIZE; tzc400_configure_region(STM32MP1_FILTER_BIT_ALL, 3, region_base, region_top, TZC_REGION_S_NONE, TZC_REGION_NSEC_ALL_ACCESS_RDWR); -#else - /* - * Region 1 set to cover all DRAM at 0xC000_0000. Apply the - * same configuration to all filters in the TZC. - */ - region_base = ddr_base; - region_top = ddr_top; - tzc400_configure_region(STM32MP1_FILTER_BIT_ALL, 1, - region_base, - region_top, - TZC_REGION_S_NONE, - TZC_REGION_NSEC_ALL_ACCESS_RDWR); #endif /* Raise an exception if a NS device tries to access secure memory */ -- cgit v1.2.3 From 536d906abcc623a54e3ee9f48417258695f67d24 Mon Sep 17 00:00:00 2001 From: Oliver Swede Date: Mon, 11 Nov 2019 11:11:06 +0000 Subject: plat/arm/board/arm_fpga: Enable basic BL31 port for an FPGA image This adds the minimal functions and definitions to create a basic BL31 port for an initial FPGA image, in order for the port to be uploaded to one the FPGA boards operated by an internal group within Arm, such that BL31 runs as a payload for an image. Future changes will enable the port for a wide range of system configurations running on the FPGA boards to ensure compatibility with multiple FPGA images. It is expected that this will replace the FPGA fork of the Linux kernel bootwrapper by performing similar secure-world initialization and setup through the use of drivers and other well-established methods, before passing control to the kernel, which will act as the BL33 payload and run in EL2NS. This change introduces a basic, loadable port with the console initialized by setting the baud rate and base address of the UART as configured by the Zeus image. It is a BL31-only port, and RESET_TO_BL31 is enabled to reflect this. Signed-off-by: Oliver Swede Change-Id: I1817ad81be00afddcdbbda1ab70eb697203178e2 --- plat/arm/board/arm_fpga/aarch64/fpga_helpers.S | 90 ++++++++++++++++++++++++++ plat/arm/board/arm_fpga/fpga_bl31_setup.c | 52 +++++++++++++++ plat/arm/board/arm_fpga/fpga_console.c | 23 +++++++ plat/arm/board/arm_fpga/fpga_def.h | 33 ++++++++++ plat/arm/board/arm_fpga/fpga_pm.c | 15 +++++ plat/arm/board/arm_fpga/fpga_private.h | 14 ++++ plat/arm/board/arm_fpga/fpga_topology.c | 25 +++++++ plat/arm/board/arm_fpga/include/plat_macros.S | 13 ++++ plat/arm/board/arm_fpga/include/platform_def.h | 38 +++++++++++ plat/arm/board/arm_fpga/platform.mk | 59 +++++++++++++++++ 10 files changed, 362 insertions(+) create mode 100644 plat/arm/board/arm_fpga/aarch64/fpga_helpers.S create mode 100644 plat/arm/board/arm_fpga/fpga_bl31_setup.c create mode 100644 plat/arm/board/arm_fpga/fpga_console.c create mode 100644 plat/arm/board/arm_fpga/fpga_def.h create mode 100644 plat/arm/board/arm_fpga/fpga_pm.c create mode 100644 plat/arm/board/arm_fpga/fpga_private.h create mode 100644 plat/arm/board/arm_fpga/fpga_topology.c create mode 100644 plat/arm/board/arm_fpga/include/plat_macros.S create mode 100644 plat/arm/board/arm_fpga/include/platform_def.h create mode 100644 plat/arm/board/arm_fpga/platform.mk diff --git a/plat/arm/board/arm_fpga/aarch64/fpga_helpers.S b/plat/arm/board/arm_fpga/aarch64/fpga_helpers.S new file mode 100644 index 000000000..57e5320bb --- /dev/null +++ b/plat/arm/board/arm_fpga/aarch64/fpga_helpers.S @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + + .globl plat_get_my_entrypoint + .globl plat_secondary_cold_boot_setup + .globl plat_is_my_cpu_primary + .globl platform_mem_init + .globl plat_my_core_pos + .globl plat_fpga_calc_core_pos + .globl plat_crash_console_init + .globl plat_crash_console_putc + .globl plat_crash_console_flush + +/* ----------------------------------------------------------------------- + * unsigned long plat_get_my_entrypoint (void); + * TODO: determine if warm boot should be supported for FPGA images + * ----------------------------------------------------------------------- + */ +func plat_get_my_entrypoint + mov x0, #0 + ret +endfunc plat_get_my_entrypoint + +/* ----------------------------------------------------------------------- + * void plat_secondary_cold_boot_setup (void); + * TODO: add placeholder PSCI implementation for FPGA images + * ----------------------------------------------------------------------- + */ +func plat_secondary_cold_boot_setup + ret +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 + mov_imm x1, MPIDR_AFFINITY_MASK + and x0, x0, x1 + cmp x0, #FPGA_PRIMARY_CPU + cset w0, eq + ret +endfunc plat_is_my_cpu_primary + +func platform_mem_init + ret +endfunc platform_mem_init + +func plat_my_core_pos + mrs x0, mpidr_el1 + b plat_fpga_calc_core_pos +endfunc plat_my_core_pos + +/* ----------------------------------------------------------------------- + * unsigned int plat_fpga_calc_core_pos(u_register_t mpidr) + * TODO: add calculation of the core position for FPGA image CPUs + * ----------------------------------------------------------------------- + */ +func plat_fpga_calc_core_pos + mov x0, #0 + ret +endfunc plat_fpga_calc_core_pos + +func plat_crash_console_init + mov_imm x0, PLAT_FPGA_CRASH_UART_BASE + mov_imm x1, PLAT_FPGA_CRASH_UART_CLK_IN_HZ + mov_imm x2, PLAT_FPGA_CONSOLE_BAUDRATE + b console_pl011_core_init +endfunc plat_crash_console_init + +func plat_crash_console_putc + mov_imm x1, PLAT_FPGA_CRASH_UART_BASE + b console_pl011_core_putc +endfunc plat_crash_console_putc + +func plat_crash_console_flush + mov_imm x0, PLAT_FPGA_CRASH_UART_BASE + b console_pl011_core_flush +endfunc plat_crash_console_flush diff --git a/plat/arm/board/arm_fpga/fpga_bl31_setup.c b/plat/arm/board/arm_fpga/fpga_bl31_setup.c new file mode 100644 index 000000000..aaa25bc30 --- /dev/null +++ b/plat/arm/board/arm_fpga/fpga_bl31_setup.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include "fpga_private.h" + +void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, + u_register_t arg2, u_register_t arg3) +{ + fpga_console_init(); + /* + * TODO: implement any extra early platform setup before jumping to BL33 + * payload + */ +} + +void bl31_plat_arch_setup(void) +{ +} + +void bl31_platform_setup(void) +{ + /* TODO: initialize GIC and timer using the specifications of the FPGA image */ +} + +entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) +{ + /* + * TODO: return entry_point_info_t struct containing information about the + * BL33 payload, which will run in EL2NS mode. + */ + return NULL; +} + +unsigned int plat_get_syscnt_freq2(void) +{ + /* + * TODO: return the frequency of the System Counter as configured by the + * FPGA image + */ + return 0; +} + +void bl31_plat_enable_mmu(uint32_t flags) +{ + /* TODO: determine if MMU needs to be enabled */ +} diff --git a/plat/arm/board/arm_fpga/fpga_console.c b/plat/arm/board/arm_fpga/fpga_console.c new file mode 100644 index 000000000..b4ebf3424 --- /dev/null +++ b/plat/arm/board/arm_fpga/fpga_console.c @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include + +static console_t console; + +void fpga_console_init(void) +{ + (void)console_pl011_register(PLAT_FPGA_BOOT_UART_BASE, + PLAT_FPGA_BOOT_UART_CLK_IN_HZ, + PLAT_FPGA_CONSOLE_BAUDRATE, + &console); + + console_set_scope(&console, CONSOLE_FLAG_BOOT | + CONSOLE_FLAG_RUNTIME); +} diff --git a/plat/arm/board/arm_fpga/fpga_def.h b/plat/arm/board/arm_fpga/fpga_def.h new file mode 100644 index 000000000..8c542e095 --- /dev/null +++ b/plat/arm/board/arm_fpga/fpga_def.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#ifndef FPGA_DEF_H +#define FPGA_DEF_H + +/* + * The initial FPGA image configures a system with 2 clusters, 1 core in each, + * and multi-threading is unimplemented. + */ +#define FPGA_MAX_CLUSTER_COUNT 2 +#define FPGA_MAX_CPUS_PER_CLUSTER 1 +#define FPGA_MAX_PE_PER_CPU 1 + +#define FPGA_PRIMARY_CPU 0x0 + +/******************************************************************************* + * FPGA image memory map related constants + ******************************************************************************/ + +/* UART base address and clock frequency, as configured by the image */ +#define PLAT_FPGA_BOOT_UART_BASE 0x7ff80000 +#define PLAT_FPGA_BOOT_UART_CLK_IN_HZ 10000000 + +#define PLAT_FPGA_CRASH_UART_BASE PLAT_FPGA_BOOT_UART_BASE +#define PLAT_FPGA_CRASH_UART_CLK_IN_HZ PLAT_FPGA_BOOT_UART_CLK_IN_HZ + +#endif diff --git a/plat/arm/board/arm_fpga/fpga_pm.c b/plat/arm/board/arm_fpga/fpga_pm.c new file mode 100644 index 000000000..dc95028da --- /dev/null +++ b/plat/arm/board/arm_fpga/fpga_pm.c @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +/* TODO: add PSCI implementation */ + +int plat_setup_psci_ops(uintptr_t sec_entrypoint, + const plat_psci_ops_t **psci_ops) +{ + return 0; +} diff --git a/plat/arm/board/arm_fpga/fpga_private.h b/plat/arm/board/arm_fpga/fpga_private.h new file mode 100644 index 000000000..28aaef2ff --- /dev/null +++ b/plat/arm/board/arm_fpga/fpga_private.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FPGA_PRIVATE_H +#define FPGA_PRIVATE_H + +unsigned int plat_fpga_calc_core_pos(u_register_t mpidr); + +void fpga_console_init(void); + +#endif diff --git a/plat/arm/board/arm_fpga/fpga_topology.c b/plat/arm/board/arm_fpga/fpga_topology.c new file mode 100644 index 000000000..5458376b5 --- /dev/null +++ b/plat/arm/board/arm_fpga/fpga_topology.c @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include "fpga_private.h" +#include + +const unsigned char *plat_get_power_domain_tree_desc(void) +{ + /* TODO: add description of power domain topology and PSCI implementation */ + return NULL; +} + +int plat_core_pos_by_mpidr(u_register_t mpidr) +{ + /* + * TODO: calculate core position in a way that accounts for CPUs that + * potentially implement multithreading + */ + return (int) plat_fpga_calc_core_pos(mpidr); +} diff --git a/plat/arm/board/arm_fpga/include/plat_macros.S b/plat/arm/board/arm_fpga/include/plat_macros.S new file mode 100644 index 000000000..44cddeb36 --- /dev/null +++ b/plat/arm/board/arm_fpga/include/plat_macros.S @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLAT_MACROS_S +#define PLAT_MACROS_S + +.macro plat_crash_print_regs +.endm + +#endif diff --git a/plat/arm/board/arm_fpga/include/platform_def.h b/plat/arm/board/arm_fpga/include/platform_def.h new file mode 100644 index 000000000..313892023 --- /dev/null +++ b/plat/arm/board/arm_fpga/include/platform_def.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +#include +#include "../fpga_def.h" + +#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64" + +#define PLATFORM_LINKER_ARCH aarch64 + +#define PLATFORM_STACK_SIZE UL(0x800) + +#define CACHE_WRITEBACK_SHIFT U(6) +#define CACHE_WRITEBACK_GRANULE (U(1) << CACHE_WRITEBACK_SHIFT) + +#define PLATFORM_CORE_COUNT \ + (FPGA_MAX_CLUSTER_COUNT * FPGA_MAX_CPUS_PER_CLUSTER * FPGA_MAX_PE_PER_CPU) + +#define PLAT_NUM_PWR_DOMAINS (FPGA_MAX_CLUSTER_COUNT + \ + PLATFORM_CORE_COUNT) + 1 + +#define BL31_BASE UL(0x80000000) +#define BL31_LIMIT UL(0x80100000) + +#define PLAT_MAX_RET_STATE 1 +#define PLAT_MAX_OFF_STATE 2 + +#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL2 + +#define PLAT_FPGA_CONSOLE_BAUDRATE 38400 + +#endif diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk new file mode 100644 index 000000000..73e1870a9 --- /dev/null +++ b/plat/arm/board/arm_fpga/platform.mk @@ -0,0 +1,59 @@ +# +# Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +RESET_TO_BL31 := 1 +ifeq (${RESET_TO_BL31}, 0) +$(error "This is a BL31-only port; RESET_TO_BL31 must be enabled") +endif + +CTX_INCLUDE_AARCH32_REGS := 0 +ifeq (${CTX_INCLUDE_AARCH32_REGS}, 1) +$(error "This is an AArch64-only port; CTX_INCLUDE_AARCH32_REGS must be disabled") +endif + +ifeq (${TRUSTED_BOARD_BOOT}, 1) +$(error "TRUSTED_BOARD_BOOT must be disabled") +endif + +ifndef PRELOADED_BL33_BASE +$(error "PRELOADED_BL33_BASE is not set") +endif + +ifndef FPGA_PRELOADED_DTB_BASE +$(error "FPGA_PRELOADED_DTB_BASE is not set") +else +$(eval $(call add_define,FPGA_PRELOADED_DTB_BASE)) +endif + +# Treating this as a memory-constrained port for now +USE_COHERENT_MEM := 0 + +# The CPU in the initial image makes use of this feature +HW_ASSISTED_COHERENCY := 1 + +FPGA_CPU_LIBS := lib/cpus/${ARCH}/aem_generic.S \ + lib/cpus/aarch64/neoverse_zeus.S + +FPGA_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ + drivers/arm/gic/v3/gicv3_main.c \ + plat/common/plat_gicv3.c + +PLAT_INCLUDES := -Iplat/arm/board/arm_fpga/include + +PLAT_BL_COMMON_SOURCES := plat/arm/board/arm_fpga/${ARCH}/fpga_helpers.S + +BL31_SOURCES += drivers/delay_timer/delay_timer.c \ + drivers/delay_timer/generic_delay_timer.c \ + drivers/arm/pl011/${ARCH}/pl011_console.S \ + plat/common/plat_psci_common.c \ + plat/arm/board/arm_fpga/fpga_pm.c \ + plat/arm/board/arm_fpga/fpga_topology.c \ + plat/arm/board/arm_fpga/fpga_console.c \ + plat/arm/board/arm_fpga/fpga_bl31_setup.c \ + ${FPGA_CPU_LIBS} \ + ${FPGA_GIC_SOURCES} + +all: bl31 -- cgit v1.2.3 From 5cfe699f2bcff007a51bea3b093fd869ef7480cf Mon Sep 17 00:00:00 2001 From: Oliver Swede Date: Mon, 11 Nov 2019 11:32:32 +0000 Subject: plat/arm/board/arm_fpga: Use preloaded BL33 alternative boot flow This makes use of the PRELOADED_BL33_BASE flag to indicate to BL31 that the BL33 payload (kernel) has already been loaded and resides in memory; BL31 will then jump to the non-secure address. For this port the BL33 payload is the Linux kernel, and in accordance with the pre-kernel setup requirements (as specified in the `Booting AArch64 Linux' documentation: https://www.kernel.org/doc/Documentation/arm64/booting.txt), this change also sets up the primary CPU's registers x0-x3 so they are the expected values, which includes the address of the DTB at x0. An external linker script is currently required to combine BL31, the BL33 payload, and any other software images to create an ELF file that can be uploaded to the FPGA board along with the bit file. It therefore has dependencies on the value of PRELOADED_BL33_BASE (kernel base) and the DTB base (plus any other relevant base addresses used to distinguish the different ELF sections), both of which are set in this patch. Signed-off-by: Oliver Swede Change-Id: If7ae8ee82d1e09fb05f553f6077ae13680dbf66b --- plat/arm/board/arm_fpga/fpga_bl31_setup.c | 49 +++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/plat/arm/board/arm_fpga/fpga_bl31_setup.c b/plat/arm/board/arm_fpga/fpga_bl31_setup.c index aaa25bc30..b641ad194 100644 --- a/plat/arm/board/arm_fpga/fpga_bl31_setup.c +++ b/plat/arm/board/arm_fpga/fpga_bl31_setup.c @@ -4,19 +4,43 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include + #include #include #include "fpga_private.h" +static entry_point_info_t bl33_image_ep_info; + +uintptr_t plat_get_ns_image_entrypoint(void) +{ +#ifdef PRELOADED_BL33_BASE + return PRELOADED_BL33_BASE; +#else + return 0; +#endif +} + +uint32_t fpga_get_spsr_for_bl33_entry(void) +{ + return SPSR_64(MODE_EL2, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); +} + void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { fpga_console_init(); - /* - * TODO: implement any extra early platform setup before jumping to BL33 - * payload - */ + + bl33_image_ep_info.pc = plat_get_ns_image_entrypoint(); + bl33_image_ep_info.spsr = fpga_get_spsr_for_bl33_entry(); + SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); + + /* Set x0-x3 for the primary CPU as expected by the kernel */ + bl33_image_ep_info.args.arg0 = (u_register_t)FPGA_PRELOADED_DTB_BASE; + bl33_image_ep_info.args.arg1 = 0U; + bl33_image_ep_info.args.arg2 = 0U; + bl33_image_ep_info.args.arg3 = 0U; } void bl31_plat_arch_setup(void) @@ -30,11 +54,18 @@ void bl31_platform_setup(void) entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) { - /* - * TODO: return entry_point_info_t struct containing information about the - * BL33 payload, which will run in EL2NS mode. - */ - return NULL; + entry_point_info_t *next_image_info; + next_image_info = &bl33_image_ep_info; + + /* Only expecting BL33: the kernel will run in EL2NS */ + assert(type == NON_SECURE); + + /* None of the images can have 0x0 as the entrypoint */ + if (next_image_info->pc) { + return next_image_info; + } else { + return NULL; + } } unsigned int plat_get_syscnt_freq2(void) -- cgit v1.2.3 From 7ee4db6e4720ebb45a7c20da06c06091ee95c298 Mon Sep 17 00:00:00 2001 From: Oliver Swede Date: Mon, 2 Dec 2019 13:21:52 +0000 Subject: plat/arm/board/arm_fpga: Add PSCI implementation for FPGA images This adds a basic PSCI implementation allow secondary CPUs to be released from an initial state and continue through to the warm boot entrypoint. Each secondary CPU is kept in a holding pen, whereby it polls the value representing its hold state, by reading this from an array that acts as a table for all the PEs. The hold states are initially set to 0 for all cores to indicate that the executing core should continue polling. To prevent the secondary CPUs from interfering with the platform's initialization, they are only updated by the primary CPU once the cold boot sequence has completed and fpga_pwr_domain_on(mpidr) is called. The polling target CPU will then read 1 (which indicates that it should branch to the warm reset entrypoint) and then jump to that address rather than continue polling. In addition to the initial polling behaviour of the secondary CPUs before their warm boot reset sequence, they are also placed in a low-power wfe() state at the end of each poll; accordingly, the PSCI fpga_pwr_domain_on(mpidr) function also signals an event to all cores (after updating the target CPU's hold entry) to wake them from this state, allowing any secondary CPUs that are still polling to check their hold state again. This method is in accordance with both the PSCI and Linux kernel recommendations, as the lessened overhead reduces the energy consumption associated with the busy-loop. The table of hold entries is implemented by a global array as shared SRAM (which is used by other platforms in similar implementations) is not available on the FPGA images. Signed-off-by: Oliver Swede Change-Id: I65cfd1892f8be1dfcb285f0e1e94e7a9870cdf5a --- plat/arm/board/arm_fpga/aarch64/fpga_helpers.S | 46 ++++++++++++++-- plat/arm/board/arm_fpga/fpga_pm.c | 76 +++++++++++++++++++++++++- plat/arm/board/arm_fpga/fpga_topology.c | 54 ++++++++++++++++-- plat/arm/board/arm_fpga/include/platform_def.h | 4 ++ 4 files changed, 169 insertions(+), 11 deletions(-) diff --git a/plat/arm/board/arm_fpga/aarch64/fpga_helpers.S b/plat/arm/board/arm_fpga/aarch64/fpga_helpers.S index 57e5320bb..f350455d5 100644 --- a/plat/arm/board/arm_fpga/aarch64/fpga_helpers.S +++ b/plat/arm/board/arm_fpga/aarch64/fpga_helpers.S @@ -20,8 +20,8 @@ .globl plat_crash_console_flush /* ----------------------------------------------------------------------- - * unsigned long plat_get_my_entrypoint (void); - * TODO: determine if warm boot should be supported for FPGA images + * Indicate a cold boot for every CPU - warm boot is unsupported for the + * holding pen PSCI implementation. * ----------------------------------------------------------------------- */ func plat_get_my_entrypoint @@ -31,11 +31,26 @@ endfunc plat_get_my_entrypoint /* ----------------------------------------------------------------------- * void plat_secondary_cold_boot_setup (void); - * TODO: add placeholder PSCI implementation for FPGA images * ----------------------------------------------------------------------- */ func plat_secondary_cold_boot_setup - ret + /* + * Poll the CPU's hold entry until it indicates to jump + * to the entrypoint address. + */ + bl plat_my_core_pos + lsl x0, x0, #PLAT_FPGA_HOLD_ENTRY_SHIFT + ldr x1, =hold_base + ldr x2, =fpga_sec_entrypoint +poll_hold_entry: + ldr x3, [x1, x0] + cmp x3, #PLAT_FPGA_HOLD_STATE_GO + b.ne 1f + ldr x3, [x2] + br x3 +1: + wfe + b poll_hold_entry endfunc plat_secondary_cold_boot_setup /* ----------------------------------------------------------------------- @@ -64,11 +79,30 @@ endfunc plat_my_core_pos /* ----------------------------------------------------------------------- * unsigned int plat_fpga_calc_core_pos(u_register_t mpidr) - * TODO: add calculation of the core position for FPGA image CPUs * ----------------------------------------------------------------------- */ func plat_fpga_calc_core_pos - mov x0, #0 + /* + * Check for MT bit in MPIDR, which may be either value for images + * running on the FPGA. + * + * 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, #FPGA_MAX_CPUS_PER_CLUSTER + madd x1, x2, x4, x1 + mov x5, #FPGA_MAX_PE_PER_CPU + madd x0, x1, x5, x0 ret endfunc plat_fpga_calc_core_pos diff --git a/plat/arm/board/arm_fpga/fpga_pm.c b/plat/arm/board/arm_fpga/fpga_pm.c index dc95028da..a734e1d8c 100644 --- a/plat/arm/board/arm_fpga/fpga_pm.c +++ b/plat/arm/board/arm_fpga/fpga_pm.c @@ -4,12 +4,86 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include + +#include +#include #include +#include + +/* + * This is a basic PSCI implementation that allows secondary CPUs to be + * released from their initial state and continue to the warm boot entrypoint. + * + * The secondary CPUs are placed in a holding pen and released by calls + * to fpga_pwr_domain_on(mpidr), which updates the hold entry for the CPU + * specified by the mpidr argument - the (polling) target CPU will then branch + * to the BL31 warm boot sequence at the entrypoint address. + * + * Additionally, the secondary CPUs are kept in a low-power wfe() state + * (placed there at the end of each poll) and woken when necessary through + * calls to sev() in fpga_pwr_domain_on(mpidr), once the hold state for the + * relevant CPU has been updated. + * + * Hotplug is currently implemented using a wfi-loop, which removes the + * dependencies on any power controllers or other mechanism that is specific + * to the running system as specified by the FPGA image. + */ + +uint64_t hold_base[PLATFORM_CORE_COUNT]; +uintptr_t fpga_sec_entrypoint; + +/* + * Calls to the CPU specified by the mpidr will set its hold entry to a value + * indicating that it should stop polling and branch off to the warm entrypoint. + */ +static int fpga_pwr_domain_on(u_register_t mpidr) +{ + unsigned int pos = plat_core_pos_by_mpidr(mpidr); + unsigned long current_mpidr = read_mpidr_el1(); + + if (mpidr == current_mpidr) { + return PSCI_E_ALREADY_ON; + } + hold_base[pos] = PLAT_FPGA_HOLD_STATE_GO; + flush_dcache_range((uintptr_t)&hold_base[pos], sizeof(uint64_t)); + sev(); /* Wake any CPUs from wfe */ + + return PSCI_E_SUCCESS; +} + +static void fpga_pwr_domain_off(const psci_power_state_t *target_state) +{ + while (1) { + wfi(); + } +} + +static void fpga_cpu_standby(plat_local_state_t cpu_state) +{ + /* + * Enter standby state + * dsb is good practice before using wfi to enter low power states + */ + u_register_t scr = read_scr_el3(); + write_scr_el3(scr|SCR_IRQ_BIT); + dsb(); + wfi(); + write_scr_el3(scr); +} -/* TODO: add PSCI implementation */ +plat_psci_ops_t plat_fpga_psci_pm_ops = { + .pwr_domain_on = fpga_pwr_domain_on, + .pwr_domain_off = fpga_pwr_domain_off, + .cpu_standby = fpga_cpu_standby +}; int plat_setup_psci_ops(uintptr_t sec_entrypoint, const plat_psci_ops_t **psci_ops) { + fpga_sec_entrypoint = sec_entrypoint; + flush_dcache_range((uint64_t)&fpga_sec_entrypoint, + sizeof(fpga_sec_entrypoint)); + *psci_ops = &plat_fpga_psci_pm_ops; return 0; } diff --git a/plat/arm/board/arm_fpga/fpga_topology.c b/plat/arm/board/arm_fpga/fpga_topology.c index 5458376b5..a705429ac 100644 --- a/plat/arm/board/arm_fpga/fpga_topology.c +++ b/plat/arm/board/arm_fpga/fpga_topology.c @@ -9,17 +9,63 @@ #include "fpga_private.h" #include +static unsigned char fpga_power_domain_tree_desc[FPGA_MAX_CLUSTER_COUNT + 2]; + const unsigned char *plat_get_power_domain_tree_desc(void) { - /* TODO: add description of power domain topology and PSCI implementation */ - return NULL; + int i; + /* + * The highest level is the system level. The next level is constituted + * by clusters and then cores in clusters. + * + * This description of the power domain topology is aligned with the CPU + * indices returned by the plat_core_pos_by_mpidr() and plat_my_core_pos() + * APIs. + */ + fpga_power_domain_tree_desc[0] = 1; + fpga_power_domain_tree_desc[1] = FPGA_MAX_CLUSTER_COUNT; + + for (i = 0; i < FPGA_MAX_CLUSTER_COUNT; i++) { + fpga_power_domain_tree_desc[i + 2] = FPGA_MAX_CPUS_PER_CLUSTER; + } + + return fpga_power_domain_tree_desc; } int plat_core_pos_by_mpidr(u_register_t mpidr) { + unsigned int cluster_id, cpu_id, thread_id; + + mpidr &= MPIDR_AFFINITY_MASK; + if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) { + return -1; + } + + if (mpidr & MPIDR_MT_MASK) { + thread_id = MPIDR_AFFLVL0_VAL(mpidr); + } else { + thread_id = 0; + } + + cpu_id = MPIDR_AFFLVL1_VAL(mpidr); + cluster_id = MPIDR_AFFLVL2_VAL(mpidr); + + if (cluster_id >= FPGA_MAX_CLUSTER_COUNT) { + return -1; + } else if (cpu_id >= FPGA_MAX_CPUS_PER_CLUSTER) { + return -1; + } else if (thread_id >= FPGA_MAX_PE_PER_CPU) { + return -1; + } + /* - * TODO: calculate core position in a way that accounts for CPUs that - * potentially implement multithreading + * The image running on the FPGA may or may not implement multithreading, + * and it shouldn't be assumed this is consistent across all CPUs. + * This ensures that any passed mpidr values reflect the status of the + * primary CPU's MT bit. */ + mpidr |= (read_mpidr_el1() & MPIDR_MT_MASK); + + /* Calculate the correct core, catering for multi-threaded images */ return (int) plat_fpga_calc_core_pos(mpidr); } diff --git a/plat/arm/board/arm_fpga/include/platform_def.h b/plat/arm/board/arm_fpga/include/platform_def.h index 313892023..bf3245e97 100644 --- a/plat/arm/board/arm_fpga/include/platform_def.h +++ b/plat/arm/board/arm_fpga/include/platform_def.h @@ -33,6 +33,10 @@ #define PLAT_MAX_PWR_LVL MPIDR_AFFLVL2 +#define PLAT_FPGA_HOLD_ENTRY_SHIFT 3 +#define PLAT_FPGA_HOLD_STATE_WAIT 0 +#define PLAT_FPGA_HOLD_STATE_GO 1 + #define PLAT_FPGA_CONSOLE_BAUDRATE 38400 #endif -- cgit v1.2.3 From 2d696d1811a370c742b69cf6442144d906a91d8c Mon Sep 17 00:00:00 2001 From: Oliver Swede Date: Mon, 2 Dec 2019 13:33:40 +0000 Subject: plat/arm/board/arm_fpga: Initialize the System Counter This sets the frequency of the system counter so that the Delay Timer driver programs the correct value to CNTCRL. This value depends on the FPGA image being used, and is 10MHz for the initial test image. Once configured, the BL31 platform setup sequence then enables the system counter. Signed-off-by: Oliver Swede Change-Id: Ieb036a36fd990f350b5953357424a255b8ac5d5a --- plat/arm/board/arm_fpga/fpga_bl31_setup.c | 14 ++++++++------ plat/arm/board/arm_fpga/fpga_def.h | 3 +++ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/plat/arm/board/arm_fpga/fpga_bl31_setup.c b/plat/arm/board/arm_fpga/fpga_bl31_setup.c index b641ad194..26228f69e 100644 --- a/plat/arm/board/arm_fpga/fpga_bl31_setup.c +++ b/plat/arm/board/arm_fpga/fpga_bl31_setup.c @@ -5,6 +5,8 @@ */ #include +#include +#include #include #include @@ -49,7 +51,11 @@ void bl31_plat_arch_setup(void) void bl31_platform_setup(void) { - /* TODO: initialize GIC and timer using the specifications of the FPGA image */ + /* Write frequency to CNTCRL and initialize timer */ + generic_delay_timer_init(); + mmio_write_32(FPGA_TIMER_BASE, ((1 << 8) | 1UL)); + + /* TODO: initialize GIC using the specifications of the FPGA image */ } entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) @@ -70,11 +76,7 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) unsigned int plat_get_syscnt_freq2(void) { - /* - * TODO: return the frequency of the System Counter as configured by the - * FPGA image - */ - return 0; + return FPGA_TIMER_FREQUENCY; } void bl31_plat_enable_mmu(uint32_t flags) diff --git a/plat/arm/board/arm_fpga/fpga_def.h b/plat/arm/board/arm_fpga/fpga_def.h index 8c542e095..0f817fe9d 100644 --- a/plat/arm/board/arm_fpga/fpga_def.h +++ b/plat/arm/board/arm_fpga/fpga_def.h @@ -30,4 +30,7 @@ #define PLAT_FPGA_CRASH_UART_BASE PLAT_FPGA_BOOT_UART_BASE #define PLAT_FPGA_CRASH_UART_CLK_IN_HZ PLAT_FPGA_BOOT_UART_CLK_IN_HZ +#define FPGA_TIMER_FREQUENCY 10000000 +#define FPGA_TIMER_BASE 0x2a830000 + #endif -- cgit v1.2.3 From 87762bce84204b38e264bb54804a6bdfbc4d2acf Mon Sep 17 00:00:00 2001 From: Oliver Swede Date: Tue, 3 Dec 2019 14:08:21 +0000 Subject: plat/arm/board/arm_fpga: Initialize the Generic Interrupt Controller This initializes the GIC using the Arm GIC drivers in TF-A. The initial FPGA image uses a GIC600 implementation, and so that its power controller is enabled, this platform port calls the corresponding implementation-specific routines. Signed-off-by: Oliver Swede Change-Id: I88d5a073eead4b653b1ca73273182cd98a95e4c5 --- plat/arm/board/arm_fpga/fpga_bl31_setup.c | 5 ++- plat/arm/board/arm_fpga/fpga_gicv3.c | 53 ++++++++++++++++++++++++++ plat/arm/board/arm_fpga/fpga_pm.c | 10 +++++ plat/arm/board/arm_fpga/fpga_private.h | 4 ++ plat/arm/board/arm_fpga/include/platform_def.h | 47 ++++++++++++++++++++++- plat/arm/board/arm_fpga/platform.mk | 11 ++++-- 6 files changed, 123 insertions(+), 7 deletions(-) create mode 100644 plat/arm/board/arm_fpga/fpga_gicv3.c diff --git a/plat/arm/board/arm_fpga/fpga_bl31_setup.c b/plat/arm/board/arm_fpga/fpga_bl31_setup.c index 26228f69e..d499379ee 100644 --- a/plat/arm/board/arm_fpga/fpga_bl31_setup.c +++ b/plat/arm/board/arm_fpga/fpga_bl31_setup.c @@ -51,11 +51,12 @@ void bl31_plat_arch_setup(void) void bl31_platform_setup(void) { + /* Initialize the GIC driver, cpu and distributor interfaces */ + plat_fpga_gic_init(); + /* Write frequency to CNTCRL and initialize timer */ generic_delay_timer_init(); mmio_write_32(FPGA_TIMER_BASE, ((1 << 8) | 1UL)); - - /* TODO: initialize GIC using the specifications of the FPGA image */ } entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) diff --git a/plat/arm/board/arm_fpga/fpga_gicv3.c b/plat/arm/board/arm_fpga/fpga_gicv3.c new file mode 100644 index 000000000..be1684e4b --- /dev/null +++ b/plat/arm/board/arm_fpga/fpga_gicv3.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include + +static const interrupt_prop_t fpga_interrupt_props[] = { + PLATFORM_G1S_PROPS(INTR_GROUP1S), + PLATFORM_G0_PROPS(INTR_GROUP0) +}; + +static uintptr_t fpga_rdistif_base_addrs[PLATFORM_CORE_COUNT]; + +static unsigned int fpga_mpidr_to_core_pos(unsigned long mpidr) +{ + return (unsigned int)plat_core_pos_by_mpidr(mpidr); +} + +static const gicv3_driver_data_t fpga_gicv3_driver_data = { + .gicd_base = GICD_BASE, + .gicr_base = GICR_BASE, + .interrupt_props = fpga_interrupt_props, + .interrupt_props_num = ARRAY_SIZE(fpga_interrupt_props), + .rdistif_num = PLATFORM_CORE_COUNT, + .rdistif_base_addrs = fpga_rdistif_base_addrs, + .mpidr_to_core_pos = fpga_mpidr_to_core_pos +}; + +void plat_fpga_gic_init(void) +{ + gicv3_driver_init(&fpga_gicv3_driver_data); + gicv3_distif_init(); + gicv3_rdistif_init(plat_my_core_pos()); + gicv3_cpuif_enable(plat_my_core_pos()); +} + +void fpga_pwr_gic_on_finish(void) +{ + gicv3_rdistif_init(plat_my_core_pos()); + gicv3_cpuif_enable(plat_my_core_pos()); +} + +void fpga_pwr_gic_off(void) +{ + gicv3_cpuif_disable(plat_my_core_pos()); + gicv3_rdistif_off(plat_my_core_pos()); +} diff --git a/plat/arm/board/arm_fpga/fpga_pm.c b/plat/arm/board/arm_fpga/fpga_pm.c index a734e1d8c..4c372179f 100644 --- a/plat/arm/board/arm_fpga/fpga_pm.c +++ b/plat/arm/board/arm_fpga/fpga_pm.c @@ -9,6 +9,8 @@ #include #include #include + +#include "fpga_private.h" #include /* @@ -52,8 +54,15 @@ static int fpga_pwr_domain_on(u_register_t mpidr) return PSCI_E_SUCCESS; } +void fpga_pwr_domain_on_finish(const psci_power_state_t *target_state) +{ + fpga_pwr_gic_on_finish(); +} + static void fpga_pwr_domain_off(const psci_power_state_t *target_state) { + fpga_pwr_gic_off(); + while (1) { wfi(); } @@ -74,6 +83,7 @@ static void fpga_cpu_standby(plat_local_state_t cpu_state) plat_psci_ops_t plat_fpga_psci_pm_ops = { .pwr_domain_on = fpga_pwr_domain_on, + .pwr_domain_on_finish = fpga_pwr_domain_on_finish, .pwr_domain_off = fpga_pwr_domain_off, .cpu_standby = fpga_cpu_standby }; diff --git a/plat/arm/board/arm_fpga/fpga_private.h b/plat/arm/board/arm_fpga/fpga_private.h index 28aaef2ff..7545bd17e 100644 --- a/plat/arm/board/arm_fpga/fpga_private.h +++ b/plat/arm/board/arm_fpga/fpga_private.h @@ -11,4 +11,8 @@ unsigned int plat_fpga_calc_core_pos(u_register_t mpidr); void fpga_console_init(void); +void plat_fpga_gic_init(void); +void fpga_pwr_gic_on_finish(void); +void fpga_pwr_gic_off(void); + #endif diff --git a/plat/arm/board/arm_fpga/include/platform_def.h b/plat/arm/board/arm_fpga/include/platform_def.h index bf3245e97..6e87a26d1 100644 --- a/plat/arm/board/arm_fpga/include/platform_def.h +++ b/plat/arm/board/arm_fpga/include/platform_def.h @@ -28,8 +28,51 @@ #define BL31_BASE UL(0x80000000) #define BL31_LIMIT UL(0x80100000) -#define PLAT_MAX_RET_STATE 1 -#define PLAT_MAX_OFF_STATE 2 +#define GICD_BASE 0x30000000 +#define GICR_BASE 0x30040000 + +#define PLAT_SDEI_NORMAL_PRI 0x70 + +#define ARM_IRQ_SEC_PHY_TIMER 29 + +#define ARM_IRQ_SEC_SGI_0 8 +#define ARM_IRQ_SEC_SGI_1 9 +#define ARM_IRQ_SEC_SGI_2 10 +#define ARM_IRQ_SEC_SGI_3 11 +#define ARM_IRQ_SEC_SGI_4 12 +#define ARM_IRQ_SEC_SGI_5 13 +#define ARM_IRQ_SEC_SGI_6 14 +#define ARM_IRQ_SEC_SGI_7 15 + +/* + * Define a list of Group 1 Secure and Group 0 interrupt properties as per GICv3 + * terminology. On a GICv2 system or mode, the lists will be merged and treated + * as Group 0 interrupts. + */ +#define PLATFORM_G1S_PROPS(grp) \ + INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, (grp), \ + GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, (grp), \ + GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, (grp), \ + GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, (grp), \ + GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, (grp), \ + GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, (grp), \ + GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, (grp), \ + GIC_INTR_CFG_EDGE) + +#define PLATFORM_G0_PROPS(grp) \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_0, PLAT_SDEI_NORMAL_PRI, (grp), \ + GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, (grp), \ + GIC_INTR_CFG_EDGE) + +#define PLAT_MAX_RET_STATE 1 +#define PLAT_MAX_OFF_STATE 2 #define PLAT_MAX_PWR_LVL MPIDR_AFFLVL2 diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk index 73e1870a9..8ce0ae004 100644 --- a/plat/arm/board/arm_fpga/platform.mk +++ b/plat/arm/board/arm_fpga/platform.mk @@ -37,9 +37,14 @@ HW_ASSISTED_COHERENCY := 1 FPGA_CPU_LIBS := lib/cpus/${ARCH}/aem_generic.S \ lib/cpus/aarch64/neoverse_zeus.S -FPGA_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v3/gicv3_main.c \ - plat/common/plat_gicv3.c +FPGA_GIC_SOURCES := drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gicdv3_helpers.c \ + drivers/arm/gic/v3/gicrv3_helpers.c \ + drivers/arm/gic/v3/gicv3_main.c \ + drivers/arm/gic/v3/gic600.c \ + drivers/arm/gic/common/gic_common.c \ + plat/common/plat_gicv3.c \ + plat/arm/board/arm_fpga/fpga_gicv3.c PLAT_INCLUDES := -Iplat/arm/board/arm_fpga/include -- cgit v1.2.3 From e726c75814e6fc25c3cf59d2103625d578eefbae Mon Sep 17 00:00:00 2001 From: Oliver Swede Date: Mon, 16 Dec 2019 14:08:27 +0000 Subject: plat/arm/board/arm_fpga: Enable port for alternative cluster configurations This change is part of the goal of enabling the port to be compatible with multiple FPGA images. The BL31 port that is uploaded as a payload to the FPGA with an image should cater for a wide variety of system configurations. This patch makes the necessary changes to enable it to function with images whose cluster configurations may be larger (either by utilizing more clusters, more CPUs per cluster, more threads in each CPU, or a combination) than the initial image being used for testing. As part of this, the hard-coded values that configure the size of the array describing the topology of the power domain tree are increased to max. 8 clusters, max. 8 cores per cluster & max 4 threads per core. This ensures the port works with cluster configurations up to these sizes. When there are too many entries for the number of available PEs, e.g. if there is a variable number of CPUs between clusters, then there will be empty entries in the array. This is permitted and the PSCI library will still function as expected. While this increases its size, this shouldn't be an issue in the context of the size of BL31, and is worth the trade-off for the extra compatibility. Signed-off-by: Oliver Swede Change-Id: I7d4ae1e20b2e99fdbac428d122a2cf9445394363 --- plat/arm/board/arm_fpga/fpga_def.h | 13 +++++++++---- plat/arm/board/arm_fpga/platform.mk | 4 ++++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/plat/arm/board/arm_fpga/fpga_def.h b/plat/arm/board/arm_fpga/fpga_def.h index 0f817fe9d..56ee1663d 100644 --- a/plat/arm/board/arm_fpga/fpga_def.h +++ b/plat/arm/board/arm_fpga/fpga_def.h @@ -10,12 +10,17 @@ #define FPGA_DEF_H /* - * The initial FPGA image configures a system with 2 clusters, 1 core in each, - * and multi-threading is unimplemented. + * These are set to large values to account for images describing systems with + * larger cluster configurations. + * + * For cases where the number of clusters, cores or threads is smaller than a + * maximum value below, this does not affect the PSCI functionality as any PEs + * that are present will still be indexed appropriately regardless of any empty + * entries in the array used to represent the topology. */ #define FPGA_MAX_CLUSTER_COUNT 2 -#define FPGA_MAX_CPUS_PER_CLUSTER 1 -#define FPGA_MAX_PE_PER_CPU 1 +#define FPGA_MAX_CPUS_PER_CLUSTER 8 +#define FPGA_MAX_PE_PER_CPU 4 #define FPGA_PRIMARY_CPU 0x0 diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk index 8ce0ae004..194c59551 100644 --- a/plat/arm/board/arm_fpga/platform.mk +++ b/plat/arm/board/arm_fpga/platform.mk @@ -9,6 +9,10 @@ ifeq (${RESET_TO_BL31}, 0) $(error "This is a BL31-only port; RESET_TO_BL31 must be enabled") endif +ifeq (${ENABLE_PIE}, 1) +override SEPARATE_CODE_AND_RODATA := 1 +endif + CTX_INCLUDE_AARCH32_REGS := 0 ifeq (${CTX_INCLUDE_AARCH32_REGS}, 1) $(error "This is an AArch64-only port; CTX_INCLUDE_AARCH32_REGS must be disabled") -- cgit v1.2.3 From 62056e4e8f9dcd298b441454b372c0720ed2abc1 Mon Sep 17 00:00:00 2001 From: Oliver Swede Date: Tue, 7 Jan 2020 14:43:01 +0000 Subject: plat/arm/board/arm_fpga: Enable position-independent execution This allows the BL31 port to run with position-independent execution enabled so that it can be ran from any address in the system. This increases the flexibility of the image, allowing it to be ran from other locations rather than only its hardcoded absolute address (currently set to the typical DRAM base of 2GB). This may be useful for future images that describe system configurations with other memory layouts (e.g. where SRAM is included). It does this by setting ENABLE_PIE=1 and changing the absolute address to 0. The load address of bl31.bin can then be specified by the -l [load address] argument in the fpga-run command (additionally, this address is required by any preceding payloads that specify the start address. For ELF payloads this is usually extracted automatically by reading the entrypoint address in the header, however bl31.bin is a different file format so has this additional dependency). Signed-off-by: Oliver Swede Change-Id: Idd74787796ab0cf605fe2701163d9c4b3223a143 --- plat/arm/board/arm_fpga/include/platform_def.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/plat/arm/board/arm_fpga/include/platform_def.h b/plat/arm/board/arm_fpga/include/platform_def.h index 6e87a26d1..5c8aff691 100644 --- a/plat/arm/board/arm_fpga/include/platform_def.h +++ b/plat/arm/board/arm_fpga/include/platform_def.h @@ -8,6 +8,8 @@ #define PLATFORM_DEF_H #include +#include +#include #include "../fpga_def.h" #define PLATFORM_LINKER_FORMAT "elf64-littleaarch64" @@ -25,8 +27,13 @@ #define PLAT_NUM_PWR_DOMAINS (FPGA_MAX_CLUSTER_COUNT + \ PLATFORM_CORE_COUNT) + 1 +#if !ENABLE_PIE #define BL31_BASE UL(0x80000000) #define BL31_LIMIT UL(0x80100000) +#else +#define BL31_BASE UL(0x0) +#define BL31_LIMIT UL(0x01000000) +#endif #define GICD_BASE 0x30000000 #define GICR_BASE 0x30040000 -- cgit v1.2.3 From 4b5793c9a873f84f27eb560b453f999eb8437755 Mon Sep 17 00:00:00 2001 From: Oliver Swede Date: Wed, 15 Jan 2020 10:20:09 +0000 Subject: plat/arm/board/arm_fpga: Compile with additional CPU libraries This change is part of the goal of enabling the port to be compatible with multiple FPGA images. BL31 behaves differently depending on whether or not the CPUs in the system use cache coherency, and as a result any CPU libraries that are compiled together must serve processors that are consistent in this regard. This compiles a different set of CPU libraries depending on whether or not the HW_ASSISTED_COHERENCY is enabled at build-time to indicate the CPUs support hardware-level support for cache coherency. This build flag is used in the makefile in the same way as the Arm FVP port. Signed-off-by: Oliver Swede Change-Id: I18300b4443176b89767015e3688c0f315a91c27e --- plat/arm/board/arm_fpga/platform.mk | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk index 194c59551..b4f38fab4 100644 --- a/plat/arm/board/arm_fpga/platform.mk +++ b/plat/arm/board/arm_fpga/platform.mk @@ -35,11 +35,36 @@ endif # Treating this as a memory-constrained port for now USE_COHERENT_MEM := 0 -# The CPU in the initial image makes use of this feature +# This can be overridden depending on CPU(s) used in the FPGA image HW_ASSISTED_COHERENCY := 1 -FPGA_CPU_LIBS := lib/cpus/${ARCH}/aem_generic.S \ - lib/cpus/aarch64/neoverse_zeus.S +FPGA_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 + FPGA_CPU_LIBS += lib/cpus/aarch64/cortex_a35.S \ + lib/cpus/aarch64/cortex_a53.S \ + lib/cpus/aarch64/cortex_a57.S \ + lib/cpus/aarch64/cortex_a72.S \ + lib/cpus/aarch64/cortex_a73.S +else +# AArch64-only cores + FPGA_CPU_LIBS += lib/cpus/aarch64/cortex_a76.S \ + lib/cpus/aarch64/cortex_a76ae.S \ + lib/cpus/aarch64/cortex_a77.S \ + lib/cpus/aarch64/neoverse_n1.S \ + lib/cpus/aarch64/neoverse_e1.S \ + lib/cpus/aarch64/neoverse_zeus.S \ + lib/cpus/aarch64/cortex_hercules.S \ + lib/cpus/aarch64/cortex_hercules_ae.S \ + lib/cpus/aarch64/cortex_a65.S \ + lib/cpus/aarch64/cortex_a65ae.S +# AArch64/AArch32 cores + FPGA_CPU_LIBS += lib/cpus/aarch64/cortex_a55.S \ + lib/cpus/aarch64/cortex_a75.S +endif FPGA_GIC_SOURCES := drivers/arm/gic/v3/gicv3_helpers.c \ drivers/arm/gic/v3/gicdv3_helpers.c \ -- cgit v1.2.3 From f98f464e2a22cc6fc3760fa9ea8b61076832d445 Mon Sep 17 00:00:00 2001 From: Manish Pandey Date: Thu, 26 Mar 2020 21:46:53 +0000 Subject: fconf: notify if fw_config dt is not used Notify if fw_config dt is either not available or not loaded from fip. Change-Id: I4dfcbe5032503d97f532a3287c5312c581578b68 Signed-off-by: Manish Pandey --- lib/fconf/fconf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/fconf/fconf.c b/lib/fconf/fconf.c index 3007273ae..a5ec14300 100644 --- a/lib/fconf/fconf.c +++ b/lib/fconf/fconf.c @@ -33,7 +33,7 @@ void fconf_load_config(void) err = load_auth_image(TB_FW_CONFIG_ID, &arm_tb_fw_info); if (err != 0) { /* Return if FW_CONFIG is not loaded */ - WARN("Failed to load FW_CONFIG\n"); + VERBOSE("FW_CONFIG not loaded, continuing without it\n"); return; } -- cgit v1.2.3 From 4c65b4decf6b48b9b95b7d4fc465730fb24d6042 Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Thu, 26 Mar 2020 16:09:21 +0100 Subject: doc: add spm and spmd related build options Signed-off-by: Olivier Deprez Change-Id: I93892dbe76611a7a4b852af3272a0e6271ae037b --- docs/getting_started/build-options.rst | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index f138feb4c..0daa71b6d 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -146,6 +146,12 @@ Common build options is on hardware that does not implement AArch32, or at least not at EL1 and higher ELs). Default value is 1. +- ``CTX_INCLUDE_EL2_REGS`` : This boolean option provides context save/restore + operations when entering/exiting an EL2 execution context. This is of primary + interest when Armv8.4-SecEL2 extension is implemented. Default is 0 (disabled). + This option must be equal to 1 (enabled) when ``SPD=spmd`` and + ``SPMD_SPM_AT_SEL2`` is set. + - ``CTX_INCLUDE_FPREGS``: Boolean option that, when set to 1, will cause the FP registers to be included when saving and restoring the CPU context. Default is 0. @@ -536,8 +542,8 @@ Common build options - ``SEPARATE_CODE_AND_RODATA``: Whether code and read-only data should be isolated on separate memory pages. This is a trade-off between security and memory usage. See "Isolating code and read-only data on separate memory - pages" section in :ref:`Firmware Design`. This flag is disabled by default and - affects all BL images. + pages" section in :ref:`Firmware Design`. This flag is disabled by default + and affects all BL images. - ``SEPARATE_NOBITS_REGION``: Setting this option to ``1`` allows the NOBITS sections of BL31 (.bss, stacks, page tables, and coherent memory) to be @@ -550,7 +556,9 @@ Common build options This build option is only valid if ``ARCH=aarch64``. The value should be the path to the directory containing the SPD source, relative to ``services/spd/``; the directory is expected to contain a makefile called - ``.mk``. + ``.mk``. The SPM Dispatcher standard service is located in + services/std_svc/spmd and enabled by ``SPD=spmd``. The SPM Dispatcher + cannot be enabled when the ``SPM_MM`` option is enabled. - ``SPIN_ON_BL1_EXIT``: This option introduces an infinite loop in BL1. It can take either 0 (no loop) or 1 (add a loop). 0 is the default. This loop stops @@ -558,13 +566,23 @@ Common build options firmware images have been loaded in memory, and the MMU and caches are turned off. Refer to the "Debugging options" section for more details. +- ``SPMD_SPM_AT_SEL2`` : this boolean option is used jointly with the SPM + Dispatcher option (``SPD=spmd``). When enabled (1) it indicates the SPMC + component runs at the S-EL2 execution state provided by the Armv8.4-SecEL2 + extension. This is the default when enabling the SPM Dispatcher. When + disabled (0) it indicates the SPMC component runs at the S-EL1 execution + state. This latter configuration supports pre-Armv8.4 platforms (aka not + implementing the Armv8.4-SecEL2 extension). + - ``SPM_MM`` : Boolean option to enable the Management Mode (MM)-based Secure - Partition Manager (SPM) implementation. The default value is ``0``. + Partition Manager (SPM) implementation. The default value is ``0`` + (disabled). This option cannot be enabled (``1``) when SPM Dispatcher is + enabled (``SPD=spmd``). - ``SP_LAYOUT_FILE``: Platform provided path to JSON file containing the - description of secure partitions. Build system will parse this file and - package all secure partition blobs in FIP. This file not necessarily be - part of TF-A tree. Only avaialbe when ``SPD=spmd``. + description of secure partitions. The build system will parse this file and + package all secure partition blobs into the FIP. This file is not + necessarily part of TF-A tree. Only available when ``SPD=spmd``. - ``SP_MIN_WITH_SECURE_FIQ``: Boolean flag to indicate the SP_MIN handles secure interrupts (caught through the FIQ line). Platforms can enable -- cgit v1.2.3 From f27b6924d615ea3d61725891e882cdc725411ba9 Mon Sep 17 00:00:00 2001 From: Zelalem Date: Thu, 26 Mar 2020 16:15:34 -0500 Subject: Flush dcache when storing timestamp On DynamIQ CPU FVPs, stats test cases are failing when hardware-assisted coherency is enabled due to a corrupt timestamp value. Investigation of the issue indicates that on these models the timestamp value is stored in cache instead of memory. This patch flushes the dcache when the timestamp is stored to make sure it is stored in memory. Change-Id: I05cd54ba5991a5a96dd07f1e08b5212273201411 Signed-off-by: Zelalem --- plat/common/plat_psci_common.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/plat/common/plat_psci_common.c b/plat/common/plat_psci_common.c index bed8890a7..c32e59f9c 100644 --- a/plat/common/plat_psci_common.c +++ b/plat/common/plat_psci_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -63,7 +63,6 @@ static u_register_t calc_stat_residency(unsigned long long pwrupts, /* * Capture timestamp before entering a low power state. - * No cache maintenance is required when capturing the timestamp. * Cache maintenance may be needed when reading these timestamps. */ void plat_psci_stat_accounting_start( @@ -71,12 +70,11 @@ void plat_psci_stat_accounting_start( { assert(state_info != NULL); PMF_CAPTURE_TIMESTAMP(psci_svc, PSCI_STAT_ID_ENTER_LOW_PWR, - PMF_NO_CACHE_MAINT); + PMF_CACHE_MAINT); } /* * Capture timestamp after exiting a low power state. - * No cache maintenance is required when capturing the timestamp. * Cache maintenance may be needed when reading these timestamps. */ void plat_psci_stat_accounting_stop( @@ -84,7 +82,7 @@ void plat_psci_stat_accounting_stop( { assert(state_info != NULL); PMF_CAPTURE_TIMESTAMP(psci_svc, PSCI_STAT_ID_EXIT_LOW_PWR, - PMF_NO_CACHE_MAINT); + PMF_CACHE_MAINT); } /* -- cgit v1.2.3 From 5c215de249a6bb96b9f758a46fea70a366b13f61 Mon Sep 17 00:00:00 2001 From: Aditya Angadi Date: Tue, 11 Feb 2020 15:46:24 +0530 Subject: plat/arm/sgi: fix the incorrect check for SCMI channel ID Use ARRAY_SIZE macro instead of sizeof operator to obtain the maximum number of SCMI channels supported on the platform. Change-Id: Id922bb548af98ac99b4ac0c34e38e589e5a80b2d Signed-off-by: Aditya Angadi --- plat/arm/css/sgi/sgi_bl31_setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/arm/css/sgi/sgi_bl31_setup.c b/plat/arm/css/sgi/sgi_bl31_setup.c index fcb7e1f9f..a4aed004d 100644 --- a/plat/arm/css/sgi/sgi_bl31_setup.c +++ b/plat/arm/css/sgi/sgi_bl31_setup.c @@ -75,7 +75,7 @@ scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id) { if (sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM || sgi_plat_info.platform_id == RD_DANIEL_SID_VER_PART_NUM) { - if (channel_id >= sizeof(rd_n1e1_edge_scmi_plat_info)) + if (channel_id >= ARRAY_SIZE(rd_n1e1_edge_scmi_plat_info)) panic(); return &rd_n1e1_edge_scmi_plat_info[channel_id]; } -- cgit v1.2.3 From a6ea06f563bf1a7545732892d1da3bf2dced2e47 Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Mon, 23 Mar 2020 18:45:17 +0000 Subject: TF-A GICv3 driver: Introduce makefile This patch moves all GICv3 driver files into new added 'gicv3.mk' makefile for the benefit of the generic driver which can evolve in the future without affecting platforms. The patch adds GICv3 driver configuration flags 'GICV3_IMPL', 'GICV3_IMPL_GIC600_MULTICHIP' and 'GICV3_OVERRIDE_DISTIF_PWR_OPS' described in 'GICv3 driver options' section of 'build-option.rst' document. NOTE: Platforms with GICv3 driver need to be modified to include 'drivers/arm/gic/v3/gicv3.mk' in their makefiles. Change-Id: If055f6770ff20f5dee5a3c99ae7ced7cdcac5c44 Signed-off-by: Alexei Fedorov --- docs/getting_started/build-options.rst | 21 +++++++++++++++++++ drivers/arm/gic/v3/gicv3.mk | 34 +++++++++++++++++++++++++++++++ plat/arm/board/fvp/platform.mk | 26 ++++++++++++----------- plat/arm/board/n1sdp/platform.mk | 14 ++++++------- plat/arm/board/rdn1edge/platform.mk | 4 +++- plat/arm/css/sgi/sgi-common.mk | 16 +++++++-------- plat/arm/css/sgm/sgm-common.mk | 16 +++++++-------- plat/imx/imx8m/imx8mm/platform.mk | 11 ++++------ plat/imx/imx8m/imx8mq/platform.mk | 11 ++++------ plat/imx/imx8qm/platform.mk | 11 ++++------ plat/imx/imx8qx/platform.mk | 11 ++++------ plat/marvell/a3700/common/a3700_common.mk | 13 +++++------- plat/mediatek/mt8183/platform.mk | 11 ++++------ plat/qemu/qemu/platform.mk | 9 ++++---- plat/qemu/qemu_sbsa/platform.mk | 9 ++++---- plat/rockchip/rk3399/platform.mk | 11 ++++------ plat/socionext/synquacer/platform.mk | 9 ++++---- plat/socionext/uniphier/platform.mk | 9 ++++---- plat/ti/k3/common/plat_common.mk | 9 ++++---- plat/xilinx/versal/platform.mk | 11 ++++------ 20 files changed, 148 insertions(+), 118 deletions(-) create mode 100644 drivers/arm/gic/v3/gicv3.mk diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 50cafcfa0..69e103d38 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -667,6 +667,27 @@ Common build options cluster platforms). If this option is enabled, then warm boot path enables D-caches immediately after enabling MMU. This option defaults to 0. +GICv3 driver options +-------------------- + +GICv3 driver files are included using directive: + +``include drivers/arm/gic/v3/gicv3.mk`` + +The driver can be configured with the following options set in the platform +makefile: + +- ``GICV3_IMPL``: Selects between GIC-500 and GIC-600 variants of GICv3. + This option can take values GIC500 and GIC600 with default set to GIC500. + +- ``GICV3_IMPL_GIC600_MULTICHIP``: Selects GIC-600 variant with multichip + functionality. This option defaults to 0 + +- ``GICV3_OVERRIDE_DISTIF_PWR_OPS``: Allows override of default implementation + of ``arm_gicv3_distif_pre_save`` and ``arm_gicv3_distif_post_restore`` + functions. This is required for FVP platform which need to simulate GIC save + and restore during SYSTEM_SUSPEND without powering down GIC. Default is 0. + Debugging options ----------------- diff --git a/drivers/arm/gic/v3/gicv3.mk b/drivers/arm/gic/v3/gicv3.mk new file mode 100644 index 000000000..164f88eda --- /dev/null +++ b/drivers/arm/gic/v3/gicv3.mk @@ -0,0 +1,34 @@ +# +# Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# Default configuration values +GICV3_IMPL ?= GIC500 +GICV3_IMPL_GIC600_MULTICHIP ?= 0 +GICV3_OVERRIDE_DISTIF_PWR_OPS ?= 0 + +GICV3_SOURCES += drivers/arm/gic/common/gic_common.c \ + drivers/arm/gic/v3/gicv3_main.c \ + drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gicdv3_helpers.c \ + drivers/arm/gic/v3/gicrv3_helpers.c + +ifeq (${GICV3_OVERRIDE_DISTIF_PWR_OPS}, 0) +GICV3_SOURCES += drivers/arm/gic/v3/arm_gicv3_common.c +endif + +# Either GIC-600 or GIC-500 can be selected at one time +ifeq (${GICV3_IMPL}, GIC600) +# GIC-600 sources +GICV3_SOURCES += drivers/arm/gic/v3/gic600.c +ifeq (${GICV3_IMPL_GIC600_MULTICHIP}, 1) +GICV3_SOURCES += drivers/arm/gic/v3/gic600_multichip.c +endif +else ifeq (${GICV3_IMPL}, GIC500) +# GIC-500 sources +GICV3_SOURCES += drivers/arm/gic/v3/gic500.c +else +$(error "Incorrect GICV3_IMPL value ${GICV3_IMPL}") +endif diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index e64c4d4cf..472e3e78c 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -48,21 +48,23 @@ endif $(eval $(call add_define,FVP_INTERCONNECT_DRIVER)) -FVP_GICV3_SOURCES := drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v3/gicv3_main.c \ - drivers/arm/gic/v3/gicv3_helpers.c \ - drivers/arm/gic/v3/gicdv3_helpers.c \ - drivers/arm/gic/v3/gicrv3_helpers.c \ +# Choose the GIC sources depending upon the how the FVP will be invoked +ifeq (${FVP_USE_GIC_DRIVER},$(filter ${FVP_USE_GIC_DRIVER},FVP_GICV3 FVP_GIC600)) + ifeq (${FVP_USE_GIC_DRIVER}, FVP_GIC600) + GICV3_IMPL := GIC600 + endif + +# GIC500 is the default option in case GICV3_IMPL is not set + +GICV3_OVERRIDE_DISTIF_PWR_OPS := 1 + +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk + +FVP_GIC_SOURCES := ${GICV3_SOURCES} \ plat/common/plat_gicv3.c \ plat/arm/common/arm_gicv3.c -# Choose the GIC sources depending upon the how the FVP will be invoked -ifeq (${FVP_USE_GIC_DRIVER}, FVP_GICV3) -FVP_GIC_SOURCES := ${FVP_GICV3_SOURCES} \ - drivers/arm/gic/v3/gic500.c -else ifeq (${FVP_USE_GIC_DRIVER},FVP_GIC600) -FVP_GIC_SOURCES := ${FVP_GICV3_SOURCES} \ - drivers/arm/gic/v3/gic600.c else ifeq (${FVP_USE_GIC_DRIVER}, FVP_GICV2) FVP_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ drivers/arm/gic/v2/gicv2_main.c \ diff --git a/plat/arm/board/n1sdp/platform.mk b/plat/arm/board/n1sdp/platform.mk index 5856c9f4f..44f7b8a52 100644 --- a/plat/arm/board/n1sdp/platform.mk +++ b/plat/arm/board/n1sdp/platform.mk @@ -14,16 +14,16 @@ PLAT_INCLUDES := -I${N1SDP_BASE}/include N1SDP_CPU_SOURCES := lib/cpus/aarch64/neoverse_n1.S +# GIC-600 configuration +GICV3_IMPL := GIC600 +GICV3_IMPL_GIC600_MULTICHIP := 1 -N1SDP_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v3/gicv3_main.c \ - drivers/arm/gic/v3/gicv3_helpers.c \ - drivers/arm/gic/v3/gicdv3_helpers.c \ - drivers/arm/gic/v3/gicrv3_helpers.c \ - drivers/arm/gic/v3/gic600_multichip.c \ +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk + +N1SDP_GIC_SOURCES := ${GICV3_SOURCES} \ plat/common/plat_gicv3.c \ plat/arm/common/arm_gicv3.c \ - drivers/arm/gic/v3/gic600.c PLAT_BL_COMMON_SOURCES := ${N1SDP_BASE}/n1sdp_plat.c \ ${N1SDP_BASE}/aarch64/n1sdp_helper.S diff --git a/plat/arm/board/rdn1edge/platform.mk b/plat/arm/board/rdn1edge/platform.mk index 135676d43..3ff85f159 100644 --- a/plat/arm/board/rdn1edge/platform.mk +++ b/plat/arm/board/rdn1edge/platform.mk @@ -4,6 +4,9 @@ # SPDX-License-Identifier: BSD-3-Clause # +# GIC-600 configuration +GICV3_IMPL_GIC600_MULTICHIP := 1 + include plat/arm/css/sgi/sgi-common.mk RDN1EDGE_BASE = plat/arm/board/rdn1edge @@ -26,7 +29,6 @@ BL31_SOURCES += ${SGI_CPU_SOURCES} \ ${RDN1EDGE_BASE}/rdn1edge_plat.c \ ${RDN1EDGE_BASE}/rdn1edge_topology.c \ drivers/cfi/v2m/v2m_flash.c \ - drivers/arm/gic/v3/gic600_multichip.c \ lib/utils/mem_region.c \ plat/arm/common/arm_nor_psci_mem_protect.c diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/css/sgi/sgi-common.mk index ea5a56356..250458144 100644 --- a/plat/arm/css/sgi/sgi-common.mk +++ b/plat/arm/css/sgi/sgi-common.mk @@ -22,15 +22,15 @@ INTERCONNECT_SOURCES := ${CSS_ENT_BASE}/sgi_interconnect.c PLAT_INCLUDES += -I${CSS_ENT_BASE}/include -ENT_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v3/gicv3_main.c \ - drivers/arm/gic/v3/gicv3_helpers.c \ - drivers/arm/gic/v3/gicdv3_helpers.c \ - drivers/arm/gic/v3/gicrv3_helpers.c \ - plat/common/plat_gicv3.c \ - plat/arm/common/arm_gicv3.c \ - drivers/arm/gic/v3/gic600.c +# GIC-600 configuration +GICV3_IMPL := GIC600 +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk + +ENT_GIC_SOURCES := ${GICV3_SOURCES} \ + plat/common/plat_gicv3.c \ + plat/arm/common/arm_gicv3.c PLAT_BL_COMMON_SOURCES += ${CSS_ENT_BASE}/sgi_plat.c \ ${CSS_ENT_BASE}/aarch64/sgi_helper.S diff --git a/plat/arm/css/sgm/sgm-common.mk b/plat/arm/css/sgm/sgm-common.mk index 49fc7176a..60e9fb2e1 100644 --- a/plat/arm/css/sgm/sgm-common.mk +++ b/plat/arm/css/sgm/sgm-common.mk @@ -22,15 +22,15 @@ SGM_CPU_SOURCES := lib/cpus/aarch64/cortex_a55.S \ INTERCONNECT_SOURCES := ${CSS_SGM_BASE}/sgm_interconnect.c -SGM_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v3/gicv3_main.c \ - drivers/arm/gic/v3/gicv3_helpers.c \ - drivers/arm/gic/v3/gicdv3_helpers.c \ - drivers/arm/gic/v3/gicrv3_helpers.c \ +# GIC-600 configuration +GICV3_IMPL := GIC600 + +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk + +SGM_GIC_SOURCES := ${GICV3_SOURCES} \ plat/common/plat_gicv3.c \ - plat/arm/common/arm_gicv3.c \ - drivers/arm/gic/v3/gic600.c \ - drivers/arm/gic/v3/arm_gicv3_common.c + plat/arm/common/arm_gicv3.c BL1_SOURCES += $(SGM_CPU_SOURCES) \ ${INTERCONNECT_SOURCES} \ diff --git a/plat/imx/imx8m/imx8mm/platform.mk b/plat/imx/imx8m/imx8mm/platform.mk index 5fa300304..3ead7b0b2 100644 --- a/plat/imx/imx8m/imx8mm/platform.mk +++ b/plat/imx/imx8m/imx8mm/platform.mk @@ -8,13 +8,10 @@ PLAT_INCLUDES := -Iplat/imx/common/include \ -Iplat/imx/imx8m/include \ -Iplat/imx/imx8m/imx8mm/include -IMX_GIC_SOURCES := drivers/arm/gic/v3/gicv3_helpers.c \ - drivers/arm/gic/v3/gicdv3_helpers.c \ - drivers/arm/gic/v3/gicrv3_helpers.c \ - drivers/arm/gic/v3/arm_gicv3_common.c \ - drivers/arm/gic/v3/gic500.c \ - drivers/arm/gic/v3/gicv3_main.c \ - drivers/arm/gic/common/gic_common.c \ +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk + +IMX_GIC_SOURCES := ${GICV3_SOURCES} \ plat/common/plat_gicv3.c \ plat/common/plat_psci_common.c \ plat/imx/common/plat_imx8_gic.c diff --git a/plat/imx/imx8m/imx8mq/platform.mk b/plat/imx/imx8m/imx8mq/platform.mk index e419f05c9..546101043 100644 --- a/plat/imx/imx8m/imx8mq/platform.mk +++ b/plat/imx/imx8m/imx8mq/platform.mk @@ -8,13 +8,10 @@ PLAT_INCLUDES := -Iplat/imx/common/include \ -Iplat/imx/imx8m/include \ -Iplat/imx/imx8m/imx8mq/include -IMX_GIC_SOURCES := drivers/arm/gic/v3/gicv3_helpers.c \ - drivers/arm/gic/v3/gicdv3_helpers.c \ - drivers/arm/gic/v3/gicrv3_helpers.c \ - drivers/arm/gic/v3/arm_gicv3_common.c \ - drivers/arm/gic/v3/gic500.c \ - drivers/arm/gic/v3/gicv3_main.c \ - drivers/arm/gic/common/gic_common.c \ +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk + +IMX_GIC_SOURCES := ${GICV3_SOURCES} \ plat/common/plat_gicv3.c \ plat/common/plat_psci_common.c \ plat/imx/common/plat_imx8_gic.c diff --git a/plat/imx/imx8qm/platform.mk b/plat/imx/imx8qm/platform.mk index 20ee05be9..f35fa0020 100644 --- a/plat/imx/imx8qm/platform.mk +++ b/plat/imx/imx8qm/platform.mk @@ -7,13 +7,10 @@ PLAT_INCLUDES := -Iplat/imx/imx8qm/include \ -Iplat/imx/common/include \ -IMX_GIC_SOURCES := drivers/arm/gic/v3/gicv3_helpers.c \ - drivers/arm/gic/v3/gicdv3_helpers.c \ - drivers/arm/gic/v3/gicrv3_helpers.c \ - drivers/arm/gic/v3/arm_gicv3_common.c \ - drivers/arm/gic/v3/gic500.c \ - drivers/arm/gic/v3/gicv3_main.c \ - drivers/arm/gic/common/gic_common.c \ +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk + +IMX_GIC_SOURCES := ${GICV3_SOURCES} \ plat/common/plat_gicv3.c \ plat/common/plat_psci_common.c \ plat/imx/common/plat_imx8_gic.c diff --git a/plat/imx/imx8qx/platform.mk b/plat/imx/imx8qx/platform.mk index 5e8ba063c..f18d634fe 100644 --- a/plat/imx/imx8qx/platform.mk +++ b/plat/imx/imx8qx/platform.mk @@ -7,13 +7,10 @@ PLAT_INCLUDES := -Iplat/imx/imx8qx/include \ -Iplat/imx/common/include \ -IMX_GIC_SOURCES := drivers/arm/gic/v3/gicv3_helpers.c \ - drivers/arm/gic/v3/gicdv3_helpers.c \ - drivers/arm/gic/v3/gicrv3_helpers.c \ - drivers/arm/gic/v3/arm_gicv3_common.c \ - drivers/arm/gic/v3/gic500.c \ - drivers/arm/gic/v3/gicv3_main.c \ - drivers/arm/gic/common/gic_common.c \ +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk + +IMX_GIC_SOURCES := ${GICV3_SOURCES} \ plat/common/plat_gicv3.c \ plat/imx/common/plat_imx8_gic.c diff --git a/plat/marvell/a3700/common/a3700_common.mk b/plat/marvell/a3700/common/a3700_common.mk index fd2b7ed79..76c067747 100644 --- a/plat/marvell/a3700/common/a3700_common.mk +++ b/plat/marvell/a3700/common/a3700_common.mk @@ -78,14 +78,11 @@ $(eval $(call add_define,CONFIG_GICV3)) # CCI-400 $(eval $(call add_define,USE_CCI)) -MARVELL_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v3/gicv3_main.c \ - drivers/arm/gic/v3/gicv3_helpers.c \ - drivers/arm/gic/v3/gicdv3_helpers.c \ - drivers/arm/gic/v3/gicrv3_helpers.c \ - drivers/arm/gic/v3/arm_gicv3_common.c \ - plat/common/plat_gicv3.c \ - drivers/arm/gic/v3/gic500.c +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk + +MARVELL_GIC_SOURCES := ${GICV3_SOURCES} \ + plat/common/plat_gicv3.c PLAT_INCLUDES := -I$(PLAT_FAMILY_BASE)/$(PLAT) \ -I$(PLAT_COMMON_BASE)/include \ diff --git a/plat/mediatek/mt8183/platform.mk b/plat/mediatek/mt8183/platform.mk index 59ffe5dc0..3ccc928ac 100644 --- a/plat/mediatek/mt8183/platform.mk +++ b/plat/mediatek/mt8183/platform.mk @@ -26,15 +26,12 @@ PLAT_BL_COMMON_SOURCES := lib/xlat_tables/aarch64/xlat_tables.c \ plat/common/plat_psci_common.c \ plat/common/aarch64/crash_console_helpers.S +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk + BL31_SOURCES += common/desc_image_load.c \ drivers/arm/cci/cci.c \ - drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v3/arm_gicv3_common.c \ - drivers/arm/gic/v3/gicv3_helpers.c \ - drivers/arm/gic/v3/gicdv3_helpers.c \ - drivers/arm/gic/v3/gicrv3_helpers.c \ - drivers/arm/gic/v3/gic500.c \ - drivers/arm/gic/v3/gicv3_main.c \ + ${GICV3_SOURCES} \ drivers/delay_timer/delay_timer.c \ drivers/delay_timer/generic_delay_timer.c \ drivers/gpio/gpio.c \ diff --git a/plat/qemu/qemu/platform.mk b/plat/qemu/qemu/platform.mk index 6aa198c33..1bf4e0801 100644 --- a/plat/qemu/qemu/platform.mk +++ b/plat/qemu/qemu/platform.mk @@ -139,11 +139,10 @@ QEMU_GICV2_SOURCES := drivers/arm/gic/v2/gicv2_helpers.c \ plat/common/plat_gicv2.c \ ${PLAT_QEMU_COMMON_PATH}/qemu_gicv2.c -QEMU_GICV3_SOURCES := drivers/arm/gic/v3/gicv3_helpers.c \ - drivers/arm/gic/v3/gicdv3_helpers.c \ - drivers/arm/gic/v3/gicrv3_helpers.c \ - drivers/arm/gic/v3/gicv3_main.c \ - drivers/arm/gic/common/gic_common.c \ +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk + +QEMU_GICV3_SOURCES := ${GICV3_SOURCES} \ plat/common/plat_gicv3.c \ ${PLAT_QEMU_COMMON_PATH}/qemu_gicv3.c diff --git a/plat/qemu/qemu_sbsa/platform.mk b/plat/qemu/qemu_sbsa/platform.mk index 6ad3d8bbf..09856d641 100644 --- a/plat/qemu/qemu_sbsa/platform.mk +++ b/plat/qemu/qemu_sbsa/platform.mk @@ -62,11 +62,10 @@ BL2_SOURCES += ${PLAT_QEMU_COMMON_PATH}/qemu_bl2_mem_params_desc.c \ common/desc_image_load.c endif -QEMU_GIC_SOURCES := drivers/arm/gic/v3/gicv3_helpers.c \ - drivers/arm/gic/v3/gicdv3_helpers.c \ - drivers/arm/gic/v3/gicrv3_helpers.c \ - drivers/arm/gic/v3/gicv3_main.c \ - drivers/arm/gic/common/gic_common.c \ +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk + +QEMU_GIC_SOURCES := ${GICV3_SOURCES} \ plat/common/plat_gicv3.c \ ${PLAT_QEMU_COMMON_PATH}/qemu_gicv3.c diff --git a/plat/rockchip/rk3399/platform.mk b/plat/rockchip/rk3399/platform.mk index 0dc1840c9..a658fb286 100644 --- a/plat/rockchip/rk3399/platform.mk +++ b/plat/rockchip/rk3399/platform.mk @@ -24,13 +24,10 @@ PLAT_INCLUDES := -I${RK_PLAT_COMMON}/ \ -I${RK_PLAT_SOC}/include/ \ -I${RK_PLAT_SOC}/include/shared/ \ -RK_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v3/arm_gicv3_common.c \ - drivers/arm/gic/v3/gic500.c \ - drivers/arm/gic/v3/gicv3_main.c \ - drivers/arm/gic/v3/gicv3_helpers.c \ - drivers/arm/gic/v3/gicdv3_helpers.c \ - drivers/arm/gic/v3/gicrv3_helpers.c \ +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk + +RK_GIC_SOURCES := ${GICV3_SOURCES} \ plat/common/plat_gicv3.c \ ${RK_PLAT}/common/rockchip_gicv3.c diff --git a/plat/socionext/synquacer/platform.mk b/plat/socionext/synquacer/platform.mk index 0d9071b32..dcd5d31ee 100644 --- a/plat/socionext/synquacer/platform.mk +++ b/plat/socionext/synquacer/platform.mk @@ -30,12 +30,11 @@ PLAT_BL_COMMON_SOURCES += $(PLAT_PATH)/sq_helpers.S \ drivers/delay_timer/generic_delay_timer.c \ ${XLAT_TABLES_LIB_SRCS} +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk + BL31_SOURCES += drivers/arm/ccn/ccn.c \ - drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v3/gicv3_helpers.c \ - drivers/arm/gic/v3/gicdv3_helpers.c \ - drivers/arm/gic/v3/gicrv3_helpers.c \ - drivers/arm/gic/v3/gicv3_main.c \ + ${GICV3_SOURCES} \ lib/cpus/aarch64/cortex_a53.S \ plat/common/plat_gicv3.c \ plat/common/plat_psci_common.c \ diff --git a/plat/socionext/uniphier/platform.mk b/plat/socionext/uniphier/platform.mk index a014f528f..0fcef1d2c 100644 --- a/plat/socionext/uniphier/platform.mk +++ b/plat/socionext/uniphier/platform.mk @@ -55,12 +55,11 @@ BL2_SOURCES += common/desc_image_load.c \ $(PLAT_PATH)/uniphier_scp.c \ $(PLAT_PATH)/uniphier_usb.c +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk + BL31_SOURCES += drivers/arm/cci/cci.c \ - drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v3/gicv3_helpers.c \ - drivers/arm/gic/v3/gicdv3_helpers.c \ - drivers/arm/gic/v3/gicrv3_helpers.c \ - drivers/arm/gic/v3/gicv3_main.c \ + ${GICV3_SOURCES} \ lib/cpus/aarch64/cortex_a53.S \ lib/cpus/aarch64/cortex_a72.S \ plat/common/plat_gicv3.c \ diff --git a/plat/ti/k3/common/plat_common.mk b/plat/ti/k3/common/plat_common.mk index 587b44bc3..03d39f186 100644 --- a/plat/ti/k3/common/plat_common.mk +++ b/plat/ti/k3/common/plat_common.mk @@ -53,12 +53,11 @@ K3_CONSOLE_SOURCES += \ drivers/ti/uart/aarch64/16550_console.S \ ${PLAT_PATH}/common/k3_console.c \ +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk + K3_GIC_SOURCES += \ - drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v3/gicv3_main.c \ - drivers/arm/gic/v3/gicv3_helpers.c \ - drivers/arm/gic/v3/gicdv3_helpers.c \ - drivers/arm/gic/v3/gicrv3_helpers.c \ + ${GICV3_SOURCES} \ plat/common/plat_gicv3.c \ ${PLAT_PATH}/common/k3_gicv3.c \ diff --git a/plat/xilinx/versal/platform.mk b/plat/xilinx/versal/platform.mk index 5d7fd697f..16396dc18 100644 --- a/plat/xilinx/versal/platform.mk +++ b/plat/xilinx/versal/platform.mk @@ -43,17 +43,14 @@ PLAT_INCLUDES := -Iinclude/plat/arm/common/ \ -Iplat/xilinx/versal/include/ \ -Iplat/xilinx/versal/pm_service/ +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk + PLAT_BL_COMMON_SOURCES := lib/xlat_tables/xlat_tables_common.c \ lib/xlat_tables/aarch64/xlat_tables.c \ drivers/delay_timer/delay_timer.c \ drivers/delay_timer/generic_delay_timer.c \ - drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v3/arm_gicv3_common.c \ - drivers/arm/gic/v3/gic500.c \ - drivers/arm/gic/v3/gicv3_main.c \ - drivers/arm/gic/v3/gicv3_helpers.c \ - drivers/arm/gic/v3/gicdv3_helpers.c \ - drivers/arm/gic/v3/gicrv3_helpers.c \ + ${GICV3_SOURCES} \ drivers/arm/pl011/aarch64/pl011_console.S \ plat/common/aarch64/crash_console_helpers.S \ plat/arm/common/arm_cci.c \ -- cgit v1.2.3 From 53adebad8b467c4c12315d7682738ad0ed677a04 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Fri, 27 Mar 2020 13:25:51 +0000 Subject: Create separate header for ARM specific SMCCC defines Moved SMCCC defines from plat_arm.h to new header and include this header in all ARM platforms. Signed-off-by: Manish V Badarkhe Change-Id: I4cbc69c7b9307461de87b7c7bf200dd9b810e485 --- include/plat/arm/common/arm_def.h | 1 + include/plat/arm/common/plat_arm.h | 5 ----- include/plat/arm/common/smccc_def.h | 15 +++++++++++++++ plat/arm/board/a5ds/include/platform_def.h | 1 + plat/arm/board/corstone700/include/platform_def.h | 2 +- plat/arm/board/fvp_ve/include/platform_def.h | 1 + plat/xilinx/versal/include/versal_def.h | 1 + plat/xilinx/zynqmp/include/zynqmp_def.h | 1 + 8 files changed, 21 insertions(+), 6 deletions(-) create mode 100644 include/plat/arm/common/smccc_def.h diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index 7df6b0d88..7c852e19f 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -12,6 +12,7 @@ #include #include #include +#include #include /****************************************************************************** diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index 83d4c20ec..1b5979529 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -148,11 +148,6 @@ void arm_setup_romlib(void); #define ARM_ROTPK_DEVEL_RSA_ID 2 #define ARM_ROTPK_DEVEL_ECDSA_ID 3 -/* Defines used to retrieve ARM SOC revision */ -#define ARM_SOC_CONTINUATION_CODE U(0x4) -#define ARM_SOC_IDENTIFICATION_CODE U(0x3B) -#define ARM_SOC_CONTINUATION_SHIFT U(24) -#define ARM_SOC_IDENTIFICATION_SHIFT U(16) /* IO storage utility functions */ int arm_io_setup(void); diff --git a/include/plat/arm/common/smccc_def.h b/include/plat/arm/common/smccc_def.h new file mode 100644 index 000000000..6e698e5d2 --- /dev/null +++ b/include/plat/arm/common/smccc_def.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef SMCCC_DEF_H +#define SMCCC_DEF_H + +/* Defines used to retrieve ARM SOC revision */ +#define ARM_SOC_CONTINUATION_CODE U(0x4) +#define ARM_SOC_IDENTIFICATION_CODE U(0x3B) +#define ARM_SOC_CONTINUATION_SHIFT U(24) +#define ARM_SOC_IDENTIFICATION_SHIFT U(16) + +#endif /* SMCCC_DEF_H */ diff --git a/plat/arm/board/a5ds/include/platform_def.h b/plat/arm/board/a5ds/include/platform_def.h index 31dfb1cf1..ab0ff5859 100644 --- a/plat/arm/board/a5ds/include/platform_def.h +++ b/plat/arm/board/a5ds/include/platform_def.h @@ -11,6 +11,7 @@ #include #include #include +#include #include /* Memory location options for TSP */ diff --git a/plat/arm/board/corstone700/include/platform_def.h b/plat/arm/board/corstone700/include/platform_def.h index 0fb74e442..cc4dc3a59 100644 --- a/plat/arm/board/corstone700/include/platform_def.h +++ b/plat/arm/board/corstone700/include/platform_def.h @@ -9,9 +9,9 @@ #include #include - #include #include +#include #include /* PL011 UART related constants */ diff --git a/plat/arm/board/fvp_ve/include/platform_def.h b/plat/arm/board/fvp_ve/include/platform_def.h index 1b07a9b42..70a12ea53 100644 --- a/plat/arm/board/fvp_ve/include/platform_def.h +++ b/plat/arm/board/fvp_ve/include/platform_def.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #include "../fvp_ve_def.h" diff --git a/plat/xilinx/versal/include/versal_def.h b/plat/xilinx/versal/include/versal_def.h index 9a9b7c017..810e5d877 100644 --- a/plat/xilinx/versal/include/versal_def.h +++ b/plat/xilinx/versal/include/versal_def.h @@ -7,6 +7,7 @@ #ifndef VERSAL_DEF_H #define VERSAL_DEF_H +#include #include /* List all consoles */ diff --git a/plat/xilinx/zynqmp/include/zynqmp_def.h b/plat/xilinx/zynqmp/include/zynqmp_def.h index 5d335d945..5e7254e5c 100644 --- a/plat/xilinx/zynqmp/include/zynqmp_def.h +++ b/plat/xilinx/zynqmp/include/zynqmp_def.h @@ -7,6 +7,7 @@ #ifndef ZYNQMP_DEF_H #define ZYNQMP_DEF_H +#include #include #define ZYNQMP_CONSOLE_ID_cadence 1 -- cgit v1.2.3 From ebe1f2cfd7749398ed5e3d7ae7fe35af8bbd507e Mon Sep 17 00:00:00 2001 From: Madhukar Pappireddy Date: Fri, 27 Mar 2020 12:52:22 -0500 Subject: plat/sgm775: Add support for dynamic config using fconf 1. Necessary changes to platform makefile to include fw_config device tree and package it in fip.bin 2. Removed hw_config node from fw_config dts as there is no HW_CONFIG device tree source for sgm775 3. Added mbedtls_heap related properties for TBBR functionality Change-Id: I26b940c65b17ad2fb5537141f8649785bb0fd4ad Signed-off-by: Madhukar Pappireddy --- plat/arm/board/sgm775/fdts/sgm775_fw_config.dts | 18 ++++++++++++------ plat/arm/board/sgm775/platform.mk | 7 ++++++- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts b/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts index a0d0ea90e..c5702ca3d 100644 --- a/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts +++ b/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts @@ -18,12 +18,6 @@ max-size = <0x200>; id = ; }; - - hw-config { - load-address = <0x0 0x83000000>; - max-size = <0x01000000>; - id = ; - }; }; tb_fw-config { @@ -31,5 +25,17 @@ /* Disable authentication for development */ disable_auth = <0x0>; + + /* + * The following two entries are placeholders for Mbed TLS + * heap information. The default values don't matter since + * they will be overwritten by BL1. + * In case of having shared Mbed TLS heap between BL1 and BL2, + * BL1 will populate these two properties with the respective + * info about the shared heap. This info will be available for + * BL2 in order to locate and re-use the heap. + */ + mbedtls_heap_addr = <0x0 0x0>; + mbedtls_heap_size = <0x0>; }; }; diff --git a/plat/arm/board/sgm775/platform.mk b/plat/arm/board/sgm775/platform.mk index 355b9ee2c..57edb923d 100644 --- a/plat/arm/board/sgm775/platform.mk +++ b/plat/arm/board/sgm775/platform.mk @@ -8,7 +8,12 @@ include plat/arm/css/sgm/sgm-common.mk SGM775_BASE= plat/arm/board/sgm775 -FDT_SOURCES += ${SGM775_BASE}/fdts/sgm775_fw_config.dts +# Add the FDT_SOURCES and options for Dynamic Config +FDT_SOURCES += ${SGM775_BASE}/fdts/${PLAT}_fw_config.dts +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb + +# Add the TB_FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) PLAT_INCLUDES +=-I${SGM775_BASE}/include/ -- cgit v1.2.3 From d5e97a1d2c79121a68ed1c68bd079e80a5f4540a Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 26 Mar 2020 13:18:48 +0900 Subject: Build: define IMAGE_AT_EL1 or IMAGE_AT_EL3 globally for C files The build system defines the IMAGE_BL* macro when compiling each image. This is useful to distinguish which image the current file is being built for by using #if defined(IMAGE_BL2) or #if defined(IMAGE_BL31), or whatever. There are some cases where we are more interested in which exception level the current file is being built for. include/lib/cpus/{aarch32,aarch64}/cpu_macros.S defines IMAGE_AT_EL3, but we do not have it globally. Pass IMAGE_AT_EL1 or IMAGE_AT_EL3 to BL*_CFLAGS so that it is available from all C code. The library code (libc.a, libmbedtls.a, etc.) is exceptional cases, where the code can be shared between BL images. Other than that, we know the exception level at the build time, and this macro will be useful in the shared code. Change-Id: I7c8a1da10726906adfba981cfe8464dff111d6b0 Signed-off-by: Masahiro Yamada --- Makefile | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Makefile b/Makefile index a1702beaa..af8f847c7 100644 --- a/Makefile +++ b/Makefile @@ -508,6 +508,18 @@ ifeq ($(ARCH),aarch64) endif endif +ifeq (${ARCH},aarch64) +BL1_CFLAGS += -DIMAGE_AT_EL3 +ifeq ($(BL2_AT_EL3),1) +BL2_CFLAGS += -DIMAGE_AT_EL3 +else +BL2_CFLAGS += -DIMAGE_AT_EL1 +endif +BL2U_CFLAGS += -DIMAGE_AT_EL1 +BL31_CFLAGS += -DIMAGE_AT_EL3 +BL32_CFLAGS += -DIMAGE_AT_EL1 +endif + # Include the CPU specific operations makefile, which provides default # values for all CPU errata workarounds and CPU specific optimisations. # This can be overridden by the platform. -- cgit v1.2.3 From fd092be23982c160a3855f1e396b7311b5225bf9 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 26 Mar 2020 13:18:48 +0900 Subject: Add get_current_el_maybe_constant() There are some cases where we want to run EL-dependent code in the shared code. We could use #ifdef, but it leaves slight possibility where we do not know the exception level at the build-time (e.g. library code). The counter approach is to use get_current_el(), but it is run-time detection, so all EL code is linked, some of which might be unneeded. This commit adds get_current_el_maybe_constant(). This is a static inline function that returns a constant value if we know the exception level at build-time. This is mostly the case. if (get_current_el_maybe_constant() == 1) { /* do something for EL1 */ } else if (get_current_el_maybe_constant() == 3) { /* do something for EL3 */ } If get_current_el_maybe_constant() is build-time constant, the compiler will optimize out the unreachable code. If such code is included from the library code, it is not built-time constant. In this case, it falls back to get_current_el(), so it still works. Change-Id: Idb03c20342a5b5173fe2d6b40e1fac7998675ad3 Signed-off-by: Masahiro Yamada --- include/arch/aarch64/arch_helpers.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h index 240c1fbda..7c30758d0 100644 --- a/include/arch/aarch64/arch_helpers.h +++ b/include/arch/aarch64/arch_helpers.h @@ -531,6 +531,23 @@ static inline unsigned int get_current_el(void) return GET_EL(read_CurrentEl()); } +static inline unsigned int get_current_el_maybe_constant(void) +{ +#if defined(IMAGE_AT_EL1) + return 1; +#elif defined(IMAGE_AT_EL2) + return 2; /* no use-case in TF-A */ +#elif defined(IMAGE_AT_EL3) + return 3; +#else + /* + * If we do not know which exception level this is being built for + * (e.g. built for library), fall back to run-time detection. + */ + return get_current_el(); +#endif +} + /* * Check if an EL is implemented from AA64PFR0 register fields. */ -- cgit v1.2.3 From f554773520602d146acb5370242c4c62dafc5080 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 26 Mar 2020 13:18:48 +0900 Subject: xlat_tables_v2: add enable_mmu() enable_mmu_* has a different function name, so it is not handy in the shared code. enable_mmu() calls an appropriate one depending on the exception level. Change-Id: I0657968bfcb91c32733f75f9259f550a5c35b1c3 Signed-off-by: Masahiro Yamada --- include/lib/xlat_tables/xlat_mmu_helpers.h | 3 +++ lib/xlat_tables_v2/xlat_tables_context.c | 17 +++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/include/lib/xlat_tables/xlat_mmu_helpers.h b/include/lib/xlat_tables/xlat_mmu_helpers.h index abdf1b6d0..269afd287 100644 --- a/include/lib/xlat_tables/xlat_mmu_helpers.h +++ b/include/lib/xlat_tables/xlat_mmu_helpers.h @@ -56,6 +56,8 @@ #include #include +#include + /* * Return the values that the MMU configuration registers must contain for the * specified translation context. `params` must be a pointer to array of size @@ -70,6 +72,7 @@ void setup_mmu_cfg(uint64_t *params, unsigned int flags, void enable_mmu_el1(unsigned int flags); void enable_mmu_el2(unsigned int flags); void enable_mmu_el3(unsigned int flags); +void enable_mmu(unsigned int flags); void enable_mmu_direct_el1(unsigned int flags); void enable_mmu_direct_el2(unsigned int flags); diff --git a/lib/xlat_tables_v2/xlat_tables_context.c b/lib/xlat_tables_v2/xlat_tables_context.c index a1c974ec0..032e1424f 100644 --- a/lib/xlat_tables_v2/xlat_tables_context.c +++ b/lib/xlat_tables_v2/xlat_tables_context.c @@ -239,6 +239,23 @@ void enable_mmu_el3(unsigned int flags) enable_mmu_direct_el3(flags); } +void enable_mmu(unsigned int flags) +{ + switch (get_current_el_maybe_constant()) { + case 1: + enable_mmu_el1(flags); + break; + case 2: + enable_mmu_el2(flags); + break; + case 3: + enable_mmu_el3(flags); + break; + default: + panic(); + } +} + #else /* !__aarch64__ */ void enable_mmu_svc_mon(unsigned int flags) -- cgit v1.2.3 From 848a7e8ce1d936f97084beb5222f1036a484bad5 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 25 Mar 2020 16:55:28 +0900 Subject: Build: introduce per-BL CPPFLAGS and ASFLAGS Currently, BL*_CFLAGS and BL*_LDFLAGS are supported. For completion, this adds BL*_CPPFLAGS and BL*_ASFLAGS. My main motivation is to pass -D to BL*_CPPFLAGS so that the macro can be used from all source files. Change-Id: I0ca1e4e26386bef7fed999af140ee7cce7c2f8ef Signed-off-by: Masahiro Yamada --- make_helpers/build_macros.mk | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk index 20a36fe08..1c3d14d05 100644 --- a/make_helpers/build_macros.mk +++ b/make_helpers/build_macros.mk @@ -273,12 +273,12 @@ define MAKE_C $(eval OBJ := $(1)/$(patsubst %.c,%.o,$(notdir $(2)))) $(eval DEP := $(patsubst %.o,%.d,$(OBJ))) -$(eval IMAGE := IMAGE_BL$(call uppercase,$(3))) +$(eval BL_CPPFLAGS := $(BL$(call uppercase,$(3))_CPPFLAGS) -DIMAGE_BL$(call uppercase,$(3))) $(eval BL_CFLAGS := $(BL$(call uppercase,$(3))_CFLAGS)) $(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | bl$(3)_dirs $$(ECHO) " CC $$<" - $$(Q)$$(CC) $$(LTO_CFLAGS) $$(TF_CFLAGS) $$(CFLAGS) $(BL_CFLAGS) -D$(IMAGE) $(MAKE_DEP) -c $$< -o $$@ + $$(Q)$$(CC) $$(LTO_CFLAGS) $$(TF_CFLAGS) $$(CFLAGS) $(BL_CPPFLAGS) $(BL_CFLAGS) $(MAKE_DEP) -c $$< -o $$@ -include $(DEP) @@ -293,11 +293,12 @@ define MAKE_S $(eval OBJ := $(1)/$(patsubst %.S,%.o,$(notdir $(2)))) $(eval DEP := $(patsubst %.o,%.d,$(OBJ))) -$(eval IMAGE := IMAGE_BL$(call uppercase,$(3))) +$(eval BL_CPPFLAGS := $(BL$(call uppercase,$(3))_CPPFLAGS) -DIMAGE_BL$(call uppercase,$(3))) +$(eval BL_ASFLAGS := $(BL$(call uppercase,$(3))_ASFLAGS)) $(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | bl$(3)_dirs $$(ECHO) " AS $$<" - $$(Q)$$(AS) $$(ASFLAGS) -D$(IMAGE) $(MAKE_DEP) -c $$< -o $$@ + $$(Q)$$(AS) $$(ASFLAGS) $(BL_CPPFLAGS) $(BL_ASFLAGS) $(MAKE_DEP) -c $$< -o $$@ -include $(DEP) @@ -311,11 +312,11 @@ endef define MAKE_LD $(eval DEP := $(1).d) -$(eval IMAGE := IMAGE_BL$(call uppercase,$(3))) +$(eval BL_CPPFLAGS := $(BL$(call uppercase,$(3))_CPPFLAGS) -DIMAGE_BL$(call uppercase,$(3))) $(1): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | bl$(3)_dirs $$(ECHO) " PP $$<" - $$(Q)$$(CPP) $$(CPPFLAGS) $(TF_CFLAGS_$(ARCH)) -P -x assembler-with-cpp -D__LINKER__ $(MAKE_DEP) -D$(IMAGE) -o $$@ $$< + $$(Q)$$(CPP) $$(CPPFLAGS) $(BL_CPPFLAGS) $(TF_CFLAGS_$(ARCH)) -P -x assembler-with-cpp -D__LINKER__ $(MAKE_DEP) -o $$@ $$< -include $(DEP) -- cgit v1.2.3 From 11a3c5ee7325f925baee9a53c865d0fc403dab06 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 25 Mar 2020 17:50:39 +0900 Subject: plat: pass -D option to BL*_CPPFLAGS instead of BL*_CFLAGS -D is a preprocessor flag that defines a macro. So, adding it to BL*_CPPFLAGS makes more sense. You can reference it not only from .c files but also from .S files. Change-Id: Ib4f2f27a3ed3eae476a6a32da7ab5225ad0649de Signed-off-by: Masahiro Yamada --- plat/arm/board/fvp/platform.mk | 14 +++++++------- plat/arm/board/juno/platform.mk | 8 ++++---- plat/arm/board/rdn1edge/platform.mk | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index e64c4d4cf..4441688cd 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -295,30 +295,30 @@ endif # Enable the dynamic translation tables library. ifeq (${ARCH},aarch32) ifeq (${RESET_TO_SP_MIN},1) - BL32_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 + BL32_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 endif else # AArch64 ifeq (${RESET_TO_BL31},1) - BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 + BL31_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 endif ifeq (${SPD},trusty) - BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 + BL31_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 endif endif ifeq (${ALLOW_RO_XLAT_TABLES}, 1) ifeq (${ARCH},aarch32) - BL32_CFLAGS += -DPLAT_RO_XLAT_TABLES=1 + BL32_CPPFLAGS += -DPLAT_RO_XLAT_TABLES=1 else # AArch64 - BL31_CFLAGS += -DPLAT_RO_XLAT_TABLES=1 + BL31_CPPFLAGS += -DPLAT_RO_XLAT_TABLES=1 ifeq (${SPD},tspd) - BL32_CFLAGS += -DPLAT_RO_XLAT_TABLES=1 + BL32_CPPFLAGS += -DPLAT_RO_XLAT_TABLES=1 endif endif endif ifeq (${USE_DEBUGFS},1) - BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 + BL31_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 endif # Add support for platform supplied linker script for BL31 build diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk index f07c1b163..dfdefa170 100644 --- a/plat/arm/board/juno/platform.mk +++ b/plat/arm/board/juno/platform.mk @@ -147,19 +147,19 @@ ENABLE_SVE_FOR_NS := 0 # Enable the dynamic translation tables library. ifeq (${ARCH},aarch32) ifeq (${RESET_TO_SP_MIN},1) - BL32_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 + BL32_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 endif else ifeq (${RESET_TO_BL31},1) - BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 + BL31_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 endif endif ifeq (${ALLOW_RO_XLAT_TABLES}, 1) ifeq (${JUNO_AARCH32_EL3_RUNTIME}, 1) - BL32_CFLAGS += -DPLAT_RO_XLAT_TABLES=1 + BL32_CPPFLAGS += -DPLAT_RO_XLAT_TABLES=1 else - BL31_CFLAGS += -DPLAT_RO_XLAT_TABLES=1 + BL31_CPPFLAGS += -DPLAT_RO_XLAT_TABLES=1 endif endif diff --git a/plat/arm/board/rdn1edge/platform.mk b/plat/arm/board/rdn1edge/platform.mk index 135676d43..571d6513e 100644 --- a/plat/arm/board/rdn1edge/platform.mk +++ b/plat/arm/board/rdn1edge/platform.mk @@ -36,7 +36,7 @@ BL2_SOURCES += ${RDN1EDGE_BASE}/rdn1edge_trusted_boot.c endif # Enable dynamic addition of MMAP regions in BL31 -BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 +BL31_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 # Add the FDT_SOURCES and options for Dynamic Config FDT_SOURCES += ${RDN1EDGE_BASE}/fdts/${PLAT}_fw_config.dts -- cgit v1.2.3 From 85ee795ca286a5a07a215902cc8d39a92c845637 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 25 Mar 2020 20:52:44 +0900 Subject: bl32: sp_min: reduce the alignment for fconf_populator sp_min.ld.S is used for aarch32. ALIGN(4) is used for alignment of the other structures. I do not think struct fconf_populator is a special case. Let's use ALIGN(4) here too. Perhaps, this is just a copy-paste mistake of commit 26d1e0c33098 ("fconf: necessary modifications to support fconf in BL31 & SP_MIN"). Change-Id: I29f4c68680842c1b5ef913934b4ccf378e9bfcfb Signed-off-by: Masahiro Yamada --- bl32/sp_min/sp_min.ld.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bl32/sp_min/sp_min.ld.S b/bl32/sp_min/sp_min.ld.S index a90a805a0..66f3b113d 100644 --- a/bl32/sp_min/sp_min.ld.S +++ b/bl32/sp_min/sp_min.ld.S @@ -56,7 +56,7 @@ SECTIONS KEEP(*(rt_svc_descs)) __RT_SVC_DESCS_END__ = .; - . = ALIGN(8); + . = ALIGN(4); __FCONF_POPULATOR_START__ = .; KEEP(*(.fconf_populator)) __FCONF_POPULATOR_END__ = .; @@ -98,7 +98,7 @@ SECTIONS KEEP(*(rt_svc_descs)) __RT_SVC_DESCS_END__ = .; - . = ALIGN(8); + . = ALIGN(4); __FCONF_POPULATOR_START__ = .; KEEP(*(.fconf_populator)) __FCONF_POPULATOR_END__ = .; -- cgit v1.2.3 From c452ba159c148de0760624896406bf0ab0604b95 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 31 Mar 2020 14:21:59 +0900 Subject: fconf: exclude fconf_dyn_cfg_getter.c from BL1_SOURCES fconf_dyn_cfg_getter.c calls FCONF_REGISTER_POPULATOR(), which populates the fconf_populator structure. However, bl1/bl1.ld.S does not have: __FCONF_POPULATOR_START__ = .; KEEP(*(.fconf_populator)) __FCONF_POPULATOR_END__ = .; So, this is not linked to bl1.elf We could change either bl1/bl1.lds.S or lib/fconf/fconf.mk to make them consistent. I chose to fix up fconf.mk to keep the current behavior. This is a groundwork to factor out the common code from linker scripts. Change-Id: I07b7ad4db4ec77b57acf1588fffd0b06306d7293 Signed-off-by: Masahiro Yamada --- lib/fconf/fconf.mk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/fconf/fconf.mk b/lib/fconf/fconf.mk index 703196949..c087102d7 100644 --- a/lib/fconf/fconf.mk +++ b/lib/fconf/fconf.mk @@ -5,8 +5,8 @@ # # Add Firmware Configuration files -FCONF_SOURCES := lib/fconf/fconf.c \ - lib/fconf/fconf_dyn_cfg_getter.c +FCONF_SOURCES := lib/fconf/fconf.c +FCONF_DYN_SOURCES := lib/fconf/fconf_dyn_cfg_getter.c BL1_SOURCES += ${FCONF_SOURCES} -BL2_SOURCES += ${FCONF_SOURCES} +BL2_SOURCES += ${FCONF_SOURCES} ${FCONF_DYN_SOURCES} -- cgit v1.2.3 From 32b209bfea25f6372894edc528d526070bb14e22 Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Tue, 25 Feb 2020 11:25:08 +0100 Subject: Makefile: don't use $(CC) before value is explicit set Unless specified in the environment, $(CC) expands to some generic host C compiler like cc or c99. We set our own value for $(CC), but only few lines later. Move the first use of the $(CC) variable behind the definition to correct this. Change-Id: I45344e063d21ddfe22b7ad77954e85c1c46087bd Fixes: 1684b8733 ("Use clang assembler when clang compiler is used") Signed-off-by: Ahmad Fatoum --- Makefile | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/Makefile b/Makefile index a1702beaa..2fb675949 100644 --- a/Makefile +++ b/Makefile @@ -84,26 +84,6 @@ endif export Q ECHO -# Process Debug flag -$(eval $(call add_define,DEBUG)) -ifneq (${DEBUG}, 0) - BUILD_TYPE := debug - TF_CFLAGS += -g - - ifneq ($(findstring clang,$(notdir $(CC))),) - ASFLAGS += -g - else - ASFLAGS += -g -Wa,--gdwarf-2 - endif - - # Use LOG_LEVEL_INFO by default for debug builds - LOG_LEVEL := 40 -else - BUILD_TYPE := release - # Use LOG_LEVEL_NOTICE by default for release builds - LOG_LEVEL := 20 -endif - # Default build string (git branch and commit) ifeq (${BUILD_STRING},) BUILD_STRING := $(shell git describe --always --dirty --tags 2> /dev/null) @@ -243,6 +223,26 @@ TF_CFLAGS_aarch64 = $(march64-directive) LD = $(LINKER) endif +# Process Debug flag +$(eval $(call add_define,DEBUG)) +ifneq (${DEBUG}, 0) + BUILD_TYPE := debug + TF_CFLAGS += -g + + ifneq ($(findstring clang,$(notdir $(CC))),) + ASFLAGS += -g + else + ASFLAGS += -g -Wa,--gdwarf-2 + endif + + # Use LOG_LEVEL_INFO by default for debug builds + LOG_LEVEL := 40 +else + BUILD_TYPE := release + # Use LOG_LEVEL_NOTICE by default for release builds + LOG_LEVEL := 20 +endif + ifeq (${AARCH32_INSTRUCTION_SET},A32) TF_CFLAGS_aarch32 += -marm else ifeq (${AARCH32_INSTRUCTION_SET},T32) -- cgit v1.2.3 From db059ea4d9741b54ad4a8305e3edc24d21c1d5ac Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Tue, 31 Mar 2020 20:38:01 +0200 Subject: doc: Fix broken external link for Odroid C2 The file README.odroid-c2 has been moved in the U-Boot repository. Reference the official uplink repository. Signed-off-by: Heinrich Schuchardt Change-Id: Ie72c7aefd6363a406f88ad2c87faee1c7a2125a3 --- docs/plat/meson-gxbb.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/plat/meson-gxbb.rst b/docs/plat/meson-gxbb.rst index 2cd8342cb..dbd83e0bc 100644 --- a/docs/plat/meson-gxbb.rst +++ b/docs/plat/meson-gxbb.rst @@ -23,4 +23,4 @@ This port has been tested in a ODROID-C2. After building it, follow the instructions in the `U-Boot repository`_, replacing the mentioned **bl31.bin** by the one built from this port. -.. _U-Boot repository: https://github.com/u-boot/u-boot/blob/master/board/amlogic/odroid-c2/README.odroid-c2 +.. _U-Boot repository: https://gitlab.denx.de/u-boot/u-boot/-/blob/master/board/amlogic/p200/README.odroid-c2 -- cgit v1.2.3 From fa65b0e45a5bdd11a78e64169963b25c4dabbf77 Mon Sep 17 00:00:00 2001 From: laurenw-arm Date: Tue, 31 Mar 2020 14:20:25 -0500 Subject: Update code freeze and release target date for 2.3 Signed-off-by: Lauren Wehrmeister Change-Id: Icf0a5737852e4f025dd8ce3748594ad25da43045 --- docs/about/release-information.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/about/release-information.rst b/docs/about/release-information.rst index c230e605d..fb1e39bdd 100644 --- a/docs/about/release-information.rst +++ b/docs/about/release-information.rst @@ -40,7 +40,7 @@ depending on project requirement and partner feedback. +-----------------+---------------------------+------------------------------+ | v2.2 | 4th week of Oct '19 | 1st week of Oct '19 | +-----------------+---------------------------+------------------------------+ -| v2.3 | 4th week of Mar '20 | 1st week of Mar '20 | +| v2.3 | 4th week of Apr '20 | 1st week of Apr '20 | +-----------------+---------------------------+------------------------------+ Removal of Deprecated Interfaces @@ -65,4 +65,4 @@ Release version after which it will be removed. -------------- -*Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.* +*Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.* -- cgit v1.2.3 From 5c38088881ffd10f9a2dc1cc2af7300295eb6f04 Mon Sep 17 00:00:00 2001 From: Scott Branden Date: Fri, 8 Jul 2016 12:09:23 -0700 Subject: drivers: Add support to retrieve plat_toc_flags Add support to retrieve plat_toc_flags value from FIP header flags. plat_toc_flags is for platform specific use. It is stored in FIP header by fiptool using --plat-toc-flags option. Change-Id: Ibadd91b4f28e6503f4426e4efd404bbe512ad124 Signed-off-by: Scott Branden Signed-off-by: Sheetal Tigadoli --- drivers/io/io_fip.c | 27 ++++++++++++++++++++++++++- include/drivers/io/io_fip.h | 3 ++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/drivers/io/io_fip.c b/drivers/io/io_fip.c index 5d49fffaa..02f85d603 100644 --- a/drivers/io/io_fip.c +++ b/drivers/io/io_fip.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -46,6 +46,7 @@ typedef struct { */ typedef struct { uintptr_t dev_spec; + uint16_t plat_toc_flag; } fip_dev_state_t; static const uuid_t uuid_null; @@ -220,6 +221,11 @@ static int fip_dev_init(io_dev_info_t *dev_info, const uintptr_t init_params) uintptr_t backend_handle; fip_toc_header_t header; size_t bytes_read; + fip_dev_state_t *state; + + assert(dev_info != NULL); + + state = (fip_dev_state_t *)dev_info->info; /* Obtain a reference to the image by querying the platform layer */ result = plat_get_image_source(image_id, &backend_dev_handle, @@ -248,6 +254,11 @@ static int fip_dev_init(io_dev_info_t *dev_info, const uintptr_t init_params) result = -ENOENT; } else { VERBOSE("FIP header looks OK.\n"); + /* + * Store 16-bit Platform ToC flags field which occupies + * bits [32-47] in fip header. + */ + state->plat_toc_flag = (header.flags >> 32) & 0xffff; } } @@ -453,3 +464,17 @@ int register_io_dev_fip(const io_dev_connector_t **dev_con) return result; } + +/* Function to retrieve plat_toc_flags, previously saved in FIP dev */ +int fip_dev_get_plat_toc_flag(io_dev_info_t *dev_info, uint16_t *plat_toc_flag) +{ + fip_dev_state_t *state; + + assert(dev_info != NULL); + + state = (fip_dev_state_t *)dev_info->info; + + *plat_toc_flag = state->plat_toc_flag; + + return 0; +} diff --git a/include/drivers/io/io_fip.h b/include/drivers/io/io_fip.h index e0b57463f..7e654361d 100644 --- a/include/drivers/io/io_fip.h +++ b/include/drivers/io/io_fip.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -10,5 +10,6 @@ struct io_dev_connector; int register_io_dev_fip(const struct io_dev_connector **dev_con); +int fip_dev_get_plat_toc_flag(io_dev_info_t *dev_info, uint16_t *plat_toc_flag); #endif /* IO_FIP_H */ -- cgit v1.2.3 From 42c33ba3bb4bb17de6e163a7f4acbd519e091715 Mon Sep 17 00:00:00 2001 From: Javier Almansa Sobrino Date: Mon, 10 Feb 2020 14:14:27 +0000 Subject: Add support to pass the nt_fw_config DTB to OP-TEE. At the moment, OP-TEE has no support to receive a DTB in Secure Memory so it cannot receive TOS_FW_CONFIG_ID as it is supposed to happen on any BL32 image. Instead, when OP-TEE is enable as BL32 payload, NT_FW_CONFIG_ID is passed. This MUST be reverted as soon as OP-TEE has support for receiving DTBs from Secure Memory. Change-Id: I9a873f42e94f2f99a60b638333e7afba1505aec9 Signed-off-by: Javier Almansa Sobrino --- common/desc_image_load.c | 69 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 49 insertions(+), 20 deletions(-) diff --git a/common/desc_image_load.c b/common/desc_image_load.c index 07692260e..47c80aa86 100644 --- a/common/desc_image_load.c +++ b/common/desc_image_load.c @@ -214,11 +214,12 @@ void populate_next_bl_params_config(bl_params_t *bl2_to_next_bl_params) { bl_params_node_t *params_node; unsigned int fw_config_id; - uintptr_t hw_config_base = 0, fw_config_base; -#if defined(SPD_spmd) +#ifdef SPD_spmd uint32_t fw_config_size = 0; #endif + uintptr_t fw_config_base; bl_mem_params_node_t *mem_params; + uintptr_t hw_config_base = 0; assert(bl2_to_next_bl_params != NULL); @@ -227,6 +228,7 @@ void populate_next_bl_params_config(bl_params_t *bl2_to_next_bl_params) * if available. */ mem_params = get_bl_mem_params_node(HW_CONFIG_ID); + if (mem_params != NULL) hw_config_base = mem_params->image_info.image_base; @@ -240,8 +242,16 @@ void populate_next_bl_params_config(bl_params_t *bl2_to_next_bl_params) fw_config_id = SOC_FW_CONFIG_ID; break; case BL32_IMAGE_ID: + /* + * At the moment, OPTEE cannot accept a DTB in secure memory, + * so fall back and use NT_FW_CONFIG instead. + * This MUST be fixed as soon as OPTEE has support to + * receive DTBs in secure memory. + */ +#ifndef SPD_opteed fw_config_id = TOS_FW_CONFIG_ID; break; +#endif case BL33_IMAGE_ID: fw_config_id = NT_FW_CONFIG_ID; break; @@ -254,38 +264,57 @@ void populate_next_bl_params_config(bl_params_t *bl2_to_next_bl_params) mem_params = get_bl_mem_params_node(fw_config_id); if (mem_params != NULL) { fw_config_base = mem_params->image_info.image_base; -#if defined(SPD_spmd) +#ifdef SPD_spmd fw_config_size = mem_params->image_info.image_size; #endif } } + +#ifdef SPD_opteed /* - * Pass hw and tb_fw config addresses to next images. NOTE - for - * EL3 runtime images (BL31 for AArch64 and BL32 for AArch32), - * arg0 is already used by generic code. Take care of not - * overwriting the previous initialisations. + * If SPD_opteed is enabled, arg[0,2] are populated by + * parse_optee_header(), which is called by + * arm_bl2_handle_post_image_load(). The meaning of the + * arguments are: + * arg0 <-- MODE_RW + * arg1 <-- Paged image base + * arg2 <-- Paged image size */ - if (params_node == bl2_to_next_bl_params->head) { - if (params_node->ep_info->args.arg1 == 0U) - params_node->ep_info->args.arg1 = + if (params_node->image_id == BL32_IMAGE_ID) { + params_node->ep_info->args.arg3 = fw_config_base; + } else { +#endif + /* + * Pass hw and tb_fw config addresses to next images. + * NOTE - for EL3 runtime images (BL31 for AArch64 + * and BL32 for AArch32), arg0 is already used by + * generic code. Take care of not overwriting the + * previous initialisations. + */ + if (params_node == bl2_to_next_bl_params->head) { + if (params_node->ep_info->args.arg1 == 0U) + params_node->ep_info->args.arg1 = fw_config_base; - if (params_node->ep_info->args.arg2 == 0U) - params_node->ep_info->args.arg2 = + if (params_node->ep_info->args.arg2 == 0U) + params_node->ep_info->args.arg2 = hw_config_base; - } else { - if (params_node->ep_info->args.arg0 == 0U) - params_node->ep_info->args.arg0 = + } else { + if (params_node->ep_info->args.arg0 == 0U) + params_node->ep_info->args.arg0 = fw_config_base; - if (params_node->ep_info->args.arg1 == 0U) - params_node->ep_info->args.arg1 = + if (params_node->ep_info->args.arg1 == 0U) + params_node->ep_info->args.arg1 = hw_config_base; -#if defined(SPD_spmd) - if (params_node->ep_info->args.arg2 == 0U) - params_node->ep_info->args.arg2 = +#ifdef SPD_spmd + if (params_node->ep_info->args.arg2 == 0U) + params_node->ep_info->args.arg2 = fw_config_size; #endif + } +#ifdef SPD_opteed } +#endif } } -- cgit v1.2.3 From 7ff088d1f0d17e6afed236f979ffc5adf005d8b0 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Sun, 22 Mar 2020 05:06:38 +0000 Subject: Enable MTE support Enable MTE support by adding memory tag option in Makefile This option is available only when ARMv8.5-MemTag is implemented MTE options are added in latest clang and armclang compiler which support below options: for clang 1. -march=arm8.5-a+memtag 2. -fsanitize=memtag for armclang 1. -march=arm8.5-a+memtag 2. -mmemtag-stack Set the option SUPPORT_STACK_MEMTAG=yes to enable memory stack tagging. Signed-off-by: Manish V Badarkhe Change-Id: I4e0bbde4e9769ce03ead6f550158e22f32c1c413 --- Makefile | 28 ++++++++++++++++++++++++++++ docs/getting_started/build-options.rst | 5 +++++ make_helpers/defaults.mk | 5 +++++ 3 files changed, 38 insertions(+) diff --git a/Makefile b/Makefile index ac461a50a..e455635b6 100644 --- a/Makefile +++ b/Makefile @@ -187,6 +187,34 @@ march64-directive = -march=armv8.${ARM_ARCH_MINOR}-a endif endif +# Memory tagging is supported in architecture Armv8.5-A AArch64 and onwards +ifeq ($(ARCH), aarch64) +ifeq ($(shell test $(ARM_ARCH_MAJOR) -gt 8; echo $$?),0) +mem_tag_arch_support = yes +else ifeq ($(shell test $(ARM_ARCH_MAJOR) -eq 8 -a $(ARM_ARCH_MINOR) -ge 5; \ + echo $$?),0) +mem_tag_arch_support = yes +endif +endif + +# Enabled required option for memory stack tagging. Currently, these options are +# enabled only for clang and armclang compiler. +ifeq (${SUPPORT_STACK_MEMTAG},yes) +ifdef mem_tag_arch_support +ifneq ( ,$(filter $(notdir $(CC)),armclang clang)) +march64-directive = -march=armv${ARM_ARCH_MAJOR}.${ARM_ARCH_MINOR}-a+memtag +ifeq ($(notdir $(CC)),armclang) +TF_CFLAGS += -mmemtag-stack +else ifeq ($(notdir $(CC)),clang) +TF_CFLAGS += -fsanitize=memtag +endif +endif +else +$(error "Error: stack memory tagging is not supported for architecture \ + ${ARCH},armv${ARM_ARCH_MAJOR}.${ARM_ARCH_MINOR}-a") +endif +endif + ifneq ($(findstring armclang,$(notdir $(CC))),) TF_CFLAGS_aarch32 = -target arm-arm-none-eabi $(march32-directive) TF_CFLAGS_aarch64 = -target aarch64-arm-none-eabi $(march64-directive) diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 69e103d38..e1c6c8f80 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -667,6 +667,11 @@ Common build options cluster platforms). If this option is enabled, then warm boot path enables D-caches immediately after enabling MMU. This option defaults to 0. +- ``SUPPORT_STACK_MEMTAG``: This flag determines whether to enable memory + tagging for stack or not. It accepts 2 values: ``yes`` and ``no``. The + default value of this flag is ``no``. Note this option must be enabled only + for ARM architecture greater than Armv8.5-A. + GICv3 driver options -------------------- diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index 4e968e2d3..590a800a6 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -288,3 +288,8 @@ ENABLE_LTO := 0 # S-EL2 firmware entry/exit. This flag is to be used with SPD=spmd option. # Default is 0. CTX_INCLUDE_EL2_REGS := 0 + +# Enable Memory tag extension which is supported for architecture greater +# than Armv8.5-A +# By default it is set to "no" +SUPPORT_STACK_MEMTAG := no -- cgit v1.2.3 From 75077e26a9a3bb4d3150e483f4486101d4dc34de Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Fri, 27 Mar 2020 11:02:05 +0000 Subject: doc: Update fconf uml diagrams Update the plantuml diagrams to match the latest modification in fconf. Signed-off-by: Louis Mayencourt Change-Id: I90f55bba0fd039a3f7e1bd39661cf849fccd64f5 --- docs/resources/diagrams/plantuml/fconf_bl1_load_config.puml | 6 +++--- docs/resources/diagrams/plantuml/fconf_bl2_populate.puml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/resources/diagrams/plantuml/fconf_bl1_load_config.puml b/docs/resources/diagrams/plantuml/fconf_bl1_load_config.puml index c36e54423..e613eefd0 100644 --- a/docs/resources/diagrams/plantuml/fconf_bl1_load_config.puml +++ b/docs/resources/diagrams/plantuml/fconf_bl1_load_config.puml @@ -24,9 +24,9 @@ arm_bl1_setup -> fconf : fconf_load_config() activate fconf note over fconf create and populate an - image_desc_t for TB_FW_CONFIG + image_desc_t for FW_CONFIG end note - fconf -> bl_common : load_auth_image(TB_FW_CONFIG_ID, &image_info) + fconf -> bl_common : load_auth_image(FW_CONFIG_ID, &image_info) activate bl_common note over bl_common load and auth image from fip @@ -42,7 +42,7 @@ activate fconf fconf <- plat_bl1_common : BL2_IMAGE_DESC note over fconf set ep_info.args.arg0 of BL2_IMAGE_DESC - to TB_FW_CONFIG base address + to FW_CONFIG base address end note arm_bl1_setup <- fconf deactivate fconf diff --git a/docs/resources/diagrams/plantuml/fconf_bl2_populate.puml b/docs/resources/diagrams/plantuml/fconf_bl2_populate.puml index 98a3ff19b..881f25343 100644 --- a/docs/resources/diagrams/plantuml/fconf_bl2_populate.puml +++ b/docs/resources/diagrams/plantuml/fconf_bl2_populate.puml @@ -20,12 +20,12 @@ end box bl2_entrypoint -> bl2_main : bl2_setup() bl2_main -> arm_bl2_setup : bl2_early_platform_setup2(\n\t arg0, arg1, arg2, arg3) note over arm_bl2_setup - arg0 = tb_fw_config + arg0 = fw_config arg1 = mem_layout end note -arm_bl2_setup -> arm_bl2_setup : arm_bl2_early_platform_setup(\n\t tb_fw_config, mem_layout) +arm_bl2_setup -> arm_bl2_setup : arm_bl2_early_platform_setup(\n\t fw_config, mem_layout) activate arm_bl2_setup - arm_bl2_setup -> fconf: fconf_polulate(tb_fw_config) + arm_bl2_setup -> fconf: fconf_polulate("TB_FW", fw_config) activate fconf fconf -> fconf_tbbr_getter: fconf_populate_tbbr_dyn_config(uintptr_t dtb) note over fconf_tbbr_getter: read tbbr propeties from dtb -- cgit v1.2.3 From a5bb389a8292a6d8e14c1b38ef83414165fbbcf1 Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Fri, 27 Mar 2020 11:49:20 +0000 Subject: doc: Fix "unexpected indentation" warning. Signed-off-by: Louis Mayencourt Change-Id: I521eed6466fdfef18a92f5237912cb402441044a --- docs/change-log.rst | 4 +++- docs/components/fconf.rst | 3 +++ docs/components/index.rst | 1 + docs/components/spci-manifest-binding.rst | 14 ++++++++++++++ 4 files changed, 21 insertions(+), 1 deletion(-) diff --git a/docs/change-log.rst b/docs/change-log.rst index cf5b57ac6..7e072a930 100644 --- a/docs/change-log.rst +++ b/docs/change-log.rst @@ -17,6 +17,7 @@ New Features - 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. @@ -84,6 +85,7 @@ New Features - 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. @@ -2841,7 +2843,7 @@ releases of TF-A. -------------- -*Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.* +*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 diff --git a/docs/components/fconf.rst b/docs/components/fconf.rst index 385660083..7352ac37a 100644 --- a/docs/components/fconf.rst +++ b/docs/components/fconf.rst @@ -107,6 +107,7 @@ As mentioned above, properties are logically grouped around namespaces and sub-namespaces. The following concepts should be considered when adding new properties/namespaces. The framework differentiates two types of properties: + - Properties used inside common code. - Properties used inside platform specific code. @@ -114,6 +115,7 @@ The first category applies to properties being part of the firmware and shared across multiple platforms. They should be globally accessible and defined inside the ``lib/fconf`` directory. The namespace must be chosen to reflect the feature/data abstracted. + Example: - |TBBR| related properties: tbbr.cot.bl2_id - Dynamic configuration information: dyn_cfg.dtb_info.hw_config_id @@ -123,6 +125,7 @@ within the framework: Platform specific properties. They must be accessed only within the platform API and are defined only inside the platform scope. The namespace must contain the platform name under which the properties defined belong. + Example: - Arm io framework: arm.io_policies.bl31_id diff --git a/docs/components/index.rst b/docs/components/index.rst index ae78b2bd1..49986ca00 100644 --- a/docs/components/index.rst +++ b/docs/components/index.rst @@ -17,4 +17,5 @@ Components romlib-design sdei secure-partition-manager-design + spci-manifest-binding xlat-tables-lib-v2-design diff --git a/docs/components/spci-manifest-binding.rst b/docs/components/spci-manifest-binding.rst index 66cca643b..584816911 100644 --- a/docs/components/spci-manifest-binding.rst +++ b/docs/components/spci-manifest-binding.rst @@ -16,6 +16,7 @@ spci-manifest-partition minor versions fo the device tree binding for the SPCI manifest represented by this node. The minor number is incremented if the binding changes in a backwards compatible manner. + - X is an integer representing the major version number of this document. - Y is an integer representing the minor version number of this document. @@ -23,6 +24,7 @@ spci-manifest-partition - value type: - Must be two 16 bits values (X, Y), concatenated as 31:16 -> X, 15:0 -> Y, where: + - X is the major version of PSA-FF-A expected by the partition at the SPCI instance it will execute. - Y is the minor version of PSA-FF-A expected by the partition at the SPCI @@ -34,10 +36,12 @@ spci-manifest-partition implemented by this partition. The UUID format is described in RFC 4122. UUID can be shared by multiple instances of partitions that offer the same service For example: + - If there are multiple instances of a Trusted OS, then the UUID can be shared by all instances. - The TEE driver in the HLOS can use the UUID with the SPCI_PARTITION_INFO_GET interface to determine the: + - Number of Trusted OSs - The partition ID of each instance of the Trusted OS @@ -56,6 +60,7 @@ spci-manifest-partition - execution-ctx-count [mandatory] - value type: - Number of vCPUs that a VM or SP wants to instantiate. + - In the absence of virtualization, this is the number of execution contexts that a partition implements. - If value of this field = 1 and number of PEs > 1 then the partition is @@ -66,6 +71,7 @@ spci-manifest-partition - exception-level [mandatory] - value type: - The target exception level for the partition: + - 0x0: EL1 - 0x1: S_EL0 - 0x2: S_EL1 @@ -76,6 +82,7 @@ spci-manifest-partition - execution-state [mandatory] - value type: - The target execution state of the partition: + - 0: AArch64 - 1: AArch32 @@ -94,6 +101,7 @@ spci-manifest-partition - xlat-granule [mandatory] - value type: - Translation granule used with the partition: + - 0x0: 4k - 0x1: 16k - 0x2: 32k @@ -113,6 +121,7 @@ spci-manifest-partition - messaging-method [mandatory] - value type: - Specifies which messaging methods are supported by the partition: + - 0x0: direct messaging method - 0x1: indirect messaging method - 0x2: both direct and indirect messaging methods @@ -125,6 +134,7 @@ spci-manifest-partition - run-time-model - value type: - Run time model that the SPM must enforce for this SP: + - 0x0: Run to completion - 0x1: Preemptible @@ -195,6 +205,7 @@ device-regions - reg [mandatory] - value type: - A (address, num-pages) pair describing the device, where: + - address: The physical base address value of the device MMIO region. - num-pages: The number of pages of the region. The total size of @@ -214,15 +225,18 @@ device-regions - stream-ids [mandatory] - value type: - A list of (id, mem-manage) pair, where: + - id: A unique value amongst all devices assigned to the partition. - mem-manage: A value used in memory management operations. - interrupts [mandatory] - value type: - A list of (id, attributes) pair describing the device interrupts, where: + - id: The interrupt IDs. - attributes: A ?? TO DEFINE value, containing the attributes for each interrupt ID: + - Interrupt type: SPI, PPI, SGI - Interrupt configuration: Edge triggered, Level triggered - Interrupt security state: Secure, Non-secure -- cgit v1.2.3 From 2765ffdc99af8b5fc171771b5f0e04e96a74a52f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 26 Mar 2020 13:18:48 +0900 Subject: uniphier: use enable_mmu() in common function Currently, enable_mmu_el1() or enable_mmu_el3() is kept outside the common function because the appropriate one must be chosen. Use enable_mmu() and move it to the common function. Change-Id: If2fb651691a7b6be05674f5cf730ae067ba95d4b Signed-off-by: Masahiro Yamada --- plat/socionext/uniphier/tsp/uniphier_tsp_setup.c | 2 -- plat/socionext/uniphier/uniphier_bl2_setup.c | 1 - plat/socionext/uniphier/uniphier_bl31_setup.c | 2 -- plat/socionext/uniphier/uniphier_xlat_setup.c | 2 ++ 4 files changed, 2 insertions(+), 5 deletions(-) diff --git a/plat/socionext/uniphier/tsp/uniphier_tsp_setup.c b/plat/socionext/uniphier/tsp/uniphier_tsp_setup.c index 091a6f7a9..4bbb2595c 100644 --- a/plat/socionext/uniphier/tsp/uniphier_tsp_setup.c +++ b/plat/socionext/uniphier/tsp/uniphier_tsp_setup.c @@ -9,7 +9,6 @@ #include #include -#include #include #include "../uniphier.h" @@ -32,5 +31,4 @@ void tsp_platform_setup(void) void tsp_plat_arch_setup(void) { uniphier_mmap_setup(uniphier_soc); - enable_mmu_el1(0); } diff --git a/plat/socionext/uniphier/uniphier_bl2_setup.c b/plat/socionext/uniphier/uniphier_bl2_setup.c index 7a7f78681..679f14d0a 100644 --- a/plat/socionext/uniphier/uniphier_bl2_setup.c +++ b/plat/socionext/uniphier/uniphier_bl2_setup.c @@ -44,7 +44,6 @@ void bl2_el3_plat_arch_setup(void) int ret; uniphier_mmap_setup(uniphier_soc); - enable_mmu_el3(0); /* add relocation offset (run-time-address - link-address) */ uniphier_mem_base += BL_CODE_BASE - BL2_BASE; diff --git a/plat/socionext/uniphier/uniphier_bl31_setup.c b/plat/socionext/uniphier/uniphier_bl31_setup.c index f2f0b298a..c2baebde9 100644 --- a/plat/socionext/uniphier/uniphier_bl31_setup.c +++ b/plat/socionext/uniphier/uniphier_bl31_setup.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include "uniphier.h" @@ -87,5 +86,4 @@ void bl31_platform_setup(void) void bl31_plat_arch_setup(void) { uniphier_mmap_setup(uniphier_soc); - enable_mmu_el3(0); } diff --git a/plat/socionext/uniphier/uniphier_xlat_setup.c b/plat/socionext/uniphier/uniphier_xlat_setup.c index 66c7834f5..c2ac7a29a 100644 --- a/plat/socionext/uniphier/uniphier_xlat_setup.c +++ b/plat/socionext/uniphier/uniphier_xlat_setup.c @@ -63,4 +63,6 @@ void uniphier_mmap_setup(unsigned int soc) MT_DEVICE | MT_RW | MT_SECURE); init_xlat_tables(); + + enable_mmu(0); } -- cgit v1.2.3 From 664e15c2bde25645ebf4f80fff7bedebeec0e876 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 26 Mar 2020 13:18:48 +0900 Subject: uniphier: support read-only xlat tables BL2 for this platform uses mmap_add_dynamic_region(), but BL31 and BL32 (TSP) only use static mapping. So, BL31 and BL32 can make the tables read-only after enabling MMU. Enable ALLOW_RO_XLAT_TABLES by default. Change-Id: Ib59c44697163629119888bb6abd47fa144f09ba3 Signed-off-by: Masahiro Yamada --- plat/socionext/uniphier/platform.mk | 7 +++++++ plat/socionext/uniphier/uniphier_xlat_setup.c | 13 +++++++++++++ 2 files changed, 20 insertions(+) diff --git a/plat/socionext/uniphier/platform.mk b/plat/socionext/uniphier/platform.mk index 0fcef1d2c..3f8a1f864 100644 --- a/plat/socionext/uniphier/platform.mk +++ b/plat/socionext/uniphier/platform.mk @@ -14,6 +14,13 @@ override ENABLE_SVE_FOR_NS := 0 # UNIPHIER_MEM_BASE so that all TF images are loaded at their link addresses. override ENABLE_PIE := 1 +ALLOW_RO_XLAT_TABLES := 1 + +ifeq ($(ALLOW_RO_XLAT_TABLES),1) +BL31_CFLAGS += -DPLAT_RO_XLAT_TABLES=1 +BL32_CFLAGS += -DPLAT_RO_XLAT_TABLES=1 +endif + # Cortex-A53 revision r0p4-51rel0 # needed for LD20, unneeded for LD11, PXs3 (no ACE) ERRATA_A53_855873 := 1 diff --git a/plat/socionext/uniphier/uniphier_xlat_setup.c b/plat/socionext/uniphier/uniphier_xlat_setup.c index c2ac7a29a..5043f4b59 100644 --- a/plat/socionext/uniphier/uniphier_xlat_setup.c +++ b/plat/socionext/uniphier/uniphier_xlat_setup.c @@ -10,6 +10,7 @@ #include #include +#include #include "uniphier.h" @@ -65,4 +66,16 @@ void uniphier_mmap_setup(unsigned int soc) init_xlat_tables(); enable_mmu(0); + +#if PLAT_RO_XLAT_TABLES + { + int ret; + + ret = xlat_make_tables_readonly(); + if (ret) { + ERROR("Failed to make translation tables read-only."); + plat_error_handler(ret); + } + } +#endif } -- cgit v1.2.3 From 07aa0c7e0e13db4b22de135247b4aa3a5b18f15b Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 12 Mar 2020 14:20:04 +0000 Subject: rpi: move plat_helpers.S to common The plat_helpers.S file was almost identical between its RPi3 and RPi4 versions. Unify the two files, moving it into the common/ directory. This adds a plat_rpi_get_model() function, which can be used to trigger RPi4 specific action, detected at runtime. We use that to do the RPi4 specific L2 cache initialisation. Change-Id: I2295704fd6dde7c76fe83b6d98c7bf998d4bf074 Signed-off-by: Andre Przywara --- plat/rpi/common/aarch64/plat_helpers.S | 214 +++++++++++++++++++++++++++++++++ plat/rpi/common/include/rpi_shared.h | 2 + plat/rpi/rpi3/aarch64/plat_helpers.S | 163 ------------------------- plat/rpi/rpi3/include/platform_def.h | 2 +- plat/rpi/rpi3/platform.mk | 4 +- plat/rpi/rpi4/aarch64/plat_helpers.S | 185 ---------------------------- plat/rpi/rpi4/include/platform_def.h | 2 +- plat/rpi/rpi4/platform.mk | 2 +- 8 files changed, 220 insertions(+), 354 deletions(-) create mode 100644 plat/rpi/common/aarch64/plat_helpers.S delete mode 100644 plat/rpi/rpi3/aarch64/plat_helpers.S delete mode 100644 plat/rpi/rpi4/aarch64/plat_helpers.S diff --git a/plat/rpi/common/aarch64/plat_helpers.S b/plat/rpi/common/aarch64/plat_helpers.S new file mode 100644 index 000000000..93c8f7f7f --- /dev/null +++ b/plat/rpi/common/aarch64/plat_helpers.S @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include + + .globl plat_crash_console_flush + .globl plat_crash_console_init + .globl plat_crash_console_putc + .globl platform_mem_init + .globl plat_get_my_entrypoint + .globl plat_is_my_cpu_primary + .globl plat_my_core_pos + .globl plat_reset_handler + .globl plat_rpi3_calc_core_pos + .globl plat_secondary_cold_boot_setup + .globl plat_rpi_get_model + + /* ----------------------------------------------------- + * unsigned int plat_my_core_pos(void) + * + * This function uses the plat_rpi3_calc_core_pos() + * definition to get the index of the calling CPU. + * ----------------------------------------------------- + */ +func plat_my_core_pos + mrs x0, mpidr_el1 + b plat_rpi3_calc_core_pos +endfunc plat_my_core_pos + + /* ----------------------------------------------------- + * unsigned int plat_rpi3_calc_core_pos(u_register_t mpidr); + * + * CorePos = (ClusterId * 4) + CoreId + * ----------------------------------------------------- + */ +func plat_rpi3_calc_core_pos + and x1, x0, #MPIDR_CPU_MASK + and x0, x0, #MPIDR_CLUSTER_MASK + add x0, x1, x0, LSR #6 + ret +endfunc plat_rpi3_calc_core_pos + + /* ----------------------------------------------------- + * 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, #RPI_PRIMARY_CPU + cset w0, eq + ret +endfunc plat_is_my_cpu_primary + + /* ----------------------------------------------------- + * 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 + /* Calculate address of our hold entry */ + bl plat_my_core_pos + lsl x0, x0, #3 + mov_imm x2, PLAT_RPI3_TM_HOLD_BASE + add x0, x0, x2 + + /* + * This code runs way before requesting the warmboot of this core, + * so it is possible to clear the mailbox before getting a request + * to boot. + */ + mov x1, PLAT_RPI3_TM_HOLD_STATE_WAIT + str x1,[x0] + + /* Wait until we have a go */ +poll_mailbox: + wfe + ldr x1, [x0] + cmp x1, PLAT_RPI3_TM_HOLD_STATE_GO + bne poll_mailbox + + /* Jump to the provided entrypoint */ + mov_imm x0, PLAT_RPI3_TM_ENTRYPOINT + ldr x1, [x0] + br x1 +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 a warm + * boot. + * + * This functions returns: + * - 0 for a cold boot. + * - Any other value for a warm boot. + * --------------------------------------------------------------------- + */ +func plat_get_my_entrypoint + /* TODO: support warm boot */ + mov x0, #0 + ret +endfunc plat_get_my_entrypoint + + /* --------------------------------------------- + * void platform_mem_init (void); + * + * No need to carry out any memory initialization. + * --------------------------------------------- + */ +func platform_mem_init + ret +endfunc platform_mem_init + + /* --------------------------------------------- + * int plat_crash_console_init(void) + * Function to initialize the crash console + * without a C Runtime to print crash report. + * Clobber list : x0 - x3 + * --------------------------------------------- + */ +func plat_crash_console_init + mov_imm x0, PLAT_RPI_MINI_UART_BASE + mov x1, xzr + mov x2, xzr + b console_16550_core_init +endfunc plat_crash_console_init + + /* --------------------------------------------- + * int plat_crash_console_putc(int c) + * Function to print a character on the crash + * console without a C Runtime. + * Clobber list : x1, x2 + * --------------------------------------------- + */ +func plat_crash_console_putc + mov_imm x1, PLAT_RPI_MINI_UART_BASE + b console_16550_core_putc +endfunc plat_crash_console_putc + + /* --------------------------------------------- + * int plat_crash_console_flush() + * Function to force a write of all buffered + * data that hasn't been output. + * Out : return -1 on error else return 0. + * Clobber list : x0, x1 + * --------------------------------------------- + */ +func plat_crash_console_flush + mov_imm x0, PLAT_RPI_MINI_UART_BASE + b console_16550_core_flush +endfunc plat_crash_console_flush + + /* --------------------------------------------- + * int plat_rpi_get_model() + * Macro to determine whether we are running on + * a Raspberry Pi 3 or 4. Just checks the MIDR for + * being either a Cortex-A72 or a Cortex-A53. + * Out : return 4 if RPi4, 3 otherwise. + * Clobber list : x0 + * --------------------------------------------- + */ + .macro _plat_rpi_get_model + mrs x0, midr_el1 + and x0, x0, #0xf0 /* Isolate low byte of part number */ + cmp w0, #0x80 /* Cortex-A72 (RPi4) is 0xd08, A53 is 0xd03 */ + mov w0, #3 + csinc w0, w0, w0, ne + .endm + + func plat_rpi_get_model + _plat_rpi_get_model + ret + endfunc plat_rpi_get_model + + /* --------------------------------------------- + * void plat_reset_handler(void); + * --------------------------------------------- + */ +func plat_reset_handler + /* L2 cache setup only needed on RPi4 */ + _plat_rpi_get_model + cmp w0, #4 + b.ne 1f + + /* ------------------------------------------------ + * Set L2 read/write cache latency: + * - L2 Data RAM latency: 3 cycles (0b010) + * - L2 Data RAM setup: 1 cycle (bit 5) + * ------------------------------------------------ + */ + mrs x0, CORTEX_A72_L2CTLR_EL1 + mov x1, #0x22 + orr x0, x0, x1 + msr CORTEX_A72_L2CTLR_EL1, x0 + isb + +1: + ret +endfunc plat_reset_handler diff --git a/plat/rpi/common/include/rpi_shared.h b/plat/rpi/common/include/rpi_shared.h index 686343892..ddf239eb5 100644 --- a/plat/rpi/common/include/rpi_shared.h +++ b/plat/rpi/common/include/rpi_shared.h @@ -36,4 +36,6 @@ void plat_rpi3_io_setup(void); /* VideoCore firmware commands */ int rpi3_vc_hardware_get_board_revision(uint32_t *revision); +int plat_rpi_get_model(void); + #endif /* RPI3_PRIVATE_H */ diff --git a/plat/rpi/rpi3/aarch64/plat_helpers.S b/plat/rpi/rpi3/aarch64/plat_helpers.S deleted file mode 100644 index ab925b6c0..000000000 --- a/plat/rpi/rpi3/aarch64/plat_helpers.S +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include -#include - - .globl plat_crash_console_flush - .globl plat_crash_console_init - .globl plat_crash_console_putc - .globl platform_mem_init - .globl plat_get_my_entrypoint - .globl plat_is_my_cpu_primary - .globl plat_my_core_pos - .globl plat_rpi3_calc_core_pos - .globl plat_secondary_cold_boot_setup - - /* ----------------------------------------------------- - * unsigned int plat_my_core_pos(void) - * - * This function uses the plat_rpi3_calc_core_pos() - * definition to get the index of the calling CPU. - * ----------------------------------------------------- - */ -func plat_my_core_pos - mrs x0, mpidr_el1 - b plat_rpi3_calc_core_pos -endfunc plat_my_core_pos - - /* ----------------------------------------------------- - * unsigned int plat_rpi3_calc_core_pos(u_register_t mpidr); - * - * CorePos = (ClusterId * 4) + CoreId - * ----------------------------------------------------- - */ -func plat_rpi3_calc_core_pos - and x1, x0, #MPIDR_CPU_MASK - and x0, x0, #MPIDR_CLUSTER_MASK - add x0, x1, x0, LSR #6 - ret -endfunc plat_rpi3_calc_core_pos - - /* ----------------------------------------------------- - * 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, #RPI3_PRIMARY_CPU - cset w0, eq - ret -endfunc plat_is_my_cpu_primary - - /* ----------------------------------------------------- - * 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 - /* Calculate address of our hold entry */ - bl plat_my_core_pos - lsl x0, x0, #3 - mov_imm x2, PLAT_RPI3_TM_HOLD_BASE - add x0, x0, x2 - - /* - * This code runs way before requesting the warmboot of this core, - * so it is possible to clear the mailbox before getting a request - * to boot. - */ - mov x1, PLAT_RPI3_TM_HOLD_STATE_WAIT - str x1,[x0] - - /* Wait until we have a go */ -poll_mailbox: - wfe - ldr x1, [x0] - cmp x1, PLAT_RPI3_TM_HOLD_STATE_GO - bne poll_mailbox - - /* Jump to the provided entrypoint */ - mov_imm x0, PLAT_RPI3_TM_ENTRYPOINT - ldr x1, [x0] - br x1 -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 a warm - * boot. - * - * This functions returns: - * - 0 for a cold boot. - * - Any other value for a warm boot. - * --------------------------------------------------------------------- - */ -func plat_get_my_entrypoint - /* TODO: support warm boot */ - mov x0, #0 - ret -endfunc plat_get_my_entrypoint - - /* --------------------------------------------- - * void platform_mem_init (void); - * - * No need to carry out any memory initialization. - * --------------------------------------------- - */ -func platform_mem_init - ret -endfunc platform_mem_init - - /* --------------------------------------------- - * int plat_crash_console_init(void) - * Function to initialize the crash console - * without a C Runtime to print crash report. - * Clobber list : x0 - x3 - * --------------------------------------------- - */ -func plat_crash_console_init - mov_imm x0, PLAT_RPI_MINI_UART_BASE - mov x1, xzr - mov x2, xzr - b console_16550_core_init -endfunc plat_crash_console_init - - /* --------------------------------------------- - * int plat_crash_console_putc(int c) - * Function to print a character on the crash - * console without a C Runtime. - * Clobber list : x1, x2 - * --------------------------------------------- - */ -func plat_crash_console_putc - mov_imm x1, PLAT_RPI_MINI_UART_BASE - b console_16550_core_putc -endfunc plat_crash_console_putc - - /* --------------------------------------------- - * int plat_crash_console_flush() - * Function to force a write of all buffered - * data that hasn't been output. - * Out : return -1 on error else return 0. - * Clobber list : x0, x1 - * --------------------------------------------- - */ -func plat_crash_console_flush - mov_imm x0, PLAT_RPI_MINI_UART_BASE - b console_16550_core_flush -endfunc plat_crash_console_flush diff --git a/plat/rpi/rpi3/include/platform_def.h b/plat/rpi/rpi3/include/platform_def.h index 9cacd9915..2bcf53ee9 100644 --- a/plat/rpi/rpi3/include/platform_def.h +++ b/plat/rpi/rpi3/include/platform_def.h @@ -24,7 +24,7 @@ #define PLATFORM_CLUSTER0_CORE_COUNT PLATFORM_MAX_CPUS_PER_CLUSTER #define PLATFORM_CORE_COUNT PLATFORM_CLUSTER0_CORE_COUNT -#define RPI3_PRIMARY_CPU U(0) +#define RPI_PRIMARY_CPU U(0) #define PLAT_MAX_PWR_LVL MPIDR_AFFLVL1 #define PLAT_NUM_PWR_DOMAINS (PLATFORM_CLUSTER_COUNT + \ diff --git a/plat/rpi/rpi3/platform.mk b/plat/rpi/rpi3/platform.mk index a5b8904d5..bcfc34e20 100644 --- a/plat/rpi/rpi3/platform.mk +++ b/plat/rpi/rpi3/platform.mk @@ -15,6 +15,7 @@ PLAT_BL_COMMON_SOURCES := drivers/ti/uart/aarch64/16550_console.S \ drivers/gpio/gpio.c \ drivers/delay_timer/delay_timer.c \ drivers/rpi3/gpio/rpi3_gpio.c \ + plat/rpi/common/aarch64/plat_helpers.S \ plat/rpi/common/rpi3_common.c \ ${XLAT_TABLES_LIB_SRCS} @@ -23,7 +24,6 @@ BL1_SOURCES += drivers/io/io_fip.c \ drivers/io/io_storage.c \ lib/cpus/aarch64/cortex_a53.S \ plat/common/aarch64/platform_mp_stack.S \ - plat/rpi/rpi3/aarch64/plat_helpers.S \ plat/rpi/rpi3/rpi3_bl1_setup.c \ plat/rpi/common/rpi3_io_storage.c \ drivers/rpi3/mailbox/rpi3_mbox.c \ @@ -38,7 +38,6 @@ BL2_SOURCES += common/desc_image_load.c \ drivers/mmc/mmc.c \ drivers/rpi3/sdhost/rpi3_sdhost.c \ plat/common/aarch64/platform_mp_stack.S \ - plat/rpi/rpi3/aarch64/plat_helpers.S \ plat/rpi/rpi3/aarch64/rpi3_bl2_mem_params_desc.c \ plat/rpi/rpi3/rpi3_bl2_setup.c \ plat/rpi/common/rpi3_image_load.c \ @@ -46,7 +45,6 @@ BL2_SOURCES += common/desc_image_load.c \ BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \ plat/common/plat_psci_common.c \ - plat/rpi/rpi3/aarch64/plat_helpers.S \ plat/rpi/rpi3/rpi3_bl31_setup.c \ plat/rpi/common/rpi3_pm.c \ plat/rpi/common/rpi3_topology.c \ diff --git a/plat/rpi/rpi4/aarch64/plat_helpers.S b/plat/rpi/rpi4/aarch64/plat_helpers.S deleted file mode 100644 index fac1b2075..000000000 --- a/plat/rpi/rpi4/aarch64/plat_helpers.S +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include -#include -#include - - .globl plat_crash_console_flush - .globl plat_crash_console_init - .globl plat_crash_console_putc - .globl platform_mem_init - .globl plat_get_my_entrypoint - .globl plat_is_my_cpu_primary - .globl plat_my_core_pos - .globl plat_reset_handler - .globl plat_rpi3_calc_core_pos - .globl plat_secondary_cold_boot_setup - - /* ----------------------------------------------------- - * unsigned int plat_my_core_pos(void) - * - * This function uses the plat_rpi3_calc_core_pos() - * definition to get the index of the calling CPU. - * ----------------------------------------------------- - */ -func plat_my_core_pos - mrs x0, mpidr_el1 - b plat_rpi3_calc_core_pos -endfunc plat_my_core_pos - - /* ----------------------------------------------------- - * unsigned int plat_rpi3_calc_core_pos(u_register_t mpidr); - * - * CorePos = (ClusterId * 4) + CoreId - * ----------------------------------------------------- - */ -func plat_rpi3_calc_core_pos - and x1, x0, #MPIDR_CPU_MASK - and x0, x0, #MPIDR_CLUSTER_MASK - add x0, x1, x0, LSR #6 - ret -endfunc plat_rpi3_calc_core_pos - - /* ----------------------------------------------------- - * 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, #RPI4_PRIMARY_CPU - cset w0, eq - ret -endfunc plat_is_my_cpu_primary - - /* ----------------------------------------------------- - * 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 - /* Calculate address of our hold entry */ - bl plat_my_core_pos - lsl x0, x0, #3 - mov_imm x2, PLAT_RPI3_TM_HOLD_BASE - add x0, x0, x2 - - /* - * This code runs way before requesting the warmboot of this core, - * so it is possible to clear the mailbox before getting a request - * to boot. - */ - mov x1, PLAT_RPI3_TM_HOLD_STATE_WAIT - str x1,[x0] - - /* Wait until we have a go */ -poll_mailbox: - wfe - ldr x1, [x0] - cmp x1, PLAT_RPI3_TM_HOLD_STATE_GO - bne poll_mailbox - - /* Jump to the provided entrypoint */ - mov_imm x0, PLAT_RPI3_TM_ENTRYPOINT - ldr x1, [x0] - br x1 -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 a warm - * boot. - * - * This functions returns: - * - 0 for a cold boot. - * - Any other value for a warm boot. - * --------------------------------------------------------------------- - */ -func plat_get_my_entrypoint - /* TODO: support warm boot */ - mov x0, #0 - ret -endfunc plat_get_my_entrypoint - - /* --------------------------------------------- - * void platform_mem_init (void); - * - * No need to carry out any memory initialization. - * --------------------------------------------- - */ -func platform_mem_init - ret -endfunc platform_mem_init - - /* --------------------------------------------- - * int plat_crash_console_init(void) - * Function to initialize the crash console - * without a C Runtime to print crash report. - * Clobber list : x0 - x3 - * --------------------------------------------- - */ -func plat_crash_console_init - mov_imm x0, PLAT_RPI_MINI_UART_BASE - mov x1, xzr - mov x2, xzr - b console_16550_core_init -endfunc plat_crash_console_init - - /* --------------------------------------------- - * int plat_crash_console_putc(int c) - * Function to print a character on the crash - * console without a C Runtime. - * Clobber list : x1, x2 - * --------------------------------------------- - */ -func plat_crash_console_putc - mov_imm x1, PLAT_RPI_MINI_UART_BASE - b console_16550_core_putc -endfunc plat_crash_console_putc - - /* --------------------------------------------- - * int plat_crash_console_flush() - * Function to force a write of all buffered - * data that hasn't been output. - * Out : return -1 on error else return 0. - * Clobber list : x0, x1 - * --------------------------------------------- - */ -func plat_crash_console_flush - mov_imm x0, PLAT_RPI_MINI_UART_BASE - b console_16550_core_flush -endfunc plat_crash_console_flush - - /* --------------------------------------------- - * void plat_reset_handler(void); - * --------------------------------------------- - */ -func plat_reset_handler - /* ------------------------------------------------ - * Set L2 read/write cache latency: - * - L2 Data RAM latency: 3 cycles (0b010) - * - L2 Data RAM setup: 1 cycle (bit 5) - * ------------------------------------------------ - */ - mrs x0, CORTEX_A72_L2CTLR_EL1 - mov x1, #0x22 - orr x0, x0, x1 - msr CORTEX_A72_L2CTLR_EL1, x0 - isb - - ret -endfunc plat_reset_handler diff --git a/plat/rpi/rpi4/include/platform_def.h b/plat/rpi/rpi4/include/platform_def.h index 6f6bbbe7a..d03eea6e9 100644 --- a/plat/rpi/rpi4/include/platform_def.h +++ b/plat/rpi/rpi4/include/platform_def.h @@ -24,7 +24,7 @@ #define PLATFORM_CLUSTER0_CORE_COUNT PLATFORM_MAX_CPUS_PER_CLUSTER #define PLATFORM_CORE_COUNT PLATFORM_CLUSTER0_CORE_COUNT -#define RPI4_PRIMARY_CPU U(0) +#define RPI_PRIMARY_CPU U(0) #define PLAT_MAX_PWR_LVL MPIDR_AFFLVL1 #define PLAT_NUM_PWR_DOMAINS (PLATFORM_CLUSTER_COUNT + \ diff --git a/plat/rpi/rpi4/platform.mk b/plat/rpi/rpi4/platform.mk index 49e78dfed..0744bceb4 100644 --- a/plat/rpi/rpi4/platform.mk +++ b/plat/rpi/rpi4/platform.mk @@ -16,7 +16,7 @@ PLAT_BL_COMMON_SOURCES := drivers/ti/uart/aarch64/16550_console.S \ ${XLAT_TABLES_LIB_SRCS} BL31_SOURCES += lib/cpus/aarch64/cortex_a72.S \ - plat/rpi/rpi4/aarch64/plat_helpers.S \ + plat/rpi/common/aarch64/plat_helpers.S \ plat/rpi/rpi4/aarch64/armstub8_header.S \ drivers/arm/gic/common/gic_common.c \ drivers/arm/gic/v2/gicv2_helpers.c \ -- cgit v1.2.3 From af2a4877a76498a03edb12908164978a7ab0c7fe Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Sat, 21 Mar 2020 11:22:13 +0000 Subject: rpi: rpi3_pwr_domain_on(): Use MMIO accessor When writing to arbitrary locations in memory using a constructed pointer, there is no guarantee that the compiler does not optimise away the access, since it cannot detect any dependency. One typical solution is to use the "volatile" keyword, but using MMIO accessors in usually the better answer, to avoid torn writes. Replace the usage of an array with such an MMIO accessor function in rpi3_pwr_domain_on(), to make sure the write is really happening. Change-Id: Ia18163c95e92f1557471089fd18abc6dc7fee0c7 Signed-off-by: Andre Przywara --- plat/rpi/common/rpi3_pm.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/plat/rpi/common/rpi3_pm.c b/plat/rpi/common/rpi3_pm.c index 2a6bf076b..83270260f 100644 --- a/plat/rpi/common/rpi3_pm.c +++ b/plat/rpi/common/rpi3_pm.c @@ -140,11 +140,14 @@ static int rpi3_pwr_domain_on(u_register_t mpidr) { int rc = PSCI_E_SUCCESS; unsigned int pos = plat_core_pos_by_mpidr(mpidr); - uint64_t *hold_base = (uint64_t *)PLAT_RPI3_TM_HOLD_BASE; + uintptr_t hold_base = PLAT_RPI3_TM_HOLD_BASE; assert(pos < PLATFORM_CORE_COUNT); - hold_base[pos] = PLAT_RPI3_TM_HOLD_STATE_GO; + hold_base += pos * PLAT_RPI3_TM_HOLD_ENTRY_SIZE; + + mmio_write_64(hold_base, PLAT_RPI3_TM_HOLD_STATE_GO); + /* No cache maintenance here, hold_base is mapped as device memory. */ /* Make sure that the write has completed */ dsb(); -- cgit v1.2.3 From 2e5f84432dabd74cbcd045e5007e02c7d3b25a91 Mon Sep 17 00:00:00 2001 From: Andrei Warkentin Date: Wed, 11 Mar 2020 22:11:06 -0700 Subject: rpi: Implement PSCI CPU_OFF We simulate the PSCI CPU_OFF operation by reseting the core via RMR. For secondaries, that already puts them in the holding pen waiting for a "warm boot" request as part of PSCI CPU_ON. For the BSP, we have to add logic to distinguish a regular boot from a CPU_OFF state, where, like the secondaries, the BSP needs to wait foor a "warm boot" request as part of CPU_ON. Testing done: - ACS suite now passes more tests (since it repeatedly calls code on secondaries via CPU_ON). - Linux testing including offlining/onlineing CPU0, e.g. "echo 0 > /sys/devices/system/cpu/cpu0/online". Change-Id: Id0ae11a0ee0721b20fa2578b54dadc72dcbd69e0 Link: https://developer.trustedfirmware.org/T686 Signed-off-by: Andrei Warkentin [Andre: adapt to unified plat_helpers.S, smaller fixes] Signed-off-by: Andre Przywara --- plat/rpi/common/aarch64/plat_helpers.S | 50 +++++++++++++++++++++++++++------- plat/rpi/common/rpi3_pm.c | 27 ++++++++++++++++++ plat/rpi/rpi3/include/platform_def.h | 1 + plat/rpi/rpi4/include/platform_def.h | 1 + 4 files changed, 69 insertions(+), 10 deletions(-) diff --git a/plat/rpi/common/aarch64/plat_helpers.S b/plat/rpi/common/aarch64/plat_helpers.S index 93c8f7f7f..e21233a1d 100644 --- a/plat/rpi/common/aarch64/plat_helpers.S +++ b/plat/rpi/common/aarch64/plat_helpers.S @@ -63,21 +63,23 @@ func plat_is_my_cpu_primary endfunc plat_is_my_cpu_primary /* ----------------------------------------------------- - * void plat_secondary_cold_boot_setup (void); + * void plat_wait_for_warm_boot (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. + * needed for a CPU to be put into holding pen to wait + * for a warm boot request. + * The function will never return. * ----------------------------------------------------- */ -func plat_secondary_cold_boot_setup - /* Calculate address of our hold entry */ +func plat_wait_for_warm_boot + /* + * Calculate address of our hold entry. + * As the function will never return, there is no need to save LR. + */ bl plat_my_core_pos lsl x0, x0, #3 mov_imm x2, PLAT_RPI3_TM_HOLD_BASE add x0, x0, x2 - /* * This code runs way before requesting the warmboot of this core, * so it is possible to clear the mailbox before getting a request @@ -97,6 +99,19 @@ poll_mailbox: mov_imm x0, PLAT_RPI3_TM_ENTRYPOINT ldr x1, [x0] br x1 +endfunc plat_wait_for_warm_boot + + /* ----------------------------------------------------- + * 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 + b plat_wait_for_warm_boot endfunc plat_secondary_cold_boot_setup /* --------------------------------------------------------------------- @@ -111,9 +126,24 @@ endfunc plat_secondary_cold_boot_setup * --------------------------------------------------------------------- */ func plat_get_my_entrypoint - /* TODO: support warm boot */ - mov x0, #0 - ret + mov x1, x30 + bl plat_is_my_cpu_primary + /* + * Secondaries always cold boot. + */ + cbz w0, 1f + /* + * Primaries warm boot if they are requested + * to power off. + */ + mov_imm x0, PLAT_RPI3_TM_HOLD_BASE + ldr x0, [x0] + cmp x0, PLAT_RPI3_TM_HOLD_STATE_BSP_OFF + adr x0, plat_wait_for_warm_boot + csel x0, x0, xzr, eq + ret x1 +1: mov x0, #0 + ret x1 endfunc plat_get_my_entrypoint /* --------------------------------------------- diff --git a/plat/rpi/common/rpi3_pm.c b/plat/rpi/common/rpi3_pm.c index 83270260f..86c61f7a6 100644 --- a/plat/rpi/common/rpi3_pm.c +++ b/plat/rpi/common/rpi3_pm.c @@ -174,6 +174,32 @@ static void rpi3_pwr_domain_on_finish(const psci_power_state_t *target_state) #endif } +static void __dead2 rpi3_pwr_down_wfi( + const psci_power_state_t *target_state) +{ + uintptr_t hold_base = PLAT_RPI3_TM_HOLD_BASE; + unsigned int pos = plat_my_core_pos(); + + if (pos == 0) { + /* + * The secondaries will always be in a wait + * for warm boot on reset, but the BSP needs + * to be able to distinguish between waiting + * for warm boot (e.g. after psci_off, waiting + * for psci_on) and a cold boot. + */ + mmio_write_64(hold_base, PLAT_RPI3_TM_HOLD_STATE_BSP_OFF); + /* No cache maintenance here, we run with caches off already. */ + dsb(); + isb(); + } + + write_rmr_el3(RMR_EL3_RR_BIT | RMR_EL3_AA64_BIT); + + while (1) + ; +} + /******************************************************************************* * Platform handlers for system reset and system off. ******************************************************************************/ @@ -239,6 +265,7 @@ static const plat_psci_ops_t plat_rpi3_psci_pm_ops = { .pwr_domain_pwr_down_wfi = rpi3_pwr_domain_pwr_down_wfi, .pwr_domain_on = rpi3_pwr_domain_on, .pwr_domain_on_finish = rpi3_pwr_domain_on_finish, + .pwr_domain_pwr_down_wfi = rpi3_pwr_down_wfi, .system_off = rpi3_system_off, .system_reset = rpi3_system_reset, .validate_power_state = rpi3_validate_power_state, diff --git a/plat/rpi/rpi3/include/platform_def.h b/plat/rpi/rpi3/include/platform_def.h index 2bcf53ee9..f44d1f526 100644 --- a/plat/rpi/rpi3/include/platform_def.h +++ b/plat/rpi/rpi3/include/platform_def.h @@ -153,6 +153,7 @@ #define PLAT_RPI3_TM_HOLD_STATE_WAIT ULL(0) #define PLAT_RPI3_TM_HOLD_STATE_GO ULL(1) +#define PLAT_RPI3_TM_HOLD_STATE_BSP_OFF ULL(2) /* * BL1 specific defines. diff --git a/plat/rpi/rpi4/include/platform_def.h b/plat/rpi/rpi4/include/platform_def.h index d03eea6e9..6787ebfee 100644 --- a/plat/rpi/rpi4/include/platform_def.h +++ b/plat/rpi/rpi4/include/platform_def.h @@ -93,6 +93,7 @@ #define PLAT_RPI3_TM_HOLD_STATE_WAIT ULL(0) #define PLAT_RPI3_TM_HOLD_STATE_GO ULL(1) +#define PLAT_RPI3_TM_HOLD_STATE_BSP_OFF ULL(2) /* * BL31 specific defines. -- cgit v1.2.3 From 4501843f2d0387e2c58147d8f4cf0a028e227938 Mon Sep 17 00:00:00 2001 From: Gilad Ben-Yossef Date: Wed, 15 May 2019 09:24:04 +0300 Subject: cryptocell: add support for Cryptocell 713 Add Crypto 713 support as crypto module and NVM counter provider. As files under include/drivers/arm/cryptocell/713/ are copied verbatim from the CryptoCell SBROM lib project they are filtered from checkpatch coding style check. Signed-off-by: Gilad Ben-Yossef Change-Id: I7c361772f00ca7d96481f81ac6cbb2704467e52c --- Makefile | 14 +- drivers/auth/cryptocell/713/cryptocell_crypto.c | 273 +++++++++++++++++++++ .../auth/cryptocell/713/cryptocell_plat_helpers.c | 109 ++++++++ drivers/auth/cryptocell/cryptocell_crypto.mk | 4 +- include/drivers/arm/cryptocell/713/bsv_api.h | 221 +++++++++++++++++ .../drivers/arm/cryptocell/713/bsv_crypto_api.h | 76 ++++++ .../arm/cryptocell/713/bsv_crypto_asym_api.h | 100 ++++++++ .../drivers/arm/cryptocell/713/bsv_crypto_defs.h | 94 +++++++ include/drivers/arm/cryptocell/713/bsv_error.h | 161 ++++++++++++ .../drivers/arm/cryptocell/713/cc_address_defs.h | 50 ++++ include/drivers/arm/cryptocell/713/cc_boot_defs.h | 52 ++++ include/drivers/arm/cryptocell/713/cc_pal_types.h | 100 ++++++++ .../drivers/arm/cryptocell/713/cc_pal_types_plat.h | 25 ++ .../arm/cryptocell/713/cc_pka_hw_plat_defs.h | 62 +++++ include/drivers/arm/cryptocell/713/cc_sec_defs.h | 70 ++++++ 15 files changed, 1408 insertions(+), 3 deletions(-) create mode 100644 drivers/auth/cryptocell/713/cryptocell_crypto.c create mode 100644 drivers/auth/cryptocell/713/cryptocell_plat_helpers.c create mode 100644 include/drivers/arm/cryptocell/713/bsv_api.h create mode 100644 include/drivers/arm/cryptocell/713/bsv_crypto_api.h create mode 100644 include/drivers/arm/cryptocell/713/bsv_crypto_asym_api.h create mode 100644 include/drivers/arm/cryptocell/713/bsv_crypto_defs.h create mode 100644 include/drivers/arm/cryptocell/713/bsv_error.h create mode 100644 include/drivers/arm/cryptocell/713/cc_address_defs.h create mode 100644 include/drivers/arm/cryptocell/713/cc_boot_defs.h create mode 100644 include/drivers/arm/cryptocell/713/cc_pal_types.h create mode 100644 include/drivers/arm/cryptocell/713/cc_pal_types_plat.h create mode 100644 include/drivers/arm/cryptocell/713/cc_pka_hw_plat_defs.h create mode 100644 include/drivers/arm/cryptocell/713/cc_sec_defs.h diff --git a/Makefile b/Makefile index e455635b6..8d910a4f4 100644 --- a/Makefile +++ b/Makefile @@ -39,12 +39,20 @@ PLAT := ${DEFAULT_PLAT} CHECKCODE_ARGS := --no-patch # Do not check the coding style on imported library files or documentation files +INC_ARM_DIRS_TO_CHECK := $(sort $(filter-out \ + include/drivers/arm/cryptocell, \ + $(wildcard include/drivers/arm/*))) +INC_ARM_DIRS_TO_CHECK += include/drivers/arm/cryptocell/*.h +INC_DRV_DIRS_TO_CHECK := $(sort $(filter-out \ + include/drivers/arm, \ + $(wildcard include/drivers/*))) INC_LIB_DIRS_TO_CHECK := $(sort $(filter-out \ include/lib/libfdt \ include/lib/libc, \ $(wildcard include/lib/*))) INC_DIRS_TO_CHECK := $(sort $(filter-out \ - include/lib, \ + include/lib \ + include/drivers, \ $(wildcard include/*))) LIB_DIRS_TO_CHECK := $(sort $(filter-out \ lib/compiler-rt \ @@ -60,7 +68,9 @@ ROOT_DIRS_TO_CHECK := $(sort $(filter-out \ CHECK_PATHS := ${ROOT_DIRS_TO_CHECK} \ ${INC_DIRS_TO_CHECK} \ ${INC_LIB_DIRS_TO_CHECK} \ - ${LIB_DIRS_TO_CHECK} + ${LIB_DIRS_TO_CHECK} \ + ${INC_DRV_DIRS_TO_CHECK} \ + ${INC_ARM_DIRS_TO_CHECK} ################################################################################ diff --git a/drivers/auth/cryptocell/713/cryptocell_crypto.c b/drivers/auth/cryptocell/713/cryptocell_crypto.c new file mode 100644 index 000000000..5f390a226 --- /dev/null +++ b/drivers/auth/cryptocell/713/cryptocell_crypto.c @@ -0,0 +1,273 @@ +/* + * Copyright (c) 2017-2020 ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include +#include +#include + +#include + +#define LIB_NAME "CryptoCell 713 SBROM" +#define RSA_SALT_LEN 32 +#define RSA_EXPONENT 65537 + +/* + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL + * } + * + * SubjectPublicKeyInfo ::= SEQUENCE { + * algorithm AlgorithmIdentifier, + * subjectPublicKey BIT STRING + * } + * + * DigestInfo ::= SEQUENCE { + * digestAlgorithm AlgorithmIdentifier, + * digest OCTET STRING + * } + * + * RSASSA-PSS-params ::= SEQUENCE { + * hashAlgorithm [0] HashAlgorithm, + * maskGenAlgorithm [1] MaskGenAlgorithm, + * saltLength [2] INTEGER, + * trailerField [3] TrailerField DEFAULT trailerFieldBC + * } + */ + +/* + * Initialize the library and export the descriptor + */ +static void init(void) +{ + CCError_t ret; + uint32_t lcs; + + /* Initialize CC SBROM */ + ret = CC_BsvInit((uintptr_t)PLAT_CRYPTOCELL_BASE); + if (ret != CC_OK) { + ERROR("CryptoCell CC_BsvInit() error %x\n", ret); + panic(); + } + + /* Initialize lifecycle state */ + ret = CC_BsvGetAndInitLcs((uintptr_t)PLAT_CRYPTOCELL_BASE, &lcs); + if (ret != CC_OK) { + ERROR("CryptoCell CC_BsvGetAndInitLcs() error %x\n", ret); + panic(); + } +} + +/* + * Verify a signature. + * + * Parameters are passed using the DER encoding format following the ASN.1 + * structures detailed above. + */ +static int verify_signature(void *data_ptr, unsigned int data_len, + void *sig_ptr, unsigned int sig_len, + void *sig_alg, unsigned int sig_alg_len, + void *pk_ptr, unsigned int pk_len) +{ + CCError_t error; + CCBsvNBuff_t NBuff; + CCBsvSignature_t signature; + int rc, exp; + mbedtls_asn1_buf sig_oid, alg_oid, params; + mbedtls_md_type_t md_alg; + mbedtls_pk_type_t pk_alg; + mbedtls_pk_rsassa_pss_options pss_opts; + size_t len; + uint8_t *p, *end; + CCHashResult_t digest; + CCBool_t is_verified; + /* This is a rather large array, we don't want it on stack */ + static uint32_t workspace[BSV_RSA_WORKSPACE_MIN_SIZE]; + + /* Verify the signature algorithm */ + /* Get pointers to signature OID and parameters */ + p = sig_alg; + end = p + sig_alg_len; + rc = mbedtls_asn1_get_alg(&p, end, &sig_oid, ¶ms); + if (rc != 0) + return CRYPTO_ERR_SIGNATURE; + + /* Get the actual signature algorithm (MD + PK) */ + rc = mbedtls_oid_get_sig_alg(&sig_oid, &md_alg, &pk_alg); + if (rc != 0) + return CRYPTO_ERR_SIGNATURE; + + /* The CryptoCell only supports RSASSA-PSS signature */ + if (pk_alg != MBEDTLS_PK_RSASSA_PSS || md_alg != MBEDTLS_MD_NONE) + return CRYPTO_ERR_SIGNATURE; + + /* Verify the RSASSA-PSS params */ + /* The trailer field is verified to be 0xBC internally by this API */ + rc = mbedtls_x509_get_rsassa_pss_params(¶ms, &md_alg, + &pss_opts.mgf1_hash_id, + &pss_opts.expected_salt_len); + if (rc != 0) + return CRYPTO_ERR_SIGNATURE; + + /* The CryptoCell only supports SHA256 as hash algorithm */ + if (md_alg != MBEDTLS_MD_SHA256 || + pss_opts.mgf1_hash_id != MBEDTLS_MD_SHA256) + return CRYPTO_ERR_SIGNATURE; + + if (pss_opts.expected_salt_len != RSA_SALT_LEN) + return CRYPTO_ERR_SIGNATURE; + + /* Parse the public key */ + p = pk_ptr; + end = p + pk_len; + rc = mbedtls_asn1_get_tag(&p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); + if (rc != 0) + return CRYPTO_ERR_SIGNATURE; + + end = p + len; + rc = mbedtls_asn1_get_alg_null(&p, end, &alg_oid); + if (rc != 0) + return CRYPTO_ERR_SIGNATURE; + + if (mbedtls_oid_get_pk_alg(&alg_oid, &pk_alg) != 0) + return CRYPTO_ERR_SIGNATURE; + + if (pk_alg != MBEDTLS_PK_RSA) + return CRYPTO_ERR_SIGNATURE; + + rc = mbedtls_asn1_get_bitstring_null(&p, end, &len); + if (rc != 0) + return CRYPTO_ERR_SIGNATURE; + + rc = mbedtls_asn1_get_tag(&p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE); + if (rc != 0) + return CRYPTO_ERR_SIGNATURE; + + rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_INTEGER); + if (rc != 0) + return CRYPTO_ERR_SIGNATURE; + + if (*p == 0) { + p++; len--; + } + if (len != BSV_CERT_RSA_KEY_SIZE_IN_BYTES || ((p + len) > end)) + return CRYPTO_ERR_SIGNATURE; + + /* + * Copy N from certificate. + */ + memcpy(NBuff, p, BSV_CERT_RSA_KEY_SIZE_IN_BYTES); + + /* Verify the RSA exponent */ + p += len; + rc = mbedtls_asn1_get_int(&p, end, &exp); + if (rc != 0) + return CRYPTO_ERR_SIGNATURE; + + if (exp != RSA_EXPONENT) + return CRYPTO_ERR_SIGNATURE; + + /* Get the signature (bitstring) */ + p = sig_ptr; + end = p + sig_len; + rc = mbedtls_asn1_get_bitstring_null(&p, end, &len); + if (rc != 0) + return CRYPTO_ERR_SIGNATURE; + + if (len != BSV_CERT_RSA_KEY_SIZE_IN_BYTES || ((p + len) > end)) + return CRYPTO_ERR_SIGNATURE; + + /* + * Copy the signature (in BE format) + */ + memcpy((uint8_t *)signature, p, BSV_CERT_RSA_KEY_SIZE_IN_BYTES); + + error = CC_BsvSha256((uintptr_t)PLAT_CRYPTOCELL_BASE, + data_ptr, data_len, digest); + if (error != CC_OK) + return CRYPTO_ERR_SIGNATURE; + + /* Verify the signature */ + error = CC_BsvRsaPssVerify((uintptr_t)PLAT_CRYPTOCELL_BASE, NBuff, + NULL, signature, digest, workspace, + BSV_RSA_WORKSPACE_MIN_SIZE, &is_verified); + if ((error != CC_OK) || (is_verified != CC_TRUE)) + return CRYPTO_ERR_SIGNATURE; + + /* Signature verification success */ + return CRYPTO_SUCCESS; +} + +/* + * Match a hash + * + * Digest info is passed in DER format following the ASN.1 structure detailed + * above. + */ +static int verify_hash(void *data_ptr, unsigned int data_len, + void *digest_info_ptr, unsigned int digest_info_len) +{ + mbedtls_asn1_buf hash_oid, params; + mbedtls_md_type_t md_alg; + uint8_t *p, *end, *hash; + CCHashResult_t pubKeyHash; + size_t len; + int rc; + CCError_t error; + + /* Digest info should be an MBEDTLS_ASN1_SEQUENCE */ + p = digest_info_ptr; + end = p + digest_info_len; + rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE); + if (rc != 0) + return CRYPTO_ERR_HASH; + + /* Get the hash algorithm */ + rc = mbedtls_asn1_get_alg(&p, end, &hash_oid, ¶ms); + if (rc != 0) + return CRYPTO_ERR_HASH; + + rc = mbedtls_oid_get_md_alg(&hash_oid, &md_alg); + if (rc != 0) + return CRYPTO_ERR_HASH; + /* Verify that hash algorithm is SHA256 */ + if (md_alg != MBEDTLS_MD_SHA256) + return CRYPTO_ERR_HASH; + + /* Hash should be octet string type */ + rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING); + if (rc != 0) + return CRYPTO_ERR_HASH; + + /* Length of hash must match the algorithm's size */ + if (len != HASH_RESULT_SIZE_IN_BYTES) + return CRYPTO_ERR_HASH; + + hash = p; + error = CC_BsvSha256((uintptr_t)PLAT_CRYPTOCELL_BASE, data_ptr, + data_len, pubKeyHash); + if (error != CC_OK) + return CRYPTO_ERR_HASH; + + rc = memcmp(pubKeyHash, hash, HASH_RESULT_SIZE_IN_BYTES); + if (rc != 0) + return CRYPTO_ERR_HASH; + + return CRYPTO_SUCCESS; +} + +/* + * Register crypto library descriptor + */ +REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL); diff --git a/drivers/auth/cryptocell/713/cryptocell_plat_helpers.c b/drivers/auth/cryptocell/713/cryptocell_plat_helpers.c new file mode 100644 index 000000000..17e12807c --- /dev/null +++ b/drivers/auth/cryptocell/713/cryptocell_plat_helpers.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2017-2020 ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include +#include + +#include +#include +#include + +/* + * Return the ROTPK hash + * + * Return: 0 = success, Otherwise = error + */ +int cc_get_rotpk_hash(unsigned char *dst, unsigned int len, unsigned int *flags) +{ + CCError_t error; + uint32_t lcs; + int i; + uint32_t *key = (uint32_t *)dst; + + assert(dst != NULL); + assert(len >= HASH_RESULT_SIZE_IN_WORDS); + assert(flags != NULL); + + error = CC_BsvLcsGet(PLAT_CRYPTOCELL_BASE, &lcs); + if (error != CC_OK) + return 1; + + if ((lcs == CC_BSV_CHIP_MANUFACTURE_LCS) || (lcs == CC_BSV_RMA_LCS)) { + *flags = ROTPK_NOT_DEPLOYED; + return 0; + } + + error = CC_BsvPubKeyHashGet(PLAT_CRYPTOCELL_BASE, + CC_SB_HASH_BOOT_KEY_256B, + key, HASH_RESULT_SIZE_IN_WORDS); + + if (error == CC_BSV_HASH_NOT_PROGRAMMED_ERR) { + *flags = ROTPK_NOT_DEPLOYED; + return 0; + } + + if (error == CC_OK) { + + /* Keys are stored in OTP in little-endian format */ + for (i = 0; i < HASH_RESULT_SIZE_IN_WORDS; i++) + key[i] = le32toh(key[i]); + + *flags = ROTPK_IS_HASH; + return 0; + } + + return 1; +} + +/* + * Return the non-volatile counter value stored in the platform. The cookie + * specifies the OID of the counter in the certificate. + * + * Return: 0 = success, Otherwise = error + */ +int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr) +{ + CCError_t error = CC_FAIL; + + if (strcmp(cookie, TRUSTED_FW_NVCOUNTER_OID) == 0) { + error = CC_BsvSwVersionGet(PLAT_CRYPTOCELL_BASE, + CC_SW_VERSION_TRUSTED, nv_ctr); + } else if (strcmp(cookie, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) { + error = CC_BsvSwVersionGet(PLAT_CRYPTOCELL_BASE, + CC_SW_VERSION_NON_TRUSTED, nv_ctr); + } + + return (error != CC_OK); +} + +/* + * Store a new non-volatile counter value in the counter specified by the OID + * in the cookie. This function is not expected to be called if the Lifecycle + * state is RMA as the values in the certificate are expected to always match + * the nvcounter values. But if called when the LCS is RMA, the underlying + * helper functions will return success but without updating the counter. + * + * Return: 0 = success, Otherwise = error + */ +int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr) +{ + CCError_t error = CC_FAIL; + + if (strcmp(cookie, TRUSTED_FW_NVCOUNTER_OID) == 0) { + error = CC_BsvSwVersionSet(PLAT_CRYPTOCELL_BASE, + CC_SW_VERSION_TRUSTED, nv_ctr); + } else if (strcmp(cookie, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) { + error = CC_BsvSwVersionSet(PLAT_CRYPTOCELL_BASE, + CC_SW_VERSION_NON_TRUSTED, nv_ctr); + } + + return (error != CC_OK); +} + diff --git a/drivers/auth/cryptocell/cryptocell_crypto.mk b/drivers/auth/cryptocell/cryptocell_crypto.mk index 2fc4ddb11..db390471f 100644 --- a/drivers/auth/cryptocell/cryptocell_crypto.mk +++ b/drivers/auth/cryptocell/cryptocell_crypto.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -22,6 +22,8 @@ endif CRYPTOCELL_VERSION ?= 712 ifeq (${CRYPTOCELL_VERSION},712) CCSBROM_LIB_FILENAME := cc_712sbromx509 +else ifeq (${CRYPTOCELL_VERSION},713) + CCSBROM_LIB_FILENAME := cc_713bsv else $(error Error: CRYPTOCELL_VERSION set to invalid version) endif diff --git a/include/drivers/arm/cryptocell/713/bsv_api.h b/include/drivers/arm/cryptocell/713/bsv_api.h new file mode 100644 index 000000000..dc494735c --- /dev/null +++ b/include/drivers/arm/cryptocell/713/bsv_api.h @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2017-2020 ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _BSV_API_H +#define _BSV_API_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*! +@file +@brief This file contains the Boot Services APIs and definitions. + +@defgroup cc_bsv_api CryptoCell Boot Services APIs and definitions +@{ +@ingroup cc_bsv +*/ + +#include "cc_pal_types.h" +#include "cc_sec_defs.h" +#include "cc_boot_defs.h" + +/* Life cycle state definitions. */ +#define CC_BSV_CHIP_MANUFACTURE_LCS 0x0 /*!< The CM life-cycle state (LCS) value. */ +#define CC_BSV_DEVICE_MANUFACTURE_LCS 0x1 /*!< The DM life-cycle state (LCS) value. */ +#define CC_BSV_SECURE_LCS 0x5 /*!< The Secure life-cycle state (LCS) value. */ +#define CC_BSV_RMA_LCS 0x7 /*!< The RMA life-cycle state (LCS) value. */ +#define CC_BSV_INVALID_LCS 0xff /*!< The invalid life-cycle state (LCS) value. */ + +/*---------------------------- + TYPES +-----------------------------------*/ + +/*---------------------------- + PUBLIC FUNCTIONS +-----------------------------------*/ + + +/*! +@brief This function verifies the product and version numbers of the HW, and initializes it. + +\warning This function must be the first CryptoCell-7xx SBROM library API called. + +@return \c CC_OK on success. +@return A non-zero value from bsv_error.h on failure. +*/ +CCError_t CC_BsvInit( + unsigned long hwBaseAddress /*!< [in] The base address of the CryptoCell HW registers. */ + ); + +/*! +@brief This function retrieves the HW LCS and performs validity checks. + +If the LCS is RMA, it also sets the OTP secret keys to a fixed value. + +@note An error is returned if there is an invalid LCS. If this happens, your code must +completely disable the device. + +@return \c CC_OK on success. +@return A non-zero value from bsv_error.h on failure. +*/ +CCError_t CC_BsvGetAndInitLcs( + unsigned long hwBaseAddress, /*!< [in] The base address of the CryptoCell HW registers. */ + uint32_t *pLcs /*!< [out] The value of the current LCS. */ + ); + +/*! +@brief This function retrieves the LCS from the NVM manager. + +@return \c CC_OK on success. +@return A non-zero value from bsv_error.h on failure. +*/ +CCError_t CC_BsvLcsGet( + unsigned long hwBaseAddress, /*!< [in] The base address of the CryptoCell HW registers. */ + uint32_t *pLcs /*!< [out] The value of the current LCS. */ + ); + +/*! +@brief This function reads software revocation counter from OTP memory, according to the provided sw version index. +SW version is stored in NVM counter and represented by ones. Meaning seVersion=5 would be stored as binary 0b11111; +hence: + the maximal of trusted is 32 + the maximal of non-trusted is 224 + +@return \c CC_OK on success. +@return A non-zero value from bsv_error.h on failure. +*/ +CCError_t CC_BsvSwVersionGet( + unsigned long hwBaseAddress, /*!< [in] HW registers base address. */ + CCSbSwVersionId_t id, /*!< [in] Enumeration defining the trusted/non-trusted counter to read. */ + uint32_t *swVersion /*!< [out] The value of the requested counter as read from OTP memory. */ + ); + +/*! +@brief This function sets the NVM counter according to swVersionID (trusted/non-trusted). + +@return \c CC_OK on success. +@return A non-zero value from bsv_error.h on failure. +*/ +CCError_t CC_BsvSwVersionSet( + unsigned long hwBaseAddress, /*!< [in] HW registers base address. */ + CCSbSwVersionId_t id, /*!< [in] Enumeration defining the trusted/non-trusted counter to read. */ + uint32_t swVersion /*!< [in] New value of the counter to be programmed in OTP memory. */ + ); + +/*! +@brief This function sets the "fatal error" flag in the NVM manager, to disable the use of +any HW keys or security services. + +@return \c CC_OK on success. +@return A non-zero value from bsv_error.h on failure. +*/ +CCError_t CC_BsvFatalErrorSet( + unsigned long hwBaseAddress /*!< [in] The base address of the CryptoCell HW registers. */ + ); + +/*! +@brief This function retrieves the public key hash from OTP memory, according to the provided index. + +@return \c CC_OK on success. +@return A non-zero value from bsv_error.h on failure. +*/ +CCError_t CC_BsvPubKeyHashGet( + unsigned long hwBaseAddress, /*!< [in] HW registers base address. */ + CCSbPubKeyIndexType_t keyIndex, /*!< [in] Enumeration defining the key hash to retrieve: 128-bit HBK0, 128-bit HBK1, or 256-bit HBK. */ + uint32_t *hashedPubKey, /*!< [out] A buffer to contain the public key HASH. */ + uint32_t hashResultSizeWords /*!< [in] The size of the hash in 32-bit words: + - Must be 4 for 128-bit hash. + - Must be 8 for 256bit hash. */ + ); + +/*! +@brief This function permanently sets the RMA LCS for the ICV and the OEM. + +@return \c CC_OK on success. +@return A non-zero value from bsv_error.h on failure. +*/ +CCError_t CC_BsvRMAModeEnable( + unsigned long hwBaseAddress /*!< [in] The base address of the CryptoCell HW registers. */ + ); + +/*! +@brief This function is called by the ICV code, to disable the OEM code from changing the ICV RMA bit flag. + +@return \c CC_OK on success. +@return A non-zero value from bsv_error.h on failure. +*/ +CCError_t CC_BsvICVRMAFlagBitLock( + unsigned long hwBaseAddress /*!< [in] The base address of the CryptoCell HW registers. */ + ); + +/*! +@brief This function locks the defined ICV class keys from further usage. + +@return \c CC_OK on success. +@return A non-zero value from bsv_error.h on failure. +*/ +CCError_t CC_BsvICVKeyLock( + unsigned long hwBaseAddress, /*!< [in] HW registers base address. */ + CCBool_t isICVProvisioningKeyLock, /*!< [in] Should the provisioning key be locked. */ + CCBool_t isICVCodeEncKeyLock /*!< [in] Should the encryption key be locked. */ + ); + + +/*! +@brief This function retrieves the value of "secure disable" bit. + +@return \c CC_OK on success. +@return A non-zero value from bsv_error.h on failure. +*/ +CCError_t CC_BsvSecureDisableGet( + unsigned long hwBaseAddress, /*!< [in] HW registers base address. */ + CCBool_t *isSDEnabled /*!< [out] The value of the SD Enable bit. */ + ); + + +/*! +@brief This function derives the platform key (Kplt) from the Kpicv, and then decrypts the customer key (Kcst) +from the EKcst (burned in the OTP). The decryption is done only in Secure and RMA LCS mode using AES-ECB. +The customer ROM should invoke this function during early boot, prior to running any non-ROM code, only if Kcst exists. +The resulting Kcst is saved in a HW register. + +@return \c CC_OK on success. +@return A non-zero value from bsv_error.h on failure. +*/ +CCError_t CC_BsvCustomerKeyDecrypt( + unsigned long hwBaseAddress /*!< [in] The base address of the CryptoCell HW registers. */ + ); +#ifdef __cplusplus +} +#endif + +/*! +@brief This function derives the unique SoC_ID for the device, as hashed (Hbk || AES_CMAC (HUK)). + +@note SoC_ID is required to create debug certificates. + +The OEM or ICV must provide a method for a developer to discover the SoC_ID of a target +device without having to first enable debugging. +One suggested implementation is to have the device ROM code compute the SoC_ID and place +it in a specific location in the flash memory, from where it can be accessed by the developer. + +@return \c CC_OK on success. +@return A non-zero value from bsv_error.h on failure. +*/ +CCError_t CC_BsvSocIDCompute( + unsigned long hwBaseAddress, /*!< [in] The base address of the CryptoCell HW registers. */ + CCHashResult_t hashResult /*!< [out] The derived SoC_ID. */ + ); + +#endif /* _BSV_API_H */ + +/** +@} + */ + diff --git a/include/drivers/arm/cryptocell/713/bsv_crypto_api.h b/include/drivers/arm/cryptocell/713/bsv_crypto_api.h new file mode 100644 index 000000000..1e6057931 --- /dev/null +++ b/include/drivers/arm/cryptocell/713/bsv_crypto_api.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2017-2020 ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _BSV_CRYPTO_API_H +#define _BSV_CRYPTO_API_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*! +@file +@brief This file contains the cryptographic ROM APIs of the Boot Services. + +@defgroup cc_bsv_crypto_api CryptoCell Boot Services cryptographic ROM APIs +@{ +@ingroup cc_bsv +*/ + +#include "cc_pal_types.h" +#include "cc_sec_defs.h" +#include "cc_address_defs.h" +#include "bsv_crypto_defs.h" + +/*---------------------------- + PUBLIC FUNCTIONS +-----------------------------------*/ + +/*! +@brief This function calculates the SHA-256 digest over contiguous memory +in an integrated operation. + +@return \c CC_OK on success. +@return A non-zero value from bsv_error.h on failure. +*/ +CCError_t CC_BsvSha256( + unsigned long hwBaseAddress, /*!< [in] The base address of the CryptoCell HW registers. */ + uint8_t *pDataIn, /*!< [in] A pointer to the input buffer to be hashed. The buffer must be contiguous. */ + size_t dataSize, /*!< [in] The size of the data to be hashed, in bytes. */ + CCHashResult_t hashBuff /*!< [out] A pointer to a word-aligned 32-byte buffer. */ + ); + + +/*! +@brief This function allows you to calculate SHA256 digest of an image with decryption base on AES-CTR, +with HW or user key. + +@return \c CC_OK on success. +@return A non-zero value from bsv_error.h on failure. (in this case, hashBuff will be returned clean, while the output data should be cleaned by the user). +*/ +CCError_t CC_BsvCryptoImageDecrypt( unsigned long hwBaseAddress, /*!< [in] The base address of the CryptoCell HW registers. */ + CCBsvflowMode_t flow, /*!< [in] The supported operations are: HASH, AES to HASH, AES and HASH. */ + CCBsvKeyType_t keyType, /*!< [in] The key type to use: Kce, Kceicv, or user key. */ + uint8_t *pUserKey, /*!< [in] A pointer to the user key buffer in case keyType is CC_BSV_USER_KEY. */ + size_t userKeySize, /*!< [in] The user key size in bytes (128bits) in case keyType is CC_BSV_USER_KEY. */ + uint8_t *pIvBuf, /*!< [in] A pointer to the IV / counter buffer. */ + uint8_t *pInputData, /*!< [in] A pointer to the input data. */ + uint8_t *pOutputData, /*!< [out] A pointer to the output buffer. (optional – should be null in case of hash only). */ + size_t dataSize, /*!< [in] The size of the input data in bytes. MUST be multiple of AES block size. */ + CCHashResult_t hashBuff /*!< [out] A pointer to a word-aligned 32-byte digest output buffer. */ + ); + +#ifdef __cplusplus +} +#endif + +#endif + +/** +@} + */ + diff --git a/include/drivers/arm/cryptocell/713/bsv_crypto_asym_api.h b/include/drivers/arm/cryptocell/713/bsv_crypto_asym_api.h new file mode 100644 index 000000000..406e1effb --- /dev/null +++ b/include/drivers/arm/cryptocell/713/bsv_crypto_asym_api.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2017-2020 ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _BSV_CRYPTO_ASYM_API_H +#define _BSV_CRYPTO_ASYM_API_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*! +@file +@brief This file contains the cryptographic Asymmetric ROM APIs of the Boot Services. + +@defgroup cc_bsv_crypto_asym_api CryptoCell Boot Services cryptographic Asymmetric ROM APIs +@{ +@ingroup cc_bsv +*/ + +#include "cc_pal_types.h" +#include "cc_pka_hw_plat_defs.h" +#include "cc_sec_defs.h" +#include "bsv_crypto_api.h" + +/*! Defines the workspace size in bytes needed for internal Asymmetric operations. */ +#define BSV_RSA_WORKSPACE_MIN_SIZE (4*BSV_CERT_RSA_KEY_SIZE_IN_BYTES +\ + 2*RSA_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_BYTES) + +/*! Definition for the RSA public modulus array. */ +typedef uint32_t CCBsvNBuff_t[BSV_CERT_RSA_KEY_SIZE_IN_WORDS]; + +/*! Definition for the RSA Barrett mod tag array. */ +typedef uint32_t CCBsvNpBuff_t[RSA_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_BYTES]; + +/*! Definition for the RSA signature array. */ +typedef uint32_t CCBsvSignature_t[BSV_CERT_RSA_KEY_SIZE_IN_WORDS]; + + +/*---------------------------- + PUBLIC FUNCTIONS +-----------------------------------*/ + +/*! +@brief This function performs the primitive operation of RSA, meaning exponent and modulus. + outBuff = (pInBuff ^ Exp) mod NBuff. ( Exp = 0x10001 ) + + The function supports 2k and 3K bit size of modulus, based on compile time define. + There are no restriction on pInBuff location, however its size must be equal to BSV_RSA_KEY_SIZE_IN_BYTES and its + value must be smaller than the modulus. + + +@return \c CC_OK on success. +@return A non-zero value from bsv_error.h on failure. +*/ +CCError_t CC_BsvRsaPrimVerify (unsigned long hwBaseAddress, /*!< [in] The base address of the CryptoCell HW registers. */ + CCBsvNBuff_t NBuff, /*!< [in] The modulus buffer big endian format. */ + CCBsvNpBuff_t NpBuff, /*!< [in] The barret tag buffer big endian format - optional. */ + uint32_t *pInBuff, /*!< [in] The DataIn buffer to be encrypted. */ + size_t inBuffSize, /*!< [in] The DataIn buffer size in bytes, must be BSV_RSA_KEY_SIZE_IN_BYTES. */ + CCBsvSignature_t pOutBuff, /*!< [out] The encrypted buffer in big endian format. */ + uint32_t *pWorkSpace, /*!< [in] The pointer to user allocated buffer for internal use. */ + size_t workBufferSize /*!< [in] The size in bytes of pWorkSpace, must be at-least BSV_RSA_WORKSPACE_MIN_SIZE. */ +); + + +/*! +@brief This function performs RSA PSS verify. + + The function should support 2k and 3K bit size of modulus, based on compile time define. + +@return \c CC_OK on success. +@return A non-zero value from bsv_error.h on failure. +*/ +CCError_t CC_BsvRsaPssVerify (unsigned long hwBaseAddress, /*!< [in] The base address of the CryptoCell HW registers. */ + CCBsvNBuff_t NBuff, /*!< [in] The modulus buffer big endian format. */ + CCBsvNpBuff_t NpBuff, /*!< [in] The barret tag buffer big endian format - optional. */ + CCBsvSignature_t signature, /*!< [in] The signature buffer to verify - big endian format. */ + CCHashResult_t hashedData, /*!< [in] The data-in buffer to be verified as sha256 digest. */ + uint32_t *pWorkSpace, /*!< [in] The pointer to user allocated buffer for internal use. */ + size_t workBufferSize, /*!< [in] The size in bytes of pWorkSpace, must be at-least BSV_RSA_WORKSPACE_MIN_SIZE. */ + CCBool_t *pIsVerified /*!< [out] The flag indicates whether the signature is verified or not. + If verified value will be CC_TRUE, otherwise CC_FALSE */ +); + + + +#ifdef __cplusplus +} +#endif + +#endif + +/** +@} + */ + diff --git a/include/drivers/arm/cryptocell/713/bsv_crypto_defs.h b/include/drivers/arm/cryptocell/713/bsv_crypto_defs.h new file mode 100644 index 000000000..9ea354deb --- /dev/null +++ b/include/drivers/arm/cryptocell/713/bsv_crypto_defs.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2017-2020 ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _BSV_CRYPTO_DEFS_H +#define _BSV_CRYPTO_DEFS_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*! +@file +@brief This file contains the definitions of the cryptographic ROM APIs. + +@defgroup cc_bsv_crypto_defs CryptoCell Boot Services cryptographic ROM API definitions +@{ +@ingroup cc_bsv +*/ + +/*! AES supported HW key code table. */ +typedef enum { + + CC_BSV_USER_KEY = 0, /*!< Definition for a user key. */ + CC_BSV_HUK_KEY = 1, /*!< Definition for the HW unique key. */ + CC_BSV_RTL_KEY = 2, /*!< Definition for the RTL key. */ + CC_BSV_SESSION_KEY = 3, /*!< Definition for the Session key. */ + CC_BSV_CE_KEY = 4, /*!< Definition for the Kce. */ + CC_BSV_PLT_KEY = 5, /*!< Definition for the Platform key. */ + CC_BSV_KCST_KEY = 6, /*!< Definition for Kcst. */ + CC_BSV_ICV_PROV_KEY = 0xd, /*!< Definition for the Kpicv. */ + CC_BSV_ICV_CE_KEY = 0xe, /*!< Definition for the Kceicv. */ + CC_BSV_PROV_KEY = 0xf, /*!< Definition for the Kcp. */ + CC_BSV_END_OF_KEY_TYPE = INT32_MAX, /*!< Reserved. */ +}CCBsvKeyType_t; + +/*! AES directions. */ +typedef enum bsvAesDirection { + BSV_AES_DIRECTION_ENCRYPT = 0, /*!< Encrypt.*/ + BSV_AES_DIRECTION_DECRYPT = 1, /*!< Decrypt.*/ + BSV_AES_NUM_OF_ENCRYPT_MODES, /*!< The maximal number of operations. */ + BSV_AES_DIRECTION_RESERVE32B = INT32_MAX /*!< Reserved.*/ +}bsvAesDirection_t; + +/*! Definitions of the cryptographic flow supported as part of the Secure Boot. */ +typedef enum { + CC_BSV_CRYPTO_HASH_MODE = 0, /*!< Hash mode only. */ + CC_BSV_CRYPTO_AES_CTR_AND_HASH_MODE = 1, /*!< Data goes into the AES and Hash engines. */ + CC_BSV_CRYPTO_AES_CTR_TO_HASH_MODE = 2 /*!< Data goes into the AES and from the AES to the Hash engine. */ +}CCBsvflowMode_t; + +/*! CryptoImage HW completion sequence mode */ +typedef enum +{ + BSV_CRYPTO_COMPLETION_NO_WAIT = 0, /*!< The driver waits only before reading the output. */ + BSV_CRYPTO_COMPLETION_WAIT_UPON_END = 1 /*!< The driver waits after each chunk of data. */ +}bsvCryptoCompletionMode_t; + + +/*! AES-CMAC result size, in words. */ +#define CC_BSV_CMAC_RESULT_SIZE_IN_WORDS 4 /* 128b */ +/*! AES-CMAC result size, in bytes. */ +#define CC_BSV_CMAC_RESULT_SIZE_IN_BYTES 16 /* 128b */ +/*! AES-CCM 128bit key size, in bytes. */ +#define CC_BSV_CCM_KEY_SIZE_BYTES 16 +/*! AES-CCM 128bit key size, in words. */ +#define CC_BSV_CCM_KEY_SIZE_WORDS 4 +/*! AES-CCM NONCE size, in bytes. */ +#define CC_BSV_CCM_NONCE_SIZE_BYTES 12 + + +/*! AES-CMAC result buffer. */ +typedef uint32_t CCBsvCmacResult_t[CC_BSV_CMAC_RESULT_SIZE_IN_WORDS]; +/*! AES-CCM key buffer.*/ +typedef uint32_t CCBsvCcmKey_t[CC_BSV_CCM_KEY_SIZE_WORDS]; +/*! AES-CCM nonce buffer.*/ +typedef uint8_t CCBsvCcmNonce_t[CC_BSV_CCM_NONCE_SIZE_BYTES]; +/*! AES-CCM MAC buffer.*/ +typedef uint8_t CCBsvCcmMacRes_t[CC_BSV_CMAC_RESULT_SIZE_IN_BYTES]; + + +#ifdef __cplusplus +} +#endif + +#endif + +/** +@} + */ + diff --git a/include/drivers/arm/cryptocell/713/bsv_error.h b/include/drivers/arm/cryptocell/713/bsv_error.h new file mode 100644 index 000000000..4d72e60aa --- /dev/null +++ b/include/drivers/arm/cryptocell/713/bsv_error.h @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2017-2020 ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _BSV_ERROR_H +#define _BSV_ERROR_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*! +@file +@brief This file defines the error code types that are returned from the Boot Services APIs. + +@defgroup cc_bsv_error CryptoCell Boot Services error codes +@{ +@ingroup cc_bsv +*/ + +/*! Defines the base address for Boot Services errors. */ +#define CC_BSV_BASE_ERROR 0x0B000000 +/*! Defines the base address for Boot Services cryptographic errors. */ +#define CC_BSV_CRYPTO_ERROR 0x0C000000 + +/*! Illegal input parameter. */ +#define CC_BSV_ILLEGAL_INPUT_PARAM_ERR (CC_BSV_BASE_ERROR + 0x00000001) +/*! Illegal HUK value. */ +#define CC_BSV_ILLEGAL_HUK_VALUE_ERR (CC_BSV_BASE_ERROR + 0x00000002) +/*! Illegal Kcp value. */ +#define CC_BSV_ILLEGAL_KCP_VALUE_ERR (CC_BSV_BASE_ERROR + 0x00000003) +/*! Illegal Kce value. */ +#define CC_BSV_ILLEGAL_KCE_VALUE_ERR (CC_BSV_BASE_ERROR + 0x00000004) +/*! Illegal Kpicv value. */ +#define CC_BSV_ILLEGAL_KPICV_VALUE_ERR (CC_BSV_BASE_ERROR + 0x00000005) +/*! Illegal Kceicv value. */ +#define CC_BSV_ILLEGAL_KCEICV_VALUE_ERR (CC_BSV_BASE_ERROR + 0x00000006) +/*! Illegal EKcst value. */ +#define CC_BSV_ILLEGAL_EKCST_VALUE_ERR (CC_BSV_BASE_ERROR + 0x00000007) +/*! Hash boot key not programmed in the OTP. */ +#define CC_BSV_HASH_NOT_PROGRAMMED_ERR (CC_BSV_BASE_ERROR + 0x00000008) +/*! Illegal Hash boot key zero count in the OTP. */ +#define CC_BSV_HBK_ZERO_COUNT_ERR (CC_BSV_BASE_ERROR + 0x00000009) +/*! Illegal LCS. */ +#define CC_BSV_ILLEGAL_LCS_ERR (CC_BSV_BASE_ERROR + 0x0000000A) +/*! OTP write compare failure. */ +#define CC_BSV_OTP_WRITE_CMP_FAIL_ERR (CC_BSV_BASE_ERROR + 0x0000000B) +/*! OTP access error */ +#define CC_BSV_OTP_ACCESS_ERR (CC_BSV_BASE_ERROR + 0x0000000C) +/*! Erase key in OTP failed. */ +#define CC_BSV_ERASE_KEY_FAILED_ERR (CC_BSV_BASE_ERROR + 0x0000000D) +/*! Illegal PIDR. */ +#define CC_BSV_ILLEGAL_PIDR_ERR (CC_BSV_BASE_ERROR + 0x0000000E) +/*! Illegal CIDR. */ +#define CC_BSV_ILLEGAL_CIDR_ERR (CC_BSV_BASE_ERROR + 0x0000000F) +/*! Device failed to move to fatal error state. */ +#define CC_BSV_FAILED_TO_SET_FATAL_ERR (CC_BSV_BASE_ERROR + 0x00000010) +/*! Failed to set RMA LCS. */ +#define CC_BSV_FAILED_TO_SET_RMA_ERR (CC_BSV_BASE_ERROR + 0x00000011) +/*! Illegal RMA indication. */ +#define CC_BSV_ILLEGAL_RMA_INDICATION_ERR (CC_BSV_BASE_ERROR + 0x00000012) +/*! Boot Services version is not initialized. */ +#define CC_BSV_VER_IS_NOT_INITIALIZED_ERR (CC_BSV_BASE_ERROR + 0x00000013) +/*! APB secure mode is locked. */ +#define CC_BSV_APB_SECURE_IS_LOCKED_ERR (CC_BSV_BASE_ERROR + 0x00000014) +/*! APB privilege mode is locked. */ +#define CC_BSV_APB_PRIVILEG_IS_LOCKED_ERR (CC_BSV_BASE_ERROR + 0x00000015) +/*! Illegal operation. */ +#define CC_BSV_ILLEGAL_OPERATION_ERR (CC_BSV_BASE_ERROR + 0x00000016) +/*! Illegal asset size. */ +#define CC_BSV_ILLEGAL_ASSET_SIZE_ERR (CC_BSV_BASE_ERROR + 0x00000017) +/*! Illegal asset value. */ +#define CC_BSV_ILLEGAL_ASSET_VAL_ERR (CC_BSV_BASE_ERROR + 0x00000018) +/*! Kpicv is locked. */ +#define CC_BSV_KPICV_IS_LOCKED_ERR (CC_BSV_BASE_ERROR + 0x00000019) +/*! Illegal SW version. */ +#define CC_BSV_ILLEGAL_SW_VERSION_ERR (CC_BSV_BASE_ERROR + 0x0000001A) +/*! AO write operation. */ +#define CC_BSV_AO_WRITE_FAILED_ERR (CC_BSV_BASE_ERROR + 0x0000001B) +/*! Chip state is already initialized. */ +#define CC_BSV_CHIP_INITIALIZED_ERR (CC_BSV_BASE_ERROR + 0x0000001C) +/*! SP is not enabled. */ +#define CC_BSV_SP_NOT_ENABLED_ERR (CC_BSV_BASE_ERROR + 0x0000001D) +/*! Production secure provisioning - header fields. */ +#define CC_BSV_PROD_PKG_HEADER_ERR (CC_BSV_BASE_ERROR + 0x0000001E) +/*! Production secure provisioning - header MAC. */ +#define CC_BSV_PROD_PKG_HEADER_MAC_ERR (CC_BSV_BASE_ERROR + 0x0000001F) +/*! Overrun buffer or size. */ +#define CC_BSV_OVERRUN_ERR (CC_BSV_BASE_ERROR + 0x00000020) +/*! Kceicv is locked. */ +#define CC_BSV_KCEICV_IS_LOCKED_ERR (CC_BSV_BASE_ERROR + 0x00000021) +/*! Chip indication is CHIP_STATE_ERROR. */ +#define CC_BSV_CHIP_INDICATION_ERR (CC_BSV_BASE_ERROR + 0x00000022) +/*! Device is locked in fatal error state. */ +#define CC_BSV_FATAL_ERR_IS_LOCKED_ERR (CC_BSV_BASE_ERROR + 0x00000023) +/*! Device has security disable feature enabled. */ +#define CC_BSV_SECURE_DISABLE_ERROR (CC_BSV_BASE_ERROR + 0x00000024) +/*! Device has Kcst in disabled state */ +#define CC_BSV_KCST_DISABLE_ERROR (CC_BSV_BASE_ERROR + 0x00000025) + + +/*! Illegal data-in pointer. */ +#define CC_BSV_CRYPTO_INVALID_DATA_IN_POINTER_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000001) +/*! Illegal data-out pointer. */ +#define CC_BSV_CRYPTO_INVALID_DATA_OUT_POINTER_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000002) +/*! Illegal data size. */ +#define CC_BSV_CRYPTO_INVALID_DATA_SIZE_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000003) +/*! Illegal key type. */ +#define CC_BSV_CRYPTO_INVALID_KEY_TYPE_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000004) +/*! Illegal key size. */ +#define CC_BSV_CRYPTO_INVALID_KEY_SIZE_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000005) +/*! Invalid key pointer. */ +#define CC_BSV_CRYPTO_INVALID_KEY_POINTER_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000006) +/*! Illegal key DMA type. */ +#define CC_BSV_CRYPTO_INVALID_KEY_DMA_TYPE_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000007) +/*! Illegal IV pointer. */ +#define CC_BSV_CRYPTO_INVALID_IV_POINTER_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000008) +/*! Illegal cipher mode. */ +#define CC_BSV_CRYPTO_INVALID_CIPHER_MODE_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000009) +/*! Illegal result buffer pointer. */ +#define CC_BSV_CRYPTO_INVALID_RESULT_BUFFER_POINTER_ERROR (CC_BSV_CRYPTO_ERROR + 0x0000000A) +/*! Invalid DMA type. */ +#define CC_BSV_CRYPTO_INVALID_DMA_TYPE_ERROR (CC_BSV_CRYPTO_ERROR + 0x0000000B) +/*! Invalid in/out buffers overlapping. */ +#define CC_BSV_CRYPTO_DATA_OUT_DATA_IN_OVERLAP_ERROR (CC_BSV_CRYPTO_ERROR + 0x0000000C) +/*! Invalid KDF label size. */ +#define CC_BSV_CRYPTO_ILLEGAL_KDF_LABEL_ERROR (CC_BSV_CRYPTO_ERROR + 0x0000000D) +/*! Invalid KDF Context size. */ +#define CC_BSV_CRYPTO_ILLEGAL_KDF_CONTEXT_ERROR (CC_BSV_CRYPTO_ERROR + 0x0000000E) +/*! Invalid CCM key. */ +#define CC_BSV_CCM_INVALID_KEY_ERROR (CC_BSV_CRYPTO_ERROR + 0x0000000f) +/*! Invalid CCM Nonce. */ +#define CC_BSV_CCM_INVALID_NONCE_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000010) +/*! Invalid CCM associated data. */ +#define CC_BSV_CCM_INVALID_ASSOC_DATA_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000011) +/*! Invalid CCM text data. */ +#define CC_BSV_CCM_INVALID_TEXT_DATA_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000012) +/*! Invalid CCM-MAC buffer. */ +#define CC_BSV_CCM_INVALID_MAC_BUF_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000013) +/*! CCM-MAC comparison failed. */ +#define CC_BSV_CCM_TAG_LENGTH_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000014) +/*! CCM-MAC comparison failed. */ +#define CC_BSV_CCM_MAC_INVALID_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000015) +/*! Illegal flow mode. */ +#define CC_BSV_CRYPTO_INVALID_FLOW_MODE_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000016) + +#ifdef __cplusplus +} +#endif + +#endif + +/** +@} + */ + + + diff --git a/include/drivers/arm/cryptocell/713/cc_address_defs.h b/include/drivers/arm/cryptocell/713/cc_address_defs.h new file mode 100644 index 000000000..0abc15c70 --- /dev/null +++ b/include/drivers/arm/cryptocell/713/cc_address_defs.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2017-2020 ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _CC_ADDRESS_DEFS_H +#define _CC_ADDRESS_DEFS_H + +/*! +@file +@brief This file contains general definitions. +*/ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "cc_pal_types.h" + +/************************ Defines ******************************/ + +/** + * Address types within CC + */ +/*! Definition of DMA address type, can be 32 bits or 64 bits according to CryptoCell's HW. */ +typedef uint64_t CCDmaAddr_t; +/*! Definition of CryptoCell address type, can be 32 bits or 64 bits according to platform. */ +typedef uint64_t CCAddr_t; +/*! Definition of CC SRAM address type, can be 32 bits according to CryptoCell's HW. */ +typedef uint32_t CCSramAddr_t; + +/* + * CCSramAddr_t is being cast into pointer type which can be 64 bit. + */ +/*! Definition of MACRO that casts SRAM addresses to pointer types. */ +#define CCSramAddr2Ptr(sramAddr) ((uintptr_t)sramAddr) + +#ifdef __cplusplus +} +#endif + +#endif + +/** + @} + */ + + diff --git a/include/drivers/arm/cryptocell/713/cc_boot_defs.h b/include/drivers/arm/cryptocell/713/cc_boot_defs.h new file mode 100644 index 000000000..4d29a6d00 --- /dev/null +++ b/include/drivers/arm/cryptocell/713/cc_boot_defs.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2017-2020 ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _CC_BOOT_DEFS_H +#define _CC_BOOT_DEFS_H + +/*! + @file + @brief This file contains general definitions of types and enums of Boot APIs. + */ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*! Version counters value. */ +typedef enum { + + CC_SW_VERSION_TRUSTED = 0, /*!< Trusted counter. */ + CC_SW_VERSION_NON_TRUSTED, /*!< Non trusted counter. */ + CC_SW_VERSION_MAX = 0x7FFFFFFF /*!< Reserved */ +} CCSbSwVersionId_t; + +/*! The hash boot key definition. */ +typedef enum { + CC_SB_HASH_BOOT_KEY_0_128B = 0, /*!< Hbk0: 128-bit truncated SHA-256 digest of PubKB0. Used by ICV */ + CC_SB_HASH_BOOT_KEY_1_128B = 1, /*!< Hbk1: 128-bit truncated SHA-256 digest of PubKB1. Used by OEM */ + CC_SB_HASH_BOOT_KEY_256B = 2, /*!< Hbk: 256-bit SHA-256 digest of public key. */ + CC_SB_HASH_BOOT_NOT_USED = 0xF, /*!< Hbk is not used. */ + CC_SB_HASH_MAX_NUM = 0x7FFFFFFF, /*!< Reserved. */ +} CCSbPubKeyIndexType_t; + +/*! Chip state. */ +typedef enum { + CHIP_STATE_NOT_INITIALIZED = 0, /*! Chip is not initialized. */ + CHIP_STATE_TEST = 1, /*! Chip is in Production state. */ + CHIP_STATE_PRODUCTION = 2, /*! Chip is in Production state. */ + CHIP_STATE_ERROR = 3, /*! Chip is in Error state. */ +} CCBsvChipState_t; +#ifdef __cplusplus +} +#endif + +#endif /*_CC_BOOT_DEFS_H */ + +/** +@} + */ diff --git a/include/drivers/arm/cryptocell/713/cc_pal_types.h b/include/drivers/arm/cryptocell/713/cc_pal_types.h new file mode 100644 index 000000000..4ab3960d3 --- /dev/null +++ b/include/drivers/arm/cryptocell/713/cc_pal_types.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2017-2020 ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CC_PAL_TYPES_H +#define CC_PAL_TYPES_H + +/*! +@file +@brief This file contains platform-dependent definitions and types of the PAL layer. + +@defgroup cc_pal_types CryptoCell platform-dependent PAL layer definitions and types +@{ +@ingroup cc_pal + + @{ + @ingroup cc_pal + @} +*/ + +#include "cc_pal_types_plat.h" + +/*! Definition of Boolean type.*/ +typedef enum { + /*! Boolean false.*/ + CC_FALSE = 0, + /*! Boolean true.*/ + CC_TRUE = 1 +} CCBool_t; + +/*! Success. */ +#define CC_SUCCESS 0UL +/*! Failure. */ +#define CC_FAIL 1UL + +/*! Success (OK). */ +#define CC_OK 0 + +/*! This macro handles unused parameters in the code, to avoid compilation warnings. */ +#define CC_UNUSED_PARAM(prm) ((void)prm) + +/*! The maximal uint32 value.*/ +#define CC_MAX_UINT32_VAL (0xFFFFFFFF) + + +/* Minimal and Maximal macros */ +#ifdef min +/*! Definition for minimal calculation. */ +#define CC_MIN(a,b) min( a , b ) +#else +/*! Definition for minimal calculation. */ +#define CC_MIN( a , b ) ( ( (a) < (b) ) ? (a) : (b) ) +#endif + +#ifdef max +/*! Definition for maximal calculation. */ +#define CC_MAX(a,b) max( a , b ) +#else +/*! Definition for maximal calculation.. */ +#define CC_MAX( a , b ) ( ( (a) > (b) ) ? (a) : (b) ) +#endif + +/*! This macro calculates the number of full Bytes from bits, where seven bits are one Byte. */ +#define CALC_FULL_BYTES(numBits) ((numBits)/CC_BITS_IN_BYTE + (((numBits) & (CC_BITS_IN_BYTE-1)) > 0)) +/*! This macro calculates the number of full 32-bit words from bits where 31 bits are one word. */ +#define CALC_FULL_32BIT_WORDS(numBits) ((numBits)/CC_BITS_IN_32BIT_WORD + (((numBits) & (CC_BITS_IN_32BIT_WORD-1)) > 0)) +/*! This macro calculates the number of full 32-bit words from Bytes where three Bytes are one word. */ +#define CALC_32BIT_WORDS_FROM_BYTES(sizeBytes) ((sizeBytes)/CC_32BIT_WORD_SIZE + (((sizeBytes) & (CC_32BIT_WORD_SIZE-1)) > 0)) +/*! This macro calculates the number of full 32-bit words from 64-bits dwords. */ +#define CALC_32BIT_WORDS_FROM_64BIT_DWORD(sizeWords) (sizeWords * CC_32BIT_WORD_IN_64BIT_DWORD) +/*! This macro rounds up bits to 32-bit words. */ +#define ROUNDUP_BITS_TO_32BIT_WORD(numBits) (CALC_FULL_32BIT_WORDS(numBits) * CC_BITS_IN_32BIT_WORD) +/*! This macro rounds up bits to Bytes. */ +#define ROUNDUP_BITS_TO_BYTES(numBits) (CALC_FULL_BYTES(numBits) * CC_BITS_IN_BYTE) +/*! This macro rounds up bytes to 32-bit words. */ +#define ROUNDUP_BYTES_TO_32BIT_WORD(sizeBytes) (CALC_32BIT_WORDS_FROM_BYTES(sizeBytes) * CC_32BIT_WORD_SIZE) +/*! This macro calculates the number Bytes from words. */ +#define CALC_WORDS_TO_BYTES(numwords) ((numwords)*CC_32BIT_WORD_SIZE) +/*! Definition of 1 KB in Bytes. */ +#define CC_1K_SIZE_IN_BYTES 1024 +/*! Definition of number of bits in a Byte. */ +#define CC_BITS_IN_BYTE 8 +/*! Definition of number of bits in a 32-bits word. */ +#define CC_BITS_IN_32BIT_WORD 32 +/*! Definition of number of Bytes in a 32-bits word. */ +#define CC_32BIT_WORD_SIZE 4 +/*! Definition of number of 32-bits words in a 64-bits dword. */ +#define CC_32BIT_WORD_IN_64BIT_DWORD 2 + + +#endif + +/** +@} + */ + + + diff --git a/include/drivers/arm/cryptocell/713/cc_pal_types_plat.h b/include/drivers/arm/cryptocell/713/cc_pal_types_plat.h new file mode 100644 index 000000000..984847217 --- /dev/null +++ b/include/drivers/arm/cryptocell/713/cc_pal_types_plat.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/*! @file +@brief This file contains basic type definitions that are platform-dependent. +*/ +#ifndef _CC_PAL_TYPES_PLAT_H +#define _CC_PAL_TYPES_PLAT_H +/* Host specific types for standard (ISO-C99) compilant platforms */ + +#include +#include + +typedef uint32_t CCStatus; + +#define CCError_t CCStatus +#define CC_INFINITE 0xFFFFFFFF + +#define CEXPORT_C +#define CIMPORT_C + +#endif /*_CC_PAL_TYPES_PLAT_H*/ diff --git a/include/drivers/arm/cryptocell/713/cc_pka_hw_plat_defs.h b/include/drivers/arm/cryptocell/713/cc_pka_hw_plat_defs.h new file mode 100644 index 000000000..1a1bce0ab --- /dev/null +++ b/include/drivers/arm/cryptocell/713/cc_pka_hw_plat_defs.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2017-2020 ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _CC_PKA_HW_PLAT_DEFS_H +#define _CC_PKA_HW_PLAT_DEFS_H + +#ifdef __cplusplus +extern "C" +{ +#endif + + +#include "cc_pal_types.h" +/*! +@file +@brief Contains the enums and definitions that are used in the PKA code (definitions that are platform dependent). +*/ + +/*! The size of the PKA engine word. */ +#define CC_PKA_WORD_SIZE_IN_BITS 128 + +/*! The maximal supported size of modulus in RSA in bits. */ +#define CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS 4096 +/*! The maximal supported size of key-generation in RSA in bits. */ +#define CC_RSA_MAX_KEY_GENERATION_HW_SIZE_BITS 4096 + +/*! Secure boot/debug certificate RSA public modulus key size in bits. */ +#if (KEY_SIZE == 3072) + #define BSV_CERT_RSA_KEY_SIZE_IN_BITS 3072 +#else + #define BSV_CERT_RSA_KEY_SIZE_IN_BITS 2048 +#endif +/*! Secure boot/debug certificate RSA public modulus key size in bytes. */ +#define BSV_CERT_RSA_KEY_SIZE_IN_BYTES (BSV_CERT_RSA_KEY_SIZE_IN_BITS/CC_BITS_IN_BYTE) +/*! Secure boot/debug certificate RSA public modulus key size in words. */ +#define BSV_CERT_RSA_KEY_SIZE_IN_WORDS (BSV_CERT_RSA_KEY_SIZE_IN_BITS/CC_BITS_IN_32BIT_WORD) + +/*! The maximal count of extra bits in PKA operations. */ +#define PKA_EXTRA_BITS 8 +/*! The number of memory registers in PKA operations. */ +#define PKA_MAX_COUNT_OF_PHYS_MEM_REGS 32 + +/*! Size of buffer for Barrett modulus tag in words. */ +#define RSA_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS 5 +/*! Size of buffer for Barrett modulus tag in bytes. */ +#define RSA_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_BYTES (RSA_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS*CC_32BIT_WORD_SIZE) + + + +#ifdef __cplusplus +} +#endif + +#endif //_CC_PKA_HW_PLAT_DEFS_H + +/** + @} + */ + diff --git a/include/drivers/arm/cryptocell/713/cc_sec_defs.h b/include/drivers/arm/cryptocell/713/cc_sec_defs.h new file mode 100644 index 000000000..8fb698ff5 --- /dev/null +++ b/include/drivers/arm/cryptocell/713/cc_sec_defs.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2017-2020 ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _CC_SEC_DEFS_H +#define _CC_SEC_DEFS_H + +/*! +@file +@brief This file contains general definitions and types. +*/ + + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "cc_pal_types.h" + +/*! Hashblock size in words. */ +#define HASH_BLOCK_SIZE_IN_WORDS 16 +/*! Hash - SHA2 results in words. */ +#define HASH_RESULT_SIZE_IN_WORDS 8 +/*! Hash - SHA2 results in bytes. */ +#define HASH_RESULT_SIZE_IN_BYTES 32 + +/*! Definition for hash result array. */ +typedef uint32_t CCHashResult_t[HASH_RESULT_SIZE_IN_WORDS]; + +/*! Definition for converting pointer to Host address. */ +#define CONVERT_TO_ADDR(ptr) (unsigned long)ptr + +/*! Definition for converting pointer to SRAM address. */ +#define CONVERT_TO_SRAM_ADDR(ptr) (0xFFFFFFFF & ptr) + +/*! The data size of the signed SW image, in bytes. */ +/*!\internal ContentCertImageRecord_t includes: HS(8W) + 64-b dstAddr(2W) + imgSize(1W) + isCodeEncUsed(1W) */ +#define SW_REC_SIGNED_DATA_SIZE_IN_BYTES 48 + +/*! The data size of the unsigned SW image, in bytes. */ +/*!\internal CCSbSwImgAddData_t includes: 64-b srcAddr(2W)*/ +#define SW_REC_NONE_SIGNED_DATA_SIZE_IN_BYTES 8 + +/*! The additional data size - storage address and length of the unsigned SW image, in words. */ +#define SW_REC_NONE_SIGNED_DATA_SIZE_IN_WORDS SW_REC_NONE_SIGNED_DATA_SIZE_IN_BYTES/CC_32BIT_WORD_SIZE + +/*! The additional data section size, in bytes. */ +#define CC_SB_MAX_SIZE_ADDITIONAL_DATA_BYTES 128 + +/*! Indication of whether or not to load the SW image to memory. */ +#define CC_SW_COMP_NO_MEM_LOAD_INDICATION 0xFFFFFFFFFFFFFFFFUL + +/*! Indication of product version, stored in certificate version field. */ +#define CC_SB_CERT_VERSION_PROJ_PRD 0x713 + +#ifdef __cplusplus +} +#endif + +#endif + +/** +@} + */ + + + -- cgit v1.2.3 From 25d819a308faba6190ca18cce3ec4ed7c783b6c9 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Wed, 1 Apr 2020 09:55:49 -0700 Subject: include: fixup 'cm_setup_context' prototype This patch changes the prototype cm_setup_context() to use struct entry_point_info rather than the typedef'ed version of it. This fixes the following compilation error seen with EL3_EXCEPTION_HANDLING = 1. In file included from bl31/ehf.c:19: include/lib/el3_runtime/context_mgmt.h:35:49: error: unknown type name 'entry_point_info_t' 35 | void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep); | ^~~~~~~~~~~~~~~~~~ Signed-off-by: Varun Wadekar Change-Id: I73b059ff2dade2259cefd0f9a097c7ea4a88055d --- include/lib/el3_runtime/context_mgmt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/lib/el3_runtime/context_mgmt.h b/include/lib/el3_runtime/context_mgmt.h index b36cd3d70..2090687ee 100644 --- a/include/lib/el3_runtime/context_mgmt.h +++ b/include/lib/el3_runtime/context_mgmt.h @@ -32,7 +32,7 @@ void cm_set_context(void *context, uint32_t security_state); void cm_init_my_context(const struct entry_point_info *ep); void cm_init_context_by_index(unsigned int cpu_idx, const struct entry_point_info *ep); -void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep); +void cm_setup_context(cpu_context_t *ctx, const struct entry_point_info *ep); void cm_prepare_el3_exit(uint32_t security_state); #ifdef __aarch64__ -- cgit v1.2.3 From adb20a1755c98325d5d94b127014bf5a6c5b4b50 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Tue, 31 Mar 2020 18:42:59 -0700 Subject: Tegra: enable EHF for watchdog timer interrupts This patch enables the Exception Handling Framework to service the WDT interrupts on all Tegra platforms. Verified that the watchdog timer interrupt fires after migrating to the EHF. Signed-off-by: Varun Wadekar Change-Id: I6b2e33da7841aa064e3a8f825c26fadf168cd0d5 --- plat/nvidia/tegra/common/tegra_fiq_glue.c | 42 +++++++++++-------------------- plat/nvidia/tegra/include/platform_def.h | 5 ++++ plat/nvidia/tegra/platform.mk | 4 +++ plat/nvidia/tegra/soc/t186/plat_setup.c | 4 +-- plat/nvidia/tegra/soc/t194/plat_setup.c | 4 +-- plat/nvidia/tegra/soc/t210/plat_setup.c | 4 +-- 6 files changed, 30 insertions(+), 33 deletions(-) diff --git a/plat/nvidia/tegra/common/tegra_fiq_glue.c b/plat/nvidia/tegra/common/tegra_fiq_glue.c index dee99fb13..bb5add819 100644 --- a/plat/nvidia/tegra/common/tegra_fiq_glue.c +++ b/plat/nvidia/tegra/common/tegra_fiq_glue.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -25,6 +26,15 @@ /* Legacy FIQ used by earlier Tegra platforms */ #define LEGACY_FIQ_PPI_WDT 28U +/* Install priority level descriptors for each dispatcher */ +ehf_pri_desc_t plat_exceptions[] = { + EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_TEGRA_WDT_PRIO), +}; + +/* Expose priority descriptors to Exception Handling Framework */ +EHF_REGISTER_PRIORITIES(plat_exceptions, ARRAY_SIZE(plat_exceptions), + PLAT_PRI_BITS); + /******************************************************************************* * Static variables ******************************************************************************/ @@ -35,26 +45,17 @@ static pcpu_fiq_state_t fiq_state[PLATFORM_CORE_COUNT]; /******************************************************************************* * Handler for FIQ interrupts ******************************************************************************/ -static uint64_t tegra_fiq_interrupt_handler(uint32_t id, - uint32_t flags, - void *handle, - void *cookie) +static int tegra_fiq_interrupt_handler(unsigned int id, unsigned int flags, + void *handle, void *cookie) { cpu_context_t *ctx = cm_get_context(NON_SECURE); el3_state_t *el3state_ctx = get_el3state_ctx(ctx); uint32_t cpu = plat_my_core_pos(); - uint32_t irq; - (void)id; (void)flags; (void)handle; (void)cookie; - /* - * Read the pending interrupt ID - */ - irq = plat_ic_get_pending_interrupt_id(); - /* * Jump to NS world only if the NS world's FIQ handler has * been registered @@ -90,7 +91,7 @@ static uint64_t tegra_fiq_interrupt_handler(uint32_t id, * disable the routing so that we can mark it as "complete" in the * GIC later. */ - if (irq == LEGACY_FIQ_PPI_WDT) { + if (id == LEGACY_FIQ_PPI_WDT) { tegra_fc_disable_fiq_to_ccplex_routing(); } #endif @@ -98,10 +99,7 @@ static uint64_t tegra_fiq_interrupt_handler(uint32_t id, /* * Mark this interrupt as complete to avoid a FIQ storm. */ - if (irq < 1022U) { - (void)plat_ic_acknowledge_interrupt(); - plat_ic_end_of_interrupt(irq); - } + plat_ic_end_of_interrupt(id); return 0; } @@ -111,23 +109,13 @@ static uint64_t tegra_fiq_interrupt_handler(uint32_t id, ******************************************************************************/ void tegra_fiq_handler_setup(void) { - uint32_t flags; - int32_t rc; - /* return if already registered */ if (fiq_handler_active == 0U) { /* * Register an interrupt handler for FIQ interrupts generated for * NS interrupt sources */ - flags = 0U; - set_interrupt_rm_flag((flags), (NON_SECURE)); - rc = register_interrupt_type_handler(INTR_TYPE_EL3, - tegra_fiq_interrupt_handler, - flags); - if (rc != 0) { - panic(); - } + ehf_register_priority_handler(PLAT_TEGRA_WDT_PRIO, tegra_fiq_interrupt_handler); /* handler is now active */ fiq_handler_active = 1; diff --git a/plat/nvidia/tegra/include/platform_def.h b/plat/nvidia/tegra/include/platform_def.h index 91a24ca7e..6bfad23e6 100644 --- a/plat/nvidia/tegra/include/platform_def.h +++ b/plat/nvidia/tegra/include/platform_def.h @@ -86,5 +86,10 @@ #define MAX_IO_DEVICES U(0) #define MAX_IO_HANDLES U(0) +/******************************************************************************* + * Platform macros to support exception handling framework + ******************************************************************************/ +#define PLAT_PRI_BITS U(3) +#define PLAT_TEGRA_WDT_PRIO U(0x40) #endif /* PLATFORM_DEF_H */ diff --git a/plat/nvidia/tegra/platform.mk b/plat/nvidia/tegra/platform.mk index 87588202c..e03e1f37b 100644 --- a/plat/nvidia/tegra/platform.mk +++ b/plat/nvidia/tegra/platform.mk @@ -20,6 +20,10 @@ $(eval $(call add_define,PLAT_LOG_LEVEL_ASSERT)) PLAT_XLAT_TABLES_DYNAMIC := 1 $(eval $(call add_define,PLAT_XLAT_TABLES_DYNAMIC)) +# Enable exception handling at EL3 +EL3_EXCEPTION_HANDLING := 1 +GICV2_G0_FOR_EL3 := 1 + # Enable PSCI v1.0 extended state ID format PSCI_EXTENDED_STATE_ID := 1 diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c index e5d0d0133..1c7c25d0f 100644 --- a/plat/nvidia/tegra/soc/t186/plat_setup.c +++ b/plat/nvidia/tegra/soc/t186/plat_setup.c @@ -214,9 +214,9 @@ void plat_late_platform_setup(void) /* Secure IRQs for Tegra186 */ static const interrupt_prop_t tegra186_interrupt_props[] = { - INTR_PROP_DESC(TEGRA186_TOP_WDT_IRQ, GIC_HIGHEST_SEC_PRIORITY, + INTR_PROP_DESC(TEGRA186_TOP_WDT_IRQ, PLAT_TEGRA_WDT_PRIO, GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE), - INTR_PROP_DESC(TEGRA186_AON_WDT_IRQ, GIC_HIGHEST_SEC_PRIORITY, + INTR_PROP_DESC(TEGRA186_AON_WDT_IRQ, PLAT_TEGRA_WDT_PRIO, GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE) }; diff --git a/plat/nvidia/tegra/soc/t194/plat_setup.c b/plat/nvidia/tegra/soc/t194/plat_setup.c index 82555403e..f90a69e27 100644 --- a/plat/nvidia/tegra/soc/t194/plat_setup.c +++ b/plat/nvidia/tegra/soc/t194/plat_setup.c @@ -275,9 +275,9 @@ void plat_early_platform_setup(void) /* Secure IRQs for Tegra194 */ static const interrupt_prop_t tegra194_interrupt_props[] = { - INTR_PROP_DESC(TEGRA194_TOP_WDT_IRQ, GIC_HIGHEST_SEC_PRIORITY, + INTR_PROP_DESC(TEGRA194_TOP_WDT_IRQ, PLAT_TEGRA_WDT_PRIO, GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE), - INTR_PROP_DESC(TEGRA194_AON_WDT_IRQ, GIC_HIGHEST_SEC_PRIORITY, + INTR_PROP_DESC(TEGRA194_AON_WDT_IRQ, PLAT_TEGRA_WDT_PRIO, GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE) }; diff --git a/plat/nvidia/tegra/soc/t210/plat_setup.c b/plat/nvidia/tegra/soc/t210/plat_setup.c index 6d014bf2c..930eeac3a 100644 --- a/plat/nvidia/tegra/soc/t210/plat_setup.c +++ b/plat/nvidia/tegra/soc/t210/plat_setup.c @@ -179,9 +179,9 @@ void plat_early_platform_setup(void) /* Secure IRQs for Tegra186 */ static const interrupt_prop_t tegra210_interrupt_props[] = { - INTR_PROP_DESC(TEGRA210_TIMER1_IRQ, GIC_HIGHEST_SEC_PRIORITY, + INTR_PROP_DESC(TEGRA210_TIMER1_IRQ, PLAT_TEGRA_WDT_PRIO, GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE), - INTR_PROP_DESC(TEGRA210_WDT_CPU_LEGACY_FIQ, GIC_HIGHEST_SEC_PRIORITY, + INTR_PROP_DESC(TEGRA210_WDT_CPU_LEGACY_FIQ, PLAT_TEGRA_WDT_PRIO, GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE), }; -- cgit v1.2.3 From 9fb288a03ed2ced7706defbbf78f008e921e17e2 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 26 Mar 2020 10:51:39 +0900 Subject: linker_script: move more common code to bl_common.ld.h These are mostly used to collect data from special structure, and repeated in many linker scripts. To differentiate the alignment size between aarch32/aarch64, I added a new macro STRUCT_ALIGN. While I moved the PMF_SVC_DESCS, I dropped #if ENABLE_PMF conditional. As you can see in include/lib/pmf/pmf_helpers.h, PMF_REGISTER_SERVICE* are no-op when ENABLE_PMF=0. So, pmf_svc_descs and pmf_timestamp_array data are not populated. Change-Id: I3f4ab7fa18f76339f1789103407ba76bda7e56d0 Signed-off-by: Masahiro Yamada --- bl1/bl1.ld.S | 34 ++--------- bl2/bl2.ld.S | 26 ++------ bl2/bl2_el3.ld.S | 56 ++--------------- bl31/bl31.ld.S | 136 ++++------------------------------------- bl32/sp_min/sp_min.ld.S | 99 +++--------------------------- bl32/tsp/tsp.ld.S | 21 +------ include/common/bl_common.ld.h | 112 +++++++++++++++++++++++++++++++++ plat/mediatek/mt6795/bl31.ld.S | 41 +------------ 8 files changed, 152 insertions(+), 373 deletions(-) diff --git a/bl1/bl1.ld.S b/bl1/bl1.ld.S index e65ab9004..87f1ae82f 100644 --- a/bl1/bl1.ld.S +++ b/bl1/bl1.ld.S @@ -4,8 +4,6 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include - #include #include @@ -47,20 +45,8 @@ SECTIONS __RODATA_START__ = .; *(SORT_BY_ALIGNMENT(.rodata*)) - /* Ensure 8-byte alignment for descriptors and ensure inclusion */ - . = ALIGN(8); - __PARSER_LIB_DESCS_START__ = .; - KEEP(*(.img_parser_lib_descs)) - __PARSER_LIB_DESCS_END__ = .; - - /* - * Ensure 8-byte alignment for cpu_ops so that its fields are also - * aligned. Also ensure cpu_ops inclusion. - */ - . = ALIGN(8); - __CPU_OPS_START__ = .; - KEEP(*(cpu_ops)) - __CPU_OPS_END__ = .; + PARSER_LIB_DESCS + CPU_OPS /* * No need to pad out the .rodata section to a page boundary. Next is @@ -81,20 +67,8 @@ SECTIONS *(SORT_BY_ALIGNMENT(.text*)) *(SORT_BY_ALIGNMENT(.rodata*)) - /* Ensure 8-byte alignment for descriptors and ensure inclusion */ - . = ALIGN(8); - __PARSER_LIB_DESCS_START__ = .; - KEEP(*(.img_parser_lib_descs)) - __PARSER_LIB_DESCS_END__ = .; - - /* - * Ensure 8-byte alignment for cpu_ops so that its fields are also - * aligned. Also ensure cpu_ops inclusion. - */ - . = ALIGN(8); - __CPU_OPS_START__ = .; - KEEP(*(cpu_ops)) - __CPU_OPS_END__ = .; + PARSER_LIB_DESCS + CPU_OPS *(.vectors) __RO_END__ = .; diff --git a/bl2/bl2.ld.S b/bl2/bl2.ld.S index d08b046e9..afb013390 100644 --- a/bl2/bl2.ld.S +++ b/bl2/bl2.ld.S @@ -4,8 +4,6 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include - #include #include @@ -47,16 +45,8 @@ SECTIONS __RODATA_START__ = .; *(SORT_BY_ALIGNMENT(.rodata*)) - . = ALIGN(8); - __FCONF_POPULATOR_START__ = .; - KEEP(*(.fconf_populator)) - __FCONF_POPULATOR_END__ = .; - - /* Ensure 8-byte alignment for descriptors and ensure inclusion */ - . = ALIGN(8); - __PARSER_LIB_DESCS_START__ = .; - KEEP(*(.img_parser_lib_descs)) - __PARSER_LIB_DESCS_END__ = .; + FCONF_POPULATOR + PARSER_LIB_DESCS . = ALIGN(PAGE_SIZE); __RODATA_END__ = .; @@ -68,16 +58,8 @@ SECTIONS *(SORT_BY_ALIGNMENT(.text*)) *(SORT_BY_ALIGNMENT(.rodata*)) - . = ALIGN(8); - __FCONF_POPULATOR_START__ = .; - KEEP(*(.fconf_populator)) - __FCONF_POPULATOR_END__ = .; - - /* Ensure 8-byte alignment for descriptors and ensure inclusion */ - . = ALIGN(8); - __PARSER_LIB_DESCS_START__ = .; - KEEP(*(.img_parser_lib_descs)) - __PARSER_LIB_DESCS_END__ = .; + FCONF_POPULATOR + PARSER_LIB_DESCS *(.vectors) __RO_END_UNALIGNED__ = .; diff --git a/bl2/bl2_el3.ld.S b/bl2/bl2_el3.ld.S index a72818c99..d23799029 100644 --- a/bl2/bl2_el3.ld.S +++ b/bl2/bl2_el3.ld.S @@ -4,8 +4,6 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include - #include #include @@ -55,30 +53,9 @@ SECTIONS __RODATA_START__ = .; *(SORT_BY_ALIGNMENT(.rodata*)) - /* Ensure 8-byte alignment for descriptors and ensure inclusion */ - . = ALIGN(8); - __PARSER_LIB_DESCS_START__ = .; - KEEP(*(.img_parser_lib_descs)) - __PARSER_LIB_DESCS_END__ = .; - - /* - * Ensure 8-byte alignment for cpu_ops so that its fields are also - * aligned. Also ensure cpu_ops inclusion. - */ - . = ALIGN(8); - __CPU_OPS_START__ = .; - KEEP(*(cpu_ops)) - __CPU_OPS_END__ = .; - - /* - * Keep the .got section in the RO section as it is patched - * prior to enabling the MMU and having the .got in RO is better for - * security. GOT is a table of addresses so ensure 8-byte alignment. - */ - . = ALIGN(8); - __GOT_START__ = .; - *(.got) - __GOT_END__ = .; + PARSER_LIB_DESCS + CPU_OPS + GOT . = ALIGN(PAGE_SIZE); __RODATA_END__ = .; @@ -96,30 +73,9 @@ SECTIONS *(SORT_BY_ALIGNMENT(.text*)) *(SORT_BY_ALIGNMENT(.rodata*)) - /* - * Ensure 8-byte alignment for cpu_ops so that its fields are also - * aligned. Also ensure cpu_ops inclusion. - */ - . = ALIGN(8); - __CPU_OPS_START__ = .; - KEEP(*(cpu_ops)) - __CPU_OPS_END__ = .; - - /* Ensure 8-byte alignment for descriptors and ensure inclusion */ - . = ALIGN(8); - __PARSER_LIB_DESCS_START__ = .; - KEEP(*(.img_parser_lib_descs)) - __PARSER_LIB_DESCS_END__ = .; - - /* - * Keep the .got section in the RO section as it is patched - * prior to enabling the MMU and having the .got in RO is better for - * security. GOT is a table of addresses so ensure 8-byte alignment. - */ - . = ALIGN(8); - __GOT_START__ = .; - *(.got) - __GOT_END__ = .; + CPU_OPS + PARSER_LIB_DESCS + GOT *(.vectors) __RO_END_UNALIGNED__ = .; diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S index 5f9f9df5b..6b7f9157a 100644 --- a/bl31/bl31.ld.S +++ b/bl31/bl31.ld.S @@ -4,8 +4,6 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include - #include #include @@ -49,43 +47,11 @@ SECTIONS __RODATA_START__ = .; *(SORT_BY_ALIGNMENT(.rodata*)) - /* Ensure 8-byte alignment for descriptors and ensure inclusion */ - . = ALIGN(8); - __RT_SVC_DESCS_START__ = .; - KEEP(*(rt_svc_descs)) - __RT_SVC_DESCS_END__ = .; - - . = ALIGN(8); - __FCONF_POPULATOR_START__ = .; - KEEP(*(.fconf_populator)) - __FCONF_POPULATOR_END__ = .; - -#if ENABLE_PMF - /* Ensure 8-byte alignment for descriptors and ensure inclusion */ - . = ALIGN(8); - __PMF_SVC_DESCS_START__ = .; - KEEP(*(pmf_svc_descs)) - __PMF_SVC_DESCS_END__ = .; -#endif /* ENABLE_PMF */ - - /* - * Ensure 8-byte alignment for cpu_ops so that its fields are also - * aligned. Also ensure cpu_ops inclusion. - */ - . = ALIGN(8); - __CPU_OPS_START__ = .; - KEEP(*(cpu_ops)) - __CPU_OPS_END__ = .; - - /* - * Keep the .got section in the RO section as it is patched - * prior to enabling the MMU and having the .got in RO is better for - * security. GOT is a table of addresses so ensure 8-byte alignment. - */ - . = ALIGN(8); - __GOT_START__ = .; - *(.got) - __GOT_END__ = .; + RT_SVC_DESCS + FCONF_POPULATOR + PMF_SVC_DESCS + CPU_OPS + GOT /* Place pubsub sections for events */ . = ALIGN(8); @@ -101,43 +67,11 @@ SECTIONS *(SORT_BY_ALIGNMENT(.text*)) *(SORT_BY_ALIGNMENT(.rodata*)) - /* Ensure 8-byte alignment for descriptors and ensure inclusion */ - . = ALIGN(8); - __RT_SVC_DESCS_START__ = .; - KEEP(*(rt_svc_descs)) - __RT_SVC_DESCS_END__ = .; - - . = ALIGN(8); - __FCONF_POPULATOR_START__ = .; - KEEP(*(.fconf_populator)) - __FCONF_POPULATOR_END__ = .; - -#if ENABLE_PMF - /* Ensure 8-byte alignment for descriptors and ensure inclusion */ - . = ALIGN(8); - __PMF_SVC_DESCS_START__ = .; - KEEP(*(pmf_svc_descs)) - __PMF_SVC_DESCS_END__ = .; -#endif /* ENABLE_PMF */ - - /* - * Ensure 8-byte alignment for cpu_ops so that its fields are also - * aligned. Also ensure cpu_ops inclusion. - */ - . = ALIGN(8); - __CPU_OPS_START__ = .; - KEEP(*(cpu_ops)) - __CPU_OPS_END__ = .; - - /* - * Keep the .got section in the RO section as it is patched - * prior to enabling the MMU and having the .got in RO is better for - * security. GOT is a table of addresses so ensure 8-byte alignment. - */ - . = ALIGN(8); - __GOT_START__ = .; - *(.got) - __GOT_END__ = .; + RT_SVC_DESCS + FCONF_POPULATOR + PMF_SVC_DESCS + CPU_OPS + GOT /* Place pubsub sections for events */ . = ALIGN(8); @@ -247,54 +181,8 @@ SECTIONS __BSS_START__ = .; *(SORT_BY_ALIGNMENT(.bss*)) *(COMMON) -#if !USE_COHERENT_MEM - /* - * Bakery locks are stored in normal .bss memory - * - * Each lock's data is spread across multiple cache lines, one per CPU, - * but multiple locks can share the same cache line. - * The compiler will allocate enough memory for one CPU's bakery locks, - * the remaining cache lines are allocated by the linker script - */ - . = ALIGN(CACHE_WRITEBACK_GRANULE); - __BAKERY_LOCK_START__ = .; - __PERCPU_BAKERY_LOCK_START__ = .; - *(bakery_lock) - . = ALIGN(CACHE_WRITEBACK_GRANULE); - __PERCPU_BAKERY_LOCK_END__ = .; - __PERCPU_BAKERY_LOCK_SIZE__ = ABSOLUTE(__PERCPU_BAKERY_LOCK_END__ - __PERCPU_BAKERY_LOCK_START__); - . = . + (__PERCPU_BAKERY_LOCK_SIZE__ * (PLATFORM_CORE_COUNT - 1)); - __BAKERY_LOCK_END__ = .; - - /* - * If BL31 doesn't use any bakery lock then __PERCPU_BAKERY_LOCK_SIZE__ - * will be zero. For this reason, the only two valid values for - * __PERCPU_BAKERY_LOCK_SIZE__ are 0 or the platform defined value - * PLAT_PERCPU_BAKERY_LOCK_SIZE. - */ -#ifdef PLAT_PERCPU_BAKERY_LOCK_SIZE - ASSERT((__PERCPU_BAKERY_LOCK_SIZE__ == 0) || (__PERCPU_BAKERY_LOCK_SIZE__ == PLAT_PERCPU_BAKERY_LOCK_SIZE), - "PLAT_PERCPU_BAKERY_LOCK_SIZE does not match bakery lock requirements"); -#endif -#endif - -#if ENABLE_PMF - /* - * Time-stamps are stored in normal .bss memory - * - * The compiler will allocate enough memory for one CPU's time-stamps, - * the remaining memory for other CPUs is allocated by the - * linker script - */ - . = ALIGN(CACHE_WRITEBACK_GRANULE); - __PMF_TIMESTAMP_START__ = .; - KEEP(*(pmf_timestamp_array)) - . = ALIGN(CACHE_WRITEBACK_GRANULE); - __PMF_PERCPU_TIMESTAMP_END__ = .; - __PERCPU_TIMESTAMP_SIZE__ = ABSOLUTE(. - __PMF_TIMESTAMP_START__); - . = . + (__PERCPU_TIMESTAMP_SIZE__ * (PLATFORM_CORE_COUNT - 1)); - __PMF_TIMESTAMP_END__ = .; -#endif /* ENABLE_PMF */ + BAKERY_LOCK_NORMAL + PMF_TIMESTAMP __BSS_END__ = .; } >NOBITS diff --git a/bl32/sp_min/sp_min.ld.S b/bl32/sp_min/sp_min.ld.S index 66f3b113d..d83b4e018 100644 --- a/bl32/sp_min/sp_min.ld.S +++ b/bl32/sp_min/sp_min.ld.S @@ -4,8 +4,6 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include - #include #include @@ -50,33 +48,10 @@ SECTIONS __RODATA_START__ = .; *(.rodata*) - /* Ensure 4-byte alignment for descriptors and ensure inclusion */ - . = ALIGN(4); - __RT_SVC_DESCS_START__ = .; - KEEP(*(rt_svc_descs)) - __RT_SVC_DESCS_END__ = .; - - . = ALIGN(4); - __FCONF_POPULATOR_START__ = .; - KEEP(*(.fconf_populator)) - __FCONF_POPULATOR_END__ = .; - -#if ENABLE_PMF - /* Ensure 4-byte alignment for descriptors and ensure inclusion */ - . = ALIGN(4); - __PMF_SVC_DESCS_START__ = .; - KEEP(*(pmf_svc_descs)) - __PMF_SVC_DESCS_END__ = .; -#endif /* ENABLE_PMF */ - - /* - * Ensure 4-byte alignment for cpu_ops so that its fields are also - * aligned. Also ensure cpu_ops inclusion. - */ - . = ALIGN(4); - __CPU_OPS_START__ = .; - KEEP(*(cpu_ops)) - __CPU_OPS_END__ = .; + RT_SVC_DESCS + FCONF_POPULATOR + PMF_SVC_DESCS + CPU_OPS /* Place pubsub sections for events */ . = ALIGN(8); @@ -92,25 +67,9 @@ SECTIONS *(.text*) *(.rodata*) - /* Ensure 4-byte alignment for descriptors and ensure inclusion */ - . = ALIGN(4); - __RT_SVC_DESCS_START__ = .; - KEEP(*(rt_svc_descs)) - __RT_SVC_DESCS_END__ = .; - - . = ALIGN(4); - __FCONF_POPULATOR_START__ = .; - KEEP(*(.fconf_populator)) - __FCONF_POPULATOR_END__ = .; - - /* - * Ensure 4-byte alignment for cpu_ops so that its fields are also - * aligned. Also ensure cpu_ops inclusion. - */ - . = ALIGN(4); - __CPU_OPS_START__ = .; - KEEP(*(cpu_ops)) - __CPU_OPS_END__ = .; + RT_SVC_DESCS + FCONF_POPULATOR + CPU_OPS /* Place pubsub sections for events */ . = ALIGN(8); @@ -162,48 +121,8 @@ SECTIONS __BSS_START__ = .; *(.bss*) *(COMMON) -#if !USE_COHERENT_MEM - /* - * Bakery locks are stored in normal .bss memory - * - * Each lock's data is spread across multiple cache lines, one per CPU, - * but multiple locks can share the same cache line. - * The compiler will allocate enough memory for one CPU's bakery locks, - * the remaining cache lines are allocated by the linker script - */ - . = ALIGN(CACHE_WRITEBACK_GRANULE); - __BAKERY_LOCK_START__ = .; - __PERCPU_BAKERY_LOCK_START__ = .; - *(bakery_lock) - . = ALIGN(CACHE_WRITEBACK_GRANULE); - __PERCPU_BAKERY_LOCK_END__ = .; - __PERCPU_BAKERY_LOCK_SIZE__ = ABSOLUTE(__PERCPU_BAKERY_LOCK_END__ - __PERCPU_BAKERY_LOCK_START__); - . = . + (__PERCPU_BAKERY_LOCK_SIZE__ * (PLATFORM_CORE_COUNT - 1)); - __BAKERY_LOCK_END__ = .; -#ifdef PLAT_PERCPU_BAKERY_LOCK_SIZE - ASSERT(__PERCPU_BAKERY_LOCK_SIZE__ == PLAT_PERCPU_BAKERY_LOCK_SIZE, - "PLAT_PERCPU_BAKERY_LOCK_SIZE does not match bakery lock requirements"); -#endif -#endif - -#if ENABLE_PMF - /* - * Time-stamps are stored in normal .bss memory - * - * The compiler will allocate enough memory for one CPU's time-stamps, - * the remaining memory for other CPUs is allocated by the - * linker script - */ - . = ALIGN(CACHE_WRITEBACK_GRANULE); - __PMF_TIMESTAMP_START__ = .; - KEEP(*(pmf_timestamp_array)) - . = ALIGN(CACHE_WRITEBACK_GRANULE); - __PMF_PERCPU_TIMESTAMP_END__ = .; - __PERCPU_TIMESTAMP_SIZE__ = ABSOLUTE(. - __PMF_TIMESTAMP_START__); - . = . + (__PERCPU_TIMESTAMP_SIZE__ * (PLATFORM_CORE_COUNT - 1)); - __PMF_TIMESTAMP_END__ = .; -#endif /* ENABLE_PMF */ - + BAKERY_LOCK_NORMAL + PMF_TIMESTAMP __BSS_END__ = .; } >RAM diff --git a/bl32/tsp/tsp.ld.S b/bl32/tsp/tsp.ld.S index da60c63a7..b1ec42350 100644 --- a/bl32/tsp/tsp.ld.S +++ b/bl32/tsp/tsp.ld.S @@ -6,7 +6,6 @@ #include #include -#include OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT) OUTPUT_ARCH(PLATFORM_LINKER_ARCH) @@ -38,15 +37,7 @@ SECTIONS __RODATA_START__ = .; *(.rodata*) - /* - * Keep the .got section in the RO section as it is patched - * prior to enabling the MMU and having the .got in RO is better for - * security. GOT is a table of addresses so ensure 8-byte alignment. - */ - . = ALIGN(8); - __GOT_START__ = .; - *(.got) - __GOT_END__ = .; + GOT . = ALIGN(PAGE_SIZE); __RODATA_END__ = .; @@ -58,15 +49,7 @@ SECTIONS *(.text*) *(.rodata*) - /* - * Keep the .got section in the RO section as it is patched - * prior to enabling the MMU and having the .got in RO is better for - * security. GOT is a table of addresses so ensure 8-byte alignment. - */ - . = ALIGN(8); - __GOT_START__ = .; - *(.got) - __GOT_END__ = .; + GOT *(.vectors) diff --git a/include/common/bl_common.ld.h b/include/common/bl_common.ld.h index 32c54b4d2..d9e2e015f 100644 --- a/include/common/bl_common.ld.h +++ b/include/common/bl_common.ld.h @@ -7,6 +7,118 @@ #ifndef BL_COMMON_LD_H #define BL_COMMON_LD_H +#include + +#ifdef __aarch64__ +#define STRUCT_ALIGN 8 +#else +#define STRUCT_ALIGN 4 +#endif + +#define CPU_OPS \ + . = ALIGN(STRUCT_ALIGN); \ + __CPU_OPS_START__ = .; \ + KEEP(*(cpu_ops)) \ + __CPU_OPS_END__ = .; + +#define PARSER_LIB_DESCS \ + . = ALIGN(STRUCT_ALIGN); \ + __PARSER_LIB_DESCS_START__ = .; \ + KEEP(*(.img_parser_lib_descs)) \ + __PARSER_LIB_DESCS_END__ = .; + +#define RT_SVC_DESCS \ + . = ALIGN(STRUCT_ALIGN); \ + __RT_SVC_DESCS_START__ = .; \ + KEEP(*(rt_svc_descs)) \ + __RT_SVC_DESCS_END__ = .; + +#define PMF_SVC_DESCS \ + . = ALIGN(STRUCT_ALIGN); \ + __PMF_SVC_DESCS_START__ = .; \ + KEEP(*(pmf_svc_descs)) \ + __PMF_SVC_DESCS_END__ = .; + +#define FCONF_POPULATOR \ + . = ALIGN(STRUCT_ALIGN); \ + __FCONF_POPULATOR_START__ = .; \ + KEEP(*(.fconf_populator)) \ + __FCONF_POPULATOR_END__ = .; + +/* + * Keep the .got section in the RO section as it is patched prior to enabling + * the MMU and having the .got in RO is better for security. GOT is a table of + * addresses so ensure pointer size alignment. + */ +#define GOT \ + . = ALIGN(STRUCT_ALIGN); \ + __GOT_START__ = .; \ + *(.got) \ + __GOT_END__ = .; + +#define STACK_SECTION \ + stacks (NOLOAD) : { \ + __STACKS_START__ = .; \ + *(tzfw_normal_stacks) \ + __STACKS_END__ = .; \ + } + +/* + * If BL doesn't use any bakery lock then __PERCPU_BAKERY_LOCK_SIZE__ + * will be zero. For this reason, the only two valid values for + * __PERCPU_BAKERY_LOCK_SIZE__ are 0 or the platform defined value + * PLAT_PERCPU_BAKERY_LOCK_SIZE. + */ +#ifdef PLAT_PERCPU_BAKERY_LOCK_SIZE +#define BAKERY_LOCK_SIZE_CHECK \ + ASSERT((__PERCPU_BAKERY_LOCK_SIZE__ == 0) || \ + (__PERCPU_BAKERY_LOCK_SIZE__ == PLAT_PERCPU_BAKERY_LOCK_SIZE), \ + "PLAT_PERCPU_BAKERY_LOCK_SIZE does not match bakery lock requirements"); +#else +#define BAKERY_LOCK_SIZE_CHECK +#endif + +/* + * Bakery locks are stored in normal .bss memory + * + * Each lock's data is spread across multiple cache lines, one per CPU, + * but multiple locks can share the same cache line. + * The compiler will allocate enough memory for one CPU's bakery locks, + * the remaining cache lines are allocated by the linker script + */ +#if !USE_COHERENT_MEM +#define BAKERY_LOCK_NORMAL \ + . = ALIGN(CACHE_WRITEBACK_GRANULE); \ + __BAKERY_LOCK_START__ = .; \ + __PERCPU_BAKERY_LOCK_START__ = .; \ + *(bakery_lock) \ + . = ALIGN(CACHE_WRITEBACK_GRANULE); \ + __PERCPU_BAKERY_LOCK_END__ = .; \ + __PERCPU_BAKERY_LOCK_SIZE__ = ABSOLUTE(__PERCPU_BAKERY_LOCK_END__ - __PERCPU_BAKERY_LOCK_START__); \ + . = . + (__PERCPU_BAKERY_LOCK_SIZE__ * (PLATFORM_CORE_COUNT - 1)); \ + __BAKERY_LOCK_END__ = .; \ + BAKERY_LOCK_SIZE_CHECK +#else +#define BAKERY_LOCK_NORMAL +#endif + +/* + * Time-stamps are stored in normal .bss memory + * + * The compiler will allocate enough memory for one CPU's time-stamps, + * the remaining memory for other CPUs is allocated by the + * linker script + */ +#define PMF_TIMESTAMP \ + . = ALIGN(CACHE_WRITEBACK_GRANULE); \ + __PMF_TIMESTAMP_START__ = .; \ + KEEP(*(pmf_timestamp_array)) \ + . = ALIGN(CACHE_WRITEBACK_GRANULE); \ + __PMF_PERCPU_TIMESTAMP_END__ = .; \ + __PERCPU_TIMESTAMP_SIZE__ = ABSOLUTE(. - __PMF_TIMESTAMP_START__); \ + . = . + (__PERCPU_TIMESTAMP_SIZE__ * (PLATFORM_CORE_COUNT - 1)); \ + __PMF_TIMESTAMP_END__ = .; + /* * The xlat_table section is for full, aligned page tables (4K). * Removing them from .bss avoids forcing 4K alignment on diff --git a/plat/mediatek/mt6795/bl31.ld.S b/plat/mediatek/mt6795/bl31.ld.S index 0fd38664c..03a737f69 100644 --- a/plat/mediatek/mt6795/bl31.ld.S +++ b/plat/mediatek/mt6795/bl31.ld.S @@ -6,7 +6,6 @@ #include #include -#include OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT) OUTPUT_ARCH(PLATFORM_LINKER_ARCH) @@ -39,20 +38,8 @@ SECTIONS *(.text*) *(.rodata*) - /* Ensure 8-byte alignment for descriptors and ensure inclusion */ - . = ALIGN(8); - __RT_SVC_DESCS_START__ = .; - KEEP(*(rt_svc_descs)) - __RT_SVC_DESCS_END__ = .; - - /* - * Ensure 8-byte alignment for cpu_ops so that its fields are also - * aligned. Also ensure cpu_ops inclusion. - */ - . = ALIGN(8); - __CPU_OPS_START__ = .; - KEEP(*(cpu_ops)) - __CPU_OPS_END__ = .; + RT_SVC_DESCS + CPU_OPS __RO_END_UNALIGNED__ = .; /* @@ -103,29 +90,7 @@ SECTIONS __BSS_START__ = .; *(.bss*) *(COMMON) -#if !USE_COHERENT_MEM - /* - * Bakery locks are stored in normal .bss memory - * - * Each lock's data is spread across multiple cache lines, one per CPU, - * but multiple locks can share the same cache line. - * The compiler will allocate enough memory for one CPU's bakery locks, - * the remaining cache lines are allocated by the linker script - */ - . = ALIGN(CACHE_WRITEBACK_GRANULE); - __BAKERY_LOCK_START__ = .; - __PERCPU_BAKERY_LOCK_START__ = .; - *(bakery_lock) - . = ALIGN(CACHE_WRITEBACK_GRANULE); - __PERCPU_BAKERY_LOCK_END__ = .; - __PERCPU_BAKERY_LOCK_SIZE__ = ABSOLUTE(__PERCPU_BAKERY_LOCK_END__ - __PERCPU_BAKERY_LOCK_START__); - . = . + (__PERCPU_BAKERY_LOCK_SIZE__ * (PLATFORM_CORE_COUNT - 1)); - __BAKERY_LOCK_END__ = .; -#ifdef PLAT_PERCPU_BAKERY_LOCK_SIZE - ASSERT(__PERCPU_BAKERY_LOCK_SIZE__ == PLAT_PERCPU_BAKERY_LOCK_SIZE, - "PLAT_PERCPU_BAKERY_LOCK_SIZE does not match bakery lock requirements"); -#endif -#endif + BAKERY_LOCK_NORMAL __BSS_END__ = .; __RW_END__ = .; } >RAM -- cgit v1.2.3 From 0a0a7a9ac82cb79af91f098cedc69cc67bca3978 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 26 Mar 2020 10:57:12 +0900 Subject: linker_script: replace common read-only data with RODATA_COMMON The common section data are repeated in many linker scripts (often twice in each script to support SEPARATE_CODE_AND_RODATA). When you add a new read-only data section, you end up with touching lots of places. After this commit, you will only need to touch bl_common.ld.h when you add a new section to RODATA_COMMON. Replace a series of RO section with RODATA_COMMON, which contains 6 sections, some of which did not exist before. This is not a big deal because unneeded data should not be compiled in the first place. I believe this should be controlled by BL*_SOURCES in Makefiles, not by linker scripts. When I was working on this commit, the BL1 image size increased due to the fconf_populator. Commit c452ba159c14 ("fconf: exclude fconf_dyn_cfg_getter.c from BL1_SOURCES") fixed this issue. I investigated BL1, BL2, BL2U, BL31 for plat=fvp, and BL2-AT-EL3, BL31, BL31 for plat=uniphier. I did not see any more unexpected code addition. Change-Id: I5d14d60dbe3c821765bce3ae538968ef266f1460 Signed-off-by: Masahiro Yamada --- bl1/bl1.ld.S | 6 ++---- bl2/bl2.ld.S | 6 ++---- bl2/bl2_el3.ld.S | 8 ++------ bl2u/bl2u.ld.S | 5 +++++ bl31/bl31.ld.S | 12 ++---------- bl32/sp_min/sp_min.ld.S | 9 ++------- bl32/tsp/tsp.ld.S | 4 ++-- include/common/bl_common.ld.h | 8 ++++++++ plat/mediatek/mt6795/bl31.ld.S | 3 +-- 9 files changed, 26 insertions(+), 35 deletions(-) diff --git a/bl1/bl1.ld.S b/bl1/bl1.ld.S index 87f1ae82f..e706ce286 100644 --- a/bl1/bl1.ld.S +++ b/bl1/bl1.ld.S @@ -45,8 +45,7 @@ SECTIONS __RODATA_START__ = .; *(SORT_BY_ALIGNMENT(.rodata*)) - PARSER_LIB_DESCS - CPU_OPS + RODATA_COMMON /* * No need to pad out the .rodata section to a page boundary. Next is @@ -67,8 +66,7 @@ SECTIONS *(SORT_BY_ALIGNMENT(.text*)) *(SORT_BY_ALIGNMENT(.rodata*)) - PARSER_LIB_DESCS - CPU_OPS + RODATA_COMMON *(.vectors) __RO_END__ = .; diff --git a/bl2/bl2.ld.S b/bl2/bl2.ld.S index afb013390..dc5165280 100644 --- a/bl2/bl2.ld.S +++ b/bl2/bl2.ld.S @@ -45,8 +45,7 @@ SECTIONS __RODATA_START__ = .; *(SORT_BY_ALIGNMENT(.rodata*)) - FCONF_POPULATOR - PARSER_LIB_DESCS + RODATA_COMMON . = ALIGN(PAGE_SIZE); __RODATA_END__ = .; @@ -58,8 +57,7 @@ SECTIONS *(SORT_BY_ALIGNMENT(.text*)) *(SORT_BY_ALIGNMENT(.rodata*)) - FCONF_POPULATOR - PARSER_LIB_DESCS + RODATA_COMMON *(.vectors) __RO_END_UNALIGNED__ = .; diff --git a/bl2/bl2_el3.ld.S b/bl2/bl2_el3.ld.S index d23799029..3c2744369 100644 --- a/bl2/bl2_el3.ld.S +++ b/bl2/bl2_el3.ld.S @@ -53,9 +53,7 @@ SECTIONS __RODATA_START__ = .; *(SORT_BY_ALIGNMENT(.rodata*)) - PARSER_LIB_DESCS - CPU_OPS - GOT + RODATA_COMMON . = ALIGN(PAGE_SIZE); __RODATA_END__ = .; @@ -73,9 +71,7 @@ SECTIONS *(SORT_BY_ALIGNMENT(.text*)) *(SORT_BY_ALIGNMENT(.rodata*)) - CPU_OPS - PARSER_LIB_DESCS - GOT + RODATA_COMMON *(.vectors) __RO_END_UNALIGNED__ = .; diff --git a/bl2u/bl2u.ld.S b/bl2u/bl2u.ld.S index 96545a3ab..37e658ad3 100644 --- a/bl2u/bl2u.ld.S +++ b/bl2u/bl2u.ld.S @@ -46,6 +46,9 @@ SECTIONS .rodata . : { __RODATA_START__ = .; *(SORT_BY_ALIGNMENT(.rodata*)) + + RODATA_COMMON + . = ALIGN(PAGE_SIZE); __RODATA_END__ = .; } >RAM @@ -56,6 +59,8 @@ SECTIONS *(SORT_BY_ALIGNMENT(.text*)) *(SORT_BY_ALIGNMENT(.rodata*)) + RODATA_COMMON + *(.vectors) __RO_END_UNALIGNED__ = .; /* diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S index 6b7f9157a..ac99a7de4 100644 --- a/bl31/bl31.ld.S +++ b/bl31/bl31.ld.S @@ -47,11 +47,7 @@ SECTIONS __RODATA_START__ = .; *(SORT_BY_ALIGNMENT(.rodata*)) - RT_SVC_DESCS - FCONF_POPULATOR - PMF_SVC_DESCS - CPU_OPS - GOT + RODATA_COMMON /* Place pubsub sections for events */ . = ALIGN(8); @@ -67,11 +63,7 @@ SECTIONS *(SORT_BY_ALIGNMENT(.text*)) *(SORT_BY_ALIGNMENT(.rodata*)) - RT_SVC_DESCS - FCONF_POPULATOR - PMF_SVC_DESCS - CPU_OPS - GOT + RODATA_COMMON /* Place pubsub sections for events */ . = ALIGN(8); diff --git a/bl32/sp_min/sp_min.ld.S b/bl32/sp_min/sp_min.ld.S index d83b4e018..f652f17e2 100644 --- a/bl32/sp_min/sp_min.ld.S +++ b/bl32/sp_min/sp_min.ld.S @@ -48,10 +48,7 @@ SECTIONS __RODATA_START__ = .; *(.rodata*) - RT_SVC_DESCS - FCONF_POPULATOR - PMF_SVC_DESCS - CPU_OPS + RODATA_COMMON /* Place pubsub sections for events */ . = ALIGN(8); @@ -67,9 +64,7 @@ SECTIONS *(.text*) *(.rodata*) - RT_SVC_DESCS - FCONF_POPULATOR - CPU_OPS + RODATA_COMMON /* Place pubsub sections for events */ . = ALIGN(8); diff --git a/bl32/tsp/tsp.ld.S b/bl32/tsp/tsp.ld.S index b1ec42350..b071e82fd 100644 --- a/bl32/tsp/tsp.ld.S +++ b/bl32/tsp/tsp.ld.S @@ -37,7 +37,7 @@ SECTIONS __RODATA_START__ = .; *(.rodata*) - GOT + RODATA_COMMON . = ALIGN(PAGE_SIZE); __RODATA_END__ = .; @@ -49,7 +49,7 @@ SECTIONS *(.text*) *(.rodata*) - GOT + RODATA_COMMON *(.vectors) diff --git a/include/common/bl_common.ld.h b/include/common/bl_common.ld.h index d9e2e015f..5c5fe5b15 100644 --- a/include/common/bl_common.ld.h +++ b/include/common/bl_common.ld.h @@ -56,6 +56,14 @@ *(.got) \ __GOT_END__ = .; +#define RODATA_COMMON \ + RT_SVC_DESCS \ + FCONF_POPULATOR \ + PMF_SVC_DESCS \ + PARSER_LIB_DESCS \ + CPU_OPS \ + GOT + #define STACK_SECTION \ stacks (NOLOAD) : { \ __STACKS_START__ = .; \ diff --git a/plat/mediatek/mt6795/bl31.ld.S b/plat/mediatek/mt6795/bl31.ld.S index 03a737f69..02d79af38 100644 --- a/plat/mediatek/mt6795/bl31.ld.S +++ b/plat/mediatek/mt6795/bl31.ld.S @@ -38,8 +38,7 @@ SECTIONS *(.text*) *(.rodata*) - RT_SVC_DESCS - CPU_OPS + RODATA_COMMON __RO_END_UNALIGNED__ = .; /* -- cgit v1.2.3 From a7739bc7b16bf3e43f370864f8a800cf8943b391 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 26 Mar 2020 13:16:33 +0900 Subject: linker_script: move bss section to bl_common.ld.h Move the bss section to the common header. This adds BAKERY_LOCK_NORMAL and PMF_TIMESTAMP, which previously existed only in BL31. This is not a big deal because unused data should not be compiled in the first place. I believe this should be controlled by BL*_SOURCES in Makefiles, not by linker scripts. I investigated BL1, BL2, BL2U, BL31 for plat=fvp, and BL2-AT-EL3, BL31, BL31 for plat=uniphier. I did not see any more unexpected code addition. The bss section has bigger alignment. I added BSS_ALIGN for this. Currently, SORT_BY_ALIGNMENT() is missing in sp_min.ld.S, and with this change, the BSS symbols in SP_MIN will be sorted by the alignment. This is not a big deal (or, even better in terms of the image size). Change-Id: I680ee61f84067a559bac0757f9d03e73119beb33 Signed-off-by: Masahiro Yamada --- bl1/bl1.ld.S | 13 +------------ bl2/bl2.ld.S | 13 +------------ bl2/bl2_el3.ld.S | 13 +------------ bl2u/bl2u.ld.S | 13 +------------ bl31/bl31.ld.S | 15 +-------------- bl32/sp_min/sp_min.ld.S | 15 +-------------- bl32/tsp/tsp.ld.S | 13 +------------ include/common/bl_common.ld.h | 18 ++++++++++++++++++ plat/mediatek/mt6795/bl31.ld.S | 15 ++------------- 9 files changed, 27 insertions(+), 101 deletions(-) diff --git a/bl1/bl1.ld.S b/bl1/bl1.ld.S index e706ce286..75355ebff 100644 --- a/bl1/bl1.ld.S +++ b/bl1/bl1.ld.S @@ -109,18 +109,7 @@ SECTIONS __STACKS_END__ = .; } >RAM - /* - * The .bss section gets initialised to 0 at runtime. - * Its base address should be 16-byte aligned for better performance of the - * zero-initialization code. - */ - .bss : ALIGN(16) { - __BSS_START__ = .; - *(SORT_BY_ALIGNMENT(.bss*)) - *(COMMON) - __BSS_END__ = .; - } >RAM - + BSS_SECTION >RAM XLAT_TABLE_SECTION >RAM #if USE_COHERENT_MEM diff --git a/bl2/bl2.ld.S b/bl2/bl2.ld.S index dc5165280..15df5dd03 100644 --- a/bl2/bl2.ld.S +++ b/bl2/bl2.ld.S @@ -94,18 +94,7 @@ SECTIONS __STACKS_END__ = .; } >RAM - /* - * The .bss section gets initialised to 0 at runtime. - * Its base address should be 16-byte aligned for better performance of the - * zero-initialization code. - */ - .bss : ALIGN(16) { - __BSS_START__ = .; - *(SORT_BY_ALIGNMENT(.bss*)) - *(COMMON) - __BSS_END__ = .; - } >RAM - + BSS_SECTION >RAM XLAT_TABLE_SECTION >RAM #if USE_COHERENT_MEM diff --git a/bl2/bl2_el3.ld.S b/bl2/bl2_el3.ld.S index 3c2744369..d04f226e9 100644 --- a/bl2/bl2_el3.ld.S +++ b/bl2/bl2_el3.ld.S @@ -129,18 +129,7 @@ SECTIONS __STACKS_END__ = .; } >RAM - /* - * The .bss section gets initialised to 0 at runtime. - * Its base address should be 16-byte aligned for better performance of the - * zero-initialization code. - */ - .bss : ALIGN(16) { - __BSS_START__ = .; - *(SORT_BY_ALIGNMENT(.bss*)) - *(COMMON) - __BSS_END__ = .; - } >RAM - + BSS_SECTION >RAM XLAT_TABLE_SECTION >RAM #if USE_COHERENT_MEM diff --git a/bl2u/bl2u.ld.S b/bl2u/bl2u.ld.S index 37e658ad3..8c0bbbdd0 100644 --- a/bl2u/bl2u.ld.S +++ b/bl2u/bl2u.ld.S @@ -96,18 +96,7 @@ SECTIONS __STACKS_END__ = .; } >RAM - /* - * The .bss section gets initialised to 0 at runtime. - * Its base address should be 16-byte aligned for better performance of the - * zero-initialization code. - */ - .bss : ALIGN(16) { - __BSS_START__ = .; - *(SORT_BY_ALIGNMENT(.bss*)) - *(COMMON) - __BSS_END__ = .; - } >RAM - + BSS_SECTION >RAM XLAT_TABLE_SECTION >RAM #if USE_COHERENT_MEM diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S index ac99a7de4..1cdf7c943 100644 --- a/bl31/bl31.ld.S +++ b/bl31/bl31.ld.S @@ -164,20 +164,7 @@ SECTIONS __STACKS_END__ = .; } >NOBITS - /* - * The .bss section gets initialised to 0 at runtime. - * Its base address should be 16-byte aligned for better performance of the - * zero-initialization code. - */ - .bss (NOLOAD) : ALIGN(16) { - __BSS_START__ = .; - *(SORT_BY_ALIGNMENT(.bss*)) - *(COMMON) - BAKERY_LOCK_NORMAL - PMF_TIMESTAMP - __BSS_END__ = .; - } >NOBITS - + BSS_SECTION >NOBITS XLAT_TABLE_SECTION >NOBITS #if USE_COHERENT_MEM diff --git a/bl32/sp_min/sp_min.ld.S b/bl32/sp_min/sp_min.ld.S index f652f17e2..da005db64 100644 --- a/bl32/sp_min/sp_min.ld.S +++ b/bl32/sp_min/sp_min.ld.S @@ -107,20 +107,7 @@ SECTIONS __STACKS_END__ = .; } >RAM - /* - * The .bss section gets initialised to 0 at runtime. - * Its base address should be 8-byte aligned for better performance of the - * zero-initialization code. - */ - .bss (NOLOAD) : ALIGN(8) { - __BSS_START__ = .; - *(.bss*) - *(COMMON) - BAKERY_LOCK_NORMAL - PMF_TIMESTAMP - __BSS_END__ = .; - } >RAM - + BSS_SECTION >RAM XLAT_TABLE_SECTION >RAM __BSS_SIZE__ = SIZEOF(.bss); diff --git a/bl32/tsp/tsp.ld.S b/bl32/tsp/tsp.ld.S index b071e82fd..bf77c9234 100644 --- a/bl32/tsp/tsp.ld.S +++ b/bl32/tsp/tsp.ld.S @@ -97,18 +97,7 @@ SECTIONS __STACKS_END__ = .; } >RAM - /* - * The .bss section gets initialised to 0 at runtime. - * Its base address should be 16-byte aligned for better performance of the - * zero-initialization code. - */ - .bss : ALIGN(16) { - __BSS_START__ = .; - *(SORT_BY_ALIGNMENT(.bss*)) - *(COMMON) - __BSS_END__ = .; - } >RAM - + BSS_SECTION >RAM XLAT_TABLE_SECTION >RAM #if USE_COHERENT_MEM diff --git a/include/common/bl_common.ld.h b/include/common/bl_common.ld.h index 5c5fe5b15..3fc8e970d 100644 --- a/include/common/bl_common.ld.h +++ b/include/common/bl_common.ld.h @@ -11,8 +11,10 @@ #ifdef __aarch64__ #define STRUCT_ALIGN 8 +#define BSS_ALIGN 16 #else #define STRUCT_ALIGN 4 +#define BSS_ALIGN 8 #endif #define CPU_OPS \ @@ -127,6 +129,22 @@ . = . + (__PERCPU_TIMESTAMP_SIZE__ * (PLATFORM_CORE_COUNT - 1)); \ __PMF_TIMESTAMP_END__ = .; + +/* + * The .bss section gets initialised to 0 at runtime. + * Its base address has bigger alignment for better performance of the + * zero-initialization code. + */ +#define BSS_SECTION \ + .bss (NOLOAD) : ALIGN(BSS_ALIGN) { \ + __BSS_START__ = .; \ + *(SORT_BY_ALIGNMENT(.bss*)) \ + *(COMMON) \ + BAKERY_LOCK_NORMAL \ + PMF_TIMESTAMP \ + __BSS_END__ = .; \ + } + /* * The xlat_table section is for full, aligned page tables (4K). * Removing them from .bss avoids forcing 4K alignment on diff --git a/plat/mediatek/mt6795/bl31.ld.S b/plat/mediatek/mt6795/bl31.ld.S index 02d79af38..b061b91ce 100644 --- a/plat/mediatek/mt6795/bl31.ld.S +++ b/plat/mediatek/mt6795/bl31.ld.S @@ -80,19 +80,8 @@ SECTIONS __STACKS_END__ = .; } >RAM - /* - * The .bss section gets initialised to 0 at runtime. - * Its base address should be 16-byte aligned for better performance of the - * zero-initialization code. - */ - .bss (NOLOAD) : ALIGN(16) { - __BSS_START__ = .; - *(.bss*) - *(COMMON) - BAKERY_LOCK_NORMAL - __BSS_END__ = .; - __RW_END__ = .; - } >RAM + BSS_SECTION >RAM + __RW_END__ = __BSS_END__; ASSERT(. <= BL31_LIMIT, "BL3-1 image has exceeded its limit.") -- cgit v1.2.3 From 268131c24fedb804589a2226d4adb3ef97cd8874 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 26 Mar 2020 13:18:48 +0900 Subject: xlat_tables_v2: fix assembler warning of PLAT_RO_XLAT_TABLES If PLAT_RO_XLAT_TABLES is defined, the base xlat table goes to the .rodata section instead of .bss section. This causes a warning like: /tmp/ccswitLr.s: Assembler messages: /tmp/ccswitLr.s:297: Warning: setting incorrect section attributes for .rodata It is practically no problem, but I want to keep the build log clean. Put the base table into the "base_xlat_table" section to suppress the assembler warnings. The linker script determines its final destination; rodata section if PLAT_RO_XLAT_TABLES=1, or bss section otherwise. So, the result is the same. Change-Id: Ic85d1d2dddd9b5339289fc2378cbcb21dd7db02e Signed-off-by: Masahiro Yamada --- include/common/bl_common.ld.h | 22 +++++++++++++++++++++- include/lib/xlat_tables/xlat_tables_v2.h | 9 ++------- lib/xlat_tables_v2/xlat_tables_context.c | 9 +-------- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/include/common/bl_common.ld.h b/include/common/bl_common.ld.h index 3fc8e970d..8ea7d6a8c 100644 --- a/include/common/bl_common.ld.h +++ b/include/common/bl_common.ld.h @@ -58,13 +58,32 @@ *(.got) \ __GOT_END__ = .; +/* + * The base xlat table + * + * It is put into the rodata section if PLAT_RO_XLAT_TABLES=1, + * or into the bss section otherwise. + */ +#define BASE_XLAT_TABLE \ + . = ALIGN(16); \ + *(base_xlat_table) + +#if PLAT_RO_XLAT_TABLES +#define BASE_XLAT_TABLE_RO BASE_XLAT_TABLE +#define BASE_XLAT_TABLE_BSS +#else +#define BASE_XLAT_TABLE_RO +#define BASE_XLAT_TABLE_BSS BASE_XLAT_TABLE +#endif + #define RODATA_COMMON \ RT_SVC_DESCS \ FCONF_POPULATOR \ PMF_SVC_DESCS \ PARSER_LIB_DESCS \ CPU_OPS \ - GOT + GOT \ + BASE_XLAT_TABLE_RO #define STACK_SECTION \ stacks (NOLOAD) : { \ @@ -142,6 +161,7 @@ *(COMMON) \ BAKERY_LOCK_NORMAL \ PMF_TIMESTAMP \ + BASE_XLAT_TABLE_BSS \ __BSS_END__ = .; \ } diff --git a/include/lib/xlat_tables/xlat_tables_v2.h b/include/lib/xlat_tables/xlat_tables_v2.h index ab311f4cb..9fe4a6e8a 100644 --- a/include/lib/xlat_tables/xlat_tables_v2.h +++ b/include/lib/xlat_tables/xlat_tables_v2.h @@ -164,20 +164,15 @@ typedef struct xlat_ctx xlat_ctx_t; * Would typically be PLAT_VIRT_ADDR_SPACE_SIZE * (resp. PLAT_PHY_ADDR_SPACE_SIZE) for the translation context describing the * BL image currently executing. - - * _base_table_section: - * Specify the name of the section where the base translation tables have to - * be placed by the linker. */ #define REGISTER_XLAT_CONTEXT(_ctx_name, _mmap_count, _xlat_tables_count, \ - _virt_addr_space_size, _phy_addr_space_size, \ - _base_table_section) \ + _virt_addr_space_size, _phy_addr_space_size) \ REGISTER_XLAT_CONTEXT_FULL_SPEC(_ctx_name, (_mmap_count), \ (_xlat_tables_count), \ (_virt_addr_space_size), \ (_phy_addr_space_size), \ EL_REGIME_INVALID, \ - "xlat_table", (_base_table_section)) + "xlat_table", "base_xlat_table") /* * Same as REGISTER_XLAT_CONTEXT plus the additional parameters: diff --git a/lib/xlat_tables_v2/xlat_tables_context.c b/lib/xlat_tables_v2/xlat_tables_context.c index 032e1424f..95dae88eb 100644 --- a/lib/xlat_tables_v2/xlat_tables_context.c +++ b/lib/xlat_tables_v2/xlat_tables_context.c @@ -25,15 +25,8 @@ uint64_t mmu_cfg_params[MMU_CFG_PARAM_MAX]; * Allocate and initialise the default translation context for the BL image * currently executing. */ -#if PLAT_RO_XLAT_TABLES -#define BASE_XLAT_TABLE_SECTION ".rodata" -#else -#define BASE_XLAT_TABLE_SECTION ".bss" -#endif - REGISTER_XLAT_CONTEXT(tf, MAX_MMAP_REGIONS, MAX_XLAT_TABLES, - PLAT_VIRT_ADDR_SPACE_SIZE, PLAT_PHY_ADDR_SPACE_SIZE, - BASE_XLAT_TABLE_SECTION); + PLAT_VIRT_ADDR_SPACE_SIZE, PLAT_PHY_ADDR_SPACE_SIZE); void mmap_add_region(unsigned long long base_pa, uintptr_t base_va, size_t size, unsigned int attr) -- cgit v1.2.3 From 9cefb4b194fe682fd45ece845e55a1f63e5d8a56 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 1 Apr 2020 14:20:58 +0900 Subject: Pass more -D options to BL*_CPPFLAGS instead of BL*_CFLAGS Commit d5e97a1d2c79 ("Build: define IMAGE_AT_EL1 or IMAGE_AT_EL3 globally for C files") does not have commit 848a7e8ce1d9 ("Build: introduce per-BL CPPFLAGS and ASFLAGS") as an ancestor because they were pulled almost at the same time. This is a follow-up conversion to be consistent with commit 11a3c5ee7325 ("plat: pass -D option to BL*_CPPFLAGS instead of BL*_CFLAGS"). With this change, the command line option, IMAGE_AT_EL3, will be passed to .S files as well. I remove the definition in include/lib/cpus/aarch64/cpu_macros.S Otherwise, the following error would happen. include/lib/cpus/aarch64/cpu_macros.S:29:0: error: "IMAGE_AT_EL3" redefined [-Werror] Change-Id: I943c8f22356483c2ae3c57b515c69243a8fa6889 Signed-off-by: Masahiro Yamada --- Makefile | 12 ++++++------ include/lib/cpus/aarch64/cpu_macros.S | 4 ---- plat/socionext/uniphier/platform.mk | 4 ++-- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/Makefile b/Makefile index e455635b6..52c049104 100644 --- a/Makefile +++ b/Makefile @@ -537,15 +537,15 @@ endif endif ifeq (${ARCH},aarch64) -BL1_CFLAGS += -DIMAGE_AT_EL3 +BL1_CPPFLAGS += -DIMAGE_AT_EL3 ifeq ($(BL2_AT_EL3),1) -BL2_CFLAGS += -DIMAGE_AT_EL3 +BL2_CPPFLAGS += -DIMAGE_AT_EL3 else -BL2_CFLAGS += -DIMAGE_AT_EL1 +BL2_CPPFLAGS += -DIMAGE_AT_EL1 endif -BL2U_CFLAGS += -DIMAGE_AT_EL1 -BL31_CFLAGS += -DIMAGE_AT_EL3 -BL32_CFLAGS += -DIMAGE_AT_EL1 +BL2U_CPPFLAGS += -DIMAGE_AT_EL1 +BL31_CPPFLAGS += -DIMAGE_AT_EL3 +BL32_CPPFLAGS += -DIMAGE_AT_EL1 endif # Include the CPU specific operations makefile, which provides default diff --git a/include/lib/cpus/aarch64/cpu_macros.S b/include/lib/cpus/aarch64/cpu_macros.S index c83824d77..92891ce38 100644 --- a/include/lib/cpus/aarch64/cpu_macros.S +++ b/include/lib/cpus/aarch64/cpu_macros.S @@ -25,10 +25,6 @@ /* Word size for 64-bit CPUs */ #define CPU_WORD_SIZE 8 -#if defined(IMAGE_BL1) || defined(IMAGE_BL31) ||(defined(IMAGE_BL2) && BL2_AT_EL3) -#define IMAGE_AT_EL3 -#endif - /* * Whether errata status needs reporting. Errata status is printed in debug * builds for both BL1 and BL31 images. diff --git a/plat/socionext/uniphier/platform.mk b/plat/socionext/uniphier/platform.mk index 3f8a1f864..cbe75d671 100644 --- a/plat/socionext/uniphier/platform.mk +++ b/plat/socionext/uniphier/platform.mk @@ -17,8 +17,8 @@ override ENABLE_PIE := 1 ALLOW_RO_XLAT_TABLES := 1 ifeq ($(ALLOW_RO_XLAT_TABLES),1) -BL31_CFLAGS += -DPLAT_RO_XLAT_TABLES=1 -BL32_CFLAGS += -DPLAT_RO_XLAT_TABLES=1 +BL31_CPPFLAGS += -DPLAT_RO_XLAT_TABLES=1 +BL32_CPPFLAGS += -DPLAT_RO_XLAT_TABLES=1 endif # Cortex-A53 revision r0p4-51rel0 -- cgit v1.2.3 From 1dc1756946a6e4ae1081c92fef935d07096f23e0 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 1 Apr 2020 14:28:24 +0900 Subject: plat: remove redundant =1 from -D option As GCC manual says, -D option defines a macro as 1, if = is omitted. -D Predefine as a macro, with definition 1. The same applied with Clang, too. In the context of -D option, =1 is always redundant. Change-Id: I487489a1ea3eb51e734741619c1e65dab1420bc4 Signed-off-by: Masahiro Yamada --- plat/arm/board/fvp/platform.mk | 14 +++++++------- plat/arm/board/juno/platform.mk | 8 ++++---- plat/arm/board/rdn1edge/platform.mk | 2 +- plat/socionext/uniphier/platform.mk | 4 ++-- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 15cd69121..784369024 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -297,30 +297,30 @@ endif # Enable the dynamic translation tables library. ifeq (${ARCH},aarch32) ifeq (${RESET_TO_SP_MIN},1) - BL32_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 + BL32_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC endif else # AArch64 ifeq (${RESET_TO_BL31},1) - BL31_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 + BL31_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC endif ifeq (${SPD},trusty) - BL31_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 + BL31_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC endif endif ifeq (${ALLOW_RO_XLAT_TABLES}, 1) ifeq (${ARCH},aarch32) - BL32_CPPFLAGS += -DPLAT_RO_XLAT_TABLES=1 + BL32_CPPFLAGS += -DPLAT_RO_XLAT_TABLES else # AArch64 - BL31_CPPFLAGS += -DPLAT_RO_XLAT_TABLES=1 + BL31_CPPFLAGS += -DPLAT_RO_XLAT_TABLES ifeq (${SPD},tspd) - BL32_CPPFLAGS += -DPLAT_RO_XLAT_TABLES=1 + BL32_CPPFLAGS += -DPLAT_RO_XLAT_TABLES endif endif endif ifeq (${USE_DEBUGFS},1) - BL31_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 + BL31_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC endif # Add support for platform supplied linker script for BL31 build diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk index dfdefa170..a871e81ac 100644 --- a/plat/arm/board/juno/platform.mk +++ b/plat/arm/board/juno/platform.mk @@ -147,19 +147,19 @@ ENABLE_SVE_FOR_NS := 0 # Enable the dynamic translation tables library. ifeq (${ARCH},aarch32) ifeq (${RESET_TO_SP_MIN},1) - BL32_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 + BL32_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC endif else ifeq (${RESET_TO_BL31},1) - BL31_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 + BL31_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC endif endif ifeq (${ALLOW_RO_XLAT_TABLES}, 1) ifeq (${JUNO_AARCH32_EL3_RUNTIME}, 1) - BL32_CPPFLAGS += -DPLAT_RO_XLAT_TABLES=1 + BL32_CPPFLAGS += -DPLAT_RO_XLAT_TABLES else - BL31_CPPFLAGS += -DPLAT_RO_XLAT_TABLES=1 + BL31_CPPFLAGS += -DPLAT_RO_XLAT_TABLES endif endif diff --git a/plat/arm/board/rdn1edge/platform.mk b/plat/arm/board/rdn1edge/platform.mk index 1daf85fff..e43654292 100644 --- a/plat/arm/board/rdn1edge/platform.mk +++ b/plat/arm/board/rdn1edge/platform.mk @@ -38,7 +38,7 @@ BL2_SOURCES += ${RDN1EDGE_BASE}/rdn1edge_trusted_boot.c endif # Enable dynamic addition of MMAP regions in BL31 -BL31_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 +BL31_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC # Add the FDT_SOURCES and options for Dynamic Config FDT_SOURCES += ${RDN1EDGE_BASE}/fdts/${PLAT}_fw_config.dts diff --git a/plat/socionext/uniphier/platform.mk b/plat/socionext/uniphier/platform.mk index cbe75d671..8819545fb 100644 --- a/plat/socionext/uniphier/platform.mk +++ b/plat/socionext/uniphier/platform.mk @@ -17,8 +17,8 @@ override ENABLE_PIE := 1 ALLOW_RO_XLAT_TABLES := 1 ifeq ($(ALLOW_RO_XLAT_TABLES),1) -BL31_CPPFLAGS += -DPLAT_RO_XLAT_TABLES=1 -BL32_CPPFLAGS += -DPLAT_RO_XLAT_TABLES=1 +BL31_CPPFLAGS += -DPLAT_RO_XLAT_TABLES +BL32_CPPFLAGS += -DPLAT_RO_XLAT_TABLES endif # Cortex-A53 revision r0p4-51rel0 -- cgit v1.2.3 From 46e2c853d681e3ad2fb1a37b7466ba450464f468 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 2 Apr 2020 14:03:53 +0900 Subject: uniphier: define PLAT_XLAT_TABLES_DYNAMIC only for BL2 This is not used in BL31 or Bl32 for this platform. Pass it to BL2_CPPFLAGS instead of defining it for all BL images. This will produce slightly smaller BL31 and Bl32. Change-Id: I66ec5179f8dc5b112e65547335e7dd0a0f4074cd Signed-off-by: Masahiro Yamada --- plat/socionext/uniphier/include/platform_def.h | 1 - plat/socionext/uniphier/platform.mk | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/plat/socionext/uniphier/include/platform_def.h b/plat/socionext/uniphier/include/platform_def.h index 7c6341d14..b23386d8b 100644 --- a/plat/socionext/uniphier/include/platform_def.h +++ b/plat/socionext/uniphier/include/platform_def.h @@ -62,7 +62,6 @@ #define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) #define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) -#define PLAT_XLAT_TABLES_DYNAMIC 1 #define MAX_XLAT_TABLES 9 #define MAX_MMAP_REGIONS 13 diff --git a/plat/socionext/uniphier/platform.mk b/plat/socionext/uniphier/platform.mk index 8819545fb..2c0ed92a3 100644 --- a/plat/socionext/uniphier/platform.mk +++ b/plat/socionext/uniphier/platform.mk @@ -21,6 +21,9 @@ BL31_CPPFLAGS += -DPLAT_RO_XLAT_TABLES BL32_CPPFLAGS += -DPLAT_RO_XLAT_TABLES endif +# The dynamic xlat table is only used in BL2 +BL2_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC + # Cortex-A53 revision r0p4-51rel0 # needed for LD20, unneeded for LD11, PXs3 (no ACE) ERRATA_A53_855873 := 1 -- cgit v1.2.3 From 44e2a03629e1bb4ecd308db6c112ecd94fab6324 Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Fri, 13 Mar 2020 13:35:27 +0100 Subject: Specify integration as the default branch for git-review Submitting a change for review using 'git review' will now automatically use the special refs/for/integration ref (instead of targeting the master branch). Change-Id: Idef58b20c492bf5ab06599f4cd4a5e5b75837066 Signed-off-by: Sandrine Bailleux --- .gitreview | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitreview b/.gitreview index 36f25485b..afdb74dff 100644 --- a/.gitreview +++ b/.gitreview @@ -2,3 +2,4 @@ host=review.trustedfirmware.org port=29418 project=TF-A/trusted-firmware-a +defaultbranch=integration -- cgit v1.2.3 From 535c824e38c5dde4c6d346e29761eabe0b38674a Mon Sep 17 00:00:00 2001 From: Javier Almansa Sobrino Date: Thu, 2 Apr 2020 12:36:16 +0100 Subject: Fix coverity defects found on the FPGA port. Signed-off-by: Javier Almansa Sobrino Change-Id: I397b642eff8a09b201f497f8d2ba39e2460c0dba --- plat/arm/board/arm_fpga/fpga_pm.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plat/arm/board/arm_fpga/fpga_pm.c b/plat/arm/board/arm_fpga/fpga_pm.c index 4c372179f..a306a23d4 100644 --- a/plat/arm/board/arm_fpga/fpga_pm.c +++ b/plat/arm/board/arm_fpga/fpga_pm.c @@ -41,9 +41,13 @@ uintptr_t fpga_sec_entrypoint; */ static int fpga_pwr_domain_on(u_register_t mpidr) { - unsigned int pos = plat_core_pos_by_mpidr(mpidr); + int pos = plat_core_pos_by_mpidr(mpidr); unsigned long current_mpidr = read_mpidr_el1(); + if (pos < 0) { + panic(); + } + if (mpidr == current_mpidr) { return PSCI_E_ALREADY_ON; } -- cgit v1.2.3 From 6f8a2565593f602bfe9f6069f086960f8cc745cd Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Wed, 25 Mar 2020 11:22:34 +0100 Subject: Check for out-of-bound accesses in the CoT description The chain of trust array is now always accessed through a fconf getter. This gives us an ideal spot to check for out-of-bound accesses. Change-Id: Ic5ea20e43cf8ca959bb7f9b60de7c0839b390add Signed-off-by: Sandrine Bailleux --- include/drivers/auth/auth_mod.h | 6 +++++- include/lib/fconf/fconf_tbbr_getter.h | 7 ++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/include/drivers/auth/auth_mod.h b/include/drivers/auth/auth_mod.h index 6c48124b5..1dc9ff441 100644 --- a/include/drivers/auth/auth_mod.h +++ b/include/drivers/auth/auth_mod.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -14,6 +14,8 @@ #include #include +#include + /* * Image flags */ @@ -41,9 +43,11 @@ int auth_mod_verify_img(unsigned int img_id, /* Macro to register a CoT defined as an array of auth_img_desc_t pointers */ #define REGISTER_COT(_cot) \ const auth_img_desc_t *const *const cot_desc_ptr = (_cot); \ + const size_t cot_desc_size = ARRAY_SIZE(_cot); \ unsigned int auth_img_flags[MAX_NUMBER_IDS] extern const auth_img_desc_t *const *const cot_desc_ptr; +extern const size_t cot_desc_size; extern unsigned int auth_img_flags[MAX_NUMBER_IDS]; #endif /* TRUSTED_BOARD_BOOT */ diff --git a/include/lib/fconf/fconf_tbbr_getter.h b/include/lib/fconf/fconf_tbbr_getter.h index eddc0c4b5..db98b68b0 100644 --- a/include/lib/fconf/fconf_tbbr_getter.h +++ b/include/lib/fconf/fconf_tbbr_getter.h @@ -7,10 +7,15 @@ #ifndef FCONF_TBBR_GETTER_H #define FCONF_TBBR_GETTER_H +#include + #include /* TBBR related getter */ -#define tbbr__cot_getter(id) cot_desc_ptr[id] +#define tbbr__cot_getter(id) __extension__ ({ \ + assert((id) < cot_desc_size); \ + cot_desc_ptr[id]; \ +}) #define tbbr__dyn_config_getter(id) tbbr_dyn_config.id -- cgit v1.2.3 From afe62624c313b78778d4bb4962f5141ac5a0b728 Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Thu, 2 Apr 2020 15:52:44 +0200 Subject: Check for out-of-bound accesses in the platform io policies The platform io policies array is now always accessed through a fconf getter. This gives us an ideal spot to check for out-of-bound accesses. Remove the assertion in plat_get_image_source(), which is now redundant. Change-Id: Iefe808d530229073b68cbd164d927b8b6662a217 Signed-off-by: Sandrine Bailleux --- include/plat/arm/common/arm_fconf_getter.h | 7 ++++++- plat/arm/common/arm_io_storage.c | 4 ---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/include/plat/arm/common/arm_fconf_getter.h b/include/plat/arm/common/arm_fconf_getter.h index 28913a43f..8fd8c7ada 100644 --- a/include/plat/arm/common/arm_fconf_getter.h +++ b/include/plat/arm/common/arm_fconf_getter.h @@ -7,10 +7,15 @@ #ifndef ARM_FCONF_GETTER #define ARM_FCONF_GETTER +#include + #include /* ARM io policies */ -#define arm__io_policies_getter(id) &policies[id] +#define arm__io_policies_getter(id) __extension__ ({ \ + assert((id) < MAX_NUMBER_IDS); \ + &policies[id]; \ +}) struct plat_io_policy { uintptr_t *dev_handle; diff --git a/plat/arm/common/arm_io_storage.c b/plat/arm/common/arm_io_storage.c index 6fcfbd6fb..34b4101e1 100644 --- a/plat/arm/common/arm_io_storage.c +++ b/plat/arm/common/arm_io_storage.c @@ -4,8 +4,6 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include - #include #include #include @@ -116,8 +114,6 @@ int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, int result; const struct plat_io_policy *policy; - assert(image_id < MAX_NUMBER_IDS); - policy = FCONF_GET_PROPERTY(arm, io_policies, image_id); result = policy->check(policy->image_spec); if (result == 0) { -- cgit v1.2.3 From 3cde15fadea9cee8863c05e6908166166e5bca9b Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 2 Apr 2020 16:20:21 +0900 Subject: xlat_tables_v2: use get_current_el_maybe_constant() in is_dcache_enabled() Using get_current_el_maybe_constant() produces more optimized code because in most cases, we know the exception level at build-time. For example, BL31 runs at EL3, so unneeded code will be trimmed. [before] 0000000000000000 : 0: d5384240 mrs x0, currentel 4: 53020c00 ubfx w0, w0, #2, #2 8: 7100041f cmp w0, #0x1 c: 54000081 b.ne 1c // b.any 10: d5381000 mrs x0, sctlr_el1 14: 53020800 ubfx w0, w0, #2, #1 18: d65f03c0 ret 1c: 7100081f cmp w0, #0x2 20: 54000061 b.ne 2c // b.any 24: d53c1000 mrs x0, sctlr_el2 28: 17fffffb b 14 2c: d53e1000 mrs x0, sctlr_el3 30: 17fffff9 b 14 [after] 0000000000000000 : 0: d53e1000 mrs x0, sctlr_el3 4: 53020800 ubfx w0, w0, #2, #1 8: d65f03c0 ret Change-Id: I3698fae9b517022ff9fbfd4cad3a320c6e137e10 Signed-off-by: Masahiro Yamada --- lib/xlat_tables_v2/aarch64/xlat_tables_arch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c index 8eeeea1dd..3832b0703 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-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -135,7 +135,7 @@ bool is_mmu_enabled_ctx(const xlat_ctx_t *ctx) bool is_dcache_enabled(void) { - unsigned int el = (unsigned int)GET_EL(read_CurrentEl()); + unsigned int el = get_current_el_maybe_constant(); if (el == 1U) { return (read_sctlr_el1() & SCTLR_C_BIT) != 0U; -- cgit v1.2.3 From 717448d622b13233e15aa43767fc8aa2f007486c Mon Sep 17 00:00:00 2001 From: Sheetal Tigadoli Date: Fri, 13 Dec 2019 10:39:06 +0530 Subject: Add bl2 setup code common across Broadcom platforms Signed-off-by: Sheetal Tigadoli Change-Id: Iabeaee35c22608c93945c8295bf70947b0f6049a --- include/plat/brcm/common/bcm_console.h | 15 + include/plat/brcm/common/brcm_def.h | 153 ++++++ include/plat/brcm/common/plat_brcm.h | 30 ++ plat/brcm/board/common/bcm_console.c | 65 +++ plat/brcm/board/common/board_common.c | 42 ++ plat/brcm/board/common/board_common.mk | 82 ++++ plat/brcm/board/common/cmn_plat_def.h | 34 ++ plat/brcm/board/common/cmn_plat_util.h | 43 ++ plat/brcm/board/common/cmn_sec.c | 49 ++ plat/brcm/board/common/cmn_sec.h | 19 + plat/brcm/board/common/err.c | 37 ++ plat/brcm/board/common/plat_setup.c | 27 ++ plat/brcm/board/common/platform_common.c | 43 ++ plat/brcm/board/stingray/aarch64/plat_helpers.S | 263 ++++++++++ plat/brcm/board/stingray/bcm958742t-ns3.mk | 16 + plat/brcm/board/stingray/bcm958742t.mk | 19 + plat/brcm/board/stingray/include/crmu_def.h | 227 +++++++++ plat/brcm/board/stingray/include/plat_macros.S | 52 ++ plat/brcm/board/stingray/include/platform_def.h | 272 +++++++++++ plat/brcm/board/stingray/include/sr_def.h | 614 ++++++++++++++++++++++++ plat/brcm/board/stingray/platform.mk | 48 ++ plat/brcm/common/brcm_bl2_mem_params_desc.c | 106 ++++ plat/brcm/common/brcm_bl2_setup.c | 202 ++++++++ plat/brcm/common/brcm_common.c | 59 +++ plat/brcm/common/brcm_image_load.c | 41 ++ plat/brcm/common/brcm_io_storage.c | 408 ++++++++++++++++ 26 files changed, 2966 insertions(+) create mode 100644 include/plat/brcm/common/bcm_console.h create mode 100644 include/plat/brcm/common/brcm_def.h create mode 100644 include/plat/brcm/common/plat_brcm.h create mode 100644 plat/brcm/board/common/bcm_console.c create mode 100644 plat/brcm/board/common/board_common.c create mode 100644 plat/brcm/board/common/board_common.mk create mode 100644 plat/brcm/board/common/cmn_plat_def.h create mode 100644 plat/brcm/board/common/cmn_plat_util.h create mode 100644 plat/brcm/board/common/cmn_sec.c create mode 100644 plat/brcm/board/common/cmn_sec.h create mode 100644 plat/brcm/board/common/err.c create mode 100644 plat/brcm/board/common/plat_setup.c create mode 100644 plat/brcm/board/common/platform_common.c create mode 100644 plat/brcm/board/stingray/aarch64/plat_helpers.S create mode 100644 plat/brcm/board/stingray/bcm958742t-ns3.mk create mode 100644 plat/brcm/board/stingray/bcm958742t.mk create mode 100644 plat/brcm/board/stingray/include/crmu_def.h create mode 100644 plat/brcm/board/stingray/include/plat_macros.S create mode 100644 plat/brcm/board/stingray/include/platform_def.h create mode 100644 plat/brcm/board/stingray/include/sr_def.h create mode 100644 plat/brcm/board/stingray/platform.mk create mode 100644 plat/brcm/common/brcm_bl2_mem_params_desc.c create mode 100644 plat/brcm/common/brcm_bl2_setup.c create mode 100644 plat/brcm/common/brcm_common.c create mode 100644 plat/brcm/common/brcm_image_load.c create mode 100644 plat/brcm/common/brcm_io_storage.c diff --git a/include/plat/brcm/common/bcm_console.h b/include/plat/brcm/common/bcm_console.h new file mode 100644 index 000000000..7b653d802 --- /dev/null +++ b/include/plat/brcm/common/bcm_console.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2018-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef BCM_CONSOLE_H +#define BCM_CONSOLE_H + +void bcm_console_boot_init(void); +void bcm_console_boot_end(void); +void bcm_console_runtime_init(void); +void bcm_console_runtime_end(void); + +#endif /* BCM_CONSOLE_H */ diff --git a/include/plat/brcm/common/brcm_def.h b/include/plat/brcm/common/brcm_def.h new file mode 100644 index 000000000..c9137bca9 --- /dev/null +++ b/include/plat/brcm/common/brcm_def.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2016 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef BRCM_DEF_H +#define BRCM_DEF_H + +#include +#include +#include +#include +#include + +#include + +#define PLAT_PHY_ADDR_SPACE_SIZE BIT_64(32) +#define PLAT_VIRT_ADDR_SPACE_SIZE BIT_64(32) + +#define BL11_DAUTH_ID 0x796C51ab +#define BL11_DAUTH_BASE BL11_RW_BASE + +/* We keep a table at the end of ROM for function pointers */ +#define ROM_TABLE_SIZE 32 +#define BL1_ROM_TABLE (BL1_RO_LIMIT - ROM_TABLE_SIZE) + +/* + * The top 16MB of DRAM1 is configured as secure access only using the TZC + * - SCP TZC DRAM: If present, DRAM reserved for SCP use + * - AP TZC DRAM: The remaining TZC secured DRAM reserved for AP use + */ +#define BRCM_TZC_DRAM1_SIZE ULL(0x01000000) + +#define BRCM_SCP_TZC_DRAM1_BASE (BRCM_DRAM1_BASE + \ + BRCM_DRAM1_SIZE - \ + BRCM_SCP_TZC_DRAM1_SIZE) +#define BRCM_SCP_TZC_DRAM1_SIZE PLAT_BRCM_SCP_TZC_DRAM1_SIZE + +#define BRCM_AP_TZC_DRAM1_BASE (BRCM_DRAM1_BASE + \ + BRCM_DRAM1_SIZE - \ + BRCM_TZC_DRAM1_SIZE) +#define BRCM_AP_TZC_DRAM1_SIZE (BRCM_TZC_DRAM1_SIZE - \ + BRCM_SCP_TZC_DRAM1_SIZE) + +#define BRCM_NS_DRAM1_BASE BRCM_DRAM1_BASE +#define BRCM_NS_DRAM1_SIZE (BRCM_DRAM1_SIZE - \ + BRCM_TZC_DRAM1_SIZE) + +#ifdef BRCM_SHARED_DRAM_BASE +#define BRCM_NS_SHARED_DRAM_BASE BRCM_SHARED_DRAM_BASE +#define BRCM_NS_SHARED_DRAM_SIZE BRCM_SHARED_DRAM_SIZE +#endif + +#define BRCM_MAP_SHARED_RAM MAP_REGION_FLAT( \ + BRCM_SHARED_RAM_BASE, \ + BRCM_SHARED_RAM_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#define BRCM_MAP_NS_DRAM1 MAP_REGION_FLAT( \ + BRCM_NS_DRAM1_BASE, \ + BRCM_NS_DRAM1_SIZE, \ + MT_MEMORY | MT_RW | MT_NS) + +#ifdef BRCM_SHARED_DRAM_BASE +#define BRCM_MAP_NS_SHARED_DRAM MAP_REGION_FLAT( \ + BRCM_NS_SHARED_DRAM_BASE, \ + BRCM_NS_SHARED_DRAM_SIZE, \ + MT_MEMORY | MT_RW | MT_NS) +#endif + +#ifdef BRCM_EXT_SRAM_BASE +#define BRCM_MAP_EXT_SRAM MAP_REGION_FLAT( \ + BRCM_EXT_SRAM_BASE, \ + BRCM_EXT_SRAM_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) +#endif + +#define BRCM_MAP_NAND_RO MAP_REGION_FLAT(NAND_BASE_ADDR,\ + NAND_SIZE, \ + MT_MEMORY | MT_RO | MT_SECURE) + +#define BRCM_MAP_QSPI_RO MAP_REGION_FLAT(QSPI_BASE_ADDR,\ + QSPI_SIZE, \ + MT_MEMORY | MT_RO | MT_SECURE) + +#define HSLS_REGION MAP_REGION_FLAT(HSLS_BASE_ADDR, \ + HSLS_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#define CCN_REGION MAP_REGION_FLAT(PLAT_BRCM_CCN_BASE, \ + CCN_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#define GIC500_REGION MAP_REGION_FLAT(GIC500_BASE, \ + GIC500_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) +#ifdef PERIPH0_BASE +#define PERIPH0_REGION MAP_REGION_FLAT(PERIPH0_BASE, \ + PERIPH0_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) +#endif + +#ifdef PERIPH1_BASE +#define PERIPH1_REGION MAP_REGION_FLAT(PERIPH1_BASE, \ + PERIPH1_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) +#endif + +#ifdef PERIPH2_BASE +#define PERIPH2_REGION MAP_REGION_FLAT(PERIPH2_BASE, \ + PERIPH2_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) +#endif + +#if BRCM_BL31_IN_DRAM +#if IMAGE_BL2 +#define BRCM_MAP_BL31_SEC_DRAM MAP_REGION_FLAT( \ + BL31_BASE, \ + PLAT_BRCM_MAX_BL31_SIZE,\ + MT_DEVICE | MT_RW | MT_SECURE) +#else +#define BRCM_MAP_BL31_SEC_DRAM MAP_REGION_FLAT( \ + BL31_BASE, \ + PLAT_BRCM_MAX_BL31_SIZE,\ + MT_MEMORY | MT_RW | MT_SECURE) +#endif +#endif + +#if defined(USB_BASE) && defined(DRIVER_USB_ENABLE) +#define USB_REGION MAP_REGION_FLAT( \ + USB_BASE, \ + USB_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) +#endif + +#ifdef USE_CRMU_SRAM +#define CRMU_SRAM_REGION MAP_REGION_FLAT( \ + CRMU_SRAM_BASE, \ + CRMU_SRAM_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) +#endif +/* + * The number of regions like RO(code), coherent and data required by + * different BL stages which need to be mapped in the MMU. + */ +#if USE_COHERENT_MEM +#define BRCM_BL_REGIONS 3 +#else +#define BRCM_BL_REGIONS 2 +#endif + +#endif /* BRCM_DEF_H */ diff --git a/include/plat/brcm/common/plat_brcm.h b/include/plat/brcm/common/plat_brcm.h new file mode 100644 index 000000000..9147caac5 --- /dev/null +++ b/include/plat/brcm/common/plat_brcm.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2019-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLAT_BRCM_H +#define PLAT_BRCM_H + +#include + +#include +#include +#include + +#include + +struct image_info; + +/* Global variables */ +extern const mmap_region_t plat_brcm_mmap[]; + +uint32_t brcm_get_spsr_for_bl32_entry(void); +uint32_t brcm_get_spsr_for_bl33_entry(void); +const mmap_region_t *plat_brcm_get_mmap(void); +int bcm_bl2_handle_scp_bl2(struct image_info *image_info); +void plat_brcm_io_setup(void); +void plat_brcm_process_flags(uint16_t plat_toc_flags); + +#endif /* PLAT_BRCM_H */ diff --git a/plat/brcm/board/common/bcm_console.c b/plat/brcm/board/common/bcm_console.c new file mode 100644 index 000000000..d484a6f63 --- /dev/null +++ b/plat/brcm/board/common/bcm_console.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include + +#include + +/******************************************************************************* + * Functions that set up the console + ******************************************************************************/ +static console_t bcm_boot_console; +static console_t bcm_runtime_console; + +/* Initialize the console to provide early debug support */ +void bcm_console_boot_init(void) +{ + int rc = console_16550_register(PLAT_BRCM_BOOT_UART_BASE, + PLAT_BRCM_BOOT_UART_CLK_IN_HZ, + BRCM_CONSOLE_BAUDRATE, + &bcm_boot_console); + if (rc == 0) { + /* + * The crash console doesn't use the multi console API, it uses + * the core console functions directly. It is safe to call panic + * and let it print debug information. + */ + panic(); + } + + console_set_scope(&bcm_boot_console, CONSOLE_FLAG_BOOT); +} + +void bcm_console_boot_end(void) +{ + (void)console_flush(); + + (void)console_unregister(&bcm_boot_console); +} + +/* Initialize the runtime console */ +void bcm_console_runtime_init(void) +{ + int rc = console_16550_register(PLAT_BRCM_BL31_RUN_UART_BASE, + PLAT_BRCM_BL31_RUN_UART_CLK_IN_HZ, + BRCM_CONSOLE_BAUDRATE, + &bcm_runtime_console); + if (rc == 0) + panic(); + + console_set_scope(&bcm_runtime_console, CONSOLE_FLAG_RUNTIME); +} + +void bcm_console_runtime_end(void) +{ + (void)console_flush(); + + (void)console_unregister(&bcm_runtime_console); +} diff --git a/plat/brcm/board/common/board_common.c b/plat/brcm/board/common/board_common.c new file mode 100644 index 000000000..e7b5e475e --- /dev/null +++ b/plat/brcm/board/common/board_common.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2016 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#if IMAGE_BL2 +const mmap_region_t plat_brcm_mmap[] = { + HSLS_REGION, + BRCM_MAP_SHARED_RAM, + BRCM_MAP_NAND_RO, + BRCM_MAP_QSPI_RO, +#ifdef PERIPH0_REGION + PERIPH0_REGION, +#endif +#ifdef PERIPH1_REGION + PERIPH1_REGION, +#endif +#ifdef USE_DDR + BRCM_MAP_NS_DRAM1, +#if BRCM_BL31_IN_DRAM + BRCM_MAP_BL31_SEC_DRAM, +#endif +#else +#ifdef BRCM_MAP_EXT_SRAM + BRCM_MAP_EXT_SRAM, +#endif +#endif +#if defined(USE_CRMU_SRAM) && defined(CRMU_SRAM_BASE) + CRMU_SRAM_REGION, +#endif + {0} +}; +#endif + +CASSERT((ARRAY_SIZE(plat_brcm_mmap) - 1) <= PLAT_BRCM_MMAP_ENTRIES, + assert_plat_brcm_mmap_mismatch); +CASSERT((PLAT_BRCM_MMAP_ENTRIES + BRCM_BL_REGIONS) <= MAX_MMAP_REGIONS, + assert_max_mmap_regions); diff --git a/plat/brcm/board/common/board_common.mk b/plat/brcm/board/common/board_common.mk new file mode 100644 index 000000000..9ac26af32 --- /dev/null +++ b/plat/brcm/board/common/board_common.mk @@ -0,0 +1,82 @@ +# +# Copyright (c) 2015 - 2020, Broadcom +# +# SPDX-License-Identifier: BSD-3-Clause +# + +PLAT_BL_COMMON_SOURCES += plat/brcm/board/common/board_common.c + +# If no board config makefile, do not include it +ifneq (${BOARD_CFG},) +BOARD_CFG_MAKE := $(shell find plat/brcm/board/${PLAT} -name '${BOARD_CFG}.mk') +$(eval $(call add_define,BOARD_CFG)) +ifneq (${BOARD_CFG_MAKE},) +$(info Including ${BOARD_CFG_MAKE}) +include ${BOARD_CFG_MAKE} +else +$(error Error: File ${BOARD_CFG}.mk not found in plat/brcm/board/${PLAT}) +endif +endif + +# To compile with highest log level (VERBOSE) set value to 50 +LOG_LEVEL := 40 + +# Use custom generic timer clock +ifneq (${GENTIMER_ACTUAL_CLOCK},) +$(info Using GENTIMER_ACTUAL_CLOCK=$(GENTIMER_ACTUAL_CLOCK)) +SYSCNT_FREQ := $(GENTIMER_ACTUAL_CLOCK) +$(eval $(call add_define,SYSCNT_FREQ)) +endif + +ifeq (${STANDALONE_BL2},yes) +$(eval $(call add_define,MMU_DISABLED)) +endif + +# BL2 XIP from QSPI +RUN_BL2_FROM_QSPI := 0 +ifeq (${RUN_BL2_FROM_QSPI},1) +$(eval $(call add_define,RUN_BL2_FROM_QSPI)) +endif + +# Use CRMU SRAM from iHOST +ifneq (${USE_CRMU_SRAM},) +$(eval $(call add_define,USE_CRMU_SRAM)) +endif + +# On BRCM platforms, separate the code and read-only data sections to allow +# mapping the former as executable and the latter as execute-never. +SEPARATE_CODE_AND_RODATA := 1 + +# Use generic OID definition (tbbr_oid.h) +USE_TBBR_DEFS := 1 + +PLAT_INCLUDES += -Iplat/brcm/board/common + +PLAT_BL_COMMON_SOURCES += plat/brcm/common/brcm_common.c \ + plat/brcm/board/common/cmn_sec.c \ + plat/brcm/board/common/bcm_console.c \ + plat/brcm/board/common/plat_setup.c \ + plat/brcm/board/common/platform_common.c \ + drivers/arm/sp804/sp804_delay_timer.c \ + drivers/delay_timer/delay_timer.c \ + drivers/io/io_fip.c \ + drivers/io/io_memmap.c \ + drivers/io/io_storage.c \ + plat/brcm/common/brcm_io_storage.c \ + plat/brcm/board/common/err.c \ + drivers/arm/sp805/sp805.c + +BL2_SOURCES += plat/brcm/common/brcm_bl2_mem_params_desc.c \ + plat/brcm/common/brcm_image_load.c \ + common/desc_image_load.c + +BL2_SOURCES += plat/brcm/common/brcm_bl2_setup.c + +# Use translation tables library v1 by default +ARM_XLAT_TABLES_LIB_V1 := 1 +ifeq (${ARM_XLAT_TABLES_LIB_V1}, 1) +$(eval $(call assert_boolean,ARM_XLAT_TABLES_LIB_V1)) +$(eval $(call add_define,ARM_XLAT_TABLES_LIB_V1)) +PLAT_BL_COMMON_SOURCES += lib/xlat_tables/aarch64/xlat_tables.c \ + lib/xlat_tables/xlat_tables_common.c +endif diff --git a/plat/brcm/board/common/cmn_plat_def.h b/plat/brcm/board/common/cmn_plat_def.h new file mode 100644 index 000000000..41d922259 --- /dev/null +++ b/plat/brcm/board/common/cmn_plat_def.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2015 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CMN_PLAT_DEF_H +#define CMN_PLAT_DEF_H + +/* Print file and line number on assert */ +#define PLAT_LOG_LEVEL_ASSERT LOG_LEVEL_INFO + +/* + * The number of regions like RO(code), coherent and data required by + * different BL stages which need to be mapped in the MMU. + */ +#if USE_COHERENT_MEM +#define CMN_BL_REGIONS 3 +#else +#define CMN_BL_REGIONS 2 +#endif + +/* + * FIP definitions + */ +#define PLAT_FIP_ATTEMPT_OFFSET 0x20000 +#define PLAT_FIP_NUM_ATTEMPTS 128 + +#define PLAT_BRCM_FIP_QSPI_BASE QSPI_BASE_ADDR +#define PLAT_BRCM_FIP_NAND_BASE NAND_BASE_ADDR +#define PLAT_BRCM_FIP_MAX_SIZE 0x01000000 + +#define PLAT_BRCM_FIP_BASE PLAT_BRCM_FIP_QSPI_BASE +#endif diff --git a/plat/brcm/board/common/cmn_plat_util.h b/plat/brcm/board/common/cmn_plat_util.h new file mode 100644 index 000000000..178c84357 --- /dev/null +++ b/plat/brcm/board/common/cmn_plat_util.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2015 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CMN_PLAT_UTIL_H +#define CMN_PLAT_UTIL_H + +#include + +/* BOOT source */ +#define BOOT_SOURCE_MASK 7 +#define BOOT_SOURCE_QSPI 0 +#define BOOT_SOURCE_NAND 1 +#define BOOT_SOURCE_SPI_NAND 2 +#define BOOT_SOURCE_UART 3 +#define BOOT_SOURCE_RES4 4 +#define BOOT_SOURCE_EMMC 5 +#define BOOT_SOURCE_ATE 6 +#define BOOT_SOURCE_USB 7 +#define BOOT_SOURCE_MAX 8 +#define BOOT_SOURCE_UNKNOWN (-1) + +#define KHMAC_SHA256_KEY_SIZE 32 + +#define SOFT_PWR_UP_RESET_L0 0 +#define SOFT_SYS_RESET_L1 1 +#define SOFT_RESET_L3 0x3 + +#define BOOT_SOURCE_SOFT_DATA_OFFSET 8 +#define BOOT_SOURCE_SOFT_ENABLE_OFFSET 14 +#define BOOT_SOURCE_SOFT_ENABLE_MASK BIT(BOOT_SOURCE_SOFT_ENABLE_OFFSET) + +typedef struct _key { + uint8_t hmac_sha256[KHMAC_SHA256_KEY_SIZE]; +} cmn_key_t; + +uint32_t boot_source_get(void); +void bl1_platform_wait_events(void); +void plat_soft_reset(uint32_t reset); + +#endif diff --git a/plat/brcm/board/common/cmn_sec.c b/plat/brcm/board/common/cmn_sec.c new file mode 100644 index 000000000..c80d5dd6f --- /dev/null +++ b/plat/brcm/board/common/cmn_sec.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2015-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include + +#include + +#pragma weak plat_tz_master_default_cfg +#pragma weak plat_tz_sdio_ns_master_set +#pragma weak plat_tz_usb_ns_master_set + +void plat_tz_master_default_cfg(void) +{ + /* This function should be implemented in the platform side. */ + ERROR("%s: TZ CONFIGURATION NOT SET!!!\n", __func__); +} + +void plat_tz_sdio_ns_master_set(uint32_t ns) +{ + /* This function should be implemented in the platform side. */ + ERROR("%s: TZ CONFIGURATION NOT SET!!!\n", __func__); +} + +void plat_tz_usb_ns_master_set(uint32_t ns) +{ + /* This function should be implemented in the platform side. */ + ERROR("%s: TZ CONFIGURATION NOT SET!!!\n", __func__); +} + +void tz_master_default_cfg(void) +{ + plat_tz_master_default_cfg(); +} + +void tz_sdio_ns_master_set(uint32_t ns) +{ + plat_tz_sdio_ns_master_set(ns); +} + +void tz_usb_ns_master_set(uint32_t ns) +{ + plat_tz_usb_ns_master_set(ns); +} diff --git a/plat/brcm/board/common/cmn_sec.h b/plat/brcm/board/common/cmn_sec.h new file mode 100644 index 000000000..f74863d88 --- /dev/null +++ b/plat/brcm/board/common/cmn_sec.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2015-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CMN_SEC_H +#define CMN_SEC_H + +#include + +#define SECURE_MASTER 0 +#define NS_MASTER 1 + +void tz_master_default_cfg(void); +void tz_usb_ns_master_set(uint32_t ns); +void tz_sdio_ns_master_set(uint32_t ns); + +#endif diff --git a/plat/brcm/board/common/err.c b/plat/brcm/board/common/err.c new file mode 100644 index 000000000..1fc73c481 --- /dev/null +++ b/plat/brcm/board/common/err.c @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2016 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include + +#include + +#define L0_RESET 0x2 + +/* + * Brcm error handler + */ +void plat_error_handler(int err) +{ + INFO("L0 reset...\n"); + + /* Ensure the characters are flushed out */ + console_flush(); + + mmio_write_32(CRMU_SOFT_RESET_CTRL, L0_RESET); + + /* + * In case we get here: + * Loop until the watchdog resets the system + */ + while (1) { + wfi(); + } +} diff --git a/plat/brcm/board/common/plat_setup.c b/plat/brcm/board/common/plat_setup.c new file mode 100644 index 000000000..95e12ed1e --- /dev/null +++ b/plat/brcm/board/common/plat_setup.c @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2015 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include + +/* + * This function returns the fixed clock frequency at which private + * timers run. This value will be programmed into CNTFRQ_EL0. + */ +unsigned int plat_get_syscnt_freq2(void) +{ + return SYSCNT_FREQ; +} + +static const char * const plat_prefix_str[] = { + "E: ", "N: ", "W: ", "I: ", "V: " +}; + +const char *plat_log_get_prefix(unsigned int log_level) +{ + return plat_prefix_str[log_level - 1U]; +} diff --git a/plat/brcm/board/common/platform_common.c b/plat/brcm/board/common/platform_common.c new file mode 100644 index 000000000..9bae83aa9 --- /dev/null +++ b/plat/brcm/board/common/platform_common.c @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2015-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include + +uint32_t boot_source_get(void) +{ + /* For now return BOOT_SOURCE_QSPI */ + return BOOT_SOURCE_QSPI; +} + +void __dead2 plat_soft_reset(uint32_t reset) +{ + if (reset == SOFT_RESET_L3) { + mmio_setbits_32(CRMU_IHOST_SW_PERSISTENT_REG1, reset); + mmio_write_32(CRMU_MAIL_BOX0, 0x0); + mmio_write_32(CRMU_MAIL_BOX1, 0xFFFFFFFF); + } + + if (reset != SOFT_SYS_RESET_L1) + reset = SOFT_PWR_UP_RESET_L0; + + if (reset == SOFT_PWR_UP_RESET_L0) + INFO("L0 RESET...\n"); + + if (reset == SOFT_SYS_RESET_L1) + INFO("L1 RESET...\n"); + + console_flush(); + + mmio_clrbits_32(CRMU_SOFT_RESET_CTRL, 1 << reset); + + while (1) { + ; + } +} diff --git a/plat/brcm/board/stingray/aarch64/plat_helpers.S b/plat/brcm/board/stingray/aarch64/plat_helpers.S new file mode 100644 index 000000000..609553248 --- /dev/null +++ b/plat/brcm/board/stingray/aarch64/plat_helpers.S @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2015-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include + +#include + + .globl plat_reset_handler + .globl platform_get_entrypoint + .globl plat_secondary_cold_boot_setup + .globl platform_mem_init + .globl platform_check_mpidr + .globl plat_crash_console_init + .globl plat_crash_console_putc + .globl plat_crash_console_flush + .globl plat_disable_acp + .globl plat_is_my_cpu_primary + .globl plat_my_core_pos + .globl platform_is_primary_cpu + .globl plat_brcm_calc_core_pos + .globl plat_get_my_entrypoint + + + /* ------------------------------------------------------------ + * void plat_l2_init(void); + * + * BL1 and BL2 run with one core, one cluster + * This is safe to disable cluster coherency + * to make use of the data cache MMU WB attribute + * for the SRAM. + * + * Set L2 Auxiliary Control Register + * -------------------------------------------------------------------- + */ +func plat_l2_init + mrs x0, CORTEX_A72_L2ACTLR_EL1 +#if (IMAGE_BL1 || IMAGE_BL2) || defined(USE_SINGLE_CLUSTER) + orr x0, x0, #CORTEX_A72_L2ACTLR_DISABLE_ACE_SH_OR_CHI +#else + bic x0, x0, #CORTEX_A72_L2ACTLR_DISABLE_ACE_SH_OR_CHI +#endif + msr CORTEX_A72_L2ACTLR_EL1, x0 + + /* Set L2 Control Register */ + mrs x0, CORTEX_A72_L2CTLR_EL1 + mov x1, #((CORTEX_A72_L2_DATA_RAM_LATENCY_MASK << \ + CORTEX_A72_L2CTLR_DATA_RAM_LATENCY_SHIFT) | \ + (CORTEX_A72_L2_TAG_RAM_LATENCY_MASK << \ + CORTEX_A72_L2CTLR_TAG_RAM_LATENCY_SHIFT) | \ + (U(0x1) << CORTEX_A72_L2CTLR_TAG_RAM_SETUP_SHIFT) | \ + (U(0x1) << CORTEX_A72_L2CTLR_DATA_RAM_SETUP_SHIFT)) + bic x0, x0, x1 + mov x1, #((CORTEX_A72_L2_DATA_RAM_LATENCY_3_CYCLES << \ + CORTEX_A72_L2CTLR_DATA_RAM_LATENCY_SHIFT) | \ + (U(0x1) << CORTEX_A72_L2CTLR_TAG_RAM_SETUP_SHIFT) | \ + (U(0x1) << CORTEX_A72_L2CTLR_DATA_RAM_SETUP_SHIFT)) + orr x0, x0, x1 + msr CORTEX_A72_L2CTLR_EL1, x0 + + isb + ret +endfunc plat_l2_init + + /* -------------------------------------------------------------------- + * void plat_reset_handler(void); + * + * Before adding code in this function, refer to the guidelines in + * docs/firmware-design.md. + * + * -------------------------------------------------------------------- + */ +func plat_reset_handler + mov x9, x30 + bl plat_l2_init + mov x30, x9 + ret +endfunc plat_reset_handler + + /* ----------------------------------------------------- + * void platform_get_entrypoint (unsigned int mpid); + * + * Main job of this routine is to distinguish between + * a cold and warm boot. + * On a cold boot the secondaries first wait for the + * platform to be initialized after which they are + * hotplugged in. The primary proceeds to perform the + * platform initialization. + * ----------------------------------------------------- + */ +func platform_get_entrypoint + /*TBD-STINGRAY*/ + mov x0, #0 + ret +endfunc platform_get_entrypoint + + /* ----------------------------------------------------- + * 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 + bl plat_my_core_pos + mov_imm x1, SECONDARY_CPU_SPIN_BASE_ADDR + add x0, x1, x0, LSL #3 + mov x1, #0 + str x1, [x0] + + /* Wait until the entrypoint gets populated */ +poll_mailbox: + ldr x1, [x0] + cbz x1, 1f + br x1 +1: + wfe + b poll_mailbox +endfunc plat_secondary_cold_boot_setup + + + /* ----------------------------------------------------- + * void platform_mem_init(void); + * + * We don't need to carry out any memory initialization + * on CSS platforms. The Secure RAM is accessible straight away. + * ----------------------------------------------------- + */ +func platform_mem_init + /*TBD-STINGRAY*/ + ret +endfunc platform_mem_init + + /* ----------------------------------------------------- + * Placeholder function which should be redefined by + * each platform. + * ----------------------------------------------------- + */ +func platform_check_mpidr + /*TBD-STINGRAY*/ + mov x0, xzr + ret +endfunc platform_check_mpidr + + /* --------------------------------------------- + * int plat_crash_console_init(void) + * Function to initialize the crash console + * without a C Runtime to print crash report. + * Clobber list : x0, x1, x2 + * --------------------------------------------- + */ + +func plat_crash_console_init + mov_imm x0, BRCM_CRASH_CONSOLE_BASE + mov_imm x1, BRCM_CRASH_CONSOLE_REFCLK + mov_imm x2, BRCM_CRASH_CONSOLE_BAUDRATE + b console_16550_core_init + ret +endfunc plat_crash_console_init + + /* --------------------------------------------- + * int plat_crash_console_putc(void) + * Function to print a character on the crash + * console without a C Runtime. + * Clobber list : x1, x2, x3 + * --------------------------------------------- + */ + +func plat_crash_console_putc + mov_imm x1, BRCM_CRASH_CONSOLE_BASE + b console_16550_core_putc + ret +endfunc plat_crash_console_putc + + /* --------------------------------------------- + * int plat_crash_console_flush(void) + * Function to flush crash console + * Clobber list : x0, x1 + * --------------------------------------------- + */ +func plat_crash_console_flush + mov_imm x0, BRCM_CRASH_CONSOLE_BASE + b console_16550_core_flush + ret +endfunc plat_crash_console_flush + + /* ----------------------------------------------------- + * Placeholder function which should be redefined by + * each platform. This function is allowed to use + * registers x0 - x17. + * ----------------------------------------------------- + */ + +func plat_disable_acp + /*TBD-STINGRAY*/ + ret +endfunc plat_disable_acp + + /* ----------------------------------------------------- + * unsigned int plat_is_my_cpu_primary (void); + * + * Find out whether the current cpu is the primary + * cpu (applicable only after a cold boot) + * ----------------------------------------------------- + */ +func plat_is_my_cpu_primary + mrs x0, mpidr_el1 + b platform_is_primary_cpu +endfunc plat_is_my_cpu_primary + + /* ----------------------------------------------------- + * unsigned int plat_my_core_pos(void) + * This function uses the plat_brcm_calc_core_pos() + * definition to get the index of the calling CPU. + * ----------------------------------------------------- + */ +func plat_my_core_pos + mrs x0, mpidr_el1 + b plat_brcm_calc_core_pos +endfunc plat_my_core_pos + + /* ----------------------------------------------------- + * unsigned int platform_is_primary_cpu (void); + * + * Find out whether the current cpu is the primary + * cpu (applicable only after a cold boot) + * ----------------------------------------------------- + */ +func platform_is_primary_cpu + mov x9, x30 + bl plat_my_core_pos + cmp x0, #PRIMARY_CPU + cset x0, eq + ret x9 +endfunc platform_is_primary_cpu + + /* ----------------------------------------------------- + * unsigned int plat_brcm_calc_core_pos(uint64_t mpidr) + * Helper function to calculate the core position. + * With this function: CorePos = (ClusterId * 4) + + * CoreId + * ----------------------------------------------------- + */ +func plat_brcm_calc_core_pos + and x1, x0, #MPIDR_CPU_MASK + and x0, x0, #MPIDR_CLUSTER_MASK + add x0, x1, x0, LSR #7 + ret +endfunc plat_brcm_calc_core_pos + +func plat_get_my_entrypoint + mrs x0, mpidr_el1 + b platform_get_entrypoint +endfunc plat_get_my_entrypoint diff --git a/plat/brcm/board/stingray/bcm958742t-ns3.mk b/plat/brcm/board/stingray/bcm958742t-ns3.mk new file mode 100644 index 000000000..f6df3b7af --- /dev/null +++ b/plat/brcm/board/stingray/bcm958742t-ns3.mk @@ -0,0 +1,16 @@ +# +# Copyright (c) 2015 - 2020, Broadcom +# +# SPDX-License-Identifier: BSD-3-Clause +# + +####################################################### +# Board config file for bcm958742t-ns3 Stingray SST100-NS3 +####################################################### + +include plat/brcm/board/stingray/bcm958742t.mk + +# Load BL33 at 0xFF00_0000 address +ifneq (${BL33_OVERRIDE_LOAD_ADDR},) +$(eval $(call add_define_val,BL33_OVERRIDE_LOAD_ADDR,0xFF000000)) +endif diff --git a/plat/brcm/board/stingray/bcm958742t.mk b/plat/brcm/board/stingray/bcm958742t.mk new file mode 100644 index 000000000..5e164b856 --- /dev/null +++ b/plat/brcm/board/stingray/bcm958742t.mk @@ -0,0 +1,19 @@ +# +# Copyright (c) 2015 - 2020, Broadcom +# +# SPDX-License-Identifier: BSD-3-Clause +# + +####################################################### +# Board config file for bcm958742t Stingray SST100 +####################################################### +BOARD_FAMILY := "" +$(eval $(call add_define,BOARD_FAMILY)) + +# Board has internal programmable regulator +IHOST_REG_TYPE := IHOST_REG_INTEGRATED +$(eval $(call add_define,IHOST_REG_TYPE)) + +# Board has internal programmable regulator +VDDC_REG_TYPE := VDDC_REG_INTEGRATED +$(eval $(call add_define,VDDC_REG_TYPE)) diff --git a/plat/brcm/board/stingray/include/crmu_def.h b/plat/brcm/board/stingray/include/crmu_def.h new file mode 100644 index 000000000..ebc2bb65b --- /dev/null +++ b/plat/brcm/board/stingray/include/crmu_def.h @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2019-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CRMU_DEF_H +#define CRMU_DEF_H + +#define CRMU_REGS_BASE 0x66410000 +/* 32 kB IDRAM */ +#define CRMU_IDRAM_BASE_ADDR CRMU_REGS_BASE +#define CRMU_IDRAM_SIZE 0x8000 +/* 4 kB Scratch RAM */ +#define CRMU_SRAM_BASE (CRMU_IDRAM_BASE_ADDR + CRMU_IDRAM_SIZE) +#define CRMU_SRAM_SIZE 0x1000 + +#define CRMU_RESERVED_SPACE 0x3000 +#define CRMU_CORE_BASE (CRMU_SRAM_BASE + CRMU_SRAM_SIZE + \ + CRMU_RESERVED_SPACE) + +#define CRMU_SHARED_SRAM_BASE CRMU_SRAM_BASE +#define CRMU_SHARED_SRAM_SIZE 0x200 +#define CRMU_CFG_BASE (CRMU_SHARED_SRAM_BASE + \ + CRMU_SHARED_SRAM_SIZE) + +#define CRMU_PWR_GOOD_STATUS CRMU_CORE_BASE +#define CRMU_PWR_GOOD_STATUS__BBL_POWER_GOOD 0 +#define CRMU_ISO_CELL_CONTROL (CRMU_CORE_BASE + 0x4) +#define CRMU_ISO_CELL_CONTROL__CRMU_ISO_PDBBL 16 +#define CRMU_ISO_CELL_CONTROL__CRMU_ISO_PDBBL_TAMPER 24 +#define CRMU_SPRU_SOURCE_SEL_STAT (CRMU_CORE_BASE + 0xc) +#define CRMU_SPRU_SOURCE_SEL_STAT__SPRU_SOURCE_SELECT 0 +#define BSTI_BASE (CRMU_CORE_BASE + 0x28) +#define BSTI_CONTROL_OFFSET BSTI_BASE +#define BSTI_COMMAND_OFFSET (BSTI_BASE + 0x4) + +#define OCOTP_REGS_BASE (CRMU_CORE_BASE + 0x400) + +#define CRMU_TCI_BASE (CRMU_CORE_BASE + 0x800) +#define CRMU_SWREG_STATUS_ADDR (CRMU_TCI_BASE + 0x0c) +#define CRMU_CHIP_OTPC_STATUS (CRMU_TCI_BASE + 0x10) +#define CRMU_CHIP_OTPC_STATUS__OTP_BISR_LOAD_DONE 19 +#define CRMU_BISR_PDG_MASK (CRMU_TCI_BASE + 0x4c) +#define CRMU_BISR_PDG_MASK__CRMU_BISR_IHOST0 2 +#define CRMU_BISR_PDG_MASK__CRMU_BISR_IHOST1 3 +#define CRMU_BISR_PDG_MASK__CRMU_BISR_IHOST2 4 +#define CRMU_BISR_PDG_MASK__CRMU_BISR_IHOST3 0 +#define CRMU_POWER_POLL (CRMU_TCI_BASE + 0x60) +#define CRMU_OTP_STATUS CRMU_POWER_POLL +#define CRMU_OTP_STATUS_BIT 1 +#define CRMU_DDR_PHY_AON_CTRL (CRMU_TCI_BASE + 0x64) +#define CRMU_DDRPHY2_HW_RESETN_R BIT(21) +#define CRMU_DDRPHY2_PWROKIN_PHY_R BIT(20) +#define CRMU_DDRPHY2_PWRONIN_PHY_R BIT(19) +#define CRMU_DDRPHY2_ISO_PHY_DFI_R BIT(18) +#define CRMU_DDRPHY2_ISO_PHY_REGS_R BIT(17) +#define CRMU_DDRPHY2_ISO_PHY_PLL_R BIT(16) +#define CRMU_DDRPHY1_HW_RESETN_R BIT(13) +#define CRMU_DDRPHY1_PWROKIN_PHY_R BIT(12) +#define CRMU_DDRPHY1_PWRONIN_PHY_R BIT(11) +#define CRMU_DDRPHY1_ISO_PHY_DFI_R BIT(10) +#define CRMU_DDRPHY1_ISO_PHY_REGS_R BIT(9) +#define CRMU_DDRPHY1_ISO_PHY_PLL_R BIT(8) +#define CRMU_DDRPHY0_HW_RESETN_R BIT(5) +#define CRMU_DDRPHY0_PWROKIN_PHY_R BIT(4) +#define CRMU_DDRPHY0_PWRONIN_PHY_R BIT(3) +#define CRMU_DDRPHY0_ISO_PHY_DFI_R BIT(2) +#define CRMU_DDRPHY0_ISO_PHY_REGS_R BIT(1) +#define CRMU_DDRPHY0_ISO_PHY_PLL_R BIT(0) +#define CRMU_EMEM_RESET_N_R BIT(16) +#define CRMU_EMEM_PRESET_N_R BIT(0) +#define CRMU_SWREG_CTRL_ADDR (CRMU_TCI_BASE + 0x6c) +#define CRMU_AON_CTRL1 (CRMU_TCI_BASE + 0x70) +#define CRMU_AON_CTRL1__LCPLL1_ISO_IN 18 +#define CRMU_AON_CTRL1__LCPLL1_PWRON_LDO 19 +#define CRMU_AON_CTRL1__LCPLL1_PWR_ON 20 +#define CRMU_AON_CTRL1__LCPLL0_ISO_IN 21 +#define CRMU_AON_CTRL1__LCPLL0_PWRON_LDO 22 +#define CRMU_AON_CTRL1__LCPLL0_PWR_ON 23 +#define CRMU_PCIE_LCPLL_PWR_ON_SHIFT 29 +#define CRMU_PCIE_LCPLL_PWR_ON_MASK BIT(CRMU_PCIE_LCPLL_PWR_ON_SHIFT) +#define CRMU_PCIE_LCPLL_PWRON_LDO_SHIFT 28 +#define CRMU_PCIE_LCPLL_PWRON_LDO_MASK BIT(CRMU_PCIE_LCPLL_PWRON_LDO_SHIFT) +#define CRMU_PCIE_LCPLL_ISO_IN_SHIFT 27 +#define CRMU_PCIE_LCPLL_ISO_IN_MASK BIT(CRMU_PCIE_LCPLL_ISO_IN_SHIFT) +#define CRMU_MASTER_AXI_ARUSER_CONFIG (CRMU_TCI_BASE + 0x74) +#define CRMU_MASTER_AXI_AWUSER_CONFIG (CRMU_TCI_BASE + 0x78) +#define CRMU_DDR_PHY_AON_CTRL_1 (CRMU_TCI_BASE + 0x8c) + +#define CDRU_BASE_ADDR (CRMU_CORE_BASE + 0x1000) +#define CDRU_MISC_RESET_CONTROL CDRU_BASE_ADDR +#define CDRU_MISC_RESET_CONTROL_TS_RESET_N 16 +#define CDRU_MISC_RESET_CONTROL__CDRU_USBSS_RESET_N 14 +#define CDRU_MISC_RESET_CONTROL__CDRU_SATA_RESET_N_R 15 +#define CDRU_MISC_RESET_CONTROL__CDRU_MHB_RESET_N_R 13 +#define CDRU_MISC_RESET_CONTROL__CDRU_PCIE_RESET_N_R 3 +#define CDRU_MISC_RESET_CONTROL__CDRU_PM_RESET_N_R 2 +#define CDRU_MISC_RESET_CONTROL__CDRU_NITRO_RESET_N_R 1 + +#define CDRU_PROC_EVENT_CLEAR (CDRU_BASE_ADDR + 0x48) +#define CDRU_PROC_EVENT_CLEAR__IH0_CDRU_STANDBYWFIL2 0 +#define CDRU_PROC_EVENT_CLEAR__IH0_CDRU_STANDBYWFI 3 +#define CDRU_PROC_EVENT_CLEAR__IH1_CDRU_STANDBYWFIL2 5 +#define CDRU_PROC_EVENT_CLEAR__IH1_CDRU_STANDBYWFI 8 +#define CDRU_PROC_EVENT_CLEAR__IH2_CDRU_STANDBYWFIL2 10 +#define CDRU_PROC_EVENT_CLEAR__IH2_CDRU_STANDBYWFI 13 +#define CDRU_PROC_EVENT_CLEAR__IH3_CDRU_STANDBYWFIL2 15 +#define CDRU_PROC_EVENT_CLEAR__IH3_CDRU_STANDBYWFI 18 + +#define CDRU_CHIP_STRAP_CTRL (CDRU_BASE_ADDR + 0x50) +#define CDRU_CHIP_STRAP_CTRL__SOFTWARE_OVERRIDE 31 + +#define CDRU_CHIP_IO_PAD_CONTROL (CDRU_BASE_ADDR + 0x58) +#define CDRU_CHIP_IO_PAD_CONTROL__CDRU_IOMUX_FORCE_PDN_R 8 +#define CDRU_CHIP_IO_PAD_CONTROL__CDRU_IOMUX_FORCE_PAD_IN_R 0 + +#define CDRU_CHIP_STRAP_DATA_LSW (CDRU_BASE_ADDR + 0x5c) +#define CDRU_CHIP_STRAP_DATA_LSW__BISR_BYPASS_MODE 18 +#define CDRU_CHIP_STRAP_DATA_LSW__NIC_MODE_MASK BIT(8) +#define CDRU_CHIP_STRAP_DATA_LSW_PAD_USB_MODE BIT(26) + +#define CDRU_CHIP_STRAP_DATA (CDRU_BASE_ADDR + 0x5c) +#define CDRU_DDR0_CONTROL_OFFSET (CDRU_BASE_ADDR + 0xb8) +#define CDRU_DDR1_CONTROL_OFFSET (CDRU_BASE_ADDR + 0xbc) +#define CDRU_DDR2_CONTROL_OFFSET (CDRU_BASE_ADDR + 0xc0) +#define CRMU_SW_POR_RESET_CTRL (CDRU_BASE_ADDR + 0x100) + +#define CDRU_GENPLL2_CONTROL1 (CDRU_BASE_ADDR + 0x1b0) +#define CDRU_GENPLL2_CONTROL1__CHNL6_FS4_CLK BIT(11) +#define CDRU_GENPLL5_CONTROL1 (CDRU_BASE_ADDR + 0x24c) +#define CDRU_GENPLL5_CONTROL1__CHNL0_DME_CLK BIT(6) +#define CDRU_GENPLL5_CONTROL1__CHNL1_CRYPTO_AE_CLK BIT(7) +#define CDRU_GENPLL5_CONTROL1__CHNL2_RAID_AE_CLK BIT(8) + +#define CDRU_NITRO_CONTROL (CDRU_BASE_ADDR + 0x2c4) +#define CDRU_NITRO_CONTROL__CDRU_NITRO_SEC_MODE_R 20 +#define CDRU_NITRO_CONTROL__CDRU_NITRO_SEC_OVERRIDE_R 16 + +#define CDRU_MISC_CLK_ENABLE_CONTROL (CDRU_BASE_ADDR + 0x2c8) +#define CDRU_MISC_CLK_ENABLE_CONTROL__CDRU_EMEM2_CLK_EN_R 11 +#define CDRU_MISC_CLK_ENABLE_CONTROL__CDRU_EMEM1_CLK_EN_R 10 +#define CDRU_MISC_CLK_ENABLE_CONTROL__CDRU_EMEM0_CLK_EN_R 9 +#define CDRU_MISC_CLK_ENABLE_CONTROL__CDRU_SATA_CLK_EN_R 8 +#define CDRU_MISC_CLK_ENABLE_CONTROL__CDRU_USBSS_CLK_EN_R 7 +#define CDRU_MISC_CLK_ENABLE_CONTROL__CDRU_MHB_CLK_EN_R 6 +#define CDRU_MISC_CLK_ENABLE_CONTROL__CDRU_HSLS_CLK_EN_R 5 +#define CDRU_MISC_CLK_ENABLE_CONTROL__CDRU_SCR_CLK_EN_R 4 +#define CDRU_MISC_CLK_ENABLE_CONTROL__CDRU_FS4_CLK_EN_R 3 +#define CDRU_MISC_CLK_ENABLE_CONTROL__CDRU_PCIE_CLK_EN_R 2 +#define CDRU_MISC_CLK_ENABLE_CONTROL__CDRU_PM_CLK_EN_R 1 +#define CDRU_MISC_CLK_ENABLE_CONTROL__CDRU_NITRO_CLK_EN_R 0 + +#define CDRU_CCN_REGISTER_CONTROL_1 (CDRU_BASE_ADDR + 0x324) +#define CDRU_CCN_REGISTER_CONTROL_1__D2XS_PD_EMEM0_BIT 6 +#define CDRU_CCN_REGISTER_CONTROL_1__D2XS_PD_EMEM1_BIT 5 +#define CDRU_CCN_REGISTER_CONTROL_1__D2XS_PD_EMEM2_BIT 4 + +#define CDRU_CHIP_TOP_SPARE_REG0 (CDRU_BASE_ADDR + 0x378) +#define CDRU_CHIP_TOP_SPARE_REG1 (CDRU_BASE_ADDR + 0x37c) + +#define CENTRAL_TIMER_BASE (CRMU_CORE_BASE + 0x5000) +#define CENTRAL_TIMER_CTRL (CENTRAL_TIMER_BASE + 0x0) +#define CENTRAL_TIMER_GET_L (CENTRAL_TIMER_BASE + 0x4) +#define CENTRAL_TIMER_GET_L0 (CENTRAL_TIMER_BASE + 0x8) /* SCR STM */ +#define CENTRAL_TIMER_GET_L1 (CENTRAL_TIMER_BASE + 0xC) /* FS STM */ +#define CENTRAL_TIMER_GET_L2 (CENTRAL_TIMER_BASE + 0x10) /* iHost0 */ +#define CENTRAL_TIMER_GET_L3 (CENTRAL_TIMER_BASE + 0x14) /* iHost1 */ +#define CENTRAL_TIMER_GET_L4 (CENTRAL_TIMER_BASE + 0x18) /* iHost2 */ +#define CENTRAL_TIMER_GET_L5 (CENTRAL_TIMER_BASE + 0x1C) /* iHost3 */ +#define CENTRAL_TIMER_GET_H (CENTRAL_TIMER_BASE + 0x28) +#define CENTRAL_TIMER_SAT_TMR_ENA (CENTRAL_TIMER_BASE + 0x34) +#define CENTRAL_TIMER_GET_IHOST_ENA_BASE (CENTRAL_TIMER_GET_L2) + +#define CRMU_WDT_REGS_BASE (CRMU_CORE_BASE + 0x6000) + +#define CRMU_MAIL_BOX0 (CRMU_CORE_BASE + 0x8024) +#define CRMU_MAIL_BOX1 (CRMU_CORE_BASE + 0x8028) +#define CRMU_READ_MAIL_BOX0 (CRMU_CORE_BASE + 0x802c) +#define CRMU_READ_MAIL_BOX1 (CRMU_CORE_BASE + 0x8030) +#define AP_TO_SCP_MAILBOX1 CRMU_MAIL_BOX1 +#define SCP_TO_AP_MAILBOX1 CRMU_READ_MAIL_BOX1 +#define CRMU_IHOST_POWER_CONFIG (CRMU_CORE_BASE + 0x8038) +#define CRMU_RESET_EVENT_LOG (CRMU_CORE_BASE + 0x8064) +#define CRMU_SOFT_RESET_CTRL (CRMU_CORE_BASE + 0x8090) +#define CRMU_SOFT_RESET_CTRL__SOFT_PWR_UP_RST 0 +#define CRMU_SOFT_RESET_CTRL__SOFT_SYS_RST 1 +#define CRMU_SPARE_REG_0 (CRMU_CORE_BASE + 0x80b8) +#define CRMU_SPARE_REG_1 (CRMU_CORE_BASE + 0x80bc) +#define CRMU_SPARE_REG_2 (CRMU_CORE_BASE + 0x80c0) +#define CRMU_SPARE_REG_3 (CRMU_CORE_BASE + 0x80c4) +#define CRMU_SPARE_REG_4 (CRMU_CORE_BASE + 0x80c8) +#define CRMU_SPARE_REG_5 (CRMU_CORE_BASE + 0x80cc) +#define CRMU_CORE_ADDR_RANGE0_LOW (CRMU_CORE_BASE + 0x8c30) +#define CRMU_CORE_ADDR_RANGE1_LOW (CRMU_CORE_BASE + 0x8c38) +#define CRMU_CORE_ADDR_RANGE2_LOW (CRMU_CORE_BASE + 0x8c40) +#define CRMU_IHOST_SW_PERSISTENT_REG0 (CRMU_CORE_BASE + 0x8c54) +#define CRMU_IHOST_SW_PERSISTENT_REG1 (CRMU_CORE_BASE + 0x8c58) +#define CRMU_IHOST_SW_PERSISTENT_REG2 (CRMU_CORE_BASE + 0x8c5c) +#define CRMU_IHOST_SW_PERSISTENT_REG3 (CRMU_CORE_BASE + 0x8c60) +#define CRMU_IHOST_SW_PERSISTENT_REG4 (CRMU_CORE_BASE + 0x8c64) +#define CRMU_IHOST_SW_PERSISTENT_REG5 (CRMU_CORE_BASE + 0x8c68) +#define CRMU_IHOST_SW_PERSISTENT_REG6 (CRMU_CORE_BASE + 0x8c6c) +#define CRMU_IHOST_SW_PERSISTENT_REG7 (CRMU_CORE_BASE + 0x8c70) +#define CRMU_BBL_AUTH_CHECK (CRMU_CORE_BASE + 0x8c78) +#define CRMU_SOTP_NEUTRALIZE_ENABLE (CRMU_CORE_BASE + 0x8c84) +#define CRMU_IHOST_SW_PERSISTENT_REG8 (CRMU_CORE_BASE + 0x8c88) +#define CRMU_IHOST_SW_PERSISTENT_REG9 (CRMU_CORE_BASE + 0x8c8c) +#define CRMU_IHOST_SW_PERSISTENT_REG10 (CRMU_CORE_BASE + 0x8c90) +#define CRMU_IHOST_SW_PERSISTENT_REG11 (CRMU_CORE_BASE + 0x8c94) + +#define CNT_CONTROL_BASE (CRMU_CORE_BASE + 0x9000) +#define CNTCR (CNT_CONTROL_BASE) +#define CNTCR__EN BIT(0) + +#define SPRU_BBL_WDATA (CRMU_CORE_BASE + 0xa000) +#define SPRU_BBL_CMD (CRMU_CORE_BASE + 0xa004) +#define SPRU_BBL_CMD__IND_SOFT_RST_N 10 +#define SPRU_BBL_CMD__IND_WR 11 +#define SPRU_BBL_CMD__BBL_ADDR_R 0 +#define SPRU_BBL_CMD__IND_RD 12 +#define SPRU_BBL_CMD__BBL_ADDR_R 0 +#define SPRU_BBL_STATUS (CRMU_CORE_BASE + 0xa008) +#define SPRU_BBL_STATUS__ACC_DONE 0 +#define SPRU_BBL_RDATA (CRMU_CORE_BASE + 0xa00c) + +#endif /* CRMU_DEF_H */ diff --git a/plat/brcm/board/stingray/include/plat_macros.S b/plat/brcm/board/stingray/include/plat_macros.S new file mode 100644 index 000000000..dccd54a32 --- /dev/null +++ b/plat/brcm/board/stingray/include/plat_macros.S @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2015-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLAT_MACROS_S +#define PLAT_MACROS_S + +.section .rodata.gic_reg_name, "aS" +gicc_regs: + .asciz "gicc_hppir", "gicc_ahppir", "gicc_ctlr", "" +gicd_pend_reg: + .asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n Offset:\t\t\tvalue\n" +newline: + .asciz "\n" +spacer: + .asciz ":\t\t0x" + +/* --------------------------------------------- + * The below required platform porting macro + * prints out relevant registers whenever an + * unhandled exception is taken in BL31. + * --------------------------------------------- + */ +.macro plat_crash_print_regs + nop +.endm + +/* --------------------------------------------- + * The below macro prints out relevant GIC + * registers whenever an unhandled exception is + * taken in BL31. + * --------------------------------------------- + */ +.macro plat_print_gic_regs + nop + /*TBD-STINGRAY*/ +.endm + +/* ------------------------------------------------ + * The below required platform porting macro prints + * out relevant interconnect registers whenever an + * unhandled exception is taken in BL3-1. + * ------------------------------------------------ + */ +.macro plat_print_interconnect_regs + nop + /*TBD-STINGRAY*/ +.endm + +#endif /* PLAT_MACROS_S */ diff --git a/plat/brcm/board/stingray/include/platform_def.h b/plat/brcm/board/stingray/include/platform_def.h new file mode 100644 index 000000000..950c66b69 --- /dev/null +++ b/plat/brcm/board/stingray/include/platform_def.h @@ -0,0 +1,272 @@ +/* + * Copyright (c) 2015-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +#include +#include +#include + +#include + +#include + +#include "sr_def.h" + +/* + * Most platform porting definitions provided by included headers + */ +#define PLAT_BRCM_SCP_TZC_DRAM1_SIZE ULL(0x0) + +/* + * Required by standard platform porting definitions + */ +#define PLATFORM_CLUSTER0_CORE_COUNT 2 +#define PLATFORM_CLUSTER1_CORE_COUNT 2 +#define PLATFORM_CLUSTER2_CORE_COUNT 2 +#define PLATFORM_CLUSTER3_CORE_COUNT 2 +#define PLATFORM_CLUSTER4_CORE_COUNT 2 + +#define BRCM_SYSTEM_COUNT 1 +#define BRCM_CLUSTER_COUNT 5 + +#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER0_CORE_COUNT + \ + PLATFORM_CLUSTER1_CORE_COUNT+ \ + PLATFORM_CLUSTER2_CORE_COUNT+ \ + PLATFORM_CLUSTER3_CORE_COUNT+ \ + PLATFORM_CLUSTER4_CORE_COUNT) + +#define PLAT_NUM_PWR_DOMAINS (BRCM_SYSTEM_COUNT + \ + BRCM_CLUSTER_COUNT + \ + PLATFORM_CORE_COUNT) + +#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL2 + +/* TBD-STINGRAY */ +#define 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 << CACHE_WRITEBACK_SHIFT) + +/* TBD-STINGRAY */ +#define PLATFORM_MAX_AFFLVL MPIDR_AFFLVL1 + +#define BL1_PLATFORM_STACK_SIZE 0x3300 +#define BL2_PLATFORM_STACK_SIZE 0xc000 +#define BL11_PLATFORM_STACK_SIZE 0x2b00 +#define DEFAULT_PLATFORM_STACK_SIZE 0x400 +#if IMAGE_BL1 +# define PLATFORM_STACK_SIZE BL1_PLATFORM_STACK_SIZE +#else +#if IMAGE_BL2 +#ifdef USE_BL1_RW +# define PLATFORM_STACK_SIZE BL2_PLATFORM_STACK_SIZE +#else +# define PLATFORM_STACK_SIZE BL1_PLATFORM_STACK_SIZE +#endif +#else +#if IMAGE_BL11 +# define PLATFORM_STACK_SIZE BL11_PLATFORM_STACK_SIZE +#else +# define PLATFORM_STACK_SIZE DEFAULT_PLATFORM_STACK_SIZE +#endif +#endif +#endif + +#define PLAT_BRCM_TRUSTED_SRAM_BASE 0x66D00000 +#define PLAT_BRCM_TRUSTED_SRAM_SIZE 0x00040000 + +#ifdef RUN_BL1_FROM_QSPI /* BL1 XIP from QSPI */ +# define PLAT_BRCM_TRUSTED_ROM_BASE QSPI_BASE_ADDR +#elif RUN_BL1_FROM_NAND /* BL1 XIP from NAND */ +# define PLAT_BRCM_TRUSTED_ROM_BASE NAND_BASE_ADDR +#else /* BL1 executed in ROM */ +# define PLAT_BRCM_TRUSTED_ROM_BASE ROM_BASE_ADDR +#endif +#define PLAT_BRCM_TRUSTED_ROM_SIZE 0x00040000 + +/******************************************************************************* + * BL1 specific defines. + ******************************************************************************/ +#define BL1_RO_BASE PLAT_BRCM_TRUSTED_ROM_BASE +#define BL1_RO_LIMIT (PLAT_BRCM_TRUSTED_ROM_BASE \ + + PLAT_BRCM_TRUSTED_ROM_SIZE) + +/* + * Put BL1 RW at the beginning of the Trusted SRAM. + */ +#define BL1_RW_BASE (BRCM_BL_RAM_BASE) +#define BL1_RW_LIMIT (BL1_RW_BASE + 0x12000) + +#define BL11_RW_BASE BL1_RW_LIMIT +#define BL11_RW_LIMIT (PLAT_BRCM_TRUSTED_SRAM_BASE + \ + PLAT_BRCM_TRUSTED_SRAM_SIZE) + +/******************************************************************************* + * BL2 specific defines. + ******************************************************************************/ +#if RUN_BL2_FROM_QSPI /* BL2 XIP from QSPI */ +#define BL2_BASE QSPI_BASE_ADDR +#define BL2_LIMIT (BL2_BASE + 0x40000) +#define BL2_RW_BASE BL1_RW_LIMIT +#define BL2_RW_LIMIT (PLAT_BRCM_TRUSTED_SRAM_BASE + \ + PLAT_BRCM_TRUSTED_SRAM_SIZE) +#elif RUN_BL2_FROM_NAND /* BL2 XIP from NAND */ +#define BL2_BASE NAND_BASE_ADDR +#define BL2_LIMIT (BL2_BASE + 0x40000) +#define BL2_RW_BASE BL1_RW_LIMIT +#define BL2_RW_LIMIT (PLAT_BRCM_TRUSTED_SRAM_BASE + \ + PLAT_BRCM_TRUSTED_SRAM_SIZE) +#else +#define BL2_BASE (BL1_RW_LIMIT + PAGE_SIZE) +#define BL2_LIMIT (BRCM_BL_RAM_BASE + BRCM_BL_RAM_SIZE) +#endif + +/* + * BL1 persistent area in internal SRAM + * This area will increase as more features gets into BL1 + */ +#define BL1_PERSISTENT_DATA_SIZE 0x2000 + +/* To reduce BL2 runtime footprint, we can re-use some BL1_RW area */ +#define BL1_RW_RECLAIM_BASE (PLAT_BRCM_TRUSTED_SRAM_BASE + \ + BL1_PERSISTENT_DATA_SIZE) + +/******************************************************************************* + * BL3-1 specific defines. + ******************************************************************************/ +/* Max Size of BL31 (in DRAM) */ +#define PLAT_BRCM_MAX_BL31_SIZE 0x30000 + +#ifdef USE_DDR +#define BL31_BASE BRCM_AP_TZC_DRAM1_BASE + +#define BL31_LIMIT (BRCM_AP_TZC_DRAM1_BASE + \ + PLAT_BRCM_MAX_BL31_SIZE) +#else +/* Put BL3-1 at the end of external on-board SRAM connected as NOR flash */ +#define BL31_BASE (NOR_BASE_ADDR + NOR_SIZE - \ + PLAT_BRCM_MAX_BL31_SIZE) + +#define BL31_LIMIT (NOR_BASE_ADDR + NOR_SIZE) +#endif + +#define SECURE_DDR_END_ADDRESS BL31_LIMIT + +#ifdef NEED_SCP_BL2 +#define SCP_BL2_BASE BL31_BASE +#define PLAT_MAX_SCP_BL2_SIZE 0x9000 +#define PLAT_SCP_COM_SHARED_MEM_BASE (CRMU_SHARED_SRAM_BASE) +/* dummy defined */ +#define PLAT_BRCM_MHU_BASE 0x0 +#endif + +#define SECONDARY_CPU_SPIN_BASE_ADDR BRCM_SHARED_RAM_BASE + +/* Generic system timer counter frequency */ +#ifndef SYSCNT_FREQ +#define SYSCNT_FREQ (125 * 1000 * 1000) +#endif + +/* + * Enable the BL32 definitions, only when optee os is selected as secure + * payload (BL32). + */ +#ifdef SPD_opteed +/* + * Reserved Memory Map : SHMEM & TZDRAM. + * + * +--------+----------+ 0x8D000000 + * | SHMEM (NS) | 16MB + * +-------------------+ 0x8E000000 + * | | TEE_RAM(S)| 4MB + * + TZDRAM +----------+ 0x8E400000 + * | | TA_RAM(S) | 12MB + * +-------------------+ 0x8F000000 + * | BL31 Binary (S) | 192KB + * +-------------------+ 0x8F030000 + */ + +#define BL32_VA_SIZE (4 * 1024 * 1024) +#define BL32_BASE (0x8E000000) +#define BL32_LIMIT (BL32_BASE + BL32_VA_SIZE) +#define TSP_SEC_MEM_BASE BL32_BASE +#define TSP_SEC_MEM_SIZE BL32_VA_SIZE +#endif + +#ifdef SPD_opteed + #define SECURE_DDR_BASE_ADDRESS BL32_BASE +#else + #define SECURE_DDR_BASE_ADDRESS BL31_BASE +#endif +/******************************************************************************* + * Platform specific page table and MMU setup constants + ******************************************************************************/ + +#define MAX_XLAT_TABLES 7 + +#define PLAT_BRCM_MMAP_ENTRIES 10 + +#define MAX_MMAP_REGIONS (PLAT_BRCM_MMAP_ENTRIES + \ + BRCM_BL_REGIONS) + +#ifdef USE_DDR +#ifdef BL33_OVERRIDE_LOAD_ADDR +#define PLAT_BRCM_NS_IMAGE_OFFSET BL33_OVERRIDE_LOAD_ADDR +#else +/* + * BL3-3 image starting offset. + * Putting start of DRAM as of now. + */ +#define PLAT_BRCM_NS_IMAGE_OFFSET 0x80000000 +#endif /* BL33_OVERRIDE_LOAD_ADDR */ +#else +/* + * BL3-3 image starting offset. + * Putting start of external on-board SRAM as of now. + */ +#define PLAT_BRCM_NS_IMAGE_OFFSET NOR_BASE_ADDR +#endif /* USE_DDR */ +/****************************************************************************** + * Required platform porting definitions common to all BRCM platforms + *****************************************************************************/ + +#define MAX_IO_DEVICES 5 +#define MAX_IO_HANDLES 6 + +#define PRIMARY_CPU 0 + +/* GIC Parameter */ +#define PLAT_BRCM_GICD_BASE GIC500_BASE +#define PLAT_BRCM_GICR_BASE (GIC500_BASE + 0x200000) + +/* Define secure interrupt as per Group here */ +#define PLAT_BRCM_G1S_IRQ_PROPS(grp) \ + INTR_PROP_DESC(BRCM_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, (grp), \ + GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(BRCM_IRQ_SEC_SPI_0, GIC_HIGHEST_SEC_PRIORITY, (grp), \ + GIC_INTR_CFG_EDGE) + +#define PLAT_BRCM_G0_IRQ_PROPS(grp) \ + INTR_PROP_DESC(BRCM_IRQ_SEC_SGI_0, PLAT_SDEI_NORMAL_PRI, (grp), \ + GIC_INTR_CFG_EDGE), \ + +/* + *CCN 502 related constants. + */ +#define PLAT_BRCM_CLUSTER_COUNT 4 /* Number of RN-F Masters */ +#define PLAT_BRCM_CLUSTER_TO_CCN_ID_MAP CLUSTER0_NODE_ID, CLUSTER1_NODE_ID, CLUSTER2_NODE_ID, CLUSTER3_NODE_ID +#define CCN_SIZE 0x1000000 +#define CLUSTER0_NODE_ID 1 +#define CLUSTER1_NODE_ID 7 +#define CLUSTER2_NODE_ID 9 +#define CLUSTER3_NODE_ID 15 + +#endif diff --git a/plat/brcm/board/stingray/include/sr_def.h b/plat/brcm/board/stingray/include/sr_def.h new file mode 100644 index 000000000..ac3ee782e --- /dev/null +++ b/plat/brcm/board/stingray/include/sr_def.h @@ -0,0 +1,614 @@ +/* + * Copyright (c) 2016-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SR_DEF_H +#define SR_DEF_H + +#ifndef __ASSEMBLER__ +#include +#endif + +#include +#include + +#include + +/* Special value used to verify platform parameters from BL2 to BL3-1 */ +#define BRCM_BL31_PLAT_PARAM_VAL ULL(0x0f1e2d3c4b5a6978) + +#define MHB_BASE_ADDR 0x60000000 +#define PLAT_BRCM_CCN_BASE 0x61000000 +#define CORESIGHT_BASE_ADDR 0x62000000 +#define SMMU_BASE 0x64000000 + +/* memory map entries*/ +/* Grouping block device for bigger MMU region */ +/* covers MHB, CNN, coresight, GIC, MMU, APB, CRMU */ +#define PERIPH0_BASE MHB_BASE_ADDR +#define PERIPH0_SIZE 0x06d00000 + +#define PERIPH1_BASE 0x66d80000 +#define PERIPH1_SIZE 0x00f80000 + +#define HSLS_BASE_ADDR 0x68900000 +#define HSLS_SIZE 0x04500000 + +#define GIC500_BASE 0x63c00000 +#define GIC500_SIZE 0x400000 + +/******************************************************************************* + * CCN related constants + ******************************************************************************/ +#define OLY_MN_REGISTERS_NODE0_SECURE_ACCESS (PLAT_BRCM_CCN_BASE + 0x0) + +#define OLY_RNI3PDVM_REGISTERS_NODE8_AUX_CTL (PLAT_BRCM_CCN_BASE + 0x880500) + +/* Used for acceleration of coherent ordered writes */ +#define OLY_RNI3PDVM_REGISTERS_NODE8_AUX_CTL_WUO BIT(4) +/* Wait for completion of requests at RN-I */ +#define OLY_RNI3PDVM_REGISTERS_NODE8_AUX_CTL_WFC BIT(3) + +/* + * Forces all reads from the RN-I to be sent with the request order bit set + * and this ensures ordered allocation of read data buffers in the RN-I + */ +#define OLY_RNI3PDVM_REGISTERS_NODE8_AUX_CTL_RQO BIT(5) + +#define OLY_RNI3PDVM_REGISTERS_NODE14_AUX_CTL (PLAT_BRCM_CCN_BASE + 0x8e0500) + +/* Wait for completion of requests at RN-I */ +#define OLY_RNI3PDVM_REGISTERS_NODE14_AUX_CTL_WFC BIT(3) + +#define OLY_HNI_REGISTERS_NODE0_POS_CONTROL (PLAT_BRCM_CCN_BASE + 0x80000) +#define POS_CONTROL_HNI_POS_EN BIT(0) + +#define OLY_HNI_REGISTERS_NODE0_PCIERC_RNI_NODEID_LIST \ + (PLAT_BRCM_CCN_BASE + 0x80008) +/* PAXB and PAXC connected to 8th Node */ +#define SR_RNI_PCIE_CONNECTED BIT(8) +/* PAXB connected to 6th Node */ +#define SRP_RNI_PCIE_CONNECTED BIT(6) + +#define OLY_HNI_REGISTERS_NODE0_SA_AUX_CTL (PLAT_BRCM_CCN_BASE + 0x80500) +#define SA_AUX_CTL_POS_EARLY_WR_COMP_EN BIT(5) +#define SA_AUX_CTL_SER_DEVNE_WR BIT(9) + +/******************************************************************************* + * Coresight related constants + ******************************************************************************/ +#define CORESIGHT_BASE_ADDR 0x62000000 + +#define IHOST0_BASE 0x66000000 +#define IHOST_ADDR_SPACE 0x2000 + +/******************************************************************************* + * SCR related constants + ******************************************************************************/ +#define SCR_BASE 0x6600a000 +#define SCR_ARCACHE_OFFSET 4 +#define SCR_ARCACHE_MASK (0x3 << SCR_ARCACHE_OFFSET) +#define SCR_AWCACHE_OFFSET 6 +#define SCR_AWCACHE_MASK (0x3 << SCR_AWCACHE_OFFSET) +#define SCR_AXCACHE_CONFIG_MASK (SCR_ARCACHE_MASK | SCR_AWCACHE_MASK) +#define SCR_TBUX_AXCACHE_CONFIG ((0x1 << SCR_AWCACHE_OFFSET) | \ + (0x1 << SCR_ARCACHE_OFFSET)) + +#define SCR_REGS_SCR_SOFT_RESET (SCR_BASE + 0x1c) +#define SCR_REGS_GIC_SOFT_RESET BIT(0) + +#define SCR_GPV_BASE 0x66100000 +#define SCR_NOC_SECURITY0 (SCR_GPV_BASE + 0x08) +#define SCR_NOC_DDR_REGISTER_ACCESS (SCR_GPV_BASE + 0x30) + +/******************************************************************************* + * MEMC and DDR related constants + ******************************************************************************/ +#define DDR0_CONTROL_ROOT 0x66200000 +#define EMEM_SS_CFG_0_ROOT 0x66202000 +#define EMEM_SYS_IF_0_ROOT 0x66204000 +#define DDR_PHY0_ROOT 0x66240000 + +#define DDR1_CONTROL_ROOT 0x66280000 +#define EMEM_SS_CFG_1_ROOT 0x66282000 +#define EMEM_SYS_IF_1_ROOT 0x66284000 +#define DDR_PHY1_ROOT 0x662c0000 + +#define DDR2_CONTROL_ROOT 0x66300000 +#define EMEM_SS_CFG_2_ROOT 0x66302000 +#define EMEM_SYS_IF_2_ROOT 0x66304000 +#define DDR_PHY2_ROOT 0x66340000 + +/******************************************************************************* + * TZC400 related constants + ******************************************************************************/ +#define TZC_400_BASE 0x66d84000 + +/******************************************************************************* + * FS4 related constants + ******************************************************************************/ +#define FS4_SRAM_IDM_IO_CONTROL_DIRECT 0x66d8a408 + +#define FS4_CRYPTO_IDM_IO_CONTROL_DIRECT 0x66d8e408 +#define FS4_CRYPTO_IDM_RESET_CONTROL 0x66d8e800 +#define FS4_CRYPTO_BASE 0x67000000 +#define FS4_CRYPTO_DME_BASE (FS4_CRYPTO_BASE + 0x280000) + +#define FS4_RAID_IDM_IO_CONTROL_DIRECT 0x66d8f408 +#define FS4_RAID_IDM_IO_STATUS 0x66d8f500 +#define FS4_RAID_IDM_RESET_CONTROL 0x66d8f800 +#define FS4_RAID_BASE 0x67400000 +#define FS4_RAID_DME_BASE (FS4_RAID_BASE + 0x280000) + +#define FS4_CRYPTO_GPV_BASE 0x67300000 +#define FS4_RAID_GPV_BASE 0x67700000 + +#define FS6_PKI_BASE 0x67400000 +#define FS6_PKI_DME_BASE 0x66D90000 + +#define TZC400_FS_SRAM_ROOT 0x66d84000 +#define GATE_KEEPER_OFFSET 0x8 +#define REGION_ATTRIBUTES_0_OFFSET 0x110 +#define REGION_ID_ACCESS_0_OFFSET 0x114 + +#define NIC400_FS_NOC_ROOT 0x66e00000 +#define NIC400_FS_NOC_SECURITY2_OFFSET 0x10 +#define NIC400_FS_NOC_SECURITY4_OFFSET 0x18 +#define NIC400_FS_NOC_SECURITY7_OFFSET 0x24 + +/******************************************************************************* + * SATA PHY related constants + ******************************************************************************/ +#define SATA_BASE 0x67d00000 + +/******************************************************************************* + * USB related constants + ******************************************************************************/ +#define USB_BASE 0x68500000 +#define USB_SIZE 0x00400000 +#define XHC_BASE (USB_BASE + 0x11000) +#define MAX_USB_PORTS 3 + +/******************************************************************************* + * HSLS related constants + ******************************************************************************/ +#define IPROC_ROOT 0x68900000 +#define HSLS_ICFG_REGS_BASE IPROC_ROOT +#define HSLS_IDM_REGS_BASE 0x68e00000 +#define HSLS_MODE_SEL_CONTROL 0x68a40000 +#define HSLS_TZPC_BASE 0x68b40000 +#define HSLS_GPV_BASE 0x6cd00000 + +/******************************************************************************* + * Chip ID related constants + ******************************************************************************/ +#define ICFG_CHIP_ID HSLS_ICFG_REGS_BASE +#define CHIP_ID_SR 0xd730 +#define CHIP_ID_NS3Z 0xe56d +#define CHIP_ID_MASK 0xf000 +#define ICFG_CHIP_REVISION_ID (HSLS_ICFG_REGS_BASE + 0x4) +#define PLAT_CHIP_ID_GET (mmio_read_32(ICFG_CHIP_ID)) +#define PLAT_CHIP_REV_GET (mmio_read_32(ICFG_CHIP_REVISION_ID)) + +/******************************************************************************* + * Timers related constants + ******************************************************************************/ +/* ChipcommonG_tim0_TIM_TIMER1Load 0x68930000 */ +#define SP804_TIMER0_BASE 0x68930000 +#define SP804_TIMER1_BASE 0x68940000 +#define SP804_TIMER0_TIMER_VAL_REG_OFFSET 0x4 +#define SP804_TIMER0_CLKMULT 2 +#define SP804_TIMER0_CLKDIV 25 + +/******************************************************************************* + * GPIO related constants + ******************************************************************************/ +#define IPROC_GPIO_NS_BASE 0x689d0000 +#define IPROC_GPIO_S_BASE 0x68b00000 +#define IPROC_GPIO_NR 151 +#define GPIO_S_CNTRL_REG 0x68b60000 + +/******************************************************************************* + * I2C SMBUS related constants + ******************************************************************************/ +#define SMBUS0_REGS_BASE 0x689b0000 +#define SMBUS1_REGS_BASE 0x689e0000 + +/******************************************************************************* + * UART related constants + ******************************************************************************/ +#define ChipcommonG_UART0_UART_RBR_THR_DLL 0x68a00000 +#define ChipcommonG_UART1_UART_RBR_THR_DLL 0x68a10000 +#define ChipcommonG_UART2_UART_RBR_THR_DLL 0x68a20000 +#define ChipcommonG_UART3_UART_RBR_THR_DLL 0x68a30000 + +#define UART0_BASE_ADDR ChipcommonG_UART0_UART_RBR_THR_DLL +#define UART1_BASE_ADDR ChipcommonG_UART1_UART_RBR_THR_DLL +#define UART2_BASE_ADDR ChipcommonG_UART2_UART_RBR_THR_DLL +#define UART3_BASE_ADDR ChipcommonG_UART3_UART_RBR_THR_DLL + +#define UART_SPR_OFFSET 0x1c /* Scratch Pad Register */ + +#define LOG_LEVEL_REGISTER CRMU_SPARE_REG_3 +#define GET_LOG_LEVEL() (mmio_read_32(LOG_LEVEL_REGISTER)) +#define SET_LOG_LEVEL(x) (mmio_write_32(LOG_LEVEL_REGISTER, x)) + +#define IO_RETRY_REGISTER CRMU_SPARE_REG_4 + +#define DWC_UART_REFCLK (25 * 1000 * 1000) +#define DWC_UART_REFCLK_DIV 16 +/* Baud rate in emulation will vary based on setting of 25MHz SCLK */ +#define DWC_UART_BAUDRATE 115200 + +#define BRCM_CRASH_CONSOLE_BASE UART1_BASE_ADDR +#define BRCM_CRASH_CONSOLE_REFCLK DWC_UART_REFCLK +#define BRCM_CRASH_CONSOLE_BAUDRATE DWC_UART_BAUDRATE + +#ifdef BOARD_CONSOLE_UART +#define PLAT_BRCM_BOOT_UART_BASE BOARD_CONSOLE_UART +#else +#define PLAT_BRCM_BOOT_UART_BASE UART1_BASE_ADDR +#endif +#define CONSOLE_UART_ID ((PLAT_BRCM_BOOT_UART_BASE >> 16) & 0x3) + +#define PLAT_BRCM_BOOT_UART_CLK_IN_HZ DWC_UART_REFCLK +#define BRCM_CONSOLE_BAUDRATE DWC_UART_BAUDRATE + +#define PLAT_BRCM_BL31_RUN_UART_BASE PLAT_BRCM_BOOT_UART_BASE +#define PLAT_BRCM_BL31_RUN_UART_CLK_IN_HZ PLAT_BRCM_BOOT_UART_CLK_IN_HZ + +/******************************************************************************* + * IOMUX related constants + ******************************************************************************/ +#define HSLS_IOPAD_BASE HSLS_MODE_SEL_CONTROL +#define MODE_SEL_CONTROL_FSEL_MASK 0x7 +#define MODE_SEL_CONTROL_FSEL_MODE0 0x0 +#define MODE_SEL_CONTROL_FSEL_MODE1 0x1 +#define MODE_SEL_CONTROL_FSEL_MODE2 0x2 +#define MODE_SEL_CONTROL_FSEL_MODE3 0x3 +#define MODE_SEL_CONTROL_FSEL_DEBUG 0x4 +#define IPROC_IOPAD_MODE_BASE (HSLS_MODE_SEL_CONTROL + 0x29c) +#define UART0_SIN_MODE_SEL_CONTROL (HSLS_MODE_SEL_CONTROL + 0x4a8) +#define UART0_SOUT_MODE_SEL_CONTROL (HSLS_MODE_SEL_CONTROL + 0x4ac) +#define UART1_SIN_MODE_SEL_CONTROL (HSLS_MODE_SEL_CONTROL + 0x3b8) +#define UART1_SOUT_MODE_SEL_CONTROL (HSLS_MODE_SEL_CONTROL + 0x3bc) +#define UARTx_SIN_MODE_SEL_CONTROL_FSEL 0 +#define UARTx_SOUT_MODE_SEL_CONTROL_FSEL 0 + +/******************************************************************************* + * PKA constants + ******************************************************************************/ +#define ICFG_PKA_MEM_PWR_CTRL (HSLS_ICFG_REGS_BASE + 0xac0) +#define ICFG_PKA_MEM_PWR_CTRL__POWERONIN BIT(0) +#define ICFG_PKA_MEM_PWR_CTRL__POWEROKIN BIT(1) +#define ICFG_PKA_MEM_PWR_CTRL__ARRPOWERONIN BIT(2) +#define ICFG_PKA_MEM_PWR_CTRL__ARRPOWEROKIN BIT(3) +#define ICFG_PKA_MEM_PWR_CTRL__POWERONOUT BIT(4) +#define ICFG_PKA_MEM_PWR_CTRL__POWEROKOUT BIT(5) +#define ICFG_PKA_MEM_PWR_CTRL__ARRPOWERONOUT BIT(6) +#define ICFG_PKA_MEM_PWR_CTRL__ARRPOWEROKOUT BIT(7) +#define ICFG_PKA_MEM_PWR_CTRL__ISO BIT(8) + +/******************************************************************************* + * Trusted Watchdog constants + ******************************************************************************/ +#define ARM_SP805_TWDG_BASE 0x68b30000 +#define ARM_SP805_TWDG_CLK_HZ ((25 * 1000 * 1000) / 2) +/* + * The TBBR document specifies a watchdog timeout of 256 seconds. SP805 + * asserts reset after two consecutive countdowns (2 x 128 = 256 sec) + */ +#define ARM_TWDG_TIMEOUT_SEC 128 +#define ARM_TWDG_LOAD_VAL (ARM_SP805_TWDG_CLK_HZ * \ + ARM_TWDG_TIMEOUT_SEC) + +/******************************************************************************* + * SOTP related constants + ******************************************************************************/ +#define SOTP_REGS_OTP_BASE 0x68b50000 +#define SOTP_CHIP_CTRL (SOTP_REGS_OTP_BASE + 0x4c) +#define SOTP_CLEAR_SYSCTRL_ALL_MASTER_NS 0 + +/******************************************************************************* + * DMAC/PL330 related constants + ******************************************************************************/ +#define DMAC_M0_IDM_IO_CONTROL_DIRECT (HSLS_IDM_REGS_BASE + 0x408) +#define BOOT_MANAGER_NS BIT(25) +#define DMAC_M0_IDM_RESET_CONTROL (HSLS_IDM_REGS_BASE + 0x800) +#define ICFG_DMAC_CONFIG_0 (HSLS_ICFG_REGS_BASE + 0x190) +#define ICFG_DMAC_CONFIG_1 (HSLS_ICFG_REGS_BASE + 0x194) +#define ICFG_DMAC_CONFIG_2 (HSLS_ICFG_REGS_BASE + 0x198) +#define BOOT_PERIPHERAL_NS 0xffffffff +#define ICFG_DMAC_CONFIG_3 (HSLS_ICFG_REGS_BASE + 0x19c) +#define BOOT_IRQ_NS 0x0000ffff +#define ICFG_DMAC_SID_ARADDR_CONTROL (HSLS_ICFG_REGS_BASE + 0xaf0) +#define ICFG_DMAC_SID_AWADDR_CONTROL (HSLS_ICFG_REGS_BASE + 0xaf4) +#define ICFG_DMAC_MEM_PWR_CTRL__POWERONIN BIT(0) +#define ICFG_DMAC_MEM_PWR_CTRL__POWEROKIN BIT(1) +#define ICFG_DMAC_MEM_PWR_CTRL__ARRPOWERONIN BIT(2) +#define ICFG_DMAC_MEM_PWR_CTRL__ARRPOWEROKIN BIT(3) +#define ICFG_DMAC_MEM_PWR_CTRL__POWERONOUT BIT(4) +#define ICFG_DMAC_MEM_PWR_CTRL__POWEROKOUT BIT(5) +#define ICFG_DMAC_MEM_PWR_CTRL__ARRPOWERONOUT BIT(6) +#define ICFG_DMAC_MEM_PWR_CTRL__ARRPOWEROKOUT BIT(7) +#define ICFG_DMAC_MEM_PWR_CTRL__ISO BIT(8) +#define ICFG_DMAC_MEM_PWR_CTRL (HSLS_ICFG_REGS_BASE + 0xadc) + +/******************************************************************************* + * PNOR related constants + ******************************************************************************/ +#define PNOR_ICFG_BASE (HSLS_ICFG_REGS_BASE + 0x780) +#define PNOR_ICFG_CS_0 PNOR_ICFG_BASE +#define PNOR_ICFG_CS_1 (PNOR_ICFG_BASE + 0x4) +#define PNOR_ICFG_CS_2 (PNOR_ICFG_BASE + 0x8) +#define PNOR_ICFG_CS_x_MASK0_MASK 0xff +#define PNOR_ICFG_CS_x_MASK0_SHIFT 8 +#define PNOR_ICFG_CS_x_MATCH0_MASK 0xff +#define PNOR_ICFG_CS_x_MATCH0_SHIFT 0 + +#define PNOR_IDM_BASE (HSLS_IDM_REGS_BASE + 0xb000) +#define PNOR_IDM_IO_CONTROL_DIRECT (PNOR_IDM_BASE + 0x408) +#define PNOR_IDM_IO_RESET_CONTROL (PNOR_IDM_BASE + 0x800) + +#define PNOR_REG_BASE 0x68c50000 +#define PNOR_REG_DIRECT_CMD (PNOR_REG_BASE + 0x010) +#define PNOR_REG_SET_CYCLES (PNOR_REG_BASE + 0x014) +#define PNOR_REG_SET_OPMODE (PNOR_REG_BASE + 0x018) +#define PNOR_REG_REFRESH_0 (PNOR_REG_BASE + 0x020) +#define PNOR_REG_PERIPH_ID0 (PNOR_REG_BASE + 0xfe0) +#define PNOR_REG_PERIPH_ID1 (PNOR_REG_BASE + 0xfe4) +#define PNOR_REG_PERIPH_ID2 (PNOR_REG_BASE + 0xfe8) +#define PNOR_REG_PERIPH_ID3 (PNOR_REG_BASE + 0xfec) +#define PNOR_REG_PERIPH_IDx_MASK 0xff + +/******************************************************************************* + * NAND related constants + ******************************************************************************/ +#define NAND_FLASH_REVISION 0x68c60000 +#define NAND_IDM_IDM_IO_CONTROL_DIRECT (HSLS_IDM_REGS_BASE + 0xa408) +#define NAND_IDM_IDM_RESET_CONTROL (HSLS_IDM_REGS_BASE + 0xa800) + +/******************************************************************************* + * eMMC related constants + ******************************************************************************/ +#define PLAT_SD_MAX_READ_LENGTH 0x400 + +#define SDIO0_EMMCSDXC_SYSADDR 0x68cf1000 +#define SDIO_IDM0_IO_CONTROL_DIRECT (HSLS_IDM_REGS_BASE + 0x2408) +#define SDIO_IDM1_IO_CONTROL_DIRECT (HSLS_IDM_REGS_BASE + 0x3408) +#define SDIO_IDM0_IDM_RESET_CONTROL (HSLS_IDM_REGS_BASE + 0x2800) +#define ICFG_SDIO0_BASE (HSLS_ICFG_REGS_BASE + 0x6e4) +#define ICFG_SDIO1_BASE (HSLS_ICFG_REGS_BASE + 0x734) +#define ICFG_SDIO0_CAP0 (ICFG_SDIO0_BASE + 0x10) +#define ICFG_SDIO0_CAP1 (ICFG_SDIO0_BASE + 0x14) +#define ICFG_SDIO0_SID (HSLS_ICFG_REGS_BASE + 0xb00) +#define ICFG_SDIO1_SID (HSLS_ICFG_REGS_BASE + 0xb08) + +/******************************************************************************* + * Bootstrap related constants + ******************************************************************************/ +#define ROM_S0_IDM_IO_STATUS (HSLS_IDM_REGS_BASE + 0x9500) + +/******************************************************************************* + * ROM related constants + ******************************************************************************/ +#define ROM_BASE_ADDR 0x6ce00000 +#define ROM_VERSION_STRING_ADDR (ROM_BASE_ADDR + 0x28000) +#define ROM_BUILD_MESSAGE_ADDR (ROM_BASE_ADDR + 0x28018) + +/******************************************************************************* + * Boot source peripheral related constants + ******************************************************************************/ +#define QSPI_CTRL_BASE_ADDR 0x68c70000 +#define QSPI_BASE_ADDR 0x70000000 +#define QSPI_SIZE 0x08000000 +#define NOR_BASE_ADDR 0x74000000 +#define NOR_SIZE 0x04000000 +#define NAND_BASE_ADDR 0x78000000 +#define NAND_SIZE 0x08000000 + +#define QSPI_IDM_RESET_CONTROL (HSLS_IDM_REGS_BASE + 0xc800) + +#define APBR_IDM_RESET_CONTROL (HSLS_IDM_REGS_BASE + 0xe800) +#define APBS_IDM_IDM_RESET_CONTROL (HSLS_IDM_REGS_BASE + 0xf800) + +#define APBX_IDM_IDM_IO_CONTROL_DIRECT (HSLS_IDM_REGS_BASE + 0x10408) +#define APBX_IDM_IDM_IO_CONTROL_DIRECT_CLK_ENABLE 0 +#define APBX_IDM_IDM_IO_CONTROL_DIRECT_WDOG_SCLK_SEL 2 +#define APBX_IDM_IDM_IO_CONTROL_DIRECT_TIM0_SCLK_SEL 4 +#define APBX_IDM_IDM_IO_CONTROL_DIRECT_TIM1_SCLK_SEL 6 +#define APBX_IDM_IDM_IO_CONTROL_DIRECT_TIM2_SCLK_SEL 8 +#define APBX_IDM_IDM_IO_CONTROL_DIRECT_TIM3_SCLK_SEL 10 +#define APBX_IDM_IDM_IO_CONTROL_DIRECT_TIM4_SCLK_SEL 12 +#define APBX_IDM_IDM_IO_CONTROL_DIRECT_TIM5_SCLK_SEL 13 +#define APBX_IDM_IDM_IO_CONTROL_DIRECT_TIM6_SCLK_SEL 14 +#define APBX_IDM_IDM_IO_CONTROL_DIRECT_TIM7_SCLK_SEL 15 + +#define APBY_IDM_IDM_IO_CONTROL_DIRECT (HSLS_IDM_REGS_BASE + 0x11408) +#define APBY_IDM_IDM_IO_CONTROL_DIRECT_CLK_ENABLE 0 +#define APBY_IDM_IDM_IO_CONTROL_DIRECT_UART0_SCLK_SEL 2 +#define APBY_IDM_IDM_IO_CONTROL_DIRECT_UART1_SCLK_SEL 4 +#define APBY_IDM_IDM_IO_CONTROL_DIRECT_UART2_SCLK_SEL 6 +#define APBY_IDM_IDM_IO_CONTROL_DIRECT_UART3_SCLK_SEL 8 + +#define APBZ_IDM_IDM_IO_CONTROL_DIRECT (HSLS_IDM_REGS_BASE + 0x12408) +#define APBZ_IDM_IDM_IO_CONTROL_DIRECT_CLK_ENABLE 0 +#define APBZ_IDM_IDM_IO_CONTROL_DIRECT_WDOG_SCLK_SEL 2 + +/******************************************************************************* + * Stingray memory map related constants + ******************************************************************************/ + +/* The last 4KB of Trusted SRAM are used as shared memory */ +#define BRCM_SHARED_RAM_SIZE 0x0 +#define BRCM_SHARED_RAM_BASE (PLAT_BRCM_TRUSTED_SRAM_BASE + \ + PLAT_BRCM_TRUSTED_SRAM_SIZE - \ + BRCM_SHARED_RAM_SIZE) + +/* Reserve 4 KB to store error logs in BL2 */ +#define BCM_ELOG_BL2_SIZE 0x00001000 +#define BCM_ELOG_BL2_BASE BL1_RW_LIMIT + +/* The remaining Trusted SRAM is used to load the BL images */ +#define BRCM_BL_RAM_BASE (PLAT_BRCM_TRUSTED_SRAM_BASE) +#define BRCM_BL_RAM_SIZE (PLAT_BRCM_TRUSTED_SRAM_SIZE - \ + BRCM_SHARED_RAM_SIZE) + +/* DDR Address where TMON temperature values are written */ +#define TMON_SHARED_DDR_ADDRESS 0x8f100000 + +/* Reserve 4 kB to pass data to BL33 */ +#define BL33_SHARED_DDR_BASE 0x8f102000 +#define BL33_SHARED_DDR_SIZE 0x1000 + +/* Default AP error logging base addr */ +#ifndef ELOG_AP_UART_LOG_BASE +#define ELOG_AP_UART_LOG_BASE 0x8f110000 +#endif + +/* Reserve 16 to store error logs in BL31 */ +#define BCM_ELOG_BL31_BASE ELOG_AP_UART_LOG_BASE +#define BCM_ELOG_BL31_SIZE 0x4000 + +/******************************************************************************* + * Non-secure DDR Map + ******************************************************************************/ +#define BRCM_DRAM1_BASE ULL(0x80000000) +#define BRCM_DRAM1_SIZE ULL(0x10000000) +#define BRCM_DRAM2_BASE ULL(0x880000000) +#define BRCM_DRAM2_SIZE ULL(0x780000000) +#define BRCM_DRAM3_BASE ULL(0x8800000000) +#define BRCM_DRAM3_SIZE ULL(0x7800000000) +#define BRCM_SHARED_DRAM_BASE BL33_SHARED_DDR_BASE +#define BRCM_SHARED_DRAM_SIZE BL33_SHARED_DDR_SIZE +#define BRCM_EXT_SRAM_BASE ULL(0x74000000) +#define BRCM_EXT_SRAM_SIZE ULL(0x4000000) + +/* Priority levels for platforms */ +#define PLAT_RAS_PRI 0x10 +#define PLAT_SDEI_CRITICAL_PRI 0x60 +#define PLAT_SDEI_NORMAL_PRI 0x70 + +/* Define a list of Group 1 Secure and Group 0 interrupts as per GICv3 */ +#define BRCM_IRQ_SEC_SGI_0 14 +#define BRCM_IRQ_SEC_SGI_1 15 + +/* RTC periodic interrupt */ +#define BRCM_IRQ_SEC_SPI_0 49 + +/* + * Macros for local power states in SR platforms encoded by State-ID field + * within the power-state parameter. + */ + +/* Local power state for power domains in Run state. */ +#define PLAT_LOCAL_STATE_RUN 0 + +/* Local power state for retention. Valid only for CPU power domains */ +#define PLAT_LOCAL_STATE_RET 1 + +/* + * Local power state for OFF/power-down. Valid for CPU and cluster power + * domains. + */ +#define PLAT_LOCAL_STATE_OFF 2 + +/* + * 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 PLAT_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 PLAT_LOCAL_STATE_OFF + +/* ChiMP-related constants */ + +#define NITRO_TZPC_TZPCDECPROT0clr 0x60c01808 +#define NITRO_TZPC_TZPCDECPROT0clr__DECPROT0_chimp_m_clr_R 1 + +#define NIC400_NITRO_CHIMP_S_IDM_IO_CONTROL_DIRECT 0x60e00408 + +#define CHIMP_INDIRECT_ADDR_MASK 0x3fffff +#define CHIMP_INDIRECT_BASE 0x60800000 + +#define CHIMP_REG_ECO_RESERVED 0x3042400 + +#define CHIMP_FLASH_ACCESS_DONE_BIT 2 + +/* indicate FRU table programming is done successfully */ +#define CHIMP_FRU_PROG_DONE_BIT 9 + +#define CHIMP_REG_CTRL_BPE_MODE_REG 0x0 +#define CHIMP_REG_CTRL_BPE_STAT_REG 0x4 +#define CHIMP_REG_CTRL_FSTBOOT_PTR_REG 0x8 +#define CHIMP_REG_CHIMP_REG_CTRL_BPE_MODE_REG__cm3_rst_L 1 +#define CHIMP_REG_CHIMP_REG_CTRL_BPE_MODE_REG__cm3_rst_R 1 +#define CHIMP_REG_CTRL_BASE 0x3040000 +#define CHIMP_FAST_BOOT_MODE_BIT 2 +#define CHIMP_REG_CHIMP_APE_SCPAD 0x3300000 +#define CHIMP_REG_CHIMP_SCPAD 0x3100000 + +/* Chimp health status offset in scratch pad ram */ +#define CHIMP_HEALTH_STATUS_OFFSET 0x8 +/* + * If not in NIC mode then FASTBOOT can be enabled. + * "Not in NIC mode" means that FORCE_FASTBOOT is set + * and a valid (1 or 2) fastboot type is specified. + * + * Three types of fastboot are supported: + * 0 = No fastboot. Boots Nitro/ChiMP and lets ROM loader + * initialize ChiMP from NVRAM (QSPI). + * + * 1 = Jump in place (need a flat image) + * This is intended to speedup Nitro FW boot on Palladium, + * can be used with a real chip as well. + * 2 = Jump normally with decompression + * Modus operandi for a real chip. Works also on Palladium + * Note: image decompressing takes time on Palladium. + * 3 = No fastboot support. No ChiMP bringup + * (use only for AP debug or for ChiMP's deferred setup). + */ +#define CHIMP_FASTBOOT_JUMP_DECOMPRESS 2 +#define CHIMP_FASTBOOT_JUMP_IN_PLACE 1 +#define CHIMP_FASTBOOT_NITRO_RESET 0 +/* + * Definitions for a non-Nitro access + * to QSPI PAD after the handshake + */ +#define QSPI_HOLD_N_MODE_SEL_CONTROL (HSLS_MODE_SEL_CONTROL + 0x3e8) +#define QSPI_WP_N_MODE_SEL_CONTROL (HSLS_MODE_SEL_CONTROL + 0x3ec) +#define QSPI_SCK_MODE_SEL_CONTROL (HSLS_MODE_SEL_CONTROL + 0x3f0) +#define QSPI_CS_N_MODE_SEL_CONTROL (HSLS_MODE_SEL_CONTROL + 0x3f4) +#define QSPI_MOSI_MODE_SEL_CONTROL (HSLS_MODE_SEL_CONTROL + 0x3f8) +#define QSPI_MISO_MODE_SEL_CONTROL (HSLS_MODE_SEL_CONTROL + 0x3fc) + +/******************************************************************************* + * Stream IDs for different blocks of SR + * block_id for different blocks is as follows: + * PCIE : 0x0 + * PAXC : 0x1 + * FS4 : 0x2 + * Rest of the masters(includes MHB via RNI): 0x3 + ******************************************************************************/ +#define SR_SID_VAL(block_id, subblock_id, device_num) ((block_id << 13) | \ + (subblock_id << 11) | \ + (device_num)) + +#define CRMU_STREAM_ID SR_SID_VAL(0x3, 0x0, 0x7) +#define CRMU_SID_SHIFT 5 + +#define DMAC_STREAM_ID SR_SID_VAL(0x3, 0x0, 0x0) +#define DMAC_SID_SHIFT 5 + +/* DDR SHMOO Values defines */ +#define IDRAM_SHMOO_VALUES_ADDR CRMU_IDRAM_BASE_ADDR +#define DDR_SHMOO_VALUES_ADDR 0x8f103000 +#define SHMOO_SIZE_PER_CHANNEL 0x1000 + +#endif /* SR_DEF_H */ diff --git a/plat/brcm/board/stingray/platform.mk b/plat/brcm/board/stingray/platform.mk new file mode 100644 index 000000000..1b9cc3b9c --- /dev/null +++ b/plat/brcm/board/stingray/platform.mk @@ -0,0 +1,48 @@ +# +# Copyright (c) 2019-2020, Broadcom +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# Enable workaround for ERRATA_A72_859971 +ERRATA_A72_859971 := 1 + +# Cache Coherency Interconnect Driver needed +DRIVER_CC_ENABLE := 1 +$(eval $(call add_define,DRIVER_CC_ENABLE)) + +USE_CRMU_SRAM := yes + +# Use single cluster +ifeq (${USE_SINGLE_CLUSTER},yes) +$(info Using Single Cluster) +$(eval $(call add_define,USE_SINGLE_CLUSTER)) +endif + +ifeq (${BOARD_CFG},) +BOARD_CFG := bcm958742k +endif + +# For testing purposes, use memsys stubs. Remove once memsys is fully tested. +USE_MEMSYS_STUBS := yes + +# Default, use BL1_RW area +ifneq (${BL2_USE_BL1_RW},no) +$(eval $(call add_define,USE_BL1_RW)) +endif + +# Default soft reset is L3 +$(eval $(call add_define,CONFIG_SOFT_RESET_L3)) + +include plat/brcm/board/common/board_common.mk + +SOC_DIR := brcm/board/stingray + +PLAT_INCLUDES += -Iplat/${SOC_DIR}/include/ \ + -Iinclude/plat/brcm/common/ \ + -Iplat/brcm/common/ + +PLAT_BL_COMMON_SOURCES += lib/cpus/aarch64/cortex_a72.S \ + plat/${SOC_DIR}/aarch64/plat_helpers.S \ + drivers/ti/uart/aarch64/16550_console.S \ + drivers/arm/tzc/tzc400.c diff --git a/plat/brcm/common/brcm_bl2_mem_params_desc.c b/plat/brcm/common/brcm_bl2_mem_params_desc.c new file mode 100644 index 000000000..f711354bc --- /dev/null +++ b/plat/brcm/common/brcm_bl2_mem_params_desc.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2019-2020, 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[] = { +#ifdef SCP_BL2_BASE + /* Fill SCP_BL2 related information if it exists */ + { + .image_id = SCP_BL2_IMAGE_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, 0), + .image_info.image_base = SCP_BL2_BASE, + .image_info.image_max_size = PLAT_MAX_SCP_BL2_SIZE, + + .next_handoff_image_id = INVALID_IMAGE_ID, + }, +#endif /* SCP_BL2_BASE */ + + /* Fill BL31 related information */ + { + .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), +#if DEBUG + .ep_info.args.arg3 = BRCM_BL31_PLAT_PARAM_VAL, +#endif + + 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, + +#ifdef BL32_BASE + .next_handoff_image_id = BL32_IMAGE_ID, +#else + .next_handoff_image_id = BL33_IMAGE_ID, +#endif + }, + +#ifdef BL32_BASE + /* 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_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_LIMIT - BL32_BASE, + + .next_handoff_image_id = BL33_IMAGE_ID, + }, +#endif /* BL32_BASE */ + + /* 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), +#ifdef PRELOADED_BL33_BASE + .ep_info.pc = PRELOADED_BL33_BASE, + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, + VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING), +#else + .ep_info.pc = PLAT_BRCM_NS_IMAGE_OFFSET, + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, + VERSION_2, image_info_t, 0), + .image_info.image_base = PLAT_BRCM_NS_IMAGE_OFFSET, + .image_info.image_max_size = BRCM_DRAM1_SIZE, +#endif /* PRELOADED_BL33_BASE */ + + .next_handoff_image_id = INVALID_IMAGE_ID, + } +}; + +REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs) diff --git a/plat/brcm/common/brcm_bl2_setup.c b/plat/brcm/common/brcm_bl2_setup.c new file mode 100644 index 000000000..9a7153b77 --- /dev/null +++ b/plat/brcm/common/brcm_bl2_setup.c @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* Data structure which holds the extents of the trusted SRAM for BL2 */ +static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE); + +/* Weak definitions may be overridden in specific BRCM platform */ +#pragma weak plat_bcm_bl2_platform_setup +#pragma weak plat_bcm_bl2_plat_arch_setup +#pragma weak plat_bcm_security_setup +#pragma weak plat_bcm_bl2_plat_handle_scp_bl2 +#pragma weak plat_bcm_bl2_early_platform_setup + +void plat_bcm_bl2_early_platform_setup(void) +{ +} + +void plat_bcm_bl2_platform_setup(void) +{ +} + +void plat_bcm_bl2_plat_arch_setup(void) +{ +} + +void plat_bcm_security_setup(void) +{ +} + +void bcm_bl2_early_platform_setup(uintptr_t tb_fw_config, + meminfo_t *mem_layout) +{ + /* Initialize the console to provide early debug support */ + bcm_console_boot_init(); + + /* Setup the BL2 memory layout */ + bl2_tzram_layout = *mem_layout; + + /* Initialise the IO layer and register platform IO devices */ + plat_brcm_io_setup(); + + /* Log HW reset event */ + INFO("RESET: 0x%x\n", + mmio_read_32(CRMU_RESET_EVENT_LOG)); +} + +void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, + u_register_t arg2, u_register_t arg3) +{ + /* SoC specific setup */ + plat_bcm_bl2_early_platform_setup(); + + /* Initialize delay timer driver using SP804 dual timer 0 */ + sp804_timer_init(SP804_TIMER0_BASE, + SP804_TIMER0_CLKMULT, SP804_TIMER0_CLKDIV); + + /* BRCM platforms generic setup */ + bcm_bl2_early_platform_setup((uintptr_t)arg0, (meminfo_t *)arg1); +} + +/* + * Perform Broadcom platform setup. + */ +void bcm_bl2_platform_setup(void) +{ + /* Initialize the secure environment */ + plat_bcm_security_setup(); +} + +void bl2_platform_setup(void) +{ + bcm_bl2_platform_setup(); + plat_bcm_bl2_platform_setup(); +} + +/******************************************************************************* + * Perform the very early platform specific architectural setup here. At the + * moment this is only initializes the mmu in a quick and dirty way. + ******************************************************************************/ +void bcm_bl2_plat_arch_setup(void) +{ +#ifndef MMU_DISABLED + if (!(read_sctlr_el1() & SCTLR_M_BIT)) { + const mmap_region_t bl_regions[] = { + MAP_REGION_FLAT(bl2_tzram_layout.total_base, + bl2_tzram_layout.total_size, + MT_MEMORY | MT_RW | MT_SECURE), + MAP_REGION_FLAT(BL_CODE_BASE, + BL_CODE_END - BL_CODE_BASE, + MT_CODE | MT_SECURE), + MAP_REGION_FLAT(BL_RO_DATA_BASE, + BL_RO_DATA_END - BL_RO_DATA_BASE, + MT_RO_DATA | MT_SECURE), +#if USE_COHERENT_MEM + MAP_REGION_FLAT(BL_COHERENT_RAM_BASE, + BL_COHERENT_RAM_END - + BL_COHERENT_RAM_BASE, + MT_DEVICE | MT_RW | MT_SECURE), +#endif + {0} + }; + + setup_page_tables(bl_regions, plat_brcm_get_mmap()); + enable_mmu_el1(0); + } +#endif +} + +void bl2_plat_arch_setup(void) +{ +#ifdef ENA_MMU_BEFORE_DDR_INIT + /* + * Once MMU is enabled before DDR, MEMORY TESTS + * get affected as read/write transaction might occures from + * caches. So For running memory test, one should not set this + * flag. + */ + bcm_bl2_plat_arch_setup(); + plat_bcm_bl2_plat_arch_setup(); +#else + plat_bcm_bl2_plat_arch_setup(); + bcm_bl2_plat_arch_setup(); +#endif +} + +int bcm_bl2_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); + + assert(bl_mem_params); + + switch (image_id) { + case BL32_IMAGE_ID: + bl_mem_params->ep_info.spsr = brcm_get_spsr_for_bl32_entry(); + break; + + case BL33_IMAGE_ID: + /* BL33 expects to receive the primary CPU MPID (through r0) */ + bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr(); + bl_mem_params->ep_info.spsr = brcm_get_spsr_for_bl33_entry(); + break; + +#ifdef SCP_BL2_BASE + case SCP_BL2_IMAGE_ID: + /* The subsequent handling of SCP_BL2 is platform specific */ + err = bcm_bl2_handle_scp_bl2(&bl_mem_params->image_info); + if (err) + WARN("Failure in platform-specific handling of SCP_BL2 image.\n"); + break; +#endif + default: + /* Do nothing in default case */ + break; + } + + return err; +} + +/******************************************************************************* + * This function can be used by the platforms to update/use image + * information for given `image_id`. + ******************************************************************************/ +int bcm_bl2_plat_handle_post_image_load(unsigned int image_id) +{ + return bcm_bl2_handle_post_image_load(image_id); +} + +int bl2_plat_handle_post_image_load(unsigned int image_id) +{ + return bcm_bl2_plat_handle_post_image_load(image_id); +} + +#ifdef SCP_BL2_BASE +int plat_bcm_bl2_plat_handle_scp_bl2(image_info_t *scp_bl2_image_info) +{ + return 0; +} + +int bcm_bl2_handle_scp_bl2(image_info_t *scp_bl2_image_info) +{ + return plat_bcm_bl2_plat_handle_scp_bl2(scp_bl2_image_info); +} +#endif diff --git a/plat/brcm/common/brcm_common.c b/plat/brcm/common/brcm_common.c new file mode 100644 index 000000000..f23719df4 --- /dev/null +++ b/plat/brcm/common/brcm_common.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include + +#include +#include + +/* Weak definitions may be overridden in specific BRCM platform */ +#pragma weak plat_get_ns_image_entrypoint +#pragma weak plat_brcm_get_mmap + +uintptr_t plat_get_ns_image_entrypoint(void) +{ +#ifdef PRELOADED_BL33_BASE + return PRELOADED_BL33_BASE; +#else + return PLAT_BRCM_NS_IMAGE_OFFSET; +#endif +} + +uint32_t brcm_get_spsr_for_bl32_entry(void) +{ + /* + * The Secure Payload Dispatcher service is responsible for + * setting the SPSR prior to entry into the BL32 image. + */ + return 0; +} + +uint32_t brcm_get_spsr_for_bl33_entry(void) +{ + unsigned int mode; + uint32_t spsr; + + /* Figure out what mode we enter the non-secure world in */ + mode = el_implemented(2) ? MODE_EL2 : MODE_EL1; + + /* + * TODO: Consider the possibility of specifying the SPSR in + * the FIP ToC and allowing the platform to have a say as + * well. + */ + spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); + return spsr; +} + +const mmap_region_t *plat_brcm_get_mmap(void) +{ + return plat_brcm_mmap; +} diff --git a/plat/brcm/common/brcm_image_load.c b/plat/brcm/common/brcm_image_load.c new file mode 100644 index 000000000..ba02bdad4 --- /dev/null +++ b/plat/brcm/common/brcm_image_load.c @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#pragma weak plat_flush_next_bl_params +#pragma weak plat_get_bl_image_load_info +#pragma weak plat_get_next_bl_params + +/******************************************************************************* + * This function flushes the data structures so that they are visible + * in memory for the next BL image. + ******************************************************************************/ +void plat_flush_next_bl_params(void) +{ + flush_bl_params_desc(); +} + +/******************************************************************************* + * This function returns the list of loadable images. + ******************************************************************************/ +struct bl_load_info *plat_get_bl_image_load_info(void) +{ + return get_bl_load_info_from_mem_params_desc(); +} + +/******************************************************************************* + * This function returns the list of executable images. + ******************************************************************************/ +struct bl_params *plat_get_next_bl_params(void) +{ + bl_params_t *next_bl_params = get_next_bl_params_from_mem_params_desc(); + + populate_next_bl_params_config(next_bl_params); + return next_bl_params; +} diff --git a/plat/brcm/common/brcm_io_storage.c b/plat/brcm/common/brcm_io_storage.c new file mode 100644 index 000000000..66ec29247 --- /dev/null +++ b/plat/brcm/common/brcm_io_storage.c @@ -0,0 +1,408 @@ +/* + * Copyright (c) 2019-2020, 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 + +/* IO devices */ +static const io_dev_connector_t *fip_dev_con; +static uintptr_t fip_dev_handle; +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 = PLAT_BRCM_FIP_BASE, + .length = PLAT_BRCM_FIP_MAX_SIZE +}; + +static const io_block_spec_t qspi_fip_block_spec = { + .offset = PLAT_BRCM_FIP_QSPI_BASE, + .length = PLAT_BRCM_FIP_MAX_SIZE +}; + +static const io_block_spec_t nand_fip_block_spec = { + .offset = PLAT_BRCM_FIP_NAND_BASE, + .length = PLAT_BRCM_FIP_MAX_SIZE +}; + +static const io_uuid_spec_t bl2_uuid_spec = { + .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2, +}; + +static const io_uuid_spec_t scp_bl2_uuid_spec = { + .uuid = UUID_SCP_FIRMWARE_SCP_BL2, +}; + +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, +}; + +static const io_uuid_spec_t tb_fw_config_uuid_spec = { + .uuid = UUID_TB_FW_CONFIG, +}; + +static const io_uuid_spec_t hw_config_uuid_spec = { + .uuid = UUID_HW_CONFIG, +}; + +static const io_uuid_spec_t soc_fw_config_uuid_spec = { + .uuid = UUID_SOC_FW_CONFIG, +}; + +static const io_uuid_spec_t tos_fw_config_uuid_spec = { + .uuid = UUID_TOS_FW_CONFIG, +}; + +static const io_uuid_spec_t nt_fw_config_uuid_spec = { + .uuid = UUID_NT_FW_CONFIG, +}; + +#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 scp_fw_key_cert_uuid_spec = { + .uuid = UUID_SCP_FW_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 nt_fw_key_cert_uuid_spec = { + .uuid = UUID_NON_TRUSTED_FW_KEY_CERT, +}; + +static const io_uuid_spec_t scp_fw_cert_uuid_spec = { + .uuid = UUID_SCP_FW_CONTENT_CERT, +}; + +static const io_uuid_spec_t soc_fw_cert_uuid_spec = { + .uuid = UUID_SOC_FW_CONTENT_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_cert_uuid_spec = { + .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT, +}; +#endif /* TRUSTED_BOARD_BOOT */ + +static int open_fip(const uintptr_t spec); +static int open_memmap(const uintptr_t spec); +static int open_qspi(const uintptr_t spec); +static int open_nand(const uintptr_t spec); + +struct plat_io_policy { + uintptr_t *dev_handle; + uintptr_t image_spec; + int (*check)(const uintptr_t spec); +}; + +/* By default, BRCM platforms load images from the FIP */ +static const struct plat_io_policy policies[] = { + [FIP_IMAGE_ID] = { + &memmap_dev_handle, + (uintptr_t)&fip_block_spec, + open_memmap + }, + [BL2_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&bl2_uuid_spec, + open_fip + }, + [SCP_BL2_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&scp_bl2_uuid_spec, + open_fip + }, + [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 + }, + [TB_FW_CONFIG_ID] = { + &fip_dev_handle, + (uintptr_t)&tb_fw_config_uuid_spec, + open_fip + }, + [HW_CONFIG_ID] = { + &fip_dev_handle, + (uintptr_t)&hw_config_uuid_spec, + open_fip + }, + [SOC_FW_CONFIG_ID] = { + &fip_dev_handle, + (uintptr_t)&soc_fw_config_uuid_spec, + open_fip + }, + [TOS_FW_CONFIG_ID] = { + &fip_dev_handle, + (uintptr_t)&tos_fw_config_uuid_spec, + open_fip + }, + [NT_FW_CONFIG_ID] = { + &fip_dev_handle, + (uintptr_t)&nt_fw_config_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 + }, + [SCP_FW_KEY_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&scp_fw_key_cert_uuid_spec, + open_fip + }, + [SOC_FW_KEY_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&soc_fw_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 + }, + [SCP_FW_CONTENT_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&scp_fw_cert_uuid_spec, + open_fip + }, + [SOC_FW_CONTENT_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&soc_fw_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 */ +}; + +/* By default, BRCM platforms load images from the FIP */ +static const struct plat_io_policy boot_source_policies[] = { + [BOOT_SOURCE_QSPI] = { + &memmap_dev_handle, + (uintptr_t)&qspi_fip_block_spec, + open_qspi + }, + [BOOT_SOURCE_NAND] = { + &memmap_dev_handle, + (uintptr_t)&nand_fip_block_spec, + open_nand + }, +}; + +/* Weak definitions may be overridden in specific brcm platform */ +#pragma weak plat_brcm_io_setup +#pragma weak plat_brcm_process_flags + +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; +} + + +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; +} + +static int open_qspi(const uintptr_t spec) +{ + return open_memmap(spec); +} + +static int open_nand(const uintptr_t spec) +{ + return open_memmap(spec); +} + + +void brcm_io_setup(void) +{ + int io_result; + uint32_t boot_source; + + io_result = register_io_dev_fip(&fip_dev_con); + assert(io_result == 0); + + io_result = register_io_dev_memmap(&memmap_dev_con); + assert(io_result == 0); + + /* Open connections to devices and cache the handles */ + io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, + &fip_dev_handle); + assert(io_result == 0); + + boot_source = boot_source_get(); + switch (boot_source) { + case BOOT_SOURCE_QSPI: + case BOOT_SOURCE_NAND: + default: + io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, + &memmap_dev_handle); + break; + } + assert(io_result == 0); + + /* Ignore improbable errors in release builds */ + (void)io_result; +} + +void plat_brcm_io_setup(void) +{ + brcm_io_setup(); +} + +void plat_brcm_process_flags(uint16_t plat_toc_flags __unused) +{ + WARN("%s not implemented\n", __func__); +} + +/* + * 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 result; + const struct plat_io_policy *policy; + uint32_t boot_source; + uint16_t lcl_plat_toc_flg; + + assert(image_id < ARRAY_SIZE(policies)); + + boot_source = boot_source_get(); + if (image_id == FIP_IMAGE_ID) + policy = &boot_source_policies[boot_source]; + else + policy = &policies[image_id]; + + result = policy->check(policy->image_spec); + if (result == 0) { + *image_spec = policy->image_spec; + *dev_handle = *(policy->dev_handle); + + if (image_id == TRUSTED_BOOT_FW_CERT_ID) { + /* + * Process the header flags to perform + * such custom actions as speeding up PLL. + * CERT seems to be the first image accessed + * by BL1 so this is where we process the flags. + */ + fip_dev_get_plat_toc_flag((io_dev_info_t *)fip_dev_handle, + &lcl_plat_toc_flg); + plat_brcm_process_flags(lcl_plat_toc_flg); + } + } + + return result; +} -- cgit v1.2.3 From 9a40c0fba66ccc706ed90ce9b40de6b0045bd660 Mon Sep 17 00:00:00 2001 From: Sheetal Tigadoli Date: Wed, 18 Dec 2019 12:01:01 +0530 Subject: Add bl31 support common across Broadcom platforms Signed-off-by: Sheetal Tigadoli Change-Id: Ic1a392a633b447935fa3a7528326c97845f5b1bc --- include/drivers/brcm/dmu.h | 35 ++ include/plat/brcm/common/plat_brcm.h | 11 + plat/brcm/board/common/board_common.c | 32 ++ plat/brcm/board/common/board_common.mk | 28 +- plat/brcm/board/common/timer_sync.c | 71 ++++ plat/brcm/board/stingray/driver/ihost_pll_config.c | 287 +++++++++++++++ plat/brcm/board/stingray/include/ihost_pm.h | 19 + plat/brcm/board/stingray/include/platform_def.h | 6 +- plat/brcm/board/stingray/include/timer_sync.h | 12 + plat/brcm/board/stingray/platform.mk | 43 ++- plat/brcm/board/stingray/src/brcm_pm_ops.c | 393 +++++++++++++++++++++ plat/brcm/board/stingray/src/ihost_pm.c | 355 +++++++++++++++++++ plat/brcm/board/stingray/src/pm.c | 131 +++++++ plat/brcm/board/stingray/src/topology.c | 52 +++ plat/brcm/board/stingray/src/tz_sec.c | 153 ++++++++ plat/brcm/common/brcm_bl31_setup.c | 291 +++++++++++++++ plat/brcm/common/brcm_ccn.c | 36 ++ plat/brcm/common/brcm_gicv3.c | 91 +++++ plat/brcm/common/brcm_mhu.c | 131 +++++++ plat/brcm/common/brcm_mhu.h | 19 + plat/brcm/common/brcm_scpi.c | 252 +++++++++++++ plat/brcm/common/brcm_scpi.h | 107 ++++++ 22 files changed, 2549 insertions(+), 6 deletions(-) create mode 100644 include/drivers/brcm/dmu.h create mode 100644 plat/brcm/board/common/timer_sync.c create mode 100644 plat/brcm/board/stingray/driver/ihost_pll_config.c create mode 100644 plat/brcm/board/stingray/include/ihost_pm.h create mode 100644 plat/brcm/board/stingray/include/timer_sync.h create mode 100644 plat/brcm/board/stingray/src/brcm_pm_ops.c create mode 100644 plat/brcm/board/stingray/src/ihost_pm.c create mode 100644 plat/brcm/board/stingray/src/pm.c create mode 100644 plat/brcm/board/stingray/src/topology.c create mode 100644 plat/brcm/board/stingray/src/tz_sec.c create mode 100644 plat/brcm/common/brcm_bl31_setup.c create mode 100644 plat/brcm/common/brcm_ccn.c create mode 100644 plat/brcm/common/brcm_gicv3.c create mode 100644 plat/brcm/common/brcm_mhu.c create mode 100644 plat/brcm/common/brcm_mhu.h create mode 100644 plat/brcm/common/brcm_scpi.c create mode 100644 plat/brcm/common/brcm_scpi.h diff --git a/include/drivers/brcm/dmu.h b/include/drivers/brcm/dmu.h new file mode 100644 index 000000000..3a57bbdee --- /dev/null +++ b/include/drivers/brcm/dmu.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2015 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef DMU_H +#define DMU_H + +/* Clock field should be 2 bits only */ +#define CLKCONFIG_MASK 0x3 + +/* argument */ +struct DmuBlockEnable { + uint32_t sotp:1; + uint32_t pka_rng:1; + uint32_t crypto:1; + uint32_t spl:1; + uint32_t cdru_vgm:1; + uint32_t apbs_s0_idm:1; + uint32_t smau_s0_idm:1; +}; + +/* prototype */ +uint32_t bcm_dmu_block_enable(struct DmuBlockEnable dbe); +uint32_t bcm_dmu_block_disable(struct DmuBlockEnable dbe); +uint32_t bcm_set_ihost_pll_freq(uint32_t cluster_num, int ihost_pll_freq_sel); +uint32_t bcm_get_ihost_pll_freq(uint32_t cluster_num); + +#define PLL_FREQ_BYPASS 0x0 +#define PLL_FREQ_FULL 0x1 +#define PLL_FREQ_HALF 0x2 +#define PLL_FREQ_QRTR 0x3 + +#endif diff --git a/include/plat/brcm/common/plat_brcm.h b/include/plat/brcm/common/plat_brcm.h index 9147caac5..66ed2cbaf 100644 --- a/include/plat/brcm/common/plat_brcm.h +++ b/include/plat/brcm/common/plat_brcm.h @@ -24,6 +24,17 @@ uint32_t brcm_get_spsr_for_bl32_entry(void); uint32_t brcm_get_spsr_for_bl33_entry(void); const mmap_region_t *plat_brcm_get_mmap(void); int bcm_bl2_handle_scp_bl2(struct image_info *image_info); +unsigned int plat_brcm_calc_core_pos(u_register_t mpidr); +void plat_brcm_gic_driver_init(void); +void plat_brcm_gic_init(void); +void plat_brcm_gic_cpuif_enable(void); +void plat_brcm_gic_cpuif_disable(void); +void plat_brcm_gic_pcpu_init(void); +void plat_brcm_gic_redistif_on(void); +void plat_brcm_gic_redistif_off(void); +void plat_brcm_interconnect_init(void); +void plat_brcm_interconnect_enter_coherency(void); +void plat_brcm_interconnect_exit_coherency(void); void plat_brcm_io_setup(void); void plat_brcm_process_flags(uint16_t plat_toc_flags); diff --git a/plat/brcm/board/common/board_common.c b/plat/brcm/board/common/board_common.c index e7b5e475e..2f764ab25 100644 --- a/plat/brcm/board/common/board_common.c +++ b/plat/brcm/board/common/board_common.c @@ -36,6 +36,38 @@ const mmap_region_t plat_brcm_mmap[] = { }; #endif +#if IMAGE_BL31 +const mmap_region_t plat_brcm_mmap[] = { + HSLS_REGION, +#ifdef PERIPH0_REGION + PERIPH0_REGION, +#endif +#ifdef PERIPH1_REGION + PERIPH1_REGION, +#endif +#ifdef PERIPH2_REGION + PERIPH2_REGION, +#endif +#ifdef USB_REGION + USB_REGION, +#endif +#ifdef USE_DDR + BRCM_MAP_NS_DRAM1, +#ifdef BRCM_MAP_NS_SHARED_DRAM + BRCM_MAP_NS_SHARED_DRAM, +#endif +#else +#ifdef BRCM_MAP_EXT_SRAM + BRCM_MAP_EXT_SRAM, +#endif +#endif +#if defined(USE_CRMU_SRAM) && defined(CRMU_SRAM_BASE) + CRMU_SRAM_REGION, +#endif + {0} +}; +#endif + CASSERT((ARRAY_SIZE(plat_brcm_mmap) - 1) <= PLAT_BRCM_MMAP_ENTRIES, assert_plat_brcm_mmap_mismatch); CASSERT((PLAT_BRCM_MMAP_ENTRIES + BRCM_BL_REGIONS) <= MAX_MMAP_REGIONS, diff --git a/plat/brcm/board/common/board_common.mk b/plat/brcm/board/common/board_common.mk index 9ac26af32..7c9cf77d3 100644 --- a/plat/brcm/board/common/board_common.mk +++ b/plat/brcm/board/common/board_common.mk @@ -28,6 +28,13 @@ SYSCNT_FREQ := $(GENTIMER_ACTUAL_CLOCK) $(eval $(call add_define,SYSCNT_FREQ)) endif +# Process ARM_BL31_IN_DRAM flag +ifeq (${ARM_BL31_IN_DRAM},) +ARM_BL31_IN_DRAM := 0 +endif +$(eval $(call assert_boolean,ARM_BL31_IN_DRAM)) +$(eval $(call add_define,ARM_BL31_IN_DRAM)) + ifeq (${STANDALONE_BL2},yes) $(eval $(call add_define,MMU_DISABLED)) endif @@ -50,7 +57,8 @@ SEPARATE_CODE_AND_RODATA := 1 # Use generic OID definition (tbbr_oid.h) USE_TBBR_DEFS := 1 -PLAT_INCLUDES += -Iplat/brcm/board/common +PLAT_INCLUDES += -Iplat/brcm/board/common \ + -Iinclude/drivers/brcm PLAT_BL_COMMON_SOURCES += plat/brcm/common/brcm_common.c \ plat/brcm/board/common/cmn_sec.c \ @@ -72,6 +80,24 @@ BL2_SOURCES += plat/brcm/common/brcm_bl2_mem_params_desc.c \ BL2_SOURCES += plat/brcm/common/brcm_bl2_setup.c +BL31_SOURCES += plat/brcm/common/brcm_bl31_setup.c + +#M0 runtime firmware +ifdef SCP_BL2 +$(eval $(call add_define,NEED_SCP_BL2)) +SCP_CFG_DIR=$(dir ${SCP_BL2}) +PLAT_INCLUDES += -I${SCP_CFG_DIR} +endif + +ifneq (${NEED_BL33},yes) +# If there is no BL33, BL31 will jump to this address. +ifeq (${USE_DDR},yes) +PRELOADED_BL33_BASE := 0x80000000 +else +PRELOADED_BL33_BASE := 0x74000000 +endif +endif + # Use translation tables library v1 by default ARM_XLAT_TABLES_LIB_V1 := 1 ifeq (${ARM_XLAT_TABLES_LIB_V1}, 1) diff --git a/plat/brcm/board/common/timer_sync.c b/plat/brcm/board/common/timer_sync.c new file mode 100644 index 000000000..7e33a9407 --- /dev/null +++ b/plat/brcm/board/common/timer_sync.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2015 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include +#include + +/******************************************************************************* + * Defines related to time sync and satelite timers + ******************************************************************************/ +#define TIME_SYNC_WR_ENA ((uint32_t)0xACCE55 << 8) +#define IHOST_STA_TMR_CTRL 0x1800 +#define IHOST_SAT_TMR_INC_L 0x1814 +#define IHOST_SAT_TMR_INC_H 0x1818 + +#define SAT_TMR_CYCLE_DELAY 2 +#define SAT_TMR_32BIT_WRAP_VAL (BIT_64(32) - SAT_TMR_CYCLE_DELAY) + +void ihost_enable_satellite_timer(unsigned int cluster_id) +{ + uintptr_t ihost_base; + uint32_t time_lx, time_h; + uintptr_t ihost_enable; + + VERBOSE("Program iHost%u satellite timer\n", cluster_id); + ihost_base = IHOST0_BASE + cluster_id * IHOST_ADDR_SPACE; + + /* this read starts the satellite timer counting from 0 */ + ihost_enable = CENTRAL_TIMER_GET_IHOST_ENA_BASE + cluster_id * 4; + time_lx = mmio_read_32(ihost_enable); + + /* + * Increment the satellite timer by the central timer plus 2 + * to accommodate for a 1 cycle delay through NOC + * plus counter starting from 0. + */ + mmio_write_32(ihost_base + IHOST_SAT_TMR_INC_L, + time_lx + SAT_TMR_CYCLE_DELAY); + + /* + * Read the latched upper data, if lx will wrap by adding 2 to it + * we need to handle the wrap + */ + time_h = mmio_read_32(CENTRAL_TIMER_GET_H); + if (time_lx >= SAT_TMR_32BIT_WRAP_VAL) + mmio_write_32(ihost_base + IHOST_SAT_TMR_INC_H, time_h + 1); + else + mmio_write_32(ihost_base + IHOST_SAT_TMR_INC_H, time_h); +} + +void brcm_timer_sync_init(void) +{ + unsigned int cluster_id; + + /* Get the Time Sync module out of reset */ + mmio_setbits_32(CDRU_MISC_RESET_CONTROL, + BIT(CDRU_MISC_RESET_CONTROL_TS_RESET_N)); + + /* Deassert the Central Timer TIMER_EN signal for all module */ + mmio_write_32(CENTRAL_TIMER_SAT_TMR_ENA, TIME_SYNC_WR_ENA); + + /* enables/programs iHost0 satellite timer*/ + cluster_id = MPIDR_AFFLVL1_VAL(read_mpidr()); + ihost_enable_satellite_timer(cluster_id); +} diff --git a/plat/brcm/board/stingray/driver/ihost_pll_config.c b/plat/brcm/board/stingray/driver/ihost_pll_config.c new file mode 100644 index 000000000..118492872 --- /dev/null +++ b/plat/brcm/board/stingray/driver/ihost_pll_config.c @@ -0,0 +1,287 @@ +/* + * Copyright (c) 2016-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include + +#include + +#define IHOST0_CONFIG_ROOT 0x66000000 +#define IHOST1_CONFIG_ROOT 0x66002000 +#define IHOST2_CONFIG_ROOT 0x66004000 +#define IHOST3_CONFIG_ROOT 0x66006000 +#define A72_CRM_PLL_PWR_ON 0x00000070 +#define A72_CRM_PLL_PWR_ON__PLL0_RESETB_R 4 +#define A72_CRM_PLL_PWR_ON__PLL0_POST_RESETB_R 5 +#define A72_CRM_PLL_CHNL_BYPS_EN 0x000000ac +#define A72_CRM_PLL_CHNL_BYPS_EN__PLL_0_CHNL_0_BYPS_EN_R 0 +#define A72_CRM_PLL_CHNL_BYPS_EN_DATAMASK 0x0000ec1f +#define A72_CRM_PLL_CMD 0x00000080 +#define A72_CRM_PLL_CMD__UPDATE_PLL0_FREQUENCY_VCO_R 0 +#define A72_CRM_PLL_CMD__UPDATE_PLL0_FREQUENCY_POST_R 1 +#define A72_CRM_PLL_STATUS 0x00000084 +#define A72_CRM_PLL_STATUS__PLL0_LOCK_R 9 +#define A72_CRM_PLL0_CTRL1 0x00000100 +#define A72_CRM_PLL0_CTRL2 0x00000104 +#define A72_CRM_PLL0_CTRL3 0x00000108 +#define A72_CRM_PLL0_CTRL3__PLL0_PDIV_R 12 +#define A72_CRM_PLL0_CTRL4 0x0000010c +#define A72_CRM_PLL0_CTRL4__PLL0_KP_R 0 +#define A72_CRM_PLL0_CTRL4__PLL0_KI_R 4 +#define A72_CRM_PLL0_CTRL4__PLL0_KA_R 7 +#define A72_CRM_PLL0_CTRL4__PLL0_FREFEFF_INFO_R 10 + +#define PLL_MODE_VCO 0x0 +#define PLL_MODE_BYPASS 0x1 +#define PLL_RESET_TYPE_PLL 0x1 +#define PLL_RESET_TYPE_POST 0x2 +#define PLL_VCO 0x1 +#define PLL_POSTDIV 0x2 +#define ARM_FREQ_3G PLL_FREQ_FULL +#define ARM_FREQ_1P5G PLL_FREQ_HALF +#define ARM_FREQ_750M PLL_FREQ_QRTR + +static unsigned int ARMCOE_crm_getBaseAddress(unsigned int cluster_num) +{ + unsigned int ihostx_config_root; + + switch (cluster_num) { + case 0: + default: + ihostx_config_root = IHOST0_CONFIG_ROOT; + break; + case 1: + ihostx_config_root = IHOST1_CONFIG_ROOT; + break; + case 2: + ihostx_config_root = IHOST2_CONFIG_ROOT; + break; + case 3: + ihostx_config_root = IHOST3_CONFIG_ROOT; + break; + } + + return ihostx_config_root; +} + +static void ARMCOE_crm_pllAssertReset(unsigned int cluster_num, + unsigned int reset_type) +{ + unsigned long ihostx_config_root; + unsigned int pll_rst_ctrl; + + ihostx_config_root = ARMCOE_crm_getBaseAddress(cluster_num); + pll_rst_ctrl = mmio_read_32(ihostx_config_root + A72_CRM_PLL_PWR_ON); + + // PLL reset + if (reset_type & PLL_RESET_TYPE_PLL) { + pll_rst_ctrl &= ~(0x1< + +#define CLUSTER_POWER_ON 0x1 +#define CLUSTER_POWER_OFF 0x0 + +void ihost_power_on_cluster(u_register_t mpidr); +void ihost_power_on_secondary_core(u_register_t mpidr, uint64_t rvbar); +void ihost_enable_satellite_timer(unsigned int cluster_id); + +#endif diff --git a/plat/brcm/board/stingray/include/platform_def.h b/plat/brcm/board/stingray/include/platform_def.h index 950c66b69..d61a7378f 100644 --- a/plat/brcm/board/stingray/include/platform_def.h +++ b/plat/brcm/board/stingray/include/platform_def.h @@ -29,16 +29,14 @@ #define PLATFORM_CLUSTER1_CORE_COUNT 2 #define PLATFORM_CLUSTER2_CORE_COUNT 2 #define PLATFORM_CLUSTER3_CORE_COUNT 2 -#define PLATFORM_CLUSTER4_CORE_COUNT 2 #define BRCM_SYSTEM_COUNT 1 -#define BRCM_CLUSTER_COUNT 5 +#define BRCM_CLUSTER_COUNT 4 #define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER0_CORE_COUNT + \ PLATFORM_CLUSTER1_CORE_COUNT+ \ PLATFORM_CLUSTER2_CORE_COUNT+ \ - PLATFORM_CLUSTER3_CORE_COUNT+ \ - PLATFORM_CLUSTER4_CORE_COUNT) + PLATFORM_CLUSTER3_CORE_COUNT) #define PLAT_NUM_PWR_DOMAINS (BRCM_SYSTEM_COUNT + \ BRCM_CLUSTER_COUNT + \ diff --git a/plat/brcm/board/stingray/include/timer_sync.h b/plat/brcm/board/stingray/include/timer_sync.h new file mode 100644 index 000000000..1f15bb0f8 --- /dev/null +++ b/plat/brcm/board/stingray/include/timer_sync.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2016 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef TIMER_SYNC_H +#define TIMER_SYNC_H + +void brcm_timer_sync_init(void); + +#endif diff --git a/plat/brcm/board/stingray/platform.mk b/plat/brcm/board/stingray/platform.mk index 1b9cc3b9c..83e502d1c 100644 --- a/plat/brcm/board/stingray/platform.mk +++ b/plat/brcm/board/stingray/platform.mk @@ -11,6 +11,9 @@ ERRATA_A72_859971 := 1 DRIVER_CC_ENABLE := 1 $(eval $(call add_define,DRIVER_CC_ENABLE)) +# BL31 is in DRAM +ARM_BL31_IN_DRAM := 1 + USE_CRMU_SRAM := yes # Use single cluster @@ -23,6 +26,12 @@ ifeq (${BOARD_CFG},) BOARD_CFG := bcm958742k endif +# BL31 build for standalone mode +ifeq (${STANDALONE_BL31},yes) +RESET_TO_BL31 := 1 +$(info Using RESET_TO_BL31) +endif + # For testing purposes, use memsys stubs. Remove once memsys is fully tested. USE_MEMSYS_STUBS := yes @@ -45,4 +54,36 @@ PLAT_INCLUDES += -Iplat/${SOC_DIR}/include/ \ PLAT_BL_COMMON_SOURCES += lib/cpus/aarch64/cortex_a72.S \ plat/${SOC_DIR}/aarch64/plat_helpers.S \ drivers/ti/uart/aarch64/16550_console.S \ - drivers/arm/tzc/tzc400.c + plat/${SOC_DIR}/src/tz_sec.c \ + drivers/arm/tzc/tzc400.c \ + plat/${SOC_DIR}/src/topology.c + + +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk + +BRCM_GIC_SOURCES := ${GICV3_SOURCES} \ + plat/common/plat_gicv3.c \ + plat/brcm/common/brcm_gicv3.c + +BL31_SOURCES += \ + drivers/arm/ccn/ccn.c \ + plat/brcm/board/common/timer_sync.c \ + plat/brcm/common/brcm_ccn.c \ + plat/common/plat_psci_common.c \ + plat/${SOC_DIR}/driver/ihost_pll_config.c \ + ${BRCM_GIC_SOURCES} + +ifdef SCP_BL2 +PLAT_INCLUDES += -Iplat/brcm/common/ + +BL31_SOURCES += plat/brcm/common/brcm_mhu.c \ + plat/brcm/common/brcm_scpi.c \ + plat/${SOC_DIR}/src/brcm_pm_ops.c +else +BL31_SOURCES += plat/${SOC_DIR}/src/ihost_pm.c \ + plat/${SOC_DIR}/src/pm.c +endif + +# Do not execute the startup code on warm reset. +PROGRAMMABLE_RESET_ADDRESS := 1 diff --git a/plat/brcm/board/stingray/src/brcm_pm_ops.c b/plat/brcm/board/stingray/src/brcm_pm_ops.c new file mode 100644 index 000000000..81d2ccf56 --- /dev/null +++ b/plat/brcm/board/stingray/src/brcm_pm_ops.c @@ -0,0 +1,393 @@ +/* + * Copyright (c) 2017 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "m0_cfg.h" + + +#define CORE_PWR_STATE(state) ((state)->pwr_domain_state[MPIDR_AFFLVL0]) +#define CLUSTER_PWR_STATE(state) \ + ((state)->pwr_domain_state[MPIDR_AFFLVL1]) +#define SYSTEM_PWR_STATE(state) ((state)->pwr_domain_state[MPIDR_AFFLVL2]) + +#define VENDOR_RST_TYPE_SHIFT 4 + +#if HW_ASSISTED_COHERENCY +/* + * On systems where participant CPUs are cache-coherent, we can use spinlocks + * instead of bakery locks. + */ +spinlock_t event_lock; +#define event_lock_get(_lock) spin_lock(&_lock) +#define event_lock_release(_lock) spin_unlock(&_lock) + +#else +/* + * Use bakery locks for state coordination as not all participants are + * cache coherent now. + */ +DEFINE_BAKERY_LOCK(event_lock); +#define event_lock_get(_lock) bakery_lock_get(&_lock) +#define event_lock_release(_lock) bakery_lock_release(&_lock) +#endif + +static int brcm_pwr_domain_on(u_register_t mpidr) +{ + /* + * SCP takes care of powering up parent power domains so we + * only need to care about level 0 + */ + scpi_set_brcm_power_state(mpidr, scpi_power_on, scpi_power_on, + scpi_power_on); + + return PSCI_E_SUCCESS; +} + +/******************************************************************************* + * Handler called when a power level has just been powered on after + * being turned off earlier. The target_state encodes the low power state that + * each level has woken up from. This handler would never be invoked with + * the system power domain uninitialized as either the primary would have taken + * care of it as part of cold boot or the first core awakened from system + * suspend would have already initialized it. + ******************************************************************************/ +static void brcm_pwr_domain_on_finish(const psci_power_state_t *target_state) +{ + unsigned long cluster_id = MPIDR_AFFLVL1_VAL(read_mpidr()); + + /* Assert that the system power domain need not be initialized */ + assert(SYSTEM_PWR_STATE(target_state) == PLAT_LOCAL_STATE_RUN); + + assert(CORE_PWR_STATE(target_state) == PLAT_LOCAL_STATE_OFF); + + /* + * Perform the common cluster specific operations i.e enable coherency + * if this cluster was off. + */ + if (CLUSTER_PWR_STATE(target_state) == PLAT_LOCAL_STATE_OFF) { + INFO("Cluster #%lu entering to snoop/dvm domain\n", cluster_id); + ccn_enter_snoop_dvm_domain(1 << cluster_id); + } + + /* Program the gic per-cpu distributor or re-distributor interface */ + plat_brcm_gic_pcpu_init(); + + /* Enable the gic cpu interface */ + plat_brcm_gic_cpuif_enable(); +} + +static void brcm_power_down_common(void) +{ + unsigned int standbywfil2, standbywfi; + uint64_t mpidr = read_mpidr_el1(); + + switch (MPIDR_AFFLVL1_VAL(mpidr)) { + case 0x0: + standbywfi = CDRU_PROC_EVENT_CLEAR__IH0_CDRU_STANDBYWFI; + standbywfil2 = CDRU_PROC_EVENT_CLEAR__IH0_CDRU_STANDBYWFIL2; + break; + case 0x1: + standbywfi = CDRU_PROC_EVENT_CLEAR__IH1_CDRU_STANDBYWFI; + standbywfil2 = CDRU_PROC_EVENT_CLEAR__IH1_CDRU_STANDBYWFIL2; + break; + case 0x2: + standbywfi = CDRU_PROC_EVENT_CLEAR__IH2_CDRU_STANDBYWFI; + standbywfil2 = CDRU_PROC_EVENT_CLEAR__IH2_CDRU_STANDBYWFIL2; + break; + case 0x3: + standbywfi = CDRU_PROC_EVENT_CLEAR__IH3_CDRU_STANDBYWFI; + standbywfil2 = CDRU_PROC_EVENT_CLEAR__IH3_CDRU_STANDBYWFIL2; + break; + default: + ERROR("Invalid cluster #%llx\n", MPIDR_AFFLVL1_VAL(mpidr)); + return; + } + /* Clear the WFI status bit */ + event_lock_get(event_lock); + mmio_setbits_32(CDRU_PROC_EVENT_CLEAR, + (1 << (standbywfi + MPIDR_AFFLVL0_VAL(mpidr))) | + (1 << standbywfil2)); + event_lock_release(event_lock); +} + +/* + * Helper function to inform power down state to SCP. + */ +static void brcm_scp_suspend(const psci_power_state_t *target_state) +{ + uint32_t cluster_state = scpi_power_on; + uint32_t system_state = scpi_power_on; + + /* Check if power down at system power domain level is requested */ + if (SYSTEM_PWR_STATE(target_state) == PLAT_LOCAL_STATE_OFF) + system_state = scpi_power_retention; + + /* Check if Cluster is to be turned off */ + if (CLUSTER_PWR_STATE(target_state) == PLAT_LOCAL_STATE_OFF) + cluster_state = scpi_power_off; + + /* + * Ask the SCP to power down the appropriate components depending upon + * their state. + */ + scpi_set_brcm_power_state(read_mpidr_el1(), + scpi_power_off, + cluster_state, + system_state); +} + +/* + * Helper function to turn off a CPU power domain and its parent power domains + * if applicable. Since SCPI doesn't differentiate between OFF and suspend, we + * call the suspend helper here. + */ +static void brcm_scp_off(const psci_power_state_t *target_state) +{ + brcm_scp_suspend(target_state); +} + +static void brcm_pwr_domain_off(const psci_power_state_t *target_state) +{ + unsigned long cluster_id = MPIDR_AFFLVL1_VAL(read_mpidr_el1()); + + assert(CORE_PWR_STATE(target_state) == PLAT_LOCAL_STATE_OFF); + /* Prevent interrupts from spuriously waking up this cpu */ + plat_brcm_gic_cpuif_disable(); + + /* Turn redistributor off */ + plat_brcm_gic_redistif_off(); + + /* If Cluster is to be turned off, disable coherency */ + if (CLUSTER_PWR_STATE(target_state) == PLAT_LOCAL_STATE_OFF) + ccn_exit_snoop_dvm_domain(1 << cluster_id); + + brcm_power_down_common(); + + brcm_scp_off(target_state); +} + +/******************************************************************************* + * Handler called when the CPU power domain is about to enter standby. + ******************************************************************************/ +static void brcm_cpu_standby(plat_local_state_t cpu_state) +{ + unsigned int scr; + + assert(cpu_state == PLAT_LOCAL_STATE_RET); + + scr = read_scr_el3(); + /* + * Enable the Non secure interrupt to wake the CPU. + * In GICv3 affinity routing mode, the non secure group1 interrupts use + * the PhysicalFIQ at EL3 whereas in GICv2, it uses the PhysicalIRQ. + * 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(); + dsb(); + wfi(); + + /* + * Restore SCR to the original value, synchronisation of scr_el3 is + * done by eret while el3_exit to save some execution cycles. + */ + write_scr_el3(scr); +} + +/* + * Helper function to shutdown the system via SCPI. + */ +static void __dead2 brcm_scp_sys_shutdown(void) +{ + /* + * Disable GIC CPU interface to prevent pending interrupt + * from waking up the AP from WFI. + */ + plat_brcm_gic_cpuif_disable(); + + /* Flush and invalidate data cache */ + dcsw_op_all(DCCISW); + + /* Bring Cluster out of coherency domain as its going to die */ + plat_brcm_interconnect_exit_coherency(); + + brcm_power_down_common(); + + /* Send the power down request to the SCP */ + scpi_sys_power_state(scpi_system_shutdown); + + wfi(); + ERROR("BRCM System Off: operation not handled.\n"); + panic(); +} + +/* + * Helper function to reset the system + */ +static void __dead2 brcm_scp_sys_reset(unsigned int reset_type) +{ + /* + * Disable GIC CPU interface to prevent pending interrupt + * from waking up the AP from WFI. + */ + plat_brcm_gic_cpuif_disable(); + + /* Flush and invalidate data cache */ + dcsw_op_all(DCCISW); + + /* Bring Cluster out of coherency domain as its going to die */ + plat_brcm_interconnect_exit_coherency(); + + brcm_power_down_common(); + + /* Send the system reset request to the SCP + * + * As per PSCI spec system power state could be + * 0-> Shutdown + * 1-> Reboot- Board level Reset + * 2-> Reset - SoC level Reset + * + * Spec allocates 8 bits, 2 nibble, for this. One nibble is sufficient + * for sending the state hence We are utilizing 2nd nibble for vendor + * define reset type. + */ + scpi_sys_power_state((reset_type << VENDOR_RST_TYPE_SHIFT) | + scpi_system_reboot); + + wfi(); + ERROR("BRCM System Reset: operation not handled.\n"); + panic(); +} + +static void __dead2 brcm_system_reset(void) +{ + brcm_scp_sys_reset(SOFT_SYS_RESET_L1); +} + +static int brcm_system_reset2(int is_vendor, int reset_type, + u_register_t cookie) +{ + if (!is_vendor) { + /* Architectural warm boot: only warm reset is supported */ + reset_type = SOFT_RESET_L3; + } + brcm_scp_sys_reset(reset_type); + + /* + * brcm_scp_sys_reset cannot return (it is a __dead function), + * but brcm_system_reset2 has to return some value, even in + * this case. + */ + return 0; +} + +static int brcm_validate_ns_entrypoint(uintptr_t entrypoint) +{ + /* + * Check if the non secure entrypoint lies within the non + * secure DRAM. + */ + if ((entrypoint >= BRCM_NS_DRAM1_BASE) && + (entrypoint < (BRCM_NS_DRAM1_BASE + BRCM_NS_DRAM1_SIZE))) + return PSCI_E_SUCCESS; +#ifndef AARCH32 + if ((entrypoint >= BRCM_DRAM2_BASE) && + (entrypoint < (BRCM_DRAM2_BASE + BRCM_DRAM2_SIZE))) + return PSCI_E_SUCCESS; + + if ((entrypoint >= BRCM_DRAM3_BASE) && + (entrypoint < (BRCM_DRAM3_BASE + BRCM_DRAM3_SIZE))) + return PSCI_E_SUCCESS; +#endif + + return PSCI_E_INVALID_ADDRESS; +} + +/******************************************************************************* + * ARM standard platform handler called to check the validity of the power state + * parameter. + ******************************************************************************/ +static int brcm_validate_power_state(unsigned int power_state, + psci_power_state_t *req_state) +{ + int pstate = psci_get_pstate_type(power_state); + int pwr_lvl = psci_get_pstate_pwrlvl(power_state); + int i; + + assert(req_state); + + if (pwr_lvl > PLAT_MAX_PWR_LVL) + return PSCI_E_INVALID_PARAMS; + + /* Sanity check the requested state */ + if (pstate == PSTATE_TYPE_STANDBY) { + /* + * It's possible to enter standby only on power level 0 + * Ignore any other power level. + */ + if (pwr_lvl != MPIDR_AFFLVL0) + return PSCI_E_INVALID_PARAMS; + + req_state->pwr_domain_state[MPIDR_AFFLVL0] = + PLAT_LOCAL_STATE_RET; + } else { + for (i = MPIDR_AFFLVL0; i <= pwr_lvl; i++) + req_state->pwr_domain_state[i] = + PLAT_LOCAL_STATE_OFF; + } + + /* + * We expect the 'state id' to be zero. + */ + if (psci_get_pstate_id(power_state)) + return PSCI_E_INVALID_PARAMS; + + return PSCI_E_SUCCESS; +} + +/******************************************************************************* + * Export the platform handlers via plat_brcm_psci_pm_ops. The ARM Standard + * platform will take care of registering the handlers with PSCI. + ******************************************************************************/ +plat_psci_ops_t plat_brcm_psci_pm_ops = { + .pwr_domain_on = brcm_pwr_domain_on, + .pwr_domain_on_finish = brcm_pwr_domain_on_finish, + .pwr_domain_off = brcm_pwr_domain_off, + .cpu_standby = brcm_cpu_standby, + .system_off = brcm_scp_sys_shutdown, + .system_reset = brcm_system_reset, + .system_reset2 = brcm_system_reset2, + .validate_ns_entrypoint = brcm_validate_ns_entrypoint, + .validate_power_state = brcm_validate_power_state, +}; + +int plat_setup_psci_ops(uintptr_t sec_entrypoint, + const struct plat_psci_ops **psci_ops) +{ + *psci_ops = &plat_brcm_psci_pm_ops; + + /* Setup mailbox with entry point. */ + mmio_write_64(CRMU_CFG_BASE + offsetof(M0CFG, core_cfg.rvbar), + sec_entrypoint); + + return 0; +} diff --git a/plat/brcm/board/stingray/src/ihost_pm.c b/plat/brcm/board/stingray/src/ihost_pm.c new file mode 100644 index 000000000..9141d3e31 --- /dev/null +++ b/plat/brcm/board/stingray/src/ihost_pm.c @@ -0,0 +1,355 @@ +/* + * Copyright (c) 2016 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include +#include +#include + +#define CDRU_CCN_REGISTER_CONTROL_1__D2XS_PD_IHOST1 2 +#define CDRU_CCN_REGISTER_CONTROL_1__D2XS_PD_IHOST2 1 +#define CDRU_CCN_REGISTER_CONTROL_1__D2XS_PD_IHOST3 0 +#define CDRU_MISC_RESET_CONTROL__CDRU_IH1_RESET 9 +#define CDRU_MISC_RESET_CONTROL__CDRU_IH2_RESET 8 +#define CDRU_MISC_RESET_CONTROL__CDRU_IH3_RESET 7 +#define A72_CRM_SOFTRESETN_0 0x480 +#define A72_CRM_SOFTRESETN_1 0x484 +#define A72_CRM_DOMAIN_4_CONTROL 0x810 +#define A72_CRM_DOMAIN_4_CONTROL__DOMAIN_4_ISO_DFT 3 +#define A72_CRM_DOMAIN_4_CONTROL__DOMAIN_4_ISO_MEM 6 +#define A72_CRM_DOMAIN_4_CONTROL__DOMAIN_4_ISO_I_O 0 +#define A72_CRM_SUBSYSTEM_MEMORY_CONTROL_3 0xB4C +#define MEMORY_PDA_HI_SHIFT 0x0 +#define A72_CRM_PLL_PWR_ON 0x70 +#define A72_CRM_PLL_PWR_ON__PLL0_ISO_PLLOUT 4 +#define A72_CRM_PLL_PWR_ON__PLL0_PWRON_LDO 1 +#define A72_CRM_PLL_PWR_ON__PLL0_PWRON_PLL 0 +#define A72_CRM_SUBSYSTEM_MEMORY_CONTROL_2 0xB48 +#define A72_CRM_PLL_INTERRUPT_STATUS 0x8c +#define A72_CRM_PLL_INTERRUPT_STATUS__PLL0_LOCK_LOST_STATUS 8 +#define A72_CRM_PLL_INTERRUPT_STATUS__PLL0_LOCK_STATUS 9 +#define A72_CRM_INTERRUPT_ENABLE 0x4 +#define A72_CRM_INTERRUPT_ENABLE__PLL0_INT_ENABLE 4 +#define A72_CRM_PLL_INTERRUPT_ENABLE 0x88 +#define A72_CRM_PLL_INTERRUPT_ENABLE__PLL0_LOCK_STATUS_INT_ENB 9 +#define A72_CRM_PLL_INTERRUPT_ENABLE__PLL0_LOCK_LOST_STATUS_INT_ENB 8 +#define A72_CRM_PLL0_CFG0_CTRL 0x120 +#define A72_CRM_PLL0_CFG1_CTRL 0x124 +#define A72_CRM_PLL0_CFG2_CTRL 0x128 +#define A72_CRM_PLL0_CFG3_CTRL 0x12C +#define A72_CRM_CORE_CONFIG_DBGCTRL__DBGROMADDRV 0 +#define A72_CRM_CORE_CONFIG_DBGCTRL 0xD50 +#define A72_CRM_CORE_CONFIG_DBGROM_LO 0xD54 +#define A72_CRM_CORE_CONFIG_DBGROM_HI 0xD58 +#define A72_CRM_SUBSYSTEM_CONFIG_1__DBGL1RSTDISABLE 2 +#define A72_CRM_SOFTRESETN_0__CRYSTAL26_SOFTRESETN 0 +#define A72_CRM_SOFTRESETN_0__CRM_PLL0_SOFTRESETN 1 +#define A72_CRM_AXI_CLK_DESC 0x304 +#define A72_CRM_ACP_CLK_DESC 0x308 +#define A72_CRM_ATB_CLK_DESC 0x30C +#define A72_CRM_PCLKDBG_DESC 0x310 +#define A72_CRM_CLOCK_MODE_CONTROL 0x40 +#define A72_CRM_CLOCK_MODE_CONTROL__CLK_CHANGE_TRIGGER 0 +#define A72_CRM_CLOCK_CONTROL_0 0x200 +#define A72_CRM_CLOCK_CONTROL_0__ARM_HW_SW_ENABLE_SEL 0 +#define A72_CRM_CLOCK_CONTROL_0__AXI_HW_SW_ENABLE_SEL 2 +#define A72_CRM_CLOCK_CONTROL_0__ACP_HW_SW_ENABLE_SEL 4 +#define A72_CRM_CLOCK_CONTROL_0__ATB_HW_SW_ENABLE_SEL 6 +#define A72_CRM_CLOCK_CONTROL_0__PCLKDBG_HW_SW_ENA_SEL 8 +#define A72_CRM_CLOCK_CONTROL_1 0x204 +#define A72_CRM_CLOCK_CONTROL_1__TMON_HW_SW_ENABLE_SEL 6 +#define A72_CRM_CLOCK_CONTROL_1__APB_HW_SW_ENABLE_SEL 8 +#define A72_CRM_SOFTRESETN_0__CRYSTAL26_SOFTRESETN 0 +#define A72_CRM_SOFTRESETN_0__CRM_PLL0_SOFTRESETN 1 +#define A72_CRM_SOFTRESETN_0__AXI_SOFTRESETN 9 +#define A72_CRM_SOFTRESETN_0__ACP_SOFTRESETN 10 +#define A72_CRM_SOFTRESETN_0__ATB_SOFTRESETN 11 +#define A72_CRM_SOFTRESETN_0__PCLKDBG_SOFTRESETN 12 +#define A72_CRM_SOFTRESETN_0__TMON_SOFTRESETN 15 +#define A72_CRM_SOFTRESETN_0__L2_SOFTRESETN 3 +#define A72_CRM_SOFTRESETN_1__APB_SOFTRESETN 8 + +/* core related regs */ +#define A72_CRM_DOMAIN_0_CONTROL 0x800 +#define A72_CRM_DOMAIN_0_CONTROL__DOMAIN_0_ISO_MEM 0x6 +#define A72_CRM_DOMAIN_0_CONTROL__DOMAIN_0_ISO_I_O 0x0 +#define A72_CRM_DOMAIN_1_CONTROL 0x804 +#define A72_CRM_DOMAIN_1_CONTROL__DOMAIN_1_ISO_MEM 0x6 +#define A72_CRM_DOMAIN_1_CONTROL__DOMAIN_1_ISO_I_O 0x0 +#define A72_CRM_CORE_CONFIG_RVBA0_LO 0xD10 +#define A72_CRM_CORE_CONFIG_RVBA0_MID 0xD14 +#define A72_CRM_CORE_CONFIG_RVBA0_HI 0xD18 +#define A72_CRM_CORE_CONFIG_RVBA1_LO 0xD20 +#define A72_CRM_CORE_CONFIG_RVBA1_MID 0xD24 +#define A72_CRM_CORE_CONFIG_RVBA1_HI 0xD28 +#define A72_CRM_SUBSYSTEM_CONFIG_0 0xC80 +#define A72_CRM_SUBSYSTEM_CONFIG_0__DBGPWRDUP_CFG_SHIFT 4 +#define A72_CRM_SOFTRESETN_0__COREPOR0_SOFTRESETN 4 +#define A72_CRM_SOFTRESETN_0__COREPOR1_SOFTRESETN 5 +#define A72_CRM_SOFTRESETN_1__CORE0_SOFTRESETN 0 +#define A72_CRM_SOFTRESETN_1__DEBUG0_SOFTRESETN 4 +#define A72_CRM_SOFTRESETN_1__CORE1_SOFTRESETN 1 +#define A72_CRM_SOFTRESETN_1__DEBUG1_SOFTRESETN 5 + +#define SPROC_MEMORY_BISR 0 + +static int cluster_power_status[PLAT_BRCM_CLUSTER_COUNT] = {CLUSTER_POWER_ON, + CLUSTER_POWER_OFF, + CLUSTER_POWER_OFF, + CLUSTER_POWER_OFF}; + +void ihost_power_on_cluster(u_register_t mpidr) +{ + uint32_t rst, d2xs; + uint32_t cluster_id; + uint32_t ihost_base; +#if SPROC_MEMORY_BISR + uint32_t bisr, cnt; +#endif + cluster_id = MPIDR_AFFLVL1_VAL(mpidr); + uint32_t cluster0_freq_sel; + + if (cluster_power_status[cluster_id] == CLUSTER_POWER_ON) + return; + + cluster_power_status[cluster_id] = CLUSTER_POWER_ON; + INFO("enabling Cluster #%u\n", cluster_id); + + switch (cluster_id) { + case 1: + rst = (1 << CDRU_MISC_RESET_CONTROL__CDRU_IH1_RESET); + d2xs = (1 << CDRU_CCN_REGISTER_CONTROL_1__D2XS_PD_IHOST1); +#if SPROC_MEMORY_BISR + bisr = CRMU_BISR_PDG_MASK__CRMU_BISR_IHOST1; +#endif + break; + case 2: + rst = (1 << CDRU_MISC_RESET_CONTROL__CDRU_IH2_RESET); + d2xs = (1 << CDRU_CCN_REGISTER_CONTROL_1__D2XS_PD_IHOST2); +#if SPROC_MEMORY_BISR + bisr = CRMU_BISR_PDG_MASK__CRMU_BISR_IHOST2; +#endif + break; + case 3: + rst = (1 << CDRU_MISC_RESET_CONTROL__CDRU_IH3_RESET); + d2xs = (1 << CDRU_CCN_REGISTER_CONTROL_1__D2XS_PD_IHOST3); +#if SPROC_MEMORY_BISR + bisr = CRMU_BISR_PDG_MASK__CRMU_BISR_IHOST3; +#endif + break; + default: + ERROR("Invalid cluster :%u\n", cluster_id); + return; + } + + /* Releasing ihost resets */ + mmio_setbits_32(CDRU_MISC_RESET_CONTROL, rst); + + /* calculate cluster/ihost base address */ + ihost_base = IHOST0_BASE + cluster_id * IHOST_ADDR_SPACE; + + /* Remove Cluster IO isolation */ + mmio_clrsetbits_32(ihost_base + A72_CRM_DOMAIN_4_CONTROL, + (1 << A72_CRM_DOMAIN_4_CONTROL__DOMAIN_4_ISO_I_O), + (1 << A72_CRM_DOMAIN_4_CONTROL__DOMAIN_4_ISO_DFT) | + (1 << A72_CRM_DOMAIN_4_CONTROL__DOMAIN_4_ISO_MEM)); + + /* + * Since BISR sequence requires that all cores of cluster should + * have removed I/O isolation hence doing same here. + */ + /* Remove core0 memory IO isolations */ + mmio_clrsetbits_32(ihost_base + A72_CRM_DOMAIN_0_CONTROL, + (1 << A72_CRM_DOMAIN_0_CONTROL__DOMAIN_0_ISO_I_O), + (1 << A72_CRM_DOMAIN_0_CONTROL__DOMAIN_0_ISO_MEM)); + + /* Remove core1 memory IO isolations */ + mmio_clrsetbits_32(ihost_base + A72_CRM_DOMAIN_1_CONTROL, + (1 << A72_CRM_DOMAIN_1_CONTROL__DOMAIN_1_ISO_I_O), + (1 << A72_CRM_DOMAIN_1_CONTROL__DOMAIN_1_ISO_MEM)); + +#if SPROC_MEMORY_BISR + mmio_setbits_32(CRMU_BISR_PDG_MASK, (1 << bisr)); + + if (!(mmio_read_32(CDRU_CHIP_STRAP_DATA_LSW) & + (1 << CDRU_CHIP_STRAP_DATA_LSW__BISR_BYPASS_MODE))) { + /* BISR completion would take max 2 usec */ + cnt = 0; + while (cnt < 2) { + udelay(1); + if (mmio_read_32(CRMU_CHIP_OTPC_STATUS) & + (1 << CRMU_CHIP_OTPC_STATUS__OTP_BISR_LOAD_DONE)) + break; + cnt++; + } + } + + /* if BISR is not completed, need to be checked with ASIC team */ + if (((mmio_read_32(CRMU_CHIP_OTPC_STATUS)) & + (1 << CRMU_CHIP_OTPC_STATUS__OTP_BISR_LOAD_DONE)) == 0) { + WARN("BISR did not completed and need to be addressed\n"); + } +#endif + + /* PLL Power up. supply is already on. Turn on PLL LDO/PWR */ + mmio_write_32(ihost_base + A72_CRM_PLL_PWR_ON, + (1 << A72_CRM_PLL_PWR_ON__PLL0_ISO_PLLOUT) | + (1 << A72_CRM_PLL_PWR_ON__PLL0_PWRON_LDO) | + (1 << A72_CRM_PLL_PWR_ON__PLL0_PWRON_PLL)); + + /* 1us in spec; Doubling it to be safe*/ + udelay(2); + + /* Remove PLL output ISO */ + mmio_write_32(ihost_base + A72_CRM_PLL_PWR_ON, + (1 << A72_CRM_PLL_PWR_ON__PLL0_PWRON_LDO) | + (1 << A72_CRM_PLL_PWR_ON__PLL0_PWRON_PLL)); + + /* + * PLL0 Configuration Control Register + * these 4 registers drive the i_pll_ctrl[63:0] input of pll + * (16b per register). + * the values are derived from the spec (sections 8 and 10). + */ + + mmio_write_32(ihost_base + A72_CRM_PLL0_CFG0_CTRL, 0x00000000); + mmio_write_32(ihost_base + A72_CRM_PLL0_CFG1_CTRL, 0x00008400); + mmio_write_32(ihost_base + A72_CRM_PLL0_CFG2_CTRL, 0x00000001); + mmio_write_32(ihost_base + A72_CRM_PLL0_CFG3_CTRL, 0x00000000); + + /* Read the freq_sel from cluster 0, which is up already */ + cluster0_freq_sel = bcm_get_ihost_pll_freq(0); + bcm_set_ihost_pll_freq(cluster_id, cluster0_freq_sel); + + udelay(1); + + /* Release clock source reset */ + mmio_setbits_32(ihost_base + A72_CRM_SOFTRESETN_0, + (1 << A72_CRM_SOFTRESETN_0__CRYSTAL26_SOFTRESETN) | + (1 << A72_CRM_SOFTRESETN_0__CRM_PLL0_SOFTRESETN)); + + udelay(1); + + /* + * Integer division for clks (divider value = n+1). + * These are the divisor of ARM PLL clock frequecy. + */ + mmio_write_32(ihost_base + A72_CRM_AXI_CLK_DESC, 0x00000001); + mmio_write_32(ihost_base + A72_CRM_ACP_CLK_DESC, 0x00000001); + mmio_write_32(ihost_base + A72_CRM_ATB_CLK_DESC, 0x00000004); + mmio_write_32(ihost_base + A72_CRM_PCLKDBG_DESC, 0x0000000b); + + /* + * clock change trigger - must set to take effect after clock + * source change + */ + mmio_setbits_32(ihost_base + A72_CRM_CLOCK_MODE_CONTROL, + (1 << A72_CRM_CLOCK_MODE_CONTROL__CLK_CHANGE_TRIGGER)); + + /* turn on functional clocks */ + mmio_setbits_32(ihost_base + A72_CRM_CLOCK_CONTROL_0, + (3 << A72_CRM_CLOCK_CONTROL_0__ARM_HW_SW_ENABLE_SEL) | + (3 << A72_CRM_CLOCK_CONTROL_0__AXI_HW_SW_ENABLE_SEL) | + (3 << A72_CRM_CLOCK_CONTROL_0__ACP_HW_SW_ENABLE_SEL) | + (3 << A72_CRM_CLOCK_CONTROL_0__ATB_HW_SW_ENABLE_SEL) | + (3 << A72_CRM_CLOCK_CONTROL_0__PCLKDBG_HW_SW_ENA_SEL)); + + mmio_setbits_32(ihost_base + A72_CRM_CLOCK_CONTROL_1, + (3 << A72_CRM_CLOCK_CONTROL_1__TMON_HW_SW_ENABLE_SEL) | + (3 << A72_CRM_CLOCK_CONTROL_1__APB_HW_SW_ENABLE_SEL)); + + /* Program D2XS Power Down Registers */ + mmio_setbits_32(CDRU_CCN_REGISTER_CONTROL_1, d2xs); + + /* Program Core Config Debug ROM Address Registers */ + /* mark valid for Debug ROM base address */ + mmio_write_32(ihost_base + A72_CRM_CORE_CONFIG_DBGCTRL, + (1 << A72_CRM_CORE_CONFIG_DBGCTRL__DBGROMADDRV)); + + /* Program Lo and HI address of coresight DBG rom address */ + mmio_write_32(ihost_base + A72_CRM_CORE_CONFIG_DBGROM_LO, + (CORESIGHT_BASE_ADDR >> 12) & 0xffff); + mmio_write_32(ihost_base + A72_CRM_CORE_CONFIG_DBGROM_HI, + (CORESIGHT_BASE_ADDR >> 28) & 0xffff); + + /* + * Release soft resets of different components. + * Order: Bus clocks --> PERIPH --> L2 --> cores + */ + + /* Bus clocks soft resets */ + mmio_setbits_32(ihost_base + A72_CRM_SOFTRESETN_0, + (1 << A72_CRM_SOFTRESETN_0__CRYSTAL26_SOFTRESETN) | + (1 << A72_CRM_SOFTRESETN_0__CRM_PLL0_SOFTRESETN) | + (1 << A72_CRM_SOFTRESETN_0__AXI_SOFTRESETN) | + (1 << A72_CRM_SOFTRESETN_0__ACP_SOFTRESETN) | + (1 << A72_CRM_SOFTRESETN_0__ATB_SOFTRESETN) | + (1 << A72_CRM_SOFTRESETN_0__PCLKDBG_SOFTRESETN)); + + mmio_setbits_32(ihost_base + A72_CRM_SOFTRESETN_1, + (1 << A72_CRM_SOFTRESETN_1__APB_SOFTRESETN)); + + /* Periph component softreset */ + mmio_setbits_32(ihost_base + A72_CRM_SOFTRESETN_0, + (1 << A72_CRM_SOFTRESETN_0__TMON_SOFTRESETN)); + + /* L2 softreset */ + mmio_setbits_32(ihost_base + A72_CRM_SOFTRESETN_0, + (1 << A72_CRM_SOFTRESETN_0__L2_SOFTRESETN)); + + /* Enable and program Satellite timer */ + ihost_enable_satellite_timer(cluster_id); +} + +void ihost_power_on_secondary_core(u_register_t mpidr, uint64_t rvbar) +{ + uint32_t ihost_base; + uint32_t coreid = MPIDR_AFFLVL0_VAL(mpidr); + uint32_t cluster_id = MPIDR_AFFLVL1_VAL(mpidr); + + ihost_base = IHOST0_BASE + cluster_id * IHOST_ADDR_SPACE; + INFO("programming core #%u\n", coreid); + + if (coreid) { + /* program the entry point for core1 */ + mmio_write_32(ihost_base + A72_CRM_CORE_CONFIG_RVBA1_LO, + rvbar & 0xFFFF); + mmio_write_32(ihost_base + A72_CRM_CORE_CONFIG_RVBA1_MID, + (rvbar >> 16) & 0xFFFF); + mmio_write_32(ihost_base + A72_CRM_CORE_CONFIG_RVBA1_HI, + (rvbar >> 32) & 0xFFFF); + } else { + /* program the entry point for core */ + mmio_write_32(ihost_base + A72_CRM_CORE_CONFIG_RVBA0_LO, + rvbar & 0xFFFF); + mmio_write_32(ihost_base + A72_CRM_CORE_CONFIG_RVBA0_MID, + (rvbar >> 16) & 0xFFFF); + mmio_write_32(ihost_base + A72_CRM_CORE_CONFIG_RVBA0_HI, + (rvbar >> 32) & 0xFFFF); + } + + /* Tell debug logic which processor is up */ + mmio_setbits_32(ihost_base + A72_CRM_SUBSYSTEM_CONFIG_0, + (coreid ? + (2 << A72_CRM_SUBSYSTEM_CONFIG_0__DBGPWRDUP_CFG_SHIFT) : + (1 << A72_CRM_SUBSYSTEM_CONFIG_0__DBGPWRDUP_CFG_SHIFT))); + + /* releasing soft resets for IHOST core */ + mmio_setbits_32(ihost_base + A72_CRM_SOFTRESETN_0, + (coreid ? + (1 << A72_CRM_SOFTRESETN_0__COREPOR1_SOFTRESETN) : + (1 << A72_CRM_SOFTRESETN_0__COREPOR0_SOFTRESETN))); + + mmio_setbits_32(ihost_base + A72_CRM_SOFTRESETN_1, + (coreid ? + ((1 << A72_CRM_SOFTRESETN_1__CORE1_SOFTRESETN) | + (1 << A72_CRM_SOFTRESETN_1__DEBUG1_SOFTRESETN)) : + ((1 << A72_CRM_SOFTRESETN_1__CORE0_SOFTRESETN) | + (1 << A72_CRM_SOFTRESETN_1__DEBUG0_SOFTRESETN)))); +} diff --git a/plat/brcm/board/stingray/src/pm.c b/plat/brcm/board/stingray/src/pm.c new file mode 100644 index 000000000..a5ac2e705 --- /dev/null +++ b/plat/brcm/board/stingray/src/pm.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2015 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef USE_PAXC +#include +#endif +#include +#include +#include +#include + +static uint64_t plat_sec_entrypoint; + +/******************************************************************************* + * SR handler called when a power domain is about to be turned on. The + * mpidr determines the CPU to be turned on. + ******************************************************************************/ +static int brcm_pwr_domain_on(u_register_t mpidr) +{ + int cpuid; + + cpuid = plat_brcm_calc_core_pos(mpidr); + INFO("mpidr :%lu, cpuid:%d\n", mpidr, cpuid); + +#ifdef USE_SINGLE_CLUSTER + if (cpuid > 1) + return PSCI_E_INTERN_FAIL; +#endif + + ihost_power_on_cluster(mpidr); + + ihost_power_on_secondary_core(mpidr, plat_sec_entrypoint); + + return PSCI_E_SUCCESS; +} + +/******************************************************************************* + * SR handler called when a power domain has just been powered on after + * being turned off earlier. The target_state encodes the low power state that + * each level has woken up from. + ******************************************************************************/ +static void brcm_pwr_domain_on_finish(const psci_power_state_t *target_state) +{ + unsigned long cluster_id = MPIDR_AFFLVL1_VAL(read_mpidr()); + + assert(target_state->pwr_domain_state[MPIDR_AFFLVL0] == + PLAT_LOCAL_STATE_OFF); + + if (target_state->pwr_domain_state[MPIDR_AFFLVL1] == + PLAT_LOCAL_STATE_OFF) { + INFO("Cluster #%lu entering to snoop/dvm domain\n", cluster_id); + ccn_enter_snoop_dvm_domain(1 << cluster_id); + } + + /* Enable the gic cpu interface */ + plat_brcm_gic_pcpu_init(); + + /* Program the gic per-cpu distributor or re-distributor interface */ + plat_brcm_gic_cpuif_enable(); + + INFO("Gic Initialization done for this affinity instance\n"); +} + +static void __dead2 brcm_system_reset(void) +{ + uint32_t reset_type = SOFT_SYS_RESET_L1; + +#ifdef USE_PAXC + if (bcm_chimp_is_nic_mode()) + reset_type = SOFT_RESET_L3; +#endif + INFO("System rebooting - L%d...\n", reset_type); + + plat_soft_reset(reset_type); + + /* Prevent the function to return due to the attribute */ + while (1) + ; +} + +static int brcm_system_reset2(int is_vendor, int reset_type, + u_register_t cookie) +{ + INFO("System rebooting - L%d...\n", reset_type); + + plat_soft_reset(reset_type); + + /* + * plat_soft_reset cannot return (it is a __dead function), + * but brcm_system_reset2 has to return some value, even in + * this case. + */ + return 0; +} + +/******************************************************************************* + * Export the platform handlers via plat_brcm_psci_pm_ops. The ARM Standard + * platform will take care of registering the handlers with PSCI. + ******************************************************************************/ +const plat_psci_ops_t plat_brcm_psci_pm_ops = { + .pwr_domain_on = brcm_pwr_domain_on, + .pwr_domain_on_finish = brcm_pwr_domain_on_finish, + .system_reset = brcm_system_reset, + .system_reset2 = brcm_system_reset2 +}; + +int plat_setup_psci_ops(uintptr_t sec_entrypoint, + const plat_psci_ops_t **psci_ops) +{ + *psci_ops = &plat_brcm_psci_pm_ops; + plat_sec_entrypoint = sec_entrypoint; + + return 0; +} diff --git a/plat/brcm/board/stingray/src/topology.c b/plat/brcm/board/stingray/src/topology.c new file mode 100644 index 000000000..24718e590 --- /dev/null +++ b/plat/brcm/board/stingray/src/topology.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2019-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include + +#include +#include + +/* + * On Stingray, the system power level is the highest power level. + * The first entry in the power domain descriptor specifies the + * number of system power domains i.e. 1. + */ +#define SR_PWR_DOMAINS_AT_MAX_PWR_LVL 1 + +/* + * The Stingray power domain tree descriptor. The cluster power domains + * are arranged so that when the PSCI generic code creates the power + * domain tree, the indices of the CPU power domain nodes it allocates + * match the linear indices returned by plat_core_pos_by_mpidr() + * i.e. CLUSTER0 CPUs are allocated indices from 0 to 1 and the higher + * indices for other Cluster CPUs. + */ +const unsigned char sr_power_domain_tree_desc[] = { + /* No of root nodes */ + SR_PWR_DOMAINS_AT_MAX_PWR_LVL, + /* No of children for the root node */ + BRCM_CLUSTER_COUNT, + /* No of children for the first cluster node */ + PLATFORM_CLUSTER0_CORE_COUNT, + /* No of children for the second cluster node */ + PLATFORM_CLUSTER1_CORE_COUNT, + /* No of children for the third cluster node */ + PLATFORM_CLUSTER2_CORE_COUNT, + /* No of children for the fourth cluster node */ + PLATFORM_CLUSTER3_CORE_COUNT, +}; + +/******************************************************************************* + * This function returns the Stingray topology tree information. + ******************************************************************************/ +const unsigned char *plat_get_power_domain_tree_desc(void) +{ + return sr_power_domain_tree_desc; +} + +int plat_core_pos_by_mpidr(u_register_t mpidr) +{ + return plat_brcm_calc_core_pos(mpidr); +} diff --git a/plat/brcm/board/stingray/src/tz_sec.c b/plat/brcm/board/stingray/src/tz_sec.c new file mode 100644 index 000000000..07b12a7a2 --- /dev/null +++ b/plat/brcm/board/stingray/src/tz_sec.c @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2016 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include +#include + +/* + * Trust Zone controllers + */ +#define TZC400_FS_SRAM_ROOT 0x66d84000 + +/* + * TZPC Master configure registers + */ + +/* TZPC_TZPCDECPROT0set */ +#define TZPC0_MASTER_NS_BASE 0x68b40804 +#define TZPC0_SATA3_BIT 5 +#define TZPC0_SATA2_BIT 4 +#define TZPC0_SATA1_BIT 3 +#define TZPC0_SATA0_BIT 2 +#define TZPC0_USB3H1_BIT 1 +#define TZPC0_USB3H0_BIT 0 +#define TZPC0_MASTER_SEC_DEFAULT 0 + +/* TZPC_TZPCDECPROT1set */ +#define TZPC1_MASTER_NS_BASE 0x68b40810 +#define TZPC1_SDIO1_BIT 6 +#define TZPC1_SDIO0_BIT 5 +#define TZPC1_AUDIO0_BIT 4 +#define TZPC1_USB2D_BIT 3 +#define TZPC1_USB2H1_BIT 2 +#define TZPC1_USB2H0_BIT 1 +#define TZPC1_AMAC0_BIT 0 +#define TZPC1_MASTER_SEC_DEFAULT 0 + + +struct tz_sec_desc { + uintptr_t addr; + uint32_t val; +}; + +static const struct tz_sec_desc tz_master_defaults[] = { +{ TZPC0_MASTER_NS_BASE, TZPC0_MASTER_SEC_DEFAULT }, +{ TZPC1_MASTER_NS_BASE, TZPC1_MASTER_SEC_DEFAULT } +}; + +/* + * Initialize the TrustZone Controller for SRAM partitioning. + */ +static void bcm_tzc_setup(void) +{ + VERBOSE("Configuring SRAM TrustZone Controller\n"); + + /* Init the TZASC controller */ + tzc400_init(TZC400_FS_SRAM_ROOT); + + /* + * Close the entire SRAM space + * Region 0 covers the entire SRAM space + * None of the NS device can access it. + */ + tzc400_configure_region0(TZC_REGION_S_RDWR, 0); + + /* Do raise an exception if a NS device tries to access secure memory */ + tzc400_set_action(TZC_ACTION_ERR); +} + +/* + * Configure TZ Master as NS_MASTER or SECURE_MASTER + * To set a Master to non-secure, use *_SET registers + * To set a Master to secure, use *_CLR registers (set + 0x4 address) + */ +static void tz_master_set(uint32_t base, uint32_t value, uint32_t ns) +{ + if (ns == SECURE_MASTER) { + mmio_write_32(base + 4, value); + } else { + mmio_write_32(base, value); + } +} + +/* + * Initialize the secure environment for sdio. + */ +void plat_tz_sdio_ns_master_set(uint32_t ns) +{ + tz_master_set(TZPC1_MASTER_NS_BASE, + 1 << TZPC1_SDIO0_BIT, + ns); +} + +/* + * Initialize the secure environment for usb. + */ +void plat_tz_usb_ns_master_set(uint32_t ns) +{ + tz_master_set(TZPC1_MASTER_NS_BASE, + 1 << TZPC1_USB2H0_BIT, + ns); +} + +/* + * Set masters to default configuration. + * + * DMA security settings are programmed into the PL-330 controller and + * are not set by iProc TZPC registers. + * DMA always comes up as secure master (*NS bit is 0). + * + * Because the default reset values of TZPC are 0 (== Secure), + * ARM Verilog code makes all masters, including PCIe, come up as + * secure. + * However, SOTP has a bit called SOTP_ALLMASTER_NS that overrides + * TZPC and makes all masters non-secure for AB devices. + * + * Hence we first set all the TZPC bits to program all masters, + * including PCIe, as non-secure, then set the CLEAR_ALLMASTER_NS bit + * so that the SOTP_ALLMASTER_NS cannot override TZPC. + * now security settings for each masters come from TZPC + * (which makes all masters other than DMA as non-secure). + * + * During the boot, all masters other than DMA Ctrlr + list + * are non-secure in an AB Prod/AB Dev/AB Pending device. + * + */ +void plat_tz_master_default_cfg(void) +{ + int i; + + /* Configure default secure and non-secure TZ Masters */ + for (i = 0; i < ARRAY_SIZE(tz_master_defaults); i++) { + tz_master_set(tz_master_defaults[i].addr, + tz_master_defaults[i].val, + SECURE_MASTER); + tz_master_set(tz_master_defaults[i].addr, + ~tz_master_defaults[i].val, + NS_MASTER); + } + + /* Clear all master NS */ + mmio_setbits_32(SOTP_CHIP_CTRL, + 1 << SOTP_CLEAR_SYSCTRL_ALL_MASTER_NS); + + /* Initialize TZ controller and Set SRAM to secure */ + bcm_tzc_setup(); +} diff --git a/plat/brcm/common/brcm_bl31_setup.c b/plat/brcm/common/brcm_bl31_setup.c new file mode 100644 index 000000000..d3fa83da7 --- /dev/null +++ b/plat/brcm/common/brcm_bl31_setup.c @@ -0,0 +1,291 @@ +/* + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifdef BL33_SHARED_DDR_BASE +struct bl33_info *bl33_info = (struct bl33_info *)BL33_SHARED_DDR_BASE; +#endif + +/* + * Placeholder variables for copying the arguments that have been passed to + * BL31 from BL2. + */ +static entry_point_info_t bl32_image_ep_info; +static entry_point_info_t bl33_image_ep_info; + +/* Weak definitions may be overridden in specific BRCM platform */ +#pragma weak plat_bcm_bl31_early_platform_setup +#pragma weak plat_brcm_pwrc_setup +#pragma weak plat_brcm_security_setup + +void plat_brcm_security_setup(void) +{ + +} + +void plat_brcm_pwrc_setup(void) +{ + +} + +void plat_bcm_bl31_early_platform_setup(void *from_bl2, + bl_params_t *plat_params_from_bl2) +{ + +} + +/******************************************************************************* + * Return a pointer to the 'entry_point_info' structure of the next image for + * the security state specified. BL33 corresponds to the non-secure image type + * while BL32 corresponds to the secure image type. A NULL pointer is returned + * if the image does not exist. + ******************************************************************************/ +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; + /* + * None of the images on the ARM development platforms can have 0x0 + * as the entrypoint + */ + if (next_image_info->pc) + return next_image_info; + else + return NULL; +} + +/******************************************************************************* + * Perform any BL31 early platform setup common to ARM standard platforms. + * Here is an opportunity to copy parameters passed by the calling EL (S-EL1 + * in BL2 & EL3 in BL1) before they are lost (potentially). This needs to be + * done before the MMU is initialized so that the memory layout can be used + * while creating page tables. BL2 has flushed this information to memory, so + * we are guaranteed to pick up good data. + ******************************************************************************/ +void __init brcm_bl31_early_platform_setup(void *from_bl2, + uintptr_t soc_fw_config, + uintptr_t hw_config, + void *plat_params_from_bl2) +{ + /* Initialize the console to provide early debug support */ + bcm_console_boot_init(); + + /* Initialize delay timer driver using SP804 dual timer 0 */ + sp804_timer_init(SP804_TIMER0_BASE, + SP804_TIMER0_CLKMULT, SP804_TIMER0_CLKDIV); + +#if RESET_TO_BL31 + /* There are no parameters from BL2 if BL31 is a reset vector */ + assert(from_bl2 == NULL); + assert(plat_params_from_bl2 == NULL); + +# ifdef BL32_BASE + /* Populate entry point information for BL32 */ + SET_PARAM_HEAD(&bl32_image_ep_info, + PARAM_EP, + VERSION_1, + 0); + SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE); + bl32_image_ep_info.pc = BL32_BASE; + bl32_image_ep_info.spsr = brcm_get_spsr_for_bl32_entry(); +# endif /* BL32_BASE */ + + /* Populate entry point information for BL33 */ + SET_PARAM_HEAD(&bl33_image_ep_info, + PARAM_EP, + VERSION_1, + 0); + /* + * Tell BL31 where the non-trusted software image + * is located and the entry state information + */ + bl33_image_ep_info.pc = plat_get_ns_image_entrypoint(); + + bl33_image_ep_info.spsr = brcm_get_spsr_for_bl33_entry(); + SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); + +# if ARM_LINUX_KERNEL_AS_BL33 + /* + * According to the file ``Documentation/arm64/booting.txt`` of the + * 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. + */ + bl33_image_ep_info.args.arg0 = (u_register_t)PRELOADED_DTB_BASE; + bl33_image_ep_info.args.arg1 = 0U; + bl33_image_ep_info.args.arg2 = 0U; + bl33_image_ep_info.args.arg3 = 0U; +# endif + +#else /* RESET_TO_BL31 */ + + /* + * In debug builds, we pass a special value in 'plat_params_from_bl2' + * to verify platform parameters from BL2 to BL31. + * In release builds, it's not used. + */ + assert(((unsigned long long)plat_params_from_bl2) == + BRCM_BL31_PLAT_PARAM_VAL); + + /* + * Check params passed from BL2 should not be NULL + */ + bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2; + + assert(params_from_bl2 != NULL); + assert(params_from_bl2->h.type == PARAM_BL_PARAMS); + assert(params_from_bl2->h.version >= VERSION_2); + + bl_params_node_t *bl_params = params_from_bl2->head; + + /* + * Copy BL33 and BL32 (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 && + bl_params->image_info->h.attr != IMAGE_ATTRIB_SKIP_LOADING) + bl32_image_ep_info = *bl_params->ep_info; + + 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(); +#endif /* RESET_TO_BL31 */ + +#ifdef BL33_SHARED_DDR_BASE + /* Pass information to BL33 thorugh x0 */ + bl33_image_ep_info.args.arg0 = (u_register_t)BL33_SHARED_DDR_BASE; + bl33_image_ep_info.args.arg1 = 0ULL; + bl33_image_ep_info.args.arg2 = 0ULL; + bl33_image_ep_info.args.arg3 = 0ULL; +#endif +} + +void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, + u_register_t arg2, u_register_t arg3) +{ +#ifdef BL31_LOG_LEVEL + SET_LOG_LEVEL(BL31_LOG_LEVEL); +#endif + + brcm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3); + + plat_bcm_bl31_early_platform_setup((void *)arg0, (void *)arg3); + +#ifdef DRIVER_CC_ENABLE + /* + * Initialize Interconnect for this cluster during cold boot. + * No need for locks as no other CPU is active. + */ + plat_brcm_interconnect_init(); + + /* + * Enable Interconnect coherency for the primary CPU's cluster. + * Earlier bootloader stages might already do this (e.g. Trusted + * Firmware's BL1 does it) but we can't assume so. There is no harm in + * executing this code twice anyway. + * Platform specific PSCI code will enable coherency for other + * clusters. + */ + plat_brcm_interconnect_enter_coherency(); +#endif +} + +/******************************************************************************* + * Perform any BL31 platform setup common to ARM standard platforms + ******************************************************************************/ +void brcm_bl31_platform_setup(void) +{ + /* Initialize the GIC driver, cpu and distributor interfaces */ + plat_brcm_gic_driver_init(); + plat_brcm_gic_init(); + + /* Initialize power controller before setting up topology */ + plat_brcm_pwrc_setup(); +} + +/******************************************************************************* + * Perform any BL31 platform runtime setup prior to BL31 exit common to ARM + * standard platforms + * Perform BL31 platform setup + ******************************************************************************/ +void brcm_bl31_plat_runtime_setup(void) +{ + console_switch_state(CONSOLE_FLAG_RUNTIME); + + /* Initialize the runtime console */ + bcm_console_runtime_init(); +} + +void bl31_platform_setup(void) +{ + brcm_bl31_platform_setup(); + + /* Initialize the secure environment */ + plat_brcm_security_setup(); +} + +void bl31_plat_runtime_setup(void) +{ + brcm_bl31_plat_runtime_setup(); +} + +/******************************************************************************* + * Perform the very early platform specific architectural setup shared between + * ARM standard platforms. This only does basic initialization. Later + * architectural setup (bl31_arch_setup()) does not do anything platform + * specific. + ******************************************************************************/ +void __init brcm_bl31_plat_arch_setup(void) +{ +#ifndef MMU_DISABLED + const mmap_region_t bl_regions[] = { + MAP_REGION_FLAT(BL31_BASE, BL31_END - BL31_BASE, + MT_MEMORY | MT_RW | MT_SECURE), + MAP_REGION_FLAT(BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE, + MT_CODE | MT_SECURE), + MAP_REGION_FLAT(BL_RO_DATA_BASE, + BL_RO_DATA_END - BL_RO_DATA_BASE, + MT_RO_DATA | MT_SECURE), +#if USE_COHERENT_MEM + MAP_REGION_FLAT(BL_COHERENT_RAM_BASE, + BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE, + MT_DEVICE | MT_RW | MT_SECURE), +#endif + {0} + }; + + setup_page_tables(bl_regions, plat_brcm_get_mmap()); + + enable_mmu_el3(0); +#endif +} + +void __init bl31_plat_arch_setup(void) +{ + brcm_bl31_plat_arch_setup(); +} diff --git a/plat/brcm/common/brcm_ccn.c b/plat/brcm/common/brcm_ccn.c new file mode 100644 index 000000000..9396aaad2 --- /dev/null +++ b/plat/brcm/common/brcm_ccn.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include + +static const unsigned char master_to_rn_id_map[] = { + PLAT_BRCM_CLUSTER_TO_CCN_ID_MAP +}; + +static const ccn_desc_t bcm_ccn_desc = { + .periphbase = PLAT_BRCM_CCN_BASE, + .num_masters = ARRAY_SIZE(master_to_rn_id_map), + .master_to_rn_id_map = master_to_rn_id_map +}; + +void plat_brcm_interconnect_init(void) +{ + ccn_init(&bcm_ccn_desc); +} + +void plat_brcm_interconnect_enter_coherency(void) +{ + ccn_enter_snoop_dvm_domain(1 << MPIDR_AFFLVL1_VAL(read_mpidr_el1())); +} + +void plat_brcm_interconnect_exit_coherency(void) +{ + ccn_exit_snoop_dvm_domain(1 << MPIDR_AFFLVL1_VAL(read_mpidr_el1())); +} diff --git a/plat/brcm/common/brcm_gicv3.c b/plat/brcm/common/brcm_gicv3.c new file mode 100644 index 000000000..c4137c0c3 --- /dev/null +++ b/plat/brcm/common/brcm_gicv3.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include + +/* The GICv3 driver only needs to be initialized in EL3 */ +static uintptr_t brcm_rdistif_base_addrs[PLATFORM_CORE_COUNT]; + +static const interrupt_prop_t brcm_interrupt_props[] = { + /* G1S interrupts */ + PLAT_BRCM_G1S_IRQ_PROPS(INTR_GROUP1S), + /* G0 interrupts */ + PLAT_BRCM_G0_IRQ_PROPS(INTR_GROUP0) +}; + +/* + * MPIDR hashing function for translating MPIDRs read from GICR_TYPER register + * to core position. + * + * Calculating core position is dependent on MPIDR_EL1.MT bit. However, affinity + * values read from GICR_TYPER don't have an MT field. To reuse the same + * translation used for CPUs, we insert MT bit read from the PE's MPIDR into + * that read from GICR_TYPER. + * + * Assumptions: + * + * - All CPUs implemented in the system have MPIDR_EL1.MT bit set; + * - No CPUs implemented in the system use affinity level 3. + */ +static unsigned int brcm_gicv3_mpidr_hash(u_register_t mpidr) +{ + mpidr |= (read_mpidr_el1() & MPIDR_MT_MASK); + return plat_core_pos_by_mpidr(mpidr); +} + +static const gicv3_driver_data_t brcm_gic_data = { + .gicd_base = PLAT_BRCM_GICD_BASE, + .gicr_base = PLAT_BRCM_GICR_BASE, + .interrupt_props = brcm_interrupt_props, + .interrupt_props_num = ARRAY_SIZE(brcm_interrupt_props), + .rdistif_num = PLATFORM_CORE_COUNT, + .rdistif_base_addrs = brcm_rdistif_base_addrs, + .mpidr_to_core_pos = brcm_gicv3_mpidr_hash +}; + +void plat_brcm_gic_driver_init(void) +{ + /* TODO Check if this is required to be initialized here + * after getting initialized in EL3, should we re-init this here + * in S-EL1 + */ + gicv3_driver_init(&brcm_gic_data); +} + +void plat_brcm_gic_init(void) +{ + gicv3_distif_init(); + gicv3_rdistif_init(plat_my_core_pos()); + gicv3_cpuif_enable(plat_my_core_pos()); +} + +void plat_brcm_gic_cpuif_enable(void) +{ + gicv3_cpuif_enable(plat_my_core_pos()); +} + +void plat_brcm_gic_cpuif_disable(void) +{ + gicv3_cpuif_disable(plat_my_core_pos()); +} + +void plat_brcm_gic_pcpu_init(void) +{ + gicv3_rdistif_init(plat_my_core_pos()); +} + +void plat_brcm_gic_redistif_on(void) +{ + gicv3_rdistif_on(plat_my_core_pos()); +} + +void plat_brcm_gic_redistif_off(void) +{ + gicv3_rdistif_off(plat_my_core_pos()); +} diff --git a/plat/brcm/common/brcm_mhu.c b/plat/brcm/common/brcm_mhu.c new file mode 100644 index 000000000..56f44e0f2 --- /dev/null +++ b/plat/brcm/common/brcm_mhu.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include + +#include +#include + +#include "m0_ipc.h" + +#define PLAT_MHU_INTR_REG AP_TO_SCP_MAILBOX1 + +/* SCP MHU secure channel registers */ +#define SCP_INTR_S_STAT CRMU_IHOST_SW_PERSISTENT_REG11 +#define SCP_INTR_S_SET CRMU_IHOST_SW_PERSISTENT_REG11 +#define SCP_INTR_S_CLEAR CRMU_IHOST_SW_PERSISTENT_REG11 + +/* CPU MHU secure channel registers */ +#define CPU_INTR_S_STAT CRMU_IHOST_SW_PERSISTENT_REG10 +#define CPU_INTR_S_SET CRMU_IHOST_SW_PERSISTENT_REG10 +#define CPU_INTR_S_CLEAR CRMU_IHOST_SW_PERSISTENT_REG10 + +static DEFINE_BAKERY_LOCK(bcm_lock); + +/* + * Slot 31 is reserved because the MHU hardware uses this register bit to + * indicate a non-secure access attempt. The total number of available slots is + * therefore 31 [30:0]. + */ +#define MHU_MAX_SLOT_ID 30 + +void mhu_secure_message_start(unsigned int slot_id) +{ + int iter = 1000000; + + assert(slot_id <= MHU_MAX_SLOT_ID); + + bakery_lock_get(&bcm_lock); + /* Make sure any previous command has finished */ + do { + if (!(mmio_read_32(PLAT_BRCM_MHU_BASE + CPU_INTR_S_STAT) & + (1 << slot_id))) + break; + + udelay(1); + + } while (--iter); + + assert(iter != 0); +} + +void mhu_secure_message_send(unsigned int slot_id) +{ + uint32_t response, iter = 1000000; + + assert(slot_id <= MHU_MAX_SLOT_ID); + assert(!(mmio_read_32(PLAT_BRCM_MHU_BASE + CPU_INTR_S_STAT) & + (1 << slot_id))); + + /* Send command to SCP */ + mmio_setbits_32(PLAT_BRCM_MHU_BASE + CPU_INTR_S_SET, 1 << slot_id); + mmio_write_32(CRMU_MAIL_BOX0, MCU_IPC_MCU_CMD_SCPI); + mmio_write_32(PLAT_BRCM_MHU_BASE + PLAT_MHU_INTR_REG, 0x1); + + /* Wait until IPC transport acknowledges reception of SCP command */ + do { + response = mmio_read_32(CRMU_MAIL_BOX0); + if ((response & ~MCU_IPC_CMD_REPLY_MASK) == + (MCU_IPC_CMD_DONE_MASK | MCU_IPC_MCU_CMD_SCPI)) + break; + + udelay(1); + + } while (--iter); + + assert(iter != 0); +} + +uint32_t mhu_secure_message_wait(void) +{ + /* Wait for response from SCP */ + uint32_t response, iter = 1000000; + + do { + response = mmio_read_32(PLAT_BRCM_MHU_BASE + SCP_INTR_S_STAT); + if (!response) + break; + + udelay(1); + } while (--iter); + assert(iter != 0); + + return response; +} + +void mhu_secure_message_end(unsigned int slot_id) +{ + assert(slot_id <= MHU_MAX_SLOT_ID); + + /* + * Clear any response we got by writing one in the relevant slot bit to + * the CLEAR register + */ + mmio_clrbits_32(PLAT_BRCM_MHU_BASE + SCP_INTR_S_CLEAR, 1 << slot_id); + bakery_lock_release(&bcm_lock); +} + +void mhu_secure_init(void) +{ + bakery_lock_init(&bcm_lock); + + /* + * The STAT register resets to zero. Ensure it is in the expected state, + * as a stale or garbage value would make us think it's a message we've + * already sent. + */ + mmio_write_32(PLAT_BRCM_MHU_BASE + CPU_INTR_S_STAT, 0); + mmio_write_32(PLAT_BRCM_MHU_BASE + SCP_INTR_S_STAT, 0); +} + +void plat_brcm_pwrc_setup(void) +{ + mhu_secure_init(); +} diff --git a/plat/brcm/common/brcm_mhu.h b/plat/brcm/common/brcm_mhu.h new file mode 100644 index 000000000..6c89a34a6 --- /dev/null +++ b/plat/brcm/common/brcm_mhu.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef BRCM_MHU_H +#define BRCM_MHU_H + +#include + +void mhu_secure_message_start(unsigned int slot_id); +void mhu_secure_message_send(unsigned int slot_id); +uint32_t mhu_secure_message_wait(void); +void mhu_secure_message_end(unsigned int slot_id); + +void mhu_secure_init(void); + +#endif /* BRCM_MHU_H */ diff --git a/plat/brcm/common/brcm_scpi.c b/plat/brcm/common/brcm_scpi.c new file mode 100644 index 000000000..0a703cb90 --- /dev/null +++ b/plat/brcm/common/brcm_scpi.c @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#define SCPI_SHARED_MEM_SCP_TO_AP (PLAT_SCP_COM_SHARED_MEM_BASE) +#define SCPI_SHARED_MEM_AP_TO_SCP (PLAT_SCP_COM_SHARED_MEM_BASE \ + + 0x100) + +/* Header and payload addresses for commands from AP to SCP */ +#define SCPI_CMD_HEADER_AP_TO_SCP \ + ((scpi_cmd_t *) SCPI_SHARED_MEM_AP_TO_SCP) +#define SCPI_CMD_PAYLOAD_AP_TO_SCP \ + ((void *) (SCPI_SHARED_MEM_AP_TO_SCP + sizeof(scpi_cmd_t))) + +/* Header and payload addresses for responses from SCP to AP */ +#define SCPI_RES_HEADER_SCP_TO_AP \ + ((scpi_cmd_t *) SCPI_SHARED_MEM_SCP_TO_AP) +#define SCPI_RES_PAYLOAD_SCP_TO_AP \ + ((void *) (SCPI_SHARED_MEM_SCP_TO_AP + sizeof(scpi_cmd_t))) + +/* ID of the MHU slot used for the SCPI protocol */ +#define SCPI_MHU_SLOT_ID 0 + +static void scpi_secure_message_start(void) +{ + mhu_secure_message_start(SCPI_MHU_SLOT_ID); +} + +static void scpi_secure_message_send(size_t payload_size) +{ + /* + * Ensure that any write to the SCPI payload area is seen by SCP before + * we write to the MHU register. If these 2 writes were reordered by + * the CPU then SCP would read stale payload data + */ + dmbst(); + + mhu_secure_message_send(SCPI_MHU_SLOT_ID); +} + +static void scpi_secure_message_receive(scpi_cmd_t *cmd) +{ + uint32_t mhu_status; + + assert(cmd != NULL); + + mhu_status = mhu_secure_message_wait(); + + /* Expect an SCPI message, reject any other protocol */ + if (mhu_status != (1 << SCPI_MHU_SLOT_ID)) { + ERROR("MHU: Unexpected protocol (MHU status: 0x%x)\n", + mhu_status); + panic(); + } + + /* + * Ensure that any read to the SCPI payload area is done after reading + * the MHU register. If these 2 reads were reordered then the CPU would + * read invalid payload data + */ + dmbld(); + + memcpy(cmd, (void *) SCPI_SHARED_MEM_SCP_TO_AP, sizeof(*cmd)); +} + +static void scpi_secure_message_end(void) +{ + mhu_secure_message_end(SCPI_MHU_SLOT_ID); +} + +int scpi_wait_ready(void) +{ + scpi_cmd_t scpi_cmd; + + VERBOSE("Waiting for SCP_READY command...\n"); + + /* Get a message from the SCP */ + scpi_secure_message_start(); + scpi_secure_message_receive(&scpi_cmd); + scpi_secure_message_end(); + + /* We are expecting 'SCP Ready', produce correct error if it's not */ + scpi_status_t status = SCP_OK; + + if (scpi_cmd.id != SCPI_CMD_SCP_READY) { + ERROR("Unexpected SCP command: expected #%u, received #%u\n", + SCPI_CMD_SCP_READY, scpi_cmd.id); + status = SCP_E_SUPPORT; + } else if (scpi_cmd.size != 0) { + ERROR("SCP_READY cmd has incorrect size: expected 0, got %u\n", + scpi_cmd.size); + status = SCP_E_SIZE; + } + + VERBOSE("Sending response for SCP_READY command\n"); + + /* + * Send our response back to SCP. + * We are using the same SCPI header, just update the status field. + */ + scpi_cmd.status = status; + scpi_secure_message_start(); + memcpy((void *) SCPI_SHARED_MEM_AP_TO_SCP, &scpi_cmd, sizeof(scpi_cmd)); + scpi_secure_message_send(0); + scpi_secure_message_end(); + + return status == SCP_OK ? 0 : -1; +} + +void scpi_set_brcm_power_state(unsigned int mpidr, + scpi_power_state_t cpu_state, scpi_power_state_t cluster_state, + scpi_power_state_t brcm_state) +{ + scpi_cmd_t *cmd; + uint32_t state = 0; + uint32_t *payload_addr; + +#if ARM_PLAT_MT + /* + * The current SCPI driver only caters for single-threaded platforms. + * Hence we ignore the thread ID (which is always 0) for such platforms. + */ + state |= (mpidr >> MPIDR_AFF1_SHIFT) & 0x0f; /* CPU ID */ + state |= ((mpidr >> MPIDR_AFF2_SHIFT) & 0x0f) << 4; /* Cluster ID */ +#else + state |= mpidr & 0x0f; /* CPU ID */ + state |= (mpidr & 0xf00) >> 4; /* Cluster ID */ +#endif /* ARM_PLAT_MT */ + + state |= cpu_state << 8; + state |= cluster_state << 12; + state |= brcm_state << 16; + + scpi_secure_message_start(); + + /* Populate the command header */ + cmd = SCPI_CMD_HEADER_AP_TO_SCP; + cmd->id = SCPI_CMD_SET_POWER_STATE; + cmd->set = SCPI_SET_NORMAL; + cmd->sender = 0; + cmd->size = sizeof(state); + /* Populate the command payload */ + payload_addr = SCPI_CMD_PAYLOAD_AP_TO_SCP; + *payload_addr = state; + scpi_secure_message_send(sizeof(state)); + + /* + * SCP does not reply to this command in order to avoid MHU interrupts + * from the sender, which could interfere with its power state request. + */ + scpi_secure_message_end(); +} + +/* + * Query and obtain power state from SCP. + * + * In response to the query, SCP returns power states of all CPUs in all + * clusters of the system. The returned response is then filtered based on the + * supplied MPIDR. Power states of requested cluster and CPUs within are updated + * via. supplied non-NULL pointer arguments. + * + * Returns 0 on success, or -1 on errors. + */ +int scpi_get_brcm_power_state(unsigned int mpidr, unsigned int *cpu_state_p, + unsigned int *cluster_state_p) +{ + scpi_cmd_t *cmd; + scpi_cmd_t response; + int power_state, cpu, cluster, rc = -1; + + /* + * Extract CPU and cluster membership of the given MPIDR. SCPI caters + * for only up to 0xf clusters, and 8 CPUs per cluster + */ + cpu = mpidr & MPIDR_AFFLVL_MASK; + cluster = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK; + if (cpu >= 8 || cluster >= 0xf) + return -1; + + scpi_secure_message_start(); + + /* Populate request headers */ + zeromem(SCPI_CMD_HEADER_AP_TO_SCP, sizeof(*cmd)); + cmd = SCPI_CMD_HEADER_AP_TO_SCP; + cmd->id = SCPI_CMD_GET_POWER_STATE; + + /* + * Send message and wait for SCP's response + */ + scpi_secure_message_send(0); + scpi_secure_message_receive(&response); + + if (response.status != SCP_OK) + goto exit; + + /* Validate SCP response */ + if (!CHECK_RESPONSE(response, cluster)) + goto exit; + + /* Extract power states for required cluster */ + power_state = *(((uint16_t *) SCPI_RES_PAYLOAD_SCP_TO_AP) + cluster); + if (CLUSTER_ID(power_state) != cluster) + goto exit; + + /* Update power state via. pointers */ + if (cluster_state_p) + *cluster_state_p = CLUSTER_POWER_STATE(power_state); + if (cpu_state_p) + *cpu_state_p = CPU_POWER_STATE(power_state); + rc = 0; + +exit: + scpi_secure_message_end(); + return rc; +} + +uint32_t scpi_sys_power_state(scpi_system_state_t system_state) +{ + scpi_cmd_t *cmd; + uint8_t *payload_addr; + + scpi_secure_message_start(); + + /* Populate the command header */ + cmd = SCPI_CMD_HEADER_AP_TO_SCP; + cmd->id = SCPI_CMD_SYS_POWER_STATE; + cmd->set = 0; + cmd->sender = 0; + cmd->size = sizeof(*payload_addr); + /* Populate the command payload */ + payload_addr = SCPI_CMD_PAYLOAD_AP_TO_SCP; + *payload_addr = system_state & 0xff; + scpi_secure_message_send(sizeof(*payload_addr)); + + scpi_secure_message_end(); + + return SCP_OK; +} diff --git a/plat/brcm/common/brcm_scpi.h b/plat/brcm/common/brcm_scpi.h new file mode 100644 index 000000000..f3b658f62 --- /dev/null +++ b/plat/brcm/common/brcm_scpi.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef BRCM_SCPI_H +#define BRCM_SCPI_H + +#include +#include + +/* + * An SCPI command consists of a header and a payload. + * The following structure describes the header. It is 64-bit long. + */ +typedef struct { + /* Command ID */ + uint32_t id : 7; + /* Set ID. Identifies whether this is a standard or extended command. */ + uint32_t set : 1; + /* Sender ID to match a reply. The value is sender specific. */ + uint32_t sender : 8; + /* Size of the payload in bytes (0 - 511) */ + uint32_t size : 9; + uint32_t reserved : 7; + /* + * Status indicating the success of a command. + * See the enum below. + */ + uint32_t status; +} scpi_cmd_t; + +typedef enum { + SCPI_SET_NORMAL = 0, /* Normal SCPI commands */ + SCPI_SET_EXTENDED /* Extended SCPI commands */ +} scpi_set_t; + +enum { + SCP_OK = 0, /* Success */ + SCP_E_PARAM, /* Invalid parameter(s) */ + SCP_E_ALIGN, /* Invalid alignment */ + SCP_E_SIZE, /* Invalid size */ + SCP_E_HANDLER, /* Invalid handler or callback */ + SCP_E_ACCESS, /* Invalid access or permission denied */ + SCP_E_RANGE, /* Value out of range */ + SCP_E_TIMEOUT, /* Time out has ocurred */ + SCP_E_NOMEM, /* Invalid memory area or pointer */ + SCP_E_PWRSTATE, /* Invalid power state */ + SCP_E_SUPPORT, /* Feature not supported or disabled */ + SCPI_E_DEVICE, /* Device error */ + SCPI_E_BUSY, /* Device is busy */ +}; + +typedef uint32_t scpi_status_t; +typedef enum { + SCPI_CMD_SCP_READY = 0x01, + SCPI_CMD_SET_POWER_STATE = 0x03, + SCPI_CMD_GET_POWER_STATE = 0x04, + SCPI_CMD_SYS_POWER_STATE = 0x05 +} scpi_command_t; + +/* + * Macros to parse SCP response to GET_POWER_STATE command + * + * [3:0] : cluster ID + * [7:4] : cluster state: 0 = on; 3 = off; rest are reserved + * [15:8]: on/off state for individual CPUs in the cluster + * + * Payload is in little-endian + */ +#define CLUSTER_ID(_resp) ((_resp) & 0xf) +#define CLUSTER_POWER_STATE(_resp) (((_resp) >> 4) & 0xf) + +/* Result is a bit mask of CPU on/off states in the cluster */ +#define CPU_POWER_STATE(_resp) (((_resp) >> 8) & 0xff) + +/* + * For GET_POWER_STATE, SCP returns the power states of every cluster. The + * size of response depends on the number of clusters in the system. The + * SCP-to-AP payload contains 2 bytes per cluster. Make sure the response is + * large enough to contain power states of a given cluster + */ +#define CHECK_RESPONSE(_resp, _clus) (_resp.size >= (((_clus) + 1) * 2)) + +typedef enum { + scpi_power_on = 0, + scpi_power_retention = 1, + scpi_power_off = 3, +} scpi_power_state_t; + +typedef enum { + scpi_system_shutdown = 0, + scpi_system_reboot = 1, + scpi_system_reset = 2 +} scpi_system_state_t; + +extern int scpi_wait_ready(void); +extern void scpi_set_brcm_power_state(unsigned int mpidr, + scpi_power_state_t cpu_state, + scpi_power_state_t cluster_state, + scpi_power_state_t css_state); +int scpi_get_brcm_power_state(unsigned int mpidr, unsigned int *cpu_state_p, + unsigned int *cluster_state_p); +uint32_t scpi_sys_power_state(scpi_system_state_t system_state); + +#endif /* BRCM_SCPI_H */ -- cgit v1.2.3 From f29d1e0c72e6665ba4c8ab11bad83f59669ea0d9 Mon Sep 17 00:00:00 2001 From: Sheetal Tigadoli Date: Wed, 18 Dec 2019 19:44:43 +0530 Subject: Add BL2 support for Broadcom stingray platform Change-Id: I5daa3f2b4b9d85cb857547a588571a9aa8ad05c2 Signed-off-by: Sheetal Tigadoli --- drivers/brcm/iproc_gpio.c | 232 +++++++ drivers/brcm/ocotp.c | 204 ++++++ drivers/brcm/scp.c | 100 +++ drivers/brcm/sotp.c | 323 +++++++++ include/drivers/brcm/chimp.h | 94 +++ include/drivers/brcm/fru.h | 144 ++++ include/drivers/brcm/iproc_gpio.h | 20 + include/drivers/brcm/ocotp.h | 27 + include/drivers/brcm/scp.h | 14 + include/drivers/brcm/sotp.h | 71 ++ include/plat/brcm/common/bcm_elog.h | 38 ++ plat/brcm/board/common/bcm_elog.c | 268 ++++++++ plat/brcm/board/common/bcm_elog_ddr.c | 133 ++++ plat/brcm/board/common/bcm_elog_ddr.h | 107 +++ plat/brcm/board/common/board_arm_trusted_boot.c | 624 +++++++++++++++++ plat/brcm/board/common/board_common.mk | 120 ++++ plat/brcm/board/common/brcm_mbedtls.c | 12 + plat/brcm/board/common/chip_id.h | 37 + plat/brcm/board/common/cmn_plat_def.h | 50 ++ plat/brcm/board/common/platform_common.c | 55 +- plat/brcm/board/common/sbl_util.c | 40 ++ plat/brcm/board/common/sbl_util.h | 19 + plat/brcm/board/stingray/bcm958742t-ns3.mk | 6 + .../stingray/driver/ddr/soc/include/board_family.h | 33 + .../stingray/driver/ext_sram_init/ext_sram_init.c | 302 +++++++++ .../stingray/driver/ext_sram_init/ext_sram_init.h | 11 + plat/brcm/board/stingray/driver/swreg.c | 375 +++++++++++ plat/brcm/board/stingray/include/board_info.h | 38 ++ plat/brcm/board/stingray/include/ddr_init.h | 39 ++ plat/brcm/board/stingray/include/platform_def.h | 4 +- plat/brcm/board/stingray/include/platform_sotp.h | 36 + plat/brcm/board/stingray/include/scp_cmd.h | 25 + plat/brcm/board/stingray/include/scp_utils.h | 34 + plat/brcm/board/stingray/include/sr_utils.h | 42 ++ plat/brcm/board/stingray/include/swreg.h | 36 + plat/brcm/board/stingray/platform.mk | 73 ++ plat/brcm/board/stingray/src/bl2_setup.c | 742 +++++++++++++++++++++ plat/brcm/board/stingray/src/scp_cmd.c | 60 ++ plat/brcm/board/stingray/src/scp_utils.c | 227 +++++++ 39 files changed, 4810 insertions(+), 5 deletions(-) create mode 100644 drivers/brcm/iproc_gpio.c create mode 100644 drivers/brcm/ocotp.c create mode 100644 drivers/brcm/scp.c create mode 100644 drivers/brcm/sotp.c create mode 100644 include/drivers/brcm/chimp.h create mode 100644 include/drivers/brcm/fru.h create mode 100644 include/drivers/brcm/iproc_gpio.h create mode 100644 include/drivers/brcm/ocotp.h create mode 100644 include/drivers/brcm/scp.h create mode 100644 include/drivers/brcm/sotp.h create mode 100644 include/plat/brcm/common/bcm_elog.h create mode 100644 plat/brcm/board/common/bcm_elog.c create mode 100644 plat/brcm/board/common/bcm_elog_ddr.c create mode 100644 plat/brcm/board/common/bcm_elog_ddr.h create mode 100644 plat/brcm/board/common/board_arm_trusted_boot.c create mode 100644 plat/brcm/board/common/brcm_mbedtls.c create mode 100644 plat/brcm/board/common/chip_id.h create mode 100644 plat/brcm/board/common/sbl_util.c create mode 100644 plat/brcm/board/common/sbl_util.h create mode 100644 plat/brcm/board/stingray/driver/ddr/soc/include/board_family.h create mode 100644 plat/brcm/board/stingray/driver/ext_sram_init/ext_sram_init.c create mode 100644 plat/brcm/board/stingray/driver/ext_sram_init/ext_sram_init.h create mode 100644 plat/brcm/board/stingray/driver/swreg.c create mode 100644 plat/brcm/board/stingray/include/board_info.h create mode 100644 plat/brcm/board/stingray/include/ddr_init.h create mode 100644 plat/brcm/board/stingray/include/platform_sotp.h create mode 100644 plat/brcm/board/stingray/include/scp_cmd.h create mode 100644 plat/brcm/board/stingray/include/scp_utils.h create mode 100644 plat/brcm/board/stingray/include/sr_utils.h create mode 100644 plat/brcm/board/stingray/include/swreg.h create mode 100644 plat/brcm/board/stingray/src/bl2_setup.c create mode 100644 plat/brcm/board/stingray/src/scp_cmd.c create mode 100644 plat/brcm/board/stingray/src/scp_utils.c diff --git a/drivers/brcm/iproc_gpio.c b/drivers/brcm/iproc_gpio.c new file mode 100644 index 000000000..f61a3bca7 --- /dev/null +++ b/drivers/brcm/iproc_gpio.c @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2019-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include + +#include +#include + +#define IPROC_GPIO_DATA_IN_OFFSET 0x00 +#define IPROC_GPIO_DATA_OUT_OFFSET 0x04 +#define IPROC_GPIO_OUT_EN_OFFSET 0x08 +#define IPROC_GPIO_PAD_RES_OFFSET 0x34 +#define IPROC_GPIO_RES_EN_OFFSET 0x38 + +#define PINMUX_OFFSET(gpio) ((gpio) * 4) +#define PINCONF_OFFSET(gpio) ((gpio) * 4) +#define PINCONF_PULL_UP BIT(4) +#define PINCONF_PULL_DOWN BIT(5) + +/* + * iProc GPIO bank is always 0x200 per bank, + * with each bank supporting 32 GPIOs. + */ +#define GPIO_BANK_SIZE 0x200 +#define NGPIOS_PER_BANK 32 +#define GPIO_BANK(pin) ((pin) / NGPIOS_PER_BANK) + +#define IPROC_GPIO_REG(pin, reg) (GPIO_BANK(pin) * GPIO_BANK_SIZE + (reg)) +#define IPROC_GPIO_SHIFT(pin) ((pin) % NGPIOS_PER_BANK) + +#define MUX_GPIO_MODE 0x3 + +/* + * @base: base address of the gpio controller + * @pinconf_base: base address of the pinconf + * @pinmux_base: base address of the mux controller + * @nr_gpios: maxinum number of GPIOs + */ +struct iproc_gpio { + uintptr_t base; + uintptr_t pinconf_base; + uintptr_t pinmux_base; + int nr_gpios; +}; + +static struct iproc_gpio iproc_gpio; + +static void gpio_set_bit(uintptr_t base, unsigned int reg, int gpio, bool set) +{ + unsigned int offset = IPROC_GPIO_REG(gpio, reg); + unsigned int shift = IPROC_GPIO_SHIFT(gpio); + uint32_t val; + + val = mmio_read_32(base + offset); + if (set) + val |= BIT(shift); + else + val &= ~BIT(shift); + + mmio_write_32(base + offset, val); +} + +static bool gpio_get_bit(uintptr_t base, unsigned int reg, int gpio) +{ + unsigned int offset = IPROC_GPIO_REG(gpio, reg); + unsigned int shift = IPROC_GPIO_SHIFT(gpio); + + return !!(mmio_read_32(base + offset) & BIT(shift)); +} + +static void mux_to_gpio(struct iproc_gpio *g, int gpio) +{ + /* mux pad to GPIO if IOPAD configuration is mandatory */ + if (g->pinmux_base) + mmio_write_32(g->pinmux_base + PINMUX_OFFSET(gpio), + MUX_GPIO_MODE); +} + +static void set_direction(int gpio, int direction) +{ + struct iproc_gpio *g = &iproc_gpio; + bool dir = (direction == GPIO_DIR_OUT) ? true : false; + + assert(gpio < g->nr_gpios); + + mux_to_gpio(g, gpio); + gpio_set_bit(g->base, IPROC_GPIO_OUT_EN_OFFSET, gpio, dir); +} + +static int get_direction(int gpio) +{ + struct iproc_gpio *g = &iproc_gpio; + int dir; + + assert(gpio < g->nr_gpios); + + mux_to_gpio(g, gpio); + dir = gpio_get_bit(g->base, IPROC_GPIO_OUT_EN_OFFSET, gpio) ? + GPIO_DIR_OUT : GPIO_DIR_IN; + + return dir; +} + +static int get_value(int gpio) +{ + struct iproc_gpio *g = &iproc_gpio; + unsigned int offset; + + assert(gpio < g->nr_gpios); + + mux_to_gpio(g, gpio); + + /* + * If GPIO is configured as output, read from the GPIO_OUT register; + * otherwise, read from the GPIO_IN register + */ + offset = gpio_get_bit(g->base, IPROC_GPIO_OUT_EN_OFFSET, gpio) ? + IPROC_GPIO_DATA_OUT_OFFSET : IPROC_GPIO_DATA_IN_OFFSET; + + return gpio_get_bit(g->base, offset, gpio); +} + +static void set_value(int gpio, int val) +{ + struct iproc_gpio *g = &iproc_gpio; + + assert(gpio < g->nr_gpios); + + mux_to_gpio(g, gpio); + + /* make sure GPIO is configured to output, and then set the value */ + gpio_set_bit(g->base, IPROC_GPIO_OUT_EN_OFFSET, gpio, true); + gpio_set_bit(g->base, IPROC_GPIO_DATA_OUT_OFFSET, gpio, !!(val)); +} + +static int get_pull(int gpio) +{ + struct iproc_gpio *g = &iproc_gpio; + uint32_t val; + + assert(gpio < g->nr_gpios); + mux_to_gpio(g, gpio); + + /* when there's a valid pinconf_base, use it */ + if (g->pinconf_base) { + val = mmio_read_32(g->pinconf_base + PINCONF_OFFSET(gpio)); + + if (val & PINCONF_PULL_UP) + return GPIO_PULL_UP; + else if (val & PINCONF_PULL_DOWN) + return GPIO_PULL_DOWN; + else + return GPIO_PULL_NONE; + } + + /* no pinconf_base. fall back to GPIO internal pull control */ + if (!gpio_get_bit(g->base, IPROC_GPIO_RES_EN_OFFSET, gpio)) + return GPIO_PULL_NONE; + + return gpio_get_bit(g->base, IPROC_GPIO_PAD_RES_OFFSET, gpio) ? + GPIO_PULL_UP : GPIO_PULL_DOWN; +} + +static void set_pull(int gpio, int pull) +{ + struct iproc_gpio *g = &iproc_gpio; + uint32_t val; + + assert(gpio < g->nr_gpios); + mux_to_gpio(g, gpio); + + /* when there's a valid pinconf_base, use it */ + if (g->pinconf_base) { + val = mmio_read_32(g->pinconf_base + PINCONF_OFFSET(gpio)); + + if (pull == GPIO_PULL_NONE) { + val &= ~(PINCONF_PULL_UP | PINCONF_PULL_DOWN); + } else if (pull == GPIO_PULL_UP) { + val |= PINCONF_PULL_UP; + val &= ~PINCONF_PULL_DOWN; + } else if (pull == GPIO_PULL_DOWN) { + val |= PINCONF_PULL_DOWN; + val &= ~PINCONF_PULL_UP; + } else { + return; + } + mmio_write_32(g->pinconf_base + PINCONF_OFFSET(gpio), val); + } + + /* no pinconf_base. fall back to GPIO internal pull control */ + if (pull == GPIO_PULL_NONE) { + gpio_set_bit(g->base, IPROC_GPIO_RES_EN_OFFSET, gpio, false); + return; + } + + /* enable pad register and pull up or down */ + gpio_set_bit(g->base, IPROC_GPIO_RES_EN_OFFSET, gpio, true); + gpio_set_bit(g->base, IPROC_GPIO_PAD_RES_OFFSET, gpio, + !!(pull == GPIO_PULL_UP)); +} + +const gpio_ops_t iproc_gpio_ops = { + .get_direction = get_direction, + .set_direction = set_direction, + .get_value = get_value, + .set_value = set_value, + .get_pull = get_pull, + .set_pull = set_pull, +}; + +void iproc_gpio_init(uintptr_t base, int nr_gpios, uintptr_t pinmux_base, + uintptr_t pinconf_base) +{ + iproc_gpio.base = base; + iproc_gpio.nr_gpios = nr_gpios; + + /* pinmux/pinconf base is optional for some SoCs */ + if (pinmux_base) + iproc_gpio.pinmux_base = pinmux_base; + + if (pinconf_base) + iproc_gpio.pinconf_base = pinconf_base; + + gpio_init(&iproc_gpio_ops); +} diff --git a/drivers/brcm/ocotp.c b/drivers/brcm/ocotp.c new file mode 100644 index 000000000..6ff855453 --- /dev/null +++ b/drivers/brcm/ocotp.c @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2017 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include + +#include +#include + +#define OTP_MAP 2 +#define OTP_NUM_WORDS 2048 +/* + * # of tries for OTP Status. The time to execute a command varies. The slowest + * commands are writes which also vary based on the # of bits turned on. Writing + * 0xffffffff takes ~3800 us. + */ +#define OTPC_RETRIES_US 5000 + +/* Sequence to enable OTP program */ +#define OTPC_PROG_EN_SEQ { 0xf, 0x4, 0x8, 0xd } + +/* OTPC Commands */ +#define OTPC_CMD_READ 0x0 +#define OTPC_CMD_OTP_PROG_ENABLE 0x2 +#define OTPC_CMD_OTP_PROG_DISABLE 0x3 +#define OTPC_CMD_PROGRAM 0x8 +#define OTPC_CMD_ECC 0x10 +#define OTPC_ECC_ADDR 0x1A +#define OTPC_ECC_VAL 0x00EC0000 + +/* OTPC Status Bits */ +#define OTPC_STAT_CMD_DONE BIT(1) +#define OTPC_STAT_PROG_OK BIT(2) + +/* OTPC register definition */ +#define OTPC_MODE_REG_OFFSET 0x0 +#define OTPC_MODE_REG_OTPC_MODE 0 +#define OTPC_COMMAND_OFFSET 0x4 +#define OTPC_COMMAND_COMMAND_WIDTH 6 +#define OTPC_CMD_START_OFFSET 0x8 +#define OTPC_CMD_START_START 0 +#define OTPC_CPU_STATUS_OFFSET 0xc +#define OTPC_CPUADDR_REG_OFFSET 0x28 +#define OTPC_CPUADDR_REG_OTPC_CPU_ADDRESS_WIDTH 16 +#define OTPC_CPU_WRITE_REG_OFFSET 0x2c + +#define OTPC_CMD_MASK (BIT(OTPC_COMMAND_COMMAND_WIDTH) - 1) +#define OTPC_ADDR_MASK (BIT(OTPC_CPUADDR_REG_OTPC_CPU_ADDRESS_WIDTH) - 1) + +#define OTPC_MODE_REG OCOTP_REGS_BASE + +struct chip_otp_cfg { + uint32_t base; + uint32_t num_words; +}; + +struct chip_otp_cfg ocotp_cfg = { + .base = OTPC_MODE_REG, + .num_words = 2048, +}; + +struct otpc_priv { + uint32_t base; + struct otpc_map *map; + int size; + int state; +}; + +struct otpc_priv otpc_info; + +static inline void set_command(uint32_t base, uint32_t command) +{ + mmio_write_32(base + OTPC_COMMAND_OFFSET, command & OTPC_CMD_MASK); +} + +static inline void set_cpu_address(uint32_t base, uint32_t addr) +{ + mmio_write_32(base + OTPC_CPUADDR_REG_OFFSET, addr & OTPC_ADDR_MASK); +} + +static inline void set_start_bit(uint32_t base) +{ + mmio_write_32(base + OTPC_CMD_START_OFFSET, 1 << OTPC_CMD_START_START); +} + +static inline void reset_start_bit(uint32_t base) +{ + mmio_write_32(base + OTPC_CMD_START_OFFSET, 0); +} + +static inline void write_cpu_data(uint32_t base, uint32_t value) +{ + mmio_write_32(base + OTPC_CPU_WRITE_REG_OFFSET, value); +} + +static int poll_cpu_status(uint32_t base, uint32_t value) +{ + uint32_t status; + uint32_t retries; + + for (retries = 0; retries < OTPC_RETRIES_US; retries++) { + status = mmio_read_32(base + OTPC_CPU_STATUS_OFFSET); + if (status & value) + break; + udelay(1); + } + if (retries == OTPC_RETRIES_US) + return -1; + + return 0; +} + +static int bcm_otpc_ecc(uint32_t enable) +{ + struct otpc_priv *priv = &otpc_info; + int ret; + + set_command(priv->base, OTPC_CMD_ECC); + set_cpu_address(priv->base, OTPC_ECC_ADDR); + + if (!enable) + write_cpu_data(priv->base, OTPC_ECC_VAL); + else + write_cpu_data(priv->base, ~OTPC_ECC_VAL); + + set_start_bit(priv->base); + ret = poll_cpu_status(priv->base, OTPC_STAT_CMD_DONE); + if (ret) { + ERROR("otp ecc op error: 0x%x", ret); + return -1; + } + reset_start_bit(priv->base); + + return 0; +} + +/* + * bcm_otpc_read read otp data in the size of 8 byte rows. + * bytes has to be the multiple of 8. + * return -1 in error case, return read bytes in success. + */ +int bcm_otpc_read(unsigned int offset, void *val, uint32_t bytes, + uint32_t ecc_flag) +{ + struct otpc_priv *priv = &otpc_info; + uint32_t *buf = val; + uint32_t bytes_read; + uint32_t address = offset / priv->map->word_size; + int i, ret; + + if (!priv->state) { + ERROR("OCOTP read failed\n"); + return -1; + } + + bcm_otpc_ecc(ecc_flag); + + for (bytes_read = 0; (bytes_read + priv->map->word_size) <= bytes;) { + set_command(priv->base, OTPC_CMD_READ); + set_cpu_address(priv->base, address++); + set_start_bit(priv->base); + ret = poll_cpu_status(priv->base, OTPC_STAT_CMD_DONE); + if (ret) { + ERROR("otp read error: 0x%x", ret); + return -1; + } + + for (i = 0; i < priv->map->otpc_row_size; i++) { + *buf++ = mmio_read_32(priv->base + + priv->map->data_r_offset[i]); + bytes_read += sizeof(*buf); + } + + reset_start_bit(priv->base); + } + + return bytes_read; +} + +int bcm_otpc_init(struct otpc_map *map) +{ + struct otpc_priv *priv; + + priv = &otpc_info; + priv->base = ocotp_cfg.base; + priv->map = map; + + priv->size = 4 * ocotp_cfg.num_words; + + /* Enable CPU access to OTPC. */ + mmio_setbits_32(priv->base + OTPC_MODE_REG_OFFSET, + BIT(OTPC_MODE_REG_OTPC_MODE)); + reset_start_bit(priv->base); + priv->state = 1; + VERBOSE("OTPC Initialization done\n"); + + return 0; +} diff --git a/drivers/brcm/scp.c b/drivers/brcm/scp.c new file mode 100644 index 000000000..61960735a --- /dev/null +++ b/drivers/brcm/scp.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2017 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include + +/* MCU binary image structure:
+ * + * Header structure: + * + * + * { }* + * + * + * MCU data () consists of several sections of code/data, to be + * installed (copied) into MCU memories. + * Header (
) gives information about sections contained in . + * + * The installer code iterates over sections in MCU binary. + * For each section, it copies the section into MCU memory. + * + * The header contains: + * - - 32-bit magic number to mark header start + * - - number of sections in + * - tuples. Each tuple describes a section. + * A tuple contains three 32-bit words. + * - - 32-bit magic number to mark header end + * + * Each section is describes by a tuple, consisting of three 32-bit words: + * - offset of section within MCU binary (relative to beginning of ) + * - section size (in bytes) in MCU binary + * - target address (in MCU memory). Section is copied to this location. + * + * All fields are 32-bit unsigned integers in little endian format. + * All sizes are assumed to be 32-bit aligned. + */ + +#define SCP_BIN_HEADER_MAGIC_START 0xfa587D01 +#define SCP_BIN_HEADER_MAGIC_END 0xf3e06a85 + +int download_scp_patch(void *image, unsigned int image_size) +{ + unsigned int *pheader = (unsigned int *)(image); + unsigned int header_size; + unsigned char *pdata; + void *dest; + unsigned int num_sections; + unsigned int section_src_offset; + unsigned int section_size; + + if (pheader && (pheader[0] != SCP_BIN_HEADER_MAGIC_START)) { + ERROR("SCP: Could not find SCP header.\n"); + return -1; + } + + num_sections = pheader[1]; + INFO("...Number of sections: %d\n", num_sections); + header_size = 4 * (1 + 1 + 3 * num_sections + 1); + + if (image_size < header_size) { + ERROR("SCP: Wrong size.\n"); + return -1; + } + + if (*(pheader + header_size/4 - 1) != SCP_BIN_HEADER_MAGIC_END) { + ERROR("SCP: Could not find SCP footer.\n"); + return -1; + } + + VERBOSE("SCP image header validated successfully\n"); + pdata = (unsigned char *)pheader + header_size; + + for (pheader += 2; num_sections > 0; num_sections--) { + + section_src_offset = pheader[0]; + section_size = pheader[1]; + dest = (void *)(unsigned long)pheader[2]; + + INFO("section: src:0x%x, size:%d, dst:0x%x\n", + section_src_offset, section_size, pheader[2]); + + if ((section_src_offset + section_size) > image_size) { + ERROR("SCP: Section points to outside of patch.\n"); + return -1; + } + + /* copy from source to target section */ + memcpy(dest, pdata + section_src_offset, section_size); + flush_dcache_range((uintptr_t)dest, section_size); + + /* next section */ + pheader += 3; + } + return 0; +} diff --git a/drivers/brcm/sotp.c b/drivers/brcm/sotp.c new file mode 100644 index 000000000..63c482066 --- /dev/null +++ b/drivers/brcm/sotp.c @@ -0,0 +1,323 @@ +/* + * Copyright (c) 2016-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include + +#include +#include + +#ifdef USE_SOFT_SOTP +extern uint64_t soft_sotp[]; +#endif + +#define SOTP_PROG_CONTROL (SOTP_REGS_OTP_BASE + 0x0000) +#define SOTP_PROG_CONTROL__OTP_CPU_MODE_EN 15 +#define SOTP_PROG_CONTROL__OTP_DISABLE_ECC 9 +#define SOTP_PROG_CONTROL__OTP_ECC_WREN 8 + +#define SOTP_WRDATA_0 (SOTP_REGS_OTP_BASE + 0x0004) +#define SOTP_WRDATA_1 (SOTP_REGS_OTP_BASE + 0x0008) + +#define SOTP_ADDR (SOTP_REGS_OTP_BASE + 0x000c) +#define SOTP_ADDR__OTP_ROW_ADDR_R 6 +#define SOTP_ADDR_MASK 0x3FF + +#define SOTP_CTRL_0 (SOTP_REGS_OTP_BASE + 0x0010) +#define SOTP_CTRL_0__START 0 +#define SOTP_CTRL_0__OTP_CMD 1 + +#define SOTP_STATUS_0 (SOTP_REGS_OTP_BASE + 0x0018) +#define SOTP_STATUS__FDONE 3 + +#define SOTP_STATUS_1 (SOTP_REGS_OTP_BASE + 0x001c) +#define SOTP_STATUS_1__CMD_DONE 1 +#define SOTP_STATUS_1__ECC_DET 17 + +#define SOTP_RDDATA_0 (SOTP_REGS_OTP_BASE + 0x0020) +#define SOTP_RDDATA_1 (SOTP_REGS_OTP_BASE + 0x0024) + +#define SOTP_READ 0 + +#define SOTP_PROG_WORD 10 +#define SOTP_STATUS__PROGOK 2 +#define SOTP_PROG_ENABLE 2 + +#define SOTP_ROW_DATA_MASK 0xffffffff +#define SOTP_ECC_ERR_BITS_MASK 0x1ff00000000 + +#define SOTP_CHIP_CTRL_SW_OVERRIDE_CHIP_STATES 4 +#define SOTP_CHIP_CTRL_SW_MANU_PROG 5 +#define SOTP_CHIP_CTRL_SW_CID_PROG 6 +#define SOTP_CHIP_CTRL_SW_AB_DEVICE 8 +#define SOTP_CHIP_CTRL_SW_AB_DEV_MODE 9 +#define CHIP_STATE_UNPROGRAMMED 0x1 +#define CHIP_STATE_UNASSIGNED 0x2 + +uint64_t sotp_mem_read(uint32_t offset, uint32_t sotp_add_ecc) +{ +#ifdef USE_SOFT_SOTP + (void)sotp_add_ecc; + + return soft_sotp[offset]; +#else + uint64_t read_data = 0; + uint64_t read_data1 = 0; + uint64_t read_data2 = 0; + + /* Check for FDONE status */ + while ((mmio_read_32(SOTP_STATUS_0) & BIT(SOTP_STATUS__FDONE)) != + BIT(SOTP_STATUS__FDONE)) + ; + + /* Enable OTP access by CPU */ + mmio_setbits_32(SOTP_PROG_CONTROL, + BIT(SOTP_PROG_CONTROL__OTP_CPU_MODE_EN)); + + if (sotp_add_ecc == 1) { + mmio_clrbits_32(SOTP_PROG_CONTROL, + BIT(SOTP_PROG_CONTROL__OTP_DISABLE_ECC)); + } + + if (sotp_add_ecc == 0) { + mmio_setbits_32(SOTP_PROG_CONTROL, + BIT(SOTP_PROG_CONTROL__OTP_DISABLE_ECC)); + } + + mmio_write_32(SOTP_ADDR, + ((offset & SOTP_ADDR_MASK) << SOTP_ADDR__OTP_ROW_ADDR_R)); + mmio_write_32(SOTP_CTRL_0, (SOTP_READ << SOTP_CTRL_0__OTP_CMD)); + + /* Start bit to tell SOTP to send command to the OTP controller */ + mmio_setbits_32(SOTP_CTRL_0, BIT(SOTP_CTRL_0__START)); + + /* Wait for SOTP command done to be set */ + while ((mmio_read_32(SOTP_STATUS_1) & BIT(SOTP_STATUS_1__CMD_DONE)) != + BIT(SOTP_STATUS_1__CMD_DONE)) + ; + + /* Clr Start bit after command done */ + mmio_clrbits_32(SOTP_CTRL_0, BIT(SOTP_CTRL_0__START)); + + if ((offset > SOTP_DEVICE_SECURE_CFG3_ROW) && + (mmio_read_32(SOTP_STATUS_1) & BIT(SOTP_STATUS_1__ECC_DET))) { + ERROR("SOTP ECC ERROR Detected row offset %d\n", offset); + read_data = SOTP_ECC_ERR_DETECT; + } else { + read_data1 = (uint64_t)mmio_read_32(SOTP_RDDATA_0); + read_data1 = read_data1 & 0xFFFFFFFF; + read_data2 = (uint64_t)mmio_read_32(SOTP_RDDATA_1); + read_data2 = (read_data2 & 0x1ff) << 32; + read_data = read_data1 | read_data2; + } + + /* Command done is cleared */ + mmio_setbits_32(SOTP_STATUS_1, BIT(SOTP_STATUS_1__CMD_DONE)); + + /* disable OTP access by CPU */ + mmio_clrbits_32(SOTP_PROG_CONTROL, + BIT(SOTP_PROG_CONTROL__OTP_CPU_MODE_EN)); + + return read_data; +#endif +} + +void sotp_mem_write(uint32_t addr, uint32_t sotp_add_ecc, uint64_t wdata) +{ +#ifdef USE_SOFT_SOTP + (void)sotp_add_ecc; + + soft_sotp[addr] = wdata; +#else + uint32_t loop; + uint8_t prog_array[4] = { 0x0F, 0x04, 0x08, 0x0D }; + + uint32_t chip_state_default = + (CHIP_STATE_UNASSIGNED|CHIP_STATE_UNPROGRAMMED); + uint32_t chip_state = mmio_read_32(SOTP_REGS_SOTP_CHIP_STATES); + uint32_t chip_ctrl_default = 0; + + /* + * The override settings is required to allow the customer to program + * the application specific keys into SOTP, before the conversion to + * one of the AB modes. + * At the end of write operation, the chip ctrl settings will restored + * to the state prior to write call + */ + if (chip_state & chip_state_default) { + uint32_t chip_ctrl; + + chip_ctrl_default = mmio_read_32(SOTP_CHIP_CTRL); + INFO("SOTP: enable special prog mode\n"); + + chip_ctrl = BIT(SOTP_CHIP_CTRL_SW_OVERRIDE_CHIP_STATES) | + BIT(SOTP_CHIP_CTRL_SW_MANU_PROG) | + BIT(SOTP_CHIP_CTRL_SW_CID_PROG) | + BIT(SOTP_CHIP_CTRL_SW_AB_DEVICE); + mmio_write_32(SOTP_CHIP_CTRL, chip_ctrl); + } + + /* Check for FDONE status */ + while ((mmio_read_32(SOTP_STATUS_0) & BIT(SOTP_STATUS__FDONE)) != + BIT(SOTP_STATUS__FDONE)) + ; + + /* Enable OTP acces by CPU */ + mmio_setbits_32(SOTP_PROG_CONTROL, + BIT(SOTP_PROG_CONTROL__OTP_CPU_MODE_EN)); + + if (addr > SOTP_DEVICE_SECURE_CFG3_ROW) { + if (sotp_add_ecc == 0) { + mmio_clrbits_32(SOTP_PROG_CONTROL, + BIT(SOTP_PROG_CONTROL__OTP_ECC_WREN)); + } + if (sotp_add_ecc == 1) { + mmio_setbits_32(SOTP_PROG_CONTROL, + BIT(SOTP_PROG_CONTROL__OTP_ECC_WREN)); + } + } else { + mmio_clrbits_32(SOTP_PROG_CONTROL, + BIT(SOTP_PROG_CONTROL__OTP_ECC_WREN)); + } + + mmio_write_32(SOTP_CTRL_0, (SOTP_PROG_ENABLE << 1)); + + /* + * In order to avoid unintentional writes / programming of the OTP + * array, the OTP Controller must be put into programming mode before + * it will accept program commands. This is done by writing 0xF, 0x4, + * 0x8, 0xD with program commands prior to starting the actual + * programming sequence + */ + for (loop = 0; loop < 4; loop++) { + mmio_write_32(SOTP_WRDATA_0, prog_array[loop]); + + /* + * Start bit to tell SOTP to send command to the OTP controller + */ + mmio_setbits_32(SOTP_CTRL_0, BIT(SOTP_CTRL_0__START)); + + /* Wait for SOTP command done to <-- be set */ + while ((mmio_read_32(SOTP_STATUS_1) & + BIT(SOTP_STATUS_1__CMD_DONE)) != + BIT(SOTP_STATUS_1__CMD_DONE)) + ; + + /* Command done is cleared w1c */ + mmio_setbits_32(SOTP_STATUS_1, BIT(SOTP_STATUS_1__CMD_DONE)); + + /* Clr Start bit after command done */ + mmio_clrbits_32(SOTP_CTRL_0, BIT(SOTP_CTRL_0__START)); + } + + /* Check for PROGOK */ + while ((mmio_read_32(SOTP_STATUS_0) & 0x4) != BIT(SOTP_STATUS__PROGOK)) + ; + + /* Set 10 bit row address */ + mmio_write_32(SOTP_ADDR, + ((addr & SOTP_ADDR_MASK) << SOTP_ADDR__OTP_ROW_ADDR_R)); + + /* Set SOTP Row data */ + mmio_write_32(SOTP_WRDATA_0, (wdata & SOTP_ROW_DATA_MASK)); + + /* Set SOTP ECC and error bits */ + mmio_write_32(SOTP_WRDATA_1, ((wdata & SOTP_ECC_ERR_BITS_MASK) >> 32)); + + /* Set prog_word command */ + mmio_write_32(SOTP_CTRL_0, (SOTP_PROG_WORD << 1)); + + /* Start bit to tell SOTP to send command to the OTP controller */ + mmio_setbits_32(SOTP_CTRL_0, BIT(SOTP_CTRL_0__START)); + + /* Wait for SOTP command done to be set */ + while ((mmio_read_32(SOTP_STATUS_1) & BIT(SOTP_STATUS_1__CMD_DONE)) != + BIT(SOTP_STATUS_1__CMD_DONE)) + ; + + /* Command done is cleared w1c */ + mmio_setbits_32(SOTP_STATUS_1, BIT(SOTP_STATUS_1__CMD_DONE)); + + /* disable OTP acces by CPU */ + mmio_clrbits_32(SOTP_PROG_CONTROL, + BIT(SOTP_PROG_CONTROL__OTP_CPU_MODE_EN)); + + /* Clr Start bit after command done */ + mmio_clrbits_32(SOTP_CTRL_0, BIT(SOTP_CTRL_0__START)); + + if (chip_state & chip_state_default) + mmio_write_32(SOTP_CHIP_CTRL, chip_ctrl_default); + +#endif +} + +int sotp_read_key(uint8_t *key, size_t keysize, int start_row, int end_row) +{ + int row; + uint32_t status = 0; + uint32_t status2 = 0xFFFFFFFF; + uint64_t row_data; + uint32_t data; + uint32_t *temp_key = (uint32_t *)key; + + row = start_row; + while ((keysize > 0) && (row <= end_row)) { + row_data = sotp_mem_read(row, SOTP_ROW_ECC); + if (!(row_data & (SOTP_ECC_ERR_DETECT | SOTP_FAIL_BITS))) { + memcpy(temp_key++, &row_data, sizeof(uint32_t)); + keysize -= sizeof(uint32_t); + data = (uint32_t)(row_data & SOTP_ROW_DATA_MASK); + status |= data; + status2 &= data; + } + row++; + } + + if ((status2 == 0xFFFFFFFF) || (status == 0) || (row > end_row)) + return -1; + + return 0; +} + +int sotp_key_erased(void) +{ + uint64_t row_data; + int status = 0; + + row_data = sotp_mem_read(SOTP_DEVICE_SECURE_CFG0_ROW, 0); + if (row_data & SOTP_DEVICE_SECURE_CFG0_OTP_ERASED_MASK) + status = 1; + + else if (mmio_read_32(SOTP_REGS_SOTP_CHIP_STATES) & + SOTP_REGS_SOTP_CHIP_STATES_OTP_ERASED_MASK) + status = 1; + + return status; +} + +/* + * This function optimise the SOTP redundancy + * by considering the 00- zero and 01,10,11 - one + */ +uint32_t sotp_redundancy_reduction(uint32_t sotp_row_data) +{ + uint32_t opt_data; + uint32_t opt_loop; + uint32_t temp_data; + + opt_data = 0; + + for (opt_loop = 0; opt_loop < 16; opt_loop = opt_loop + 1) { + temp_data = ((sotp_row_data >> (opt_loop * 2)) & 0x3); + + if (temp_data != 0x0) + opt_data = (opt_data | (1 << opt_loop)); + } + return opt_data; +} diff --git a/include/drivers/brcm/chimp.h b/include/drivers/brcm/chimp.h new file mode 100644 index 000000000..02d528b9f --- /dev/null +++ b/include/drivers/brcm/chimp.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2016 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SR_CHIMP_H +#define SR_CHIMP_H + +#include +#include +#include + +#include + +#define CHIMP_WINDOW_SIZE 0x400000 +#define CHIMP_ERROR_OFFSET 28 +#define CHIMP_ERROR_MASK 0xf0000000 + +#ifndef EMULATION_SETUP +#define CHIMP_HANDSHAKE_TIMEOUT_MS 10000 +#else +/* + * 1hr timeout for test in emulator + * By doing this ChiMP is given a chance to boot + * fully from the QSPI + * (on Palladium this takes upto 50 min depending on QSPI clk) + */ + +#define CHIMP_HANDSHAKE_TIMEOUT_MS 3600000 +#endif + +#define CHIMP_BPE_MODE_ID_PATTERN (0x25000000) +#define CHIMP_BPE_MODE_ID_MASK (0x7f000000) +#define NIC_RESET_RELEASE_TIMEOUT_US (10) + +/* written by M0, used by ChiMP ROM */ +#define SR_IN_SMARTNIC_MODE_BIT 0 +/* written by M0, used by ChiMP ROM */ +#define SR_CHIMP_SECURE_BOOT_BIT 1 +/* cleared by AP, set by ChiMP BC2 code */ +#define SR_FLASH_ACCESS_DONE_BIT 2 + +#ifdef USE_CHIMP +void bcm_chimp_write(uintptr_t addr, uint32_t value); +uint32_t bcm_chimp_read(uintptr_t addr); +uint32_t bcm_chimp_read_ctrl(uint32_t offset); +void bcm_chimp_clrbits(uintptr_t addr, uint32_t bits); +void bcm_chimp_setbits(uintptr_t addr, uint32_t bits); +int bcm_chimp_is_nic_mode(void); +void bcm_chimp_fru_prog_done(bool status); +int bcm_chimp_handshake_done(void); +int bcm_chimp_wait_handshake(void); +/* Fastboot-related*/ +int bcm_chimp_initiate_fastboot(int fastboot_type); +#else +static inline void bcm_chimp_write(uintptr_t addr, uint32_t value) +{ +} +static inline uint32_t bcm_chimp_read(uintptr_t addr) +{ + return 0; +} +static inline uint32_t bcm_chimp_read_ctrl(uint32_t offset) +{ + return 0; +} +static inline void bcm_chimp_clrbits(uintptr_t addr, uint32_t bits) +{ +} +static inline void bcm_chimp_setbits(uintptr_t addr, uint32_t bits) +{ +} +static inline int bcm_chimp_is_nic_mode(void) +{ + return 0; +} +static inline void bcm_chimp_fru_prog_done(bool status) +{ +} +static inline int bcm_chimp_handshake_done(void) +{ + return 0; +} +static inline int bcm_chimp_wait_handshake(void) +{ + return 0; +} +static inline int bcm_chimp_initiate_fastboot(int fastboot_type) +{ + return 0; +} +#endif /* USE_CHIMP */ +#endif diff --git a/include/drivers/brcm/fru.h b/include/drivers/brcm/fru.h new file mode 100644 index 000000000..ee863b480 --- /dev/null +++ b/include/drivers/brcm/fru.h @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2019-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FRU_H +#define FRU_H + +#include +#include + +/* max string length */ +#define FRU_MAX_STR_LEN 32 + +/* max number of DDR channels */ +#define BCM_MAX_NR_DDR 3 + +/* max supported FRU table size */ +#define BCM_MAX_FRU_LEN 512 + +/* FRU table starting offset */ +#define BCM_FRU_TBL_OFFSET 0x300000 + +/* FRU time constants */ +#define MINS_PER_DAY 1440 +#define MINS_PER_HOUR 60 +#define FRU_YEAR_START 1996 +#define FRU_MONTH_START 1 +#define FRU_DAY_START 1 +#define MONTHS_PER_YEAR 12 + +/* + * FRU areas based on the spec + */ +enum fru_area_name { + FRU_AREA_INTERNAL = 0, + FRU_AREA_CHASSIS_INFO, + FRU_AREA_BOARD_INFO, + FRU_AREA_PRODUCT_INFO, + FRU_AREA_MRECORD_INFO, + FRU_MAX_NR_AREAS +}; + +/* + * FRU area information + * + * @use: indicate this area is being used + * @version: format version + * @offset: offset of this area from the beginning of the FRU table + * @len: total length of the area + */ +struct fru_area_info { + bool use; + uint8_t version; + unsigned int offset; + unsigned int len; +}; + +/* + * DDR MCB information + * + * @idx: DDR channel index + * @size_mb: DDR size of this channel in MB + * @ref_id: DDR MCB reference ID + */ +struct ddr_mcb { + unsigned int idx; + unsigned int size_mb; + uint32_t ref_id; +}; + +/* + * DDR information + * + * @ddr_info: array that contains MCB related info for each channel + */ +struct ddr_info { + struct ddr_mcb mcb[BCM_MAX_NR_DDR]; +}; + +/* + * FRU board area information + * + * @lang: Language code + * @mfg_date: Manufacturing date + * @manufacturer: Manufacturer + * @product_name: Product name + * @serial_number: Serial number + * @part_number: Part number + * @file_id: FRU file ID + */ +struct fru_board_info { + unsigned char lang; + unsigned int mfg_date; + unsigned char manufacturer[FRU_MAX_STR_LEN]; + unsigned char product_name[FRU_MAX_STR_LEN]; + unsigned char serial_number[FRU_MAX_STR_LEN]; + unsigned char part_number[FRU_MAX_STR_LEN]; + unsigned char file_id[FRU_MAX_STR_LEN]; +}; + +/* + * FRU manufacture date in human readable format + */ +struct fru_time { + unsigned int min; + unsigned int hour; + unsigned int day; + unsigned int month; + unsigned int year; +}; + +#ifdef USE_FRU +int fru_validate(uint8_t *data, struct fru_area_info *fru_area); +int fru_parse_ddr(uint8_t *data, struct fru_area_info *area, + struct ddr_info *ddr); +int fru_parse_board(uint8_t *data, struct fru_area_info *area, + struct fru_board_info *board); +void fru_format_time(unsigned int min, struct fru_time *tm); +#else +static inline int fru_validate(uint8_t *data, struct fru_area_info *fru_area) +{ + return -1; +} + +static inline int fru_parse_ddr(uint8_t *data, struct fru_area_info *area, + struct ddr_info *ddr) +{ + return -1; +} + +static inline int fru_parse_board(uint8_t *data, struct fru_area_info *area, + struct fru_board_info *board) +{ + return -1; +} + +static inline void fru_format_time(unsigned int min, struct fru_time *tm) +{ +} +#endif /* USE_FRU */ + +#endif /* FRU_H */ diff --git a/include/drivers/brcm/iproc_gpio.h b/include/drivers/brcm/iproc_gpio.h new file mode 100644 index 000000000..be971f6f6 --- /dev/null +++ b/include/drivers/brcm/iproc_gpio.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2019-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef IPROC_GPIO_H +#define IPROC_GPIO_H + +#ifdef USE_GPIO +void iproc_gpio_init(uintptr_t base, int nr_gpios, uintptr_t pinmux_base, + uintptr_t pinconf_base); +#else +static void iproc_gpio_init(uintptr_t base, int nr_gpios, uintptr_t pinmux_base, + uintptr_t pinconf_base) +{ +} +#endif /* IPROC_GPIO */ + +#endif /* IPROC_GPIO_H */ diff --git a/include/drivers/brcm/ocotp.h b/include/drivers/brcm/ocotp.h new file mode 100644 index 000000000..830b3e4cd --- /dev/null +++ b/include/drivers/brcm/ocotp.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2016 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef OCOTP_H +#define OCOTP_H + +#include + +struct otpc_map { + /* in words. */ + uint32_t otpc_row_size; + /* 128 bit row / 4 words support. */ + uint16_t data_r_offset[4]; + /* 128 bit row / 4 words support. */ + uint16_t data_w_offset[4]; + int word_size; + int stride; +}; + +int bcm_otpc_init(struct otpc_map *map); +int bcm_otpc_read(unsigned int offset, void *val, uint32_t bytes, + uint32_t ecc_flag); + +#endif /* OCOTP_H */ diff --git a/include/drivers/brcm/scp.h b/include/drivers/brcm/scp.h new file mode 100644 index 000000000..b7b5bad74 --- /dev/null +++ b/include/drivers/brcm/scp.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2017 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SCP_H_ +#define SCP_H + +#include + +int download_scp_patch(void *image, unsigned int image_size); + +#endif /* SCP_H */ diff --git a/include/drivers/brcm/sotp.h b/include/drivers/brcm/sotp.h new file mode 100644 index 000000000..a93d687f2 --- /dev/null +++ b/include/drivers/brcm/sotp.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2016-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SOTP_H +#define SOTP_H + +#include +#include + +#include + +#define SOTP_ROW_NO_ECC 0 +#define SOTP_ROW_ECC 1 + +#define SOTP_STATUS_1 (SOTP_REGS_OTP_BASE + 0x001c) +#define SOTP_FAIL_BITS 0x18000000000 +#define SOTP_ECC_ERR_DETECT 0x8000000000000000 + +#define SOTP_REGS_SOTP_CHIP_STATES (SOTP_REGS_OTP_BASE + 0x0028) +#define SOTP_REGS_OTP_WR_LOCK (SOTP_REGS_OTP_BASE + 0x0038) + +#define SOTP_CHIP_STATES_MANU_DEBUG_MASK (1 << 8) +#define SOTP_DEVICE_SECURE_CFG0_OTP_ERASED_MASK (3 << 16) +#define SOTP_REGS_SOTP_CHIP_STATES_OTP_ERASED_MASK (1 << 16) + +#define SOTP_DEVICE_SECURE_CFG0_CID_MASK (3 << 2) +#define SOTP_DEVICE_SECURE_CFG0_AB_MASK (3 << 6) +#define SOTP_DEVICE_SECURE_CFG0_DEV_MASK (3 << 8) + +#define SOTP_BOOT_SOURCE_SHIFT 8 +/* bits 14 and 15 */ +#define SOTP_BOOT_SOURCE_ENABLE_MASK (0xC0 << SOTP_BOOT_SOURCE_SHIFT) +/* bits 8 to 13 */ +#define SOTP_BOOT_SOURCE_BITS0 (0x03 << SOTP_BOOT_SOURCE_SHIFT) +#define SOTP_BOOT_SOURCE_BITS1 (0x0C << SOTP_BOOT_SOURCE_SHIFT) +#define SOTP_BOOT_SOURCE_BITS2 (0x30 << SOTP_BOOT_SOURCE_SHIFT) +#define SOTP_BOOT_SOURCE_MASK (0x3F << SOTP_BOOT_SOURCE_SHIFT) + +#define SOTP_ATF_CFG_ROW_ID SOTP_DEVICE_SECURE_CFG2_ROW +/* bits 28 and 29 */ +#define SOTP_SBL_MASK (3 << 28) +/* bits 30 and 31 */ +#define SOTP_ATF_NVCOUNTER_ENABLE_MASK ((uint64_t)3 << 30) +/* bits 32 and 33 */ +#define SOTP_ATF_WATCHDOG_ENABLE_MASK ((uint64_t)3 << 32) +/* bits 34 and 35 */ +#define SOTP_ATF_PLL_ON ((uint64_t)3 << 34) +/* bits 36 and 37 */ +#define SOTP_ATF_RESET_RETRY ((uint64_t)3 << 36) +/* bits 38 to 40 */ +#define SOTP_ATF_LOG_LEVEL_SHIFT 38 +#define SOTP_ATF_LOG_LEVEL ((uint64_t)7 << SOTP_ATF_LOG_LEVEL_SHIFT) + +#define SOTP_ATF2_CFG_ROW_ID SOTP_DEVICE_SECURE_CFG3_ROW +/* bits 16 and 17 */ +#define SOTP_ROMKEY_MASK (3 << 16) +/* bits 18 and 19 */ +#define SOTP_EC_EN_MASK (3 << 18) + +#define SOTP_ENC_DEV_TYPE_AB_DEV ((uint64_t)0x19999800000) +#define SOTP_ENC_DEV_TYPE_MASK ((uint64_t)0x1ffff800000) + +uint64_t sotp_mem_read(uint32_t offset, uint32_t sotp_add_ecc); +void sotp_mem_write(uint32_t addr, uint32_t sotp_add_ecc, uint64_t wdata); +int sotp_read_key(uint8_t *key, size_t keysize, int start_row, int end_row); +int sotp_key_erased(void); +uint32_t sotp_redundancy_reduction(uint32_t sotp_row_data); +#endif diff --git a/include/plat/brcm/common/bcm_elog.h b/include/plat/brcm/common/bcm_elog.h new file mode 100644 index 000000000..ea4b1692d --- /dev/null +++ b/include/plat/brcm/common/bcm_elog.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2018 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef BCM_ELOG_H +#define BCM_ELOG_H + +#ifndef __ASSEMBLER__ + +#include + +#if defined(BCM_ELOG) && (defined(IMAGE_BL2) || defined(IMAGE_BL31)) +int bcm_elog_init(void *base, uint32_t size, unsigned int level); +void bcm_elog_exit(void); +int bcm_elog_copy_log(void *dst, uint32_t max_size); +void bcm_elog(const char *fmt, ...); +#else +static inline int bcm_elog_init(void *base, uint32_t size, + unsigned int level) +{ + return 0; +} +static inline void bcm_elog_exit(void) +{ +} +static inline int bcm_elog_copy_log(void *dst, uint32_t max_size) +{ + return 0; +} +static inline void bcm_elog(const char *fmt, ...) +{ +} +#endif /* BCM_ELOG */ + +#endif /* __ASSEMBLER__ */ +#endif /* BCM_ELOG_H */ diff --git a/plat/brcm/board/common/bcm_elog.c b/plat/brcm/board/common/bcm_elog.c new file mode 100644 index 000000000..093157ef0 --- /dev/null +++ b/plat/brcm/board/common/bcm_elog.c @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2018 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include +#include +#include + +#include + +/* error logging signature */ +#define BCM_ELOG_SIG_OFFSET 0x0000 +#define BCM_ELOG_SIG_VAL 0x75767971 + +/* current logging offset that points to where new logs should be added */ +#define BCM_ELOG_OFF_OFFSET 0x0004 + +/* current logging length (excluding header) */ +#define BCM_ELOG_LEN_OFFSET 0x0008 + +#define BCM_ELOG_HEADER_LEN 12 + +/* + * @base: base address of memory where log is saved + * @max_size: max size of memory reserved for logging + * @is_active: indicates logging is currently active + * @level: current logging level + */ +struct bcm_elog { + uintptr_t base; + uint32_t max_size; + unsigned int is_active; + unsigned int level; +}; + +static struct bcm_elog global_elog; + +extern void memcpy16(void *dst, const void *src, unsigned int len); + +/* + * Log one character + */ +static void elog_putchar(struct bcm_elog *elog, unsigned char c) +{ + uint32_t offset, len; + + offset = mmio_read_32(elog->base + BCM_ELOG_OFF_OFFSET); + len = mmio_read_32(elog->base + BCM_ELOG_LEN_OFFSET); + mmio_write_8(elog->base + offset, c); + offset++; + + /* log buffer is now full and need to wrap around */ + if (offset >= elog->max_size) + offset = BCM_ELOG_HEADER_LEN; + + /* only increment length when log buffer is not full */ + if (len < elog->max_size - BCM_ELOG_HEADER_LEN) + len++; + + mmio_write_32(elog->base + BCM_ELOG_OFF_OFFSET, offset); + mmio_write_32(elog->base + BCM_ELOG_LEN_OFFSET, len); +} + +static void elog_unsigned_num(struct bcm_elog *elog, unsigned long unum, + unsigned int radix) +{ + /* Just need enough space to store 64 bit decimal integer */ + unsigned char num_buf[20]; + int i = 0, rem; + + do { + rem = unum % radix; + if (rem < 0xa) + num_buf[i++] = '0' + rem; + else + num_buf[i++] = 'a' + (rem - 0xa); + } while (unum /= radix); + + while (--i >= 0) + elog_putchar(elog, num_buf[i]); +} + +static void elog_string(struct bcm_elog *elog, const char *str) +{ + while (*str) + elog_putchar(elog, *str++); +} + +/* + * Routine to initialize error logging + */ +int bcm_elog_init(void *base, uint32_t size, unsigned int level) +{ + struct bcm_elog *elog = &global_elog; + uint32_t val; + + elog->base = (uintptr_t)base; + elog->max_size = size; + elog->is_active = 1; + elog->level = level / 10; + + /* + * If a valid signature can be found, it means logs have been copied + * into designated memory by another software. In this case, we should + * not re-initialize the entry header in the designated memory + */ + val = mmio_read_32(elog->base + BCM_ELOG_SIG_OFFSET); + if (val != BCM_ELOG_SIG_VAL) { + mmio_write_32(elog->base + BCM_ELOG_SIG_OFFSET, + BCM_ELOG_SIG_VAL); + mmio_write_32(elog->base + BCM_ELOG_OFF_OFFSET, + BCM_ELOG_HEADER_LEN); + mmio_write_32(elog->base + BCM_ELOG_LEN_OFFSET, 0); + } + + return 0; +} + +/* + * Routine to disable error logging + */ +void bcm_elog_exit(void) +{ + struct bcm_elog *elog = &global_elog; + + if (!elog->is_active) + return; + + elog->is_active = 0; + + flush_dcache_range(elog->base, elog->max_size); +} + +/* + * Routine to copy error logs from current memory to 'dst' memory and continue + * logging from the new 'dst' memory. + * dst and base addresses must be 16-bytes aligned. + */ +int bcm_elog_copy_log(void *dst, uint32_t max_size) +{ + struct bcm_elog *elog = &global_elog; + uint32_t offset, len; + + if (!elog->is_active || ((uintptr_t)dst == elog->base)) + return -1; + + /* flush cache before copying logs */ + flush_dcache_range(elog->base, max_size); + + /* + * If current offset exceeds the new max size, then that is considered + * as a buffer overflow situation. In this case, we reset the offset + * back to the beginning + */ + offset = mmio_read_32(elog->base + BCM_ELOG_OFF_OFFSET); + if (offset >= max_size) { + offset = BCM_ELOG_HEADER_LEN; + mmio_write_32(elog->base + BCM_ELOG_OFF_OFFSET, offset); + } + + /* note payload length does not include header */ + len = mmio_read_32(elog->base + BCM_ELOG_LEN_OFFSET); + if (len > max_size - BCM_ELOG_HEADER_LEN) { + len = max_size - BCM_ELOG_HEADER_LEN; + mmio_write_32(elog->base + BCM_ELOG_LEN_OFFSET, len); + } + + /* Need to copy everything including the header. */ + memcpy16(dst, (const void *)elog->base, len + BCM_ELOG_HEADER_LEN); + elog->base = (uintptr_t)dst; + elog->max_size = max_size; + + return 0; +} + +/* + * Main routine to save logs into memory + */ +void bcm_elog(const char *fmt, ...) +{ + va_list args; + const char *prefix_str; + int bit64; + int64_t num; + uint64_t unum; + char *str; + struct bcm_elog *elog = &global_elog; + + /* We expect the LOG_MARKER_* macro as the first character */ + unsigned int level = fmt[0]; + + if (!elog->is_active || level > elog->level) + return; + + prefix_str = plat_log_get_prefix(level); + + while (*prefix_str != '\0') { + elog_putchar(elog, *prefix_str); + prefix_str++; + } + + va_start(args, fmt); + fmt++; + while (*fmt) { + bit64 = 0; + + if (*fmt == '%') { + fmt++; + /* Check the format specifier */ +loop: + switch (*fmt) { + case 'i': /* Fall through to next one */ + case 'd': + if (bit64) + num = va_arg(args, int64_t); + else + num = va_arg(args, int32_t); + + if (num < 0) { + elog_putchar(elog, '-'); + unum = (unsigned long)-num; + } else + unum = (unsigned long)num; + + elog_unsigned_num(elog, unum, 10); + break; + case 's': + str = va_arg(args, char *); + elog_string(elog, str); + break; + case 'x': + if (bit64) + unum = va_arg(args, uint64_t); + else + unum = va_arg(args, uint32_t); + + elog_unsigned_num(elog, unum, 16); + break; + case 'l': + bit64 = 1; + fmt++; + goto loop; + case 'u': + if (bit64) + unum = va_arg(args, uint64_t); + else + unum = va_arg(args, uint32_t); + + elog_unsigned_num(elog, unum, 10); + break; + default: + /* Exit on any other format specifier */ + goto exit; + } + fmt++; + continue; + } + elog_putchar(elog, *fmt++); + } +exit: + va_end(args); +} diff --git a/plat/brcm/board/common/bcm_elog_ddr.c b/plat/brcm/board/common/bcm_elog_ddr.c new file mode 100644 index 000000000..89e7bff8f --- /dev/null +++ b/plat/brcm/board/common/bcm_elog_ddr.c @@ -0,0 +1,133 @@ +/* + * Copyright 2019-2020 Broadcom. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include +#include +#include + +#include "bcm_elog_ddr.h" +#include "m0_cfg.h" +#include "m0_ipc.h" + +void elog_init_ddr_log(void) +{ + struct elog_setup setup = {0}; + struct elog_global_header global; + struct elog_meta_record rec; + unsigned int rec_idx = 0; + uint32_t log_offset; + uintptr_t metadata; + char *rec_desc[ELOG_SUPPORTED_REC_CNT] = {"SYSRESET", "THERMAL", + "DDR_ECC", "APBOOTLG", + "IDM"}; + + /* + * If this is warm boot, return immediately. + * We expect metadata to be initialized already + */ + if (is_warmboot()) { + WARN("Warmboot detected, skip ELOG metadata initialization\n"); + return; + } + + memset(&global, 0, sizeof(global)); + + global.sector_size = ELOG_SECTOR_SIZE; + global.signature = ELOG_GLOBAL_META_HDR_SIG; + global.rec_count = ELOG_SUPPORTED_REC_CNT; + + /* Start of logging area in DDR memory */ + log_offset = ELOG_STORE_OFFSET; + + /* Shift to the first RECORD header */ + log_offset += 2 * global.sector_size; + + /* Temporary place to hold metadata */ + metadata = TMP_ELOG_METADATA_BASE; + + memcpy((void *)metadata, &global, sizeof(global)); + metadata += sizeof(global); + + while (rec_idx < global.rec_count) { + memset(&rec, 0, sizeof(rec)); + + rec.type = rec_idx; + if (rec_idx == ELOG_REC_UART_LOG) { + rec.format = ELOG_REC_FMT_ASCII; + rec.src_mem_type = ELOG_SRC_MEM_TYPE_DDR; + rec.alt_src_mem_type = ELOG_SRC_MEM_TYPE_FS4_SCRATCH; + rec.src_mem_addr = BCM_ELOG_BL31_BASE; + rec.alt_src_mem_addr = BCM_ELOG_BL2_BASE; + rec.rec_size = ELOG_APBOOTLG_REC_SIZE; + } else if (rec_idx == ELOG_REC_IDM_LOG) { + rec.type = IDM_ELOG_REC_TYPE; + rec.format = ELOG_REC_FMT_CUSTOM; + rec.src_mem_type = ELOG_SRC_MEM_TYPE_DDR; + rec.alt_src_mem_type = ELOG_SRC_MEM_TYPE_CRMU_SCRATCH; + rec.src_mem_addr = ELOG_IDM_SRC_MEM_ADDR; + rec.alt_src_mem_addr = 0x0; + rec.rec_size = ELOG_DEFAULT_REC_SIZE; + } else { + rec.format = ELOG_REC_FMT_CUSTOM; + rec.src_mem_type = ELOG_SRC_MEM_TYPE_CRMU_SCRATCH; + rec.alt_src_mem_type = ELOG_SRC_MEM_TYPE_CRMU_SCRATCH; + rec.src_mem_addr = ELOG_USE_DEFAULT_MEM_ADDR; + rec.alt_src_mem_addr = ELOG_USE_DEFAULT_MEM_ADDR; + rec.rec_size = ELOG_DEFAULT_REC_SIZE; + } + + rec.nvm_type = LOG_MEDIA_DDR; + rec.sector_size = ELOG_SECTOR_SIZE; + + rec.rec_addr = (uint64_t)log_offset; + log_offset += rec.rec_size; + + /* Sanity checks */ + if (rec.type > ELOG_MAX_REC_COUNT || + rec.format > ELOG_MAX_REC_FORMAT || + (rec.nvm_type > ELOG_MAX_NVM_TYPE && + rec.nvm_type != ELOG_NVM_DEFAULT) || + !rec.rec_size || + !rec.sector_size || + rec_idx >= ELOG_SUPPORTED_REC_CNT) { + ERROR("Invalid ELOG record(%u) detected\n", rec_idx); + return; + } + + memset(rec.rec_desc, ' ', sizeof(rec.rec_desc)); + + memcpy(rec.rec_desc, rec_desc[rec_idx], + strlen(rec_desc[rec_idx])); + + memcpy((void *)metadata, &rec, sizeof(rec)); + metadata += sizeof(rec); + + rec_idx++; + } + + setup.params[0] = TMP_ELOG_METADATA_BASE; + setup.params[1] = (sizeof(global) + global.rec_count * sizeof(rec)); + setup.cmd = ELOG_SETUP_CMD_WRITE_META; + + flush_dcache_range((uintptr_t)&setup, sizeof(struct elog_setup)); + flush_dcache_range((uintptr_t)setup.params[0], setup.params[1]); + + /* initialize DDR Logging METADATA if this is NOT warmboot */ + if (!is_warmboot()) { + if (scp_send_cmd(MCU_IPC_MCU_CMD_ELOG_SETUP, + (uint32_t)(uintptr_t)(&setup), + SCP_CMD_DEFAULT_TIMEOUT_US)) { + ERROR("scp_send_cmd: timeout/error for elog setup\n"); + return; + } + } + + NOTICE("MCU Error logging initialized\n"); +} diff --git a/plat/brcm/board/common/bcm_elog_ddr.h b/plat/brcm/board/common/bcm_elog_ddr.h new file mode 100644 index 000000000..6f21a680d --- /dev/null +++ b/plat/brcm/board/common/bcm_elog_ddr.h @@ -0,0 +1,107 @@ +/* + * Copyright 2019-2020 Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef BCM_ELOG_DDR_H +#define BCM_ELOG_DDR_H + +#define ELOG_GLOBAL_META_HDR_SIG 0x45524c47 +#define ELOG_MAX_REC_COUNT 13 +#define ELOG_MAX_REC_FORMAT 1 +#define ELOG_MAX_NVM_TYPE 4 +/* Use a default NVM, set by m0 configuration */ +#define ELOG_NVM_DEFAULT 0xff + +/* Max. number of cmd parameters per elog spec */ +#define ELOG_PARAM_COUNT 3 +/* + * Number of supported RECORD Types- + * SYSRESET, THERMAL, DDR_ECC, APBOOTLG, IDM + */ +#define ELOG_SUPPORTED_REC_CNT 5 + +#define ELOG_REC_DESC_LENGTH 8 + +#define ELOG_SECTOR_SIZE 0x1000 + +/* Default Record size for all record types except APBOOTLOG */ +#define ELOG_DEFAULT_REC_SIZE 0x10000 + +/* Default record size for APBOOTLOG record */ +#define ELOG_APBOOTLG_REC_SIZE 0x60000 + +/* Use default CRMU provided mem address */ +#define ELOG_USE_DEFAULT_MEM_ADDR 0x0 + +/* Temporary place to hold metadata */ +#define TMP_ELOG_METADATA_BASE (ELOG_AP_UART_LOG_BASE + \ + BCM_ELOG_BL2_SIZE) +/* IDM ELOG source memory address */ +#define ELOG_IDM_SRC_MEM_ADDR 0x8f213000 + +#define IDM_ELOG_REC_TYPE 5 + +enum elog_record_type { + ELOG_REC_SYS_RESET_EVT = 0, + ELOG_REC_THERMAL_EVT, + ELOG_REC_DDR_ECC, + ELOG_REC_UART_LOG, + ELOG_REC_IDM_LOG, + ELOG_REC_MAX +}; + +enum elog_record_format { + ELOG_REC_FMT_ASCII = 0, + ELOG_REC_FMT_CUSTOM +}; + +enum elog_src_memory_type { + ELOG_SRC_MEM_TYPE_CRMU_SCRATCH = 0, + ELOG_SRC_MEM_TYPE_FS4_SCRATCH, + ELOG_SRC_MEM_TYPE_DDR, + ELOG_SRC_MEM_TYPE_CHIMP_SCRATCH +}; + +enum elog_setup_cmd { + ELOG_SETUP_CMD_VALIDATE_META, + ELOG_SETUP_CMD_WRITE_META, + ELOG_SETUP_CMD_ERASE, + ELOG_SETUP_CMD_READ, + ELOG_SETUP_CMD_CHECK +}; + +struct elog_setup { + uint32_t cmd; + uint32_t params[ELOG_PARAM_COUNT]; + uint32_t result; + uint32_t ret_code; +}; + +struct elog_meta_record { + uint8_t type; + uint8_t format; + uint8_t src_mem_type; + uint8_t alt_src_mem_type; + uint8_t nvm_type; + char rec_desc[ELOG_REC_DESC_LENGTH]; + uint64_t src_mem_addr; + uint64_t alt_src_mem_addr; + uint64_t rec_addr; + uint32_t rec_size; + uint32_t sector_size; + uint8_t padding[3]; +} __packed; + +struct elog_global_header { + uint32_t signature; + uint32_t sector_size; + uint8_t revision; + uint8_t rec_count; + uint16_t padding; +} __packed; + +void elog_init_ddr_log(void); + +#endif /* BCM_ELOG_DDR_H */ diff --git a/plat/brcm/board/common/board_arm_trusted_boot.c b/plat/brcm/board/common/board_arm_trusted_boot.c new file mode 100644 index 000000000..7a4dad013 --- /dev/null +++ b/plat/brcm/board/common/board_arm_trusted_boot.c @@ -0,0 +1,624 @@ +/* + * Copyright 2015 - 2020 Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +/* Weak definition may be overridden in specific platform */ +#pragma weak plat_match_rotpk +#pragma weak plat_get_nv_ctr +#pragma weak plat_set_nv_ctr + +/* SHA256 algorithm */ +#define SHA256_BYTES 32 + +/* ROTPK locations */ +#define ARM_ROTPK_REGS_ID 1 +#define ARM_ROTPK_DEVEL_RSA_ID 2 +#define BRCM_ROTPK_SOTP_RSA_ID 3 + +#if !ARM_ROTPK_LOCATION_ID + #error "ARM_ROTPK_LOCATION_ID not defined" +#endif + +static const unsigned char rotpk_hash_hdr[] = + "\x30\x31\x30\x0D\x06\x09\x60\x86\x48" + "\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20"; +static const unsigned int rotpk_hash_hdr_len = sizeof(rotpk_hash_hdr) - 1; +static unsigned char rotpk_hash_der[sizeof(rotpk_hash_hdr) - 1 + SHA256_BYTES]; + +#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) +static const unsigned char arm_devel_rotpk_hash[] = + "\xB0\xF3\x82\x09\x12\x97\xD8\x3A" + "\x37\x7A\x72\x47\x1B\xEC\x32\x73" + "\xE9\x92\x32\xE2\x49\x59\xF6\x5E" + "\x8B\x4A\x4A\x46\xD8\x22\x9A\xDA"; +#endif + +#pragma weak plat_rotpk_hash +const unsigned char plat_rotpk_hash[] = + "\xdb\x06\x67\x95\x4f\x88\x2b\x88" + "\x49\xbf\x70\x3f\xde\x50\x4a\x96" + "\xd8\x17\x69\xd4\xa0\x6c\xba\xee" + "\x66\x3e\x71\x82\x2d\x95\x69\xe4"; + +#pragma weak rom_slice +const unsigned char rom_slice[] = + "\x77\x06\xbc\x98\x40\xbe\xfd\xab" + "\x60\x4b\x74\x3c\x9a\xb3\x80\x75" + "\x39\xb6\xda\x27\x07\x2e\x5b\xbf" + "\x5c\x47\x91\xc9\x95\x26\x26\x0c"; + +#if (ARM_ROTPK_LOCATION_ID == BRCM_ROTPK_SOTP_RSA_ID) +static int plat_is_trusted_boot(void) +{ + uint64_t section3_row0_data; + + section3_row0_data = sotp_mem_read(SOTP_DEVICE_SECURE_CFG0_ROW, 0); + + if ((section3_row0_data & SOTP_DEVICE_SECURE_CFG0_AB_MASK) == 0) { + INFO("NOT AB\n"); + return 0; + } + + INFO("AB\n"); + return TRUSTED_BOARD_BOOT; +} + +/* + * FAST AUTH is enabled if all following conditions are met: + * - AB part + * - SOTP.DEV != 0 + * - SOTP.CID != 0 + * - SOTP.ENC_DEV_TYPE = ENC_AB_DEV + * - Manuf_debug strap set high + */ +static int plat_fast_auth_enabled(void) +{ + uint32_t chip_state; + uint64_t section3_row0_data; + uint64_t section3_row1_data; + + section3_row0_data = + sotp_mem_read(SOTP_DEVICE_SECURE_CFG0_ROW, 0); + section3_row1_data = + sotp_mem_read(SOTP_DEVICE_SECURE_CFG1_ROW, 0); + + chip_state = mmio_read_32(SOTP_REGS_SOTP_CHIP_STATES); + + if (plat_is_trusted_boot() && + (section3_row0_data & SOTP_DEVICE_SECURE_CFG0_DEV_MASK) && + (section3_row0_data & SOTP_DEVICE_SECURE_CFG0_CID_MASK) && + ((section3_row1_data & SOTP_ENC_DEV_TYPE_MASK) == + SOTP_ENC_DEV_TYPE_AB_DEV) && + (chip_state & SOTP_CHIP_STATES_MANU_DEBUG_MASK)) + return 1; + + return 0; +} +#endif + +/* + * 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) +{ + uint8_t *dst; + + assert(key_ptr != NULL); + assert(key_len != NULL); + assert(flags != NULL); + + *flags = 0; + + /* Copy the DER header */ + memcpy(rotpk_hash_der, rotpk_hash_hdr, rotpk_hash_hdr_len); + dst = (uint8_t *)&rotpk_hash_der[rotpk_hash_hdr_len]; + +#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) + memcpy(dst, arm_devel_rotpk_hash, SHA256_BYTES); +#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID) + uint32_t *src, tmp; + unsigned int words, i; + + /* + * Append the hash from Trusted Root-Key Storage registers. The hash has + * not been written linearly into the registers, so we have to do a bit + * of byte swapping: + * + * 0x00 0x04 0x08 0x0C 0x10 0x14 0x18 0x1C + * +---------------------------------------------------------------+ + * | Reg0 | Reg1 | Reg2 | Reg3 | Reg4 | Reg5 | Reg6 | Reg7 | + * +---------------------------------------------------------------+ + * | ... ... | | ... ... | + * | +--------------------+ | +-------+ + * | | | | + * +----------------------------+ +----------------------------+ + * | | | | + * +-------+ | +--------------------+ | + * | | | | + * v v v v + * +---------------------------------------------------------------+ + * | | | + * +---------------------------------------------------------------+ + * 0 15 16 31 + * + * Additionally, we have to access the registers in 32-bit words + */ + words = SHA256_BYTES >> 3; + + /* Swap bytes 0-15 (first four registers) */ + src = (uint32_t *)TZ_PUB_KEY_HASH_BASE; + for (i = 0 ; i < words ; i++) { + tmp = src[words - 1 - i]; + /* Words are read in little endian */ + *dst++ = (uint8_t)((tmp >> 24) & 0xFF); + *dst++ = (uint8_t)((tmp >> 16) & 0xFF); + *dst++ = (uint8_t)((tmp >> 8) & 0xFF); + *dst++ = (uint8_t)(tmp & 0xFF); + } + + /* Swap bytes 16-31 (last four registers) */ + src = (uint32_t *)(TZ_PUB_KEY_HASH_BASE + SHA256_BYTES / 2); + for (i = 0 ; i < words ; i++) { + tmp = src[words - 1 - i]; + *dst++ = (uint8_t)((tmp >> 24) & 0xFF); + *dst++ = (uint8_t)((tmp >> 16) & 0xFF); + *dst++ = (uint8_t)((tmp >> 8) & 0xFF); + *dst++ = (uint8_t)(tmp & 0xFF); + } +#elif (ARM_ROTPK_LOCATION_ID == BRCM_ROTPK_SOTP_RSA_ID) +{ + int i; + int ret = -1; + + /* + * In non-AB mode, we do not read the key. + * In AB mode: + * - The Dauth is in BL11 if SBL is enabled + * - The Dauth is in SOTP if SBL is disabled. + */ + if (plat_is_trusted_boot() == 0) { + + INFO("NON-AB: Do not read DAUTH!\n"); + *flags = ROTPK_NOT_DEPLOYED; + ret = 0; + + } else if ((sbl_status() == SBL_ENABLED) && + (mmio_read_32(BL11_DAUTH_BASE) == BL11_DAUTH_ID)) { + + /* Read hash from BL11 */ + INFO("readKeys (DAUTH) from BL11\n"); + + memcpy(dst, + (void *)(BL11_DAUTH_BASE + sizeof(uint32_t)), + SHA256_BYTES); + + for (i = 0; i < SHA256_BYTES; i++) + if (dst[i] != 0) + break; + + if (i >= SHA256_BYTES) + ERROR("Hash not valid from BL11\n"); + else + ret = 0; + + } else if (sotp_key_erased()) { + + memcpy(dst, plat_rotpk_hash, SHA256_BYTES); + + INFO("SOTP erased, Use internal key hash.\n"); + ret = 0; + + } else if (plat_fast_auth_enabled()) { + + INFO("AB DEV: FAST AUTH!\n"); + *flags = ROTPK_NOT_DEPLOYED; + ret = 0; + + } else if (!(mmio_read_32(SOTP_STATUS_1) & SOTP_DAUTH_ECC_ERROR_MASK)) { + + /* Read hash from SOTP */ + ret = sotp_read_key(dst, + SHA256_BYTES, + SOTP_DAUTH_ROW, + SOTP_K_HMAC_ROW-1); + + INFO("sotp_read_key (DAUTH): %i\n", ret); + + } else { + + uint64_t row_data; + uint32_t k; + + for (k = 0; k < (SOTP_K_HMAC_ROW - SOTP_DAUTH_ROW); k++) { + row_data = sotp_mem_read(SOTP_DAUTH_ROW + k, + SOTP_ROW_NO_ECC); + + if (row_data != 0) + break; + } + + if (k == (SOTP_K_HMAC_ROW - SOTP_DAUTH_ROW)) { + INFO("SOTP NOT PROGRAMMED: Do not use DAUTH!\n"); + + if (sotp_mem_read(SOTP_ATF2_CFG_ROW_ID, + SOTP_ROW_NO_ECC) & SOTP_ROMKEY_MASK) { + memcpy(dst, plat_rotpk_hash, SHA256_BYTES); + + INFO("Use internal key hash.\n"); + ret = 0; + } else { + *flags = ROTPK_NOT_DEPLOYED; + ret = 0; + } + } else { + INFO("No hash found in SOTP\n"); + } + } + if (ret) + return ret; +} +#endif + + *key_ptr = (void *)rotpk_hash_der; + *key_len = (unsigned int)sizeof(rotpk_hash_der); + *flags |= ROTPK_IS_HASH; + + return 0; +} + +#define SOTP_NUM_BITS_PER_ROW 41 +#define SOTP_NVCTR_ROW_ALL_ONES 0x1ffffffffff +#define SOTP_NVCTR_TRUSTED_IN_USE \ + ((uint64_t)0x3 << (SOTP_NUM_BITS_PER_ROW-2)) +#define SOTP_NVCTR_NON_TRUSTED_IN_USE ((uint64_t)0x3) +#define SOTP_NVCTR_TRUSTED_NEAR_END SOTP_NVCTR_NON_TRUSTED_IN_USE +#define SOTP_NVCTR_NON_TRUSTED_NEAR_END SOTP_NVCTR_TRUSTED_IN_USE + +#define SOTP_NVCTR_ROW_START 64 +#define SOTP_NVCTR_ROW_END 75 + +/* + * SOTP NVCTR are stored in section 10 of SOTP (rows 64-75). + * Each row of SOTP is 41 bits. + * NVCTR's are stored in a bitstream format. + * We are tolerant to consecutive bit errors. + * Trusted NVCTR starts at the top of row 64 in bitstream format. + * Non Trusted NVCTR starts at the bottom of row 75 in reverse bitstream. + * Each row can only be used by 1 of the 2 counters. This is determined + * by 2 zeros remaining at the beginning or end of the last available row. + * If one counter has already starting using a row, the other will be + * prevent from writing to that row. + * + * Example counter values for SOTP programmed below: + * Trusted Counter (rows64-69) = 5 * 41 + 40 = 245 + * NonTrusted Counter (row75-71) = 3 * 41 + 4 = 127 + * 40 39 38 37 36 ..... 5 4 3 2 1 0 + * row 64 1 1 1 1 1 1 1 1 1 1 1 + * row 65 1 1 1 1 1 1 1 1 1 1 1 + * row 66 1 1 1 1 1 1 1 1 1 1 1 + * row 67 1 1 1 1 1 1 1 1 1 1 1 + * row 68 1 1 1 1 1 1 1 1 1 1 1 + * row 69 1 1 1 1 1 1 1 1 1 1 0 + * row 71 0 0 0 0 0 0 0 0 0 0 0 + * row 71 0 0 0 0 0 0 0 0 0 0 0 + * row 71 0 0 0 0 0 0 0 1 1 1 1 + * row 73 1 1 1 1 1 1 1 1 1 1 1 + * row 74 1 1 1 1 1 1 1 1 1 1 1 + * row 75 1 1 1 1 1 1 1 1 1 1 1 + * + */ + +#if (DEBUG == 1) +/* + * Dump sotp rows + */ +void sotp_dump_rows(uint32_t start_row, uint32_t end_row) +{ + int32_t rownum; + uint64_t rowdata; + + for (rownum = start_row; rownum <= end_row; rownum++) { + rowdata = sotp_mem_read(rownum, SOTP_ROW_NO_ECC); + INFO("%d 0x%llx\n", rownum, rowdata); + } +} +#endif + +/* + * Get SOTP Trusted nvctr + */ +unsigned int sotp_get_trusted_nvctr(void) +{ + uint64_t rowdata; + uint64_t nextrowdata; + uint32_t rownum; + unsigned int nvctr; + + rownum = SOTP_NVCTR_ROW_START; + nvctr = SOTP_NUM_BITS_PER_ROW; + + /* + * Determine what row has last valid data for trusted ctr + */ + rowdata = sotp_mem_read(rownum, SOTP_ROW_NO_ECC); + while ((rowdata & SOTP_NVCTR_TRUSTED_IN_USE) && + (rowdata & SOTP_NVCTR_TRUSTED_NEAR_END) && + (rownum < SOTP_NVCTR_ROW_END)) { + /* + * Current row in use and has data in last 2 bits as well. + * Check if next row also has data for this counter + */ + nextrowdata = sotp_mem_read(rownum+1, SOTP_ROW_NO_ECC); + if (nextrowdata & SOTP_NVCTR_TRUSTED_IN_USE) { + /* Next row also has data so increment rownum */ + rownum++; + nvctr += SOTP_NUM_BITS_PER_ROW; + rowdata = nextrowdata; + } else { + /* Next row does not have data */ + break; + } + } + + if (rowdata & SOTP_NVCTR_TRUSTED_IN_USE) { + while ((rowdata & 0x1) == 0) { + nvctr--; + rowdata >>= 1; + } + } else + nvctr -= SOTP_NUM_BITS_PER_ROW; + + INFO("CTR %i\n", nvctr); + return nvctr; +} + +/* + * Get SOTP NonTrusted nvctr + */ +unsigned int sotp_get_nontrusted_nvctr(void) +{ + uint64_t rowdata; + uint64_t nextrowdata; + uint32_t rownum; + unsigned int nvctr; + + nvctr = SOTP_NUM_BITS_PER_ROW; + rownum = SOTP_NVCTR_ROW_END; + + /* + * Determine what row has last valid data for nontrusted ctr + */ + rowdata = sotp_mem_read(rownum, SOTP_ROW_NO_ECC); + while ((rowdata & SOTP_NVCTR_NON_TRUSTED_NEAR_END) && + (rowdata & SOTP_NVCTR_NON_TRUSTED_IN_USE) && + (rownum > SOTP_NVCTR_ROW_START)) { + /* + * Current row in use and has data in last 2 bits as well. + * Check if next row also has data for this counter + */ + nextrowdata = sotp_mem_read(rownum-1, SOTP_ROW_NO_ECC); + if (nextrowdata & SOTP_NVCTR_NON_TRUSTED_IN_USE) { + /* Next row also has data so decrement rownum */ + rownum--; + nvctr += SOTP_NUM_BITS_PER_ROW; + rowdata = nextrowdata; + } else { + /* Next row does not have data */ + break; + } + } + + if (rowdata & SOTP_NVCTR_NON_TRUSTED_IN_USE) { + while ((rowdata & ((uint64_t)0x1 << (SOTP_NUM_BITS_PER_ROW-1))) + == + 0) { + nvctr--; + rowdata <<= 1; + } + } else + nvctr -= SOTP_NUM_BITS_PER_ROW; + + INFO("NCTR %i\n", nvctr); + return nvctr; +} + +/* + * Set SOTP Trusted nvctr + */ +int sotp_set_trusted_nvctr(unsigned int nvctr) +{ + int numrows_available; + uint32_t nontrusted_rownum; + uint32_t trusted_rownum; + uint64_t rowdata; + unsigned int maxnvctr; + + /* + * Read SOTP to find out how many rows are used by the + * NON Trusted nvctr + */ + nontrusted_rownum = SOTP_NVCTR_ROW_END; + do { + rowdata = sotp_mem_read(nontrusted_rownum, SOTP_ROW_NO_ECC); + if (rowdata & SOTP_NVCTR_NON_TRUSTED_IN_USE) + nontrusted_rownum--; + else + break; + } while (nontrusted_rownum >= SOTP_NVCTR_ROW_START); + + /* + * Calculate maximum value we can have for nvctr based on + * number of available rows. + */ + numrows_available = nontrusted_rownum - SOTP_NVCTR_ROW_START + 1; + maxnvctr = numrows_available * SOTP_NUM_BITS_PER_ROW; + if (maxnvctr) { + /* + * Last 2 bits of counter can't be written or it will + * overflow with nontrusted counter + */ + maxnvctr -= 2; + } + + if (nvctr > maxnvctr) { + /* Error - not enough room */ + WARN("tctr not set\n"); + return 1; + } + + /* + * It is safe to write the nvctr, fill all 1's up to the + * last row and then fill the last row with partial bitstream + */ + trusted_rownum = SOTP_NVCTR_ROW_START; + rowdata = SOTP_NVCTR_ROW_ALL_ONES; + + while (nvctr >= SOTP_NUM_BITS_PER_ROW) { + sotp_mem_write(trusted_rownum, SOTP_ROW_NO_ECC, rowdata); + nvctr -= SOTP_NUM_BITS_PER_ROW; + trusted_rownum++; + } + rowdata <<= (SOTP_NUM_BITS_PER_ROW - nvctr); + sotp_mem_write(trusted_rownum, SOTP_ROW_NO_ECC, rowdata); + return 0; +} + +/* + * Set SOTP NonTrusted nvctr + */ +int sotp_set_nontrusted_nvctr(unsigned int nvctr) +{ + int numrows_available; + uint32_t nontrusted_rownum; + uint32_t trusted_rownum; + uint64_t rowdata; + unsigned int maxnvctr; + + /* + * Read SOTP to find out how many rows are used by the + * Trusted nvctr + */ + trusted_rownum = SOTP_NVCTR_ROW_START; + do { + rowdata = sotp_mem_read(trusted_rownum, SOTP_ROW_NO_ECC); + if (rowdata & SOTP_NVCTR_TRUSTED_IN_USE) + trusted_rownum++; + else + break; + } while (trusted_rownum <= SOTP_NVCTR_ROW_END); + + /* + * Calculate maximum value we can have for nvctr based on + * number of available rows. + */ + numrows_available = SOTP_NVCTR_ROW_END - trusted_rownum + 1; + maxnvctr = numrows_available * SOTP_NUM_BITS_PER_ROW; + if (maxnvctr) { + /* + * Last 2 bits of counter can't be written or it will + * overflow with nontrusted counter + */ + maxnvctr -= 2; + } + + if (nvctr > maxnvctr) { + /* Error - not enough room */ + WARN("nctr not set\n"); + return 1; + } + + /* + * It is safe to write the nvctr, fill all 1's up to the + * last row and then fill the last row with partial bitstream + */ + nontrusted_rownum = SOTP_NVCTR_ROW_END; + rowdata = SOTP_NVCTR_ROW_ALL_ONES; + + while (nvctr >= SOTP_NUM_BITS_PER_ROW) { + sotp_mem_write(nontrusted_rownum, SOTP_ROW_NO_ECC, rowdata); + nvctr -= SOTP_NUM_BITS_PER_ROW; + nontrusted_rownum--; + } + rowdata >>= (SOTP_NUM_BITS_PER_ROW - nvctr); + sotp_mem_write(nontrusted_rownum, SOTP_ROW_NO_ECC, rowdata); + return 0; +} + +/* + * Return the non-volatile counter value stored in the platform. The cookie + * will contain the OID of the counter in the certificate. + * + * Return: 0 = success, Otherwise = error + */ +int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr) +{ + const char *oid; + + assert(cookie != NULL); + assert(nv_ctr != NULL); + + *nv_ctr = 0; + if ((sotp_mem_read(SOTP_ATF_CFG_ROW_ID, SOTP_ROW_NO_ECC) & + SOTP_ATF_NVCOUNTER_ENABLE_MASK)) { + oid = (const char *)cookie; + if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) + *nv_ctr = sotp_get_trusted_nvctr(); + else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) + *nv_ctr = sotp_get_nontrusted_nvctr(); + else + return 1; + } + return 0; +} + +/* + * Store a new non-volatile counter value. + * + * Return: 0 = success, Otherwise = error + */ +int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr) +{ + const char *oid; + + if (sotp_mem_read(SOTP_ATF_CFG_ROW_ID, SOTP_ROW_NO_ECC) & + SOTP_ATF_NVCOUNTER_ENABLE_MASK) { + INFO("set CTR %i\n", nv_ctr); + oid = (const char *)cookie; + if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) + return sotp_set_trusted_nvctr(nv_ctr); + else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) + return sotp_set_nontrusted_nvctr(nv_ctr); + return 1; + } + return 0; +} + +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/brcm/board/common/board_common.mk b/plat/brcm/board/common/board_common.mk index 7c9cf77d3..3a879de5b 100644 --- a/plat/brcm/board/common/board_common.mk +++ b/plat/brcm/board/common/board_common.mk @@ -28,6 +28,17 @@ SYSCNT_FREQ := $(GENTIMER_ACTUAL_CLOCK) $(eval $(call add_define,SYSCNT_FREQ)) endif +# By default, Trusted Watchdog is always enabled unless SPIN_ON_BL1_EXIT is set +ifeq (${BRCM_DISABLE_TRUSTED_WDOG},) +BRCM_DISABLE_TRUSTED_WDOG := 0 +endif +ifeq (${SPIN_ON_BL1_EXIT}, 1) +BRCM_DISABLE_TRUSTED_WDOG := 1 +endif + +$(eval $(call assert_boolean,BRCM_DISABLE_TRUSTED_WDOG)) +$(eval $(call add_define,BRCM_DISABLE_TRUSTED_WDOG)) + # Process ARM_BL31_IN_DRAM flag ifeq (${ARM_BL31_IN_DRAM},) ARM_BL31_IN_DRAM := 0 @@ -36,6 +47,7 @@ $(eval $(call assert_boolean,ARM_BL31_IN_DRAM)) $(eval $(call add_define,ARM_BL31_IN_DRAM)) ifeq (${STANDALONE_BL2},yes) +BL2_LOG_LEVEL := 40 $(eval $(call add_define,MMU_DISABLED)) endif @@ -45,6 +57,29 @@ ifeq (${RUN_BL2_FROM_QSPI},1) $(eval $(call add_define,RUN_BL2_FROM_QSPI)) endif +# BL2 XIP from NAND +RUN_BL2_FROM_NAND := 0 +ifeq (${RUN_BL2_FROM_NAND},1) +$(eval $(call add_define,RUN_BL2_FROM_NAND)) +endif + +ifneq (${ELOG_AP_UART_LOG_BASE},) +$(eval $(call add_define,ELOG_AP_UART_LOG_BASE)) +endif + +ifeq (${ELOG_SUPPORT},1) +ifeq (${ELOG_STORE_MEDIA},DDR) +$(eval $(call add_define,ELOG_STORE_MEDIA_DDR)) +ifneq (${ELOG_STORE_OFFSET},) +$(eval $(call add_define,ELOG_STORE_OFFSET)) +endif +endif +endif + +ifneq (${BL2_LOG_LEVEL},) +$(eval $(call add_define,BL2_LOG_LEVEL)) +endif + # Use CRMU SRAM from iHOST ifneq (${USE_CRMU_SRAM},) $(eval $(call add_define,USE_CRMU_SRAM)) @@ -63,15 +98,18 @@ PLAT_INCLUDES += -Iplat/brcm/board/common \ PLAT_BL_COMMON_SOURCES += plat/brcm/common/brcm_common.c \ plat/brcm/board/common/cmn_sec.c \ plat/brcm/board/common/bcm_console.c \ + plat/brcm/board/common/brcm_mbedtls.c \ plat/brcm/board/common/plat_setup.c \ plat/brcm/board/common/platform_common.c \ drivers/arm/sp804/sp804_delay_timer.c \ + drivers/brcm/sotp.c \ drivers/delay_timer/delay_timer.c \ drivers/io/io_fip.c \ drivers/io/io_memmap.c \ drivers/io/io_storage.c \ plat/brcm/common/brcm_io_storage.c \ plat/brcm/board/common/err.c \ + plat/brcm/board/common/sbl_util.c \ drivers/arm/sp805/sp805.c BL2_SOURCES += plat/brcm/common/brcm_bl2_mem_params_desc.c \ @@ -82,6 +120,88 @@ BL2_SOURCES += plat/brcm/common/brcm_bl2_setup.c BL31_SOURCES += plat/brcm/common/brcm_bl31_setup.c +ifeq (${BCM_ELOG},yes) +ELOG_SOURCES += plat/brcm/board/common/bcm_elog.c +BL2_SOURCES += ${ELOG_SOURCES} +endif + +ifeq (${DRIVER_OCOTP_ENABLE},1) +$(eval $(call add_define,DRIVER_OCOTP_ENABLE)) +BL2_SOURCES += drivers/brcm/ocotp.c +endif + +# Enable FRU table support +ifeq (${USE_FRU},yes) +$(eval $(call add_define,USE_FRU)) +BL2_SOURCES += drivers/brcm/fru.c +endif + +# Enable GPIO support +ifeq (${USE_GPIO},yes) +$(eval $(call add_define,USE_GPIO)) +BL2_SOURCES += drivers/gpio/gpio.c +BL2_SOURCES += drivers/brcm/iproc_gpio.c +ifeq (${GPIO_SUPPORT_FLOAT_DETECTION},yes) +$(eval $(call add_define,GPIO_SUPPORT_FLOAT_DETECTION)) +endif +endif + +# Include mbedtls if it can be located +MBEDTLS_DIR := mbedtls +MBEDTLS_CHECK := $(shell find ${MBEDTLS_DIR}/include -name '${MBEDTLS_DIR}') + +ifneq (${MBEDTLS_CHECK},) +$(info Found mbedTLS at ${MBEDTLS_DIR}) +PLAT_INCLUDES += -I${MBEDTLS_DIR}/include/mbedtls +# Specify mbedTLS configuration file +MBEDTLS_CONFIG_FILE := "" + +# By default, use RSA keys +KEY_ALG := rsa_1_5 + +# Include common TBB sources +AUTH_SOURCES += drivers/auth/auth_mod.c \ + drivers/auth/crypto_mod.c \ + drivers/auth/img_parser_mod.c \ + drivers/auth/tbbr/tbbr_cot.c + +BL2_SOURCES += ${AUTH_SOURCES} + +# Use ATF framework for MBEDTLS +TRUSTED_BOARD_BOOT := 1 +CRYPTO_LIB_MK := drivers/auth/mbedtls/mbedtls_crypto.mk +IMG_PARSER_LIB_MK := drivers/auth/mbedtls/mbedtls_x509.mk +$(info Including ${CRYPTO_LIB_MK}) +include ${CRYPTO_LIB_MK} +$(info Including ${IMG_PARSER_LIB_MK}) +include ${IMG_PARSER_LIB_MK} + +# Use ATF secure boot functions +# Use Hardcoded hash for devel + +ARM_ROTPK_LOCATION=arm_rsa +ifeq (${ARM_ROTPK_LOCATION}, arm_rsa) +ARM_ROTPK_LOCATION_ID=ARM_ROTPK_DEVEL_RSA_ID +ROT_KEY=plat/arm/board/common/rotpk/arm_rotprivk_rsa.pem +else ifeq (${ARM_ROTPK_LOCATION}, brcm_rsa) +ARM_ROTPK_LOCATION_ID=BRCM_ROTPK_SOTP_RSA_ID +ifeq (${ROT_KEY},) +ROT_KEY=plat/brcm/board/common/rotpk/rsa_dauth2048_key.pem +endif +KEY_FIND := $(shell m="${ROT_KEY}"; [ -f "$$m" ] && echo "$$m") +ifeq (${KEY_FIND},) +$(error Error: No ${ROT_KEY} located) +else +$(info Using ROT_KEY: ${ROT_KEY}) +endif +else +$(error "Unsupported ARM_ROTPK_LOCATION value") +endif + +$(eval $(call add_define,ARM_ROTPK_LOCATION_ID)) +PLAT_BL_COMMON_SOURCES+=plat/brcm/board/common/board_arm_trusted_boot.c +endif + #M0 runtime firmware ifdef SCP_BL2 $(eval $(call add_define,NEED_SCP_BL2)) diff --git a/plat/brcm/board/common/brcm_mbedtls.c b/plat/brcm/board/common/brcm_mbedtls.c new file mode 100644 index 000000000..af42b861b --- /dev/null +++ b/plat/brcm/board/common/brcm_mbedtls.c @@ -0,0 +1,12 @@ +/* + * Copyright 2015 - 2020 Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +void tls_exit(int code) +{ + INFO("%s: 0x%x\n", __func__, code); +} diff --git a/plat/brcm/board/common/chip_id.h b/plat/brcm/board/common/chip_id.h new file mode 100644 index 000000000..842ac1f88 --- /dev/null +++ b/plat/brcm/board/common/chip_id.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2017 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CHIP_ID_H +#define CHIP_ID_H + +#include + +#include + +#define CHIP_REV_MAJOR_MASK 0xF0 +#define CHIP_REV_MAJOR_AX 0x00 +#define CHIP_REV_MAJOR_BX 0x10 +#define CHIP_REV_MAJOR_CX 0x20 +#define CHIP_REV_MAJOR_DX 0x30 + +/* Get Chip ID (product number) of the chip */ +static inline unsigned int chip_get_product_id(void) +{ + return PLAT_CHIP_ID_GET; +} + +/* Get Revision ID (major and minor) number of the chip */ +static inline unsigned int chip_get_rev_id(void) +{ + return PLAT_CHIP_REV_GET; +} + +static inline unsigned int chip_get_rev_id_major(void) +{ + return (chip_get_rev_id() & CHIP_REV_MAJOR_MASK); +} + +#endif diff --git a/plat/brcm/board/common/cmn_plat_def.h b/plat/brcm/board/common/cmn_plat_def.h index 41d922259..8aa7fd453 100644 --- a/plat/brcm/board/common/cmn_plat_def.h +++ b/plat/brcm/board/common/cmn_plat_def.h @@ -7,6 +7,56 @@ #ifndef CMN_PLAT_DEF_H #define CMN_PLAT_DEF_H +#include + +#ifndef GET_LOG_LEVEL +#define GET_LOG_LEVEL() LOG_LEVEL +#endif + +#ifndef SET_LOG_LEVEL +#define SET_LOG_LEVEL(x) ((void)(x)) +#endif + +#define PLAT_LOG_NOTICE(...) \ + do { \ + if (GET_LOG_LEVEL() >= LOG_LEVEL_NOTICE) { \ + bcm_elog(LOG_MARKER_NOTICE __VA_ARGS__); \ + tf_log(LOG_MARKER_NOTICE __VA_ARGS__); \ + } \ + } while (0) + +#define PLAT_LOG_ERROR(...) \ + do { \ + if (GET_LOG_LEVEL() >= LOG_LEVEL_ERROR) { \ + bcm_elog(LOG_MARKER_ERROR, __VA_ARGS__); \ + tf_log(LOG_MARKER_ERROR __VA_ARGS__); \ + } \ + } while (0) + +#define PLAT_LOG_WARN(...) \ + do { \ + if (GET_LOG_LEVEL() >= LOG_LEVEL_WARNING) { \ + bcm_elog(LOG_MARKER_WARNING, __VA_ARGS__);\ + tf_log(LOG_MARKER_WARNING __VA_ARGS__); \ + } \ + } while (0) + +#define PLAT_LOG_INFO(...) \ + do { \ + if (GET_LOG_LEVEL() >= LOG_LEVEL_INFO) { \ + bcm_elog(LOG_MARKER_INFO __VA_ARGS__); \ + tf_log(LOG_MARKER_INFO __VA_ARGS__); \ + } \ + } while (0) + +#define PLAT_LOG_VERBOSE(...) \ + do { \ + if (GET_LOG_LEVEL() >= LOG_LEVEL_VERBOSE) { \ + bcm_elog(LOG_MARKER_VERBOSE __VA_ARGS__);\ + tf_log(LOG_MARKER_VERBOSE __VA_ARGS__); \ + } \ + } while (0) + /* Print file and line number on assert */ #define PLAT_LOG_LEVEL_ASSERT LOG_LEVEL_INFO diff --git a/plat/brcm/board/common/platform_common.c b/plat/brcm/board/common/platform_common.c index 9bae83aa9..f4c9a738f 100644 --- a/plat/brcm/board/common/platform_common.c +++ b/plat/brcm/board/common/platform_common.c @@ -6,14 +6,65 @@ #include #include +#include #include #include uint32_t boot_source_get(void) { - /* For now return BOOT_SOURCE_QSPI */ - return BOOT_SOURCE_QSPI; + uint32_t data; + +#ifdef FORCE_BOOTSOURCE + data = FORCE_BOOTSOURCE; +#else + /* Read primary boot strap from CRMU persistent registers */ + data = mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG1); + if (data & BOOT_SOURCE_SOFT_ENABLE_MASK) { + data >>= BOOT_SOURCE_SOFT_DATA_OFFSET; + } else { + uint64_t sotp_atf_row; + + sotp_atf_row = + sotp_mem_read(SOTP_ATF_CFG_ROW_ID, SOTP_ROW_NO_ECC); + + if (sotp_atf_row & SOTP_BOOT_SOURCE_ENABLE_MASK) { + /* Construct the boot source based on SOTP bits */ + data = 0; + if (sotp_atf_row & SOTP_BOOT_SOURCE_BITS0) + data |= 0x1; + if (sotp_atf_row & SOTP_BOOT_SOURCE_BITS1) + data |= 0x2; + if (sotp_atf_row & SOTP_BOOT_SOURCE_BITS2) + data |= 0x4; + } else { + + /* + * This path is for L0 reset with + * Primary Boot source disabled in SOTP. + * BOOT_SOURCE_FROM_PR_ON_L1 compile flag will allow + * to never come back here so that the + * external straps will not be read on L1 reset. + */ + + /* Use the external straps */ + data = mmio_read_32(ROM_S0_IDM_IO_STATUS); + +#ifdef BOOT_SOURCE_FROM_PR_ON_L1 + /* Enable boot source read from PR#1 */ + mmio_setbits_32(CRMU_IHOST_SW_PERSISTENT_REG1, + BOOT_SOURCE_SOFT_ENABLE_MASK); + + /* set boot source */ + data &= BOOT_SOURCE_MASK; + mmio_clrsetbits_32(CRMU_IHOST_SW_PERSISTENT_REG1, + BOOT_SOURCE_MASK << BOOT_SOURCE_SOFT_DATA_OFFSET, + data << BOOT_SOURCE_SOFT_DATA_OFFSET); +#endif + } + } +#endif + return (data & BOOT_SOURCE_MASK); } void __dead2 plat_soft_reset(uint32_t reset) diff --git a/plat/brcm/board/common/sbl_util.c b/plat/brcm/board/common/sbl_util.c new file mode 100644 index 000000000..06e5b33b7 --- /dev/null +++ b/plat/brcm/board/common/sbl_util.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2015 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include + +#include +#include +#include + +#pragma weak plat_sbl_status + +int plat_sbl_status(uint64_t sbl_status) +{ + return sbl_status ? 1:0; +} + +int sbl_status(void) +{ + uint64_t sbl_sotp = 0; + int ret = SBL_DISABLED; + + sbl_sotp = sotp_mem_read(SOTP_ATF_CFG_ROW_ID, SOTP_ROW_NO_ECC); + + if (sbl_sotp != SOTP_ECC_ERR_DETECT) { + + sbl_sotp &= SOTP_SBL_MASK; + + if (plat_sbl_status(sbl_sotp)) + ret = SBL_ENABLED; + } + + VERBOSE("SBL status: %d\n", ret); + + return ret; +} diff --git a/plat/brcm/board/common/sbl_util.h b/plat/brcm/board/common/sbl_util.h new file mode 100644 index 000000000..07473895e --- /dev/null +++ b/plat/brcm/board/common/sbl_util.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2015 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SBL_UTIL_H +#define SBL_UTIL_H + +#include + +#include + +#define SBL_DISABLED 0 +#define SBL_ENABLED 1 + +int sbl_status(void); + +#endif /* #ifdef SBL_UTIL_H */ diff --git a/plat/brcm/board/stingray/bcm958742t-ns3.mk b/plat/brcm/board/stingray/bcm958742t-ns3.mk index f6df3b7af..5164eeb5c 100644 --- a/plat/brcm/board/stingray/bcm958742t-ns3.mk +++ b/plat/brcm/board/stingray/bcm958742t-ns3.mk @@ -14,3 +14,9 @@ include plat/brcm/board/stingray/bcm958742t.mk ifneq (${BL33_OVERRIDE_LOAD_ADDR},) $(eval $(call add_define_val,BL33_OVERRIDE_LOAD_ADDR,0xFF000000)) endif + +# Nitro DDR secure memory +# Nitro FW and config 0x8AE00000 - 0x8B000000 +# Nitro Crash dump 0x8B000000 - 0x8D000000 +DDR_NITRO_SECURE_REGION_START := 0x8AE00000 +DDR_NITRO_SECURE_REGION_END := 0x8D000000 diff --git a/plat/brcm/board/stingray/driver/ddr/soc/include/board_family.h b/plat/brcm/board/stingray/driver/ddr/soc/include/board_family.h new file mode 100644 index 000000000..b2427cf1d --- /dev/null +++ b/plat/brcm/board/stingray/driver/ddr/soc/include/board_family.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2019-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef BOARD_FAMILY_H +#define BOARD_FAMILY_H + +#if defined(DRIVER_SPD_ENABLE) && !defined(DRIVER_SPD_SPOOF) +#include +#endif + +#ifdef USE_GPIO +/* max number of supported GPIOs to construct the bitmap for board detection */ +#define MAX_NR_GPIOS 4 + +/* max GPIO bitmap value */ +#define MAX_GPIO_BITMAP_VAL (BIT(MAX_NR_GPIOS) - 1) +#endif + +struct mcb_ref_group { + uint32_t mcb_ref; + unsigned int *mcb_cfg; +}; + +#define MCB_REF_GROUP(ref) \ +{ \ + .mcb_ref = 0x ## ref, \ + .mcb_cfg = mcb_ ## ref, \ +} + +#endif diff --git a/plat/brcm/board/stingray/driver/ext_sram_init/ext_sram_init.c b/plat/brcm/board/stingray/driver/ext_sram_init/ext_sram_init.c new file mode 100644 index 000000000..74d207735 --- /dev/null +++ b/plat/brcm/board/stingray/driver/ext_sram_init/ext_sram_init.c @@ -0,0 +1,302 @@ +/* + * Copyright (c) 2016-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include +#include + +#include + +static void brcm_stingray_pnor_pinmux_init(void) +{ + unsigned int i; + + INFO(" - pnor pinmux init start.\n"); + + /* Set PNOR_ADV_N_MODE_SEL_CONTROL.fsel = 0x2 */ + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x2dc), + MODE_SEL_CONTROL_FSEL_MASK, + MODE_SEL_CONTROL_FSEL_MODE2); + + /* Set PNOR_BAA_N_MODE_SEL_CONTROL.fsel = 0x2 */ + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x2e0), + MODE_SEL_CONTROL_FSEL_MASK, + MODE_SEL_CONTROL_FSEL_MODE2); + + /* Set PNOR_BLS_0_N_MODE_SEL_CONTROL.fsel = 0x2 */ + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x2e4), + MODE_SEL_CONTROL_FSEL_MASK, + MODE_SEL_CONTROL_FSEL_MODE2); + + /* Set PNOR_BLS_1_N_MODE_SEL_CONTROL.fsel = 0x2 */ + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x2e8), + MODE_SEL_CONTROL_FSEL_MASK, + MODE_SEL_CONTROL_FSEL_MODE2); + + /* Set PNOR_CRE_MODE_SEL_CONTROL.fsel = 0x2 */ + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x2ec), + MODE_SEL_CONTROL_FSEL_MASK, + MODE_SEL_CONTROL_FSEL_MODE2); + + /* Set PNOR_CS_2_N_MODE_SEL_CONTROL.fsel = 0x2 */ + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x2f0), + MODE_SEL_CONTROL_FSEL_MASK, + MODE_SEL_CONTROL_FSEL_MODE2); + + /* Set PNOR_CS_1_N_MODE_SEL_CONTROL.fsel = 0x2 */ + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x2f4), + MODE_SEL_CONTROL_FSEL_MASK, + MODE_SEL_CONTROL_FSEL_MODE2); + + /* Set PNOR_CS_0_N_MODE_SEL_CONTROL.fsel = 0x2 */ + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x2f8), + MODE_SEL_CONTROL_FSEL_MASK, + MODE_SEL_CONTROL_FSEL_MODE2); + + /* Set PNOR_WE_N_MODE_SEL_CONTROL.fsel = 0x2 */ + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x2fc), + MODE_SEL_CONTROL_FSEL_MASK, + MODE_SEL_CONTROL_FSEL_MODE2); + + /* Set PNOR_OE_N_MODE_SEL_CONTROL.fsel = 0x2 */ + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x300), + MODE_SEL_CONTROL_FSEL_MASK, + MODE_SEL_CONTROL_FSEL_MODE2); + + /* Set PNOR_INTR_MODE_SEL_CONTROL.fsel = 0x2 */ + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x304), + MODE_SEL_CONTROL_FSEL_MASK, + MODE_SEL_CONTROL_FSEL_MODE2); + + /* Set PNOR_DAT_x_MODE_SEL_CONTROL.fsel = 0x2 */ + for (i = 0; i < 0x40; i += 0x4) { + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x308 + i), + MODE_SEL_CONTROL_FSEL_MASK, + MODE_SEL_CONTROL_FSEL_MODE2); + } + + /* Set NAND_CE1_N_MODE_SEL_CONTROL.fsel = 0x2 */ + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x348), + MODE_SEL_CONTROL_FSEL_MASK, + MODE_SEL_CONTROL_FSEL_MODE2); + + /* Set NAND_CE0_N_MODE_SEL_CONTROL.fsel = 0x2 */ + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x34c), + MODE_SEL_CONTROL_FSEL_MASK, + MODE_SEL_CONTROL_FSEL_MODE2); + + /* Set NAND_WE_N_MODE_SEL_CONTROL.fsel = 0x2 */ + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x350), + MODE_SEL_CONTROL_FSEL_MASK, + MODE_SEL_CONTROL_FSEL_MODE2); + + /* Set NAND_WP_N_MODE_SEL_CONTROL.fsel = 0x2 */ + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x354), + MODE_SEL_CONTROL_FSEL_MASK, + MODE_SEL_CONTROL_FSEL_MODE2); + + /* Set NAND_RE_N_MODE_SEL_CONTROL.fsel = 0x2 */ + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x358), + MODE_SEL_CONTROL_FSEL_MASK, + MODE_SEL_CONTROL_FSEL_MODE2); + + /* Set NAND_RDY_BSY_N_MODE_SEL_CONTROL.fsel = 0x2 */ + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x35c), + MODE_SEL_CONTROL_FSEL_MASK, + MODE_SEL_CONTROL_FSEL_MODE2); + + /* Set NAND_IOx_0_MODE_SEL_CONTROL.fsel = 0x2 */ + for (i = 0; i < 0x40; i += 0x4) { + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x360 + i), + MODE_SEL_CONTROL_FSEL_MASK, + MODE_SEL_CONTROL_FSEL_MODE2); + } + + /* Set NAND_ALE_MODE_SEL_CONTROL.fsel = 0x2 */ + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x3a0), + MODE_SEL_CONTROL_FSEL_MASK, + MODE_SEL_CONTROL_FSEL_MODE2); + + /* Set NAND_CLE_MODE_SEL_CONTROL.fsel = 0x2 */ + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x3a4), + MODE_SEL_CONTROL_FSEL_MASK, + MODE_SEL_CONTROL_FSEL_MODE2); + + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x40), (7 << 1), 0x8); + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x44), (7 << 1), 0x8); + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x48), (7 << 1), 0x8); + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x4c), (7 << 1), 0x8); + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x50), (7 << 1), 0x8); + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x54), (7 << 1), 0x8); + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x58), (7 << 1), 0x8); + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x5c), (7 << 1), 0x8); + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x60), (7 << 1), 0x8); + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x64), (7 << 1), 0x8); + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x68), (7 << 1), 0x8); + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x6c), (7 << 1), 0x8); + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x70), (7 << 1), 0x8); + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x74), (7 << 1), 0x8); + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x78), (7 << 1), 0x8); + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x7c), (7 << 1), 0x8); + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x80), (7 << 1), 0x8); + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x84), (7 << 1), 0x8); + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x88), (7 << 1), 0x8); + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x8c), (7 << 1), 0x8); + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x90), (7 << 1), 0x8); + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x94), (7 << 1), 0x8); + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x98), (7 << 1), 0x8); + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x9c), (7 << 1), 0x8); + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0xa0), (7 << 1), 0x8); + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0xa4), (7 << 1), 0x8); + mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0xa8), (7 << 1), 0x8); + + INFO(" - pnor pinmux init done.\n"); +} + +#if BL2_TEST_EXT_SRAM +#define SRAM_CHECKS_GRANUL 0x100000 +#define SRAM_CHECKS_CNT 8 +static unsigned int sram_checks[SRAM_CHECKS_CNT] = { + /* offset, magic */ + 0xd00dfeed, + 0xfadebabe, + 0xc001d00d, + 0xa5a5b5b5, + 0x5a5a5b5b, + 0xc5c5d5d5, + 0x5c5c5d5d, + 0xe5e5f5f5, +}; +#endif + +static void brcm_stingray_pnor_sram_init(void) +{ + unsigned int val, tmp; +#if BL2_TEST_EXT_SRAM + unsigned int off, i; +#endif + INFO(" - pnor sram init start.\n"); + + /* Enable PNOR Clock */ + INFO(" -- enable pnor clock\n"); + mmio_write_32((uintptr_t)(PNOR_IDM_IO_CONTROL_DIRECT), 0x1); + udelay(500); + + /* Reset PNOR */ + INFO(" -- reset pnor\n"); + mmio_setbits_32((uintptr_t)(PNOR_IDM_IO_RESET_CONTROL), 0x1); + udelay(500); + mmio_clrbits_32((uintptr_t)(PNOR_IDM_IO_RESET_CONTROL), 0x1); + udelay(500); + + /* Configure slave address to chip-select mapping */ + INFO(" -- configure pnor slave address to chip-select mapping\n"); + /* 0x74000000-0x75ffffff => CS0 (32MB) */ + val = (0xfe << PNOR_ICFG_CS_x_MASK0_SHIFT); + val |= (0x74); + mmio_write_32((uintptr_t)(PNOR_ICFG_CS_0), val); + /* 0x76000000-0x77ffffff => CS1 (32MB) */ + val = (0xfe << PNOR_ICFG_CS_x_MASK0_SHIFT); + val |= (0x76); + mmio_write_32((uintptr_t)(PNOR_ICFG_CS_1), val); + /* 0xffffffff-0xffffffff => CS2 (0MB) */ + val = (0x00 << PNOR_ICFG_CS_x_MASK0_SHIFT); + val |= (0xff); + mmio_write_32((uintptr_t)(PNOR_ICFG_CS_2), val); + + /* Print PNOR ID */ + tmp = 0x0; + val = mmio_read_32((uintptr_t)(PNOR_REG_PERIPH_ID0)); + tmp |= (val & PNOR_REG_PERIPH_IDx_MASK); + val = mmio_read_32((uintptr_t)(PNOR_REG_PERIPH_ID1)); + tmp |= ((val & PNOR_REG_PERIPH_IDx_MASK) << 8); + val = mmio_read_32((uintptr_t)(PNOR_REG_PERIPH_ID2)); + tmp |= ((val & PNOR_REG_PERIPH_IDx_MASK) << 16); + val = mmio_read_32((uintptr_t)(PNOR_REG_PERIPH_ID3)); + tmp |= ((val & PNOR_REG_PERIPH_IDx_MASK) << 24); + INFO(" -- pnor primecell_id = 0x%x\n", tmp); + + /* PNOR set_cycles */ +#ifdef EMULATION_SETUP + val = 0x00129A44; +#else + val = 0x00125954; /* 0x00002DEF; */ +#endif + mmio_write_32((uintptr_t)(PNOR_REG_SET_CYCLES), val); + INFO(" -- pnor set_cycles = 0x%x\n", val); + + /* PNOR set_opmode */ + val = 0x0; +#ifdef EMULATION_SETUP + /* TODO: Final values to be provided by DV folks */ + val &= ~(0x7 << 7); /* set_wr_bl */ + val &= ~(0x7 << 3); /* set_rd_bl */ + val &= ~(0x3); + val |= (0x1); /* set_mw */ +#else + /* TODO: Final values to be provided by DV folks */ + val &= ~(0x7 << 7); /* set_wr_bl */ + val &= ~(0x7 << 3); /* set_rd_bl */ + val &= ~(0x3); + val |= (0x1); /* set_mw */ +#endif + mmio_write_32((uintptr_t)(PNOR_REG_SET_OPMODE), val); + INFO(" -- pnor set_opmode = 0x%x\n", val); + +#ifndef EMULATION_SETUP + /* Actual SRAM chip will require self-refresh */ + val = 0x1; + mmio_write_32((uintptr_t)(PNOR_REG_REFRESH_0), val); + INFO(" -- pnor refresh_0 = 0x%x\n", val); +#endif + +#if BL2_TEST_EXT_SRAM + /* Check PNOR SRAM access */ + for (off = 0; off < NOR_SIZE; off += SRAM_CHECKS_GRANUL) { + i = (off / SRAM_CHECKS_GRANUL) % SRAM_CHECKS_CNT; + val = sram_checks[i]; + INFO(" -- pnor sram write addr=0x%lx value=0x%lx\n", + (unsigned long)(NOR_BASE_ADDR + off), + (unsigned long)val); + mmio_write_32((uintptr_t)(NOR_BASE_ADDR + off), val); + } + tmp = 0; + for (off = 0; off < NOR_SIZE; off += SRAM_CHECKS_GRANUL) { + i = (off / SRAM_CHECKS_GRANUL) % SRAM_CHECKS_CNT; + val = mmio_read_32((uintptr_t)(NOR_BASE_ADDR + off)); + INFO(" -- pnor sram read addr=0x%lx value=0x%lx\n", + (unsigned long)(NOR_BASE_ADDR + off), + (unsigned long)val); + if (val == sram_checks[i]) + tmp++; + } + INFO(" -- pnor sram checks pass=%d total=%d\n", + tmp, (NOR_SIZE / SRAM_CHECKS_GRANUL)); + + if (tmp != (NOR_SIZE / SRAM_CHECKS_GRANUL)) { + INFO(" - pnor sram init failed.\n"); + while (1) + ; + } else { + INFO(" - pnor sram init done.\n"); + } +#endif +} + +void ext_sram_init(void) +{ + INFO("%s start.\n", __func__); + + brcm_stingray_pnor_pinmux_init(); + + brcm_stingray_pnor_sram_init(); + + INFO("%s done.\n", __func__); +} diff --git a/plat/brcm/board/stingray/driver/ext_sram_init/ext_sram_init.h b/plat/brcm/board/stingray/driver/ext_sram_init/ext_sram_init.h new file mode 100644 index 000000000..85086538f --- /dev/null +++ b/plat/brcm/board/stingray/driver/ext_sram_init/ext_sram_init.h @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2016-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef EXT_SRAM_INIT_H +#define EXT_SRAM_INIT_H + +void ext_sram_init(void); +#endif diff --git a/plat/brcm/board/stingray/driver/swreg.c b/plat/brcm/board/stingray/driver/swreg.c new file mode 100644 index 000000000..2b7c53b53 --- /dev/null +++ b/plat/brcm/board/stingray/driver/swreg.c @@ -0,0 +1,375 @@ +/* + * Copyright (c) 2017 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#define MIN_VOLT 760000 +#define MAX_VOLT 1060000 + +#define BSTI_WRITE 0x1 +#define BSTI_READ 0x2 +#define BSTI_COMMAND_TA 0x2 +#define BSTI_COMMAND_DATA 0xFF +#define BSTI_CONTROL_VAL 0x81 +#define BSTI_CONTROL_BUSY 0x100 +#define BSTI_TOGGLE_BIT 0x2 +#define BSTI_CONFI_DONE_MASK 0xFFFFFFFD +#define BSTI_REG_DATA_MASK 0xFFFF +#define BSTI_CMD(sb, op, pa, ra, ta, data) \ + ((((sb) & 0x3) << 30) | (((op) & 0x3) << 28) | \ + (((pa) & 0x1F) << 23) | (((ra) & 0x1F) << 18) | \ + (((ta) & 0x3) << 16) | (data)) + +#define PHY_REG0 0x0 +#define PHY_REG1 0x1 +#define PHY_REG4 0x4 +#define PHY_REG5 0x5 +#define PHY_REG6 0x6 +#define PHY_REG7 0x7 +#define PHY_REGC 0xc + +#define IHOST_VDDC_DATA 0x560 +#define DDR_CORE_DATA 0x2560 +#define UPDATE_POS_EDGE(data, set) ((data) | ((set) << 1)) + +/* + * Formula for SR A2 reworked board: + * step = ((vol/(1.4117 * 0.98)) - 500000)/3125 + * where, + * vol - input voltage + * 500000 - Reference voltage + * 3125 - one step value + */ +#define A2_VOL_REF 500000 +#define ONE_STEP_VALUE 3125 +#define VOL_DIV(vol) (((vol*10000ull)/(14117*98ull)) * 100ull) +#define STEP_VALUE(vol) \ + ((((((VOL_DIV(vol)) - A2_VOL_REF) / ONE_STEP_VALUE) & 0xFF) << 8) | 4) + +#define B0_VOL_REF ((500000/100)*98) +#define B0_ONE_STEP_VALUE 3125 +/* + * Formula for SR B0 chip for IHOST12/03 and VDDC_CORE + * step = ((vol/1.56) - (500000 * 0.98))/3125 + * where, + * vol - input voltage + * 500000 - Reference voltage + * 3125 - one step value + */ +#define B0_VOL_DIV(vol) (((vol)*100ull)/156) +#define B0_STEP_VALUE(vol) \ + ((((((B0_VOL_DIV(vol)) - B0_VOL_REF) / B0_ONE_STEP_VALUE) \ + & 0xFF) << 8) | 4) + +/* + * Formula for SR B0 chip for DDR-CORE + * step = ((vol/1) - (500000 * 0.98))/3125 + * where, + * vol - input voltage + * 500000 - Reference voltage + * 3125 - one step value + */ +#define B0_DDR_VDDC_VOL_DIV(vol) ((vol)/1) +#define B0_DDR_VDDC_STEP_VALUE(vol) \ + ((((((B0_DDR_VDDC_VOL_DIV(vol)) - B0_VOL_REF) / B0_ONE_STEP_VALUE) \ + & 0xFF) << 8) | 4) + +#define MAX_SWREG_CNT 8 +#define MAX_ADDR_PER_SWREG 16 +#define MAX_REG_ADDR 0xF +#define MIN_REG_ADDR 0x0 + +static const char *sw_reg_name[MAX_SWREG_CNT] = { + "DDR_VDDC", + "IHOST03", + "IHOST12", + "IHOST_ARRAY", + "DDRIO_SLAVE", + "VDDC_CORE", + "VDDC1", + "DDRIO_MASTER" +}; + +/* firmware values for all SWREG for 3.3V input operation */ +static const uint16_t swreg_fm_data_bx[MAX_SWREG_CNT][MAX_ADDR_PER_SWREG] = { + /* DDR logic: Power Domains independent of 12v or 3p3v */ + {0x25E0, 0x2D54, 0x0EC6, 0x01EC, 0x28BB, 0x1144, 0x0200, 0x69C0, + 0x0010, 0x0EDF, 0x90D7, 0x8000, 0x820C, 0x0003, 0x0001, 0x0000}, + + /* ihost03, 3p3V */ + {0x05E0, 0x39E5, 0x03C1, 0x007C, 0x8BA9, 0x4444, 0x3300, 0x6B80, + 0x003F, 0x0FFF, 0x90D7, 0x8000, 0x240C, 0x0003, 0x0001, 0x0000}, + + /* ihost12 3p3v */ + {0x05E0, 0x39E5, 0x03C1, 0x007C, 0x8BA9, 0x4444, 0x3300, 0x6B80, + 0x003F, 0x0FFF, 0x90D7, 0x8000, 0x240C, 0x0003, 0x0001, 0x0000}, + + /* ihost array */ + {0x25E0, 0x2D94, 0x0EC6, 0x01EC, 0x2ABB, 0x1144, 0x0340, 0x69C0, + 0x0010, 0x0EDF, 0x90D7, 0x8000, 0x860C, 0x0003, 0x0001, 0x0000}, + + /* ddr io slave : 3p3v */ + {0x0560, 0x4438, 0x0000, 0x001F, 0x8028, 0x4444, 0x0300, 0x4380, + 0x003F, 0x0FFF, 0x10D7, 0x8000, 0xA70C, 0x0003, 0x0001, 0x0000}, + + /* core master 3p3v */ + {0x05E0, 0x39E5, 0x03C1, 0x007C, 0x8BA9, 0x4444, 0x3300, 0x6B80, + 0x003F, 0x0FFF, 0x90D7, 0x8000, 0x240C, 0x0003, 0x0001, 0x0000}, + + /* core slave 3p3v */ + {0x0560, 0x4438, 0x0000, 0x001F, 0x8028, 0x4444, 0x0300, 0x4380, + 0x003F, 0x0FFF, 0x10D7, 0x8000, 0x240C, 0x0003, 0x0001, 0x0000}, + + /* ddr io master : 3p3v */ + {0x05E0, 0x39E5, 0x03C1, 0x007C, 0x8BA9, 0x4444, 0x3300, 0x6B80, + 0x003F, 0x0FFF, 0x90D7, 0x8000, 0xA70C, 0x0003, 0x0001, 0x0000}, +}; + +#define FM_DATA swreg_fm_data_bx + +static int swreg_poll(void) +{ + uint32_t data; + int retry = 100; + + do { + data = mmio_read_32(BSTI_CONTROL_OFFSET); + if ((data & BSTI_CONTROL_BUSY) != BSTI_CONTROL_BUSY) + return 0; + retry--; + udelay(1); + } while (retry > 0); + + return -ETIMEDOUT; +} + +static int write_swreg_config(enum sw_reg reg_id, uint32_t addr, uint32_t data) +{ + uint32_t cmd; + int ret; + + cmd = BSTI_CMD(0x1, BSTI_WRITE, reg_id, addr, BSTI_COMMAND_TA, data); + mmio_write_32(BSTI_CONTROL_OFFSET, BSTI_CONTROL_VAL); + mmio_write_32(BSTI_COMMAND_OFFSET, cmd); + ret = swreg_poll(); + if (ret) { + ERROR("Failed to write swreg %s addr 0x%x\n", + sw_reg_name[reg_id-1], addr); + return ret; + } + return ret; +} + +static int read_swreg_config(enum sw_reg reg_id, uint32_t addr, uint32_t *data) +{ + uint32_t cmd; + int ret; + + cmd = BSTI_CMD(0x1, BSTI_READ, reg_id, addr, BSTI_COMMAND_TA, PHY_REG0); + mmio_write_32(BSTI_CONTROL_OFFSET, BSTI_CONTROL_VAL); + mmio_write_32(BSTI_COMMAND_OFFSET, cmd); + ret = swreg_poll(); + if (ret) { + ERROR("Failed to read swreg %s addr 0x%x\n", + sw_reg_name[reg_id-1], addr); + return ret; + } + + *data = mmio_read_32(BSTI_COMMAND_OFFSET); + *data &= BSTI_REG_DATA_MASK; + return ret; +} + +static int swreg_config_done(enum sw_reg reg_id) +{ + uint32_t read_data; + int ret; + + ret = read_swreg_config(reg_id, PHY_REG0, &read_data); + if (ret) + return ret; + + read_data &= BSTI_CONFI_DONE_MASK; + read_data |= BSTI_TOGGLE_BIT; + ret = write_swreg_config(reg_id, PHY_REG0, read_data); + if (ret) + return ret; + + ret = read_swreg_config(reg_id, PHY_REG0, &read_data); + if (ret) + return ret; + + read_data &= BSTI_CONFI_DONE_MASK; + ret = write_swreg_config(reg_id, PHY_REG0, read_data); + if (ret) + return ret; + + return ret; +} + +#ifdef DUMP_SWREG +static void dump_swreg_firmware(void) +{ + enum sw_reg reg_id; + uint32_t data; + int addr; + int ret; + + for (reg_id = DDR_VDDC; reg_id <= DDRIO_MASTER; reg_id++) { + INFO("SWREG: %s\n", sw_reg_name[reg_id - 1]); + for (addr = MIN_REG_ADDR; addr <= MAX_REG_ADDR; addr++) { + ret = read_swreg_config(reg_id, addr, &data); + if (ret) + ERROR("Failed to read offset %d\n", addr); + INFO("\t0x%x: 0x%04x\n", addr, data); + } + } +} +#endif + +int set_swreg(enum sw_reg reg_id, uint32_t micro_volts) +{ + uint32_t step, programmed_step; + uint32_t data = IHOST_VDDC_DATA; + int ret; + + if ((micro_volts > MAX_VOLT) || (micro_volts < MIN_VOLT)) { + ERROR("input voltage out-of-range\n"); + ret = -EINVAL; + goto failed; + } + + ret = read_swreg_config(reg_id, PHY_REGC, &programmed_step); + if (ret) + goto failed; + + if (reg_id == DDR_VDDC) + step = B0_DDR_VDDC_STEP_VALUE(micro_volts); + else + step = B0_STEP_VALUE(micro_volts); + + if ((step >> 8) != (programmed_step >> 8)) { + ret = write_swreg_config(reg_id, PHY_REGC, step); + if (ret) + goto failed; + + if (reg_id == DDR_VDDC) + data = DDR_CORE_DATA; + + ret = write_swreg_config(reg_id, PHY_REG0, + UPDATE_POS_EDGE(data, 1)); + if (ret) + goto failed; + + ret = write_swreg_config(reg_id, PHY_REG0, + UPDATE_POS_EDGE(data, 0)); + if (ret) + goto failed; + } + + INFO("%s voltage updated to %duV\n", sw_reg_name[reg_id-1], + micro_volts); + return ret; + +failed: + /* + * Stop booting if voltages are not set + * correctly. Booting will fail at random point + * if we continue with wrong voltage settings. + */ + ERROR("Failed to set %s voltage to %duV\n", sw_reg_name[reg_id-1], + micro_volts); + assert(0); + + return ret; +} + +/* Update SWREG firmware for all power doman for A2 chip */ +int swreg_firmware_update(void) +{ + enum sw_reg reg_id; + uint32_t data; + int addr; + int ret; + + /* write firmware values */ + for (reg_id = DDR_VDDC; reg_id <= DDRIO_MASTER; reg_id++) { + /* write higher location first */ + for (addr = MAX_REG_ADDR; addr >= MIN_REG_ADDR; addr--) { + ret = write_swreg_config(reg_id, addr, + FM_DATA[reg_id - 1][addr]); + if (ret) + goto exit; + } + } + + /* trigger SWREG firmware update */ + for (reg_id = DDR_VDDC; reg_id <= DDRIO_MASTER; reg_id++) { + /* + * Slave regulator doesn't have to be updated, + * Updating Master is enough + */ + if ((reg_id == DDRIO_SLAVE) || (reg_id == VDDC1)) + continue; + + ret = swreg_config_done(reg_id); + if (ret) { + ERROR("Failed to trigger SWREG firmware update for %s\n" + , sw_reg_name[reg_id-1]); + return ret; + } + } + + for (reg_id = DDR_VDDC; reg_id <= DDRIO_MASTER; reg_id++) { + /* + * IHOST_ARRAY will be used on some boards like STRATUS and + * there will not be any issue even if it is updated on other + * boards where it is not used. + */ + if (reg_id == IHOST_ARRAY) + continue; + + for (addr = MIN_REG_ADDR; addr <= MAX_REG_ADDR; addr++) { + ret = read_swreg_config(reg_id, addr, &data); + if (ret || (!ret && + (data != FM_DATA[reg_id - 1][addr]))) { + ERROR("swreg fm update failed: %s at off %d\n", + sw_reg_name[reg_id - 1], addr); + ERROR("Read val: 0x%x, expected val: 0x%x\n", + data, FM_DATA[reg_id - 1][addr]); + return -1; + } + } + } + + INFO("Updated SWREG firmware\n"); + +#ifdef DUMP_SWREG + dump_swreg_firmware(); +#endif + return ret; + +exit: + /* + * Stop booting if swreg firmware update fails. + * Booting will fail at random point if we + * continue with wrong voltage settings. + */ + ERROR("Failed to update firmware for %s SWREG\n", + sw_reg_name[reg_id-1]); + assert(0); + + return ret; +} diff --git a/plat/brcm/board/stingray/include/board_info.h b/plat/brcm/board/stingray/include/board_info.h new file mode 100644 index 000000000..89012591e --- /dev/null +++ b/plat/brcm/board/stingray/include/board_info.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2017 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef BOARD_INFO_H +#define BOARD_INFO_H + +#define IHOST_REG_INTEGRATED 0 +#define IHOST_REG_EXT_PROGRAMMABLE 1 +#define IHOST_REG_EXT_FIXED 2 + +#if defined(IHOST_REG_TYPE) + #if ((IHOST_REG_TYPE != IHOST_REG_INTEGRATED) && \ + (IHOST_REG_TYPE != IHOST_REG_EXT_PROGRAMMABLE) && \ + (IHOST_REG_TYPE != IHOST_REG_EXT_FIXED)) + #error "IHOST_REG_TYPE not valid" + #endif +#else + #define IHOST_REG_TYPE IHOST_REG_INTEGRATED +#endif + +#define VDDC_REG_INTEGRATED 0 +#define VDDC_REG_EXT_PROGRAMMABLE 1 +#define VDDC_REG_EXT_FIXED 2 + +#if defined(VDDC_REG_TYPE) + #if ((VDDC_REG_TYPE != VDDC_REG_INTEGRATED) && \ + (VDDC_REG_TYPE != VDDC_REG_EXT_PROGRAMMABLE) && \ + (VDDC_REG_TYPE != VDDC_REG_EXT_FIXED)) + #error "VDDC_REG_TYPE not valid" + #endif +#else + #define VDDC_REG_TYPE VDDC_REG_INTEGRATED +#endif + +#endif diff --git a/plat/brcm/board/stingray/include/ddr_init.h b/plat/brcm/board/stingray/include/ddr_init.h new file mode 100644 index 000000000..0c135b1d5 --- /dev/null +++ b/plat/brcm/board/stingray/include/ddr_init.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef DDR_INIT_H +#define DDR_INIT_H + +#include + +#pragma weak ddr_initialize +#pragma weak ddr_secure_region_config +#pragma weak ddr_info_save +#pragma weak get_active_ddr_channel +#pragma weak is_warmboot + +void ddr_initialize(struct ddr_info *ddr) +{ +} + +void ddr_secure_region_config(uint64_t start, uint64_t end) +{ +} + +void ddr_info_save(void) +{ +} + +unsigned char get_active_ddr_channel(void) +{ + return 0; +} + +static inline unsigned int is_warmboot(void) +{ + return 0; +} +#endif diff --git a/plat/brcm/board/stingray/include/platform_def.h b/plat/brcm/board/stingray/include/platform_def.h index d61a7378f..474212429 100644 --- a/plat/brcm/board/stingray/include/platform_def.h +++ b/plat/brcm/board/stingray/include/platform_def.h @@ -12,10 +12,8 @@ #include #include - -#include - #include "sr_def.h" +#include /* * Most platform porting definitions provided by included headers diff --git a/plat/brcm/board/stingray/include/platform_sotp.h b/plat/brcm/board/stingray/include/platform_sotp.h new file mode 100644 index 000000000..0389f3871 --- /dev/null +++ b/plat/brcm/board/stingray/include/platform_sotp.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2016-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLATFORM_SOTP_H +#define PLATFORM_SOTP_H + +#define SOTP_DEVICE_SECURE_CFG0_ROW 17 +#define SOTP_DEVICE_SECURE_CFG1_ROW 18 +#define SOTP_DEVICE_SECURE_CFG2_ROW 19 +#define SOTP_DEVICE_SECURE_CFG3_ROW 20 +#define SOTP_BRCM_SOFTWARE_CFG0_ROW 21 +#define SOTP_BRCM_SOFTWARE_CFG1_ROW 22 +#define SOTP_BRCM_SOFTWARE_CFG2_ROW 23 +#define SOTP_BRCM_SOFTWARE_CFG3_ROW 24 +#define SOTP_CUSTOMER_ID_CFG0_ROW 25 +#define SOTP_CUSTOMER_ID_CFG1_ROW 26 +#define SOTP_CUSTOMER_ID_CFG2_ROW 27 +#define SOTP_CUSTOMER_ID_CFG3_ROW 28 +#define SOTP_CUSTOMER_DEV_CFG0_ROW 29 +#define SOTP_CUSTOMER_DEV_CFG1_ROW 30 +#define SOTP_CUSTOMER_DEV_CFG2_ROW 31 +#define SOTP_CUSTOMER_DEV_CFG3_ROW 32 +#define SOTP_DAUTH_ROW 33 +#define SOTP_K_HMAC_ROW 45 +#define SOTP_K_AES_ROW 57 +#define SOTP_NVCOUNTER_ROW 69 + +#define SOTP_BRCM_CFG_ECC_ERROR_MASK 0x100000 +#define SOTP_DAUTH_ECC_ERROR_MASK 0x800000 +#define SOTP_K_HMAC_ECC_ERROR_MASK 0x1000000 +#define SOTP_K_AES_ECC_ERROR_MASK 0x2000000 + +#endif diff --git a/plat/brcm/board/stingray/include/scp_cmd.h b/plat/brcm/board/stingray/include/scp_cmd.h new file mode 100644 index 000000000..806ef56a5 --- /dev/null +++ b/plat/brcm/board/stingray/include/scp_cmd.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2017-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SCP_CMD_H +#define SCP_SMD_H + +#include + +typedef struct { + int cmd; + int completed; + int ret; +} crmu_response_t; + + +#define SCP_CMD_MASK 0xffff +#define SCP_CMD_DEFAULT_TIMEOUT_US 1000 +#define SCP_CMD_SCP_BOOT_TIMEOUT_US 5000 + +int scp_send_cmd(uint32_t cmd, uint32_t param, uint32_t timeout); + +#endif diff --git a/plat/brcm/board/stingray/include/scp_utils.h b/plat/brcm/board/stingray/include/scp_utils.h new file mode 100644 index 000000000..c39b18cb2 --- /dev/null +++ b/plat/brcm/board/stingray/include/scp_utils.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2019-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SCP_UTILS_H +#define SCP_UTILS_H + +#include +#include + +#include + +int plat_bcm_bl2_plat_handle_scp_bl2(image_info_t *scp_bl2_image_info); + +bool is_crmu_alive(void); +bool bcm_scp_issue_sys_reset(void); + +#define SCP_READ_CFG(cfg) mmio_read_32(CRMU_CFG_BASE + \ + offsetof(M0CFG, cfg)) +#define SCP_WRITE_CFG(cfg, value) mmio_write_32(CRMU_CFG_BASE + \ + offsetof(M0CFG, cfg), value) + +#define SCP_READ_CFG16(cfg) mmio_read_16(CRMU_CFG_BASE + \ + offsetof(M0CFG, cfg)) +#define SCP_WRITE_CFG16(cfg, value) mmio_write_16(CRMU_CFG_BASE + \ + offsetof(M0CFG, cfg), value) + +#define SCP_READ_CFG8(cfg) mmio_read_8(CRMU_CFG_BASE + \ + offsetof(M0CFG, cfg)) +#define SCP_WRITE_CFG8(cfg, value) mmio_write_8(CRMU_CFG_BASE + \ + offsetof(M0CFG, cfg), value) +#endif diff --git a/plat/brcm/board/stingray/include/sr_utils.h b/plat/brcm/board/stingray/include/sr_utils.h new file mode 100644 index 000000000..b3fc735f7 --- /dev/null +++ b/plat/brcm/board/stingray/include/sr_utils.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2017 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SR_UTILS_H +#define SR_UTILS_H + +#include + +#include +#include +#include + +static inline void brcm_stingray_set_qspi_mux(int enable_ap) +{ + mmio_write_32(QSPI_HOLD_N_MODE_SEL_CONTROL, enable_ap); + mmio_write_32(QSPI_WP_N_MODE_SEL_CONTROL, enable_ap); + mmio_write_32(QSPI_SCK_MODE_SEL_CONTROL, enable_ap); + mmio_write_32(QSPI_CS_N_MODE_SEL_CONTROL, enable_ap); + mmio_write_32(QSPI_MOSI_MODE_SEL_CONTROL, enable_ap); + mmio_write_32(QSPI_MISO_MODE_SEL_CONTROL, enable_ap); +} + +static inline void brcm_stingray_set_straps(uint32_t boot_source) +{ + /* Enable software strap override */ + mmio_setbits_32(CDRU_CHIP_STRAP_CTRL, + BIT(CDRU_CHIP_STRAP_CTRL__SOFTWARE_OVERRIDE)); + + /* set straps to the next boot source */ + mmio_clrsetbits_32(CDRU_CHIP_STRAP_DATA, + BOOT_SOURCE_MASK, + boot_source); + + /* Disable software strap override */ + mmio_clrbits_32(CDRU_CHIP_STRAP_CTRL, + BIT(CDRU_CHIP_STRAP_CTRL__SOFTWARE_OVERRIDE)); +} + +#endif diff --git a/plat/brcm/board/stingray/include/swreg.h b/plat/brcm/board/stingray/include/swreg.h new file mode 100644 index 000000000..6e971ce34 --- /dev/null +++ b/plat/brcm/board/stingray/include/swreg.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2017 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SWREG_H +#define SWREG_H + +/* default voltage if no valid OTP */ +#define VDDC_CORE_DEF_VOLT 910000 /* 0.91v */ +#define IHOST_DEF_VOLT 940000 /* 0.94v */ + +#define B0_VDDC_CORE_DEF_VOLT 950000 /* 0.95v */ +#define B0_IHOST_DEF_VOLT 950000 /* 0.95v */ +#define B0_DDR_VDDC_DEF_VOLT 1000000 /* 1v */ + +#define SWREG_IHOST1_DIS 4 +#define SWREG_IHOST1_REG_RESETB 5 +#define SWREG_IHOST1_PMU_STABLE 2 + +enum sw_reg { + DDR_VDDC = 1, + IHOST03, + IHOST12, + IHOST_ARRAY, + DDRIO_SLAVE, + VDDC_CORE, + VDDC1, + DDRIO_MASTER +}; + +int set_swreg(enum sw_reg reg_id, uint32_t micro_volts); +int swreg_firmware_update(void); + +#endif diff --git a/plat/brcm/board/stingray/platform.mk b/plat/brcm/board/stingray/platform.mk index 83e502d1c..f4b665ca6 100644 --- a/plat/brcm/board/stingray/platform.mk +++ b/plat/brcm/board/stingray/platform.mk @@ -4,6 +4,19 @@ # SPDX-License-Identifier: BSD-3-Clause # +# Set the toc_flags to 1 for 100% speed operation +# Set the toc_flags to 2 for 50% speed operation +# Set the toc_flags to 3 for 25% speed operation +# Set the toc_flags bit 3 to indicate ignore the fip in UEFI copy mode +PLAT_TOC_FLAGS := 0x0 + +# Set the IHOST_PLL_FREQ to, +# 1 for full speed +# 2 for 50% speed +# 3 for 25% speed +# 0 for bypass +$(eval $(call add_define_val,IHOST_PLL_FREQ,1)) + # Enable workaround for ERRATA_A72_859971 ERRATA_A72_859971 := 1 @@ -16,16 +29,42 @@ ARM_BL31_IN_DRAM := 1 USE_CRMU_SRAM := yes +# Enable error logging by default for Stingray +BCM_ELOG := yes + +# Enable FRU support by default for Stingray +ifeq (${USE_FRU},) +USE_FRU := no +endif + # Use single cluster ifeq (${USE_SINGLE_CLUSTER},yes) $(info Using Single Cluster) $(eval $(call add_define,USE_SINGLE_CLUSTER)) endif +# Use DDR +ifeq (${USE_DDR},yes) +$(info Using DDR) +$(eval $(call add_define,USE_DDR)) +endif + ifeq (${BOARD_CFG},) BOARD_CFG := bcm958742k endif +# Use NAND +ifeq (${USE_NAND},$(filter yes, ${USE_NAND})) +$(info Using NAND) +$(eval $(call add_define,USE_NAND)) +endif + +# Enable Broadcom error logging support +ifeq (${BCM_ELOG},yes) +$(info Using BCM_ELOG) +$(eval $(call add_define,BCM_ELOG)) +endif + # BL31 build for standalone mode ifeq (${STANDALONE_BL31},yes) RESET_TO_BL31 := 1 @@ -43,6 +82,9 @@ endif # Default soft reset is L3 $(eval $(call add_define,CONFIG_SOFT_RESET_L3)) +# Enable Chip OTP driver +DRIVER_OCOTP_ENABLE := 1 + include plat/brcm/board/common/board_common.mk SOC_DIR := brcm/board/stingray @@ -58,6 +100,17 @@ PLAT_BL_COMMON_SOURCES += lib/cpus/aarch64/cortex_a72.S \ drivers/arm/tzc/tzc400.c \ plat/${SOC_DIR}/src/topology.c +BL2_SOURCES += plat/${SOC_DIR}/driver/ihost_pll_config.c \ + plat/${SOC_DIR}/src/bl2_setup.c \ + plat/${SOC_DIR}/driver/swreg.c + + +ifeq (${USE_DDR},yes) +PLAT_INCLUDES += -Iplat/${SOC_DIR}/driver/ddr/soc/include +else +PLAT_INCLUDES += -Iplat/${SOC_DIR}/driver/ext_sram_init +BL2_SOURCES += plat/${SOC_DIR}/driver/ext_sram_init/ext_sram_init.c +endif # Include GICv3 driver files include drivers/arm/gic/v3/gicv3.mk @@ -77,6 +130,12 @@ BL31_SOURCES += \ ifdef SCP_BL2 PLAT_INCLUDES += -Iplat/brcm/common/ +BL2_SOURCES += plat/brcm/common/brcm_mhu.c \ + plat/brcm/common/brcm_scpi.c \ + plat/${SOC_DIR}/src/scp_utils.c \ + plat/${SOC_DIR}/src/scp_cmd.c \ + drivers/brcm/scp.c + BL31_SOURCES += plat/brcm/common/brcm_mhu.c \ plat/brcm/common/brcm_scpi.c \ plat/${SOC_DIR}/src/brcm_pm_ops.c @@ -85,5 +144,19 @@ BL31_SOURCES += plat/${SOC_DIR}/src/ihost_pm.c \ plat/${SOC_DIR}/src/pm.c endif +ifeq (${ELOG_SUPPORT},1) +ifeq (${ELOG_STORE_MEDIA},DDR) +BL2_SOURCES += plat/brcm/board/common/bcm_elog_ddr.c +endif +endif + # Do not execute the startup code on warm reset. PROGRAMMABLE_RESET_ADDRESS := 1 + +# Nitro FW, config and Crash log uses secure DDR memory +# Inaddition to above, Nitro master and slave is also secure +ifneq ($(NITRO_SECURE_ACCESS),) +$(eval $(call add_define,NITRO_SECURE_ACCESS)) +$(eval $(call add_define,DDR_NITRO_SECURE_REGION_START)) +$(eval $(call add_define,DDR_NITRO_SECURE_REGION_END)) +endif diff --git a/plat/brcm/board/stingray/src/bl2_setup.c b/plat/brcm/board/stingray/src/bl2_setup.c new file mode 100644 index 000000000..0b0a3ffe1 --- /dev/null +++ b/plat/brcm/board/stingray/src/bl2_setup.c @@ -0,0 +1,742 @@ +/* + * Copyright (c) 2016-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#ifdef USE_GPIO +#include +#include +#endif +#include +#include +#include +#include +#ifdef USE_DDR +#include +#else +#include +#endif +#if DRIVER_OCOTP_ENABLE +#include +#endif +#include "board_info.h" + +#define WORD_SIZE 8 +#define SWREG_AVS_OTP_OFFSET (13 * WORD_SIZE) /* 13th row byte offset */ +#define AON_GPIO_OTP_OFFSET (28 * WORD_SIZE) /* 28th row byte offset */ +#define BYTES_TO_READ 8 + +/* OTP voltage step definitions */ +#define MVOLT_STEP_MAX 0x18 /* 1v */ +#define MVOLT_PER_STEP 10 /* 0.01mv per step */ +#define MVOLT_BASE 760 /* 0.76v */ + +#define STEP_TO_UVOLTS(step) \ + ((MVOLT_BASE + (MVOLT_PER_STEP * (step))) * 1000) + +#define GET_BITS(first, last, data) \ + ((data >> first) & ((1 << (last - first + 1)) - 1)) + +/* + * SW-REG OTP encoding: + * + * SWREG_bits[11:0] = OTP 13th row 12 bits[55:44] + * SWREG_bits[11:10] - Valid Bits (0x2 - valid, if not 0x2 - Invalid) + * SWREG_bits[9:5] - iHost03, iHost12 + * SWREG_bits[4:0] - Core VDDC + */ +#define SWREG_OTP_BITS_START 12 /* 44th bit in MSB 32-bits */ +#define SWREG_OTP_BITS_END 23 /* 55th bit in MSB 32-bits */ +#define SWREG_VDDC_FIELD_START 0 +#define SWREG_VDDC_FIELD_END 4 +#define SWREG_IHOST_FIELD_START 5 +#define SWREG_IHOST_FIELD_END 9 +#define SWREG_VALID_BIT_START 10 +#define SWREG_VALID_BIT_END 11 +#define SWREG_VALID_BITS 0x2 + +/* + * Row 13 bit 56 is programmed as '1' today. It is not being used, so plan + * is to flip this bit to '0' for B1 rev. Hence SW can leverage this bit + * to identify Bx chip to program different sw-regulators. + */ +#define SPARE_BIT 24 + +#define IS_SR_B0(data) (((data) >> SPARE_BIT) & 0x1) + +#if DRIVER_OCOTP_ENABLE +static struct otpc_map otp_stingray_map = { + .otpc_row_size = 2, + .data_r_offset = {0x10, 0x5c}, + .data_w_offset = {0x2c, 0x64}, + .word_size = 8, + .stride = 8, +}; +#endif + +void plat_bcm_bl2_early_platform_setup(void) +{ + /* Select UART0 for AP via mux setting*/ + if (PLAT_BRCM_BOOT_UART_BASE == UART0_BASE_ADDR) { + mmio_write_32(UART0_SIN_MODE_SEL_CONTROL, 1); + mmio_write_32(UART0_SOUT_MODE_SEL_CONTROL, 1); + } +} + +#ifdef USE_NAND +static void brcm_stingray_nand_init(void) +{ + unsigned int val; + unsigned int nand_idm_reset_control = 0x68e0a800; + + VERBOSE(" stingray nand init start.\n"); + + /* Reset NAND */ + VERBOSE(" - reset nand\n"); + val = mmio_read_32((uintptr_t)(nand_idm_reset_control + 0x0)); + mmio_write_32((uintptr_t)(nand_idm_reset_control + 0x0), val | 0x1); + udelay(500); + val = mmio_read_32((uintptr_t)(nand_idm_reset_control + 0x0)); + mmio_write_32((uintptr_t)(nand_idm_reset_control + 0x0), val & ~0x1); + udelay(500); + + VERBOSE(" stingray nand init done.\n"); +} +#endif + +#if defined(USE_PAXB) || defined(USE_PAXC) || defined(USE_SATA) +#define PCIE_RESCAL_CFG_0 0x40000130 +#define PCIE_CFG_RESCAL_RSTB_R (1 << 16) +#define PCIE_CFG_RESCAL_PWRDNB_R (1 << 8) +#define PCIE_RESCAL_STATUS_0 0x4000014c +#define PCIE_STAT_PON_VALID_R (1 << 0) +#define PCIE_RESCAL_OUTPUT_STATUS 0x40000154 +#define CDRU_PCIE_RESET_N_R (1 << CDRU_MISC_RESET_CONTROL__CDRU_PCIE_RESET_N_R) + +#ifdef EMULATION_SETUP +static void brcm_stingray_pcie_reset(void) +{ +} +#else +static void brcm_stingray_pcie_reset(void) +{ + unsigned int data; + int try; + + if (bcm_chimp_is_nic_mode()) { + INFO("NIC mode detected; PCIe reset/rescal not executed\n"); + return; + } + + mmio_clrbits_32(CDRU_MISC_RESET_CONTROL, CDRU_PCIE_RESET_N_R); + mmio_setbits_32(CDRU_MISC_RESET_CONTROL, CDRU_PCIE_RESET_N_R); + /* Release reset */ + mmio_setbits_32(PCIE_RESCAL_CFG_0, PCIE_CFG_RESCAL_RSTB_R); + mdelay(1); + /* Power UP */ + mmio_setbits_32(PCIE_RESCAL_CFG_0, + (PCIE_CFG_RESCAL_RSTB_R | PCIE_CFG_RESCAL_PWRDNB_R)); + + try = 1000; + do { + udelay(1); + data = mmio_read_32(PCIE_RESCAL_STATUS_0); + try--; + } while ((data & PCIE_STAT_PON_VALID_R) == 0x0 && (try > 0)); + + if (try <= 0) + ERROR("PCIE_RESCAL_STATUS_0: 0x%x\n", data); + + VERBOSE("PCIE_SATA_RESCAL_STATUS_0 0x%x.\n", + mmio_read_32(PCIE_RESCAL_STATUS_0)); + VERBOSE("PCIE_SATA_RESCAL_OUTPUT_STATUS 0x%x.\n", + mmio_read_32(PCIE_RESCAL_OUTPUT_STATUS)); + INFO("PCIE SATA Rescal Init done\n"); +} +#endif /* EMULATION_SETUP */ +#endif /* USE_PAXB || USE_PAXC || USE_SATA */ + +#ifdef USE_PAXC +void brcm_stingray_chimp_check_and_fastboot(void) +{ + int fastboot_init_result; + + if (bcm_chimp_is_nic_mode()) + /* Do not wait here */ + return; + +#if WARMBOOT_DDR_S3_SUPPORT + /* + * Currently DDR shmoo parameters and QSPI boot source are + * tied. DDR shmoo parameters are stored in QSPI, which is + * used for warmboot. + * Do not reset nitro for warmboot + */ + if (is_warmboot() && (boot_source_get() == BOOT_SOURCE_QSPI)) + return; +#endif /* WARMBOOT_DDR_S3_SUPPORT */ + + /* + * Not in NIC mode, + * initiate fastboot (if enabled) + */ + if (FASTBOOT_TYPE == CHIMP_FASTBOOT_NITRO_RESET) { + + VERBOSE("Bring up Nitro/ChiMP\n"); + + if (boot_source_get() == BOOT_SOURCE_QSPI) + WARN("Nitro boots from QSPI when AP has booted from QSPI.\n"); + brcm_stingray_set_qspi_mux(0); + VERBOSE("Nitro controls the QSPI\n"); + } + + fastboot_init_result = bcm_chimp_initiate_fastboot(FASTBOOT_TYPE); + if (fastboot_init_result && boot_source_get() != BOOT_SOURCE_QSPI) + ERROR("Nitro init error %d. Status: 0x%x; bpe_mod reg: 0x%x\n" + "fastboot register: 0x%x; handshake register 0x%x\n", + fastboot_init_result, + bcm_chimp_read_ctrl(CHIMP_REG_CTRL_BPE_STAT_REG), + bcm_chimp_read_ctrl(CHIMP_REG_CTRL_BPE_MODE_REG), + bcm_chimp_read_ctrl(CHIMP_REG_CTRL_FSTBOOT_PTR_REG), + bcm_chimp_read(CHIMP_REG_ECO_RESERVED)); + + /* + * CRMU watchdog kicks is an example, which is L1 reset, + * does not clear Nitro scratch pad ram. + * For Nitro resets: Clear the Nitro health status memory. + */ + bcm_chimp_write((CHIMP_REG_CHIMP_SCPAD + CHIMP_HEALTH_STATUS_OFFSET), + 0); +} +#endif + +void set_ihost_vddc_swreg(uint32_t ihost_uvolts, uint32_t vddc_uvolts) +{ + NOTICE("ihost_uvolts: %duv, vddc_uvolts: %duv\n", + ihost_uvolts, vddc_uvolts); + + set_swreg(VDDC_CORE, vddc_uvolts); + set_swreg(IHOST03, ihost_uvolts); + set_swreg(IHOST12, ihost_uvolts); +} + +/* + * Reads SWREG AVS OTP bits (13th row) with ECC enabled and get voltage + * defined in OTP if valid OTP is found + */ +void read_avs_otp_bits(uint32_t *ihost_uvolts, uint32_t *vddc_uvolts) +{ + uint32_t offset = SWREG_AVS_OTP_OFFSET; + uint32_t ihost_step, vddc_step; + uint32_t avs_bits; + uint32_t buf[2]; + + if (bcm_otpc_read(offset, &buf[0], BYTES_TO_READ, 1) == -1) + return; + + VERBOSE("AVS OTP %d ROW: 0x%x.0x%x\n", + offset/WORD_SIZE, buf[1], buf[0]); + + /* get voltage readings from AVS OTP bits */ + avs_bits = GET_BITS(SWREG_OTP_BITS_START, + SWREG_OTP_BITS_END, + buf[1]); + + /* check for valid otp bits */ + if (GET_BITS(SWREG_VALID_BIT_START, SWREG_VALID_BIT_END, avs_bits) != + SWREG_VALID_BITS) { + WARN("Invalid AVS OTP bits at %d row\n", offset/WORD_SIZE); + return; + } + + /* get ihost and vddc step value */ + vddc_step = GET_BITS(SWREG_VDDC_FIELD_START, + SWREG_VDDC_FIELD_END, + avs_bits); + + ihost_step = GET_BITS(SWREG_IHOST_FIELD_START, + SWREG_IHOST_FIELD_END, + avs_bits); + + if ((ihost_step > MVOLT_STEP_MAX) || (vddc_step > MVOLT_STEP_MAX)) { + WARN("OTP entry invalid\n"); + return; + } + + /* get voltage in micro-volts */ + *ihost_uvolts = STEP_TO_UVOLTS(ihost_step); + *vddc_uvolts = STEP_TO_UVOLTS(vddc_step); +} + +/* + * This api reads otp bits and program internal swreg's - ihos12, ihost03, + * vddc_core and ddr_core based on different chip. External swreg's + * programming will be done from crmu. + * + * For A2 chip: + * Read OTP row 20, bit 50. This bit will be set for A2 chip. Once A2 chip is + * found, read AVS OTP row 13, 12bits[55:44], if valid otp bits are found + * then set ihost and vddc according to avs otp bits else set them to 0.94v + * and 0.91v respectively. Also update the firmware after setting voltage. + * + * For B0 chip: + * Read OTP row 13, bit 56. This bit will be set for B0 chip. Once B0 chip is + * found then set ihost and vddc to 0.95v and ddr_core to 1v. No AVS OTP bits + * are used get ihost/vddc voltages. + * + * For B1 chip: + * Read AVS OTP row 13, 12bits[55:44], if valid otp bits are found then set + * ihost and vddc according to avs otp bits else set them to 0.94v and 0.91v + * respectively. + */ +void set_swreg_based_on_otp(void) +{ + /* default voltage if no valid OTP */ + uint32_t vddc_uvolts = VDDC_CORE_DEF_VOLT; + uint32_t ihost_uvolts = IHOST_DEF_VOLT; + uint32_t ddrc_uvolts; + uint32_t offset; + uint32_t buf[2]; + + offset = SWREG_AVS_OTP_OFFSET; + if (bcm_otpc_read(offset, &buf[0], BYTES_TO_READ, 1) == -1) + return; + + VERBOSE("OTP %d ROW: 0x%x.0x%x\n", + offset/WORD_SIZE, buf[1], buf[0]); + + if (IS_SR_B0(buf[1])) { + /* don't read AVS OTP for B0 */ + ihost_uvolts = B0_IHOST_DEF_VOLT; + vddc_uvolts = B0_VDDC_CORE_DEF_VOLT; + ddrc_uvolts = B0_DDR_VDDC_DEF_VOLT; + } else { + read_avs_otp_bits(&ihost_uvolts, &vddc_uvolts); + } + +#if (IHOST_REG_TYPE == IHOST_REG_INTEGRATED) && \ + (VDDC_REG_TYPE == VDDC_REG_INTEGRATED) + /* enable IHOST12 cluster before changing voltage */ + NOTICE("Switching on the Regulator idx: %u\n", + SWREG_IHOST1_DIS); + mmio_clrsetbits_32(CRMU_SWREG_CTRL_ADDR, + BIT(SWREG_IHOST1_DIS), + BIT(SWREG_IHOST1_REG_RESETB)); + + /* wait for regulator supply gets stable */ + while (!(mmio_read_32(CRMU_SWREG_STATUS_ADDR) & + (1 << SWREG_IHOST1_PMU_STABLE))) + ; + + INFO("Regulator supply got stable\n"); + +#ifndef DEFAULT_SWREG_CONFIG + swreg_firmware_update(); +#endif + + set_ihost_vddc_swreg(ihost_uvolts, vddc_uvolts); +#endif + if (IS_SR_B0(buf[1])) { + NOTICE("ddrc_uvolts: %duv\n", ddrc_uvolts); + set_swreg(DDR_VDDC, ddrc_uvolts); + } +} + +#ifdef USE_DDR +static struct ddr_info ddr_info; +#endif +#ifdef USE_FRU +static struct fru_area_info fru_area[FRU_MAX_NR_AREAS]; +static struct fru_board_info board_info; +static struct fru_time fru_tm; +static uint8_t fru_tbl[BCM_MAX_FRU_LEN]; + +static void board_detect_fru(void) +{ + uint32_t i, result; + int ret = -1; + + result = bcm_emmc_init(false); + if (!result) { + ERROR("eMMC init failed\n"); + return; + } + + /* go through eMMC boot partitions looking for FRU table */ + for (i = EMMC_BOOT_PARTITION1; i <= EMMC_BOOT_PARTITION2; i++) { + result = emmc_partition_select(i); + if (!result) { + ERROR("Switching to eMMC part %u failed\n", i); + return; + } + + result = emmc_read(BCM_FRU_TBL_OFFSET, (uintptr_t)fru_tbl, + BCM_MAX_FRU_LEN, BCM_MAX_FRU_LEN); + if (!result) { + ERROR("Failed to read from eMMC part %u\n", i); + return; + } + + /* + * Run sanity check and checksum to make sure valid FRU table + * is detected + */ + ret = fru_validate(fru_tbl, fru_area); + if (ret < 0) { + WARN("FRU table not found in eMMC part %u\n", i); + continue; + } + + /* parse DDR information from FRU table */ + ret = fru_parse_ddr(fru_tbl, &fru_area[FRU_AREA_INTERNAL], + &ddr_info); + if (ret < 0) { + WARN("No FRU DDR info found in eMMC part %u\n", i); + continue; + } + + /* parse board information from FRU table */ + ret = fru_parse_board(fru_tbl, &fru_area[FRU_AREA_BOARD_INFO], + &board_info); + if (ret < 0) { + WARN("No FRU board info found in eMMC part %u\n", i); + continue; + } + + /* if we reach here, valid FRU table is parsed */ + break; + } + + if (ret < 0) { + WARN("FRU table missing for this board\n"); + return; + } + + for (i = 0; i < BCM_MAX_NR_DDR; i++) { + INFO("DDR channel index: %d\n", ddr_info.mcb[i].idx); + INFO("DDR size %u GB\n", ddr_info.mcb[i].size_mb / 1024); + INFO("DDR ref ID by SW (Not MCB Ref ID) 0x%x\n", + ddr_info.mcb[i].ref_id); + } + + fru_format_time(board_info.mfg_date, &fru_tm); + + INFO("**** FRU board information ****\n"); + INFO("Language 0x%x\n", board_info.lang); + INFO("Manufacturing Date %u.%02u.%02u, %02u:%02u\n", + fru_tm.year, fru_tm.month, fru_tm.day, + fru_tm.hour, fru_tm.min); + INFO("Manufacturing Date(Raw) 0x%x\n", board_info.mfg_date); + INFO("Manufacturer %s\n", board_info.manufacturer); + INFO("Product Name %s\n", board_info.product_name); + INFO("Serial number %s\n", board_info.serial_number); + INFO("Part number %s\n", board_info.part_number); + INFO("File ID %s\n", board_info.file_id); +} +#endif /* USE_FRU */ + +#ifdef USE_GPIO + +#define INVALID_GPIO 0xffff + +static const int gpio_cfg_bitmap[MAX_NR_GPIOS] = { +#ifdef BRD_DETECT_GPIO_BIT0 + BRD_DETECT_GPIO_BIT0, +#else + INVALID_GPIO, +#endif +#ifdef BRD_DETECT_GPIO_BIT1 + BRD_DETECT_GPIO_BIT1, +#else + INVALID_GPIO, +#endif +#ifdef BRD_DETECT_GPIO_BIT2 + BRD_DETECT_GPIO_BIT2, +#else + INVALID_GPIO, +#endif +#ifdef BRD_DETECT_GPIO_BIT3 + BRD_DETECT_GPIO_BIT3, +#else + INVALID_GPIO, +#endif +}; + +static uint8_t gpio_bitmap; + +/* + * Use an odd number to avoid potential conflict with public GPIO level + * defines + */ +#define GPIO_STATE_FLOAT 15 + +/* + * If GPIO_SUPPORT_FLOAT_DETECTION is disabled, simply return GPIO level + * + * If GPIO_SUPPORT_FLOAT_DETECTION is enabled, add additional test for possible + * pin floating (unconnected) scenario. This support is assuming externally + * applied pull up / pull down will have a stronger pull than the internal pull + * up / pull down. + */ +static uint8_t gpio_get_state(int gpio) +{ + uint8_t val; + + /* set direction to GPIO input */ + gpio_set_direction(gpio, GPIO_DIR_IN); + +#ifndef GPIO_SUPPORT_FLOAT_DETECTION + if (gpio_get_value(gpio) == GPIO_LEVEL_HIGH) + val = GPIO_LEVEL_HIGH; + else + val = GPIO_LEVEL_LOW; + + return val; +#else + /* + * Enable internal pull down. If GPIO level is still high, there must + * be an external pull up + */ + gpio_set_pull(gpio, GPIO_PULL_DOWN); + if (gpio_get_value(gpio) == GPIO_LEVEL_HIGH) { + val = GPIO_LEVEL_HIGH; + goto exit; + } + + /* + * Enable internal pull up. If GPIO level is still low, there must + * be an external pull down + */ + gpio_set_pull(gpio, GPIO_PULL_UP); + if (gpio_get_value(gpio) == GPIO_LEVEL_LOW) { + val = GPIO_LEVEL_LOW; + goto exit; + } + + /* if reached here, the pin must be not connected */ + val = GPIO_STATE_FLOAT; + +exit: + /* make sure internall pull is disabled */ + if (gpio_get_pull(gpio) != GPIO_PULL_NONE) + gpio_set_pull(gpio, GPIO_PULL_NONE); + + return val; +#endif +} + +static void board_detect_gpio(void) +{ + unsigned int i, val; + int gpio; + + iproc_gpio_init(IPROC_GPIO_S_BASE, IPROC_GPIO_NR, + IPROC_IOPAD_MODE_BASE, HSLS_IOPAD_BASE); + + gpio_bitmap = 0; + for (i = 0; i < MAX_NR_GPIOS; i++) { + if (gpio_cfg_bitmap[i] == INVALID_GPIO) + continue; + + /* + * Construct the bitmap based on GPIO value. Floating pin + * detection is a special case. As soon as a floating pin is + * detected, a special value of MAX_GPIO_BITMAP_VAL is + * assigned and we break out of the loop immediately + */ + gpio = gpio_cfg_bitmap[i]; + val = gpio_get_state(gpio); + if (val == GPIO_STATE_FLOAT) { + gpio_bitmap = MAX_GPIO_BITMAP_VAL; + break; + } + + if (val == GPIO_LEVEL_HIGH) + gpio_bitmap |= BIT(i); + } + + memcpy(&ddr_info, &gpio_ddr_info[gpio_bitmap], sizeof(ddr_info)); + INFO("Board detection GPIO bitmap = 0x%x\n", gpio_bitmap); +} +#endif /* USE_GPIO */ + +static void bcm_board_detect(void) +{ +#ifdef DDR_LEGACY_MCB_SUPPORTED + /* Loading default DDR info */ + memcpy(&ddr_info, &default_ddr_info, sizeof(ddr_info)); +#endif +#ifdef USE_FRU + board_detect_fru(); +#endif +#ifdef USE_GPIO + board_detect_gpio(); +#endif +} + +static void dump_persistent_regs(void) +{ + NOTICE("pr0: %x\n", mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG0)); + NOTICE("pr1: %x\n", mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG1)); + NOTICE("pr2: %x\n", mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG2)); + NOTICE("pr3: %x\n", mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG3)); + NOTICE("pr4: %x\n", mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG4)); + NOTICE("pr5: %x\n", mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG5)); + NOTICE("pr6: %x\n", mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG6)); + NOTICE("pr7: %x\n", mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG7)); + NOTICE("pr8: %x\n", mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG8)); + NOTICE("pr9: %x\n", mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG9)); + NOTICE("pr10: %x\n", mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG10)); + NOTICE("pr11: %x\n", mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG11)); +} + +void plat_bcm_bl2_plat_arch_setup(void) +{ + if (chip_get_rev_id_major() == CHIP_REV_MAJOR_AX) { + if (!(sotp_mem_read(SOTP_ATF_CFG_ROW_ID, SOTP_ROW_NO_ECC) & + SOTP_ATF_WATCHDOG_ENABLE_MASK)) { + /* + * Stop sp805 watchdog timer immediately. + * It might has been set up by MCU patch earlier for + * eMMC workaround. + * + * Note the watchdog timer started in CRMU has a very + * short timeout and needs to be stopped immediately. + * Down below we restart it with a much longer timeout + * for BL2 and BL31 + */ + sp805_stop(ARM_SP805_TWDG_BASE); + } + } + +#if !BRCM_DISABLE_TRUSTED_WDOG + /* + * start secure watchdog for BL2 and BL31. + * Note that UART download can take a longer time, + * so do not allow watchdog for UART download, + * as this boot source is not a standard modus operandi. + */ + if (boot_source_get() != BOOT_SOURCE_UART) + sp805_start(ARM_SP805_TWDG_BASE, ARM_TWDG_LOAD_VAL); +#endif + +#ifdef BCM_ELOG + /* Ensure logging is started out fresh in BL2. */ + mmio_write_32(BCM_ELOG_BL2_BASE, 0); +#endif + /* + * In BL2, since we have very limited space to store logs, we only + * save logs that are >= the WARNING level. + */ + bcm_elog_init((void *)BCM_ELOG_BL2_BASE, BCM_ELOG_BL2_SIZE, + LOG_LEVEL_WARNING); + + dump_persistent_regs(); + + /* Read CRMU mailbox 0 */ + NOTICE("RESET (reported by CRMU): 0x%x\n", + mmio_read_32(CRMU_READ_MAIL_BOX0)); + + /* + * All non-boot-source PADs are in forced input-mode at + * reset so clear the force on non-boot-source PADs using + * CDRU register. + */ + mmio_clrbits_32((uintptr_t)CDRU_CHIP_IO_PAD_CONTROL, + (1 << CDRU_CHIP_IO_PAD_CONTROL__CDRU_IOMUX_FORCE_PAD_IN_R)); + +#if DRIVER_OCOTP_ENABLE + bcm_otpc_init(&otp_stingray_map); +#endif + + set_swreg_based_on_otp(); + +#if IHOST_PLL_FREQ != 0 + bcm_set_ihost_pll_freq(0x0, IHOST_PLL_FREQ); +#endif + +#ifdef INCLUDE_EMMC_DRIVER_ERASE_CODE + /* The erasable unit of the eMMC is the "Erase Group"; + * Erase group is measured in write blocks which are the + * basic writable units of the Device. + * The size of the Erase Group is a Device specific parameter + */ + emmc_erase(EMMC_ERASE_START_BLOCK, EMMC_ERASE_BLOCK_COUNT, + EMMC_ERASE_PARTITION); +#endif + + bcm_board_detect(); +#ifdef DRIVER_EMMC_ENABLE + /* Initialize the card, if it is not */ + if (bcm_emmc_init(true) < 0) + WARN("eMMC Card Initialization Failed!!!\n"); +#endif + +#if BL2_TEST_I2C + i2c_test(); +#endif + +#ifdef USE_DDR + ddr_initialize(&ddr_info); + + ddr_secure_region_config(SECURE_DDR_BASE_ADDRESS, + SECURE_DDR_END_ADDRESS); +#ifdef NITRO_SECURE_ACCESS + ddr_secure_region_config(DDR_NITRO_SECURE_REGION_START, + DDR_NITRO_SECURE_REGION_END); +#endif +#else + ext_sram_init(); +#endif + +#if BL2_TEST_MEM + ddr_test(); +#endif + +#ifdef USE_NAND + brcm_stingray_nand_init(); +#endif + +#if defined(USE_PAXB) || defined(USE_PAXC) || defined(USE_SATA) + brcm_stingray_pcie_reset(); +#endif + +#ifdef USE_PAXC + if (boot_source_get() != BOOT_SOURCE_QSPI) + brcm_stingray_chimp_check_and_fastboot(); +#endif + +#if ((!CLEAN_DDR || MMU_DISABLED)) + /* + * Now DDR has been initialized. We want to copy all the logs in SRAM + * into DDR so we will have much more space to store the logs in the + * next boot stage + */ + bcm_elog_copy_log((void *)BCM_ELOG_BL31_BASE, + MIN(BCM_ELOG_BL2_SIZE, BCM_ELOG_BL31_SIZE) + ); + + /* + * We are not yet at the end of BL2, but we can stop log here so we do + * not need to add 'bcm_elog_exit' to the standard BL2 code. The + * benefit of capturing BL2 logs after this is very minimal in a + * production system + * NOTE: BL2 logging must be exited before going forward to setup + * page tables + */ + bcm_elog_exit(); +#endif +} diff --git a/plat/brcm/board/stingray/src/scp_cmd.c b/plat/brcm/board/stingray/src/scp_cmd.c new file mode 100644 index 000000000..2aa95194a --- /dev/null +++ b/plat/brcm/board/stingray/src/scp_cmd.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2017-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include +#include +#include + +#include "m0_ipc.h" + +/* + * Reads a response from CRMU MAILBOX + * Assumes that access has been granted and locked. + * Note that this is just a temporary implementation until + * channels are introduced + */ +static void scp_read_response(crmu_response_t *resp) +{ + uint32_t code; + + code = mmio_read_32(CRMU_MAIL_BOX0); + resp->completed = code & MCU_IPC_CMD_DONE_MASK; + resp->cmd = code & SCP_CMD_MASK; + resp->ret = (code & MCU_IPC_CMD_REPLY_MASK) >> MCU_IPC_CMD_REPLY_SHIFT; +} + +/* + * Send a command to SCP and wait for timeout us. + * Return: 0 on success + * -1 if there was no proper reply from SCP + * >0 if there was a response from MCU, but + * command completed with an error. + */ +int scp_send_cmd(uint32_t cmd, uint32_t param, uint32_t timeout) +{ + int ret = -1; + + mmio_write_32(CRMU_MAIL_BOX0, cmd); + mmio_write_32(CRMU_MAIL_BOX1, param); + do { + crmu_response_t scp_resp; + + udelay(1); + scp_read_response(&scp_resp); + if (scp_resp.completed && + (scp_resp.cmd == cmd)) { + /* This command has completed */ + ret = scp_resp.ret; + break; + } + } while (--timeout); + + return ret; +} diff --git a/plat/brcm/board/stingray/src/scp_utils.c b/plat/brcm/board/stingray/src/scp_utils.c new file mode 100644 index 000000000..1d82ceff1 --- /dev/null +++ b/plat/brcm/board/stingray/src/scp_utils.c @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2017-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "m0_cfg.h" +#include "m0_ipc.h" + +#ifdef BCM_ELOG +static void prepare_elog(void) +{ +#if (CLEAN_DDR && !defined(MMU_DISABLED)) + /* + * Now DDR has been initialized. We want to copy all the logs in SRAM + * into DDR so we will have much more space to store the logs in the + * next boot stage + */ + bcm_elog_copy_log((void *)BCM_ELOG_BL31_BASE, + MIN(BCM_ELOG_BL2_SIZE, BCM_ELOG_BL31_SIZE) + ); + + /* + * We are almost at the end of BL2, and we can stop log here so we do + * not need to add 'bcm_elog_exit' to the standard BL2 code. The + * benefit of capturing BL2 logs after this is very minimal in a + * production system. + */ + bcm_elog_exit(); +#endif + + /* + * Notify CRMU that now it should pull logs from DDR instead of from + * FS4 SRAM. + */ + SCP_WRITE_CFG(flash_log.can_use_ddr, 1); +} +#endif + +bool is_crmu_alive(void) +{ + return (scp_send_cmd(MCU_IPC_MCU_CMD_NOP, 0, SCP_CMD_DEFAULT_TIMEOUT_US) + == 0); +} + +bool bcm_scp_issue_sys_reset(void) +{ + return (scp_send_cmd(MCU_IPC_MCU_CMD_L1_RESET, 0, + SCP_CMD_DEFAULT_TIMEOUT_US)); +} + +/* + * Note that this is just a temporary implementation until + * channels are introduced + */ + +int plat_bcm_bl2_plat_handle_scp_bl2(image_info_t *scp_bl2_image_info) +{ + int scp_patch_activated, scp_patch_version; +#ifndef EMULATION_SETUP + uint8_t active_ch_bitmap, i; +#endif + uint32_t reset_state = 0; + uint32_t mcu_ap_init_param = 0; + + /* + * First check if SCP patch has already been loaded + * Send NOP command and see if there is a valid response + */ + scp_patch_activated = + (scp_send_cmd(MCU_IPC_MCU_CMD_NOP, 0, + SCP_CMD_DEFAULT_TIMEOUT_US) == 0); + if (scp_patch_activated) { + INFO("SCP Patch is already active.\n"); + + reset_state = SCP_READ_CFG(board_cfg.reset_state); + mcu_ap_init_param = SCP_READ_CFG(board_cfg.mcu_init_param); + + /* Clear reset state, it's been already read */ + SCP_WRITE_CFG(board_cfg.reset_state, 0); + + if (mcu_ap_init_param & MCU_PATCH_LOADED_BY_NITRO) { + /* + * Reset "MCU_PATCH_LOADED_BY_NITRO" flag, but + * Preserve any other flags we don't deal with here + */ + INFO("AP booted by Nitro\n"); + SCP_WRITE_CFG( + board_cfg.mcu_init_param, + mcu_ap_init_param & + ~MCU_PATCH_LOADED_BY_NITRO + ); + } + } else { + /* + * MCU Patch not loaded, so load it. + * MCU patch stamps critical points in REG9 (debug test-point) + * Display its last content here. This helps to locate + * where crash occurred if a CRMU watchdog kicked in. + */ + int ret; + + INFO("MCU Patch Point: 0x%x\n", + mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG9)); + + ret = download_scp_patch((void *)scp_bl2_image_info->image_base, + scp_bl2_image_info->image_size); + if (ret != 0) + return ret; + + VERBOSE("SCP Patch loaded OK.\n"); + + ret = scp_send_cmd(MCU_IPC_MCU_CMD_INIT, + MCU_PATCH_LOADED_BY_AP, + SCP_CMD_SCP_BOOT_TIMEOUT_US); + if (ret) { + ERROR("SCP Patch could not initialize; error %d\n", + ret); + return ret; + } + + INFO("SCP Patch successfully initialized.\n"); + } + + scp_patch_version = scp_send_cmd(MCU_IPC_MCU_CMD_GET_FW_VERSION, 0, + SCP_CMD_DEFAULT_TIMEOUT_US); + INFO("SCP Patch version :0x%x\n", scp_patch_version); + + /* Next block just reports current AVS voltages (if applicable) */ + { + uint16_t vcore_mv, ihost03_mv, ihost12_mv; + + vcore_mv = SCP_READ_CFG16(vcore.millivolts) + + SCP_READ_CFG8(vcore.avs_cfg.additive_margin); + ihost03_mv = SCP_READ_CFG16(ihost03.millivolts) + + SCP_READ_CFG8(ihost03.avs_cfg.additive_margin); + ihost12_mv = SCP_READ_CFG16(ihost12.millivolts) + + SCP_READ_CFG8(ihost12.avs_cfg.additive_margin); + + if (vcore_mv || ihost03_mv || ihost12_mv) { + INFO("AVS voltages from cfg (including margin)\n"); + if (vcore_mv > 0) + INFO("%s\tVCORE: %dmv\n", + SCP_READ_CFG8(vcore.avs_cfg.avs_set) ? + "*" : "n/a", vcore_mv); + if (ihost03_mv > 0) + INFO("%s\tIHOST03: %dmv\n", + SCP_READ_CFG8(ihost03.avs_cfg.avs_set) ? + "*" : "n/a", ihost03_mv); + if (ihost12_mv > 0) + INFO("%s\tIHOST12: %dmv\n", + SCP_READ_CFG8(ihost12.avs_cfg.avs_set) ? + "*" : "n/a", ihost12_mv); + } else { + INFO("AVS settings not applicable\n"); + } + } + +#if (CLEAN_DDR && !defined(MMU_DISABLED) && !defined(EMULATION_SETUP)) + /* This will clean the DDR and enable ECC if set */ + check_ddr_clean(); +#endif + +#if (WARMBOOT_DDR_S3_SUPPORT && ELOG_STORE_MEDIA_DDR) + elog_init_ddr_log(); +#endif + +#ifdef BCM_ELOG + /* Prepare ELOG to use DDR */ + prepare_elog(); +#endif + +#ifndef EMULATION_SETUP + /* Ask ddr_init to save obtained DDR information into DDR */ + ddr_info_save(); +#endif + + /* + * Configure TMON DDR address. + * This cfg is common for all cases + */ + SCP_WRITE_CFG(tmon_cfg.ddr_desc, TMON_SHARED_DDR_ADDRESS); + + if (reset_state == SOFT_RESET_L3 && !mcu_ap_init_param) { + INFO("SCP configuration after L3 RESET done.\n"); + return 0; + } + + if (bcm_chimp_is_nic_mode()) + /* Configure AP WDT to not reset the NIC interface */ + SCP_WRITE_CFG(board_cfg.apwdt_reset_type, SOFT_RESET_L3); + +#if (WARMBOOT_DDR_S3_SUPPORT && ELOG_STORE_MEDIA_DDR) + /* When AP WDog triggers perform L3 reset if DDR err logging enabled */ + SCP_WRITE_CFG(board_cfg.apwdt_reset_type, SOFT_RESET_L3); +#endif + +#ifndef EMULATION_SETUP + +#ifdef DDR_SCRUB_ENA + ddr_scrub_enable(); +#endif + /* Fill the Active channel information */ + active_ch_bitmap = get_active_ddr_channel(); + for (i = 0; i < MAX_NR_DDR_CH; i++) + SCP_WRITE_CFG(ddr_cfg.ddr_cfg[i], + (active_ch_bitmap & BIT(i)) ? 1 : 0); +#endif + return 0; +} -- cgit v1.2.3 From 3942d3a8ea0c1deda44e0bb481876f03b256e25d Mon Sep 17 00:00:00 2001 From: Sheetal Tigadoli Date: Wed, 18 Dec 2019 20:05:09 +0530 Subject: Add BL31 support for Broadcom stingray platform Change-Id: Icfef5b6923dc292e637001045a334c499d346fe9 Signed-off-by: Sheetal Tigadoli --- drivers/brcm/chimp.c | 398 ++++++++++ include/drivers/brcm/chimp_nv_defs.h | 419 ++++++++++ plat/brcm/board/common/board_common.mk | 5 + plat/brcm/board/stingray/include/bl33_info.h | 38 + plat/brcm/board/stingray/include/fsx.h | 37 + plat/brcm/board/stingray/include/iommu.h | 19 + plat/brcm/board/stingray/include/ncsi.h | 32 + plat/brcm/board/stingray/include/paxb.h | 74 ++ plat/brcm/board/stingray/include/paxc.h | 23 + plat/brcm/board/stingray/include/sdio.h | 247 ++++++ plat/brcm/board/stingray/platform.mk | 119 +++ plat/brcm/board/stingray/src/bl31_setup.c | 1068 ++++++++++++++++++++++++++ plat/brcm/board/stingray/src/brcm_pm_ops.c | 16 +- plat/brcm/board/stingray/src/fsx.c | 477 ++++++++++++ plat/brcm/board/stingray/src/iommu.c | 536 +++++++++++++ plat/brcm/board/stingray/src/ncsi.c | 54 ++ plat/brcm/board/stingray/src/paxb.c | 911 ++++++++++++++++++++++ plat/brcm/board/stingray/src/paxc.c | 267 +++++++ plat/brcm/board/stingray/src/sdio.c | 144 ++++ plat/brcm/board/stingray/src/sr_paxb_phy.c | 806 +++++++++++++++++++ 20 files changed, 5689 insertions(+), 1 deletion(-) create mode 100644 drivers/brcm/chimp.c create mode 100644 include/drivers/brcm/chimp_nv_defs.h create mode 100644 plat/brcm/board/stingray/include/bl33_info.h create mode 100644 plat/brcm/board/stingray/include/fsx.h create mode 100644 plat/brcm/board/stingray/include/iommu.h create mode 100644 plat/brcm/board/stingray/include/ncsi.h create mode 100644 plat/brcm/board/stingray/include/paxb.h create mode 100644 plat/brcm/board/stingray/include/paxc.h create mode 100644 plat/brcm/board/stingray/include/sdio.h create mode 100644 plat/brcm/board/stingray/src/bl31_setup.c create mode 100644 plat/brcm/board/stingray/src/fsx.c create mode 100644 plat/brcm/board/stingray/src/iommu.c create mode 100644 plat/brcm/board/stingray/src/ncsi.c create mode 100644 plat/brcm/board/stingray/src/paxb.c create mode 100644 plat/brcm/board/stingray/src/paxc.c create mode 100644 plat/brcm/board/stingray/src/sdio.c create mode 100644 plat/brcm/board/stingray/src/sr_paxb_phy.c diff --git a/drivers/brcm/chimp.c b/drivers/brcm/chimp.c new file mode 100644 index 000000000..81767bb5b --- /dev/null +++ b/drivers/brcm/chimp.c @@ -0,0 +1,398 @@ +/* + * Copyright (c) 2016 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include + +#include +#include + +#define CHIMP_DEFAULT_STARTUP_ADDR 0xb4300000 + +/* ChiMP's view of APE scratchpad memory for fastboot */ +#define CHIMP_FASTBOOT_ADDR 0x61000000 + +#define CHIMP_PREPARE_ACCESS_WINDOW(addr) \ + (\ + mmio_write_32(\ + NIC400_NITRO_CHIMP_S_IDM_IO_CONTROL_DIRECT, \ + addr & 0xffc00000)\ + ) +#define CHIMP_INDIRECT_TGT_ADDR(addr) \ + (CHIMP_INDIRECT_BASE + (addr & CHIMP_INDIRECT_ADDR_MASK)) + +#define CHIMP_CTRL_ADDR(x) (CHIMP_REG_CTRL_BASE + x) + +/* For non-PAXC builds */ +#ifndef CHIMP_FB1_ENTRY +#define CHIMP_FB1_ENTRY 0 +#endif + +#define CHIMP_DBG VERBOSE + +void bcm_chimp_write(uintptr_t addr, uint32_t value) +{ + CHIMP_PREPARE_ACCESS_WINDOW(addr); + mmio_write_32(CHIMP_INDIRECT_TGT_ADDR(addr), value); +} + +uint32_t bcm_chimp_read(uintptr_t addr) +{ + CHIMP_PREPARE_ACCESS_WINDOW(addr); + return mmio_read_32(CHIMP_INDIRECT_TGT_ADDR(addr)); +} + +void bcm_chimp_clrbits(uintptr_t addr, uint32_t bits) +{ + CHIMP_PREPARE_ACCESS_WINDOW(addr); + mmio_clrbits_32(CHIMP_INDIRECT_TGT_ADDR(addr), bits); +} + +void bcm_chimp_setbits(uintptr_t addr, uint32_t bits) +{ + CHIMP_PREPARE_ACCESS_WINDOW(addr); + mmio_setbits_32(CHIMP_INDIRECT_TGT_ADDR(addr), bits); +} + +int bcm_chimp_is_nic_mode(void) +{ + uint32_t val; + + /* Check if ChiMP straps are set */ + val = mmio_read_32(CDRU_CHIP_STRAP_DATA_LSW); + val &= CDRU_CHIP_STRAP_DATA_LSW__NIC_MODE_MASK; + + return val == CDRU_CHIP_STRAP_DATA_LSW__NIC_MODE_MASK; +} + +void bcm_chimp_fru_prog_done(bool is_done) +{ + uint32_t val; + + val = is_done ? (1 << CHIMP_FRU_PROG_DONE_BIT) : 0; + bcm_chimp_setbits(CHIMP_REG_ECO_RESERVED, val); +} + +int bcm_chimp_handshake_done(void) +{ + uint32_t value; + + value = bcm_chimp_read(CHIMP_REG_ECO_RESERVED); + value &= (1 << CHIMP_FLASH_ACCESS_DONE_BIT); + + return value != 0; +} + +int bcm_chimp_wait_handshake(void) +{ + uint32_t timeout = CHIMP_HANDSHAKE_TIMEOUT_MS; + uint32_t status; + + INFO("Waiting for ChiMP handshake...\n"); + do { + if (bcm_chimp_handshake_done()) + break; + /* No need to wait if ChiMP reported an error */ + status = bcm_chimp_read_ctrl(CHIMP_REG_CTRL_BPE_STAT_REG); + if (status & CHIMP_ERROR_MASK) { + ERROR("ChiMP error 0x%x. Wait aborted\n", status); + break; + } + mdelay(1); + } while (--timeout); + + if (!bcm_chimp_handshake_done()) { + if (timeout == 0) { + WARN("Timeout waiting for ChiMP handshake\n"); + } + } else { + INFO("Got handshake from ChiMP!\n"); + } + + return bcm_chimp_handshake_done(); +} + +uint32_t bcm_chimp_read_ctrl(uint32_t offset) +{ + return bcm_chimp_read(CHIMP_CTRL_ADDR(offset)); +} + +static int bcm_chimp_nitro_reset(void) +{ + uint32_t timeout; + + /* Perform tasks done by M0 in NIC mode */ + CHIMP_DBG("Taking Nitro out of reset\n"); + mmio_setbits_32(CDRU_MISC_RESET_CONTROL, + /* MHB_RESET_N */ + (1 << CDRU_MISC_RESET_CONTROL__CDRU_MHB_RESET_N_R) | + /* PCI_RESET_N */ + (1 << CDRU_MISC_RESET_CONTROL__CDRU_PCIE_RESET_N_R) | + /* PM_RESET_N */ + (1 << CDRU_MISC_RESET_CONTROL__CDRU_PM_RESET_N_R) | + /* NIC_RESET_N */ + (1 << CDRU_MISC_RESET_CONTROL__CDRU_NITRO_RESET_N_R) + ); + + /* Wait until Nitro is out of reset */ + timeout = NIC_RESET_RELEASE_TIMEOUT_US; + do { + uint32_t value; + + value = bcm_chimp_read_ctrl(CHIMP_REG_CTRL_BPE_MODE_REG); + if ((value & CHIMP_BPE_MODE_ID_MASK) == + CHIMP_BPE_MODE_ID_PATTERN) + break; + udelay(1); + } while (--timeout); + + if (timeout == 0) { + ERROR("NIC reset release timed out\n"); + return -1; + } + + return 0; +} + +static void bcm_nitro_secure_mode_enable(void) +{ + mmio_setbits_32(CDRU_NITRO_CONTROL, + (1 << CDRU_NITRO_CONTROL__CDRU_NITRO_SEC_MODE_R) | + (1 << CDRU_NITRO_CONTROL__CDRU_NITRO_SEC_OVERRIDE_R)); + mmio_write_32(NITRO_TZPC_TZPCDECPROT0clr, + /* NITRO_TZPC */ + 1 << NITRO_TZPC_TZPCDECPROT0clr__DECPROT0_chimp_m_clr_R); +} + +static int bcm_chimp_reset_and_initial_setup(void) +{ + + int err; + uint32_t handshake_reg; + + err = bcm_chimp_nitro_reset(); + if (err) + return err; + + /* Enable Nitro secure mode */ + bcm_nitro_secure_mode_enable(); + + /* Force ChiMP back into reset */ + bcm_chimp_setbits(CHIMP_CTRL_ADDR(CHIMP_REG_CTRL_BPE_MODE_REG), + 1 << CHIMP_REG_CHIMP_REG_CTRL_BPE_MODE_REG__cm3_rst_R); + + handshake_reg = (1 << SR_IN_SMARTNIC_MODE_BIT); + + /* Get OTP secure Chimp boot status */ + if (mmio_read_32(CRMU_OTP_STATUS) & (1 << CRMU_OTP_STATUS_BIT)) + handshake_reg |= (1 << SR_CHIMP_SECURE_BOOT_BIT); + + bcm_chimp_write(CHIMP_REG_ECO_RESERVED, handshake_reg); + + CHIMP_DBG("ChiMP reset and initial handshake parameters set\n"); + + return 0; +} + +static void bcm_nitro_chimp_release_reset(void) +{ + bcm_chimp_clrbits(CHIMP_CTRL_ADDR(CHIMP_REG_CTRL_BPE_MODE_REG), + 1 << CHIMP_REG_CHIMP_REG_CTRL_BPE_MODE_REG__cm3_rst_R); + + CHIMP_DBG("Nitro Reset Released\n"); +} + +static void bcm_chimp_set_fastboot(int mode) +{ + uint32_t fb_entry; + + /* 1. Enable fastboot */ + bcm_chimp_setbits(CHIMP_CTRL_ADDR(CHIMP_REG_CTRL_BPE_MODE_REG), + (1 << CHIMP_FAST_BOOT_MODE_BIT)); + fb_entry = CHIMP_FASTBOOT_ADDR | mode; + if (mode == CHIMP_FASTBOOT_JUMP_IN_PLACE) + fb_entry = CHIMP_FB1_ENTRY; + /* 2. Write startup address and mode */ + INFO("Setting fastboot type %d entry to 0x%x\n", mode, fb_entry); + bcm_chimp_write( + CHIMP_CTRL_ADDR(CHIMP_REG_CTRL_FSTBOOT_PTR_REG), + fb_entry); +} + +#ifndef CHIMPFW_USE_SIDELOAD +static void bcm_chimp_load_fw_from_spi(uintptr_t spi_addr, size_t size) +{ + uintptr_t ape_scpad; + uintptr_t dest; + size_t bytes_left; + + ape_scpad = CHIMP_REG_CHIMP_APE_SCPAD; + dest = CHIMP_INDIRECT_TGT_ADDR(CHIMP_REG_CHIMP_APE_SCPAD); + bytes_left = size; + + while (bytes_left) { + uint32_t delta; + + delta = bytes_left > CHIMP_WINDOW_SIZE ? + bytes_left - CHIMP_WINDOW_SIZE : bytes_left; + CHIMP_PREPARE_ACCESS_WINDOW(ape_scpad); + INFO("Transferring %d byte(s) from 0x%lx to 0x%lx\n", + delta, spi_addr, dest); + /* + * This single memcpy call takes significant amount of time + * on Palladium. Be patient + */ + memcpy((void *)dest, (void *)spi_addr, delta); + bytes_left -= delta; + INFO("Transferred %d byte(s) from 0x%lx to 0x%lx (%lu%%)\n", + delta, spi_addr, dest, + ((size - bytes_left) * 100)/size); + spi_addr += delta; + dest += delta; + ape_scpad += delta; + } +} + +static int bcm_chimp_find_fw_in_spi(uintptr_t *addr, size_t *size) +{ + int i; + bnxnvm_master_block_header_t *master_block_hdr; + bnxnvm_directory_block_header_t *dir_block_hdr; + bnxnvm_directory_entry_t *dir_entry; + int found; + + found = 0; + + /* Read the master block */ + master_block_hdr = + (bnxnvm_master_block_header_t *)(uintptr_t)QSPI_BASE_ADDR; + if (master_block_hdr->sig != BNXNVM_MASTER_BLOCK_SIG) { + WARN("Invalid masterblock 0x%x (expected 0x%x)\n", + master_block_hdr->sig, + BNXNVM_MASTER_BLOCK_SIG); + return -NV_NOT_NVRAM; + } + if ((master_block_hdr->block_size > NV_MAX_BLOCK_SIZE) || + (master_block_hdr->directory_offset >= + master_block_hdr->nvram_size)) { + WARN("Invalid masterblock block size 0x%x or directory offset 0x%x\n", + master_block_hdr->block_size, + master_block_hdr->directory_offset); + return -NV_BAD_MB; + } + + /* Skip to the Directory block start */ + dir_block_hdr = + (bnxnvm_directory_block_header_t *) + ((uintptr_t)QSPI_BASE_ADDR + + master_block_hdr->directory_offset); + if (dir_block_hdr->sig != BNXNVM_DIRECTORY_BLOCK_SIG) { + WARN("Invalid directory header 0x%x (expected 0x%x)\n", + dir_block_hdr->sig, + BNXNVM_DIRECTORY_BLOCK_SIG); + return -NV_BAD_DIR_HEADER; + } + + /* Locate the firmware */ + for (i = 0; i < dir_block_hdr->entries; i++) { + *addr = ((uintptr_t)dir_block_hdr + dir_block_hdr->length + + i * dir_block_hdr->entry_length); + dir_entry = (bnxnvm_directory_entry_t *)(*addr); + if ((dir_entry->type == BNX_DIR_TYPE_BOOTCODE) || + (dir_entry->type == BNX_DIR_TYPE_BOOTCODE_2)) { + found = 1; + break; + } + } + + if (!found) + return -NV_FW_NOT_FOUND; + + *addr = QSPI_BASE_ADDR + dir_entry->item_location; + *size = dir_entry->data_length; + + INFO("Found chimp firmware at 0x%lx, size %lu byte(s)\n", + *addr, *size); + + return NV_OK; +} +#endif + +int bcm_chimp_initiate_fastboot(int fastboot_type) +{ + int err; + + if ((fastboot_type != CHIMP_FASTBOOT_NITRO_RESET) && + (fastboot_type <= CHIMP_FASTBOOT_JUMP_DECOMPRESS)) { + CHIMP_DBG("Initiating ChiMP fastboot type %d\n", fastboot_type); + } + + /* + * If we are here, M0 did not setup Nitro because NIC mode + * strap was not present + */ + err = bcm_chimp_reset_and_initial_setup(); + if (err) + return err; + + if (fastboot_type > CHIMP_FASTBOOT_JUMP_DECOMPRESS) { + WARN("ChiMP setup deferred\n"); + return -1; + } + + if (fastboot_type != CHIMP_FASTBOOT_NITRO_RESET) { + + if ((fastboot_type == CHIMP_FASTBOOT_JUMP_IN_PLACE) && + (CHIMP_FB1_ENTRY == 0)) { + ERROR("Missing ESAL entry point for fastboot type 1.\n" + "Fastboot failed\n"); + return -1; + } + + /* + * TODO: We need to think of the way to load the ChiMP fw. + * This could be SPI, NAND, etc. + * For now we temporarily stick to the SPI load unless + * CHIMPFW_USE_SIDELOAD is defined. Note that for the SPI NVRAM + * image we need to parse directory and get the image. + * When we load image from other media there is no need to + * parse because fw image can be directly placed into the APE's + * scratchpad. + * For sideload method we simply reset the ChiMP, set bpe_reg + * to do fastboot with the type we define, and release from + * reset so that ROM loader would initiate fastboot immediately + */ +#ifndef CHIMPFW_USE_SIDELOAD + { + uintptr_t spi_addr; + size_t size; + + err = bcm_chimp_find_fw_in_spi(&spi_addr, &size); + if (!err) { + INFO("Loading ChiMP firmware, addr 0x%lx, size %lu byte(s)\n", + spi_addr, size); + bcm_chimp_load_fw_from_spi(spi_addr, size); + } else { + ERROR("Error %d ChiMP firmware not in NVRAM directory!\n", + err); + } + } +#else + INFO("Skip ChiMP QSPI fastboot type %d due to sideload requested\n", + fastboot_type); +#endif + if (!err) { + INFO("Instruct ChiMP to fastboot\n"); + bcm_chimp_set_fastboot(fastboot_type); + INFO("Fastboot mode set\n"); + } + } + + bcm_nitro_chimp_release_reset(); + + return err; +} diff --git a/include/drivers/brcm/chimp_nv_defs.h b/include/drivers/brcm/chimp_nv_defs.h new file mode 100644 index 000000000..9be361f6e --- /dev/null +++ b/include/drivers/brcm/chimp_nv_defs.h @@ -0,0 +1,419 @@ +/* + * Copyright (c) 2016 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef BNXNVM_DEFS_H +#define BNXNVM_DEFS_H + +#if defined(__GNUC__) + #define PACKED_STRUCT __packed +#else /* non-GCC compiler */ + +#ifndef DOS_DRIVERS + #pragma pack(push) + #pragma pack(1) +#endif + #define PACKED_STRUCT +#endif + +typedef uint32_t u32_t; +typedef uint8_t u8_t; +typedef uint16_t u16_t; + +#define BNXNVM_DEFAULT_BLOCK_SIZE 4096 +#define BNXNVM_UNUSED_BYTE_VALUE 0xff + +#define NV_MAX_BLOCK_SIZE 16384 + +#define BITS_PER_BYTE (8) +#define SIZEOF_IN_BITS(x) (sizeof(x)*BITS_PER_BYTE) + +/************************/ +/* byte-swapping macros */ +/************************/ +#define BYTE_SWAP_16(x) \ + ((((u16_t)(x) & 0xff00) >> 8) | \ + (((u16_t)(x) & 0x00ff) << 8)) +#define BYTE_SWAP_32(x) \ + ((((u32_t)(x) & 0xff000000) >> 24) | \ + (((u32_t)(x) & 0x00ff0000) >> 8) | \ + (((u32_t)(x) & 0x0000ff00) << 8) | \ + (((u32_t)(x) & 0x000000ff) << 24)) + +/* auto-detect integer size */ +#define BYTE_SWAP_INT(x) \ + (SIZEOF_IN_BITS(x) == 16 ? BYTE_SWAP_16(x) : \ + SIZEOF_IN_BITS(x) == 32 ? BYTE_SWAP_32(x) : (x)) + +/********************************/ +/* Architecture-specific macros */ +/********************************/ +#ifdef __BIG_ENDIAN__ /* e.g. Motorola */ + + #define BE_INT16(x) (x) + #define BE_INT32(x) (x) + #define BE_INT(x) (x) + #define LE_INT16(x) BYTE_SWAP_16(x) + #define LE_INT32(x) BYTE_SWAP_32(x) + #define LE_INT(x) BYTE_SWAP_INT(x) + +#else /* Little Endian (e.g. Intel) */ + + #define LE_INT16(x) (x) + #define LE_INT32(x) (x) + #define LE_INT(x) (x) + #define BE_INT16(x) BYTE_SWAP_16(x) + #define BE_INT32(x) BYTE_SWAP_32(x) + #define BE_INT(x) BYTE_SWAP_INT(x) + +#endif + + +enum { + NV_OK = 0, + NV_NOT_NVRAM, + NV_BAD_MB, + NV_BAD_DIR_HEADER, + NV_BAD_DIR_ENTRY, + NV_FW_NOT_FOUND, +}; + +typedef struct { +#define BNXNVM_MASTER_BLOCK_SIG BE_INT32(0x424E5834) /*"BNX4"*/ + /* Signature*/ + u32_t sig; + /* Length of Master Block Header, in bytes [32] */ + u32_t length; + /* Block size, in bytes [4096] */ + u32_t block_size; + /* Byte-offset to Directory Block (translated) */ + u32_t directory_offset; + /* Byte-offset to Block Redirection Table (non-translated) */ + u32_t redirect_offset; + /* Size, in bytes of Reserved Blocks region (at end of NVRAM) */ + u32_t reserved_size; + /* + * Size of NVRAM (in bytes) - may be used to + * override auto-detected size + */ + u32_t nvram_size; + /* CRC-32 (IEEE 802.3 compatible) of the above */ + u32_t chksum; +} PACKED_STRUCT bnxnvm_master_block_header_t; + +typedef struct { +#define BNXNVM_DIRECTORY_BLOCK_SIG BE_INT32(0x44697230) /* "Dir0" */ + /* Signature */ + u32_t sig; + /* Length of Directory Header, in bytes [16] */ + u32_t length; + /* Number of Directory Entries */ + u32_t entries; + /* Length of each Directory Entry, in bytes [24] */ + u32_t entry_length; +} PACKED_STRUCT bnxnvm_directory_block_header_t; + +typedef struct { + /* Directory Entry Type (see enum bnxnvm_directory_type) */ + u16_t type; + /* Instance of this Directory Entry type (0-based) */ + u16_t ordinal; + /* + * Directory Entry Extension flags used to identify + * secondary instances of a type:ordinal combinations + */ + u16_t ext; + /* Directory Entry Attribute flags used to describe the item contents */ + u16_t attr; + /* Item location in NVRAM specified as offset (in bytes) */ + u32_t item_location; + /* + * Length of NVRAM item in bytes + * (including padding - multiple of block size) + */ + u32_t item_length; + /* Length of item data in bytes (excluding padding) */ + u32_t data_length; + /* + * CRC-32 (IEEE 802.3 compatible) of item data + * (excluding padding) (optional) + */ + u32_t data_chksum; +} PACKED_STRUCT bnxnvm_directory_entry_t; + +enum bnxnvm_version_format { + /* US-ASCII string (not necessarily null-terminated) */ + BNX_VERSION_FMT_ASCII = 0, + /* Each field 16-bits, displayed as unpadded decimal (e.g. "1.2.3.4") */ + BNX_VERSION_FMT_DEC = 1, + /* A single hexadecimal value, up to 64-bits (no dots) */ + BNX_VERSION_FMT_HEX = 2, + /* Multiple version values (three 8-bit version fields) */ + BNX_VERSION_FMT_MULTI = 3 +}; + +/* This structure definition must not change: */ +typedef struct { + u16_t flags; /* bit-flags (defaults to 0x0000) */ + u8_t version_format; /* enum bnxnvm_version_format */ + u8_t version_length; /* in bytes */ + u8_t version[16]; /* version value */ + u16_t dir_type; /* enum bnxnvm_directory_type */ + /* size of the entire trailer (to locate end of component data) */ + u16_t trailer_length; +#define BNXNVM_COMPONENT_TRAILER_SIG BE_INT32(0x54726c72) /* "Trlr" */ + u32_t sig; + u32_t chksum; /* CRC-32 of all bytes to this point */ +} PACKED_STRUCT bnxnvm_component_trailer_base_t; + +typedef struct { + /* + * new trailer members (e.g. digital signature) + * go here (insert at top): + */ + u8_t rsa_sig[256]; /* 2048-bit RSA-encrypted SHA-256 hash */ + bnxnvm_component_trailer_base_t base; +} PACKED_STRUCT bnxnvm_component_trailer_t; + +#define BNX_MAX_LEN_DIR_NAME 12 +#define BNX_MAX_LEN_DIR_DESC 50 +/********************************************************* + * NVRAM Directory Entry/Item Types, Names, and Descriptions + * + * If you see a name or description that needs improvement, + * please correct it or raise for discussion. + * When adding a new directory type, it would be appreciated + * if you also updated ../../libs/nvm/bnxt_nvm_str.c. + * DIR_NAME macros may contain up to 12 alpha-numeric + * US-ASCII characters only, camelCase is preferred for clarity. + * DIR_DESC macros may contain up to 50 US-ASCII characters + * providing a verbose description of the directory type. + */ +enum bnxnvm_directory_type { + /* 0x00 Unused directory entry, available for use */ + BNX_DIR_TYPE_UNUSED = 0, +#define BNX_DIR_NAME_UNUSED "unused" +#define BNX_DIR_DESC_UNUSED "Deleted directory entry, available for reuse" + /* 0x01 Package installation log */ + BNX_DIR_TYPE_PKG_LOG = 1, +#define BNX_DIR_NAME_PKG_LOG "pkgLog" +#define BNX_DIR_DESC_PKG_LOG "Package Installation Log" + BNX_DIR_TYPE_CHIMP_PATCH = 3, +#define BNX_DIR_NAME_CHIMP_PATCH "chimpPatch" +#define BNX_DIR_DESC_CHIMP_PATCH "ChiMP Patch Firmware" + /* 0x04 ChiMP firmware: Boot Code phase 1 */ + BNX_DIR_TYPE_BOOTCODE = 4, +#define BNX_DIR_NAME_BOOTCODE "chimpBoot" +#define BNX_DIR_DESC_BOOTCODE "Chip Management Processor Boot Firmware" + /* 0x05 VPD data block */ + BNX_DIR_TYPE_VPD = 5, +#define BNX_DIR_NAME_VPD "VPD" +#define BNX_DIR_DESC_VPD "Vital Product Data" + /* 0x06 Exp ROM MBA */ + BNX_DIR_TYPE_EXP_ROM_MBA = 6, +#define BNX_DIR_NAME_EXP_ROM_MBA "MBA" +#define BNX_DIR_DESC_EXP_ROM_MBA "Multiple Boot Agent Expansion ROM" + BNX_DIR_TYPE_AVS = 7, /* 0x07 AVS FW */ +#define BNX_DIR_NAME_AVS "AVS" +#define BNX_DIR_DESC_AVS "Adaptive Voltage Scaling Firmware" + BNX_DIR_TYPE_PCIE = 8, /* 0x08 PCIE FW */ +#define BNX_DIR_NAME_PCIE "PCIEucode" +#define BNX_DIR_DESC_PCIE "PCIe Microcode" + BNX_DIR_TYPE_PORT_MACRO = 9, /* 0x09 PORT MACRO FW */ +#define BNX_DIR_NAME_PORT_MACRO "portMacro" +#define BNX_DIR_DESC_PORT_MACRO "Port Macro Firmware" + BNX_DIR_TYPE_APE_FW = 10, /* 0x0A APE Firmware */ +#define BNX_DIR_NAME_APE_FW "apeFW" +#define BNX_DIR_DESC_APE_FW "Application Processing Engine Firmware" + /* 0x0B Patch firmware executed by APE ROM */ + BNX_DIR_TYPE_APE_PATCH = 11, +#define BNX_DIR_NAME_APE_PATCH "apePatch" +#define BNX_DIR_DESC_APE_PATCH "APE Patch Firmware" + BNX_DIR_TYPE_KONG_FW = 12, /* 0x0C Kong Firmware */ +#define BNX_DIR_NAME_KONG_FW "kongFW" +#define BNX_DIR_DESC_KONG_FW "Kong Firmware" + /* 0x0D Patch firmware executed by Kong ROM */ + BNX_DIR_TYPE_KONG_PATCH = 13, +#define BNX_DIR_NAME_KONG_PATCH "kongPatch" +#define BNX_DIR_DESC_KONG_PATCH "Kong Patch Firmware" + BNX_DIR_TYPE_BONO_FW = 14, /* 0x0E Bono Firmware */ +#define BNX_DIR_NAME_BONO_FW "bonoFW" +#define BNX_DIR_DESC_BONO_FW "Bono Firmware" + /* 0x0F Patch firmware executed by Bono ROM */ + BNX_DIR_TYPE_BONO_PATCH = 15, +#define BNX_DIR_NAME_BONO_PATCH "bonoPatch" +#define BNX_DIR_DESC_BONO_PATCH "Bono Patch Firmware" + BNX_DIR_TYPE_TANG_FW = 16, /* 0x10 Tang firmware */ +#define BNX_DIR_NAME_TANG_FW "tangFW" +#define BNX_DIR_DESC_TANG_FW "Tang Firmware" + /* 0x11 Patch firmware executed by Tang ROM */ + BNX_DIR_TYPE_TANG_PATCH = 17, +#define BNX_DIR_NAME_TANG_PATCH "tangPatch" +#define BNX_DIR_DESC_TANG_PATCH "Tang Patch Firmware" + /* 0x12 ChiMP firmware: Boot Code phase 2 (loaded by phase 1) */ + BNX_DIR_TYPE_BOOTCODE_2 = 18, +#define BNX_DIR_NAME_BOOTCODE_2 "chimpHWRM" +#define BNX_DIR_DESC_BOOTCODE_2 "ChiMP Hardware Resource Manager Firmware" + BNX_DIR_TYPE_CCM = 19, /* 0x13 CCM ROM binary */ +#define BNX_DIR_NAME_CCM "CCM" +#define BNX_DIR_DESC_CCM "Comprehensive Configuration Management" + /* 0x14 PCI-IDs, PCI-related configuration properties */ + BNX_DIR_TYPE_PCI_CFG = 20, +#define BNX_DIR_NAME_PCI_CFG "pciCFG" +#define BNX_DIR_DESC_PCI_CFG "PCIe Configuration Data" + + BNX_DIR_TYPE_TSCF_UCODE = 21, /* 0x15 TSCF micro-code */ +#define BNX_DIR_NAME_TSCF_UCODE "PHYucode" +#define BNX_DIR_DESC_TSCF_UCODE "Falcon PHY Microcode" + BNX_DIR_TYPE_ISCSI_BOOT = 22, /* 0x16 iSCSI Boot */ +#define BNX_DIR_NAME_ISCSI_BOOT "iSCSIboot" +#define BNX_DIR_DESC_ISCSI_BOOT "iSCSI Boot Software Initiator" + /* 0x18 iSCSI Boot IPV6 - ***DEPRECATED*** */ + BNX_DIR_TYPE_ISCSI_BOOT_IPV6 = 24, + /* 0x19 iSCSI Boot IPV4N6 - ***DEPRECATED*** */ + BNX_DIR_TYPE_ISCSI_BOOT_IPV4N6 = 25, + BNX_DIR_TYPE_ISCSI_BOOT_CFG = 26, /* 0x1a iSCSI Boot CFG v6 */ +#define BNX_DIR_NAME_ISCSI_BOOT_CFG "iSCSIcfg" +#define BNX_DIR_DESC_ISCSI_BOOT_CFG "iSCSI Boot Configuration Data" + BNX_DIR_TYPE_EXT_PHY = 27, /* 0x1b External PHY FW */ +#define BNX_DIR_NAME_EXT_PHY "extPHYfw" +#define BNX_DIR_DESC_EXT_PHY "External PHY Firmware" + BNX_DIR_TYPE_MODULES_PN = 28, /* 0x1c Modules PartNum list */ +#define BNX_DIR_NAME_MODULES_PN "modPartNums" +#define BNX_DIR_DESC_MODULES_PN "Optical Modules Part Number List" + BNX_DIR_TYPE_SHARED_CFG = 40, /* 0x28 shared configuration block */ +#define BNX_DIR_NAME_SHARED_CFG "sharedCFG" +#define BNX_DIR_DESC_SHARED_CFG "Shared Configuration Data" + BNX_DIR_TYPE_PORT_CFG = 41, /* 0x29 port configuration block */ +#define BNX_DIR_NAME_PORT_CFG "portCFG" +#define BNX_DIR_DESC_PORT_CFG "Port Configuration Data" + BNX_DIR_TYPE_FUNC_CFG = 42, /* 0x2A func configuration block */ +#define BNX_DIR_NAME_FUNC_CFG "funcCFG" +#define BNX_DIR_DESC_FUNC_CFG "Function Configuration Data" + + /* Management Firmware (TruManage) related dir entries*/ + /* 0x30 Management firmware configuration (see BMCFG library)*/ + BNX_DIR_TYPE_MGMT_CFG = 48, +#define BNX_DIR_NAME_MGMT_CFG "mgmtCFG" +#define BNX_DIR_DESC_MGMT_CFG "Out-of-band Management Configuration Data" + BNX_DIR_TYPE_MGMT_DATA = 49, /* 0x31 "Opaque Management Data" */ +#define BNX_DIR_NAME_MGMT_DATA "mgmtData" +#define BNX_DIR_DESC_MGMT_DATA "Out-of-band Management Data" + BNX_DIR_TYPE_MGMT_WEB_DATA = 50, /* 0x32 "Web GUI" file data */ +#define BNX_DIR_NAME_MGMT_WEB_DATA "webData" +#define BNX_DIR_DESC_MGMT_WEB_DATA "Out-of-band Management Web Data" + /* 0x33 "Web GUI" file metadata */ + BNX_DIR_TYPE_MGMT_WEB_META = 51, +#define BNX_DIR_NAME_MGMT_WEB_META "webMeta" +#define BNX_DIR_DESC_MGMT_WEB_META "Out-of-band Management Web Metadata" + /* 0x34 Management firmware Event Log (a.k.a. "SEL") */ + BNX_DIR_TYPE_MGMT_EVENT_LOG = 52, +#define BNX_DIR_NAME_MGMT_EVENT_LOG "eventLog" +#define BNX_DIR_DESC_MGMT_EVENT_LOG "Out-of-band Management Event Log" + /* 0x35 Management firmware Audit Log */ + BNX_DIR_TYPE_MGMT_AUDIT_LOG = 53 +#define BNX_DIR_NAME_MGMT_AUDIT_LOG "auditLog" +#define BNX_DIR_DESC_MGMT_AUDIT_LOG "Out-of-band Management Audit Log" + +}; + +/* For backwards compatibility only, may be removed later */ +#define BNX_DIR_TYPE_ISCSI_BOOT_CFG6 BNX_DIR_TYPE_ISCSI_BOOT_CFG + +/* Firmware NVM items of "APE BIN" format are identified with + * the following macro: + */ +#define BNX_DIR_TYPE_IS_APE_BIN_FMT(type)\ + ((type) == BNX_DIR_TYPE_CHIMP_PATCH \ + || (type) == BNX_DIR_TYPE_BOOTCODE \ + || (type) == BNX_DIR_TYPE_BOOTCODE_2 \ + || (type) == BNX_DIR_TYPE_APE_FW \ + || (type) == BNX_DIR_TYPE_APE_PATCH \ + || (type) == BNX_DIR_TYPE_TANG_FW \ + || (type) == BNX_DIR_TYPE_TANG_PATCH \ + || (type) == BNX_DIR_TYPE_KONG_FW \ + || (type) == BNX_DIR_TYPE_KONG_PATCH \ + || (type) == BNX_DIR_TYPE_BONO_FW \ + || (type) == BNX_DIR_TYPE_BONO_PATCH \ + ) + +/* Other (non APE BIN) executable NVM items are identified with + * the following macro: + */ +#define BNX_DIR_TYPE_IS_OTHER_EXEC(type)\ + ((type) == BNX_DIR_TYPE_AVS \ + || (type) == BNX_DIR_TYPE_EXP_ROM_MBA \ + || (type) == BNX_DIR_TYPE_PCIE \ + || (type) == BNX_DIR_TYPE_TSCF_UCODE \ + || (type) == BNX_DIR_TYPE_EXT_PHY \ + || (type) == BNX_DIR_TYPE_CCM \ + || (type) == BNX_DIR_TYPE_ISCSI_BOOT \ + ) + +/* Executable NVM items (e.g. microcode, firmware, software) identified + * with the following macro + */ +#define BNX_DIR_TYPE_IS_EXECUTABLE(type) \ + (BNX_DIR_TYPE_IS_APE_BIN_FMT(type) \ + || BNX_DIR_TYPE_IS_OTHER_EXEC(type)) + +#define BNX_DIR_ORDINAL_FIRST 0 /* Ordinals are 0-based */ + +/* No extension flags for this directory entry */ +#define BNX_DIR_EXT_NONE 0 +/* Directory entry is inactive (not used, not hidden, + * not available for reuse) + */ +#define BNX_DIR_EXT_INACTIVE (1 << 0) +/* Directory content is a temporary staging location for + * updating the primary (non-update) directory entry contents + * (e.g. performing a secure firmware update) + */ +#define BNX_DIR_EXT_UPDATE (1 << 1) + +/* No attribute flags set for this directory entry */ +#define BNX_DIR_ATTR_NONE 0 +/* Directory entry checksum of contents is purposely incorrect */ +#define BNX_DIR_ATTR_NO_CHKSUM (1 << 0) +/* Directory contents are in the form of a property-stream + * (e.g. configuration properties) + */ +#define BNX_DIR_ATTR_PROP_STREAM (1 << 1) +/* Directory content (e.g. iSCSI boot) supports IPv4 */ +#define BNX_DIR_ATTR_IPv4 (1 << 2) +/* Directory content (e.g. iSCSI boot) supports IPv6 */ +#define BNX_DIR_ATTR_IPv6 (1 << 3) +/* Directory content includes standard NVM component trailer + * (bnxnvm_component_trailer_t) + */ +#define BNX_DIR_ATTR_TRAILER (1 << 4) + +/* Index of tab-delimited fields in each package log + * (BNX_DIR_TYPE_PKG_LOG) record (\n-terminated line): + */ +enum bnxnvm_pkglog_field_index { + /* Package installation date/time in ISO-8601 format */ + BNX_PKG_LOG_FIELD_IDX_INSTALLED_TIMESTAMP = 0, + /* Installed package description (from package header) or "N/A" */ + BNX_PKG_LOG_FIELD_IDX_PKG_DESCRIPTION = 1, + /* Installed package version string (from package header) or "N/A" */ + BNX_PKG_LOG_FIELD_IDX_PKG_VERSION = 2, + /* Installed package creation/modification timestamp (ISO-8601) */ + BNX_PKG_LOG_FIELD_IDX_PKG_TIMESTAMP = 3, + /* Installed package checksum in hexadecimal (CRC-32) or "N/A" */ + BNX_PKG_LOG_FIELD_IDX_PKG_CHECKSUM = 4, + /* Total number of packaged items applied in this installation */ + BNX_PKG_LOG_FIELD_IDX_INSTALLED_ITEMS = 5, + /* Hexadecimal bit-mask identifying which items were installed */ + BNX_PKG_LOG_FIELD_IDX_INSTALLED_MASK = 6 +}; + +#if !defined(__GNUC__) +#ifndef DOS_DRIVERS + #pragma pack(pop) /* original packing */ +#endif +#endif + +#endif /* Don't add anything after this line */ diff --git a/plat/brcm/board/common/board_common.mk b/plat/brcm/board/common/board_common.mk index 3a879de5b..a0112c516 100644 --- a/plat/brcm/board/common/board_common.mk +++ b/plat/brcm/board/common/board_common.mk @@ -80,6 +80,10 @@ ifneq (${BL2_LOG_LEVEL},) $(eval $(call add_define,BL2_LOG_LEVEL)) endif +ifneq (${BL31_LOG_LEVEL},) +$(eval $(call add_define,BL31_LOG_LEVEL)) +endif + # Use CRMU SRAM from iHOST ifneq (${USE_CRMU_SRAM},) $(eval $(call add_define,USE_CRMU_SRAM)) @@ -123,6 +127,7 @@ BL31_SOURCES += plat/brcm/common/brcm_bl31_setup.c ifeq (${BCM_ELOG},yes) ELOG_SOURCES += plat/brcm/board/common/bcm_elog.c BL2_SOURCES += ${ELOG_SOURCES} +BL31_SOURCES += ${ELOG_SOURCES} endif ifeq (${DRIVER_OCOTP_ENABLE},1) diff --git a/plat/brcm/board/stingray/include/bl33_info.h b/plat/brcm/board/stingray/include/bl33_info.h new file mode 100644 index 000000000..1dac48c17 --- /dev/null +++ b/plat/brcm/board/stingray/include/bl33_info.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef BL33_INFO_H +#define BL33_INFO_H + +/* Increase version number each time this file is modified */ +#define BL33_INFO_VERSION 4 + +struct chip_info { + unsigned int chip_id; + unsigned int rev_id; +}; + +struct boot_time_info { + unsigned int bl1_start; + unsigned int bl1_end; + unsigned int bl2_start; + unsigned int bl2_end; + unsigned int bl31_start; + unsigned int bl31_end; + unsigned int bl32_start; + unsigned int bl32_end; + unsigned int bl33_start; + unsigned int bl33_prompt; + unsigned int bl33_end; +}; + +struct bl33_info { + unsigned int version; + struct chip_info chip; + struct boot_time_info boot_time_info; +}; + +#endif diff --git a/plat/brcm/board/stingray/include/fsx.h b/plat/brcm/board/stingray/include/fsx.h new file mode 100644 index 000000000..c52ff0a0d --- /dev/null +++ b/plat/brcm/board/stingray/include/fsx.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2017 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FSX_H +#define FSX_H + +#include + +typedef enum FSX_TYPE { + eFS4_RAID, + eFS4_CRYPTO, + eFS6_PKI, +} eFSX_TYPE; + +void fsx_init(eFSX_TYPE fsx_type, + unsigned int ring_count, + unsigned int dme_count, + unsigned int ae_count, + unsigned int start_stream_id, + unsigned int msi_dev_id, + uintptr_t idm_io_control_direct, + uintptr_t idm_reset_control, + uintptr_t base, + uintptr_t dme_base); + +void fsx_meminit(const char *name, + uintptr_t idm_io_control_direct, + uintptr_t idm_io_status); + +void fs4_disable_clocks(bool disable_sram, + bool disable_crypto, + bool disable_raid); + +#endif /* FSX_H */ diff --git a/plat/brcm/board/stingray/include/iommu.h b/plat/brcm/board/stingray/include/iommu.h new file mode 100644 index 000000000..e7b29854e --- /dev/null +++ b/plat/brcm/board/stingray/include/iommu.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2016 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef IOMMU_H +#define IOMMU_H + +enum iommu_domain { + PCIE_PAXC, + DOMAIN_CRMU, +}; + +void arm_smmu_create_identity_map(enum iommu_domain dom); +void arm_smmu_reserve_secure_cntxt(void); +void arm_smmu_enable_secure_client_port(void); + +#endif /* IOMMU_H */ diff --git a/plat/brcm/board/stingray/include/ncsi.h b/plat/brcm/board/stingray/include/ncsi.h new file mode 100644 index 000000000..04dd64001 --- /dev/null +++ b/plat/brcm/board/stingray/include/ncsi.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2019-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef NCSI_H +#define NCSI_H + +/* + * There are 10 registers for NCSI IO drivers. + */ +#define NITRO_NCSI_IOPAD_CONTROL_NUM 10 +#define NITRO_NCSI_IOPAD_CONTROL_BASE 0x60e05080 + +/* + * NCSI IO Drive strength + * 000 - Drives 2mA + * 001 - Drives 4mA + * 010 - Drives 6mA + * 011 - Drives 8mA + * 100 - Drives 10mA + * 101 - Drives 12mA + * 110 - Drives 14mA + * 111 - Drives 16mA + */ +#define PAD_SELX_VALUE(selx) ((selx) << 1) +#define PAD_SELX_MASK (0x7 << 1) + +void brcm_stingray_ncsi_init(void); + +#endif diff --git a/plat/brcm/board/stingray/include/paxb.h b/plat/brcm/board/stingray/include/paxb.h new file mode 100644 index 000000000..c64c8a6c6 --- /dev/null +++ b/plat/brcm/board/stingray/include/paxb.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2016 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PAXB_H +#define PAXB_H + +/* total number of PCIe cores */ +#define NUM_OF_SR_PCIE_CORES 8 +#define NUM_OF_NS3Z_PCIE_CORES 1 + +/* + * List of PCIe core and PAXB wrapper memory power registers + */ +#define PCIE_CORE_BASE 0x40000800 +#define PCIE_CORE_SOFT_RST_CFG_BASE (PCIE_CORE_BASE + 0x40) +#define PCIE_CORE_SOFT_RST 0x1 +#define PCIE_CORE_ISO_CFG_BASE (PCIE_CORE_BASE + 0x54) +#define PCIE_CORE_MEM_ISO 0x2 +#define PCIE_CORE_ISO 0x1 + +#define PCIE_CORE_MEM_PWR_BASE (PCIE_CORE_BASE + 0x58) +#define PCIE_PAXB_MEM_PWR_BASE (PCIE_CORE_BASE + 0x5c) +#define PCIE_CORE_PMI_CFG_BASE (PCIE_CORE_BASE + 0x64) +#define PCIE_CORE_RESERVED_CFG (PCIE_CORE_BASE + 0x6c) +#define PCIE_CORE_MEM_PWR_STATUS_BASE (PCIE_CORE_BASE + 0x74) +#define PCIE_PAXB_MEM_PWR_STATUS_BASE (PCIE_CORE_BASE + 0x78) +#define PCIE_CORE_PWR_OFFSET 0x100 + +#define SR_A0_DEVICE_ID 0xd713 +#define SR_B0_DEVICE_ID 0xd714 +/* TODO: Modify device ID once available */ +#define NS3Z_DEVICE_ID 0xd715 + +/* FIXME: change link speed to GEN3 when it's ready */ +#define GEN1_LINK_SPEED 1 +#define GEN2_LINK_SPEED 2 +#define GEN3_LINK_SPEED 3 + +typedef struct { + uint32_t type; + uint32_t device_id; + uint32_t pipemux_idx; + uint32_t num_cores; + int (*pipemux_init)(void); + int (*phy_init)(void); + int (*core_needs_enable)(unsigned int core_idx); + unsigned int (*get_link_width)(unsigned int core_idx); + unsigned int (*get_link_speed)(void); +} paxb_cfg; + +enum paxb_type { + PAXB_SR, + PAXB_NS3Z, +}; + +extern const paxb_cfg *paxb; + +#ifdef USE_PAXB +void paxb_init(void); +void paxb_rc_cfg_write(unsigned int core_idx, unsigned int where, + uint32_t val); +unsigned int paxb_rc_cfg_read(unsigned int core_idx, unsigned int where); +int pcie_core_needs_enable(unsigned int core_idx); +const paxb_cfg *paxb_get_sr_config(void); +#else +static inline void paxb_init(void) +{ +} +#endif + +#endif /* PAXB_H */ diff --git a/plat/brcm/board/stingray/include/paxc.h b/plat/brcm/board/stingray/include/paxc.h new file mode 100644 index 000000000..ae1af2ed3 --- /dev/null +++ b/plat/brcm/board/stingray/include/paxc.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2017 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PAXC_H +#define PAXC_H + +#ifdef USE_PAXC +void paxc_init(void); +void paxc_mhb_ns_init(void); +#else +static inline void paxc_init(void) +{ +} + +static inline void paxc_mhb_ns_init(void) +{ +} +#endif + +#endif /* PAXC_H */ diff --git a/plat/brcm/board/stingray/include/sdio.h b/plat/brcm/board/stingray/include/sdio.h new file mode 100644 index 000000000..e08904eaa --- /dev/null +++ b/plat/brcm/board/stingray/include/sdio.h @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2019-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SDIO_H +#define SDIO_H + +#include + +#define SR_IPROC_SDIO0_CFG_BASE 0x689006e4 +#define SR_IPROC_SDIO0_SID_BASE 0x68900b00 +#define SR_IPROC_SDIO0_PAD_BASE 0x68a4017c +#define SR_IPROC_SDIO0_IOCTRL_BASE 0x68e02408 + +#define SR_IPROC_SDIO1_CFG_BASE 0x68900734 +#define SR_IPROC_SDIO1_SID_BASE 0x68900b08 +#define SR_IPROC_SDIO1_PAD_BASE 0x68a401b4 +#define SR_IPROC_SDIO1_IOCTRL_BASE 0x68e03408 + +#define NS3Z_IPROC_SDIO0_CFG_BASE 0x68a20540 +#define NS3Z_IPROC_SDIO0_SID_BASE 0x68900b00 +#define NS3Z_IPROC_SDIO0_TP_OUT_SEL 0x68a20308 +#define NS3Z_IPROC_SDIO0_PAD_BASE 0x68a20500 +#define NS3Z_IPROC_SDIO0_IOCTRL_BASE 0x68e02408 + +#define PHY_BYPASS BIT(14) +#define LEGACY_EN BIT(31) +#define PHY_DISABLE (LEGACY_EN | PHY_BYPASS) + +#define NS3Z_IPROC_SDIO1_CFG_BASE 0x68a30540 +#define NS3Z_IPROC_SDIO1_SID_BASE 0x68900b08 +#define NS3Z_IPROC_SDIO1_PAD_BASE 0x68a30500 +#define NS3Z_IPROC_SDIO1_IOCTRL_BASE 0x68e03408 + +#define ICFG_SDIO_CAP0 0x10 +#define ICFG_SDIO_CAP1 0x14 +#define ICFG_SDIO_STRAPSTATUS_0 0x0 +#define ICFG_SDIO_STRAPSTATUS_1 0x4 +#define ICFG_SDIO_STRAPSTATUS_2 0x8 +#define ICFG_SDIO_STRAPSTATUS_3 0xc +#define ICFG_SDIO_STRAPSTATUS_4 0x18 + +#define ICFG_SDIO_SID_ARADDR 0x0 +#define ICFG_SDIO_SID_AWADDR 0x4 + +#define ICFG_SDIOx_CAP0__SLOT_TYPE_MASK 0x3 +#define ICFG_SDIOx_CAP0__SLOT_TYPE_SHIFT 27 +#define ICFG_SDIOx_CAP0__INT_MODE_SHIFT 26 +#define ICFG_SDIOx_CAP0__SYS_BUS_64BIT_SHIFT 25 +#define ICFG_SDIOx_CAP0__VOLTAGE_1P8V_SHIFT 24 +#define ICFG_SDIOx_CAP0__VOLTAGE_3P0V_SHIFT 23 +#define ICFG_SDIOx_CAP0__VOLTAGE_3P3V_SHIFT 22 +#define ICFG_SDIOx_CAP0__SUSPEND_RESUME_SHIFT 21 +#define ICFG_SDIOx_CAP0__SDMA_SHIFT 20 +#define ICFG_SDIOx_CAP0__HIGH_SPEED_SHIFT 19 +#define ICFG_SDIOx_CAP0__ADMA2_SHIFT 18 +#define ICFG_SDIOx_CAP0__EXTENDED_MEDIA_SHIFT 17 +#define ICFG_SDIOx_CAP0__MAX_BLOCK_LEN_MASK 0x3 +#define ICFG_SDIOx_CAP0__MAX_BLOCK_LEN_SHIFT 15 +#define ICFG_SDIOx_CAP0__BASE_CLK_FREQ_MASK 0xff +#define ICFG_SDIOx_CAP0__BASE_CLK_FREQ_SHIFT 7 +#define ICFG_SDIOx_CAP0__TIMEOUT_UNIT_SHIFT 6 +#define ICFG_SDIOx_CAP0__TIMEOUT_CLK_FREQ_MASK 0x3f +#define ICFG_SDIOx_CAP0__TIMEOUT_CLK_FREQ_SHIFT 0 + +#define ICFG_SDIOx_CAP1__SPI_BLOCK_MODE_SHIFT 22 +#define ICFG_SDIOx_CAP1__SPI_MODE_SHIFT 21 +#define ICFG_SDIOx_CAP1__CLK_MULT_MASK 0xff +#define ICFG_SDIOx_CAP1__CLK_MULT_SHIFT 13 +#define ICFG_SDIOx_CAP1__RETUNING_MODE_MASK 0x3 +#define ICFG_SDIOx_CAP1__RETUNING_MODE_SHIFT 11 +#define ICFG_SDIOx_CAP1__TUNE_SDR50_SHIFT 10 +#define ICFG_SDIOx_CAP1__TIME_RETUNE_MASK 0xf +#define ICFG_SDIOx_CAP1__TIME_RETUNE_SHIFT 6 +#define ICFG_SDIOx_CAP1__DRIVER_D_SHIFT 5 +#define ICFG_SDIOx_CAP1__DRIVER_C_SHIFT 4 +#define ICFG_SDIOx_CAP1__DRIVER_A_SHIFT 3 +#define ICFG_SDIOx_CAP1__DDR50_SHIFT 2 +#define ICFG_SDIOx_CAP1__SDR104_SHIFT 1 +#define ICFG_SDIOx_CAP1__SDR50_SHIFT 0 + +#ifdef USE_DDR +#define SDIO_DMA 1 +#else +#define SDIO_DMA 0 +#endif + +#define SDIO0_CAP0_CFG \ + (0x1 << ICFG_SDIOx_CAP0__SLOT_TYPE_SHIFT) \ + | (0x0 << ICFG_SDIOx_CAP0__INT_MODE_SHIFT) \ + | (0x0 << ICFG_SDIOx_CAP0__SYS_BUS_64BIT_SHIFT) \ + | (0x1 << ICFG_SDIOx_CAP0__VOLTAGE_1P8V_SHIFT) \ + | (0x1 << ICFG_SDIOx_CAP0__VOLTAGE_3P0V_SHIFT) \ + | (0x1 << ICFG_SDIOx_CAP0__VOLTAGE_3P3V_SHIFT) \ + | (0x1 << ICFG_SDIOx_CAP0__SUSPEND_RESUME_SHIFT) \ + | (SDIO_DMA << ICFG_SDIOx_CAP0__SDMA_SHIFT) \ + | (SDIO_DMA << ICFG_SDIOx_CAP0__ADMA2_SHIFT) \ + | (0x1 << ICFG_SDIOx_CAP0__HIGH_SPEED_SHIFT) \ + | (0x1 << ICFG_SDIOx_CAP0__EXTENDED_MEDIA_SHIFT) \ + | (0x2 << ICFG_SDIOx_CAP0__MAX_BLOCK_LEN_SHIFT) \ + | (0xc8 << ICFG_SDIOx_CAP0__BASE_CLK_FREQ_SHIFT) \ + | (0x1 << ICFG_SDIOx_CAP0__TIMEOUT_UNIT_SHIFT) \ + | (0x30 << ICFG_SDIOx_CAP0__TIMEOUT_CLK_FREQ_SHIFT) + +#define SDIO0_CAP1_CFG \ + (0x1 << ICFG_SDIOx_CAP1__SPI_BLOCK_MODE_SHIFT)\ + | (0x1 << ICFG_SDIOx_CAP1__SPI_MODE_SHIFT)\ + | (0x0 << ICFG_SDIOx_CAP1__CLK_MULT_SHIFT)\ + | (0x2 << ICFG_SDIOx_CAP1__RETUNING_MODE_SHIFT)\ + | (0x1 << ICFG_SDIOx_CAP1__TUNE_SDR50_SHIFT)\ + | (0x0 << ICFG_SDIOx_CAP1__DRIVER_D_SHIFT)\ + | (0x0 << ICFG_SDIOx_CAP1__DRIVER_C_SHIFT)\ + | (0x1 << ICFG_SDIOx_CAP1__DRIVER_A_SHIFT)\ + | (0x1 << ICFG_SDIOx_CAP1__DDR50_SHIFT)\ + | (0x1 << ICFG_SDIOx_CAP1__SDR104_SHIFT)\ + | (0x1 << ICFG_SDIOx_CAP1__SDR50_SHIFT) + +#define SDIO1_CAP0_CFG \ + (0x0 << ICFG_SDIOx_CAP0__SLOT_TYPE_SHIFT) \ + | (0x0 << ICFG_SDIOx_CAP0__INT_MODE_SHIFT) \ + | (0x0 << ICFG_SDIOx_CAP0__SYS_BUS_64BIT_SHIFT) \ + | (0x1 << ICFG_SDIOx_CAP0__VOLTAGE_1P8V_SHIFT) \ + | (0x1 << ICFG_SDIOx_CAP0__VOLTAGE_3P0V_SHIFT) \ + | (0x1 << ICFG_SDIOx_CAP0__VOLTAGE_3P3V_SHIFT) \ + | (0x1 << ICFG_SDIOx_CAP0__SUSPEND_RESUME_SHIFT) \ + | (SDIO_DMA << ICFG_SDIOx_CAP0__SDMA_SHIFT) \ + | (SDIO_DMA << ICFG_SDIOx_CAP0__ADMA2_SHIFT) \ + | (0x1 << ICFG_SDIOx_CAP0__HIGH_SPEED_SHIFT) \ + | (0x1 << ICFG_SDIOx_CAP0__EXTENDED_MEDIA_SHIFT) \ + | (0x2 << ICFG_SDIOx_CAP0__MAX_BLOCK_LEN_SHIFT) \ + | (0xc8 << ICFG_SDIOx_CAP0__BASE_CLK_FREQ_SHIFT) \ + | (0x1 << ICFG_SDIOx_CAP0__TIMEOUT_UNIT_SHIFT) \ + | (0x30 << ICFG_SDIOx_CAP0__TIMEOUT_CLK_FREQ_SHIFT) + +#define SDIO1_CAP1_CFG \ + (0x1 << ICFG_SDIOx_CAP1__SPI_BLOCK_MODE_SHIFT)\ + | (0x1 << ICFG_SDIOx_CAP1__SPI_MODE_SHIFT)\ + | (0x0 << ICFG_SDIOx_CAP1__CLK_MULT_SHIFT)\ + | (0x2 << ICFG_SDIOx_CAP1__RETUNING_MODE_SHIFT)\ + | (0x1 << ICFG_SDIOx_CAP1__TUNE_SDR50_SHIFT)\ + | (0x0 << ICFG_SDIOx_CAP1__DRIVER_D_SHIFT)\ + | (0x0 << ICFG_SDIOx_CAP1__DRIVER_C_SHIFT)\ + | (0x1 << ICFG_SDIOx_CAP1__DRIVER_A_SHIFT)\ + | (0x1 << ICFG_SDIOx_CAP1__DDR50_SHIFT)\ + | (0x1 << ICFG_SDIOx_CAP1__SDR104_SHIFT)\ + | (0x1 << ICFG_SDIOx_CAP1__SDR50_SHIFT) + +#define PAD_SDIO_CLK 0x4 +#define PAD_SDIO_DATA0 0x8 +#define PAD_SDIO_DATA1 0xc +#define PAD_SDIO_DATA2 0x10 +#define PAD_SDIO_DATA3 0x14 +#define PAD_SDIO_DATA4 0x18 +#define PAD_SDIO_DATA5 0x1c +#define PAD_SDIO_DATA6 0x20 +#define PAD_SDIO_DATA7 0x24 +#define PAD_SDIO_CMD 0x28 + +/* 12mA Drive strength*/ +#define PAD_SDIO_SELX (0x5 << 1) +#define PAD_SDIO_SRC (1 << 0) +#define PAD_SDIO_MASK (0xF << 0) +#define PAD_SDIO_VALUE (PAD_SDIO_SELX | PAD_SDIO_SRC) + +/* + * SDIO_PRESETVAL0 + * + * Each 13 Bit filed consists: + * drivestrength - 12:11 + * clkgensel - b10 + * sdkclkfreqsel - 9:0 + * Field Bit(s) Description + * ============================================================ + * SDR25_PRESET 25:13 Preset Value for SDR25 + * SDR50_PRESET 12:0 Preset Value for SDR50 + */ +#define SDIO_PRESETVAL0 0x01005001 + +/* + * SDIO_PRESETVAL1 + * + * Each 13 Bit filed consists: + * drivestrength - 12:11 + * clkgensel - b10 + * sdkclkfreqsel - 9:0 + * Field Bit(s) Description + * ============================================================ + * SDR104_PRESET 25:13 Preset Value for SDR104 + * SDR12_PRESET 12:0 Preset Value for SDR12 + */ +#define SDIO_PRESETVAL1 0x03000004 + +/* + * SDIO_PRESETVAL2 + * + * Each 13 Bit filed consists: + * drivestrength - 12:11 + * clkgensel - b10 + * sdkclkfreqsel - 9:0 + * Field Bit(s) Description + * ============================================================ + * HIGH_SPEED_PRESET 25:13 Preset Value for High Speed + * INIT_PRESET 12:0 Preset Value for Initialization + */ +#define SDIO_PRESETVAL2 0x010040FA + +/* + * SDIO_PRESETVAL3 + * + * Each 13 Bit filed consists: + * drivestrength - 12:11 + * clkgensel - b10 + * sdkclkfreqsel - 9:0 + * Field Bit(s) Description + * ============================================================ + * DDR50_PRESET 25:13 Preset Value for DDR50 + * DEFAULT_PRESET 12:0 Preset Value for Default Speed + */ +#define SDIO_PRESETVAL3 0x01004004 + +/* + * SDIO_PRESETVAL4 + * + * Field Bit(s) Description + * ============================================================ + * FORCE_USE_IP_TUNE_CLK 30 Force use IP clock + * TUNING_COUNT 29:24 Tuning count + * OVERRIDE_1P8V 23:16 + * OVERRIDE_3P3V 15:8 + * OVERRIDE_3P0V 7:0 + */ +#define SDIO_PRESETVAL4 0x20010101 + +#define SDIO_SID_SHIFT 5 + +typedef struct { + uintptr_t cfg_base; + uintptr_t sid_base; + uintptr_t io_ctrl_base; + uintptr_t pad_base; +} SDIO_CFG; + +void brcm_stingray_sdio_init(void); + +#endif /* SDIO_H */ diff --git a/plat/brcm/board/stingray/platform.mk b/plat/brcm/board/stingray/platform.mk index f4b665ca6..cc7ae5303 100644 --- a/plat/brcm/board/stingray/platform.mk +++ b/plat/brcm/board/stingray/platform.mk @@ -27,8 +27,21 @@ $(eval $(call add_define,DRIVER_CC_ENABLE)) # BL31 is in DRAM ARM_BL31_IN_DRAM := 1 +ifneq (${USE_EMULATOR},yes) +STINGRAY_EMULATION_SETUP := 0 +ifeq (${FASTBOOT_TYPE},) +override FASTBOOT_TYPE := 0 +endif +USE_PAXB := yes +USE_PAXC := yes +USE_CHIMP := yes +endif + USE_CRMU_SRAM := yes +# Disable FS4 clocks - they can be reenabled when needed by linux +FS4_DISABLE_CLOCK := yes + # Enable error logging by default for Stingray BCM_ELOG := yes @@ -53,6 +66,35 @@ ifeq (${BOARD_CFG},) BOARD_CFG := bcm958742k endif +# Use PAXB +ifeq (${USE_PAXB},yes) +$(info Using PAXB) +$(eval $(call add_define,USE_PAXB)) +endif + +# Use FS4 +ifeq (${USE_FS4},yes) +$(info Using FS4) +$(eval $(call add_define,USE_FS4)) +endif + +# Use FS6 +ifeq (${USE_FS6},yes) +$(info Using FS6) +$(eval $(call add_define,USE_FS6)) +endif + +# Disable FS4 clock +ifeq (${FS4_DISABLE_CLOCK},yes) +$(info Using FS4_DISABLE_CLOCK) +$(eval $(call add_define,FS4_DISABLE_CLOCK)) +endif + +ifneq (${NCSI_IO_DRIVE_STRENGTH_MA},) +$(info Using NCSI_IO_DRIVE_STRENGTH_MA) +$(eval $(call add_define,NCSI_IO_DRIVE_STRENGTH_MA)) +endif + # Use NAND ifeq (${USE_NAND},$(filter yes, ${USE_NAND})) $(info Using NAND) @@ -71,6 +113,44 @@ RESET_TO_BL31 := 1 $(info Using RESET_TO_BL31) endif +# BL31 force full frequency for all CPUs +ifeq (${BL31_FORCE_CPU_FULL_FREQ},yes) +$(info Using BL31_FORCE_CPU_FULL_FREQ) +$(eval $(call add_define,BL31_FORCE_CPU_FULL_FREQ)) +endif + +# Enable non-secure accesses to CCN registers +ifeq (${BL31_CCN_NONSECURE},yes) +$(info Using BL31_CCN_NONSECURE) +$(eval $(call add_define,BL31_CCN_NONSECURE)) +endif + +# Use ChiMP +ifeq (${USE_CHIMP},yes) +$(info Using ChiMP) +$(eval $(call add_define,USE_CHIMP)) +endif + +# Use PAXC +ifeq (${USE_PAXC},yes) +$(info Using PAXC) +$(eval $(call add_define,USE_PAXC)) +ifeq (${CHIMPFW_USE_SIDELOAD},yes) +$(info Using ChiMP FW sideload) +$(eval $(call add_define,CHIMPFW_USE_SIDELOAD)) +endif +$(eval $(call add_define,FASTBOOT_TYPE)) +$(eval $(call add_define,CHIMP_FB1_ENTRY)) +endif + +ifeq (${DEFAULT_SWREG_CONFIG}, 1) +$(eval $(call add_define,DEFAULT_SWREG_CONFIG)) +endif + +ifeq (${CHIMP_ALWAYS_NEEDS_QSPI},yes) +$(eval $(call add_define,CHIMP_ALWAYS_NEEDS_QSPI)) +endif + # For testing purposes, use memsys stubs. Remove once memsys is fully tested. USE_MEMSYS_STUBS := yes @@ -100,6 +180,10 @@ PLAT_BL_COMMON_SOURCES += lib/cpus/aarch64/cortex_a72.S \ drivers/arm/tzc/tzc400.c \ plat/${SOC_DIR}/src/topology.c +ifeq (${USE_CHIMP},yes) +PLAT_BL_COMMON_SOURCES += drivers/brcm/chimp.c +endif + BL2_SOURCES += plat/${SOC_DIR}/driver/ihost_pll_config.c \ plat/${SOC_DIR}/src/bl2_setup.c \ plat/${SOC_DIR}/driver/swreg.c @@ -125,8 +209,25 @@ BL31_SOURCES += \ plat/brcm/common/brcm_ccn.c \ plat/common/plat_psci_common.c \ plat/${SOC_DIR}/driver/ihost_pll_config.c \ + plat/${SOC_DIR}/src/bl31_setup.c \ + plat/${SOC_DIR}/src/fsx.c \ + plat/${SOC_DIR}/src/iommu.c \ + plat/${SOC_DIR}/src/sdio.c \ ${BRCM_GIC_SOURCES} +ifneq (${NCSI_IO_DRIVE_STRENGTH_MA},) +BL31_SOURCES += plat/${SOC_DIR}/src/ncsi.c +endif + +ifeq (${USE_PAXB},yes) +BL31_SOURCES += plat/${SOC_DIR}/src/paxb.c +BL31_SOURCES += plat/${SOC_DIR}/src/sr_paxb_phy.c +endif + +ifeq (${USE_PAXC},yes) +BL31_SOURCES += plat/${SOC_DIR}/src/paxc.c +endif + ifdef SCP_BL2 PLAT_INCLUDES += -Iplat/brcm/common/ @@ -150,6 +251,24 @@ BL2_SOURCES += plat/brcm/board/common/bcm_elog_ddr.c endif endif +ifeq (${BL31_BOOT_PRELOADED_SCP}, 1) +ifdef SCP_BL2 +SCP_CFG_DIR=$(dir ${SCP_BL2}) +PLAT_INCLUDES += -I${SCP_CFG_DIR} +endif +PLAT_INCLUDES += -Iplat/brcm/common/ + +# By default use OPTEE Assigned memory +PRELOADED_SCP_BASE ?= 0x8E000000 +PRELOADED_SCP_SIZE ?= 0x10000 +$(eval $(call add_define,PRELOADED_SCP_BASE)) +$(eval $(call add_define,PRELOADED_SCP_SIZE)) +$(eval $(call add_define,BL31_BOOT_PRELOADED_SCP)) +BL31_SOURCES += plat/${SOC_DIR}/src/scp_utils.c \ + plat/${SOC_DIR}/src/scp_cmd.c \ + drivers/brcm/scp.c +endif + # Do not execute the startup code on warm reset. PROGRAMMABLE_RESET_ADDRESS := 1 diff --git a/plat/brcm/board/stingray/src/bl31_setup.c b/plat/brcm/board/stingray/src/bl31_setup.c new file mode 100644 index 000000000..d94755184 --- /dev/null +++ b/plat/brcm/board/stingray/src/bl31_setup.c @@ -0,0 +1,1068 @@ +/* + * Copyright (c) 2015 - 2020, Broadcom + * + * 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 +#include +#include + +/******************************************************************************* + * Perform any BL3-1 platform setup common to ARM standard platforms + ******************************************************************************/ + +static void brcm_stingray_gain_qspi_control(void) +{ + if (boot_source_get() != BOOT_SOURCE_QSPI) { + if (bcm_chimp_is_nic_mode() && + (!bcm_chimp_handshake_done())) { + /* + * Last chance to wait for ChiMP firmware to report + * "I am done" before grabbing the QSPI + */ + WARN("ChiMP still not booted\n"); +#ifndef CHIMP_ALWAYS_NEEDS_QSPI + WARN("ChiMP is given the last chance to boot (%d s)\n", + CHIMP_HANDSHAKE_TIMEOUT_MS / 1000); + + if (!bcm_chimp_wait_handshake()) { + ERROR("ChiMP failed to boot\n"); + } else { + INFO("ChiMP booted successfully\n"); + } +#endif + } + +#ifndef CHIMP_ALWAYS_NEEDS_QSPI + INFO("AP grabs QSPI\n"); + /* + * For QSPI boot sbl/bl1 has already taken care. + * For other boot sources QSPI needs to be muxed to + * AP for exclusive use + */ + brcm_stingray_set_qspi_mux(1); + INFO("AP (bl31) gained control over QSPI\n"); +#endif + } +} + +static void brcm_stingray_dma_pl330_init(void) +{ + unsigned int val; + + VERBOSE("dma pl330 init start\n"); + + /* Set DMAC boot_manager_ns = 0x1 */ + VERBOSE(" - configure boot security state\n"); + mmio_setbits_32(DMAC_M0_IDM_IO_CONTROL_DIRECT, BOOT_MANAGER_NS); + /* Set boot_peripheral_ns[n:0] = 0xffffffff */ + mmio_write_32(ICFG_DMAC_CONFIG_2, BOOT_PERIPHERAL_NS); + /* Set boot_irq_ns[n:0] = 0x0000ffff */ + mmio_write_32(ICFG_DMAC_CONFIG_3, BOOT_IRQ_NS); + + /* Set DMAC stream_id */ + VERBOSE(" - configure stream_id = 0x6000\n"); + val = (DMAC_STREAM_ID << DMAC_SID_SHIFT); + mmio_write_32(ICFG_DMAC_SID_ARADDR_CONTROL, val); + mmio_write_32(ICFG_DMAC_SID_AWADDR_CONTROL, val); + + /* Reset DMAC */ + VERBOSE(" - reset dma pl330\n"); + + mmio_setbits_32(DMAC_M0_IDM_RESET_CONTROL, 0x1); + udelay(500); + + mmio_clrbits_32(DMAC_M0_IDM_RESET_CONTROL, 0x1); + udelay(500); + + INFO("dma pl330 init done\n"); +} + +static void brcm_stingray_spi_pl022_init(uintptr_t idm_reset_control) +{ + VERBOSE("spi pl022 init start\n"); + + /* Reset APB SPI bridge */ + VERBOSE(" - reset apb spi bridge\n"); + mmio_setbits_32(idm_reset_control, 0x1); + udelay(500); + + mmio_clrbits_32(idm_reset_control, 0x1); + udelay(500); + + INFO("spi pl022 init done\n"); +} + +#define CDRU_SATA_RESET_N \ + BIT(CDRU_MISC_RESET_CONTROL__CDRU_SATA_RESET_N_R) +#define CDRU_MISC_CLK_SATA \ + BIT(CDRU_MISC_CLK_ENABLE_CONTROL__CDRU_SATA_CLK_EN_R) +#define CCN_CONFIG_CLK_ENABLE (1 << 2) +#define MMU_CONFIG_CLK_ENABLE (0x3F << 16) + +#define SATA_SATA_TOP_CTRL_BUS_CTRL (SATA_BASE + 0x2044) +#define DMA_BIT_CTRL_MASK 0x003 +#define DMA_DESCR_ENDIAN_CTRL (DMA_BIT_CTRL_MASK << 0x002) +#define DMA_DATA_ENDIAN_CTRL (DMA_BIT_CTRL_MASK << 0x004) + +#define SATA_PORT_SATA3_PCB_REG8 (SATA_BASE + 0x2320) +#define SATA_PORT_SATA3_PCB_REG11 (SATA_BASE + 0x232c) +#define SATA_PORT_SATA3_PCB_BLOCK_ADDR (SATA_BASE + 0x233c) + +#define SATA3_AFE_TXRX_ACTRL 0x1d0 +/* TXDriver swing setting is 800mV */ +#define DFS_SWINGNOPE_VALUE (0x0 << 6) +#define DFS_SWINGNOPE_MASK (0x3 << 6) + +#define DFS_SWINGPE_VALUE (0x1 << 4) +#define DFS_SWINGPE_MASK (0x3 << 4) + +#define DFS_INJSTRENGTH_VALUE (0x0 << 4) +#define DFS_INJSTRENGTH_MASK (0x3 << 4) + +#define DFS_INJEN (0x1 << 3) + +#define SATA_CORE_MEM_CTRL (SATA_BASE + 0x3a08) +#define SATA_CORE_MEM_CTRL_ISO BIT(0) +#define SATA_CORE_MEM_CTRL_ARRPOWEROKIN BIT(1) +#define SATA_CORE_MEM_CTRL_ARRPOWERONIN BIT(2) +#define SATA_CORE_MEM_CTRL_POWEROKIN BIT(3) +#define SATA_CORE_MEM_CTRL_POWERONIN BIT(4) + +#define SATA0_IDM_RESET_CONTROL (SATA_BASE + 0x500800) +#define SATA_APBT0_IDM_IO_CONTROL_DIRECT (SATA_BASE + 0x51a408) +#define IO_CONTROL_DIRECT_CLK_ENABLE BIT(0) +#define SATA_APBT0_IDM_RESET_CONTROL (SATA_BASE + 0x51a800) +#define IDM_RESET_CONTROL_RESET BIT(0) + +#define NIC400_SATA_NOC_SECURITY1 0x6830000c +#define SATA_NOC_SECURITY1_FIELD 0xf +#define NIC400_SATA_NOC_SECURITY2 0x68300010 +#define SATA_NOC_SECURITY2_FIELD 0xf +#define NIC400_SATA_NOC_SECURITY3 0x68300014 +#define SATA_NOC_SECURITY3_FIELD 0x1 +#define NIC400_SATA_NOC_SECURITY4 0x68300018 +#define SATA_NOC_SECURITY4_FIELD 0x1 +#define NIC400_SATA_NOC_SECURITY5 0x6830001c +#define SATA_NOC_SECURITY5_FIELD 0xf +#define NIC400_SATA_NOC_SECURITY6 0x68300020 +#define SATA_NOC_SECURITY6_FIELD 0x1 +#define NIC400_SATA_NOC_SECURITY7 0x68300024 +#define SATA_NOC_SECURITY7_FIELD 0xf +#define NIC400_SATA_NOC_SECURITY8 0x68300028 +#define SATA_NOC_SECURITY8_FIELD 0xf +#define NIC400_SATA_NOC_SECURITY9 0x6830002c +#define SATA_NOC_SECURITY9_FIELD 0x1 + +#define SATA_APBT_IDM_PORT_REG(port, reg) \ + (((port/4) << 12) + reg) + +#define SATA_IDM_PORT_REG(port, reg) ((port << 12) + reg) + +#define SATA_PORT_REG(port, reg) \ + (((port%4) << 16) + ((port/4) << 20) + reg) + +#define MAX_SATA_PORTS 8 +#define USE_SATA_PORTS 8 + +#ifdef USE_SATA +static const uint8_t sr_b0_sata_port[MAX_SATA_PORTS] = { + 0, 1, 2, 3, 4, 5, 6, 7 +}; + +static uint32_t brcm_stingray_get_sata_port(unsigned int port) +{ + return sr_b0_sata_port[port]; +} + +static void brcm_stingray_sata_init(void) +{ + unsigned int port = 0; + uint32_t sata_port; + + mmio_setbits_32(CDRU_MISC_CLK_ENABLE_CONTROL, + CDRU_MISC_CLK_SATA); + + mmio_clrbits_32(CDRU_MISC_RESET_CONTROL, CDRU_SATA_RESET_N); + mmio_setbits_32(CDRU_MISC_RESET_CONTROL, CDRU_SATA_RESET_N); + + for (port = 0; port < USE_SATA_PORTS; port++) { + + sata_port = brcm_stingray_get_sata_port(port); + mmio_write_32(SATA_APBT_IDM_PORT_REG(sata_port, + SATA_APBT0_IDM_RESET_CONTROL), + 0x0); + mmio_setbits_32(SATA_APBT_IDM_PORT_REG(sata_port, + SATA_APBT0_IDM_IO_CONTROL_DIRECT), + IO_CONTROL_DIRECT_CLK_ENABLE); + mmio_write_32(SATA_IDM_PORT_REG(sata_port, + SATA0_IDM_RESET_CONTROL), + 0x0); + + mmio_setbits_32(SATA_PORT_REG(sata_port, SATA_CORE_MEM_CTRL), + SATA_CORE_MEM_CTRL_ARRPOWERONIN); + mmio_setbits_32(SATA_PORT_REG(sata_port, SATA_CORE_MEM_CTRL), + SATA_CORE_MEM_CTRL_ARRPOWEROKIN); + mmio_setbits_32(SATA_PORT_REG(sata_port, SATA_CORE_MEM_CTRL), + SATA_CORE_MEM_CTRL_POWERONIN); + mmio_setbits_32(SATA_PORT_REG(sata_port, SATA_CORE_MEM_CTRL), + SATA_CORE_MEM_CTRL_POWEROKIN); + mmio_clrbits_32(SATA_PORT_REG(sata_port, SATA_CORE_MEM_CTRL), + SATA_CORE_MEM_CTRL_ISO); + + mmio_clrbits_32(SATA_PORT_REG(sata_port, + SATA_SATA_TOP_CTRL_BUS_CTRL), + (DMA_DESCR_ENDIAN_CTRL | DMA_DATA_ENDIAN_CTRL)); + } + + mmio_setbits_32(NIC400_SATA_NOC_SECURITY1, SATA_NOC_SECURITY1_FIELD); + mmio_setbits_32(NIC400_SATA_NOC_SECURITY2, SATA_NOC_SECURITY2_FIELD); + mmio_setbits_32(NIC400_SATA_NOC_SECURITY3, SATA_NOC_SECURITY3_FIELD); + mmio_setbits_32(NIC400_SATA_NOC_SECURITY4, SATA_NOC_SECURITY4_FIELD); + mmio_setbits_32(NIC400_SATA_NOC_SECURITY5, SATA_NOC_SECURITY5_FIELD); + mmio_setbits_32(NIC400_SATA_NOC_SECURITY6, SATA_NOC_SECURITY6_FIELD); + mmio_setbits_32(NIC400_SATA_NOC_SECURITY7, SATA_NOC_SECURITY7_FIELD); + mmio_setbits_32(NIC400_SATA_NOC_SECURITY8, SATA_NOC_SECURITY8_FIELD); + mmio_setbits_32(NIC400_SATA_NOC_SECURITY9, SATA_NOC_SECURITY9_FIELD); + + INFO("sata init done\n"); +} +#else +static void poweroff_sata_pll(void) +{ + /* + * SATA subsystem is clocked by LCPLL0 which is enabled by + * default by bootrom. Poweroff the PLL if SATA is not used + */ + + /* enable isolation */ + mmio_setbits_32(CRMU_AON_CTRL1, + BIT(CRMU_AON_CTRL1__LCPLL0_ISO_IN)); + + /* Power off the SATA PLL/LDO */ + mmio_clrbits_32(CRMU_AON_CTRL1, + (BIT(CRMU_AON_CTRL1__LCPLL0_PWRON_LDO) | + BIT(CRMU_AON_CTRL1__LCPLL0_PWR_ON))); +} +#endif + +#ifdef USE_AMAC +#ifdef EMULATION_SETUP +#define ICFG_AMAC_STRAP_CONFIG (HSLS_ICFG_REGS_BASE + 0xa5c) +#define ICFG_AMAC_STRAP_DLL_BYPASS (1 << 2) +#endif +#define ICFG_AMAC_MAC_CTRL_REG (HSLS_ICFG_REGS_BASE + 0xa6c) +#define ICFG_AMAC_MAC_FULL_DUPLEX (1 << 1) +#define ICFG_AMAC_RGMII_PHY_CONFIG (HSLS_ICFG_REGS_BASE + 0xa60) +#define ICFG_AMAC_SID_CONTROL (HSLS_ICFG_REGS_BASE + 0xb10) +#define ICFG_AMAC_SID_SHIFT 5 +#define ICFG_AMAC_SID_AWADDR_OFFSET 0x0 +#define ICFG_AMAC_SID_ARADDR_OFFSET 0x4 +#define AMAC_RPHY_1000_DATARATE (1 << 20) +#define AMAC_RPHY_FULL_DUPLEX (1 << 5) +#define AMAC_RPHY_SPEED_OFFSET 2 +#define AMAC_RPHY_SPEED_MASK (7 << AMAC_RPHY_SPEED_OFFSET) +#define AMAC_RPHY_1G_SPEED (2 << AMAC_RPHY_SPEED_OFFSET) +#define ICFG_AMAC_MEM_PWR_CTRL (HSLS_ICFG_REGS_BASE + 0xa68) +#define AMAC_ISO BIT(9) +#define AMAC_STDBY BIT(8) +#define AMAC_ARRPOWEROKIN BIT(7) +#define AMAC_ARRPOWERONIN BIT(6) +#define AMAC_POWEROKIN BIT(5) +#define AMAC_POWERONIN BIT(4) + +#define AMAC_IDM0_IO_CONTROL_DIRECT (HSLS_IDM_REGS_BASE + 0x4408) +#define AMAC_IDM0_ARCACHE_OFFSET 16 +#define AMAC_IDM0_AWCACHE_OFFSET 7 +#define AMAC_IDM0_ARCACHE_MASK (0xF << AMAC_IDM0_ARCACHE_OFFSET) +#define AMAC_IDM0_AWCACHE_MASK (0xF << AMAC_IDM0_AWCACHE_OFFSET) +/* ARCACHE - AWCACHE is 0xB7 for write-back no allocate */ +#define AMAC_IDM0_ARCACHE_VAL (0xb << AMAC_IDM0_ARCACHE_OFFSET) +#define AMAC_IDM0_AWCACHE_VAL (0x7 << AMAC_IDM0_AWCACHE_OFFSET) + +static void brcm_stingray_amac_init(void) +{ + unsigned int val; + uintptr_t icfg_amac_sid = ICFG_AMAC_SID_CONTROL; + + VERBOSE("amac init start\n"); + + val = SR_SID_VAL(0x3, 0x0, 0x4) << ICFG_AMAC_SID_SHIFT; + mmio_write_32(icfg_amac_sid + ICFG_AMAC_SID_AWADDR_OFFSET, val); + mmio_write_32(icfg_amac_sid + ICFG_AMAC_SID_ARADDR_OFFSET, val); + + mmio_setbits_32(ICFG_AMAC_MEM_PWR_CTRL, AMAC_ARRPOWEROKIN); + mmio_setbits_32(ICFG_AMAC_MEM_PWR_CTRL, AMAC_ARRPOWERONIN); + mmio_setbits_32(ICFG_AMAC_MEM_PWR_CTRL, AMAC_POWEROKIN); + mmio_setbits_32(ICFG_AMAC_MEM_PWR_CTRL, AMAC_POWERONIN); + mmio_clrbits_32(ICFG_AMAC_MEM_PWR_CTRL, AMAC_ISO); + mmio_write_32(APBR_IDM_RESET_CONTROL, 0x0); + mmio_clrsetbits_32(ICFG_AMAC_RGMII_PHY_CONFIG, AMAC_RPHY_SPEED_MASK, + AMAC_RPHY_1G_SPEED); /*1 Gbps line rate*/ + /* 1000 datarate set */ + mmio_setbits_32(ICFG_AMAC_RGMII_PHY_CONFIG, AMAC_RPHY_1000_DATARATE); + /* full duplex */ + mmio_setbits_32(ICFG_AMAC_RGMII_PHY_CONFIG, AMAC_RPHY_FULL_DUPLEX); +#ifdef EMULATION_SETUP + /* DLL bypass */ + mmio_setbits_32(ICFG_AMAC_STRAP_CONFIG, ICFG_AMAC_STRAP_DLL_BYPASS); +#endif + /* serdes full duplex */ + mmio_setbits_32(ICFG_AMAC_MAC_CTRL_REG, ICFG_AMAC_MAC_FULL_DUPLEX); + mmio_clrsetbits_32(AMAC_IDM0_IO_CONTROL_DIRECT, AMAC_IDM0_ARCACHE_MASK, + AMAC_IDM0_ARCACHE_VAL); + mmio_clrsetbits_32(AMAC_IDM0_IO_CONTROL_DIRECT, AMAC_IDM0_AWCACHE_MASK, + AMAC_IDM0_AWCACHE_VAL); + INFO("amac init done\n"); +} +#endif /* USE_AMAC */ + +static void brcm_stingray_pka_meminit(void) +{ + uintptr_t icfg_mem_ctrl = ICFG_PKA_MEM_PWR_CTRL; + + VERBOSE("pka meminit start\n"); + + VERBOSE(" - arrpoweron\n"); + mmio_setbits_32(icfg_mem_ctrl, + ICFG_PKA_MEM_PWR_CTRL__ARRPOWERONIN); + while (!(mmio_read_32(icfg_mem_ctrl) & + ICFG_PKA_MEM_PWR_CTRL__ARRPOWERONOUT)) + ; + + VERBOSE(" - arrpowerok\n"); + mmio_setbits_32(icfg_mem_ctrl, + ICFG_PKA_MEM_PWR_CTRL__ARRPOWEROKIN); + while (!(mmio_read_32(icfg_mem_ctrl) & + ICFG_PKA_MEM_PWR_CTRL__ARRPOWEROKOUT)) + ; + + VERBOSE(" - poweron\n"); + mmio_setbits_32(icfg_mem_ctrl, + ICFG_PKA_MEM_PWR_CTRL__POWERONIN); + while (!(mmio_read_32(icfg_mem_ctrl) & + ICFG_PKA_MEM_PWR_CTRL__POWERONOUT)) + ; + + VERBOSE(" - powerok\n"); + mmio_setbits_32(icfg_mem_ctrl, + ICFG_PKA_MEM_PWR_CTRL__POWEROKIN); + while (!(mmio_read_32(icfg_mem_ctrl) & + ICFG_PKA_MEM_PWR_CTRL__POWEROKOUT)) + ; + + /* Wait sometime */ + mdelay(1); + + VERBOSE(" - remove isolation\n"); + mmio_clrbits_32(icfg_mem_ctrl, ICFG_PKA_MEM_PWR_CTRL__ISO); + + INFO("pka meminit done\n"); +} + +static void brcm_stingray_smmu_init(void) +{ + unsigned int val; + uintptr_t smmu_base = SMMU_BASE; + + VERBOSE("smmu init start\n"); + + /* Configure SCR0 */ + VERBOSE(" - configure scr0\n"); + val = mmio_read_32(smmu_base + 0x0); + val |= (0x1 << 12); + mmio_write_32(smmu_base + 0x0, val); + + /* Reserve context banks for secure masters */ + arm_smmu_reserve_secure_cntxt(); + + /* Print configuration */ + VERBOSE(" - scr0=0x%x scr1=0x%x scr2=0x%x\n", + mmio_read_32(smmu_base + 0x0), + mmio_read_32(smmu_base + 0x4), + mmio_read_32(smmu_base + 0x8)); + + VERBOSE(" - idr0=0x%x idr1=0x%x idr2=0x%x\n", + mmio_read_32(smmu_base + 0x20), + mmio_read_32(smmu_base + 0x24), + mmio_read_32(smmu_base + 0x28)); + + VERBOSE(" - idr3=0x%x idr4=0x%x idr5=0x%x\n", + mmio_read_32(smmu_base + 0x2c), + mmio_read_32(smmu_base + 0x30), + mmio_read_32(smmu_base + 0x34)); + + VERBOSE(" - idr6=0x%x idr7=0x%x\n", + mmio_read_32(smmu_base + 0x38), + mmio_read_32(smmu_base + 0x3c)); + + INFO("smmu init done\n"); +} + +static void brcm_stingray_dma_pl330_meminit(void) +{ + uintptr_t icfg_mem_ctrl = ICFG_DMAC_MEM_PWR_CTRL; + + VERBOSE("dmac meminit start\n"); + + VERBOSE(" - arrpoweron\n"); + mmio_setbits_32(icfg_mem_ctrl, + ICFG_DMAC_MEM_PWR_CTRL__ARRPOWERONIN); + while (!(mmio_read_32(icfg_mem_ctrl) & + ICFG_DMAC_MEM_PWR_CTRL__ARRPOWERONOUT)) + ; + + VERBOSE(" - arrpowerok\n"); + mmio_setbits_32(icfg_mem_ctrl, + ICFG_DMAC_MEM_PWR_CTRL__ARRPOWEROKIN); + while (!(mmio_read_32(icfg_mem_ctrl) & + ICFG_DMAC_MEM_PWR_CTRL__ARRPOWEROKOUT)) + ; + + VERBOSE(" - poweron\n"); + mmio_setbits_32(icfg_mem_ctrl, + ICFG_DMAC_MEM_PWR_CTRL__POWERONIN); + while (!(mmio_read_32(icfg_mem_ctrl) & + ICFG_DMAC_MEM_PWR_CTRL__POWERONOUT)) + ; + + VERBOSE(" - powerok\n"); + mmio_setbits_32(icfg_mem_ctrl, + ICFG_DMAC_MEM_PWR_CTRL__POWEROKIN); + while (!(mmio_read_32(icfg_mem_ctrl) & + ICFG_DMAC_MEM_PWR_CTRL__POWEROKOUT)) + ; + + /* Wait sometime */ + mdelay(1); + + VERBOSE(" - remove isolation\n"); + mmio_clrbits_32(icfg_mem_ctrl, ICFG_DMAC_MEM_PWR_CTRL__ISO); + + INFO("dmac meminit done\n"); +} + +/* program the crmu access ranges for allowing non sec access*/ +static void brcm_stingray_crmu_access_init(void) +{ + /* Enable 0x6641c001 - 0x6641c701 for non secure access */ + mmio_write_32(CRMU_CORE_ADDR_RANGE0_LOW, 0x6641c001); + mmio_write_32(CRMU_CORE_ADDR_RANGE0_LOW + 0x4, 0x6641c701); + + /* Enable 0x6641d001 - 0x66424b01 for non secure access */ + mmio_write_32(CRMU_CORE_ADDR_RANGE1_LOW, 0x6641d001); + mmio_write_32(CRMU_CORE_ADDR_RANGE1_LOW + 0x4, 0x66424b01); + + /* Enable 0x66425001 - 0x66425f01 for non secure access */ + mmio_write_32(CRMU_CORE_ADDR_RANGE2_LOW, 0x66425001); + mmio_write_32(CRMU_CORE_ADDR_RANGE2_LOW + 0x4, 0x66425f01); + + INFO("crmu access init done\n"); +} + +static void brcm_stingray_scr_init(void) +{ + unsigned int val; + uintptr_t scr_base = SCR_BASE; + unsigned int clr_mask = SCR_AXCACHE_CONFIG_MASK; + unsigned int set_mask = SCR_TBUX_AXCACHE_CONFIG; + + VERBOSE("scr init start\n"); + + /* awdomain=0x1 and ardomain=0x1 */ + mmio_clrsetbits_32(scr_base + 0x0, clr_mask, set_mask); + val = mmio_read_32(scr_base + 0x0); + VERBOSE(" - set tbu0_config=0x%x\n", val); + + /* awdomain=0x1 and ardomain=0x1 */ + mmio_clrsetbits_32(scr_base + 0x4, clr_mask, set_mask); + val = mmio_read_32(scr_base + 0x4); + VERBOSE(" - set tbu1_config=0x%x\n", val); + + /* awdomain=0x1 and ardomain=0x1 */ + mmio_clrsetbits_32(scr_base + 0x8, clr_mask, set_mask); + val = mmio_read_32(scr_base + 0x8); + VERBOSE(" - set tbu2_config=0x%x\n", val); + + /* awdomain=0x1 and ardomain=0x1 */ + mmio_clrsetbits_32(scr_base + 0xc, clr_mask, set_mask); + val = mmio_read_32(scr_base + 0xc); + VERBOSE(" - set tbu3_config=0x%x\n", val); + + /* awdomain=0x1 and ardomain=0x1 */ + mmio_clrsetbits_32(scr_base + 0x10, clr_mask, set_mask); + val = mmio_read_32(scr_base + 0x10); + VERBOSE(" - set tbu4_config=0x%x\n", val); + + /* awdomain=0x0 and ardomain=0x0 */ + mmio_clrbits_32(scr_base + 0x14, clr_mask); + val = mmio_read_32(scr_base + 0x14); + VERBOSE(" - set gic_config=0x%x\n", val); + + INFO("scr init done\n"); +} + +static void brcm_stingray_hsls_tzpcprot_init(void) +{ + unsigned int val; + uintptr_t tzpcdecprot_base = HSLS_TZPC_BASE; + + VERBOSE("hsls tzpcprot init start\n"); + + /* Treat third-party masters as non-secured */ + val = 0; + val |= BIT(6); /* SDIO1 */ + val |= BIT(5); /* SDIO0 */ + val |= BIT(0); /* AMAC */ + mmio_write_32(tzpcdecprot_base + 0x810, val); + + /* Print TZPC decode status registers */ + VERBOSE(" - tzpcdecprot0=0x%x\n", + mmio_read_32(tzpcdecprot_base + 0x800)); + + VERBOSE(" - tzpcdecprot1=0x%x\n", + mmio_read_32(tzpcdecprot_base + 0x80c)); + + INFO("hsls tzpcprot init done\n"); +} + +#ifdef USE_I2S +#define ICFG_AUDIO_POWER_CTRL (HSLS_ICFG_REGS_BASE + 0xaa8) +#define ICFG_AUDIO_POWER_CTRL__POWERONIN BIT(0) +#define ICFG_AUDIO_POWER_CTRL__POWEROKIN BIT(1) +#define ICFG_AUDIO_POWER_CTRL__ARRPOWERONIN BIT(2) +#define ICFG_AUDIO_POWER_CTRL__ARRPOWEROKIN BIT(3) +#define ICFG_AUDIO_POWER_CTRL__POWERONOUT BIT(4) +#define ICFG_AUDIO_POWER_CTRL__POWEROKOUT BIT(5) +#define ICFG_AUDIO_POWER_CTRL__ARRPOWERONOUT BIT(6) +#define ICFG_AUDIO_POWER_CTRL__ARRPOWEROKOUT BIT(7) +#define ICFG_AUDIO_POWER_CTRL__ISO BIT(8) +#define ICFG_AUDIO_SID_CONTROL (HSLS_ICFG_REGS_BASE + 0xaf8) +#define ICFG_AUDIO_SID_SHIFT 5 +#define ICFG_AUDIO_SID_AWADDR_OFFSET 0x0 +#define ICFG_AUDIO_SID_ARADDR_OFFSET 0x4 + +#define I2S_RESET_CONTROL (HSLS_IDM_REGS_BASE + 0x1800) +#define I2S_IDM_IO_CONTROL (HSLS_IDM_REGS_BASE + 0x1408) +#define IO_CONTROL_CLK_ENABLE BIT(0) +#define I2S_IDM0_ARCACHE_OFFSET 16 +#define I2S_IDM0_AWCACHE_OFFSET 20 +#define I2S_IDM0_ARCACHE_MASK (0xF << I2S_IDM0_ARCACHE_OFFSET) +#define I2S_IDM0_AWCACHE_MASK (0xF << I2S_IDM0_AWCACHE_OFFSET) +/* ARCACHE - AWCACHE is 0x22 Normal Non-cacheable Non-bufferable. */ +#define I2S_IDM0_ARCACHE_VAL (0x2 << I2S_IDM0_ARCACHE_OFFSET) +#define I2S_IDM0_AWCACHE_VAL (0x2 << I2S_IDM0_AWCACHE_OFFSET) + +static void brcm_stingray_audio_init(void) +{ + unsigned int val; + uintptr_t icfg_mem_ctrl = ICFG_AUDIO_POWER_CTRL; + uintptr_t icfg_audio_sid = ICFG_AUDIO_SID_CONTROL; + + mmio_write_32(I2S_RESET_CONTROL, 0x0); + + mmio_clrsetbits_32(I2S_IDM_IO_CONTROL, I2S_IDM0_ARCACHE_MASK, + I2S_IDM0_ARCACHE_VAL); + + mmio_clrsetbits_32(I2S_IDM_IO_CONTROL, I2S_IDM0_AWCACHE_MASK, + I2S_IDM0_AWCACHE_VAL); + + mmio_setbits_32(I2S_IDM_IO_CONTROL, IO_CONTROL_CLK_ENABLE); + + VERBOSE("audio meminit start\n"); + + VERBOSE(" - configure stream_id = 0x6001\n"); + val = SR_SID_VAL(0x3, 0x0, 0x1) << ICFG_AUDIO_SID_SHIFT; + mmio_write_32(icfg_audio_sid + ICFG_AUDIO_SID_AWADDR_OFFSET, val); + mmio_write_32(icfg_audio_sid + ICFG_AUDIO_SID_ARADDR_OFFSET, val); + + VERBOSE(" - arrpoweron\n"); + mmio_setbits_32(icfg_mem_ctrl, + ICFG_AUDIO_POWER_CTRL__ARRPOWERONIN); + while (!(mmio_read_32(icfg_mem_ctrl) & + ICFG_AUDIO_POWER_CTRL__ARRPOWERONOUT)) + ; + + VERBOSE(" - arrpowerok\n"); + mmio_setbits_32(icfg_mem_ctrl, + ICFG_AUDIO_POWER_CTRL__ARRPOWEROKIN); + while (!(mmio_read_32(icfg_mem_ctrl) & + ICFG_AUDIO_POWER_CTRL__ARRPOWEROKOUT)) + ; + + VERBOSE(" - poweron\n"); + mmio_setbits_32(icfg_mem_ctrl, + ICFG_AUDIO_POWER_CTRL__POWERONIN); + while (!(mmio_read_32(icfg_mem_ctrl) & + ICFG_AUDIO_POWER_CTRL__POWERONOUT)) + ; + + VERBOSE(" - powerok\n"); + mmio_setbits_32(icfg_mem_ctrl, + ICFG_AUDIO_POWER_CTRL__POWEROKIN); + while (!(mmio_read_32(icfg_mem_ctrl) & + ICFG_AUDIO_POWER_CTRL__POWEROKOUT)) + ; + + /* Wait sometime */ + mdelay(1); + + VERBOSE(" - remove isolation\n"); + mmio_clrbits_32(icfg_mem_ctrl, ICFG_AUDIO_POWER_CTRL__ISO); + + INFO("audio meminit done\n"); +} +#endif /* USE_I2S */ + +/* + * These defines do not match the regfile but they are renamed in a way such + * that they are much more readible + */ + +#define SCR_GPV_SMMU_NS (SCR_GPV_BASE + 0x28) +#define SCR_GPV_GIC500_NS (SCR_GPV_BASE + 0x34) +#define HSLS_GPV_NOR_S0_NS (HSLS_GPV_BASE + 0x14) +#define HSLS_GPV_IDM1_NS (HSLS_GPV_BASE + 0x18) +#define HSLS_GPV_IDM2_NS (HSLS_GPV_BASE + 0x1c) +#define HSLS_SDIO0_SLAVE_NS (HSLS_GPV_BASE + 0x20) +#define HSLS_SDIO1_SLAVE_NS (HSLS_GPV_BASE + 0x24) +#define HSLS_GPV_APBY_NS (HSLS_GPV_BASE + 0x2c) +#define HSLS_GPV_APBZ_NS (HSLS_GPV_BASE + 0x30) +#define HSLS_GPV_APBX_NS (HSLS_GPV_BASE + 0x34) +#define HSLS_GPV_APBS_NS (HSLS_GPV_BASE + 0x38) +#define HSLS_GPV_QSPI_S0_NS (HSLS_GPV_BASE + 0x68) +#define HSLS_GPV_APBR_NS (HSLS_GPV_BASE + 0x6c) +#define FS4_CRYPTO_GPV_RM_SLAVE_NS (FS4_CRYPTO_GPV_BASE + 0x8) +#define FS4_CRYPTO_GPV_APB_SWITCH_NS (FS4_CRYPTO_GPV_BASE + 0xc) +#define FS4_RAID_GPV_RM_SLAVE_NS (FS4_RAID_GPV_BASE + 0x8) +#define FS4_RAID_GPV_APB_SWITCH_NS (FS4_RAID_GPV_BASE + 0xc) +#define FS4_CRYPTO_IDM_NS (NIC400_FS_NOC_ROOT + 0x1c) +#define FS4_RAID_IDM_NS (NIC400_FS_NOC_ROOT + 0x28) + +#define FS4_CRYPTO_RING_COUNT 32 +#define FS4_CRYPTO_DME_COUNT 10 +#define FS4_CRYPTO_AE_COUNT 10 +#define FS4_CRYPTO_START_STREAM_ID 0x4000 +#define FS4_CRYPTO_MSI_DEVICE_ID 0x4100 + +#define FS4_RAID_RING_COUNT 32 +#define FS4_RAID_DME_COUNT 8 +#define FS4_RAID_AE_COUNT 8 +#define FS4_RAID_START_STREAM_ID 0x4200 +#define FS4_RAID_MSI_DEVICE_ID 0x4300 + +#define FS6_PKI_AXI_SLAVE_NS \ + (NIC400_FS_NOC_ROOT + NIC400_FS_NOC_SECURITY2_OFFSET) + +#define FS6_PKI_AE_DME_APB_NS \ + (NIC400_FS_NOC_ROOT + NIC400_FS_NOC_SECURITY7_OFFSET) +#define FS6_PKI_IDM_IO_CONTROL_DIRECT 0x0 +#define FS6_PKI_IDM_RESET_CONTROL 0x0 +#define FS6_PKI_RING_COUNT 32 +#define FS6_PKI_DME_COUNT 1 +#define FS6_PKI_AE_COUNT 4 +#define FS6_PKI_START_STREAM_ID 0x4000 +#define FS6_PKI_MSI_DEVICE_ID 0x4100 + +static void brcm_stingray_security_init(void) +{ + unsigned int val; + + val = mmio_read_32(SCR_GPV_SMMU_NS); + val |= BIT(0); /* SMMU NS = 1 */ + mmio_write_32(SCR_GPV_SMMU_NS, val); + + val = mmio_read_32(SCR_GPV_GIC500_NS); + val |= BIT(0); /* GIC-500 NS = 1 */ + mmio_write_32(SCR_GPV_GIC500_NS, val); + + val = mmio_read_32(HSLS_GPV_NOR_S0_NS); + val |= BIT(0); /* NOR SLAVE NS = 1 */ + mmio_write_32(HSLS_GPV_NOR_S0_NS, val); + + val = mmio_read_32(HSLS_GPV_IDM1_NS); + val |= BIT(0); /* DMA IDM NS = 1 */ + val |= BIT(1); /* I2S IDM NS = 1 */ + val |= BIT(2); /* AMAC IDM NS = 1 */ + val |= BIT(3); /* SDIO0 IDM NS = 1 */ + val |= BIT(4); /* SDIO1 IDM NS = 1 */ + val |= BIT(5); /* DS_3 IDM NS = 1 */ + mmio_write_32(HSLS_GPV_IDM1_NS, val); + + val = mmio_read_32(HSLS_GPV_IDM2_NS); + val |= BIT(2); /* QSPI IDM NS = 1 */ + val |= BIT(1); /* NOR IDM NS = 1 */ + val |= BIT(0); /* NAND IDM NS = 1 */ + mmio_write_32(HSLS_GPV_IDM2_NS, val); + + val = mmio_read_32(HSLS_GPV_APBY_NS); + val |= BIT(10); /* I2S NS = 1 */ + val |= BIT(4); /* IOPAD NS = 1 */ + val |= 0xf; /* UARTx NS = 1 */ + mmio_write_32(HSLS_GPV_APBY_NS, val); + + val = mmio_read_32(HSLS_GPV_APBZ_NS); + val |= BIT(2); /* RNG NS = 1 */ + mmio_write_32(HSLS_GPV_APBZ_NS, val); + + val = mmio_read_32(HSLS_GPV_APBS_NS); + val |= 0x3; /* SPIx NS = 1 */ + mmio_write_32(HSLS_GPV_APBS_NS, val); + + val = mmio_read_32(HSLS_GPV_APBR_NS); + val |= BIT(7); /* QSPI APB NS = 1 */ + val |= BIT(6); /* NAND APB NS = 1 */ + val |= BIT(5); /* NOR APB NS = 1 */ + val |= BIT(4); /* AMAC APB NS = 1 */ + val |= BIT(1); /* DMA S1 APB NS = 1 */ + mmio_write_32(HSLS_GPV_APBR_NS, val); + + val = mmio_read_32(HSLS_SDIO0_SLAVE_NS); + val |= BIT(0); /* SDIO0 NS = 1 */ + mmio_write_32(HSLS_SDIO0_SLAVE_NS, val); + + val = mmio_read_32(HSLS_SDIO1_SLAVE_NS); + val |= BIT(0); /* SDIO1 NS = 1 */ + mmio_write_32(HSLS_SDIO1_SLAVE_NS, val); + + val = mmio_read_32(HSLS_GPV_APBX_NS); + val |= BIT(14); /* SMBUS1 NS = 1 */ + val |= BIT(13); /* GPIO NS = 1 */ + val |= BIT(12); /* WDT NS = 1 */ + val |= BIT(11); /* SMBUS0 NS = 1 */ + val |= BIT(10); /* Timer7 NS = 1 */ + val |= BIT(9); /* Timer6 NS = 1 */ + val |= BIT(8); /* Timer5 NS = 1 */ + val |= BIT(7); /* Timer4 NS = 1 */ + val |= BIT(6); /* Timer3 NS = 1 */ + val |= BIT(5); /* Timer2 NS = 1 */ + val |= BIT(4); /* Timer1 NS = 1 */ + val |= BIT(3); /* Timer0 NS = 1 */ + val |= BIT(2); /* MDIO NS = 1 */ + val |= BIT(1); /* PWM NS = 1 */ + mmio_write_32(HSLS_GPV_APBX_NS, val); + + val = mmio_read_32(HSLS_GPV_QSPI_S0_NS); + val |= BIT(0); /* QSPI NS = 1 */ + mmio_write_32(HSLS_GPV_QSPI_S0_NS, val); + +#ifdef USE_FS4 + val = 0x1; /* FS4 Crypto rm_slave */ + mmio_write_32(FS4_CRYPTO_GPV_RM_SLAVE_NS, val); + val = 0x1; /* FS4 Crypto apb_switch */ + mmio_write_32(FS4_CRYPTO_GPV_APB_SWITCH_NS, val); + + val = 0x1; /* FS4 Raid rm_slave */ + mmio_write_32(FS4_RAID_GPV_RM_SLAVE_NS, val); + val = 0x1; /* FS4 Raid apb_switch */ + mmio_write_32(FS4_RAID_GPV_APB_SWITCH_NS, val); + + val = 0x1; /* FS4 Crypto IDM */ + mmio_write_32(FS4_CRYPTO_IDM_NS, val); + val = 0x1; /* FS4 RAID IDM */ + mmio_write_32(FS4_RAID_IDM_NS, val); +#endif + +#ifdef BL31_CCN_NONSECURE + /* Enable non-secure access to CCN registers */ + mmio_write_32(OLY_MN_REGISTERS_NODE0_SECURE_ACCESS, 0x1); +#endif + +#ifdef DDR_CTRL_PHY_NONSECURE + mmio_write_32(SCR_NOC_DDR_REGISTER_ACCESS, 0x1); +#endif + + paxc_mhb_ns_init(); + + /* unlock scr idm for non secure access */ + mmio_write_32(SCR_NOC_SECURITY0, 0xffffffff); + + INFO("security init done\r\n"); +} + +void brcm_gpio_pad_ns_init(void) +{ + /* configure all GPIO pads for non secure world access*/ + mmio_write_32(GPIO_S_CNTRL_REG, 0xffffffff); /* 128-140 gpio pads */ + mmio_write_32(GPIO_S_CNTRL_REG + 0x4, 0xffffffff); /* 96-127 gpio pad */ + mmio_write_32(GPIO_S_CNTRL_REG + 0x8, 0xffffffff); /* 64-95 gpio pad */ + mmio_write_32(GPIO_S_CNTRL_REG + 0xc, 0xffffffff); /* 32-63 gpio pad */ + mmio_write_32(GPIO_S_CNTRL_REG + 0x10, 0xffffffff); /* 0-31 gpio pad */ +} + +#ifndef USE_DDR +static void brcm_stingray_sram_ns_init(void) +{ + uintptr_t sram_root = TZC400_FS_SRAM_ROOT; + uintptr_t noc_root = NIC400_FS_NOC_ROOT; + + mmio_write_32(sram_root + GATE_KEEPER_OFFSET, 1); + mmio_write_32(sram_root + REGION_ATTRIBUTES_0_OFFSET, 0xc0000000); + mmio_write_32(sram_root + REGION_ID_ACCESS_0_OFFSET, 0x00010001); + mmio_write_32(noc_root + NIC400_FS_NOC_SECURITY4_OFFSET, 0x1); + INFO(" stingray sram ns init done.\n"); +} +#endif + +static void ccn_pre_init(void) +{ + /* + * Set WFC bit of RN-I nodes where FS4 is connected. + * This is required inorder to wait for read/write requests + * completion acknowledgment. Otherwise FS4 Ring Manager is + * getting stale data because of re-ordering of read/write + * requests at CCN level + */ + mmio_setbits_32(OLY_RNI3PDVM_REGISTERS_NODE8_AUX_CTL, + OLY_RNI3PDVM_REGISTERS_NODE8_AUX_CTL_WFC); +} + +static void ccn_post_init(void) +{ + mmio_setbits_32(OLY_HNI_REGISTERS_NODE0_PCIERC_RNI_NODEID_LIST, + SRP_RNI_PCIE_CONNECTED); + mmio_setbits_32(OLY_HNI_REGISTERS_NODE0_SA_AUX_CTL, + SA_AUX_CTL_SER_DEVNE_WR); + + mmio_clrbits_32(OLY_HNI_REGISTERS_NODE0_POS_CONTROL, + POS_CONTROL_HNI_POS_EN); + mmio_clrbits_32(OLY_HNI_REGISTERS_NODE0_SA_AUX_CTL, + SA_AUX_CTL_POS_EARLY_WR_COMP_EN); +} + +#ifndef BL31_BOOT_PRELOADED_SCP +static void crmu_init(void) +{ + /* + * Configure CRMU for using SMMU + */ + + /*Program CRMU Stream ID */ + mmio_write_32(CRMU_MASTER_AXI_ARUSER_CONFIG, + (CRMU_STREAM_ID << CRMU_SID_SHIFT)); + mmio_write_32(CRMU_MASTER_AXI_AWUSER_CONFIG, + (CRMU_STREAM_ID << CRMU_SID_SHIFT)); + + /* Create Identity mapping */ + arm_smmu_create_identity_map(DOMAIN_CRMU); + + /* Enable Client Port for Secure Masters*/ + arm_smmu_enable_secure_client_port(); +} +#endif + +static void brcm_fsx_init(void) +{ +#if defined(USE_FS4) && defined(USE_FS6) + #error "USE_FS4 and USE_FS6 should not be used together" +#endif + +#ifdef USE_FS4 + fsx_init(eFS4_CRYPTO, FS4_CRYPTO_RING_COUNT, FS4_CRYPTO_DME_COUNT, + FS4_CRYPTO_AE_COUNT, FS4_CRYPTO_START_STREAM_ID, + FS4_CRYPTO_MSI_DEVICE_ID, FS4_CRYPTO_IDM_IO_CONTROL_DIRECT, + FS4_CRYPTO_IDM_RESET_CONTROL, FS4_CRYPTO_BASE, + FS4_CRYPTO_DME_BASE); + + fsx_init(eFS4_RAID, FS4_RAID_RING_COUNT, FS4_RAID_DME_COUNT, + FS4_RAID_AE_COUNT, FS4_RAID_START_STREAM_ID, + FS4_RAID_MSI_DEVICE_ID, FS4_RAID_IDM_IO_CONTROL_DIRECT, + FS4_RAID_IDM_RESET_CONTROL, FS4_RAID_BASE, + FS4_RAID_DME_BASE); + + fsx_meminit("raid", + FS4_RAID_IDM_IO_CONTROL_DIRECT, + FS4_RAID_IDM_IO_STATUS); +#endif +} + +static void bcm_bl33_pass_info(void) +{ + struct bl33_info *info = (struct bl33_info *)BL33_SHARED_DDR_BASE; + + if (sizeof(*info) > BL33_SHARED_DDR_SIZE) + WARN("bl33 shared area not reserved\n"); + + info->version = BL33_INFO_VERSION; + info->chip.chip_id = PLAT_CHIP_ID_GET; + info->chip.rev_id = PLAT_CHIP_REV_GET; +} + +DEFINE_RENAME_SYSREG_RW_FUNCS(l2ctlr_el1, CORTEX_A72_L2CTLR_EL1) + +void plat_bcm_bl31_early_platform_setup(void *from_bl2, + bl_params_t *plat_params_from_bl2) +{ +#ifdef BL31_BOOT_PRELOADED_SCP + image_info_t scp_image_info; + + scp_image_info.image_base = PRELOADED_SCP_BASE; + scp_image_info.image_size = PRELOADED_SCP_SIZE; + bcm_bl2_plat_handle_scp_bl2(&scp_image_info); +#endif + /* + * In BL31, logs are saved to DDR and we have much larger space to + * store logs. We can now afford to save all logs >= the 'INFO' level + */ + bcm_elog_init((void *)BCM_ELOG_BL31_BASE, BCM_ELOG_BL31_SIZE, + LOG_LEVEL_INFO); + + INFO("L2CTLR = 0x%lx\n", read_l2ctlr_el1()); + + brcm_timer_sync_init(); + + brcm_stingray_dma_pl330_init(); + + brcm_stingray_dma_pl330_meminit(); + + brcm_stingray_spi_pl022_init(APBS_IDM_IDM_RESET_CONTROL); + +#ifdef USE_AMAC + brcm_stingray_amac_init(); +#endif + + brcm_stingray_sdio_init(); + +#ifdef NCSI_IO_DRIVE_STRENGTH_MA + brcm_stingray_ncsi_init(); +#endif + +#ifdef USE_USB + xhci_phy_init(); +#endif + +#ifdef USE_SATA + brcm_stingray_sata_init(); +#else + poweroff_sata_pll(); +#endif + + ccn_pre_init(); + + brcm_fsx_init(); + + brcm_stingray_smmu_init(); + + brcm_stingray_pka_meminit(); + + brcm_stingray_crmu_access_init(); + + brcm_stingray_scr_init(); + + brcm_stingray_hsls_tzpcprot_init(); + +#ifdef USE_I2S + brcm_stingray_audio_init(); +#endif + + ccn_post_init(); + + paxb_init(); + + paxc_init(); + +#ifndef BL31_BOOT_PRELOADED_SCP + crmu_init(); +#endif + + /* Note: this should be last thing because + * FS4 GPV registers only work after FS4 block + * (i.e. crypto,raid,cop) is out of reset. + */ + brcm_stingray_security_init(); + + brcm_gpio_pad_ns_init(); + +#ifndef USE_DDR + brcm_stingray_sram_ns_init(); +#endif + +#ifdef BL31_FORCE_CPU_FULL_FREQ + bcm_set_ihost_pll_freq(0x0, PLL_FREQ_FULL); +#endif + + brcm_stingray_gain_qspi_control(); + +#ifdef USE_PAXC + /* + * Check that the handshake has occurred and report ChiMP status. + * This is required. Otherwise (especially on Palladium) + * Linux might have booted to the pcie stage whereas + * ChiMP has not yet booted. Note that nic_mode case has already + * been considered above. + */ + if ((boot_source_get() != BOOT_SOURCE_QSPI) && + (!bcm_chimp_is_nic_mode()) && + (!bcm_chimp_wait_handshake()) + ) { + /* Does ChiMP report an error ? */ + uint32_t err; + + err = bcm_chimp_read_ctrl(CHIMP_REG_CTRL_BPE_STAT_REG); + if ((err & CHIMP_ERROR_MASK) == 0) + /* ChiMP has not booted yet, but no error reported */ + WARN("ChiMP not booted yet, but no error reported.\n"); + } + +#if DEBUG + if (boot_source_get() != BOOT_SOURCE_QSPI) + INFO("Current ChiMP Status: 0x%x; bpe_mod reg: 0x%x\n" + "fastboot register: 0x%x; handshake register 0x%x\n", + bcm_chimp_read_ctrl(CHIMP_REG_CTRL_BPE_STAT_REG), + bcm_chimp_read_ctrl(CHIMP_REG_CTRL_BPE_MODE_REG), + bcm_chimp_read_ctrl(CHIMP_REG_CTRL_FSTBOOT_PTR_REG), + bcm_chimp_read(CHIMP_REG_ECO_RESERVED)); +#endif /* DEBUG */ +#endif + +#ifdef FS4_DISABLE_CLOCK + flush_dcache_range( + PLAT_BRCM_TRUSTED_SRAM_BASE, + PLAT_BRCM_TRUSTED_SRAM_SIZE); + fs4_disable_clocks(true, true, true); +#endif + + /* pass information to BL33 through shared DDR region */ + bcm_bl33_pass_info(); + + /* + * We are not yet at the end of BL31, but we can stop log here so we do + * not need to add 'bcm_elog_exit' to the standard BL31 code. The + * benefit of capturing BL31 logs after this is very minimal in a + * production system + */ + bcm_elog_exit(); + +#if !BRCM_DISABLE_TRUSTED_WDOG + /* + * Secure watchdog was started earlier in BL2, now it's time to stop + * it + */ + sp805_stop(ARM_SP805_TWDG_BASE); +#endif +} diff --git a/plat/brcm/board/stingray/src/brcm_pm_ops.c b/plat/brcm/board/stingray/src/brcm_pm_ops.c index 81d2ccf56..090fbca53 100644 --- a/plat/brcm/board/stingray/src/brcm_pm_ops.c +++ b/plat/brcm/board/stingray/src/brcm_pm_ops.c @@ -16,9 +16,11 @@ #include #include +#include #include #include #include +#include #include "m0_cfg.h" @@ -280,7 +282,14 @@ static void __dead2 brcm_scp_sys_reset(unsigned int reset_type) static void __dead2 brcm_system_reset(void) { - brcm_scp_sys_reset(SOFT_SYS_RESET_L1); + unsigned int reset_type; + + if (bcm_chimp_is_nic_mode()) + reset_type = SOFT_RESET_L3; + else + reset_type = SOFT_SYS_RESET_L1; + + brcm_scp_sys_reset(reset_type); } static int brcm_system_reset2(int is_vendor, int reset_type, @@ -289,6 +298,11 @@ static int brcm_system_reset2(int is_vendor, int reset_type, if (!is_vendor) { /* Architectural warm boot: only warm reset is supported */ reset_type = SOFT_RESET_L3; + } else { + uint32_t boot_source = (uint32_t)cookie; + + boot_source &= BOOT_SOURCE_MASK; + brcm_stingray_set_straps(boot_source); } brcm_scp_sys_reset(reset_type); diff --git a/plat/brcm/board/stingray/src/fsx.c b/plat/brcm/board/stingray/src/fsx.c new file mode 100644 index 000000000..5725a2e2a --- /dev/null +++ b/plat/brcm/board/stingray/src/fsx.c @@ -0,0 +1,477 @@ +/* + * Copyright (c) 2019-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#define FS4_IDM_IO_CONTROL_DIRECT__SRAM_CLK_EN 0 + +#define FS4_IDM_IO_CONTROL_DIRECT__MEM_POWERON 11 +#define FS4_IDM_IO_CONTROL_DIRECT__MEM_POWEROK 12 +#define FS4_IDM_IO_CONTROL_DIRECT__MEM_ARRPOWERON 13 +#define FS4_IDM_IO_CONTROL_DIRECT__MEM_ARRPOWEROK 14 +#define FS4_IDM_IO_CONTROL_DIRECT__MEM_ISO 15 +#define FS4_IDM_IO_CONTROL_DIRECT__CLK_EN 31 + +#define FS4_IDM_IO_STATUS__MEM_POWERON 0 +#define FS4_IDM_IO_STATUS__MEM_POWEROK 1 +#define FS4_IDM_IO_STATUS__MEM_ARRPOWERON 2 +#define FS4_IDM_IO_STATUS__MEM_ARRPOWEROK 3 +#define FS4_IDM_IO_STATUS__MEM_ALLOK 0xf + +#define FS4_IDM_RESET_CONTROL__RESET 0 + +#define FSX_RINGx_BASE(__b, __i) \ + ((__b) + (__i) * 0x10000) + +#define FSX_RINGx_VERSION_NUMBER(__b, __i) \ + (FSX_RINGx_BASE(__b, __i) + 0x0) + +#define FSX_RINGx_MSI_DEV_ID(__b, __i) \ + (FSX_RINGx_BASE(__b, __i) + 0x44) + +#define FSX_COMM_RINGx_BASE(__b, __i) \ + ((__b) + 0x200000 + (__i) * 0x100) + +#define FSX_COMM_RINGx_CONTROL(__b, __i) \ + (FSX_COMM_RINGx_BASE(__b, __i) + 0x0) +#define FSX_COMM_RINGx_CONTROL__AXI_ID 8 +#define FSX_COMM_RINGx_CONTROL__AXI_ID_MASK 0x1f +#define FSX_COMM_RINGx_CONTROL__PRIORITY 4 +#define FSX_COMM_RINGx_CONTROL__PRIORITY_MASK 0x7 +#define FSX_COMM_RINGx_CONTROL__AE_GROUP 0 +#define FSX_COMM_RINGx_CONTROL__AE_GROUP_MASK 0x7 + +#define FSX_COMM_RINGx_MSI_DEV_ID(__b, __i) \ + (FSX_COMM_RINGx_BASE(__b, __i) + 0x4) + +#define FSX_AEx_BASE(__b, __i) \ + ((__b) + 0x202000 + (__i) * 0x100) + +#define FSX_AEx_CONTROL_REGISTER(__b, __i) \ + (FSX_AEx_BASE(__b, __i) + 0x0) +#define FSX_AEx_CONTROL_REGISTER__ACTIVE 4 +#define FSX_AEx_CONTROL_REGISTER__GROUP_ID 0 +#define FSX_AEx_CONTROL_REGISTER__GROUP_ID_MASK 0x7 + +#define FSX_COMM_RM_RING_SECURITY_SETTING 0x0 + +#define FSX_COMM_RM_SSID_CONTROL 0x4 +#define FSX_COMM_RM_SSID_CONTROL__RING_BITS 5 +#define FSX_COMM_RM_SSID_CONTROL__MASK 0x3ff + +#define FSX_COMM_RM_CONTROL_REGISTER 0x8 +#define FSX_COMM_RM_CONTROL_REGISTER__CONFIG_DONE 2 +#define FSX_COMM_RM_CONTROL_REGISTER__AE_TIMEOUT 5 +#define FSX_COMM_RM_CONTROL_REGISTER__AE_LOCKING 7 + +#define FSX_COMM_RM_TIMER_CONTROL_0 0xc +#define FSX_COMM_RM_TIMER_CONTROL_0__FAST 16 +#define FSX_COMM_RM_TIMER_CONTROL_0__MEDIUM 0 + +#define FSX_COMM_RM_TIMER_CONTROL_1 0x10 +#define FSX_COMM_RM_TIMER_CONTROL_1__SLOW 16 +#define FSX_COMM_RM_TIMER_CONTROL_1__IDLE 0 + +#define FSX_COMM_RM_BURST_BD_THRESHOLD 0x14 +#define FSX_COMM_RM_BURST_BD_THRESHOLD_LOW 0 +#define FSX_COMM_RM_BURST_BD_THRESHOLD_HIGH 16 + +#define FSX_COMM_RM_BURST_LENGTH 0x18 +#define FSX_COMM_RM_BURST_LENGTH__FOR_DDR_ADDR_GEN 16 +#define FSX_COMM_RM_BURST_LENGTH__FOR_DDR_ADDR_GEN_MASK 0x1ff +#define FSX_COMM_RM_BURST_LENGTH__FOR_TOGGLE 0 +#define FSX_COMM_RM_BURST_LENGTH__FOR_TOGGLE_MASK 0x1ff + +#define FSX_COMM_RM_FIFO_THRESHOLD 0x1c +#define FSX_COMM_RM_FIFO_THRESHOLD__BD_FIFO_FULL 16 +#define FSX_COMM_RM_FIFO_THRESHOLD__BD_FIFO_FULL_MASK 0x1ff +#define FSX_COMM_RM_FIFO_THRESHOLD__AE_FIFO_FULL 0 +#define FSX_COMM_RM_FIFO_THRESHOLD__AE_FIFO_FULL_MASK 0x1f + +#define FSX_COMM_RM_AE_TIMEOUT 0x24 + +#define FSX_COMM_RM_RING_FLUSH_TIMEOUT 0x2c + +#define FSX_COMM_RM_MEMORY_CONFIGURATION 0x30 +#define FSX_COMM_RM_MEMORY_CONFIGURATION__ARRPOWERONIN 12 +#define FSX_COMM_RM_MEMORY_CONFIGURATION__ARRPOWEROKIN 13 +#define FSX_COMM_RM_MEMORY_CONFIGURATION__POWERONIN 14 +#define FSX_COMM_RM_MEMORY_CONFIGURATION__POWEROKIN 15 + +#define FSX_COMM_RM_AXI_CONTROL 0x34 +#define FSX_COMM_RM_AXI_CONTROL__WRITE_CHANNEL_EN 28 +#define FSX_COMM_RM_AXI_CONTROL__READ_CHANNEL_EN 24 +#define FSX_COMM_RM_AXI_CONTROL__AWQOS 20 +#define FSX_COMM_RM_AXI_CONTROL__ARQOS 16 +#define FSX_COMM_RM_AXI_CONTROL__AWPROT 12 +#define FSX_COMM_RM_AXI_CONTROL__ARPROT 8 +#define FSX_COMM_RM_AXI_CONTROL__AWCACHE 4 +#define FSX_COMM_RM_AXI_CONTROL__ARCACHE 0 + +#define FSX_COMM_RM_CONFIG_INTERRUPT_STATUS_CLEAR 0x48 + +#define FSX_COMM_RM_GROUP_PKT_EXTENSION_SUPPORT 0xc0 + +#define FSX_COMM_RM_AXI_READ_BURST_THRESHOLD 0xc8 +#define FSX_COMM_RM_AXI_READ_BURST_THRESHOLD__MASK 0x1ff +#define FSX_COMM_RM_AXI_READ_BURST_THRESHOLD__MAX 16 +#define FSX_COMM_RM_AXI_READ_BURST_THRESHOLD__MIN 0 + +#define FSX_COMM_RM_GROUP_RING_COUNT 0xcc + +#define FSX_COMM_RM_MAIN_HW_INIT_DONE 0x12c +#define FSX_COMM_RM_MAIN_HW_INIT_DONE__MASK 0x1 + +#define FSX_DMEx_BASE(__b, __i) \ + ((__b) + (__i) * 0x1000) + +#define FSX_DMEx_AXI_CONTROL(__b, __i) \ + (FSX_DMEx_BASE(__b, __i) + 0x4) +#define FSX_DMEx_AXI_CONTROL__WRITE_CHANNEL_EN 28 +#define FSX_DMEx_AXI_CONTROL__READ_CHANNEL_EN 24 +#define FSX_DMEx_AXI_CONTROL__AWQOS 20 +#define FSX_DMEx_AXI_CONTROL__ARQOS 16 +#define FSX_DMEx_AXI_CONTROL__AWCACHE 4 +#define FSX_DMEx_AXI_CONTROL__ARCACHE 0 + +#define FSX_DMEx_WR_FIFO_THRESHOLD(__b, __i) \ + (FSX_DMEx_BASE(__b, __i) + 0xc) +#define FSX_DMEx_WR_FIFO_THRESHOLD__MASK 0x3ff +#define FSX_DMEx_WR_FIFO_THRESHOLD__MAX 10 +#define FSX_DMEx_WR_FIFO_THRESHOLD__MIN 0 + +#define FSX_DMEx_RD_FIFO_THRESHOLD(__b, __i) \ + (FSX_DMEx_BASE(__b, __i) + 0x14) +#define FSX_DMEx_RD_FIFO_THRESHOLD__MASK 0x3ff +#define FSX_DMEx_RD_FIFO_THRESHOLD__MAX 10 +#define FSX_DMEx_RD_FIFO_THRESHOLD__MIN 0 + +#define FS6_SUB_TOP_BASE 0x66D8F800 +#define FS6_PKI_DME_RESET 0x4 +#define PKI_DME_RESET 1 + +char *fsx_type_names[] = { + "fs4-raid", + "fs4-crypto", + "fs6-pki", +}; + +void fsx_init(eFSX_TYPE fsx_type, + unsigned int ring_count, + unsigned int dme_count, + unsigned int ae_count, + unsigned int start_stream_id, + unsigned int msi_dev_id, + uintptr_t idm_io_control_direct, + uintptr_t idm_reset_control, + uintptr_t base, + uintptr_t dme_base) +{ + int try; + unsigned int i, v, data; + uintptr_t fs4_idm_io_control_direct = idm_io_control_direct; + uintptr_t fs4_idm_reset_control = idm_reset_control; + uintptr_t fsx_comm_rm = (base + 0x203000); + + VERBOSE("fsx %s init start\n", fsx_type_names[fsx_type]); + + if (fsx_type == eFS4_RAID || fsx_type == eFS4_CRYPTO) { + /* Enable FSx engine clock */ + VERBOSE(" - enable fsx clock\n"); + mmio_write_32(fs4_idm_io_control_direct, + (1U << FS4_IDM_IO_CONTROL_DIRECT__CLK_EN)); + udelay(500); + + /* Reset FSx engine */ + VERBOSE(" - reset fsx\n"); + v = mmio_read_32(fs4_idm_reset_control); + v |= (1 << FS4_IDM_RESET_CONTROL__RESET); + mmio_write_32(fs4_idm_reset_control, v); + udelay(500); + v = mmio_read_32(fs4_idm_reset_control); + v &= ~(1 << FS4_IDM_RESET_CONTROL__RESET); + mmio_write_32(fs4_idm_reset_control, v); + } else { + /* + * Default RM and AE are out of reset, + * So only DME Reset added here + */ + v = mmio_read_32(FS6_SUB_TOP_BASE + FS6_PKI_DME_RESET); + v &= ~(PKI_DME_RESET); + mmio_write_32(FS6_SUB_TOP_BASE + FS6_PKI_DME_RESET, v); + } + + /* Wait for HW-init done */ + VERBOSE(" - wait for HW-init done\n"); + try = 10000; + do { + udelay(1); + data = mmio_read_32(fsx_comm_rm + + FSX_COMM_RM_MAIN_HW_INIT_DONE); + try--; + } while (!(data & FSX_COMM_RM_MAIN_HW_INIT_DONE__MASK) && (try > 0)); + + if (try <= 0) + ERROR("fsx_comm_rm + 0x%x: 0x%x\n", + data, FSX_COMM_RM_MAIN_HW_INIT_DONE); + + /* Make all rings non-secured */ + VERBOSE(" - make all rings non-secured\n"); + v = 0xffffffff; + mmio_write_32(fsx_comm_rm + FSX_COMM_RM_RING_SECURITY_SETTING, v); + + /* Set start stream-id for rings to */ + VERBOSE(" - set start stream-id for rings to 0x%x\n", + start_stream_id); + v = start_stream_id >> FSX_COMM_RM_SSID_CONTROL__RING_BITS; + v &= FSX_COMM_RM_SSID_CONTROL__MASK; + mmio_write_32(fsx_comm_rm + FSX_COMM_RM_SSID_CONTROL, v); + + /* Set timer configuration */ + VERBOSE(" - set timer configuration\n"); + v = 0x0271 << FSX_COMM_RM_TIMER_CONTROL_0__MEDIUM; + v |= (0x0138 << FSX_COMM_RM_TIMER_CONTROL_0__FAST); + mmio_write_32(fsx_comm_rm + FSX_COMM_RM_TIMER_CONTROL_0, v); + v = 0x09c4 << FSX_COMM_RM_TIMER_CONTROL_1__IDLE; + v |= (0x04e2 << FSX_COMM_RM_TIMER_CONTROL_1__SLOW); + mmio_write_32(fsx_comm_rm + FSX_COMM_RM_TIMER_CONTROL_1, v); + v = 0x0000f424; + mmio_write_32(fsx_comm_rm + FSX_COMM_RM_RING_FLUSH_TIMEOUT, v); + + /* Set burst length and fifo threshold */ + VERBOSE(" - set burst length, fifo and bd threshold\n"); + v = 0x0; + v |= (0x8 << FSX_COMM_RM_BURST_LENGTH__FOR_DDR_ADDR_GEN); + v |= (0x8 << FSX_COMM_RM_BURST_LENGTH__FOR_TOGGLE); + mmio_write_32(fsx_comm_rm + FSX_COMM_RM_BURST_LENGTH, v); + v = 0x0; + v |= (0x67 << FSX_COMM_RM_FIFO_THRESHOLD__BD_FIFO_FULL); + v |= (0x18 << FSX_COMM_RM_FIFO_THRESHOLD__AE_FIFO_FULL); + mmio_write_32(fsx_comm_rm + FSX_COMM_RM_FIFO_THRESHOLD, v); + v = 0x0; + v |= (0x8 << FSX_COMM_RM_BURST_BD_THRESHOLD_LOW); + v |= (0x8 << FSX_COMM_RM_BURST_BD_THRESHOLD_HIGH); + mmio_write_32(fsx_comm_rm + FSX_COMM_RM_BURST_BD_THRESHOLD, v); + + /* Set memory configuration */ + VERBOSE(" - set memory configuration\n"); + v = 0x0; + v |= (1 << FSX_COMM_RM_MEMORY_CONFIGURATION__POWERONIN); + v |= (1 << FSX_COMM_RM_MEMORY_CONFIGURATION__POWEROKIN); + v |= (1 << FSX_COMM_RM_MEMORY_CONFIGURATION__ARRPOWERONIN); + v |= (1 << FSX_COMM_RM_MEMORY_CONFIGURATION__ARRPOWEROKIN); + mmio_write_32(fsx_comm_rm + FSX_COMM_RM_MEMORY_CONFIGURATION, v); + + /* AXI configuration for RM */ + v = 0; + v |= (0x1 << FSX_COMM_RM_AXI_CONTROL__WRITE_CHANNEL_EN); + v |= (0x1 << FSX_COMM_RM_AXI_CONTROL__READ_CHANNEL_EN); + v |= (0xe << FSX_COMM_RM_AXI_CONTROL__AWQOS); + v |= (0xa << FSX_COMM_RM_AXI_CONTROL__ARQOS); + v |= (0x2 << FSX_COMM_RM_AXI_CONTROL__AWPROT); + v |= (0x2 << FSX_COMM_RM_AXI_CONTROL__ARPROT); + v |= (0xf << FSX_COMM_RM_AXI_CONTROL__AWCACHE); + v |= (0xf << FSX_COMM_RM_AXI_CONTROL__ARCACHE); + mmio_write_32(fsx_comm_rm + FSX_COMM_RM_AXI_CONTROL, v); + VERBOSE(" - set AXI control = 0x%x\n", + mmio_read_32(fsx_comm_rm + FSX_COMM_RM_AXI_CONTROL)); + v = 0x0; + v |= (0x10 << FSX_COMM_RM_AXI_READ_BURST_THRESHOLD__MAX); + v |= (0x10 << FSX_COMM_RM_AXI_READ_BURST_THRESHOLD__MIN); + mmio_write_32(fsx_comm_rm + FSX_COMM_RM_AXI_READ_BURST_THRESHOLD, v); + VERBOSE(" - set AXI read burst threshold = 0x%x\n", + mmio_read_32(fsx_comm_rm + FSX_COMM_RM_AXI_READ_BURST_THRESHOLD)); + + /* Configure group ring count for all groups */ + /* By default we schedule extended packets + * on all AEs/DMEs in a group. + */ + v = (dme_count & 0xf) << 0; + v |= (dme_count & 0xf) << 4; + v |= (dme_count & 0xf) << 8; + v |= (dme_count & 0xf) << 12; + v |= (dme_count & 0xf) << 16; + v |= (dme_count & 0xf) << 20; + v |= (dme_count & 0xf) << 24; + v |= (dme_count & 0xf) << 28; + mmio_write_32(fsx_comm_rm + FSX_COMM_RM_GROUP_RING_COUNT, v); + + /* + * Due to HW issue spurious interrupts are getting generated. + * To fix sw needs to clear the config status interrupts + * before setting CONFIG_DONE. + */ + mmio_write_32(fsx_comm_rm + + FSX_COMM_RM_CONFIG_INTERRUPT_STATUS_CLEAR, + 0xffffffff); + + /* Configure RM control */ + VERBOSE(" - configure RM control\n"); + v = mmio_read_32(fsx_comm_rm + FSX_COMM_RM_CONTROL_REGISTER); + v |= (1 << FSX_COMM_RM_CONTROL_REGISTER__AE_LOCKING); + mmio_write_32(fsx_comm_rm + FSX_COMM_RM_CONTROL_REGISTER, v); + v |= (1 << FSX_COMM_RM_CONTROL_REGISTER__CONFIG_DONE); + mmio_write_32(fsx_comm_rm + FSX_COMM_RM_CONTROL_REGISTER, v); + + /* Configure AE timeout */ + VERBOSE(" - configure AE timeout\n"); + v = 0x00003fff; + mmio_write_32(fsx_comm_rm + FSX_COMM_RM_AE_TIMEOUT, v); + + /* Initialize all AEs */ + for (i = 0; i < ae_count; i++) { + VERBOSE(" - initialize AE%d\n", i); + v = (0x1 << FSX_AEx_CONTROL_REGISTER__ACTIVE); + mmio_write_32(FSX_AEx_CONTROL_REGISTER(base, i), v); + } + + /* Initialize all DMEs */ + for (i = 0; i < dme_count; i++) { + VERBOSE(" - initialize DME%d\n", i); + v = 0; + v |= (0x1 << FSX_DMEx_AXI_CONTROL__WRITE_CHANNEL_EN); + v |= (0x1 << FSX_DMEx_AXI_CONTROL__READ_CHANNEL_EN); + v |= (0xe << FSX_DMEx_AXI_CONTROL__AWQOS); + v |= (0xa << FSX_DMEx_AXI_CONTROL__ARQOS); + v |= (0xf << FSX_DMEx_AXI_CONTROL__AWCACHE); + v |= (0xf << FSX_DMEx_AXI_CONTROL__ARCACHE); + mmio_write_32(FSX_DMEx_AXI_CONTROL(dme_base, i), v); + VERBOSE(" -- AXI_CONTROL = 0x%x\n", + mmio_read_32(FSX_DMEx_AXI_CONTROL(dme_base, i))); + v = 0; + v |= (0x4 << FSX_DMEx_WR_FIFO_THRESHOLD__MIN); + v |= (0x4 << FSX_DMEx_WR_FIFO_THRESHOLD__MAX); + mmio_write_32(FSX_DMEx_WR_FIFO_THRESHOLD(dme_base, i), v); + VERBOSE(" -- WR_FIFO_THRESHOLD = 0x%x\n", + mmio_read_32(FSX_DMEx_WR_FIFO_THRESHOLD(dme_base, i))); + v = 0; + v |= (0x4 << FSX_DMEx_RD_FIFO_THRESHOLD__MIN); + v |= (0x4 << FSX_DMEx_RD_FIFO_THRESHOLD__MAX); + mmio_write_32(FSX_DMEx_RD_FIFO_THRESHOLD(dme_base, i), v); + VERBOSE(" -- RD_FIFO_THRESHOLD = 0x%x\n", + mmio_read_32(FSX_DMEx_RD_FIFO_THRESHOLD(dme_base, i))); + } + + /* Configure ring axi id and msi device id */ + for (i = 0; i < ring_count; i++) { + VERBOSE(" - ring%d version=0x%x\n", i, + mmio_read_32(FSX_RINGx_VERSION_NUMBER(base, i))); + mmio_write_32(FSX_COMM_RINGx_MSI_DEV_ID(base, i), + msi_dev_id); + v = 0; + v |= ((i & FSX_COMM_RINGx_CONTROL__AXI_ID_MASK) << + FSX_COMM_RINGx_CONTROL__AXI_ID); + mmio_write_32(FSX_COMM_RINGx_CONTROL(base, i), v); + } + + INFO("fsx %s init done\n", fsx_type_names[fsx_type]); +} + +void fsx_meminit(const char *name, + uintptr_t idm_io_control_direct, + uintptr_t idm_io_status) +{ + int try; + unsigned int val; + + VERBOSE("fsx %s meminit start\n", name); + + VERBOSE(" - arrpoweron\n"); + mmio_setbits_32(idm_io_control_direct, + BIT(FS4_IDM_IO_CONTROL_DIRECT__MEM_ARRPOWERON)); + while (!(mmio_read_32(idm_io_status) & + BIT(FS4_IDM_IO_STATUS__MEM_ARRPOWERON))) + ; + + VERBOSE(" - arrpowerok\n"); + mmio_setbits_32(idm_io_control_direct, + (1 << FS4_IDM_IO_CONTROL_DIRECT__MEM_ARRPOWEROK)); + while (!(mmio_read_32(idm_io_status) & + BIT(FS4_IDM_IO_STATUS__MEM_ARRPOWEROK))) + ; + + VERBOSE(" - poweron\n"); + mmio_setbits_32(idm_io_control_direct, + (1 << FS4_IDM_IO_CONTROL_DIRECT__MEM_POWERON)); + while (!(mmio_read_32(idm_io_status) & + BIT(FS4_IDM_IO_STATUS__MEM_POWERON))) + ; + + VERBOSE(" - powerok\n"); + mmio_setbits_32(idm_io_control_direct, + (1 << FS4_IDM_IO_CONTROL_DIRECT__MEM_POWEROK)); + while (!(mmio_read_32(idm_io_status) & + BIT(FS4_IDM_IO_STATUS__MEM_POWEROK))) + ; + + /* Final check on all power bits */ + try = 10; + do { + val = mmio_read_32(idm_io_status); + if (val == FS4_IDM_IO_STATUS__MEM_ALLOK) + break; + + /* Wait sometime */ + mdelay(1); + + try--; + } while (try > 0); + + /* Remove memory isolation if things are fine. */ + if (try <= 0) { + INFO(" - powerup failed\n"); + } else { + VERBOSE(" - remove isolation\n"); + mmio_clrbits_32(idm_io_control_direct, + (1 << FS4_IDM_IO_CONTROL_DIRECT__MEM_ISO)); + VERBOSE(" - powerup done\n"); + } + + INFO("fsx %s meminit done\n", name); +} + +void fs4_disable_clocks(bool disable_sram, + bool disable_crypto, + bool disable_raid) +{ + VERBOSE("fs4 disable clocks start\n"); + + if (disable_sram) { + VERBOSE(" - disable sram clock\n"); + mmio_clrbits_32(FS4_SRAM_IDM_IO_CONTROL_DIRECT, + (1 << FS4_IDM_IO_CONTROL_DIRECT__SRAM_CLK_EN)); + } + + if (disable_crypto) { + VERBOSE(" - disable crypto clock\n"); + mmio_setbits_32(CDRU_GENPLL5_CONTROL1, + CDRU_GENPLL5_CONTROL1__CHNL1_CRYPTO_AE_CLK); + } + + if (disable_raid) { + VERBOSE(" - disable raid clock\n"); + mmio_setbits_32(CDRU_GENPLL5_CONTROL1, + CDRU_GENPLL5_CONTROL1__CHNL2_RAID_AE_CLK); + } + + if (disable_sram && disable_crypto && disable_raid) { + VERBOSE(" - disable root clock\n"); + mmio_setbits_32(CDRU_GENPLL5_CONTROL1, + CDRU_GENPLL5_CONTROL1__CHNL0_DME_CLK); + mmio_setbits_32(CDRU_GENPLL2_CONTROL1, + CDRU_GENPLL2_CONTROL1__CHNL6_FS4_CLK); + } + + INFO("fs4 disable clocks done\n"); +} diff --git a/plat/brcm/board/stingray/src/iommu.c b/plat/brcm/board/stingray/src/iommu.c new file mode 100644 index 000000000..de8b995db --- /dev/null +++ b/plat/brcm/board/stingray/src/iommu.c @@ -0,0 +1,536 @@ +/* + * Copyright (c) 2017 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +#include +#include + +#define SMMU_BASE 0x64000000 +#define ARM_SMMU_MAX_NUM_CNTXT_BANK 64 +#define SMMU_CTX_BANK_IDX_SECURE_CRMU 63 +#define ARM_SMMU_NUM_SECURE_MASTER 1 +#define ARM_SMMU_NSNUMCBO (ARM_SMMU_MAX_NUM_CNTXT_BANK - \ + ARM_SMMU_NUM_SECURE_MASTER) +#define ARM_SMMU_NSNUMSMRGO (ARM_SMMU_MAX_NUM_CNTXT_BANK - \ + ARM_SMMU_NUM_SECURE_MASTER) +/* Reserved Banks. */ +#define SMMU_CTX_BANK_IDX (SMMU_CTX_BANK_IDX_SECURE_CRMU - \ + ARM_SMMU_NUM_SECURE_MASTER) +#define NUM_OF_SMRS 1 + +#define STG1_WITH_STG2_BYPASS 1 +#define ARM_LPAE_PGTBL_PHYS_CRMU 0x880000000 +#define ARM_LPAE_PGTBL_PHYS 0x880200000 +#define ARM_LPAE_PGTBL_PTE_CNT 512 +#define ARM_LPAE_PTE_L1_BLOCK_SIZE 0x40000000 +#define ARM_LPAE_PTE_L1_ADDR_MASK 0x0000FFFFC0000000UL +#define ARM_LPAE_PTE_TABLE 0x2UL +#define ARM_LPAE_PTE_VALID 0x1UL +#define ARM_LPAE_PTE_ATTRINDX 2 +#define ARM_LPAE_PTE_NS 5 +#define ARM_LPAE_PTE_AP 6 +#define ARM_LPAE_PTE_AP_EL1_RW 0x0 +#define ARM_LPAE_PTE_AP_EL0_RW 0x1 +#define ARM_LPAE_PTE_SH 8 +#define ARM_LPAE_PTE_SH_NON 0x0 +#define ARM_LPAE_PTE_SH_OUTER 0x2 +#define ARM_LPAE_PTE_SH_INNER 0x3 +#define ARM_LPAE_PTE_AF 10 +#define ARM_SMMU_RES_SIZE 0x80000 + +#define ARM_LPAE_PTE_NSTABLE 0x8000000000000000UL +#define ARM_LPAE_PTE_L1_INDEX_SHIFT 30 +#define ARM_LPAE_PTE_L1_INDEX_MASK 0x1ff +#define ARM_LPAE_PTE_L0_INDEX_SHIFT 39 +#define ARM_LPAE_PTE_L0_INDEX_MASK 0x1ff +#define ARM_LPAE_PTE_TABLE_MASK ~(0xfffUL) +/* Configuration registers */ +#define ARM_SMMU_GR0_sCR0 0x0 +#define sCR0_CLIENTPD (1 << 0) +#define sCR0_GFRE (1 << 1) +#define sCR0_GFIE (1 << 2) +#define sCR0_GCFGFRE (1 << 4) +#define sCR0_GCFGFIE (1 << 5) +#define sCR0_USFCFG (1 << 10) +#define sCR0_VMIDPNE (1 << 11) +#define sCR0_PTM (1 << 12) +#define sCR0_FB (1 << 13) +#define sCR0_VMID16EN (1 << 31) +#define sCR0_BSU_SHIFT 14 +#define sCR0_BSU_MASK 0x3 +#define ARM_SMMU_SMMU_SCR1 0x4 +#define SCR1_NSNUMCBO_MASK 0xFF +#define SCR1_NSNUMCBO_SHIFT 0x0 +#define SCR1_NSNUMSMRGO_MASK 0xFF00 +#define SCR1_NSNUMSMRGO_SHIFT 0x8 + +/* Identification registers */ +#define ARM_SMMU_GR0_ID0 0x20 +#define ARM_SMMU_GR0_ID1 0x24 +#define ARM_SMMU_GR0_ID2 0x28 +#define ARM_SMMU_GR0_ID3 0x2c +#define ARM_SMMU_GR0_ID4 0x30 +#define ARM_SMMU_GR0_ID5 0x34 +#define ARM_SMMU_GR0_ID6 0x38 +#define ARM_SMMU_GR0_ID7 0x3c +#define ARM_SMMU_GR0_sGFSR 0x48 +#define ARM_SMMU_GR0_sGFSYNR0 0x50 +#define ARM_SMMU_GR0_sGFSYNR1 0x54 +#define ARM_SMMU_GR0_sGFSYNR2 0x58 + +#define ID1_PAGESIZE (1U << 31) +#define ID1_NUMPAGENDXB_SHIFT 28 +#define ID1_NUMPAGENDXB_MASK 7 +#define ID1_NUMS2CB_SHIFT 16 +#define ID1_NUMS2CB_MASK 0xff +#define ID1_NUMCB_SHIFT 0 +#define ID1_NUMCB_MASK 0xff + +/* SMMU global address space */ +#define ARM_SMMU_GR0(smmu) ((smmu)->base) +#define ARM_SMMU_GR1(smmu) ((smmu)->base + (1 << (smmu)->pgshift)) + +/* Stream mapping registers */ +#define ARM_SMMU_GR0_SMR(n) (0x800 + (n << 2)) +#define SMR_VALID (1U << 31) +#define SMR_MASK_SHIFT 16 +#define SMR_ID_SHIFT 0 + +#define ARM_SMMU_GR0_S2CR(n) (0xc00 + (n << 2)) +#define S2CR_CBNDX_SHIFT 0 +#define S2CR_CBNDX_MASK 0xff +#define S2CR_TYPE_SHIFT 16 +#define S2CR_TYPE_MASK 0x3 + +#define ARM_SMMU_GR1_CBA2R(n) (0x800 + (n << 2)) +#define CBA2R_RW64_32BIT (0 << 0) +#define CBA2R_RW64_64BIT (1 << 0) +#define CBA2R_VMID_SHIFT 16 +#define CBA2R_VMID_MASK 0xffff + +#define ARM_SMMU_GR1_CBAR(n) (0x0 + (n << 2)) +#define CBAR_VMID_SHIFT 0 +#define CBAR_VMID_MASK 0xff +#define CBAR_S1_BPSHCFG_SHIFT 8 +#define CBAR_S1_BPSHCFG_MASK 3 +#define CBAR_S1_BPSHCFG_NSH 3 +#define CBAR_S1_MEMATTR_SHIFT 12 +#define CBAR_S1_MEMATTR_MASK 0xf +#define CBAR_S1_MEMATTR_WB 0xf +#define CBAR_TYPE_SHIFT 16 +#define CBAR_TYPE_MASK 0x3 +#define CBAR_TYPE_S2_TRANS (0 << CBAR_TYPE_SHIFT) +#define CBAR_TYPE_S1_TRANS_S2_BYPASS (1 << CBAR_TYPE_SHIFT) +#define CBAR_TYPE_S1_TRANS_S2_FAULT (2 << CBAR_TYPE_SHIFT) +#define CBAR_TYPE_S1_TRANS_S2_TRANS (3 << CBAR_TYPE_SHIFT) +#define CBAR_IRPTNDX_SHIFT 24 +#define CBAR_IRPTNDX_MASK 0xff + +/* Translation context bank */ +#define ARM_SMMU_CB_BASE(smmu) ((smmu)->base + ((smmu)->size >> 1)) +#define ARM_SMMU_CB(smmu, n) ((n) * (1 << (smmu)->pgshift)) + +#define ARM_SMMU_CB_SCTLR 0x0 +#define ARM_SMMU_CB_ACTLR 0x4 +#define ARM_SMMU_CB_RESUME 0x8 +#define ARM_SMMU_CB_TTBCR2 0x10 +#define ARM_SMMU_CB_TTBR0 0x20 +#define ARM_SMMU_CB_TTBR1 0x28 +#define ARM_SMMU_CB_TTBCR 0x30 +#define ARM_SMMU_CB_CONTEXTIDR 0x34 +#define ARM_SMMU_CB_S1_MAIR0 0x38 +#define ARM_SMMU_CB_S1_MAIR1 0x3c +#define ARM_SMMU_CB_PAR 0x50 +#define ARM_SMMU_CB_FSR 0x58 +#define ARM_SMMU_CB_FAR 0x60 +#define ARM_SMMU_CB_FSYNR0 0x68 +#define ARM_SMMU_CB_S1_TLBIVA 0x600 +#define ARM_SMMU_CB_S1_TLBIASID 0x610 +#define ARM_SMMU_CB_S1_TLBIVAL 0x620 +#define ARM_SMMU_CB_S2_TLBIIPAS2 0x630 +#define ARM_SMMU_CB_S2_TLBIIPAS2L 0x638 +#define ARM_SMMU_CB_ATS1PR 0x800 +#define ARM_SMMU_CB_ATSR 0x8f0 + +#define SCTLR_S1_ASIDPNE (1 << 12) +#define SCTLR_CFCFG (1 << 7) +#define SCTLR_CFIE (1 << 6) +#define SCTLR_CFRE (1 << 5) +#define SCTLR_E (1 << 4) +#define SCTLR_AFE (1 << 2) +#define SCTLR_TRE (1 << 1) +#define SCTLR_M (1 << 0) + +/* ARM LPAE configuration. */ +/**************************************************************/ +/* Register bits */ +#define ARM_32_LPAE_TCR_EAE (1 << 31) +#define ARM_64_LPAE_S2_TCR_RES1 (1 << 31) + +#define ARM_LPAE_TCR_EPD1 (1 << 23) + +#define ARM_LPAE_TCR_TG0_4K (0 << 14) +#define ARM_LPAE_TCR_TG0_64K (1 << 14) +#define ARM_LPAE_TCR_TG0_16K (2 << 14) + +#define ARM_LPAE_TCR_SH0_SHIFT 12 +#define ARM_LPAE_TCR_SH0_MASK 0x3 +#define ARM_LPAE_TCR_SH_NS 0 +#define ARM_LPAE_TCR_SH_OS 2 +#define ARM_LPAE_TCR_SH_IS 3 + +#define ARM_LPAE_TCR_ORGN0_SHIFT 10 +#define ARM_LPAE_TCR_IRGN0_SHIFT 8 +#define ARM_LPAE_TCR_RGN_MASK 0x3 +#define ARM_LPAE_TCR_RGN_NC 0 +#define ARM_LPAE_TCR_RGN_WBWA 1 +#define ARM_LPAE_TCR_RGN_WT 2 +#define ARM_LPAE_TCR_RGN_WB 3 + +#define ARM_LPAE_TCR_SL0_SHIFT 6 +#define ARM_LPAE_TCR_SL0_MASK 0x3 + +#define ARM_LPAE_TCR_T0SZ_SHIFT 0 +#define ARM_LPAE_TCR_SZ_MASK 0xf + +#define ARM_LPAE_TCR_PS_SHIFT 16 +#define ARM_LPAE_TCR_PS_MASK 0x7 + +#define ARM_LPAE_TCR_IPS_SHIFT 32 +#define ARM_LPAE_TCR_IPS_MASK 0x7 + +#define ARM_LPAE_TCR_PS_32_BIT 0x0ULL +#define ARM_LPAE_TCR_PS_36_BIT 0x1ULL +#define ARM_LPAE_TCR_PS_40_BIT 0x2ULL +#define ARM_LPAE_TCR_PS_42_BIT 0x3ULL +#define ARM_LPAE_TCR_PS_44_BIT 0x4ULL +#define ARM_LPAE_TCR_PS_48_BIT 0x5ULL + +#define ARM_LPAE_MAIR_ATTR_SHIFT(n) ((n) << 3) +#define ARM_LPAE_MAIR_ATTR_MASK 0xff +#define ARM_LPAE_MAIR_ATTR_DEVICE 0x04 +#define ARM_LPAE_MAIR_ATTR_NC 0x44 +#define ARM_LPAE_MAIR_ATTR_WBRWA 0xff +#define ARM_LPAE_MAIR_ATTR_IDX_NC 0 +#define ARM_LPAE_MAIR_ATTR_IDX_CACHE 1 +#define ARM_LPAE_MAIR_ATTR_IDX_DEV 2 + +#define TTBRn_ASID_SHIFT 48 +#define TTBCR2_SEP_SHIFT 15 +#define TTBCR2_SEP_UPSTREAM (0x7 << TTBCR2_SEP_SHIFT) +#define TTBCR2_AS (1 << 4) +#define TTBCR_T0SZ(ia_bits) (64 - (ia_bits)) + +#define S2CR_PRIVCFG_SHIFT 24 +#define S2CR_PRIVCFG_MASK 0x3 + +/**************************************************************/ + +uint16_t paxc_stream_ids[] = { 0x2000 }; + +uint16_t paxc_stream_ids_mask[] = { 0x1fff }; +uint16_t crmu_stream_ids[] = { CRMU_STREAM_ID }; +uint16_t crmu_stream_ids_mask[] = { 0x0 }; + +enum arm_smmu_s2cr_type { + S2CR_TYPE_TRANS, + S2CR_TYPE_BYPASS, + S2CR_TYPE_FAULT, +}; + +enum arm_smmu_s2cr_privcfg { + S2CR_PRIVCFG_DEFAULT, + S2CR_PRIVCFG_DIPAN, + S2CR_PRIVCFG_UNPRIV, + S2CR_PRIVCFG_PRIV, +}; + +struct arm_smmu_smr { + uint16_t mask; + uint16_t id; + uint32_t valid; +}; + +struct arm_smmu_s2cr { + int count; + enum arm_smmu_s2cr_type type; + enum arm_smmu_s2cr_privcfg privcfg; + uint8_t cbndx; +}; + +struct arm_smmu_cfg { + uint8_t cbndx; + uint8_t irptndx; + uint32_t cbar; +}; + +struct arm_smmu_device { + uint8_t *base; + uint32_t streams; + unsigned long size; + unsigned long pgshift; + unsigned long va_size; + unsigned long ipa_size; + unsigned long pa_size; + struct arm_smmu_smr smr[NUM_OF_SMRS]; + struct arm_smmu_s2cr s2cr[NUM_OF_SMRS]; + struct arm_smmu_cfg cfg[NUM_OF_SMRS]; + uint16_t *stream_ids; + uint16_t *stream_ids_mask; +}; + +void arm_smmu_enable_secure_client_port(void) +{ + uintptr_t smmu_base = SMMU_BASE; + + mmio_clrbits_32(smmu_base, sCR0_CLIENTPD); +} + +void arm_smmu_reserve_secure_cntxt(void) +{ + uintptr_t smmu_base = SMMU_BASE; + + mmio_clrsetbits_32(smmu_base + ARM_SMMU_SMMU_SCR1, + (SCR1_NSNUMSMRGO_MASK | SCR1_NSNUMCBO_MASK), + ((ARM_SMMU_NSNUMCBO << SCR1_NSNUMCBO_SHIFT) | + (ARM_SMMU_NSNUMSMRGO << SCR1_NSNUMSMRGO_SHIFT))); +} + +static void arm_smmu_smr_cfg(struct arm_smmu_device *smmu, uint32_t index) +{ + uint32_t idx = smmu->cfg[index].cbndx; + struct arm_smmu_smr *smr = &smmu->smr[index]; + uint32_t reg = smr->id << SMR_ID_SHIFT | smr->mask << SMR_MASK_SHIFT; + + if (smr->valid) + reg |= SMR_VALID; + + mmio_write_32((uintptr_t) (ARM_SMMU_GR0(smmu) + + ARM_SMMU_GR0_SMR(idx)), reg); +} + +static void arm_smmu_s2cr_cfg(struct arm_smmu_device *smmu, uint32_t index) +{ + uint32_t idx = smmu->cfg[index].cbndx; + struct arm_smmu_s2cr *s2cr = &smmu->s2cr[index]; + + uint32_t reg = (s2cr->type & S2CR_TYPE_MASK) << S2CR_TYPE_SHIFT | + (s2cr->cbndx & S2CR_CBNDX_MASK) << S2CR_CBNDX_SHIFT | + (s2cr->privcfg & S2CR_PRIVCFG_MASK) << S2CR_PRIVCFG_SHIFT; + + mmio_write_32((uintptr_t) (ARM_SMMU_GR0(smmu) + + ARM_SMMU_GR0_S2CR(idx)), reg); +} + +static void smmu_set_pgtbl(struct arm_smmu_device *smmu, + enum iommu_domain dom, + uint64_t *pg_table_base) +{ + int i, l0_index, l1_index; + uint64_t addr, *pte, *l0_base, *l1_base; + uint64_t addr_space_limit; + + if (dom == PCIE_PAXC) { + addr_space_limit = 0xffffffffff; + } else if (dom == DOMAIN_CRMU) { + addr_space_limit = 0xffffffff; + } else { + ERROR("dom is not supported\n"); + return; + } + + l0_base = pg_table_base; + /* clear L0 descriptors. */ + for (i = 0; i < ARM_LPAE_PGTBL_PTE_CNT; i++) + l0_base[i] = 0x0; + + addr = 0x0; + while (addr < addr_space_limit) { + /* find L0 pte */ + l0_index = ((addr >> ARM_LPAE_PTE_L0_INDEX_SHIFT) & + ARM_LPAE_PTE_L0_INDEX_MASK); + l1_base = l0_base + ((l0_index + 1) * ARM_LPAE_PGTBL_PTE_CNT); + + /* setup L0 pte if required */ + pte = l0_base + l0_index; + if (*pte == 0x0) { + *pte |= ((uint64_t)l1_base & ARM_LPAE_PTE_TABLE_MASK); + if (dom == PCIE_PAXC) + *pte |= ARM_LPAE_PTE_NSTABLE; + *pte |= ARM_LPAE_PTE_TABLE; + *pte |= ARM_LPAE_PTE_VALID; + } + + /* find L1 pte */ + l1_index = ((addr >> ARM_LPAE_PTE_L1_INDEX_SHIFT) & + ARM_LPAE_PTE_L1_INDEX_MASK); + pte = l1_base + l1_index; + + /* setup L1 pte */ + *pte = 0x0; + *pte |= (addr & ARM_LPAE_PTE_L1_ADDR_MASK); + if (addr < 0x80000000) { + *pte |= (ARM_LPAE_MAIR_ATTR_IDX_DEV << + ARM_LPAE_PTE_ATTRINDX); + if (dom == PCIE_PAXC) + *pte |= (1 << ARM_LPAE_PTE_NS); + } else { + *pte |= (ARM_LPAE_MAIR_ATTR_IDX_CACHE << + ARM_LPAE_PTE_ATTRINDX); + *pte |= (1 << ARM_LPAE_PTE_NS); + } + *pte |= (ARM_LPAE_PTE_AP_EL0_RW << ARM_LPAE_PTE_AP); + *pte |= (ARM_LPAE_PTE_SH_INNER << ARM_LPAE_PTE_SH); + *pte |= (1 << ARM_LPAE_PTE_AF); + *pte |= ARM_LPAE_PTE_VALID; + + addr += ARM_LPAE_PTE_L1_BLOCK_SIZE; + } +} + +void arm_smmu_create_identity_map(enum iommu_domain dom) +{ + struct arm_smmu_device iommu; + struct arm_smmu_device *smmu = &iommu; + uint32_t reg, reg2; + unsigned long long reg64; + uint32_t idx; + uint16_t asid; + unsigned int context_bank_index; + unsigned long long pg_table_base; + + smmu->base = (uint8_t *) SMMU_BASE; + reg = mmio_read_32((uintptr_t) (ARM_SMMU_GR0(smmu) + ARM_SMMU_GR0_ID1)); + smmu->pgshift = (reg & ID1_PAGESIZE) ? 16 : 12; + smmu->size = ARM_SMMU_RES_SIZE; + smmu->stream_ids = NULL; + + switch (dom) { + case PCIE_PAXC: + smmu->stream_ids = &paxc_stream_ids[0]; + smmu->stream_ids_mask = &paxc_stream_ids_mask[0]; + smmu->streams = ARRAY_SIZE(paxc_stream_ids); + context_bank_index = SMMU_CTX_BANK_IDX; + pg_table_base = ARM_LPAE_PGTBL_PHYS; + break; + case DOMAIN_CRMU: + smmu->stream_ids = &crmu_stream_ids[0]; + smmu->stream_ids_mask = &crmu_stream_ids_mask[0]; + smmu->streams = ARRAY_SIZE(crmu_stream_ids); + context_bank_index = SMMU_CTX_BANK_IDX_SECURE_CRMU; + pg_table_base = ARM_LPAE_PGTBL_PHYS_CRMU; + break; + default: + ERROR("domain not supported\n"); + return; + } + + if (smmu->streams > NUM_OF_SMRS) { + INFO("can not support more than %d sids\n", NUM_OF_SMRS); + return; + } + + /* set up iommu dev. */ + for (idx = 0; idx < smmu->streams; idx++) { + /* S2CR. */ + smmu->s2cr[idx].type = S2CR_TYPE_TRANS; + smmu->s2cr[idx].privcfg = S2CR_PRIVCFG_DEFAULT; + smmu->s2cr[idx].cbndx = context_bank_index; + smmu->cfg[idx].cbndx = context_bank_index; + smmu->cfg[idx].cbar = STG1_WITH_STG2_BYPASS << CBAR_TYPE_SHIFT; + arm_smmu_s2cr_cfg(smmu, idx); + + /* SMR. */ + smmu->smr[idx].mask = smmu->stream_ids_mask[idx]; + smmu->smr[idx].id = smmu->stream_ids[idx]; + smmu->smr[idx].valid = 1; + arm_smmu_smr_cfg(smmu, idx); + + /* CBA2R. 64-bit Translation */ + mmio_write_32((uintptr_t) (ARM_SMMU_GR1(smmu) + + ARM_SMMU_GR1_CBA2R(smmu->cfg[idx].cbndx)), + 0x1); + /* CBAR.*/ + reg = smmu->cfg[idx].cbar; + reg |= (CBAR_S1_BPSHCFG_NSH << CBAR_S1_BPSHCFG_SHIFT) | + (CBAR_S1_MEMATTR_WB << CBAR_S1_MEMATTR_SHIFT); + + mmio_write_32((uintptr_t) (ARM_SMMU_GR1(smmu) + + ARM_SMMU_GR1_CBAR(smmu->cfg[idx].cbndx)), + reg); + + /* TTBCR. */ + reg64 = (ARM_LPAE_TCR_SH_IS << ARM_LPAE_TCR_SH0_SHIFT) | + (ARM_LPAE_TCR_RGN_WBWA << ARM_LPAE_TCR_IRGN0_SHIFT) | + (ARM_LPAE_TCR_RGN_WBWA << ARM_LPAE_TCR_ORGN0_SHIFT); + reg64 |= ARM_LPAE_TCR_TG0_4K; + reg64 |= (ARM_LPAE_TCR_PS_40_BIT << ARM_LPAE_TCR_IPS_SHIFT); + /* ias 40 bits.*/ + reg64 |= TTBCR_T0SZ(40) << ARM_LPAE_TCR_T0SZ_SHIFT; + /* Disable speculative walks through TTBR1 */ + reg64 |= ARM_LPAE_TCR_EPD1; + reg = (uint32_t) reg64; + reg2 = (uint32_t) (reg64 >> 32); + reg2 |= TTBCR2_SEP_UPSTREAM; + reg2 |= TTBCR2_AS; + + mmio_write_32((uintptr_t) (ARM_SMMU_CB_BASE(smmu) + + ARM_SMMU_CB(smmu, smmu->cfg[idx].cbndx) + + ARM_SMMU_CB_TTBCR2), reg2); + + mmio_write_32((uintptr_t) (ARM_SMMU_CB_BASE(smmu) + + ARM_SMMU_CB(smmu, smmu->cfg[idx].cbndx) + + ARM_SMMU_CB_TTBCR), reg); + + /* TTBR0. */ + asid = smmu->cfg[idx].cbndx; + reg64 = pg_table_base; + reg64 |= (unsigned long long) asid << TTBRn_ASID_SHIFT; + + mmio_write_64((uintptr_t) (ARM_SMMU_CB_BASE(smmu) + + ARM_SMMU_CB(smmu, smmu->cfg[idx].cbndx) + + ARM_SMMU_CB_TTBR0), reg64); + /* TTBR1. */ + reg64 = 0; + reg64 |= (unsigned long long) asid << TTBRn_ASID_SHIFT; + + mmio_write_64((uintptr_t) (ARM_SMMU_CB_BASE(smmu) + + ARM_SMMU_CB(smmu, smmu->cfg[idx].cbndx) + + ARM_SMMU_CB_TTBR1), reg64); + /* MAIR. */ + reg = (ARM_LPAE_MAIR_ATTR_NC + << ARM_LPAE_MAIR_ATTR_SHIFT + (ARM_LPAE_MAIR_ATTR_IDX_NC)) | + (ARM_LPAE_MAIR_ATTR_WBRWA << + ARM_LPAE_MAIR_ATTR_SHIFT + (ARM_LPAE_MAIR_ATTR_IDX_CACHE)) | + (ARM_LPAE_MAIR_ATTR_DEVICE << + ARM_LPAE_MAIR_ATTR_SHIFT + (ARM_LPAE_MAIR_ATTR_IDX_DEV)); + + mmio_write_32((uintptr_t) (ARM_SMMU_CB_BASE(smmu) + + ARM_SMMU_CB(smmu, smmu->cfg[idx].cbndx) + + ARM_SMMU_CB_S1_MAIR0), reg); + + /* MAIR1. */ + reg = 0; + mmio_write_32((uintptr_t) (ARM_SMMU_CB_BASE(smmu) + + ARM_SMMU_CB(smmu, smmu->cfg[idx].cbndx) + + ARM_SMMU_CB_S1_MAIR1), reg); + /* SCTLR. */ + reg = SCTLR_CFIE | SCTLR_CFRE | SCTLR_AFE | SCTLR_TRE | SCTLR_M; + /* stage 1.*/ + reg |= SCTLR_S1_ASIDPNE; + mmio_write_32((uintptr_t) (ARM_SMMU_CB_BASE(smmu) + + ARM_SMMU_CB(smmu, smmu->cfg[idx].cbndx) + + ARM_SMMU_CB_SCTLR), reg); + } + smmu_set_pgtbl(smmu, dom, (uint64_t *)pg_table_base); +} diff --git a/plat/brcm/board/stingray/src/ncsi.c b/plat/brcm/board/stingray/src/ncsi.c new file mode 100644 index 000000000..58ea9e2d6 --- /dev/null +++ b/plat/brcm/board/stingray/src/ncsi.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2019-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include + +#include +#include +#include + +static const char *const io_drives[] = { + "2mA", "4mA", "6mA", "8mA", + "10mA", "12mA", "14mA", "16mA" +}; + +void brcm_stingray_ncsi_init(void) +{ + unsigned int i = 0; + unsigned int selx = 0; + +#if NCSI_IO_DRIVE_STRENGTH_MA == 2 + selx = 0x0; +#elif NCSI_IO_DRIVE_STRENGTH_MA == 4 + selx = 0x1; +#elif NCSI_IO_DRIVE_STRENGTH_MA == 6 + selx = 0x2; +#elif NCSI_IO_DRIVE_STRENGTH_MA == 8 + selx = 0x3; +#elif NCSI_IO_DRIVE_STRENGTH_MA == 10 + selx = 0x4; +#elif NCSI_IO_DRIVE_STRENGTH_MA == 12 + selx = 0x5; +#elif NCSI_IO_DRIVE_STRENGTH_MA == 14 + selx = 0x6; +#elif NCSI_IO_DRIVE_STRENGTH_MA == 16 + selx = 0x7; +#else + ERROR("Unsupported NCSI_IO_DRIVE_STRENGTH_MA. Please check it.\n"); + return; +#endif + INFO("ncsi io drives: %s\n", io_drives[selx]); + + for (i = 0; i < NITRO_NCSI_IOPAD_CONTROL_NUM; i++) { + mmio_clrsetbits_32((NITRO_NCSI_IOPAD_CONTROL_BASE + (i * 4)), + PAD_SELX_MASK, PAD_SELX_VALUE(selx)); + } + + INFO("ncsi init done\n"); +} diff --git a/plat/brcm/board/stingray/src/paxb.c b/plat/brcm/board/stingray/src/paxb.c new file mode 100644 index 000000000..28065f07a --- /dev/null +++ b/plat/brcm/board/stingray/src/paxb.c @@ -0,0 +1,911 @@ +/* + * Copyright (c) 2016 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#define PCIE_CORE_PWR_ARR_POWERON 0x8 +#define PCIE_CORE_PWR_ARR_POWEROK 0x4 +#define PCIE_CORE_PWR_POWERON 0x2 +#define PCIE_CORE_PWR_POWEROK 0x1 + +#define PCIE_CORE_USER_CFG (PCIE_CORE_BASE + 0x38) +#define PCIE_PAXB_SMMU_SID_CFG (PCIE_CORE_BASE + 0x60) +#ifdef SID_B8_D1_F1 +#define PAXB_SMMU_SID_CFG_BUS_WIDTH (0x8 << 8) +#define PAXB_SMMU_SID_CFG_DEV_WIDTH (0x1 << 12) +#define PAXB_SMMU_SID_CFG_FUN_WIDTH (0x1 << 16) +#else +#define PAXB_SMMU_SID_CFG_BUS_WIDTH (0x2 << 8) +#define PAXB_SMMU_SID_CFG_DEV_WIDTH (0x5 << 12) +#define PAXB_SMMU_SID_CFG_FUN_WIDTH (0x3 << 16) +#endif + +#define PAXB_APB_TIMEOUT_COUNT_OFFSET 0x034 + +/* allow up to 5 ms for each power switch to stabilize */ +#define PCIE_CORE_PWR_TIMEOUT_MS 5 + +/* wait 1 microsecond for PCIe core soft reset */ +#define PCIE_CORE_SOFT_RST_DELAY_US 1 + +/* + * List of PAXB APB registers + */ +#define PAXB_BASE 0x48000000 +#define PAXB_BASE_OFFSET 0x4000 +#define PAXB_OFFSET(core) (PAXB_BASE + \ + (core) * PAXB_BASE_OFFSET) + +#define PAXB_CLK_CTRL_OFFSET 0x000 +#define PAXB_EP_PERST_SRC_SEL_MASK (1 << 2) +#define PAXB_EP_MODE_PERST_MASK (1 << 1) +#define PAXB_RC_PCIE_RST_OUT_MASK (1 << 0) + +#define PAXB_MAX_IMAP_WINDOWS 8 +#define PAXB_IMAP_REG_WIDTH 8 +#define PAXB_IMAP0_REG_WIDTH 4 +#define PAXB_AXUSER_REG_WIDTH 4 + +#define PAXB_CFG_IND_ADDR_OFFSET 0x120 +#define PAXB_CFG_IND_DATA_OFFSET 0x124 +#define PAXB_CFG_IND_ADDR_MASK 0x1ffc +#define PAXB_CFG_CFG_TYPE_MASK 0x1 + +#define PAXB_EP_CFG_ADDR_OFFSET 0x1f8 +#define PAXB_EP_CFG_DATA_OFFSET 0x1fc +#define PAXB_EP_CFG_ADDR_MASK 0xffc +#define PAXB_EP_CFG_TYPE_MASK 0x1 + +#define PAXB_0_DEFAULT_IMAP 0xed0 +#define DEFAULT_ADDR_INVALID BIT(0) +#define PAXB_0_DEFAULT_IMAP_AXUSER 0xed8 +#define PAXB_0_DEFAULT_IMAP_AXCACHE 0xedc +#define IMAP_AXCACHE 0xff +#define OARR_VALID BIT(0) +#define IMAP_VALID BIT(0) + +#define PAXB_IMAP0_BASE_OFFSET 0xc00 +#define PAXB_IARR0_BASE_OFFSET 0xd00 +#define PAXB_IMAP0_OFFSET(idx) (PAXB_IMAP0_BASE_OFFSET + \ + (idx) * PAXB_IMAP0_REG_WIDTH) +#define PAXB_IMAP0_WINDOW_SIZE 0x1000 + +#define PAXB_IMAP2_OFFSET 0xcc0 +#define PAXB_IMAP0_REGS_TYPE_OFFSET 0xcd0 +#define PAXB_IARR2_LOWER_OFFSET 0xd10 + +#define PAXB_IMAP3_BASE_OFFSET 0xe08 +#define PAXB_IMAP3_OFFSET(idx) (PAXB_IMAP3_BASE_OFFSET + \ + (idx) * PAXB_IMAP_REG_WIDTH) + +#define PAXB_IMAP3_0_AXUSER_B_OFFSET 0xe48 +#define PAXB_IMAP3_0_AXUSER_OFFSET(idx) (PAXB_IMAP3_0_AXUSER_B_OFFSET + \ + (idx) * PAXB_AXUSER_REG_WIDTH) + +#define PAXB_IMAP4_BASE_OFFSET 0xe70 +#define PAXB_IMAP4_OFFSET(idx) (PAXB_IMAP4_BASE_OFFSET + \ + (idx) * PAXB_IMAP_REG_WIDTH) + +#define PAXB_IMAP4_0_AXUSER_B_OFFSET 0xeb0 +#define PAXB_IMAP4_0_AXUSER_OFFSET(idx) (PAXB_IMAP4_0_AXUSER_B_OFFSET + \ + (idx) * PAXB_AXUSER_REG_WIDTH) + +#define PAXB_CFG_LINK_STATUS_OFFSET 0xf0c +#define PAXB_CFG_PHYLINKUP_MASK (1 << 3) +#define PAXB_CFG_DL_ACTIVE_MASK (1 << 2) + +#define PAXB_IMAP0_0_AXUSER_OFFSET 0xf60 +#define PAXB_IMAP2_AXUSER_OFFSET 0xfe0 + +/* cacheable write-back, allocate on both reads and writes */ +#define IMAP_ARCACHE 0x0f0 +#define IMAP_AWCACHE 0xf00 +/* normal access, nonsecure access, and data access */ +/* AWQOS:0xe and ARQOS:0xa */ +/* AWPROT:0x2 and ARPROT:0x1 */ +#define IMAP_AXUSER 0x002e002a + +/* + * List of NIC security and PIPEMUX related registers + */ +#define SR_PCIE_NIC_SECURITY_BASE 0x58100000 +#define NS3Z_PCIE_NIC_SECURITY_BASE 0x48100000 + +#define GITS_TRANSLATER 0x63c30000 + +#define VENDOR_ID 0x14e4 +#define CFG_RC_DEV_ID 0x434 +#define CFG_RC_DEV_SUBID 0x438 +#define PCI_BRIDGE_CTRL_REG_OFFSET 0x43c +#define PCI_CLASS_BRIDGE_MASK 0xffff00 +#define PCI_CLASS_BRIDGE_SHIFT 8 +#define PCI_CLASS_BRIDGE_PCI 0x0604 + +/* + * List of PAXB RC configuration space registers + */ + +/* first capability list entry */ +#define PCI_CAPABILITY_LIST_OFFSET 0x34 +#define PCI_CAPABILITY_SPEED_OFFSET 0xc +#define PCI_EP_CAPABILITY_OFFSET 0x10 + +#define CFG_RC_LINK_STATUS_CTRL_2 0x0dc +#define CFG_RC_LINK_SPEED_SHIFT 0 +#define CFG_RC_LINK_SPEED_MASK (0xf << CFG_RC_LINK_SPEED_SHIFT) + +#define CFG_RC_DEVICE_CAP 0x4d4 +#define CFG_RC_DEVICE_CAP_MPS_SHIFT 0 +#define CFG_RC_DEVICE_CAP_MPS_MASK (0x7 << CFG_RC_DEVICE_CAP_MPS_SHIFT) +/* MPS 256 bytes */ +#define CFG_RC_DEVICE_CAP_MPS_256B (0x1 << CFG_RC_DEVICE_CAP_MPS_SHIFT) +/* MPS 512 bytes */ +#define CFG_RC_DEVICE_CAP_MPS_512B (0x2 << CFG_RC_DEVICE_CAP_MPS_SHIFT) + +#define CFG_RC_TL_FCIMM_NP_LIMIT 0xa10 +#define CFG_RC_TL_FCIMM_NP_VAL 0x01500000 +#define CFG_RC_TL_FCIMM_P_LIMIT 0xa14 +#define CFG_RC_TL_FCIMM_P_VAL 0x03408080 + +#define CFG_RC_LINK_CAP 0x4dc +#define CFG_RC_LINK_CAP_SPEED_SHIFT 0 +#define CFG_RC_LINK_CAP_SPEED_MASK (0xf << CFG_RC_LINK_CAP_SPEED_SHIFT) +#define CFG_RC_LINK_CAP_WIDTH_SHIFT 4 +#define CFG_RC_LINK_CAP_WIDTH_MASK (0x1f << CFG_RC_LINK_CAP_WIDTH_SHIFT) + +#define CFG_LINK_CAP_RC 0x4f0 +#define CFG_RC_DL_ACTIVE_SHIFT 0 +#define CFG_RC_DL_ACTIVE_MASK (0x1 << CFG_RC_DL_ACTIVE_SHIFT) +#define CFG_RC_SLOT_CLK_SHIFT 1 +#define CFG_RC_SLOT_CLK_MASK (0x1 << CFG_RC_SLOT_CLK_SHIFT) + +#define CFG_ROOT_CAP_RC 0x4f8 +#define CFG_ROOT_CAP_LTR_SHIFT 1 +#define CFG_ROOT_CAP_LTR_MASK (0x1 << CFG_ROOT_CAP_LTR_SHIFT) + +#define CFG_RC_CLKREQ_ENABLED 0x4fc +#define CFG_RC_CLKREQ_ENABLED_SHIFT 0 +#define CFG_RC_CLKREQ_ENABLED_MASK (0x1 << CFG_RC_CLKREQ_ENABLED_SHIFT) + +#define CFG_RC_COEFF_ADDR 0x638 + +#define CFG_RC_TL_CTRL_0 0x800 +#define RC_MEM_DW_CHK_MASK 0x03fe + +#define CFG_RC_PDL_CTRL_4 0x1010 +#define NPH_FC_INIT_SHIFT 24 +#define NPH_FC_INIT_MASK (U(0xff) << NPH_FC_INIT_SHIFT) +#define PD_FC_INIT_SHIFT 12 +#define PD_FC_INIT_MASK (0xffff << PD_FC_INIT_SHIFT) + +#define CFG_RC_PDL_CTRL_5 0x1014 +#define PH_INIT_SHIFT 0 +#define PH_INIT_MASK (0xff << PH_INIT_SHIFT) + +#define DL_STATUS_OFFSET 0x1048 +#define PHYLINKUP BIT(13) + +#define PH_INIT 0x10 +#define PD_FC_INIT 0x100 +#define NPH_FC_INIT 0x8 + +#define SRP_PH_INIT 0x7F +#define SRP_PD_FC_INIT 0x200 +#define SRP_NPH_FC_INIT 0x7F + +#define CFG_ADDR_BUS_NUM_SHIFT 20 +#define CFG_ADDR_DEV_NUM_SHIFT 15 +#define CFG_ADDR_FUNC_NUM_SHIFT 12 +#define CFG_ADDR_REG_NUM_SHIFT 2 +#define CFG_ADDR_REG_NUM_MASK 0x00000ffc +#define CFG_ADDR_CFG_TYPE_MASK 0x00000003 + +#define DL_LINK_UP_TIMEOUT_MS 1000 + +#define CFG_RETRY_STATUS 0xffff0001 +#define CRS_TIMEOUT_MS 5000 + +/* create EP config data to write */ +#define DEF_BUS_NO 1 /* default bus 1 */ +#define DEF_SLOT_NO 0 /* default slot 0 */ +#define DEF_FN_NO 0 /* default fn 0 */ + +#define EP_CONFIG_VAL(bus_no, slot, fn, where) \ + (((bus_no) << CFG_ADDR_BUS_NUM_SHIFT) | \ + ((slot) << CFG_ADDR_DEV_NUM_SHIFT) | \ + ((fn) << CFG_ADDR_FUNC_NUM_SHIFT) | \ + ((where) & CFG_ADDR_REG_NUM_MASK) | \ + (1 & CFG_ADDR_CFG_TYPE_MASK)) + +/* PAXB security offset */ +#define PAXB_SECURITY_IDM_OFFSET 0x1c +#define PAXB_SECURITY_APB_OFFSET 0x24 +#define PAXB_SECURITY_ECAM_OFFSET 0x3c + +#define paxb_get_config(type) paxb_get_##type##_config() + +static unsigned int paxb_sec_reg_offset[] = { + 0x0c, /* PAXB0 AXI */ + 0x10, /* PAXB1 AXI */ + 0x14, /* PAXB2 AXI */ + 0x18, /* PAXB3 AXI */ + 0x20, /* PAXB4 AXI */ + 0x28, /* PAXB5 AXI */ + 0x2c, /* PAXB6 AXI */ + 0x30, /* PAXB7 AXI */ + 0x24, /* PAXB APB */ +}; + +const paxb_cfg *paxb; + +/* + * Given a PIPEMUX strap and PCIe core index, this function returns 1 if a + * PCIe core needs to be enabled + */ +int pcie_core_needs_enable(unsigned int core_idx) +{ + if (paxb->core_needs_enable) + return paxb->core_needs_enable(core_idx); + + return 0; +} + +static void pcie_set_default_tx_coeff(uint32_t core_idx, uint32_t link_width) +{ + unsigned int lanes = 0; + uint32_t data, addr; + + addr = CFG_RC_COEFF_ADDR; + for (lanes = 0; lanes < link_width; lanes = lanes + 2) { + data = paxb_rc_cfg_read(core_idx, addr); + data &= 0xf0f0f0f0; + data |= (7 & 0xf); + data |= (7 & 0xf) << 8; + data |= (7 & 0xf) << 16; + data |= (7 & 0xf) << 24; + + paxb_rc_cfg_write(core_idx, addr, data); + addr += 4; + } +} + +static int paxb_rc_link_init(void) +{ + uint32_t val, link_speed; + unsigned int link_width; + uint32_t core_idx; + + for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) { + if (!pcie_core_needs_enable(core_idx)) + continue; + + link_width = paxb->get_link_width(core_idx); + if (!link_width) { + ERROR("Unsupported PIPEMUX\n"); + return -EOPNOTSUPP; + } + + link_speed = paxb->get_link_speed(); + /* program RC's link cap reg to advertise proper link width */ + val = paxb_rc_cfg_read(core_idx, CFG_RC_LINK_CAP); + val &= ~CFG_RC_LINK_CAP_WIDTH_MASK; + val |= (link_width << CFG_RC_LINK_CAP_WIDTH_SHIFT); + paxb_rc_cfg_write(core_idx, CFG_RC_LINK_CAP, val); + + /* program RC's link cap reg to advertise proper link speed */ + val = paxb_rc_cfg_read(core_idx, CFG_RC_LINK_CAP); + val &= ~CFG_RC_LINK_CAP_SPEED_MASK; + val |= link_speed << CFG_RC_LINK_CAP_SPEED_SHIFT; + paxb_rc_cfg_write(core_idx, CFG_RC_LINK_CAP, val); + + /* also need to program RC's link status control register */ + val = paxb_rc_cfg_read(core_idx, CFG_RC_LINK_STATUS_CTRL_2); + val &= ~(CFG_RC_LINK_SPEED_MASK); + val |= link_speed << CFG_RC_LINK_SPEED_SHIFT; + paxb_rc_cfg_write(core_idx, CFG_RC_LINK_STATUS_CTRL_2, val); + +#ifdef WAR_PLX_PRESET_PARITY_FAIL + /* WAR to avoid crash with PLX switch in GEN3*/ + /* While PRESET, PLX switch is not fixing parity so disabled */ + val = paxb_rc_cfg_read(core_idx, CFG_RC_REG_PHY_CTL_10); + val &= ~(PHY_CTL_10_GEN3_MATCH_PARITY); + paxb_rc_cfg_write(core_idx, CFG_RC_REG_PHY_CTL_10, val); +#endif + pcie_set_default_tx_coeff(core_idx, link_width); + } + return 0; +} + +#ifdef PAXB_LINKUP +static void paxb_perst_ctrl(unsigned int core_idx, bool assert) +{ + uint32_t clk_ctrl = PAXB_OFFSET(core_idx) + PAXB_CLK_CTRL_OFFSET; + + if (assert) { + mmio_clrbits_32(clk_ctrl, PAXB_EP_PERST_SRC_SEL_MASK | + PAXB_EP_MODE_PERST_MASK | + PAXB_RC_PCIE_RST_OUT_MASK); + udelay(250); + } else { + mmio_setbits_32(clk_ctrl, PAXB_RC_PCIE_RST_OUT_MASK); + mdelay(100); + } +} + +static void paxb_start_link_up(void) +{ + unsigned int core_idx; + uint32_t val, timeout; + + for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) { + if (!pcie_core_needs_enable(core_idx)) + continue; + + /* toggle PERST */ + paxb_perst_ctrl(core_idx, true); + paxb_perst_ctrl(core_idx, false); + + timeout = DL_LINK_UP_TIMEOUT_MS; + /* wait for Link up */ + do { + val = mmio_read_32(PAXB_OFFSET(core_idx) + + PAXB_CFG_LINK_STATUS_OFFSET); + if (val & PAXB_CFG_DL_ACTIVE_MASK) + break; + + mdelay(1); + } while (--timeout); + + if (!timeout) + ERROR("PAXB core %u link is down\n", core_idx); + } +} +#endif + +static void pcie_core_soft_reset(unsigned int core_idx) +{ + uint32_t offset = core_idx * PCIE_CORE_PWR_OFFSET; + uintptr_t ctrl = (uintptr_t)(PCIE_CORE_SOFT_RST_CFG_BASE + offset); + + /* Put PCIe core in soft reset */ + mmio_clrbits_32(ctrl, PCIE_CORE_SOFT_RST); + + /* Wait for 1 us before pulling PCIe core out of soft reset */ + udelay(PCIE_CORE_SOFT_RST_DELAY_US); + + mmio_setbits_32(ctrl, PCIE_CORE_SOFT_RST); +} + +static int pcie_core_pwron_switch(uintptr_t ctrl, uintptr_t status, + uint32_t mask) +{ + uint32_t val; + unsigned int timeout = PCIE_CORE_PWR_TIMEOUT_MS; + + /* enable switch */ + mmio_setbits_32(ctrl, mask); + + /* now wait for it to stabilize */ + do { + val = mmio_read_32(status); + if ((val & mask) == mask) + return 0; + mdelay(1); + } while (--timeout); + + return -EIO; +} + +static int pcie_core_pwr_seq(uintptr_t ctrl, uintptr_t status) +{ + int ret; + + /* + * Enable the switch with the following sequence: + * 1. Array weak switch output switch + * 2. Array strong switch + * 3. Weak switch output acknowledge + * 4. Strong switch output acknowledge + */ + ret = pcie_core_pwron_switch(ctrl, status, PCIE_CORE_PWR_ARR_POWERON); + if (ret) + return ret; + + ret = pcie_core_pwron_switch(ctrl, status, PCIE_CORE_PWR_ARR_POWEROK); + if (ret) + return ret; + + ret = pcie_core_pwron_switch(ctrl, status, PCIE_CORE_PWR_POWERON); + if (ret) + return ret; + + ret = pcie_core_pwron_switch(ctrl, status, PCIE_CORE_PWR_POWEROK); + if (ret) + return ret; + + return 0; +} + +/* + * This function enables PCIe core and PAXB memory buffer power, and then + * remove the PCIe core from isolation + */ +static int pcie_core_pwr_init(unsigned int core_idx) +{ + int ret; + uint32_t offset = core_idx * PCIE_CORE_PWR_OFFSET; + uintptr_t ctrl, status; + + /* enable mem power to PCIe core */ + ctrl = (uintptr_t)(PCIE_CORE_MEM_PWR_BASE + offset); + status = (uintptr_t)(PCIE_CORE_MEM_PWR_STATUS_BASE + offset); + ret = pcie_core_pwr_seq(ctrl, status); + if (ret) { + ERROR("PCIe core mem power failed\n"); + return ret; + } + + /* now enable mem power to PAXB wrapper */ + ctrl = (uintptr_t)(PCIE_PAXB_MEM_PWR_BASE + offset); + status = (uintptr_t)(PCIE_PAXB_MEM_PWR_STATUS_BASE + offset); + ret = pcie_core_pwr_seq(ctrl, status); + if (ret) { + ERROR("PAXB mem power failed\n"); + return ret; + } + + /* now remove power isolation */ + ctrl = (uintptr_t)(PCIE_CORE_ISO_CFG_BASE + offset); + mmio_clrbits_32(ctrl, PCIE_CORE_ISO | PCIE_CORE_MEM_ISO); + + return 0; +} + +static void pcie_ss_reset(void) +{ + mmio_setbits_32(CDRU_MISC_RESET_CONTROL, + 1 << CDRU_MISC_RESET_CONTROL__CDRU_PCIE_RESET_N_R); +} + +/* + * This function reads the PIPEMUX strap, figures out all the PCIe cores that + * need to be enabled and enable the mem power for those cores + */ +static int pcie_cores_init(void) +{ + int ret; + uint32_t core_idx; + + if (paxb->pipemux_init) { + ret = paxb->pipemux_init(); + if (ret) + return ret; + } + + /* bring PCIe subsystem out of reset */ + pcie_ss_reset(); + + /* power up all PCIe cores that will be used as RC */ + for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) { + if (!pcie_core_needs_enable(core_idx)) + continue; + + ret = pcie_core_pwr_init(core_idx); + if (ret) { + ERROR("PCIe core %u power up failed\n", core_idx); + return ret; + } + + pcie_core_soft_reset(core_idx); + + VERBOSE("PCIe core %u is powered up\n", core_idx); + } + + return ret; +} + +void paxb_rc_cfg_write(unsigned int core_idx, unsigned int where, + uint32_t val) +{ + mmio_write_32(PAXB_OFFSET(core_idx) + PAXB_CFG_IND_ADDR_OFFSET, + (where & PAXB_CFG_IND_ADDR_MASK) | + PAXB_CFG_CFG_TYPE_MASK); + mmio_write_32(PAXB_OFFSET(core_idx) + PAXB_CFG_IND_DATA_OFFSET, val); +} + +unsigned int paxb_rc_cfg_read(unsigned int core_idx, unsigned int where) +{ + unsigned int val; + + mmio_write_32(PAXB_OFFSET(core_idx) + PAXB_CFG_IND_ADDR_OFFSET, + (where & PAXB_CFG_IND_ADDR_MASK) | + PAXB_CFG_CFG_TYPE_MASK); + val = mmio_read_32(PAXB_OFFSET(core_idx) + PAXB_CFG_IND_DATA_OFFSET); + + return val; +} + +static void paxb_cfg_mps(void) +{ + uint32_t val, core_idx, mps; + + for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) { + if (!pcie_core_needs_enable(core_idx)) + continue; + + val = paxb_rc_cfg_read(core_idx, CFG_RC_DEVICE_CAP); + val &= ~CFG_RC_DEVICE_CAP_MPS_MASK; + mps = CFG_RC_DEVICE_CAP_MPS_256B; + if (core_idx == 0 || core_idx == 1 || + core_idx == 6 || core_idx == 7) { + mps = CFG_RC_DEVICE_CAP_MPS_512B; + } + val |= mps; + paxb_rc_cfg_write(core_idx, CFG_RC_DEVICE_CAP, val); + } +} + +static void paxb_cfg_dev_id(void) +{ + uint32_t val, core_idx; + uint32_t device_id; + + device_id = paxb->device_id; + + for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) { + if (!pcie_core_needs_enable(core_idx)) + continue; + + /* Set Core in RC mode */ + mmio_setbits_32(PCIE_CORE_USER_CFG + + (core_idx * PCIE_CORE_PWR_OFFSET), 1); + + /* force class to PCI_CLASS_BRIDGE_PCI (0x0604) */ + val = paxb_rc_cfg_read(core_idx, PCI_BRIDGE_CTRL_REG_OFFSET); + val &= ~PCI_CLASS_BRIDGE_MASK; + val |= (PCI_CLASS_BRIDGE_PCI << PCI_CLASS_BRIDGE_SHIFT); + paxb_rc_cfg_write(core_idx, PCI_BRIDGE_CTRL_REG_OFFSET, val); + + val = (VENDOR_ID << 16) | device_id; + paxb_rc_cfg_write(core_idx, CFG_RC_DEV_ID, val); + + val = (device_id << 16) | VENDOR_ID; + paxb_rc_cfg_write(core_idx, CFG_RC_DEV_SUBID, val); + } +} + +static void paxb_cfg_tgt_trn(void) +{ + uint32_t val, core_idx; + + /* + * Disable all mem Rd/Wr size check so it allows target read/write + * transactions to be more than stipulated DW. As a result, PAXB root + * complex will not abort these read/write transcations beyond + * stipulated limit + */ + for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) { + if (!pcie_core_needs_enable(core_idx)) + continue; + + val = paxb_rc_cfg_read(core_idx, CFG_RC_TL_CTRL_0); + val &= ~(RC_MEM_DW_CHK_MASK); + paxb_rc_cfg_write(core_idx, CFG_RC_TL_CTRL_0, val); + } +} + +static void paxb_cfg_pdl_ctrl(void) +{ + uint32_t val, core_idx; + uint32_t nph, ph, pd; + + /* increase the credit counter to 4 for non-posted header */ + for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) { + if (!pcie_core_needs_enable(core_idx)) + continue; + + nph = NPH_FC_INIT; + ph = PH_INIT; + pd = PD_FC_INIT; + + if (core_idx == 0 || core_idx == 1 || + core_idx == 6 || core_idx == 7) { + nph = SRP_NPH_FC_INIT; + ph = SRP_PH_INIT; + pd = SRP_PD_FC_INIT; + } + val = paxb_rc_cfg_read(core_idx, CFG_RC_PDL_CTRL_4); + val &= ~NPH_FC_INIT_MASK; + val &= ~PD_FC_INIT_MASK; + val = val | (nph << NPH_FC_INIT_SHIFT); + val = val | (pd << PD_FC_INIT_SHIFT); + paxb_rc_cfg_write(core_idx, CFG_RC_PDL_CTRL_4, val); + + val = paxb_rc_cfg_read(core_idx, CFG_RC_PDL_CTRL_5); + val &= ~PH_INIT_MASK; + val = val | (ph << PH_INIT_SHIFT); + paxb_rc_cfg_write(core_idx, CFG_RC_PDL_CTRL_5, val); + + /* + * ASIC to give more optmized value after further investigation. + * till then this is important to have to get similar + * performance on all the slots. + */ + paxb_rc_cfg_write(core_idx, CFG_RC_TL_FCIMM_NP_LIMIT, + CFG_RC_TL_FCIMM_NP_VAL); + + paxb_rc_cfg_write(core_idx, CFG_RC_TL_FCIMM_P_LIMIT, + CFG_RC_TL_FCIMM_P_VAL); + } +} + +static void paxb_cfg_clkreq(void) +{ + uint32_t val, core_idx; + + for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) { + if (!pcie_core_needs_enable(core_idx)) + continue; + + val = paxb_rc_cfg_read(core_idx, CFG_RC_CLKREQ_ENABLED); + val &= ~CFG_RC_CLKREQ_ENABLED_MASK; + paxb_rc_cfg_write(core_idx, CFG_RC_CLKREQ_ENABLED, val); + } +} + +static void paxb_cfg_dl_active(bool enable) +{ + uint32_t val, core_idx; + + for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) { + if (!pcie_core_needs_enable(core_idx)) + continue; + + val = paxb_rc_cfg_read(core_idx, CFG_LINK_CAP_RC); + if (enable) + val |= CFG_RC_DL_ACTIVE_MASK; + else + val &= ~CFG_RC_DL_ACTIVE_MASK; + paxb_rc_cfg_write(core_idx, CFG_LINK_CAP_RC, val); + } +} + +static void paxb_cfg_LTR(int enable) +{ + uint32_t val, core_idx; + + for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) { + if (!pcie_core_needs_enable(core_idx)) + continue; + + val = paxb_rc_cfg_read(core_idx, CFG_ROOT_CAP_RC); + if (enable) + val |= CFG_ROOT_CAP_LTR_MASK; + else + val &= ~CFG_ROOT_CAP_LTR_MASK; + paxb_rc_cfg_write(core_idx, CFG_ROOT_CAP_RC, val); + } +} + +static void paxb_ib_regs_bypass(void) +{ + unsigned int i, j; + + for (i = 0; i < paxb->num_cores; i++) { + if (!pcie_core_needs_enable(i)) + continue; + + /* Configure Default IMAP window */ + mmio_write_32(PAXB_OFFSET(i) + PAXB_0_DEFAULT_IMAP, + DEFAULT_ADDR_INVALID); + mmio_write_32(PAXB_OFFSET(i) + PAXB_0_DEFAULT_IMAP_AXUSER, + IMAP_AXUSER); + mmio_write_32(PAXB_OFFSET(i) + PAXB_0_DEFAULT_IMAP_AXCACHE, + IMAP_AXCACHE); + + /* Configure MSI IMAP window */ + mmio_setbits_32(PAXB_OFFSET(i) + + PAXB_IMAP0_REGS_TYPE_OFFSET, + 0x1); + mmio_write_32(PAXB_OFFSET(i) + PAXB_IARR0_BASE_OFFSET, + GITS_TRANSLATER | OARR_VALID); + for (j = 0; j < PAXB_MAX_IMAP_WINDOWS; j++) { + mmio_write_32(PAXB_OFFSET(i) + PAXB_IMAP0_OFFSET(j), + (GITS_TRANSLATER + + (j * PAXB_IMAP0_WINDOW_SIZE)) | + IMAP_VALID); + } + } +} + +static void paxb_ib_regs_init(void) +{ + unsigned int core_idx; + + for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) { + if (!pcie_core_needs_enable(core_idx)) + continue; + + /* initialize IARR2 to zero */ + mmio_write_32(PAXB_OFFSET(core_idx) + PAXB_IARR2_LOWER_OFFSET, + 0x0); + mmio_setbits_32(PAXB_OFFSET(core_idx) + + PAXB_IMAP0_REGS_TYPE_OFFSET, + 0x1); + } +} + +static void paxb_cfg_apb_timeout(void) +{ + unsigned int core_idx; + + for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) { + if (!pcie_core_needs_enable(core_idx)) + continue; + + /* allow unlimited timeout */ + mmio_write_32(PAXB_OFFSET(core_idx) + + PAXB_APB_TIMEOUT_COUNT_OFFSET, + 0xFFFFFFFF); + } +} + +static void paxb_smmu_cfg(void) +{ + unsigned int core_idx; + uint32_t offset; + uint32_t val; + + for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) { + if (!pcie_core_needs_enable(core_idx)) + continue; + + offset = core_idx * PCIE_CORE_PWR_OFFSET; + val = mmio_read_32(PCIE_PAXB_SMMU_SID_CFG + offset); + val &= ~(0xFFF00); + val |= (PAXB_SMMU_SID_CFG_FUN_WIDTH | + PAXB_SMMU_SID_CFG_DEV_WIDTH | + PAXB_SMMU_SID_CFG_BUS_WIDTH); + mmio_write_32(PCIE_PAXB_SMMU_SID_CFG + offset, val); + val = mmio_read_32(PCIE_PAXB_SMMU_SID_CFG + offset); + VERBOSE("smmu cfg reg 0x%x\n", val); + } +} + +static void paxb_cfg_coherency(void) +{ + unsigned int i, j; + + for (i = 0; i < paxb->num_cores; i++) { + if (!pcie_core_needs_enable(i)) + continue; + +#ifdef USE_DDR + mmio_write_32(PAXB_OFFSET(i) + PAXB_IMAP2_OFFSET, + IMAP_ARCACHE | IMAP_AWCACHE); +#endif + + mmio_write_32(PAXB_OFFSET(i) + PAXB_IMAP0_0_AXUSER_OFFSET, + IMAP_AXUSER); + + mmio_write_32(PAXB_OFFSET(i) + PAXB_IMAP2_AXUSER_OFFSET, + IMAP_AXUSER); + + for (j = 0; j < PAXB_MAX_IMAP_WINDOWS; j++) { +#ifdef USE_DDR + mmio_write_32(PAXB_OFFSET(i) + PAXB_IMAP3_OFFSET(j), + IMAP_ARCACHE | IMAP_AWCACHE); + mmio_write_32(PAXB_OFFSET(i) + PAXB_IMAP4_OFFSET(j), + IMAP_ARCACHE | IMAP_AWCACHE); +#endif + /* zero out IMAP0 mapping windows for MSI/MSI-X */ + mmio_write_32(PAXB_OFFSET(i) + PAXB_IMAP0_OFFSET(j), + 0x0); + + mmio_write_32(PAXB_OFFSET(i) + + PAXB_IMAP3_0_AXUSER_OFFSET(j), + IMAP_AXUSER); + mmio_write_32(PAXB_OFFSET(i) + + PAXB_IMAP4_0_AXUSER_OFFSET(j), + IMAP_AXUSER); + } + } +} + +/* + * This function configures all PAXB related blocks to allow non-secure access + */ +void paxb_ns_init(enum paxb_type type) +{ + unsigned int reg; + + switch (type) { + case PAXB_SR: + for (reg = 0; reg < ARRAY_SIZE(paxb_sec_reg_offset); reg++) { + + mmio_setbits_32(SR_PCIE_NIC_SECURITY_BASE + + paxb_sec_reg_offset[reg], 0x1); + } + /* Enabled all PAXB's relevant IDM blocks access in non-secure mode */ + mmio_setbits_32(SR_PCIE_NIC_SECURITY_BASE + PAXB_SECURITY_IDM_OFFSET, + 0xffff); + break; + case PAXB_NS3Z: + mmio_setbits_32(NS3Z_PCIE_NIC_SECURITY_BASE + + paxb_sec_reg_offset[0], 0x1); + mmio_setbits_32(NS3Z_PCIE_NIC_SECURITY_BASE + + PAXB_SECURITY_IDM_OFFSET, 0xffff); + mmio_setbits_32(NS3Z_PCIE_NIC_SECURITY_BASE + + PAXB_SECURITY_APB_OFFSET, 0x7); + mmio_setbits_32(NS3Z_PCIE_NIC_SECURITY_BASE + + PAXB_SECURITY_ECAM_OFFSET, 0x1); + break; + } +} + +static int paxb_set_config(void) +{ + paxb = paxb_get_config(sr); + if (paxb) + return 0; + + return -ENODEV; +} + +void paxb_init(void) +{ + int ret; + + ret = paxb_set_config(); + if (ret) + return; + + paxb_ns_init(paxb->type); + + ret = pcie_cores_init(); + if (ret) + return; + + if (paxb->phy_init) { + ret = paxb->phy_init(); + if (ret) + return; + } + + paxb_cfg_dev_id(); + paxb_cfg_tgt_trn(); + paxb_cfg_pdl_ctrl(); + if (paxb->type == PAXB_SR) { + paxb_ib_regs_init(); + paxb_cfg_coherency(); + } else + paxb_ib_regs_bypass(); + + paxb_cfg_apb_timeout(); + paxb_smmu_cfg(); + paxb_cfg_clkreq(); + paxb_rc_link_init(); + + /* Stingray Doesn't support LTR */ + paxb_cfg_LTR(false); + paxb_cfg_dl_active(true); + + paxb_cfg_mps(); + +#ifdef PAXB_LINKUP + paxb_start_link_up(); +#endif + INFO("PAXB init done\n"); +} diff --git a/plat/brcm/board/stingray/src/paxc.c b/plat/brcm/board/stingray/src/paxc.c new file mode 100644 index 000000000..44af4b010 --- /dev/null +++ b/plat/brcm/board/stingray/src/paxc.c @@ -0,0 +1,267 @@ +/* + * Copyright (c) 2017 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include +#include + +#define PAXC_BASE 0x60400000 +#define PAXC_AXI_CFG_PF 0x10 +#define PAXC_AXI_CFG_PF_OFFSET(pf) (PAXC_AXI_CFG_PF + (pf) * 4) +#define PAXC_ARPROT_PF_CFG 0x40 +#define PAXC_AWPROT_PF_CFG 0x44 + +#define PAXC_ARQOS_PF_CFG 0x48 +#define PAXC_ARQOS_VAL 0xaaaaaaaa + +#define PAXC_AWQOS_PF_CFG 0x4c +#define PAXC_AWQOS_VAL 0xeeeeeeee + +#define PAXC_CFG_IND_ADDR_OFFSET 0x1f0 +#define PAXC_CFG_IND_ADDR_MASK 0xffc +#define PAXC_CFG_IND_DATA_OFFSET 0x1f4 + +/* offsets for PAXC root complex configuration space registers */ + +#define PAXC_CFG_ID_OFFSET 0x434 +#define PAXC_RC_VENDOR_ID 0x14e4 +#define PAXC_RC_VENDOR_ID_SHIFT 16 + +#define PAXC_RC_DEVICE_ID 0xd750 + +#define PAXC_CFG_LINK_CAP_OFFSET 0x4dc +#define PAXC_RC_LINK_CAP_SPD_SHIFT 0 +#define PAXC_RC_LINK_CAP_SPD_MASK (0xf << PAXC_RC_LINK_CAP_SPD_SHIFT) +#define PAXC_RC_LINK_CAP_SPD 3 +#define PAXC_RC_LINK_CAP_WIDTH_SHIFT 4 +#define PAXC_RC_LINK_CAP_WIDTH_MASK (0x1f << PAXC_RC_LINK_CAP_WIDTH_SHIFT) +#define PAXC_RC_LINK_CAP_WIDTH 16 + +/* offsets for MHB registers */ + +#define MHB_BASE 0x60401000 +#define MHB_MEM_PWR_STATUS_PAXC (MHB_BASE + 0x1c0) +#define MHB_PWR_ARR_POWERON 0x8 +#define MHB_PWR_ARR_POWEROK 0x4 +#define MHB_PWR_POWERON 0x2 +#define MHB_PWR_POWEROK 0x1 +#define MHB_PWR_STATUS_MASK (MHB_PWR_ARR_POWERON | \ + MHB_PWR_ARR_POWEROK | \ + MHB_PWR_POWERON | \ + MHB_PWR_POWEROK) + +/* max number of PFs from Nitro that PAXC sees */ +#define MAX_NR_NITRO_PF 8 + +#ifdef EMULATION_SETUP +static void paxc_reg_dump(void) +{ +} +#else +/* total number of PAXC registers */ +#define NR_PAXC_REGS 53 +static void paxc_reg_dump(void) +{ + uint32_t idx, offset = 0; + + VERBOSE("PAXC register dump start\n"); + for (idx = 0; idx < NR_PAXC_REGS; idx++, offset += 4) + VERBOSE("offset: 0x%x val: 0x%x\n", offset, + mmio_read_32(PAXC_BASE + offset)); + VERBOSE("PAXC register dump end\n"); +} +#endif /* EMULATION_SETUP */ + +#ifdef EMULATION_SETUP +static void mhb_reg_dump(void) +{ +} +#else +#define NR_MHB_REGS 227 +static void mhb_reg_dump(void) +{ + uint32_t idx, offset = 0; + + VERBOSE("MHB register dump start\n"); + for (idx = 0; idx < NR_MHB_REGS; idx++, offset += 4) + VERBOSE("offset: 0x%x val: 0x%x\n", offset, + mmio_read_32(MHB_BASE + offset)); + VERBOSE("MHB register dump end\n"); +} +#endif /* EMULATION_SETUP */ + +static void paxc_rc_cfg_write(uint32_t where, uint32_t val) +{ + mmio_write_32(PAXC_BASE + PAXC_CFG_IND_ADDR_OFFSET, + where & PAXC_CFG_IND_ADDR_MASK); + mmio_write_32(PAXC_BASE + PAXC_CFG_IND_DATA_OFFSET, val); +} + +static uint32_t paxc_rc_cfg_read(uint32_t where) +{ + mmio_write_32(PAXC_BASE + PAXC_CFG_IND_ADDR_OFFSET, + where & PAXC_CFG_IND_ADDR_MASK); + return mmio_read_32(PAXC_BASE + PAXC_CFG_IND_DATA_OFFSET); +} + +/* + * Function to program PAXC root complex link capability register + */ +static void paxc_cfg_link_cap(void) +{ + uint32_t val; + + val = paxc_rc_cfg_read(PAXC_CFG_LINK_CAP_OFFSET); + val &= ~(PAXC_RC_LINK_CAP_SPD_MASK | PAXC_RC_LINK_CAP_WIDTH_MASK); + val |= (PAXC_RC_LINK_CAP_SPD << PAXC_RC_LINK_CAP_SPD_SHIFT) | + (PAXC_RC_LINK_CAP_WIDTH << PAXC_RC_LINK_CAP_WIDTH_SHIFT); + paxc_rc_cfg_write(PAXC_CFG_LINK_CAP_OFFSET, val); +} + +/* + * Function to program PAXC root complex vendor ID and device ID + */ +static void paxc_cfg_id(void) +{ + uint32_t val; + + val = (PAXC_RC_VENDOR_ID << PAXC_RC_VENDOR_ID_SHIFT) | + PAXC_RC_DEVICE_ID; + paxc_rc_cfg_write(PAXC_CFG_ID_OFFSET, val); +} + +void paxc_init(void) +{ + unsigned int pf_index; + unsigned int val; + + val = mmio_read_32(MHB_MEM_PWR_STATUS_PAXC); + if ((val & MHB_PWR_STATUS_MASK) != MHB_PWR_STATUS_MASK) { + INFO("PAXC not powered\n"); + return; + } + + paxc_cfg_id(); + paxc_cfg_link_cap(); + + paxc_reg_dump(); + mhb_reg_dump(); + +#ifdef USE_DDR + /* + * Set AWCACHE and ARCACHE to 0xff (Cacheable write-back, + * allocate on both reads and writes) per + * recommendation from the ASIC team + */ + val = 0xff; +#else + /* disable IO cache if non-DDR memory is used, e.g., external SRAM */ + val = 0x0; +#endif + for (pf_index = 0; pf_index < MAX_NR_NITRO_PF; pf_index++) + mmio_write_32(PAXC_BASE + PAXC_AXI_CFG_PF_OFFSET(pf_index), + val); + + /* + * Set ARPROT and AWPROT to enable non-secure access from + * PAXC to all PFs, PF0 to PF7 + */ + mmio_write_32(PAXC_BASE + PAXC_ARPROT_PF_CFG, 0x22222222); + mmio_write_32(PAXC_BASE + PAXC_AWPROT_PF_CFG, 0x22222222); + + mmio_write_32(PAXC_BASE + PAXC_ARQOS_PF_CFG, PAXC_ARQOS_VAL); + mmio_write_32(PAXC_BASE + PAXC_AWQOS_PF_CFG, PAXC_AWQOS_VAL); + + INFO("PAXC init done\n"); +} + +/* + * These defines do not match the regfile but they are renamed in a way such + * that they are much more readible + */ + +#define MHB_NIC_SECURITY_BASE 0x60500000 +#define MHB_NIC_PAXC_AXI_NS 0x0008 +#define MHB_NIC_IDM_NS 0x000c +#define MHB_NIC_MHB_APB_NS 0x0010 +#define MHB_NIC_NITRO_AXI_NS 0x0014 +#define MHB_NIC_PCIE_AXI_NS 0x0018 +#define MHB_NIC_PAXC_APB_NS 0x001c +#define MHB_NIC_EP_APB_NS 0x0020 + +#define MHB_NIC_PAXC_APB_S_IDM_SHIFT 5 +#define MHB_NIC_EP_APB_S_IDM_SHIFT 4 +#define MHB_NIC_MHB_APB_S_IDM_SHIFT 3 +#define MHB_NIC_PAXC_AXI_S_IDM_SHIFT 2 +#define MHB_NIC_PCIE_AXI_S_IDM_SHIFT 1 +#define MHB_NIC_NITRO_AXI_S_IDM_SHIFT 0 + +#define NIC400_NITRO_TOP_NIC_SECURITY_BASE 0x60d00000 + +#define NITRO_NIC_SECURITY_3_SHIFT 0x14 +#define NITRO_NIC_SECURITY_4_SHIFT 0x18 +#define NITRO_NIC_SECURITY_5_SHIFT 0x1c +#define NITRO_NIC_SECURITY_6_SHIFT 0x20 + +void paxc_mhb_ns_init(void) +{ + unsigned int val; + uintptr_t mhb_nic_gpv = MHB_NIC_SECURITY_BASE; +#ifndef NITRO_SECURE_ACCESS + uintptr_t nic400_nitro_gpv = NIC400_NITRO_TOP_NIC_SECURITY_BASE; +#endif /* NITRO_SECURE_ACCESS */ + + /* set PAXC AXI to allow non-secure access */ + val = mmio_read_32(mhb_nic_gpv + MHB_NIC_PAXC_AXI_NS); + val |= 0x1; + mmio_write_32(mhb_nic_gpv + MHB_NIC_PAXC_AXI_NS, val); + + /* set various MHB IDM interfaces to allow non-secure access */ + val = mmio_read_32(mhb_nic_gpv + MHB_NIC_IDM_NS); + val |= (0x1 << MHB_NIC_PAXC_APB_S_IDM_SHIFT); + val |= (0x1 << MHB_NIC_EP_APB_S_IDM_SHIFT); + val |= (0x1 << MHB_NIC_MHB_APB_S_IDM_SHIFT); + val |= (0x1 << MHB_NIC_PAXC_AXI_S_IDM_SHIFT); + val |= (0x1 << MHB_NIC_PCIE_AXI_S_IDM_SHIFT); + val |= (0x1 << MHB_NIC_NITRO_AXI_S_IDM_SHIFT); + mmio_write_32(mhb_nic_gpv + MHB_NIC_IDM_NS, val); + + /* set MHB APB to allow non-secure access */ + val = mmio_read_32(mhb_nic_gpv + MHB_NIC_MHB_APB_NS); + val |= 0x1; + mmio_write_32(mhb_nic_gpv + MHB_NIC_MHB_APB_NS, val); + + /* set Nitro AXI to allow non-secure access */ + val = mmio_read_32(mhb_nic_gpv + MHB_NIC_NITRO_AXI_NS); + val |= 0x1; + mmio_write_32(mhb_nic_gpv + MHB_NIC_NITRO_AXI_NS, val); + + /* set PCIe AXI to allow non-secure access */ + val = mmio_read_32(mhb_nic_gpv + MHB_NIC_PCIE_AXI_NS); + val |= 0x1; + mmio_write_32(mhb_nic_gpv + MHB_NIC_PCIE_AXI_NS, val); + + /* set PAXC APB to allow non-secure access */ + val = mmio_read_32(mhb_nic_gpv + MHB_NIC_PAXC_APB_NS); + val |= 0x1; + mmio_write_32(mhb_nic_gpv + MHB_NIC_PAXC_APB_NS, val); + + /* set EP APB to allow non-secure access */ + val = mmio_read_32(mhb_nic_gpv + MHB_NIC_EP_APB_NS); + val |= 0x1; + mmio_write_32(mhb_nic_gpv + MHB_NIC_EP_APB_NS, val); + +#ifndef NITRO_SECURE_ACCESS + /* Set NIC400 to allow non-secure access */ + mmio_setbits_32(nic400_nitro_gpv + NITRO_NIC_SECURITY_3_SHIFT, 0x1); + mmio_setbits_32(nic400_nitro_gpv + NITRO_NIC_SECURITY_4_SHIFT, 0x1); + mmio_setbits_32(nic400_nitro_gpv + NITRO_NIC_SECURITY_5_SHIFT, 0x1); + mmio_setbits_32(nic400_nitro_gpv + NITRO_NIC_SECURITY_6_SHIFT, 0x1); +#endif /* NITRO_SECURE_ACCESS */ +} diff --git a/plat/brcm/board/stingray/src/sdio.c b/plat/brcm/board/stingray/src/sdio.c new file mode 100644 index 000000000..aa2b71acb --- /dev/null +++ b/plat/brcm/board/stingray/src/sdio.c @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2019-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include +#include + +#include +#include +#include + +const SDIO_CFG sr_sdio0_cfg = { + .cfg_base = SR_IPROC_SDIO0_CFG_BASE, + .sid_base = SR_IPROC_SDIO0_SID_BASE, + .io_ctrl_base = SR_IPROC_SDIO0_IOCTRL_BASE, + .pad_base = SR_IPROC_SDIO0_PAD_BASE, +}; +const SDIO_CFG sr_sdio1_cfg = { + .cfg_base = SR_IPROC_SDIO1_CFG_BASE, + .sid_base = SR_IPROC_SDIO1_SID_BASE, + .io_ctrl_base = SR_IPROC_SDIO1_IOCTRL_BASE, + .pad_base = SR_IPROC_SDIO1_PAD_BASE, +}; + +void brcm_stingray_sdio_init(void) +{ + unsigned int val; + const SDIO_CFG *sdio0_cfg, *sdio1_cfg; + + sdio0_cfg = &sr_sdio0_cfg; + sdio1_cfg = &sr_sdio1_cfg; + + INFO("set sdio0 caps\n"); + /* SDIO0 CAPS0 */ + val = SDIO0_CAP0_CFG; + INFO("caps0 0x%x\n", val); + mmio_write_32(sdio0_cfg->cfg_base + ICFG_SDIO_CAP0, val); + + /* SDIO0 CAPS1 */ + val = SDIO0_CAP1_CFG; + INFO("caps1 0x%x\n", val); + mmio_write_32(sdio0_cfg->cfg_base + ICFG_SDIO_CAP1, val); + + mmio_write_32(sdio0_cfg->cfg_base + ICFG_SDIO_STRAPSTATUS_0, + SDIO_PRESETVAL0); + mmio_write_32(sdio0_cfg->cfg_base + ICFG_SDIO_STRAPSTATUS_1, + SDIO_PRESETVAL1); + mmio_write_32(sdio0_cfg->cfg_base + ICFG_SDIO_STRAPSTATUS_2, + SDIO_PRESETVAL2); + mmio_write_32(sdio0_cfg->cfg_base + ICFG_SDIO_STRAPSTATUS_3, + SDIO_PRESETVAL3); + mmio_write_32(sdio0_cfg->cfg_base + ICFG_SDIO_STRAPSTATUS_4, + SDIO_PRESETVAL4); + + val = SR_SID_VAL(0x3, 0x0, 0x2) << SDIO_SID_SHIFT; + mmio_write_32(sdio0_cfg->sid_base + ICFG_SDIO_SID_ARADDR, val); + mmio_write_32(sdio0_cfg->sid_base + ICFG_SDIO_SID_AWADDR, val); + + val = mmio_read_32(sdio0_cfg->io_ctrl_base); + val &= ~(0xff << 23); /* Clear ARCACHE and AWCACHE */ + val |= (0xb7 << 23); /* Set ARCACHE and AWCACHE */ + mmio_write_32(sdio0_cfg->io_ctrl_base, val); + + mmio_clrsetbits_32(sdio0_cfg->pad_base + PAD_SDIO_CLK, + PAD_SDIO_MASK, PAD_SDIO_VALUE); + mmio_clrsetbits_32(sdio0_cfg->pad_base + PAD_SDIO_DATA0, + PAD_SDIO_MASK, PAD_SDIO_VALUE); + mmio_clrsetbits_32(sdio0_cfg->pad_base + PAD_SDIO_DATA1, + PAD_SDIO_MASK, PAD_SDIO_VALUE); + mmio_clrsetbits_32(sdio0_cfg->pad_base + PAD_SDIO_DATA2, + PAD_SDIO_MASK, PAD_SDIO_VALUE); + mmio_clrsetbits_32(sdio0_cfg->pad_base + PAD_SDIO_DATA3, + PAD_SDIO_MASK, PAD_SDIO_VALUE); + mmio_clrsetbits_32(sdio0_cfg->pad_base + PAD_SDIO_DATA4, + PAD_SDIO_MASK, PAD_SDIO_VALUE); + mmio_clrsetbits_32(sdio0_cfg->pad_base + PAD_SDIO_DATA5, + PAD_SDIO_MASK, PAD_SDIO_VALUE); + mmio_clrsetbits_32(sdio0_cfg->pad_base + PAD_SDIO_DATA6, + PAD_SDIO_MASK, PAD_SDIO_VALUE); + mmio_clrsetbits_32(sdio0_cfg->pad_base + PAD_SDIO_DATA7, + PAD_SDIO_MASK, PAD_SDIO_VALUE); + mmio_clrsetbits_32(sdio0_cfg->pad_base + PAD_SDIO_CMD, + PAD_SDIO_MASK, PAD_SDIO_VALUE); + + INFO("set sdio1 caps\n"); + + /* SDIO1 CAPS0 */ + val = SDIO1_CAP0_CFG; + INFO("caps0 0x%x\n", val); + mmio_write_32(sdio1_cfg->cfg_base + ICFG_SDIO_CAP0, val); + /* SDIO1 CAPS1 */ + val = SDIO1_CAP1_CFG; + INFO("caps1 0x%x\n", val); + mmio_write_32(sdio1_cfg->cfg_base + ICFG_SDIO_CAP1, val); + + mmio_write_32(sdio1_cfg->cfg_base + ICFG_SDIO_STRAPSTATUS_0, + SDIO_PRESETVAL0); + mmio_write_32(sdio1_cfg->cfg_base + ICFG_SDIO_STRAPSTATUS_1, + SDIO_PRESETVAL1); + mmio_write_32(sdio1_cfg->cfg_base + ICFG_SDIO_STRAPSTATUS_2, + SDIO_PRESETVAL2); + mmio_write_32(sdio1_cfg->cfg_base + ICFG_SDIO_STRAPSTATUS_3, + SDIO_PRESETVAL3); + mmio_write_32(sdio1_cfg->cfg_base + ICFG_SDIO_STRAPSTATUS_4, + SDIO_PRESETVAL4); + + val = SR_SID_VAL(0x3, 0x0, 0x3) << SDIO_SID_SHIFT; + mmio_write_32(sdio1_cfg->sid_base + ICFG_SDIO_SID_ARADDR, val); + mmio_write_32(sdio1_cfg->sid_base + ICFG_SDIO_SID_AWADDR, val); + + val = mmio_read_32(sdio1_cfg->io_ctrl_base); + val &= ~(0xff << 23); /* Clear ARCACHE and AWCACHE */ + val |= (0xb7 << 23); /* Set ARCACHE and AWCACHE */ + mmio_write_32(sdio1_cfg->io_ctrl_base, val); + + mmio_clrsetbits_32(sdio1_cfg->pad_base + PAD_SDIO_CLK, + PAD_SDIO_MASK, PAD_SDIO_VALUE); + mmio_clrsetbits_32(sdio1_cfg->pad_base + PAD_SDIO_DATA0, + PAD_SDIO_MASK, PAD_SDIO_VALUE); + mmio_clrsetbits_32(sdio1_cfg->pad_base + PAD_SDIO_DATA1, + PAD_SDIO_MASK, PAD_SDIO_VALUE); + mmio_clrsetbits_32(sdio1_cfg->pad_base + PAD_SDIO_DATA2, + PAD_SDIO_MASK, PAD_SDIO_VALUE); + mmio_clrsetbits_32(sdio1_cfg->pad_base + PAD_SDIO_DATA3, + PAD_SDIO_MASK, PAD_SDIO_VALUE); + mmio_clrsetbits_32(sdio1_cfg->pad_base + PAD_SDIO_DATA4, + PAD_SDIO_MASK, PAD_SDIO_VALUE); + mmio_clrsetbits_32(sdio1_cfg->pad_base + PAD_SDIO_DATA5, + PAD_SDIO_MASK, PAD_SDIO_VALUE); + mmio_clrsetbits_32(sdio1_cfg->pad_base + PAD_SDIO_DATA6, + PAD_SDIO_MASK, PAD_SDIO_VALUE); + mmio_clrsetbits_32(sdio1_cfg->pad_base + PAD_SDIO_DATA7, + PAD_SDIO_MASK, PAD_SDIO_VALUE); + mmio_clrsetbits_32(sdio1_cfg->pad_base + PAD_SDIO_CMD, + PAD_SDIO_MASK, PAD_SDIO_VALUE); + + INFO("sdio init done\n"); +} diff --git a/plat/brcm/board/stingray/src/sr_paxb_phy.c b/plat/brcm/board/stingray/src/sr_paxb_phy.c new file mode 100644 index 000000000..7380e09a3 --- /dev/null +++ b/plat/brcm/board/stingray/src/sr_paxb_phy.c @@ -0,0 +1,806 @@ +/* + * Copyright (c) 2019-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include +#include + +#include +#include +#include + +/* total number of PCIe Phys */ +#define NUM_OF_PCIE_SERDES 8 + +#define CFG_RC_PMI_ADDR 0x1130 +#define PMI_RX_TERM_SEQ ((0x1 << 27) | (0x1ff << 16) | (0xd090)) +#define PMI_RX_TERM_VAL 0x4c00 +#define PMI_PLL_CTRL_4 0xd0b4 +#define PMI_SERDES_CLK_ENABLE (1 << 12) + +#define WAR_PLX_PRESET_PARITY_FAIL + +#define CFG_RC_REG_PHY_CTL_10 0x1838 +#define PHY_CTL_10_GEN3_MATCH_PARITY (1 << 15) + +#define PMI_X8_CORE0_7_PATCH_SEQ ((0x1 << 27) | (0x1ff << 16) | (0xd2a5)) +#define PMI_X8_CORE0_7_PATCH_VAL 0xd864 + +#define PMI_ADDR_BCAST(addr) ((0x1 << 27) | (0x1ff << 16) | (addr)) +#define PMI_ADDR_LANE0(addr) ((0x1 << 27) | (addr)) +#define PMI_ADDR_LANE1(addr) ((0x1 << 27) | (0x1 << 16) | (addr)) + +#define MERLIN16_PCIE_BLK2_PWRMGMT_7 ((0x1 << 27) | (0x1ff << 16) | 0x1208) +#define MERLIN16_PCIE_BLK2_PWRMGMT_8 ((0x1 << 27) | (0x1ff << 16) | 0x1209) +#define MERLIN16_AMS_TX_CTRL_5 ((0x1 << 27) | (0x1ff << 16) | 0xd0a5) +#define MERLIN16_AMS_TX_CTRL_5_VAL \ + ((1 << 13) | (1 << 12) | (1 << 11) | (1 << 10)) +#define MERLIN16_PCIE_BLK2_PWRMGMT_7_VAL 0x96 +#define MERLIN16_PCIE_BLK2_PWRMGMT_8_VAL 0x12c + +#define CFG_RC_PMI_WDATA 0x1134 +#define CFG_RC_WCMD_SHIFT 31 +#define CFG_RC_WCMD_MASK ((uint32_t)1U << CFG_RC_WCMD_SHIFT) +#define CFG_RC_RCMD_SHIFT 30 +#define CFG_RC_RCMD_MASK ((uint32_t)1U << CFG_RC_RCMD_SHIFT) +#define CFG_RC_RWCMD_MASK (CFG_RC_RCMD_MASK | CFG_RC_WCMD_MASK) +#define CFG_RC_PMI_RDATA 0x1138 +#define CFG_RC_RACK_SHIFT 31 +#define CFG_RC_RACK_MASK ((uint32_t)1U << CFG_RC_RACK_SHIFT) + +/* allow up to 5 ms for PMI write to finish */ +#define PMI_TIMEOUT_MS 5 + +/* in 2x8 RC mode, one needs to patch up Serdes 3 and 7 for link to come up */ +#define SERDES_PATCH_PIPEMUX_INDEX 0x3 +#define SERDES_PATCH_INDEX 0x8 + +#define DSC_UC_CTRL 0xd00d +#define DSC_UC_CTRL_RDY_CMD (1 << 7) +#define LANE_DBG_RST_CTRL 0xd164 +#define UC_A_CLK_CTRL0 0xd200 +#define UC_A_RST_CTRL0 0xd201 +#define UC_A_AHB_CTRL0 0xd202 +#define UC_A_AHB_STAT0 0xd203 +#define UC_A_AHB_WADDR_LSW 0xd204 +#define UC_A_AHB_WADDR_MSW 0xd205 +#define UC_A_AHB_WDATA_LSW 0xd206 +#define UC_A_AHB_WDATA_MSW 0xd207 +#define UC_A_AHB_RADDR_LSW 0xd208 +#define UC_A_AHB_RADDR_MSW 0xd209 +#define UC_A_AHB_RDATA_LSW 0xd20a +#define UC_A_AHB_RDATA_MSW 0xd20b +#define UC_VERSION_NUM 0xd230 +#define DSC_SM_CTL22 0xd267 +#define UC_DBG1 0xd251 + +#define LOAD_UC_CHECK 0 +#define UC_RAM_INIT_TIMEOUT 100 +#define UC_RAM_CONTROL 0xd225 +#define UC_INIT_TIMEOUT 100 +#define SIZE_ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) +#define SZ_4 4 +#define GET_2_BYTES(p, i) ((uint16_t)p[i] | (uint16_t)p[i+1] << 8) + +/* + * List of PCIe LCPLL related registers + * + * LCPLL channel 0 provides the Serdes pad clock when running in RC mode + */ +#define PCIE_LCPLL_BASE 0x40000000 + +#define PCIE_LCPLL_CTRL0_OFFSET 0x00 +#define PCIE_LCPLL_RESETB_SHIFT 31 +#define PCIE_LCPLL_RESETB_MASK BIT(PCIE_LCPLL_RESETB_SHIFT) +#define PCIE_LCPLL_P_RESETB_SHIFT 30 +#define PCIE_LCPLL_P_RESETB_MASK BIT(PCIE_LCPLL_P_RESETB_SHIFT) + +#define PCIE_LCPLL_CTRL3_OFFSET 0x0c +#define PCIE_LCPLL_EN_CTRL_SHIFT 16 +#define PCIE_LCPLL_CM_ENA 0x1a +#define PCIE_LCPLL_CM_BUF_ENA 0x18 +#define PCIE_LCPLL_D2C2_ENA 0x2 +#define PCIE_LCPLL_REF_CLK_SHIFT 1 +#define PCIE_LCPLL_REF_CLK_MASK BIT(PCIE_LCPLL_REF_CLK_SHIFT) +#define PCIE_LCPLL_CTRL13_OFFSET 0x34 +#define PCIE_LCPLL_D2C2_CTRL_SHIFT 16 +#define PCIE_LCPLL_D2C2_TERM_DISC 0xe0 + +#define PCIE_LCPLL_STATUS_OFFSET 0x40 +#define PCIE_LCPLL_LOCK_SHIFT 12 +#define PCIE_LCPLL_LOCK_MASK BIT(PCIE_LCPLL_LOCK_SHIFT) + +#define PCIE_PIPE_MUX_RC_MODE_OVERRIDE_CFG 0x114 +#define PCIE_TX_CLKMASTER_CTRL_OVERRIDE_CFG 0x11c + +/* wait 500 microseconds for PCIe LCPLL to power up */ +#define PCIE_LCPLL_DELAY_US 500 + +/* allow up to 5 ms for PCIe LCPLL VCO to lock */ +#define PCIE_LCPLL_TIMEOUT_MS 5 + +#define PCIE_PIPE_MUX_CONFIGURATION_CFG 0x4000010c + +#define PCIE_PIPEMUX_SHIFT 19 +#define PCIE_PIPEMUX_MASK 0xf + +/* keep track of PIPEMUX index to use */ +static unsigned int pipemux_idx; + +/* + * PCIe PIPEMUX lookup table + * + * Each array index represents a PIPEMUX strap setting + * The array element represents a bitmap where a set bit means the PCIe core + * needs to be enabled as RC + */ +static uint8_t pipemux_table[] = { + /* PIPEMUX = 0, EP 1x16 */ + 0x00, + /* PIPEMUX = 1, EP 1x8 + RC 1x8, core 7 */ + 0x80, + /* PIPEMUX = 2, EP 4x4 */ + 0x00, + /* PIPEMUX = 3, RC 2x8, cores 0, 7 */ + 0x81, + /* PIPEMUX = 4, RC 4x4, cores 0, 1, 6, 7 */ + 0xc3, + /* PIPEMUX = 5, RC 8x2, all 8 cores */ + 0xff, + /* PIPEMUX = 6, RC 3x4 + 2x2, cores 0, 2, 3, 6, 7 */ + 0xcd, + /* PIPEMUX = 7, RC 1x4 + 6x2, cores 0, 2, 3, 4, 5, 6, 7 */ + 0xfd, + /* PIPEMUX = 8, EP 1x8 + RC 4x2, cores 4, 5, 6, 7 */ + 0xf0, + /* PIPEMUX = 9, EP 1x8 + RC 2x4, cores 6, 7 */ + 0xc0, + /* PIPEMUX = 10, EP 2x4 + RC 2x4, cores 1, 6 */ + 0x42, + /* PIPEMUX = 11, EP 2x4 + RC 4x2, cores 2, 3, 4, 5 */ + 0x3c, + /* PIPEMUX = 12, EP 1x4 + RC 6x2, cores 2, 3, 4, 5, 6, 7 */ + 0xfc, + /* PIPEMUX = 13, RC 2x4 + RC 1x4 + 2x2, cores 2, 3, 6 */ + 0x4c, +}; + +/* + * Return 1 if pipemux strap is supported + */ +static int pipemux_strap_is_valid(uint32_t pipemux) +{ + if (pipemux < ARRAY_SIZE(pipemux_table)) + return 1; + else + return 0; +} + +/* + * Read the PCIe PIPEMUX from strap + */ +static uint32_t pipemux_strap_read(void) +{ + uint32_t pipemux; + + pipemux = mmio_read_32(PCIE_PIPE_MUX_CONFIGURATION_CFG); + pipemux &= PCIE_PIPEMUX_MASK; + if (pipemux == PCIE_PIPEMUX_MASK) { + /* read the PCIe PIPEMUX strap setting */ + pipemux = mmio_read_32(CDRU_CHIP_STRAP_DATA_LSW); + pipemux >>= PCIE_PIPEMUX_SHIFT; + pipemux &= PCIE_PIPEMUX_MASK; + } + + return pipemux; +} + +/* + * Store the PIPEMUX index (set for each boot) + */ +static void pipemux_save_index(unsigned int idx) +{ + pipemux_idx = idx; +} + +static int paxb_sr_core_needs_enable(unsigned int core_idx) +{ + return !!((pipemux_table[pipemux_idx] >> core_idx) & 0x1); +} + +static int pipemux_sr_init(void) +{ + uint32_t pipemux; + + /* read the PCIe PIPEMUX strap setting */ + pipemux = pipemux_strap_read(); + if (!pipemux_strap_is_valid(pipemux)) { + ERROR("Invalid PCIe PIPEMUX strap %u\n", pipemux); + return -EIO; + } + + /* no PCIe RC is needed */ + if (!pipemux_table[pipemux]) { + WARN("PIPEMUX indicates no PCIe RC required\n"); + return -ENODEV; + } + + /* save the PIPEMUX strap */ + pipemux_save_index(pipemux); + + return 0; +} + +/* + * PCIe RC serdes link width + * + * The array is first organized in rows as indexed by the PIPEMUX setting. + * Within each row, eight lane width entries are specified -- one entry + * per PCIe core, from 0 to 7. + * + * Note: The EP lanes/cores are not mapped in this table! EP cores are + * controlled and thus configured by Nitro. + */ +static uint8_t link_width_table[][NUM_OF_SR_PCIE_CORES] = { + /* PIPEMUX = 0, EP 1x16 */ + {0, 0, 0, 0, 0, 0, 0, 0}, + /* PIPEMUX = 1, EP 1x8 + RC 1x8, core 7 */ + {0, 0, 0, 0, 0, 0, 0, 8}, + /* PIPEMUX = 2, EP 4x4 */ + {0, 0, 0, 0, 0, 0, 0, 0}, + /* PIPEMUX = 3, RC 2x8, cores 0, 7 */ + {8, 0, 0, 0, 0, 0, 0, 8}, + /* PIPEMUX = 4, RC 4x4, cores 0, 1, 6, 7 */ + {4, 4, 0, 0, 0, 0, 4, 4}, + /* PIPEMUX = 5, RC 8x2, all 8 cores */ + {2, 2, 2, 2, 2, 2, 2, 2}, + /* PIPEMUX = 6, RC 3x4 (cores 0, 6, 7), RC 2x2 (cores 2, 3) */ + {4, 0, 2, 2, 0, 0, 4, 4}, + /* PIPEMUX = 7, RC 1x4 (core 0), RC 6x2 (cores 2, 3, 4, 5, 6, 7 */ + {4, 0, 2, 2, 2, 2, 2, 2}, + /* PIPEMUX = 8, EP 1x8 + RC 4x2 (cores 4, 5, 6, 7) */ + {0, 0, 0, 0, 2, 2, 2, 2}, + /* PIPEMUX = 9, EP 1x8 + RC 2x4 (cores 6, 7) */ + {0, 0, 0, 0, 0, 0, 4, 4}, + /* PIPEMUX = 10, EP 2x4 + RC 2x4 (cores 1, 6) */ + {0, 4, 0, 0, 0, 0, 4, 0}, + /* PIPEMUX = 11, EP 2x4 + RC 4x2 (cores 2, 3, 4, 5) */ + {0, 0, 2, 2, 2, 2, 0, 0}, + /* PIPEMUX = 12, EP 1x4 + RC 6x2 (cores 2, 3, 4, 5, 6, 7) */ + {0, 0, 2, 2, 2, 2, 2, 2}, + /* PIPEMUX = 13, EP 2x4 + RC 1x4 (core 6) + RC 2x2 (cores 2, 3) */ + {0, 0, 2, 2, 0, 0, 4, 0} +}; + +/* + * function for writes to the Serdes registers through the PMI interface + */ +static int paxb_pmi_write(unsigned int core_idx, uint32_t pmi, uint32_t val) +{ + uint32_t status; + unsigned int timeout = PMI_TIMEOUT_MS; + + paxb_rc_cfg_write(core_idx, CFG_RC_PMI_ADDR, pmi); + + val &= ~CFG_RC_RWCMD_MASK; + val |= CFG_RC_WCMD_MASK; + paxb_rc_cfg_write(core_idx, CFG_RC_PMI_WDATA, val); + + do { + status = paxb_rc_cfg_read(core_idx, CFG_RC_PMI_WDATA); + + /* wait for write command bit to clear */ + if ((status & CFG_RC_WCMD_MASK) == 0) + return 0; + } while (--timeout); + + return -EIO; +} + +/* + * function for reads from the Serdes registers through the PMI interface + */ +static int paxb_pmi_read(unsigned int core_idx, uint32_t pmi, uint32_t *val) +{ + uint32_t status; + unsigned int timeout = PMI_TIMEOUT_MS; + + paxb_rc_cfg_write(core_idx, CFG_RC_PMI_ADDR, pmi); + + paxb_rc_cfg_write(core_idx, CFG_RC_PMI_WDATA, CFG_RC_RCMD_MASK); + + do { + status = paxb_rc_cfg_read(core_idx, CFG_RC_PMI_RDATA); + + /* wait for read ack bit set */ + if ((status & CFG_RC_RACK_MASK)) { + *val = paxb_rc_cfg_read(core_idx, CFG_RC_PMI_RDATA); + return 0; + } + } while (--timeout); + + return -EIO; +} + + +#ifndef BOARD_PCIE_EXT_CLK +/* + * PCIe Override clock lookup table + * + * Each array index represents pcie override clock has been done + * by CFW or not. + */ +static uint8_t pcie_override_clk_table[] = { + /* PIPEMUX = 0, EP 1x16 */ + 0x0, + /* PIPEMUX = 1, EP 1x8 + RC 1x8, core 7 */ + 0x1, + /* PIPEMUX = 2, EP 4x4 */ + 0x0, + /* PIPEMUX = 3, RC 2x8, cores 0, 7 */ + 0x0, + /* PIPEMUX = 4, RC 4x4, cores 0, 1, 6, 7 */ + 0x0, + /* PIPEMUX = 5, RC 8x2, all 8 cores */ + 0x0, + /* PIPEMUX = 6, RC 3x4 + 2x2, cores 0, 2, 3, 6, 7 */ + 0x0, + /* PIPEMUX = 7, RC 1x4 + 6x2, cores 0, 2, 3, 4, 5, 6, 7 */ + 0x0, + /* PIPEMUX = 8, EP 1x8 + RC 4x2, cores 4, 5, 6, 7 */ + 0x0, + /* PIPEMUX = 9, EP 1x8 + RC 2x4, cores 6, 7 */ + 0x0, + /* PIPEMUX = 10, EP 2x4 + RC 2x4, cores 1, 6 */ + 0x0, + /* PIPEMUX = 11, EP 2x4 + RC 4x2, cores 2, 3, 4, 5 */ + 0x0, + /* PIPEMUX = 12, EP 1x4 + RC 6x2, cores 2, 3, 4, 5, 6, 7 */ + 0x0, + /* PIPEMUX = 13, RC 2x4 + RC 1x4 + 2x2, cores 2, 3, 6 */ + 0x0, +}; + +/* + * Bring up LCPLL channel 0 reference clock for PCIe serdes used in RC mode + */ +static int pcie_lcpll_init(void) +{ + uintptr_t reg; + unsigned int timeout = PCIE_LCPLL_TIMEOUT_MS; + uint32_t val; + + if (pcie_override_clk_table[pipemux_idx]) { + /* + * Check rc_mode_override again to avoid halt + * because of cfw uninitialized lcpll. + */ + reg = (uintptr_t)(PCIE_LCPLL_BASE + + PCIE_PIPE_MUX_RC_MODE_OVERRIDE_CFG); + val = mmio_read_32(reg); + if (val & 0x1) + return 0; + else + return -ENODEV; + } + + /* power on PCIe LCPLL and its LDO */ + reg = (uintptr_t)CRMU_AON_CTRL1; + mmio_setbits_32(reg, CRMU_PCIE_LCPLL_PWR_ON_MASK | + CRMU_PCIE_LCPLL_PWRON_LDO_MASK); + udelay(PCIE_LCPLL_DELAY_US); + + /* remove isolation */ + mmio_clrbits_32(reg, CRMU_PCIE_LCPLL_ISO_IN_MASK); + udelay(PCIE_LCPLL_DELAY_US); + + /* disconnect termination */ + reg = (uintptr_t)(PCIE_LCPLL_BASE + PCIE_LCPLL_CTRL13_OFFSET); + mmio_setbits_32(reg, PCIE_LCPLL_D2C2_TERM_DISC << + PCIE_LCPLL_D2C2_CTRL_SHIFT); + + /* enable CML buf1/2 and D2C2 */ + reg = (uintptr_t)(PCIE_LCPLL_BASE + PCIE_LCPLL_CTRL3_OFFSET); + mmio_setbits_32(reg, PCIE_LCPLL_CM_ENA << PCIE_LCPLL_EN_CTRL_SHIFT); + + /* select diff clock mux out as ref clock */ + mmio_clrbits_32(reg, PCIE_LCPLL_REF_CLK_MASK); + + /* delay for 500 microseconds per ASIC spec for PCIe LCPLL */ + udelay(PCIE_LCPLL_DELAY_US); + + /* now bring PCIe LCPLL out of reset */ + reg = (uintptr_t)(PCIE_LCPLL_BASE + PCIE_LCPLL_CTRL0_OFFSET); + mmio_setbits_32(reg, PCIE_LCPLL_RESETB_MASK); + + /* wait for PLL to lock */ + reg = (uintptr_t)(PCIE_LCPLL_BASE + PCIE_LCPLL_STATUS_OFFSET); + do { + val = mmio_read_32(reg); + if ((val & PCIE_LCPLL_LOCK_MASK) == PCIE_LCPLL_LOCK_MASK) { + /* now bring the post divider out of reset */ + reg = (uintptr_t)(PCIE_LCPLL_BASE + + PCIE_LCPLL_CTRL0_OFFSET); + mmio_setbits_32(reg, PCIE_LCPLL_P_RESETB_MASK); + VERBOSE("PCIe LCPLL locked\n"); + return 0; + } + mdelay(1); + } while (--timeout); + + ERROR("PCIe LCPLL failed to lock\n"); + return -EIO; +} +#else +/* + * Bring up EXT CLK reference clock for PCIe serdes used in RC mode + * XTAL_BYPASS (3 << 0) + * INTR_LC_REF (5 << 0) + * PD_CML_LC_REF_OUT (1 << 4) + * PD_CML_REF_CH_OUT (1 << 8) + * CLK_MASTER_SEL (1 << 11) + * CLK_MASTER_CTRL_A (1 << 12) + * CLK_MASTER_CTRL_B (2 << 14) + */ +static const uint16_t pcie_ext_clk[][NUM_OF_PCIE_SERDES] = { + /* PIPEMUX = 0, EP 1x16 */ + {0}, + /* PIPEMUX = 1, EP 1x8 + RC 1x8, core 7 */ + {0}, + /* PIPEMUX = 2, EP 4x4 */ + {0}, + /* PIPEMUX = 3, RC 2x8, cores 0, 7 */ + {0x8803, 0x9115, 0x9115, 0x1115, 0x8803, 0x9115, 0x9115, 0x1115}, + /* PIPEMUX = 4, RC 4x4, cores 0, 1, 6, 7 */ + {0x8803, 0x1115, 0x8915, 0x1115, 0x8803, 0x1115, 0x8915, 0x1115,}, + /* PIPEMUX = 5, RC 8x2, all 8 cores */ + {0x0803, 0x0915, 0x0915, 0x0915, 0x0803, 0x0915, 0x0915, 0x0915,}, + /* PIPEMUX = 6, RC 3x4 + 2x2, cores 0, 2, 3, 6, 7 */ + {0}, + /* PIPEMUX = 7, RC 1x4 + 6x2, cores 0, 2, 3, 4, 5, 6, 7 */ + {0}, + /* PIPEMUX = 8, EP 1x8 + RC 4x2, cores 4, 5, 6, 7 */ + {0}, + /* PIPEMUX = 9, EP 1x8 + RC 2x4, cores 6, 7 */ + {0}, + /* PIPEMUX = 10, EP 2x4 + RC 2x4, cores 1, 6 */ + {0}, + /* PIPEMUX = 11, EP 2x4 + RC 4x2, cores 2, 3, 4, 5 */ + {0}, + /* PIPEMUX = 12, EP 1x4 + RC 6x2, cores 2, 3, 4, 5, 6, 7 */ + {0}, + /* PIPEMUX = 13, RC 2x4 + RC 1x4 + 2x2, cores 2, 3, 6 */ + {0}, +}; + +static void pcie_ext_clk_init(void) +{ + unsigned int serdes; + uint32_t val; + + for (serdes = 0; serdes < NUM_OF_PCIE_SERDES; serdes++) { + val = pcie_ext_clk[pipemux_idx][serdes]; + if (!val) + return; + mmio_write_32(PCIE_CORE_RESERVED_CFG + + serdes * PCIE_CORE_PWR_OFFSET, val); + } + /* disable CML buf1/2 and enable D2C2 */ + mmio_clrsetbits_32((PCIE_LCPLL_BASE + PCIE_LCPLL_CTRL3_OFFSET), + PCIE_LCPLL_CM_BUF_ENA << PCIE_LCPLL_EN_CTRL_SHIFT, + PCIE_LCPLL_D2C2_ENA << PCIE_LCPLL_EN_CTRL_SHIFT); + mmio_write_32(PCIE_LCPLL_BASE + PCIE_TX_CLKMASTER_CTRL_OVERRIDE_CFG, 1); + INFO("Overriding Clocking - using REF clock from PAD...\n"); +} +#endif + +static int load_uc(unsigned int core_idx) +{ + return 0; +} + +static int paxb_serdes_gate_clock(unsigned int core_idx, int gate_clk) +{ + unsigned int link_width, serdes, nr_serdes; + uintptr_t pmi_base; + unsigned int rdata; + uint32_t core_offset = core_idx * PCIE_CORE_PWR_OFFSET; + + link_width = paxb->get_link_width(core_idx); + if (!link_width) { + ERROR("Unsupported PIPEMUX\n"); + return -EOPNOTSUPP; + } + + nr_serdes = link_width / 2; + pmi_base = (uintptr_t)(PCIE_CORE_PMI_CFG_BASE + core_offset); + + for (serdes = 0; serdes < nr_serdes; serdes++) { + mmio_write_32(pmi_base, serdes); + paxb_pmi_read(core_idx, PMI_ADDR_LANE0(PMI_PLL_CTRL_4), &rdata); + if (!gate_clk) + rdata |= PMI_SERDES_CLK_ENABLE; + else + rdata &= ~PMI_SERDES_CLK_ENABLE; + paxb_pmi_write(core_idx, PMI_ADDR_BCAST(PMI_PLL_CTRL_4), rdata); + } + return 0; +} + +static int paxb_gen3_serdes_init(unsigned int core_idx, uint32_t nSerdes) +{ + uint32_t rdata; + int serdes; + uintptr_t pmi_base; + unsigned int timeout; + unsigned int reg_d230, reg_d267; + + + pmi_base = (uintptr_t)(PCIE_CORE_PMI_CFG_BASE + + (core_idx * PCIE_CORE_PWR_OFFSET)); + + for (serdes = 0; serdes < nSerdes; serdes++) { + /* select the PMI interface */ + mmio_write_32(pmi_base, serdes); + + /* Clock enable */ + paxb_pmi_write(core_idx, PMI_ADDR_BCAST(UC_A_CLK_CTRL0), + 0x3); + + /* Release reset of master */ + paxb_pmi_write(core_idx, PMI_ADDR_BCAST(UC_A_RST_CTRL0), + 0x1); + + /* clearing PRAM memory */ + paxb_pmi_write(core_idx, PMI_ADDR_BCAST(UC_A_AHB_CTRL0), + 0x100); + + timeout = UC_RAM_INIT_TIMEOUT; + do { + paxb_pmi_read(core_idx, + PMI_ADDR_LANE0(UC_A_AHB_STAT0), + &rdata); + } while ((rdata & 0x01) == 0 && timeout--); + + if (!timeout) + return -EIO; + + timeout = UC_RAM_INIT_TIMEOUT; + do { + paxb_pmi_read(core_idx, + PMI_ADDR_LANE1(UC_A_AHB_STAT0), + &rdata); + } while ((rdata & 0x01) == 0 && timeout--); + + if (!timeout) + return -EIO; + + /* clearing PRAM memory */ + paxb_pmi_write(core_idx, PMI_ADDR_BCAST(UC_A_AHB_CTRL0), + 0); + + /* to identify 2 lane serdes */ + paxb_pmi_write(core_idx, PMI_ADDR_BCAST(UC_DBG1), 0x1); + + /* De-Assert Pram & master resets */ + paxb_pmi_write(core_idx, PMI_ADDR_BCAST(UC_A_RST_CTRL0), + 0x9); + + if (load_uc(core_idx)) + return -EIO; + + /* UC UC ready for command */ + paxb_pmi_read(core_idx, PMI_ADDR_LANE0(DSC_UC_CTRL), + &rdata); + rdata |= DSC_UC_CTRL_RDY_CMD; + paxb_pmi_write(core_idx, PMI_ADDR_LANE0(DSC_UC_CTRL), + rdata); + + paxb_pmi_read(core_idx, PMI_ADDR_LANE1(DSC_UC_CTRL), + &rdata); + rdata |= DSC_UC_CTRL_RDY_CMD; + paxb_pmi_write(core_idx, PMI_ADDR_LANE1(DSC_UC_CTRL), + rdata); + + /* Lane reset */ + paxb_pmi_write(core_idx, + PMI_ADDR_BCAST(LANE_DBG_RST_CTRL), 0x3); + + /* De-Assert Core and Master resets */ + paxb_pmi_write(core_idx, PMI_ADDR_BCAST(UC_A_RST_CTRL0), + 0x3); + + timeout = UC_INIT_TIMEOUT; + while (timeout--) { + paxb_pmi_read(core_idx, + PMI_ADDR_LANE0(UC_VERSION_NUM), + ®_d230); + paxb_pmi_read(core_idx, + PMI_ADDR_LANE0(DSC_SM_CTL22), + ®_d267); + + if (((reg_d230 & 0xffff) != 0) & + ((reg_d267 & 0xc000) == 0xc000)) { + break; + } + mdelay(1); + } + + if (!timeout) + return -EIO; + + timeout = UC_INIT_TIMEOUT; + while (timeout--) { + paxb_pmi_read(core_idx, + PMI_ADDR_LANE1(UC_VERSION_NUM), + ®_d230); + paxb_pmi_read(core_idx, + PMI_ADDR_LANE1(DSC_SM_CTL22), + ®_d267); + + if (((reg_d230 & 0xffff) != 0) & + ((reg_d267 & 0xc000) == 0xc000)) { + break; + } + mdelay(1); + } + + if (!timeout) + return -EIO; + } + return 0; +} + +static int pcie_serdes_requires_patch(unsigned int serdes_idx) +{ + if (pipemux_idx != SERDES_PATCH_PIPEMUX_INDEX) + return 0; + + return !!((SERDES_PATCH_INDEX >> serdes_idx) & 0x1); +} + +static void pcie_tx_coeff_p7(unsigned int core_idx) +{ + paxb_pmi_write(core_idx, PMI_ADDR_BCAST(0xd11b), 0x00aa); + paxb_pmi_write(core_idx, PMI_ADDR_BCAST(0xd11c), 0x1155); + paxb_pmi_write(core_idx, PMI_ADDR_BCAST(0xd11d), 0x2449); + paxb_pmi_write(core_idx, PMI_ADDR_BCAST(0xd11e), 0x000f); + paxb_pmi_write(core_idx, PMI_ADDR_BCAST(0xd307), 0x0001); +} + + +static unsigned int paxb_sr_get_rc_link_width(unsigned int core_idx) +{ + return link_width_table[pipemux_idx][core_idx]; +} + +static uint32_t paxb_sr_get_rc_link_speed(void) +{ + return GEN3_LINK_SPEED; +} + + +static int paxb_serdes_init(unsigned int core_idx, unsigned int nr_serdes) +{ + uint32_t core_offset = core_idx * PCIE_CORE_PWR_OFFSET; + unsigned int serdes; + uintptr_t pmi_base; + int ret; + + /* + * Each serdes has a x2 link width + * + * Use PAXB to patch the serdes for proper RX termination through the + * PMI interface + */ + pmi_base = (uintptr_t)(PCIE_CORE_PMI_CFG_BASE + core_offset); + for (serdes = 0; serdes < nr_serdes; serdes++) { + /* select the PMI interface */ + mmio_write_32(pmi_base, serdes); + + /* patch Serdes for RX termination */ + ret = paxb_pmi_write(core_idx, PMI_RX_TERM_SEQ, + PMI_RX_TERM_VAL); + if (ret) + goto err_pmi; + + ret = paxb_pmi_write(core_idx, MERLIN16_PCIE_BLK2_PWRMGMT_7, + MERLIN16_PCIE_BLK2_PWRMGMT_7_VAL); + if (ret) + goto err_pmi; + + ret = paxb_pmi_write(core_idx, MERLIN16_PCIE_BLK2_PWRMGMT_8, + MERLIN16_PCIE_BLK2_PWRMGMT_8_VAL); + if (ret) + goto err_pmi; + + ret = paxb_pmi_write(core_idx, MERLIN16_AMS_TX_CTRL_5, + MERLIN16_AMS_TX_CTRL_5_VAL); + if (ret) + goto err_pmi; + + pcie_tx_coeff_p7(core_idx); + + if (pcie_serdes_requires_patch(serdes)) { + if (((core_idx == 0) || (core_idx == 7))) { + ret = paxb_pmi_write(core_idx, + PMI_X8_CORE0_7_PATCH_SEQ, + PMI_X8_CORE0_7_PATCH_VAL); + if (ret) + goto err_pmi; + } + } + } + + return 0; + +err_pmi: + ERROR("PCIe PMI write failed\n"); + return ret; +} + +static int paxb_sr_phy_init(void) +{ + int ret; + unsigned int core_idx; + +#ifndef BOARD_PCIE_EXT_CLK + ret = pcie_lcpll_init(); + if (ret) + return ret; +#else + pcie_ext_clk_init(); +#endif + + for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) { + if (!pcie_core_needs_enable(core_idx)) + continue; + unsigned int link_width; + + paxb_serdes_gate_clock(core_idx, 0); + + link_width = paxb->get_link_width(core_idx); + if (!link_width) { + ERROR("Unsupported PIPEMUX\n"); + return -EOPNOTSUPP; + } + + ret = paxb_serdes_init(core_idx, link_width / 2); + if (ret) { + ERROR("PCIe serdes initialization failed for core %u\n", + core_idx); + return ret; + } + + + ret = paxb_gen3_serdes_init(core_idx, link_width / 2); + if (ret) { + ERROR("PCIe GEN3 serdes initialization failed\n"); + return ret; + } + + } + return 0; +} + +const paxb_cfg sr_paxb_cfg = { + .type = PAXB_SR, + .device_id = SR_B0_DEVICE_ID, + .pipemux_init = pipemux_sr_init, + .phy_init = paxb_sr_phy_init, + .core_needs_enable = paxb_sr_core_needs_enable, + .num_cores = NUM_OF_SR_PCIE_CORES, + .get_link_width = paxb_sr_get_rc_link_width, + .get_link_speed = paxb_sr_get_rc_link_speed, +}; + +const paxb_cfg *paxb_get_sr_config(void) +{ + return &sr_paxb_cfg; +} -- cgit v1.2.3 From bffde63de7a2c1a8534c1d969857d17fa17e30df Mon Sep 17 00:00:00 2001 From: Sheetal Tigadoli Date: Sun, 5 Jan 2020 14:59:04 +0530 Subject: drivers: Add emmc driver for Broadcom platforms Add emmc driver for Broadcom platforms Change-Id: I126a6dfccd41062cb0b856f2c2fb1f724730b95e Signed-off-by: Sheetal Tigadoli --- drivers/brcm/emmc/emmc_chal_sd.c | 1017 ++++++++++++++++++ drivers/brcm/emmc/emmc_csl_sdcard.c | 1087 +++++++++++++++++++ drivers/brcm/emmc/emmc_csl_sdcmd.c | 842 +++++++++++++++ drivers/brcm/emmc/emmc_pboot_hal_memory_drv.c | 621 +++++++++++ include/drivers/brcm/emmc/bcm_emmc.h | 104 ++ include/drivers/brcm/emmc/emmc_api.h | 47 + include/drivers/brcm/emmc/emmc_brcm_rdb_sd4_top.h | 1116 ++++++++++++++++++++ include/drivers/brcm/emmc/emmc_chal_sd.h | 202 ++++ include/drivers/brcm/emmc/emmc_chal_types.h | 20 + include/drivers/brcm/emmc/emmc_csl_sd.h | 96 ++ include/drivers/brcm/emmc/emmc_csl_sdcmd.h | 168 +++ include/drivers/brcm/emmc/emmc_csl_sdprot.h | 435 ++++++++ .../drivers/brcm/emmc/emmc_pboot_hal_memory_drv.h | 94 ++ plat/brcm/board/common/board_common.mk | 31 +- plat/brcm/board/stingray/driver/plat_emmc.c | 109 ++ plat/brcm/board/stingray/platform.mk | 8 + plat/brcm/board/stingray/src/bl2_setup.c | 1 + 17 files changed, 5997 insertions(+), 1 deletion(-) create mode 100644 drivers/brcm/emmc/emmc_chal_sd.c create mode 100644 drivers/brcm/emmc/emmc_csl_sdcard.c create mode 100644 drivers/brcm/emmc/emmc_csl_sdcmd.c create mode 100644 drivers/brcm/emmc/emmc_pboot_hal_memory_drv.c create mode 100644 include/drivers/brcm/emmc/bcm_emmc.h create mode 100644 include/drivers/brcm/emmc/emmc_api.h create mode 100644 include/drivers/brcm/emmc/emmc_brcm_rdb_sd4_top.h create mode 100644 include/drivers/brcm/emmc/emmc_chal_sd.h create mode 100644 include/drivers/brcm/emmc/emmc_chal_types.h create mode 100644 include/drivers/brcm/emmc/emmc_csl_sd.h create mode 100644 include/drivers/brcm/emmc/emmc_csl_sdcmd.h create mode 100644 include/drivers/brcm/emmc/emmc_csl_sdprot.h create mode 100644 include/drivers/brcm/emmc/emmc_pboot_hal_memory_drv.h create mode 100644 plat/brcm/board/stingray/driver/plat_emmc.c diff --git a/drivers/brcm/emmc/emmc_chal_sd.c b/drivers/brcm/emmc/emmc_chal_sd.c new file mode 100644 index 000000000..34d761c73 --- /dev/null +++ b/drivers/brcm/emmc/emmc_chal_sd.c @@ -0,0 +1,1017 @@ +/* + * Copyright (c) 2016 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include + +#include + +#include "bcm_emmc.h" +#include "emmc_chal_types.h" +#include "emmc_chal_sd.h" +#include "emmc_pboot_hal_memory_drv.h" + +extern void emmc_soft_reset(void); + +#define SD_VDD_WINDOW_1_6_TO_1_7 0x00000010 // 1.6 V to 1.7 Volts +#define SD_VDD_WINDOW_1_7_TO_1_8 0x00000020 // 1.7 V to 1.8 Volts +#define SD_VDD_WINDOW_1_8_TO_1_9 0x00000040 // 1.8 V to 1.9 Volts +#define SD_VDD_WINDOW_1_9_TO_2_0 0x00000080 // 1.9 V to 2.0 Volts +#define SD_VDD_WINDOW_2_0_TO_2_1 0x00000100 // 2.0 V to 2.1 Volts +#define SD_VDD_WINDOW_2_1_TO_2_2 0x00000200 // 2.1 V to 2.2 Volts +#define SD_VDD_WINDOW_2_2_TO_2_3 0x00000400 // 2.2 V to 2.3 Volts +#define SD_VDD_WINDOW_2_3_TO_2_4 0x00000800 // 2.3 V to 2.4 Volts +#define SD_VDD_WINDOW_2_4_TO_2_5 0x00001000 // 2.4 V to 2.5 Volts +#define SD_VDD_WINDOW_2_5_TO_2_6 0x00002000 // 2.5 V to 2.6 Volts +#define SD_VDD_WINDOW_2_6_TO_2_7 0x00004000 // 2.6 V to 2.7 Volts +#define SD_VDD_WINDOW_2_7_TO_2_8 0x00008000 // 2.7 V to 2.8 Volts +#define SD_VDD_WINDOW_2_8_TO_2_9 0x00010000 // 2.8 V to 2.9 Volts +#define SD_VDD_WINDOW_2_9_TO_3_0 0x00020000 // 2.9 V to 3.0 Volts +#define SD_VDD_WINDOW_3_0_TO_3_1 0x00040000 // 3.0 V to 3.1 Volts +#define SD_VDD_WINDOW_3_1_TO_3_2 0x00080000 // 3.1 V to 3.2 Volts +#define SD_VDD_WINDOW_3_2_TO_3_3 0x00100000 // 3.2 V to 3.3 Volts +#define SD_VDD_WINDOW_3_3_TO_3_4 0x00200000 // 3.3 V to 3.4 Volts +#define SD_VDD_WINDOW_3_4_TO_3_5 0x00400000 // 3.4 V to 3.5 Volts +#define SD_VDD_WINDOW_3_5_TO_3_6 0x00800000 // 3.5 V to 3.6 Volts + +#define SD_VDD_WINDOW_1_6_TO_2_6 (SD_VDD_WINDOW_1_6_TO_1_7 | \ + SD_VDD_WINDOW_1_7_TO_1_8 | \ + SD_VDD_WINDOW_1_8_TO_1_9 | \ + SD_VDD_WINDOW_1_9_TO_2_0 | \ + SD_VDD_WINDOW_2_0_TO_2_1 | \ + SD_VDD_WINDOW_2_1_TO_2_2 | \ + SD_VDD_WINDOW_2_2_TO_2_3 | \ + SD_VDD_WINDOW_2_3_TO_2_4 | \ + SD_VDD_WINDOW_2_4_TO_2_5 | \ + SD_VDD_WINDOW_2_5_TO_2_6) + +#define SD_VDD_WINDOW_2_6_TO_3_2 (SD_VDD_WINDOW_2_6_TO_2_7 | \ + SD_VDD_WINDOW_2_7_TO_2_8 | \ + SD_VDD_WINDOW_2_8_TO_2_9 | \ + SD_VDD_WINDOW_2_9_TO_3_0 | \ + SD_VDD_WINDOW_3_0_TO_3_1 | \ + SD_VDD_WINDOW_3_1_TO_3_2) + +#define SD_VDD_WINDOW_3_2_TO_3_6 (SD_VDD_WINDOW_3_2_TO_3_3 | \ + SD_VDD_WINDOW_3_3_TO_3_4 | \ + SD_VDD_WINDOW_3_4_TO_3_5 | \ + SD_VDD_WINDOW_3_5_TO_3_6) + + +static int32_t chal_sd_set_power(struct sd_dev *handle, + uint32_t voltage, uint32_t state); + +static void chal_sd_set_dma_boundary(struct sd_dev *handle, uint32_t boundary); + +static int32_t chal_sd_setup_handler(struct sd_dev *handle, + uint32_t sdBbase, uint32_t hostBase); + +/* + * Configure host controller pwr settings, + * to match voltage requirements by SD Card + */ +static int32_t chal_sd_set_power(struct sd_dev *handle, + uint32_t voltage, uint32_t state) +{ + int32_t rc, rval = SD_FAIL; + uint32_t time = 0; + + if (handle == NULL) + return SD_INVALID_HANDLE; + + mmio_clrsetbits_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_CTRL_OFFSET, + (SD4_EMMC_TOP_CTRL_SDVSELVDD1_MASK | + SD4_EMMC_TOP_CTRL_SDPWR_MASK), + (voltage << 9)); + + /* + * Long delay is required here in emulation. Without this, the initial + * commands sent to the eMMC card timeout. We don't know if this + * delay is necessary with silicon, leaving in for safety. + * It is observed that 403ms on emulation system and as per the clock + * calculations it is expected to complete with in 1ms on chip + */ + do { + rc = mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_INTR_OFFSET); + + if ((rc & SD4_EMMC_TOP_INTR_CRDINS_MASK) == + SD4_EMMC_TOP_INTR_CRDINS_MASK) + break; + + mdelay(1); + } while (time++ < EMMC_CARD_DETECT_TIMEOUT_MS); + + if (time >= EMMC_CARD_DETECT_TIMEOUT_MS) { + ERROR("EMMC: Card insert event detection timeout\n"); + return rval; + } + + VERBOSE("EMMC: Card detection delay: %dms\n", time); + + if (state) + mmio_setbits_32(handle->ctrl.sdRegBaseAddr + SD4_EMMC_TOP_CTRL_OFFSET, + SD4_EMMC_TOP_CTRL_SDPWR_MASK); + + /* dummy write & ack to verify if the sdio is ready to send commads */ + mmio_write_32(handle->ctrl.sdRegBaseAddr + SD4_EMMC_TOP_ARG_OFFSET, 0); + mmio_write_32(handle->ctrl.sdRegBaseAddr + SD4_EMMC_TOP_CMD_OFFSET, 0); + + /* + * 63ms observed on emulation system, As per clock calculations + * it will complete < 1ms on chip. + */ + time = 0; + do { + rc = mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_INTR_OFFSET); + + if (rc & SD4_EMMC_TOP_INTR_ERRIRQ_MASK) + break; + + if ((rc & SD4_EMMC_TOP_INTR_CMDDONE_MASK) == + SD4_EMMC_TOP_INTR_CMDDONE_MASK) + break; + + mdelay(1); + } while (time++ < EMMC_CMD_TIMEOUT_MS); + + if (time >= EMMC_CMD_TIMEOUT_MS) { + WARN("%s %d Initial dummy command timeout is happened\n", + __func__, __LINE__); + return rval; + } + + VERBOSE("EMMC: Dummy Command delay: %dms\n", time); + + return SD_OK; +} + +/* + * Configure DMA Boundaries + */ +static void chal_sd_set_dma_boundary(struct sd_dev *handle, uint32_t boundary) +{ + if (handle == NULL) + return; + + mmio_clrsetbits_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_BLOCK_OFFSET, + SD4_EMMC_TOP_BLOCK_HSBS_MASK, boundary); +} + +static int32_t chal_sd_setup_handler(struct sd_dev *handle, uint32_t sdBase, + uint32_t hostBase) +{ + if (handle == NULL) + return SD_INVALID_HANDLE; + + handle->ctrl.sdRegBaseAddr = sdBase; + handle->ctrl.hostRegBaseAddr = hostBase; + handle->ctrl.present = 0; + handle->ctrl.rca = 0; + handle->ctrl.blkGapEnable = 0; + handle->ctrl.cmdStatus = 0; + + return SD_OK; +} + +/* + * Initialize SD Host controller + */ +int32_t chal_sd_init(CHAL_HANDLE *sd_handle) +{ + uint32_t cap_val_l = 0; + uint32_t ctl_val, voltage; + uint32_t timeout_val; + struct sd_dev *handle; + uint32_t reg_val; + int32_t rval = SD_FAIL; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + handle = (struct sd_dev *)sd_handle; + + /* + * Set SDIO Host Controller capabilities register + */ + EMMC_TRACE("Set Host Controller Capabilities register\n"); + + reg_val = 0; + reg_val |= (1 << ICFG_SDIO0_CAP0__SLOT_TYPE_R); + reg_val |= (0 << ICFG_SDIO0_CAP0__INT_MODE_R); + reg_val |= (0 << ICFG_SDIO0_CAP0__SYS_BUS_64BIT_R); + reg_val |= (1 << ICFG_SDIO0_CAP0__VOLTAGE_1P8V_R); + reg_val |= (1 << ICFG_SDIO0_CAP0__VOLTAGE_3P0V_R); + reg_val |= (1 << ICFG_SDIO0_CAP0__VOLTAGE_3P3V_R); + reg_val |= (1 << ICFG_SDIO0_CAP0__SUSPEND_RESUME_R); + reg_val |= (1 << ICFG_SDIO0_CAP0__SDMA_R); + reg_val |= (1 << ICFG_SDIO0_CAP0__HIGH_SPEED_R); + reg_val |= (1 << ICFG_SDIO0_CAP0__ADMA2_R); + reg_val |= (1 << ICFG_SDIO0_CAP0__EXTENDED_MEDIA_R); + reg_val |= (2 << ICFG_SDIO0_CAP0__MAX_BLOCK_LEN_R); + reg_val |= (0xd0 << ICFG_SDIO0_CAP0__BASE_CLK_FREQ_R); + reg_val |= (1 << ICFG_SDIO0_CAP0__TIMEOUT_UNIT_R); + reg_val |= (0x30 << ICFG_SDIO0_CAP0__TIMEOUT_CLK_FREQ_R); + + mmio_write_32(ICFG_SDIO0_CAP0, reg_val); + + reg_val = 0; + reg_val |= (1 << ICFG_SDIO0_CAP1__SPI_BLOCK_MODE_R); + reg_val |= (1 << ICFG_SDIO0_CAP1__SPI_MODE_R); + reg_val |= (0 << ICFG_SDIO0_CAP1__CLK_MULT_R); + reg_val |= (0 << ICFG_SDIO0_CAP1__RETUNING_MODE_R); + reg_val |= (1 << ICFG_SDIO0_CAP1__TUNE_SDR50_R); + reg_val |= (1 << ICFG_SDIO0_CAP1__TIME_RETUNE_R); + reg_val |= (1 << ICFG_SDIO0_CAP1__DRIVER_D_R); + reg_val |= (1 << ICFG_SDIO0_CAP1__DRIVER_C_R); + reg_val |= (1 << ICFG_SDIO0_CAP1__DRIVER_A_R); + reg_val |= (1 << ICFG_SDIO0_CAP1__DDR50_R); + reg_val |= (1 << ICFG_SDIO0_CAP1__SDR104_R); + reg_val |= (1 << ICFG_SDIO0_CAP1__SDR50_R); + + mmio_write_32(ICFG_SDIO0_CAP1, reg_val); + + /* Reset the SDIO controller */ + chal_sd_stop(); + + /* Turn on SD clock */ + chal_sd_set_clock(sd_handle, + chal_sd_freq_2_div_ctrl_setting(INIT_CLK_FREQ), 1); + + /* program data time out value to the max */ + timeout_val = SD_HOST_CORE_TIMEOUT; + + ctl_val = mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_CTRL1_OFFSET); + ctl_val |= ((timeout_val & 0xf) << SD4_EMMC_TOP_CTRL1_DTCNT_SHIFT); + + mmio_write_32(handle->ctrl.sdRegBaseAddr + SD4_EMMC_TOP_CTRL1_OFFSET, + ctl_val); + + /* enable all interrupt status */ + mmio_write_32(handle->ctrl.sdRegBaseAddr + SD4_EMMC_TOP_INTREN1_OFFSET, + 0); + mmio_write_32(handle->ctrl.sdRegBaseAddr + SD4_EMMC_TOP_INTREN2_OFFSET, + 0); + + SD_US_DELAY(100); + + mmio_write_32(handle->ctrl.sdRegBaseAddr + SD4_EMMC_TOP_INTREN1_OFFSET, + SD_NOR_INTERRUPTS | SD_ERR_INTERRUPTS); + mmio_write_32(handle->ctrl.sdRegBaseAddr + SD4_EMMC_TOP_INTREN2_OFFSET, + SD_NOR_INTERRUPTS | SD_ERR_INTERRUPTS); + + /* Select SD bus voltage */ + cap_val_l = mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_CAPABILITIES1_OFFSET); + handle->cfg.voltage = 0; + voltage = 0x7; + + if (cap_val_l & SD4_EMMC_TOP_CAPABILITIES1_V33_MASK) { + handle->cfg.voltage |= SD_VDD_WINDOW_3_3_TO_3_4; + voltage = 0x7; + } else if (cap_val_l & SD4_EMMC_TOP_CAPABILITIES1_V3_MASK) { + handle->cfg.voltage |= SD_VDD_WINDOW_3_0_TO_3_1; + voltage = 0x6; + } else if (cap_val_l & SD4_EMMC_TOP_CAPABILITIES1_V18_MASK) { + handle->cfg.voltage |= SD_VDD_WINDOW_1_8_TO_1_9; + voltage = 0x5; + } + + rval = chal_sd_set_power(handle, voltage, SD4_EMMC_TOP_CTRL_SDPWR_MASK); + + ctl_val = mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_HCVERSIRQ_OFFSET); + handle->ctrl.version = ((ctl_val >> 16) & 0xFF); + + return rval; +} + +void chal_sd_set_speed(CHAL_HANDLE *sd_handle, uint32_t speed) +{ + struct sd_dev *handle; + + if (sd_handle == NULL) + return; + + handle = (struct sd_dev *) sd_handle; + + if (speed) { + EMMC_TRACE("enable HighSpeed\n"); + mmio_setbits_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_CTRL_OFFSET, + SD4_EMMC_TOP_CTRL_HSEN_MASK); + } else { + EMMC_TRACE("disable HighSpeed\n"); + mmio_clrbits_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_CTRL_OFFSET, + SD4_EMMC_TOP_CTRL_HSEN_MASK); + } +} + +int32_t chal_sd_stop(void) +{ + uintptr_t idm_rst_ctrl_addr = EMMC_IDM_RESET_CTRL_ADDR; + + /* Configure IO pins */ + emmc_soft_reset(); + + /* Reset the SDIO controller */ + mmio_write_32(idm_rst_ctrl_addr, 1); + SD_US_DELAY(100); + mmio_write_32(idm_rst_ctrl_addr, 0); + SD_US_DELAY(100); + + return SD_OK; +} + +/* + * Check if host supports specified capability + * returns -ve val on error, 0 if capability not supported else 1. + */ +int32_t chal_sd_check_cap(CHAL_HANDLE *sd_handle, uint32_t caps) +{ + struct sd_dev *handle; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + handle = (struct sd_dev *) sd_handle; + + if (caps & mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_CAPABILITIES1_OFFSET)) + return 1; + else + return 0; +} + +int32_t chal_sd_start(CHAL_HANDLE *sd_handle, + uint32_t mode, uint32_t sd_base, uint32_t host_base) +{ + + struct sd_dev *handle; + int32_t rval = SD_FAIL; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + handle = (struct sd_dev *) sd_handle; + + handle->cfg.mode = SD_PIO_MODE; /* set to PIO mode first for init */ + handle->cfg.dma = SD_DMA_OFF; + + chal_sd_setup_handler(handle, sd_base, host_base); + + /* init and start hw */ + rval = chal_sd_init(sd_handle); + if (rval != SD_OK) + return rval; + + chal_sd_clear_pending_irq(sd_handle); + + handle->ctrl.eventList = 0; + handle->cfg.mode = mode; + + return SD_OK; +} + +/* + * Function to check 8bits of err generated from auto CMD12 + */ +int32_t chal_sd_get_atuo12_error(CHAL_HANDLE *sd_handle) +{ + struct sd_dev *handle; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + handle = (struct sd_dev *) sd_handle; + + return (mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_ERRSTAT_OFFSET) & 0xFF); +} + +/* + * Read present state register + */ +uint32_t chal_sd_get_present_status(CHAL_HANDLE *sd_handle) +{ + struct sd_dev *handle; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + handle = (struct sd_dev *) sd_handle; + + return mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_PSTATE_OFFSET); +} + +/* + * Set SD bus width + */ +int32_t chal_sd_config_bus_width(CHAL_HANDLE *sd_handle, int32_t width) +{ + uint32_t ctl_val; + struct sd_dev *handle; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + handle = (struct sd_dev *)sd_handle; + + ctl_val = mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_CTRL_OFFSET); + + switch (width) { +#ifdef DRIVER_EMMC_ENABLE_DATA_WIDTH_8BIT + case SD_BUS_DATA_WIDTH_8BIT: + ctl_val &= ~SD_BUS_DATA_WIDTH_4BIT; + ctl_val |= SD_BUS_DATA_WIDTH_8BIT; + break; +#endif + case SD_BUS_DATA_WIDTH_4BIT: + ctl_val &= ~SD_BUS_DATA_WIDTH_8BIT; + ctl_val |= SD_BUS_DATA_WIDTH_4BIT; + break; + case SD_BUS_DATA_WIDTH_1BIT: + ctl_val &= ~(SD_BUS_DATA_WIDTH_4BIT | SD_BUS_DATA_WIDTH_8BIT); + break; + default: + return SD_INV_DATA_WIDTH; + }; + + mmio_write_32(handle->ctrl.sdRegBaseAddr + SD4_EMMC_TOP_CTRL_OFFSET, + ctl_val); + + return SD_OK; +} + +/* + * Function to enable or disable DMA control. + */ +int32_t chal_sd_set_dma(CHAL_HANDLE *sd_handle, uint32_t mode) +{ + uint32_t val; + struct sd_dev *handle; + int32_t rc; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + handle = (struct sd_dev *)sd_handle; + + if (mode) { + rc = chal_sd_check_cap(sd_handle, + SD4_EMMC_TOP_CAPABILITIES1_SDMA_MASK | + SD4_EMMC_TOP_CAPABILITIES1_ADMA2_MASK); + if (rc < 0) + return rc; + + if (rc) { + + handle->cfg.dma = mode; + val = mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_CTRL_OFFSET); + val &= ~(SD4_EMMC_TOP_CTRL_DMASEL_MASK); + val |= handle->cfg.dma - 1; + mmio_write_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_CTRL_OFFSET, val); + return SD_OK; + } + } + handle->cfg.dma = 0; + + return SD_FAIL; +} + +/* + * Get current DMA address. + * Called only when there is no data transaction activity. + */ +uintptr_t chal_sd_get_dma_addr(CHAL_HANDLE *sd_handle) +{ + struct sd_dev *handle; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + handle = (struct sd_dev *) sd_handle; + + if (handle->cfg.dma == SD_DMA_OFF) + return 0; + + return (uintptr_t)mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_SYSADDR_OFFSET); +} + +int32_t chal_sd_send_cmd(CHAL_HANDLE *sd_handle, uint32_t cmd_idx, + uint32_t argument, uint32_t options) +{ + uint32_t cmd_mode_reg = 0; + struct sd_dev *handle; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + handle = (struct sd_dev *) sd_handle; + + EMMC_TRACE("%s %d cmd:%d argReg:%x options:%x\n", + __func__, __LINE__, cmd_idx, argument, options); + + /* Configure the value for command and mode registers */ + cmd_mode_reg = (cmd_idx << 24) | options; + + /* + * 1. Write block size reg & block count reg, + * this is done in the tx or rx setup + */ + mmio_write_32(handle->ctrl.sdRegBaseAddr + SD4_EMMC_TOP_BLOCK_OFFSET, + handle->ctrl.blkReg); + + /* 2. Write argument reg */ + mmio_write_32(handle->ctrl.sdRegBaseAddr + SD4_EMMC_TOP_ARG_OFFSET, + argument); + handle->ctrl.argReg = argument; + + /* + * 3. Write transfer mode reg & command reg, check the DMA bit which is + * set before this function call if it is selected. + */ + if (cmd_idx == 24 || cmd_idx == 25 || cmd_idx == 18 || cmd_idx == 17 || + cmd_idx == 42 || cmd_idx == 51 || cmd_idx == 53) + cmd_mode_reg |= ((handle->cfg.dma) ? 1 : 0); + + mmio_write_32(handle->ctrl.sdRegBaseAddr + SD4_EMMC_TOP_CMD_OFFSET, + cmd_mode_reg); + + handle->ctrl.cmdIndex = cmd_idx; + + return SD_OK; +} + +int32_t chal_sd_set_dma_addr(CHAL_HANDLE *sd_handle, uintptr_t address) +{ + struct sd_dev *handle; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + handle = (struct sd_dev *) sd_handle; + + if (handle->cfg.dma == SD_DMA_OFF) + return SD_FAIL; + + mmio_write_32(handle->ctrl.sdRegBaseAddr + SD4_EMMC_TOP_SYSADDR_OFFSET, + address); + return SD_OK; +} + +uint32_t chal_sd_freq_2_div_ctrl_setting(uint32_t desired_freq) +{ + /* + * Divider control setting represents 1/2 of the actual divider value. + * + * DesiredFreq = BaseClockFreq / (2 * div_ctrl_setting) + * + * ==> div_ctrl_setting = BaseClockFreq / (2 * DesiredFreq) + */ + uint32_t div_ctrl_setting; + uint32_t actual_freq; + + assert(desired_freq != 0); + + /* Special case, 0 = divider of 1. */ + if (desired_freq >= BASE_CLK_FREQ) + return 0; + + /* Normal case, desired_freq < BASE_CLK_FREQ */ + div_ctrl_setting = BASE_CLK_FREQ / (2 * desired_freq); + + actual_freq = BASE_CLK_FREQ / (2 * div_ctrl_setting); + + if (actual_freq > desired_freq) { + /* + * Division does not result in exact freqency match. + * Make sure resulting frequency does not exceed requested freq. + */ + div_ctrl_setting++; + } + + return div_ctrl_setting; +} + +int32_t chal_sd_set_clock(CHAL_HANDLE *sd_handle, uint32_t div_ctrl_setting, + uint32_t on) +{ + uint32_t value; + struct sd_dev *handle; + uint32_t time; + uint32_t clk_sel_high_byte = 0xFF & (div_ctrl_setting >> 8); + uint32_t clk_sel_low_byte = 0xFF & div_ctrl_setting; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + EMMC_TRACE("set_clock(div_ctrl_setting=%d,on=%d)\n", + div_ctrl_setting, on); + + handle = (struct sd_dev *) sd_handle; + + /* Read control register content. */ + value = mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_CTRL1_OFFSET); + + /* Disable Clock */ + value &= ~(SD4_EMMC_TOP_CTRL1_SDCLKEN_MASK); + + mmio_write_32(handle->ctrl.sdRegBaseAddr + SD4_EMMC_TOP_CTRL1_OFFSET, + value); + + /* Clear bits of interest. */ + value &= ~(SD4_EMMC_TOP_CTRL1_SDCLKSEL_MASK | + SD4_EMMC_TOP_CTRL1_SDCLKSEL_UP_MASK); + + /* Set bits of interest to new value. */ + value |= (SD4_EMMC_TOP_CTRL1_SDCLKSEL_MASK & + (clk_sel_low_byte << SD4_EMMC_TOP_CTRL1_SDCLKSEL_SHIFT)); + value |= (SD4_EMMC_TOP_CTRL1_SDCLKSEL_UP_MASK & + (clk_sel_high_byte << SD4_EMMC_TOP_CTRL1_SDCLKSEL_UP_SHIFT)); + value |= SD4_EMMC_TOP_CTRL1_ICLKEN_MASK; + + /* Write updated value back to control register. */ + mmio_write_32(handle->ctrl.sdRegBaseAddr + SD4_EMMC_TOP_CTRL1_OFFSET, + value); + + time = 0; + do { + value = mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_CTRL1_OFFSET); + + if ((value & SD4_EMMC_TOP_CTRL1_ICLKSTB_MASK) == + SD4_EMMC_TOP_CTRL1_ICLKSTB_MASK) + break; + + mdelay(1); + } while (time++ < EMMC_CLOCK_SETTING_TIMEOUT_MS); + + if (time >= EMMC_CLOCK_SETTING_TIMEOUT_MS) + WARN("%s %d clock settings timeout happenedi (%dms)\n", + __func__, __LINE__, time); + + VERBOSE("EMMC: clock settings delay: %dms\n", time); + + value = mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_CTRL1_OFFSET); + + if (on) + value |= SD4_EMMC_TOP_CTRL1_SDCLKEN_MASK; + + mmio_write_32(handle->ctrl.sdRegBaseAddr + SD4_EMMC_TOP_CTRL1_OFFSET, + value); + + return SD_OK; +} + +/* + * function to setup DMA buffer and data length, calculates block + * size and the number of blocks to be transferred and return + * the DMA buffer address. + */ +int32_t chal_sd_setup_xfer(CHAL_HANDLE *sd_handle, + uint8_t *data, uint32_t length, int32_t dir) +{ + uint32_t blocks = 0; + struct sd_dev *handle; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + handle = (struct sd_dev *) sd_handle; + + if (length <= handle->cfg.blockSize) { + handle->ctrl.blkReg = length | handle->cfg.dmaBoundary; + } else { + blocks = length / handle->cfg.blockSize; + handle->ctrl.blkReg = (blocks << 16) | handle->cfg.blockSize | + handle->cfg.dmaBoundary; + } + + if (handle->cfg.dma != SD_DMA_OFF) { + /* For DMA target address setting, physical address should be used */ + mmio_write_32(handle->ctrl.sdRegBaseAddr + SD4_EMMC_TOP_SYSADDR_OFFSET, + (uintptr_t)data); + } + + return SD_OK; +} + +#ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE +/* + * function to write one block data directly to the + * host controller's FIFO which is 1K uint8_t or + * 2K uint8_t in size. + * It is used in Non-DMA mode for data transmission. + */ +int32_t chal_sd_write_buffer(CHAL_HANDLE *sd_handle, uint32_t length, + uint8_t *data) +{ + uint32_t i, leftOver = 0, blockSize, size, value = 0; + struct sd_dev *handle; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + handle = (struct sd_dev *) sd_handle; + + blockSize = handle->cfg.blockSize; + + if (length == 0) + return SD_OK; + + /* PIO mode, push into fifo word by word */ + if (length >= blockSize) { + size = blockSize; + } else { + size = ((length >> 2) << 2); + leftOver = length % 4; + } + + for (i = 0; i < size; i += 4) { + value = *(uint32_t *)(data + i); + mmio_write_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_BUFDAT_OFFSET, value); + } +/* + * BUG ALERT: + * This implementation has TWO issues that must be addressed before you + * can safely INCLUDE_EMMC_DRIVER_WRITE_CODE. + * + * (1) For the last leftOver bytes, driver writes full word, which means + * some of the eMMC content (i.e. "4 - leftOver" will be erroneously + * overwritten). + * (2) eMMC is a block device. What happens when less than a full block of + * data is submitted??? + */ + if (leftOver > 0) { + value = ((*(uint32_t *)(data + i)) << (4 - leftOver)); + mmio_write_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_BUFDAT_OFFSET, value); + } + + return SD_OK; +} +#endif /* INCLUDE_EMMC_DRIVER_WRITE_CODE */ + +/* + * Function to read maximal one block data directly + * from the data port of the host controller (FIFO). It is used + * in Non-DMA mode for data transmission. + */ +int32_t chal_sd_read_buffer(CHAL_HANDLE *sd_handle, uint32_t length, + uint8_t *data) +{ + uint32_t i, size, leftOver, blockSize, value; + struct sd_dev *handle; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + handle = (struct sd_dev *)sd_handle; + + value = 0; + + blockSize = handle->cfg.blockSize; + + /* PIO mode, extract fifo word by word */ + if (length >= blockSize) { + size = blockSize; + leftOver = 0; + } else { + leftOver = length % 4; + size = ((length >> 2) << 2); + } + + for (i = 0; i < size; i += 4) { + value = + mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_BUFDAT_OFFSET); + memcpy((void *)(data + i), &value, sizeof(uint32_t)); + } + + if (leftOver > 0) { + value = mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_BUFDAT_OFFSET); + + /* + * Copy remaining non-full word bytes. + * (We run ARM as Little Endian) + */ + uint8_t j = 0; + + for (j = 0; j < leftOver; j++) { + data[i + j] = (value >> (j * 8)) & 0xFF; + } + } + + return SD_OK; +} + +/* + * Resets both DAT or CMD line. + */ +int32_t chal_sd_reset_line(CHAL_HANDLE *sd_handle, uint32_t line) +{ + uint32_t control, flag; + struct sd_dev *handle; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + handle = (struct sd_dev *) sd_handle; + + flag = SD4_EMMC_TOP_CTRL1_CMDRST_MASK | SD4_EMMC_TOP_CTRL1_DATRST_MASK; + + if (flag != (line | flag)) + return SD_FAIL; + + control = mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_CTRL1_OFFSET); + control |= line; + mmio_write_32(handle->ctrl.sdRegBaseAddr + SD4_EMMC_TOP_CTRL1_OFFSET, + control); + + /* reset CMD and DATA line should always work, no need to timed out */ + do { + control = mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_CTRL1_OFFSET); + } while (control & line); + + return SD_OK; +} + +/* + * Function to be called once a SD command is done to read + * back it's response data. + */ +int32_t chal_sd_get_response(CHAL_HANDLE *sd_handle, uint32_t *resp) +{ + struct sd_dev *handle; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + handle = (struct sd_dev *) sd_handle; + resp[0] = mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_RESP0_OFFSET); + resp[1] = mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_RESP2_OFFSET); + resp[2] = mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_RESP4_OFFSET); + resp[3] = mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_RESP6_OFFSET); + + return SD_OK; +} + +/* + * The function is called to clean all the pending interrupts. + */ +int32_t chal_sd_clear_pending_irq(CHAL_HANDLE *sd_handle) +{ + uint32_t status = SD_OK; + struct sd_dev *handle; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + handle = (struct sd_dev *)sd_handle; + + /* Make sure clean all interrupts */ + do { + mmio_write_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_INTR_OFFSET, 0xFFFFFFFF); + SD_US_DELAY(10); + } while (mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_INTR_OFFSET)); + + return status; +} + +/* + * The function returns interrupt status register value. + */ +int32_t chal_sd_get_irq_status(CHAL_HANDLE *sd_handle) +{ + struct sd_dev *handle; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + handle = (struct sd_dev *) sd_handle; + + return (mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_INTR_OFFSET)); +} + +/* + * The function clears interrupt(s) specified in the mask. + */ +int32_t chal_sd_clear_irq(CHAL_HANDLE *sd_handle, uint32_t mask) +{ + struct sd_dev *handle; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + handle = (struct sd_dev *) sd_handle; + + /* Make sure clean masked interrupts */ + do { + mmio_write_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_INTR_OFFSET, mask); + SD_US_DELAY(10); + } while (mask & + mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_INTR_OFFSET)); + + return SD_OK; +} + +/* + * Description: The function configures the SD host controller. + */ +int32_t chal_sd_config(CHAL_HANDLE *sd_handle, uint32_t speed, uint32_t retry, + uint32_t boundary, uint32_t blkSize, uint32_t dma) +{ + struct sd_dev *handle; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + handle = (struct sd_dev *) sd_handle; + + handle->cfg.speedMode = speed; + handle->cfg.retryLimit = retry; + handle->cfg.dmaBoundary = boundary; + handle->cfg.blockSize = blkSize; + + chal_sd_set_dma(sd_handle, dma); + SD_US_DELAY(100); + chal_sd_set_dma_boundary(handle, boundary); + SD_US_DELAY(100); + + chal_sd_set_speed(sd_handle, speed); + + SD_US_DELAY(100); + return SD_OK; +} + +/* + * Cleans up HC FIFO. + */ +void chal_sd_dump_fifo(CHAL_HANDLE *sd_handle) +{ + struct sd_dev *handle; + + if (sd_handle == NULL) + return; + + handle = (struct sd_dev *)sd_handle; + + /* in case there still data in the host buffer */ + while (mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_PSTATE_OFFSET) & 0x800) { + mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_BUFDAT_OFFSET); + }; +} + +/* + * Enable or disable a SD interrupt signal. + */ +void chal_sd_set_irq_signal(CHAL_HANDLE *sd_handle, uint32_t mask, + uint32_t state) +{ + struct sd_dev *handle; + + if (sd_handle == NULL) + return; + + handle = (struct sd_dev *)sd_handle; + + if (state) + mmio_setbits_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_INTREN2_OFFSET, mask); + else + mmio_clrbits_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_INTREN2_OFFSET, mask); +} diff --git a/drivers/brcm/emmc/emmc_csl_sdcard.c b/drivers/brcm/emmc/emmc_csl_sdcard.c new file mode 100644 index 000000000..d6ad4bc9c --- /dev/null +++ b/drivers/brcm/emmc/emmc_csl_sdcard.c @@ -0,0 +1,1087 @@ +/* + * Copyright (c) 2016 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include +#include + +#include "bcm_emmc.h" +#include "emmc_chal_types.h" +#include "emmc_csl_sdprot.h" +#include "emmc_chal_sd.h" +#include "emmc_csl_sdcmd.h" +#include "emmc_csl_sd.h" +#include "emmc_pboot_hal_memory_drv.h" + +#define SD_CARD_BUSY 0x80000000 +#define SD_CARD_RETRY_LIMIT 1000 +#define SD_CARD_HIGH_SPEED_PS 13 +#define SD_CHK_HIGH_SPEED_MODE 0x00FFFFF1 +#define SD_SET_HIGH_SPEED_MODE 0x80FFFFF1 +#define SD_MMC_ENABLE_HIGH_SPEED 0x03b90100 //0x03b90103 +#define SD_MMC_8BIT_MODE 0x03b70200 +#define SD_MMC_4BIT_MODE 0x03b70100 +#define SD_MMC_1BIT_MODE 0x03b70000 + +#define SD_MMC_BOOT_8BIT_MODE 0x03b10200 +#define SD_MMC_BOOT_4BIT_MODE 0x03b10100 +#define SD_MMC_BOOT_1BIT_MODE 0x03b10000 +#define SDIO_HW_EMMC_EXT_CSD_BOOT_CNF 0X03B30000 + +#ifdef USE_EMMC_FIP_TOC_CACHE +/* + * Cache size mirrors the size of the global eMMC temp buffer + * which is used for non-image body reads such as headers, ToC etc. + */ +#define CACHE_SIZE ((EMMC_BLOCK_SIZE) * 2) +#define PARTITION_BLOCK_ADDR ((PLAT_FIP_ATTEMPT_OFFSET)/(EMMC_BLOCK_SIZE)) + +static uint32_t cached_partition_block; +static uint8_t cached_block[CACHE_SIZE]; +#endif + +static int set_card_data_width(struct sd_handle *handle, int width); +static int abort_err(struct sd_handle *handle); +static int err_recovery(struct sd_handle *handle, uint32_t errors); +static int xfer_data(struct sd_handle *handle, uint32_t mode, uint32_t addr, + uint32_t length, uint8_t *base); + +int set_boot_config(struct sd_handle *handle, uint32_t config) +{ + return mmc_cmd6(handle, SDIO_HW_EMMC_EXT_CSD_BOOT_CNF | config); +} + +void process_csd_mmc_speed(struct sd_handle *handle, uint32_t csd_mmc_speed) +{ + uint32_t div_ctrl_setting; + + /* CSD field TRAN_SPEED: + * Bits [2:0] 0 = 100 KHz + * 1 = 1 MHz + * 2 = 10 MHz + * 3 = 100 MHz + * 4...7 Reserved. + * Bits [6:3] 0 = Reserved + * 1 = 1.0 + * 2 = 1.2 + * 3 = 1.3 + * 4 = 1.5 + * 5 = 2.0 + * 6 = 2.6 + * 7 = 3.0 + * 8 = 3.5 + * 9 = 4.0 + * A = 4.5 + * B = 5.2 + * C = 5.5 + * D = 6.0 + * E = 7.0 + * F = 8.0 + * For cards supporting version 4.0, 4.1, and 4.2 of the standard, + * the value shall be 20 MHz (0x2A). + * For cards supporting version 4.3 , the value shall be 26 MHz (0x32) + */ + + switch (csd_mmc_speed & 0x7F) { + case 0x2A: + EMMC_TRACE("Speeding up eMMC clock to 20MHz\n"); + div_ctrl_setting = + chal_sd_freq_2_div_ctrl_setting(20 * 1000 * 1000); + break; + case 0x32: + EMMC_TRACE("Speeding up eMMC clock to 26MHz\n"); + div_ctrl_setting = + chal_sd_freq_2_div_ctrl_setting(26 * 1000 * 1000); + break; + default: + /* Unknown */ + return; + } + + chal_sd_set_clock((CHAL_HANDLE *) handle->device, div_ctrl_setting, 0); + + chal_sd_set_clock((CHAL_HANDLE *) handle->device, div_ctrl_setting, 1); + + SD_US_DELAY(1000); +} + + +/* + * The function changes SD/SDIO/MMC card data width if + * the card support configurable data width. The host controller + * and the card has to be in the same bus data width. + */ +int set_card_data_width(struct sd_handle *handle, int width) +{ + uint32_t data_width = 0; + int is_valid_arg = 1; + int rc = SD_FAIL; + char *bitwidth_str = " "; + char *result_str = "failed"; + + switch (width) { +#ifdef DRIVER_EMMC_ENABLE_DATA_WIDTH_8BIT + case SD_BUS_DATA_WIDTH_8BIT: + data_width = SD_MMC_8BIT_MODE; +#if LOG_LEVEL >= LOG_LEVEL_VERBOSE + bitwidth_str = "8_BIT"; +#endif + break; +#endif + case SD_BUS_DATA_WIDTH_4BIT: + data_width = SD_MMC_4BIT_MODE; +#if LOG_LEVEL >= LOG_LEVEL_VERBOSE + bitwidth_str = "4_BIT"; +#endif + break; + + case SD_BUS_DATA_WIDTH_1BIT: + data_width = SD_MMC_1BIT_MODE; +#if LOG_LEVEL >= LOG_LEVEL_VERBOSE + bitwidth_str = "1_BIT"; +#endif + break; + + default: + is_valid_arg = 0; +#if LOG_LEVEL >= LOG_LEVEL_VERBOSE + bitwidth_str = "unknown"; +#endif + break; + } + + if (is_valid_arg) { + rc = mmc_cmd6(handle, data_width); + if (rc == SD_OK) { +#if LOG_LEVEL >= LOG_LEVEL_VERBOSE + result_str = "succeeded"; +#endif + chal_sd_config_bus_width((CHAL_HANDLE *) handle->device, + width); + } else { +#if LOG_LEVEL >= LOG_LEVEL_VERBOSE + result_str = "failed"; +#endif + } + } else { + rc = SD_FAIL; +#if LOG_LEVEL >= LOG_LEVEL_VERBOSE + result_str = "ignored"; +#endif + } + + VERBOSE("SDIO Data Width(%s) %s.\n", bitwidth_str, result_str); + + return rc; +} + + +/* + * Error handling routine. Does abort data + * transmission if error is found. + */ +static int abort_err(struct sd_handle *handle) +{ + uint32_t present, options, event, rel = 0; + struct sd_resp cmdRsp; + + handle->device->ctrl.argReg = 0; + handle->device->ctrl.cmdIndex = SD_CMD_STOP_TRANSMISSION; + + options = (SD_CMD_STOP_TRANSMISSION << 24) | + (SD_CMDR_RSP_TYPE_R1b_5b << SD_CMDR_RSP_TYPE_S) | + SD4_EMMC_TOP_CMD_CRC_EN_MASK | + SD4_EMMC_TOP_CMD_CCHK_EN_MASK; + + chal_sd_send_cmd((CHAL_HANDLE *) handle->device, + handle->device->ctrl.cmdIndex, + handle->device->ctrl.argReg, options); + + event = wait_for_event(handle, + SD4_EMMC_TOP_INTR_CMDDONE_MASK | + SD_ERR_INTERRUPTS, + handle->device->cfg.wfe_retry); + + if (event & SD_CMD_ERROR_INT) { + rel = SD_ERROR_NON_RECOVERABLE; + } else { + if (event & SD_DAT_TIMEOUT) { + return SD_ERROR_NON_RECOVERABLE; + } + + chal_sd_get_response((CHAL_HANDLE *) handle->device, + (uint32_t *)&cmdRsp); + + process_cmd_response(handle, handle->device->ctrl.cmdIndex, + cmdRsp.data.r2.rsp1, cmdRsp.data.r2.rsp2, + cmdRsp.data.r2.rsp3, cmdRsp.data.r2.rsp4, + &cmdRsp); + + SD_US_DELAY(2000); + + present = + chal_sd_get_present_status((CHAL_HANDLE *) handle->device); + + if ((present & 0x00F00000) == 0x00F00000) + rel = SD_ERROR_RECOVERABLE; + else + rel = SD_ERROR_NON_RECOVERABLE; + } + + return rel; +} + + +/* + * The function handles real data transmission on both DMA and + * none DMA mode, In None DMA mode the data transfer starts + * when the command is sent to the card, data has to be written + * into the host contollers buffer at this time one block + * at a time. + * In DMA mode, the real data transfer is done by the DMA engine + * and this functions just waits for the data transfer to complete. + * + */ +int process_data_xfer(struct sd_handle *handle, uint8_t *buffer, uint32_t addr, + uint32_t length, int dir) +{ + if (dir == SD_XFER_HOST_TO_CARD) { +#ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE + if (handle->device->cfg.dma == SD_DMA_OFF) { + /* + * In NON DMA mode, the real data xfer starts from here + */ + if (write_buffer(handle, length, buffer)) + return SD_WRITE_ERROR; + } else { + wait_for_event(handle, + SD4_EMMC_TOP_INTR_TXDONE_MASK | + SD_ERR_INTERRUPTS, + handle->device->cfg.wfe_retry); + + if (handle->device->ctrl.cmdStatus == SD_OK) + return SD_OK; + + check_error(handle, handle->device->ctrl.cmdStatus); + return SD_WRITE_ERROR; + } +#else + return SD_WRITE_ERROR; +#endif + } else { /* SD_XFER_CARD_TO_HOST */ + + if (handle->device->cfg.dma == SD_DMA_OFF) { + /* In NON DMA mode, the real data + * transfer starts from here + */ + if (read_buffer(handle, length, buffer)) + return SD_READ_ERROR; + + } else { /* for DMA mode */ + + /* + * once the data transmission is done + * copy data to the host buffer. + */ + wait_for_event(handle, + SD4_EMMC_TOP_INTR_TXDONE_MASK | + SD_ERR_INTERRUPTS, + handle->device->cfg.wfe_retry); + + if (handle->device->ctrl.cmdStatus == SD_OK) + return SD_OK; + + check_error(handle, handle->device->ctrl.cmdStatus); + return SD_READ_ERROR; + } + } + return SD_OK; +} + + +/* + * The function sets block size for the next SD/SDIO/MMC + * card read/write command. + */ +int select_blk_sz(struct sd_handle *handle, uint16_t size) +{ + return sd_cmd16(handle, size); +} + + +/* + * The function initalizes the SD/SDIO/MMC/CEATA and detects + * the card according to the flag of detection. + * Once this function is called, the card is put into ready state + * so application can do data transfer to and from the card. + */ +int init_card(struct sd_handle *handle, int detection) +{ + /* + * After Reset, eMMC comes up in 1 Bit Data Width by default. + * Set host side to match. + */ + chal_sd_config_bus_width((CHAL_HANDLE *) handle->device, + SD_BUS_DATA_WIDTH_1BIT); + +#ifdef USE_EMMC_FIP_TOC_CACHE + cached_partition_block = 0; +#endif + handle->device->ctrl.present = 0; /* init card present to be no card */ + + init_mmc_card(handle); + + handle->device->ctrl.present = 1; /* card is detected */ + + /* switch the data width back */ + if (handle->card->type != SD_CARD_MMC) + return SD_FAIL; + + /* + * Dynamically set Data Width to highest supported value. + * Try different data width settings (highest to lowest). + * Verify each setting by reading EXT_CSD and comparing + * against the EXT_CSD contents previously read in call to + * init_mmc_card() earlier. Stop at first verified data width + * setting. + */ + { +#define EXT_CSD_PROPERTIES_SECTION_START_INDEX 192 +#define EXT_CSD_PROPERTIES_SECTION_END_INDEX 511 + uint8_t buffer[EXT_CSD_SIZE]; +#ifdef DRIVER_EMMC_ENABLE_DATA_WIDTH_8BIT + /* Try 8 Bit Data Width */ + chal_sd_config_bus_width((CHAL_HANDLE *) handle->device, + SD_BUS_DATA_WIDTH_8BIT); + if ((!set_card_data_width(handle, SD_BUS_DATA_WIDTH_8BIT)) && + (!mmc_cmd8(handle, buffer)) && + (!memcmp(&buffer[EXT_CSD_PROPERTIES_SECTION_START_INDEX], + &(emmc_global_buf_ptr->u.Ext_CSD_storage[EXT_CSD_PROPERTIES_SECTION_START_INDEX]), + EXT_CSD_PROPERTIES_SECTION_END_INDEX - EXT_CSD_PROPERTIES_SECTION_START_INDEX + 1))) + + return SD_OK; +#endif + /* Fall back to 4 Bit Data Width */ + chal_sd_config_bus_width((CHAL_HANDLE *) handle->device, + SD_BUS_DATA_WIDTH_4BIT); + if ((!set_card_data_width(handle, SD_BUS_DATA_WIDTH_4BIT)) && + (!mmc_cmd8(handle, buffer)) && + (!memcmp(&buffer[EXT_CSD_PROPERTIES_SECTION_START_INDEX], + &(emmc_global_buf_ptr->u.Ext_CSD_storage[EXT_CSD_PROPERTIES_SECTION_START_INDEX]), + EXT_CSD_PROPERTIES_SECTION_END_INDEX - EXT_CSD_PROPERTIES_SECTION_START_INDEX + 1))) + + return SD_OK; + + /* Fall back to 1 Bit Data Width */ + chal_sd_config_bus_width((CHAL_HANDLE *) handle->device, + SD_BUS_DATA_WIDTH_1BIT); + /* Just use 1 Bit Data Width then. */ + if (!set_card_data_width(handle, SD_BUS_DATA_WIDTH_1BIT)) + return SD_OK; + + } + return SD_CARD_INIT_ERROR; +} + + +/* + * The function handles MMC/CEATA card initalization. + */ +int init_mmc_card(struct sd_handle *handle) +{ + uint32_t ocr = 0, newOcr, rc, limit = 0; + uint32_t cmd1_option = 0x40300000; + uint32_t sec_count; + + handle->card->type = SD_CARD_MMC; + + do { + SD_US_DELAY(1000); + newOcr = 0; + ocr = 0; + rc = sd_cmd1(handle, cmd1_option, &newOcr); + limit++; + + if (rc == SD_OK) + ocr = newOcr; + + } while (((ocr & SD_CARD_BUSY) == 0) && (limit < SD_CARD_RETRY_LIMIT)); + + if (limit >= SD_CARD_RETRY_LIMIT) { + handle->card->type = SD_CARD_UNKNOWN; + EMMC_TRACE("CMD1 Timeout: Device is not ready\n"); + return SD_CARD_UNKNOWN; + } + + /* Save the ocr register */ + handle->device->ctrl.ocr = ocr; + + /* Ready State */ + rc = sd_cmd2(handle); + if (rc != SD_OK) { + handle->card->type = SD_CARD_UNKNOWN; + return SD_CARD_UNKNOWN; + } + + rc = sd_cmd3(handle); + if (rc != SD_OK) { + handle->card->type = SD_CARD_UNKNOWN; + return SD_CARD_UNKNOWN; + } + /* read CSD */ + rc = sd_cmd9(handle, &emmc_global_vars_ptr->cardData); + if (rc != SD_OK) { + handle->card->type = SD_CARD_UNKNOWN; + return SD_CARD_UNKNOWN; + } + + /* Increase clock frequency according to what the card advertises */ + EMMC_TRACE("From CSD... cardData.csd.mmc.speed = 0x%X\n", + emmc_global_vars_ptr->cardData.csd.mmc.speed); + process_csd_mmc_speed(handle, + emmc_global_vars_ptr->cardData.csd.mmc.speed); + + /* goto transfer mode */ + rc = sd_cmd7(handle, handle->device->ctrl.rca); + if (rc != SD_OK) { + handle->card->type = SD_CARD_UNKNOWN; + return SD_CARD_UNKNOWN; + } + + rc = mmc_cmd8(handle, emmc_global_buf_ptr->u.Ext_CSD_storage); + if (rc == SD_OK) { + /* calcul real capacity */ + sec_count = emmc_global_buf_ptr->u.Ext_CSD_storage[212] | + emmc_global_buf_ptr->u.Ext_CSD_storage[213] << 8 | + emmc_global_buf_ptr->u.Ext_CSD_storage[214] << 16 | + emmc_global_buf_ptr->u.Ext_CSD_storage[215] << 24; + + EMMC_TRACE("Device density = %ldMBytes\n", + handle->card->size / (1024 * 1024)); + + if (sec_count > 0) { + handle->card->size = (uint64_t)sec_count * 512; + + EMMC_TRACE("Updated Device density = %ldMBytes\n", + handle->card->size / (1024 * 1024)); + } + + if (sec_count > (2u * 1024 * 1024 * 1024) / 512) { + handle->device->ctrl.ocr |= SD_CARD_HIGH_CAPACITY; + handle->device->cfg.blockSize = 512; + } + + if (handle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) + EMMC_TRACE("Sector addressing\n"); + else + EMMC_TRACE("Byte addressing\n"); + + EMMC_TRACE("Ext_CSD_storage[162]: 0x%02X Ext_CSD_storage[179]: 0x%02X\n", + emmc_global_buf_ptr->u.Ext_CSD_storage[162], + emmc_global_buf_ptr->u.Ext_CSD_storage[179]); + } + + return handle->card->type; +} + + +/* + * The function send reset command to the card. + * The card will be in ready status after the reset. + */ +int reset_card(struct sd_handle *handle) +{ + int res = SD_OK; + + /* on reset, card's RCA should return to 0 */ + handle->device->ctrl.rca = 0; + + res = sd_cmd0(handle); + + if (res != SD_OK) + return SD_RESET_ERROR; + + return res; +} + + +/* + * The function sends command to the card and starts + * data transmission. + */ +static int xfer_data(struct sd_handle *handle, + uint32_t mode, + uint32_t addr, uint32_t length, uint8_t *base) +{ + int rc = SD_OK; + + VERBOSE("XFER: dest: 0x%llx, addr: 0x%x, size: 0x%x bytes\n", + (uint64_t)base, addr, length); + + if ((length / handle->device->cfg.blockSize) > 1) { + if (mode == SD_OP_READ) { + inv_dcache_range((uintptr_t)base, (uint64_t)length); + rc = sd_cmd18(handle, addr, length, base); + } else { +#ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE + flush_dcache_range((uintptr_t)base, (uint64_t)length); + rc = sd_cmd25(handle, addr, length, base); +#else + rc = SD_DATA_XFER_ERROR; +#endif + } + } else { + if (mode == SD_OP_READ) { + inv_dcache_range((uintptr_t)base, (uint64_t)length); + rc = sd_cmd17(handle, addr, + handle->device->cfg.blockSize, base); + } else { +#ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE + flush_dcache_range((uintptr_t)base, (uint64_t)length); + rc = sd_cmd24(handle, addr, + handle->device->cfg.blockSize, base); +#else + rc = SD_DATA_XFER_ERROR; +#endif + } + } + + if (rc != SD_OK) + return SD_DATA_XFER_ERROR; + + return SD_OK; +} + +#ifdef INCLUDE_EMMC_DRIVER_ERASE_CODE +int erase_card(struct sd_handle *handle, uint32_t addr, uint32_t blocks) +{ + uint32_t end_addr; + + INFO("ERASE: addr: 0x%x, num of sectors: 0x%x\n", addr, blocks); + + if (sd_cmd35(handle, addr) != SD_OK) + return SD_FAIL; + + end_addr = addr + blocks - 1; + if (sd_cmd36(handle, end_addr) != SD_OK) + return SD_FAIL; + + if (sd_cmd38(handle) != SD_OK) + return SD_FAIL; + + return SD_OK; +} +#endif + +/* + * The function reads block data from a card. + */ +#ifdef USE_EMMC_FIP_TOC_CACHE +int read_block(struct sd_handle *handle, + uint8_t *dst, uint32_t addr, uint32_t len) +{ + int rel = SD_OK; + + /* + * Avoid doing repeated reads of the partition block + * by caching. + */ + if (cached_partition_block && + addr == PARTITION_BLOCK_ADDR && + len == CACHE_SIZE) { + memcpy(dst, cached_block, len); + } else { + rel = xfer_data(handle, SD_OP_READ, addr, len, dst); + + if (len == CACHE_SIZE && addr == PARTITION_BLOCK_ADDR) { + cached_partition_block = 1; + memcpy(cached_block, dst, len); + } + } + + return rel; +} +#else +int read_block(struct sd_handle *handle, + uint8_t *dst, uint32_t addr, uint32_t len) +{ + return xfer_data(handle, SD_OP_READ, addr, len, dst); +} +#endif + +#ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE + +/* + * The function writes block data to a card. + */ +int write_block(struct sd_handle *handle, + uint8_t *src, uint32_t addr, uint32_t len) +{ + int rel = SD_OK; + + /* + * Current HC has problem to get response of cmd16 after cmd12, + * the delay is necessary to sure the next cmd16 will not be timed out. + * The delay has to be at least 4 ms. + * The code removed cmd16 and use cmd13 to get card status before + * sending cmd18 or cmd25 to make sure the card is ready and thus + * no need to have delay here. + */ + + rel = xfer_data(handle, SD_OP_WRITE, addr, len, src); + + EMMC_TRACE("wr_blk addr:0x%08X src:0x%08X len:0x%08X result:%d\n", + addr, src, len, rel); + + return rel; +} + + +/* + * The function is called to write one block data directly to + * a card's data buffer. + * it is used in Non-DMA mode for card data transmission. + */ +int write_buffer(struct sd_handle *handle, uint32_t length, uint8_t *data) +{ + uint32_t rem, blockSize, event; + uint8_t *pData = data; + + blockSize = handle->device->cfg.blockSize; + rem = length; + + if (rem == 0) + return SD_OK; + + while (rem > 0) { + + event = wait_for_event(handle, + SD4_EMMC_TOP_INTR_BWRDY_MASK | + SD_ERR_INTERRUPTS, + handle->device->cfg.wfe_retry); + + if (handle->device->ctrl.cmdStatus) { + check_error(handle, handle->device->ctrl.cmdStatus); + return SD_WRITE_ERROR; + } + + if (rem >= blockSize) + chal_sd_write_buffer((CHAL_HANDLE *) handle->device, + blockSize, pData); + else + chal_sd_write_buffer((CHAL_HANDLE *) handle->device, + rem, pData); + + if (rem > blockSize) { + rem -= blockSize; + pData += blockSize; + } else { + pData += rem; + rem = 0; + } + } + + if ((event & SD4_EMMC_TOP_INTR_TXDONE_MASK) != + SD4_EMMC_TOP_INTR_TXDONE_MASK) { + event = wait_for_event(handle, + SD4_EMMC_TOP_INTR_TXDONE_MASK | + SD_ERR_INTERRUPTS, + handle->device->cfg.wfe_retry); + + if (handle->device->ctrl.cmdStatus != SD_OK) { + check_error(handle, handle->device->ctrl.cmdStatus); + return SD_WRITE_ERROR; + } + } else { + handle->device->ctrl.eventList &= ~SD4_EMMC_TOP_INTR_TXDONE_MASK; + } + + return SD_OK; +} +#endif /* INCLUDE_EMMC_DRIVER_WRITE_CODE */ + + +/* + * The function is called to read maximal one block data + * directly from a card + * It is used in Non-DMA mode for card data transmission. + */ +int read_buffer(struct sd_handle *handle, uint32_t length, uint8_t *data) +{ + uint32_t rem, blockSize, event = 0; + uint8_t *pData = data; + + blockSize = handle->device->cfg.blockSize; + rem = length; + + if (rem == 0) + return SD_OK; + + while (rem > 0) { + event = wait_for_event(handle, + SD4_EMMC_TOP_INTR_BRRDY_MASK | + SD_ERR_INTERRUPTS, + handle->device->cfg.wfe_retry); + + if (handle->device->ctrl.cmdStatus) { + check_error(handle, handle->device->ctrl.cmdStatus); + return SD_READ_ERROR; + } + + if (rem >= blockSize) + chal_sd_read_buffer((CHAL_HANDLE *) handle->device, + blockSize, pData); + else + chal_sd_read_buffer((CHAL_HANDLE *) handle->device, rem, + pData); + + if (rem > blockSize) { + rem -= blockSize; + pData += blockSize; + } else { + pData += rem; + rem = 0; + } + } + + /* In case, there are extra data in the SD FIFO, just dump them. */ + chal_sd_dump_fifo((CHAL_HANDLE *) handle->device); + + if ((event & SD4_EMMC_TOP_INTR_TXDONE_MASK) != + SD4_EMMC_TOP_INTR_TXDONE_MASK) { + event = wait_for_event(handle, SD4_EMMC_TOP_INTR_TXDONE_MASK, + handle->device->cfg.wfe_retry); + + if (handle->device->ctrl.cmdStatus) { + check_error(handle, handle->device->ctrl.cmdStatus); + return SD_READ_ERROR; + } + } else { + handle->device->ctrl.eventList &= ~SD4_EMMC_TOP_INTR_TXDONE_MASK; + } + + return SD_OK; +} + + +/* + * Error handling routine. + * The function just reset the DAT + * and CMD line if an error occures during data transmission. + */ +int check_error(struct sd_handle *handle, uint32_t ints) +{ + uint32_t rel; + + chal_sd_set_irq_signal((CHAL_HANDLE *) handle->device, + SD_ERR_INTERRUPTS, 0); + + if (ints & SD4_EMMC_TOP_INTR_CMDERROR_MASK) { + + chal_sd_reset_line((CHAL_HANDLE *) handle->device, + SD4_EMMC_TOP_CTRL1_CMDRST_MASK); + rel = abort_err(handle); + + chal_sd_reset_line((CHAL_HANDLE *) handle->device, + SD4_EMMC_TOP_CTRL1_DATRST_MASK); + chal_sd_set_irq_signal((CHAL_HANDLE *) handle->device, + SD_ERR_INTERRUPTS, 1); + + return (rel == SD_ERROR_NON_RECOVERABLE) ? + SD_ERROR_NON_RECOVERABLE : SD_ERROR_RECOVERABLE; + } else { + rel = err_recovery(handle, ints); + } + + chal_sd_set_irq_signal((CHAL_HANDLE *) handle->device, + SD_ERR_INTERRUPTS, 1); + + return rel; +} + + +/* + * Error recovery routine. + * Try to recover from the error. + */ +static int err_recovery(struct sd_handle *handle, uint32_t errors) +{ + uint32_t rel = 0; + + /* + * In case of timeout error, the cmd line and data line maybe + * still active or stuck at atcitve so it is needed to reset + * either data line or cmd line to make sure a new cmd can be sent. + */ + + if (errors & SD_CMD_ERROR_INT) + chal_sd_reset_line((CHAL_HANDLE *) handle->device, + SD4_EMMC_TOP_CTRL1_CMDRST_MASK); + + if (errors & SD_DAT_ERROR_INT) + chal_sd_reset_line((CHAL_HANDLE *) handle->device, + SD4_EMMC_TOP_CTRL1_DATRST_MASK); + + /* Abort transaction by sending out stop command */ + if ((handle->device->ctrl.cmdIndex == 18) || + (handle->device->ctrl.cmdIndex == 25)) + rel = abort_err(handle); + + return rel; +} + + +/* + * The function is called to read one block data directly from a card. + * It is used in Non-DMA mode for card data transmission. + */ +int process_cmd_response(struct sd_handle *handle, + uint32_t cmdIndex, + uint32_t rsp0, + uint32_t rsp1, + uint32_t rsp2, uint32_t rsp3, struct sd_resp *resp) +{ + int result = SD_OK; + + /* R6 */ + uint32_t rca = (rsp0 >> 16) & 0xffff; + uint32_t cardStatus = rsp0; + + /* R4 */ + uint32_t cBit = (rsp0 >> 31) & 0x1; + uint32_t funcs = (rsp0 >> 28) & 0x7; + uint32_t memPresent = (rsp0 >> 27) & 0x1; + + resp->r1 = 0x3f; + resp->cardStatus = cardStatus; + + if (cmdIndex == SD_CMD_IO_SEND_OP_COND) { + resp->data.r4.cardReady = cBit; + resp->data.r4.funcs = funcs; + resp->data.r4.memPresent = memPresent; + resp->data.r4.ocr = cardStatus; + } + + if (cmdIndex == SD_CMD_MMC_SET_RCA) { + resp->data.r6.rca = rca; + resp->data.r6.cardStatus = cardStatus & 0xFFFF; + } + + if (cmdIndex == SD_CMD_SELECT_DESELECT_CARD) { + resp->data.r7.rca = rca; + } + + if (cmdIndex == SD_CMD_IO_RW_DIRECT) { + if (((rsp0 >> 16) & 0xffff) != 0) + result = SD_CMD_ERR_INVALID_RESPONSE; + + resp->data.r5.data = rsp0 & 0xff; + } + + if (cmdIndex == SD_CMD_IO_RW_EXTENDED) { + if (((rsp0 >> 16) & 0xffff) != 0) + result = SD_CMD_ERR_INVALID_RESPONSE; + + resp->data.r5.data = rsp0 & 0xff; + } + + if (cmdIndex == SD_ACMD_SD_SEND_OP_COND || + cmdIndex == SD_CMD_SEND_OPCOND) + resp->data.r3.ocr = cardStatus; + + if (cmdIndex == SD_CMD_SEND_CSD || + cmdIndex == SD_CMD_SEND_CID || + cmdIndex == SD_CMD_ALL_SEND_CID) { + resp->data.r2.rsp4 = rsp3; + resp->data.r2.rsp3 = rsp2; + resp->data.r2.rsp2 = rsp1; + resp->data.r2.rsp1 = rsp0; + } + + if ((cmdIndex == SD_CMD_READ_EXT_CSD) && + (handle->card->type == SD_CARD_SD)) { + if ((resp->cardStatus & 0xAA) != 0xAA) { + result = SD_CMD_ERR_INVALID_RESPONSE; + } + } + + return result; +} + + +/* + * The function sets DMA buffer and data length, process + * block size and the number of blocks to be transferred. + * It returns the DMA buffer address. + * It copies dma data from user buffer to the DMA buffer + * if the operation is to write data to the SD card. + */ +void data_xfer_setup(struct sd_handle *handle, uint8_t *data, uint32_t length, + int dir) +{ + chal_sd_setup_xfer((CHAL_HANDLE *)handle->device, data, length, dir); +} + + +/* + * The function does soft reset the host SD controller. After + * the function call all host controller's register are reset + * to default vallue; + * + * Note This function only resets the host controller it does not + * reset the controller's handler. + */ +int reset_host_ctrl(struct sd_handle *handle) +{ + chal_sd_stop(); + + return SD_OK; +} + +static void pstate_log(struct sd_handle *handle) +{ + ERROR("PSTATE: 0x%x\n", mmio_read_32 + (handle->device->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_PSTATE_SD4_OFFSET)); + ERROR("ERRSTAT: 0x%x\n", mmio_read_32 + (handle->device->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_ERRSTAT_OFFSET)); +} + +/* + * The function waits for one or a group of interrupts specified + * by mask. The function returns if any one the interrupt status + * is set. If interrupt mode is not enabled then it will poll + * the interrupt status register until a interrupt status is set + * an error interrupt happens. If interrupt mode is enabled then + * this function should be called after the interrupt + * is received by ISR routine. + */ +uint32_t wait_for_event(struct sd_handle *handle, + uint32_t mask, uint32_t retry) +{ + uint32_t regval, cmd12, time = 0; + + handle->device->ctrl.cmdStatus = 0; /* no error */ + EMMC_TRACE("%s %d mask:0x%x timeout:%d irq_status:0x%x\n", + __func__, __LINE__, mask, retry, + chal_sd_get_irq_status((CHAL_HANDLE *)handle->device)); + + /* Polling mode */ + do { + regval = chal_sd_get_irq_status((CHAL_HANDLE *)handle->device); + + if (regval & SD4_EMMC_TOP_INTR_DMAIRQ_MASK) { + chal_sd_set_dma_addr((CHAL_HANDLE *)handle->device, + (uintptr_t) + chal_sd_get_dma_addr((CHAL_HANDLE *) + handle->device)); + chal_sd_clear_irq((CHAL_HANDLE *)handle->device, + SD4_EMMC_TOP_INTR_DMAIRQ_MASK); + } + + if (time++ > retry) { + ERROR("EMMC: No response (cmd%d) after %dus.\n", + handle->device->ctrl.cmdIndex, + time * EMMC_WFE_RETRY_DELAY_US); + handle->device->ctrl.cmdStatus = SD_CMD_MISSING; + pstate_log(handle); + ERROR("EMMC: INT[0x%x]\n", regval); + break; + } + + if (regval & SD4_EMMC_TOP_INTR_CTOERR_MASK) { + ERROR("EMMC: Cmd%d timeout INT[0x%x]\n", + handle->device->ctrl.cmdIndex, regval); + handle->device->ctrl.cmdStatus = + SD4_EMMC_TOP_INTR_CTOERR_MASK; + pstate_log(handle); + break; + } + if (regval & SD_CMD_ERROR_FLAGS) { + ERROR("EMMC: Cmd%d error INT[0x%x]\n", + handle->device->ctrl.cmdIndex, regval); + handle->device->ctrl.cmdStatus = SD_CMD_ERROR_FLAGS; + pstate_log(handle); + break; + } + + cmd12 = chal_sd_get_atuo12_error((CHAL_HANDLE *)handle->device); + if (cmd12) { + ERROR("EMMC: Cmd%d auto cmd12 err:0x%x\n", + handle->device->ctrl.cmdIndex, cmd12); + handle->device->ctrl.cmdStatus = cmd12; + pstate_log(handle); + break; + } + + if (SD_DATA_ERROR_FLAGS & regval) { + ERROR("EMMC: Data for cmd%d error, INT[0x%x]\n", + handle->device->ctrl.cmdIndex, regval); + handle->device->ctrl.cmdStatus = + (SD_DATA_ERROR_FLAGS & regval); + pstate_log(handle); + break; + } + + if ((regval & mask) == 0) + udelay(EMMC_WFE_RETRY_DELAY_US); + + } while ((regval & mask) == 0); + + /* clear the interrupt since it is processed */ + chal_sd_clear_irq((CHAL_HANDLE *)handle->device, (regval & mask)); + + return (regval & mask); +} + +int32_t set_config(struct sd_handle *handle, uint32_t speed, uint32_t retry, + uint32_t dma, uint32_t dmaBound, uint32_t blkSize, + uint32_t wfe_retry) +{ + int32_t rel = 0; + + if (handle == NULL) + return SD_FAIL; + + handle->device->cfg.wfe_retry = wfe_retry; + + rel = chal_sd_config((CHAL_HANDLE *)handle->device, speed, retry, + dmaBound, blkSize, dma); + return rel; + +} + +int mmc_cmd1(struct sd_handle *handle) +{ + uint32_t newOcr, res; + uint32_t cmd1_option = MMC_OCR_OP_VOLT | MMC_OCR_SECTOR_ACCESS_MODE; + + /* + * After Reset, eMMC comes up in 1 Bit Data Width by default. + * Set host side to match. + */ + chal_sd_config_bus_width((CHAL_HANDLE *) handle->device, + SD_BUS_DATA_WIDTH_1BIT); + +#ifdef USE_EMMC_FIP_TOC_CACHE + cached_partition_block = 0; +#endif + handle->device->ctrl.present = 0; /* init card present to be no card */ + + handle->card->type = SD_CARD_MMC; + + res = sd_cmd1(handle, cmd1_option, &newOcr); + + if (res != SD_OK) { + EMMC_TRACE("CMD1 Timeout: Device is not ready\n"); + res = SD_CARD_UNKNOWN; + } + return res; +} diff --git a/drivers/brcm/emmc/emmc_csl_sdcmd.c b/drivers/brcm/emmc/emmc_csl_sdcmd.c new file mode 100644 index 000000000..c62886cf6 --- /dev/null +++ b/drivers/brcm/emmc/emmc_csl_sdcmd.c @@ -0,0 +1,842 @@ +/* + * Copyright (c) 2016 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include "bcm_emmc.h" +#include "emmc_chal_types.h" +#include "emmc_chal_sd.h" +#include "emmc_csl_sdprot.h" +#include "emmc_csl_sdcmd.h" +#include "emmc_csl_sd.h" +#include "emmc_chal_sd.h" +#include "emmc_pboot_hal_memory_drv.h" + +int sd_cmd0(struct sd_handle *handle) +{ + int res; + uint32_t argument = 0x0; /* Go to IDLE state. */ + + /* send cmd and parse result */ + res = send_cmd(handle, SD_CMD_GO_IDLE_STATE, argument, 0, NULL); + + if (res == SD_OK) { + /* Clear all other interrupts */ + chal_sd_clear_irq((void *)handle->device, 0xffffffff); + } + + return res; +} + +int sd_cmd1(struct sd_handle *handle, uint32_t ocr, uint32_t *ocr_output) +{ + int res; + uint32_t options; + struct sd_resp resp; + + options = SD_CMDR_RSP_TYPE_R3_4 << SD_CMDR_RSP_TYPE_S; + + if (ocr_output == NULL) { + EMMC_TRACE("Invalid args\n"); + return SD_FAIL; + } + + /* send cmd and parse result */ + res = send_cmd(handle, SD_CMD_SEND_OPCOND, ocr, options, &resp); + + if (res == SD_OK) + *ocr_output = resp.data.r3.ocr; + + return res; +} + +int sd_cmd2(struct sd_handle *handle) +{ + uint32_t options; + struct sd_resp resp; + + /* send cmd and parse result */ + options = SD_CMDR_RSP_TYPE_R2 << SD_CMDR_RSP_TYPE_S; + + return send_cmd(handle, SD_CMD_ALL_SEND_CID, 0, options, &resp); +} + +int sd_cmd3(struct sd_handle *handle) +{ + int res; + uint32_t options = 0; + uint32_t argument; + struct sd_resp resp; + + /* use non zero and non 0x1 value for rca */ + handle->device->ctrl.rca = 0x5; + argument = handle->device->ctrl.rca << SD_CMD7_ARG_RCA_SHIFT; + + options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S | + SD4_EMMC_TOP_CMD_CCHK_EN_MASK | + SD4_EMMC_TOP_CMD_CRC_EN_MASK; + + /* send cmd and parse result */ + res = send_cmd(handle, SD_CMD_MMC_SET_RCA, argument, options, &resp); + + if (res != SD_OK) + handle->device->ctrl.rca = 0; + + return res; +} + +int sd_cmd7(struct sd_handle *handle, uint32_t rca) +{ + int res; + uint32_t argument, options; + struct sd_resp resp; + + argument = (rca << SD_CMD7_ARG_RCA_SHIFT); + + /* + * Response to CMD7 is: + * R1 while selectiing from Stand-By State to Transfer State + * R1b while selecting from Disconnected State to Programming State. + * + * In this driver, we only issue a CMD7 once, to go to transfer mode + * during init_mmc_card(). + */ + options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S | + SD4_EMMC_TOP_CMD_CCHK_EN_MASK | + SD4_EMMC_TOP_CMD_CRC_EN_MASK; + + /* send cmd and parse result */ + res = send_cmd(handle, SD_CMD_SELECT_DESELECT_CARD, argument, options, + &resp); + + if (res == SD_OK) + /* Clear all other interrupts */ + chal_sd_clear_irq((void *)handle->device, 0xffffffff); + + return res; +} + + +/* + * CMD8 Get CSD_EXT + */ +int mmc_cmd8(struct sd_handle *handle, uint8_t *extCsdReg) +{ + uint32_t res, options; + struct sd_resp resp; + + data_xfer_setup(handle, extCsdReg, CEATA_EXT_CSDBLOCK_SIZE, + SD_XFER_CARD_TO_HOST); + + options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S | + SD4_EMMC_TOP_CMD_DPS_MASK | SD4_EMMC_TOP_CMD_DTDS_MASK | + SD4_EMMC_TOP_CMD_CCHK_EN_MASK | SD4_EMMC_TOP_CMD_CRC_EN_MASK; + + /* send cmd and parse result */ + res = send_cmd(handle, SD_CMD_READ_EXT_CSD, 0, options, &resp); + + if (res == SD_OK) + res = process_data_xfer(handle, extCsdReg, 0, + CEATA_EXT_CSDBLOCK_SIZE, + SD_XFER_CARD_TO_HOST); + + return res; +} + +int sd_cmd9(struct sd_handle *handle, struct sd_card_data *card) +{ + int res; + uint32_t argument, options, iBlkNum, multiFactor = 1; + uint32_t maxReadBlockLen = 1, maxWriteBlockLen = 1; + struct sd_resp resp; + + argument = handle->device->ctrl.rca << SD_CMD7_ARG_RCA_SHIFT; + + options = SD_CMDR_RSP_TYPE_R2 << SD_CMDR_RSP_TYPE_S | + SD4_EMMC_TOP_CMD_CRC_EN_MASK; + + /* send cmd and parse result */ + res = send_cmd(handle, SD_CMD_SEND_CSD, argument, options, &resp); + + if (res != SD_OK) + return res; + + if (handle->card->type == SD_CARD_MMC) { + card->csd.mmc.structure = (resp.data.r2.rsp4 >> 22) & 0x3; + card->csd.mmc.csdSpecVer = (resp.data.r2.rsp4 >> 18) & 0x0f; + card->csd.mmc.taac = (resp.data.r2.rsp4 >> 8) & 0xff; + card->csd.mmc.nsac = resp.data.r2.rsp4 & 0xff; + card->csd.mmc.speed = resp.data.r2.rsp3 >> 24; + card->csd.mmc.classes = (resp.data.r2.rsp3 >> 12) & 0xfff; + card->csd.mmc.rdBlkLen = (resp.data.r2.rsp3 >> 8) & 0xf; + card->csd.mmc.rdBlkPartial = (resp.data.r2.rsp3 >> 7) & 0x01; + card->csd.mmc.wrBlkMisalign = (resp.data.r2.rsp3 >> 6) & 0x1; + card->csd.mmc.rdBlkMisalign = (resp.data.r2.rsp3 >> 5) & 0x1; + card->csd.mmc.dsr = (resp.data.r2.rsp2 >> 4) & 0x01; + card->csd.mmc.size = + ((resp.data.r2.rsp3 & 0x3) << 10) + + ((resp.data.r2.rsp2 >> 22) & 0x3ff); + card->csd.mmc.vddRdCurrMin = (resp.data.r2.rsp2 >> 19) & 0x7; + card->csd.mmc.vddRdCurrMax = (resp.data.r2.rsp2 >> 16) & 0x7; + card->csd.mmc.vddWrCurrMin = (resp.data.r2.rsp2 >> 13) & 0x7; + card->csd.mmc.vddWrCurrMax = (resp.data.r2.rsp2 >> 10) & 0x7; + card->csd.mmc.devSizeMulti = (resp.data.r2.rsp2 >> 7) & 0x7; + card->csd.mmc.eraseGrpSize = (resp.data.r2.rsp2 >> 2) & 0x1f; + card->csd.mmc.eraseGrpSizeMulti = + ((resp.data.r2.rsp2 & 0x3) << 3) + + ((resp.data.r2.rsp1 >> 29) & 0x7); + card->csd.mmc.wrProtGroupSize = + ((resp.data.r2.rsp1 >> 24) & 0x1f); + card->csd.mmc.wrProtGroupEnable = + (resp.data.r2.rsp1 >> 23) & 0x1; + card->csd.mmc.manuDefEcc = (resp.data.r2.rsp1 >> 21) & 0x3; + card->csd.mmc.wrSpeedFactor = (resp.data.r2.rsp1 >> 18) & 0x7; + card->csd.mmc.wrBlkLen = (resp.data.r2.rsp1 >> 14) & 0xf; + card->csd.mmc.wrBlkPartial = (resp.data.r2.rsp1 >> 13) & 0x1; + card->csd.mmc.protAppl = (resp.data.r2.rsp1 >> 8) & 0x1; + card->csd.mmc.copyFlag = (resp.data.r2.rsp1 >> 7) & 0x1; + card->csd.mmc.permWrProt = (resp.data.r2.rsp1 >> 6) & 0x1; + card->csd.mmc.tmpWrProt = (resp.data.r2.rsp1 >> 5) & 0x1; + card->csd.mmc.fileFormat = (resp.data.r2.rsp1 >> 4) & 0x03; + card->csd.mmc.eccCode = resp.data.r2.rsp1 & 0x03; + maxReadBlockLen <<= card->csd.mmc.rdBlkLen; + maxWriteBlockLen <<= card->csd.mmc.wrBlkLen; + + iBlkNum = card->csd.mmc.size + 1; + multiFactor = (1 << (card->csd.mmc.devSizeMulti + 2)); + + handle->card->size = + iBlkNum * multiFactor * (1 << card->csd.mmc.rdBlkLen); + } + + handle->card->maxRdBlkLen = maxReadBlockLen; + handle->card->maxWtBlkLen = maxWriteBlockLen; + + if (handle->card->size < 0xA00000) { + /* + * 10MB Too small size mean, cmd9 response is wrong, + * Use default value 1G + */ + handle->card->size = 0x40000000; + handle->card->maxRdBlkLen = 512; + handle->card->maxWtBlkLen = 512; + } + + if ((handle->card->maxRdBlkLen > 512) || + (handle->card->maxWtBlkLen > 512)) { + handle->card->maxRdBlkLen = 512; + handle->card->maxWtBlkLen = 512; + } else if ((handle->card->maxRdBlkLen == 0) || + (handle->card->maxWtBlkLen == 0)) { + handle->card->maxRdBlkLen = 512; + handle->card->maxWtBlkLen = 512; + } + + handle->device->cfg.blockSize = handle->card->maxRdBlkLen; + + return res; +} + +int sd_cmd13(struct sd_handle *handle, uint32_t *status) +{ + int res; + uint32_t argument, options; + struct sd_resp resp; + + argument = handle->device->ctrl.rca << SD_CMD7_ARG_RCA_SHIFT; + + options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S | + SD4_EMMC_TOP_CMD_CCHK_EN_MASK | + SD4_EMMC_TOP_CMD_CRC_EN_MASK; + + /* send cmd and parse result */ + res = send_cmd(handle, SD_CMD_SEND_STATUS, argument, options, &resp); + + if (res == SD_OK) { + *status = resp.cardStatus; + } + + return res; +} + +int sd_cmd16(struct sd_handle *handle, uint32_t length) +{ + int res; + uint32_t argument, options, ntry; + struct sd_resp resp; + + argument = length; + + options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S | + SD4_EMMC_TOP_CMD_CRC_EN_MASK | + SD4_EMMC_TOP_CMD_CCHK_EN_MASK; + + ntry = 0; + do { + res = sd_cmd13(handle, &resp.cardStatus); + if (res != SD_OK) { + EMMC_TRACE( + "cmd13 failed before cmd16: rca 0x%0x, return %d, response 0x%0x\n", + handle->device->ctrl.rca, res, resp.cardStatus); + return res; + } + + if (resp.cardStatus & 0x100) + break; + + EMMC_TRACE("cmd13 rsp:0x%08x before cmd16\n", resp.cardStatus); + + if (ntry > handle->device->cfg.retryLimit) { + EMMC_TRACE("cmd13 retry reach limit %d\n", + handle->device->cfg.retryLimit); + return SD_CMD_TIMEOUT; + } + + ntry++; + EMMC_TRACE("cmd13 retry %d\n", ntry); + + SD_US_DELAY(1000); + + } while (1); + + /* send cmd and parse result */ + res = send_cmd(handle, SD_CMD_SET_BLOCKLEN, argument, options, &resp); + + return res; +} + +int sd_cmd17(struct sd_handle *handle, + uint32_t addr, uint32_t len, uint8_t *buffer) +{ + int res; + uint32_t argument, options, ntry; + struct sd_resp resp; + + ntry = 0; + do { + res = sd_cmd13(handle, &resp.cardStatus); + if (res != SD_OK) { + EMMC_TRACE( + "cmd 13 failed before cmd17: rca 0x%0x, return %d, response 0x%0x\n", + handle->device->ctrl.rca, res, resp.cardStatus); + return res; + } + + if (resp.cardStatus & 0x100) + break; + + EMMC_TRACE("cmd13 rsp:0x%08x before cmd17\n", resp.cardStatus); + + if (ntry > handle->device->cfg.retryLimit) { + EMMC_TRACE("cmd13 retry reach limit %d\n", + handle->device->cfg.retryLimit); + return SD_CMD_TIMEOUT; + } + + ntry++; + EMMC_TRACE("cmd13 retry %d\n", ntry); + + SD_US_DELAY(1000); + + } while (1); + + data_xfer_setup(handle, buffer, len, SD_XFER_CARD_TO_HOST); + + /* send cmd and parse result */ + argument = addr; + options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S | + SD4_EMMC_TOP_CMD_DPS_MASK | SD4_EMMC_TOP_CMD_DTDS_MASK | + SD4_EMMC_TOP_CMD_CRC_EN_MASK | SD4_EMMC_TOP_CMD_CCHK_EN_MASK; + + res = send_cmd(handle, SD_CMD_READ_SINGLE_BLOCK, argument, options, + &resp); + + if (res != SD_OK) + return res; + + res = process_data_xfer(handle, buffer, addr, len, SD_XFER_CARD_TO_HOST); + + return res; +} + +int sd_cmd18(struct sd_handle *handle, + uint32_t addr, uint32_t len, uint8_t *buffer) +{ + int res; + uint32_t argument, options, ntry; + struct sd_resp resp; + + ntry = 0; + do { + res = sd_cmd13(handle, &resp.cardStatus); + if (res != SD_OK) { + EMMC_TRACE( + "cmd 13 failed before cmd18: rca 0x%0x, return %d, response 0x%0x\n", + handle->device->ctrl.rca, res, resp.cardStatus); + return res; + } + + if (resp.cardStatus & 0x100) + break; + + EMMC_TRACE("cmd13 rsp:0x%08x before cmd18\n", resp.cardStatus); + + if (ntry > handle->device->cfg.retryLimit) { + EMMC_TRACE("cmd13 retry reach limit %d\n", + handle->device->cfg.retryLimit); + return SD_CMD_TIMEOUT; + } + + ntry++; + EMMC_TRACE("cmd13 retry %d\n", ntry); + + SD_US_DELAY(1000); + } while (1); + + data_xfer_setup(handle, buffer, len, SD_XFER_CARD_TO_HOST); + + argument = addr; + + options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S | + SD4_EMMC_TOP_CMD_DPS_MASK | SD4_EMMC_TOP_CMD_DTDS_MASK | + SD4_EMMC_TOP_CMD_MSBS_MASK | SD4_EMMC_TOP_CMD_CCHK_EN_MASK | + SD4_EMMC_TOP_CMD_BCEN_MASK | SD4_EMMC_TOP_CMD_CRC_EN_MASK | + BIT(SD4_EMMC_TOP_CMD_ACMDEN_SHIFT); + + /* send cmd and parse result */ + res = send_cmd(handle, SD_CMD_READ_MULTIPLE_BLOCK, argument, options, + &resp); + + if (res != SD_OK) + return res; + + res = process_data_xfer(handle, buffer, addr, len, SD_XFER_CARD_TO_HOST); + + return res; +} + +#ifdef INCLUDE_EMMC_DRIVER_ERASE_CODE +static int card_sts_resp(struct sd_handle *handle, uint32_t *status) +{ + int res; + uint32_t ntry = 0; + + do { + res = sd_cmd13(handle, status); + if (res != SD_OK) { + EMMC_TRACE( + "cmd 13 failed before cmd35: rca 0x%0x, return %d\n", + handle->device->ctrl.rca, res); + return res; + } + + if (*status & 0x100) + break; + + EMMC_TRACE("cmd13 rsp:0x%08x before cmd35\n", resp.cardStatus); + + if (ntry > handle->device->cfg.retryLimit) { + EMMC_TRACE("cmd13 retry reach limit %d\n", + handle->device->cfg.retryLimit); + return SD_CMD_TIMEOUT; + } + + ntry++; + EMMC_TRACE("cmd13 retry %d\n", ntry); + + SD_US_DELAY(1000); + } while (1); + + return SD_OK; +} + +int sd_cmd35(struct sd_handle *handle, uint32_t start) +{ + int res; + uint32_t argument, options; + struct sd_resp resp; + + res = card_sts_resp(handle, &resp.cardStatus); + if (res != SD_OK) + return res; + + argument = start; + + options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S | + SD4_EMMC_TOP_CMD_CRC_EN_MASK | + SD4_EMMC_TOP_CMD_CCHK_EN_MASK; + + /* send cmd and parse result */ + res = send_cmd(handle, SD_CMD_ERASE_GROUP_START, + argument, options, &resp); + + if (res != SD_OK) + return res; + + return res; +} + +int sd_cmd36(struct sd_handle *handle, uint32_t end) +{ + int res; + uint32_t argument, options; + struct sd_resp resp; + + res = card_sts_resp(handle, &resp.cardStatus); + if (res != SD_OK) + return res; + + argument = end; + + options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S | + SD4_EMMC_TOP_CMD_CRC_EN_MASK | + SD4_EMMC_TOP_CMD_CCHK_EN_MASK; + + /* send cmd and parse result */ + res = send_cmd(handle, SD_CMD_ERASE_GROUP_END, + argument, options, &resp); + + if (res != SD_OK) + return res; + + return res; +} + +int sd_cmd38(struct sd_handle *handle) +{ + int res; + uint32_t argument, options; + struct sd_resp resp; + + res = card_sts_resp(handle, &resp.cardStatus); + if (res != SD_OK) + return res; + + argument = 0; + + options = (SD_CMDR_RSP_TYPE_R1b_5b << SD_CMDR_RSP_TYPE_S) | + SD4_EMMC_TOP_CMD_CRC_EN_MASK | + SD4_EMMC_TOP_CMD_CCHK_EN_MASK; + + /* send cmd and parse result */ + res = send_cmd(handle, SD_CMD_ERASE, argument, options, &resp); + + if (res != SD_OK) + return res; + + return res; +} +#endif + +#ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE + +int sd_cmd24(struct sd_handle *handle, + uint32_t addr, uint32_t len, uint8_t *buffer) +{ + int res; + uint32_t argument, options, ntry; + struct sd_resp resp; + + ntry = 0; + do { + res = sd_cmd13(handle, &resp.cardStatus); + if (res != SD_OK) { + EMMC_TRACE( + "cmd 13 failed before cmd24: rca 0x%0x, return %d, response 0x%0x\n", + handle->device->ctrl.rca, res, &resp.cardStatus); + return res; + } + + if (resp.cardStatus & 0x100) + break; + + EMMC_TRACE("cmd13 rsp:0x%08x before cmd24\n", resp.cardStatus); + + if (ntry > handle->device->cfg.retryLimit) { + EMMC_TRACE("cmd13 retry reach limit %d\n", + handle->device->cfg.retryLimit); + return SD_CMD_TIMEOUT; + } + + ntry++; + EMMC_TRACE("cmd13 retry %d\n", ntry); + + SD_US_DELAY(1000); + + } while (1); + + data_xfer_setup(handle, buffer, len, SD_XFER_HOST_TO_CARD); + + argument = addr; + + options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S | + SD4_EMMC_TOP_CMD_DPS_MASK | SD4_EMMC_TOP_CMD_CRC_EN_MASK | + SD4_EMMC_TOP_CMD_CCHK_EN_MASK; + + /* send cmd and parse result */ + res = send_cmd(handle, SD_CMD_WRITE_BLOCK, argument, options, &resp); + + if (res != SD_OK) + return res; + + res = process_data_xfer(handle, buffer, addr, len, SD_XFER_HOST_TO_CARD); + + return res; +} + +int sd_cmd25(struct sd_handle *handle, + uint32_t addr, uint32_t len, uint8_t *buffer) +{ + int res = SD_OK; + uint32_t argument, options, ntry; + struct sd_resp resp; + + ntry = 0; + do { + res = sd_cmd13(handle, &resp.cardStatus); + if (res != SD_OK) { + EMMC_TRACE( + "cmd 13 failed before cmd25: rca 0x%0x, return %d, response 0x%0x\n", + handle->device->ctrl.rca, res, &resp.cardStatus); + return res; + } + + if (resp.cardStatus & 0x100) + break; + + EMMC_TRACE("cmd13 rsp:0x%08x before cmd25\n", resp.cardStatus); + + if (ntry > handle->device->cfg.retryLimit) { + EMMC_TRACE("cmd13 retry reach limit %d\n", + handle->device->cfg.retryLimit); + return SD_CMD_TIMEOUT; + } + + ntry++; + EMMC_TRACE("cmd13 retry %d\n", ntry); + + SD_US_DELAY(1000); + } while (1); + + data_xfer_setup(handle, buffer, len, SD_XFER_HOST_TO_CARD); + + argument = addr; + + options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S | + SD4_EMMC_TOP_CMD_DPS_MASK | SD4_EMMC_TOP_CMD_MSBS_MASK | + SD4_EMMC_TOP_CMD_CCHK_EN_MASK | SD4_EMMC_TOP_CMD_BCEN_MASK | + SD4_EMMC_TOP_CMD_CRC_EN_MASK | + BIT(SD4_EMMC_TOP_CMD_ACMDEN_SHIFT); + + /* send cmd and parse result */ + res = send_cmd(handle, SD_CMD_WRITE_MULTIPLE_BLOCK, + argument, options, &resp); + + if (res != SD_OK) + return res; + + res = process_data_xfer(handle, buffer, addr, len, SD_XFER_HOST_TO_CARD); + + return res; +} +#endif /* INCLUDE_EMMC_DRIVER_WRITE_CODE */ + +int mmc_cmd6(struct sd_handle *handle, uint32_t argument) +{ + int res; + uint32_t options; + struct sd_resp resp; + + options = SD_CMDR_RSP_TYPE_R1b_5b << SD_CMDR_RSP_TYPE_S | + SD4_EMMC_TOP_CMD_CCHK_EN_MASK | SD4_EMMC_TOP_CMD_CRC_EN_MASK; + + EMMC_TRACE("Sending CMD6 with argument 0x%X\n", argument); + + /* send cmd and parse result */ + res = send_cmd(handle, SD_ACMD_SET_BUS_WIDTH, argument, options, &resp); + + /* + * For R1b type response: + * controller issues a COMMAND COMPLETE interrupt when the R1 + * response is received, + * then controller monitors DAT0 for busy status, + * controller issues a TRANSFER COMPLETE interrupt when busy signal + * clears. + */ + wait_for_event(handle, + SD4_EMMC_TOP_INTR_TXDONE_MASK | SD_ERR_INTERRUPTS, + handle->device->cfg.wfe_retry); + + if (res == SD_OK) { + /* Check result of Cmd6 using Cmd13 to check card status */ + + /* Check status using Cmd13 */ + res = sd_cmd13(handle, &resp.cardStatus); + + if (res == SD_OK) { + /* Check bit 7 (SWITCH_ERROR) in card status */ + if ((resp.cardStatus & 0x80) != 0) { + EMMC_TRACE("cmd6 failed: SWITCH_ERROR\n"); + res = SD_FAIL; + } + } else { + EMMC_TRACE("cmd13 failed after cmd6: "); + EMMC_TRACE("rca 0x%0x, return %d, response 0x%0x\n", + handle->device->ctrl.rca, res, resp.cardStatus); + } + } + + return res; +} + + +#define SD_BUSY_CHECK 0x00203000 +#define DAT0_LEVEL_MASK 0x100000 /* bit20 in PSTATE */ +#define DEV_BUSY_TIMEOUT 600000 /* 60 Sec : 600000 * 100us */ + +int send_cmd(struct sd_handle *handle, uint32_t cmdIndex, uint32_t argument, + uint32_t options, struct sd_resp *resp) +{ + int status = SD_OK; + uint32_t event = 0, present, timeout = 0, retry = 0, mask = 3; + uint32_t temp_resp[4]; + + if (handle == NULL) { + EMMC_TRACE("Invalid handle for cmd%d\n", cmdIndex); + return SD_INVALID_HANDLE; + } + + mask = (SD_BUSY_CHECK & options) ? 3 : 1; + +RETRY_WRITE_CMD: + do { + /* Make sure it is ok to send command */ + present = + chal_sd_get_present_status((CHAL_HANDLE *) handle->device); + timeout++; + + if (present & mask) + SD_US_DELAY(1000); + else + break; + + } while (timeout < EMMC_BUSY_CMD_TIMEOUT_MS); + + if (timeout >= EMMC_BUSY_CMD_TIMEOUT_MS) { + status = SD_CMD_MISSING; + EMMC_TRACE("cmd%d timedout %dms\n", cmdIndex, timeout); + } + + /* Reset both DAT and CMD line if only of them are stuck */ + if (present & mask) + check_error(handle, SD4_EMMC_TOP_INTR_CMDERROR_MASK); + + handle->device->ctrl.argReg = argument; + chal_sd_send_cmd((CHAL_HANDLE *) handle->device, cmdIndex, + handle->device->ctrl.argReg, options); + + handle->device->ctrl.cmdIndex = cmdIndex; + + event = wait_for_event(handle, + (SD4_EMMC_TOP_INTR_CMDDONE_MASK | + SD_ERR_INTERRUPTS), + handle->device->cfg.wfe_retry); + + if (handle->device->ctrl.cmdStatus == SD_CMD_MISSING) { + retry++; + + if (retry >= handle->device->cfg.retryLimit) { + status = SD_CMD_MISSING; + EMMC_TRACE("cmd%d retry reaches the limit %d\n", + cmdIndex, retry); + } else { + /* reset both DAT & CMD line if one of them is stuck */ + present = chal_sd_get_present_status((CHAL_HANDLE *) + handle->device); + + if (present & mask) + check_error(handle, + SD4_EMMC_TOP_INTR_CMDERROR_MASK); + + EMMC_TRACE("cmd%d retry %d PSTATE[0x%08x]\n", + cmdIndex, retry, + chal_sd_get_present_status((CHAL_HANDLE *) + handle->device)); + goto RETRY_WRITE_CMD; + } + } + + if (handle->device->ctrl.cmdStatus == SD_OK) { + if (resp != NULL) { + status = + chal_sd_get_response((CHAL_HANDLE *) handle->device, + temp_resp); + process_cmd_response(handle, + handle->device->ctrl.cmdIndex, + temp_resp[0], temp_resp[1], + temp_resp[2], temp_resp[3], resp); + } + + /* Check Device busy after CMD */ + if ((cmdIndex == 5) || (cmdIndex == 6) || (cmdIndex == 7) || + (cmdIndex == 28) || (cmdIndex == 29) || (cmdIndex == 38)) { + + timeout = 0; + do { + present = + chal_sd_get_present_status((CHAL_HANDLE *) + handle->device); + + timeout++; + + /* Dat[0]:bit20 low means device busy */ + if ((present & DAT0_LEVEL_MASK) == 0) { + EMMC_TRACE("Device busy: "); + EMMC_TRACE( + "cmd%d arg:0x%08x: PSTATE[0x%08x]\n", + cmdIndex, argument, present); + SD_US_DELAY(100); + } else { + break; + } + } while (timeout < DEV_BUSY_TIMEOUT); + } + } else if (handle->device->ctrl.cmdStatus && + handle->device->ctrl.cmdStatus != SD_CMD_MISSING) { + retry++; + status = check_error(handle, handle->device->ctrl.cmdStatus); + + EMMC_TRACE( + "cmd%d error: cmdStatus:0x%08x error_status:0x%08x\n", + cmdIndex, handle->device->ctrl.cmdStatus, status); + + if ((handle->device->ctrl.cmdIndex == 1) || + (handle->device->ctrl.cmdIndex == 5)) { + status = event; + } else if ((handle->device->ctrl.cmdIndex == 7) || + (handle->device->ctrl.cmdIndex == 41)) { + status = event; + } else if ((status == SD_ERROR_RECOVERABLE) && + (retry < handle->device->cfg.retryLimit)) { + EMMC_TRACE("cmd%d recoverable error ", cmdIndex); + EMMC_TRACE("retry %d PSTATE[0x%08x].\n", retry, + chal_sd_get_present_status((CHAL_HANDLE *) + handle->device)); + goto RETRY_WRITE_CMD; + } else { + EMMC_TRACE("cmd%d retry reaches the limit %d\n", + cmdIndex, retry); + status = event; + } + } + + handle->device->ctrl.blkReg = 0; + /* clear error status for next command */ + handle->device->ctrl.cmdStatus = 0; + + return status; +} diff --git a/drivers/brcm/emmc/emmc_pboot_hal_memory_drv.c b/drivers/brcm/emmc/emmc_pboot_hal_memory_drv.c new file mode 100644 index 000000000..68f93e75e --- /dev/null +++ b/drivers/brcm/emmc/emmc_pboot_hal_memory_drv.c @@ -0,0 +1,621 @@ +/* + * Copyright (c) 2016 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include + +#define MAX_CMD_RETRY 10 + +#if EMMC_USE_DMA +#define USE_DMA 1 +#else +#define USE_DMA 0 +#endif + +struct emmc_global_buffer emmc_global_buf; +struct emmc_global_buffer *emmc_global_buf_ptr = &emmc_global_buf; + +struct emmc_global_vars emmc_global_vars; +struct emmc_global_vars *emmc_global_vars_ptr = &emmc_global_vars; + +static struct sd_handle *sdio_gethandle(void); +static uint32_t sdio_idle(struct sd_handle *p_sdhandle); + +static uint32_t sdio_read(struct sd_handle *p_sdhandle, + uintptr_t mem_addr, + uintptr_t storage_addr, + size_t storage_size, + size_t bytes_to_read); + +#ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE +static uint32_t sdio_write(struct sd_handle *p_sdhandle, + uintptr_t mem_addr, + uintptr_t data_addr, + size_t bytes_to_write); +#endif + +static struct sd_handle *sdio_init(void); +static int32_t bcm_emmc_card_ready_state(struct sd_handle *p_sdhandle); + +static void init_globals(void) +{ + memset((void *)emmc_global_buf_ptr, 0, sizeof(*emmc_global_buf_ptr)); + memset((void *)emmc_global_vars_ptr, 0, sizeof(*emmc_global_vars_ptr)); +} + +/* + * This function is used to change partition + */ +uint32_t emmc_partition_select(uint32_t partition) +{ + int rc; + struct sd_handle *sd_handle = sdio_gethandle(); + + if (sd_handle->device == 0) { + EMMC_TRACE("eMMC init is not done"); + return 0; + } + + switch (partition) { + case EMMC_BOOT_PARTITION1: + rc = set_boot_config(sd_handle, + SDIO_HW_EMMC_EXT_CSD_BOOT_ACC_BOOT1); + EMMC_TRACE( + "Change to Boot Partition 1 result:%d (0 means SD_OK)\n", + rc); + break; + + case EMMC_BOOT_PARTITION2: + rc = set_boot_config(sd_handle, + SDIO_HW_EMMC_EXT_CSD_BOOT_ACC_BOOT2); + EMMC_TRACE( + "Change to Boot Partition 2 result:%d (0 means SD_OK)\n", + rc); + break; + + case EMMC_USE_CURRENT_PARTITION: + rc = SD_OK; + EMMC_TRACE("Stay on current partition"); + break; + + case EMMC_USER_AREA: + default: + rc = set_boot_config(sd_handle, + SDIO_HW_EMMC_EXT_CSD_BOOT_ACC_USER); + EMMC_TRACE("Change to User area result:%d (0 means SD_OK)\n", + rc); + break; + + } + return (rc == SD_OK); +} + +/* + * Initialize emmc controller for eMMC + * Returns 0 on fail condition + */ +uint32_t bcm_emmc_init(bool card_rdy_only) +{ + struct sd_handle *p_sdhandle; + uint32_t result = 0; + + EMMC_TRACE("Enter emmc_controller_init()\n"); + + /* If eMMC is already initialized, skip init */ + if (emmc_global_vars_ptr->init_done) + return 1; + + init_globals(); + + p_sdhandle = sdio_init(); + + if (p_sdhandle == NULL) { + ERROR("eMMC init failed"); + return result; + } + + if (card_rdy_only) { + /* Put the card in Ready state, Not complete init */ + result = bcm_emmc_card_ready_state(p_sdhandle); + return !result; + } + + if (sdio_idle(p_sdhandle) == EMMC_BOOT_OK) { + set_config(p_sdhandle, SD_NORMAL_SPEED, MAX_CMD_RETRY, USE_DMA, + SD_DMA_BOUNDARY_256K, EMMC_BLOCK_SIZE, + EMMC_WFE_RETRY); + + if (!select_blk_sz(p_sdhandle, + p_sdhandle->device->cfg.blockSize)) { + emmc_global_vars_ptr->init_done = 1; + result = 1; + } else { + ERROR("Select Block Size failed\n"); + } + } else { + ERROR("eMMC init failed"); + } + + /* Initialization is failed, so deinit HW setting */ + if (result == 0) + emmc_deinit(); + + return result; +} + +/* + * Function to de-init SDIO controller for eMMC + */ +void emmc_deinit(void) +{ + emmc_global_vars_ptr->init_done = 0; + emmc_global_vars_ptr->sdHandle.card = 0; + emmc_global_vars_ptr->sdHandle.device = 0; +} + +/* + * Read eMMC memory + * Returns read_size + */ +uint32_t emmc_read(uintptr_t mem_addr, uintptr_t storage_addr, + size_t storage_size, size_t bytes_to_read) +{ + struct sd_handle *sd_handle = sdio_gethandle(); + + if (sd_handle->device == 0) { + EMMC_TRACE("eMMC init is not done"); + return 0; + } + + return sdio_read(sdio_gethandle(), mem_addr, storage_addr, + storage_size, bytes_to_read); +} + +#ifdef INCLUDE_EMMC_DRIVER_ERASE_CODE +#define EXT_CSD_ERASE_GRP_SIZE 224 + +static int emmc_block_erase(uintptr_t mem_addr, size_t blocks) +{ + struct sd_handle *sd_handle = sdio_gethandle(); + + if (sd_handle->device == 0) { + ERROR("eMMC init is not done"); + return -1; + } + + return erase_card(sdio_gethandle(), mem_addr, blocks); +} + +int emmc_erase(uintptr_t mem_addr, size_t num_of_blocks, uint32_t partition) +{ + int err = 0; + size_t block_count = 0, blocks = 0; + size_t erase_group = 0; + + erase_group = + emmc_global_buf_ptr->u.Ext_CSD_storage[EXT_CSD_ERASE_GRP_SIZE]*1024; + + INFO("eMMC Erase Group Size=0x%lx\n", erase_group); + + emmc_partition_select(partition); + + while (block_count < num_of_blocks) { + blocks = ((num_of_blocks - block_count) > erase_group) ? + erase_group : (num_of_blocks - block_count); + err = emmc_block_erase(mem_addr + block_count, blocks); + if (err) + break; + + block_count += blocks; + } + + if (err == 0) + INFO("eMMC Erase of partition %d successful\n", partition); + else + ERROR("eMMC Erase of partition %d Failed(%i)\n", partition, err); + + return err; +} +#endif + +#ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE +/* + * Write to eMMC memory + * Returns written_size + */ +uint32_t emmc_write(uintptr_t mem_addr, uintptr_t data_addr, + size_t bytes_to_write) +{ + struct sd_handle *sd_handle = sdio_gethandle(); + + if (sd_handle->device == 0) { + EMMC_TRACE("eMMC init is not done"); + return 0; + } + + return sdio_write(sd_handle, mem_addr, data_addr, bytes_to_write); +} +#endif + +/* + * Send SDIO Cmd + * Return 0 for pass condition + */ +uint32_t send_sdio_cmd(uint32_t cmdIndex, uint32_t argument, + uint32_t options, struct sd_resp *resp) +{ + struct sd_handle *sd_handle = sdio_gethandle(); + + if (sd_handle->device == 0) { + EMMC_TRACE("eMMC init is not done"); + return 1; + } + + return send_cmd(sd_handle, cmdIndex, argument, options, resp); +} + + +/* + * This function return SDIO handle + */ +struct sd_handle *sdio_gethandle(void) +{ + return &emmc_global_vars_ptr->sdHandle; +} + +/* + * Initialize SDIO controller + */ +struct sd_handle *sdio_init(void) +{ + uint32_t SDIO_base; + struct sd_handle *p_sdhandle = &emmc_global_vars_ptr->sdHandle; + + SDIO_base = EMMC_CTRL_REGS_BASE_ADDR; + + if (SDIO_base == SDIO0_EMMCSDXC_SYSADDR) + EMMC_TRACE(" ---> for SDIO 0 Controller\n\n"); + + memset(p_sdhandle, 0, sizeof(struct sd_handle)); + + p_sdhandle->device = &emmc_global_vars_ptr->sdDevice; + p_sdhandle->card = &emmc_global_vars_ptr->sdCard; + + memset(p_sdhandle->device, 0, sizeof(struct sd_dev)); + memset(p_sdhandle->card, 0, sizeof(struct sd_card_info)); + + if (chal_sd_start((CHAL_HANDLE *) p_sdhandle->device, + SD_PIO_MODE, SDIO_base, SDIO_base) != SD_OK) + return NULL; + + set_config(p_sdhandle, SD_NORMAL_SPEED, MAX_CMD_RETRY, SD_DMA_OFF, + SD_DMA_BOUNDARY_4K, EMMC_BLOCK_SIZE, EMMC_WFE_RETRY); + + return &emmc_global_vars_ptr->sdHandle; +} + +uint32_t sdio_idle(struct sd_handle *p_sdhandle) +{ + reset_card(p_sdhandle); + + SD_US_DELAY(1000); + + if (init_card(p_sdhandle, SD_CARD_DETECT_MMC) != SD_OK) { + reset_card(p_sdhandle); + reset_host_ctrl(p_sdhandle); + return EMMC_BOOT_NO_CARD; + } + + return EMMC_BOOT_OK; +} + +/* + * This function read eMMC + */ +uint32_t sdio_read(struct sd_handle *p_sdhandle, + uintptr_t mem_addr, + uintptr_t storage_addr, + size_t storage_size, size_t bytes_to_read) +{ + uint32_t offset = 0, blockAddr, readLen = 0, rdCount; + uint32_t remSize, manual_copy_size; + uint8_t *outputBuf = (uint8_t *) storage_addr; + const size_t blockSize = p_sdhandle->device->cfg.blockSize; + + VERBOSE("EMMC READ: dst=0x%lx, src=0x%lx, size=0x%lx\n", + storage_addr, mem_addr, bytes_to_read); + + if (storage_size < bytes_to_read) + /* Don't have sufficient storage to complete the operation */ + return 0; + + /* Range check non high capacity memory */ + if ((p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) == 0) { + if (mem_addr > 0x80000000) + return 0; + } + + /* High capacity card use block address mode */ + if (p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) { + blockAddr = (uint32_t) (mem_addr / blockSize); + offset = (uint32_t) (mem_addr - (blockAddr * blockSize)); + } else { + blockAddr = (uint32_t) (mem_addr / blockSize) * blockSize; + offset = (uint32_t) (mem_addr - blockAddr); + } + + remSize = bytes_to_read; + + rdCount = 0; + + /* Process first unaligned block of MAX_READ_LENGTH */ + if (offset > 0) { + if (!read_block(p_sdhandle, emmc_global_buf_ptr->u.tempbuf, + blockAddr, SD_MAX_READ_LENGTH)) { + + if (remSize < (blockSize - offset)) { + rdCount += remSize; + manual_copy_size = remSize; + remSize = 0; /* read is done */ + } else { + remSize -= (blockSize - offset); + rdCount += (blockSize - offset); + manual_copy_size = blockSize - offset; + } + + /* Check for overflow */ + if (manual_copy_size > storage_size || + (((uintptr_t)outputBuf + manual_copy_size) > + (storage_addr + storage_size))) { + ERROR("EMMC READ: Overflow 1\n"); + return 0; + } + + memcpy(outputBuf, + (void *)((uintptr_t) + (emmc_global_buf_ptr->u.tempbuf + offset)), + manual_copy_size); + + /* Update Physical address */ + outputBuf += manual_copy_size; + + if (p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) + blockAddr++; + else + blockAddr += blockSize; + } else { + return 0; + } + } + + while (remSize >= blockSize) { + + if (remSize >= SD_MAX_BLK_TRANSFER_LENGTH) + readLen = SD_MAX_BLK_TRANSFER_LENGTH; + else + readLen = (remSize / blockSize) * blockSize; + + /* Check for overflow */ + if ((rdCount + readLen) > storage_size || + (((uintptr_t) outputBuf + readLen) > + (storage_addr + storage_size))) { + ERROR("EMMC READ: Overflow\n"); + return 0; + } + + if (!read_block(p_sdhandle, outputBuf, blockAddr, readLen)) { + if (p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) + blockAddr += (readLen / blockSize); + else + blockAddr += readLen; + + remSize -= readLen; + rdCount += readLen; + + /* Update Physical address */ + outputBuf += readLen; + } else { + return 0; + } + } + + /* process the last unaligned block reading */ + if (remSize > 0) { + if (!read_block(p_sdhandle, emmc_global_buf_ptr->u.tempbuf, + blockAddr, SD_MAX_READ_LENGTH)) { + + rdCount += remSize; + /* Check for overflow */ + if (rdCount > storage_size || + (((uintptr_t) outputBuf + remSize) > + (storage_addr + storage_size))) { + ERROR("EMMC READ: Overflow\n"); + return 0; + } + + memcpy(outputBuf, + emmc_global_buf_ptr->u.tempbuf, remSize); + + /* Update Physical address */ + outputBuf += remSize; + } else { + rdCount = 0; + } + } + + return rdCount; +} + +#ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE +static uint32_t sdio_write(struct sd_handle *p_sdhandle, uintptr_t mem_addr, + uintptr_t data_addr, size_t bytes_to_write) +{ + + uint32_t offset, blockAddr, writeLen, wtCount = 0; + uint32_t remSize, manual_copy_size = 0; + + uint8_t *inputBuf = (uint8_t *)data_addr; + + /* range check non high capacity memory */ + if ((p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) == 0) { + if (mem_addr > 0x80000000) + return 0; + } + + /* the high capacity card use block address mode */ + if (p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) { + blockAddr = + (uint32_t)(mem_addr / p_sdhandle->device->cfg.blockSize); + offset = + (uint32_t)(mem_addr - + blockAddr * p_sdhandle->device->cfg.blockSize); + } else { + blockAddr = + ((uint32_t)mem_addr / p_sdhandle->device->cfg.blockSize) * + p_sdhandle->device->cfg.blockSize; + offset = (uint32_t) mem_addr - blockAddr; + } + + remSize = bytes_to_write; + + wtCount = 0; + + /* process first unaligned block */ + if (offset > 0) { + if (!read_block(p_sdhandle, emmc_global_buf_ptr->u.tempbuf, + blockAddr, p_sdhandle->device->cfg.blockSize)) { + + if (remSize < + (p_sdhandle->device->cfg.blockSize - offset)) + manual_copy_size = remSize; + else + manual_copy_size = + p_sdhandle->device->cfg.blockSize - offset; + + memcpy((void *)((uintptr_t) + (emmc_global_buf_ptr->u.tempbuf + offset)), + inputBuf, + manual_copy_size); + + /* Update Physical address */ + + if (!write_block(p_sdhandle, + emmc_global_buf_ptr->u.tempbuf, + blockAddr, + p_sdhandle->device->cfg.blockSize)) { + + if (remSize < + (p_sdhandle->device->cfg.blockSize - + offset)) { + wtCount += remSize; + manual_copy_size = remSize; + remSize = 0; /* read is done */ + } else { + remSize -= + (p_sdhandle->device->cfg.blockSize - + offset); + wtCount += + (p_sdhandle->device->cfg.blockSize - + offset); + manual_copy_size = + p_sdhandle->device->cfg.blockSize - + offset; + } + + inputBuf += manual_copy_size; + + if (p_sdhandle->device->ctrl.ocr & + SD_CARD_HIGH_CAPACITY) + blockAddr++; + else + blockAddr += + p_sdhandle->device->cfg.blockSize; + } else + return 0; + } else { + return 0; + } + } + + /* process block writing */ + while (remSize >= p_sdhandle->device->cfg.blockSize) { + if (remSize >= SD_MAX_READ_LENGTH) { + writeLen = SD_MAX_READ_LENGTH; + } else { + writeLen = + (remSize / p_sdhandle->device->cfg.blockSize) * + p_sdhandle->device->cfg.blockSize; + } + + if (!write_block(p_sdhandle, inputBuf, blockAddr, writeLen)) { + if (p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) + blockAddr += + (writeLen / + p_sdhandle->device->cfg.blockSize); + else + blockAddr += writeLen; + + remSize -= writeLen; + wtCount += writeLen; + inputBuf += writeLen; + } else { + return 0; + } + } + + /* process the last unaligned block reading */ + if (remSize > 0) { + if (!read_block(p_sdhandle, + emmc_global_buf_ptr->u.tempbuf, + blockAddr, p_sdhandle->device->cfg.blockSize)) { + + memcpy(emmc_global_buf_ptr->u.tempbuf, + inputBuf, remSize); + + /* Update Physical address */ + + if (!write_block(p_sdhandle, + emmc_global_buf_ptr->u.tempbuf, + blockAddr, + p_sdhandle->device->cfg.blockSize)) { + wtCount += remSize; + inputBuf += remSize; + } else { + return 0; + } + } else { + wtCount = 0; + } + } + + return wtCount; +} +#endif + +/* + * Function to put the card in Ready state by sending CMD0 and CMD1 + */ +static int32_t bcm_emmc_card_ready_state(struct sd_handle *p_sdhandle) +{ + int32_t result = 0; + uint32_t argument = MMC_CMD_IDLE_RESET_ARG; /* Exit from Boot mode */ + + if (p_sdhandle) { + send_sdio_cmd(SD_CMD_GO_IDLE_STATE, argument, 0, NULL); + + result = reset_card(p_sdhandle); + if (result != SD_OK) { + EMMC_TRACE("eMMC Reset error\n"); + return SD_RESET_ERROR; + } + SD_US_DELAY(2000); + result = mmc_cmd1(p_sdhandle); + } + + return result; +} diff --git a/include/drivers/brcm/emmc/bcm_emmc.h b/include/drivers/brcm/emmc/bcm_emmc.h new file mode 100644 index 000000000..67f060229 --- /dev/null +++ b/include/drivers/brcm/emmc/bcm_emmc.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2016 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef EMMC_H +#define EMMC_H + +#include + +#include + +#include + +#include "emmc_chal_types.h" +#include "emmc_chal_sd.h" +#include "emmc_csl_sdprot.h" +#include "emmc_csl_sdcmd.h" +#include "emmc_pboot_hal_memory_drv.h" + +/* ------------------------------------------------------------------- */ +#define EXT_CSD_SIZE 512 + +#ifdef PLAT_SD_MAX_READ_LENGTH +#define SD_MAX_READ_LENGTH PLAT_SD_MAX_READ_LENGTH +#ifdef USE_EMMC_LARGE_BLK_TRANSFER_LENGTH +#define SD_MAX_BLK_TRANSFER_LENGTH 0x10000000 +#else +#define SD_MAX_BLK_TRANSFER_LENGTH 0x1000 +#endif +#else +#define SD_MAX_READ_LENGTH EMMC_BLOCK_SIZE +#define SD_MAX_BLK_TRANSFER_LENGTH EMMC_BLOCK_SIZE +#endif + +struct emmc_global_buffer { + union { + uint8_t Ext_CSD_storage[EXT_CSD_SIZE]; + uint8_t tempbuf[SD_MAX_READ_LENGTH]; + } u; +}; + +struct emmc_global_vars { + struct sd_card_data cardData; + struct sd_handle sdHandle; + struct sd_dev sdDevice; + struct sd_card_info sdCard; + unsigned int init_done; +}; + +#define ICFG_SDIO0_CAP0__SLOT_TYPE_R 27 +#define ICFG_SDIO0_CAP0__INT_MODE_R 26 +#define ICFG_SDIO0_CAP0__SYS_BUS_64BIT_R 25 +#define ICFG_SDIO0_CAP0__VOLTAGE_1P8V_R 24 +#define ICFG_SDIO0_CAP0__VOLTAGE_3P0V_R 23 +#define ICFG_SDIO0_CAP0__VOLTAGE_3P3V_R 22 +#define ICFG_SDIO0_CAP0__SUSPEND_RESUME_R 21 +#define ICFG_SDIO0_CAP0__SDMA_R 20 +#define ICFG_SDIO0_CAP0__HIGH_SPEED_R 19 +#define ICFG_SDIO0_CAP0__ADMA2_R 18 +#define ICFG_SDIO0_CAP0__EXTENDED_MEDIA_R 17 +#define ICFG_SDIO0_CAP0__MAX_BLOCK_LEN_R 15 +#define ICFG_SDIO0_CAP0__BASE_CLK_FREQ_R 7 +#define ICFG_SDIO0_CAP0__TIMEOUT_UNIT_R 6 +#define ICFG_SDIO0_CAP0__TIMEOUT_CLK_FREQ_R 0 +#define ICFG_SDIO0_CAP1__SPI_BLOCK_MODE_R 22 +#define ICFG_SDIO0_CAP1__SPI_MODE_R 21 +#define ICFG_SDIO0_CAP1__CLK_MULT_R 13 +#define ICFG_SDIO0_CAP1__RETUNING_MODE_R 11 +#define ICFG_SDIO0_CAP1__TUNE_SDR50_R 10 +#define ICFG_SDIO0_CAP1__TIME_RETUNE_R 6 +#define ICFG_SDIO0_CAP1__DRIVER_D_R 5 +#define ICFG_SDIO0_CAP1__DRIVER_C_R 4 +#define ICFG_SDIO0_CAP1__DRIVER_A_R 3 +#define ICFG_SDIO0_CAP1__DDR50_R 2 +#define ICFG_SDIO0_CAP1__SDR104_R 1 +#define ICFG_SDIO0_CAP1__SDR50_R 0 + +#define SDIO0_CTRL_REGS_BASE_ADDR (SDIO0_EMMCSDXC_SYSADDR) +#define SDIO0_IDM_RESET_CTRL_ADDR (SDIO_IDM0_IDM_RESET_CONTROL) + +#define EMMC_CTRL_REGS_BASE_ADDR SDIO0_CTRL_REGS_BASE_ADDR +#define EMMC_IDM_RESET_CTRL_ADDR SDIO0_IDM_RESET_CTRL_ADDR +#define EMMC_IDM_IO_CTRL_DIRECT_ADDR SDIO_IDM0_IO_CONTROL_DIRECT + +extern struct emmc_global_buffer *emmc_global_buf_ptr; + +extern struct emmc_global_vars *emmc_global_vars_ptr; + +#define EMMC_CARD_DETECT_TIMEOUT_MS 1200 +#define EMMC_CMD_TIMEOUT_MS 200 +#define EMMC_BUSY_CMD_TIMEOUT_MS 200 +#define EMMC_CLOCK_SETTING_TIMEOUT_MS 100 +#define EMMC_WFE_RETRY 40000 +#define EMMC_WFE_RETRY_DELAY_US 10 + +#ifdef EMMC_DEBUG +#define EMMC_TRACE INFO +#else +#define EMMC_TRACE(...) +#endif + +#endif /* EMMC_H */ diff --git a/include/drivers/brcm/emmc/emmc_api.h b/include/drivers/brcm/emmc/emmc_api.h new file mode 100644 index 000000000..c4c2a5803 --- /dev/null +++ b/include/drivers/brcm/emmc/emmc_api.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2016 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef EMMC_API_H +#define EMMC_API_H + +#include "bcm_emmc.h" +#include "emmc_pboot_hal_memory_drv.h" + +#ifdef INCLUDE_EMMC_DRIVER_ERASE_CODE +/* + * The erasable unit of the eMMC is the Erase Group + * Erase group is measured in write blocks which + * are the basic writable units of the Device + * EMMC_ERASE_GROUP_SIZE is the number of writeable + * units (each unit is 512 bytes) + */ + +/* Start address (sector) */ +#define EMMC_ERASE_START_BLOCK 0x0 +/* Number of blocks to be erased */ +#define EMMC_ERASE_BLOCK_COUNT 0x1 + +#define EMMC_ERASE_USER_AREA 0 +#define EMMC_ERASE_BOOT_PARTITION1 1 +#define EMMC_ERASE_BOOT_PARTITION2 2 + +/* eMMC partition to be erased */ +#define EMMC_ERASE_PARTITION EMMC_ERASE_USER_AREA +#endif + +uint32_t bcm_emmc_init(bool card_rdy_only); +void emmc_deinit(void); + +#ifdef INCLUDE_EMMC_DRIVER_ERASE_CODE +int emmc_erase(uintptr_t mem_addr, size_t num_of_blocks, uint32_t partition); +#endif + +uint32_t emmc_partition_select(uint32_t partition); +uint32_t emmc_read(uintptr_t mem_addr, uintptr_t storage_addr, + size_t storage_size, size_t bytes_to_read); +uint32_t emmc_write(uintptr_t mem_addr, uintptr_t data_addr, + size_t bytes_to_write); +#endif /* EMMC_API_H */ diff --git a/include/drivers/brcm/emmc/emmc_brcm_rdb_sd4_top.h b/include/drivers/brcm/emmc/emmc_brcm_rdb_sd4_top.h new file mode 100644 index 000000000..96c333da4 --- /dev/null +++ b/include/drivers/brcm/emmc/emmc_brcm_rdb_sd4_top.h @@ -0,0 +1,1116 @@ +/* + * Copyright (c) 2016 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef BRCM_RDB_SD4_EMMC_TOP_H +#define BRCM_RDB_SD4_EMMC_TOP_H + +#define SD4_EMMC_TOP_SYSADDR_OFFSET 0x00000000 +#define SD4_EMMC_TOP_SYSADDR_DEFAULT 0x00000000 +#define SD4_EMMC_TOP_SYSADDR_TYPE uint32_t +#define SD4_EMMC_TOP_SYSADDR_RESERVED_MASK 0x00000000 +#define SD4_EMMC_TOP_SYSADDR_SYSADDR_SHIFT 0 +#define SD4_EMMC_TOP_SYSADDR_SYSADDR_MASK 0xFFFFFFFF + +#define SD4_EMMC_TOP_BLOCK_OFFSET 0x00000004 +#define SD4_EMMC_TOP_BLOCK_DEFAULT 0x00000000 +#define SD4_EMMC_TOP_BLOCK_TYPE uint32_t +#define SD4_EMMC_TOP_BLOCK_RESERVED_MASK 0x00008000 +#define SD4_EMMC_TOP_BLOCK_BCNT_SHIFT 16 +#define SD4_EMMC_TOP_BLOCK_BCNT_MASK 0xFFFF0000 +#define SD4_EMMC_TOP_BLOCK_HSBS_SHIFT 12 +#define SD4_EMMC_TOP_BLOCK_HSBS_MASK 0x00007000 +#define SD4_EMMC_TOP_BLOCK_TBS_SHIFT 0 +#define SD4_EMMC_TOP_BLOCK_TBS_MASK 0x00000FFF + +#define SD4_EMMC_TOP_ARG_OFFSET 0x00000008 +#define SD4_EMMC_TOP_ARG_DEFAULT 0x00000000 +#define SD4_EMMC_TOP_ARG_TYPE uint32_t +#define SD4_EMMC_TOP_ARG_RESERVED_MASK 0x00000000 +#define SD4_EMMC_TOP_ARG_ARG_SHIFT 0 +#define SD4_EMMC_TOP_ARG_ARG_MASK 0xFFFFFFFF + +#define SD4_EMMC_TOP_CMD_OFFSET 0x0000000C +#define SD4_EMMC_TOP_CMD_DEFAULT 0x00000000 +#define SD4_EMMC_TOP_CMD_TYPE uint32_t +#define SD4_EMMC_TOP_CMD_RESERVED_MASK 0xC004FFC0 +#define SD4_EMMC_TOP_CMD_CIDX_SHIFT 24 +#define SD4_EMMC_TOP_CMD_CIDX_MASK 0x3F000000 +#define SD4_EMMC_TOP_CMD_CTYP_SHIFT 22 +#define SD4_EMMC_TOP_CMD_CTYP_MASK 0x00C00000 +#define SD4_EMMC_TOP_CMD_DPS_SHIFT 21 +#define SD4_EMMC_TOP_CMD_DPS_MASK 0x00200000 +#define SD4_EMMC_TOP_CMD_CCHK_EN_SHIFT 20 +#define SD4_EMMC_TOP_CMD_CCHK_EN_MASK 0x00100000 +#define SD4_EMMC_TOP_CMD_CRC_EN_SHIFT 19 +#define SD4_EMMC_TOP_CMD_CRC_EN_MASK 0x00080000 +#define SD4_EMMC_TOP_CMD_RTSEL_SHIFT 16 +#define SD4_EMMC_TOP_CMD_RTSEL_MASK 0x00030000 +#define SD4_EMMC_TOP_CMD_MSBS_SHIFT 5 +#define SD4_EMMC_TOP_CMD_MSBS_MASK 0x00000020 +#define SD4_EMMC_TOP_CMD_DTDS_SHIFT 4 +#define SD4_EMMC_TOP_CMD_DTDS_MASK 0x00000010 +#define SD4_EMMC_TOP_CMD_ACMDEN_SHIFT 2 +#define SD4_EMMC_TOP_CMD_ACMDEN_MASK 0x0000000C +#define SD4_EMMC_TOP_CMD_BCEN_SHIFT 1 +#define SD4_EMMC_TOP_CMD_BCEN_MASK 0x00000002 +#define SD4_EMMC_TOP_CMD_DMA_SHIFT 0 +#define SD4_EMMC_TOP_CMD_DMA_MASK 0x00000001 + +#define SD4_EMMC_TOP_CMD_SD4_OFFSET 0x0000000C +#define SD4_EMMC_TOP_CMD_SD4_DEFAULT 0x00000000 +#define SD4_EMMC_TOP_CMD_SD4_TYPE uint32_t +#define SD4_EMMC_TOP_CMD_SD4_RESERVED_MASK 0xC004FE00 +#define SD4_EMMC_TOP_CMD_SD4_CIDX_SHIFT 24 +#define SD4_EMMC_TOP_CMD_SD4_CIDX_MASK 0x3F000000 +#define SD4_EMMC_TOP_CMD_SD4_CTYP_SHIFT 22 +#define SD4_EMMC_TOP_CMD_SD4_CTYP_MASK 0x00C00000 +#define SD4_EMMC_TOP_CMD_SD4_DPS_SHIFT 21 +#define SD4_EMMC_TOP_CMD_SD4_DPS_MASK 0x00200000 +#define SD4_EMMC_TOP_CMD_SD4_CCHK_EN_SHIFT 20 +#define SD4_EMMC_TOP_CMD_SD4_CCHK_EN_MASK 0x00100000 +#define SD4_EMMC_TOP_CMD_SD4_CRC_EN_SHIFT 19 +#define SD4_EMMC_TOP_CMD_SD4_CRC_EN_MASK 0x00080000 +#define SD4_EMMC_TOP_CMD_SD4_RTSEL_SHIFT 16 +#define SD4_EMMC_TOP_CMD_SD4_RTSEL_MASK 0x00030000 +#define SD4_EMMC_TOP_CMD_SD4_RESPIRQDIS_SHIFT 8 +#define SD4_EMMC_TOP_CMD_SD4_RESPIRQDIS_MASK 0x00000100 +#define SD4_EMMC_TOP_CMD_SD4_RESPERRCHKEN_SHIFT 7 +#define SD4_EMMC_TOP_CMD_SD4_RESPERRCHKEN_MASK 0x00000080 +#define SD4_EMMC_TOP_CMD_SD4_RESPR1R5_SHIFT 6 +#define SD4_EMMC_TOP_CMD_SD4_RESPR1R5_MASK 0x00000040 +#define SD4_EMMC_TOP_CMD_SD4_MSBS_SHIFT 5 +#define SD4_EMMC_TOP_CMD_SD4_MSBS_MASK 0x00000020 +#define SD4_EMMC_TOP_CMD_SD4_DTDS_SHIFT 4 +#define SD4_EMMC_TOP_CMD_SD4_DTDS_MASK 0x00000010 +#define SD4_EMMC_TOP_CMD_SD4_ACMDEN_SHIFT 2 +#define SD4_EMMC_TOP_CMD_SD4_ACMDEN_MASK 0x0000000C +#define SD4_EMMC_TOP_CMD_SD4_BCEN_SHIFT 1 +#define SD4_EMMC_TOP_CMD_SD4_BCEN_MASK 0x00000002 +#define SD4_EMMC_TOP_CMD_SD4_DMA_SHIFT 0 +#define SD4_EMMC_TOP_CMD_SD4_DMA_MASK 0x00000001 + +#define SD4_EMMC_TOP_RESP0_OFFSET 0x00000010 +#define SD4_EMMC_TOP_RESP0_DEFAULT 0x00000000 +#define SD4_EMMC_TOP_RESP0_TYPE uint32_t +#define SD4_EMMC_TOP_RESP0_RESERVED_MASK 0x00000000 +#define SD4_EMMC_TOP_RESP0_RESP0_SHIFT 0 +#define SD4_EMMC_TOP_RESP0_RESP0_MASK 0xFFFFFFFF + +#define SD4_EMMC_TOP_RESP2_OFFSET 0x00000014 +#define SD4_EMMC_TOP_RESP2_DEFAULT 0x00000000 +#define SD4_EMMC_TOP_RESP2_TYPE uint32_t +#define SD4_EMMC_TOP_RESP2_RESERVED_MASK 0x00000000 +#define SD4_EMMC_TOP_RESP2_RESP2_SHIFT 0 +#define SD4_EMMC_TOP_RESP2_RESP2_MASK 0xFFFFFFFF + +#define SD4_EMMC_TOP_RESP4_OFFSET 0x00000018 +#define SD4_EMMC_TOP_RESP4_DEFAULT 0x00000000 +#define SD4_EMMC_TOP_RESP4_TYPE uint32_t +#define SD4_EMMC_TOP_RESP4_RESERVED_MASK 0x00000000 +#define SD4_EMMC_TOP_RESP4_RESP4_SHIFT 0 +#define SD4_EMMC_TOP_RESP4_RESP4_MASK 0xFFFFFFFF + +#define SD4_EMMC_TOP_RESP6_OFFSET 0x0000001C +#define SD4_EMMC_TOP_RESP6_DEFAULT 0x00000000 +#define SD4_EMMC_TOP_RESP6_TYPE uint32_t +#define SD4_EMMC_TOP_RESP6_RESERVED_MASK 0x00000000 +#define SD4_EMMC_TOP_RESP6_RESP6_SHIFT 0 +#define SD4_EMMC_TOP_RESP6_RESP6_MASK 0xFFFFFFFF + +#define SD4_EMMC_TOP_BUFDAT_OFFSET 0x00000020 +#define SD4_EMMC_TOP_BUFDAT_DEFAULT 0x00000000 +#define SD4_EMMC_TOP_BUFDAT_TYPE uint32_t +#define SD4_EMMC_TOP_BUFDAT_RESERVED_MASK 0x00000000 +#define SD4_EMMC_TOP_BUFDAT_BUFDAT_SHIFT 0 +#define SD4_EMMC_TOP_BUFDAT_BUFDAT_MASK 0xFFFFFFFF + +#define SD4_EMMC_TOP_PSTATE_OFFSET 0x00000024 +#define SD4_EMMC_TOP_PSTATE_DEFAULT 0x1FFC0000 +#define SD4_EMMC_TOP_PSTATE_TYPE uint32_t +#define SD4_EMMC_TOP_PSTATE_RESERVED_MASK 0xE000F0F0 +#define SD4_EMMC_TOP_PSTATE_DLS7_4_SHIFT 25 +#define SD4_EMMC_TOP_PSTATE_DLS7_4_MASK 0x1E000000 +#define SD4_EMMC_TOP_PSTATE_CLSL_SHIFT 24 +#define SD4_EMMC_TOP_PSTATE_CLSL_MASK 0x01000000 +#define SD4_EMMC_TOP_PSTATE_DLS3_0_SHIFT 20 +#define SD4_EMMC_TOP_PSTATE_DLS3_0_MASK 0x00F00000 +#define SD4_EMMC_TOP_PSTATE_WPSL_SHIFT 19 +#define SD4_EMMC_TOP_PSTATE_WPSL_MASK 0x00080000 +#define SD4_EMMC_TOP_PSTATE_CDPL_SHIFT 18 +#define SD4_EMMC_TOP_PSTATE_CDPL_MASK 0x00040000 +#define SD4_EMMC_TOP_PSTATE_CSS_SHIFT 17 +#define SD4_EMMC_TOP_PSTATE_CSS_MASK 0x00020000 +#define SD4_EMMC_TOP_PSTATE_CINS_SHIFT 16 +#define SD4_EMMC_TOP_PSTATE_CINS_MASK 0x00010000 +#define SD4_EMMC_TOP_PSTATE_BREN_SHIFT 11 +#define SD4_EMMC_TOP_PSTATE_BREN_MASK 0x00000800 +#define SD4_EMMC_TOP_PSTATE_BWEN_SHIFT 10 +#define SD4_EMMC_TOP_PSTATE_BWEN_MASK 0x00000400 +#define SD4_EMMC_TOP_PSTATE_RXACT_SHIFT 9 +#define SD4_EMMC_TOP_PSTATE_RXACT_MASK 0x00000200 +#define SD4_EMMC_TOP_PSTATE_WXACT_SHIFT 8 +#define SD4_EMMC_TOP_PSTATE_WXACT_MASK 0x00000100 +#define SD4_EMMC_TOP_PSTATE_RETUNE_REQ_SHIFT 3 +#define SD4_EMMC_TOP_PSTATE_RETUNE_REQ_MASK 0x00000008 +#define SD4_EMMC_TOP_PSTATE_DATACT_SHIFT 2 +#define SD4_EMMC_TOP_PSTATE_DATACT_MASK 0x00000004 +#define SD4_EMMC_TOP_PSTATE_DATINH_SHIFT 1 +#define SD4_EMMC_TOP_PSTATE_DATINH_MASK 0x00000002 +#define SD4_EMMC_TOP_PSTATE_CMDINH_SHIFT 0 +#define SD4_EMMC_TOP_PSTATE_CMDINH_MASK 0x00000001 + +#define SD4_EMMC_TOP_PSTATE_SD4_OFFSET 0x00000024 +#define SD4_EMMC_TOP_PSTATE_SD4_DEFAULT 0x01FC00F0 +#define SD4_EMMC_TOP_PSTATE_SD4_TYPE uint32_t +#define SD4_EMMC_TOP_PSTATE_SD4_RESERVED_MASK 0x1E00F000 +#define SD4_EMMC_TOP_PSTATE_SD4_STBLDET_SHIFT 31 +#define SD4_EMMC_TOP_PSTATE_SD4_STBLDET_MASK 0x80000000 +#define SD4_EMMC_TOP_PSTATE_SD4_LANESYNC_SHIFT 30 +#define SD4_EMMC_TOP_PSTATE_SD4_LANESYNC_MASK 0x40000000 +#define SD4_EMMC_TOP_PSTATE_SD4_INDORMNTSTATE_SHIFT 29 +#define SD4_EMMC_TOP_PSTATE_SD4_INDORMNTSTATE_MASK 0x20000000 +#define SD4_EMMC_TOP_PSTATE_SD4_CLSL_SHIFT 24 +#define SD4_EMMC_TOP_PSTATE_SD4_CLSL_MASK 0x01000000 +#define SD4_EMMC_TOP_PSTATE_SD4_DLS3_0_SHIFT 20 +#define SD4_EMMC_TOP_PSTATE_SD4_DLS3_0_MASK 0x00F00000 +#define SD4_EMMC_TOP_PSTATE_SD4_WPSL_SHIFT 19 +#define SD4_EMMC_TOP_PSTATE_SD4_WPSL_MASK 0x00080000 +#define SD4_EMMC_TOP_PSTATE_SD4_CDPL_SHIFT 18 +#define SD4_EMMC_TOP_PSTATE_SD4_CDPL_MASK 0x00040000 +#define SD4_EMMC_TOP_PSTATE_SD4_CSS_SHIFT 17 +#define SD4_EMMC_TOP_PSTATE_SD4_CSS_MASK 0x00020000 +#define SD4_EMMC_TOP_PSTATE_SD4_CINS_SHIFT 16 +#define SD4_EMMC_TOP_PSTATE_SD4_CINS_MASK 0x00010000 +#define SD4_EMMC_TOP_PSTATE_SD4_BREN_SHIFT 11 +#define SD4_EMMC_TOP_PSTATE_SD4_BREN_MASK 0x00000800 +#define SD4_EMMC_TOP_PSTATE_SD4_BWEN_SHIFT 10 +#define SD4_EMMC_TOP_PSTATE_SD4_BWEN_MASK 0x00000400 +#define SD4_EMMC_TOP_PSTATE_SD4_RXACT_SHIFT 9 +#define SD4_EMMC_TOP_PSTATE_SD4_RXACT_MASK 0x00000200 +#define SD4_EMMC_TOP_PSTATE_SD4_WXACT_SHIFT 8 +#define SD4_EMMC_TOP_PSTATE_SD4_WXACT_MASK 0x00000100 +#define SD4_EMMC_TOP_PSTATE_SD4_DLS7_4_SHIFT 4 +#define SD4_EMMC_TOP_PSTATE_SD4_DLS7_4_MASK 0x000000F0 +#define SD4_EMMC_TOP_PSTATE_SD4_RETUNE_REQ_SHIFT 3 +#define SD4_EMMC_TOP_PSTATE_SD4_RETUNE_REQ_MASK 0x00000008 +#define SD4_EMMC_TOP_PSTATE_SD4_DATACT_SHIFT 2 +#define SD4_EMMC_TOP_PSTATE_SD4_DATACT_MASK 0x00000004 +#define SD4_EMMC_TOP_PSTATE_SD4_DATINH_SHIFT 1 +#define SD4_EMMC_TOP_PSTATE_SD4_DATINH_MASK 0x00000002 +#define SD4_EMMC_TOP_PSTATE_SD4_CMDINH_SHIFT 0 +#define SD4_EMMC_TOP_PSTATE_SD4_CMDINH_MASK 0x00000001 + +#define SD4_EMMC_TOP_CTRL_OFFSET 0x00000028 +#define SD4_EMMC_TOP_CTRL_DEFAULT 0x00000000 +#define SD4_EMMC_TOP_CTRL_TYPE uint32_t +#define SD4_EMMC_TOP_CTRL_RESERVED_MASK 0xF800E000 +#define SD4_EMMC_TOP_CTRL_WAKENRMV_SHIFT 26 +#define SD4_EMMC_TOP_CTRL_WAKENRMV_MASK 0x04000000 +#define SD4_EMMC_TOP_CTRL_WAKENINS_SHIFT 25 +#define SD4_EMMC_TOP_CTRL_WAKENINS_MASK 0x02000000 +#define SD4_EMMC_TOP_CTRL_WAKENIRQ_SHIFT 24 +#define SD4_EMMC_TOP_CTRL_WAKENIRQ_MASK 0x01000000 +#define SD4_EMMC_TOP_CTRL_BOOTACK_SHIFT 23 +#define SD4_EMMC_TOP_CTRL_BOOTACK_MASK 0x00800000 +#define SD4_EMMC_TOP_CTRL_ATLBOOTEN_SHIFT 22 +#define SD4_EMMC_TOP_CTRL_ATLBOOTEN_MASK 0x00400000 +#define SD4_EMMC_TOP_CTRL_BOOTEN_SHIFT 21 +#define SD4_EMMC_TOP_CTRL_BOOTEN_MASK 0x00200000 +#define SD4_EMMC_TOP_CTRL_SPIMODE_SHIFT 20 +#define SD4_EMMC_TOP_CTRL_SPIMODE_MASK 0x00100000 +#define SD4_EMMC_TOP_CTRL_BLKIRQ_SHIFT 19 +#define SD4_EMMC_TOP_CTRL_BLKIRQ_MASK 0x00080000 +#define SD4_EMMC_TOP_CTRL_RDWTCRTL_SHIFT 18 +#define SD4_EMMC_TOP_CTRL_RDWTCRTL_MASK 0x00040000 +#define SD4_EMMC_TOP_CTRL_CONTREQ_SHIFT 17 +#define SD4_EMMC_TOP_CTRL_CONTREQ_MASK 0x00020000 +#define SD4_EMMC_TOP_CTRL_BLKSTPREQ_SHIFT 16 +#define SD4_EMMC_TOP_CTRL_BLKSTPREQ_MASK 0x00010000 +#define SD4_EMMC_TOP_CTRL_HRESET_SHIFT 12 +#define SD4_EMMC_TOP_CTRL_HRESET_MASK 0x00001000 +#define SD4_EMMC_TOP_CTRL_SDVSELVDD1_SHIFT 9 +#define SD4_EMMC_TOP_CTRL_SDVSELVDD1_MASK 0x00000E00 +#define SD4_EMMC_TOP_CTRL_SDPWR_SHIFT 8 +#define SD4_EMMC_TOP_CTRL_SDPWR_MASK 0x00000100 +#define SD4_EMMC_TOP_CTRL_CDSD_SHIFT 7 +#define SD4_EMMC_TOP_CTRL_CDSD_MASK 0x00000080 +#define SD4_EMMC_TOP_CTRL_CDTL_SHIFT 6 +#define SD4_EMMC_TOP_CTRL_CDTL_MASK 0x00000040 +#define SD4_EMMC_TOP_CTRL_SDB_SHIFT 5 +#define SD4_EMMC_TOP_CTRL_SDB_MASK 0x00000020 +#define SD4_EMMC_TOP_CTRL_DMASEL_SHIFT 3 +#define SD4_EMMC_TOP_CTRL_DMASEL_MASK 0x00000018 +#define SD4_EMMC_TOP_CTRL_HSEN_SHIFT 2 +#define SD4_EMMC_TOP_CTRL_HSEN_MASK 0x00000004 +#define SD4_EMMC_TOP_CTRL_DXTW_SHIFT 1 +#define SD4_EMMC_TOP_CTRL_DXTW_MASK 0x00000002 +#define SD4_EMMC_TOP_CTRL_LEDCTL_SHIFT 0 +#define SD4_EMMC_TOP_CTRL_LEDCTL_MASK 0x00000001 + +#define SD4_EMMC_TOP_CTRL_SD4_OFFSET 0x00000028 +#define SD4_EMMC_TOP_CTRL_SD4_DEFAULT 0x00000000 +#define SD4_EMMC_TOP_CTRL_SD4_TYPE uint32_t +#define SD4_EMMC_TOP_CTRL_SD4_RESERVED_MASK 0xF8F00000 +#define SD4_EMMC_TOP_CTRL_SD4_WAKENRMV_SHIFT 26 +#define SD4_EMMC_TOP_CTRL_SD4_WAKENRMV_MASK 0x04000000 +#define SD4_EMMC_TOP_CTRL_SD4_WAKENINS_SHIFT 25 +#define SD4_EMMC_TOP_CTRL_SD4_WAKENINS_MASK 0x02000000 +#define SD4_EMMC_TOP_CTRL_SD4_WAKENIRQ_SHIFT 24 +#define SD4_EMMC_TOP_CTRL_SD4_WAKENIRQ_MASK 0x01000000 +#define SD4_EMMC_TOP_CTRL_SD4_BLKIRQ_SHIFT 19 +#define SD4_EMMC_TOP_CTRL_SD4_BLKIRQ_MASK 0x00080000 +#define SD4_EMMC_TOP_CTRL_SD4_RDWTCRTL_SHIFT 18 +#define SD4_EMMC_TOP_CTRL_SD4_RDWTCRTL_MASK 0x00040000 +#define SD4_EMMC_TOP_CTRL_SD4_CONTREQ_SHIFT 17 +#define SD4_EMMC_TOP_CTRL_SD4_CONTREQ_MASK 0x00020000 +#define SD4_EMMC_TOP_CTRL_SD4_BLKSTPREQ_SHIFT 16 +#define SD4_EMMC_TOP_CTRL_SD4_BLKSTPREQ_MASK 0x00010000 +#define SD4_EMMC_TOP_CTRL_SD4_SDVSELVDD2_SHIFT 13 +#define SD4_EMMC_TOP_CTRL_SD4_SDVSELVDD2_MASK 0x0000E000 +#define SD4_EMMC_TOP_CTRL_SD4_SDPWRVDD2_SHIFT 12 +#define SD4_EMMC_TOP_CTRL_SD4_SDPWRVDD2_MASK 0x00001000 +#define SD4_EMMC_TOP_CTRL_SD4_SDVSELVDD1_SHIFT 9 +#define SD4_EMMC_TOP_CTRL_SD4_SDVSELVDD1_MASK 0x00000E00 +#define SD4_EMMC_TOP_CTRL_SD4_SDPWR_SHIFT 8 +#define SD4_EMMC_TOP_CTRL_SD4_SDPWR_MASK 0x00000100 +#define SD4_EMMC_TOP_CTRL_SD4_CDSD_SHIFT 7 +#define SD4_EMMC_TOP_CTRL_SD4_CDSD_MASK 0x00000080 +#define SD4_EMMC_TOP_CTRL_SD4_CDTL_SHIFT 6 +#define SD4_EMMC_TOP_CTRL_SD4_CDTL_MASK 0x00000040 +#define SD4_EMMC_TOP_CTRL_SD4_SDB_SHIFT 5 +#define SD4_EMMC_TOP_CTRL_SD4_SDB_MASK 0x00000020 +#define SD4_EMMC_TOP_CTRL_SD4_DMASEL_SHIFT 3 +#define SD4_EMMC_TOP_CTRL_SD4_DMASEL_MASK 0x00000018 +#define SD4_EMMC_TOP_CTRL_SD4_HSEN_SHIFT 2 +#define SD4_EMMC_TOP_CTRL_SD4_HSEN_MASK 0x00000004 +#define SD4_EMMC_TOP_CTRL_SD4_DXTW_SHIFT 1 +#define SD4_EMMC_TOP_CTRL_SD4_DXTW_MASK 0x00000002 +#define SD4_EMMC_TOP_CTRL_SD4_LEDCTL_SHIFT 0 +#define SD4_EMMC_TOP_CTRL_SD4_LEDCTL_MASK 0x00000001 + +#define SD4_EMMC_TOP_CTRL1_OFFSET 0x0000002C +#define SD4_EMMC_TOP_CTRL1_DEFAULT 0x00000000 +#define SD4_EMMC_TOP_CTRL1_TYPE uint32_t +#define SD4_EMMC_TOP_CTRL1_RESERVED_MASK 0xF8F00018 +#define SD4_EMMC_TOP_CTRL1_DATRST_SHIFT 26 +#define SD4_EMMC_TOP_CTRL1_DATRST_MASK 0x04000000 +#define SD4_EMMC_TOP_CTRL1_CMDRST_SHIFT 25 +#define SD4_EMMC_TOP_CTRL1_CMDRST_MASK 0x02000000 +#define SD4_EMMC_TOP_CTRL1_RST_SHIFT 24 +#define SD4_EMMC_TOP_CTRL1_RST_MASK 0x01000000 +#define SD4_EMMC_TOP_CTRL1_DTCNT_SHIFT 16 +#define SD4_EMMC_TOP_CTRL1_DTCNT_MASK 0x000F0000 +#define SD4_EMMC_TOP_CTRL1_SDCLKSEL_SHIFT 8 +#define SD4_EMMC_TOP_CTRL1_SDCLKSEL_MASK 0x0000FF00 +#define SD4_EMMC_TOP_CTRL1_SDCLKSEL_UP_SHIFT 6 +#define SD4_EMMC_TOP_CTRL1_SDCLKSEL_UP_MASK 0x000000C0 +#define SD4_EMMC_TOP_CTRL1_CLKGENSEL_SHIFT 5 +#define SD4_EMMC_TOP_CTRL1_CLKGENSEL_MASK 0x00000020 +#define SD4_EMMC_TOP_CTRL1_SDCLKEN_SHIFT 2 +#define SD4_EMMC_TOP_CTRL1_SDCLKEN_MASK 0x00000004 +#define SD4_EMMC_TOP_CTRL1_ICLKSTB_SHIFT 1 +#define SD4_EMMC_TOP_CTRL1_ICLKSTB_MASK 0x00000002 +#define SD4_EMMC_TOP_CTRL1_ICLKEN_SHIFT 0 +#define SD4_EMMC_TOP_CTRL1_ICLKEN_MASK 0x00000001 + +#define SD4_EMMC_TOP_INTR_OFFSET 0x00000030 +#define SD4_EMMC_TOP_INTR_DEFAULT 0x00000000 +#define SD4_EMMC_TOP_INTR_TYPE uint32_t +#define SD4_EMMC_TOP_INTR_RESERVED_MASK 0xEC000000 +#define SD4_EMMC_TOP_INTR_TRESPERR_SHIFT 28 +#define SD4_EMMC_TOP_INTR_TRESPERR_MASK 0x10000000 +#define SD4_EMMC_TOP_INTR_ADMAERR_SHIFT 25 +#define SD4_EMMC_TOP_INTR_ADMAERR_MASK 0x02000000 +#define SD4_EMMC_TOP_INTR_CMDERROR_SHIFT 24 +#define SD4_EMMC_TOP_INTR_CMDERROR_MASK 0x01000000 +#define SD4_EMMC_TOP_INTR_IERR_SHIFT 23 +#define SD4_EMMC_TOP_INTR_IERR_MASK 0x00800000 +#define SD4_EMMC_TOP_INTR_DEBERR_SHIFT 22 +#define SD4_EMMC_TOP_INTR_DEBERR_MASK 0x00400000 +#define SD4_EMMC_TOP_INTR_DCRCERR_SHIFT 21 +#define SD4_EMMC_TOP_INTR_DCRCERR_MASK 0x00200000 +#define SD4_EMMC_TOP_INTR_DTOERR_SHIFT 20 +#define SD4_EMMC_TOP_INTR_DTOERR_MASK 0x00100000 +#define SD4_EMMC_TOP_INTR_CMDIDXERR_SHIFT 19 +#define SD4_EMMC_TOP_INTR_CMDIDXERR_MASK 0x00080000 +#define SD4_EMMC_TOP_INTR_CEBERR_SHIFT 18 +#define SD4_EMMC_TOP_INTR_CEBERR_MASK 0x00040000 +#define SD4_EMMC_TOP_INTR_CCRCERR_SHIFT 17 +#define SD4_EMMC_TOP_INTR_CCRCERR_MASK 0x00020000 +#define SD4_EMMC_TOP_INTR_CTOERR_SHIFT 16 +#define SD4_EMMC_TOP_INTR_CTOERR_MASK 0x00010000 +#define SD4_EMMC_TOP_INTR_ERRIRQ_SHIFT 15 +#define SD4_EMMC_TOP_INTR_ERRIRQ_MASK 0x00008000 +#define SD4_EMMC_TOP_INTR_BTIRQ_SHIFT 14 +#define SD4_EMMC_TOP_INTR_BTIRQ_MASK 0x00004000 +#define SD4_EMMC_TOP_INTR_BTACKRX_SHIFT 13 +#define SD4_EMMC_TOP_INTR_BTACKRX_MASK 0x00002000 +#define SD4_EMMC_TOP_INTR_RETUNE_EVENT_SHIFT 12 +#define SD4_EMMC_TOP_INTR_RETUNE_EVENT_MASK 0x00001000 +#define SD4_EMMC_TOP_INTR_INT_C_SHIFT 11 +#define SD4_EMMC_TOP_INTR_INT_C_MASK 0x00000800 +#define SD4_EMMC_TOP_INTR_INT_B_SHIFT 10 +#define SD4_EMMC_TOP_INTR_INT_B_MASK 0x00000400 +#define SD4_EMMC_TOP_INTR_INT_A_SHIFT 9 +#define SD4_EMMC_TOP_INTR_INT_A_MASK 0x00000200 +#define SD4_EMMC_TOP_INTR_CRDIRQ_SHIFT 8 +#define SD4_EMMC_TOP_INTR_CRDIRQ_MASK 0x00000100 +#define SD4_EMMC_TOP_INTR_CRDRMV_SHIFT 7 +#define SD4_EMMC_TOP_INTR_CRDRMV_MASK 0x00000080 +#define SD4_EMMC_TOP_INTR_CRDINS_SHIFT 6 +#define SD4_EMMC_TOP_INTR_CRDINS_MASK 0x00000040 +#define SD4_EMMC_TOP_INTR_BRRDY_SHIFT 5 +#define SD4_EMMC_TOP_INTR_BRRDY_MASK 0x00000020 +#define SD4_EMMC_TOP_INTR_BWRDY_SHIFT 4 +#define SD4_EMMC_TOP_INTR_BWRDY_MASK 0x00000010 +#define SD4_EMMC_TOP_INTR_DMAIRQ_SHIFT 3 +#define SD4_EMMC_TOP_INTR_DMAIRQ_MASK 0x00000008 +#define SD4_EMMC_TOP_INTR_BLKENT_SHIFT 2 +#define SD4_EMMC_TOP_INTR_BLKENT_MASK 0x00000004 +#define SD4_EMMC_TOP_INTR_TXDONE_SHIFT 1 +#define SD4_EMMC_TOP_INTR_TXDONE_MASK 0x00000002 +#define SD4_EMMC_TOP_INTR_CMDDONE_SHIFT 0 +#define SD4_EMMC_TOP_INTR_CMDDONE_MASK 0x00000001 + +#define SD4_EMMC_TOP_INTR_SD4_OFFSET 0x00000030 +#define SD4_EMMC_TOP_INTR_SD4_DEFAULT 0x00000000 +#define SD4_EMMC_TOP_INTR_SD4_TYPE uint32_t +#define SD4_EMMC_TOP_INTR_SD4_RESERVED_MASK 0xF0006000 +#define SD4_EMMC_TOP_INTR_SD4_TRESPERR_SHIFT 27 +#define SD4_EMMC_TOP_INTR_SD4_TRESPERR_MASK 0x08000000 +#define SD4_EMMC_TOP_INTR_SD4_TUNEERR_SHIFT 26 +#define SD4_EMMC_TOP_INTR_SD4_TUNEERR_MASK 0x04000000 +#define SD4_EMMC_TOP_INTR_SD4_ADMAERR_SHIFT 25 +#define SD4_EMMC_TOP_INTR_SD4_ADMAERR_MASK 0x02000000 +#define SD4_EMMC_TOP_INTR_SD4_CMDERROR_SHIFT 24 +#define SD4_EMMC_TOP_INTR_SD4_CMDERROR_MASK 0x01000000 +#define SD4_EMMC_TOP_INTR_SD4_IERR_SHIFT 23 +#define SD4_EMMC_TOP_INTR_SD4_IERR_MASK 0x00800000 +#define SD4_EMMC_TOP_INTR_SD4_DEBERR_SHIFT 22 +#define SD4_EMMC_TOP_INTR_SD4_DEBERR_MASK 0x00400000 +#define SD4_EMMC_TOP_INTR_SD4_DCRCERR_SHIFT 21 +#define SD4_EMMC_TOP_INTR_SD4_DCRCERR_MASK 0x00200000 +#define SD4_EMMC_TOP_INTR_SD4_DTOERR_SHIFT 20 +#define SD4_EMMC_TOP_INTR_SD4_DTOERR_MASK 0x00100000 +#define SD4_EMMC_TOP_INTR_SD4_CMDIDXERR_SHIFT 19 +#define SD4_EMMC_TOP_INTR_SD4_CMDIDXERR_MASK 0x00080000 +#define SD4_EMMC_TOP_INTR_SD4_CEBERR_SHIFT 18 +#define SD4_EMMC_TOP_INTR_SD4_CEBERR_MASK 0x00040000 +#define SD4_EMMC_TOP_INTR_SD4_CCRCERR_SHIFT 17 +#define SD4_EMMC_TOP_INTR_SD4_CCRCERR_MASK 0x00020000 +#define SD4_EMMC_TOP_INTR_SD4_CTOERR_SHIFT 16 +#define SD4_EMMC_TOP_INTR_SD4_CTOERR_MASK 0x00010000 +#define SD4_EMMC_TOP_INTR_SD4_ERRIRQ_SHIFT 15 +#define SD4_EMMC_TOP_INTR_SD4_ERRIRQ_MASK 0x00008000 +#define SD4_EMMC_TOP_INTR_SD4_RETUNE_EVENT_SHIFT 12 +#define SD4_EMMC_TOP_INTR_SD4_RETUNE_EVENT_MASK 0x00001000 +#define SD4_EMMC_TOP_INTR_SD4_INT_C_SHIFT 11 +#define SD4_EMMC_TOP_INTR_SD4_INT_C_MASK 0x00000800 +#define SD4_EMMC_TOP_INTR_SD4_INT_B_SHIFT 10 +#define SD4_EMMC_TOP_INTR_SD4_INT_B_MASK 0x00000400 +#define SD4_EMMC_TOP_INTR_SD4_INT_A_SHIFT 9 +#define SD4_EMMC_TOP_INTR_SD4_INT_A_MASK 0x00000200 +#define SD4_EMMC_TOP_INTR_SD4_CRDIRQ_SHIFT 8 +#define SD4_EMMC_TOP_INTR_SD4_CRDIRQ_MASK 0x00000100 +#define SD4_EMMC_TOP_INTR_SD4_CRDRMV_SHIFT 7 +#define SD4_EMMC_TOP_INTR_SD4_CRDRMV_MASK 0x00000080 +#define SD4_EMMC_TOP_INTR_SD4_CRDINS_SHIFT 6 +#define SD4_EMMC_TOP_INTR_SD4_CRDINS_MASK 0x00000040 +#define SD4_EMMC_TOP_INTR_SD4_BRRDY_SHIFT 5 +#define SD4_EMMC_TOP_INTR_SD4_BRRDY_MASK 0x00000020 +#define SD4_EMMC_TOP_INTR_SD4_BWRDY_SHIFT 4 +#define SD4_EMMC_TOP_INTR_SD4_BWRDY_MASK 0x00000010 +#define SD4_EMMC_TOP_INTR_SD4_DMAIRQ_SHIFT 3 +#define SD4_EMMC_TOP_INTR_SD4_DMAIRQ_MASK 0x00000008 +#define SD4_EMMC_TOP_INTR_SD4_BLKENT_SHIFT 2 +#define SD4_EMMC_TOP_INTR_SD4_BLKENT_MASK 0x00000004 +#define SD4_EMMC_TOP_INTR_SD4_TXDONE_SHIFT 1 +#define SD4_EMMC_TOP_INTR_SD4_TXDONE_MASK 0x00000002 +#define SD4_EMMC_TOP_INTR_SD4_CMDDONE_SHIFT 0 +#define SD4_EMMC_TOP_INTR_SD4_CMDDONE_MASK 0x00000001 + +#define SD4_EMMC_TOP_INTREN1_OFFSET 0x00000034 +#define SD4_EMMC_TOP_INTREN1_DEFAULT 0x00000000 +#define SD4_EMMC_TOP_INTREN1_TYPE uint32_t +#define SD4_EMMC_TOP_INTREN1_RESERVED_MASK 0xEC000000 +#define SD4_EMMC_TOP_INTREN1_TRESPERREN_SHIFT 28 +#define SD4_EMMC_TOP_INTREN1_TRESPERREN_MASK 0x10000000 +#define SD4_EMMC_TOP_INTREN1_ADMAEREN_SHIFT 25 +#define SD4_EMMC_TOP_INTREN1_ADMAEREN_MASK 0x02000000 +#define SD4_EMMC_TOP_INTREN1_CMDERREN_SHIFT 24 +#define SD4_EMMC_TOP_INTREN1_CMDERREN_MASK 0x01000000 +#define SD4_EMMC_TOP_INTREN1_ILIMERREN_SHIFT 23 +#define SD4_EMMC_TOP_INTREN1_ILIMERREN_MASK 0x00800000 +#define SD4_EMMC_TOP_INTREN1_DEBERREN_SHIFT 22 +#define SD4_EMMC_TOP_INTREN1_DEBERREN_MASK 0x00400000 +#define SD4_EMMC_TOP_INTREN1_DCRCERREN_SHIFT 21 +#define SD4_EMMC_TOP_INTREN1_DCRCERREN_MASK 0x00200000 +#define SD4_EMMC_TOP_INTREN1_DTOERREN_SHIFT 20 +#define SD4_EMMC_TOP_INTREN1_DTOERREN_MASK 0x00100000 +#define SD4_EMMC_TOP_INTREN1_CIDXERREN_SHIFT 19 +#define SD4_EMMC_TOP_INTREN1_CIDXERREN_MASK 0x00080000 +#define SD4_EMMC_TOP_INTREN1_CEBERREN_SHIFT 18 +#define SD4_EMMC_TOP_INTREN1_CEBERREN_MASK 0x00040000 +#define SD4_EMMC_TOP_INTREN1_CMDCRCEN_SHIFT 17 +#define SD4_EMMC_TOP_INTREN1_CMDCRCEN_MASK 0x00020000 +#define SD4_EMMC_TOP_INTREN1_CMDTOEN_SHIFT 16 +#define SD4_EMMC_TOP_INTREN1_CMDTOEN_MASK 0x00010000 +#define SD4_EMMC_TOP_INTREN1_FIXZ_SHIFT 15 +#define SD4_EMMC_TOP_INTREN1_FIXZ_MASK 0x00008000 +#define SD4_EMMC_TOP_INTREN1_BTIRQEN_SHIFT 14 +#define SD4_EMMC_TOP_INTREN1_BTIRQEN_MASK 0x00004000 +#define SD4_EMMC_TOP_INTREN1_BTACKRXEN_SHIFT 13 +#define SD4_EMMC_TOP_INTREN1_BTACKRXEN_MASK 0x00002000 +#define SD4_EMMC_TOP_INTREN1_RETUNE_EVENTEN_SHIFT 12 +#define SD4_EMMC_TOP_INTREN1_RETUNE_EVENTEN_MASK 0x00001000 +#define SD4_EMMC_TOP_INTREN1_INT_C_EN_SHIFT 11 +#define SD4_EMMC_TOP_INTREN1_INT_C_EN_MASK 0x00000800 +#define SD4_EMMC_TOP_INTREN1_INT_B_EN_SHIFT 10 +#define SD4_EMMC_TOP_INTREN1_INT_B_EN_MASK 0x00000400 +#define SD4_EMMC_TOP_INTREN1_INT_A_EN_SHIFT 9 +#define SD4_EMMC_TOP_INTREN1_INT_A_EN_MASK 0x00000200 +#define SD4_EMMC_TOP_INTREN1_CIRQEN_SHIFT 8 +#define SD4_EMMC_TOP_INTREN1_CIRQEN_MASK 0x00000100 +#define SD4_EMMC_TOP_INTREN1_CRDRMVEN_SHIFT 7 +#define SD4_EMMC_TOP_INTREN1_CRDRMVEN_MASK 0x00000080 +#define SD4_EMMC_TOP_INTREN1_CRDINSEN_SHIFT 6 +#define SD4_EMMC_TOP_INTREN1_CRDINSEN_MASK 0x00000040 +#define SD4_EMMC_TOP_INTREN1_BUFRREN_SHIFT 5 +#define SD4_EMMC_TOP_INTREN1_BUFRREN_MASK 0x00000020 +#define SD4_EMMC_TOP_INTREN1_BUFWREN_SHIFT 4 +#define SD4_EMMC_TOP_INTREN1_BUFWREN_MASK 0x00000010 +#define SD4_EMMC_TOP_INTREN1_DMAIRQEN_SHIFT 3 +#define SD4_EMMC_TOP_INTREN1_DMAIRQEN_MASK 0x00000008 +#define SD4_EMMC_TOP_INTREN1_BLKEN_SHIFT 2 +#define SD4_EMMC_TOP_INTREN1_BLKEN_MASK 0x00000004 +#define SD4_EMMC_TOP_INTREN1_TXDONEEN_SHIFT 1 +#define SD4_EMMC_TOP_INTREN1_TXDONEEN_MASK 0x00000002 +#define SD4_EMMC_TOP_INTREN1_CMDDONEEN_SHIFT 0 +#define SD4_EMMC_TOP_INTREN1_CMDDONEEN_MASK 0x00000001 + +#define SD4_EMMC_TOP_INTREN1_SD4_OFFSET 0x00000034 +#define SD4_EMMC_TOP_INTREN1_SD4_DEFAULT 0x00000000 +#define SD4_EMMC_TOP_INTREN1_SD4_TYPE uint32_t +#define SD4_EMMC_TOP_INTREN1_SD4_RESERVED_MASK 0x00006000 +#define SD4_EMMC_TOP_INTREN1_SD4_VNDRERREN_SHIFT 28 +#define SD4_EMMC_TOP_INTREN1_SD4_VNDRERREN_MASK 0xF0000000 +#define SD4_EMMC_TOP_INTREN1_SD4_TRESPERREN_SHIFT 27 +#define SD4_EMMC_TOP_INTREN1_SD4_TRESPERREN_MASK 0x08000000 +#define SD4_EMMC_TOP_INTREN1_SD4_TUNEERREN_SHIFT 26 +#define SD4_EMMC_TOP_INTREN1_SD4_TUNEERREN_MASK 0x04000000 +#define SD4_EMMC_TOP_INTREN1_SD4_ADMAEREN_SHIFT 25 +#define SD4_EMMC_TOP_INTREN1_SD4_ADMAEREN_MASK 0x02000000 +#define SD4_EMMC_TOP_INTREN1_SD4_CMDERREN_SHIFT 24 +#define SD4_EMMC_TOP_INTREN1_SD4_CMDERREN_MASK 0x01000000 +#define SD4_EMMC_TOP_INTREN1_SD4_ILIMERREN_SHIFT 23 +#define SD4_EMMC_TOP_INTREN1_SD4_ILIMERREN_MASK 0x00800000 +#define SD4_EMMC_TOP_INTREN1_SD4_DEBERREN_SHIFT 22 +#define SD4_EMMC_TOP_INTREN1_SD4_DEBERREN_MASK 0x00400000 +#define SD4_EMMC_TOP_INTREN1_SD4_DCRCERREN_SHIFT 21 +#define SD4_EMMC_TOP_INTREN1_SD4_DCRCERREN_MASK 0x00200000 +#define SD4_EMMC_TOP_INTREN1_SD4_DTOERREN_SHIFT 20 +#define SD4_EMMC_TOP_INTREN1_SD4_DTOERREN_MASK 0x00100000 +#define SD4_EMMC_TOP_INTREN1_SD4_CIDXERREN_SHIFT 19 +#define SD4_EMMC_TOP_INTREN1_SD4_CIDXERREN_MASK 0x00080000 +#define SD4_EMMC_TOP_INTREN1_SD4_CEBERREN_SHIFT 18 +#define SD4_EMMC_TOP_INTREN1_SD4_CEBERREN_MASK 0x00040000 +#define SD4_EMMC_TOP_INTREN1_SD4_CMDCRCEN_SHIFT 17 +#define SD4_EMMC_TOP_INTREN1_SD4_CMDCRCEN_MASK 0x00020000 +#define SD4_EMMC_TOP_INTREN1_SD4_CMDTOEN_SHIFT 16 +#define SD4_EMMC_TOP_INTREN1_SD4_CMDTOEN_MASK 0x00010000 +#define SD4_EMMC_TOP_INTREN1_SD4_FIXZ_SHIFT 15 +#define SD4_EMMC_TOP_INTREN1_SD4_FIXZ_MASK 0x00008000 +#define SD4_EMMC_TOP_INTREN1_SD4_RETUNE_EVENTEN_SHIFT 12 +#define SD4_EMMC_TOP_INTREN1_SD4_RETUNE_EVENTEN_MASK 0x00001000 +#define SD4_EMMC_TOP_INTREN1_SD4_INT_C_EN_SHIFT 11 +#define SD4_EMMC_TOP_INTREN1_SD4_INT_C_EN_MASK 0x00000800 +#define SD4_EMMC_TOP_INTREN1_SD4_INT_B_EN_SHIFT 10 +#define SD4_EMMC_TOP_INTREN1_SD4_INT_B_EN_MASK 0x00000400 +#define SD4_EMMC_TOP_INTREN1_SD4_INT_A_EN_SHIFT 9 +#define SD4_EMMC_TOP_INTREN1_SD4_INT_A_EN_MASK 0x00000200 +#define SD4_EMMC_TOP_INTREN1_SD4_CIRQEN_SHIFT 8 +#define SD4_EMMC_TOP_INTREN1_SD4_CIRQEN_MASK 0x00000100 +#define SD4_EMMC_TOP_INTREN1_SD4_CRDRMVEN_SHIFT 7 +#define SD4_EMMC_TOP_INTREN1_SD4_CRDRMVEN_MASK 0x00000080 +#define SD4_EMMC_TOP_INTREN1_SD4_CRDINSEN_SHIFT 6 +#define SD4_EMMC_TOP_INTREN1_SD4_CRDINSEN_MASK 0x00000040 +#define SD4_EMMC_TOP_INTREN1_SD4_BUFRREN_SHIFT 5 +#define SD4_EMMC_TOP_INTREN1_SD4_BUFRREN_MASK 0x00000020 +#define SD4_EMMC_TOP_INTREN1_SD4_BUFWREN_SHIFT 4 +#define SD4_EMMC_TOP_INTREN1_SD4_BUFWREN_MASK 0x00000010 +#define SD4_EMMC_TOP_INTREN1_SD4_DMAIRQEN_SHIFT 3 +#define SD4_EMMC_TOP_INTREN1_SD4_DMAIRQEN_MASK 0x00000008 +#define SD4_EMMC_TOP_INTREN1_SD4_BLKEN_SHIFT 2 +#define SD4_EMMC_TOP_INTREN1_SD4_BLKEN_MASK 0x00000004 +#define SD4_EMMC_TOP_INTREN1_SD4_TXDONEEN_SHIFT 1 +#define SD4_EMMC_TOP_INTREN1_SD4_TXDONEEN_MASK 0x00000002 +#define SD4_EMMC_TOP_INTREN1_SD4_CMDDONEEN_SHIFT 0 +#define SD4_EMMC_TOP_INTREN1_SD4_CMDDONEEN_MASK 0x00000001 + +#define SD4_EMMC_TOP_INTREN2_OFFSET 0x00000038 +#define SD4_EMMC_TOP_INTREN2_DEFAULT 0x00000000 +#define SD4_EMMC_TOP_INTREN2_TYPE uint32_t +#define SD4_EMMC_TOP_INTREN2_RESERVED_MASK 0xEC000000 +#define SD4_EMMC_TOP_INTREN2_TRESPERRSEN_SHIFT 28 +#define SD4_EMMC_TOP_INTREN2_TRESPERRSEN_MASK 0x10000000 +#define SD4_EMMC_TOP_INTREN2_ADMASIGEN_SHIFT 25 +#define SD4_EMMC_TOP_INTREN2_ADMASIGEN_MASK 0x02000000 +#define SD4_EMMC_TOP_INTREN2_CMDSIGEN_SHIFT 24 +#define SD4_EMMC_TOP_INTREN2_CMDSIGEN_MASK 0x01000000 +#define SD4_EMMC_TOP_INTREN2_ILIMSIGEN_SHIFT 23 +#define SD4_EMMC_TOP_INTREN2_ILIMSIGEN_MASK 0x00800000 +#define SD4_EMMC_TOP_INTREN2_DEBSIGEN_SHIFT 22 +#define SD4_EMMC_TOP_INTREN2_DEBSIGEN_MASK 0x00400000 +#define SD4_EMMC_TOP_INTREN2_DCRCSIGEN_SHIFT 21 +#define SD4_EMMC_TOP_INTREN2_DCRCSIGEN_MASK 0x00200000 +#define SD4_EMMC_TOP_INTREN2_DTOSIGEN_SHIFT 20 +#define SD4_EMMC_TOP_INTREN2_DTOSIGEN_MASK 0x00100000 +#define SD4_EMMC_TOP_INTREN2_CIDXSIGEN_SHIFT 19 +#define SD4_EMMC_TOP_INTREN2_CIDXSIGEN_MASK 0x00080000 +#define SD4_EMMC_TOP_INTREN2_CEBSIGEN_SHIFT 18 +#define SD4_EMMC_TOP_INTREN2_CEBSIGEN_MASK 0x00040000 +#define SD4_EMMC_TOP_INTREN2_CMDCRCSIGEN_SHIFT 17 +#define SD4_EMMC_TOP_INTREN2_CMDCRCSIGEN_MASK 0x00020000 +#define SD4_EMMC_TOP_INTREN2_CMDTOSIGEN_SHIFT 16 +#define SD4_EMMC_TOP_INTREN2_CMDTOSIGEN_MASK 0x00010000 +#define SD4_EMMC_TOP_INTREN2_FIXZERO_SHIFT 15 +#define SD4_EMMC_TOP_INTREN2_FIXZERO_MASK 0x00008000 +#define SD4_EMMC_TOP_INTREN2_BTIRQSEN_SHIFT 14 +#define SD4_EMMC_TOP_INTREN2_BTIRQSEN_MASK 0x00004000 +#define SD4_EMMC_TOP_INTREN2_BTACKRXSEN_SHIFT 13 +#define SD4_EMMC_TOP_INTREN2_BTACKRXSEN_MASK 0x00002000 +#define SD4_EMMC_TOP_INTREN2_RETUNE_EVENTSIGEN_SHIFT 12 +#define SD4_EMMC_TOP_INTREN2_RETUNE_EVENTSIGEN_MASK 0x00001000 +#define SD4_EMMC_TOP_INTREN2_INT_C_SIGEN_SHIFT 11 +#define SD4_EMMC_TOP_INTREN2_INT_C_SIGEN_MASK 0x00000800 +#define SD4_EMMC_TOP_INTREN2_INT_B_SIGEN_SHIFT 10 +#define SD4_EMMC_TOP_INTREN2_INT_B_SIGEN_MASK 0x00000400 +#define SD4_EMMC_TOP_INTREN2_INT_A_SIGEN_SHIFT 9 +#define SD4_EMMC_TOP_INTREN2_INT_A_SIGEN_MASK 0x00000200 +#define SD4_EMMC_TOP_INTREN2_CRDIRQEN_SHIFT 8 +#define SD4_EMMC_TOP_INTREN2_CRDIRQEN_MASK 0x00000100 +#define SD4_EMMC_TOP_INTREN2_CRDRVMEN_SHIFT 7 +#define SD4_EMMC_TOP_INTREN2_CRDRVMEN_MASK 0x00000080 +#define SD4_EMMC_TOP_INTREN2_CRDINSEN_SHIFT 6 +#define SD4_EMMC_TOP_INTREN2_CRDINSEN_MASK 0x00000040 +#define SD4_EMMC_TOP_INTREN2_BUFRRDYEN_SHIFT 5 +#define SD4_EMMC_TOP_INTREN2_BUFRRDYEN_MASK 0x00000020 +#define SD4_EMMC_TOP_INTREN2_BUFWRDYEN_SHIFT 4 +#define SD4_EMMC_TOP_INTREN2_BUFWRDYEN_MASK 0x00000010 +#define SD4_EMMC_TOP_INTREN2_DMAIRQEN_SHIFT 3 +#define SD4_EMMC_TOP_INTREN2_DMAIRQEN_MASK 0x00000008 +#define SD4_EMMC_TOP_INTREN2_BLKGAPEN_SHIFT 2 +#define SD4_EMMC_TOP_INTREN2_BLKGAPEN_MASK 0x00000004 +#define SD4_EMMC_TOP_INTREN2_TXDONE_SHIFT 1 +#define SD4_EMMC_TOP_INTREN2_TXDONE_MASK 0x00000002 +#define SD4_EMMC_TOP_INTREN2_CMDDONE_SHIFT 0 +#define SD4_EMMC_TOP_INTREN2_CMDDONE_MASK 0x00000001 + +#define SD4_EMMC_TOP_INTREN2_SD4_OFFSET 0x00000038 +#define SD4_EMMC_TOP_INTREN2_SD4_DEFAULT 0x00000000 +#define SD4_EMMC_TOP_INTREN2_SD4_TYPE uint32_t +#define SD4_EMMC_TOP_INTREN2_SD4_RESERVED_MASK 0xF0006000 +#define SD4_EMMC_TOP_INTREN2_SD4_TRESPERRSEN_SHIFT 27 +#define SD4_EMMC_TOP_INTREN2_SD4_TRESPERRSEN_MASK 0x08000000 +#define SD4_EMMC_TOP_INTREN2_SD4_TUNERRSIGEN_SHIFT 26 +#define SD4_EMMC_TOP_INTREN2_SD4_TUNERRSIGEN_MASK 0x04000000 +#define SD4_EMMC_TOP_INTREN2_SD4_ADMASIGEN_SHIFT 25 +#define SD4_EMMC_TOP_INTREN2_SD4_ADMASIGEN_MASK 0x02000000 +#define SD4_EMMC_TOP_INTREN2_SD4_CMDSIGEN_SHIFT 24 +#define SD4_EMMC_TOP_INTREN2_SD4_CMDSIGEN_MASK 0x01000000 +#define SD4_EMMC_TOP_INTREN2_SD4_ILIMSIGEN_SHIFT 23 +#define SD4_EMMC_TOP_INTREN2_SD4_ILIMSIGEN_MASK 0x00800000 +#define SD4_EMMC_TOP_INTREN2_SD4_DEBSIGEN_SHIFT 22 +#define SD4_EMMC_TOP_INTREN2_SD4_DEBSIGEN_MASK 0x00400000 +#define SD4_EMMC_TOP_INTREN2_SD4_DCRCSIGEN_SHIFT 21 +#define SD4_EMMC_TOP_INTREN2_SD4_DCRCSIGEN_MASK 0x00200000 +#define SD4_EMMC_TOP_INTREN2_SD4_DTOSIGEN_SHIFT 20 +#define SD4_EMMC_TOP_INTREN2_SD4_DTOSIGEN_MASK 0x00100000 +#define SD4_EMMC_TOP_INTREN2_SD4_CIDXSIGEN_SHIFT 19 +#define SD4_EMMC_TOP_INTREN2_SD4_CIDXSIGEN_MASK 0x00080000 +#define SD4_EMMC_TOP_INTREN2_SD4_CEBSIGEN_SHIFT 18 +#define SD4_EMMC_TOP_INTREN2_SD4_CEBSIGEN_MASK 0x00040000 +#define SD4_EMMC_TOP_INTREN2_SD4_CMDCRCSIGEN_SHIFT 17 +#define SD4_EMMC_TOP_INTREN2_SD4_CMDCRCSIGEN_MASK 0x00020000 +#define SD4_EMMC_TOP_INTREN2_SD4_CMDTOSIGEN_SHIFT 16 +#define SD4_EMMC_TOP_INTREN2_SD4_CMDTOSIGEN_MASK 0x00010000 +#define SD4_EMMC_TOP_INTREN2_SD4_FIXZERO_SHIFT 15 +#define SD4_EMMC_TOP_INTREN2_SD4_FIXZERO_MASK 0x00008000 +#define SD4_EMMC_TOP_INTREN2_SD4_RETUNE_EVENTSIGEN_SHIFT 12 +#define SD4_EMMC_TOP_INTREN2_SD4_RETUNE_EVENTSIGEN_MASK 0x00001000 +#define SD4_EMMC_TOP_INTREN2_SD4_INT_C_SIGEN_SHIFT 11 +#define SD4_EMMC_TOP_INTREN2_SD4_INT_C_SIGEN_MASK 0x00000800 +#define SD4_EMMC_TOP_INTREN2_SD4_INT_B_SIGEN_SHIFT 10 +#define SD4_EMMC_TOP_INTREN2_SD4_INT_B_SIGEN_MASK 0x00000400 +#define SD4_EMMC_TOP_INTREN2_SD4_INT_A_SIGEN_SHIFT 9 +#define SD4_EMMC_TOP_INTREN2_SD4_INT_A_SIGEN_MASK 0x00000200 +#define SD4_EMMC_TOP_INTREN2_SD4_CRDIRQEN_SHIFT 8 +#define SD4_EMMC_TOP_INTREN2_SD4_CRDIRQEN_MASK 0x00000100 +#define SD4_EMMC_TOP_INTREN2_SD4_CRDRVMEN_SHIFT 7 +#define SD4_EMMC_TOP_INTREN2_SD4_CRDRVMEN_MASK 0x00000080 +#define SD4_EMMC_TOP_INTREN2_SD4_CRDINSEN_SHIFT 6 +#define SD4_EMMC_TOP_INTREN2_SD4_CRDINSEN_MASK 0x00000040 +#define SD4_EMMC_TOP_INTREN2_SD4_BUFRRDYEN_SHIFT 5 +#define SD4_EMMC_TOP_INTREN2_SD4_BUFRRDYEN_MASK 0x00000020 +#define SD4_EMMC_TOP_INTREN2_SD4_BUFWRDYEN_SHIFT 4 +#define SD4_EMMC_TOP_INTREN2_SD4_BUFWRDYEN_MASK 0x00000010 +#define SD4_EMMC_TOP_INTREN2_SD4_DMAIRQEN_SHIFT 3 +#define SD4_EMMC_TOP_INTREN2_SD4_DMAIRQEN_MASK 0x00000008 +#define SD4_EMMC_TOP_INTREN2_SD4_BLKGAPEN_SHIFT 2 +#define SD4_EMMC_TOP_INTREN2_SD4_BLKGAPEN_MASK 0x00000004 +#define SD4_EMMC_TOP_INTREN2_SD4_TXDONE_SHIFT 1 +#define SD4_EMMC_TOP_INTREN2_SD4_TXDONE_MASK 0x00000002 +#define SD4_EMMC_TOP_INTREN2_SD4_CMDDONE_SHIFT 0 +#define SD4_EMMC_TOP_INTREN2_SD4_CMDDONE_MASK 0x00000001 + +#define SD4_EMMC_TOP_ERRSTAT_OFFSET 0x0000003C +#define SD4_EMMC_TOP_ERRSTAT_DEFAULT 0x00000000 +#define SD4_EMMC_TOP_ERRSTAT_TYPE uint32_t +#define SD4_EMMC_TOP_ERRSTAT_RESERVED_MASK 0x3F00FF60 +#define SD4_EMMC_TOP_ERRSTAT_PRESETEN_SHIFT 31 +#define SD4_EMMC_TOP_ERRSTAT_PRESETEN_MASK 0x80000000 +#define SD4_EMMC_TOP_ERRSTAT_ASYNC_INTREN_SHIFT 30 +#define SD4_EMMC_TOP_ERRSTAT_ASYNC_INTREN_MASK 0x40000000 +#define SD4_EMMC_TOP_ERRSTAT_SAMPLECLOCKSEL_SHIFT 23 +#define SD4_EMMC_TOP_ERRSTAT_SAMPLECLOCKSEL_MASK 0x00800000 +#define SD4_EMMC_TOP_ERRSTAT_EXECTUNE_SHIFT 22 +#define SD4_EMMC_TOP_ERRSTAT_EXECTUNE_MASK 0x00400000 +#define SD4_EMMC_TOP_ERRSTAT_DRVSTRESEL_SHIFT 20 +#define SD4_EMMC_TOP_ERRSTAT_DRVSTRESEL_MASK 0x00300000 +#define SD4_EMMC_TOP_ERRSTAT_EN1P8V_SHIFT 19 +#define SD4_EMMC_TOP_ERRSTAT_EN1P8V_MASK 0x00080000 +#define SD4_EMMC_TOP_ERRSTAT_UHSMODESEL_SHIFT 16 +#define SD4_EMMC_TOP_ERRSTAT_UHSMODESEL_MASK 0x00070000 +#define SD4_EMMC_TOP_ERRSTAT_NOCMD_SHIFT 7 +#define SD4_EMMC_TOP_ERRSTAT_NOCMD_MASK 0x00000080 +#define SD4_EMMC_TOP_ERRSTAT_CMDIDXERR_SHIFT 4 +#define SD4_EMMC_TOP_ERRSTAT_CMDIDXERR_MASK 0x00000010 +#define SD4_EMMC_TOP_ERRSTAT_CMDENDERR_SHIFT 3 +#define SD4_EMMC_TOP_ERRSTAT_CMDENDERR_MASK 0x00000008 +#define SD4_EMMC_TOP_ERRSTAT_CMDCRCERR_SHIFT 2 +#define SD4_EMMC_TOP_ERRSTAT_CMDCRCERR_MASK 0x00000004 +#define SD4_EMMC_TOP_ERRSTAT_CMDTOERR_SHIFT 1 +#define SD4_EMMC_TOP_ERRSTAT_CMDTOERR_MASK 0x00000002 +#define SD4_EMMC_TOP_ERRSTAT_CMDNOEXEC_SHIFT 0 +#define SD4_EMMC_TOP_ERRSTAT_CMDNOEXEC_MASK 0x00000001 + +#define SD4_EMMC_TOP_ERRSTAT_SD4_OFFSET 0x0000003C +#define SD4_EMMC_TOP_ERRSTAT_SD4_DEFAULT 0x00000000 +#define SD4_EMMC_TOP_ERRSTAT_SD4_TYPE uint32_t +#define SD4_EMMC_TOP_ERRSTAT_SD4_RESERVED_MASK 0x0E00FF40 +#define SD4_EMMC_TOP_ERRSTAT_SD4_PRESETEN_SHIFT 31 +#define SD4_EMMC_TOP_ERRSTAT_SD4_PRESETEN_MASK 0x80000000 +#define SD4_EMMC_TOP_ERRSTAT_SD4_ASYNC_INTREN_SHIFT 30 +#define SD4_EMMC_TOP_ERRSTAT_SD4_ASYNC_INTREN_MASK 0x40000000 +#define SD4_EMMC_TOP_ERRSTAT_SD4_ADDR64_SHIFT 29 +#define SD4_EMMC_TOP_ERRSTAT_SD4_ADDR64_MASK 0x20000000 +#define SD4_EMMC_TOP_ERRSTAT_SD4_HOSTVER4_00_SHIFT 28 +#define SD4_EMMC_TOP_ERRSTAT_SD4_HOSTVER4_00_MASK 0x10000000 +#define SD4_EMMC_TOP_ERRSTAT_SD4_UHS2INTFEN_SHIFT 24 +#define SD4_EMMC_TOP_ERRSTAT_SD4_UHS2INTFEN_MASK 0x01000000 +#define SD4_EMMC_TOP_ERRSTAT_SD4_SAMPLECLOCKSEL_SHIFT 23 +#define SD4_EMMC_TOP_ERRSTAT_SD4_SAMPLECLOCKSEL_MASK 0x00800000 +#define SD4_EMMC_TOP_ERRSTAT_SD4_EXECTUNE_SHIFT 22 +#define SD4_EMMC_TOP_ERRSTAT_SD4_EXECTUNE_MASK 0x00400000 +#define SD4_EMMC_TOP_ERRSTAT_SD4_DRVSTRESEL_SHIFT 20 +#define SD4_EMMC_TOP_ERRSTAT_SD4_DRVSTRESEL_MASK 0x00300000 +#define SD4_EMMC_TOP_ERRSTAT_SD4_EN1P8V_SHIFT 19 +#define SD4_EMMC_TOP_ERRSTAT_SD4_EN1P8V_MASK 0x00080000 +#define SD4_EMMC_TOP_ERRSTAT_SD4_UHSMODESEL_SHIFT 16 +#define SD4_EMMC_TOP_ERRSTAT_SD4_UHSMODESEL_MASK 0x00070000 +#define SD4_EMMC_TOP_ERRSTAT_SD4_NOCMD_SHIFT 7 +#define SD4_EMMC_TOP_ERRSTAT_SD4_NOCMD_MASK 0x00000080 +#define SD4_EMMC_TOP_ERRSTAT_SD4_CMDRESPERR_SHIFT 5 +#define SD4_EMMC_TOP_ERRSTAT_SD4_CMDRESPERR_MASK 0x00000020 +#define SD4_EMMC_TOP_ERRSTAT_SD4_CMDIDXERR_SHIFT 4 +#define SD4_EMMC_TOP_ERRSTAT_SD4_CMDIDXERR_MASK 0x00000010 +#define SD4_EMMC_TOP_ERRSTAT_SD4_CMDENDERR_SHIFT 3 +#define SD4_EMMC_TOP_ERRSTAT_SD4_CMDENDERR_MASK 0x00000008 +#define SD4_EMMC_TOP_ERRSTAT_SD4_CMDCRCERR_SHIFT 2 +#define SD4_EMMC_TOP_ERRSTAT_SD4_CMDCRCERR_MASK 0x00000004 +#define SD4_EMMC_TOP_ERRSTAT_SD4_CMDTOERR_SHIFT 1 +#define SD4_EMMC_TOP_ERRSTAT_SD4_CMDTOERR_MASK 0x00000002 +#define SD4_EMMC_TOP_ERRSTAT_SD4_CMDNOEXEC_SHIFT 0 +#define SD4_EMMC_TOP_ERRSTAT_SD4_CMDNOEXEC_MASK 0x00000001 + +#define SD4_EMMC_TOP_CAPABILITIES1_OFFSET 0x00000040 +#define SD4_EMMC_TOP_CAPABILITIES1_DEFAULT 0x17EFD0B0 +#define SD4_EMMC_TOP_CAPABILITIES1_TYPE uint32_t +#define SD4_EMMC_TOP_CAPABILITIES1_RESERVED_MASK 0x08100040 +#define SD4_EMMC_TOP_CAPABILITIES1_SLOTTYPE_SHIFT 30 +#define SD4_EMMC_TOP_CAPABILITIES1_SLOTTYPE_MASK 0xC0000000 +#define SD4_EMMC_TOP_CAPABILITIES1_ASYNCHIRQ_SHIFT 29 +#define SD4_EMMC_TOP_CAPABILITIES1_ASYNCHIRQ_MASK 0x20000000 +#define SD4_EMMC_TOP_CAPABILITIES1_SYSBUS64_SHIFT 28 +#define SD4_EMMC_TOP_CAPABILITIES1_SYSBUS64_MASK 0x10000000 +#define SD4_EMMC_TOP_CAPABILITIES1_V18_SHIFT 26 +#define SD4_EMMC_TOP_CAPABILITIES1_V18_MASK 0x04000000 +#define SD4_EMMC_TOP_CAPABILITIES1_V3_SHIFT 25 +#define SD4_EMMC_TOP_CAPABILITIES1_V3_MASK 0x02000000 +#define SD4_EMMC_TOP_CAPABILITIES1_V33_SHIFT 24 +#define SD4_EMMC_TOP_CAPABILITIES1_V33_MASK 0x01000000 +#define SD4_EMMC_TOP_CAPABILITIES1_SUPRSM_SHIFT 23 +#define SD4_EMMC_TOP_CAPABILITIES1_SUPRSM_MASK 0x00800000 +#define SD4_EMMC_TOP_CAPABILITIES1_SDMA_SHIFT 22 +#define SD4_EMMC_TOP_CAPABILITIES1_SDMA_MASK 0x00400000 +#define SD4_EMMC_TOP_CAPABILITIES1_HSPEED_SHIFT 21 +#define SD4_EMMC_TOP_CAPABILITIES1_HSPEED_MASK 0x00200000 +#define SD4_EMMC_TOP_CAPABILITIES1_ADMA2_SHIFT 19 +#define SD4_EMMC_TOP_CAPABILITIES1_ADMA2_MASK 0x00080000 +#define SD4_EMMC_TOP_CAPABILITIES1_EXTBUSMED_SHIFT 18 +#define SD4_EMMC_TOP_CAPABILITIES1_EXTBUSMED_MASK 0x00040000 +#define SD4_EMMC_TOP_CAPABILITIES1_MAXBLK_SHIFT 16 +#define SD4_EMMC_TOP_CAPABILITIES1_MAXBLK_MASK 0x00030000 +#define SD4_EMMC_TOP_CAPABILITIES1_BCLK_SHIFT 8 +#define SD4_EMMC_TOP_CAPABILITIES1_BCLK_MASK 0x0000FF00 +#define SD4_EMMC_TOP_CAPABILITIES1_TOUT_SHIFT 7 +#define SD4_EMMC_TOP_CAPABILITIES1_TOUT_MASK 0x00000080 +#define SD4_EMMC_TOP_CAPABILITIES1_TOUTFREQ_SHIFT 0 +#define SD4_EMMC_TOP_CAPABILITIES1_TOUTFREQ_MASK 0x0000003F + +#define SD4_EMMC_TOP_CAPABILITIES1_SD4_OFFSET 0x00000040 +#define SD4_EMMC_TOP_CAPABILITIES1_SD4_DEFAULT 0x10E934B4 +#define SD4_EMMC_TOP_CAPABILITIES1_SD4_TYPE uint32_t +#define SD4_EMMC_TOP_CAPABILITIES1_SD4_RESERVED_MASK 0x08100040 +#define SD4_EMMC_TOP_CAPABILITIES1_SD4_SLOTTYPE_SHIFT 30 +#define SD4_EMMC_TOP_CAPABILITIES1_SD4_SLOTTYPE_MASK 0xC0000000 +#define SD4_EMMC_TOP_CAPABILITIES1_SD4_ASYNCHIRQ_SHIFT 29 +#define SD4_EMMC_TOP_CAPABILITIES1_SD4_ASYNCHIRQ_MASK 0x20000000 +#define SD4_EMMC_TOP_CAPABILITIES1_SD4_SYSBUS64_SHIFT 28 +#define SD4_EMMC_TOP_CAPABILITIES1_SD4_SYSBUS64_MASK 0x10000000 +#define SD4_EMMC_TOP_CAPABILITIES1_SD4_V18_SHIFT 26 +#define SD4_EMMC_TOP_CAPABILITIES1_SD4_V18_MASK 0x04000000 +#define SD4_EMMC_TOP_CAPABILITIES1_SD4_V3_SHIFT 25 +#define SD4_EMMC_TOP_CAPABILITIES1_SD4_V3_MASK 0x02000000 +#define SD4_EMMC_TOP_CAPABILITIES1_SD4_V33_SHIFT 24 +#define SD4_EMMC_TOP_CAPABILITIES1_SD4_V33_MASK 0x01000000 +#define SD4_EMMC_TOP_CAPABILITIES1_SD4_SUPRSM_SHIFT 23 +#define SD4_EMMC_TOP_CAPABILITIES1_SD4_SUPRSM_MASK 0x00800000 +#define SD4_EMMC_TOP_CAPABILITIES1_SD4_SDMA_SHIFT 22 +#define SD4_EMMC_TOP_CAPABILITIES1_SD4_SDMA_MASK 0x00400000 +#define SD4_EMMC_TOP_CAPABILITIES1_SD4_HSPEED_SHIFT 21 +#define SD4_EMMC_TOP_CAPABILITIES1_SD4_HSPEED_MASK 0x00200000 +#define SD4_EMMC_TOP_CAPABILITIES1_SD4_ADMA2_SHIFT 19 +#define SD4_EMMC_TOP_CAPABILITIES1_SD4_ADMA2_MASK 0x00080000 +#define SD4_EMMC_TOP_CAPABILITIES1_SD4_EXTBUSMED_SHIFT 18 +#define SD4_EMMC_TOP_CAPABILITIES1_SD4_EXTBUSMED_MASK 0x00040000 +#define SD4_EMMC_TOP_CAPABILITIES1_SD4_MAXBLK_SHIFT 16 +#define SD4_EMMC_TOP_CAPABILITIES1_SD4_MAXBLK_MASK 0x00030000 +#define SD4_EMMC_TOP_CAPABILITIES1_SD4_BCLK_SHIFT 8 +#define SD4_EMMC_TOP_CAPABILITIES1_SD4_BCLK_MASK 0x0000FF00 +#define SD4_EMMC_TOP_CAPABILITIES1_SD4_TOUT_SHIFT 7 +#define SD4_EMMC_TOP_CAPABILITIES1_SD4_TOUT_MASK 0x00000080 +#define SD4_EMMC_TOP_CAPABILITIES1_SD4_TOUTFREQ_SHIFT 0 +#define SD4_EMMC_TOP_CAPABILITIES1_SD4_TOUTFREQ_MASK 0x0000003F + +#define SD4_EMMC_TOP_CAPABILITIES2_OFFSET 0x00000044 +#define SD4_EMMC_TOP_CAPABILITIES2_DEFAULT 0x03002177 +#define SD4_EMMC_TOP_CAPABILITIES2_TYPE uint32_t +#define SD4_EMMC_TOP_CAPABILITIES2_RESERVED_MASK 0xFC001088 +#define SD4_EMMC_TOP_CAPABILITIES2_SPIBLOCKMODE_SHIFT 25 +#define SD4_EMMC_TOP_CAPABILITIES2_SPIBLOCKMODE_MASK 0x02000000 +#define SD4_EMMC_TOP_CAPABILITIES2_SPIMODE_CAP_SHIFT 24 +#define SD4_EMMC_TOP_CAPABILITIES2_SPIMODE_CAP_MASK 0x01000000 +#define SD4_EMMC_TOP_CAPABILITIES2_CLOCKMULT_SHIFT 16 +#define SD4_EMMC_TOP_CAPABILITIES2_CLOCKMULT_MASK 0x00FF0000 +#define SD4_EMMC_TOP_CAPABILITIES2_RETUNE_MODE_SHIFT 14 +#define SD4_EMMC_TOP_CAPABILITIES2_RETUNE_MODE_MASK 0x0000C000 +#define SD4_EMMC_TOP_CAPABILITIES2_USETUNE_SDR50_SHIFT 13 +#define SD4_EMMC_TOP_CAPABILITIES2_USETUNE_SDR50_MASK 0x00002000 +#define SD4_EMMC_TOP_CAPABILITIES2_TMRCNT_RETUNE_SHIFT 8 +#define SD4_EMMC_TOP_CAPABILITIES2_TMRCNT_RETUNE_MASK 0x00000F00 +#define SD4_EMMC_TOP_CAPABILITIES2_DRVR_TYPED_SHIFT 6 +#define SD4_EMMC_TOP_CAPABILITIES2_DRVR_TYPED_MASK 0x00000040 +#define SD4_EMMC_TOP_CAPABILITIES2_DRVR_TYPEC_SHIFT 5 +#define SD4_EMMC_TOP_CAPABILITIES2_DRVR_TYPEC_MASK 0x00000020 +#define SD4_EMMC_TOP_CAPABILITIES2_DRVR_TYPEA_SHIFT 4 +#define SD4_EMMC_TOP_CAPABILITIES2_DRVR_TYPEA_MASK 0x00000010 +#define SD4_EMMC_TOP_CAPABILITIES2_DDR50_SHIFT 2 +#define SD4_EMMC_TOP_CAPABILITIES2_DDR50_MASK 0x00000004 +#define SD4_EMMC_TOP_CAPABILITIES2_SDR104_SHIFT 1 +#define SD4_EMMC_TOP_CAPABILITIES2_SDR104_MASK 0x00000002 +#define SD4_EMMC_TOP_CAPABILITIES2_SDR50_SHIFT 0 +#define SD4_EMMC_TOP_CAPABILITIES2_SDR50_MASK 0x00000001 + +#define SD4_EMMC_TOP_CAPABILITIES2_SD4_OFFSET 0x00000044 +#define SD4_EMMC_TOP_CAPABILITIES2_SD4_DEFAULT 0x10000064 +#define SD4_EMMC_TOP_CAPABILITIES2_SD4_TYPE uint32_t +#define SD4_EMMC_TOP_CAPABILITIES2_SD4_RESERVED_MASK 0xE7001080 +#define SD4_EMMC_TOP_CAPABILITIES2_SD4_VDD2_18_SHIFT 28 +#define SD4_EMMC_TOP_CAPABILITIES2_SD4_VDD2_18_MASK 0x10000000 +#define SD4_EMMC_TOP_CAPABILITIES2_SD4_ADMA3_SHIFT 27 +#define SD4_EMMC_TOP_CAPABILITIES2_SD4_ADMA3_MASK 0x08000000 +#define SD4_EMMC_TOP_CAPABILITIES2_SD4_CLOCKMULT_SHIFT 16 +#define SD4_EMMC_TOP_CAPABILITIES2_SD4_CLOCKMULT_MASK 0x00FF0000 +#define SD4_EMMC_TOP_CAPABILITIES2_SD4_RETUNE_MODE_SHIFT 14 +#define SD4_EMMC_TOP_CAPABILITIES2_SD4_RETUNE_MODE_MASK 0x0000C000 +#define SD4_EMMC_TOP_CAPABILITIES2_SD4_USETUNE_SDR50_SHIFT 13 +#define SD4_EMMC_TOP_CAPABILITIES2_SD4_USETUNE_SDR50_MASK 0x00002000 +#define SD4_EMMC_TOP_CAPABILITIES2_SD4_TMRCNT_RETUNE_SHIFT 8 +#define SD4_EMMC_TOP_CAPABILITIES2_SD4_TMRCNT_RETUNE_MASK 0x00000F00 +#define SD4_EMMC_TOP_CAPABILITIES2_SD4_DRVR_TYPED_SHIFT 6 +#define SD4_EMMC_TOP_CAPABILITIES2_SD4_DRVR_TYPED_MASK 0x00000040 +#define SD4_EMMC_TOP_CAPABILITIES2_SD4_DRVR_TYPEC_SHIFT 5 +#define SD4_EMMC_TOP_CAPABILITIES2_SD4_DRVR_TYPEC_MASK 0x00000020 +#define SD4_EMMC_TOP_CAPABILITIES2_SD4_DRVR_TYPEA_SHIFT 4 +#define SD4_EMMC_TOP_CAPABILITIES2_SD4_DRVR_TYPEA_MASK 0x00000010 +#define SD4_EMMC_TOP_CAPABILITIES2_SD4_UHS_II_SHIFT 3 +#define SD4_EMMC_TOP_CAPABILITIES2_SD4_UHS_II_MASK 0x00000008 +#define SD4_EMMC_TOP_CAPABILITIES2_SD4_DDR50_SHIFT 2 +#define SD4_EMMC_TOP_CAPABILITIES2_SD4_DDR50_MASK 0x00000004 +#define SD4_EMMC_TOP_CAPABILITIES2_SD4_SDR104_SHIFT 1 +#define SD4_EMMC_TOP_CAPABILITIES2_SD4_SDR104_MASK 0x00000002 +#define SD4_EMMC_TOP_CAPABILITIES2_SD4_SDR50_SHIFT 0 +#define SD4_EMMC_TOP_CAPABILITIES2_SD4_SDR50_MASK 0x00000001 + +#define SD4_EMMC_TOP_MAX_A1_OFFSET 0x00000048 +#define SD4_EMMC_TOP_MAX_A1_DEFAULT 0x00000001 +#define SD4_EMMC_TOP_MAX_A1_TYPE uint32_t +#define SD4_EMMC_TOP_MAX_A1_RESERVED_MASK 0xFF000000 +#define SD4_EMMC_TOP_MAX_A1_MAXA18_SHIFT 16 +#define SD4_EMMC_TOP_MAX_A1_MAXA18_MASK 0x00FF0000 +#define SD4_EMMC_TOP_MAX_A1_MAXA30_SHIFT 8 +#define SD4_EMMC_TOP_MAX_A1_MAXA30_MASK 0x0000FF00 +#define SD4_EMMC_TOP_MAX_A1_MAXA33_SHIFT 0 +#define SD4_EMMC_TOP_MAX_A1_MAXA33_MASK 0x000000FF + +#define SD4_EMMC_TOP_MAX_A2_OFFSET 0x0000004C +#define SD4_EMMC_TOP_MAX_A2_DEFAULT 0x00000000 +#define SD4_EMMC_TOP_MAX_A2_TYPE uint32_t +#define SD4_EMMC_TOP_MAX_A2_RESERVED_MASK 0xFFFFFFFF + +#define SD4_EMMC_TOP_MAX_A2_SD4_OFFSET 0x0000004C +#define SD4_EMMC_TOP_MAX_A2_SD4_DEFAULT 0x00000001 +#define SD4_EMMC_TOP_MAX_A2_SD4_TYPE uint32_t +#define SD4_EMMC_TOP_MAX_A2_SD4_RESERVED_MASK 0xFFFFFF00 +#define SD4_EMMC_TOP_MAX_A2_SD4_MAXAVDD2_SHIFT 0 +#define SD4_EMMC_TOP_MAX_A2_SD4_MAXAVDD2_MASK 0x000000FF + +#define SD4_EMMC_TOP_CMDENTSTAT_OFFSET 0x00000050 +#define SD4_EMMC_TOP_CMDENTSTAT_DEFAULT 0x00000000 +#define SD4_EMMC_TOP_CMDENTSTAT_TYPE uint32_t +#define SD4_EMMC_TOP_CMDENTSTAT_RESERVED_MASK 0x2C00FF60 +#define SD4_EMMC_TOP_CMDENTSTAT_VSES_SHIFT 30 +#define SD4_EMMC_TOP_CMDENTSTAT_VSES_MASK 0xC0000000 +#define SD4_EMMC_TOP_CMDENTSTAT_TRERR_SHIFT 28 +#define SD4_EMMC_TOP_CMDENTSTAT_TRERR_MASK 0x10000000 +#define SD4_EMMC_TOP_CMDENTSTAT_ADMAERR_SHIFT 25 +#define SD4_EMMC_TOP_CMDENTSTAT_ADMAERR_MASK 0x02000000 +#define SD4_EMMC_TOP_CMDENTSTAT_ACMDERR_SHIFT 24 +#define SD4_EMMC_TOP_CMDENTSTAT_ACMDERR_MASK 0x01000000 +#define SD4_EMMC_TOP_CMDENTSTAT_ILERR_SHIFT 23 +#define SD4_EMMC_TOP_CMDENTSTAT_ILERR_MASK 0x00800000 +#define SD4_EMMC_TOP_CMDENTSTAT_DENDERR_SHIFT 22 +#define SD4_EMMC_TOP_CMDENTSTAT_DENDERR_MASK 0x00400000 +#define SD4_EMMC_TOP_CMDENTSTAT_DCRCERR_SHIFT 21 +#define SD4_EMMC_TOP_CMDENTSTAT_DCRCERR_MASK 0x00200000 +#define SD4_EMMC_TOP_CMDENTSTAT_DTOUTERR_SHIFT 20 +#define SD4_EMMC_TOP_CMDENTSTAT_DTOUTERR_MASK 0x00100000 +#define SD4_EMMC_TOP_CMDENTSTAT_CIDXERR_SHIFT 19 +#define SD4_EMMC_TOP_CMDENTSTAT_CIDXERR_MASK 0x00080000 +#define SD4_EMMC_TOP_CMDENTSTAT_CENDERR_SHIFT 18 +#define SD4_EMMC_TOP_CMDENTSTAT_CENDERR_MASK 0x00040000 +#define SD4_EMMC_TOP_CMDENTSTAT_CCRCERR_SHIFT 17 +#define SD4_EMMC_TOP_CMDENTSTAT_CCRCERR_MASK 0x00020000 +#define SD4_EMMC_TOP_CMDENTSTAT_CTOUTERR_SHIFT 16 +#define SD4_EMMC_TOP_CMDENTSTAT_CTOUTERR_MASK 0x00010000 +#define SD4_EMMC_TOP_CMDENTSTAT_NOFRCENT_SHIFT 7 +#define SD4_EMMC_TOP_CMDENTSTAT_NOFRCENT_MASK 0x00000080 +#define SD4_EMMC_TOP_CMDENTSTAT_IDXERR_SHIFT 4 +#define SD4_EMMC_TOP_CMDENTSTAT_IDXERR_MASK 0x00000010 +#define SD4_EMMC_TOP_CMDENTSTAT_EBITERR_SHIFT 3 +#define SD4_EMMC_TOP_CMDENTSTAT_EBITERR_MASK 0x00000008 +#define SD4_EMMC_TOP_CMDENTSTAT_CRCERR_SHIFT 2 +#define SD4_EMMC_TOP_CMDENTSTAT_CRCERR_MASK 0x00000004 +#define SD4_EMMC_TOP_CMDENTSTAT_TOUTERR_SHIFT 1 +#define SD4_EMMC_TOP_CMDENTSTAT_TOUTERR_MASK 0x00000002 +#define SD4_EMMC_TOP_CMDENTSTAT_AUTONOEX_SHIFT 0 +#define SD4_EMMC_TOP_CMDENTSTAT_AUTONOEX_MASK 0x00000001 + +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_OFFSET 0x00000050 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_DEFAULT 0x00000000 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_TYPE uint32_t +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_RESERVED_MASK 0x0000FF40 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_VSES_SHIFT 28 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_VSES_MASK 0xF0000000 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_TRESPERR_SHIFT 27 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_TRESPERR_MASK 0x08000000 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_TUNERR_SHIFT 26 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_TUNERR_MASK 0x04000000 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_ADMAERR_SHIFT 25 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_ADMAERR_MASK 0x02000000 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_ACMDERR_SHIFT 24 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_ACMDERR_MASK 0x01000000 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_ILERR_SHIFT 23 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_ILERR_MASK 0x00800000 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_DENDERR_SHIFT 22 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_DENDERR_MASK 0x00400000 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_DCRCERR_SHIFT 21 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_DCRCERR_MASK 0x00200000 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_DTOUTERR_SHIFT 20 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_DTOUTERR_MASK 0x00100000 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_CIDXERR_SHIFT 19 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_CIDXERR_MASK 0x00080000 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_CENDERR_SHIFT 18 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_CENDERR_MASK 0x00040000 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_CCRCERR_SHIFT 17 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_CCRCERR_MASK 0x00020000 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_CTOUTERR_SHIFT 16 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_CTOUTERR_MASK 0x00010000 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_NOFRCENT_SHIFT 7 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_NOFRCENT_MASK 0x00000080 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_RESPERR_SHIFT 5 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_RESPERR_MASK 0x00000020 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_IDXERR_SHIFT 4 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_IDXERR_MASK 0x00000010 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_EBITERR_SHIFT 3 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_EBITERR_MASK 0x00000008 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_CRCERR_SHIFT 2 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_CRCERR_MASK 0x00000004 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_TOUTERR_SHIFT 1 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_TOUTERR_MASK 0x00000002 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_AUTONOEX_SHIFT 0 +#define SD4_EMMC_TOP_CMDENTSTAT_SD4_AUTONOEX_MASK 0x00000001 + +#define SD4_EMMC_TOP_ADMAERR_OFFSET 0x00000054 +#define SD4_EMMC_TOP_ADMAERR_DEFAULT 0x00000000 +#define SD4_EMMC_TOP_ADMAERR_TYPE uint32_t +#define SD4_EMMC_TOP_ADMAERR_RESERVED_MASK 0xFFFFFFF8 +#define SD4_EMMC_TOP_ADMAERR_ADMALERR_SHIFT 2 +#define SD4_EMMC_TOP_ADMAERR_ADMALERR_MASK 0x00000004 +#define SD4_EMMC_TOP_ADMAERR_ADMAERR_SHIFT 0 +#define SD4_EMMC_TOP_ADMAERR_ADMAERR_MASK 0x00000003 + +#define SD4_EMMC_TOP_ADMAADDR0_OFFSET 0x00000058 +#define SD4_EMMC_TOP_ADMAADDR0_DEFAULT 0x00000000 +#define SD4_EMMC_TOP_ADMAADDR0_TYPE uint32_t +#define SD4_EMMC_TOP_ADMAADDR0_RESERVED_MASK 0x00000000 +#define SD4_EMMC_TOP_ADMAADDR0_ADMAADDR0_SHIFT 0 +#define SD4_EMMC_TOP_ADMAADDR0_ADMAADDR0_MASK 0xFFFFFFFF + +#define SD4_EMMC_TOP_ADMAADDR1_OFFSET 0x0000005C +#define SD4_EMMC_TOP_ADMAADDR1_DEFAULT 0x00000000 +#define SD4_EMMC_TOP_ADMAADDR1_TYPE uint32_t +#define SD4_EMMC_TOP_ADMAADDR1_RESERVED_MASK 0x00000000 +#define SD4_EMMC_TOP_ADMAADDR1_ADMAADDR1_SHIFT 0 +#define SD4_EMMC_TOP_ADMAADDR1_ADMAADDR1_MASK 0xFFFFFFFF + +#define SD4_EMMC_TOP_PRESETVAL1_OFFSET 0x00000060 +#define SD4_EMMC_TOP_PRESETVAL1_DEFAULT 0x00000000 +#define SD4_EMMC_TOP_PRESETVAL1_TYPE uint32_t +#define SD4_EMMC_TOP_PRESETVAL1_RESERVED_MASK 0x38003800 +#define SD4_EMMC_TOP_PRESETVAL1_DRVS_SEL_DFS_SHIFT 30 +#define SD4_EMMC_TOP_PRESETVAL1_DRVS_SEL_DFS_MASK 0xC0000000 +#define SD4_EMMC_TOP_PRESETVAL1_CLKGENSEL_DFS_SHIFT 26 +#define SD4_EMMC_TOP_PRESETVAL1_CLKGENSEL_DFS_MASK 0x04000000 +#define SD4_EMMC_TOP_PRESETVAL1_FREQ_SEL_DFS_SHIFT 16 +#define SD4_EMMC_TOP_PRESETVAL1_FREQ_SEL_DFS_MASK 0x03FF0000 +#define SD4_EMMC_TOP_PRESETVAL1_DRVS_SEL_INIT_SHIFT 14 +#define SD4_EMMC_TOP_PRESETVAL1_DRVS_SEL_INIT_MASK 0x0000C000 +#define SD4_EMMC_TOP_PRESETVAL1_CLKGENSEL_INIT_SHIFT 10 +#define SD4_EMMC_TOP_PRESETVAL1_CLKGENSEL_INIT_MASK 0x00000400 +#define SD4_EMMC_TOP_PRESETVAL1_FREQ_SEL_INIT_SHIFT 0 +#define SD4_EMMC_TOP_PRESETVAL1_FREQ_SEL_INIT_MASK 0x000003FF + +#define SD4_EMMC_TOP_PRESETVAL2_OFFSET 0x00000064 +#define SD4_EMMC_TOP_PRESETVAL2_DEFAULT 0x00000000 +#define SD4_EMMC_TOP_PRESETVAL2_TYPE uint32_t +#define SD4_EMMC_TOP_PRESETVAL2_RESERVED_MASK 0x38003800 +#define SD4_EMMC_TOP_PRESETVAL2_DRVS_SEL_SDR12_SHIFT 30 +#define SD4_EMMC_TOP_PRESETVAL2_DRVS_SEL_SDR12_MASK 0xC0000000 +#define SD4_EMMC_TOP_PRESETVAL2_CLKGENSEL_SDR12_SHIFT 26 +#define SD4_EMMC_TOP_PRESETVAL2_CLKGENSEL_SDR12_MASK 0x04000000 +#define SD4_EMMC_TOP_PRESETVAL2_FREQ_SEL_SDR12_SHIFT 16 +#define SD4_EMMC_TOP_PRESETVAL2_FREQ_SEL_SDR12_MASK 0x03FF0000 +#define SD4_EMMC_TOP_PRESETVAL2_DRVS_SEL_HS_SHIFT 14 +#define SD4_EMMC_TOP_PRESETVAL2_DRVS_SEL_HS_MASK 0x0000C000 +#define SD4_EMMC_TOP_PRESETVAL2_CLKGENSEL_HS_SHIFT 10 +#define SD4_EMMC_TOP_PRESETVAL2_CLKGENSEL_HS_MASK 0x00000400 +#define SD4_EMMC_TOP_PRESETVAL2_FREQ_SEL_HS_SHIFT 0 +#define SD4_EMMC_TOP_PRESETVAL2_FREQ_SEL_HS_MASK 0x000003FF + +#define SD4_EMMC_TOP_PRESETVAL3_OFFSET 0x00000068 +#define SD4_EMMC_TOP_PRESETVAL3_DEFAULT 0x00000000 +#define SD4_EMMC_TOP_PRESETVAL3_TYPE uint32_t +#define SD4_EMMC_TOP_PRESETVAL3_RESERVED_MASK 0x38003800 +#define SD4_EMMC_TOP_PRESETVAL3_DRVS_SEL_SDR50_SHIFT 30 +#define SD4_EMMC_TOP_PRESETVAL3_DRVS_SEL_SDR50_MASK 0xC0000000 +#define SD4_EMMC_TOP_PRESETVAL3_CLKGENSEL_SDR50_SHIFT 26 +#define SD4_EMMC_TOP_PRESETVAL3_CLKGENSEL_SDR50_MASK 0x04000000 +#define SD4_EMMC_TOP_PRESETVAL3_FREQ_SEL_SDR50_SHIFT 16 +#define SD4_EMMC_TOP_PRESETVAL3_FREQ_SEL_SDR50_MASK 0x03FF0000 +#define SD4_EMMC_TOP_PRESETVAL3_DRVS_SEL_SDR25_SHIFT 14 +#define SD4_EMMC_TOP_PRESETVAL3_DRVS_SEL_SDR25_MASK 0x0000C000 +#define SD4_EMMC_TOP_PRESETVAL3_CLKGENSEL_SDR25_SHIFT 10 +#define SD4_EMMC_TOP_PRESETVAL3_CLKGENSEL_SDR25_MASK 0x00000400 +#define SD4_EMMC_TOP_PRESETVAL3_FREQ_SEL_SDR25_SHIFT 0 +#define SD4_EMMC_TOP_PRESETVAL3_FREQ_SEL_SDR25_MASK 0x000003FF + +#define SD4_EMMC_TOP_PRESETVAL4_OFFSET 0x0000006C +#define SD4_EMMC_TOP_PRESETVAL4_DEFAULT 0x00000000 +#define SD4_EMMC_TOP_PRESETVAL4_TYPE uint32_t +#define SD4_EMMC_TOP_PRESETVAL4_RESERVED_MASK 0x38003800 +#define SD4_EMMC_TOP_PRESETVAL4_DRVS_SEL_DDR50_SHIFT 30 +#define SD4_EMMC_TOP_PRESETVAL4_DRVS_SEL_DDR50_MASK 0xC0000000 +#define SD4_EMMC_TOP_PRESETVAL4_CLKGENSEL_DDR50_SHIFT 26 +#define SD4_EMMC_TOP_PRESETVAL4_CLKGENSEL_DDR50_MASK 0x04000000 +#define SD4_EMMC_TOP_PRESETVAL4_FREQ_SEL_DDR50_SHIFT 16 +#define SD4_EMMC_TOP_PRESETVAL4_FREQ_SEL_DDR50_MASK 0x03FF0000 +#define SD4_EMMC_TOP_PRESETVAL4_DRVS_SEL_SDR104_SHIFT 14 +#define SD4_EMMC_TOP_PRESETVAL4_DRVS_SEL_SDR104_MASK 0x0000C000 +#define SD4_EMMC_TOP_PRESETVAL4_CLKGENSEL_SDR104_SHIFT 10 +#define SD4_EMMC_TOP_PRESETVAL4_CLKGENSEL_SDR104_MASK 0x00000400 +#define SD4_EMMC_TOP_PRESETVAL4_FREQ_SEL_SDR104_SHIFT 0 +#define SD4_EMMC_TOP_PRESETVAL4_FREQ_SEL_SDR104_MASK 0x000003FF + +#define SD4_EMMC_TOP_BOOTTIMEOUT_OFFSET 0x00000070 +#define SD4_EMMC_TOP_BOOTTIMEOUT_DEFAULT 0x00000000 +#define SD4_EMMC_TOP_BOOTTIMEOUT_TYPE uint32_t +#define SD4_EMMC_TOP_BOOTTIMEOUT_RESERVED_MASK 0x00000000 +#define SD4_EMMC_TOP_BOOTTIMEOUT_BOOTDATATIMEOUTCTRVALUE_SHIFT 0 +#define SD4_EMMC_TOP_BOOTTIMEOUT_BOOTDATATIMEOUTCTRVALUE_MASK 0xFFFFFFFF + +#define SD4_EMMC_TOP_DBGSEL_OFFSET 0x00000074 +#define SD4_EMMC_TOP_DBGSEL_DEFAULT 0x00000000 +#define SD4_EMMC_TOP_DBGSEL_TYPE uint32_t +#define SD4_EMMC_TOP_DBGSEL_RESERVED_MASK 0xFFFFFFFE +#define SD4_EMMC_TOP_DBGSEL_DBGSEL_SHIFT 0 +#define SD4_EMMC_TOP_DBGSEL_DBGSEL_MASK 0x00000001 + +#define SD4_EMMC_TOP_UHS2_PRESETVAL_OFFSET 0x00000074 +#define SD4_EMMC_TOP_UHS2_PRESETVAL_DEFAULT 0x00000000 +#define SD4_EMMC_TOP_UHS2_PRESETVAL_TYPE uint32_t +#define SD4_EMMC_TOP_UHS2_PRESETVAL_RESERVED_MASK 0xFFFF3800 +#define SD4_EMMC_TOP_UHS2_PRESETVAL_DRVSTRVAL_SHIFT 14 +#define SD4_EMMC_TOP_UHS2_PRESETVAL_DRVSTRVAL_MASK 0x0000C000 +#define SD4_EMMC_TOP_UHS2_PRESETVAL_CLKGENSELVAL_SHIFT 10 +#define SD4_EMMC_TOP_UHS2_PRESETVAL_CLKGENSELVAL_MASK 0x00000400 +#define SD4_EMMC_TOP_UHS2_PRESETVAL_SDCLKFREQSELVAL_SHIFT 0 +#define SD4_EMMC_TOP_UHS2_PRESETVAL_SDCLKFREQSELVAL_MASK 0x000003FF + +#define SD4_EMMC_TOP_HCVERSIRQ_OFFSET 0x000000FC +#define SD4_EMMC_TOP_HCVERSIRQ_DEFAULT 0x10020000 +#define SD4_EMMC_TOP_HCVERSIRQ_TYPE uint32_t +#define SD4_EMMC_TOP_HCVERSIRQ_RESERVED_MASK 0x0000FF00 +#define SD4_EMMC_TOP_HCVERSIRQ_VENDVER_SHIFT 24 +#define SD4_EMMC_TOP_HCVERSIRQ_VENDVER_MASK 0xFF000000 +#define SD4_EMMC_TOP_HCVERSIRQ_SPECVER_SHIFT 16 +#define SD4_EMMC_TOP_HCVERSIRQ_SPECVER_MASK 0x00FF0000 +#define SD4_EMMC_TOP_HCVERSIRQ_SIRQ_SHIFT 0 +#define SD4_EMMC_TOP_HCVERSIRQ_SIRQ_MASK 0x000000FF + +#define SD4_EMMC_TOP_HCVERSIRQ_SD4_OFFSET 0x000000FC +#define SD4_EMMC_TOP_HCVERSIRQ_SD4_DEFAULT 0x01030000 +#define SD4_EMMC_TOP_HCVERSIRQ_SD4_TYPE uint32_t +#define SD4_EMMC_TOP_HCVERSIRQ_SD4_RESERVED_MASK 0x0000FF00 +#define SD4_EMMC_TOP_HCVERSIRQ_SD4_VENDVER_SHIFT 24 +#define SD4_EMMC_TOP_HCVERSIRQ_SD4_VENDVER_MASK 0xFF000000 +#define SD4_EMMC_TOP_HCVERSIRQ_SD4_SPECVER_SHIFT 16 +#define SD4_EMMC_TOP_HCVERSIRQ_SD4_SPECVER_MASK 0x00FF0000 +#define SD4_EMMC_TOP_HCVERSIRQ_SD4_SIRQ_SHIFT 0 +#define SD4_EMMC_TOP_HCVERSIRQ_SD4_SIRQ_MASK 0x000000FF + +#endif /* BRCM_RDB_SD4_EMMC_TOP_H */ diff --git a/include/drivers/brcm/emmc/emmc_chal_sd.h b/include/drivers/brcm/emmc/emmc_chal_sd.h new file mode 100644 index 000000000..8d223f9dd --- /dev/null +++ b/include/drivers/brcm/emmc/emmc_chal_sd.h @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2016 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CHAL_SD_H +#define CHAL_SD_H + +#include + +#define BASE_CLK_FREQ (200 * 1000 * 1000) +#define INIT_CLK_FREQ (400 * 1000) + +#define SD_ERROR_RECOVERABLE 0 +#define SD_ERROR_NON_RECOVERABLE 1 + +#define SD_OK 0 +#define SD_FAIL (-1) +#define SD_INVALID_HANDLE (-2) +#define SD_CEATA_INIT_ERROR (-3) +#define SD_RESET_ERROR (-4) +#define SD_CARD_INIT_ERROR (-5) +#define SD_INV_DATA_WIDTH (-6) +#define SD_SET_BUS_WIDTH_ERROR (-7) +#define SD_DMA_NOT_SUPPORT (-8) +#define SD_SDIO_READ_ERROR (-9) +#define SD_SDIO_WRITE_ERROR (-10) +#define SD_WRITE_ERROR (-11) +#define SD_READ_ERROR (-12) +#define SD_READ_SIZE_ERROR (-13) +#define SD_RW_ADDRESS_ERROR (-14) +#define SD_XFER_ADDRESS_ERROR (-15) +#define SD_DATA_XFER_ADDR_ERROR (-16) +#define SD_DATA_XFER_ERROR (-17) +#define SD_WRITE_SIZE_ERROR (-18) +#define SD_CMD_STATUS_UPDATE_ERR (-19) +#define SD_CMD12_ERROR (-20) +#define SD_CMD_DATA_ERROR (-21) +#define SD_CMD_TIMEOUT (-22) +#define SD_CMD_NO_RESPONSE (-22) +#define SD_CMD_ABORT_ERROR (-23) +#define SD_CMD_INVALID (-24) +#define SD_CMD_RESUME_ERROR (-25) +#define SD_CMD_ERR_INVALID_RESPONSE (-26) +#define SD_WAIT_TIMEOUT (-27) +#define SD_READ_TIMEOUT (-28) +#define SD_CEATA_REST_ERROR (-29) +#define SD_INIT_CAED_FAILED (-30) +#define SD_ERROR_CLOCK_OFFLIMIT (-31) +#define SD_INV_SLOT (-32) + +#define SD_NOR_INTERRUPTS 0x000000FF +#define SD_ERR_INTERRUPTS 0x03FF0000 +#define SD_CMD_ERROR_INT 0x010F0000 +#define SD_DAT_ERROR_INT 0x02F00000 +#define SD_DAT_TIMEOUT 0x00100000 + +/* Operation modes */ +#define SD_PIO_MODE 0 +#define SD_INT_MODE 1 + +/* Support both ADMA and SDMA (for version 2.0 and above) */ +#define SD_DMA_OFF 0 +#define SD_DMA_SDMA 1 +#define SD_DMA_ADMA 2 + +#define SD_NORMAL_SPEED 0 +#define SD_HIGH_SPEED 1 + +#define SD_XFER_CARD_TO_HOST 3 +#define SD_XFER_HOST_TO_CARD 4 + +#define SD_CARD_DETECT_AUTO 0 +#define SD_CARD_DETECT_SD 1 +#define SD_CARD_DETECT_SDIO 2 +#define SD_CARD_DETECT_MMC 3 +#define SD_CARD_DETECT_CEATA 4 + +#define SD_ABORT_SYNC_MODE 0 +#define SD_ABORT_ASYNC_MODE 1 + +#define SD_CMD_ERROR_FLAGS (0x18F << 16) +#define SD_DATA_ERROR_FLAGS (0x70 << 16) +#define SD_AUTO_CMD12_ERROR_FLAGS (0x9F) + +#define SD_CARD_STATUS_ERROR 0x10000000 +#define SD_CMD_MISSING 0x80000000 +#define SD_ERROR_INT 0x8000 + +#define SD_TRAN_HIGH_SPEED 0x32 +#define SD_CARD_HIGH_CAPACITY 0x40000000 +#define SD_CARD_POWER_UP_STATUS 0x80000000 + +#define SD_HOST_CORE_TIMEOUT 0x0E + +/* SD CARD and Host Controllers bus width */ +#define SD_BUS_DATA_WIDTH_1BIT 0x00 +#define SD_BUS_DATA_WIDTH_4BIT 0x02 +#define SD_BUS_DATA_WIDTH_8BIT 0x20 + +/* dma boundary settings */ +#define SD_DMA_BOUNDARY_4K 0 +#define SD_DMA_BOUNDARY_8K (1 << 12) +#define SD_DMA_BOUNDARY_16K (2 << 12) +#define SD_DMA_BOUNDARY_32K (3 << 12) +#define SD_DMA_BOUNDARY_64K (4 << 12) +#define SD_DMA_BOUNDARY_128K (5 << 12) +#define SD_DMA_BOUNDARY_256K (6 << 12) +#define SD_DMA_BOUNDARY_512K (7 << 12) + +#define SD_CMDR_CMD_NORMAL 0x00000000 +#define SD_CMDR_CMD_SUSPEND 0x00400000 +#define SD_CMDR_CMD_RESUME 0x00800000 +#define SD_CMDR_CMD_ABORT 0x00c00000 + +#define SD_CMDR_RSP_TYPE_NONE 0x0 +#define SD_CMDR_RSP_TYPE_R2 0x1 +#define SD_CMDR_RSP_TYPE_R3_4 0x2 +#define SD_CMDR_RSP_TYPE_R1_5_6 0x2 +#define SD_CMDR_RSP_TYPE_R1b_5b 0x3 +#define SD_CMDR_RSP_TYPE_S 16 + +struct sd_ctrl_info { + uint32_t blkReg; /* current block register cache value */ + uint32_t cmdReg; /* current command register cache value */ + uint32_t argReg; /* current argument register cache value */ + uint32_t cmdIndex; /* current command index */ + uint32_t cmdStatus; /* current command status, cmd/data compelete */ + uint16_t rca; /* relative card address */ + uint32_t ocr; /* operation codition */ + uint32_t eventList; /* events list */ + uint32_t blkGapEnable; + + uint32_t capability; /* controller's capbilities */ + uint32_t maxCurrent; /* maximum current supported */ + uint32_t present; /* if card is inserted or removed */ + uint32_t version; /* SD spec version 1.0 or 2.0 */ + uint32_t vendor; /* vendor number */ + + uintptr_t sdRegBaseAddr; /* sdio control registers */ + uintptr_t hostRegBaseAddr; /* SD Host control registers */ +}; + +struct sd_cfg { + uint32_t mode; /* interrupt or polling */ + uint32_t dma; /* dma enabled or disabled */ + uint32_t retryLimit; /* command retry limit */ + uint32_t speedMode; /* speed mode, 0 standard, 1 high speed */ + uint32_t voltage; /* voltage level */ + uint32_t blockSize; /* access block size (512 for HC card) */ + uint32_t dmaBoundary; /* dma address boundary */ + uint32_t detSignal; /* card det signal src, for test purpose only */ + uint32_t rdWaiting; + uint32_t wakeupOut; + uint32_t wakeupIn; + uint32_t wakeupInt; + uint32_t wfe_retry; + uint32_t gapInt; + uint32_t readWait; + uint32_t led; +}; + +struct sd_dev { + struct sd_cfg cfg; /* SD configuration */ + struct sd_ctrl_info ctrl; /* SD info */ +}; + +int32_t chal_sd_start(CHAL_HANDLE *sdHandle, uint32_t mode, + uint32_t sdBase, uint32_t hostBase); +int32_t chal_sd_config(CHAL_HANDLE *sdHandle, uint32_t speed, + uint32_t retry, uint32_t boundary, + uint32_t blkSize, uint32_t dma); +int32_t chal_sd_stop(void); +int32_t chal_sd_set_dma(CHAL_HANDLE *sdHandle, uint32_t mode); +uintptr_t chal_sd_get_dma_addr(CHAL_HANDLE *handle); +int32_t chal_sd_config_bus_width(CHAL_HANDLE *sdHandle, int32_t width); +int32_t chal_sd_send_cmd(CHAL_HANDLE *sdHandle, uint32_t cmdIndex, + uint32_t arg, uint32_t options); +int32_t chal_sd_set_dma_addr(CHAL_HANDLE *sdHandle, uintptr_t address); +int32_t chal_sd_set_clock(CHAL_HANDLE *sdHandle, + uint32_t div_ctrl_setting, uint32_t on); +uint32_t chal_sd_freq_2_div_ctrl_setting(uint32_t desired_freq); +int32_t chal_sd_setup_xfer(CHAL_HANDLE *sdHandle, uint8_t *data, + uint32_t length, int32_t dir); +int32_t chal_sd_write_buffer(CHAL_HANDLE *sdHandle, uint32_t length, + uint8_t *data); +int32_t chal_sd_read_buffer(CHAL_HANDLE *sdHandle, uint32_t length, + uint8_t *data); +int32_t chal_sd_reset_line(CHAL_HANDLE *sdHandle, uint32_t line); +int32_t chal_sd_get_response(CHAL_HANDLE *sdHandle, uint32_t *resp); +int32_t chal_sd_clear_pending_irq(CHAL_HANDLE *sdHandle); +int32_t chal_sd_get_irq_status(CHAL_HANDLE *sdHandle); +int32_t chal_sd_clear_irq(CHAL_HANDLE *sdHandle, uint32_t mask); +uint32_t chal_sd_get_present_status(CHAL_HANDLE *sdHandle); +int32_t chal_sd_get_atuo12_error(CHAL_HANDLE *sdHandle); +void chal_sd_set_speed(CHAL_HANDLE *sdHandle, uint32_t speed); +int32_t chal_sd_check_cap(CHAL_HANDLE *sdHandle, uint32_t cap); +void chal_sd_set_irq_signal(CHAL_HANDLE *sdHandle, uint32_t mask, + uint32_t state); +void chal_sd_dump_fifo(CHAL_HANDLE *sdHandle); +#endif /* CHAL_SD_H */ diff --git a/include/drivers/brcm/emmc/emmc_chal_types.h b/include/drivers/brcm/emmc/emmc_chal_types.h new file mode 100644 index 000000000..9563273ad --- /dev/null +++ b/include/drivers/brcm/emmc/emmc_chal_types.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2016 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + + +#ifndef CHAL_TYPES_H +#define CHAL_TYPES_H + +#include + +// +// Generic cHAL handler +// +#ifndef CHAL_HANDLE + typedef void *CHAL_HANDLE; ///< void pointer (32 bits wide) +#endif + +#endif /* _CHAL_TYPES_H_ */ diff --git a/include/drivers/brcm/emmc/emmc_csl_sd.h b/include/drivers/brcm/emmc/emmc_csl_sd.h new file mode 100644 index 000000000..52b8bc84b --- /dev/null +++ b/include/drivers/brcm/emmc/emmc_csl_sd.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2016 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CSL_SD_H +#define CSL_SD_H + +#define SD_CLOCK_BASE 104000000 +#define SD_CLOCK_52MHZ 52000000 +#define SD_CLOCK_26MHZ 26000000 +#define SD_CLOCK_17MHZ 17330000 +#define SD_CLOCK_13MHZ 13000000 +#define SD_CLOCK_10MHZ 10000000 +#define SD_CLOCK_9MHZ 9000000 +#define SD_CLOCK_7MHZ 7000000 +#define SD_CLOCK_5MHZ 5000000 +#define SD_CLOCK_1MHZ 1000000 +#define SD_CLOCK_400KHZ 400000 + +#define SD_DRIVE_STRENGTH_MASK 0x38000000 +#if defined(_BCM213x1_) || defined(_BCM21551_) || defined(_ATHENA_) +#define SD_DRIVE_STRENGTH 0x28000000 +#elif defined(_BCM2153_) +#define SD_DRIVE_STRENGTH 0x38000000 +#else +#define SD_DRIVE_STRENGTH 0x00000000 +#endif + +#define SD_NUM_HOST 2 + +#define SD_CARD_UNLOCK 0 +#define SD_CARD_LOCK 0x4 +#define SD_CARD_CLEAR_PWD 0x2 +#define SD_CARD_SET_PWD 0x1 +#define SD_CARD_ERASE_PWD 0x8 + +#define SD_CARD_LOCK_STATUS 0x02000000 +#define SD_CARD_UNLOCK_STATUS 0x01000000 + +#define SD_CMD_ERROR_FLAGS (0x18F << 16) +#define SD_DATA_ERROR_FLAGS (0x70 << 16) +#define SD_AUTO_CMD12_ERROR_FLAGS (0x9F) +#define SD_CARD_STATUS_ERROR 0x10000000 +#define SD_CMD_MISSING 0x80000000 + +#define SD_TRAN_HIGH_SPEED 0x32 +#define SD_CARD_HIGH_CAPACITY 0x40000000 +#define SD_CARD_POWER_UP_STATUS 0x80000000 + +struct sd_dev_info { + uint32_t mode; /* interrupt or polling */ + uint32_t dma; /* dma enabled or disabled */ + uint32_t voltage; /* voltage level */ + uint32_t slot; /* if the HC is locatd at slot 0 or slot 1 */ + uint32_t version; /* 1.0 or 2.0 */ + uint32_t curSystemAddr; /* system address */ + uint32_t dataWidth; /* data width for the controller */ + uint32_t clock; /* clock rate */ + uint32_t status; /* if device is active on transfer or not */ +}; + +void data_xfer_setup(struct sd_handle *handle, uint8_t *data, + uint32_t length, int dir); +int reset_card(struct sd_handle *handle); +int reset_host_ctrl(struct sd_handle *handle); +int init_card(struct sd_handle *handle, int detection); +int init_mmc_card(struct sd_handle *handle); +int write_buffer(struct sd_handle *handle, uint32_t len, uint8_t *buffer); +int read_buffer(struct sd_handle *handle, uint32_t len, uint8_t *buffer); +int select_blk_sz(struct sd_handle *handle, uint16_t size); +int check_error(struct sd_handle *handle, uint32_t ints); + +int process_data_xfer(struct sd_handle *handle, uint8_t *buffer, + uint32_t addr, uint32_t length, int dir); +int read_block(struct sd_handle *handle, uint8_t *dst, uint32_t addr, + uint32_t len); +#ifdef INCLUDE_EMMC_DRIVER_ERASE_CODE +int erase_card(struct sd_handle *handle, uint32_t addr, uint32_t blocks); +#endif +int write_block(struct sd_handle *handle, uint8_t *src, uint32_t addr, + uint32_t len); +int process_cmd_response(struct sd_handle *handle, uint32_t cmdIndex, + uint32_t rsp0, uint32_t rsp1, uint32_t rsp2, + uint32_t rsp3, struct sd_resp *resp); +int32_t set_config(struct sd_handle *handle, uint32_t speed, + uint32_t retry, uint32_t dma, uint32_t dmaBound, + uint32_t blkSize, uint32_t wfe_retry); + +uint32_t wait_for_event(struct sd_handle *handle, uint32_t mask, + uint32_t retry); +int set_boot_config(struct sd_handle *handle, uint32_t config); + +int mmc_cmd1(struct sd_handle *handle); +#endif /* CSL_SD_H */ diff --git a/include/drivers/brcm/emmc/emmc_csl_sdcmd.h b/include/drivers/brcm/emmc/emmc_csl_sdcmd.h new file mode 100644 index 000000000..425603f89 --- /dev/null +++ b/include/drivers/brcm/emmc/emmc_csl_sdcmd.h @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2016 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CSL_SD_CMD_H +#define CSL_SD_CMD_H + +#define SD_CMD_OK 0 +#define SD_CMD_ERROR -1 + +#define SD_CMD_ERR_NO_IO_FUNC 5 +#define SD_CMD_ERR_INVALID_PARAMETER 6 +#define SD_CMD_ERR_R1_ILLEGAL_COMMAND 7 +#define SD_CMD_ERR_R1_COM_CRC_ERROR 8 +#define SD_CMD_ERR_R1_FUNC_NUM_ERROR 9 +#define SD_CMD_ERR_R1_ADDRESS_ERROR 10 +#define SD_CMD_ERR_R1_PARAMETER_ERROR 11 +#define SD_CMD_ERR_DATA_ERROR_TOKEN 12 +#define SD_CMD_ERR_DATA_NOT_ACCEPTED 13 +#define SD_CMD7_ARG_RCA_SHIFT 16 + +#define SD_CARD_STATUS_PENDING 0x01 +#define SD_CARD_STATUS_BUFFER_OVERFLOW 0x01 +#define SD_CARD_STATUS_DEVICE_BUSY 0x02 +#define SD_CARD_STATUS_UNSUCCESSFUL 0x03 +#define SD_CARD_STATUS_NOT_IMPLEMENTED 0x04 +#define SD_CARD_STATUS_ACCESS_VIOLATION 0x05 +#define SD_CARD_STATUS_INVALID_HANDLE 0x06 +#define SD_CARD_STATUS_INVALID_PARAMETER 0x07 +#define SD_CARD_STATUS_NO_SUCH_DEVICE 0x08 +#define SD_CARD_STATUS_INVALID_DEVICE_REQUEST 0x09 +#define SD_CARD_STATUS_NO_MEMORY 0x0A +#define SD_CARD_STATUS_BUS_DRIVER_NOT_READY 0x0B +#define SD_CARD_STATUS_DATA_ERROR 0x0C +#define SD_CARD_STATUS_CRC_ERROR 0x0D +#define SD_CARD_STATUS_INSUFFICIENT_RESOURCES 0x0E +#define SD_CARD_STATUS_DEVICE_NOT_CONNECTED 0x10 +#define SD_CARD_STATUS_DEVICE_REMOVED 0x11 +#define SD_CARD_STATUS_DEVICE_NOT_RESPONDING 0x12 +#define SD_CARD_STATUS_CANCELED 0x13 +#define SD_CARD_STATUS_RESPONSE_TIMEOUT 0x14 +#define SD_CARD_STATUS_DATA_TIMEOUT 0x15 +#define SD_CARD_STATUS_DEVICE_RESPONSE_ERROR 0x16 +#define SD_CARD_STATUS_DEVICE_UNSUPPORTED 0x17 + +/* Response structure */ +struct sd_r2_resp { + uint32_t rsp4; /* 127:96 */ + uint32_t rsp3; /* 95:64 */ + uint32_t rsp2; /* 63:32 */ + uint32_t rsp1; /* 31:0 */ +}; + +struct sd_r3_resp { + uint32_t ocr; +}; + +struct sd_r4_resp { + uint8_t cardReady; + uint8_t funcs; + uint8_t memPresent; + uint32_t ocr; +}; + +struct sd_r5_resp { + uint8_t data; +}; + +struct sd_r6_resp { + uint16_t rca; + uint16_t cardStatus; +}; + +struct sd_r7_resp { + uint16_t rca; +}; + +struct sd_resp { + uint8_t r1; + uint32_t cardStatus; + uint32_t rawData[4]; + union { + struct sd_r2_resp r2; + struct sd_r3_resp r3; + struct sd_r4_resp r4; + struct sd_r5_resp r5; + struct sd_r6_resp r6; + struct sd_r7_resp r7; + } data; +}; + +struct sd_card_info { + uint32_t type; /* card type SD, MMC or SDIO */ + uint64_t size; /* card size */ + uint32_t speed; /* card speed */ + uint32_t voltage; /* voltage supported */ + uint32_t mId; /* manufacturer ID */ + uint32_t oId; /* OEM ID */ + uint32_t classes; /* card class */ + uint32_t name1; /* product name part 1 */ + uint32_t name2; /* product name part 2 */ + uint32_t revision; /* revison */ + uint32_t sn; /* serial number */ + uint32_t numIoFuns; /* total I/O function number */ + uint32_t maxRdBlkLen; /* max read block length */ + uint32_t maxWtBlkLen; /* max write block length */ + uint32_t blkMode; /* sdio card block mode support */ + uint32_t f0Cis; /* sdio card block mode support */ + uint32_t f1Cis; /* sdio card block mode support */ + + uint8_t partRead; /* partial block read allowed */ + uint8_t partWrite; /* partial block write allowed */ + uint8_t dsr; /* card DSR */ + uint8_t rdCurMin; /* min current for read */ + uint8_t rdCurMax; /* max current for read */ + uint8_t wtCurMin; /* min current for write */ + uint8_t wtCurMax; /* max current for write */ + uint8_t erase; /* erase enable */ + uint8_t eraseSecSize; /* erase sector size */ + uint8_t proGrpSize; /* write protection group size */ + uint8_t protect; /* permanent write protection or not */ + uint8_t tmpProt; /* temp write protection or not */ + uint8_t wtSpeed; /* write speed relatively to read */ + uint8_t version; /* card version 0:1.0 - 1.01, 1:1.10, 2:2.0 */ + uint8_t eraseState; /* if the data will be 0 or 1 after erase */ + uint8_t bus; /* data with supported */ + uint8_t security; /* security support 0, 2:1.01 3:2.0 */ + uint8_t format; /* file format */ + uint8_t fileGrp; /* file group */ + char pwd[20]; /* password */ +}; + +struct sd_handle { + struct sd_dev *device; + struct sd_card_info *card; +}; + +int sd_cmd0(struct sd_handle *handle); +int sd_cmd1(struct sd_handle *handle, uint32_t initOcr, uint32_t *ocr); +int sd_cmd2(struct sd_handle *handle); +int sd_cmd3(struct sd_handle *handle); +int sd_cmd7(struct sd_handle *handle, uint32_t rca); +int sd_cmd9(struct sd_handle *handle, struct sd_card_data *card); +int sd_cmd13(struct sd_handle *handle, uint32_t *status); +int sd_cmd16(struct sd_handle *handle, uint32_t blockLen); +int sd_cmd17(struct sd_handle *handle, + uint32_t addr, uint32_t len, uint8_t *buffer); +int sd_cmd18(struct sd_handle *handle, + uint32_t addr, uint32_t len, uint8_t *buffer); +#ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE +int sd_cmd24(struct sd_handle *handle, + uint32_t addr, uint32_t len, uint8_t *buffer); +int sd_cmd25(struct sd_handle *handle, + uint32_t addr, uint32_t len, uint8_t *buffer); +#endif +#ifdef INCLUDE_EMMC_DRIVER_ERASE_CODE +int sd_cmd35(struct sd_handle *handle, uint32_t start); +int sd_cmd36(struct sd_handle *handle, uint32_t end); +int sd_cmd38(struct sd_handle *handle); +#endif +int mmc_cmd6(struct sd_handle *handle, uint32_t argument); +int mmc_cmd8(struct sd_handle *handle, uint8_t *extCsdReg); + +int send_cmd(struct sd_handle *handle, uint32_t cmdIndex, + uint32_t argument, uint32_t options, struct sd_resp *resp); +#endif /* CSL_SD_CMD_H */ diff --git a/include/drivers/brcm/emmc/emmc_csl_sdprot.h b/include/drivers/brcm/emmc/emmc_csl_sdprot.h new file mode 100644 index 000000000..597e1e087 --- /dev/null +++ b/include/drivers/brcm/emmc/emmc_csl_sdprot.h @@ -0,0 +1,435 @@ +/* + * Copyright (c) 2016 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CSL_SD_PROT_H +#define CSL_SD_PROT_H + +#define SD_CARD_UNKNOWN 0 /* bad type or unrecognized */ +#define SD_CARD_SD 1 /* IO only card */ +#define SD_CARD_SDIO 2 /* memory only card */ +#define SD_CARD_COMBO 3 /* IO and memory combo card */ +#define SD_CARD_MMC 4 /* memory only card */ +#define SD_CARD_CEATA 5 /* IO and memory combo card */ + +#define SD_IO_FIXED_ADDRESS 0 /* fix Address */ +#define SD_IO_INCREMENT_ADDRESS 1 + +#define SD_HIGH_CAPACITY_CARD 0x40000000 + +#define MMC_CMD_IDLE_RESET_ARG 0xF0F0F0F0 + +/* Supported operating voltages are 3.2-3.3 and 3.3-3.4 */ +#define MMC_OCR_OP_VOLT 0x00300000 +/* Enable sector access mode */ +#define MMC_OCR_SECTOR_ACCESS_MODE 0x40000000 + +/* command index */ +#define SD_CMD_GO_IDLE_STATE 0 /* mandatory for SDIO */ +#define SD_CMD_SEND_OPCOND 1 +#define SD_CMD_ALL_SEND_CID 2 +#define SD_CMD_MMC_SET_RCA 3 +#define SD_CMD_MMC_SET_DSR 4 +#define SD_CMD_IO_SEND_OP_COND 5 /* mandatory for SDIO */ +#define SD_ACMD_SET_BUS_WIDTH 6 +#define SD_CMD_SWITCH_FUNC 6 +#define SD_CMD_SELECT_DESELECT_CARD 7 +#define SD_CMD_READ_EXT_CSD 8 +#define SD_CMD_SEND_CSD 9 +#define SD_CMD_SEND_CID 10 +#define SD_CMD_STOP_TRANSMISSION 12 +#define SD_CMD_SEND_STATUS 13 +#define SD_ACMD_SD_STATUS 13 +#define SD_CMD_GO_INACTIVE_STATE 15 +#define SD_CMD_SET_BLOCKLEN 16 +#define SD_CMD_READ_SINGLE_BLOCK 17 +#define SD_CMD_READ_MULTIPLE_BLOCK 18 +#define SD_CMD_WRITE_BLOCK 24 +#define SD_CMD_WRITE_MULTIPLE_BLOCK 25 +#define SD_CMD_PROGRAM_CSD 27 +#define SD_CMD_SET_WRITE_PROT 28 +#define SD_CMD_CLR_WRITE_PROT 29 +#define SD_CMD_SEND_WRITE_PROT 30 +#define SD_CMD_ERASE_WR_BLK_START 32 +#define SD_CMD_ERASE_WR_BLK_END 33 +#define SD_CMD_ERASE_GROUP_START 35 +#define SD_CMD_ERASE_GROUP_END 36 +#define SD_CMD_ERASE 38 +#define SD_CMD_LOCK_UNLOCK 42 +#define SD_CMD_IO_RW_DIRECT 52 /* mandatory for SDIO */ +#define SD_CMD_IO_RW_EXTENDED 53 /* mandatory for SDIO */ +#define SD_CMD_APP_CMD 55 +#define SD_CMD_GEN_CMD 56 +#define SD_CMD_READ_OCR 58 +#define SD_CMD_CRC_ON_OFF 59 /* mandatory for SDIO */ +#define SD_ACMD_SEND_NUM_WR_BLOCKS 22 +#define SD_ACMD_SET_WR_BLOCK_ERASE_CNT 23 +#define SD_ACMD_SD_SEND_OP_COND 41 +#define SD_ACMD_SET_CLR_CARD_DETECT 42 +#define SD_ACMD_SEND_SCR 51 + +/* response parameters */ +#define SD_RSP_NO_NONE 0 +#define SD_RSP_NO_1 1 +#define SD_RSP_NO_2 2 +#define SD_RSP_NO_3 3 +#define SD_RSP_NO_4 4 +#define SD_RSP_NO_5 5 +#define SD_RSP_NO_6 6 + +/* Modified R6 response (to CMD3) */ +#define SD_RSP_MR6_COM_CRC_ERROR 0x8000 +#define SD_RSP_MR6_ILLEGAL_COMMAND 0x4000 +#define SD_RSP_MR6_ERROR 0x2000 + +/* Modified R1 in R4 Response (to CMD5) */ +#define SD_RSP_MR1_SBIT 0x80 +#define SD_RSP_MR1_PARAMETER_ERROR 0x40 +#define SD_RSP_MR1_RFU5 0x20 +#define SD_RSP_MR1_FUNC_NUM_ERROR 0x10 +#define SD_RSP_MR1_COM_CRC_ERROR 0x80 +#define SD_RSP_MR1_ILLEGAL_COMMAND 0x40 +#define SD_RSP_MR1_RFU1 0x20 +#define SD_RSP_MR1_IDLE_STATE 0x01 + +/* R5 response (to CMD52 and CMD53) */ +#define SD_RSP_R5_COM_CRC_ERROR 0x80 +#define SD_RSP_R5_ILLEGAL_COMMAND 0x40 +#define SD_RSP_R5_IO_CURRENTSTATE1 0x20 +#define SD_RSP_R5_IO_CURRENTSTATE0 0x10 +#define SD_RSP_R5_ERROR 0x80 +#define SD_RSP_R5_RFU 0x40 +#define SD_RSP_R5_FUNC_NUM_ERROR 0x20 +#define SD_RSP_R5_OUT_OF_RANGE 0x01 + +/* argument for SD_CMD_IO_RW_DIRECT and SD_CMD_IO_RW_EXTENDED */ +#define SD_OP_READ 0 /* Read_Write */ +#define SD_OP_WRITE 1 /* Read_Write */ + +#define SD_RW_NORMAL 0 /* no RAW */ +#define SD_RW_RAW 1 /* RAW */ + +#define SD_BYTE_MODE 0 /* Byte Mode */ +#define SD_BLOCK_MODE 1 /* BlockMode */ + +#define SD_FIXED_ADDRESS 0 /* fix Address */ +#define SD_INCREMENT_ADDRESS 1 /* IncrementAddress */ + +#define SD_CMD5_ARG_IO_OCR_MASK 0x00FFFFFF +#define SD_CMD5_ARG_IO_OCR_SHIFT 0 +#define SD_CMD55_ARG_RCA_SHIFT 16 +#define SD_CMD59_ARG_CRC_OPTION_MASK 0x01 +#define SD_CMD59_ARG_CRC_OPTION_SHIFT 0 + +/* SD_CMD_IO_RW_DIRECT Argument */ +#define SdioIoRWDirectArg(rw, raw, func, addr, data) \ + (((rw & 1) << 31) | ((func & 0x7) << 28) | \ + ((raw & 1) << 27) | ((addr & 0x1FFFF) << 9) | \ + (data & 0xFF)) + +/* build SD_CMD_IO_RW_EXTENDED Argument */ +#define SdioIoRWExtArg(rw, blk, func, addr, inc_addr, count) \ + (((rw & 1) << 31) | ((func & 0x7) << 28) | \ + ((blk & 1) << 27) | ((inc_addr & 1) << 26) | \ + ((addr & 0x1FFFF) << 9) | (count & 0x1FF)) + +/* + * The Common I/O area shall be implemented on all SDIO cards and + * is accessed the the host via I/O reads and writes to function 0, + * the registers within the CIA are provided to enable/disable + * the operationo fthe i/o funciton. + */ + +/* cccr_sdio_rev */ +#define SDIO_REV_SDIOID_MASK 0xf0 /* SDIO spec revision number */ +#define SDIO_REV_CCCRID_MASK 0x0f /* CCCR format version number */ + +/* sd_rev */ +#define SDIO_REV_PHY_MASK 0x0f /* SD format version number */ +#define SDIO_FUNC_ENABLE_1 0x02 /* function 1 I/O enable */ +#define SDIO_FUNC_READY_1 0x02 /* function 1 I/O ready */ +#define SDIO_INTR_CTL_FUNC1_EN 0x2 /* interrupt enable for function 1 */ +#define SDIO_INTR_CTL_MASTER_EN 0x1 /* interrupt enable master */ +#define SDIO_INTR_STATUS_FUNC1 0x2 /* interrupt pending for function 1 */ +#define SDIO_IO_ABORT_RESET_ALL 0x08 /* I/O card reset */ +#define SDIO_IO_ABORT_FUNC_MASK 0x07 /* abort selection: function x */ +#define SDIO_BUS_CARD_DETECT_DIS 0x80 /* Card Detect disable */ +#define SDIO_BUS_SPI_CONT_INTR_CAP 0x40 /* support continuous SPI interrupt */ +#define SDIO_BUS_SPI_CONT_INTR_EN 0x20 /* continuous SPI interrupt enable */ +#define SDIO_BUS_DATA_WIDTH_MASK 0x03 /* bus width mask */ +#define SDIO_BUS_DATA_WIDTH_4BIT 0x02 /* bus width 4-bit mode */ +#define SDIO_BUS_DATA_WIDTH_1BIT 0x00 /* bus width 1-bit mode */ + +/* capability */ +#define SDIO_CAP_4BLS 0x80 /* 4-bit support for low speed card */ +#define SDIO_CAP_LSC 0x40 /* low speed card */ +#define SDIO_CAP_E4MI 0x20 /* enable int between block in 4-bit mode */ +#define SDIO_CAP_S4MI 0x10 /* support int between block in 4-bit mode */ +#define SDIO_CAP_SBS 0x08 /* support suspend/resume */ +#define SDIO_CAP_SRW 0x04 /* support read wait */ +#define SDIO_CAP_SMB 0x02 /* support multi-block transfer */ +#define SDIO_CAP_SDC 0x01 /* Support Direct cmd during multi-uint8 transfer */ + +/* CIA FBR1 registers */ +#define SDIO_FUNC1_INFO 0x100 /* basic info for function 1 */ +#define SDIO_FUNC1_EXT 0x101 /* extension of standard I/O device */ +#define SDIO_CIS_FUNC1_BASE_LOW 0x109 /* function 1 cis address bit 0-7 */ +#define SDIO_CIS_FUNC1_BASE_MID 0x10A /* function 1 cis address bit 8-15 */ +#define SDIO_CIS_FUNC1_BASE_HIGH 0x10B /* function 1 cis address bit 16 */ +#define SDIO_CSA_BASE_LOW 0x10C /* CSA base address uint8_t 0 */ +#define SDIO_CSA_BASE_MID 0x10D /* CSA base address uint8_t 1 */ +#define SDIO_CSA_BASE_HIGH 0x10E /* CSA base address uint8_t 2 */ +#define SDIO_CSA_DATA_OFFSET 0x10F /* CSA data register */ +#define SDIO_IO_BLK_SIZE_LOW 0x110 /* I/O block size uint8_t 0 */ +#define SDIO_IO_BLK_SIZE_HIGH 0x111 /* I/O block size uint8_t 1 */ + +/* SD_SDIO_FUNC1_INFO bits */ +#define SDIO_FUNC1_INFO_DIC 0x0f /* device interface code */ +#define SDIO_FUNC1_INFO_CSA 0x40 /* CSA support flag */ +#define SDIO_FUNC1_INFO_CSA_EN 0x80 /* CSA enabled */ + +/* SD_SDIO_FUNC1_EXT bits */ +#define SDIO_FUNC1_EXT_SHP 0x03 /* support high power */ +#define SDIO_FUNC1_EXT_EHP 0x04 /* enable high power */ + +/* devctr */ +/* I/O device interface code */ +#define SDIO_DEVCTR_DEVINTER 0x0f +/* support CSA */ +#define SDIO_DEVCTR_CSA_SUP 0x40 +/* enable CSA */ +#define SDIO_DEVCTR_CSA_EN 0x80 + +/* ext_dev */ +/* supports high-power mask */ +#define SDIO_HIGHPWR_SUPPORT_M 0x3 +/* enable high power */ +#define SDIO_HIGHPWR_EN 0x4 +/* standard power function(up to 200mA */ +#define SDIO_HP_STD 0 +/* need high power to operate */ +#define SDIO_HP_REQUIRED 0x2 +/* can work with standard power, but prefer high power */ +#define SDIO_HP_DESIRED 0x3 + +/* misc define */ +/* macro to calculate fbr register base */ +#define FBR_REG_BASE(n) (n*0x100) +#define SDIO_FUNC_0 0 +#define SDIO_FUNC_1 1 +#define SDIO_FUNC_2 2 +#define SDIO_FUNC_3 3 +#define SDIO_FUNC_4 4 +#define SDIO_FUNC_5 5 +#define SDIO_FUNC_6 6 +#define SDIO_FUNC_7 7 + +/* maximum block size for block mode operation */ +#define SDIO_MAX_BLOCK_SIZE 2048 +/* minimum block size for block mode operation */ +#define SDIO_MIN_BLOCK_SIZE 1 + +/* Card registers: status bit position */ +#define SDIO_STATUS_OUTOFRANGE 31 +#define SDIO_STATUS_COMCRCERROR 23 +#define SDIO_STATUS_ILLEGALCOMMAND 22 +#define SDIO_STATUS_ERROR 19 +#define SDIO_STATUS_IOCURRENTSTATE3 12 +#define SDIO_STATUS_IOCURRENTSTATE2 11 +#define SDIO_STATUS_IOCURRENTSTATE1 10 +#define SDIO_STATUS_IOCURRENTSTATE0 9 +#define SDIO_STATUS_FUN_NUM_ERROR 4 + +#define GET_SDIOCARD_STATUS(x) ((x >> 9) & 0x0f) +#define SDIO_STATUS_STATE_IDLE 0 +#define SDIO_STATUS_STATE_READY 1 +#define SDIO_STATUS_STATE_IDENT 2 +#define SDIO_STATUS_STATE_STBY 3 +#define SDIO_STATUS_STATE_TRAN 4 +#define SDIO_STATUS_STATE_DATA 5 +#define SDIO_STATUS_STATE_RCV 6 +#define SDIO_STATUS_STATE_PRG 7 +#define SDIO_STATUS_STATE_DIS 8 + +/* sprom */ +#define SBSDIO_SPROM_CS 0x10000 /* command and status */ +#define SBSDIO_SPROM_INFO 0x10001 /* info register */ +#define SBSDIO_SPROM_DATA_LOW 0x10002 /* indirect access data uint8_t 0 */ +#define SBSDIO_SPROM_DATA_HIGH 0x10003 /* indirect access data uint8_t 1 */ +#define SBSDIO_SPROM_ADDR_LOW 0x10004 /* indirect access addr uint8_t 0 */ +#define SBSDIO_SPROM_ADDR_HIGH 0x10005 /* indirect access addr uint8_t 0 */ +#define SBSDIO_CHIP_CTRL_DATA 0x10006 /* xtal_pu data output */ +#define SBSDIO_CHIP_CTRL_EN 0x10007 /* xtal_pu enable */ +#define SBSDIO_WATERMARK 0x10008 /* retired in rev 7 */ +#define SBSDIO_DEVICE_CTL 0x10009 /* control busy signal generation */ + +#define SBSDIO_SPROM_IDLE 0 +#define SBSDIO_SPROM_WRITE 1 +#define SBSDIO_SPROM_READ 2 +#define SBSDIO_SPROM_WEN 4 +#define SBSDIO_SPROM_WDS 7 +#define SBSDIO_SPROM_DONE 8 + +/* SBSDIO_SPROM_INFO */ +#define SBSDIO_SROM_SZ_MASK 0x03 /* SROM size, 1: 4k, 2: 16k */ +#define SBSDIO_SROM_BLANK 0x04 /* depreciated in corerev 6 */ +#define SBSDIO_SROM_OTP 0x80 /* OTP present */ + +/* SBSDIO_CHIP_CTRL */ +/* or'd with onchip xtal_pu, 1: power on oscillator */ +#define SBSDIO_CHIP_CTRL_XTAL 0x01 + +/* SBSDIO_WATERMARK */ +/* number of bytes minus 1 for sd device to wait before sending data to host */ +#define SBSDIO_WATERMARK_MASK 0x3f + +/* SBSDIO_DEVICE_CTL */ +/* 1: device will assert busy signal when receiving CMD53 */ +#define SBSDIO_DEVCTL_SETBUSY 0x01 +/* 1: assertion of sdio interrupt is synchronous to the sdio clock */ +#define SBSDIO_DEVCTL_SPI_INTR_SYNC 0x02 + +/* function 1 OCP space */ +/* sb offset addr is <= 15 bits, 32k */ +#define SBSDIO_SB_OFT_ADDR_MASK 0x07FFF +#define SBSDIO_SB_OFT_ADDR_LIMIT 0x08000 +/* sdsdio function 1 OCP space has 16/32 bit section */ +#define SBSDIO_SB_ACCESS_2_4B_FLAG 0x08000 + +/* direct(mapped) cis space */ +/* MAPPED common CIS address */ +#define SBSDIO_CIS_BASE_COMMON 0x1000 +/* function 0(common) cis size in bytes */ +#define SBSDIO_CIS_FUNC0_LIMIT 0x020 +/* funciton 1 cis size in bytes */ +#define SBSDIO_CIS_SIZE_LIMIT 0x200 +/* cis offset addr is < 17 bits */ +#define SBSDIO_CIS_OFT_ADDR_MASK 0x1FFFF +/* manfid tuple length, include tuple, link bytes */ +#define SBSDIO_CIS_MANFID_TUPLE_LEN 6 + +/* indirect cis access (in sprom) */ +/* 8 control bytes first, CIS starts from 8th uint8_t */ +#define SBSDIO_SPROM_CIS_OFFSET 0x8 +/* sdio uint8_t mode: maximum length of one data comamnd */ +#define SBSDIO_BYTEMODE_DATALEN_MAX 64 +/* 4317 supports less */ +#define SBSDIO_BYTEMODE_DATALEN_MAX_4317 52 +/* sdio core function one address mask */ +#define SBSDIO_CORE_ADDR_MASK 0x1FFFF + +/* CEATA defines */ +#define CEATA_EXT_CSDBLOCK_SIZE 512 +#define CEATA_FAST_IO 39 +#define CEATA_MULTIPLE_REGISTER_RW 60 +#define CEATA_MULTIPLE_BLOCK_RW 61 + +/* defines CE ATA task file registers */ +#define CEATA_SCT_CNT_EXP_REG 0x02 +#define CEATA_LBA_LOW_EXP_REG 0x03 +#define CEATA_LBA_MID_EXP_REG 0x04 +#define CEATA_LBA_HIGH_EXP_REG 0x05 +#define CEATA_CNTRL_REG 0x06 +#define CEATA_FEATURE_REG 0x09 /* write */ +#define CEATA_ERROR_REG 0x09 /* read */ +#define CEATA_SCT_CNT_REG 0x0A +#define CEATA_LBA_LOW_REG 0x0B +#define CEATA_LBA_MID_REG 0x0C +#define CEATA_LBA_HIGH_REG 0x0D +#define CEATA_DEV_HEAD_REG 0x0E +#define CEATA_STA_REG 0x0F /* read */ +#define CEATA_CMD_REG 0x0F /* write */ + +/* defines CEATA control and status registers for ce ata client driver */ +#define CEATA_SCR_TEMPC_REG 0x80 +#define CEATA_SCR_TEMPMAXP_REG 0x84 +#define CEATA_TEMPMINP_REG 0x88 +#define CEATA_SCR_STATUS_REG 0x8C +#define CEATA_SCR_REALLOCSA_REG 0x90 +#define CEATA_SCR_ERETRACTSA_REG 0x94 +#define CEATA_SCR_CAPABILITIES_REG 0x98 +#define CEATA_SCR_CONTROL_REG 0xC0 + +/* defines for SCR capabilities register bits for ce ata client driver */ +#define CEATA_SCR_CAP_512 0x00000001 +#define CEATA_SCR_CAP_1K 0x00000002 +#define CEATA_SCR_CAP_4K 0x00000004 + +/* defines CE ATA Control reg bits for ce ata client driver */ +#define CEATA_CNTRL_ENABLE_INTR 0x00 +#define CEATA_CNTRL_DISABLE_INTR 0x02 +#define CEATA_CNTRL_SRST 0x04 +#define CEATA_CNTRL_RSRST 0x00 + +/* define CE ATA Status reg bits for ce ata client driver */ +#define CEATA_STA_ERROR_BIT 0x01 +#define CEATA_STA_OVR_BIT 0x02 +#define CEATA_STA_SPT_BIT 0x04 +#define CEATA_STA_DRQ_BIT 0x08 +#define CEATA_STA_DRDY_BIT 0x40 +#define CEATA_STA_BSY_BIT 0x80 + +/* define CE ATA Error reg bits for ce ata client driver */ +#define CEATA_ERROR_ABORTED_BIT 0x04 +#define CEATA_ERROR_IDNF_BIT 0x10 +#define CEATA_ERROR_UNCORRECTABLE_BIT 0x40 +#define CEATA_ERROR_ICRC_BIT 0x80 + +/* define CE ATA Commands for ce ata client driver */ +#define CEATA_CMD_IDENTIFY_DEVICE 0xEC +#define CEATA_CMD_READ_DMA_EXT 0x25 +#define CEATA_CMD_WRITE_DMA_EXT 0x35 +#define CEATA_CMD_STANDBY_IMMEDIATE 0xE0 +#define CEATA_CMD_FLUSH_CACHE_EXT 0xEA + +struct csd_mmc { + uint32_t padding:8; + uint32_t structure:2; + uint32_t csdSpecVer:4; + uint32_t reserved1:2; + uint32_t taac:8; + uint32_t nsac:8; + uint32_t speed:8; + uint32_t classes:12; + uint32_t rdBlkLen:4; + uint32_t rdBlkPartial:1; + uint32_t wrBlkMisalign:1; + uint32_t rdBlkMisalign:1; + uint32_t dsr:1; + uint32_t reserved2:2; + uint32_t size:12; + uint32_t vddRdCurrMin:3; + uint32_t vddRdCurrMax:3; + uint32_t vddWrCurrMin:3; + uint32_t vddWrCurrMax:3; + uint32_t devSizeMulti:3; + uint32_t eraseGrpSize:5; + uint32_t eraseGrpSizeMulti:5; + uint32_t wrProtGroupSize:5; + uint32_t wrProtGroupEnable:1; + uint32_t manuDefEcc:2; + uint32_t wrSpeedFactor:3; + uint32_t wrBlkLen:4; + uint32_t wrBlkPartial:1; + uint32_t reserved5:4; + uint32_t protAppl:1; + uint32_t fileFormatGrp:1; + uint32_t copyFlag:1; + uint32_t permWrProt:1; + uint32_t tmpWrProt:1; + uint32_t fileFormat:2; + uint32_t eccCode:2; +}; + +/* CSD register*/ +union sd_csd { + uint32_t csd[4]; + struct csd_mmc mmc; +}; + +struct sd_card_data { + union sd_csd csd; +}; +#endif /* CSL_SD_PROT_H */ diff --git a/include/drivers/brcm/emmc/emmc_pboot_hal_memory_drv.h b/include/drivers/brcm/emmc/emmc_pboot_hal_memory_drv.h new file mode 100644 index 000000000..8e61b51c0 --- /dev/null +++ b/include/drivers/brcm/emmc/emmc_pboot_hal_memory_drv.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2016 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PBOOT_HAL_MEMORY_EMMC_DRV_H +#define PBOOT_HAL_MEMORY_EMMC_DRV_H + +#include + +#include "emmc_chal_types.h" +#include "emmc_chal_sd.h" +#include "emmc_csl_sdprot.h" +#include "emmc_csl_sdcmd.h" +#include "emmc_csl_sd.h" +#include "emmc_brcm_rdb_sd4_top.h" + +#define CLK_SDIO_DIV_52MHZ 0x0 +#define SYSCFG_IOCR4_PAD_10MA 0x38000000 + +#define SDCLK_CNT_PER_MS 52000 +#define BOOT_ACK_TIMEOUT (50 * SDCLK_CNT_PER_MS) +#define BOOT_DATA_TIMEOUT (1000 * SDCLK_CNT_PER_MS) + +#define EMMC_BOOT_OK 0 +#define EMMC_BOOT_ERROR 1 +#define EMMC_BOOT_TIMEOUT 2 +#define EMMC_BOOT_INVALIDIMAGE 3 +#define EMMC_BOOT_NO_CARD 4 + +#define EMMC_USER_AREA 0 +#define EMMC_BOOT_PARTITION1 1 +#define EMMC_BOOT_PARTITION2 2 +#define EMMC_USE_CURRENT_PARTITION 3 + +#define EMMC_BOOT_PARTITION_SIZE (128*1024) +#define EMMC_BLOCK_SIZE 512 +#define EMMC_DMA_SIZE (4*1024) + +/* + * EMMC4.3 definitions + * Table 6 EXT_CSD access mode + * Access + * Bits Access Name Operation + * 00 Command Set The command set is changed according to the Cmd Set field of + * the argument + * 01 Set Bits The bits in the pointed uint8_t are set, + * according to the 1 bits in the Value field. + * 10 Clear Bits The bits in the pointed uint8_t are cleared, + * according to the 1 bits in the Value field. + * 11 Write Byte The Value field is written into the pointed uint8_t. + */ + +#define SDIO_HW_EMMC_EXT_CSD_WRITE_BYTE 0X03000000 + +/* Boot bus width1 BOOT_BUS_WIDTH 1 R/W [177] */ +#define SDIO_HW_EMMC_EXT_CSD_BOOT_BUS_WIDTH_OFFSET 0X00B10000 + +/* Boot configuration BOOT_CONFIG 1 R/W [179] */ +#define SDIO_HW_EMMC_EXT_CSD_BOOT_CONFIG_OFFSET 0X00B30000 + +/* Bus width mode BUS_WIDTH 1 WO [183] */ +#define SDIO_HW_EMMC_EXT_CSD_BUS_WIDTH_OFFSET 0X00B70000 + +/* + * Bit 6: BOOT_ACK (non-volatile) + * 0x0 : No boot acknowledge sent (default) + * 0x1 : Boot acknowledge sent during boot operation + * Bit[5:3] : BOOT_PARTITION_ENABLE (non-volatile) + * User selects boot data that will be sent to master + * 0x0 : Device not boot enabled (default) + * 0x1 : Boot partition 1 enabled for boot + * 0x2 : Boot partition 2 enabled for boot + * 0x3-0x6 : Reserved + * 0x7 : User area enabled for boot + * Bit[2:0] : BOOT_PARTITION_ACCESS + * User selects boot partition for read and write operation + * 0x0 : No access to boot partition (default) + * 0x1 : R/W boot partition 1 + * 0x2 : R/W boot partition 2 + * 0x3-0x7 : Reserved + */ + +#define SDIO_HW_EMMC_EXT_CSD_BOOT_ACC_BOOT1 0X00000100 +#define SDIO_HW_EMMC_EXT_CSD_BOOT_ACC_BOOT2 0X00000200 +#define SDIO_HW_EMMC_EXT_CSD_BOOT_ACC_USER 0X00000000 +#define SDIO_HW_EMMC_EXT_CSD_BOOT_EN_BOOT1 0X00004800 +#define SDIO_HW_EMMC_EXT_CSD_BOOT_EN_BOOT2 0X00005000 +#define SDIO_HW_EMMC_EXT_CSD_BOOT_EN_USER 0X00007800 + +#define SD_US_DELAY(x) udelay(x) + +#endif diff --git a/plat/brcm/board/common/board_common.mk b/plat/brcm/board/common/board_common.mk index a0112c516..2a7ebdf66 100644 --- a/plat/brcm/board/common/board_common.mk +++ b/plat/brcm/board/common/board_common.mk @@ -28,6 +28,10 @@ SYSCNT_FREQ := $(GENTIMER_ACTUAL_CLOCK) $(eval $(call add_define,SYSCNT_FREQ)) endif +ifeq (${DRIVER_EMMC_ENABLE},) +DRIVER_EMMC_ENABLE :=1 +endif + # By default, Trusted Watchdog is always enabled unless SPIN_ON_BL1_EXIT is set ifeq (${BRCM_DISABLE_TRUSTED_WDOG},) BRCM_DISABLE_TRUSTED_WDOG := 0 @@ -89,6 +93,14 @@ ifneq (${USE_CRMU_SRAM},) $(eval $(call add_define,USE_CRMU_SRAM)) endif +# Use PIO mode if DDR is not used +ifeq (${USE_DDR},yes) +EMMC_USE_DMA := 1 +else +EMMC_USE_DMA := 0 +endif +$(eval $(call add_define,EMMC_USE_DMA)) + # On BRCM platforms, separate the code and read-only data sections to allow # mapping the former as executable and the latter as execute-never. SEPARATE_CODE_AND_RODATA := 1 @@ -97,7 +109,8 @@ SEPARATE_CODE_AND_RODATA := 1 USE_TBBR_DEFS := 1 PLAT_INCLUDES += -Iplat/brcm/board/common \ - -Iinclude/drivers/brcm + -Iinclude/drivers/brcm \ + -Iinclude/drivers/brcm/emmc PLAT_BL_COMMON_SOURCES += plat/brcm/common/brcm_common.c \ plat/brcm/board/common/cmn_sec.c \ @@ -116,6 +129,22 @@ PLAT_BL_COMMON_SOURCES += plat/brcm/common/brcm_common.c \ plat/brcm/board/common/sbl_util.c \ drivers/arm/sp805/sp805.c +# Add eMMC driver +ifeq (${DRIVER_EMMC_ENABLE},1) +$(eval $(call add_define,DRIVER_EMMC_ENABLE)) + +EMMC_SOURCES += drivers/brcm/emmc/emmc_chal_sd.c \ + drivers/brcm/emmc/emmc_csl_sdcard.c \ + drivers/brcm/emmc/emmc_csl_sdcmd.c \ + drivers/brcm/emmc/emmc_pboot_hal_memory_drv.c + +PLAT_BL_COMMON_SOURCES += ${EMMC_SOURCES} + +ifeq (${DRIVER_EMMC_ENABLE_DATA_WIDTH_8BIT},) +$(eval $(call add_define,DRIVER_EMMC_ENABLE_DATA_WIDTH_8BIT)) +endif +endif + BL2_SOURCES += plat/brcm/common/brcm_bl2_mem_params_desc.c \ plat/brcm/common/brcm_image_load.c \ common/desc_image_load.c diff --git a/plat/brcm/board/stingray/driver/plat_emmc.c b/plat/brcm/board/stingray/driver/plat_emmc.c new file mode 100644 index 000000000..82085e1af --- /dev/null +++ b/plat/brcm/board/stingray/driver/plat_emmc.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2016 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include + +#include + +#define ICFG_IPROC_IOPAD_CTRL_4 (IPROC_ROOT + 0x9c0) +#define ICFG_IPROC_IOPAD_CTRL_5 (IPROC_ROOT + 0x9c4) +#define ICFG_IPROC_IOPAD_CTRL_6 (IPROC_ROOT + 0x9c8) +#define ICFG_IPROC_IOPAD_CTRL_7 (IPROC_ROOT + 0x9cc) + +#define IOPAD_CTRL4_SDIO0_CD_IND_R 30 +#define IOPAD_CTRL4_SDIO0_CD_SRC_R 31 +#define IOPAD_CTRL4_SDIO0_CD_HYS_R 29 +#define IOPAD_CTRL4_SDIO0_CD_PULL_R 28 +#define IOPAD_CTRL4_SDIO0_CD_DRIVE_R 24 +#define IOPAD_CTRL4_SDIO0_CLK_SDCARD_SRC_R 23 +#define IOPAD_CTRL4_SDIO0_CLK_SDCARD_HYS_R 21 +#define IOPAD_CTRL4_SDIO0_CLK_SDCARD_DRIVE_R 17 + +#define IOPAD_CTRL4_SDIO0_DATA0_SRC_R 15 +#define IOPAD_CTRL4_SDIO0_DATA0_HYS_R 13 +#define IOPAD_CTRL4_SDIO0_DATA0_DRIVE_R 9 +#define IOPAD_CTRL4_SDIO0_DATA1_SRC_R 7 +#define IOPAD_CTRL4_SDIO0_DATA1_HYS_R 5 +#define IOPAD_CTRL4_SDIO0_DATA1_DRIVE_R 1 + +#define IOPAD_CTRL5_SDIO0_DATA2_SRC_R 31 +#define IOPAD_CTRL5_SDIO0_DATA2_HYS_R 29 +#define IOPAD_CTRL5_SDIO0_DATA2_DRIVE_R 25 +#define IOPAD_CTRL5_SDIO0_DATA3_SRC_R 23 +#define IOPAD_CTRL5_SDIO0_DATA3_IND_R 22 +#define IOPAD_CTRL5_SDIO0_DATA3_HYS_R 21 +#define IOPAD_CTRL5_SDIO0_DATA3_DRIVE_R 17 +#define IOPAD_CTRL5_SDIO0_DATA4_SRC_R 15 +#define IOPAD_CTRL5_SDIO0_DATA4_HYS_R 13 +#define IOPAD_CTRL5_SDIO0_DATA4_DRIVE_R 9 +#define IOPAD_CTRL5_SDIO0_DATA5_SRC_R 7 +#define IOPAD_CTRL5_SDIO0_DATA5_HYS_R 5 +#define IOPAD_CTRL5_SDIO0_DATA5_DRIVE_R 1 + +#define IOPAD_CTRL6_SDIO0_DATA6_SRC_R 31 +#define IOPAD_CTRL6_SDIO0_DATA6_HYS_R 29 +#define IOPAD_CTRL6_SDIO0_DATA6_DRIVE_R 25 +#define IOPAD_CTRL6_SDIO0_DATA7_SRC_R 23 +#define IOPAD_CTRL6_SDIO0_DATA7_HYS_R 21 +#define IOPAD_CTRL6_SDIO0_DATA7_DRIVE_R 17 + +void emmc_soft_reset(void) +{ + uint32_t val = 0; + + val = (BIT(IOPAD_CTRL6_SDIO0_DATA7_SRC_R) | + BIT(IOPAD_CTRL6_SDIO0_DATA7_HYS_R) | + BIT(IOPAD_CTRL6_SDIO0_DATA7_DRIVE_R) | + BIT(IOPAD_CTRL6_SDIO0_DATA6_SRC_R) | + BIT(IOPAD_CTRL6_SDIO0_DATA6_HYS_R) | + BIT(IOPAD_CTRL6_SDIO0_DATA6_DRIVE_R)); + + mmio_write_32(ICFG_IPROC_IOPAD_CTRL_6, val); + + val = (BIT(IOPAD_CTRL5_SDIO0_DATA3_SRC_R) | + BIT(IOPAD_CTRL5_SDIO0_DATA3_HYS_R) | + BIT(IOPAD_CTRL5_SDIO0_DATA3_DRIVE_R) | + BIT(IOPAD_CTRL5_SDIO0_DATA4_SRC_R) | + BIT(IOPAD_CTRL5_SDIO0_DATA4_HYS_R) | + BIT(IOPAD_CTRL5_SDIO0_DATA4_DRIVE_R) | + BIT(IOPAD_CTRL5_SDIO0_DATA5_SRC_R) | + BIT(IOPAD_CTRL5_SDIO0_DATA5_HYS_R) | + BIT(IOPAD_CTRL5_SDIO0_DATA5_DRIVE_R)); + + mmio_write_32(ICFG_IPROC_IOPAD_CTRL_5, val); + + val = (BIT(IOPAD_CTRL4_SDIO0_DATA0_SRC_R) | + BIT(IOPAD_CTRL4_SDIO0_DATA0_HYS_R) | + BIT(IOPAD_CTRL4_SDIO0_DATA0_DRIVE_R) | + BIT(IOPAD_CTRL4_SDIO0_DATA1_SRC_R) | + BIT(IOPAD_CTRL4_SDIO0_DATA1_HYS_R) | + BIT(IOPAD_CTRL4_SDIO0_DATA1_DRIVE_R) | + BIT(IOPAD_CTRL5_SDIO0_DATA2_SRC_R) | + BIT(IOPAD_CTRL5_SDIO0_DATA2_HYS_R) | + BIT(IOPAD_CTRL5_SDIO0_DATA2_DRIVE_R)); + + mmio_write_32(ICFG_IPROC_IOPAD_CTRL_6, val); + + val = (BIT(IOPAD_CTRL4_SDIO0_CLK_SDCARD_SRC_R) | + BIT(IOPAD_CTRL4_SDIO0_CLK_SDCARD_HYS_R) | + BIT(IOPAD_CTRL4_SDIO0_CLK_SDCARD_DRIVE_R) | + BIT(IOPAD_CTRL4_SDIO0_CD_SRC_R) | + BIT(IOPAD_CTRL4_SDIO0_CD_HYS_R)); + + /* + * set pull-down, clear pull-up=0 + * bit 12: pull-down bit 11: pull-up + * Note: In emulation, this pull-down setting was not + * sufficient. Board design likely requires pull down on + * this pin for eMMC. + */ + + val |= BIT(IOPAD_CTRL4_SDIO0_CD_PULL_R); + + mmio_write_32(ICFG_IPROC_IOPAD_CTRL_4, val); +} diff --git a/plat/brcm/board/stingray/platform.mk b/plat/brcm/board/stingray/platform.mk index cc7ae5303..8d2119d24 100644 --- a/plat/brcm/board/stingray/platform.mk +++ b/plat/brcm/board/stingray/platform.mk @@ -24,6 +24,13 @@ ERRATA_A72_859971 := 1 DRIVER_CC_ENABLE := 1 $(eval $(call add_define,DRIVER_CC_ENABLE)) +# Enable to erase eMMC +INCLUDE_EMMC_DRIVER_ERASE_CODE := 0 + +ifeq (${INCLUDE_EMMC_DRIVER_ERASE_CODE},1) +$(eval $(call add_define,INCLUDE_EMMC_DRIVER_ERASE_CODE)) +endif + # BL31 is in DRAM ARM_BL31_IN_DRAM := 1 @@ -178,6 +185,7 @@ PLAT_BL_COMMON_SOURCES += lib/cpus/aarch64/cortex_a72.S \ drivers/ti/uart/aarch64/16550_console.S \ plat/${SOC_DIR}/src/tz_sec.c \ drivers/arm/tzc/tzc400.c \ + plat/${SOC_DIR}/driver/plat_emmc.c \ plat/${SOC_DIR}/src/topology.c ifeq (${USE_CHIMP},yes) diff --git a/plat/brcm/board/stingray/src/bl2_setup.c b/plat/brcm/board/stingray/src/bl2_setup.c index 0b0a3ffe1..9a79744d5 100644 --- a/plat/brcm/board/stingray/src/bl2_setup.c +++ b/plat/brcm/board/stingray/src/bl2_setup.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #ifdef USE_GPIO #include -- cgit v1.2.3 From e3ee7b7dc85fdfd5fd445353ad65cd39302e94f6 Mon Sep 17 00:00:00 2001 From: Sheetal Tigadoli Date: Sun, 5 Jan 2020 21:19:02 +0530 Subject: drivers: Add iproc spi driver Add iproc spi driver Change-Id: I652efab1efd9c487974dae9cb9d98b9b8e3759c4 Signed-off-by: Sheetal Tigadoli --- drivers/brcm/spi/iproc_qspi.c | 317 +++++++++++++++++++++++++++++++++ drivers/brcm/spi/iproc_qspi.h | 107 +++++++++++ drivers/brcm/spi/iproc_spi.c | 31 ++++ include/drivers/brcm/spi.h | 21 +++ plat/brcm/board/common/board_common.mk | 10 ++ plat/brcm/board/stingray/platform.mk | 4 + 6 files changed, 490 insertions(+) create mode 100644 drivers/brcm/spi/iproc_qspi.c create mode 100644 drivers/brcm/spi/iproc_qspi.h create mode 100644 drivers/brcm/spi/iproc_spi.c create mode 100644 include/drivers/brcm/spi.h diff --git a/drivers/brcm/spi/iproc_qspi.c b/drivers/brcm/spi/iproc_qspi.c new file mode 100644 index 000000000..4c533d534 --- /dev/null +++ b/drivers/brcm/spi/iproc_qspi.c @@ -0,0 +1,317 @@ +/* + * Copyright (c) 2017 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "iproc_qspi.h" + +struct bcmspi_priv spi_cfg; + +/* Redefined by platform to force appropriate information */ +#pragma weak plat_spi_init +int plat_spi_init(uint32_t *max_hz) +{ + return 0; +} + +/* Initialize & setup iproc qspi controller */ +int iproc_qspi_setup(uint32_t bus, uint32_t cs, uint32_t max_hz, uint32_t mode) +{ + struct bcmspi_priv *priv = NULL; + uint32_t spbr; + + priv = &spi_cfg; + priv->spi_mode = mode; + priv->state = QSPI_STATE_DISABLED; + priv->bspi_hw = QSPI_BSPI_MODE_REG_BASE; + priv->mspi_hw = QSPI_MSPI_MODE_REG_BASE; + + /* Initialize clock and platform specific */ + if (plat_spi_init(&max_hz) != 0) + return -1; + + priv->max_hz = max_hz; + + /* MSPI: Basic hardware initialization */ + mmio_write_32(priv->mspi_hw + MSPI_SPCR1_LSB_REG, 0); + mmio_write_32(priv->mspi_hw + MSPI_SPCR1_MSB_REG, 0); + mmio_write_32(priv->mspi_hw + MSPI_NEWQP_REG, 0); + mmio_write_32(priv->mspi_hw + MSPI_ENDQP_REG, 0); + mmio_write_32(priv->mspi_hw + MSPI_SPCR2_REG, 0); + + /* MSPI: SCK configuration */ + spbr = (QSPI_AXI_CLK - 1) / (2 * priv->max_hz) + 1; + spbr = MIN(spbr, SPBR_DIV_MAX); + spbr = MAX(spbr, SPBR_DIV_MIN); + mmio_write_32(priv->mspi_hw + MSPI_SPCR0_LSB_REG, spbr); + + /* MSPI: Mode configuration (8 bits by default) */ + priv->mspi_16bit = 0; + mmio_write_32(priv->mspi_hw + MSPI_SPCR0_MSB_REG, + BIT(MSPI_SPCR0_MSB_REG_MSTR_SHIFT) | /* Master */ + MSPI_SPCR0_MSB_REG_16_BITS_PER_WD_SHIFT | /* 16 bits per word */ + (priv->spi_mode & MSPI_SPCR0_MSB_REG_MODE_MASK)); /* mode: CPOL / CPHA */ + + /* Display bus info */ + VERBOSE("SPI: SPCR0_LSB: 0x%x\n", + mmio_read_32(priv->mspi_hw + MSPI_SPCR0_LSB_REG)); + VERBOSE("SPI: SPCR0_MSB: 0x%x\n", + mmio_read_32(priv->mspi_hw + MSPI_SPCR0_MSB_REG)); + VERBOSE("SPI: SPCR1_LSB: 0x%x\n", + mmio_read_32(priv->mspi_hw + MSPI_SPCR1_LSB_REG)); + VERBOSE("SPI: SPCR1_MSB: 0x%x\n", + mmio_read_32(priv->mspi_hw + MSPI_SPCR1_MSB_REG)); + VERBOSE("SPI: SPCR2: 0x%x\n", + mmio_read_32(priv->mspi_hw + MSPI_SPCR2_REG)); + VERBOSE("SPI: CLK: %d\n", priv->max_hz); + + return 0; +} + +void bcmspi_enable_bspi(struct bcmspi_priv *priv) +{ + if (priv->state != QSPI_STATE_BSPI) { + /* Switch to BSPI */ + mmio_write_32(priv->bspi_hw + BSPI_MAST_N_BOOT_CTRL_REG, 0); + + priv->state = QSPI_STATE_BSPI; + } +} + +static int bcmspi_disable_bspi(struct bcmspi_priv *priv) +{ + uint32_t retry; + + if (priv->state == QSPI_STATE_MSPI) + return 0; + + /* Switch to MSPI if not yet */ + if ((mmio_read_32(priv->bspi_hw + BSPI_MAST_N_BOOT_CTRL_REG) & + MSPI_CTRL_MASK) == 0) { + retry = QSPI_RETRY_COUNT_US_MAX; + do { + if ((mmio_read_32( + priv->bspi_hw + BSPI_BUSY_STATUS_REG) & + BSPI_BUSY_MASK) == 0) { + mmio_write_32(priv->bspi_hw + + BSPI_MAST_N_BOOT_CTRL_REG, + MSPI_CTRL_MASK); + udelay(1); + break; + } + udelay(1); + } while (retry--); + + if ((mmio_read_32(priv->bspi_hw + BSPI_MAST_N_BOOT_CTRL_REG) & + MSPI_CTRL_MASK) != MSPI_CTRL_MASK) { + ERROR("QSPI: Switching to QSPI error.\n"); + return -1; + } + } + + /* Update state */ + priv->state = QSPI_STATE_MSPI; + + return 0; +} + +int iproc_qspi_claim_bus(void) +{ + struct bcmspi_priv *priv = &spi_cfg; + + /* Switch to MSPI by default */ + if (bcmspi_disable_bspi(priv) != 0) + return -1; + + return 0; +} + +void iproc_qspi_release_bus(void) +{ + struct bcmspi_priv *priv = &spi_cfg; + + /* Switch to BSPI by default */ + bcmspi_enable_bspi(priv); +} + +static int mspi_xfer(struct bcmspi_priv *priv, uint32_t bytes, + const uint8_t *tx, uint8_t *rx, uint32_t flag) +{ + uint32_t retry; + uint32_t mode = CDRAM_PCS0; + + if (flag & SPI_XFER_QUAD) { + mode |= CDRAM_QUAD_MODE; + VERBOSE("SPI: QUAD mode\n"); + + if (!tx) { + VERBOSE("SPI: 4 lane input\n"); + mode |= CDRAM_RBIT_INPUT; + } + } + + /* Use 8-bit queue for odd-bytes transfer */ + if (bytes & 1) + priv->mspi_16bit = 0; + else { + priv->mspi_16bit = 1; + mode |= CDRAM_BITS_EN; + } + + while (bytes) { + uint32_t chunk; + uint32_t queues; + uint32_t i; + + /* Separate code for 16bit and 8bit transfers for performance */ + if (priv->mspi_16bit) { + VERBOSE("SPI: 16 bits xfer\n"); + /* Determine how many bytes to process this time */ + chunk = MIN(bytes, NUM_CDRAM_BYTES * 2); + queues = (chunk - 1) / 2 + 1; + bytes -= chunk; + + /* Fill CDRAMs */ + for (i = 0; i < queues; i++) + mmio_write_32(priv->mspi_hw + MSPI_CDRAM_REG + + (i << 2), mode | CDRAM_CONT); + + /* Fill TXRAMs */ + for (i = 0; i < chunk; i++) + if (tx) + mmio_write_32(priv->mspi_hw + + MSPI_TXRAM_REG + + (i << 2), tx[i]); + } else { + VERBOSE("SPI: 8 bits xfer\n"); + /* Determine how many bytes to process this time */ + chunk = MIN(bytes, NUM_CDRAM_BYTES); + queues = chunk; + bytes -= chunk; + + /* Fill CDRAMs and TXRAMS */ + for (i = 0; i < chunk; i++) { + mmio_write_32(priv->mspi_hw + MSPI_CDRAM_REG + + (i << 2), mode | CDRAM_CONT); + if (tx) + mmio_write_32(priv->mspi_hw + + MSPI_TXRAM_REG + + (i << 3), tx[i]); + } + } + + /* Advance pointers */ + if (tx) + tx += chunk; + + /* Setup queue pointers */ + mmio_write_32(priv->mspi_hw + MSPI_NEWQP_REG, 0); + mmio_write_32(priv->mspi_hw + MSPI_ENDQP_REG, queues - 1); + + /* Remove CONT on the last byte command */ + if (bytes == 0 && (flag & SPI_XFER_END)) + mmio_write_32(priv->mspi_hw + MSPI_CDRAM_REG + + ((queues - 1) << 2), mode); + + /* Kick off */ + mmio_write_32(priv->mspi_hw + MSPI_STATUS_REG, 0); + if (bytes == 0 && (flag & SPI_XFER_END)) + mmio_write_32(priv->mspi_hw + MSPI_SPCR2_REG, MSPI_SPE); + else + mmio_write_32(priv->mspi_hw + MSPI_SPCR2_REG, + MSPI_SPE | MSPI_CONT_AFTER_CMD); + + /* Wait for completion */ + retry = QSPI_RETRY_COUNT_US_MAX; + do { + if (mmio_read_32(priv->mspi_hw + MSPI_STATUS_REG) & + MSPI_CMD_COMPLETE_MASK) + break; + udelay(1); + } while (retry--); + + if ((mmio_read_32(priv->mspi_hw + MSPI_STATUS_REG) & + MSPI_CMD_COMPLETE_MASK) == 0) { + ERROR("SPI: Completion timeout.\n"); + return -1; + } + + /* Read data out */ + if (rx) { + if (priv->mspi_16bit) { + for (i = 0; i < chunk; i++) { + rx[i] = mmio_read_32(priv->mspi_hw + + MSPI_RXRAM_REG + + (i << 2)) + & 0xff; + } + } else { + for (i = 0; i < chunk; i++) { + rx[i] = mmio_read_32(priv->mspi_hw + + MSPI_RXRAM_REG + + (((i << 1) + 1) << 2)) + & 0xff; + } + } + rx += chunk; + } + } + + return 0; +} + +int iproc_qspi_xfer(uint32_t bitlen, + const void *dout, void *din, unsigned long flags) +{ + struct bcmspi_priv *priv; + const uint8_t *tx = dout; + uint8_t *rx = din; + uint32_t bytes = bitlen / 8; + int ret = 0; + + priv = &spi_cfg; + + if (priv->state == QSPI_STATE_DISABLED) { + ERROR("QSPI: state disabled\n"); + return -1; + } + + /* we can only do 8 bit transfers */ + if (bitlen % 8) { + ERROR("QSPI: Only support 8 bit transfers (requested %d)\n", + bitlen); + return -1; + } + + /* MSPI: Enable write lock at the beginning */ + if (flags & SPI_XFER_BEGIN) { + /* Switch to MSPI if not yet */ + if (bcmspi_disable_bspi(priv) != 0) { + ERROR("QSPI: Switch to MSPI failed\n"); + return -1; + } + + mmio_write_32(priv->mspi_hw + MSPI_WRITE_LOCK_REG, 1); + } + + /* MSPI: Transfer it */ + if (bytes) + ret = mspi_xfer(priv, bytes, tx, rx, flags); + + /* MSPI: Disable write lock if it's done */ + if (flags & SPI_XFER_END) + mmio_write_32(priv->mspi_hw + MSPI_WRITE_LOCK_REG, 0); + + return ret; +} diff --git a/drivers/brcm/spi/iproc_qspi.h b/drivers/brcm/spi/iproc_qspi.h new file mode 100644 index 000000000..7a8bd91f7 --- /dev/null +++ b/drivers/brcm/spi/iproc_qspi.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2017 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef IPROC_QSPI_H +#define IPROC_QSPI_H + +#include + +/*SPI configuration enable*/ +#define IPROC_QSPI_CLK_SPEED 62500000 +#define SPI_CPHA (1 << 0) +#define SPI_CPOL (1 << 1) +#define IPROC_QSPI_MODE0 0 +#define IPROC_QSPI_MODE3 (SPI_CPOL|SPI_CPHA) + +#define IPROC_QSPI_BUS 0 +#define IPROC_QSPI_CS 0 +#define IPROC_QSPI_BASE_REG QSPI_CTRL_BASE_ADDR +#define IPROC_QSPI_CRU_CONTROL_REG QSPI_CLK_CTRL + +#define QSPI_AXI_CLK 200000000 + +#define QSPI_RETRY_COUNT_US_MAX 200000 + +/* Chip attributes */ +#define QSPI_REG_BASE IPROC_QSPI_BASE_REG +#define CRU_CONTROL_REG IPROC_QSPI_CRU_CONTROL_REG +#define SPBR_DIV_MIN 8U +#define SPBR_DIV_MAX 255U +#define NUM_CDRAM_BYTES 16U + +/* Register fields */ +#define MSPI_SPCR0_MSB_BITS_8 0x00000020 + +/* Flash opcode and parameters */ +#define CDRAM_PCS0 2 +#define CDRAM_CONT (1 << 7) +#define CDRAM_BITS_EN (1 << 6) +#define CDRAM_QUAD_MODE (1 << 8) +#define CDRAM_RBIT_INPUT (1 << 10) + +/* MSPI registers */ +#define QSPI_MSPI_MODE_REG_BASE (QSPI_REG_BASE + 0x200) +#define MSPI_SPCR0_LSB_REG 0x000 +#define MSPI_SPCR0_MSB_REG 0x004 +#define MSPI_SPCR1_LSB_REG 0x008 +#define MSPI_SPCR1_MSB_REG 0x00c +#define MSPI_NEWQP_REG 0x010 +#define MSPI_ENDQP_REG 0x014 +#define MSPI_SPCR2_REG 0x018 +#define MSPI_STATUS_REG 0x020 +#define MSPI_CPTQP_REG 0x024 +#define MSPI_TXRAM_REG 0x040 +#define MSPI_RXRAM_REG 0x0c0 +#define MSPI_CDRAM_REG 0x140 +#define MSPI_WRITE_LOCK_REG 0x180 +#define MSPI_DISABLE_FLUSH_GEN_REG 0x184 + +#define MSPI_SPCR0_MSB_REG_MSTR_SHIFT 7 +#define MSPI_SPCR0_MSB_REG_16_BITS_PER_WD_SHIFT (0 << 2) +#define MSPI_SPCR0_MSB_REG_MODE_MASK 0x3 + +/* BSPI registers */ +#define QSPI_BSPI_MODE_REG_BASE QSPI_REG_BASE +#define BSPI_MAST_N_BOOT_CTRL_REG 0x008 +#define BSPI_BUSY_STATUS_REG 0x00c + +#define MSPI_CMD_COMPLETE_MASK 1 +#define BSPI_BUSY_MASK 1 +#define MSPI_CTRL_MASK 1 + +#define MSPI_SPE (1 << 6) +#define MSPI_CONT_AFTER_CMD (1 << 7) + +/* State */ +enum bcm_qspi_state { + QSPI_STATE_DISABLED, + QSPI_STATE_MSPI, + QSPI_STATE_BSPI +}; + +/* QSPI private data */ +struct bcmspi_priv { + /* Specified SPI parameters */ + uint32_t max_hz; + uint32_t spi_mode; + + /* State */ + enum bcm_qspi_state state; + int mspi_16bit; + + /* Registers */ + uintptr_t mspi_hw; + uintptr_t bspi_hw; +}; + +int iproc_qspi_setup(uint32_t bus, uint32_t cs, + uint32_t max_hz, uint32_t mode); +int iproc_qspi_claim_bus(void); +void iproc_qspi_release_bus(void); +int iproc_qspi_xfer(uint32_t bitlen, const void *dout, + void *din, unsigned long flags); + +#endif /* _IPROC_QSPI_H_ */ diff --git a/drivers/brcm/spi/iproc_spi.c b/drivers/brcm/spi/iproc_spi.c new file mode 100644 index 000000000..551e58732 --- /dev/null +++ b/drivers/brcm/spi/iproc_spi.c @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2017 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include "iproc_qspi.h" + +int spi_init(void) +{ + return iproc_qspi_setup(IPROC_QSPI_BUS, IPROC_QSPI_CS, + IPROC_QSPI_CLK_SPEED, IPROC_QSPI_MODE0); +} + +int spi_claim_bus(void) +{ + return iproc_qspi_claim_bus(); +} + +void spi_release_bus(void) +{ + iproc_qspi_release_bus(); +} + +int spi_xfer(uint32_t bitlen, const void *dout, + void *din, uint32_t flags) +{ + return iproc_qspi_xfer(bitlen, dout, din, flags); +} diff --git a/include/drivers/brcm/spi.h b/include/drivers/brcm/spi.h new file mode 100644 index 000000000..9d92d8cfc --- /dev/null +++ b/include/drivers/brcm/spi.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2017 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SPI_H +#define SPI_H + +#include + +#define SPI_XFER_BEGIN (1 << 0) /* Assert CS before transfer */ +#define SPI_XFER_END (1 << 1) /* De-assert CS after transfer */ +#define SPI_XFER_QUAD (1 << 2) + +int spi_init(void); +int spi_claim_bus(void); +void spi_release_bus(void); +int spi_xfer(uint32_t bitlen, const void *dout, void *din, uint32_t flags); + +#endif /* _SPI_H_ */ diff --git a/plat/brcm/board/common/board_common.mk b/plat/brcm/board/common/board_common.mk index 2a7ebdf66..bc7f5c6f7 100644 --- a/plat/brcm/board/common/board_common.mk +++ b/plat/brcm/board/common/board_common.mk @@ -32,6 +32,10 @@ ifeq (${DRIVER_EMMC_ENABLE},) DRIVER_EMMC_ENABLE :=1 endif +ifeq (${DRIVER_SPI_ENABLE},) +DRIVER_SPI_ENABLE := 0 +endif + # By default, Trusted Watchdog is always enabled unless SPIN_ON_BL1_EXIT is set ifeq (${BRCM_DISABLE_TRUSTED_WDOG},) BRCM_DISABLE_TRUSTED_WDOG := 0 @@ -159,6 +163,12 @@ BL2_SOURCES += ${ELOG_SOURCES} BL31_SOURCES += ${ELOG_SOURCES} endif +# Add spi driver +ifeq (${DRIVER_SPI_ENABLE},1) +PLAT_BL_COMMON_SOURCES += drivers/brcm/spi/iproc_spi.c \ + drivers/brcm/spi/iproc_qspi.c +endif + ifeq (${DRIVER_OCOTP_ENABLE},1) $(eval $(call add_define,DRIVER_OCOTP_ENABLE)) BL2_SOURCES += drivers/brcm/ocotp.c diff --git a/plat/brcm/board/stingray/platform.mk b/plat/brcm/board/stingray/platform.mk index 8d2119d24..20ebcddc3 100644 --- a/plat/brcm/board/stingray/platform.mk +++ b/plat/brcm/board/stingray/platform.mk @@ -172,6 +172,10 @@ $(eval $(call add_define,CONFIG_SOFT_RESET_L3)) # Enable Chip OTP driver DRIVER_OCOTP_ENABLE := 1 +ifneq (${WARMBOOT_DDR_S3_SUPPORT},) +DRIVER_SPI_ENABLE := 1 +endif + include plat/brcm/board/common/board_common.mk SOC_DIR := brcm/board/stingray -- cgit v1.2.3 From 49dec7f7f2ce911dfa3c57a54d5b21bd061d67ee Mon Sep 17 00:00:00 2001 From: Sheetal Tigadoli Date: Mon, 6 Jan 2020 00:08:24 +0530 Subject: drivers: Add SPI Nor flash support Add SPI Nor flash support Change-Id: I0cde3fdb4dcad5bcaf445b3bb48e279332bd28af Signed-off-by: Sheetal Tigadoli --- drivers/brcm/spi_flash.c | 308 +++++++++++++++++++++++++++++++++ drivers/brcm/spi_sf.c | 60 +++++++ include/drivers/brcm/sf.h | 90 ++++++++++ include/drivers/brcm/spi_flash.h | 18 ++ plat/brcm/board/common/board_common.mk | 6 + 5 files changed, 482 insertions(+) create mode 100644 drivers/brcm/spi_flash.c create mode 100644 drivers/brcm/spi_sf.c create mode 100644 include/drivers/brcm/sf.h create mode 100644 include/drivers/brcm/spi_flash.h diff --git a/drivers/brcm/spi_flash.c b/drivers/brcm/spi_flash.c new file mode 100644 index 000000000..336d2304b --- /dev/null +++ b/drivers/brcm/spi_flash.c @@ -0,0 +1,308 @@ +/* + * Copyright (c) 2019-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#define SPI_FLASH_CMD_LEN 4 +#define QSPI_WAIT_TIMEOUT_US 200000U /* usec */ + +#define FINFO(jedec_id, ext_id, _sector_size, _n_sectors, _page_size, _flags) \ + .id = { \ + ((jedec_id) >> 16) & 0xff, \ + ((jedec_id) >> 8) & 0xff, \ + (jedec_id) & 0xff, \ + ((ext_id) >> 8) & 0xff, \ + (ext_id) & 0xff, \ + }, \ + .id_len = (!(jedec_id) ? 0 : (3 + ((ext_id) ? 2 : 0))), \ + .sector_size = (_sector_size), \ + .n_sectors = (_n_sectors), \ + .page_size = _page_size, \ + .flags = (_flags), + +/* SPI/QSPI flash device params structure */ +const struct spi_flash_info spi_flash_ids[] = { + {"W25Q64CV", FINFO(0xef4017, 0x0, 64 * 1024, 128, 256, WR_QPP | SECT_4K)}, + {"W25Q64DW", FINFO(0xef6017, 0x0, 64 * 1024, 128, 256, WR_QPP | SECT_4K)}, + {"W25Q32", FINFO(0xef4016, 0x0, 64 * 1024, 64, 256, SECT_4K)}, + {"MX25l3205D", FINFO(0xc22016, 0x0, 64 * 1024, 64, 256, SECT_4K)}, +}; + +static void spi_flash_addr(uint32_t addr, uint8_t *cmd) +{ + /* + * cmd[0] holds a SPI Flash command, stored earlier + * cmd[1/2/3] holds 24bit flash address + */ + cmd[1] = addr >> 16; + cmd[2] = addr >> 8; + cmd[3] = addr >> 0; +} + +static const struct spi_flash_info *spi_flash_read_id(void) +{ + const struct spi_flash_info *info; + uint8_t id[SPI_FLASH_MAX_ID_LEN]; + int ret; + + ret = spi_flash_cmd(CMD_READ_ID, id, SPI_FLASH_MAX_ID_LEN); + if (ret < 0) { + ERROR("SF: Error %d reading JEDEC ID\n", ret); + return NULL; + } + + for (info = spi_flash_ids; info->name != NULL; info++) { + if (info->id_len) { + if (!memcmp(info->id, id, info->id_len)) + return info; + } + } + + printf("SF: unrecognized JEDEC id bytes: %02x, %02x, %02x\n", + id[0], id[1], id[2]); + return NULL; +} + +/* Enable writing on the SPI flash */ +static inline int spi_flash_cmd_write_enable(struct spi_flash *flash) +{ + return spi_flash_cmd(CMD_WRITE_ENABLE, NULL, 0); +} + +static int spi_flash_cmd_wait(struct spi_flash *flash) +{ + uint8_t cmd; + uint32_t i; + uint8_t status; + int ret; + + i = 0; + while (1) { + cmd = CMD_RDSR; + ret = spi_flash_cmd_read(&cmd, 1, &status, 1); + if (ret < 0) { + ERROR("SF: cmd wait failed\n"); + break; + } + if (!(status & STATUS_WIP)) + break; + + i++; + if (i >= QSPI_WAIT_TIMEOUT_US) { + ERROR("SF: cmd wait timeout\n"); + ret = -1; + break; + } + udelay(1); + } + + return ret; +} + +static int spi_flash_write_common(struct spi_flash *flash, const uint8_t *cmd, + size_t cmd_len, const void *buf, + size_t buf_len) +{ + int ret; + + ret = spi_flash_cmd_write_enable(flash); + if (ret < 0) { + ERROR("SF: enabling write failed\n"); + return ret; + } + + ret = spi_flash_cmd_write(cmd, cmd_len, buf, buf_len); + if (ret < 0) { + ERROR("SF: write cmd failed\n"); + return ret; + } + + ret = spi_flash_cmd_wait(flash); + if (ret < 0) { + ERROR("SF: write timed out\n"); + return ret; + } + + return ret; +} + +static int spi_flash_read_common(const uint8_t *cmd, size_t cmd_len, + void *data, size_t data_len) +{ + int ret; + + ret = spi_flash_cmd_read(cmd, cmd_len, data, data_len); + if (ret < 0) { + ERROR("SF: read cmd failed\n"); + return ret; + } + + return ret; +} + +int spi_flash_read(struct spi_flash *flash, uint32_t offset, + uint32_t len, void *data) +{ + uint32_t read_len = 0, read_addr; + uint8_t cmd[SPI_FLASH_CMD_LEN]; + int ret; + + ret = spi_claim_bus(); + if (ret) { + ERROR("SF: unable to claim SPI bus\n"); + return ret; + } + + cmd[0] = CMD_READ_NORMAL; + while (len) { + read_addr = offset; + read_len = MIN(flash->page_size, (len - read_len)); + spi_flash_addr(read_addr, cmd); + + ret = spi_flash_read_common(cmd, sizeof(cmd), data, read_len); + if (ret < 0) { + ERROR("SF: read failed\n"); + break; + } + + offset += read_len; + len -= read_len; + data += read_len; + } + SPI_DEBUG("SF read done\n"); + + spi_release_bus(); + return ret; +} + +int spi_flash_write(struct spi_flash *flash, uint32_t offset, + uint32_t len, void *buf) +{ + unsigned long byte_addr, page_size; + uint8_t cmd[SPI_FLASH_CMD_LEN]; + uint32_t chunk_len, actual; + uint32_t write_addr; + int ret; + + ret = spi_claim_bus(); + if (ret) { + ERROR("SF: unable to claim SPI bus\n"); + return ret; + } + + page_size = flash->page_size; + + cmd[0] = flash->write_cmd; + for (actual = 0; actual < len; actual += chunk_len) { + write_addr = offset; + byte_addr = offset % page_size; + chunk_len = MIN(len - actual, + (uint32_t)(page_size - byte_addr)); + spi_flash_addr(write_addr, cmd); + + SPI_DEBUG("SF:0x%p=>cmd:{0x%02x 0x%02x%02x%02x} chunk_len:%d\n", + buf + actual, cmd[0], cmd[1], + cmd[2], cmd[3], chunk_len); + + ret = spi_flash_write_common(flash, cmd, sizeof(cmd), + buf + actual, chunk_len); + if (ret < 0) { + ERROR("SF: write cmd failed\n"); + break; + } + + offset += chunk_len; + } + SPI_DEBUG("SF write done\n"); + + spi_release_bus(); + return ret; +} + +int spi_flash_erase(struct spi_flash *flash, uint32_t offset, uint32_t len) +{ + uint8_t cmd[SPI_FLASH_CMD_LEN]; + uint32_t erase_size, erase_addr; + int ret; + + erase_size = flash->erase_size; + + if (offset % erase_size || len % erase_size) { + ERROR("SF: Erase offset/length not multiple of erase size\n"); + return -1; + } + + ret = spi_claim_bus(); + if (ret) { + ERROR("SF: unable to claim SPI bus\n"); + return ret; + } + + cmd[0] = flash->erase_cmd; + while (len) { + erase_addr = offset; + spi_flash_addr(erase_addr, cmd); + + SPI_DEBUG("SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1], + cmd[2], cmd[3], erase_addr); + + ret = spi_flash_write_common(flash, cmd, sizeof(cmd), NULL, 0); + if (ret < 0) { + ERROR("SF: erase failed\n"); + break; + } + + offset += erase_size; + len -= erase_size; + } + SPI_DEBUG("sf erase done\n"); + + spi_release_bus(); + return ret; +} + +int spi_flash_probe(struct spi_flash *flash) +{ + const struct spi_flash_info *info = NULL; + int ret; + + ret = spi_claim_bus(); + if (ret) { + ERROR("SF: Unable to claim SPI bus\n"); + ERROR("SF: probe failed\n"); + return ret; + } + + info = spi_flash_read_id(); + if (!info) + goto probe_fail; + + INFO("Flash Name: %s sectors %x, sec size %x\n", + info->name, info->n_sectors, + info->sector_size); + flash->size = info->n_sectors * info->sector_size; + flash->sector_size = info->sector_size; + flash->page_size = info->page_size; + flash->flags = info->flags; + + flash->read_cmd = CMD_READ_NORMAL; + flash->write_cmd = CMD_PAGE_PROGRAM; + flash->erase_cmd = CMD_ERASE_64K; + flash->erase_size = ERASE_SIZE_64K; + +probe_fail: + spi_release_bus(); + return ret; +} diff --git a/drivers/brcm/spi_sf.c b/drivers/brcm/spi_sf.c new file mode 100644 index 000000000..8bbb09fac --- /dev/null +++ b/drivers/brcm/spi_sf.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2019-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include + +#define BITS_PER_BYTE 8 +#define CMD_LEN1 1 + +static int spi_flash_read_write(const uint8_t *cmd, + size_t cmd_len, + const uint8_t *data_out, + uint8_t *data_in, + size_t data_len) +{ + unsigned long flags = SPI_XFER_BEGIN; + int ret; + + if (data_len == 0) + flags |= SPI_XFER_END; + + ret = spi_xfer(cmd_len * BITS_PER_BYTE, cmd, NULL, flags); + if (ret) { + ERROR("SF: Failed to send command (%zu bytes): %d\n", + cmd_len, ret); + } else if (data_len != 0) { + ret = spi_xfer(data_len * BITS_PER_BYTE, data_out, + data_in, SPI_XFER_END); + if (ret) + ERROR("SF: Failed to transfer %zu bytes of data: %d\n", + data_len, ret); + } + + return ret; +} + +int spi_flash_cmd_read(const uint8_t *cmd, + size_t cmd_len, + void *data, + size_t data_len) +{ + return spi_flash_read_write(cmd, cmd_len, NULL, data, data_len); +} + +int spi_flash_cmd(uint8_t cmd, void *response, size_t len) +{ + return spi_flash_cmd_read(&cmd, CMD_LEN1, response, len); +} + +int spi_flash_cmd_write(const uint8_t *cmd, + size_t cmd_len, + const void *data, + size_t data_len) +{ + return spi_flash_read_write(cmd, cmd_len, data, NULL, data_len); +} diff --git a/include/drivers/brcm/sf.h b/include/drivers/brcm/sf.h new file mode 100644 index 000000000..c32cbebf9 --- /dev/null +++ b/include/drivers/brcm/sf.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2019-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SF_H +#define SF_H + +#include +#include + +#ifdef SPI_DEBUG +#define SPI_DEBUG(fmt, ...) INFO(fmt, ##__VA_ARGS__) +#else +#define SPI_DEBUG(fmt, ...) +#endif + +#define SPI_FLASH_MAX_ID_LEN 6 + +#define CMD_WRSR 0x01 /* Write status register */ +#define CMD_PAGE_PROGRAM 0x02 +#define CMD_READ_NORMAL 0x03 +#define CMD_RDSR 0x05 +#define CMD_WRITE_ENABLE 0x06 +#define CMD_RDFSR 0x70 +#define CMD_READ_ID 0x9f +#define CMD_ERASE_4K 0x20 +#define CMD_ERASE_64K 0xd8 +#define ERASE_SIZE_64K (64 * 1024) + +/* Common status */ +#define STATUS_WIP BIT(0) + +struct spi_flash { + struct spi_slave *spi; + uint32_t size; + uint32_t page_size; + uint32_t sector_size; + uint32_t erase_size; + uint8_t erase_cmd; + uint8_t read_cmd; + uint8_t write_cmd; + uint8_t flags; +}; + +struct spi_flash_info { + const char *name; + + /* + * This array stores the ID bytes. + * The first three bytes are the JEDIC ID. + * JEDEC ID zero means "no ID" (mostly older chips). + */ + uint8_t id[SPI_FLASH_MAX_ID_LEN]; + uint8_t id_len; + + uint32_t sector_size; + uint32_t n_sectors; + uint16_t page_size; + + uint8_t flags; +}; + +/* Enum list - Full read commands */ +enum spi_read_cmds { + ARRAY_SLOW = BIT(0), + ARRAY_FAST = BIT(1), + DUAL_OUTPUT_FAST = BIT(2), + DUAL_IO_FAST = BIT(3), + QUAD_OUTPUT_FAST = BIT(4), + QUAD_IO_FAST = BIT(5), +}; + +/* sf param flags */ +enum spi_param_flag { + SECT_4K = BIT(0), + SECT_32K = BIT(1), + E_FSR = BIT(2), + SST_BP = BIT(3), + SST_WP = BIT(4), + WR_QPP = BIT(5), +}; + +int spi_flash_cmd_read(const uint8_t *cmd, size_t cmd_len, + void *data, size_t data_len); +int spi_flash_cmd(uint8_t cmd, void *response, size_t len); +int spi_flash_cmd_write(const uint8_t *cmd, size_t cmd_len, + const void *data, size_t data_len); +#endif diff --git a/include/drivers/brcm/spi_flash.h b/include/drivers/brcm/spi_flash.h new file mode 100644 index 000000000..bbaaa5088 --- /dev/null +++ b/include/drivers/brcm/spi_flash.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2019-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SPI_FLASH_H +#define SPI_FLASH_H + +#include + +int spi_flash_probe(struct spi_flash *flash); +int spi_flash_erase(struct spi_flash *flash, uint32_t offset, uint32_t len); +int spi_flash_write(struct spi_flash *flash, uint32_t offset, + uint32_t len, void *buf); +int spi_flash_read(struct spi_flash *flash, uint32_t offset, + uint32_t len, void *data); +#endif /* _SPI_FLASH_H_ */ diff --git a/plat/brcm/board/common/board_common.mk b/plat/brcm/board/common/board_common.mk index bc7f5c6f7..1795ce7f6 100644 --- a/plat/brcm/board/common/board_common.mk +++ b/plat/brcm/board/common/board_common.mk @@ -169,6 +169,12 @@ PLAT_BL_COMMON_SOURCES += drivers/brcm/spi/iproc_spi.c \ drivers/brcm/spi/iproc_qspi.c endif +# Add spi nor/flash driver +ifeq (${DRIVER_SPI_NOR_ENABLE},1) +PLAT_BL_COMMON_SOURCES += drivers/brcm/spi_sf.c \ + drivers/brcm/spi_flash.c +endif + ifeq (${DRIVER_OCOTP_ENABLE},1) $(eval $(call add_define,DRIVER_OCOTP_ENABLE)) BL2_SOURCES += drivers/brcm/ocotp.c -- cgit v1.2.3 From fd1017b121f7be9434bbdcb33177bf9311bf5d82 Mon Sep 17 00:00:00 2001 From: Sheetal Tigadoli Date: Sat, 21 Mar 2020 00:12:50 +0530 Subject: doc: brcm: Add documentation file for brcm stingray platform Signed-off-by: Sheetal Tigadoli Change-Id: I5e2c1220e9694d6ba771cc90daa0e70e967eebe6 --- docs/plat/brcm-stingray.rst | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 docs/plat/brcm-stingray.rst diff --git a/docs/plat/brcm-stingray.rst b/docs/plat/brcm-stingray.rst new file mode 100644 index 000000000..c43c8504c --- /dev/null +++ b/docs/plat/brcm-stingray.rst @@ -0,0 +1,40 @@ +Description +=========== +Broadcom's Stingray(BCM958742t) is a multi-core processor with 8 Cortex-A72 cores. +Trusted Firmware-A (TF-A) is used to implement secure world firmware, supporting +BL2 and BL31 for Broadcom Stingray SoCs + +On Poweron, Boot ROM will load bl2 image and Bl2 will initialize the hardware, +then loads bl31 and bl33 into DDR and boots to bl33. + +Boot Sequence +============= + +Bootrom --> TF-A BL2 --> TF-A BL31 --> BL33(u-boot) + +Code Locations +-------------- +- Trusted Firmware-A: + `link `__ + +How to build +============ + +Build Procedure +--------------- + +- Prepare AARCH64 toolchain. + +- Build u-boot first, and get the binary image: u-boot.bin, + +- Build TF-A + + Build fip: + + .. code::shell + + make CROSS_COMPILE=aarch64-linux-gnu- PLAT=stingray BOARD_CFG=bcm958742t all fip BL33=u-boot.bin + +Deploy TF-A Images +----------------- +The u-boot will be upstreamed soon, this doc will be updated once they are ready, and the link will be posted. -- cgit v1.2.3 From 06aca857f4a8ceae4f2ec126b8a9892b82077415 Mon Sep 17 00:00:00 2001 From: Pramod Kumar Date: Wed, 19 Feb 2020 10:39:10 +0530 Subject: xlat lib v2: Add support to pass shareability attribute for normal memory region Present framework restricts platform to pass desired shareability attribute for normal memory region mapped in MMU. it defaults to inner shareability. There are platforms where memories (like SRAM) are not placed at snoopable region in advaned interconnect like CCN/CMN hence snoopable transaction is not possible to these memory. Though These memories could be mapped in MMU as MT_NON_CACHEABLE, data caches benefits won't be available. If these memories are mapped as cacheable with non-shareable attribute, when only one core is running like at boot time, MMU data cached could be used for faster execution. Hence adding support to pass the shareability attribute for memory regions. Signed-off-by: Pramod Kumar Change-Id: I678cb50120a28dae4aa9d1896e8faf1dd5cf1754 --- include/lib/xlat_tables/xlat_tables_v2.h | 17 +++++++++++++++++ lib/xlat_tables_v2/xlat_tables_core.c | 11 ++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/include/lib/xlat_tables/xlat_tables_v2.h b/include/lib/xlat_tables/xlat_tables_v2.h index 9fe4a6e8a..8eb84a892 100644 --- a/include/lib/xlat_tables/xlat_tables_v2.h +++ b/include/lib/xlat_tables/xlat_tables_v2.h @@ -66,6 +66,11 @@ #define MT_EXECUTE_SHIFT U(5) /* In the EL1&0 translation regime, User (EL0) or Privileged (EL1). */ #define MT_USER_SHIFT U(6) + +/* Shareability attribute for the memory region */ +#define MT_SHAREABILITY_SHIFT U(7) +#define MT_SHAREABILITY_MASK (U(3) << MT_SHAREABILITY_SHIFT) +#define MT_SHAREABILITY(_attr) ((_attr) & MT_SHAREABILITY_MASK) /* All other bits are reserved */ /* @@ -106,6 +111,18 @@ #define MT_USER (U(1) << MT_USER_SHIFT) #define MT_PRIVILEGED (U(0) << MT_USER_SHIFT) +/* + * Shareability defines the visibility of any cache changes to + * all masters belonging to a shareable domain. + * + * MT_SHAREABILITY_ISH: For inner shareable domain + * MT_SHAREABILITY_OSH: For outer shareable domain + * MT_SHAREABILITY_NSH: For non shareable domain + */ +#define MT_SHAREABILITY_ISH (U(1) << MT_SHAREABILITY_SHIFT) +#define MT_SHAREABILITY_OSH (U(2) << MT_SHAREABILITY_SHIFT) +#define MT_SHAREABILITY_NSH (U(3) << MT_SHAREABILITY_SHIFT) + /* Compound attributes for most common usages */ #define MT_CODE (MT_MEMORY | MT_RO | MT_EXECUTE) #define MT_RO_DATA (MT_MEMORY | MT_RO | MT_EXECUTE_NEVER) diff --git a/lib/xlat_tables_v2/xlat_tables_core.c b/lib/xlat_tables_v2/xlat_tables_core.c index b2259e5f3..bb6d18459 100644 --- a/lib/xlat_tables_v2/xlat_tables_core.c +++ b/lib/xlat_tables_v2/xlat_tables_core.c @@ -109,6 +109,7 @@ uint64_t xlat_desc(const xlat_ctx_t *ctx, uint32_t attr, { uint64_t desc; uint32_t mem_type; + uint32_t shareability_type; /* Make sure that the granularity is fine enough to map this address. */ assert((addr_pa & XLAT_BLOCK_MASK(level)) == 0U); @@ -194,8 +195,16 @@ uint64_t xlat_desc(const xlat_ctx_t *ctx, uint32_t attr, desc |= xlat_arch_regime_get_xn_desc(ctx->xlat_regime); } + shareability_type = MT_SHAREABILITY(attr); if (mem_type == MT_MEMORY) { - desc |= LOWER_ATTRS(ATTR_IWBWA_OWBWA_NTR_INDEX | ISH); + desc |= LOWER_ATTRS(ATTR_IWBWA_OWBWA_NTR_INDEX); + if (shareability_type == MT_SHAREABILITY_NSH) { + desc |= LOWER_ATTRS(NSH); + } else if (shareability_type == MT_SHAREABILITY_OSH) { + desc |= LOWER_ATTRS(OSH); + } else { + desc |= LOWER_ATTRS(ISH); + } /* Check if Branch Target Identification is enabled */ #if ENABLE_BTI -- cgit v1.2.3 From 3e588036469d213245ee3de59c8baf1cca1dc0f5 Mon Sep 17 00:00:00 2001 From: Manish Pandey Date: Fri, 3 Apr 2020 18:59:20 +0100 Subject: arm_fpga: adapt to new way of including gicv3 files with commit a6ea06f5, the way platform includes gicv3 files has been modified, this patch adapts to new method of including gicv3 files for arm_fpga platform. Signed-off-by: Manish Pandey Change-Id: Ic5ccae842b39b7db06d4f23c5738b174c42edf63 --- plat/arm/board/arm_fpga/platform.mk | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk index b4f38fab4..302aabf38 100644 --- a/plat/arm/board/arm_fpga/platform.mk +++ b/plat/arm/board/arm_fpga/platform.mk @@ -66,12 +66,13 @@ else lib/cpus/aarch64/cortex_a75.S endif -FPGA_GIC_SOURCES := drivers/arm/gic/v3/gicv3_helpers.c \ - drivers/arm/gic/v3/gicdv3_helpers.c \ - drivers/arm/gic/v3/gicrv3_helpers.c \ - drivers/arm/gic/v3/gicv3_main.c \ - drivers/arm/gic/v3/gic600.c \ - drivers/arm/gic/common/gic_common.c \ +# GIC-600 configuration +GICV3_IMPL := GIC600 + +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk + +FPGA_GIC_SOURCES := ${GICV3_SOURCES} \ plat/common/plat_gicv3.c \ plat/arm/board/arm_fpga/fpga_gicv3.c -- cgit v1.2.3 From 3443a7027d78a9ccebc6940f0a69300ec7c1ed44 Mon Sep 17 00:00:00 2001 From: John Powell Date: Fri, 20 Mar 2020 14:21:05 -0500 Subject: Fix MISRA C issues in BL1/BL2/BL31 Attempts to address MISRA compliance issues in BL1, BL2, and BL31 code. Mainly issues like not using boolean expressions in conditionals, conflicting variable names, ignoring return values without (void), adding explicit casts, etc. Change-Id: If1fa18ab621b9c374db73fa6eaa6f6e5e55c146a Signed-off-by: John Powell --- bl1/aarch32/bl1_context_mgmt.c | 20 ++-- bl1/aarch64/bl1_context_mgmt.c | 12 +-- bl1/bl1_fwu.c | 201 +++++++++++++++++++++-------------------- bl1/bl1_main.c | 33 +++---- bl2/bl2_image_load_v2.c | 14 +-- bl2u/bl2u_main.c | 4 +- include/arch/aarch32/arch.h | 20 ++-- include/arch/aarch64/arch.h | 4 +- include/lib/smccc.h | 22 ++--- include/lib/utils_def.h | 4 +- 10 files changed, 172 insertions(+), 162 deletions(-) diff --git a/bl1/aarch32/bl1_context_mgmt.c b/bl1/aarch32/bl1_context_mgmt.c index b5a6a3417..85d35a72b 100644 --- a/bl1/aarch32/bl1_context_mgmt.c +++ b/bl1/aarch32/bl1_context_mgmt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -53,10 +53,10 @@ void *cm_get_context(uint32_t security_state) return &bl1_cpu_context[security_state]; } -void cm_set_next_context(void *cpu_context) +void cm_set_next_context(void *context) { - assert(cpu_context); - bl1_next_cpu_context_ptr = cpu_context; + assert(context != NULL); + bl1_next_cpu_context_ptr = context; } void *cm_get_next_context(void) @@ -103,21 +103,21 @@ static void flush_smc_and_cpu_ctx(void) void bl1_prepare_next_image(unsigned int image_id) { unsigned int security_state, mode = MODE32_svc; - image_desc_t *image_desc; + image_desc_t *desc; entry_point_info_t *next_bl_ep; /* Get the image descriptor. */ - image_desc = bl1_plat_get_image_desc(image_id); - assert(image_desc); + desc = bl1_plat_get_image_desc(image_id); + assert(desc != NULL); /* Get the entry point info. */ - next_bl_ep = &image_desc->ep_info; + next_bl_ep = &desc->ep_info; /* Get the image security state. */ security_state = GET_SECURITY_STATE(next_bl_ep->h.attr); /* Prepare the SPSR for the next BL image. */ - if ((security_state != SECURE) && (GET_VIRT_EXT(read_id_pfr1()))) { + if ((security_state != SECURE) && (GET_VIRT_EXT(read_id_pfr1()) != 0U)) { mode = MODE32_hyp; } @@ -166,7 +166,7 @@ void bl1_prepare_next_image(unsigned int image_id) flush_smc_and_cpu_ctx(); /* Indicate that image is in execution state. */ - image_desc->state = IMAGE_STATE_EXECUTED; + desc->state = IMAGE_STATE_EXECUTED; print_entry_point_info(next_bl_ep); } diff --git a/bl1/aarch64/bl1_context_mgmt.c b/bl1/aarch64/bl1_context_mgmt.c index 210c35842..fec513db8 100644 --- a/bl1/aarch64/bl1_context_mgmt.c +++ b/bl1/aarch64/bl1_context_mgmt.c @@ -43,7 +43,7 @@ void cm_set_context(void *context, uint32_t security_state) void bl1_prepare_next_image(unsigned int image_id) { unsigned int security_state, mode = MODE_EL1; - image_desc_t *image_desc; + image_desc_t *desc; entry_point_info_t *next_bl_ep; #if CTX_INCLUDE_AARCH32_REGS @@ -59,11 +59,11 @@ void bl1_prepare_next_image(unsigned int image_id) #endif /* Get the image descriptor. */ - image_desc = bl1_plat_get_image_desc(image_id); - assert(image_desc); + desc = bl1_plat_get_image_desc(image_id); + assert(desc != NULL); /* Get the entry point info. */ - next_bl_ep = &image_desc->ep_info; + next_bl_ep = &desc->ep_info; /* Get the image security state. */ security_state = GET_SECURITY_STATE(next_bl_ep->h.attr); @@ -77,7 +77,7 @@ void bl1_prepare_next_image(unsigned int image_id) mode = MODE_EL2; } - next_bl_ep->spsr = SPSR_64(mode, MODE_SP_ELX, + next_bl_ep->spsr = (uint32_t)SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); /* Allow platform to make change */ @@ -88,7 +88,7 @@ void bl1_prepare_next_image(unsigned int image_id) cm_prepare_el3_exit(security_state); /* Indicate that image is in execution state. */ - image_desc->state = IMAGE_STATE_EXECUTED; + desc->state = IMAGE_STATE_EXECUTED; print_entry_point_info(next_bl_ep); } diff --git a/bl1/bl1_fwu.c b/bl1/bl1_fwu.c index 42a3ded5b..b70bffd91 100644 --- a/bl1/bl1_fwu.c +++ b/bl1/bl1_fwu.c @@ -67,28 +67,32 @@ u_register_t bl1_fwu_smc_handler(unsigned int smc_fid, switch (smc_fid) { case FWU_SMC_IMAGE_COPY: - SMC_RET1(handle, bl1_fwu_image_copy(x1, x2, x3, x4, flags)); + SMC_RET1(handle, bl1_fwu_image_copy((uint32_t)x1, x2, + (uint32_t)x3, (uint32_t)x4, flags)); case FWU_SMC_IMAGE_AUTH: - SMC_RET1(handle, bl1_fwu_image_auth(x1, x2, x3, flags)); + SMC_RET1(handle, bl1_fwu_image_auth((uint32_t)x1, x2, + (uint32_t)x3, flags)); case FWU_SMC_IMAGE_EXECUTE: - SMC_RET1(handle, bl1_fwu_image_execute(x1, &handle, flags)); + SMC_RET1(handle, bl1_fwu_image_execute((uint32_t)x1, &handle, + flags)); case FWU_SMC_IMAGE_RESUME: - SMC_RET1(handle, bl1_fwu_image_resume((register_t)x1, &handle, flags)); + SMC_RET1(handle, bl1_fwu_image_resume((register_t)x1, &handle, + flags)); case FWU_SMC_SEC_IMAGE_DONE: SMC_RET1(handle, bl1_fwu_sec_image_done(&handle, flags)); case FWU_SMC_IMAGE_RESET: - SMC_RET1(handle, bl1_fwu_image_reset(x1, flags)); + SMC_RET1(handle, bl1_fwu_image_reset((uint32_t)x1, flags)); case FWU_SMC_UPDATE_DONE: bl1_fwu_done((void *)x1, NULL); default: - assert(0); /* Unreachable */ + assert(false); /* Unreachable */ break; } @@ -159,14 +163,14 @@ static int bl1_fwu_remove_loaded_id(unsigned int image_id) ******************************************************************************/ static int bl1_fwu_image_check_overlaps(unsigned int image_id) { - const image_desc_t *image_desc, *checked_image_desc; + const image_desc_t *desc, *checked_desc; const image_info_t *info, *checked_info; uintptr_t image_base, image_end; uintptr_t checked_image_base, checked_image_end; - checked_image_desc = bl1_plat_get_image_desc(image_id); - checked_info = &checked_image_desc->image_info; + checked_desc = bl1_plat_get_image_desc(image_id); + checked_info = &checked_desc->image_info; /* Image being checked mustn't be empty. */ assert(checked_info->image_size != 0); @@ -182,12 +186,12 @@ static int bl1_fwu_image_check_overlaps(unsigned int image_id) (bl1_fwu_loaded_ids[i] == image_id)) continue; - image_desc = bl1_plat_get_image_desc(bl1_fwu_loaded_ids[i]); + desc = bl1_plat_get_image_desc(bl1_fwu_loaded_ids[i]); /* Only check images that are loaded or being loaded. */ - assert (image_desc && image_desc->state != IMAGE_STATE_RESET); + assert ((desc != NULL) && (desc->state != IMAGE_STATE_RESET)); - info = &image_desc->image_info; + info = &desc->image_info; /* There cannot be overlaps with an empty image. */ if (info->image_size == 0) @@ -203,10 +207,10 @@ static int bl1_fwu_image_check_overlaps(unsigned int image_id) assert (image_end > image_base); /* Check if there are overlaps. */ - if (!(image_end < checked_image_base || - checked_image_end < image_base)) { + if (!((image_end < checked_image_base) || + (checked_image_end < image_base))) { VERBOSE("Image with ID %d overlaps existing image with ID %d", - checked_image_desc->image_id, image_desc->image_id); + checked_desc->image_id, desc->image_id); return -EPERM; } } @@ -225,10 +229,11 @@ static int bl1_fwu_image_copy(unsigned int image_id, { uintptr_t dest_addr; unsigned int remaining; + image_desc_t *desc; /* Get the image descriptor. */ - image_desc_t *image_desc = bl1_plat_get_image_desc(image_id); - if (!image_desc) { + desc = bl1_plat_get_image_desc(image_id); + if (desc == NULL) { WARN("BL1-FWU: Invalid image ID %u\n", image_id); return -EPERM; } @@ -241,66 +246,66 @@ static int bl1_fwu_image_copy(unsigned int image_id, WARN("BL1-FWU: Copy not allowed from secure world.\n"); return -EPERM; } - if (GET_SECURITY_STATE(image_desc->ep_info.h.attr) == NON_SECURE) { + if (GET_SECURITY_STATE(desc->ep_info.h.attr) == NON_SECURE) { WARN("BL1-FWU: Copy not allowed for non-secure images.\n"); return -EPERM; } /* Check whether the FWU state machine is in the correct state. */ - if ((image_desc->state != IMAGE_STATE_RESET) && - (image_desc->state != IMAGE_STATE_COPYING)) { + if ((desc->state != IMAGE_STATE_RESET) && + (desc->state != IMAGE_STATE_COPYING)) { WARN("BL1-FWU: Copy not allowed at this point of the FWU" " process.\n"); return -EPERM; } - if ((!image_src) || (!block_size) || + if ((image_src == 0U) || (block_size == 0U) || check_uptr_overflow(image_src, block_size - 1)) { WARN("BL1-FWU: Copy not allowed due to invalid image source" " or block size\n"); return -ENOMEM; } - if (image_desc->state == IMAGE_STATE_COPYING) { + if (desc->state == IMAGE_STATE_COPYING) { /* * There must have been at least 1 copy operation for this image * previously. */ - assert(image_desc->copied_size != 0); + assert(desc->copied_size != 0U); /* * The image size must have been recorded in the 1st copy * operation. */ - image_size = image_desc->image_info.image_size; + image_size = desc->image_info.image_size; assert(image_size != 0); - assert(image_desc->copied_size < image_size); + assert(desc->copied_size < image_size); INFO("BL1-FWU: Continuing image copy in blocks\n"); - } else { /* image_desc->state == IMAGE_STATE_RESET */ + } else { /* desc->state == IMAGE_STATE_RESET */ INFO("BL1-FWU: Initial call to copy an image\n"); /* * image_size is relevant only for the 1st copy request, it is * then ignored for subsequent calls for this image. */ - if (!image_size) { + if (image_size == 0) { WARN("BL1-FWU: Copy not allowed due to invalid image" " size\n"); return -ENOMEM; } /* Check that the image size to load is within limit */ - if (image_size > image_desc->image_info.image_max_size) { + if (image_size > desc->image_info.image_max_size) { WARN("BL1-FWU: Image size out of bounds\n"); return -ENOMEM; } /* Save the given image size. */ - image_desc->image_info.image_size = image_size; + desc->image_info.image_size = image_size; /* Make sure the image doesn't overlap other images. */ - if (bl1_fwu_image_check_overlaps(image_id)) { - image_desc->image_info.image_size = 0; + if (bl1_fwu_image_check_overlaps(image_id) != 0) { + desc->image_info.image_size = 0; WARN("BL1-FWU: This image overlaps another one\n"); return -EPERM; } @@ -310,32 +315,32 @@ static int bl1_fwu_image_copy(unsigned int image_id, * FWU code doesn't necessarily do it when it resets the state * machine. */ - image_desc->copied_size = 0; + desc->copied_size = 0; } /* * If the given block size is more than the total image size * then clip the former to the latter. */ - remaining = image_size - image_desc->copied_size; + remaining = image_size - desc->copied_size; if (block_size > remaining) { WARN("BL1-FWU: Block size is too big, clipping it.\n"); block_size = remaining; } /* Make sure the source image is mapped in memory. */ - if (bl1_plat_mem_check(image_src, block_size, flags)) { + if (bl1_plat_mem_check(image_src, block_size, flags) != 0) { WARN("BL1-FWU: Source image is not mapped.\n"); return -ENOMEM; } - if (bl1_fwu_add_loaded_id(image_id)) { + if (bl1_fwu_add_loaded_id(image_id) != 0) { WARN("BL1-FWU: Too many images loaded at the same time.\n"); return -ENOMEM; } /* Allow the platform to handle pre-image load before copying */ - if (image_desc->state == IMAGE_STATE_RESET) { + if (desc->state == IMAGE_STATE_RESET) { if (bl1_plat_handle_pre_image_load(image_id) != 0) { ERROR("BL1-FWU: Failure in pre-image load of image id %d\n", image_id); @@ -344,12 +349,12 @@ static int bl1_fwu_image_copy(unsigned int image_id, } /* Everything looks sane. Go ahead and copy the block of data. */ - dest_addr = image_desc->image_info.image_base + image_desc->copied_size; - memcpy((void *) dest_addr, (const void *) image_src, block_size); + dest_addr = desc->image_info.image_base + desc->copied_size; + (void)memcpy((void *) dest_addr, (const void *) image_src, block_size); flush_dcache_range(dest_addr, block_size); - image_desc->copied_size += block_size; - image_desc->state = (block_size == remaining) ? + desc->copied_size += block_size; + desc->state = (block_size == remaining) ? IMAGE_STATE_COPIED : IMAGE_STATE_COPYING; INFO("BL1-FWU: Copy operation successful.\n"); @@ -367,27 +372,28 @@ static int bl1_fwu_image_auth(unsigned int image_id, int result; uintptr_t base_addr; unsigned int total_size; + image_desc_t *desc; /* Get the image descriptor. */ - image_desc_t *image_desc = bl1_plat_get_image_desc(image_id); - if (!image_desc) + desc = bl1_plat_get_image_desc(image_id); + if (desc == NULL) return -EPERM; if (GET_SECURITY_STATE(flags) == SECURE) { - if (image_desc->state != IMAGE_STATE_RESET) { + if (desc->state != IMAGE_STATE_RESET) { WARN("BL1-FWU: Authentication from secure world " "while in invalid state\n"); return -EPERM; } } else { - if (GET_SECURITY_STATE(image_desc->ep_info.h.attr) == SECURE) { - if (image_desc->state != IMAGE_STATE_COPIED) { + if (GET_SECURITY_STATE(desc->ep_info.h.attr) == SECURE) { + if (desc->state != IMAGE_STATE_COPIED) { WARN("BL1-FWU: Authentication of secure image " "from non-secure world while not in copied state\n"); return -EPERM; } } else { - if (image_desc->state != IMAGE_STATE_RESET) { + if (desc->state != IMAGE_STATE_RESET) { WARN("BL1-FWU: Authentication of non-secure image " "from non-secure world while in invalid state\n"); return -EPERM; @@ -395,15 +401,15 @@ static int bl1_fwu_image_auth(unsigned int image_id, } } - if (image_desc->state == IMAGE_STATE_COPIED) { + if (desc->state == IMAGE_STATE_COPIED) { /* * Image is in COPIED state. * Use the stored address and size. */ - base_addr = image_desc->image_info.image_base; - total_size = image_desc->image_info.image_size; + base_addr = desc->image_info.image_base; + total_size = desc->image_info.image_size; } else { - if ((!image_src) || (!image_size) || + if ((image_src == 0U) || (image_size == 0U) || check_uptr_overflow(image_src, image_size - 1)) { WARN("BL1-FWU: Auth not allowed due to invalid" " image source/size\n"); @@ -415,12 +421,12 @@ static int bl1_fwu_image_auth(unsigned int image_id, * Check the parameters and authenticate the source image in place. */ if (bl1_plat_mem_check(image_src, image_size, \ - image_desc->ep_info.h.attr)) { + desc->ep_info.h.attr) != 0) { WARN("BL1-FWU: Authentication arguments source/size not mapped\n"); return -ENOMEM; } - if (bl1_fwu_add_loaded_id(image_id)) { + if (bl1_fwu_add_loaded_id(image_id) != 0) { WARN("BL1-FWU: Too many images loaded at the same time.\n"); return -ENOMEM; } @@ -429,7 +435,7 @@ static int bl1_fwu_image_auth(unsigned int image_id, total_size = image_size; /* Update the image size in the descriptor. */ - image_desc->image_info.image_size = total_size; + desc->image_info.image_size = total_size; } /* @@ -446,13 +452,13 @@ static int bl1_fwu_image_auth(unsigned int image_id, * This is to prevent an attack where this contains * some malicious code that can somehow be executed later. */ - if (image_desc->state == IMAGE_STATE_COPIED) { + if (desc->state == IMAGE_STATE_COPIED) { /* Clear the memory.*/ zero_normalmem((void *)base_addr, total_size); flush_dcache_range(base_addr, total_size); /* Indicate that image can be copied again*/ - image_desc->state = IMAGE_STATE_RESET; + desc->state = IMAGE_STATE_RESET; } /* @@ -460,12 +466,12 @@ static int bl1_fwu_image_auth(unsigned int image_id, * The image cannot be in RESET state here, it is checked at the * beginning of the function. */ - bl1_fwu_remove_loaded_id(image_id); + (void)bl1_fwu_remove_loaded_id(image_id); return -EAUTH; } /* Indicate that image is in authenticated state. */ - image_desc->state = IMAGE_STATE_AUTHENTICATED; + desc->state = IMAGE_STATE_AUTHENTICATED; /* Allow the platform to handle post-image load */ result = bl1_plat_handle_post_image_load(image_id); @@ -483,7 +489,7 @@ static int bl1_fwu_image_auth(unsigned int image_id, * Flush image_info to memory so that other * secure world images can see changes. */ - flush_dcache_range((uintptr_t)&image_desc->image_info, + flush_dcache_range((uintptr_t)&desc->image_info, sizeof(image_info_t)); INFO("BL1-FWU: Authentication was successful\n"); @@ -499,7 +505,7 @@ static int bl1_fwu_image_execute(unsigned int image_id, unsigned int flags) { /* Get the image descriptor. */ - image_desc_t *image_desc = bl1_plat_get_image_desc(image_id); + image_desc_t *desc = bl1_plat_get_image_desc(image_id); /* * Execution is NOT allowed if: @@ -509,11 +515,11 @@ static int bl1_fwu_image_execute(unsigned int image_id, * Image is Non-Executable OR * Image is NOT in AUTHENTICATED state. */ - if ((!image_desc) || + if ((desc == NULL) || (GET_SECURITY_STATE(flags) == SECURE) || - (GET_SECURITY_STATE(image_desc->ep_info.h.attr) == NON_SECURE) || - (EP_GET_EXE(image_desc->ep_info.h.attr) == NON_EXECUTABLE) || - (image_desc->state != IMAGE_STATE_AUTHENTICATED)) { + (GET_SECURITY_STATE(desc->ep_info.h.attr) == NON_SECURE) || + (EP_GET_EXE(desc->ep_info.h.attr) == NON_EXECUTABLE) || + (desc->state != IMAGE_STATE_AUTHENTICATED)) { WARN("BL1-FWU: Execution not allowed due to invalid state/args\n"); return -EPERM; } @@ -547,37 +553,37 @@ static register_t bl1_fwu_image_resume(register_t image_param, void **handle, unsigned int flags) { - image_desc_t *image_desc; + image_desc_t *desc; unsigned int resume_sec_state; unsigned int caller_sec_state = GET_SECURITY_STATE(flags); /* Get the image descriptor for last executed secure image id. */ - image_desc = bl1_plat_get_image_desc(sec_exec_image_id); + desc = bl1_plat_get_image_desc(sec_exec_image_id); if (caller_sec_state == NON_SECURE) { - if (!image_desc) { + if (desc == NULL) { WARN("BL1-FWU: Resume not allowed due to no available" "secure image\n"); return -EPERM; } } else { - /* image_desc must be valid for secure world callers */ - assert(image_desc); + /* desc must be valid for secure world callers */ + assert(desc != NULL); } - assert(GET_SECURITY_STATE(image_desc->ep_info.h.attr) == SECURE); - assert(EP_GET_EXE(image_desc->ep_info.h.attr) == EXECUTABLE); + assert(GET_SECURITY_STATE(desc->ep_info.h.attr) == SECURE); + assert(EP_GET_EXE(desc->ep_info.h.attr) == EXECUTABLE); if (caller_sec_state == SECURE) { - assert(image_desc->state == IMAGE_STATE_EXECUTED); + assert(desc->state == IMAGE_STATE_EXECUTED); /* Update the flags. */ - image_desc->state = IMAGE_STATE_INTERRUPTED; + desc->state = IMAGE_STATE_INTERRUPTED; resume_sec_state = NON_SECURE; } else { - assert(image_desc->state == IMAGE_STATE_INTERRUPTED); + assert(desc->state == IMAGE_STATE_INTERRUPTED); /* Update the flags. */ - image_desc->state = IMAGE_STATE_EXECUTED; + desc->state = IMAGE_STATE_EXECUTED; resume_sec_state = SECURE; } @@ -612,7 +618,7 @@ static register_t bl1_fwu_image_resume(register_t image_param, ******************************************************************************/ static int bl1_fwu_sec_image_done(void **handle, unsigned int flags) { - image_desc_t *image_desc; + image_desc_t *desc; /* Make sure caller is from the secure world */ if (GET_SECURITY_STATE(flags) == NON_SECURE) { @@ -621,13 +627,13 @@ static int bl1_fwu_sec_image_done(void **handle, unsigned int flags) } /* Get the image descriptor for last executed secure image id */ - image_desc = bl1_plat_get_image_desc(sec_exec_image_id); + desc = bl1_plat_get_image_desc(sec_exec_image_id); - /* image_desc must correspond to a valid secure executing image */ - assert(image_desc); - assert(GET_SECURITY_STATE(image_desc->ep_info.h.attr) == SECURE); - assert(EP_GET_EXE(image_desc->ep_info.h.attr) == EXECUTABLE); - assert(image_desc->state == IMAGE_STATE_EXECUTED); + /* desc must correspond to a valid secure executing image */ + assert(desc != NULL); + assert(GET_SECURITY_STATE(desc->ep_info.h.attr) == SECURE); + assert(EP_GET_EXE(desc->ep_info.h.attr) == EXECUTABLE); + assert(desc->state == IMAGE_STATE_EXECUTED); #if ENABLE_ASSERTIONS int rc = bl1_fwu_remove_loaded_id(sec_exec_image_id); @@ -637,7 +643,7 @@ static int bl1_fwu_sec_image_done(void **handle, unsigned int flags) #endif /* Update the flags. */ - image_desc->state = IMAGE_STATE_RESET; + desc->state = IMAGE_STATE_RESET; sec_exec_image_id = INVALID_IMAGE_ID; INFO("BL1-FWU: Resuming Normal world context\n"); @@ -676,7 +682,7 @@ __dead2 static void bl1_fwu_done(void *client_cookie, void *reserved) * Call platform done function. */ bl1_plat_fwu_done(client_cookie, reserved); - assert(0); + assert(false); } /******************************************************************************* @@ -685,14 +691,14 @@ __dead2 static void bl1_fwu_done(void *client_cookie, void *reserved) ******************************************************************************/ static int bl1_fwu_image_reset(unsigned int image_id, unsigned int flags) { - image_desc_t *image_desc = bl1_plat_get_image_desc(image_id); + image_desc_t *desc = bl1_plat_get_image_desc(image_id); - if ((!image_desc) || (GET_SECURITY_STATE(flags) == SECURE)) { + if ((desc == NULL) || (GET_SECURITY_STATE(flags) == SECURE)) { WARN("BL1-FWU: Reset not allowed due to invalid args\n"); return -EPERM; } - switch (image_desc->state) { + switch (desc->state) { case IMAGE_STATE_RESET: /* Nothing to do. */ @@ -703,25 +709,26 @@ static int bl1_fwu_image_reset(unsigned int image_id, unsigned int flags) case IMAGE_STATE_COPIED: case IMAGE_STATE_COPYING: - if (bl1_fwu_remove_loaded_id(image_id)) { + if (bl1_fwu_remove_loaded_id(image_id) != 0) { WARN("BL1-FWU: Image reset couldn't find the image ID\n"); return -EPERM; } - if (image_desc->copied_size) { + if (desc->copied_size != 0U) { /* Clear the memory if the image is copied */ - assert(GET_SECURITY_STATE(image_desc->ep_info.h.attr) == SECURE); + assert(GET_SECURITY_STATE(desc->ep_info.h.attr) + == SECURE); - zero_normalmem((void *)image_desc->image_info.image_base, - image_desc->copied_size); - flush_dcache_range(image_desc->image_info.image_base, - image_desc->copied_size); + zero_normalmem((void *)desc->image_info.image_base, + desc->copied_size); + flush_dcache_range(desc->image_info.image_base, + desc->copied_size); } /* Reset status variables */ - image_desc->copied_size = 0; - image_desc->image_info.image_size = 0; - image_desc->state = IMAGE_STATE_RESET; + desc->copied_size = 0; + desc->image_info.image_size = 0; + desc->state = IMAGE_STATE_RESET; /* Clear authentication state */ auth_img_flags[image_id] = 0; @@ -730,7 +737,7 @@ static int bl1_fwu_image_reset(unsigned int image_id, unsigned int flags) case IMAGE_STATE_EXECUTED: default: - assert(0); /* Unreachable */ + assert(false); /* Unreachable */ break; } diff --git a/bl1/bl1_main.c b/bl1/bl1_main.c index e11ead608..1479a967b 100644 --- a/bl1/bl1_main.c +++ b/bl1/bl1_main.c @@ -90,8 +90,7 @@ void bl1_main(void) 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); + INFO("BL1: RAM %p - %p\n", (void *)BL1_RAM_BASE, (void *)BL1_RAM_LIMIT); print_errata_status(); @@ -105,9 +104,9 @@ void bl1_main(void) #else val = read_sctlr(); #endif - assert(val & SCTLR_M_BIT); - assert(val & SCTLR_C_BIT); - assert(val & SCTLR_I_BIT); + assert((val & SCTLR_M_BIT) != 0); + assert((val & SCTLR_C_BIT) != 0); + assert((val & SCTLR_I_BIT) != 0); /* * Check that Cache Writeback Granule (CWG) in CTR_EL0 matches the * provided platform value @@ -166,33 +165,33 @@ void bl1_main(void) ******************************************************************************/ static void bl1_load_bl2(void) { - image_desc_t *image_desc; - image_info_t *image_info; + image_desc_t *desc; + image_info_t *info; int err; /* Get the image descriptor */ - image_desc = bl1_plat_get_image_desc(BL2_IMAGE_ID); - assert(image_desc != NULL); + desc = bl1_plat_get_image_desc(BL2_IMAGE_ID); + assert(desc != NULL); /* Get the image info */ - image_info = &image_desc->image_info; + info = &desc->image_info; INFO("BL1: Loading BL2\n"); err = bl1_plat_handle_pre_image_load(BL2_IMAGE_ID); - if (err) { + 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, image_info); - if (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) { + if (err != 0) { ERROR("Failure in post image load handling of BL2 (%d)\n", err); plat_error_handler(err); } @@ -258,11 +257,9 @@ u_register_t bl1_smc_handler(unsigned int smc_fid, SMC_RET1(handle, BL1_SMC_MAJOR_VER | BL1_SMC_MINOR_VER); default: - break; + WARN("Unimplemented BL1 SMC Call: 0x%x\n", smc_fid); + SMC_RET1(handle, SMC_UNK); } - - WARN("Unimplemented BL1 SMC Call: 0x%x \n", smc_fid); - SMC_RET1(handle, SMC_UNK); } /******************************************************************************* diff --git a/bl2/bl2_image_load_v2.c b/bl2/bl2_image_load_v2.c index 81d4b2bcc..48c9beca6 100644 --- a/bl2/bl2_image_load_v2.c +++ b/bl2/bl2_image_load_v2.c @@ -47,8 +47,9 @@ struct entry_point_info *bl2_load_images(void) * if indicated in the image attributes AND if NOT * already done before. */ - if (bl2_node_info->image_info->h.attr & IMAGE_ATTRIB_PLAT_SETUP) { - if (plat_setup_done) { + if ((bl2_node_info->image_info->h.attr & + IMAGE_ATTRIB_PLAT_SETUP) != 0U) { + if (plat_setup_done != 0) { WARN("BL2: Platform setup already done!!\n"); } else { INFO("BL2: Doing platform setup\n"); @@ -58,16 +59,17 @@ struct entry_point_info *bl2_load_images(void) } err = bl2_plat_handle_pre_image_load(bl2_node_info->image_id); - if (err) { + if (err != 0) { ERROR("BL2: Failure in pre image load handling (%i)\n", err); plat_error_handler(err); } - if (!(bl2_node_info->image_info->h.attr & IMAGE_ATTRIB_SKIP_LOADING)) { + if ((bl2_node_info->image_info->h.attr & + IMAGE_ATTRIB_SKIP_LOADING) == 0U) { INFO("BL2: Loading image id %d\n", bl2_node_info->image_id); err = load_auth_image(bl2_node_info->image_id, bl2_node_info->image_info); - if (err) { + if (err != 0) { ERROR("BL2: Failed to load image id %d (%i)\n", bl2_node_info->image_id, err); plat_error_handler(err); @@ -78,7 +80,7 @@ struct entry_point_info *bl2_load_images(void) /* Allow platform to handle image information. */ err = bl2_plat_handle_post_image_load(bl2_node_info->image_id); - if (err) { + if (err != 0) { ERROR("BL2: Failure in post image load handling (%i)\n", err); plat_error_handler(err); } diff --git a/bl2u/bl2u_main.c b/bl2u/bl2u_main.c index d49c9ce9e..fcb73b9c7 100644 --- a/bl2u/bl2u_main.c +++ b/bl2u/bl2u_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -34,7 +34,7 @@ void bl2u_main(void) int rc; /* Load the subsequent bootloader images */ rc = bl2u_plat_handle_scp_bl2u(); - if (rc) { + if (rc != 0) { ERROR("Failed to load SCP_BL2U (%i)\n", rc); panic(); } diff --git a/include/arch/aarch32/arch.h b/include/arch/aarch32/arch.h index 20175481f..8492b3ea4 100644 --- a/include/arch/aarch32/arch.h +++ b/include/arch/aarch32/arch.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -388,13 +388,17 @@ #define GET_M32(mode) (((mode) >> MODE32_SHIFT) & MODE32_MASK) -#define SPSR_MODE32(mode, isa, endian, aif) \ - ((MODE_RW_32 << MODE_RW_SHIFT | \ - ((mode) & MODE32_MASK) << MODE32_SHIFT | \ - ((isa) & SPSR_T_MASK) << SPSR_T_SHIFT | \ - ((endian) & SPSR_E_MASK) << SPSR_E_SHIFT | \ - ((aif) & SPSR_AIF_MASK) << SPSR_AIF_SHIFT) & \ - (~(SPSR_SSBS_BIT))) +#define SPSR_MODE32(mode, isa, endian, aif) \ +( \ + ( \ + (MODE_RW_32 << MODE_RW_SHIFT) | \ + (((mode) & MODE32_MASK) << MODE32_SHIFT) | \ + (((isa) & SPSR_T_MASK) << SPSR_T_SHIFT) | \ + (((endian) & SPSR_E_MASK) << SPSR_E_SHIFT) | \ + (((aif) & SPSR_AIF_MASK) << SPSR_AIF_SHIFT) \ + ) & \ + (~(SPSR_SSBS_BIT)) \ +) /* * TTBR definitions diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index 2b2c11652..19dd8c5e3 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -264,8 +264,8 @@ (U(1) << 22) | (U(1) << 18) | (U(1) << 16) | \ (U(1) << 11) | (U(1) << 5) | (U(1) << 4)) -#define SCTLR_EL1_RES1 ((U(1) << 29) | (U(1) << 28) | (U(1) << 23) | \ - (U(1) << 22) | (U(1) << 20) | (U(1) << 11)) +#define SCTLR_EL1_RES1 ((UL(1) << 29) | (UL(1) << 28) | (UL(1) << 23) | \ + (UL(1) << 22) | (UL(1) << 20) | (UL(1) << 11)) #define SCTLR_AARCH32_EL1_RES1 \ ((U(1) << 23) | (U(1) << 22) | (U(1) << 11) | \ (U(1) << 4) | (U(1) << 3)) diff --git a/include/lib/smccc.h b/include/lib/smccc.h index 5e13e6f0a..26509aeca 100644 --- a/include/lib/smccc.h +++ b/include/lib/smccc.h @@ -122,18 +122,18 @@ */ #define DEFINE_SVC_UUID2(_name, _tl, _tm, _th, _cl, _ch, \ _n0, _n1, _n2, _n3, _n4, _n5) \ - CASSERT((uint32_t)(_tl) != (uint32_t) SMC_UNK, invalid_svc_uuid);\ + CASSERT((uint32_t)(_tl) != (uint32_t)SMC_UNK, invalid_svc_uuid);\ static const uuid_t _name = { \ - {(_tl >> 24) & 0xFF, \ - (_tl >> 16) & 0xFF, \ - (_tl >> 8) & 0xFF, \ - (_tl & 0xFF)}, \ - {(_tm >> 8) & 0xFF, \ - (_tm & 0xFF)}, \ - {(_th >> 8) & 0xFF, \ - (_th & 0xFF)}, \ - _cl, _ch, \ - { _n0, _n1, _n2, _n3, _n4, _n5 } \ + {((_tl) >> 24) & 0xFF, \ + ((_tl) >> 16) & 0xFF, \ + ((_tl) >> 8) & 0xFF, \ + ((_tl) & 0xFF)}, \ + {((_tm) >> 8) & 0xFF, \ + ((_tm) & 0xFF)}, \ + {((_th) >> 8) & 0xFF, \ + ((_th) & 0xFF)}, \ + (_cl), (_ch), \ + { (_n0), (_n1), (_n2), (_n3), (_n4), (_n5) } \ } /* diff --git a/include/lib/utils_def.h b/include/lib/utils_def.h index 09ae3999d..2d0e9c08e 100644 --- a/include/lib/utils_def.h +++ b/include/lib/utils_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -17,7 +17,7 @@ #define IS_POWER_OF_TWO(x) \ (((x) & ((x) - 1)) == 0) -#define SIZE_FROM_LOG2_WORDS(n) (4 << (n)) +#define SIZE_FROM_LOG2_WORDS(n) (U(4) << (n)) #define BIT_32(nr) (U(1) << (nr)) #define BIT_64(nr) (ULL(1) << (nr)) -- cgit v1.2.3 From a39493cb02c785085cf359b1609d21cbc16cb293 Mon Sep 17 00:00:00 2001 From: Max Shvetsov Date: Mon, 6 Apr 2020 11:32:38 +0100 Subject: stingray: Fix board configuration typo. Default board configuration was set to bcm958742k which is not present in current codebase. This causes a default platform build to fail. Changing to bcm958742t. Signed-off-by: Max Shvetsov Change-Id: Ie24f94ef0ef316ff56fe142df5de45d70ba93c28 --- plat/brcm/board/stingray/platform.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/brcm/board/stingray/platform.mk b/plat/brcm/board/stingray/platform.mk index 20ebcddc3..c5509bb6b 100644 --- a/plat/brcm/board/stingray/platform.mk +++ b/plat/brcm/board/stingray/platform.mk @@ -70,7 +70,7 @@ $(eval $(call add_define,USE_DDR)) endif ifeq (${BOARD_CFG},) -BOARD_CFG := bcm958742k +BOARD_CFG := bcm958742t endif # Use PAXB -- cgit v1.2.3 From 8f3ad7661400c1cf23276f8ffff905102c54329a Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Mon, 6 Apr 2020 16:27:54 +0100 Subject: TF-A GICv3 driver: Add extended PPI and SPI range This patch provides support for GICv3.1 extended PPI and SPI range. The option is enabled by setting to 1 and passing `GIC_EXT_INTID` build flag to gicv3.mk makefile. This option defaults to 0 with no extended range support. Change-Id: I7d09086fe22ea531c5df51a8a1efd8928458d394 Signed-off-by: Alexei Fedorov --- docs/getting_started/build-options.rst | 3 + drivers/arm/gic/v3/gicdv3_helpers.c | 226 ++++++++++++-- drivers/arm/gic/v3/gicrv3_helpers.c | 186 +++--------- drivers/arm/gic/v3/gicv3.mk | 8 +- drivers/arm/gic/v3/gicv3_helpers.c | 207 ++++++++----- drivers/arm/gic/v3/gicv3_main.c | 528 +++++++++++++++++++++++---------- drivers/arm/gic/v3/gicv3_private.h | 268 +++++++++++------ include/drivers/arm/gicv3.h | 131 ++++++-- 8 files changed, 1052 insertions(+), 505 deletions(-) diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index e1c6c8f80..38845ff0b 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -693,6 +693,9 @@ makefile: functions. This is required for FVP platform which need to simulate GIC save and restore during SYSTEM_SUSPEND without powering down GIC. Default is 0. +- ``GIC_EXT_INTID``: When set to ``1``, GICv3 driver will support extended + PPI (1056-1119) and SPI (4096-5119) range. This option defaults to 0. + Debugging options ----------------- diff --git a/drivers/arm/gic/v3/gicdv3_helpers.c b/drivers/arm/gic/v3/gicdv3_helpers.c index 3f5ff45fc..987be69e7 100644 --- a/drivers/arm/gic/v3/gicdv3_helpers.c +++ b/drivers/arm/gic/v3/gicdv3_helpers.c @@ -9,50 +9,236 @@ #include "gicv3_private.h" /******************************************************************************* - * GIC Distributor interface accessors for bit operations + * GIC Distributor functions for accessing the GIC registers + * corresponding to a single interrupt ID. These functions use bitwise + * operations or appropriate register accesses to modify or return + * the bit-field corresponding the single interrupt ID. ******************************************************************************/ /* - * Accessor to read the GIC Distributor IGRPMODR corresponding to the - * interrupt `id`, 32 interrupt IDs at a time. + * Accessors to set the bits corresponding to interrupt ID + * in GIC Distributor ICFGR and ICFGRE. */ -uint32_t gicd_read_igrpmodr(uintptr_t base, unsigned int id) +void gicd_set_icfgr(uintptr_t base, unsigned int id, unsigned int cfg) { - return GICD_READ(IGRPMODR, base, id); + /* Interrupt configuration is a 2-bit field */ + unsigned int bit_shift = BIT_NUM(ICFG, id) << 1U; + + /* Clear the field, and insert required configuration */ + mmio_clrsetbits_32(base + GICD_OFFSET(ICFG, id), + (uint32_t)GIC_CFG_MASK << bit_shift, + (cfg & GIC_CFG_MASK) << bit_shift); } /* - * Accessor to write the GIC Distributor IGRPMODR corresponding to the - * interrupt `id`, 32 interrupt IDs at a time. + * Accessors to get/set/clear the bit corresponding to interrupt ID + * in GIC Distributor IGROUPR and IGROUPRE. */ -void gicd_write_igrpmodr(uintptr_t base, unsigned int id, uint32_t val) +unsigned int gicd_get_igroupr(uintptr_t base, unsigned int id) +{ + return GICD_GET_BIT(IGROUP, base, id); +} + +void gicd_set_igroupr(uintptr_t base, unsigned int id) +{ + GICD_SET_BIT(IGROUP, base, id); +} + +void gicd_clr_igroupr(uintptr_t base, unsigned int id) { - GICD_WRITE(IGRPMODR, base, id, val); + GICD_CLR_BIT(IGROUP, base, id); } /* - * Accessor to get the bit corresponding to interrupt ID - * in GIC Distributor IGRPMODR. + * Accessors to get/set/clear the bit corresponding to interrupt ID + * in GIC Distributor IGRPMODR and IGRPMODRE. */ unsigned int gicd_get_igrpmodr(uintptr_t base, unsigned int id) { - return GICD_GET_BIT(IGRPMODR, base, id); + return GICD_GET_BIT(IGRPMOD, base, id); +} + +void gicd_set_igrpmodr(uintptr_t base, unsigned int id) +{ + GICD_SET_BIT(IGRPMOD, base, id); +} + +void gicd_clr_igrpmodr(uintptr_t base, unsigned int id) +{ + GICD_CLR_BIT(IGRPMOD, base, id); } /* - * Accessor to set the bit corresponding to interrupt ID - * in GIC Distributor IGRPMODR. + * Accessors to set the bit corresponding to interrupt ID + * in GIC Distributor ICENABLER and ICENABLERE. */ -void gicd_set_igrpmodr(uintptr_t base, unsigned int id) +void gicd_set_icenabler(uintptr_t base, unsigned int id) { - GICD_SET_BIT(IGRPMODR, base, id); + GICD_WRITE_BIT(ICENABLE, base, id); } /* - * Accessor to clear the bit corresponding to interrupt ID - * in GIC Distributor IGRPMODR. + * Accessors to set the bit corresponding to interrupt ID + * in GIC Distributor ICPENDR and ICPENDRE. */ -void gicd_clr_igrpmodr(uintptr_t base, unsigned int id) +void gicd_set_icpendr(uintptr_t base, unsigned int id) +{ + GICD_WRITE_BIT(ICPEND, base, id); +} + +/* + * Accessors to get/set the bit corresponding to interrupt ID + * in GIC Distributor ISACTIVER and ISACTIVERE. + */ +unsigned int gicd_get_isactiver(uintptr_t base, unsigned int id) +{ + return GICD_GET_BIT(ISACTIVE, base, id); +} + +void gicd_set_isactiver(uintptr_t base, unsigned int id) +{ + GICD_WRITE_BIT(ISACTIVE, base, id); +} + +/* + * Accessors to set the bit corresponding to interrupt ID + * in GIC Distributor ISENABLER and ISENABLERE. + */ +void gicd_set_isenabler(uintptr_t base, unsigned int id) +{ + GICD_WRITE_BIT(ISENABLE, base, id); +} + +/* + * Accessors to set the bit corresponding to interrupt ID + * in GIC Distributor ISPENDR and ISPENDRE. + */ +void gicd_set_ispendr(uintptr_t base, unsigned int id) +{ + GICD_WRITE_BIT(ISPEND, base, id); +} + +/* + * Accessors to set the bit corresponding to interrupt ID + * in GIC Distributor IPRIORITYR and IPRIORITYRE. + */ +void gicd_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri) +{ + GICD_WRITE_8(IPRIORITY, base, id, (uint8_t)(pri & GIC_PRI_MASK)); +} + +/******************************************************************************* + * GIC Distributor interface accessors for reading/writing entire registers + ******************************************************************************/ + +/* + * Accessors to read/write the GIC Distributor ICGFR and ICGFRE + * corresponding to the interrupt ID, 16 interrupt IDs at a time. + */ +unsigned int gicd_read_icfgr(uintptr_t base, unsigned int id) +{ + return GICD_READ(ICFG, base, id); +} + +void gicd_write_icfgr(uintptr_t base, unsigned int id, unsigned int val) +{ + GICD_WRITE(ICFG, base, id, val); +} + +/* + * Accessors to read/write the GIC Distributor IGROUPR and IGROUPRE + * corresponding to the interrupt ID, 32 interrupt IDs at a time. + */ +unsigned int gicd_read_igroupr(uintptr_t base, unsigned int id) +{ + return GICD_READ(IGROUP, base, id); +} + +void gicd_write_igroupr(uintptr_t base, unsigned int id, unsigned int val) +{ + GICD_WRITE(IGROUP, base, id, val); +} + +/* + * Accessors to read/write the GIC Distributor IGRPMODR and IGRPMODRE + * corresponding to the interrupt ID, 32 interrupt IDs at a time. + */ +unsigned int gicd_read_igrpmodr(uintptr_t base, unsigned int id) +{ + return GICD_READ(IGRPMOD, base, id); +} + +void gicd_write_igrpmodr(uintptr_t base, unsigned int id, unsigned int val) +{ + GICD_WRITE(IGRPMOD, base, id, val); +} + +/* + * Accessors to read/write the GIC Distributor IPRIORITYR and IPRIORITYRE + * corresponding to the interrupt ID, 4 interrupt IDs at a time. + */ +unsigned int gicd_read_ipriorityr(uintptr_t base, unsigned int id) +{ + return GICD_READ(IPRIORITY, base, id); +} + +void gicd_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val) +{ + GICD_WRITE(IPRIORITY, base, id, val); +} + +/* + * Accessors to read/write the GIC Distributor ISACTIVER and ISACTIVERE + * corresponding to the interrupt ID, 32 interrupt IDs at a time. + */ +unsigned int gicd_read_isactiver(uintptr_t base, unsigned int id) +{ + return GICD_READ(ISACTIVE, base, id); +} + +void gicd_write_isactiver(uintptr_t base, unsigned int id, unsigned int val) +{ + GICD_WRITE(ISACTIVE, base, id, val); +} + +/* + * Accessors to read/write the GIC Distributor ISENABLER and ISENABLERE + * corresponding to the interrupt ID, 32 interrupt IDs at a time. + */ +unsigned int gicd_read_isenabler(uintptr_t base, unsigned int id) +{ + return GICD_READ(ISENABLE, base, id); +} + +void gicd_write_isenabler(uintptr_t base, unsigned int id, unsigned int val) +{ + GICD_WRITE(ISENABLE, base, id, val); +} + +/* + * Accessors to read/write the GIC Distributor ISPENDR and ISPENDRE + * corresponding to the interrupt ID, 32 interrupt IDs at a time. + */ +unsigned int gicd_read_ispendr(uintptr_t base, unsigned int id) +{ + return GICD_READ(ISPEND, base, id); +} + +void gicd_write_ispendr(uintptr_t base, unsigned int id, unsigned int val) +{ + GICD_WRITE(ISPEND, base, id, val); +} + +/* + * Accessors to read/write the GIC Distributor NSACR and NSACRE + * corresponding to the interrupt ID, 16 interrupt IDs at a time. + */ +unsigned int gicd_read_nsacr(uintptr_t base, unsigned int id) +{ + return GICD_READ(NSAC, base, id); +} + +void gicd_write_nsacr(uintptr_t base, unsigned int id, unsigned int val) { - GICD_CLR_BIT(IGRPMODR, base, id); + GICD_WRITE(NSAC, base, id, val); } diff --git a/drivers/arm/gic/v3/gicrv3_helpers.c b/drivers/arm/gic/v3/gicrv3_helpers.c index 294acda5a..e46b15e24 100644 --- a/drivers/arm/gic/v3/gicrv3_helpers.c +++ b/drivers/arm/gic/v3/gicrv3_helpers.c @@ -13,203 +13,113 @@ /******************************************************************************* * GIC Redistributor functions - * Note: The raw register values correspond to multiple interrupt IDs and - * the number of interrupt IDs involved depends on the register accessed. + * Note: The raw register values correspond to multiple interrupt `id`s and + * the number of interrupt `id`s involved depends on the register accessed. ******************************************************************************/ /* - * Accessor to read the GIC Redistributor IPRIORITYR corresponding to the - * interrupt `id`, 4 interrupts IDs at a time. - */ -unsigned int gicr_read_ipriorityr(uintptr_t base, unsigned int id) -{ - unsigned int n = id >> IPRIORITYR_SHIFT; - - return mmio_read_32(base + GICR_IPRIORITYR + (n << 2)); -} - -/* - * Accessor to write the GIC Redistributor IPRIORITYR corresponding to the - * interrupt `id`, 4 interrupts IDs at a time. - */ -void gicr_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val) -{ - unsigned int n = id >> IPRIORITYR_SHIFT; - - mmio_write_32(base + GICR_IPRIORITYR + (n << 2), val); -} - -/* - * Accessor to set the byte corresponding to interrupt ID - * in GIC Redistributor IPRIORITYR. + * Accessor to set the byte corresponding to interrupt `id` + * in GIC Redistributor IPRIORITYR and IPRIORITYRE. */ void gicr_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri) { - GICR_WRITE_8(IPRIORITYR, base, id, pri & GIC_PRI_MASK); + GICR_WRITE_8(IPRIORITY, base, id, (uint8_t)(pri & GIC_PRI_MASK)); } /* - * Accessor to get the bit corresponding to interrupt ID - * from GIC Redistributor IGROUPR0. + * Accessors to get/set/clear the bit corresponding to interrupt `id` + * from GIC Redistributor IGROUPR0 and IGROUPRE */ -unsigned int gicr_get_igroupr0(uintptr_t base, unsigned int id) +unsigned int gicr_get_igroupr(uintptr_t base, unsigned int id) { - unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U); - unsigned int reg_val = gicr_read_igroupr0(base); - - return (reg_val >> bit_num) & 0x1U; + return GICR_GET_BIT(IGROUP, base, id); } -/* - * Accessor to set the bit corresponding to interrupt ID - * in GIC Redistributor IGROUPR0. - */ -void gicr_set_igroupr0(uintptr_t base, unsigned int id) +void gicr_set_igroupr(uintptr_t base, unsigned int id) { - unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U); - unsigned int reg_val = gicr_read_igroupr0(base); - - gicr_write_igroupr0(base, reg_val | (1U << bit_num)); + GICR_SET_BIT(IGROUP, base, id); } -/* - * Accessor to clear the bit corresponding to interrupt ID - * in GIC Redistributor IGROUPR0. - */ -void gicr_clr_igroupr0(uintptr_t base, unsigned int id) +void gicr_clr_igroupr(uintptr_t base, unsigned int id) { - unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U); - unsigned int reg_val = gicr_read_igroupr0(base); - - gicr_write_igroupr0(base, reg_val & ~(1U << bit_num)); + GICR_CLR_BIT(IGROUP, base, id); } /* - * Accessor to get the bit corresponding to interrupt ID - * from GIC Redistributor IGRPMODR0. + * Accessors to get/set/clear the bit corresponding to interrupt `id` + * from GIC Redistributor IGRPMODR0 and IGRPMODRE */ -unsigned int gicr_get_igrpmodr0(uintptr_t base, unsigned int id) +unsigned int gicr_get_igrpmodr(uintptr_t base, unsigned int id) { - unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U); - unsigned int reg_val = gicr_read_igrpmodr0(base); - - return (reg_val >> bit_num) & 0x1U; + return GICR_GET_BIT(IGRPMOD, base, id); } -/* - * Accessor to set the bit corresponding to interrupt ID - * in GIC Redistributor IGRPMODR0. - */ -void gicr_set_igrpmodr0(uintptr_t base, unsigned int id) +void gicr_set_igrpmodr(uintptr_t base, unsigned int id) { - unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U); - unsigned int reg_val = gicr_read_igrpmodr0(base); - - gicr_write_igrpmodr0(base, reg_val | (1U << bit_num)); + GICR_SET_BIT(IGRPMOD, base, id); } -/* - * Accessor to clear the bit corresponding to interrupt ID - * in GIC Redistributor IGRPMODR0. - */ -void gicr_clr_igrpmodr0(uintptr_t base, unsigned int id) +void gicr_clr_igrpmodr(uintptr_t base, unsigned int id) { - unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U); - unsigned int reg_val = gicr_read_igrpmodr0(base); - - gicr_write_igrpmodr0(base, reg_val & ~(1U << bit_num)); + GICR_CLR_BIT(IGRPMOD, base, id); } /* - * Accessor to set the bit corresponding to interrupt ID - * in GIC Redistributor ISENABLER0. + * Accessor to write the bit corresponding to interrupt `id` + * in GIC Redistributor ISENABLER0 and ISENABLERE */ -void gicr_set_isenabler0(uintptr_t base, unsigned int id) +void gicr_set_isenabler(uintptr_t base, unsigned int id) { - unsigned int bit_num = id & ((1U << ISENABLER_SHIFT) - 1U); - - gicr_write_isenabler0(base, (1U << bit_num)); + GICR_WRITE_BIT(ISENABLE, base, id); } /* - * Accessor to set the bit corresponding to interrupt ID in GIC Redistributor - * ICENABLER0. + * Accessor to write the bit corresponding to interrupt `id` + * in GIC Redistributor ICENABLER0 and ICENABLERE */ -void gicr_set_icenabler0(uintptr_t base, unsigned int id) +void gicr_set_icenabler(uintptr_t base, unsigned int id) { - unsigned int bit_num = id & ((1U << ICENABLER_SHIFT) - 1U); - - gicr_write_icenabler0(base, (1U << bit_num)); + GICR_WRITE_BIT(ICENABLE, base, id); } /* - * Accessor to set the bit corresponding to interrupt ID in GIC Redistributor - * ISACTIVER0. + * Accessor to get the bit corresponding to interrupt `id` + * in GIC Redistributor ISACTIVER0 and ISACTIVERE */ -unsigned int gicr_get_isactiver0(uintptr_t base, unsigned int id) +unsigned int gicr_get_isactiver(uintptr_t base, unsigned int id) { - unsigned int bit_num = id & ((1U << ISACTIVER_SHIFT) - 1U); - unsigned int reg_val = gicr_read_isactiver0(base); - - return (reg_val >> bit_num) & 0x1U; + return GICR_GET_BIT(ISACTIVE, base, id); } /* - * Accessor to clear the bit corresponding to interrupt ID in GIC Redistributor - * ICPENDRR0. + * Accessor to clear the bit corresponding to interrupt `id` + * in GIC Redistributor ICPENDR0 and ICPENDRE */ -void gicr_set_icpendr0(uintptr_t base, unsigned int id) +void gicr_set_icpendr(uintptr_t base, unsigned int id) { - unsigned int bit_num = id & ((1U << ICPENDR_SHIFT) - 1U); - - gicr_write_icpendr0(base, (1U << bit_num)); + GICR_WRITE_BIT(ICPEND, base, id); } /* - * Accessor to set the bit corresponding to interrupt ID in GIC Redistributor - * ISPENDR0. + * Accessor to write the bit corresponding to interrupt `id` + * in GIC Redistributor ISPENDR0 and ISPENDRE */ -void gicr_set_ispendr0(uintptr_t base, unsigned int id) +void gicr_set_ispendr(uintptr_t base, unsigned int id) { - unsigned int bit_num = id & ((1U << ISPENDR_SHIFT) - 1U); - - gicr_write_ispendr0(base, (1U << bit_num)); + GICR_WRITE_BIT(ISPEND, base, id); } /* - * Accessor to set the bit fields corresponding to interrupt ID - * in GIC Redistributor ICFGR0. + * Accessor to set the bit fields corresponding to interrupt `id` + * in GIC Redistributor ICFGR0, ICFGR1 and ICFGRE */ -void gicr_set_icfgr0(uintptr_t base, unsigned int id, unsigned int cfg) +void gicr_set_icfgr(uintptr_t base, unsigned int id, unsigned int cfg) { /* Interrupt configuration is a 2-bit field */ - unsigned int bit_num = id & ((1U << ICFGR_SHIFT) - 1U); - unsigned int bit_shift = bit_num << 1U; - - uint32_t reg_val = gicr_read_icfgr0(base); + unsigned int bit_shift = BIT_NUM(ICFG, id) << 1U; /* Clear the field, and insert required configuration */ - reg_val &= ~(GIC_CFG_MASK << bit_shift); - reg_val |= ((cfg & GIC_CFG_MASK) << bit_shift); - - gicr_write_icfgr0(base, reg_val); -} - -/* - * Accessor to set the bit fields corresponding to interrupt ID - * in GIC Redistributor ICFGR1. - */ -void gicr_set_icfgr1(uintptr_t base, unsigned int id, unsigned int cfg) -{ - /* Interrupt configuration is a 2-bit field */ - unsigned int bit_num = id & ((1U << ICFGR_SHIFT) - 1U); - unsigned int bit_shift = bit_num << 1U; - - uint32_t reg_val = gicr_read_icfgr1(base); - - /* Clear the field, and insert required configuration */ - reg_val &= ~(GIC_CFG_MASK << bit_shift); - reg_val |= ((cfg & GIC_CFG_MASK) << bit_shift); - - gicr_write_icfgr1(base, reg_val); + mmio_clrsetbits_32(base + GICR_OFFSET(ICFG, id), + (uint32_t)GIC_CFG_MASK << bit_shift, + (cfg & GIC_CFG_MASK) << bit_shift); } diff --git a/drivers/arm/gic/v3/gicv3.mk b/drivers/arm/gic/v3/gicv3.mk index 164f88eda..73339d991 100644 --- a/drivers/arm/gic/v3/gicv3.mk +++ b/drivers/arm/gic/v3/gicv3.mk @@ -8,9 +8,9 @@ GICV3_IMPL ?= GIC500 GICV3_IMPL_GIC600_MULTICHIP ?= 0 GICV3_OVERRIDE_DISTIF_PWR_OPS ?= 0 +GIC_EXT_INTID ?= 0 -GICV3_SOURCES += drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v3/gicv3_main.c \ +GICV3_SOURCES += drivers/arm/gic/v3/gicv3_main.c \ drivers/arm/gic/v3/gicv3_helpers.c \ drivers/arm/gic/v3/gicdv3_helpers.c \ drivers/arm/gic/v3/gicrv3_helpers.c @@ -32,3 +32,7 @@ GICV3_SOURCES += drivers/arm/gic/v3/gic500.c else $(error "Incorrect GICV3_IMPL value ${GICV3_IMPL}") endif + +# Set support for extended PPI and SPI range +$(eval $(call assert_boolean,GIC_EXT_INTID)) +$(eval $(call add_define,GIC_EXT_INTID)) diff --git a/drivers/arm/gic/v3/gicv3_helpers.c b/drivers/arm/gic/v3/gicv3_helpers.c index d5aaf9696..09fa6786e 100644 --- a/drivers/arm/gic/v3/gicv3_helpers.c +++ b/drivers/arm/gic/v3/gicv3_helpers.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -31,8 +31,8 @@ void gicv3_rdistif_mark_core_awake(uintptr_t gicr_base) gicr_write_waker(gicr_base, gicr_read_waker(gicr_base) & ~WAKER_PS_BIT); /* Wait till the WAKER_CA_BIT changes to 0 */ - while ((gicr_read_waker(gicr_base) & WAKER_CA_BIT) != 0U) - ; + while ((gicr_read_waker(gicr_base) & WAKER_CA_BIT) != 0U) { + } } /****************************************************************************** @@ -45,11 +45,10 @@ void gicv3_rdistif_mark_core_asleep(uintptr_t gicr_base) gicr_write_waker(gicr_base, gicr_read_waker(gicr_base) | WAKER_PS_BIT); /* Wait till the WAKER_CA_BIT changes to 1 */ - while ((gicr_read_waker(gicr_base) & WAKER_CA_BIT) == 0U) - ; + while ((gicr_read_waker(gicr_base) & WAKER_CA_BIT) == 0U) { + } } - /******************************************************************************* * This function probes the Redistributor frames when the driver is initialised * and saves their base addresses. These base addresses are used later to @@ -84,47 +83,78 @@ void gicv3_rdistif_base_addrs_probe(uintptr_t *rdistif_base_addrs, TYPER_PROC_NUM_MASK; } - if (proc_num < rdistif_num) + if (proc_num < rdistif_num) { rdistif_base_addrs[proc_num] = rdistif_base; + } rdistif_base += (1U << GICR_PCPUBASE_SHIFT); } while ((typer_val & TYPER_LAST_BIT) == 0U); } /******************************************************************************* - * Helper function to configure the default attributes of SPIs. + * Helper function to configure the default attributes of (E)SPIs. ******************************************************************************/ void gicv3_spis_config_defaults(uintptr_t gicd_base) { - unsigned int index, num_ints; + unsigned int i, num_ints; +#if GIC_EXT_INTID + unsigned int num_eints; +#endif + unsigned int typer_reg = gicd_read_typer(gicd_base); + + /* Maximum SPI INTID is 32 * (GICD_TYPER.ITLinesNumber + 1) - 1 */ + num_ints = ((typer_reg & TYPER_IT_LINES_NO_MASK) + 1U) << 5; + + /* Treat all (E)SPIs as G1NS by default. We do 32 at a time. */ + for (i = MIN_SPI_ID; i < num_ints; i += (1U << IGROUPR_SHIFT)) { + gicd_write_igroupr(gicd_base, i, ~0U); + } - num_ints = gicd_read_typer(gicd_base); - num_ints &= TYPER_IT_LINES_NO_MASK; - num_ints = (num_ints + 1U) << 5; +#if GIC_EXT_INTID + /* Check if extended SPI range is implemented */ + if ((typer_reg & TYPER_ESPI) != 0U) { + /* + * Maximum ESPI INTID is 32 * (GICD_TYPER.ESPI_range + 1) + 4095 + */ + num_eints = ((((typer_reg >> TYPER_ESPI_RANGE_SHIFT) & + TYPER_ESPI_RANGE_MASK) + 1U) << 5) + MIN_ESPI_ID - 1; - /* - * Treat all SPIs as G1NS by default. The number of interrupts is - * calculated as 32 * (IT_LINES + 1). We do 32 at a time. - */ - for (index = MIN_SPI_ID; index < num_ints; index += 32U) - gicd_write_igroupr(gicd_base, index, ~0U); + for (i = MIN_ESPI_ID; i < num_eints; + i += (1U << IGROUPR_SHIFT)) { + gicd_write_igroupr(gicd_base, i, ~0U); + } + } else { + num_eints = 0U; + } +#endif - /* Setup the default SPI priorities doing four at a time */ - for (index = MIN_SPI_ID; index < num_ints; index += 4U) - gicd_write_ipriorityr(gicd_base, - index, - GICD_IPRIORITYR_DEF_VAL); + /* Setup the default (E)SPI priorities doing four at a time */ + for (i = MIN_SPI_ID; i < num_ints; i += (1U << IPRIORITYR_SHIFT)) { + gicd_write_ipriorityr(gicd_base, i, GICD_IPRIORITYR_DEF_VAL); + } +#if GIC_EXT_INTID + for (i = MIN_ESPI_ID; i < num_eints; + i += (1U << IPRIORITYR_SHIFT)) { + gicd_write_ipriorityr(gicd_base, i, GICD_IPRIORITYR_DEF_VAL); + } +#endif /* - * Treat all SPIs as level triggered by default, write 16 at - * a time + * Treat all (E)SPIs as level triggered by default, write 16 at a time */ - for (index = MIN_SPI_ID; index < num_ints; index += 16U) - gicd_write_icfgr(gicd_base, index, 0U); + for (i = MIN_SPI_ID; i < num_ints; i += (1U << ICFGR_SHIFT)) { + gicd_write_icfgr(gicd_base, i, 0U); + } + +#if GIC_EXT_INTID + for (i = MIN_ESPI_ID; i < num_eints; i += (1U << ICFGR_SHIFT)) { + gicd_write_icfgr(gicd_base, i, 0U); + } +#endif } /******************************************************************************* - * Helper function to configure properties of secure SPIs + * Helper function to configure properties of secure (E)SPIs ******************************************************************************/ unsigned int gicv3_secure_spis_config_props(uintptr_t gicd_base, const interrupt_prop_t *interrupt_props, @@ -136,80 +166,108 @@ unsigned int gicv3_secure_spis_config_props(uintptr_t gicd_base, unsigned int ctlr_enable = 0U; /* Make sure there's a valid property array */ - if (interrupt_props_num > 0U) + if (interrupt_props_num > 0U) { assert(interrupt_props != NULL); + } for (i = 0U; i < interrupt_props_num; i++) { current_prop = &interrupt_props[i]; - if (current_prop->intr_num < MIN_SPI_ID) + unsigned int intr_num = current_prop->intr_num; + + /* Skip SGI, (E)PPI and LPI interrupts */ + if (!IS_SPI(intr_num)) { continue; + } /* Configure this interrupt as a secure interrupt */ - gicd_clr_igroupr(gicd_base, current_prop->intr_num); + gicd_clr_igroupr(gicd_base, intr_num); /* Configure this interrupt as G0 or a G1S interrupt */ assert((current_prop->intr_grp == INTR_GROUP0) || (current_prop->intr_grp == INTR_GROUP1S)); + if (current_prop->intr_grp == INTR_GROUP1S) { - gicd_set_igrpmodr(gicd_base, current_prop->intr_num); + gicd_set_igrpmodr(gicd_base, intr_num); ctlr_enable |= CTLR_ENABLE_G1S_BIT; } else { - gicd_clr_igrpmodr(gicd_base, current_prop->intr_num); + gicd_clr_igrpmodr(gicd_base, intr_num); ctlr_enable |= CTLR_ENABLE_G0_BIT; } /* Set interrupt configuration */ - gicd_set_icfgr(gicd_base, current_prop->intr_num, - current_prop->intr_cfg); + gicd_set_icfgr(gicd_base, intr_num, current_prop->intr_cfg); /* Set the priority of this interrupt */ - gicd_set_ipriorityr(gicd_base, current_prop->intr_num, - current_prop->intr_pri); + gicd_set_ipriorityr(gicd_base, intr_num, + current_prop->intr_pri); - /* Target SPIs to the primary CPU */ + /* Target (E)SPIs to the primary CPU */ gic_affinity_val = gicd_irouter_val_from_mpidr(read_mpidr(), 0U); - gicd_write_irouter(gicd_base, current_prop->intr_num, - gic_affinity_val); + gicd_write_irouter(gicd_base, intr_num, + gic_affinity_val); /* Enable this interrupt */ - gicd_set_isenabler(gicd_base, current_prop->intr_num); + gicd_set_isenabler(gicd_base, intr_num); } return ctlr_enable; } /******************************************************************************* - * Helper function to configure the default attributes of SPIs. + * Helper function to configure the default attributes of (E)SPIs ******************************************************************************/ void gicv3_ppi_sgi_config_defaults(uintptr_t gicr_base) { - unsigned int index; - + unsigned int i, ppi_regs_num, regs_num; + +#if GIC_EXT_INTID + /* Calculate number of PPI registers */ + ppi_regs_num = (unsigned int)((gicr_read_typer(gicr_base) >> + TYPER_PPI_NUM_SHIFT) & TYPER_PPI_NUM_MASK) + 1; + /* All other values except PPInum [0-2] are reserved */ + if (ppi_regs_num > 3U) { + ppi_regs_num = 1U; + } +#else + ppi_regs_num = 1U; +#endif /* - * Disable all SGIs (imp. def.)/PPIs before configuring them. This is a - * more scalable approach as it avoids clearing the enable bits in the - * GICD_CTLR + * Disable all SGIs (imp. def.)/(E)PPIs before configuring them. + * This is a more scalable approach as it avoids clearing + * the enable bits in the GICD_CTLR. */ - gicr_write_icenabler0(gicr_base, ~0U); + for (i = 0U; i < ppi_regs_num; ++i) { + gicr_write_icenabler(gicr_base, i, ~0U); + } + + /* Wait for pending writes to GICR_ICENABLER */ gicr_wait_for_pending_write(gicr_base); - /* Treat all SGIs/PPIs as G1NS by default. */ - gicr_write_igroupr0(gicr_base, ~0U); + /* 32 interrupt IDs per GICR_IGROUPR register */ + for (i = 0U; i < ppi_regs_num; ++i) { + /* Treat all SGIs/(E)PPIs as G1NS by default */ + gicr_write_igroupr(gicr_base, i, ~0U); + } - /* Setup the default PPI/SGI priorities doing four at a time */ - for (index = 0U; index < MIN_SPI_ID; index += 4U) - gicr_write_ipriorityr(gicr_base, - index, - GICD_IPRIORITYR_DEF_VAL); + /* 4 interrupt IDs per GICR_IPRIORITYR register */ + regs_num = ppi_regs_num << 3; + for (i = 0U; i < regs_num; ++i) { + /* Setup the default (E)PPI/SGI priorities doing 4 at a time */ + gicr_write_ipriorityr(gicr_base, i, GICD_IPRIORITYR_DEF_VAL); + } - /* Configure all PPIs as level triggered by default */ - gicr_write_icfgr1(gicr_base, 0U); + /* 16 interrupt IDs per GICR_ICFGR register */ + regs_num = ppi_regs_num << 1; + for (i = (MIN_PPI_ID >> ICFGR_SHIFT); i < regs_num; ++i) { + /* Configure all (E)PPIs as level triggered by default */ + gicr_write_icfgr(gicr_base, i, 0U); + } } /******************************************************************************* - * Helper function to configure properties of secure G0 and G1S PPIs and SGIs. + * Helper function to configure properties of secure G0 and G1S (E)PPIs and SGIs ******************************************************************************/ unsigned int gicv3_secure_ppi_sgi_config_props(uintptr_t gicr_base, const interrupt_prop_t *interrupt_props, @@ -220,45 +278,50 @@ unsigned int gicv3_secure_ppi_sgi_config_props(uintptr_t gicr_base, unsigned int ctlr_enable = 0U; /* Make sure there's a valid property array */ - if (interrupt_props_num > 0U) + if (interrupt_props_num > 0U) { assert(interrupt_props != NULL); + } for (i = 0U; i < interrupt_props_num; i++) { current_prop = &interrupt_props[i]; - if (current_prop->intr_num >= MIN_SPI_ID) + unsigned int intr_num = current_prop->intr_num; + + /* Skip (E)SPI interrupt */ + if (!IS_SGI_PPI(intr_num)) { continue; + } /* Configure this interrupt as a secure interrupt */ - gicr_clr_igroupr0(gicr_base, current_prop->intr_num); + gicr_clr_igroupr(gicr_base, intr_num); /* Configure this interrupt as G0 or a G1S interrupt */ assert((current_prop->intr_grp == INTR_GROUP0) || - (current_prop->intr_grp == INTR_GROUP1S)); + (current_prop->intr_grp == INTR_GROUP1S)); + if (current_prop->intr_grp == INTR_GROUP1S) { - gicr_set_igrpmodr0(gicr_base, current_prop->intr_num); + gicr_set_igrpmodr(gicr_base, intr_num); ctlr_enable |= CTLR_ENABLE_G1S_BIT; } else { - gicr_clr_igrpmodr0(gicr_base, current_prop->intr_num); + gicr_clr_igrpmodr(gicr_base, intr_num); ctlr_enable |= CTLR_ENABLE_G0_BIT; } /* Set the priority of this interrupt */ - gicr_set_ipriorityr(gicr_base, current_prop->intr_num, - current_prop->intr_pri); + gicr_set_ipriorityr(gicr_base, intr_num, + current_prop->intr_pri); /* - * Set interrupt configuration for PPIs. Configuration for SGIs - * are ignored. + * Set interrupt configuration for (E)PPIs. + * Configurations for SGIs 0-15 are ignored. */ - if ((current_prop->intr_num >= MIN_PPI_ID) && - (current_prop->intr_num < MIN_SPI_ID)) { - gicr_set_icfgr1(gicr_base, current_prop->intr_num, + if (intr_num >= MIN_PPI_ID) { + gicr_set_icfgr(gicr_base, intr_num, current_prop->intr_cfg); } /* Enable this interrupt */ - gicr_set_isenabler0(gicr_base, current_prop->intr_num); + gicr_set_isenabler(gicr_base, intr_num); } return ctlr_enable; diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c index a672b18f3..aefaa3595 100644 --- a/drivers/arm/gic/v3/gicv3_main.c +++ b/drivers/arm/gic/v3/gicv3_main.c @@ -31,26 +31,62 @@ static spinlock_t gic_lock; #pragma weak gicv3_rdistif_off #pragma weak gicv3_rdistif_on +/* Check interrupt ID for SGI/(E)PPI and (E)SPIs */ +static bool is_sgi_ppi(unsigned int id); + +/* + * Helper macros to save and restore GICR and GICD registers + * corresponding to their numbers to and from the context + */ +#define RESTORE_GICR_REG(base, ctx, name, i) \ + gicr_write_##name((base), (i), (ctx)->gicr_##name[(i)]) + +#define SAVE_GICR_REG(base, ctx, name, i) \ + (ctx)->gicr_##name[(i)] = gicr_read_##name((base), (i)) /* Helper macros to save and restore GICD registers to and from the context */ #define RESTORE_GICD_REGS(base, ctx, intr_num, reg, REG) \ do { \ - for (unsigned int int_id = MIN_SPI_ID; int_id < (intr_num); \ - int_id += (1U << REG##_SHIFT)) { \ - gicd_write_##reg(base, int_id, \ - ctx->gicd_##reg[(int_id - MIN_SPI_ID) >> REG##_SHIFT]); \ + for (unsigned int int_id = MIN_SPI_ID; int_id < (intr_num);\ + int_id += (1U << REG##R_SHIFT)) { \ + gicd_write_##reg((base), int_id, \ + (ctx)->gicd_##reg[(int_id - MIN_SPI_ID) >> \ + REG##R_SHIFT]); \ } \ } while (false) #define SAVE_GICD_REGS(base, ctx, intr_num, reg, REG) \ do { \ - for (unsigned int int_id = MIN_SPI_ID; int_id < (intr_num); \ - int_id += (1U << REG##_SHIFT)) { \ - ctx->gicd_##reg[(int_id - MIN_SPI_ID) >> REG##_SHIFT] =\ - gicd_read_##reg(base, int_id); \ + for (unsigned int int_id = MIN_SPI_ID; int_id < (intr_num);\ + int_id += (1U << REG##R_SHIFT)) { \ + (ctx)->gicd_##reg[(int_id - MIN_SPI_ID) >> \ + REG##R_SHIFT] = gicd_read_##reg((base), int_id); \ } \ } while (false) +#if GIC_EXT_INTID +#define RESTORE_GICD_EREGS(base, ctx, intr_num, reg, REG) \ + do { \ + for (unsigned int int_id = MIN_ESPI_ID; int_id < (intr_num);\ + int_id += (1U << REG##R_SHIFT)) { \ + gicd_write_##reg((base), int_id, \ + (ctx)->gicd_##reg[(int_id - (MIN_ESPI_ID - MIN_SPI_ID))\ + >> REG##R_SHIFT]); \ + } \ + } while (false) + +#define SAVE_GICD_EREGS(base, ctx, intr_num, reg, REG) \ + do { \ + for (unsigned int int_id = MIN_ESPI_ID; int_id < (intr_num);\ + int_id += (1U << REG##R_SHIFT)) { \ + (ctx)->gicd_##reg[(int_id - (MIN_ESPI_ID - MIN_SPI_ID))\ + >> REG##R_SHIFT] = gicd_read_##reg((base), int_id);\ + } \ + } while (false) +#else +#define SAVE_GICD_EREGS(base, ctx, intr_num, reg, REG) +#define RESTORE_GICD_EREGS(base, ctx, intr_num, reg, REG) +#endif /* GIC_EXT_INTID */ /******************************************************************************* * This function initialises the ARM GICv3 driver in EL3 with provided platform @@ -80,7 +116,7 @@ void __init gicv3_driver_init(const gicv3_driver_data_t *plat_driver_data) (ID_AA64PFR0_GIC_MASK << ID_AA64PFR0_GIC_SHIFT)) != 0U); #endif /* !__aarch64__ */ - /* The GIC version should be 3.0 */ + /* The GIC version should be 3 */ gic_version = gicd_read_pidr2(plat_driver_data->gicd_base); gic_version >>= PIDR2_ARCH_REV_SHIFT; gic_version &= PIDR2_ARCH_REV_MASK; @@ -133,7 +169,6 @@ void __init gicv3_driver_init(const gicv3_driver_data_t *plat_driver_data) INFO("GICv3 with%s legacy support detected." " ARM GICv3 driver initialized in EL3\n", (gicv2_compat == 0U) ? "" : "out"); - } /******************************************************************************* @@ -142,7 +177,7 @@ void __init gicv3_driver_init(const gicv3_driver_data_t *plat_driver_data) ******************************************************************************/ void __init gicv3_distif_init(void) { - unsigned int bitmap = 0; + unsigned int bitmap; assert(gicv3_driver_data != NULL); assert(gicv3_driver_data->gicd_base != 0U); @@ -164,7 +199,7 @@ void __init gicv3_distif_init(void) gicd_set_ctlr(gicv3_driver_data->gicd_base, CTLR_ARE_S_BIT | CTLR_ARE_NS_BIT, RWP_TRUE); - /* Set the default attribute of all SPIs */ + /* Set the default attribute of all (E)SPIs */ gicv3_spis_config_defaults(gicv3_driver_data->gicd_base); bitmap = gicv3_secure_spis_config_props( @@ -172,7 +207,7 @@ void __init gicv3_distif_init(void) gicv3_driver_data->interrupt_props, gicv3_driver_data->interrupt_props_num); - /* Enable the secure SPIs now that they have been configured */ + /* Enable the secure (E)SPIs now that they have been configured */ gicd_set_ctlr(gicv3_driver_data->gicd_base, bitmap, RWP_TRUE); } @@ -184,7 +219,7 @@ void __init gicv3_distif_init(void) void gicv3_rdistif_init(unsigned int proc_num) { uintptr_t gicr_base; - unsigned int bitmap = 0U; + unsigned int bitmap; uint32_t ctlr; assert(gicv3_driver_data != NULL); @@ -203,7 +238,7 @@ void gicv3_rdistif_init(unsigned int proc_num) gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; assert(gicr_base != 0U); - /* Set the default attribute of all SGIs and PPIs */ + /* Set the default attribute of all SGIs and (E)PPIs */ gicv3_ppi_sgi_config_defaults(gicr_base); bitmap = gicv3_secure_ppi_sgi_config_props(gicr_base, @@ -211,8 +246,9 @@ void gicv3_rdistif_init(unsigned int proc_num) gicv3_driver_data->interrupt_props_num); /* Enable interrupt groups as required, if not already */ - if ((ctlr & bitmap) != bitmap) + if ((ctlr & bitmap) != bitmap) { gicd_set_ctlr(gicv3_driver_data->gicd_base, bitmap, RWP_TRUE); + } } /******************************************************************************* @@ -220,12 +256,10 @@ void gicv3_rdistif_init(unsigned int proc_num) ******************************************************************************/ void gicv3_rdistif_off(unsigned int proc_num) { - return; } void gicv3_rdistif_on(unsigned int proc_num) { - return; } /******************************************************************************* @@ -342,8 +376,9 @@ unsigned int gicv3_get_pending_interrupt_id(void) * If the ID is special identifier corresponding to G1S or G1NS * interrupt, then read the highest pending group 1 interrupt. */ - if ((id == PENDING_G1S_INTID) || (id == PENDING_G1NS_INTID)) + if ((id == PENDING_G1S_INTID) || (id == PENDING_G1NS_INTID)) { return (uint32_t)read_icc_hppir1_el1() & HPPIR1_EL1_INTID_MASK; + } return id; } @@ -373,8 +408,7 @@ unsigned int gicv3_get_pending_interrupt_type(void) * INTR_GROUP1NS: The interrupt type is a Secure Group 1 non secure * interrupt. ******************************************************************************/ -unsigned int gicv3_get_interrupt_type(unsigned int id, - unsigned int proc_num) +unsigned int gicv3_get_interrupt_type(unsigned int id, unsigned int proc_num) { unsigned int igroup, grpmodr; uintptr_t gicr_base; @@ -387,15 +421,19 @@ unsigned int gicv3_get_interrupt_type(unsigned int id, assert(proc_num < gicv3_driver_data->rdistif_num); /* All LPI interrupts are Group 1 non secure */ - if (id >= MIN_LPI_ID) + if (id >= MIN_LPI_ID) { return INTR_GROUP1NS; + } - if (id < MIN_SPI_ID) { + /* Check interrupt ID */ + if (is_sgi_ppi(id)) { + /* SGIs: 0-15, PPIs: 16-31, EPPIs: 1056-1119 */ assert(gicv3_driver_data->rdistif_base_addrs != NULL); gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; - igroup = gicr_get_igroupr0(gicr_base, id); - grpmodr = gicr_get_igrpmodr0(gicr_base, id); + igroup = gicr_get_igroupr(gicr_base, id); + grpmodr = gicr_get_igrpmodr(gicr_base, id); } else { + /* SPIs: 32-1019, ESPIs: 4096-5119 */ assert(gicv3_driver_data->gicd_base != 0U); igroup = gicd_get_igroupr(gicv3_driver_data->gicd_base, id); grpmodr = gicd_get_igrpmodr(gicv3_driver_data->gicd_base, id); @@ -405,12 +443,14 @@ unsigned int gicv3_get_interrupt_type(unsigned int id, * If the IGROUP bit is set, then it is a Group 1 Non secure * interrupt */ - if (igroup != 0U) + if (igroup != 0U) { return INTR_GROUP1NS; + } /* If the GRPMOD bit is set, then it is a Group 1 Secure interrupt */ - if (grpmodr != 0U) + if (grpmodr != 0U) { return INTR_GROUP1S; + } /* Else it is a Group 0 Secure interrupt */ return INTR_GROUP0; @@ -427,7 +467,8 @@ unsigned int gicv3_get_interrupt_type(unsigned int id, * * This function must be invoked after the GIC CPU interface is disabled. *****************************************************************************/ -void gicv3_its_save_disable(uintptr_t gits_base, gicv3_its_ctx_t * const its_ctx) +void gicv3_its_save_disable(uintptr_t gits_base, + gicv3_its_ctx_t * const its_ctx) { unsigned int i; @@ -439,8 +480,7 @@ void gicv3_its_save_disable(uintptr_t gits_base, gicv3_its_ctx_t * const its_ctx its_ctx->gits_ctlr = gits_read_ctlr(gits_base); /* Disable the ITS */ - gits_write_ctlr(gits_base, its_ctx->gits_ctlr & - (~GITS_CTLR_ENABLED_BIT)); + gits_write_ctlr(gits_base, its_ctx->gits_ctlr & ~GITS_CTLR_ENABLED_BIT); /* Wait for quiescent state */ gits_wait_for_quiescent_bit(gits_base); @@ -448,8 +488,9 @@ void gicv3_its_save_disable(uintptr_t gits_base, gicv3_its_ctx_t * const its_ctx its_ctx->gits_cbaser = gits_read_cbaser(gits_base); its_ctx->gits_cwriter = gits_read_cwriter(gits_base); - for (i = 0; i < ARRAY_SIZE(its_ctx->gits_baser); i++) + for (i = 0U; i < ARRAY_SIZE(its_ctx->gits_baser); i++) { its_ctx->gits_baser[i] = gits_read_baser(gits_base, i); + } } /***************************************************************************** @@ -460,7 +501,8 @@ void gicv3_its_save_disable(uintptr_t gits_base, gicv3_its_ctx_t * const its_ctx * * This must be invoked before the GIC CPU interface is enabled. *****************************************************************************/ -void gicv3_its_restore(uintptr_t gits_base, const gicv3_its_ctx_t * const its_ctx) +void gicv3_its_restore(uintptr_t gits_base, + const gicv3_its_ctx_t * const its_ctx) { unsigned int i; @@ -476,22 +518,23 @@ void gicv3_its_restore(uintptr_t gits_base, const gicv3_its_ctx_t * const its_ct gits_write_cbaser(gits_base, its_ctx->gits_cbaser); gits_write_cwriter(gits_base, its_ctx->gits_cwriter); - for (i = 0; i < ARRAY_SIZE(its_ctx->gits_baser); i++) + for (i = 0U; i < ARRAY_SIZE(its_ctx->gits_baser); i++) { gits_write_baser(gits_base, i, its_ctx->gits_baser[i]); + } /* Restore the ITS CTLR but leave the ITS disabled */ - gits_write_ctlr(gits_base, its_ctx->gits_ctlr & - (~GITS_CTLR_ENABLED_BIT)); + gits_write_ctlr(gits_base, its_ctx->gits_ctlr & ~GITS_CTLR_ENABLED_BIT); } /***************************************************************************** * Function to save the GIC Redistributor register context. This function * must be invoked after CPU interface disable and prior to Distributor save. *****************************************************************************/ -void gicv3_rdistif_save(unsigned int proc_num, gicv3_redist_ctx_t * const rdist_ctx) +void gicv3_rdistif_save(unsigned int proc_num, + gicv3_redist_ctx_t * const rdist_ctx) { uintptr_t gicr_base; - unsigned int int_id; + unsigned int i, ppi_regs_num, regs_num; assert(gicv3_driver_data != NULL); assert(proc_num < gicv3_driver_data->rdistif_num); @@ -501,6 +544,17 @@ void gicv3_rdistif_save(unsigned int proc_num, gicv3_redist_ctx_t * const rdist_ gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; +#if GIC_EXT_INTID + /* Calculate number of PPI registers */ + ppi_regs_num = (unsigned int)((gicr_read_typer(gicr_base) >> + TYPER_PPI_NUM_SHIFT) & TYPER_PPI_NUM_MASK) + 1; + /* All other values except PPInum [0-2] are reserved */ + if (ppi_regs_num > 3U) { + ppi_regs_num = 1U; + } +#else + ppi_regs_num = 1U; +#endif /* * Wait for any write to GICR_CTLR to complete before trying to save any * state. @@ -512,20 +566,28 @@ void gicv3_rdistif_save(unsigned int proc_num, gicv3_redist_ctx_t * const rdist_ rdist_ctx->gicr_propbaser = gicr_read_propbaser(gicr_base); rdist_ctx->gicr_pendbaser = gicr_read_pendbaser(gicr_base); - rdist_ctx->gicr_igroupr0 = gicr_read_igroupr0(gicr_base); - rdist_ctx->gicr_isenabler0 = gicr_read_isenabler0(gicr_base); - rdist_ctx->gicr_ispendr0 = gicr_read_ispendr0(gicr_base); - rdist_ctx->gicr_isactiver0 = gicr_read_isactiver0(gicr_base); - rdist_ctx->gicr_icfgr0 = gicr_read_icfgr0(gicr_base); - rdist_ctx->gicr_icfgr1 = gicr_read_icfgr1(gicr_base); - rdist_ctx->gicr_igrpmodr0 = gicr_read_igrpmodr0(gicr_base); - rdist_ctx->gicr_nsacr = gicr_read_nsacr(gicr_base); - for (int_id = MIN_SGI_ID; int_id < TOTAL_PCPU_INTR_NUM; - int_id += (1U << IPRIORITYR_SHIFT)) { - rdist_ctx->gicr_ipriorityr[(int_id - MIN_SGI_ID) >> IPRIORITYR_SHIFT] = - gicr_read_ipriorityr(gicr_base, int_id); + /* 32 interrupt IDs per register */ + for (i = 0U; i < ppi_regs_num; ++i) { + SAVE_GICR_REG(gicr_base, rdist_ctx, igroupr, i); + SAVE_GICR_REG(gicr_base, rdist_ctx, isenabler, i); + SAVE_GICR_REG(gicr_base, rdist_ctx, ispendr, i); + SAVE_GICR_REG(gicr_base, rdist_ctx, isactiver, i); + SAVE_GICR_REG(gicr_base, rdist_ctx, igrpmodr, i); } + /* 16 interrupt IDs per GICR_ICFGR register */ + regs_num = ppi_regs_num << 1; + for (i = 0U; i < regs_num; ++i) { + SAVE_GICR_REG(gicr_base, rdist_ctx, icfgr, i); + } + + rdist_ctx->gicr_nsacr = gicr_read_nsacr(gicr_base); + + /* 4 interrupt IDs per GICR_IPRIORITYR register */ + regs_num = ppi_regs_num << 3; + for (i = 0U; i < regs_num; ++i) { + SAVE_GICR_REG(gicr_base, rdist_ctx, ipriorityr, i); + } /* * Call the pre-save hook that implements the IMP DEF sequence that may @@ -546,7 +608,7 @@ void gicv3_rdistif_init_restore(unsigned int proc_num, const gicv3_redist_ctx_t * const rdist_ctx) { uintptr_t gicr_base; - unsigned int int_id; + unsigned int i, ppi_regs_num, regs_num; assert(gicv3_driver_data != NULL); assert(proc_num < gicv3_driver_data->rdistif_num); @@ -556,6 +618,17 @@ void gicv3_rdistif_init_restore(unsigned int proc_num, gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; +#if GIC_EXT_INTID + /* Calculate number of PPI registers */ + ppi_regs_num = (unsigned int)((gicr_read_typer(gicr_base) >> + TYPER_PPI_NUM_SHIFT) & TYPER_PPI_NUM_MASK) + 1; + /* All other values except PPInum [0-2] are reserved */ + if (ppi_regs_num > 3U) { + ppi_regs_num = 1U; + } +#else + ppi_regs_num = 1U; +#endif /* Power on redistributor */ gicv3_rdistif_on(proc_num); @@ -567,11 +640,14 @@ void gicv3_rdistif_init_restore(unsigned int proc_num, gicv3_distif_post_restore(proc_num); /* - * Disable all SGIs (imp. def.)/PPIs before configuring them. This is a - * more scalable approach as it avoids clearing the enable bits in the - * GICD_CTLR + * Disable all SGIs (imp. def.)/(E)PPIs before configuring them. + * This is a more scalable approach as it avoids clearing the enable + * bits in the GICD_CTLR. */ - gicr_write_icenabler0(gicr_base, ~0U); + for (i = 0U; i < ppi_regs_num; ++i) { + gicr_write_icenabler(gicr_base, i, ~0U); + } + /* Wait for pending writes to GICR_ICENABLER */ gicr_wait_for_pending_write(gicr_base); @@ -586,30 +662,44 @@ void gicv3_rdistif_init_restore(unsigned int proc_num, gicr_write_propbaser(gicr_base, rdist_ctx->gicr_propbaser); gicr_write_pendbaser(gicr_base, rdist_ctx->gicr_pendbaser); - gicr_write_igroupr0(gicr_base, rdist_ctx->gicr_igroupr0); + /* 32 interrupt IDs per register */ + for (i = 0U; i < ppi_regs_num; ++i) { + RESTORE_GICR_REG(gicr_base, rdist_ctx, igroupr, i); + RESTORE_GICR_REG(gicr_base, rdist_ctx, igrpmodr, i); + } + + /* 4 interrupt IDs per GICR_IPRIORITYR register */ + regs_num = ppi_regs_num << 3; + for (i = 0U; i < regs_num; ++i) { + RESTORE_GICR_REG(gicr_base, rdist_ctx, ipriorityr, i); + } - for (int_id = MIN_SGI_ID; int_id < TOTAL_PCPU_INTR_NUM; - int_id += (1U << IPRIORITYR_SHIFT)) { - gicr_write_ipriorityr(gicr_base, int_id, - rdist_ctx->gicr_ipriorityr[ - (int_id - MIN_SGI_ID) >> IPRIORITYR_SHIFT]); + /* 16 interrupt IDs per GICR_ICFGR register */ + regs_num = ppi_regs_num << 1; + for (i = 0U; i < regs_num; ++i) { + RESTORE_GICR_REG(gicr_base, rdist_ctx, icfgr, i); } - gicr_write_icfgr0(gicr_base, rdist_ctx->gicr_icfgr0); - gicr_write_icfgr1(gicr_base, rdist_ctx->gicr_icfgr1); - gicr_write_igrpmodr0(gicr_base, rdist_ctx->gicr_igrpmodr0); gicr_write_nsacr(gicr_base, rdist_ctx->gicr_nsacr); - /* Restore after group and priorities are set */ - gicr_write_ispendr0(gicr_base, rdist_ctx->gicr_ispendr0); - gicr_write_isactiver0(gicr_base, rdist_ctx->gicr_isactiver0); + /* Restore after group and priorities are set. + * 32 interrupt IDs per register + */ + for (i = 0U; i < ppi_regs_num; ++i) { + RESTORE_GICR_REG(gicr_base, rdist_ctx, ispendr, i); + RESTORE_GICR_REG(gicr_base, rdist_ctx, isactiver, i); + } /* * Wait for all writes to the Distributor to complete before enabling - * the SGI and PPIs. + * the SGI and (E)PPIs. */ gicr_wait_for_upstream_pending_write(gicr_base); - gicr_write_isenabler0(gicr_base, rdist_ctx->gicr_isenabler0); + + /* 32 interrupt IDs per GICR_ISENABLER register */ + for (i = 0U; i < ppi_regs_num; ++i) { + RESTORE_GICR_REG(gicr_base, rdist_ctx, isenabler, i); + } /* * Restore GICR_CTLR.Enable_LPIs bit and wait for pending writes in case @@ -627,7 +717,10 @@ void gicv3_rdistif_init_restore(unsigned int proc_num, *****************************************************************************/ void gicv3_distif_save(gicv3_dist_ctx_t * const dist_ctx) { - unsigned int num_ints; + unsigned int typer_reg, num_ints; +#if GIC_EXT_INTID + unsigned int num_eints; +#endif assert(gicv3_driver_data != NULL); assert(gicv3_driver_data->gicd_base != 0U); @@ -636,14 +729,28 @@ void gicv3_distif_save(gicv3_dist_ctx_t * const dist_ctx) uintptr_t gicd_base = gicv3_driver_data->gicd_base; - num_ints = gicd_read_typer(gicd_base); - num_ints &= TYPER_IT_LINES_NO_MASK; - num_ints = (num_ints + 1U) << 5; + typer_reg = gicd_read_typer(gicd_base); + + /* Maximum SPI INTID is 32 * (GICD_TYPER.ITLinesNumber + 1) - 1 */ + num_ints = ((typer_reg & TYPER_IT_LINES_NO_MASK) + 1U) << 5; /* Filter out special INTIDs 1020-1023 */ - if (num_ints > (MAX_SPI_ID + 1U)) + if (num_ints > (MAX_SPI_ID + 1U)) { num_ints = MAX_SPI_ID + 1U; + } +#if GIC_EXT_INTID + /* Check if extended SPI range is implemented */ + if ((typer_reg & TYPER_ESPI) != 0U) { + /* + * Maximum ESPI INTID is 32 * (GICD_TYPER.ESPI_range + 1) + 4095 + */ + num_eints = ((((typer_reg >> TYPER_ESPI_RANGE_SHIFT) & + TYPER_ESPI_RANGE_MASK) + 1U) << 5) + MIN_ESPI_ID - 1; + } else { + num_eints = 0U; + } +#endif /* Wait for pending write to complete */ gicd_wait_for_pending_write(gicd_base); @@ -651,31 +758,58 @@ void gicv3_distif_save(gicv3_dist_ctx_t * const dist_ctx) dist_ctx->gicd_ctlr = gicd_read_ctlr(gicd_base); /* Save GICD_IGROUPR for INTIDs 32 - 1019 */ - SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, igroupr, IGROUPR); + SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, igroupr, IGROUP); + + /* Save GICD_IGROUPRE for INTIDs 4096 - 5119 */ + SAVE_GICD_EREGS(gicd_base, dist_ctx, num_eints, igroupr, IGROUP); /* Save GICD_ISENABLER for INT_IDs 32 - 1019 */ - SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, isenabler, ISENABLER); + SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, isenabler, ISENABLE); + + /* Save GICD_ISENABLERE for INT_IDs 4096 - 5119 */ + SAVE_GICD_EREGS(gicd_base, dist_ctx, num_eints, isenabler, ISENABLE); /* Save GICD_ISPENDR for INTIDs 32 - 1019 */ - SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, ispendr, ISPENDR); + SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, ispendr, ISPEND); + + /* Save GICD_ISPENDRE for INTIDs 4096 - 5119 */ + SAVE_GICD_EREGS(gicd_base, dist_ctx, num_eints, ispendr, ISPEND); /* Save GICD_ISACTIVER for INTIDs 32 - 1019 */ - SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, isactiver, ISACTIVER); + SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, isactiver, ISACTIVE); + + /* Save GICD_ISACTIVERE for INTIDs 4096 - 5119 */ + SAVE_GICD_EREGS(gicd_base, dist_ctx, num_eints, isactiver, ISACTIVE); /* Save GICD_IPRIORITYR for INTIDs 32 - 1019 */ - SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, ipriorityr, IPRIORITYR); + SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, ipriorityr, IPRIORITY); + + /* Save GICD_IPRIORITYRE for INTIDs 4096 - 5119 */ + SAVE_GICD_EREGS(gicd_base, dist_ctx, num_eints, ipriorityr, IPRIORITY); /* Save GICD_ICFGR for INTIDs 32 - 1019 */ - SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, icfgr, ICFGR); + SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, icfgr, ICFG); + + /* Save GICD_ICFGRE for INTIDs 4096 - 5119 */ + SAVE_GICD_EREGS(gicd_base, dist_ctx, num_eints, icfgr, ICFG); /* Save GICD_IGRPMODR for INTIDs 32 - 1019 */ - SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, igrpmodr, IGRPMODR); + SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, igrpmodr, IGRPMOD); + + /* Save GICD_IGRPMODRE for INTIDs 4096 - 5119 */ + SAVE_GICD_EREGS(gicd_base, dist_ctx, num_eints, igrpmodr, IGRPMOD); /* Save GICD_NSACR for INTIDs 32 - 1019 */ - SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, nsacr, NSACR); + SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, nsacr, NSAC); + + /* Save GICD_NSACRE for INTIDs 4096 - 5119 */ + SAVE_GICD_EREGS(gicd_base, dist_ctx, num_eints, nsacr, NSAC); /* Save GICD_IROUTER for INTIDs 32 - 1019 */ - SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, irouter, IROUTER); + SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, irouter, IROUTE); + + /* Save GICD_IROUTERE for INTIDs 4096 - 5119 */ + SAVE_GICD_EREGS(gicd_base, dist_ctx, num_eints, irouter, IROUTE); /* * GICD_ITARGETSR and GICD_SPENDSGIR are RAZ/WI when @@ -693,7 +827,10 @@ void gicv3_distif_save(gicv3_dist_ctx_t * const dist_ctx) *****************************************************************************/ void gicv3_distif_init_restore(const gicv3_dist_ctx_t * const dist_ctx) { - unsigned int num_ints = 0U; + unsigned int typer_reg, num_ints; +#if GIC_EXT_INTID + unsigned int num_eints; +#endif assert(gicv3_driver_data != NULL); assert(gicv3_driver_data->gicd_base != 0U); @@ -716,50 +853,90 @@ void gicv3_distif_init_restore(const gicv3_dist_ctx_t * const dist_ctx) /* Set the ARE_S and ARE_NS bit now that interrupts have been disabled */ gicd_set_ctlr(gicd_base, CTLR_ARE_S_BIT | CTLR_ARE_NS_BIT, RWP_TRUE); - num_ints = gicd_read_typer(gicd_base); - num_ints &= TYPER_IT_LINES_NO_MASK; - num_ints = (num_ints + 1U) << 5; + typer_reg = gicd_read_typer(gicd_base); + + /* Maximum SPI INTID is 32 * (GICD_TYPER.ITLinesNumber + 1) - 1 */ + num_ints = ((typer_reg & TYPER_IT_LINES_NO_MASK) + 1U) << 5; /* Filter out special INTIDs 1020-1023 */ - if (num_ints > (MAX_SPI_ID + 1U)) + if (num_ints > (MAX_SPI_ID + 1U)) { num_ints = MAX_SPI_ID + 1U; + } +#if GIC_EXT_INTID + /* Check if extended SPI range is implemented */ + if ((typer_reg & TYPER_ESPI) != 0U) { + /* + * Maximum ESPI INTID is 32 * (GICD_TYPER.ESPI_range + 1) + 4095 + */ + num_eints = ((((typer_reg >> TYPER_ESPI_RANGE_SHIFT) & + TYPER_ESPI_RANGE_MASK) + 1U) << 5) + MIN_ESPI_ID - 1; + } else { + num_eints = 0U; + } +#endif /* Restore GICD_IGROUPR for INTIDs 32 - 1019 */ - RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, igroupr, IGROUPR); + RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, igroupr, IGROUP); + + /* Restore GICD_IGROUPRE for INTIDs 4096 - 5119 */ + RESTORE_GICD_EREGS(gicd_base, dist_ctx, num_eints, igroupr, IGROUP); /* Restore GICD_IPRIORITYR for INTIDs 32 - 1019 */ - RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, ipriorityr, IPRIORITYR); + RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, ipriorityr, IPRIORITY); + + /* Restore GICD_IPRIORITYRE for INTIDs 4096 - 5119 */ + RESTORE_GICD_EREGS(gicd_base, dist_ctx, num_eints, ipriorityr, IPRIORITY); /* Restore GICD_ICFGR for INTIDs 32 - 1019 */ - RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, icfgr, ICFGR); + RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, icfgr, ICFG); + + /* Restore GICD_ICFGRE for INTIDs 4096 - 5119 */ + RESTORE_GICD_EREGS(gicd_base, dist_ctx, num_eints, icfgr, ICFG); /* Restore GICD_IGRPMODR for INTIDs 32 - 1019 */ - RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, igrpmodr, IGRPMODR); + RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, igrpmodr, IGRPMOD); + + /* Restore GICD_IGRPMODRE for INTIDs 4096 - 5119 */ + RESTORE_GICD_EREGS(gicd_base, dist_ctx, num_eints, igrpmodr, IGRPMOD); /* Restore GICD_NSACR for INTIDs 32 - 1019 */ - RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, nsacr, NSACR); + RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, nsacr, NSAC); + + /* Restore GICD_NSACRE for INTIDs 4096 - 5119 */ + RESTORE_GICD_EREGS(gicd_base, dist_ctx, num_eints, nsacr, NSAC); /* Restore GICD_IROUTER for INTIDs 32 - 1019 */ - RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, irouter, IROUTER); + RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, irouter, IROUTE); + + /* Restore GICD_IROUTERE for INTIDs 4096 - 5119 */ + RESTORE_GICD_EREGS(gicd_base, dist_ctx, num_eints, irouter, IROUTE); /* - * Restore ISENABLER, ISPENDR and ISACTIVER after the interrupts are - * configured. + * Restore ISENABLER(E), ISPENDR(E) and ISACTIVER(E) after + * the interrupts are configured. */ /* Restore GICD_ISENABLER for INT_IDs 32 - 1019 */ - RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, isenabler, ISENABLER); + RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, isenabler, ISENABLE); + + /* Restore GICD_ISENABLERE for INT_IDs 4096 - 5119 */ + RESTORE_GICD_EREGS(gicd_base, dist_ctx, num_eints, isenabler, ISENABLE); /* Restore GICD_ISPENDR for INTIDs 32 - 1019 */ - RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, ispendr, ISPENDR); + RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, ispendr, ISPEND); + + /* Restore GICD_ISPENDRE for INTIDs 4096 - 5119 */ + RESTORE_GICD_EREGS(gicd_base, dist_ctx, num_eints, ispendr, ISPEND); /* Restore GICD_ISACTIVER for INTIDs 32 - 1019 */ - RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, isactiver, ISACTIVER); + RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, isactiver, ISACTIVE); + + /* Restore GICD_ISACTIVERE for INTIDs 4096 - 5119 */ + RESTORE_GICD_EREGS(gicd_base, dist_ctx, num_eints, isactiver, ISACTIVE); /* Restore the GICD_CTLR */ gicd_write_ctlr(gicd_base, dist_ctx->gicd_ctlr); gicd_wait_for_pending_write(gicd_base); - } /******************************************************************************* @@ -774,28 +951,25 @@ unsigned int gicv3_get_running_priority(void) /******************************************************************************* * This function checks if the interrupt identified by id is active (whether the * state is either active, or active and pending). The proc_num is used if the - * interrupt is SGI or PPI and programs the corresponding Redistributor + * interrupt is SGI or (E)PPI and programs the corresponding Redistributor * interface. ******************************************************************************/ unsigned int gicv3_get_interrupt_active(unsigned int id, unsigned int proc_num) { - unsigned int value; - assert(gicv3_driver_data != NULL); assert(gicv3_driver_data->gicd_base != 0U); assert(proc_num < gicv3_driver_data->rdistif_num); assert(gicv3_driver_data->rdistif_base_addrs != NULL); - assert(id <= MAX_SPI_ID); - if (id < MIN_SPI_ID) { - /* For SGIs and PPIs */ - value = gicr_get_isactiver0( - gicv3_driver_data->rdistif_base_addrs[proc_num], id); - } else { - value = gicd_get_isactiver(gicv3_driver_data->gicd_base, id); + /* Check interrupt ID */ + if (is_sgi_ppi(id)) { + /* For SGIs: 0-15, PPIs: 16-31 and EPPIs: 1056-1119 */ + return gicr_get_isactiver( + gicv3_driver_data->rdistif_base_addrs[proc_num], id); } - return value; + /* For SPIs: 32-1019 and ESPIs: 4096-5119 */ + return gicd_get_isactiver(gicv3_driver_data->gicd_base, id); } /******************************************************************************* @@ -809,19 +983,20 @@ void gicv3_enable_interrupt(unsigned int id, unsigned int proc_num) assert(gicv3_driver_data->gicd_base != 0U); assert(proc_num < gicv3_driver_data->rdistif_num); assert(gicv3_driver_data->rdistif_base_addrs != NULL); - assert(id <= MAX_SPI_ID); /* * Ensure that any shared variable updates depending on out of band * interrupt trigger are observed before enabling interrupt. */ dsbishst(); - if (id < MIN_SPI_ID) { - /* For SGIs and PPIs */ - gicr_set_isenabler0( - gicv3_driver_data->rdistif_base_addrs[proc_num], - id); + + /* Check interrupt ID */ + if (is_sgi_ppi(id)) { + /* For SGIs: 0-15, PPIs: 16-31 and EPPIs: 1056-1119 */ + gicr_set_isenabler( + gicv3_driver_data->rdistif_base_addrs[proc_num], id); } else { + /* For SPIs: 32-1019 and ESPIs: 4096-5119 */ gicd_set_isenabler(gicv3_driver_data->gicd_base, id); } } @@ -837,22 +1012,23 @@ void gicv3_disable_interrupt(unsigned int id, unsigned int proc_num) assert(gicv3_driver_data->gicd_base != 0U); assert(proc_num < gicv3_driver_data->rdistif_num); assert(gicv3_driver_data->rdistif_base_addrs != NULL); - assert(id <= MAX_SPI_ID); /* * Disable interrupt, and ensure that any shared variable updates * depending on out of band interrupt trigger are observed afterwards. */ - if (id < MIN_SPI_ID) { - /* For SGIs and PPIs */ - gicr_set_icenabler0( - gicv3_driver_data->rdistif_base_addrs[proc_num], - id); + + /* Check interrupt ID */ + if (is_sgi_ppi(id)) { + /* For SGIs: 0-15, PPIs: 16-31 and EPPIs: 1056-1119 */ + gicr_set_icenabler( + gicv3_driver_data->rdistif_base_addrs[proc_num], id); /* Write to clear enable requires waiting for pending writes */ gicr_wait_for_pending_write( - gicv3_driver_data->rdistif_base_addrs[proc_num]); + gicv3_driver_data->rdistif_base_addrs[proc_num]); } else { + /* For SPIs: 32-1019 and ESPIs: 4096-5119 */ gicd_set_icenabler(gicv3_driver_data->gicd_base, id); /* Write to clear enable requires waiting for pending writes */ @@ -875,19 +1051,21 @@ void gicv3_set_interrupt_priority(unsigned int id, unsigned int proc_num, assert(gicv3_driver_data->gicd_base != 0U); assert(proc_num < gicv3_driver_data->rdistif_num); assert(gicv3_driver_data->rdistif_base_addrs != NULL); - assert(id <= MAX_SPI_ID); - if (id < MIN_SPI_ID) { + /* Check interrupt ID */ + if (is_sgi_ppi(id)) { + /* For SGIs: 0-15, PPIs: 16-31 and EPPIs: 1056-1119 */ gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; gicr_set_ipriorityr(gicr_base, id, priority); } else { + /* For SPIs: 32-1019 and ESPIs: 4096-5119 */ gicd_set_ipriorityr(gicv3_driver_data->gicd_base, id, priority); } } /******************************************************************************* * This function assigns group for the interrupt identified by id. The proc_num - * is used if the interrupt is SGI or PPI, and programs the corresponding + * is used if the interrupt is SGI or (E)PPI, and programs the corresponding * Redistributor interface. The group can be any of GICV3_INTR_GROUP* ******************************************************************************/ void gicv3_set_interrupt_type(unsigned int id, unsigned int proc_num, @@ -919,29 +1097,26 @@ void gicv3_set_interrupt_type(unsigned int id, unsigned int proc_num, break; } - if (id < MIN_SPI_ID) { + /* Check interrupt ID */ + if (is_sgi_ppi(id)) { + /* For SGIs: 0-15, PPIs: 16-31 and EPPIs: 1056-1119 */ gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; - if (igroup) - gicr_set_igroupr0(gicr_base, id); - else - gicr_clr_igroupr0(gicr_base, id); - - if (grpmod) - gicr_set_igrpmodr0(gicr_base, id); - else - gicr_clr_igrpmodr0(gicr_base, id); + + igroup ? gicr_set_igroupr(gicr_base, id) : + gicr_clr_igroupr(gicr_base, id); + grpmod ? gicr_set_igrpmodr(gicr_base, id) : + gicr_clr_igrpmodr(gicr_base, id); } else { + /* For SPIs: 32-1019 and ESPIs: 4096-5119 */ + /* Serialize read-modify-write to Distributor registers */ spin_lock(&gic_lock); - if (igroup) - gicd_set_igroupr(gicv3_driver_data->gicd_base, id); - else - gicd_clr_igroupr(gicv3_driver_data->gicd_base, id); - - if (grpmod) - gicd_set_igrpmodr(gicv3_driver_data->gicd_base, id); - else - gicd_clr_igrpmodr(gicv3_driver_data->gicd_base, id); + + igroup ? gicd_set_igroupr(gicv3_driver_data->gicd_base, id) : + gicd_clr_igroupr(gicv3_driver_data->gicd_base, id); + grpmod ? gicd_set_igrpmodr(gicv3_driver_data->gicd_base, id) : + gicd_clr_igrpmodr(gicv3_driver_data->gicd_base, id); + spin_unlock(&gic_lock); } } @@ -986,7 +1161,7 @@ void gicv3_raise_secure_g0_sgi(unsigned int sgi_num, u_register_t target) } /******************************************************************************* - * This function sets the interrupt routing for the given SPI interrupt id. + * This function sets the interrupt routing for the given (E)SPI interrupt id. * The interrupt routing is specified in routing mode and mpidr. * * The routing mode can be either of: @@ -1005,7 +1180,8 @@ void gicv3_set_spi_routing(unsigned int id, unsigned int irm, u_register_t mpidr assert(gicv3_driver_data->gicd_base != 0U); assert((irm == GICV3_IRM_ANY) || (irm == GICV3_IRM_PE)); - assert((id >= MIN_SPI_ID) && (id <= MAX_SPI_ID)); + + assert(IS_SPI(id)); aff = gicd_irouter_val_from_mpidr(mpidr, irm); gicd_write_irouter(gicv3_driver_data->gicd_base, id, aff); @@ -1025,7 +1201,7 @@ void gicv3_set_spi_routing(unsigned int id, unsigned int irm, u_register_t mpidr /******************************************************************************* * This function clears the pending status of an interrupt identified by id. - * The proc_num is used if the interrupt is SGI or PPI, and programs the + * The proc_num is used if the interrupt is SGI or (E)PPI, and programs the * corresponding Redistributor interface. ******************************************************************************/ void gicv3_clear_interrupt_pending(unsigned int id, unsigned int proc_num) @@ -1039,13 +1215,17 @@ void gicv3_clear_interrupt_pending(unsigned int id, unsigned int proc_num) * Clear pending interrupt, and ensure that any shared variable updates * depending on out of band interrupt trigger are observed afterwards. */ - if (id < MIN_SPI_ID) { - /* For SGIs and PPIs */ - gicr_set_icpendr0(gicv3_driver_data->rdistif_base_addrs[proc_num], - id); + + /* Check interrupt ID */ + if (is_sgi_ppi(id)) { + /* For SGIs: 0-15, PPIs: 16-31 and EPPIs: 1056-1119 */ + gicr_set_icpendr( + gicv3_driver_data->rdistif_base_addrs[proc_num], id); } else { + /* For SPIs: 32-1019 and ESPIs: 4096-5119 */ gicd_set_icpendr(gicv3_driver_data->gicd_base, id); } + dsbishst(); } @@ -1066,11 +1246,14 @@ void gicv3_set_interrupt_pending(unsigned int id, unsigned int proc_num) * interrupt trigger are observed before setting interrupt pending. */ dsbishst(); - if (id < MIN_SPI_ID) { - /* For SGIs and PPIs */ - gicr_set_ispendr0(gicv3_driver_data->rdistif_base_addrs[proc_num], - id); + + /* Check interrupt ID */ + if (is_sgi_ppi(id)) { + /* For SGIs: 0-15, PPIs: 16-31 and EPPIs: 1056-1119 */ + gicr_set_ispendr( + gicv3_driver_data->rdistif_base_addrs[proc_num], id); } else { + /* For SPIs: 32-1019 and ESPIs: 4096-5119 */ gicd_set_ispendr(gicv3_driver_data->gicd_base, id); } } @@ -1083,7 +1266,7 @@ unsigned int gicv3_set_pmr(unsigned int mask) { unsigned int old_mask; - old_mask = (uint32_t) read_icc_pmr_el1(); + old_mask = (unsigned int)read_icc_pmr_el1(); /* * Order memory updates w.r.t. PMR write, and ensure they're visible @@ -1130,15 +1313,17 @@ int gicv3_rdistif_probe(const uintptr_t gicr_frame) mpidr = mpidr_from_gicr_typer(typer_val); proc_num = gicv3_driver_data->mpidr_to_core_pos(mpidr); } else { - proc_num = (unsigned int)(typer_val >> TYPER_PROC_NUM_SHIFT) & - TYPER_PROC_NUM_MASK; + proc_num = (unsigned int)(typer_val >> + TYPER_PROC_NUM_SHIFT) & TYPER_PROC_NUM_MASK; } if (proc_num == proc_self) { /* The base address doesn't need to be initialized on * every warm boot. */ - if (gicv3_driver_data->rdistif_base_addrs[proc_num] != 0U) + if (gicv3_driver_data->rdistif_base_addrs[proc_num] + != 0U) { return 0; + } gicv3_driver_data->rdistif_base_addrs[proc_num] = rdistif_base; gicr_frame_found = true; @@ -1147,8 +1332,9 @@ int gicv3_rdistif_probe(const uintptr_t gicr_frame) rdistif_base += (uintptr_t)(ULL(1) << GICR_PCPUBASE_SHIFT); } while ((typer_val & TYPER_LAST_BIT) == 0U); - if (!gicr_frame_found) + if (!gicr_frame_found) { return -1; + } /* * Flush the driver data to ensure coherency. This is @@ -1164,3 +1350,23 @@ int gicv3_rdistif_probe(const uintptr_t gicr_frame) #endif return 0; /* Found matching GICR frame */ } + +/****************************************************************************** + * This function checks the interrupt ID and returns true for SGIs and (E)PPIs + * and false for (E)SPIs IDs. + *****************************************************************************/ +static bool is_sgi_ppi(unsigned int id) +{ + /* SGIs: 0-15, PPIs: 16-31, EPPIs: 1056-1119 */ + if (IS_SGI_PPI(id)) { + return true; + } + + /* SPIs: 32-1019, ESPIs: 4096-5119 */ + if (IS_SPI(id)) { + return false; + } + + assert(false); + panic(); +} diff --git a/drivers/arm/gic/v3/gicv3_private.h b/drivers/arm/gic/v3/gicv3_private.h index dae01cb1e..26c8de53c 100644 --- a/drivers/arm/gic/v3/gicv3_private.h +++ b/drivers/arm/gic/v3/gicv3_private.h @@ -26,39 +26,59 @@ /* Calculate GIC register bit number corresponding to its interrupt ID */ #define BIT_NUM(REG, id) \ - ((id) & ((1U << REG##_SHIFT) - 1U)) + ((id) & ((1U << REG##R_SHIFT) - 1U)) -/* Calculate 8-bit GICD register offset corresponding to its interrupt ID */ +/* + * Calculate 8, 32 and 64-bit GICD register offset + * corresponding to its interrupt ID + */ +#if GIC_EXT_INTID + /* GICv3.1 */ +#define GICD_OFFSET_8(REG, id) \ + (((id) <= MAX_SPI_ID) ? \ + GICD_##REG##R + (uintptr_t)(id) : \ + GICD_##REG##RE + (uintptr_t)(id) - MIN_ESPI_ID) + +#define GICD_OFFSET(REG, id) \ + (((id) <= MAX_SPI_ID) ? \ + GICD_##REG##R + (((uintptr_t)(id) >> REG##R_SHIFT) << 2) : \ + GICD_##REG##RE + ((((uintptr_t)(id) - MIN_ESPI_ID) >> \ + REG##R_SHIFT) << 2)) + +#define GICD_OFFSET_64(REG, id) \ + (((id) <= MAX_SPI_ID) ? \ + GICD_##REG##R + (((uintptr_t)(id) >> REG##R_SHIFT) << 3) : \ + GICD_##REG##RE + (((uintptr_t)(id) - MIN_ESPI_ID) << 3)) + +#else /* GICv3 */ #define GICD_OFFSET_8(REG, id) \ - GICD_##REG + (id) + (GICD_##REG##R + (uintptr_t)(id)) -/* Calculate 32-bit GICD register offset corresponding to its interrupt ID */ #define GICD_OFFSET(REG, id) \ - GICD_##REG + (((id) >> REG##_SHIFT) << 2) + (GICD_##REG##R + (((uintptr_t)(id) >> REG##R_SHIFT) << 2)) -/* Calculate 64-bit GICD register offset corresponding to its interrupt ID */ #define GICD_OFFSET_64(REG, id) \ - GICD_##REG + (((id) >> REG##_SHIFT) << 3) + (GICD_##REG##R + (((uintptr_t)(id) >> REG##R_SHIFT) << 3)) +#endif /* GIC_EXT_INTID */ -/* Read 32-bit GIC Distributor register corresponding to its interrupt ID */ +/* + * Read/Write 8, 32 and 64-bit GIC Distributor register + * corresponding to its interrupt ID + */ #define GICD_READ(REG, base, id) \ mmio_read_32((base) + GICD_OFFSET(REG, (id))) -/* Read 64-bit GIC Distributor register corresponding to its interrupt ID */ #define GICD_READ_64(REG, base, id) \ mmio_read_64((base) + GICD_OFFSET_64(REG, (id))) -/* Write to 64-bit GIC Distributor register corresponding to its interrupt ID */ -#define GICD_WRITE_64(REG, base, id, val) \ - mmio_write_64((base) + GICD_OFFSET_64(REG, (id)), (val)) +#define GICD_WRITE_8(REG, base, id, val) \ + mmio_write_8((base) + GICD_OFFSET_8(REG, (id)), (val)) -/* Write to 32-bit GIC Distributor register corresponding to its interrupt ID */ -#define GICD_WRITE(REG, base, id, val) \ +#define GICD_WRITE(REG, base, id, val) \ mmio_write_32((base) + GICD_OFFSET(REG, (id)), (val)) -/* Write to 8-bit GIC Distributor register corresponding to its interrupt ID */ -#define GICD_WRITE_8(REG, base, id, val) \ - mmio_write_8((base) + GICD_OFFSET_8(REG, (id)), (val)) +#define GICD_WRITE_64(REG, base, id, val) \ + mmio_write_64((base) + GICD_OFFSET_64(REG, (id)), (val)) /* * Bit operations on GIC Distributor register corresponding @@ -80,19 +100,43 @@ ((uint32_t)1 << BIT_NUM(REG, (id)))) /* Write bit in GIC Distributor register */ -#define GICD_WRITE_BIT(REG, base, id) \ +#define GICD_WRITE_BIT(REG, base, id) \ mmio_write_32((base) + GICD_OFFSET(REG, (id)), \ ((uint32_t)1 << BIT_NUM(REG, (id)))) /* - * Calculate GICv3 GICR register offset + * Calculate 8 and 32-bit GICR register offset + * corresponding to its interrupt ID */ +#if GIC_EXT_INTID + /* GICv3.1 */ +#define GICR_OFFSET_8(REG, id) \ + (((id) <= MAX_PPI_ID) ? \ + GICR_##REG##R + (uintptr_t)(id) : \ + GICR_##REG##R + (uintptr_t)(id) - (MIN_EPPI_ID - MIN_SPI_ID)) + +#define GICR_OFFSET(REG, id) \ + (((id) <= MAX_PPI_ID) ? \ + GICR_##REG##R + (((uintptr_t)(id) >> REG##R_SHIFT) << 2) : \ + GICR_##REG##R + ((((uintptr_t)(id) - (MIN_EPPI_ID - MIN_SPI_ID))\ + >> REG##R_SHIFT) << 2)) +#else /* GICv3 */ +#define GICR_OFFSET_8(REG, id) \ + (GICR_##REG##R + (uintptr_t)(id)) + #define GICR_OFFSET(REG, id) \ - GICR_##REG + (((id) >> REG##_SHIFT) << 2) + (GICR_##REG##R + (((uintptr_t)(id) >> REG##R_SHIFT) << 2)) +#endif -/* Write to GIC Redistributor register corresponding to its interrupt ID */ -#define GICR_WRITE_8(REG, base, id, val) \ - mmio_write_8((base) + GICR_##REG + (id), (val)) +/* Read/Write GIC Redistributor register corresponding to its interrupt ID */ +#define GICR_READ(REG, base, id) \ + mmio_read_32((base) + GICR_OFFSET(REG, (id))) + +#define GICR_WRITE_8(REG, base, id, val) \ + mmio_write_8((base) + GICR_OFFSET_8(REG, (id)), (val)) + +#define GICR_WRITE(REG, base, id, val) \ + mmio_write((base) + GICR_OFFSET(REG, (id)), (val)) /* * Bit operations on GIC Redistributor register @@ -105,7 +149,7 @@ /* Write bit in GIC Redistributor register */ #define GICR_WRITE_BIT(REG, base, id) \ - mmio_write_32((base) + GICR_OFFSET(REG, (id)), \ + mmio_write_32((base) + GICR_OFFSET(REG, (id)), \ ((uint32_t)1 << BIT_NUM(REG, (id)))) /* Set bit in GIC Redistributor register */ @@ -157,10 +201,8 @@ extern const gicv3_driver_data_t *gicv3_driver_data; * Note: The raw register values correspond to multiple interrupt IDs and * the number of interrupt IDs involved depends on the register accessed. ******************************************************************************/ -uint32_t gicd_read_igrpmodr(uintptr_t base, unsigned int id); -unsigned int gicr_read_ipriorityr(uintptr_t base, unsigned int id); -void gicd_write_igrpmodr(uintptr_t base, unsigned int id, uint32_t val); -void gicr_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val); +unsigned int gicd_read_igrpmodr(uintptr_t base, unsigned int id); +void gicd_write_igrpmodr(uintptr_t base, unsigned int id, unsigned int val); /******************************************************************************* * Private GICv3 function prototypes for accessing the GIC registers @@ -169,22 +211,21 @@ void gicr_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val); * the bit-field corresponding the single interrupt ID. ******************************************************************************/ unsigned int gicd_get_igrpmodr(uintptr_t base, unsigned int id); -unsigned int gicr_get_igrpmodr0(uintptr_t base, unsigned int id); -unsigned int gicr_get_igroupr0(uintptr_t base, unsigned int id); -unsigned int gicr_get_isactiver0(uintptr_t base, unsigned int id); +unsigned int gicr_get_igrpmodr(uintptr_t base, unsigned int id); +unsigned int gicr_get_igroupr(uintptr_t base, unsigned int id); +unsigned int gicr_get_isactiver(uintptr_t base, unsigned int id); void gicd_set_igrpmodr(uintptr_t base, unsigned int id); -void gicr_set_igrpmodr0(uintptr_t base, unsigned int id); -void gicr_set_isenabler0(uintptr_t base, unsigned int id); -void gicr_set_icenabler0(uintptr_t base, unsigned int id); -void gicr_set_ispendr0(uintptr_t base, unsigned int id); -void gicr_set_icpendr0(uintptr_t base, unsigned int id); -void gicr_set_igroupr0(uintptr_t base, unsigned int id); +void gicr_set_igrpmodr(uintptr_t base, unsigned int id); +void gicr_set_isenabler(uintptr_t base, unsigned int id); +void gicr_set_icenabler(uintptr_t base, unsigned int id); +void gicr_set_ispendr(uintptr_t base, unsigned int id); +void gicr_set_icpendr(uintptr_t base, unsigned int id); +void gicr_set_igroupr(uintptr_t base, unsigned int id); void gicd_clr_igrpmodr(uintptr_t base, unsigned int id); -void gicr_clr_igrpmodr0(uintptr_t base, unsigned int id); -void gicr_clr_igroupr0(uintptr_t base, unsigned int id); +void gicr_clr_igrpmodr(uintptr_t base, unsigned int id); +void gicr_clr_igroupr(uintptr_t base, unsigned int id); void gicr_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri); -void gicr_set_icfgr0(uintptr_t base, unsigned int id, unsigned int cfg); -void gicr_set_icfgr1(uintptr_t base, unsigned int id, unsigned int cfg); +void gicr_set_icfgr(uintptr_t base, unsigned int id, unsigned int cfg); /******************************************************************************* * Private GICv3 helper function prototypes @@ -208,10 +249,10 @@ void gicv3_rdistif_mark_core_asleep(uintptr_t gicr_base); * GIC Distributor interface accessors ******************************************************************************/ /* - * Wait for updates to : + * Wait for updates to: * GICD_CTLR[2:0] - the Group Enables - * GICD_CTLR[5:4] - the ARE bits - * GICD_ICENABLERn - the clearing of enable state for SPIs + * GICD_CTLR[7:4] - the ARE bits, E1NWF bit and DS bit + * GICD_ICENABLER - the clearing of enable state for SPIs */ static inline void gicd_wait_for_pending_write(uintptr_t gicd_base) { @@ -227,7 +268,7 @@ static inline uint32_t gicd_read_pidr2(uintptr_t base) static inline uint64_t gicd_read_irouter(uintptr_t base, unsigned int id) { assert(id >= MIN_SPI_ID); - return GICD_READ_64(IROUTER, base, id); + return GICD_READ_64(IROUTE, base, id); } static inline void gicd_write_irouter(uintptr_t base, @@ -235,7 +276,7 @@ static inline void gicd_write_irouter(uintptr_t base, uint64_t affinity) { assert(id >= MIN_SPI_ID); - GICD_WRITE_64(IROUTER, base, id, affinity); + GICD_WRITE_64(IROUTE, base, id, affinity); } static inline void gicd_clr_ctlr(uintptr_t base, @@ -287,11 +328,12 @@ static inline void gicr_write_waker(uintptr_t base, uint32_t val) } /* - * Wait for updates to : + * Wait for updates to: * GICR_ICENABLER0 * GICR_CTLR.DPG1S * GICR_CTLR.DPG1NS * GICR_CTLR.DPG0 + * GICR_CTLR, which clears EnableLPIs from 1 to 0 */ static inline void gicr_wait_for_pending_write(uintptr_t gicr_base) { @@ -314,101 +356,150 @@ void arm_gicv3_distif_post_restore(unsigned int rdist_proc_num); * Note: The raw register values correspond to multiple interrupt IDs and * the number of interrupt IDs involved depends on the register accessed. ******************************************************************************/ -static inline unsigned int gicr_read_icenabler0(uintptr_t base) -{ - return mmio_read_32(base + GICR_ICENABLER0); -} -static inline void gicr_write_icenabler0(uintptr_t base, unsigned int val) +/* + * Accessors to read/write GIC Redistributor ICENABLER0 and ICENABLERE + * register corresponding to its number + */ +static inline unsigned int gicr_read_icenabler(uintptr_t base, + unsigned int reg_num) { - mmio_write_32(base + GICR_ICENABLER0, val); + return mmio_read_32(base + GICR_ICENABLER + (reg_num << 2)); } -static inline unsigned int gicr_read_isenabler0(uintptr_t base) +static inline void gicr_write_icenabler(uintptr_t base, unsigned int reg_num, + unsigned int val) { - return mmio_read_32(base + GICR_ISENABLER0); + mmio_write_32(base + GICR_ICENABLER + (reg_num << 2), val); } -static inline void gicr_write_icpendr0(uintptr_t base, unsigned int val) +/* + * Accessor to read/write GIC Redistributor ICFGR0, ICFGR1 and ICFGRE + * register corresponding to its number + */ +static inline unsigned int gicr_read_icfgr(uintptr_t base, unsigned int reg_num) { - mmio_write_32(base + GICR_ICPENDR0, val); + return mmio_read_32(base + GICR_ICFGR + (reg_num << 2)); } -static inline void gicr_write_isenabler0(uintptr_t base, unsigned int val) +static inline void gicr_write_icfgr(uintptr_t base, unsigned int reg_num, + unsigned int val) { - mmio_write_32(base + GICR_ISENABLER0, val); + mmio_write_32(base + GICR_ICFGR + (reg_num << 2), val); } -static inline unsigned int gicr_read_igroupr0(uintptr_t base) +/* + * Accessors to read/write GIC Redistributor IGROUPR0 and IGROUPRE + * register corresponding to its number + */ +static inline unsigned int gicr_read_igroupr(uintptr_t base, + unsigned int reg_num) { - return mmio_read_32(base + GICR_IGROUPR0); + return mmio_read_32(base + GICR_IGROUPR + (reg_num << 2)); } -static inline unsigned int gicr_read_ispendr0(uintptr_t base) +static inline void gicr_write_igroupr(uintptr_t base, unsigned int reg_num, + unsigned int val) { - return mmio_read_32(base + GICR_ISPENDR0); + mmio_write_32(base + GICR_IGROUPR + (reg_num << 2), val); } -static inline void gicr_write_ispendr0(uintptr_t base, unsigned int val) +/* + * Accessors to read/write GIC Redistributor IGRPMODR0 and IGRPMODRE + * register corresponding to its number + */ +static inline unsigned int gicr_read_igrpmodr(uintptr_t base, + unsigned int reg_num) { - mmio_write_32(base + GICR_ISPENDR0, val); + return mmio_read_32(base + GICR_IGRPMODR + (reg_num << 2)); } -static inline void gicr_write_igroupr0(uintptr_t base, unsigned int val) +static inline void gicr_write_igrpmodr(uintptr_t base, unsigned int reg_num, + unsigned int val) { - mmio_write_32(base + GICR_IGROUPR0, val); + mmio_write_32(base + GICR_IGRPMODR + (reg_num << 2), val); } -static inline unsigned int gicr_read_igrpmodr0(uintptr_t base) +/* + * Accessors to read/write the GIC Redistributor IPRIORITYR(E) register + * corresponding to its number, 4 interrupts IDs at a time. + */ +static inline unsigned int gicr_read_ipriorityr(uintptr_t base, + unsigned int reg_num) { - return mmio_read_32(base + GICR_IGRPMODR0); + return mmio_read_32(base + GICR_IPRIORITYR + (reg_num << 2)); } -static inline void gicr_write_igrpmodr0(uintptr_t base, unsigned int val) +static inline void gicr_write_ipriorityr(uintptr_t base, unsigned int reg_num, + unsigned int val) { - mmio_write_32(base + GICR_IGRPMODR0, val); + mmio_write_32(base + GICR_IPRIORITYR + (reg_num << 2), val); } -static inline unsigned int gicr_read_nsacr(uintptr_t base) +/* + * Accessors to read/write GIC Redistributor ISACTIVER0 and ISACTIVERE + * register corresponding to its number + */ +static inline unsigned int gicr_read_isactiver(uintptr_t base, + unsigned int reg_num) { - return mmio_read_32(base + GICR_NSACR); + return mmio_read_32(base + GICR_ISACTIVER + (reg_num << 2)); } -static inline void gicr_write_nsacr(uintptr_t base, unsigned int val) +static inline void gicr_write_isactiver(uintptr_t base, unsigned int reg_num, + unsigned int val) { - mmio_write_32(base + GICR_NSACR, val); + mmio_write_32(base + GICR_ISACTIVER + (reg_num << 2), val); } -static inline unsigned int gicr_read_isactiver0(uintptr_t base) +/* + * Accessors to read/write GIC Redistributor ISENABLER0 and ISENABLERE + * register corresponding to its number + */ +static inline unsigned int gicr_read_isenabler(uintptr_t base, + unsigned int reg_num) { - return mmio_read_32(base + GICR_ISACTIVER0); + return mmio_read_32(base + GICR_ISENABLER + (reg_num << 2)); } -static inline void gicr_write_isactiver0(uintptr_t base, unsigned int val) +static inline void gicr_write_isenabler(uintptr_t base, unsigned int reg_num, + unsigned int val) { - mmio_write_32(base + GICR_ISACTIVER0, val); + mmio_write_32(base + GICR_ISENABLER + (reg_num << 2), val); } -static inline unsigned int gicr_read_icfgr0(uintptr_t base) +/* + * Accessors to read/write GIC Redistributor ISPENDR0 and ISPENDRE + * register corresponding to its number + */ +static inline unsigned int gicr_read_ispendr(uintptr_t base, + unsigned int reg_num) { - return mmio_read_32(base + GICR_ICFGR0); + return mmio_read_32(base + GICR_ISPENDR + (reg_num << 2)); } -static inline unsigned int gicr_read_icfgr1(uintptr_t base) +static inline void gicr_write_ispendr(uintptr_t base, unsigned int reg_num, + unsigned int val) { - return mmio_read_32(base + GICR_ICFGR1); + mmio_write_32(base + GICR_ISPENDR + (reg_num << 2), val); } -static inline void gicr_write_icfgr0(uintptr_t base, unsigned int val) +/* + * Accessors to read/write GIC Redistributor NSACR register + */ +static inline unsigned int gicr_read_nsacr(uintptr_t base) { - mmio_write_32(base + GICR_ICFGR0, val); + return mmio_read_32(base + GICR_NSACR); } -static inline void gicr_write_icfgr1(uintptr_t base, unsigned int val) +static inline void gicr_write_nsacr(uintptr_t base, unsigned int val) { - mmio_write_32(base + GICR_ICFGR1, val); + mmio_write_32(base + GICR_NSACR, val); } +/* + * Accessors to read/write GIC Redistributor PROPBASER register + */ static inline uint64_t gicr_read_propbaser(uintptr_t base) { return mmio_read_64(base + GICR_PROPBASER); @@ -419,6 +510,9 @@ static inline void gicr_write_propbaser(uintptr_t base, uint64_t val) mmio_write_64(base + GICR_PROPBASER, val); } +/* + * Accessors to read/write GIC Redistributor PENDBASER register + */ static inline uint64_t gicr_read_pendbaser(uintptr_t base) { return mmio_read_64(base + GICR_PENDBASER); diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h index e6339bcfe..c29896b4b 100644 --- a/include/drivers/arm/gicv3.h +++ b/include/drivers/arm/gicv3.h @@ -8,7 +8,7 @@ #define GICV3_H /******************************************************************************* - * GICv3 miscellaneous definitions + * GICv3 and 3.1 miscellaneous definitions ******************************************************************************/ /* Interrupt group definitions */ #define INTR_GROUP1S U(0) @@ -25,20 +25,85 @@ /* GICv3 can only target up to 16 PEs with SGI */ #define GICV3_MAX_SGI_TARGETS U(16) +/* PPIs INTIDs 16-31 */ +#define MAX_PPI_ID U(31) + +#if GIC_EXT_INTID + +/* GICv3.1 extended PPIs INTIDs 1056-1119 */ +#define MIN_EPPI_ID U(1056) +#define MAX_EPPI_ID U(1119) + +/* Total number of GICv3.1 EPPIs */ +#define TOTAL_EPPI_INTR_NUM (MAX_EPPI_ID - MIN_EPPI_ID + U(1)) + +/* Total number of GICv3.1 PPIs and EPPIs */ +#define TOTAL_PRIVATE_INTR_NUM (TOTAL_PCPU_INTR_NUM + TOTAL_EPPI_INTR_NUM) + +/* GICv3.1 extended SPIs INTIDs 4096 - 5119 */ +#define MIN_ESPI_ID U(4096) +#define MAX_ESPI_ID U(5119) + +/* Total number of GICv3.1 ESPIs */ +#define TOTAL_ESPI_INTR_NUM (MAX_ESPI_ID - MIN_ESPI_ID + U(1)) + +/* Total number of GICv3.1 SPIs and ESPIs */ +#define TOTAL_SHARED_INTR_NUM (TOTAL_SPI_INTR_NUM + TOTAL_ESPI_INTR_NUM) + +/* SGIs: 0-15, PPIs: 16-31, EPPIs: 1056-1119 */ +#define IS_SGI_PPI(id) (((id) <= MAX_PPI_ID) || \ + (((id) >= MIN_EPPI_ID) && \ + ((id) <= MAX_EPPI_ID))) + +/* SPIs: 32-1019, ESPIs: 4096-5119 */ +#define IS_SPI(id) ((((id) >= MIN_SPI_ID) && \ + ((id) <= MAX_SPI_ID)) || \ + (((id) >= MIN_ESPI_ID) && \ + ((id) <= MAX_ESPI_ID))) +#else /* GICv3 */ + +/* Total number of GICv3 PPIs */ +#define TOTAL_PRIVATE_INTR_NUM TOTAL_PCPU_INTR_NUM + +/* Total number of GICv3 SPIs */ +#define TOTAL_SHARED_INTR_NUM TOTAL_SPI_INTR_NUM + +/* SGIs: 0-15, PPIs: 16-31 */ +#define IS_SGI_PPI(id) ((id) <= MAX_PPI_ID) + +/* SPIs: 32-1019 */ +#define IS_SPI(id) (((id) >= MIN_SPI_ID) && ((id) <= MAX_SPI_ID)) + +#endif /* GIC_EXT_INTID */ + /******************************************************************************* - * GICv3 specific Distributor interface register offsets and constants. + * GICv3 and 3.1 specific Distributor interface register offsets and constants ******************************************************************************/ +#define GICD_TYPER2 U(0x0c) #define GICD_STATUSR U(0x10) #define GICD_SETSPI_NSR U(0x40) #define GICD_CLRSPI_NSR U(0x48) #define GICD_SETSPI_SR U(0x50) #define GICD_CLRSPI_SR U(0x58) #define GICD_IGRPMODR U(0xd00) +#define GICD_IGROUPRE U(0x1000) +#define GICD_ISENABLERE U(0x1200) +#define GICD_ICENABLERE U(0x1400) +#define GICD_ISPENDRE U(0x1600) +#define GICD_ICPENDRE U(0x1800) +#define GICD_ISACTIVERE U(0x1a00) +#define GICD_ICACTIVERE U(0x1c00) +#define GICD_IPRIORITYRE U(0x2000) +#define GICD_ICFGRE U(0x3000) +#define GICD_IGRPMODRE U(0x3400) +#define GICD_NSACRE U(0x3600) /* - * GICD_IROUTER register is at 0x6000 + 8n, where n is the interrupt id and - * n >= 32, making the effective offset as 0x6100. + * GICD_IROUTER register is at 0x6000 + 8n, where n is the interrupt ID + * and n >= 32, making the effective offset as 0x6100 */ #define GICD_IROUTER U(0x6000) +#define GICD_IROUTERE U(0x8000) + #define GICD_PIDR2_GICV3 U(0xffe8) #define IGRPMODR_SHIFT 5 @@ -78,14 +143,22 @@ #define NUM_OF_DIST_REGS 30 +/* GICD_TYPER shifts and masks */ +#define TYPER_ESPI U(1 << 8) +#define TYPER_DVIS U(1 << 18) +#define TYPER_ESPI_RANGE_MASK U(0x1f) +#define TYPER_ESPI_RANGE_SHIFT U(27) +#define TYPER_ESPI_RANGE U(TYPER_ESPI_MASK << TYPER_ESPI_SHIFT) + /******************************************************************************* - * GICv3 Redistributor interface registers & constants + * GICv3 and 3.1 Redistributor interface registers & constants ******************************************************************************/ #define GICR_PCPUBASE_SHIFT 0x11 #define GICR_SGIBASE_OFFSET U(65536) /* 64 KB */ #define GICR_CTLR U(0x0) #define GICR_IIDR U(0x04) #define GICR_TYPER U(0x08) +#define GICR_STATUSR U(0x10) #define GICR_WAKER U(0x14) #define GICR_PROPBASER U(0x70) #define GICR_PENDBASER U(0x78) @@ -102,6 +175,16 @@ #define GICR_IGRPMODR0 (GICR_SGIBASE_OFFSET + U(0xd00)) #define GICR_NSACR (GICR_SGIBASE_OFFSET + U(0xe00)) +#define GICR_IGROUPR GICR_IGROUPR0 +#define GICR_ISENABLER GICR_ISENABLER0 +#define GICR_ICENABLER GICR_ICENABLER0 +#define GICR_ISPENDR GICR_ISPENDR0 +#define GICR_ICPENDR GICR_ICPENDR0 +#define GICR_ISACTIVER GICR_ISACTIVER0 +#define GICR_ICACTIVER GICR_ICACTIVER0 +#define GICR_ICFGR GICR_ICFGR0 +#define GICR_IGRPMODR GICR_IGRPMODR0 + /* GICR_CTLR bit definitions */ #define GICR_CTLR_UWP_SHIFT 31 #define GICR_CTLR_UWP_MASK U(0x1) @@ -132,12 +215,13 @@ #define TYPER_LAST_BIT BIT_32(TYPER_LAST_SHIFT) -#define NUM_OF_REDIST_REGS 30 +#define TYPER_PPI_NUM_SHIFT U(27) +#define TYPER_PPI_NUM_MASK U(0x1f) /******************************************************************************* - * GICv3 CPU interface registers & constants + * GICv3 and 3.1 CPU interface registers & constants ******************************************************************************/ -/* ICC_SRE bit definitions*/ +/* ICC_SRE bit definitions */ #define ICC_SRE_EN_BIT BIT_32(3) #define ICC_SRE_DIB_BIT BIT_32(2) #define ICC_SRE_DFB_BIT BIT_32(1) @@ -192,9 +276,8 @@ ((_tgt) & SGIR_TGT_MASK)) /***************************************************************************** - * GICv3 ITS registers and constants + * GICv3 and 3.1 ITS registers and constants *****************************************************************************/ - #define GITS_CTLR U(0x0) #define GITS_IIDR U(0x4) #define GITS_TYPER U(0x8) @@ -205,8 +288,7 @@ /* GITS_CTLR bit definitions */ #define GITS_CTLR_ENABLED_BIT BIT_32(0) -#define GITS_CTLR_QUIESCENT_SHIFT 31 -#define GITS_CTLR_QUIESCENT_BIT BIT_32(GITS_CTLR_QUIESCENT_SHIFT) +#define GITS_CTLR_QUIESCENT_BIT BIT_32(1) #ifndef __ASSEMBLER__ @@ -224,7 +306,7 @@ static inline bool gicv3_is_intr_id_special_identifier(unsigned int id) } /******************************************************************************* - * Helper GICv3 macros for SEL1 + * Helper GICv3 and 3.1 macros for SEL1 ******************************************************************************/ static inline uint32_t gicv3_acknowledge_interrupt_sel1(void) { @@ -255,14 +337,14 @@ static inline void gicv3_end_of_interrupt(unsigned int id) } /* - * This macro returns the total number of GICD registers corresponding to - * the name. + * This macro returns the total number of GICD/GICR registers corresponding to + * the register name */ #define GICD_NUM_REGS(reg_name) \ - DIV_ROUND_UP_2EVAL(TOTAL_SPI_INTR_NUM, (1 << reg_name ## _SHIFT)) + DIV_ROUND_UP_2EVAL(TOTAL_SHARED_INTR_NUM, (1 << reg_name##_SHIFT)) #define GICR_NUM_REGS(reg_name) \ - DIV_ROUND_UP_2EVAL(TOTAL_PCPU_INTR_NUM, (1 << reg_name ## _SHIFT)) + DIV_ROUND_UP_2EVAL(TOTAL_PRIVATE_INTR_NUM, (1 << reg_name##_SHIFT)) /* Interrupt ID mask for HPPIR, AHPPIR, IAR and AIAR CPU Interface registers */ #define INT_ID_MASK U(0xffffff) @@ -325,20 +407,19 @@ typedef struct gicv3_redist_ctx { /* 32 bits registers */ uint32_t gicr_ctlr; - uint32_t gicr_igroupr0; - uint32_t gicr_isenabler0; - uint32_t gicr_ispendr0; - uint32_t gicr_isactiver0; + uint32_t gicr_igroupr[GICR_NUM_REGS(IGROUPR)]; + uint32_t gicr_isenabler[GICR_NUM_REGS(ISENABLER)]; + uint32_t gicr_ispendr[GICR_NUM_REGS(ISPENDR)]; + uint32_t gicr_isactiver[GICR_NUM_REGS(ISACTIVER)]; uint32_t gicr_ipriorityr[GICR_NUM_REGS(IPRIORITYR)]; - uint32_t gicr_icfgr0; - uint32_t gicr_icfgr1; - uint32_t gicr_igrpmodr0; + uint32_t gicr_icfgr[GICR_NUM_REGS(ICFGR)]; + uint32_t gicr_igrpmodr[GICR_NUM_REGS(IGRPMODR)]; uint32_t gicr_nsacr; } gicv3_redist_ctx_t; typedef struct gicv3_dist_ctx { /* 64 bits registers */ - uint64_t gicd_irouter[TOTAL_SPI_INTR_NUM]; + uint64_t gicd_irouter[TOTAL_SHARED_INTR_NUM]; /* 32 bits registers */ uint32_t gicd_ctlr; -- cgit v1.2.3 From 115041633d662ea8f2d3952f10c6e39ad5f5ef22 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 2 Apr 2020 15:35:19 +0900 Subject: locks: bakery: use is_dcache_enabled() helper bakery_lock_normal.c uses the raw register accessor, read_sctlr(_el3) to check whether the dcache is enabled. Using is_dcache_enabled() is cleaner, and a good abstraction for the library code like this. A problem is is_dcache_enabled() is declared in the local header, lib/xlat_tables_v2/xlat_tables_private.h I searched for a good place to declare this helper. Moving it to arch_helpers.h, closed to cache operation helpers, looks good enough to me. I also changed the type of 'is_cached' to bool for consistency, and to avoid MISRA warnings. Change-Id: I9b016f67bc8eade25c316aa9c0db0fa4cd375b79 Signed-off-by: Masahiro Yamada --- include/arch/aarch32/arch_helpers.h | 4 +++- include/arch/aarch64/arch_helpers.h | 1 + lib/locks/bakery/bakery_lock_normal.c | 21 +++++++-------------- lib/xlat_tables_v2/xlat_tables_private.h | 5 +---- 4 files changed, 12 insertions(+), 19 deletions(-) diff --git a/include/arch/aarch32/arch_helpers.h b/include/arch/aarch32/arch_helpers.h index cbac84b93..a90b2a54c 100644 --- a/include/arch/aarch32/arch_helpers.h +++ b/include/arch/aarch32/arch_helpers.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -8,6 +8,7 @@ #define ARCH_HELPERS_H #include +#include #include #include @@ -178,6 +179,7 @@ static inline void _op ## _type(u_register_t v) \ void flush_dcache_range(uintptr_t addr, size_t size); void clean_dcache_range(uintptr_t addr, size_t size); void inv_dcache_range(uintptr_t addr, size_t size); +bool is_dcache_enabled(void); void dcsw_op_louis(u_register_t op_type); void dcsw_op_all(u_register_t op_type); diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h index 7c30758d0..669a1403c 100644 --- a/include/arch/aarch64/arch_helpers.h +++ b/include/arch/aarch64/arch_helpers.h @@ -226,6 +226,7 @@ DEFINE_SYSOP_PARAM_FUNC(xpaci) void flush_dcache_range(uintptr_t addr, size_t size); void clean_dcache_range(uintptr_t addr, size_t size); void inv_dcache_range(uintptr_t addr, size_t size); +bool is_dcache_enabled(void); void dcsw_op_louis(u_register_t op_type); void dcsw_op_all(u_register_t op_type); diff --git a/lib/locks/bakery/bakery_lock_normal.c b/lib/locks/bakery/bakery_lock_normal.c index 0605fceb9..7d35dea66 100644 --- a/lib/locks/bakery/bakery_lock_normal.c +++ b/lib/locks/bakery/bakery_lock_normal.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -84,7 +84,7 @@ static inline void read_cache_op(uintptr_t addr, bool cached) /* Helper function to check if the lock is acquired */ static inline bool is_lock_acquired(const bakery_info_t *my_bakery_info, - int is_cached) + bool is_cached) { /* * Even though lock data is updated only by the owning cpu and @@ -99,7 +99,7 @@ static inline bool is_lock_acquired(const bakery_info_t *my_bakery_info, } static unsigned int bakery_get_ticket(bakery_lock_t *lock, - unsigned int me, int is_cached) + unsigned int me, bool is_cached) { unsigned int my_ticket, their_ticket; unsigned int they; @@ -164,17 +164,14 @@ static unsigned int bakery_get_ticket(bakery_lock_t *lock, void bakery_lock_get(bakery_lock_t *lock) { - unsigned int they, me, is_cached; + unsigned int they, me; unsigned int my_ticket, my_prio, their_ticket; bakery_info_t *their_bakery_info; unsigned int their_bakery_data; + bool is_cached; me = plat_my_core_pos(); -#ifdef __aarch64__ - is_cached = read_sctlr_el3() & SCTLR_C_BIT; -#else - is_cached = read_sctlr() & SCTLR_C_BIT; -#endif + is_cached = is_dcache_enabled(); /* Get a ticket */ my_ticket = bakery_get_ticket(lock, me, is_cached); @@ -232,11 +229,7 @@ void bakery_lock_get(bakery_lock_t *lock) void bakery_lock_release(bakery_lock_t *lock) { bakery_info_t *my_bakery_info; -#ifdef __aarch64__ - unsigned int is_cached = read_sctlr_el3() & SCTLR_C_BIT; -#else - unsigned int is_cached = read_sctlr() & SCTLR_C_BIT; -#endif + bool is_cached = is_dcache_enabled(); my_bakery_info = get_bakery_info(plat_my_core_pos(), lock); diff --git a/lib/xlat_tables_v2/xlat_tables_private.h b/lib/xlat_tables_v2/xlat_tables_private.h index 70ef39523..863470cf3 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-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -99,9 +99,6 @@ unsigned long long xlat_arch_get_max_supported_pa(void); */ bool is_mmu_enabled_ctx(const xlat_ctx_t *ctx); -/* Returns true if the data cache is enabled at the current EL. */ -bool is_dcache_enabled(void); - /* * Returns minimum virtual address space size supported by the architecture */ -- cgit v1.2.3 From 9dfe46c21b897365c58654eb85df3c04ad20bdf0 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Thu, 2 Apr 2020 13:23:45 +0100 Subject: Increase maximum size of BL2 image Increased the maximum size of BL2 image in order to accommodate the BL2 image when TF-A build with no compiler optimization for ARM platform. Note: As of now, "no compiler optimization" build works only when TRUSTED_BOOT_BOARD option is set to 0. This change is verified using below CI configuration: 1. juno-no-optimize-default:juno-linux.uboot 2. fvp-no-optimize-default,fvp-default:fvp-tftf-fip.tftf-aemv8a-debug Change-Id: I5932621237f8acd1b510682388f3ba78eae90ea4 Signed-off-by: Manish V Badarkhe --- plat/arm/board/fvp/include/platform_def.h | 2 +- plat/arm/board/juno/include/platform_def.h | 2 +- plat/arm/css/sgi/include/sgi_base_platform_def.h | 2 +- plat/arm/css/sgm/include/sgm_base_platform_def.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h index 1f569c250..1ed307429 100644 --- a/plat/arm/board/fvp/include/platform_def.h +++ b/plat/arm/board/fvp/include/platform_def.h @@ -120,7 +120,7 @@ #if TRUSTED_BOARD_BOOT # define PLAT_ARM_MAX_BL2_SIZE (UL(0x1D000) - FVP_BL2_ROMLIB_OPTIMIZATION) #else -# define PLAT_ARM_MAX_BL2_SIZE (UL(0x11000) - FVP_BL2_ROMLIB_OPTIMIZATION) +# define PLAT_ARM_MAX_BL2_SIZE (UL(0x12000) - FVP_BL2_ROMLIB_OPTIMIZATION) #endif #if RESET_TO_BL31 diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h index b44639528..43c267d08 100644 --- a/plat/arm/board/juno/include/platform_def.h +++ b/plat/arm/board/juno/include/platform_def.h @@ -139,7 +139,7 @@ # define PLAT_ARM_MAX_BL2_SIZE (UL(0x1D000) - JUNO_BL2_ROMLIB_OPTIMIZATION) #endif #else -# define PLAT_ARM_MAX_BL2_SIZE (UL(0xF000) - JUNO_BL2_ROMLIB_OPTIMIZATION) +# define PLAT_ARM_MAX_BL2_SIZE (UL(0x11000) - JUNO_BL2_ROMLIB_OPTIMIZATION) #endif /* 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 8c8b2311d..3b8d56585 100644 --- a/plat/arm/css/sgi/include/sgi_base_platform_def.h +++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h @@ -77,7 +77,7 @@ #if TRUSTED_BOARD_BOOT # define PLAT_ARM_MAX_BL2_SIZE 0x1D000 #else -# define PLAT_ARM_MAX_BL2_SIZE 0x11000 +# define PLAT_ARM_MAX_BL2_SIZE 0x14000 #endif /* diff --git a/plat/arm/css/sgm/include/sgm_base_platform_def.h b/plat/arm/css/sgm/include/sgm_base_platform_def.h index 0ac0c2b3c..12fa07f3c 100644 --- a/plat/arm/css/sgm/include/sgm_base_platform_def.h +++ b/plat/arm/css/sgm/include/sgm_base_platform_def.h @@ -187,7 +187,7 @@ #if TRUSTED_BOARD_BOOT # define PLAT_ARM_MAX_BL2_SIZE 0x1D000 #else -# define PLAT_ARM_MAX_BL2_SIZE 0x11000 +# define PLAT_ARM_MAX_BL2_SIZE 0x12000 #endif /* -- cgit v1.2.3 From 579d1e90d417909c43870d3decf3760851573770 Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Thu, 26 Mar 2020 18:06:21 -0700 Subject: coreboot: Add memory range parsing This patch adds code to parse memory range information passed by coreboot, and a simple helper to test whether a specific address belongs to a range. This may be useful for coreboot-using platforms that need to know information about the system's memory layout (e.g. to check whether an address passed in via SMC targets valid DRAM). Signed-off-by: Julius Werner Change-Id: I3bea326c426db27d1a8b7d6e17418e4850e884b4 --- include/lib/coreboot.h | 23 ++++++++++++++++++++++- lib/coreboot/coreboot_table.c | 32 +++++++++++++++++++++++++++++++- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/include/lib/coreboot.h b/include/lib/coreboot.h index 88212c315..dda3173a2 100644 --- a/include/lib/coreboot.h +++ b/include/lib/coreboot.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -19,6 +19,27 @@ typedef struct { } coreboot_serial_t; extern coreboot_serial_t coreboot_serial; +#define COREBOOT_MAX_MEMRANGES 32 /* libpayload also uses this limit */ + +typedef struct __packed { + uint64_t start; + uint64_t size; + uint32_t type; +} coreboot_memrange_t; +extern coreboot_memrange_t coreboot_memranges[COREBOOT_MAX_MEMRANGES]; + +typedef enum { + CB_MEM_NONE = 0, /* coreboot will never report this */ + CB_MEM_RAM = 1, + CB_MEM_RESERVED = 2, + CB_MEM_ACPI = 3, + CB_MEM_NVS = 4, + CB_MEM_UNUSABLE = 5, + CB_MEM_VENDOR_RSVD = 6, + CB_MEM_TABLE = 16, +} coreboot_memory_t; + +coreboot_memory_t coreboot_get_memory_type(uintptr_t address); void coreboot_table_setup(void *base); #endif /* COREBOOT_H */ diff --git a/lib/coreboot/coreboot_table.c b/lib/coreboot/coreboot_table.c index 253fac2ac..c4cd1d752 100644 --- a/lib/coreboot/coreboot_table.c +++ b/lib/coreboot/coreboot_table.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -29,6 +29,7 @@ typedef struct { } cb_header_t; typedef enum { + CB_TAG_MEMORY = 0x1, CB_TAG_SERIAL = 0xf, CB_TAG_CBMEM_CONSOLE = 0x17, } cb_tag_t; @@ -37,11 +38,13 @@ typedef struct { uint32_t tag; uint32_t size; union { + coreboot_memrange_t memranges[COREBOOT_MAX_MEMRANGES]; coreboot_serial_t serial; uint64_t uint64; }; } cb_entry_t; +coreboot_memrange_t coreboot_memranges[COREBOOT_MAX_MEMRANGES]; coreboot_serial_t coreboot_serial; /* @@ -86,6 +89,23 @@ static void setup_cbmem_console(uintptr_t baseaddr) CONSOLE_FLAG_CRASH); } +coreboot_memory_t coreboot_get_memory_type(uintptr_t address) +{ + int i; + + for (i = 0; i < COREBOOT_MAX_MEMRANGES; i++) { + coreboot_memrange_t *range = &coreboot_memranges[i]; + + if (range->type == CB_MEM_NONE) + break; /* end of table reached */ + if (address >= range->start && + address - range->start < range->size) + return range->type; + } + + return CB_MEM_NONE; +} + void coreboot_table_setup(void *base) { cb_header_t *header = base; @@ -99,6 +119,7 @@ void coreboot_table_setup(void *base) ptr = base + header->header_bytes; for (i = 0; i < header->table_entries; i++) { + size_t size; cb_entry_t *entry = ptr; if (ptr - base >= header->header_bytes + header->table_bytes) { @@ -107,6 +128,15 @@ void coreboot_table_setup(void *base) } switch (read_le32(&entry->tag)) { + case CB_TAG_MEMORY: + size = read_le32(&entry->size) - + offsetof(cb_entry_t, memranges); + if (size > sizeof(coreboot_memranges)) { + ERROR("Need to truncate coreboot memranges!\n"); + size = sizeof(coreboot_memranges); + } + memcpy(&coreboot_memranges, &entry->memranges, size); + break; case CB_TAG_SERIAL: memcpy(&coreboot_serial, &entry->serial, sizeof(coreboot_serial)); -- cgit v1.2.3 From 5875f2665d7efd7fe3e71e53a7c83dafc9717315 Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Mon, 6 Apr 2020 19:00:35 +0100 Subject: TF-A: Add GICv4 extension for GIC driver This patch adds support for GICv4 extension. New `GIC_ENABLE_V4_EXTN` option passed to gicv3.mk makefile was added, and enables GICv4 related changes when set to 1. This option defaults to 0. Change-Id: I30ebe1b7a98d3a54863900f37eda4589c707a288 Signed-off-by: Alexei Fedorov --- docs/getting_started/build-options.rst | 3 +++ drivers/arm/gic/v3/gicv3.mk | 5 +++++ drivers/arm/gic/v3/gicv3_main.c | 19 +++++++++++++------ include/drivers/arm/gic_common.h | 16 +++++++--------- include/drivers/arm/gicv3.h | 6 +++++- 5 files changed, 33 insertions(+), 16 deletions(-) diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 38845ff0b..778b49c20 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -693,6 +693,9 @@ makefile: functions. This is required for FVP platform which need to simulate GIC save and restore during SYSTEM_SUSPEND without powering down GIC. Default is 0. +- ``GIC_ENABLE_V4_EXTN`` : Enables GICv4 related changes in GICv3 driver. + This option defaults to 0. + - ``GIC_EXT_INTID``: When set to ``1``, GICv3 driver will support extended PPI (1056-1119) and SPI (4096-5119) range. This option defaults to 0. diff --git a/drivers/arm/gic/v3/gicv3.mk b/drivers/arm/gic/v3/gicv3.mk index 73339d991..0f401035d 100644 --- a/drivers/arm/gic/v3/gicv3.mk +++ b/drivers/arm/gic/v3/gicv3.mk @@ -8,6 +8,7 @@ GICV3_IMPL ?= GIC500 GICV3_IMPL_GIC600_MULTICHIP ?= 0 GICV3_OVERRIDE_DISTIF_PWR_OPS ?= 0 +GIC_ENABLE_V4_EXTN ?= 0 GIC_EXT_INTID ?= 0 GICV3_SOURCES += drivers/arm/gic/v3/gicv3_main.c \ @@ -33,6 +34,10 @@ else $(error "Incorrect GICV3_IMPL value ${GICV3_IMPL}") endif +# Set GICv4 extension +$(eval $(call assert_boolean,GIC_ENABLE_V4_EXTN)) +$(eval $(call add_define,GIC_ENABLE_V4_EXTN)) + # Set support for extended PPI and SPI range $(eval $(call assert_boolean,GIC_EXT_INTID)) $(eval $(call add_define,GIC_EXT_INTID)) diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c index aefaa3595..8c27efdae 100644 --- a/drivers/arm/gic/v3/gicv3_main.c +++ b/drivers/arm/gic/v3/gicv3_main.c @@ -116,12 +116,20 @@ void __init gicv3_driver_init(const gicv3_driver_data_t *plat_driver_data) (ID_AA64PFR0_GIC_MASK << ID_AA64PFR0_GIC_SHIFT)) != 0U); #endif /* !__aarch64__ */ - /* The GIC version should be 3 */ gic_version = gicd_read_pidr2(plat_driver_data->gicd_base); gic_version >>= PIDR2_ARCH_REV_SHIFT; gic_version &= PIDR2_ARCH_REV_MASK; - assert(gic_version == ARCH_REV_GICV3); + /* 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 + assert(gic_version == ARCH_REV_GICV3); +#endif /* * Find out whether the GIC supports the GICv2 compatibility mode. * The ARE_S bit resets to 0 if supported @@ -165,10 +173,9 @@ void __init gicv3_driver_init(const gicv3_driver_data_t *plat_driver_data) flush_dcache_range((uintptr_t)gicv3_driver_data, sizeof(*gicv3_driver_data)); #endif - - INFO("GICv3 with%s legacy support detected." - " ARM GICv3 driver initialized in EL3\n", - (gicv2_compat == 0U) ? "" : "out"); + INFO("GICv%u with%s legacy support detected.\n", gic_version, + (gicv2_compat == 0U) ? "" : "out"); + INFO("ARM GICv%u driver initialized in EL3\n", gic_version); } /******************************************************************************* diff --git a/include/drivers/arm/gic_common.h b/include/drivers/arm/gic_common.h index 3ac1b43ff..dc23721bb 100644 --- a/include/drivers/arm/gic_common.h +++ b/include/drivers/arm/gic_common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -40,7 +40,7 @@ #define GIC_HIGHEST_NS_PRIORITY U(0x80) /******************************************************************************* - * GIC Distributor interface register offsets that are common to GICv3 & GICv2 + * Common GIC Distributor interface register offsets ******************************************************************************/ #define GICD_CTLR U(0x0) #define GICD_TYPER U(0x4) @@ -61,19 +61,17 @@ #define CTLR_ENABLE_G0_MASK U(0x1) #define CTLR_ENABLE_G0_BIT BIT_32(CTLR_ENABLE_G0_SHIFT) - /******************************************************************************* - * GIC Distributor interface register constants that are common to GICv3 & GICv2 + * Common GIC Distributor interface register constants ******************************************************************************/ #define PIDR2_ARCH_REV_SHIFT 4 #define PIDR2_ARCH_REV_MASK U(0xf) -/* GICv3 revision as reported by the PIDR2 register */ -#define ARCH_REV_GICV3 U(0x3) -/* GICv2 revision as reported by the PIDR2 register */ -#define ARCH_REV_GICV2 U(0x2) -/* GICv1 revision as reported by the PIDR2 register */ +/* GIC revision as reported by PIDR2.ArchRev register field */ #define ARCH_REV_GICV1 U(0x1) +#define ARCH_REV_GICV2 U(0x2) +#define ARCH_REV_GICV3 U(0x3) +#define ARCH_REV_GICV4 U(0x4) #define IGROUPR_SHIFT 5 #define ISENABLER_SHIFT 5 diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h index c29896b4b..03596b96e 100644 --- a/include/drivers/arm/gicv3.h +++ b/include/drivers/arm/gicv3.h @@ -151,9 +151,13 @@ #define TYPER_ESPI_RANGE U(TYPER_ESPI_MASK << TYPER_ESPI_SHIFT) /******************************************************************************* - * GICv3 and 3.1 Redistributor interface registers & constants + * 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_SGIBASE_OFFSET U(65536) /* 64 KB */ #define GICR_CTLR U(0x0) #define GICR_IIDR U(0x04) -- cgit v1.2.3 From e6e10ecc42b48f3d2f49b20bb4d0cf7cc4f4c180 Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Tue, 7 Apr 2020 11:48:00 +0100 Subject: FVP: Add support for GICv4 extension This patch adds support for GICv4 extension for FVP platform. Change-Id: Ia389b61266af669b1ca9b999a8b76476cab214f4 Signed-off-by: Alexei Fedorov --- plat/arm/board/fvp/fvp_def.h | 10 +++++++++- plat/arm/board/fvp/platform.mk | 13 +++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/plat/arm/board/fvp/fvp_def.h b/plat/arm/board/fvp/fvp_def.h index 909b68717..c5d156858 100644 --- a/plat/arm/board/fvp/fvp_def.h +++ b/plat/arm/board/fvp/fvp_def.h @@ -52,10 +52,18 @@ #define DEVICE1_BASE UL(0x2e000000) #define DEVICE1_SIZE UL(0x1A00000) #else -/* GICv2 and GICv3 mapping: GICD + CORE_COUNT * 128KB */ #define DEVICE1_BASE BASE_GICD_BASE + +#if GIC_ENABLE_V4_EXTN +/* GICv4 mapping: GICD + CORE_COUNT * 256KB */ +#define DEVICE1_SIZE ((BASE_GICR_BASE - BASE_GICD_BASE) + \ + (PLATFORM_CORE_COUNT * 0x40000)) +#else +/* GICv2 and GICv3 mapping: GICD + CORE_COUNT * 128KB */ #define DEVICE1_SIZE ((BASE_GICR_BASE - BASE_GICD_BASE) + \ (PLATFORM_CORE_COUNT * 0x20000)) +#endif /* GIC_ENABLE_V4_EXTN */ + #define NSRAM_BASE UL(0x2e000000) #define NSRAM_SIZE UL(0x10000) #endif diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 784369024..04cebcac3 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -50,12 +50,12 @@ $(eval $(call add_define,FVP_INTERCONNECT_DRIVER)) # Choose the GIC sources depending upon the how the FVP will be invoked ifeq (${FVP_USE_GIC_DRIVER},$(filter ${FVP_USE_GIC_DRIVER},FVP_GICV3 FVP_GIC600)) + + # GIC500 is the default option in case GICV3_IMPL is not set ifeq (${FVP_USE_GIC_DRIVER}, FVP_GIC600) GICV3_IMPL := GIC600 endif -# GIC500 is the default option in case GICV3_IMPL is not set - GICV3_OVERRIDE_DISTIF_PWR_OPS := 1 # Include GICv3 driver files @@ -66,6 +66,15 @@ FVP_GIC_SOURCES := ${GICV3_SOURCES} \ plat/arm/common/arm_gicv3.c else ifeq (${FVP_USE_GIC_DRIVER}, FVP_GICV2) + +# No GICv4 extension +GIC_ENABLE_V4_EXTN := 0 +$(eval $(call add_define,GIC_ENABLE_V4_EXTN)) + +# No support for extended PPI and SPI range +GIC_EXT_INTID := 0 +$(eval $(call add_define,GIC_EXT_INTID)) + FVP_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 b24ece54e040537599d3c94bb2b2f639bd5c2509 Mon Sep 17 00:00:00 2001 From: Vijayenthiran Subramaniam Date: Mon, 6 Apr 2020 13:54:50 +0530 Subject: gic multichip: add support for clayton GIC-Clayton supports multichip operation mode which allows it to connect upto 16 other GIC-Clayton instances. GIC-Clayton's multichip programming and operation remains same as GIC-600 with a minor change in the SPI_BLOCKS and SPI_BLOCK_MIN shifts to accommodate additional SPI ranges. So identify if the GIC v4 extension is enabled by the platform makefile and appropriately select the SPI_BLOCKS and SPI_BLOCK_MIN shifts. Change-Id: I95fd80ef16af6c7ca09e2335539187b133052d41 Signed-off-by: Vijayenthiran Subramaniam --- drivers/arm/gic/v3/gic600_multichip_private.h | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/arm/gic/v3/gic600_multichip_private.h b/drivers/arm/gic/v3/gic600_multichip_private.h index b0217b6d4..fe4134cba 100644 --- a/drivers/arm/gic/v3/gic600_multichip_private.h +++ b/drivers/arm/gic/v3/gic600_multichip_private.h @@ -24,11 +24,21 @@ /* GIC600 GICD multichip related shifts */ #define GICD_CHIPRx_ADDR_SHIFT 16 -#define GICD_CHIPRx_SPI_BLOCK_MIN_SHIFT 10 -#define GICD_CHIPRx_SPI_BLOCKS_SHIFT 5 #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-Clayton. + * Other shifts and mask remains same between GIC-600 and GIC-Clayton. + */ +#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 + #define GICD_CHIPSR_RTS_STATE_DISCONNECTED U(0) #define GICD_CHIPSR_RTS_STATE_UPDATING U(1) #define GICD_CHIPSR_RTS_STATE_CONSISTENT U(2) -- cgit v1.2.3 From eb0f3149d20dd4a5d803003ad362ba9a7baafeba Mon Sep 17 00:00:00 2001 From: Vijayenthiran Subramaniam Date: Mon, 6 Apr 2020 17:54:42 +0530 Subject: plat/arm/rddaniel: enabled GICv4 extension RD-Daniel uses GIC-Clayton as its interrupt controller which is an implementation of GICv4.1 architecture. Hence for RD-Daniel, enable GICv4 extension support. Change-Id: I45ae8c82376f8fe8fc0666306822ae2db74e71b8 Signed-off-by: Vijayenthiran Subramaniam --- plat/arm/board/rddaniel/platform.mk | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plat/arm/board/rddaniel/platform.mk b/plat/arm/board/rddaniel/platform.mk index ca2647418..94a3928f8 100644 --- a/plat/arm/board/rddaniel/platform.mk +++ b/plat/arm/board/rddaniel/platform.mk @@ -3,6 +3,9 @@ # SPDX-License-Identifier: BSD-3-Clause # +# RD-Daniel platform uses GIC-Clayton which is based on GICv4.1 +GIC_ENABLE_V4_EXTN := 1 + include plat/arm/css/sgi/sgi-common.mk RDDANIEL_BASE = plat/arm/board/rddaniel -- cgit v1.2.3 From e2a4027b1b5b5af0bedd9a9626ca6b70040901d5 Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Tue, 7 Apr 2020 18:16:18 +0100 Subject: TF-A GICv3 driver: Change API for GICR_IPRIORITYR accessors To support compatibility with previous GICv3 driver version this patch: - restores original API for gicr_read_ipriority() and gicr_wrtite_ipriority() functions; - adds accessor functions for GICR_XXX0,1 registers, e.g. GICR_IGROUPR0, GICR_ICFGR0, GICR_ICFGR1, etc. Change-Id: I796a312a61665ff384e3d9de2f4b3c60f700b43b Signed-off-by: Alexei Fedorov --- drivers/arm/gic/v3/gicrv3_helpers.c | 14 ++++ drivers/arm/gic/v3/gicv3_main.c | 6 +- drivers/arm/gic/v3/gicv3_private.h | 131 ++++++++++++++++++++++++++++++++++-- 3 files changed, 144 insertions(+), 7 deletions(-) diff --git a/drivers/arm/gic/v3/gicrv3_helpers.c b/drivers/arm/gic/v3/gicrv3_helpers.c index e46b15e24..3004054ee 100644 --- a/drivers/arm/gic/v3/gicrv3_helpers.c +++ b/drivers/arm/gic/v3/gicrv3_helpers.c @@ -17,6 +17,20 @@ * the number of interrupt `id`s involved depends on the register accessed. ******************************************************************************/ +/* + * Accessors to read/write the GIC Redistributor IPRIORITYR and IPRIORITYRE + * register corresponding to the interrupt `id`, 4 interrupts IDs at a time. + */ +unsigned int gicr_read_ipriorityr(uintptr_t base, unsigned int id) +{ + return GICR_READ(IPRIORITY, base, id); +} + +void gicr_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val) +{ + GICR_WRITE(IPRIORITY, base, id, val); +} + /* * Accessor to set the byte corresponding to interrupt `id` * in GIC Redistributor IPRIORITYR and IPRIORITYRE. diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c index 8c27efdae..22efd458d 100644 --- a/drivers/arm/gic/v3/gicv3_main.c +++ b/drivers/arm/gic/v3/gicv3_main.c @@ -593,7 +593,8 @@ void gicv3_rdistif_save(unsigned int proc_num, /* 4 interrupt IDs per GICR_IPRIORITYR register */ regs_num = ppi_regs_num << 3; for (i = 0U; i < regs_num; ++i) { - SAVE_GICR_REG(gicr_base, rdist_ctx, ipriorityr, i); + rdist_ctx->gicr_ipriorityr[i] = + gicr_ipriorityr_read(gicr_base, i); } /* @@ -678,7 +679,8 @@ void gicv3_rdistif_init_restore(unsigned int proc_num, /* 4 interrupt IDs per GICR_IPRIORITYR register */ regs_num = ppi_regs_num << 3; for (i = 0U; i < regs_num; ++i) { - RESTORE_GICR_REG(gicr_base, rdist_ctx, ipriorityr, i); + gicr_ipriorityr_write(gicr_base, i, + rdist_ctx->gicr_ipriorityr[i]); } /* 16 interrupt IDs per GICR_ICFGR register */ diff --git a/drivers/arm/gic/v3/gicv3_private.h b/drivers/arm/gic/v3/gicv3_private.h index 26c8de53c..c5d027da2 100644 --- a/drivers/arm/gic/v3/gicv3_private.h +++ b/drivers/arm/gic/v3/gicv3_private.h @@ -126,7 +126,7 @@ #define GICR_OFFSET(REG, id) \ (GICR_##REG##R + (((uintptr_t)(id) >> REG##R_SHIFT) << 2)) -#endif +#endif /* GIC_EXT_INTID */ /* Read/Write GIC Redistributor register corresponding to its interrupt ID */ #define GICR_READ(REG, base, id) \ @@ -136,7 +136,7 @@ mmio_write_8((base) + GICR_OFFSET_8(REG, (id)), (val)) #define GICR_WRITE(REG, base, id, val) \ - mmio_write((base) + GICR_OFFSET(REG, (id)), (val)) + mmio_write_32((base) + GICR_OFFSET(REG, (id)), (val)) /* * Bit operations on GIC Redistributor register @@ -202,7 +202,9 @@ extern const gicv3_driver_data_t *gicv3_driver_data; * the number of interrupt IDs involved depends on the register accessed. ******************************************************************************/ unsigned int gicd_read_igrpmodr(uintptr_t base, unsigned int id); +unsigned int gicr_read_ipriorityr(uintptr_t base, unsigned int id); void gicd_write_igrpmodr(uintptr_t base, unsigned int id, unsigned int val); +void gicr_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val); /******************************************************************************* * Private GICv3 function prototypes for accessing the GIC registers @@ -357,6 +359,19 @@ void arm_gicv3_distif_post_restore(unsigned int rdist_proc_num); * the number of interrupt IDs involved depends on the register accessed. ******************************************************************************/ +/* + * Accessors to read/write GIC Redistributor ICENABLER0 register + */ +static inline unsigned int gicr_read_icenabler0(uintptr_t base) +{ + return mmio_read_32(base + GICR_ICENABLER0); +} + +static inline void gicr_write_icenabler0(uintptr_t base, unsigned int val) +{ + mmio_write_32(base + GICR_ICENABLER0, val); +} + /* * Accessors to read/write GIC Redistributor ICENABLER0 and ICENABLERE * register corresponding to its number @@ -374,7 +389,30 @@ static inline void gicr_write_icenabler(uintptr_t base, unsigned int reg_num, } /* - * Accessor to read/write GIC Redistributor ICFGR0, ICFGR1 and ICFGRE + * Accessors to read/write GIC Redistributor ICFGR0, ICFGR1 registers + */ +static inline unsigned int gicr_read_icfgr0(uintptr_t base) +{ + return mmio_read_32(base + GICR_ICFGR0); +} + +static inline unsigned int gicr_read_icfgr1(uintptr_t base) +{ + return mmio_read_32(base + GICR_ICFGR1); +} + +static inline void gicr_write_icfgr0(uintptr_t base, unsigned int val) +{ + mmio_write_32(base + GICR_ICFGR0, val); +} + +static inline void gicr_write_icfgr1(uintptr_t base, unsigned int val) +{ + mmio_write_32(base + GICR_ICFGR1, val); +} + +/* + * Accessors to read/write GIC Redistributor ICFGR0, ICFGR1 and ICFGRE * register corresponding to its number */ static inline unsigned int gicr_read_icfgr(uintptr_t base, unsigned int reg_num) @@ -388,6 +426,37 @@ static inline void gicr_write_icfgr(uintptr_t base, unsigned int reg_num, mmio_write_32(base + GICR_ICFGR + (reg_num << 2), val); } +/* + * Accessor to write GIC Redistributor ICPENDR0 register + */ +static inline void gicr_write_icpendr0(uintptr_t base, unsigned int val) +{ + mmio_write_32(base + GICR_ICPENDR0, val); +} + +/* + * Accessor to write GIC Redistributor ICPENDR0 and ICPENDRE + * register corresponding to its number + */ +static inline void gicr_write_icpendr(uintptr_t base, unsigned int reg_num, + unsigned int val) +{ + mmio_write_32(base + GICR_ICPENDR + (reg_num << 2), val); +} + +/* + * Accessors to read/write GIC Redistributor IGROUPR0 register + */ +static inline unsigned int gicr_read_igroupr0(uintptr_t base) +{ + return mmio_read_32(base + GICR_IGROUPR0); +} + +static inline void gicr_write_igroupr0(uintptr_t base, unsigned int val) +{ + mmio_write_32(base + GICR_IGROUPR0, val); +} + /* * Accessors to read/write GIC Redistributor IGROUPR0 and IGROUPRE * register corresponding to its number @@ -404,6 +473,19 @@ static inline void gicr_write_igroupr(uintptr_t base, unsigned int reg_num, mmio_write_32(base + GICR_IGROUPR + (reg_num << 2), val); } +/* + * Accessors to read/write GIC Redistributor IGRPMODR0 register + */ +static inline unsigned int gicr_read_igrpmodr0(uintptr_t base) +{ + return mmio_read_32(base + GICR_IGRPMODR0); +} + +static inline void gicr_write_igrpmodr0(uintptr_t base, unsigned int val) +{ + mmio_write_32(base + GICR_IGRPMODR0, val); +} + /* * Accessors to read/write GIC Redistributor IGRPMODR0 and IGRPMODRE * register corresponding to its number @@ -424,18 +506,31 @@ static inline void gicr_write_igrpmodr(uintptr_t base, unsigned int reg_num, * Accessors to read/write the GIC Redistributor IPRIORITYR(E) register * corresponding to its number, 4 interrupts IDs at a time. */ -static inline unsigned int gicr_read_ipriorityr(uintptr_t base, +static inline unsigned int gicr_ipriorityr_read(uintptr_t base, unsigned int reg_num) { return mmio_read_32(base + GICR_IPRIORITYR + (reg_num << 2)); } -static inline void gicr_write_ipriorityr(uintptr_t base, unsigned int reg_num, +static inline void gicr_ipriorityr_write(uintptr_t base, unsigned int reg_num, unsigned int val) { mmio_write_32(base + GICR_IPRIORITYR + (reg_num << 2), val); } +/* + * Accessors to read/write GIC Redistributor ISACTIVER0 register + */ +static inline unsigned int gicr_read_isactiver0(uintptr_t base) +{ + return mmio_read_32(base + GICR_ISACTIVER0); +} + +static inline void gicr_write_isactiver0(uintptr_t base, unsigned int val) +{ + mmio_write_32(base + GICR_ISACTIVER0, val); +} + /* * Accessors to read/write GIC Redistributor ISACTIVER0 and ISACTIVERE * register corresponding to its number @@ -452,6 +547,19 @@ static inline void gicr_write_isactiver(uintptr_t base, unsigned int reg_num, mmio_write_32(base + GICR_ISACTIVER + (reg_num << 2), val); } +/* + * Accessors to read/write GIC Redistributor ISENABLER0 register + */ +static inline unsigned int gicr_read_isenabler0(uintptr_t base) +{ + return mmio_read_32(base + GICR_ISENABLER0); +} + +static inline void gicr_write_isenabler0(uintptr_t base, unsigned int val) +{ + mmio_write_32(base + GICR_ISENABLER0, val); +} + /* * Accessors to read/write GIC Redistributor ISENABLER0 and ISENABLERE * register corresponding to its number @@ -468,6 +576,19 @@ static inline void gicr_write_isenabler(uintptr_t base, unsigned int reg_num, mmio_write_32(base + GICR_ISENABLER + (reg_num << 2), val); } +/* + * Accessors to read/write GIC Redistributor ISPENDR0 register + */ +static inline unsigned int gicr_read_ispendr0(uintptr_t base) +{ + return mmio_read_32(base + GICR_ISPENDR0); +} + +static inline void gicr_write_ispendr0(uintptr_t base, unsigned int val) +{ + mmio_write_32(base + GICR_ISPENDR0, val); +} + /* * Accessors to read/write GIC Redistributor ISPENDR0 and ISPENDRE * register corresponding to its number -- cgit v1.2.3 From a82ea1dbbf0d651d9fed35bf3a962cd8fce4b01c Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 9 Apr 2020 11:27:21 +0100 Subject: arm_fpga: Remove bogus timer initialisation The arm_fpga platform code contains an dubious line to initialise some timer. On closer inspection this turn out to be bogus, as this was only needed on some special (older) FPGA board, and is actually not needed on the current model. Also the base address was wrong anyways. Remove the code entirely. Change-Id: I02e71aea645051b5addb42d972d7a79f04b81106 Signed-off-by: Andre Przywara --- plat/arm/board/arm_fpga/fpga_bl31_setup.c | 1 - plat/arm/board/arm_fpga/fpga_def.h | 1 - 2 files changed, 2 deletions(-) diff --git a/plat/arm/board/arm_fpga/fpga_bl31_setup.c b/plat/arm/board/arm_fpga/fpga_bl31_setup.c index d499379ee..632949723 100644 --- a/plat/arm/board/arm_fpga/fpga_bl31_setup.c +++ b/plat/arm/board/arm_fpga/fpga_bl31_setup.c @@ -56,7 +56,6 @@ void bl31_platform_setup(void) /* Write frequency to CNTCRL and initialize timer */ generic_delay_timer_init(); - mmio_write_32(FPGA_TIMER_BASE, ((1 << 8) | 1UL)); } entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) diff --git a/plat/arm/board/arm_fpga/fpga_def.h b/plat/arm/board/arm_fpga/fpga_def.h index 56ee1663d..dbdbe6f4d 100644 --- a/plat/arm/board/arm_fpga/fpga_def.h +++ b/plat/arm/board/arm_fpga/fpga_def.h @@ -36,6 +36,5 @@ #define PLAT_FPGA_CRASH_UART_CLK_IN_HZ PLAT_FPGA_BOOT_UART_CLK_IN_HZ #define FPGA_TIMER_FREQUENCY 10000000 -#define FPGA_TIMER_BASE 0x2a830000 #endif -- cgit v1.2.3 From 2176716671878e0ab514be61b82138f7c0db84dc Mon Sep 17 00:00:00 2001 From: Sheetal Tigadoli Date: Mon, 13 Apr 2020 18:43:29 +0530 Subject: stingray: fix coverity reported issues on brcm platform fix coverity reported issues 1. uninitialized var, 2. check for negative val on unsigned variable Signed-off-by: Sheetal Tigadoli Change-Id: I28b7517135ba6c1ba0df04f0c73189cf84ba89e6 --- plat/brcm/board/stingray/src/bl2_setup.c | 2 +- plat/brcm/board/stingray/src/paxb.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plat/brcm/board/stingray/src/bl2_setup.c b/plat/brcm/board/stingray/src/bl2_setup.c index 9a79744d5..b2c8aec12 100644 --- a/plat/brcm/board/stingray/src/bl2_setup.c +++ b/plat/brcm/board/stingray/src/bl2_setup.c @@ -682,7 +682,7 @@ void plat_bcm_bl2_plat_arch_setup(void) bcm_board_detect(); #ifdef DRIVER_EMMC_ENABLE /* Initialize the card, if it is not */ - if (bcm_emmc_init(true) < 0) + if (bcm_emmc_init(true) == 0) WARN("eMMC Card Initialization Failed!!!\n"); #endif diff --git a/plat/brcm/board/stingray/src/paxb.c b/plat/brcm/board/stingray/src/paxb.c index 28065f07a..89f76d06a 100644 --- a/plat/brcm/board/stingray/src/paxb.c +++ b/plat/brcm/board/stingray/src/paxb.c @@ -485,7 +485,7 @@ static void pcie_ss_reset(void) */ static int pcie_cores_init(void) { - int ret; + int ret = 0; uint32_t core_idx; if (paxb->pipemux_init) { -- cgit v1.2.3 From def3b54b74140e00e66e409bcb798c0e1902b4cc Mon Sep 17 00:00:00 2001 From: Aditya Angadi Date: Wed, 8 Apr 2020 14:17:08 +0530 Subject: plat/arm/sgi: update mmap and xlat count A single chip platform requires five mmap entries and a corresponding number of translation tables. For every additional chip in the system, three additional mmap entries are required to map the shared SRAM and the IO regions. A corresponding number of additional translation tables are required as well. Change-Id: I1332a1305f2af62181387cf36954f6fb0e6f11ed Signed-off-by: Aditya Angadi --- plat/arm/css/sgi/include/sgi_base_platform_def.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 3b8d56585..14cdb7e76 100644 --- a/plat/arm/css/sgi/include/sgi_base_platform_def.h +++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h @@ -38,8 +38,8 @@ # define PLAT_SP_IMAGE_MMAP_REGIONS 7 # define PLAT_SP_IMAGE_MAX_XLAT_TABLES 10 # else -# define PLAT_ARM_MMAP_ENTRIES 8 -# define MAX_XLAT_TABLES 8 +# define PLAT_ARM_MMAP_ENTRIES (5 + ((CSS_SGI_CHIP_COUNT - 1) * 3)) +# define MAX_XLAT_TABLES (5 + ((CSS_SGI_CHIP_COUNT - 1) * 3)) # endif #elif defined(IMAGE_BL32) # define PLAT_ARM_MMAP_ENTRIES 8 -- cgit v1.2.3 From 77516a733100bd1e138a4af319688eeb7d1d08a6 Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Wed, 15 Apr 2020 11:13:38 +0200 Subject: Fix Broadcom Stingray platform documentation - Include the platform documentation in the table of contents. - Add a title for the document. Without this, the platform documentation was listed under a 'Description' title on page https://trustedfirmware-a.readthedocs.io/en/latest/plat/index.html - Change TF-A git repository URL to point to tf.org (rather than the deprecated read-only mirror on Github). - Fix the restructuredText syntax for the FIP command line. It was not displayed at all on the rendered version. Change-Id: I7a0f062bcf8e0dfc65e8f8bdd6775c497a47e619 Signed-off-by: Sandrine Bailleux --- docs/plat/brcm-stingray.rst | 21 ++++++++++++--------- docs/plat/index.rst | 1 + 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/docs/plat/brcm-stingray.rst b/docs/plat/brcm-stingray.rst index c43c8504c..95029cc3d 100644 --- a/docs/plat/brcm-stingray.rst +++ b/docs/plat/brcm-stingray.rst @@ -1,27 +1,30 @@ +Broadcom Stingray +================= + Description -=========== +----------- Broadcom's Stingray(BCM958742t) is a multi-core processor with 8 Cortex-A72 cores. Trusted Firmware-A (TF-A) is used to implement secure world firmware, supporting -BL2 and BL31 for Broadcom Stingray SoCs +BL2 and BL31 for Broadcom Stingray SoCs. On Poweron, Boot ROM will load bl2 image and Bl2 will initialize the hardware, then loads bl31 and bl33 into DDR and boots to bl33. Boot Sequence -============= +------------- Bootrom --> TF-A BL2 --> TF-A BL31 --> BL33(u-boot) Code Locations --------------- +~~~~~~~~~~~~~~ - Trusted Firmware-A: - `link `__ + `link `__ How to build -============ +------------ Build Procedure ---------------- +~~~~~~~~~~~~~~~ - Prepare AARCH64 toolchain. @@ -31,10 +34,10 @@ Build Procedure Build fip: - .. code::shell + .. code:: shell make CROSS_COMPILE=aarch64-linux-gnu- PLAT=stingray BOARD_CFG=bcm958742t all fip BL33=u-boot.bin Deploy TF-A Images ------------------ +~~~~~~~~~~~~~~~~~~ The u-boot will be upstreamed soon, this doc will be updated once they are ready, and the link will be posted. diff --git a/docs/plat/index.rst b/docs/plat/index.rst index a6ef1884b..7969003c9 100644 --- a/docs/plat/index.rst +++ b/docs/plat/index.rst @@ -37,6 +37,7 @@ Platform Ports ti-k3 xilinx-versal xilinx-zynqmp + brcm-stingray This section provides a list of supported upstream *platform ports* and the documentation associated with them. -- cgit v1.2.3 From 9cf7f355ce8984a4cde970d5f57c913d5247ca6d Mon Sep 17 00:00:00 2001 From: Madhukar Pappireddy Date: Wed, 30 Oct 2019 14:24:39 -0500 Subject: Provide a hint to power controller for DSU cluster power down By writing 0 to CLUSTERPWRDN DSU register bit 0, we send an advisory to the power controller that cluster power is not required when all cores are powered down. The AArch32 CLUSTERPWRDN register is architecturally mapped to the AArch64 CLUSTERPWRDN_EL1 register Change-Id: Ie6e67c1c7d811fa25c51e2e405ca7f59bd20c81b Signed-off-by: Madhukar Pappireddy --- include/arch/aarch32/arch.h | 10 ++++++++++ include/arch/aarch32/arch_helpers.h | 5 +++++ include/arch/aarch64/arch.h | 10 ++++++++++ include/arch/aarch64/arch_helpers.h | 6 ++++++ plat/arm/board/fvp/fvp_pm.c | 19 +++++++++++++++++++ plat/arm/css/common/css_pm.c | 22 +++++++++++++++++++++- 6 files changed, 71 insertions(+), 1 deletion(-) diff --git a/include/arch/aarch32/arch.h b/include/arch/aarch32/arch.h index 8492b3ea4..a11d55e08 100644 --- a/include/arch/aarch32/arch.h +++ b/include/arch/aarch32/arch.h @@ -701,4 +701,14 @@ #define AMEVTYPER1E p15, 0, c13, c15, 6 #define AMEVTYPER1F p15, 0, c13, c15, 7 +/******************************************************************************* + * Definitions for DynamicIQ Shared Unit registers + ******************************************************************************/ +#define CLUSTERPWRDN p15, 0, c15, c3, 6 + +/* CLUSTERPWRDN register definitions */ +#define DSU_CLUSTER_PWR_OFF 0 +#define DSU_CLUSTER_PWR_ON 1 +#define DSU_CLUSTER_PWR_MASK U(1) + #endif /* ARCH_H */ diff --git a/include/arch/aarch32/arch_helpers.h b/include/arch/aarch32/arch_helpers.h index a90b2a54c..eed56e219 100644 --- a/include/arch/aarch32/arch_helpers.h +++ b/include/arch/aarch32/arch_helpers.h @@ -336,6 +336,11 @@ DEFINE_DCOP_PARAM_FUNC(cvac, DCCIMVAC) DEFINE_DCOP_PARAM_FUNC(cvac, DCCMVAC) #endif +/* + * DynamIQ Shared Unit power management + */ +DEFINE_COPROCR_RW_FUNCS(clusterpwrdn, CLUSTERPWRDN) + /* Previously defined accessor functions with incomplete register names */ #define dsb() dsbsy() #define dmb() dmbsy() diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index 19dd8c5e3..e45a594c5 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -947,4 +947,14 @@ #define RGSR_EL1 S3_0_C1_C0_5 #define GCR_EL1 S3_0_C1_C0_6 +/******************************************************************************* + * Definitions for DynamicIQ Shared Unit registers + ******************************************************************************/ +#define CLUSTERPWRDN_EL1 S3_0_c15_c3_6 + +/* CLUSTERPWRDN_EL1 register definitions */ +#define DSU_CLUSTER_PWR_OFF 0 +#define DSU_CLUSTER_PWR_ON 1 +#define DSU_CLUSTER_PWR_MASK U(1) + #endif /* ARCH_H */ diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h index 669a1403c..9cd1ae515 100644 --- a/include/arch/aarch64/arch_helpers.h +++ b/include/arch/aarch64/arch_helpers.h @@ -520,6 +520,9 @@ DEFINE_RENAME_SYSREG_RW_FUNCS(tfsr_el1, TFSR_EL1) DEFINE_RENAME_SYSREG_RW_FUNCS(rgsr_el1, RGSR_EL1) DEFINE_RENAME_SYSREG_RW_FUNCS(gcr_el1, GCR_EL1) +/* DynamIQ Shared Unit power management */ +DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpwrdn_el1, CLUSTERPWRDN_EL1) + #define IS_IN_EL(x) \ (GET_EL(read_CurrentEl()) == MODE_EL##x) @@ -582,4 +585,7 @@ static inline uint64_t el_implemented(unsigned int el) #define read_cpacr() read_cpacr_el1() #define write_cpacr(_v) write_cpacr_el1(_v) +#define read_clusterpwrdn() read_clusterpwrdn_el1() +#define write_clusterpwrdn(_v) write_clusterpwrdn_el1(_v) + #endif /* ARCH_HELPERS_H */ diff --git a/plat/arm/board/fvp/fvp_pm.c b/plat/arm/board/fvp/fvp_pm.c index c47d83779..333d89288 100644 --- a/plat/arm/board/fvp/fvp_pm.c +++ b/plat/arm/board/fvp/fvp_pm.c @@ -64,6 +64,25 @@ static void fvp_cluster_pwrdwn_common(void) /* Disable coherency if this cluster is to be turned off */ fvp_interconnect_disable(); +#if HW_ASSISTED_COHERENCY + uint32_t reg; + + /* + * If we have determined this core to be the last man standing and we + * intend to power down the cluster proactively, we provide a hint to + * the power controller that cluster power is not required when all + * cores are powered down. + * Note that this is only an advisory to power controller and is supported + * by SoCs with DynamIQ Shared Units only. + */ + reg = read_clusterpwrdn(); + + /* Clear and set bit 0 : Cluster power not required */ + reg &= ~DSU_CLUSTER_PWR_MASK; + reg |= DSU_CLUSTER_PWR_OFF; + write_clusterpwrdn(reg); +#endif + /* Program the power controller to turn the cluster off */ fvp_pwrc_write_pcoffr(mpidr); } diff --git a/plat/arm/css/common/css_pm.c b/plat/arm/css/common/css_pm.c index af69c6fb4..8e7452634 100644 --- a/plat/arm/css/common/css_pm.c +++ b/plat/arm/css/common/css_pm.c @@ -124,8 +124,28 @@ static void css_power_down_common(const psci_power_state_t *target_state) plat_arm_gic_cpuif_disable(); /* Cluster is to be turned off, so disable coherency */ - if (CSS_CLUSTER_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF) + if (CSS_CLUSTER_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF) { plat_arm_interconnect_exit_coherency(); + +#if HW_ASSISTED_COHERENCY + uint32_t reg; + + /* + * If we have determined this core to be the last man standing and we + * intend to power down the cluster proactively, we provide a hint to + * the power controller that cluster power is not required when all + * cores are powered down. + * Note that this is only an advisory to power controller and is supported + * by SoCs with DynamIQ Shared Units only. + */ + reg = read_clusterpwrdn(); + + /* Clear and set bit 0 : Cluster power not required */ + reg &= ~DSU_CLUSTER_PWR_MASK; + reg |= DSU_CLUSTER_PWR_OFF; + write_clusterpwrdn(reg); +#endif + } } /******************************************************************************* -- cgit v1.2.3 From 3056819b2bfd97a23b043bda4de0c6330dbcc21e Mon Sep 17 00:00:00 2001 From: laurenw-arm Date: Wed, 15 Apr 2020 15:19:50 -0500 Subject: docs: Updating Release information for v2.4 Signed-off-by: Lauren Wehrmeister Change-Id: I5a7ae778999295f3453b7ab0bfc26351e545fb8f --- docs/about/release-information.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/about/release-information.rst b/docs/about/release-information.rst index fb1e39bdd..f3167fb25 100644 --- a/docs/about/release-information.rst +++ b/docs/about/release-information.rst @@ -42,6 +42,8 @@ depending on project requirement and partner feedback. +-----------------+---------------------------+------------------------------+ | v2.3 | 4th week of Apr '20 | 1st week of Apr '20 | +-----------------+---------------------------+------------------------------+ +| v2.4 | 4th week of Oct '20 | 1st week of Oct '20 | ++-----------------+---------------------------+------------------------------+ Removal of Deprecated Interfaces -------------------------------- @@ -59,9 +61,6 @@ Release version after which it will be removed. +--------------------------------+-------------+---------+---------------------------------------------------------+ | ``__ASSEMBLY__`` macro | Oct '19 | v2.3 | Deprecated in favor of ``__ASSEMBLER__`` | +--------------------------------+-------------+---------+---------------------------------------------------------+ -| Prototype SPCI-based SPM | Oct '19 | v2.2 | Based on outdated Alpha 1 spec. Will be replaced with | -| (services/std_svc/spm) | | | alternative methods of secure partitioning support. | -+--------------------------------+-------------+---------+---------------------------------------------------------+ -------------- -- cgit v1.2.3 From 495553d5725a9ea7f9b1c651144e2278e1518c44 Mon Sep 17 00:00:00 2001 From: laurenw-arm Date: Wed, 15 Apr 2020 17:48:36 -0500 Subject: docs: Fixes and updates for the v2.3 release A small set of misc changes to ensure correctness before the v2.3 release. Signed-off-by: Lauren Wehrmeister Change-Id: I5b4e35b3b46616df0453cecff61f5a414951cd62 --- docs/about/features.rst | 10 +++++----- docs/about/maintainers.rst | 3 --- docs/plat/arm/fvp/index.rst | 16 ++++++++-------- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/docs/about/features.rst b/docs/about/features.rst index 3441c5ebe..58954725f 100644 --- a/docs/about/features.rst +++ b/docs/about/features.rst @@ -86,8 +86,8 @@ Current features 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. -- A prototype implementation of a Secure Partition Manager (SPM) that is based - on the SPCI Alpha 1 and SPRT draft specifications. +- Support for the Secure Partition Manager Dispatcher (SPMD) component as a + new standard service. - Support for ARMv8.3 pointer authentication in the normal and secure worlds. The use of pointer authentication in the normal world is enabled whenever @@ -96,8 +96,8 @@ Current features experimental configuration at this time and requires the ``BRANCH_PROTECTION`` option to be set to non-zero. -- Position-Independent Executable (PIE) support. Initially for BL31 only, with - further support to be added in a future release. +- Position-Independent Executable (PIE) support. Currently for BL2, BL31, and + TSP, with further support to be added in a future release. Still to come ------------- @@ -124,4 +124,4 @@ Still to come -------------- -*Copyright (c) 2019, Arm Limited. All rights reserved.* +*Copyright (c) 2020, Arm Limited. All rights reserved.* diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst index 9e55e60e0..e4fb09d6c 100644 --- a/docs/about/maintainers.rst +++ b/docs/about/maintainers.rst @@ -17,8 +17,6 @@ Main maintainers :G: `sandrine-bailleux-arm`_ :M: Alexei Fedorov :G: `AlexeiFedorov`_ -:M: György Szing -:G: `gyuri-szing`_ :M: Manish Pandey :G: `manish-pandey-arm`_ :M: Mark Dykes @@ -311,7 +309,6 @@ Xilinx platform port .. _etienne-lms: https://github.com/etienne-lms .. _glneo: https://github.com/glneo .. _grandpaul: https://github.com/grandpaul -.. _gyuri-szing: https://github.com/gyuri-szing .. _hzhuang1: https://github.com/hzhuang1 .. _JackyBai: https://github.com/JackyBai .. _jenswi-linaro: https://github.com/jenswi-linaro diff --git a/docs/plat/arm/fvp/index.rst b/docs/plat/arm/fvp/index.rst index 169b6f366..eb7eb0054 100644 --- a/docs/plat/arm/fvp/index.rst +++ b/docs/plat/arm/fvp/index.rst @@ -12,7 +12,7 @@ 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.6 Build 45, unless otherwise stated. + The FVP models used are Version 11.9 Build 41, unless otherwise stated. - ``FVP_Base_AEMv8A-AEMv8A`` - ``FVP_Base_AEMv8A-AEMv8A-AEMv8A-AEMv8A-CCN502`` @@ -26,8 +26,8 @@ Arm FVPs without shifted affinities, and that do not support threaded CPU cores - ``FVP_Base_Cortex-A57x2-A53x4`` - ``FVP_Base_Cortex-A57x4-A53x4`` - ``FVP_Base_Cortex-A57x4`` -- ``FVP_Base_Cortex-A65x4`` (Version 11.9 build 41) -- ``FVP_Base_Cortex-A65AEx8`` (Version 11.9 build 41) +- ``FVP_Base_Cortex-A65x4`` +- ``FVP_Base_Cortex-A65AEx8`` - ``FVP_Base_Cortex-A72x4-A53x4`` - ``FVP_Base_Cortex-A72x4`` - ``FVP_Base_Cortex-A73x4-A53x4`` @@ -36,13 +36,13 @@ Arm FVPs without shifted affinities, and that do not support threaded CPU cores - ``FVP_Base_Cortex-A76x4`` - ``FVP_Base_Cortex-A76AEx4`` - ``FVP_Base_Cortex-A76AEx8`` -- ``FVP_Base_Cortex-A77x4`` (Version 11.7 build 36) +- ``FVP_Base_Cortex-A77x4`` - ``FVP_Base_Neoverse-N1x4`` - ``FVP_Base_Zeusx4`` -- ``FVP_CSS_SGI-575`` (Version 11.3 build 42) -- ``FVP_CSS_SGM-775`` (Version 11.3 build 42) -- ``FVP_RD_E1Edge`` (Version 11.3 build 42) -- ``FVP_RD_N1Edge`` +- ``FVP_CSS_SGI-575`` (Version 11.10 build 25) +- ``FVP_CSS_SGM-775`` +- ``FVP_RD_E1Edge`` +- ``FVP_RD_N1Edge`` (Version 11.10 build 25) - ``Foundation_Platform`` The latest version of the AArch32 build of TF-A has been tested on the -- cgit v1.2.3 From 3ba55a3c5fa260c9218be1adff8f39fc2a568d68 Mon Sep 17 00:00:00 2001 From: laurenw-arm Date: Thu, 16 Apr 2020 10:02:17 -0500 Subject: docs: Update SMCCC doc, other changes for release Signed-off-by: Lauren Wehrmeister Change-Id: Ie842d6a9919776de151a4e9304f870aede07c47a --- docs/about/features.rst | 4 ++-- docs/components/arm-sip-service.rst | 4 ++-- docs/components/debugfs-design.rst | 2 +- docs/components/exception-handling.rst | 2 +- docs/components/secure-partition-manager-design.rst | 4 ++-- docs/design/firmware-design.rst | 4 ++-- docs/design/interrupt-framework-design.rst | 4 ++-- docs/getting_started/psci-lib-integration-guide.rst | 4 ++-- docs/getting_started/rt-svc-writers-guide.rst | 4 ++-- docs/index.rst | 2 +- docs/security_advisories/security-advisory-tfv-8.rst | 2 +- 11 files changed, 18 insertions(+), 18 deletions(-) diff --git a/docs/about/features.rst b/docs/about/features.rst index 58954725f..49b74aefa 100644 --- a/docs/about/features.rst +++ b/docs/about/features.rst @@ -117,11 +117,11 @@ Still to come - Ongoing security hardening, optimization and quality improvements. -.. _SMC Calling Convention: http://infocenter.arm.com/help/topic/com.arm.doc.den0028b/ARM_DEN0028B_SMC_Calling_Convention.pdf +.. _SMC Calling Convention: https://developer.arm.com/docs/den0028/latest .. _OP-TEE Secure OS: https://github.com/OP-TEE/optee_os .. _NVIDIA Trusted Little Kernel: http://nv-tegra.nvidia.com/gitweb/?p=3rdparty/ote_partner/tlk.git;a=summary .. _Trusty Secure OS: https://source.android.com/security/trusty -------------- -*Copyright (c) 2020, Arm Limited. All rights reserved.* +*Copyright (c) 2019-2020, Arm Limited. All rights reserved.* diff --git a/docs/components/arm-sip-service.rst b/docs/components/arm-sip-service.rst index 01bc04d71..b51a94dc7 100644 --- a/docs/components/arm-sip-service.rst +++ b/docs/components/arm-sip-service.rst @@ -430,6 +430,6 @@ uint32_t w1: On success, debugfs interface version, 32 bits -------------- -*Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved.* +*Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.* -.. _SMC Calling Convention: http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html +.. _SMC Calling Convention: https://developer.arm.com/docs/den0028/latest diff --git a/docs/components/debugfs-design.rst b/docs/components/debugfs-design.rst index 8ce1ba6a7..a4f98d064 100644 --- a/docs/components/debugfs-design.rst +++ b/docs/components/debugfs-design.rst @@ -119,7 +119,7 @@ The SMC interface is accessible from an NS environment, that is: *Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.* -.. _SMC Calling Convention PDD: http://infocenter.arm.com/help/topic/com.arm.doc.den0028b/ +.. _SMC Calling Convention: https://developer.arm.com/docs/den0028/latest .. _Notes on the Plan 9 Kernel Source: http://lsub.org/who/nemo/9.pdf .. _Linux 9p remote filesystem protocol: https://www.kernel.org/doc/Documentation/filesystems/9p.txt .. _ARM SiP Services: arm-sip-service.rst diff --git a/docs/components/exception-handling.rst b/docs/components/exception-handling.rst index e330a62a4..4cca5f40b 100644 --- a/docs/components/exception-handling.rst +++ b/docs/components/exception-handling.rst @@ -467,7 +467,7 @@ SMCs from Non-secure world are synchronous exceptions, and are mechanisms for Non-secure world to request Secure services. They're broadly classified as *Fast* or *Yielding* (see `SMCCC`__). -.. __: http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html +.. __: https://developer.arm.com/docs/den0028/latest - *Fast* SMCs are atomic from the caller's point of view. I.e., they return to the caller only when the Secure world has finished serving the request. diff --git a/docs/components/secure-partition-manager-design.rst b/docs/components/secure-partition-manager-design.rst index 52b1c03e8..4f6718594 100644 --- a/docs/components/secure-partition-manager-design.rst +++ b/docs/components/secure-partition-manager-design.rst @@ -807,13 +807,13 @@ Error Codes -------------- -*Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved.* +*Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.* .. _Armv8-A ARM: https://developer.arm.com/docs/ddi0487/latest/arm-architecture-reference-manual-armv8-for-armv8-a-architecture-profile .. _instructions in the EDK2 repository: https://github.com/tianocore/edk2-staging/blob/AArch64StandaloneMm/HowtoBuild.MD .. _Management Mode Interface Specification: http://infocenter.arm.com/help/topic/com.arm.doc.den0060a/DEN0060A_ARM_MM_Interface_Specification.pdf .. _SDEI Specification: http://infocenter.arm.com/help/topic/com.arm.doc.den0054a/ARM_DEN0054A_Software_Delegated_Exception_Interface.pdf -.. _SMC Calling Convention: http://infocenter.arm.com/help/topic/com.arm.doc.den0028b/ARM_DEN0028B_SMC_Calling_Convention.pdf +.. _SMC Calling Convention: https://developer.arm.com/docs/den0028/latest .. |Image 1| image:: ../resources/diagrams/secure_sw_stack_tos.png .. |Image 2| image:: ../resources/diagrams/secure_sw_stack_sp.png diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst index 8e9dc38e4..7d99d8629 100644 --- a/docs/design/firmware-design.rst +++ b/docs/design/firmware-design.rst @@ -2720,11 +2720,11 @@ kernel at boot time. These can be found in the ``fdts`` directory. *Copyright (c) 2013-2020, 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: http://infocenter.arm.com/help/topic/com.arm.doc.den0028b/ARM_DEN0028B_SMC_Calling_Convention.pdf +.. _SMCCC: https://developer.arm.com/docs/den0028/latest .. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf .. _Power State Coordination Interface PDD: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf .. _Arm ARM: https://developer.arm.com/docs/ddi0487/latest -.. _SMC Calling Convention PDD: http://infocenter.arm.com/help/topic/com.arm.doc.den0028b/ARM_DEN0028B_SMC_Calling_Convention.pdf +.. _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 .. |Image 1| image:: ../resources/diagrams/rt-svc-descs-layout.png diff --git a/docs/design/interrupt-framework-design.rst b/docs/design/interrupt-framework-design.rst index d155cb356..14f7227d7 100644 --- a/docs/design/interrupt-framework-design.rst +++ b/docs/design/interrupt-framework-design.rst @@ -1011,9 +1011,9 @@ TSP by returning ``SMC_UNK`` error. -------------- -*Copyright (c) 2014-2019, Arm Limited and Contributors. All rights reserved.* +*Copyright (c) 2014-2020, Arm Limited and Contributors. All rights reserved.* -.. _SMC calling convention: http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html +.. _SMC calling convention: https://developer.arm.com/docs/den0028/latest .. |Image 1| image:: ../resources/diagrams/sec-int-handling.png .. |Image 2| image:: ../resources/diagrams/non-sec-int-handling.png diff --git a/docs/getting_started/psci-lib-integration-guide.rst b/docs/getting_started/psci-lib-integration-guide.rst index 1351fff00..37352659d 100644 --- a/docs/getting_started/psci-lib-integration-guide.rst +++ b/docs/getting_started/psci-lib-integration-guide.rst @@ -538,9 +538,9 @@ workarounds. -------------- -*Copyright (c) 2016-2019, Arm Limited and Contributors. All rights reserved.* +*Copyright (c) 2016-2020, Arm Limited and Contributors. All rights reserved.* .. _PSCI spec: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf -.. _SMCCC: https://silver.arm.com/download/ARM_and_AMBA_Architecture/AR570-DA-80002-r0p0-00rel0/ARM_DEN0028A_SMC_Calling_Convention.pdf +.. _SMCCC: https://developer.arm.com/docs/den0028/latest .. _PSCI specification: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf .. _PSCI Specification: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf diff --git a/docs/getting_started/rt-svc-writers-guide.rst b/docs/getting_started/rt-svc-writers-guide.rst index 5375b659d..b3758b824 100644 --- a/docs/getting_started/rt-svc-writers-guide.rst +++ b/docs/getting_started/rt-svc-writers-guide.rst @@ -314,7 +314,7 @@ provide this information.... -------------- -*Copyright (c) 2014-2019, Arm Limited and Contributors. All rights reserved.* +*Copyright (c) 2014-2020, Arm Limited and Contributors. All rights reserved.* -.. _SMCCC: http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html +.. _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/index.rst b/docs/index.rst index 7413edd1b..cb5312753 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -91,4 +91,4 @@ have previously been raised against the software. .. _Trusted Board Boot Requirements CLIENT (TBBR-CLIENT): https://developer.arm.com/docs/den0006/latest/trusted-board-boot-requirements-client-tbbr-client-armv8-a .. _System Control and Management Interface (SCMI): http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/DEN0056A_System_Control_and_Management_Interface.pdf .. _Software Delegated Exception Interface (SDEI): http://infocenter.arm.com/help/topic/com.arm.doc.den0054a/ARM_DEN0054A_Software_Delegated_Exception_Interface.pdf -.. _SMC Calling Convention: http://infocenter.arm.com/help/topic/com.arm.doc.den0028b/ARM_DEN0028B_SMC_Calling_Convention.pdf +.. _SMC Calling Convention: https://developer.arm.com/docs/den0028/latest diff --git a/docs/security_advisories/security-advisory-tfv-8.rst b/docs/security_advisories/security-advisory-tfv-8.rst index c401eb3df..ebe324e72 100644 --- a/docs/security_advisories/security-advisory-tfv-8.rst +++ b/docs/security_advisories/security-advisory-tfv-8.rst @@ -99,5 +99,5 @@ line 19 (referring to the version of the code as of `commit c385955`_): .. _CVE-2018-19440: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-19440 .. _commit c385955: https://github.com/ARM-software/arm-trusted-firmware/commit/c385955 -.. _SMC Calling Convention: http://arminfo.emea.arm.com/help/topic/com.arm.doc.den0028b/ARM_DEN0028B_SMC_Calling_Convention.pdf +.. _SMC Calling Convention: https://developer.arm.com/docs/den0028/latest .. _Pull Request #1710: https://github.com/ARM-software/arm-trusted-firmware/pull/1710 -- cgit v1.2.3 From 4204e074cd8661d04a43423d3515b1b2f7463936 Mon Sep 17 00:00:00 2001 From: laurenw-arm Date: Tue, 14 Apr 2020 16:44:52 -0500 Subject: docs: Updating Change log for v2.3 Release Updating the change log for the v2.3 release and the upcoming change log template for v2.4 release. Signed-off-by: Lauren Wehrmeister Change-Id: Ice875d3c93227069738a429d4b945512af8470e9 --- docs/change-log-upcoming.rst | 30 +-- docs/change-log.rst | 528 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 532 insertions(+), 26 deletions(-) diff --git a/docs/change-log-upcoming.rst b/docs/change-log-upcoming.rst index f089a5ed6..03806d910 100644 --- a/docs/change-log-upcoming.rst +++ b/docs/change-log-upcoming.rst @@ -7,7 +7,7 @@ of this file will be moved to the collective change-log.rst file at the time of release code freeze. -Upcoming Release Version 2.3 +Upcoming Release Version 2.4 ---------------------------- **Trusted Firmware-A Contributors, @@ -20,56 +20,35 @@ 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). - Example: "Add support for Branch Target Identification (BTI)" - BL-specific - - Enhanced BL2 bootloader flow to load secure partitions based on firmware - configuration data (fconf). + - Example: "Enhanced BL2 bootloader flow to load secure partitions based + on firmware configuration data (fconf)." - 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). + - Example: "Modify FVP makefile for CPUs that support both AArch64/32" - CPU Support - Example: "cortex-a55: Workaround for erratum 1221012" - - Use Speculation Barrier instruction for v8.5+ cores - Drivers - Example: "console: Allow the console to register multiple times" - Libraries - Example: "Introduce BTI support in Library at ROM (romlib)" - - Add Firmware Configuration Framework (fconf). - - Add DebugFS functionality - New Platforms Support - Example: "qemu/qemu_sbsa: New platform support added for QEMU SBSA platform" - Platforms - Example: "arm/common: Introduce wrapper functions to setup secure watchdog" - - plat/arm: Add support for the new `dualroot` chain of trust. - - plat/arm/fvp: Add support for fconf in BL31 and SP_MIN. Populate power - domain desciptor dynamically by leveraging fconf APIs. - PSCI - Example: "Adding new optional PSCI hook ``pwr_domain_on_finish_late``" - Security - Example: "UBSAN support and handlers" - - Add support for optional firmware encryption feature (experimental). - - Introduce a new `dualroot` chain of trust. - - aarch32: stop speculative execution past exception returns. - -- SPCI - - Introduced the SPM Dispatcher (SPMD) component as a new standard service. - Tools - Example: "fiptool: Add support to build fiptool on Windows." @@ -103,7 +82,6 @@ Changed - Example: "Refactor SPSR initialisation code" - Tools - - sptool updated to accomodate building secure partition packages. - Example: "cert_create: Remove RSA PKCS#1 v1.5 support" diff --git a/docs/change-log.rst b/docs/change-log.rst index 7e072a930..7befba437 100644 --- a/docs/change-log.rst +++ b/docs/change-log.rst @@ -4,6 +4,534 @@ 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.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/cornstone700: Add support for mhuv2 and stack protector + + - arm/fvp: Add support for fconf in BL31 and SP_MIN. Populate power + domain desciptor 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 accomodate 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 ----------- -- cgit v1.2.3 From c2c150e7c5bb9f56bd482a6ed98e28a7f1962edf Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Thu, 9 Apr 2020 16:32:20 +0100 Subject: doc: Set fconf as experimental feature Following the messages on the mailing list regarding the possible issue around reading DTB's information, we decided to flag the fconf feature as experimental. A uniform approach should be used to handle properties miss and DTB validation. Signed-off-by: Louis Mayencourt Change-Id: Ib3c86e81fb2e89452c593f68d825d3d8f505e1fb --- docs/about/features.rst | 2 ++ docs/getting_started/build-options.rst | 1 + 2 files changed, 3 insertions(+) diff --git a/docs/about/features.rst b/docs/about/features.rst index 58954725f..baec52b58 100644 --- a/docs/about/features.rst +++ b/docs/about/features.rst @@ -73,6 +73,8 @@ Current features to be configured at runtime if required by the platform. It also enables 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. - Support for alternative boot flows, for example to support platforms where the EL3 Runtime Software is loaded using other firmware or a separate diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 778b49c20..90fe83feb 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -643,6 +643,7 @@ 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. - ``USE_ROMLIB``: This flag determines whether library at ROM will be used. -- cgit v1.2.3 From 71ac931f331906f31e4565eba3d300409cf707a7 Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Fri, 17 Apr 2020 14:06:52 +0200 Subject: doc: Fixup some SMCCC links This is a fixup for patch 3ba55a3c5fa260c9218be1adff8f39fc2a568d68 ("docs: Update SMCCC doc, other changes for release"), where some links names got changed but their references didn't. Change-Id: I980d04dde338f3539a2ec1ae2e807440587b1cf5 Signed-off-by: Sandrine Bailleux --- docs/components/debugfs-design.rst | 2 +- docs/design/firmware-design.rst | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/components/debugfs-design.rst b/docs/components/debugfs-design.rst index a4f98d064..2096bdbb7 100644 --- a/docs/components/debugfs-design.rst +++ b/docs/components/debugfs-design.rst @@ -78,7 +78,7 @@ SMC interface ------------- The communication with the 9p layer in BL31 is made through an SMC conduit -(`SMC Calling Convention PDD`_), using a specific SiP Function Id. An NS +(`SMC Calling Convention`_), using a specific SiP Function Id. An NS shared buffer is used to pass path string parameters, or e.g. to exchange data on a read operation. Refer to `ARM SiP Services`_ for a description of the SMC interface. diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst index 7d99d8629..b336b38e7 100644 --- a/docs/design/firmware-design.rst +++ b/docs/design/firmware-design.rst @@ -544,7 +544,7 @@ It then replaces the exception vectors populated by BL1 with its own. BL31 exception vectors implement more elaborate support for handling SMCs since this is the only mechanism to access the runtime services implemented by BL31 (PSCI for example). BL31 checks each SMC for validity as specified by the -`SMC Calling Convention PDD`_ before passing control to the required SMC +`SMC Calling Convention`_ before passing control to the required SMC handler routine. BL31 programs the ``CNTFRQ_EL0`` register with the clock frequency of the system @@ -2711,7 +2711,7 @@ kernel at boot time. These can be found in the ``fdts`` directory. - `Power State Coordination Interface PDD`_ -- `SMC Calling Convention PDD`_ +- `SMC Calling Convention`_ - :ref:`Interrupt Management Framework` -- cgit v1.2.3 From 868a7d1eb40f0fc1438783cdf2547c140ded8d56 Mon Sep 17 00:00:00 2001 From: Chris Kay Date: Fri, 17 Apr 2020 10:36:34 +0100 Subject: juno/sgm: Align SCP_BL2 to page boundary This commit fixes an assertion that was triggering in certain contexts: ERROR: mmap_add_region_check() failed. error -22 ASSERT: lib/xlat_tables_v2/xlat_tables_core.c:790 Change-Id: Ia55b3fb4f496c8cd791ea6093d122edae0a7e92a Signed-off-by: Chris Kay Signed-off-by: Sandrine Bailleux --- plat/arm/board/juno/include/platform_def.h | 4 +++- plat/arm/css/sgm/include/sgm_base_platform_def.h | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h index 43c267d08..67802d487 100644 --- a/plat/arm/board/juno/include/platform_def.h +++ b/plat/arm/board/juno/include/platform_def.h @@ -253,7 +253,9 @@ * anything else in this memory region and is handed over to the SCP before * BL31 is loaded over the top. */ -#define PLAT_CSS_MAX_SCP_BL2_SIZE (SCP_BL2_LIMIT - ARM_TB_FW_CONFIG_LIMIT) +#define PLAT_CSS_MAX_SCP_BL2_SIZE \ + ((SCP_BL2_LIMIT - ARM_TB_FW_CONFIG_LIMIT) & ~PAGE_SIZE_MASK) + #define PLAT_CSS_MAX_SCP_BL2U_SIZE PLAT_CSS_MAX_SCP_BL2_SIZE #define PLAT_ARM_G1S_IRQ_PROPS(grp) \ diff --git a/plat/arm/css/sgm/include/sgm_base_platform_def.h b/plat/arm/css/sgm/include/sgm_base_platform_def.h index 12fa07f3c..8be0b344f 100644 --- a/plat/arm/css/sgm/include/sgm_base_platform_def.h +++ b/plat/arm/css/sgm/include/sgm_base_platform_def.h @@ -137,7 +137,9 @@ * anything else in this memory region and is handed over to the SCP before * BL31 is loaded over the top. */ -#define PLAT_CSS_MAX_SCP_BL2_SIZE (SCP_BL2_LIMIT - ARM_TB_FW_CONFIG_LIMIT) +#define PLAT_CSS_MAX_SCP_BL2_SIZE \ + ((SCP_BL2_LIMIT - ARM_TB_FW_CONFIG_LIMIT) & ~PAGE_SIZE_MASK) + #define PLAT_CSS_MAX_SCP_BL2U_SIZE PLAT_CSS_MAX_SCP_BL2_SIZE /* -- cgit v1.2.3 From e3c152d1156af8a4b6453376454ecdceaf81704c Mon Sep 17 00:00:00 2001 From: lakshmi Kailasanathan Date: Fri, 17 Apr 2020 12:52:19 +0100 Subject: fdts: a5ds: Fix for the system timer issue. A5DS FPGA system timer clock frequency is 7.5Mhz. The dt is file updated inline with the hardware clock frequency. Change-Id: I3f6c2e0d4a7b293175a42cf398a8730448504af9 Signed-off-by: lakshmi Kailasanathan --- fdts/a5ds.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdts/a5ds.dts b/fdts/a5ds.dts index 7334c4559..c6f5be6fa 100644 --- a/fdts/a5ds.dts +++ b/fdts/a5ds.dts @@ -128,7 +128,7 @@ #size-cells = <1>; ranges; reg = <0x1a040000 0x1000>; - clock-frequency = <50000000>; + clock-frequency = <7500000>; frame@1a050000 { frame-number = <0>; -- cgit v1.2.3 From eca80334a54da09a0d7ffe8e5d0b6c005fe71009 Mon Sep 17 00:00:00 2001 From: Madhukar Pappireddy Date: Mon, 20 Apr 2020 00:01:09 -0500 Subject: Incrementing the minor version to reflect upcoming v2.3 release Change-Id: I27f7d92988fc16f68041c2ddaa8dd3a60362ddd1 Signed-off-by: Madhukar Pappireddy --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d605ae92b..f01a9ae3e 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ # Trusted Firmware Version # VERSION_MAJOR := 2 -VERSION_MINOR := 2 +VERSION_MINOR := 3 # Default goal is build all images .DEFAULT_GOAL := all -- cgit v1.2.3 From 8b815a4e03169e8b00c3345d31250513fb4cc953 Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Fri, 17 Apr 2020 14:19:20 +0200 Subject: doc: Treat Sphinx warnings as errors 'make doc' will now fail if Sphinx outputs any warning messages during documentation generation. Change-Id: I3e466af58ccf29b14a7e61037539b79ab6fc6037 Signed-off-by: Sandrine Bailleux --- docs/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/Makefile b/docs/Makefile index eed3a0815..3dd7ebc4d 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -1,5 +1,5 @@ # -# Copyright (c) 2019, ARM Limited. All rights reserved. +# Copyright (c) 2019-2020, ARM Limited. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -7,7 +7,7 @@ # # You can set these variables from the command line. -SPHINXOPTS = +SPHINXOPTS = -W SPHINXBUILD = sphinx-build SPHINXPROJ = TrustedFirmware-A SOURCEDIR = . -- cgit v1.2.3 From 5a726a5dcc90a92acfc2e2b0557133b2ee1c0375 Mon Sep 17 00:00:00 2001 From: Aditya Angadi Date: Mon, 6 Apr 2020 17:11:23 +0530 Subject: board/rddanielxlr: add support for rd-daniel config-xlr platform RD-Daniel Config-XLR platform has four identical chips connected via a high speed coherent CCIX link. Each chip has four Neoverse cores connected via coherent CMN interconnect. Change-Id: I37d1b91f2b6ba08f61c64d0288bc16a429836c08 Signed-off-by: Aditya Angadi --- .../rddanielxlr/fdts/rddanielxlr_fw_config.dts | 47 ++++++++ .../rddanielxlr/fdts/rddanielxlr_nt_fw_config.dts | 22 ++++ plat/arm/board/rddanielxlr/include/platform_def.h | 37 ++++++ plat/arm/board/rddanielxlr/platform.mk | 57 +++++++++ plat/arm/board/rddanielxlr/rddanielxlr_err.c | 17 +++ plat/arm/board/rddanielxlr/rddanielxlr_plat.c | 131 +++++++++++++++++++++ plat/arm/board/rddanielxlr/rddanielxlr_security.c | 10 ++ plat/arm/board/rddanielxlr/rddanielxlr_topology.c | 78 ++++++++++++ 8 files changed, 399 insertions(+) create mode 100644 plat/arm/board/rddanielxlr/fdts/rddanielxlr_fw_config.dts create mode 100644 plat/arm/board/rddanielxlr/fdts/rddanielxlr_nt_fw_config.dts create mode 100644 plat/arm/board/rddanielxlr/include/platform_def.h create mode 100644 plat/arm/board/rddanielxlr/platform.mk create mode 100644 plat/arm/board/rddanielxlr/rddanielxlr_err.c create mode 100644 plat/arm/board/rddanielxlr/rddanielxlr_plat.c create mode 100644 plat/arm/board/rddanielxlr/rddanielxlr_security.c create mode 100644 plat/arm/board/rddanielxlr/rddanielxlr_topology.c diff --git a/plat/arm/board/rddanielxlr/fdts/rddanielxlr_fw_config.dts b/plat/arm/board/rddanielxlr/fdts/rddanielxlr_fw_config.dts new file mode 100644 index 000000000..81e4cc12d --- /dev/null +++ b/plat/arm/board/rddanielxlr/fdts/rddanielxlr_fw_config.dts @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +/dts-v1/; + +/ { + dtb-registry { + compatible = "arm,dyn_cfg-dtb_registry"; + + /* tb_fw_config is temporarily contained on this dtb */ + tb_fw-config { + load-address = <0x0 0x4001010>; + max-size = <0x200>; + id = ; + }; + + nt_fw-config { + load-address = <0x0 0xFEF00000>; + max-size = <0x0100000>; + id = ; + }; + }; + + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + + /* + * The following two entries are placeholders for Mbed TLS + * heap information. The default values don't matter since + * they will be overwritten by BL1. + * In case of having shared Mbed TLS heap between BL1 and BL2, + * BL1 will populate these two properties with the respective + * info about the shared heap. This info will be available for + * BL2 in order to locate and re-use the heap. + */ + mbedtls_heap_addr = <0x0 0x0>; + mbedtls_heap_size = <0x0>; + }; +}; diff --git a/plat/arm/board/rddanielxlr/fdts/rddanielxlr_nt_fw_config.dts b/plat/arm/board/rddanielxlr/fdts/rddanielxlr_nt_fw_config.dts new file mode 100644 index 000000000..42d07a450 --- /dev/null +++ b/plat/arm/board/rddanielxlr/fdts/rddanielxlr_nt_fw_config.dts @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; +/ { + /* compatible string */ + compatible = "arm,rd-daniel-xlr"; + + /* + * Place holder for system-id node with default values. The + * value of platform-id and config-id will be set to the + * correct values during the BL2 stage of boot. + */ + system-id { + platform-id = <0x0>; + config-id = <0x0>; + multi-chip-mode = <0x0>; + }; +}; diff --git a/plat/arm/board/rddanielxlr/include/platform_def.h b/plat/arm/board/rddanielxlr/include/platform_def.h new file mode 100644 index 000000000..b1376b85d --- /dev/null +++ b/plat/arm/board/rddanielxlr/include/platform_def.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +#include +#include + +#define PLAT_ARM_CLUSTER_COUNT U(4) +#define CSS_SGI_MAX_CPUS_PER_CLUSTER U(1) +#define CSS_SGI_MAX_PE_PER_CPU U(1) + +#define PLAT_CSS_MHU_BASE UL(0x45400000) +#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE + +#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL2 +#define PLAT_MAX_PWR_LVL ARM_PWR_LVL1 + +/* Virtual address used by dynamic mem_protect for chunk_base */ +#define PLAT_ARM_MEM_PROTEC_VA_FRAME UL(0xC0000000) + +/* Physical and virtual address space limits for MMU in AARCH64 mode */ +#define PLAT_PHY_ADDR_SPACE_SIZE CSS_SGI_REMOTE_CHIP_MEM_OFFSET( \ + CSS_SGI_CHIP_COUNT) +#define PLAT_VIRT_ADDR_SPACE_SIZE CSS_SGI_REMOTE_CHIP_MEM_OFFSET( \ + CSS_SGI_CHIP_COUNT) + +/* GIC related constants */ +#define PLAT_ARM_GICD_BASE UL(0x30000000) +#define PLAT_ARM_GICC_BASE UL(0x2C000000) +#define PLAT_ARM_GICR_BASE UL(0x30140000) + +#endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/rddanielxlr/platform.mk b/plat/arm/board/rddanielxlr/platform.mk new file mode 100644 index 000000000..36a00993a --- /dev/null +++ b/plat/arm/board/rddanielxlr/platform.mk @@ -0,0 +1,57 @@ +# Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# Enable GICv4 extension with multichip driver +GIC_ENABLE_V4_EXTN := 1 +GICV3_IMPL_GIC600_MULTICHIP := 1 + +include plat/arm/css/sgi/sgi-common.mk + +RDDANIELXLR_BASE = plat/arm/board/rddanielxlr + +PLAT_INCLUDES += -I${RDDANIELXLR_BASE}/include/ + +SGI_CPU_SOURCES := lib/cpus/aarch64/neoverse_zeus.S + +BL1_SOURCES += ${SGI_CPU_SOURCES} \ + ${RDDANIELXLR_BASE}/rddanielxlr_err.c + +BL2_SOURCES += ${RDDANIELXLR_BASE}/rddanielxlr_plat.c \ + ${RDDANIELXLR_BASE}/rddanielxlr_security.c \ + ${RDDANIELXLR_BASE}/rddanielxlr_err.c \ + lib/utils/mem_region.c \ + plat/arm/common/arm_nor_psci_mem_protect.c + +BL31_SOURCES += ${SGI_CPU_SOURCES} \ + ${RDDANIELXLR_BASE}/rddanielxlr_plat.c \ + ${RDDANIELXLR_BASE}/rddanielxlr_topology.c \ + drivers/cfi/v2m/v2m_flash.c \ + drivers/arm/gic/v3/gic600_multichip.c \ + lib/utils/mem_region.c \ + plat/arm/common/arm_nor_psci_mem_protect.c + +# Enable dynamic addition of MMAP regions in BL31 +BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC + +# Add the FDT_SOURCES and options for Dynamic Config +FDT_SOURCES += ${RDDANIELXLR_BASE}/fdts/${PLAT}_fw_config.dts +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb + +# Add the TB_FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) + +$(eval $(call CREATE_SEQ,SEQ,4)) +ifneq ($(CSS_SGI_CHIP_COUNT),$(filter $(CSS_SGI_CHIP_COUNT),$(SEQ))) + $(error "Chip count for RD-Daniel Config-XLR should be either $(SEQ) \ + currently it is set to ${CSS_SGI_CHIP_COUNT}.") +endif + +FDT_SOURCES += ${RDDANIELXLR_BASE}/fdts/${PLAT}_nt_fw_config.dts +NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb + +# Add the NT_FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config)) + +override CTX_INCLUDE_AARCH32_REGS := 0 diff --git a/plat/arm/board/rddanielxlr/rddanielxlr_err.c b/plat/arm/board/rddanielxlr/rddanielxlr_err.c new file mode 100644 index 000000000..bff57cdae --- /dev/null +++ b/plat/arm/board/rddanielxlr/rddanielxlr_err.c @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +/* + * rddanielxlr error handler + */ +void __dead2 plat_arm_error_handler(int err) +{ + while (true) { + wfi(); + } +} diff --git a/plat/arm/board/rddanielxlr/rddanielxlr_plat.c b/plat/arm/board/rddanielxlr/rddanielxlr_plat.c new file mode 100644 index 000000000..4b5f16a4f --- /dev/null +++ b/plat/arm/board/rddanielxlr/rddanielxlr_plat.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include + +#if defined(IMAGE_BL31) +static const mmap_region_t rddanielxlr_dynamic_mmap[] = { + ARM_MAP_SHARED_RAM_REMOTE_CHIP(1), + CSS_SGI_MAP_DEVICE_REMOTE_CHIP(1), + SOC_CSS_MAP_DEVICE_REMOTE_CHIP(1), +#if (CSS_SGI_CHIP_COUNT > 2) + ARM_MAP_SHARED_RAM_REMOTE_CHIP(2), + CSS_SGI_MAP_DEVICE_REMOTE_CHIP(2), + SOC_CSS_MAP_DEVICE_REMOTE_CHIP(2), +#endif +#if (CSS_SGI_CHIP_COUNT > 3) + ARM_MAP_SHARED_RAM_REMOTE_CHIP(3), + CSS_SGI_MAP_DEVICE_REMOTE_CHIP(3), + SOC_CSS_MAP_DEVICE_REMOTE_CHIP(3) +#endif +}; + +static struct gic600_multichip_data rddanielxlr_multichip_data __init = { + .rt_owner_base = PLAT_ARM_GICD_BASE, + .rt_owner = 0, + .chip_count = CSS_SGI_CHIP_COUNT, + .chip_addrs = { + PLAT_ARM_GICD_BASE >> 16, + (PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1)) >> 16, +#if (CSS_SGI_CHIP_COUNT > 2) + (PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(2)) >> 16, +#endif +#if (CSS_SGI_CHIP_COUNT > 3) + (PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(3)) >> 16, +#endif + }, + .spi_ids = { + {32, 255}, + {0, 0}, +#if (CSS_SGI_CHIP_COUNT > 2) + {0, 0}, +#endif +#if (CSS_SGI_CHIP_COUNT > 3) + {0, 0}, +#endif + } +}; + +static uintptr_t rddanielxlr_multichip_gicr_frames[] = { + /* Chip 0's GICR Base */ + PLAT_ARM_GICR_BASE, + /* Chip 1's GICR BASE */ + PLAT_ARM_GICR_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1), +#if (CSS_SGI_CHIP_COUNT > 2) + /* Chip 2's GICR BASE */ + PLAT_ARM_GICR_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(2), +#endif +#if (CSS_SGI_CHIP_COUNT > 3) + /* Chip 3's GICR BASE */ + PLAT_ARM_GICR_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(3), +#endif + UL(0) /* Zero Termination */ +}; +#endif /* IMAGE_BL31 */ + +unsigned int plat_arm_sgi_get_platform_id(void) +{ + return mmio_read_32(SID_REG_BASE + SID_SYSTEM_ID_OFFSET) + & SID_SYSTEM_ID_PART_NUM_MASK; +} + +unsigned int plat_arm_sgi_get_config_id(void) +{ + return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET); +} + +unsigned int plat_arm_sgi_get_multi_chip_mode(void) +{ + return (mmio_read_32(SID_REG_BASE + SID_NODE_ID_OFFSET) & + SID_MULTI_CHIP_MODE_MASK) >> SID_MULTI_CHIP_MODE_SHIFT; +} + +/* + * bl31_platform_setup_function is guarded by IMAGE_BL31 macro because + * PLAT_XLAT_TABLES_DYNAMIC macro is set to build only for BL31 and not + * for other stages. + */ +#if defined(IMAGE_BL31) +void bl31_platform_setup(void) +{ + int ret; + unsigned int i; + + if ((plat_arm_sgi_get_multi_chip_mode() == 0) && + (CSS_SGI_CHIP_COUNT > 1)) { + ERROR("Chip Count is set to %u but multi-chip mode is not " + "enabled\n", CSS_SGI_CHIP_COUNT); + panic(); + } else if ((plat_arm_sgi_get_multi_chip_mode() == 1) && + (CSS_SGI_CHIP_COUNT > 1)) { + INFO("Enabling support for multi-chip in RD-Daniel Cfg-XLR\n"); + + for (i = 0; i < ARRAY_SIZE(rddanielxlr_dynamic_mmap); i++) { + ret = mmap_add_dynamic_region( + rddanielxlr_dynamic_mmap[i].base_pa, + rddanielxlr_dynamic_mmap[i].base_va, + rddanielxlr_dynamic_mmap[i].size, + rddanielxlr_dynamic_mmap[i].attr); + if (ret != 0) { + ERROR("Failed to add dynamic mmap entry " + "(ret=%d)\n", ret); + panic(); + } + } + + plat_arm_override_gicr_frames( + rddanielxlr_multichip_gicr_frames); + gic600_multichip_init(&rddanielxlr_multichip_data); + } + + sgi_bl31_common_platform_setup(); +} +#endif /* IMAGE_BL31 */ diff --git a/plat/arm/board/rddanielxlr/rddanielxlr_security.c b/plat/arm/board/rddanielxlr/rddanielxlr_security.c new file mode 100644 index 000000000..541f800a8 --- /dev/null +++ b/plat/arm/board/rddanielxlr/rddanielxlr_security.c @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* Initialize the secure environment */ +void plat_arm_security_setup(void) +{ +} diff --git a/plat/arm/board/rddanielxlr/rddanielxlr_topology.c b/plat/arm/board/rddanielxlr/rddanielxlr_topology.c new file mode 100644 index 000000000..610e667ce --- /dev/null +++ b/plat/arm/board/rddanielxlr/rddanielxlr_topology.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +/****************************************************************************** + * The power domain tree descriptor. + ******************************************************************************/ +const unsigned char rd_daniel_xlr_pd_tree_desc_multi_chip[] = { + ((PLAT_ARM_CLUSTER_COUNT) * (CSS_SGI_CHIP_COUNT)), + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, +#if (CSS_SGI_CHIP_COUNT > 1) + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, +#endif +#if (CSS_SGI_CHIP_COUNT > 2) + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, +#endif +#if (CSS_SGI_CHIP_COUNT > 3) + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER +#endif +}; + +/******************************************************************************* + * This function returns the topology tree information. + ******************************************************************************/ +const unsigned char *plat_get_power_domain_tree_desc(void) +{ + if (plat_arm_sgi_get_multi_chip_mode() == 1) + return rd_daniel_xlr_pd_tree_desc_multi_chip; + panic(); +} + +/******************************************************************************* + * The array mapping platform core position (implemented by plat_my_core_pos()) + * to the SCMI power domain ID implemented by SCP. + ******************************************************************************/ +const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = { + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x0)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x1)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x2)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x3)), +#if (CSS_SGI_CHIP_COUNT > 1) + (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x0)), + (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x1)), + (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x2)), + (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x3)), +#endif +#if (CSS_SGI_CHIP_COUNT > 2) + (SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x0)), + (SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x1)), + (SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x2)), + (SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x3)), +#endif +#if (CSS_SGI_CHIP_COUNT > 3) + (SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x0)), + (SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x1)), + (SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x2)), + (SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x3)) +#endif +}; -- cgit v1.2.3 From d7b5f026174b965b08a13e02a8a86a321ed85e72 Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Tue, 31 Mar 2020 10:51:46 +0100 Subject: spm: Normalize the style of spm core manifest Signed-off-by: Louis Mayencourt Change-Id: Ib39e53eb53521b8651fb30b7bf0058f7669569d5 --- plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts index 79c4c07f6..ebfbe174b 100644 --- a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts +++ b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts @@ -27,12 +27,12 @@ vm1 { is_spci_partition; debug_name = "cactus-primary"; - load-addr = <0x7000000>; + load_address = <0x7000000>; }; vm2 { is_spci_partition; debug_name = "cactus-secondary"; - load-addr = <0x7100000>; + load_address = <0x7100000>; vcpu_count = <2>; mem_size = <1048576>; }; -- cgit v1.2.3 From b9f7b57d3a14e629af43bebc531763a923032239 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 7 Apr 2020 11:17:38 +0900 Subject: bl1: remove '.' from stacks section in linker script Only BL1 specifies '.' in the address field of the stacks section. Commit 4f59d8359f97 ("Make BL1 RO and RW base addresses configurable") added '.' on purpose but the commit message does not help to understand why. This commit gets rid of it in order to factor out the stacks section into include/common/bl_common.ld.h I compared the build result for PLAT=qemu. 'aarch64-linux-gnu-nm -n build/qemu/release/bl1/bl1.elf' will change as follows: @@ -336,8 +336,8 @@ 000000000e04e0e0 d max_log_level 000000000e04e0e4 D console_state 000000000e04e0e5 D __DATA_RAM_END__ -000000000e04e0e5 B __STACKS_START__ 000000000e04e100 b platform_normal_stacks +000000000e04e100 B __STACKS_START__ 000000000e04f100 b bl1_cpu_context 000000000e04f100 B __BSS_START__ 000000000e04f100 B __STACKS_END__ After this change, __STACKS_START__ will match to platform_normal_stacks, and I think it makes more sense. 'aarch64-linux-gnu-objdump -h build/qemu/release/bl1/bl1.elf' will change as follows: @@ -9,11 +9,11 @@ CONTENTS, ALLOC, LOAD, READONLY, DATA 2 .data 000000e5 000000000e04e000 0000000000004a60 0001e000 2**4 CONTENTS, ALLOC, LOAD, DATA - 3 stacks 0000101b 000000000e04e0e5 000000000e04e0e5 0001e0e5 2**6 + 3 stacks 00001000 000000000e04e100 0000000000004b45 0001e100 2**6 ALLOC - 4 .bss 000007e0 000000000e04f100 000000000e04f100 0001e0e5 2**5 + 4 .bss 000007e0 000000000e04f100 0000000000004b50 0001f100 2**5 ALLOC - 5 xlat_table 00006000 000000000e050000 000000000e050000 0001e0e5 2**12 + 5 xlat_table 00006000 000000000e050000 0000000000004b45 00020000 2**12 ALLOC 6 coherent_ram 00000000 000000000e056000 000000000e056000 0001f000 2**12 CONTENTS Sandrine pointed me to a useful document [1] to understand why LMAs of stacks, .bss, and xlat_table section have changed. Before this patch, they fell into this scenario: "If the section has a specific VMA address, then this is used as the LMA address as well." With this commit, the following applies: "Otherwise if a memory region can be found that is compatible with the current section, and this region contains at least one section, then the LMA is set so the difference between the VMA and LMA is the same as the difference between the VMA and LMA of the last section in the located region." Anyway, those three sections are not loaded, so the LMA changes will not be a problem. The size of bl1.bin is still the same. QEMU still boots successfully with this change. A good thing is, this fixes the error for the latest LLD. If I use the mainline LLVM, I see the following error. The alignment check will probably be included in the LLVM 11 release, so it is better to fix it now. $ PLAT=qemu CC=clang CROSS_COMPILE=aarch64-linux-gnu- [ snip ] ld.lld: error: address (0xe04e0e5) of section stacks is not a multiple of alignment (64) make: *** [Makefile:1050: build/qemu/release/bl1/bl1.elf] Error 1 [1]: https://sourceware.org/binutils/docs/ld/Output-Section-LMA.html#Output-Section-LMA Change-Id: I3d2f3cc2858be8b3ce2eab3812a76d1e0b5f3a32 Signed-off-by: Masahiro Yamada --- bl1/bl1.ld.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bl1/bl1.ld.S b/bl1/bl1.ld.S index 75355ebff..009a9b59c 100644 --- a/bl1/bl1.ld.S +++ b/bl1/bl1.ld.S @@ -103,7 +103,7 @@ SECTIONS __DATA_RAM_END__ = .; } >RAM AT>ROM - stacks . (NOLOAD) : { + stacks (NOLOAD) : { __STACKS_START__ = .; *(tzfw_normal_stacks) __STACKS_END__ = .; -- cgit v1.2.3 From a926a9f60aa94a034b0a06eed296996363245d30 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 7 Apr 2020 13:04:24 +0900 Subject: linker_script: move stacks section to bl_common.ld.h The stacks section is the same for all BL linker scripts. Move it to the common header file. Change-Id: Ibd253488667ab4f69702d56ff9e9929376704f6c Signed-off-by: Masahiro Yamada --- bl1/bl1.ld.S | 7 +------ bl2/bl2.ld.S | 7 +------ bl2/bl2_el3.ld.S | 7 +------ bl2u/bl2u.ld.S | 7 +------ bl31/bl31.ld.S | 7 +------ bl32/sp_min/sp_min.ld.S | 7 +------ bl32/tsp/tsp.ld.S | 7 +------ plat/mediatek/mt6795/bl31.ld.S | 7 +------ 8 files changed, 8 insertions(+), 48 deletions(-) diff --git a/bl1/bl1.ld.S b/bl1/bl1.ld.S index 009a9b59c..4ebe8a02a 100644 --- a/bl1/bl1.ld.S +++ b/bl1/bl1.ld.S @@ -103,12 +103,7 @@ SECTIONS __DATA_RAM_END__ = .; } >RAM AT>ROM - stacks (NOLOAD) : { - __STACKS_START__ = .; - *(tzfw_normal_stacks) - __STACKS_END__ = .; - } >RAM - + STACK_SECTION >RAM BSS_SECTION >RAM XLAT_TABLE_SECTION >RAM diff --git a/bl2/bl2.ld.S b/bl2/bl2.ld.S index 15df5dd03..17475f061 100644 --- a/bl2/bl2.ld.S +++ b/bl2/bl2.ld.S @@ -88,12 +88,7 @@ SECTIONS __DATA_END__ = .; } >RAM - stacks (NOLOAD) : { - __STACKS_START__ = .; - *(tzfw_normal_stacks) - __STACKS_END__ = .; - } >RAM - + STACK_SECTION >RAM BSS_SECTION >RAM XLAT_TABLE_SECTION >RAM diff --git a/bl2/bl2_el3.ld.S b/bl2/bl2_el3.ld.S index d04f226e9..ea7a23500 100644 --- a/bl2/bl2_el3.ld.S +++ b/bl2/bl2_el3.ld.S @@ -123,12 +123,7 @@ SECTIONS } >RAM __RELA_END__ = .; - stacks (NOLOAD) : { - __STACKS_START__ = .; - *(tzfw_normal_stacks) - __STACKS_END__ = .; - } >RAM - + STACK_SECTION >RAM BSS_SECTION >RAM XLAT_TABLE_SECTION >RAM diff --git a/bl2u/bl2u.ld.S b/bl2u/bl2u.ld.S index 8c0bbbdd0..3ab43825c 100644 --- a/bl2u/bl2u.ld.S +++ b/bl2u/bl2u.ld.S @@ -90,12 +90,7 @@ SECTIONS __DATA_END__ = .; } >RAM - stacks (NOLOAD) : { - __STACKS_START__ = .; - *(tzfw_normal_stacks) - __STACKS_END__ = .; - } >RAM - + STACK_SECTION >RAM BSS_SECTION >RAM XLAT_TABLE_SECTION >RAM diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S index 1cdf7c943..94d03e3da 100644 --- a/bl31/bl31.ld.S +++ b/bl31/bl31.ld.S @@ -158,12 +158,7 @@ SECTIONS __NOBITS_START__ = .; #endif - stacks (NOLOAD) : { - __STACKS_START__ = .; - *(tzfw_normal_stacks) - __STACKS_END__ = .; - } >NOBITS - + STACK_SECTION >NOBITS BSS_SECTION >NOBITS XLAT_TABLE_SECTION >NOBITS diff --git a/bl32/sp_min/sp_min.ld.S b/bl32/sp_min/sp_min.ld.S index da005db64..8e91cec91 100644 --- a/bl32/sp_min/sp_min.ld.S +++ b/bl32/sp_min/sp_min.ld.S @@ -101,12 +101,7 @@ SECTIONS ASSERT(. <= BL32_PROGBITS_LIMIT, "BL32 progbits has exceeded its limit.") #endif - stacks (NOLOAD) : { - __STACKS_START__ = .; - *(tzfw_normal_stacks) - __STACKS_END__ = .; - } >RAM - + STACK_SECTION >RAM BSS_SECTION >RAM XLAT_TABLE_SECTION >RAM diff --git a/bl32/tsp/tsp.ld.S b/bl32/tsp/tsp.ld.S index bf77c9234..7428c0345 100644 --- a/bl32/tsp/tsp.ld.S +++ b/bl32/tsp/tsp.ld.S @@ -91,12 +91,7 @@ SECTIONS ASSERT(. <= TSP_PROGBITS_LIMIT, "TSP progbits has exceeded its limit.") #endif - stacks (NOLOAD) : { - __STACKS_START__ = .; - *(tzfw_normal_stacks) - __STACKS_END__ = .; - } >RAM - + STACK_SECTION >RAM BSS_SECTION >RAM XLAT_TABLE_SECTION >RAM diff --git a/plat/mediatek/mt6795/bl31.ld.S b/plat/mediatek/mt6795/bl31.ld.S index b061b91ce..91ca87cb6 100644 --- a/plat/mediatek/mt6795/bl31.ld.S +++ b/plat/mediatek/mt6795/bl31.ld.S @@ -74,12 +74,7 @@ SECTIONS ASSERT(. <= BL31_PROGBITS_LIMIT, "BL3-1 progbits has exceeded its limit.") #endif - stacks (NOLOAD) : { - __STACKS_START__ = .; - *(tzfw_normal_stacks) - __STACKS_END__ = .; - } >RAM - + STACK_SECTION >RAM BSS_SECTION >RAM __RW_END__ = __BSS_END__; -- cgit v1.2.3 From f1de4c8fd729ba14b3c1b714f14eaeb763c3cbd1 Mon Sep 17 00:00:00 2001 From: Peiyuan Song Date: Sat, 25 Apr 2020 16:53:43 +0800 Subject: Fix build type is empty in version string Signed-off-by: Peiyuan Song Change-Id: I97c2e6f8c12ecf828605811019d47a24293c1ebb --- Makefile | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index f01a9ae3e..5c4f36c4f 100644 --- a/Makefile +++ b/Makefile @@ -94,12 +94,6 @@ endif export Q ECHO -# Default build string (git branch and commit) -ifeq (${BUILD_STRING},) - BUILD_STRING := $(shell git describe --always --dirty --tags 2> /dev/null) -endif -VERSION_STRING := v${VERSION_MAJOR}.${VERSION_MINOR}(${BUILD_TYPE}):${BUILD_STRING} - # The cert_create tool cannot generate certificates individually, so we use the # target 'certificates' to create them all ifneq (${GENERATE_COT},0) @@ -281,6 +275,12 @@ else LOG_LEVEL := 20 endif +# Default build string (git branch and commit) +ifeq (${BUILD_STRING},) + BUILD_STRING := $(shell git describe --always --dirty --tags 2> /dev/null) +endif +VERSION_STRING := v${VERSION_MAJOR}.${VERSION_MINOR}(${BUILD_TYPE}):${BUILD_STRING} + ifeq (${AARCH32_INSTRUCTION_SET},A32) TF_CFLAGS_aarch32 += -marm else ifeq (${AARCH32_INSTRUCTION_SET},T32) -- cgit v1.2.3 From caa3e7e0a4aeb657873bbd2c002c0e33a614eb1d Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 22 Apr 2020 10:50:12 +0900 Subject: linker_script: move .data section to bl_common.ld.h Move the data section to the common header. I slightly tweaked some scripts as follows: [1] bl1.ld.S has ALIGN(16). I added DATA_ALIGN macro, which is 1 by default, but overridden by bl1.ld.S. Currently, ALIGN(16) of the .data section is redundant because commit 412865907699 ("Fix boot failures on some builds linked with ld.lld.") padded out the previous section to work around the issue of LLD version <= 10.0. This will be fixed in the future release of LLVM, so I am keeping the proper way to align LMA. [2] bl1.ld.S and bl2_el3.ld.S define __DATA_RAM_{START,END}__ instead of __DATA_{START,END}__. I put them out of the .data section. [3] SORT_BY_ALIGNMENT() is missing tsp.ld.S, sp_min.ld.S, and mediatek/mt6795/bl31.ld.S. This commit adds SORT_BY_ALIGNMENT() for all images, so the symbol order in those three will change, but I do not think it is a big deal. Change-Id: I215bb23c319f045cd88e6f4e8ee2518c67f03692 Signed-off-by: Masahiro Yamada --- bl1/bl1.ld.S | 26 +++++++++++--------------- bl2/bl2.ld.S | 12 +----------- bl2/bl2_el3.ld.S | 13 +++---------- bl2u/bl2u.ld.S | 12 +----------- bl31/bl31.ld.S | 11 +---------- bl32/sp_min/sp_min.ld.S | 6 +----- bl32/tsp/tsp.ld.S | 6 +----- include/common/bl_common.ld.h | 16 ++++++++++++++++ plat/mediatek/mt6795/bl31.ld.S | 11 +---------- 9 files changed, 36 insertions(+), 77 deletions(-) diff --git a/bl1/bl1.ld.S b/bl1/bl1.ld.S index 4ebe8a02a..bc23828e4 100644 --- a/bl1/bl1.ld.S +++ b/bl1/bl1.ld.S @@ -4,6 +4,14 @@ * SPDX-License-Identifier: BSD-3-Clause */ +/* + * The .data section gets copied from ROM to RAM at runtime. + * Its LMA should be 16-byte aligned to allow efficient copying of 16-bytes + * aligned regions in it. + * Its VMA must be page-aligned as it marks the first read/write page. + */ +#define DATA_ALIGN 16 + #include #include @@ -87,21 +95,9 @@ SECTIONS ASSERT(BL1_RW_BASE == ALIGN(PAGE_SIZE), "BL1_RW_BASE address is not aligned on a page boundary.") - /* - * The .data section gets copied from ROM to RAM at runtime. - * Its LMA should be 16-byte aligned to allow efficient copying of 16-bytes - * aligned regions in it. - * Its VMA must be page-aligned as it marks the first read/write page. - * - * It must be placed at a lower address than the stacks if the stack - * protector is enabled. Alternatively, the .data.stack_protector_canary - * section can be placed independently of the main .data section. - */ - .data . : ALIGN(16) { - __DATA_RAM_START__ = .; - *(SORT_BY_ALIGNMENT(.data*)) - __DATA_RAM_END__ = .; - } >RAM AT>ROM + DATA_SECTION >RAM AT>ROM + __DATA_RAM_START__ = __DATA_START__; + __DATA_RAM_END__ = __DATA_END__; STACK_SECTION >RAM BSS_SECTION >RAM diff --git a/bl2/bl2.ld.S b/bl2/bl2.ld.S index 17475f061..37849c312 100644 --- a/bl2/bl2.ld.S +++ b/bl2/bl2.ld.S @@ -77,17 +77,7 @@ SECTIONS */ __RW_START__ = . ; - /* - * .data must be placed at a lower address than the stacks if the stack - * protector is enabled. Alternatively, the .data.stack_protector_canary - * section can be placed independently of the main .data section. - */ - .data . : { - __DATA_START__ = .; - *(SORT_BY_ALIGNMENT(.data*)) - __DATA_END__ = .; - } >RAM - + DATA_SECTION >RAM STACK_SECTION >RAM BSS_SECTION >RAM XLAT_TABLE_SECTION >RAM diff --git a/bl2/bl2_el3.ld.S b/bl2/bl2_el3.ld.S index ea7a23500..8c45d9898 100644 --- a/bl2/bl2_el3.ld.S +++ b/bl2/bl2_el3.ld.S @@ -101,16 +101,9 @@ SECTIONS */ __RW_START__ = . ; - /* - * .data must be placed at a lower address than the stacks if the stack - * protector is enabled. Alternatively, the .data.stack_protector_canary - * section can be placed independently of the main .data section. - */ - .data . : { - __DATA_RAM_START__ = .; - *(SORT_BY_ALIGNMENT(.data*)) - __DATA_RAM_END__ = .; - } >RAM AT>ROM + DATA_SECTION >RAM AT>ROM + __DATA_RAM_START__ = __DATA_START__; + __DATA_RAM_END__ = __DATA_END__; /* * .rela.dyn needs to come after .data for the read-elf utility to parse diff --git a/bl2u/bl2u.ld.S b/bl2u/bl2u.ld.S index 3ab43825c..a7752a490 100644 --- a/bl2u/bl2u.ld.S +++ b/bl2u/bl2u.ld.S @@ -79,17 +79,7 @@ SECTIONS */ __RW_START__ = . ; - /* - * .data must be placed at a lower address than the stacks if the stack - * protector is enabled. Alternatively, the .data.stack_protector_canary - * section can be placed independently of the main .data section. - */ - .data . : { - __DATA_START__ = .; - *(SORT_BY_ALIGNMENT(.data*)) - __DATA_END__ = .; - } >RAM - + DATA_SECTION >RAM STACK_SECTION >RAM BSS_SECTION >RAM XLAT_TABLE_SECTION >RAM diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S index 94d03e3da..11e86a3c1 100644 --- a/bl31/bl31.ld.S +++ b/bl31/bl31.ld.S @@ -114,16 +114,7 @@ SECTIONS */ __RW_START__ = . ; - /* - * .data must be placed at a lower address than the stacks if the stack - * protector is enabled. Alternatively, the .data.stack_protector_canary - * section can be placed independently of the main .data section. - */ - .data . : { - __DATA_START__ = .; - *(SORT_BY_ALIGNMENT(.data*)) - __DATA_END__ = .; - } >RAM + DATA_SECTION >RAM /* * .rela.dyn needs to come after .data for the read-elf utility to parse diff --git a/bl32/sp_min/sp_min.ld.S b/bl32/sp_min/sp_min.ld.S index 8e91cec91..9e0596f1f 100644 --- a/bl32/sp_min/sp_min.ld.S +++ b/bl32/sp_min/sp_min.ld.S @@ -91,11 +91,7 @@ SECTIONS */ __RW_START__ = . ; - .data . : { - __DATA_START__ = .; - *(.data*) - __DATA_END__ = .; - } >RAM + DATA_SECTION >RAM #ifdef BL32_PROGBITS_LIMIT ASSERT(. <= BL32_PROGBITS_LIMIT, "BL32 progbits has exceeded its limit.") diff --git a/bl32/tsp/tsp.ld.S b/bl32/tsp/tsp.ld.S index 7428c0345..bdcd2cf70 100644 --- a/bl32/tsp/tsp.ld.S +++ b/bl32/tsp/tsp.ld.S @@ -70,11 +70,7 @@ SECTIONS */ __RW_START__ = . ; - .data . : { - __DATA_START__ = .; - *(.data*) - __DATA_END__ = .; - } >RAM + DATA_SECTION >RAM /* * .rela.dyn needs to come after .data for the read-elf utility to parse diff --git a/include/common/bl_common.ld.h b/include/common/bl_common.ld.h index 8ea7d6a8c..97fed7204 100644 --- a/include/common/bl_common.ld.h +++ b/include/common/bl_common.ld.h @@ -17,6 +17,10 @@ #define BSS_ALIGN 8 #endif +#ifndef DATA_ALIGN +#define DATA_ALIGN 1 +#endif + #define CPU_OPS \ . = ALIGN(STRUCT_ALIGN); \ __CPU_OPS_START__ = .; \ @@ -85,6 +89,18 @@ GOT \ BASE_XLAT_TABLE_RO +/* + * .data must be placed at a lower address than the stacks if the stack + * protector is enabled. Alternatively, the .data.stack_protector_canary + * section can be placed independently of the main .data section. + */ +#define DATA_SECTION \ + .data . : ALIGN(DATA_ALIGN) { \ + __DATA_START__ = .; \ + *(SORT_BY_ALIGNMENT(.data*)) \ + __DATA_END__ = .; \ + } + #define STACK_SECTION \ stacks (NOLOAD) : { \ __STACKS_START__ = .; \ diff --git a/plat/mediatek/mt6795/bl31.ld.S b/plat/mediatek/mt6795/bl31.ld.S index 91ca87cb6..3d881fc43 100644 --- a/plat/mediatek/mt6795/bl31.ld.S +++ b/plat/mediatek/mt6795/bl31.ld.S @@ -59,16 +59,7 @@ SECTIONS */ __RW_START__ = . ; - /* - * .data must be placed at a lower address than the stacks if the stack - * protector is enabled. Alternatively, the .data.stack_protector_canary - * section can be placed independently of the main .data section. - */ - .data . : { - __DATA_START__ = .; - *(.data*) - __DATA_END__ = .; - } >RAM + DATA_SECTION >RAM #ifdef BL31_PROGBITS_LIMIT ASSERT(. <= BL31_PROGBITS_LIMIT, "BL3-1 progbits has exceeded its limit.") -- cgit v1.2.3 From dcd08687bffbe5c6ab16b69b805e51b4b0fd7b3c Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 11 Apr 2020 19:02:29 +0200 Subject: rcar_gen3: plat: Zero-terminate the string in unsigned_num_print() Make sure the string generated in unsigned_num_print() is zero-terminated. Signed-off-by: Marek Vasut Change-Id: Ic0ac1ebca255002522159a9152ab41991f043d05 --- plat/renesas/rcar/bl2_plat_setup.c | 1 + 1 file changed, 1 insertion(+) diff --git a/plat/renesas/rcar/bl2_plat_setup.c b/plat/renesas/rcar/bl2_plat_setup.c index 891096724..add2a4f9b 100644 --- a/plat/renesas/rcar/bl2_plat_setup.c +++ b/plat/renesas/rcar/bl2_plat_setup.c @@ -134,6 +134,7 @@ static void unsigned_num_print(unsigned long long int unum, unsigned int radix, while (--i >= 0) *string++ = num_buf[i]; + *string = 0; } #if (RCAR_LOSSY_ENABLE == 1) -- cgit v1.2.3 From 6e3a89f449fa5b4c0153990a64124211197f426a Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 30 Mar 2020 23:21:13 +0100 Subject: fdt/wrappers: Generalise fdtw_read_array() Currently our fdtw_read_array() implementation requires the length of the property to exactly match the requested size, which makes it less flexible for parsing generic device trees. Also the name is slightly misleading, since we treat the cells of the array as 32 bit unsigned integers, performing the endianess conversion. To fix those issues and align the code more with other DT users (Linux kernel or U-Boot), rename the function to "fdt_read_uint32_array", and relax the length check to only check if the property covers at least the number of cells we request. This also changes the variable names to be more in-line with other DT users, and switches to the proper data types. This makes this function more useful in later patches. Change-Id: Id86f4f588ffcb5106d4476763ecdfe35a735fa6c Signed-off-by: Andre Przywara --- common/fdt_wrappers.c | 31 ++++++++++------------- include/common/fdt_wrappers.h | 4 +-- plat/arm/board/fvp/fconf/fconf_hw_config_getter.c | 4 +-- plat/arm/board/fvp/jmptbl.i | 1 + plat/arm/board/juno/jmptbl.i | 1 + plat/arm/common/fconf/arm_fconf_io.c | 3 ++- plat/arm/common/fconf/arm_fconf_sp.c | 4 +-- 7 files changed, 24 insertions(+), 24 deletions(-) diff --git a/common/fdt_wrappers.c b/common/fdt_wrappers.c index ca5b4556d..5afa14271 100644 --- a/common/fdt_wrappers.c +++ b/common/fdt_wrappers.c @@ -65,38 +65,35 @@ int fdtw_read_cells(const void *dtb, int node, const char *prop, /* * Read cells from a given property of the given node. Any number of 32-bit - * cells of the property can be read. The fdt pointer is updated. Returns 0 on - * success, and -1 on error. + * cells of the property can be read. Returns 0 on success, or a negative + * FDT error value otherwise. */ -int fdtw_read_array(const void *dtb, int node, const char *prop, - unsigned int cells, void *value) +int fdt_read_uint32_array(const void *dtb, int node, const char *prop_name, + unsigned int cells, uint32_t *value) { - const uint32_t *value_ptr; + const fdt32_t *prop; int value_len; assert(dtb != NULL); - assert(prop != NULL); + assert(prop_name != NULL); assert(value != NULL); assert(node >= 0); /* Access property and obtain its length (in bytes) */ - value_ptr = fdt_getprop_namelen(dtb, node, prop, (int)strlen(prop), - &value_len); - if (value_ptr == NULL) { - WARN("Couldn't find property %s in dtb\n", prop); - return -1; + prop = fdt_getprop(dtb, node, prop_name, &value_len); + if (prop == NULL) { + WARN("Couldn't find property %s in dtb\n", prop_name); + return -FDT_ERR_NOTFOUND; } - /* Verify that property length accords with cell length */ - if (NCELLS((unsigned int)value_len) != cells) { + /* Verify that property length can fill the entire array. */ + if (NCELLS((unsigned int)value_len) < cells) { WARN("Property length mismatch\n"); - return -1; + return -FDT_ERR_BADVALUE; } - uint32_t *dst = value; - for (unsigned int i = 0U; i < cells; i++) { - dst[i] = fdt32_to_cpu(value_ptr[i]); + value[i] = fdt32_to_cpu(prop[i]); } return 0; diff --git a/include/common/fdt_wrappers.h b/include/common/fdt_wrappers.h index f467958b7..e3158f1c5 100644 --- a/include/common/fdt_wrappers.h +++ b/include/common/fdt_wrappers.h @@ -14,8 +14,8 @@ int fdtw_read_cells(const void *dtb, int node, const char *prop, unsigned int cells, void *value); -int fdtw_read_array(const void *dtb, int node, const char *prop, - unsigned int cells, void *value); +int fdt_read_uint32_array(const void *dtb, int node, const char *prop_name, + unsigned int cells, uint32_t *value); int fdtw_read_string(const void *dtb, int node, const char *prop, char *str, size_t size); int fdtw_write_inplace_cells(void *dtb, int node, const char *prop, 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 2952cde80..bac1f1587 100644 --- a/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c +++ b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c @@ -18,7 +18,7 @@ int fconf_populate_gicv3_config(uintptr_t config) { int err; int node; - int addr[20]; + uint32_t addr[20]; /* Necessary to work with libfdt APIs */ const void *hw_config_dtb = (const void *)config; @@ -42,7 +42,7 @@ int fconf_populate_gicv3_config(uintptr_t config) <0x0 0x2c02f000 0 0x2000>; // GICV */ - err = fdtw_read_array(hw_config_dtb, node, "reg", 20, &addr); + err = fdt_read_uint32_array(hw_config_dtb, node, "reg", 20, addr); if (err < 0) { ERROR("FCONF: Failed to read reg property of GIC node\n"); } diff --git a/plat/arm/board/fvp/jmptbl.i b/plat/arm/board/fvp/jmptbl.i index 0c93d0aab..6469e2995 100644 --- a/plat/arm/board/fvp/jmptbl.i +++ b/plat/arm/board/fvp/jmptbl.i @@ -15,6 +15,7 @@ # fdt fdt_getprop_namelen patch rom rom_lib_init +fdt fdt_getprop fdt fdt_getprop_namelen fdt fdt_setprop_inplace fdt fdt_check_header diff --git a/plat/arm/board/juno/jmptbl.i b/plat/arm/board/juno/jmptbl.i index b1b9ed463..66d6e4592 100644 --- a/plat/arm/board/juno/jmptbl.i +++ b/plat/arm/board/juno/jmptbl.i @@ -15,6 +15,7 @@ # fdt fdt_getprop_namelen patch rom rom_lib_init +fdt fdt_getprop fdt fdt_getprop_namelen fdt fdt_setprop_inplace fdt fdt_check_header diff --git a/plat/arm/common/fconf/arm_fconf_io.c b/plat/arm/common/fconf/arm_fconf_io.c index 6ebc467ed..26e51b2a3 100644 --- a/plat/arm/common/fconf/arm_fconf_io.c +++ b/plat/arm/common/fconf/arm_fconf_io.c @@ -241,7 +241,8 @@ int fconf_populate_arm_io_policies(uintptr_t config) /* Locate the uuid cells and read the value for all the load info uuid */ for (i = 0; i < FCONF_ARM_IO_UUID_NUMBER; i++) { uuid_ptr = pool_alloc(&fconf_arm_uuids_pool); - err = fdtw_read_array(dtb, node, load_info[i].name, 4, &uuid_helper.word); + err = fdt_read_uint32_array(dtb, node, load_info[i].name, + 4, uuid_helper.word); if (err < 0) { WARN("FCONF: Read cell failed for %s\n", load_info[i].name); return err; diff --git a/plat/arm/common/fconf/arm_fconf_sp.c b/plat/arm/common/fconf/arm_fconf_sp.c index 9b6fa9b1f..c46ecb114 100644 --- a/plat/arm/common/fconf/arm_fconf_sp.c +++ b/plat/arm/common/fconf/arm_fconf_sp.c @@ -44,8 +44,8 @@ int fconf_populate_arm_sp(uintptr_t config) } fdt_for_each_subnode(sp_node, dtb, node) { - err = fdtw_read_array(dtb, sp_node, "uuid", 4, - &uuid_helper.word); + err = fdt_read_uint32_array(dtb, sp_node, "uuid", 4, + uuid_helper.word); if (err < 0) { ERROR("FCONF: cannot read SP uuid\n"); return -1; -- cgit v1.2.3 From 52a616b48c617fe8721106f29f2910ca4681afea Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 26 Mar 2020 12:51:21 +0000 Subject: plat/stm32: Use generic fdt_read_uint32_array() implementation The device tree parsing code for the STM32 platform is using its own FDT helper functions, some of them being rather generic. In particular the existing fdt_read_uint32_array() implementation is now almost identical to the new generic code in fdt_wrappers.c, so we can remove the ST specific version and adjust the existing callers. Compared to the original ST implementation the new version takes a pointer to the DTB as the first argument, and also swaps the order of the number of cells and the pointer. Change-Id: Id06b0f1ba4db1ad1f733be40e82c34f46638551a Signed-off-by: Andre Przywara --- drivers/st/clk/stm32mp1_clk.c | 22 +++++++++++++-------- drivers/st/clk/stm32mp_clkfunc.c | 7 ++++--- drivers/st/ddr/stm32mp1_ram.c | 7 ++++--- include/drivers/st/stm32mp_clkfunc.h | 4 ++-- plat/st/common/include/stm32mp_dt.h | 2 -- plat/st/common/stm32mp_dt.c | 38 +++--------------------------------- plat/st/stm32mp1/platform.mk | 3 ++- 7 files changed, 29 insertions(+), 54 deletions(-) diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c index 0cc87cc71..a16f36dcc 100644 --- a/drivers/st/clk/stm32mp1_clk.c +++ b/drivers/st/clk/stm32mp1_clk.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -1600,20 +1601,25 @@ int stm32mp1_clk_init(void) bool pll4_preserve = false; bool pll4_bootrom = false; const fdt32_t *pkcs_cell; + void *fdt; + + if (fdt_get_address(&fdt) == 0) { + return false; + } /* Check status field to disable security */ if (!fdt_get_rcc_secure_status()) { mmio_write_32(rcc_base + RCC_TZCR, 0); } - ret = fdt_rcc_read_uint32_array("st,clksrc", clksrc, - (uint32_t)CLKSRC_NB); + ret = fdt_rcc_read_uint32_array("st,clksrc", (uint32_t)CLKSRC_NB, + clksrc); if (ret < 0) { return -FDT_ERR_NOTFOUND; } - ret = fdt_rcc_read_uint32_array("st,clkdiv", clkdiv, - (uint32_t)CLKDIV_NB); + ret = fdt_rcc_read_uint32_array("st,clkdiv", (uint32_t)CLKDIV_NB, + clkdiv); if (ret < 0) { return -FDT_ERR_NOTFOUND; } @@ -1628,8 +1634,8 @@ int stm32mp1_clk_init(void) continue; } - ret = fdt_read_uint32_array(plloff[i], "cfg", - pllcfg[i], (int)PLLCFG_NB); + ret = fdt_read_uint32_array(fdt, plloff[i], "cfg", + (int)PLLCFG_NB, pllcfg[i]); if (ret < 0) { return -FDT_ERR_NOTFOUND; } @@ -1800,8 +1806,8 @@ int stm32mp1_clk_init(void) if (ret != 0) { return ret; } - ret = fdt_read_uint32_array(plloff[i], "csg", csg, - (uint32_t)PLLCSG_NB); + ret = fdt_read_uint32_array(fdt, plloff[i], "csg", + (uint32_t)PLLCSG_NB, csg); if (ret == 0) { stm32mp1_pll_csg(i, csg); } else if (ret != -FDT_ERR_NOTFOUND) { diff --git a/drivers/st/clk/stm32mp_clkfunc.c b/drivers/st/clk/stm32mp_clkfunc.c index 87c8e2b84..6404d9933 100644 --- a/drivers/st/clk/stm32mp_clkfunc.c +++ b/drivers/st/clk/stm32mp_clkfunc.c @@ -10,6 +10,7 @@ #include +#include #include #include @@ -200,8 +201,8 @@ uint32_t fdt_rcc_read_addr(void) * @param count: number of parameters to be read * @return: 0 on succes or a negative value on error */ -int fdt_rcc_read_uint32_array(const char *prop_name, - uint32_t *array, uint32_t count) +int fdt_rcc_read_uint32_array(const char *prop_name, uint32_t count, + uint32_t *array) { int node; void *fdt; @@ -215,7 +216,7 @@ int fdt_rcc_read_uint32_array(const char *prop_name, return -FDT_ERR_NOTFOUND; } - return fdt_read_uint32_array(node, prop_name, array, count); + return fdt_read_uint32_array(fdt, node, prop_name, count, array); } /* diff --git a/drivers/st/ddr/stm32mp1_ram.c b/drivers/st/ddr/stm32mp1_ram.c index 40cd4554f..273dec0df 100644 --- a/drivers/st/ddr/stm32mp1_ram.c +++ b/drivers/st/ddr/stm32mp1_ram.c @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -223,10 +224,10 @@ static int stm32mp1_ddr_setup(void) INFO("RAM: %s\n", config.info.name); for (idx = 0; idx < ARRAY_SIZE(param); idx++) { - ret = fdt_read_uint32_array(node, param[idx].name, + ret = fdt_read_uint32_array(fdt, node, param[idx].name, + param[idx].size, (void *)((uintptr_t)&config + - param[idx].offset), - param[idx].size); + param[idx].offset)); VERBOSE("%s: %s[0x%x] = %d\n", __func__, param[idx].name, param[idx].size, ret); diff --git a/include/drivers/st/stm32mp_clkfunc.h b/include/drivers/st/stm32mp_clkfunc.h index 076916730..0902f445d 100644 --- a/include/drivers/st/stm32mp_clkfunc.h +++ b/include/drivers/st/stm32mp_clkfunc.h @@ -21,8 +21,8 @@ uint32_t fdt_osc_read_uint32_default(enum stm32mp_osc_id osc_id, int fdt_get_rcc_node(void *fdt); uint32_t fdt_rcc_read_addr(void); -int fdt_rcc_read_uint32_array(const char *prop_name, - uint32_t *array, uint32_t count); +int fdt_rcc_read_uint32_array(const char *prop_name, uint32_t count, + uint32_t *array); int fdt_rcc_subnode_offset(const char *name); const fdt32_t *fdt_rcc_read_prop(const char *prop_name, int *lenp); bool fdt_get_rcc_secure_status(void); diff --git a/plat/st/common/include/stm32mp_dt.h b/plat/st/common/include/stm32mp_dt.h index a29d9148d..92f3d6528 100644 --- a/plat/st/common/include/stm32mp_dt.h +++ b/plat/st/common/include/stm32mp_dt.h @@ -30,8 +30,6 @@ bool fdt_check_node(int node); uint8_t fdt_get_status(int node); uint32_t fdt_read_uint32_default(int node, const char *prop_name, uint32_t dflt_value); -int fdt_read_uint32_array(int node, const char *prop_name, - uint32_t *array, uint32_t count); int fdt_get_reg_props_by_name(int node, const char *name, uintptr_t *base, size_t *size); int dt_set_stdout_pinctrl(void); diff --git a/plat/st/common/stm32mp_dt.c b/plat/st/common/stm32mp_dt.c index acb323cf2..6b76424ae 100644 --- a/plat/st/common/stm32mp_dt.c +++ b/plat/st/common/stm32mp_dt.c @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -154,39 +155,6 @@ uint32_t fdt_read_uint32_default(int node, const char *prop_name, return fdt32_to_cpu(*cuint); } -/******************************************************************************* - * This function reads a series of parameters in a node property - * (generic use of fdt library). - * It reads the values inside the device tree, from property name and node. - * The number of parameters is also indicated as entry parameter. - * Returns 0 on success and a negative FDT error code on failure. - * If success, values are stored at the third parameter address. - ******************************************************************************/ -int fdt_read_uint32_array(int node, const char *prop_name, uint32_t *array, - uint32_t count) -{ - const fdt32_t *cuint; - int len; - uint32_t i; - - cuint = fdt_getprop(fdt, node, prop_name, &len); - if (cuint == NULL) { - return -FDT_ERR_NOTFOUND; - } - - if ((uint32_t)len != (count * sizeof(uint32_t))) { - return -FDT_ERR_BADLAYOUT; - } - - for (i = 0; i < ((uint32_t)len / sizeof(uint32_t)); i++) { - *array = fdt32_to_cpu(*cuint); - array++; - cuint++; - } - - return 0; -} - /******************************************************************************* * This function fills reg node info (base & size) with an index found by * checking the reg-names node. @@ -396,7 +364,7 @@ uintptr_t dt_get_ddrctrl_base(void) assert((fdt_get_node_parent_address_cells(node) == 1) && (fdt_get_node_parent_size_cells(node) == 1)); - if (fdt_read_uint32_array(node, "reg", array, 4) < 0) { + if (fdt_read_uint32_array(fdt, node, "reg", 4, array) < 0) { return 0; } @@ -421,7 +389,7 @@ uintptr_t dt_get_ddrphyc_base(void) assert((fdt_get_node_parent_address_cells(node) == 1) && (fdt_get_node_parent_size_cells(node) == 1)); - if (fdt_read_uint32_array(node, "reg", array, 4) < 0) { + if (fdt_read_uint32_array(fdt, node, "reg", 4, array) < 0) { return 0; } diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk index 5ce7a9c4f..b0ba82abf 100644 --- a/plat/st/stm32mp1/platform.mk +++ b/plat/st/stm32mp1/platform.mk @@ -62,7 +62,8 @@ DTC_FLAGS += -Wno-unit_address_vs_reg include lib/libfdt/libfdt.mk -PLAT_BL_COMMON_SOURCES := plat/st/common/stm32mp_common.c \ +PLAT_BL_COMMON_SOURCES := common/fdt_wrappers.c \ + plat/st/common/stm32mp_common.c \ plat/st/stm32mp1/stm32mp1_private.c PLAT_BL_COMMON_SOURCES += drivers/st/uart/aarch32/stm32_console.S -- cgit v1.2.3 From ff4e6c35c9f3f0b1d190b5d3761a13d701af6925 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 26 Mar 2020 11:22:37 +0000 Subject: fdt/wrappers: Replace fdtw_read_cells() implementation Our fdtw_read_cells() implementation goes to great lengths to sanity-check every parameter and result, but leaves a big hole open: The size of the storage the value pointer points at needs to match the number of cells given. This can't be easily checked at compile time, since we lose the size information by using a void pointer. Regardless the current usage of this function is somewhat wrong anyways, since we use it on single-element, fixed-length properties only, for which the DT binding specifies the size. Typically we use those functions dealing with a number of cells in DT context to deal with *dynamically* sized properties, which depend on other properties (#size-cells, #clock-cells, ...), to specify the number of cells needed. Another problem with the current implementation is the use of ambiguously sized types (uintptr_t, size_t) together with a certain expectation about their size. In general there is no relation between the length of a DT property and the bitness of the code that parses the DTB: AArch64 code could encounter 32-bit addresses (where the physical address space is limited to 4GB [1]), while AArch32 code could read 64-bit sized properties (/memory nodes on LPAE systems, [2]). To make this more clear, fix the potential issues and also align more with other DT users (Linux and U-Boot), introduce functions to explicitly read uint32 and uint64 properties. As the other DT consumers, we do this based on the generic "read array" function. Convert all users to use either of those two new functions, and make sure we never use a pointer to anything other than uint32_t or uint64_t variables directly. This reveals (and fixes) a bug in plat_spmd_manifest.c, where we write 4 bytes into a uint16_t variable (passed via a void pointer). Also we change the implementation of the function to better align with other libfdt users, by using the right types (fdt32_t) and common variable names (*prop, prop_names). [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi#n874 [2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm/boot/dts/ecx-2000.dts Change-Id: I718de960515117ac7a3331a1b177d2ec224a3890 Signed-off-by: Andre Przywara --- common/fdt_wrappers.c | 70 +++++++---------------- include/common/fdt_wrappers.h | 6 +- lib/fconf/fconf_dyn_cfg_getter.c | 12 +++- lib/fconf/fconf_tbbr_getter.c | 12 ++-- plat/arm/board/fvp/fconf/fconf_hw_config_getter.c | 9 +-- plat/arm/common/fconf/arm_fconf_sp.c | 5 +- plat/common/plat_spmd_manifest.c | 16 +++--- 7 files changed, 58 insertions(+), 72 deletions(-) diff --git a/common/fdt_wrappers.c b/common/fdt_wrappers.c index 5afa14271..394f3b0ca 100644 --- a/common/fdt_wrappers.c +++ b/common/fdt_wrappers.c @@ -14,55 +14,6 @@ #include #include -/* - * Read cells from a given property of the given node. At most 2 cells of the - * property are read, and pointer is updated. Returns 0 on success, and -1 upon - * error - */ -int fdtw_read_cells(const void *dtb, int node, const char *prop, - unsigned int cells, void *value) -{ - const uint32_t *value_ptr; - uint32_t hi = 0, lo; - int value_len; - - assert(dtb != NULL); - assert(prop != NULL); - assert(value != NULL); - assert(node >= 0); - - /* We expect either 1 or 2 cell property */ - assert(cells <= 2U); - - /* Access property and obtain its length (in bytes) */ - value_ptr = fdt_getprop_namelen(dtb, node, prop, (int)strlen(prop), - &value_len); - if (value_ptr == NULL) { - WARN("Couldn't find property %s in dtb\n", prop); - return -1; - } - - /* Verify that property length accords with cell length */ - if (NCELLS((unsigned int)value_len) != cells) { - WARN("Property length mismatch\n"); - return -1; - } - - if (cells == 2U) { - hi = fdt32_to_cpu(*value_ptr); - value_ptr++; - } - - lo = fdt32_to_cpu(*value_ptr); - - if (cells == 2U) - *((uint64_t *) value) = ((uint64_t) hi << 32) | lo; - else - *((uint32_t *) value) = lo; - - return 0; -} - /* * Read cells from a given property of the given node. Any number of 32-bit * cells of the property can be read. Returns 0 on success, or a negative @@ -99,6 +50,27 @@ int fdt_read_uint32_array(const void *dtb, int node, const char *prop_name, return 0; } +int fdt_read_uint32(const void *dtb, int node, const char *prop_name, + uint32_t *value) +{ + return fdt_read_uint32_array(dtb, node, prop_name, 1, value); +} + +int fdt_read_uint64(const void *dtb, int node, const char *prop_name, + uint64_t *value) +{ + uint32_t array[2] = {0, 0}; + int ret; + + ret = fdt_read_uint32_array(dtb, node, prop_name, 2, array); + if (ret < 0) { + return ret; + } + + *value = ((uint64_t)array[0] << 32) | array[1]; + return 0; +} + /* * Read bytes from a given property of the given node. Any number of * bytes of the property can be read. The fdt pointer is updated. diff --git a/include/common/fdt_wrappers.h b/include/common/fdt_wrappers.h index e3158f1c5..e28dee142 100644 --- a/include/common/fdt_wrappers.h +++ b/include/common/fdt_wrappers.h @@ -12,8 +12,10 @@ /* Number of cells, given total length in bytes. Each cell is 4 bytes long */ #define NCELLS(len) ((len) / 4U) -int fdtw_read_cells(const void *dtb, int node, const char *prop, - unsigned int cells, void *value); +int fdt_read_uint32(const void *dtb, int node, const char *prop_name, + uint32_t *value); +int fdt_read_uint64(const void *dtb, int node, const char *prop_name, + uint64_t *value); int fdt_read_uint32_array(const void *dtb, int node, const char *prop_name, unsigned int cells, uint32_t *value); int fdtw_read_string(const void *dtb, int node, const char *prop, diff --git a/lib/fconf/fconf_dyn_cfg_getter.c b/lib/fconf/fconf_dyn_cfg_getter.c index 317d3e5d3..03aaf9bb6 100644 --- a/lib/fconf/fconf_dyn_cfg_getter.c +++ b/lib/fconf/fconf_dyn_cfg_getter.c @@ -57,26 +57,32 @@ int fconf_populate_dtb_registry(uintptr_t config) } fdt_for_each_subnode(child, dtb, node) { + uint32_t val32; + uint64_t val64; + dtb_info = pool_alloc(&dtb_info_pool); /* Read configuration dtb information */ - rc = fdtw_read_cells(dtb, child, "load-address", 2, &dtb_info->config_addr); + rc = fdt_read_uint64(dtb, child, "load-address", &val64); if (rc < 0) { ERROR("FCONF: Incomplete configuration property in dtb-registry.\n"); return rc; } + dtb_info->config_addr = (uintptr_t)val64; - rc = fdtw_read_cells(dtb, child, "max-size", 1, &dtb_info->config_max_size); + rc = fdt_read_uint32(dtb, child, "max-size", &val32); if (rc < 0) { ERROR("FCONF: Incomplete configuration property in dtb-registry.\n"); return rc; } + dtb_info->config_max_size = val32; - rc = fdtw_read_cells(dtb, child, "id", 1, &dtb_info->config_id); + rc = fdt_read_uint32(dtb, child, "id", &val32); if (rc < 0) { ERROR("FCONF: Incomplete configuration property in dtb-registry.\n"); return rc; } + dtb_info->config_id = val32; VERBOSE("FCONF: dyn_cfg.dtb_registry cell found with:\n"); VERBOSE("\tload-address = %lx\n", dtb_info->config_addr); diff --git a/lib/fconf/fconf_tbbr_getter.c b/lib/fconf/fconf_tbbr_getter.c index a4d61d8cd..21278019e 100644 --- a/lib/fconf/fconf_tbbr_getter.c +++ b/lib/fconf/fconf_tbbr_getter.c @@ -17,6 +17,8 @@ int fconf_populate_tbbr_dyn_config(uintptr_t config) { int err; int node; + uint64_t val64; + uint32_t val32; /* As libfdt use void *, we can't avoid this cast */ const void *dtb = (void *)config; @@ -30,7 +32,7 @@ int fconf_populate_tbbr_dyn_config(uintptr_t config) } /* Locate the disable_auth cell and read the value */ - err = fdtw_read_cells(dtb, node, "disable_auth", 1, &tbbr_dyn_config.disable_auth); + err = fdt_read_uint32(dtb, node, "disable_auth", &tbbr_dyn_config.disable_auth); if (err < 0) { WARN("FCONF: Read cell failed for `disable_auth`\n"); return err; @@ -48,19 +50,19 @@ int fconf_populate_tbbr_dyn_config(uintptr_t config) #endif /* Retrieve the Mbed TLS heap details from the DTB */ - err = fdtw_read_cells(dtb, node, - "mbedtls_heap_addr", 2, &tbbr_dyn_config.mbedtls_heap_addr); + err = fdt_read_uint64(dtb, node, "mbedtls_heap_addr", &val64); if (err < 0) { ERROR("FCONF: Read cell failed for mbedtls_heap\n"); return err; } + tbbr_dyn_config.mbedtls_heap_addr = (void *)(uintptr_t)val64; - err = fdtw_read_cells(dtb, node, - "mbedtls_heap_size", 1, &tbbr_dyn_config.mbedtls_heap_size); + err = fdt_read_uint32(dtb, node, "mbedtls_heap_size", &val32); if (err < 0) { ERROR("FCONF: Read cell failed for mbedtls_heap\n"); return err; } + tbbr_dyn_config.mbedtls_heap_size = val32; VERBOSE("FCONF:tbbr.disable_auth cell found with value = %d\n", tbbr_dyn_config.disable_auth); 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 bac1f1587..44e9d0135 100644 --- a/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c +++ b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c @@ -51,8 +51,9 @@ int fconf_populate_gicv3_config(uintptr_t config) int fconf_populate_topology(uintptr_t config) { - int err, node, cluster_node, core_node, thread_node, max_pwr_lvl = 0; + int err, node, cluster_node, core_node, thread_node; uint32_t cluster_count = 0, max_cpu_per_cluster = 0, total_cpu_count = 0; + uint32_t max_pwr_lvl = 0; /* Necessary to work with libfdt APIs */ const void *hw_config_dtb = (const void *)config; @@ -64,7 +65,7 @@ int fconf_populate_topology(uintptr_t config) return node; } - err = fdtw_read_cells(hw_config_dtb, node, "max-pwr-lvl", 1, &max_pwr_lvl); + err = fdt_read_uint32(hw_config_dtb, node, "max-pwr-lvl", &max_pwr_lvl); if (err < 0) { /* * Some legacy FVP dts may not have this property. Assign the default @@ -74,7 +75,7 @@ int fconf_populate_topology(uintptr_t config) max_pwr_lvl = 2; } - assert((uint32_t)max_pwr_lvl <= MPIDR_AFFLVL2); + assert(max_pwr_lvl <= MPIDR_AFFLVL2); /* Find the offset of the "cpus" node */ node = fdt_path_offset(hw_config_dtb, "/cpus"); @@ -156,7 +157,7 @@ int fconf_populate_topology(uintptr_t config) return -1; } - soc_topology.plat_max_pwr_level = (uint32_t)max_pwr_lvl; + soc_topology.plat_max_pwr_level = max_pwr_lvl; soc_topology.plat_cluster_count = cluster_count; soc_topology.cluster_cpu_count = max_cpu_per_cluster; soc_topology.plat_cpu_count = total_cpu_count; diff --git a/plat/arm/common/fconf/arm_fconf_sp.c b/plat/arm/common/fconf/arm_fconf_sp.c index c46ecb114..1b09bc8e5 100644 --- a/plat/arm/common/fconf/arm_fconf_sp.c +++ b/plat/arm/common/fconf/arm_fconf_sp.c @@ -29,6 +29,7 @@ int fconf_populate_arm_sp(uintptr_t config) int sp_node, node, err; union uuid_helper_t uuid_helper; unsigned int index = 0; + uint32_t val32; const unsigned int sp_start_index = MAX_NUMBER_IDS - MAX_SP_IDS; /* As libfdt use void *, we can't avoid this cast */ @@ -53,12 +54,12 @@ int fconf_populate_arm_sp(uintptr_t config) arm_sp.uuids[index] = uuid_helper; - err = fdtw_read_cells(dtb, sp_node, "load-address", 1, - &arm_sp.load_addr[index]); + 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 %x-%x-%x-%x load_addr=%lx\n", __func__, diff --git a/plat/common/plat_spmd_manifest.c b/plat/common/plat_spmd_manifest.c index f0aa27cfb..8330356ae 100644 --- a/plat/common/plat_spmd_manifest.c +++ b/plat/common/plat_spmd_manifest.c @@ -21,41 +21,43 @@ static int manifest_parse_attribute(spmc_manifest_sect_attribute_t *attr, const void *fdt, int node) { + uint32_t val32; int rc = 0; assert(attr && fdt); - rc = fdtw_read_cells(fdt, node, "maj_ver", 1, &attr->major_version); + rc = fdt_read_uint32(fdt, node, "maj_ver", &attr->major_version); if (rc) { ERROR("Missing SPCI major version in SPM core manifest.\n"); return -ENOENT; } - rc = fdtw_read_cells(fdt, node, "min_ver", 1, &attr->minor_version); + rc = fdt_read_uint32(fdt, node, "min_ver", &attr->minor_version); if (rc) { ERROR("Missing SPCI minor version in SPM core manifest.\n"); return -ENOENT; } - rc = fdtw_read_cells(fdt, node, "spmc_id", 1, &attr->spmc_id); + rc = fdt_read_uint32(fdt, node, "spmc_id", &val32); if (rc) { ERROR("Missing SPMC ID in manifest.\n"); return -ENOENT; } + attr->spmc_id = val32; - rc = fdtw_read_cells(fdt, node, "exec_state", 1, &attr->exec_state); + rc = fdt_read_uint32(fdt, node, "exec_state", &attr->exec_state); if (rc) NOTICE("Execution state not specified in SPM core manifest.\n"); - rc = fdtw_read_cells(fdt, node, "binary_size", 1, &attr->binary_size); + rc = fdt_read_uint32(fdt, node, "binary_size", &attr->binary_size); if (rc) NOTICE("Binary size not specified in SPM core manifest.\n"); - rc = fdtw_read_cells(fdt, node, "load_address", 2, &attr->load_address); + rc = fdt_read_uint64(fdt, node, "load_address", &attr->load_address); if (rc) NOTICE("Load address not specified in SPM core manifest.\n"); - rc = fdtw_read_cells(fdt, node, "entrypoint", 2, &attr->entrypoint); + rc = fdt_read_uint64(fdt, node, "entrypoint", &attr->entrypoint); if (rc) NOTICE("Entrypoint not specified in SPM core manifest.\n"); -- cgit v1.2.3 From be858cffa91fbcd5b8657200fbec1667c65bb1b7 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 26 Mar 2020 11:50:33 +0000 Subject: plat/stm32: Implement fdt_read_uint32_default() as a wrapper The STM32 platform code uses its own set of FDT helper functions, although some of them are fairly generic. Remove the implementation of fdt_read_uint32_default() and implement it on top of the newly introduced fdt_read_uint32() function, then convert all users over. This also fixes two callers, which were slightly abusing the "default" semantic. Change-Id: I570533362b4846e58dd797a92347de3e0e5abb75 Signed-off-by: Andre Przywara --- common/fdt_wrappers.c | 13 +++++++++++++ drivers/st/clk/stm32mp1_clk.c | 9 ++++++--- drivers/st/clk/stm32mp_clkfunc.c | 3 ++- drivers/st/ddr/stm32mp1_ram.c | 8 ++++---- include/common/fdt_wrappers.h | 2 ++ plat/st/common/include/stm32mp_dt.h | 2 -- plat/st/common/stm32mp_dt.c | 22 +--------------------- 7 files changed, 28 insertions(+), 31 deletions(-) diff --git a/common/fdt_wrappers.c b/common/fdt_wrappers.c index 394f3b0ca..57e3bcd40 100644 --- a/common/fdt_wrappers.c +++ b/common/fdt_wrappers.c @@ -56,6 +56,19 @@ int fdt_read_uint32(const void *dtb, int node, const char *prop_name, return fdt_read_uint32_array(dtb, node, prop_name, 1, value); } +uint32_t fdt_read_uint32_default(const void *dtb, int node, + const char *prop_name, uint32_t dflt_value) +{ + uint32_t ret = dflt_value; + int err = fdt_read_uint32(dtb, node, prop_name, &ret); + + if (err < 0) { + return dflt_value; + } + + return ret; +} + int fdt_read_uint64(const void *dtb, int node, const char *prop_name, uint64_t *value) { diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c index a16f36dcc..540c66aa3 100644 --- a/drivers/st/clk/stm32mp1_clk.c +++ b/drivers/st/clk/stm32mp1_clk.c @@ -1240,7 +1240,8 @@ static bool stm32mp1_check_pll_conf(enum stm32mp1_pll_id pll_id, uintptr_t clksrc_address = rcc_base + (clksrc >> 4); unsigned long refclk; uint32_t ifrge = 0U; - uint32_t src, value, fracv; + uint32_t src, value, fracv = 0; + void *fdt; /* Check PLL output */ if (mmio_read_32(pllxcr) != RCC_PLLNCR_PLLON) { @@ -1279,7 +1280,9 @@ static bool stm32mp1_check_pll_conf(enum stm32mp1_pll_id pll_id, } /* Fractional configuration */ - fracv = fdt_read_uint32_default(plloff, "frac", 0); + if (fdt_get_address(&fdt) == 1) { + fracv = fdt_read_uint32_default(fdt, plloff, "frac", 0); + } value = fracv << RCC_PLLNFRACR_FRACV_SHIFT; value |= RCC_PLLNFRACR_FRACLE; @@ -1800,7 +1803,7 @@ int stm32mp1_clk_init(void) continue; } - fracv = fdt_read_uint32_default(plloff[i], "frac", 0); + fracv = fdt_read_uint32_default(fdt, plloff[i], "frac", 0); ret = stm32mp1_pll_config(i, pllcfg[i], fracv); if (ret != 0) { diff --git a/drivers/st/clk/stm32mp_clkfunc.c b/drivers/st/clk/stm32mp_clkfunc.c index 6404d9933..e87ab1ba7 100644 --- a/drivers/st/clk/stm32mp_clkfunc.c +++ b/drivers/st/clk/stm32mp_clkfunc.c @@ -151,7 +151,8 @@ uint32_t fdt_osc_read_uint32_default(enum stm32mp_osc_id osc_id, continue; } - return fdt_read_uint32_default(subnode, prop_name, dflt_value); + return fdt_read_uint32_default(fdt, subnode, prop_name, + dflt_value); } return dflt_value; diff --git a/drivers/st/ddr/stm32mp1_ram.c b/drivers/st/ddr/stm32mp1_ram.c index 273dec0df..b21c8949f 100644 --- a/drivers/st/ddr/stm32mp1_ram.c +++ b/drivers/st/ddr/stm32mp1_ram.c @@ -206,13 +206,13 @@ static int stm32mp1_ddr_setup(void) return -EINVAL; } - config.info.speed = fdt_read_uint32_default(node, "st,mem-speed", 0); - if (!config.info.speed) { + ret = fdt_read_uint32(fdt, node, "st,mem-speed", &config.info.speed); + if (ret < 0) { VERBOSE("%s: no st,mem-speed\n", __func__); return -EINVAL; } - config.info.size = fdt_read_uint32_default(node, "st,mem-size", 0); - if (!config.info.size) { + ret = fdt_read_uint32(fdt, node, "st,mem-size", &config.info.size); + if (ret < 0) { VERBOSE("%s: no st,mem-size\n", __func__); return -EINVAL; } diff --git a/include/common/fdt_wrappers.h b/include/common/fdt_wrappers.h index e28dee142..852fe1bf8 100644 --- a/include/common/fdt_wrappers.h +++ b/include/common/fdt_wrappers.h @@ -14,6 +14,8 @@ int fdt_read_uint32(const void *dtb, int node, const char *prop_name, uint32_t *value); +uint32_t fdt_read_uint32_default(const void *dtb, int node, + const char *prop_name, uint32_t dflt_value); int fdt_read_uint64(const void *dtb, int node, const char *prop_name, uint64_t *value); int fdt_read_uint32_array(const void *dtb, int node, const char *prop_name, diff --git a/plat/st/common/include/stm32mp_dt.h b/plat/st/common/include/stm32mp_dt.h index 92f3d6528..91a8d67c8 100644 --- a/plat/st/common/include/stm32mp_dt.h +++ b/plat/st/common/include/stm32mp_dt.h @@ -28,8 +28,6 @@ int dt_open_and_check(void); int fdt_get_address(void **fdt_addr); bool fdt_check_node(int node); uint8_t fdt_get_status(int node); -uint32_t fdt_read_uint32_default(int node, const char *prop_name, - uint32_t dflt_value); int fdt_get_reg_props_by_name(int node, const char *name, uintptr_t *base, size_t *size); int dt_set_stdout_pinctrl(void); diff --git a/plat/st/common/stm32mp_dt.c b/plat/st/common/stm32mp_dt.c index 6b76424ae..c76b03358 100644 --- a/plat/st/common/stm32mp_dt.c +++ b/plat/st/common/stm32mp_dt.c @@ -135,26 +135,6 @@ static int fdt_get_node_parent_size_cells(int node) } #endif -/******************************************************************************* - * This function reads a value of a node property (generic use of fdt - * library). - * Returns value if success, and a default value if property not found. - * Default value is passed as parameter. - ******************************************************************************/ -uint32_t fdt_read_uint32_default(int node, const char *prop_name, - uint32_t dflt_value) -{ - const fdt32_t *cuint; - int lenp; - - cuint = fdt_getprop(fdt, node, prop_name, &lenp); - if (cuint == NULL) { - return dflt_value; - } - - return fdt32_to_cpu(*cuint); -} - /******************************************************************************* * This function fills reg node info (base & size) with an index found by * checking the reg-names node. @@ -343,7 +323,7 @@ uint32_t dt_get_ddr_size(void) return 0; } - return fdt_read_uint32_default(node, "st,mem-size", 0); + return fdt_read_uint32_default(fdt, node, "st,mem-size", 0); } /******************************************************************************* -- cgit v1.2.3 From 4874793d2ba048b15322aed651bcede35d9dfe33 Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Mon, 20 Apr 2020 14:14:10 +0100 Subject: doc: Add binding document for fconf. Complete the documentation with information on how to write a DTS for fconf. This patch adds the bindings information for dynamic configuration properties. Signed-off-by: Louis Mayencourt Change-Id: Ic6d9f927df53bb87315c23ec5a8943d0c3258d45 --- docs/components/fconf.rst | 131 -------------------------- docs/components/fconf/fconf_properties.rst | 32 +++++++ docs/components/fconf/index.rst | 144 +++++++++++++++++++++++++++++ docs/components/index.rst | 2 +- 4 files changed, 177 insertions(+), 132 deletions(-) delete mode 100644 docs/components/fconf.rst create mode 100644 docs/components/fconf/fconf_properties.rst create mode 100644 docs/components/fconf/index.rst diff --git a/docs/components/fconf.rst b/docs/components/fconf.rst deleted file mode 100644 index 7352ac37a..000000000 --- a/docs/components/fconf.rst +++ /dev/null @@ -1,131 +0,0 @@ -Firmware Configuration Framework -================================ - -This document provides an overview of the |FCONF| framework. - -Introduction -~~~~~~~~~~~~ - -The Firmware CONfiguration Framework (|FCONF|) is an abstraction layer for -platform specific data, allowing a "property" to be queried and a value -retrieved without the requesting entity knowing what backing store is being used -to hold the data. - -It is used to bridge new and old ways of providing platform-specific data. -Today, information like the Chain of Trust is held within several, nested -platform-defined tables. In the future, it may be provided as part of a device -blob, along with the rest of the information about images to load. -Introducing this abstraction layer will make migration easier and will preserve -functionality for platforms that cannot / don't want to use device tree. - -Accessing properties -~~~~~~~~~~~~~~~~~~~~ - -Properties defined in the |FCONF| are grouped around namespaces and -sub-namespaces: a.b.property. -Examples namespace can be: - -- (|TBBR|) Chain of Trust data: tbbr.cot.trusted_boot_fw_cert -- (|TBBR|) dynamic configuration info: tbbr.dyn_config.disable_auth -- Arm io policies: arm.io_policies.bl2_image -- GICv3 properties: hw_config.gicv3_config.gicr_base - -Properties can be accessed with the ``FCONF_GET_PROPERTY(a,b,property)`` macro. - -Defining properties -~~~~~~~~~~~~~~~~~~~ - -Properties composing the |FCONF| have to be stored in C structures. If -properties originate from a different backend source such as a device tree, -then the platform has to provide a ``populate()`` function which essentially -captures the property and stores them into a corresponding |FCONF| based C -structure. - -Such a ``populate()`` function is usually platform specific and is associated -with a specific backend source. For example, a populator function which -captures the hardware topology of the platform from the HW_CONFIG device tree. -Hence each ``populate()`` function must be registered with a specific -``config_type`` identifier. It broadly represents a logical grouping of -configuration properties which is usually a device tree file. - -Example: - - TB_FW: properties related to trusted firmware such as IO policies, - base address of other DTBs, mbedtls heap info etc. - - HW_CONFIG: properties related to hardware configuration of the SoC - such as topology, GIC controller, PSCI hooks, CPU ID etc. - -Hence the ``populate()`` callback must be registered to the (|FCONF|) framework -with the ``FCONF_REGISTER_POPULATOR()`` macro. This ensures that the function -would be called inside the generic ``fconf_populate()`` function during -initialization. - -:: - - int fconf_populate_topology(uintptr_t config) - { - /* read hw config dtb and fill soc_topology struct */ - } - - FCONF_REGISTER_POPULATOR(HW_CONFIG, topology, fconf_populate_topology); - -Then, a wrapper has to be provided to match the ``FCONF_GET_PROPERTY()`` macro: - -:: - - /* generic getter */ - #define FCONF_GET_PROPERTY(a,b,property) a##__##b##_getter(property) - - /* my specific getter */ - #define hw_config__topology_getter(prop) soc_topology.prop - -This second level wrapper can be used to remap the ``FCONF_GET_PROPERTY()`` to -anything appropriate: structure, array, function, etc.. - -Loading the property device tree -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The ``fconf_load_config()`` must be called to load the device tree containing -the properties' values. This must be done after the io layer is initialized, as -the |DTB| is stored on an external device (FIP). - -.. uml:: ../resources/diagrams/plantuml/fconf_bl1_load_config.puml - -Populating the properties -~~~~~~~~~~~~~~~~~~~~~~~~~ - -Once a valid device tree is available, the ``fconf_populate(config)`` function -can be used to fill the C data structure with the data from the config |DTB|. -This function will call all the ``populate()`` callbacks which have been -registered with ``FCONF_REGISTER_POPULATOR()`` as described above. - -.. uml:: ../resources/diagrams/plantuml/fconf_bl2_populate.puml - -Namespace guidance -~~~~~~~~~~~~~~~~~~ - -As mentioned above, properties are logically grouped around namespaces and -sub-namespaces. The following concepts should be considered when adding new -properties/namespaces. -The framework differentiates two types of properties: - - - Properties used inside common code. - - Properties used inside platform specific code. - -The first category applies to properties being part of the firmware and shared -across multiple platforms. They should be globally accessible and defined -inside the ``lib/fconf`` directory. The namespace must be chosen to reflect the -feature/data abstracted. - -Example: - - |TBBR| related properties: tbbr.cot.bl2_id - - Dynamic configuration information: dyn_cfg.dtb_info.hw_config_id - -The second category should represent the majority of the properties defined -within the framework: Platform specific properties. They must be accessed only -within the platform API and are defined only inside the platform scope. The -namespace must contain the platform name under which the properties defined -belong. - -Example: - - Arm io framework: arm.io_policies.bl31_id - diff --git a/docs/components/fconf/fconf_properties.rst b/docs/components/fconf/fconf_properties.rst new file mode 100644 index 000000000..5c28a7ae5 --- /dev/null +++ b/docs/components/fconf/fconf_properties.rst @@ -0,0 +1,32 @@ +DTB binding for FCONF properties +================================ + +This document describes the device tree format of |FCONF| properties. These +properties are not related to a specific platform and can be queried from +common code. + +Dynamic configuration +~~~~~~~~~~~~~~~~~~~~~ + +The |FCONF| framework expects a *dtb-registry* node with the following field: + +- compatible [mandatory] + - value type: + - Must be the string "fconf,dyn_cfg-dtb_registry". + +Then a list of subnodes representing a configuration |DTB|, which can be used +by |FCONF|. Each subnode should be named according to the information it +contains, and must be formed with the following fields: + +- load-address [mandatory] + - value type: + - Physical loading base address of the configuration. + +- max-size [mandatory] + - value type: + - Maximum size of the configuration. + +- id [mandatory] + - value type: + - Image ID of the configuration. + diff --git a/docs/components/fconf/index.rst b/docs/components/fconf/index.rst new file mode 100644 index 000000000..0da56ec3b --- /dev/null +++ b/docs/components/fconf/index.rst @@ -0,0 +1,144 @@ +Firmware Configuration Framework +================================ + +This document provides an overview of the |FCONF| framework. + +Introduction +~~~~~~~~~~~~ + +The Firmware CONfiguration Framework (|FCONF|) is an abstraction layer for +platform specific data, allowing a "property" to be queried and a value +retrieved without the requesting entity knowing what backing store is being used +to hold the data. + +It is used to bridge new and old ways of providing platform-specific data. +Today, information like the Chain of Trust is held within several, nested +platform-defined tables. In the future, it may be provided as part of a device +blob, along with the rest of the information about images to load. +Introducing this abstraction layer will make migration easier and will preserve +functionality for platforms that cannot / don't want to use device tree. + +Accessing properties +~~~~~~~~~~~~~~~~~~~~ + +Properties defined in the |FCONF| are grouped around namespaces and +sub-namespaces: a.b.property. +Examples namespace can be: + +- (|TBBR|) Chain of Trust data: tbbr.cot.trusted_boot_fw_cert +- (|TBBR|) dynamic configuration info: tbbr.dyn_config.disable_auth +- Arm io policies: arm.io_policies.bl2_image +- GICv3 properties: hw_config.gicv3_config.gicr_base + +Properties can be accessed with the ``FCONF_GET_PROPERTY(a,b,property)`` macro. + +Defining properties +~~~~~~~~~~~~~~~~~~~ + +Properties composing the |FCONF| have to be stored in C structures. If +properties originate from a different backend source such as a device tree, +then the platform has to provide a ``populate()`` function which essentially +captures the property and stores them into a corresponding |FCONF| based C +structure. + +Such a ``populate()`` function is usually platform specific and is associated +with a specific backend source. For example, a populator function which +captures the hardware topology of the platform from the HW_CONFIG device tree. +Hence each ``populate()`` function must be registered with a specific +``config_type`` identifier. It broadly represents a logical grouping of +configuration properties which is usually a device tree file. + +Example: + - TB_FW: properties related to trusted firmware such as IO policies, + base address of other DTBs, mbedtls heap info etc. + - HW_CONFIG: properties related to hardware configuration of the SoC + such as topology, GIC controller, PSCI hooks, CPU ID etc. + +Hence the ``populate()`` callback must be registered to the (|FCONF|) framework +with the ``FCONF_REGISTER_POPULATOR()`` macro. This ensures that the function +would be called inside the generic ``fconf_populate()`` function during +initialization. + +:: + + int fconf_populate_topology(uintptr_t config) + { + /* read hw config dtb and fill soc_topology struct */ + } + + FCONF_REGISTER_POPULATOR(HW_CONFIG, topology, fconf_populate_topology); + +Then, a wrapper has to be provided to match the ``FCONF_GET_PROPERTY()`` macro: + +:: + + /* generic getter */ + #define FCONF_GET_PROPERTY(a,b,property) a##__##b##_getter(property) + + /* my specific getter */ + #define hw_config__topology_getter(prop) soc_topology.prop + +This second level wrapper can be used to remap the ``FCONF_GET_PROPERTY()`` to +anything appropriate: structure, array, function, etc.. + +To ensure a good interpretation of the properties, this documentation must +explain how the properties are described for a specific backend. Refer to the +:ref:`binding-document` section for more information and example. + +Loading the property device tree +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``fconf_load_config()`` must be called to load the device tree containing +the properties' values. This must be done after the io layer is initialized, as +the |DTB| is stored on an external device (FIP). + +.. uml:: ../../resources/diagrams/plantuml/fconf_bl1_load_config.puml + +Populating the properties +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Once a valid device tree is available, the ``fconf_populate(config)`` function +can be used to fill the C data structure with the data from the config |DTB|. +This function will call all the ``populate()`` callbacks which have been +registered with ``FCONF_REGISTER_POPULATOR()`` as described above. + +.. uml:: ../../resources/diagrams/plantuml/fconf_bl2_populate.puml + +Namespace guidance +~~~~~~~~~~~~~~~~~~ + +As mentioned above, properties are logically grouped around namespaces and +sub-namespaces. The following concepts should be considered when adding new +properties/namespaces. +The framework differentiates two types of properties: + + - Properties used inside common code. + - Properties used inside platform specific code. + +The first category applies to properties being part of the firmware and shared +across multiple platforms. They should be globally accessible and defined +inside the ``lib/fconf`` directory. The namespace must be chosen to reflect the +feature/data abstracted. + +Example: + - |TBBR| related properties: tbbr.cot.bl2_id + - Dynamic configuration information: dyn_cfg.dtb_info.hw_config_id + +The second category should represent the majority of the properties defined +within the framework: Platform specific properties. They must be accessed only +within the platform API and are defined only inside the platform scope. The +namespace must contain the platform name under which the properties defined +belong. + +Example: + - Arm io framework: arm.io_policies.bl31_id + +.. _binding-document: + +Properties binding information +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. toctree:: + :maxdepth: 1 + + fconf_properties diff --git a/docs/components/index.rst b/docs/components/index.rst index 49986ca00..e3ce61489 100644 --- a/docs/components/index.rst +++ b/docs/components/index.rst @@ -10,7 +10,7 @@ Components arm-sip-service debugfs-design exception-handling - fconf + fconf/index firmware-update platform-interrupt-controller-API ras -- cgit v1.2.3 From 592c396dcf4614b5e109fa182c71f70302d85935 Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Mon, 20 Apr 2020 14:17:21 +0100 Subject: fconf: Update dyn_config compatible string Dynamic configuration properties are fconf properties. Modify the compatible string from "arm,.." to "fconf,.." to reflect this. Signed-off-by: Louis Mayencourt Change-Id: I85eb75cf877c5f4d3feea3936d4c348ca843bc6c --- lib/fconf/fconf_dyn_cfg_getter.c | 4 ++-- plat/arm/board/a5ds/fdts/a5ds_fw_config.dts | 2 +- plat/arm/board/fvp/fdts/fvp_fw_config.dts | 2 +- plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts | 2 +- plat/arm/board/juno/fdts/juno_fw_config.dts | 2 +- plat/arm/board/rddaniel/fdts/rddaniel_fw_config.dts | 2 +- plat/arm/board/rddanielxlr/fdts/rddanielxlr_fw_config.dts | 2 +- plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts | 2 +- plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts | 2 +- plat/arm/board/sgi575/fdts/sgi575_fw_config.dts | 2 +- plat/arm/board/sgm775/fdts/sgm775_fw_config.dts | 2 +- 11 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/fconf/fconf_dyn_cfg_getter.c b/lib/fconf/fconf_dyn_cfg_getter.c index 317d3e5d3..56e0c4ae7 100644 --- a/lib/fconf/fconf_dyn_cfg_getter.c +++ b/lib/fconf/fconf_dyn_cfg_getter.c @@ -48,8 +48,8 @@ int fconf_populate_dtb_registry(uintptr_t config) /* As libfdt use void *, we can't avoid this cast */ const void *dtb = (void *)config; - /* Find the node offset point to "arm,dyn_cfg-dtb_registry" compatible property */ - const char *compatible_str = "arm,dyn_cfg-dtb_registry"; + /* Find the node offset point to "fconf,dyn_cfg-dtb_registry" compatible property */ + const char *compatible_str = "fconf,dyn_cfg-dtb_registry"; 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); diff --git a/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts b/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts index 2f2d265c5..ff079ab6f 100644 --- a/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts +++ b/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts @@ -10,7 +10,7 @@ / { dtb-registry { - compatible = "arm,dyn_cfg-dtb_registry"; + compatible = "fconf,dyn_cfg-dtb_registry"; /* tb_fw_config is temporarily contained in this dtb */ tb_fw-config { diff --git a/plat/arm/board/fvp/fdts/fvp_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_fw_config.dts index 98ea85760..7c111085d 100644 --- a/plat/arm/board/fvp/fdts/fvp_fw_config.dts +++ b/plat/arm/board/fvp/fdts/fvp_fw_config.dts @@ -10,7 +10,7 @@ / { dtb-registry { - compatible = "arm,dyn_cfg-dtb_registry"; + compatible = "fconf,dyn_cfg-dtb_registry"; /* tb_fw_config is temporarily contained on this dtb */ tb_fw-config { diff --git a/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts b/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts index 147c8f366..1727e2e24 100644 --- a/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts +++ b/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts @@ -10,7 +10,7 @@ / { dtb-registry { - compatible = "arm,dyn_cfg-dtb_registry"; + compatible = "fconf,dyn_cfg-dtb_registry"; /* tb_fw_config is temporarily contained on this dtb */ tb_fw-config { diff --git a/plat/arm/board/juno/fdts/juno_fw_config.dts b/plat/arm/board/juno/fdts/juno_fw_config.dts index cab6f2bf4..4e460aa78 100644 --- a/plat/arm/board/juno/fdts/juno_fw_config.dts +++ b/plat/arm/board/juno/fdts/juno_fw_config.dts @@ -10,7 +10,7 @@ / { dtb-registry { - compatible = "arm,dyn_cfg-dtb_registry"; + compatible = "fconf,dyn_cfg-dtb_registry"; /* tb_fw_config is temporarily contained on this dtb */ tb_fw-config { diff --git a/plat/arm/board/rddaniel/fdts/rddaniel_fw_config.dts b/plat/arm/board/rddaniel/fdts/rddaniel_fw_config.dts index 81e4cc12d..bb544a410 100644 --- a/plat/arm/board/rddaniel/fdts/rddaniel_fw_config.dts +++ b/plat/arm/board/rddaniel/fdts/rddaniel_fw_config.dts @@ -10,7 +10,7 @@ / { dtb-registry { - compatible = "arm,dyn_cfg-dtb_registry"; + compatible = "fconf,dyn_cfg-dtb_registry"; /* tb_fw_config is temporarily contained on this dtb */ tb_fw-config { diff --git a/plat/arm/board/rddanielxlr/fdts/rddanielxlr_fw_config.dts b/plat/arm/board/rddanielxlr/fdts/rddanielxlr_fw_config.dts index 81e4cc12d..bb544a410 100644 --- a/plat/arm/board/rddanielxlr/fdts/rddanielxlr_fw_config.dts +++ b/plat/arm/board/rddanielxlr/fdts/rddanielxlr_fw_config.dts @@ -10,7 +10,7 @@ / { dtb-registry { - compatible = "arm,dyn_cfg-dtb_registry"; + compatible = "fconf,dyn_cfg-dtb_registry"; /* tb_fw_config is temporarily contained on this dtb */ tb_fw-config { diff --git a/plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts b/plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts index 2719ab415..a5b4a583d 100644 --- a/plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts +++ b/plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts @@ -10,7 +10,7 @@ / { dtb-registry { - compatible = "arm,dyn_cfg-dtb_registry"; + compatible = "fconf,dyn_cfg-dtb_registry"; /* tb_fw_config is temporarily contained on this dtb */ tb_fw-config { diff --git a/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts b/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts index ba74b75bc..1f460f185 100644 --- a/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts +++ b/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts @@ -9,7 +9,7 @@ /dts-v1/; / { dtb-registry { - compatible = "arm,dyn_cfg-dtb_registry"; + compatible = "fconf,dyn_cfg-dtb_registry"; /* tb_fw_config is temporarily contained on this dtb */ tb_fw-config { diff --git a/plat/arm/board/sgi575/fdts/sgi575_fw_config.dts b/plat/arm/board/sgi575/fdts/sgi575_fw_config.dts index 605cc08b7..da933e546 100644 --- a/plat/arm/board/sgi575/fdts/sgi575_fw_config.dts +++ b/plat/arm/board/sgi575/fdts/sgi575_fw_config.dts @@ -10,7 +10,7 @@ / { dtb-registry { - compatible = "arm,dyn_cfg-dtb_registry"; + compatible = "fconf,dyn_cfg-dtb_registry"; /* tb_fw_config is temporarily contained on this dtb */ tb_fw-config { diff --git a/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts b/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts index c5702ca3d..306bd89b9 100644 --- a/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts +++ b/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts @@ -10,7 +10,7 @@ / { dtb-registry { - compatible = "arm,dyn_cfg-dtb_registry"; + compatible = "fconf,dyn_cfg-dtb_registry"; /* tb_fw_config is temporarily contained on this dtb */ tb_fw-config { -- cgit v1.2.3 From 364ad245a24efce0732245f050a80b9b702fc7b2 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 26 Mar 2020 11:57:43 +0000 Subject: arm: fconf: Fix GICv3 dynamic configuration At the moment the fconf_populate_gicv3_config() implementation is somewhat incomplete: First it actually fails to store the retrieved information (the local addr[] array is going nowhere), but also it makes quite some assumptions about the device tree passed to it: it needs to use two address-cells and two size-cells, and also requires all five register regions to be specified, where actually only the first two are mandatory according to the binding (and needed by our code). Fix this by introducing a proper generic function to retrieve "reg" property information from a DT node: We retrieve the #address-cells and #size-cells properties from the parent node, then use those to extract the right values from the "reg" property. The function takes an index to select one region of a reg property. This is loosely based on the STM32 implementation using "reg-names", which we will subsume in a follow-up patch. Change-Id: Ia59bfdf80aea4e36876c7b6ed4d153e303f482e8 Signed-off-by: Andre Przywara --- common/fdt_wrappers.c | 50 ++++++++++++++++++++++ include/common/fdt_wrappers.h | 2 + plat/arm/board/fvp/fconf/fconf_hw_config_getter.c | 27 +++++++----- .../arm/board/fvp/include/fconf_hw_config_getter.h | 4 +- plat/arm/board/fvp/jmptbl.i | 3 ++ plat/arm/board/juno/jmptbl.i | 1 + 6 files changed, 74 insertions(+), 13 deletions(-) diff --git a/common/fdt_wrappers.c b/common/fdt_wrappers.c index 57e3bcd40..842d71339 100644 --- a/common/fdt_wrappers.c +++ b/common/fdt_wrappers.c @@ -226,3 +226,53 @@ int fdtw_write_inplace_bytes(void *dtb, int node, const char *prop, return err; } + +static uint64_t fdt_read_prop_cells(const fdt32_t *prop, int nr_cells) +{ + uint64_t reg = fdt32_to_cpu(prop[0]); + + if (nr_cells > 1) { + reg = (reg << 32) | fdt32_to_cpu(prop[1]); + } + + return reg; +} + +int fdt_get_reg_props_by_index(const void *dtb, int node, int index, + uintptr_t *base, size_t *size) +{ + const fdt32_t *prop; + int parent, len; + int ac, sc; + int cell; + + parent = fdt_parent_offset(dtb, node); + if (parent < 0) { + return -FDT_ERR_BADOFFSET; + } + + ac = fdt_address_cells(dtb, parent); + sc = fdt_size_cells(dtb, parent); + + cell = index * (ac + sc); + + prop = fdt_getprop(dtb, node, "reg", &len); + if (prop == NULL) { + WARN("Couldn't find \"reg\" property in dtb\n"); + return -FDT_ERR_NOTFOUND; + } + + if (((cell + ac + sc) * (int)sizeof(uint32_t)) > len) { + return -FDT_ERR_BADVALUE; + } + + if (base != NULL) { + *base = (uintptr_t)fdt_read_prop_cells(&prop[cell], ac); + } + + if (size != NULL) { + *size = (size_t)fdt_read_prop_cells(&prop[cell + ac], sc); + } + + return 0; +} diff --git a/include/common/fdt_wrappers.h b/include/common/fdt_wrappers.h index 852fe1bf8..7a6b59893 100644 --- a/include/common/fdt_wrappers.h +++ b/include/common/fdt_wrappers.h @@ -28,5 +28,7 @@ int fdtw_read_bytes(const void *dtb, int node, const char *prop, unsigned int length, void *value); int fdtw_write_inplace_bytes(void *dtb, int node, const char *prop, unsigned int length, const void *data); +int fdt_get_reg_props_by_index(const void *dtb, int node, int index, + uintptr_t *base, size_t *size); #endif /* FDT_WRAPPERS_H */ 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 44e9d0135..f1d9b93f7 100644 --- a/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c +++ b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c @@ -18,7 +18,7 @@ int fconf_populate_gicv3_config(uintptr_t config) { int err; int node; - uint32_t addr[20]; + uintptr_t addr; /* Necessary to work with libfdt APIs */ const void *hw_config_dtb = (const void *)config; @@ -33,19 +33,24 @@ int fconf_populate_gicv3_config(uintptr_t config) WARN("FCONF: Unable to locate node with arm,gic-v3 compatible property\n"); return 0; } - /* Read the reg cell holding base address of GIC controller modules - A sample reg cell array is shown here: - reg = <0x0 0x2f000000 0 0x10000>, // GICD - <0x0 0x2f100000 0 0x200000>, // GICR - <0x0 0x2c000000 0 0x2000>, // GICC - <0x0 0x2c010000 0 0x2000>, // GICH - <0x0 0x2c02f000 0 0x2000>; // GICV - */ + /* The GICv3 DT binding holds at least two address/size pairs, + * the first describing the distributor, the second the redistributors. + * See: bindings/interrupt-controller/arm,gic-v3.yaml + */ + err = fdt_get_reg_props_by_index(hw_config_dtb, node, 0, &addr, NULL); + if (err < 0) { + ERROR("FCONF: Failed to read GICD reg property of GIC node\n"); + return err; + } + gicv3_config.gicd_base = addr; - err = fdt_read_uint32_array(hw_config_dtb, node, "reg", 20, addr); + err = fdt_get_reg_props_by_index(hw_config_dtb, node, 1, &addr, NULL); if (err < 0) { - ERROR("FCONF: Failed to read reg property of GIC node\n"); + ERROR("FCONF: Failed to read GICR reg property of GIC node\n"); + } else { + gicv3_config.gicr_base = addr; } + return err; } diff --git a/plat/arm/board/fvp/include/fconf_hw_config_getter.h b/plat/arm/board/fvp/include/fconf_hw_config_getter.h index cab832f68..a9e569e78 100644 --- a/plat/arm/board/fvp/include/fconf_hw_config_getter.h +++ b/plat/arm/board/fvp/include/fconf_hw_config_getter.h @@ -15,8 +15,8 @@ #define hw_config__topology_getter(prop) soc_topology.prop struct gicv3_config_t { - void *gicd_base; - void *gicr_base; + uintptr_t gicd_base; + uintptr_t gicr_base; }; struct hw_topology_t { diff --git a/plat/arm/board/fvp/jmptbl.i b/plat/arm/board/fvp/jmptbl.i index 6469e2995..50a5ba4d9 100644 --- a/plat/arm/board/fvp/jmptbl.i +++ b/plat/arm/board/fvp/jmptbl.i @@ -25,6 +25,9 @@ fdt fdt_first_subnode fdt fdt_next_subnode fdt fdt_path_offset fdt fdt_subnode_offset +fdt fdt_address_cells +fdt fdt_size_cells +fdt fdt_parent_offset mbedtls mbedtls_asn1_get_alg mbedtls mbedtls_asn1_get_alg_null mbedtls mbedtls_asn1_get_bitstring_null diff --git a/plat/arm/board/juno/jmptbl.i b/plat/arm/board/juno/jmptbl.i index 66d6e4592..eb4399ec0 100644 --- a/plat/arm/board/juno/jmptbl.i +++ b/plat/arm/board/juno/jmptbl.i @@ -23,6 +23,7 @@ fdt fdt_node_offset_by_compatible fdt fdt_setprop_inplace_namelen_partial fdt fdt_first_subnode fdt fdt_next_subnode +fdt fdt_parent_offset mbedtls mbedtls_asn1_get_alg mbedtls mbedtls_asn1_get_alg_null mbedtls mbedtls_asn1_get_bitstring_null -- cgit v1.2.3 From a718c3d677f8b3a65db766406e8c7df25af02529 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Tue, 28 Apr 2020 13:25:56 +0100 Subject: Fix SMCCC_ARCH_SOC_ID implementation Commit 0e753437e75b ("Implement SMCCC_ARCH_SOC_ID SMC call") executes and return the result of SMCCC_ARCH_SOC_ID(soc_id_type) to the SMCCC_ARCH_FEATURES(SMCCC_ARCH_SOC_ID) itself. Moreover it expect to pass soc_id_type for SMCCC_ARCH_FEATURES(SMCCC_ARCH_SOC_ID) which is incorrect. Fix the implementation by returning SMC_OK for SMCCC_ARCH_FEATURES(SMCCC_ARCH_SOC_ID) always and move the current implementation under "smccc_arch_id" function which gets called from SMC handler on receiving "SMCCC_ARCH_SOC_ID" command. This change is tested over linux operating system Change-Id: I61a980045081eae786b907d408767ba9ecec3468 Signed-off-by: Sudeep Holla Signed-off-by: Manish V Badarkhe --- services/arm_arch_svc/arm_arch_svc_setup.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/services/arm_arch_svc/arm_arch_svc_setup.c b/services/arm_arch_svc/arm_arch_svc_setup.c index ba539309d..588656d57 100644 --- a/services/arm_arch_svc/arm_arch_svc_setup.c +++ b/services/arm_arch_svc/arm_arch_svc_setup.c @@ -19,20 +19,13 @@ static int32_t smccc_version(void) return MAKE_SMCCC_VERSION(SMCCC_MAJOR_VERSION, SMCCC_MINOR_VERSION); } -static int32_t smccc_arch_features(u_register_t arg1, u_register_t arg2) +static int32_t smccc_arch_features(u_register_t arg1) { switch (arg1) { case SMCCC_VERSION: case SMCCC_ARCH_FEATURES: - return SMC_OK; case SMCCC_ARCH_SOC_ID: - if (arg2 == SMCCC_GET_SOC_REVISION) { - return plat_get_soc_revision(); - } - if (arg2 == SMCCC_GET_SOC_VERSION) { - return plat_get_soc_version(); - } - return SMC_ARCH_CALL_INVAL_PARAM; + return SMC_OK; #if WORKAROUND_CVE_2017_5715 case SMCCC_ARCH_WORKAROUND_1: if (check_wa_cve_2017_5715() == ERRATA_NOT_APPLIES) @@ -87,6 +80,19 @@ static int32_t smccc_arch_features(u_register_t arg1, u_register_t arg2) } } +/* return soc revision or soc version on success otherwise + * return invalid parameter */ +static int32_t smccc_arch_id(u_register_t arg1) +{ + if (arg1 == SMCCC_GET_SOC_REVISION) { + return plat_get_soc_revision(); + } + if (arg1 == SMCCC_GET_SOC_VERSION) { + return plat_get_soc_version(); + } + return SMC_ARCH_CALL_INVAL_PARAM; +} + /* * Top-level Arm Architectural Service SMC handler. */ @@ -103,7 +109,9 @@ static uintptr_t arm_arch_svc_smc_handler(uint32_t smc_fid, case SMCCC_VERSION: SMC_RET1(handle, smccc_version()); case SMCCC_ARCH_FEATURES: - SMC_RET1(handle, smccc_arch_features(x1, x2)); + SMC_RET1(handle, smccc_arch_features(x1)); + case SMCCC_ARCH_SOC_ID: + SMC_RET1(handle, smccc_arch_id(x1)); #if WORKAROUND_CVE_2017_5715 case SMCCC_ARCH_WORKAROUND_1: /* -- cgit v1.2.3 From 93bb7a0ac35bb1490bac0b0b667f5845f9dbdd3c Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 9 Apr 2020 10:10:09 +0100 Subject: arm_fpga: Use Generic UART The SCP firmware on the ARM FPGA initialises the UART already. This allows us to treat the PL011 as an SBSA Generic UART, which does not require any further setup. This in particular removes the need for any baudrate and base clock related settings to be hard coded into the BL31 image. Change-Id: I16fc943526267356b97166a7068459e06ff77f0f Signed-off-by: Andre Przywara --- plat/arm/board/arm_fpga/aarch64/fpga_helpers.S | 2 -- plat/arm/board/arm_fpga/fpga_console.c | 4 +--- plat/arm/board/arm_fpga/fpga_def.h | 6 +----- plat/arm/board/arm_fpga/include/platform_def.h | 2 -- plat/arm/board/arm_fpga/platform.mk | 2 ++ 5 files changed, 4 insertions(+), 12 deletions(-) diff --git a/plat/arm/board/arm_fpga/aarch64/fpga_helpers.S b/plat/arm/board/arm_fpga/aarch64/fpga_helpers.S index f350455d5..aeed3108e 100644 --- a/plat/arm/board/arm_fpga/aarch64/fpga_helpers.S +++ b/plat/arm/board/arm_fpga/aarch64/fpga_helpers.S @@ -108,8 +108,6 @@ endfunc plat_fpga_calc_core_pos func plat_crash_console_init mov_imm x0, PLAT_FPGA_CRASH_UART_BASE - mov_imm x1, PLAT_FPGA_CRASH_UART_CLK_IN_HZ - mov_imm x2, PLAT_FPGA_CONSOLE_BAUDRATE b console_pl011_core_init endfunc plat_crash_console_init diff --git a/plat/arm/board/arm_fpga/fpga_console.c b/plat/arm/board/arm_fpga/fpga_console.c index b4ebf3424..a1fdb7832 100644 --- a/plat/arm/board/arm_fpga/fpga_console.c +++ b/plat/arm/board/arm_fpga/fpga_console.c @@ -13,9 +13,7 @@ static console_t console; void fpga_console_init(void) { - (void)console_pl011_register(PLAT_FPGA_BOOT_UART_BASE, - PLAT_FPGA_BOOT_UART_CLK_IN_HZ, - PLAT_FPGA_CONSOLE_BAUDRATE, + (void)console_pl011_register(PLAT_FPGA_BOOT_UART_BASE, 0, 0, &console); console_set_scope(&console, CONSOLE_FLAG_BOOT | diff --git a/plat/arm/board/arm_fpga/fpga_def.h b/plat/arm/board/arm_fpga/fpga_def.h index dbdbe6f4d..609263745 100644 --- a/plat/arm/board/arm_fpga/fpga_def.h +++ b/plat/arm/board/arm_fpga/fpga_def.h @@ -23,17 +23,13 @@ #define FPGA_MAX_PE_PER_CPU 4 #define FPGA_PRIMARY_CPU 0x0 - /******************************************************************************* * FPGA image memory map related constants ******************************************************************************/ -/* UART base address and clock frequency, as configured by the image */ +/* UART base address, as configured by the image */ #define PLAT_FPGA_BOOT_UART_BASE 0x7ff80000 -#define PLAT_FPGA_BOOT_UART_CLK_IN_HZ 10000000 - #define PLAT_FPGA_CRASH_UART_BASE PLAT_FPGA_BOOT_UART_BASE -#define PLAT_FPGA_CRASH_UART_CLK_IN_HZ PLAT_FPGA_BOOT_UART_CLK_IN_HZ #define FPGA_TIMER_FREQUENCY 10000000 diff --git a/plat/arm/board/arm_fpga/include/platform_def.h b/plat/arm/board/arm_fpga/include/platform_def.h index 5c8aff691..37f3d8ae5 100644 --- a/plat/arm/board/arm_fpga/include/platform_def.h +++ b/plat/arm/board/arm_fpga/include/platform_def.h @@ -87,6 +87,4 @@ #define PLAT_FPGA_HOLD_STATE_WAIT 0 #define PLAT_FPGA_HOLD_STATE_GO 1 -#define PLAT_FPGA_CONSOLE_BAUDRATE 38400 - #endif diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk index 302aabf38..335000037 100644 --- a/plat/arm/board/arm_fpga/platform.mk +++ b/plat/arm/board/arm_fpga/platform.mk @@ -38,6 +38,8 @@ USE_COHERENT_MEM := 0 # This can be overridden depending on CPU(s) used in the FPGA image HW_ASSISTED_COHERENCY := 1 +PL011_GENERIC_UART := 1 + FPGA_CPU_LIBS := lib/cpus/${ARCH}/aem_generic.S # select a different set of CPU files, depending on whether we compile for -- cgit v1.2.3 From 7ad6d362016a875eaee0d227365b74acd464050b Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 26 Mar 2020 12:11:34 +0000 Subject: plat/stm32: Use generic fdt_get_reg_props_by_name() The STM32 platform port parse DT nodes to find base address to peripherals. It does this by using its own implementation, even though this functionality is generic and actually widely useful outside of the STM32 code. Re-implement fdt_get_reg_props_by_name() on top of the newly introduced fdt_get_reg_props_by_index() function, and move it to fdt_wrapper.c. This is removes the assumption that #address-cells and #size-cells are always one. Change-Id: I6d584930262c732b6e0356d98aea50b2654f789d Signed-off-by: Andre Przywara --- common/fdt_wrappers.c | 18 +++++++++++++++++ drivers/st/spi/stm32_qspi.c | 5 +++-- include/common/fdt_wrappers.h | 2 ++ plat/arm/board/fvp/jmptbl.i | 1 + plat/arm/board/juno/jmptbl.i | 1 + plat/st/common/include/stm32mp_dt.h | 2 -- plat/st/common/stm32mp_dt.c | 40 ------------------------------------- 7 files changed, 25 insertions(+), 44 deletions(-) diff --git a/common/fdt_wrappers.c b/common/fdt_wrappers.c index 842d71339..2c4b9c353 100644 --- a/common/fdt_wrappers.c +++ b/common/fdt_wrappers.c @@ -276,3 +276,21 @@ int fdt_get_reg_props_by_index(const void *dtb, int node, int index, return 0; } + +/******************************************************************************* + * This function fills reg node info (base & size) with an index found by + * checking the reg-names node. + * Returns 0 on success and a negative FDT error code on failure. + ******************************************************************************/ +int fdt_get_reg_props_by_name(const void *dtb, int node, const char *name, + uintptr_t *base, size_t *size) +{ + int index; + + index = fdt_stringlist_search(dtb, node, "reg-names", name); + if (index < 0) { + return index; + } + + return fdt_get_reg_props_by_index(dtb, node, index, base, size); +} diff --git a/drivers/st/spi/stm32_qspi.c b/drivers/st/spi/stm32_qspi.c index c5e4ea86e..ff92796e7 100644 --- a/drivers/st/spi/stm32_qspi.c +++ b/drivers/st/spi/stm32_qspi.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -465,13 +466,13 @@ int stm32_qspi_init(void) return -FDT_ERR_NOTFOUND; } - ret = fdt_get_reg_props_by_name(qspi_node, "qspi", + ret = fdt_get_reg_props_by_name(fdt, qspi_node, "qspi", &stm32_qspi.reg_base, &size); if (ret != 0) { return ret; } - ret = fdt_get_reg_props_by_name(qspi_node, "qspi_mm", + ret = fdt_get_reg_props_by_name(fdt, qspi_node, "qspi_mm", &stm32_qspi.mm_base, &stm32_qspi.mm_size); if (ret != 0) { diff --git a/include/common/fdt_wrappers.h b/include/common/fdt_wrappers.h index 7a6b59893..06625e476 100644 --- a/include/common/fdt_wrappers.h +++ b/include/common/fdt_wrappers.h @@ -30,5 +30,7 @@ int fdtw_write_inplace_bytes(void *dtb, int node, const char *prop, unsigned int length, const void *data); int fdt_get_reg_props_by_index(const void *dtb, int node, int index, uintptr_t *base, size_t *size); +int fdt_get_reg_props_by_name(const void *dtb, int node, const char *name, + uintptr_t *base, size_t *size); #endif /* FDT_WRAPPERS_H */ diff --git a/plat/arm/board/fvp/jmptbl.i b/plat/arm/board/fvp/jmptbl.i index 50a5ba4d9..c656c7938 100644 --- a/plat/arm/board/fvp/jmptbl.i +++ b/plat/arm/board/fvp/jmptbl.i @@ -28,6 +28,7 @@ fdt fdt_subnode_offset fdt fdt_address_cells fdt fdt_size_cells fdt fdt_parent_offset +fdt fdt_stringlist_search mbedtls mbedtls_asn1_get_alg mbedtls mbedtls_asn1_get_alg_null mbedtls mbedtls_asn1_get_bitstring_null diff --git a/plat/arm/board/juno/jmptbl.i b/plat/arm/board/juno/jmptbl.i index eb4399ec0..213afd008 100644 --- a/plat/arm/board/juno/jmptbl.i +++ b/plat/arm/board/juno/jmptbl.i @@ -24,6 +24,7 @@ fdt fdt_setprop_inplace_namelen_partial fdt fdt_first_subnode fdt fdt_next_subnode fdt fdt_parent_offset +fdt fdt_stringlist_search mbedtls mbedtls_asn1_get_alg mbedtls mbedtls_asn1_get_alg_null mbedtls mbedtls_asn1_get_bitstring_null diff --git a/plat/st/common/include/stm32mp_dt.h b/plat/st/common/include/stm32mp_dt.h index 91a8d67c8..e79551a31 100644 --- a/plat/st/common/include/stm32mp_dt.h +++ b/plat/st/common/include/stm32mp_dt.h @@ -28,8 +28,6 @@ int dt_open_and_check(void); int fdt_get_address(void **fdt_addr); bool fdt_check_node(int node); uint8_t fdt_get_status(int node); -int fdt_get_reg_props_by_name(int node, const char *name, uintptr_t *base, - size_t *size); 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); diff --git a/plat/st/common/stm32mp_dt.c b/plat/st/common/stm32mp_dt.c index c76b03358..356af0bbc 100644 --- a/plat/st/common/stm32mp_dt.c +++ b/plat/st/common/stm32mp_dt.c @@ -135,46 +135,6 @@ static int fdt_get_node_parent_size_cells(int node) } #endif -/******************************************************************************* - * This function fills reg node info (base & size) with an index found by - * checking the reg-names node. - * Returns 0 on success and a negative FDT error code on failure. - ******************************************************************************/ -int fdt_get_reg_props_by_name(int node, const char *name, uintptr_t *base, - size_t *size) -{ - const fdt32_t *cuint; - int index, len; - - assert((fdt_get_node_parent_address_cells(node) == 1) && - (fdt_get_node_parent_size_cells(node) == 1)); - - index = fdt_stringlist_search(fdt, node, "reg-names", name); - if (index < 0) { - return index; - } - - cuint = fdt_getprop(fdt, node, "reg", &len); - if (cuint == NULL) { - return -FDT_ERR_NOTFOUND; - } - - if ((index * (int)sizeof(uint32_t)) > len) { - return -FDT_ERR_BADVALUE; - } - - cuint += index << 1; - if (base != NULL) { - *base = fdt32_to_cpu(*cuint); - } - cuint++; - if (size != NULL) { - *size = fdt32_to_cpu(*cuint); - } - - return 0; -} - /******************************************************************************* * This function gets the stdout path node. * It reads the value indicated inside the device tree. -- cgit v1.2.3 From 670c66af0667e13857405ade5af7d3c4d248abe5 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Fri, 24 Jan 2020 15:02:27 +0000 Subject: arm_fpga: Read generic timer counter frequency from DT The ARM Generic Timer DT binding describes an (optional) property to declare the counter frequency. Its usage is normally discouraged, as the value should be read from the CNTFRQ_EL0 system register. However in our case we can use it to program this register in the first place, which avoids us to hard code a counter frequency into the code. We keep some default value in, if the DT lacks that property for whatever reason. Change-Id: I5b71176db413f904f21eb16f3302fbb799cb0305 Signed-off-by: Andre Przywara --- plat/arm/board/arm_fpga/fpga_bl31_setup.c | 16 ++++++++++++++-- plat/arm/board/arm_fpga/fpga_def.h | 2 +- plat/arm/board/arm_fpga/platform.mk | 5 ++++- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/plat/arm/board/arm_fpga/fpga_bl31_setup.c b/plat/arm/board/arm_fpga/fpga_bl31_setup.c index 632949723..e4b9767d4 100644 --- a/plat/arm/board/arm_fpga/fpga_bl31_setup.c +++ b/plat/arm/board/arm_fpga/fpga_bl31_setup.c @@ -5,8 +5,11 @@ */ #include -#include + +#include #include +#include +#include #include #include @@ -76,7 +79,16 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) unsigned int plat_get_syscnt_freq2(void) { - return FPGA_TIMER_FREQUENCY; + const void *fdt = (void *)(uintptr_t)FPGA_PRELOADED_DTB_BASE; + int node; + + node = fdt_node_offset_by_compatible(fdt, 0, "arm,armv8-timer"); + if (node < 0) { + return FPGA_DEFAULT_TIMER_FREQUENCY; + } + + return fdt_read_uint32_default(fdt, node, "clock-frequency", + FPGA_DEFAULT_TIMER_FREQUENCY); } void bl31_plat_enable_mmu(uint32_t flags) diff --git a/plat/arm/board/arm_fpga/fpga_def.h b/plat/arm/board/arm_fpga/fpga_def.h index 609263745..0bb2b22e0 100644 --- a/plat/arm/board/arm_fpga/fpga_def.h +++ b/plat/arm/board/arm_fpga/fpga_def.h @@ -31,6 +31,6 @@ #define PLAT_FPGA_BOOT_UART_BASE 0x7ff80000 #define PLAT_FPGA_CRASH_UART_BASE PLAT_FPGA_BOOT_UART_BASE -#define FPGA_TIMER_FREQUENCY 10000000 +#define FPGA_DEFAULT_TIMER_FREQUENCY 10000000 #endif diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk index 335000037..0d0d010a1 100644 --- a/plat/arm/board/arm_fpga/platform.mk +++ b/plat/arm/board/arm_fpga/platform.mk @@ -4,6 +4,8 @@ # SPDX-License-Identifier: BSD-3-Clause # +include lib/libfdt/libfdt.mk + RESET_TO_BL31 := 1 ifeq (${RESET_TO_BL31}, 0) $(error "This is a BL31-only port; RESET_TO_BL31 must be enabled") @@ -82,7 +84,8 @@ PLAT_INCLUDES := -Iplat/arm/board/arm_fpga/include PLAT_BL_COMMON_SOURCES := plat/arm/board/arm_fpga/${ARCH}/fpga_helpers.S -BL31_SOURCES += drivers/delay_timer/delay_timer.c \ +BL31_SOURCES += common/fdt_wrappers.c \ + drivers/delay_timer/delay_timer.c \ drivers/delay_timer/generic_delay_timer.c \ drivers/arm/pl011/${ARCH}/pl011_console.S \ plat/common/plat_psci_common.c \ -- cgit v1.2.3 From 60e2e27db51df2b819ad10521a0821544f2f8ce0 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 26 Mar 2020 12:52:06 +0000 Subject: fdt/wrappers: Introduce code to find UART DT node The stdout-path property in the /chosen node of a DTB points to a device node, which is used for boot console output. On most (if not all) ARM based platforms this is the debug UART. The ST platform code contains a function to parse this property and chase down eventual aliases to learn the node offset of this UART node. Introduce a slightly more generalised version of this ST platform function in the generic fdt_wrappers code. This will be useful for other platforms as well. Change-Id: Ie6da47ace7833861b5e35fe8cba49835db3659a5 Signed-off-by: Andre Przywara --- common/fdt_wrappers.c | 47 +++++++++++++++++++++++++++++++++++++++++++ include/common/fdt_wrappers.h | 1 + plat/arm/board/fvp/jmptbl.i | 2 ++ plat/arm/board/juno/jmptbl.i | 3 +++ 4 files changed, 53 insertions(+) diff --git a/common/fdt_wrappers.c b/common/fdt_wrappers.c index 2c4b9c353..1901a2040 100644 --- a/common/fdt_wrappers.c +++ b/common/fdt_wrappers.c @@ -294,3 +294,50 @@ int fdt_get_reg_props_by_name(const void *dtb, int node, const char *name, return fdt_get_reg_props_by_index(dtb, node, index, base, size); } + +/******************************************************************************* + * This function gets the stdout path node. + * It reads the value indicated inside the device tree. + * Returns node offset on success and a negative FDT error code on failure. + ******************************************************************************/ +int fdt_get_stdout_node_offset(const void *dtb) +{ + int node; + const char *prop, *path; + int len; + + /* The /secure-chosen node takes precedence over the standard one. */ + node = fdt_path_offset(dtb, "/secure-chosen"); + if (node < 0) { + node = fdt_path_offset(dtb, "/chosen"); + if (node < 0) { + return -FDT_ERR_NOTFOUND; + } + } + + prop = fdt_getprop(dtb, node, "stdout-path", NULL); + if (prop == NULL) { + return -FDT_ERR_NOTFOUND; + } + + /* Determine the actual path length, as a colon terminates the path. */ + path = strchr(prop, ':'); + if (path == NULL) { + len = strlen(prop); + } else { + len = path - prop; + } + + /* Aliases cannot start with a '/', so it must be the actual path. */ + if (prop[0] == '/') { + return fdt_path_offset_namelen(dtb, prop, len); + } + + /* Lookup the alias, as this contains the actual path. */ + path = fdt_get_alias_namelen(dtb, prop, len); + if (path == NULL) { + return -FDT_ERR_NOTFOUND; + } + + return fdt_path_offset(dtb, path); +} diff --git a/include/common/fdt_wrappers.h b/include/common/fdt_wrappers.h index 06625e476..382651e5d 100644 --- a/include/common/fdt_wrappers.h +++ b/include/common/fdt_wrappers.h @@ -32,5 +32,6 @@ int fdt_get_reg_props_by_index(const void *dtb, int node, int index, uintptr_t *base, size_t *size); int fdt_get_reg_props_by_name(const void *dtb, int node, const char *name, uintptr_t *base, size_t *size); +int fdt_get_stdout_node_offset(const void *dtb); #endif /* FDT_WRAPPERS_H */ diff --git a/plat/arm/board/fvp/jmptbl.i b/plat/arm/board/fvp/jmptbl.i index c656c7938..213a9749d 100644 --- a/plat/arm/board/fvp/jmptbl.i +++ b/plat/arm/board/fvp/jmptbl.i @@ -24,11 +24,13 @@ fdt fdt_setprop_inplace_namelen_partial fdt fdt_first_subnode fdt fdt_next_subnode fdt fdt_path_offset +fdt fdt_path_offset_namelen fdt fdt_subnode_offset fdt fdt_address_cells fdt fdt_size_cells fdt fdt_parent_offset fdt fdt_stringlist_search +fdt fdt_get_alias_namelen mbedtls mbedtls_asn1_get_alg mbedtls mbedtls_asn1_get_alg_null mbedtls mbedtls_asn1_get_bitstring_null diff --git a/plat/arm/board/juno/jmptbl.i b/plat/arm/board/juno/jmptbl.i index 213afd008..09017acdc 100644 --- a/plat/arm/board/juno/jmptbl.i +++ b/plat/arm/board/juno/jmptbl.i @@ -25,6 +25,9 @@ fdt fdt_first_subnode fdt fdt_next_subnode fdt fdt_parent_offset fdt fdt_stringlist_search +fdt fdt_get_alias_namelen +fdt fdt_path_offset +fdt fdt_path_offset_namelen mbedtls mbedtls_asn1_get_alg mbedtls mbedtls_asn1_get_alg_null mbedtls mbedtls_asn1_get_bitstring_null -- cgit v1.2.3 From 1a0f9366d82f7e9fac96a29bd38c78828044a147 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Fri, 24 Jan 2020 15:46:05 +0000 Subject: arm_fpga: Read GICD and GICR base addresses from DT Since we use a DTB with all platform information to pass this on to a kernel loaded as BL33, we can as well make use of it for our own purposes. Every DT would contain a node for the GIC(v3) interrupt controller, so we can read the base address for the distributor and redistributors from there. This avoids hard coding this information in the code and allows for a more flexible binary. Change-Id: Ic530e223a21a45bc30a07a21048116d5af69e972 Signed-off-by: Andre Przywara --- plat/arm/board/arm_fpga/fpga_gicv3.c | 32 +++++++++++++++++++++++--- plat/arm/board/arm_fpga/include/platform_def.h | 3 --- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/plat/arm/board/arm_fpga/fpga_gicv3.c b/plat/arm/board/arm_fpga/fpga_gicv3.c index be1684e4b..9fb5fa935 100644 --- a/plat/arm/board/arm_fpga/fpga_gicv3.c +++ b/plat/arm/board/arm_fpga/fpga_gicv3.c @@ -4,9 +4,13 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include +#include #include #include +#include +#include #include #include @@ -22,9 +26,7 @@ static unsigned int fpga_mpidr_to_core_pos(unsigned long mpidr) return (unsigned int)plat_core_pos_by_mpidr(mpidr); } -static const gicv3_driver_data_t fpga_gicv3_driver_data = { - .gicd_base = GICD_BASE, - .gicr_base = GICR_BASE, +static gicv3_driver_data_t fpga_gicv3_driver_data = { .interrupt_props = fpga_interrupt_props, .interrupt_props_num = ARRAY_SIZE(fpga_interrupt_props), .rdistif_num = PLATFORM_CORE_COUNT, @@ -34,6 +36,30 @@ static const gicv3_driver_data_t fpga_gicv3_driver_data = { void plat_fpga_gic_init(void) { + const void *fdt = (void *)(uintptr_t)FPGA_PRELOADED_DTB_BASE; + int node, ret; + + node = fdt_node_offset_by_compatible(fdt, 0, "arm,gic-v3"); + if (node < 0) { + WARN("No \"arm,gic-v3\" compatible node found in DT, no GIC support.\n"); + return; + } + + /* TODO: Assuming only empty "ranges;" properties up the bus path. */ + ret = fdt_get_reg_props_by_index(fdt, node, 0, + &fpga_gicv3_driver_data.gicd_base, NULL); + if (ret < 0) { + WARN("Could not read GIC distributor address from DT.\n"); + 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; + } + gicv3_driver_init(&fpga_gicv3_driver_data); gicv3_distif_init(); gicv3_rdistif_init(plat_my_core_pos()); diff --git a/plat/arm/board/arm_fpga/include/platform_def.h b/plat/arm/board/arm_fpga/include/platform_def.h index 37f3d8ae5..31fc9870c 100644 --- a/plat/arm/board/arm_fpga/include/platform_def.h +++ b/plat/arm/board/arm_fpga/include/platform_def.h @@ -35,9 +35,6 @@ #define BL31_LIMIT UL(0x01000000) #endif -#define GICD_BASE 0x30000000 -#define GICR_BASE 0x30040000 - #define PLAT_SDEI_NORMAL_PRI 0x70 #define ARM_IRQ_SEC_PHY_TIMER 29 -- cgit v1.2.3 From 7a61114da619f3d0fe0d068f879ad2f7f99ee3c4 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 9 Apr 2020 11:27:21 +0100 Subject: plat/stm32: Use generic fdt_get_stdout_node_offset() Now that we have an implementation for getting the node offset of the stdout-path property in the generic fdt_wrappers code, use that to replace the current ST platform specific implementation. Change-Id: I5dd05684e7ca3cb563b5f71c885e1066393e057e Signed-off-by: Andre Przywara --- plat/st/common/stm32mp_dt.c | 50 ++------------------------------------------- 1 file changed, 2 insertions(+), 48 deletions(-) diff --git a/plat/st/common/stm32mp_dt.c b/plat/st/common/stm32mp_dt.c index 356af0bbc..155f78404 100644 --- a/plat/st/common/stm32mp_dt.c +++ b/plat/st/common/stm32mp_dt.c @@ -135,52 +135,6 @@ static int fdt_get_node_parent_size_cells(int node) } #endif -/******************************************************************************* - * This function gets the stdout path node. - * It reads the value indicated inside the device tree. - * Returns node offset on success and a negative FDT error code on failure. - ******************************************************************************/ -static int dt_get_stdout_node_offset(void) -{ - int node; - const char *cchar; - - node = fdt_path_offset(fdt, "/secure-chosen"); - if (node < 0) { - node = fdt_path_offset(fdt, "/chosen"); - if (node < 0) { - return -FDT_ERR_NOTFOUND; - } - } - - cchar = fdt_getprop(fdt, node, "stdout-path", NULL); - if (cchar == NULL) { - return -FDT_ERR_NOTFOUND; - } - - node = -FDT_ERR_NOTFOUND; - if (strchr(cchar, (int)':') != NULL) { - const char *name; - char *str = (char *)cchar; - int len = 0; - - while (strncmp(":", str, 1)) { - len++; - str++; - } - - name = fdt_get_alias_namelen(fdt, cchar, len); - - if (name != NULL) { - node = fdt_path_offset(fdt, name); - } - } else { - node = fdt_path_offset(fdt, cchar); - } - - return node; -} - /******************************************************************************* * This function gets the stdout pin configuration information from the DT. * And then calls the sub-function to treat it and set GPIO registers. @@ -190,7 +144,7 @@ int dt_set_stdout_pinctrl(void) { int node; - node = dt_get_stdout_node_offset(); + node = fdt_get_stdout_node_offset(fdt); if (node < 0) { return -FDT_ERR_NOTFOUND; } @@ -259,7 +213,7 @@ int dt_get_stdout_uart_info(struct dt_node_info *info) { int node; - node = dt_get_stdout_node_offset(); + node = fdt_get_stdout_node_offset(fdt); if (node < 0) { return -FDT_ERR_NOTFOUND; } -- cgit v1.2.3 From dee3042cd6cfcd7b6995260a944d741bb93adce0 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 9 Apr 2020 10:25:43 +0100 Subject: arm_fpga: Read UART address from DT The arm_fpga port requires a DTB, to launch a BL33 payload. To make this port more flexible, we can also use the information in the DT to configure the console driver. For a start, find the DT node pointed to by the stdout-path property, and read the base address from there. This assumes for now that the stdout-path points to a PL011 UART. This allows to remove platform specific addresses from the image. We keep the original base address for the crash console. Change-Id: I46a990de2315f81cae4d7913ae99a07b0bec5cb1 Signed-off-by: Andre Przywara --- plat/arm/board/arm_fpga/fpga_console.c | 23 ++++++++++++++++++++--- plat/arm/board/arm_fpga/fpga_def.h | 8 +++++--- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/plat/arm/board/arm_fpga/fpga_console.c b/plat/arm/board/arm_fpga/fpga_console.c index a1fdb7832..8c1da62e2 100644 --- a/plat/arm/board/arm_fpga/fpga_console.c +++ b/plat/arm/board/arm_fpga/fpga_console.c @@ -4,8 +4,12 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include +#include +#include + +#include #include +#include #include @@ -13,8 +17,21 @@ static console_t console; void fpga_console_init(void) { - (void)console_pl011_register(PLAT_FPGA_BOOT_UART_BASE, 0, 0, - &console); + const void *fdt = (void *)(uintptr_t)FPGA_PRELOADED_DTB_BASE; + uintptr_t base_addr = PLAT_FPGA_CRASH_UART_BASE; + int node; + + /* + * Try to read the UART base address from the DT, by chasing the + * stdout-path property of the chosen node. + * If this does not work, use the crash console address as a fallback. + */ + node = fdt_get_stdout_node_offset(fdt); + if (node >= 0) { + fdt_get_reg_props_by_index(fdt, node, 0, &base_addr, NULL); + } + + (void)console_pl011_register(base_addr, 0, 0, &console); console_set_scope(&console, CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME); diff --git a/plat/arm/board/arm_fpga/fpga_def.h b/plat/arm/board/arm_fpga/fpga_def.h index 0bb2b22e0..03787293c 100644 --- a/plat/arm/board/arm_fpga/fpga_def.h +++ b/plat/arm/board/arm_fpga/fpga_def.h @@ -27,9 +27,11 @@ * FPGA image memory map related constants ******************************************************************************/ -/* UART base address, as configured by the image */ -#define PLAT_FPGA_BOOT_UART_BASE 0x7ff80000 -#define PLAT_FPGA_CRASH_UART_BASE PLAT_FPGA_BOOT_UART_BASE +/* + * UART base address, just for the crash console, as a fallback. + * The actual console UART address is taken from the DT. + */ +#define PLAT_FPGA_CRASH_UART_BASE 0x7ff80000 #define FPGA_DEFAULT_TIMER_FREQUENCY 10000000 -- cgit v1.2.3 From e3e5e6617bc06b95ed9207168724daa9e59360b9 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Thu, 23 Apr 2020 09:56:06 -0700 Subject: Tegra194: remove support for CPU suspend power down state Tegra194 platforms removed support to power down CPUs during CPU suspend. This patch removes the support for CPU suspend power down as a result. Signed-off-by: Varun Wadekar Change-Id: Ifde72c90c194582a79fb80904154b9886413f16e --- plat/nvidia/tegra/soc/t194/plat_psci_handlers.c | 34 ++----------------------- 1 file changed, 2 insertions(+), 32 deletions(-) diff --git a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c index ce5815b46..8f6e19fc3 100644 --- a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c @@ -78,14 +78,6 @@ int32_t tegra_soc_validate_power_state(uint32_t power_state, req_state->pwr_domain_state[MPIDR_AFFLVL1] = PSCI_LOCAL_STATE_RUN; break; - case PSTATE_ID_CORE_POWERDN: - - /* Core powerdown request */ - req_state->pwr_domain_state[MPIDR_AFFLVL0] = state_id; - req_state->pwr_domain_state[MPIDR_AFFLVL1] = state_id; - - break; - default: ERROR("%s: unsupported state id (%d)\n", __func__, state_id); ret = PSCI_E_INVALID_PARAMS; @@ -117,7 +109,7 @@ int32_t tegra_soc_cpu_standby(plat_local_state_t cpu_state) int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) { const plat_local_state_t *pwr_domain_state; - uint8_t stateid_afflvl0, stateid_afflvl2; + uint8_t stateid_afflvl2; plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); uint64_t mc_ctx_base; uint32_t val; @@ -128,25 +120,14 @@ int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) .system_state_force = 1U, .update_wake_mask = 1U, }; - uint32_t cpu = plat_my_core_pos(); int32_t ret = 0; /* get the state ID */ pwr_domain_state = target_state->pwr_domain_state; - stateid_afflvl0 = pwr_domain_state[MPIDR_AFFLVL0] & - TEGRA194_STATE_ID_MASK; stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL] & TEGRA194_STATE_ID_MASK; - if (stateid_afflvl0 == PSTATE_ID_CORE_POWERDN) { - - /* Enter CPU powerdown */ - (void)mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE, - (uint64_t)TEGRA_NVG_CORE_C7, - t19x_percpu_data[cpu].wake_time, - 0U); - - } else if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) { + if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) { /* save 'Secure Boot' Processor Feature Config Register */ val = mmio_read_32(TEGRA_MISC_BASE + MISCREG_PFCFG); @@ -187,8 +168,6 @@ int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) /* set system suspend state for house-keeping */ tegra194_set_system_suspend_entry(); - } else { - ; /* do nothing */ } return PSCI_E_SUCCESS; @@ -226,15 +205,6 @@ static plat_local_state_t tegra_get_afflvl1_pwr_state(const plat_local_state_t * plat_local_state_t target = states[core_pos]; mce_cstate_info_t cstate_info = { 0 }; - /* CPU suspend */ - if (target == PSTATE_ID_CORE_POWERDN) { - - /* Program default wake mask */ - cstate_info.wake_mask = TEGRA194_CORE_WAKE_MASK; - cstate_info.update_wake_mask = 1; - mce_update_cstate_info(&cstate_info); - } - /* CPU off */ if (target == PLAT_MAX_OFF_STATE) { -- cgit v1.2.3 From bc693ecc8b68144ef557371ae19de9787e696700 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Tue, 5 May 2020 22:44:20 -0700 Subject: Tegra194: validate C6 power state type This patch validates that PSTATE_STANDBY is set as the C6 power state type. Signed-off-by: Varun Wadekar Change-Id: I26a4a61bcb4ee0d1846ab61c007eeba3c180e5aa --- plat/nvidia/tegra/soc/t194/plat_psci_handlers.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c index 8f6e19fc3..e226372ee 100644 --- a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c @@ -73,6 +73,11 @@ int32_t tegra_soc_validate_power_state(uint32_t power_state, switch (state_id) { case PSTATE_ID_CORE_IDLE: + if (psci_get_pstate_type(power_state) != PSTATE_TYPE_STANDBY) { + ret = PSCI_E_INVALID_PARAMS; + break; + } + /* Core idle request */ req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_RET_STATE; req_state->pwr_domain_state[MPIDR_AFFLVL1] = PSCI_LOCAL_STATE_RUN; -- cgit v1.2.3 From c0ea3b1b79aeb67495e1a5389e50c5a315ba8de0 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Mon, 2 Dec 2019 10:05:02 +0100 Subject: plat/st: move GPIO bank helper function to platform source files Relation between GPIO banks and their base address and offset address if platform dependent. This change moves helper functions stm32_get_gpio_bank_base() and stm32_get_gpio_bank_offset() from plat/st/common to plat/st/stm32mp1/. Change-Id: Id3d03e585746aa5509c6fab7d88183a92d561e3f Signed-off-by: Etienne Carriere --- plat/st/common/stm32mp_common.c | 22 ---------------------- plat/st/stm32mp1/stm32mp1_private.c | 22 ++++++++++++++++++++++ 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/plat/st/common/stm32mp_common.c b/plat/st/common/stm32mp_common.c index 9af156457..48a747c7c 100644 --- a/plat/st/common/stm32mp_common.c +++ b/plat/st/common/stm32mp_common.c @@ -97,28 +97,6 @@ bool stm32mp_lock_available(void) return (read_sctlr() & c_m_bits) == c_m_bits; } -uintptr_t stm32_get_gpio_bank_base(unsigned int bank) -{ - if (bank == GPIO_BANK_Z) { - return GPIOZ_BASE; - } - - assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K); - - return GPIOA_BASE + (bank * GPIO_BANK_OFFSET); -} - -uint32_t stm32_get_gpio_bank_offset(unsigned int bank) -{ - if (bank == GPIO_BANK_Z) { - return 0; - } - - assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K); - - return bank * GPIO_BANK_OFFSET; -} - int stm32mp_check_header(boot_api_image_header_t *header, uintptr_t buffer) { uint32_t i; diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c index ac4519575..284ec9f9f 100644 --- a/plat/st/stm32mp1/stm32mp1_private.c +++ b/plat/st/stm32mp1/stm32mp1_private.c @@ -76,6 +76,28 @@ void configure_mmu(void) enable_mmu_svc_mon(0); } +uintptr_t stm32_get_gpio_bank_base(unsigned int bank) +{ + if (bank == GPIO_BANK_Z) { + return GPIOZ_BASE; + } + + assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K); + + return GPIOA_BASE + (bank * GPIO_BANK_OFFSET); +} + +uint32_t stm32_get_gpio_bank_offset(unsigned int bank) +{ + if (bank == GPIO_BANK_Z) { + return 0; + } + + assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K); + + return bank * GPIO_BANK_OFFSET; +} + unsigned long stm32_get_gpio_bank_clock(unsigned int bank) { if (bank == GPIO_BANK_Z) { -- cgit v1.2.3 From ccc199eddaa6f5545e5c375be258b6ba686205ff Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Sat, 25 Apr 2020 11:14:45 +0200 Subject: plat/stm32mp1: fdt helpers for secure aware gpio bank New helper functions to get GPIO banks configuration from the FDT. stm32_get_gpio_bank_pinctrl_node() allows stm32mp platforms to differentiate specific GPIO banks when these are defined with a specific path in the FDT. fdt_get_gpio_bank_pin_count() returns the number of pins in a GPIO bank as it depends on the SoC variant. Change-Id: I4481774152b3c6bf35bf986f58e357c2f9c19176 Signed-off-by: Etienne Carriere --- plat/st/common/include/stm32mp_common.h | 3 +++ plat/st/common/include/stm32mp_dt.h | 2 ++ plat/st/common/stm32mp_dt.c | 48 +++++++++++++++++++++++++++++++++ plat/st/stm32mp1/stm32mp1_private.c | 22 +++++++++++++++ 4 files changed, 75 insertions(+) diff --git a/plat/st/common/include/stm32mp_common.h b/plat/st/common/include/stm32mp_common.h index 27ddab0c8..feeb4a790 100644 --- a/plat/st/common/include/stm32mp_common.h +++ b/plat/st/common/include/stm32mp_common.h @@ -61,6 +61,9 @@ uintptr_t stm32_get_gpio_bank_base(unsigned int bank); unsigned long stm32_get_gpio_bank_clock(unsigned int bank); uint32_t stm32_get_gpio_bank_offset(unsigned int bank); +/* Return node offset for target GPIO bank ID @bank or a FDT error code */ +int stm32_get_gpio_bank_pinctrl_node(void *fdt, unsigned int bank); + /* Print CPU information */ void stm32mp_print_cpuinfo(void); diff --git a/plat/st/common/include/stm32mp_dt.h b/plat/st/common/include/stm32mp_dt.h index e79551a31..44ad820dc 100644 --- a/plat/st/common/include/stm32mp_dt.h +++ b/plat/st/common/include/stm32mp_dt.h @@ -1,4 +1,5 @@ /* + * Copyright (c) 2020, STMicroelectronics - All Rights Reserved * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -39,5 +40,6 @@ uintptr_t dt_get_pwr_base(void); uint32_t dt_get_pwr_vdd_voltage(void); uintptr_t dt_get_syscfg_base(void); const char *dt_get_board_model(void); +int fdt_get_gpio_bank_pin_count(unsigned int bank); #endif /* STM32MP_DT_H */ diff --git a/plat/st/common/stm32mp_dt.c b/plat/st/common/stm32mp_dt.c index 155f78404..4b8b2db90 100644 --- a/plat/st/common/stm32mp_dt.c +++ b/plat/st/common/stm32mp_dt.c @@ -393,3 +393,51 @@ const char *dt_get_board_model(void) return (const char *)fdt_getprop(fdt, node, "model", NULL); } + +/******************************************************************************* + * This function gets the pin count for a GPIO bank based from the FDT. + * It also checks node consistency. + ******************************************************************************/ +int fdt_get_gpio_bank_pin_count(unsigned int bank) +{ + int pinctrl_node; + int node; + uint32_t bank_offset; + + pinctrl_node = stm32_get_gpio_bank_pinctrl_node(fdt, bank); + if (pinctrl_node < 0) { + return -FDT_ERR_NOTFOUND; + } + + bank_offset = stm32_get_gpio_bank_offset(bank); + + fdt_for_each_subnode(node, fdt, pinctrl_node) { + const fdt32_t *cuint; + + if (fdt_getprop(fdt, node, "gpio-controller", NULL) == NULL) { + continue; + } + + cuint = fdt_getprop(fdt, node, "reg", NULL); + if (cuint == NULL) { + continue; + } + + if (fdt32_to_cpu(*cuint) != bank_offset) { + continue; + } + + if (fdt_get_status(node) == DT_DISABLED) { + return 0; + } + + cuint = fdt_getprop(fdt, node, "ngpios", NULL); + if (cuint == NULL) { + return -FDT_ERR_NOTFOUND; + } + + return (int)fdt32_to_cpu(*cuint); + } + + return 0; +} diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c index 284ec9f9f..779228d4a 100644 --- a/plat/st/stm32mp1/stm32mp1_private.c +++ b/plat/st/stm32mp1/stm32mp1_private.c @@ -109,6 +109,28 @@ unsigned long stm32_get_gpio_bank_clock(unsigned int bank) return GPIOA + (bank - GPIO_BANK_A); } +int stm32_get_gpio_bank_pinctrl_node(void *fdt, unsigned int bank) +{ + switch (bank) { + case GPIO_BANK_A: + case GPIO_BANK_B: + case GPIO_BANK_C: + case GPIO_BANK_D: + case GPIO_BANK_E: + case GPIO_BANK_F: + case GPIO_BANK_G: + case GPIO_BANK_H: + case GPIO_BANK_I: + case GPIO_BANK_J: + case GPIO_BANK_K: + return fdt_path_offset(fdt, "/soc/pin-controller"); + case GPIO_BANK_Z: + return fdt_path_offset(fdt, "/soc/pin-controller-z"); + default: + panic(); + } +} + static int get_part_number(uint32_t *part_nb) { uint32_t part_number; -- cgit v1.2.3 From 8fbcd9e421e2b7854928e92ccf11a0542cf186bb Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Sun, 8 Dec 2019 08:20:12 +0100 Subject: drivers: stm32mp1 clocks: allow tree lookup for several system clocks Oscillators, PLLs and some system clocks can be related straight to a parent clock. Prior this change were only oscillators and few clocks supported by this look up. This changes adds PLLs and other system clocks. This enables for flexible use of clock tree exploration when computing a clock frequency value. Change-Id: I15ec98023a7095e3120a6954de59a4799d92c66b Signed-off-by: Etienne Carriere --- drivers/st/clk/stm32mp1_clk.c | 84 ++++++++++++++++++++++++++++++--------- include/drivers/st/stm32mp1_rcc.h | 4 ++ 2 files changed, 70 insertions(+), 18 deletions(-) diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c index 540c66aa3..20369453e 100644 --- a/drivers/st/clk/stm32mp1_clk.c +++ b/drivers/st/clk/stm32mp1_clk.c @@ -106,10 +106,61 @@ enum stm32mp1_parent_sel { _MCUS_SEL, _USBPHY_SEL, _USBO_SEL, + _MPU_SEL, + _PER_SEL, _PARENT_SEL_NB, _UNKNOWN_SEL = 0xff, }; +/* State the parent clock ID straight related to a clock */ +static const uint8_t parent_id_clock_id[_PARENT_NB] = { + [_HSE] = CK_HSE, + [_HSI] = CK_HSI, + [_CSI] = CK_CSI, + [_LSE] = CK_LSE, + [_LSI] = CK_LSI, + [_I2S_CKIN] = _UNKNOWN_ID, + [_USB_PHY_48] = _UNKNOWN_ID, + [_HSI_KER] = CK_HSI, + [_HSE_KER] = CK_HSE, + [_HSE_KER_DIV2] = CK_HSE_DIV2, + [_CSI_KER] = CK_CSI, + [_PLL1_P] = PLL1_P, + [_PLL1_Q] = PLL1_Q, + [_PLL1_R] = PLL1_R, + [_PLL2_P] = PLL2_P, + [_PLL2_Q] = PLL2_Q, + [_PLL2_R] = PLL2_R, + [_PLL3_P] = PLL3_P, + [_PLL3_Q] = PLL3_Q, + [_PLL3_R] = PLL3_R, + [_PLL4_P] = PLL4_P, + [_PLL4_Q] = PLL4_Q, + [_PLL4_R] = PLL4_R, + [_ACLK] = CK_AXI, + [_PCLK1] = CK_AXI, + [_PCLK2] = CK_AXI, + [_PCLK3] = CK_AXI, + [_PCLK4] = CK_AXI, + [_PCLK5] = CK_AXI, + [_CK_PER] = CK_PER, + [_CK_MPU] = CK_MPU, + [_CK_MCU] = CK_MCU, +}; + +static unsigned int clock_id2parent_id(unsigned long id) +{ + unsigned int n; + + for (n = 0U; n < ARRAY_SIZE(parent_id_clock_id); n++) { + if (parent_id_clock_id[n] == id) { + return n; + } + } + + return _UNKNOWN_ID; +} + enum stm32mp1_pll_id { _PLL1, _PLL2, @@ -281,19 +332,6 @@ struct stm32mp1_clk_pll { .refclk[3] = (p4), \ } -static const uint8_t stm32mp1_clks[][2] = { - { CK_PER, _CK_PER }, - { CK_MPU, _CK_MPU }, - { CK_AXI, _ACLK }, - { CK_MCU, _CK_MCU }, - { CK_HSE, _HSE }, - { CK_CSI, _CSI }, - { CK_LSI, _LSI }, - { CK_LSE, _LSE }, - { CK_HSI, _HSI }, - { CK_HSE_DIV2, _HSE_KER_DIV2 }, -}; - #define NB_GATES ARRAY_SIZE(stm32mp1_clk_gate) static const struct stm32mp1_clk_gate stm32mp1_clk_gate[] = { @@ -440,6 +478,14 @@ static const uint8_t usbo_parents[] = { _PLL4_R, _USB_PHY_48 }; +static const uint8_t mpu_parents[] = { + _HSI, _HSE, _PLL1_P, _PLL1_P /* specific div */ +}; + +static const uint8_t per_parents[] = { + _HSI, _HSE, _CSI, +}; + static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = { _CLK_PARENT_SEL(I2C12, RCC_I2C12CKSELR, i2c12_parents), _CLK_PARENT_SEL(I2C35, RCC_I2C35CKSELR, i2c35_parents), @@ -448,6 +494,8 @@ static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = { _CLK_PARENT_SEL(SPI6, RCC_SPI6CKSELR, spi6_parents), _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(UART6, RCC_UART6CKSELR, uart6_parents), _CLK_PARENT_SEL(UART24, RCC_UART24CKSELR, uart234578_parents), _CLK_PARENT_SEL(UART35, RCC_UART35CKSELR, uart234578_parents), @@ -618,16 +666,16 @@ static enum stm32mp1_parent_id stm32mp1_clk_get_fixed_parent(int i) static int stm32mp1_clk_get_parent(unsigned long id) { const struct stm32mp1_clk_sel *sel; - uint32_t j, p_sel; + uint32_t p_sel; int i; enum stm32mp1_parent_id p; enum stm32mp1_parent_sel s; uintptr_t rcc_base = stm32mp_rcc_base(); - for (j = 0U; j < ARRAY_SIZE(stm32mp1_clks); j++) { - if (stm32mp1_clks[j][0] == id) { - return (int)stm32mp1_clks[j][1]; - } + /* Few non gateable clock have a static parent ID, find them */ + i = (int)clock_id2parent_id(id); + if (i != _UNKNOWN_ID) { + return i; } i = stm32mp1_clk_get_gated_id(id); diff --git a/include/drivers/st/stm32mp1_rcc.h b/include/drivers/st/stm32mp1_rcc.h index 4b4aac87d..2ffc3b2bc 100644 --- a/include/drivers/st/stm32mp1_rcc.h +++ b/include/drivers/st/stm32mp1_rcc.h @@ -250,6 +250,8 @@ #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 @@ -266,6 +268,8 @@ #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) -- cgit v1.2.3 From 8ae08dcd19ef5f027163e57d197b7690443927d2 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Sun, 8 Dec 2019 08:20:40 +0100 Subject: drivers: stm32mp1 clocks: support shifted clock selector bit masks The current implementation optimizes memory consumed by gateable clock table by storing bit mask and bit shift with 1 byte each. The issue is that register selector bit masks above the 7th LSBit cannot be stored. This change uses the shift info to shift the mask before it is used, allowing clock selector register bit fields to be spread on the 32 bits of the register as long as the mask fits in 8 contiguous bit at most. This change is needed to add the RTC clock to the gateable clocks table. Change-Id: I8a0fbcbf20ea383fb3d712f5064d2d307e44465d Signed-off-by: Etienne Carriere --- drivers/st/clk/stm32mp1_clk.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c index 20369453e..823e4a972 100644 --- a/drivers/st/clk/stm32mp1_clk.c +++ b/drivers/st/clk/stm32mp1_clk.c @@ -310,7 +310,8 @@ struct stm32mp1_clk_pll { [_ ## _label ## _SEL] = { \ .offset = _rcc_selr, \ .src = _rcc_selr ## _ ## _label ## SRC_SHIFT, \ - .msk = _rcc_selr ## _ ## _label ## SRC_MASK, \ + .msk = (_rcc_selr ## _ ## _label ## SRC_MASK) >> \ + (_rcc_selr ## _ ## _label ## SRC_SHIFT), \ .parent = (_parents), \ .nb_parent = ARRAY_SIZE(_parents) \ } @@ -697,7 +698,8 @@ static int stm32mp1_clk_get_parent(unsigned long id) } sel = clk_sel_ref(s); - p_sel = (mmio_read_32(rcc_base + sel->offset) & sel->msk) >> sel->src; + p_sel = (mmio_read_32(rcc_base + sel->offset) & + (sel->msk << sel->src)) >> sel->src; if (p_sel < sel->nb_parent) { return (int)sel->parent[p_sel]; } -- cgit v1.2.3 From 016af0064d79a04a2cba3115496b5ca17d44062a Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Sun, 8 Dec 2019 08:22:31 +0100 Subject: drivers: stm32mp1 clocks: add RTC as a gateable clock Adds RTC clock to the list of the supported clocks. This allows stm32mp_clk_*() API functions to enable, disable and set and get rate for the clock RTC clock. Change-Id: I8efc3f00b1f22d1912f59d1846994e9e646d6614 Signed-off-by: Etienne Carriere --- drivers/st/clk/stm32mp1_clk.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c index 823e4a972..18a2fe4f3 100644 --- a/drivers/st/clk/stm32mp1_clk.c +++ b/drivers/st/clk/stm32mp1_clk.c @@ -108,6 +108,7 @@ enum stm32mp1_parent_sel { _USBO_SEL, _MPU_SEL, _PER_SEL, + _RTC_SEL, _PARENT_SEL_NB, _UNKNOWN_SEL = 0xff, }; @@ -408,6 +409,7 @@ static const struct stm32mp1_clk_gate stm32mp1_clk_gate[] = { _CLK_SC_SELEC(RCC_MP_AHB6ENSETR, 17, SDMMC2_K, _SDMMC12_SEL), _CLK_SC_SELEC(RCC_MP_AHB6ENSETR, 24, USBH, _UNKNOWN_SEL), + _CLK_SELEC(RCC_BDCR, 20, RTC, _RTC_SEL), _CLK_SELEC(RCC_DBGCFGR, 8, CK_DBG, _UNKNOWN_SEL), }; @@ -487,6 +489,10 @@ static const uint8_t per_parents[] = { _HSI, _HSE, _CSI, }; +static const uint8_t rtc_parents[] = { + _UNKNOWN_ID, _LSE, _LSI, _HSE +}; + static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = { _CLK_PARENT_SEL(I2C12, RCC_I2C12CKSELR, i2c12_parents), _CLK_PARENT_SEL(I2C35, RCC_I2C35CKSELR, i2c35_parents), @@ -497,6 +503,7 @@ static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = { _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(RTC, RCC_BDCR, rtc_parents), _CLK_PARENT_SEL(UART6, RCC_UART6CKSELR, uart6_parents), _CLK_PARENT_SEL(UART24, RCC_UART24CKSELR, uart234578_parents), _CLK_PARENT_SEL(UART35, RCC_UART35CKSELR, uart234578_parents), -- cgit v1.2.3 From 35848200b9ff2e5bf5888dff04d6527807143b20 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Sun, 8 Dec 2019 08:21:44 +0100 Subject: drivers: stm32mp1 clocks: prevent crash on always on clocks Oscillators and PLLs are not gated on stm32mp_clk_enable/disable() calls. This change prevents functions to panic when called for such always-on clocks. Gating these clocks is out of the scope of this change. Change-Id: Ie730553dea480b529de942446176db9119587832 Signed-off-by: Etienne Carriere --- drivers/st/clk/stm32mp1_clk.c | 45 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c index 18a2fe4f3..faf4bf6f9 100644 --- a/drivers/st/clk/stm32mp1_clk.c +++ b/drivers/st/clk/stm32mp1_clk.c @@ -1029,12 +1029,41 @@ unsigned int stm32mp1_clk_get_refcount(unsigned long id) return gate_refcounts[i]; } +/* Oscillators and PLLs are not gated at runtime */ +static bool clock_is_always_on(unsigned long id) +{ + switch (id) { + case CK_HSE: + case CK_CSI: + case CK_LSI: + case CK_LSE: + case CK_HSI: + case CK_HSE_DIV2: + case PLL1_Q: + case PLL1_R: + case PLL2_P: + case PLL2_Q: + case PLL2_R: + case PLL3_P: + case PLL3_Q: + case PLL3_R: + return true; + default: + return false; + } +} + void __stm32mp1_clk_enable(unsigned long id, bool secure) { const struct stm32mp1_clk_gate *gate; - int i = stm32mp1_clk_get_gated_id(id); + int i; unsigned int *refcnt; + if (clock_is_always_on(id)) { + return; + } + + i = stm32mp1_clk_get_gated_id(id); if (i < 0) { ERROR("Clock %d can't be enabled\n", (uint32_t)id); panic(); @@ -1055,9 +1084,14 @@ void __stm32mp1_clk_enable(unsigned long id, bool secure) void __stm32mp1_clk_disable(unsigned long id, bool secure) { const struct stm32mp1_clk_gate *gate; - int i = stm32mp1_clk_get_gated_id(id); + int i; unsigned int *refcnt; + if (clock_is_always_on(id)) { + return; + } + + i = stm32mp1_clk_get_gated_id(id); if (i < 0) { ERROR("Clock %d can't be disabled\n", (uint32_t)id); panic(); @@ -1087,8 +1121,13 @@ void stm32mp_clk_disable(unsigned long id) bool stm32mp_clk_is_enabled(unsigned long id) { - int i = stm32mp1_clk_get_gated_id(id); + int i; + if (clock_is_always_on(id)) { + return true; + } + + i = stm32mp1_clk_get_gated_id(id); if (i < 0) { panic(); } -- cgit v1.2.3 From 033b6c3ac3e501de569f99beac9b37f5aca73a27 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Sun, 8 Dec 2019 08:23:35 +0100 Subject: drivers: stm32mp1 clocks: enable system clocks during initialization Enable few system clocks at related BL initialization. Change-Id: I12b35e8cdc128b993de4a1dc4c6e9d52624dd8d9 Signed-off-by: Etienne Carriere --- drivers/st/clk/stm32mp1_clk.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c index faf4bf6f9..4a90a7b6a 100644 --- a/drivers/st/clk/stm32mp1_clk.c +++ b/drivers/st/clk/stm32mp1_clk.c @@ -2009,6 +2009,23 @@ static void stm32mp1_osc_init(void) static void sync_earlyboot_clocks_state(void) { + unsigned int idx; + const unsigned long secure_enable[] = { + AXIDCG, + BSEC, + DDRC1, DDRC1LP, + DDRC2, DDRC2LP, + DDRCAPB, DDRPHYCAPB, DDRPHYCAPBLP, + DDRPHYC, DDRPHYCLP, + TZC1, TZC2, + TZPC, + STGEN_K, + }; + + 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); } -- cgit v1.2.3 From 25be845ed23e1bad5ac210cef22814a016181255 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Sun, 8 Dec 2019 08:21:08 +0100 Subject: drivers: stm32mp1 clocks: fix debug trace on clock enable/disable Adds missing terminal new line character '\n' to debug traces, fix format as index is an unsigned value and use present tense rather than past tense in the printed message. Change-Id: I88c06ef4d3a11d97ff8e96875a3dd0f58a3c98b6 Signed-off-by: Etienne Carriere --- drivers/st/clk/stm32mp1_clk.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c index 4a90a7b6a..2f4dcadfc 100644 --- a/drivers/st/clk/stm32mp1_clk.c +++ b/drivers/st/clk/stm32mp1_clk.c @@ -988,27 +988,27 @@ static void __clk_enable(struct stm32mp1_clk_gate const *gate) { uintptr_t rcc_base = stm32mp_rcc_base(); + VERBOSE("Enable clock %u\n", gate->index); + if (gate->set_clr != 0U) { mmio_write_32(rcc_base + gate->offset, BIT(gate->bit)); } else { mmio_setbits_32(rcc_base + gate->offset, BIT(gate->bit)); } - - VERBOSE("Clock %d has been enabled", gate->index); } static void __clk_disable(struct stm32mp1_clk_gate const *gate) { uintptr_t rcc_base = stm32mp_rcc_base(); + VERBOSE("Disable clock %u\n", gate->index); + if (gate->set_clr != 0U) { mmio_write_32(rcc_base + gate->offset + RCC_MP_ENCLRR_OFFSET, BIT(gate->bit)); } else { mmio_clrbits_32(rcc_base + gate->offset, BIT(gate->bit)); } - - VERBOSE("Clock %d has been disabled", gate->index); } static bool __clk_is_enabled(struct stm32mp1_clk_gate const *gate) -- cgit v1.2.3 From b5b2923d9d1676d6f4395cb64d6fe6ca3f4109d4 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Tue, 12 May 2020 14:04:10 -0700 Subject: Tegra: introduce support for SMCCC_ARCH_SOC_ID This patch returns the SOC version and revision values from the 'plat_get_soc_version' and 'plat_get_soc_revision' handlers. Verified using TFTF SMCCC_ARCH_SOC_ID test. > Executing 'SMCCC_ARCH_SOC_ID test' TEST COMPLETE Passed SOC Rev = 0x102 SOC Ver = 0x36b0019 Signed-off-by: Varun Wadekar Change-Id: Ibd7101619143b74f6f6660732daeac1a8bca3e44 --- plat/nvidia/tegra/common/tegra_platform.c | 27 +++++++++++++++++++++++++++ plat/nvidia/tegra/include/tegra_platform.h | 7 +++++++ 2 files changed, 34 insertions(+) diff --git a/plat/nvidia/tegra/common/tegra_platform.c b/plat/nvidia/tegra/common/tegra_platform.c index c1e420959..e4338b963 100644 --- a/plat/nvidia/tegra/common/tegra_platform.c +++ b/plat/nvidia/tegra/common/tegra_platform.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -259,3 +260,29 @@ bool tegra_platform_is_virt_dev_kit(void) { return ((tegra_get_platform() == TEGRA_PLATFORM_VIRT_DEV_KIT) ? true : false); } + +/* + * This function returns soc version which mainly consist of below fields + * + * soc_version[30:24] = JEP-106 continuation code for the SiP + * soc_version[23:16] = JEP-106 identification code with parity bit for the SiP + * soc_version[0:15] = chip identification + */ +int32_t plat_get_soc_version(void) +{ + uint32_t chip_id = ((tegra_get_chipid() >> CHIP_ID_SHIFT) & CHIP_ID_MASK); + uint32_t manfid = (JEDEC_NVIDIA_BKID << 24) | (JEDEC_NVIDIA_MFID << 16); + + return (int32_t)(manfid | (chip_id & 0xFFFF)); +} + +/* + * This function returns soc revision in below format + * + * soc_revision[8:15] = major version number + * soc_revision[0:7] = minor version number + */ +int32_t plat_get_soc_revision(void) +{ + return (int32_t)((tegra_get_chipid_major() << 8) | tegra_get_chipid_minor()); +} diff --git a/plat/nvidia/tegra/include/tegra_platform.h b/plat/nvidia/tegra/include/tegra_platform.h index d83ce48b8..7dfa4d089 100644 --- a/plat/nvidia/tegra/include/tegra_platform.h +++ b/plat/nvidia/tegra/include/tegra_platform.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -30,6 +31,12 @@ #define TEGRA_CHIPID_TEGRA21 U(0x21) #define TEGRA_CHIPID_TEGRA18 U(0x18) +/******************************************************************************* + * JEDEC Standard Manufacturer's Identification Code and Bank ID + ******************************************************************************/ +#define JEDEC_NVIDIA_MFID U(0x6B) +#define JEDEC_NVIDIA_BKID U(3) + #ifndef __ASSEMBLER__ /* -- cgit v1.2.3 From 52696946ab3f441496436ad7223cb2bd853c8beb Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Thu, 16 Apr 2020 13:39:06 +0200 Subject: SPMD: code/comments cleanup As a follow-up to bdd2596d4, and related to SPM Dispatcher EL3 component and SPM Core S-EL2/S-EL1 component: update with cosmetic and coding rules changes. In addition: -Add Armv8.4-SecEL2 arch detection helper. -Add an SPMC context (on current core) get helper. -Return more meaningful error return codes. -Remove complexity in few spmd_smc_handler switch-cases. -Remove unused defines and structures from spmd_private.h Signed-off-by: Olivier Deprez Change-Id: I99e642450b0dafb19d3218a2f0e2d3107e8ca3fe --- include/arch/aarch64/arch_features.h | 8 +- include/plat/common/platform.h | 2 +- include/services/spm_core_manifest.h | 14 +-- plat/common/plat_spmd_manifest.c | 105 +++++++++-------- services/std_svc/spmd/spmd_main.c | 219 ++++++++++++++++++----------------- services/std_svc/spmd/spmd_private.h | 26 +---- 6 files changed, 193 insertions(+), 181 deletions(-) diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h index 0491f48c6..9513e977d 100644 --- a/include/arch/aarch64/arch_features.h +++ b/include/arch/aarch64/arch_features.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Arm Limited. All rights reserved. + * Copyright (c) 2019-2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -52,4 +52,10 @@ static inline unsigned int get_armv8_5_mte_support(void) ID_AA64PFR1_EL1_MTE_MASK); } +static inline bool is_armv8_4_sel2_present(void) +{ + return ((read_id_aa64pfr0_el1() >> ID_AA64PFR0_SEL2_SHIFT) & + ID_AA64PFR0_SEL2_MASK) == 1ULL; +} + #endif /* ARCH_FEATURES_H */ diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h index e4431d2f0..946a3b8b8 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.h @@ -289,7 +289,7 @@ int plat_spm_sp_rd_load(struct sp_res_desc *rd, const void *ptr, size_t size); int plat_spm_sp_get_next_address(void **sp_base, size_t *sp_size, void **rd_base, size_t *rd_size); #if defined(SPD_spmd) -int plat_spm_core_manifest_load(spmc_manifest_sect_attribute_t *manifest, +int plat_spm_core_manifest_load(spmc_manifest_attribute_t *manifest, const void *ptr, size_t size); #endif diff --git a/include/services/spm_core_manifest.h b/include/services/spm_core_manifest.h index 71e6cfbe4..0c4363691 100644 --- a/include/services/spm_core_manifest.h +++ b/include/services/spm_core_manifest.h @@ -4,8 +4,8 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#ifndef SPMC_MANIFEST_H -#define SPMC_MANIFEST_H +#ifndef SPM_CORE_MANIFEST_H +#define SPM_CORE_MANIFEST_H #include @@ -28,18 +28,18 @@ typedef struct spm_core_manifest_sect_attribute { uint32_t exec_state; /* - * Address of binary image containing SPM core in bytes (optional). + * Address of binary image containing SPM Core (optional). */ uint64_t load_address; /* * Offset from the base of the partition's binary image to the entry - * point of the partition. + * point of the partition (optional). */ uint64_t entrypoint; /* - * Size of binary image containing SPM core in bytes (mandatory). + * Size of binary image containing SPM Core in bytes (mandatory). */ uint32_t binary_size; @@ -48,6 +48,6 @@ typedef struct spm_core_manifest_sect_attribute { */ uint16_t spmc_id; -} spmc_manifest_sect_attribute_t; +} spmc_manifest_attribute_t; -#endif /* SPMC_MANIFEST_H */ +#endif /* SPM_CORE_MANIFEST_H */ diff --git a/plat/common/plat_spmd_manifest.c b/plat/common/plat_spmd_manifest.c index 8330356ae..a3e30e89c 100644 --- a/plat/common/plat_spmd_manifest.c +++ b/plat/common/plat_spmd_manifest.c @@ -5,65 +5,78 @@ */ #include +#include #include #include #include #include -#include #include #include +#define ATTRIBUTE_ROOT_NODE_STR "attribute" + /******************************************************************************* - * Attribute section handler + * SPMC attribute node parser ******************************************************************************/ -static int manifest_parse_attribute(spmc_manifest_sect_attribute_t *attr, +static int manifest_parse_attribute(spmc_manifest_attribute_t *attr, const void *fdt, int node) { uint32_t val32; - int rc = 0; + int rc; - assert(attr && fdt); + assert((attr != NULL) && (fdt != NULL)); rc = fdt_read_uint32(fdt, node, "maj_ver", &attr->major_version); - if (rc) { - ERROR("Missing SPCI major version in SPM core manifest.\n"); - return -ENOENT; + if (rc != 0) { + ERROR("Missing SPCI %s version in SPM Core manifest.\n", + "major"); + return rc; } rc = fdt_read_uint32(fdt, node, "min_ver", &attr->minor_version); - if (rc) { - ERROR("Missing SPCI minor version in SPM core manifest.\n"); - return -ENOENT; + if (rc != 0) { + ERROR("Missing SPCI %s version in SPM Core manifest.\n", + "minor"); + return rc; } rc = fdt_read_uint32(fdt, node, "spmc_id", &val32); - if (rc) { + if (rc != 0) { ERROR("Missing SPMC ID in manifest.\n"); - return -ENOENT; + return rc; } - attr->spmc_id = val32; + + attr->spmc_id = val32 & 0xffff; rc = fdt_read_uint32(fdt, node, "exec_state", &attr->exec_state); - if (rc) - NOTICE("Execution state not specified in SPM core manifest.\n"); + if (rc != 0) { + NOTICE("%s not specified in SPM Core manifest.\n", + "Execution state"); + } rc = fdt_read_uint32(fdt, node, "binary_size", &attr->binary_size); - if (rc) - NOTICE("Binary size not specified in SPM core manifest.\n"); + if (rc != 0) { + NOTICE("%s not specified in SPM Core manifest.\n", + "Binary size"); + } rc = fdt_read_uint64(fdt, node, "load_address", &attr->load_address); - if (rc) - NOTICE("Load address not specified in SPM core manifest.\n"); + if (rc != 0) { + NOTICE("%s not specified in SPM Core manifest.\n", + "Load address"); + } rc = fdt_read_uint64(fdt, node, "entrypoint", &attr->entrypoint); - if (rc) - NOTICE("Entrypoint not specified in SPM core manifest.\n"); + if (rc != 0) { + NOTICE("%s not specified in SPM Core manifest.\n", + "Entry point"); + } - VERBOSE("SPM core manifest attribute section:\n"); - VERBOSE(" version: %x.%x\n", attr->major_version, attr->minor_version); - VERBOSE(" spmc_id: %x\n", attr->spmc_id); + VERBOSE("SPM Core manifest attribute section:\n"); + 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); @@ -74,53 +87,51 @@ static int manifest_parse_attribute(spmc_manifest_sect_attribute_t *attr, /******************************************************************************* * Root node handler ******************************************************************************/ -static int manifest_parse_root(spmc_manifest_sect_attribute_t *manifest, - const void *fdt, - int root) +static int manifest_parse_root(spmc_manifest_attribute_t *manifest, + const void *fdt, + int root) { int node; - char *str; - str = "attribute"; - node = fdt_subnode_offset_namelen(fdt, root, str, strlen(str)); + assert(manifest != NULL); + + node = fdt_subnode_offset_namelen(fdt, root, ATTRIBUTE_ROOT_NODE_STR, + sizeof(ATTRIBUTE_ROOT_NODE_STR) - 1); if (node < 0) { - ERROR("Root node doesn't contain subnode '%s'\n", str); - return -ENOENT; + ERROR("Root node doesn't contain subnode '%s'\n", + ATTRIBUTE_ROOT_NODE_STR); + return node; } return manifest_parse_attribute(manifest, fdt, node); } /******************************************************************************* - * Platform handler to parse a SPM core manifest. + * Platform handler to parse a SPM Core manifest. ******************************************************************************/ -int plat_spm_core_manifest_load(spmc_manifest_sect_attribute_t *manifest, +int plat_spm_core_manifest_load(spmc_manifest_attribute_t *manifest, const void *ptr, size_t size) { int rc; - int root_node; assert(manifest != NULL); assert(ptr != NULL); - INFO("Reading SPM core manifest at address %p\n", ptr); + INFO("Reading SPM Core manifest at address %p\n", ptr); rc = fdt_check_header(ptr); if (rc != 0) { - ERROR("Wrong format for SPM core manifest (%d).\n", rc); - return -EINVAL; + ERROR("Wrong format for SPM Core manifest (%d).\n", rc); + return rc; } - INFO("Reading SPM core manifest at address %p\n", ptr); - - root_node = fdt_node_offset_by_compatible(ptr, -1, + rc = fdt_node_offset_by_compatible(ptr, -1, "arm,spci-core-manifest-1.0"); - if (root_node < 0) { - ERROR("Unrecognized SPM core manifest\n"); - return -ENOENT; + if (rc < 0) { + ERROR("Unrecognized SPM Core manifest\n"); + return rc; } - INFO("Reading SPM core manifest at address %p\n", ptr); - return manifest_parse_root(manifest, ptr, root_node); + return manifest_parse_root(manifest, ptr, rc); } diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c index a3e1a2d57..f6dbb97e3 100644 --- a/services/std_svc/spmd/spmd_main.c +++ b/services/std_svc/spmd/spmd_main.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -28,12 +29,12 @@ /******************************************************************************* * SPM Core context information. ******************************************************************************/ -spmd_spm_core_context_t spm_core_context[PLATFORM_CORE_COUNT]; +static spmd_spm_core_context_t spm_core_context[PLATFORM_CORE_COUNT]; /******************************************************************************* * SPM Core attribute information read from its manifest. ******************************************************************************/ -static spmc_manifest_sect_attribute_t spmc_attrs; +static spmc_manifest_attribute_t spmc_attrs; /******************************************************************************* * SPM Core entry point information. Discovered on the primary core and reused @@ -41,19 +42,35 @@ static spmc_manifest_sect_attribute_t spmc_attrs; ******************************************************************************/ static entry_point_info_t *spmc_ep_info; +/******************************************************************************* + * SPM Core context on current CPU get helper. + ******************************************************************************/ +spmd_spm_core_context_t *spmd_get_context(void) +{ + unsigned int linear_id = plat_my_core_pos(); + + return &spm_core_context[linear_id]; +} + /******************************************************************************* * Static function declaration. ******************************************************************************/ -static int32_t spmd_init(void); -static int spmd_spmc_init(void *rd_base, size_t rd_size); -static uint64_t spmd_spci_error_return(void *handle, int error_code); -static uint64_t spmd_smc_forward(uint32_t smc_fid, bool secure_origin, - uint64_t x1, uint64_t x2, uint64_t x3, - uint64_t x4, void *handle); +static int32_t spmd_init(void); +static int spmd_spmc_init(void *rd_base, + size_t rd_size); +static uint64_t spmd_spci_error_return(void *handle, + int error_code); +static uint64_t spmd_smc_forward(uint32_t smc_fid, + bool secure_origin, + uint64_t x1, + uint64_t x2, + uint64_t x3, + uint64_t x4, + void *handle); /******************************************************************************* - * This function takes an SP context pointer and performs a synchronous entry - * into it. + * This function takes an SPMC context pointer and performs a synchronous + * SPMC entry. ******************************************************************************/ uint64_t spmd_spm_core_sync_entry(spmd_spm_core_context_t *spmc_ctx) { @@ -83,14 +100,14 @@ uint64_t spmd_spm_core_sync_entry(spmd_spm_core_context_t *spmc_ctx) } /******************************************************************************* - * This function returns to the place where spm_sp_synchronous_entry() was + * This function returns to the place where spmd_spm_core_sync_entry() was * called originally. ******************************************************************************/ __dead2 void spmd_spm_core_sync_exit(uint64_t rc) { - spmd_spm_core_context_t *ctx = &spm_core_context[plat_my_core_pos()]; + spmd_spm_core_context_t *ctx = spmd_get_context(); - /* Get context of the SP in use by this CPU. */ + /* Get current CPU context from SPMC context */ assert(cm_get_context(SECURE) == &(ctx->cpu_ctx)); /* @@ -104,110 +121,98 @@ __dead2 void spmd_spm_core_sync_exit(uint64_t rc) } /******************************************************************************* - * Jump to the SPM core for the first time. + * Jump to the SPM Core for the first time. ******************************************************************************/ static int32_t spmd_init(void) { - uint64_t rc = 0; - spmd_spm_core_context_t *ctx = &spm_core_context[plat_my_core_pos()]; + spmd_spm_core_context_t *ctx = spmd_get_context(); + uint64_t rc; - INFO("SPM Core init start.\n"); + VERBOSE("SPM Core init start.\n"); ctx->state = SPMC_STATE_RESET; rc = spmd_spm_core_sync_entry(ctx); - if (rc) { + if (rc != 0ULL) { ERROR("SPMC initialisation failed 0x%llx\n", rc); - panic(); + return 0; } ctx->state = SPMC_STATE_IDLE; - INFO("SPM Core init end.\n"); + VERBOSE("SPM Core init end.\n"); return 1; } /******************************************************************************* - * Load SPMC manifest, init SPMC. + * Loads SPMC manifest and inits SPMC. ******************************************************************************/ static int spmd_spmc_init(void *rd_base, size_t rd_size) { - int rc; + spmd_spm_core_context_t *spm_ctx = spmd_get_context(); uint32_t ep_attr; - unsigned int linear_id = plat_my_core_pos(); - spmd_spm_core_context_t *spm_ctx = &spm_core_context[linear_id]; + int rc; - /* Load the SPM core manifest */ + /* Load the SPM Core manifest */ rc = plat_spm_core_manifest_load(&spmc_attrs, rd_base, rd_size); if (rc != 0) { - WARN("No or invalid SPM core manifest image provided by BL2 " - "boot loader. "); - return 1; + WARN("No or invalid SPM Core manifest image provided by BL2\n"); + return rc; } /* - * Ensure that the SPM core version is compatible with the SPM - * dispatcher version + * Ensure that the SPM Core version is compatible with the SPM + * Dispatcher version. */ if ((spmc_attrs.major_version != SPCI_VERSION_MAJOR) || (spmc_attrs.minor_version > SPCI_VERSION_MINOR)) { - WARN("Unsupported SPCI version (%x.%x) specified in SPM core " - "manifest image provided by BL2 boot loader.\n", + WARN("Unsupported SPCI version (%u.%u)\n", spmc_attrs.major_version, spmc_attrs.minor_version); - return 1; + return -EINVAL; } - INFO("SPCI version (%x.%x).\n", spmc_attrs.major_version, + VERBOSE("SPCI version (%u.%u).\n", spmc_attrs.major_version, spmc_attrs.minor_version); - INFO("SPM core run time EL%x.\n", + VERBOSE("SPM Core run time EL%x.\n", SPMD_SPM_AT_SEL2 ? MODE_EL2 : MODE_EL1); /* Validate the SPMC ID, Ensure high bit is set */ - if (!(spmc_attrs.spmc_id >> SPMC_SECURE_ID_SHIFT) & - SPMC_SECURE_ID_MASK) { - WARN("Invalid ID (0x%x) for SPMC.\n", - spmc_attrs.spmc_id); - return 1; + if (((spmc_attrs.spmc_id >> SPMC_SECURE_ID_SHIFT) & + SPMC_SECURE_ID_MASK) == 0U) { + WARN("Invalid ID (0x%x) for SPMC.\n", spmc_attrs.spmc_id); + return -EINVAL; } - INFO("SPMC ID %x.\n", spmc_attrs.spmc_id); - - /* Validate the SPM core execution state */ + /* Validate the SPM Core execution state */ if ((spmc_attrs.exec_state != MODE_RW_64) && (spmc_attrs.exec_state != MODE_RW_32)) { - WARN("Unsupported SPM core execution state %x specified in " - "manifest image provided by BL2 boot loader.\n", + WARN("Unsupported SPM Core execution state 0x%x.\n", spmc_attrs.exec_state); - return 1; + return -EINVAL; } - INFO("SPM core execution state %x.\n", spmc_attrs.exec_state); + VERBOSE("SPM Core execution state 0x%x.\n", spmc_attrs.exec_state); #if SPMD_SPM_AT_SEL2 /* Ensure manifest has not requested AArch32 state in S-EL2 */ if (spmc_attrs.exec_state == MODE_RW_32) { WARN("AArch32 state at S-EL2 is not supported.\n"); - return 1; + return -EINVAL; } /* * Check if S-EL2 is supported on this system if S-EL2 * is required for SPM */ - uint64_t sel2 = read_id_aa64pfr0_el1(); - - sel2 >>= ID_AA64PFR0_SEL2_SHIFT; - sel2 &= ID_AA64PFR0_SEL2_MASK; - - if (!sel2) { - WARN("SPM core run time S-EL2 is not supported."); - return 1; + if (!is_armv8_4_sel2_present()) { + WARN("SPM Core run time S-EL2 is not supported.\n"); + return -EINVAL; } #endif /* SPMD_SPM_AT_SEL2 */ /* Initialise an entrypoint to set up the CPU context */ ep_attr = SECURE | EP_ST_ENABLE; - if (read_sctlr_el3() & SCTLR_EE_BIT) { + if ((read_sctlr_el3() & SCTLR_EE_BIT) != 0ULL) { ep_attr |= EP_EE_BIG; } @@ -215,8 +220,8 @@ static int spmd_spmc_init(void *rd_base, size_t rd_size) assert(spmc_ep_info->pc == BL32_BASE); /* - * Populate SPSR for SPM core based upon validated parameters from the - * manifest + * Populate SPSR for SPM Core based upon validated parameters from the + * manifest. */ if (spmc_attrs.exec_state == MODE_RW_32) { spmc_ep_info->spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM, @@ -236,22 +241,22 @@ static int spmd_spmc_init(void *rd_base, size_t rd_size) DISABLE_ALL_EXCEPTIONS); } - /* Initialise SPM core context with this entry point information */ + /* Initialise SPM Core context with this entry point information */ cm_setup_context(&spm_ctx->cpu_ctx, spmc_ep_info); /* Reuse PSCI affinity states to mark this SPMC context as off */ spm_ctx->state = AFF_STATE_OFF; - INFO("SPM core setup done.\n"); + INFO("SPM Core setup done.\n"); - /* Register init function for deferred init. */ + /* Register init function for deferred init. */ bl31_register_bl32_init(&spmd_init); return 0; } /******************************************************************************* - * Initialize context of SPM core. + * Initialize context of SPM Core. ******************************************************************************/ int spmd_setup(void) { @@ -262,26 +267,24 @@ int spmd_setup(void) uintptr_t rd_size_align; spmc_ep_info = bl31_plat_get_next_image_ep_info(SECURE); - if (!spmc_ep_info) { - WARN("No SPM core image provided by BL2 boot loader, Booting " - "device without SP initialization. SMC`s destined for SPM " - "core will return SMC_UNK\n"); - return 1; + if (spmc_ep_info == NULL) { + WARN("No SPM Core image provided by BL2 boot loader.\n"); + return -EINVAL; } /* Under no circumstances will this parameter be 0 */ - assert(spmc_ep_info->pc != 0U); + assert(spmc_ep_info->pc != 0ULL); /* * Check if BL32 ep_info has a reference to 'tos_fw_config'. This will - * be used as a manifest for the SPM core at the next lower EL/mode. + * be used as a manifest for the SPM Core at the next lower EL/mode. */ if (spmc_ep_info->args.arg0 == 0U || spmc_ep_info->args.arg2 == 0U) { ERROR("Invalid or absent SPM core manifest\n"); panic(); } - /* Obtain whereabouts of SPM core manifest */ + /* Obtain whereabouts of SPM Core manifest */ rd_base = (void *) spmc_ep_info->args.arg0; rd_size = spmc_ep_info->args.arg2; @@ -305,9 +308,7 @@ int spmd_setup(void) if (rc != 0) { int mmap_rc; - WARN("Booting device without SPM initialization. " - "SPCI SMCs destined for SPM core will return " - "ENOTSUPPORTED\n"); + WARN("Booting device without SPM initialization.\n"); mmap_rc = mmap_remove_dynamic_region(rd_base_align, rd_size_align); @@ -326,9 +327,13 @@ int spmd_setup(void) /******************************************************************************* * Forward SMC to the other security state ******************************************************************************/ -static uint64_t spmd_smc_forward(uint32_t smc_fid, bool secure_origin, - uint64_t x1, uint64_t x2, uint64_t x3, - uint64_t x4, void *handle) +static uint64_t spmd_smc_forward(uint32_t smc_fid, + bool secure_origin, + uint64_t x1, + uint64_t x2, + uint64_t x3, + uint64_t x4, + void *handle) { uint32_t secure_state_in = (secure_origin) ? SECURE : NON_SECURE; uint32_t secure_state_out = (!secure_origin) ? SECURE : NON_SECURE; @@ -367,19 +372,23 @@ static uint64_t spmd_spci_error_return(void *handle, int error_code) * This function handles all SMCs in the range reserved for SPCI. Each call is * either forwarded to the other security state or handled by the SPM dispatcher ******************************************************************************/ -uint64_t spmd_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, - uint64_t x3, uint64_t x4, void *cookie, void *handle, +uint64_t spmd_smc_handler(uint32_t smc_fid, + uint64_t x1, + uint64_t x2, + uint64_t x3, + uint64_t x4, + void *cookie, + void *handle, uint64_t flags) { - spmd_spm_core_context_t *ctx = &spm_core_context[plat_my_core_pos()]; + spmd_spm_core_context_t *ctx = spmd_get_context(); bool secure_origin; int32_t ret; /* Determine which security state this SMC originated from */ secure_origin = is_caller_secure(flags); - INFO("SPM: 0x%x, 0x%llx, 0x%llx, 0x%llx, 0x%llx, " - "0x%llx, 0x%llx, 0x%llx\n", + INFO("SPM: 0x%x 0x%llx 0x%llx 0x%llx 0x%llx 0x%llx 0x%llx 0x%llx\n", 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)); @@ -388,7 +397,7 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, case SPCI_ERROR: /* * Check if this is the first invocation of this interface on - * this CPU. If so, then indicate that the SPM core initialised + * this CPU. If so, then indicate that the SPM Core initialised * unsuccessfully. */ if (secure_origin && (ctx->state == SPMC_STATE_RESET)) { @@ -402,9 +411,9 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, case SPCI_VERSION: /* * TODO: This is an optimization that the version information - * provided by the SPM core manifest is returned by the SPM + * provided by the SPM Core manifest is returned by the SPM * dispatcher. It might be a better idea to simply forward this - * call to the SPM core and wash our hands completely. + * call to the SPM Core and wash our hands completely. */ ret = MAKE_SPCI_VERSION(spmc_attrs.major_version, spmc_attrs.minor_version); @@ -416,7 +425,7 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, case SPCI_FEATURES: /* * This is an optional interface. Do the minimal checks and - * forward to SPM core which will handle it if implemented. + * forward to SPM Core which will handle it if implemented. */ /* @@ -428,42 +437,42 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, SPCI_ERROR_NOT_SUPPORTED); } - /* Forward SMC from Normal world to the SPM core */ + /* Forward SMC from Normal world to the SPM Core */ if (!secure_origin) { return spmd_smc_forward(smc_fid, secure_origin, x1, x2, x3, x4, handle); - } else { - /* - * Return success if call was from secure world i.e. all - * SPCI functions are supported. This is essentially a - * nop. - */ - SMC_RET8(handle, SPCI_SUCCESS_SMC32, 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)); } + /* + * Return success if call was from secure world i.e. all + * SPCI functions are supported. This is essentially a + * nop. + */ + SMC_RET8(handle, SPCI_SUCCESS_SMC32, 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)); + break; /* not reached */ case SPCI_ID_GET: /* * Returns the ID of the calling SPCI component. - */ + */ if (!secure_origin) { SMC_RET8(handle, SPCI_SUCCESS_SMC32, SPCI_TARGET_INFO_MBZ, SPCI_NS_ENDPOINT_ID, SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, SPCI_PARAM_MBZ); - } else { - SMC_RET8(handle, SPCI_SUCCESS_SMC32, - SPCI_TARGET_INFO_MBZ, spmc_attrs.spmc_id, - SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, - SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, - SPCI_PARAM_MBZ); } + SMC_RET8(handle, SPCI_SUCCESS_SMC32, + SPCI_TARGET_INFO_MBZ, spmc_attrs.spmc_id, + SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, + SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, + SPCI_PARAM_MBZ); + break; /* not reached */ case SPCI_RX_RELEASE: @@ -513,7 +522,7 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, /* * Check if this is the first invocation of this interface on * this CPU from the Secure world. If so, then indicate that the - * SPM core initialised successfully. + * SPM Core initialised successfully. */ if (secure_origin && (ctx->state == SPMC_STATE_RESET)) { spmd_spm_core_sync_exit(0); diff --git a/services/std_svc/spmd/spmd_private.h b/services/std_svc/spmd/spmd_private.h index 0ad35c7c1..232031bb3 100644 --- a/services/std_svc/spmd/spmd_private.h +++ b/services/std_svc/spmd/spmd_private.h @@ -33,12 +33,6 @@ #include #include -/* - * Convert a function no. in a FID to a bit position. All function nos. are - * between 0 and 0x1f - */ -#define SPCI_FNO_TO_BIT_POS(_fid) (1 << ((_fid) & U(0x1f))) - typedef enum spmc_state { SPMC_STATE_RESET = 0, SPMC_STATE_IDLE @@ -60,21 +54,10 @@ typedef struct spmd_spm_core_context { #define SPCI_NS_ENDPOINT_ID U(0) /* Mask and shift to check valid secure SPCI Endpoint ID. */ -#define SPMC_SECURE_ID_MASK 0x1 -#define SPMC_SECURE_ID_SHIFT 15 - -/* - * Data structure used by the SPM dispatcher (SPMD) in EL3 to track sequence of - * SPCI calls from lower ELs. - * - * next_smc_bit_map: Per-cpu bit map of SMCs from each world that are expected - * next. - */ -typedef struct spmd_spci_context { - uint32_t next_smc_bit_map[2]; -} spmd_spci_context_t; +#define SPMC_SECURE_ID_MASK U(1) +#define SPMC_SECURE_ID_SHIFT U(15) -/* Functions used to enter/exit a Secure Partition synchronously */ +/* Functions used to enter/exit SPMC synchronously */ uint64_t spmd_spm_core_sync_entry(spmd_spm_core_context_t *ctx); __dead2 void spmd_spm_core_sync_exit(uint64_t rc); @@ -82,6 +65,9 @@ __dead2 void spmd_spm_core_sync_exit(uint64_t rc); uint64_t spmd_spm_core_enter(uint64_t *c_rt_ctx); void __dead2 spmd_spm_core_exit(uint64_t c_rt_ctx, uint64_t ret); +/* SPMC context on current CPU get helper */ +spmd_spm_core_context_t *spmd_get_context(void); + #endif /* __ASSEMBLER__ */ #endif /* SPMD_PRIVATE_H */ -- cgit v1.2.3 From 23d5ba86bd7a43e7abb634c328d7a85bbc877fb5 Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Fri, 7 Feb 2020 15:44:43 +0100 Subject: SPMD: extract SPMC DTB header size from SPMD Currently BL2 passes TOS_FW_CONFIG address and size through registers to BL31. This corresponds to SPMC manifest load address and size. The SPMC manifest is mapped in BL31 by dynamic mapping. This patch removes BL2 changes from generic code (which were enclosed by SPD=spmd) and retrieves SPMC manifest size directly from within SPMD. The SPMC manifest load address is still passed through a register by generic code. Signed-off-by: Olivier Deprez Change-Id: I35c5abd95c616ae25677302f0b1d0c45c51c042f --- common/desc_image_load.c | 12 ------- include/plat/common/platform.h | 3 +- plat/common/plat_spmd_manifest.c | 68 +++++++++++++++++++++++++++++++++------ services/std_svc/spmd/spmd_main.c | 62 ++++++++--------------------------- 4 files changed, 73 insertions(+), 72 deletions(-) diff --git a/common/desc_image_load.c b/common/desc_image_load.c index 47c80aa86..30b97e050 100644 --- a/common/desc_image_load.c +++ b/common/desc_image_load.c @@ -214,9 +214,6 @@ void populate_next_bl_params_config(bl_params_t *bl2_to_next_bl_params) { bl_params_node_t *params_node; unsigned int fw_config_id; -#ifdef SPD_spmd - uint32_t fw_config_size = 0; -#endif uintptr_t fw_config_base; bl_mem_params_node_t *mem_params; uintptr_t hw_config_base = 0; @@ -264,10 +261,6 @@ void populate_next_bl_params_config(bl_params_t *bl2_to_next_bl_params) mem_params = get_bl_mem_params_node(fw_config_id); if (mem_params != NULL) { fw_config_base = mem_params->image_info.image_base; -#ifdef SPD_spmd - fw_config_size = - mem_params->image_info.image_size; -#endif } } @@ -306,11 +299,6 @@ void populate_next_bl_params_config(bl_params_t *bl2_to_next_bl_params) if (params_node->ep_info->args.arg1 == 0U) params_node->ep_info->args.arg1 = hw_config_base; -#ifdef SPD_spmd - if (params_node->ep_info->args.arg2 == 0U) - params_node->ep_info->args.arg2 = - fw_config_size; -#endif } #ifdef SPD_opteed } diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h index 946a3b8b8..b8ba14c57 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.h @@ -290,8 +290,7 @@ int plat_spm_sp_get_next_address(void **sp_base, size_t *sp_size, void **rd_base, size_t *rd_size); #if defined(SPD_spmd) int plat_spm_core_manifest_load(spmc_manifest_attribute_t *manifest, - const void *ptr, - size_t size); + const void *pm_addr); #endif /******************************************************************************* * Mandatory BL image load functions(may be overridden). diff --git a/plat/common/plat_spmd_manifest.c b/plat/common/plat_spmd_manifest.c index a3e30e89c..109b001f0 100644 --- a/plat/common/plat_spmd_manifest.c +++ b/plat/common/plat_spmd_manifest.c @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -110,28 +111,75 @@ static int manifest_parse_root(spmc_manifest_attribute_t *manifest, * Platform handler to parse a SPM Core manifest. ******************************************************************************/ int plat_spm_core_manifest_load(spmc_manifest_attribute_t *manifest, - const void *ptr, - size_t size) + const void *pm_addr) { - int rc; + int rc, unmap_ret; + uintptr_t pm_base, pm_base_align; + size_t mapped_size; assert(manifest != NULL); - assert(ptr != NULL); + assert(pm_addr != NULL); + + /* + * Assume TOS_FW_CONFIG is not necessarily aligned to a page + * boundary, thus calculate the remaining space between SPMC + * manifest start address and upper page limit. + * + */ + pm_base = (uintptr_t)pm_addr; + pm_base_align = page_align(pm_base, UP); + mapped_size = pm_base_align - pm_base; + + /* Check space within the page at least maps the FDT header */ + if (mapped_size < sizeof(struct fdt_header)) { + ERROR("Error while mapping SPM Core manifest.\n"); + return -EINVAL; + } - INFO("Reading SPM Core manifest at address %p\n", ptr); + /* Map first SPMC manifest page in the SPMD translation regime */ + pm_base_align = page_align(pm_base, DOWN); + rc = mmap_add_dynamic_region((unsigned long long)pm_base_align, + pm_base_align, + PAGE_SIZE, + MT_RO_DATA); + if (rc != 0) { + ERROR("Error while mapping SPM Core manifest (%d).\n", rc); + return rc; + } - rc = fdt_check_header(ptr); + rc = fdt_check_header(pm_addr); if (rc != 0) { ERROR("Wrong format for SPM Core manifest (%d).\n", rc); - return rc; + goto exit_unmap; } - rc = fdt_node_offset_by_compatible(ptr, -1, + /* Check SPMC manifest fits within the upper mapped page boundary */ + if (mapped_size < fdt_totalsize(pm_addr)) { + ERROR("SPM Core manifest too large.\n"); + rc = -EINVAL; + goto exit_unmap; + } + + VERBOSE("Reading SPM Core manifest at address %p\n", pm_addr); + + rc = fdt_node_offset_by_compatible(pm_addr, -1, "arm,spci-core-manifest-1.0"); if (rc < 0) { ERROR("Unrecognized SPM Core manifest\n"); - return rc; + goto exit_unmap; + } + + rc = manifest_parse_root(manifest, pm_addr, rc); + +exit_unmap: + unmap_ret = mmap_remove_dynamic_region(pm_base_align, PAGE_SIZE); + if (unmap_ret != 0) { + ERROR("Error while unmapping SPM Core manifest (%d).\n", + unmap_ret); + if (rc == 0) { + rc = unmap_ret; + } } - return manifest_parse_root(manifest, ptr, rc); + return rc; } diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c index f6dbb97e3..501782ffb 100644 --- a/services/std_svc/spmd/spmd_main.c +++ b/services/std_svc/spmd/spmd_main.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -56,8 +55,7 @@ spmd_spm_core_context_t *spmd_get_context(void) * Static function declaration. ******************************************************************************/ static int32_t spmd_init(void); -static int spmd_spmc_init(void *rd_base, - size_t rd_size); +static int spmd_spmc_init(void *pm_addr); static uint64_t spmd_spci_error_return(void *handle, int error_code); static uint64_t spmd_smc_forward(uint32_t smc_fid, @@ -146,14 +144,14 @@ static int32_t spmd_init(void) /******************************************************************************* * Loads SPMC manifest and inits SPMC. ******************************************************************************/ -static int spmd_spmc_init(void *rd_base, size_t rd_size) +static int spmd_spmc_init(void *pm_addr) { spmd_spm_core_context_t *spm_ctx = spmd_get_context(); uint32_t ep_attr; int rc; /* Load the SPM Core manifest */ - rc = plat_spm_core_manifest_load(&spmc_attrs, rd_base, rd_size); + rc = plat_spm_core_manifest_load(&spmc_attrs, pm_addr); if (rc != 0) { WARN("No or invalid SPM Core manifest image provided by BL2\n"); return rc; @@ -170,7 +168,7 @@ static int spmd_spmc_init(void *rd_base, size_t rd_size) return -EINVAL; } - VERBOSE("SPCI version (%u.%u).\n", spmc_attrs.major_version, + VERBOSE("SPCI version (%u.%u)\n", spmc_attrs.major_version, spmc_attrs.minor_version); VERBOSE("SPM Core run time EL%x.\n", @@ -186,12 +184,13 @@ static int spmd_spmc_init(void *rd_base, size_t rd_size) /* Validate the SPM Core execution state */ if ((spmc_attrs.exec_state != MODE_RW_64) && (spmc_attrs.exec_state != MODE_RW_32)) { - WARN("Unsupported SPM Core execution state 0x%x.\n", + WARN("Unsupported %s%x.\n", "SPM Core execution state 0x", spmc_attrs.exec_state); return -EINVAL; } - VERBOSE("SPM Core execution state 0x%x.\n", spmc_attrs.exec_state); + VERBOSE("%s%x.\n", "SPM Core execution state 0x", + spmc_attrs.exec_state); #if SPMD_SPM_AT_SEL2 /* Ensure manifest has not requested AArch32 state in S-EL2 */ @@ -260,11 +259,8 @@ static int spmd_spmc_init(void *rd_base, size_t rd_size) ******************************************************************************/ int spmd_setup(void) { + void *spmc_manifest; int rc; - void *rd_base; - size_t rd_size; - uintptr_t rd_base_align; - uintptr_t rd_size_align; spmc_ep_info = bl31_plat_get_next_image_ep_info(SECURE); if (spmc_ep_info == NULL) { @@ -279,49 +275,19 @@ int spmd_setup(void) * Check if BL32 ep_info has a reference to 'tos_fw_config'. This will * be used as a manifest for the SPM Core at the next lower EL/mode. */ - if (spmc_ep_info->args.arg0 == 0U || spmc_ep_info->args.arg2 == 0U) { - ERROR("Invalid or absent SPM core manifest\n"); - panic(); - } - - /* Obtain whereabouts of SPM Core manifest */ - rd_base = (void *) spmc_ep_info->args.arg0; - rd_size = spmc_ep_info->args.arg2; - - rd_base_align = page_align((uintptr_t) rd_base, DOWN); - rd_size_align = page_align((uintptr_t) rd_size, UP); - - /* Map the manifest in the SPMD translation regime first */ - VERBOSE("SPM core manifest base : 0x%lx\n", rd_base_align); - VERBOSE("SPM core manifest size : 0x%lx\n", rd_size_align); - rc = mmap_add_dynamic_region((unsigned long long) rd_base_align, - (uintptr_t) rd_base_align, - rd_size_align, - MT_RO_DATA); - if (rc != 0) { - ERROR("Error while mapping SPM core manifest (%d).\n", rc); - panic(); + spmc_manifest = (void *)spmc_ep_info->args.arg0; + if (spmc_manifest == NULL) { + ERROR("Invalid or absent SPM Core manifest.\n"); + return -EINVAL; } /* Load manifest, init SPMC */ - rc = spmd_spmc_init(rd_base, rd_size); + rc = spmd_spmc_init(spmc_manifest); if (rc != 0) { - int mmap_rc; - WARN("Booting device without SPM initialization.\n"); - - mmap_rc = mmap_remove_dynamic_region(rd_base_align, - rd_size_align); - if (mmap_rc != 0) { - ERROR("Error while unmapping SPM core manifest (%d).\n", - mmap_rc); - panic(); - } - - return rc; } - return 0; + return rc; } /******************************************************************************* -- cgit v1.2.3 From 3d28b0a42df56bf44037544f4aa192bcd47896ea Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Tue, 12 May 2020 10:36:05 +0200 Subject: doc: Update various process documents Most of the changes consist in using the new code owners terminology (from [1]). [1] https://developer.trustedfirmware.org/w/collaboration/project-maintenance-process/ Change-Id: Icead20e9335af12aa47d3f1ac5d04ca157b20c82 Signed-off-by: Sandrine Bailleux --- docs/about/maintainers.rst | 94 +++++++++++++++++++++++++------------------ docs/process/contributing.rst | 30 ++++++++------ docs/process/faq.rst | 4 +- 3 files changed, 72 insertions(+), 56 deletions(-) diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst index e4fb09d6c..358d5409b 100644 --- a/docs/about/maintainers.rst +++ b/docs/about/maintainers.rst @@ -1,14 +1,20 @@ -Maintainers -=========== +Project Maintenance +=================== -Trusted Firmware-A (TF-A) is an Arm maintained project. All contributions are -ultimately merged by the maintainers listed below. Technical ownership of some -parts of the codebase is delegated to the sub-maintainers listed below. An -acknowledgement from these sub-maintainers may be required before the +Trusted Firmware-A (TF-A) is an open governance community project. All +contributions are ultimately merged by the maintainers listed below. Technical +ownership of most parts of the codebase falls on the code owners listed +below. An acknowledgement from these code owners is required before the maintainers merge a contribution. -Main maintainers ----------------- +More details may be found in the `Project Maintenance Process`_ document. + + +.. _maintainers: + +Maintainers +----------- + :M: Dan Handley :G: `danh-arm`_ :M: Soby Mathew @@ -28,8 +34,14 @@ Main maintainers :M: Joanna Farley :G: `joannafarley-arm`_ + +.. _code owners: + +Code owners +----------- + Allwinner ARMv8 platform port ------------------------------ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :M: Andre Przywara :G: `Andre-ARM`_ :M: Samuel Holland @@ -39,7 +51,7 @@ Allwinner ARMv8 platform port :F: drivers/allwinner/ Amlogic Meson S905 (GXBB) platform port ---------------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :M: Andre Przywara :G: `Andre-ARM`_ :F: docs/plat/meson-gxbb.rst @@ -47,33 +59,33 @@ Amlogic Meson S905 (GXBB) platform port :F: plat/amlogic/gxbb/ Amlogic Meson S905x (GXL) platform port ---------------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :M: Remi Pommarel :G: `remi-triplefault`_ :F: docs/plat/meson-gxl.rst :F: plat/amlogic/gxl/ Amlogic Meson S905X2 (G12A) platform port ------------------------------------------ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :M: Carlo Caione :G: `carlocaione`_ :F: docs/plat/meson-g12a.rst :F: plat/amlogic/g12a/ Amlogic Meson A113D (AXG) platform port ------------------------------------------ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :M: Carlo Caione :G: `carlocaione`_ :F: docs/plat/meson-axg.rst :F: plat/amlogic/axg/ Armv7-A architecture port -------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^ :M: Etienne Carriere :G: `etienne-lms`_ Arm System Guidance for Infrastructure / Mobile FVP platforms -------------------------------------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :M: Nariman Poushin :G: `npoushin`_ :M: Thomas Abraham @@ -84,7 +96,7 @@ Arm System Guidance for Infrastructure / Mobile FVP platforms :F: plat/arm/board/sgm775/ Console API framework ---------------------- +^^^^^^^^^^^^^^^^^^^^^ :M: Julius Werner :G: `jwerner-chromium`_ :F: drivers/console/ @@ -92,7 +104,7 @@ Console API framework :F: plat/common/aarch64/crash_console_helpers.S coreboot support libraries --------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^ :M: Julius Werner :G: `jwerner-chromium`_ :F: drivers/coreboot/ @@ -101,7 +113,7 @@ coreboot support libraries :F: lib/coreboot/ eMMC/UFS drivers ----------------- +^^^^^^^^^^^^^^^^ :M: Haojian Zhuang :G: `hzhuang1`_ :F: drivers/partition/ @@ -113,7 +125,7 @@ eMMC/UFS drivers :F: include/drivers/synopsys/dw_mmc.h HiSilicon HiKey and HiKey960 platform ports -------------------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :M: Haojian Zhuang :G: `hzhuang1`_ :F: docs/plat/hikey.rst @@ -122,14 +134,14 @@ HiSilicon HiKey and HiKey960 platform ports :F: plat/hisilicon/hikey960/ HiSilicon Poplar platform port ------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :M: Shawn Guo :G: `shawnguo2`_ :F: docs/plat/poplar.rst :F: plat/hisilicon/poplar/ Intel SocFPGA platform ports ----------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :M: Tien Hock Loh :G: `thloh85-intel`_ :M: Hadi Asyrafi @@ -138,13 +150,13 @@ Intel SocFPGA platform ports :F: drivers/intel/soc/ MediaTek platform ports ------------------------ +^^^^^^^^^^^^^^^^^^^^^^^ :M: Yidi Lin (林以廸) :G: `mtk09422`_ :F: plat/mediatek/ Marvell platform ports and SoC drivers --------------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :M: Konstantin Porotchkin :G: `kostapr`_ :F: docs/plat/marvell/ @@ -153,7 +165,7 @@ Marvell platform ports and SoC drivers :F: tools/marvell/ NVidia platform ports ---------------------- +^^^^^^^^^^^^^^^^^^^^^ :M: Varun Wadekar :G: `vwadekar`_ :F: docs/plat/nvidia-tegra.rst @@ -162,14 +174,14 @@ NVidia platform ports :F: plat/nvidia/ NXP QorIQ Layerscape platform ports ------------------------------------ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :M: Jiafei Pan :G: `qoriq-open-source`_ :F: docs/plat/ls1043a.rst :F: plat/layerscape/ NXP i.MX 7 WaRP7 platform port and SoC drivers ----------------------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :M: Bryan O'Donoghue :G: `bryanodonoghue`_ :M: Jun Nie @@ -182,35 +194,35 @@ NXP i.MX 7 WaRP7 platform port and SoC drivers :F: drivers/imx/usdhc/ NXP i.MX 8 platform port ------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^ :M: Anson Huang :G: `Anson-Huang`_ :F: docs/plat/imx8.rst :F: plat/imx/ NXP i.MX8M platform port ------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^ :M: Jacky Bai :G: `JackyBai`_ :F: docs/plat/imx8m.rst :F: plat/imx/imx8m/ OP-TEE dispatcher ------------------ +^^^^^^^^^^^^^^^^^ :M: Jens Wiklander :G: `jenswi-linaro`_ :F: docs/components/spd/optee-dispatcher.rst :F: services/spd/opteed/ QEMU platform port ------------------- +^^^^^^^^^^^^^^^^^^ :M: Jens Wiklander :G: `jenswi-linaro`_ :F: docs/plat/qemu.rst :F: plat/qemu/ Raspberry Pi 3 platform port ----------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :M: Ying-Chun Liu (PaulLiu) :G: `grandpaul`_ :F: docs/plat/rpi3.rst @@ -220,7 +232,7 @@ Raspberry Pi 3 platform port :F: include/drivers/rpi3/ Raspberry Pi 4 platform port ----------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :M: Andre Przywara :G: `Andre-ARM`_ :F: docs/plat/rpi4.rst @@ -230,7 +242,7 @@ Raspberry Pi 4 platform port :F: include/drivers/rpi3/ Renesas rcar-gen3 platform port -------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :M: Jorge Ramirez-Ortiz :G: `ldts`_ :M: Marek Vasut @@ -241,7 +253,7 @@ Renesas rcar-gen3 platform port :F: tools/renesas/rcar_layout_create RockChip platform port ----------------------- +^^^^^^^^^^^^^^^^^^^^^^ :M: Tony Xie :G: `TonyXie06`_ :G: `rockchip-linux`_ @@ -250,7 +262,7 @@ RockChip platform port :F: plat/rockchip/ STM32MP1 platform port ----------------------- +^^^^^^^^^^^^^^^^^^^^^^ :M: Yann Gautier :G: `Yann-lms`_ :F: docs/plat/stm32mp1.rst @@ -262,21 +274,21 @@ STM32MP1 platform port :F: tools/stm32image/ Synquacer platform port ------------------------ +^^^^^^^^^^^^^^^^^^^^^^^ :M: Sumit Garg :G: `b49020`_ :F: docs/plat/synquacer.rst :F: plat/socionext/synquacer/ Texas Instruments platform port -------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :M: Andrew F. Davis :G: `glneo`_ :F: docs/plat/ti-k3.rst :F: plat/ti/ TLK/Trusty secure payloads --------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^ :M: Varun Wadekar :G: `vwadekar`_ :F: docs/components/spd/tlk-dispatcher.rst @@ -286,14 +298,14 @@ TLK/Trusty secure payloads :F: services/spd/trusty/ UniPhier platform port ----------------------- +^^^^^^^^^^^^^^^^^^^^^^ :M: Masahiro Yamada :G: `masahir0y`_ :F: docs/plat/socionext-uniphier.rst :F: plat/socionext/uniphier/ Xilinx platform port --------------------- +^^^^^^^^^^^^^^^^^^^^ :M: Siva Durga Prasad Paladugu :G: `sivadur`_ :F: docs/plat/xilinx-zynqmp.rst @@ -339,3 +351,5 @@ Xilinx platform port .. _odeprez: https://github.com/odeprez .. _bipinravi-arm: https://github.com/bipinravi-arm .. _joannafarley-arm: https://github.com/joannafarley-arm + +.. _Project Maintenance Process: https://developer.trustedfirmware.org/w/collaboration/project-maintenance-process/ diff --git a/docs/process/contributing.rst b/docs/process/contributing.rst index 68c494baa..7886cf4f5 100644 --- a/docs/process/contributing.rst +++ b/docs/process/contributing.rst @@ -4,8 +4,8 @@ Contributor's Guide Getting Started --------------- -- Make sure you have a Github account and you are logged on - `developer.trustedfirmware.org`_. +- Make sure you have a Github account and you are logged on both + `developer.trustedfirmware.org`_ and `review.trustedfirmware.org`_. - Create an `issue`_ for your work if one does not already exist. This gives everyone visibility of whether others are working on something similar. @@ -55,9 +55,9 @@ Making Changes where XXXX is the year of first contribution (if different to YYYY) and YYYY is the year of most recent contribution. is your name or your company name. - - If you are submitting new files that you intend to be the technical - sub-maintainer for (for example, a new platform port), then also update - the :ref:`maintainers` file. + - If you are submitting new files that you intend to be the code owner for + (for example, a new platform port), then also update the + :ref:`code owners` file. - For topics with multiple commits, you should make all documentation changes (and nothing else) in the last commit of the series. Otherwise, include the documentation changes within the single commit. @@ -91,8 +91,10 @@ Submitting Changes targeting the ``integration`` branch. - The changes will then undergo further review and testing by the - :ref:`maintainers`. Any review comments will be made directly on your - patch. This may require you to do some rework. + :ref:`code owners` and :ref:`maintainers`. Any review comments will be + made directly on your patch. This may require you to do some rework. For + controversial changes, the discussion might be moved to the `TF-A mailing + list`_ to involve more of the community. Refer to the `Gerrit Uploading Changes documentation`_ for more details. @@ -102,12 +104,12 @@ Submitting Changes ``integration`` branch. - If the changes are not based on a sufficiently-recent commit, or if they cannot be automatically rebased, then the :ref:`maintainers` may rebase it - on the ``master`` branch or ask you to do so. + on the ``integration`` branch or ask you to do so. - After final integration testing, the changes will make their way into the - ``master`` branch. If a problem is found during integration, the merge - commit will be removed from the ``integration`` branch and the - :ref:`maintainers` will ask you to create a new patch set to resolve the - problem. + ``master`` branch. If a problem is found during integration, the + :ref:`maintainers` will request your help to solve the issue. They may + revert your patches and ask you to resubmit a reworked version of them or + they may ask you to provide a fix-up patch. Binary Components ----------------- @@ -131,12 +133,14 @@ Binary Components *Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.* .. _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://git.trustedfirmware.org/TF-A/tf-a-tests.git/about/ +.. _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 +.. _TF-A mailing list: https://lists.trustedfirmware.org/mailman/listinfo/tf-a diff --git a/docs/process/faq.rst b/docs/process/faq.rst index 2c3658480..daab1987f 100644 --- a/docs/process/faq.rst +++ b/docs/process/faq.rst @@ -70,12 +70,10 @@ What are these strange comments in my changes? All the comments from ``ci-bot-user`` are associated with Continuous Integration infrastructure. The links published on the comment are not currently accessible, but would be after the CI has been transitioned to `trustedfirmware.org`_. -Please refer to https://github.com/ARM-software/tf-issues/issues/681 for more -details on the timelines. -------------- -*Copyright (c) 2019, Arm Limited. All rights reserved.* +*Copyright (c) 2019-2020, Arm Limited. All rights reserved.* .. _Gerrit Upload Patch Set documentation: https://review.trustedfirmware.org/Documentation/intro-user.html#upload-patch-set .. _Gerrit Replace Changes documentation: https://review.trustedfirmware.org/Documentation/user-upload.html#push_replace -- cgit v1.2.3 From 0c16d684b256e9fe1e276a77771a813c0be9f2f4 Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Wed, 13 May 2020 08:57:41 +0200 Subject: doc: Reorganize maintainers.rst file The maintainers.rst file provides the list of all TF-A modules and their code owners. As there are quite a lot of modules (and more to come) in TF-A, it is sometimes hard to find the information. Introduce categories (core code, drivers/libraries/framework, ...) and classify each module in the right one. Note that the core code category is pretty much empty right now but the plan would be to expand it with further modules (e.g. PSCI, SDEI, TBBR, ...) in a future patch. Change-Id: Id68a2dd79a8f6b68af5364bbf1c59b20c05f8fe7 Signed-off-by: Sandrine Bailleux --- docs/about/maintainers.rst | 121 ++++++++++++++++++++++++++------------------- 1 file changed, 70 insertions(+), 51 deletions(-) diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst index 358d5409b..d40134f81 100644 --- a/docs/about/maintainers.rst +++ b/docs/about/maintainers.rst @@ -40,6 +40,54 @@ Maintainers Code owners ----------- +Core Code +~~~~~~~~~ + +.. note:: + This section is incomplete right now. + +Armv7-A architecture port +^^^^^^^^^^^^^^^^^^^^^^^^^ +:M: Etienne Carriere +:G: `etienne-lms`_ + + +Drivers, Libraries and Framework Code +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Console API framework +^^^^^^^^^^^^^^^^^^^^^ +:M: Julius Werner +:G: `jwerner-chromium`_ +:F: drivers/console/ +:F: include/drivers/console.h +:F: plat/common/aarch64/crash_console_helpers.S + +coreboot support libraries +^^^^^^^^^^^^^^^^^^^^^^^^^^ +:M: Julius Werner +:G: `jwerner-chromium`_ +:F: drivers/coreboot/ +:F: include/drivers/coreboot/ +:F: include/lib/coreboot.h +:F: lib/coreboot/ + +eMMC/UFS drivers +^^^^^^^^^^^^^^^^ +:M: Haojian Zhuang +:G: `hzhuang1`_ +:F: drivers/partition/ +:F: drivers/synopsys/emmc/ +:F: drivers/synopsys/ufs/ +:F: drivers/ufs/ +:F: include/drivers/dw_ufs.h +:F: include/drivers/ufs.h +:F: include/drivers/synopsys/dw_mmc.h + + +Platform Ports +~~~~~~~~~~~~~~ + Allwinner ARMv8 platform port ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :M: Andre Przywara @@ -79,11 +127,6 @@ Amlogic Meson A113D (AXG) platform port :F: docs/plat/meson-axg.rst :F: plat/amlogic/axg/ -Armv7-A architecture port -^^^^^^^^^^^^^^^^^^^^^^^^^ -:M: Etienne Carriere -:G: `etienne-lms`_ - Arm System Guidance for Infrastructure / Mobile FVP platforms ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :M: Nariman Poushin @@ -95,35 +138,6 @@ Arm System Guidance for Infrastructure / Mobile FVP platforms :F: plat/arm/board/sgi575/ :F: plat/arm/board/sgm775/ -Console API framework -^^^^^^^^^^^^^^^^^^^^^ -:M: Julius Werner -:G: `jwerner-chromium`_ -:F: drivers/console/ -:F: include/drivers/console.h -:F: plat/common/aarch64/crash_console_helpers.S - -coreboot support libraries -^^^^^^^^^^^^^^^^^^^^^^^^^^ -:M: Julius Werner -:G: `jwerner-chromium`_ -:F: drivers/coreboot/ -:F: include/drivers/coreboot/ -:F: include/lib/coreboot.h -:F: lib/coreboot/ - -eMMC/UFS drivers -^^^^^^^^^^^^^^^^ -:M: Haojian Zhuang -:G: `hzhuang1`_ -:F: drivers/partition/ -:F: drivers/synopsys/emmc/ -:F: drivers/synopsys/ufs/ -:F: drivers/ufs/ -:F: include/drivers/dw_ufs.h -:F: include/drivers/ufs.h -:F: include/drivers/synopsys/dw_mmc.h - HiSilicon HiKey and HiKey960 platform ports ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :M: Haojian Zhuang @@ -207,13 +221,6 @@ NXP i.MX8M platform port :F: docs/plat/imx8m.rst :F: plat/imx/imx8m/ -OP-TEE dispatcher -^^^^^^^^^^^^^^^^^ -:M: Jens Wiklander -:G: `jenswi-linaro`_ -:F: docs/components/spd/optee-dispatcher.rst -:F: services/spd/opteed/ - QEMU platform port ^^^^^^^^^^^^^^^^^^ :M: Jens Wiklander @@ -287,16 +294,6 @@ Texas Instruments platform port :F: docs/plat/ti-k3.rst :F: plat/ti/ -TLK/Trusty secure payloads -^^^^^^^^^^^^^^^^^^^^^^^^^^ -:M: Varun Wadekar -:G: `vwadekar`_ -:F: docs/components/spd/tlk-dispatcher.rst -:F: docs/components/spd/trusty-dispatcher.rst -:F: include/bl32/payloads/tlk.h -:F: services/spd/tlkd/ -:F: services/spd/trusty/ - UniPhier platform port ^^^^^^^^^^^^^^^^^^^^^^ :M: Masahiro Yamada @@ -311,6 +308,28 @@ Xilinx platform port :F: docs/plat/xilinx-zynqmp.rst :F: plat/xilinx/ + +Secure Payload Dispatchers +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +OP-TEE dispatcher +^^^^^^^^^^^^^^^^^ +:M: Jens Wiklander +:G: `jenswi-linaro`_ +:F: docs/components/spd/optee-dispatcher.rst +:F: services/spd/opteed/ + +TLK/Trusty secure payloads +^^^^^^^^^^^^^^^^^^^^^^^^^^ +:M: Varun Wadekar +:G: `vwadekar`_ +:F: docs/components/spd/tlk-dispatcher.rst +:F: docs/components/spd/trusty-dispatcher.rst +:F: include/bl32/payloads/tlk.h +:F: services/spd/tlkd/ +:F: services/spd/trusty/ + + .. _AlexeiFedorov: https://github.com/AlexeiFedorov .. _Andre-ARM: https://github.com/Andre-ARM .. _Anson-Huang: https://github.com/Anson-Huang -- cgit v1.2.3 From 45aecff003e7055b3990076ef774dd78ce86e6d1 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Tue, 28 Apr 2020 04:53:32 +0100 Subject: Implement workaround for AT speculative behaviour During context switching from higher EL (EL2 or higher) to lower EL can cause incorrect translation in TLB due to speculative execution of AT instruction using out-of-context translation regime. Workaround is implemented as below during EL's (EL1 or EL2) "context_restore" operation: 1. Disable page table walk using SCTLR.M and TCR.EPD0 & EPD1 bits for EL1 or EL2 (stage1 and stage2 disabled) 2. Save all system registers except TCR and SCTLR (for EL1 and EL2) 3. Do memory barrier operation (isb) to ensure all system register writes are done. 4. Restore TCR and SCTLR registers (for EL1 and EL2) Errata details are available for various CPUs as below: Cortex-A76: 1165522 Cortex-A72: 1319367 Cortex-A57: 1319537 Cortex-A55: 1530923 Cortex-A53: 1530924 More details can be found in mail-chain: https://lists.trustedfirmware.org/pipermail/tf-a/2020-April/000445.html Currently, Workaround is implemented as build option which is default disabled. Signed-off-by: Manish V Badarkhe Change-Id: If8545e61f782cb0c2dda7ffbaf50681c825bd2f0 --- Makefile | 2 + docs/getting_started/build-options.rst | 23 ++++++++++++ include/arch/aarch64/arch.h | 1 + lib/el3_runtime/aarch64/context.S | 68 +++++++++++++++++++++++++++++----- make_helpers/defaults.mk | 3 ++ 5 files changed, 87 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index 5c4f36c4f..997236269 100644 --- a/Makefile +++ b/Makefile @@ -891,6 +891,7 @@ $(eval $(call assert_boolean,BL2_INV_DCACHE)) $(eval $(call assert_boolean,USE_SPINLOCK_CAS)) $(eval $(call assert_boolean,ENCRYPT_BL31)) $(eval $(call assert_boolean,ENCRYPT_BL32)) +$(eval $(call assert_boolean,ERRATA_SPECULATIVE_AT)) $(eval $(call assert_numeric,ARM_ARCH_MAJOR)) $(eval $(call assert_numeric,ARM_ARCH_MINOR)) @@ -967,6 +968,7 @@ $(eval $(call add_define,BL2_AT_EL3)) $(eval $(call add_define,BL2_IN_XIP_MEM)) $(eval $(call add_define,BL2_INV_DCACHE)) $(eval $(call add_define,USE_SPINLOCK_CAS)) +$(eval $(call add_define,ERRATA_SPECULATIVE_AT)) ifeq (${SANITIZE_UB},trap) $(eval $(call add_define,MONITOR_TRAPS)) diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 90fe83feb..6f3b605a8 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -673,6 +673,29 @@ Common build options default value of this flag is ``no``. Note this option must be enabled only for ARM architecture greater than Armv8.5-A. +- ``ERRATA_SPECULATIVE_AT``: This flag enables/disables page table walk during + context restore as speculative AT instructions using an out-of-context + translation regime could cause subsequent requests to generate an incorrect + translation. + System registers are not updated during context save, hence this workaround + need not be applied in the context save path. + + This boolean option enables errata for all below CPUs. + + +---------+--------------+ + | Errata | CPU | + +=========+==============+ + | 1165522 | Cortex-A76 | + +---------+--------------+ + | 1319367 | Cortex-A72 | + +---------+--------------+ + | 1319537 | Cortex-A57 | + +---------+--------------+ + | 1530923 | Cortex-A55 | + +---------+--------------+ + | 1530924 | Cortex-A53 | + +---------+--------------+ + GICv3 driver options -------------------- diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index e45a594c5..81e0f271e 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -381,6 +381,7 @@ /* HCR definitions */ #define HCR_API_BIT (ULL(1) << 41) #define HCR_APK_BIT (ULL(1) << 40) +#define HCR_E2H_BIT (ULL(1) << 34) #define HCR_TGE_BIT (ULL(1) << 27) #define HCR_RW_SHIFT U(31) #define HCR_RW_BIT (ULL(1) << HCR_RW_SHIFT) diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S index 221f33e06..984468a53 100644 --- a/lib/el3_runtime/aarch64/context.S +++ b/lib/el3_runtime/aarch64/context.S @@ -234,6 +234,21 @@ endfunc el2_sysregs_context_save */ func el2_sysregs_context_restore +#if ERRATA_SPECULATIVE_AT +/* Clear EPD0 and EPD1 bit and M bit to disable PTW */ + mrs x9, hcr_el2 + tst x9, #HCR_E2H_BIT + bne 1f + mrs x9, tcr_el2 + orr x9, x9, #TCR_EPD0_BIT + orr x9, x9, #TCR_EPD1_BIT + msr tcr_el2, x9 +1: mrs x9, sctlr_el2 + bic x9, x9, #SCTLR_M_BIT + msr sctlr_el2, x9 + isb +#endif + ldp x9, x10, [x0, #CTX_ACTLR_EL2] msr actlr_el2, x9 msr afsr0_el2, x10 @@ -282,17 +297,15 @@ func el2_sysregs_context_restore msr mair_el2, x15 msr mdcr_el2, x16 - ldp x17, x9, [x0, #CTX_PMSCR_EL2] + ldr x17, [x0, #CTX_PMSCR_EL2] msr PMSCR_EL2, x17 - msr sctlr_el2, x9 ldp x10, x11, [x0, #CTX_SPSR_EL2] msr spsr_el2, x10 msr sp_el2, x11 - ldp x12, x13, [x0, #CTX_TCR_EL2] - msr tcr_el2, x12 - msr tpidr_el2, x13 + ldr x12, [x0, #CTX_TPIDR_EL2] + msr tpidr_el2, x12 ldp x14, x15, [x0, #CTX_TTBR0_EL2] msr ttbr0_el2, x14 @@ -404,6 +417,19 @@ func el2_sysregs_context_restore msr scxtnum_el2, x9 #endif +#if ERRATA_SPECULATIVE_AT +/* + * Make sure all registers are stored successfully except + * SCTLR_EL2 and TCR_EL2 + */ + isb +#endif + + ldr x9, [x0, #CTX_SCTLR_EL2] + msr sctlr_el2, x9 + ldr x9, [x0, #CTX_TCR_EL2] + msr tcr_el2, x9 + ret endfunc el2_sysregs_context_restore @@ -515,12 +541,22 @@ endfunc el1_sysregs_context_save */ func el1_sysregs_context_restore +#if ERRATA_SPECULATIVE_AT + mrs x9, tcr_el1 + orr x9, x9, #TCR_EPD0_BIT + orr x9, x9, #TCR_EPD1_BIT + msr tcr_el1, x9 + mrs x9, sctlr_el1 + bic x9, x9, #SCTLR_M_BIT + msr sctlr_el1, x9 + isb +#endif + ldp x9, x10, [x0, #CTX_SPSR_EL1] msr spsr_el1, x9 msr elr_el1, x10 - ldp x15, x16, [x0, #CTX_SCTLR_EL1] - msr sctlr_el1, x15 + ldr x16, [x0, #CTX_ACTLR_EL1] msr actlr_el1, x16 ldp x17, x9, [x0, #CTX_CPACR_EL1] @@ -539,9 +575,8 @@ func el1_sysregs_context_restore msr mair_el1, x14 msr amair_el1, x15 - ldp x16, x17, [x0, #CTX_TCR_EL1] - msr tcr_el1, x16 - msr tpidr_el1, x17 + ldr x16,[x0, #CTX_TPIDR_EL1] + msr tpidr_el1, x16 ldp x9, x10, [x0, #CTX_TPIDR_EL0] msr tpidr_el0, x9 @@ -597,6 +632,19 @@ func el1_sysregs_context_restore msr GCR_EL1, x14 #endif +#if ERRATA_SPECULATIVE_AT +/* + * Make sure all registers are stored successfully except + * SCTLR_EL1 and TCR_EL1 + */ + isb +#endif + + ldr x9, [x0, #CTX_SCTLR_EL1] + msr sctlr_el1, x9 + ldr x9, [x0, #CTX_TCR_EL1] + msr tcr_el1, x9 + /* No explict ISB required here as ERET covers it */ ret endfunc el1_sysregs_context_restore diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index 590a800a6..608e96349 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -293,3 +293,6 @@ CTX_INCLUDE_EL2_REGS := 0 # than Armv8.5-A # By default it is set to "no" SUPPORT_STACK_MEMTAG := no + +# Select workaround for AT speculative behaviour. +ERRATA_SPECULATIVE_AT := 0 -- cgit v1.2.3 From cbf9e84a193883f11a99b2f61417710a69e36e0d Mon Sep 17 00:00:00 2001 From: Balint Dobszay Date: Wed, 18 Dec 2019 15:28:00 +0100 Subject: plat/arm/fvp: Support performing SDEI platform setup in runtime This patch introduces dynamic configuration for SDEI setup and is supported when the new build flag SDEI_IN_FCONF is enabled. Instead of using C arrays and processing the configuration at compile time, the config is moved to dts files. It will be retrieved at runtime during SDEI init, using the fconf layer. Change-Id: If5c35a7517ba00a9f258d7f3e7c8c20cee169a31 Signed-off-by: Balint Dobszay Co-authored-by: Madhukar Pappireddy --- Makefile | 8 +++ docs/getting_started/build-options.rst | 5 ++ fdts/fvp-base-gicv3-psci-common.dtsi | 26 +++++++ include/plat/arm/common/arm_def.h | 8 +++ include/plat/arm/common/fconf_sdei_getter.h | 31 +++++++++ include/plat/common/platform.h | 1 + include/services/sdei.h | 47 +------------ include/services/sdei_flags.h | 56 +++++++++++++++ make_helpers/defaults.mk | 5 +- plat/arm/board/fvp/include/platform_def.h | 5 ++ plat/arm/common/aarch64/arm_sdei.c | 47 ++++++++++++- plat/arm/common/arm_common.mk | 3 + plat/arm/common/fconf/fconf_sdei_getter.c | 103 ++++++++++++++++++++++++++++ services/std_svc/sdei/sdei_main.c | 10 ++- 14 files changed, 303 insertions(+), 52 deletions(-) create mode 100644 include/plat/arm/common/fconf_sdei_getter.h create mode 100644 include/services/sdei_flags.h create mode 100644 plat/arm/common/fconf/fconf_sdei_getter.c diff --git a/Makefile b/Makefile index 997236269..2f53cdf1b 100644 --- a/Makefile +++ b/Makefile @@ -651,6 +651,12 @@ ifeq ($(DYN_DISABLE_AUTH), 1) endif 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 + # If pointer authentication is used in the firmware, make sure that all the # registers associated to it are also saved and restored. # Not doing it would leak the value of the keys used by EL3 to EL1 and S-EL1. @@ -882,6 +888,7 @@ $(eval $(call assert_boolean,TRUSTED_BOARD_BOOT)) $(eval $(call assert_boolean,USE_COHERENT_MEM)) $(eval $(call assert_boolean,USE_DEBUGFS)) $(eval $(call assert_boolean,ARM_IO_IN_DTB)) +$(eval $(call assert_boolean,SDEI_IN_FCONF)) $(eval $(call assert_boolean,USE_ROMLIB)) $(eval $(call assert_boolean,USE_TBBR_DEFS)) $(eval $(call assert_boolean,WARMBOOT_ENABLE_DCACHE_EARLY)) @@ -961,6 +968,7 @@ $(eval $(call add_define,TRUSTED_BOARD_BOOT)) $(eval $(call add_define,USE_COHERENT_MEM)) $(eval $(call add_define,USE_DEBUGFS)) $(eval $(call add_define,ARM_IO_IN_DTB)) +$(eval $(call add_define,SDEI_IN_FCONF)) $(eval $(call add_define,USE_ROMLIB)) $(eval $(call add_define,USE_TBBR_DEFS)) $(eval $(call add_define,WARMBOOT_ENABLE_DCACHE_EARLY)) diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 6f3b605a8..c86307948 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -645,6 +645,11 @@ Common build options configuration device tree, instead of static structure in the code base. This is currently an experimental feature. +- ``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. - ``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/fdts/fvp-base-gicv3-psci-common.dtsi b/fdts/fvp-base-gicv3-psci-common.dtsi index fb73f6053..4a7b65658 100644 --- a/fdts/fvp-base-gicv3-psci-common.dtsi +++ b/fdts/fvp-base-gicv3-psci-common.dtsi @@ -4,6 +4,8 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include + /memreserve/ 0x80000000 0x00010000; / { @@ -36,6 +38,30 @@ max-pwr-lvl = <2>; }; +#if SDEI_IN_FCONF + firmware { + sdei { + compatible = "arm,sdei-1.0"; + method = "smc"; + private_event_count = <3>; + shared_event_count = <3>; + /* + * Each event descriptor has typically 3 fields: + * 1. Event number + * 2. Interrupt number the event is bound to or + * if event is dynamic, specified as SDEI_DYN_IRQ + * 3. Bit map of event flags + */ + private_events = <1000 SDEI_DYN_IRQ SDEI_MAPF_DYNAMIC>, + <1001 SDEI_DYN_IRQ SDEI_MAPF_DYNAMIC>, + <1002 SDEI_DYN_IRQ SDEI_MAPF_DYNAMIC>; + shared_events = <2000 SDEI_DYN_IRQ SDEI_MAPF_DYNAMIC>, + <2001 SDEI_DYN_IRQ SDEI_MAPF_DYNAMIC>, + <2002 SDEI_DYN_IRQ SDEI_MAPF_DYNAMIC>; + }; + }; +#endif /* SDEI_IN_FCONF */ + cpus { #address-cells = <2>; #size-cells = <0>; diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index 7c852e19f..89f7c6146 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -565,6 +565,13 @@ /* SGI used for SDEI signalling */ #define ARM_SDEI_SGI ARM_IRQ_SEC_SGI_0 +#if SDEI_IN_FCONF +/* ARM SDEI dynamic private event max count */ +#define ARM_SDEI_DP_EVENT_MAX_CNT 3 + +/* ARM SDEI dynamic shared event max count */ +#define ARM_SDEI_DS_EVENT_MAX_CNT 3 +#else /* ARM SDEI dynamic private event numbers */ #define ARM_SDEI_DP_EVENT_0 1000 #define ARM_SDEI_DP_EVENT_1 1001 @@ -585,5 +592,6 @@ SDEI_SHARED_EVENT(ARM_SDEI_DS_EVENT_0, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC), \ SDEI_SHARED_EVENT(ARM_SDEI_DS_EVENT_1, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC), \ SDEI_SHARED_EVENT(ARM_SDEI_DS_EVENT_2, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC) +#endif /* SDEI_IN_FCONF */ #endif /* ARM_DEF_H */ diff --git a/include/plat/arm/common/fconf_sdei_getter.h b/include/plat/arm/common/fconf_sdei_getter.h new file mode 100644 index 000000000..e0a97a6fb --- /dev/null +++ b/include/plat/arm/common/fconf_sdei_getter.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FCONF_SDEI_GETTER_H +#define FCONF_SDEI_GETTER_H + +#include + +#include + +#define sdei__dyn_config_getter(id) sdei_dyn_config.id + +struct sdei_dyn_config_t { + uint32_t private_ev_cnt; + int32_t private_ev_nums[PLAT_SDEI_DP_EVENT_MAX_CNT]; + unsigned int private_ev_intrs[PLAT_SDEI_DP_EVENT_MAX_CNT]; + unsigned int private_ev_flags[PLAT_SDEI_DP_EVENT_MAX_CNT]; + uint32_t shared_ev_cnt; + int32_t shared_ev_nums[PLAT_SDEI_DS_EVENT_MAX_CNT]; + unsigned int shared_ev_intrs[PLAT_SDEI_DS_EVENT_MAX_CNT]; + unsigned int shared_ev_flags[PLAT_SDEI_DS_EVENT_MAX_CNT]; +}; + +int fconf_populate_sdei_dyn_config(uintptr_t config); + +extern struct sdei_dyn_config_t sdei_dyn_config; + +#endif /* FCONF_SDEI_GETTER_H */ diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h index b8ba14c57..720c259b8 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.h @@ -132,6 +132,7 @@ struct meminfo *bl1_plat_sec_mem_layout(void); /* SDEI platform functions */ #if SDEI_SUPPORT +void plat_sdei_setup(void); int plat_sdei_validate_entry_point(uintptr_t ep, unsigned int client_mode); void plat_sdei_handle_masked_trigger(uint64_t mpidr, unsigned int intr); #endif diff --git a/include/services/sdei.h b/include/services/sdei.h index ae8c7e42f..063ed6f28 100644 --- a/include/services/sdei.h +++ b/include/services/sdei.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,6 +9,7 @@ #include #include +#include /* Range 0xC4000020 - 0xC400003F reserved for SDE 64bit smc calls */ #define SDEI_VERSION 0xC4000020U @@ -41,50 +42,6 @@ #define SDEI_EV_HANDLED 0U #define SDEI_EV_FAILED 1U -/* Internal: SDEI flag bit positions */ -#define SDEI_MAPF_DYNAMIC_SHIFT_ 1U -#define SDEI_MAPF_BOUND_SHIFT_ 2U -#define SDEI_MAPF_SIGNALABLE_SHIFT_ 3U -#define SDEI_MAPF_PRIVATE_SHIFT_ 4U -#define SDEI_MAPF_CRITICAL_SHIFT_ 5U -#define SDEI_MAPF_EXPLICIT_SHIFT_ 6U - -/* SDEI event 0 */ -#define SDEI_EVENT_0 0 - -/* Placeholder interrupt for dynamic mapping */ -#define SDEI_DYN_IRQ 0U - -/* SDEI flags */ - -/* - * These flags determine whether or not an event can be associated with an - * interrupt. Static events are permanently associated with an interrupt, and - * can't be changed at runtime. Association of dynamic events with interrupts - * can be changed at run time using the SDEI_INTERRUPT_BIND and - * SDEI_INTERRUPT_RELEASE calls. - * - * SDEI_MAPF_DYNAMIC only indicates run time configurability, where as - * SDEI_MAPF_BOUND indicates interrupt association. For example: - * - * - Calling SDEI_INTERRUPT_BIND on a dynamic event will have both - * SDEI_MAPF_DYNAMIC and SDEI_MAPF_BOUND set. - * - * - Statically-bound events will always have SDEI_MAPF_BOUND set, and neither - * SDEI_INTERRUPT_BIND nor SDEI_INTERRUPT_RELEASE can be called on them. - * - * See also the is_map_bound() macro. - */ -#define SDEI_MAPF_DYNAMIC BIT(SDEI_MAPF_DYNAMIC_SHIFT_) -#define SDEI_MAPF_BOUND BIT(SDEI_MAPF_BOUND_SHIFT_) -#define SDEI_MAPF_EXPLICIT BIT(SDEI_MAPF_EXPLICIT_SHIFT_) - -#define SDEI_MAPF_SIGNALABLE BIT(SDEI_MAPF_SIGNALABLE_SHIFT_) -#define SDEI_MAPF_PRIVATE BIT(SDEI_MAPF_PRIVATE_SHIFT_) - -#define SDEI_MAPF_NORMAL 0 -#define SDEI_MAPF_CRITICAL BIT(SDEI_MAPF_CRITICAL_SHIFT_) - /* Indices of private and shared mappings */ #define SDEI_MAP_IDX_PRIV_ 0U #define SDEI_MAP_IDX_SHRD_ 1U diff --git a/include/services/sdei_flags.h b/include/services/sdei_flags.h new file mode 100644 index 000000000..d1308f82a --- /dev/null +++ b/include/services/sdei_flags.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SDEI_FLAGS_H +#define SDEI_FLAGS_H + +#include + +/* Internal: SDEI flag bit positions */ +#define SDEI_MAPF_DYNAMIC_SHIFT_ 1U +#define SDEI_MAPF_BOUND_SHIFT_ 2U +#define SDEI_MAPF_SIGNALABLE_SHIFT_ 3U +#define SDEI_MAPF_PRIVATE_SHIFT_ 4U +#define SDEI_MAPF_CRITICAL_SHIFT_ 5U +#define SDEI_MAPF_EXPLICIT_SHIFT_ 6U + +/* SDEI event 0 */ +#define SDEI_EVENT_0 0 + +/* Placeholder interrupt for dynamic mapping */ +#define SDEI_DYN_IRQ 0U + +/* SDEI flags */ + +/* + * These flags determine whether or not an event can be associated with an + * interrupt. Static events are permanently associated with an interrupt, and + * can't be changed at runtime. Association of dynamic events with interrupts + * can be changed at run time using the SDEI_INTERRUPT_BIND and + * SDEI_INTERRUPT_RELEASE calls. + * + * SDEI_MAPF_DYNAMIC only indicates run time configurability, where as + * SDEI_MAPF_BOUND indicates interrupt association. For example: + * + * - Calling SDEI_INTERRUPT_BIND on a dynamic event will have both + * SDEI_MAPF_DYNAMIC and SDEI_MAPF_BOUND set. + * + * - Statically-bound events will always have SDEI_MAPF_BOUND set, and neither + * SDEI_INTERRUPT_BIND nor SDEI_INTERRUPT_RELEASE can be called on them. + * + * See also the is_map_bound() macro. + */ +#define SDEI_MAPF_DYNAMIC BIT(SDEI_MAPF_DYNAMIC_SHIFT_) +#define SDEI_MAPF_BOUND BIT(SDEI_MAPF_BOUND_SHIFT_) +#define SDEI_MAPF_EXPLICIT BIT(SDEI_MAPF_EXPLICIT_SHIFT_) + +#define SDEI_MAPF_SIGNALABLE BIT(SDEI_MAPF_SIGNALABLE_SHIFT_) +#define SDEI_MAPF_PRIVATE BIT(SDEI_MAPF_PRIVATE_SHIFT_) + +#define SDEI_MAPF_NORMAL 0 +#define SDEI_MAPF_CRITICAL BIT(SDEI_MAPF_CRITICAL_SHIFT_) + +#endif /* SDEI_FLAGS_H */ diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index 608e96349..e5880d206 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -223,7 +223,10 @@ USE_COHERENT_MEM := 1 USE_DEBUGFS := 0 # Build option to fconf based io -ARM_IO_IN_DTB := 0 +ARM_IO_IN_DTB := 0 + +# Build option to support SDEI through fconf +SDEI_IN_FCONF :=0 # Build option to choose whether Trusted Firmware uses library at ROM USE_ROMLIB := 0 diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h index 1ed307429..62ede9ab8 100644 --- a/plat/arm/board/fvp/include/platform_def.h +++ b/plat/arm/board/fvp/include/platform_def.h @@ -264,8 +264,13 @@ #define PLAT_ARM_G0_IRQ_PROPS(grp) ARM_G0_IRQ_PROPS(grp) +#if SDEI_IN_FCONF +#define PLAT_SDEI_DP_EVENT_MAX_CNT ARM_SDEI_DP_EVENT_MAX_CNT +#define PLAT_SDEI_DS_EVENT_MAX_CNT ARM_SDEI_DS_EVENT_MAX_CNT +#else #define PLAT_ARM_PRIVATE_SDEI_EVENTS ARM_SDEI_PRIVATE_EVENTS #define PLAT_ARM_SHARED_SDEI_EVENTS ARM_SDEI_SHARED_EVENTS +#endif #define PLAT_ARM_SP_IMAGE_STACK_BASE (PLAT_SP_IMAGE_NS_BUF_BASE + \ PLAT_SP_IMAGE_NS_BUF_SIZE) diff --git a/plat/arm/common/aarch64/arm_sdei.c b/plat/arm/common/aarch64/arm_sdei.c index 493134b6a..3c74a465c 100644 --- a/plat/arm/common/aarch64/arm_sdei.c +++ b/plat/arm/common/aarch64/arm_sdei.c @@ -1,16 +1,51 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /* SDEI configuration for ARM platforms */ -#include - #include +#include #include +#if SDEI_IN_FCONF +#include +#endif +#include +#include + + +#if SDEI_IN_FCONF +/* Private event mappings */ +static sdei_ev_map_t arm_sdei_private[PLAT_SDEI_DP_EVENT_MAX_CNT + 1] = { 0 }; + +/* Shared event mappings */ +static sdei_ev_map_t arm_sdei_shared[PLAT_SDEI_DS_EVENT_MAX_CNT] = { 0 }; + +void plat_sdei_setup(void) +{ + uint32_t i; + + arm_sdei_private[0] = (sdei_ev_map_t)SDEI_DEFINE_EVENT_0(ARM_SDEI_SGI); + + for (i = 0; i < FCONF_GET_PROPERTY(sdei, dyn_config, private_ev_cnt); i++) { + arm_sdei_private[i + 1] = (sdei_ev_map_t)SDEI_PRIVATE_EVENT( + FCONF_GET_PROPERTY(sdei, dyn_config, private_ev_nums[i]), + FCONF_GET_PROPERTY(sdei, dyn_config, private_ev_intrs[i]), + FCONF_GET_PROPERTY(sdei, dyn_config, private_ev_flags[i])); + } + + for (i = 0; i < FCONF_GET_PROPERTY(sdei, dyn_config, shared_ev_cnt); i++) { + arm_sdei_shared[i] = (sdei_ev_map_t)SDEI_SHARED_EVENT( \ + FCONF_GET_PROPERTY(sdei, dyn_config, shared_ev_nums[i]), + FCONF_GET_PROPERTY(sdei, dyn_config, shared_ev_intrs[i]), + FCONF_GET_PROPERTY(sdei, dyn_config, shared_ev_flags[i])); + } + INFO("FCONF: SDEI platform setup\n"); +} +#else /* Private event mappings */ static sdei_ev_map_t arm_sdei_private[] = { PLAT_ARM_PRIVATE_SDEI_EVENTS @@ -21,5 +56,11 @@ static sdei_ev_map_t arm_sdei_shared[] = { PLAT_ARM_SHARED_SDEI_EVENTS }; +void plat_sdei_setup(void) +{ + INFO("SDEI platform setup\n"); +} +#endif /* SDEI_IN_FCONF */ + /* Export ARM SDEI events */ REGISTER_SDEI_MAP(arm_sdei_private, arm_sdei_shared); diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index 3b0c39d4b..387c131e1 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -263,6 +263,9 @@ endif ifeq (${SDEI_SUPPORT},1) BL31_SOURCES += plat/arm/common/aarch64/arm_sdei.c +ifeq (${SDEI_IN_FCONF},1) +BL31_SOURCES += plat/arm/common/fconf/fconf_sdei_getter.c +endif endif # RAS sources diff --git a/plat/arm/common/fconf/fconf_sdei_getter.c b/plat/arm/common/fconf/fconf_sdei_getter.c new file mode 100644 index 000000000..c26e316a5 --- /dev/null +++ b/plat/arm/common/fconf/fconf_sdei_getter.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include + +#include +#include +#include +#include + +#define PRIVATE_EVENT_NUM(i) private_events[3 * (i)] +#define PRIVATE_EVENT_INTR(i) private_events[3 * (i) + 1] +#define PRIVATE_EVENT_FLAGS(i) private_events[3 * (i) + 2] + +#define SHARED_EVENT_NUM(i) shared_events[3 * (i)] +#define SHARED_EVENT_INTR(i) shared_events[3 * (i) + 1] +#define SHARED_EVENT_FLAGS(i) shared_events[3 * (i) + 2] + +struct sdei_dyn_config_t sdei_dyn_config; + +int fconf_populate_sdei_dyn_config(uintptr_t config) +{ + uint32_t i; + int node, err; + uint32_t private_events[PLAT_SDEI_DP_EVENT_MAX_CNT * 3]; + uint32_t shared_events[PLAT_SDEI_DS_EVENT_MAX_CNT * 3]; + + const void *dtb = (void *)config; + + /* Check that the node offset points to compatible property */ + node = fdt_node_offset_by_compatible(dtb, -1, "arm,sdei-1.0"); + if (node < 0) { + ERROR("FCONF: Can't find 'arm,sdei-1.0' compatible node in dtb\n"); + return node; + } + + /* Read number of private mappings */ + err = fdt_read_uint32(dtb, node, "private_event_count", + &sdei_dyn_config.private_ev_cnt); + if (err < 0) { + ERROR("FCONF: Read cell failed for 'private_event_count': %u\n", + sdei_dyn_config.private_ev_cnt); + return err; + } + + /* Check if the value is in range */ + if (sdei_dyn_config.private_ev_cnt > PLAT_SDEI_DP_EVENT_MAX_CNT) { + ERROR("FCONF: Invalid value for 'private_event_count': %u\n", + sdei_dyn_config.private_ev_cnt); + return -1; + } + + /* Read private mappings */ + err = fdt_read_uint32_array(dtb, node, "private_events", + sdei_dyn_config.private_ev_cnt * 3, private_events); + if (err < 0) { + ERROR("FCONF: Read cell failed for 'private_events': %d\n", err); + return err; + } + + /* Move data to fconf struct */ + for (i = 0; i < sdei_dyn_config.private_ev_cnt; i++) { + sdei_dyn_config.private_ev_nums[i] = PRIVATE_EVENT_NUM(i); + sdei_dyn_config.private_ev_intrs[i] = PRIVATE_EVENT_INTR(i); + sdei_dyn_config.private_ev_flags[i] = PRIVATE_EVENT_FLAGS(i); + } + + /* Read number of shared mappings */ + err = fdt_read_uint32(dtb, node, "shared_event_count", + &sdei_dyn_config.shared_ev_cnt); + if (err < 0) { + ERROR("FCONF: Read cell failed for 'shared_event_count'\n"); + return err; + } + + /* Check if the value is in range */ + if (sdei_dyn_config.shared_ev_cnt > PLAT_SDEI_DS_EVENT_MAX_CNT) { + ERROR("FCONF: Invalid value for 'shared_event_count': %u\n", + sdei_dyn_config.shared_ev_cnt); + return -1; + } + + /* Read shared mappings */ + err = fdt_read_uint32_array(dtb, node, "shared_events", + sdei_dyn_config.shared_ev_cnt * 3, shared_events); + if (err < 0) { + ERROR("FCONF: Read cell failed for 'shared_events': %d\n", err); + return err; + } + + /* Move data to fconf struct */ + for (i = 0; i < sdei_dyn_config.shared_ev_cnt; i++) { + sdei_dyn_config.shared_ev_nums[i] = SHARED_EVENT_NUM(i); + sdei_dyn_config.shared_ev_intrs[i] = SHARED_EVENT_INTR(i); + sdei_dyn_config.shared_ev_flags[i] = SHARED_EVENT_FLAGS(i); + } + + return 0; +} + +FCONF_REGISTER_POPULATOR(HW_CONFIG, sdei, fconf_populate_sdei_dyn_config); diff --git a/services/std_svc/sdei/sdei_main.c b/services/std_svc/sdei/sdei_main.c index 042417764..dba5e07ff 100644 --- a/services/std_svc/sdei/sdei_main.c +++ b/services/std_svc/sdei/sdei_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -226,6 +226,7 @@ static void sdei_class_init(sdei_class_t class) /* SDEI dispatcher initialisation */ void sdei_init(void) { + plat_sdei_setup(); sdei_class_init(SDEI_CRITICAL); sdei_class_init(SDEI_NORMAL); @@ -328,8 +329,11 @@ finish: } /* Register handler and argument for an SDEI event */ -static int64_t sdei_event_register(int ev_num, uint64_t ep, uint64_t arg, - uint64_t flags, uint64_t mpidr) +static int64_t sdei_event_register(int ev_num, + uint64_t ep, + uint64_t arg, + uint64_t flags, + uint64_t mpidr) { int ret; unsigned int routing; -- cgit v1.2.3 From 1a04b2e536c2d9512188d6cd730cf4d5d84e8dcd Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Sat, 16 May 2020 20:59:30 -0700 Subject: Fix compilation error when ENABLE_PIE=1 This patch fixes compilation errors when ENABLE_PIE=1. bl31/aarch64/bl31_entrypoint.S: Assembler messages: bl31/aarch64/bl31_entrypoint.S:61: Error: invalid operand (*UND* section) for `~' bl31/aarch64/bl31_entrypoint.S:61: Error: invalid immediate Makefile:1079: recipe for target 'build/tegra/t194/debug/bl31/bl31_entrypoint.o' failed Verified by setting 'ENABLE_PIE=1' for Tegra platform builds. Signed-off-by: Varun Wadekar Change-Id: Ifd184f89b86b4360fda86a6ce83fd8495f930bbc --- include/arch/aarch64/el3_common_macros.S | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S index 156b18a4f..0708de689 100644 --- a/include/arch/aarch64/el3_common_macros.S +++ b/include/arch/aarch64/el3_common_macros.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,6 +9,7 @@ #include #include +#include /* * Helper macro to initialise EL3 registers we care about. -- cgit v1.2.3 From 359acf7746e70e7e0ceddc75de08c59c167e2ab6 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Sat, 16 May 2020 22:10:09 -0700 Subject: Tegra: enable stack protection This patch sets ENABLE_STACK_PROTECTOR=strong and implements the platform support to generate a stack protection canary value. Signed-off-by: Varun Wadekar Change-Id: Ia8afe464b5645917b1c77d49305d19c7cd01866a --- plat/nvidia/tegra/common/tegra_common.mk | 5 +++++ plat/nvidia/tegra/common/tegra_stack_protector.c | 28 ++++++++++++++++++++++++ plat/nvidia/tegra/platform.mk | 3 +++ 3 files changed, 36 insertions(+) create mode 100644 plat/nvidia/tegra/common/tegra_stack_protector.c diff --git a/plat/nvidia/tegra/common/tegra_common.mk b/plat/nvidia/tegra/common/tegra_common.mk index c946a7597..79cc03ac9 100644 --- a/plat/nvidia/tegra/common/tegra_common.mk +++ b/plat/nvidia/tegra/common/tegra_common.mk @@ -1,5 +1,6 @@ # # Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2020, NVIDIA Corporation. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -32,3 +33,7 @@ BL31_SOURCES += drivers/delay_timer/delay_timer.c \ ${COMMON_DIR}/tegra_platform.c \ ${COMMON_DIR}/tegra_pm.c \ ${COMMON_DIR}/tegra_sip_calls.c + +ifneq ($(ENABLE_STACK_PROTECTOR), 0) +BL31_SOURCES += ${COMMON_DIR}/tegra_stack_protector.c +endif diff --git a/plat/nvidia/tegra/common/tegra_stack_protector.c b/plat/nvidia/tegra/common/tegra_stack_protector.c new file mode 100644 index 000000000..f6c459a8e --- /dev/null +++ b/plat/nvidia/tegra/common/tegra_stack_protector.c @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include + +u_register_t plat_get_stack_protector_canary(void) +{ + u_register_t seed; + + /* + * Ideally, a random number should be returned instead. As the + * platform does not have any random number generator, this is + * better than nothing, but not really secure. + */ + seed = mmio_read_32(TEGRA_MISC_BASE + HARDWARE_REVISION_OFFSET); + seed <<= 32; + seed |= mmio_read_32(TEGRA_TMRUS_BASE); + + return seed ^ read_cntpct_el0(); +} diff --git a/plat/nvidia/tegra/platform.mk b/plat/nvidia/tegra/platform.mk index e03e1f37b..aedd3c6ff 100644 --- a/plat/nvidia/tegra/platform.mk +++ b/plat/nvidia/tegra/platform.mk @@ -49,6 +49,9 @@ ENABLE_TEGRA_WDT_LEGACY_FIQ_HANDLING ?= 0 # Flag to allow relocation of BL32 image to TZDRAM during boot RELOCATE_BL32_IMAGE ?= 0 +# Enable stack protection +ENABLE_STACK_PROTECTOR := strong + include plat/nvidia/tegra/common/tegra_common.mk include ${SOC_DIR}/platform_${TARGET_SOC}.mk -- cgit v1.2.3 From ad43c49ee39f52d2f3e682aefd76ecbbe3e0c712 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Sat, 16 May 2020 16:36:39 +0100 Subject: Cleanup the code for TBBR CoT descriptors CoT used for BL1 and BL2 are moved to tbbr_cot_bl1.c and tbbr_cot_bl2.c respectively. Common CoT used across BL1 and BL2 are moved to tbbr_cot_common.c. Signed-off-by: Manish V Badarkhe Change-Id: I2252ac8a6960b3431bcaafdb3ea4fb2d01b79cf5 --- docs/design/auth-framework.rst | 14 +- drivers/auth/dualroot/cot.c | 38 -- drivers/auth/tbbr/tbbr_cot.c | 855 --------------------------------- drivers/auth/tbbr/tbbr_cot_bl1.c | 168 +++++++ drivers/auth/tbbr/tbbr_cot_bl2.c | 563 ++++++++++++++++++++++ drivers/auth/tbbr/tbbr_cot_common.c | 116 +++++ include/common/tbbr/cot_def.h | 36 +- include/drivers/auth/tbbr_cot_common.h | 31 ++ plat/arm/common/arm_common.mk | 6 +- plat/brcm/board/common/board_common.mk | 3 +- plat/hisilicon/hikey/platform.mk | 10 +- plat/hisilicon/hikey960/platform.mk | 10 +- plat/imx/imx7/common/imx7.mk | 7 +- plat/qemu/qemu/platform.mk | 8 +- plat/rpi/rpi3/platform.mk | 10 +- plat/socionext/uniphier/platform.mk | 3 +- 16 files changed, 956 insertions(+), 922 deletions(-) delete mode 100644 drivers/auth/tbbr/tbbr_cot.c create mode 100644 drivers/auth/tbbr/tbbr_cot_bl1.c create mode 100644 drivers/auth/tbbr/tbbr_cot_bl2.c create mode 100644 drivers/auth/tbbr/tbbr_cot_common.c create mode 100644 include/drivers/auth/tbbr_cot_common.h diff --git a/docs/design/auth-framework.rst b/docs/design/auth-framework.rst index 1a53e2292..6913e66e1 100644 --- a/docs/design/auth-framework.rst +++ b/docs/design/auth-framework.rst @@ -619,11 +619,13 @@ recommended to read this guide along with the source code. The TBBR CoT ~~~~~~~~~~~~ -The CoT can be found in ``drivers/auth/tbbr/tbbr_cot.c``. This CoT consists of -an array of pointers to image descriptors and it is registered in the framework -using the macro ``REGISTER_COT(cot_desc)``, where ``cot_desc`` must be the name -of the array (passing a pointer or any other type of indirection will cause the -registration process to fail). +CoT specific to BL1 and BL2 can be found in ``drivers/auth/tbbr/tbbr_cot_bl1.c`` +and ``drivers/auth/tbbr/tbbr_cot_bl2.c`` respectively. The common CoT used across +BL1 and BL2 can be found in ``drivers/auth/tbbr/tbbr_cot_common.c``. +This CoT consists of an array of pointers to image descriptors and it is +registered in the framework using the macro ``REGISTER_COT(cot_desc)``, where +``cot_desc`` must be the name of the array (passing a pointer or any other +type of indirection will cause the registration process to fail). The number of images participating in the boot process depends on the CoT. There is, however, a minimum set of images that are mandatory in TF-A and thus @@ -702,7 +704,7 @@ Each image descriptor must specify: address/size to store the parameter. The CoT is responsible for allocating the required memory to store the parameters. This pointer may be NULL. -In the ``tbbr_cot.c`` file, a set of buffers are allocated to store the parameters +In the ``tbbr_cot*.c`` file, a set of buffers are allocated to store the parameters extracted from the certificates. In the case of the TBBR CoT, these parameters are hashes and public keys. In DER format, an RSA-4096 public key requires 550 bytes, and a hash requires 51 bytes. Depending on the CoT and the authentication diff --git a/drivers/auth/dualroot/cot.c b/drivers/auth/dualroot/cot.c index eb0b020d7..8aca2be6d 100644 --- a/drivers/auth/dualroot/cot.c +++ b/drivers/auth/dualroot/cot.c @@ -12,44 +12,6 @@ #include #include -/* - * TODO: Remove dependency on mbedTLS. The chain of trust should be agnostic of - * the specific cryptographic library in use. -*/ -/* - * Maximum key and hash sizes (in DER format). - * - * Both RSA and ECDSA keys may be used at the same time. In this case, the key - * buffers must be big enough to hold either. As RSA keys are bigger than ECDSA - * ones for all key sizes we support, they impose the minimum size of these - * buffers. - */ -#if TF_MBEDTLS_USE_RSA -#if TF_MBEDTLS_KEY_SIZE == 1024 -#define PK_DER_LEN 162 -#elif TF_MBEDTLS_KEY_SIZE == 2048 -#define PK_DER_LEN 294 -#elif TF_MBEDTLS_KEY_SIZE == 3072 -#define PK_DER_LEN 422 -#elif TF_MBEDTLS_KEY_SIZE == 4096 -#define PK_DER_LEN 550 -#else -#error "Invalid value for TF_MBEDTLS_KEY_SIZE" -#endif -#else /* Only using ECDSA keys. */ -#define PK_DER_LEN 91 -#endif - -#if TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA256 -#define HASH_DER_LEN 51 -#elif TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA384 -#define HASH_DER_LEN 67 -#elif TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA512 -#define HASH_DER_LEN 83 -#else -#error "Invalid value for TF_MBEDTLS_HASH_ALG_ID" -#endif - /* * Allocate static buffers to store the authentication parameters extracted from * the certificates. diff --git a/drivers/auth/tbbr/tbbr_cot.c b/drivers/auth/tbbr/tbbr_cot.c deleted file mode 100644 index 6f00b180c..000000000 --- a/drivers/auth/tbbr/tbbr_cot.c +++ /dev/null @@ -1,855 +0,0 @@ -/* - * Copyright (c) 2015-2020, 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 - - -/* - * Maximum key and hash sizes (in DER format). - * - * Both RSA and ECDSA keys may be used at the same time. In this case, the key - * buffers must be big enough to hold either. As RSA keys are bigger than ECDSA - * ones for all key sizes we support, they impose the minimum size of these - * buffers. - */ -#if TF_MBEDTLS_USE_RSA -#if TF_MBEDTLS_KEY_SIZE == 1024 -#define PK_DER_LEN 162 -#elif TF_MBEDTLS_KEY_SIZE == 2048 -#define PK_DER_LEN 294 -#elif TF_MBEDTLS_KEY_SIZE == 3072 -#define PK_DER_LEN 422 -#elif TF_MBEDTLS_KEY_SIZE == 4096 -#define PK_DER_LEN 550 -#else -#error "Invalid value for TF_MBEDTLS_KEY_SIZE" -#endif -#else /* Only using ECDSA keys. */ -#define PK_DER_LEN 91 -#endif - -#if TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA256 -#define HASH_DER_LEN 51 -#elif TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA384 -#define HASH_DER_LEN 67 -#elif TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA512 -#define HASH_DER_LEN 83 -#else -#error "Invalid value for TF_MBEDTLS_HASH_ALG_ID" -#endif - -/* - * The platform must allocate buffers to store the authentication parameters - * extracted from the certificates. In this case, because of the way the CoT is - * established, we can reuse some of the buffers on different stages - */ - -static unsigned char tb_fw_hash_buf[HASH_DER_LEN]; -static unsigned char tb_fw_config_hash_buf[HASH_DER_LEN]; -static unsigned char hw_config_hash_buf[HASH_DER_LEN]; -static unsigned char scp_fw_hash_buf[HASH_DER_LEN]; -static unsigned char nt_world_bl_hash_buf[HASH_DER_LEN]; - -#ifdef IMAGE_BL2 -static unsigned char soc_fw_hash_buf[HASH_DER_LEN]; -static unsigned char tos_fw_hash_buf[HASH_DER_LEN]; -static unsigned char tos_fw_extra1_hash_buf[HASH_DER_LEN]; -static unsigned char tos_fw_extra2_hash_buf[HASH_DER_LEN]; -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 soc_fw_config_hash_buf[HASH_DER_LEN]; -static unsigned char tos_fw_config_hash_buf[HASH_DER_LEN]; -static unsigned char nt_fw_config_hash_buf[HASH_DER_LEN]; -#endif - -/* - * Parameter type descriptors - */ -static auth_param_type_desc_t trusted_nv_ctr = AUTH_PARAM_TYPE_DESC( - AUTH_PARAM_NV_CTR, TRUSTED_FW_NVCOUNTER_OID); - -static auth_param_type_desc_t subject_pk = AUTH_PARAM_TYPE_DESC( - AUTH_PARAM_PUB_KEY, 0); -static auth_param_type_desc_t sig = AUTH_PARAM_TYPE_DESC( - AUTH_PARAM_SIG, 0); -static auth_param_type_desc_t sig_alg = AUTH_PARAM_TYPE_DESC( - AUTH_PARAM_SIG_ALG, 0); -static auth_param_type_desc_t raw_data = AUTH_PARAM_TYPE_DESC( - AUTH_PARAM_RAW_DATA, 0); - - -static auth_param_type_desc_t tb_fw_hash = AUTH_PARAM_TYPE_DESC( - AUTH_PARAM_HASH, TRUSTED_BOOT_FW_HASH_OID); -static auth_param_type_desc_t tb_fw_config_hash = AUTH_PARAM_TYPE_DESC( - AUTH_PARAM_HASH, TRUSTED_BOOT_FW_CONFIG_HASH_OID); -static auth_param_type_desc_t hw_config_hash = AUTH_PARAM_TYPE_DESC( - AUTH_PARAM_HASH, HW_CONFIG_HASH_OID); -#ifdef IMAGE_BL1 -static auth_param_type_desc_t scp_bl2u_hash = AUTH_PARAM_TYPE_DESC( - AUTH_PARAM_HASH, SCP_FWU_CFG_HASH_OID); -static auth_param_type_desc_t bl2u_hash = AUTH_PARAM_TYPE_DESC( - AUTH_PARAM_HASH, AP_FWU_CFG_HASH_OID); -static auth_param_type_desc_t ns_bl2u_hash = AUTH_PARAM_TYPE_DESC( - AUTH_PARAM_HASH, FWU_HASH_OID); -#endif /* IMAGE_BL1 */ - -#ifdef IMAGE_BL2 -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 scp_fw_content_pk = AUTH_PARAM_TYPE_DESC( - AUTH_PARAM_PUB_KEY, SCP_FW_CONTENT_CERT_PK_OID); -static auth_param_type_desc_t soc_fw_content_pk = AUTH_PARAM_TYPE_DESC( - AUTH_PARAM_PUB_KEY, SOC_FW_CONTENT_CERT_PK_OID); -static auth_param_type_desc_t tos_fw_content_pk = AUTH_PARAM_TYPE_DESC( - AUTH_PARAM_PUB_KEY, TRUSTED_OS_FW_CONTENT_CERT_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 scp_fw_hash = AUTH_PARAM_TYPE_DESC( - AUTH_PARAM_HASH, SCP_FW_HASH_OID); -static auth_param_type_desc_t soc_fw_hash = AUTH_PARAM_TYPE_DESC( - AUTH_PARAM_HASH, SOC_AP_FW_HASH_OID); -static auth_param_type_desc_t soc_fw_config_hash = AUTH_PARAM_TYPE_DESC( - AUTH_PARAM_HASH, SOC_FW_CONFIG_HASH_OID); -static auth_param_type_desc_t tos_fw_hash = AUTH_PARAM_TYPE_DESC( - AUTH_PARAM_HASH, TRUSTED_OS_FW_HASH_OID); -static auth_param_type_desc_t tos_fw_config_hash = AUTH_PARAM_TYPE_DESC( - AUTH_PARAM_HASH, TRUSTED_OS_FW_CONFIG_HASH_OID); -static auth_param_type_desc_t tos_fw_extra1_hash = AUTH_PARAM_TYPE_DESC( - AUTH_PARAM_HASH, TRUSTED_OS_FW_EXTRA1_HASH_OID); -static auth_param_type_desc_t tos_fw_extra2_hash = AUTH_PARAM_TYPE_DESC( - AUTH_PARAM_HASH, TRUSTED_OS_FW_EXTRA2_HASH_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); - -#endif /* IMAGE_BL2 */ - - - /* - * BL2 - */ -static const auth_img_desc_t trusted_boot_fw_cert = { - .img_id = TRUSTED_BOOT_FW_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 = &tb_fw_hash, - .data = { - .ptr = (void *)tb_fw_hash_buf, - .len = (unsigned int)HASH_DER_LEN - } - }, - [1] = { - .type_desc = &tb_fw_config_hash, - .data = { - .ptr = (void *)tb_fw_config_hash_buf, - .len = (unsigned int)HASH_DER_LEN - } - }, - [2] = { - .type_desc = &hw_config_hash, - .data = { - .ptr = (void *)hw_config_hash_buf, - .len = (unsigned int)HASH_DER_LEN - } - } - } - }; -#ifdef IMAGE_BL1 -static const auth_img_desc_t bl2_image = { - .img_id = BL2_IMAGE_ID, - .img_type = IMG_RAW, - .parent = &trusted_boot_fw_cert, - .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { - [0] = { - .type = AUTH_METHOD_HASH, - .param.hash = { - .data = &raw_data, - .hash = &tb_fw_hash - } - } - } -}; -#endif /* IMAGE_BL1 */ -/* HW Config */ -static const auth_img_desc_t hw_config = { - .img_id = HW_CONFIG_ID, - .img_type = IMG_RAW, - .parent = &trusted_boot_fw_cert, - .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { - [0] = { - .type = AUTH_METHOD_HASH, - .param.hash = { - .data = &raw_data, - .hash = &hw_config_hash - } - } - } -}; -/* TB FW Config */ -#ifdef IMAGE_BL1 -static const auth_img_desc_t tb_fw_config = { - .img_id = TB_FW_CONFIG_ID, - .img_type = IMG_RAW, - .parent = &trusted_boot_fw_cert, - .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { - [0] = { - .type = AUTH_METHOD_HASH, - .param.hash = { - .data = &raw_data, - .hash = &tb_fw_config_hash - } - } - } -}; -#endif /* IMAGE_BL1 */ -#ifdef IMAGE_BL2 -/* - * 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 - } - } - } -}; -/* - * SCP Firmware - */ -static const auth_img_desc_t scp_fw_key_cert = { - .img_id = SCP_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 = &trusted_world_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 = &scp_fw_content_pk, - .data = { - .ptr = (void *)content_pk_buf, - .len = (unsigned int)PK_DER_LEN - } - } - } -}; -static const auth_img_desc_t scp_fw_content_cert = { - .img_id = SCP_FW_CONTENT_CERT_ID, - .img_type = IMG_CERT, - .parent = &scp_fw_key_cert, - .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { - [0] = { - .type = AUTH_METHOD_SIG, - .param.sig = { - .pk = &scp_fw_content_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 = &scp_fw_hash, - .data = { - .ptr = (void *)scp_fw_hash_buf, - .len = (unsigned int)HASH_DER_LEN - } - } - } -}; -static const auth_img_desc_t scp_bl2_image = { - .img_id = SCP_BL2_IMAGE_ID, - .img_type = IMG_RAW, - .parent = &scp_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 = &scp_fw_hash - } - } - } -}; -/* - * SoC Firmware - */ -static const auth_img_desc_t soc_fw_key_cert = { - .img_id = SOC_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 = &trusted_world_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 = &soc_fw_content_pk, - .data = { - .ptr = (void *)content_pk_buf, - .len = (unsigned int)PK_DER_LEN - } - } - } -}; -static const auth_img_desc_t soc_fw_content_cert = { - .img_id = SOC_FW_CONTENT_CERT_ID, - .img_type = IMG_CERT, - .parent = &soc_fw_key_cert, - .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { - [0] = { - .type = AUTH_METHOD_SIG, - .param.sig = { - .pk = &soc_fw_content_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 = &soc_fw_hash, - .data = { - .ptr = (void *)soc_fw_hash_buf, - .len = (unsigned int)HASH_DER_LEN - } - }, - [1] = { - .type_desc = &soc_fw_config_hash, - .data = { - .ptr = (void *)soc_fw_config_hash_buf, - .len = (unsigned int)HASH_DER_LEN - } - } - } -}; -static const auth_img_desc_t bl31_image = { - .img_id = BL31_IMAGE_ID, - .img_type = IMG_RAW, - .parent = &soc_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 = &soc_fw_hash - } - } - } -}; -/* SOC FW Config */ -static const auth_img_desc_t soc_fw_config = { - .img_id = SOC_FW_CONFIG_ID, - .img_type = IMG_RAW, - .parent = &soc_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 = &soc_fw_config_hash - } - } - } -}; -/* - * Trusted OS Firmware - */ -static const auth_img_desc_t trusted_os_fw_key_cert = { - .img_id = TRUSTED_OS_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 = &trusted_world_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 = &tos_fw_content_pk, - .data = { - .ptr = (void *)content_pk_buf, - .len = (unsigned int)PK_DER_LEN - } - } - } -}; -static const auth_img_desc_t trusted_os_fw_content_cert = { - .img_id = TRUSTED_OS_FW_CONTENT_CERT_ID, - .img_type = IMG_CERT, - .parent = &trusted_os_fw_key_cert, - .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { - [0] = { - .type = AUTH_METHOD_SIG, - .param.sig = { - .pk = &tos_fw_content_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 = &tos_fw_hash, - .data = { - .ptr = (void *)tos_fw_hash_buf, - .len = (unsigned int)HASH_DER_LEN - } - }, - [1] = { - .type_desc = &tos_fw_extra1_hash, - .data = { - .ptr = (void *)tos_fw_extra1_hash_buf, - .len = (unsigned int)HASH_DER_LEN - } - }, - [2] = { - .type_desc = &tos_fw_extra2_hash, - .data = { - .ptr = (void *)tos_fw_extra2_hash_buf, - .len = (unsigned int)HASH_DER_LEN - } - }, - [3] = { - .type_desc = &tos_fw_config_hash, - .data = { - .ptr = (void *)tos_fw_config_hash_buf, - .len = (unsigned int)HASH_DER_LEN - } - } - } -}; -static const auth_img_desc_t bl32_image = { - .img_id = BL32_IMAGE_ID, - .img_type = IMG_RAW, - .parent = &trusted_os_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 = &tos_fw_hash - } - } - } -}; -static const auth_img_desc_t bl32_extra1_image = { - .img_id = BL32_EXTRA1_IMAGE_ID, - .img_type = IMG_RAW, - .parent = &trusted_os_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 = &tos_fw_extra1_hash - } - } - } -}; -static const auth_img_desc_t bl32_extra2_image = { - .img_id = BL32_EXTRA2_IMAGE_ID, - .img_type = IMG_RAW, - .parent = &trusted_os_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 = &tos_fw_extra2_hash - } - } - } -}; -/* TOS FW Config */ -static const auth_img_desc_t tos_fw_config = { - .img_id = TOS_FW_CONFIG_ID, - .img_type = IMG_RAW, - .parent = &trusted_os_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 = &tos_fw_config_hash - } - } - } -}; -/* - * 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 - } - } - } -}; -/* NT FW Config */ -static const auth_img_desc_t nt_fw_config = { - .img_id = NT_FW_CONFIG_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_fw_config_hash - } - } - } -}; -#else /* IMAGE_BL2 */ -/* - * FWU auth descriptor. - */ -static const auth_img_desc_t fwu_cert = { - .img_id = FWU_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 - } - } - }, - .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { - [0] = { - .type_desc = &scp_bl2u_hash, - .data = { - .ptr = (void *)scp_fw_hash_buf, - .len = (unsigned int)HASH_DER_LEN - } - }, - [1] = { - .type_desc = &bl2u_hash, - .data = { - .ptr = (void *)tb_fw_hash_buf, - .len = (unsigned int)HASH_DER_LEN - } - }, - [2] = { - .type_desc = &ns_bl2u_hash, - .data = { - .ptr = (void *)nt_world_bl_hash_buf, - .len = (unsigned int)HASH_DER_LEN - } - } - } -}; -/* - * SCP_BL2U - */ -static const auth_img_desc_t scp_bl2u_image = { - .img_id = SCP_BL2U_IMAGE_ID, - .img_type = IMG_RAW, - .parent = &fwu_cert, - .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { - [0] = { - .type = AUTH_METHOD_HASH, - .param.hash = { - .data = &raw_data, - .hash = &scp_bl2u_hash - } - } - } -}; -/* - * BL2U - */ -static const auth_img_desc_t bl2u_image = { - .img_id = BL2U_IMAGE_ID, - .img_type = IMG_RAW, - .parent = &fwu_cert, - .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { - [0] = { - .type = AUTH_METHOD_HASH, - .param.hash = { - .data = &raw_data, - .hash = &bl2u_hash - } - } - } -}; -/* - * NS_BL2U - */ -static const auth_img_desc_t ns_bl2u_image = { - .img_id = NS_BL2U_IMAGE_ID, - .img_type = IMG_RAW, - .parent = &fwu_cert, - .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { - [0] = { - .type = AUTH_METHOD_HASH, - .param.hash = { - .data = &raw_data, - .hash = &ns_bl2u_hash - } - } - } - }; -#endif /* IMAGE_BL2 */ -/* - * TBBR Chain of trust definition - */ - -#ifdef IMAGE_BL1 -static const auth_img_desc_t * const cot_desc[] = { - [TRUSTED_BOOT_FW_CERT_ID] = &trusted_boot_fw_cert, - [BL2_IMAGE_ID] = &bl2_image, - [HW_CONFIG_ID] = &hw_config, - [TB_FW_CONFIG_ID] = &tb_fw_config, - [FWU_CERT_ID] = &fwu_cert, - [SCP_BL2U_IMAGE_ID] = &scp_bl2u_image, - [BL2U_IMAGE_ID] = &bl2u_image, - [NS_BL2U_IMAGE_ID] = &ns_bl2u_image -}; -#else /* IMAGE_BL2 */ -static const auth_img_desc_t * const cot_desc[] = { - [TRUSTED_BOOT_FW_CERT_ID] = &trusted_boot_fw_cert, - [HW_CONFIG_ID] = &hw_config, - [TRUSTED_KEY_CERT_ID] = &trusted_key_cert, - [SCP_FW_KEY_CERT_ID] = &scp_fw_key_cert, - [SCP_FW_CONTENT_CERT_ID] = &scp_fw_content_cert, - [SCP_BL2_IMAGE_ID] = &scp_bl2_image, - [SOC_FW_KEY_CERT_ID] = &soc_fw_key_cert, - [SOC_FW_CONTENT_CERT_ID] = &soc_fw_content_cert, - [BL31_IMAGE_ID] = &bl31_image, - [SOC_FW_CONFIG_ID] = &soc_fw_config, - [TRUSTED_OS_FW_KEY_CERT_ID] = &trusted_os_fw_key_cert, - [TRUSTED_OS_FW_CONTENT_CERT_ID] = &trusted_os_fw_content_cert, - [BL32_IMAGE_ID] = &bl32_image, - [BL32_EXTRA1_IMAGE_ID] = &bl32_extra1_image, - [BL32_EXTRA2_IMAGE_ID] = &bl32_extra2_image, - [TOS_FW_CONFIG_ID] = &tos_fw_config, - [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, - [NT_FW_CONFIG_ID] = &nt_fw_config, -}; -#endif - -/* Register the CoT in the authentication module */ -REGISTER_COT(cot_desc); diff --git a/drivers/auth/tbbr/tbbr_cot_bl1.c b/drivers/auth/tbbr/tbbr_cot_bl1.c new file mode 100644 index 000000000..f3bb37674 --- /dev/null +++ b/drivers/auth/tbbr/tbbr_cot_bl1.c @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include + +#include +#include +#if USE_TBBR_DEFS +#include +#else +#include +#endif + +static auth_param_type_desc_t scp_bl2u_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SCP_FWU_CFG_HASH_OID); +static auth_param_type_desc_t bl2u_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, AP_FWU_CFG_HASH_OID); +static auth_param_type_desc_t ns_bl2u_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, FWU_HASH_OID); + +static const auth_img_desc_t bl2_image = { + .img_id = BL2_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &trusted_boot_fw_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &tb_fw_hash + } + } + } +}; + +/* + * FWU auth descriptor. + */ +static const auth_img_desc_t fwu_cert = { + .img_id = FWU_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 + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &scp_bl2u_hash, + .data = { + .ptr = (void *)scp_fw_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [1] = { + .type_desc = &bl2u_hash, + .data = { + .ptr = (void *)tb_fw_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [2] = { + .type_desc = &ns_bl2u_hash, + .data = { + .ptr = (void *)nt_world_bl_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + } + } +}; +/* + * SCP_BL2U + */ +static const auth_img_desc_t scp_bl2u_image = { + .img_id = SCP_BL2U_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &fwu_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &scp_bl2u_hash + } + } + } +}; +/* + * BL2U + */ +static const auth_img_desc_t bl2u_image = { + .img_id = BL2U_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &fwu_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &bl2u_hash + } + } + } +}; +/* + * NS_BL2U + */ +static const auth_img_desc_t ns_bl2u_image = { + .img_id = NS_BL2U_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &fwu_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &ns_bl2u_hash + } + } + } +}; +/* + * TB_FW_CONFIG + */ +static const auth_img_desc_t tb_fw_config = { + .img_id = TB_FW_CONFIG_ID, + .img_type = IMG_RAW, + .parent = &trusted_boot_fw_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &tb_fw_config_hash + } + } + } +}; + +/* + * TBBR Chain of trust definition + */ +static const auth_img_desc_t * const cot_desc[] = { + [TRUSTED_BOOT_FW_CERT_ID] = &trusted_boot_fw_cert, + [BL2_IMAGE_ID] = &bl2_image, + [HW_CONFIG_ID] = &hw_config, + [TB_FW_CONFIG_ID] = &tb_fw_config, + [FWU_CERT_ID] = &fwu_cert, + [SCP_BL2U_IMAGE_ID] = &scp_bl2u_image, + [BL2U_IMAGE_ID] = &bl2u_image, + [NS_BL2U_IMAGE_ID] = &ns_bl2u_image +}; + +/* Register the CoT in the authentication module */ +REGISTER_COT(cot_desc); diff --git a/drivers/auth/tbbr/tbbr_cot_bl2.c b/drivers/auth/tbbr/tbbr_cot_bl2.c new file mode 100644 index 000000000..c47bf1aca --- /dev/null +++ b/drivers/auth/tbbr/tbbr_cot_bl2.c @@ -0,0 +1,563 @@ +/* + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include + +#include +#include +#if USE_TBBR_DEFS +#include +#else +#include +#endif + +static unsigned char soc_fw_hash_buf[HASH_DER_LEN]; +static unsigned char tos_fw_hash_buf[HASH_DER_LEN]; +static unsigned char tos_fw_extra1_hash_buf[HASH_DER_LEN]; +static unsigned char tos_fw_extra2_hash_buf[HASH_DER_LEN]; +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 soc_fw_config_hash_buf[HASH_DER_LEN]; +static unsigned char tos_fw_config_hash_buf[HASH_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 scp_fw_content_pk = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_PUB_KEY, SCP_FW_CONTENT_CERT_PK_OID); +static auth_param_type_desc_t soc_fw_content_pk = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_PUB_KEY, SOC_FW_CONTENT_CERT_PK_OID); +static auth_param_type_desc_t tos_fw_content_pk = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_PUB_KEY, TRUSTED_OS_FW_CONTENT_CERT_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 scp_fw_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SCP_FW_HASH_OID); +static auth_param_type_desc_t soc_fw_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SOC_AP_FW_HASH_OID); +static auth_param_type_desc_t soc_fw_config_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SOC_FW_CONFIG_HASH_OID); +static auth_param_type_desc_t tos_fw_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, TRUSTED_OS_FW_HASH_OID); +static auth_param_type_desc_t tos_fw_config_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, TRUSTED_OS_FW_CONFIG_HASH_OID); +static auth_param_type_desc_t tos_fw_extra1_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, TRUSTED_OS_FW_EXTRA1_HASH_OID); +static auth_param_type_desc_t tos_fw_extra2_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, TRUSTED_OS_FW_EXTRA2_HASH_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 + } + } + } +}; +/* + * SCP Firmware + */ +static const auth_img_desc_t scp_fw_key_cert = { + .img_id = SCP_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 = &trusted_world_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 = &scp_fw_content_pk, + .data = { + .ptr = (void *)content_pk_buf, + .len = (unsigned int)PK_DER_LEN + } + } + } +}; +static const auth_img_desc_t scp_fw_content_cert = { + .img_id = SCP_FW_CONTENT_CERT_ID, + .img_type = IMG_CERT, + .parent = &scp_fw_key_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &scp_fw_content_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 = &scp_fw_hash, + .data = { + .ptr = (void *)scp_fw_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + } + } +}; +static const auth_img_desc_t scp_bl2_image = { + .img_id = SCP_BL2_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &scp_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 = &scp_fw_hash + } + } + } +}; +/* + * SoC Firmware + */ +static const auth_img_desc_t soc_fw_key_cert = { + .img_id = SOC_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 = &trusted_world_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 = &soc_fw_content_pk, + .data = { + .ptr = (void *)content_pk_buf, + .len = (unsigned int)PK_DER_LEN + } + } + } +}; +static const auth_img_desc_t soc_fw_content_cert = { + .img_id = SOC_FW_CONTENT_CERT_ID, + .img_type = IMG_CERT, + .parent = &soc_fw_key_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &soc_fw_content_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 = &soc_fw_hash, + .data = { + .ptr = (void *)soc_fw_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [1] = { + .type_desc = &soc_fw_config_hash, + .data = { + .ptr = (void *)soc_fw_config_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + } + } +}; +static const auth_img_desc_t bl31_image = { + .img_id = BL31_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &soc_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 = &soc_fw_hash + } + } + } +}; +/* SOC FW Config */ +static const auth_img_desc_t soc_fw_config = { + .img_id = SOC_FW_CONFIG_ID, + .img_type = IMG_RAW, + .parent = &soc_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 = &soc_fw_config_hash + } + } + } +}; +/* + * Trusted OS Firmware + */ +static const auth_img_desc_t trusted_os_fw_key_cert = { + .img_id = TRUSTED_OS_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 = &trusted_world_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 = &tos_fw_content_pk, + .data = { + .ptr = (void *)content_pk_buf, + .len = (unsigned int)PK_DER_LEN + } + } + } +}; +static const auth_img_desc_t trusted_os_fw_content_cert = { + .img_id = TRUSTED_OS_FW_CONTENT_CERT_ID, + .img_type = IMG_CERT, + .parent = &trusted_os_fw_key_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &tos_fw_content_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 = &tos_fw_hash, + .data = { + .ptr = (void *)tos_fw_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [1] = { + .type_desc = &tos_fw_extra1_hash, + .data = { + .ptr = (void *)tos_fw_extra1_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [2] = { + .type_desc = &tos_fw_extra2_hash, + .data = { + .ptr = (void *)tos_fw_extra2_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [3] = { + .type_desc = &tos_fw_config_hash, + .data = { + .ptr = (void *)tos_fw_config_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + } + } +}; +static const auth_img_desc_t bl32_image = { + .img_id = BL32_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &trusted_os_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 = &tos_fw_hash + } + } + } +}; +static const auth_img_desc_t bl32_extra1_image = { + .img_id = BL32_EXTRA1_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &trusted_os_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 = &tos_fw_extra1_hash + } + } + } +}; +static const auth_img_desc_t bl32_extra2_image = { + .img_id = BL32_EXTRA2_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &trusted_os_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 = &tos_fw_extra2_hash + } + } + } +}; +/* TOS FW Config */ +static const auth_img_desc_t tos_fw_config = { + .img_id = TOS_FW_CONFIG_ID, + .img_type = IMG_RAW, + .parent = &trusted_os_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 = &tos_fw_config_hash + } + } + } +}; +/* + * 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 + } + } + } +}; +/* NT FW Config */ +static const auth_img_desc_t nt_fw_config = { + .img_id = NT_FW_CONFIG_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_fw_config_hash + } + } + } +}; + +static const auth_img_desc_t * const cot_desc[] = { + [TRUSTED_BOOT_FW_CERT_ID] = &trusted_boot_fw_cert, + [HW_CONFIG_ID] = &hw_config, + [TRUSTED_KEY_CERT_ID] = &trusted_key_cert, + [SCP_FW_KEY_CERT_ID] = &scp_fw_key_cert, + [SCP_FW_CONTENT_CERT_ID] = &scp_fw_content_cert, + [SCP_BL2_IMAGE_ID] = &scp_bl2_image, + [SOC_FW_KEY_CERT_ID] = &soc_fw_key_cert, + [SOC_FW_CONTENT_CERT_ID] = &soc_fw_content_cert, + [BL31_IMAGE_ID] = &bl31_image, + [SOC_FW_CONFIG_ID] = &soc_fw_config, + [TRUSTED_OS_FW_KEY_CERT_ID] = &trusted_os_fw_key_cert, + [TRUSTED_OS_FW_CONTENT_CERT_ID] = &trusted_os_fw_content_cert, + [BL32_IMAGE_ID] = &bl32_image, + [BL32_EXTRA1_IMAGE_ID] = &bl32_extra1_image, + [BL32_EXTRA2_IMAGE_ID] = &bl32_extra2_image, + [TOS_FW_CONFIG_ID] = &tos_fw_config, + [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, + [NT_FW_CONFIG_ID] = &nt_fw_config, +}; + +/* Register the CoT in the authentication module */ +REGISTER_COT(cot_desc); diff --git a/drivers/auth/tbbr/tbbr_cot_common.c b/drivers/auth/tbbr/tbbr_cot_common.c new file mode 100644 index 000000000..0a4b75e00 --- /dev/null +++ b/drivers/auth/tbbr/tbbr_cot_common.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include + +#include +#include +#if USE_TBBR_DEFS +#include +#else +#include +#endif + +/* + * The platform must allocate buffers to store the authentication parameters + * extracted from the certificates. In this case, because of the way the CoT is + * established, we can reuse some of the buffers on different stages + */ + +unsigned char tb_fw_hash_buf[HASH_DER_LEN]; +unsigned char tb_fw_config_hash_buf[HASH_DER_LEN]; +unsigned char hw_config_hash_buf[HASH_DER_LEN]; +unsigned char scp_fw_hash_buf[HASH_DER_LEN]; +unsigned char nt_world_bl_hash_buf[HASH_DER_LEN]; + +/* + * common Parameter type descriptors across BL1 and BL2 + */ +auth_param_type_desc_t trusted_nv_ctr = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_NV_CTR, TRUSTED_FW_NVCOUNTER_OID); +auth_param_type_desc_t subject_pk = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_PUB_KEY, 0); +auth_param_type_desc_t sig = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_SIG, 0); +auth_param_type_desc_t sig_alg = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_SIG_ALG, 0); +auth_param_type_desc_t raw_data = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_RAW_DATA, 0); + +/* common hash used across BL1 and BL2 */ +auth_param_type_desc_t tb_fw_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, TRUSTED_BOOT_FW_HASH_OID); +auth_param_type_desc_t tb_fw_config_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, TRUSTED_BOOT_FW_CONFIG_HASH_OID); +auth_param_type_desc_t hw_config_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, HW_CONFIG_HASH_OID); + +/* trusted_boot_fw_cert */ +const auth_img_desc_t trusted_boot_fw_cert = { + .img_id = TRUSTED_BOOT_FW_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 = &tb_fw_hash, + .data = { + .ptr = (void *)tb_fw_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [1] = { + .type_desc = &tb_fw_config_hash, + .data = { + .ptr = (void *)tb_fw_config_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [2] = { + .type_desc = &hw_config_hash, + .data = { + .ptr = (void *)hw_config_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + } + } +}; + +/* HW Config */ +const auth_img_desc_t hw_config = { + .img_id = HW_CONFIG_ID, + .img_type = IMG_RAW, + .parent = &trusted_boot_fw_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &hw_config_hash + } + } + } +}; diff --git a/include/common/tbbr/cot_def.h b/include/common/tbbr/cot_def.h index 33350a0d3..c41114692 100644 --- a/include/common/tbbr/cot_def.h +++ b/include/common/tbbr/cot_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,4 +11,38 @@ #define COT_MAX_VERIFIED_PARAMS 4 +/* + * Maximum key and hash sizes (in DER format). + * + * Both RSA and ECDSA keys may be used at the same time. In this case, the key + * buffers must be big enough to hold either. As RSA keys are bigger than ECDSA + * ones for all key sizes we support, they impose the minimum size of these + * buffers. + */ +#if TF_MBEDTLS_USE_RSA +#if TF_MBEDTLS_KEY_SIZE == 1024 +#define PK_DER_LEN 162 +#elif TF_MBEDTLS_KEY_SIZE == 2048 +#define PK_DER_LEN 294 +#elif TF_MBEDTLS_KEY_SIZE == 3072 +#define PK_DER_LEN 422 +#elif TF_MBEDTLS_KEY_SIZE == 4096 +#define PK_DER_LEN 550 +#else +#error "Invalid value for TF_MBEDTLS_KEY_SIZE" +#endif +#else /* Only using ECDSA keys. */ +#define PK_DER_LEN 91 +#endif + +#if TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA256 +#define HASH_DER_LEN 51 +#elif TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA384 +#define HASH_DER_LEN 67 +#elif TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA512 +#define HASH_DER_LEN 83 +#else +#error "Invalid value for TF_MBEDTLS_HASH_ALG_ID" +#endif + #endif /* COT_DEF_H */ diff --git a/include/drivers/auth/tbbr_cot_common.h b/include/drivers/auth/tbbr_cot_common.h new file mode 100644 index 000000000..0ea5f6575 --- /dev/null +++ b/include/drivers/auth/tbbr_cot_common.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef TBBR_COT_COMMON_H +#define TBBR_COT_COMMON_H + +#include + +extern unsigned char tb_fw_hash_buf[HASH_DER_LEN]; +extern unsigned char tb_fw_config_hash_buf[HASH_DER_LEN]; +extern unsigned char hw_config_hash_buf[HASH_DER_LEN]; +extern unsigned char scp_fw_hash_buf[HASH_DER_LEN]; +extern unsigned char nt_world_bl_hash_buf[HASH_DER_LEN]; + +extern auth_param_type_desc_t trusted_nv_ctr; +extern auth_param_type_desc_t subject_pk; +extern auth_param_type_desc_t sig; +extern auth_param_type_desc_t sig_alg; +extern auth_param_type_desc_t raw_data; + +extern auth_param_type_desc_t tb_fw_hash; +extern auth_param_type_desc_t tb_fw_config_hash; +extern auth_param_type_desc_t hw_config_hash; + +extern const auth_img_desc_t trusted_boot_fw_cert; +extern const auth_img_desc_t hw_config; + +#endif /* TBBR_COT_COMMON_H */ diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index 387c131e1..a28736808 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -297,7 +297,7 @@ ifneq (${TRUSTED_BOARD_BOOT},0) # Include the selected chain of trust sources. ifeq (${COT},tbbr) - AUTH_SOURCES += drivers/auth/tbbr/tbbr_cot.c + AUTH_SOURCES += drivers/auth/tbbr/tbbr_cot_common.c else ifeq (${COT},dualroot) AUTH_SOURCES += drivers/auth/dualroot/cot.c else @@ -307,10 +307,12 @@ ifneq (${TRUSTED_BOARD_BOOT},0) BL1_SOURCES += ${AUTH_SOURCES} \ bl1/tbbr/tbbr_img_desc.c \ plat/arm/common/arm_bl1_fwu.c \ + drivers/auth/tbbr/tbbr_cot_bl1.c \ plat/common/tbbr/plat_tbbr.c BL2_SOURCES += ${AUTH_SOURCES} \ - plat/common/tbbr/plat_tbbr.c + plat/common/tbbr/plat_tbbr.c \ + drivers/auth/tbbr/tbbr_cot_bl2.c $(eval $(call TOOL_ADD_IMG,ns_bl2u,--fwu,FWU_)) diff --git a/plat/brcm/board/common/board_common.mk b/plat/brcm/board/common/board_common.mk index 1795ce7f6..808a10741 100644 --- a/plat/brcm/board/common/board_common.mk +++ b/plat/brcm/board/common/board_common.mk @@ -213,7 +213,8 @@ KEY_ALG := rsa_1_5 AUTH_SOURCES += drivers/auth/auth_mod.c \ drivers/auth/crypto_mod.c \ drivers/auth/img_parser_mod.c \ - drivers/auth/tbbr/tbbr_cot.c + drivers/auth/tbbr/tbbr_cot_common.c \ + drivers/auth/tbbr/tbbr_cot_bl2.c BL2_SOURCES += ${AUTH_SOURCES} diff --git a/plat/hisilicon/hikey/platform.mk b/plat/hisilicon/hikey/platform.mk index fbf743292..18197cf4d 100644 --- a/plat/hisilicon/hikey/platform.mk +++ b/plat/hisilicon/hikey/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -126,17 +126,19 @@ 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.c + drivers/auth/tbbr/tbbr_cot_common.c BL1_SOURCES += ${AUTH_SOURCES} \ plat/common/tbbr/plat_tbbr.c \ plat/hisilicon/hikey/hikey_tbbr.c \ - plat/hisilicon/hikey/hikey_rotpk.S + plat/hisilicon/hikey/hikey_rotpk.S \ + drivers/auth/tbbr/tbbr_cot_bl1.c BL2_SOURCES += ${AUTH_SOURCES} \ plat/common/tbbr/plat_tbbr.c \ plat/hisilicon/hikey/hikey_tbbr.c \ - plat/hisilicon/hikey/hikey_rotpk.S + plat/hisilicon/hikey/hikey_rotpk.S \ + drivers/auth/tbbr/tbbr_cot_bl2.c ROT_KEY = $(BUILD_PLAT)/rot_key.pem ROTPK_HASH = $(BUILD_PLAT)/rotpk_sha256.bin diff --git a/plat/hisilicon/hikey960/platform.mk b/plat/hisilicon/hikey960/platform.mk index 8ebabebc9..fc2c209f8 100644 --- a/plat/hisilicon/hikey960/platform.mk +++ b/plat/hisilicon/hikey960/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -118,17 +118,19 @@ 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.c + drivers/auth/tbbr/tbbr_cot_common.c BL1_SOURCES += ${AUTH_SOURCES} \ plat/common/tbbr/plat_tbbr.c \ plat/hisilicon/hikey960/hikey960_tbbr.c \ - plat/hisilicon/hikey960/hikey960_rotpk.S + plat/hisilicon/hikey960/hikey960_rotpk.S \ + drivers/auth/tbbr/tbbr_cot_bl1.c BL2_SOURCES += ${AUTH_SOURCES} \ plat/common/tbbr/plat_tbbr.c \ plat/hisilicon/hikey960/hikey960_tbbr.c \ - plat/hisilicon/hikey960/hikey960_rotpk.S + plat/hisilicon/hikey960/hikey960_rotpk.S \ + drivers/auth/tbbr/tbbr_cot_bl2.c ROT_KEY = $(BUILD_PLAT)/rot_key.pem ROTPK_HASH = $(BUILD_PLAT)/rotpk_sha256.bin diff --git a/plat/imx/imx7/common/imx7.mk b/plat/imx/imx7/common/imx7.mk index 849ddcd76..3a95772b1 100644 --- a/plat/imx/imx7/common/imx7.mk +++ b/plat/imx/imx7/common/imx7.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -58,12 +58,13 @@ 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.c + drivers/auth/tbbr/tbbr_cot_common.c BL2_SOURCES += ${AUTH_SOURCES} \ plat/common/tbbr/plat_tbbr.c \ plat/imx/imx7/common/imx7_trusted_boot.c \ - plat/imx/imx7/common/imx7_rotpk.S + plat/imx/imx7/common/imx7_rotpk.S \ + drivers/auth/tbbr/tbbr_cot_bl2.c ROT_KEY = $(BUILD_PLAT)/rot_key.pem ROTPK_HASH = $(BUILD_PLAT)/rotpk_sha256.bin diff --git a/plat/qemu/qemu/platform.mk b/plat/qemu/qemu/platform.mk index 1bf4e0801..944143795 100644 --- a/plat/qemu/qemu/platform.mk +++ b/plat/qemu/qemu/platform.mk @@ -59,18 +59,20 @@ ifneq (${TRUSTED_BOARD_BOOT},0) AUTH_SOURCES := drivers/auth/auth_mod.c \ drivers/auth/crypto_mod.c \ drivers/auth/img_parser_mod.c \ - drivers/auth/tbbr/tbbr_cot.c + drivers/auth/tbbr/tbbr_cot_common.c BL1_SOURCES += ${AUTH_SOURCES} \ bl1/tbbr/tbbr_img_desc.c \ plat/common/tbbr/plat_tbbr.c \ ${PLAT_QEMU_COMMON_PATH}/qemu_trusted_boot.c \ - $(PLAT_QEMU_COMMON_PATH)/qemu_rotpk.S + $(PLAT_QEMU_COMMON_PATH)/qemu_rotpk.S \ + drivers/auth/tbbr/tbbr_cot_bl1.c BL2_SOURCES += ${AUTH_SOURCES} \ plat/common/tbbr/plat_tbbr.c \ ${PLAT_QEMU_COMMON_PATH}/qemu_trusted_boot.c \ - $(PLAT_QEMU_COMMON_PATH)/qemu_rotpk.S + $(PLAT_QEMU_COMMON_PATH)/qemu_rotpk.S \ + drivers/auth/tbbr/tbbr_cot_bl2.c ROT_KEY = $(BUILD_PLAT)/rot_key.pem ROTPK_HASH = $(BUILD_PLAT)/rotpk_sha256.bin diff --git a/plat/rpi/rpi3/platform.mk b/plat/rpi/rpi3/platform.mk index bcfc34e20..4d627b8a5 100644 --- a/plat/rpi/rpi3/platform.mk +++ b/plat/rpi/rpi3/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -185,18 +185,20 @@ ifneq (${TRUSTED_BOARD_BOOT},0) AUTH_SOURCES := drivers/auth/auth_mod.c \ drivers/auth/crypto_mod.c \ drivers/auth/img_parser_mod.c \ - drivers/auth/tbbr/tbbr_cot.c + drivers/auth/tbbr/tbbr_cot_common.c BL1_SOURCES += ${AUTH_SOURCES} \ bl1/tbbr/tbbr_img_desc.c \ plat/common/tbbr/plat_tbbr.c \ plat/rpi/common/rpi3_trusted_boot.c \ - plat/rpi/common/rpi3_rotpk.S + plat/rpi/common/rpi3_rotpk.S \ + drivers/auth/tbbr/tbbr_cot_bl1.c BL2_SOURCES += ${AUTH_SOURCES} \ plat/common/tbbr/plat_tbbr.c \ plat/rpi/common/rpi3_trusted_boot.c \ - plat/rpi/common/rpi3_rotpk.S + plat/rpi/common/rpi3_rotpk.S \ + drivers/auth/tbbr/tbbr_cot_bl2.c ROT_KEY = $(BUILD_PLAT)/rot_key.pem ROTPK_HASH = $(BUILD_PLAT)/rotpk_sha256.bin diff --git a/plat/socionext/uniphier/platform.mk b/plat/socionext/uniphier/platform.mk index 2c0ed92a3..6edd181f4 100644 --- a/plat/socionext/uniphier/platform.mk +++ b/plat/socionext/uniphier/platform.mk @@ -92,7 +92,8 @@ include drivers/auth/mbedtls/mbedtls_x509.mk BL2_SOURCES += drivers/auth/auth_mod.c \ drivers/auth/crypto_mod.c \ drivers/auth/img_parser_mod.c \ - drivers/auth/tbbr/tbbr_cot.c \ + drivers/auth/tbbr/tbbr_cot_common.c \ + drivers/auth/tbbr/tbbr_cot_bl2.c \ plat/common/tbbr/plat_tbbr.c \ $(PLAT_PATH)/uniphier_rotpk.S \ $(PLAT_PATH)/uniphier_tbbr.c -- cgit v1.2.3 From 003faaa59f247ed81973f3262e968258824f677a Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Wed, 13 May 2020 21:13:57 +0100 Subject: FVP: Add support for passing platform's topology to DTS This patch adds support for passing FVP platform's topology configuration to DTS files for compilation, which allows to build DTBs with correct number of clusters and CPUs. This removes non-existing clusters/CPUs from the compiled device tree blob and fixes reported Linux errors when trying to power on absent CPUs/PEs. If DTS file is passed using FVP_HW_CONFIG_DTS build option from the platform's makefile, FVP_CLUSTER_COUNT, FVP_MAX_CPUS_PER_CLUSTER and FVP_MAX_PE_PER_CPU parameters are used, otherwise CI script will use the default values from the corresponding DTS file. Change-Id: Idcb45dc6ad5e3eaea18573aff1a01c9344404ab3 Signed-off-by: Alexei Fedorov --- fdts/fvp-base-gicv2-psci-aarch32.dts | 111 +------- fdts/fvp-base-gicv2-psci.dts | 110 +------- fdts/fvp-base-gicv3-psci-1t.dts | 37 +-- fdts/fvp-base-gicv3-psci-aarch32-1t.dts | 38 +-- fdts/fvp-base-gicv3-psci-aarch32-common.dtsi | 104 +------ fdts/fvp-base-gicv3-psci-aarch32.dts | 6 + fdts/fvp-base-gicv3-psci-common.dtsi | 104 +------ fdts/fvp-base-gicv3-psci-dynamiq-2t.dts | 188 +------------ fdts/fvp-base-gicv3-psci-dynamiq-common.dtsi | 35 +-- fdts/fvp-base-gicv3-psci-dynamiq.dts | 41 +-- fdts/fvp-base-gicv3-psci.dts | 5 + fdts/fvp-defs-dynamiq.dtsi | 289 +++++++++++++++++++ fdts/fvp-defs.dtsi | 400 +++++++++++++++++++++++++++ fdts/fvp-foundation-gicv2-psci.dts | 60 +--- fdts/fvp-foundation-gicv3-psci.dts | 60 +--- 15 files changed, 769 insertions(+), 819 deletions(-) create mode 100644 fdts/fvp-defs-dynamiq.dtsi create mode 100644 fdts/fvp-defs.dtsi diff --git a/fdts/fvp-base-gicv2-psci-aarch32.dts b/fdts/fvp-base-gicv2-psci-aarch32.dts index fcef927b3..591ec5896 100644 --- a/fdts/fvp-base-gicv2-psci-aarch32.dts +++ b/fdts/fvp-base-gicv2-psci-aarch32.dts @@ -4,8 +4,15 @@ * SPDX-License-Identifier: BSD-3-Clause */ +/* Configuration: max 4 clusters with up to 4 CPUs */ + /dts-v1/; +#define AFF +#define REG_32 + +#include "fvp-defs.dtsi" + /memreserve/ 0x80000000 0x00010000; / { @@ -42,37 +49,7 @@ #address-cells = <1>; #size-cells = <0>; - cpu-map { - cluster0 { - core0 { - cpu = <&CPU0>; - }; - core1 { - cpu = <&CPU1>; - }; - core2 { - cpu = <&CPU2>; - }; - core3 { - cpu = <&CPU3>; - }; - }; - - cluster1 { - core0 { - cpu = <&CPU4>; - }; - core1 { - cpu = <&CPU5>; - }; - core2 { - cpu = <&CPU6>; - }; - core3 { - cpu = <&CPU7>; - }; - }; - }; + CPU_MAP idle-states { entry-method = "arm,psci"; @@ -96,77 +73,7 @@ }; }; - CPU0:cpu@0 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU1:cpu@1 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x1>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU2:cpu@2 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x2>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU3:cpu@3 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x3>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU4:cpu@100 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x100>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU5:cpu@101 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x101>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU6:cpu@102 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x102>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU7:cpu@103 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x103>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; + CPUS L2_0: l2-cache0 { compatible = "cache"; diff --git a/fdts/fvp-base-gicv2-psci.dts b/fdts/fvp-base-gicv2-psci.dts index 1e0a81c3c..4b3942e19 100644 --- a/fdts/fvp-base-gicv2-psci.dts +++ b/fdts/fvp-base-gicv2-psci.dts @@ -4,8 +4,14 @@ * SPDX-License-Identifier: BSD-3-Clause */ +/* Configuration: max 4 clusters with up to 4 CPUs */ + /dts-v1/; +#define AFF + +#include "fvp-defs.dtsi" + /memreserve/ 0x80000000 0x00010000; / { @@ -42,37 +48,7 @@ #address-cells = <2>; #size-cells = <0>; - cpu-map { - cluster0 { - core0 { - cpu = <&CPU0>; - }; - core1 { - cpu = <&CPU1>; - }; - core2 { - cpu = <&CPU2>; - }; - core3 { - cpu = <&CPU3>; - }; - }; - - cluster1 { - core0 { - cpu = <&CPU4>; - }; - core1 { - cpu = <&CPU5>; - }; - core2 { - cpu = <&CPU6>; - }; - core3 { - cpu = <&CPU7>; - }; - }; - }; + CPU_MAP idle-states { entry-method = "arm,psci"; @@ -96,77 +72,7 @@ }; }; - CPU0:cpu@0 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x0>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU1:cpu@1 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x1>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU2:cpu@2 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x2>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU3:cpu@3 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x3>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU4:cpu@100 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x100>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU5:cpu@101 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x101>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU6:cpu@102 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x102>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU7:cpu@103 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x103>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; + CPUS L2_0: l2-cache0 { compatible = "cache"; diff --git a/fdts/fvp-base-gicv3-psci-1t.dts b/fdts/fvp-base-gicv3-psci-1t.dts index 3c82f7b13..c5e0424f6 100644 --- a/fdts/fvp-base-gicv3-psci-1t.dts +++ b/fdts/fvp-base-gicv3-psci-1t.dts @@ -4,38 +4,11 @@ * SPDX-License-Identifier: BSD-3-Clause */ -/dts-v1/; - -#include "fvp-base-gicv3-psci-common.dtsi" - -&CPU0 { - reg = <0x0 0x0>; -}; - -&CPU1 { - reg = <0x0 0x100>; -}; +/* Configuration: max 4 clusters with up to 4 CPUs with 1 thread per each */ -&CPU2 { - reg = <0x0 0x200>; -}; - -&CPU3 { - reg = <0x0 0x300>; -}; - -&CPU4 { - reg = <0x0 0x10000>; -}; - -&CPU5 { - reg = <0x0 0x10100>; -}; +/dts-v1/; -&CPU6 { - reg = <0x0 0x10200>; -}; +#define AFF 00 -&CPU7 { - reg = <0x0 0x10300>; -}; +#include "fvp-defs.dtsi" +#include "fvp-base-gicv3-psci-common.dtsi" diff --git a/fdts/fvp-base-gicv3-psci-aarch32-1t.dts b/fdts/fvp-base-gicv3-psci-aarch32-1t.dts index d1d33485c..a31c70374 100644 --- a/fdts/fvp-base-gicv3-psci-aarch32-1t.dts +++ b/fdts/fvp-base-gicv3-psci-aarch32-1t.dts @@ -4,38 +4,12 @@ * SPDX-License-Identifier: BSD-3-Clause */ -/dts-v1/; - -#include "fvp-base-gicv3-psci-aarch32-common.dtsi" - -&CPU0 { - reg = <0x0>; -}; - -&CPU1 { - reg = <0x100>; -}; +/* Configuration: max 4 clusters with up to 4 CPUs with 1 thread per each */ -&CPU2 { - reg = <0x200>; -}; - -&CPU3 { - reg = <0x300>; -}; - -&CPU4 { - reg = <0x10000>; -}; - -&CPU5 { - reg = <0x10100>; -}; +/dts-v1/; -&CPU6 { - reg = <0x10200>; -}; +#define AFF 00 +#define REG_32 -&CPU7 { - reg = <0x10300>; -}; +#include "fvp-defs.dtsi" +#include "fvp-base-gicv3-psci-aarch32-common.dtsi" diff --git a/fdts/fvp-base-gicv3-psci-aarch32-common.dtsi b/fdts/fvp-base-gicv3-psci-aarch32-common.dtsi index a28a4a537..1a1bd12d2 100644 --- a/fdts/fvp-base-gicv3-psci-aarch32-common.dtsi +++ b/fdts/fvp-base-gicv3-psci-aarch32-common.dtsi @@ -40,37 +40,7 @@ #address-cells = <1>; #size-cells = <0>; - cpu-map { - cluster0 { - core0 { - cpu = <&CPU0>; - }; - core1 { - cpu = <&CPU1>; - }; - core2 { - cpu = <&CPU2>; - }; - core3 { - cpu = <&CPU3>; - }; - }; - - cluster1 { - core0 { - cpu = <&CPU4>; - }; - core1 { - cpu = <&CPU5>; - }; - core2 { - cpu = <&CPU6>; - }; - core3 { - cpu = <&CPU7>; - }; - }; - }; + CPU_MAP idle-states { entry-method = "arm,psci"; @@ -94,77 +64,7 @@ }; }; - CPU0:cpu@0 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU1:cpu@1 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x1>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU2:cpu@2 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x2>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU3:cpu@3 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x3>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU4:cpu@100 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x100>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU5:cpu@101 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x101>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU6:cpu@102 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x102>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU7:cpu@103 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x103>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; + CPUS L2_0: l2-cache0 { compatible = "cache"; diff --git a/fdts/fvp-base-gicv3-psci-aarch32.dts b/fdts/fvp-base-gicv3-psci-aarch32.dts index 513014b32..971b2e4d2 100644 --- a/fdts/fvp-base-gicv3-psci-aarch32.dts +++ b/fdts/fvp-base-gicv3-psci-aarch32.dts @@ -4,6 +4,12 @@ * SPDX-License-Identifier: BSD-3-Clause */ +/* Configuration: max 4 clusters with up to 4 CPUs */ + /dts-v1/; +#define REG_32 +#define AFF + +#include "fvp-defs.dtsi" #include "fvp-base-gicv3-psci-aarch32-common.dtsi" diff --git a/fdts/fvp-base-gicv3-psci-common.dtsi b/fdts/fvp-base-gicv3-psci-common.dtsi index 4a7b65658..0deb8a2e7 100644 --- a/fdts/fvp-base-gicv3-psci-common.dtsi +++ b/fdts/fvp-base-gicv3-psci-common.dtsi @@ -66,37 +66,7 @@ #address-cells = <2>; #size-cells = <0>; - CPU_MAP:cpu-map { - cluster0 { - core0 { - cpu = <&CPU0>; - }; - core1 { - cpu = <&CPU1>; - }; - core2 { - cpu = <&CPU2>; - }; - core3 { - cpu = <&CPU3>; - }; - }; - - cluster1 { - core0 { - cpu = <&CPU4>; - }; - core1 { - cpu = <&CPU5>; - }; - core2 { - cpu = <&CPU6>; - }; - core3 { - cpu = <&CPU7>; - }; - }; - }; + CPU_MAP idle-states { entry-method = "arm,psci"; @@ -120,77 +90,7 @@ }; }; - CPU0:cpu@0 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x0>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU1:cpu@1 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x1>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU2:cpu@2 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x2>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU3:cpu@3 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x3>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU4:cpu@100 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x100>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU5:cpu@101 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x101>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU6:cpu@102 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x102>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU7:cpu@103 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x103>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; + CPUS L2_0: l2-cache0 { compatible = "cache"; diff --git a/fdts/fvp-base-gicv3-psci-dynamiq-2t.dts b/fdts/fvp-base-gicv3-psci-dynamiq-2t.dts index 6e63b4351..bda4b8dd4 100644 --- a/fdts/fvp-base-gicv3-psci-dynamiq-2t.dts +++ b/fdts/fvp-base-gicv3-psci-dynamiq-2t.dts @@ -4,185 +4,15 @@ * SPDX-License-Identifier: BSD-3-Clause */ -/dts-v1/; - -#include "fvp-base-gicv3-psci-dynamiq-common.dtsi" - -&CPU_MAP { - /delete-node/ cluster0; - - cluster0 { - core0 { - thread0 { - cpu = <&CPU0>; - }; - thread1 { - cpu = <&CPU1>; - }; - }; - core1 { - thread0 { - cpu = <&CPU2>; - }; - thread1 { - cpu = <&CPU3>; - }; - }; - core2 { - thread0 { - cpu = <&CPU4>; - }; - thread1 { - cpu = <&CPU5>; - }; - }; - core3 { - thread0 { - cpu = <&CPU6>; - }; - thread1 { - cpu = <&CPU7>; - }; - }; - core4 { - thread0 { - cpu = <&CPU8>; - }; - thread1 { - cpu = <&CPU9>; - }; - }; - core5 { - thread0 { - cpu = <&CPU10>; - }; - thread1 { - cpu = <&CPU11>; - }; - }; - core6 { - thread0 { - cpu = <&CPU12>; - }; - thread1 { - cpu = <&CPU13>; - }; - }; - core7 { - thread0 { - cpu = <&CPU14>; - }; - thread1 { - cpu = <&CPU15>; - }; - }; - }; -}; - -/ { - cpus { - CPU0:cpu@0 { - reg = <0x0 0x0>; - }; - - CPU1:cpu@1 { - reg = <0x0 0x1>; - }; - - CPU2:cpu@2 { - reg = <0x0 0x100>; - }; - - CPU3:cpu@3 { - reg = <0x0 0x101>; - }; - - CPU4:cpu@100 { - reg = <0x0 0x200>; - }; +/* DynamIQ configuration: 1 cluster with up to 8 CPUs with 2 threads per each */ - CPU5:cpu@101 { - reg = <0x0 0x201>; - }; +/* Set default value if not passed from platform's makefile */ +#ifdef FVP_MAX_PE_PER_CPU +#define PE_PER_CPU FVP_MAX_PE_PER_CPU +#else +#define PE_PER_CPU 2 +#endif - CPU6:cpu@102 { - reg = <0x0 0x300>; - }; - - CPU7:cpu@103 { - reg = <0x0 0x301>; - }; - - CPU8:cpu@200 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x400>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU9:cpu@201 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x401>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU10:cpu@202 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x500>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU11:cpu@203 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x501>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU12:cpu@300 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x600>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU13:cpu@301 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x601>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU14:cpu@302 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x700>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; +/dts-v1/; - CPU15:cpu@303 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x701>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - }; -}; +#include "fvp-base-gicv3-psci-dynamiq-common.dtsi" diff --git a/fdts/fvp-base-gicv3-psci-dynamiq-common.dtsi b/fdts/fvp-base-gicv3-psci-dynamiq-common.dtsi index 4bed36ff4..42a439f4d 100644 --- a/fdts/fvp-base-gicv3-psci-dynamiq-common.dtsi +++ b/fdts/fvp-base-gicv3-psci-dynamiq-common.dtsi @@ -6,38 +6,5 @@ /dts-v1/; +#include "fvp-defs-dynamiq.dtsi" #include "fvp-base-gicv3-psci-common.dtsi" - -/* DynamIQ based designs have upto 8 CPUs in each cluster */ - -&CPU_MAP { - /delete-node/ cluster0; - /delete-node/ cluster1; - - cluster0 { - core0 { - cpu = <&CPU0>; - }; - core1 { - cpu = <&CPU1>; - }; - core2 { - cpu = <&CPU2>; - }; - core3 { - cpu = <&CPU3>; - }; - core4 { - cpu = <&CPU4>; - }; - core5 { - cpu = <&CPU5>; - }; - core6 { - cpu = <&CPU6>; - }; - core7 { - cpu = <&CPU7>; - }; - }; -}; diff --git a/fdts/fvp-base-gicv3-psci-dynamiq.dts b/fdts/fvp-base-gicv3-psci-dynamiq.dts index b8b044500..b693f7512 100644 --- a/fdts/fvp-base-gicv3-psci-dynamiq.dts +++ b/fdts/fvp-base-gicv3-psci-dynamiq.dts @@ -4,38 +4,15 @@ * SPDX-License-Identifier: BSD-3-Clause */ -/dts-v1/; - -#include "fvp-base-gicv3-psci-dynamiq-common.dtsi" - -&CPU0 { - reg = <0x0 0x0>; -}; - -&CPU1 { - reg = <0x0 0x100>; -}; +/* DynamIQ configuration: 1 cluster with up to 8 CPUs */ -&CPU2 { - reg = <0x0 0x200>; -}; +/* Set default value if not passed from platform's makefile */ +#ifdef FVP_MAX_PE_PER_CPU +#define PE_PER_CPU FVP_MAX_PE_PER_CPU +#else +#define PE_PER_CPU 1 +#endif -&CPU3 { - reg = <0x0 0x300>; -}; - -&CPU4 { - reg = <0x0 0x400>; -}; - -&CPU5 { - reg = <0x0 0x500>; -}; - -&CPU6 { - reg = <0x0 0x600>; -}; +/dts-v1/; -&CPU7 { - reg = <0x0 0x700>; -}; +#include "fvp-base-gicv3-psci-dynamiq-common.dtsi" diff --git a/fdts/fvp-base-gicv3-psci.dts b/fdts/fvp-base-gicv3-psci.dts index 65fa4b0d9..eb994728a 100644 --- a/fdts/fvp-base-gicv3-psci.dts +++ b/fdts/fvp-base-gicv3-psci.dts @@ -4,6 +4,11 @@ * SPDX-License-Identifier: BSD-3-Clause */ +/* Configuration: max 4 clusters with up to 4 CPUs */ + /dts-v1/; +#define AFF + +#include "fvp-defs.dtsi" #include "fvp-base-gicv3-psci-common.dtsi" diff --git a/fdts/fvp-defs-dynamiq.dtsi b/fdts/fvp-defs-dynamiq.dtsi new file mode 100644 index 000000000..3659cd3d5 --- /dev/null +++ b/fdts/fvp-defs-dynamiq.dtsi @@ -0,0 +1,289 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FVP_DEFS_DYNAMIQ_DTSI +#define FVP_DEFS_DYNAMIQ_DTSI + +/* Set default topology values if not passed from platform's makefile */ +#ifdef FVP_CLUSTER_COUNT +#define CLUSTER_COUNT FVP_CLUSTER_COUNT +#else +#define CLUSTER_COUNT 1 +#endif + +#ifdef FVP_MAX_CPUS_PER_CLUSTER +#define CPUS_PER_CLUSTER FVP_MAX_CPUS_PER_CLUSTER +#else +#define CPUS_PER_CLUSTER 8 +#endif + +#define CONCAT(x, y) x##y +#define CONC(x, y) CONCAT(x, y) + +/* + * n - CPU number + * r - MPID + */ +#define CPU(n, r) \ + CPU##n:cpu@r## { \ + device_type = "cpu"; \ + compatible = "arm,armv8"; \ + reg = <0x0 0x##r>; \ + enable-method = "psci"; \ + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; \ + next-level-cache = <&L2_0>; \ + }; + +#if (PE_PER_CPU == 2) +#define THREAD(n) \ + thread##n { \ + cpu = <&CONC(CPU, __COUNTER__)>; \ + }; + +#define CORE(n) \ + core##n { \ + THREAD(0) \ + THREAD(1) \ + }; + +#else /* PE_PER_CPU == 1 */ +#define CORE(n) \ + core##n { \ + cpu = <&CPU##n>;\ + }; +#endif /* PE_PER_CORE */ + +#if (CPUS_PER_CLUSTER == 1) +#if (PE_PER_CPU == 1) +#define CPUS \ + CPU(0, 0) +#else +#define CPUS \ + CPU(0, 0) \ + CPU(1, 1) +#endif +#define CLUSTER(n) \ + cluster##n { \ + CORE(0) \ + }; + +#elif (CPUS_PER_CLUSTER == 2) +#if (PE_PER_CPU == 1) +#define CPUS \ + CPU(0, 0) \ + CPU(1, 100) +#else +#define CPUS \ + CPU(0, 0) \ + CPU(1, 1) \ + CPU(2, 100) \ + CPU(3, 101) +#endif +#define CLUSTER(n) \ + cluster##n { \ + CORE(0) \ + CORE(1) \ + }; + +#elif (CPUS_PER_CLUSTER == 3) +#if (PE_PER_CPU == 1) +#define CPUS \ + CPU(0, 0) \ + CPU(1, 100) \ + CPU(2, 200) +#else +#define CPUS \ + CPU(0, 0) \ + CPU(1, 1) \ + CPU(2, 100) \ + CPU(3, 101) \ + CPU(4, 200) \ + CPU(5, 201) +#endif +#define CLUSTER(n) \ + cluster##n { \ + CORE(0) \ + CORE(1) \ + CORE(2) \ + }; + +#elif (CPUS_PER_CLUSTER == 4) +#if (PE_PER_CPU == 1) +#define CPUS \ + CPU(0, 0) \ + CPU(1, 100) \ + CPU(2, 200) \ + CPU(3, 300) +#else +#define CPUS \ + CPU(0, 0) \ + CPU(1, 1) \ + CPU(2, 100) \ + CPU(3, 101) \ + CPU(4, 200) \ + CPU(5, 201) \ + CPU(6, 300) \ + CPU(7, 301) +#endif +#define CLUSTER(n) \ + cluster##n { \ + CORE(0) \ + CORE(1) \ + CORE(2) \ + CORE(3) \ + }; + +#elif (CPUS_PER_CLUSTER == 5) +#if (PE_PER_CPU == 1) +#define CPUS \ + CPU(0, 0) \ + CPU(1, 100) \ + CPU(2, 200) \ + CPU(3, 300) \ + CPU(4, 400) +#else +#define CPUS \ + CPU(0, 0) \ + CPU(1, 1) \ + CPU(2, 100) \ + CPU(3, 101) \ + CPU(4, 200) \ + CPU(5, 201) \ + CPU(6, 300) \ + CPU(7, 301) \ + CPU(8, 400) \ + CPU(9, 401) +#endif +#define CLUSTER(n) \ + cluster##n { \ + CORE(0) \ + CORE(1) \ + CORE(2) \ + CORE(3) \ + CORE(4) \ + }; + +#elif (CPUS_PER_CLUSTER == 6) +#if (PE_PER_CPU == 1) +#define CPUS \ + CPU(0, 0) \ + CPU(1, 100) \ + CPU(2, 200) \ + CPU(3, 300) \ + CPU(4, 400) \ + CPU(5, 500) +#else +#define CPUS \ + CPU(0, 0) \ + CPU(1, 1) \ + CPU(2, 100) \ + CPU(3, 101) \ + CPU(4, 200) \ + CPU(5, 201) \ + CPU(6, 300) \ + CPU(7, 301) \ + CPU(8, 400) \ + CPU(9, 401) \ + CPU(10, 500) \ + CPU(11, 501) +#endif +#define CLUSTER(n) \ + cluster##n { \ + CORE(0) \ + CORE(1) \ + CORE(2) \ + CORE(3) \ + CORE(4) \ + CORE(5) \ + }; + +#elif (CPUS_PER_CLUSTER == 7) +#if (PE_PER_CPU == 1) +#define CPUS \ + CPU(0, 0) \ + CPU(1, 100) \ + CPU(2, 200) \ + CPU(3, 300) \ + CPU(4, 400) \ + CPU(5, 500) \ + CPU(6, 600) +#else +#define CPUS \ + CPU(0, 0) \ + CPU(1, 1) \ + CPU(2, 100) \ + CPU(3, 101) \ + CPU(4, 200) \ + CPU(5, 201) \ + CPU(6, 300) \ + CPU(7, 301) \ + CPU(8, 400) \ + CPU(9, 401) \ + CPU(10, 500) \ + CPU(11, 501) \ + CPU(12, 600) \ + CPU(13, 601) +#endif +#define CLUSTER(n) \ + cluster##n { \ + CORE(0) \ + CORE(1) \ + CORE(2) \ + CORE(3) \ + CORE(4) \ + CORE(5) \ + CORE(6) \ + }; + +#else +#if (PE_PER_CPU == 1) +#define CPUS \ + CPU(0, 0) \ + CPU(1, 100) \ + CPU(2, 200) \ + CPU(3, 300) \ + CPU(4, 400) \ + CPU(5, 500) \ + CPU(6, 600) \ + CPU(7, 700) +#else +#define CPUS \ + CPU(0, 0) \ + CPU(1, 1) \ + CPU(2, 100) \ + CPU(3, 101) \ + CPU(4, 200) \ + CPU(5, 201) \ + CPU(6, 300) \ + CPU(7, 301) \ + CPU(8, 400) \ + CPU(9, 401) \ + CPU(10, 500) \ + CPU(11, 501) \ + CPU(12, 600) \ + CPU(13, 601) \ + CPU(14, 700) \ + CPU(15, 701) +#endif +#define CLUSTER(n) \ + cluster##n { \ + CORE(0) \ + CORE(1) \ + CORE(2) \ + CORE(3) \ + CORE(4) \ + CORE(5) \ + CORE(6) \ + CORE(7) \ + }; +#endif /* CPUS_PER_CLUSTER */ + +#define CPU_MAP \ + cpu-map { \ + CLUSTER(0) \ + }; + +#endif /* FVP_DEFS_DYNAMIQ_DTSI */ diff --git a/fdts/fvp-defs.dtsi b/fdts/fvp-defs.dtsi new file mode 100644 index 000000000..1ffe65a2a --- /dev/null +++ b/fdts/fvp-defs.dtsi @@ -0,0 +1,400 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FVP_DEFS_DTSI +#define FVP_DEFS_DTSI + +/* Set default topology values if not passed from platform's makefile */ +#ifndef CLUSTER_COUNT +#ifdef FVP_CLUSTER_COUNT +#define CLUSTER_COUNT FVP_CLUSTER_COUNT +#else +#define CLUSTER_COUNT 2 +#endif +#endif /* CLUSTER_COUNT */ + +#ifndef CPUS_PER_CLUSTER +#ifdef FVP_MAX_CPUS_PER_CLUSTER +#define CPUS_PER_CLUSTER FVP_MAX_CPUS_PER_CLUSTER +#else +#define CPUS_PER_CLUSTER 4 +#endif +#endif /* CPUS_PER_CLUSTER */ + +/* Get platform's topology */ +#define CPUS_COUNT (CLUSTER_COUNT * CPUS_PER_CLUSTER) + +#define CONCAT(x, y) x##y +#define CONC(x, y) CONCAT(x, y) + +/* CPU's cluster */ +#define CLS(n) (n / CPUS_PER_CLUSTER) + +/* CPU's position in cluster */ +#define POS(n) (n % CPUS_PER_CLUSTER) + +#define ADR(n, c, p) \ + CPU##n:cpu@CONC(c, CONC(p, AFF)) { + +#define PRE \ + device_type = "cpu"; \ + compatible = "arm,armv8"; + +#ifdef REG_32 +/* 32-bit address */ +#define REG(c, p) \ + reg = ; +#else +/* 64-bit address */ +#define REG(c, p) \ + reg = <0x0 CONC(0x, CONC(c, CONC(p, AFF)))>; +#endif /* REG_32 */ + +#define POST \ + enable-method = "psci"; \ + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; \ + next-level-cache = <&L2_0>; \ + }; + +#ifdef REG_32 +#define CPU_0 \ + CPU0:cpu@0 { \ + PRE \ + reg = <0x0>; \ + POST +#else +#define CPU_0 \ + CPU0:cpu@0 { \ + PRE \ + reg = <0x0 0x0>;\ + POST +#endif /* REG_32 */ + +/* + * n - CPU number + */ +#define CPU(n, c, p) \ + ADR(n, c, p) \ + PRE \ + REG(c, p) \ + POST + +/* 2 CPUs */ +#if (CPUS_COUNT > 1) +#if (CLS(1) == 0) +#define c1 +#define p1 1 +#else +#define c1 10 +#define p1 0 +#endif + +#define CPU_1 CPU(1, c1, p1) /* CPU1: 0.1; 1.0 */ + +/* 3 CPUs */ +#if (CPUS_COUNT > 2) +#if (CLS(2) == 0) +#define c2 +#define p2 2 +#elif (CLS(2) == 1) +#define c2 10 +#define p2 0 +#else +#define c2 20 +#define p2 0 +#endif + +#define CPU_2 CPU(2, c2, p2) /* CPU2: 0.2; 1.0; 2.0 */ + +/* 4 CPUs */ +#if (CPUS_COUNT > 3) +#if (CLS(3) == 0) +#define c3 +#elif (CLS(3) == 1) +#define c3 10 +#else +#define c3 30 +#endif + +#if (POS(3) == 0) +#define p3 0 +#elif (POS(3) == 1) +#define p3 1 +#else +#define p3 3 +#endif + +#define CPU_3 CPU(3, c3, p3) /* CPU3: 0.3; 1.0; 1.1; 3.0 */ + +/* 6 CPUs */ +#if (CPUS_COUNT > 4) +#if (CLS(4) == 1) +#define c4 10 +#else +#define c4 20 +#endif + +#if (POS(4) == 0) +#define p4 0 +#else +#define p4 1 +#endif + +#if (CLS(5) == 1) +#define c5 10 +#else +#define c5 20 +#endif + +#if (POS(5) == 1) +#define p5 1 +#else +#define p5 2 +#endif + +#define CPU_4 CPU(4, c4, p4) /* CPU4: 1.0; 1.1; 2.0 */ +#define CPU_5 CPU(5, c5, p5) /* CPU5: 1.1; 1.2; 2.1 */ + +/* 8 CPUs */ +#if (CPUS_COUNT > 6) +#if (CLS(6) == 1) +#define c6 10 +#define p6 2 +#elif (CLS(6) == 2) +#define c6 20 +#define p6 0 +#else +#define c6 30 +#define p6 0 +#endif + +#if (CLS(7) == 1) +#define c7 10 +#define p7 3 +#elif (CLS(7) == 2) +#define c7 20 +#define p7 1 +#else +#define c7 30 +#define p7 1 +#endif + +#define CPU_6 CPU(6, c6, p6) /* CPU6: 1.2; 2.0; 3.0 */ +#define CPU_7 CPU(7, c7, p7) /* CPU7: 1.3; 2.1; 3.1 */ + +/* 9 CPUs */ +#if (CPUS_COUNT > 8) +#if (POS(8) == 0) +#define p8 0 +#else +#define p8 2 +#endif + +#define CPU_8 CPU(8, 20, p8) /* CPU8: 2.0; 2.2 */ + +/* 12 CPUs */ +#if (CPUS_COUNT > 9) +#if (CLS(9) == 2) +#define c9 20 +#define p9 1 +#else +#define c9 30 +#define p9 0 +#endif + +#if (CLS(10) == 2) +#define c10 20 +#define p10 2 +#else +#define c10 30 +#define p10 1 +#endif + +#if (CLS(11) == 2) +#define c11 20 +#define p11 3 +#else +#define c11 30 +#define p11 2 +#endif + +#define CPU_9 CPU(9, c9, p9) /* CPU9: 2.1; 3.0 */ +#define CPU_10 CPU(10, c10, p10) /* CPU10: 2.2; 3.1 */ +#define CPU_11 CPU(11, c11, p11) /* CPU11: 2.3; 3.2 */ + +/* 16 CPUs */ +#if (CPUS_COUNT > 12) +#define CPU_12 CPU(12, 30, 0) /* CPU12: 3.0 */ +#define CPU_13 CPU(13, 30, 1) /* CPU13: 3.1 */ +#define CPU_14 CPU(14, 30, 2) /* CPU14: 3.2 */ +#define CPU_15 CPU(15, 30, 3) /* CPU15: 3.3 */ +#endif /* > 12 */ +#endif /* > 9 */ +#endif /* > 8 */ +#endif /* > 6 */ +#endif /* > 4 */ +#endif /* > 3 */ +#endif /* > 2 */ +#endif /* > 1 */ + +#if (CPUS_COUNT == 1) +#define CPUS \ + CPU_0 + +#elif (CPUS_COUNT == 2) +#define CPUS \ + CPU_0 \ + CPU_1 + +#elif (CPUS_COUNT == 3) +#define CPUS \ + CPU_0 \ + CPU_1 \ + CPU_2 + +#elif (CPUS_COUNT == 4) +#define CPUS \ + CPU_0 \ + CPU_1 \ + CPU_2 \ + CPU_3 + +#elif (CPUS_COUNT == 6) +#define CPUS \ + CPU_0 \ + CPU_1 \ + CPU_2 \ + CPU_3 \ + CPU_4 \ + CPU_5 + +#elif (CPUS_COUNT == 8) +#define CPUS \ + CPU_0 \ + CPU_1 \ + CPU_2 \ + CPU_3 \ + CPU_4 \ + CPU_5 \ + CPU_6 \ + CPU_7 + +#elif (CPUS_COUNT == 9) +#define CPUS \ + CPU_0 \ + CPU_1 \ + CPU_2 \ + CPU_3 \ + CPU_4 \ + CPU_5 \ + CPU_6 \ + CPU_7 \ + CPU_8 + +#elif (CPUS_COUNT == 12) +#define CPUS \ + CPU_0 \ + CPU_1 \ + CPU_2 \ + CPU_3 \ + CPU_4 \ + CPU_5 \ + CPU_6 \ + CPU_7 \ + CPU_8 \ + CPU_9 \ + CPU_10 \ + CPU_11 + +#else +#define CPUS \ + CPU_0 \ + CPU_1 \ + CPU_2 \ + CPU_3 \ + CPU_4 \ + CPU_5 \ + CPU_6 \ + CPU_7 \ + CPU_8 \ + CPU_9 \ + CPU_10 \ + CPU_11 \ + CPU_12 \ + CPU_13 \ + CPU_14 \ + CPU_15 +#endif /* CPUS_COUNT */ + +#define CORE(n) \ + core##n { \ + cpu = <&CONC(CPU, __COUNTER__)>; \ + }; + +/* Max 4 CPUs per cluster */ +#if (CPUS_PER_CLUSTER == 1) +#define CLUSTER(n) \ + cluster##n { \ + CORE(0) \ + }; +#elif (CPUS_PER_CLUSTER == 2) +#define CLUSTER(n) \ + cluster##n { \ + CORE(0) \ + CORE(1) \ + }; + +#elif (CPUS_PER_CLUSTER == 3) +#define CLUSTER(n) \ + cluster##n { \ + CORE(0) \ + CORE(1) \ + CORE(2) \ + }; + +#else +#define CLUSTER(n) \ + cluster##n { \ + CORE(0) \ + CORE(1) \ + CORE(2) \ + CORE(3) \ + }; +#endif /* CPUS_PER_CLUSTER */ + +/* Max 4 clusters */ +#if (CLUSTER_COUNT == 1) +#define CPU_MAP \ + cpu-map { \ + CLUSTER(0) \ + }; + +#elif (CLUSTER_COUNT == 2) +#define CPU_MAP \ + cpu-map { \ + CLUSTER(0) \ + CLUSTER(1) \ + }; + +#elif (CLUSTER_COUNT == 3) +#define CPU_MAP \ + cpu-map { \ + CLUSTER(0) \ + CLUSTER(1) \ + CLUSTER(2) \ + }; + +#else +#define CPU_MAP \ + cpu-map { \ + CLUSTER(0) \ + CLUSTER(1) \ + CLUSTER(2) \ + CLUSTER(3) \ + }; +#endif /* CLUSTER_COUNT */ + +#endif /* FVP_DEFS_DTSI */ diff --git a/fdts/fvp-foundation-gicv2-psci.dts b/fdts/fvp-foundation-gicv2-psci.dts index 3a204cb24..95a800e66 100644 --- a/fdts/fvp-foundation-gicv2-psci.dts +++ b/fdts/fvp-foundation-gicv2-psci.dts @@ -4,8 +4,15 @@ * SPDX-License-Identifier: BSD-3-Clause */ +/* Configuration: 1 cluster with up to 4 CPUs */ + /dts-v1/; +#define AFF +#define CLUSTER_COUNT 1 + +#include "fvp-defs.dtsi" + /memreserve/ 0x80000000 0x00010000; / { @@ -42,22 +49,7 @@ #address-cells = <2>; #size-cells = <0>; - cpu-map { - cluster0 { - core0 { - cpu = <&CPU0>; - }; - core1 { - cpu = <&CPU1>; - }; - core2 { - cpu = <&CPU2>; - }; - core3 { - cpu = <&CPU3>; - }; - }; - }; + CPU_MAP idle-states { entry-method = "arm,psci"; @@ -81,41 +73,7 @@ }; }; - CPU0:cpu@0 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x0>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU1:cpu@1 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x1>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU2:cpu@2 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x2>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU3:cpu@3 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x3>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; + CPUS L2_0: l2-cache0 { compatible = "cache"; diff --git a/fdts/fvp-foundation-gicv3-psci.dts b/fdts/fvp-foundation-gicv3-psci.dts index d85305afe..c295dc1c8 100644 --- a/fdts/fvp-foundation-gicv3-psci.dts +++ b/fdts/fvp-foundation-gicv3-psci.dts @@ -4,8 +4,15 @@ * SPDX-License-Identifier: BSD-3-Clause */ +/* Configuration: 1 cluster with up to 4 CPUs */ + /dts-v1/; +#define AFF +#define CLUSTER_COUNT 1 + +#include "fvp-defs.dtsi" + /memreserve/ 0x80000000 0x00010000; / { @@ -42,22 +49,7 @@ #address-cells = <2>; #size-cells = <0>; - cpu-map { - cluster0 { - core0 { - cpu = <&CPU0>; - }; - core1 { - cpu = <&CPU1>; - }; - core2 { - cpu = <&CPU2>; - }; - core3 { - cpu = <&CPU3>; - }; - }; - }; + CPU_MAP idle-states { entry-method = "arm,psci"; @@ -81,41 +73,7 @@ }; }; - CPU0:cpu@0 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x0>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU1:cpu@1 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x1>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU2:cpu@2 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x2>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; - - CPU3:cpu@3 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x3>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; - next-level-cache = <&L2_0>; - }; + CPUS L2_0: l2-cache0 { compatible = "cache"; -- cgit v1.2.3 From 30ee3755d0a6f6e2f5aada0dc4b73ea2c3963eee Mon Sep 17 00:00:00 2001 From: Max Shvetsov Date: Wed, 13 May 2020 18:15:39 +0100 Subject: Fix exception in save/restore of EL2 registers. Removing FPEXC32_EL2 from the register save/restore routine for EL2 registers since it is already a part of save/restore routine for fpregs. Signed-off-by: Max Shvetsov Change-Id: I5ed45fdbf7c8efa8dcfcd96586328d4f6b256bc4 --- include/lib/el3_runtime/aarch64/context.h | 119 +++++++++++++------------- lib/el3_runtime/aarch64/context.S | 134 +++++++++++++++--------------- 2 files changed, 124 insertions(+), 129 deletions(-) diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h index 0029658ac..90807cec6 100644 --- a/include/lib/el3_runtime/aarch64/context.h +++ b/include/lib/el3_runtime/aarch64/context.h @@ -168,76 +168,75 @@ #define CTX_ELR_EL2 U(0x58) #define CTX_ESR_EL2 U(0x60) #define CTX_FAR_EL2 U(0x68) -#define CTX_FPEXC32_EL2 U(0x70) -#define CTX_HACR_EL2 U(0x78) -#define CTX_HCR_EL2 U(0x80) -#define CTX_HPFAR_EL2 U(0x88) -#define CTX_HSTR_EL2 U(0x90) -#define CTX_ICC_SRE_EL2 U(0x98) -#define CTX_ICH_HCR_EL2 U(0xa0) -#define CTX_ICH_VMCR_EL2 U(0xa8) -#define CTX_MAIR_EL2 U(0xb0) -#define CTX_MDCR_EL2 U(0xb8) -#define CTX_PMSCR_EL2 U(0xc0) -#define CTX_SCTLR_EL2 U(0xc8) -#define CTX_SPSR_EL2 U(0xd0) -#define CTX_SP_EL2 U(0xd8) -#define CTX_TCR_EL2 U(0xe0) -#define CTX_TPIDR_EL2 U(0xe8) -#define CTX_TTBR0_EL2 U(0xf0) -#define CTX_VBAR_EL2 U(0xf8) -#define CTX_VMPIDR_EL2 U(0x100) -#define CTX_VPIDR_EL2 U(0x108) -#define CTX_VTCR_EL2 U(0x110) -#define CTX_VTTBR_EL2 U(0x118) +#define CTX_HACR_EL2 U(0x70) +#define CTX_HCR_EL2 U(0x78) +#define CTX_HPFAR_EL2 U(0x80) +#define CTX_HSTR_EL2 U(0x88) +#define CTX_ICC_SRE_EL2 U(0x90) +#define CTX_ICH_HCR_EL2 U(0x98) +#define CTX_ICH_VMCR_EL2 U(0xa0) +#define CTX_MAIR_EL2 U(0xa8) +#define CTX_MDCR_EL2 U(0xb0) +#define CTX_PMSCR_EL2 U(0xb8) +#define CTX_SCTLR_EL2 U(0xc0) +#define CTX_SPSR_EL2 U(0xc8) +#define CTX_SP_EL2 U(0xd0) +#define CTX_TCR_EL2 U(0xd8) +#define CTX_TPIDR_EL2 U(0xe0) +#define CTX_TTBR0_EL2 U(0xe8) +#define CTX_VBAR_EL2 U(0xf0) +#define CTX_VMPIDR_EL2 U(0xf8) +#define CTX_VPIDR_EL2 U(0x100) +#define CTX_VTCR_EL2 U(0x108) +#define CTX_VTTBR_EL2 U(0x110) // Only if MTE registers in use -#define CTX_TFSR_EL2 U(0x120) +#define CTX_TFSR_EL2 U(0x118) // Only if ENABLE_MPAM_FOR_LOWER_ELS==1 -#define CTX_MPAM2_EL2 U(0x128) -#define CTX_MPAMHCR_EL2 U(0x130) -#define CTX_MPAMVPM0_EL2 U(0x138) -#define CTX_MPAMVPM1_EL2 U(0x140) -#define CTX_MPAMVPM2_EL2 U(0x148) -#define CTX_MPAMVPM3_EL2 U(0x150) -#define CTX_MPAMVPM4_EL2 U(0x158) -#define CTX_MPAMVPM5_EL2 U(0x160) -#define CTX_MPAMVPM6_EL2 U(0x168) -#define CTX_MPAMVPM7_EL2 U(0x170) -#define CTX_MPAMVPMV_EL2 U(0x178) +#define CTX_MPAM2_EL2 U(0x120) +#define CTX_MPAMHCR_EL2 U(0x128) +#define CTX_MPAMVPM0_EL2 U(0x130) +#define CTX_MPAMVPM1_EL2 U(0x138) +#define CTX_MPAMVPM2_EL2 U(0x140) +#define CTX_MPAMVPM3_EL2 U(0x148) +#define CTX_MPAMVPM4_EL2 U(0x150) +#define CTX_MPAMVPM5_EL2 U(0x158) +#define CTX_MPAMVPM6_EL2 U(0x160) +#define CTX_MPAMVPM7_EL2 U(0x168) +#define CTX_MPAMVPMV_EL2 U(0x170) // Starting with Armv8.6 -#define CTX_HAFGRTR_EL2 U(0x180) -#define CTX_HDFGRTR_EL2 U(0x188) -#define CTX_HDFGWTR_EL2 U(0x190) -#define CTX_HFGITR_EL2 U(0x198) -#define CTX_HFGRTR_EL2 U(0x1a0) -#define CTX_HFGWTR_EL2 U(0x1a8) -#define CTX_CNTPOFF_EL2 U(0x1b0) +#define CTX_HAFGRTR_EL2 U(0x178) +#define CTX_HDFGRTR_EL2 U(0x180) +#define CTX_HDFGWTR_EL2 U(0x188) +#define CTX_HFGITR_EL2 U(0x190) +#define CTX_HFGRTR_EL2 U(0x198) +#define CTX_HFGWTR_EL2 U(0x1a0) +#define CTX_CNTPOFF_EL2 U(0x1a8) // Starting with Armv8.4 -#define CTX_CNTHPS_CTL_EL2 U(0x1b8) -#define CTX_CNTHPS_CVAL_EL2 U(0x1c0) -#define CTX_CNTHPS_TVAL_EL2 U(0x1c8) -#define CTX_CNTHVS_CTL_EL2 U(0x1d0) -#define CTX_CNTHVS_CVAL_EL2 U(0x1d8) -#define CTX_CNTHVS_TVAL_EL2 U(0x1e0) -#define CTX_CNTHV_CTL_EL2 U(0x1e8) -#define CTX_CNTHV_CVAL_EL2 U(0x1f0) -#define CTX_CNTHV_TVAL_EL2 U(0x1f8) -#define CTX_CONTEXTIDR_EL2 U(0x200) -#define CTX_SDER32_EL2 U(0x208) -#define CTX_TTBR1_EL2 U(0x210) -#define CTX_VDISR_EL2 U(0x218) -#define CTX_VNCR_EL2 U(0x220) -#define CTX_VSESR_EL2 U(0x228) -#define CTX_VSTCR_EL2 U(0x230) -#define CTX_VSTTBR_EL2 U(0x238) -#define CTX_TRFCR_EL2 U(0x240) +#define CTX_CNTHPS_CTL_EL2 U(0x1b0) +#define CTX_CNTHPS_CVAL_EL2 U(0x1b8) +#define CTX_CNTHPS_TVAL_EL2 U(0x1c0) +#define CTX_CNTHVS_CTL_EL2 U(0x1c8) +#define CTX_CNTHVS_CVAL_EL2 U(0x1d0) +#define CTX_CNTHVS_TVAL_EL2 U(0x1d8) +#define CTX_CNTHV_CTL_EL2 U(0x1e0) +#define CTX_CNTHV_CVAL_EL2 U(0x1e8) +#define CTX_CNTHV_TVAL_EL2 U(0x1f0) +#define CTX_CONTEXTIDR_EL2 U(0x1f8) +#define CTX_SDER32_EL2 U(0x200) +#define CTX_TTBR1_EL2 U(0x208) +#define CTX_VDISR_EL2 U(0x210) +#define CTX_VNCR_EL2 U(0x218) +#define CTX_VSESR_EL2 U(0x220) +#define CTX_VSTCR_EL2 U(0x228) +#define CTX_VSTTBR_EL2 U(0x230) +#define CTX_TRFCR_EL2 U(0x238) // Starting with Armv8.5 -#define CTX_SCXTNUM_EL2 U(0x248) +#define CTX_SCXTNUM_EL2 U(0x240) /* Align to the next 16 byte boundary */ #define CTX_EL2_SYSREGS_END U(0x250) diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S index 984468a53..1568ef05b 100644 --- a/lib/el3_runtime/aarch64/context.S +++ b/lib/el3_runtime/aarch64/context.S @@ -71,53 +71,52 @@ func el2_sysregs_context_save mrs x15, far_el2 stp x14, x15, [x0, #CTX_ESR_EL2] - mrs x16, fpexc32_el2 - mrs x17, hacr_el2 - stp x16, x17, [x0, #CTX_FPEXC32_EL2] + mrs x16, hacr_el2 + mrs x17, hcr_el2 + stp x16, x17, [x0, #CTX_HACR_EL2] - mrs x9, hcr_el2 - mrs x10, hpfar_el2 - stp x9, x10, [x0, #CTX_HCR_EL2] + mrs x9, hpfar_el2 + mrs x10, hstr_el2 + stp x9, x10, [x0, #CTX_HPFAR_EL2] - mrs x11, hstr_el2 - mrs x12, ICC_SRE_EL2 - stp x11, x12, [x0, #CTX_HSTR_EL2] + mrs x11, ICC_SRE_EL2 + mrs x12, ICH_HCR_EL2 + stp x11, x12, [x0, #CTX_ICC_SRE_EL2] - mrs x13, ICH_HCR_EL2 - mrs x14, ICH_VMCR_EL2 - stp x13, x14, [x0, #CTX_ICH_HCR_EL2] + mrs x13, ICH_VMCR_EL2 + mrs x14, mair_el2 + stp x13, x14, [x0, #CTX_ICH_VMCR_EL2] - mrs x15, mair_el2 - mrs x16, mdcr_el2 - stp x15, x16, [x0, #CTX_MAIR_EL2] + mrs x15, mdcr_el2 + mrs x16, PMSCR_EL2 + stp x15, x16, [x0, #CTX_MDCR_EL2] - mrs x17, PMSCR_EL2 - mrs x9, sctlr_el2 - stp x17, x9, [x0, #CTX_PMSCR_EL2] + mrs x17, sctlr_el2 + mrs x9, spsr_el2 + stp x17, x9, [x0, #CTX_SCTLR_EL2] - mrs x10, spsr_el2 - mrs x11, sp_el2 - stp x10, x11, [x0, #CTX_SPSR_EL2] + mrs x10, sp_el2 + mrs x11, tcr_el2 + stp x10, x11, [x0, #CTX_SP_EL2] - mrs x12, tcr_el2 - mrs x13, tpidr_el2 - stp x12, x13, [x0, #CTX_TCR_EL2] + mrs x12, tpidr_el2 + mrs x13, ttbr0_el2 + stp x12, x13, [x0, #CTX_TPIDR_EL2] - mrs x14, ttbr0_el2 - mrs x15, vbar_el2 - stp x14, x15, [x0, #CTX_TTBR0_EL2] + mrs x14, vbar_el2 + mrs x15, vmpidr_el2 + stp x14, x15, [x0, #CTX_VBAR_EL2] - mrs x16, vmpidr_el2 - mrs x17, vpidr_el2 - stp x16, x17, [x0, #CTX_VMPIDR_EL2] + mrs x16, vpidr_el2 + mrs x17, vtcr_el2 + stp x16, x17, [x0, #CTX_VPIDR_EL2] - mrs x9, vtcr_el2 - mrs x10, vttbr_el2 - stp x9, x10, [x0, #CTX_VTCR_EL2] + mrs x9, vttbr_el2 + str x9, [x0, #CTX_VTTBR_EL2] #if CTX_INCLUDE_MTE_REGS - mrs x11, TFSR_EL2 - str x11, [x0, #CTX_TFSR_EL2] + mrs x10, TFSR_EL2 + str x10, [x0, #CTX_TFSR_EL2] #endif #if ENABLE_MPAM_FOR_LOWER_ELS @@ -277,51 +276,48 @@ func el2_sysregs_context_restore msr esr_el2, x14 msr far_el2, x15 - ldp x16, x17, [x0, #CTX_FPEXC32_EL2] - msr fpexc32_el2, x16 - msr hacr_el2, x17 - - ldp x9, x10, [x0, #CTX_HCR_EL2] - msr hcr_el2, x9 - msr hpfar_el2, x10 + ldp x16, x17, [x0, #CTX_HACR_EL2] + msr hacr_el2, x16 + msr hcr_el2, x17 - ldp x11, x12, [x0, #CTX_HSTR_EL2] - msr hstr_el2, x11 - msr ICC_SRE_EL2, x12 + ldp x9, x10, [x0, #CTX_HPFAR_EL2] + msr hpfar_el2, x9 + msr hstr_el2, x10 - ldp x13, x14, [x0, #CTX_ICH_HCR_EL2] - msr ICH_HCR_EL2, x13 - msr ICH_VMCR_EL2, x14 + ldp x11, x12, [x0, #CTX_ICC_SRE_EL2] + msr ICC_SRE_EL2, x11 + msr ICH_HCR_EL2, x12 - ldp x15, x16, [x0, #CTX_MAIR_EL2] - msr mair_el2, x15 - msr mdcr_el2, x16 + ldp x13, x14, [x0, #CTX_ICH_VMCR_EL2] + msr ICH_VMCR_EL2, x13 + msr mair_el2, x14 - ldr x17, [x0, #CTX_PMSCR_EL2] - msr PMSCR_EL2, x17 + ldp x15, x16, [x0, #CTX_MDCR_EL2] + msr mdcr_el2, x15 + msr PMSCR_EL2, x16 - ldp x10, x11, [x0, #CTX_SPSR_EL2] - msr spsr_el2, x10 - msr sp_el2, x11 + ldp x17, x9, [x0, #CTX_SPSR_EL2] + msr spsr_el2, x17 + msr sp_el2, x9 - ldr x12, [x0, #CTX_TPIDR_EL2] - msr tpidr_el2, x12 + ldp x10, x11, [x0, #CTX_TPIDR_EL2] + msr tpidr_el2, x10 + msr ttbr0_el2, x11 - ldp x14, x15, [x0, #CTX_TTBR0_EL2] - msr ttbr0_el2, x14 - msr vbar_el2, x15 + ldp x12, x13, [x0, #CTX_VBAR_EL2] + msr vbar_el2, x12 + msr vmpidr_el2, x13 - ldp x16, x17, [x0, #CTX_VMPIDR_EL2] - msr vmpidr_el2, x16 - msr vpidr_el2, x17 + ldp x14, x15, [x0, #CTX_VPIDR_EL2] + msr vpidr_el2, x14 + msr vtcr_el2, x15 - ldp x9, x10, [x0, #CTX_VTCR_EL2] - msr vtcr_el2, x9 - msr vttbr_el2, x10 + ldr x16, [x0, #CTX_VTTBR_EL2] + msr vttbr_el2, x16 #if CTX_INCLUDE_MTE_REGS - ldr x11, [x0, #CTX_TFSR_EL2] - msr TFSR_EL2, x11 + ldr x17, [x0, #CTX_TFSR_EL2] + msr TFSR_EL2, x17 #endif #if ENABLE_MPAM_FOR_LOWER_ELS -- cgit v1.2.3 From 8370c8ce3c7689b2de4b84b2d8d65b0048bdc8eb Mon Sep 17 00:00:00 2001 From: laurenw-arm Date: Tue, 12 May 2020 10:58:11 -0500 Subject: plat/fvp: Populate GICv3 parameters dynamically Query the GICD and GICR base addresses in runtime using fconf getter APIs. Signed-off-by: Lauren Wehrmeister Change-Id: I309fb2874f3329ddeb8677ddb53ed4c02199a1e9 --- plat/arm/board/fvp/fvp_gicv3.c | 119 +++++++++++++++++++++ .../arm/board/fvp/include/fconf_hw_config_getter.h | 4 +- plat/arm/board/fvp/platform.mk | 4 + 3 files changed, 125 insertions(+), 2 deletions(-) create mode 100644 plat/arm/board/fvp/fvp_gicv3.c diff --git a/plat/arm/board/fvp/fvp_gicv3.c b/plat/arm/board/fvp/fvp_gicv3.c new file mode 100644 index 000000000..a3ee8ef1b --- /dev/null +++ b/plat/arm/board/fvp/fvp_gicv3.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +/* The GICv3 driver only needs to be initialized in EL3 */ +static uintptr_t fvp_rdistif_base_addrs[PLATFORM_CORE_COUNT]; + +/* Default GICR base address to be used for GICR probe. */ +static uint64_t fvp_gicr_base_addrs[2] = { 0U }; + +/* List of zero terminated GICR frame addresses which CPUs will probe */ +static uint64_t *fvp_gicr_frames = fvp_gicr_base_addrs; + +static const interrupt_prop_t fvp_interrupt_props[] = { + PLAT_ARM_G1S_IRQ_PROPS(INTR_GROUP1S), + PLAT_ARM_G0_IRQ_PROPS(INTR_GROUP0) +}; + +/* + * MPIDR hashing function for translating MPIDRs read from GICR_TYPER register + * to core position. + * + * Calculating core position is dependent on MPIDR_EL1.MT bit. However, affinity + * values read from GICR_TYPER don't have an MT field. To reuse the same + * translation used for CPUs, we insert MT bit read from the PE's MPIDR into + * that read from GICR_TYPER. + * + * Assumptions: + * + * - All CPUs implemented in the system have MPIDR_EL1.MT bit set; + * - No CPUs implemented in the system use affinity level 3. + */ +static unsigned int fvp_gicv3_mpidr_hash(u_register_t mpidr) +{ + u_register_t temp_mpidr = mpidr; + + temp_mpidr |= (read_mpidr_el1() & MPIDR_MT_MASK); + return plat_arm_calc_core_pos(temp_mpidr); +} + + +static gicv3_driver_data_t fvp_gic_data = { + .interrupt_props = fvp_interrupt_props, + .interrupt_props_num = ARRAY_SIZE(fvp_interrupt_props), + .rdistif_num = PLATFORM_CORE_COUNT, + .rdistif_base_addrs = fvp_rdistif_base_addrs, + .mpidr_to_core_pos = fvp_gicv3_mpidr_hash +}; + +void plat_arm_gic_driver_init(void) +{ + /* Get GICD and GICR base addressed through FCONF APIs */ +#if (!defined(__aarch64__) && defined(IMAGE_BL32)) || \ + (defined(__aarch64__) && defined(IMAGE_BL31)) + fvp_gic_data.gicd_base = (uintptr_t)FCONF_GET_PROPERTY(hw_config, + gicv3_config, + gicd_base); + fvp_gicr_base_addrs[0] = FCONF_GET_PROPERTY(hw_config, gicv3_config, + gicr_base); +#else + fvp_gic_data.gicd_base = PLAT_ARM_GICD_BASE; + fvp_gicr_base_addrs[0] = PLAT_ARM_GICR_BASE; +#endif + + /* + * The GICv3 driver is initialized in EL3 and does not need + * to be initialized again in SEL1. This is because the S-EL1 + * can use GIC system registers to manage interrupts and does + * not need GIC interface base addresses to be configured. + */ + +#if (!defined(__aarch64__) && defined(IMAGE_BL32)) || \ + (defined(__aarch64__) && defined(IMAGE_BL31)) + gicv3_driver_init(&fvp_gic_data); + if (gicv3_rdistif_probe((uintptr_t)fvp_gicr_base_addrs[0]) == -1) { + ERROR("No GICR base frame found for Primary CPU\n"); + panic(); + } +#endif +} + +/****************************************************************************** + * Function to iterate over all GICR frames and discover the corresponding + * per-cpu redistributor frame as well as initialize the corresponding + * interface in GICv3. + *****************************************************************************/ +void plat_arm_gic_pcpu_init(void) +{ + int result; + const uint64_t *plat_gicr_frames = fvp_gicr_frames; + + do { + result = gicv3_rdistif_probe(*plat_gicr_frames); + + /* If the probe is successful, no need to proceed further */ + if (result == 0) + break; + + plat_gicr_frames++; + } while (*plat_gicr_frames != 0U); + + if (result == -1) { + ERROR("No GICR base frame found for CPU 0x%lx\n", read_mpidr()); + panic(); + } + gicv3_rdistif_init(plat_my_core_pos()); +} diff --git a/plat/arm/board/fvp/include/fconf_hw_config_getter.h b/plat/arm/board/fvp/include/fconf_hw_config_getter.h index a9e569e78..dbce0e424 100644 --- a/plat/arm/board/fvp/include/fconf_hw_config_getter.h +++ b/plat/arm/board/fvp/include/fconf_hw_config_getter.h @@ -15,8 +15,8 @@ #define hw_config__topology_getter(prop) soc_topology.prop struct gicv3_config_t { - uintptr_t gicd_base; - uintptr_t gicr_base; + uint64_t gicd_base; + uint64_t gicr_base; }; struct hw_topology_t { diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 04cebcac3..a88ec1336 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -65,6 +65,10 @@ FVP_GIC_SOURCES := ${GICV3_SOURCES} \ plat/common/plat_gicv3.c \ plat/arm/common/arm_gicv3.c + ifeq ($(filter 1,${BL2_AT_EL3} ${RESET_TO_BL31} ${RESET_TO_SP_MIN}),) + FVP_GIC_SOURCES += plat/arm/board/fvp/fvp_gicv3.c + endif + else ifeq (${FVP_USE_GIC_DRIVER}, FVP_GICV2) # No GICv4 extension -- cgit v1.2.3 From 6cac724d52cc8d6cac9b47f186cc47f4b3cf6bd6 Mon Sep 17 00:00:00 2001 From: johpow01 Date: Wed, 22 Apr 2020 14:05:13 -0500 Subject: Enable v8.6 WFE trap delays This patch enables the v8.6 extension to add a delay before WFE traps are taken. A weak hook plat_arm_set_twedel_scr_el3 has been added in plat/common/aarch64/plat_common.c that disables this feature by default but platform-specific code can override it when needed. The only hook provided sets the TWED fields in SCR_EL3, there are similar fields in HCR_EL2, SCTLR_EL2, and SCTLR_EL1 to control WFE trap delays in lower ELs but these should be configured by code running at EL2 and/or EL1 depending on the platform configuration and is outside the scope of TF-A. Signed-off-by: John Powell Change-Id: I0a9bb814205efeab693a3d0a0623e62144abba2d --- docs/getting_started/porting-guide.rst | 15 +++++++++++++++ include/arch/aarch64/arch.h | 9 +++++++++ include/arch/aarch64/arch_features.h | 6 ++++++ include/arch/aarch64/arch_helpers.h | 1 + include/lib/extensions/twed.h | 16 ++++++++++++++++ lib/el3_runtime/aarch64/context_mgmt.c | 19 +++++++++++++++++++ plat/common/aarch64/plat_common.c | 15 +++++++++++++++ 7 files changed, 81 insertions(+) create mode 100644 include/lib/extensions/twed.h diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst index 2d17f122a..2ad725632 100644 --- a/docs/getting_started/porting-guide.rst +++ b/docs/getting_started/porting-guide.rst @@ -1890,6 +1890,21 @@ frequency for the CPU's generic timer. This value will be programmed into the of the system counter, which is retrieved from the first entry in the frequency modes table. +Function : plat_arm_set_twedel_scr_el3() [optional] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : uint32_t + +This function is used in v8.6+ systems to set the WFE trap delay value in +SCR_EL3. If this function returns TWED_DISABLED or is left unimplemented, this +feature is not enabled. The only hook provided is to set the TWED fields in +SCR_EL3, there are similar fields in HCR_EL2, SCTLR_EL2, and SCTLR_EL1 to adjust +the WFE trap delays in lower ELs and these fields should be set by the +appropriate EL2 or EL1 code depending on the platform configuration. + #define : PLAT_PERCPU_BAKERY_LOCK_SIZE [optional] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index 81e0f271e..92e673771 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -226,6 +226,12 @@ #define ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED ULL(0x1) #define ID_AA64MMFR0_EL1_TGRAN16_NOT_SUPPORTED ULL(0x0) +/* ID_AA64MMFR1_EL1 definitions */ +#define ID_AA64MMFR1_EL1_TWED_SHIFT U(32) +#define ID_AA64MMFR1_EL1_TWED_MASK ULL(0xf) +#define ID_AA64MMFR1_EL1_TWED_SUPPORTED ULL(0x1) +#define ID_AA64MMFR1_EL1_TWED_NOT_SUPPORTED ULL(0x0) + /* ID_AA64MMFR2_EL1 definitions */ #define ID_AA64MMFR2_EL1 S3_0_C0_C7_2 @@ -312,6 +318,9 @@ /* SCR definitions */ #define SCR_RES1_BITS ((U(1) << 4) | (U(1) << 5)) +#define SCR_TWEDEL_SHIFT U(30) +#define SCR_TWEDEL_MASK ULL(0xf) +#define SCR_TWEDEn_BIT (UL(1) << 29) #define SCR_ATA_BIT (U(1) << 26) #define SCR_FIEN_BIT (U(1) << 21) #define SCR_EEL2_BIT (U(1) << 18) diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h index 9513e977d..49d827dba 100644 --- a/include/arch/aarch64/arch_features.h +++ b/include/arch/aarch64/arch_features.h @@ -58,4 +58,10 @@ static inline bool is_armv8_4_sel2_present(void) ID_AA64PFR0_SEL2_MASK) == 1ULL; } +static inline bool is_armv8_6_twed_present(void) +{ + return (((read_id_aa64mmfr1_el1() >> ID_AA64MMFR1_EL1_TWED_SHIFT) & + ID_AA64MMFR1_EL1_TWED_MASK) == ID_AA64MMFR1_EL1_TWED_SUPPORTED); +} + #endif /* ARCH_FEATURES_H */ diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h index 9cd1ae515..09059ca80 100644 --- a/include/arch/aarch64/arch_helpers.h +++ b/include/arch/aarch64/arch_helpers.h @@ -358,6 +358,7 @@ void __dead2 smc(uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3, DEFINE_SYSREG_READ_FUNC(midr_el1) DEFINE_SYSREG_READ_FUNC(mpidr_el1) DEFINE_SYSREG_READ_FUNC(id_aa64mmfr0_el1) +DEFINE_SYSREG_READ_FUNC(id_aa64mmfr1_el1) DEFINE_SYSREG_RW_FUNCS(scr_el3) DEFINE_SYSREG_RW_FUNCS(hcr_el2) diff --git a/include/lib/extensions/twed.h b/include/lib/extensions/twed.h new file mode 100644 index 000000000..eac4aa314 --- /dev/null +++ b/include/lib/extensions/twed.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef TWED_H +#define TWED_H + +#include + +#define TWED_DISABLED U(0xFFFFFFFF) + +uint32_t plat_arm_set_twedel_scr_el3(void); + +#endif /* TWEDE_H */ diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c index 0314a8511..64a2d7b5c 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 @@ -229,6 +230,24 @@ void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep) sctlr_elx |= SCTLR_IESB_BIT; #endif + /* Enable WFE trap delay in SCR_EL3 if supported and configured */ + if (is_armv8_6_twed_present()) { + uint32_t delay = plat_arm_set_twedel_scr_el3(); + + if (delay != TWED_DISABLED) { + /* Make sure delay value fits */ + assert((delay & ~SCR_TWEDEL_MASK) == 0U); + + /* Set delay in SCR_EL3 */ + scr_el3 &= ~(SCR_TWEDEL_MASK << SCR_TWEDEL_SHIFT); + scr_el3 |= ((delay & SCR_TWEDEL_MASK) + << SCR_TWEDEL_SHIFT); + + /* Enable WFE delay */ + scr_el3 |= SCR_TWEDEn_BIT; + } + } + /* * Store the initialised SCTLR_EL1 value in the cpu_context - SCTLR_EL2 * and other EL2 registers are set up by cm_prepare_ns_entry() as they diff --git a/plat/common/aarch64/plat_common.c b/plat/common/aarch64/plat_common.c index 63871d9e5..b8a4d012e 100644 --- a/plat/common/aarch64/plat_common.c +++ b/plat/common/aarch64/plat_common.c @@ -11,6 +11,7 @@ #if RAS_EXTENSION #include #endif +#include #include #include @@ -20,6 +21,7 @@ * platforms but may also be overridden by a platform if required. */ #pragma weak bl31_plat_runtime_setup +#pragma weak plat_arm_set_twedel_scr_el3 #if SDEI_SUPPORT #pragma weak plat_sdei_handle_masked_trigger @@ -100,3 +102,16 @@ void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie, #endif panic(); } + +/******************************************************************************* + * In v8.6+ platforms with delayed trapping of WFE this hook sets the delay. It + * is a weak function definition so can be overridden depending on the + * requirements of a platform. The only hook provided is for the TWED fields + * in SCR_EL3, the TWED fields in HCR_EL2, SCTLR_EL2, and SCTLR_EL1 should be + * configured as needed in lower exception levels. + ******************************************************************************/ + +uint32_t plat_arm_set_twedel_scr_el3(void) +{ + return TWED_DISABLED; +} -- cgit v1.2.3 From d886628de6a0863571f7e6a29b218c5669d4e551 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Fri, 17 Apr 2020 19:09:21 -0700 Subject: Tegra: enable SDEI handling This patch enables SDEI support for all Tegra platforms, with the following configuration settings. * SGI 8 as the source IRQ * Special Private Event 0 * Three private, dynamic events * Three shared, dynamic events * Twelve general purpose explicit events Verified using TFTF SDEI test suite. ******************************* Summary ******************************* Test suite 'SDEI' Passed ================================= Tests Skipped : 0 Tests Passed : 5 Tests Failed : 0 Tests Crashed : 0 Total tests : 5 ================================= Signed-off-by: Varun Wadekar Change-Id: I1922069931a7876a4594e53260ee09f2e4f09390 --- plat/nvidia/tegra/common/tegra_common.mk | 4 ++- plat/nvidia/tegra/common/tegra_ehf.c | 28 ++++++++++++++++ plat/nvidia/tegra/common/tegra_fiq_glue.c | 9 ----- plat/nvidia/tegra/common/tegra_sdei.c | 56 +++++++++++++++++++++++++++++++ plat/nvidia/tegra/include/platform_def.h | 34 +++++++++++++++++++ plat/nvidia/tegra/platform.mk | 4 +++ plat/nvidia/tegra/soc/t186/plat_setup.c | 2 ++ plat/nvidia/tegra/soc/t194/plat_setup.c | 2 ++ plat/nvidia/tegra/soc/t210/plat_setup.c | 2 ++ 9 files changed, 131 insertions(+), 10 deletions(-) create mode 100644 plat/nvidia/tegra/common/tegra_ehf.c create mode 100644 plat/nvidia/tegra/common/tegra_sdei.c diff --git a/plat/nvidia/tegra/common/tegra_common.mk b/plat/nvidia/tegra/common/tegra_common.mk index 79cc03ac9..a86a31535 100644 --- a/plat/nvidia/tegra/common/tegra_common.mk +++ b/plat/nvidia/tegra/common/tegra_common.mk @@ -28,11 +28,13 @@ BL31_SOURCES += drivers/delay_timer/delay_timer.c \ ${COMMON_DIR}/lib/debug/profiler.c \ ${COMMON_DIR}/tegra_bl31_setup.c \ ${COMMON_DIR}/tegra_delay_timer.c \ + ${COMMON_DIR}/tegra_ehf.c \ ${COMMON_DIR}/tegra_fiq_glue.c \ ${COMMON_DIR}/tegra_io_storage.c \ ${COMMON_DIR}/tegra_platform.c \ ${COMMON_DIR}/tegra_pm.c \ - ${COMMON_DIR}/tegra_sip_calls.c + ${COMMON_DIR}/tegra_sip_calls.c \ + ${COMMON_DIR}/tegra_sdei.c ifneq ($(ENABLE_STACK_PROTECTOR), 0) BL31_SOURCES += ${COMMON_DIR}/tegra_stack_protector.c diff --git a/plat/nvidia/tegra/common/tegra_ehf.c b/plat/nvidia/tegra/common/tegra_ehf.c new file mode 100644 index 000000000..ea6e443f3 --- /dev/null +++ b/plat/nvidia/tegra/common/tegra_ehf.c @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include + +/* + * Enumeration of priority levels on Tegra platforms. + */ +ehf_pri_desc_t tegra_exceptions[] = { + /* Watchdog priority */ + EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_TEGRA_WDT_PRIO), + +#if SDEI_SUPPORT + /* Critical priority SDEI */ + EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_SDEI_CRITICAL_PRI), + + /* Normal priority SDEI */ + EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_SDEI_NORMAL_PRI), +#endif +}; + +/* Plug in Tegra exceptions to Exception Handling Framework. */ +EHF_REGISTER_PRIORITIES(tegra_exceptions, ARRAY_SIZE(tegra_exceptions), PLAT_PRI_BITS); diff --git a/plat/nvidia/tegra/common/tegra_fiq_glue.c b/plat/nvidia/tegra/common/tegra_fiq_glue.c index bb5add819..5309d98cd 100644 --- a/plat/nvidia/tegra/common/tegra_fiq_glue.c +++ b/plat/nvidia/tegra/common/tegra_fiq_glue.c @@ -26,15 +26,6 @@ /* Legacy FIQ used by earlier Tegra platforms */ #define LEGACY_FIQ_PPI_WDT 28U -/* Install priority level descriptors for each dispatcher */ -ehf_pri_desc_t plat_exceptions[] = { - EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_TEGRA_WDT_PRIO), -}; - -/* Expose priority descriptors to Exception Handling Framework */ -EHF_REGISTER_PRIORITIES(plat_exceptions, ARRAY_SIZE(plat_exceptions), - PLAT_PRI_BITS); - /******************************************************************************* * Static variables ******************************************************************************/ diff --git a/plat/nvidia/tegra/common/tegra_sdei.c b/plat/nvidia/tegra/common/tegra_sdei.c new file mode 100644 index 000000000..9241b8172 --- /dev/null +++ b/plat/nvidia/tegra/common/tegra_sdei.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* SDEI configuration for Tegra platforms */ + +#include + +#include +#include +#include +#include +#include + +/* Private event mappings */ +static sdei_ev_map_t tegra_sdei_private[] = { + /* Event 0 definition */ + SDEI_DEFINE_EVENT_0(TEGRA_SDEI_SGI_PRIVATE), + + /* Dynamic private events */ + SDEI_PRIVATE_EVENT(TEGRA_SDEI_DP_EVENT_0, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC), + SDEI_PRIVATE_EVENT(TEGRA_SDEI_DP_EVENT_1, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC), + SDEI_PRIVATE_EVENT(TEGRA_SDEI_DP_EVENT_2, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC), + + /* General purpose explicit events */ + SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_0, SDEI_MAPF_CRITICAL), + SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_1, SDEI_MAPF_CRITICAL), + SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_2, SDEI_MAPF_CRITICAL), + SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_3, SDEI_MAPF_CRITICAL), + SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_4, SDEI_MAPF_CRITICAL), + SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_5, SDEI_MAPF_CRITICAL), + SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_6, SDEI_MAPF_CRITICAL), + SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_7, SDEI_MAPF_CRITICAL), + SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_8, SDEI_MAPF_CRITICAL), + SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_9, SDEI_MAPF_CRITICAL), + SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_10, SDEI_MAPF_CRITICAL), + SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_11, SDEI_MAPF_CRITICAL) +}; + +/* Shared event mappings */ +static sdei_ev_map_t tegra_sdei_shared[] = { + /* Dynamic shared events */ + SDEI_SHARED_EVENT(TEGRA_SDEI_DS_EVENT_0, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC), + SDEI_SHARED_EVENT(TEGRA_SDEI_DS_EVENT_1, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC), + SDEI_SHARED_EVENT(TEGRA_SDEI_DS_EVENT_2, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC) +}; + +void plat_sdei_setup(void) +{ + INFO("SDEI platform setup\n"); +} + +/* Export Tegra SDEI events */ +REGISTER_SDEI_MAP(tegra_sdei_private, tegra_sdei_shared); diff --git a/plat/nvidia/tegra/include/platform_def.h b/plat/nvidia/tegra/include/platform_def.h index 6bfad23e6..678b15c14 100644 --- a/plat/nvidia/tegra/include/platform_def.h +++ b/plat/nvidia/tegra/include/platform_def.h @@ -86,10 +86,44 @@ #define MAX_IO_DEVICES U(0) #define MAX_IO_HANDLES U(0) +/******************************************************************************* + * Platforms macros to support SDEI + ******************************************************************************/ +#define TEGRA_SDEI_SGI_PRIVATE U(8) + /******************************************************************************* * Platform macros to support exception handling framework ******************************************************************************/ #define PLAT_PRI_BITS U(3) +#define PLAT_SDEI_CRITICAL_PRI U(0x20) +#define PLAT_SDEI_NORMAL_PRI U(0x30) #define PLAT_TEGRA_WDT_PRIO U(0x40) +/******************************************************************************* + * SDEI events + ******************************************************************************/ +/* SDEI dynamic private event numbers */ +#define TEGRA_SDEI_DP_EVENT_0 U(100) +#define TEGRA_SDEI_DP_EVENT_1 U(101) +#define TEGRA_SDEI_DP_EVENT_2 U(102) + +/* SDEI dynamic shared event numbers */ +#define TEGRA_SDEI_DS_EVENT_0 U(200) +#define TEGRA_SDEI_DS_EVENT_1 U(201) +#define TEGRA_SDEI_DS_EVENT_2 U(202) + +/* SDEI explicit events */ +#define TEGRA_SDEI_EP_EVENT_0 U(300) +#define TEGRA_SDEI_EP_EVENT_1 U(301) +#define TEGRA_SDEI_EP_EVENT_2 U(302) +#define TEGRA_SDEI_EP_EVENT_3 U(303) +#define TEGRA_SDEI_EP_EVENT_4 U(304) +#define TEGRA_SDEI_EP_EVENT_5 U(305) +#define TEGRA_SDEI_EP_EVENT_6 U(306) +#define TEGRA_SDEI_EP_EVENT_7 U(307) +#define TEGRA_SDEI_EP_EVENT_8 U(308) +#define TEGRA_SDEI_EP_EVENT_9 U(309) +#define TEGRA_SDEI_EP_EVENT_10 U(310) +#define TEGRA_SDEI_EP_EVENT_11 U(311) + #endif /* PLATFORM_DEF_H */ diff --git a/plat/nvidia/tegra/platform.mk b/plat/nvidia/tegra/platform.mk index aedd3c6ff..3d61f0656 100644 --- a/plat/nvidia/tegra/platform.mk +++ b/plat/nvidia/tegra/platform.mk @@ -52,6 +52,9 @@ RELOCATE_BL32_IMAGE ?= 0 # Enable stack protection ENABLE_STACK_PROTECTOR := strong +# Enable SDEI +SDEI_SUPPORT := 1 + include plat/nvidia/tegra/common/tegra_common.mk include ${SOC_DIR}/platform_${TARGET_SOC}.mk @@ -66,6 +69,7 @@ TF_CFLAGS += -Wsign-compare -nostdlib # override with necessary libc files for the Tegra platform override LIBC_SRCS := $(addprefix lib/libc/, \ + aarch64/setjmp.S \ assert.c \ memcpy.c \ memmove.c \ diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c index 1c7c25d0f..c216b5d51 100644 --- a/plat/nvidia/tegra/soc/t186/plat_setup.c +++ b/plat/nvidia/tegra/soc/t186/plat_setup.c @@ -214,6 +214,8 @@ void plat_late_platform_setup(void) /* Secure IRQs for Tegra186 */ static const interrupt_prop_t tegra186_interrupt_props[] = { + INTR_PROP_DESC(TEGRA_SDEI_SGI_PRIVATE, PLAT_SDEI_CRITICAL_PRI, + GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE), INTR_PROP_DESC(TEGRA186_TOP_WDT_IRQ, PLAT_TEGRA_WDT_PRIO, GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE), INTR_PROP_DESC(TEGRA186_AON_WDT_IRQ, PLAT_TEGRA_WDT_PRIO, diff --git a/plat/nvidia/tegra/soc/t194/plat_setup.c b/plat/nvidia/tegra/soc/t194/plat_setup.c index f90a69e27..5d6c60b6c 100644 --- a/plat/nvidia/tegra/soc/t194/plat_setup.c +++ b/plat/nvidia/tegra/soc/t194/plat_setup.c @@ -275,6 +275,8 @@ void plat_early_platform_setup(void) /* Secure IRQs for Tegra194 */ static const interrupt_prop_t tegra194_interrupt_props[] = { + INTR_PROP_DESC(TEGRA_SDEI_SGI_PRIVATE, PLAT_SDEI_CRITICAL_PRI, + GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE), INTR_PROP_DESC(TEGRA194_TOP_WDT_IRQ, PLAT_TEGRA_WDT_PRIO, GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE), INTR_PROP_DESC(TEGRA194_AON_WDT_IRQ, PLAT_TEGRA_WDT_PRIO, diff --git a/plat/nvidia/tegra/soc/t210/plat_setup.c b/plat/nvidia/tegra/soc/t210/plat_setup.c index 930eeac3a..f2b267b21 100644 --- a/plat/nvidia/tegra/soc/t210/plat_setup.c +++ b/plat/nvidia/tegra/soc/t210/plat_setup.c @@ -179,6 +179,8 @@ void plat_early_platform_setup(void) /* Secure IRQs for Tegra186 */ static const interrupt_prop_t tegra210_interrupt_props[] = { + INTR_PROP_DESC(TEGRA_SDEI_SGI_PRIVATE, PLAT_SDEI_CRITICAL_PRI, + GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE), INTR_PROP_DESC(TEGRA210_TIMER1_IRQ, PLAT_TEGRA_WDT_PRIO, GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE), INTR_PROP_DESC(TEGRA210_WDT_CPU_LEGACY_FIQ, PLAT_TEGRA_WDT_PRIO, -- cgit v1.2.3 From 447870bf0d6619c2e0f3afd483cc22834a3d7500 Mon Sep 17 00:00:00 2001 From: Madhukar Pappireddy Date: Tue, 24 Mar 2020 10:03:34 -0500 Subject: plat/fvp: Support for extracting UART serial node info from DT This patch introduces the populate function which leverages a new driver to extract base address and clk frequency properties of the uart serial node from HW_CONFIG device tree. This patch also introduces fdt helper API fdtw_translate_address() which helps in performing address translation. Change-Id: I053628065ebddbde0c9cb3aa93d838619f502ee3 Signed-off-by: Madhukar Pappireddy --- common/fdt_wrappers.c | 196 +++++++++++++++++++++ include/common/fdt_wrappers.h | 3 + plat/arm/board/fvp/fconf/fconf_hw_config_getter.c | 96 +++++++++- .../arm/board/fvp/include/fconf_hw_config_getter.h | 9 + plat/arm/board/fvp/jmptbl.i | 4 + plat/arm/board/juno/jmptbl.i | 4 + 6 files changed, 311 insertions(+), 1 deletion(-) diff --git a/common/fdt_wrappers.c b/common/fdt_wrappers.c index 1901a2040..5aad14e38 100644 --- a/common/fdt_wrappers.c +++ b/common/fdt_wrappers.c @@ -341,3 +341,199 @@ int fdt_get_stdout_node_offset(const void *dtb) return fdt_path_offset(dtb, path); } + + +/******************************************************************************* + * Only devices which are direct children of root node use CPU address domain. + * All other devices use addresses that are local to the device node and cannot + * directly used by CPU. Device tree provides an address translation mechanism + * through "ranges" property which provides mappings from local address space to + * parent address space. Since a device could be a child of a child node to the + * root node, there can be more than one level of address translation needed to + * map the device local address space to CPU address space. + * fdtw_translate_address() API performs address translation of a local address + * to a global address with help of various helper functions. + ******************************************************************************/ + +static bool fdtw_xlat_hit(const uint32_t *value, int child_addr_size, + int parent_addr_size, int range_size, uint64_t base_address, + uint64_t *translated_addr) +{ + uint64_t local_address, parent_address, addr_range; + + local_address = fdt_read_prop_cells(value, child_addr_size); + parent_address = fdt_read_prop_cells(value + child_addr_size, + parent_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", + local_address, parent_address, addr_range); + + /* Perform range check */ + if ((base_address < local_address) || + (base_address >= local_address + addr_range)) { + return false; + } + + /* 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); + return true; +} + +#define ILLEGAL_ADDR ULL(~0) + +static uint64_t fdtw_search_all_xlat_entries(const void *dtb, + const struct fdt_property *ranges_prop, + int local_bus, uint64_t base_address) +{ + uint64_t translated_addr; + const uint32_t *next_entry; + int parent_bus_node, nxlat_entries, length; + int self_addr_cells, parent_addr_cells, self_size_cells, ncells_xlat; + + /* + * The number of cells in one translation entry in ranges is the sum of + * the following values: + * self#address-cells + parent#address-cells + self#size-cells + * Ex: the iofpga ranges property has one translation entry with 4 cells + * They represent iofpga#addr-cells + motherboard#addr-cells + iofpga#size-cells + * = 1 + 2 + 1 + */ + + parent_bus_node = fdt_parent_offset(dtb, local_bus); + self_addr_cells = fdt_address_cells(dtb, local_bus); + self_size_cells = fdt_size_cells(dtb, local_bus); + parent_addr_cells = fdt_address_cells(dtb, parent_bus_node); + + /* Number of cells per translation entry i.e., mapping */ + ncells_xlat = self_addr_cells + parent_addr_cells + self_size_cells; + + assert(ncells_xlat > 0); + + /* + * Find the number of translations(mappings) specified in the current + * `ranges` property. Note that length represents number of bytes and + * is stored in big endian mode. + */ + length = fdt32_to_cpu(ranges_prop->len); + nxlat_entries = (length/sizeof(uint32_t))/ncells_xlat; + + assert(nxlat_entries > 0); + + next_entry = (const uint32_t *)ranges_prop->data; + + /* Iterate over the entries in the "ranges" */ + for (int i = 0; i < nxlat_entries; i++) { + if (fdtw_xlat_hit(next_entry, self_addr_cells, + parent_addr_cells, self_size_cells, base_address, + &translated_addr)){ + return translated_addr; + } + 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)); + return ILLEGAL_ADDR; +} + + +/******************************************************************************* + * address mapping needs to be done recursively starting from current node to + * root node through all intermediate parent nodes. + * Sample device tree is shown here: + +smb@0,0 { + compatible = "simple-bus"; + + #address-cells = <2>; + #size-cells = <1>; + ranges = <0 0 0 0x08000000 0x04000000>, + <1 0 0 0x14000000 0x04000000>, + <2 0 0 0x18000000 0x04000000>, + <3 0 0 0x1c000000 0x04000000>, + <4 0 0 0x0c000000 0x04000000>, + <5 0 0 0x10000000 0x04000000>; + + motherboard { + arm,v2m-memory-map = "rs1"; + compatible = "arm,vexpress,v2m-p1", "simple-bus"; + #address-cells = <2>; + #size-cells = <1>; + ranges; + + iofpga@3,00000000 { + compatible = "arm,amba-bus", "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 3 0 0x200000>; + v2m_serial1: uart@a0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0a0000 0x1000>; + interrupts = <0 6 4>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + }; +}; + + * As seen above, there are 3 levels of address translations needed. An empty + * `ranges` property denotes identity mapping (as seen in `motherboard` node). + * Each ranges property can map a set of child addresses to parent bus. Hence + * there can be more than 1 (translation) entry in the ranges property as seen + * in the `smb` node which has 6 translation entries. + ******************************************************************************/ + +/* Recursive implementation */ +uint64_t fdtw_translate_address(const void *dtb, int node, + uint64_t base_address) +{ + int length, local_bus_node; + const char *node_name; + uint64_t global_address; + + local_bus_node = fdt_parent_offset(dtb, node); + node_name = fdt_get_name(dtb, local_bus_node, NULL); + + /* + * In the example given above, starting from the leaf node: + * uart@a000 represents the current node + * iofpga@3,00000000 represents the local bus + * motherboard represents the parent bus + */ + + /* Read the ranges property */ + const struct fdt_property *property = fdt_get_property(dtb, + local_bus_node, "ranges", &length); + + if (property == NULL) { + if (local_bus_node == 0) { + /* + * root node doesn't have range property as addresses + * are in CPU address space. + */ + return base_address; + } + INFO("DT: Couldn't find ranges property in node %s\n", + node_name); + return ILLEGAL_ADDR; + } else if (length == 0) { + /* empty ranges indicates identity map to parent bus */ + return fdtw_translate_address(dtb, local_bus_node, base_address); + } + + VERBOSE("DT: Translation lookup in node %s at offset %d\n", node_name, + local_bus_node); + global_address = fdtw_search_all_xlat_entries(dtb, property, + local_bus_node, base_address); + + if (global_address == ILLEGAL_ADDR) { + return ILLEGAL_ADDR; + } + + /* Translate the local device address recursively */ + return fdtw_translate_address(dtb, local_bus_node, global_address); +} diff --git a/include/common/fdt_wrappers.h b/include/common/fdt_wrappers.h index 382651e5d..1d8da1823 100644 --- a/include/common/fdt_wrappers.h +++ b/include/common/fdt_wrappers.h @@ -34,4 +34,7 @@ int fdt_get_reg_props_by_name(const void *dtb, int node, const char *name, uintptr_t *base, size_t *size); int fdt_get_stdout_node_offset(const void *dtb); +uint64_t fdtw_translate_address(const void *dtb, int bus_node, + uint64_t base_address); + #endif /* FDT_WRAPPERS_H */ 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 f1d9b93f7..8172a6ebe 100644 --- a/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c +++ b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c @@ -13,6 +13,9 @@ struct gicv3_config_t gicv3_config; struct hw_topology_t soc_topology; +struct uart_serial_config_t uart_serial_config; + +#define ILLEGAL_ADDR ULL(~0) int fconf_populate_gicv3_config(uintptr_t config) { @@ -147,7 +150,8 @@ int fconf_populate_topology(uintptr_t config) return -1; } - INFO("CLUSTER ID: %d cpu-count: %d\n", cluster_count, cpus_per_cluster[cluster_count]); + VERBOSE("CLUSTER ID: %d cpu-count: %d\n", cluster_count, + cpus_per_cluster[cluster_count]); /* Find the maximum number of cpus in any cluster */ max_cpu_per_cluster = MAX(max_cpu_per_cluster, cpus_per_cluster[cluster_count]); @@ -170,5 +174,95 @@ int fconf_populate_topology(uintptr_t config) return 0; } +int fconf_populate_uart_config(uintptr_t config) +{ + int uart_node, node, err; + uintptr_t addr; + const char *path; + uint32_t phandle; + uint64_t translated_addr; + + /* Necessary to work with libfdt APIs */ + const void *hw_config_dtb = (const void *)config; + + /* + * uart child node is indirectly referenced through its path which is + * specified in the `serial1` property of the "aliases" node. + * Note that TF-A boot console is mapped to serial0 while runtime + * console is mapped to serial1. + */ + + path = fdt_get_alias(hw_config_dtb, "serial1"); + if (path == NULL) { + ERROR("FCONF: Could not read serial1 property in aliases node\n"); + return -1; + } + + /* Find the offset of the uart serial node */ + uart_node = fdt_path_offset(hw_config_dtb, path); + if (uart_node < 0) { + ERROR("FCONF: Failed to locate uart serial node using its path\n"); + return -1; + } + + /* uart serial node has its offset and size of address in reg property */ + err = fdt_get_reg_props_by_index(hw_config_dtb, uart_node, 0, &addr, + NULL); + if (err < 0) { + ERROR("FCONF: Failed to read reg property of '%s' node\n", + "uart serial"); + return err; + } + VERBOSE("FCONF: UART node address: %lx\n", addr); + + /* + * Perform address translation of local device address to CPU address + * domain. + */ + translated_addr = fdtw_translate_address(hw_config_dtb, + uart_node, (uint64_t)addr); + if (translated_addr == ILLEGAL_ADDR) { + ERROR("FCONF: failed to translate UART node base address"); + return -1; + } + + uart_serial_config.uart_base = translated_addr; + + VERBOSE("FCONF: UART serial device base address: %llx\n", + uart_serial_config.uart_base); + + /* + * The phandle of the DT node which captures the clock info of uart + * serial node is specified in the "clocks" property. + */ + err = fdt_read_uint32(hw_config_dtb, uart_node, "clocks", &phandle); + if (err < 0) { + ERROR("FCONF: Could not read clocks property in uart serial node\n"); + return err; + } + + node = fdt_node_offset_by_phandle(hw_config_dtb, phandle); + if (node < 0) { + ERROR("FCONF: Failed to locate clk node using its path\n"); + return node; + } + + /* + * Retrieve clock frequency. We assume clock provider generates a fixed + * clock. + */ + err = fdt_read_uint32(hw_config_dtb, node, "clock-frequency", + &uart_serial_config.uart_clk); + if (err < 0) { + ERROR("FCONF: Could not read clock-frequency property in clk node\n"); + return err; + } + + VERBOSE("FCONF: UART serial device clk frequency: %x\n", + uart_serial_config.uart_clk); + return 0; +} + FCONF_REGISTER_POPULATOR(HW_CONFIG, gicv3_config, fconf_populate_gicv3_config); FCONF_REGISTER_POPULATOR(HW_CONFIG, topology, fconf_populate_topology); +FCONF_REGISTER_POPULATOR(HW_CONFIG, uart_config, fconf_populate_uart_config); diff --git a/plat/arm/board/fvp/include/fconf_hw_config_getter.h b/plat/arm/board/fvp/include/fconf_hw_config_getter.h index a9e569e78..bea7318c8 100644 --- a/plat/arm/board/fvp/include/fconf_hw_config_getter.h +++ b/plat/arm/board/fvp/include/fconf_hw_config_getter.h @@ -14,6 +14,8 @@ #define hw_config__topology_getter(prop) soc_topology.prop +#define hw_config__uart_serial_config_getter(prop) uart_serial_config.prop + struct gicv3_config_t { uintptr_t gicd_base; uintptr_t gicr_base; @@ -26,10 +28,17 @@ struct hw_topology_t { uint32_t plat_max_pwr_level; }; +struct uart_serial_config_t { + uint64_t uart_base; + uint32_t uart_clk; +}; + int fconf_populate_gicv3_config(uintptr_t config); int fconf_populate_topology(uintptr_t config); +int fconf_populate_uart_config(uintptr_t config); extern struct gicv3_config_t gicv3_config; extern struct hw_topology_t soc_topology; +extern struct uart_serial_config_t uart_serial_config; #endif /* FCONF_HW_CONFIG_GETTER_H */ diff --git a/plat/arm/board/fvp/jmptbl.i b/plat/arm/board/fvp/jmptbl.i index 213a9749d..b72bdab4a 100644 --- a/plat/arm/board/fvp/jmptbl.i +++ b/plat/arm/board/fvp/jmptbl.i @@ -16,6 +16,7 @@ rom rom_lib_init fdt fdt_getprop +fdt fdt_get_property fdt fdt_getprop_namelen fdt fdt_setprop_inplace fdt fdt_check_header @@ -31,6 +32,9 @@ fdt fdt_size_cells fdt fdt_parent_offset fdt fdt_stringlist_search fdt fdt_get_alias_namelen +fdt fdt_get_name +fdt fdt_get_alias +fdt fdt_node_offset_by_phandle mbedtls mbedtls_asn1_get_alg mbedtls mbedtls_asn1_get_alg_null mbedtls mbedtls_asn1_get_bitstring_null diff --git a/plat/arm/board/juno/jmptbl.i b/plat/arm/board/juno/jmptbl.i index 09017acdc..20ed2c73c 100644 --- a/plat/arm/board/juno/jmptbl.i +++ b/plat/arm/board/juno/jmptbl.i @@ -16,6 +16,7 @@ rom rom_lib_init fdt fdt_getprop +fdt fdt_get_property fdt fdt_getprop_namelen fdt fdt_setprop_inplace fdt fdt_check_header @@ -28,6 +29,9 @@ fdt fdt_stringlist_search fdt fdt_get_alias_namelen fdt fdt_path_offset fdt fdt_path_offset_namelen +fdt fdt_get_name +fdt fdt_get_alias +fdt fdt_node_offset_by_phandle mbedtls mbedtls_asn1_get_alg mbedtls mbedtls_asn1_get_alg_null mbedtls mbedtls_asn1_get_bitstring_null -- cgit v1.2.3 From 12d1343027694634c4be3dcfb43c2e9c47a58388 Mon Sep 17 00:00:00 2001 From: Madhukar Pappireddy Date: Thu, 16 Apr 2020 17:54:25 -0500 Subject: plat/arm/fvp: populate runtime console parameters dynamically We query the UART base address and clk frequency in runtime using fconf getter APIs. Change-Id: I5f4e84953be5f384472bf90720b706d45cb86260 Signed-off-by: Madhukar Pappireddy --- plat/arm/board/fvp/fvp_console.c | 54 +++++++++++++++++++++++++++++++++ plat/arm/board/fvp/platform.mk | 1 + plat/arm/board/fvp/sp_min/sp_min-fvp.mk | 1 + plat/arm/common/arm_console.c | 3 ++ 4 files changed, 59 insertions(+) create mode 100644 plat/arm/board/fvp/fvp_console.c diff --git a/plat/arm/board/fvp/fvp_console.c b/plat/arm/board/fvp/fvp_console.c new file mode 100644 index 000000000..928b47bf1 --- /dev/null +++ b/plat/arm/board/fvp/fvp_console.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include + +#include +#include +#include +#include +#include + +static console_t fvp_runtime_console; + +/* Initialize the runtime console */ +void arm_console_runtime_init(void) +{ + uintptr_t uart_base; + uint32_t uart_clk; + + /* + * fconf APIs are not supported for RESET_TO_SP_MIN, RESET_TO_BL31 and + * BL2_AT_EL3 systems. + */ +#if RESET_TO_SP_MIN || RESET_TO_BL31 || BL2_AT_EL3 + uart_base = PLAT_ARM_RUN_UART_BASE; + uart_clk = PLAT_ARM_RUN_UART_CLK_IN_HZ; +#else + uart_base = FCONF_GET_PROPERTY(hw_config, uart_serial_config, + uart_base); + uart_clk = FCONF_GET_PROPERTY(hw_config, uart_serial_config, + uart_clk); +#endif + + int rc = console_pl011_register(uart_base, uart_clk, + ARM_CONSOLE_BAUDRATE, + &fvp_runtime_console); + + if (rc == 0) { + panic(); + } + + console_set_scope(&fvp_runtime_console, CONSOLE_FLAG_RUNTIME); +} + +void arm_console_runtime_end(void) +{ + (void)console_flush(); + (void)console_unregister(&fvp_runtime_console); +} diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 04cebcac3..6daa8966d 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -201,6 +201,7 @@ BL31_SOURCES += drivers/arm/fvp/fvp_pwrc.c \ drivers/cfi/v2m/v2m_flash.c \ lib/utils/mem_region.c \ plat/arm/board/fvp/fvp_bl31_setup.c \ + plat/arm/board/fvp/fvp_console.c \ plat/arm/board/fvp/fvp_pm.c \ plat/arm/board/fvp/fvp_topology.c \ plat/arm/board/fvp/aarch64/fvp_helpers.S \ 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 36bf441ab..ba6ceec4e 100644 --- a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk +++ b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk @@ -10,6 +10,7 @@ BL32_SOURCES += drivers/arm/fvp/fvp_pwrc.c \ lib/utils/mem_region.c \ plat/arm/board/fvp/aarch32/fvp_helpers.S \ plat/arm/board/fvp/fvp_pm.c \ + plat/arm/board/fvp/fvp_console.c \ plat/arm/board/fvp/fvp_topology.c \ plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c \ plat/arm/common/arm_nor_psci_mem_protect.c \ diff --git a/plat/arm/common/arm_console.c b/plat/arm/common/arm_console.c index 0cac5d999..c2281c42d 100644 --- a/plat/arm/common/arm_console.c +++ b/plat/arm/common/arm_console.c @@ -13,6 +13,9 @@ #include #include +#pragma weak arm_console_runtime_init +#pragma weak arm_console_runtime_end + /******************************************************************************* * Functions that set up the console ******************************************************************************/ -- cgit v1.2.3 From 58fdd608a495ebc969c8f1cb39ba1705df3b277c Mon Sep 17 00:00:00 2001 From: Jacky Bai Date: Thu, 28 Nov 2019 13:16:33 +0800 Subject: plat: imx8mn: Add imx8mn basic support Add imx8mn basic support Signed-off-by: Jacky Bai Change-Id: Ibdfcc87700bfaf980e429f3a5fa08515218ae78d --- docs/plat/imx8m.rst | 1 + plat/imx/imx8m/imx8mn/gpc.c | 94 ++++++++++++++ plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c | 186 +++++++++++++++++++++++++++ plat/imx/imx8m/imx8mn/imx8mn_psci.c | 44 +++++++ plat/imx/imx8m/imx8mn/include/platform_def.h | 135 +++++++++++++++++++ plat/imx/imx8m/imx8mn/platform.mk | 56 ++++++++ plat/imx/imx8m/include/gpc.h | 5 + 7 files changed, 521 insertions(+) create mode 100644 plat/imx/imx8m/imx8mn/gpc.c create mode 100644 plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c create mode 100644 plat/imx/imx8m/imx8mn/imx8mn_psci.c create mode 100644 plat/imx/imx8m/imx8mn/include/platform_def.h create mode 100644 plat/imx/imx8m/imx8mn/platform.mk diff --git a/docs/plat/imx8m.rst b/docs/plat/imx8m.rst index 8acd13cf7..ba087a2a3 100644 --- a/docs/plat/imx8m.rst +++ b/docs/plat/imx8m.rst @@ -32,6 +32,7 @@ Build Procedure Target_SoC should be "imx8mq" for i.MX8MQ SoC. Target_SoC should be "imx8mm" for i.MX8MM SoC. + Target_SoC should be "imx8mn" for i.MX8MN SoC. Deploy TF-A Images ~~~~~~~~~~~~~~~~~~ diff --git a/plat/imx/imx8m/imx8mn/gpc.c b/plat/imx/imx8m/imx8mn/gpc.c new file mode 100644 index 000000000..37d4226a6 --- /dev/null +++ b/plat/imx/imx8m/imx8mn/gpc.c @@ -0,0 +1,94 @@ +/* + * Copyright 2019-2020 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define CCGR(x) (0x4000 + (x) * 0x10) + +void imx_gpc_init(void) +{ + unsigned int val; + int i; + + /* mask all the wakeup irq by default */ + for (i = 0; i < 4; i++) { + mmio_write_32(IMX_GPC_BASE + IMR1_CORE0_A53 + i * 4, ~0x0); + mmio_write_32(IMX_GPC_BASE + IMR1_CORE1_A53 + i * 4, ~0x0); + mmio_write_32(IMX_GPC_BASE + IMR1_CORE2_A53 + i * 4, ~0x0); + mmio_write_32(IMX_GPC_BASE + IMR1_CORE3_A53 + i * 4, ~0x0); + mmio_write_32(IMX_GPC_BASE + IMR1_CORE0_M4 + i * 4, ~0x0); + } + + val = mmio_read_32(IMX_GPC_BASE + LPCR_A53_BSC); + /* use GIC wake_request to wakeup C0~C3 from LPM */ + val |= CORE_WKUP_FROM_GIC; + /* clear the MASTER0 LPM handshake */ + val &= ~MASTER0_LPM_HSK; + mmio_write_32(IMX_GPC_BASE + LPCR_A53_BSC, val); + + /* clear MASTER1 & MASTER2 mapping in CPU0(A53) */ + mmio_clrbits_32(IMX_GPC_BASE + MST_CPU_MAPPING, (MASTER1_MAPPING | + MASTER2_MAPPING)); + + /* set all mix/PU in A53 domain */ + mmio_write_32(IMX_GPC_BASE + PGC_CPU_0_1_MAPPING, 0xffff); + + /* + * Set the CORE & SCU power up timing: + * SW = 0x1, SW2ISO = 0x1; + * the CPU CORE and SCU power up timming counter + * is drived by 32K OSC, each domain's power up + * latency is (SW + SW2ISO) / 32768 + */ + mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(0) + 0x4, 0x401); + mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(1) + 0x4, 0x401); + mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(2) + 0x4, 0x401); + mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(3) + 0x4, 0x401); + mmio_write_32(IMX_GPC_BASE + PLAT_PGC_PCR + 0x4, 0x401); + mmio_write_32(IMX_GPC_BASE + PGC_SCU_TIMING, + (0x59 << TMC_TMR_SHIFT) | 0x5B | (0x2 << TRC1_TMC_SHIFT)); + + /* set DUMMY PDN/PUP ACK by default for A53 domain */ + mmio_write_32(IMX_GPC_BASE + PGC_ACK_SEL_A53, + A53_DUMMY_PUP_ACK | A53_DUMMY_PDN_ACK); + + /* clear DSM by default */ + val = mmio_read_32(IMX_GPC_BASE + SLPCR); + val &= ~SLPCR_EN_DSM; + /* enable the fast wakeup wait mode */ + val |= SLPCR_A53_FASTWUP_WAIT_MODE; + /* clear the RBC */ + val &= ~(0x3f << SLPCR_RBC_COUNT_SHIFT); + /* set the STBY_COUNT to 0x5, (128 * 30)us */ + val &= ~(0x7 << SLPCR_STBY_COUNT_SHFT); + val |= (0x5 << SLPCR_STBY_COUNT_SHFT); + mmio_write_32(IMX_GPC_BASE + SLPCR, val); + + /* + * USB PHY power up needs to make sure RESET bit in SRC is clear, + * otherwise, the PU power up bit in GPC will NOT self-cleared. + * only need to do it once. + */ + mmio_clrbits_32(IMX_SRC_BASE + SRC_OTG1PHY_SCR, 0x1); + + /* enable all the power domain by default */ + for (i = 0; i < 103; i++) + mmio_write_32(IMX_CCM_BASE + CCGR(i), 0x3); + mmio_write_32(IMX_GPC_BASE + PU_PGC_UP_TRG, 0x485); +} diff --git a/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c b/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c new file mode 100644 index 000000000..d4705eeeb --- /dev/null +++ b/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c @@ -0,0 +1,186 @@ +/* + * Copyright 2019-2020 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 +#include +#include + +static const mmap_region_t imx_mmap[] = { + GIC_MAP, AIPS_MAP, OCRAM_S_MAP, DDRC_MAP, {0}, +}; + +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}, +}; + +static const struct imx_rdc_cfg rdc[] = { + /* Master domain assignment */ + RDC_MDAn(0x1, DID1), + + /* peripherals domain permission */ + + /* memory region */ + RDC_MEM_REGIONn(16, 0x0, 0x0, 0xff), + RDC_MEM_REGIONn(17, 0x0, 0x0, 0xff), + RDC_MEM_REGIONn(18, 0x0, 0x0, 0xff), + + /* Sentinel */ + {0}, +}; + +static entry_point_info_t bl32_image_ep_info; +static entry_point_info_t bl33_image_ep_info; + +/* get SPSR for BL33 entry */ +static uint32_t get_spsr_for_bl33_entry(void) +{ + unsigned long el_status; + unsigned long mode; + uint32_t spsr; + + /* figure out what mode we enter the non-secure world */ + el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT; + el_status &= ID_AA64PFR0_ELX_MASK; + + mode = (el_status) ? MODE_EL2 : MODE_EL1; + + spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); + return spsr; +} + +static void bl31_tzc380_setup(void) +{ + unsigned int val; + + val = mmio_read_32(IMX_IOMUX_GPR_BASE + 0x28); + if ((val & GPR_TZASC_EN) != GPR_TZASC_EN) + return; + + tzc380_init(IMX_TZASC_BASE); + + /* + * Need to substact offset 0x40000000 from CPU address when + * programming tzasc region for i.mx8mn. + */ + + /* Enable 1G-5G S/NS RW */ + tzc380_configure_region(0, 0x00000000, TZC_ATTR_REGION_SIZE(TZC_REGION_SIZE_4G) | + TZC_ATTR_REGION_EN_MASK | TZC_ATTR_SP_ALL); +} + +void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, + u_register_t arg2, u_register_t arg3) +{ + static console_t console; + int i; + + /* Enable CSU NS access permission */ + for (i = 0; i < 64; i++) { + mmio_write_32(IMX_CSU_BASE + i * 4, 0x00ff00ff); + } + + imx_aipstz_init(aipstz); + + imx_rdc_init(rdc); + + imx8m_caam_init(); + + console_imx_uart_register(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ, + IMX_CONSOLE_BAUDRATE, &console); + /* This console is only used for boot stage */ + console_set_scope(&console, CONSOLE_FLAG_BOOT); + + /* + * tell BL3-1 where the non-secure software image is located + * and the entry state information. + */ + bl33_image_ep_info.pc = PLAT_NS_IMAGE_OFFSET; + bl33_image_ep_info.spsr = get_spsr_for_bl33_entry(); + SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); + +#ifdef SPD_opteed + /* Populate entry point information for BL32 */ + SET_PARAM_HEAD(&bl32_image_ep_info, PARAM_EP, VERSION_1, 0); + SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE); + bl32_image_ep_info.pc = BL32_BASE; + bl32_image_ep_info.spsr = 0; + + /* Pass TEE base and size to bl33 */ + bl33_image_ep_info.args.arg1 = BL32_BASE; + bl33_image_ep_info.args.arg2 = BL32_SIZE; +#endif + + bl31_tzc380_setup(); +} + +void bl31_plat_arch_setup(void) +{ + mmap_add_region(BL31_BASE, BL31_BASE, (BL31_LIMIT - BL31_BASE), + MT_MEMORY | MT_RW | MT_SECURE); + mmap_add_region(BL_CODE_BASE, BL_CODE_BASE, (BL_CODE_END - BL_CODE_BASE), + MT_MEMORY | MT_RO | MT_SECURE); +#if USE_COHERENT_MEM + mmap_add_region(BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_BASE, + (BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE), + MT_DEVICE | MT_RW | MT_SECURE); +#endif + mmap_add(imx_mmap); + + init_xlat_tables(); + + enable_mmu_el3(0); +} + +void bl31_platform_setup(void) +{ + generic_delay_timer_init(); + + /* select the CKIL source to 32K OSC */ + mmio_write_32(IMX_ANAMIX_BASE + ANAMIX_MISC_CTL, 0x1); + + plat_gic_driver_init(); + plat_gic_init(); + + imx_gpc_init(); +} + +entry_point_info_t *bl31_plat_get_next_image_ep_info(unsigned int type) +{ + if (type == NON_SECURE) + return &bl33_image_ep_info; + if (type == SECURE) + return &bl32_image_ep_info; + + return NULL; +} + +unsigned int plat_get_syscnt_freq2(void) +{ + return COUNTER_FREQUENCY; +} diff --git a/plat/imx/imx8m/imx8mn/imx8mn_psci.c b/plat/imx/imx8m/imx8mn/imx8mn_psci.c new file mode 100644 index 000000000..f541fc138 --- /dev/null +++ b/plat/imx/imx8m/imx8mn/imx8mn_psci.c @@ -0,0 +1,44 @@ +/* + * Copyright 2019-2020 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +static const plat_psci_ops_t imx_plat_psci_ops = { + .pwr_domain_on = imx_pwr_domain_on, + .pwr_domain_on_finish = imx_pwr_domain_on_finish, + .pwr_domain_off = imx_pwr_domain_off, + .validate_ns_entrypoint = imx_validate_ns_entrypoint, + .validate_power_state = imx_validate_power_state, + .cpu_standby = imx_cpu_standby, + .pwr_domain_suspend = imx_domain_suspend, + .pwr_domain_suspend_finish = imx_domain_suspend_finish, + .pwr_domain_pwr_down_wfi = imx_pwr_domain_pwr_down_wfi, + .get_sys_suspend_power_state = imx_get_sys_suspend_power_state, + .system_reset = imx_system_reset, + .system_off = imx_system_off, +}; + +/* export the platform specific psci ops */ +int plat_setup_psci_ops(uintptr_t sec_entrypoint, + const plat_psci_ops_t **psci_ops) +{ + /* sec_entrypoint is used for warm reset */ + imx_mailbox_init(sec_entrypoint); + + *psci_ops = &imx_plat_psci_ops; + + return 0; +} diff --git a/plat/imx/imx8m/imx8mn/include/platform_def.h b/plat/imx/imx8m/imx8mn/include/platform_def.h new file mode 100644 index 000000000..2444e662e --- /dev/null +++ b/plat/imx/imx8m/imx8mn/include/platform_def.h @@ -0,0 +1,135 @@ +/* + * Copyright 2020 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +#include +#include + +#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64" +#define PLATFORM_LINKER_ARCH aarch64 + +#define PLATFORM_STACK_SIZE 0xB00 +#define CACHE_WRITEBACK_GRANULE 64 + +#define PLAT_PRIMARY_CPU U(0x0) +#define PLATFORM_MAX_CPU_PER_CLUSTER U(4) +#define PLATFORM_CLUSTER_COUNT U(1) +#define PLATFORM_CLUSTER0_CORE_COUNT U(4) +#define PLATFORM_CLUSTER1_CORE_COUNT U(0) +#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER0_CORE_COUNT) + +#define IMX_PWR_LVL0 MPIDR_AFFLVL0 +#define IMX_PWR_LVL1 MPIDR_AFFLVL1 +#define IMX_PWR_LVL2 MPIDR_AFFLVL2 + +#define PWR_DOMAIN_AT_MAX_LVL U(1) +#define PLAT_MAX_PWR_LVL U(2) +#define PLAT_MAX_OFF_STATE U(4) +#define PLAT_MAX_RET_STATE U(2) + +#define PLAT_WAIT_RET_STATE U(1) +#define PLAT_STOP_OFF_STATE U(3) + +#define BL31_BASE U(0x960000) +#define BL31_LIMIT U(0x980000) + +/* non-secure uboot base */ +#define PLAT_NS_IMAGE_OFFSET U(0x40200000) + +/* GICv3 base address */ +#define PLAT_GICD_BASE U(0x38800000) +#define PLAT_GICR_BASE U(0x38880000) + +#define PLAT_VIRT_ADDR_SPACE_SIZE (ULL(1) << 32) +#define PLAT_PHY_ADDR_SPACE_SIZE (ULL(1) << 32) + +#define MAX_XLAT_TABLES 8 +#define MAX_MMAP_REGIONS 16 + +#define HAB_RVT_BASE U(0x00000900) /* HAB_RVT for i.MX8MM */ + +#define IMX_BOOT_UART_CLK_IN_HZ 24000000 /* Select 24MHz oscillator */ +#define PLAT_CRASH_UART_BASE IMX_BOOT_UART_BASE +#define PLAT_CRASH_UART_CLK_IN_HZ 24000000 +#define IMX_CONSOLE_BAUDRATE 115200 + +#define IMX_AIPSTZ1 U(0x301f0000) +#define IMX_AIPSTZ2 U(0x305f0000) +#define IMX_AIPSTZ3 U(0x309f0000) +#define IMX_AIPSTZ4 U(0x32df0000) + +#define IMX_AIPS_BASE U(0x30000000) +#define IMX_AIPS_SIZE U(0xC00000) +#define IMX_GPV_BASE U(0x32000000) +#define IMX_GPV_SIZE U(0x800000) +#define IMX_AIPS1_BASE U(0x30200000) +#define IMX_AIPS4_BASE U(0x32c00000) +#define IMX_ANAMIX_BASE U(0x30360000) +#define IMX_CCM_BASE U(0x30380000) +#define IMX_SRC_BASE U(0x30390000) +#define IMX_GPC_BASE U(0x303a0000) +#define IMX_RDC_BASE U(0x303d0000) +#define IMX_CSU_BASE U(0x303e0000) +#define IMX_WDOG_BASE U(0x30280000) +#define IMX_SNVS_BASE U(0x30370000) +#define IMX_NOC_BASE U(0x32700000) +#define IMX_TZASC_BASE U(0x32F80000) +#define IMX_IOMUX_GPR_BASE U(0x30340000) +#define IMX_CAAM_BASE U(0x30900000) +#define IMX_DDRC_BASE U(0x3d400000) +#define IMX_DDRPHY_BASE U(0x3c000000) +#define IMX_DDR_IPS_BASE U(0x3d000000) +#define IMX_DDR_IPS_SIZE U(0x1800000) +#define IMX_ROM_BASE U(0x0) + +#define IMX_GIC_BASE PLAT_GICD_BASE +#define IMX_GIC_SIZE U(0x200000) + +#define WDOG_WSR U(0x2) +#define WDOG_WCR_WDZST BIT(0) +#define WDOG_WCR_WDBG BIT(1) +#define WDOG_WCR_WDE BIT(2) +#define WDOG_WCR_WDT BIT(3) +#define WDOG_WCR_SRS BIT(4) +#define WDOG_WCR_WDA BIT(5) +#define WDOG_WCR_SRE BIT(6) +#define WDOG_WCR_WDW BIT(7) + +#define SRC_A53RCR0 U(0x4) +#define SRC_A53RCR1 U(0x8) +#define SRC_OTG1PHY_SCR U(0x20) +#define SRC_GPR1_OFFSET U(0x74) + +#define SNVS_LPCR U(0x38) +#define SNVS_LPCR_SRTC_ENV BIT(0) +#define SNVS_LPCR_DP_EN BIT(5) +#define SNVS_LPCR_TOP BIT(6) + +#define IOMUXC_GPR10 U(0x28) +#define GPR_TZASC_EN BIT(0) +#define GPR_TZASC_EN_LOCK BIT(16) + +#define ANAMIX_MISC_CTL U(0x124) +#define DRAM_PLL_CTRL (IMX_ANAMIX_BASE + 0x50) + +#define MAX_CSU_NUM U(64) + +#define OCRAM_S_BASE U(0x00180000) +#define OCRAM_S_SIZE U(0x8000) +#define OCRAM_S_LIMIT (OCRAM_S_BASE + OCRAM_S_SIZE) +#define SAVED_DRAM_TIMING_BASE OCRAM_S_BASE + +#define COUNTER_FREQUENCY 8000000 /* 8MHz */ + +#define IMX_WDOG_B_RESET + +#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_DEVICE | MT_RW) /* OCRAM_S */ +#define DDRC_MAP MAP_REGION_FLAT(IMX_DDRPHY_BASE, IMX_DDR_IPS_SIZE, MT_DEVICE | MT_RW) /* DDRMIX */ + +#endif /* platform_def.h */ diff --git a/plat/imx/imx8m/imx8mn/platform.mk b/plat/imx/imx8m/imx8mn/platform.mk new file mode 100644 index 000000000..8c4ad1c21 --- /dev/null +++ b/plat/imx/imx8m/imx8mn/platform.mk @@ -0,0 +1,56 @@ +# +# Copyright 2019-2020 NXP +# +# SPDX-License-Identifier: BSD-3-Clause +# + +PLAT_INCLUDES := -Iplat/imx/common/include \ + -Iplat/imx/imx8m/include \ + -Iplat/imx/imx8m/imx8mn/include +# Translation tables library +include lib/xlat_tables_v2/xlat_tables.mk + +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk + +IMX_GIC_SOURCES := ${GICV3_SOURCES} \ + plat/common/plat_gicv3.c \ + plat/common/plat_psci_common.c \ + plat/imx/common/plat_imx8_gic.c + +BL31_SOURCES += plat/imx/common/imx8_helpers.S \ + plat/imx/imx8m/gpc_common.c \ + plat/imx/imx8m/imx_aipstz.c \ + plat/imx/imx8m/imx_rdc.c \ + plat/imx/imx8m/imx8m_caam.c \ + plat/imx/imx8m/imx8m_psci_common.c \ + plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c \ + plat/imx/imx8m/imx8mn/imx8mn_psci.c \ + plat/imx/imx8m/imx8mn/gpc.c \ + plat/imx/common/imx8_topology.c \ + plat/imx/common/imx_sip_handler.c \ + plat/imx/common/imx_sip_svc.c \ + plat/imx/common/imx_uart_console.S \ + lib/cpus/aarch64/cortex_a53.S \ + drivers/arm/tzc/tzc380.c \ + drivers/delay_timer/delay_timer.c \ + drivers/delay_timer/generic_delay_timer.c \ + ${IMX_GIC_SOURCES} \ + ${XLAT_TABLES_LIB_SRCS} + +USE_COHERENT_MEM := 1 +RESET_TO_BL31 := 1 +A53_DISABLE_NON_TEMPORAL_HINT := 0 + +ERRATA_A53_835769 := 1 +ERRATA_A53_843419 := 1 +ERRATA_A53_855873 := 1 + +BL32_BASE ?= 0xbe000000 +$(eval $(call add_define,BL32_BASE)) + +BL32_SIZE ?= 0x2000000 +$(eval $(call add_define,BL32_SIZE)) + +IMX_BOOT_UART_BASE ?= 0x30890000 +$(eval $(call add_define,IMX_BOOT_UART_BASE)) diff --git a/plat/imx/imx8m/include/gpc.h b/plat/imx/imx8m/include/gpc.h index 139132c40..6033b0d7c 100644 --- a/plat/imx/imx8m/include/gpc.h +++ b/plat/imx/imx8m/include/gpc.h @@ -39,6 +39,7 @@ #define IRQ_SRC_C0 BIT(28) #define IRQ_SRC_C3 BIT(23) #define IRQ_SRC_C2 BIT(22) +#define CORE_WKUP_FROM_GIC (IRQ_SRC_C0 | IRQ_SRC_C1 | IRQ_SRC_C2 | IRQ_SRC_C3) #define CPU_CLOCK_ON_LPM BIT(14) #define A53_CLK_ON_LPM BIT(14) #define MASTER0_LPM_HSK BIT(6) @@ -71,6 +72,10 @@ #define MASTER1_MAPPING BIT(1) #define MASTER2_MAPPING BIT(2) +#define TMR_TCD2_SHIFT 0 +#define TMC_TMR_SHIFT 10 +#define TRC1_TMC_SHIFT 20 + /* helper macro */ #define A53_LPM_MASK U(0xF) #define A53_LPM_WAIT U(0x5) -- cgit v1.2.3 From 662af36d9ca38eec53eed8613b916d12f8442e3e Mon Sep 17 00:00:00 2001 From: J-Alves Date: Thu, 7 May 2020 18:42:25 +0100 Subject: SPCI is now called PSA FF-A SPCI is renamed as PSA FF-A which stands for Platform Security Architecture Firmware Framework for A class processors. This patch replaces the occurrence of SPCI with PSA FF-A(in documents) or simply FFA(in code). Change-Id: I4ab10adb9ffeef1ff784641dfafd99f515133760 Signed-off-by: J-Alves --- docs/about/features.rst | 4 +- docs/components/index.rst | 2 +- docs/components/psa-ffa-manifest-binding.rst | 253 ++++++++++++++++++++++++++ docs/components/spci-manifest-binding.rst | 253 -------------------------- docs/global_substitutions.txt | 2 +- docs/glossary.rst | 9 +- include/services/ffa_svc.h | 139 ++++++++++++++ include/services/spci_svc.h | 139 -------------- include/services/spm_core_manifest.h | 2 +- include/services/spmd_svc.h | 2 +- plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts | 14 +- plat/common/plat_spmd_manifest.c | 6 +- services/std_svc/spmd/spmd_main.c | 138 +++++++------- services/std_svc/spmd/spmd_private.h | 8 +- services/std_svc/std_svc_setup.c | 4 +- 15 files changed, 490 insertions(+), 485 deletions(-) create mode 100644 docs/components/psa-ffa-manifest-binding.rst delete mode 100644 docs/components/spci-manifest-binding.rst create mode 100644 include/services/ffa_svc.h delete mode 100644 include/services/spci_svc.h diff --git a/docs/about/features.rst b/docs/about/features.rst index 7c73952d3..964cb2570 100644 --- a/docs/about/features.rst +++ b/docs/about/features.rst @@ -108,8 +108,8 @@ Still to come - Refinements to Position Independent Executable (PIE) support. -- Continued support for the draft SPCI specification, to enable the use of - secure partition management in the secure world. +- Continued support for the PSA FF-A v1.0 (formally known as SPCI) specification, to enable the + use of secure partition management in the secure world. - Documentation enhancements. diff --git a/docs/components/index.rst b/docs/components/index.rst index e3ce61489..c5f6264e1 100644 --- a/docs/components/index.rst +++ b/docs/components/index.rst @@ -17,5 +17,5 @@ Components romlib-design sdei secure-partition-manager-design - spci-manifest-binding + psa-ffa-manifest-binding xlat-tables-lib-v2-design diff --git a/docs/components/psa-ffa-manifest-binding.rst b/docs/components/psa-ffa-manifest-binding.rst new file mode 100644 index 000000000..7a1c1eb07 --- /dev/null +++ b/docs/components/psa-ffa-manifest-binding.rst @@ -0,0 +1,253 @@ +PSA FF-A manifest binding to device tree +======================================== + +This document defines the nodes and properties used to define a partition, +according to the PSA FF-A specification. + +Version 1.0 +----------- + +psa-ffa-manifest-partition +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- compatible [mandatory] + - value type: + - Must be the string "arm,ffa-manifest-X.Y" which specifies the major and + minor versions fo the device tree binding for the FFA manifest represented + by this node. The minor number is incremented if the binding changes in a + backwards compatible manner. + + - X is an integer representing the major version number of this document. + - Y is an integer representing the minor version number of this document. + +- ffa-version [mandatory] + - value type: + - Must be two 16 bits values (X, Y), concatenated as 31:16 -> X, + 15:0 -> Y, where: + + - X is the major version of PSA-FF-A expected by the partition at the FFA + instance it will execute. + - Y is the minor version of PSA-FF-A expected by the partition at the FFA + instance it will execute. + +- uuid [mandatory] + - value type: + - An array consisting of 4 values, identifying the UUID of the service + implemented by this partition. The UUID format is described in RFC 4122. + UUID can be shared by multiple instances of partitions that offer the same + service For example: + + - If there are multiple instances of a Trusted OS, then the UUID can be + shared by all instances. + - The TEE driver in the HLOS can use the UUID with the + FFA_PARTITION_INFO_GET interface to determine the: + + - Number of Trusted OSs + - The partition ID of each instance of the Trusted OS + +- id + - value type: + - Pre-allocated partition ID. + +- auxiliary-id + - value type: + - Pre-allocated ID that could be used in memory management transactions. + +- description + - value type: + - Name of the partition e.g. for debugging purposes. + +- execution-ctx-count [mandatory] + - value type: + - Number of vCPUs that a VM or SP wants to instantiate. + + - In the absence of virtualization, this is the number of execution + contexts that a partition implements. + - If value of this field = 1 and number of PEs > 1 then the partition is + treated as UP & migrate capable. + - If the value of this field > 1 then the partition is treated as a MP + capable partition irrespective of the number of PEs. + +- exception-level [mandatory] + - value type: + - The target exception level for the partition: + + - 0x0: EL1 + - 0x1: S_EL0 + - 0x2: S_EL1 + - 0x3: EL2 + - 0x4: Supervisor mode + - 0x5: Secure User mode + +- execution-state [mandatory] + - value type: + - The target execution state of the partition: + + - 0: AArch64 + - 1: AArch32 + +- load-address + - value type: + - Physical base address of the partition in memory. Absence of this field + indicates that the partition is position independent and can be loaded at + any address chosen at boot time. + +- entrypoint-offset + - value type: + - Offset from the base of the partition's binary image to the entry point of + the partition. Absence of this field indicates that the entry point is at + offset 0x0 from the base of the partition's binary. + +- xlat-granule [mandatory] + - value type: + - Translation granule used with the partition: + + - 0x0: 4k + - 0x1: 16k + - 0x2: 32k + +- boot-order + - value type: + - A unique number amongst all partitions that specifies if this partition + must be booted before others. The partition with the smaller number will be + booted first. + +- rx-tx-buffer + - value type: "memory-regions" node + - Specific "memory-regions" nodes that describe the RX/TX buffers expected + by the partition. + The "compatible" must be the string "arm,ffa-manifest-rx_tx-buffer". + +- messaging-method [mandatory] + - value type: + - Specifies which messaging methods are supported by the partition: + + - 0x0: direct messaging method + - 0x1: indirect messaging method + - 0x2: both direct and indirect messaging methods + +- has-primary-scheduler + - value type: + - Presence of this field indicates that the partition implements the primary + scheduler. If so, run-time EL must be EL1. + +- run-time-model + - value type: + - Run time model that the SPM must enforce for this SP: + + - 0x0: Run to completion + - 0x1: Preemptible + +- time-slice-mem + - value type: + - Presence of this field indicates that the partition doesn't expect the + partition manager to time slice long running memory management functions. + +- gp-register-num + - value type: + - Presence of this field indicates that the partition expects the + ffa_init_info structure to be passed in via the specified general purpose + register. + The field specifies the general purpose register number but not its width. + The width is derived from the partition's execution state, as specified in + the partition properties. For example, if the number value is 1 then the + general-purpose register used will be x1 in AArch64 state and w1 in AArch32 + state. + +- stream-endpoint-ids + - value type: + - List of tuples, identifying the IDs this partition is acting as + proxy for. + +memory-regions +-------------- + +- compatible [mandatory] + - value type: + - Must be the string "arm,ffa-manifest-memory-regions". + +- description + - value type: + - Name of the memory region e.g. for debugging purposes. + +- pages-count [mandatory] + - value type: + - Count of pages of memory region as a multiple of the translation granule + size + +- attributes [mandatory] + - value type: + - ?? TO DEFINE + +- base-address + - value type: + - Base address of the region. The address must be aligned to the translation + granule size. + The address given may be a Physical Address (PA), Virtual Address (VA), or + Intermediate Physical Address (IPA). Refer to the FFA specification for + more information on the restrictions around the address type. + If the base address is omitted then the partition manager must map a memory + region of the specified size into the partition's translation regime and + then communicate the region properties (including the base address chosen + by the partition manager) to the partition. + +device-regions +-------------- + +- compatible [mandatory] + - value type: + - Must be the string "arm,ffa-manifest-device-regions". + +- description + - value type: + - Name of the device region e.g. for debugging purposes. + +- reg [mandatory] + - value type: + - A (address, num-pages) pair describing the device, where: + + - address: The physical base address value of the device MMIO + region. + - num-pages: The number of pages of the region. The total size of + the region is this value multiplied by the translation granule size. + +- attributes [mandatory] + - value type: + - ?? TO DEFINE + +- smmu-id + - value type: + - On systems with multiple System Memory Management Units (SMMUs) this + identifier is used to inform the partition manager which SMMU the device is + upstream of. If the field is omitted then it is assumed that the device is + not upstream of any SMMU. + +- stream-ids [mandatory] + - value type: + - A list of (id, mem-manage) pair, where: + + - id: A unique value amongst all devices assigned to the partition. + - mem-manage: A value used in memory management operations. + +- interrupts [mandatory] + - value type: + - A list of (id, attributes) pair describing the device interrupts, where: + + - id: The interrupt IDs. + - attributes: A ?? TO DEFINE value, + containing the attributes for each interrupt ID: + + - Interrupt type: SPI, PPI, SGI + - Interrupt configuration: Edge triggered, Level triggered + - Interrupt security state: Secure, Non-secure + - Interrupt priority value + - Target execution context/vCPU for each SPI + +- exclusive-access + - value type: + - Presence of this field implies that this endpoint must be granted exclusive + access and ownership of this devices's MMIO region. + +-------------- + +*Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.* diff --git a/docs/components/spci-manifest-binding.rst b/docs/components/spci-manifest-binding.rst deleted file mode 100644 index 584816911..000000000 --- a/docs/components/spci-manifest-binding.rst +++ /dev/null @@ -1,253 +0,0 @@ -SPCI manifest binding to device tree -==================================== - -This document defines the nodes and properties used to define a partition, -according to the SPCI specification. - -Version 1.0 ------------ - -spci-manifest-partition -^^^^^^^^^^^^^^^^^^^^^^^ - -- compatible [mandatory] - - value type: - - Must be the string "arm,spci-manifest-X.Y" which specifies the major and - minor versions fo the device tree binding for the SPCI manifest represented - by this node. The minor number is incremented if the binding changes in a - backwards compatible manner. - - - X is an integer representing the major version number of this document. - - Y is an integer representing the minor version number of this document. - -- spci-version [mandatory] - - value type: - - Must be two 16 bits values (X, Y), concatenated as 31:16 -> X, - 15:0 -> Y, where: - - - X is the major version of PSA-FF-A expected by the partition at the SPCI - instance it will execute. - - Y is the minor version of PSA-FF-A expected by the partition at the SPCI - instance it will execute. - -- uuid [mandatory] - - value type: - - An array consisting of 4 values, identifying the UUID of the service - implemented by this partition. The UUID format is described in RFC 4122. - UUID can be shared by multiple instances of partitions that offer the same - service For example: - - - If there are multiple instances of a Trusted OS, then the UUID can be - shared by all instances. - - The TEE driver in the HLOS can use the UUID with the - SPCI_PARTITION_INFO_GET interface to determine the: - - - Number of Trusted OSs - - The partition ID of each instance of the Trusted OS - -- id - - value type: - - Pre-allocated partition ID. - -- auxiliary-id - - value type: - - Pre-allocated ID that could be used in memory management transactions. - -- description - - value type: - - Name of the partition e.g. for debugging purposes. - -- execution-ctx-count [mandatory] - - value type: - - Number of vCPUs that a VM or SP wants to instantiate. - - - In the absence of virtualization, this is the number of execution - contexts that a partition implements. - - If value of this field = 1 and number of PEs > 1 then the partition is - treated as UP & migrate capable. - - If the value of this field > 1 then the partition is treated as a MP - capable partition irrespective of the number of PEs. - -- exception-level [mandatory] - - value type: - - The target exception level for the partition: - - - 0x0: EL1 - - 0x1: S_EL0 - - 0x2: S_EL1 - - 0x3: EL2 - - 0x4: Supervisor mode - - 0x5: Secure User mode - -- execution-state [mandatory] - - value type: - - The target execution state of the partition: - - - 0: AArch64 - - 1: AArch32 - -- load-address - - value type: - - Physical base address of the partition in memory. Absence of this field - indicates that the partition is position independent and can be loaded at - any address chosen at boot time. - -- entrypoint-offset - - value type: - - Offset from the base of the partition's binary image to the entry point of - the partition. Absence of this field indicates that the entry point is at - offset 0x0 from the base of the partition's binary. - -- xlat-granule [mandatory] - - value type: - - Translation granule used with the partition: - - - 0x0: 4k - - 0x1: 16k - - 0x2: 32k - -- boot-order - - value type: - - A unique number amongst all partitions that specifies if this partition - must be booted before others. The partition with the smaller number will be - booted first. - -- rx-tx-buffer - - value type: "memory-regions" node - - Specific "memory-regions" nodes that describe the RX/TX buffers expected - by the partition. - The "compatible" must be the string "arm,spci-manifest-rx_tx-buffer". - -- messaging-method [mandatory] - - value type: - - Specifies which messaging methods are supported by the partition: - - - 0x0: direct messaging method - - 0x1: indirect messaging method - - 0x2: both direct and indirect messaging methods - -- has-primary-scheduler - - value type: - - Presence of this field indicates that the partition implements the primary - scheduler. If so, run-time EL must be EL1. - -- run-time-model - - value type: - - Run time model that the SPM must enforce for this SP: - - - 0x0: Run to completion - - 0x1: Preemptible - -- time-slice-mem - - value type: - - Presence of this field indicates that the partition doesn't expect the - partition manager to time slice long running memory management functions. - -- gp-register-num - - value type: - - Presence of this field indicates that the partition expects the - spci_init_info structure to be passed in via the specified general purpose - register. - The field specifies the general purpose register number but not its width. - The width is derived from the partition's execution state, as specified in - the partition properties. For example, if the number value is 1 then the - general-purpose register used will be x1 in AArch64 state and w1 in AArch32 - state. - -- stream-endpoint-ids - - value type: - - List of tuples, identifying the IDs this partition is acting as - proxy for. - -memory-regions --------------- - -- compatible [mandatory] - - value type: - - Must be the string "arm,spci-manifest-memory-regions". - -- description - - value type: - - Name of the memory region e.g. for debugging purposes. - -- pages-count [mandatory] - - value type: - - Count of pages of memory region as a multiple of the translation granule - size - -- attributes [mandatory] - - value type: - - ?? TO DEFINE - -- base-address - - value type: - - Base address of the region. The address must be aligned to the translation - granule size. - The address given may be a Physical Address (PA), Virtual Address (VA), or - Intermediate Physical Address (IPA). Refer to the SPCI specification for - more information on the restrictions around the address type. - If the base address is omitted then the partition manager must map a memory - region of the specified size into the partition's translation regime and - then communicate the region properties (including the base address chosen - by the partition manager) to the partition. - -device-regions --------------- - -- compatible [mandatory] - - value type: - - Must be the string "arm,spci-manifest-device-regions". - -- description - - value type: - - Name of the device region e.g. for debugging purposes. - -- reg [mandatory] - - value type: - - A (address, num-pages) pair describing the device, where: - - - address: The physical base address value of the device MMIO - region. - - num-pages: The number of pages of the region. The total size of - the region is this value multiplied by the translation granule size. - -- attributes [mandatory] - - value type: - - ?? TO DEFINE - -- smmu-id - - value type: - - On systems with multiple System Memory Management Units (SMMUs) this - identifier is used to inform the partition manager which SMMU the device is - upstream of. If the field is omitted then it is assumed that the device is - not upstream of any SMMU. - -- stream-ids [mandatory] - - value type: - - A list of (id, mem-manage) pair, where: - - - id: A unique value amongst all devices assigned to the partition. - - mem-manage: A value used in memory management operations. - -- interrupts [mandatory] - - value type: - - A list of (id, attributes) pair describing the device interrupts, where: - - - id: The interrupt IDs. - - attributes: A ?? TO DEFINE value, - containing the attributes for each interrupt ID: - - - Interrupt type: SPI, PPI, SGI - - Interrupt configuration: Edge triggered, Level triggered - - Interrupt security state: Secure, Non-secure - - Interrupt priority value - - Target execution context/vCPU for each SPI - -- exclusive-access - - value type: - - Presence of this field implies that this endpoint must be granted exclusive - access and ownership of this devices's MMIO region. - --------------- - -*Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.* diff --git a/docs/global_substitutions.txt b/docs/global_substitutions.txt index 4dda1dcd4..d33155b9a 100644 --- a/docs/global_substitutions.txt +++ b/docs/global_substitutions.txt @@ -14,6 +14,7 @@ .. |EHF| replace:: :term:`EHF` .. |FCONF| replace:: :term:`FCONF` .. |FDT| replace:: :term:`FDT` +.. |FFA| replace:: :term:`FFA` .. |FIP| replace:: :term:`FIP` .. |FVP| replace:: :term:`FVP` .. |FWU| replace:: :term:`FWU` @@ -44,7 +45,6 @@ .. |SMCCC| replace:: :term:`SMCCC` .. |SoC| replace:: :term:`SoC` .. |SP| replace:: :term:`SP` -.. |SPCI| replace:: :term:`SPCI` .. |SPD| replace:: :term:`SPD` .. |SPM| replace:: :term:`SPM` .. |SSBS| replace:: :term:`SSBS` diff --git a/docs/glossary.rst b/docs/glossary.rst index 3da30b02a..e08707946 100644 --- a/docs/glossary.rst +++ b/docs/glossary.rst @@ -57,6 +57,9 @@ You can find additional definitions in the `Arm Glossary`_. FDT Flattened Device Tree + FFA + Firmware Framework for A-class processors + FIP Firmware Image Package @@ -107,6 +110,9 @@ You can find additional definitions in the `Arm Glossary`_. PMF Performance Measurement Framework + PSA + Platform Security Architecture + PSCI Power State Coordination Interface @@ -149,9 +155,6 @@ You can find additional definitions in the `Arm Glossary`_. SP Secure Partition - SPCI - Secure Partition Client Interface - SPD Secure Payload Dispatcher diff --git a/include/services/ffa_svc.h b/include/services/ffa_svc.h new file mode 100644 index 000000000..fe321750a --- /dev/null +++ b/include/services/ffa_svc.h @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FFA_SVC_H +#define FFA_SVC_H + +#include +#include +#include + +/* FFA error codes. */ +#define FFA_ERROR_NOT_SUPPORTED -1 +#define FFA_ERROR_INVALID_PARAMETER -2 +#define FFA_ERROR_NO_MEMORY -3 +#define FFA_ERROR_BUSY -4 +#define FFA_ERROR_INTERRUPTED -5 +#define FFA_ERROR_DENIED -6 +#define FFA_ERROR_RETRY -7 + +/* The macros below are used to identify FFA calls from the SMC function ID */ +#define FFA_FNUM_MIN_VALUE U(0x60) +#define FFA_FNUM_MAX_VALUE U(0x7f) +#define is_ffa_fid(fid) __extension__ ({ \ + __typeof__(fid) _fid = (fid); \ + ((GET_SMC_NUM(_fid) >= FFA_FNUM_MIN_VALUE) && \ + (GET_SMC_NUM(_fid) <= FFA_FNUM_MAX_VALUE)); }) + +/* FFA_VERSION helpers */ +#define FFA_VERSION_MAJOR U(1) +#define FFA_VERSION_MAJOR_SHIFT 16 +#define FFA_VERSION_MAJOR_MASK U(0x7FFF) +#define FFA_VERSION_MINOR U(0) +#define FFA_VERSION_MINOR_SHIFT 0 +#define FFA_VERSION_MINOR_MASK U(0xFFFF) + +#define MAKE_FFA_VERSION(major, minor) \ + ((((major) & FFA_VERSION_MAJOR_MASK) << FFA_VERSION_MAJOR_SHIFT) | \ + (((minor) & FFA_VERSION_MINOR_MASK) << FFA_VERSION_MINOR_SHIFT)) +#define FFA_VERSION_COMPILED MAKE_FFA_VERSION(FFA_VERSION_MAJOR, \ + FFA_VERSION_MINOR) + +/* FFA_MSG_SEND helpers */ +#define FFA_MSG_SEND_ATTRS_BLK_SHIFT U(0) +#define FFA_MSG_SEND_ATTRS_BLK_MASK U(0x1) +#define FFA_MSG_SEND_ATTRS_BLK U(0) +#define FFA_MSG_SEND_ATTRS_BLK_NOT U(1) +#define FFA_MSG_SEND_ATTRS(blk) \ + (((blk) & FFA_MSG_SEND_ATTRS_BLK_MASK) \ + << FFA_MSG_SEND_ATTRS_BLK_SHIFT) + +/* Get FFA fastcall std FID from function number */ +#define FFA_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)) + +/* FFA function numbers */ +#define FFA_FNUM_ERROR U(0x60) +#define FFA_FNUM_SUCCESS U(0x61) +#define FFA_FNUM_INTERRUPT U(0x62) +#define FFA_FNUM_VERSION U(0x63) +#define FFA_FNUM_FEATURES U(0x64) +#define FFA_FNUM_RX_RELEASE U(0x65) +#define FFA_FNUM_RXTX_MAP U(0x66) +#define FFA_FNUM_RXTX_UNMAP U(0x67) +#define FFA_FNUM_PARTITION_INFO_GET U(0x68) +#define FFA_FNUM_ID_GET U(0x69) +#define FFA_FNUM_MSG_POLL U(0x6A) +#define FFA_FNUM_MSG_WAIT U(0x6B) +#define FFA_FNUM_MSG_YIELD U(0x6C) +#define FFA_FNUM_MSG_RUN U(0x6D) +#define FFA_FNUM_MSG_SEND U(0x6E) +#define FFA_FNUM_MSG_SEND_DIRECT_REQ U(0x6F) +#define FFA_FNUM_MSG_SEND_DIRECT_RESP U(0x70) +#define FFA_FNUM_MEM_DONATE U(0x71) +#define FFA_FNUM_MEM_LEND U(0x72) +#define FFA_FNUM_MEM_SHARE U(0x73) +#define FFA_FNUM_MEM_RETRIEVE_REQ U(0x74) +#define FFA_FNUM_MEM_RETRIEVE_RESP U(0x75) +#define FFA_FNUM_MEM_RELINQUISH U(0x76) +#define FFA_FNUM_MEM_RECLAIM U(0x77) + +/* FFA SMC32 FIDs */ +#define FFA_ERROR FFA_FID(SMC_32, FFA_FNUM_ERROR) +#define FFA_SUCCESS_SMC32 FFA_FID(SMC_32, FFA_FNUM_SUCCESS) +#define FFA_INTERRUPT FFA_FID(SMC_32, FFA_FNUM_INTERRUPT) +#define FFA_VERSION FFA_FID(SMC_32, FFA_FNUM_VERSION) +#define FFA_FEATURES FFA_FID(SMC_32, FFA_FNUM_FEATURES) +#define FFA_RX_RELEASE FFA_FID(SMC_32, FFA_FNUM_RX_RELEASE) +#define FFA_RXTX_MAP_SMC32 FFA_FID(SMC_32, FFA_FNUM_RXTX_MAP) +#define FFA_RXTX_UNMAP FFA_FID(SMC_32, FFA_FNUM_RXTX_UNMAP) +#define FFA_PARTITION_INFO_GET FFA_FID(SMC_32, FFA_FNUM_PARTITION_INFO_GET) +#define FFA_ID_GET FFA_FID(SMC_32, FFA_FNUM_ID_GET) +#define FFA_MSG_POLL FFA_FID(SMC_32, FFA_FNUM_MSG_POLL) +#define FFA_MSG_WAIT FFA_FID(SMC_32, FFA_FNUM_MSG_WAIT) +#define FFA_MSG_YIELD FFA_FID(SMC_32, FFA_FNUM_MSG_YIELD) +#define FFA_MSG_RUN FFA_FID(SMC_32, FFA_FNUM_MSG_RUN) +#define FFA_MSG_SEND FFA_FID(SMC_32, FFA_FNUM_MSG_SEND) +#define FFA_MSG_SEND_DIRECT_REQ_SMC32 \ + FFA_FID(SMC_32, FFA_FNUM_MSG_SEND_DIRECT_REQ) +#define FFA_MSG_SEND_DIRECT_RESP_SMC32 \ + FFA_FID(SMC_32, FFA_FNUM_MSG_SEND_DIRECT_RESP) +#define FFA_MEM_DONATE_SMC32 FFA_FID(SMC_32, FFA_FNUM_MEM_DONATE) +#define FFA_MEM_LEND_SMC32 FFA_FID(SMC_32, FFA_FNUM_MEM_LEND) +#define FFA_MEM_SHARE_SMC32 FFA_FID(SMC_32, FFA_FNUM_MEM_SHARE) +#define FFA_MEM_RETRIEVE_REQ_SMC32 \ + FFA_FID(SMC_32, FFA_FNUM_MEM_RETRIEVE_REQ) +#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) + +/* FFA SMC64 FIDs */ +#define FFA_SUCCESS_SMC64 FFA_FID(SMC_64, FFA_FNUM_SUCCESS) +#define FFA_RXTX_MAP_SMC64 FFA_FID(SMC_64, FFA_FNUM_RXTX_MAP) +#define FFA_MSG_SEND_DIRECT_REQ_SMC64 \ + FFA_FID(SMC_64, FFA_FNUM_MSG_SEND_DIRECT_REQ) +#define FFA_MSG_SEND_DIRECT_RESP_SMC64 \ + FFA_FID(SMC_64, FFA_FNUM_MSG_SEND_DIRECT_RESP) +#define FFA_MEM_DONATE_SMC64 FFA_FID(SMC_64, FFA_FNUM_MEM_DONATE) +#define FFA_MEM_LEND_SMC64 FFA_FID(SMC_64, FFA_FNUM_MEM_LEND) +#define FFA_MEM_SHARE_SMC64 FFA_FID(SMC_64, FFA_FNUM_MEM_SHARE) +#define FFA_MEM_RETRIEVE_REQ_SMC64 \ + FFA_FID(SMC_64, FFA_FNUM_MEM_RETRIEVE_REQ) + +/* + * Reserve a special value for traffic targeted to the Hypervisor or SPM. + */ +#define FFA_TARGET_INFO_MBZ U(0x0) + +/* + * Reserve a special value for MBZ parameters. + */ +#define FFA_PARAM_MBZ U(0x0) + +#endif /* FFA_SVC_H */ diff --git a/include/services/spci_svc.h b/include/services/spci_svc.h deleted file mode 100644 index 49ba40858..000000000 --- a/include/services/spci_svc.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 2019, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef SPCI_SVC_H -#define SPCI_SVC_H - -#include -#include -#include - -/* SPCI error codes. */ -#define SPCI_ERROR_NOT_SUPPORTED -1 -#define SPCI_ERROR_INVALID_PARAMETER -2 -#define SPCI_ERROR_NO_MEMORY -3 -#define SPCI_ERROR_BUSY -4 -#define SPCI_ERROR_INTERRUPTED -5 -#define SPCI_ERROR_DENIED -6 -#define SPCI_ERROR_RETRY -7 - -/* The macros below are used to identify SPCI calls from the SMC function ID */ -#define SPCI_FNUM_MIN_VALUE U(0x60) -#define SPCI_FNUM_MAX_VALUE U(0x7f) -#define is_spci_fid(fid) __extension__ ({ \ - __typeof__(fid) _fid = (fid); \ - ((GET_SMC_NUM(_fid) >= SPCI_FNUM_MIN_VALUE) && \ - (GET_SMC_NUM(_fid) <= SPCI_FNUM_MAX_VALUE)); }) - -/* SPCI_VERSION helpers */ -#define SPCI_VERSION_MAJOR U(0) -#define SPCI_VERSION_MAJOR_SHIFT 16 -#define SPCI_VERSION_MAJOR_MASK U(0x7FFF) -#define SPCI_VERSION_MINOR U(9) -#define SPCI_VERSION_MINOR_SHIFT 0 -#define SPCI_VERSION_MINOR_MASK U(0xFFFF) - -#define MAKE_SPCI_VERSION(major, minor) \ - ((((major) & SPCI_VERSION_MAJOR_MASK) << SPCI_VERSION_MAJOR_SHIFT) | \ - (((minor) & SPCI_VERSION_MINOR_MASK) << SPCI_VERSION_MINOR_SHIFT)) -#define SPCI_VERSION_COMPILED MAKE_SPCI_VERSION(SPCI_VERSION_MAJOR, \ - SPCI_VERSION_MINOR) - -/* SPCI_MSG_SEND helpers */ -#define SPCI_MSG_SEND_ATTRS_BLK_SHIFT U(0) -#define SPCI_MSG_SEND_ATTRS_BLK_MASK U(0x1) -#define SPCI_MSG_SEND_ATTRS_BLK U(0) -#define SPCI_MSG_SEND_ATTRS_BLK_NOT U(1) -#define SPCI_MSG_SEND_ATTRS(blk) \ - (((blk) & SPCI_MSG_SEND_ATTRS_BLK_MASK) \ - << SPCI_MSG_SEND_ATTRS_BLK_SHIFT) - -/* Get SPCI fastcall std FID from function number */ -#define SPCI_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)) - -/* SPCI function numbers */ -#define SPCI_FNUM_ERROR U(0x60) -#define SPCI_FNUM_SUCCESS U(0x61) -#define SPCI_FNUM_INTERRUPT U(0x62) -#define SPCI_FNUM_VERSION U(0x63) -#define SPCI_FNUM_FEATURES U(0x64) -#define SPCI_FNUM_RX_RELEASE U(0x65) -#define SPCI_FNUM_RXTX_MAP U(0x66) -#define SPCI_FNUM_RXTX_UNMAP U(0x67) -#define SPCI_FNUM_PARTITION_INFO_GET U(0x68) -#define SPCI_FNUM_ID_GET U(0x69) -#define SPCI_FNUM_MSG_POLL U(0x6A) -#define SPCI_FNUM_MSG_WAIT U(0x6B) -#define SPCI_FNUM_MSG_YIELD U(0x6C) -#define SPCI_FNUM_MSG_RUN U(0x6D) -#define SPCI_FNUM_MSG_SEND U(0x6E) -#define SPCI_FNUM_MSG_SEND_DIRECT_REQ U(0x6F) -#define SPCI_FNUM_MSG_SEND_DIRECT_RESP U(0x70) -#define SPCI_FNUM_MEM_DONATE U(0x71) -#define SPCI_FNUM_MEM_LEND U(0x72) -#define SPCI_FNUM_MEM_SHARE U(0x73) -#define SPCI_FNUM_MEM_RETRIEVE_REQ U(0x74) -#define SPCI_FNUM_MEM_RETRIEVE_RESP U(0x75) -#define SPCI_FNUM_MEM_RELINQUISH U(0x76) -#define SPCI_FNUM_MEM_RECLAIM U(0x77) - -/* SPCI SMC32 FIDs */ -#define SPCI_ERROR SPCI_FID(SMC_32, SPCI_FNUM_ERROR) -#define SPCI_SUCCESS_SMC32 SPCI_FID(SMC_32, SPCI_FNUM_SUCCESS) -#define SPCI_INTERRUPT SPCI_FID(SMC_32, SPCI_FNUM_INTERRUPT) -#define SPCI_VERSION SPCI_FID(SMC_32, SPCI_FNUM_VERSION) -#define SPCI_FEATURES SPCI_FID(SMC_32, SPCI_FNUM_FEATURES) -#define SPCI_RX_RELEASE SPCI_FID(SMC_32, SPCI_FNUM_RX_RELEASE) -#define SPCI_RXTX_MAP_SMC32 SPCI_FID(SMC_32, SPCI_FNUM_RXTX_MAP) -#define SPCI_RXTX_UNMAP SPCI_FID(SMC_32, SPCI_FNUM_RXTX_UNMAP) -#define SPCI_PARTITION_INFO_GET SPCI_FID(SMC_32, SPCI_FNUM_PARTITION_INFO_GET) -#define SPCI_ID_GET SPCI_FID(SMC_32, SPCI_FNUM_ID_GET) -#define SPCI_MSG_POLL SPCI_FID(SMC_32, SPCI_FNUM_MSG_POLL) -#define SPCI_MSG_WAIT SPCI_FID(SMC_32, SPCI_FNUM_MSG_WAIT) -#define SPCI_MSG_YIELD SPCI_FID(SMC_32, SPCI_FNUM_MSG_YIELD) -#define SPCI_MSG_RUN SPCI_FID(SMC_32, SPCI_FNUM_MSG_RUN) -#define SPCI_MSG_SEND SPCI_FID(SMC_32, SPCI_FNUM_MSG_SEND) -#define SPCI_MSG_SEND_DIRECT_REQ_SMC32 \ - SPCI_FID(SMC_32, SPCI_FNUM_MSG_SEND_DIRECT_REQ) -#define SPCI_MSG_SEND_DIRECT_RESP_SMC32 \ - SPCI_FID(SMC_32, SPCI_FNUM_MSG_SEND_DIRECT_RESP) -#define SPCI_MEM_DONATE_SMC32 SPCI_FID(SMC_32, SPCI_FNUM_MEM_DONATE) -#define SPCI_MEM_LEND_SMC32 SPCI_FID(SMC_32, SPCI_FNUM_MEM_LEND) -#define SPCI_MEM_SHARE_SMC32 SPCI_FID(SMC_32, SPCI_FNUM_MEM_SHARE) -#define SPCI_MEM_RETRIEVE_REQ_SMC32 \ - SPCI_FID(SMC_32, SPCI_FNUM_MEM_RETRIEVE_REQ) -#define SPCI_MEM_RETRIEVE_RESP SPCI_FID(SMC_32, SPCI_FNUM_MEM_RETRIEVE_RESP) -#define SPCI_MEM_RELINQUISH SPCI_FID(SMC_32, SPCI_FNUM_MEM_RELINQUISH) -#define SPCI_MEM_RECLAIM SPCI_FID(SMC_32, SPCI_FNUM_MEM_RECLAIM) - -/* SPCI SMC64 FIDs */ -#define SPCI_SUCCESS_SMC64 SPCI_FID(SMC_64, SPCI_FNUM_SUCCESS) -#define SPCI_RXTX_MAP_SMC64 SPCI_FID(SMC_64, SPCI_FNUM_RXTX_MAP) -#define SPCI_MSG_SEND_DIRECT_REQ_SMC64 \ - SPCI_FID(SMC_64, SPCI_FNUM_MSG_SEND_DIRECT_REQ) -#define SPCI_MSG_SEND_DIRECT_RESP_SMC64 \ - SPCI_FID(SMC_64, SPCI_FNUM_MSG_SEND_DIRECT_RESP) -#define SPCI_MEM_DONATE_SMC64 SPCI_FID(SMC_64, SPCI_FNUM_MEM_DONATE) -#define SPCI_MEM_LEND_SMC64 SPCI_FID(SMC_64, SPCI_FNUM_MEM_LEND) -#define SPCI_MEM_SHARE_SMC64 SPCI_FID(SMC_64, SPCI_FNUM_MEM_SHARE) -#define SPCI_MEM_RETRIEVE_REQ_SMC64 \ - SPCI_FID(SMC_64, SPCI_FNUM_MEM_RETRIEVE_REQ) - -/* - * Reserve a special value for traffic targeted to the Hypervisor or SPM. - */ -#define SPCI_TARGET_INFO_MBZ U(0x0) - -/* - * Reserve a special value for MBZ parameters. - */ -#define SPCI_PARAM_MBZ U(0x0) - -#endif /* SPCI_SVC_H */ diff --git a/include/services/spm_core_manifest.h b/include/services/spm_core_manifest.h index 0c4363691..64ecce005 100644 --- a/include/services/spm_core_manifest.h +++ b/include/services/spm_core_manifest.h @@ -15,7 +15,7 @@ typedef struct spm_core_manifest_sect_attribute { /* - * SPCI version (mandatory). + * FFA version (mandatory). */ uint32_t major_version; uint32_t minor_version; diff --git a/include/services/spmd_svc.h b/include/services/spmd_svc.h index a766dcf8f..1e7e6aa87 100644 --- a/include/services/spmd_svc.h +++ b/include/services/spmd_svc.h @@ -8,7 +8,7 @@ #define SPMD_SVC_H #ifndef __ASSEMBLER__ -#include +#include #include int spmd_setup(void); diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts index ebfbe174b..a1c909449 100644 --- a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts +++ b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts @@ -6,12 +6,14 @@ /dts-v1/; / { - compatible = "arm,spci-core-manifest-1.0"; + compatible = "arm,ffa-core-manifest-1.0"; + #address-cells = <2>; + #size-cells = <1>; attribute { spmc_id = <0x8000>; - maj_ver = <0x0>; - min_ver = <0x9>; + maj_ver = <0x1>; + min_ver = <0x0>; exec_state = <0x0>; load_address = <0x0 0x6000000>; entrypoint = <0x0 0x6000000>; @@ -25,12 +27,12 @@ hypervisor { compatible = "hafnium,hafnium"; vm1 { - is_spci_partition; + is_ffa_partition; debug_name = "cactus-primary"; load_address = <0x7000000>; }; vm2 { - is_spci_partition; + is_ffa_partition; debug_name = "cactus-secondary"; load_address = <0x7100000>; vcpu_count = <2>; @@ -62,6 +64,6 @@ memory@60000000 { device_type = "memory"; - reg = <0x6000000 0x2000000>; /* Trusted DRAM */ + reg = <0x0 0x6000000 0x2000000>; /* Trusted DRAM */ }; }; diff --git a/plat/common/plat_spmd_manifest.c b/plat/common/plat_spmd_manifest.c index 109b001f0..455b9808b 100644 --- a/plat/common/plat_spmd_manifest.c +++ b/plat/common/plat_spmd_manifest.c @@ -31,14 +31,14 @@ static int manifest_parse_attribute(spmc_manifest_attribute_t *attr, rc = fdt_read_uint32(fdt, node, "maj_ver", &attr->major_version); if (rc != 0) { - ERROR("Missing SPCI %s version in SPM Core manifest.\n", + ERROR("Missing FFA %s version in SPM Core manifest.\n", "major"); return rc; } rc = fdt_read_uint32(fdt, node, "min_ver", &attr->minor_version); if (rc != 0) { - ERROR("Missing SPCI %s version in SPM Core manifest.\n", + ERROR("Missing FFA %s version in SPM Core manifest.\n", "minor"); return rc; } @@ -163,7 +163,7 @@ int plat_spm_core_manifest_load(spmc_manifest_attribute_t *manifest, VERBOSE("Reading SPM Core manifest at address %p\n", pm_addr); rc = fdt_node_offset_by_compatible(pm_addr, -1, - "arm,spci-core-manifest-1.0"); + "arm,ffa-core-manifest-1.0"); if (rc < 0) { ERROR("Unrecognized SPM Core manifest\n"); goto exit_unmap; diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c index 501782ffb..a818037cb 100644 --- a/services/std_svc/spmd/spmd_main.c +++ b/services/std_svc/spmd/spmd_main.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include #include "spmd_private.h" @@ -56,7 +56,7 @@ spmd_spm_core_context_t *spmd_get_context(void) ******************************************************************************/ static int32_t spmd_init(void); static int spmd_spmc_init(void *pm_addr); -static uint64_t spmd_spci_error_return(void *handle, +static uint64_t spmd_ffa_error_return(void *handle, int error_code); static uint64_t spmd_smc_forward(uint32_t smc_fid, bool secure_origin, @@ -161,14 +161,14 @@ static int spmd_spmc_init(void *pm_addr) * Ensure that the SPM Core version is compatible with the SPM * Dispatcher version. */ - if ((spmc_attrs.major_version != SPCI_VERSION_MAJOR) || - (spmc_attrs.minor_version > SPCI_VERSION_MINOR)) { - WARN("Unsupported SPCI version (%u.%u)\n", + if ((spmc_attrs.major_version != FFA_VERSION_MAJOR) || + (spmc_attrs.minor_version > FFA_VERSION_MINOR)) { + WARN("Unsupported FFA version (%u.%u)\n", spmc_attrs.major_version, spmc_attrs.minor_version); return -EINVAL; } - VERBOSE("SPCI version (%u.%u)\n", spmc_attrs.major_version, + VERBOSE("FFA version (%u.%u)\n", spmc_attrs.major_version, spmc_attrs.minor_version); VERBOSE("SPM Core run time EL%x.\n", @@ -324,18 +324,18 @@ static uint64_t spmd_smc_forward(uint32_t smc_fid, } /******************************************************************************* - * Return SPCI_ERROR with specified error code + * Return FFA_ERROR with specified error code ******************************************************************************/ -static uint64_t spmd_spci_error_return(void *handle, int error_code) +static uint64_t spmd_ffa_error_return(void *handle, int error_code) { - SMC_RET8(handle, SPCI_ERROR, - SPCI_TARGET_INFO_MBZ, error_code, - SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, - SPCI_PARAM_MBZ, SPCI_PARAM_MBZ); + SMC_RET8(handle, FFA_ERROR, + FFA_TARGET_INFO_MBZ, error_code, + FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, + FFA_PARAM_MBZ, FFA_PARAM_MBZ); } /******************************************************************************* - * This function handles all SMCs in the range reserved for SPCI. Each call is + * This function handles all SMCs in the range reserved for FFA. Each call is * either forwarded to the other security state or handled by the SPM dispatcher ******************************************************************************/ uint64_t spmd_smc_handler(uint32_t smc_fid, @@ -360,7 +360,7 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, SMC_GET_GP(handle, CTX_GPREG_X7)); switch (smc_fid) { - case SPCI_ERROR: + case FFA_ERROR: /* * Check if this is the first invocation of this interface on * this CPU. If so, then indicate that the SPM Core initialised @@ -374,33 +374,33 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, x1, x2, x3, x4, handle); break; /* not reached */ - case SPCI_VERSION: + case FFA_VERSION: /* * TODO: This is an optimization that the version information * provided by the SPM Core manifest is returned by the SPM * dispatcher. It might be a better idea to simply forward this * call to the SPM Core and wash our hands completely. */ - ret = MAKE_SPCI_VERSION(spmc_attrs.major_version, + ret = MAKE_FFA_VERSION(spmc_attrs.major_version, spmc_attrs.minor_version); - SMC_RET8(handle, SPCI_SUCCESS_SMC32, SPCI_TARGET_INFO_MBZ, ret, - SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, - SPCI_PARAM_MBZ, SPCI_PARAM_MBZ); + SMC_RET8(handle, FFA_SUCCESS_SMC32, FFA_TARGET_INFO_MBZ, ret, + FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, + FFA_PARAM_MBZ, FFA_PARAM_MBZ); break; /* not reached */ - case SPCI_FEATURES: + case FFA_FEATURES: /* * This is an optional interface. Do the minimal checks and * forward to SPM Core which will handle it if implemented. */ /* - * Check if x1 holds a valid SPCI fid. This is an + * Check if x1 holds a valid FFA fid. This is an * optimization. */ - if (!is_spci_fid(x1)) { - return spmd_spci_error_return(handle, - SPCI_ERROR_NOT_SUPPORTED); + if (!is_ffa_fid(x1)) { + return spmd_ffa_error_return(handle, + FFA_ERROR_NOT_SUPPORTED); } /* Forward SMC from Normal world to the SPM Core */ @@ -411,68 +411,68 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, /* * Return success if call was from secure world i.e. all - * SPCI functions are supported. This is essentially a + * FFA functions are supported. This is essentially a * nop. */ - SMC_RET8(handle, SPCI_SUCCESS_SMC32, x1, x2, x3, x4, + SMC_RET8(handle, FFA_SUCCESS_SMC32, 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)); break; /* not reached */ - case SPCI_ID_GET: + case FFA_ID_GET: /* - * Returns the ID of the calling SPCI component. + * Returns the ID of the calling FFA component. */ if (!secure_origin) { - SMC_RET8(handle, SPCI_SUCCESS_SMC32, - SPCI_TARGET_INFO_MBZ, SPCI_NS_ENDPOINT_ID, - SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, - SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, - SPCI_PARAM_MBZ); + SMC_RET8(handle, FFA_SUCCESS_SMC32, + FFA_TARGET_INFO_MBZ, FFA_NS_ENDPOINT_ID, + FFA_PARAM_MBZ, FFA_PARAM_MBZ, + FFA_PARAM_MBZ, FFA_PARAM_MBZ, + FFA_PARAM_MBZ); } - SMC_RET8(handle, SPCI_SUCCESS_SMC32, - SPCI_TARGET_INFO_MBZ, spmc_attrs.spmc_id, - SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, - SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, - SPCI_PARAM_MBZ); + SMC_RET8(handle, FFA_SUCCESS_SMC32, + FFA_TARGET_INFO_MBZ, spmc_attrs.spmc_id, + FFA_PARAM_MBZ, FFA_PARAM_MBZ, + FFA_PARAM_MBZ, FFA_PARAM_MBZ, + FFA_PARAM_MBZ); break; /* not reached */ - case SPCI_RX_RELEASE: - case SPCI_RXTX_MAP_SMC32: - case SPCI_RXTX_MAP_SMC64: - case SPCI_RXTX_UNMAP: - case SPCI_MSG_RUN: + case FFA_RX_RELEASE: + case FFA_RXTX_MAP_SMC32: + case FFA_RXTX_MAP_SMC64: + case FFA_RXTX_UNMAP: + case FFA_MSG_RUN: /* This interface must be invoked only by the Normal world */ if (secure_origin) { - return spmd_spci_error_return(handle, - SPCI_ERROR_NOT_SUPPORTED); + return spmd_ffa_error_return(handle, + FFA_ERROR_NOT_SUPPORTED); } /* Fall through to forward the call to the other world */ - case SPCI_PARTITION_INFO_GET: - case SPCI_MSG_SEND: - case SPCI_MSG_SEND_DIRECT_REQ_SMC32: - case SPCI_MSG_SEND_DIRECT_REQ_SMC64: - case SPCI_MSG_SEND_DIRECT_RESP_SMC32: - case SPCI_MSG_SEND_DIRECT_RESP_SMC64: - case SPCI_MEM_DONATE_SMC32: - case SPCI_MEM_DONATE_SMC64: - case SPCI_MEM_LEND_SMC32: - case SPCI_MEM_LEND_SMC64: - case SPCI_MEM_SHARE_SMC32: - case SPCI_MEM_SHARE_SMC64: - case SPCI_MEM_RETRIEVE_REQ_SMC32: - case SPCI_MEM_RETRIEVE_REQ_SMC64: - case SPCI_MEM_RETRIEVE_RESP: - case SPCI_MEM_RELINQUISH: - case SPCI_MEM_RECLAIM: - case SPCI_SUCCESS_SMC32: - case SPCI_SUCCESS_SMC64: + case FFA_PARTITION_INFO_GET: + case FFA_MSG_SEND: + case FFA_MSG_SEND_DIRECT_REQ_SMC32: + case FFA_MSG_SEND_DIRECT_REQ_SMC64: + case FFA_MSG_SEND_DIRECT_RESP_SMC32: + case FFA_MSG_SEND_DIRECT_RESP_SMC64: + case FFA_MEM_DONATE_SMC32: + case FFA_MEM_DONATE_SMC64: + case FFA_MEM_LEND_SMC32: + case FFA_MEM_LEND_SMC64: + case FFA_MEM_SHARE_SMC32: + case FFA_MEM_SHARE_SMC64: + case FFA_MEM_RETRIEVE_REQ_SMC32: + case FFA_MEM_RETRIEVE_REQ_SMC64: + case FFA_MEM_RETRIEVE_RESP: + case FFA_MEM_RELINQUISH: + case FFA_MEM_RECLAIM: + case FFA_SUCCESS_SMC32: + case FFA_SUCCESS_SMC64: /* * TODO: Assume that no requests originate from EL3 at the * moment. This will change if a SP service is required in @@ -484,7 +484,7 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, x1, x2, x3, x4, handle); break; /* not reached */ - case SPCI_MSG_WAIT: + case FFA_MSG_WAIT: /* * Check if this is the first invocation of this interface on * this CPU from the Secure world. If so, then indicate that the @@ -496,11 +496,11 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, /* Fall through to forward the call to the other world */ - case SPCI_MSG_YIELD: + case FFA_MSG_YIELD: /* This interface must be invoked only by the Secure world */ if (!secure_origin) { - return spmd_spci_error_return(handle, - SPCI_ERROR_NOT_SUPPORTED); + return spmd_ffa_error_return(handle, + FFA_ERROR_NOT_SUPPORTED); } return spmd_smc_forward(smc_fid, secure_origin, @@ -509,6 +509,6 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, default: WARN("SPM: Unsupported call 0x%08x\n", smc_fid); - return spmd_spci_error_return(handle, SPCI_ERROR_NOT_SUPPORTED); + 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 232031bb3..494630907 100644 --- a/services/std_svc/spmd/spmd_private.h +++ b/services/std_svc/spmd/spmd_private.h @@ -30,7 +30,7 @@ #define SPMD_C_RT_CTX_ENTRIES (SPMD_C_RT_CTX_SIZE >> DWORD_SHIFT) #ifndef __ASSEMBLER__ -#include +#include #include typedef enum spmc_state { @@ -49,11 +49,11 @@ typedef struct spmd_spm_core_context { } spmd_spm_core_context_t; /* - * Reserve ID for NS physical SPCI Endpoint. + * Reserve ID for NS physical FFA Endpoint. */ -#define SPCI_NS_ENDPOINT_ID U(0) +#define FFA_NS_ENDPOINT_ID U(0) -/* Mask and shift to check valid secure SPCI Endpoint ID. */ +/* Mask and shift to check valid secure FFA Endpoint ID. */ #define SPMC_SECURE_ID_MASK U(1) #define SPMC_SECURE_ID_SHIFT U(15) diff --git a/services/std_svc/std_svc_setup.c b/services/std_svc/std_svc_setup.c index 895fd292f..cdd17bc1d 100644 --- a/services/std_svc/std_svc_setup.c +++ b/services/std_svc/std_svc_setup.c @@ -123,10 +123,10 @@ static uintptr_t std_svc_smc_handler(uint32_t smc_fid, #if defined(SPD_spmd) /* - * Dispatch SPCI calls to the SPCI SMC handler implemented by the SPM + * Dispatch FFA calls to the FFA SMC handler implemented by the SPM * dispatcher and return its return value */ - if (is_spci_fid(smc_fid)) { + if (is_ffa_fid(smc_fid)) { return spmd_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags); } -- cgit v1.2.3 From 00f850871a6359bec75ce30443d09ab897948de4 Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Wed, 8 Apr 2020 13:04:33 +0100 Subject: doc: Fixes in PSA FF-A binding document - Fix possible run-time ELs value and xlat-granule size. - Remove mandatory field for stream-ids. - Define interrupts attributes to . - Remove mem-manage field. - Add description for memory/device region attributes. Co-authored-by: Manish Pandey Signed-off-by: Louis Mayencourt Signed-off-by: Manish Pandey Change-Id: I71cf4406c78eaf894fa6532f83467a6f4110b344 --- docs/components/psa-ffa-manifest-binding.rst | 40 ++++++++++++---------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/docs/components/psa-ffa-manifest-binding.rst b/docs/components/psa-ffa-manifest-binding.rst index 7a1c1eb07..09894ae57 100644 --- a/docs/components/psa-ffa-manifest-binding.rst +++ b/docs/components/psa-ffa-manifest-binding.rst @@ -7,8 +7,8 @@ according to the PSA FF-A specification. Version 1.0 ----------- -psa-ffa-manifest-partition -^^^^^^^^^^^^^^^^^^^^^^^^^^ +Partition Properties +^^^^^^^^^^^^^^^^^^^^ - compatible [mandatory] - value type: @@ -34,16 +34,6 @@ psa-ffa-manifest-partition - value type: - An array consisting of 4 values, identifying the UUID of the service implemented by this partition. The UUID format is described in RFC 4122. - UUID can be shared by multiple instances of partitions that offer the same - service For example: - - - If there are multiple instances of a Trusted OS, then the UUID can be - shared by all instances. - - The TEE driver in the HLOS can use the UUID with the - FFA_PARTITION_INFO_GET interface to determine the: - - - Number of Trusted OSs - - The partition ID of each instance of the Trusted OS - id - value type: @@ -75,9 +65,6 @@ psa-ffa-manifest-partition - 0x0: EL1 - 0x1: S_EL0 - 0x2: S_EL1 - - 0x3: EL2 - - 0x4: Supervisor mode - - 0x5: Secure User mode - execution-state [mandatory] - value type: @@ -104,7 +91,7 @@ psa-ffa-manifest-partition - 0x0: 4k - 0x1: 16k - - 0x2: 32k + - 0x2: 64k - boot-order - value type: @@ -159,7 +146,7 @@ psa-ffa-manifest-partition - List of tuples, identifying the IDs this partition is acting as proxy for. -memory-regions +Memory Regions -------------- - compatible [mandatory] @@ -177,7 +164,11 @@ memory-regions - attributes [mandatory] - value type: - - ?? TO DEFINE + - Mapping modes: ORed to get required permission + + - 0x1: Read + - 0x2: Write + - 0x4: Execute - base-address - value type: @@ -191,7 +182,7 @@ memory-regions then communicate the region properties (including the base address chosen by the partition manager) to the partition. -device-regions +Device Regions -------------- - compatible [mandatory] @@ -213,7 +204,11 @@ device-regions - attributes [mandatory] - value type: - - ?? TO DEFINE + - Mapping modes: ORed to get required permission + + - 0x1: Read + - 0x2: Write + - 0x4: Execute - smmu-id - value type: @@ -222,19 +217,18 @@ device-regions upstream of. If the field is omitted then it is assumed that the device is not upstream of any SMMU. -- stream-ids [mandatory] +- stream-ids - value type: - A list of (id, mem-manage) pair, where: - id: A unique value amongst all devices assigned to the partition. - - mem-manage: A value used in memory management operations. - interrupts [mandatory] - value type: - A list of (id, attributes) pair describing the device interrupts, where: - id: The interrupt IDs. - - attributes: A ?? TO DEFINE value, + - attributes: A value, containing the attributes for each interrupt ID: - Interrupt type: SPI, PPI, SGI -- cgit v1.2.3 From 42d9b3aaf473a1e01475a020644b504ecc3d4443 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Sun, 17 May 2020 10:21:09 +0200 Subject: ti: k3: common: Implement stub system_off PSCI demands that SYSTEM_OFF must not return. While it seems like a generic ATF bug that this is possible when a platform does not Implement a corresponding handler, let's do that here until it's addressed differently. Signed-off-by: Jan Kiszka Change-Id: I4c08948b18bbfdc3a24214f2ae0fbad9e017ada1 --- plat/ti/k3/common/k3_psci.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/plat/ti/k3/common/k3_psci.c b/plat/ti/k3/common/k3_psci.c index d6ed7667e..050074007 100644 --- a/plat/ti/k3/common/k3_psci.c +++ b/plat/ti/k3/common/k3_psci.c @@ -203,6 +203,13 @@ void k3_pwr_domain_on_finish(const psci_power_state_t *target_state) k3_gic_cpuif_enable(); } +static void __dead2 k3_system_off(void) +{ + ERROR("System Off: operation not handled.\n"); + while (true) + wfi(); +} + static void __dead2 k3_system_reset(void) { /* Send the system reset request to system firmware */ @@ -232,6 +239,7 @@ static const plat_psci_ops_t k3_plat_psci_ops = { .pwr_domain_on = k3_pwr_domain_on, .pwr_domain_off = k3_pwr_domain_off, .pwr_domain_on_finish = k3_pwr_domain_on_finish, + .system_off = k3_system_off, .system_reset = k3_system_reset, .validate_power_state = k3_validate_power_state, .validate_ns_entrypoint = k3_validate_ns_entrypoint -- cgit v1.2.3 From b62a5313ef9d4962b0593573d34594ad9053564b Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Fri, 15 May 2020 12:05:51 +0200 Subject: doc: Fix plat_sdei_validate_entry_point() documentation Document the second argument of the function. Minor rewording. Change-Id: I190794b8cc74c99db4cfe6efc225217c32dd0774 Signed-off-by: Sandrine Bailleux --- docs/getting_started/porting-guide.rst | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst index 2ad725632..b7a93e40a 100644 --- a/docs/getting_started/porting-guide.rst +++ b/docs/getting_started/porting-guide.rst @@ -1956,23 +1956,27 @@ be higher than Normal |SDEI| priority. Functions ......... -Function: int plat_sdei_validate_entry_point(uintptr_t ep) [optional] -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Function: int plat_sdei_validate_entry_point() [optional] +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :: - Argument: uintptr_t + Argument: uintptr_t ep, unsigned int client_mode Return: int -This function validates the address of client entry points provided for both -event registration and *Complete and Resume* |SDEI| calls. The function -takes one argument, which is the address of the handler the |SDEI| client -requested to register. The function must return ``0`` for successful validation, -or ``-1`` upon failure. +This function validates the entry point address of the event handler provided by +the client for both event registration and *Complete and Resume* |SDEI| calls. +The function ensures that the address is valid in the client translation regime. + +The second argument is the exception level that the client is executing in. It +can be Non-Secure EL1 or Non-Secure EL2. + +The function must return ``0`` for successful validation, or ``-1`` upon failure. The default implementation always returns ``0``. On Arm platforms, this function -is implemented to translate the entry point to physical address, and further to -ensure that the address is located in Non-secure DRAM. +translates the entry point address within the client translation regime and +further ensures that the resulting physical address is located in Non-secure +DRAM. Function: void plat_sdei_handle_masked_trigger(uint64_t mpidr, unsigned int intr) [optional] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- cgit v1.2.3 From dbcc44a10ece0c4e02efb1f9ff52dad38dc6fc89 Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Tue, 26 May 2020 13:16:41 +0100 Subject: TF-A: Fix wrong register read for MPAM extension This patch fixes wrong ID_AA64DFR0_EL1 register read instead of ID_AA64PFR0_EL1 to detect support for MPAM extension. It also implements get_mpam_version() function which returns MPAM version as: 0x00: None Armv8.0 or later; 0x01: v0.1 Armv8.4 or later; 0x10: v1.0 Armv8.2 or later; 0x11: v1.1 Armv8.4 or later; Change-Id: I31d776b1a1b60cb16e5e62296d70adb129d7b760 Reported-by: Matteo Zini Signed-off-by: Alexei Fedorov --- include/arch/aarch64/arch.h | 3 +++ include/arch/aarch64/arch_features.h | 17 +++++++++++++++++ lib/extensions/mpam/mpam.c | 21 +++++++++------------ 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index 92e673771..9d4ad3ba8 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -259,6 +259,9 @@ #define MTE_IMPLEMENTED_EL0 ULL(1) /* MTE is only implemented at EL0 */ #define MTE_IMPLEMENTED_ELX ULL(2) /* MTE is implemented at all ELs */ +#define ID_AA64PFR1_MPAM_FRAC_SHIFT ULL(16) +#define ID_AA64PFR1_MPAM_FRAC_MASK ULL(0xf) + /* ID_PFR1_EL1 definitions */ #define ID_PFR1_VIRTEXT_SHIFT U(12) #define ID_PFR1_VIRTEXT_MASK U(0xf) diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h index 49d827dba..321485aed 100644 --- a/include/arch/aarch64/arch_features.h +++ b/include/arch/aarch64/arch_features.h @@ -64,4 +64,21 @@ static inline bool is_armv8_6_twed_present(void) ID_AA64MMFR1_EL1_TWED_MASK) == ID_AA64MMFR1_EL1_TWED_SUPPORTED); } +/* + * Return MPAM version: + * + * 0x00: None Armv8.0 or later + * 0x01: v0.1 Armv8.4 or later + * 0x10: v1.0 Armv8.2 or later + * 0x11: v1.1 Armv8.4 or later + * + */ +static inline unsigned int get_mpam_version(void) +{ + return (unsigned int)((((read_id_aa64pfr0_el1() >> + ID_AA64PFR0_MPAM_SHIFT) & ID_AA64PFR0_MPAM_MASK) << 4) | + ((read_id_aa64pfr1_el1() >> + ID_AA64PFR1_MPAM_FRAC_SHIFT) & ID_AA64PFR1_MPAM_FRAC_MASK)); +} + #endif /* ARCH_FEATURES_H */ diff --git a/lib/extensions/mpam/mpam.c b/lib/extensions/mpam/mpam.c index e794f013b..65601ddec 100644 --- a/lib/extensions/mpam/mpam.c +++ b/lib/extensions/mpam/mpam.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,20 +7,16 @@ #include #include +#include #include #include -bool mpam_supported(void) -{ - uint64_t features = read_id_aa64dfr0_el1() >> ID_AA64PFR0_MPAM_SHIFT; - - return ((features & ID_AA64PFR0_MPAM_MASK) != 0U); -} - void mpam_enable(bool el2_unused) { - if (!mpam_supported()) + /* Check if MPAM is implemented */ + if (get_mpam_version() == 0U) { return; + } /* * Enable MPAM, and disable trapping to EL3 when lower ELs access their @@ -34,10 +30,11 @@ void mpam_enable(bool el2_unused) * If EL2 is implemented and used, enable trapping to EL2. */ if (el2_unused) { - write_mpam2_el2(0); + write_mpam2_el2(0ULL); - if ((read_mpamidr_el1() & MPAMIDR_HAS_HCR_BIT) != 0U) - write_mpamhcr_el2(0); + if ((read_mpamidr_el1() & MPAMIDR_HAS_HCR_BIT) != 0U) { + write_mpamhcr_el2(0ULL); + } } else { write_mpam2_el2(MPAM2_EL2_TRAPMPAM0EL1 | MPAM2_EL2_TRAPMPAM1EL1); -- cgit v1.2.3 From b58956e976626b80508a95d3521c4b70ac31f9c9 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Wed, 27 May 2020 09:39:42 +0100 Subject: Fix the build error for dualroot chain of trust. Fixed build error for dualroot chain of trust. Build error were thrown as below while compiling the code for dualroot chain of trust: aarch64-none-elf-ld.bfd: ./build/fvp/debug/bl1/tbbr_cot_bl1.o: (.bss.auth_img_flags+0x0): multiple definition of `auth_img_flags'; ./build/fvp/debug/bl1/cot.o:(.bss.auth_img_flags+0x0): first defined here aarch64-none-elf-ld.bfd: ./build/fvp/debug/bl1/tbbr_cot_bl1.o: (.rodata.cot_desc_size+0x0): multiple definition of `cot_desc_size'; ./build/fvp/debug/bl1/cot.o:(.rodata.cot_desc_size+0x0): first defined here aarch64-none-elf-ld.bfd: ./build/fvp/debug/bl1/tbbr_cot_bl1.o: (.rodata.cot_desc_ptr+0x0): multiple definition of `cot_desc_ptr'; ./build/fvp/debug/bl1/cot.o:(.rodata.cot_desc_ptr+0x0): first defined here Signed-off-by: Manish V Badarkhe Change-Id: I1a426c4e7f5f8013d71dafc176c7467c1b329757 --- plat/arm/common/arm_common.mk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index a28736808..a92bf2578 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -298,6 +298,8 @@ ifneq (${TRUSTED_BOARD_BOOT},0) # Include the selected chain of trust sources. ifeq (${COT},tbbr) AUTH_SOURCES += drivers/auth/tbbr/tbbr_cot_common.c + BL1_SOURCES += drivers/auth/tbbr/tbbr_cot_bl1.c + BL2_SOURCES += drivers/auth/tbbr/tbbr_cot_bl2.c else ifeq (${COT},dualroot) AUTH_SOURCES += drivers/auth/dualroot/cot.c else @@ -307,12 +309,10 @@ ifneq (${TRUSTED_BOARD_BOOT},0) BL1_SOURCES += ${AUTH_SOURCES} \ bl1/tbbr/tbbr_img_desc.c \ plat/arm/common/arm_bl1_fwu.c \ - drivers/auth/tbbr/tbbr_cot_bl1.c \ plat/common/tbbr/plat_tbbr.c BL2_SOURCES += ${AUTH_SOURCES} \ - plat/common/tbbr/plat_tbbr.c \ - drivers/auth/tbbr/tbbr_cot_bl2.c + plat/common/tbbr/plat_tbbr.c $(eval $(call TOOL_ADD_IMG,ns_bl2u,--fwu,FWU_)) -- cgit v1.2.3 From f5c58af653b69687b17aac10da1d62179abe48ec Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Fri, 17 Apr 2020 16:13:39 +0100 Subject: plat/arm: Introduce TC0 platform This patch adds support for Total Compute (TC0) platform. It is an initial port and additional features are expected to be added later. TC0 has a SCP which brings the primary Cortex-A out of reset which starts executing BL1. TF-A optionally authenticates the SCP ram-fw available in FIP and makes it available for SCP to copy. Some of the major features included and tested in this platform port include TBBR, PSCI, MHUv2 and DVFS. Change-Id: I1675e9d200ca7687c215009eef483d9b3ee764ef Signed-off-by: Usama Arif --- docs/plat/arm/index.rst | 1 + docs/plat/arm/tc0/index.rst | 50 +++++ fdts/tc0.dts | 316 ++++++++++++++++++++++++++++++ plat/arm/board/tc0/fdts/tc0_fw_config.dts | 46 +++++ plat/arm/board/tc0/include/plat_macros.S | 24 +++ plat/arm/board/tc0/include/platform_def.h | 194 ++++++++++++++++++ plat/arm/board/tc0/include/tc0_helpers.S | 61 ++++++ plat/arm/board/tc0/include/tc0_plat.h | 12 ++ plat/arm/board/tc0/platform.mk | 97 +++++++++ plat/arm/board/tc0/tc0_bl31_setup.c | 55 ++++++ plat/arm/board/tc0/tc0_err.c | 17 ++ plat/arm/board/tc0/tc0_interconnect.c | 35 ++++ plat/arm/board/tc0/tc0_plat.c | 145 ++++++++++++++ plat/arm/board/tc0/tc0_security.c | 12 ++ plat/arm/board/tc0/tc0_topology.c | 55 ++++++ plat/arm/board/tc0/tc0_trusted_boot.c | 26 +++ 16 files changed, 1146 insertions(+) create mode 100644 docs/plat/arm/tc0/index.rst create mode 100644 fdts/tc0.dts create mode 100644 plat/arm/board/tc0/fdts/tc0_fw_config.dts create mode 100644 plat/arm/board/tc0/include/plat_macros.S create mode 100644 plat/arm/board/tc0/include/platform_def.h create mode 100644 plat/arm/board/tc0/include/tc0_helpers.S create mode 100644 plat/arm/board/tc0/include/tc0_plat.h create mode 100644 plat/arm/board/tc0/platform.mk create mode 100644 plat/arm/board/tc0/tc0_bl31_setup.c create mode 100644 plat/arm/board/tc0/tc0_err.c create mode 100644 plat/arm/board/tc0/tc0_interconnect.c create mode 100644 plat/arm/board/tc0/tc0_plat.c create mode 100644 plat/arm/board/tc0/tc0_security.c create mode 100644 plat/arm/board/tc0/tc0_topology.c create mode 100644 plat/arm/board/tc0/tc0_trusted_boot.c diff --git a/docs/plat/arm/index.rst b/docs/plat/arm/index.rst index e26f75e56..1afe475c6 100644 --- a/docs/plat/arm/index.rst +++ b/docs/plat/arm/index.rst @@ -8,6 +8,7 @@ Arm Development Platforms juno/index fvp/index fvp-ve/index + tc0/index arm-build-options This chapter holds documentation related to Arm's development platforms, diff --git a/docs/plat/arm/tc0/index.rst b/docs/plat/arm/tc0/index.rst new file mode 100644 index 000000000..34d1f1342 --- /dev/null +++ b/docs/plat/arm/tc0/index.rst @@ -0,0 +1,50 @@ +TC0 Total Compute Platform +========================== + +Some of the features of TC0 platform referenced in TF-A include: + +- A `System Control Processor `_ + to abstract power and system management tasks away from application + processors. The RAM firmware for SCP is included in the TF-A FIP and is + loaded by AP BL2 from FIP in flash to SRAM for copying by SCP (SCP has access + to AP SRAM). +- GICv4 +- Trusted Board Boot +- SCMI +- MHUv2 + +Boot Sequence +------------- + +The execution begins from SCP_BL1. SCP_BL1 powers up the AP which starts +executing AP_BL1 and then executes AP_BL2 which loads the SCP_BL2 from +FIP to SRAM. The SCP has access to AP SRAM. The address and size of SCP_BL2 +is communicated to SCP using SDS. SCP copies SCP_BL2 from SRAM to its own +RAM and starts executing it. The AP then continues executing the rest of TF-A +stages including BL31 runtime stage and hands off executing to +Non-secure world (u-boot). + +Build Procedure (TF-A only) +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Obtain arm `toolchain `_. + Set the CROSS_COMPILE environment variable to point to the toolchain folder. + +- Build TF-A: + + .. code:: shell + + make PLAT=tc0 BL33= \ + SCP_BL2= 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) 2020, Arm Limited. All rights reserved.* diff --git a/fdts/tc0.dts b/fdts/tc0.dts new file mode 100644 index 000000000..e736e4975 --- /dev/null +++ b/fdts/tc0.dts @@ -0,0 +1,316 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +/ { + compatible = "arm,tc0"; + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + aliases { + serial0 = &soc_uart0; + }; + + chosen { + stdout-path = "soc_uart0:115200n8"; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu-map { + cluster0 { + core0 { + cpu = <&CPU0>; + }; + core1 { + cpu = <&CPU1>; + }; + core2 { + cpu = <&CPU2>; + }; + core3 { + cpu = <&CPU3>; + }; + }; + }; + + CPU0:cpu@0 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0>; + enable-method = "psci"; + clocks = <&scmi_dvfs 0>; + }; + + CPU1:cpu@100 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x100>; + enable-method = "psci"; + clocks = <&scmi_dvfs 0>; + }; + + CPU2:cpu@200 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x200>; + enable-method = "psci"; + clocks = <&scmi_dvfs 0>; + }; + + CPU3:cpu@300 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x300>; + enable-method = "psci"; + clocks = <&scmi_dvfs 0>; + }; + + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x0 0x80000000 0x0 0x80000000>; + }; + + psci { + compatible = "arm,psci-1.0", "arm,psci-0.2", "arm,psci"; + method = "smc"; + }; + + sram: sram@6000000 { + compatible = "mmio-sram"; + reg = <0x0 0x06000000 0x0 0x8000>; + + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x0 0x06000000 0x8000>; + + cpu_scp_scmi_mem: scp-shmem@0 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0x80>; + }; + }; + + mbox_db_rx: mhu@45010000 { + compatible = "arm,mhuv2","arm,primecell"; + reg = <0x0 0x45010000 0x0 0x1000>; + clocks = <&soc_refclk100mhz>; + clock-names = "apb_pclk"; + #mbox-cells = <1>; + interrupts = <0 316 4>; + interrupt-names = "mhu_rx"; + mhu-protocol = "doorbell"; + }; + + mbox_db_tx: mhu@45000000 { + compatible = "arm,mhuv2","arm,primecell"; + reg = <0x0 0x45000000 0x0 0x1000>; + clocks = <&soc_refclk100mhz>; + clock-names = "apb_pclk"; + #mbox-cells = <1>; + interrupt-names = "mhu_tx"; + mhu-protocol = "doorbell"; + }; + + scmi { + compatible = "arm,scmi"; + method = "mailbox-doorbell"; + mbox-names = "tx", "rx"; + mboxes = <&mbox_db_tx 0 &mbox_db_rx 0>; + shmem = <&cpu_scp_scmi_mem &cpu_scp_scmi_mem>; + #address-cells = <1>; + #size-cells = <0>; + + scmi_dvfs: protocol@13 { + reg = <0x13>; + #clock-cells = <1>; + }; + + scmi_clk: protocol@14 { + reg = <0x14>; + #clock-cells = <1>; + }; + }; + + gic: interrupt-controller@2c010000 { + compatible = "arm,gic-600", "arm,gic-v3"; + #address-cells = <2>; + #interrupt-cells = <3>; + #size-cells = <2>; + ranges; + interrupt-controller; + reg = <0x0 0x30000000 0 0x10000>, /* GICD */ + <0x0 0x30140000 0 0x200000>; /* GICR */ + interrupts = <0x1 0x9 0x4>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <0x1 13 0x8>, + <0x1 14 0x8>, + <0x1 11 0x8>, + <0x1 10 0x8>; + }; + + soc_refclk100mhz: refclk100mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <100000000>; + clock-output-names = "apb_pclk"; + }; + + soc_refclk60mhz: refclk60mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <60000000>; + clock-output-names = "iofpga_clk"; + }; + + soc_uartclk: uartclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <50000000>; + clock-output-names = "uartclk"; + }; + + soc_uart0: uart@7ff80000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0 0x7ff80000 0x0 0x1000>; + interrupts = <0x0 116 0x4>; + clocks = <&soc_uartclk>, <&soc_refclk100mhz>; + clock-names = "uartclk", "apb_pclk"; + status = "okay"; + }; + + vencoder { + compatible = "drm,virtual-encoder"; + + port { + vencoder_in: endpoint { + remote-endpoint = <&hdlcd_out>; + }; + }; + + display-timings { + panel-timing { + clock-frequency = <25175000>; + hactive = <640>; + vactive = <480>; + hfront-porch = <16>; + hback-porch = <48>; + hsync-len = <96>; + vfront-porch = <10>; + vback-porch = <33>; + vsync-len = <2>; + }; + }; + + }; + + hdlcd: hdlcd@7ff60000 { + compatible = "arm,hdlcd"; + reg = <0x0 0x7ff60000 0x0 0x1000>; + interrupts = <0x0 117 0x4>; + clocks = <&fake_hdlcd_clk>; + clock-names = "pxlclk"; + status = "ok"; + + port { + hdlcd_out: endpoint { + remote-endpoint = <&vencoder_in>; + }; + }; + }; + + fake_hdlcd_clk: fake-hdlcd-clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25175000>; + clock-output-names = "pxlclk"; + }; + + ethernet@18000000 { + compatible = "smsc,lan91c111"; + reg = <0x0 0x18000000 0x0 0x10000>; + interrupts = <0 109 4>; + }; + + kmi@1c060000 { + compatible = "arm,pl050", "arm,primecell"; + reg = <0x0 0x001c060000 0x0 0x1000>; + interrupts = <0 197 4>; + clocks = <&bp_clock24mhz>, <&bp_clock24mhz>; + clock-names = "KMIREFCLK", "apb_pclk"; + }; + + kmi@1c070000 { + compatible = "arm,pl050", "arm,primecell"; + reg = <0x0 0x001c070000 0x0 0x1000>; + interrupts = <0 103 4>; + clocks = <&bp_clock24mhz>, <&bp_clock24mhz>; + clock-names = "KMIREFCLK", "apb_pclk"; + }; + + bp_clock24mhz: clock24mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24000000>; + clock-output-names = "bp:clock24mhz"; + }; + + virtio_block@1c130000 { + compatible = "virtio,mmio"; + reg = <0x0 0x1c130000 0x0 0x200>; + interrupts = <0 204 4>; + }; + + dp0: display@2cc00000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "arm,mali-d71"; + reg = <0 0x2cc00000 0 0x20000>; + interrupts = <0 69 4>; + interrupt-names = "DPU"; + clocks = <&scmi_clk 0>; + clock-names = "aclk"; + status = "disabled"; + pl0: pipeline@0 { + reg = <0>; + clocks = <&scmi_clk 1>; + clock-names = "pxclk"; + pl_id = <0>; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + dp_pl0_out0: endpoint { + remote-endpoint = <&vencoder_in>; + }; + }; + }; + }; + + pl1: pipeline@1 { + reg = <1>; + clocks = <&scmi_clk 2>; + clock-names = "pxclk"; + pl_id = <1>; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + }; + }; + }; + }; +}; diff --git a/plat/arm/board/tc0/fdts/tc0_fw_config.dts b/plat/arm/board/tc0/fdts/tc0_fw_config.dts new file mode 100644 index 000000000..8d7faf8b4 --- /dev/null +++ b/plat/arm/board/tc0/fdts/tc0_fw_config.dts @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +/dts-v1/; + +/ { + dtb-registry { + compatible = "fconf,dyn_cfg-dtb_registry"; + + /* tb_fw_config is temporarily contained in this dtb */ + tb_fw-config { + load-address = <0x0 0x2001010>; + max-size = <0x200>; + id = ; + }; + + hw-config { + load-address = <0x0 0x83000000>; + max-size = <0x01000000>; + id = ; + }; + }; + + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + /* + * The following two entries are placeholders for Mbed TLS + * heap information. The default values don't matter since + * they will be overwritten by BL1. + * In case of having shared Mbed TLS heap between BL1 and BL2, + * BL1 will populate these two properties with the respective + * info about the shared heap. This info will be available for + * BL2 in order to locate and re-use the heap. + */ + mbedtls_heap_addr = <0x0 0x0>; + mbedtls_heap_size = <0x0>; + }; +}; diff --git a/plat/arm/board/tc0/include/plat_macros.S b/plat/arm/board/tc0/include/plat_macros.S new file mode 100644 index 000000000..6006fa5b8 --- /dev/null +++ b/plat/arm/board/tc0/include/plat_macros.S @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef PLAT_MACROS_S +#define PLAT_MACROS_S + +#include + +/* --------------------------------------------- + * The below required platform porting macro + * prints out relevant platform registers + * whenever an unhandled exception is taken in + * BL31. + * + * There are currently no platform specific regs + * to print. + * --------------------------------------------- + */ + .macro plat_crash_print_regs + .endm + +#endif /* PLAT_MACROS_S */ diff --git a/plat/arm/board/tc0/include/platform_def.h b/plat/arm/board/tc0/include/platform_def.h new file mode 100644 index 000000000..56c71c16c --- /dev/null +++ b/plat/arm/board/tc0/include/platform_def.h @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PLATFORM_CORE_COUNT 4 + +#define PLAT_ARM_TRUSTED_SRAM_SIZE 0x00080000 /* 512 KB */ + +/* + * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the + * plat_arm_mmap array defined for each BL stage. + */ +#if defined(IMAGE_BL31) +# if SPM_MM +# define PLAT_ARM_MMAP_ENTRIES 9 +# define MAX_XLAT_TABLES 7 +# define PLAT_SP_IMAGE_MMAP_REGIONS 7 +# define PLAT_SP_IMAGE_MAX_XLAT_TABLES 10 +# else +# define PLAT_ARM_MMAP_ENTRIES 8 +# define MAX_XLAT_TABLES 8 +# endif +#elif defined(IMAGE_BL32) +# define PLAT_ARM_MMAP_ENTRIES 8 +# define MAX_XLAT_TABLES 5 +#elif !USE_ROMLIB +# define PLAT_ARM_MMAP_ENTRIES 11 +# define MAX_XLAT_TABLES 7 +#else +# define PLAT_ARM_MMAP_ENTRIES 12 +# define MAX_XLAT_TABLES 6 +#endif + +/* + * 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 0xC000 + +/* + * PLAT_ARM_MAX_ROMLIB_RW_SIZE is define to use a full page + */ + +#if USE_ROMLIB +#define PLAT_ARM_MAX_ROMLIB_RW_SIZE 0x1000 +#define PLAT_ARM_MAX_ROMLIB_RO_SIZE 0xe000 +#else +#define PLAT_ARM_MAX_ROMLIB_RW_SIZE 0 +#define PLAT_ARM_MAX_ROMLIB_RO_SIZE 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 +# define PLAT_ARM_MAX_BL2_SIZE 0x1E000 +#else +# define PLAT_ARM_MAX_BL2_SIZE 0x11000 +#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 0x3B000 + +/* + * Size of cacheable stacks + */ +#if defined(IMAGE_BL1) +# if TRUSTED_BOARD_BOOT +# define PLATFORM_STACK_SIZE 0x1000 +# else +# define PLATFORM_STACK_SIZE 0x440 +# endif +#elif defined(IMAGE_BL2) +# if TRUSTED_BOARD_BOOT +# define PLATFORM_STACK_SIZE 0x1000 +# else +# define PLATFORM_STACK_SIZE 0x400 +# endif +#elif defined(IMAGE_BL2U) +# define PLATFORM_STACK_SIZE 0x400 +#elif defined(IMAGE_BL31) +# if SPM_MM +# define PLATFORM_STACK_SIZE 0x500 +# else +# define PLATFORM_STACK_SIZE 0x400 +# endif +#elif defined(IMAGE_BL32) +# define PLATFORM_STACK_SIZE 0x440 +#endif + + +#define TC0_DEVICE_BASE 0x21000000 +#define TC0_DEVICE_SIZE 0x5f000000 + +// TC0_MAP_DEVICE covers different peripherals +// available to the platform +#define TC0_MAP_DEVICE MAP_REGION_FLAT( \ + TC0_DEVICE_BASE, \ + TC0_DEVICE_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + + +#define TC0_FLASH0_RO MAP_REGION_FLAT(V2M_FLASH0_BASE,\ + V2M_FLASH0_SIZE, \ + MT_DEVICE | MT_RO | MT_SECURE) + +#define PLAT_ARM_NSTIMER_FRAME_ID 0 + +#define PLAT_ARM_TRUSTED_ROM_BASE 0x0 +#define PLAT_ARM_TRUSTED_ROM_SIZE 0x00080000 /* 512KB */ + +#define PLAT_ARM_NSRAM_BASE 0x06000000 +#define PLAT_ARM_NSRAM_SIZE 0x00080000 /* 512KB */ + +#define PLAT_ARM_DRAM2_BASE ULL(0x8080000000) +#define PLAT_ARM_DRAM2_SIZE ULL(0x180000000) + +#define PLAT_ARM_G1S_IRQ_PROPS(grp) CSS_G1S_IRQ_PROPS(grp) +#define PLAT_ARM_G0_IRQ_PROPS(grp) ARM_G0_IRQ_PROPS(grp) + +#define PLAT_ARM_SP_IMAGE_STACK_BASE (PLAT_SP_IMAGE_NS_BUF_BASE + \ + PLAT_SP_IMAGE_NS_BUF_SIZE) + +/******************************************************************************* + * Memprotect definitions + ******************************************************************************/ +/* PSCI memory protect definitions: + * This variable is stored in a non-secure flash because some ARM reference + * platforms do not have secure NVRAM. Real systems that provided MEM_PROTECT + * support must use a secure NVRAM to store the PSCI MEM_PROTECT definitions. + */ +#define PLAT_ARM_MEM_PROT_ADDR (V2M_FLASH0_BASE + \ + V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE) + +/*Secure Watchdog Constants */ +#define SBSA_SECURE_WDOG_BASE UL(0x2A480000) +#define SBSA_SECURE_WDOG_TIMEOUT UL(100) + +#define PLAT_ARM_SCMI_CHANNEL_COUNT 1 + +#define PLAT_ARM_CLUSTER_COUNT U(1) +#define PLAT_MAX_CPUS_PER_CLUSTER U(4) +#define PLAT_MAX_PE_PER_CPU U(1) + +#define PLAT_CSS_MHU_BASE UL(0x45400000) +#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE + +#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL2 +#define PLAT_MAX_PWR_LVL ARM_PWR_LVL1 + +/* + * Physical and virtual address space limits for MMU in AARCH64 + */ +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 36) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 36) + +/* GIC related constants */ +#define PLAT_ARM_GICD_BASE UL(0x30000000) +#define PLAT_ARM_GICC_BASE UL(0x2C000000) +#define PLAT_ARM_GICR_BASE UL(0x30140000) + +/* + * PLAT_CSS_MAX_SCP_BL2_SIZE is calculated using the current + * SCP_BL2 size plus a little space for growth. + */ +#define PLAT_CSS_MAX_SCP_BL2_SIZE 0x14000 + +/* + * PLAT_CSS_MAX_SCP_BL2U_SIZE is calculated using the current + * SCP_BL2U size plus a little space for growth. + */ +#define PLAT_CSS_MAX_SCP_BL2U_SIZE 0x14000 + +#endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/tc0/include/tc0_helpers.S b/plat/arm/board/tc0/include/tc0_helpers.S new file mode 100644 index 000000000..90623a273 --- /dev/null +++ b/plat/arm/board/tc0/include/tc0_helpers.S @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + + .globl plat_arm_calc_core_pos + .globl plat_reset_handler + + /* --------------------------------------------------------------------- + * unsigned int plat_arm_calc_core_pos(u_register_t mpidr) + * + * Function to calculate the core position on TC0. + * + * (ClusterId * PLAT_MAX_CPUS_PER_CLUSTER * PLAT_MAX_PE_PER_CPU) + + * (CPUId * PLAT_MAX_PE_PER_CPU) + + * ThreadId + * + * which can be simplified as: + * + * ((ClusterId * PLAT_MAX_CPUS_PER_CLUSTER + CPUId) * PLAT_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, #PLAT_MAX_CPUS_PER_CLUSTER + madd x1, x2, x4, x1 + mov x5, #PLAT_MAX_PE_PER_CPU + madd x0, x1, x5, x0 + ret +endfunc plat_arm_calc_core_pos + + /* ----------------------------------------------------- + * void plat_reset_handler(void); + * + * Determine the CPU MIDR and disable power down bit for + * that CPU. + * ----------------------------------------------------- + */ +func plat_reset_handler + ret +endfunc plat_reset_handler diff --git a/plat/arm/board/tc0/include/tc0_plat.h b/plat/arm/board/tc0/include/tc0_plat.h new file mode 100644 index 000000000..f0cb43132 --- /dev/null +++ b/plat/arm/board/tc0/include/tc0_plat.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef tc0_bl31_common_platform_setup_PLAT_H +#define tc0_bl31_common_platform_setup_PLAT_H + +void tc0_bl31_common_platform_setup(void); + +#endif /* tc0_bl31_common_platform_setup_PLAT_H */ diff --git a/plat/arm/board/tc0/platform.mk b/plat/arm/board/tc0/platform.mk new file mode 100644 index 000000000..265826f9f --- /dev/null +++ b/plat/arm/board/tc0/platform.mk @@ -0,0 +1,97 @@ +# Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +CSS_LOAD_SCP_IMAGES := 1 + +CSS_USE_SCMI_SDS_DRIVER := 1 + +RAS_EXTENSION := 0 + +SDEI_SUPPORT := 0 + +EL3_EXCEPTION_HANDLING := 0 + +HANDLE_EA_EL3_FIRST := 0 + +# System coherency is managed in hardware +HW_ASSISTED_COHERENCY := 1 + +# When building for systems with hardware-assisted coherency, there's no need to +# use USE_COHERENT_MEM. Require that USE_COHERENT_MEM must be set to 0 too. +USE_COHERENT_MEM := 0 + +GIC_ENABLE_V4_EXTN := 1 + +# GIC-600 configuration +GICV3_IMPL := GIC600 + +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk + +ENT_GIC_SOURCES := ${GICV3_SOURCES} \ + plat/common/plat_gicv3.c \ + plat/arm/common/arm_gicv3.c + +override NEED_BL2U := no + +override ARM_PLAT_MT := 1 + +TC0_BASE = plat/arm/board/tc0 + +PLAT_INCLUDES += -I${TC0_BASE}/include/ + +TC0_CPU_SOURCES := lib/cpus/aarch64/cortex_matterhorn.S + +INTERCONNECT_SOURCES := ${TC0_BASE}/tc0_interconnect.c + +PLAT_BL_COMMON_SOURCES += ${TC0_BASE}/tc0_plat.c \ + ${TC0_BASE}/include/tc0_helpers.S + +BL1_SOURCES += ${INTERCONNECT_SOURCES} \ + ${TC0_CPU_SOURCES} \ + ${TC0_BASE}/tc0_trusted_boot.c \ + ${TC0_BASE}/tc0_err.c \ + drivers/arm/sbsa/sbsa.c + + +BL2_SOURCES += ${TC0_BASE}/tc0_security.c \ + ${TC0_BASE}/tc0_err.c \ + ${TC0_BASE}/tc0_trusted_boot.c \ + lib/utils/mem_region.c \ + plat/arm/common/arm_nor_psci_mem_protect.c + +BL31_SOURCES += ${INTERCONNECT_SOURCES} \ + ${TC0_CPU_SOURCES} \ + ${ENT_GIC_SOURCES} \ + ${TC0_BASE}/tc0_bl31_setup.c \ + ${TC0_BASE}/tc0_topology.c \ + drivers/cfi/v2m/v2m_flash.c \ + lib/utils/mem_region.c \ + plat/arm/common/arm_nor_psci_mem_protect.c + +# Add the FDT_SOURCES and options for Dynamic Config +FDT_SOURCES += ${TC0_BASE}/fdts/${PLAT}_fw_config.dts +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb + +# Add the TB_FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) + +#Device tree +TC0_HW_CONFIG_DTS := fdts/tc0.dts +TC0_HW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}.dtb +FDT_SOURCES += ${TC0_HW_CONFIG_DTS} +$(eval TC0_HW_CONFIG := ${BUILD_PLAT}/$(patsubst %.dts,%.dtb,$(TC0_HW_CONFIG_DTS))) + +# Add the HW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${TC0_HW_CONFIG},--hw-config)) + +override CTX_INCLUDE_AARCH32_REGS := 0 + +override CTX_INCLUDE_PAUTH_REGS := 1 + +include plat/arm/common/arm_common.mk +include plat/arm/css/common/css_common.mk +include plat/arm/soc/common/soc_css.mk +include plat/arm/board/common/board_common.mk diff --git a/plat/arm/board/tc0/tc0_bl31_setup.c b/plat/arm/board/tc0/tc0_bl31_setup.c new file mode 100644 index 000000000..b91b11c9d --- /dev/null +++ b/plat/arm/board/tc0/tc0_bl31_setup.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +static scmi_channel_plat_info_t tc0_scmi_plat_info[] = { + { + .scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE, + .db_reg_addr = PLAT_CSS_MHU_BASE + SENDER_REG_SET(0), + .db_preserve_mask = 0xfffffffe, + .db_modify_mask = 0x1, + .ring_doorbell = &mhuv2_ring_doorbell, + } +}; + +void bl31_platform_setup(void) +{ + tc0_bl31_common_platform_setup(); +} + +scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id) +{ + + return &tc0_scmi_plat_info[channel_id]; + +} + +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); +} + +void tc0_bl31_common_platform_setup(void) +{ + arm_bl31_platform_setup(); +} + +const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops) +{ + return css_scmi_override_pm_ops(ops); +} diff --git a/plat/arm/board/tc0/tc0_err.c b/plat/arm/board/tc0/tc0_err.c new file mode 100644 index 000000000..4fc050526 --- /dev/null +++ b/plat/arm/board/tc0/tc0_err.c @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +/* + * tc0 error handler + */ +void __dead2 plat_arm_error_handler(int err) +{ + while (1) { + wfi(); + } +} diff --git a/plat/arm/board/tc0/tc0_interconnect.c b/plat/arm/board/tc0/tc0_interconnect.c new file mode 100644 index 000000000..e2fc4e1e1 --- /dev/null +++ b/plat/arm/board/tc0/tc0_interconnect.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +/* + * For Total Compute we should not do anything in these interface functions. + * They are used to override the weak functions in cci drivers. + */ + +/****************************************************************************** + * Helper function to initialize ARM interconnect driver. + *****************************************************************************/ +void __init plat_arm_interconnect_init(void) +{ +} + +/****************************************************************************** + * Helper function to place current master into coherency + *****************************************************************************/ +void plat_arm_interconnect_enter_coherency(void) +{ +} + +/****************************************************************************** + * Helper function to remove current master from coherency + *****************************************************************************/ +void plat_arm_interconnect_exit_coherency(void) +{ +} diff --git a/plat/arm/board/tc0/tc0_plat.c b/plat/arm/board/tc0/tc0_plat.c new file mode 100644 index 000000000..b1ec39b58 --- /dev/null +++ b/plat/arm/board/tc0/tc0_plat.c @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Table of regions for different BL stages to map using the MMU. + * This doesn't include Trusted RAM as the 'mem_layout' argument passed to + * arm_configure_mmu_elx() will give the available subset of that. + */ +#if IMAGE_BL1 +const mmap_region_t plat_arm_mmap[] = { + ARM_MAP_SHARED_RAM, + TC0_FLASH0_RO, + TC0_MAP_DEVICE, + {0} +}; +#endif +#if IMAGE_BL2 +const mmap_region_t plat_arm_mmap[] = { + ARM_MAP_SHARED_RAM, + TC0_FLASH0_RO, + TC0_MAP_DEVICE, + ARM_MAP_NS_DRAM1, +#if ARM_BL31_IN_DRAM + ARM_MAP_BL31_SEC_DRAM, +#endif +#if SPM_MM + ARM_SP_IMAGE_MMAP, +#endif +#if TRUSTED_BOARD_BOOT && !BL2_AT_EL3 + ARM_MAP_BL1_RW, +#endif + {0} +}; +#endif +#if IMAGE_BL31 +const mmap_region_t plat_arm_mmap[] = { + ARM_MAP_SHARED_RAM, + V2M_MAP_IOFPGA, + TC0_MAP_DEVICE, +#if SPM_MM + ARM_SPM_BUF_EL3_MMAP, +#endif + {0} +}; + +#if SPM_MM && defined(IMAGE_BL31) +const mmap_region_t plat_arm_secure_partition_mmap[] = { + PLAT_ARM_SECURE_MAP_DEVICE, + ARM_SP_IMAGE_MMAP, + ARM_SP_IMAGE_NS_BUF_MMAP, + ARM_SP_CPER_BUF_MMAP, + ARM_SP_IMAGE_RW_MMAP, + ARM_SPM_BUF_EL0_MMAP, + {0} +}; +#endif /* SPM_MM && defined(IMAGE_BL31) */ +#endif + +ARM_CASSERT_MMAP + +#if SPM_MM && defined(IMAGE_BL31) +/* + * Boot information passed to a secure partition during initialisation. Linear + * indices in MP information will be filled at runtime. + */ +static spm_mm_mp_info_t sp_mp_info[] = { + [0] = {0x81000000, 0}, + [1] = {0x81000100, 0}, + [2] = {0x81000200, 0}, + [3] = {0x81000300, 0}, + [4] = {0x81010000, 0}, + [5] = {0x81010100, 0}, + [6] = {0x81010200, 0}, + [7] = {0x81010300, 0}, +}; + +const spm_mm_boot_info_t plat_arm_secure_partition_boot_info = { + .h.type = PARAM_SP_IMAGE_BOOT_INFO, + .h.version = VERSION_1, + .h.size = sizeof(spm_mm_boot_info_t), + .h.attr = 0, + .sp_mem_base = ARM_SP_IMAGE_BASE, + .sp_mem_limit = ARM_SP_IMAGE_LIMIT, + .sp_image_base = ARM_SP_IMAGE_BASE, + .sp_stack_base = PLAT_SP_IMAGE_STACK_BASE, + .sp_heap_base = ARM_SP_IMAGE_HEAP_BASE, + .sp_ns_comm_buf_base = PLAT_SP_IMAGE_NS_BUF_BASE, + .sp_shared_buf_base = PLAT_SPM_BUF_BASE, + .sp_image_size = ARM_SP_IMAGE_SIZE, + .sp_pcpu_stack_size = PLAT_SP_IMAGE_STACK_PCPU_SIZE, + .sp_heap_size = ARM_SP_IMAGE_HEAP_SIZE, + .sp_ns_comm_buf_size = PLAT_SP_IMAGE_NS_BUF_SIZE, + .sp_shared_buf_size = PLAT_SPM_BUF_SIZE, + .num_sp_mem_regions = ARM_SP_IMAGE_NUM_MEM_REGIONS, + .num_cpus = PLATFORM_CORE_COUNT, + .mp_info = &sp_mp_info[0], +}; + +const struct mmap_region *plat_get_secure_partition_mmap(void *cookie) +{ + return plat_arm_secure_partition_mmap; +} + +const struct spm_mm_boot_info *plat_get_secure_partition_boot_info( + void *cookie) +{ + return &plat_arm_secure_partition_boot_info; +} +#endif /* SPM_MM && defined(IMAGE_BL31) */ + +#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 plat_arm_secure_wdt_start(void) +{ + sbsa_wdog_start(SBSA_SECURE_WDOG_BASE, SBSA_SECURE_WDOG_TIMEOUT); +} + +void plat_arm_secure_wdt_stop(void) +{ + sbsa_wdog_stop(SBSA_SECURE_WDOG_BASE); +} diff --git a/plat/arm/board/tc0/tc0_security.c b/plat/arm/board/tc0/tc0_security.c new file mode 100644 index 000000000..6aa38c822 --- /dev/null +++ b/plat/arm/board/tc0/tc0_security.c @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +/* Initialize the secure environment */ +void plat_arm_security_setup(void) +{ +} diff --git a/plat/arm/board/tc0/tc0_topology.c b/plat/arm/board/tc0/tc0_topology.c new file mode 100644 index 000000000..5478fbc32 --- /dev/null +++ b/plat/arm/board/tc0/tc0_topology.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +/****************************************************************************** + * The power domain tree descriptor. + ******************************************************************************/ +const unsigned char tc0_pd_tree_desc[] = { + PLAT_ARM_CLUSTER_COUNT, + PLAT_MAX_CPUS_PER_CLUSTER, +}; + +/******************************************************************************* + * This function returns the topology tree information. + ******************************************************************************/ +const unsigned char *plat_get_power_domain_tree_desc(void) +{ + return tc0_pd_tree_desc; +} + +/******************************************************************************* + * The array mapping platform core position (implemented by plat_my_core_pos()) + * to the SCMI power domain ID implemented by SCP. + ******************************************************************************/ +const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = { + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x0)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x1)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x2)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x3)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x4)), +}; + +/******************************************************************************* + * This function returns the core count within the cluster corresponding to + * `mpidr`. + ******************************************************************************/ +unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr) +{ + return PLAT_MAX_CPUS_PER_CLUSTER; +} + +#if ARM_PLAT_MT +/****************************************************************************** + * Return the number of PE's supported by the CPU. + *****************************************************************************/ +unsigned int plat_arm_get_cpu_pe_count(u_register_t mpidr) +{ + return PLAT_MAX_PE_PER_CPU; +} +#endif diff --git a/plat/arm/board/tc0/tc0_trusted_boot.c b/plat/arm/board/tc0/tc0_trusted_boot.c new file mode 100644 index 000000000..614f7e2ad --- /dev/null +++ b/plat/arm/board/tc0/tc0_trusted_boot.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#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); +} -- cgit v1.2.3 From da37ac88f1270fbf0bfc209e9722937bc8ec1019 Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Wed, 27 May 2020 10:36:56 +0200 Subject: doc: Update the list of code owners Extend the list of modules and assign code owners to each of them. Change-Id: I267b87d8e239c7eff143b4c7e6ce9712fcf7101e Signed-off-by: Sandrine Bailleux --- docs/about/maintainers.rst | 241 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 236 insertions(+), 5 deletions(-) diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst index d40134f81..3ac55486c 100644 --- a/docs/about/maintainers.rst +++ b/docs/about/maintainers.rst @@ -43,14 +43,49 @@ Code owners Core Code ~~~~~~~~~ -.. note:: - This section is incomplete right now. - Armv7-A architecture port ^^^^^^^^^^^^^^^^^^^^^^^^^ :M: Etienne Carriere :G: `etienne-lms`_ +Software Delegated Exception Interface (SDEI) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:M: Mark Dykes +:G: `mardyk01`_ +:M: John Powell +:G: `john-powell-arm`_ +:F: services/std_svc/sdei/ + +Trusted Boot +^^^^^^^^^^^^ +:M: Sandrine Bailleux +:G: `sandrine-bailleux-arm`_ +:M: Manish Pandey +:G: `manish-pandey-arm`_ +:M: Manish Badarkhe +:G: `ManishVB-Arm`_ +:F: drivers/auth/ + +Secure Partition Manager (SPM) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:M: Olivier Deprez +:G: `odeprez`_ +:M: Manish Pandey +:G: `manish-pandey-arm`_ +:M: Maksims Svecovs +:G: `max-shvetsov`_ +:M: Joao Alves +:G: `J-Alves`_ +:F: services/std_svc/spm\* + +Exception Handling Framework (EHF) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:M: Manish Badarkhe +:G: `ManishVB-Arm`_ +:M: John Powell +:G: `john-powell-arm`_ +:F: bl31/ehf.c + Drivers, Libraries and Framework Code ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -84,6 +119,152 @@ eMMC/UFS drivers :F: include/drivers/ufs.h :F: include/drivers/synopsys/dw_mmc.h +Power State Coordination Interface (PSCI) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:M: Javier Almansa Sobrino +:G: `javieralso-arm`_ +:M: Madhukar Pappireddy +:G: `madhukar-Arm`_ +:M: Lauren Wehrmeister +:G: `laurenw-arm`_ +:M: Zelalem Aweke +:G: `zelalem-aweke`_ +:F: lib/psci/ + +DebugFS +^^^^^^^ +:M: Olivier Deprez +:G: `odeprez`_ +:F: lib/debugfs/ + +Firmware Configuration Framework (FCONF) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:M: Madhukar Pappireddy +:G: `madhukar-Arm`_ +:M: Manish Badarkhe +:G: `ManishVB-Arm`_ +:M: Lauren Wehrmeister +:G: `laurenw-arm`_ +:F: lib/fconf/ + +Performance Measurement Framework (PMF) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:M: Joao Alves +:G: `J-Alves`_ +:M: Jimmy Brisson +:G: `theotherjimmy`_ +:F: lib/pmf/ + +Arm CPU libraries +^^^^^^^^^^^^^^^^^ +:M: Lauren Wehrmeister +:G: `laurenw-arm`_ +:M: John Powell +:G: `john-powell-arm`_ +:F: lib/cpus/ + +Reliability Availability Serviceabilty (RAS) framework +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:M: Olivier Deprez +:G: `odeprez`_ +:M: Manish Pandey +:G: `manish-pandey-arm`_ +:F: lib/extensions/ras/ + +Activity Monitors Unit (AMU) extensions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:M: Alexei Fedorov +:G: `AlexeiFedorov`_ +:F: lib/extensions/amu/ + +Memory Partitioning And Monitoring (MPAM) extensions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:M: Zelalem Aweke +:G: `zelalem-aweke`_ +:M: Jimmy Brisson +:G: `theotherjimmy`_ +:F: lib/extensions/mpam/ + +Pointer Authentication (PAuth) and Branch Target Identification (BTI) extensions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:M: Alexei Fedorov +:G: `AlexeiFedorov`_ +:M: Zelalem Aweke +:G: `zelalem-aweke`_ +:F: lib/extensions/pauth/ + +Statistical Profiling Extension (SPE) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:M: Zelalem Aweke +:G: `zelalem-aweke`_ +:M: Jimmy Brisson +:G: `theotherjimmy`_ +:F: lib/extensions/spe/ + +Scalable Vector Extension (SVE) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:M: Jimmy Brisson +:G: `theotherjimmy`_ +:F: lib/extensions/sve/ + +Standard C library +^^^^^^^^^^^^^^^^^^ +:M: Alexei Fedorov +:G: `AlexeiFedorov`_ +:M: John Powell +:G: `john-powell-arm`_ +:F: lib/libc/ + +Library At ROM (ROMlib) +^^^^^^^^^^^^^^^^^^^^^^^ +:M: Madhukar Pappireddy +:G: `madhukar-Arm`_ +:F: lib/romlib/ + +Translation tables (``xlat_tables``) library +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:M: Javier Almansa Sobrino +:G: `javieralso-arm`_ +:M: Joao Alves +:G: `J-Alves`_ +:F: lib/xlat\_tables_\*/ + +IO abstraction layer +^^^^^^^^^^^^^^^^^^^^ +:M: Manish Pandey +:G: `manish-pandey-arm`_ +:M: Olivier Deprez +:G: `odeprez`_ +:F: drivers/io/ + +GIC driver +^^^^^^^^^^ +:M: Alexei Fedorov +:G: `AlexeiFedorov`_ +:M: Manish Pandey +:G: `manish-pandey-arm`_ +:M: Madhukar Pappireddy +:G: `madhukar-Arm`_ +:M: Olivier Deprez +:G: `odeprez`_ +:F: drivers/arm/gic/ + +Libfdt wrappers +^^^^^^^^^^^^^^^ +:M: Madhukar Pappireddy +:G: `madhukar-Arm`_ +:M: Manish Badarkhe +:G: `ManishVB-Arm`_ +:F: common/fdt_wrappers.c + +Firmware Encryption Framework +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:M: Sumit Garg +:G: `b49020`_ +:F: drivers/io/io_encrypted.c +:F: include/drivers/io/io_encrypted.h +:F: include/tools_share/firmware_encrypted.h + Platform Ports ~~~~~~~~~~~~~~ @@ -309,8 +490,8 @@ Xilinx platform port :F: plat/xilinx/ -Secure Payload Dispatchers -~~~~~~~~~~~~~~~~~~~~~~~~~~ +Secure Payloads and Dispatchers +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ OP-TEE dispatcher ^^^^^^^^^^^^^^^^^ @@ -329,6 +510,46 @@ TLK/Trusty secure payloads :F: services/spd/tlkd/ :F: services/spd/trusty/ +Test Secure Payload (TSP) +^^^^^^^^^^^^^^^^^^^^^^^^^ +:M: Manish Badarkhe +:G: `ManishVB-Arm`_ +:F: bl32/tsp/ +:F: services/spd/tspd/ + +Tools +~~~~~ + +Fiptool +^^^^^^^ +:M: Joao Alves +:G: `J-Alves`_ +:F: tools/fiptool/ + +Cert_create tool +^^^^^^^^^^^^^^^^ +:M: Sandrine Bailleux +:G: `sandrine-bailleux-arm`_ +:F: tools/cert_create/ + +Encrypt_fw tool +^^^^^^^^^^^^^^^ +:M: Sumit Garg +:G: `b49020`_ +:F: tools/encrypt_fw/ + +Sptool +^^^^^^ +:M: Manish Pandey +:G: `manish-pandey-arm`_ +:F: tools/sptool/ + +Build system +^^^^^^^^^^^^ +:M: Manish Pandey +:G: `manish-pandey-arm`_ +:F: Makefile +:F: make_helpers/ .. _AlexeiFedorov: https://github.com/AlexeiFedorov .. _Andre-ARM: https://github.com/Andre-ARM @@ -370,5 +591,15 @@ TLK/Trusty secure payloads .. _odeprez: https://github.com/odeprez .. _bipinravi-arm: https://github.com/bipinravi-arm .. _joannafarley-arm: https://github.com/joannafarley-arm +.. _ManishVB-Arm: https://github.com/ManishVB-Arm +.. _max-shvetsov: https://github.com/max-shvetsov +.. _javieralso-arm: https://github.com/javieralso-arm +.. _laurenw-arm: https://github.com/laurenw-arm +.. _zelalem-aweke: https://github.com/zelalem-aweke +.. _theotherjimmy: https://github.com/theotherjimmy +.. _J-Alves: https://github.com/J-Alves +.. _madhukar-Arm: https://github.com/madhukar-Arm +.. _john-powell-arm: https://github.com/john-powell-arm + .. _Project Maintenance Process: https://developer.trustedfirmware.org/w/collaboration/project-maintenance-process/ -- cgit v1.2.3 From 55d6596ec37037e9a5e3072e92e3af9ed48010cd Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Thu, 28 May 2020 10:38:54 +0200 Subject: Add new maintainers for the project As per the trustedfirmware.org Project Maintenance Process [1], the current maintainers of the TF-A project have nominated some contributors to become maintainers themselves. List them in the maintainers.rst file to make this official. [1] https://developer.trustedfirmware.org/w/collaboration/project-maintenance-process/ Change-Id: Id4e3cfd12a9074f4e255087fa5dd6fa5f902845f Signed-off-by: Sandrine Bailleux --- docs/about/maintainers.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst index 3ac55486c..9d298d001 100644 --- a/docs/about/maintainers.rst +++ b/docs/about/maintainers.rst @@ -33,6 +33,16 @@ Maintainers :G: `bipinravi-arm`_ :M: Joanna Farley :G: `joannafarley-arm`_ +:M: Julius Werner +:G: `jwerner-chromium`_ +:M: Varun Wadekar +:G: `vwadekar`_ +:M: Andre Przywara +:G: `Andre-ARM`_ +:M: Lauren Wehrmeister +:G: `laurenw-arm`_ +:M: Madhukar Pappireddy +:G: `madhukar-Arm`_ .. _code owners: -- cgit v1.2.3 From 34dd1e96fdae59d56d19a8d1270a03860af9f015 Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Sat, 30 May 2020 17:33:26 +0100 Subject: TF-A: Fix BL31 linker script error The patch fixes BL31 linker script error "Init code ends past the end of the stacks" for platforms with number of CPUs less than 4, which is caused by __STACKS_END__ address being lower than __INIT_CODE_END__. The modified BL31 linker script detects such cases and increases the total amount of stack memory, setting __STACKS_END__ = __INIT_CODE_END__, and CPUs' stacks are calculated by BL31 'plat_get_my_stack' function accordingly. For platforms with more than 4 CPUs and __INIT_CODE_END__ < __STACKS_END__ stack memory does not increase and allocated CPUs' stacks match the existing implementation. The patch removes exclusion of PSCI initialization functions from the reclaimed .init section in 'arm_reclaim_init.ld.S' script, which increases the size of reclaimed memory region. Change-Id: I927773e00dd84e1ffe72f9ee534f4f2fc7b6153c Signed-off-by: Alexei Fedorov --- include/common/bl_common.ld.h | 2 ++ include/plat/arm/common/arm_reclaim_init.ld.S | 45 +++++++++++++++++++++++---- plat/common/aarch64/platform_mp_stack.S | 40 +++++++++++++++++++++--- 3 files changed, 77 insertions(+), 10 deletions(-) diff --git a/include/common/bl_common.ld.h b/include/common/bl_common.ld.h index 97fed7204..208e3d681 100644 --- a/include/common/bl_common.ld.h +++ b/include/common/bl_common.ld.h @@ -101,12 +101,14 @@ __DATA_END__ = .; \ } +#if !(defined(IMAGE_BL31) && RECLAIM_INIT_CODE) #define STACK_SECTION \ stacks (NOLOAD) : { \ __STACKS_START__ = .; \ *(tzfw_normal_stacks) \ __STACKS_END__ = .; \ } +#endif /* * If BL doesn't use any bakery lock then __PERCPU_BAKERY_LOCK_SIZE__ diff --git a/include/plat/arm/common/arm_reclaim_init.ld.S b/include/plat/arm/common/arm_reclaim_init.ld.S index b5bf47365..03976f34f 100644 --- a/include/plat/arm/common/arm_reclaim_init.ld.S +++ b/include/plat/arm/common/arm_reclaim_init.ld.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -12,11 +12,7 @@ SECTIONS . = . + PLATFORM_STACK_SIZE; . = ALIGN(PAGE_SIZE); __INIT_CODE_START__ = .; - /* - * Exclude PSCI initialization functions to ensure the init section - * does not become larger than the overlaid stack region - */ - *(EXCLUDE_FILE (*psci_setup.o).text.init*) + *(*text.init*); __INIT_CODE_UNALIGNED__ = .; . = ALIGN(PAGE_SIZE); __INIT_CODE_END__ = .; @@ -32,4 +28,41 @@ SECTIONS } +#undef MIN +#define ABS ABSOLUTE +#define COUNT PLATFORM_CORE_COUNT +#define ALIGN_MASK ~(CACHE_WRITEBACK_GRANULE - 1) + +#define PRIMARY_STACK \ + __STACKS_START__ = .; \ + *(tzfw_normal_stacks) \ + OFFSET = ABS(SIZEOF(.init) - (. - __STACKS_START__)); \ + /* Offset sign */ \ + SIGN = ABS(OFFSET) & (1 << 63); \ + /* Offset mask */ \ + MASK = ABS(SIGN >> 63) - 1; \ + . += ABS(OFFSET) & ABS(MASK); \ + __STACKS_END__ = .; \ + /* Total stack size */ \ + SIZE = ABS(. - __STACKS_START__); \ + /* Maximum primary CPU stack */ \ + STACK = ABS(__STACKS_START__ + SIZE / COUNT) & ALIGN_MASK; \ + /* Primary CPU stack */ \ + __PRIMARY_STACK__ = MIN(STACK, ABS(__INIT_CODE_START__)); + +#if (COUNT > 1) +#define SECONDARY_STACK \ + /* Size of the secondary CPUs' stack */ \ + REST = ABS(__STACKS_END__ - __PRIMARY_STACK__); \ + /* Secondary per-CPU stack size */ \ + __STACK_SIZE__ = ABS(REST / (COUNT - 1)); +#else +#define SECONDARY_STACK +#endif + +#define STACK_SECTION \ + stacks (NOLOAD) : { \ + PRIMARY_STACK \ + SECONDARY_STACK \ + } #endif /* ARM_RECLAIM_INIT_LD_S */ diff --git a/plat/common/aarch64/platform_mp_stack.S b/plat/common/aarch64/platform_mp_stack.S index f9780e80c..e2d71da7a 100644 --- a/plat/common/aarch64/platform_mp_stack.S +++ b/plat/common/aarch64/platform_mp_stack.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -32,9 +32,41 @@ * ----------------------------------------------------- */ func plat_get_my_stack - mov x10, x30 // lr +#if (defined(IMAGE_BL31) && RECLAIM_INIT_CODE) +#if (PLATFORM_CORE_COUNT == 1) + /* Single CPU */ + adrp x0, __PRIMARY_STACK__ + add x0, x0, :lo12:__PRIMARY_STACK__ + ret +#else + mov x10, x30 + bl plat_my_core_pos + cbnz x0, 2f + + /* Primary CPU */ + adrp x0, __PRIMARY_STACK__ + add x0, x0, :lo12:__PRIMARY_STACK__ + ret x10 + + /* Secondary CPU */ +2: sub x0, x0, #(PLATFORM_CORE_COUNT - 1) + adrp x1, __STACKS_END__ + adrp x2, __STACK_SIZE__ + add x1, x1, :lo12:__STACKS_END__ + add x2, x2, :lo12:__STACK_SIZE__ + + madd x0, x0, x2, x1 + bic x0, x0, #(CACHE_WRITEBACK_GRANULE - 1) + ret x10 +#endif + .word platform_normal_stacks + +#else /* !(IMAGE_BL31 && RECLAIM_INIT_CODE) */ + mov x10, x30 get_my_mp_stack platform_normal_stacks, PLATFORM_STACK_SIZE ret x10 + +#endif /* IMAGE_BL31 && RECLAIM_INIT_CODE */ endfunc plat_get_my_stack /* ----------------------------------------------------- @@ -45,14 +77,14 @@ endfunc plat_get_my_stack * ----------------------------------------------------- */ func plat_set_my_stack - mov x9, x30 // lr + mov x9, x30 bl plat_get_my_stack mov sp, x0 ret x9 endfunc plat_set_my_stack /* ----------------------------------------------------- - * Per-cpu stacks in normal memory. Each cpu gets a + * Per-CPU stacks in normal memory. Each CPU gets a * stack of PLATFORM_STACK_SIZE bytes. * ----------------------------------------------------- */ -- cgit v1.2.3 From 45c70e68673b4fd39c301725e63c03d0846339c5 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Sun, 8 Dec 2019 08:14:40 +0100 Subject: drivers: stm32_reset adapt interface to timeout argument MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changes stm32mp1 reset driver to API to add a timeout argument to stm32mp_reset_assert() and stm32mp_reset_deassert() and a return value. With a supplied timeout, the functions wait the target reset state is reached before returning. With a timeout of zero, the functions simply load target reset state in SoC interface and return without waiting. Helper functions stm32mp_reset_set() and stm32mp_reset_release() use a zero timeout and return without a return code. This change updates few stm32 drivers and plat/stm32mp1 blé_plat_setup.c accordingly without any functional change. functional change. Change-Id: Ia1a73a15125d3055fd8739c125b70bcb9562c27f Signed-off-by: Etienne Carriere --- drivers/st/crypto/stm32_hash.c | 11 +++++++++-- drivers/st/fmc/stm32_fmc2_nand.c | 14 ++++++++++++-- drivers/st/mmc/stm32_sdmmc2.c | 13 +++++++++++-- drivers/st/reset/stm32mp1_reset.c | 35 ++++++++++++++++++++-------------- drivers/st/spi/stm32_qspi.c | 13 +++++++++++-- include/drivers/st/stm32mp_reset.h | 39 ++++++++++++++++++++++++++++++++++++-- plat/st/stm32mp1/bl2_plat_setup.c | 15 +++++++++++++-- 7 files changed, 114 insertions(+), 26 deletions(-) diff --git a/drivers/st/crypto/stm32_hash.c b/drivers/st/crypto/stm32_hash.c index f72787d33..3184df9de 100644 --- a/drivers/st/crypto/stm32_hash.c +++ b/drivers/st/crypto/stm32_hash.c @@ -51,6 +51,7 @@ #define SHA224_DIGEST_SIZE 28U #define SHA256_DIGEST_SIZE 32U +#define RESET_TIMEOUT_US_1MS 1000U #define HASH_TIMEOUT_US 10000U enum stm32_hash_data_format { @@ -319,9 +320,15 @@ int stm32_hash_register(void) stm32mp_clk_enable(stm32_hash.clock); if (hash_info.reset >= 0) { - stm32mp_reset_assert((unsigned long)hash_info.reset); + uint32_t id = (uint32_t)hash_info.reset; + + if (stm32mp_reset_assert(id, RESET_TIMEOUT_US_1MS) != 0) { + panic(); + } udelay(20); - stm32mp_reset_deassert((unsigned long)hash_info.reset); + if (stm32mp_reset_deassert(id, RESET_TIMEOUT_US_1MS) != 0) { + panic(); + } } stm32mp_clk_disable(stm32_hash.clock); diff --git a/drivers/st/fmc/stm32_fmc2_nand.c b/drivers/st/fmc/stm32_fmc2_nand.c index d2d7e06b7..dbbeee4c5 100644 --- a/drivers/st/fmc/stm32_fmc2_nand.c +++ b/drivers/st/fmc/stm32_fmc2_nand.c @@ -22,6 +22,9 @@ #include #include +/* Timeout for device interface reset */ +#define TIMEOUT_US_1_MS 1000U + /* FMC2 Compatibility */ #define DT_FMC2_COMPAT "st,stm32mp15-fmc2" #define MAX_CS 2U @@ -793,6 +796,7 @@ int stm32_fmc2_init(void) void *fdt = NULL; const fdt32_t *cuint; struct dt_node_info info; + int ret; if (fdt_get_address(&fdt) == 0) { return -FDT_ERR_NOTFOUND; @@ -861,8 +865,14 @@ int stm32_fmc2_init(void) stm32mp_clk_enable(stm32_fmc2.clock_id); /* Reset IP */ - stm32mp_reset_assert(stm32_fmc2.reset_id); - stm32mp_reset_deassert(stm32_fmc2.reset_id); + ret = stm32mp_reset_assert(stm32_fmc2.reset_id, TIMEOUT_US_1_MS); + if (ret != 0) { + panic(); + } + ret = stm32mp_reset_deassert(stm32_fmc2.reset_id, TIMEOUT_US_1_MS); + if (ret != 0) { + panic(); + } /* Setup default IP registers */ stm32_fmc2_ctrl_init(); diff --git a/drivers/st/mmc/stm32_sdmmc2.c b/drivers/st/mmc/stm32_sdmmc2.c index 24e6efe98..63fbb0747 100644 --- a/drivers/st/mmc/stm32_sdmmc2.c +++ b/drivers/st/mmc/stm32_sdmmc2.c @@ -113,6 +113,7 @@ SDMMC_STAR_IDMATE | \ SDMMC_STAR_IDMABTC) +#define TIMEOUT_US_1_MS 1000U #define TIMEOUT_US_10_MS 10000U #define TIMEOUT_US_1_S 1000000U @@ -711,6 +712,8 @@ unsigned long long stm32_sdmmc2_mmc_get_device_size(void) int stm32_sdmmc2_mmc_init(struct stm32_sdmmc2_params *params) { + int rc; + assert((params != NULL) && ((params->reg_base & MMC_BLOCK_MASK) == 0U) && ((params->bus_width == MMC_BUS_WIDTH_1) || @@ -726,9 +729,15 @@ int stm32_sdmmc2_mmc_init(struct stm32_sdmmc2_params *params) stm32mp_clk_enable(sdmmc2_params.clock_id); - stm32mp_reset_assert(sdmmc2_params.reset_id); + rc = stm32mp_reset_assert(sdmmc2_params.reset_id, TIMEOUT_US_1_MS); + if (rc != 0) { + panic(); + } udelay(2); - stm32mp_reset_deassert(sdmmc2_params.reset_id); + rc = stm32mp_reset_deassert(sdmmc2_params.reset_id, TIMEOUT_US_1_MS); + if (rc != 0) { + panic(); + } mdelay(1); sdmmc2_params.clk_rate = stm32mp_clk_get_rate(sdmmc2_params.clock_id); diff --git a/drivers/st/reset/stm32mp1_reset.c b/drivers/st/reset/stm32mp1_reset.c index fd3f93e01..98c8dcf71 100644 --- a/drivers/st/reset/stm32mp1_reset.c +++ b/drivers/st/reset/stm32mp1_reset.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include #include #include @@ -15,8 +16,6 @@ #include #include -#define RESET_TIMEOUT_US_1MS U(1000) - static uint32_t id2reg_offset(unsigned int reset_id) { return ((reset_id & GENMASK(31, 5)) >> 5) * sizeof(uint32_t); @@ -27,36 +26,44 @@ static uint8_t id2reg_bit_pos(unsigned int reset_id) return (uint8_t)(reset_id & GENMASK(4, 0)); } -void stm32mp_reset_assert(uint32_t id) +int stm32mp_reset_assert(uint32_t id, unsigned int to_us) { uint32_t offset = id2reg_offset(id); uint32_t bitmsk = BIT(id2reg_bit_pos(id)); - uint64_t timeout_ref; uintptr_t rcc_base = stm32mp_rcc_base(); mmio_write_32(rcc_base + offset, bitmsk); - timeout_ref = timeout_init_us(RESET_TIMEOUT_US_1MS); - while ((mmio_read_32(rcc_base + offset) & bitmsk) == 0U) { - if (timeout_elapsed(timeout_ref)) { - panic(); + if (to_us != 0U) { + uint64_t timeout_ref = timeout_init_us(to_us); + + while ((mmio_read_32(rcc_base + offset) & bitmsk) == 0U) { + if (timeout_elapsed(timeout_ref)) { + return -ETIMEDOUT; + } } } + + return 0; } -void stm32mp_reset_deassert(uint32_t id) +int stm32mp_reset_deassert(uint32_t id, unsigned int to_us) { uint32_t offset = id2reg_offset(id) + RCC_RSTCLRR_OFFSET; uint32_t bitmsk = BIT(id2reg_bit_pos(id)); - uint64_t timeout_ref; uintptr_t rcc_base = stm32mp_rcc_base(); mmio_write_32(rcc_base + offset, bitmsk); - timeout_ref = timeout_init_us(RESET_TIMEOUT_US_1MS); - while ((mmio_read_32(rcc_base + offset) & bitmsk) != 0U) { - if (timeout_elapsed(timeout_ref)) { - panic(); + if (to_us != 0U) { + uint64_t timeout_ref = timeout_init_us(to_us); + + while ((mmio_read_32(rcc_base + offset) & bitmsk) != 0U) { + if (timeout_elapsed(timeout_ref)) { + return -ETIMEDOUT; + } } } + + return 0; } diff --git a/drivers/st/spi/stm32_qspi.c b/drivers/st/spi/stm32_qspi.c index ff92796e7..d67f8313f 100644 --- a/drivers/st/spi/stm32_qspi.c +++ b/drivers/st/spi/stm32_qspi.c @@ -18,6 +18,9 @@ #include #include +/* Timeout for device interface reset */ +#define TIMEOUT_US_1_MS 1000U + /* QUADSPI registers */ #define QSPI_CR 0x00U #define QSPI_DCR 0x04U @@ -492,8 +495,14 @@ int stm32_qspi_init(void) stm32mp_clk_enable(stm32_qspi.clock_id); - stm32mp_reset_assert(stm32_qspi.reset_id); - stm32mp_reset_deassert(stm32_qspi.reset_id); + ret = stm32mp_reset_assert(stm32_qspi.reset_id, TIMEOUT_US_1_MS); + if (ret != 0) { + panic(); + } + ret = stm32mp_reset_deassert(stm32_qspi.reset_id, TIMEOUT_US_1_MS); + if (ret != 0) { + panic(); + } mmio_write_32(qspi_base() + QSPI_CR, QSPI_CR_SSHIFT); mmio_write_32(qspi_base() + QSPI_DCR, QSPI_DCR_FSIZE_MASK); diff --git a/include/drivers/st/stm32mp_reset.h b/include/drivers/st/stm32mp_reset.h index 2da5adf44..84448050d 100644 --- a/include/drivers/st/stm32mp_reset.h +++ b/include/drivers/st/stm32mp_reset.h @@ -9,7 +9,42 @@ #include -void stm32mp_reset_assert(uint32_t reset_id); -void stm32mp_reset_deassert(uint32_t reset_id); +/* + * Assert target reset, if @to_us non null, wait until reset is asserted + * + * @reset_id: Reset controller ID + * @to_us: Timeout in microsecond, or 0 if not waiting + * Return 0 on success and -ETIMEDOUT if waiting and timeout expired + */ +int stm32mp_reset_assert(uint32_t reset_id, unsigned int to_us); + +/* + * Enable reset control for target resource + * + * @reset_id: Reset controller ID + */ +static inline void stm32mp_reset_set(uint32_t reset_id) +{ + (void)stm32mp_reset_assert(reset_id, 0U); +} + +/* + * Deassert target reset, if @to_us non null, wait until reset is deasserted + * + * @reset_id: Reset controller ID + * @to_us: Timeout in microsecond, or 0 if not waiting + * Return 0 on success and -ETIMEDOUT if waiting and timeout expired + */ +int stm32mp_reset_deassert(uint32_t reset_id, unsigned int to_us); + +/* + * Release reset control for target resource + * + * @reset_id: Reset controller ID + */ +static inline void stm32mp_reset_release(uint32_t reset_id) +{ + (void)stm32mp_reset_deassert(reset_id, 0U); +} #endif /* STM32MP_RESET_H */ diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c index 652765ce1..e09ce63c2 100644 --- a/plat/st/stm32mp1/bl2_plat_setup.c +++ b/plat/st/stm32mp1/bl2_plat_setup.c @@ -31,6 +31,8 @@ #include #include +#define RESET_TIMEOUT_US_1MS 1000U + static console_t console; static struct stm32mp_auth_ops stm32mp1_auth_ops; @@ -263,9 +265,18 @@ void bl2_el3_plat_arch_setup(void) stm32mp_clk_enable((unsigned long)dt_uart_info.clock); - stm32mp_reset_assert((uint32_t)dt_uart_info.reset); + if (stm32mp_reset_assert((uint32_t)dt_uart_info.reset, + RESET_TIMEOUT_US_1MS) != 0) { + panic(); + } + udelay(2); - stm32mp_reset_deassert((uint32_t)dt_uart_info.reset); + + if (stm32mp_reset_deassert((uint32_t)dt_uart_info.reset, + RESET_TIMEOUT_US_1MS) != 0) { + panic(); + } + mdelay(1); clk_rate = stm32mp_clk_get_rate((unsigned long)dt_uart_info.clock); -- cgit v1.2.3 From 5621fe252f4876f62a50318b7a8012a21ff2abf4 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Wed, 20 May 2020 07:35:48 +0200 Subject: ti: k3: common: Make UART number configurable This allows to build for k3-based boards that use a different UART as console, such as the IOT2050 which requires K3_USART=1. Signed-off-by: Jan Kiszka Change-Id: I7171f86c3cabae2c575b8fbeecef839b48bd109b --- plat/ti/k3/common/plat_common.mk | 3 +++ plat/ti/k3/include/platform_def.h | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/plat/ti/k3/common/plat_common.mk b/plat/ti/k3/common/plat_common.mk index 03d39f186..c00262bcf 100644 --- a/plat/ti/k3/common/plat_common.mk +++ b/plat/ti/k3/common/plat_common.mk @@ -37,6 +37,9 @@ ENABLE_PIE := 1 TI_16550_MDR_QUIRK := 1 $(eval $(call add_define,TI_16550_MDR_QUIRK)) +K3_USART := 0 +$(eval $(call add_define,K3_USART)) + # Allow customizing the UART baud rate K3_USART_BAUD := 115200 $(eval $(call add_define,K3_USART_BAUD)) diff --git a/plat/ti/k3/include/platform_def.h b/plat/ti/k3/include/platform_def.h index 690c68e5c..98db626e2 100644 --- a/plat/ti/k3/include/platform_def.h +++ b/plat/ti/k3/include/platform_def.h @@ -91,7 +91,7 @@ /* Platform default console definitions */ #ifndef K3_USART_BASE -#define K3_USART_BASE 0x02800000 +#define K3_USART_BASE (0x02800000 + 0x10000 * K3_USART) #endif /* USART has a default size for address space */ -- cgit v1.2.3 From 83c1584dcbaeca03a16ce36af828468b5704c10c Mon Sep 17 00:00:00 2001 From: Jimmy Brisson Date: Mon, 1 Jun 2020 16:49:34 -0500 Subject: Rename Cortex Hercules Files to Cortex A78 This should allow git to easily track file moves Signed-off-by: Jimmy Brisson Change-Id: I1592cf39a4f94209c560dc6d1a8bc1bfb21d8327 --- include/lib/cpus/aarch64/cortex_a78.h | 44 ++++++++ include/lib/cpus/aarch64/cortex_hercules.h | 44 -------- include/lib/cpus/aarch64/cortex_hercules_ae.h | 4 +- lib/cpus/aarch64/cortex_a78.S | 143 ++++++++++++++++++++++++++ lib/cpus/aarch64/cortex_hercules.S | 143 -------------------------- plat/arm/board/arm_fpga/platform.mk | 2 +- plat/arm/board/fvp/platform.mk | 2 +- 7 files changed, 191 insertions(+), 191 deletions(-) create mode 100644 include/lib/cpus/aarch64/cortex_a78.h delete mode 100644 include/lib/cpus/aarch64/cortex_hercules.h create mode 100644 lib/cpus/aarch64/cortex_a78.S delete mode 100644 lib/cpus/aarch64/cortex_hercules.S diff --git a/include/lib/cpus/aarch64/cortex_a78.h b/include/lib/cpus/aarch64/cortex_a78.h new file mode 100644 index 000000000..563d6684c --- /dev/null +++ b/include/lib/cpus/aarch64/cortex_a78.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2019-2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CORTEX_HERCULES_H +#define CORTEX_HERCULES_H + +#include + +#define CORTEX_HERCULES_MIDR U(0x410FD410) + +/******************************************************************************* + * CPU Extended Control register specific definitions. + ******************************************************************************/ +#define CORTEX_HERCULES_CPUECTLR_EL1 S3_0_C15_C1_4 + +/******************************************************************************* + * CPU Power Control register specific definitions + ******************************************************************************/ +#define CORTEX_HERCULES_CPUPWRCTLR_EL1 S3_0_C15_C2_7 +#define CORTEX_HERCULES_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT U(1) + +/******************************************************************************* + * CPU Auxiliary Control register specific definitions. + ******************************************************************************/ +#define CORTEX_HERCULES_ACTLR_TAM_BIT (ULL(1) << 30) + +#define CORTEX_HERCULES_ACTLR2_EL1 S3_0_C15_C1_1 +#define CORTEX_HERCULES_ACTLR2_EL1_BIT_1 (ULL(1) << 1) + +/******************************************************************************* + * CPU Activity Monitor Unit register specific definitions. + ******************************************************************************/ +#define CPUAMCNTENCLR0_EL0 S3_3_C15_C2_4 +#define CPUAMCNTENSET0_EL0 S3_3_C15_C2_5 +#define CPUAMCNTENCLR1_EL0 S3_3_C15_C3_0 +#define CPUAMCNTENSET1_EL0 S3_3_C15_C3_1 + +#define CORTEX_HERCULES_AMU_GROUP0_MASK U(0xF) +#define CORTEX_HERCULES_AMU_GROUP1_MASK U(0x7) + +#endif /* CORTEX_HERCULES_H */ diff --git a/include/lib/cpus/aarch64/cortex_hercules.h b/include/lib/cpus/aarch64/cortex_hercules.h deleted file mode 100644 index d5ca85ed2..000000000 --- a/include/lib/cpus/aarch64/cortex_hercules.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2019, ARM Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef CORTEX_HERCULES_H -#define CORTEX_HERCULES_H - -#include - -#define CORTEX_HERCULES_MIDR U(0x410FD410) - -/******************************************************************************* - * CPU Extended Control register specific definitions. - ******************************************************************************/ -#define CORTEX_HERCULES_CPUECTLR_EL1 S3_0_C15_C1_4 - -/******************************************************************************* - * CPU Power Control register specific definitions - ******************************************************************************/ -#define CORTEX_HERCULES_CPUPWRCTLR_EL1 S3_0_C15_C2_7 -#define CORTEX_HERCULES_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT U(1) - -/******************************************************************************* - * CPU Auxiliary Control register specific definitions. - ******************************************************************************/ -#define CORTEX_HERCULES_ACTLR_TAM_BIT (ULL(1) << 30) - -#define CORTEX_HERCULES_ACTLR2_EL1 S3_0_C15_C1_1 -#define CORTEX_HERCULES_ACTLR2_EL1_BIT_1 (ULL(1) << 1) - -/******************************************************************************* - * CPU Activity Monitor Unit register specific definitions. - ******************************************************************************/ -#define CPUAMCNTENCLR0_EL0 S3_3_C15_C2_4 -#define CPUAMCNTENSET0_EL0 S3_3_C15_C2_5 -#define CPUAMCNTENCLR1_EL0 S3_3_C15_C3_0 -#define CPUAMCNTENSET1_EL0 S3_3_C15_C3_1 - -#define CORTEX_HERCULES_AMU_GROUP0_MASK U(0xF) -#define CORTEX_HERCULES_AMU_GROUP1_MASK U(0x7) - -#endif /* CORTEX_HERCULES_H */ diff --git a/include/lib/cpus/aarch64/cortex_hercules_ae.h b/include/lib/cpus/aarch64/cortex_hercules_ae.h index 795563bc3..73c22f732 100644 --- a/include/lib/cpus/aarch64/cortex_hercules_ae.h +++ b/include/lib/cpus/aarch64/cortex_hercules_ae.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, ARM Limited. All rights reserved. + * Copyright (c) 2019-2020, ARM Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,7 +7,7 @@ #ifndef CORTEX_HERCULES_AE_H #define CORTEX_HERCULES_AE_H -#include +#include #define CORTEX_HERCULES_AE_MIDR U(0x410FD420) diff --git a/lib/cpus/aarch64/cortex_a78.S b/lib/cpus/aarch64/cortex_a78.S new file mode 100644 index 000000000..2293109a7 --- /dev/null +++ b/lib/cpus/aarch64/cortex_a78.S @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2019-2020, 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_hercules must be compiled with HW_ASSISTED_COHERENCY enabled" +#endif + + +/* -------------------------------------------------- + * Errata Workaround for Hercules Erratum 1688305. + * This applies to revision r0p0 and r1p0 of Hercules. + * Inputs: + * x0: variant[4:7] and revision[0:3] of current cpu. + * Shall clobber: x0-x17 + * -------------------------------------------------- + */ +func errata_hercules_1688305_wa + /* Compare x0 against revision r1p0 */ + mov x17, x30 + bl check_errata_1688305 + cbz x0, 1f + mrs x1, CORTEX_HERCULES_ACTLR2_EL1 + orr x1, x1, CORTEX_HERCULES_ACTLR2_EL1_BIT_1 + msr CORTEX_HERCULES_ACTLR2_EL1, x1 + isb +1: + ret x17 +endfunc errata_hercules_1688305_wa + +func check_errata_1688305 + /* Applies to r0p0 and r1p0 */ + mov x1, #0x10 + b cpu_rev_var_ls +endfunc check_errata_1688305 + + /* ------------------------------------------------- + * The CPU Ops reset function for Cortex-Hercules + * ------------------------------------------------- + */ +func cortex_hercules_reset_func + mov x19, x30 + bl cpu_get_rev_var + mov x18, x0 + +#if ERRATA_HERCULES_1688305 + mov x0, x18 + bl errata_hercules_1688305_wa +#endif + +#if ENABLE_AMU + /* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */ + mrs x0, actlr_el3 + bic x0, x0, #CORTEX_HERCULES_ACTLR_TAM_BIT + msr actlr_el3, x0 + + /* Make sure accesses from non-secure EL0/EL1 are not trapped to EL2 */ + mrs x0, actlr_el2 + bic x0, x0, #CORTEX_HERCULES_ACTLR_TAM_BIT + msr actlr_el2, x0 + + /* Enable group0 counters */ + mov x0, #CORTEX_HERCULES_AMU_GROUP0_MASK + msr CPUAMCNTENSET0_EL0, x0 + + /* Enable group1 counters */ + mov x0, #CORTEX_HERCULES_AMU_GROUP1_MASK + msr CPUAMCNTENSET1_EL0, x0 +#endif + + isb + ret x19 +endfunc cortex_hercules_reset_func + + /* --------------------------------------------- + * HW will do the cache maintenance while powering down + * --------------------------------------------- + */ +func cortex_hercules_core_pwr_dwn + /* --------------------------------------------- + * Enable CPU power down bit in power control register + * --------------------------------------------- + */ + mrs x0, CORTEX_HERCULES_CPUPWRCTLR_EL1 + orr x0, x0, #CORTEX_HERCULES_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT + msr CORTEX_HERCULES_CPUPWRCTLR_EL1, x0 + isb + ret +endfunc cortex_hercules_core_pwr_dwn + + /* + * Errata printing function for cortex_hercules. Must follow AAPCS. + */ +#if REPORT_ERRATA +func cortex_hercules_errata_report + stp x8, x30, [sp, #-16]! + + bl cpu_get_rev_var + mov x8, x0 + + /* + * Report all errata. The revision-variant information is passed to + * checking functions of each errata. + */ + report_errata ERRATA_HERCULES_1688305, cortex_hercules, 1688305 + + ldp x8, x30, [sp], #16 + ret +endfunc cortex_hercules_errata_report +#endif + + /* --------------------------------------------- + * This function provides cortex_hercules 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_hercules_regs, "aS" +cortex_hercules_regs: /* The ascii list of register names to be reported */ + .asciz "cpuectlr_el1", "" + +func cortex_hercules_cpu_reg_dump + adr x6, cortex_hercules_regs + mrs x8, CORTEX_HERCULES_CPUECTLR_EL1 + ret +endfunc cortex_hercules_cpu_reg_dump + +declare_cpu_ops cortex_hercules, CORTEX_HERCULES_MIDR, \ + cortex_hercules_reset_func, \ + cortex_hercules_core_pwr_dwn diff --git a/lib/cpus/aarch64/cortex_hercules.S b/lib/cpus/aarch64/cortex_hercules.S deleted file mode 100644 index a23919626..000000000 --- a/lib/cpus/aarch64/cortex_hercules.S +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) 2019, 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_hercules must be compiled with HW_ASSISTED_COHERENCY enabled" -#endif - - -/* -------------------------------------------------- - * Errata Workaround for Hercules Erratum 1688305. - * This applies to revision r0p0 and r1p0 of Hercules. - * Inputs: - * x0: variant[4:7] and revision[0:3] of current cpu. - * Shall clobber: x0-x17 - * -------------------------------------------------- - */ -func errata_hercules_1688305_wa - /* Compare x0 against revision r1p0 */ - mov x17, x30 - bl check_errata_1688305 - cbz x0, 1f - mrs x1, CORTEX_HERCULES_ACTLR2_EL1 - orr x1, x1, CORTEX_HERCULES_ACTLR2_EL1_BIT_1 - msr CORTEX_HERCULES_ACTLR2_EL1, x1 - isb -1: - ret x17 -endfunc errata_hercules_1688305_wa - -func check_errata_1688305 - /* Applies to r0p0 and r1p0 */ - mov x1, #0x10 - b cpu_rev_var_ls -endfunc check_errata_1688305 - - /* ------------------------------------------------- - * The CPU Ops reset function for Cortex-Hercules - * ------------------------------------------------- - */ -func cortex_hercules_reset_func - mov x19, x30 - bl cpu_get_rev_var - mov x18, x0 - -#if ERRATA_HERCULES_1688305 - mov x0, x18 - bl errata_hercules_1688305_wa -#endif - -#if ENABLE_AMU - /* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */ - mrs x0, actlr_el3 - bic x0, x0, #CORTEX_HERCULES_ACTLR_TAM_BIT - msr actlr_el3, x0 - - /* Make sure accesses from non-secure EL0/EL1 are not trapped to EL2 */ - mrs x0, actlr_el2 - bic x0, x0, #CORTEX_HERCULES_ACTLR_TAM_BIT - msr actlr_el2, x0 - - /* Enable group0 counters */ - mov x0, #CORTEX_HERCULES_AMU_GROUP0_MASK - msr CPUAMCNTENSET0_EL0, x0 - - /* Enable group1 counters */ - mov x0, #CORTEX_HERCULES_AMU_GROUP1_MASK - msr CPUAMCNTENSET1_EL0, x0 -#endif - - isb - ret x19 -endfunc cortex_hercules_reset_func - - /* --------------------------------------------- - * HW will do the cache maintenance while powering down - * --------------------------------------------- - */ -func cortex_hercules_core_pwr_dwn - /* --------------------------------------------- - * Enable CPU power down bit in power control register - * --------------------------------------------- - */ - mrs x0, CORTEX_HERCULES_CPUPWRCTLR_EL1 - orr x0, x0, #CORTEX_HERCULES_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT - msr CORTEX_HERCULES_CPUPWRCTLR_EL1, x0 - isb - ret -endfunc cortex_hercules_core_pwr_dwn - - /* - * Errata printing function for cortex_hercules. Must follow AAPCS. - */ -#if REPORT_ERRATA -func cortex_hercules_errata_report - stp x8, x30, [sp, #-16]! - - bl cpu_get_rev_var - mov x8, x0 - - /* - * Report all errata. The revision-variant information is passed to - * checking functions of each errata. - */ - report_errata ERRATA_HERCULES_1688305, cortex_hercules, 1688305 - - ldp x8, x30, [sp], #16 - ret -endfunc cortex_hercules_errata_report -#endif - - /* --------------------------------------------- - * This function provides cortex_hercules 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_hercules_regs, "aS" -cortex_hercules_regs: /* The ascii list of register names to be reported */ - .asciz "cpuectlr_el1", "" - -func cortex_hercules_cpu_reg_dump - adr x6, cortex_hercules_regs - mrs x8, CORTEX_HERCULES_CPUECTLR_EL1 - ret -endfunc cortex_hercules_cpu_reg_dump - -declare_cpu_ops cortex_hercules, CORTEX_HERCULES_MIDR, \ - cortex_hercules_reset_func, \ - cortex_hercules_core_pwr_dwn diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk index 0d0d010a1..7039a6d04 100644 --- a/plat/arm/board/arm_fpga/platform.mk +++ b/plat/arm/board/arm_fpga/platform.mk @@ -58,10 +58,10 @@ else FPGA_CPU_LIBS += lib/cpus/aarch64/cortex_a76.S \ lib/cpus/aarch64/cortex_a76ae.S \ lib/cpus/aarch64/cortex_a77.S \ + lib/cpus/aarch64/cortex_a78.S \ lib/cpus/aarch64/neoverse_n1.S \ lib/cpus/aarch64/neoverse_e1.S \ lib/cpus/aarch64/neoverse_zeus.S \ - lib/cpus/aarch64/cortex_hercules.S \ lib/cpus/aarch64/cortex_hercules_ae.S \ lib/cpus/aarch64/cortex_a65.S \ lib/cpus/aarch64/cortex_a65ae.S diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 33531f3fd..024e682bc 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -129,10 +129,10 @@ else FVP_CPU_LIBS += lib/cpus/aarch64/cortex_a76.S \ lib/cpus/aarch64/cortex_a76ae.S \ lib/cpus/aarch64/cortex_a77.S \ + lib/cpus/aarch64/cortex_a78.S \ lib/cpus/aarch64/neoverse_n1.S \ lib/cpus/aarch64/neoverse_e1.S \ lib/cpus/aarch64/neoverse_zeus.S \ - lib/cpus/aarch64/cortex_hercules.S \ lib/cpus/aarch64/cortex_hercules_ae.S \ lib/cpus/aarch64/cortex_klein.S \ lib/cpus/aarch64/cortex_matterhorn.S \ -- cgit v1.2.3 From 3f35709c55e1c27f60389ef1b43a2b436d3d4eb7 Mon Sep 17 00:00:00 2001 From: Jimmy Brisson Date: Mon, 1 Jun 2020 10:18:22 -0500 Subject: Rename Cortex-Hercules to Cortex-A78 Change-Id: I89b90cbdfc8f2aa898b4f3676a4764f060f8e138 Signed-off-by: Jimmy Brisson --- docs/design/cpu-specific-build-macros.rst | 9 ++-- include/lib/cpus/aarch64/cortex_a78.h | 24 +++++------ lib/cpus/aarch64/cortex_a78.S | 72 +++++++++++++++---------------- lib/cpus/aarch64/cortex_hercules_ae.S | 18 ++++---- lib/cpus/cpu-ops.mk | 10 ++--- 5 files changed, 66 insertions(+), 67 deletions(-) diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst index 258f73d0b..591f2f886 100644 --- a/docs/design/cpu-specific-build-macros.rst +++ b/docs/design/cpu-specific-build-macros.rst @@ -227,11 +227,10 @@ For Cortex-A76, the following errata build flags are defined : - ``ERRATA_A76_1275112``: This applies errata 1275112 workaround to Cortex-A76 CPU. This needs to be enabled only for revision <= r3p0 of the CPU. -For Hercules, the following errata build flags are defined : +For Cortex-A78, the following errata build flags are defined : -- ``ERRATA_HERCULES_1688305``: This applies errata 1688305 workaround to - Hercules CPU. This needs to be enabled only for revision r0p0 - r1p0 of - the CPU. +- ``ERRATA_A78_1688305``: This applies errata 1688305 workaround to Cortex-A78 + CPU. This needs to be enabled only for revision r0p0 - r1p0 of the CPU. For Neoverse N1, the following errata build flags are defined : @@ -338,7 +337,7 @@ architecture that can be enabled by the platform as desired. -------------- -*Copyright (c) 2014-2019, Arm Limited and Contributors. All rights reserved.* +*Copyright (c) 2014-2020, Arm Limited and Contributors. All rights reserved.* .. _CVE-2017-5715: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715 .. _CVE-2018-3639: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3639 diff --git a/include/lib/cpus/aarch64/cortex_a78.h b/include/lib/cpus/aarch64/cortex_a78.h index 563d6684c..0d4712b6a 100644 --- a/include/lib/cpus/aarch64/cortex_a78.h +++ b/include/lib/cpus/aarch64/cortex_a78.h @@ -4,31 +4,31 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#ifndef CORTEX_HERCULES_H -#define CORTEX_HERCULES_H +#ifndef CORTEX_A78_H +#define CORTEX_A78_H #include -#define CORTEX_HERCULES_MIDR U(0x410FD410) +#define CORTEX_A78_MIDR U(0x410FD410) /******************************************************************************* * CPU Extended Control register specific definitions. ******************************************************************************/ -#define CORTEX_HERCULES_CPUECTLR_EL1 S3_0_C15_C1_4 +#define CORTEX_A78_CPUECTLR_EL1 S3_0_C15_C1_4 /******************************************************************************* * CPU Power Control register specific definitions ******************************************************************************/ -#define CORTEX_HERCULES_CPUPWRCTLR_EL1 S3_0_C15_C2_7 -#define CORTEX_HERCULES_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT U(1) +#define CORTEX_A78_CPUPWRCTLR_EL1 S3_0_C15_C2_7 +#define CORTEX_A78_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT U(1) /******************************************************************************* * CPU Auxiliary Control register specific definitions. ******************************************************************************/ -#define CORTEX_HERCULES_ACTLR_TAM_BIT (ULL(1) << 30) +#define CORTEX_A78_ACTLR_TAM_BIT (ULL(1) << 30) -#define CORTEX_HERCULES_ACTLR2_EL1 S3_0_C15_C1_1 -#define CORTEX_HERCULES_ACTLR2_EL1_BIT_1 (ULL(1) << 1) +#define CORTEX_A78_ACTLR2_EL1 S3_0_C15_C1_1 +#define CORTEX_A78_ACTLR2_EL1_BIT_1 (ULL(1) << 1) /******************************************************************************* * CPU Activity Monitor Unit register specific definitions. @@ -38,7 +38,7 @@ #define CPUAMCNTENCLR1_EL0 S3_3_C15_C3_0 #define CPUAMCNTENSET1_EL0 S3_3_C15_C3_1 -#define CORTEX_HERCULES_AMU_GROUP0_MASK U(0xF) -#define CORTEX_HERCULES_AMU_GROUP1_MASK U(0x7) +#define CORTEX_A78_AMU_GROUP0_MASK U(0xF) +#define CORTEX_A78_AMU_GROUP1_MASK U(0x7) -#endif /* CORTEX_HERCULES_H */ +#endif /* CORTEX_A78_H */ diff --git a/lib/cpus/aarch64/cortex_a78.S b/lib/cpus/aarch64/cortex_a78.S index 2293109a7..9914f12e8 100644 --- a/lib/cpus/aarch64/cortex_a78.S +++ b/lib/cpus/aarch64/cortex_a78.S @@ -13,30 +13,30 @@ /* Hardware handled coherency */ #if HW_ASSISTED_COHERENCY == 0 -#error "cortex_hercules must be compiled with HW_ASSISTED_COHERENCY enabled" +#error "cortex_a78 must be compiled with HW_ASSISTED_COHERENCY enabled" #endif /* -------------------------------------------------- - * Errata Workaround for Hercules Erratum 1688305. - * This applies to revision r0p0 and r1p0 of Hercules. + * Errata Workaround for A78 Erratum 1688305. + * This applies to revision r0p0 and r1p0 of A78. * Inputs: * x0: variant[4:7] and revision[0:3] of current cpu. * Shall clobber: x0-x17 * -------------------------------------------------- */ -func errata_hercules_1688305_wa +func errata_a78_1688305_wa /* Compare x0 against revision r1p0 */ mov x17, x30 bl check_errata_1688305 cbz x0, 1f - mrs x1, CORTEX_HERCULES_ACTLR2_EL1 - orr x1, x1, CORTEX_HERCULES_ACTLR2_EL1_BIT_1 - msr CORTEX_HERCULES_ACTLR2_EL1, x1 + mrs x1, CORTEX_A78_ACTLR2_EL1 + orr x1, x1, CORTEX_A78_ACTLR2_EL1_BIT_1 + msr CORTEX_A78_ACTLR2_EL1, x1 isb 1: ret x17 -endfunc errata_hercules_1688305_wa +endfunc errata_a78_1688305_wa func check_errata_1688305 /* Applies to r0p0 and r1p0 */ @@ -45,64 +45,64 @@ func check_errata_1688305 endfunc check_errata_1688305 /* ------------------------------------------------- - * The CPU Ops reset function for Cortex-Hercules + * The CPU Ops reset function for Cortex-A78 * ------------------------------------------------- */ -func cortex_hercules_reset_func +func cortex_a78_reset_func mov x19, x30 bl cpu_get_rev_var mov x18, x0 -#if ERRATA_HERCULES_1688305 +#if ERRATA_A78_1688305 mov x0, x18 - bl errata_hercules_1688305_wa + bl errata_a78_1688305_wa #endif #if ENABLE_AMU /* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */ mrs x0, actlr_el3 - bic x0, x0, #CORTEX_HERCULES_ACTLR_TAM_BIT + bic x0, x0, #CORTEX_A78_ACTLR_TAM_BIT msr actlr_el3, x0 /* Make sure accesses from non-secure EL0/EL1 are not trapped to EL2 */ mrs x0, actlr_el2 - bic x0, x0, #CORTEX_HERCULES_ACTLR_TAM_BIT + bic x0, x0, #CORTEX_A78_ACTLR_TAM_BIT msr actlr_el2, x0 /* Enable group0 counters */ - mov x0, #CORTEX_HERCULES_AMU_GROUP0_MASK + mov x0, #CORTEX_A78_AMU_GROUP0_MASK msr CPUAMCNTENSET0_EL0, x0 /* Enable group1 counters */ - mov x0, #CORTEX_HERCULES_AMU_GROUP1_MASK + mov x0, #CORTEX_A78_AMU_GROUP1_MASK msr CPUAMCNTENSET1_EL0, x0 #endif isb ret x19 -endfunc cortex_hercules_reset_func +endfunc cortex_a78_reset_func /* --------------------------------------------- * HW will do the cache maintenance while powering down * --------------------------------------------- */ -func cortex_hercules_core_pwr_dwn +func cortex_a78_core_pwr_dwn /* --------------------------------------------- * Enable CPU power down bit in power control register * --------------------------------------------- */ - mrs x0, CORTEX_HERCULES_CPUPWRCTLR_EL1 - orr x0, x0, #CORTEX_HERCULES_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT - msr CORTEX_HERCULES_CPUPWRCTLR_EL1, x0 + mrs x0, CORTEX_A78_CPUPWRCTLR_EL1 + orr x0, x0, #CORTEX_A78_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT + msr CORTEX_A78_CPUPWRCTLR_EL1, x0 isb ret -endfunc cortex_hercules_core_pwr_dwn +endfunc cortex_a78_core_pwr_dwn /* - * Errata printing function for cortex_hercules. Must follow AAPCS. + * Errata printing function for cortex_a78. Must follow AAPCS. */ #if REPORT_ERRATA -func cortex_hercules_errata_report +func cortex_a78_errata_report stp x8, x30, [sp, #-16]! bl cpu_get_rev_var @@ -112,15 +112,15 @@ func cortex_hercules_errata_report * Report all errata. The revision-variant information is passed to * checking functions of each errata. */ - report_errata ERRATA_HERCULES_1688305, cortex_hercules, 1688305 + report_errata ERRATA_A78_1688305, cortex_a78, 1688305 ldp x8, x30, [sp], #16 ret -endfunc cortex_hercules_errata_report +endfunc cortex_a78_errata_report #endif /* --------------------------------------------- - * This function provides cortex_hercules specific + * This function provides cortex_a78 specific * register information for crash reporting. * It needs to return with x6 pointing to * a list of register names in ascii and @@ -128,16 +128,16 @@ endfunc cortex_hercules_errata_report * reported. * --------------------------------------------- */ -.section .rodata.cortex_hercules_regs, "aS" -cortex_hercules_regs: /* The ascii list of register names to be reported */ +.section .rodata.cortex_a78_regs, "aS" +cortex_a78_regs: /* The ascii list of register names to be reported */ .asciz "cpuectlr_el1", "" -func cortex_hercules_cpu_reg_dump - adr x6, cortex_hercules_regs - mrs x8, CORTEX_HERCULES_CPUECTLR_EL1 +func cortex_a78_cpu_reg_dump + adr x6, cortex_a78_regs + mrs x8, CORTEX_A78_CPUECTLR_EL1 ret -endfunc cortex_hercules_cpu_reg_dump +endfunc cortex_a78_cpu_reg_dump -declare_cpu_ops cortex_hercules, CORTEX_HERCULES_MIDR, \ - cortex_hercules_reset_func, \ - cortex_hercules_core_pwr_dwn +declare_cpu_ops cortex_a78, CORTEX_A78_MIDR, \ + cortex_a78_reset_func, \ + cortex_a78_core_pwr_dwn diff --git a/lib/cpus/aarch64/cortex_hercules_ae.S b/lib/cpus/aarch64/cortex_hercules_ae.S index c4a216353..4452c419a 100644 --- a/lib/cpus/aarch64/cortex_hercules_ae.S +++ b/lib/cpus/aarch64/cortex_hercules_ae.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, ARM Limited. All rights reserved. + * Copyright (c) 2019-2020, ARM Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -24,20 +24,20 @@ func cortex_hercules_ae_reset_func /* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */ mrs x0, actlr_el3 - bic x0, x0, #CORTEX_HERCULES_ACTLR_TAM_BIT + bic x0, x0, #CORTEX_A78_ACTLR_TAM_BIT msr actlr_el3, x0 /* Make sure accesses from non-secure EL0/EL1 are not trapped to EL2 */ mrs x0, actlr_el2 - bic x0, x0, #CORTEX_HERCULES_ACTLR_TAM_BIT + bic x0, x0, #CORTEX_A78_ACTLR_TAM_BIT msr actlr_el2, x0 /* Enable group0 counters */ - mov x0, #CORTEX_HERCULES_AMU_GROUP0_MASK + mov x0, #CORTEX_A78_AMU_GROUP0_MASK msr CPUAMCNTENSET0_EL0, x0 /* Enable group1 counters */ - mov x0, #CORTEX_HERCULES_AMU_GROUP1_MASK + mov x0, #CORTEX_A78_AMU_GROUP1_MASK msr CPUAMCNTENSET1_EL0, x0 isb @@ -54,9 +54,9 @@ func cortex_hercules_ae_core_pwr_dwn * Enable CPU power down bit in power control register * ------------------------------------------------------- */ - mrs x0, CORTEX_HERCULES_CPUPWRCTLR_EL1 - orr x0, x0, #CORTEX_HERCULES_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT - msr CORTEX_HERCULES_CPUPWRCTLR_EL1, x0 + mrs x0, CORTEX_A78_CPUPWRCTLR_EL1 + orr x0, x0, #CORTEX_A78_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT + msr CORTEX_A78_CPUPWRCTLR_EL1, x0 isb ret endfunc cortex_hercules_ae_core_pwr_dwn @@ -85,7 +85,7 @@ cortex_hercules_ae_regs: /* The ascii list of register names to be reported */ func cortex_hercules_ae_cpu_reg_dump adr x6, cortex_hercules_ae_regs - mrs x8, CORTEX_HERCULES_CPUECTLR_EL1 + mrs x8, CORTEX_A78_CPUECTLR_EL1 ret endfunc cortex_hercules_ae_cpu_reg_dump diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk index 3c0c9cd13..1bc082d82 100644 --- a/lib/cpus/cpu-ops.mk +++ b/lib/cpus/cpu-ops.mk @@ -251,8 +251,8 @@ ERRATA_A76_1275112 ?=0 ERRATA_A76_1286807 ?=0 # Flag to apply erratum 1688305 workaround during reset. This erratum applies -# to revisions r0p0 - r1p0 of the Hercules cpu. -ERRATA_HERCULES_1688305 ?=0 +# to revisions r0p0 - r1p0 of the A78 cpu. +ERRATA_A78_1688305 ?=0 # Flag to apply T32 CLREX workaround during reset. This erratum applies # only to r0p0 and r1p0 of the Neoverse N1 cpu. @@ -487,9 +487,9 @@ $(eval $(call add_define,ERRATA_A76_1275112)) $(eval $(call assert_boolean,ERRATA_A76_1286807)) $(eval $(call add_define,ERRATA_A76_1286807)) -# Process ERRATA_HERCULES_1688305 flag -$(eval $(call assert_boolean,ERRATA_HERCULES_1688305)) -$(eval $(call add_define,ERRATA_HERCULES_1688305)) +# Process ERRATA_A78_1688305 flag +$(eval $(call assert_boolean,ERRATA_A78_1688305)) +$(eval $(call add_define,ERRATA_A78_1688305)) # Process ERRATA_N1_1043202 flag $(eval $(call assert_boolean,ERRATA_N1_1043202)) -- cgit v1.2.3 From 0922e481e5a2dc2925ca9f26a4de7c9ef7abe1d6 Mon Sep 17 00:00:00 2001 From: Masahisa Kojima Date: Tue, 2 Jun 2020 05:54:13 +0900 Subject: xlat_tables_v2: add base table section name parameter for spm_mm Core spm_mm code expects the translation tables are located in the inner & outer WBWA & shareable memory. REGISTER_XLAT_CONTEXT2 macro is used to specify the translation table section in spm_mm. In the commit 363830df1c28e (xlat_tables_v2: merge REGISTER_XLAT_CONTEXT_{FULL_SPEC,RO_BASE_TABLE}), REGISTER_XLAT_CONTEXT2 macro explicitly specifies the base xlat table goes into .bss by default. This change affects the existing SynQuacer spm_mm implementation. plat/socionext/synquacer/include/plat.ld.S linker script intends to locate ".bss.sp_base_xlat_table" into "sp_xlat_table" section, but this implementation is no longer available. This patch adds the base table section name parameter for REGISTER_XLAT_CONTEXT2 so that platform can specify the inner & outer WBWA & shareable memory for spm_mm base xlat table. If PLAT_SP_IMAGE_BASE_XLAT_SECTION_NAME is not defined, base xlat table goes into .bss by default, the result is same as before. Change-Id: Ie0e1a235e5bd4288dc376f582d6c44c5df6d31b2 Signed-off-by: Masahisa Kojima --- include/lib/xlat_tables/xlat_tables_v2.h | 8 ++++++-- plat/socionext/synquacer/include/plat.ld.S | 1 - plat/socionext/synquacer/include/platform_def.h | 1 + services/std_svc/spm_mm/spm_mm_xlat.c | 6 +++++- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/include/lib/xlat_tables/xlat_tables_v2.h b/include/lib/xlat_tables/xlat_tables_v2.h index 8eb84a892..359b9839a 100644 --- a/include/lib/xlat_tables/xlat_tables_v2.h +++ b/include/lib/xlat_tables/xlat_tables_v2.h @@ -201,16 +201,20 @@ typedef struct xlat_ctx xlat_ctx_t; * _section_name: * Specify the name of the section where the translation tables have to be * placed by the linker. + * + * _base_table_section_name: + * Specify the name of the section where the base translation tables have to + * be placed by the linker. */ #define REGISTER_XLAT_CONTEXT2(_ctx_name, _mmap_count, _xlat_tables_count, \ _virt_addr_space_size, _phy_addr_space_size, \ - _xlat_regime, _section_name) \ + _xlat_regime, _section_name, _base_table_section_name) \ REGISTER_XLAT_CONTEXT_FULL_SPEC(_ctx_name, (_mmap_count), \ (_xlat_tables_count), \ (_virt_addr_space_size), \ (_phy_addr_space_size), \ (_xlat_regime), \ - (_section_name), ".bss" \ + (_section_name), (_base_table_section_name) \ ) /****************************************************************************** diff --git a/plat/socionext/synquacer/include/plat.ld.S b/plat/socionext/synquacer/include/plat.ld.S index a06fe2adb..af7a172db 100644 --- a/plat/socionext/synquacer/include/plat.ld.S +++ b/plat/socionext/synquacer/include/plat.ld.S @@ -25,7 +25,6 @@ SECTIONS */ sp_xlat_table (NOLOAD) : ALIGN(PAGE_SIZE) { *(sp_xlat_table) - *(.bss.sp_base_xlat_table) } >SP_DRAM } diff --git a/plat/socionext/synquacer/include/platform_def.h b/plat/socionext/synquacer/include/platform_def.h index b87ac3fd6..2f8613a7e 100644 --- a/plat/socionext/synquacer/include/platform_def.h +++ b/plat/socionext/synquacer/include/platform_def.h @@ -144,6 +144,7 @@ #define PLAT_SP_IMAGE_MMAP_REGIONS 30 #define PLAT_SP_IMAGE_MAX_XLAT_TABLES 20 #define PLAT_SP_IMAGE_XLAT_SECTION_NAME "sp_xlat_table" +#define PLAT_SP_IMAGE_BASE_XLAT_SECTION_NAME "sp_xlat_table" #define PLAT_SQ_UART1_BASE PLAT_SQ_BOOT_UART_BASE #define PLAT_SQ_UART1_SIZE ULL(0x1000) diff --git a/services/std_svc/spm_mm/spm_mm_xlat.c b/services/std_svc/spm_mm/spm_mm_xlat.c index 6c02f0743..eae597cab 100644 --- a/services/std_svc/spm_mm/spm_mm_xlat.c +++ b/services/std_svc/spm_mm/spm_mm_xlat.c @@ -21,13 +21,17 @@ #ifndef PLAT_SP_IMAGE_XLAT_SECTION_NAME #define PLAT_SP_IMAGE_XLAT_SECTION_NAME "xlat_table" #endif +#ifndef PLAT_SP_IMAGE_BASE_XLAT_SECTION_NAME +#define PLAT_SP_IMAGE_BASE_XLAT_SECTION_NAME ".bss" +#endif /* Allocate and initialise the translation context for the secure partitions. */ REGISTER_XLAT_CONTEXT2(sp, PLAT_SP_IMAGE_MMAP_REGIONS, PLAT_SP_IMAGE_MAX_XLAT_TABLES, PLAT_VIRT_ADDR_SPACE_SIZE, PLAT_PHY_ADDR_SPACE_SIZE, - EL1_EL0_REGIME, PLAT_SP_IMAGE_XLAT_SECTION_NAME); + EL1_EL0_REGIME, PLAT_SP_IMAGE_XLAT_SECTION_NAME, + PLAT_SP_IMAGE_BASE_XLAT_SECTION_NAME); /* Lock used for SP_MEMORY_ATTRIBUTES_GET and SP_MEMORY_ATTRIBUTES_SET */ static spinlock_t mem_attr_smc_lock; -- cgit v1.2.3 From 110ee4330af41a83afff102c8852c1dc161b7501 Mon Sep 17 00:00:00 2001 From: Jimmy Brisson Date: Thu, 16 Apr 2020 10:47:56 -0500 Subject: Enable ARMv8.6-FGT when booting to EL2 The Fine Grained Traps (FGT) architecture extension was added to aarch64 in ARMv8.6. This extension primarily allows hypervisors, at EL2, to trap specific instructions in a more fine grained manner, with an enable bit for each instruction. This patch adds support for this extension by enabling the extension when booting an hypervisor at EL2. Change-Id: Idb9013ed118b6a1b7b76287237096de992ca4da3 Signed-off-by: Jimmy Brisson --- include/arch/aarch64/arch.h | 6 ++++++ include/arch/aarch64/arch_features.h | 6 ++++++ lib/el3_runtime/aarch64/context_mgmt.c | 7 +++++++ 3 files changed, 19 insertions(+) diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index 9d4ad3ba8..c7cf9f47d 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -211,6 +211,11 @@ #define PARANGE_0101 U(48) #define PARANGE_0110 U(52) +#define ID_AA64MMFR0_EL1_FGT_SHIFT U(56) +#define ID_AA64MMFR0_EL1_FGT_MASK ULL(0xf) +#define ID_AA64MMFR0_EL1_FGT_SUPPORTED ULL(0x1) +#define ID_AA64MMFR0_EL1_FGT_NOT_SUPPORTED ULL(0x0) + #define ID_AA64MMFR0_EL1_TGRAN4_SHIFT U(28) #define ID_AA64MMFR0_EL1_TGRAN4_MASK ULL(0xf) #define ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED ULL(0x0) @@ -324,6 +329,7 @@ #define SCR_TWEDEL_SHIFT U(30) #define SCR_TWEDEL_MASK ULL(0xf) #define SCR_TWEDEn_BIT (UL(1) << 29) +#define SCR_FGTEN_BIT (U(1) << 27) #define SCR_ATA_BIT (U(1) << 26) #define SCR_FIEN_BIT (U(1) << 21) #define SCR_EEL2_BIT (U(1) << 18) diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h index 321485aed..9bcf30598 100644 --- a/include/arch/aarch64/arch_features.h +++ b/include/arch/aarch64/arch_features.h @@ -64,6 +64,12 @@ static inline bool is_armv8_6_twed_present(void) ID_AA64MMFR1_EL1_TWED_MASK) == ID_AA64MMFR1_EL1_TWED_SUPPORTED); } +static inline bool is_armv8_6_fgt_present(void) +{ + return ((read_id_aa64mmfr0_el1() >> ID_AA64MMFR0_EL1_FGT_SHIFT) & + ID_AA64MMFR0_EL1_FGT_MASK) == ID_AA64MMFR0_EL1_FGT_SUPPORTED; +} + /* * Return MPAM version: * diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c index 64a2d7b5c..1c5ba3608 100644 --- a/lib/el3_runtime/aarch64/context_mgmt.c +++ b/lib/el3_runtime/aarch64/context_mgmt.c @@ -173,11 +173,18 @@ void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep) * SCR_EL3.HCE: Enable HVC instructions if next execution state is * AArch64 and next EL is EL2, or if next execution state is AArch32 and * next mode is Hyp. + * SCR_EL3.FGTEn: Enable Fine Grained Virtualization Traps under the + * same conditions as HVC instructions and when the processor supports + * ARMv8.6-FGT. */ if (((GET_RW(ep->spsr) == MODE_RW_64) && (GET_EL(ep->spsr) == MODE_EL2)) || ((GET_RW(ep->spsr) != MODE_RW_64) && (GET_M32(ep->spsr) == MODE32_hyp))) { scr_el3 |= SCR_HCE_BIT; + + if (is_armv8_6_fgt_present()) { + scr_el3 |= SCR_FGTEN_BIT; + } } /* Enable S-EL2 if the next EL is EL2 and security state is secure */ -- cgit v1.2.3 From 29d0ee542dc171d3b75db82c7f7f2dae0ffab64f Mon Sep 17 00:00:00 2001 From: Jimmy Brisson Date: Thu, 16 Apr 2020 10:48:02 -0500 Subject: Enable ARMv8.6-ECV Self-Synch when booting to EL2 Enhanced Counter Virtualization, ECV, is an architecture extension introduced in ARMv8.6. This extension allows the hypervisor, at EL2, to setup self-synchronizing views of the timers for it's EL1 Guests. This patch pokes the control register to enable this extension when booting a hypervisor at EL2. Change-Id: I4e929ecdf400cea17eff1de5cf8704aa7e40973d Signed-off-by: Jimmy Brisson --- include/arch/aarch64/arch.h | 7 +++++++ include/arch/aarch64/arch_features.h | 6 ++++++ lib/el3_runtime/aarch64/context_mgmt.c | 8 ++++++++ 3 files changed, 21 insertions(+) diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index c7cf9f47d..10fe926ea 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -211,6 +211,12 @@ #define PARANGE_0101 U(48) #define PARANGE_0110 U(52) +#define ID_AA64MMFR0_EL1_ECV_SHIFT U(60) +#define ID_AA64MMFR0_EL1_ECV_MASK ULL(0xf) +#define ID_AA64MMFR0_EL1_ECV_NOT_SUPPORTED ULL(0x0) +#define ID_AA64MMFR0_EL1_ECV_SUPPORTED ULL(0x1) +#define ID_AA64MMFR0_EL1_ECV_SELF_SYNCH ULL(0x2) + #define ID_AA64MMFR0_EL1_FGT_SHIFT U(56) #define ID_AA64MMFR0_EL1_FGT_MASK ULL(0xf) #define ID_AA64MMFR0_EL1_FGT_SUPPORTED ULL(0x1) @@ -329,6 +335,7 @@ #define SCR_TWEDEL_SHIFT U(30) #define SCR_TWEDEL_MASK ULL(0xf) #define SCR_TWEDEn_BIT (UL(1) << 29) +#define SCR_ECVEN_BIT (U(1) << 28) #define SCR_FGTEN_BIT (U(1) << 27) #define SCR_ATA_BIT (U(1) << 26) #define SCR_FIEN_BIT (U(1) << 21) diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h index 9bcf30598..6b5d32696 100644 --- a/include/arch/aarch64/arch_features.h +++ b/include/arch/aarch64/arch_features.h @@ -70,6 +70,12 @@ static inline bool is_armv8_6_fgt_present(void) ID_AA64MMFR0_EL1_FGT_MASK) == ID_AA64MMFR0_EL1_FGT_SUPPORTED; } +static inline unsigned long int get_armv8_6_ecv_support(void) +{ + return ((read_id_aa64mmfr0_el1() >> ID_AA64MMFR0_EL1_ECV_SHIFT) & + ID_AA64MMFR0_EL1_ECV_MASK); +} + /* * Return MPAM version: * diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c index 1c5ba3608..53b4ea3e3 100644 --- a/lib/el3_runtime/aarch64/context_mgmt.c +++ b/lib/el3_runtime/aarch64/context_mgmt.c @@ -176,6 +176,9 @@ void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep) * SCR_EL3.FGTEn: Enable Fine Grained Virtualization Traps under the * same conditions as HVC instructions and when the processor supports * ARMv8.6-FGT. + * SCR_EL3.ECVEn: Enable Enhanced Counter Virtualization (ECV) + * CNTPOFF_EL2 register under the same conditions as HVC instructions + * and when the processor supports ECV. */ if (((GET_RW(ep->spsr) == MODE_RW_64) && (GET_EL(ep->spsr) == MODE_EL2)) || ((GET_RW(ep->spsr) != MODE_RW_64) @@ -185,6 +188,11 @@ void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep) if (is_armv8_6_fgt_present()) { scr_el3 |= SCR_FGTEN_BIT; } + + if (get_armv8_6_ecv_support() + == ID_AA64MMFR0_EL1_ECV_SELF_SYNCH) { + scr_el3 |= SCR_ECVEN_BIT; + } } /* Enable S-EL2 if the next EL is EL2 and security state is secure */ -- cgit v1.2.3 From 03363af88871f9d6298a6e8cff40dc0714e782e2 Mon Sep 17 00:00:00 2001 From: Marcin Wojtas Date: Tue, 2 Jun 2020 15:12:06 +0200 Subject: marvell: a8k: enable BL31 cache by default BL31_CACHE_DISABLE flag was introduced as a work-around for the older SoC revisions. Since it is not relevant in the newest versions, toggle it to be disabled by default. One can still specify it by adding 'BL31_CACHE_DISABLE=1' string to the build command. Change-Id: I11b52dade3ff7f8ee643b8078c6e447c45946570 Signed-off-by: Marcin Wojtas --- plat/marvell/a8k/common/a8k_common.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plat/marvell/a8k/common/a8k_common.mk b/plat/marvell/a8k/common/a8k_common.mk index bf79ebeec..1ff28f846 100644 --- a/plat/marvell/a8k/common/a8k_common.mk +++ b/plat/marvell/a8k/common/a8k_common.mk @@ -1,5 +1,5 @@ # -# Copyright (C) 2016 - 2018 Marvell International Ltd. +# Copyright (C) 2016 - 2020 Marvell International Ltd. # # SPDX-License-Identifier: BSD-3-Clause # https://spdx.org/licenses @@ -22,7 +22,7 @@ ERRATA_A72_859971 := 1 MSS_SUPPORT := 1 # Disable EL3 cache for power management -BL31_CACHE_DISABLE := 1 +BL31_CACHE_DISABLE := 0 $(eval $(call add_define,BL31_CACHE_DISABLE)) $(eval $(call add_define,PCI_EP_SUPPORT)) -- cgit v1.2.3 From 2d1d2f05c4703df4d0e39123d2645f6d28078dc6 Mon Sep 17 00:00:00 2001 From: Marcin Wojtas Date: Tue, 12 May 2020 18:19:33 +0200 Subject: marvell: drivers: mochi: specify stream ID for SD/MMC This patch enables the stream ID for the SD/MMC controllers via dedicated unit register. Thanks to this change it is possible to configure properly the IOMMU in OS and use the SD/MMC interface in a guest Virtual Machine. Change-Id: I99cbd2c9882eb558ba01405d3d8a3e969f06e082 Signed-off-by: Marcin Wojtas Signed-off-by: Tomasz Nowicki --- drivers/marvell/mochi/cp110_setup.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/marvell/mochi/cp110_setup.c b/drivers/marvell/mochi/cp110_setup.c index 7186f9857..0fa049764 100644 --- a/drivers/marvell/mochi/cp110_setup.c +++ b/drivers/marvell/mochi/cp110_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 Marvell International Ltd. + * Copyright (C) 2018-2020 Marvell International Ltd. * * SPDX-License-Identifier: BSD-3-Clause * https://spdx.org/licenses @@ -130,6 +130,7 @@ enum axi_attr { #define USB3H_1_STREAM_ID_REG (RFU_STREAM_ID_BASE + 0x10) #define SATA_0_STREAM_ID_REG (RFU_STREAM_ID_BASE + 0x14) #define SATA_1_STREAM_ID_REG (RFU_STREAM_ID_BASE + 0x18) +#define SDIO_0_STREAM_ID_REG (RFU_STREAM_ID_BASE + 0x28) #define CP_DMA_0_STREAM_ID_REG (0x6B0010) #define CP_DMA_1_STREAM_ID_REG (0x6D0010) @@ -144,6 +145,7 @@ uintptr_t stream_id_reg[] = { CP_DMA_1_STREAM_ID_REG, SATA_0_STREAM_ID_REG, SATA_1_STREAM_ID_REG, + SDIO_0_STREAM_ID_REG, 0 }; -- cgit v1.2.3 From 77d0504ed5eb90f5eabacb60084ec108fd0eada4 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Sun, 8 Dec 2019 08:15:15 +0100 Subject: drivers: introduce ST ETZPC driver ETZPC stands for Extended TrustZone Protection Controller. It is a resource conditional access device. It is mainly based on Arm TZPC. ST ETZPC exposes memory mapped DECPROT cells to set access permissions to SoC peripheral interfaces as I2C, SPI, DDR controllers, and some of the SoC internal memories. ST ETZPC exposes memory mapped TZMA cells to set access permissions to some SoC internal memories. Change-Id: I47ce20ffcfb55306dab923153b71e1bcbe2a5570 Co-developed-by: Yann Gautier Signed-off-by: Yann Gautier Signed-off-by: Etienne Carriere --- drivers/st/etzpc/etzpc.c | 258 +++++++++++++++++++++++++++++++ include/drivers/st/etzpc.h | 35 +++++ include/dt-bindings/soc/st,stm32-etzpc.h | 20 +++ 3 files changed, 313 insertions(+) create mode 100644 drivers/st/etzpc/etzpc.c create mode 100644 include/drivers/st/etzpc.h create mode 100644 include/dt-bindings/soc/st,stm32-etzpc.h diff --git a/drivers/st/etzpc/etzpc.c b/drivers/st/etzpc/etzpc.c new file mode 100644 index 000000000..ff52a22d9 --- /dev/null +++ b/drivers/st/etzpc/etzpc.c @@ -0,0 +1,258 @@ +/* + * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +/* Device Tree related definitions */ +#define ETZPC_COMPAT "st,stm32-etzpc" +#define ETZPC_LOCK_MASK 0x1U +#define ETZPC_MODE_SHIFT 8 +#define ETZPC_MODE_MASK GENMASK(1, 0) +#define ETZPC_ID_SHIFT 16 +#define ETZPC_ID_MASK GENMASK(7, 0) + +/* ID Registers */ +#define ETZPC_TZMA0_SIZE 0x000U +#define ETZPC_DECPROT0 0x010U +#define ETZPC_DECPROT_LOCK0 0x030U +#define ETZPC_HWCFGR 0x3F0U +#define ETZPC_VERR 0x3F4U + +/* ID Registers fields */ +#define ETZPC_TZMA0_SIZE_LOCK BIT(31) +#define ETZPC_DECPROT0_MASK GENMASK(1, 0) +#define ETZPC_HWCFGR_NUM_TZMA_SHIFT 0 +#define ETZPC_HWCFGR_NUM_PER_SEC_SHIFT 8 +#define ETZPC_HWCFGR_NUM_AHB_SEC_SHIFT 16 +#define ETZPC_HWCFGR_CHUNCKS1N4_SHIFT 24 + +#define DECPROT_SHIFT 1 +#define IDS_PER_DECPROT_REGS 16U +#define IDS_PER_DECPROT_LOCK_REGS 32U + +/* + * etzpc_instance. + * base : register base address set during init given by user + * chunk_size : supported TZMA size steps + * num_tzma: number of TZMA zone read from register at init + * num_ahb_sec : number of securable AHB master zone read from register + * num_per_sec : number of securable AHB & APB Peripherals read from register + * revision : IP revision read from register at init + */ +struct etzpc_instance { + uintptr_t base; + uint8_t chunck_size; + uint8_t num_tzma; + uint8_t num_per_sec; + uint8_t num_ahb_sec; + uint8_t revision; +}; + +/* Only 1 instance of the ETZPC is expected per platform */ +static struct etzpc_instance etzpc_dev; + +/* + * Implementation uses uint8_t to store each securable DECPROT configuration. + * When resuming from deep suspend, the DECPROT configurations are restored. + */ +#define PERIPH_LOCK_BIT BIT(7) +#define PERIPH_ATTR_MASK GENMASK(2, 0) + +#if ENABLE_ASSERTIONS +static bool valid_decprot_id(unsigned int id) +{ + return id < (unsigned int)etzpc_dev.num_per_sec; +} + +static bool valid_tzma_id(unsigned int id) +{ + return id < (unsigned int)etzpc_dev.num_tzma; +} +#endif + +/* + * etzpc_configure_decprot : Load a DECPROT configuration + * decprot_id : ID of the IP + * decprot_attr : Restriction access attribute + */ +void etzpc_configure_decprot(uint32_t decprot_id, + enum etzpc_decprot_attributes decprot_attr) +{ + uintptr_t offset = 4U * (decprot_id / IDS_PER_DECPROT_REGS); + uint32_t shift = (decprot_id % IDS_PER_DECPROT_REGS) << DECPROT_SHIFT; + uint32_t masked_decprot = (uint32_t)decprot_attr & ETZPC_DECPROT0_MASK; + + assert(valid_decprot_id(decprot_id)); + + mmio_clrsetbits_32(etzpc_dev.base + ETZPC_DECPROT0 + offset, + (uint32_t)ETZPC_DECPROT0_MASK << shift, + masked_decprot << shift); +} + +/* + * etzpc_get_decprot : Get the DECPROT attribute + * decprot_id : ID of the IP + * return : Attribute of this DECPROT + */ +enum etzpc_decprot_attributes etzpc_get_decprot(uint32_t decprot_id) +{ + uintptr_t offset = 4U * (decprot_id / IDS_PER_DECPROT_REGS); + uint32_t shift = (decprot_id % IDS_PER_DECPROT_REGS) << DECPROT_SHIFT; + uintptr_t base_decprot = etzpc_dev.base + offset; + uint32_t value; + + assert(valid_decprot_id(decprot_id)); + + value = (mmio_read_32(base_decprot + ETZPC_DECPROT0) >> shift) & + ETZPC_DECPROT0_MASK; + + return (enum etzpc_decprot_attributes)value; +} + +/* + * etzpc_lock_decprot : Lock access to the DECPROT attribute + * decprot_id : ID of the IP + */ +void etzpc_lock_decprot(uint32_t decprot_id) +{ + uintptr_t offset = 4U * (decprot_id / IDS_PER_DECPROT_LOCK_REGS); + uint32_t shift = BIT(decprot_id % IDS_PER_DECPROT_LOCK_REGS); + uintptr_t base_decprot = etzpc_dev.base + offset; + + assert(valid_decprot_id(decprot_id)); + + mmio_write_32(base_decprot + ETZPC_DECPROT_LOCK0, shift); +} + +/* + * etzpc_configure_tzma : Configure the target TZMA read only size + * tzma_id : ID of the memory + * tzma_value : read-only size + */ +void etzpc_configure_tzma(uint32_t tzma_id, uint16_t tzma_value) +{ + assert(valid_tzma_id(tzma_id)); + + mmio_write_32(etzpc_dev.base + ETZPC_TZMA0_SIZE + + (sizeof(uint32_t) * tzma_id), tzma_value); +} + +/* + * etzpc_get_tzma : Get the target TZMA read only size + * tzma_id : TZMA ID + * return : Size of read only size + */ +uint16_t etzpc_get_tzma(uint32_t tzma_id) +{ + assert(valid_tzma_id(tzma_id)); + + return (uint16_t)mmio_read_32(etzpc_dev.base + ETZPC_TZMA0_SIZE + + (sizeof(uint32_t) * tzma_id)); +} + +/* + * etzpc_lock_tzma : Lock the target TZMA + * tzma_id : TZMA ID + */ +void etzpc_lock_tzma(uint32_t tzma_id) +{ + assert(valid_tzma_id(tzma_id)); + + mmio_setbits_32(etzpc_dev.base + ETZPC_TZMA0_SIZE + + (sizeof(uint32_t) * tzma_id), ETZPC_TZMA0_SIZE_LOCK); +} + +/* + * etzpc_get_lock_tzma : Return the lock status of the target TZMA + * tzma_id : TZMA ID + * return : True if TZMA is locked, false otherwise + */ +bool etzpc_get_lock_tzma(uint32_t tzma_id) +{ + uint32_t tzma_size; + + assert(valid_tzma_id(tzma_id)); + + tzma_size = mmio_read_32(etzpc_dev.base + ETZPC_TZMA0_SIZE + + (sizeof(uint32_t) * tzma_id)); + + return (tzma_size & ETZPC_TZMA0_SIZE_LOCK) != 0; +} + +/* + * etzpc_get_num_per_sec : Return the DECPROT ID limit value + */ +uint8_t etzpc_get_num_per_sec(void) +{ + return etzpc_dev.num_per_sec; +} + +/* + * etzpc_get_revision : Return the ETZPC IP revision + */ +uint8_t etzpc_get_revision(void) +{ + return etzpc_dev.revision; +} + +/* + * etzpc_get_base_address : Return the ETZPC IP base address + */ +uintptr_t etzpc_get_base_address(void) +{ + return etzpc_dev.base; +} + +/* + * etzpc_init : Initialize the ETZPC driver + * Return 0 on success and a negative errno on failure + */ +int etzpc_init(void) +{ + uint32_t hwcfg; + int node; + struct dt_node_info etzpc_info; + + node = dt_get_node(&etzpc_info, -1, ETZPC_COMPAT); + if (node < 0) { + return -EIO; + } + + /* Check ETZPC is secure only */ + if (etzpc_info.status != DT_SECURE) { + return -EACCES; + } + + etzpc_dev.base = etzpc_info.base; + + hwcfg = mmio_read_32(etzpc_dev.base + ETZPC_HWCFGR); + + etzpc_dev.num_tzma = (uint8_t)(hwcfg >> ETZPC_HWCFGR_NUM_TZMA_SHIFT); + etzpc_dev.num_per_sec = (uint8_t)(hwcfg >> + ETZPC_HWCFGR_NUM_PER_SEC_SHIFT); + etzpc_dev.num_ahb_sec = (uint8_t)(hwcfg >> + ETZPC_HWCFGR_NUM_AHB_SEC_SHIFT); + etzpc_dev.chunck_size = (uint8_t)(hwcfg >> + ETZPC_HWCFGR_CHUNCKS1N4_SHIFT); + + etzpc_dev.revision = mmio_read_8(etzpc_dev.base + ETZPC_VERR); + + VERBOSE("ETZPC version 0x%x", etzpc_dev.revision); + + return 0; +} diff --git a/include/drivers/st/etzpc.h b/include/drivers/st/etzpc.h new file mode 100644 index 000000000..6e3fec1ea --- /dev/null +++ b/include/drivers/st/etzpc.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef DRIVERS_ST_ETZPC_H +#define DRIVERS_ST_ETZPC_H + +/* Define security level for each peripheral (DECPROT) */ +enum etzpc_decprot_attributes { + ETZPC_DECPROT_S_RW = 0, + ETZPC_DECPROT_NS_R_S_W = 1, + ETZPC_DECPROT_MCU_ISOLATION = 2, + ETZPC_DECPROT_NS_RW = 3, + ETZPC_DECPROT_MAX = 4, +}; + +void etzpc_configure_decprot(uint32_t decprot_id, + enum etzpc_decprot_attributes decprot_attr); +enum etzpc_decprot_attributes etzpc_get_decprot(uint32_t decprot_id); +void etzpc_lock_decprot(uint32_t decprot_id); + +void etzpc_configure_tzma(uint32_t tzma_id, uint16_t tzma_value); +uint16_t etzpc_get_tzma(uint32_t tzma_id); +void etzpc_lock_tzma(uint32_t tzma_id); +bool etzpc_get_lock_tzma(uint32_t tzma_id); + +uint8_t etzpc_get_num_per_sec(void); +uint8_t etzpc_get_revision(void); +uintptr_t etzpc_get_base_address(void); + +int etzpc_init(void); + +#endif /* DRIVERS_ST_ETZPC_H */ diff --git a/include/dt-bindings/soc/st,stm32-etzpc.h b/include/dt-bindings/soc/st,stm32-etzpc.h new file mode 100644 index 000000000..3f9fb3b12 --- /dev/null +++ b/include/dt-bindings/soc/st,stm32-etzpc.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2017-2020, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause + */ + +#ifndef _DT_BINDINGS_STM32_ETZPC_H +#define _DT_BINDINGS_STM32_ETZPC_H + +/* DECPROT modes */ +#define DECPROT_S_RW 0x0 +#define DECPROT_NS_R_S_W 0x1 +#define DECPROT_MCU_ISOLATION 0x2 +#define DECPROT_NS_RW 0x3 + +/* DECPROT lock */ +#define DECPROT_UNLOCK 0x0 +#define DECPROT_LOCK 0x1 + +#endif /* _DT_BINDINGS_STM32_ETZPC_H */ -- cgit v1.2.3 From 627298d4b65526cde17f8c49b77f2ea4d573a796 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Sun, 8 Dec 2019 08:16:43 +0100 Subject: dts: stm32mp157c: add etzpc node Add a node for the ETZPC device so that driver initializes during stm32mp15* boot sequence. Change-Id: I84bf10572e5df7b8f450163c79bcfe6956fc838f Signed-off-by: Etienne Carriere --- fdts/stm32mp157c.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fdts/stm32mp157c.dtsi b/fdts/stm32mp157c.dtsi index 0942a91c2..a9a24dae7 100644 --- a/fdts/stm32mp157c.dtsi +++ b/fdts/stm32mp157c.dtsi @@ -362,5 +362,13 @@ #size-cells = <0>; status = "disabled"; }; + + etzpc: etzpc@5c007000 { + compatible = "st,stm32-etzpc"; + reg = <0x5C007000 0x400>; + clocks = <&rcc TZPC>; + status = "disabled"; + secure-status = "okay"; + }; }; }; -- cgit v1.2.3 From 7b3a46f0e41786d635a57fa7797c8bf14573ce10 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Fri, 10 Apr 2020 11:32:54 +0200 Subject: plat/stm32mp1: sp_min relies on etzpc driver Use ETZPC driver to configure secure aware interfaces to assign them to non-secure world. Sp_min also configures BootROM resources and SYSRAM to assign both to secure world only. Define stm32mp15 SoC identifiers for the platform specific DECPROT instances. Change-Id: I3bec9f47b04bcba3929e4df886ddb1d5ff843089 Signed-off-by: Etienne Carriere --- plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk | 4 +- plat/st/stm32mp1/sp_min/sp_min_setup.c | 28 +++++++-- plat/st/stm32mp1/stm32mp1_def.h | 98 ++++++++++++++++++++++++++++++ 3 files changed, 124 insertions(+), 6 deletions(-) diff --git a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk index 4188cc58a..180620e88 100644 --- a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk +++ b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk @@ -6,10 +6,12 @@ SP_MIN_WITH_SECURE_FIQ := 1 -BL32_SOURCES += plat/common/aarch32/platform_mp_stack.S \ +BL32_SOURCES += drivers/st/etzpc/etzpc.c \ + plat/common/aarch32/platform_mp_stack.S \ plat/st/stm32mp1/sp_min/sp_min_setup.c \ plat/st/stm32mp1/stm32mp1_pm.c \ plat/st/stm32mp1/stm32mp1_topology.c + # Generic GIC v2 BL32_SOURCES += drivers/arm/gic/common/gic_common.c \ drivers/arm/gic/v2/gicv2_helpers.c \ diff --git a/plat/st/stm32mp1/sp_min/sp_min_setup.c b/plat/st/stm32mp1/sp_min/sp_min_setup.c index 4e74c275d..e1799eda6 100644 --- a/plat/st/stm32mp1/sp_min/sp_min_setup.c +++ b/plat/st/stm32mp1/sp_min/sp_min_setup.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -76,6 +77,26 @@ entry_point_info_t *sp_min_plat_get_bl33_ep_info(void) return next_image_info; } +#define TZMA1_SECURE_RANGE STM32MP1_ETZPC_TZMA_ALL_SECURE +#define TZMA0_SECURE_RANGE STM32MP1_ETZPC_TZMA_ALL_SECURE + +static void stm32mp1_etzpc_early_setup(void) +{ + unsigned int n; + + if (etzpc_init() != 0) { + panic(); + } + + etzpc_configure_tzma(STM32MP1_ETZPC_TZMA_ROM, TZMA0_SECURE_RANGE); + etzpc_configure_tzma(STM32MP1_ETZPC_TZMA_SYSRAM, TZMA1_SECURE_RANGE); + + /* Release security on all shared resources */ + for (n = 0; n < STM32MP1_ETZPC_SEC_ID_LIMIT; n++) { + etzpc_configure_decprot(n, ETZPC_DECPROT_NS_RW); + } +} + /******************************************************************************* * Perform any BL32 specific platform actions. ******************************************************************************/ @@ -144,6 +165,8 @@ void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1, #endif console_set_scope(&console, console_flags); } + + stm32mp1_etzpc_early_setup(); } /******************************************************************************* @@ -158,11 +181,6 @@ void sp_min_platform_setup(void) stm32mp1_gic_init(); - /* Unlock ETZPC securable peripherals */ -#define STM32MP1_ETZPC_BASE 0x5C007000U -#define ETZPC_DECPROT0 0x010U - mmio_write_32(STM32MP1_ETZPC_BASE + ETZPC_DECPROT0, 0xFFFFFFFF); - /* Set GPIO bank Z as non secure */ for (uint32_t pin = 0U; pin < STM32MP_GPIOZ_PIN_MAX_COUNT; pin++) { set_gpio_secure_cfg(GPIO_BANK_Z, pin, false); diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h index fc776ae8b..0a12b6e57 100644 --- a/plat/st/stm32mp1/stm32mp1_def.h +++ b/plat/st/stm32mp1/stm32mp1_def.h @@ -246,6 +246,104 @@ enum ddr_type { #define DEBUG_UART_TX_EN_REG RCC_MP_APB1ENSETR #define DEBUG_UART_TX_EN RCC_MP_APB1ENSETR_UART4EN +/******************************************************************************* + * STM32MP1 ETZPC + ******************************************************************************/ +#define STM32MP1_ETZPC_BASE U(0x5C007000) + +/* ETZPC TZMA IDs */ +#define STM32MP1_ETZPC_TZMA_ROM U(0) +#define STM32MP1_ETZPC_TZMA_SYSRAM U(1) + +#define STM32MP1_ETZPC_TZMA_ALL_SECURE GENMASK_32(9, 0) + +/* ETZPC DECPROT IDs */ +#define STM32MP1_ETZPC_STGENC_ID 0 +#define STM32MP1_ETZPC_BKPSRAM_ID 1 +#define STM32MP1_ETZPC_IWDG1_ID 2 +#define STM32MP1_ETZPC_USART1_ID 3 +#define STM32MP1_ETZPC_SPI6_ID 4 +#define STM32MP1_ETZPC_I2C4_ID 5 +#define STM32MP1_ETZPC_RNG1_ID 7 +#define STM32MP1_ETZPC_HASH1_ID 8 +#define STM32MP1_ETZPC_CRYP1_ID 9 +#define STM32MP1_ETZPC_DDRCTRL_ID 10 +#define STM32MP1_ETZPC_DDRPHYC_ID 11 +#define STM32MP1_ETZPC_I2C6_ID 12 +#define STM32MP1_ETZPC_SEC_ID_LIMIT 13 + +#define STM32MP1_ETZPC_TIM2_ID 16 +#define STM32MP1_ETZPC_TIM3_ID 17 +#define STM32MP1_ETZPC_TIM4_ID 18 +#define STM32MP1_ETZPC_TIM5_ID 19 +#define STM32MP1_ETZPC_TIM6_ID 20 +#define STM32MP1_ETZPC_TIM7_ID 21 +#define STM32MP1_ETZPC_TIM12_ID 22 +#define STM32MP1_ETZPC_TIM13_ID 23 +#define STM32MP1_ETZPC_TIM14_ID 24 +#define STM32MP1_ETZPC_LPTIM1_ID 25 +#define STM32MP1_ETZPC_WWDG1_ID 26 +#define STM32MP1_ETZPC_SPI2_ID 27 +#define STM32MP1_ETZPC_SPI3_ID 28 +#define STM32MP1_ETZPC_SPDIFRX_ID 29 +#define STM32MP1_ETZPC_USART2_ID 30 +#define STM32MP1_ETZPC_USART3_ID 31 +#define STM32MP1_ETZPC_UART4_ID 32 +#define STM32MP1_ETZPC_UART5_ID 33 +#define STM32MP1_ETZPC_I2C1_ID 34 +#define STM32MP1_ETZPC_I2C2_ID 35 +#define STM32MP1_ETZPC_I2C3_ID 36 +#define STM32MP1_ETZPC_I2C5_ID 37 +#define STM32MP1_ETZPC_CEC_ID 38 +#define STM32MP1_ETZPC_DAC_ID 39 +#define STM32MP1_ETZPC_UART7_ID 40 +#define STM32MP1_ETZPC_UART8_ID 41 +#define STM32MP1_ETZPC_MDIOS_ID 44 +#define STM32MP1_ETZPC_TIM1_ID 48 +#define STM32MP1_ETZPC_TIM8_ID 49 +#define STM32MP1_ETZPC_USART6_ID 51 +#define STM32MP1_ETZPC_SPI1_ID 52 +#define STM32MP1_ETZPC_SPI4_ID 53 +#define STM32MP1_ETZPC_TIM15_ID 54 +#define STM32MP1_ETZPC_TIM16_ID 55 +#define STM32MP1_ETZPC_TIM17_ID 56 +#define STM32MP1_ETZPC_SPI5_ID 57 +#define STM32MP1_ETZPC_SAI1_ID 58 +#define STM32MP1_ETZPC_SAI2_ID 59 +#define STM32MP1_ETZPC_SAI3_ID 60 +#define STM32MP1_ETZPC_DFSDM_ID 61 +#define STM32MP1_ETZPC_TT_FDCAN_ID 62 +#define STM32MP1_ETZPC_LPTIM2_ID 64 +#define STM32MP1_ETZPC_LPTIM3_ID 65 +#define STM32MP1_ETZPC_LPTIM4_ID 66 +#define STM32MP1_ETZPC_LPTIM5_ID 67 +#define STM32MP1_ETZPC_SAI4_ID 68 +#define STM32MP1_ETZPC_VREFBUF_ID 69 +#define STM32MP1_ETZPC_DCMI_ID 70 +#define STM32MP1_ETZPC_CRC2_ID 71 +#define STM32MP1_ETZPC_ADC_ID 72 +#define STM32MP1_ETZPC_HASH2_ID 73 +#define STM32MP1_ETZPC_RNG2_ID 74 +#define STM32MP1_ETZPC_CRYP2_ID 75 +#define STM32MP1_ETZPC_SRAM1_ID 80 +#define STM32MP1_ETZPC_SRAM2_ID 81 +#define STM32MP1_ETZPC_SRAM3_ID 82 +#define STM32MP1_ETZPC_SRAM4_ID 83 +#define STM32MP1_ETZPC_RETRAM_ID 84 +#define STM32MP1_ETZPC_OTG_ID 85 +#define STM32MP1_ETZPC_SDMMC3_ID 86 +#define STM32MP1_ETZPC_DLYBSD3_ID 87 +#define STM32MP1_ETZPC_DMA1_ID 88 +#define STM32MP1_ETZPC_DMA2_ID 89 +#define STM32MP1_ETZPC_DMAMUX_ID 90 +#define STM32MP1_ETZPC_FMC_ID 91 +#define STM32MP1_ETZPC_QSPI_ID 92 +#define STM32MP1_ETZPC_DLYBQ_ID 93 +#define STM32MP1_ETZPC_ETH_ID 94 +#define STM32MP1_ETZPC_RSV_ID 95 + +#define STM32MP_ETZPC_MAX_ID 96 + /******************************************************************************* * STM32MP1 TZC (TZ400) ******************************************************************************/ -- cgit v1.2.3 From d7f5be8ec2fc5254fc581af52156b5fde5deb822 Mon Sep 17 00:00:00 2001 From: Masahisa Kojima Date: Tue, 19 May 2020 19:49:36 +0900 Subject: qemu/qemu_sbsa: increase size to handle fdt 64KB was not enouth to handle fdt, bl2 shows following error message. "ERROR: Invalid Device Tree at 0x10000000000: error -3" This patch increases the size to 1MB to address above error. Signed-off-by: Masahisa Kojima Change-Id: I0726a0cea95087175451da0dba7410acd27df808 --- plat/qemu/qemu_sbsa/include/platform_def.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/qemu/qemu_sbsa/include/platform_def.h b/plat/qemu/qemu_sbsa/include/platform_def.h index f44b9f6e0..d0a56cf14 100644 --- a/plat/qemu/qemu_sbsa/include/platform_def.h +++ b/plat/qemu/qemu_sbsa/include/platform_def.h @@ -233,7 +233,7 @@ * DT related constants */ #define PLAT_QEMU_DT_BASE NS_DRAM0_BASE -#define PLAT_QEMU_DT_MAX_SIZE 0x10000 +#define PLAT_QEMU_DT_MAX_SIZE 0x100000 /* * System counter -- cgit v1.2.3 From bca652a28463cba40c429cc9465c1ee9b3449ea2 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Wed, 3 Jun 2020 18:12:20 +0200 Subject: dts: stm32mp157c: fix etzpc node location in DTSI file Fix etzpc node location in stm32mp157c DTSI file as requested during the patch review. The comment was addressed then fixup change discarded while rebasing. Change-Id: Ie53531fec7da224de0b86c968a66aec441bfc25d Fixes: 627298d4b655 ("dts: stm32mp157c: add etzpc node") Reported-by: Yann Gautier Signed-off-by: Etienne Carriere --- fdts/stm32mp157c.dtsi | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/fdts/stm32mp157c.dtsi b/fdts/stm32mp157c.dtsi index a9a24dae7..91b20fa4a 100644 --- a/fdts/stm32mp157c.dtsi +++ b/fdts/stm32mp157c.dtsi @@ -349,6 +349,14 @@ }; }; + etzpc: etzpc@5c007000 { + compatible = "st,stm32-etzpc"; + reg = <0x5C007000 0x400>; + clocks = <&rcc TZPC>; + status = "disabled"; + secure-status = "okay"; + }; + i2c6: i2c@5c009000 { compatible = "st,stm32f7-i2c"; reg = <0x5c009000 0x400>; @@ -362,13 +370,5 @@ #size-cells = <0>; status = "disabled"; }; - - etzpc: etzpc@5c007000 { - compatible = "st,stm32-etzpc"; - reg = <0x5C007000 0x400>; - clocks = <&rcc TZPC>; - status = "disabled"; - secure-status = "okay"; - }; }; }; -- cgit v1.2.3 From a7e0be55918455194986d9178202bc8e80415594 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Fri, 5 Jun 2020 17:51:19 +0200 Subject: rockchip: rk3368: increase MAX_MMAP_REGIONS Current value is 16, count the MAP_REGION calls gets us at least 17, so increase the max value to 20 to have a bit of a margin. Signed-off-by: Heiko Stuebner Change-Id: I93d0324f3d483758366e758f8f663545d365e03f --- plat/rockchip/rk3368/include/platform_def.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/rockchip/rk3368/include/platform_def.h b/plat/rockchip/rk3368/include/platform_def.h index 12115b4f0..6fcf2ba82 100644 --- a/plat/rockchip/rk3368/include/platform_def.h +++ b/plat/rockchip/rk3368/include/platform_def.h @@ -86,7 +86,7 @@ #define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) #define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) #define MAX_XLAT_TABLES 8 -#define MAX_MMAP_REGIONS 16 +#define MAX_MMAP_REGIONS 20 /******************************************************************************* * Declarations and constants to access the mailboxes safely. Each mailbox is -- cgit v1.2.3 From a28471722afb3ae784d7bce2118c2ea703f8444c Mon Sep 17 00:00:00 2001 From: Grzegorz Jaszczyk Date: Tue, 5 Nov 2019 13:14:59 +0100 Subject: marvell: armada: add extra level in marvell platform hierarchy This commit is a preparation for upcoming support for OcteonTX and OcteonTX2 product families. Armada platform related files (docs, plat, include/plat) are moved to the new "armada" sub-folder. Change-Id: Icf03356187078ad6a2e56c9870992be3ca4c9655 Signed-off-by: Grzegorz Jaszczyk Signed-off-by: Marcin Wojtas --- docs/plat/marvell/armada/build.rst | 253 ++++++ .../marvell/armada/misc/mvebu-a8k-addr-map.rst | 49 ++ docs/plat/marvell/armada/misc/mvebu-amb.rst | 58 ++ docs/plat/marvell/armada/misc/mvebu-ccu.rst | 33 + docs/plat/marvell/armada/misc/mvebu-io-win.rst | 46 ++ docs/plat/marvell/armada/misc/mvebu-iob.rst | 52 ++ docs/plat/marvell/armada/porting.rst | 163 ++++ docs/plat/marvell/build.rst | 253 ------ docs/plat/marvell/index.rst | 14 +- docs/plat/marvell/misc/mvebu-a8k-addr-map.rst | 49 -- docs/plat/marvell/misc/mvebu-amb.rst | 58 -- docs/plat/marvell/misc/mvebu-ccu.rst | 33 - docs/plat/marvell/misc/mvebu-io-win.rst | 46 -- docs/plat/marvell/misc/mvebu-iob.rst | 52 -- docs/plat/marvell/porting.rst | 163 ---- drivers/marvell/comphy/phy-comphy-cp110.c | 2 +- drivers/marvell/comphy/phy-comphy-cp110.h | 2 +- include/plat/marvell/a3700/common/armada_common.h | 17 - .../plat/marvell/a3700/common/board_marvell_def.h | 76 -- include/plat/marvell/a3700/common/marvell_def.h | 177 ----- include/plat/marvell/a3700/common/plat_marvell.h | 103 --- include/plat/marvell/a8k/common/armada_common.h | 129 ---- .../plat/marvell/a8k/common/board_marvell_def.h | 77 -- include/plat/marvell/a8k/common/marvell_def.h | 181 ----- include/plat/marvell/a8k/common/plat_marvell.h | 137 ---- include/plat/marvell/a8k/common/plat_pm_trace.h | 99 --- .../marvell/armada/a3700/common/armada_common.h | 17 + .../armada/a3700/common/board_marvell_def.h | 76 ++ .../plat/marvell/armada/a3700/common/marvell_def.h | 177 +++++ .../marvell/armada/a3700/common/plat_marvell.h | 103 +++ .../plat/marvell/armada/a8k/common/armada_common.h | 129 ++++ .../marvell/armada/a8k/common/board_marvell_def.h | 77 ++ .../plat/marvell/armada/a8k/common/marvell_def.h | 181 +++++ .../plat/marvell/armada/a8k/common/plat_marvell.h | 137 ++++ .../plat/marvell/armada/a8k/common/plat_pm_trace.h | 99 +++ .../marvell/armada/common/aarch64/cci_macros.S | 39 + .../marvell/armada/common/aarch64/marvell_macros.S | 134 ++++ .../plat/marvell/armada/common/marvell_plat_priv.h | 34 + include/plat/marvell/armada/common/marvell_pm.h | 26 + include/plat/marvell/armada/common/mvebu.h | 39 + include/plat/marvell/common/aarch64/cci_macros.S | 39 - .../plat/marvell/common/aarch64/marvell_macros.S | 134 ---- include/plat/marvell/common/marvell_plat_priv.h | 34 - include/plat/marvell/common/marvell_pm.h | 26 - include/plat/marvell/common/mvebu.h | 39 - plat/marvell/a3700/a3700/board/pm_src.c | 37 - plat/marvell/a3700/a3700/mvebu_def.h | 13 - plat/marvell/a3700/a3700/plat_bl31_setup.c | 70 -- plat/marvell/a3700/a3700/platform.mk | 10 - plat/marvell/a3700/common/a3700_common.mk | 170 ----- plat/marvell/a3700/common/a3700_ea.c | 23 - plat/marvell/a3700/common/a3700_sip_svc.c | 84 -- plat/marvell/a3700/common/aarch64/a3700_common.c | 53 -- plat/marvell/a3700/common/aarch64/plat_helpers.S | 68 -- plat/marvell/a3700/common/dram_win.c | 278 ------- plat/marvell/a3700/common/include/a3700_plat_def.h | 122 --- plat/marvell/a3700/common/include/a3700_pm.h | 51 -- plat/marvell/a3700/common/include/ddr_info.h | 14 - plat/marvell/a3700/common/include/dram_win.h | 18 - plat/marvell/a3700/common/include/io_addr_dec.h | 66 -- plat/marvell/a3700/common/include/plat_macros.S | 26 - plat/marvell/a3700/common/include/platform_def.h | 232 ------ plat/marvell/a3700/common/io_addr_dec.c | 179 ----- plat/marvell/a3700/common/marvell_plat_config.c | 34 - plat/marvell/a3700/common/plat_pm.c | 807 -------------------- plat/marvell/a8k/a70x0/board/dram_port.c | 90 --- plat/marvell/a8k/a70x0/board/marvell_plat_config.c | 145 ---- plat/marvell/a8k/a70x0/mvebu_def.h | 15 - plat/marvell/a8k/a70x0/platform.mk | 19 - plat/marvell/a8k/a70x0_amc/board/dram_port.c | 90 --- .../a8k/a70x0_amc/board/marvell_plat_config.c | 142 ---- plat/marvell/a8k/a70x0_amc/mvebu_def.h | 31 - plat/marvell/a8k/a70x0_amc/platform.mk | 19 - plat/marvell/a8k/a80x0/board/dram_port.c | 142 ---- plat/marvell/a8k/a80x0/board/marvell_plat_config.c | 196 ----- plat/marvell/a8k/a80x0/board/phy-porting-layer.h | 181 ----- plat/marvell/a8k/a80x0/mvebu_def.h | 17 - plat/marvell/a8k/a80x0/platform.mk | 20 - plat/marvell/a8k/a80x0_mcbin/board/dram_port.c | 130 ---- .../a8k/a80x0_mcbin/board/marvell_plat_config.c | 198 ----- plat/marvell/a8k/a80x0_mcbin/mvebu_def.h | 17 - plat/marvell/a8k/a80x0_mcbin/platform.mk | 19 - plat/marvell/a8k/common/a8k_common.mk | 130 ---- plat/marvell/a8k/common/aarch64/a8k_common.c | 64 -- plat/marvell/a8k/common/aarch64/plat_arch_config.c | 45 -- plat/marvell/a8k/common/aarch64/plat_helpers.S | 112 --- plat/marvell/a8k/common/ble/ble.ld.S | 76 -- plat/marvell/a8k/common/ble/ble.mk | 32 - plat/marvell/a8k/common/ble/ble_main.c | 99 --- plat/marvell/a8k/common/ble/ble_mem.S | 30 - plat/marvell/a8k/common/include/a8k_plat_def.h | 194 ----- plat/marvell/a8k/common/include/ddr_info.h | 9 - plat/marvell/a8k/common/include/mentor_i2c_plat.h | 33 - plat/marvell/a8k/common/include/plat_macros.S | 20 - plat/marvell/a8k/common/include/platform_def.h | 203 ----- plat/marvell/a8k/common/mss/mss_a8k.mk | 21 - plat/marvell/a8k/common/mss/mss_bl2_setup.c | 151 ---- plat/marvell/a8k/common/mss/mss_pm_ipc.c | 85 --- plat/marvell/a8k/common/mss/mss_pm_ipc.h | 35 - plat/marvell/a8k/common/plat_bl1_setup.c | 19 - plat/marvell/a8k/common/plat_bl31_setup.c | 140 ---- plat/marvell/a8k/common/plat_ble_setup.c | 735 ------------------ plat/marvell/a8k/common/plat_pm.c | 844 --------------------- plat/marvell/a8k/common/plat_pm_trace.c | 92 --- plat/marvell/a8k/common/plat_thermal.c | 130 ---- plat/marvell/armada/a3700/a3700/board/pm_src.c | 37 + plat/marvell/armada/a3700/a3700/mvebu_def.h | 13 + plat/marvell/armada/a3700/a3700/plat_bl31_setup.c | 70 ++ plat/marvell/armada/a3700/a3700/platform.mk | 10 + plat/marvell/armada/a3700/common/a3700_common.mk | 170 +++++ plat/marvell/armada/a3700/common/a3700_ea.c | 23 + plat/marvell/armada/a3700/common/a3700_sip_svc.c | 84 ++ .../armada/a3700/common/aarch64/a3700_common.c | 53 ++ .../armada/a3700/common/aarch64/plat_helpers.S | 68 ++ plat/marvell/armada/a3700/common/dram_win.c | 278 +++++++ .../armada/a3700/common/include/a3700_plat_def.h | 122 +++ .../marvell/armada/a3700/common/include/a3700_pm.h | 51 ++ .../marvell/armada/a3700/common/include/ddr_info.h | 14 + .../marvell/armada/a3700/common/include/dram_win.h | 18 + .../armada/a3700/common/include/io_addr_dec.h | 66 ++ .../armada/a3700/common/include/plat_macros.S | 26 + .../armada/a3700/common/include/platform_def.h | 232 ++++++ plat/marvell/armada/a3700/common/io_addr_dec.c | 179 +++++ .../armada/a3700/common/marvell_plat_config.c | 34 + plat/marvell/armada/a3700/common/plat_pm.c | 807 ++++++++++++++++++++ plat/marvell/armada/a8k/a70x0/board/dram_port.c | 90 +++ .../armada/a8k/a70x0/board/marvell_plat_config.c | 145 ++++ plat/marvell/armada/a8k/a70x0/mvebu_def.h | 15 + plat/marvell/armada/a8k/a70x0/platform.mk | 19 + .../marvell/armada/a8k/a70x0_amc/board/dram_port.c | 90 +++ .../a8k/a70x0_amc/board/marvell_plat_config.c | 142 ++++ plat/marvell/armada/a8k/a70x0_amc/mvebu_def.h | 31 + plat/marvell/armada/a8k/a70x0_amc/platform.mk | 19 + plat/marvell/armada/a8k/a80x0/board/dram_port.c | 142 ++++ .../armada/a8k/a80x0/board/marvell_plat_config.c | 196 +++++ .../armada/a8k/a80x0/board/phy-porting-layer.h | 181 +++++ plat/marvell/armada/a8k/a80x0/mvebu_def.h | 17 + plat/marvell/armada/a8k/a80x0/platform.mk | 20 + .../armada/a8k/a80x0_mcbin/board/dram_port.c | 130 ++++ .../a8k/a80x0_mcbin/board/marvell_plat_config.c | 198 +++++ plat/marvell/armada/a8k/a80x0_mcbin/mvebu_def.h | 17 + plat/marvell/armada/a8k/a80x0_mcbin/platform.mk | 19 + plat/marvell/armada/a8k/common/a8k_common.mk | 130 ++++ .../marvell/armada/a8k/common/aarch64/a8k_common.c | 64 ++ .../armada/a8k/common/aarch64/plat_arch_config.c | 45 ++ .../armada/a8k/common/aarch64/plat_helpers.S | 112 +++ plat/marvell/armada/a8k/common/ble/ble.ld.S | 76 ++ plat/marvell/armada/a8k/common/ble/ble.mk | 32 + plat/marvell/armada/a8k/common/ble/ble_main.c | 99 +++ plat/marvell/armada/a8k/common/ble/ble_mem.S | 30 + .../armada/a8k/common/include/a8k_plat_def.h | 194 +++++ plat/marvell/armada/a8k/common/include/ddr_info.h | 9 + .../armada/a8k/common/include/mentor_i2c_plat.h | 33 + .../armada/a8k/common/include/plat_macros.S | 20 + .../armada/a8k/common/include/platform_def.h | 203 +++++ plat/marvell/armada/a8k/common/mss/mss_a8k.mk | 21 + plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c | 151 ++++ plat/marvell/armada/a8k/common/mss/mss_pm_ipc.c | 85 +++ plat/marvell/armada/a8k/common/mss/mss_pm_ipc.h | 35 + plat/marvell/armada/a8k/common/plat_bl1_setup.c | 19 + plat/marvell/armada/a8k/common/plat_bl31_setup.c | 140 ++++ plat/marvell/armada/a8k/common/plat_ble_setup.c | 735 ++++++++++++++++++ plat/marvell/armada/a8k/common/plat_pm.c | 844 +++++++++++++++++++++ plat/marvell/armada/a8k/common/plat_pm_trace.c | 92 +++ plat/marvell/armada/a8k/common/plat_thermal.c | 130 ++++ .../common/aarch64/marvell_bl2_mem_params_desc.c | 129 ++++ .../marvell/armada/common/aarch64/marvell_common.c | 137 ++++ .../armada/common/aarch64/marvell_helpers.S | 250 ++++++ plat/marvell/armada/common/marvell_bl1_setup.c | 105 +++ plat/marvell/armada/common/marvell_bl2_setup.c | 135 ++++ plat/marvell/armada/common/marvell_bl31_setup.c | 237 ++++++ plat/marvell/armada/common/marvell_cci.c | 52 ++ plat/marvell/armada/common/marvell_common.mk | 72 ++ plat/marvell/armada/common/marvell_console.c | 76 ++ plat/marvell/armada/common/marvell_ddr_info.c | 112 +++ plat/marvell/armada/common/marvell_gicv2.c | 148 ++++ plat/marvell/armada/common/marvell_gicv3.c | 210 +++++ plat/marvell/armada/common/marvell_image_load.c | 36 + plat/marvell/armada/common/marvell_io_storage.c | 208 +++++ plat/marvell/armada/common/marvell_pm.c | 60 ++ plat/marvell/armada/common/marvell_topology.c | 84 ++ plat/marvell/armada/common/mrvl_sip_svc.c | 149 ++++ plat/marvell/armada/common/mss/mss_common.mk | 20 + plat/marvell/armada/common/mss/mss_ipc_drv.c | 113 +++ plat/marvell/armada/common/mss/mss_ipc_drv.h | 120 +++ plat/marvell/armada/common/mss/mss_mem.h | 60 ++ .../marvell/armada/common/mss/mss_scp_bl2_format.h | 45 ++ .../marvell/armada/common/mss/mss_scp_bootloader.c | 343 +++++++++ .../marvell/armada/common/mss/mss_scp_bootloader.h | 19 + plat/marvell/armada/common/plat_delay_timer.c | 34 + .../common/aarch64/marvell_bl2_mem_params_desc.c | 129 ---- plat/marvell/common/aarch64/marvell_common.c | 137 ---- plat/marvell/common/aarch64/marvell_helpers.S | 250 ------ plat/marvell/common/marvell_bl1_setup.c | 105 --- plat/marvell/common/marvell_bl2_setup.c | 135 ---- plat/marvell/common/marvell_bl31_setup.c | 237 ------ plat/marvell/common/marvell_cci.c | 52 -- plat/marvell/common/marvell_common.mk | 72 -- plat/marvell/common/marvell_console.c | 76 -- plat/marvell/common/marvell_ddr_info.c | 112 --- plat/marvell/common/marvell_gicv2.c | 148 ---- plat/marvell/common/marvell_gicv3.c | 210 ----- plat/marvell/common/marvell_image_load.c | 36 - plat/marvell/common/marvell_io_storage.c | 208 ----- plat/marvell/common/marvell_pm.c | 60 -- plat/marvell/common/marvell_topology.c | 84 -- plat/marvell/common/mrvl_sip_svc.c | 149 ---- plat/marvell/common/mss/mss_common.mk | 20 - plat/marvell/common/mss/mss_ipc_drv.c | 113 --- plat/marvell/common/mss/mss_ipc_drv.h | 120 --- plat/marvell/common/mss/mss_mem.h | 60 -- plat/marvell/common/mss/mss_scp_bl2_format.h | 45 -- plat/marvell/common/mss/mss_scp_bootloader.c | 343 --------- plat/marvell/common/mss/mss_scp_bootloader.h | 19 - plat/marvell/common/plat_delay_timer.c | 34 - 215 files changed, 12010 insertions(+), 12010 deletions(-) create mode 100644 docs/plat/marvell/armada/build.rst create mode 100644 docs/plat/marvell/armada/misc/mvebu-a8k-addr-map.rst create mode 100644 docs/plat/marvell/armada/misc/mvebu-amb.rst create mode 100644 docs/plat/marvell/armada/misc/mvebu-ccu.rst create mode 100644 docs/plat/marvell/armada/misc/mvebu-io-win.rst create mode 100644 docs/plat/marvell/armada/misc/mvebu-iob.rst create mode 100644 docs/plat/marvell/armada/porting.rst delete mode 100644 docs/plat/marvell/build.rst delete mode 100644 docs/plat/marvell/misc/mvebu-a8k-addr-map.rst delete mode 100644 docs/plat/marvell/misc/mvebu-amb.rst delete mode 100644 docs/plat/marvell/misc/mvebu-ccu.rst delete mode 100644 docs/plat/marvell/misc/mvebu-io-win.rst delete mode 100644 docs/plat/marvell/misc/mvebu-iob.rst delete mode 100644 docs/plat/marvell/porting.rst delete mode 100644 include/plat/marvell/a3700/common/armada_common.h delete mode 100644 include/plat/marvell/a3700/common/board_marvell_def.h delete mode 100644 include/plat/marvell/a3700/common/marvell_def.h delete mode 100644 include/plat/marvell/a3700/common/plat_marvell.h delete mode 100644 include/plat/marvell/a8k/common/armada_common.h delete mode 100644 include/plat/marvell/a8k/common/board_marvell_def.h delete mode 100644 include/plat/marvell/a8k/common/marvell_def.h delete mode 100644 include/plat/marvell/a8k/common/plat_marvell.h delete mode 100644 include/plat/marvell/a8k/common/plat_pm_trace.h create mode 100644 include/plat/marvell/armada/a3700/common/armada_common.h create mode 100644 include/plat/marvell/armada/a3700/common/board_marvell_def.h create mode 100644 include/plat/marvell/armada/a3700/common/marvell_def.h create mode 100644 include/plat/marvell/armada/a3700/common/plat_marvell.h create mode 100644 include/plat/marvell/armada/a8k/common/armada_common.h create mode 100644 include/plat/marvell/armada/a8k/common/board_marvell_def.h create mode 100644 include/plat/marvell/armada/a8k/common/marvell_def.h create mode 100644 include/plat/marvell/armada/a8k/common/plat_marvell.h create mode 100644 include/plat/marvell/armada/a8k/common/plat_pm_trace.h create mode 100644 include/plat/marvell/armada/common/aarch64/cci_macros.S create mode 100644 include/plat/marvell/armada/common/aarch64/marvell_macros.S create mode 100644 include/plat/marvell/armada/common/marvell_plat_priv.h create mode 100644 include/plat/marvell/armada/common/marvell_pm.h create mode 100644 include/plat/marvell/armada/common/mvebu.h delete mode 100644 include/plat/marvell/common/aarch64/cci_macros.S delete mode 100644 include/plat/marvell/common/aarch64/marvell_macros.S delete mode 100644 include/plat/marvell/common/marvell_plat_priv.h delete mode 100644 include/plat/marvell/common/marvell_pm.h delete mode 100644 include/plat/marvell/common/mvebu.h delete mode 100644 plat/marvell/a3700/a3700/board/pm_src.c delete mode 100644 plat/marvell/a3700/a3700/mvebu_def.h delete mode 100644 plat/marvell/a3700/a3700/plat_bl31_setup.c delete mode 100644 plat/marvell/a3700/a3700/platform.mk delete mode 100644 plat/marvell/a3700/common/a3700_common.mk delete mode 100644 plat/marvell/a3700/common/a3700_ea.c delete mode 100644 plat/marvell/a3700/common/a3700_sip_svc.c delete mode 100644 plat/marvell/a3700/common/aarch64/a3700_common.c delete mode 100644 plat/marvell/a3700/common/aarch64/plat_helpers.S delete mode 100644 plat/marvell/a3700/common/dram_win.c delete mode 100644 plat/marvell/a3700/common/include/a3700_plat_def.h delete mode 100644 plat/marvell/a3700/common/include/a3700_pm.h delete mode 100644 plat/marvell/a3700/common/include/ddr_info.h delete mode 100644 plat/marvell/a3700/common/include/dram_win.h delete mode 100644 plat/marvell/a3700/common/include/io_addr_dec.h delete mode 100644 plat/marvell/a3700/common/include/plat_macros.S delete mode 100644 plat/marvell/a3700/common/include/platform_def.h delete mode 100644 plat/marvell/a3700/common/io_addr_dec.c delete mode 100644 plat/marvell/a3700/common/marvell_plat_config.c delete mode 100644 plat/marvell/a3700/common/plat_pm.c delete mode 100644 plat/marvell/a8k/a70x0/board/dram_port.c delete mode 100644 plat/marvell/a8k/a70x0/board/marvell_plat_config.c delete mode 100644 plat/marvell/a8k/a70x0/mvebu_def.h delete mode 100644 plat/marvell/a8k/a70x0/platform.mk delete mode 100644 plat/marvell/a8k/a70x0_amc/board/dram_port.c delete mode 100644 plat/marvell/a8k/a70x0_amc/board/marvell_plat_config.c delete mode 100644 plat/marvell/a8k/a70x0_amc/mvebu_def.h delete mode 100644 plat/marvell/a8k/a70x0_amc/platform.mk delete mode 100644 plat/marvell/a8k/a80x0/board/dram_port.c delete mode 100644 plat/marvell/a8k/a80x0/board/marvell_plat_config.c delete mode 100644 plat/marvell/a8k/a80x0/board/phy-porting-layer.h delete mode 100644 plat/marvell/a8k/a80x0/mvebu_def.h delete mode 100644 plat/marvell/a8k/a80x0/platform.mk delete mode 100644 plat/marvell/a8k/a80x0_mcbin/board/dram_port.c delete mode 100644 plat/marvell/a8k/a80x0_mcbin/board/marvell_plat_config.c delete mode 100644 plat/marvell/a8k/a80x0_mcbin/mvebu_def.h delete mode 100644 plat/marvell/a8k/a80x0_mcbin/platform.mk delete mode 100644 plat/marvell/a8k/common/a8k_common.mk delete mode 100644 plat/marvell/a8k/common/aarch64/a8k_common.c delete mode 100644 plat/marvell/a8k/common/aarch64/plat_arch_config.c delete mode 100644 plat/marvell/a8k/common/aarch64/plat_helpers.S delete mode 100644 plat/marvell/a8k/common/ble/ble.ld.S delete mode 100644 plat/marvell/a8k/common/ble/ble.mk delete mode 100644 plat/marvell/a8k/common/ble/ble_main.c delete mode 100644 plat/marvell/a8k/common/ble/ble_mem.S delete mode 100644 plat/marvell/a8k/common/include/a8k_plat_def.h delete mode 100644 plat/marvell/a8k/common/include/ddr_info.h delete mode 100644 plat/marvell/a8k/common/include/mentor_i2c_plat.h delete mode 100644 plat/marvell/a8k/common/include/plat_macros.S delete mode 100644 plat/marvell/a8k/common/include/platform_def.h delete mode 100644 plat/marvell/a8k/common/mss/mss_a8k.mk delete mode 100644 plat/marvell/a8k/common/mss/mss_bl2_setup.c delete mode 100644 plat/marvell/a8k/common/mss/mss_pm_ipc.c delete mode 100644 plat/marvell/a8k/common/mss/mss_pm_ipc.h delete mode 100644 plat/marvell/a8k/common/plat_bl1_setup.c delete mode 100644 plat/marvell/a8k/common/plat_bl31_setup.c delete mode 100644 plat/marvell/a8k/common/plat_ble_setup.c delete mode 100644 plat/marvell/a8k/common/plat_pm.c delete mode 100644 plat/marvell/a8k/common/plat_pm_trace.c delete mode 100644 plat/marvell/a8k/common/plat_thermal.c create mode 100644 plat/marvell/armada/a3700/a3700/board/pm_src.c create mode 100644 plat/marvell/armada/a3700/a3700/mvebu_def.h create mode 100644 plat/marvell/armada/a3700/a3700/plat_bl31_setup.c create mode 100644 plat/marvell/armada/a3700/a3700/platform.mk create mode 100644 plat/marvell/armada/a3700/common/a3700_common.mk create mode 100644 plat/marvell/armada/a3700/common/a3700_ea.c create mode 100644 plat/marvell/armada/a3700/common/a3700_sip_svc.c create mode 100644 plat/marvell/armada/a3700/common/aarch64/a3700_common.c create mode 100644 plat/marvell/armada/a3700/common/aarch64/plat_helpers.S create mode 100644 plat/marvell/armada/a3700/common/dram_win.c create mode 100644 plat/marvell/armada/a3700/common/include/a3700_plat_def.h create mode 100644 plat/marvell/armada/a3700/common/include/a3700_pm.h create mode 100644 plat/marvell/armada/a3700/common/include/ddr_info.h create mode 100644 plat/marvell/armada/a3700/common/include/dram_win.h create mode 100644 plat/marvell/armada/a3700/common/include/io_addr_dec.h create mode 100644 plat/marvell/armada/a3700/common/include/plat_macros.S create mode 100644 plat/marvell/armada/a3700/common/include/platform_def.h create mode 100644 plat/marvell/armada/a3700/common/io_addr_dec.c create mode 100644 plat/marvell/armada/a3700/common/marvell_plat_config.c create mode 100644 plat/marvell/armada/a3700/common/plat_pm.c create mode 100644 plat/marvell/armada/a8k/a70x0/board/dram_port.c create mode 100644 plat/marvell/armada/a8k/a70x0/board/marvell_plat_config.c create mode 100644 plat/marvell/armada/a8k/a70x0/mvebu_def.h create mode 100644 plat/marvell/armada/a8k/a70x0/platform.mk create mode 100644 plat/marvell/armada/a8k/a70x0_amc/board/dram_port.c create mode 100644 plat/marvell/armada/a8k/a70x0_amc/board/marvell_plat_config.c create mode 100644 plat/marvell/armada/a8k/a70x0_amc/mvebu_def.h create mode 100644 plat/marvell/armada/a8k/a70x0_amc/platform.mk create mode 100644 plat/marvell/armada/a8k/a80x0/board/dram_port.c create mode 100644 plat/marvell/armada/a8k/a80x0/board/marvell_plat_config.c create mode 100644 plat/marvell/armada/a8k/a80x0/board/phy-porting-layer.h create mode 100644 plat/marvell/armada/a8k/a80x0/mvebu_def.h create mode 100644 plat/marvell/armada/a8k/a80x0/platform.mk create mode 100644 plat/marvell/armada/a8k/a80x0_mcbin/board/dram_port.c create mode 100644 plat/marvell/armada/a8k/a80x0_mcbin/board/marvell_plat_config.c create mode 100644 plat/marvell/armada/a8k/a80x0_mcbin/mvebu_def.h create mode 100644 plat/marvell/armada/a8k/a80x0_mcbin/platform.mk create mode 100644 plat/marvell/armada/a8k/common/a8k_common.mk create mode 100644 plat/marvell/armada/a8k/common/aarch64/a8k_common.c create mode 100644 plat/marvell/armada/a8k/common/aarch64/plat_arch_config.c create mode 100644 plat/marvell/armada/a8k/common/aarch64/plat_helpers.S create mode 100644 plat/marvell/armada/a8k/common/ble/ble.ld.S create mode 100644 plat/marvell/armada/a8k/common/ble/ble.mk create mode 100644 plat/marvell/armada/a8k/common/ble/ble_main.c create mode 100644 plat/marvell/armada/a8k/common/ble/ble_mem.S create mode 100644 plat/marvell/armada/a8k/common/include/a8k_plat_def.h create mode 100644 plat/marvell/armada/a8k/common/include/ddr_info.h create mode 100644 plat/marvell/armada/a8k/common/include/mentor_i2c_plat.h create mode 100644 plat/marvell/armada/a8k/common/include/plat_macros.S create mode 100644 plat/marvell/armada/a8k/common/include/platform_def.h create mode 100644 plat/marvell/armada/a8k/common/mss/mss_a8k.mk create mode 100644 plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c create mode 100644 plat/marvell/armada/a8k/common/mss/mss_pm_ipc.c create mode 100644 plat/marvell/armada/a8k/common/mss/mss_pm_ipc.h create mode 100644 plat/marvell/armada/a8k/common/plat_bl1_setup.c create mode 100644 plat/marvell/armada/a8k/common/plat_bl31_setup.c create mode 100644 plat/marvell/armada/a8k/common/plat_ble_setup.c create mode 100644 plat/marvell/armada/a8k/common/plat_pm.c create mode 100644 plat/marvell/armada/a8k/common/plat_pm_trace.c create mode 100644 plat/marvell/armada/a8k/common/plat_thermal.c create mode 100644 plat/marvell/armada/common/aarch64/marvell_bl2_mem_params_desc.c create mode 100644 plat/marvell/armada/common/aarch64/marvell_common.c create mode 100644 plat/marvell/armada/common/aarch64/marvell_helpers.S create mode 100644 plat/marvell/armada/common/marvell_bl1_setup.c create mode 100644 plat/marvell/armada/common/marvell_bl2_setup.c create mode 100644 plat/marvell/armada/common/marvell_bl31_setup.c create mode 100644 plat/marvell/armada/common/marvell_cci.c create mode 100644 plat/marvell/armada/common/marvell_common.mk create mode 100644 plat/marvell/armada/common/marvell_console.c create mode 100644 plat/marvell/armada/common/marvell_ddr_info.c create mode 100644 plat/marvell/armada/common/marvell_gicv2.c create mode 100644 plat/marvell/armada/common/marvell_gicv3.c create mode 100644 plat/marvell/armada/common/marvell_image_load.c create mode 100644 plat/marvell/armada/common/marvell_io_storage.c create mode 100644 plat/marvell/armada/common/marvell_pm.c create mode 100644 plat/marvell/armada/common/marvell_topology.c create mode 100644 plat/marvell/armada/common/mrvl_sip_svc.c create mode 100644 plat/marvell/armada/common/mss/mss_common.mk create mode 100644 plat/marvell/armada/common/mss/mss_ipc_drv.c create mode 100644 plat/marvell/armada/common/mss/mss_ipc_drv.h create mode 100644 plat/marvell/armada/common/mss/mss_mem.h create mode 100644 plat/marvell/armada/common/mss/mss_scp_bl2_format.h create mode 100644 plat/marvell/armada/common/mss/mss_scp_bootloader.c create mode 100644 plat/marvell/armada/common/mss/mss_scp_bootloader.h create mode 100644 plat/marvell/armada/common/plat_delay_timer.c delete mode 100644 plat/marvell/common/aarch64/marvell_bl2_mem_params_desc.c delete mode 100644 plat/marvell/common/aarch64/marvell_common.c delete mode 100644 plat/marvell/common/aarch64/marvell_helpers.S delete mode 100644 plat/marvell/common/marvell_bl1_setup.c delete mode 100644 plat/marvell/common/marvell_bl2_setup.c delete mode 100644 plat/marvell/common/marvell_bl31_setup.c delete mode 100644 plat/marvell/common/marvell_cci.c delete mode 100644 plat/marvell/common/marvell_common.mk delete mode 100644 plat/marvell/common/marvell_console.c delete mode 100644 plat/marvell/common/marvell_ddr_info.c delete mode 100644 plat/marvell/common/marvell_gicv2.c delete mode 100644 plat/marvell/common/marvell_gicv3.c delete mode 100644 plat/marvell/common/marvell_image_load.c delete mode 100644 plat/marvell/common/marvell_io_storage.c delete mode 100644 plat/marvell/common/marvell_pm.c delete mode 100644 plat/marvell/common/marvell_topology.c delete mode 100644 plat/marvell/common/mrvl_sip_svc.c delete mode 100644 plat/marvell/common/mss/mss_common.mk delete mode 100644 plat/marvell/common/mss/mss_ipc_drv.c delete mode 100644 plat/marvell/common/mss/mss_ipc_drv.h delete mode 100644 plat/marvell/common/mss/mss_mem.h delete mode 100644 plat/marvell/common/mss/mss_scp_bl2_format.h delete mode 100644 plat/marvell/common/mss/mss_scp_bootloader.c delete mode 100644 plat/marvell/common/mss/mss_scp_bootloader.h delete mode 100644 plat/marvell/common/plat_delay_timer.c diff --git a/docs/plat/marvell/armada/build.rst b/docs/plat/marvell/armada/build.rst new file mode 100644 index 000000000..1b60fc554 --- /dev/null +++ b/docs/plat/marvell/armada/build.rst @@ -0,0 +1,253 @@ +TF-A Build Instructions for Marvell Platforms +============================================= + +This section describes how to compile the Trusted Firmware-A (TF-A) project for Marvell's platforms. + +Build Instructions +------------------ +(1) Set the cross compiler + + .. code:: shell + + > export CROSS_COMPILE=/path/to/toolchain/aarch64-linux-gnu- + +(2) Set path for FIP images: + +Set U-Boot image path (relatively to TF-A root or absolute path) + + .. code:: shell + + > export BL33=path/to/u-boot.bin + +For example: if U-Boot project (and its images) is located at ``~/project/u-boot``, +BL33 should be ``~/project/u-boot/u-boot.bin`` + + .. note:: + + *u-boot.bin* should be used and not *u-boot-spl.bin* + +Set MSS/SCP image path (mandatory only for Armada80x0) + + .. code:: shell + + > export SCP_BL2=path/to/mrvl_scp_bl2*.img + +(3) Armada-37x0 build requires WTP tools installation. + +See below in the section "Tools and external components installation". +Install ARM 32-bit cross compiler, which is required for building WTMI image for CM3 + + .. code:: shell + + > sudo apt-get install gcc-arm-linux-gnueabi + +(4) Clean previous build residuals (if any) + + .. code:: shell + + > make distclean + +(5) Build TF-A + +There are several build options: + +- DEBUG + + Default is without debug information (=0). in order to enable it use ``DEBUG=1``. + Must be disabled when building UART recovery images due to current console driver + implementation that is not compatible with Xmodem protocol used for boot image download. + +- LOG_LEVEL + + Defines the level of logging which will be purged to the default output port. + + LOG_LEVEL_NONE 0 + LOG_LEVEL_ERROR 10 + LOG_LEVEL_NOTICE 20 + LOG_LEVEL_WARNING 30 + LOG_LEVEL_INFO 40 + LOG_LEVEL_VERBOSE 50 + +- USE_COHERENT_MEM + + This flag determines whether to include the coherent memory region in the + BL memory map or not. + +- LLC_ENABLE + + Flag defining the LLC (L3) cache state. The cache is enabled by default (``LLC_ENABLE=1``). + +- MARVELL_SECURE_BOOT + + Build trusted(=1)/non trusted(=0) image, default is non trusted. + +- BLE_PATH + + Points to BLE (Binary ROM extension) sources folder. Only required for A8K builds. + The parameter is optional, its default value is ``plat/marvell/armada/a8k/common/ble``. + +- MV_DDR_PATH + + For A7/8K, use this parameter to point to mv_ddr driver sources to allow BLE build. For A37x0, + it is used for ddr_tool build. + + Usage example: MV_DDR_PATH=path/to/mv_ddr + + The parameter is optional for A7/8K, when this parameter is not set, the mv_ddr + sources are expected to be located at: drivers/marvell/mv_ddr. However, the parameter + is necessary for A37x0. + + For the mv_ddr source location, check the section "Tools and external components installation" + +- DDR_TOPOLOGY + + For Armada37x0 only, the DDR topology map index/name, default is 0. + + Supported Options: + - DDR3 1CS (0): DB-88F3720-DDR3-Modular (512MB); EspressoBIN (512MB) + - DDR4 1CS (1): DB-88F3720-DDR4-Modular (512MB) + - DDR3 2CS (2): EspressoBIN V3-V5 (1GB) + - DDR4 2CS (3): DB-88F3720-DDR4-Modular (4GB) + - DDR3 1CS (4): DB-88F3720-DDR3-Modular (1GB) + - DDR4 1CS (5): EspressoBin V7 (1GB) + - DDR4 2CS (6): EspressoBin V7 (2GB) + - CUSTOMER (CUST): Customer board, DDR3 1CS 512MB + +- CLOCKSPRESET + + For Armada37x0 only, the clock tree configuration preset including CPU and DDR frequency, + default is CPU_800_DDR_800. + + - CPU_600_DDR_600 - CPU at 600 MHz, DDR at 600 MHz + - CPU_800_DDR_800 - CPU at 800 MHz, DDR at 800 MHz + - CPU_1000_DDR_800 - CPU at 1000 MHz, DDR at 800 MHz + - CPU_1200_DDR_750 - CPU at 1200 MHz, DDR at 750 MHz + +- BOOTDEV + + For Armada37x0 only, the flash boot device, default is ``SPINOR``. + + Currently, Armada37x0 only supports ``SPINOR``, ``SPINAND``, ``EMMCNORM`` and ``SATA``: + + - SPINOR - SPI NOR flash boot + - SPINAND - SPI NAND flash boot + - EMMCNORM - eMMC Download Mode + + Download boot loader or program code from eMMC flash into CM3 or CA53 + Requires full initialization and command sequence + + - SATA - SATA device boot + +- PARTNUM + + For Armada37x0 only, the boot partition number, default is 0. + + To boot from eMMC, the value should be aligned with the parameter in + U-Boot with name of ``CONFIG_SYS_MMC_ENV_PART``, whose value by default is + 1. For details about CONFIG_SYS_MMC_ENV_PART, please refer to the U-Boot + build instructions. + +- WTMI_IMG + + For Armada37x0 only, the path of the WTMI image can point to an image which + does nothing, an image which supports EFUSE or a customized CM3 firmware + binary. The default image is wtmi.bin that built from sources in WTP + folder, which is the next option. If the default image is OK, then this + option should be skipped. + +- WTP + + For Armada37x0 only, use this parameter to point to wtptools source code + directory, which can be found as a3700_utils.zip in the release. Usage + example: ``WTP=/path/to/a3700_utils`` + + For example, in order to build the image in debug mode with log level up to 'notice' level run + + .. code:: shell + + > make DEBUG=1 USE_COHERENT_MEM=0 LOG_LEVEL=20 PLAT= all fip + + And if we want to build a Armada37x0 image in debug mode with log level up to 'notice' level, + the image has the preset CPU at 1000 MHz, preset DDR3 at 800 MHz, the DDR topology of DDR4 2CS, + the image boot from SPI NOR flash partition 0, and the image is non trusted in WTP, the command + line is as following + + .. code:: shell + + > make DEBUG=1 USE_COHERENT_MEM=0 LOG_LEVEL=20 CLOCKSPRESET=CPU_1000_DDR_800 \ + MARVELL_SECURE_BOOT=0 DDR_TOPOLOGY=3 BOOTDEV=SPINOR PARTNUM=0 PLAT=a3700 all fip + + Supported MARVELL_PLATFORM are: + - a3700 (for both A3720 DB and EspressoBin) + - a70x0 + - a70x0_amc (for AMC board) + - a80x0 + - a80x0_mcbin (for MacciatoBin) + +Special Build Flags +-------------------- + +- PLAT_RECOVERY_IMAGE_ENABLE + When set this option to enable secondary recovery function when build atf. + In order to build UART recovery image this operation should be disabled for + a70x0 and a80x0 because of hardware limitation (boot from secondary image + can interrupt UART recovery process). This MACRO definition is set in + ``plat/marvell/armada/a8k/common/include/platform_def.h`` file. + +For more information about build options, please refer to the +:ref:`Build Options` document. + + +Build output +------------ +Marvell's TF-A compilation generates 7 files: + + - ble.bin - BLe image + - bl1.bin - BL1 image + - bl2.bin - BL2 image + - bl31.bin - BL31 image + - fip.bin - FIP image (contains BL2, BL31 & BL33 (U-Boot) images) + - boot-image.bin - TF-A image (contains BL1 and FIP images) + - flash-image.bin - Image which contains boot-image.bin and SPL image. + Should be placed on the boot flash/device. + + +Tools and external components installation +------------------------------------------ + +Armada37x0 Builds require installation of 3 components +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +(1) ARM cross compiler capable of building images for the service CPU (CM3). + This component is usually included in the Linux host packages. + On Debian/Ubuntu hosts the default GNU ARM tool chain can be installed + using the following command + + .. code:: shell + + > sudo apt-get install gcc-arm-linux-gnueabi + + Only if required, the default tool chain prefix ``arm-linux-gnueabi-`` can be + overwritten using the environment variable ``CROSS_CM3``. + Example for BASH shell + + .. code:: shell + + > export CROSS_CM3=/opt/arm-cross/bin/arm-linux-gnueabi + +(2) DDR initialization library sources (mv_ddr) available at the following repository + (use the "mv_ddr-armada-atf-mainline" branch): + + https://github.com/MarvellEmbeddedProcessors/mv-ddr-marvell.git + +(3) Armada3700 tools available at the following repository (use the latest release branch): + + https://github.com/MarvellEmbeddedProcessors/A3700-utils-marvell.git + +Armada70x0 and Armada80x0 Builds require installation of an additional component +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +(1) DDR initialization library sources (mv_ddr) available at the following repository + (use the "mv_ddr-armada-atf-mainline" branch): + + https://github.com/MarvellEmbeddedProcessors/mv-ddr-marvell.git diff --git a/docs/plat/marvell/armada/misc/mvebu-a8k-addr-map.rst b/docs/plat/marvell/armada/misc/mvebu-a8k-addr-map.rst new file mode 100644 index 000000000..e88a4582b --- /dev/null +++ b/docs/plat/marvell/armada/misc/mvebu-a8k-addr-map.rst @@ -0,0 +1,49 @@ +Address decoding flow and address translation units of Marvell Armada 8K SoC family +=================================================================================== + +:: + + +--------------------------------------------------------------------------------------------------+ + | +-------------+ +--------------+ | + | | Memory +----- DRAM CS | | + |+------------+ +-----------+ +-----------+ | Controller | +--------------+ | + || AP DMA | | | | | +-------------+ | + || SD/eMMC | | CA72 CPUs | | AP MSS | +-------------+ | + || MCI-0/1 | | | | | | Memory | | + |+------+-----+ +--+--------+ +--------+--+ +------------+ | Controller | +-------------+ | + | | | | | +----- Translaton | |AP | | + | | | | | | +-------------+ |Configuration| | + | | | +-----+ +-------------------------Space | | + | | | +-------------+ | CCU | +-------------+ | + | | | | MMU +---------+ Windows | +-----------+ +-------------+ | + | | +-| translation | | Lookup +---- +--------- AP SPI | | + | | +-------------+ | | | | +-------------+ | + | | +-------------+ | | | IO | +-------------+ | + | +------------| SMMU +---------+ | | Windows +--------- AP MCI0/1 | | + | | translation | +------------+ | Lookup | +-------------+ | + | +---------+---+ | | +-------------+ | + | - | | +--------- AP STM | | + | +----------------- | | +-------------+ | + | AP | | +-+---------+ | + +---------------------------------------------------------------|----------------------------------+ + +-------------|-------------------------------------------------|----------------------------------+ + | CP | +-------------+ +------+-----+ +-------------------+ | + | | | | | +------- SB CFG Space | | + | | | DIOB | | | +-------------------+ | + | | | Windows ----------------- IOB | +-------------------+ | + | | | Control | | Windows +------| SB PCIe-0 - PCIe2 | | + | | | | | Lookup | +-------------------+ | + | | +------+------+ | | +-------------------+ | + | | | | +------+ SB NAND | | + | | | +------+-----+ +-------------------+ | + | | | | | + | | | | | + | +------------------+ +------------+ +------+-----+ +-------------------+ | + | | Network Engine | | | | +------- SB SPI-0/SPI-1 | | + | | Security Engine | | PCIe, MSS | | RUNIT | +-------------------+ | + | | SATA, USB | | DMA | | Windows | +-------------------+ | + | | SD/eMMC | | | | Lookup +------- SB Device Bus | | + | | TDM, I2C | | | | | +-------------------+ | + | +------------------+ +------------+ +------------+ | + | | + +--------------------------------------------------------------------------------------------------+ diff --git a/docs/plat/marvell/armada/misc/mvebu-amb.rst b/docs/plat/marvell/armada/misc/mvebu-amb.rst new file mode 100644 index 000000000..d734003d6 --- /dev/null +++ b/docs/plat/marvell/armada/misc/mvebu-amb.rst @@ -0,0 +1,58 @@ +AMB - AXI MBUS address decoding +=============================== + +AXI to M-bridge decoding unit driver for Marvell Armada 8K and 8K+ SoCs. + +The Runit offers a second level of address windows lookup. It is used to map +transaction towards the CD BootROM, SPI0, SPI1 and Device bus (NOR). + +The Runit contains eight configurable windows. Each window defines a contiguous, +address space and the properties associated with that address space. + +:: + + Unit Bank ATTR + Device-Bus DEV_BOOT_CS 0x2F + DEV_CS0 0x3E + DEV_CS1 0x3D + DEV_CS2 0x3B + DEV_CS3 0x37 + SPI-0 SPI_A_CS0 0x1E + SPI_A_CS1 0x5E + SPI_A_CS2 0x9E + SPI_A_CS3 0xDE + SPI_A_CS4 0x1F + SPI_A_CS5 0x5F + SPI_A_CS6 0x9F + SPI_A_CS7 0xDF + SPI SPI_B_CS0 0x1A + SPI_B_CS1 0x5A + SPI_B_CS2 0x9A + SPI_B_CS3 0xDA + BOOT_ROM BOOT_ROM 0x1D + UART UART 0x01 + +Mandatory functions +------------------- + +- marvell_get_amb_memory_map + Returns the AMB windows configuration and the number of windows + +Mandatory structures +-------------------- + +- amb_memory_map + Array that include the configuration of the windows. Every window/entry is a + struct which has 2 parameters: + + - Base address of the window + - Attribute of the window + +Examples +-------- + +.. code:: c + + struct addr_map_win amb_memory_map[] = { + {0xf900, AMB_DEV_CS0_ID}, + }; diff --git a/docs/plat/marvell/armada/misc/mvebu-ccu.rst b/docs/plat/marvell/armada/misc/mvebu-ccu.rst new file mode 100644 index 000000000..5bac11faf --- /dev/null +++ b/docs/plat/marvell/armada/misc/mvebu-ccu.rst @@ -0,0 +1,33 @@ +Marvell CCU address decoding bindings +===================================== + +CCU configration driver (1st stage address translation) for Marvell Armada 8K and 8K+ SoCs. + +The CCU node includes a description of the address decoding configuration. + +Mandatory functions +------------------- + +- marvell_get_ccu_memory_map + Return the CCU windows configuration and the number of windows of the + specific AP. + +Mandatory structures +-------------------- + +- ccu_memory_map + Array that includes the configuration of the windows. Every window/entry is + a struct which has 3 parameters: + + - Base address of the window + - Size of the window + - Target-ID of the window + +Example +------- + +.. code:: c + + struct addr_map_win ccu_memory_map[] = { + {0x00000000f2000000, 0x00000000e000000, IO_0_TID}, /* IO window */ + }; diff --git a/docs/plat/marvell/armada/misc/mvebu-io-win.rst b/docs/plat/marvell/armada/misc/mvebu-io-win.rst new file mode 100644 index 000000000..52845ca02 --- /dev/null +++ b/docs/plat/marvell/armada/misc/mvebu-io-win.rst @@ -0,0 +1,46 @@ +Marvell IO WIN address decoding bindings +======================================== + +IO Window configration driver (2nd stage address translation) for Marvell Armada 8K and 8K+ SoCs. + +The IO WIN includes a description of the address decoding configuration. + +Transactions that are decoded by CCU windows as IO peripheral, have an additional +layer of decoding. This additional address decoding layer defines one of the +following targets: + +- **0x0** = BootRom +- **0x1** = STM (Serial Trace Macro-cell, a programmer's port into trace stream) +- **0x2** = SPI direct access +- **0x3** = PCIe registers +- **0x4** = MCI Port +- **0x5** = PCIe port + +Mandatory functions +------------------- + +- marvell_get_io_win_memory_map + Returns the IO windows configuration and the number of windows of the + specific AP. + +Mandatory structures +-------------------- + +- io_win_memory_map + Array that include the configuration of the windows. Every window/entry is + a struct which has 3 parameters: + + - Base address of the window + - Size of the window + - Target-ID of the window + +Example +------- + +.. code:: c + + struct addr_map_win io_win_memory_map[] = { + {0x00000000fe000000, 0x000000001f00000, PCIE_PORT_TID}, /* PCIe window 31Mb for PCIe port*/ + {0x00000000ffe00000, 0x000000000100000, PCIE_REGS_TID}, /* PCI-REG window 64Kb for PCIe-reg*/ + {0x00000000f6000000, 0x000000000100000, MCIPHY_TID}, /* MCI window 1Mb for PHY-reg*/ + }; diff --git a/docs/plat/marvell/armada/misc/mvebu-iob.rst b/docs/plat/marvell/armada/misc/mvebu-iob.rst new file mode 100644 index 000000000..d02a7e84c --- /dev/null +++ b/docs/plat/marvell/armada/misc/mvebu-iob.rst @@ -0,0 +1,52 @@ +Marvell IOB address decoding bindings +===================================== + +IO bridge configration driver (3rd stage address translation) for Marvell Armada 8K and 8K+ SoCs. + +The IOB includes a description of the address decoding configuration. + +IOB supports up to n (in CP110 n=24) windows for external memory transaction. +When a transaction passes through the IOB, its address is compared to each of +the enabled windows. If there is a hit and it passes the security checks, it is +advanced to the target port. + +Mandatory functions +------------------- + +- marvell_get_iob_memory_map + Returns the IOB windows configuration and the number of windows + +Mandatory structures +-------------------- + +- iob_memory_map + Array that includes the configuration of the windows. Every window/entry is + a struct which has 3 parameters: + + - Base address of the window + - Size of the window + - Target-ID of the window + +Target ID options +----------------- + +- **0x0** = Internal configuration space +- **0x1** = MCI0 +- **0x2** = PEX1_X1 +- **0x3** = PEX2_X1 +- **0x4** = PEX0_X4 +- **0x5** = NAND flash +- **0x6** = RUNIT (NOR/SPI/BootRoom) +- **0x7** = MCI1 + +Example +------- + +.. code:: c + + struct addr_map_win iob_memory_map[] = { + {0x00000000f7000000, 0x0000000001000000, PEX1_TID}, /* PEX1_X1 window */ + {0x00000000f8000000, 0x0000000001000000, PEX2_TID}, /* PEX2_X1 window */ + {0x00000000f6000000, 0x0000000001000000, PEX0_TID}, /* PEX0_X4 window */ + {0x00000000f9000000, 0x0000000001000000, NAND_TID} /* NAND window */ + }; diff --git a/docs/plat/marvell/armada/porting.rst b/docs/plat/marvell/armada/porting.rst new file mode 100644 index 000000000..1723ebb57 --- /dev/null +++ b/docs/plat/marvell/armada/porting.rst @@ -0,0 +1,163 @@ +TF-A Porting Guide for Marvell Platforms +======================================== + +This section describes how to port TF-A to a customer board, assuming that the +SoC being used is already supported in TF-A. + + +Source Code Structure +--------------------- + +- The customer platform specific code shall reside under ``plat/marvell/armada//_cust`` + (e.g. 'plat/marvell/armada/a8k/a7040_cust'). +- The platform name for build purposes is called ``_cust`` (e.g. ``a7040_cust``). +- The build system will reuse all files from within the soc directory, and take only the porting + files from the customer platform directory. + +Files that require porting are located at ``plat/marvell/armada//_cust`` directory. + + +Armada-70x0/Armada-80x0 Porting +------------------------------- + +SoC Physical Address Map (marvell_plat_config.c) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This file describes the SoC physical memory mapping to be used for the CCU, +IOWIN, AXI-MBUS and IOB address decode units (Refer to the functional spec for +more details). + +In most cases, using the default address decode windows should work OK. + +In cases where a special physical address map is needed (e.g. Special size for +PCIe MEM windows, large memory mapped SPI flash...), then porting of the SoC +memory map is required. + +.. note:: + For a detailed information on how CCU, IOWIN, AXI-MBUS & IOB work, please + refer to the SoC functional spec, and under + ``docs/marvell/misc/mvebu-[ccu/iob/amb/io-win].txt`` files. + +boot loader recovery (marvell_plat_config.c) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Background: + + Boot rom can skip the current image and choose to boot from next position if a + specific value (``0xDEADB002``) is returned by the ble main function. This + feature is used for boot loader recovery by booting from a valid flash-image + saved in next position on flash (e.g. address 2M in SPI flash). + + Supported options to implement the skip request are: + - GPIO + - I2C + - User defined + +- Porting: + + Under marvell_plat_config.c, implement struct skip_image that includes + specific board parameters. + + .. warning:: + To disable this feature make sure the struct skip_image is not implemented. + +- Example: + +In A7040-DB specific implementation +(``plat/marvell/armada/a8k/a70x0/board/marvell_plat_config.c``), the image skip is +implemented using GPIO: mpp 33 (SW5). + +Before resetting the board make sure there is a valid image on the next flash +address: + + -tftp [valid address] flash-image.bin + -sf update [valid address] 0x2000000 [size] + +Press reset and keep pressing the button connected to the chosen GPIO pin. A +skip image request message is printed on the screen and boot rom boots from the +saved image at the next position. + +DDR Porting (dram_port.c) +~~~~~~~~~~~~~~~~~~~~~~~~~ + +This file defines the dram topology and parameters of the target board. + +The DDR code is part of the BLE component, which is an extension of ARM Trusted +Firmware (TF-A). + +The DDR driver called mv_ddr is released separately apart from TF-A sources. + +The BLE and consequently, the DDR init code is executed at the early stage of +the boot process. + +Each supported platform of the TF-A has its own DDR porting file called +dram_port.c located at ``atf/plat/marvell/armada/a8k//board`` directory. + +Please refer to '/doc/porting_guide.txt' for detailed +porting description. + +The build target directory is "build//release/ble". + +Comphy Porting (phy-porting-layer.h or phy-default-porting-layer.h) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Background: + Some of the comphy's parameters value depend on the HW connection between + the SoC and the PHY. Every board type has specific HW characteristics like + wire length. Due to those differences some comphy parameters vary between + board types. Therefore each board type can have its own list of values for + all relevant comphy parameters. The PHY porting layer specifies which + parameters need to be suited and the board designer should provide relevant + values. + + .. seealso:: + For XFI/SFI comphy type there is procedure "rx_training" which eases + process of suiting some of the parameters. Please see *uboot_cmd* + section: rx_training. + + The PHY porting layer simplifies updating static values per board type, + which are now grouped in one place. + + .. note:: + The parameters for the same type of comphy may vary even for the same + board type, it is because the lanes from comphy-x to some PHY may have + different HW characteristic than lanes from comphy-y to the same + (multiplexed) or other PHY. + +- Porting: + The porting layer for PHY was introduced in TF-A. There is one file + ``drivers/marvell/comphy/phy-default-porting-layer.h`` which contains the + defaults. Those default parameters are used only if there is no appropriate + phy-porting-layer.h file under: ``plat/marvell/armada///board/phy-porting-layer.h``. If the phy-porting-layer.h + exists, the phy-default-porting-layer.h is not going to be included. + + .. warning:: + Not all comphy types are already reworked to support the PHY porting + layer, currently the porting layer is supported for XFI/SFI and SATA + comphy types. + + The easiest way to prepare the PHY porting layer for custom board is to copy + existing example to a new platform: + + - cp ``plat/marvell/armada/a8k/a80x0/board/phy-porting-layer.h`` "plat/marvell/armada///board/phy-porting-layer.h" + - adjust relevant parameters or + - if different comphy index is used for specific feature, move it to proper table entry and then adjust. + + .. note:: + The final table size with comphy parameters can be different, depending + on the CP module count for given SoC type. + +- Example: + Example porting layer for armada-8040-db is under: + ``plat/marvell/armada/a8k/a80x0/board/phy-porting-layer.h`` + + .. note:: + If there is no PHY porting layer for new platform (missing + phy-porting-layer.h), the default values are used + (drivers/marvell/comphy/phy-default-porting-layer.h) and the user is + warned: + + .. warning:: + "Using default comphy parameters - it may be required to suit them for + your board". diff --git a/docs/plat/marvell/build.rst b/docs/plat/marvell/build.rst deleted file mode 100644 index c10bcff79..000000000 --- a/docs/plat/marvell/build.rst +++ /dev/null @@ -1,253 +0,0 @@ -TF-A Build Instructions for Marvell Platforms -============================================= - -This section describes how to compile the Trusted Firmware-A (TF-A) project for Marvell's platforms. - -Build Instructions ------------------- -(1) Set the cross compiler - - .. code:: shell - - > export CROSS_COMPILE=/path/to/toolchain/aarch64-linux-gnu- - -(2) Set path for FIP images: - -Set U-Boot image path (relatively to TF-A root or absolute path) - - .. code:: shell - - > export BL33=path/to/u-boot.bin - -For example: if U-Boot project (and its images) is located at ``~/project/u-boot``, -BL33 should be ``~/project/u-boot/u-boot.bin`` - - .. note:: - - *u-boot.bin* should be used and not *u-boot-spl.bin* - -Set MSS/SCP image path (mandatory only for Armada80x0) - - .. code:: shell - - > export SCP_BL2=path/to/mrvl_scp_bl2*.img - -(3) Armada-37x0 build requires WTP tools installation. - -See below in the section "Tools and external components installation". -Install ARM 32-bit cross compiler, which is required for building WTMI image for CM3 - - .. code:: shell - - > sudo apt-get install gcc-arm-linux-gnueabi - -(4) Clean previous build residuals (if any) - - .. code:: shell - - > make distclean - -(5) Build TF-A - -There are several build options: - -- DEBUG - - Default is without debug information (=0). in order to enable it use ``DEBUG=1``. - Must be disabled when building UART recovery images due to current console driver - implementation that is not compatible with Xmodem protocol used for boot image download. - -- LOG_LEVEL - - Defines the level of logging which will be purged to the default output port. - - LOG_LEVEL_NONE 0 - LOG_LEVEL_ERROR 10 - LOG_LEVEL_NOTICE 20 - LOG_LEVEL_WARNING 30 - LOG_LEVEL_INFO 40 - LOG_LEVEL_VERBOSE 50 - -- USE_COHERENT_MEM - - This flag determines whether to include the coherent memory region in the - BL memory map or not. - -- LLC_ENABLE - - Flag defining the LLC (L3) cache state. The cache is enabled by default (``LLC_ENABLE=1``). - -- MARVELL_SECURE_BOOT - - Build trusted(=1)/non trusted(=0) image, default is non trusted. - -- BLE_PATH - - Points to BLE (Binary ROM extension) sources folder. Only required for A8K builds. - The parameter is optional, its default value is ``plat/marvell/a8k/common/ble``. - -- MV_DDR_PATH - - For A7/8K, use this parameter to point to mv_ddr driver sources to allow BLE build. For A37x0, - it is used for ddr_tool build. - - Usage example: MV_DDR_PATH=path/to/mv_ddr - - The parameter is optional for A7/8K, when this parameter is not set, the mv_ddr - sources are expected to be located at: drivers/marvell/mv_ddr. However, the parameter - is necessary for A37x0. - - For the mv_ddr source location, check the section "Tools and external components installation" - -- DDR_TOPOLOGY - - For Armada37x0 only, the DDR topology map index/name, default is 0. - - Supported Options: - - DDR3 1CS (0): DB-88F3720-DDR3-Modular (512MB); EspressoBIN (512MB) - - DDR4 1CS (1): DB-88F3720-DDR4-Modular (512MB) - - DDR3 2CS (2): EspressoBIN V3-V5 (1GB) - - DDR4 2CS (3): DB-88F3720-DDR4-Modular (4GB) - - DDR3 1CS (4): DB-88F3720-DDR3-Modular (1GB) - - DDR4 1CS (5): EspressoBin V7 (1GB) - - DDR4 2CS (6): EspressoBin V7 (2GB) - - CUSTOMER (CUST): Customer board, DDR3 1CS 512MB - -- CLOCKSPRESET - - For Armada37x0 only, the clock tree configuration preset including CPU and DDR frequency, - default is CPU_800_DDR_800. - - - CPU_600_DDR_600 - CPU at 600 MHz, DDR at 600 MHz - - CPU_800_DDR_800 - CPU at 800 MHz, DDR at 800 MHz - - CPU_1000_DDR_800 - CPU at 1000 MHz, DDR at 800 MHz - - CPU_1200_DDR_750 - CPU at 1200 MHz, DDR at 750 MHz - -- BOOTDEV - - For Armada37x0 only, the flash boot device, default is ``SPINOR``. - - Currently, Armada37x0 only supports ``SPINOR``, ``SPINAND``, ``EMMCNORM`` and ``SATA``: - - - SPINOR - SPI NOR flash boot - - SPINAND - SPI NAND flash boot - - EMMCNORM - eMMC Download Mode - - Download boot loader or program code from eMMC flash into CM3 or CA53 - Requires full initialization and command sequence - - - SATA - SATA device boot - -- PARTNUM - - For Armada37x0 only, the boot partition number, default is 0. - - To boot from eMMC, the value should be aligned with the parameter in - U-Boot with name of ``CONFIG_SYS_MMC_ENV_PART``, whose value by default is - 1. For details about CONFIG_SYS_MMC_ENV_PART, please refer to the U-Boot - build instructions. - -- WTMI_IMG - - For Armada37x0 only, the path of the WTMI image can point to an image which - does nothing, an image which supports EFUSE or a customized CM3 firmware - binary. The default image is wtmi.bin that built from sources in WTP - folder, which is the next option. If the default image is OK, then this - option should be skipped. - -- WTP - - For Armada37x0 only, use this parameter to point to wtptools source code - directory, which can be found as a3700_utils.zip in the release. Usage - example: ``WTP=/path/to/a3700_utils`` - - For example, in order to build the image in debug mode with log level up to 'notice' level run - - .. code:: shell - - > make DEBUG=1 USE_COHERENT_MEM=0 LOG_LEVEL=20 PLAT= all fip - - And if we want to build a Armada37x0 image in debug mode with log level up to 'notice' level, - the image has the preset CPU at 1000 MHz, preset DDR3 at 800 MHz, the DDR topology of DDR4 2CS, - the image boot from SPI NOR flash partition 0, and the image is non trusted in WTP, the command - line is as following - - .. code:: shell - - > make DEBUG=1 USE_COHERENT_MEM=0 LOG_LEVEL=20 CLOCKSPRESET=CPU_1000_DDR_800 \ - MARVELL_SECURE_BOOT=0 DDR_TOPOLOGY=3 BOOTDEV=SPINOR PARTNUM=0 PLAT=a3700 all fip - - Supported MARVELL_PLATFORM are: - - a3700 (for both A3720 DB and EspressoBin) - - a70x0 - - a70x0_amc (for AMC board) - - a80x0 - - a80x0_mcbin (for MacciatoBin) - -Special Build Flags --------------------- - -- PLAT_RECOVERY_IMAGE_ENABLE - When set this option to enable secondary recovery function when build atf. - In order to build UART recovery image this operation should be disabled for - a70x0 and a80x0 because of hardware limitation (boot from secondary image - can interrupt UART recovery process). This MACRO definition is set in - ``plat/marvell/a8k/common/include/platform_def.h`` file. - -For more information about build options, please refer to the -:ref:`Build Options` document. - - -Build output ------------- -Marvell's TF-A compilation generates 7 files: - - - ble.bin - BLe image - - bl1.bin - BL1 image - - bl2.bin - BL2 image - - bl31.bin - BL31 image - - fip.bin - FIP image (contains BL2, BL31 & BL33 (U-Boot) images) - - boot-image.bin - TF-A image (contains BL1 and FIP images) - - flash-image.bin - Image which contains boot-image.bin and SPL image. - Should be placed on the boot flash/device. - - -Tools and external components installation ------------------------------------------- - -Armada37x0 Builds require installation of 3 components -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -(1) ARM cross compiler capable of building images for the service CPU (CM3). - This component is usually included in the Linux host packages. - On Debian/Ubuntu hosts the default GNU ARM tool chain can be installed - using the following command - - .. code:: shell - - > sudo apt-get install gcc-arm-linux-gnueabi - - Only if required, the default tool chain prefix ``arm-linux-gnueabi-`` can be - overwritten using the environment variable ``CROSS_CM3``. - Example for BASH shell - - .. code:: shell - - > export CROSS_CM3=/opt/arm-cross/bin/arm-linux-gnueabi - -(2) DDR initialization library sources (mv_ddr) available at the following repository - (use the "mv_ddr-armada-atf-mainline" branch): - - https://github.com/MarvellEmbeddedProcessors/mv-ddr-marvell.git - -(3) Armada3700 tools available at the following repository (use the latest release branch): - - https://github.com/MarvellEmbeddedProcessors/A3700-utils-marvell.git - -Armada70x0 and Armada80x0 Builds require installation of an additional component -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -(1) DDR initialization library sources (mv_ddr) available at the following repository - (use the "mv_ddr-armada-atf-mainline" branch): - - https://github.com/MarvellEmbeddedProcessors/mv-ddr-marvell.git diff --git a/docs/plat/marvell/index.rst b/docs/plat/marvell/index.rst index 89ebdc0a4..0d33432ba 100644 --- a/docs/plat/marvell/index.rst +++ b/docs/plat/marvell/index.rst @@ -5,10 +5,10 @@ Marvell :maxdepth: 1 :caption: Contents - build - porting - misc/mvebu-a8k-addr-map - misc/mvebu-amb - misc/mvebu-ccu - misc/mvebu-io-win - misc/mvebu-iob + armada/build + armada/porting + armada/misc/mvebu-a8k-addr-map + armada/misc/mvebu-amb + armada/misc/mvebu-ccu + armada/misc/mvebu-io-win + armada/misc/mvebu-iob diff --git a/docs/plat/marvell/misc/mvebu-a8k-addr-map.rst b/docs/plat/marvell/misc/mvebu-a8k-addr-map.rst deleted file mode 100644 index e88a4582b..000000000 --- a/docs/plat/marvell/misc/mvebu-a8k-addr-map.rst +++ /dev/null @@ -1,49 +0,0 @@ -Address decoding flow and address translation units of Marvell Armada 8K SoC family -=================================================================================== - -:: - - +--------------------------------------------------------------------------------------------------+ - | +-------------+ +--------------+ | - | | Memory +----- DRAM CS | | - |+------------+ +-----------+ +-----------+ | Controller | +--------------+ | - || AP DMA | | | | | +-------------+ | - || SD/eMMC | | CA72 CPUs | | AP MSS | +-------------+ | - || MCI-0/1 | | | | | | Memory | | - |+------+-----+ +--+--------+ +--------+--+ +------------+ | Controller | +-------------+ | - | | | | | +----- Translaton | |AP | | - | | | | | | +-------------+ |Configuration| | - | | | +-----+ +-------------------------Space | | - | | | +-------------+ | CCU | +-------------+ | - | | | | MMU +---------+ Windows | +-----------+ +-------------+ | - | | +-| translation | | Lookup +---- +--------- AP SPI | | - | | +-------------+ | | | | +-------------+ | - | | +-------------+ | | | IO | +-------------+ | - | +------------| SMMU +---------+ | | Windows +--------- AP MCI0/1 | | - | | translation | +------------+ | Lookup | +-------------+ | - | +---------+---+ | | +-------------+ | - | - | | +--------- AP STM | | - | +----------------- | | +-------------+ | - | AP | | +-+---------+ | - +---------------------------------------------------------------|----------------------------------+ - +-------------|-------------------------------------------------|----------------------------------+ - | CP | +-------------+ +------+-----+ +-------------------+ | - | | | | | +------- SB CFG Space | | - | | | DIOB | | | +-------------------+ | - | | | Windows ----------------- IOB | +-------------------+ | - | | | Control | | Windows +------| SB PCIe-0 - PCIe2 | | - | | | | | Lookup | +-------------------+ | - | | +------+------+ | | +-------------------+ | - | | | | +------+ SB NAND | | - | | | +------+-----+ +-------------------+ | - | | | | | - | | | | | - | +------------------+ +------------+ +------+-----+ +-------------------+ | - | | Network Engine | | | | +------- SB SPI-0/SPI-1 | | - | | Security Engine | | PCIe, MSS | | RUNIT | +-------------------+ | - | | SATA, USB | | DMA | | Windows | +-------------------+ | - | | SD/eMMC | | | | Lookup +------- SB Device Bus | | - | | TDM, I2C | | | | | +-------------------+ | - | +------------------+ +------------+ +------------+ | - | | - +--------------------------------------------------------------------------------------------------+ diff --git a/docs/plat/marvell/misc/mvebu-amb.rst b/docs/plat/marvell/misc/mvebu-amb.rst deleted file mode 100644 index d734003d6..000000000 --- a/docs/plat/marvell/misc/mvebu-amb.rst +++ /dev/null @@ -1,58 +0,0 @@ -AMB - AXI MBUS address decoding -=============================== - -AXI to M-bridge decoding unit driver for Marvell Armada 8K and 8K+ SoCs. - -The Runit offers a second level of address windows lookup. It is used to map -transaction towards the CD BootROM, SPI0, SPI1 and Device bus (NOR). - -The Runit contains eight configurable windows. Each window defines a contiguous, -address space and the properties associated with that address space. - -:: - - Unit Bank ATTR - Device-Bus DEV_BOOT_CS 0x2F - DEV_CS0 0x3E - DEV_CS1 0x3D - DEV_CS2 0x3B - DEV_CS3 0x37 - SPI-0 SPI_A_CS0 0x1E - SPI_A_CS1 0x5E - SPI_A_CS2 0x9E - SPI_A_CS3 0xDE - SPI_A_CS4 0x1F - SPI_A_CS5 0x5F - SPI_A_CS6 0x9F - SPI_A_CS7 0xDF - SPI SPI_B_CS0 0x1A - SPI_B_CS1 0x5A - SPI_B_CS2 0x9A - SPI_B_CS3 0xDA - BOOT_ROM BOOT_ROM 0x1D - UART UART 0x01 - -Mandatory functions -------------------- - -- marvell_get_amb_memory_map - Returns the AMB windows configuration and the number of windows - -Mandatory structures --------------------- - -- amb_memory_map - Array that include the configuration of the windows. Every window/entry is a - struct which has 2 parameters: - - - Base address of the window - - Attribute of the window - -Examples --------- - -.. code:: c - - struct addr_map_win amb_memory_map[] = { - {0xf900, AMB_DEV_CS0_ID}, - }; diff --git a/docs/plat/marvell/misc/mvebu-ccu.rst b/docs/plat/marvell/misc/mvebu-ccu.rst deleted file mode 100644 index 5bac11faf..000000000 --- a/docs/plat/marvell/misc/mvebu-ccu.rst +++ /dev/null @@ -1,33 +0,0 @@ -Marvell CCU address decoding bindings -===================================== - -CCU configration driver (1st stage address translation) for Marvell Armada 8K and 8K+ SoCs. - -The CCU node includes a description of the address decoding configuration. - -Mandatory functions -------------------- - -- marvell_get_ccu_memory_map - Return the CCU windows configuration and the number of windows of the - specific AP. - -Mandatory structures --------------------- - -- ccu_memory_map - Array that includes the configuration of the windows. Every window/entry is - a struct which has 3 parameters: - - - Base address of the window - - Size of the window - - Target-ID of the window - -Example -------- - -.. code:: c - - struct addr_map_win ccu_memory_map[] = { - {0x00000000f2000000, 0x00000000e000000, IO_0_TID}, /* IO window */ - }; diff --git a/docs/plat/marvell/misc/mvebu-io-win.rst b/docs/plat/marvell/misc/mvebu-io-win.rst deleted file mode 100644 index 52845ca02..000000000 --- a/docs/plat/marvell/misc/mvebu-io-win.rst +++ /dev/null @@ -1,46 +0,0 @@ -Marvell IO WIN address decoding bindings -======================================== - -IO Window configration driver (2nd stage address translation) for Marvell Armada 8K and 8K+ SoCs. - -The IO WIN includes a description of the address decoding configuration. - -Transactions that are decoded by CCU windows as IO peripheral, have an additional -layer of decoding. This additional address decoding layer defines one of the -following targets: - -- **0x0** = BootRom -- **0x1** = STM (Serial Trace Macro-cell, a programmer's port into trace stream) -- **0x2** = SPI direct access -- **0x3** = PCIe registers -- **0x4** = MCI Port -- **0x5** = PCIe port - -Mandatory functions -------------------- - -- marvell_get_io_win_memory_map - Returns the IO windows configuration and the number of windows of the - specific AP. - -Mandatory structures --------------------- - -- io_win_memory_map - Array that include the configuration of the windows. Every window/entry is - a struct which has 3 parameters: - - - Base address of the window - - Size of the window - - Target-ID of the window - -Example -------- - -.. code:: c - - struct addr_map_win io_win_memory_map[] = { - {0x00000000fe000000, 0x000000001f00000, PCIE_PORT_TID}, /* PCIe window 31Mb for PCIe port*/ - {0x00000000ffe00000, 0x000000000100000, PCIE_REGS_TID}, /* PCI-REG window 64Kb for PCIe-reg*/ - {0x00000000f6000000, 0x000000000100000, MCIPHY_TID}, /* MCI window 1Mb for PHY-reg*/ - }; diff --git a/docs/plat/marvell/misc/mvebu-iob.rst b/docs/plat/marvell/misc/mvebu-iob.rst deleted file mode 100644 index d02a7e84c..000000000 --- a/docs/plat/marvell/misc/mvebu-iob.rst +++ /dev/null @@ -1,52 +0,0 @@ -Marvell IOB address decoding bindings -===================================== - -IO bridge configration driver (3rd stage address translation) for Marvell Armada 8K and 8K+ SoCs. - -The IOB includes a description of the address decoding configuration. - -IOB supports up to n (in CP110 n=24) windows for external memory transaction. -When a transaction passes through the IOB, its address is compared to each of -the enabled windows. If there is a hit and it passes the security checks, it is -advanced to the target port. - -Mandatory functions -------------------- - -- marvell_get_iob_memory_map - Returns the IOB windows configuration and the number of windows - -Mandatory structures --------------------- - -- iob_memory_map - Array that includes the configuration of the windows. Every window/entry is - a struct which has 3 parameters: - - - Base address of the window - - Size of the window - - Target-ID of the window - -Target ID options ------------------ - -- **0x0** = Internal configuration space -- **0x1** = MCI0 -- **0x2** = PEX1_X1 -- **0x3** = PEX2_X1 -- **0x4** = PEX0_X4 -- **0x5** = NAND flash -- **0x6** = RUNIT (NOR/SPI/BootRoom) -- **0x7** = MCI1 - -Example -------- - -.. code:: c - - struct addr_map_win iob_memory_map[] = { - {0x00000000f7000000, 0x0000000001000000, PEX1_TID}, /* PEX1_X1 window */ - {0x00000000f8000000, 0x0000000001000000, PEX2_TID}, /* PEX2_X1 window */ - {0x00000000f6000000, 0x0000000001000000, PEX0_TID}, /* PEX0_X4 window */ - {0x00000000f9000000, 0x0000000001000000, NAND_TID} /* NAND window */ - }; diff --git a/docs/plat/marvell/porting.rst b/docs/plat/marvell/porting.rst deleted file mode 100644 index 0a71dbd54..000000000 --- a/docs/plat/marvell/porting.rst +++ /dev/null @@ -1,163 +0,0 @@ -TF-A Porting Guide for Marvell Platforms -======================================== - -This section describes how to port TF-A to a customer board, assuming that the -SoC being used is already supported in TF-A. - - -Source Code Structure ---------------------- - -- The customer platform specific code shall reside under ``plat/marvell//_cust`` - (e.g. 'plat/marvell/a8k/a7040_cust'). -- The platform name for build purposes is called ``_cust`` (e.g. ``a7040_cust``). -- The build system will reuse all files from within the soc directory, and take only the porting - files from the customer platform directory. - -Files that require porting are located at ``plat/marvell//_cust`` directory. - - -Armada-70x0/Armada-80x0 Porting -------------------------------- - -SoC Physical Address Map (marvell_plat_config.c) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -This file describes the SoC physical memory mapping to be used for the CCU, -IOWIN, AXI-MBUS and IOB address decode units (Refer to the functional spec for -more details). - -In most cases, using the default address decode windows should work OK. - -In cases where a special physical address map is needed (e.g. Special size for -PCIe MEM windows, large memory mapped SPI flash...), then porting of the SoC -memory map is required. - -.. note:: - For a detailed information on how CCU, IOWIN, AXI-MBUS & IOB work, please - refer to the SoC functional spec, and under - ``docs/marvell/misc/mvebu-[ccu/iob/amb/io-win].txt`` files. - -boot loader recovery (marvell_plat_config.c) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- Background: - - Boot rom can skip the current image and choose to boot from next position if a - specific value (``0xDEADB002``) is returned by the ble main function. This - feature is used for boot loader recovery by booting from a valid flash-image - saved in next position on flash (e.g. address 2M in SPI flash). - - Supported options to implement the skip request are: - - GPIO - - I2C - - User defined - -- Porting: - - Under marvell_plat_config.c, implement struct skip_image that includes - specific board parameters. - - .. warning:: - To disable this feature make sure the struct skip_image is not implemented. - -- Example: - -In A7040-DB specific implementation -(``plat/marvell/a8k/a70x0/board/marvell_plat_config.c``), the image skip is -implemented using GPIO: mpp 33 (SW5). - -Before resetting the board make sure there is a valid image on the next flash -address: - - -tftp [valid address] flash-image.bin - -sf update [valid address] 0x2000000 [size] - -Press reset and keep pressing the button connected to the chosen GPIO pin. A -skip image request message is printed on the screen and boot rom boots from the -saved image at the next position. - -DDR Porting (dram_port.c) -~~~~~~~~~~~~~~~~~~~~~~~~~ - -This file defines the dram topology and parameters of the target board. - -The DDR code is part of the BLE component, which is an extension of ARM Trusted -Firmware (TF-A). - -The DDR driver called mv_ddr is released separately apart from TF-A sources. - -The BLE and consequently, the DDR init code is executed at the early stage of -the boot process. - -Each supported platform of the TF-A has its own DDR porting file called -dram_port.c located at ``atf/plat/marvell/a8k//board`` directory. - -Please refer to '/doc/porting_guide.txt' for detailed -porting description. - -The build target directory is "build//release/ble". - -Comphy Porting (phy-porting-layer.h or phy-default-porting-layer.h) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- Background: - Some of the comphy's parameters value depend on the HW connection between - the SoC and the PHY. Every board type has specific HW characteristics like - wire length. Due to those differences some comphy parameters vary between - board types. Therefore each board type can have its own list of values for - all relevant comphy parameters. The PHY porting layer specifies which - parameters need to be suited and the board designer should provide relevant - values. - - .. seealso:: - For XFI/SFI comphy type there is procedure "rx_training" which eases - process of suiting some of the parameters. Please see *uboot_cmd* - section: rx_training. - - The PHY porting layer simplifies updating static values per board type, - which are now grouped in one place. - - .. note:: - The parameters for the same type of comphy may vary even for the same - board type, it is because the lanes from comphy-x to some PHY may have - different HW characteristic than lanes from comphy-y to the same - (multiplexed) or other PHY. - -- Porting: - The porting layer for PHY was introduced in TF-A. There is one file - ``drivers/marvell/comphy/phy-default-porting-layer.h`` which contains the - defaults. Those default parameters are used only if there is no appropriate - phy-porting-layer.h file under: ``plat/marvell///board/phy-porting-layer.h``. If the phy-porting-layer.h - exists, the phy-default-porting-layer.h is not going to be included. - - .. warning:: - Not all comphy types are already reworked to support the PHY porting - layer, currently the porting layer is supported for XFI/SFI and SATA - comphy types. - - The easiest way to prepare the PHY porting layer for custom board is to copy - existing example to a new platform: - - - cp ``plat/marvell/a8k/a80x0/board/phy-porting-layer.h`` "plat/marvell///board/phy-porting-layer.h" - - adjust relevant parameters or - - if different comphy index is used for specific feature, move it to proper table entry and then adjust. - - .. note:: - The final table size with comphy parameters can be different, depending - on the CP module count for given SoC type. - -- Example: - Example porting layer for armada-8040-db is under: - ``plat/marvell/a8k/a80x0/board/phy-porting-layer.h`` - - .. note:: - If there is no PHY porting layer for new platform (missing - phy-porting-layer.h), the default values are used - (drivers/marvell/comphy/phy-default-porting-layer.h) and the user is - warned: - - .. warning:: - "Using default comphy parameters - it may be required to suit them for - your board". diff --git a/drivers/marvell/comphy/phy-comphy-cp110.c b/drivers/marvell/comphy/phy-comphy-cp110.c index 384dd39f2..b68208629 100644 --- a/drivers/marvell/comphy/phy-comphy-cp110.c +++ b/drivers/marvell/comphy/phy-comphy-cp110.c @@ -2236,7 +2236,7 @@ int mvebu_cp110_comphy_xfi_rx_training(uint64_t comphy_base, printf("########################################################\n"); printf("# To use trained values update the ATF sources:\n"); - printf("# plat/marvell/a8k//board/phy-porting-layer.h "); + printf("# plat/marvell/armada/a8k//board/phy-porting-layer.h "); printf("file\n# with new values as below (for appropriate AP nr %d", ap_nr); printf("and CP nr: %d comphy_index %d\n\n", diff --git a/drivers/marvell/comphy/phy-comphy-cp110.h b/drivers/marvell/comphy/phy-comphy-cp110.h index 407909bf7..63aef1200 100644 --- a/drivers/marvell/comphy/phy-comphy-cp110.h +++ b/drivers/marvell/comphy/phy-comphy-cp110.h @@ -7,7 +7,7 @@ /* Those are parameters for xfi mode, which need to be tune for each board type. * For known DB boards the parameters was already calibrated and placed under - * the plat/marvell/a8k//board/phy-porting-layer.h + * the plat/marvell/armada/a8k//board/phy-porting-layer.h */ struct xfi_params { uint8_t g1_ffe_res_sel; diff --git a/include/plat/marvell/a3700/common/armada_common.h b/include/plat/marvell/a3700/common/armada_common.h deleted file mode 100644 index c6953fb71..000000000 --- a/include/plat/marvell/a3700/common/armada_common.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef ARMADA_COMMON_H -#define ARMADA_COMMON_H - -#include - -#include - -int marvell_get_io_dec_win_conf(struct dec_win_config **win, uint32_t *size); - -#endif /* ARMADA_COMMON_H */ diff --git a/include/plat/marvell/a3700/common/board_marvell_def.h b/include/plat/marvell/a3700/common/board_marvell_def.h deleted file mode 100644 index 178259662..000000000 --- a/include/plat/marvell/a3700/common/board_marvell_def.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef BOARD_MARVELL_DEF_H -#define BOARD_MARVELL_DEF_H - -/* - * Required platform porting definitions common to all ARM - * development platforms - */ - -/* Size of cacheable stacks */ -#if IMAGE_BL1 -#if TRUSTED_BOARD_BOOT -# define PLATFORM_STACK_SIZE 0x1000 -#else -# define PLATFORM_STACK_SIZE 0x440 -#endif -#elif IMAGE_BL2 -# if TRUSTED_BOARD_BOOT -# define PLATFORM_STACK_SIZE 0x1000 -# else -# define PLATFORM_STACK_SIZE 0x400 -# endif -#elif IMAGE_BL31 -# define PLATFORM_STACK_SIZE 0x400 -#elif IMAGE_BL32 -# define PLATFORM_STACK_SIZE 0x440 -#endif - -/* - * PLAT_MARVELL_MMAP_ENTRIES depends on the number of entries in the - * plat_arm_mmap array defined for each BL stage. - */ -#if IMAGE_BLE -# define PLAT_MARVELL_MMAP_ENTRIES 3 -#endif -#if IMAGE_BL1 -# if TRUSTED_BOARD_BOOT -# define PLAT_MARVELL_MMAP_ENTRIES 7 -# else -# define PLAT_MARVELL_MMAP_ENTRIES 6 -# endif /* TRUSTED_BOARD_BOOT */ -#endif -#if IMAGE_BL2 -# define PLAT_MARVELL_MMAP_ENTRIES 8 -#endif -#if IMAGE_BL31 -#define PLAT_MARVELL_MMAP_ENTRIES 5 -#endif - -/* - * Platform specific page table and MMU setup constants - */ -#if IMAGE_BL1 -#define MAX_XLAT_TABLES 4 -#elif IMAGE_BLE -# define MAX_XLAT_TABLES 4 -#elif IMAGE_BL2 -# define MAX_XLAT_TABLES 4 -#elif IMAGE_BL31 -# define MAX_XLAT_TABLES 4 -#elif IMAGE_BL32 -# define MAX_XLAT_TABLES 4 -#endif - -#define MAX_IO_DEVICES 3 -#define MAX_IO_HANDLES 4 - -#define PLAT_MARVELL_TRUSTED_SRAM_SIZE 0x80000 /* 512 KB */ - -#endif /* BOARD_MARVELL_DEF_H */ diff --git a/include/plat/marvell/a3700/common/marvell_def.h b/include/plat/marvell/a3700/common/marvell_def.h deleted file mode 100644 index eb13ba8af..000000000 --- a/include/plat/marvell/a3700/common/marvell_def.h +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef MARVELL_DEF_H -#define MARVELL_DEF_H - -#include - -#include -#include -#include -#include - -/**************************************************************************** - * Definitions common to all MARVELL standard platforms - **************************************************************************** - */ -/* Special value used to verify platform parameters from BL2 to BL31 */ -#define MARVELL_BL31_PLAT_PARAM_VAL 0x0f1e2d3c4b5a6978ULL - -#define PLAT_MARVELL_NORTHB_COUNT 1 - -#define PLAT_MARVELL_CLUSTER_COUNT 1 - -#define MARVELL_CACHE_WRITEBACK_SHIFT 6 - -/* - * Macros mapping the MPIDR Affinity levels to MARVELL Platform Power levels. - * The power levels have a 1:1 mapping with the MPIDR affinity levels. - */ -#define MARVELL_PWR_LVL0 MPIDR_AFFLVL0 -#define MARVELL_PWR_LVL1 MPIDR_AFFLVL1 -#define MARVELL_PWR_LVL2 MPIDR_AFFLVL2 - -/* - * Macros for local power states in Marvell platforms encoded by State-ID field - * within the power-state parameter. - */ -/* Local power state for power domains in Run state. */ -#define MARVELL_LOCAL_STATE_RUN 0 -/* Local power state for retention. Valid only for CPU power domains */ -#define MARVELL_LOCAL_STATE_RET 1 -/* Local power state for OFF/power-down. - * Valid for CPU and cluster power domains - */ -#define MARVELL_LOCAL_STATE_OFF 2 - -/* The first 4KB of Trusted SRAM are used as shared memory */ -#define MARVELL_TRUSTED_SRAM_BASE PLAT_MARVELL_ATF_BASE -#define MARVELL_SHARED_RAM_BASE MARVELL_TRUSTED_SRAM_BASE -#define MARVELL_SHARED_RAM_SIZE 0x00001000 /* 4 KB */ - -/* The remaining Trusted SRAM is used to load the BL images */ -#define MARVELL_BL_RAM_BASE (MARVELL_SHARED_RAM_BASE + \ - MARVELL_SHARED_RAM_SIZE) -#define MARVELL_BL_RAM_SIZE (PLAT_MARVELL_TRUSTED_SRAM_SIZE - \ - MARVELL_SHARED_RAM_SIZE) - -#define MARVELL_DRAM_BASE ULL(0x0) -#define MARVELL_DRAM_SIZE ULL(0x20000000) -#define MARVELL_DRAM_END (MARVELL_DRAM_BASE + \ - MARVELL_DRAM_SIZE - 1) - -#define MARVELL_IRQ_SEC_PHY_TIMER 29 - -#define MARVELL_IRQ_SEC_SGI_0 8 -#define MARVELL_IRQ_SEC_SGI_1 9 -#define MARVELL_IRQ_SEC_SGI_2 10 -#define MARVELL_IRQ_SEC_SGI_3 11 -#define MARVELL_IRQ_SEC_SGI_4 12 -#define MARVELL_IRQ_SEC_SGI_5 13 -#define MARVELL_IRQ_SEC_SGI_6 14 -#define MARVELL_IRQ_SEC_SGI_7 15 - -#define MARVELL_MAP_SHARED_RAM MAP_REGION_FLAT( \ - MARVELL_SHARED_RAM_BASE, \ - MARVELL_SHARED_RAM_SIZE, \ - MT_MEMORY | MT_RW | MT_SECURE) - -#define MARVELL_MAP_DRAM MAP_REGION_FLAT( \ - MARVELL_DRAM_BASE, \ - MARVELL_DRAM_SIZE, \ - MT_MEMORY | MT_RW | MT_NS) - - -/* - * The number of regions like RO(code), coherent and data required by - * different BL stages which need to be mapped in the MMU. - */ -#if USE_COHERENT_MEM -#define MARVELL_BL_REGIONS 3 -#else -#define MARVELL_BL_REGIONS 2 -#endif - -#define MAX_MMAP_REGIONS (PLAT_MARVELL_MMAP_ENTRIES + \ - MARVELL_BL_REGIONS) - -#define MARVELL_CONSOLE_BAUDRATE 115200 - -/**************************************************************************** - * Required platform porting definitions common to all MARVELL std. platforms - **************************************************************************** - */ -#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) -#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) - -/* - * 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 MARVELL_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 MARVELL_LOCAL_STATE_OFF - - -#define PLATFORM_CORE_COUNT PLAT_MARVELL_CLUSTER_CORE_COUNT - -/* - * 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 << MARVELL_CACHE_WRITEBACK_SHIFT) - - -/***************************************************************************** - * BL1 specific defines. - * BL1 RW data is relocated from ROM to RAM at runtime so we need 2 sets of - * addresses. - ***************************************************************************** - */ -#define BL1_RO_BASE PLAT_MARVELL_TRUSTED_ROM_BASE -#define BL1_RO_LIMIT (PLAT_MARVELL_TRUSTED_ROM_BASE \ - + PLAT_MARVELL_TRUSTED_ROM_SIZE) -/* - * Put BL1 RW at the top of the Trusted SRAM. - */ -#define BL1_RW_BASE (MARVELL_BL_RAM_BASE + \ - MARVELL_BL_RAM_SIZE - \ - PLAT_MARVELL_MAX_BL1_RW_SIZE) -#define BL1_RW_LIMIT (MARVELL_BL_RAM_BASE + MARVELL_BL_RAM_SIZE) - -/***************************************************************************** - * BL2 specific defines. - ***************************************************************************** - */ -/* - * Put BL2 just below BL31. - */ -#define BL2_BASE (BL31_BASE - PLAT_MARVELL_MAX_BL2_SIZE) -#define BL2_LIMIT BL31_BASE - -/***************************************************************************** - * BL31 specific defines. - ***************************************************************************** - */ -/* - * Put BL31 at the top of the Trusted SRAM. - */ -#define BL31_BASE (MARVELL_BL_RAM_BASE + \ - MARVELL_BL_RAM_SIZE - \ - PLAT_MARVEL_MAX_BL31_SIZE) -#define BL31_PROGBITS_LIMIT BL1_RW_BASE -#define BL31_LIMIT (MARVELL_BL_RAM_BASE + \ - MARVELL_BL_RAM_SIZE) - - -#endif /* MARVELL_DEF_H */ diff --git a/include/plat/marvell/a3700/common/plat_marvell.h b/include/plat/marvell/a3700/common/plat_marvell.h deleted file mode 100644 index ea7cdcd4c..000000000 --- a/include/plat/marvell/a3700/common/plat_marvell.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2016 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef PLAT_MARVELL_H -#define PLAT_MARVELL_H - -#include - -#include -#include -#include -#include - -/* - * Extern declarations common to Marvell standard platforms - */ -extern const mmap_region_t plat_marvell_mmap[]; - -#define MARVELL_CASSERT_MMAP \ - CASSERT((ARRAY_SIZE(plat_marvell_mmap) + MARVELL_BL_REGIONS) \ - <= MAX_MMAP_REGIONS, \ - assert_max_mmap_regions) - -/* - * Utility functions common to Marvell standard platforms - */ -void marvell_setup_page_tables(uintptr_t total_base, - size_t total_size, - uintptr_t code_start, - uintptr_t code_limit, - uintptr_t rodata_start, - uintptr_t rodata_limit -#if USE_COHERENT_MEM - , uintptr_t coh_start, - uintptr_t coh_limit -#endif -); - -/* Console utility functions */ -void marvell_console_boot_init(void); -void marvell_console_boot_end(void); -void marvell_console_runtime_init(void); -void marvell_console_runtime_end(void); - -/* IO storage utility functions */ -void marvell_io_setup(void); - -/* Systimer utility function */ -void marvell_configure_sys_timer(void); - -/* Topology utility function */ -int marvell_check_mpidr(u_register_t mpidr); - -/* BL1 utility functions */ -void marvell_bl1_early_platform_setup(void); -void marvell_bl1_platform_setup(void); -void marvell_bl1_plat_arch_setup(void); - -/* BL2 utility functions */ -void marvell_bl2_early_platform_setup(meminfo_t *mem_layout); -void marvell_bl2_platform_setup(void); -void marvell_bl2_plat_arch_setup(void); -uint32_t marvell_get_spsr_for_bl32_entry(void); -uint32_t marvell_get_spsr_for_bl33_entry(void); - -/* BL31 utility functions */ -void marvell_bl31_early_platform_setup(void *from_bl2, - uintptr_t soc_fw_config, - uintptr_t hw_config, - void *plat_params_from_bl2); -void marvell_bl31_platform_setup(void); -void marvell_bl31_plat_runtime_setup(void); -void marvell_bl31_plat_arch_setup(void); - -/* FIP TOC validity check */ -int marvell_io_is_toc_valid(void); - -/* - * PSCI functionality - */ -void marvell_psci_arch_init(int idx); -void plat_marvell_system_reset(void); - -/* - * Optional functions required in Marvell standard platforms - */ -void plat_marvell_io_setup(void); -int plat_marvell_get_alt_image_source( - unsigned int image_id, - uintptr_t *dev_handle, - uintptr_t *image_spec); -unsigned int plat_marvell_calc_core_pos(u_register_t mpidr); - -void plat_marvell_interconnect_init(void); -void plat_marvell_interconnect_enter_coherency(void); - -const mmap_region_t *plat_marvell_get_mmap(void); - -#endif /* PLAT_MARVELL_H */ diff --git a/include/plat/marvell/a8k/common/armada_common.h b/include/plat/marvell/a8k/common/armada_common.h deleted file mode 100644 index 709d009c2..000000000 --- a/include/plat/marvell/a8k/common/armada_common.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef ARMADA_COMMON_H -#define ARMADA_COMMON_H - -#include -#include -#include -#include - -/* - * This struct supports skip image request - * detection_method: the method used to detect the request "signal". - * info: - * GPIO: - * detection_method: HIGH (pressed button), LOW (unpressed button), - * num (button mpp number). - * i2c: - * i2c_addr: the address of the i2c chosen. - * i2d_reg: the i2c register chosen. - * test: - * choose the DIE you picked the button in (AP or CP). - * in case of CP(cp_index = 0 if CP0, cp_index = 1 if CP1) - */ -struct skip_image { - enum { - GPIO, - I2C, - USER_DEFINED - } detection_method; - - struct { - struct { - int num; - enum { - HIGH, - LOW - } button_state; - - } gpio; - - struct { - int i2c_addr; - int i2c_reg; - } i2c; - - struct { - enum { - CP, - AP - } cp_ap; - int cp_index; - } test; - } info; -}; - -/* - * This struct supports SoC power off method - * type: the method used to power off the SoC - * cfg: - * PMIC_GPIO: - * pin_count: current GPIO pin number used for toggling the signal for - * notifying external PMIC - * info: holds the GPIOs information, CP GPIO should be used and - * all GPIOs should be within same GPIO config. register - * step_count: current step number to toggle the GPIO for PMIC - * seq: GPIO toggling values in sequence, each bit represents a GPIO. - * For example, bit0 represents first GPIO used for toggling - * the GPIO the last step is used to trigger the power off - * signal - * delay_ms: transition interval for the GPIO setting to take effect - * in unit of ms - */ -/* Max GPIO number used to notify PMIC to power off the SoC */ -#define PMIC_GPIO_MAX_NUMBER 8 -/* Max GPIO toggling steps in sequence to power off the SoC */ -#define PMIC_GPIO_MAX_TOGGLE_STEP 8 - -enum gpio_output_state { - GPIO_LOW = 0, - GPIO_HIGH -}; - -typedef struct gpio_info { - int cp_index; - int gpio_index; -} gpio_info_t; - -struct power_off_method { - enum { - PMIC_GPIO, - } type; - - struct { - struct { - int pin_count; - struct gpio_info info[PMIC_GPIO_MAX_NUMBER]; - int step_count; - uint32_t seq[PMIC_GPIO_MAX_TOGGLE_STEP]; - int delay_ms; - } gpio; - } cfg; -}; - -int marvell_gpio_config(void); -uint32_t marvell_get_io_win_gcr_target(int ap_idx); -uint32_t marvell_get_ccu_gcr_target(int ap_idx); - - -/* - * The functions below are defined as Weak and may be overridden - * in specific Marvell standard platform - */ -int marvell_get_amb_memory_map(struct addr_map_win **win, - uint32_t *size, uintptr_t base); -int marvell_get_io_win_memory_map(int ap_idx, struct addr_map_win **win, - uint32_t *size); -int marvell_get_iob_memory_map(struct addr_map_win **win, - uint32_t *size, uintptr_t base); -int marvell_get_ccu_memory_map(int ap_idx, struct addr_map_win **win, - uint32_t *size); -int system_power_off(void); - -#endif /* ARMADA_COMMON_H */ diff --git a/include/plat/marvell/a8k/common/board_marvell_def.h b/include/plat/marvell/a8k/common/board_marvell_def.h deleted file mode 100644 index 0da56e7af..000000000 --- a/include/plat/marvell/a8k/common/board_marvell_def.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef BOARD_MARVELL_DEF_H -#define BOARD_MARVELL_DEF_H - -/* - * Required platform porting definitions common to all ARM - * development platforms - */ - -/* Size of cacheable stacks */ -#if IMAGE_BL1 -#if TRUSTED_BOARD_BOOT -# define PLATFORM_STACK_SIZE 0x1000 -#else -# define PLATFORM_STACK_SIZE 0x440 -#endif -#elif IMAGE_BL2 -# if TRUSTED_BOARD_BOOT -# define PLATFORM_STACK_SIZE 0x1000 -# else -# define PLATFORM_STACK_SIZE 0x400 -# endif -#elif IMAGE_BL31 -# define PLATFORM_STACK_SIZE 0x400 -#elif IMAGE_BL32 -# define PLATFORM_STACK_SIZE 0x440 -#endif - -/* - * PLAT_MARVELL_MMAP_ENTRIES depends on the number of entries in the - * plat_arm_mmap array defined for each BL stage. - */ -#if IMAGE_BLE -# define PLAT_MARVELL_MMAP_ENTRIES 3 -#endif -#if IMAGE_BL1 -# if TRUSTED_BOARD_BOOT -# define PLAT_MARVELL_MMAP_ENTRIES 7 -# else -# define PLAT_MARVELL_MMAP_ENTRIES 6 -# endif /* TRUSTED_BOARD_BOOT */ -#endif -#if IMAGE_BL2 -# define PLAT_MARVELL_MMAP_ENTRIES 8 -#endif -#if IMAGE_BL31 -#define PLAT_MARVELL_MMAP_ENTRIES 5 -#endif - -/* - * Platform specific page table and MMU setup constants - */ -#if IMAGE_BL1 -#define MAX_XLAT_TABLES 4 -#elif IMAGE_BLE -# define MAX_XLAT_TABLES 4 -#elif IMAGE_BL2 -# define MAX_XLAT_TABLES 4 -#elif IMAGE_BL31 -# define MAX_XLAT_TABLES 4 -#elif IMAGE_BL32 -# define MAX_XLAT_TABLES 4 -#endif - -#define MAX_IO_DEVICES 3 -#define MAX_IO_HANDLES 4 - -#define PLAT_MARVELL_TRUSTED_SRAM_SIZE 0x80000 /* 512 KB */ - - -#endif /* BOARD_MARVELL_DEF_H */ diff --git a/include/plat/marvell/a8k/common/marvell_def.h b/include/plat/marvell/a8k/common/marvell_def.h deleted file mode 100644 index 4eda01f1e..000000000 --- a/include/plat/marvell/a8k/common/marvell_def.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef MARVELL_DEF_H -#define MARVELL_DEF_H - -#include - -#include -#include -#include -#include - -/****************************************************************************** - * Definitions common to all MARVELL standard platforms - *****************************************************************************/ - -/* Special value used to verify platform parameters from BL2 to BL31 */ -#define MARVELL_BL31_PLAT_PARAM_VAL 0x0f1e2d3c4b5a6978ULL - - -#define MARVELL_CACHE_WRITEBACK_SHIFT 6 - -/* - * Macros mapping the MPIDR Affinity levels to MARVELL Platform Power levels. - * The power levels have a 1:1 mapping with the MPIDR affinity levels. - */ -#define MARVELL_PWR_LVL0 MPIDR_AFFLVL0 -#define MARVELL_PWR_LVL1 MPIDR_AFFLVL1 -#define MARVELL_PWR_LVL2 MPIDR_AFFLVL2 - -/* - * Macros for local power states in Marvell platforms encoded by - * State-ID field within the power-state parameter. - */ -/* Local power state for power domains in Run state. */ -#define MARVELL_LOCAL_STATE_RUN 0 -/* Local power state for retention. Valid only for CPU power domains */ -#define MARVELL_LOCAL_STATE_RET 1 -/* - * Local power state for OFF/power-down. Valid for CPU - * and cluster power domains - */ -#define MARVELL_LOCAL_STATE_OFF 2 - -/* The first 4KB of Trusted SRAM are used as shared memory */ -#define MARVELL_TRUSTED_SRAM_BASE PLAT_MARVELL_ATF_BASE -#define MARVELL_SHARED_RAM_BASE MARVELL_TRUSTED_SRAM_BASE -#define MARVELL_SHARED_RAM_SIZE 0x00001000 /* 4 KB */ - -/* The remaining Trusted SRAM is used to load the BL images */ -#define MARVELL_BL_RAM_BASE (MARVELL_SHARED_RAM_BASE + \ - MARVELL_SHARED_RAM_SIZE) -#define MARVELL_BL_RAM_SIZE (PLAT_MARVELL_TRUSTED_SRAM_SIZE - \ - MARVELL_SHARED_RAM_SIZE) -/* Non-shared DRAM */ -#define MARVELL_DRAM_BASE ULL(0x0) -#define MARVELL_DRAM_SIZE ULL(0x80000000) -#define MARVELL_DRAM_END (MARVELL_DRAM_BASE + \ - MARVELL_DRAM_SIZE - 1) - -#define MARVELL_IRQ_PIC0 28 -#define MARVELL_IRQ_SEC_PHY_TIMER 29 - -#define MARVELL_IRQ_SEC_SGI_0 8 -#define MARVELL_IRQ_SEC_SGI_1 9 -#define MARVELL_IRQ_SEC_SGI_2 10 -#define MARVELL_IRQ_SEC_SGI_3 11 -#define MARVELL_IRQ_SEC_SGI_4 12 -#define MARVELL_IRQ_SEC_SGI_5 13 -#define MARVELL_IRQ_SEC_SGI_6 14 -#define MARVELL_IRQ_SEC_SGI_7 15 - -#define MARVELL_MAP_SHARED_RAM MAP_REGION_FLAT( \ - MARVELL_SHARED_RAM_BASE,\ - MARVELL_SHARED_RAM_SIZE,\ - MT_MEMORY | MT_RW | MT_SECURE) - -#define MARVELL_MAP_DRAM MAP_REGION_FLAT( \ - MARVELL_DRAM_BASE, \ - MARVELL_DRAM_SIZE, \ - MT_MEMORY | MT_RW | MT_NS) - - -/* - * The number of regions like RO(code), coherent and data required by - * different BL stages which need to be mapped in the MMU. - */ -#if USE_COHERENT_MEM -#define MARVELL_BL_REGIONS 3 -#else -#define MARVELL_BL_REGIONS 2 -#endif - -#define MAX_MMAP_REGIONS (PLAT_MARVELL_MMAP_ENTRIES + \ - MARVELL_BL_REGIONS) - -#define MARVELL_CONSOLE_BAUDRATE 115200 - -/****************************************************************************** - * Required platform porting definitions common to all MARVELL std. platforms - *****************************************************************************/ - -#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) -#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) - -/* - * 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 MARVELL_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 MARVELL_LOCAL_STATE_OFF - - -#define PLATFORM_CORE_COUNT PLAT_MARVELL_CORE_COUNT -#define PLAT_NUM_PWR_DOMAINS (PLAT_MARVELL_CLUSTER_COUNT + \ - PLATFORM_CORE_COUNT) - -/* - * 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 << MARVELL_CACHE_WRITEBACK_SHIFT) - - -/******************************************************************************* - * BL1 specific defines. - * BL1 RW data is relocated from ROM to RAM at runtime so we need 2 sets of - * addresses. - ******************************************************************************/ -#define BL1_RO_BASE PLAT_MARVELL_TRUSTED_ROM_BASE -#define BL1_RO_LIMIT (PLAT_MARVELL_TRUSTED_ROM_BASE \ - + PLAT_MARVELL_TRUSTED_ROM_SIZE) -/* - * Put BL1 RW at the top of the Trusted SRAM. - */ -#define BL1_RW_BASE (MARVELL_BL_RAM_BASE + \ - MARVELL_BL_RAM_SIZE - \ - PLAT_MARVELL_MAX_BL1_RW_SIZE) -#define BL1_RW_LIMIT (MARVELL_BL_RAM_BASE + MARVELL_BL_RAM_SIZE) - -/******************************************************************************* - * BLE specific defines. - ******************************************************************************/ -#define BLE_BASE PLAT_MARVELL_SRAM_BASE -#define BLE_LIMIT PLAT_MARVELL_SRAM_END - -/******************************************************************************* - * BL2 specific defines. - ******************************************************************************/ -/* - * Put BL2 just below BL31. - */ -#define BL2_BASE (BL31_BASE - PLAT_MARVELL_MAX_BL2_SIZE) -#define BL2_LIMIT BL31_BASE - -/******************************************************************************* - * BL31 specific defines. - ******************************************************************************/ -/* - * Put BL31 at the top of the Trusted SRAM. - */ -#define BL31_BASE (MARVELL_BL_RAM_BASE + \ - MARVELL_BL_RAM_SIZE - \ - PLAT_MARVEL_MAX_BL31_SIZE) -#define BL31_PROGBITS_LIMIT BL1_RW_BASE -#define BL31_LIMIT (MARVELL_BL_RAM_BASE + \ - MARVELL_BL_RAM_SIZE) - - -#endif /* MARVELL_DEF_H */ diff --git a/include/plat/marvell/a8k/common/plat_marvell.h b/include/plat/marvell/a8k/common/plat_marvell.h deleted file mode 100644 index 5d805a7f1..000000000 --- a/include/plat/marvell/a8k/common/plat_marvell.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef PLAT_MARVELL_H -#define PLAT_MARVELL_H - -#include - -#include -#include -#include -#include - -/* - * Extern declarations common to Marvell standard platforms - */ -extern const mmap_region_t plat_marvell_mmap[]; - -#define MARVELL_CASSERT_MMAP \ - CASSERT((ARRAY_SIZE(plat_marvell_mmap) + MARVELL_BL_REGIONS) \ - <= MAX_MMAP_REGIONS, \ - assert_max_mmap_regions) - -struct marvell_bl31_params { - param_header_t h; - image_info_t *bl31_image_info; - entry_point_info_t *bl32_ep_info; - image_info_t *bl32_image_info; - entry_point_info_t *bl33_ep_info; - image_info_t *bl33_image_info; -}; - -/* - * Utility functions common to Marvell standard platforms - */ -void marvell_setup_page_tables(uintptr_t total_base, - size_t total_size, - uintptr_t code_start, - uintptr_t code_limit, - uintptr_t rodata_start, - uintptr_t rodata_limit -#if USE_COHERENT_MEM - , uintptr_t coh_start, - uintptr_t coh_limit -#endif -); - -/* Console utility functions */ -void marvell_console_boot_init(void); -void marvell_console_boot_end(void); -void marvell_console_runtime_init(void); -void marvell_console_runtime_end(void); - -/* IO storage utility functions */ -void marvell_io_setup(void); - -/* Systimer utility function */ -void marvell_configure_sys_timer(void); - -/* Topology utility function */ -int marvell_check_mpidr(u_register_t mpidr); - -/* BLE utility functions */ -int ble_plat_setup(int *skip); -void plat_marvell_dram_update_topology(void); -void ble_plat_pcie_ep_setup(void); -struct pci_hw_cfg *plat_get_pcie_hw_data(void); - -/* BL1 utility functions */ -void marvell_bl1_early_platform_setup(void); -void marvell_bl1_platform_setup(void); -void marvell_bl1_plat_arch_setup(void); - -/* BL2 utility functions */ -void marvell_bl2_early_platform_setup(meminfo_t *mem_layout); -void marvell_bl2_platform_setup(void); -void marvell_bl2_plat_arch_setup(void); -uint32_t marvell_get_spsr_for_bl32_entry(void); -uint32_t marvell_get_spsr_for_bl33_entry(void); - -/* BL31 utility functions */ -void marvell_bl31_early_platform_setup(void *from_bl2, - uintptr_t soc_fw_config, - uintptr_t hw_config, - void *plat_params_from_bl2); -void marvell_bl31_platform_setup(void); -void marvell_bl31_plat_runtime_setup(void); -void marvell_bl31_plat_arch_setup(void); - -/* Power management config to power off the SoC */ -void *plat_marvell_get_pm_cfg(void); - -/* Check if MSS AP CM3 firmware contains PM support */ -_Bool is_pm_fw_running(void); - -/* Bootrom image recovery utility functions */ -void *plat_marvell_get_skip_image_data(void); - -/* FIP TOC validity check */ -int marvell_io_is_toc_valid(void); - -/* - * PSCI functionality - */ -void marvell_psci_arch_init(int ap_idx); -void plat_marvell_system_reset(void); - -/* - * Miscellaneous platform SMC routines - */ -#ifdef MVEBU_PMU_IRQ_WA -void mvebu_pmu_interrupt_enable(void); -void mvebu_pmu_interrupt_disable(void); -#endif - -/* - * Optional functions required in Marvell standard platforms - */ -void plat_marvell_io_setup(void); -int plat_marvell_get_alt_image_source( - unsigned int image_id, - uintptr_t *dev_handle, - uintptr_t *image_spec); -unsigned int plat_marvell_calc_core_pos(u_register_t mpidr); - -const mmap_region_t *plat_marvell_get_mmap(void); -void marvell_ble_prepare_exit(void); -void marvell_exit_bootrom(uintptr_t base); - -int plat_marvell_early_cpu_powerdown(void); -int bl2_plat_handle_scp_bl2(image_info_t *scp_bl2_image_info); - -#endif /* PLAT_MARVELL_H */ diff --git a/include/plat/marvell/a8k/common/plat_pm_trace.h b/include/plat/marvell/a8k/common/plat_pm_trace.h deleted file mode 100644 index a9549147d..000000000 --- a/include/plat/marvell/a8k/common/plat_pm_trace.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef PLAT_PM_TRACE_H -#define PLAT_PM_TRACE_H - -/* - * PM Trace is for Debug purpose only!!! - * It should not be enabled during System Run time - */ -#undef PM_TRACE_ENABLE - - -/* trace entry time */ -struct pm_trace_entry { - /* trace entry time stamp */ - unsigned int timestamp; - - /* trace info - * [16-31] - API Trace Id - * [00-15] - API Step Id - */ - unsigned int trace_info; -}; - -struct pm_trace_ctrl { - /* trace pointer - points to next free entry in trace cyclic queue */ - unsigned int trace_pointer; - - /* trace count - number of entries in the queue, clear upon read */ - unsigned int trace_count; -}; - -/* trace size definition */ -#define AP_MSS_ATF_CORE_INFO_SIZE (256) -#define AP_MSS_ATF_CORE_ENTRY_SIZE (8) -#define AP_MSS_ATF_TRACE_SIZE_MASK (0xFF) - -/* trace address definition */ -#define AP_MSS_TIMER_BASE (MVEBU_REGS_BASE_MASK + 0x580110) - -#define AP_MSS_ATF_CORE_0_CTRL_BASE (MVEBU_REGS_BASE_MASK + 0x520140) -#define AP_MSS_ATF_CORE_1_CTRL_BASE (MVEBU_REGS_BASE_MASK + 0x520150) -#define AP_MSS_ATF_CORE_2_CTRL_BASE (MVEBU_REGS_BASE_MASK + 0x520160) -#define AP_MSS_ATF_CORE_3_CTRL_BASE (MVEBU_REGS_BASE_MASK + 0x520170) -#define AP_MSS_ATF_CORE_CTRL_BASE (AP_MSS_ATF_CORE_0_CTRL_BASE) - -#define AP_MSS_ATF_CORE_0_INFO_BASE (MVEBU_REGS_BASE_MASK + 0x5201C0) -#define AP_MSS_ATF_CORE_0_INFO_TRACE (MVEBU_REGS_BASE_MASK + 0x5201C4) -#define AP_MSS_ATF_CORE_1_INFO_BASE (MVEBU_REGS_BASE_MASK + 0x5209C0) -#define AP_MSS_ATF_CORE_1_INFO_TRACE (MVEBU_REGS_BASE_MASK + 0x5209C4) -#define AP_MSS_ATF_CORE_2_INFO_BASE (MVEBU_REGS_BASE_MASK + 0x5211C0) -#define AP_MSS_ATF_CORE_2_INFO_TRACE (MVEBU_REGS_BASE_MASK + 0x5211C4) -#define AP_MSS_ATF_CORE_3_INFO_BASE (MVEBU_REGS_BASE_MASK + 0x5219C0) -#define AP_MSS_ATF_CORE_3_INFO_TRACE (MVEBU_REGS_BASE_MASK + 0x5219C4) -#define AP_MSS_ATF_CORE_INFO_BASE (AP_MSS_ATF_CORE_0_INFO_BASE) - -/* trace info definition */ -#define TRACE_PWR_DOMAIN_OFF (0x10000) -#define TRACE_PWR_DOMAIN_SUSPEND (0x20000) -#define TRACE_PWR_DOMAIN_SUSPEND_FINISH (0x30000) -#define TRACE_PWR_DOMAIN_ON (0x40000) -#define TRACE_PWR_DOMAIN_ON_FINISH (0x50000) - -#define TRACE_PWR_DOMAIN_ON_MASK (0xFF) - -#ifdef PM_TRACE_ENABLE - -/* trace API definition */ -void pm_core_0_trace(unsigned int trace); -void pm_core_1_trace(unsigned int trace); -void pm_core_2_trace(unsigned int trace); -void pm_core_3_trace(unsigned int trace); - -typedef void (*core_trace_func)(unsigned int); - -extern core_trace_func funcTbl[PLATFORM_CORE_COUNT]; - -#define PM_TRACE(trace) funcTbl[plat_my_core_pos()](trace) - -#else - -#define PM_TRACE(trace) - -#endif - -/******************************************************************************* - * pm_trace_add - * - * DESCRIPTION: Add PM trace - ****************************************************************************** - */ -void pm_trace_add(unsigned int trace, unsigned int core); - -#endif /* PLAT_PM_TRACE_H */ diff --git a/include/plat/marvell/armada/a3700/common/armada_common.h b/include/plat/marvell/armada/a3700/common/armada_common.h new file mode 100644 index 000000000..c6953fb71 --- /dev/null +++ b/include/plat/marvell/armada/a3700/common/armada_common.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef ARMADA_COMMON_H +#define ARMADA_COMMON_H + +#include + +#include + +int marvell_get_io_dec_win_conf(struct dec_win_config **win, uint32_t *size); + +#endif /* ARMADA_COMMON_H */ diff --git a/include/plat/marvell/armada/a3700/common/board_marvell_def.h b/include/plat/marvell/armada/a3700/common/board_marvell_def.h new file mode 100644 index 000000000..178259662 --- /dev/null +++ b/include/plat/marvell/armada/a3700/common/board_marvell_def.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef BOARD_MARVELL_DEF_H +#define BOARD_MARVELL_DEF_H + +/* + * Required platform porting definitions common to all ARM + * development platforms + */ + +/* Size of cacheable stacks */ +#if IMAGE_BL1 +#if TRUSTED_BOARD_BOOT +# define PLATFORM_STACK_SIZE 0x1000 +#else +# define PLATFORM_STACK_SIZE 0x440 +#endif +#elif IMAGE_BL2 +# if TRUSTED_BOARD_BOOT +# define PLATFORM_STACK_SIZE 0x1000 +# else +# define PLATFORM_STACK_SIZE 0x400 +# endif +#elif IMAGE_BL31 +# define PLATFORM_STACK_SIZE 0x400 +#elif IMAGE_BL32 +# define PLATFORM_STACK_SIZE 0x440 +#endif + +/* + * PLAT_MARVELL_MMAP_ENTRIES depends on the number of entries in the + * plat_arm_mmap array defined for each BL stage. + */ +#if IMAGE_BLE +# define PLAT_MARVELL_MMAP_ENTRIES 3 +#endif +#if IMAGE_BL1 +# if TRUSTED_BOARD_BOOT +# define PLAT_MARVELL_MMAP_ENTRIES 7 +# else +# define PLAT_MARVELL_MMAP_ENTRIES 6 +# endif /* TRUSTED_BOARD_BOOT */ +#endif +#if IMAGE_BL2 +# define PLAT_MARVELL_MMAP_ENTRIES 8 +#endif +#if IMAGE_BL31 +#define PLAT_MARVELL_MMAP_ENTRIES 5 +#endif + +/* + * Platform specific page table and MMU setup constants + */ +#if IMAGE_BL1 +#define MAX_XLAT_TABLES 4 +#elif IMAGE_BLE +# define MAX_XLAT_TABLES 4 +#elif IMAGE_BL2 +# define MAX_XLAT_TABLES 4 +#elif IMAGE_BL31 +# define MAX_XLAT_TABLES 4 +#elif IMAGE_BL32 +# define MAX_XLAT_TABLES 4 +#endif + +#define MAX_IO_DEVICES 3 +#define MAX_IO_HANDLES 4 + +#define PLAT_MARVELL_TRUSTED_SRAM_SIZE 0x80000 /* 512 KB */ + +#endif /* BOARD_MARVELL_DEF_H */ diff --git a/include/plat/marvell/armada/a3700/common/marvell_def.h b/include/plat/marvell/armada/a3700/common/marvell_def.h new file mode 100644 index 000000000..eb13ba8af --- /dev/null +++ b/include/plat/marvell/armada/a3700/common/marvell_def.h @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef MARVELL_DEF_H +#define MARVELL_DEF_H + +#include + +#include +#include +#include +#include + +/**************************************************************************** + * Definitions common to all MARVELL standard platforms + **************************************************************************** + */ +/* Special value used to verify platform parameters from BL2 to BL31 */ +#define MARVELL_BL31_PLAT_PARAM_VAL 0x0f1e2d3c4b5a6978ULL + +#define PLAT_MARVELL_NORTHB_COUNT 1 + +#define PLAT_MARVELL_CLUSTER_COUNT 1 + +#define MARVELL_CACHE_WRITEBACK_SHIFT 6 + +/* + * Macros mapping the MPIDR Affinity levels to MARVELL Platform Power levels. + * The power levels have a 1:1 mapping with the MPIDR affinity levels. + */ +#define MARVELL_PWR_LVL0 MPIDR_AFFLVL0 +#define MARVELL_PWR_LVL1 MPIDR_AFFLVL1 +#define MARVELL_PWR_LVL2 MPIDR_AFFLVL2 + +/* + * Macros for local power states in Marvell platforms encoded by State-ID field + * within the power-state parameter. + */ +/* Local power state for power domains in Run state. */ +#define MARVELL_LOCAL_STATE_RUN 0 +/* Local power state for retention. Valid only for CPU power domains */ +#define MARVELL_LOCAL_STATE_RET 1 +/* Local power state for OFF/power-down. + * Valid for CPU and cluster power domains + */ +#define MARVELL_LOCAL_STATE_OFF 2 + +/* The first 4KB of Trusted SRAM are used as shared memory */ +#define MARVELL_TRUSTED_SRAM_BASE PLAT_MARVELL_ATF_BASE +#define MARVELL_SHARED_RAM_BASE MARVELL_TRUSTED_SRAM_BASE +#define MARVELL_SHARED_RAM_SIZE 0x00001000 /* 4 KB */ + +/* The remaining Trusted SRAM is used to load the BL images */ +#define MARVELL_BL_RAM_BASE (MARVELL_SHARED_RAM_BASE + \ + MARVELL_SHARED_RAM_SIZE) +#define MARVELL_BL_RAM_SIZE (PLAT_MARVELL_TRUSTED_SRAM_SIZE - \ + MARVELL_SHARED_RAM_SIZE) + +#define MARVELL_DRAM_BASE ULL(0x0) +#define MARVELL_DRAM_SIZE ULL(0x20000000) +#define MARVELL_DRAM_END (MARVELL_DRAM_BASE + \ + MARVELL_DRAM_SIZE - 1) + +#define MARVELL_IRQ_SEC_PHY_TIMER 29 + +#define MARVELL_IRQ_SEC_SGI_0 8 +#define MARVELL_IRQ_SEC_SGI_1 9 +#define MARVELL_IRQ_SEC_SGI_2 10 +#define MARVELL_IRQ_SEC_SGI_3 11 +#define MARVELL_IRQ_SEC_SGI_4 12 +#define MARVELL_IRQ_SEC_SGI_5 13 +#define MARVELL_IRQ_SEC_SGI_6 14 +#define MARVELL_IRQ_SEC_SGI_7 15 + +#define MARVELL_MAP_SHARED_RAM MAP_REGION_FLAT( \ + MARVELL_SHARED_RAM_BASE, \ + MARVELL_SHARED_RAM_SIZE, \ + MT_MEMORY | MT_RW | MT_SECURE) + +#define MARVELL_MAP_DRAM MAP_REGION_FLAT( \ + MARVELL_DRAM_BASE, \ + MARVELL_DRAM_SIZE, \ + MT_MEMORY | MT_RW | MT_NS) + + +/* + * The number of regions like RO(code), coherent and data required by + * different BL stages which need to be mapped in the MMU. + */ +#if USE_COHERENT_MEM +#define MARVELL_BL_REGIONS 3 +#else +#define MARVELL_BL_REGIONS 2 +#endif + +#define MAX_MMAP_REGIONS (PLAT_MARVELL_MMAP_ENTRIES + \ + MARVELL_BL_REGIONS) + +#define MARVELL_CONSOLE_BAUDRATE 115200 + +/**************************************************************************** + * Required platform porting definitions common to all MARVELL std. platforms + **************************************************************************** + */ +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) + +/* + * 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 MARVELL_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 MARVELL_LOCAL_STATE_OFF + + +#define PLATFORM_CORE_COUNT PLAT_MARVELL_CLUSTER_CORE_COUNT + +/* + * 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 << MARVELL_CACHE_WRITEBACK_SHIFT) + + +/***************************************************************************** + * BL1 specific defines. + * BL1 RW data is relocated from ROM to RAM at runtime so we need 2 sets of + * addresses. + ***************************************************************************** + */ +#define BL1_RO_BASE PLAT_MARVELL_TRUSTED_ROM_BASE +#define BL1_RO_LIMIT (PLAT_MARVELL_TRUSTED_ROM_BASE \ + + PLAT_MARVELL_TRUSTED_ROM_SIZE) +/* + * Put BL1 RW at the top of the Trusted SRAM. + */ +#define BL1_RW_BASE (MARVELL_BL_RAM_BASE + \ + MARVELL_BL_RAM_SIZE - \ + PLAT_MARVELL_MAX_BL1_RW_SIZE) +#define BL1_RW_LIMIT (MARVELL_BL_RAM_BASE + MARVELL_BL_RAM_SIZE) + +/***************************************************************************** + * BL2 specific defines. + ***************************************************************************** + */ +/* + * Put BL2 just below BL31. + */ +#define BL2_BASE (BL31_BASE - PLAT_MARVELL_MAX_BL2_SIZE) +#define BL2_LIMIT BL31_BASE + +/***************************************************************************** + * BL31 specific defines. + ***************************************************************************** + */ +/* + * Put BL31 at the top of the Trusted SRAM. + */ +#define BL31_BASE (MARVELL_BL_RAM_BASE + \ + MARVELL_BL_RAM_SIZE - \ + PLAT_MARVEL_MAX_BL31_SIZE) +#define BL31_PROGBITS_LIMIT BL1_RW_BASE +#define BL31_LIMIT (MARVELL_BL_RAM_BASE + \ + MARVELL_BL_RAM_SIZE) + + +#endif /* MARVELL_DEF_H */ diff --git a/include/plat/marvell/armada/a3700/common/plat_marvell.h b/include/plat/marvell/armada/a3700/common/plat_marvell.h new file mode 100644 index 000000000..ea7cdcd4c --- /dev/null +++ b/include/plat/marvell/armada/a3700/common/plat_marvell.h @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2016 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef PLAT_MARVELL_H +#define PLAT_MARVELL_H + +#include + +#include +#include +#include +#include + +/* + * Extern declarations common to Marvell standard platforms + */ +extern const mmap_region_t plat_marvell_mmap[]; + +#define MARVELL_CASSERT_MMAP \ + CASSERT((ARRAY_SIZE(plat_marvell_mmap) + MARVELL_BL_REGIONS) \ + <= MAX_MMAP_REGIONS, \ + assert_max_mmap_regions) + +/* + * Utility functions common to Marvell standard platforms + */ +void marvell_setup_page_tables(uintptr_t total_base, + size_t total_size, + uintptr_t code_start, + uintptr_t code_limit, + uintptr_t rodata_start, + uintptr_t rodata_limit +#if USE_COHERENT_MEM + , uintptr_t coh_start, + uintptr_t coh_limit +#endif +); + +/* Console utility functions */ +void marvell_console_boot_init(void); +void marvell_console_boot_end(void); +void marvell_console_runtime_init(void); +void marvell_console_runtime_end(void); + +/* IO storage utility functions */ +void marvell_io_setup(void); + +/* Systimer utility function */ +void marvell_configure_sys_timer(void); + +/* Topology utility function */ +int marvell_check_mpidr(u_register_t mpidr); + +/* BL1 utility functions */ +void marvell_bl1_early_platform_setup(void); +void marvell_bl1_platform_setup(void); +void marvell_bl1_plat_arch_setup(void); + +/* BL2 utility functions */ +void marvell_bl2_early_platform_setup(meminfo_t *mem_layout); +void marvell_bl2_platform_setup(void); +void marvell_bl2_plat_arch_setup(void); +uint32_t marvell_get_spsr_for_bl32_entry(void); +uint32_t marvell_get_spsr_for_bl33_entry(void); + +/* BL31 utility functions */ +void marvell_bl31_early_platform_setup(void *from_bl2, + uintptr_t soc_fw_config, + uintptr_t hw_config, + void *plat_params_from_bl2); +void marvell_bl31_platform_setup(void); +void marvell_bl31_plat_runtime_setup(void); +void marvell_bl31_plat_arch_setup(void); + +/* FIP TOC validity check */ +int marvell_io_is_toc_valid(void); + +/* + * PSCI functionality + */ +void marvell_psci_arch_init(int idx); +void plat_marvell_system_reset(void); + +/* + * Optional functions required in Marvell standard platforms + */ +void plat_marvell_io_setup(void); +int plat_marvell_get_alt_image_source( + unsigned int image_id, + uintptr_t *dev_handle, + uintptr_t *image_spec); +unsigned int plat_marvell_calc_core_pos(u_register_t mpidr); + +void plat_marvell_interconnect_init(void); +void plat_marvell_interconnect_enter_coherency(void); + +const mmap_region_t *plat_marvell_get_mmap(void); + +#endif /* PLAT_MARVELL_H */ diff --git a/include/plat/marvell/armada/a8k/common/armada_common.h b/include/plat/marvell/armada/a8k/common/armada_common.h new file mode 100644 index 000000000..709d009c2 --- /dev/null +++ b/include/plat/marvell/armada/a8k/common/armada_common.h @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef ARMADA_COMMON_H +#define ARMADA_COMMON_H + +#include +#include +#include +#include + +/* + * This struct supports skip image request + * detection_method: the method used to detect the request "signal". + * info: + * GPIO: + * detection_method: HIGH (pressed button), LOW (unpressed button), + * num (button mpp number). + * i2c: + * i2c_addr: the address of the i2c chosen. + * i2d_reg: the i2c register chosen. + * test: + * choose the DIE you picked the button in (AP or CP). + * in case of CP(cp_index = 0 if CP0, cp_index = 1 if CP1) + */ +struct skip_image { + enum { + GPIO, + I2C, + USER_DEFINED + } detection_method; + + struct { + struct { + int num; + enum { + HIGH, + LOW + } button_state; + + } gpio; + + struct { + int i2c_addr; + int i2c_reg; + } i2c; + + struct { + enum { + CP, + AP + } cp_ap; + int cp_index; + } test; + } info; +}; + +/* + * This struct supports SoC power off method + * type: the method used to power off the SoC + * cfg: + * PMIC_GPIO: + * pin_count: current GPIO pin number used for toggling the signal for + * notifying external PMIC + * info: holds the GPIOs information, CP GPIO should be used and + * all GPIOs should be within same GPIO config. register + * step_count: current step number to toggle the GPIO for PMIC + * seq: GPIO toggling values in sequence, each bit represents a GPIO. + * For example, bit0 represents first GPIO used for toggling + * the GPIO the last step is used to trigger the power off + * signal + * delay_ms: transition interval for the GPIO setting to take effect + * in unit of ms + */ +/* Max GPIO number used to notify PMIC to power off the SoC */ +#define PMIC_GPIO_MAX_NUMBER 8 +/* Max GPIO toggling steps in sequence to power off the SoC */ +#define PMIC_GPIO_MAX_TOGGLE_STEP 8 + +enum gpio_output_state { + GPIO_LOW = 0, + GPIO_HIGH +}; + +typedef struct gpio_info { + int cp_index; + int gpio_index; +} gpio_info_t; + +struct power_off_method { + enum { + PMIC_GPIO, + } type; + + struct { + struct { + int pin_count; + struct gpio_info info[PMIC_GPIO_MAX_NUMBER]; + int step_count; + uint32_t seq[PMIC_GPIO_MAX_TOGGLE_STEP]; + int delay_ms; + } gpio; + } cfg; +}; + +int marvell_gpio_config(void); +uint32_t marvell_get_io_win_gcr_target(int ap_idx); +uint32_t marvell_get_ccu_gcr_target(int ap_idx); + + +/* + * The functions below are defined as Weak and may be overridden + * in specific Marvell standard platform + */ +int marvell_get_amb_memory_map(struct addr_map_win **win, + uint32_t *size, uintptr_t base); +int marvell_get_io_win_memory_map(int ap_idx, struct addr_map_win **win, + uint32_t *size); +int marvell_get_iob_memory_map(struct addr_map_win **win, + uint32_t *size, uintptr_t base); +int marvell_get_ccu_memory_map(int ap_idx, struct addr_map_win **win, + uint32_t *size); +int system_power_off(void); + +#endif /* ARMADA_COMMON_H */ diff --git a/include/plat/marvell/armada/a8k/common/board_marvell_def.h b/include/plat/marvell/armada/a8k/common/board_marvell_def.h new file mode 100644 index 000000000..0da56e7af --- /dev/null +++ b/include/plat/marvell/armada/a8k/common/board_marvell_def.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef BOARD_MARVELL_DEF_H +#define BOARD_MARVELL_DEF_H + +/* + * Required platform porting definitions common to all ARM + * development platforms + */ + +/* Size of cacheable stacks */ +#if IMAGE_BL1 +#if TRUSTED_BOARD_BOOT +# define PLATFORM_STACK_SIZE 0x1000 +#else +# define PLATFORM_STACK_SIZE 0x440 +#endif +#elif IMAGE_BL2 +# if TRUSTED_BOARD_BOOT +# define PLATFORM_STACK_SIZE 0x1000 +# else +# define PLATFORM_STACK_SIZE 0x400 +# endif +#elif IMAGE_BL31 +# define PLATFORM_STACK_SIZE 0x400 +#elif IMAGE_BL32 +# define PLATFORM_STACK_SIZE 0x440 +#endif + +/* + * PLAT_MARVELL_MMAP_ENTRIES depends on the number of entries in the + * plat_arm_mmap array defined for each BL stage. + */ +#if IMAGE_BLE +# define PLAT_MARVELL_MMAP_ENTRIES 3 +#endif +#if IMAGE_BL1 +# if TRUSTED_BOARD_BOOT +# define PLAT_MARVELL_MMAP_ENTRIES 7 +# else +# define PLAT_MARVELL_MMAP_ENTRIES 6 +# endif /* TRUSTED_BOARD_BOOT */ +#endif +#if IMAGE_BL2 +# define PLAT_MARVELL_MMAP_ENTRIES 8 +#endif +#if IMAGE_BL31 +#define PLAT_MARVELL_MMAP_ENTRIES 5 +#endif + +/* + * Platform specific page table and MMU setup constants + */ +#if IMAGE_BL1 +#define MAX_XLAT_TABLES 4 +#elif IMAGE_BLE +# define MAX_XLAT_TABLES 4 +#elif IMAGE_BL2 +# define MAX_XLAT_TABLES 4 +#elif IMAGE_BL31 +# define MAX_XLAT_TABLES 4 +#elif IMAGE_BL32 +# define MAX_XLAT_TABLES 4 +#endif + +#define MAX_IO_DEVICES 3 +#define MAX_IO_HANDLES 4 + +#define PLAT_MARVELL_TRUSTED_SRAM_SIZE 0x80000 /* 512 KB */ + + +#endif /* BOARD_MARVELL_DEF_H */ diff --git a/include/plat/marvell/armada/a8k/common/marvell_def.h b/include/plat/marvell/armada/a8k/common/marvell_def.h new file mode 100644 index 000000000..4eda01f1e --- /dev/null +++ b/include/plat/marvell/armada/a8k/common/marvell_def.h @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef MARVELL_DEF_H +#define MARVELL_DEF_H + +#include + +#include +#include +#include +#include + +/****************************************************************************** + * Definitions common to all MARVELL standard platforms + *****************************************************************************/ + +/* Special value used to verify platform parameters from BL2 to BL31 */ +#define MARVELL_BL31_PLAT_PARAM_VAL 0x0f1e2d3c4b5a6978ULL + + +#define MARVELL_CACHE_WRITEBACK_SHIFT 6 + +/* + * Macros mapping the MPIDR Affinity levels to MARVELL Platform Power levels. + * The power levels have a 1:1 mapping with the MPIDR affinity levels. + */ +#define MARVELL_PWR_LVL0 MPIDR_AFFLVL0 +#define MARVELL_PWR_LVL1 MPIDR_AFFLVL1 +#define MARVELL_PWR_LVL2 MPIDR_AFFLVL2 + +/* + * Macros for local power states in Marvell platforms encoded by + * State-ID field within the power-state parameter. + */ +/* Local power state for power domains in Run state. */ +#define MARVELL_LOCAL_STATE_RUN 0 +/* Local power state for retention. Valid only for CPU power domains */ +#define MARVELL_LOCAL_STATE_RET 1 +/* + * Local power state for OFF/power-down. Valid for CPU + * and cluster power domains + */ +#define MARVELL_LOCAL_STATE_OFF 2 + +/* The first 4KB of Trusted SRAM are used as shared memory */ +#define MARVELL_TRUSTED_SRAM_BASE PLAT_MARVELL_ATF_BASE +#define MARVELL_SHARED_RAM_BASE MARVELL_TRUSTED_SRAM_BASE +#define MARVELL_SHARED_RAM_SIZE 0x00001000 /* 4 KB */ + +/* The remaining Trusted SRAM is used to load the BL images */ +#define MARVELL_BL_RAM_BASE (MARVELL_SHARED_RAM_BASE + \ + MARVELL_SHARED_RAM_SIZE) +#define MARVELL_BL_RAM_SIZE (PLAT_MARVELL_TRUSTED_SRAM_SIZE - \ + MARVELL_SHARED_RAM_SIZE) +/* Non-shared DRAM */ +#define MARVELL_DRAM_BASE ULL(0x0) +#define MARVELL_DRAM_SIZE ULL(0x80000000) +#define MARVELL_DRAM_END (MARVELL_DRAM_BASE + \ + MARVELL_DRAM_SIZE - 1) + +#define MARVELL_IRQ_PIC0 28 +#define MARVELL_IRQ_SEC_PHY_TIMER 29 + +#define MARVELL_IRQ_SEC_SGI_0 8 +#define MARVELL_IRQ_SEC_SGI_1 9 +#define MARVELL_IRQ_SEC_SGI_2 10 +#define MARVELL_IRQ_SEC_SGI_3 11 +#define MARVELL_IRQ_SEC_SGI_4 12 +#define MARVELL_IRQ_SEC_SGI_5 13 +#define MARVELL_IRQ_SEC_SGI_6 14 +#define MARVELL_IRQ_SEC_SGI_7 15 + +#define MARVELL_MAP_SHARED_RAM MAP_REGION_FLAT( \ + MARVELL_SHARED_RAM_BASE,\ + MARVELL_SHARED_RAM_SIZE,\ + MT_MEMORY | MT_RW | MT_SECURE) + +#define MARVELL_MAP_DRAM MAP_REGION_FLAT( \ + MARVELL_DRAM_BASE, \ + MARVELL_DRAM_SIZE, \ + MT_MEMORY | MT_RW | MT_NS) + + +/* + * The number of regions like RO(code), coherent and data required by + * different BL stages which need to be mapped in the MMU. + */ +#if USE_COHERENT_MEM +#define MARVELL_BL_REGIONS 3 +#else +#define MARVELL_BL_REGIONS 2 +#endif + +#define MAX_MMAP_REGIONS (PLAT_MARVELL_MMAP_ENTRIES + \ + MARVELL_BL_REGIONS) + +#define MARVELL_CONSOLE_BAUDRATE 115200 + +/****************************************************************************** + * Required platform porting definitions common to all MARVELL std. platforms + *****************************************************************************/ + +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) + +/* + * 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 MARVELL_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 MARVELL_LOCAL_STATE_OFF + + +#define PLATFORM_CORE_COUNT PLAT_MARVELL_CORE_COUNT +#define PLAT_NUM_PWR_DOMAINS (PLAT_MARVELL_CLUSTER_COUNT + \ + PLATFORM_CORE_COUNT) + +/* + * 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 << MARVELL_CACHE_WRITEBACK_SHIFT) + + +/******************************************************************************* + * BL1 specific defines. + * BL1 RW data is relocated from ROM to RAM at runtime so we need 2 sets of + * addresses. + ******************************************************************************/ +#define BL1_RO_BASE PLAT_MARVELL_TRUSTED_ROM_BASE +#define BL1_RO_LIMIT (PLAT_MARVELL_TRUSTED_ROM_BASE \ + + PLAT_MARVELL_TRUSTED_ROM_SIZE) +/* + * Put BL1 RW at the top of the Trusted SRAM. + */ +#define BL1_RW_BASE (MARVELL_BL_RAM_BASE + \ + MARVELL_BL_RAM_SIZE - \ + PLAT_MARVELL_MAX_BL1_RW_SIZE) +#define BL1_RW_LIMIT (MARVELL_BL_RAM_BASE + MARVELL_BL_RAM_SIZE) + +/******************************************************************************* + * BLE specific defines. + ******************************************************************************/ +#define BLE_BASE PLAT_MARVELL_SRAM_BASE +#define BLE_LIMIT PLAT_MARVELL_SRAM_END + +/******************************************************************************* + * BL2 specific defines. + ******************************************************************************/ +/* + * Put BL2 just below BL31. + */ +#define BL2_BASE (BL31_BASE - PLAT_MARVELL_MAX_BL2_SIZE) +#define BL2_LIMIT BL31_BASE + +/******************************************************************************* + * BL31 specific defines. + ******************************************************************************/ +/* + * Put BL31 at the top of the Trusted SRAM. + */ +#define BL31_BASE (MARVELL_BL_RAM_BASE + \ + MARVELL_BL_RAM_SIZE - \ + PLAT_MARVEL_MAX_BL31_SIZE) +#define BL31_PROGBITS_LIMIT BL1_RW_BASE +#define BL31_LIMIT (MARVELL_BL_RAM_BASE + \ + MARVELL_BL_RAM_SIZE) + + +#endif /* MARVELL_DEF_H */ diff --git a/include/plat/marvell/armada/a8k/common/plat_marvell.h b/include/plat/marvell/armada/a8k/common/plat_marvell.h new file mode 100644 index 000000000..5d805a7f1 --- /dev/null +++ b/include/plat/marvell/armada/a8k/common/plat_marvell.h @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef PLAT_MARVELL_H +#define PLAT_MARVELL_H + +#include + +#include +#include +#include +#include + +/* + * Extern declarations common to Marvell standard platforms + */ +extern const mmap_region_t plat_marvell_mmap[]; + +#define MARVELL_CASSERT_MMAP \ + CASSERT((ARRAY_SIZE(plat_marvell_mmap) + MARVELL_BL_REGIONS) \ + <= MAX_MMAP_REGIONS, \ + assert_max_mmap_regions) + +struct marvell_bl31_params { + param_header_t h; + image_info_t *bl31_image_info; + entry_point_info_t *bl32_ep_info; + image_info_t *bl32_image_info; + entry_point_info_t *bl33_ep_info; + image_info_t *bl33_image_info; +}; + +/* + * Utility functions common to Marvell standard platforms + */ +void marvell_setup_page_tables(uintptr_t total_base, + size_t total_size, + uintptr_t code_start, + uintptr_t code_limit, + uintptr_t rodata_start, + uintptr_t rodata_limit +#if USE_COHERENT_MEM + , uintptr_t coh_start, + uintptr_t coh_limit +#endif +); + +/* Console utility functions */ +void marvell_console_boot_init(void); +void marvell_console_boot_end(void); +void marvell_console_runtime_init(void); +void marvell_console_runtime_end(void); + +/* IO storage utility functions */ +void marvell_io_setup(void); + +/* Systimer utility function */ +void marvell_configure_sys_timer(void); + +/* Topology utility function */ +int marvell_check_mpidr(u_register_t mpidr); + +/* BLE utility functions */ +int ble_plat_setup(int *skip); +void plat_marvell_dram_update_topology(void); +void ble_plat_pcie_ep_setup(void); +struct pci_hw_cfg *plat_get_pcie_hw_data(void); + +/* BL1 utility functions */ +void marvell_bl1_early_platform_setup(void); +void marvell_bl1_platform_setup(void); +void marvell_bl1_plat_arch_setup(void); + +/* BL2 utility functions */ +void marvell_bl2_early_platform_setup(meminfo_t *mem_layout); +void marvell_bl2_platform_setup(void); +void marvell_bl2_plat_arch_setup(void); +uint32_t marvell_get_spsr_for_bl32_entry(void); +uint32_t marvell_get_spsr_for_bl33_entry(void); + +/* BL31 utility functions */ +void marvell_bl31_early_platform_setup(void *from_bl2, + uintptr_t soc_fw_config, + uintptr_t hw_config, + void *plat_params_from_bl2); +void marvell_bl31_platform_setup(void); +void marvell_bl31_plat_runtime_setup(void); +void marvell_bl31_plat_arch_setup(void); + +/* Power management config to power off the SoC */ +void *plat_marvell_get_pm_cfg(void); + +/* Check if MSS AP CM3 firmware contains PM support */ +_Bool is_pm_fw_running(void); + +/* Bootrom image recovery utility functions */ +void *plat_marvell_get_skip_image_data(void); + +/* FIP TOC validity check */ +int marvell_io_is_toc_valid(void); + +/* + * PSCI functionality + */ +void marvell_psci_arch_init(int ap_idx); +void plat_marvell_system_reset(void); + +/* + * Miscellaneous platform SMC routines + */ +#ifdef MVEBU_PMU_IRQ_WA +void mvebu_pmu_interrupt_enable(void); +void mvebu_pmu_interrupt_disable(void); +#endif + +/* + * Optional functions required in Marvell standard platforms + */ +void plat_marvell_io_setup(void); +int plat_marvell_get_alt_image_source( + unsigned int image_id, + uintptr_t *dev_handle, + uintptr_t *image_spec); +unsigned int plat_marvell_calc_core_pos(u_register_t mpidr); + +const mmap_region_t *plat_marvell_get_mmap(void); +void marvell_ble_prepare_exit(void); +void marvell_exit_bootrom(uintptr_t base); + +int plat_marvell_early_cpu_powerdown(void); +int bl2_plat_handle_scp_bl2(image_info_t *scp_bl2_image_info); + +#endif /* PLAT_MARVELL_H */ diff --git a/include/plat/marvell/armada/a8k/common/plat_pm_trace.h b/include/plat/marvell/armada/a8k/common/plat_pm_trace.h new file mode 100644 index 000000000..a9549147d --- /dev/null +++ b/include/plat/marvell/armada/a8k/common/plat_pm_trace.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef PLAT_PM_TRACE_H +#define PLAT_PM_TRACE_H + +/* + * PM Trace is for Debug purpose only!!! + * It should not be enabled during System Run time + */ +#undef PM_TRACE_ENABLE + + +/* trace entry time */ +struct pm_trace_entry { + /* trace entry time stamp */ + unsigned int timestamp; + + /* trace info + * [16-31] - API Trace Id + * [00-15] - API Step Id + */ + unsigned int trace_info; +}; + +struct pm_trace_ctrl { + /* trace pointer - points to next free entry in trace cyclic queue */ + unsigned int trace_pointer; + + /* trace count - number of entries in the queue, clear upon read */ + unsigned int trace_count; +}; + +/* trace size definition */ +#define AP_MSS_ATF_CORE_INFO_SIZE (256) +#define AP_MSS_ATF_CORE_ENTRY_SIZE (8) +#define AP_MSS_ATF_TRACE_SIZE_MASK (0xFF) + +/* trace address definition */ +#define AP_MSS_TIMER_BASE (MVEBU_REGS_BASE_MASK + 0x580110) + +#define AP_MSS_ATF_CORE_0_CTRL_BASE (MVEBU_REGS_BASE_MASK + 0x520140) +#define AP_MSS_ATF_CORE_1_CTRL_BASE (MVEBU_REGS_BASE_MASK + 0x520150) +#define AP_MSS_ATF_CORE_2_CTRL_BASE (MVEBU_REGS_BASE_MASK + 0x520160) +#define AP_MSS_ATF_CORE_3_CTRL_BASE (MVEBU_REGS_BASE_MASK + 0x520170) +#define AP_MSS_ATF_CORE_CTRL_BASE (AP_MSS_ATF_CORE_0_CTRL_BASE) + +#define AP_MSS_ATF_CORE_0_INFO_BASE (MVEBU_REGS_BASE_MASK + 0x5201C0) +#define AP_MSS_ATF_CORE_0_INFO_TRACE (MVEBU_REGS_BASE_MASK + 0x5201C4) +#define AP_MSS_ATF_CORE_1_INFO_BASE (MVEBU_REGS_BASE_MASK + 0x5209C0) +#define AP_MSS_ATF_CORE_1_INFO_TRACE (MVEBU_REGS_BASE_MASK + 0x5209C4) +#define AP_MSS_ATF_CORE_2_INFO_BASE (MVEBU_REGS_BASE_MASK + 0x5211C0) +#define AP_MSS_ATF_CORE_2_INFO_TRACE (MVEBU_REGS_BASE_MASK + 0x5211C4) +#define AP_MSS_ATF_CORE_3_INFO_BASE (MVEBU_REGS_BASE_MASK + 0x5219C0) +#define AP_MSS_ATF_CORE_3_INFO_TRACE (MVEBU_REGS_BASE_MASK + 0x5219C4) +#define AP_MSS_ATF_CORE_INFO_BASE (AP_MSS_ATF_CORE_0_INFO_BASE) + +/* trace info definition */ +#define TRACE_PWR_DOMAIN_OFF (0x10000) +#define TRACE_PWR_DOMAIN_SUSPEND (0x20000) +#define TRACE_PWR_DOMAIN_SUSPEND_FINISH (0x30000) +#define TRACE_PWR_DOMAIN_ON (0x40000) +#define TRACE_PWR_DOMAIN_ON_FINISH (0x50000) + +#define TRACE_PWR_DOMAIN_ON_MASK (0xFF) + +#ifdef PM_TRACE_ENABLE + +/* trace API definition */ +void pm_core_0_trace(unsigned int trace); +void pm_core_1_trace(unsigned int trace); +void pm_core_2_trace(unsigned int trace); +void pm_core_3_trace(unsigned int trace); + +typedef void (*core_trace_func)(unsigned int); + +extern core_trace_func funcTbl[PLATFORM_CORE_COUNT]; + +#define PM_TRACE(trace) funcTbl[plat_my_core_pos()](trace) + +#else + +#define PM_TRACE(trace) + +#endif + +/******************************************************************************* + * pm_trace_add + * + * DESCRIPTION: Add PM trace + ****************************************************************************** + */ +void pm_trace_add(unsigned int trace, unsigned int core); + +#endif /* PLAT_PM_TRACE_H */ diff --git a/include/plat/marvell/armada/common/aarch64/cci_macros.S b/include/plat/marvell/armada/common/aarch64/cci_macros.S new file mode 100644 index 000000000..b0a909bb6 --- /dev/null +++ b/include/plat/marvell/armada/common/aarch64/cci_macros.S @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef CCI_MACROS_S +#define CCI_MACROS_S + +#include +#include + +.section .rodata.cci_reg_name, "aS" +cci_iface_regs: + .asciz "cci_snoop_ctrl_cluster0", "cci_snoop_ctrl_cluster1" , "" + + /* ------------------------------------------------ + * The below required platform porting macro prints + * out relevant interconnect registers whenever an + * unhandled exception is taken in BL31. + * Clobbers: x0 - x9, sp + * ------------------------------------------------ + */ + .macro print_cci_regs + adr x6, cci_iface_regs + /* Store in x7 the base address of the first interface */ + mov_imm x7, (PLAT_MARVELL_CCI_BASE + SLAVE_IFACE_OFFSET( \ + PLAT_MARVELL_CCI_CLUSTER0_SL_IFACE_IX)) + ldr w8, [x7, #SNOOP_CTRL_REG] + /* Store in x7 the base address of the second interface */ + mov_imm x7, (PLAT_MARVELL_CCI_BASE + SLAVE_IFACE_OFFSET( \ + PLAT_MARVELL_CCI_CLUSTER1_SL_IFACE_IX)) + ldr w9, [x7, #SNOOP_CTRL_REG] + /* Store to the crash buf and print to console */ + bl str_in_crash_buf_print + .endm + +#endif /* CCI_MACROS_S */ diff --git a/include/plat/marvell/armada/common/aarch64/marvell_macros.S b/include/plat/marvell/armada/common/aarch64/marvell_macros.S new file mode 100644 index 000000000..bfe2d4127 --- /dev/null +++ b/include/plat/marvell/armada/common/aarch64/marvell_macros.S @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef MARVELL_MACROS_S +#define MARVELL_MACROS_S + +#include +#include +#include +#include +#include + +/* + * These Macros are required by ATF + */ + +.section .rodata.gic_reg_name, "aS" +/* Applicable only to GICv2 and GICv3 with SRE disabled (legacy mode) */ +gicc_regs: + .asciz "gicc_hppir", "gicc_ahppir", "gicc_ctlr", "" + +#ifdef USE_CCI +/* Applicable only to GICv3 with SRE enabled */ +icc_regs: + .asciz "icc_hppir0_el1", "icc_hppir1_el1", "icc_ctlr_el3", "" +#endif +/* Registers common to both GICv2 and GICv3 */ +gicd_pend_reg: + .asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n" \ + " Offset:\t\t\tvalue\n" +newline: + .asciz "\n" +spacer: + .asciz ":\t\t0x" + + /* --------------------------------------------- + * The below utility macro prints out relevant GIC + * registers whenever an unhandled exception is + * taken in BL31 on ARM standard platforms. + * Expects: GICD base in x16, GICC base in x17 + * Clobbers: x0 - x10, sp + * --------------------------------------------- + */ + .macro marvell_print_gic_regs + /* Check for GICv3 system register access */ + mrs x7, id_aa64pfr0_el1 + ubfx x7, x7, #ID_AA64PFR0_GIC_SHIFT, #ID_AA64PFR0_GIC_WIDTH + cmp x7, #1 + b.ne print_gicv2 + + /* Check for SRE enable */ + mrs x8, ICC_SRE_EL3 + tst x8, #ICC_SRE_SRE_BIT + b.eq print_gicv2 + +#ifdef USE_CCI + /* Load the icc reg list to x6 */ + adr x6, icc_regs + /* Load the icc regs to gp regs used by str_in_crash_buf_print */ + mrs x8, ICC_HPPIR0_EL1 + mrs x9, ICC_HPPIR1_EL1 + mrs x10, ICC_CTLR_EL3 + /* Store to the crash buf and print to console */ + bl str_in_crash_buf_print +#endif + b print_gic_common + +print_gicv2: + /* Load the gicc reg list to x6 */ + adr x6, gicc_regs + /* Load the gicc regs to gp regs used by str_in_crash_buf_print */ + ldr w8, [x17, #GICC_HPPIR] + ldr w9, [x17, #GICC_AHPPIR] + ldr w10, [x17, #GICC_CTLR] + /* Store to the crash buf and print to console */ + bl str_in_crash_buf_print + +print_gic_common: + /* Print the GICD_ISPENDR regs */ + add x7, x16, #GICD_ISPENDR + adr x4, gicd_pend_reg + bl asm_print_str +gicd_ispendr_loop: + sub x4, x7, x16 + cmp x4, #0x280 + b.eq exit_print_gic_regs + bl asm_print_hex + + adr x4, spacer + bl asm_print_str + + ldr x4, [x7], #8 + bl asm_print_hex + + adr x4, newline + bl asm_print_str + b gicd_ispendr_loop +exit_print_gic_regs: + .endm + + +.section .rodata.cci_reg_name, "aS" +cci_iface_regs: + .asciz "cci_snoop_ctrl_cluster0", "cci_snoop_ctrl_cluster1" , "" + + /* ------------------------------------------------ + * The below required platform porting macro prints + * out relevant interconnect registers whenever an + * unhandled exception is taken in BL31. + * Clobbers: x0 - x9, sp + * ------------------------------------------------ + */ + .macro print_cci_regs +#ifdef USE_CCI + adr x6, cci_iface_regs + /* Store in x7 the base address of the first interface */ + mov_imm x7, (PLAT_MARVELL_CCI_BASE + SLAVE_IFACE_OFFSET( \ + PLAT_MARVELL_CCI_CLUSTER0_SL_IFACE_IX)) + ldr w8, [x7, #SNOOP_CTRL_REG] + /* Store in x7 the base address of the second interface */ + mov_imm x7, (PLAT_MARVELL_CCI_BASE + SLAVE_IFACE_OFFSET( \ + PLAT_MARVELL_CCI_CLUSTER1_SL_IFACE_IX)) + ldr w9, [x7, #SNOOP_CTRL_REG] + /* Store to the crash buf and print to console */ + bl str_in_crash_buf_print +#endif + .endm + + +#endif /* MARVELL_MACROS_S */ diff --git a/include/plat/marvell/armada/common/marvell_plat_priv.h b/include/plat/marvell/armada/common/marvell_plat_priv.h new file mode 100644 index 000000000..78b5331e4 --- /dev/null +++ b/include/plat/marvell/armada/common/marvell_plat_priv.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef MARVELL_PLAT_PRIV_H +#define MARVELL_PLAT_PRIV_H + +#include + +/***************************************************************************** + * Function and variable prototypes + ***************************************************************************** + */ +void plat_delay_timer_init(void); + +uint64_t mvebu_get_dram_size(uint64_t ap_base_addr); + +/* + * GIC operation, mandatory functions required in Marvell standard platforms + */ +void plat_marvell_gic_driver_init(void); +void plat_marvell_gic_init(void); +void plat_marvell_gic_cpuif_enable(void); +void plat_marvell_gic_cpuif_disable(void); +void plat_marvell_gic_pcpu_init(void); +void plat_marvell_gic_irq_save(void); +void plat_marvell_gic_irq_restore(void); +void plat_marvell_gic_irq_pcpu_save(void); +void plat_marvell_gic_irq_pcpu_restore(void); + +#endif /* MARVELL_PLAT_PRIV_H */ diff --git a/include/plat/marvell/armada/common/marvell_pm.h b/include/plat/marvell/armada/common/marvell_pm.h new file mode 100644 index 000000000..8f1660755 --- /dev/null +++ b/include/plat/marvell/armada/common/marvell_pm.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef MARVELL_PM_H +#define MARVELL_PM_H + +#define MVEBU_MAILBOX_MAGIC_NUM PLAT_MARVELL_MAILBOX_MAGIC_NUM +#define MVEBU_MAILBOX_SUSPEND_STATE 0xb007de7c + +/* Mailbox entry indexes */ +/* Magic number for validity check */ +#define MBOX_IDX_MAGIC 0 +/* Recovery from suspend entry point */ +#define MBOX_IDX_SEC_ADDR 1 +/* Suspend state magic number */ +#define MBOX_IDX_SUSPEND_MAGIC 2 +/* Recovery jump address for ROM bypass */ +#define MBOX_IDX_ROM_EXIT_ADDR 3 +/* BLE execution start counter value */ +#define MBOX_IDX_START_CNT 4 + +#endif /* MARVELL_PM_H */ diff --git a/include/plat/marvell/armada/common/mvebu.h b/include/plat/marvell/armada/common/mvebu.h new file mode 100644 index 000000000..35a0200ad --- /dev/null +++ b/include/plat/marvell/armada/common/mvebu.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef MVEBU_H +#define MVEBU_H + +/* Use this functions only when printf is allowed */ +#define debug_enter() VERBOSE("----> Enter %s\n", __func__) +#define debug_exit() VERBOSE("<---- Exit %s\n", __func__) + +/* Macro for testing alignment. Positive if number is NOT aligned */ +#define IS_NOT_ALIGN(number, align) ((number) & ((align) - 1)) + +/* Macro for alignment up. For example, ALIGN_UP(0x0330, 0x20) = 0x0340 */ +#define ALIGN_UP(number, align) (((number) & ((align) - 1)) ? \ + (((number) + (align)) & ~((align)-1)) : (number)) + +/* Macro for testing whether a number is a power of 2. Positive if so */ +#define IS_POWER_OF_2(number) ((number) != 0 && \ + (((number) & ((number) - 1)) == 0)) + +/* + * Macro for ronding up to next power of 2 + * it is done by count leading 0 (clz assembly opcode) and see msb set bit. + * then you can shift it left and get number which power of 2 + * Note: this Macro is for 32 bit number + */ +#define ROUND_UP_TO_POW_OF_2(number) (1 << \ + (32 - __builtin_clz((number) - 1))) + +#define _1MB_ (1024ULL * 1024ULL) +#define _1GB_ (_1MB_ * 1024ULL) +#define _2GB_ (2 * _1GB_) + +#endif /* MVEBU_H */ diff --git a/include/plat/marvell/common/aarch64/cci_macros.S b/include/plat/marvell/common/aarch64/cci_macros.S deleted file mode 100644 index b0a909bb6..000000000 --- a/include/plat/marvell/common/aarch64/cci_macros.S +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef CCI_MACROS_S -#define CCI_MACROS_S - -#include -#include - -.section .rodata.cci_reg_name, "aS" -cci_iface_regs: - .asciz "cci_snoop_ctrl_cluster0", "cci_snoop_ctrl_cluster1" , "" - - /* ------------------------------------------------ - * The below required platform porting macro prints - * out relevant interconnect registers whenever an - * unhandled exception is taken in BL31. - * Clobbers: x0 - x9, sp - * ------------------------------------------------ - */ - .macro print_cci_regs - adr x6, cci_iface_regs - /* Store in x7 the base address of the first interface */ - mov_imm x7, (PLAT_MARVELL_CCI_BASE + SLAVE_IFACE_OFFSET( \ - PLAT_MARVELL_CCI_CLUSTER0_SL_IFACE_IX)) - ldr w8, [x7, #SNOOP_CTRL_REG] - /* Store in x7 the base address of the second interface */ - mov_imm x7, (PLAT_MARVELL_CCI_BASE + SLAVE_IFACE_OFFSET( \ - PLAT_MARVELL_CCI_CLUSTER1_SL_IFACE_IX)) - ldr w9, [x7, #SNOOP_CTRL_REG] - /* Store to the crash buf and print to console */ - bl str_in_crash_buf_print - .endm - -#endif /* CCI_MACROS_S */ diff --git a/include/plat/marvell/common/aarch64/marvell_macros.S b/include/plat/marvell/common/aarch64/marvell_macros.S deleted file mode 100644 index bfe2d4127..000000000 --- a/include/plat/marvell/common/aarch64/marvell_macros.S +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef MARVELL_MACROS_S -#define MARVELL_MACROS_S - -#include -#include -#include -#include -#include - -/* - * These Macros are required by ATF - */ - -.section .rodata.gic_reg_name, "aS" -/* Applicable only to GICv2 and GICv3 with SRE disabled (legacy mode) */ -gicc_regs: - .asciz "gicc_hppir", "gicc_ahppir", "gicc_ctlr", "" - -#ifdef USE_CCI -/* Applicable only to GICv3 with SRE enabled */ -icc_regs: - .asciz "icc_hppir0_el1", "icc_hppir1_el1", "icc_ctlr_el3", "" -#endif -/* Registers common to both GICv2 and GICv3 */ -gicd_pend_reg: - .asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n" \ - " Offset:\t\t\tvalue\n" -newline: - .asciz "\n" -spacer: - .asciz ":\t\t0x" - - /* --------------------------------------------- - * The below utility macro prints out relevant GIC - * registers whenever an unhandled exception is - * taken in BL31 on ARM standard platforms. - * Expects: GICD base in x16, GICC base in x17 - * Clobbers: x0 - x10, sp - * --------------------------------------------- - */ - .macro marvell_print_gic_regs - /* Check for GICv3 system register access */ - mrs x7, id_aa64pfr0_el1 - ubfx x7, x7, #ID_AA64PFR0_GIC_SHIFT, #ID_AA64PFR0_GIC_WIDTH - cmp x7, #1 - b.ne print_gicv2 - - /* Check for SRE enable */ - mrs x8, ICC_SRE_EL3 - tst x8, #ICC_SRE_SRE_BIT - b.eq print_gicv2 - -#ifdef USE_CCI - /* Load the icc reg list to x6 */ - adr x6, icc_regs - /* Load the icc regs to gp regs used by str_in_crash_buf_print */ - mrs x8, ICC_HPPIR0_EL1 - mrs x9, ICC_HPPIR1_EL1 - mrs x10, ICC_CTLR_EL3 - /* Store to the crash buf and print to console */ - bl str_in_crash_buf_print -#endif - b print_gic_common - -print_gicv2: - /* Load the gicc reg list to x6 */ - adr x6, gicc_regs - /* Load the gicc regs to gp regs used by str_in_crash_buf_print */ - ldr w8, [x17, #GICC_HPPIR] - ldr w9, [x17, #GICC_AHPPIR] - ldr w10, [x17, #GICC_CTLR] - /* Store to the crash buf and print to console */ - bl str_in_crash_buf_print - -print_gic_common: - /* Print the GICD_ISPENDR regs */ - add x7, x16, #GICD_ISPENDR - adr x4, gicd_pend_reg - bl asm_print_str -gicd_ispendr_loop: - sub x4, x7, x16 - cmp x4, #0x280 - b.eq exit_print_gic_regs - bl asm_print_hex - - adr x4, spacer - bl asm_print_str - - ldr x4, [x7], #8 - bl asm_print_hex - - adr x4, newline - bl asm_print_str - b gicd_ispendr_loop -exit_print_gic_regs: - .endm - - -.section .rodata.cci_reg_name, "aS" -cci_iface_regs: - .asciz "cci_snoop_ctrl_cluster0", "cci_snoop_ctrl_cluster1" , "" - - /* ------------------------------------------------ - * The below required platform porting macro prints - * out relevant interconnect registers whenever an - * unhandled exception is taken in BL31. - * Clobbers: x0 - x9, sp - * ------------------------------------------------ - */ - .macro print_cci_regs -#ifdef USE_CCI - adr x6, cci_iface_regs - /* Store in x7 the base address of the first interface */ - mov_imm x7, (PLAT_MARVELL_CCI_BASE + SLAVE_IFACE_OFFSET( \ - PLAT_MARVELL_CCI_CLUSTER0_SL_IFACE_IX)) - ldr w8, [x7, #SNOOP_CTRL_REG] - /* Store in x7 the base address of the second interface */ - mov_imm x7, (PLAT_MARVELL_CCI_BASE + SLAVE_IFACE_OFFSET( \ - PLAT_MARVELL_CCI_CLUSTER1_SL_IFACE_IX)) - ldr w9, [x7, #SNOOP_CTRL_REG] - /* Store to the crash buf and print to console */ - bl str_in_crash_buf_print -#endif - .endm - - -#endif /* MARVELL_MACROS_S */ diff --git a/include/plat/marvell/common/marvell_plat_priv.h b/include/plat/marvell/common/marvell_plat_priv.h deleted file mode 100644 index 78b5331e4..000000000 --- a/include/plat/marvell/common/marvell_plat_priv.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef MARVELL_PLAT_PRIV_H -#define MARVELL_PLAT_PRIV_H - -#include - -/***************************************************************************** - * Function and variable prototypes - ***************************************************************************** - */ -void plat_delay_timer_init(void); - -uint64_t mvebu_get_dram_size(uint64_t ap_base_addr); - -/* - * GIC operation, mandatory functions required in Marvell standard platforms - */ -void plat_marvell_gic_driver_init(void); -void plat_marvell_gic_init(void); -void plat_marvell_gic_cpuif_enable(void); -void plat_marvell_gic_cpuif_disable(void); -void plat_marvell_gic_pcpu_init(void); -void plat_marvell_gic_irq_save(void); -void plat_marvell_gic_irq_restore(void); -void plat_marvell_gic_irq_pcpu_save(void); -void plat_marvell_gic_irq_pcpu_restore(void); - -#endif /* MARVELL_PLAT_PRIV_H */ diff --git a/include/plat/marvell/common/marvell_pm.h b/include/plat/marvell/common/marvell_pm.h deleted file mode 100644 index 8f1660755..000000000 --- a/include/plat/marvell/common/marvell_pm.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef MARVELL_PM_H -#define MARVELL_PM_H - -#define MVEBU_MAILBOX_MAGIC_NUM PLAT_MARVELL_MAILBOX_MAGIC_NUM -#define MVEBU_MAILBOX_SUSPEND_STATE 0xb007de7c - -/* Mailbox entry indexes */ -/* Magic number for validity check */ -#define MBOX_IDX_MAGIC 0 -/* Recovery from suspend entry point */ -#define MBOX_IDX_SEC_ADDR 1 -/* Suspend state magic number */ -#define MBOX_IDX_SUSPEND_MAGIC 2 -/* Recovery jump address for ROM bypass */ -#define MBOX_IDX_ROM_EXIT_ADDR 3 -/* BLE execution start counter value */ -#define MBOX_IDX_START_CNT 4 - -#endif /* MARVELL_PM_H */ diff --git a/include/plat/marvell/common/mvebu.h b/include/plat/marvell/common/mvebu.h deleted file mode 100644 index 35a0200ad..000000000 --- a/include/plat/marvell/common/mvebu.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef MVEBU_H -#define MVEBU_H - -/* Use this functions only when printf is allowed */ -#define debug_enter() VERBOSE("----> Enter %s\n", __func__) -#define debug_exit() VERBOSE("<---- Exit %s\n", __func__) - -/* Macro for testing alignment. Positive if number is NOT aligned */ -#define IS_NOT_ALIGN(number, align) ((number) & ((align) - 1)) - -/* Macro for alignment up. For example, ALIGN_UP(0x0330, 0x20) = 0x0340 */ -#define ALIGN_UP(number, align) (((number) & ((align) - 1)) ? \ - (((number) + (align)) & ~((align)-1)) : (number)) - -/* Macro for testing whether a number is a power of 2. Positive if so */ -#define IS_POWER_OF_2(number) ((number) != 0 && \ - (((number) & ((number) - 1)) == 0)) - -/* - * Macro for ronding up to next power of 2 - * it is done by count leading 0 (clz assembly opcode) and see msb set bit. - * then you can shift it left and get number which power of 2 - * Note: this Macro is for 32 bit number - */ -#define ROUND_UP_TO_POW_OF_2(number) (1 << \ - (32 - __builtin_clz((number) - 1))) - -#define _1MB_ (1024ULL * 1024ULL) -#define _1GB_ (_1MB_ * 1024ULL) -#define _2GB_ (2 * _1GB_) - -#endif /* MVEBU_H */ diff --git a/plat/marvell/a3700/a3700/board/pm_src.c b/plat/marvell/a3700/a3700/board/pm_src.c deleted file mode 100644 index d6eca5d16..000000000 --- a/plat/marvell/a3700/a3700/board/pm_src.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include - -/* This struct provides the PM wake up src configuration */ -static struct pm_wake_up_src_config wake_up_src_cfg = { - .wake_up_src_num = 3, - .wake_up_src[0] = { - .wake_up_src_type = WAKE_UP_SRC_GPIO, - .wake_up_data = { - .gpio_data.bank_num = 0, /* North Bridge */ - .gpio_data.gpio_num = 14 - } - }, - .wake_up_src[1] = { - .wake_up_src_type = WAKE_UP_SRC_GPIO, - .wake_up_data = { - .gpio_data.bank_num = 1, /* South Bridge */ - .gpio_data.gpio_num = 2 - } - }, - .wake_up_src[2] = { - .wake_up_src_type = WAKE_UP_SRC_UART1, - } -}; - -struct pm_wake_up_src_config *mv_wake_up_src_config_get(void) -{ - return &wake_up_src_cfg; -} - diff --git a/plat/marvell/a3700/a3700/mvebu_def.h b/plat/marvell/a3700/a3700/mvebu_def.h deleted file mode 100644 index dad1085f8..000000000 --- a/plat/marvell/a3700/a3700/mvebu_def.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef MVEBU_DEF_H -#define MVEBU_DEF_H - -#include - -#endif /* MVEBU_DEF_H */ diff --git a/plat/marvell/a3700/a3700/plat_bl31_setup.c b/plat/marvell/a3700/a3700/plat_bl31_setup.c deleted file mode 100644 index 6862a8670..000000000 --- a/plat/marvell/a3700/a3700/plat_bl31_setup.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -#include -#include -#include -#include -#include - -/* This routine does MPP initialization */ -static void marvell_bl31_mpp_init(void) -{ - mmio_clrbits_32(MVEBU_NB_GPIO_SEL_REG, 1 << MVEBU_GPIO_TW1_GPIO_EN_OFF); - - /* Set hidden GPIO setting for SPI. - * In north_bridge_pin_out_en_high register 13804, - * bit 28 is the one which enables CS, CLK pins to be - * output, need to set it to 1. - * The initial value of this bit is 1, but in UART boot mode - * initialization, this bit is disabled and the SPI CS and CLK pins - * are used for downloading image purpose; so after downloading, - * we should set this bit to 1 again to enable SPI CS and CLK pins. - * And anyway, this bit value should be 1 in all modes, - * so here we does not judge boot mode and set this bit to 1 always. - */ - mmio_setbits_32(MVEBU_NB_GPIO_OUTPUT_EN_HIGH_REG, - 1 << MVEBU_GPIO_NB_SPI_PIN_MODE_OFF); -} - -/* This function overruns the same function in marvell_bl31_setup.c */ -void bl31_plat_arch_setup(void) -{ - struct dec_win_config *io_dec_map; - uint32_t dec_win_num; - struct dram_win_map dram_wins_map; - - marvell_bl31_plat_arch_setup(); - - /* MPP init */ - marvell_bl31_mpp_init(); - - /* initialize the timer for delay functionality */ - plat_delay_timer_init(); - - /* CPU address decoder windows initialization. */ - cpu_wins_init(); - - /* fetch CPU-DRAM window mapping information by reading - * CPU-DRAM decode windows (only the enabled ones) - */ - dram_win_map_build(&dram_wins_map); - - /* Get IO address decoder windows */ - if (marvell_get_io_dec_win_conf(&io_dec_map, &dec_win_num)) { - printf("No IO address decoder windows configurations found!\n"); - return; - } - - /* IO address decoder init */ - if (init_io_addr_dec(&dram_wins_map, io_dec_map, dec_win_num)) { - printf("IO address decoder windows initialization failed!\n"); - return; - } -} diff --git a/plat/marvell/a3700/a3700/platform.mk b/plat/marvell/a3700/a3700/platform.mk deleted file mode 100644 index 4f7ac08c4..000000000 --- a/plat/marvell/a3700/a3700/platform.mk +++ /dev/null @@ -1,10 +0,0 @@ -# -# Copyright (C) 2018 Marvell International Ltd. -# -# SPDX-License-Identifier: BSD-3-Clause -# https://spdx.org/licenses -# - -include plat/marvell/a3700/common/a3700_common.mk - -include plat/marvell/common/marvell_common.mk diff --git a/plat/marvell/a3700/common/a3700_common.mk b/plat/marvell/a3700/common/a3700_common.mk deleted file mode 100644 index 76c067747..000000000 --- a/plat/marvell/a3700/common/a3700_common.mk +++ /dev/null @@ -1,170 +0,0 @@ -# -# Copyright (C) 2018 Marvell International Ltd. -# -# SPDX-License-Identifier: BSD-3-Clause -# https://spdx.org/licenses -# - -MARVELL_PLAT_BASE := plat/marvell -MARVELL_PLAT_INCLUDE_BASE := include/plat/marvell -PLAT_FAMILY := a3700 -PLAT_FAMILY_BASE := $(MARVELL_PLAT_BASE)/$(PLAT_FAMILY) -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 $(MARVELL_PLAT_BASE)/marvell.mk - -#*********** A3700 ************* -DOIMAGEPATH := $(WTP) -DOIMAGETOOL := $(DOIMAGEPATH)/wtptp/linux/tbb_linux - -ifeq ($(MARVELL_SECURE_BOOT),1) -DOIMAGE_CFG := $(DOIMAGEPATH)/atf-tim.txt -IMAGESPATH := $(DOIMAGEPATH)/tim/trusted - -TIMNCFG := $(DOIMAGEPATH)/atf-timN.txt -TIMNSIG := $(IMAGESPATH)/timnsign.txt -TIM2IMGARGS := -i $(DOIMAGE_CFG) -n $(TIMNCFG) -TIMN_IMAGE := $$(grep "Image Filename:" -m 1 $(TIMNCFG) | cut -c 17-) -else #MARVELL_SECURE_BOOT -DOIMAGE_CFG := $(DOIMAGEPATH)/atf-ntim.txt -IMAGESPATH := $(DOIMAGEPATH)/tim/untrusted -TIM2IMGARGS := -i $(DOIMAGE_CFG) -endif #MARVELL_SECURE_BOOT - -TIMBUILD := $(DOIMAGEPATH)/script/buildtim.sh -TIM2IMG := $(DOIMAGEPATH)/script/tim2img.pl - -# WTMI_IMG is used to specify the customized RTOS image running over -# Service CPU (CM3 processor). By the default, it points to a -# baremetal binary of fuse programming in A3700_utils. -WTMI_IMG := $(DOIMAGEPATH)/wtmi/fuse/build/fuse.bin - -# WTMI_SYSINIT_IMG is used for the system early initialization, -# such as AVS settings, clock-tree setup and dynamic DDR PHY training. -# After the initialization is done, this image will be wiped out -# from the memory and CM3 will continue with RTOS image or other application. -WTMI_SYSINIT_IMG := $(DOIMAGEPATH)/wtmi/sys_init/build/sys_init.bin - -# WTMI_MULTI_IMG is composed of CM3 RTOS image (WTMI_IMG) -# and sys-init image (WTMI_SYSINIT_IMG). -WTMI_MULTI_IMG := $(DOIMAGEPATH)/wtmi/build/wtmi.bin - -WTMI_ENC_IMG := $(DOIMAGEPATH)/wtmi/build/wtmi-enc.bin -BUILD_UART := uart-images - -SRCPATH := $(dir $(BL33)) - -CLOCKSPRESET ?= CPU_800_DDR_800 - -DDR_TOPOLOGY ?= 0 - -BOOTDEV ?= SPINOR -PARTNUM ?= 0 - -TIM_IMAGE := $$(grep "Image Filename:" -m 1 $(DOIMAGE_CFG) | cut -c 17-) -TIMBLDARGS := $(MARVELL_SECURE_BOOT) $(BOOTDEV) $(IMAGESPATH) $(DOIMAGEPATH) $(CLOCKSPRESET) \ - $(DDR_TOPOLOGY) $(PARTNUM) $(DEBUG) $(DOIMAGE_CFG) $(TIMNCFG) $(TIMNSIG) 1 -TIMBLDUARTARGS := $(MARVELL_SECURE_BOOT) UART $(IMAGESPATH) $(DOIMAGEPATH) $(CLOCKSPRESET) \ - $(DDR_TOPOLOGY) 0 0 $(DOIMAGE_CFG) $(TIMNCFG) $(TIMNSIG) 0 -DOIMAGE_FLAGS := -r $(DOIMAGE_CFG) -v -D - -# GICV3 -$(eval $(call add_define,CONFIG_GICV3)) - -# CCI-400 -$(eval $(call add_define,USE_CCI)) - -# Include GICv3 driver files -include drivers/arm/gic/v3/gicv3.mk - -MARVELL_GIC_SOURCES := ${GICV3_SOURCES} \ - plat/common/plat_gicv3.c - -PLAT_INCLUDES := -I$(PLAT_FAMILY_BASE)/$(PLAT) \ - -I$(PLAT_COMMON_BASE)/include \ - -I$(PLAT_INCLUDE_BASE)/common \ - -I$(MARVELL_DRV_BASE) \ - -I$/drivers/arm/gic/common/ - -PLAT_BL_COMMON_SOURCES := $(PLAT_COMMON_BASE)/aarch64/a3700_common.c \ - $(MARVELL_COMMON_BASE)/marvell_cci.c \ - $(MARVELL_DRV_BASE)/uart/a3700_console.S - -BL1_SOURCES += $(PLAT_COMMON_BASE)/aarch64/plat_helpers.S \ - lib/cpus/aarch64/cortex_a53.S - -BL31_PORTING_SOURCES := $(PLAT_FAMILY_BASE)/$(PLAT)/board/pm_src.c - -MARVELL_DRV := $(MARVELL_DRV_BASE)/comphy/phy-comphy-3700.c - -BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \ - $(PLAT_COMMON_BASE)/aarch64/plat_helpers.S \ - $(PLAT_COMMON_BASE)/plat_pm.c \ - $(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_ddr_info.c \ - $(MARVELL_COMMON_BASE)/marvell_gicv3.c \ - $(MARVELL_GIC_SOURCES) \ - drivers/arm/cci/cci.c \ - $(BL31_PORTING_SOURCES) \ - $(PLAT_COMMON_BASE)/a3700_sip_svc.c \ - $(MARVELL_DRV) - -mrvl_flash: ${BUILD_PLAT}/${FIP_NAME} ${DOIMAGETOOL} - $(shell truncate -s %128K ${BUILD_PLAT}/bl1.bin) - $(shell cat ${BUILD_PLAT}/bl1.bin ${BUILD_PLAT}/${FIP_NAME} > ${BUILD_PLAT}/${BOOT_IMAGE}) - $(shell truncate -s %4 ${BUILD_PLAT}/${BOOT_IMAGE}) - $(shell truncate -s %4 $(WTMI_IMG)) - @echo - @echo "Building uart images" - $(TIMBUILD) $(TIMBLDUARTARGS) - @sed -i 's|WTMI_IMG|$(WTMI_MULTI_IMG)|1' $(DOIMAGE_CFG) - @sed -i 's|BOOT_IMAGE|$(BUILD_PLAT)/$(BOOT_IMAGE)|1' $(DOIMAGE_CFG) -ifeq ($(MARVELL_SECURE_BOOT),1) - @sed -i 's|WTMI_IMG|$(WTMI_MULTI_IMG)|1' $(TIMNCFG) - @sed -i 's|BOOT_IMAGE|$(BUILD_PLAT)/$(BOOT_IMAGE)|1' $(TIMNCFG) -endif - $(DOIMAGETOOL) $(DOIMAGE_FLAGS) - @if [ -e "$(TIMNCFG)" ]; then $(DOIMAGETOOL) -r $(TIMNCFG); fi - @rm -rf $(BUILD_PLAT)/$(BUILD_UART)* - @mkdir $(BUILD_PLAT)/$(BUILD_UART) - @mv -t $(BUILD_PLAT)/$(BUILD_UART) $(TIM_IMAGE) $(DOIMAGE_CFG) $(TIMN_IMAGE) $(TIMNCFG) - @find . -name "*_h.*" |xargs cp -ut $(BUILD_PLAT)/$(BUILD_UART) - @mv $(subst .bin,_h.bin,$(WTMI_MULTI_IMG)) $(BUILD_PLAT)/$(BUILD_UART)/wtmi_h.bin - @tar czf $(BUILD_PLAT)/$(BUILD_UART).tgz -C $(BUILD_PLAT) ./$(BUILD_UART) - @echo - @echo "Building flash image" - $(TIMBUILD) $(TIMBLDARGS) - sed -i 's|WTMI_IMG|$(WTMI_MULTI_IMG)|1' $(DOIMAGE_CFG) - sed -i 's|BOOT_IMAGE|$(BUILD_PLAT)/$(BOOT_IMAGE)|1' $(DOIMAGE_CFG) -ifeq ($(MARVELL_SECURE_BOOT),1) - @sed -i 's|WTMI_IMG|$(WTMI_MULTI_IMG)|1' $(TIMNCFG) - @sed -i 's|BOOT_IMAGE|$(BUILD_PLAT)/$(BOOT_IMAGE)|1' $(TIMNCFG) - @echo -e "\n\t=======================================================\n"; - @echo -e "\t Secure boot. Encrypting wtmi and boot-image \n"; - @echo -e "\t=======================================================\n"; - @truncate -s %16 $(WTMI_MULTI_IMG) - @openssl enc -aes-256-cbc -e -in $(WTMI_MULTI_IMG) \ - -out $(WTMI_ENC_IMG) \ - -K `cat $(IMAGESPATH)/aes-256.txt` -nosalt \ - -iv `cat $(IMAGESPATH)/iv.txt` -p - @truncate -s %16 $(BUILD_PLAT)/$(BOOT_IMAGE); - @openssl enc -aes-256-cbc -e -in $(BUILD_PLAT)/$(BOOT_IMAGE) \ - -out $(BUILD_PLAT)/$(BOOT_ENC_IMAGE) \ - -K `cat $(IMAGESPATH)/aes-256.txt` -nosalt \ - -iv `cat $(IMAGESPATH)/iv.txt` -p -endif - $(DOIMAGETOOL) $(DOIMAGE_FLAGS) - @if [ -e "$(TIMNCFG)" ]; then $(DOIMAGETOOL) -r $(TIMNCFG); fi - @if [ "$(MARVELL_SECURE_BOOT)" = "1" ]; then sed -i 's|$(WTMI_MULTI_IMG)|$(WTMI_ENC_IMG)|1;s|$(BOOT_IMAGE)|$(BOOT_ENC_IMAGE)|1;' $(TIMNCFG); fi - $(TIM2IMG) $(TIM2IMGARGS) -o $(BUILD_PLAT)/$(FLASH_IMAGE) - @mv -t $(BUILD_PLAT) $(TIM_IMAGE) $(DOIMAGE_CFG) $(TIMN_IMAGE) $(TIMNCFG) $(WTMI_IMG) $(WTMI_SYSINIT_IMG) $(WTMI_MULTI_IMG) - @if [ "$(MARVELL_SECURE_BOOT)" = "1" ]; then mv -t $(BUILD_PLAT) $(WTMI_ENC_IMG) OtpHash.txt; fi - @find . -name "*.txt" | grep -E "CSK[[:alnum:]]_KeyHash.txt|Tim_msg.txt|TIMHash.txt" | xargs rm -f diff --git a/plat/marvell/a3700/common/a3700_ea.c b/plat/marvell/a3700/common/a3700_ea.c deleted file mode 100644 index dd46beb55..000000000 --- a/plat/marvell/a3700/common/a3700_ea.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2019 Repk repk@triplefau.lt - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ -#include -#include -#include - -#define ADVK_SERROR_SYNDROME 0xbf000002 - -void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie, - void *handle, uint64_t flags) -{ - if (syndrome != ADVK_SERROR_SYNDROME) { - ERROR("Unhandled External Abort received on 0x%lx at EL3!\n", - read_mpidr_el1()); - ERROR(" exception reason=%u syndrome=0x%llx\n", ea_reason, - syndrome); - panic(); - } -} diff --git a/plat/marvell/a3700/common/a3700_sip_svc.c b/plat/marvell/a3700/common/a3700_sip_svc.c deleted file mode 100644 index e8ac5fc08..000000000 --- a/plat/marvell/a3700/common/a3700_sip_svc.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include -#include - -#include -#include - -#include "comphy/phy-comphy-3700.h" - -/* Comphy related FID's */ -#define MV_SIP_COMPHY_POWER_ON 0x82000001 -#define MV_SIP_COMPHY_POWER_OFF 0x82000002 -#define MV_SIP_COMPHY_PLL_LOCK 0x82000003 - -/* Miscellaneous FID's' */ -#define MV_SIP_DRAM_SIZE 0x82000010 - -/* This macro is used to identify COMPHY related calls from SMC function ID */ -#define is_comphy_fid(fid) \ - ((fid) >= MV_SIP_COMPHY_POWER_ON && (fid) <= MV_SIP_COMPHY_PLL_LOCK) - -uintptr_t mrvl_sip_smc_handler(uint32_t smc_fid, - u_register_t x1, - u_register_t x2, - u_register_t x3, - u_register_t x4, - void *cookie, - void *handle, - u_register_t flags) -{ - u_register_t ret; - - VERBOSE("%s: got SMC (0x%x) x1 0x%lx, x2 0x%lx\n", - __func__, smc_fid, x1, x2); - if (is_comphy_fid(smc_fid)) { - if (x1 >= MAX_LANE_NR) { - ERROR("%s: Wrong smc (0x%x) lane nr: %lx\n", - __func__, smc_fid, x2); - SMC_RET1(handle, SMC_UNK); - } - } - - switch (smc_fid) { - /* Comphy related FID's */ - case MV_SIP_COMPHY_POWER_ON: - /* x1: comphy_index, x2: comphy_mode */ - ret = mvebu_3700_comphy_power_on(x1, x2); - SMC_RET1(handle, ret); - case MV_SIP_COMPHY_POWER_OFF: - /* x1: comphy_index, x2: comphy_mode */ - ret = mvebu_3700_comphy_power_off(x1, x2); - SMC_RET1(handle, ret); - case MV_SIP_COMPHY_PLL_LOCK: - /* x1: comphy_index, x2: comphy_mode */ - ret = mvebu_3700_comphy_is_pll_locked(x1, x2); - SMC_RET1(handle, ret); - /* Miscellaneous FID's' */ - case MV_SIP_DRAM_SIZE: - /* x1: ap_base_addr */ - ret = mvebu_get_dram_size(MVEBU_REGS_BASE); - SMC_RET1(handle, ret); - - default: - ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid); - SMC_RET1(handle, SMC_UNK); - } -} - -/* Define a runtime service descriptor for fast SMC calls */ -DECLARE_RT_SVC( - marvell_sip_svc, - OEN_SIP_START, - OEN_SIP_END, - SMC_TYPE_FAST, - NULL, - mrvl_sip_smc_handler -); diff --git a/plat/marvell/a3700/common/aarch64/a3700_common.c b/plat/marvell/a3700/common/aarch64/a3700_common.c deleted file mode 100644 index 63512853c..000000000 --- a/plat/marvell/a3700/common/aarch64/a3700_common.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ -#include - -/* MMU entry for internal (register) space access */ -#define MAP_DEVICE0 MAP_REGION_FLAT(DEVICE0_BASE, \ - DEVICE0_SIZE, \ - MT_DEVICE | MT_RW | MT_SECURE) - -/* - * Table of regions for various BL stages to map using the MMU. - */ -#if IMAGE_BL1 -const mmap_region_t plat_marvell_mmap[] = { - MARVELL_MAP_SHARED_RAM, - MAP_DEVICE0, - {0} -}; -#endif -#if IMAGE_BL2 -const mmap_region_t plat_marvell_mmap[] = { - MARVELL_MAP_SHARED_RAM, - MAP_DEVICE0, - MARVELL_MAP_DRAM, - {0} -}; -#endif -#if IMAGE_BL2U -const mmap_region_t plat_marvell_mmap[] = { - MAP_DEVICE0, - {0} -}; -#endif -#if IMAGE_BL31 -const mmap_region_t plat_marvell_mmap[] = { - MARVELL_MAP_SHARED_RAM, - MAP_DEVICE0, - MARVELL_MAP_DRAM, - {0} -}; -#endif -#if IMAGE_BL32 -const mmap_region_t plat_marvell_mmap[] = { - MAP_DEVICE0, - {0} -}; -#endif - -MARVELL_CASSERT_MMAP; diff --git a/plat/marvell/a3700/common/aarch64/plat_helpers.S b/plat/marvell/a3700/common/aarch64/plat_helpers.S deleted file mode 100644 index 90d76f08e..000000000 --- a/plat/marvell/a3700/common/aarch64/plat_helpers.S +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include - - .globl plat_secondary_cold_boot_setup - .globl plat_get_my_entrypoint - .globl plat_is_my_cpu_primary - - /* ----------------------------------------------------- - * void plat_secondary_cold_boot_setup (void); - * - * This function performs any platform specific actions - * needed for a secondary cpu after a cold reset. Right - * now this is a stub function. - * ----------------------------------------------------- - */ -func plat_secondary_cold_boot_setup - mov x0, #0 - ret -endfunc plat_secondary_cold_boot_setup - - /* --------------------------------------------------------------------- - * unsigned long plat_get_my_entrypoint (void); - * - * Main job of this routine is to distinguish between cold and warm boot - * For a cold boot, return 0. - * For a warm boot, read the mailbox and return the address it contains. - * A magic number is placed before entrypoint to avoid mistake caused by - * uninitialized mailbox data area. - * --------------------------------------------------------------------- - */ -func plat_get_my_entrypoint - /* Read first word and compare it with magic num */ - mov_imm x0, PLAT_MARVELL_MAILBOX_BASE - ldr x1, [x0] - mov_imm x2, PLAT_MARVELL_MAILBOX_MAGIC_NUM - cmp x1, x2 - /* If compare failed, return 0, i.e. cold boot */ - beq entrypoint - mov x0, #0 - ret -entrypoint: - /* Second word contains the jump address */ - add x0, x0, #8 - ldr x0, [x0] - ret -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 - and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK) - cmp x0, #MVEBU_PRIMARY_CPU - cset w0, eq - ret -endfunc plat_is_my_cpu_primary diff --git a/plat/marvell/a3700/common/dram_win.c b/plat/marvell/a3700/common/dram_win.c deleted file mode 100644 index 694f6d480..000000000 --- a/plat/marvell/a3700/common/dram_win.c +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -#include - -#include -#include -#include -#include - -/* Armada 3700 has 5 configurable windows */ -#define MV_CPU_WIN_NUM 5 - -#define CPU_WIN_DISABLED 0 -#define CPU_WIN_ENABLED 1 - -/* - * There are 2 different cpu decode window configuration cases: - * - DRAM size is not over 2GB; - * - DRAM size is 4GB. - */ -enum cpu_win_config_num { - CPU_WIN_CONFIG_DRAM_NOT_OVER_2GB = 0, - CPU_WIN_CONFIG_DRAM_4GB, - CPU_WIN_CONFIG_MAX -}; - -enum cpu_win_target { - CPU_WIN_TARGET_DRAM = 0, - CPU_WIN_TARGET_INTERNAL_REG, - CPU_WIN_TARGET_PCIE, - CPU_WIN_TARGET_PCIE_OVER_MCI, - CPU_WIN_TARGET_BOOT_ROM, - CPU_WIN_TARGET_MCI_EXTERNAL, - CPU_WIN_TARGET_RWTM_RAM = 7, - CPU_WIN_TARGET_CCI400_REG -}; - -struct cpu_win_configuration { - uint32_t enabled; - enum cpu_win_target target; - uint64_t base_addr; - uint64_t size; - uint64_t remap_addr; -}; - -struct cpu_win_configuration mv_cpu_wins[CPU_WIN_CONFIG_MAX][MV_CPU_WIN_NUM] = { - /* - * When total dram size is not over 2GB: - * DDR window 0 is configured in tim header, its size may be not 512MB, - * but the actual dram size, no need to configure it again; - * other cpu windows are kept as default. - */ - { - /* enabled - * target - * base - * size - * remap - */ - {CPU_WIN_ENABLED, - CPU_WIN_TARGET_DRAM, - 0x0, - 0x08000000, - 0x0}, - {CPU_WIN_ENABLED, - CPU_WIN_TARGET_MCI_EXTERNAL, - 0xe0000000, - 0x08000000, - 0xe0000000}, - {CPU_WIN_ENABLED, - CPU_WIN_TARGET_PCIE, - 0xe8000000, - 0x08000000, - 0xe8000000}, - {CPU_WIN_ENABLED, - CPU_WIN_TARGET_RWTM_RAM, - 0xf0000000, - 0x00020000, - 0x1fff0000}, - {CPU_WIN_ENABLED, - CPU_WIN_TARGET_PCIE_OVER_MCI, - 0x80000000, - 0x10000000, - 0x80000000}, - }, - - /* - * If total dram size is more than 2GB, now there is only one case - 4GB - * dram; we will use below cpu windows configurations: - * - Internal Regs, CCI-400, Boot Rom and PCIe windows are kept as - * default; - * - Use 4 CPU decode windows for DRAM, which cover 3.375GB DRAM; - * DDR window 0 is configured in tim header with 2GB size, no need to - * configure it again here; - * - * 0xFFFFFFFF ---> |-----------------------| - * | Boot ROM | 64KB - * 0xFFF00000 ---> +-----------------------+ - * : : - * 0xF0000000 ---> |-----------------------| - * | PCIE | 128 MB - * 0xE8000000 ---> |-----------------------| - * | DDR window 3 | 128 MB - * 0xE0000000 ---> +-----------------------+ - * : : - * 0xD8010000 ---> |-----------------------| - * | CCI Regs | 64 KB - * 0xD8000000 ---> +-----------------------+ - * : : - * : : - * 0xD2000000 ---> +-----------------------+ - * | Internal Regs | 32MB - * 0xD0000000 ---> |-----------------------| - * | DDR window 2 | 256 MB - * 0xC0000000 ---> |-----------------------| - * | | - * | DDR window 1 | 1 GB - * | | - * 0x80000000 ---> |-----------------------| - * | | - * | | - * | DDR window 0 | 2 GB - * | | - * | | - * 0x00000000 ---> +-----------------------+ - */ - { - /* win_id - * target - * base - * size - * remap - */ - {CPU_WIN_ENABLED, - CPU_WIN_TARGET_DRAM, - 0x0, - 0x80000000, - 0x0}, - {CPU_WIN_ENABLED, - CPU_WIN_TARGET_DRAM, - 0x80000000, - 0x40000000, - 0x80000000}, - {CPU_WIN_ENABLED, - CPU_WIN_TARGET_DRAM, - 0xc0000000, - 0x10000000, - 0xc0000000}, - {CPU_WIN_ENABLED, - CPU_WIN_TARGET_DRAM, - 0xe0000000, - 0x08000000, - 0xe0000000}, - {CPU_WIN_ENABLED, - CPU_WIN_TARGET_PCIE, - 0xe8000000, - 0x08000000, - 0xe8000000}, - }, -}; - -/* - * dram_win_map_build - * - * This function builds cpu dram windows mapping - * which includes base address and window size by - * reading cpu dram decode windows registers. - * - * @input: N/A - * - * @output: - * - win_map: cpu dram windows mapping - * - * @return: N/A - */ -void dram_win_map_build(struct dram_win_map *win_map) -{ - int32_t win_id; - struct dram_win *win; - uint32_t base_reg, ctrl_reg, size_reg, enabled, target; - - memset(win_map, 0, sizeof(struct dram_win_map)); - for (win_id = 0; win_id < DRAM_WIN_MAP_NUM_MAX; win_id++) { - ctrl_reg = mmio_read_32(CPU_DEC_WIN_CTRL_REG(win_id)); - target = (ctrl_reg & CPU_DEC_CR_WIN_TARGET_MASK) >> - CPU_DEC_CR_WIN_TARGET_OFFS; - enabled = ctrl_reg & CPU_DEC_CR_WIN_ENABLE; - /* Ignore invalid and non-dram windows*/ - if ((enabled == 0) || (target != DRAM_CPU_DEC_TARGET_NUM)) - continue; - - win = win_map->dram_windows + win_map->dram_win_num; - base_reg = mmio_read_32(CPU_DEC_WIN_BASE_REG(win_id)); - size_reg = mmio_read_32(CPU_DEC_WIN_SIZE_REG(win_id)); - /* Base reg [15:0] corresponds to transaction address [39:16] */ - win->base_addr = (base_reg & CPU_DEC_BR_BASE_MASK) >> - CPU_DEC_BR_BASE_OFFS; - win->base_addr *= CPU_DEC_CR_WIN_SIZE_ALIGNMENT; - /* - * Size reg [15:0] is programmed from LSB to MSB as a sequence - * of 1s followed by a sequence of 0s and the number of 1s - * specifies the size of the window in 64 KB granularity, - * for example, a value of 00FFh specifies 256 x 64 KB = 16 MB - */ - win->win_size = (size_reg & CPU_DEC_CR_WIN_SIZE_MASK) >> - CPU_DEC_CR_WIN_SIZE_OFFS; - win->win_size = (win->win_size + 1) * - CPU_DEC_CR_WIN_SIZE_ALIGNMENT; - - win_map->dram_win_num++; - } -} - -static void cpu_win_set(uint32_t win_id, struct cpu_win_configuration *win_cfg) -{ - uint32_t base_reg, ctrl_reg, size_reg, remap_reg; - - /* Disable window */ - ctrl_reg = mmio_read_32(CPU_DEC_WIN_CTRL_REG(win_id)); - ctrl_reg &= ~CPU_DEC_CR_WIN_ENABLE; - mmio_write_32(CPU_DEC_WIN_CTRL_REG(win_id), ctrl_reg); - - /* For an disabled window, only disable it. */ - if (!win_cfg->enabled) - return; - - /* Set Base Register */ - base_reg = (uint32_t)(win_cfg->base_addr / - CPU_DEC_CR_WIN_SIZE_ALIGNMENT); - base_reg <<= CPU_DEC_BR_BASE_OFFS; - base_reg &= CPU_DEC_BR_BASE_MASK; - mmio_write_32(CPU_DEC_WIN_BASE_REG(win_id), base_reg); - - /* Set Remap Register with the same value - * as the field in Base Register - */ - remap_reg = (uint32_t)(win_cfg->remap_addr / - CPU_DEC_CR_WIN_SIZE_ALIGNMENT); - remap_reg <<= CPU_DEC_RLR_REMAP_LOW_OFFS; - remap_reg &= CPU_DEC_RLR_REMAP_LOW_MASK; - mmio_write_32(CPU_DEC_REMAP_LOW_REG(win_id), remap_reg); - - /* Set Size Register */ - size_reg = (win_cfg->size / CPU_DEC_CR_WIN_SIZE_ALIGNMENT) - 1; - size_reg <<= CPU_DEC_CR_WIN_SIZE_OFFS; - size_reg &= CPU_DEC_CR_WIN_SIZE_MASK; - mmio_write_32(CPU_DEC_WIN_SIZE_REG(win_id), size_reg); - - /* Set Control Register - set target id and enable window */ - ctrl_reg &= ~CPU_DEC_CR_WIN_TARGET_MASK; - ctrl_reg |= (win_cfg->target << CPU_DEC_CR_WIN_TARGET_OFFS); - ctrl_reg |= CPU_DEC_CR_WIN_ENABLE; - mmio_write_32(CPU_DEC_WIN_CTRL_REG(win_id), ctrl_reg); -} - -void cpu_wins_init(void) -{ - uint32_t cfg_idx, win_id; - - if (mvebu_get_dram_size(MVEBU_REGS_BASE) <= _2GB_) - cfg_idx = CPU_WIN_CONFIG_DRAM_NOT_OVER_2GB; - else - cfg_idx = CPU_WIN_CONFIG_DRAM_4GB; - - /* Window 0 is configured always for DRAM in tim header - * already, no need to configure it again here - */ - for (win_id = 1; win_id < MV_CPU_WIN_NUM; win_id++) - cpu_win_set(win_id, &mv_cpu_wins[cfg_idx][win_id]); -} - diff --git a/plat/marvell/a3700/common/include/a3700_plat_def.h b/plat/marvell/a3700/common/include/a3700_plat_def.h deleted file mode 100644 index c7f40adc3..000000000 --- a/plat/marvell/a3700/common/include/a3700_plat_def.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef A3700_PLAT_DEF_H -#define A3700_PLAT_DEF_H - -#include - - -#define MVEBU_MAX_CPUS_PER_CLUSTER 2 - -#define MVEBU_PRIMARY_CPU 0x0 - -/* - * The counter on A3700 is always fed from reference 25M clock (XTAL). - * However minimal CPU counter prescaler is 2, so the counter - * frequency will be divided by 2, the number is 12.5M - */ -#define COUNTER_FREQUENCY 12500000 - -#define MVEBU_REGS_BASE 0xD0000000 - -/***************************************************************************** - * MVEBU memory map related constants - ***************************************************************************** - */ -/* Aggregate of all devices in the first GB */ -#define DEVICE0_BASE MVEBU_REGS_BASE -#define DEVICE0_SIZE 0x10000000 - -/***************************************************************************** - * GIC-500 & interrupt handling related constants - ***************************************************************************** - */ -/* Base MVEBU compatible GIC memory map */ -#define MVEBU_GICD_BASE 0x1D00000 -#define MVEBU_GICR_BASE 0x1D40000 -#define MVEBU_GICC_BASE 0x1D80000 - -/* CCI-400 */ -#define MVEBU_CCI_BASE 0x8000000 - -/***************************************************************************** - * North and south bridge register base - ***************************************************************************** - */ -#define MVEBU_NB_REGS_BASE (MVEBU_REGS_BASE + 0x13000) -#define MVEBU_SB_REGS_BASE (MVEBU_REGS_BASE + 0x18000) - -/***************************************************************************** - * GPIO registers related constants - ***************************************************************************** - */ -/* North and south bridge GPIO register base address */ -#define MVEBU_NB_GPIO_REG_BASE (MVEBU_NB_REGS_BASE + 0x800) -#define MVEBU_NB_GPIO_IRQ_REG_BASE (MVEBU_NB_REGS_BASE + 0xC00) -#define MVEBU_SB_GPIO_REG_BASE (MVEBU_SB_REGS_BASE + 0x800) -#define MVEBU_SB_GPIO_IRQ_REG_BASE (MVEBU_SB_REGS_BASE + 0xC00) -#define MVEBU_NB_SB_IRQ_REG_BASE (MVEBU_REGS_BASE + 0x8A00) - -/* North Bridge GPIO selection register */ -#define MVEBU_NB_GPIO_SEL_REG (MVEBU_NB_GPIO_REG_BASE + 0x30) -#define MVEBU_NB_GPIO_OUTPUT_EN_HIGH_REG (MVEBU_NB_GPIO_REG_BASE + 0x04) -/* I2C1 GPIO Enable bit offset */ -#define MVEBU_GPIO_TW1_GPIO_EN_OFF (10) -/* SPI pins mode bit offset */ -#define MVEBU_GPIO_NB_SPI_PIN_MODE_OFF (28) - -/***************************************************************************** - * DRAM registers related constants - ***************************************************************************** - */ -#define MVEBU_DRAM_REG_BASE (MVEBU_REGS_BASE) - -/***************************************************************************** - * SB wake-up registers related constants - ***************************************************************************** - */ -#define MVEBU_SB_WAKEUP_REG_BASE (MVEBU_REGS_BASE + 0x19000) - -/***************************************************************************** - * PMSU registers related constants - ***************************************************************************** - */ -#define MVEBU_PMSU_REG_BASE (MVEBU_REGS_BASE + 0x14000) - -/***************************************************************************** - * North Bridge Step-Down Registers - ***************************************************************************** - */ -#define MVEBU_NB_STEP_DOWN_REG_BASE (MVEBU_REGS_BASE + 0x12800) - -/***************************************************************************** - * DRAM CS memory map register base - ***************************************************************************** - */ -#define MVEBU_CS_MMAP_REG_BASE (MVEBU_REGS_BASE + 0x200) - -/***************************************************************************** - * CPU decoder window registers related constants - ***************************************************************************** - */ -#define MVEBU_CPU_DEC_WIN_REG_BASE (MVEBU_REGS_BASE + 0xCF00) - -/***************************************************************************** - * AVS registers related constants - ***************************************************************************** - */ -#define MVEBU_AVS_REG_BASE (MVEBU_REGS_BASE + 0x11500) - - -/***************************************************************************** - * AVS registers related constants - ***************************************************************************** - */ -#define MVEBU_COMPHY_REG_BASE (MVEBU_REGS_BASE + 0x18300) - -#endif /* A3700_PLAT_DEF_H */ diff --git a/plat/marvell/a3700/common/include/a3700_pm.h b/plat/marvell/a3700/common/include/a3700_pm.h deleted file mode 100644 index cc6cf436a..000000000 --- a/plat/marvell/a3700/common/include/a3700_pm.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2016 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef A3700_PM_H -#define A3700_PM_H - -#include - -/* supported wake up sources */ -enum pm_wake_up_src_type { - WAKE_UP_SRC_GPIO, - /* FOLLOWING SRC NOT SUPPORTED YET */ - WAKE_UP_SRC_TIMER, - WAKE_UP_SRC_UART0, - WAKE_UP_SRC_UART1, - WAKE_UP_SRC_MAX, -}; - -struct pm_gpio_data { - /* - * bank 0: North bridge GPIO - * bank 1: South bridge GPIO - */ - uint32_t bank_num; - uint32_t gpio_num; -}; - -union pm_wake_up_src_data { - struct pm_gpio_data gpio_data; - /* delay in seconds */ - uint32_t timer_delay; -}; - -struct pm_wake_up_src { - enum pm_wake_up_src_type wake_up_src_type; - - union pm_wake_up_src_data wake_up_data; -}; - -struct pm_wake_up_src_config { - uint32_t wake_up_src_num; - struct pm_wake_up_src wake_up_src[WAKE_UP_SRC_MAX]; -}; - -struct pm_wake_up_src_config *mv_wake_up_src_config_get(void); - -#endif /* A3700_PM_H */ diff --git a/plat/marvell/a3700/common/include/ddr_info.h b/plat/marvell/a3700/common/include/ddr_info.h deleted file mode 100644 index 254f78c1b..000000000 --- a/plat/marvell/a3700/common/include/ddr_info.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef DDR_INFO_H -#define DDR_INFO_H - -#define DRAM_MAX_IFACE 1 -#define DRAM_CH0_MMAP_LOW_OFFSET 0x200 - -#endif /* DDR_INFO_H */ diff --git a/plat/marvell/a3700/common/include/dram_win.h b/plat/marvell/a3700/common/include/dram_win.h deleted file mode 100644 index 26a013784..000000000 --- a/plat/marvell/a3700/common/include/dram_win.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef DRAM_WIN_H -#define DRAM_WIN_H - -#include - -#include - -void dram_win_map_build(struct dram_win_map *win_map); -void cpu_wins_init(void); - -#endif /* DRAM_WIN_H */ diff --git a/plat/marvell/a3700/common/include/io_addr_dec.h b/plat/marvell/a3700/common/include/io_addr_dec.h deleted file mode 100644 index 42ef30bc2..000000000 --- a/plat/marvell/a3700/common/include/io_addr_dec.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef IO_ADDR_DEC_H -#define IO_ADDR_DEC_H - -#include - -/* There are 5 configurable cpu decoder windows. */ -#define DRAM_WIN_MAP_NUM_MAX 5 -/* Target number for dram in cpu decoder windows. */ -#define DRAM_CPU_DEC_TARGET_NUM 0 - -/* - * Not all configurable decode windows could be used for dram, some units have - * to reserve one decode window for other unit they have to communicate with; - * for example, DMA engineer has 3 configurable windows, but only two could be - * for dram while the last one has to be for pcie, so for DMA, its max_dram_win - * is 2. - */ -struct dec_win_config { - uint32_t dec_reg_base; /* IO address decoder register base address */ - uint32_t win_attr; /* IO address decoder windows attributes */ - /* How many configurable dram decoder windows that this unit has; */ - uint32_t max_dram_win; - /* The decoder windows number including remapping that this unit has */ - uint32_t max_remap; - /* The offset between continuous decode windows - * within the same unit, typically 0x10 - */ - uint32_t win_offset; -}; - -struct dram_win { - uintptr_t base_addr; - uintptr_t win_size; -}; - -struct dram_win_map { - int dram_win_num; - struct dram_win dram_windows[DRAM_WIN_MAP_NUM_MAX]; -}; - -/* - * init_io_addr_dec - * - * This function initializes io address decoder windows by - * cpu dram window mapping information - * - * @input: N/A - * - dram_wins_map: cpu dram windows mapping - * - io_dec_config: io address decoder windows configuration - * - io_unit_num: io address decoder unit number - * @output: N/A - * - * @return: 0 on success and others on failure - */ -int init_io_addr_dec(struct dram_win_map *dram_wins_map, - struct dec_win_config *io_dec_config, - uint32_t io_unit_num); - -#endif /* IO_ADDR_DEC_H */ diff --git a/plat/marvell/a3700/common/include/plat_macros.S b/plat/marvell/a3700/common/include/plat_macros.S deleted file mode 100644 index f689b4f39..000000000 --- a/plat/marvell/a3700/common/include/plat_macros.S +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef PLAT_MACROS_S -#define PLAT_MACROS_S - -#include - -/* --------------------------------------------- - * The below macro prints out relevant GIC and - * CCI registers registers whenever an unhandled - * exception is taken in BL31. - * --------------------------------------------- - */ -.macro plat_crash_print_regs - mov_imm x17, MVEBU_GICC_BASE - mov_imm x16, MVEBU_GICD_BASE - marvell_print_gic_regs - print_cci_regs -.endm - -#endif /* PLAT_MACROS_S */ diff --git a/plat/marvell/a3700/common/include/platform_def.h b/plat/marvell/a3700/common/include/platform_def.h deleted file mode 100644 index e6660d407..000000000 --- a/plat/marvell/a3700/common/include/platform_def.h +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright (C) 2016-2019 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef PLATFORM_DEF_H -#define PLATFORM_DEF_H - -#ifndef __ASSEMBLER__ -#include -#endif /* __ASSEMBLER__ */ - -#include -#include - -/* - * Most platform porting definitions provided by included headers - */ - -/* - * DRAM Memory layout: - * +-----------------------+ - * : : - * : Linux : - * 0x04X00000-->+-----------------------+ - * | BL3-3(u-boot) |>>}>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - * |-----------------------| } | - * | BL3-[0,1, 2] | }---------------------------------> | - * |-----------------------| } || | - * | BL2 | }->FIP (loaded by || | - * |-----------------------| } BootROM to DRAM) || | - * | FIP_TOC | } || | - * 0x04120000-->|-----------------------| || | - * | BL1 (RO) | || | - * 0x04100000-->+-----------------------+ || | - * : : || | - * : Trusted SRAM section : \/ | - * 0x04040000-->+-----------------------+ Replaced by BL2 +----------------+ | - * | BL1 (RW) | <<<<<<<<<<<<<<<< | BL3-1 NOBITS | | - * 0x04037000-->|-----------------------| <<<<<<<<<<<<<<<< |----------------| | - * | | <<<<<<<<<<<<<<<< | BL3-1 PROGBITS | | - * 0x04023000-->|-----------------------| +----------------+ | - * | BL2 | | - * |-----------------------| | - * | | | - * 0x04001000-->|-----------------------| | - * | Shared | | - * 0x04000000-->+-----------------------+ | - * : : | - * : Linux : | - * : : | - * |-----------------------| | - * | | U-Boot(BL3-3) Loaded by BL2 | - * | U-Boot | <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - * 0x00000000-->+-----------------------+ - * - * Trusted SRAM section 0x4000000..0x4200000: - * ---------------------------------------- - * SRAM_BASE = 0x4001000 - * BL2_BASE = 0x4006000 - * BL2_LIMIT = BL31_BASE - * BL31_BASE = 0x4023000 = (64MB + 256KB - 0x1D000) - * BL31_PROGBITS_LIMIT = BL1_RW_BASE - * BL1_RW_BASE = 0x4037000 = (64MB + 256KB - 0x9000) - * BL1_RW_LIMIT = BL31_LIMIT = 0x4040000 - * - * - * PLAT_MARVELL_FIP_BASE = 0x4120000 - */ - -#define PLAT_MARVELL_ATF_BASE 0x4000000 -#define PLAT_MARVELL_ATF_LOAD_ADDR \ - (PLAT_MARVELL_ATF_BASE + 0x100000) - -#define PLAT_MARVELL_FIP_BASE \ - (PLAT_MARVELL_ATF_LOAD_ADDR + 0x20000) -#define PLAT_MARVELL_FIP_MAX_SIZE 0x4000000 - -#define PLAT_MARVELL_CLUSTER_CORE_COUNT U(2) -/* DRAM[2MB..66MB] is used as Trusted ROM */ -#define PLAT_MARVELL_TRUSTED_ROM_BASE PLAT_MARVELL_ATF_LOAD_ADDR -/* 64 MB TODO: reduce this to minimum needed according to fip image size*/ -#define PLAT_MARVELL_TRUSTED_ROM_SIZE 0x04000000 -/* Reserve 16M for SCP (Secure PayLoad) Trusted DRAM */ -#define PLAT_MARVELL_TRUSTED_DRAM_BASE 0x04400000 -#define PLAT_MARVELL_TRUSTED_DRAM_SIZE 0x01000000 /* 16 MB */ - -/* - * PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size - * plus a little space for growth. - */ -#define PLAT_MARVELL_MAX_BL1_RW_SIZE 0xA000 - -/* - * PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a - * little space for growth. - */ -#define PLAT_MARVELL_MAX_BL2_SIZE 0xF000 - -/* - * PLAT_ARM_MAX_BL31_SIZE is calculated using the current BL31 debug size plus a - * little space for growth. - */ -#define PLAT_MARVEL_MAX_BL31_SIZE 0x5D000 - -#define PLAT_MARVELL_CPU_ENTRY_ADDR BL1_RO_BASE - -/* GIC related definitions */ -#define PLAT_MARVELL_GICD_BASE (MVEBU_REGS_BASE + MVEBU_GICD_BASE) -#define PLAT_MARVELL_GICR_BASE (MVEBU_REGS_BASE + MVEBU_GICR_BASE) -#define PLAT_MARVELL_GICC_BASE (MVEBU_REGS_BASE + MVEBU_GICC_BASE) - -#define PLAT_MARVELL_G0_IRQ_PROPS(grp) \ - INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_LEVEL) - -#define PLAT_MARVELL_G1S_IRQ_PROPS(grp) \ - INTR_PROP_DESC(MARVELL_IRQ_SEC_PHY_TIMER, \ - GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_LEVEL) - - -#define PLAT_MARVELL_SHARED_RAM_CACHED 1 - -/* CCI related constants */ -#define PLAT_MARVELL_CCI_BASE (MVEBU_REGS_BASE + MVEBU_CCI_BASE) -#define PLAT_MARVELL_CCI_CLUSTER0_SL_IFACE_IX 3 -#define PLAT_MARVELL_CCI_CLUSTER1_SL_IFACE_IX 4 - -/* - * Load address of BL3-3 for this platform port - */ -#define PLAT_MARVELL_NS_IMAGE_OFFSET 0x0 - -/* System Reference Clock*/ -#define PLAT_REF_CLK_IN_HZ COUNTER_FREQUENCY - -/* - * PL011 related constants - */ -#define PLAT_MARVELL_BOOT_UART_BASE (MVEBU_REGS_BASE + 0x12000) -#define PLAT_MARVELL_BOOT_UART_CLK_IN_HZ 25804800 - -#define PLAT_MARVELL_CRASH_UART_BASE PLAT_MARVELL_BOOT_UART_BASE -#define PLAT_MARVELL_CRASH_UART_CLK_IN_HZ PLAT_MARVELL_BOOT_UART_CLK_IN_HZ - -#define PLAT_MARVELL_BL31_RUN_UART_BASE PLAT_MARVELL_BOOT_UART_BASE -#define PLAT_MARVELL_BL31_RUN_UART_CLK_IN_HZ PLAT_MARVELL_BOOT_UART_CLK_IN_HZ - -/* Required platform porting definitions */ -#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL1 - -/* System timer related constants */ -#define PLAT_MARVELL_NSTIMER_FRAME_ID 1 - -/* Mailbox base address */ -#define PLAT_MARVELL_MAILBOX_BASE \ - (MARVELL_TRUSTED_SRAM_BASE + 0x400) -#define PLAT_MARVELL_MAILBOX_SIZE 0x100 -#define PLAT_MARVELL_MAILBOX_MAGIC_NUM 0x6D72766C /* mrvl */ - -/* DRAM CS memory map registers related constants */ -#define MVEBU_CS_MMAP_LOW(cs_num) \ - (MVEBU_CS_MMAP_REG_BASE + (cs_num) * 0x8) -#define MVEBU_CS_MMAP_ENABLE 0x1 -#define MVEBU_CS_MMAP_AREA_LEN_OFFS 16 -#define MVEBU_CS_MMAP_AREA_LEN_MASK \ - (0x1f << MVEBU_CS_MMAP_AREA_LEN_OFFS) -#define MVEBU_CS_MMAP_START_ADDR_LOW_OFFS 23 -#define MVEBU_CS_MMAP_START_ADDR_LOW_MASK \ - (0x1ff << MVEBU_CS_MMAP_START_ADDR_LOW_OFFS) - -#define MVEBU_CS_MMAP_HIGH(cs_num) \ - (MVEBU_CS_MMAP_REG_BASE + 0x4 + (cs_num) * 0x8) - -/* DRAM max CS number */ -#define MVEBU_MAX_CS_MMAP_NUM (2) - -/* CPU decoder window related constants */ -#define CPU_DEC_WIN_CTRL_REG(win_num) \ - (MVEBU_CPU_DEC_WIN_REG_BASE + (win_num) * 0x10) -#define CPU_DEC_CR_WIN_ENABLE 0x1 -#define CPU_DEC_CR_WIN_TARGET_OFFS 4 -#define CPU_DEC_CR_WIN_TARGET_MASK \ - (0xf << CPU_DEC_CR_WIN_TARGET_OFFS) - -#define CPU_DEC_WIN_SIZE_REG(win_num) \ - (MVEBU_CPU_DEC_WIN_REG_BASE + 0x4 + (win_num) * 0x10) -#define CPU_DEC_CR_WIN_SIZE_OFFS 0 -#define CPU_DEC_CR_WIN_SIZE_MASK \ - (0xffff << CPU_DEC_CR_WIN_SIZE_OFFS) -#define CPU_DEC_CR_WIN_SIZE_ALIGNMENT 0x10000 - -#define CPU_DEC_WIN_BASE_REG(win_num) \ - (MVEBU_CPU_DEC_WIN_REG_BASE + 0x8 + (win_num) * 0x10) -#define CPU_DEC_BR_BASE_OFFS 0 -#define CPU_DEC_BR_BASE_MASK \ - (0xffff << CPU_DEC_BR_BASE_OFFS) - -#define CPU_DEC_REMAP_LOW_REG(win_num) \ - (MVEBU_CPU_DEC_WIN_REG_BASE + 0xC + (win_num) * 0x10) -#define CPU_DEC_RLR_REMAP_LOW_OFFS 0 -#define CPU_DEC_RLR_REMAP_LOW_MASK \ - (0xffff << CPU_DEC_BR_BASE_OFFS) - -/* Securities */ -#define IRQ_SEC_OS_TICK_INT MARVELL_IRQ_SEC_PHY_TIMER - -#define TRUSTED_DRAM_BASE PLAT_MARVELL_TRUSTED_DRAM_BASE -#define TRUSTED_DRAM_SIZE PLAT_MARVELL_TRUSTED_DRAM_SIZE - -#ifdef BL32 -#define BL32_BASE TRUSTED_DRAM_BASE -#define BL32_LIMIT TRUSTED_DRAM_SIZE -#endif - -#endif /* PLATFORM_DEF_H */ diff --git a/plat/marvell/a3700/common/io_addr_dec.c b/plat/marvell/a3700/common/io_addr_dec.c deleted file mode 100644 index b27633cf2..000000000 --- a/plat/marvell/a3700/common/io_addr_dec.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (C) 2016 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include - -#include -#include - -#define MVEBU_DEC_WIN_CTRL_REG(base, win, off) (MVEBU_REGS_BASE + (base) + \ - (win) * (off)) -#define MVEBU_DEC_WIN_BASE_REG(base, win, off) (MVEBU_REGS_BASE + (base) + \ - (win) * (off) + 0x4) -#define MVEBU_DEC_WIN_REMAP_REG(base, win, off) (MVEBU_REGS_BASE + (base) + \ - (win) * (off) + 0x8) - -#define MVEBU_DEC_WIN_CTRL_SIZE_OFF (16) -#define MVEBU_DEC_WIN_ENABLE (0x1) -#define MVEBU_DEC_WIN_CTRL_ATTR_OFF (8) -#define MVEBU_DEC_WIN_CTRL_TARGET_OFF (4) -#define MVEBU_DEC_WIN_CTRL_EN_OFF (0) -#define MVEBU_DEC_WIN_BASE_OFF (16) - -#define MVEBU_WIN_BASE_SIZE_ALIGNMENT (0x10000) - -/* There are up to 14 IO unit which need address decode in Armada-3700 */ -#define IO_UNIT_NUM_MAX (14) - -#define MVEBU_MAX_ADDRSS_4GB (0x100000000ULL) - - -static void set_io_addr_dec_win(int win_id, uintptr_t base_addr, - uintptr_t win_size, - struct dec_win_config *dec_win) -{ - uint32_t ctrl = 0; - uint32_t base = 0; - - /* set size */ - ctrl = ((win_size / MVEBU_WIN_BASE_SIZE_ALIGNMENT) - 1) << - MVEBU_DEC_WIN_CTRL_SIZE_OFF; - /* set attr according to IO decode window */ - ctrl |= dec_win->win_attr << MVEBU_DEC_WIN_CTRL_ATTR_OFF; - /* set target */ - ctrl |= DRAM_CPU_DEC_TARGET_NUM << MVEBU_DEC_WIN_CTRL_TARGET_OFF; - /* set base */ - base = (base_addr / MVEBU_WIN_BASE_SIZE_ALIGNMENT) << - MVEBU_DEC_WIN_BASE_OFF; - - /* set base address*/ - mmio_write_32(MVEBU_DEC_WIN_BASE_REG(dec_win->dec_reg_base, - win_id, dec_win->win_offset), - base); - /* set remap window, some unit does not have remap window */ - if (win_id < dec_win->max_remap) - mmio_write_32(MVEBU_DEC_WIN_REMAP_REG(dec_win->dec_reg_base, - win_id, dec_win->win_offset), base); - /* set control register */ - mmio_write_32(MVEBU_DEC_WIN_CTRL_REG(dec_win->dec_reg_base, - win_id, dec_win->win_offset), ctrl); - /* enable the address decode window at last to make it effective */ - ctrl |= MVEBU_DEC_WIN_ENABLE << MVEBU_DEC_WIN_CTRL_EN_OFF; - mmio_write_32(MVEBU_DEC_WIN_CTRL_REG(dec_win->dec_reg_base, - win_id, dec_win->win_offset), ctrl); - - INFO("set_io_addr_dec %d result: ctrl(0x%x) base(0x%x)", - win_id, mmio_read_32(MVEBU_DEC_WIN_CTRL_REG(dec_win->dec_reg_base, - win_id, dec_win->win_offset)), - mmio_read_32(MVEBU_DEC_WIN_BASE_REG(dec_win->dec_reg_base, - win_id, dec_win->win_offset))); - if (win_id < dec_win->max_remap) - INFO(" remap(%x)\n", - mmio_read_32(MVEBU_DEC_WIN_REMAP_REG(dec_win->dec_reg_base, - win_id, dec_win->win_offset))); - else - INFO("\n"); -} - -/* Set io decode window */ -static int set_io_addr_dec(struct dram_win_map *win_map, - struct dec_win_config *dec_win) -{ - struct dram_win *win; - int id; - - /* disable all windows first */ - for (id = 0; id < dec_win->max_dram_win; id++) - mmio_write_32(MVEBU_DEC_WIN_CTRL_REG(dec_win->dec_reg_base, id, - dec_win->win_offset), 0); - - /* configure IO decode windows for DRAM, inheritate DRAM size, - * base and target from CPU-DRAM decode window and others - * from hard coded IO decode window settings array. - */ - if (win_map->dram_win_num > dec_win->max_dram_win) { - /* - * If cpu dram windows number exceeds the io decode windows - * max number, then fill the first io decode window - * with base(0) and size(4GB). - */ - set_io_addr_dec_win(0, 0, MVEBU_MAX_ADDRSS_4GB, dec_win); - - return 0; - } - - for (id = 0; id < win_map->dram_win_num; id++, win++) { - win = &win_map->dram_windows[id]; - set_io_addr_dec_win(id, win->base_addr, win->win_size, dec_win); - } - - return 0; -} - -/* - * init_io_addr_dec - * - * This function initializes io address decoder windows by - * cpu dram window mapping information - * - * @input: N/A - * - dram_wins_map: cpu dram windows mapping - * - io_dec_config: io address decoder windows configuration - * - io_unit_num: io address decoder unit number - * @output: N/A - * - * @return: 0 on success and others on failure - */ -int init_io_addr_dec(struct dram_win_map *dram_wins_map, - struct dec_win_config *io_dec_config, uint32_t io_unit_num) -{ - int32_t index; - struct dec_win_config *io_dec_win; - int32_t ret; - - INFO("Initializing IO address decode windows\n"); - - if (io_dec_config == NULL || io_unit_num == 0) { - ERROR("No IO address decoder windows configurations!\n"); - return -1; - } - - if (io_unit_num > IO_UNIT_NUM_MAX) { - ERROR("IO address decoder windows number %d is over max %d\n", - io_unit_num, IO_UNIT_NUM_MAX); - return -1; - } - - if (dram_wins_map == NULL) { - ERROR("No cpu dram decoder windows map!\n"); - return -1; - } - - for (index = 0; index < dram_wins_map->dram_win_num; index++) - INFO("DRAM mapping %d base(0x%lx) size(0x%lx)\n", - index, dram_wins_map->dram_windows[index].base_addr, - dram_wins_map->dram_windows[index].win_size); - - /* Set address decode window for each IO */ - for (index = 0; index < io_unit_num; index++) { - io_dec_win = io_dec_config + index; - ret = set_io_addr_dec(dram_wins_map, io_dec_win); - if (ret) { - ERROR("Failed to set IO address decode\n"); - return -1; - } - INFO("Set IO decode window successfully, base(0x%x)", - io_dec_win->dec_reg_base); - INFO(" win_attr(%x) max_dram_win(%d) max_remap(%d)", - io_dec_win->win_attr, io_dec_win->max_dram_win, - io_dec_win->max_remap); - INFO(" win_offset(%d)\n", io_dec_win->win_offset); - } - - return 0; -} diff --git a/plat/marvell/a3700/common/marvell_plat_config.c b/plat/marvell/a3700/common/marvell_plat_config.c deleted file mode 100644 index 3bf3d96bd..000000000 --- a/plat/marvell/a3700/common/marvell_plat_config.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -#include -#include - -struct dec_win_config io_dec_win_conf[] = { - /* dec_reg_base win_attr max_dram_win max_remap win_offset */ - {0xc000, 0x3d, 2, 0, 0x08}, /* USB */ - {0xc100, 0x3d, 3, 0, 0x10}, /* USB3 */ - {0xc200, 0x3d, 2, 0, 0x10}, /* DMA */ - {0xc300, 0x3d, 2, 0, 0x10}, /* NETA0 */ - {0xc400, 0x3d, 2, 0, 0x10}, /* NETA1 */ - {0xc500, 0x3d, 2, 0, 0x10}, /* PCIe */ - {0xc800, 0x3d, 3, 0, 0x10}, /* SATA */ - {0xca00, 0x3d, 3, 0, 0x08}, /* SD */ - {0xcb00, 0x3d, 3, 0, 0x10}, /* eMMC */ - {0xce00, 0x3d, 2, 0, 0x08}, /* EIP97 */ -}; - -int marvell_get_io_dec_win_conf(struct dec_win_config **win, uint32_t *size) -{ - *win = io_dec_win_conf; - *size = sizeof(io_dec_win_conf)/sizeof(struct dec_win_config); - - return 0; -} - diff --git a/plat/marvell/a3700/common/plat_pm.c b/plat/marvell/a3700/common/plat_pm.c deleted file mode 100644 index f8ce6fe29..000000000 --- a/plat/marvell/a3700/common/plat_pm.c +++ /dev/null @@ -1,807 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#ifdef USE_CCI -#include -#endif -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Warm reset register */ -#define MVEBU_WARM_RESET_REG (MVEBU_NB_REGS_BASE + 0x840) -#define MVEBU_WARM_RESET_MAGIC 0x1D1E - -/* North Bridge GPIO1 SEL register */ -#define MVEBU_NB_GPIO1_SEL_REG (MVEBU_NB_REGS_BASE + 0x830) - #define MVEBU_NB_GPIO1_UART1_SEL BIT(19) - #define MVEBU_NB_GPIO1_GPIO_25_26_EN BIT(17) - #define MVEBU_NB_GPIO1_GPIO_19_EN BIT(14) - #define MVEBU_NB_GPIO1_GPIO_18_EN BIT(13) - -/* CPU 1 reset register */ -#define MVEBU_CPU_1_RESET_VECTOR (MVEBU_REGS_BASE + 0x14044) -#define MVEBU_CPU_1_RESET_REG (MVEBU_REGS_BASE + 0xD00C) -#define MVEBU_CPU_1_RESET_BIT 31 - -/* IRQ register */ -#define MVEBU_NB_IRQ_STATUS_1_REG (MVEBU_NB_SB_IRQ_REG_BASE) -#define MVEBU_NB_IRQ_STATUS_2_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ - 0x10) -#define MVEBU_NB_IRQ_MASK_2_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ - 0x18) -#define MVEBU_SB_IRQ_STATUS_1_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ - 0x40) -#define MVEBU_SB_IRQ_STATUS_2_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ - 0x50) -#define MVEBU_NB_GPIO_IRQ_MASK_1_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ - 0xC8) -#define MVEBU_NB_GPIO_IRQ_MASK_2_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ - 0xD8) -#define MVEBU_SB_GPIO_IRQ_MASK_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ - 0xE8) -#define MVEBU_NB_GPIO_IRQ_EN_LOW_REG (MVEBU_NB_GPIO_IRQ_REG_BASE) -#define MVEBU_NB_GPIO_IRQ_EN_HIGH_REG (MVEBU_NB_GPIO_IRQ_REG_BASE + \ - 0x04) -#define MVEBU_NB_GPIO_IRQ_STATUS_LOW_REG (MVEBU_NB_GPIO_IRQ_REG_BASE + \ - 0x10) -#define MVEBU_NB_GPIO_IRQ_STATUS_HIGH_REG (MVEBU_NB_GPIO_IRQ_REG_BASE + \ - 0x14) -#define MVEBU_NB_GPIO_IRQ_WK_LOW_REG (MVEBU_NB_GPIO_IRQ_REG_BASE + \ - 0x18) -#define MVEBU_NB_GPIO_IRQ_WK_HIGH_REG (MVEBU_NB_GPIO_IRQ_REG_BASE + \ - 0x1C) -#define MVEBU_SB_GPIO_IRQ_EN_REG (MVEBU_SB_GPIO_IRQ_REG_BASE) -#define MVEBU_SB_GPIO_IRQ_STATUS_REG (MVEBU_SB_GPIO_IRQ_REG_BASE + \ - 0x10) -#define MVEBU_SB_GPIO_IRQ_WK_REG (MVEBU_SB_GPIO_IRQ_REG_BASE + \ - 0x18) - -/* PMU registers */ -#define MVEBU_PM_NB_PWR_CTRL_REG (MVEBU_PMSU_REG_BASE) - #define MVEBU_PM_PWR_DN_CNT_SEL BIT(28) - #define MVEBU_PM_SB_PWR_DWN BIT(4) - #define MVEBU_PM_INTERFACE_IDLE BIT(0) -#define MVEBU_PM_NB_CPU_PWR_CTRL_REG (MVEBU_PMSU_REG_BASE + 0x4) - #define MVEBU_PM_L2_FLUSH_EN BIT(22) -#define MVEBU_PM_NB_PWR_OPTION_REG (MVEBU_PMSU_REG_BASE + 0x8) - #define MVEBU_PM_DDR_SR_EN BIT(29) - #define MVEBU_PM_DDR_CLK_DIS_EN BIT(28) - #define MVEBU_PM_WARM_RESET_EN BIT(27) - #define MVEBU_PM_DDRPHY_PWRDWN_EN BIT(23) - #define MVEBU_PM_DDRPHY_PAD_PWRDWN_EN BIT(22) - #define MVEBU_PM_OSC_OFF_EN BIT(21) - #define MVEBU_PM_TBG_OFF_EN BIT(20) - #define MVEBU_PM_CPU_VDDV_OFF_EN BIT(19) - #define MVEBU_PM_AVS_DISABLE_MODE BIT(14) - #define MVEBU_PM_AVS_VDD2_MODE BIT(13) - #define MVEBU_PM_AVS_HOLD_MODE BIT(12) - #define MVEBU_PM_L2_SRAM_LKG_PD_EN BIT(8) - #define MVEBU_PM_EIP_SRAM_LKG_PD_EN BIT(7) - #define MVEBU_PM_DDRMC_SRAM_LKG_PD_EN BIT(6) - #define MVEBU_PM_MCI_SRAM_LKG_PD_EN BIT(5) - #define MVEBU_PM_MMC_SRAM_LKG_PD_EN BIT(4) - #define MVEBU_PM_SATA_SRAM_LKG_PD_EN BIT(3) - #define MVEBU_PM_DMA_SRAM_LKG_PD_EN BIT(2) - #define MVEBU_PM_SEC_SRAM_LKG_PD_EN BIT(1) - #define MVEBU_PM_CPU_SRAM_LKG_PD_EN BIT(0) - #define MVEBU_PM_NB_SRAM_LKG_PD_EN (MVEBU_PM_L2_SRAM_LKG_PD_EN |\ - MVEBU_PM_EIP_SRAM_LKG_PD_EN | MVEBU_PM_DDRMC_SRAM_LKG_PD_EN |\ - MVEBU_PM_MCI_SRAM_LKG_PD_EN | MVEBU_PM_MMC_SRAM_LKG_PD_EN |\ - MVEBU_PM_SATA_SRAM_LKG_PD_EN | MVEBU_PM_DMA_SRAM_LKG_PD_EN |\ - MVEBU_PM_SEC_SRAM_LKG_PD_EN | MVEBU_PM_CPU_SRAM_LKG_PD_EN) -#define MVEBU_PM_NB_PWR_DEBUG_REG (MVEBU_PMSU_REG_BASE + 0xC) - #define MVEBU_PM_NB_FORCE_CLK_ON BIT(30) - #define MVEBU_PM_IGNORE_CM3_SLEEP BIT(21) - #define MVEBU_PM_IGNORE_CM3_DEEP BIT(20) -#define MVEBU_PM_NB_WAKE_UP_EN_REG (MVEBU_PMSU_REG_BASE + 0x2C) - #define MVEBU_PM_SB_WKP_NB_EN BIT(31) - #define MVEBU_PM_NB_GPIO_WKP_EN BIT(27) - #define MVEBU_PM_SOC_TIMER_WKP_EN BIT(26) - #define MVEBU_PM_UART_WKP_EN BIT(25) - #define MVEBU_PM_UART2_WKP_EN BIT(19) - #define MVEBU_PM_CPU_TIMER_WKP_EN BIT(17) - #define MVEBU_PM_NB_WKP_EN BIT(16) - #define MVEBU_PM_CORE1_FIQ_IRQ_WKP_EN BIT(13) - #define MVEBU_PM_CORE0_FIQ_IRQ_WKP_EN BIT(12) -#define MVEBU_PM_CPU_0_PWR_CTRL_REG (MVEBU_PMSU_REG_BASE + 0x34) -#define MVEBU_PM_CPU_1_PWR_CTRL_REG (MVEBU_PMSU_REG_BASE + 0x38) - #define MVEBU_PM_CORE_SOC_PD BIT(2) - #define MVEBU_PM_CORE_PROC_PD BIT(1) - #define MVEBU_PM_CORE_PD BIT(0) -#define MVEBU_PM_CORE_1_RETURN_ADDR_REG (MVEBU_PMSU_REG_BASE + 0x44) -#define MVEBU_PM_CPU_VDD_OFF_INFO_1_REG (MVEBU_PMSU_REG_BASE + 0x48) -#define MVEBU_PM_CPU_VDD_OFF_INFO_2_REG (MVEBU_PMSU_REG_BASE + 0x4C) - #define MVEBU_PM_LOW_POWER_STATE BIT(0) -#define MVEBU_PM_CPU_WAKE_UP_CONF_REG (MVEBU_PMSU_REG_BASE + 0x54) - #define MVEBU_PM_CORE1_WAKEUP BIT(13) - #define MVEBU_PM_CORE0_WAKEUP BIT(12) -#define MVEBU_PM_WAIT_DDR_RDY_VALUE (0x15) -#define MVEBU_PM_SB_CPU_PWR_CTRL_REG (MVEBU_SB_WAKEUP_REG_BASE) - #define MVEBU_PM_SB_PM_START BIT(0) -#define MVEBU_PM_SB_PWR_OPTION_REG (MVEBU_SB_WAKEUP_REG_BASE + 0x4) - #define MVEBU_PM_SDIO_PHY_PDWN_EN BIT(17) - #define MVEBU_PM_SB_VDDV_OFF_EN BIT(16) - #define MVEBU_PM_EBM_SRAM_LKG_PD_EN BIT(11) - #define MVEBU_PM_PCIE_SRAM_LKG_PD_EN BIT(10) - #define MVEBU_PM_GBE1_TX_SRAM_LKG_PD_EN BIT(9) - #define MVEBU_PM_GBE1_RX_SRAM_LKG_PD_EN BIT(8) - #define MVEBU_PM_GBE1_MIB_SRAM_LKG_PD_EN BIT(7) - #define MVEBU_PM_GBE0_TX_SRAM_LKG_PD_EN BIT(6) - #define MVEBU_PM_GBE0_RX_SRAM_LKG_PD_EN BIT(5) - #define MVEBU_PM_GBE0_MIB_SRAM_LKG_PD_EN BIT(4) - #define MVEBU_PM_SDIO_SRAM_LKG_PD_EN BIT(3) - #define MVEBU_PM_USB2_SRAM_LKG_PD_EN BIT(2) - #define MVEBU_PM_USB3_H_SRAM_LKG_PD_EN BIT(1) - #define MVEBU_PM_SB_SRAM_LKG_PD_EN (MVEBU_PM_EBM_SRAM_LKG_PD_EN |\ - MVEBU_PM_PCIE_SRAM_LKG_PD_EN | MVEBU_PM_GBE1_TX_SRAM_LKG_PD_EN |\ - MVEBU_PM_GBE1_RX_SRAM_LKG_PD_EN | MVEBU_PM_GBE1_MIB_SRAM_LKG_PD_EN |\ - MVEBU_PM_GBE0_TX_SRAM_LKG_PD_EN | MVEBU_PM_GBE0_RX_SRAM_LKG_PD_EN |\ - MVEBU_PM_GBE0_MIB_SRAM_LKG_PD_EN | MVEBU_PM_SDIO_SRAM_LKG_PD_EN |\ - MVEBU_PM_USB2_SRAM_LKG_PD_EN | MVEBU_PM_USB3_H_SRAM_LKG_PD_EN) -#define MVEBU_PM_SB_WK_EN_REG (MVEBU_SB_WAKEUP_REG_BASE + 0x10) - #define MVEBU_PM_SB_GPIO_WKP_EN BIT(24) - #define MVEBU_PM_SB_WKP_EN BIT(20) - -/* DRAM registers */ -#define MVEBU_DRAM_STATS_CH0_REG (MVEBU_DRAM_REG_BASE + 0x4) - #define MVEBU_DRAM_WCP_EMPTY BIT(19) -#define MVEBU_DRAM_CMD_0_REG (MVEBU_DRAM_REG_BASE + 0x20) - #define MVEBU_DRAM_CH0_CMD0 BIT(28) - #define MVEBU_DRAM_CS_CMD0 BIT(24) - #define MVEBU_DRAM_WCB_DRAIN_REQ BIT(1) -#define MVEBU_DRAM_PWR_CTRL_REG (MVEBU_DRAM_REG_BASE + 0x54) - #define MVEBU_DRAM_PHY_CLK_GATING_EN BIT(1) - #define MVEBU_DRAM_PHY_AUTO_AC_OFF_EN BIT(0) - -/* AVS registers */ -#define MVEBU_AVS_CTRL_2_REG (MVEBU_AVS_REG_BASE + 0x8) - #define MVEBU_LOW_VDD_MODE_EN BIT(6) - -/* Clock registers */ -#define MVEBU_NB_CLOCK_SEL_REG (MVEBU_NB_REGS_BASE + 0x10) - #define MVEBU_A53_CPU_CLK_SEL BIT(15) - -/* North Bridge Step-Down Registers */ -#define MVEBU_NB_STEP_DOWN_INT_EN_REG MVEBU_NB_STEP_DOWN_REG_BASE - #define MVEBU_NB_GPIO_INT_WAKE_WCPU_CLK BIT(8) - -#define MVEBU_NB_GPIO_18 18 -#define MVEBU_NB_GPIO_19 19 -#define MVEBU_NB_GPIO_25 25 -#define MVEBU_NB_GPIO_26 26 - -typedef int (*wake_up_src_func)(union pm_wake_up_src_data *); - -struct wake_up_src_func_map { - enum pm_wake_up_src_type type; - wake_up_src_func func; -}; - -void marvell_psci_arch_init(int die_index) -{ -} - -static void a3700_pm_ack_irq(void) -{ - uint32_t reg; - - reg = mmio_read_32(MVEBU_NB_IRQ_STATUS_1_REG); - if (reg) - mmio_write_32(MVEBU_NB_IRQ_STATUS_1_REG, reg); - - reg = mmio_read_32(MVEBU_NB_IRQ_STATUS_2_REG); - if (reg) - mmio_write_32(MVEBU_NB_IRQ_STATUS_2_REG, reg); - - reg = mmio_read_32(MVEBU_SB_IRQ_STATUS_1_REG); - if (reg) - mmio_write_32(MVEBU_SB_IRQ_STATUS_1_REG, reg); - - reg = mmio_read_32(MVEBU_SB_IRQ_STATUS_2_REG); - if (reg) - mmio_write_32(MVEBU_SB_IRQ_STATUS_2_REG, reg); - - reg = mmio_read_32(MVEBU_NB_GPIO_IRQ_STATUS_LOW_REG); - if (reg) - mmio_write_32(MVEBU_NB_GPIO_IRQ_STATUS_LOW_REG, reg); - - reg = mmio_read_32(MVEBU_NB_GPIO_IRQ_STATUS_HIGH_REG); - if (reg) - mmio_write_32(MVEBU_NB_GPIO_IRQ_STATUS_HIGH_REG, reg); - - reg = mmio_read_32(MVEBU_SB_GPIO_IRQ_STATUS_REG); - if (reg) - mmio_write_32(MVEBU_SB_GPIO_IRQ_STATUS_REG, reg); -} - -/***************************************************************************** - * A3700 handler called to check the validity of the power state - * parameter. - ***************************************************************************** - */ -int a3700_validate_power_state(unsigned int power_state, - psci_power_state_t *req_state) -{ - ERROR("%s needs to be implemented\n", __func__); - panic(); -} - -/***************************************************************************** - * A3700 handler called when a CPU is about to enter standby. - ***************************************************************************** - */ -void a3700_cpu_standby(plat_local_state_t cpu_state) -{ - ERROR("%s needs to be implemented\n", __func__); - panic(); -} - -/***************************************************************************** - * A3700 handler called when a power domain is about to be turned on. The - * mpidr determines the CPU to be turned on. - ***************************************************************************** - */ -int a3700_pwr_domain_on(u_register_t mpidr) -{ - /* Set barrier */ - dsbsy(); - - /* Set the cpu start address to BL1 entry point */ - mmio_write_32(MVEBU_CPU_1_RESET_VECTOR, - PLAT_MARVELL_CPU_ENTRY_ADDR >> 2); - - /* Get the cpu out of reset */ - mmio_clrbits_32(MVEBU_CPU_1_RESET_REG, BIT(MVEBU_CPU_1_RESET_BIT)); - mmio_setbits_32(MVEBU_CPU_1_RESET_REG, BIT(MVEBU_CPU_1_RESET_BIT)); - - return 0; -} - -/***************************************************************************** - * A3700 handler called to validate the entry point. - ***************************************************************************** - */ -int a3700_validate_ns_entrypoint(uintptr_t entrypoint) -{ - return PSCI_E_SUCCESS; -} - -/***************************************************************************** - * A3700 handler called when a power domain is about to be turned off. The - * target_state encodes the power state that each level should transition to. - ***************************************************************************** - */ -void a3700_pwr_domain_off(const psci_power_state_t *target_state) -{ - /* Prevent interrupts from spuriously waking up this cpu */ - plat_marvell_gic_cpuif_disable(); - - /* Core can not be powered down with pending IRQ, - * acknowledge all the pending IRQ - */ - a3700_pm_ack_irq(); -} - -static void a3700_set_gen_pwr_off_option(void) -{ - /* Enable L2 flush -> processor state-machine option */ - mmio_setbits_32(MVEBU_PM_NB_CPU_PWR_CTRL_REG, MVEBU_PM_L2_FLUSH_EN); - - /* - * North bridge cannot be VDD off (always ON). - * The NB state machine support low power mode by its state machine. - * This bit MUST be set for north bridge power down, e.g., - * OSC input cutoff(NOT TEST), SRAM power down, PMIC, etc. - * It is not related to CPU VDD OFF!! - */ - mmio_clrbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_CPU_VDDV_OFF_EN); - - /* - * MUST: Switch CPU/AXI clock to OSC - * NB state machine clock is always connected to OSC (slow clock). - * But Core0/1/processor state machine's clock are connected to AXI - * clock. Now, AXI clock takes the TBG as clock source. - * If using AXI clock, Core0/1/processor state machine may much faster - * than NB state machine. It will cause problem in this case if cores - * are released before north bridge gets ready. - */ - mmio_clrbits_32(MVEBU_NB_CLOCK_SEL_REG, MVEBU_A53_CPU_CLK_SEL); - - /* - * These register bits will trigger north bridge - * power-down state machine regardless CM3 status. - */ - mmio_setbits_32(MVEBU_PM_NB_PWR_DEBUG_REG, MVEBU_PM_IGNORE_CM3_SLEEP); - mmio_setbits_32(MVEBU_PM_NB_PWR_DEBUG_REG, MVEBU_PM_IGNORE_CM3_DEEP); - - /* - * SRAM => controlled by north bridge state machine. - * Core VDD OFF is not related to CPU SRAM power down. - */ - mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_NB_SRAM_LKG_PD_EN); - - /* - * Idle AXI interface in order to get L2_WFI - * L2 WFI is only asserted after CORE-0 and CORE-1 WFI asserted. - * (only both core-0/1in WFI, L2 WFI will be issued by CORE.) - * Once L2 WFI asserted, this bit is used for signalling assertion - * to AXI IO masters. - */ - mmio_setbits_32(MVEBU_PM_NB_PWR_CTRL_REG, MVEBU_PM_INTERFACE_IDLE); - - /* Enable core0 and core1 VDD_OFF */ - mmio_setbits_32(MVEBU_PM_CPU_0_PWR_CTRL_REG, MVEBU_PM_CORE_PD); - mmio_setbits_32(MVEBU_PM_CPU_1_PWR_CTRL_REG, MVEBU_PM_CORE_PD); - - /* Enable North bridge power down - - * Both Cores MUST enable this bit to power down north bridge! - */ - mmio_setbits_32(MVEBU_PM_CPU_0_PWR_CTRL_REG, MVEBU_PM_CORE_SOC_PD); - mmio_setbits_32(MVEBU_PM_CPU_1_PWR_CTRL_REG, MVEBU_PM_CORE_SOC_PD); - - /* CA53 (processor domain) power down */ - mmio_setbits_32(MVEBU_PM_CPU_0_PWR_CTRL_REG, MVEBU_PM_CORE_PROC_PD); - mmio_setbits_32(MVEBU_PM_CPU_1_PWR_CTRL_REG, MVEBU_PM_CORE_PROC_PD); -} - -static void a3700_en_ddr_self_refresh(void) -{ - /* - * Both count is 16 bits and configurable. By default, osc stb cnt - * is 0xFFF for lower 12 bits. - * Thus, powerdown count is smaller than osc count. - * This count is used for exiting DDR SR mode on wakeup event. - * The powerdown count also has impact on the following - * state changes: idle -> count-down -> ... (power-down, vdd off, etc) - * Here, make stable counter shorter - * Use power down count value instead of osc_stb_cnt to speed up - * DDR self refresh exit - */ - mmio_setbits_32(MVEBU_PM_NB_PWR_CTRL_REG, MVEBU_PM_PWR_DN_CNT_SEL); - - /* - * Enable DDR SR mode => controlled by north bridge state machine - * Therefore, we must powerdown north bridge to trigger the DDR SR - * mode switching. - */ - mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_DDR_SR_EN); - /* Disable DDR clock, otherwise DDR will not enter into SR mode. */ - mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_DDR_CLK_DIS_EN); - /* Power down DDR PHY (PAD) */ - mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_DDRPHY_PWRDWN_EN); - mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, - MVEBU_PM_DDRPHY_PAD_PWRDWN_EN); - - /* Set wait time for DDR ready in ROM code */ - mmio_write_32(MVEBU_PM_CPU_VDD_OFF_INFO_1_REG, - MVEBU_PM_WAIT_DDR_RDY_VALUE); - - /* DDR flush write buffer - mandatory */ - mmio_write_32(MVEBU_DRAM_CMD_0_REG, MVEBU_DRAM_CH0_CMD0 | - MVEBU_DRAM_CS_CMD0 | MVEBU_DRAM_WCB_DRAIN_REQ); - while ((mmio_read_32(MVEBU_DRAM_STATS_CH0_REG) & - MVEBU_DRAM_WCP_EMPTY) != MVEBU_DRAM_WCP_EMPTY) - ; - - /* Trigger PHY reset after ddr out of self refresh => - * supply reset pulse for DDR phy after wake up - */ - mmio_setbits_32(MVEBU_DRAM_PWR_CTRL_REG, MVEBU_DRAM_PHY_CLK_GATING_EN | - MVEBU_DRAM_PHY_AUTO_AC_OFF_EN); -} - -static void a3700_pwr_dn_avs(void) -{ - /* - * AVS power down - controlled by north bridge statemachine - * Enable AVS power down by clear the AVS disable bit. - */ - mmio_clrbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_AVS_DISABLE_MODE); - /* - * Should set BIT[12:13] to powerdown AVS. - * 1. Enable AVS VDD2 mode - * 2. After power down AVS, we must hold AVS output voltage. - * 3. We can choose the lower VDD for AVS power down. - */ - mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_AVS_VDD2_MODE); - mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_AVS_HOLD_MODE); - - /* Enable low VDD mode, AVS will set CPU to lowest core VDD 747mV */ - mmio_setbits_32(MVEBU_AVS_CTRL_2_REG, MVEBU_LOW_VDD_MODE_EN); -} - -static void a3700_pwr_dn_tbg(void) -{ - /* Power down TBG */ - mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_TBG_OFF_EN); -} - -static void a3700_pwr_dn_sb(void) -{ - /* Enable south bridge power down option */ - mmio_setbits_32(MVEBU_PM_NB_PWR_CTRL_REG, MVEBU_PM_SB_PWR_DWN); - - /* Enable SDIO_PHY_PWRDWN */ - mmio_setbits_32(MVEBU_PM_SB_PWR_OPTION_REG, MVEBU_PM_SDIO_PHY_PDWN_EN); - - /* Enable SRAM LRM on SB */ - mmio_setbits_32(MVEBU_PM_SB_PWR_OPTION_REG, MVEBU_PM_SB_SRAM_LKG_PD_EN); - - /* Enable SB Power Off */ - mmio_setbits_32(MVEBU_PM_SB_PWR_OPTION_REG, MVEBU_PM_SB_VDDV_OFF_EN); - - /* Kick off South Bridge Power Off */ - mmio_setbits_32(MVEBU_PM_SB_CPU_PWR_CTRL_REG, MVEBU_PM_SB_PM_START); -} - -static void a3700_set_pwr_off_option(void) -{ - /* Set general power off option */ - a3700_set_gen_pwr_off_option(); - - /* Enable DDR self refresh in low power mode */ - a3700_en_ddr_self_refresh(); - - /* Power down AVS */ - a3700_pwr_dn_avs(); - - /* Power down TBG */ - a3700_pwr_dn_tbg(); - - /* Power down south bridge, pay attention south bridge setting - * should be done before - */ - a3700_pwr_dn_sb(); -} - -static void a3700_set_wake_up_option(void) -{ - /* - * Enable the wakeup event for NB SOC => north-bridge - * state-machine enablement on wake-up event - */ - mmio_setbits_32(MVEBU_PM_NB_WAKE_UP_EN_REG, MVEBU_PM_NB_WKP_EN); - - /* Enable both core0 and core1 wakeup on demand */ - mmio_setbits_32(MVEBU_PM_CPU_WAKE_UP_CONF_REG, - MVEBU_PM_CORE1_WAKEUP | MVEBU_PM_CORE0_WAKEUP); - - /* Enable warm reset in low power mode */ - mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_WARM_RESET_EN); -} - -static void a3700_pm_en_nb_gpio(uint32_t gpio) -{ - /* For GPIO1 interrupt -- North bridge only */ - if (gpio >= 32) { - /* GPIO int mask */ - mmio_clrbits_32(MVEBU_NB_GPIO_IRQ_MASK_2_REG, BIT(gpio - 32)); - - /* NB_CPU_WAKE-up ENABLE GPIO int */ - mmio_setbits_32(MVEBU_NB_GPIO_IRQ_EN_HIGH_REG, BIT(gpio - 32)); - } else { - /* GPIO int mask */ - mmio_clrbits_32(MVEBU_NB_GPIO_IRQ_MASK_1_REG, BIT(gpio)); - - /* NB_CPU_WAKE-up ENABLE GPIO int */ - mmio_setbits_32(MVEBU_NB_GPIO_IRQ_EN_LOW_REG, BIT(gpio)); - } - - mmio_setbits_32(MVEBU_NB_STEP_DOWN_INT_EN_REG, - MVEBU_NB_GPIO_INT_WAKE_WCPU_CLK); - - /* Enable using GPIO as wakeup event - * (actually not only for north bridge) - */ - mmio_setbits_32(MVEBU_PM_NB_WAKE_UP_EN_REG, MVEBU_PM_NB_GPIO_WKP_EN | - MVEBU_PM_NB_WKP_EN | MVEBU_PM_CORE1_FIQ_IRQ_WKP_EN | - MVEBU_PM_CORE0_FIQ_IRQ_WKP_EN); -} - -static void a3700_pm_en_sb_gpio(uint32_t gpio) -{ - /* Enable using GPIO as wakeup event */ - mmio_setbits_32(MVEBU_PM_NB_WAKE_UP_EN_REG, MVEBU_PM_SB_WKP_NB_EN | - MVEBU_PM_NB_WKP_EN | MVEBU_PM_CORE1_FIQ_IRQ_WKP_EN | - MVEBU_PM_CORE0_FIQ_IRQ_WKP_EN); - - /* SB GPIO Wake UP | South Bridge Wake Up Enable */ - mmio_setbits_32(MVEBU_PM_SB_WK_EN_REG, MVEBU_PM_SB_GPIO_WKP_EN | - MVEBU_PM_SB_GPIO_WKP_EN); - - /* GPIO int mask */ - mmio_clrbits_32(MVEBU_SB_GPIO_IRQ_MASK_REG, BIT(gpio)); - - /* NB_CPU_WAKE-up ENABLE GPIO int */ - mmio_setbits_32(MVEBU_SB_GPIO_IRQ_EN_REG, BIT(gpio)); -} - -int a3700_pm_src_gpio(union pm_wake_up_src_data *src_data) -{ - if (src_data->gpio_data.bank_num == 0) - /* North Bridge GPIO */ - a3700_pm_en_nb_gpio(src_data->gpio_data.gpio_num); - else - a3700_pm_en_sb_gpio(src_data->gpio_data.gpio_num); - return 0; -} - -int a3700_pm_src_uart1(union pm_wake_up_src_data *src_data) -{ - /* Clear Uart1 select */ - mmio_clrbits_32(MVEBU_NB_GPIO1_SEL_REG, MVEBU_NB_GPIO1_UART1_SEL); - /* set pin 19 gpio usage*/ - mmio_setbits_32(MVEBU_NB_GPIO1_SEL_REG, MVEBU_NB_GPIO1_GPIO_19_EN); - /* Enable gpio wake-up*/ - a3700_pm_en_nb_gpio(MVEBU_NB_GPIO_19); - /* set pin 18 gpio usage*/ - mmio_setbits_32(MVEBU_NB_GPIO1_SEL_REG, MVEBU_NB_GPIO1_GPIO_18_EN); - /* Enable gpio wake-up*/ - a3700_pm_en_nb_gpio(MVEBU_NB_GPIO_18); - - return 0; -} - -int a3700_pm_src_uart0(union pm_wake_up_src_data *src_data) -{ - /* set pin 25/26 gpio usage*/ - mmio_setbits_32(MVEBU_NB_GPIO1_SEL_REG, MVEBU_NB_GPIO1_GPIO_25_26_EN); - /* Enable gpio wake-up*/ - a3700_pm_en_nb_gpio(MVEBU_NB_GPIO_25); - /* Enable gpio wake-up*/ - a3700_pm_en_nb_gpio(MVEBU_NB_GPIO_26); - - return 0; -} - -struct wake_up_src_func_map src_func_table[WAKE_UP_SRC_MAX] = { - {WAKE_UP_SRC_GPIO, a3700_pm_src_gpio}, - {WAKE_UP_SRC_UART1, a3700_pm_src_uart1}, - {WAKE_UP_SRC_UART0, a3700_pm_src_uart0}, - /* FOLLOWING SRC NOT SUPPORTED YET */ - {WAKE_UP_SRC_TIMER, NULL} -}; - -static wake_up_src_func a3700_get_wake_up_src_func( - enum pm_wake_up_src_type type) -{ - uint32_t loop; - - for (loop = 0; loop < WAKE_UP_SRC_MAX; loop++) { - if (src_func_table[loop].type == type) - return src_func_table[loop].func; - } - return NULL; -} - -static void a3700_set_wake_up_source(void) -{ - struct pm_wake_up_src_config *wake_up_src; - uint32_t loop; - wake_up_src_func src_func = NULL; - - wake_up_src = mv_wake_up_src_config_get(); - for (loop = 0; loop < wake_up_src->wake_up_src_num; loop++) { - src_func = a3700_get_wake_up_src_func( - wake_up_src->wake_up_src[loop].wake_up_src_type); - if (src_func) - src_func( - &(wake_up_src->wake_up_src[loop].wake_up_data)); - } -} - -static void a3700_pm_save_lp_flag(void) -{ - /* Save the flag for enter the low power mode */ - mmio_setbits_32(MVEBU_PM_CPU_VDD_OFF_INFO_2_REG, - MVEBU_PM_LOW_POWER_STATE); -} - -static void a3700_pm_clear_lp_flag(void) -{ - /* Clear the flag for enter the low power mode */ - mmio_clrbits_32(MVEBU_PM_CPU_VDD_OFF_INFO_2_REG, - MVEBU_PM_LOW_POWER_STATE); -} - -static uint32_t a3700_pm_get_lp_flag(void) -{ - /* Get the flag for enter the low power mode */ - return mmio_read_32(MVEBU_PM_CPU_VDD_OFF_INFO_2_REG) & - MVEBU_PM_LOW_POWER_STATE; -} - -/***************************************************************************** - * A3700 handler called when a power domain is about to be suspended. The - * target_state encodes the power state that each level should transition to. - ***************************************************************************** - */ -void a3700_pwr_domain_suspend(const psci_power_state_t *target_state) -{ - /* Prevent interrupts from spuriously waking up this cpu */ - plat_marvell_gic_cpuif_disable(); - - /* Save IRQ states */ - plat_marvell_gic_irq_save(); - - /* Set wake up options */ - a3700_set_wake_up_option(); - - /* Set wake up sources */ - a3700_set_wake_up_source(); - - /* SoC can not be powered down with pending IRQ, - * acknowledge all the pending IRQ - */ - a3700_pm_ack_irq(); - - /* Set power off options */ - a3700_set_pwr_off_option(); - - /* Save the flag for enter the low power mode */ - a3700_pm_save_lp_flag(); - - isb(); -} - -/***************************************************************************** - * A3700 handler called when a power domain has just been powered on after - * being turned off earlier. The target_state encodes the low power state that - * each level has woken up from. - ***************************************************************************** - */ -void a3700_pwr_domain_on_finish(const psci_power_state_t *target_state) -{ - /* arch specific configuration */ - marvell_psci_arch_init(0); - - /* Per-CPU interrupt initialization */ - plat_marvell_gic_pcpu_init(); - plat_marvell_gic_cpuif_enable(); - - /* Restore the per-cpu IRQ state */ - if (a3700_pm_get_lp_flag()) - plat_marvell_gic_irq_pcpu_restore(); -} - -/***************************************************************************** - * A3700 handler called when a power domain has just been powered on after - * having been suspended earlier. The target_state encodes the low power state - * that each level has woken up from. - * TODO: At the moment we reuse the on finisher and reinitialize the secure - * context. Need to implement a separate suspend finisher. - ***************************************************************************** - */ -void a3700_pwr_domain_suspend_finish(const psci_power_state_t *target_state) -{ - struct dec_win_config *io_dec_map; - uint32_t dec_win_num; - struct dram_win_map dram_wins_map; - - /* arch specific configuration */ - marvell_psci_arch_init(0); - - /* Interrupt initialization */ - plat_marvell_gic_init(); - - /* Restore IRQ states */ - plat_marvell_gic_irq_restore(); - - /* - * Initialize CCI for this cluster after resume from suspend state. - * No need for locks as no other CPU is active. - */ - plat_marvell_interconnect_init(); - /* - * Enable CCI coherency for the primary CPU's cluster. - * Platform specific PSCI code will enable coherency for other - * clusters. - */ - plat_marvell_interconnect_enter_coherency(); - - /* CPU address decoder windows initialization. */ - cpu_wins_init(); - - /* fetch CPU-DRAM window mapping information by reading - * CPU-DRAM decode windows (only the enabled ones) - */ - dram_win_map_build(&dram_wins_map); - - /* Get IO address decoder windows */ - if (marvell_get_io_dec_win_conf(&io_dec_map, &dec_win_num)) { - printf("No IO address decoder windows configurations found!\n"); - return; - } - - /* IO address decoder init */ - if (init_io_addr_dec(&dram_wins_map, io_dec_map, dec_win_num)) { - printf("IO address decoder windows initialization failed!\n"); - return; - } - - /* Clear low power mode flag */ - a3700_pm_clear_lp_flag(); -} - -/***************************************************************************** - * This handler is called by the PSCI implementation during the `SYSTEM_SUSPEND - * call to get the `power_state` parameter. This allows the platform to encode - * the appropriate State-ID field within the `power_state` parameter which can - * be utilized in `pwr_domain_suspend()` to suspend to system affinity level. - ***************************************************************************** - */ -void a3700_get_sys_suspend_power_state(psci_power_state_t *req_state) -{ - /* lower affinities use PLAT_MAX_OFF_STATE */ - for (int i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++) - req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE; -} - -/***************************************************************************** - * A3700 handlers to shutdown/reboot the system - ***************************************************************************** - */ -static void __dead2 a3700_system_off(void) -{ - ERROR("%s needs to be implemented\n", __func__); - panic(); -} - -/***************************************************************************** - * A3700 handlers to reset the system - ***************************************************************************** - */ -static void __dead2 a3700_system_reset(void) -{ - /* Clean the mailbox magic number to let it as act like cold boot */ - mmio_write_32(PLAT_MARVELL_MAILBOX_BASE, 0x0); - - dsbsy(); - - /* Flush data cache if the mail box shared RAM is cached */ -#if PLAT_MARVELL_SHARED_RAM_CACHED - flush_dcache_range((uintptr_t)PLAT_MARVELL_MAILBOX_BASE, - 2 * sizeof(uint64_t)); -#endif - - /* Trigger the warm reset */ - mmio_write_32(MVEBU_WARM_RESET_REG, MVEBU_WARM_RESET_MAGIC); - - /* Shouldn't get to this point */ - panic(); -} - -/***************************************************************************** - * Export the platform handlers via plat_arm_psci_pm_ops. The ARM Standard - * platform layer will take care of registering the handlers with PSCI. - ***************************************************************************** - */ -const plat_psci_ops_t plat_arm_psci_pm_ops = { - .cpu_standby = a3700_cpu_standby, - .pwr_domain_on = a3700_pwr_domain_on, - .pwr_domain_off = a3700_pwr_domain_off, - .pwr_domain_suspend = a3700_pwr_domain_suspend, - .pwr_domain_on_finish = a3700_pwr_domain_on_finish, - .pwr_domain_suspend_finish = a3700_pwr_domain_suspend_finish, - .get_sys_suspend_power_state = a3700_get_sys_suspend_power_state, - .system_off = a3700_system_off, - .system_reset = a3700_system_reset, - .validate_power_state = a3700_validate_power_state, - .validate_ns_entrypoint = a3700_validate_ns_entrypoint -}; diff --git a/plat/marvell/a8k/a70x0/board/dram_port.c b/plat/marvell/a8k/a70x0/board/dram_port.c deleted file mode 100644 index 4fca7e383..000000000 --- a/plat/marvell/a8k/a70x0/board/dram_port.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2018 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 - */ -static struct mv_ddr_topology_map board_topology_map = { -/* FIXME: MISL board 2CS 4Gb x8 devices of micron - 2133P */ - 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_2133P, /* 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 */ - MV_DDR_32BIT_ECC_PUP8_BUS_MASK, /* subphys mask */ - MV_DDR_CFG_DEFAULT, /* ddr configuration data source */ - { {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 */ - }, - } -}; - -struct mv_ddr_topology_map *mv_ddr_topology_map_get(void) -{ - /* Return the board topology as defined in the board code */ - return &board_topology_map; -} diff --git a/plat/marvell/a8k/a70x0/board/marvell_plat_config.c b/plat/marvell/a8k/a70x0/board/marvell_plat_config.c deleted file mode 100644 index d126f5567..000000000 --- a/plat/marvell/a8k/a70x0/board/marvell_plat_config.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (C) 2018 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 - {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 -struct skip_image skip_im = { - .detection_method = GPIO, - .info.gpio.num = 33, - .info.gpio.button_state = HIGH, - .info.test.cp_ap = CP, - .info.test.cp_index = 0, -}; - -void *plat_marvell_get_skip_image_data(void) -{ - /* Return the skip_image configurations */ - return &skip_im; -} -#endif -#endif diff --git a/plat/marvell/a8k/a70x0/mvebu_def.h b/plat/marvell/a8k/a70x0/mvebu_def.h deleted file mode 100644 index 72bca12e3..000000000 --- a/plat/marvell/a8k/a70x0/mvebu_def.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (C) 2018 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/a8k/a70x0/platform.mk b/plat/marvell/a8k/a70x0/platform.mk deleted file mode 100644 index d3a01676e..000000000 --- a/plat/marvell/a8k/a70x0/platform.mk +++ /dev/null @@ -1,19 +0,0 @@ -# -# Copyright (C) 2018 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 - -include plat/marvell/a8k/common/a8k_common.mk - -include plat/marvell/common/marvell_common.mk diff --git a/plat/marvell/a8k/a70x0_amc/board/dram_port.c b/plat/marvell/a8k/a70x0_amc/board/dram_port.c deleted file mode 100644 index aecf6c567..000000000 --- a/plat/marvell/a8k/a70x0_amc/board/dram_port.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2018 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 - */ -static struct mv_ddr_topology_map board_topology_map = { -/* FIXME: MISL board 2CS 8Gb x8 devices of micron - 2133P */ - 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_2400T, /* 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 */ - MV_DDR_32BIT_ECC_PUP8_BUS_MASK, /* subphys mask */ - MV_DDR_CFG_DEFAULT, /* ddr configuration data source */ - { {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 */ - }, - } -}; - -struct mv_ddr_topology_map *mv_ddr_topology_map_get(void) -{ - /* Return the board topology as defined in the board code */ - return &board_topology_map; -} diff --git a/plat/marvell/a8k/a70x0_amc/board/marvell_plat_config.c b/plat/marvell/a8k/a70x0_amc/board/marvell_plat_config.c deleted file mode 100644 index f8a1c40be..000000000 --- a/plat/marvell/a8k/a70x0_amc/board/marvell_plat_config.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (C) 2018 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; - -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[] = { - /* PEX0_X4 window */ - {0x00000000f6000000, 0x6000000, PEX0_TID}, - {0x00000000c0000000, 0x30000000, PEX0_TID}, - {0x0000000800000000, 0x200000000, PEX0_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[] = { -#ifdef IMAGE_BLE - {0x00000000f2000000, 0x4000000, IO_0_TID}, /* IO window */ -#else - {0x00000000f2000000, 0xe000000, IO_0_TID}, - {0x00000000c0000000, 0x30000000, IO_0_TID}, /* IO window */ - {0x0000000800000000, 0x200000000, 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 - -struct pci_hw_cfg *plat_get_pcie_hw_data(void) -{ - return NULL; -} - -/***************************************************************************** - * SKIP IMAGE Configuration - ***************************************************************************** - */ -#if PLAT_RECOVERY_IMAGE_ENABLE -struct skip_image skip_im = { - .detection_method = GPIO, - .info.gpio.num = 33, - .info.gpio.button_state = HIGH, - .info.test.cp_ap = CP, - .info.test.cp_index = 0, -}; - -void *plat_marvell_get_skip_image_data(void) -{ - /* Return the skip_image configurations */ - return &skip_im; -} -#endif -#endif diff --git a/plat/marvell/a8k/a70x0_amc/mvebu_def.h b/plat/marvell/a8k/a70x0_amc/mvebu_def.h deleted file mode 100644 index cedf3239a..000000000 --- a/plat/marvell/a8k/a70x0_amc/mvebu_def.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2018 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 */ - -/*********************************************************************** - * Required platform porting definitions common to all - * Management Compute SubSystems (MSS) - *********************************************************************** - */ -/* - * Load address of SCP_BL2 - * SCP_BL2 is loaded to the same place as BL31. - * Once SCP_BL2 is transferred to the SCP, - * it is discarded and BL31 is loaded over the top. - */ -#ifdef SCP_IMAGE -#define SCP_BL2_BASE BL31_BASE -#endif - - -#endif /* MVEBU_DEF_H */ diff --git a/plat/marvell/a8k/a70x0_amc/platform.mk b/plat/marvell/a8k/a70x0_amc/platform.mk deleted file mode 100644 index d3a01676e..000000000 --- a/plat/marvell/a8k/a70x0_amc/platform.mk +++ /dev/null @@ -1,19 +0,0 @@ -# -# Copyright (C) 2018 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 - -include plat/marvell/a8k/common/a8k_common.mk - -include plat/marvell/common/marvell_common.mk diff --git a/plat/marvell/a8k/a80x0/board/dram_port.c b/plat/marvell/a8k/a80x0/board/dram_port.c deleted file mode 100644 index 02f4ffb0a..000000000 --- a/plat/marvell/a8k/a80x0/board/dram_port.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include -#include -#include - -#include -#include -#include - -#define MVEBU_AP_MPP_CTRL0_7_REG MVEBU_AP_MPP_REGS(0) -#define MVEBU_AP_MPP_CTRL4_OFFS 16 -#define MVEBU_AP_MPP_CTRL5_OFFS 20 -#define MVEBU_AP_MPP_CTRL4_I2C0_SDA_ENA 0x3 -#define MVEBU_AP_MPP_CTRL5_I2C0_SCK_ENA 0x3 - -#define MVEBU_CP_MPP_CTRL37_OFFS 20 -#define MVEBU_CP_MPP_CTRL38_OFFS 24 -#define MVEBU_CP_MPP_CTRL37_I2C0_SCK_ENA 0x2 -#define MVEBU_CP_MPP_CTRL38_I2C0_SDA_ENA 0x2 - -#define MVEBU_MPP_CTRL_MASK 0xf - -/* - * This struct provides the DRAM training code with - * the appropriate board DRAM configuration - */ -static struct mv_ddr_topology_map board_topology_map = { - /* MISL board with 1CS 8Gb x4 devices of Micron 2400T */ - DEBUG_LEVEL_ERROR, - 0x1, /* active interfaces */ - /* cs_mask, mirror, dqs_swap, ck_swap X subphys */ - { { { {0x1, 0x0, 0, 0}, /* FIXME: change the cs mask for all 64 bit */ - {0x1, 0x0, 0, 0}, - {0x1, 0x0, 0, 0}, - {0x1, 0x0, 0, 0}, - {0x1, 0x0, 0, 0}, - {0x1, 0x0, 0, 0}, - {0x1, 0x0, 0, 0}, - {0x1, 0x0, 0, 0}, - {0x1, 0x0, 0, 0} }, - /* TODO: double check if the speed bin is 2400T */ - SPEED_BIN_DDR_2400T, /* 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 */ - MV_DDR_64BIT_ECC_PUP8_BUS_MASK, /* subphys mask */ - MV_DDR_CFG_SPD, /* ddr configuration data source */ - { {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 */ - }, - } -}; - -struct mv_ddr_topology_map *mv_ddr_topology_map_get(void) -{ - /* Return the board topology as defined in the board code */ - return &board_topology_map; -} - -static void mpp_config(void) -{ - uintptr_t reg; - uint32_t val; - - reg = MVEBU_CP_MPP_REGS(0, 4); - /* configure CP0 MPP 37 and 38 to i2c */ - val = mmio_read_32(reg); - val &= ~((MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL37_OFFS) | - (MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL38_OFFS)); - val |= (MVEBU_CP_MPP_CTRL37_I2C0_SCK_ENA << - MVEBU_CP_MPP_CTRL37_OFFS) | - (MVEBU_CP_MPP_CTRL38_I2C0_SDA_ENA << - MVEBU_CP_MPP_CTRL38_OFFS); - mmio_write_32(reg, val); -} - -/* - * 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) -{ - struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); - - INFO("Gathering DRAM information\n"); - - if (tm->cfg_src == MV_DDR_CFG_SPD) { - /* configure MPPs to enable i2c */ - mpp_config(); - - /* initialize i2c */ - i2c_init((void *)MVEBU_CP0_I2C_BASE); - - /* select SPD memory page 0 to access DRAM configuration */ - i2c_write(I2C_SPD_P0_ADDR, 0x0, 1, tm->spd_data.all_bytes, 1); - - /* read data from spd */ - i2c_read(I2C_SPD_ADDR, 0x0, 1, tm->spd_data.all_bytes, - sizeof(tm->spd_data.all_bytes)); - } -} diff --git a/plat/marvell/a8k/a80x0/board/marvell_plat_config.c b/plat/marvell/a8k/a80x0/board/marvell_plat_config.c deleted file mode 100644 index 7901dd225..000000000 --- a/plat/marvell/a8k/a80x0/board/marvell_plat_config.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (C) 2018 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[] = { - /* CP1 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[] = { - /* CP1 (MCI0) internal regs */ - {0x00000000f4000000, 0x2000000, MCI_0_TID}, -#ifndef IMAGE_BLE - /* PCIe0 and SPI1_CS0 (RUNIT) on CP1*/ - {0x00000000f9000000, 0x2000000, MCI_0_TID}, - /* PCIe1 on CP1*/ - {0x00000000fb000000, 0x1000000, MCI_0_TID}, - /* PCIe2 on CP1*/ - {0x00000000fc000000, 0x1000000, MCI_0_TID}, - /* 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_cp0[] = { - /* CP0 */ - /* PEX1_X1 window */ - {0x00000000f7000000, 0x1000000, PEX1_TID}, - /* PEX2_X1 window */ - {0x00000000f8000000, 0x1000000, PEX2_TID}, - /* PEX0_X4 window */ - {0x00000000f6000000, 0x1000000, PEX0_TID}, - {0x00000000c0000000, 0x30000000, PEX0_TID}, - {0x0000000800000000, 0x100000000, PEX0_TID}, -}; - -struct addr_map_win iob_memory_map_cp1[] = { - /* CP1 */ - /* SPI1_CS0 (RUNIT) window */ - {0x00000000f9000000, 0x1000000, RUNIT_TID}, - /* PEX1_X1 window */ - {0x00000000fb000000, 0x1000000, PEX1_TID}, - /* PEX2_X1 window */ - {0x00000000fc000000, 0x1000000, PEX2_TID}, - /* PEX0_X4 window */ - {0x00000000fa000000, 0x1000000, PEX0_TID} -}; - -int marvell_get_iob_memory_map(struct addr_map_win **win, uint32_t *size, - uintptr_t base) -{ - switch (base) { - case MVEBU_CP_REGS_BASE(0): - *win = iob_memory_map_cp0; - *size = ARRAY_SIZE(iob_memory_map_cp0); - return 0; - case MVEBU_CP_REGS_BASE(1): - *win = iob_memory_map_cp1; - *size = ARRAY_SIZE(iob_memory_map_cp1); - return 0; - default: - *size = 0; - *win = 0; - return 1; - } -} -#endif - -/***************************************************************************** - * CCU Configuration - ***************************************************************************** - */ -struct addr_map_win ccu_memory_map[] = { -#ifdef IMAGE_BLE - {0x00000000f2000000, 0x4000000, IO_0_TID}, /* IO window */ -#else - {0x00000000f2000000, 0xe000000, IO_0_TID}, /* IO window */ - {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, struct addr_map_win **win, - uint32_t *size) -{ - *win = ccu_memory_map; - *size = ARRAY_SIZE(ccu_memory_map); - - return 0; -} - -#ifndef IMAGE_BLE -/***************************************************************************** - * SoC PM configuration - ***************************************************************************** - */ -/* CP GPIO should be used and the GPIOs should be within same GPIO register */ -struct power_off_method pm_cfg = { - .type = PMIC_GPIO, - .cfg.gpio.pin_count = 1, - .cfg.gpio.info = {{0, 35} }, - .cfg.gpio.step_count = 7, - .cfg.gpio.seq = {1, 0, 1, 0, 1, 0, 1}, - .cfg.gpio.delay_ms = 10, -}; - -void *plat_marvell_get_pm_cfg(void) -{ - /* Return the PM configurations */ - return &pm_cfg; -} - -/* In reference to #ifndef IMAGE_BLE, this part is used for BLE only. */ -#else -/***************************************************************************** - * SKIP IMAGE Configuration - ***************************************************************************** - */ -#if PLAT_RECOVERY_IMAGE_ENABLE -struct skip_image skip_im = { - .detection_method = GPIO, - .info.gpio.num = 33, - .info.gpio.button_state = HIGH, - .info.test.cp_ap = CP, - .info.test.cp_index = 0, -}; - -void *plat_marvell_get_skip_image_data(void) -{ - /* Return the skip_image configurations */ - return &skip_im; -} -#endif -#endif diff --git a/plat/marvell/a8k/a80x0/board/phy-porting-layer.h b/plat/marvell/a8k/a80x0/board/phy-porting-layer.h deleted file mode 100644 index abd85b5d2..000000000 --- a/plat/marvell/a8k/a80x0/board/phy-porting-layer.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (C) 2018 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 */ - { .g1_ffe_res_sel = 0x3, .g1_ffe_cap_sel = 0xf, - .align90 = 0x5f, - .g1_dfe_res = 0x2, .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 = 0x1 }, /* Comphy2 */ - { 0 }, /* Comphy3 */ - { .g1_ffe_res_sel = 0x3, .g1_ffe_cap_sel = 0xf, - .align90 = 0x5f, - .g1_dfe_res = 0x2, .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 = 0x1 }, /* Comphy4 */ - { 0 }, /* Comphy5 */ - }, - - /* CP 1 */ - { - { 0 }, /* Comphy0 */ - { 0 }, /* Comphy1 */ - { .g1_ffe_res_sel = 0x3, .g1_ffe_cap_sel = 0xf, - .align90 = 0x5f, - .g1_dfe_res = 0x2, .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 = 0x1 }, /* Comphy2 */ - { 0 }, /* Comphy3 */ - { .g1_ffe_res_sel = 0x3, .g1_ffe_cap_sel = 0xf, - .align90 = 0x5f, - .g1_dfe_res = 0x2, .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 = 0x1 }, /* Comphy4 */ - { 0 }, /* Comphy5 */ - }, - }, -}; - -static const struct sata_params - sata_static_values_tab[AP_NUM][CP_NUM][MAX_LANE_NR] = { - /* AP0 */ - { - /* CP 0 */ - { - { 0 }, /* Comphy0 */ - { .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, - .valid = 0x1 - }, /* Comphy1 */ - { 0 }, /* 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, - .valid = 0x1 - }, /* Comphy3 */ - { 0 }, /* Comphy4 */ - { 0 }, /* Comphy5 */ - }, - - /* CP 1 */ - { - { 0 }, /* Comphy0 */ - { .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, - .valid = 0x1 - }, /* Comphy1 */ - { 0 }, /* 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, - .valid = 0x1 - }, /* Comphy3 */ - { 0 }, /* Comphy4 */ - { 0 }, /* Comphy5 */ - - }, - }, -}; -#endif /* PHY_PORTING_LAYER_H */ diff --git a/plat/marvell/a8k/a80x0/mvebu_def.h b/plat/marvell/a8k/a80x0/mvebu_def.h deleted file mode 100644 index 3fa119af6..000000000 --- a/plat/marvell/a8k/a80x0/mvebu_def.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (C) 2018 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 2 /* A80x0 has both CP0 & CP1 */ -#define I2C_SPD_ADDR 0x53 /* Access SPD data */ -#define I2C_SPD_P0_ADDR 0x36 /* Select SPD data page 0 */ - -#endif /* MVEBU_DEF_H */ diff --git a/plat/marvell/a8k/a80x0/platform.mk b/plat/marvell/a8k/a80x0/platform.mk deleted file mode 100644 index 00d24b278..000000000 --- a/plat/marvell/a8k/a80x0/platform.mk +++ /dev/null @@ -1,20 +0,0 @@ -# -# Copyright (C) 2018 Marvell International Ltd. -# -# SPDX-License-Identifier: BSD-3-Clause -# https://spdx.org/licenses -# - -PCI_EP_SUPPORT := 0 - -CP_NUM := 2 -$(eval $(call add_define,CP_NUM)) - -DOIMAGE_SEC := tools/doimage/secure/sec_img_8K.cfg - -MARVELL_MOCHI_DRV := drivers/marvell/mochi/apn806_setup.c - -include plat/marvell/a8k/common/a8k_common.mk - -include plat/marvell/common/marvell_common.mk -PLAT_INCLUDES += -Iplat/marvell/a8k/a80x0/board diff --git a/plat/marvell/a8k/a80x0_mcbin/board/dram_port.c b/plat/marvell/a8k/a80x0_mcbin/board/dram_port.c deleted file mode 100644 index 25808523c..000000000 --- a/plat/marvell/a8k/a80x0_mcbin/board/dram_port.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include -#include -#include - -#include -#include -#include - -#define MVEBU_CP_MPP_CTRL37_OFFS 20 -#define MVEBU_CP_MPP_CTRL38_OFFS 24 -#define MVEBU_CP_MPP_CTRL37_I2C0_SCK_ENA 0x2 -#define MVEBU_CP_MPP_CTRL38_I2C0_SDA_ENA 0x2 - -#define MVEBU_MPP_CTRL_MASK 0xf - -/* - * This struct provides the DRAM training code with - * the appropriate board DRAM configuration - */ -static struct mv_ddr_topology_map board_topology_map = { - /* Board with 1CS 8Gb x4 devices of Micron 2400T */ - DEBUG_LEVEL_ERROR, - 0x1, /* active interfaces */ - /* cs_mask, mirror, dqs_swap, ck_swap X subphys */ - { { { {0x1, 0x0, 0, 0}, /* FIXME: change the cs mask for all 64 bit */ - {0x1, 0x0, 0, 0}, - {0x1, 0x0, 0, 0}, - {0x1, 0x0, 0, 0}, - {0x1, 0x0, 0, 0}, - {0x1, 0x0, 0, 0}, - {0x1, 0x0, 0, 0}, - {0x1, 0x0, 0, 0}, - {0x1, 0x0, 0, 0} }, - /* TODO: double check if the speed bin is 2400T */ - SPEED_BIN_DDR_2400T, /* 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 */ - MV_DDR_64BIT_BUS_MASK, /* subphys mask */ - MV_DDR_CFG_SPD, /* ddr configuration data source */ - { {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 */ - }, - } -}; - -struct mv_ddr_topology_map *mv_ddr_topology_map_get(void) -{ - /* Return the board topology as defined in the board code */ - return &board_topology_map; -} - -static void mpp_config(void) -{ - uint32_t val; - uintptr_t reg = MVEBU_CP_MPP_REGS(0, 4); - - /* configure CP0 MPP 37 and 38 to i2c */ - val = mmio_read_32(reg); - val &= ~((MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL37_OFFS) | - (MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL38_OFFS)); - val |= (MVEBU_CP_MPP_CTRL37_I2C0_SCK_ENA << MVEBU_CP_MPP_CTRL37_OFFS) | - (MVEBU_CP_MPP_CTRL38_I2C0_SDA_ENA << MVEBU_CP_MPP_CTRL38_OFFS); - mmio_write_32(reg, val); -} - -/* - * 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) -{ - struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); - - INFO("Gathering DRAM information\n"); - - if (tm->cfg_src == MV_DDR_CFG_SPD) { - /* configure MPPs to enable i2c */ - mpp_config(); - /* initialize the i2c */ - i2c_init((void *)MVEBU_CP0_I2C_BASE); - /* select SPD memory page 0 to access DRAM configuration */ - i2c_write(I2C_SPD_P0_ADDR, 0x0, 1, tm->spd_data.all_bytes, 1); - /* read data from spd */ - i2c_read(I2C_SPD_ADDR, 0x0, 1, tm->spd_data.all_bytes, - sizeof(tm->spd_data.all_bytes)); - } -} diff --git a/plat/marvell/a8k/a80x0_mcbin/board/marvell_plat_config.c b/plat/marvell/a8k/a80x0_mcbin/board/marvell_plat_config.c deleted file mode 100644 index fa4e144c9..000000000 --- a/plat/marvell/a8k/a80x0_mcbin/board/marvell_plat_config.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include - -#include - -/* - * If bootrom is currently at BLE there's no need to include the memory - * maps structure at this point - */ -#include -#ifndef IMAGE_BLE - -/***************************************************************************** - * GPIO Configuration - ***************************************************************************** - */ -#define MPP_CONTROL_REGISTER 0xf2440018 -#define MPP_CONTROL_MPP_SEL_52_MASK 0xf0000 -#define GPIO_DATA_OUT1_REGISTER 0xf2440140 -#define GPIO_DATA_OUT_EN_CTRL1_REGISTER 0xf2440144 -#define GPIO52_MASK 0x100000 - -/* Reset PCIe via GPIO number 52 */ -int marvell_gpio_config(void) -{ - uint32_t reg; - - reg = mmio_read_32(MPP_CONTROL_REGISTER); - reg |= MPP_CONTROL_MPP_SEL_52_MASK; - mmio_write_32(MPP_CONTROL_REGISTER, reg); - - reg = mmio_read_32(GPIO_DATA_OUT1_REGISTER); - reg |= GPIO52_MASK; - mmio_write_32(GPIO_DATA_OUT1_REGISTER, reg); - - reg = mmio_read_32(GPIO_DATA_OUT_EN_CTRL1_REGISTER); - reg &= ~GPIO52_MASK; - mmio_write_32(GPIO_DATA_OUT_EN_CTRL1_REGISTER, reg); - udelay(100); - - return 0; -} - -/***************************************************************************** - * AMB Configuration - ***************************************************************************** - */ -struct addr_map_win amb_memory_map[] = { - /* CP1 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[] = { - /* CP1 (MCI0) internal regs */ - {0x00000000f4000000, 0x2000000, MCI_0_TID}, -#ifndef IMAGE_BLE - /* PCIe0 and SPI1_CS0 (RUNIT) on CP1*/ - {0x00000000f9000000, 0x2000000, MCI_0_TID}, - /* PCIe1 on CP1*/ - {0x00000000fb000000, 0x1000000, MCI_0_TID}, - /* PCIe2 on CP1*/ - {0x00000000fc000000, 0x1000000, MCI_0_TID}, - /* 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_cp0[] = { - /* CP0 */ - /* PEX1_X1 window */ - {0x00000000f7000000, 0x1000000, PEX1_TID}, - /* PEX2_X1 window */ - {0x00000000f8000000, 0x1000000, PEX2_TID}, - /* PEX0_X4 window */ - {0x00000000f6000000, 0x1000000, PEX0_TID}, - {0x00000000c0000000, 0x30000000, PEX0_TID}, - {0x0000000800000000, 0x100000000, PEX0_TID}, -}; - -struct addr_map_win iob_memory_map_cp1[] = { - /* CP1 */ - /* SPI1_CS0 (RUNIT) window */ - {0x00000000f9000000, 0x1000000, RUNIT_TID}, - /* PEX1_X1 window */ - {0x00000000fb000000, 0x1000000, PEX1_TID}, - /* PEX2_X1 window */ - {0x00000000fc000000, 0x1000000, PEX2_TID}, - /* PEX0_X4 window */ - {0x00000000fa000000, 0x1000000, PEX0_TID} -}; - -int marvell_get_iob_memory_map(struct addr_map_win **win, uint32_t *size, - uintptr_t base) -{ - switch (base) { - case MVEBU_CP_REGS_BASE(0): - *win = iob_memory_map_cp0; - *size = ARRAY_SIZE(iob_memory_map_cp0); - return 0; - case MVEBU_CP_REGS_BASE(1): - *win = iob_memory_map_cp1; - *size = ARRAY_SIZE(iob_memory_map_cp1); - return 0; - default: - *size = 0; - *win = 0; - return 1; - } -} -#endif - -/***************************************************************************** - * CCU Configuration - ***************************************************************************** - */ -struct addr_map_win ccu_memory_map[] = { -#ifdef IMAGE_BLE - {0x00000000f2000000, 0x4000000, IO_0_TID}, /* IO window */ -#else - {0x00000000f2000000, 0xe000000, IO_0_TID}, /* IO window */ - {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; -} - -/* In reference to #ifndef IMAGE_BLE, this part is used for BLE only. */ - -/***************************************************************************** - * SKIP IMAGE Configuration - ***************************************************************************** - */ -void *plat_marvell_get_skip_image_data(void) -{ - /* No recovery button on A8k-MCBIN board */ - return NULL; -} diff --git a/plat/marvell/a8k/a80x0_mcbin/mvebu_def.h b/plat/marvell/a8k/a80x0_mcbin/mvebu_def.h deleted file mode 100644 index 3fa119af6..000000000 --- a/plat/marvell/a8k/a80x0_mcbin/mvebu_def.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (C) 2018 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 2 /* A80x0 has both CP0 & CP1 */ -#define I2C_SPD_ADDR 0x53 /* Access SPD data */ -#define I2C_SPD_P0_ADDR 0x36 /* Select SPD data page 0 */ - -#endif /* MVEBU_DEF_H */ diff --git a/plat/marvell/a8k/a80x0_mcbin/platform.mk b/plat/marvell/a8k/a80x0_mcbin/platform.mk deleted file mode 100644 index 3749c3781..000000000 --- a/plat/marvell/a8k/a80x0_mcbin/platform.mk +++ /dev/null @@ -1,19 +0,0 @@ -# -# Copyright (C) 2018 Marvell International Ltd. -# -# SPDX-License-Identifier: BSD-3-Clause -# https://spdx.org/licenses -# - -PCI_EP_SUPPORT := 0 - -CP_NUM := 2 -$(eval $(call add_define,CP_NUM)) - -DOIMAGE_SEC := tools/doimage/secure/sec_img_8K.cfg - -MARVELL_MOCHI_DRV := drivers/marvell/mochi/apn806_setup.c - -include plat/marvell/a8k/common/a8k_common.mk - -include plat/marvell/common/marvell_common.mk diff --git a/plat/marvell/a8k/common/a8k_common.mk b/plat/marvell/a8k/common/a8k_common.mk deleted file mode 100644 index 1ff28f846..000000000 --- a/plat/marvell/a8k/common/a8k_common.mk +++ /dev/null @@ -1,130 +0,0 @@ -# -# Copyright (C) 2016 - 2020 Marvell International Ltd. -# -# SPDX-License-Identifier: BSD-3-Clause -# https://spdx.org/licenses - -include tools/marvell/doimage/doimage.mk - -PLAT_FAMILY := a8k -PLAT_FAMILY_BASE := plat/marvell/$(PLAT_FAMILY) -PLAT_INCLUDE_BASE := include/plat/marvell/$(PLAT_FAMILY) -PLAT_COMMON_BASE := $(PLAT_FAMILY_BASE)/common -MARVELL_DRV_BASE := drivers/marvell -MARVELL_COMMON_BASE := plat/marvell/common - -MARVELL_SVC_TEST := 0 -$(eval $(call add_define,MARVELL_SVC_TEST)) - -ERRATA_A72_859971 := 1 - -# Enable MSS support for a8k family -MSS_SUPPORT := 1 - -# Disable EL3 cache for power management -BL31_CACHE_DISABLE := 0 -$(eval $(call add_define,BL31_CACHE_DISABLE)) - -$(eval $(call add_define,PCI_EP_SUPPORT)) -$(eval $(call assert_boolean,PCI_EP_SUPPORT)) - -AP_NUM := 1 -$(eval $(call add_define,AP_NUM)) - -DOIMAGEPATH ?= tools/marvell/doimage -DOIMAGETOOL ?= ${DOIMAGEPATH}/doimage - -ROM_BIN_EXT ?= $(BUILD_PLAT)/ble.bin -DOIMAGE_FLAGS += -b $(ROM_BIN_EXT) $(NAND_DOIMAGE_FLAGS) $(DOIMAGE_SEC_FLAGS) - -# Check whether to build system_power.c for the platform -ifneq ("$(wildcard $(PLAT_FAMILY_BASE)/$(PLAT)/board/system_power.c)","") -SYSTEM_POWER_SUPPORT = 1 -else -SYSTEM_POWER_SUPPORT = 0 -endif - -# This define specifies DDR type for BLE -$(eval $(call add_define,CONFIG_DDR4)) - -MARVELL_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v2/gicv2_main.c \ - drivers/arm/gic/v2/gicv2_helpers.c \ - plat/common/plat_gicv2.c - -PLAT_INCLUDES := -I$(PLAT_FAMILY_BASE)/$(PLAT) \ - -I$(PLAT_COMMON_BASE)/include \ - -I$(PLAT_INCLUDE_BASE)/common - -PLAT_BL_COMMON_SOURCES := $(PLAT_COMMON_BASE)/aarch64/a8k_common.c \ - drivers/ti/uart/aarch64/16550_console.S - -BLE_PORTING_SOURCES := $(PLAT_FAMILY_BASE)/$(PLAT)/board/dram_port.c \ - $(PLAT_FAMILY_BASE)/$(PLAT)/board/marvell_plat_config.c - -MARVELL_MOCHI_DRV += $(MARVELL_DRV_BASE)/mochi/cp110_setup.c - -BLE_SOURCES := drivers/mentor/i2c/mi2cv.c \ - $(PLAT_COMMON_BASE)/plat_ble_setup.c \ - $(MARVELL_MOCHI_DRV) \ - $(PLAT_COMMON_BASE)/plat_pm.c \ - $(MARVELL_DRV_BASE)/ap807_clocks_init.c \ - $(MARVELL_DRV_BASE)/thermal.c \ - $(PLAT_COMMON_BASE)/plat_thermal.c \ - $(BLE_PORTING_SOURCES) \ - $(MARVELL_DRV_BASE)/ccu.c \ - $(MARVELL_DRV_BASE)/io_win.c - -BL1_SOURCES += $(PLAT_COMMON_BASE)/aarch64/plat_helpers.S \ - lib/cpus/aarch64/cortex_a72.S - -MARVELL_DRV := $(MARVELL_DRV_BASE)/io_win.c \ - $(MARVELL_DRV_BASE)/iob.c \ - $(MARVELL_DRV_BASE)/mci.c \ - $(MARVELL_DRV_BASE)/amb_adec.c \ - $(MARVELL_DRV_BASE)/ccu.c \ - $(MARVELL_DRV_BASE)/cache_llc.c \ - $(MARVELL_DRV_BASE)/comphy/phy-comphy-cp110.c \ - $(MARVELL_DRV_BASE)/mc_trustzone/mc_trustzone.c - -BL31_PORTING_SOURCES := $(PLAT_FAMILY_BASE)/$(PLAT)/board/marvell_plat_config.c - -ifeq ($(SYSTEM_POWER_SUPPORT),1) -BL31_PORTING_SOURCES += $(PLAT_FAMILY_BASE)/$(PLAT)/board/system_power.c -endif - -BL31_SOURCES += lib/cpus/aarch64/cortex_a72.S \ - $(PLAT_COMMON_BASE)/aarch64/plat_helpers.S \ - $(PLAT_COMMON_BASE)/aarch64/plat_arch_config.c \ - $(PLAT_COMMON_BASE)/plat_pm.c \ - $(PLAT_COMMON_BASE)/plat_bl31_setup.c \ - $(MARVELL_COMMON_BASE)/marvell_gicv2.c \ - $(MARVELL_COMMON_BASE)/mrvl_sip_svc.c \ - $(MARVELL_COMMON_BASE)/marvell_ddr_info.c \ - $(BL31_PORTING_SOURCES) \ - $(MARVELL_DRV) \ - $(MARVELL_MOCHI_DRV) \ - $(MARVELL_GIC_SOURCES) - -# Add trace functionality for PM -BL31_SOURCES += $(PLAT_COMMON_BASE)/plat_pm_trace.c - -# Force builds with BL2 image on a80x0 platforms -ifndef SCP_BL2 - $(error "Error: SCP_BL2 image is mandatory for a8k family") -endif - -# MSS (SCP) build -include $(PLAT_COMMON_BASE)/mss/mss_a8k.mk - -# BLE (ROM context execution code, AKA binary extension) -BLE_PATH ?= $(PLAT_COMMON_BASE)/ble - -include ${BLE_PATH}/ble.mk -$(eval $(call MAKE_BL,e)) - -mrvl_flash: ${BUILD_PLAT}/${FIP_NAME} ${DOIMAGETOOL} ${BUILD_PLAT}/ble.bin - $(shell truncate -s %128K ${BUILD_PLAT}/bl1.bin) - $(shell cat ${BUILD_PLAT}/bl1.bin ${BUILD_PLAT}/${FIP_NAME} > ${BUILD_PLAT}/${BOOT_IMAGE}) - ${DOIMAGETOOL} ${DOIMAGE_FLAGS} ${BUILD_PLAT}/${BOOT_IMAGE} ${BUILD_PLAT}/${FLASH_IMAGE} - diff --git a/plat/marvell/a8k/common/aarch64/a8k_common.c b/plat/marvell/a8k/common/aarch64/a8k_common.c deleted file mode 100644 index 7c2bf318f..000000000 --- a/plat/marvell/a8k/common/aarch64/a8k_common.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - - -/* MMU entry for internal (register) space access */ -#define MAP_DEVICE0 MAP_REGION_FLAT(DEVICE0_BASE, \ - DEVICE0_SIZE, \ - MT_DEVICE | MT_RW | MT_SECURE) - -/* - * Table of regions for various BL stages to map using the MMU. - */ -#if IMAGE_BL1 -const mmap_region_t plat_marvell_mmap[] = { - MARVELL_MAP_SHARED_RAM, - MAP_DEVICE0, - {0} -}; -#endif -#if IMAGE_BL2 -const mmap_region_t plat_marvell_mmap[] = { - MARVELL_MAP_SHARED_RAM, - MAP_DEVICE0, - MARVELL_MAP_DRAM, - {0} -}; -#endif - -#if IMAGE_BL2U -const mmap_region_t plat_marvell_mmap[] = { - MAP_DEVICE0, - {0} -}; -#endif - -#if IMAGE_BLE -const mmap_region_t plat_marvell_mmap[] = { - MAP_DEVICE0, - {0} -}; -#endif - -#if IMAGE_BL31 -const mmap_region_t plat_marvell_mmap[] = { - MARVELL_MAP_SHARED_RAM, - MAP_DEVICE0, - MARVELL_MAP_DRAM, - {0} -}; -#endif -#if IMAGE_BL32 -const mmap_region_t plat_marvell_mmap[] = { - MAP_DEVICE0, - {0} -}; -#endif - -MARVELL_CASSERT_MMAP; diff --git a/plat/marvell/a8k/common/aarch64/plat_arch_config.c b/plat/marvell/a8k/common/aarch64/plat_arch_config.c deleted file mode 100644 index 06dc84115..000000000 --- a/plat/marvell/a8k/common/aarch64/plat_arch_config.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include -#include -#include -#include - -#define CCU_HTC_ASET (MVEBU_CCU_BASE(MVEBU_AP0) + 0x264) -#define MVEBU_IO_AFFINITY (0xF00) - - -static void plat_enable_affinity(void) -{ - int cluster_id; - int affinity; - - /* set CPU Affinity */ - cluster_id = plat_my_core_pos() / PLAT_MARVELL_CLUSTER_CORE_COUNT; - affinity = (MVEBU_IO_AFFINITY | (1 << cluster_id)); - mmio_write_32(CCU_HTC_ASET, affinity); - - /* set barier */ - isb(); -} - -void marvell_psci_arch_init(int die_index) -{ -#if LLC_ENABLE - /* check if LLC is in exclusive mode - * as L2 is configured to UniqueClean eviction - * (in a8k reset handler) - */ - if (llc_is_exclusive(0) == 0) - ERROR("LLC should be configured to exclusice mode\n"); -#endif - - /* Enable Affinity */ - plat_enable_affinity(); -} diff --git a/plat/marvell/a8k/common/aarch64/plat_helpers.S b/plat/marvell/a8k/common/aarch64/plat_helpers.S deleted file mode 100644 index fadc4c26b..000000000 --- a/plat/marvell/a8k/common/aarch64/plat_helpers.S +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include -#include - - .globl plat_secondary_cold_boot_setup - .globl plat_get_my_entrypoint - .globl plat_is_my_cpu_primary - .globl 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. Right - * now this is a stub function. - * ----------------------------------------------------- - */ -func plat_secondary_cold_boot_setup - mov x0, #0 - ret -endfunc plat_secondary_cold_boot_setup - - /* --------------------------------------------------------------------- - * unsigned long plat_get_my_entrypoint (void); - * - * Main job of this routine is to distinguish - * between a cold and warm boot - * For a cold boot, return 0. - * For a warm boot, read the mailbox and return the address it contains. - * - * --------------------------------------------------------------------- - */ -func plat_get_my_entrypoint - /* Read first word and compare it with magic num */ - mov_imm x0, PLAT_MARVELL_MAILBOX_BASE - ldr x1, [x0] - mov_imm x2, MVEBU_MAILBOX_MAGIC_NUM - cmp x1, x2 - beq warm_boot /* If compare failed, return 0, i.e. cold boot */ - mov x0, #0 - ret -warm_boot: - mov_imm x1, MBOX_IDX_SEC_ADDR /* Get the jump address */ - subs x1, x1, #1 - mov x2, #(MBOX_IDX_SEC_ADDR * 8) - lsl x3, x2, x1 - add x0, x0, x3 - ldr x0, [x0] - ret -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 - and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK) - cmp x0, #MVEBU_PRIMARY_CPU - cset w0, eq - ret -endfunc plat_is_my_cpu_primary - - /* ----------------------------------------------------- - * void plat_reset_handler (void); - * - * Platform specific configuration right after cpu is - * is our of reset. - * - * The plat_reset_handler can clobber x0 - x18, x30. - * ----------------------------------------------------- - */ -func plat_reset_handler - /* - * Note: the configurations below should be done before MMU, - * I Cache and L2are enabled. - * The reset handler is executed right after reset - * and before Caches are enabled. - */ - - /* Enable L1/L2 ECC and Parity */ - mrs x5, s3_1_c11_c0_2 /* L2 Ctrl */ - orr x5, x5, #(1 << 21) /* Enable L1/L2 cache ECC & Parity */ - msr s3_1_c11_c0_2, x5 /* L2 Ctrl */ - -#if LLC_ENABLE - /* - * Enable L2 UniqueClean evictions - * Note: this configuration assumes that LLC is configured - * in exclusive mode. - * Later on in the code this assumption will be validated - */ - mrs x5, s3_1_c15_c0_0 /* L2 Ctrl */ - orr x5, x5, #(1 << 14) /* Enable UniqueClean evictions with data */ - msr s3_1_c15_c0_0, x5 /* L2 Ctrl */ -#endif - - /* Instruction Barrier to allow msr command completion */ - isb - - ret -endfunc plat_reset_handler diff --git a/plat/marvell/a8k/common/ble/ble.ld.S b/plat/marvell/a8k/common/ble/ble.ld.S deleted file mode 100644 index d7a05928c..000000000 --- a/plat/marvell/a8k/common/ble/ble.ld.S +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT) -OUTPUT_ARCH(PLATFORM_LINKER_ARCH) -ENTRY(ble_main) - -MEMORY { - RAM (rwx): ORIGIN = BLE_BASE, LENGTH = BLE_LIMIT - BLE_BASE -} - -SECTIONS -{ - . = BLE_BASE; - - ro . : { - __RO_START__ = .; - *ble_main.o(.entry*) - *(.text*) - *(.rodata*) - __RO_END_UNALIGNED__ = .; - __RO_END__ = .; - } >RAM - - /* - * Define a linker symbol to mark start of the RW memory area for this - * image. - */ - __RW_START__ = . ; - - .data . : { - __DATA_START__ = .; - *(.data*) - __DATA_END__ = .; - } >RAM - - stacks . (NOLOAD) : { - __STACKS_START__ = .; - *(tzfw_normal_stacks) - __STACKS_END__ = .; - } >RAM - - .bss : { - __BSS_START__ = .; - *(.bss*) - __BSS_END__ = .; - } >RAM - - /* - * Extend the BLE binary to the maximum size allocated for it in platform - * definition files and prevent overlapping between BLE BSS section and - * additional extensions that can follow the BLE in flash image preamble. - * This situation happens for instance when secure extension is added to - * the image preamble. - */ - .fill LOADADDR(.bss) + SIZEOF(.bss) : { - FILL(0xDEADC0DE); - . = ORIGIN(RAM) + LENGTH(RAM) - 1; - BYTE(0x00) - } >RAM - - /* - * Define a linker symbol to mark end of the RW memory area for this - * image. - */ - __RW_END__ = .; - __BLE_END__ = .; - - __BSS_SIZE__ = SIZEOF(.bss); -} diff --git a/plat/marvell/a8k/common/ble/ble.mk b/plat/marvell/a8k/common/ble/ble.mk deleted file mode 100644 index b6a9cd291..000000000 --- a/plat/marvell/a8k/common/ble/ble.mk +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright (C) 2018 Marvell International Ltd. -# -# SPDX-License-Identifier: BSD-3-Clause -# https://spdx.org/licenses - -MV_DDR_PATH ?= drivers/marvell/mv_ddr - -MV_DDR_LIB = $(CURDIR)/$(BUILD_PLAT)/ble/mv_ddr_lib.a -LIBC_LIB = $(CURDIR)/$(BUILD_PLAT)/lib/libc.a -BLE_LIBS = $(MV_DDR_LIB) $(LIBC_LIB) -PLAT_MARVELL = plat/marvell - -BLE_SOURCES += $(BLE_PATH)/ble_main.c \ - $(BLE_PATH)/ble_mem.S \ - drivers/delay_timer/delay_timer.c \ - $(PLAT_MARVELL)/common/aarch64/marvell_helpers.S \ - $(PLAT_MARVELL)/common/plat_delay_timer.c \ - $(PLAT_MARVELL)/common/marvell_console.c - -PLAT_INCLUDES += -I$(MV_DDR_PATH) \ - -I$(CURDIR)/include \ - -I$(CURDIR)/include/arch/aarch64 \ - -I$(CURDIR)/include/lib/libc \ - -I$(CURDIR)/include/lib/libc/aarch64 \ - -I$(CURDIR)/drivers/marvell - -BLE_LINKERFILE := $(BLE_PATH)/ble.ld.S - -FORCE: - -$(MV_DDR_LIB): FORCE - @+make -C $(MV_DDR_PATH) --no-print-directory PLAT_INCLUDES="$(PLAT_INCLUDES)" PLATFORM=$(PLAT) ARCH=AARCH64 OBJ_DIR=$(CURDIR)/$(BUILD_PLAT)/ble diff --git a/plat/marvell/a8k/common/ble/ble_main.c b/plat/marvell/a8k/common/ble/ble_main.c deleted file mode 100644 index 5b3acec2d..000000000 --- a/plat/marvell/a8k/common/ble/ble_main.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -#include - -#include -#include -#include - -#include -#include -#include - -#define BR_FLAG_SILENT 0x1 -#define SKIP_IMAGE_CODE 0xDEADB002 - -void mailbox_clean(void) -{ - uintptr_t *mailbox = (void *)PLAT_MARVELL_MAILBOX_BASE; - - memset(mailbox, 0, PLAT_MARVELL_MAILBOX_SIZE); -} - -int exec_ble_main(int bootrom_flags) -{ - int skip = 0; - uintptr_t *mailbox = (void *)PLAT_MARVELL_MAILBOX_BASE; - - /* - * In some situations, like boot from UART, bootrom will - * request to avoid printing to console. in that case don't - * initialize the console and prints will be ignored - */ - if ((bootrom_flags & BR_FLAG_SILENT) == 0) - marvell_console_boot_init(); - - NOTICE("Starting binary extension\n"); - - /* initialize time (for delay functionality) */ - plat_delay_timer_init(); - - ble_plat_setup(&skip); - - /* if there's skip image request, bootrom will load from the image - * saved on the next address of the flash - */ - if (skip) - return SKIP_IMAGE_CODE; - - /* - * Check if the mailbox magic number is stored at index MBOX_IDX_MAGIC - * and the suspend to RAM magic number at index MBOX_IDX_SUSPEND_MAGIC. - * If the above is true, this is the recovery from suspend to RAM state. - * In such case the mailbox should remain intact, since it stores the - * warm boot jump address to be used by the TF-A in BL31. - * Othervise the mailbox should be cleaned from a garbage data. - */ - if (mailbox[MBOX_IDX_MAGIC] != MVEBU_MAILBOX_MAGIC_NUM || - mailbox[MBOX_IDX_SUSPEND_MAGIC] != MVEBU_MAILBOX_SUSPEND_STATE) { - NOTICE("Cold boot\n"); - mailbox_clean(); - } else { - void (*bootrom_exit)(void) = - (void (*)(void))mailbox[MBOX_IDX_ROM_EXIT_ADDR]; - - INFO("Recovery...\n"); - /* - * If this is recovery from suspend, two things has to be done: - * 1. Define the DRAM region as executable memory for preparing - * jump to TF-A - * 2. Instead of returning control to the BootROM, invalidate - * and flush caches, and continue execution at address stored - * in the mailbox. - * This should be done until the BootROM have a native support - * for the system restore flow. - */ - marvell_ble_prepare_exit(); - bootrom_exit(); - } - - return 0; -} - -/* NOTE: don't notify this function, all code must be added to exec_ble_main - * in order to keep the end of ble_main as a fixed address. - */ -int __attribute__ ((section(".entry"))) ble_main(int bootrom_flags) -{ - volatile int ret; - - ret = exec_ble_main(bootrom_flags); - return ret; -} diff --git a/plat/marvell/a8k/common/ble/ble_mem.S b/plat/marvell/a8k/common/ble/ble_mem.S deleted file mode 100644 index a48d5463c..000000000 --- a/plat/marvell/a8k/common/ble/ble_mem.S +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include -#include - -#define PTE_NON_EXEC_OFF 54 /* XN - eXecute Never bit offset - see VMSAv8-64 */ - - .globl marvell_ble_prepare_exit - -func marvell_ble_prepare_exit - /* - * Read the page table base and set the first page to be executable. - * This is required for jumping to DRAM for further execution. - */ - mrs x0, ttbr0_el3 - ldr x1, [x0] - mov x2, #1 - bic x1, x1, x2, lsl #PTE_NON_EXEC_OFF - str x1, [x0] - tlbi alle3 - dsb sy - isb - ret -endfunc marvell_ble_prepare_exit diff --git a/plat/marvell/a8k/common/include/a8k_plat_def.h b/plat/marvell/a8k/common/include/a8k_plat_def.h deleted file mode 100644 index de8031536..000000000 --- a/plat/marvell/a8k/common/include/a8k_plat_def.h +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef A8K_PLAT_DEF_H -#define A8K_PLAT_DEF_H - -#include - -#define MVEBU_PRIMARY_CPU 0x0 -#define MVEBU_AP0 0x0 - -/* APN806 revision ID */ -#define MVEBU_CSS_GWD_CTRL_IIDR2_REG (MVEBU_REGS_BASE + 0x610FCC) -#define GWD_IIDR2_REV_ID_OFFSET 12 -#define GWD_IIDR2_REV_ID_MASK 0xF -#define GWD_IIDR2_CHIP_ID_OFFSET 20 -#define GWD_IIDR2_CHIP_ID_MASK (0xFFFu << GWD_IIDR2_CHIP_ID_OFFSET) - -#define CHIP_ID_AP806 0x806 -#define CHIP_ID_AP807 0x807 - -#define COUNTER_FREQUENCY 25000000 - -#define MVEBU_REGS_BASE 0xF0000000 -#define MVEBU_REGS_BASE_MASK 0xF0000000 -#define MVEBU_REGS_BASE_AP(ap) MVEBU_REGS_BASE -#define MVEBU_AP_IO_BASE(ap) 0xF2000000 -#define MVEBU_CP_OFFSET 0x2000000 -#define MVEBU_CP_REGS_BASE(cp_index) (MVEBU_AP_IO_BASE(0) + \ - (cp_index) * MVEBU_CP_OFFSET) -#define MVEBU_RFU_BASE (MVEBU_REGS_BASE + 0x6F0000) -#define MVEBU_IO_WIN_BASE(ap_index) (MVEBU_RFU_BASE) -#define MVEBU_IO_WIN_GCR_OFFSET (0x70) -#define MVEBU_IO_WIN_MAX_WINS (7) - -/* Misc SoC configurations Base */ -#define MVEBU_MISC_SOC_BASE (MVEBU_REGS_BASE + 0x6F4300) - -#define MVEBU_CCU_BASE(ap_index) (MVEBU_REGS_BASE + 0x4000) -#define MVEBU_CCU_MAX_WINS (8) - -#define MVEBU_LLC_BASE(ap_index) (MVEBU_REGS_BASE + 0x8000) -#define MVEBU_DRAM_MAC_BASE (MVEBU_REGS_BASE + 0x20000) -#define MVEBU_DRAM_PHY_BASE (MVEBU_REGS_BASE + 0x20000) -#define MVEBU_SMMU_BASE (MVEBU_REGS_BASE + 0x100000) -#define MVEBU_CP_MPP_REGS(cp_index, n) (MVEBU_CP_REGS_BASE(cp_index) + \ - 0x440000 + ((n) << 2)) -#define MVEBU_PM_MPP_REGS(cp_index, n) (MVEBU_CP_REGS_BASE(cp_index) + \ - 0x440000 + ((n / 8) << 2)) -#define MVEBU_CP_GPIO_DATA_OUT(cp_index, n) \ - (MVEBU_CP_REGS_BASE(cp_index) + \ - 0x440100 + ((n > 31) ? 0x40 : 0x00)) -#define MVEBU_CP_GPIO_DATA_OUT_EN(cp_index, n) \ - (MVEBU_CP_REGS_BASE(cp_index) + \ - 0x440104 + ((n > 31) ? 0x40 : 0x00)) -#define MVEBU_CP_GPIO_DATA_IN(cp_index, n) (MVEBU_CP_REGS_BASE(cp_index) + \ - 0x440110 + ((n > 31) ? 0x40 : 0x00)) -#define MVEBU_AP_MPP_REGS(n) (MVEBU_RFU_BASE + 0x4000 + ((n) << 2)) -#define MVEBU_AP_GPIO_REGS (MVEBU_RFU_BASE + 0x5040) -#define MVEBU_AP_GPIO_DATA_IN (MVEBU_AP_GPIO_REGS + 0x10) -#define MVEBU_AP_I2C_BASE (MVEBU_REGS_BASE + 0x511000) -#define MVEBU_CP0_I2C_BASE (MVEBU_CP_REGS_BASE(0) + 0x701000) -#define MVEBU_AP_EXT_TSEN_BASE (MVEBU_RFU_BASE + 0x8084) - -#define MVEBU_AP_MC_TRUSTZONE_REG_LOW(ap, win) (MVEBU_REGS_BASE_AP(ap) + \ - 0x20080 + ((win) * 0x8)) -#define MVEBU_AP_MC_TRUSTZONE_REG_HIGH(ap, win) (MVEBU_REGS_BASE_AP(ap) + \ - 0x20084 + ((win) * 0x8)) - -/* MCI indirect access definitions */ -#define MCI_MAX_UNIT_ID 2 -/* SoC RFU / IHBx4 Control */ -#define MCIX4_REG_START_ADDRESS_REG(unit_id) (MVEBU_RFU_BASE + \ - 0x4218 + (unit_id * 0x20)) -#define MCI_REMAP_OFF_SHIFT 8 - -#define MVEBU_MCI_REG_BASE_REMAP(index) (0xFD000000 + \ - ((index) * 0x1000000)) - -#define MVEBU_PCIE_X4_MAC_BASE(x) (MVEBU_CP_REGS_BASE(x) + 0x600000) -#define MVEBU_COMPHY_BASE(x) (MVEBU_CP_REGS_BASE(x) + 0x441000) -#define MVEBU_HPIPE_BASE(x) (MVEBU_CP_REGS_BASE(x) + 0x120000) -#define MVEBU_CP_DFX_OFFSET (0x400200) - -/***************************************************************************** - * MVEBU memory map related constants - ***************************************************************************** - */ -/* Aggregate of all devices in the first GB */ -#define DEVICE0_BASE MVEBU_REGS_BASE -#define DEVICE0_SIZE 0x10000000 - -/***************************************************************************** - * GIC-400 & interrupt handling related constants - ***************************************************************************** - */ -/* Base MVEBU compatible GIC memory map */ -#define MVEBU_GICD_BASE 0x210000 -#define MVEBU_GICC_BASE 0x220000 - - -/***************************************************************************** - * AXI Configuration - ***************************************************************************** - */ -#define MVEBU_AXI_ATTR_ARCACHE_OFFSET 4 -#define MVEBU_AXI_ATTR_ARCACHE_MASK (0xF << \ - MVEBU_AXI_ATTR_ARCACHE_OFFSET) -#define MVEBU_AXI_ATTR_ARDOMAIN_OFFSET 12 -#define MVEBU_AXI_ATTR_ARDOMAIN_MASK (0x3 << \ - MVEBU_AXI_ATTR_ARDOMAIN_OFFSET) -#define MVEBU_AXI_ATTR_AWCACHE_OFFSET 20 -#define MVEBU_AXI_ATTR_AWCACHE_MASK (0xF << \ - MVEBU_AXI_ATTR_AWCACHE_OFFSET) -#define MVEBU_AXI_ATTR_AWDOMAIN_OFFSET 28 -#define MVEBU_AXI_ATTR_AWDOMAIN_MASK (0x3 << \ - MVEBU_AXI_ATTR_AWDOMAIN_OFFSET) - -/* SATA MBUS to AXI configuration */ -#define MVEBU_SATA_M2A_AXI_ARCACHE_OFFSET 1 -#define MVEBU_SATA_M2A_AXI_ARCACHE_MASK (0xF << \ - MVEBU_SATA_M2A_AXI_ARCACHE_OFFSET) -#define MVEBU_SATA_M2A_AXI_AWCACHE_OFFSET 5 -#define MVEBU_SATA_M2A_AXI_AWCACHE_MASK (0xF << \ - MVEBU_SATA_M2A_AXI_AWCACHE_OFFSET) - -/* ARM cache attributes */ -#define CACHE_ATTR_BUFFERABLE 0x1 -#define CACHE_ATTR_CACHEABLE 0x2 -#define CACHE_ATTR_READ_ALLOC 0x4 -#define CACHE_ATTR_WRITE_ALLOC 0x8 -/* Domain */ -#define DOMAIN_NON_SHAREABLE 0x0 -#define DOMAIN_INNER_SHAREABLE 0x1 -#define DOMAIN_OUTER_SHAREABLE 0x2 -#define DOMAIN_SYSTEM_SHAREABLE 0x3 - -/************************************************************************ - * Required platform porting definitions common to all - * Management Compute SubSystems (MSS) - ************************************************************************ - */ -/* - * Load address of SCP_BL2 - * SCP_BL2 is loaded to the same place as BL31. - * Once SCP_BL2 is transferred to the SCP, - * it is discarded and BL31 is loaded over the top. - */ -#ifdef SCP_IMAGE -#define SCP_BL2_BASE BL31_BASE -#define SCP_BL2_SIZE BL31_LIMIT -#endif - -#ifndef __ASSEMBLER__ -enum ap806_sar_target_dev { - SAR_PIDI_MCIX2 = 0x0, - SAR_MCIX4 = 0x1, - SAR_SPI = 0x2, - SAR_SD = 0x3, - SAR_PIDI_MCIX2_BD = 0x4, /* BootRom disabled */ - SAR_MCIX4_DB = 0x5, /* BootRom disabled */ - SAR_SPI_DB = 0x6, /* BootRom disabled */ - SAR_EMMC = 0x7 -}; - -enum io_win_target_ids { - MCI_0_TID = 0x0, - MCI_1_TID = 0x1, - MCI_2_TID = 0x2, - PIDI_TID = 0x3, - SPI_TID = 0x4, - STM_TID = 0x5, - BOOTROM_TID = 0x6, - IO_WIN_MAX_TID -}; - -enum ccu_target_ids { - IO_0_TID = 0x00, - DRAM_0_TID = 0x03, - IO_1_TID = 0x0F, - CFG_REG_TID = 0x10, - RAR_TID = 0x20, - SRAM_TID = 0x40, - DRAM_1_TID = 0xC0, - CCU_MAX_TID, - INVALID_TID = 0xFF -}; -#endif /* __ASSEMBLER__ */ - -#endif /* A8K_PLAT_DEF_H */ diff --git a/plat/marvell/a8k/common/include/ddr_info.h b/plat/marvell/a8k/common/include/ddr_info.h deleted file mode 100644 index e19036a26..000000000 --- a/plat/marvell/a8k/common/include/ddr_info.h +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#define DRAM_MAX_IFACE 1 -#define DRAM_CH0_MMAP_LOW_OFFSET 0x20200 diff --git a/plat/marvell/a8k/common/include/mentor_i2c_plat.h b/plat/marvell/a8k/common/include/mentor_i2c_plat.h deleted file mode 100644 index e03c448a6..000000000 --- a/plat/marvell/a8k/common/include/mentor_i2c_plat.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ -/* This driver provides I2C support for Marvell A8K and compatible SoCs */ - -#ifndef MENTOR_I2C_PLAT_H -#define MENTOR_I2C_PLAT_H - -#define CONFIG_SYS_TCLK 250000000 -#define CONFIG_SYS_I2C_SPEED 100000 -#define CONFIG_SYS_I2C_SLAVE 0x0 - -#define I2C_CAN_UNSTUCK - -struct mentor_i2c_regs { - uint32_t slave_address; - uint32_t data; - uint32_t control; - union { - uint32_t status; /* when reading */ - uint32_t baudrate; /* when writing */ - }; - uint32_t xtnd_slave_addr; - uint32_t reserved[2]; - uint32_t soft_reset; - uint8_t reserved2[0xa0 - 0x20]; - uint32_t unstuck; -}; - -#endif /* MENTOR_I2C_PLAT_H */ diff --git a/plat/marvell/a8k/common/include/plat_macros.S b/plat/marvell/a8k/common/include/plat_macros.S deleted file mode 100644 index 8faccf00b..000000000 --- a/plat/marvell/a8k/common/include/plat_macros.S +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef PLAT_MACROS_S -#define PLAT_MACROS_S - -#include - -/* - * Required platform porting macros - * (Provided by included headers) - */ -.macro plat_crash_print_regs -.endm - -#endif /* PLAT_MACROS_S */ diff --git a/plat/marvell/a8k/common/include/platform_def.h b/plat/marvell/a8k/common/include/platform_def.h deleted file mode 100644 index ec1c9036c..000000000 --- a/plat/marvell/a8k/common/include/platform_def.h +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef PLATFORM_DEF_H -#define PLATFORM_DEF_H - -#ifndef __ASSEMBLER__ -#include -#endif /* __ASSEMBLER__ */ - -#include -#include - -#include -#include - -/* - * Most platform porting definitions provided by included headers - */ - -/* - * DRAM Memory layout: - * +-----------------------+ - * : : - * : Linux : - * 0x04X00000-->+-----------------------+ - * | BL3-3(u-boot) |>>}>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - * |-----------------------| } | - * | BL3-[0,1, 2] | }---------------------------------> | - * |-----------------------| } || | - * | BL2 | }->FIP (loaded by || | - * |-----------------------| } BootROM to DRAM) || | - * | FIP_TOC | } || | - * 0x04120000-->|-----------------------| || | - * | BL1 (RO) | || | - * 0x04100000-->+-----------------------+ || | - * : : || | - * : Trusted SRAM section : \/ | - * 0x04040000-->+-----------------------+ Replaced by BL2 +----------------+ | - * | BL1 (RW) | <<<<<<<<<<<<<<<< | BL3-1 NOBITS | | - * 0x04037000-->|-----------------------| <<<<<<<<<<<<<<<< |----------------| | - * | | <<<<<<<<<<<<<<<< | BL3-1 PROGBITS | | - * 0x04023000-->|-----------------------| +----------------+ | - * | BL2 | | - * |-----------------------| | - * | | | - * 0x04001000-->|-----------------------| | - * | Shared | | - * 0x04000000-->+-----------------------+ | - * : : | - * : Linux : | - * : : | - * |-----------------------| | - * | | U-Boot(BL3-3) Loaded by BL2 | - * | U-Boot | <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - * 0x00000000-->+-----------------------+ - * - * Trusted SRAM section 0x4000000..0x4200000: - * ---------------------------------------- - * SRAM_BASE = 0x4001000 - * BL2_BASE = 0x4006000 - * BL2_LIMIT = BL31_BASE - * BL31_BASE = 0x4023000 = (64MB + 256KB - 0x1D000) - * BL31_PROGBITS_LIMIT = BL1_RW_BASE - * BL1_RW_BASE = 0x4037000 = (64MB + 256KB - 0x9000) - * BL1_RW_LIMIT = BL31_LIMIT = 0x4040000 - * - * - * PLAT_MARVELL_FIP_BASE = 0x4120000 - */ - -#define PLAT_MARVELL_SRAM_BASE 0xFFE1C048 -#define PLAT_MARVELL_SRAM_END 0xFFE78000 - -#define PLAT_MARVELL_ATF_BASE 0x4000000 -#define PLAT_MARVELL_ATF_LOAD_ADDR (PLAT_MARVELL_ATF_BASE + \ - 0x100000) - -#define PLAT_MARVELL_FIP_BASE (PLAT_MARVELL_ATF_LOAD_ADDR + \ - 0x20000) -#define PLAT_MARVELL_FIP_MAX_SIZE 0x4000000 - -#define PLAT_MARVELL_NORTHB_COUNT 1 - -#define PLAT_MARVELL_CLUSTER_COUNT U(2) -#define PLAT_MARVELL_CLUSTER_CORE_COUNT U(2) - -#define PLAT_MARVELL_CORE_COUNT (PLAT_MARVELL_CLUSTER_COUNT * \ - PLAT_MARVELL_CLUSTER_CORE_COUNT) - -/* DRAM[2MB..66MB] is used as Trusted ROM */ -#define PLAT_MARVELL_TRUSTED_ROM_BASE PLAT_MARVELL_ATF_LOAD_ADDR -/* 64 MB TODO: reduce this to minimum needed according to fip image size */ -#define PLAT_MARVELL_TRUSTED_ROM_SIZE 0x04000000 -/* Reserve 16M for SCP (Secure PayLoad) Trusted DRAM */ -#define PLAT_MARVELL_TRUSTED_DRAM_BASE 0x04400000 -#define PLAT_MARVELL_TRUSTED_DRAM_SIZE 0x01000000 /* 16 MB */ - -/* - * PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size - * plus a little space for growth. - */ -#define PLAT_MARVELL_MAX_BL1_RW_SIZE 0xA000 - -/* - * PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a - * little space for growth. - */ -#define PLAT_MARVELL_MAX_BL2_SIZE 0xF000 - -/* - * PLAT_ARM_MAX_BL31_SIZE is calculated using the current BL31 debug size plus a - * little space for growth. - */ -#define PLAT_MARVEL_MAX_BL31_SIZE 0x5D000 - -#define PLAT_MARVELL_CPU_ENTRY_ADDR BL1_RO_BASE - -/* GIC related definitions */ -#define PLAT_MARVELL_GICD_BASE (MVEBU_REGS_BASE + MVEBU_GICD_BASE) -#define PLAT_MARVELL_GICC_BASE (MVEBU_REGS_BASE + MVEBU_GICC_BASE) - -#define PLAT_MARVELL_G0_IRQ_PROPS(grp) \ - INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(MARVELL_IRQ_PIC0, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_LEVEL) - -#define PLAT_MARVELL_G1S_IRQ_PROPS(grp) \ - INTR_PROP_DESC(MARVELL_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, \ - grp, GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_LEVEL) - -#define PLAT_MARVELL_SHARED_RAM_CACHED 1 - -/* - * Load address of BL3-3 for this platform port - */ -#define PLAT_MARVELL_NS_IMAGE_OFFSET 0x0 - -/* System Reference Clock*/ -#define PLAT_REF_CLK_IN_HZ COUNTER_FREQUENCY - -/* - * PL011 related constants - */ -#define PLAT_MARVELL_BOOT_UART_BASE (MVEBU_REGS_BASE + 0x512000) -#define PLAT_MARVELL_BOOT_UART_CLK_IN_HZ 200000000 - -#define PLAT_MARVELL_CRASH_UART_BASE PLAT_MARVELL_BOOT_UART_BASE -#define PLAT_MARVELL_CRASH_UART_CLK_IN_HZ PLAT_MARVELL_BOOT_UART_CLK_IN_HZ - -#define PLAT_MARVELL_BL31_RUN_UART_BASE PLAT_MARVELL_BOOT_UART_BASE -#define PLAT_MARVELL_BL31_RUN_UART_CLK_IN_HZ PLAT_MARVELL_BOOT_UART_CLK_IN_HZ - -/* Recovery image enable */ -#define PLAT_RECOVERY_IMAGE_ENABLE 0 - -/* Required platform porting definitions */ -#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL1 - -/* System timer related constants */ -#define PLAT_MARVELL_NSTIMER_FRAME_ID 1 - -/* Mailbox base address (note the lower memory space - * is reserved for BLE data) - */ -#define PLAT_MARVELL_MAILBOX_BASE (MARVELL_TRUSTED_SRAM_BASE \ - + 0x400) -#define PLAT_MARVELL_MAILBOX_SIZE 0x100 -#define PLAT_MARVELL_MAILBOX_MAGIC_NUM 0x6D72766C /* mrvl */ - -/* Securities */ -#define IRQ_SEC_OS_TICK_INT MARVELL_IRQ_SEC_PHY_TIMER - -#define TRUSTED_DRAM_BASE PLAT_MARVELL_TRUSTED_DRAM_BASE -#define TRUSTED_DRAM_SIZE PLAT_MARVELL_TRUSTED_DRAM_SIZE - -#ifdef BL32 -#define BL32_BASE TRUSTED_DRAM_BASE -#define BL32_LIMIT TRUSTED_DRAM_SIZE -#endif - -#define MVEBU_PMU_IRQ_WA - -#endif /* PLATFORM_DEF_H */ diff --git a/plat/marvell/a8k/common/mss/mss_a8k.mk b/plat/marvell/a8k/common/mss/mss_a8k.mk deleted file mode 100644 index efd03c5a2..000000000 --- a/plat/marvell/a8k/common/mss/mss_a8k.mk +++ /dev/null @@ -1,21 +0,0 @@ -# -# Copyright (C) 2018 Marvell International Ltd. -# -# SPDX-License-Identifier: BSD-3-Clause -# https://spdx.org/licenses -# - -PLAT_MARVELL := plat/marvell -A8K_MSS_SOURCE := $(PLAT_MARVELL)/a8k/common/mss - -BL2_SOURCES += $(A8K_MSS_SOURCE)/mss_bl2_setup.c \ - $(MARVELL_MOCHI_DRV) - -BL31_SOURCES += $(A8K_MSS_SOURCE)/mss_pm_ipc.c - -PLAT_INCLUDES += -I$(A8K_MSS_SOURCE) - -ifneq (${SCP_BL2},) -# This define is used to inidcate the SCP image is present -$(eval $(call add_define,SCP_IMAGE)) -endif diff --git a/plat/marvell/a8k/common/mss/mss_bl2_setup.c b/plat/marvell/a8k/common/mss/mss_bl2_setup.c deleted file mode 100644 index 09b8446fa..000000000 --- a/plat/marvell/a8k/common/mss/mss_bl2_setup.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -#include -#include -#include -#include -#include - -#include -#include /* timer functionality */ - -#include "mss_scp_bootloader.h" - -/* IO windows configuration */ -#define IOW_GCR_OFFSET (0x70) - -/* MSS windows configuration */ -#define MSS_AEBR(base) (base + 0x160) -#define MSS_AIBR(base) (base + 0x164) -#define MSS_AEBR_MASK 0xFFF -#define MSS_AIBR_MASK 0xFFF - -#define MSS_EXTERNAL_SPACE 0x50000000 -#define MSS_EXTERNAL_ACCESS_BIT 28 -#define MSS_EXTERNAL_ADDR_MASK 0xfffffff -#define MSS_INTERNAL_ACCESS_BIT 28 - -struct addr_map_win ccu_mem_map[] = { - {MVEBU_CP_REGS_BASE(0), 0x4000000, IO_0_TID} -}; - -/* Since the scp_bl2 image can contain firmware for cp1 and cp0 coprocessors, - * the access to cp0 and cp1 need to be provided. More precisely it is - * required to: - * - get the information about device id which is stored in CP0 registers - * (to distinguish between cases where we have cp0 and cp1 or standalone cp0) - * - get the access to cp which is needed for loading fw for cp0/cp1 - * coprocessors - * This function configures ccu windows accordingly. - * - * Note: there is no need to restore previous ccu configuration, since in next - * phase (BL31) the init_ccu will be called (via apn806_init/ - * bl31_plat_arch_setu) and therefore the ccu configuration will be overwritten. - */ -static int bl2_plat_mmap_init(void) -{ - int cfg_num, win_id, cfg_idx; - - cfg_num = ARRAY_SIZE(ccu_mem_map); - - /* CCU window-0 should not be counted - it's already used */ - if (cfg_num > (MVEBU_CCU_MAX_WINS - 1)) { - ERROR("BL2: %s: trying to open too many windows\n", __func__); - return -1; - } - - /* Enable required CCU windows - * Do not touch CCU window 0, - * it's used for the internal registers access - */ - for (cfg_idx = 0, win_id = 1; cfg_idx < cfg_num; cfg_idx++, win_id++) { - /* Enable required CCU windows */ - ccu_win_check(&ccu_mem_map[cfg_idx]); - ccu_enable_win(MVEBU_AP0, &ccu_mem_map[cfg_idx], win_id); - } - - /* Set the default target id to PIDI */ - mmio_write_32(MVEBU_IO_WIN_BASE(MVEBU_AP0) + IOW_GCR_OFFSET, PIDI_TID); - - /* Open AMB bridge required for MG access */ - cp110_amb_init(MVEBU_CP_REGS_BASE(0)); - - if (CP_COUNT == 2) - cp110_amb_init(MVEBU_CP_REGS_BASE(1)); - - return 0; -} - -/***************************************************************************** - * Transfer SCP_BL2 from Trusted RAM using the SCP Download protocol. - * Return 0 on success, -1 otherwise. - ***************************************************************************** - */ -int bl2_plat_handle_scp_bl2(image_info_t *scp_bl2_image_info) -{ - int ret; - - INFO("BL2: Initiating SCP_BL2 transfer to SCP\n"); - - /* initialize time (for delay functionality) */ - plat_delay_timer_init(); - - ret = bl2_plat_mmap_init(); - if (ret != 0) - return ret; - - ret = scp_bootloader_transfer((void *)scp_bl2_image_info->image_base, - scp_bl2_image_info->image_size); - - if (ret == 0) - INFO("BL2: SCP_BL2 transferred to SCP\n"); - else - ERROR("BL2: SCP_BL2 transfer failure\n"); - - return ret; -} - -uintptr_t bl2_plat_get_cp_mss_regs(int ap_idx, int cp_idx) -{ - return MVEBU_CP_REGS_BASE(cp_idx) + 0x280000; -} - -uintptr_t bl2_plat_get_ap_mss_regs(int ap_idx) -{ - return MVEBU_REGS_BASE + 0x580000; -} - -uint32_t bl2_plat_get_cp_count(int ap_idx) -{ - uint32_t revision = cp110_device_id_get(MVEBU_CP_REGS_BASE(0)); - /* A8040: two CPs. - * A7040: one CP. - */ - if (revision == MVEBU_80X0_DEV_ID || - revision == MVEBU_80X0_CP115_DEV_ID) - return 2; - else - return 1; -} - -uint32_t bl2_plat_get_ap_count(void) -{ - /* A8040 and A7040 have only one AP */ - return 1; -} - -void bl2_plat_configure_mss_windows(uintptr_t mss_regs) -{ - /* set AXI External and Internal Address Bus extension */ - mmio_write_32(MSS_AEBR(mss_regs), - ((0x0 >> MSS_EXTERNAL_ACCESS_BIT) & MSS_AEBR_MASK)); - mmio_write_32(MSS_AIBR(mss_regs), - ((mss_regs >> MSS_INTERNAL_ACCESS_BIT) & MSS_AIBR_MASK)); -} diff --git a/plat/marvell/a8k/common/mss/mss_pm_ipc.c b/plat/marvell/a8k/common/mss/mss_pm_ipc.c deleted file mode 100644 index a0705832f..000000000 --- a/plat/marvell/a8k/common/mss/mss_pm_ipc.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -#include -#include -#include - -#include - -/* - * SISR is 32 bit interrupt register representing 32 interrupts - * - * +======+=============+=============+ - * + Bits + 31 + 30 - 00 + - * +======+=============+=============+ - * + Desc + MSS Msg Int + Reserved + - * +======+=============+=============+ - */ -#define MSS_SISR (MVEBU_REGS_BASE + 0x5800D0) -#define MSS_SISTR (MVEBU_REGS_BASE + 0x5800D8) - -#define MSS_MSG_INT_MASK (0x80000000) -#define MSS_TIMER_BASE (MVEBU_REGS_BASE_MASK + 0x580110) -#define MSS_TRIGGER_TIMEOUT (2000) - -/***************************************************************************** - * mss_pm_ipc_msg_send - * - * DESCRIPTION: create and transmit IPC message - ***************************************************************************** - */ -int mss_pm_ipc_msg_send(unsigned int channel_id, unsigned int msg_id, - const psci_power_state_t *target_state) -{ - /* Transmit IPC message */ -#ifndef DISABLE_CLUSTER_LEVEL - mv_pm_ipc_msg_tx(channel_id, msg_id, - (unsigned int)target_state->pwr_domain_state[ - MPIDR_AFFLVL1]); -#else - mv_pm_ipc_msg_tx(channel_id, msg_id, 0); -#endif - - return 0; -} - -/***************************************************************************** - * mss_pm_ipc_msg_trigger - * - * DESCRIPTION: Trigger IPC message interrupt to MSS - ***************************************************************************** - */ -int mss_pm_ipc_msg_trigger(void) -{ - unsigned int timeout; - unsigned int t_end; - unsigned int t_start = mmio_read_32(MSS_TIMER_BASE); - - mmio_write_32(MSS_SISR, MSS_MSG_INT_MASK); - - do { - /* wait while SCP process incoming interrupt */ - if (mmio_read_32(MSS_SISTR) != MSS_MSG_INT_MASK) - break; - - /* check timeout */ - t_end = mmio_read_32(MSS_TIMER_BASE); - - timeout = ((t_start > t_end) ? - (t_start - t_end) : (t_end - t_start)); - if (timeout > MSS_TRIGGER_TIMEOUT) { - ERROR("PM MSG Trigger Timeout\n"); - break; - } - - } while (1); - - return 0; -} diff --git a/plat/marvell/a8k/common/mss/mss_pm_ipc.h b/plat/marvell/a8k/common/mss/mss_pm_ipc.h deleted file mode 100644 index 1dfa9fa03..000000000 --- a/plat/marvell/a8k/common/mss/mss_pm_ipc.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef MSS_PM_IPC_H -#define MSS_PM_IPC_H - -#include - -/* Currently MSS does not support Cluster level Power Down */ -#define DISABLE_CLUSTER_LEVEL - - -/***************************************************************************** - * mss_pm_ipc_msg_send - * - * DESCRIPTION: create and transmit IPC message - ***************************************************************************** - */ -int mss_pm_ipc_msg_send(unsigned int channel_id, unsigned int msg_id, - const psci_power_state_t *target_state); - -/***************************************************************************** - * mss_pm_ipc_msg_trigger - * - * DESCRIPTION: Trigger IPC message interrupt to MSS - ***************************************************************************** - */ -int mss_pm_ipc_msg_trigger(void); - - -#endif /* MSS_PM_IPC_H */ diff --git a/plat/marvell/a8k/common/plat_bl1_setup.c b/plat/marvell/a8k/common/plat_bl1_setup.c deleted file mode 100644 index f9521c871..000000000 --- a/plat/marvell/a8k/common/plat_bl1_setup.c +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -#include - -void marvell_bl1_setup_mpps(void) -{ - /* Enable UART MPPs. - ** In a normal system, this is done by Bootrom. - */ - mmio_write_32(MVEBU_AP_MPP_REGS(1), 0x3000); - mmio_write_32(MVEBU_AP_MPP_REGS(2), 0x3000); -} diff --git a/plat/marvell/a8k/common/plat_bl31_setup.c b/plat/marvell/a8k/common/plat_bl31_setup.c deleted file mode 100644 index 98b3966ae..000000000 --- a/plat/marvell/a8k/common/plat_bl31_setup.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -/* In Armada-8k family AP806/AP807, CP0 connected to PIDI - * and CP1 connected to IHB via MCI #0 - */ -#define MVEBU_MCI0 0 - -static _Bool pm_fw_running; - -/* Set a weak stub for platforms that don't need to configure GPIO */ -#pragma weak marvell_gpio_config -int marvell_gpio_config(void) -{ - return 0; -} - -static void marvell_bl31_mpp_init(int cp) -{ - uint32_t reg; - - /* need to do for CP#0 only */ - if (cp) - return; - - - /* - * Enable CP0 I2C MPPs (MPP: 37-38) - * U-Boot rely on proper MPP settings for I2C EEPROM usage - * (only for CP0) - */ - reg = mmio_read_32(MVEBU_CP_MPP_REGS(0, 4)); - mmio_write_32(MVEBU_CP_MPP_REGS(0, 4), reg | 0x2200000); -} - -void marvell_bl31_mss_init(void) -{ - struct mss_pm_ctrl_block *mss_pm_crtl = - (struct mss_pm_ctrl_block *)MSS_SRAM_PM_CONTROL_BASE; - - /* Check that the image was loaded successfully */ - if (mss_pm_crtl->handshake != HOST_ACKNOWLEDGMENT) { - NOTICE("MSS PM is not supported in this build\n"); - return; - } - - /* If we got here it means that the PM firmware is running */ - pm_fw_running = 1; - - INFO("MSS IPC init\n"); - - if (mss_pm_crtl->ipc_state == IPC_INITIALIZED) - mv_pm_ipc_init(mss_pm_crtl->ipc_base_address | MVEBU_REGS_BASE); -} - -_Bool is_pm_fw_running(void) -{ - return pm_fw_running; -} - -/* For TrusTzone we treat the "target" field of addr_map_win - * struct as attribute - */ -static const struct addr_map_win tz_map[] = { - {PLAT_MARVELL_ATF_BASE, 0x200000, TZ_PERM_ABORT} -}; - -/* Configure MC TrustZone regions */ -static void marvell_bl31_security_setup(void) -{ - int tz_nr, win_id; - - tz_nr = ARRAY_SIZE(tz_map); - - for (win_id = 0; win_id < tz_nr; win_id++) - tz_enable_win(MVEBU_AP0, tz_map, win_id); -} - -/* This function overruns the same function in marvell_bl31_setup.c */ -void bl31_plat_arch_setup(void) -{ - int cp; - uintptr_t *mailbox = (void *)PLAT_MARVELL_MAILBOX_BASE; - - /* initialize the timer for mdelay/udelay functionality */ - plat_delay_timer_init(); - - /* configure apn806 */ - ap_init(); - - /* In marvell_bl31_plat_arch_setup, el3 mmu is configured. - * el3 mmu configuration MUST be called after apn806_init, if not, - * this will cause an hang in init_io_win - * (after setting the IO windows GCR values). - */ - if (mailbox[MBOX_IDX_MAGIC] != MVEBU_MAILBOX_MAGIC_NUM || - mailbox[MBOX_IDX_SUSPEND_MAGIC] != MVEBU_MAILBOX_SUSPEND_STATE) - marvell_bl31_plat_arch_setup(); - - for (cp = 0; cp < CP_COUNT; cp++) { - /* configure cp110 for CP0*/ - if (cp == 1) - mci_initialize(MVEBU_MCI0); - - /* initialize MCI & CP1 */ - cp110_init(MVEBU_CP_REGS_BASE(cp), - STREAM_ID_BASE + (cp * MAX_STREAM_ID_PER_CP)); - - /* Should be called only after setting IOB windows */ - marvell_bl31_mpp_init(cp); - } - - /* initialize IPC between MSS and ATF */ - if (mailbox[MBOX_IDX_MAGIC] != MVEBU_MAILBOX_MAGIC_NUM || - mailbox[MBOX_IDX_SUSPEND_MAGIC] != MVEBU_MAILBOX_SUSPEND_STATE) - marvell_bl31_mss_init(); - - /* Configure GPIO */ - marvell_gpio_config(); - - marvell_bl31_security_setup(); -} diff --git a/plat/marvell/a8k/common/plat_ble_setup.c b/plat/marvell/a8k/common/plat_ble_setup.c deleted file mode 100644 index 7f9e24278..000000000 --- a/plat/marvell/a8k/common/plat_ble_setup.c +++ /dev/null @@ -1,735 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/* Register for skip image use */ -#define SCRATCH_PAD_REG2 0xF06F00A8 -#define SCRATCH_PAD_SKIP_VAL 0x01 -#define NUM_OF_GPIO_PER_REG 32 - -#define MMAP_SAVE_AND_CONFIG 0 -#define MMAP_RESTORE_SAVED 1 - -/* SAR clock settings */ -#define MVEBU_AP_GEN_MGMT_BASE (MVEBU_RFU_BASE + 0x8000) -#define MVEBU_AP_SAR_REG_BASE(r) (MVEBU_AP_GEN_MGMT_BASE + 0x200 +\ - ((r) << 2)) - -#define SAR_CLOCK_FREQ_MODE_OFFSET (0) -#define SAR_CLOCK_FREQ_MODE_MASK (0x1f << SAR_CLOCK_FREQ_MODE_OFFSET) -#define SAR_PIDI_LOW_SPEED_OFFSET (20) -#define SAR_PIDI_LOW_SPEED_MASK (1 << SAR_PIDI_LOW_SPEED_OFFSET) -#define SAR_PIDI_LOW_SPEED_SHIFT (15) -#define SAR_PIDI_LOW_SPEED_SET (1 << SAR_PIDI_LOW_SPEED_SHIFT) - -#define FREQ_MODE_AP_SAR_REG_NUM (0) -#define SAR_CLOCK_FREQ_MODE(v) (((v) & SAR_CLOCK_FREQ_MODE_MASK) >> \ - SAR_CLOCK_FREQ_MODE_OFFSET) - -#define AVS_I2C_EEPROM_ADDR 0x57 /* EEPROM */ -#define AVS_EN_CTRL_REG (MVEBU_AP_GEN_MGMT_BASE + 0x130) -#define AVS_ENABLE_OFFSET (0) -#define AVS_SOFT_RESET_OFFSET (2) -#define AVS_TARGET_DELTA_OFFSET (21) - -#ifndef MVEBU_SOC_AP807 - /* AP806 SVC bits */ - #define AVS_LOW_VDD_LIMIT_OFFSET (4) - #define AVS_HIGH_VDD_LIMIT_OFFSET (12) - #define AVS_VDD_LOW_LIMIT_MASK (0xFF << AVS_LOW_VDD_LIMIT_OFFSET) - #define AVS_VDD_HIGH_LIMIT_MASK (0xFF << AVS_HIGH_VDD_LIMIT_OFFSET) -#else - /* AP807 SVC bits */ - #define AVS_LOW_VDD_LIMIT_OFFSET (3) - #define AVS_HIGH_VDD_LIMIT_OFFSET (13) - #define AVS_VDD_LOW_LIMIT_MASK (0x3FF << AVS_LOW_VDD_LIMIT_OFFSET) - #define AVS_VDD_HIGH_LIMIT_MASK (0x3FF << AVS_HIGH_VDD_LIMIT_OFFSET) -#endif - -/* VDD limit is 0.9V for A70x0 @ CPU frequency < 1600MHz */ -#define AVS_A7K_LOW_CLK_VALUE ((0x80 << AVS_TARGET_DELTA_OFFSET) | \ - (0x1A << AVS_HIGH_VDD_LIMIT_OFFSET) | \ - (0x1A << AVS_LOW_VDD_LIMIT_OFFSET) | \ - (0x1 << AVS_SOFT_RESET_OFFSET) | \ - (0x1 << AVS_ENABLE_OFFSET)) -/* VDD limit is 1.0V for all A80x0 devices */ -#define AVS_A8K_CLK_VALUE ((0x80 << AVS_TARGET_DELTA_OFFSET) | \ - (0x24 << AVS_HIGH_VDD_LIMIT_OFFSET) | \ - (0x24 << AVS_LOW_VDD_LIMIT_OFFSET) | \ - (0x1 << AVS_SOFT_RESET_OFFSET) | \ - (0x1 << AVS_ENABLE_OFFSET)) -/* VDD limit is 0.82V for all A3900 devices - * AVS offsets are not the same as in A70x0 - */ -#define AVS_A3900_CLK_VALUE ((0x80u << 24) | \ - (0x2c2 << 13) | \ - (0x2c2 << 3) | \ - (0x1 << AVS_SOFT_RESET_OFFSET) | \ - (0x1 << AVS_ENABLE_OFFSET)) -/* VDD is 0.88V for 2GHz clock */ -#define AVS_A3900_HIGH_CLK_VALUE ((0x80u << 24) | \ - (0x2f5 << 13) | \ - (0x2f5 << 3) | \ - (0x1 << AVS_SOFT_RESET_OFFSET) | \ - (0x1 << AVS_ENABLE_OFFSET)) - -#define MVEBU_AP_EFUSE_SRV_CTRL_REG (MVEBU_AP_GEN_MGMT_BASE + 0x8) -#define EFUSE_SRV_CTRL_LD_SELECT_OFFS 6 -#define EFUSE_SRV_CTRL_LD_SEL_USER_MASK (1 << EFUSE_SRV_CTRL_LD_SELECT_OFFS) - - -/* - * - Identification information in the LD-0 eFuse: - * DRO: LD0[74:65] - Not used by the SW - * Revision: LD0[78:75] - Not used by the SW - * Bin: LD0[80:79] - Not used by the SW - * SW Revision: LD0[115:113] - * Cluster 1 PWR: LD0[193] - if set to 1, power down CPU Cluster-1 - * resulting in 2 CPUs active only (7020) - */ -#define MVEBU_AP_LD_EFUSE_BASE (MVEBU_AP_GEN_MGMT_BASE + 0xF00) -/* Bits [94:63] - 32 data bits total */ -#define MVEBU_AP_LD0_94_63_EFUSE_OFFS (MVEBU_AP_LD_EFUSE_BASE + 0x8) -/* Bits [125:95] - 31 data bits total, 32nd bit is parity for bits [125:63] */ -#define MVEBU_AP_LD0_125_95_EFUSE_OFFS (MVEBU_AP_LD_EFUSE_BASE + 0xC) -/* Bits [220:189] - 32 data bits total */ -#define MVEBU_AP_LD0_220_189_EFUSE_OFFS (MVEBU_AP_LD_EFUSE_BASE + 0x18) -/* Offsets for the above 2 fields combined into single 64-bit value [125:63] */ -#define EFUSE_AP_LD0_DRO_OFFS 2 /* LD0[74:65] */ -#define EFUSE_AP_LD0_DRO_MASK 0x3FF -#define EFUSE_AP_LD0_REVID_OFFS 12 /* LD0[78:75] */ -#define EFUSE_AP_LD0_REVID_MASK 0xF -#define EFUSE_AP_LD0_BIN_OFFS 16 /* LD0[80:79] */ -#define EFUSE_AP_LD0_BIN_MASK 0x3 -#define EFUSE_AP_LD0_SWREV_OFFS 50 /* LD0[115:113] */ -#define EFUSE_AP_LD0_SWREV_MASK 0x7 - -#ifndef MVEBU_SOC_AP807 - /* AP806 AVS work points in the LD0 eFuse - * SVC1 work point: LD0[88:81] - * SVC2 work point: LD0[96:89] - * SVC3 work point: LD0[104:97] - * SVC4 work point: LD0[112:105] - */ - #define EFUSE_AP_LD0_SVC1_OFFS 18 /* LD0[88:81] */ - #define EFUSE_AP_LD0_SVC2_OFFS 26 /* LD0[96:89] */ - #define EFUSE_AP_LD0_SVC3_OFFS 34 /* LD0[104:97] */ - #define EFUSE_AP_LD0_WP_MASK 0xFF -#else - /* AP807 AVS work points in the LD0 eFuse - * SVC1 work point: LD0[91:81] - * SVC2 work point: LD0[102:92] - * SVC3 work point: LD0[113:103] - */ - #define EFUSE_AP_LD0_SVC1_OFFS 17 /* LD0[91:81] */ - #define EFUSE_AP_LD0_SVC2_OFFS 28 /* LD0[102:92] */ - #define EFUSE_AP_LD0_SVC3_OFFS 39 /* LD0[113:103] */ - #define EFUSE_AP_LD0_WP_MASK 0x3FF -#endif - -#define EFUSE_AP_LD0_SVC4_OFFS 42 /* LD0[112:105] */ - -#define EFUSE_AP_LD0_CLUSTER_DOWN_OFFS 4 - -#if MARVELL_SVC_TEST -#define MVEBU_CP_MPP_CTRL37_OFFS 20 -#define MVEBU_CP_MPP_CTRL38_OFFS 24 -#define MVEBU_CP_MPP_I2C_FUNC 2 -#define MVEBU_MPP_CTRL_MASK 0xf -#endif - -/* Return the AP revision of the chip */ -static unsigned int ble_get_ap_type(void) -{ - unsigned int chip_rev_id; - - chip_rev_id = mmio_read_32(MVEBU_CSS_GWD_CTRL_IIDR2_REG); - chip_rev_id = ((chip_rev_id & GWD_IIDR2_CHIP_ID_MASK) >> - GWD_IIDR2_CHIP_ID_OFFSET); - - return chip_rev_id; -} - -/****************************************************************************** - * The routine allows to save the CCU and IO windows configuration during DRAM - * setup and restore them afterwards before exiting the BLE stage. - * Such window configuration is required since not all default settings coming - * from the HW and the BootROM allow access to peripherals connected to - * all available CPn components. - * For instance, when the boot device is located on CP0, the IO window to CP1 - * is not opened automatically by the HW and if the DRAM SPD is located on CP1 - * i2c channel, it cannot be read at BLE stage. - * Therefore the DRAM init procedure have to provide access to all available - * CPn peripherals during the BLE stage by setting the CCU IO window to all - * CPnph addresses and by enabling the IO windows accordingly. - * Additionally this function configures the CCU GCR to DRAM, which allows - * usage or more than 4GB DRAM as it configured by the default CCU DRAM window. - * - * IN: - * MMAP_SAVE_AND_CONFIG - save the existing configuration and update it - * MMAP_RESTORE_SAVED - restore saved configuration - * OUT: - * NONE - **************************************************************************** - */ -static void ble_plat_mmap_config(int restore) -{ - if (restore == MMAP_RESTORE_SAVED) { - /* Restore all orig. settings that were modified by BLE stage */ - ccu_restore_win_all(MVEBU_AP0); - /* Restore CCU */ - iow_restore_win_all(MVEBU_AP0); - return; - } - - /* Store original values */ - ccu_save_win_all(MVEBU_AP0); - /* Save CCU */ - iow_save_win_all(MVEBU_AP0); - - init_ccu(MVEBU_AP0); - /* The configuration saved, now all the changes can be done */ - init_io_win(MVEBU_AP0); -} - -/**************************************************************************** - * Setup Adaptive Voltage Switching - this is required for some platforms - **************************************************************************** - */ -#if !MARVELL_SVC_TEST -static void ble_plat_avs_config(void) -{ - uint32_t freq_mode, device_id; - uint32_t avs_val = 0; - - freq_mode = - SAR_CLOCK_FREQ_MODE(mmio_read_32(MVEBU_AP_SAR_REG_BASE( - FREQ_MODE_AP_SAR_REG_NUM))); - /* Check which SoC is running and act accordingly */ - if (ble_get_ap_type() == CHIP_ID_AP807) { - /* Increase CPU voltage for higher CPU clock */ - if (freq_mode == CPU_2000_DDR_1200_RCLK_1200) - avs_val = AVS_A3900_HIGH_CLK_VALUE; - else - avs_val = AVS_A3900_CLK_VALUE; - } else { - /* Check which SoC is running and act accordingly */ - device_id = cp110_device_id_get(MVEBU_CP_REGS_BASE(0)); - switch (device_id) { - case MVEBU_80X0_DEV_ID: - case MVEBU_80X0_CP115_DEV_ID: - /* Always fix the default AVS value on A80x0 */ - avs_val = AVS_A8K_CLK_VALUE; - break; - case MVEBU_70X0_DEV_ID: - case MVEBU_70X0_CP115_DEV_ID: - /* Fix AVS for CPU clocks lower than 1600MHz on A70x0 */ - if ((freq_mode > CPU_1600_DDR_900_RCLK_900_2) && - (freq_mode < CPU_DDR_RCLK_INVALID)) - avs_val = AVS_A7K_LOW_CLK_VALUE; - break; - default: - ERROR("Unsupported Device ID 0x%x\n", device_id); - return; - } - } - - if (avs_val) { - VERBOSE("AVS: Setting AVS CTRL to 0x%x\n", avs_val); - mmio_write_32(AVS_EN_CTRL_REG, avs_val); - } -} -#endif -/****************************************************************************** - * Update or override current AVS work point value using data stored in EEPROM - * This is only required by QA/validation flows and activated by - * MARVELL_SVC_TEST flag. - * - * The function is expected to be called twice. - * - * First time with AVS value of 0 for testing if the EEPROM requests completely - * override the AVS value and bypass the eFuse test - * - * Second time - with non-zero AVS value obtained from eFuses as an input. - * In this case the EEPROM may contain AVS correction value (either positive - * or negative) that is added to the input AVS value and returned back for - * further processing. - ****************************************************************************** - */ -static uint32_t avs_update_from_eeprom(uint32_t avs_workpoint) -{ - uint32_t new_wp = avs_workpoint; -#if MARVELL_SVC_TEST - /* --------------------------------------------------------------------- - * EEPROM | Data description (avs_step) - * address | - * --------------------------------------------------------------------- - * 0x120 | AVS workpoint correction value - * | if not 0 and not 0xff, correct the AVS taken from eFuse - * | by the number of steps indicated by bit[6:0] - * | bit[7] defines correction direction. - * | If bit[7]=1, add the value from bit[6:0] to AVS workpoint, - * | othervise substruct this value from AVS workpoint. - * --------------------------------------------------------------------- - * 0x121 | AVS workpoint override value - * | Override the AVS workpoint with the value stored in this - * | byte. When running on AP806, the AVS workpoint is 7 bits - * | wide and override value is valid when bit[6:0] holds - * | value greater than zero and smaller than 0x33. - * | When running on AP807, the AVS workpoint is 10 bits wide. - * | Additional 2 MSB bits are supplied by EEPROM byte 0x122. - * | AVS override value is valid when byte @ 0x121 and bit[1:0] - * | of byte @ 0x122 combined have non-zero value. - * --------------------------------------------------------------------- - * 0x122 | Extended AVS workpoint override value - * | Valid only for AP807 platforms and must be less than 0x4 - * --------------------------------------------------------------------- - */ - static uint8_t avs_step[3] = {0}; - uintptr_t reg; - uint32_t val; - unsigned int ap_type = ble_get_ap_type(); - - /* Always happens on second call to this function */ - if (avs_workpoint != 0) { - /* Get correction steps from the EEPROM */ - if ((avs_step[0] != 0) && (avs_step[0] != 0xff)) { - NOTICE("AVS request to step %s by 0x%x from old 0x%x\n", - avs_step[0] & 0x80 ? "DOWN" : "UP", - avs_step[0] & 0x7f, new_wp); - if (avs_step[0] & 0x80) - new_wp -= avs_step[0] & 0x7f; - else - new_wp += avs_step[0] & 0x7f; - } - - return new_wp; - } - - /* AVS values are located in EEPROM - * at CP0 i2c bus #0, device 0x57 offset 0x120 - * The SDA and SCK pins of CP0 i2c-0: MPP[38:37], i2c function 0x2. - */ - reg = MVEBU_CP_MPP_REGS(0, 4); - val = mmio_read_32(reg); - val &= ~((MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL37_OFFS) | - (MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL38_OFFS)); - val |= (MVEBU_CP_MPP_I2C_FUNC << MVEBU_CP_MPP_CTRL37_OFFS) | - (MVEBU_CP_MPP_I2C_FUNC << MVEBU_CP_MPP_CTRL38_OFFS); - mmio_write_32(reg, val); - - /* Init CP0 i2c-0 */ - i2c_init((void *)(MVEBU_CP0_I2C_BASE)); - - /* Read EEPROM only once at the fist call! */ - i2c_read(AVS_I2C_EEPROM_ADDR, 0x120, 2, avs_step, 3); - NOTICE("== SVC test build ==\n"); - NOTICE("EEPROM holds values 0x%x, 0x%x and 0x%x\n", - avs_step[0], avs_step[1], avs_step[2]); - - /* Override the AVS value? */ - if ((ap_type != CHIP_ID_AP807) && (avs_step[1] < 0x33)) { - /* AP806 - AVS is 7 bits */ - new_wp = avs_step[1]; - - } else if (ap_type == CHIP_ID_AP807 && (avs_step[2] < 0x4)) { - /* AP807 - AVS is 10 bits */ - new_wp = avs_step[2]; - new_wp <<= 8; - new_wp |= avs_step[1]; - } - - if (new_wp == 0) - NOTICE("Ignore BAD AVS Override value in EEPROM!\n"); - else - NOTICE("Override AVS by EEPROM value 0x%x\n", new_wp); -#endif /* MARVELL_SVC_TEST */ - return new_wp; -} - -/**************************************************************************** - * SVC flow - v0.10 - * The feature is intended to configure AVS value according to eFuse values - * that are burned individually for each SoC during the test process. - * Primary AVS value is stored in HD efuse and processed on power on - * by the HW engine - * Secondary AVS value is located in LD efuse and contains 4 work points for - * various CPU frequencies. - * The Secondary AVS value is only taken into account if the SW Revision stored - * in the efuse is greater than 0 and the CPU is running in a certain speed. - **************************************************************************** - */ -static void ble_plat_svc_config(void) -{ - uint32_t reg_val, avs_workpoint, freq_pidi_mode; - uint64_t efuse; - uint32_t device_id, single_cluster; - uint16_t svc[4], perr[4], i, sw_ver; - unsigned int ap_type; - - /* Set access to LD0 */ - avs_workpoint = avs_update_from_eeprom(0); - if (avs_workpoint) - goto set_aws_wp; - - /* Set access to LD0 */ - reg_val = mmio_read_32(MVEBU_AP_EFUSE_SRV_CTRL_REG); - reg_val &= ~EFUSE_SRV_CTRL_LD_SELECT_OFFS; - mmio_write_32(MVEBU_AP_EFUSE_SRV_CTRL_REG, reg_val); - - /* Obtain the value of LD0[125:63] */ - efuse = mmio_read_32(MVEBU_AP_LD0_125_95_EFUSE_OFFS); - efuse <<= 32; - efuse |= mmio_read_32(MVEBU_AP_LD0_94_63_EFUSE_OFFS); - - /* SW Revision: - * Starting from SW revision 1 the SVC flow is supported. - * SW version 0 (efuse not programmed) should follow the - * regular AVS update flow. - */ - sw_ver = (efuse >> EFUSE_AP_LD0_SWREV_OFFS) & EFUSE_AP_LD0_SWREV_MASK; - if (sw_ver < 1) { - NOTICE("SVC: SW Revision 0x%x. SVC is not supported\n", sw_ver); -#if MARVELL_SVC_TEST - NOTICE("SVC_TEST: AVS bypassed\n"); - -#else - ble_plat_avs_config(); -#endif - return; - } - - /* Frequency mode from SAR */ - freq_pidi_mode = SAR_CLOCK_FREQ_MODE( - mmio_read_32( - MVEBU_AP_SAR_REG_BASE( - FREQ_MODE_AP_SAR_REG_NUM))); - - /* Decode all SVC work points */ - svc[0] = (efuse >> EFUSE_AP_LD0_SVC1_OFFS) & EFUSE_AP_LD0_WP_MASK; - svc[1] = (efuse >> EFUSE_AP_LD0_SVC2_OFFS) & EFUSE_AP_LD0_WP_MASK; - svc[2] = (efuse >> EFUSE_AP_LD0_SVC3_OFFS) & EFUSE_AP_LD0_WP_MASK; - - /* Fetch AP type to distinguish between AP806 and AP807 */ - ap_type = ble_get_ap_type(); - - if (ap_type != CHIP_ID_AP807) { - svc[3] = (efuse >> EFUSE_AP_LD0_SVC4_OFFS) - & EFUSE_AP_LD0_WP_MASK; - INFO("SVC: Efuse WP: [0]=0x%x, [1]=0x%x, [2]=0x%x, [3]=0x%x\n", - svc[0], svc[1], svc[2], svc[3]); - } else { - INFO("SVC: Efuse WP: [0]=0x%x, [1]=0x%x, [2]=0x%x\n", - svc[0], svc[1], svc[2]); - } - - /* Validate parity of SVC workpoint values */ - for (i = 0; i < 4; i++) { - uint8_t parity, bit; - - perr[i] = 0; - - for (bit = 1, parity = svc[i] & 1; bit < 7; bit++) - parity ^= (svc[i] >> bit) & 1; - - /* Starting from SW version 2, the parity check is mandatory */ - if ((sw_ver > 1) && (parity != ((svc[i] >> 7) & 1))) - perr[i] = 1; /* register the error */ - } - - single_cluster = mmio_read_32(MVEBU_AP_LD0_220_189_EFUSE_OFFS); - single_cluster = (single_cluster >> EFUSE_AP_LD0_CLUSTER_DOWN_OFFS) & 1; - - device_id = cp110_device_id_get(MVEBU_CP_REGS_BASE(0)); - if (device_id == MVEBU_80X0_DEV_ID || - device_id == MVEBU_80X0_CP115_DEV_ID) { - /* A8040/A8020 */ - NOTICE("SVC: DEV ID: %s, FREQ Mode: 0x%x\n", - single_cluster == 0 ? "8040" : "8020", freq_pidi_mode); - switch (freq_pidi_mode) { - case CPU_1800_DDR_1200_RCLK_1200: - case CPU_1800_DDR_1050_RCLK_1050: - if (perr[1]) - goto perror; - avs_workpoint = svc[1]; - break; - case CPU_1600_DDR_1050_RCLK_1050: - case CPU_1600_DDR_900_RCLK_900_2: - if (perr[2]) - goto perror; - avs_workpoint = svc[2]; - break; - case CPU_1300_DDR_800_RCLK_800: - case CPU_1300_DDR_650_RCLK_650: - if (perr[3]) - goto perror; - avs_workpoint = svc[3]; - break; - case CPU_2000_DDR_1200_RCLK_1200: - case CPU_2000_DDR_1050_RCLK_1050: - default: - if (perr[0]) - goto perror; - avs_workpoint = svc[0]; - break; - } - } else if (device_id == MVEBU_70X0_DEV_ID || - device_id == MVEBU_70X0_CP115_DEV_ID) { - /* A7040/A7020/A6040 */ - NOTICE("SVC: DEV ID: %s, FREQ Mode: 0x%x\n", - single_cluster == 0 ? "7040" : "7020", freq_pidi_mode); - switch (freq_pidi_mode) { - case CPU_1400_DDR_800_RCLK_800: - if (single_cluster) {/* 7020 */ - if (perr[1]) - goto perror; - avs_workpoint = svc[1]; - } else { - if (perr[0]) - goto perror; - avs_workpoint = svc[0]; - } - break; - case CPU_1200_DDR_800_RCLK_800: - if (single_cluster) {/* 7020 */ - if (perr[2]) - goto perror; - avs_workpoint = svc[2]; - } else { - if (perr[1]) - goto perror; - avs_workpoint = svc[1]; - } - break; - case CPU_800_DDR_800_RCLK_800: - case CPU_1000_DDR_800_RCLK_800: - if (single_cluster) {/* 7020 */ - if (perr[3]) - goto perror; - avs_workpoint = svc[3]; - } else { - if (perr[2]) - goto perror; - avs_workpoint = svc[2]; - } - break; - case CPU_600_DDR_800_RCLK_800: - if (perr[3]) - goto perror; - avs_workpoint = svc[3]; /* Same for 6040 and 7020 */ - break; - case CPU_1600_DDR_800_RCLK_800: /* 7020 only */ - default: - if (single_cluster) {/* 7020 */ - if (perr[0]) - goto perror; - avs_workpoint = svc[0]; - } else - avs_workpoint = 0; - break; - } - } else if (device_id == MVEBU_3900_DEV_ID) { - NOTICE("SVC: DEV ID: %s, FREQ Mode: 0x%x\n", - "3900", freq_pidi_mode); - switch (freq_pidi_mode) { - case CPU_1600_DDR_1200_RCLK_1200: - if (perr[0]) - goto perror; - avs_workpoint = svc[0]; - break; - case CPU_1300_DDR_800_RCLK_800: - if (perr[1]) - goto perror; - avs_workpoint = svc[1]; - break; - default: - if (perr[0]) - goto perror; - avs_workpoint = svc[0]; - break; - } - } else { - ERROR("SVC: Unsupported Device ID 0x%x\n", device_id); - return; - } - - /* Set AVS control if needed */ - if (avs_workpoint == 0) { - ERROR("SVC: AVS work point not changed\n"); - return; - } - - /* Remove parity bit */ - if (ap_type != CHIP_ID_AP807) - avs_workpoint &= 0x7F; - - /* Update WP from EEPROM if needed */ - avs_workpoint = avs_update_from_eeprom(avs_workpoint); - -set_aws_wp: - reg_val = mmio_read_32(AVS_EN_CTRL_REG); - NOTICE("SVC: AVS work point changed from 0x%x to 0x%x\n", - (reg_val & AVS_VDD_LOW_LIMIT_MASK) >> AVS_LOW_VDD_LIMIT_OFFSET, - avs_workpoint); - reg_val &= ~(AVS_VDD_LOW_LIMIT_MASK | AVS_VDD_HIGH_LIMIT_MASK); - reg_val |= 0x1 << AVS_ENABLE_OFFSET; - reg_val |= avs_workpoint << AVS_HIGH_VDD_LIMIT_OFFSET; - reg_val |= avs_workpoint << AVS_LOW_VDD_LIMIT_OFFSET; - mmio_write_32(AVS_EN_CTRL_REG, reg_val); - return; - -perror: - ERROR("Failed SVC WP[%d] parity check!\n", i); - ERROR("Ignoring the WP values\n"); -} - -#if PLAT_RECOVERY_IMAGE_ENABLE -static int ble_skip_image_i2c(struct skip_image *skip_im) -{ - ERROR("skipping image using i2c is not supported\n"); - /* not supported */ - return 0; -} - -static int ble_skip_image_other(struct skip_image *skip_im) -{ - ERROR("implementation missing for skip image request\n"); - /* not supported, make your own implementation */ - return 0; -} - -static int ble_skip_image_gpio(struct skip_image *skip_im) -{ - unsigned int val; - unsigned int mpp_address = 0; - unsigned int offset = 0; - - switch (skip_im->info.test.cp_ap) { - case(CP): - mpp_address = MVEBU_CP_GPIO_DATA_IN(skip_im->info.test.cp_index, - skip_im->info.gpio.num); - if (skip_im->info.gpio.num > NUM_OF_GPIO_PER_REG) - offset = skip_im->info.gpio.num - NUM_OF_GPIO_PER_REG; - else - offset = skip_im->info.gpio.num; - break; - case(AP): - mpp_address = MVEBU_AP_GPIO_DATA_IN; - offset = skip_im->info.gpio.num; - break; - } - - val = mmio_read_32(mpp_address); - val &= (1 << offset); - if ((!val && skip_im->info.gpio.button_state == HIGH) || - (val && skip_im->info.gpio.button_state == LOW)) { - mmio_write_32(SCRATCH_PAD_REG2, SCRATCH_PAD_SKIP_VAL); - return 1; - } - - return 0; -} - -/* - * This function checks if there's a skip image request: - * return values: - * 1: (true) images request been made. - * 0: (false) no image request been made. - */ -static int ble_skip_current_image(void) -{ - struct skip_image *skip_im; - - /*fetching skip image info*/ - skip_im = (struct skip_image *)plat_marvell_get_skip_image_data(); - - if (skip_im == NULL) - return 0; - - /* check if skipping image request has already been made */ - if (mmio_read_32(SCRATCH_PAD_REG2) == SCRATCH_PAD_SKIP_VAL) - return 0; - - switch (skip_im->detection_method) { - case GPIO: - return ble_skip_image_gpio(skip_im); - case I2C: - return ble_skip_image_i2c(skip_im); - case USER_DEFINED: - return ble_skip_image_other(skip_im); - } - - return 0; -} -#endif - - -int ble_plat_setup(int *skip) -{ - int ret; - unsigned int freq_mode; - - /* Power down unused CPUs */ - plat_marvell_early_cpu_powerdown(); - - /* - * Save the current CCU configuration and make required changes: - * - Allow access to DRAM larger than 4GB - * - Open memory access to all CPn peripherals - */ - ble_plat_mmap_config(MMAP_SAVE_AND_CONFIG); - -#if PLAT_RECOVERY_IMAGE_ENABLE - /* Check if there's a skip request to bootRom recovery Image */ - if (ble_skip_current_image()) { - /* close memory access to all CPn peripherals. */ - ble_plat_mmap_config(MMAP_RESTORE_SAVED); - *skip = 1; - return 0; - } -#endif - /* Do required CP-110 setups for BLE stage */ - cp110_ble_init(MVEBU_CP_REGS_BASE(0)); - - /* Setup AVS */ - ble_plat_svc_config(); - - /* read clk option from sampled-at-reset register */ - freq_mode = - SAR_CLOCK_FREQ_MODE(mmio_read_32(MVEBU_AP_SAR_REG_BASE( - FREQ_MODE_AP_SAR_REG_NUM))); - - /* work with PLL clock driver in AP807 */ - if (ble_get_ap_type() == CHIP_ID_AP807) - ap807_clocks_init(freq_mode); - - /* Do required AP setups for BLE stage */ - ap_ble_init(); - - /* Update DRAM topology (scan DIMM SPDs) */ - plat_marvell_dram_update_topology(); - - /* Kick it in */ - ret = dram_init(); - - /* Restore the original CCU configuration before exit from BLE */ - ble_plat_mmap_config(MMAP_RESTORE_SAVED); - - return ret; -} diff --git a/plat/marvell/a8k/common/plat_pm.c b/plat/marvell/a8k/common/plat_pm.c deleted file mode 100644 index 96e95c271..000000000 --- a/plat/marvell/a8k/common/plat_pm.c +++ /dev/null @@ -1,844 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#define MVEBU_PRIVATE_UID_REG 0x30 -#define MVEBU_RFU_GLOBL_SW_RST 0x84 -#define MVEBU_CCU_RVBAR(cpu) (MVEBU_REGS_BASE + 0x640 + (cpu * 4)) -#define MVEBU_CCU_CPU_UN_RESET(cpu) (MVEBU_REGS_BASE + 0x650 + (cpu * 4)) - -#define MPIDR_CPU_GET(mpidr) ((mpidr) & MPIDR_CPU_MASK) -#define MPIDR_CLUSTER_GET(mpidr) MPIDR_AFFLVL1_VAL((mpidr)) - -#define MVEBU_GPIO_MASK(index) (1 << (index % 32)) -#define MVEBU_MPP_MASK(index) (0xF << (4 * (index % 8))) -#define MVEBU_GPIO_VALUE(index, value) (value << (index % 32)) - -#define MVEBU_USER_CMD_0_REG (MVEBU_DRAM_MAC_BASE + 0x20) -#define MVEBU_USER_CMD_CH0_OFFSET 28 -#define MVEBU_USER_CMD_CH0_MASK (1 << MVEBU_USER_CMD_CH0_OFFSET) -#define MVEBU_USER_CMD_CH0_EN (1 << MVEBU_USER_CMD_CH0_OFFSET) -#define MVEBU_USER_CMD_CS_OFFSET 24 -#define MVEBU_USER_CMD_CS_MASK (0xF << MVEBU_USER_CMD_CS_OFFSET) -#define MVEBU_USER_CMD_CS_ALL (0xF << MVEBU_USER_CMD_CS_OFFSET) -#define MVEBU_USER_CMD_SR_OFFSET 6 -#define MVEBU_USER_CMD_SR_MASK (0x3 << MVEBU_USER_CMD_SR_OFFSET) -#define MVEBU_USER_CMD_SR_ENTER (0x1 << MVEBU_USER_CMD_SR_OFFSET) -#define MVEBU_MC_PWR_CTRL_REG (MVEBU_DRAM_MAC_BASE + 0x54) -#define MVEBU_MC_AC_ON_DLY_OFFSET 8 -#define MVEBU_MC_AC_ON_DLY_MASK (0xF << MVEBU_MC_AC_ON_DLY_OFFSET) -#define MVEBU_MC_AC_ON_DLY_DEF_VAR (8 << MVEBU_MC_AC_ON_DLY_OFFSET) -#define MVEBU_MC_AC_OFF_DLY_OFFSET 4 -#define MVEBU_MC_AC_OFF_DLY_MASK (0xF << MVEBU_MC_AC_OFF_DLY_OFFSET) -#define MVEBU_MC_AC_OFF_DLY_DEF_VAR (0xC << MVEBU_MC_AC_OFF_DLY_OFFSET) -#define MVEBU_MC_PHY_AUTO_OFF_OFFSET 0 -#define MVEBU_MC_PHY_AUTO_OFF_MASK (1 << MVEBU_MC_PHY_AUTO_OFF_OFFSET) -#define MVEBU_MC_PHY_AUTO_OFF_EN (1 << MVEBU_MC_PHY_AUTO_OFF_OFFSET) - -/* this lock synchronize AP multiple cores execution with MSS */ -DEFINE_BAKERY_LOCK(pm_sys_lock); - -/* Weak definitions may be overridden in specific board */ -#pragma weak plat_marvell_get_pm_cfg - -/* AP806 CPU power down /power up definitions */ -enum CPU_ID { - CPU0, - CPU1, - CPU2, - CPU3 -}; - -#define REG_WR_VALIDATE_TIMEOUT (2000) - -#define FEATURE_DISABLE_STATUS_REG \ - (MVEBU_REGS_BASE + 0x6F8230) -#define FEATURE_DISABLE_STATUS_CPU_CLUSTER_OFFSET 4 -#define FEATURE_DISABLE_STATUS_CPU_CLUSTER_MASK \ - (0x1 << FEATURE_DISABLE_STATUS_CPU_CLUSTER_OFFSET) - -#ifdef MVEBU_SOC_AP807 - #define PWRC_CPUN_CR_PWR_DN_RQ_OFFSET 1 - #define PWRC_CPUN_CR_LDO_BYPASS_RDY_OFFSET 0 -#else - #define PWRC_CPUN_CR_PWR_DN_RQ_OFFSET 0 - #define PWRC_CPUN_CR_LDO_BYPASS_RDY_OFFSET 31 -#endif - -#define PWRC_CPUN_CR_REG(cpu_id) \ - (MVEBU_REGS_BASE + 0x680000 + (cpu_id * 0x10)) -#define PWRC_CPUN_CR_PWR_DN_RQ_MASK \ - (0x1 << PWRC_CPUN_CR_PWR_DN_RQ_OFFSET) -#define PWRC_CPUN_CR_ISO_ENABLE_OFFSET 16 -#define PWRC_CPUN_CR_ISO_ENABLE_MASK \ - (0x1 << PWRC_CPUN_CR_ISO_ENABLE_OFFSET) -#define PWRC_CPUN_CR_LDO_BYPASS_RDY_MASK \ - (0x1U << PWRC_CPUN_CR_LDO_BYPASS_RDY_OFFSET) - -#define CCU_B_PRCRN_REG(cpu_id) \ - (MVEBU_REGS_BASE + 0x1A50 + \ - ((cpu_id / 2) * (0x400)) + ((cpu_id % 2) * 4)) -#define CCU_B_PRCRN_CPUPORESET_STATIC_OFFSET 0 -#define CCU_B_PRCRN_CPUPORESET_STATIC_MASK \ - (0x1 << CCU_B_PRCRN_CPUPORESET_STATIC_OFFSET) - -/* power switch fingers */ -#define AP807_PWRC_LDO_CR0_REG \ - (MVEBU_REGS_BASE + 0x680000 + 0x100) -#define AP807_PWRC_LDO_CR0_OFFSET 16 -#define AP807_PWRC_LDO_CR0_MASK \ - (0xff << AP807_PWRC_LDO_CR0_OFFSET) -#define AP807_PWRC_LDO_CR0_VAL 0xfc - -/* - * Power down CPU: - * Used to reduce power consumption, and avoid SoC unnecessary temperature rise. - */ -static int plat_marvell_cpu_powerdown(int cpu_id) -{ - uint32_t reg_val; - int exit_loop = REG_WR_VALIDATE_TIMEOUT; - - INFO("Powering down CPU%d\n", cpu_id); - - /* 1. Isolation enable */ - reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); - reg_val |= 0x1 << PWRC_CPUN_CR_ISO_ENABLE_OFFSET; - mmio_write_32(PWRC_CPUN_CR_REG(cpu_id), reg_val); - - /* 2. Read and check Isolation enabled - verify bit set to 1 */ - do { - reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); - exit_loop--; - } while (!(reg_val & (0x1 << PWRC_CPUN_CR_ISO_ENABLE_OFFSET)) && - exit_loop > 0); - - /* 3. Switch off CPU power */ - reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); - reg_val &= ~PWRC_CPUN_CR_PWR_DN_RQ_MASK; - mmio_write_32(PWRC_CPUN_CR_REG(cpu_id), reg_val); - - /* 4. Read and check Switch Off - verify bit set to 0 */ - exit_loop = REG_WR_VALIDATE_TIMEOUT; - do { - reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); - exit_loop--; - } while (reg_val & PWRC_CPUN_CR_PWR_DN_RQ_MASK && exit_loop > 0); - - if (exit_loop <= 0) - goto cpu_poweroff_error; - - /* 5. De-Assert power ready */ - reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); - reg_val &= ~PWRC_CPUN_CR_LDO_BYPASS_RDY_MASK; - mmio_write_32(PWRC_CPUN_CR_REG(cpu_id), reg_val); - - /* 6. Assert CPU POR reset */ - reg_val = mmio_read_32(CCU_B_PRCRN_REG(cpu_id)); - reg_val &= ~CCU_B_PRCRN_CPUPORESET_STATIC_MASK; - mmio_write_32(CCU_B_PRCRN_REG(cpu_id), reg_val); - - /* 7. Read and poll on Validate the CPU is out of reset */ - exit_loop = REG_WR_VALIDATE_TIMEOUT; - do { - reg_val = mmio_read_32(CCU_B_PRCRN_REG(cpu_id)); - exit_loop--; - } while (reg_val & CCU_B_PRCRN_CPUPORESET_STATIC_MASK && exit_loop > 0); - - if (exit_loop <= 0) - goto cpu_poweroff_error; - - INFO("Successfully powered down CPU%d\n", cpu_id); - - return 0; - -cpu_poweroff_error: - ERROR("ERROR: Can't power down CPU%d\n", cpu_id); - return -1; -} - -/* - * Power down CPUs 1-3 at early boot stage, - * to reduce power consumption and SoC temperature. - * This is triggered by BLE prior to DDR initialization. - * - * Note: - * All CPUs will be powered up by plat_marvell_cpu_powerup on Linux boot stage, - * which is triggered by PSCI ops (pwr_domain_on). - */ -int plat_marvell_early_cpu_powerdown(void) -{ - uint32_t cpu_cluster_status = - mmio_read_32(FEATURE_DISABLE_STATUS_REG) & - FEATURE_DISABLE_STATUS_CPU_CLUSTER_MASK; - /* if cpu_cluster_status bit is set, - * that means we have only single cluster - */ - int cluster_count = cpu_cluster_status ? 1 : 2; - - INFO("Powering off unused CPUs\n"); - - /* CPU1 is in AP806 cluster-0, which always exists, so power it down */ - if (plat_marvell_cpu_powerdown(CPU1) == -1) - return -1; - - /* - * CPU2-3 are in AP806 2nd cluster (cluster-1), - * which doesn't exists in dual-core systems. - * so need to check if we have dual-core (single cluster) - * or quad-code (2 clusters) - */ - if (cluster_count == 2) { - /* CPU2-3 are part of 2nd cluster */ - if (plat_marvell_cpu_powerdown(CPU2) == -1) - return -1; - if (plat_marvell_cpu_powerdown(CPU3) == -1) - return -1; - } - - return 0; -} - -/* - * Power up CPU - part of Linux boot stage - */ -static int plat_marvell_cpu_powerup(u_register_t mpidr) -{ - uint32_t reg_val; - int cpu_id = MPIDR_CPU_GET(mpidr), - cluster = MPIDR_CLUSTER_GET(mpidr); - int exit_loop = REG_WR_VALIDATE_TIMEOUT; - - /* calculate absolute CPU ID */ - cpu_id = cluster * PLAT_MARVELL_CLUSTER_CORE_COUNT + cpu_id; - - INFO("Powering on CPU%d\n", cpu_id); - -#ifdef MVEBU_SOC_AP807 - /* Activate 2 power switch fingers */ - reg_val = mmio_read_32(AP807_PWRC_LDO_CR0_REG); - reg_val &= ~(AP807_PWRC_LDO_CR0_MASK); - reg_val |= (AP807_PWRC_LDO_CR0_VAL << AP807_PWRC_LDO_CR0_OFFSET); - mmio_write_32(AP807_PWRC_LDO_CR0_REG, reg_val); - udelay(100); -#endif - - /* 1. Switch CPU power ON */ - reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); - reg_val |= 0x1 << PWRC_CPUN_CR_PWR_DN_RQ_OFFSET; - mmio_write_32(PWRC_CPUN_CR_REG(cpu_id), reg_val); - - /* 2. Wait for CPU on, up to 100 uSec: */ - udelay(100); - - /* 3. Assert power ready */ - reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); - reg_val |= 0x1U << PWRC_CPUN_CR_LDO_BYPASS_RDY_OFFSET; - mmio_write_32(PWRC_CPUN_CR_REG(cpu_id), reg_val); - - /* 4. Read & Validate power ready - * used in order to generate 16 Host CPU cycles - */ - do { - reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); - exit_loop--; - } while (!(reg_val & (0x1U << PWRC_CPUN_CR_LDO_BYPASS_RDY_OFFSET)) && - exit_loop > 0); - - if (exit_loop <= 0) - goto cpu_poweron_error; - - /* 5. Isolation disable */ - reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); - reg_val &= ~PWRC_CPUN_CR_ISO_ENABLE_MASK; - mmio_write_32(PWRC_CPUN_CR_REG(cpu_id), reg_val); - - /* 6. Read and check Isolation enabled - verify bit set to 1 */ - exit_loop = REG_WR_VALIDATE_TIMEOUT; - do { - reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); - exit_loop--; - } while ((reg_val & (0x1 << PWRC_CPUN_CR_ISO_ENABLE_OFFSET)) && - exit_loop > 0); - - /* 7. De Assert CPU POR reset & Core reset */ - reg_val = mmio_read_32(CCU_B_PRCRN_REG(cpu_id)); - reg_val |= 0x1 << CCU_B_PRCRN_CPUPORESET_STATIC_OFFSET; - mmio_write_32(CCU_B_PRCRN_REG(cpu_id), reg_val); - - /* 8. Read & Validate CPU POR reset */ - exit_loop = REG_WR_VALIDATE_TIMEOUT; - do { - reg_val = mmio_read_32(CCU_B_PRCRN_REG(cpu_id)); - exit_loop--; - } while (!(reg_val & (0x1 << CCU_B_PRCRN_CPUPORESET_STATIC_OFFSET)) && - exit_loop > 0); - - if (exit_loop <= 0) - goto cpu_poweron_error; - - INFO("Successfully powered on CPU%d\n", cpu_id); - - return 0; - -cpu_poweron_error: - ERROR("ERROR: Can't power up CPU%d\n", cpu_id); - return -1; -} - -static int plat_marvell_cpu_on(u_register_t mpidr) -{ - int cpu_id; - int cluster; - - /* Set barierr */ - dsbsy(); - - /* Get cpu number - use CPU ID */ - cpu_id = MPIDR_CPU_GET(mpidr); - - /* Get cluster number - use affinity level 1 */ - cluster = MPIDR_CLUSTER_GET(mpidr); - - /* Set CPU private UID */ - mmio_write_32(MVEBU_REGS_BASE + MVEBU_PRIVATE_UID_REG, cluster + 0x4); - - /* Set the cpu start address to BL1 entry point (align to 0x10000) */ - mmio_write_32(MVEBU_CCU_RVBAR(cpu_id), - PLAT_MARVELL_CPU_ENTRY_ADDR >> 16); - - /* Get the cpu out of reset */ - mmio_write_32(MVEBU_CCU_CPU_UN_RESET(cpu_id), 0x10001); - - return 0; -} - -/***************************************************************************** - * A8K handler called to check the validity of the power state - * parameter. - ***************************************************************************** - */ -static int a8k_validate_power_state(unsigned int power_state, - psci_power_state_t *req_state) -{ - int pstate = psci_get_pstate_type(power_state); - int pwr_lvl = psci_get_pstate_pwrlvl(power_state); - int i; - - if (pwr_lvl > PLAT_MAX_PWR_LVL) - return PSCI_E_INVALID_PARAMS; - - /* Sanity check the requested state */ - if (pstate == PSTATE_TYPE_STANDBY) { - /* - * It's possible to enter standby only on power level 0 - * Ignore any other power level. - */ - if (pwr_lvl != MARVELL_PWR_LVL0) - return PSCI_E_INVALID_PARAMS; - - req_state->pwr_domain_state[MARVELL_PWR_LVL0] = - MARVELL_LOCAL_STATE_RET; - } else { - for (i = MARVELL_PWR_LVL0; i <= pwr_lvl; i++) - req_state->pwr_domain_state[i] = - MARVELL_LOCAL_STATE_OFF; - } - - /* - * We expect the 'state id' to be zero. - */ - if (psci_get_pstate_id(power_state)) - return PSCI_E_INVALID_PARAMS; - - return PSCI_E_SUCCESS; -} - -/***************************************************************************** - * A8K handler called when a CPU is about to enter standby. - ***************************************************************************** - */ -static void a8k_cpu_standby(plat_local_state_t cpu_state) -{ - if (!is_pm_fw_running()) { - ERROR("%s: needs to be implemented\n", __func__); - panic(); - } -} - -/***************************************************************************** - * A8K handler called when a power domain is about to be turned on. The - * mpidr determines the CPU to be turned on. - ***************************************************************************** - */ -static int a8k_pwr_domain_on(u_register_t mpidr) -{ - /* Power up CPU (CPUs 1-3 are powered off at start of BLE) */ - plat_marvell_cpu_powerup(mpidr); - - if (is_pm_fw_running()) { - unsigned int target = - ((mpidr & 0xFF) + (((mpidr >> 8) & 0xFF) * 2)); - - /* - * pm system synchronization - used to synchronize - * multiple core access to MSS - */ - bakery_lock_get(&pm_sys_lock); - - /* send CPU ON IPC Message to MSS */ - mss_pm_ipc_msg_send(target, PM_IPC_MSG_CPU_ON, 0); - - /* trigger IPC message to MSS */ - mss_pm_ipc_msg_trigger(); - - /* pm system synchronization */ - bakery_lock_release(&pm_sys_lock); - - /* trace message */ - PM_TRACE(TRACE_PWR_DOMAIN_ON | target); - } else { - /* proprietary CPU ON exection flow */ - plat_marvell_cpu_on(mpidr); - } - - return 0; -} - -/***************************************************************************** - * A8K handler called to validate the entry point. - ***************************************************************************** - */ -static int a8k_validate_ns_entrypoint(uintptr_t entrypoint) -{ - return PSCI_E_SUCCESS; -} - -/***************************************************************************** - * A8K handler called when a power domain is about to be turned off. The - * target_state encodes the power state that each level should transition to. - ***************************************************************************** - */ -static void a8k_pwr_domain_off(const psci_power_state_t *target_state) -{ - if (is_pm_fw_running()) { - unsigned int idx = plat_my_core_pos(); - - /* Prevent interrupts from spuriously waking up this cpu */ - gicv2_cpuif_disable(); - - /* pm system synchronization - used to synchronize multiple - * core access to MSS - */ - bakery_lock_get(&pm_sys_lock); - - /* send CPU OFF IPC Message to MSS */ - mss_pm_ipc_msg_send(idx, PM_IPC_MSG_CPU_OFF, target_state); - - /* trigger IPC message to MSS */ - mss_pm_ipc_msg_trigger(); - - /* pm system synchronization */ - bakery_lock_release(&pm_sys_lock); - - /* trace message */ - PM_TRACE(TRACE_PWR_DOMAIN_OFF); - } else { - INFO("%s: is not supported without SCP\n", __func__); - } -} - -/* Get PM config to power off the SoC */ -void *plat_marvell_get_pm_cfg(void) -{ - return NULL; -} - -/* - * This function should be called on restore from - * "suspend to RAM" state when the execution flow - * has to bypass BootROM image to RAM copy and speed up - * the system recovery - * - */ -static void plat_marvell_exit_bootrom(void) -{ - marvell_exit_bootrom(PLAT_MARVELL_TRUSTED_ROM_BASE); -} - -/* - * Prepare for the power off of the system via GPIO - */ -static void plat_marvell_power_off_gpio(struct power_off_method *pm_cfg, - register_t *gpio_addr, - register_t *gpio_data) -{ - unsigned int gpio; - unsigned int idx; - unsigned int shift; - unsigned int reg; - unsigned int addr; - gpio_info_t *info; - unsigned int tog_bits; - - assert((pm_cfg->cfg.gpio.pin_count < PMIC_GPIO_MAX_NUMBER) && - (pm_cfg->cfg.gpio.step_count < PMIC_GPIO_MAX_TOGGLE_STEP)); - - /* Prepare GPIOs for PMIC */ - for (gpio = 0; gpio < pm_cfg->cfg.gpio.pin_count; gpio++) { - info = &pm_cfg->cfg.gpio.info[gpio]; - /* Set PMIC GPIO to output mode */ - reg = mmio_read_32(MVEBU_CP_GPIO_DATA_OUT_EN( - info->cp_index, info->gpio_index)); - mmio_write_32(MVEBU_CP_GPIO_DATA_OUT_EN( - info->cp_index, info->gpio_index), - reg & ~MVEBU_GPIO_MASK(info->gpio_index)); - - /* Set the appropriate MPP to GPIO mode */ - reg = mmio_read_32(MVEBU_PM_MPP_REGS(info->cp_index, - info->gpio_index)); - mmio_write_32(MVEBU_PM_MPP_REGS(info->cp_index, - info->gpio_index), - reg & ~MVEBU_MPP_MASK(info->gpio_index)); - } - - /* Wait for MPP & GPIO pre-configurations done */ - mdelay(pm_cfg->cfg.gpio.delay_ms); - - /* Toggle the GPIO values, and leave final step to be triggered - * after DDR self-refresh is enabled - */ - for (idx = 0; idx < pm_cfg->cfg.gpio.step_count; idx++) { - tog_bits = pm_cfg->cfg.gpio.seq[idx]; - - /* The GPIOs must be within same GPIO register, - * thus could get the original value by first GPIO - */ - info = &pm_cfg->cfg.gpio.info[0]; - reg = mmio_read_32(MVEBU_CP_GPIO_DATA_OUT( - info->cp_index, info->gpio_index)); - addr = MVEBU_CP_GPIO_DATA_OUT(info->cp_index, info->gpio_index); - - for (gpio = 0; gpio < pm_cfg->cfg.gpio.pin_count; gpio++) { - shift = pm_cfg->cfg.gpio.info[gpio].gpio_index % 32; - if (GPIO_LOW == (tog_bits & (1 << gpio))) - reg &= ~(1 << shift); - else - reg |= (1 << shift); - } - - /* Set the GPIO register, for last step just store - * register address and values to system registers - */ - if (idx < pm_cfg->cfg.gpio.step_count - 1) { - mmio_write_32(MVEBU_CP_GPIO_DATA_OUT( - info->cp_index, info->gpio_index), reg); - mdelay(pm_cfg->cfg.gpio.delay_ms); - } else { - /* Save GPIO register and address values for - * finishing the power down operation later - */ - *gpio_addr = addr; - *gpio_data = reg; - } - } -} - -/* - * Prepare for the power off of the system - */ -static void plat_marvell_power_off_prepare(struct power_off_method *pm_cfg, - register_t *addr, register_t *data) -{ - switch (pm_cfg->type) { - case PMIC_GPIO: - plat_marvell_power_off_gpio(pm_cfg, addr, data); - break; - default: - break; - } -} - -/***************************************************************************** - * A8K handler called when a power domain is about to be suspended. The - * target_state encodes the power state that each level should transition to. - ***************************************************************************** - */ -static void a8k_pwr_domain_suspend(const psci_power_state_t *target_state) -{ - if (is_pm_fw_running()) { - unsigned int idx; - - /* Prevent interrupts from spuriously waking up this cpu */ - gicv2_cpuif_disable(); - - idx = plat_my_core_pos(); - - /* pm system synchronization - used to synchronize multiple - * core access to MSS - */ - bakery_lock_get(&pm_sys_lock); - - /* send CPU Suspend IPC Message to MSS */ - mss_pm_ipc_msg_send(idx, PM_IPC_MSG_CPU_SUSPEND, target_state); - - /* trigger IPC message to MSS */ - mss_pm_ipc_msg_trigger(); - - /* pm system synchronization */ - bakery_lock_release(&pm_sys_lock); - - /* trace message */ - PM_TRACE(TRACE_PWR_DOMAIN_SUSPEND); - } else { - uintptr_t *mailbox = (void *)PLAT_MARVELL_MAILBOX_BASE; - - INFO("Suspending to RAM\n"); - - marvell_console_runtime_end(); - - /* Prevent interrupts from spuriously waking up this cpu */ - gicv2_cpuif_disable(); - - mailbox[MBOX_IDX_SUSPEND_MAGIC] = MVEBU_MAILBOX_SUSPEND_STATE; - mailbox[MBOX_IDX_ROM_EXIT_ADDR] = (uintptr_t)&plat_marvell_exit_bootrom; - -#if PLAT_MARVELL_SHARED_RAM_CACHED - flush_dcache_range(PLAT_MARVELL_MAILBOX_BASE + - MBOX_IDX_SUSPEND_MAGIC * sizeof(uintptr_t), - 2 * sizeof(uintptr_t)); -#endif - /* Flush and disable LLC before going off-power */ - llc_disable(0); - - isb(); - /* - * Do not halt here! - * The function must return for allowing the caller function - * psci_power_up_finish() to do the proper context saving and - * to release the CPU lock. - */ - } -} - -/***************************************************************************** - * A8K handler called when a power domain has just been powered on after - * being turned off earlier. The target_state encodes the low power state that - * each level has woken up from. - ***************************************************************************** - */ -static void a8k_pwr_domain_on_finish(const psci_power_state_t *target_state) -{ - /* arch specific configuration */ - marvell_psci_arch_init(0); - - /* Interrupt initialization */ - gicv2_pcpu_distif_init(); - gicv2_cpuif_enable(); - - if (is_pm_fw_running()) { - /* trace message */ - PM_TRACE(TRACE_PWR_DOMAIN_ON_FINISH); - } -} - -/***************************************************************************** - * A8K handler called when a power domain has just been powered on after - * having been suspended earlier. The target_state encodes the low power state - * that each level has woken up from. - * TODO: At the moment we reuse the on finisher and reinitialize the secure - * context. Need to implement a separate suspend finisher. - ***************************************************************************** - */ -static void a8k_pwr_domain_suspend_finish( - const psci_power_state_t *target_state) -{ - if (is_pm_fw_running()) { - /* arch specific configuration */ - marvell_psci_arch_init(0); - - /* Interrupt initialization */ - gicv2_cpuif_enable(); - - /* trace message */ - PM_TRACE(TRACE_PWR_DOMAIN_SUSPEND_FINISH); - } else { - uintptr_t *mailbox = (void *)PLAT_MARVELL_MAILBOX_BASE; - - /* Only primary CPU requres platform init */ - if (!plat_my_core_pos()) { - /* Initialize the console to provide - * early debug support - */ - marvell_console_runtime_init(); - - bl31_plat_arch_setup(); - marvell_bl31_platform_setup(); - /* - * Remove suspend to RAM marker from the mailbox - * for treating a regular reset as a cold boot - */ - mailbox[MBOX_IDX_SUSPEND_MAGIC] = 0; - mailbox[MBOX_IDX_ROM_EXIT_ADDR] = 0; -#if PLAT_MARVELL_SHARED_RAM_CACHED - flush_dcache_range(PLAT_MARVELL_MAILBOX_BASE + - MBOX_IDX_SUSPEND_MAGIC * sizeof(uintptr_t), - 2 * sizeof(uintptr_t)); -#endif - } - } -} - -/***************************************************************************** - * This handler is called by the PSCI implementation during the `SYSTEM_SUSPEND` - * call to get the `power_state` parameter. This allows the platform to encode - * the appropriate State-ID field within the `power_state` parameter which can - * be utilized in `pwr_domain_suspend()` to suspend to system affinity level. - ***************************************************************************** - */ -static void a8k_get_sys_suspend_power_state(psci_power_state_t *req_state) -{ - /* lower affinities use PLAT_MAX_OFF_STATE */ - for (int i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++) - req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE; -} - -static void -__dead2 a8k_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state) -{ - struct power_off_method *pm_cfg; - unsigned int srcmd; - unsigned int sdram_reg; - register_t gpio_data = 0, gpio_addr = 0; - - if (is_pm_fw_running()) { - psci_power_down_wfi(); - panic(); - } - - pm_cfg = (struct power_off_method *)plat_marvell_get_pm_cfg(); - - /* Prepare for power off */ - plat_marvell_power_off_prepare(pm_cfg, &gpio_addr, &gpio_data); - - /* First step to enable DDR self-refresh - * to keep the data during suspend - */ - mmio_write_32(MVEBU_MC_PWR_CTRL_REG, 0x8C1); - - /* Save DDR self-refresh second step register - * and value to be issued later - */ - sdram_reg = MVEBU_USER_CMD_0_REG; - srcmd = mmio_read_32(sdram_reg); - srcmd &= ~(MVEBU_USER_CMD_CH0_MASK | MVEBU_USER_CMD_CS_MASK | - MVEBU_USER_CMD_SR_MASK); - srcmd |= (MVEBU_USER_CMD_CH0_EN | MVEBU_USER_CMD_CS_ALL | - MVEBU_USER_CMD_SR_ENTER); - - /* - * Wait for DRAM is done using registers access only. - * At this stage any access to DRAM (procedure call) will - * release it from the self-refresh mode - */ - __asm__ volatile ( - /* Align to a cache line */ - " .balign 64\n\t" - - /* Enter self refresh */ - " str %[srcmd], [%[sdram_reg]]\n\t" - - /* - * Wait 100 cycles for DDR to enter self refresh, by - * doing 50 times two instructions. - */ - " mov x1, #50\n\t" - "1: subs x1, x1, #1\n\t" - " bne 1b\n\t" - - /* Issue the command to trigger the SoC power off */ - " str %[gpio_data], [%[gpio_addr]]\n\t" - - /* Trap the processor */ - " b .\n\t" - : : [srcmd] "r" (srcmd), [sdram_reg] "r" (sdram_reg), - [gpio_addr] "r" (gpio_addr), [gpio_data] "r" (gpio_data) - : "x1"); - - panic(); -} - -/***************************************************************************** - * A8K handlers to shutdown/reboot the system - ***************************************************************************** - */ - -/* Set a weak stub for platforms that don't configure system power off */ -#pragma weak system_power_off -int system_power_off(void) -{ - return 0; -} - -static void __dead2 a8k_system_off(void) -{ - /* Call the platform specific system power off function */ - system_power_off(); - - /* board doesn't have a system off implementation */ - ERROR("%s: needs to be implemented\n", __func__); - panic(); -} - -void plat_marvell_system_reset(void) -{ - mmio_write_32(MVEBU_RFU_BASE + MVEBU_RFU_GLOBL_SW_RST, 0x0); -} - -static void __dead2 a8k_system_reset(void) -{ - plat_marvell_system_reset(); - - /* we shouldn't get to this point */ - panic(); -} - -/***************************************************************************** - * Export the platform handlers via plat_arm_psci_pm_ops. The ARM Standard - * platform layer will take care of registering the handlers with PSCI. - ***************************************************************************** - */ -const plat_psci_ops_t plat_arm_psci_pm_ops = { - .cpu_standby = a8k_cpu_standby, - .pwr_domain_on = a8k_pwr_domain_on, - .pwr_domain_off = a8k_pwr_domain_off, - .pwr_domain_suspend = a8k_pwr_domain_suspend, - .pwr_domain_on_finish = a8k_pwr_domain_on_finish, - .get_sys_suspend_power_state = a8k_get_sys_suspend_power_state, - .pwr_domain_suspend_finish = a8k_pwr_domain_suspend_finish, - .pwr_domain_pwr_down_wfi = a8k_pwr_domain_pwr_down_wfi, - .system_off = a8k_system_off, - .system_reset = a8k_system_reset, - .validate_power_state = a8k_validate_power_state, - .validate_ns_entrypoint = a8k_validate_ns_entrypoint -}; diff --git a/plat/marvell/a8k/common/plat_pm_trace.c b/plat/marvell/a8k/common/plat_pm_trace.c deleted file mode 100644 index f589ff31b..000000000 --- a/plat/marvell/a8k/common/plat_pm_trace.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include - -#include -#include - -#ifdef PM_TRACE_ENABLE - -/* core trace APIs */ -core_trace_func funcTbl[PLATFORM_CORE_COUNT] = { - pm_core_0_trace, - pm_core_1_trace, - pm_core_2_trace, - pm_core_3_trace}; - -/***************************************************************************** - * pm_core0_trace - * pm_core1_trace - * pm_core2_trace - * pm_core_3trace - * - * This functions set trace info into core cyclic trace queue in MSS SRAM - * memory space - ***************************************************************************** - */ -void pm_core_0_trace(unsigned int trace) -{ - unsigned int current_position_core_0 = - mmio_read_32(AP_MSS_ATF_CORE_0_CTRL_BASE); - mmio_write_32((AP_MSS_ATF_CORE_0_INFO_BASE + - (current_position_core_0 * AP_MSS_ATF_CORE_ENTRY_SIZE)), - mmio_read_32(AP_MSS_TIMER_BASE)); - mmio_write_32((AP_MSS_ATF_CORE_0_INFO_TRACE + - (current_position_core_0 * AP_MSS_ATF_CORE_ENTRY_SIZE)), - trace); - mmio_write_32(AP_MSS_ATF_CORE_0_CTRL_BASE, - ((current_position_core_0 + 1) & - AP_MSS_ATF_TRACE_SIZE_MASK)); -} - -void pm_core_1_trace(unsigned int trace) -{ - unsigned int current_position_core_1 = - mmio_read_32(AP_MSS_ATF_CORE_1_CTRL_BASE); - mmio_write_32((AP_MSS_ATF_CORE_1_INFO_BASE + - (current_position_core_1 * AP_MSS_ATF_CORE_ENTRY_SIZE)), - mmio_read_32(AP_MSS_TIMER_BASE)); - mmio_write_32((AP_MSS_ATF_CORE_1_INFO_TRACE + - (current_position_core_1 * AP_MSS_ATF_CORE_ENTRY_SIZE)), - trace); - mmio_write_32(AP_MSS_ATF_CORE_1_CTRL_BASE, - ((current_position_core_1 + 1) & - AP_MSS_ATF_TRACE_SIZE_MASK)); -} - -void pm_core_2_trace(unsigned int trace) -{ - unsigned int current_position_core_2 = - mmio_read_32(AP_MSS_ATF_CORE_2_CTRL_BASE); - mmio_write_32((AP_MSS_ATF_CORE_2_INFO_BASE + - (current_position_core_2 * AP_MSS_ATF_CORE_ENTRY_SIZE)), - mmio_read_32(AP_MSS_TIMER_BASE)); - mmio_write_32((AP_MSS_ATF_CORE_2_INFO_TRACE + - (current_position_core_2 * AP_MSS_ATF_CORE_ENTRY_SIZE)), - trace); - mmio_write_32(AP_MSS_ATF_CORE_2_CTRL_BASE, - ((current_position_core_2 + 1) & - AP_MSS_ATF_TRACE_SIZE_MASK)); -} - -void pm_core_3_trace(unsigned int trace) -{ - unsigned int current_position_core_3 = - mmio_read_32(AP_MSS_ATF_CORE_3_CTRL_BASE); - mmio_write_32((AP_MSS_ATF_CORE_3_INFO_BASE + - (current_position_core_3 * AP_MSS_ATF_CORE_ENTRY_SIZE)), - mmio_read_32(AP_MSS_TIMER_BASE)); - mmio_write_32((AP_MSS_ATF_CORE_3_INFO_TRACE + - (current_position_core_3 * AP_MSS_ATF_CORE_ENTRY_SIZE)), - trace); - mmio_write_32(AP_MSS_ATF_CORE_3_CTRL_BASE, - ((current_position_core_3 + 1) & - AP_MSS_ATF_TRACE_SIZE_MASK)); -} -#endif /* PM_TRACE_ENABLE */ diff --git a/plat/marvell/a8k/common/plat_thermal.c b/plat/marvell/a8k/common/plat_thermal.c deleted file mode 100644 index a2fc0d0ab..000000000 --- a/plat/marvell/a8k/common/plat_thermal.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include -#include -#include - -#include - -#define THERMAL_TIMEOUT 1200 - -#define THERMAL_SEN_CTRL_LSB_STRT_OFFSET 0 -#define THERMAL_SEN_CTRL_LSB_STRT_MASK \ - (0x1 << THERMAL_SEN_CTRL_LSB_STRT_OFFSET) -#define THERMAL_SEN_CTRL_LSB_RST_OFFSET 1 -#define THERMAL_SEN_CTRL_LSB_RST_MASK \ - (0x1 << THERMAL_SEN_CTRL_LSB_RST_OFFSET) -#define THERMAL_SEN_CTRL_LSB_EN_OFFSET 2 -#define THERMAL_SEN_CTRL_LSB_EN_MASK \ - (0x1 << THERMAL_SEN_CTRL_LSB_EN_OFFSET) - -#define THERMAL_SEN_CTRL_STATS_VALID_OFFSET 16 -#define THERMAL_SEN_CTRL_STATS_VALID_MASK \ - (0x1 << THERMAL_SEN_CTRL_STATS_VALID_OFFSET) -#define THERMAL_SEN_CTRL_STATS_TEMP_OUT_OFFSET 0 -#define THERMAL_SEN_CTRL_STATS_TEMP_OUT_MASK \ - (0x3FF << THERMAL_SEN_CTRL_STATS_TEMP_OUT_OFFSET) - -#define THERMAL_SEN_OUTPUT_MSB 512 -#define THERMAL_SEN_OUTPUT_COMP 1024 - -struct tsen_regs { - uint32_t ext_tsen_ctrl_lsb; - uint32_t ext_tsen_ctrl_msb; - uint32_t ext_tsen_status; -}; - -static int ext_tsen_probe(struct tsen_config *tsen_cfg) -{ - uint32_t reg, timeout = 0; - struct tsen_regs *base; - - if (tsen_cfg == NULL && tsen_cfg->regs_base == NULL) { - ERROR("initial thermal sensor configuration is missing\n"); - return -1; - } - base = (struct tsen_regs *)tsen_cfg->regs_base; - - INFO("initializing thermal sensor\n"); - - /* initialize thermal sensor hardware reset once */ - reg = mmio_read_32((uintptr_t)&base->ext_tsen_ctrl_lsb); - reg &= ~THERMAL_SEN_CTRL_LSB_RST_OFFSET; /* de-assert TSEN_RESET */ - reg |= THERMAL_SEN_CTRL_LSB_EN_MASK; /* set TSEN_EN to 1 */ - reg |= THERMAL_SEN_CTRL_LSB_STRT_MASK; /* set TSEN_START to 1 */ - mmio_write_32((uintptr_t)&base->ext_tsen_ctrl_lsb, reg); - - reg = mmio_read_32((uintptr_t)&base->ext_tsen_status); - while ((reg & THERMAL_SEN_CTRL_STATS_VALID_MASK) == 0 && - timeout < THERMAL_TIMEOUT) { - udelay(100); - reg = mmio_read_32((uintptr_t)&base->ext_tsen_status); - timeout++; - } - - if ((reg & THERMAL_SEN_CTRL_STATS_VALID_MASK) == 0) { - ERROR("thermal sensor is not ready\n"); - return -1; - } - - tsen_cfg->tsen_ready = 1; - - VERBOSE("thermal sensor was initialized\n"); - - return 0; -} - -static int ext_tsen_read(struct tsen_config *tsen_cfg, int *temp) -{ - uint32_t reg; - struct tsen_regs *base; - - if (tsen_cfg == NULL && !tsen_cfg->tsen_ready) { - ERROR("thermal sensor was not initialized\n"); - return -1; - } - base = (struct tsen_regs *)tsen_cfg->regs_base; - - reg = mmio_read_32((uintptr_t)&base->ext_tsen_status); - reg = ((reg & THERMAL_SEN_CTRL_STATS_TEMP_OUT_MASK) >> - THERMAL_SEN_CTRL_STATS_TEMP_OUT_OFFSET); - - /* - * TSEN output format is signed as a 2s complement number - * ranging from-512 to +511. when MSB is set, need to - * calculate the complement number - */ - if (reg >= THERMAL_SEN_OUTPUT_MSB) - reg -= THERMAL_SEN_OUTPUT_COMP; - - if (tsen_cfg->tsen_divisor == 0) { - ERROR("thermal sensor divisor cannot be zero\n"); - return -1; - } - - *temp = ((tsen_cfg->tsen_gain * ((int)reg)) + - tsen_cfg->tsen_offset) / tsen_cfg->tsen_divisor; - - return 0; -} - -static struct tsen_config tsen_cfg = { - .tsen_offset = 153400, - .tsen_gain = 425, - .tsen_divisor = 1000, - .tsen_ready = 0, - .regs_base = (void *)MVEBU_AP_EXT_TSEN_BASE, - .ptr_tsen_probe = ext_tsen_probe, - .ptr_tsen_read = ext_tsen_read -}; - -struct tsen_config *marvell_thermal_config_get(void) -{ - return &tsen_cfg; -} diff --git a/plat/marvell/armada/a3700/a3700/board/pm_src.c b/plat/marvell/armada/a3700/a3700/board/pm_src.c new file mode 100644 index 000000000..d6eca5d16 --- /dev/null +++ b/plat/marvell/armada/a3700/a3700/board/pm_src.c @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include + +/* This struct provides the PM wake up src configuration */ +static struct pm_wake_up_src_config wake_up_src_cfg = { + .wake_up_src_num = 3, + .wake_up_src[0] = { + .wake_up_src_type = WAKE_UP_SRC_GPIO, + .wake_up_data = { + .gpio_data.bank_num = 0, /* North Bridge */ + .gpio_data.gpio_num = 14 + } + }, + .wake_up_src[1] = { + .wake_up_src_type = WAKE_UP_SRC_GPIO, + .wake_up_data = { + .gpio_data.bank_num = 1, /* South Bridge */ + .gpio_data.gpio_num = 2 + } + }, + .wake_up_src[2] = { + .wake_up_src_type = WAKE_UP_SRC_UART1, + } +}; + +struct pm_wake_up_src_config *mv_wake_up_src_config_get(void) +{ + return &wake_up_src_cfg; +} + diff --git a/plat/marvell/armada/a3700/a3700/mvebu_def.h b/plat/marvell/armada/a3700/a3700/mvebu_def.h new file mode 100644 index 000000000..dad1085f8 --- /dev/null +++ b/plat/marvell/armada/a3700/a3700/mvebu_def.h @@ -0,0 +1,13 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef MVEBU_DEF_H +#define MVEBU_DEF_H + +#include + +#endif /* MVEBU_DEF_H */ diff --git a/plat/marvell/armada/a3700/a3700/plat_bl31_setup.c b/plat/marvell/armada/a3700/a3700/plat_bl31_setup.c new file mode 100644 index 000000000..6862a8670 --- /dev/null +++ b/plat/marvell/armada/a3700/a3700/plat_bl31_setup.c @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include +#include +#include +#include +#include + +/* This routine does MPP initialization */ +static void marvell_bl31_mpp_init(void) +{ + mmio_clrbits_32(MVEBU_NB_GPIO_SEL_REG, 1 << MVEBU_GPIO_TW1_GPIO_EN_OFF); + + /* Set hidden GPIO setting for SPI. + * In north_bridge_pin_out_en_high register 13804, + * bit 28 is the one which enables CS, CLK pins to be + * output, need to set it to 1. + * The initial value of this bit is 1, but in UART boot mode + * initialization, this bit is disabled and the SPI CS and CLK pins + * are used for downloading image purpose; so after downloading, + * we should set this bit to 1 again to enable SPI CS and CLK pins. + * And anyway, this bit value should be 1 in all modes, + * so here we does not judge boot mode and set this bit to 1 always. + */ + mmio_setbits_32(MVEBU_NB_GPIO_OUTPUT_EN_HIGH_REG, + 1 << MVEBU_GPIO_NB_SPI_PIN_MODE_OFF); +} + +/* This function overruns the same function in marvell_bl31_setup.c */ +void bl31_plat_arch_setup(void) +{ + struct dec_win_config *io_dec_map; + uint32_t dec_win_num; + struct dram_win_map dram_wins_map; + + marvell_bl31_plat_arch_setup(); + + /* MPP init */ + marvell_bl31_mpp_init(); + + /* initialize the timer for delay functionality */ + plat_delay_timer_init(); + + /* CPU address decoder windows initialization. */ + cpu_wins_init(); + + /* fetch CPU-DRAM window mapping information by reading + * CPU-DRAM decode windows (only the enabled ones) + */ + dram_win_map_build(&dram_wins_map); + + /* Get IO address decoder windows */ + if (marvell_get_io_dec_win_conf(&io_dec_map, &dec_win_num)) { + printf("No IO address decoder windows configurations found!\n"); + return; + } + + /* IO address decoder init */ + if (init_io_addr_dec(&dram_wins_map, io_dec_map, dec_win_num)) { + printf("IO address decoder windows initialization failed!\n"); + return; + } +} diff --git a/plat/marvell/armada/a3700/a3700/platform.mk b/plat/marvell/armada/a3700/a3700/platform.mk new file mode 100644 index 000000000..bd9464aae --- /dev/null +++ b/plat/marvell/armada/a3700/a3700/platform.mk @@ -0,0 +1,10 @@ +# +# Copyright (C) 2018 Marvell International Ltd. +# +# SPDX-License-Identifier: BSD-3-Clause +# https://spdx.org/licenses +# + +include plat/marvell/armada/a3700/common/a3700_common.mk + +include plat/marvell/armada/common/marvell_common.mk diff --git a/plat/marvell/armada/a3700/common/a3700_common.mk b/plat/marvell/armada/a3700/common/a3700_common.mk new file mode 100644 index 000000000..36865a896 --- /dev/null +++ b/plat/marvell/armada/a3700/common/a3700_common.mk @@ -0,0 +1,170 @@ +# +# Copyright (C) 2018 Marvell International Ltd. +# +# SPDX-License-Identifier: BSD-3-Clause +# https://spdx.org/licenses +# + +MARVELL_PLAT_BASE := plat/marvell/armada +MARVELL_PLAT_INCLUDE_BASE := include/plat/marvell/armada +PLAT_FAMILY := a3700 +PLAT_FAMILY_BASE := $(MARVELL_PLAT_BASE)/$(PLAT_FAMILY) +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 + +#*********** A3700 ************* +DOIMAGEPATH := $(WTP) +DOIMAGETOOL := $(DOIMAGEPATH)/wtptp/linux/tbb_linux + +ifeq ($(MARVELL_SECURE_BOOT),1) +DOIMAGE_CFG := $(DOIMAGEPATH)/atf-tim.txt +IMAGESPATH := $(DOIMAGEPATH)/tim/trusted + +TIMNCFG := $(DOIMAGEPATH)/atf-timN.txt +TIMNSIG := $(IMAGESPATH)/timnsign.txt +TIM2IMGARGS := -i $(DOIMAGE_CFG) -n $(TIMNCFG) +TIMN_IMAGE := $$(grep "Image Filename:" -m 1 $(TIMNCFG) | cut -c 17-) +else #MARVELL_SECURE_BOOT +DOIMAGE_CFG := $(DOIMAGEPATH)/atf-ntim.txt +IMAGESPATH := $(DOIMAGEPATH)/tim/untrusted +TIM2IMGARGS := -i $(DOIMAGE_CFG) +endif #MARVELL_SECURE_BOOT + +TIMBUILD := $(DOIMAGEPATH)/script/buildtim.sh +TIM2IMG := $(DOIMAGEPATH)/script/tim2img.pl + +# WTMI_IMG is used to specify the customized RTOS image running over +# Service CPU (CM3 processor). By the default, it points to a +# baremetal binary of fuse programming in A3700_utils. +WTMI_IMG := $(DOIMAGEPATH)/wtmi/fuse/build/fuse.bin + +# WTMI_SYSINIT_IMG is used for the system early initialization, +# such as AVS settings, clock-tree setup and dynamic DDR PHY training. +# After the initialization is done, this image will be wiped out +# from the memory and CM3 will continue with RTOS image or other application. +WTMI_SYSINIT_IMG := $(DOIMAGEPATH)/wtmi/sys_init/build/sys_init.bin + +# WTMI_MULTI_IMG is composed of CM3 RTOS image (WTMI_IMG) +# and sys-init image (WTMI_SYSINIT_IMG). +WTMI_MULTI_IMG := $(DOIMAGEPATH)/wtmi/build/wtmi.bin + +WTMI_ENC_IMG := $(DOIMAGEPATH)/wtmi/build/wtmi-enc.bin +BUILD_UART := uart-images + +SRCPATH := $(dir $(BL33)) + +CLOCKSPRESET ?= CPU_800_DDR_800 + +DDR_TOPOLOGY ?= 0 + +BOOTDEV ?= SPINOR +PARTNUM ?= 0 + +TIM_IMAGE := $$(grep "Image Filename:" -m 1 $(DOIMAGE_CFG) | cut -c 17-) +TIMBLDARGS := $(MARVELL_SECURE_BOOT) $(BOOTDEV) $(IMAGESPATH) $(DOIMAGEPATH) $(CLOCKSPRESET) \ + $(DDR_TOPOLOGY) $(PARTNUM) $(DEBUG) $(DOIMAGE_CFG) $(TIMNCFG) $(TIMNSIG) 1 +TIMBLDUARTARGS := $(MARVELL_SECURE_BOOT) UART $(IMAGESPATH) $(DOIMAGEPATH) $(CLOCKSPRESET) \ + $(DDR_TOPOLOGY) 0 0 $(DOIMAGE_CFG) $(TIMNCFG) $(TIMNSIG) 0 +DOIMAGE_FLAGS := -r $(DOIMAGE_CFG) -v -D + +# GICV3 +$(eval $(call add_define,CONFIG_GICV3)) + +# CCI-400 +$(eval $(call add_define,USE_CCI)) + +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk + +MARVELL_GIC_SOURCES := ${GICV3_SOURCES} \ + plat/common/plat_gicv3.c + +PLAT_INCLUDES := -I$(PLAT_FAMILY_BASE)/$(PLAT) \ + -I$(PLAT_COMMON_BASE)/include \ + -I$(PLAT_INCLUDE_BASE)/common \ + -I$(MARVELL_DRV_BASE) \ + -I$/drivers/arm/gic/common/ + +PLAT_BL_COMMON_SOURCES := $(PLAT_COMMON_BASE)/aarch64/a3700_common.c \ + $(MARVELL_COMMON_BASE)/marvell_cci.c \ + $(MARVELL_DRV_BASE)/uart/a3700_console.S + +BL1_SOURCES += $(PLAT_COMMON_BASE)/aarch64/plat_helpers.S \ + lib/cpus/aarch64/cortex_a53.S + +BL31_PORTING_SOURCES := $(PLAT_FAMILY_BASE)/$(PLAT)/board/pm_src.c + +MARVELL_DRV := $(MARVELL_DRV_BASE)/comphy/phy-comphy-3700.c + +BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \ + $(PLAT_COMMON_BASE)/aarch64/plat_helpers.S \ + $(PLAT_COMMON_BASE)/plat_pm.c \ + $(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_ddr_info.c \ + $(MARVELL_COMMON_BASE)/marvell_gicv3.c \ + $(MARVELL_GIC_SOURCES) \ + drivers/arm/cci/cci.c \ + $(BL31_PORTING_SOURCES) \ + $(PLAT_COMMON_BASE)/a3700_sip_svc.c \ + $(MARVELL_DRV) + +mrvl_flash: ${BUILD_PLAT}/${FIP_NAME} ${DOIMAGETOOL} + $(shell truncate -s %128K ${BUILD_PLAT}/bl1.bin) + $(shell cat ${BUILD_PLAT}/bl1.bin ${BUILD_PLAT}/${FIP_NAME} > ${BUILD_PLAT}/${BOOT_IMAGE}) + $(shell truncate -s %4 ${BUILD_PLAT}/${BOOT_IMAGE}) + $(shell truncate -s %4 $(WTMI_IMG)) + @echo + @echo "Building uart images" + $(TIMBUILD) $(TIMBLDUARTARGS) + @sed -i 's|WTMI_IMG|$(WTMI_MULTI_IMG)|1' $(DOIMAGE_CFG) + @sed -i 's|BOOT_IMAGE|$(BUILD_PLAT)/$(BOOT_IMAGE)|1' $(DOIMAGE_CFG) +ifeq ($(MARVELL_SECURE_BOOT),1) + @sed -i 's|WTMI_IMG|$(WTMI_MULTI_IMG)|1' $(TIMNCFG) + @sed -i 's|BOOT_IMAGE|$(BUILD_PLAT)/$(BOOT_IMAGE)|1' $(TIMNCFG) +endif + $(DOIMAGETOOL) $(DOIMAGE_FLAGS) + @if [ -e "$(TIMNCFG)" ]; then $(DOIMAGETOOL) -r $(TIMNCFG); fi + @rm -rf $(BUILD_PLAT)/$(BUILD_UART)* + @mkdir $(BUILD_PLAT)/$(BUILD_UART) + @mv -t $(BUILD_PLAT)/$(BUILD_UART) $(TIM_IMAGE) $(DOIMAGE_CFG) $(TIMN_IMAGE) $(TIMNCFG) + @find . -name "*_h.*" |xargs cp -ut $(BUILD_PLAT)/$(BUILD_UART) + @mv $(subst .bin,_h.bin,$(WTMI_MULTI_IMG)) $(BUILD_PLAT)/$(BUILD_UART)/wtmi_h.bin + @tar czf $(BUILD_PLAT)/$(BUILD_UART).tgz -C $(BUILD_PLAT) ./$(BUILD_UART) + @echo + @echo "Building flash image" + $(TIMBUILD) $(TIMBLDARGS) + sed -i 's|WTMI_IMG|$(WTMI_MULTI_IMG)|1' $(DOIMAGE_CFG) + sed -i 's|BOOT_IMAGE|$(BUILD_PLAT)/$(BOOT_IMAGE)|1' $(DOIMAGE_CFG) +ifeq ($(MARVELL_SECURE_BOOT),1) + @sed -i 's|WTMI_IMG|$(WTMI_MULTI_IMG)|1' $(TIMNCFG) + @sed -i 's|BOOT_IMAGE|$(BUILD_PLAT)/$(BOOT_IMAGE)|1' $(TIMNCFG) + @echo -e "\n\t=======================================================\n"; + @echo -e "\t Secure boot. Encrypting wtmi and boot-image \n"; + @echo -e "\t=======================================================\n"; + @truncate -s %16 $(WTMI_MULTI_IMG) + @openssl enc -aes-256-cbc -e -in $(WTMI_MULTI_IMG) \ + -out $(WTMI_ENC_IMG) \ + -K `cat $(IMAGESPATH)/aes-256.txt` -nosalt \ + -iv `cat $(IMAGESPATH)/iv.txt` -p + @truncate -s %16 $(BUILD_PLAT)/$(BOOT_IMAGE); + @openssl enc -aes-256-cbc -e -in $(BUILD_PLAT)/$(BOOT_IMAGE) \ + -out $(BUILD_PLAT)/$(BOOT_ENC_IMAGE) \ + -K `cat $(IMAGESPATH)/aes-256.txt` -nosalt \ + -iv `cat $(IMAGESPATH)/iv.txt` -p +endif + $(DOIMAGETOOL) $(DOIMAGE_FLAGS) + @if [ -e "$(TIMNCFG)" ]; then $(DOIMAGETOOL) -r $(TIMNCFG); fi + @if [ "$(MARVELL_SECURE_BOOT)" = "1" ]; then sed -i 's|$(WTMI_MULTI_IMG)|$(WTMI_ENC_IMG)|1;s|$(BOOT_IMAGE)|$(BOOT_ENC_IMAGE)|1;' $(TIMNCFG); fi + $(TIM2IMG) $(TIM2IMGARGS) -o $(BUILD_PLAT)/$(FLASH_IMAGE) + @mv -t $(BUILD_PLAT) $(TIM_IMAGE) $(DOIMAGE_CFG) $(TIMN_IMAGE) $(TIMNCFG) $(WTMI_IMG) $(WTMI_SYSINIT_IMG) $(WTMI_MULTI_IMG) + @if [ "$(MARVELL_SECURE_BOOT)" = "1" ]; then mv -t $(BUILD_PLAT) $(WTMI_ENC_IMG) OtpHash.txt; fi + @find . -name "*.txt" | grep -E "CSK[[:alnum:]]_KeyHash.txt|Tim_msg.txt|TIMHash.txt" | xargs rm -f diff --git a/plat/marvell/armada/a3700/common/a3700_ea.c b/plat/marvell/armada/a3700/common/a3700_ea.c new file mode 100644 index 000000000..dd46beb55 --- /dev/null +++ b/plat/marvell/armada/a3700/common/a3700_ea.c @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2019 Repk repk@triplefau.lt + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ +#include +#include +#include + +#define ADVK_SERROR_SYNDROME 0xbf000002 + +void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie, + void *handle, uint64_t flags) +{ + if (syndrome != ADVK_SERROR_SYNDROME) { + ERROR("Unhandled External Abort received on 0x%lx at EL3!\n", + read_mpidr_el1()); + ERROR(" exception reason=%u syndrome=0x%llx\n", ea_reason, + syndrome); + panic(); + } +} diff --git a/plat/marvell/armada/a3700/common/a3700_sip_svc.c b/plat/marvell/armada/a3700/common/a3700_sip_svc.c new file mode 100644 index 000000000..e8ac5fc08 --- /dev/null +++ b/plat/marvell/armada/a3700/common/a3700_sip_svc.c @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include +#include + +#include +#include + +#include "comphy/phy-comphy-3700.h" + +/* Comphy related FID's */ +#define MV_SIP_COMPHY_POWER_ON 0x82000001 +#define MV_SIP_COMPHY_POWER_OFF 0x82000002 +#define MV_SIP_COMPHY_PLL_LOCK 0x82000003 + +/* Miscellaneous FID's' */ +#define MV_SIP_DRAM_SIZE 0x82000010 + +/* This macro is used to identify COMPHY related calls from SMC function ID */ +#define is_comphy_fid(fid) \ + ((fid) >= MV_SIP_COMPHY_POWER_ON && (fid) <= MV_SIP_COMPHY_PLL_LOCK) + +uintptr_t mrvl_sip_smc_handler(uint32_t smc_fid, + u_register_t x1, + u_register_t x2, + u_register_t x3, + u_register_t x4, + void *cookie, + void *handle, + u_register_t flags) +{ + u_register_t ret; + + VERBOSE("%s: got SMC (0x%x) x1 0x%lx, x2 0x%lx\n", + __func__, smc_fid, x1, x2); + if (is_comphy_fid(smc_fid)) { + if (x1 >= MAX_LANE_NR) { + ERROR("%s: Wrong smc (0x%x) lane nr: %lx\n", + __func__, smc_fid, x2); + SMC_RET1(handle, SMC_UNK); + } + } + + switch (smc_fid) { + /* Comphy related FID's */ + case MV_SIP_COMPHY_POWER_ON: + /* x1: comphy_index, x2: comphy_mode */ + ret = mvebu_3700_comphy_power_on(x1, x2); + SMC_RET1(handle, ret); + case MV_SIP_COMPHY_POWER_OFF: + /* x1: comphy_index, x2: comphy_mode */ + ret = mvebu_3700_comphy_power_off(x1, x2); + SMC_RET1(handle, ret); + case MV_SIP_COMPHY_PLL_LOCK: + /* x1: comphy_index, x2: comphy_mode */ + ret = mvebu_3700_comphy_is_pll_locked(x1, x2); + SMC_RET1(handle, ret); + /* Miscellaneous FID's' */ + case MV_SIP_DRAM_SIZE: + /* x1: ap_base_addr */ + ret = mvebu_get_dram_size(MVEBU_REGS_BASE); + SMC_RET1(handle, ret); + + default: + ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid); + SMC_RET1(handle, SMC_UNK); + } +} + +/* Define a runtime service descriptor for fast SMC calls */ +DECLARE_RT_SVC( + marvell_sip_svc, + OEN_SIP_START, + OEN_SIP_END, + SMC_TYPE_FAST, + NULL, + mrvl_sip_smc_handler +); diff --git a/plat/marvell/armada/a3700/common/aarch64/a3700_common.c b/plat/marvell/armada/a3700/common/aarch64/a3700_common.c new file mode 100644 index 000000000..63512853c --- /dev/null +++ b/plat/marvell/armada/a3700/common/aarch64/a3700_common.c @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ +#include + +/* MMU entry for internal (register) space access */ +#define MAP_DEVICE0 MAP_REGION_FLAT(DEVICE0_BASE, \ + DEVICE0_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +/* + * Table of regions for various BL stages to map using the MMU. + */ +#if IMAGE_BL1 +const mmap_region_t plat_marvell_mmap[] = { + MARVELL_MAP_SHARED_RAM, + MAP_DEVICE0, + {0} +}; +#endif +#if IMAGE_BL2 +const mmap_region_t plat_marvell_mmap[] = { + MARVELL_MAP_SHARED_RAM, + MAP_DEVICE0, + MARVELL_MAP_DRAM, + {0} +}; +#endif +#if IMAGE_BL2U +const mmap_region_t plat_marvell_mmap[] = { + MAP_DEVICE0, + {0} +}; +#endif +#if IMAGE_BL31 +const mmap_region_t plat_marvell_mmap[] = { + MARVELL_MAP_SHARED_RAM, + MAP_DEVICE0, + MARVELL_MAP_DRAM, + {0} +}; +#endif +#if IMAGE_BL32 +const mmap_region_t plat_marvell_mmap[] = { + MAP_DEVICE0, + {0} +}; +#endif + +MARVELL_CASSERT_MMAP; diff --git a/plat/marvell/armada/a3700/common/aarch64/plat_helpers.S b/plat/marvell/armada/a3700/common/aarch64/plat_helpers.S new file mode 100644 index 000000000..90d76f08e --- /dev/null +++ b/plat/marvell/armada/a3700/common/aarch64/plat_helpers.S @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include + + .globl plat_secondary_cold_boot_setup + .globl plat_get_my_entrypoint + .globl plat_is_my_cpu_primary + + /* ----------------------------------------------------- + * void plat_secondary_cold_boot_setup (void); + * + * This function performs any platform specific actions + * needed for a secondary cpu after a cold reset. Right + * now this is a stub function. + * ----------------------------------------------------- + */ +func plat_secondary_cold_boot_setup + mov x0, #0 + ret +endfunc plat_secondary_cold_boot_setup + + /* --------------------------------------------------------------------- + * unsigned long plat_get_my_entrypoint (void); + * + * Main job of this routine is to distinguish between cold and warm boot + * For a cold boot, return 0. + * For a warm boot, read the mailbox and return the address it contains. + * A magic number is placed before entrypoint to avoid mistake caused by + * uninitialized mailbox data area. + * --------------------------------------------------------------------- + */ +func plat_get_my_entrypoint + /* Read first word and compare it with magic num */ + mov_imm x0, PLAT_MARVELL_MAILBOX_BASE + ldr x1, [x0] + mov_imm x2, PLAT_MARVELL_MAILBOX_MAGIC_NUM + cmp x1, x2 + /* If compare failed, return 0, i.e. cold boot */ + beq entrypoint + mov x0, #0 + ret +entrypoint: + /* Second word contains the jump address */ + add x0, x0, #8 + ldr x0, [x0] + ret +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 + and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK) + cmp x0, #MVEBU_PRIMARY_CPU + cset w0, eq + ret +endfunc plat_is_my_cpu_primary diff --git a/plat/marvell/armada/a3700/common/dram_win.c b/plat/marvell/armada/a3700/common/dram_win.c new file mode 100644 index 000000000..694f6d480 --- /dev/null +++ b/plat/marvell/armada/a3700/common/dram_win.c @@ -0,0 +1,278 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include + +#include +#include +#include +#include + +/* Armada 3700 has 5 configurable windows */ +#define MV_CPU_WIN_NUM 5 + +#define CPU_WIN_DISABLED 0 +#define CPU_WIN_ENABLED 1 + +/* + * There are 2 different cpu decode window configuration cases: + * - DRAM size is not over 2GB; + * - DRAM size is 4GB. + */ +enum cpu_win_config_num { + CPU_WIN_CONFIG_DRAM_NOT_OVER_2GB = 0, + CPU_WIN_CONFIG_DRAM_4GB, + CPU_WIN_CONFIG_MAX +}; + +enum cpu_win_target { + CPU_WIN_TARGET_DRAM = 0, + CPU_WIN_TARGET_INTERNAL_REG, + CPU_WIN_TARGET_PCIE, + CPU_WIN_TARGET_PCIE_OVER_MCI, + CPU_WIN_TARGET_BOOT_ROM, + CPU_WIN_TARGET_MCI_EXTERNAL, + CPU_WIN_TARGET_RWTM_RAM = 7, + CPU_WIN_TARGET_CCI400_REG +}; + +struct cpu_win_configuration { + uint32_t enabled; + enum cpu_win_target target; + uint64_t base_addr; + uint64_t size; + uint64_t remap_addr; +}; + +struct cpu_win_configuration mv_cpu_wins[CPU_WIN_CONFIG_MAX][MV_CPU_WIN_NUM] = { + /* + * When total dram size is not over 2GB: + * DDR window 0 is configured in tim header, its size may be not 512MB, + * but the actual dram size, no need to configure it again; + * other cpu windows are kept as default. + */ + { + /* enabled + * target + * base + * size + * remap + */ + {CPU_WIN_ENABLED, + CPU_WIN_TARGET_DRAM, + 0x0, + 0x08000000, + 0x0}, + {CPU_WIN_ENABLED, + CPU_WIN_TARGET_MCI_EXTERNAL, + 0xe0000000, + 0x08000000, + 0xe0000000}, + {CPU_WIN_ENABLED, + CPU_WIN_TARGET_PCIE, + 0xe8000000, + 0x08000000, + 0xe8000000}, + {CPU_WIN_ENABLED, + CPU_WIN_TARGET_RWTM_RAM, + 0xf0000000, + 0x00020000, + 0x1fff0000}, + {CPU_WIN_ENABLED, + CPU_WIN_TARGET_PCIE_OVER_MCI, + 0x80000000, + 0x10000000, + 0x80000000}, + }, + + /* + * If total dram size is more than 2GB, now there is only one case - 4GB + * dram; we will use below cpu windows configurations: + * - Internal Regs, CCI-400, Boot Rom and PCIe windows are kept as + * default; + * - Use 4 CPU decode windows for DRAM, which cover 3.375GB DRAM; + * DDR window 0 is configured in tim header with 2GB size, no need to + * configure it again here; + * + * 0xFFFFFFFF ---> |-----------------------| + * | Boot ROM | 64KB + * 0xFFF00000 ---> +-----------------------+ + * : : + * 0xF0000000 ---> |-----------------------| + * | PCIE | 128 MB + * 0xE8000000 ---> |-----------------------| + * | DDR window 3 | 128 MB + * 0xE0000000 ---> +-----------------------+ + * : : + * 0xD8010000 ---> |-----------------------| + * | CCI Regs | 64 KB + * 0xD8000000 ---> +-----------------------+ + * : : + * : : + * 0xD2000000 ---> +-----------------------+ + * | Internal Regs | 32MB + * 0xD0000000 ---> |-----------------------| + * | DDR window 2 | 256 MB + * 0xC0000000 ---> |-----------------------| + * | | + * | DDR window 1 | 1 GB + * | | + * 0x80000000 ---> |-----------------------| + * | | + * | | + * | DDR window 0 | 2 GB + * | | + * | | + * 0x00000000 ---> +-----------------------+ + */ + { + /* win_id + * target + * base + * size + * remap + */ + {CPU_WIN_ENABLED, + CPU_WIN_TARGET_DRAM, + 0x0, + 0x80000000, + 0x0}, + {CPU_WIN_ENABLED, + CPU_WIN_TARGET_DRAM, + 0x80000000, + 0x40000000, + 0x80000000}, + {CPU_WIN_ENABLED, + CPU_WIN_TARGET_DRAM, + 0xc0000000, + 0x10000000, + 0xc0000000}, + {CPU_WIN_ENABLED, + CPU_WIN_TARGET_DRAM, + 0xe0000000, + 0x08000000, + 0xe0000000}, + {CPU_WIN_ENABLED, + CPU_WIN_TARGET_PCIE, + 0xe8000000, + 0x08000000, + 0xe8000000}, + }, +}; + +/* + * dram_win_map_build + * + * This function builds cpu dram windows mapping + * which includes base address and window size by + * reading cpu dram decode windows registers. + * + * @input: N/A + * + * @output: + * - win_map: cpu dram windows mapping + * + * @return: N/A + */ +void dram_win_map_build(struct dram_win_map *win_map) +{ + int32_t win_id; + struct dram_win *win; + uint32_t base_reg, ctrl_reg, size_reg, enabled, target; + + memset(win_map, 0, sizeof(struct dram_win_map)); + for (win_id = 0; win_id < DRAM_WIN_MAP_NUM_MAX; win_id++) { + ctrl_reg = mmio_read_32(CPU_DEC_WIN_CTRL_REG(win_id)); + target = (ctrl_reg & CPU_DEC_CR_WIN_TARGET_MASK) >> + CPU_DEC_CR_WIN_TARGET_OFFS; + enabled = ctrl_reg & CPU_DEC_CR_WIN_ENABLE; + /* Ignore invalid and non-dram windows*/ + if ((enabled == 0) || (target != DRAM_CPU_DEC_TARGET_NUM)) + continue; + + win = win_map->dram_windows + win_map->dram_win_num; + base_reg = mmio_read_32(CPU_DEC_WIN_BASE_REG(win_id)); + size_reg = mmio_read_32(CPU_DEC_WIN_SIZE_REG(win_id)); + /* Base reg [15:0] corresponds to transaction address [39:16] */ + win->base_addr = (base_reg & CPU_DEC_BR_BASE_MASK) >> + CPU_DEC_BR_BASE_OFFS; + win->base_addr *= CPU_DEC_CR_WIN_SIZE_ALIGNMENT; + /* + * Size reg [15:0] is programmed from LSB to MSB as a sequence + * of 1s followed by a sequence of 0s and the number of 1s + * specifies the size of the window in 64 KB granularity, + * for example, a value of 00FFh specifies 256 x 64 KB = 16 MB + */ + win->win_size = (size_reg & CPU_DEC_CR_WIN_SIZE_MASK) >> + CPU_DEC_CR_WIN_SIZE_OFFS; + win->win_size = (win->win_size + 1) * + CPU_DEC_CR_WIN_SIZE_ALIGNMENT; + + win_map->dram_win_num++; + } +} + +static void cpu_win_set(uint32_t win_id, struct cpu_win_configuration *win_cfg) +{ + uint32_t base_reg, ctrl_reg, size_reg, remap_reg; + + /* Disable window */ + ctrl_reg = mmio_read_32(CPU_DEC_WIN_CTRL_REG(win_id)); + ctrl_reg &= ~CPU_DEC_CR_WIN_ENABLE; + mmio_write_32(CPU_DEC_WIN_CTRL_REG(win_id), ctrl_reg); + + /* For an disabled window, only disable it. */ + if (!win_cfg->enabled) + return; + + /* Set Base Register */ + base_reg = (uint32_t)(win_cfg->base_addr / + CPU_DEC_CR_WIN_SIZE_ALIGNMENT); + base_reg <<= CPU_DEC_BR_BASE_OFFS; + base_reg &= CPU_DEC_BR_BASE_MASK; + mmio_write_32(CPU_DEC_WIN_BASE_REG(win_id), base_reg); + + /* Set Remap Register with the same value + * as the field in Base Register + */ + remap_reg = (uint32_t)(win_cfg->remap_addr / + CPU_DEC_CR_WIN_SIZE_ALIGNMENT); + remap_reg <<= CPU_DEC_RLR_REMAP_LOW_OFFS; + remap_reg &= CPU_DEC_RLR_REMAP_LOW_MASK; + mmio_write_32(CPU_DEC_REMAP_LOW_REG(win_id), remap_reg); + + /* Set Size Register */ + size_reg = (win_cfg->size / CPU_DEC_CR_WIN_SIZE_ALIGNMENT) - 1; + size_reg <<= CPU_DEC_CR_WIN_SIZE_OFFS; + size_reg &= CPU_DEC_CR_WIN_SIZE_MASK; + mmio_write_32(CPU_DEC_WIN_SIZE_REG(win_id), size_reg); + + /* Set Control Register - set target id and enable window */ + ctrl_reg &= ~CPU_DEC_CR_WIN_TARGET_MASK; + ctrl_reg |= (win_cfg->target << CPU_DEC_CR_WIN_TARGET_OFFS); + ctrl_reg |= CPU_DEC_CR_WIN_ENABLE; + mmio_write_32(CPU_DEC_WIN_CTRL_REG(win_id), ctrl_reg); +} + +void cpu_wins_init(void) +{ + uint32_t cfg_idx, win_id; + + if (mvebu_get_dram_size(MVEBU_REGS_BASE) <= _2GB_) + cfg_idx = CPU_WIN_CONFIG_DRAM_NOT_OVER_2GB; + else + cfg_idx = CPU_WIN_CONFIG_DRAM_4GB; + + /* Window 0 is configured always for DRAM in tim header + * already, no need to configure it again here + */ + for (win_id = 1; win_id < MV_CPU_WIN_NUM; win_id++) + cpu_win_set(win_id, &mv_cpu_wins[cfg_idx][win_id]); +} + diff --git a/plat/marvell/armada/a3700/common/include/a3700_plat_def.h b/plat/marvell/armada/a3700/common/include/a3700_plat_def.h new file mode 100644 index 000000000..c7f40adc3 --- /dev/null +++ b/plat/marvell/armada/a3700/common/include/a3700_plat_def.h @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef A3700_PLAT_DEF_H +#define A3700_PLAT_DEF_H + +#include + + +#define MVEBU_MAX_CPUS_PER_CLUSTER 2 + +#define MVEBU_PRIMARY_CPU 0x0 + +/* + * The counter on A3700 is always fed from reference 25M clock (XTAL). + * However minimal CPU counter prescaler is 2, so the counter + * frequency will be divided by 2, the number is 12.5M + */ +#define COUNTER_FREQUENCY 12500000 + +#define MVEBU_REGS_BASE 0xD0000000 + +/***************************************************************************** + * MVEBU memory map related constants + ***************************************************************************** + */ +/* Aggregate of all devices in the first GB */ +#define DEVICE0_BASE MVEBU_REGS_BASE +#define DEVICE0_SIZE 0x10000000 + +/***************************************************************************** + * GIC-500 & interrupt handling related constants + ***************************************************************************** + */ +/* Base MVEBU compatible GIC memory map */ +#define MVEBU_GICD_BASE 0x1D00000 +#define MVEBU_GICR_BASE 0x1D40000 +#define MVEBU_GICC_BASE 0x1D80000 + +/* CCI-400 */ +#define MVEBU_CCI_BASE 0x8000000 + +/***************************************************************************** + * North and south bridge register base + ***************************************************************************** + */ +#define MVEBU_NB_REGS_BASE (MVEBU_REGS_BASE + 0x13000) +#define MVEBU_SB_REGS_BASE (MVEBU_REGS_BASE + 0x18000) + +/***************************************************************************** + * GPIO registers related constants + ***************************************************************************** + */ +/* North and south bridge GPIO register base address */ +#define MVEBU_NB_GPIO_REG_BASE (MVEBU_NB_REGS_BASE + 0x800) +#define MVEBU_NB_GPIO_IRQ_REG_BASE (MVEBU_NB_REGS_BASE + 0xC00) +#define MVEBU_SB_GPIO_REG_BASE (MVEBU_SB_REGS_BASE + 0x800) +#define MVEBU_SB_GPIO_IRQ_REG_BASE (MVEBU_SB_REGS_BASE + 0xC00) +#define MVEBU_NB_SB_IRQ_REG_BASE (MVEBU_REGS_BASE + 0x8A00) + +/* North Bridge GPIO selection register */ +#define MVEBU_NB_GPIO_SEL_REG (MVEBU_NB_GPIO_REG_BASE + 0x30) +#define MVEBU_NB_GPIO_OUTPUT_EN_HIGH_REG (MVEBU_NB_GPIO_REG_BASE + 0x04) +/* I2C1 GPIO Enable bit offset */ +#define MVEBU_GPIO_TW1_GPIO_EN_OFF (10) +/* SPI pins mode bit offset */ +#define MVEBU_GPIO_NB_SPI_PIN_MODE_OFF (28) + +/***************************************************************************** + * DRAM registers related constants + ***************************************************************************** + */ +#define MVEBU_DRAM_REG_BASE (MVEBU_REGS_BASE) + +/***************************************************************************** + * SB wake-up registers related constants + ***************************************************************************** + */ +#define MVEBU_SB_WAKEUP_REG_BASE (MVEBU_REGS_BASE + 0x19000) + +/***************************************************************************** + * PMSU registers related constants + ***************************************************************************** + */ +#define MVEBU_PMSU_REG_BASE (MVEBU_REGS_BASE + 0x14000) + +/***************************************************************************** + * North Bridge Step-Down Registers + ***************************************************************************** + */ +#define MVEBU_NB_STEP_DOWN_REG_BASE (MVEBU_REGS_BASE + 0x12800) + +/***************************************************************************** + * DRAM CS memory map register base + ***************************************************************************** + */ +#define MVEBU_CS_MMAP_REG_BASE (MVEBU_REGS_BASE + 0x200) + +/***************************************************************************** + * CPU decoder window registers related constants + ***************************************************************************** + */ +#define MVEBU_CPU_DEC_WIN_REG_BASE (MVEBU_REGS_BASE + 0xCF00) + +/***************************************************************************** + * AVS registers related constants + ***************************************************************************** + */ +#define MVEBU_AVS_REG_BASE (MVEBU_REGS_BASE + 0x11500) + + +/***************************************************************************** + * AVS registers related constants + ***************************************************************************** + */ +#define MVEBU_COMPHY_REG_BASE (MVEBU_REGS_BASE + 0x18300) + +#endif /* A3700_PLAT_DEF_H */ diff --git a/plat/marvell/armada/a3700/common/include/a3700_pm.h b/plat/marvell/armada/a3700/common/include/a3700_pm.h new file mode 100644 index 000000000..cc6cf436a --- /dev/null +++ b/plat/marvell/armada/a3700/common/include/a3700_pm.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2016 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef A3700_PM_H +#define A3700_PM_H + +#include + +/* supported wake up sources */ +enum pm_wake_up_src_type { + WAKE_UP_SRC_GPIO, + /* FOLLOWING SRC NOT SUPPORTED YET */ + WAKE_UP_SRC_TIMER, + WAKE_UP_SRC_UART0, + WAKE_UP_SRC_UART1, + WAKE_UP_SRC_MAX, +}; + +struct pm_gpio_data { + /* + * bank 0: North bridge GPIO + * bank 1: South bridge GPIO + */ + uint32_t bank_num; + uint32_t gpio_num; +}; + +union pm_wake_up_src_data { + struct pm_gpio_data gpio_data; + /* delay in seconds */ + uint32_t timer_delay; +}; + +struct pm_wake_up_src { + enum pm_wake_up_src_type wake_up_src_type; + + union pm_wake_up_src_data wake_up_data; +}; + +struct pm_wake_up_src_config { + uint32_t wake_up_src_num; + struct pm_wake_up_src wake_up_src[WAKE_UP_SRC_MAX]; +}; + +struct pm_wake_up_src_config *mv_wake_up_src_config_get(void); + +#endif /* A3700_PM_H */ diff --git a/plat/marvell/armada/a3700/common/include/ddr_info.h b/plat/marvell/armada/a3700/common/include/ddr_info.h new file mode 100644 index 000000000..254f78c1b --- /dev/null +++ b/plat/marvell/armada/a3700/common/include/ddr_info.h @@ -0,0 +1,14 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef DDR_INFO_H +#define DDR_INFO_H + +#define DRAM_MAX_IFACE 1 +#define DRAM_CH0_MMAP_LOW_OFFSET 0x200 + +#endif /* DDR_INFO_H */ diff --git a/plat/marvell/armada/a3700/common/include/dram_win.h b/plat/marvell/armada/a3700/common/include/dram_win.h new file mode 100644 index 000000000..26a013784 --- /dev/null +++ b/plat/marvell/armada/a3700/common/include/dram_win.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef DRAM_WIN_H +#define DRAM_WIN_H + +#include + +#include + +void dram_win_map_build(struct dram_win_map *win_map); +void cpu_wins_init(void); + +#endif /* DRAM_WIN_H */ diff --git a/plat/marvell/armada/a3700/common/include/io_addr_dec.h b/plat/marvell/armada/a3700/common/include/io_addr_dec.h new file mode 100644 index 000000000..42ef30bc2 --- /dev/null +++ b/plat/marvell/armada/a3700/common/include/io_addr_dec.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef IO_ADDR_DEC_H +#define IO_ADDR_DEC_H + +#include + +/* There are 5 configurable cpu decoder windows. */ +#define DRAM_WIN_MAP_NUM_MAX 5 +/* Target number for dram in cpu decoder windows. */ +#define DRAM_CPU_DEC_TARGET_NUM 0 + +/* + * Not all configurable decode windows could be used for dram, some units have + * to reserve one decode window for other unit they have to communicate with; + * for example, DMA engineer has 3 configurable windows, but only two could be + * for dram while the last one has to be for pcie, so for DMA, its max_dram_win + * is 2. + */ +struct dec_win_config { + uint32_t dec_reg_base; /* IO address decoder register base address */ + uint32_t win_attr; /* IO address decoder windows attributes */ + /* How many configurable dram decoder windows that this unit has; */ + uint32_t max_dram_win; + /* The decoder windows number including remapping that this unit has */ + uint32_t max_remap; + /* The offset between continuous decode windows + * within the same unit, typically 0x10 + */ + uint32_t win_offset; +}; + +struct dram_win { + uintptr_t base_addr; + uintptr_t win_size; +}; + +struct dram_win_map { + int dram_win_num; + struct dram_win dram_windows[DRAM_WIN_MAP_NUM_MAX]; +}; + +/* + * init_io_addr_dec + * + * This function initializes io address decoder windows by + * cpu dram window mapping information + * + * @input: N/A + * - dram_wins_map: cpu dram windows mapping + * - io_dec_config: io address decoder windows configuration + * - io_unit_num: io address decoder unit number + * @output: N/A + * + * @return: 0 on success and others on failure + */ +int init_io_addr_dec(struct dram_win_map *dram_wins_map, + struct dec_win_config *io_dec_config, + uint32_t io_unit_num); + +#endif /* IO_ADDR_DEC_H */ diff --git a/plat/marvell/armada/a3700/common/include/plat_macros.S b/plat/marvell/armada/a3700/common/include/plat_macros.S new file mode 100644 index 000000000..f689b4f39 --- /dev/null +++ b/plat/marvell/armada/a3700/common/include/plat_macros.S @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef PLAT_MACROS_S +#define PLAT_MACROS_S + +#include + +/* --------------------------------------------- + * The below macro prints out relevant GIC and + * CCI registers registers whenever an unhandled + * exception is taken in BL31. + * --------------------------------------------- + */ +.macro plat_crash_print_regs + mov_imm x17, MVEBU_GICC_BASE + mov_imm x16, MVEBU_GICD_BASE + marvell_print_gic_regs + print_cci_regs +.endm + +#endif /* PLAT_MACROS_S */ diff --git a/plat/marvell/armada/a3700/common/include/platform_def.h b/plat/marvell/armada/a3700/common/include/platform_def.h new file mode 100644 index 000000000..e6660d407 --- /dev/null +++ b/plat/marvell/armada/a3700/common/include/platform_def.h @@ -0,0 +1,232 @@ +/* + * Copyright (C) 2016-2019 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +#ifndef __ASSEMBLER__ +#include +#endif /* __ASSEMBLER__ */ + +#include +#include + +/* + * Most platform porting definitions provided by included headers + */ + +/* + * DRAM Memory layout: + * +-----------------------+ + * : : + * : Linux : + * 0x04X00000-->+-----------------------+ + * | BL3-3(u-boot) |>>}>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + * |-----------------------| } | + * | BL3-[0,1, 2] | }---------------------------------> | + * |-----------------------| } || | + * | BL2 | }->FIP (loaded by || | + * |-----------------------| } BootROM to DRAM) || | + * | FIP_TOC | } || | + * 0x04120000-->|-----------------------| || | + * | BL1 (RO) | || | + * 0x04100000-->+-----------------------+ || | + * : : || | + * : Trusted SRAM section : \/ | + * 0x04040000-->+-----------------------+ Replaced by BL2 +----------------+ | + * | BL1 (RW) | <<<<<<<<<<<<<<<< | BL3-1 NOBITS | | + * 0x04037000-->|-----------------------| <<<<<<<<<<<<<<<< |----------------| | + * | | <<<<<<<<<<<<<<<< | BL3-1 PROGBITS | | + * 0x04023000-->|-----------------------| +----------------+ | + * | BL2 | | + * |-----------------------| | + * | | | + * 0x04001000-->|-----------------------| | + * | Shared | | + * 0x04000000-->+-----------------------+ | + * : : | + * : Linux : | + * : : | + * |-----------------------| | + * | | U-Boot(BL3-3) Loaded by BL2 | + * | U-Boot | <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + * 0x00000000-->+-----------------------+ + * + * Trusted SRAM section 0x4000000..0x4200000: + * ---------------------------------------- + * SRAM_BASE = 0x4001000 + * BL2_BASE = 0x4006000 + * BL2_LIMIT = BL31_BASE + * BL31_BASE = 0x4023000 = (64MB + 256KB - 0x1D000) + * BL31_PROGBITS_LIMIT = BL1_RW_BASE + * BL1_RW_BASE = 0x4037000 = (64MB + 256KB - 0x9000) + * BL1_RW_LIMIT = BL31_LIMIT = 0x4040000 + * + * + * PLAT_MARVELL_FIP_BASE = 0x4120000 + */ + +#define PLAT_MARVELL_ATF_BASE 0x4000000 +#define PLAT_MARVELL_ATF_LOAD_ADDR \ + (PLAT_MARVELL_ATF_BASE + 0x100000) + +#define PLAT_MARVELL_FIP_BASE \ + (PLAT_MARVELL_ATF_LOAD_ADDR + 0x20000) +#define PLAT_MARVELL_FIP_MAX_SIZE 0x4000000 + +#define PLAT_MARVELL_CLUSTER_CORE_COUNT U(2) +/* DRAM[2MB..66MB] is used as Trusted ROM */ +#define PLAT_MARVELL_TRUSTED_ROM_BASE PLAT_MARVELL_ATF_LOAD_ADDR +/* 64 MB TODO: reduce this to minimum needed according to fip image size*/ +#define PLAT_MARVELL_TRUSTED_ROM_SIZE 0x04000000 +/* Reserve 16M for SCP (Secure PayLoad) Trusted DRAM */ +#define PLAT_MARVELL_TRUSTED_DRAM_BASE 0x04400000 +#define PLAT_MARVELL_TRUSTED_DRAM_SIZE 0x01000000 /* 16 MB */ + +/* + * PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size + * plus a little space for growth. + */ +#define PLAT_MARVELL_MAX_BL1_RW_SIZE 0xA000 + +/* + * PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a + * little space for growth. + */ +#define PLAT_MARVELL_MAX_BL2_SIZE 0xF000 + +/* + * PLAT_ARM_MAX_BL31_SIZE is calculated using the current BL31 debug size plus a + * little space for growth. + */ +#define PLAT_MARVEL_MAX_BL31_SIZE 0x5D000 + +#define PLAT_MARVELL_CPU_ENTRY_ADDR BL1_RO_BASE + +/* GIC related definitions */ +#define PLAT_MARVELL_GICD_BASE (MVEBU_REGS_BASE + MVEBU_GICD_BASE) +#define PLAT_MARVELL_GICR_BASE (MVEBU_REGS_BASE + MVEBU_GICR_BASE) +#define PLAT_MARVELL_GICC_BASE (MVEBU_REGS_BASE + MVEBU_GICC_BASE) + +#define PLAT_MARVELL_G0_IRQ_PROPS(grp) \ + INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL) + +#define PLAT_MARVELL_G1S_IRQ_PROPS(grp) \ + INTR_PROP_DESC(MARVELL_IRQ_SEC_PHY_TIMER, \ + GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL) + + +#define PLAT_MARVELL_SHARED_RAM_CACHED 1 + +/* CCI related constants */ +#define PLAT_MARVELL_CCI_BASE (MVEBU_REGS_BASE + MVEBU_CCI_BASE) +#define PLAT_MARVELL_CCI_CLUSTER0_SL_IFACE_IX 3 +#define PLAT_MARVELL_CCI_CLUSTER1_SL_IFACE_IX 4 + +/* + * Load address of BL3-3 for this platform port + */ +#define PLAT_MARVELL_NS_IMAGE_OFFSET 0x0 + +/* System Reference Clock*/ +#define PLAT_REF_CLK_IN_HZ COUNTER_FREQUENCY + +/* + * PL011 related constants + */ +#define PLAT_MARVELL_BOOT_UART_BASE (MVEBU_REGS_BASE + 0x12000) +#define PLAT_MARVELL_BOOT_UART_CLK_IN_HZ 25804800 + +#define PLAT_MARVELL_CRASH_UART_BASE PLAT_MARVELL_BOOT_UART_BASE +#define PLAT_MARVELL_CRASH_UART_CLK_IN_HZ PLAT_MARVELL_BOOT_UART_CLK_IN_HZ + +#define PLAT_MARVELL_BL31_RUN_UART_BASE PLAT_MARVELL_BOOT_UART_BASE +#define PLAT_MARVELL_BL31_RUN_UART_CLK_IN_HZ PLAT_MARVELL_BOOT_UART_CLK_IN_HZ + +/* Required platform porting definitions */ +#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL1 + +/* System timer related constants */ +#define PLAT_MARVELL_NSTIMER_FRAME_ID 1 + +/* Mailbox base address */ +#define PLAT_MARVELL_MAILBOX_BASE \ + (MARVELL_TRUSTED_SRAM_BASE + 0x400) +#define PLAT_MARVELL_MAILBOX_SIZE 0x100 +#define PLAT_MARVELL_MAILBOX_MAGIC_NUM 0x6D72766C /* mrvl */ + +/* DRAM CS memory map registers related constants */ +#define MVEBU_CS_MMAP_LOW(cs_num) \ + (MVEBU_CS_MMAP_REG_BASE + (cs_num) * 0x8) +#define MVEBU_CS_MMAP_ENABLE 0x1 +#define MVEBU_CS_MMAP_AREA_LEN_OFFS 16 +#define MVEBU_CS_MMAP_AREA_LEN_MASK \ + (0x1f << MVEBU_CS_MMAP_AREA_LEN_OFFS) +#define MVEBU_CS_MMAP_START_ADDR_LOW_OFFS 23 +#define MVEBU_CS_MMAP_START_ADDR_LOW_MASK \ + (0x1ff << MVEBU_CS_MMAP_START_ADDR_LOW_OFFS) + +#define MVEBU_CS_MMAP_HIGH(cs_num) \ + (MVEBU_CS_MMAP_REG_BASE + 0x4 + (cs_num) * 0x8) + +/* DRAM max CS number */ +#define MVEBU_MAX_CS_MMAP_NUM (2) + +/* CPU decoder window related constants */ +#define CPU_DEC_WIN_CTRL_REG(win_num) \ + (MVEBU_CPU_DEC_WIN_REG_BASE + (win_num) * 0x10) +#define CPU_DEC_CR_WIN_ENABLE 0x1 +#define CPU_DEC_CR_WIN_TARGET_OFFS 4 +#define CPU_DEC_CR_WIN_TARGET_MASK \ + (0xf << CPU_DEC_CR_WIN_TARGET_OFFS) + +#define CPU_DEC_WIN_SIZE_REG(win_num) \ + (MVEBU_CPU_DEC_WIN_REG_BASE + 0x4 + (win_num) * 0x10) +#define CPU_DEC_CR_WIN_SIZE_OFFS 0 +#define CPU_DEC_CR_WIN_SIZE_MASK \ + (0xffff << CPU_DEC_CR_WIN_SIZE_OFFS) +#define CPU_DEC_CR_WIN_SIZE_ALIGNMENT 0x10000 + +#define CPU_DEC_WIN_BASE_REG(win_num) \ + (MVEBU_CPU_DEC_WIN_REG_BASE + 0x8 + (win_num) * 0x10) +#define CPU_DEC_BR_BASE_OFFS 0 +#define CPU_DEC_BR_BASE_MASK \ + (0xffff << CPU_DEC_BR_BASE_OFFS) + +#define CPU_DEC_REMAP_LOW_REG(win_num) \ + (MVEBU_CPU_DEC_WIN_REG_BASE + 0xC + (win_num) * 0x10) +#define CPU_DEC_RLR_REMAP_LOW_OFFS 0 +#define CPU_DEC_RLR_REMAP_LOW_MASK \ + (0xffff << CPU_DEC_BR_BASE_OFFS) + +/* Securities */ +#define IRQ_SEC_OS_TICK_INT MARVELL_IRQ_SEC_PHY_TIMER + +#define TRUSTED_DRAM_BASE PLAT_MARVELL_TRUSTED_DRAM_BASE +#define TRUSTED_DRAM_SIZE PLAT_MARVELL_TRUSTED_DRAM_SIZE + +#ifdef BL32 +#define BL32_BASE TRUSTED_DRAM_BASE +#define BL32_LIMIT TRUSTED_DRAM_SIZE +#endif + +#endif /* PLATFORM_DEF_H */ diff --git a/plat/marvell/armada/a3700/common/io_addr_dec.c b/plat/marvell/armada/a3700/common/io_addr_dec.c new file mode 100644 index 000000000..b27633cf2 --- /dev/null +++ b/plat/marvell/armada/a3700/common/io_addr_dec.c @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2016 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include + +#include +#include + +#define MVEBU_DEC_WIN_CTRL_REG(base, win, off) (MVEBU_REGS_BASE + (base) + \ + (win) * (off)) +#define MVEBU_DEC_WIN_BASE_REG(base, win, off) (MVEBU_REGS_BASE + (base) + \ + (win) * (off) + 0x4) +#define MVEBU_DEC_WIN_REMAP_REG(base, win, off) (MVEBU_REGS_BASE + (base) + \ + (win) * (off) + 0x8) + +#define MVEBU_DEC_WIN_CTRL_SIZE_OFF (16) +#define MVEBU_DEC_WIN_ENABLE (0x1) +#define MVEBU_DEC_WIN_CTRL_ATTR_OFF (8) +#define MVEBU_DEC_WIN_CTRL_TARGET_OFF (4) +#define MVEBU_DEC_WIN_CTRL_EN_OFF (0) +#define MVEBU_DEC_WIN_BASE_OFF (16) + +#define MVEBU_WIN_BASE_SIZE_ALIGNMENT (0x10000) + +/* There are up to 14 IO unit which need address decode in Armada-3700 */ +#define IO_UNIT_NUM_MAX (14) + +#define MVEBU_MAX_ADDRSS_4GB (0x100000000ULL) + + +static void set_io_addr_dec_win(int win_id, uintptr_t base_addr, + uintptr_t win_size, + struct dec_win_config *dec_win) +{ + uint32_t ctrl = 0; + uint32_t base = 0; + + /* set size */ + ctrl = ((win_size / MVEBU_WIN_BASE_SIZE_ALIGNMENT) - 1) << + MVEBU_DEC_WIN_CTRL_SIZE_OFF; + /* set attr according to IO decode window */ + ctrl |= dec_win->win_attr << MVEBU_DEC_WIN_CTRL_ATTR_OFF; + /* set target */ + ctrl |= DRAM_CPU_DEC_TARGET_NUM << MVEBU_DEC_WIN_CTRL_TARGET_OFF; + /* set base */ + base = (base_addr / MVEBU_WIN_BASE_SIZE_ALIGNMENT) << + MVEBU_DEC_WIN_BASE_OFF; + + /* set base address*/ + mmio_write_32(MVEBU_DEC_WIN_BASE_REG(dec_win->dec_reg_base, + win_id, dec_win->win_offset), + base); + /* set remap window, some unit does not have remap window */ + if (win_id < dec_win->max_remap) + mmio_write_32(MVEBU_DEC_WIN_REMAP_REG(dec_win->dec_reg_base, + win_id, dec_win->win_offset), base); + /* set control register */ + mmio_write_32(MVEBU_DEC_WIN_CTRL_REG(dec_win->dec_reg_base, + win_id, dec_win->win_offset), ctrl); + /* enable the address decode window at last to make it effective */ + ctrl |= MVEBU_DEC_WIN_ENABLE << MVEBU_DEC_WIN_CTRL_EN_OFF; + mmio_write_32(MVEBU_DEC_WIN_CTRL_REG(dec_win->dec_reg_base, + win_id, dec_win->win_offset), ctrl); + + INFO("set_io_addr_dec %d result: ctrl(0x%x) base(0x%x)", + win_id, mmio_read_32(MVEBU_DEC_WIN_CTRL_REG(dec_win->dec_reg_base, + win_id, dec_win->win_offset)), + mmio_read_32(MVEBU_DEC_WIN_BASE_REG(dec_win->dec_reg_base, + win_id, dec_win->win_offset))); + if (win_id < dec_win->max_remap) + INFO(" remap(%x)\n", + mmio_read_32(MVEBU_DEC_WIN_REMAP_REG(dec_win->dec_reg_base, + win_id, dec_win->win_offset))); + else + INFO("\n"); +} + +/* Set io decode window */ +static int set_io_addr_dec(struct dram_win_map *win_map, + struct dec_win_config *dec_win) +{ + struct dram_win *win; + int id; + + /* disable all windows first */ + for (id = 0; id < dec_win->max_dram_win; id++) + mmio_write_32(MVEBU_DEC_WIN_CTRL_REG(dec_win->dec_reg_base, id, + dec_win->win_offset), 0); + + /* configure IO decode windows for DRAM, inheritate DRAM size, + * base and target from CPU-DRAM decode window and others + * from hard coded IO decode window settings array. + */ + if (win_map->dram_win_num > dec_win->max_dram_win) { + /* + * If cpu dram windows number exceeds the io decode windows + * max number, then fill the first io decode window + * with base(0) and size(4GB). + */ + set_io_addr_dec_win(0, 0, MVEBU_MAX_ADDRSS_4GB, dec_win); + + return 0; + } + + for (id = 0; id < win_map->dram_win_num; id++, win++) { + win = &win_map->dram_windows[id]; + set_io_addr_dec_win(id, win->base_addr, win->win_size, dec_win); + } + + return 0; +} + +/* + * init_io_addr_dec + * + * This function initializes io address decoder windows by + * cpu dram window mapping information + * + * @input: N/A + * - dram_wins_map: cpu dram windows mapping + * - io_dec_config: io address decoder windows configuration + * - io_unit_num: io address decoder unit number + * @output: N/A + * + * @return: 0 on success and others on failure + */ +int init_io_addr_dec(struct dram_win_map *dram_wins_map, + struct dec_win_config *io_dec_config, uint32_t io_unit_num) +{ + int32_t index; + struct dec_win_config *io_dec_win; + int32_t ret; + + INFO("Initializing IO address decode windows\n"); + + if (io_dec_config == NULL || io_unit_num == 0) { + ERROR("No IO address decoder windows configurations!\n"); + return -1; + } + + if (io_unit_num > IO_UNIT_NUM_MAX) { + ERROR("IO address decoder windows number %d is over max %d\n", + io_unit_num, IO_UNIT_NUM_MAX); + return -1; + } + + if (dram_wins_map == NULL) { + ERROR("No cpu dram decoder windows map!\n"); + return -1; + } + + for (index = 0; index < dram_wins_map->dram_win_num; index++) + INFO("DRAM mapping %d base(0x%lx) size(0x%lx)\n", + index, dram_wins_map->dram_windows[index].base_addr, + dram_wins_map->dram_windows[index].win_size); + + /* Set address decode window for each IO */ + for (index = 0; index < io_unit_num; index++) { + io_dec_win = io_dec_config + index; + ret = set_io_addr_dec(dram_wins_map, io_dec_win); + if (ret) { + ERROR("Failed to set IO address decode\n"); + return -1; + } + INFO("Set IO decode window successfully, base(0x%x)", + io_dec_win->dec_reg_base); + INFO(" win_attr(%x) max_dram_win(%d) max_remap(%d)", + io_dec_win->win_attr, io_dec_win->max_dram_win, + io_dec_win->max_remap); + INFO(" win_offset(%d)\n", io_dec_win->win_offset); + } + + return 0; +} diff --git a/plat/marvell/armada/a3700/common/marvell_plat_config.c b/plat/marvell/armada/a3700/common/marvell_plat_config.c new file mode 100644 index 000000000..3bf3d96bd --- /dev/null +++ b/plat/marvell/armada/a3700/common/marvell_plat_config.c @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include +#include + +struct dec_win_config io_dec_win_conf[] = { + /* dec_reg_base win_attr max_dram_win max_remap win_offset */ + {0xc000, 0x3d, 2, 0, 0x08}, /* USB */ + {0xc100, 0x3d, 3, 0, 0x10}, /* USB3 */ + {0xc200, 0x3d, 2, 0, 0x10}, /* DMA */ + {0xc300, 0x3d, 2, 0, 0x10}, /* NETA0 */ + {0xc400, 0x3d, 2, 0, 0x10}, /* NETA1 */ + {0xc500, 0x3d, 2, 0, 0x10}, /* PCIe */ + {0xc800, 0x3d, 3, 0, 0x10}, /* SATA */ + {0xca00, 0x3d, 3, 0, 0x08}, /* SD */ + {0xcb00, 0x3d, 3, 0, 0x10}, /* eMMC */ + {0xce00, 0x3d, 2, 0, 0x08}, /* EIP97 */ +}; + +int marvell_get_io_dec_win_conf(struct dec_win_config **win, uint32_t *size) +{ + *win = io_dec_win_conf; + *size = sizeof(io_dec_win_conf)/sizeof(struct dec_win_config); + + return 0; +} + diff --git a/plat/marvell/armada/a3700/common/plat_pm.c b/plat/marvell/armada/a3700/common/plat_pm.c new file mode 100644 index 000000000..f8ce6fe29 --- /dev/null +++ b/plat/marvell/armada/a3700/common/plat_pm.c @@ -0,0 +1,807 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#ifdef USE_CCI +#include +#endif +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Warm reset register */ +#define MVEBU_WARM_RESET_REG (MVEBU_NB_REGS_BASE + 0x840) +#define MVEBU_WARM_RESET_MAGIC 0x1D1E + +/* North Bridge GPIO1 SEL register */ +#define MVEBU_NB_GPIO1_SEL_REG (MVEBU_NB_REGS_BASE + 0x830) + #define MVEBU_NB_GPIO1_UART1_SEL BIT(19) + #define MVEBU_NB_GPIO1_GPIO_25_26_EN BIT(17) + #define MVEBU_NB_GPIO1_GPIO_19_EN BIT(14) + #define MVEBU_NB_GPIO1_GPIO_18_EN BIT(13) + +/* CPU 1 reset register */ +#define MVEBU_CPU_1_RESET_VECTOR (MVEBU_REGS_BASE + 0x14044) +#define MVEBU_CPU_1_RESET_REG (MVEBU_REGS_BASE + 0xD00C) +#define MVEBU_CPU_1_RESET_BIT 31 + +/* IRQ register */ +#define MVEBU_NB_IRQ_STATUS_1_REG (MVEBU_NB_SB_IRQ_REG_BASE) +#define MVEBU_NB_IRQ_STATUS_2_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ + 0x10) +#define MVEBU_NB_IRQ_MASK_2_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ + 0x18) +#define MVEBU_SB_IRQ_STATUS_1_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ + 0x40) +#define MVEBU_SB_IRQ_STATUS_2_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ + 0x50) +#define MVEBU_NB_GPIO_IRQ_MASK_1_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ + 0xC8) +#define MVEBU_NB_GPIO_IRQ_MASK_2_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ + 0xD8) +#define MVEBU_SB_GPIO_IRQ_MASK_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ + 0xE8) +#define MVEBU_NB_GPIO_IRQ_EN_LOW_REG (MVEBU_NB_GPIO_IRQ_REG_BASE) +#define MVEBU_NB_GPIO_IRQ_EN_HIGH_REG (MVEBU_NB_GPIO_IRQ_REG_BASE + \ + 0x04) +#define MVEBU_NB_GPIO_IRQ_STATUS_LOW_REG (MVEBU_NB_GPIO_IRQ_REG_BASE + \ + 0x10) +#define MVEBU_NB_GPIO_IRQ_STATUS_HIGH_REG (MVEBU_NB_GPIO_IRQ_REG_BASE + \ + 0x14) +#define MVEBU_NB_GPIO_IRQ_WK_LOW_REG (MVEBU_NB_GPIO_IRQ_REG_BASE + \ + 0x18) +#define MVEBU_NB_GPIO_IRQ_WK_HIGH_REG (MVEBU_NB_GPIO_IRQ_REG_BASE + \ + 0x1C) +#define MVEBU_SB_GPIO_IRQ_EN_REG (MVEBU_SB_GPIO_IRQ_REG_BASE) +#define MVEBU_SB_GPIO_IRQ_STATUS_REG (MVEBU_SB_GPIO_IRQ_REG_BASE + \ + 0x10) +#define MVEBU_SB_GPIO_IRQ_WK_REG (MVEBU_SB_GPIO_IRQ_REG_BASE + \ + 0x18) + +/* PMU registers */ +#define MVEBU_PM_NB_PWR_CTRL_REG (MVEBU_PMSU_REG_BASE) + #define MVEBU_PM_PWR_DN_CNT_SEL BIT(28) + #define MVEBU_PM_SB_PWR_DWN BIT(4) + #define MVEBU_PM_INTERFACE_IDLE BIT(0) +#define MVEBU_PM_NB_CPU_PWR_CTRL_REG (MVEBU_PMSU_REG_BASE + 0x4) + #define MVEBU_PM_L2_FLUSH_EN BIT(22) +#define MVEBU_PM_NB_PWR_OPTION_REG (MVEBU_PMSU_REG_BASE + 0x8) + #define MVEBU_PM_DDR_SR_EN BIT(29) + #define MVEBU_PM_DDR_CLK_DIS_EN BIT(28) + #define MVEBU_PM_WARM_RESET_EN BIT(27) + #define MVEBU_PM_DDRPHY_PWRDWN_EN BIT(23) + #define MVEBU_PM_DDRPHY_PAD_PWRDWN_EN BIT(22) + #define MVEBU_PM_OSC_OFF_EN BIT(21) + #define MVEBU_PM_TBG_OFF_EN BIT(20) + #define MVEBU_PM_CPU_VDDV_OFF_EN BIT(19) + #define MVEBU_PM_AVS_DISABLE_MODE BIT(14) + #define MVEBU_PM_AVS_VDD2_MODE BIT(13) + #define MVEBU_PM_AVS_HOLD_MODE BIT(12) + #define MVEBU_PM_L2_SRAM_LKG_PD_EN BIT(8) + #define MVEBU_PM_EIP_SRAM_LKG_PD_EN BIT(7) + #define MVEBU_PM_DDRMC_SRAM_LKG_PD_EN BIT(6) + #define MVEBU_PM_MCI_SRAM_LKG_PD_EN BIT(5) + #define MVEBU_PM_MMC_SRAM_LKG_PD_EN BIT(4) + #define MVEBU_PM_SATA_SRAM_LKG_PD_EN BIT(3) + #define MVEBU_PM_DMA_SRAM_LKG_PD_EN BIT(2) + #define MVEBU_PM_SEC_SRAM_LKG_PD_EN BIT(1) + #define MVEBU_PM_CPU_SRAM_LKG_PD_EN BIT(0) + #define MVEBU_PM_NB_SRAM_LKG_PD_EN (MVEBU_PM_L2_SRAM_LKG_PD_EN |\ + MVEBU_PM_EIP_SRAM_LKG_PD_EN | MVEBU_PM_DDRMC_SRAM_LKG_PD_EN |\ + MVEBU_PM_MCI_SRAM_LKG_PD_EN | MVEBU_PM_MMC_SRAM_LKG_PD_EN |\ + MVEBU_PM_SATA_SRAM_LKG_PD_EN | MVEBU_PM_DMA_SRAM_LKG_PD_EN |\ + MVEBU_PM_SEC_SRAM_LKG_PD_EN | MVEBU_PM_CPU_SRAM_LKG_PD_EN) +#define MVEBU_PM_NB_PWR_DEBUG_REG (MVEBU_PMSU_REG_BASE + 0xC) + #define MVEBU_PM_NB_FORCE_CLK_ON BIT(30) + #define MVEBU_PM_IGNORE_CM3_SLEEP BIT(21) + #define MVEBU_PM_IGNORE_CM3_DEEP BIT(20) +#define MVEBU_PM_NB_WAKE_UP_EN_REG (MVEBU_PMSU_REG_BASE + 0x2C) + #define MVEBU_PM_SB_WKP_NB_EN BIT(31) + #define MVEBU_PM_NB_GPIO_WKP_EN BIT(27) + #define MVEBU_PM_SOC_TIMER_WKP_EN BIT(26) + #define MVEBU_PM_UART_WKP_EN BIT(25) + #define MVEBU_PM_UART2_WKP_EN BIT(19) + #define MVEBU_PM_CPU_TIMER_WKP_EN BIT(17) + #define MVEBU_PM_NB_WKP_EN BIT(16) + #define MVEBU_PM_CORE1_FIQ_IRQ_WKP_EN BIT(13) + #define MVEBU_PM_CORE0_FIQ_IRQ_WKP_EN BIT(12) +#define MVEBU_PM_CPU_0_PWR_CTRL_REG (MVEBU_PMSU_REG_BASE + 0x34) +#define MVEBU_PM_CPU_1_PWR_CTRL_REG (MVEBU_PMSU_REG_BASE + 0x38) + #define MVEBU_PM_CORE_SOC_PD BIT(2) + #define MVEBU_PM_CORE_PROC_PD BIT(1) + #define MVEBU_PM_CORE_PD BIT(0) +#define MVEBU_PM_CORE_1_RETURN_ADDR_REG (MVEBU_PMSU_REG_BASE + 0x44) +#define MVEBU_PM_CPU_VDD_OFF_INFO_1_REG (MVEBU_PMSU_REG_BASE + 0x48) +#define MVEBU_PM_CPU_VDD_OFF_INFO_2_REG (MVEBU_PMSU_REG_BASE + 0x4C) + #define MVEBU_PM_LOW_POWER_STATE BIT(0) +#define MVEBU_PM_CPU_WAKE_UP_CONF_REG (MVEBU_PMSU_REG_BASE + 0x54) + #define MVEBU_PM_CORE1_WAKEUP BIT(13) + #define MVEBU_PM_CORE0_WAKEUP BIT(12) +#define MVEBU_PM_WAIT_DDR_RDY_VALUE (0x15) +#define MVEBU_PM_SB_CPU_PWR_CTRL_REG (MVEBU_SB_WAKEUP_REG_BASE) + #define MVEBU_PM_SB_PM_START BIT(0) +#define MVEBU_PM_SB_PWR_OPTION_REG (MVEBU_SB_WAKEUP_REG_BASE + 0x4) + #define MVEBU_PM_SDIO_PHY_PDWN_EN BIT(17) + #define MVEBU_PM_SB_VDDV_OFF_EN BIT(16) + #define MVEBU_PM_EBM_SRAM_LKG_PD_EN BIT(11) + #define MVEBU_PM_PCIE_SRAM_LKG_PD_EN BIT(10) + #define MVEBU_PM_GBE1_TX_SRAM_LKG_PD_EN BIT(9) + #define MVEBU_PM_GBE1_RX_SRAM_LKG_PD_EN BIT(8) + #define MVEBU_PM_GBE1_MIB_SRAM_LKG_PD_EN BIT(7) + #define MVEBU_PM_GBE0_TX_SRAM_LKG_PD_EN BIT(6) + #define MVEBU_PM_GBE0_RX_SRAM_LKG_PD_EN BIT(5) + #define MVEBU_PM_GBE0_MIB_SRAM_LKG_PD_EN BIT(4) + #define MVEBU_PM_SDIO_SRAM_LKG_PD_EN BIT(3) + #define MVEBU_PM_USB2_SRAM_LKG_PD_EN BIT(2) + #define MVEBU_PM_USB3_H_SRAM_LKG_PD_EN BIT(1) + #define MVEBU_PM_SB_SRAM_LKG_PD_EN (MVEBU_PM_EBM_SRAM_LKG_PD_EN |\ + MVEBU_PM_PCIE_SRAM_LKG_PD_EN | MVEBU_PM_GBE1_TX_SRAM_LKG_PD_EN |\ + MVEBU_PM_GBE1_RX_SRAM_LKG_PD_EN | MVEBU_PM_GBE1_MIB_SRAM_LKG_PD_EN |\ + MVEBU_PM_GBE0_TX_SRAM_LKG_PD_EN | MVEBU_PM_GBE0_RX_SRAM_LKG_PD_EN |\ + MVEBU_PM_GBE0_MIB_SRAM_LKG_PD_EN | MVEBU_PM_SDIO_SRAM_LKG_PD_EN |\ + MVEBU_PM_USB2_SRAM_LKG_PD_EN | MVEBU_PM_USB3_H_SRAM_LKG_PD_EN) +#define MVEBU_PM_SB_WK_EN_REG (MVEBU_SB_WAKEUP_REG_BASE + 0x10) + #define MVEBU_PM_SB_GPIO_WKP_EN BIT(24) + #define MVEBU_PM_SB_WKP_EN BIT(20) + +/* DRAM registers */ +#define MVEBU_DRAM_STATS_CH0_REG (MVEBU_DRAM_REG_BASE + 0x4) + #define MVEBU_DRAM_WCP_EMPTY BIT(19) +#define MVEBU_DRAM_CMD_0_REG (MVEBU_DRAM_REG_BASE + 0x20) + #define MVEBU_DRAM_CH0_CMD0 BIT(28) + #define MVEBU_DRAM_CS_CMD0 BIT(24) + #define MVEBU_DRAM_WCB_DRAIN_REQ BIT(1) +#define MVEBU_DRAM_PWR_CTRL_REG (MVEBU_DRAM_REG_BASE + 0x54) + #define MVEBU_DRAM_PHY_CLK_GATING_EN BIT(1) + #define MVEBU_DRAM_PHY_AUTO_AC_OFF_EN BIT(0) + +/* AVS registers */ +#define MVEBU_AVS_CTRL_2_REG (MVEBU_AVS_REG_BASE + 0x8) + #define MVEBU_LOW_VDD_MODE_EN BIT(6) + +/* Clock registers */ +#define MVEBU_NB_CLOCK_SEL_REG (MVEBU_NB_REGS_BASE + 0x10) + #define MVEBU_A53_CPU_CLK_SEL BIT(15) + +/* North Bridge Step-Down Registers */ +#define MVEBU_NB_STEP_DOWN_INT_EN_REG MVEBU_NB_STEP_DOWN_REG_BASE + #define MVEBU_NB_GPIO_INT_WAKE_WCPU_CLK BIT(8) + +#define MVEBU_NB_GPIO_18 18 +#define MVEBU_NB_GPIO_19 19 +#define MVEBU_NB_GPIO_25 25 +#define MVEBU_NB_GPIO_26 26 + +typedef int (*wake_up_src_func)(union pm_wake_up_src_data *); + +struct wake_up_src_func_map { + enum pm_wake_up_src_type type; + wake_up_src_func func; +}; + +void marvell_psci_arch_init(int die_index) +{ +} + +static void a3700_pm_ack_irq(void) +{ + uint32_t reg; + + reg = mmio_read_32(MVEBU_NB_IRQ_STATUS_1_REG); + if (reg) + mmio_write_32(MVEBU_NB_IRQ_STATUS_1_REG, reg); + + reg = mmio_read_32(MVEBU_NB_IRQ_STATUS_2_REG); + if (reg) + mmio_write_32(MVEBU_NB_IRQ_STATUS_2_REG, reg); + + reg = mmio_read_32(MVEBU_SB_IRQ_STATUS_1_REG); + if (reg) + mmio_write_32(MVEBU_SB_IRQ_STATUS_1_REG, reg); + + reg = mmio_read_32(MVEBU_SB_IRQ_STATUS_2_REG); + if (reg) + mmio_write_32(MVEBU_SB_IRQ_STATUS_2_REG, reg); + + reg = mmio_read_32(MVEBU_NB_GPIO_IRQ_STATUS_LOW_REG); + if (reg) + mmio_write_32(MVEBU_NB_GPIO_IRQ_STATUS_LOW_REG, reg); + + reg = mmio_read_32(MVEBU_NB_GPIO_IRQ_STATUS_HIGH_REG); + if (reg) + mmio_write_32(MVEBU_NB_GPIO_IRQ_STATUS_HIGH_REG, reg); + + reg = mmio_read_32(MVEBU_SB_GPIO_IRQ_STATUS_REG); + if (reg) + mmio_write_32(MVEBU_SB_GPIO_IRQ_STATUS_REG, reg); +} + +/***************************************************************************** + * A3700 handler called to check the validity of the power state + * parameter. + ***************************************************************************** + */ +int a3700_validate_power_state(unsigned int power_state, + psci_power_state_t *req_state) +{ + ERROR("%s needs to be implemented\n", __func__); + panic(); +} + +/***************************************************************************** + * A3700 handler called when a CPU is about to enter standby. + ***************************************************************************** + */ +void a3700_cpu_standby(plat_local_state_t cpu_state) +{ + ERROR("%s needs to be implemented\n", __func__); + panic(); +} + +/***************************************************************************** + * A3700 handler called when a power domain is about to be turned on. The + * mpidr determines the CPU to be turned on. + ***************************************************************************** + */ +int a3700_pwr_domain_on(u_register_t mpidr) +{ + /* Set barrier */ + dsbsy(); + + /* Set the cpu start address to BL1 entry point */ + mmio_write_32(MVEBU_CPU_1_RESET_VECTOR, + PLAT_MARVELL_CPU_ENTRY_ADDR >> 2); + + /* Get the cpu out of reset */ + mmio_clrbits_32(MVEBU_CPU_1_RESET_REG, BIT(MVEBU_CPU_1_RESET_BIT)); + mmio_setbits_32(MVEBU_CPU_1_RESET_REG, BIT(MVEBU_CPU_1_RESET_BIT)); + + return 0; +} + +/***************************************************************************** + * A3700 handler called to validate the entry point. + ***************************************************************************** + */ +int a3700_validate_ns_entrypoint(uintptr_t entrypoint) +{ + return PSCI_E_SUCCESS; +} + +/***************************************************************************** + * A3700 handler called when a power domain is about to be turned off. The + * target_state encodes the power state that each level should transition to. + ***************************************************************************** + */ +void a3700_pwr_domain_off(const psci_power_state_t *target_state) +{ + /* Prevent interrupts from spuriously waking up this cpu */ + plat_marvell_gic_cpuif_disable(); + + /* Core can not be powered down with pending IRQ, + * acknowledge all the pending IRQ + */ + a3700_pm_ack_irq(); +} + +static void a3700_set_gen_pwr_off_option(void) +{ + /* Enable L2 flush -> processor state-machine option */ + mmio_setbits_32(MVEBU_PM_NB_CPU_PWR_CTRL_REG, MVEBU_PM_L2_FLUSH_EN); + + /* + * North bridge cannot be VDD off (always ON). + * The NB state machine support low power mode by its state machine. + * This bit MUST be set for north bridge power down, e.g., + * OSC input cutoff(NOT TEST), SRAM power down, PMIC, etc. + * It is not related to CPU VDD OFF!! + */ + mmio_clrbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_CPU_VDDV_OFF_EN); + + /* + * MUST: Switch CPU/AXI clock to OSC + * NB state machine clock is always connected to OSC (slow clock). + * But Core0/1/processor state machine's clock are connected to AXI + * clock. Now, AXI clock takes the TBG as clock source. + * If using AXI clock, Core0/1/processor state machine may much faster + * than NB state machine. It will cause problem in this case if cores + * are released before north bridge gets ready. + */ + mmio_clrbits_32(MVEBU_NB_CLOCK_SEL_REG, MVEBU_A53_CPU_CLK_SEL); + + /* + * These register bits will trigger north bridge + * power-down state machine regardless CM3 status. + */ + mmio_setbits_32(MVEBU_PM_NB_PWR_DEBUG_REG, MVEBU_PM_IGNORE_CM3_SLEEP); + mmio_setbits_32(MVEBU_PM_NB_PWR_DEBUG_REG, MVEBU_PM_IGNORE_CM3_DEEP); + + /* + * SRAM => controlled by north bridge state machine. + * Core VDD OFF is not related to CPU SRAM power down. + */ + mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_NB_SRAM_LKG_PD_EN); + + /* + * Idle AXI interface in order to get L2_WFI + * L2 WFI is only asserted after CORE-0 and CORE-1 WFI asserted. + * (only both core-0/1in WFI, L2 WFI will be issued by CORE.) + * Once L2 WFI asserted, this bit is used for signalling assertion + * to AXI IO masters. + */ + mmio_setbits_32(MVEBU_PM_NB_PWR_CTRL_REG, MVEBU_PM_INTERFACE_IDLE); + + /* Enable core0 and core1 VDD_OFF */ + mmio_setbits_32(MVEBU_PM_CPU_0_PWR_CTRL_REG, MVEBU_PM_CORE_PD); + mmio_setbits_32(MVEBU_PM_CPU_1_PWR_CTRL_REG, MVEBU_PM_CORE_PD); + + /* Enable North bridge power down - + * Both Cores MUST enable this bit to power down north bridge! + */ + mmio_setbits_32(MVEBU_PM_CPU_0_PWR_CTRL_REG, MVEBU_PM_CORE_SOC_PD); + mmio_setbits_32(MVEBU_PM_CPU_1_PWR_CTRL_REG, MVEBU_PM_CORE_SOC_PD); + + /* CA53 (processor domain) power down */ + mmio_setbits_32(MVEBU_PM_CPU_0_PWR_CTRL_REG, MVEBU_PM_CORE_PROC_PD); + mmio_setbits_32(MVEBU_PM_CPU_1_PWR_CTRL_REG, MVEBU_PM_CORE_PROC_PD); +} + +static void a3700_en_ddr_self_refresh(void) +{ + /* + * Both count is 16 bits and configurable. By default, osc stb cnt + * is 0xFFF for lower 12 bits. + * Thus, powerdown count is smaller than osc count. + * This count is used for exiting DDR SR mode on wakeup event. + * The powerdown count also has impact on the following + * state changes: idle -> count-down -> ... (power-down, vdd off, etc) + * Here, make stable counter shorter + * Use power down count value instead of osc_stb_cnt to speed up + * DDR self refresh exit + */ + mmio_setbits_32(MVEBU_PM_NB_PWR_CTRL_REG, MVEBU_PM_PWR_DN_CNT_SEL); + + /* + * Enable DDR SR mode => controlled by north bridge state machine + * Therefore, we must powerdown north bridge to trigger the DDR SR + * mode switching. + */ + mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_DDR_SR_EN); + /* Disable DDR clock, otherwise DDR will not enter into SR mode. */ + mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_DDR_CLK_DIS_EN); + /* Power down DDR PHY (PAD) */ + mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_DDRPHY_PWRDWN_EN); + mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, + MVEBU_PM_DDRPHY_PAD_PWRDWN_EN); + + /* Set wait time for DDR ready in ROM code */ + mmio_write_32(MVEBU_PM_CPU_VDD_OFF_INFO_1_REG, + MVEBU_PM_WAIT_DDR_RDY_VALUE); + + /* DDR flush write buffer - mandatory */ + mmio_write_32(MVEBU_DRAM_CMD_0_REG, MVEBU_DRAM_CH0_CMD0 | + MVEBU_DRAM_CS_CMD0 | MVEBU_DRAM_WCB_DRAIN_REQ); + while ((mmio_read_32(MVEBU_DRAM_STATS_CH0_REG) & + MVEBU_DRAM_WCP_EMPTY) != MVEBU_DRAM_WCP_EMPTY) + ; + + /* Trigger PHY reset after ddr out of self refresh => + * supply reset pulse for DDR phy after wake up + */ + mmio_setbits_32(MVEBU_DRAM_PWR_CTRL_REG, MVEBU_DRAM_PHY_CLK_GATING_EN | + MVEBU_DRAM_PHY_AUTO_AC_OFF_EN); +} + +static void a3700_pwr_dn_avs(void) +{ + /* + * AVS power down - controlled by north bridge statemachine + * Enable AVS power down by clear the AVS disable bit. + */ + mmio_clrbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_AVS_DISABLE_MODE); + /* + * Should set BIT[12:13] to powerdown AVS. + * 1. Enable AVS VDD2 mode + * 2. After power down AVS, we must hold AVS output voltage. + * 3. We can choose the lower VDD for AVS power down. + */ + mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_AVS_VDD2_MODE); + mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_AVS_HOLD_MODE); + + /* Enable low VDD mode, AVS will set CPU to lowest core VDD 747mV */ + mmio_setbits_32(MVEBU_AVS_CTRL_2_REG, MVEBU_LOW_VDD_MODE_EN); +} + +static void a3700_pwr_dn_tbg(void) +{ + /* Power down TBG */ + mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_TBG_OFF_EN); +} + +static void a3700_pwr_dn_sb(void) +{ + /* Enable south bridge power down option */ + mmio_setbits_32(MVEBU_PM_NB_PWR_CTRL_REG, MVEBU_PM_SB_PWR_DWN); + + /* Enable SDIO_PHY_PWRDWN */ + mmio_setbits_32(MVEBU_PM_SB_PWR_OPTION_REG, MVEBU_PM_SDIO_PHY_PDWN_EN); + + /* Enable SRAM LRM on SB */ + mmio_setbits_32(MVEBU_PM_SB_PWR_OPTION_REG, MVEBU_PM_SB_SRAM_LKG_PD_EN); + + /* Enable SB Power Off */ + mmio_setbits_32(MVEBU_PM_SB_PWR_OPTION_REG, MVEBU_PM_SB_VDDV_OFF_EN); + + /* Kick off South Bridge Power Off */ + mmio_setbits_32(MVEBU_PM_SB_CPU_PWR_CTRL_REG, MVEBU_PM_SB_PM_START); +} + +static void a3700_set_pwr_off_option(void) +{ + /* Set general power off option */ + a3700_set_gen_pwr_off_option(); + + /* Enable DDR self refresh in low power mode */ + a3700_en_ddr_self_refresh(); + + /* Power down AVS */ + a3700_pwr_dn_avs(); + + /* Power down TBG */ + a3700_pwr_dn_tbg(); + + /* Power down south bridge, pay attention south bridge setting + * should be done before + */ + a3700_pwr_dn_sb(); +} + +static void a3700_set_wake_up_option(void) +{ + /* + * Enable the wakeup event for NB SOC => north-bridge + * state-machine enablement on wake-up event + */ + mmio_setbits_32(MVEBU_PM_NB_WAKE_UP_EN_REG, MVEBU_PM_NB_WKP_EN); + + /* Enable both core0 and core1 wakeup on demand */ + mmio_setbits_32(MVEBU_PM_CPU_WAKE_UP_CONF_REG, + MVEBU_PM_CORE1_WAKEUP | MVEBU_PM_CORE0_WAKEUP); + + /* Enable warm reset in low power mode */ + mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_WARM_RESET_EN); +} + +static void a3700_pm_en_nb_gpio(uint32_t gpio) +{ + /* For GPIO1 interrupt -- North bridge only */ + if (gpio >= 32) { + /* GPIO int mask */ + mmio_clrbits_32(MVEBU_NB_GPIO_IRQ_MASK_2_REG, BIT(gpio - 32)); + + /* NB_CPU_WAKE-up ENABLE GPIO int */ + mmio_setbits_32(MVEBU_NB_GPIO_IRQ_EN_HIGH_REG, BIT(gpio - 32)); + } else { + /* GPIO int mask */ + mmio_clrbits_32(MVEBU_NB_GPIO_IRQ_MASK_1_REG, BIT(gpio)); + + /* NB_CPU_WAKE-up ENABLE GPIO int */ + mmio_setbits_32(MVEBU_NB_GPIO_IRQ_EN_LOW_REG, BIT(gpio)); + } + + mmio_setbits_32(MVEBU_NB_STEP_DOWN_INT_EN_REG, + MVEBU_NB_GPIO_INT_WAKE_WCPU_CLK); + + /* Enable using GPIO as wakeup event + * (actually not only for north bridge) + */ + mmio_setbits_32(MVEBU_PM_NB_WAKE_UP_EN_REG, MVEBU_PM_NB_GPIO_WKP_EN | + MVEBU_PM_NB_WKP_EN | MVEBU_PM_CORE1_FIQ_IRQ_WKP_EN | + MVEBU_PM_CORE0_FIQ_IRQ_WKP_EN); +} + +static void a3700_pm_en_sb_gpio(uint32_t gpio) +{ + /* Enable using GPIO as wakeup event */ + mmio_setbits_32(MVEBU_PM_NB_WAKE_UP_EN_REG, MVEBU_PM_SB_WKP_NB_EN | + MVEBU_PM_NB_WKP_EN | MVEBU_PM_CORE1_FIQ_IRQ_WKP_EN | + MVEBU_PM_CORE0_FIQ_IRQ_WKP_EN); + + /* SB GPIO Wake UP | South Bridge Wake Up Enable */ + mmio_setbits_32(MVEBU_PM_SB_WK_EN_REG, MVEBU_PM_SB_GPIO_WKP_EN | + MVEBU_PM_SB_GPIO_WKP_EN); + + /* GPIO int mask */ + mmio_clrbits_32(MVEBU_SB_GPIO_IRQ_MASK_REG, BIT(gpio)); + + /* NB_CPU_WAKE-up ENABLE GPIO int */ + mmio_setbits_32(MVEBU_SB_GPIO_IRQ_EN_REG, BIT(gpio)); +} + +int a3700_pm_src_gpio(union pm_wake_up_src_data *src_data) +{ + if (src_data->gpio_data.bank_num == 0) + /* North Bridge GPIO */ + a3700_pm_en_nb_gpio(src_data->gpio_data.gpio_num); + else + a3700_pm_en_sb_gpio(src_data->gpio_data.gpio_num); + return 0; +} + +int a3700_pm_src_uart1(union pm_wake_up_src_data *src_data) +{ + /* Clear Uart1 select */ + mmio_clrbits_32(MVEBU_NB_GPIO1_SEL_REG, MVEBU_NB_GPIO1_UART1_SEL); + /* set pin 19 gpio usage*/ + mmio_setbits_32(MVEBU_NB_GPIO1_SEL_REG, MVEBU_NB_GPIO1_GPIO_19_EN); + /* Enable gpio wake-up*/ + a3700_pm_en_nb_gpio(MVEBU_NB_GPIO_19); + /* set pin 18 gpio usage*/ + mmio_setbits_32(MVEBU_NB_GPIO1_SEL_REG, MVEBU_NB_GPIO1_GPIO_18_EN); + /* Enable gpio wake-up*/ + a3700_pm_en_nb_gpio(MVEBU_NB_GPIO_18); + + return 0; +} + +int a3700_pm_src_uart0(union pm_wake_up_src_data *src_data) +{ + /* set pin 25/26 gpio usage*/ + mmio_setbits_32(MVEBU_NB_GPIO1_SEL_REG, MVEBU_NB_GPIO1_GPIO_25_26_EN); + /* Enable gpio wake-up*/ + a3700_pm_en_nb_gpio(MVEBU_NB_GPIO_25); + /* Enable gpio wake-up*/ + a3700_pm_en_nb_gpio(MVEBU_NB_GPIO_26); + + return 0; +} + +struct wake_up_src_func_map src_func_table[WAKE_UP_SRC_MAX] = { + {WAKE_UP_SRC_GPIO, a3700_pm_src_gpio}, + {WAKE_UP_SRC_UART1, a3700_pm_src_uart1}, + {WAKE_UP_SRC_UART0, a3700_pm_src_uart0}, + /* FOLLOWING SRC NOT SUPPORTED YET */ + {WAKE_UP_SRC_TIMER, NULL} +}; + +static wake_up_src_func a3700_get_wake_up_src_func( + enum pm_wake_up_src_type type) +{ + uint32_t loop; + + for (loop = 0; loop < WAKE_UP_SRC_MAX; loop++) { + if (src_func_table[loop].type == type) + return src_func_table[loop].func; + } + return NULL; +} + +static void a3700_set_wake_up_source(void) +{ + struct pm_wake_up_src_config *wake_up_src; + uint32_t loop; + wake_up_src_func src_func = NULL; + + wake_up_src = mv_wake_up_src_config_get(); + for (loop = 0; loop < wake_up_src->wake_up_src_num; loop++) { + src_func = a3700_get_wake_up_src_func( + wake_up_src->wake_up_src[loop].wake_up_src_type); + if (src_func) + src_func( + &(wake_up_src->wake_up_src[loop].wake_up_data)); + } +} + +static void a3700_pm_save_lp_flag(void) +{ + /* Save the flag for enter the low power mode */ + mmio_setbits_32(MVEBU_PM_CPU_VDD_OFF_INFO_2_REG, + MVEBU_PM_LOW_POWER_STATE); +} + +static void a3700_pm_clear_lp_flag(void) +{ + /* Clear the flag for enter the low power mode */ + mmio_clrbits_32(MVEBU_PM_CPU_VDD_OFF_INFO_2_REG, + MVEBU_PM_LOW_POWER_STATE); +} + +static uint32_t a3700_pm_get_lp_flag(void) +{ + /* Get the flag for enter the low power mode */ + return mmio_read_32(MVEBU_PM_CPU_VDD_OFF_INFO_2_REG) & + MVEBU_PM_LOW_POWER_STATE; +} + +/***************************************************************************** + * A3700 handler called when a power domain is about to be suspended. The + * target_state encodes the power state that each level should transition to. + ***************************************************************************** + */ +void a3700_pwr_domain_suspend(const psci_power_state_t *target_state) +{ + /* Prevent interrupts from spuriously waking up this cpu */ + plat_marvell_gic_cpuif_disable(); + + /* Save IRQ states */ + plat_marvell_gic_irq_save(); + + /* Set wake up options */ + a3700_set_wake_up_option(); + + /* Set wake up sources */ + a3700_set_wake_up_source(); + + /* SoC can not be powered down with pending IRQ, + * acknowledge all the pending IRQ + */ + a3700_pm_ack_irq(); + + /* Set power off options */ + a3700_set_pwr_off_option(); + + /* Save the flag for enter the low power mode */ + a3700_pm_save_lp_flag(); + + isb(); +} + +/***************************************************************************** + * A3700 handler called when a power domain has just been powered on after + * being turned off earlier. The target_state encodes the low power state that + * each level has woken up from. + ***************************************************************************** + */ +void a3700_pwr_domain_on_finish(const psci_power_state_t *target_state) +{ + /* arch specific configuration */ + marvell_psci_arch_init(0); + + /* Per-CPU interrupt initialization */ + plat_marvell_gic_pcpu_init(); + plat_marvell_gic_cpuif_enable(); + + /* Restore the per-cpu IRQ state */ + if (a3700_pm_get_lp_flag()) + plat_marvell_gic_irq_pcpu_restore(); +} + +/***************************************************************************** + * A3700 handler called when a power domain has just been powered on after + * having been suspended earlier. The target_state encodes the low power state + * that each level has woken up from. + * TODO: At the moment we reuse the on finisher and reinitialize the secure + * context. Need to implement a separate suspend finisher. + ***************************************************************************** + */ +void a3700_pwr_domain_suspend_finish(const psci_power_state_t *target_state) +{ + struct dec_win_config *io_dec_map; + uint32_t dec_win_num; + struct dram_win_map dram_wins_map; + + /* arch specific configuration */ + marvell_psci_arch_init(0); + + /* Interrupt initialization */ + plat_marvell_gic_init(); + + /* Restore IRQ states */ + plat_marvell_gic_irq_restore(); + + /* + * Initialize CCI for this cluster after resume from suspend state. + * No need for locks as no other CPU is active. + */ + plat_marvell_interconnect_init(); + /* + * Enable CCI coherency for the primary CPU's cluster. + * Platform specific PSCI code will enable coherency for other + * clusters. + */ + plat_marvell_interconnect_enter_coherency(); + + /* CPU address decoder windows initialization. */ + cpu_wins_init(); + + /* fetch CPU-DRAM window mapping information by reading + * CPU-DRAM decode windows (only the enabled ones) + */ + dram_win_map_build(&dram_wins_map); + + /* Get IO address decoder windows */ + if (marvell_get_io_dec_win_conf(&io_dec_map, &dec_win_num)) { + printf("No IO address decoder windows configurations found!\n"); + return; + } + + /* IO address decoder init */ + if (init_io_addr_dec(&dram_wins_map, io_dec_map, dec_win_num)) { + printf("IO address decoder windows initialization failed!\n"); + return; + } + + /* Clear low power mode flag */ + a3700_pm_clear_lp_flag(); +} + +/***************************************************************************** + * This handler is called by the PSCI implementation during the `SYSTEM_SUSPEND + * call to get the `power_state` parameter. This allows the platform to encode + * the appropriate State-ID field within the `power_state` parameter which can + * be utilized in `pwr_domain_suspend()` to suspend to system affinity level. + ***************************************************************************** + */ +void a3700_get_sys_suspend_power_state(psci_power_state_t *req_state) +{ + /* lower affinities use PLAT_MAX_OFF_STATE */ + for (int i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++) + req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE; +} + +/***************************************************************************** + * A3700 handlers to shutdown/reboot the system + ***************************************************************************** + */ +static void __dead2 a3700_system_off(void) +{ + ERROR("%s needs to be implemented\n", __func__); + panic(); +} + +/***************************************************************************** + * A3700 handlers to reset the system + ***************************************************************************** + */ +static void __dead2 a3700_system_reset(void) +{ + /* Clean the mailbox magic number to let it as act like cold boot */ + mmio_write_32(PLAT_MARVELL_MAILBOX_BASE, 0x0); + + dsbsy(); + + /* Flush data cache if the mail box shared RAM is cached */ +#if PLAT_MARVELL_SHARED_RAM_CACHED + flush_dcache_range((uintptr_t)PLAT_MARVELL_MAILBOX_BASE, + 2 * sizeof(uint64_t)); +#endif + + /* Trigger the warm reset */ + mmio_write_32(MVEBU_WARM_RESET_REG, MVEBU_WARM_RESET_MAGIC); + + /* Shouldn't get to this point */ + panic(); +} + +/***************************************************************************** + * Export the platform handlers via plat_arm_psci_pm_ops. The ARM Standard + * platform layer will take care of registering the handlers with PSCI. + ***************************************************************************** + */ +const plat_psci_ops_t plat_arm_psci_pm_ops = { + .cpu_standby = a3700_cpu_standby, + .pwr_domain_on = a3700_pwr_domain_on, + .pwr_domain_off = a3700_pwr_domain_off, + .pwr_domain_suspend = a3700_pwr_domain_suspend, + .pwr_domain_on_finish = a3700_pwr_domain_on_finish, + .pwr_domain_suspend_finish = a3700_pwr_domain_suspend_finish, + .get_sys_suspend_power_state = a3700_get_sys_suspend_power_state, + .system_off = a3700_system_off, + .system_reset = a3700_system_reset, + .validate_power_state = a3700_validate_power_state, + .validate_ns_entrypoint = a3700_validate_ns_entrypoint +}; diff --git a/plat/marvell/armada/a8k/a70x0/board/dram_port.c b/plat/marvell/armada/a8k/a70x0/board/dram_port.c new file mode 100644 index 000000000..4fca7e383 --- /dev/null +++ b/plat/marvell/armada/a8k/a70x0/board/dram_port.c @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2018 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 + */ +static struct mv_ddr_topology_map board_topology_map = { +/* FIXME: MISL board 2CS 4Gb x8 devices of micron - 2133P */ + 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_2133P, /* 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 */ + MV_DDR_32BIT_ECC_PUP8_BUS_MASK, /* subphys mask */ + MV_DDR_CFG_DEFAULT, /* ddr configuration data source */ + { {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 */ + }, + } +}; + +struct mv_ddr_topology_map *mv_ddr_topology_map_get(void) +{ + /* Return the board topology as defined in the board code */ + return &board_topology_map; +} diff --git a/plat/marvell/armada/a8k/a70x0/board/marvell_plat_config.c b/plat/marvell/armada/a8k/a70x0/board/marvell_plat_config.c new file mode 100644 index 000000000..d126f5567 --- /dev/null +++ b/plat/marvell/armada/a8k/a70x0/board/marvell_plat_config.c @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2018 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 + {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 +struct skip_image skip_im = { + .detection_method = GPIO, + .info.gpio.num = 33, + .info.gpio.button_state = HIGH, + .info.test.cp_ap = CP, + .info.test.cp_index = 0, +}; + +void *plat_marvell_get_skip_image_data(void) +{ + /* Return the skip_image configurations */ + return &skip_im; +} +#endif +#endif diff --git a/plat/marvell/armada/a8k/a70x0/mvebu_def.h b/plat/marvell/armada/a8k/a70x0/mvebu_def.h new file mode 100644 index 000000000..72bca12e3 --- /dev/null +++ b/plat/marvell/armada/a8k/a70x0/mvebu_def.h @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2018 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/platform.mk b/plat/marvell/armada/a8k/a70x0/platform.mk new file mode 100644 index 000000000..a77e34985 --- /dev/null +++ b/plat/marvell/armada/a8k/a70x0/platform.mk @@ -0,0 +1,19 @@ +# +# Copyright (C) 2018 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 + +include plat/marvell/armada/a8k/common/a8k_common.mk + +include plat/marvell/armada/common/marvell_common.mk diff --git a/plat/marvell/armada/a8k/a70x0_amc/board/dram_port.c b/plat/marvell/armada/a8k/a70x0_amc/board/dram_port.c new file mode 100644 index 000000000..aecf6c567 --- /dev/null +++ b/plat/marvell/armada/a8k/a70x0_amc/board/dram_port.c @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2018 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 + */ +static struct mv_ddr_topology_map board_topology_map = { +/* FIXME: MISL board 2CS 8Gb x8 devices of micron - 2133P */ + 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_2400T, /* 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 */ + MV_DDR_32BIT_ECC_PUP8_BUS_MASK, /* subphys mask */ + MV_DDR_CFG_DEFAULT, /* ddr configuration data source */ + { {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 */ + }, + } +}; + +struct mv_ddr_topology_map *mv_ddr_topology_map_get(void) +{ + /* Return the board topology as defined in the board code */ + return &board_topology_map; +} diff --git a/plat/marvell/armada/a8k/a70x0_amc/board/marvell_plat_config.c b/plat/marvell/armada/a8k/a70x0_amc/board/marvell_plat_config.c new file mode 100644 index 000000000..f8a1c40be --- /dev/null +++ b/plat/marvell/armada/a8k/a70x0_amc/board/marvell_plat_config.c @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2018 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; + +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[] = { + /* PEX0_X4 window */ + {0x00000000f6000000, 0x6000000, PEX0_TID}, + {0x00000000c0000000, 0x30000000, PEX0_TID}, + {0x0000000800000000, 0x200000000, PEX0_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[] = { +#ifdef IMAGE_BLE + {0x00000000f2000000, 0x4000000, IO_0_TID}, /* IO window */ +#else + {0x00000000f2000000, 0xe000000, IO_0_TID}, + {0x00000000c0000000, 0x30000000, IO_0_TID}, /* IO window */ + {0x0000000800000000, 0x200000000, 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 + +struct pci_hw_cfg *plat_get_pcie_hw_data(void) +{ + return NULL; +} + +/***************************************************************************** + * SKIP IMAGE Configuration + ***************************************************************************** + */ +#if PLAT_RECOVERY_IMAGE_ENABLE +struct skip_image skip_im = { + .detection_method = GPIO, + .info.gpio.num = 33, + .info.gpio.button_state = HIGH, + .info.test.cp_ap = CP, + .info.test.cp_index = 0, +}; + +void *plat_marvell_get_skip_image_data(void) +{ + /* Return the skip_image configurations */ + return &skip_im; +} +#endif +#endif diff --git a/plat/marvell/armada/a8k/a70x0_amc/mvebu_def.h b/plat/marvell/armada/a8k/a70x0_amc/mvebu_def.h new file mode 100644 index 000000000..cedf3239a --- /dev/null +++ b/plat/marvell/armada/a8k/a70x0_amc/mvebu_def.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2018 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 */ + +/*********************************************************************** + * Required platform porting definitions common to all + * Management Compute SubSystems (MSS) + *********************************************************************** + */ +/* + * Load address of SCP_BL2 + * SCP_BL2 is loaded to the same place as BL31. + * Once SCP_BL2 is transferred to the SCP, + * it is discarded and BL31 is loaded over the top. + */ +#ifdef SCP_IMAGE +#define SCP_BL2_BASE BL31_BASE +#endif + + +#endif /* MVEBU_DEF_H */ diff --git a/plat/marvell/armada/a8k/a70x0_amc/platform.mk b/plat/marvell/armada/a8k/a70x0_amc/platform.mk new file mode 100644 index 000000000..a77e34985 --- /dev/null +++ b/plat/marvell/armada/a8k/a70x0_amc/platform.mk @@ -0,0 +1,19 @@ +# +# Copyright (C) 2018 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 + +include plat/marvell/armada/a8k/common/a8k_common.mk + +include plat/marvell/armada/common/marvell_common.mk diff --git a/plat/marvell/armada/a8k/a80x0/board/dram_port.c b/plat/marvell/armada/a8k/a80x0/board/dram_port.c new file mode 100644 index 000000000..02f4ffb0a --- /dev/null +++ b/plat/marvell/armada/a8k/a80x0/board/dram_port.c @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include +#include +#include + +#include +#include +#include + +#define MVEBU_AP_MPP_CTRL0_7_REG MVEBU_AP_MPP_REGS(0) +#define MVEBU_AP_MPP_CTRL4_OFFS 16 +#define MVEBU_AP_MPP_CTRL5_OFFS 20 +#define MVEBU_AP_MPP_CTRL4_I2C0_SDA_ENA 0x3 +#define MVEBU_AP_MPP_CTRL5_I2C0_SCK_ENA 0x3 + +#define MVEBU_CP_MPP_CTRL37_OFFS 20 +#define MVEBU_CP_MPP_CTRL38_OFFS 24 +#define MVEBU_CP_MPP_CTRL37_I2C0_SCK_ENA 0x2 +#define MVEBU_CP_MPP_CTRL38_I2C0_SDA_ENA 0x2 + +#define MVEBU_MPP_CTRL_MASK 0xf + +/* + * This struct provides the DRAM training code with + * the appropriate board DRAM configuration + */ +static struct mv_ddr_topology_map board_topology_map = { + /* MISL board with 1CS 8Gb x4 devices of Micron 2400T */ + DEBUG_LEVEL_ERROR, + 0x1, /* active interfaces */ + /* cs_mask, mirror, dqs_swap, ck_swap X subphys */ + { { { {0x1, 0x0, 0, 0}, /* FIXME: change the cs mask for all 64 bit */ + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0} }, + /* TODO: double check if the speed bin is 2400T */ + SPEED_BIN_DDR_2400T, /* 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 */ + MV_DDR_64BIT_ECC_PUP8_BUS_MASK, /* subphys mask */ + MV_DDR_CFG_SPD, /* ddr configuration data source */ + { {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 */ + }, + } +}; + +struct mv_ddr_topology_map *mv_ddr_topology_map_get(void) +{ + /* Return the board topology as defined in the board code */ + return &board_topology_map; +} + +static void mpp_config(void) +{ + uintptr_t reg; + uint32_t val; + + reg = MVEBU_CP_MPP_REGS(0, 4); + /* configure CP0 MPP 37 and 38 to i2c */ + val = mmio_read_32(reg); + val &= ~((MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL37_OFFS) | + (MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL38_OFFS)); + val |= (MVEBU_CP_MPP_CTRL37_I2C0_SCK_ENA << + MVEBU_CP_MPP_CTRL37_OFFS) | + (MVEBU_CP_MPP_CTRL38_I2C0_SDA_ENA << + MVEBU_CP_MPP_CTRL38_OFFS); + mmio_write_32(reg, val); +} + +/* + * 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) +{ + struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); + + INFO("Gathering DRAM information\n"); + + if (tm->cfg_src == MV_DDR_CFG_SPD) { + /* configure MPPs to enable i2c */ + mpp_config(); + + /* initialize i2c */ + i2c_init((void *)MVEBU_CP0_I2C_BASE); + + /* select SPD memory page 0 to access DRAM configuration */ + i2c_write(I2C_SPD_P0_ADDR, 0x0, 1, tm->spd_data.all_bytes, 1); + + /* read data from spd */ + i2c_read(I2C_SPD_ADDR, 0x0, 1, tm->spd_data.all_bytes, + sizeof(tm->spd_data.all_bytes)); + } +} diff --git a/plat/marvell/armada/a8k/a80x0/board/marvell_plat_config.c b/plat/marvell/armada/a8k/a80x0/board/marvell_plat_config.c new file mode 100644 index 000000000..7901dd225 --- /dev/null +++ b/plat/marvell/armada/a8k/a80x0/board/marvell_plat_config.c @@ -0,0 +1,196 @@ +/* + * Copyright (C) 2018 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[] = { + /* CP1 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[] = { + /* CP1 (MCI0) internal regs */ + {0x00000000f4000000, 0x2000000, MCI_0_TID}, +#ifndef IMAGE_BLE + /* PCIe0 and SPI1_CS0 (RUNIT) on CP1*/ + {0x00000000f9000000, 0x2000000, MCI_0_TID}, + /* PCIe1 on CP1*/ + {0x00000000fb000000, 0x1000000, MCI_0_TID}, + /* PCIe2 on CP1*/ + {0x00000000fc000000, 0x1000000, MCI_0_TID}, + /* 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_cp0[] = { + /* CP0 */ + /* PEX1_X1 window */ + {0x00000000f7000000, 0x1000000, PEX1_TID}, + /* PEX2_X1 window */ + {0x00000000f8000000, 0x1000000, PEX2_TID}, + /* PEX0_X4 window */ + {0x00000000f6000000, 0x1000000, PEX0_TID}, + {0x00000000c0000000, 0x30000000, PEX0_TID}, + {0x0000000800000000, 0x100000000, PEX0_TID}, +}; + +struct addr_map_win iob_memory_map_cp1[] = { + /* CP1 */ + /* SPI1_CS0 (RUNIT) window */ + {0x00000000f9000000, 0x1000000, RUNIT_TID}, + /* PEX1_X1 window */ + {0x00000000fb000000, 0x1000000, PEX1_TID}, + /* PEX2_X1 window */ + {0x00000000fc000000, 0x1000000, PEX2_TID}, + /* PEX0_X4 window */ + {0x00000000fa000000, 0x1000000, PEX0_TID} +}; + +int marvell_get_iob_memory_map(struct addr_map_win **win, uint32_t *size, + uintptr_t base) +{ + switch (base) { + case MVEBU_CP_REGS_BASE(0): + *win = iob_memory_map_cp0; + *size = ARRAY_SIZE(iob_memory_map_cp0); + return 0; + case MVEBU_CP_REGS_BASE(1): + *win = iob_memory_map_cp1; + *size = ARRAY_SIZE(iob_memory_map_cp1); + return 0; + default: + *size = 0; + *win = 0; + return 1; + } +} +#endif + +/***************************************************************************** + * CCU Configuration + ***************************************************************************** + */ +struct addr_map_win ccu_memory_map[] = { +#ifdef IMAGE_BLE + {0x00000000f2000000, 0x4000000, IO_0_TID}, /* IO window */ +#else + {0x00000000f2000000, 0xe000000, IO_0_TID}, /* IO window */ + {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, struct addr_map_win **win, + uint32_t *size) +{ + *win = ccu_memory_map; + *size = ARRAY_SIZE(ccu_memory_map); + + return 0; +} + +#ifndef IMAGE_BLE +/***************************************************************************** + * SoC PM configuration + ***************************************************************************** + */ +/* CP GPIO should be used and the GPIOs should be within same GPIO register */ +struct power_off_method pm_cfg = { + .type = PMIC_GPIO, + .cfg.gpio.pin_count = 1, + .cfg.gpio.info = {{0, 35} }, + .cfg.gpio.step_count = 7, + .cfg.gpio.seq = {1, 0, 1, 0, 1, 0, 1}, + .cfg.gpio.delay_ms = 10, +}; + +void *plat_marvell_get_pm_cfg(void) +{ + /* Return the PM configurations */ + return &pm_cfg; +} + +/* In reference to #ifndef IMAGE_BLE, this part is used for BLE only. */ +#else +/***************************************************************************** + * SKIP IMAGE Configuration + ***************************************************************************** + */ +#if PLAT_RECOVERY_IMAGE_ENABLE +struct skip_image skip_im = { + .detection_method = GPIO, + .info.gpio.num = 33, + .info.gpio.button_state = HIGH, + .info.test.cp_ap = CP, + .info.test.cp_index = 0, +}; + +void *plat_marvell_get_skip_image_data(void) +{ + /* Return the skip_image configurations */ + return &skip_im; +} +#endif +#endif diff --git a/plat/marvell/armada/a8k/a80x0/board/phy-porting-layer.h b/plat/marvell/armada/a8k/a80x0/board/phy-porting-layer.h new file mode 100644 index 000000000..abd85b5d2 --- /dev/null +++ b/plat/marvell/armada/a8k/a80x0/board/phy-porting-layer.h @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2018 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 */ + { .g1_ffe_res_sel = 0x3, .g1_ffe_cap_sel = 0xf, + .align90 = 0x5f, + .g1_dfe_res = 0x2, .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 = 0x1 }, /* Comphy2 */ + { 0 }, /* Comphy3 */ + { .g1_ffe_res_sel = 0x3, .g1_ffe_cap_sel = 0xf, + .align90 = 0x5f, + .g1_dfe_res = 0x2, .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 = 0x1 }, /* Comphy4 */ + { 0 }, /* Comphy5 */ + }, + + /* CP 1 */ + { + { 0 }, /* Comphy0 */ + { 0 }, /* Comphy1 */ + { .g1_ffe_res_sel = 0x3, .g1_ffe_cap_sel = 0xf, + .align90 = 0x5f, + .g1_dfe_res = 0x2, .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 = 0x1 }, /* Comphy2 */ + { 0 }, /* Comphy3 */ + { .g1_ffe_res_sel = 0x3, .g1_ffe_cap_sel = 0xf, + .align90 = 0x5f, + .g1_dfe_res = 0x2, .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 = 0x1 }, /* Comphy4 */ + { 0 }, /* Comphy5 */ + }, + }, +}; + +static const struct sata_params + sata_static_values_tab[AP_NUM][CP_NUM][MAX_LANE_NR] = { + /* AP0 */ + { + /* CP 0 */ + { + { 0 }, /* Comphy0 */ + { .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, + .valid = 0x1 + }, /* Comphy1 */ + { 0 }, /* 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, + .valid = 0x1 + }, /* Comphy3 */ + { 0 }, /* Comphy4 */ + { 0 }, /* Comphy5 */ + }, + + /* CP 1 */ + { + { 0 }, /* Comphy0 */ + { .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, + .valid = 0x1 + }, /* Comphy1 */ + { 0 }, /* 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, + .valid = 0x1 + }, /* Comphy3 */ + { 0 }, /* Comphy4 */ + { 0 }, /* Comphy5 */ + + }, + }, +}; +#endif /* PHY_PORTING_LAYER_H */ diff --git a/plat/marvell/armada/a8k/a80x0/mvebu_def.h b/plat/marvell/armada/a8k/a80x0/mvebu_def.h new file mode 100644 index 000000000..3fa119af6 --- /dev/null +++ b/plat/marvell/armada/a8k/a80x0/mvebu_def.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2018 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 2 /* A80x0 has both CP0 & CP1 */ +#define I2C_SPD_ADDR 0x53 /* Access SPD data */ +#define I2C_SPD_P0_ADDR 0x36 /* Select SPD data page 0 */ + +#endif /* MVEBU_DEF_H */ diff --git a/plat/marvell/armada/a8k/a80x0/platform.mk b/plat/marvell/armada/a8k/a80x0/platform.mk new file mode 100644 index 000000000..56c4117d6 --- /dev/null +++ b/plat/marvell/armada/a8k/a80x0/platform.mk @@ -0,0 +1,20 @@ +# +# Copyright (C) 2018 Marvell International Ltd. +# +# SPDX-License-Identifier: BSD-3-Clause +# https://spdx.org/licenses +# + +PCI_EP_SUPPORT := 0 + +CP_NUM := 2 +$(eval $(call add_define,CP_NUM)) + +DOIMAGE_SEC := tools/doimage/secure/sec_img_8K.cfg + +MARVELL_MOCHI_DRV := drivers/marvell/mochi/apn806_setup.c + +include plat/marvell/armada/a8k/common/a8k_common.mk + +include plat/marvell/armada/common/marvell_common.mk +PLAT_INCLUDES += -Iplat/marvell/armada/a8k/a80x0/board diff --git a/plat/marvell/armada/a8k/a80x0_mcbin/board/dram_port.c b/plat/marvell/armada/a8k/a80x0_mcbin/board/dram_port.c new file mode 100644 index 000000000..25808523c --- /dev/null +++ b/plat/marvell/armada/a8k/a80x0_mcbin/board/dram_port.c @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include +#include +#include + +#include +#include +#include + +#define MVEBU_CP_MPP_CTRL37_OFFS 20 +#define MVEBU_CP_MPP_CTRL38_OFFS 24 +#define MVEBU_CP_MPP_CTRL37_I2C0_SCK_ENA 0x2 +#define MVEBU_CP_MPP_CTRL38_I2C0_SDA_ENA 0x2 + +#define MVEBU_MPP_CTRL_MASK 0xf + +/* + * This struct provides the DRAM training code with + * the appropriate board DRAM configuration + */ +static struct mv_ddr_topology_map board_topology_map = { + /* Board with 1CS 8Gb x4 devices of Micron 2400T */ + DEBUG_LEVEL_ERROR, + 0x1, /* active interfaces */ + /* cs_mask, mirror, dqs_swap, ck_swap X subphys */ + { { { {0x1, 0x0, 0, 0}, /* FIXME: change the cs mask for all 64 bit */ + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0} }, + /* TODO: double check if the speed bin is 2400T */ + SPEED_BIN_DDR_2400T, /* 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 */ + MV_DDR_64BIT_BUS_MASK, /* subphys mask */ + MV_DDR_CFG_SPD, /* ddr configuration data source */ + { {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 */ + }, + } +}; + +struct mv_ddr_topology_map *mv_ddr_topology_map_get(void) +{ + /* Return the board topology as defined in the board code */ + return &board_topology_map; +} + +static void mpp_config(void) +{ + uint32_t val; + uintptr_t reg = MVEBU_CP_MPP_REGS(0, 4); + + /* configure CP0 MPP 37 and 38 to i2c */ + val = mmio_read_32(reg); + val &= ~((MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL37_OFFS) | + (MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL38_OFFS)); + val |= (MVEBU_CP_MPP_CTRL37_I2C0_SCK_ENA << MVEBU_CP_MPP_CTRL37_OFFS) | + (MVEBU_CP_MPP_CTRL38_I2C0_SDA_ENA << MVEBU_CP_MPP_CTRL38_OFFS); + mmio_write_32(reg, val); +} + +/* + * 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) +{ + struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); + + INFO("Gathering DRAM information\n"); + + if (tm->cfg_src == MV_DDR_CFG_SPD) { + /* configure MPPs to enable i2c */ + mpp_config(); + /* initialize the i2c */ + i2c_init((void *)MVEBU_CP0_I2C_BASE); + /* select SPD memory page 0 to access DRAM configuration */ + i2c_write(I2C_SPD_P0_ADDR, 0x0, 1, tm->spd_data.all_bytes, 1); + /* read data from spd */ + i2c_read(I2C_SPD_ADDR, 0x0, 1, tm->spd_data.all_bytes, + sizeof(tm->spd_data.all_bytes)); + } +} diff --git a/plat/marvell/armada/a8k/a80x0_mcbin/board/marvell_plat_config.c b/plat/marvell/armada/a8k/a80x0_mcbin/board/marvell_plat_config.c new file mode 100644 index 000000000..fa4e144c9 --- /dev/null +++ b/plat/marvell/armada/a8k/a80x0_mcbin/board/marvell_plat_config.c @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include + +#include + +/* + * If bootrom is currently at BLE there's no need to include the memory + * maps structure at this point + */ +#include +#ifndef IMAGE_BLE + +/***************************************************************************** + * GPIO Configuration + ***************************************************************************** + */ +#define MPP_CONTROL_REGISTER 0xf2440018 +#define MPP_CONTROL_MPP_SEL_52_MASK 0xf0000 +#define GPIO_DATA_OUT1_REGISTER 0xf2440140 +#define GPIO_DATA_OUT_EN_CTRL1_REGISTER 0xf2440144 +#define GPIO52_MASK 0x100000 + +/* Reset PCIe via GPIO number 52 */ +int marvell_gpio_config(void) +{ + uint32_t reg; + + reg = mmio_read_32(MPP_CONTROL_REGISTER); + reg |= MPP_CONTROL_MPP_SEL_52_MASK; + mmio_write_32(MPP_CONTROL_REGISTER, reg); + + reg = mmio_read_32(GPIO_DATA_OUT1_REGISTER); + reg |= GPIO52_MASK; + mmio_write_32(GPIO_DATA_OUT1_REGISTER, reg); + + reg = mmio_read_32(GPIO_DATA_OUT_EN_CTRL1_REGISTER); + reg &= ~GPIO52_MASK; + mmio_write_32(GPIO_DATA_OUT_EN_CTRL1_REGISTER, reg); + udelay(100); + + return 0; +} + +/***************************************************************************** + * AMB Configuration + ***************************************************************************** + */ +struct addr_map_win amb_memory_map[] = { + /* CP1 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[] = { + /* CP1 (MCI0) internal regs */ + {0x00000000f4000000, 0x2000000, MCI_0_TID}, +#ifndef IMAGE_BLE + /* PCIe0 and SPI1_CS0 (RUNIT) on CP1*/ + {0x00000000f9000000, 0x2000000, MCI_0_TID}, + /* PCIe1 on CP1*/ + {0x00000000fb000000, 0x1000000, MCI_0_TID}, + /* PCIe2 on CP1*/ + {0x00000000fc000000, 0x1000000, MCI_0_TID}, + /* 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_cp0[] = { + /* CP0 */ + /* PEX1_X1 window */ + {0x00000000f7000000, 0x1000000, PEX1_TID}, + /* PEX2_X1 window */ + {0x00000000f8000000, 0x1000000, PEX2_TID}, + /* PEX0_X4 window */ + {0x00000000f6000000, 0x1000000, PEX0_TID}, + {0x00000000c0000000, 0x30000000, PEX0_TID}, + {0x0000000800000000, 0x100000000, PEX0_TID}, +}; + +struct addr_map_win iob_memory_map_cp1[] = { + /* CP1 */ + /* SPI1_CS0 (RUNIT) window */ + {0x00000000f9000000, 0x1000000, RUNIT_TID}, + /* PEX1_X1 window */ + {0x00000000fb000000, 0x1000000, PEX1_TID}, + /* PEX2_X1 window */ + {0x00000000fc000000, 0x1000000, PEX2_TID}, + /* PEX0_X4 window */ + {0x00000000fa000000, 0x1000000, PEX0_TID} +}; + +int marvell_get_iob_memory_map(struct addr_map_win **win, uint32_t *size, + uintptr_t base) +{ + switch (base) { + case MVEBU_CP_REGS_BASE(0): + *win = iob_memory_map_cp0; + *size = ARRAY_SIZE(iob_memory_map_cp0); + return 0; + case MVEBU_CP_REGS_BASE(1): + *win = iob_memory_map_cp1; + *size = ARRAY_SIZE(iob_memory_map_cp1); + return 0; + default: + *size = 0; + *win = 0; + return 1; + } +} +#endif + +/***************************************************************************** + * CCU Configuration + ***************************************************************************** + */ +struct addr_map_win ccu_memory_map[] = { +#ifdef IMAGE_BLE + {0x00000000f2000000, 0x4000000, IO_0_TID}, /* IO window */ +#else + {0x00000000f2000000, 0xe000000, IO_0_TID}, /* IO window */ + {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; +} + +/* In reference to #ifndef IMAGE_BLE, this part is used for BLE only. */ + +/***************************************************************************** + * SKIP IMAGE Configuration + ***************************************************************************** + */ +void *plat_marvell_get_skip_image_data(void) +{ + /* No recovery button on A8k-MCBIN board */ + return NULL; +} diff --git a/plat/marvell/armada/a8k/a80x0_mcbin/mvebu_def.h b/plat/marvell/armada/a8k/a80x0_mcbin/mvebu_def.h new file mode 100644 index 000000000..3fa119af6 --- /dev/null +++ b/plat/marvell/armada/a8k/a80x0_mcbin/mvebu_def.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2018 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 2 /* A80x0 has both CP0 & CP1 */ +#define I2C_SPD_ADDR 0x53 /* Access SPD data */ +#define I2C_SPD_P0_ADDR 0x36 /* Select SPD data page 0 */ + +#endif /* MVEBU_DEF_H */ diff --git a/plat/marvell/armada/a8k/a80x0_mcbin/platform.mk b/plat/marvell/armada/a8k/a80x0_mcbin/platform.mk new file mode 100644 index 000000000..d962b3d2a --- /dev/null +++ b/plat/marvell/armada/a8k/a80x0_mcbin/platform.mk @@ -0,0 +1,19 @@ +# +# Copyright (C) 2018 Marvell International Ltd. +# +# SPDX-License-Identifier: BSD-3-Clause +# https://spdx.org/licenses +# + +PCI_EP_SUPPORT := 0 + +CP_NUM := 2 +$(eval $(call add_define,CP_NUM)) + +DOIMAGE_SEC := tools/doimage/secure/sec_img_8K.cfg + +MARVELL_MOCHI_DRV := drivers/marvell/mochi/apn806_setup.c + +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 new file mode 100644 index 000000000..471bc82c6 --- /dev/null +++ b/plat/marvell/armada/a8k/common/a8k_common.mk @@ -0,0 +1,130 @@ +# +# Copyright (C) 2016 - 2020 Marvell International Ltd. +# +# SPDX-License-Identifier: BSD-3-Clause +# https://spdx.org/licenses + +include tools/marvell/doimage/doimage.mk + +PLAT_FAMILY := a8k +PLAT_FAMILY_BASE := plat/marvell/armada/$(PLAT_FAMILY) +PLAT_INCLUDE_BASE := include/plat/marvell/armada/$(PLAT_FAMILY) +PLAT_COMMON_BASE := $(PLAT_FAMILY_BASE)/common +MARVELL_DRV_BASE := drivers/marvell +MARVELL_COMMON_BASE := plat/marvell/armada/common + +MARVELL_SVC_TEST := 0 +$(eval $(call add_define,MARVELL_SVC_TEST)) + +ERRATA_A72_859971 := 1 + +# Enable MSS support for a8k family +MSS_SUPPORT := 1 + +# Disable EL3 cache for power management +BL31_CACHE_DISABLE := 0 +$(eval $(call add_define,BL31_CACHE_DISABLE)) + +$(eval $(call add_define,PCI_EP_SUPPORT)) +$(eval $(call assert_boolean,PCI_EP_SUPPORT)) + +AP_NUM := 1 +$(eval $(call add_define,AP_NUM)) + +DOIMAGEPATH ?= tools/marvell/doimage +DOIMAGETOOL ?= ${DOIMAGEPATH}/doimage + +ROM_BIN_EXT ?= $(BUILD_PLAT)/ble.bin +DOIMAGE_FLAGS += -b $(ROM_BIN_EXT) $(NAND_DOIMAGE_FLAGS) $(DOIMAGE_SEC_FLAGS) + +# Check whether to build system_power.c for the platform +ifneq ("$(wildcard $(PLAT_FAMILY_BASE)/$(PLAT)/board/system_power.c)","") +SYSTEM_POWER_SUPPORT = 1 +else +SYSTEM_POWER_SUPPORT = 0 +endif + +# This define specifies DDR type for BLE +$(eval $(call add_define,CONFIG_DDR4)) + +MARVELL_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ + drivers/arm/gic/v2/gicv2_main.c \ + drivers/arm/gic/v2/gicv2_helpers.c \ + plat/common/plat_gicv2.c + +PLAT_INCLUDES := -I$(PLAT_FAMILY_BASE)/$(PLAT) \ + -I$(PLAT_COMMON_BASE)/include \ + -I$(PLAT_INCLUDE_BASE)/common + +PLAT_BL_COMMON_SOURCES := $(PLAT_COMMON_BASE)/aarch64/a8k_common.c \ + drivers/ti/uart/aarch64/16550_console.S + +BLE_PORTING_SOURCES := $(PLAT_FAMILY_BASE)/$(PLAT)/board/dram_port.c \ + $(PLAT_FAMILY_BASE)/$(PLAT)/board/marvell_plat_config.c + +MARVELL_MOCHI_DRV += $(MARVELL_DRV_BASE)/mochi/cp110_setup.c + +BLE_SOURCES := drivers/mentor/i2c/mi2cv.c \ + $(PLAT_COMMON_BASE)/plat_ble_setup.c \ + $(MARVELL_MOCHI_DRV) \ + $(PLAT_COMMON_BASE)/plat_pm.c \ + $(MARVELL_DRV_BASE)/ap807_clocks_init.c \ + $(MARVELL_DRV_BASE)/thermal.c \ + $(PLAT_COMMON_BASE)/plat_thermal.c \ + $(BLE_PORTING_SOURCES) \ + $(MARVELL_DRV_BASE)/ccu.c \ + $(MARVELL_DRV_BASE)/io_win.c + +BL1_SOURCES += $(PLAT_COMMON_BASE)/aarch64/plat_helpers.S \ + lib/cpus/aarch64/cortex_a72.S + +MARVELL_DRV := $(MARVELL_DRV_BASE)/io_win.c \ + $(MARVELL_DRV_BASE)/iob.c \ + $(MARVELL_DRV_BASE)/mci.c \ + $(MARVELL_DRV_BASE)/amb_adec.c \ + $(MARVELL_DRV_BASE)/ccu.c \ + $(MARVELL_DRV_BASE)/cache_llc.c \ + $(MARVELL_DRV_BASE)/comphy/phy-comphy-cp110.c \ + $(MARVELL_DRV_BASE)/mc_trustzone/mc_trustzone.c + +BL31_PORTING_SOURCES := $(PLAT_FAMILY_BASE)/$(PLAT)/board/marvell_plat_config.c + +ifeq ($(SYSTEM_POWER_SUPPORT),1) +BL31_PORTING_SOURCES += $(PLAT_FAMILY_BASE)/$(PLAT)/board/system_power.c +endif + +BL31_SOURCES += lib/cpus/aarch64/cortex_a72.S \ + $(PLAT_COMMON_BASE)/aarch64/plat_helpers.S \ + $(PLAT_COMMON_BASE)/aarch64/plat_arch_config.c \ + $(PLAT_COMMON_BASE)/plat_pm.c \ + $(PLAT_COMMON_BASE)/plat_bl31_setup.c \ + $(MARVELL_COMMON_BASE)/marvell_gicv2.c \ + $(MARVELL_COMMON_BASE)/mrvl_sip_svc.c \ + $(MARVELL_COMMON_BASE)/marvell_ddr_info.c \ + $(BL31_PORTING_SOURCES) \ + $(MARVELL_DRV) \ + $(MARVELL_MOCHI_DRV) \ + $(MARVELL_GIC_SOURCES) + +# Add trace functionality for PM +BL31_SOURCES += $(PLAT_COMMON_BASE)/plat_pm_trace.c + +# Force builds with BL2 image on a80x0 platforms +ifndef SCP_BL2 + $(error "Error: SCP_BL2 image is mandatory for a8k family") +endif + +# MSS (SCP) build +include $(PLAT_COMMON_BASE)/mss/mss_a8k.mk + +# BLE (ROM context execution code, AKA binary extension) +BLE_PATH ?= $(PLAT_COMMON_BASE)/ble + +include ${BLE_PATH}/ble.mk +$(eval $(call MAKE_BL,e)) + +mrvl_flash: ${BUILD_PLAT}/${FIP_NAME} ${DOIMAGETOOL} ${BUILD_PLAT}/ble.bin + $(shell truncate -s %128K ${BUILD_PLAT}/bl1.bin) + $(shell cat ${BUILD_PLAT}/bl1.bin ${BUILD_PLAT}/${FIP_NAME} > ${BUILD_PLAT}/${BOOT_IMAGE}) + ${DOIMAGETOOL} ${DOIMAGE_FLAGS} ${BUILD_PLAT}/${BOOT_IMAGE} ${BUILD_PLAT}/${FLASH_IMAGE} + diff --git a/plat/marvell/armada/a8k/common/aarch64/a8k_common.c b/plat/marvell/armada/a8k/common/aarch64/a8k_common.c new file mode 100644 index 000000000..7c2bf318f --- /dev/null +++ b/plat/marvell/armada/a8k/common/aarch64/a8k_common.c @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + + +/* MMU entry for internal (register) space access */ +#define MAP_DEVICE0 MAP_REGION_FLAT(DEVICE0_BASE, \ + DEVICE0_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +/* + * Table of regions for various BL stages to map using the MMU. + */ +#if IMAGE_BL1 +const mmap_region_t plat_marvell_mmap[] = { + MARVELL_MAP_SHARED_RAM, + MAP_DEVICE0, + {0} +}; +#endif +#if IMAGE_BL2 +const mmap_region_t plat_marvell_mmap[] = { + MARVELL_MAP_SHARED_RAM, + MAP_DEVICE0, + MARVELL_MAP_DRAM, + {0} +}; +#endif + +#if IMAGE_BL2U +const mmap_region_t plat_marvell_mmap[] = { + MAP_DEVICE0, + {0} +}; +#endif + +#if IMAGE_BLE +const mmap_region_t plat_marvell_mmap[] = { + MAP_DEVICE0, + {0} +}; +#endif + +#if IMAGE_BL31 +const mmap_region_t plat_marvell_mmap[] = { + MARVELL_MAP_SHARED_RAM, + MAP_DEVICE0, + MARVELL_MAP_DRAM, + {0} +}; +#endif +#if IMAGE_BL32 +const mmap_region_t plat_marvell_mmap[] = { + MAP_DEVICE0, + {0} +}; +#endif + +MARVELL_CASSERT_MMAP; diff --git a/plat/marvell/armada/a8k/common/aarch64/plat_arch_config.c b/plat/marvell/armada/a8k/common/aarch64/plat_arch_config.c new file mode 100644 index 000000000..06dc84115 --- /dev/null +++ b/plat/marvell/armada/a8k/common/aarch64/plat_arch_config.c @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include +#include +#include +#include + +#define CCU_HTC_ASET (MVEBU_CCU_BASE(MVEBU_AP0) + 0x264) +#define MVEBU_IO_AFFINITY (0xF00) + + +static void plat_enable_affinity(void) +{ + int cluster_id; + int affinity; + + /* set CPU Affinity */ + cluster_id = plat_my_core_pos() / PLAT_MARVELL_CLUSTER_CORE_COUNT; + affinity = (MVEBU_IO_AFFINITY | (1 << cluster_id)); + mmio_write_32(CCU_HTC_ASET, affinity); + + /* set barier */ + isb(); +} + +void marvell_psci_arch_init(int die_index) +{ +#if LLC_ENABLE + /* check if LLC is in exclusive mode + * as L2 is configured to UniqueClean eviction + * (in a8k reset handler) + */ + if (llc_is_exclusive(0) == 0) + ERROR("LLC should be configured to exclusice mode\n"); +#endif + + /* Enable Affinity */ + plat_enable_affinity(); +} diff --git a/plat/marvell/armada/a8k/common/aarch64/plat_helpers.S b/plat/marvell/armada/a8k/common/aarch64/plat_helpers.S new file mode 100644 index 000000000..fadc4c26b --- /dev/null +++ b/plat/marvell/armada/a8k/common/aarch64/plat_helpers.S @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include +#include + + .globl plat_secondary_cold_boot_setup + .globl plat_get_my_entrypoint + .globl plat_is_my_cpu_primary + .globl 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. Right + * now this is a stub function. + * ----------------------------------------------------- + */ +func plat_secondary_cold_boot_setup + mov x0, #0 + ret +endfunc plat_secondary_cold_boot_setup + + /* --------------------------------------------------------------------- + * unsigned long plat_get_my_entrypoint (void); + * + * Main job of this routine is to distinguish + * between a cold and warm boot + * For a cold boot, return 0. + * For a warm boot, read the mailbox and return the address it contains. + * + * --------------------------------------------------------------------- + */ +func plat_get_my_entrypoint + /* Read first word and compare it with magic num */ + mov_imm x0, PLAT_MARVELL_MAILBOX_BASE + ldr x1, [x0] + mov_imm x2, MVEBU_MAILBOX_MAGIC_NUM + cmp x1, x2 + beq warm_boot /* If compare failed, return 0, i.e. cold boot */ + mov x0, #0 + ret +warm_boot: + mov_imm x1, MBOX_IDX_SEC_ADDR /* Get the jump address */ + subs x1, x1, #1 + mov x2, #(MBOX_IDX_SEC_ADDR * 8) + lsl x3, x2, x1 + add x0, x0, x3 + ldr x0, [x0] + ret +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 + and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK) + cmp x0, #MVEBU_PRIMARY_CPU + cset w0, eq + ret +endfunc plat_is_my_cpu_primary + + /* ----------------------------------------------------- + * void plat_reset_handler (void); + * + * Platform specific configuration right after cpu is + * is our of reset. + * + * The plat_reset_handler can clobber x0 - x18, x30. + * ----------------------------------------------------- + */ +func plat_reset_handler + /* + * Note: the configurations below should be done before MMU, + * I Cache and L2are enabled. + * The reset handler is executed right after reset + * and before Caches are enabled. + */ + + /* Enable L1/L2 ECC and Parity */ + mrs x5, s3_1_c11_c0_2 /* L2 Ctrl */ + orr x5, x5, #(1 << 21) /* Enable L1/L2 cache ECC & Parity */ + msr s3_1_c11_c0_2, x5 /* L2 Ctrl */ + +#if LLC_ENABLE + /* + * Enable L2 UniqueClean evictions + * Note: this configuration assumes that LLC is configured + * in exclusive mode. + * Later on in the code this assumption will be validated + */ + mrs x5, s3_1_c15_c0_0 /* L2 Ctrl */ + orr x5, x5, #(1 << 14) /* Enable UniqueClean evictions with data */ + msr s3_1_c15_c0_0, x5 /* L2 Ctrl */ +#endif + + /* Instruction Barrier to allow msr command completion */ + isb + + ret +endfunc plat_reset_handler diff --git a/plat/marvell/armada/a8k/common/ble/ble.ld.S b/plat/marvell/armada/a8k/common/ble/ble.ld.S new file mode 100644 index 000000000..d7a05928c --- /dev/null +++ b/plat/marvell/armada/a8k/common/ble/ble.ld.S @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT) +OUTPUT_ARCH(PLATFORM_LINKER_ARCH) +ENTRY(ble_main) + +MEMORY { + RAM (rwx): ORIGIN = BLE_BASE, LENGTH = BLE_LIMIT - BLE_BASE +} + +SECTIONS +{ + . = BLE_BASE; + + ro . : { + __RO_START__ = .; + *ble_main.o(.entry*) + *(.text*) + *(.rodata*) + __RO_END_UNALIGNED__ = .; + __RO_END__ = .; + } >RAM + + /* + * Define a linker symbol to mark start of the RW memory area for this + * image. + */ + __RW_START__ = . ; + + .data . : { + __DATA_START__ = .; + *(.data*) + __DATA_END__ = .; + } >RAM + + stacks . (NOLOAD) : { + __STACKS_START__ = .; + *(tzfw_normal_stacks) + __STACKS_END__ = .; + } >RAM + + .bss : { + __BSS_START__ = .; + *(.bss*) + __BSS_END__ = .; + } >RAM + + /* + * Extend the BLE binary to the maximum size allocated for it in platform + * definition files and prevent overlapping between BLE BSS section and + * additional extensions that can follow the BLE in flash image preamble. + * This situation happens for instance when secure extension is added to + * the image preamble. + */ + .fill LOADADDR(.bss) + SIZEOF(.bss) : { + FILL(0xDEADC0DE); + . = ORIGIN(RAM) + LENGTH(RAM) - 1; + BYTE(0x00) + } >RAM + + /* + * Define a linker symbol to mark end of the RW memory area for this + * image. + */ + __RW_END__ = .; + __BLE_END__ = .; + + __BSS_SIZE__ = SIZEOF(.bss); +} diff --git a/plat/marvell/armada/a8k/common/ble/ble.mk b/plat/marvell/armada/a8k/common/ble/ble.mk new file mode 100644 index 000000000..82ac09882 --- /dev/null +++ b/plat/marvell/armada/a8k/common/ble/ble.mk @@ -0,0 +1,32 @@ +# Copyright (C) 2018 Marvell International Ltd. +# +# SPDX-License-Identifier: BSD-3-Clause +# https://spdx.org/licenses + +MV_DDR_PATH ?= drivers/marvell/mv_ddr + +MV_DDR_LIB = $(CURDIR)/$(BUILD_PLAT)/ble/mv_ddr_lib.a +LIBC_LIB = $(CURDIR)/$(BUILD_PLAT)/lib/libc.a +BLE_LIBS = $(MV_DDR_LIB) $(LIBC_LIB) +PLAT_MARVELL = plat/marvell/armada + +BLE_SOURCES += $(BLE_PATH)/ble_main.c \ + $(BLE_PATH)/ble_mem.S \ + drivers/delay_timer/delay_timer.c \ + $(PLAT_MARVELL)/common/aarch64/marvell_helpers.S \ + $(PLAT_MARVELL)/common/plat_delay_timer.c \ + $(PLAT_MARVELL)/common/marvell_console.c + +PLAT_INCLUDES += -I$(MV_DDR_PATH) \ + -I$(CURDIR)/include \ + -I$(CURDIR)/include/arch/aarch64 \ + -I$(CURDIR)/include/lib/libc \ + -I$(CURDIR)/include/lib/libc/aarch64 \ + -I$(CURDIR)/drivers/marvell + +BLE_LINKERFILE := $(BLE_PATH)/ble.ld.S + +FORCE: + +$(MV_DDR_LIB): FORCE + @+make -C $(MV_DDR_PATH) --no-print-directory PLAT_INCLUDES="$(PLAT_INCLUDES)" PLATFORM=$(PLAT) ARCH=AARCH64 OBJ_DIR=$(CURDIR)/$(BUILD_PLAT)/ble diff --git a/plat/marvell/armada/a8k/common/ble/ble_main.c b/plat/marvell/armada/a8k/common/ble/ble_main.c new file mode 100644 index 000000000..5b3acec2d --- /dev/null +++ b/plat/marvell/armada/a8k/common/ble/ble_main.c @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include + +#include +#include +#include + +#include +#include +#include + +#define BR_FLAG_SILENT 0x1 +#define SKIP_IMAGE_CODE 0xDEADB002 + +void mailbox_clean(void) +{ + uintptr_t *mailbox = (void *)PLAT_MARVELL_MAILBOX_BASE; + + memset(mailbox, 0, PLAT_MARVELL_MAILBOX_SIZE); +} + +int exec_ble_main(int bootrom_flags) +{ + int skip = 0; + uintptr_t *mailbox = (void *)PLAT_MARVELL_MAILBOX_BASE; + + /* + * In some situations, like boot from UART, bootrom will + * request to avoid printing to console. in that case don't + * initialize the console and prints will be ignored + */ + if ((bootrom_flags & BR_FLAG_SILENT) == 0) + marvell_console_boot_init(); + + NOTICE("Starting binary extension\n"); + + /* initialize time (for delay functionality) */ + plat_delay_timer_init(); + + ble_plat_setup(&skip); + + /* if there's skip image request, bootrom will load from the image + * saved on the next address of the flash + */ + if (skip) + return SKIP_IMAGE_CODE; + + /* + * Check if the mailbox magic number is stored at index MBOX_IDX_MAGIC + * and the suspend to RAM magic number at index MBOX_IDX_SUSPEND_MAGIC. + * If the above is true, this is the recovery from suspend to RAM state. + * In such case the mailbox should remain intact, since it stores the + * warm boot jump address to be used by the TF-A in BL31. + * Othervise the mailbox should be cleaned from a garbage data. + */ + if (mailbox[MBOX_IDX_MAGIC] != MVEBU_MAILBOX_MAGIC_NUM || + mailbox[MBOX_IDX_SUSPEND_MAGIC] != MVEBU_MAILBOX_SUSPEND_STATE) { + NOTICE("Cold boot\n"); + mailbox_clean(); + } else { + void (*bootrom_exit)(void) = + (void (*)(void))mailbox[MBOX_IDX_ROM_EXIT_ADDR]; + + INFO("Recovery...\n"); + /* + * If this is recovery from suspend, two things has to be done: + * 1. Define the DRAM region as executable memory for preparing + * jump to TF-A + * 2. Instead of returning control to the BootROM, invalidate + * and flush caches, and continue execution at address stored + * in the mailbox. + * This should be done until the BootROM have a native support + * for the system restore flow. + */ + marvell_ble_prepare_exit(); + bootrom_exit(); + } + + return 0; +} + +/* NOTE: don't notify this function, all code must be added to exec_ble_main + * in order to keep the end of ble_main as a fixed address. + */ +int __attribute__ ((section(".entry"))) ble_main(int bootrom_flags) +{ + volatile int ret; + + ret = exec_ble_main(bootrom_flags); + return ret; +} diff --git a/plat/marvell/armada/a8k/common/ble/ble_mem.S b/plat/marvell/armada/a8k/common/ble/ble_mem.S new file mode 100644 index 000000000..a48d5463c --- /dev/null +++ b/plat/marvell/armada/a8k/common/ble/ble_mem.S @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include +#include + +#define PTE_NON_EXEC_OFF 54 /* XN - eXecute Never bit offset - see VMSAv8-64 */ + + .globl marvell_ble_prepare_exit + +func marvell_ble_prepare_exit + /* + * Read the page table base and set the first page to be executable. + * This is required for jumping to DRAM for further execution. + */ + mrs x0, ttbr0_el3 + ldr x1, [x0] + mov x2, #1 + bic x1, x1, x2, lsl #PTE_NON_EXEC_OFF + str x1, [x0] + tlbi alle3 + dsb sy + isb + ret +endfunc marvell_ble_prepare_exit diff --git a/plat/marvell/armada/a8k/common/include/a8k_plat_def.h b/plat/marvell/armada/a8k/common/include/a8k_plat_def.h new file mode 100644 index 000000000..de8031536 --- /dev/null +++ b/plat/marvell/armada/a8k/common/include/a8k_plat_def.h @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef A8K_PLAT_DEF_H +#define A8K_PLAT_DEF_H + +#include + +#define MVEBU_PRIMARY_CPU 0x0 +#define MVEBU_AP0 0x0 + +/* APN806 revision ID */ +#define MVEBU_CSS_GWD_CTRL_IIDR2_REG (MVEBU_REGS_BASE + 0x610FCC) +#define GWD_IIDR2_REV_ID_OFFSET 12 +#define GWD_IIDR2_REV_ID_MASK 0xF +#define GWD_IIDR2_CHIP_ID_OFFSET 20 +#define GWD_IIDR2_CHIP_ID_MASK (0xFFFu << GWD_IIDR2_CHIP_ID_OFFSET) + +#define CHIP_ID_AP806 0x806 +#define CHIP_ID_AP807 0x807 + +#define COUNTER_FREQUENCY 25000000 + +#define MVEBU_REGS_BASE 0xF0000000 +#define MVEBU_REGS_BASE_MASK 0xF0000000 +#define MVEBU_REGS_BASE_AP(ap) MVEBU_REGS_BASE +#define MVEBU_AP_IO_BASE(ap) 0xF2000000 +#define MVEBU_CP_OFFSET 0x2000000 +#define MVEBU_CP_REGS_BASE(cp_index) (MVEBU_AP_IO_BASE(0) + \ + (cp_index) * MVEBU_CP_OFFSET) +#define MVEBU_RFU_BASE (MVEBU_REGS_BASE + 0x6F0000) +#define MVEBU_IO_WIN_BASE(ap_index) (MVEBU_RFU_BASE) +#define MVEBU_IO_WIN_GCR_OFFSET (0x70) +#define MVEBU_IO_WIN_MAX_WINS (7) + +/* Misc SoC configurations Base */ +#define MVEBU_MISC_SOC_BASE (MVEBU_REGS_BASE + 0x6F4300) + +#define MVEBU_CCU_BASE(ap_index) (MVEBU_REGS_BASE + 0x4000) +#define MVEBU_CCU_MAX_WINS (8) + +#define MVEBU_LLC_BASE(ap_index) (MVEBU_REGS_BASE + 0x8000) +#define MVEBU_DRAM_MAC_BASE (MVEBU_REGS_BASE + 0x20000) +#define MVEBU_DRAM_PHY_BASE (MVEBU_REGS_BASE + 0x20000) +#define MVEBU_SMMU_BASE (MVEBU_REGS_BASE + 0x100000) +#define MVEBU_CP_MPP_REGS(cp_index, n) (MVEBU_CP_REGS_BASE(cp_index) + \ + 0x440000 + ((n) << 2)) +#define MVEBU_PM_MPP_REGS(cp_index, n) (MVEBU_CP_REGS_BASE(cp_index) + \ + 0x440000 + ((n / 8) << 2)) +#define MVEBU_CP_GPIO_DATA_OUT(cp_index, n) \ + (MVEBU_CP_REGS_BASE(cp_index) + \ + 0x440100 + ((n > 31) ? 0x40 : 0x00)) +#define MVEBU_CP_GPIO_DATA_OUT_EN(cp_index, n) \ + (MVEBU_CP_REGS_BASE(cp_index) + \ + 0x440104 + ((n > 31) ? 0x40 : 0x00)) +#define MVEBU_CP_GPIO_DATA_IN(cp_index, n) (MVEBU_CP_REGS_BASE(cp_index) + \ + 0x440110 + ((n > 31) ? 0x40 : 0x00)) +#define MVEBU_AP_MPP_REGS(n) (MVEBU_RFU_BASE + 0x4000 + ((n) << 2)) +#define MVEBU_AP_GPIO_REGS (MVEBU_RFU_BASE + 0x5040) +#define MVEBU_AP_GPIO_DATA_IN (MVEBU_AP_GPIO_REGS + 0x10) +#define MVEBU_AP_I2C_BASE (MVEBU_REGS_BASE + 0x511000) +#define MVEBU_CP0_I2C_BASE (MVEBU_CP_REGS_BASE(0) + 0x701000) +#define MVEBU_AP_EXT_TSEN_BASE (MVEBU_RFU_BASE + 0x8084) + +#define MVEBU_AP_MC_TRUSTZONE_REG_LOW(ap, win) (MVEBU_REGS_BASE_AP(ap) + \ + 0x20080 + ((win) * 0x8)) +#define MVEBU_AP_MC_TRUSTZONE_REG_HIGH(ap, win) (MVEBU_REGS_BASE_AP(ap) + \ + 0x20084 + ((win) * 0x8)) + +/* MCI indirect access definitions */ +#define MCI_MAX_UNIT_ID 2 +/* SoC RFU / IHBx4 Control */ +#define MCIX4_REG_START_ADDRESS_REG(unit_id) (MVEBU_RFU_BASE + \ + 0x4218 + (unit_id * 0x20)) +#define MCI_REMAP_OFF_SHIFT 8 + +#define MVEBU_MCI_REG_BASE_REMAP(index) (0xFD000000 + \ + ((index) * 0x1000000)) + +#define MVEBU_PCIE_X4_MAC_BASE(x) (MVEBU_CP_REGS_BASE(x) + 0x600000) +#define MVEBU_COMPHY_BASE(x) (MVEBU_CP_REGS_BASE(x) + 0x441000) +#define MVEBU_HPIPE_BASE(x) (MVEBU_CP_REGS_BASE(x) + 0x120000) +#define MVEBU_CP_DFX_OFFSET (0x400200) + +/***************************************************************************** + * MVEBU memory map related constants + ***************************************************************************** + */ +/* Aggregate of all devices in the first GB */ +#define DEVICE0_BASE MVEBU_REGS_BASE +#define DEVICE0_SIZE 0x10000000 + +/***************************************************************************** + * GIC-400 & interrupt handling related constants + ***************************************************************************** + */ +/* Base MVEBU compatible GIC memory map */ +#define MVEBU_GICD_BASE 0x210000 +#define MVEBU_GICC_BASE 0x220000 + + +/***************************************************************************** + * AXI Configuration + ***************************************************************************** + */ +#define MVEBU_AXI_ATTR_ARCACHE_OFFSET 4 +#define MVEBU_AXI_ATTR_ARCACHE_MASK (0xF << \ + MVEBU_AXI_ATTR_ARCACHE_OFFSET) +#define MVEBU_AXI_ATTR_ARDOMAIN_OFFSET 12 +#define MVEBU_AXI_ATTR_ARDOMAIN_MASK (0x3 << \ + MVEBU_AXI_ATTR_ARDOMAIN_OFFSET) +#define MVEBU_AXI_ATTR_AWCACHE_OFFSET 20 +#define MVEBU_AXI_ATTR_AWCACHE_MASK (0xF << \ + MVEBU_AXI_ATTR_AWCACHE_OFFSET) +#define MVEBU_AXI_ATTR_AWDOMAIN_OFFSET 28 +#define MVEBU_AXI_ATTR_AWDOMAIN_MASK (0x3 << \ + MVEBU_AXI_ATTR_AWDOMAIN_OFFSET) + +/* SATA MBUS to AXI configuration */ +#define MVEBU_SATA_M2A_AXI_ARCACHE_OFFSET 1 +#define MVEBU_SATA_M2A_AXI_ARCACHE_MASK (0xF << \ + MVEBU_SATA_M2A_AXI_ARCACHE_OFFSET) +#define MVEBU_SATA_M2A_AXI_AWCACHE_OFFSET 5 +#define MVEBU_SATA_M2A_AXI_AWCACHE_MASK (0xF << \ + MVEBU_SATA_M2A_AXI_AWCACHE_OFFSET) + +/* ARM cache attributes */ +#define CACHE_ATTR_BUFFERABLE 0x1 +#define CACHE_ATTR_CACHEABLE 0x2 +#define CACHE_ATTR_READ_ALLOC 0x4 +#define CACHE_ATTR_WRITE_ALLOC 0x8 +/* Domain */ +#define DOMAIN_NON_SHAREABLE 0x0 +#define DOMAIN_INNER_SHAREABLE 0x1 +#define DOMAIN_OUTER_SHAREABLE 0x2 +#define DOMAIN_SYSTEM_SHAREABLE 0x3 + +/************************************************************************ + * Required platform porting definitions common to all + * Management Compute SubSystems (MSS) + ************************************************************************ + */ +/* + * Load address of SCP_BL2 + * SCP_BL2 is loaded to the same place as BL31. + * Once SCP_BL2 is transferred to the SCP, + * it is discarded and BL31 is loaded over the top. + */ +#ifdef SCP_IMAGE +#define SCP_BL2_BASE BL31_BASE +#define SCP_BL2_SIZE BL31_LIMIT +#endif + +#ifndef __ASSEMBLER__ +enum ap806_sar_target_dev { + SAR_PIDI_MCIX2 = 0x0, + SAR_MCIX4 = 0x1, + SAR_SPI = 0x2, + SAR_SD = 0x3, + SAR_PIDI_MCIX2_BD = 0x4, /* BootRom disabled */ + SAR_MCIX4_DB = 0x5, /* BootRom disabled */ + SAR_SPI_DB = 0x6, /* BootRom disabled */ + SAR_EMMC = 0x7 +}; + +enum io_win_target_ids { + MCI_0_TID = 0x0, + MCI_1_TID = 0x1, + MCI_2_TID = 0x2, + PIDI_TID = 0x3, + SPI_TID = 0x4, + STM_TID = 0x5, + BOOTROM_TID = 0x6, + IO_WIN_MAX_TID +}; + +enum ccu_target_ids { + IO_0_TID = 0x00, + DRAM_0_TID = 0x03, + IO_1_TID = 0x0F, + CFG_REG_TID = 0x10, + RAR_TID = 0x20, + SRAM_TID = 0x40, + DRAM_1_TID = 0xC0, + CCU_MAX_TID, + INVALID_TID = 0xFF +}; +#endif /* __ASSEMBLER__ */ + +#endif /* A8K_PLAT_DEF_H */ diff --git a/plat/marvell/armada/a8k/common/include/ddr_info.h b/plat/marvell/armada/a8k/common/include/ddr_info.h new file mode 100644 index 000000000..e19036a26 --- /dev/null +++ b/plat/marvell/armada/a8k/common/include/ddr_info.h @@ -0,0 +1,9 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#define DRAM_MAX_IFACE 1 +#define DRAM_CH0_MMAP_LOW_OFFSET 0x20200 diff --git a/plat/marvell/armada/a8k/common/include/mentor_i2c_plat.h b/plat/marvell/armada/a8k/common/include/mentor_i2c_plat.h new file mode 100644 index 000000000..e03c448a6 --- /dev/null +++ b/plat/marvell/armada/a8k/common/include/mentor_i2c_plat.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ +/* This driver provides I2C support for Marvell A8K and compatible SoCs */ + +#ifndef MENTOR_I2C_PLAT_H +#define MENTOR_I2C_PLAT_H + +#define CONFIG_SYS_TCLK 250000000 +#define CONFIG_SYS_I2C_SPEED 100000 +#define CONFIG_SYS_I2C_SLAVE 0x0 + +#define I2C_CAN_UNSTUCK + +struct mentor_i2c_regs { + uint32_t slave_address; + uint32_t data; + uint32_t control; + union { + uint32_t status; /* when reading */ + uint32_t baudrate; /* when writing */ + }; + uint32_t xtnd_slave_addr; + uint32_t reserved[2]; + uint32_t soft_reset; + uint8_t reserved2[0xa0 - 0x20]; + uint32_t unstuck; +}; + +#endif /* MENTOR_I2C_PLAT_H */ diff --git a/plat/marvell/armada/a8k/common/include/plat_macros.S b/plat/marvell/armada/a8k/common/include/plat_macros.S new file mode 100644 index 000000000..8faccf00b --- /dev/null +++ b/plat/marvell/armada/a8k/common/include/plat_macros.S @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef PLAT_MACROS_S +#define PLAT_MACROS_S + +#include + +/* + * Required platform porting macros + * (Provided by included headers) + */ +.macro plat_crash_print_regs +.endm + +#endif /* PLAT_MACROS_S */ diff --git a/plat/marvell/armada/a8k/common/include/platform_def.h b/plat/marvell/armada/a8k/common/include/platform_def.h new file mode 100644 index 000000000..ec1c9036c --- /dev/null +++ b/plat/marvell/armada/a8k/common/include/platform_def.h @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +#ifndef __ASSEMBLER__ +#include +#endif /* __ASSEMBLER__ */ + +#include +#include + +#include +#include + +/* + * Most platform porting definitions provided by included headers + */ + +/* + * DRAM Memory layout: + * +-----------------------+ + * : : + * : Linux : + * 0x04X00000-->+-----------------------+ + * | BL3-3(u-boot) |>>}>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + * |-----------------------| } | + * | BL3-[0,1, 2] | }---------------------------------> | + * |-----------------------| } || | + * | BL2 | }->FIP (loaded by || | + * |-----------------------| } BootROM to DRAM) || | + * | FIP_TOC | } || | + * 0x04120000-->|-----------------------| || | + * | BL1 (RO) | || | + * 0x04100000-->+-----------------------+ || | + * : : || | + * : Trusted SRAM section : \/ | + * 0x04040000-->+-----------------------+ Replaced by BL2 +----------------+ | + * | BL1 (RW) | <<<<<<<<<<<<<<<< | BL3-1 NOBITS | | + * 0x04037000-->|-----------------------| <<<<<<<<<<<<<<<< |----------------| | + * | | <<<<<<<<<<<<<<<< | BL3-1 PROGBITS | | + * 0x04023000-->|-----------------------| +----------------+ | + * | BL2 | | + * |-----------------------| | + * | | | + * 0x04001000-->|-----------------------| | + * | Shared | | + * 0x04000000-->+-----------------------+ | + * : : | + * : Linux : | + * : : | + * |-----------------------| | + * | | U-Boot(BL3-3) Loaded by BL2 | + * | U-Boot | <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + * 0x00000000-->+-----------------------+ + * + * Trusted SRAM section 0x4000000..0x4200000: + * ---------------------------------------- + * SRAM_BASE = 0x4001000 + * BL2_BASE = 0x4006000 + * BL2_LIMIT = BL31_BASE + * BL31_BASE = 0x4023000 = (64MB + 256KB - 0x1D000) + * BL31_PROGBITS_LIMIT = BL1_RW_BASE + * BL1_RW_BASE = 0x4037000 = (64MB + 256KB - 0x9000) + * BL1_RW_LIMIT = BL31_LIMIT = 0x4040000 + * + * + * PLAT_MARVELL_FIP_BASE = 0x4120000 + */ + +#define PLAT_MARVELL_SRAM_BASE 0xFFE1C048 +#define PLAT_MARVELL_SRAM_END 0xFFE78000 + +#define PLAT_MARVELL_ATF_BASE 0x4000000 +#define PLAT_MARVELL_ATF_LOAD_ADDR (PLAT_MARVELL_ATF_BASE + \ + 0x100000) + +#define PLAT_MARVELL_FIP_BASE (PLAT_MARVELL_ATF_LOAD_ADDR + \ + 0x20000) +#define PLAT_MARVELL_FIP_MAX_SIZE 0x4000000 + +#define PLAT_MARVELL_NORTHB_COUNT 1 + +#define PLAT_MARVELL_CLUSTER_COUNT U(2) +#define PLAT_MARVELL_CLUSTER_CORE_COUNT U(2) + +#define PLAT_MARVELL_CORE_COUNT (PLAT_MARVELL_CLUSTER_COUNT * \ + PLAT_MARVELL_CLUSTER_CORE_COUNT) + +/* DRAM[2MB..66MB] is used as Trusted ROM */ +#define PLAT_MARVELL_TRUSTED_ROM_BASE PLAT_MARVELL_ATF_LOAD_ADDR +/* 64 MB TODO: reduce this to minimum needed according to fip image size */ +#define PLAT_MARVELL_TRUSTED_ROM_SIZE 0x04000000 +/* Reserve 16M for SCP (Secure PayLoad) Trusted DRAM */ +#define PLAT_MARVELL_TRUSTED_DRAM_BASE 0x04400000 +#define PLAT_MARVELL_TRUSTED_DRAM_SIZE 0x01000000 /* 16 MB */ + +/* + * PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size + * plus a little space for growth. + */ +#define PLAT_MARVELL_MAX_BL1_RW_SIZE 0xA000 + +/* + * PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a + * little space for growth. + */ +#define PLAT_MARVELL_MAX_BL2_SIZE 0xF000 + +/* + * PLAT_ARM_MAX_BL31_SIZE is calculated using the current BL31 debug size plus a + * little space for growth. + */ +#define PLAT_MARVEL_MAX_BL31_SIZE 0x5D000 + +#define PLAT_MARVELL_CPU_ENTRY_ADDR BL1_RO_BASE + +/* GIC related definitions */ +#define PLAT_MARVELL_GICD_BASE (MVEBU_REGS_BASE + MVEBU_GICD_BASE) +#define PLAT_MARVELL_GICC_BASE (MVEBU_REGS_BASE + MVEBU_GICC_BASE) + +#define PLAT_MARVELL_G0_IRQ_PROPS(grp) \ + INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(MARVELL_IRQ_PIC0, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL) + +#define PLAT_MARVELL_G1S_IRQ_PROPS(grp) \ + INTR_PROP_DESC(MARVELL_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, \ + grp, GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL) + +#define PLAT_MARVELL_SHARED_RAM_CACHED 1 + +/* + * Load address of BL3-3 for this platform port + */ +#define PLAT_MARVELL_NS_IMAGE_OFFSET 0x0 + +/* System Reference Clock*/ +#define PLAT_REF_CLK_IN_HZ COUNTER_FREQUENCY + +/* + * PL011 related constants + */ +#define PLAT_MARVELL_BOOT_UART_BASE (MVEBU_REGS_BASE + 0x512000) +#define PLAT_MARVELL_BOOT_UART_CLK_IN_HZ 200000000 + +#define PLAT_MARVELL_CRASH_UART_BASE PLAT_MARVELL_BOOT_UART_BASE +#define PLAT_MARVELL_CRASH_UART_CLK_IN_HZ PLAT_MARVELL_BOOT_UART_CLK_IN_HZ + +#define PLAT_MARVELL_BL31_RUN_UART_BASE PLAT_MARVELL_BOOT_UART_BASE +#define PLAT_MARVELL_BL31_RUN_UART_CLK_IN_HZ PLAT_MARVELL_BOOT_UART_CLK_IN_HZ + +/* Recovery image enable */ +#define PLAT_RECOVERY_IMAGE_ENABLE 0 + +/* Required platform porting definitions */ +#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL1 + +/* System timer related constants */ +#define PLAT_MARVELL_NSTIMER_FRAME_ID 1 + +/* Mailbox base address (note the lower memory space + * is reserved for BLE data) + */ +#define PLAT_MARVELL_MAILBOX_BASE (MARVELL_TRUSTED_SRAM_BASE \ + + 0x400) +#define PLAT_MARVELL_MAILBOX_SIZE 0x100 +#define PLAT_MARVELL_MAILBOX_MAGIC_NUM 0x6D72766C /* mrvl */ + +/* Securities */ +#define IRQ_SEC_OS_TICK_INT MARVELL_IRQ_SEC_PHY_TIMER + +#define TRUSTED_DRAM_BASE PLAT_MARVELL_TRUSTED_DRAM_BASE +#define TRUSTED_DRAM_SIZE PLAT_MARVELL_TRUSTED_DRAM_SIZE + +#ifdef BL32 +#define BL32_BASE TRUSTED_DRAM_BASE +#define BL32_LIMIT TRUSTED_DRAM_SIZE +#endif + +#define MVEBU_PMU_IRQ_WA + +#endif /* PLATFORM_DEF_H */ diff --git a/plat/marvell/armada/a8k/common/mss/mss_a8k.mk b/plat/marvell/armada/a8k/common/mss/mss_a8k.mk new file mode 100644 index 000000000..d8d492193 --- /dev/null +++ b/plat/marvell/armada/a8k/common/mss/mss_a8k.mk @@ -0,0 +1,21 @@ +# +# Copyright (C) 2018 Marvell International Ltd. +# +# SPDX-License-Identifier: BSD-3-Clause +# https://spdx.org/licenses +# + +PLAT_MARVELL := plat/marvell/armada +A8K_MSS_SOURCE := $(PLAT_MARVELL)/a8k/common/mss + +BL2_SOURCES += $(A8K_MSS_SOURCE)/mss_bl2_setup.c \ + $(MARVELL_MOCHI_DRV) + +BL31_SOURCES += $(A8K_MSS_SOURCE)/mss_pm_ipc.c + +PLAT_INCLUDES += -I$(A8K_MSS_SOURCE) + +ifneq (${SCP_BL2},) +# This define is used to inidcate the SCP image is present +$(eval $(call add_define,SCP_IMAGE)) +endif diff --git a/plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c b/plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c new file mode 100644 index 000000000..09b8446fa --- /dev/null +++ b/plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include /* timer functionality */ + +#include "mss_scp_bootloader.h" + +/* IO windows configuration */ +#define IOW_GCR_OFFSET (0x70) + +/* MSS windows configuration */ +#define MSS_AEBR(base) (base + 0x160) +#define MSS_AIBR(base) (base + 0x164) +#define MSS_AEBR_MASK 0xFFF +#define MSS_AIBR_MASK 0xFFF + +#define MSS_EXTERNAL_SPACE 0x50000000 +#define MSS_EXTERNAL_ACCESS_BIT 28 +#define MSS_EXTERNAL_ADDR_MASK 0xfffffff +#define MSS_INTERNAL_ACCESS_BIT 28 + +struct addr_map_win ccu_mem_map[] = { + {MVEBU_CP_REGS_BASE(0), 0x4000000, IO_0_TID} +}; + +/* Since the scp_bl2 image can contain firmware for cp1 and cp0 coprocessors, + * the access to cp0 and cp1 need to be provided. More precisely it is + * required to: + * - get the information about device id which is stored in CP0 registers + * (to distinguish between cases where we have cp0 and cp1 or standalone cp0) + * - get the access to cp which is needed for loading fw for cp0/cp1 + * coprocessors + * This function configures ccu windows accordingly. + * + * Note: there is no need to restore previous ccu configuration, since in next + * phase (BL31) the init_ccu will be called (via apn806_init/ + * bl31_plat_arch_setu) and therefore the ccu configuration will be overwritten. + */ +static int bl2_plat_mmap_init(void) +{ + int cfg_num, win_id, cfg_idx; + + cfg_num = ARRAY_SIZE(ccu_mem_map); + + /* CCU window-0 should not be counted - it's already used */ + if (cfg_num > (MVEBU_CCU_MAX_WINS - 1)) { + ERROR("BL2: %s: trying to open too many windows\n", __func__); + return -1; + } + + /* Enable required CCU windows + * Do not touch CCU window 0, + * it's used for the internal registers access + */ + for (cfg_idx = 0, win_id = 1; cfg_idx < cfg_num; cfg_idx++, win_id++) { + /* Enable required CCU windows */ + ccu_win_check(&ccu_mem_map[cfg_idx]); + ccu_enable_win(MVEBU_AP0, &ccu_mem_map[cfg_idx], win_id); + } + + /* Set the default target id to PIDI */ + mmio_write_32(MVEBU_IO_WIN_BASE(MVEBU_AP0) + IOW_GCR_OFFSET, PIDI_TID); + + /* Open AMB bridge required for MG access */ + cp110_amb_init(MVEBU_CP_REGS_BASE(0)); + + if (CP_COUNT == 2) + cp110_amb_init(MVEBU_CP_REGS_BASE(1)); + + return 0; +} + +/***************************************************************************** + * Transfer SCP_BL2 from Trusted RAM using the SCP Download protocol. + * Return 0 on success, -1 otherwise. + ***************************************************************************** + */ +int bl2_plat_handle_scp_bl2(image_info_t *scp_bl2_image_info) +{ + int ret; + + INFO("BL2: Initiating SCP_BL2 transfer to SCP\n"); + + /* initialize time (for delay functionality) */ + plat_delay_timer_init(); + + ret = bl2_plat_mmap_init(); + if (ret != 0) + return ret; + + ret = scp_bootloader_transfer((void *)scp_bl2_image_info->image_base, + scp_bl2_image_info->image_size); + + if (ret == 0) + INFO("BL2: SCP_BL2 transferred to SCP\n"); + else + ERROR("BL2: SCP_BL2 transfer failure\n"); + + return ret; +} + +uintptr_t bl2_plat_get_cp_mss_regs(int ap_idx, int cp_idx) +{ + return MVEBU_CP_REGS_BASE(cp_idx) + 0x280000; +} + +uintptr_t bl2_plat_get_ap_mss_regs(int ap_idx) +{ + return MVEBU_REGS_BASE + 0x580000; +} + +uint32_t bl2_plat_get_cp_count(int ap_idx) +{ + uint32_t revision = cp110_device_id_get(MVEBU_CP_REGS_BASE(0)); + /* A8040: two CPs. + * A7040: one CP. + */ + if (revision == MVEBU_80X0_DEV_ID || + revision == MVEBU_80X0_CP115_DEV_ID) + return 2; + else + return 1; +} + +uint32_t bl2_plat_get_ap_count(void) +{ + /* A8040 and A7040 have only one AP */ + return 1; +} + +void bl2_plat_configure_mss_windows(uintptr_t mss_regs) +{ + /* set AXI External and Internal Address Bus extension */ + mmio_write_32(MSS_AEBR(mss_regs), + ((0x0 >> MSS_EXTERNAL_ACCESS_BIT) & MSS_AEBR_MASK)); + mmio_write_32(MSS_AIBR(mss_regs), + ((mss_regs >> MSS_INTERNAL_ACCESS_BIT) & MSS_AIBR_MASK)); +} diff --git a/plat/marvell/armada/a8k/common/mss/mss_pm_ipc.c b/plat/marvell/armada/a8k/common/mss/mss_pm_ipc.c new file mode 100644 index 000000000..a0705832f --- /dev/null +++ b/plat/marvell/armada/a8k/common/mss/mss_pm_ipc.c @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include +#include +#include + +#include + +/* + * SISR is 32 bit interrupt register representing 32 interrupts + * + * +======+=============+=============+ + * + Bits + 31 + 30 - 00 + + * +======+=============+=============+ + * + Desc + MSS Msg Int + Reserved + + * +======+=============+=============+ + */ +#define MSS_SISR (MVEBU_REGS_BASE + 0x5800D0) +#define MSS_SISTR (MVEBU_REGS_BASE + 0x5800D8) + +#define MSS_MSG_INT_MASK (0x80000000) +#define MSS_TIMER_BASE (MVEBU_REGS_BASE_MASK + 0x580110) +#define MSS_TRIGGER_TIMEOUT (2000) + +/***************************************************************************** + * mss_pm_ipc_msg_send + * + * DESCRIPTION: create and transmit IPC message + ***************************************************************************** + */ +int mss_pm_ipc_msg_send(unsigned int channel_id, unsigned int msg_id, + const psci_power_state_t *target_state) +{ + /* Transmit IPC message */ +#ifndef DISABLE_CLUSTER_LEVEL + mv_pm_ipc_msg_tx(channel_id, msg_id, + (unsigned int)target_state->pwr_domain_state[ + MPIDR_AFFLVL1]); +#else + mv_pm_ipc_msg_tx(channel_id, msg_id, 0); +#endif + + return 0; +} + +/***************************************************************************** + * mss_pm_ipc_msg_trigger + * + * DESCRIPTION: Trigger IPC message interrupt to MSS + ***************************************************************************** + */ +int mss_pm_ipc_msg_trigger(void) +{ + unsigned int timeout; + unsigned int t_end; + unsigned int t_start = mmio_read_32(MSS_TIMER_BASE); + + mmio_write_32(MSS_SISR, MSS_MSG_INT_MASK); + + do { + /* wait while SCP process incoming interrupt */ + if (mmio_read_32(MSS_SISTR) != MSS_MSG_INT_MASK) + break; + + /* check timeout */ + t_end = mmio_read_32(MSS_TIMER_BASE); + + timeout = ((t_start > t_end) ? + (t_start - t_end) : (t_end - t_start)); + if (timeout > MSS_TRIGGER_TIMEOUT) { + ERROR("PM MSG Trigger Timeout\n"); + break; + } + + } while (1); + + return 0; +} diff --git a/plat/marvell/armada/a8k/common/mss/mss_pm_ipc.h b/plat/marvell/armada/a8k/common/mss/mss_pm_ipc.h new file mode 100644 index 000000000..1dfa9fa03 --- /dev/null +++ b/plat/marvell/armada/a8k/common/mss/mss_pm_ipc.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef MSS_PM_IPC_H +#define MSS_PM_IPC_H + +#include + +/* Currently MSS does not support Cluster level Power Down */ +#define DISABLE_CLUSTER_LEVEL + + +/***************************************************************************** + * mss_pm_ipc_msg_send + * + * DESCRIPTION: create and transmit IPC message + ***************************************************************************** + */ +int mss_pm_ipc_msg_send(unsigned int channel_id, unsigned int msg_id, + const psci_power_state_t *target_state); + +/***************************************************************************** + * mss_pm_ipc_msg_trigger + * + * DESCRIPTION: Trigger IPC message interrupt to MSS + ***************************************************************************** + */ +int mss_pm_ipc_msg_trigger(void); + + +#endif /* MSS_PM_IPC_H */ diff --git a/plat/marvell/armada/a8k/common/plat_bl1_setup.c b/plat/marvell/armada/a8k/common/plat_bl1_setup.c new file mode 100644 index 000000000..f9521c871 --- /dev/null +++ b/plat/marvell/armada/a8k/common/plat_bl1_setup.c @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include + +void marvell_bl1_setup_mpps(void) +{ + /* Enable UART MPPs. + ** In a normal system, this is done by Bootrom. + */ + mmio_write_32(MVEBU_AP_MPP_REGS(1), 0x3000); + mmio_write_32(MVEBU_AP_MPP_REGS(2), 0x3000); +} diff --git a/plat/marvell/armada/a8k/common/plat_bl31_setup.c b/plat/marvell/armada/a8k/common/plat_bl31_setup.c new file mode 100644 index 000000000..98b3966ae --- /dev/null +++ b/plat/marvell/armada/a8k/common/plat_bl31_setup.c @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/* In Armada-8k family AP806/AP807, CP0 connected to PIDI + * and CP1 connected to IHB via MCI #0 + */ +#define MVEBU_MCI0 0 + +static _Bool pm_fw_running; + +/* Set a weak stub for platforms that don't need to configure GPIO */ +#pragma weak marvell_gpio_config +int marvell_gpio_config(void) +{ + return 0; +} + +static void marvell_bl31_mpp_init(int cp) +{ + uint32_t reg; + + /* need to do for CP#0 only */ + if (cp) + return; + + + /* + * Enable CP0 I2C MPPs (MPP: 37-38) + * U-Boot rely on proper MPP settings for I2C EEPROM usage + * (only for CP0) + */ + reg = mmio_read_32(MVEBU_CP_MPP_REGS(0, 4)); + mmio_write_32(MVEBU_CP_MPP_REGS(0, 4), reg | 0x2200000); +} + +void marvell_bl31_mss_init(void) +{ + struct mss_pm_ctrl_block *mss_pm_crtl = + (struct mss_pm_ctrl_block *)MSS_SRAM_PM_CONTROL_BASE; + + /* Check that the image was loaded successfully */ + if (mss_pm_crtl->handshake != HOST_ACKNOWLEDGMENT) { + NOTICE("MSS PM is not supported in this build\n"); + return; + } + + /* If we got here it means that the PM firmware is running */ + pm_fw_running = 1; + + INFO("MSS IPC init\n"); + + if (mss_pm_crtl->ipc_state == IPC_INITIALIZED) + mv_pm_ipc_init(mss_pm_crtl->ipc_base_address | MVEBU_REGS_BASE); +} + +_Bool is_pm_fw_running(void) +{ + return pm_fw_running; +} + +/* For TrusTzone we treat the "target" field of addr_map_win + * struct as attribute + */ +static const struct addr_map_win tz_map[] = { + {PLAT_MARVELL_ATF_BASE, 0x200000, TZ_PERM_ABORT} +}; + +/* Configure MC TrustZone regions */ +static void marvell_bl31_security_setup(void) +{ + int tz_nr, win_id; + + tz_nr = ARRAY_SIZE(tz_map); + + for (win_id = 0; win_id < tz_nr; win_id++) + tz_enable_win(MVEBU_AP0, tz_map, win_id); +} + +/* This function overruns the same function in marvell_bl31_setup.c */ +void bl31_plat_arch_setup(void) +{ + int cp; + uintptr_t *mailbox = (void *)PLAT_MARVELL_MAILBOX_BASE; + + /* initialize the timer for mdelay/udelay functionality */ + plat_delay_timer_init(); + + /* configure apn806 */ + ap_init(); + + /* In marvell_bl31_plat_arch_setup, el3 mmu is configured. + * el3 mmu configuration MUST be called after apn806_init, if not, + * this will cause an hang in init_io_win + * (after setting the IO windows GCR values). + */ + if (mailbox[MBOX_IDX_MAGIC] != MVEBU_MAILBOX_MAGIC_NUM || + mailbox[MBOX_IDX_SUSPEND_MAGIC] != MVEBU_MAILBOX_SUSPEND_STATE) + marvell_bl31_plat_arch_setup(); + + for (cp = 0; cp < CP_COUNT; cp++) { + /* configure cp110 for CP0*/ + if (cp == 1) + mci_initialize(MVEBU_MCI0); + + /* initialize MCI & CP1 */ + cp110_init(MVEBU_CP_REGS_BASE(cp), + STREAM_ID_BASE + (cp * MAX_STREAM_ID_PER_CP)); + + /* Should be called only after setting IOB windows */ + marvell_bl31_mpp_init(cp); + } + + /* initialize IPC between MSS and ATF */ + if (mailbox[MBOX_IDX_MAGIC] != MVEBU_MAILBOX_MAGIC_NUM || + mailbox[MBOX_IDX_SUSPEND_MAGIC] != MVEBU_MAILBOX_SUSPEND_STATE) + marvell_bl31_mss_init(); + + /* Configure GPIO */ + marvell_gpio_config(); + + marvell_bl31_security_setup(); +} diff --git a/plat/marvell/armada/a8k/common/plat_ble_setup.c b/plat/marvell/armada/a8k/common/plat_ble_setup.c new file mode 100644 index 000000000..7f9e24278 --- /dev/null +++ b/plat/marvell/armada/a8k/common/plat_ble_setup.c @@ -0,0 +1,735 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* Register for skip image use */ +#define SCRATCH_PAD_REG2 0xF06F00A8 +#define SCRATCH_PAD_SKIP_VAL 0x01 +#define NUM_OF_GPIO_PER_REG 32 + +#define MMAP_SAVE_AND_CONFIG 0 +#define MMAP_RESTORE_SAVED 1 + +/* SAR clock settings */ +#define MVEBU_AP_GEN_MGMT_BASE (MVEBU_RFU_BASE + 0x8000) +#define MVEBU_AP_SAR_REG_BASE(r) (MVEBU_AP_GEN_MGMT_BASE + 0x200 +\ + ((r) << 2)) + +#define SAR_CLOCK_FREQ_MODE_OFFSET (0) +#define SAR_CLOCK_FREQ_MODE_MASK (0x1f << SAR_CLOCK_FREQ_MODE_OFFSET) +#define SAR_PIDI_LOW_SPEED_OFFSET (20) +#define SAR_PIDI_LOW_SPEED_MASK (1 << SAR_PIDI_LOW_SPEED_OFFSET) +#define SAR_PIDI_LOW_SPEED_SHIFT (15) +#define SAR_PIDI_LOW_SPEED_SET (1 << SAR_PIDI_LOW_SPEED_SHIFT) + +#define FREQ_MODE_AP_SAR_REG_NUM (0) +#define SAR_CLOCK_FREQ_MODE(v) (((v) & SAR_CLOCK_FREQ_MODE_MASK) >> \ + SAR_CLOCK_FREQ_MODE_OFFSET) + +#define AVS_I2C_EEPROM_ADDR 0x57 /* EEPROM */ +#define AVS_EN_CTRL_REG (MVEBU_AP_GEN_MGMT_BASE + 0x130) +#define AVS_ENABLE_OFFSET (0) +#define AVS_SOFT_RESET_OFFSET (2) +#define AVS_TARGET_DELTA_OFFSET (21) + +#ifndef MVEBU_SOC_AP807 + /* AP806 SVC bits */ + #define AVS_LOW_VDD_LIMIT_OFFSET (4) + #define AVS_HIGH_VDD_LIMIT_OFFSET (12) + #define AVS_VDD_LOW_LIMIT_MASK (0xFF << AVS_LOW_VDD_LIMIT_OFFSET) + #define AVS_VDD_HIGH_LIMIT_MASK (0xFF << AVS_HIGH_VDD_LIMIT_OFFSET) +#else + /* AP807 SVC bits */ + #define AVS_LOW_VDD_LIMIT_OFFSET (3) + #define AVS_HIGH_VDD_LIMIT_OFFSET (13) + #define AVS_VDD_LOW_LIMIT_MASK (0x3FF << AVS_LOW_VDD_LIMIT_OFFSET) + #define AVS_VDD_HIGH_LIMIT_MASK (0x3FF << AVS_HIGH_VDD_LIMIT_OFFSET) +#endif + +/* VDD limit is 0.9V for A70x0 @ CPU frequency < 1600MHz */ +#define AVS_A7K_LOW_CLK_VALUE ((0x80 << AVS_TARGET_DELTA_OFFSET) | \ + (0x1A << AVS_HIGH_VDD_LIMIT_OFFSET) | \ + (0x1A << AVS_LOW_VDD_LIMIT_OFFSET) | \ + (0x1 << AVS_SOFT_RESET_OFFSET) | \ + (0x1 << AVS_ENABLE_OFFSET)) +/* VDD limit is 1.0V for all A80x0 devices */ +#define AVS_A8K_CLK_VALUE ((0x80 << AVS_TARGET_DELTA_OFFSET) | \ + (0x24 << AVS_HIGH_VDD_LIMIT_OFFSET) | \ + (0x24 << AVS_LOW_VDD_LIMIT_OFFSET) | \ + (0x1 << AVS_SOFT_RESET_OFFSET) | \ + (0x1 << AVS_ENABLE_OFFSET)) +/* VDD limit is 0.82V for all A3900 devices + * AVS offsets are not the same as in A70x0 + */ +#define AVS_A3900_CLK_VALUE ((0x80u << 24) | \ + (0x2c2 << 13) | \ + (0x2c2 << 3) | \ + (0x1 << AVS_SOFT_RESET_OFFSET) | \ + (0x1 << AVS_ENABLE_OFFSET)) +/* VDD is 0.88V for 2GHz clock */ +#define AVS_A3900_HIGH_CLK_VALUE ((0x80u << 24) | \ + (0x2f5 << 13) | \ + (0x2f5 << 3) | \ + (0x1 << AVS_SOFT_RESET_OFFSET) | \ + (0x1 << AVS_ENABLE_OFFSET)) + +#define MVEBU_AP_EFUSE_SRV_CTRL_REG (MVEBU_AP_GEN_MGMT_BASE + 0x8) +#define EFUSE_SRV_CTRL_LD_SELECT_OFFS 6 +#define EFUSE_SRV_CTRL_LD_SEL_USER_MASK (1 << EFUSE_SRV_CTRL_LD_SELECT_OFFS) + + +/* + * - Identification information in the LD-0 eFuse: + * DRO: LD0[74:65] - Not used by the SW + * Revision: LD0[78:75] - Not used by the SW + * Bin: LD0[80:79] - Not used by the SW + * SW Revision: LD0[115:113] + * Cluster 1 PWR: LD0[193] - if set to 1, power down CPU Cluster-1 + * resulting in 2 CPUs active only (7020) + */ +#define MVEBU_AP_LD_EFUSE_BASE (MVEBU_AP_GEN_MGMT_BASE + 0xF00) +/* Bits [94:63] - 32 data bits total */ +#define MVEBU_AP_LD0_94_63_EFUSE_OFFS (MVEBU_AP_LD_EFUSE_BASE + 0x8) +/* Bits [125:95] - 31 data bits total, 32nd bit is parity for bits [125:63] */ +#define MVEBU_AP_LD0_125_95_EFUSE_OFFS (MVEBU_AP_LD_EFUSE_BASE + 0xC) +/* Bits [220:189] - 32 data bits total */ +#define MVEBU_AP_LD0_220_189_EFUSE_OFFS (MVEBU_AP_LD_EFUSE_BASE + 0x18) +/* Offsets for the above 2 fields combined into single 64-bit value [125:63] */ +#define EFUSE_AP_LD0_DRO_OFFS 2 /* LD0[74:65] */ +#define EFUSE_AP_LD0_DRO_MASK 0x3FF +#define EFUSE_AP_LD0_REVID_OFFS 12 /* LD0[78:75] */ +#define EFUSE_AP_LD0_REVID_MASK 0xF +#define EFUSE_AP_LD0_BIN_OFFS 16 /* LD0[80:79] */ +#define EFUSE_AP_LD0_BIN_MASK 0x3 +#define EFUSE_AP_LD0_SWREV_OFFS 50 /* LD0[115:113] */ +#define EFUSE_AP_LD0_SWREV_MASK 0x7 + +#ifndef MVEBU_SOC_AP807 + /* AP806 AVS work points in the LD0 eFuse + * SVC1 work point: LD0[88:81] + * SVC2 work point: LD0[96:89] + * SVC3 work point: LD0[104:97] + * SVC4 work point: LD0[112:105] + */ + #define EFUSE_AP_LD0_SVC1_OFFS 18 /* LD0[88:81] */ + #define EFUSE_AP_LD0_SVC2_OFFS 26 /* LD0[96:89] */ + #define EFUSE_AP_LD0_SVC3_OFFS 34 /* LD0[104:97] */ + #define EFUSE_AP_LD0_WP_MASK 0xFF +#else + /* AP807 AVS work points in the LD0 eFuse + * SVC1 work point: LD0[91:81] + * SVC2 work point: LD0[102:92] + * SVC3 work point: LD0[113:103] + */ + #define EFUSE_AP_LD0_SVC1_OFFS 17 /* LD0[91:81] */ + #define EFUSE_AP_LD0_SVC2_OFFS 28 /* LD0[102:92] */ + #define EFUSE_AP_LD0_SVC3_OFFS 39 /* LD0[113:103] */ + #define EFUSE_AP_LD0_WP_MASK 0x3FF +#endif + +#define EFUSE_AP_LD0_SVC4_OFFS 42 /* LD0[112:105] */ + +#define EFUSE_AP_LD0_CLUSTER_DOWN_OFFS 4 + +#if MARVELL_SVC_TEST +#define MVEBU_CP_MPP_CTRL37_OFFS 20 +#define MVEBU_CP_MPP_CTRL38_OFFS 24 +#define MVEBU_CP_MPP_I2C_FUNC 2 +#define MVEBU_MPP_CTRL_MASK 0xf +#endif + +/* Return the AP revision of the chip */ +static unsigned int ble_get_ap_type(void) +{ + unsigned int chip_rev_id; + + chip_rev_id = mmio_read_32(MVEBU_CSS_GWD_CTRL_IIDR2_REG); + chip_rev_id = ((chip_rev_id & GWD_IIDR2_CHIP_ID_MASK) >> + GWD_IIDR2_CHIP_ID_OFFSET); + + return chip_rev_id; +} + +/****************************************************************************** + * The routine allows to save the CCU and IO windows configuration during DRAM + * setup and restore them afterwards before exiting the BLE stage. + * Such window configuration is required since not all default settings coming + * from the HW and the BootROM allow access to peripherals connected to + * all available CPn components. + * For instance, when the boot device is located on CP0, the IO window to CP1 + * is not opened automatically by the HW and if the DRAM SPD is located on CP1 + * i2c channel, it cannot be read at BLE stage. + * Therefore the DRAM init procedure have to provide access to all available + * CPn peripherals during the BLE stage by setting the CCU IO window to all + * CPnph addresses and by enabling the IO windows accordingly. + * Additionally this function configures the CCU GCR to DRAM, which allows + * usage or more than 4GB DRAM as it configured by the default CCU DRAM window. + * + * IN: + * MMAP_SAVE_AND_CONFIG - save the existing configuration and update it + * MMAP_RESTORE_SAVED - restore saved configuration + * OUT: + * NONE + **************************************************************************** + */ +static void ble_plat_mmap_config(int restore) +{ + if (restore == MMAP_RESTORE_SAVED) { + /* Restore all orig. settings that were modified by BLE stage */ + ccu_restore_win_all(MVEBU_AP0); + /* Restore CCU */ + iow_restore_win_all(MVEBU_AP0); + return; + } + + /* Store original values */ + ccu_save_win_all(MVEBU_AP0); + /* Save CCU */ + iow_save_win_all(MVEBU_AP0); + + init_ccu(MVEBU_AP0); + /* The configuration saved, now all the changes can be done */ + init_io_win(MVEBU_AP0); +} + +/**************************************************************************** + * Setup Adaptive Voltage Switching - this is required for some platforms + **************************************************************************** + */ +#if !MARVELL_SVC_TEST +static void ble_plat_avs_config(void) +{ + uint32_t freq_mode, device_id; + uint32_t avs_val = 0; + + freq_mode = + SAR_CLOCK_FREQ_MODE(mmio_read_32(MVEBU_AP_SAR_REG_BASE( + FREQ_MODE_AP_SAR_REG_NUM))); + /* Check which SoC is running and act accordingly */ + if (ble_get_ap_type() == CHIP_ID_AP807) { + /* Increase CPU voltage for higher CPU clock */ + if (freq_mode == CPU_2000_DDR_1200_RCLK_1200) + avs_val = AVS_A3900_HIGH_CLK_VALUE; + else + avs_val = AVS_A3900_CLK_VALUE; + } else { + /* Check which SoC is running and act accordingly */ + device_id = cp110_device_id_get(MVEBU_CP_REGS_BASE(0)); + switch (device_id) { + case MVEBU_80X0_DEV_ID: + case MVEBU_80X0_CP115_DEV_ID: + /* Always fix the default AVS value on A80x0 */ + avs_val = AVS_A8K_CLK_VALUE; + break; + case MVEBU_70X0_DEV_ID: + case MVEBU_70X0_CP115_DEV_ID: + /* Fix AVS for CPU clocks lower than 1600MHz on A70x0 */ + if ((freq_mode > CPU_1600_DDR_900_RCLK_900_2) && + (freq_mode < CPU_DDR_RCLK_INVALID)) + avs_val = AVS_A7K_LOW_CLK_VALUE; + break; + default: + ERROR("Unsupported Device ID 0x%x\n", device_id); + return; + } + } + + if (avs_val) { + VERBOSE("AVS: Setting AVS CTRL to 0x%x\n", avs_val); + mmio_write_32(AVS_EN_CTRL_REG, avs_val); + } +} +#endif +/****************************************************************************** + * Update or override current AVS work point value using data stored in EEPROM + * This is only required by QA/validation flows and activated by + * MARVELL_SVC_TEST flag. + * + * The function is expected to be called twice. + * + * First time with AVS value of 0 for testing if the EEPROM requests completely + * override the AVS value and bypass the eFuse test + * + * Second time - with non-zero AVS value obtained from eFuses as an input. + * In this case the EEPROM may contain AVS correction value (either positive + * or negative) that is added to the input AVS value and returned back for + * further processing. + ****************************************************************************** + */ +static uint32_t avs_update_from_eeprom(uint32_t avs_workpoint) +{ + uint32_t new_wp = avs_workpoint; +#if MARVELL_SVC_TEST + /* --------------------------------------------------------------------- + * EEPROM | Data description (avs_step) + * address | + * --------------------------------------------------------------------- + * 0x120 | AVS workpoint correction value + * | if not 0 and not 0xff, correct the AVS taken from eFuse + * | by the number of steps indicated by bit[6:0] + * | bit[7] defines correction direction. + * | If bit[7]=1, add the value from bit[6:0] to AVS workpoint, + * | othervise substruct this value from AVS workpoint. + * --------------------------------------------------------------------- + * 0x121 | AVS workpoint override value + * | Override the AVS workpoint with the value stored in this + * | byte. When running on AP806, the AVS workpoint is 7 bits + * | wide and override value is valid when bit[6:0] holds + * | value greater than zero and smaller than 0x33. + * | When running on AP807, the AVS workpoint is 10 bits wide. + * | Additional 2 MSB bits are supplied by EEPROM byte 0x122. + * | AVS override value is valid when byte @ 0x121 and bit[1:0] + * | of byte @ 0x122 combined have non-zero value. + * --------------------------------------------------------------------- + * 0x122 | Extended AVS workpoint override value + * | Valid only for AP807 platforms and must be less than 0x4 + * --------------------------------------------------------------------- + */ + static uint8_t avs_step[3] = {0}; + uintptr_t reg; + uint32_t val; + unsigned int ap_type = ble_get_ap_type(); + + /* Always happens on second call to this function */ + if (avs_workpoint != 0) { + /* Get correction steps from the EEPROM */ + if ((avs_step[0] != 0) && (avs_step[0] != 0xff)) { + NOTICE("AVS request to step %s by 0x%x from old 0x%x\n", + avs_step[0] & 0x80 ? "DOWN" : "UP", + avs_step[0] & 0x7f, new_wp); + if (avs_step[0] & 0x80) + new_wp -= avs_step[0] & 0x7f; + else + new_wp += avs_step[0] & 0x7f; + } + + return new_wp; + } + + /* AVS values are located in EEPROM + * at CP0 i2c bus #0, device 0x57 offset 0x120 + * The SDA and SCK pins of CP0 i2c-0: MPP[38:37], i2c function 0x2. + */ + reg = MVEBU_CP_MPP_REGS(0, 4); + val = mmio_read_32(reg); + val &= ~((MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL37_OFFS) | + (MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL38_OFFS)); + val |= (MVEBU_CP_MPP_I2C_FUNC << MVEBU_CP_MPP_CTRL37_OFFS) | + (MVEBU_CP_MPP_I2C_FUNC << MVEBU_CP_MPP_CTRL38_OFFS); + mmio_write_32(reg, val); + + /* Init CP0 i2c-0 */ + i2c_init((void *)(MVEBU_CP0_I2C_BASE)); + + /* Read EEPROM only once at the fist call! */ + i2c_read(AVS_I2C_EEPROM_ADDR, 0x120, 2, avs_step, 3); + NOTICE("== SVC test build ==\n"); + NOTICE("EEPROM holds values 0x%x, 0x%x and 0x%x\n", + avs_step[0], avs_step[1], avs_step[2]); + + /* Override the AVS value? */ + if ((ap_type != CHIP_ID_AP807) && (avs_step[1] < 0x33)) { + /* AP806 - AVS is 7 bits */ + new_wp = avs_step[1]; + + } else if (ap_type == CHIP_ID_AP807 && (avs_step[2] < 0x4)) { + /* AP807 - AVS is 10 bits */ + new_wp = avs_step[2]; + new_wp <<= 8; + new_wp |= avs_step[1]; + } + + if (new_wp == 0) + NOTICE("Ignore BAD AVS Override value in EEPROM!\n"); + else + NOTICE("Override AVS by EEPROM value 0x%x\n", new_wp); +#endif /* MARVELL_SVC_TEST */ + return new_wp; +} + +/**************************************************************************** + * SVC flow - v0.10 + * The feature is intended to configure AVS value according to eFuse values + * that are burned individually for each SoC during the test process. + * Primary AVS value is stored in HD efuse and processed on power on + * by the HW engine + * Secondary AVS value is located in LD efuse and contains 4 work points for + * various CPU frequencies. + * The Secondary AVS value is only taken into account if the SW Revision stored + * in the efuse is greater than 0 and the CPU is running in a certain speed. + **************************************************************************** + */ +static void ble_plat_svc_config(void) +{ + uint32_t reg_val, avs_workpoint, freq_pidi_mode; + uint64_t efuse; + uint32_t device_id, single_cluster; + uint16_t svc[4], perr[4], i, sw_ver; + unsigned int ap_type; + + /* Set access to LD0 */ + avs_workpoint = avs_update_from_eeprom(0); + if (avs_workpoint) + goto set_aws_wp; + + /* Set access to LD0 */ + reg_val = mmio_read_32(MVEBU_AP_EFUSE_SRV_CTRL_REG); + reg_val &= ~EFUSE_SRV_CTRL_LD_SELECT_OFFS; + mmio_write_32(MVEBU_AP_EFUSE_SRV_CTRL_REG, reg_val); + + /* Obtain the value of LD0[125:63] */ + efuse = mmio_read_32(MVEBU_AP_LD0_125_95_EFUSE_OFFS); + efuse <<= 32; + efuse |= mmio_read_32(MVEBU_AP_LD0_94_63_EFUSE_OFFS); + + /* SW Revision: + * Starting from SW revision 1 the SVC flow is supported. + * SW version 0 (efuse not programmed) should follow the + * regular AVS update flow. + */ + sw_ver = (efuse >> EFUSE_AP_LD0_SWREV_OFFS) & EFUSE_AP_LD0_SWREV_MASK; + if (sw_ver < 1) { + NOTICE("SVC: SW Revision 0x%x. SVC is not supported\n", sw_ver); +#if MARVELL_SVC_TEST + NOTICE("SVC_TEST: AVS bypassed\n"); + +#else + ble_plat_avs_config(); +#endif + return; + } + + /* Frequency mode from SAR */ + freq_pidi_mode = SAR_CLOCK_FREQ_MODE( + mmio_read_32( + MVEBU_AP_SAR_REG_BASE( + FREQ_MODE_AP_SAR_REG_NUM))); + + /* Decode all SVC work points */ + svc[0] = (efuse >> EFUSE_AP_LD0_SVC1_OFFS) & EFUSE_AP_LD0_WP_MASK; + svc[1] = (efuse >> EFUSE_AP_LD0_SVC2_OFFS) & EFUSE_AP_LD0_WP_MASK; + svc[2] = (efuse >> EFUSE_AP_LD0_SVC3_OFFS) & EFUSE_AP_LD0_WP_MASK; + + /* Fetch AP type to distinguish between AP806 and AP807 */ + ap_type = ble_get_ap_type(); + + if (ap_type != CHIP_ID_AP807) { + svc[3] = (efuse >> EFUSE_AP_LD0_SVC4_OFFS) + & EFUSE_AP_LD0_WP_MASK; + INFO("SVC: Efuse WP: [0]=0x%x, [1]=0x%x, [2]=0x%x, [3]=0x%x\n", + svc[0], svc[1], svc[2], svc[3]); + } else { + INFO("SVC: Efuse WP: [0]=0x%x, [1]=0x%x, [2]=0x%x\n", + svc[0], svc[1], svc[2]); + } + + /* Validate parity of SVC workpoint values */ + for (i = 0; i < 4; i++) { + uint8_t parity, bit; + + perr[i] = 0; + + for (bit = 1, parity = svc[i] & 1; bit < 7; bit++) + parity ^= (svc[i] >> bit) & 1; + + /* Starting from SW version 2, the parity check is mandatory */ + if ((sw_ver > 1) && (parity != ((svc[i] >> 7) & 1))) + perr[i] = 1; /* register the error */ + } + + single_cluster = mmio_read_32(MVEBU_AP_LD0_220_189_EFUSE_OFFS); + single_cluster = (single_cluster >> EFUSE_AP_LD0_CLUSTER_DOWN_OFFS) & 1; + + device_id = cp110_device_id_get(MVEBU_CP_REGS_BASE(0)); + if (device_id == MVEBU_80X0_DEV_ID || + device_id == MVEBU_80X0_CP115_DEV_ID) { + /* A8040/A8020 */ + NOTICE("SVC: DEV ID: %s, FREQ Mode: 0x%x\n", + single_cluster == 0 ? "8040" : "8020", freq_pidi_mode); + switch (freq_pidi_mode) { + case CPU_1800_DDR_1200_RCLK_1200: + case CPU_1800_DDR_1050_RCLK_1050: + if (perr[1]) + goto perror; + avs_workpoint = svc[1]; + break; + case CPU_1600_DDR_1050_RCLK_1050: + case CPU_1600_DDR_900_RCLK_900_2: + if (perr[2]) + goto perror; + avs_workpoint = svc[2]; + break; + case CPU_1300_DDR_800_RCLK_800: + case CPU_1300_DDR_650_RCLK_650: + if (perr[3]) + goto perror; + avs_workpoint = svc[3]; + break; + case CPU_2000_DDR_1200_RCLK_1200: + case CPU_2000_DDR_1050_RCLK_1050: + default: + if (perr[0]) + goto perror; + avs_workpoint = svc[0]; + break; + } + } else if (device_id == MVEBU_70X0_DEV_ID || + device_id == MVEBU_70X0_CP115_DEV_ID) { + /* A7040/A7020/A6040 */ + NOTICE("SVC: DEV ID: %s, FREQ Mode: 0x%x\n", + single_cluster == 0 ? "7040" : "7020", freq_pidi_mode); + switch (freq_pidi_mode) { + case CPU_1400_DDR_800_RCLK_800: + if (single_cluster) {/* 7020 */ + if (perr[1]) + goto perror; + avs_workpoint = svc[1]; + } else { + if (perr[0]) + goto perror; + avs_workpoint = svc[0]; + } + break; + case CPU_1200_DDR_800_RCLK_800: + if (single_cluster) {/* 7020 */ + if (perr[2]) + goto perror; + avs_workpoint = svc[2]; + } else { + if (perr[1]) + goto perror; + avs_workpoint = svc[1]; + } + break; + case CPU_800_DDR_800_RCLK_800: + case CPU_1000_DDR_800_RCLK_800: + if (single_cluster) {/* 7020 */ + if (perr[3]) + goto perror; + avs_workpoint = svc[3]; + } else { + if (perr[2]) + goto perror; + avs_workpoint = svc[2]; + } + break; + case CPU_600_DDR_800_RCLK_800: + if (perr[3]) + goto perror; + avs_workpoint = svc[3]; /* Same for 6040 and 7020 */ + break; + case CPU_1600_DDR_800_RCLK_800: /* 7020 only */ + default: + if (single_cluster) {/* 7020 */ + if (perr[0]) + goto perror; + avs_workpoint = svc[0]; + } else + avs_workpoint = 0; + break; + } + } else if (device_id == MVEBU_3900_DEV_ID) { + NOTICE("SVC: DEV ID: %s, FREQ Mode: 0x%x\n", + "3900", freq_pidi_mode); + switch (freq_pidi_mode) { + case CPU_1600_DDR_1200_RCLK_1200: + if (perr[0]) + goto perror; + avs_workpoint = svc[0]; + break; + case CPU_1300_DDR_800_RCLK_800: + if (perr[1]) + goto perror; + avs_workpoint = svc[1]; + break; + default: + if (perr[0]) + goto perror; + avs_workpoint = svc[0]; + break; + } + } else { + ERROR("SVC: Unsupported Device ID 0x%x\n", device_id); + return; + } + + /* Set AVS control if needed */ + if (avs_workpoint == 0) { + ERROR("SVC: AVS work point not changed\n"); + return; + } + + /* Remove parity bit */ + if (ap_type != CHIP_ID_AP807) + avs_workpoint &= 0x7F; + + /* Update WP from EEPROM if needed */ + avs_workpoint = avs_update_from_eeprom(avs_workpoint); + +set_aws_wp: + reg_val = mmio_read_32(AVS_EN_CTRL_REG); + NOTICE("SVC: AVS work point changed from 0x%x to 0x%x\n", + (reg_val & AVS_VDD_LOW_LIMIT_MASK) >> AVS_LOW_VDD_LIMIT_OFFSET, + avs_workpoint); + reg_val &= ~(AVS_VDD_LOW_LIMIT_MASK | AVS_VDD_HIGH_LIMIT_MASK); + reg_val |= 0x1 << AVS_ENABLE_OFFSET; + reg_val |= avs_workpoint << AVS_HIGH_VDD_LIMIT_OFFSET; + reg_val |= avs_workpoint << AVS_LOW_VDD_LIMIT_OFFSET; + mmio_write_32(AVS_EN_CTRL_REG, reg_val); + return; + +perror: + ERROR("Failed SVC WP[%d] parity check!\n", i); + ERROR("Ignoring the WP values\n"); +} + +#if PLAT_RECOVERY_IMAGE_ENABLE +static int ble_skip_image_i2c(struct skip_image *skip_im) +{ + ERROR("skipping image using i2c is not supported\n"); + /* not supported */ + return 0; +} + +static int ble_skip_image_other(struct skip_image *skip_im) +{ + ERROR("implementation missing for skip image request\n"); + /* not supported, make your own implementation */ + return 0; +} + +static int ble_skip_image_gpio(struct skip_image *skip_im) +{ + unsigned int val; + unsigned int mpp_address = 0; + unsigned int offset = 0; + + switch (skip_im->info.test.cp_ap) { + case(CP): + mpp_address = MVEBU_CP_GPIO_DATA_IN(skip_im->info.test.cp_index, + skip_im->info.gpio.num); + if (skip_im->info.gpio.num > NUM_OF_GPIO_PER_REG) + offset = skip_im->info.gpio.num - NUM_OF_GPIO_PER_REG; + else + offset = skip_im->info.gpio.num; + break; + case(AP): + mpp_address = MVEBU_AP_GPIO_DATA_IN; + offset = skip_im->info.gpio.num; + break; + } + + val = mmio_read_32(mpp_address); + val &= (1 << offset); + if ((!val && skip_im->info.gpio.button_state == HIGH) || + (val && skip_im->info.gpio.button_state == LOW)) { + mmio_write_32(SCRATCH_PAD_REG2, SCRATCH_PAD_SKIP_VAL); + return 1; + } + + return 0; +} + +/* + * This function checks if there's a skip image request: + * return values: + * 1: (true) images request been made. + * 0: (false) no image request been made. + */ +static int ble_skip_current_image(void) +{ + struct skip_image *skip_im; + + /*fetching skip image info*/ + skip_im = (struct skip_image *)plat_marvell_get_skip_image_data(); + + if (skip_im == NULL) + return 0; + + /* check if skipping image request has already been made */ + if (mmio_read_32(SCRATCH_PAD_REG2) == SCRATCH_PAD_SKIP_VAL) + return 0; + + switch (skip_im->detection_method) { + case GPIO: + return ble_skip_image_gpio(skip_im); + case I2C: + return ble_skip_image_i2c(skip_im); + case USER_DEFINED: + return ble_skip_image_other(skip_im); + } + + return 0; +} +#endif + + +int ble_plat_setup(int *skip) +{ + int ret; + unsigned int freq_mode; + + /* Power down unused CPUs */ + plat_marvell_early_cpu_powerdown(); + + /* + * Save the current CCU configuration and make required changes: + * - Allow access to DRAM larger than 4GB + * - Open memory access to all CPn peripherals + */ + ble_plat_mmap_config(MMAP_SAVE_AND_CONFIG); + +#if PLAT_RECOVERY_IMAGE_ENABLE + /* Check if there's a skip request to bootRom recovery Image */ + if (ble_skip_current_image()) { + /* close memory access to all CPn peripherals. */ + ble_plat_mmap_config(MMAP_RESTORE_SAVED); + *skip = 1; + return 0; + } +#endif + /* Do required CP-110 setups for BLE stage */ + cp110_ble_init(MVEBU_CP_REGS_BASE(0)); + + /* Setup AVS */ + ble_plat_svc_config(); + + /* read clk option from sampled-at-reset register */ + freq_mode = + SAR_CLOCK_FREQ_MODE(mmio_read_32(MVEBU_AP_SAR_REG_BASE( + FREQ_MODE_AP_SAR_REG_NUM))); + + /* work with PLL clock driver in AP807 */ + if (ble_get_ap_type() == CHIP_ID_AP807) + ap807_clocks_init(freq_mode); + + /* Do required AP setups for BLE stage */ + ap_ble_init(); + + /* Update DRAM topology (scan DIMM SPDs) */ + plat_marvell_dram_update_topology(); + + /* Kick it in */ + ret = dram_init(); + + /* Restore the original CCU configuration before exit from BLE */ + ble_plat_mmap_config(MMAP_RESTORE_SAVED); + + return ret; +} diff --git a/plat/marvell/armada/a8k/common/plat_pm.c b/plat/marvell/armada/a8k/common/plat_pm.c new file mode 100644 index 000000000..96e95c271 --- /dev/null +++ b/plat/marvell/armada/a8k/common/plat_pm.c @@ -0,0 +1,844 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define MVEBU_PRIVATE_UID_REG 0x30 +#define MVEBU_RFU_GLOBL_SW_RST 0x84 +#define MVEBU_CCU_RVBAR(cpu) (MVEBU_REGS_BASE + 0x640 + (cpu * 4)) +#define MVEBU_CCU_CPU_UN_RESET(cpu) (MVEBU_REGS_BASE + 0x650 + (cpu * 4)) + +#define MPIDR_CPU_GET(mpidr) ((mpidr) & MPIDR_CPU_MASK) +#define MPIDR_CLUSTER_GET(mpidr) MPIDR_AFFLVL1_VAL((mpidr)) + +#define MVEBU_GPIO_MASK(index) (1 << (index % 32)) +#define MVEBU_MPP_MASK(index) (0xF << (4 * (index % 8))) +#define MVEBU_GPIO_VALUE(index, value) (value << (index % 32)) + +#define MVEBU_USER_CMD_0_REG (MVEBU_DRAM_MAC_BASE + 0x20) +#define MVEBU_USER_CMD_CH0_OFFSET 28 +#define MVEBU_USER_CMD_CH0_MASK (1 << MVEBU_USER_CMD_CH0_OFFSET) +#define MVEBU_USER_CMD_CH0_EN (1 << MVEBU_USER_CMD_CH0_OFFSET) +#define MVEBU_USER_CMD_CS_OFFSET 24 +#define MVEBU_USER_CMD_CS_MASK (0xF << MVEBU_USER_CMD_CS_OFFSET) +#define MVEBU_USER_CMD_CS_ALL (0xF << MVEBU_USER_CMD_CS_OFFSET) +#define MVEBU_USER_CMD_SR_OFFSET 6 +#define MVEBU_USER_CMD_SR_MASK (0x3 << MVEBU_USER_CMD_SR_OFFSET) +#define MVEBU_USER_CMD_SR_ENTER (0x1 << MVEBU_USER_CMD_SR_OFFSET) +#define MVEBU_MC_PWR_CTRL_REG (MVEBU_DRAM_MAC_BASE + 0x54) +#define MVEBU_MC_AC_ON_DLY_OFFSET 8 +#define MVEBU_MC_AC_ON_DLY_MASK (0xF << MVEBU_MC_AC_ON_DLY_OFFSET) +#define MVEBU_MC_AC_ON_DLY_DEF_VAR (8 << MVEBU_MC_AC_ON_DLY_OFFSET) +#define MVEBU_MC_AC_OFF_DLY_OFFSET 4 +#define MVEBU_MC_AC_OFF_DLY_MASK (0xF << MVEBU_MC_AC_OFF_DLY_OFFSET) +#define MVEBU_MC_AC_OFF_DLY_DEF_VAR (0xC << MVEBU_MC_AC_OFF_DLY_OFFSET) +#define MVEBU_MC_PHY_AUTO_OFF_OFFSET 0 +#define MVEBU_MC_PHY_AUTO_OFF_MASK (1 << MVEBU_MC_PHY_AUTO_OFF_OFFSET) +#define MVEBU_MC_PHY_AUTO_OFF_EN (1 << MVEBU_MC_PHY_AUTO_OFF_OFFSET) + +/* this lock synchronize AP multiple cores execution with MSS */ +DEFINE_BAKERY_LOCK(pm_sys_lock); + +/* Weak definitions may be overridden in specific board */ +#pragma weak plat_marvell_get_pm_cfg + +/* AP806 CPU power down /power up definitions */ +enum CPU_ID { + CPU0, + CPU1, + CPU2, + CPU3 +}; + +#define REG_WR_VALIDATE_TIMEOUT (2000) + +#define FEATURE_DISABLE_STATUS_REG \ + (MVEBU_REGS_BASE + 0x6F8230) +#define FEATURE_DISABLE_STATUS_CPU_CLUSTER_OFFSET 4 +#define FEATURE_DISABLE_STATUS_CPU_CLUSTER_MASK \ + (0x1 << FEATURE_DISABLE_STATUS_CPU_CLUSTER_OFFSET) + +#ifdef MVEBU_SOC_AP807 + #define PWRC_CPUN_CR_PWR_DN_RQ_OFFSET 1 + #define PWRC_CPUN_CR_LDO_BYPASS_RDY_OFFSET 0 +#else + #define PWRC_CPUN_CR_PWR_DN_RQ_OFFSET 0 + #define PWRC_CPUN_CR_LDO_BYPASS_RDY_OFFSET 31 +#endif + +#define PWRC_CPUN_CR_REG(cpu_id) \ + (MVEBU_REGS_BASE + 0x680000 + (cpu_id * 0x10)) +#define PWRC_CPUN_CR_PWR_DN_RQ_MASK \ + (0x1 << PWRC_CPUN_CR_PWR_DN_RQ_OFFSET) +#define PWRC_CPUN_CR_ISO_ENABLE_OFFSET 16 +#define PWRC_CPUN_CR_ISO_ENABLE_MASK \ + (0x1 << PWRC_CPUN_CR_ISO_ENABLE_OFFSET) +#define PWRC_CPUN_CR_LDO_BYPASS_RDY_MASK \ + (0x1U << PWRC_CPUN_CR_LDO_BYPASS_RDY_OFFSET) + +#define CCU_B_PRCRN_REG(cpu_id) \ + (MVEBU_REGS_BASE + 0x1A50 + \ + ((cpu_id / 2) * (0x400)) + ((cpu_id % 2) * 4)) +#define CCU_B_PRCRN_CPUPORESET_STATIC_OFFSET 0 +#define CCU_B_PRCRN_CPUPORESET_STATIC_MASK \ + (0x1 << CCU_B_PRCRN_CPUPORESET_STATIC_OFFSET) + +/* power switch fingers */ +#define AP807_PWRC_LDO_CR0_REG \ + (MVEBU_REGS_BASE + 0x680000 + 0x100) +#define AP807_PWRC_LDO_CR0_OFFSET 16 +#define AP807_PWRC_LDO_CR0_MASK \ + (0xff << AP807_PWRC_LDO_CR0_OFFSET) +#define AP807_PWRC_LDO_CR0_VAL 0xfc + +/* + * Power down CPU: + * Used to reduce power consumption, and avoid SoC unnecessary temperature rise. + */ +static int plat_marvell_cpu_powerdown(int cpu_id) +{ + uint32_t reg_val; + int exit_loop = REG_WR_VALIDATE_TIMEOUT; + + INFO("Powering down CPU%d\n", cpu_id); + + /* 1. Isolation enable */ + reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); + reg_val |= 0x1 << PWRC_CPUN_CR_ISO_ENABLE_OFFSET; + mmio_write_32(PWRC_CPUN_CR_REG(cpu_id), reg_val); + + /* 2. Read and check Isolation enabled - verify bit set to 1 */ + do { + reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); + exit_loop--; + } while (!(reg_val & (0x1 << PWRC_CPUN_CR_ISO_ENABLE_OFFSET)) && + exit_loop > 0); + + /* 3. Switch off CPU power */ + reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); + reg_val &= ~PWRC_CPUN_CR_PWR_DN_RQ_MASK; + mmio_write_32(PWRC_CPUN_CR_REG(cpu_id), reg_val); + + /* 4. Read and check Switch Off - verify bit set to 0 */ + exit_loop = REG_WR_VALIDATE_TIMEOUT; + do { + reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); + exit_loop--; + } while (reg_val & PWRC_CPUN_CR_PWR_DN_RQ_MASK && exit_loop > 0); + + if (exit_loop <= 0) + goto cpu_poweroff_error; + + /* 5. De-Assert power ready */ + reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); + reg_val &= ~PWRC_CPUN_CR_LDO_BYPASS_RDY_MASK; + mmio_write_32(PWRC_CPUN_CR_REG(cpu_id), reg_val); + + /* 6. Assert CPU POR reset */ + reg_val = mmio_read_32(CCU_B_PRCRN_REG(cpu_id)); + reg_val &= ~CCU_B_PRCRN_CPUPORESET_STATIC_MASK; + mmio_write_32(CCU_B_PRCRN_REG(cpu_id), reg_val); + + /* 7. Read and poll on Validate the CPU is out of reset */ + exit_loop = REG_WR_VALIDATE_TIMEOUT; + do { + reg_val = mmio_read_32(CCU_B_PRCRN_REG(cpu_id)); + exit_loop--; + } while (reg_val & CCU_B_PRCRN_CPUPORESET_STATIC_MASK && exit_loop > 0); + + if (exit_loop <= 0) + goto cpu_poweroff_error; + + INFO("Successfully powered down CPU%d\n", cpu_id); + + return 0; + +cpu_poweroff_error: + ERROR("ERROR: Can't power down CPU%d\n", cpu_id); + return -1; +} + +/* + * Power down CPUs 1-3 at early boot stage, + * to reduce power consumption and SoC temperature. + * This is triggered by BLE prior to DDR initialization. + * + * Note: + * All CPUs will be powered up by plat_marvell_cpu_powerup on Linux boot stage, + * which is triggered by PSCI ops (pwr_domain_on). + */ +int plat_marvell_early_cpu_powerdown(void) +{ + uint32_t cpu_cluster_status = + mmio_read_32(FEATURE_DISABLE_STATUS_REG) & + FEATURE_DISABLE_STATUS_CPU_CLUSTER_MASK; + /* if cpu_cluster_status bit is set, + * that means we have only single cluster + */ + int cluster_count = cpu_cluster_status ? 1 : 2; + + INFO("Powering off unused CPUs\n"); + + /* CPU1 is in AP806 cluster-0, which always exists, so power it down */ + if (plat_marvell_cpu_powerdown(CPU1) == -1) + return -1; + + /* + * CPU2-3 are in AP806 2nd cluster (cluster-1), + * which doesn't exists in dual-core systems. + * so need to check if we have dual-core (single cluster) + * or quad-code (2 clusters) + */ + if (cluster_count == 2) { + /* CPU2-3 are part of 2nd cluster */ + if (plat_marvell_cpu_powerdown(CPU2) == -1) + return -1; + if (plat_marvell_cpu_powerdown(CPU3) == -1) + return -1; + } + + return 0; +} + +/* + * Power up CPU - part of Linux boot stage + */ +static int plat_marvell_cpu_powerup(u_register_t mpidr) +{ + uint32_t reg_val; + int cpu_id = MPIDR_CPU_GET(mpidr), + cluster = MPIDR_CLUSTER_GET(mpidr); + int exit_loop = REG_WR_VALIDATE_TIMEOUT; + + /* calculate absolute CPU ID */ + cpu_id = cluster * PLAT_MARVELL_CLUSTER_CORE_COUNT + cpu_id; + + INFO("Powering on CPU%d\n", cpu_id); + +#ifdef MVEBU_SOC_AP807 + /* Activate 2 power switch fingers */ + reg_val = mmio_read_32(AP807_PWRC_LDO_CR0_REG); + reg_val &= ~(AP807_PWRC_LDO_CR0_MASK); + reg_val |= (AP807_PWRC_LDO_CR0_VAL << AP807_PWRC_LDO_CR0_OFFSET); + mmio_write_32(AP807_PWRC_LDO_CR0_REG, reg_val); + udelay(100); +#endif + + /* 1. Switch CPU power ON */ + reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); + reg_val |= 0x1 << PWRC_CPUN_CR_PWR_DN_RQ_OFFSET; + mmio_write_32(PWRC_CPUN_CR_REG(cpu_id), reg_val); + + /* 2. Wait for CPU on, up to 100 uSec: */ + udelay(100); + + /* 3. Assert power ready */ + reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); + reg_val |= 0x1U << PWRC_CPUN_CR_LDO_BYPASS_RDY_OFFSET; + mmio_write_32(PWRC_CPUN_CR_REG(cpu_id), reg_val); + + /* 4. Read & Validate power ready + * used in order to generate 16 Host CPU cycles + */ + do { + reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); + exit_loop--; + } while (!(reg_val & (0x1U << PWRC_CPUN_CR_LDO_BYPASS_RDY_OFFSET)) && + exit_loop > 0); + + if (exit_loop <= 0) + goto cpu_poweron_error; + + /* 5. Isolation disable */ + reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); + reg_val &= ~PWRC_CPUN_CR_ISO_ENABLE_MASK; + mmio_write_32(PWRC_CPUN_CR_REG(cpu_id), reg_val); + + /* 6. Read and check Isolation enabled - verify bit set to 1 */ + exit_loop = REG_WR_VALIDATE_TIMEOUT; + do { + reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id)); + exit_loop--; + } while ((reg_val & (0x1 << PWRC_CPUN_CR_ISO_ENABLE_OFFSET)) && + exit_loop > 0); + + /* 7. De Assert CPU POR reset & Core reset */ + reg_val = mmio_read_32(CCU_B_PRCRN_REG(cpu_id)); + reg_val |= 0x1 << CCU_B_PRCRN_CPUPORESET_STATIC_OFFSET; + mmio_write_32(CCU_B_PRCRN_REG(cpu_id), reg_val); + + /* 8. Read & Validate CPU POR reset */ + exit_loop = REG_WR_VALIDATE_TIMEOUT; + do { + reg_val = mmio_read_32(CCU_B_PRCRN_REG(cpu_id)); + exit_loop--; + } while (!(reg_val & (0x1 << CCU_B_PRCRN_CPUPORESET_STATIC_OFFSET)) && + exit_loop > 0); + + if (exit_loop <= 0) + goto cpu_poweron_error; + + INFO("Successfully powered on CPU%d\n", cpu_id); + + return 0; + +cpu_poweron_error: + ERROR("ERROR: Can't power up CPU%d\n", cpu_id); + return -1; +} + +static int plat_marvell_cpu_on(u_register_t mpidr) +{ + int cpu_id; + int cluster; + + /* Set barierr */ + dsbsy(); + + /* Get cpu number - use CPU ID */ + cpu_id = MPIDR_CPU_GET(mpidr); + + /* Get cluster number - use affinity level 1 */ + cluster = MPIDR_CLUSTER_GET(mpidr); + + /* Set CPU private UID */ + mmio_write_32(MVEBU_REGS_BASE + MVEBU_PRIVATE_UID_REG, cluster + 0x4); + + /* Set the cpu start address to BL1 entry point (align to 0x10000) */ + mmio_write_32(MVEBU_CCU_RVBAR(cpu_id), + PLAT_MARVELL_CPU_ENTRY_ADDR >> 16); + + /* Get the cpu out of reset */ + mmio_write_32(MVEBU_CCU_CPU_UN_RESET(cpu_id), 0x10001); + + return 0; +} + +/***************************************************************************** + * A8K handler called to check the validity of the power state + * parameter. + ***************************************************************************** + */ +static int a8k_validate_power_state(unsigned int power_state, + psci_power_state_t *req_state) +{ + int pstate = psci_get_pstate_type(power_state); + int pwr_lvl = psci_get_pstate_pwrlvl(power_state); + int i; + + if (pwr_lvl > PLAT_MAX_PWR_LVL) + return PSCI_E_INVALID_PARAMS; + + /* Sanity check the requested state */ + if (pstate == PSTATE_TYPE_STANDBY) { + /* + * It's possible to enter standby only on power level 0 + * Ignore any other power level. + */ + if (pwr_lvl != MARVELL_PWR_LVL0) + return PSCI_E_INVALID_PARAMS; + + req_state->pwr_domain_state[MARVELL_PWR_LVL0] = + MARVELL_LOCAL_STATE_RET; + } else { + for (i = MARVELL_PWR_LVL0; i <= pwr_lvl; i++) + req_state->pwr_domain_state[i] = + MARVELL_LOCAL_STATE_OFF; + } + + /* + * We expect the 'state id' to be zero. + */ + if (psci_get_pstate_id(power_state)) + return PSCI_E_INVALID_PARAMS; + + return PSCI_E_SUCCESS; +} + +/***************************************************************************** + * A8K handler called when a CPU is about to enter standby. + ***************************************************************************** + */ +static void a8k_cpu_standby(plat_local_state_t cpu_state) +{ + if (!is_pm_fw_running()) { + ERROR("%s: needs to be implemented\n", __func__); + panic(); + } +} + +/***************************************************************************** + * A8K handler called when a power domain is about to be turned on. The + * mpidr determines the CPU to be turned on. + ***************************************************************************** + */ +static int a8k_pwr_domain_on(u_register_t mpidr) +{ + /* Power up CPU (CPUs 1-3 are powered off at start of BLE) */ + plat_marvell_cpu_powerup(mpidr); + + if (is_pm_fw_running()) { + unsigned int target = + ((mpidr & 0xFF) + (((mpidr >> 8) & 0xFF) * 2)); + + /* + * pm system synchronization - used to synchronize + * multiple core access to MSS + */ + bakery_lock_get(&pm_sys_lock); + + /* send CPU ON IPC Message to MSS */ + mss_pm_ipc_msg_send(target, PM_IPC_MSG_CPU_ON, 0); + + /* trigger IPC message to MSS */ + mss_pm_ipc_msg_trigger(); + + /* pm system synchronization */ + bakery_lock_release(&pm_sys_lock); + + /* trace message */ + PM_TRACE(TRACE_PWR_DOMAIN_ON | target); + } else { + /* proprietary CPU ON exection flow */ + plat_marvell_cpu_on(mpidr); + } + + return 0; +} + +/***************************************************************************** + * A8K handler called to validate the entry point. + ***************************************************************************** + */ +static int a8k_validate_ns_entrypoint(uintptr_t entrypoint) +{ + return PSCI_E_SUCCESS; +} + +/***************************************************************************** + * A8K handler called when a power domain is about to be turned off. The + * target_state encodes the power state that each level should transition to. + ***************************************************************************** + */ +static void a8k_pwr_domain_off(const psci_power_state_t *target_state) +{ + if (is_pm_fw_running()) { + unsigned int idx = plat_my_core_pos(); + + /* Prevent interrupts from spuriously waking up this cpu */ + gicv2_cpuif_disable(); + + /* pm system synchronization - used to synchronize multiple + * core access to MSS + */ + bakery_lock_get(&pm_sys_lock); + + /* send CPU OFF IPC Message to MSS */ + mss_pm_ipc_msg_send(idx, PM_IPC_MSG_CPU_OFF, target_state); + + /* trigger IPC message to MSS */ + mss_pm_ipc_msg_trigger(); + + /* pm system synchronization */ + bakery_lock_release(&pm_sys_lock); + + /* trace message */ + PM_TRACE(TRACE_PWR_DOMAIN_OFF); + } else { + INFO("%s: is not supported without SCP\n", __func__); + } +} + +/* Get PM config to power off the SoC */ +void *plat_marvell_get_pm_cfg(void) +{ + return NULL; +} + +/* + * This function should be called on restore from + * "suspend to RAM" state when the execution flow + * has to bypass BootROM image to RAM copy and speed up + * the system recovery + * + */ +static void plat_marvell_exit_bootrom(void) +{ + marvell_exit_bootrom(PLAT_MARVELL_TRUSTED_ROM_BASE); +} + +/* + * Prepare for the power off of the system via GPIO + */ +static void plat_marvell_power_off_gpio(struct power_off_method *pm_cfg, + register_t *gpio_addr, + register_t *gpio_data) +{ + unsigned int gpio; + unsigned int idx; + unsigned int shift; + unsigned int reg; + unsigned int addr; + gpio_info_t *info; + unsigned int tog_bits; + + assert((pm_cfg->cfg.gpio.pin_count < PMIC_GPIO_MAX_NUMBER) && + (pm_cfg->cfg.gpio.step_count < PMIC_GPIO_MAX_TOGGLE_STEP)); + + /* Prepare GPIOs for PMIC */ + for (gpio = 0; gpio < pm_cfg->cfg.gpio.pin_count; gpio++) { + info = &pm_cfg->cfg.gpio.info[gpio]; + /* Set PMIC GPIO to output mode */ + reg = mmio_read_32(MVEBU_CP_GPIO_DATA_OUT_EN( + info->cp_index, info->gpio_index)); + mmio_write_32(MVEBU_CP_GPIO_DATA_OUT_EN( + info->cp_index, info->gpio_index), + reg & ~MVEBU_GPIO_MASK(info->gpio_index)); + + /* Set the appropriate MPP to GPIO mode */ + reg = mmio_read_32(MVEBU_PM_MPP_REGS(info->cp_index, + info->gpio_index)); + mmio_write_32(MVEBU_PM_MPP_REGS(info->cp_index, + info->gpio_index), + reg & ~MVEBU_MPP_MASK(info->gpio_index)); + } + + /* Wait for MPP & GPIO pre-configurations done */ + mdelay(pm_cfg->cfg.gpio.delay_ms); + + /* Toggle the GPIO values, and leave final step to be triggered + * after DDR self-refresh is enabled + */ + for (idx = 0; idx < pm_cfg->cfg.gpio.step_count; idx++) { + tog_bits = pm_cfg->cfg.gpio.seq[idx]; + + /* The GPIOs must be within same GPIO register, + * thus could get the original value by first GPIO + */ + info = &pm_cfg->cfg.gpio.info[0]; + reg = mmio_read_32(MVEBU_CP_GPIO_DATA_OUT( + info->cp_index, info->gpio_index)); + addr = MVEBU_CP_GPIO_DATA_OUT(info->cp_index, info->gpio_index); + + for (gpio = 0; gpio < pm_cfg->cfg.gpio.pin_count; gpio++) { + shift = pm_cfg->cfg.gpio.info[gpio].gpio_index % 32; + if (GPIO_LOW == (tog_bits & (1 << gpio))) + reg &= ~(1 << shift); + else + reg |= (1 << shift); + } + + /* Set the GPIO register, for last step just store + * register address and values to system registers + */ + if (idx < pm_cfg->cfg.gpio.step_count - 1) { + mmio_write_32(MVEBU_CP_GPIO_DATA_OUT( + info->cp_index, info->gpio_index), reg); + mdelay(pm_cfg->cfg.gpio.delay_ms); + } else { + /* Save GPIO register and address values for + * finishing the power down operation later + */ + *gpio_addr = addr; + *gpio_data = reg; + } + } +} + +/* + * Prepare for the power off of the system + */ +static void plat_marvell_power_off_prepare(struct power_off_method *pm_cfg, + register_t *addr, register_t *data) +{ + switch (pm_cfg->type) { + case PMIC_GPIO: + plat_marvell_power_off_gpio(pm_cfg, addr, data); + break; + default: + break; + } +} + +/***************************************************************************** + * A8K handler called when a power domain is about to be suspended. The + * target_state encodes the power state that each level should transition to. + ***************************************************************************** + */ +static void a8k_pwr_domain_suspend(const psci_power_state_t *target_state) +{ + if (is_pm_fw_running()) { + unsigned int idx; + + /* Prevent interrupts from spuriously waking up this cpu */ + gicv2_cpuif_disable(); + + idx = plat_my_core_pos(); + + /* pm system synchronization - used to synchronize multiple + * core access to MSS + */ + bakery_lock_get(&pm_sys_lock); + + /* send CPU Suspend IPC Message to MSS */ + mss_pm_ipc_msg_send(idx, PM_IPC_MSG_CPU_SUSPEND, target_state); + + /* trigger IPC message to MSS */ + mss_pm_ipc_msg_trigger(); + + /* pm system synchronization */ + bakery_lock_release(&pm_sys_lock); + + /* trace message */ + PM_TRACE(TRACE_PWR_DOMAIN_SUSPEND); + } else { + uintptr_t *mailbox = (void *)PLAT_MARVELL_MAILBOX_BASE; + + INFO("Suspending to RAM\n"); + + marvell_console_runtime_end(); + + /* Prevent interrupts from spuriously waking up this cpu */ + gicv2_cpuif_disable(); + + mailbox[MBOX_IDX_SUSPEND_MAGIC] = MVEBU_MAILBOX_SUSPEND_STATE; + mailbox[MBOX_IDX_ROM_EXIT_ADDR] = (uintptr_t)&plat_marvell_exit_bootrom; + +#if PLAT_MARVELL_SHARED_RAM_CACHED + flush_dcache_range(PLAT_MARVELL_MAILBOX_BASE + + MBOX_IDX_SUSPEND_MAGIC * sizeof(uintptr_t), + 2 * sizeof(uintptr_t)); +#endif + /* Flush and disable LLC before going off-power */ + llc_disable(0); + + isb(); + /* + * Do not halt here! + * The function must return for allowing the caller function + * psci_power_up_finish() to do the proper context saving and + * to release the CPU lock. + */ + } +} + +/***************************************************************************** + * A8K handler called when a power domain has just been powered on after + * being turned off earlier. The target_state encodes the low power state that + * each level has woken up from. + ***************************************************************************** + */ +static void a8k_pwr_domain_on_finish(const psci_power_state_t *target_state) +{ + /* arch specific configuration */ + marvell_psci_arch_init(0); + + /* Interrupt initialization */ + gicv2_pcpu_distif_init(); + gicv2_cpuif_enable(); + + if (is_pm_fw_running()) { + /* trace message */ + PM_TRACE(TRACE_PWR_DOMAIN_ON_FINISH); + } +} + +/***************************************************************************** + * A8K handler called when a power domain has just been powered on after + * having been suspended earlier. The target_state encodes the low power state + * that each level has woken up from. + * TODO: At the moment we reuse the on finisher and reinitialize the secure + * context. Need to implement a separate suspend finisher. + ***************************************************************************** + */ +static void a8k_pwr_domain_suspend_finish( + const psci_power_state_t *target_state) +{ + if (is_pm_fw_running()) { + /* arch specific configuration */ + marvell_psci_arch_init(0); + + /* Interrupt initialization */ + gicv2_cpuif_enable(); + + /* trace message */ + PM_TRACE(TRACE_PWR_DOMAIN_SUSPEND_FINISH); + } else { + uintptr_t *mailbox = (void *)PLAT_MARVELL_MAILBOX_BASE; + + /* Only primary CPU requres platform init */ + if (!plat_my_core_pos()) { + /* Initialize the console to provide + * early debug support + */ + marvell_console_runtime_init(); + + bl31_plat_arch_setup(); + marvell_bl31_platform_setup(); + /* + * Remove suspend to RAM marker from the mailbox + * for treating a regular reset as a cold boot + */ + mailbox[MBOX_IDX_SUSPEND_MAGIC] = 0; + mailbox[MBOX_IDX_ROM_EXIT_ADDR] = 0; +#if PLAT_MARVELL_SHARED_RAM_CACHED + flush_dcache_range(PLAT_MARVELL_MAILBOX_BASE + + MBOX_IDX_SUSPEND_MAGIC * sizeof(uintptr_t), + 2 * sizeof(uintptr_t)); +#endif + } + } +} + +/***************************************************************************** + * This handler is called by the PSCI implementation during the `SYSTEM_SUSPEND` + * call to get the `power_state` parameter. This allows the platform to encode + * the appropriate State-ID field within the `power_state` parameter which can + * be utilized in `pwr_domain_suspend()` to suspend to system affinity level. + ***************************************************************************** + */ +static void a8k_get_sys_suspend_power_state(psci_power_state_t *req_state) +{ + /* lower affinities use PLAT_MAX_OFF_STATE */ + for (int i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++) + req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE; +} + +static void +__dead2 a8k_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state) +{ + struct power_off_method *pm_cfg; + unsigned int srcmd; + unsigned int sdram_reg; + register_t gpio_data = 0, gpio_addr = 0; + + if (is_pm_fw_running()) { + psci_power_down_wfi(); + panic(); + } + + pm_cfg = (struct power_off_method *)plat_marvell_get_pm_cfg(); + + /* Prepare for power off */ + plat_marvell_power_off_prepare(pm_cfg, &gpio_addr, &gpio_data); + + /* First step to enable DDR self-refresh + * to keep the data during suspend + */ + mmio_write_32(MVEBU_MC_PWR_CTRL_REG, 0x8C1); + + /* Save DDR self-refresh second step register + * and value to be issued later + */ + sdram_reg = MVEBU_USER_CMD_0_REG; + srcmd = mmio_read_32(sdram_reg); + srcmd &= ~(MVEBU_USER_CMD_CH0_MASK | MVEBU_USER_CMD_CS_MASK | + MVEBU_USER_CMD_SR_MASK); + srcmd |= (MVEBU_USER_CMD_CH0_EN | MVEBU_USER_CMD_CS_ALL | + MVEBU_USER_CMD_SR_ENTER); + + /* + * Wait for DRAM is done using registers access only. + * At this stage any access to DRAM (procedure call) will + * release it from the self-refresh mode + */ + __asm__ volatile ( + /* Align to a cache line */ + " .balign 64\n\t" + + /* Enter self refresh */ + " str %[srcmd], [%[sdram_reg]]\n\t" + + /* + * Wait 100 cycles for DDR to enter self refresh, by + * doing 50 times two instructions. + */ + " mov x1, #50\n\t" + "1: subs x1, x1, #1\n\t" + " bne 1b\n\t" + + /* Issue the command to trigger the SoC power off */ + " str %[gpio_data], [%[gpio_addr]]\n\t" + + /* Trap the processor */ + " b .\n\t" + : : [srcmd] "r" (srcmd), [sdram_reg] "r" (sdram_reg), + [gpio_addr] "r" (gpio_addr), [gpio_data] "r" (gpio_data) + : "x1"); + + panic(); +} + +/***************************************************************************** + * A8K handlers to shutdown/reboot the system + ***************************************************************************** + */ + +/* Set a weak stub for platforms that don't configure system power off */ +#pragma weak system_power_off +int system_power_off(void) +{ + return 0; +} + +static void __dead2 a8k_system_off(void) +{ + /* Call the platform specific system power off function */ + system_power_off(); + + /* board doesn't have a system off implementation */ + ERROR("%s: needs to be implemented\n", __func__); + panic(); +} + +void plat_marvell_system_reset(void) +{ + mmio_write_32(MVEBU_RFU_BASE + MVEBU_RFU_GLOBL_SW_RST, 0x0); +} + +static void __dead2 a8k_system_reset(void) +{ + plat_marvell_system_reset(); + + /* we shouldn't get to this point */ + panic(); +} + +/***************************************************************************** + * Export the platform handlers via plat_arm_psci_pm_ops. The ARM Standard + * platform layer will take care of registering the handlers with PSCI. + ***************************************************************************** + */ +const plat_psci_ops_t plat_arm_psci_pm_ops = { + .cpu_standby = a8k_cpu_standby, + .pwr_domain_on = a8k_pwr_domain_on, + .pwr_domain_off = a8k_pwr_domain_off, + .pwr_domain_suspend = a8k_pwr_domain_suspend, + .pwr_domain_on_finish = a8k_pwr_domain_on_finish, + .get_sys_suspend_power_state = a8k_get_sys_suspend_power_state, + .pwr_domain_suspend_finish = a8k_pwr_domain_suspend_finish, + .pwr_domain_pwr_down_wfi = a8k_pwr_domain_pwr_down_wfi, + .system_off = a8k_system_off, + .system_reset = a8k_system_reset, + .validate_power_state = a8k_validate_power_state, + .validate_ns_entrypoint = a8k_validate_ns_entrypoint +}; diff --git a/plat/marvell/armada/a8k/common/plat_pm_trace.c b/plat/marvell/armada/a8k/common/plat_pm_trace.c new file mode 100644 index 000000000..f589ff31b --- /dev/null +++ b/plat/marvell/armada/a8k/common/plat_pm_trace.c @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include + +#include +#include + +#ifdef PM_TRACE_ENABLE + +/* core trace APIs */ +core_trace_func funcTbl[PLATFORM_CORE_COUNT] = { + pm_core_0_trace, + pm_core_1_trace, + pm_core_2_trace, + pm_core_3_trace}; + +/***************************************************************************** + * pm_core0_trace + * pm_core1_trace + * pm_core2_trace + * pm_core_3trace + * + * This functions set trace info into core cyclic trace queue in MSS SRAM + * memory space + ***************************************************************************** + */ +void pm_core_0_trace(unsigned int trace) +{ + unsigned int current_position_core_0 = + mmio_read_32(AP_MSS_ATF_CORE_0_CTRL_BASE); + mmio_write_32((AP_MSS_ATF_CORE_0_INFO_BASE + + (current_position_core_0 * AP_MSS_ATF_CORE_ENTRY_SIZE)), + mmio_read_32(AP_MSS_TIMER_BASE)); + mmio_write_32((AP_MSS_ATF_CORE_0_INFO_TRACE + + (current_position_core_0 * AP_MSS_ATF_CORE_ENTRY_SIZE)), + trace); + mmio_write_32(AP_MSS_ATF_CORE_0_CTRL_BASE, + ((current_position_core_0 + 1) & + AP_MSS_ATF_TRACE_SIZE_MASK)); +} + +void pm_core_1_trace(unsigned int trace) +{ + unsigned int current_position_core_1 = + mmio_read_32(AP_MSS_ATF_CORE_1_CTRL_BASE); + mmio_write_32((AP_MSS_ATF_CORE_1_INFO_BASE + + (current_position_core_1 * AP_MSS_ATF_CORE_ENTRY_SIZE)), + mmio_read_32(AP_MSS_TIMER_BASE)); + mmio_write_32((AP_MSS_ATF_CORE_1_INFO_TRACE + + (current_position_core_1 * AP_MSS_ATF_CORE_ENTRY_SIZE)), + trace); + mmio_write_32(AP_MSS_ATF_CORE_1_CTRL_BASE, + ((current_position_core_1 + 1) & + AP_MSS_ATF_TRACE_SIZE_MASK)); +} + +void pm_core_2_trace(unsigned int trace) +{ + unsigned int current_position_core_2 = + mmio_read_32(AP_MSS_ATF_CORE_2_CTRL_BASE); + mmio_write_32((AP_MSS_ATF_CORE_2_INFO_BASE + + (current_position_core_2 * AP_MSS_ATF_CORE_ENTRY_SIZE)), + mmio_read_32(AP_MSS_TIMER_BASE)); + mmio_write_32((AP_MSS_ATF_CORE_2_INFO_TRACE + + (current_position_core_2 * AP_MSS_ATF_CORE_ENTRY_SIZE)), + trace); + mmio_write_32(AP_MSS_ATF_CORE_2_CTRL_BASE, + ((current_position_core_2 + 1) & + AP_MSS_ATF_TRACE_SIZE_MASK)); +} + +void pm_core_3_trace(unsigned int trace) +{ + unsigned int current_position_core_3 = + mmio_read_32(AP_MSS_ATF_CORE_3_CTRL_BASE); + mmio_write_32((AP_MSS_ATF_CORE_3_INFO_BASE + + (current_position_core_3 * AP_MSS_ATF_CORE_ENTRY_SIZE)), + mmio_read_32(AP_MSS_TIMER_BASE)); + mmio_write_32((AP_MSS_ATF_CORE_3_INFO_TRACE + + (current_position_core_3 * AP_MSS_ATF_CORE_ENTRY_SIZE)), + trace); + mmio_write_32(AP_MSS_ATF_CORE_3_CTRL_BASE, + ((current_position_core_3 + 1) & + AP_MSS_ATF_TRACE_SIZE_MASK)); +} +#endif /* PM_TRACE_ENABLE */ diff --git a/plat/marvell/armada/a8k/common/plat_thermal.c b/plat/marvell/armada/a8k/common/plat_thermal.c new file mode 100644 index 000000000..a2fc0d0ab --- /dev/null +++ b/plat/marvell/armada/a8k/common/plat_thermal.c @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include +#include +#include + +#include + +#define THERMAL_TIMEOUT 1200 + +#define THERMAL_SEN_CTRL_LSB_STRT_OFFSET 0 +#define THERMAL_SEN_CTRL_LSB_STRT_MASK \ + (0x1 << THERMAL_SEN_CTRL_LSB_STRT_OFFSET) +#define THERMAL_SEN_CTRL_LSB_RST_OFFSET 1 +#define THERMAL_SEN_CTRL_LSB_RST_MASK \ + (0x1 << THERMAL_SEN_CTRL_LSB_RST_OFFSET) +#define THERMAL_SEN_CTRL_LSB_EN_OFFSET 2 +#define THERMAL_SEN_CTRL_LSB_EN_MASK \ + (0x1 << THERMAL_SEN_CTRL_LSB_EN_OFFSET) + +#define THERMAL_SEN_CTRL_STATS_VALID_OFFSET 16 +#define THERMAL_SEN_CTRL_STATS_VALID_MASK \ + (0x1 << THERMAL_SEN_CTRL_STATS_VALID_OFFSET) +#define THERMAL_SEN_CTRL_STATS_TEMP_OUT_OFFSET 0 +#define THERMAL_SEN_CTRL_STATS_TEMP_OUT_MASK \ + (0x3FF << THERMAL_SEN_CTRL_STATS_TEMP_OUT_OFFSET) + +#define THERMAL_SEN_OUTPUT_MSB 512 +#define THERMAL_SEN_OUTPUT_COMP 1024 + +struct tsen_regs { + uint32_t ext_tsen_ctrl_lsb; + uint32_t ext_tsen_ctrl_msb; + uint32_t ext_tsen_status; +}; + +static int ext_tsen_probe(struct tsen_config *tsen_cfg) +{ + uint32_t reg, timeout = 0; + struct tsen_regs *base; + + if (tsen_cfg == NULL && tsen_cfg->regs_base == NULL) { + ERROR("initial thermal sensor configuration is missing\n"); + return -1; + } + base = (struct tsen_regs *)tsen_cfg->regs_base; + + INFO("initializing thermal sensor\n"); + + /* initialize thermal sensor hardware reset once */ + reg = mmio_read_32((uintptr_t)&base->ext_tsen_ctrl_lsb); + reg &= ~THERMAL_SEN_CTRL_LSB_RST_OFFSET; /* de-assert TSEN_RESET */ + reg |= THERMAL_SEN_CTRL_LSB_EN_MASK; /* set TSEN_EN to 1 */ + reg |= THERMAL_SEN_CTRL_LSB_STRT_MASK; /* set TSEN_START to 1 */ + mmio_write_32((uintptr_t)&base->ext_tsen_ctrl_lsb, reg); + + reg = mmio_read_32((uintptr_t)&base->ext_tsen_status); + while ((reg & THERMAL_SEN_CTRL_STATS_VALID_MASK) == 0 && + timeout < THERMAL_TIMEOUT) { + udelay(100); + reg = mmio_read_32((uintptr_t)&base->ext_tsen_status); + timeout++; + } + + if ((reg & THERMAL_SEN_CTRL_STATS_VALID_MASK) == 0) { + ERROR("thermal sensor is not ready\n"); + return -1; + } + + tsen_cfg->tsen_ready = 1; + + VERBOSE("thermal sensor was initialized\n"); + + return 0; +} + +static int ext_tsen_read(struct tsen_config *tsen_cfg, int *temp) +{ + uint32_t reg; + struct tsen_regs *base; + + if (tsen_cfg == NULL && !tsen_cfg->tsen_ready) { + ERROR("thermal sensor was not initialized\n"); + return -1; + } + base = (struct tsen_regs *)tsen_cfg->regs_base; + + reg = mmio_read_32((uintptr_t)&base->ext_tsen_status); + reg = ((reg & THERMAL_SEN_CTRL_STATS_TEMP_OUT_MASK) >> + THERMAL_SEN_CTRL_STATS_TEMP_OUT_OFFSET); + + /* + * TSEN output format is signed as a 2s complement number + * ranging from-512 to +511. when MSB is set, need to + * calculate the complement number + */ + if (reg >= THERMAL_SEN_OUTPUT_MSB) + reg -= THERMAL_SEN_OUTPUT_COMP; + + if (tsen_cfg->tsen_divisor == 0) { + ERROR("thermal sensor divisor cannot be zero\n"); + return -1; + } + + *temp = ((tsen_cfg->tsen_gain * ((int)reg)) + + tsen_cfg->tsen_offset) / tsen_cfg->tsen_divisor; + + return 0; +} + +static struct tsen_config tsen_cfg = { + .tsen_offset = 153400, + .tsen_gain = 425, + .tsen_divisor = 1000, + .tsen_ready = 0, + .regs_base = (void *)MVEBU_AP_EXT_TSEN_BASE, + .ptr_tsen_probe = ext_tsen_probe, + .ptr_tsen_read = ext_tsen_read +}; + +struct tsen_config *marvell_thermal_config_get(void) +{ + return &tsen_cfg; +} diff --git a/plat/marvell/armada/common/aarch64/marvell_bl2_mem_params_desc.c b/plat/marvell/armada/common/aarch64/marvell_bl2_mem_params_desc.c new file mode 100644 index 000000000..6a8e11c90 --- /dev/null +++ b/plat/marvell/armada/common/aarch64/marvell_bl2_mem_params_desc.c @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * + * 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 + * 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[] = { +#ifdef SCP_BL2_BASE + /* Fill SCP_BL2 related information if it exists */ + { + .image_id = SCP_BL2_IMAGE_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, 0), + .image_info.image_base = SCP_BL2_BASE, + .image_info.image_max_size = SCP_BL2_SIZE, + + .next_handoff_image_id = INVALID_IMAGE_ID, + }, +#endif /* SCP_BL2_BASE */ + +#ifdef EL3_PAYLOAD_BASE + /* Fill EL3 payload related information (BL31 is EL3 payload)*/ + { + .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 = EL3_PAYLOAD_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_ATTRIB_SKIP_LOADING), + + .next_handoff_image_id = INVALID_IMAGE_ID, + }, + +#else /* EL3_PAYLOAD_BASE */ + + /* Fill BL31 related information */ + { + .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), +#if DEBUG + .ep_info.args.arg3 = MARVELL_BL31_PLAT_PARAM_VAL, +#endif + + 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, + +# ifdef BL32_BASE + .next_handoff_image_id = BL32_IMAGE_ID, +# else + .next_handoff_image_id = BL33_IMAGE_ID, +# endif + }, + +# ifdef BL32_BASE + /* 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_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_LIMIT - BL32_BASE, + + .next_handoff_image_id = BL33_IMAGE_ID, + }, +# endif /* BL32_BASE */ + + /* 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), +# ifdef PRELOADED_BL33_BASE + .ep_info.pc = PRELOADED_BL33_BASE, + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, + VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING), +# else + .ep_info.pc = MARVELL_DRAM_BASE, + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, + VERSION_2, image_info_t, 0), + .image_info.image_base = MARVELL_DRAM_BASE, + .image_info.image_max_size = MARVELL_DRAM_SIZE, +# endif /* PRELOADED_BL33_BASE */ + + .next_handoff_image_id = INVALID_IMAGE_ID, + } +#endif /* EL3_PAYLOAD_BASE */ +}; + +REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs) diff --git a/plat/marvell/armada/common/aarch64/marvell_common.c b/plat/marvell/armada/common/aarch64/marvell_common.c new file mode 100644 index 000000000..21a62d483 --- /dev/null +++ b/plat/marvell/armada/common/aarch64/marvell_common.c @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +/* Weak definitions may be overridden in specific ARM standard platform */ +#pragma weak plat_get_ns_image_entrypoint +#pragma weak plat_marvell_get_mmap + +/* + * Set up the page tables for the generic and platform-specific memory regions. + * The extents of the generic memory regions are specified by the function + * arguments and consist of: + * - Trusted SRAM seen by the BL image; + * - Code section; + * - Read-only data section; + * - Coherent memory region, if applicable. + */ +void marvell_setup_page_tables(uintptr_t total_base, + size_t total_size, + uintptr_t code_start, + uintptr_t code_limit, + uintptr_t rodata_start, + uintptr_t rodata_limit +#if USE_COHERENT_MEM + , + uintptr_t coh_start, + uintptr_t coh_limit +#endif + ) +{ + /* + * Map the Trusted SRAM with appropriate memory attributes. + * Subsequent mappings will adjust the attributes for specific regions. + */ + VERBOSE("Trusted SRAM seen by this BL image: %p - %p\n", + (void *) total_base, (void *) (total_base + total_size)); + mmap_add_region(total_base, total_base, + total_size, + MT_MEMORY | MT_RW | MT_SECURE); + + /* Re-map the code section */ + VERBOSE("Code region: %p - %p\n", + (void *) code_start, (void *) code_limit); + mmap_add_region(code_start, code_start, + code_limit - code_start, + MT_CODE | MT_SECURE); + + /* Re-map the read-only data section */ + VERBOSE("Read-only data region: %p - %p\n", + (void *) rodata_start, (void *) rodata_limit); + mmap_add_region(rodata_start, rodata_start, + rodata_limit - rodata_start, + MT_RO_DATA | MT_SECURE); + +#if USE_COHERENT_MEM + /* Re-map the coherent memory region */ + VERBOSE("Coherent region: %p - %p\n", + (void *) coh_start, (void *) coh_limit); + mmap_add_region(coh_start, coh_start, + coh_limit - coh_start, + MT_DEVICE | MT_RW | MT_SECURE); +#endif + + /* Now (re-)map the platform-specific memory regions */ + mmap_add(plat_marvell_get_mmap()); + + /* Create the page tables to reflect the above mappings */ + init_xlat_tables(); +} + +unsigned long plat_get_ns_image_entrypoint(void) +{ + return PLAT_MARVELL_NS_IMAGE_OFFSET; +} + +/***************************************************************************** + * Gets SPSR for BL32 entry + ***************************************************************************** + */ +uint32_t marvell_get_spsr_for_bl32_entry(void) +{ + /* + * The Secure Payload Dispatcher service is responsible for + * setting the SPSR prior to entry into the BL32 image. + */ + return 0; +} + +/***************************************************************************** + * Gets SPSR for BL33 entry + ***************************************************************************** + */ +uint32_t marvell_get_spsr_for_bl33_entry(void) +{ + unsigned long el_status; + unsigned int mode; + uint32_t spsr; + + /* Figure out what mode we enter the non-secure world in */ + el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT; + el_status &= ID_AA64PFR0_ELX_MASK; + + mode = (el_status) ? MODE_EL2 : MODE_EL1; + + /* + * TODO: Consider the possibility of specifying the SPSR in + * the FIP ToC and allowing the platform to have a say as + * well. + */ + spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); + return spsr; +} + +/***************************************************************************** + * Returns ARM platform specific memory map regions. + ***************************************************************************** + */ +const mmap_region_t *plat_marvell_get_mmap(void) +{ + return plat_marvell_mmap; +} + diff --git a/plat/marvell/armada/common/aarch64/marvell_helpers.S b/plat/marvell/armada/common/aarch64/marvell_helpers.S new file mode 100644 index 000000000..6f625b95d --- /dev/null +++ b/plat/marvell/armada/common/aarch64/marvell_helpers.S @@ -0,0 +1,250 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include +#ifndef PLAT_a3700 +#include +#include +#endif +#include +#include + + .weak plat_marvell_calc_core_pos + .weak plat_my_core_pos + .globl plat_crash_console_init + .globl plat_crash_console_putc + .globl plat_crash_console_flush + .globl platform_mem_init + .globl disable_mmu_dcache + .globl invalidate_tlb_all + .globl platform_unmap_sram + .globl disable_sram + .globl disable_icache + .globl invalidate_icache_all + .globl marvell_exit_bootrom + .globl ca72_l2_enable_unique_clean + + /* ----------------------------------------------------- + * unsigned int plat_my_core_pos(void) + * This function uses the plat_marvell_calc_core_pos() + * definition to get the index of the calling CPU. + * ----------------------------------------------------- + */ +func plat_my_core_pos + mrs x0, mpidr_el1 + b plat_marvell_calc_core_pos +endfunc plat_my_core_pos + + /* ----------------------------------------------------- + * unsigned int plat_marvell_calc_core_pos(uint64_t mpidr) + * Helper function to calculate the core position. + * With this function: CorePos = (ClusterId * 2) + + * CoreId + * ----------------------------------------------------- + */ +func plat_marvell_calc_core_pos + and x1, x0, #MPIDR_CPU_MASK + and x0, x0, #MPIDR_CLUSTER_MASK + add x0, x1, x0, LSR #7 + ret +endfunc plat_marvell_calc_core_pos + + /* --------------------------------------------- + * int plat_crash_console_init(void) + * Function to initialize the crash console + * without a C Runtime to print crash report. + * Clobber list : x0, x1, x2 + * --------------------------------------------- + */ +func plat_crash_console_init + mov_imm x0, PLAT_MARVELL_CRASH_UART_BASE + mov_imm x1, PLAT_MARVELL_CRASH_UART_CLK_IN_HZ + mov_imm x2, MARVELL_CONSOLE_BAUDRATE +#ifdef PLAT_a3700 + b console_a3700_core_init +#else + b console_16550_core_init +#endif +endfunc plat_crash_console_init + + /* --------------------------------------------- + * int plat_crash_console_putc(int c) + * Function to print a character on the crash + * console without a C Runtime. + * Clobber list : x1, x2 + * --------------------------------------------- + */ +func plat_crash_console_putc + mov_imm x1, PLAT_MARVELL_CRASH_UART_BASE +#ifdef PLAT_a3700 + + b console_a3700_core_putc +#else + b console_16550_core_putc +#endif +endfunc plat_crash_console_putc + + /* --------------------------------------------- + * int plat_crash_console_flush() + * Function to force a write of all buffered + * data that hasn't been output. + * Out : return -1 on error else return 0. + * Clobber list : r0 + * --------------------------------------------- + */ +func plat_crash_console_flush + mov_imm x0, PLAT_MARVELL_CRASH_UART_BASE +#ifdef PLAT_a3700 + b console_a3700_core_flush +#else + b console_16550_core_flush +#endif +endfunc plat_crash_console_flush + + /* --------------------------------------------------------------------- + * We don't need to carry out any memory initialization on ARM + * platforms. The Secure RAM is accessible straight away. + * --------------------------------------------------------------------- + */ +func platform_mem_init + ret +endfunc platform_mem_init + + /* ----------------------------------------------------- + * Disable icache, dcache, and MMU + * ----------------------------------------------------- + */ +func disable_mmu_dcache + mrs x0, sctlr_el3 + bic x0, x0, 0x1 /* M bit - MMU */ + bic x0, x0, 0x4 /* C bit - Dcache L1 & L2 */ + msr sctlr_el3, x0 + isb + b mmu_off +mmu_off: + ret +endfunc disable_mmu_dcache + + /* ----------------------------------------------------- + * Disable all TLB entries + * ----------------------------------------------------- + */ +func invalidate_tlb_all + tlbi alle3 + dsb sy + isb + ret +endfunc invalidate_tlb_all + + /* ----------------------------------------------------- + * Disable the i cache + * ----------------------------------------------------- + */ +func disable_icache + mrs x0, sctlr_el3 + bic x0, x0, 0x1000 /* I bit - Icache L1 & L2 */ + msr sctlr_el3, x0 + isb + ret +endfunc disable_icache + + /* ----------------------------------------------------- + * Disable all of the i caches + * ----------------------------------------------------- + */ +func invalidate_icache_all + ic ialluis + isb sy + ret +endfunc invalidate_icache_all + + /* ----------------------------------------------------- + * Clear the SRAM enabling bit to unmap SRAM + * ----------------------------------------------------- + */ +func platform_unmap_sram + ldr x0, =CCU_SRAM_WIN_CR + str wzr, [x0] + ret +endfunc platform_unmap_sram + + /* ----------------------------------------------------- + * Disable the SRAM + * ----------------------------------------------------- + */ +func disable_sram + /* Disable the line lockings. They must be disabled expictly + * or the OS will have problems using the cache */ + ldr x1, =MASTER_LLC_TC0_LOCK + str wzr, [x1] + + /* Invalidate all ways */ + ldr w1, =LLC_WAY_MASK + ldr x0, =MASTER_L2X0_INV_WAY + str w1, [x0] + + /* Finally disable LLC */ + ldr x0, =MASTER_LLC_CTRL + str wzr, [x0] + + ret +endfunc disable_sram + + /* ----------------------------------------------------- + * Operation when exit bootROM: + * Disable the MMU + * Disable and invalidate the dcache + * Unmap and disable the SRAM + * Disable and invalidate the icache + * ----------------------------------------------------- + */ +func marvell_exit_bootrom + /* Save the system restore address */ + mov x28, x0 + + /* Close the caches and MMU */ + bl disable_mmu_dcache + + /* + * There is nothing important in the caches now, + * so invalidate them instead of cleaning. + */ + adr x0, __RW_START__ + adr x1, __RW_END__ + sub x1, x1, x0 + bl inv_dcache_range + bl invalidate_tlb_all + + /* + * Clean the memory mapping of SRAM + * the DDR mapping will remain to enable boot image to execute + */ + bl platform_unmap_sram + + /* Disable the SRAM */ + bl disable_sram + + /* Disable and invalidate icache */ + bl disable_icache + bl invalidate_icache_all + + mov x0, x28 + br x0 +endfunc marvell_exit_bootrom + + /* + * Enable L2 UniqueClean evictions with data + */ +func ca72_l2_enable_unique_clean + + mrs x0, CORTEX_A72_L2ACTLR_EL1 + orr x0, x0, #CORTEX_A72_L2ACTLR_ENABLE_UNIQUE_CLEAN + msr CORTEX_A72_L2ACTLR_EL1, x0 + + ret +endfunc ca72_l2_enable_unique_clean diff --git a/plat/marvell/armada/common/marvell_bl1_setup.c b/plat/marvell/armada/common/marvell_bl1_setup.c new file mode 100644 index 000000000..7b7cef39b --- /dev/null +++ b/plat/marvell/armada/common/marvell_bl1_setup.c @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include + +/* Weak definitions may be overridden in specific Marvell standard platform */ +#pragma weak bl1_early_platform_setup +#pragma weak bl1_plat_arch_setup +#pragma weak bl1_platform_setup +#pragma weak bl1_plat_sec_mem_layout + +/* Data structure which holds the extents of the RAM for BL1*/ +static meminfo_t bl1_ram_layout; + +meminfo_t *bl1_plat_sec_mem_layout(void) +{ + return &bl1_ram_layout; +} + +/* + * BL1 specific platform actions shared between Marvell standard platforms. + */ +void marvell_bl1_early_platform_setup(void) +{ + /* Initialize the console to provide early debug support */ + marvell_console_boot_init(); + + /* Allow BL1 to see the whole Trusted RAM */ + bl1_ram_layout.total_base = MARVELL_BL_RAM_BASE; + bl1_ram_layout.total_size = MARVELL_BL_RAM_SIZE; +} + +void bl1_early_platform_setup(void) +{ + marvell_bl1_early_platform_setup(); +} + +/* + * Perform the very early platform specific architecture setup shared between + * MARVELL standard platforms. This only does basic initialization. Later + * architectural setup (bl1_arch_setup()) does not do anything platform + * specific. + */ +void marvell_bl1_plat_arch_setup(void) +{ + marvell_setup_page_tables(bl1_ram_layout.total_base, + bl1_ram_layout.total_size, + BL1_RO_BASE, + BL1_RO_LIMIT, + BL1_RO_DATA_BASE, + BL1_RO_DATA_END +#if USE_COHERENT_MEM + , BL_COHERENT_RAM_BASE, + BL_COHERENT_RAM_END +#endif + ); + enable_mmu_el3(0); +} + +void bl1_plat_arch_setup(void) +{ + marvell_bl1_plat_arch_setup(); +} + +/* + * Perform the platform specific architecture setup shared between + * MARVELL standard platforms. + */ +void marvell_bl1_platform_setup(void) +{ + /* Initialise the IO layer and register platform IO devices */ + plat_marvell_io_setup(); +} + +void bl1_platform_setup(void) +{ + marvell_bl1_platform_setup(); +} + +void bl1_plat_prepare_exit(entry_point_info_t *ep_info) +{ +#ifdef EL3_PAYLOAD_BASE + /* + * Program the EL3 payload's entry point address into the CPUs mailbox + * in order to release secondary CPUs from their holding pen and make + * them jump there. + */ + marvell_program_trusted_mailbox(ep_info->pc); + dsbsy(); + sev(); +#endif +} diff --git a/plat/marvell/armada/common/marvell_bl2_setup.c b/plat/marvell/armada/common/marvell_bl2_setup.c new file mode 100644 index 000000000..3c1c39112 --- /dev/null +++ b/plat/marvell/armada/common/marvell_bl2_setup.c @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +/* Data structure which holds the extents of the trusted SRAM for BL2 */ +static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE); + +/* Weak definitions may be overridden in specific MARVELL standard platform */ +#pragma weak bl2_early_platform_setup2 +#pragma weak bl2_platform_setup +#pragma weak bl2_plat_arch_setup +#pragma weak bl2_plat_sec_mem_layout + +meminfo_t *bl2_plat_sec_mem_layout(void) +{ + return &bl2_tzram_layout; +} + +/***************************************************************************** + * BL1 has passed the extents of the trusted SRAM that should be visible to BL2 + * in x0. This memory layout is sitting at the base of the free trusted SRAM. + * Copy it to a safe location before its reclaimed by later BL2 functionality. + ***************************************************************************** + */ +void marvell_bl2_early_platform_setup(meminfo_t *mem_layout) +{ + /* Initialize the console to provide early debug support */ + marvell_console_boot_init(); + + /* Setup the BL2 memory layout */ + bl2_tzram_layout = *mem_layout; + + /* Initialise the IO layer and register platform IO devices */ + plat_marvell_io_setup(); +} + + +void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, + u_register_t arg2, u_register_t arg3) +{ + struct meminfo *mem_layout = (struct meminfo *)arg1; + + marvell_bl2_early_platform_setup(mem_layout); +} + +void bl2_platform_setup(void) +{ + /* Nothing to do */ +} + +/***************************************************************************** + * Perform the very early platform specific architectural setup here. At the + * moment this is only initializes the mmu in a quick and dirty way. + ***************************************************************************** + */ +void marvell_bl2_plat_arch_setup(void) +{ + marvell_setup_page_tables(bl2_tzram_layout.total_base, + bl2_tzram_layout.total_size, + BL_CODE_BASE, + BL_CODE_END, + BL_RO_DATA_BASE, + BL_RO_DATA_END +#if USE_COHERENT_MEM + , BL_COHERENT_RAM_BASE, + BL_COHERENT_RAM_END +#endif + ); + enable_mmu_el1(0); +} + +void bl2_plat_arch_setup(void) +{ + marvell_bl2_plat_arch_setup(); +} + +int marvell_bl2_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); + + assert(bl_mem_params); + + switch (image_id) { + + case BL33_IMAGE_ID: + /* BL33 expects to receive the primary CPU MPID (through r0) */ + bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr(); + bl_mem_params->ep_info.spsr = marvell_get_spsr_for_bl33_entry(); + break; +#ifdef SCP_BL2_BASE + case SCP_BL2_IMAGE_ID: + /* The subsequent handling of SCP_BL2 is platform specific */ + err = bl2_plat_handle_scp_bl2(&bl_mem_params->image_info); + if (err) { + WARN("Failure in platform-specific handling of SCP_BL2 image.\n"); + } + break; +#endif + default: + /* Do nothing in default case */ + break; + } + + return err; + +} + +/******************************************************************************* + * This function can be used by the platforms to update/use image + * information for given `image_id`. + ******************************************************************************/ +int bl2_plat_handle_post_image_load(unsigned int image_id) +{ + return marvell_bl2_handle_post_image_load(image_id); +} + diff --git a/plat/marvell/armada/common/marvell_bl31_setup.c b/plat/marvell/armada/common/marvell_bl31_setup.c new file mode 100644 index 000000000..26ba90654 --- /dev/null +++ b/plat/marvell/armada/common/marvell_bl31_setup.c @@ -0,0 +1,237 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include +#include +#include +#ifdef USE_CCI +#include +#endif +#include +#include + +#include +#include +#include + +/* + * Placeholder variables for copying the arguments that have been passed to + * BL31 from BL2. + */ +static entry_point_info_t bl32_image_ep_info; +static entry_point_info_t bl33_image_ep_info; + +/* Weak definitions may be overridden in specific ARM standard platform */ +#pragma weak bl31_early_platform_setup2 +#pragma weak bl31_platform_setup +#pragma weak bl31_plat_arch_setup +#pragma weak bl31_plat_get_next_image_ep_info +#pragma weak plat_get_syscnt_freq2 + +/***************************************************************************** + * Return a pointer to the 'entry_point_info' structure of the next image for + * the security state specified. BL33 corresponds to the non-secure image type + * while BL32 corresponds to the secure image type. A NULL pointer is returned + * if the image does not exist. + ***************************************************************************** + */ +entry_point_info_t *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; + + return next_image_info; +} + +/***************************************************************************** + * Perform any BL31 early platform setup common to ARM standard platforms. + * Here is an opportunity to copy parameters passed by the calling EL (S-EL1 + * in BL2 & EL3 in BL1) before they are lost (potentially). This needs to be + * done before the MMU is initialized so that the memory layout can be used + * while creating page tables. BL2 has flushed this information to memory, so + * we are guaranteed to pick up good data. + ***************************************************************************** + */ +void marvell_bl31_early_platform_setup(void *from_bl2, + uintptr_t soc_fw_config, + uintptr_t hw_config, + void *plat_params_from_bl2) +{ + /* Initialize the console to provide early debug support */ + marvell_console_boot_init(); + +#if RESET_TO_BL31 + /* There are no parameters from BL2 if BL31 is a reset vector */ + assert(from_bl2 == NULL); + assert(plat_params_from_bl2 == NULL); + +#ifdef BL32_BASE + /* Populate entry point information for BL32 */ + SET_PARAM_HEAD(&bl32_image_ep_info, + PARAM_EP, + VERSION_1, + 0); + SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE); + bl32_image_ep_info.pc = BL32_BASE; + bl32_image_ep_info.spsr = marvell_get_spsr_for_bl32_entry(); +#endif /* BL32_BASE */ + + /* Populate entry point information for BL33 */ + SET_PARAM_HEAD(&bl33_image_ep_info, + PARAM_EP, + VERSION_1, + 0); + /* + * Tell BL31 where the non-trusted software image + * is located and the entry state information + */ + bl33_image_ep_info.pc = plat_get_ns_image_entrypoint(); + bl33_image_ep_info.spsr = marvell_get_spsr_for_bl33_entry(); + SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); + +#else + /* + * In debug builds, we pass a special value in 'plat_params_from_bl2' + * to verify platform parameters from BL2 to BL31. + * In release builds, it's not used. + */ + assert(((unsigned long long)plat_params_from_bl2) == + MARVELL_BL31_PLAT_PARAM_VAL); + + /* + * Check params passed from BL2 should not be NULL, + */ + bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2; + assert(params_from_bl2 != NULL); + assert(params_from_bl2->h.type == PARAM_BL_PARAMS); + assert(params_from_bl2->h.version >= VERSION_2); + + bl_params_node_t *bl_params = params_from_bl2->head; + + /* + * Copy BL33 and BL32 (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) + bl32_image_ep_info = *bl_params->ep_info; + + if (bl_params->image_id == BL33_IMAGE_ID) + bl33_image_ep_info = *bl_params->ep_info; + + bl_params = bl_params->next_params_info; + } +#endif +} + +void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, + u_register_t arg2, u_register_t arg3) + +{ + marvell_bl31_early_platform_setup((void *)arg0, arg1, arg2, + (void *)arg3); + +#ifdef USE_CCI + /* + * Initialize CCI for this cluster during cold boot. + * No need for locks as no other CPU is active. + */ + plat_marvell_interconnect_init(); + + /* + * Enable CCI coherency for the primary CPU's cluster. + * Platform specific PSCI code will enable coherency for other + * clusters. + */ + plat_marvell_interconnect_enter_coherency(); +#endif +} + +/***************************************************************************** + * Perform any BL31 platform setup common to ARM standard platforms + ***************************************************************************** + */ +void marvell_bl31_platform_setup(void) +{ + /* Initialize the GIC driver, cpu and distributor interfaces */ + plat_marvell_gic_driver_init(); + plat_marvell_gic_init(); + + /* For Armada-8k-plus family, the SoC includes more than + * a single AP die, but the default die that boots is AP #0. + * For other families there is only one die (#0). + * Initialize psci arch from die 0 + */ + marvell_psci_arch_init(0); +} + +/***************************************************************************** + * Perform any BL31 platform runtime setup prior to BL31 exit common to ARM + * standard platforms + ***************************************************************************** + */ +void marvell_bl31_plat_runtime_setup(void) +{ + console_switch_state(CONSOLE_FLAG_RUNTIME); + + /* Initialize the runtime console */ + marvell_console_runtime_init(); +} + +void bl31_platform_setup(void) +{ + marvell_bl31_platform_setup(); +} + +void bl31_plat_runtime_setup(void) +{ + marvell_bl31_plat_runtime_setup(); +} + +/***************************************************************************** + * Perform the very early platform specific architectural setup shared between + * ARM standard platforms. This only does basic initialization. Later + * architectural setup (bl31_arch_setup()) does not do anything platform + * specific. + ***************************************************************************** + */ +void marvell_bl31_plat_arch_setup(void) +{ + marvell_setup_page_tables(BL31_BASE, + BL31_END - BL31_BASE, + BL_CODE_BASE, + BL_CODE_END, + BL_RO_DATA_BASE, + BL_RO_DATA_END +#if USE_COHERENT_MEM + , BL_COHERENT_RAM_BASE, + BL_COHERENT_RAM_END +#endif + ); + +#if BL31_CACHE_DISABLE + enable_mmu_el3(DISABLE_DCACHE); + INFO("Cache is disabled in BL3\n"); +#else + enable_mmu_el3(0); +#endif +} + +void bl31_plat_arch_setup(void) +{ + marvell_bl31_plat_arch_setup(); +} + +unsigned int plat_get_syscnt_freq2(void) +{ + return PLAT_REF_CLK_IN_HZ; +} diff --git a/plat/marvell/armada/common/marvell_cci.c b/plat/marvell/armada/common/marvell_cci.c new file mode 100644 index 000000000..80351aedc --- /dev/null +++ b/plat/marvell/armada/common/marvell_cci.c @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include + +static const int cci_map[] = { + PLAT_MARVELL_CCI_CLUSTER0_SL_IFACE_IX, + PLAT_MARVELL_CCI_CLUSTER1_SL_IFACE_IX +}; + +/**************************************************************************** + * The following functions are defined as weak to allow a platform to override + * the way ARM CCI driver is initialised and used. + **************************************************************************** + */ +#pragma weak plat_marvell_interconnect_init +#pragma weak plat_marvell_interconnect_enter_coherency +#pragma weak plat_marvell_interconnect_exit_coherency + + +/**************************************************************************** + * Helper function to initialize ARM CCI driver. + **************************************************************************** + */ +void plat_marvell_interconnect_init(void) +{ + cci_init(PLAT_MARVELL_CCI_BASE, cci_map, ARRAY_SIZE(cci_map)); +} + +/**************************************************************************** + * Helper function to place current master into coherency + **************************************************************************** + */ +void plat_marvell_interconnect_enter_coherency(void) +{ + cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr_el1())); +} + +/**************************************************************************** + * Helper function to remove current master from coherency + **************************************************************************** + */ +void plat_marvell_interconnect_exit_coherency(void) +{ + cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr_el1())); +} diff --git a/plat/marvell/armada/common/marvell_common.mk b/plat/marvell/armada/common/marvell_common.mk new file mode 100644 index 000000000..f5f0c416e --- /dev/null +++ b/plat/marvell/armada/common/marvell_common.mk @@ -0,0 +1,72 @@ +# Copyright (C) 2018 Marvell International Ltd. +# +# SPDX-License-Identifier: BSD-3-Clause +# https://spdx.org/licenses + +MARVELL_PLAT_BASE := plat/marvell/armada +MARVELL_PLAT_INCLUDE_BASE := include/plat/marvell/armada + +include plat/marvell/version.mk +include plat/marvell/marvell.mk + +VERSION_STRING +=(Marvell-${SUBVERSION}) + +SEPARATE_CODE_AND_RODATA := 1 + +# flag to switch from PLL to ARO +ARO_ENABLE := 0 +$(eval $(call add_define,ARO_ENABLE)) +# Enable/Disable LLC +LLC_ENABLE := 1 +$(eval $(call add_define,LLC_ENABLE)) + +include lib/xlat_tables_v2/xlat_tables.mk + +PLAT_INCLUDES += -I$(MARVELL_PLAT_INCLUDE_BASE)/common \ + -I$(MARVELL_PLAT_INCLUDE_BASE)/common/aarch64 + + +PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS} \ + $(MARVELL_PLAT_BASE)/common/aarch64/marvell_common.c \ + $(MARVELL_PLAT_BASE)/common/aarch64/marvell_helpers.S \ + $(MARVELL_COMMON_BASE)/marvell_console.c + +BL1_SOURCES += drivers/delay_timer/delay_timer.c \ + drivers/io/io_fip.c \ + drivers/io/io_memmap.c \ + drivers/io/io_storage.c \ + $(MARVELL_PLAT_BASE)/common/marvell_bl1_setup.c \ + $(MARVELL_PLAT_BASE)/common/marvell_io_storage.c \ + $(MARVELL_PLAT_BASE)/common/plat_delay_timer.c + +ifdef EL3_PAYLOAD_BASE +# Need the arm_program_trusted_mailbox() function to release secondary CPUs from +# their holding pen +endif + +BL2_SOURCES += drivers/io/io_fip.c \ + drivers/io/io_memmap.c \ + drivers/io/io_storage.c \ + common/desc_image_load.c \ + $(MARVELL_PLAT_BASE)/common/marvell_bl2_setup.c \ + $(MARVELL_PLAT_BASE)/common/marvell_io_storage.c \ + $(MARVELL_PLAT_BASE)/common/aarch64/marvell_bl2_mem_params_desc.c \ + $(MARVELL_PLAT_BASE)/common/marvell_image_load.c + + +BL31_SOURCES += $(MARVELL_PLAT_BASE)/common/marvell_bl31_setup.c \ + $(MARVELL_PLAT_BASE)/common/marvell_pm.c \ + $(MARVELL_PLAT_BASE)/common/marvell_topology.c \ + plat/common/plat_psci_common.c \ + $(MARVELL_PLAT_BASE)/common/plat_delay_timer.c \ + drivers/delay_timer/delay_timer.c + +# PSCI functionality +$(eval $(call add_define,CONFIG_ARM64)) + +# MSS (SCP) build +ifeq (${MSS_SUPPORT}, 1) +include $(MARVELL_PLAT_BASE)/common/mss/mss_common.mk +endif + +fip: mrvl_flash diff --git a/plat/marvell/armada/common/marvell_console.c b/plat/marvell/armada/common/marvell_console.c new file mode 100644 index 000000000..17166618a --- /dev/null +++ b/plat/marvell/armada/common/marvell_console.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include + +#include + +#include +#include + +#include + +#ifdef PLAT_a3700 +#include +#define console_marvell_register console_a3700_register +#else +#include +#define console_marvell_register console_16550_register +#endif + +static console_t marvell_boot_console; +static console_t marvell_runtime_console; + +/******************************************************************************* + * Functions that set up the console + ******************************************************************************/ + +/* Initialize the console to provide early debug support */ +void marvell_console_boot_init(void) +{ + int rc = + console_marvell_register(PLAT_MARVELL_BOOT_UART_BASE, + PLAT_MARVELL_BOOT_UART_CLK_IN_HZ, + MARVELL_CONSOLE_BAUDRATE, + &marvell_boot_console); + if (rc == 0) { + /* + * The crash console doesn't use the multi console API, it uses + * the core console functions directly. It is safe to call panic + * and let it print debug information. + */ + panic(); + } + + console_set_scope(&marvell_boot_console, CONSOLE_FLAG_BOOT); +} + +void marvell_console_boot_end(void) +{ + (void)console_flush(); + + (void)console_unregister(&marvell_boot_console); +} + +/* Initialize the runtime console */ +void marvell_console_runtime_init(void) +{ + int rc = + console_marvell_register(PLAT_MARVELL_BOOT_UART_BASE, + PLAT_MARVELL_BOOT_UART_CLK_IN_HZ, + MARVELL_CONSOLE_BAUDRATE, + &marvell_runtime_console); + if (rc == 0) + panic(); + + console_set_scope(&marvell_runtime_console, CONSOLE_FLAG_RUNTIME); +} + +void marvell_console_runtime_end(void) +{ + (void)console_flush(); + + (void)console_unregister(&marvell_runtime_console); +} diff --git a/plat/marvell/armada/common/marvell_ddr_info.c b/plat/marvell/armada/common/marvell_ddr_info.c new file mode 100644 index 000000000..734099652 --- /dev/null +++ b/plat/marvell/armada/common/marvell_ddr_info.c @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include +#include + +#include + +#define DRAM_CH0_MMAP_LOW_REG(iface, cs, base) \ + (base + DRAM_CH0_MMAP_LOW_OFFSET + (iface) * 0x10000 + (cs) * 0x8) +#define DRAM_CH0_MMAP_HIGH_REG(iface, cs, base) \ + (DRAM_CH0_MMAP_LOW_REG(iface, cs, base) + 4) +#define DRAM_CS_VALID_ENABLED_MASK 0x1 +#define DRAM_AREA_LENGTH_OFFS 16 +#define DRAM_AREA_LENGTH_MASK (0x1f << DRAM_AREA_LENGTH_OFFS) +#define DRAM_START_ADDRESS_L_OFFS 23 +#define DRAM_START_ADDRESS_L_MASK \ + (0x1ff << DRAM_START_ADDRESS_L_OFFS) +#define DRAM_START_ADDR_HTOL_OFFS 32 + +#define DRAM_MAX_CS_NUM 2 + +#define DRAM_CS_ENABLED(iface, cs, base) \ + (mmio_read_32(DRAM_CH0_MMAP_LOW_REG(iface, cs, base)) & \ + DRAM_CS_VALID_ENABLED_MASK) +#define GET_DRAM_REGION_SIZE_CODE(iface, cs, base) \ + (mmio_read_32(DRAM_CH0_MMAP_LOW_REG(iface, cs, base)) & \ + DRAM_AREA_LENGTH_MASK) >> DRAM_AREA_LENGTH_OFFS + +/* Mapping between DDR area length and real DDR size is specific and looks like + * bellow: + * 0 => 384 MB + * 1 => 768 MB + * 2 => 1536 MB + * 3 => 3 GB + * 4 => 6 GB + * + * 7 => 8 MB + * 8 => 16 MB + * 9 => 32 MB + * 10 => 64 MB + * 11 => 128 MB + * 12 => 256 MB + * 13 => 512 MB + * 14 => 1 GB + * 15 => 2 GB + * 16 => 4 GB + * 17 => 8 GB + * 18 => 16 GB + * 19 => 32 GB + * 20 => 64 GB + * 21 => 128 GB + * 22 => 256 GB + * 23 => 512 GB + * 24 => 1 TB + * 25 => 2 TB + * 26 => 4 TB + * + * to calculate real size we need to use two different formulas: + * -- GET_DRAM_REGION_SIZE_ODD for values 0-4 (DRAM_REGION_SIZE_ODD) + * -- GET_DRAM_REGION_SIZE_EVEN for values 7-26 (DRAM_REGION_SIZE_EVEN) + * using mentioned formulas we cover whole mapping between "Area length" value + * and real size (see above mapping). + */ +#define DRAM_REGION_SIZE_EVEN(C) (((C) >= 7) && ((C) <= 26)) +#define GET_DRAM_REGION_SIZE_EVEN(C) ((uint64_t)1 << ((C) + 16)) +#define DRAM_REGION_SIZE_ODD(C) ((C) <= 4) +#define GET_DRAM_REGION_SIZE_ODD(C) ((uint64_t)0x18000000 << (C)) + + +uint64_t mvebu_get_dram_size(uint64_t ap_base_addr) +{ + uint64_t mem_size = 0; + uint8_t region_code; + uint8_t cs, iface; + + for (iface = 0; iface < DRAM_MAX_IFACE; iface++) { + for (cs = 0; cs < DRAM_MAX_CS_NUM; cs++) { + + /* Exit loop on first disabled DRAM CS */ + if (!DRAM_CS_ENABLED(iface, cs, ap_base_addr)) + break; + + /* Decode area length for current CS + * from register value + */ + region_code = + GET_DRAM_REGION_SIZE_CODE(iface, cs, + ap_base_addr); + + if (DRAM_REGION_SIZE_EVEN(region_code)) { + mem_size += + GET_DRAM_REGION_SIZE_EVEN(region_code); + } else if (DRAM_REGION_SIZE_ODD(region_code)) { + mem_size += + GET_DRAM_REGION_SIZE_ODD(region_code); + } else { + WARN("%s: Invalid mem region (0x%x) CS#%d\n", + __func__, region_code, cs); + return 0; + } + } + } + + return mem_size; +} diff --git a/plat/marvell/armada/common/marvell_gicv2.c b/plat/marvell/armada/common/marvell_gicv2.c new file mode 100644 index 000000000..2505c9f84 --- /dev/null +++ b/plat/marvell/armada/common/marvell_gicv2.c @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include + +/* + * The following functions are defined as weak to allow a platform to override + * the way the GICv2 driver is initialised and used. + */ +#pragma weak plat_marvell_gic_driver_init +#pragma weak plat_marvell_gic_init + +#define A7K8K_PIC_CAUSE_REG 0xf03f0100 +#define A7K8K_PIC0_MASK_REG 0xf03f0108 + +#define A7K8K_PIC_PMUOF_IRQ_MASK (1 << 17) + +#define A7K8K_PIC_MAX_IRQS 32 +#define A7K8K_PIC_MAX_IRQ_MASK ((1UL << A7K8K_PIC_MAX_IRQS) - 1) + +#define A7K8K_ODMIN_SET_REG 0xf0300040 +#define A7K8K_ODMI_PMU_IRQ(idx) ((2 + idx) << 12) + +#define A7K8K_ODMI_PMU_GIC_IRQ(idx) (130 + idx) + +static DEFINE_BAKERY_LOCK(a7k8k_irq_lock); + +/* + * On a GICv2 system, the Group 1 secure interrupts are treated as Group 0 + * interrupts. + */ +static const interrupt_prop_t marvell_interrupt_props[] = { + PLAT_MARVELL_G1S_IRQ_PROPS(GICV2_INTR_GROUP0), + PLAT_MARVELL_G0_IRQ_PROPS(GICV2_INTR_GROUP0) +}; + +static unsigned int target_mask_array[PLATFORM_CORE_COUNT]; + +/* + * Ideally `marvell_gic_data` structure definition should be a `const` but it is + * kept as modifiable for overwriting with different GICD and GICC base when + * running on FVP with VE memory map. + */ +static gicv2_driver_data_t marvell_gic_data = { + .gicd_base = PLAT_MARVELL_GICD_BASE, + .gicc_base = PLAT_MARVELL_GICC_BASE, + .interrupt_props = marvell_interrupt_props, + .interrupt_props_num = ARRAY_SIZE(marvell_interrupt_props), + .target_masks = target_mask_array, + .target_masks_num = ARRAY_SIZE(target_mask_array), +}; + +/* + * ARM common helper to initialize the GICv2 only driver. + */ +void plat_marvell_gic_driver_init(void) +{ + gicv2_driver_init(&marvell_gic_data); +} + +static uint64_t a7k8k_pmu_interrupt_handler(uint32_t id, + uint32_t flags, + void *handle, + void *cookie) +{ + unsigned int idx = plat_my_core_pos(); + uint32_t irq; + + bakery_lock_get(&a7k8k_irq_lock); + + /* Acknowledge IRQ */ + irq = plat_ic_acknowledge_interrupt(); + + plat_ic_end_of_interrupt(irq); + + if (irq != MARVELL_IRQ_PIC0) { + bakery_lock_release(&a7k8k_irq_lock); + return 0; + } + + /* Acknowledge PMU overflow IRQ in PIC0 */ + mmio_setbits_32(A7K8K_PIC_CAUSE_REG, A7K8K_PIC_PMUOF_IRQ_MASK); + + /* Trigger ODMI Frame IRQ */ + mmio_write_32(A7K8K_ODMIN_SET_REG, A7K8K_ODMI_PMU_IRQ(idx)); + + bakery_lock_release(&a7k8k_irq_lock); + + return 0; +} + +void mvebu_pmu_interrupt_enable(void) +{ + unsigned int idx; + uint32_t flags; + int32_t rc; + + /* Reset PIC */ + mmio_write_32(A7K8K_PIC_CAUSE_REG, A7K8K_PIC_MAX_IRQ_MASK); + /* Unmask PMU overflow IRQ in PIC0 */ + mmio_clrbits_32(A7K8K_PIC0_MASK_REG, A7K8K_PIC_PMUOF_IRQ_MASK); + + /* Configure ODMI Frame IRQs as edge triggered */ + for (idx = 0; idx < PLATFORM_CORE_COUNT; idx++) + gicv2_interrupt_set_cfg(A7K8K_ODMI_PMU_GIC_IRQ(idx), + GIC_INTR_CFG_EDGE); + + /* + * Register IRQ handler as INTR_TYPE_S_EL1 as its the only valid type + * for GICv2 in ARM-TF. + */ + flags = 0U; + set_interrupt_rm_flag((flags), (NON_SECURE)); + rc = register_interrupt_type_handler(INTR_TYPE_S_EL1, + a7k8k_pmu_interrupt_handler, + flags); + if (rc != 0) + panic(); +} + +void mvebu_pmu_interrupt_disable(void) +{ + /* Reset PIC */ + mmio_write_32(A7K8K_PIC_CAUSE_REG, A7K8K_PIC_MAX_IRQ_MASK); + /* Mask PMU overflow IRQ in PIC0 */ + mmio_setbits_32(A7K8K_PIC0_MASK_REG, A7K8K_PIC_PMUOF_IRQ_MASK); +} + +void plat_marvell_gic_init(void) +{ + gicv2_distif_init(); + gicv2_pcpu_distif_init(); + gicv2_set_pe_target_mask(plat_my_core_pos()); + gicv2_cpuif_enable(); +} diff --git a/plat/marvell/armada/common/marvell_gicv3.c b/plat/marvell/armada/common/marvell_gicv3.c new file mode 100644 index 000000000..0bd554570 --- /dev/null +++ b/plat/marvell/armada/common/marvell_gicv3.c @@ -0,0 +1,210 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include +#include +#include +#include + +#include +#include + +/****************************************************************************** + * The following functions are defined as weak to allow a platform to override + * the way the GICv3 driver is initialised and used. + ****************************************************************************** + */ +#pragma weak plat_marvell_gic_driver_init +#pragma weak plat_marvell_gic_init +#pragma weak plat_marvell_gic_cpuif_enable +#pragma weak plat_marvell_gic_cpuif_disable +#pragma weak plat_marvell_gic_pcpu_init + +/* The GICv3 driver only needs to be initialized in EL3 */ +static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT]; + +static const interrupt_prop_t marvell_interrupt_props[] = { + PLAT_MARVELL_G1S_IRQ_PROPS(INTR_GROUP1S), + PLAT_MARVELL_G0_IRQ_PROPS(INTR_GROUP0) +}; + +/* + * We save and restore the GICv3 context on system suspend. Allocate the + * data in the designated EL3 Secure carve-out memory + */ +static gicv3_redist_ctx_t rdist_ctx __section("arm_el3_tzc_dram"); +static gicv3_dist_ctx_t dist_ctx __section("arm_el3_tzc_dram"); + +/* + * MPIDR hashing function for translating MPIDRs read from GICR_TYPER register + * to core position. + * + * Calculating core position is dependent on MPIDR_EL1.MT bit. However, affinity + * values read from GICR_TYPER don't have an MT field. To reuse the same + * translation used for CPUs, we insert MT bit read from the PE's MPIDR into + * that read from GICR_TYPER. + * + * Assumptions: + * + * - All CPUs implemented in the system have MPIDR_EL1.MT bit set; + * - No CPUs implemented in the system use affinity level 3. + */ +static unsigned int marvell_gicv3_mpidr_hash(u_register_t mpidr) +{ + mpidr |= (read_mpidr_el1() & MPIDR_MT_MASK); + return plat_marvell_calc_core_pos(mpidr); +} + +const gicv3_driver_data_t marvell_gic_data = { + .gicd_base = PLAT_MARVELL_GICD_BASE, + .gicr_base = PLAT_MARVELL_GICR_BASE, + .interrupt_props = marvell_interrupt_props, + .interrupt_props_num = ARRAY_SIZE(marvell_interrupt_props), + .rdistif_num = PLATFORM_CORE_COUNT, + .rdistif_base_addrs = rdistif_base_addrs, + .mpidr_to_core_pos = marvell_gicv3_mpidr_hash +}; + +void plat_marvell_gic_driver_init(void) +{ + /* + * The GICv3 driver is initialized in EL3 and does not need + * to be initialized again in SEL1. This is because the S-EL1 + * can use GIC system registers to manage interrupts and does + * not need GIC interface base addresses to be configured. + */ +#if IMAGE_BL31 + gicv3_driver_init(&marvell_gic_data); +#endif +} + +/****************************************************************************** + * Marvell common helper to initialize the GIC. Only invoked by BL31 + ****************************************************************************** + */ +void plat_marvell_gic_init(void) +{ + /* Initialize GIC-600 Multi Chip feature, + * only if the maximum number of north bridges + * is more than 1 - otherwise no need for multi + * chip feature initialization + */ +#if (PLAT_MARVELL_NORTHB_COUNT > 1) + if (gic600_multi_chip_init()) + ERROR("GIC-600 Multi Chip initialization failed\n"); +#endif + gicv3_distif_init(); + gicv3_rdistif_init(plat_my_core_pos()); + gicv3_cpuif_enable(plat_my_core_pos()); +} + +/****************************************************************************** + * Marvell common helper to enable the GIC CPU interface + ****************************************************************************** + */ +void plat_marvell_gic_cpuif_enable(void) +{ + gicv3_cpuif_enable(plat_my_core_pos()); +} + +/****************************************************************************** + * Marvell common helper to disable the GIC CPU interface + ****************************************************************************** + */ +void plat_marvell_gic_cpuif_disable(void) +{ + gicv3_cpuif_disable(plat_my_core_pos()); +} + +/****************************************************************************** + * Marvell common helper to init. the per-cpu redistributor interface in GICv3 + ****************************************************************************** + */ +void plat_marvell_gic_pcpu_init(void) +{ + gicv3_rdistif_init(plat_my_core_pos()); +} + +/****************************************************************************** + * Marvell common helper to save SPI irq states in GICv3 + ****************************************************************************** + */ +void plat_marvell_gic_irq_save(void) +{ + + /* + * If an ITS is available, save its context before + * the Redistributor using: + * gicv3_its_save_disable(gits_base, &its_ctx[i]) + * Additionally, an implementation-defined sequence may + * be required to save the whole ITS state. + */ + + /* + * Save the GIC Redistributors and ITS contexts before the + * Distributor context. As we only handle SYSTEM SUSPEND API, + * we only need to save the context of the CPU that is issuing + * the SYSTEM SUSPEND call, i.e. the current CPU. + */ + gicv3_rdistif_save(plat_my_core_pos(), &rdist_ctx); + + /* Save the GIC Distributor context */ + gicv3_distif_save(&dist_ctx); + + /* + * From here, all the components of the GIC can be safely powered down + * as long as there is an alternate way to handle wakeup interrupt + * sources. + */ +} + +/****************************************************************************** + * Marvell common helper to restore SPI irq states in GICv3 + ****************************************************************************** + */ +void plat_marvell_gic_irq_restore(void) +{ + /* Restore the GIC Distributor context */ + gicv3_distif_init_restore(&dist_ctx); + + /* + * Restore the GIC Redistributor and ITS contexts after the + * Distributor context. As we only handle SYSTEM SUSPEND API, + * we only need to restore the context of the CPU that issued + * the SYSTEM SUSPEND call. + */ + gicv3_rdistif_init_restore(plat_my_core_pos(), &rdist_ctx); + + /* + * If an ITS is available, restore its context after + * the Redistributor using: + * gicv3_its_restore(gits_base, &its_ctx[i]) + * An implementation-defined sequence may be required to + * restore the whole ITS state. The ITS must also be + * re-enabled after this sequence has been executed. + */ +} + +/****************************************************************************** + * Marvell common helper to save per-cpu PPI irq states in GICv3 + ****************************************************************************** + */ +void plat_marvell_gic_irq_pcpu_save(void) +{ + gicv3_rdistif_save(plat_my_core_pos(), &rdist_ctx); +} + +/****************************************************************************** + * Marvell common helper to restore per-cpu PPI irq states in GICv3 + ****************************************************************************** + */ +void plat_marvell_gic_irq_pcpu_restore(void) +{ + gicv3_rdistif_init_restore(plat_my_core_pos(), &rdist_ctx); +} diff --git a/plat/marvell/armada/common/marvell_image_load.c b/plat/marvell/armada/common/marvell_image_load.c new file mode 100644 index 000000000..be16b0898 --- /dev/null +++ b/plat/marvell/armada/common/marvell_image_load.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include + +/******************************************************************************* + * This function flushes the data structures so that they are visible + * in memory for the next BL image. + ******************************************************************************/ +void plat_flush_next_bl_params(void) +{ + flush_bl_params_desc(); +} + +/******************************************************************************* + * This function returns the list of loadable images. + ******************************************************************************/ +bl_load_info_t *plat_get_bl_image_load_info(void) +{ + return get_bl_load_info_from_mem_params_desc(); +} + +/******************************************************************************* + * This function returns the list of executable images. + ******************************************************************************/ +bl_params_t *plat_get_next_bl_params(void) +{ + return get_next_bl_params_from_mem_params_desc(); +} diff --git a/plat/marvell/armada/common/marvell_io_storage.c b/plat/marvell/armada/common/marvell_io_storage.c new file mode 100644 index 000000000..065f95688 --- /dev/null +++ b/plat/marvell/armada/common/marvell_io_storage.c @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +/* IO devices */ +static const io_dev_connector_t *fip_dev_con; +static uintptr_t fip_dev_handle; +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 = PLAT_MARVELL_FIP_BASE, + .length = PLAT_MARVELL_FIP_MAX_SIZE +}; + +static const io_uuid_spec_t bl2_uuid_spec = { + .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2, +}; + +static const io_uuid_spec_t scp_bl2_uuid_spec = { + .uuid = UUID_SCP_FIRMWARE_SCP_BL2, +}; + +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 bl33_uuid_spec = { + .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33, +}; + +static int open_fip(const uintptr_t spec); +static int open_memmap(const uintptr_t spec); + +struct plat_io_policy { + uintptr_t *dev_handle; + uintptr_t image_spec; + int (*check)(const uintptr_t spec); +}; + +/* By default, Marvell platforms load images from the FIP */ +static const struct plat_io_policy policies[] = { + [FIP_IMAGE_ID] = { + &memmap_dev_handle, + (uintptr_t)&fip_block_spec, + open_memmap + }, + [BL2_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&bl2_uuid_spec, + open_fip + }, + [SCP_BL2_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&scp_bl2_uuid_spec, + open_fip + }, + [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 + }, + [BL33_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&bl33_uuid_spec, + open_fip + }, +}; + + +/* Weak definitions may be overridden in specific ARM standard platform */ +#pragma weak plat_marvell_io_setup +#pragma weak plat_marvell_get_alt_image_source + + +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; +} + + +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; +} + + +void marvell_io_setup(void) +{ + int io_result; + + io_result = register_io_dev_fip(&fip_dev_con); + assert(io_result == 0); + + io_result = register_io_dev_memmap(&memmap_dev_con); + assert(io_result == 0); + + /* Open connections to devices and cache the handles */ + io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, + &fip_dev_handle); + assert(io_result == 0); + + io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, + &memmap_dev_handle); + assert(io_result == 0); + + /* Ignore improbable errors in release builds */ + (void)io_result; +} + +void plat_marvell_io_setup(void) +{ + marvell_io_setup(); +} + +int plat_marvell_get_alt_image_source( + unsigned int image_id __attribute__((unused)), + uintptr_t *dev_handle __attribute__((unused)), + uintptr_t *image_spec __attribute__((unused))) +{ + /* By default do not try an alternative */ + return -ENOENT; +} + +/* + * 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 result; + const struct plat_io_policy *policy; + + assert(image_id < ARRAY_SIZE(policies)); + + policy = &policies[image_id]; + result = policy->check(policy->image_spec); + if (result == 0) { + *image_spec = policy->image_spec; + *dev_handle = *(policy->dev_handle); + } else { + VERBOSE("Trying alternative IO\n"); + result = plat_marvell_get_alt_image_source(image_id, dev_handle, + image_spec); + } + + return result; +} + +/* + * See if a Firmware Image Package is available, + * by checking if TOC is valid or not. + */ +int marvell_io_is_toc_valid(void) +{ + int result; + + result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); + + return result == 0; +} diff --git a/plat/marvell/armada/common/marvell_pm.c b/plat/marvell/armada/common/marvell_pm.c new file mode 100644 index 000000000..3c675b296 --- /dev/null +++ b/plat/marvell/armada/common/marvell_pm.c @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include +#include + +#include + +/* Standard ARM platforms are expected to export plat_arm_psci_pm_ops */ +extern const plat_psci_ops_t plat_arm_psci_pm_ops; + +/***************************************************************************** + * Private function to program the mailbox for a cpu before it is released + * from reset. This function assumes that the mail box base is within + * the MARVELL_SHARED_RAM region + ***************************************************************************** + */ +void marvell_program_mailbox(uintptr_t address) +{ + uintptr_t *mailbox = (void *)PLAT_MARVELL_MAILBOX_BASE; + + /* + * Ensure that the PLAT_MARVELL_MAILBOX_BASE is within + * MARVELL_SHARED_RAM region. + */ + assert((PLAT_MARVELL_MAILBOX_BASE >= MARVELL_SHARED_RAM_BASE) && + ((PLAT_MARVELL_MAILBOX_BASE + sizeof(*mailbox)) <= + (MARVELL_SHARED_RAM_BASE + MARVELL_SHARED_RAM_SIZE))); + + mailbox[MBOX_IDX_MAGIC] = MVEBU_MAILBOX_MAGIC_NUM; + mailbox[MBOX_IDX_SEC_ADDR] = address; + + /* Flush data cache if the mail box shared RAM is cached */ +#if PLAT_MARVELL_SHARED_RAM_CACHED + flush_dcache_range((uintptr_t)PLAT_MARVELL_MAILBOX_BASE + + 8 * MBOX_IDX_MAGIC, + 2 * sizeof(uint64_t)); +#endif +} + +/***************************************************************************** + * The ARM Standard platform definition of platform porting API + * `plat_setup_psci_ops`. + ***************************************************************************** + */ +int plat_setup_psci_ops(uintptr_t sec_entrypoint, + const plat_psci_ops_t **psci_ops) +{ + *psci_ops = &plat_arm_psci_pm_ops; + + /* Setup mailbox with entry point. */ + marvell_program_mailbox(sec_entrypoint); + return 0; +} diff --git a/plat/marvell/armada/common/marvell_topology.c b/plat/marvell/armada/common/marvell_topology.c new file mode 100644 index 000000000..a40ff6f50 --- /dev/null +++ b/plat/marvell/armada/common/marvell_topology.c @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +/* The power domain tree descriptor */ +unsigned char marvell_power_domain_tree_desc[PLAT_MARVELL_CLUSTER_COUNT + 1]; + +/***************************************************************************** + * This function dynamically constructs the topology according to + * PLAT_MARVELL_CLUSTER_COUNT and returns it. + ***************************************************************************** + */ +const unsigned char *plat_get_power_domain_tree_desc(void) +{ + int i; + + /* + * The power domain tree does not have a single system level power + * domain i.e. a single root node. The first entry in the power domain + * descriptor specifies the number of power domains at the highest power + * level. + * For Marvell Platform this is the number of cluster power domains. + */ + marvell_power_domain_tree_desc[0] = PLAT_MARVELL_CLUSTER_COUNT; + + for (i = 0; i < PLAT_MARVELL_CLUSTER_COUNT; i++) + marvell_power_domain_tree_desc[i + 1] = + PLAT_MARVELL_CLUSTER_CORE_COUNT; + + return marvell_power_domain_tree_desc; +} + +/***************************************************************************** + * This function validates an MPIDR by checking whether it falls within the + * acceptable bounds. An error code (-1) is returned if an incorrect mpidr + * is passed. + ***************************************************************************** + */ +int marvell_check_mpidr(u_register_t mpidr) +{ + unsigned int nb_id, cluster_id, cpu_id; + + mpidr &= MPIDR_AFFINITY_MASK; + + if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK | + MPIDR_AFFLVL_MASK << MPIDR_AFF2_SHIFT)) + return -1; + + /* Get north bridge ID */ + nb_id = MPIDR_AFFLVL3_VAL(mpidr); + cluster_id = MPIDR_AFFLVL1_VAL(mpidr); + cpu_id = MPIDR_AFFLVL0_VAL(mpidr); + + if (nb_id >= PLAT_MARVELL_CLUSTER_COUNT) + return -1; + + if (cluster_id >= PLAT_MARVELL_CLUSTER_COUNT) + return -1; + + if (cpu_id >= PLAT_MARVELL_CLUSTER_CORE_COUNT) + return -1; + + return 0; +} + +/***************************************************************************** + * This function implements a part of the critical interface between the PSCI + * generic layer and the platform that allows the former to query the platform + * to convert an MPIDR to a unique linear index. An error code (-1) is returned + * in case the MPIDR is invalid. + ***************************************************************************** + */ +int plat_core_pos_by_mpidr(u_register_t mpidr) +{ + if (marvell_check_mpidr(mpidr) == -1) + return -1; + + return plat_marvell_calc_core_pos(mpidr); +} diff --git a/plat/marvell/armada/common/mrvl_sip_svc.c b/plat/marvell/armada/common/mrvl_sip_svc.c new file mode 100644 index 000000000..0291024d7 --- /dev/null +++ b/plat/marvell/armada/common/mrvl_sip_svc.c @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include "comphy/phy-comphy-cp110.h" +#include + +/* #define DEBUG_COMPHY */ +#ifdef DEBUG_COMPHY +#define debug(format...) NOTICE(format) +#else +#define debug(format, arg...) +#endif + +/* Comphy related FID's */ +#define MV_SIP_COMPHY_POWER_ON 0x82000001 +#define MV_SIP_COMPHY_POWER_OFF 0x82000002 +#define MV_SIP_COMPHY_PLL_LOCK 0x82000003 +#define MV_SIP_COMPHY_XFI_TRAIN 0x82000004 +#define MV_SIP_COMPHY_DIG_RESET 0x82000005 + +/* Miscellaneous FID's' */ +#define MV_SIP_DRAM_SIZE 0x82000010 +#define MV_SIP_LLC_ENABLE 0x82000011 +#define MV_SIP_PMU_IRQ_ENABLE 0x82000012 +#define MV_SIP_PMU_IRQ_DISABLE 0x82000013 + +#define MAX_LANE_NR 6 +#define MVEBU_COMPHY_OFFSET 0x441000 +#define MVEBU_CP_BASE_MASK (~0xffffff) + +/* This macro is used to identify COMPHY related calls from SMC function ID */ +#define is_comphy_fid(fid) \ + ((fid) >= MV_SIP_COMPHY_POWER_ON && (fid) <= MV_SIP_COMPHY_DIG_RESET) + +_Bool is_cp_range_valid(u_register_t *addr) +{ + int cp_nr; + + *addr &= MVEBU_CP_BASE_MASK; + for (cp_nr = 0; cp_nr < CP_NUM; cp_nr++) { + if (*addr == MVEBU_CP_REGS_BASE(cp_nr)) + return true; + } + + return false; +} + +uintptr_t mrvl_sip_smc_handler(uint32_t smc_fid, + u_register_t x1, + u_register_t x2, + u_register_t x3, + u_register_t x4, + void *cookie, + void *handle, + u_register_t flags) +{ + u_register_t ret; + int i; + + debug("%s: got SMC (0x%x) x1 0x%lx, x2 0x%lx, x3 0x%lx\n", + __func__, smc_fid, x1, x2, x3); + + if (is_comphy_fid(smc_fid)) { + /* validate address passed via x1 */ + if (!is_cp_range_valid(&x1)) { + ERROR("%s: Wrong smc (0x%x) address: %lx\n", + __func__, smc_fid, x1); + SMC_RET1(handle, SMC_UNK); + } + + x1 += MVEBU_COMPHY_OFFSET; + + if (x2 >= MAX_LANE_NR) { + ERROR("%s: Wrong smc (0x%x) lane nr: %lx\n", + __func__, smc_fid, x2); + SMC_RET1(handle, SMC_UNK); + } + } + + switch (smc_fid) { + + /* Comphy related FID's */ + case MV_SIP_COMPHY_POWER_ON: + /* x1: comphy_base, x2: comphy_index, x3: comphy_mode */ + ret = mvebu_cp110_comphy_power_on(x1, x2, x3); + SMC_RET1(handle, ret); + case MV_SIP_COMPHY_POWER_OFF: + /* x1: comphy_base, x2: comphy_index */ + ret = mvebu_cp110_comphy_power_off(x1, x2, x3); + SMC_RET1(handle, ret); + case MV_SIP_COMPHY_PLL_LOCK: + /* x1: comphy_base, x2: comphy_index */ + ret = mvebu_cp110_comphy_is_pll_locked(x1, x2); + SMC_RET1(handle, ret); + case MV_SIP_COMPHY_XFI_TRAIN: + /* x1: comphy_base, x2: comphy_index */ + ret = mvebu_cp110_comphy_xfi_rx_training(x1, x2); + SMC_RET1(handle, ret); + case MV_SIP_COMPHY_DIG_RESET: + /* x1: comphy_base, x2: comphy_index, x3: mode, x4: command */ + ret = mvebu_cp110_comphy_digital_reset(x1, x2, x3, x4); + SMC_RET1(handle, ret); + + /* Miscellaneous FID's' */ + case MV_SIP_DRAM_SIZE: + ret = mvebu_get_dram_size(MVEBU_REGS_BASE); + SMC_RET1(handle, ret); + case MV_SIP_LLC_ENABLE: + for (i = 0; i < ap_get_count(); i++) + llc_runtime_enable(i); + + SMC_RET1(handle, 0); +#ifdef MVEBU_PMU_IRQ_WA + case MV_SIP_PMU_IRQ_ENABLE: + mvebu_pmu_interrupt_enable(); + SMC_RET1(handle, 0); + case MV_SIP_PMU_IRQ_DISABLE: + mvebu_pmu_interrupt_disable(); + SMC_RET1(handle, 0); +#endif + + default: + ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid); + SMC_RET1(handle, SMC_UNK); + } +} + +/* Define a runtime service descriptor for fast SMC calls */ +DECLARE_RT_SVC( + marvell_sip_svc, + OEN_SIP_START, + OEN_SIP_END, + SMC_TYPE_FAST, + NULL, + mrvl_sip_smc_handler +); diff --git a/plat/marvell/armada/common/mss/mss_common.mk b/plat/marvell/armada/common/mss/mss_common.mk new file mode 100644 index 000000000..050d88d2a --- /dev/null +++ b/plat/marvell/armada/common/mss/mss_common.mk @@ -0,0 +1,20 @@ +# +# Copyright (C) 2018 Marvell International Ltd. +# +# SPDX-License-Identifier: BSD-3-Clause +# https://spdx.org/licenses +# + + +PLAT_MARVELL := plat/marvell/armada +MSS_SOURCE := $(PLAT_MARVELL)/common/mss + +BL2_SOURCES += $(MSS_SOURCE)/mss_scp_bootloader.c \ + $(PLAT_MARVELL)/common/plat_delay_timer.c \ + drivers/delay_timer/delay_timer.c \ + $(MARVELL_DRV) \ + $(PLAT_FAMILY_BASE)/$(PLAT)/board/marvell_plat_config.c + +BL31_SOURCES += $(MSS_SOURCE)/mss_ipc_drv.c + +PLAT_INCLUDES += -I$(MSS_SOURCE) diff --git a/plat/marvell/armada/common/mss/mss_ipc_drv.c b/plat/marvell/armada/common/mss/mss_ipc_drv.c new file mode 100644 index 000000000..70ccfa5ac --- /dev/null +++ b/plat/marvell/armada/common/mss/mss_ipc_drv.c @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include +#include + +#include +#include + +#define IPC_MSG_BASE_MASK MVEBU_REGS_BASE_MASK + +#define IPC_CH_NUM_OF_MSG (16) +#define IPC_CH_MSG_IDX (-1) + +unsigned long mv_pm_ipc_msg_base; +unsigned int mv_pm_ipc_queue_size; + +unsigned int msg_sync; +int msg_index = IPC_CH_MSG_IDX; + +/****************************************************************************** + * mss_pm_ipc_init + * + * DESCRIPTION: Initialize PM IPC infrastructure + ****************************************************************************** + */ +int mv_pm_ipc_init(unsigned long ipc_control_addr) +{ + struct mss_pm_ipc_ctrl *ipc_control = + (struct mss_pm_ipc_ctrl *)ipc_control_addr; + + /* Initialize PM IPC control block */ + mv_pm_ipc_msg_base = ipc_control->msg_base_address | + IPC_MSG_BASE_MASK; + mv_pm_ipc_queue_size = ipc_control->queue_size; + + return 0; +} + +/****************************************************************************** + * mv_pm_ipc_queue_addr_get + * + * DESCRIPTION: Returns the IPC queue address + ****************************************************************************** + */ +unsigned int mv_pm_ipc_queue_addr_get(void) +{ + unsigned int addr; + + inv_dcache_range((uint64_t)&msg_index, sizeof(msg_index)); + msg_index = msg_index + 1; + if (msg_index >= IPC_CH_NUM_OF_MSG) + msg_index = 0; + + addr = (unsigned int)(mv_pm_ipc_msg_base + + (msg_index * mv_pm_ipc_queue_size)); + + flush_dcache_range((uint64_t)&msg_index, sizeof(msg_index)); + + return addr; +} + +/****************************************************************************** + * mv_pm_ipc_msg_rx + * + * DESCRIPTION: Retrieve message from IPC channel + ****************************************************************************** + */ +int mv_pm_ipc_msg_rx(unsigned int channel_id, struct mss_pm_ipc_msg *msg) +{ + unsigned int addr = mv_pm_ipc_queue_addr_get(); + + msg->msg_reply = mmio_read_32(addr + IPC_MSG_REPLY_LOC); + + return 0; +} + +/****************************************************************************** + * mv_pm_ipc_msg_tx + * + * DESCRIPTION: Send message via IPC channel + ****************************************************************************** + */ +int mv_pm_ipc_msg_tx(unsigned int channel_id, unsigned int msg_id, + unsigned int cluster_power_state) +{ + unsigned int addr = mv_pm_ipc_queue_addr_get(); + + /* Validate the entry for message placed by the host is free */ + if (mmio_read_32(addr + IPC_MSG_STATE_LOC) == IPC_MSG_FREE) { + inv_dcache_range((uint64_t)&msg_sync, sizeof(msg_sync)); + msg_sync = msg_sync + 1; + flush_dcache_range((uint64_t)&msg_sync, sizeof(msg_sync)); + + mmio_write_32(addr + IPC_MSG_SYNC_ID_LOC, msg_sync); + mmio_write_32(addr + IPC_MSG_ID_LOC, msg_id); + mmio_write_32(addr + IPC_MSG_CPU_ID_LOC, channel_id); + mmio_write_32(addr + IPC_MSG_POWER_STATE_LOC, + cluster_power_state); + mmio_write_32(addr + IPC_MSG_STATE_LOC, IPC_MSG_OCCUPY); + + } else { + ERROR("%s: FAILED\n", __func__); + } + + return 0; +} diff --git a/plat/marvell/armada/common/mss/mss_ipc_drv.h b/plat/marvell/armada/common/mss/mss_ipc_drv.h new file mode 100644 index 000000000..bcb4b2d8f --- /dev/null +++ b/plat/marvell/armada/common/mss/mss_ipc_drv.h @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef MSS_IPC_DRV_H +#define MSS_IPC_DRV_H + +#include + +#define MV_PM_FW_IPC_VERSION_MAGIC (0xCA530000) /* Do NOT change */ +/* Increament for each version */ +#define MV_PM_FW_IPC_VERSION_SEQ (0x00000001) +#define MV_PM_FW_IPC_VERSION (MV_PM_FW_IPC_VERSION_MAGIC | \ + MV_PM_FW_IPC_VERSION_SEQ) + +#define IPC_MSG_STATE_LOC (0x0) +#define IPC_MSG_SYNC_ID_LOC (0x4) +#define IPC_MSG_ID_LOC (0x8) +#define IPC_MSG_RET_CH_ID_LOC (0xC) +#define IPC_MSG_CPU_ID_LOC (0x10) +#define IPC_MSG_CLUSTER_ID_LOC (0x14) +#define IPC_MSG_SYSTEM_ID_LOC (0x18) +#define IPC_MSG_POWER_STATE_LOC (0x1C) +#define IPC_MSG_REPLY_LOC (0x20) +#define IPC_MSG_RESERVED_LOC (0x24) + +/* IPC initialization state */ +enum mss_pm_ipc_init_state { + IPC_UN_INITIALIZED = 1, + IPC_INITIALIZED = 2 +}; + +/* IPC queue direction */ +enum mss_pm_ipc_init_msg_dir { + IPC_MSG_TX = 0, + IPC_MSG_RX = 1 +}; + +/* IPC message state */ +enum mss_pm_ipc_msg_state { + IPC_MSG_FREE = 1, + IPC_MSG_OCCUPY = 2 + +}; + +/* IPC control block */ +struct mss_pm_ipc_ctrl { + unsigned int ctrl_base_address; + unsigned int msg_base_address; + unsigned int num_of_channels; + unsigned int channel_size; + unsigned int queue_size; +}; + +/* IPC message types */ +enum mss_pm_msg_id { + PM_IPC_MSG_CPU_SUSPEND = 1, + PM_IPC_MSG_CPU_OFF = 2, + PM_IPC_MSG_CPU_ON = 3, + PM_IPC_MSG_SYSTEM_RESET = 4, + PM_IPC_MSG_SYSTEM_SUSPEND = 5, + PM_IPC_MAX_MSG +}; + +struct mss_pm_ipc_msg { + unsigned int msg_sync_id; /* + * Sync number, validate message + * reply corresponding to message + * received + */ + unsigned int msg_id; /* Message Id */ + unsigned int ret_channel_id; /* IPC channel reply */ + unsigned int cpu_id; /* CPU Id */ + unsigned int cluster_id; /* Cluster Id */ + unsigned int system_id; /* System Id */ + unsigned int power_state; + unsigned int msg_reply; /* Message reply */ +}; + +/* IPC queue */ +struct mss_pm_ipc_queue { + unsigned int state; + struct mss_pm_ipc_msg msg; +}; + +/* IPC channel */ +struct mss_pm_ipc_ch { + struct mss_pm_ipc_queue *tx_queue; + struct mss_pm_ipc_queue *rx_queue; +}; + +/***************************************************************************** + * mv_pm_ipc_init + * + * DESCRIPTION: Initialize PM IPC infrastructure + ***************************************************************************** + */ +int mv_pm_ipc_init(unsigned long ipc_control_addr); + +/***************************************************************************** + * mv_pm_ipc_msg_rx + * + * DESCRIPTION: Retrieve message from IPC channel + ***************************************************************************** + */ +int mv_pm_ipc_msg_rx(unsigned int channel_id, struct mss_pm_ipc_msg *msg); + +/***************************************************************************** + * mv_pm_ipc_msg_tx + * + * DESCRIPTION: Send message via IPC channel + ***************************************************************************** + */ +int mv_pm_ipc_msg_tx(unsigned int channel_id, unsigned int msg_id, + unsigned int cluster_power_state); + +#endif /* MSS_IPC_DRV_H */ diff --git a/plat/marvell/armada/common/mss/mss_mem.h b/plat/marvell/armada/common/mss/mss_mem.h new file mode 100644 index 000000000..5d68ac788 --- /dev/null +++ b/plat/marvell/armada/common/mss/mss_mem.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef MSS_MEM_H +#define MSS_MEM_H + +/* MSS SRAM Memory base */ +#define MSS_SRAM_PM_CONTROL_BASE (MVEBU_REGS_BASE + 0x520000) + +enum mss_pm_ctrl_handshake { + MSS_UN_INITIALIZED = 0, + MSS_COMPATIBILITY_ERROR = 1, + MSS_ACKNOWLEDGMENT = 2, + HOST_ACKNOWLEDGMENT = 3 +}; + +enum mss_pm_ctrl_rtos_env { + MSS_MULTI_PROCESS_ENV = 0, + MSS_SINGLE_PROCESS_ENV = 1, + MSS_MAX_PROCESS_ENV +}; + +struct mss_pm_ctrl_block { + /* This field is used to synchronize the Host + * and MSS initialization sequence + * Valid Values + * 0 - Un-Initialized + * 1 - Compatibility Error + * 2 - MSS Acknowledgment + * 3 - Host Acknowledgment + */ + unsigned int handshake; + + /* + * This field include Host IPC version. Once received by the MSS + * It will be compared to MSS IPC version and set MSS Acknowledge to + * "compatibility error" in case there is no match + */ + unsigned int ipc_version; + unsigned int ipc_base_address; + unsigned int ipc_state; + + /* Following fields defines firmware core architecture */ + unsigned int num_of_cores; + unsigned int num_of_clusters; + unsigned int num_of_cores_per_cluster; + + /* Following fields define pm trace debug base address */ + unsigned int pm_trace_ctrl_base_address; + unsigned int pm_trace_info_base_address; + unsigned int pm_trace_info_core_size; + + unsigned int ctrl_blk_size; +}; + +#endif /* MSS_MEM_H */ diff --git a/plat/marvell/armada/common/mss/mss_scp_bl2_format.h b/plat/marvell/armada/common/mss/mss_scp_bl2_format.h new file mode 100644 index 000000000..7150f0a06 --- /dev/null +++ b/plat/marvell/armada/common/mss/mss_scp_bl2_format.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef MSS_SCP_BL2_FORMAT_H +#define MSS_SCP_BL2_FORMAT_H + +#define MAX_NR_OF_FILES 8 +#define FILE_MAGIC 0xddd01ff +#define HEADER_VERSION 0x1 + +#define MSS_IDRAM_SIZE 0x10000 /* 64KB */ +#define MG_SRAM_SIZE 0x20000 /* 128KB */ + +/* Types definitions */ +typedef struct file_header { + /* Magic specific for concatenated file (used for validation) */ + uint32_t magic; + uint32_t nr_of_imgs; /* Number of images concatenated */ +} file_header_t; + +/* Types definitions */ +enum cm3_t { + MSS_AP, + MSS_CP0, + MSS_CP1, + MSS_CP2, + MSS_CP3, + MG_CP0, + MG_CP1, + MG_CP2, +}; + +typedef struct img_header { + uint32_t type; /* CM3 type, can be one of cm3_t */ + uint32_t length; /* Image length */ + uint32_t version; /* For sanity checks and future + * extended functionality + */ +} img_header_t; + +#endif /* MSS_SCP_BL2_FORMAT_H */ diff --git a/plat/marvell/armada/common/mss/mss_scp_bootloader.c b/plat/marvell/armada/common/mss/mss_scp_bootloader.c new file mode 100644 index 000000000..4473d81e1 --- /dev/null +++ b/plat/marvell/armada/common/mss/mss_scp_bootloader.c @@ -0,0 +1,343 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define MSS_DMA_SRCBR(base) (base + 0xC0) +#define MSS_DMA_DSTBR(base) (base + 0xC4) +#define MSS_DMA_CTRLR(base) (base + 0xC8) +#define MSS_M3_RSTCR(base) (base + 0xFC) + +#define MSS_DMA_CTRLR_SIZE_OFFSET (0) +#define MSS_DMA_CTRLR_REQ_OFFSET (15) +#define MSS_DMA_CTRLR_REQ_SET (1) +#define MSS_DMA_CTRLR_ACK_OFFSET (12) +#define MSS_DMA_CTRLR_ACK_MASK (0x1) +#define MSS_DMA_CTRLR_ACK_READY (1) +#define MSS_M3_RSTCR_RST_OFFSET (0) +#define MSS_M3_RSTCR_RST_OFF (1) + +#define MSS_DMA_TIMEOUT 1000 +#define MSS_EXTERNAL_SPACE 0x50000000 +#define MSS_EXTERNAL_ADDR_MASK 0xfffffff + +#define DMA_SIZE 128 + +#define MSS_HANDSHAKE_TIMEOUT 50 + +#define MG_CM3_SRAM_BASE(CP) (MVEBU_CP_REGS_BASE(CP) + 0x100000) + +static int mss_check_image_ready(volatile struct mss_pm_ctrl_block *mss_pm_crtl) +{ + int timeout = MSS_HANDSHAKE_TIMEOUT; + + /* Wait for SCP to signal it's ready */ + while ((mss_pm_crtl->handshake != MSS_ACKNOWLEDGMENT) && + (timeout-- > 0)) + mdelay(1); + + if (mss_pm_crtl->handshake != MSS_ACKNOWLEDGMENT) + return -1; + + mss_pm_crtl->handshake = HOST_ACKNOWLEDGMENT; + + return 0; +} + +static int mg_image_load(uintptr_t src_addr, uint32_t size, uintptr_t mg_regs) +{ + if (size > MG_SRAM_SIZE) { + ERROR("image is too big to fit into MG CM3 memory\n"); + return 1; + } + + NOTICE("Loading MG image from address 0x%lx Size 0x%x to MG at 0x%lx\n", + src_addr, size, mg_regs); + + /* Copy image to MG CM3 SRAM */ + memcpy((void *)mg_regs, (void *)src_addr, size); + + /* + * Don't release MG CM3 from reset - it will be done by next step + * bootloader (e.g. U-Boot), when appriopriate device-tree setup (which + * has enabeld 802.3. auto-neg) will be choosen. + */ + + return 0; +} + +static int mss_image_load(uint32_t src_addr, uint32_t size, uintptr_t mss_regs) +{ + uint32_t i, loop_num, timeout; + + /* Check if the img size is not bigger than ID-RAM size of MSS CM3 */ + if (size > MSS_IDRAM_SIZE) { + ERROR("image is too big to fit into MSS CM3 memory\n"); + return 1; + } + + NOTICE("Loading MSS image from addr. 0x%x Size 0x%x to MSS at 0x%lx\n", + src_addr, size, mss_regs); + /* load image to MSS RAM using DMA */ + loop_num = (size / DMA_SIZE) + (((size & (DMA_SIZE - 1)) == 0) ? 0 : 1); + + for (i = 0; i < loop_num; i++) { + /* write destination and source addresses */ + mmio_write_32(MSS_DMA_SRCBR(mss_regs), + MSS_EXTERNAL_SPACE | + ((src_addr & MSS_EXTERNAL_ADDR_MASK) + + (i * DMA_SIZE))); + mmio_write_32(MSS_DMA_DSTBR(mss_regs), (i * DMA_SIZE)); + + dsb(); /* make sure DMA data is ready before triggering it */ + + /* set the DMA control register */ + mmio_write_32(MSS_DMA_CTRLR(mss_regs), ((MSS_DMA_CTRLR_REQ_SET + << MSS_DMA_CTRLR_REQ_OFFSET) | + (DMA_SIZE << MSS_DMA_CTRLR_SIZE_OFFSET))); + + /* Poll DMA_ACK at MSS_DMACTLR until it is ready */ + timeout = MSS_DMA_TIMEOUT; + while (timeout) { + if ((mmio_read_32(MSS_DMA_CTRLR(mss_regs)) >> + MSS_DMA_CTRLR_ACK_OFFSET & MSS_DMA_CTRLR_ACK_MASK) + == MSS_DMA_CTRLR_ACK_READY) { + break; + } + + udelay(50); + timeout--; + } + + if (timeout == 0) { + ERROR("\nDMA failed to load MSS image\n"); + return 1; + } + } + + bl2_plat_configure_mss_windows(mss_regs); + + /* Release M3 from reset */ + mmio_write_32(MSS_M3_RSTCR(mss_regs), (MSS_M3_RSTCR_RST_OFF << + MSS_M3_RSTCR_RST_OFFSET)); + + NOTICE("Done\n"); + + return 0; +} + +/* Load image to MSS AP and do PM related initialization + * Note that this routine is different than other CM3 loading routines, because + * firmware for AP is dedicated for PM and therefore some additional PM + * initialization is required + */ +static int mss_ap_load_image(uintptr_t single_img, + uint32_t image_size, uint32_t ap_idx) +{ + volatile struct mss_pm_ctrl_block *mss_pm_crtl; + int ret; + + /* TODO: add PM Control Info from platform */ + mss_pm_crtl = (struct mss_pm_ctrl_block *)MSS_SRAM_PM_CONTROL_BASE; + mss_pm_crtl->ipc_version = MV_PM_FW_IPC_VERSION; + mss_pm_crtl->num_of_clusters = PLAT_MARVELL_CLUSTER_COUNT; + mss_pm_crtl->num_of_cores_per_cluster = + PLAT_MARVELL_CLUSTER_CORE_COUNT; + mss_pm_crtl->num_of_cores = PLAT_MARVELL_CLUSTER_COUNT * + PLAT_MARVELL_CLUSTER_CORE_COUNT; + mss_pm_crtl->pm_trace_ctrl_base_address = AP_MSS_ATF_CORE_CTRL_BASE; + mss_pm_crtl->pm_trace_info_base_address = AP_MSS_ATF_CORE_INFO_BASE; + mss_pm_crtl->pm_trace_info_core_size = AP_MSS_ATF_CORE_INFO_SIZE; + VERBOSE("MSS Control Block = 0x%x\n", MSS_SRAM_PM_CONTROL_BASE); + VERBOSE("mss_pm_crtl->ipc_version = 0x%x\n", + mss_pm_crtl->ipc_version); + VERBOSE("mss_pm_crtl->num_of_cores = 0x%x\n", + mss_pm_crtl->num_of_cores); + VERBOSE("mss_pm_crtl->num_of_clusters = 0x%x\n", + mss_pm_crtl->num_of_clusters); + VERBOSE("mss_pm_crtl->num_of_cores_per_cluster = 0x%x\n", + mss_pm_crtl->num_of_cores_per_cluster); + VERBOSE("mss_pm_crtl->pm_trace_ctrl_base_address = 0x%x\n", + mss_pm_crtl->pm_trace_ctrl_base_address); + VERBOSE("mss_pm_crtl->pm_trace_info_base_address = 0x%x\n", + mss_pm_crtl->pm_trace_info_base_address); + VERBOSE("mss_pm_crtl->pm_trace_info_core_size = 0x%x\n", + mss_pm_crtl->pm_trace_info_core_size); + + /* TODO: add checksum to image */ + VERBOSE("Send info about the SCP_BL2 image to be transferred to SCP\n"); + + ret = mss_image_load(single_img, image_size, + bl2_plat_get_ap_mss_regs(ap_idx)); + if (ret != 0) { + ERROR("SCP Image load failed\n"); + return -1; + } + + /* check that the image was loaded successfully */ + ret = mss_check_image_ready(mss_pm_crtl); + if (ret != 0) + NOTICE("SCP Image doesn't contain PM firmware\n"); + + return 0; +} + +/* Load CM3 image (single_img) to CM3 pointed by cm3_type */ +static int load_img_to_cm3(enum cm3_t cm3_type, + uintptr_t single_img, uint32_t image_size) +{ + int ret, ap_idx, cp_index; + uint32_t ap_count = bl2_plat_get_ap_count(); + + switch (cm3_type) { + case MSS_AP: + for (ap_idx = 0; ap_idx < ap_count; ap_idx++) { + NOTICE("Load image to AP%d MSS\n", ap_idx); + ret = mss_ap_load_image(single_img, image_size, ap_idx); + if (ret != 0) + return ret; + } + break; + case MSS_CP0: + case MSS_CP1: + case MSS_CP2: + case MSS_CP3: + /* MSS_AP = 0 + * MSS_CP1 = 1 + * . + * . + * MSS_CP3 = 4 + * Actual CP index is MSS_CPX - 1 + */ + cp_index = cm3_type - 1; + for (ap_idx = 0; ap_idx < ap_count; ap_idx++) { + /* Check if we should load this image + * according to number of CPs + */ + if (bl2_plat_get_cp_count(ap_idx) <= cp_index) { + NOTICE("Skipping MSS CP%d related image\n", + cp_index); + break; + } + + NOTICE("Load image to CP%d MSS AP%d\n", + cp_index, ap_idx); + ret = mss_image_load(single_img, image_size, + bl2_plat_get_cp_mss_regs( + ap_idx, cp_index)); + if (ret != 0) { + ERROR("SCP Image load failed\n"); + return -1; + } + } + break; + case MG_CP0: + case MG_CP1: + case MG_CP2: + cp_index = cm3_type - MG_CP0; + if (bl2_plat_get_cp_count(0) <= cp_index) { + NOTICE("Skipping MG CP%d related image\n", + cp_index); + break; + } + NOTICE("Load image to CP%d MG\n", cp_index); + ret = mg_image_load(single_img, image_size, + MG_CM3_SRAM_BASE(cp_index)); + if (ret != 0) { + ERROR("SCP Image load failed\n"); + return -1; + } + break; + default: + ERROR("SCP_BL2 wrong img format (cm3_type=%d)\n", cm3_type); + break; + } + + return 0; +} + +/* The Armada 8K has 5 service CPUs and Armada 7K has 3. Therefore it was + * required to provide a method for loading firmware to all of the service CPUs. + * To achieve that, the scp_bl2 image in fact is file containing up to 5 + * concatenated firmwares and this routine splits concatenated image into single + * images dedicated for appropriate service CPU and then load them. + */ +static int split_and_load_bl2_image(void *image) +{ + file_header_t *file_hdr; + img_header_t *img_hdr; + uintptr_t single_img; + int i; + + file_hdr = (file_header_t *)image; + + if (file_hdr->magic != FILE_MAGIC) { + ERROR("SCP_BL2 wrong img format\n"); + return -1; + } + + if (file_hdr->nr_of_imgs > MAX_NR_OF_FILES) { + ERROR("SCP_BL2 concatenated image contains too many images\n"); + return -1; + } + + img_hdr = (img_header_t *)((uintptr_t)image + sizeof(file_header_t)); + single_img = (uintptr_t)image + sizeof(file_header_t) + + sizeof(img_header_t) * file_hdr->nr_of_imgs; + + NOTICE("SCP_BL2 contains %d concatenated images\n", + file_hdr->nr_of_imgs); + for (i = 0; i < file_hdr->nr_of_imgs; i++) { + + /* Before loading make sanity check on header */ + if (img_hdr->version != HEADER_VERSION) { + ERROR("Wrong header, img corrupted exiting\n"); + return -1; + } + + load_img_to_cm3(img_hdr->type, single_img, img_hdr->length); + + /* Prepare offsets for next run */ + single_img += img_hdr->length; + img_hdr++; + } + + return 0; +} + +int scp_bootloader_transfer(void *image, unsigned int image_size) +{ +#ifdef SCP_BL2_BASE + assert((uintptr_t) image == SCP_BL2_BASE); +#endif + + VERBOSE("Concatenated img size %d\n", image_size); + + if (image_size == 0) { + ERROR("SCP_BL2 image size can't be 0 (current size = 0x%x)\n", + image_size); + return -1; + } + + if (split_and_load_bl2_image(image)) + return -1; + + return 0; +} diff --git a/plat/marvell/armada/common/mss/mss_scp_bootloader.h b/plat/marvell/armada/common/mss/mss_scp_bootloader.h new file mode 100644 index 000000000..4950d2472 --- /dev/null +++ b/plat/marvell/armada/common/mss/mss_scp_bootloader.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef MSS_SCP_BOOTLOADER_H +#define MSS_SCP_BOOTLOADER_H + +int scp_bootloader_transfer(void *image, unsigned int image_size); +uintptr_t bl2_plat_get_cp_mss_regs(int ap_idx, int cp_idx); +uintptr_t bl2_plat_get_ap_mss_regs(int ap_idx); +uint32_t bl2_plat_get_cp_count(int ap_idx); +uint32_t bl2_plat_get_ap_count(void); +void bl2_plat_configure_mss_windows(uintptr_t mss_regs); +int bl2_plat_mss_check_image_ready(void); + +#endif /* MSS_SCP_BOOTLOADER_H */ diff --git a/plat/marvell/armada/common/plat_delay_timer.c b/plat/marvell/armada/common/plat_delay_timer.c new file mode 100644 index 000000000..253975264 --- /dev/null +++ b/plat/marvell/armada/common/plat_delay_timer.c @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include + +#include + +#define SYS_COUNTER_FREQ_IN_MHZ (COUNTER_FREQUENCY/1000000) + +static uint32_t plat_get_timer_value(void) +{ + /* + * Generic delay timer implementation expects the timer to be a down + * counter. We apply bitwise NOT operator to the tick values returned + * by read_cntpct_el0() to simulate the down counter. + */ + return (uint32_t)(~read_cntpct_el0()); +} + +static const timer_ops_t plat_timer_ops = { + .get_timer_value = plat_get_timer_value, + .clk_mult = 1, + .clk_div = SYS_COUNTER_FREQ_IN_MHZ +}; + +void plat_delay_timer_init(void) +{ + timer_init(&plat_timer_ops); +} diff --git a/plat/marvell/common/aarch64/marvell_bl2_mem_params_desc.c b/plat/marvell/common/aarch64/marvell_bl2_mem_params_desc.c deleted file mode 100644 index 6a8e11c90..000000000 --- a/plat/marvell/common/aarch64/marvell_bl2_mem_params_desc.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. - * - * 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 - * 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[] = { -#ifdef SCP_BL2_BASE - /* Fill SCP_BL2 related information if it exists */ - { - .image_id = SCP_BL2_IMAGE_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, 0), - .image_info.image_base = SCP_BL2_BASE, - .image_info.image_max_size = SCP_BL2_SIZE, - - .next_handoff_image_id = INVALID_IMAGE_ID, - }, -#endif /* SCP_BL2_BASE */ - -#ifdef EL3_PAYLOAD_BASE - /* Fill EL3 payload related information (BL31 is EL3 payload)*/ - { - .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 = EL3_PAYLOAD_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_ATTRIB_SKIP_LOADING), - - .next_handoff_image_id = INVALID_IMAGE_ID, - }, - -#else /* EL3_PAYLOAD_BASE */ - - /* Fill BL31 related information */ - { - .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), -#if DEBUG - .ep_info.args.arg3 = MARVELL_BL31_PLAT_PARAM_VAL, -#endif - - 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, - -# ifdef BL32_BASE - .next_handoff_image_id = BL32_IMAGE_ID, -# else - .next_handoff_image_id = BL33_IMAGE_ID, -# endif - }, - -# ifdef BL32_BASE - /* 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_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_LIMIT - BL32_BASE, - - .next_handoff_image_id = BL33_IMAGE_ID, - }, -# endif /* BL32_BASE */ - - /* 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), -# ifdef PRELOADED_BL33_BASE - .ep_info.pc = PRELOADED_BL33_BASE, - - SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, - VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING), -# else - .ep_info.pc = MARVELL_DRAM_BASE, - - SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, - VERSION_2, image_info_t, 0), - .image_info.image_base = MARVELL_DRAM_BASE, - .image_info.image_max_size = MARVELL_DRAM_SIZE, -# endif /* PRELOADED_BL33_BASE */ - - .next_handoff_image_id = INVALID_IMAGE_ID, - } -#endif /* EL3_PAYLOAD_BASE */ -}; - -REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs) diff --git a/plat/marvell/common/aarch64/marvell_common.c b/plat/marvell/common/aarch64/marvell_common.c deleted file mode 100644 index 21a62d483..000000000 --- a/plat/marvell/common/aarch64/marvell_common.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -#include - -#include -#include -#include -#include -#include - -#include - -/* Weak definitions may be overridden in specific ARM standard platform */ -#pragma weak plat_get_ns_image_entrypoint -#pragma weak plat_marvell_get_mmap - -/* - * Set up the page tables for the generic and platform-specific memory regions. - * The extents of the generic memory regions are specified by the function - * arguments and consist of: - * - Trusted SRAM seen by the BL image; - * - Code section; - * - Read-only data section; - * - Coherent memory region, if applicable. - */ -void marvell_setup_page_tables(uintptr_t total_base, - size_t total_size, - uintptr_t code_start, - uintptr_t code_limit, - uintptr_t rodata_start, - uintptr_t rodata_limit -#if USE_COHERENT_MEM - , - uintptr_t coh_start, - uintptr_t coh_limit -#endif - ) -{ - /* - * Map the Trusted SRAM with appropriate memory attributes. - * Subsequent mappings will adjust the attributes for specific regions. - */ - VERBOSE("Trusted SRAM seen by this BL image: %p - %p\n", - (void *) total_base, (void *) (total_base + total_size)); - mmap_add_region(total_base, total_base, - total_size, - MT_MEMORY | MT_RW | MT_SECURE); - - /* Re-map the code section */ - VERBOSE("Code region: %p - %p\n", - (void *) code_start, (void *) code_limit); - mmap_add_region(code_start, code_start, - code_limit - code_start, - MT_CODE | MT_SECURE); - - /* Re-map the read-only data section */ - VERBOSE("Read-only data region: %p - %p\n", - (void *) rodata_start, (void *) rodata_limit); - mmap_add_region(rodata_start, rodata_start, - rodata_limit - rodata_start, - MT_RO_DATA | MT_SECURE); - -#if USE_COHERENT_MEM - /* Re-map the coherent memory region */ - VERBOSE("Coherent region: %p - %p\n", - (void *) coh_start, (void *) coh_limit); - mmap_add_region(coh_start, coh_start, - coh_limit - coh_start, - MT_DEVICE | MT_RW | MT_SECURE); -#endif - - /* Now (re-)map the platform-specific memory regions */ - mmap_add(plat_marvell_get_mmap()); - - /* Create the page tables to reflect the above mappings */ - init_xlat_tables(); -} - -unsigned long plat_get_ns_image_entrypoint(void) -{ - return PLAT_MARVELL_NS_IMAGE_OFFSET; -} - -/***************************************************************************** - * Gets SPSR for BL32 entry - ***************************************************************************** - */ -uint32_t marvell_get_spsr_for_bl32_entry(void) -{ - /* - * The Secure Payload Dispatcher service is responsible for - * setting the SPSR prior to entry into the BL32 image. - */ - return 0; -} - -/***************************************************************************** - * Gets SPSR for BL33 entry - ***************************************************************************** - */ -uint32_t marvell_get_spsr_for_bl33_entry(void) -{ - unsigned long el_status; - unsigned int mode; - uint32_t spsr; - - /* Figure out what mode we enter the non-secure world in */ - el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT; - el_status &= ID_AA64PFR0_ELX_MASK; - - mode = (el_status) ? MODE_EL2 : MODE_EL1; - - /* - * TODO: Consider the possibility of specifying the SPSR in - * the FIP ToC and allowing the platform to have a say as - * well. - */ - spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); - return spsr; -} - -/***************************************************************************** - * Returns ARM platform specific memory map regions. - ***************************************************************************** - */ -const mmap_region_t *plat_marvell_get_mmap(void) -{ - return plat_marvell_mmap; -} - diff --git a/plat/marvell/common/aarch64/marvell_helpers.S b/plat/marvell/common/aarch64/marvell_helpers.S deleted file mode 100644 index 6f625b95d..000000000 --- a/plat/marvell/common/aarch64/marvell_helpers.S +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include -#ifndef PLAT_a3700 -#include -#include -#endif -#include -#include - - .weak plat_marvell_calc_core_pos - .weak plat_my_core_pos - .globl plat_crash_console_init - .globl plat_crash_console_putc - .globl plat_crash_console_flush - .globl platform_mem_init - .globl disable_mmu_dcache - .globl invalidate_tlb_all - .globl platform_unmap_sram - .globl disable_sram - .globl disable_icache - .globl invalidate_icache_all - .globl marvell_exit_bootrom - .globl ca72_l2_enable_unique_clean - - /* ----------------------------------------------------- - * unsigned int plat_my_core_pos(void) - * This function uses the plat_marvell_calc_core_pos() - * definition to get the index of the calling CPU. - * ----------------------------------------------------- - */ -func plat_my_core_pos - mrs x0, mpidr_el1 - b plat_marvell_calc_core_pos -endfunc plat_my_core_pos - - /* ----------------------------------------------------- - * unsigned int plat_marvell_calc_core_pos(uint64_t mpidr) - * Helper function to calculate the core position. - * With this function: CorePos = (ClusterId * 2) + - * CoreId - * ----------------------------------------------------- - */ -func plat_marvell_calc_core_pos - and x1, x0, #MPIDR_CPU_MASK - and x0, x0, #MPIDR_CLUSTER_MASK - add x0, x1, x0, LSR #7 - ret -endfunc plat_marvell_calc_core_pos - - /* --------------------------------------------- - * int plat_crash_console_init(void) - * Function to initialize the crash console - * without a C Runtime to print crash report. - * Clobber list : x0, x1, x2 - * --------------------------------------------- - */ -func plat_crash_console_init - mov_imm x0, PLAT_MARVELL_CRASH_UART_BASE - mov_imm x1, PLAT_MARVELL_CRASH_UART_CLK_IN_HZ - mov_imm x2, MARVELL_CONSOLE_BAUDRATE -#ifdef PLAT_a3700 - b console_a3700_core_init -#else - b console_16550_core_init -#endif -endfunc plat_crash_console_init - - /* --------------------------------------------- - * int plat_crash_console_putc(int c) - * Function to print a character on the crash - * console without a C Runtime. - * Clobber list : x1, x2 - * --------------------------------------------- - */ -func plat_crash_console_putc - mov_imm x1, PLAT_MARVELL_CRASH_UART_BASE -#ifdef PLAT_a3700 - - b console_a3700_core_putc -#else - b console_16550_core_putc -#endif -endfunc plat_crash_console_putc - - /* --------------------------------------------- - * int plat_crash_console_flush() - * Function to force a write of all buffered - * data that hasn't been output. - * Out : return -1 on error else return 0. - * Clobber list : r0 - * --------------------------------------------- - */ -func plat_crash_console_flush - mov_imm x0, PLAT_MARVELL_CRASH_UART_BASE -#ifdef PLAT_a3700 - b console_a3700_core_flush -#else - b console_16550_core_flush -#endif -endfunc plat_crash_console_flush - - /* --------------------------------------------------------------------- - * We don't need to carry out any memory initialization on ARM - * platforms. The Secure RAM is accessible straight away. - * --------------------------------------------------------------------- - */ -func platform_mem_init - ret -endfunc platform_mem_init - - /* ----------------------------------------------------- - * Disable icache, dcache, and MMU - * ----------------------------------------------------- - */ -func disable_mmu_dcache - mrs x0, sctlr_el3 - bic x0, x0, 0x1 /* M bit - MMU */ - bic x0, x0, 0x4 /* C bit - Dcache L1 & L2 */ - msr sctlr_el3, x0 - isb - b mmu_off -mmu_off: - ret -endfunc disable_mmu_dcache - - /* ----------------------------------------------------- - * Disable all TLB entries - * ----------------------------------------------------- - */ -func invalidate_tlb_all - tlbi alle3 - dsb sy - isb - ret -endfunc invalidate_tlb_all - - /* ----------------------------------------------------- - * Disable the i cache - * ----------------------------------------------------- - */ -func disable_icache - mrs x0, sctlr_el3 - bic x0, x0, 0x1000 /* I bit - Icache L1 & L2 */ - msr sctlr_el3, x0 - isb - ret -endfunc disable_icache - - /* ----------------------------------------------------- - * Disable all of the i caches - * ----------------------------------------------------- - */ -func invalidate_icache_all - ic ialluis - isb sy - ret -endfunc invalidate_icache_all - - /* ----------------------------------------------------- - * Clear the SRAM enabling bit to unmap SRAM - * ----------------------------------------------------- - */ -func platform_unmap_sram - ldr x0, =CCU_SRAM_WIN_CR - str wzr, [x0] - ret -endfunc platform_unmap_sram - - /* ----------------------------------------------------- - * Disable the SRAM - * ----------------------------------------------------- - */ -func disable_sram - /* Disable the line lockings. They must be disabled expictly - * or the OS will have problems using the cache */ - ldr x1, =MASTER_LLC_TC0_LOCK - str wzr, [x1] - - /* Invalidate all ways */ - ldr w1, =LLC_WAY_MASK - ldr x0, =MASTER_L2X0_INV_WAY - str w1, [x0] - - /* Finally disable LLC */ - ldr x0, =MASTER_LLC_CTRL - str wzr, [x0] - - ret -endfunc disable_sram - - /* ----------------------------------------------------- - * Operation when exit bootROM: - * Disable the MMU - * Disable and invalidate the dcache - * Unmap and disable the SRAM - * Disable and invalidate the icache - * ----------------------------------------------------- - */ -func marvell_exit_bootrom - /* Save the system restore address */ - mov x28, x0 - - /* Close the caches and MMU */ - bl disable_mmu_dcache - - /* - * There is nothing important in the caches now, - * so invalidate them instead of cleaning. - */ - adr x0, __RW_START__ - adr x1, __RW_END__ - sub x1, x1, x0 - bl inv_dcache_range - bl invalidate_tlb_all - - /* - * Clean the memory mapping of SRAM - * the DDR mapping will remain to enable boot image to execute - */ - bl platform_unmap_sram - - /* Disable the SRAM */ - bl disable_sram - - /* Disable and invalidate icache */ - bl disable_icache - bl invalidate_icache_all - - mov x0, x28 - br x0 -endfunc marvell_exit_bootrom - - /* - * Enable L2 UniqueClean evictions with data - */ -func ca72_l2_enable_unique_clean - - mrs x0, CORTEX_A72_L2ACTLR_EL1 - orr x0, x0, #CORTEX_A72_L2ACTLR_ENABLE_UNIQUE_CLEAN - msr CORTEX_A72_L2ACTLR_EL1, x0 - - ret -endfunc ca72_l2_enable_unique_clean diff --git a/plat/marvell/common/marvell_bl1_setup.c b/plat/marvell/common/marvell_bl1_setup.c deleted file mode 100644 index 7b7cef39b..000000000 --- a/plat/marvell/common/marvell_bl1_setup.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -#include -#include -#include -#include -#include -#include - -#include - -/* Weak definitions may be overridden in specific Marvell standard platform */ -#pragma weak bl1_early_platform_setup -#pragma weak bl1_plat_arch_setup -#pragma weak bl1_platform_setup -#pragma weak bl1_plat_sec_mem_layout - -/* Data structure which holds the extents of the RAM for BL1*/ -static meminfo_t bl1_ram_layout; - -meminfo_t *bl1_plat_sec_mem_layout(void) -{ - return &bl1_ram_layout; -} - -/* - * BL1 specific platform actions shared between Marvell standard platforms. - */ -void marvell_bl1_early_platform_setup(void) -{ - /* Initialize the console to provide early debug support */ - marvell_console_boot_init(); - - /* Allow BL1 to see the whole Trusted RAM */ - bl1_ram_layout.total_base = MARVELL_BL_RAM_BASE; - bl1_ram_layout.total_size = MARVELL_BL_RAM_SIZE; -} - -void bl1_early_platform_setup(void) -{ - marvell_bl1_early_platform_setup(); -} - -/* - * Perform the very early platform specific architecture setup shared between - * MARVELL standard platforms. This only does basic initialization. Later - * architectural setup (bl1_arch_setup()) does not do anything platform - * specific. - */ -void marvell_bl1_plat_arch_setup(void) -{ - marvell_setup_page_tables(bl1_ram_layout.total_base, - bl1_ram_layout.total_size, - BL1_RO_BASE, - BL1_RO_LIMIT, - BL1_RO_DATA_BASE, - BL1_RO_DATA_END -#if USE_COHERENT_MEM - , BL_COHERENT_RAM_BASE, - BL_COHERENT_RAM_END -#endif - ); - enable_mmu_el3(0); -} - -void bl1_plat_arch_setup(void) -{ - marvell_bl1_plat_arch_setup(); -} - -/* - * Perform the platform specific architecture setup shared between - * MARVELL standard platforms. - */ -void marvell_bl1_platform_setup(void) -{ - /* Initialise the IO layer and register platform IO devices */ - plat_marvell_io_setup(); -} - -void bl1_platform_setup(void) -{ - marvell_bl1_platform_setup(); -} - -void bl1_plat_prepare_exit(entry_point_info_t *ep_info) -{ -#ifdef EL3_PAYLOAD_BASE - /* - * Program the EL3 payload's entry point address into the CPUs mailbox - * in order to release secondary CPUs from their holding pen and make - * them jump there. - */ - marvell_program_trusted_mailbox(ep_info->pc); - dsbsy(); - sev(); -#endif -} diff --git a/plat/marvell/common/marvell_bl2_setup.c b/plat/marvell/common/marvell_bl2_setup.c deleted file mode 100644 index 3c1c39112..000000000 --- a/plat/marvell/common/marvell_bl2_setup.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -/* Data structure which holds the extents of the trusted SRAM for BL2 */ -static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE); - -/* Weak definitions may be overridden in specific MARVELL standard platform */ -#pragma weak bl2_early_platform_setup2 -#pragma weak bl2_platform_setup -#pragma weak bl2_plat_arch_setup -#pragma weak bl2_plat_sec_mem_layout - -meminfo_t *bl2_plat_sec_mem_layout(void) -{ - return &bl2_tzram_layout; -} - -/***************************************************************************** - * BL1 has passed the extents of the trusted SRAM that should be visible to BL2 - * in x0. This memory layout is sitting at the base of the free trusted SRAM. - * Copy it to a safe location before its reclaimed by later BL2 functionality. - ***************************************************************************** - */ -void marvell_bl2_early_platform_setup(meminfo_t *mem_layout) -{ - /* Initialize the console to provide early debug support */ - marvell_console_boot_init(); - - /* Setup the BL2 memory layout */ - bl2_tzram_layout = *mem_layout; - - /* Initialise the IO layer and register platform IO devices */ - plat_marvell_io_setup(); -} - - -void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, - u_register_t arg2, u_register_t arg3) -{ - struct meminfo *mem_layout = (struct meminfo *)arg1; - - marvell_bl2_early_platform_setup(mem_layout); -} - -void bl2_platform_setup(void) -{ - /* Nothing to do */ -} - -/***************************************************************************** - * Perform the very early platform specific architectural setup here. At the - * moment this is only initializes the mmu in a quick and dirty way. - ***************************************************************************** - */ -void marvell_bl2_plat_arch_setup(void) -{ - marvell_setup_page_tables(bl2_tzram_layout.total_base, - bl2_tzram_layout.total_size, - BL_CODE_BASE, - BL_CODE_END, - BL_RO_DATA_BASE, - BL_RO_DATA_END -#if USE_COHERENT_MEM - , BL_COHERENT_RAM_BASE, - BL_COHERENT_RAM_END -#endif - ); - enable_mmu_el1(0); -} - -void bl2_plat_arch_setup(void) -{ - marvell_bl2_plat_arch_setup(); -} - -int marvell_bl2_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); - - assert(bl_mem_params); - - switch (image_id) { - - case BL33_IMAGE_ID: - /* BL33 expects to receive the primary CPU MPID (through r0) */ - bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr(); - bl_mem_params->ep_info.spsr = marvell_get_spsr_for_bl33_entry(); - break; -#ifdef SCP_BL2_BASE - case SCP_BL2_IMAGE_ID: - /* The subsequent handling of SCP_BL2 is platform specific */ - err = bl2_plat_handle_scp_bl2(&bl_mem_params->image_info); - if (err) { - WARN("Failure in platform-specific handling of SCP_BL2 image.\n"); - } - break; -#endif - default: - /* Do nothing in default case */ - break; - } - - return err; - -} - -/******************************************************************************* - * This function can be used by the platforms to update/use image - * information for given `image_id`. - ******************************************************************************/ -int bl2_plat_handle_post_image_load(unsigned int image_id) -{ - return marvell_bl2_handle_post_image_load(image_id); -} - diff --git a/plat/marvell/common/marvell_bl31_setup.c b/plat/marvell/common/marvell_bl31_setup.c deleted file mode 100644 index 26ba90654..000000000 --- a/plat/marvell/common/marvell_bl31_setup.c +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -#include -#include -#include -#ifdef USE_CCI -#include -#endif -#include -#include - -#include -#include -#include - -/* - * Placeholder variables for copying the arguments that have been passed to - * BL31 from BL2. - */ -static entry_point_info_t bl32_image_ep_info; -static entry_point_info_t bl33_image_ep_info; - -/* Weak definitions may be overridden in specific ARM standard platform */ -#pragma weak bl31_early_platform_setup2 -#pragma weak bl31_platform_setup -#pragma weak bl31_plat_arch_setup -#pragma weak bl31_plat_get_next_image_ep_info -#pragma weak plat_get_syscnt_freq2 - -/***************************************************************************** - * Return a pointer to the 'entry_point_info' structure of the next image for - * the security state specified. BL33 corresponds to the non-secure image type - * while BL32 corresponds to the secure image type. A NULL pointer is returned - * if the image does not exist. - ***************************************************************************** - */ -entry_point_info_t *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; - - return next_image_info; -} - -/***************************************************************************** - * Perform any BL31 early platform setup common to ARM standard platforms. - * Here is an opportunity to copy parameters passed by the calling EL (S-EL1 - * in BL2 & EL3 in BL1) before they are lost (potentially). This needs to be - * done before the MMU is initialized so that the memory layout can be used - * while creating page tables. BL2 has flushed this information to memory, so - * we are guaranteed to pick up good data. - ***************************************************************************** - */ -void marvell_bl31_early_platform_setup(void *from_bl2, - uintptr_t soc_fw_config, - uintptr_t hw_config, - void *plat_params_from_bl2) -{ - /* Initialize the console to provide early debug support */ - marvell_console_boot_init(); - -#if RESET_TO_BL31 - /* There are no parameters from BL2 if BL31 is a reset vector */ - assert(from_bl2 == NULL); - assert(plat_params_from_bl2 == NULL); - -#ifdef BL32_BASE - /* Populate entry point information for BL32 */ - SET_PARAM_HEAD(&bl32_image_ep_info, - PARAM_EP, - VERSION_1, - 0); - SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE); - bl32_image_ep_info.pc = BL32_BASE; - bl32_image_ep_info.spsr = marvell_get_spsr_for_bl32_entry(); -#endif /* BL32_BASE */ - - /* Populate entry point information for BL33 */ - SET_PARAM_HEAD(&bl33_image_ep_info, - PARAM_EP, - VERSION_1, - 0); - /* - * Tell BL31 where the non-trusted software image - * is located and the entry state information - */ - bl33_image_ep_info.pc = plat_get_ns_image_entrypoint(); - bl33_image_ep_info.spsr = marvell_get_spsr_for_bl33_entry(); - SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); - -#else - /* - * In debug builds, we pass a special value in 'plat_params_from_bl2' - * to verify platform parameters from BL2 to BL31. - * In release builds, it's not used. - */ - assert(((unsigned long long)plat_params_from_bl2) == - MARVELL_BL31_PLAT_PARAM_VAL); - - /* - * Check params passed from BL2 should not be NULL, - */ - bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2; - assert(params_from_bl2 != NULL); - assert(params_from_bl2->h.type == PARAM_BL_PARAMS); - assert(params_from_bl2->h.version >= VERSION_2); - - bl_params_node_t *bl_params = params_from_bl2->head; - - /* - * Copy BL33 and BL32 (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) - bl32_image_ep_info = *bl_params->ep_info; - - if (bl_params->image_id == BL33_IMAGE_ID) - bl33_image_ep_info = *bl_params->ep_info; - - bl_params = bl_params->next_params_info; - } -#endif -} - -void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, - u_register_t arg2, u_register_t arg3) - -{ - marvell_bl31_early_platform_setup((void *)arg0, arg1, arg2, - (void *)arg3); - -#ifdef USE_CCI - /* - * Initialize CCI for this cluster during cold boot. - * No need for locks as no other CPU is active. - */ - plat_marvell_interconnect_init(); - - /* - * Enable CCI coherency for the primary CPU's cluster. - * Platform specific PSCI code will enable coherency for other - * clusters. - */ - plat_marvell_interconnect_enter_coherency(); -#endif -} - -/***************************************************************************** - * Perform any BL31 platform setup common to ARM standard platforms - ***************************************************************************** - */ -void marvell_bl31_platform_setup(void) -{ - /* Initialize the GIC driver, cpu and distributor interfaces */ - plat_marvell_gic_driver_init(); - plat_marvell_gic_init(); - - /* For Armada-8k-plus family, the SoC includes more than - * a single AP die, but the default die that boots is AP #0. - * For other families there is only one die (#0). - * Initialize psci arch from die 0 - */ - marvell_psci_arch_init(0); -} - -/***************************************************************************** - * Perform any BL31 platform runtime setup prior to BL31 exit common to ARM - * standard platforms - ***************************************************************************** - */ -void marvell_bl31_plat_runtime_setup(void) -{ - console_switch_state(CONSOLE_FLAG_RUNTIME); - - /* Initialize the runtime console */ - marvell_console_runtime_init(); -} - -void bl31_platform_setup(void) -{ - marvell_bl31_platform_setup(); -} - -void bl31_plat_runtime_setup(void) -{ - marvell_bl31_plat_runtime_setup(); -} - -/***************************************************************************** - * Perform the very early platform specific architectural setup shared between - * ARM standard platforms. This only does basic initialization. Later - * architectural setup (bl31_arch_setup()) does not do anything platform - * specific. - ***************************************************************************** - */ -void marvell_bl31_plat_arch_setup(void) -{ - marvell_setup_page_tables(BL31_BASE, - BL31_END - BL31_BASE, - BL_CODE_BASE, - BL_CODE_END, - BL_RO_DATA_BASE, - BL_RO_DATA_END -#if USE_COHERENT_MEM - , BL_COHERENT_RAM_BASE, - BL_COHERENT_RAM_END -#endif - ); - -#if BL31_CACHE_DISABLE - enable_mmu_el3(DISABLE_DCACHE); - INFO("Cache is disabled in BL3\n"); -#else - enable_mmu_el3(0); -#endif -} - -void bl31_plat_arch_setup(void) -{ - marvell_bl31_plat_arch_setup(); -} - -unsigned int plat_get_syscnt_freq2(void) -{ - return PLAT_REF_CLK_IN_HZ; -} diff --git a/plat/marvell/common/marvell_cci.c b/plat/marvell/common/marvell_cci.c deleted file mode 100644 index 80351aedc..000000000 --- a/plat/marvell/common/marvell_cci.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -#include - -static const int cci_map[] = { - PLAT_MARVELL_CCI_CLUSTER0_SL_IFACE_IX, - PLAT_MARVELL_CCI_CLUSTER1_SL_IFACE_IX -}; - -/**************************************************************************** - * The following functions are defined as weak to allow a platform to override - * the way ARM CCI driver is initialised and used. - **************************************************************************** - */ -#pragma weak plat_marvell_interconnect_init -#pragma weak plat_marvell_interconnect_enter_coherency -#pragma weak plat_marvell_interconnect_exit_coherency - - -/**************************************************************************** - * Helper function to initialize ARM CCI driver. - **************************************************************************** - */ -void plat_marvell_interconnect_init(void) -{ - cci_init(PLAT_MARVELL_CCI_BASE, cci_map, ARRAY_SIZE(cci_map)); -} - -/**************************************************************************** - * Helper function to place current master into coherency - **************************************************************************** - */ -void plat_marvell_interconnect_enter_coherency(void) -{ - cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr_el1())); -} - -/**************************************************************************** - * Helper function to remove current master from coherency - **************************************************************************** - */ -void plat_marvell_interconnect_exit_coherency(void) -{ - cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr_el1())); -} diff --git a/plat/marvell/common/marvell_common.mk b/plat/marvell/common/marvell_common.mk deleted file mode 100644 index f41d7a47f..000000000 --- a/plat/marvell/common/marvell_common.mk +++ /dev/null @@ -1,72 +0,0 @@ -# Copyright (C) 2018 Marvell International Ltd. -# -# SPDX-License-Identifier: BSD-3-Clause -# https://spdx.org/licenses - -MARVELL_PLAT_BASE := plat/marvell -MARVELL_PLAT_INCLUDE_BASE := include/plat/marvell - -include $(MARVELL_PLAT_BASE)/version.mk -include $(MARVELL_PLAT_BASE)/marvell.mk - -VERSION_STRING +=(Marvell-${SUBVERSION}) - -SEPARATE_CODE_AND_RODATA := 1 - -# flag to switch from PLL to ARO -ARO_ENABLE := 0 -$(eval $(call add_define,ARO_ENABLE)) -# Enable/Disable LLC -LLC_ENABLE := 1 -$(eval $(call add_define,LLC_ENABLE)) - -include lib/xlat_tables_v2/xlat_tables.mk - -PLAT_INCLUDES += -I$(MARVELL_PLAT_INCLUDE_BASE)/common \ - -I$(MARVELL_PLAT_INCLUDE_BASE)/common/aarch64 - - -PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS} \ - $(MARVELL_PLAT_BASE)/common/aarch64/marvell_common.c \ - $(MARVELL_PLAT_BASE)/common/aarch64/marvell_helpers.S \ - $(MARVELL_COMMON_BASE)/marvell_console.c - -BL1_SOURCES += drivers/delay_timer/delay_timer.c \ - drivers/io/io_fip.c \ - drivers/io/io_memmap.c \ - drivers/io/io_storage.c \ - $(MARVELL_PLAT_BASE)/common/marvell_bl1_setup.c \ - $(MARVELL_PLAT_BASE)/common/marvell_io_storage.c \ - $(MARVELL_PLAT_BASE)/common/plat_delay_timer.c - -ifdef EL3_PAYLOAD_BASE -# Need the arm_program_trusted_mailbox() function to release secondary CPUs from -# their holding pen -endif - -BL2_SOURCES += drivers/io/io_fip.c \ - drivers/io/io_memmap.c \ - drivers/io/io_storage.c \ - common/desc_image_load.c \ - $(MARVELL_PLAT_BASE)/common/marvell_bl2_setup.c \ - $(MARVELL_PLAT_BASE)/common/marvell_io_storage.c \ - $(MARVELL_PLAT_BASE)/common/aarch64/marvell_bl2_mem_params_desc.c \ - $(MARVELL_PLAT_BASE)/common/marvell_image_load.c - - -BL31_SOURCES += $(MARVELL_PLAT_BASE)/common/marvell_bl31_setup.c \ - $(MARVELL_PLAT_BASE)/common/marvell_pm.c \ - $(MARVELL_PLAT_BASE)/common/marvell_topology.c \ - plat/common/plat_psci_common.c \ - $(MARVELL_PLAT_BASE)/common/plat_delay_timer.c \ - drivers/delay_timer/delay_timer.c - -# PSCI functionality -$(eval $(call add_define,CONFIG_ARM64)) - -# MSS (SCP) build -ifeq (${MSS_SUPPORT}, 1) -include $(MARVELL_PLAT_BASE)/common/mss/mss_common.mk -endif - -fip: mrvl_flash diff --git a/plat/marvell/common/marvell_console.c b/plat/marvell/common/marvell_console.c deleted file mode 100644 index 17166618a..000000000 --- a/plat/marvell/common/marvell_console.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ -#include - -#include - -#include -#include - -#include - -#ifdef PLAT_a3700 -#include -#define console_marvell_register console_a3700_register -#else -#include -#define console_marvell_register console_16550_register -#endif - -static console_t marvell_boot_console; -static console_t marvell_runtime_console; - -/******************************************************************************* - * Functions that set up the console - ******************************************************************************/ - -/* Initialize the console to provide early debug support */ -void marvell_console_boot_init(void) -{ - int rc = - console_marvell_register(PLAT_MARVELL_BOOT_UART_BASE, - PLAT_MARVELL_BOOT_UART_CLK_IN_HZ, - MARVELL_CONSOLE_BAUDRATE, - &marvell_boot_console); - if (rc == 0) { - /* - * The crash console doesn't use the multi console API, it uses - * the core console functions directly. It is safe to call panic - * and let it print debug information. - */ - panic(); - } - - console_set_scope(&marvell_boot_console, CONSOLE_FLAG_BOOT); -} - -void marvell_console_boot_end(void) -{ - (void)console_flush(); - - (void)console_unregister(&marvell_boot_console); -} - -/* Initialize the runtime console */ -void marvell_console_runtime_init(void) -{ - int rc = - console_marvell_register(PLAT_MARVELL_BOOT_UART_BASE, - PLAT_MARVELL_BOOT_UART_CLK_IN_HZ, - MARVELL_CONSOLE_BAUDRATE, - &marvell_runtime_console); - if (rc == 0) - panic(); - - console_set_scope(&marvell_runtime_console, CONSOLE_FLAG_RUNTIME); -} - -void marvell_console_runtime_end(void) -{ - (void)console_flush(); - - (void)console_unregister(&marvell_runtime_console); -} diff --git a/plat/marvell/common/marvell_ddr_info.c b/plat/marvell/common/marvell_ddr_info.c deleted file mode 100644 index 734099652..000000000 --- a/plat/marvell/common/marvell_ddr_info.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -#include -#include - -#include - -#define DRAM_CH0_MMAP_LOW_REG(iface, cs, base) \ - (base + DRAM_CH0_MMAP_LOW_OFFSET + (iface) * 0x10000 + (cs) * 0x8) -#define DRAM_CH0_MMAP_HIGH_REG(iface, cs, base) \ - (DRAM_CH0_MMAP_LOW_REG(iface, cs, base) + 4) -#define DRAM_CS_VALID_ENABLED_MASK 0x1 -#define DRAM_AREA_LENGTH_OFFS 16 -#define DRAM_AREA_LENGTH_MASK (0x1f << DRAM_AREA_LENGTH_OFFS) -#define DRAM_START_ADDRESS_L_OFFS 23 -#define DRAM_START_ADDRESS_L_MASK \ - (0x1ff << DRAM_START_ADDRESS_L_OFFS) -#define DRAM_START_ADDR_HTOL_OFFS 32 - -#define DRAM_MAX_CS_NUM 2 - -#define DRAM_CS_ENABLED(iface, cs, base) \ - (mmio_read_32(DRAM_CH0_MMAP_LOW_REG(iface, cs, base)) & \ - DRAM_CS_VALID_ENABLED_MASK) -#define GET_DRAM_REGION_SIZE_CODE(iface, cs, base) \ - (mmio_read_32(DRAM_CH0_MMAP_LOW_REG(iface, cs, base)) & \ - DRAM_AREA_LENGTH_MASK) >> DRAM_AREA_LENGTH_OFFS - -/* Mapping between DDR area length and real DDR size is specific and looks like - * bellow: - * 0 => 384 MB - * 1 => 768 MB - * 2 => 1536 MB - * 3 => 3 GB - * 4 => 6 GB - * - * 7 => 8 MB - * 8 => 16 MB - * 9 => 32 MB - * 10 => 64 MB - * 11 => 128 MB - * 12 => 256 MB - * 13 => 512 MB - * 14 => 1 GB - * 15 => 2 GB - * 16 => 4 GB - * 17 => 8 GB - * 18 => 16 GB - * 19 => 32 GB - * 20 => 64 GB - * 21 => 128 GB - * 22 => 256 GB - * 23 => 512 GB - * 24 => 1 TB - * 25 => 2 TB - * 26 => 4 TB - * - * to calculate real size we need to use two different formulas: - * -- GET_DRAM_REGION_SIZE_ODD for values 0-4 (DRAM_REGION_SIZE_ODD) - * -- GET_DRAM_REGION_SIZE_EVEN for values 7-26 (DRAM_REGION_SIZE_EVEN) - * using mentioned formulas we cover whole mapping between "Area length" value - * and real size (see above mapping). - */ -#define DRAM_REGION_SIZE_EVEN(C) (((C) >= 7) && ((C) <= 26)) -#define GET_DRAM_REGION_SIZE_EVEN(C) ((uint64_t)1 << ((C) + 16)) -#define DRAM_REGION_SIZE_ODD(C) ((C) <= 4) -#define GET_DRAM_REGION_SIZE_ODD(C) ((uint64_t)0x18000000 << (C)) - - -uint64_t mvebu_get_dram_size(uint64_t ap_base_addr) -{ - uint64_t mem_size = 0; - uint8_t region_code; - uint8_t cs, iface; - - for (iface = 0; iface < DRAM_MAX_IFACE; iface++) { - for (cs = 0; cs < DRAM_MAX_CS_NUM; cs++) { - - /* Exit loop on first disabled DRAM CS */ - if (!DRAM_CS_ENABLED(iface, cs, ap_base_addr)) - break; - - /* Decode area length for current CS - * from register value - */ - region_code = - GET_DRAM_REGION_SIZE_CODE(iface, cs, - ap_base_addr); - - if (DRAM_REGION_SIZE_EVEN(region_code)) { - mem_size += - GET_DRAM_REGION_SIZE_EVEN(region_code); - } else if (DRAM_REGION_SIZE_ODD(region_code)) { - mem_size += - GET_DRAM_REGION_SIZE_ODD(region_code); - } else { - WARN("%s: Invalid mem region (0x%x) CS#%d\n", - __func__, region_code, cs); - return 0; - } - } - } - - return mem_size; -} diff --git a/plat/marvell/common/marvell_gicv2.c b/plat/marvell/common/marvell_gicv2.c deleted file mode 100644 index 2505c9f84..000000000 --- a/plat/marvell/common/marvell_gicv2.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -#include -#include -#include -#include -#include -#include - -#include - -/* - * The following functions are defined as weak to allow a platform to override - * the way the GICv2 driver is initialised and used. - */ -#pragma weak plat_marvell_gic_driver_init -#pragma weak plat_marvell_gic_init - -#define A7K8K_PIC_CAUSE_REG 0xf03f0100 -#define A7K8K_PIC0_MASK_REG 0xf03f0108 - -#define A7K8K_PIC_PMUOF_IRQ_MASK (1 << 17) - -#define A7K8K_PIC_MAX_IRQS 32 -#define A7K8K_PIC_MAX_IRQ_MASK ((1UL << A7K8K_PIC_MAX_IRQS) - 1) - -#define A7K8K_ODMIN_SET_REG 0xf0300040 -#define A7K8K_ODMI_PMU_IRQ(idx) ((2 + idx) << 12) - -#define A7K8K_ODMI_PMU_GIC_IRQ(idx) (130 + idx) - -static DEFINE_BAKERY_LOCK(a7k8k_irq_lock); - -/* - * On a GICv2 system, the Group 1 secure interrupts are treated as Group 0 - * interrupts. - */ -static const interrupt_prop_t marvell_interrupt_props[] = { - PLAT_MARVELL_G1S_IRQ_PROPS(GICV2_INTR_GROUP0), - PLAT_MARVELL_G0_IRQ_PROPS(GICV2_INTR_GROUP0) -}; - -static unsigned int target_mask_array[PLATFORM_CORE_COUNT]; - -/* - * Ideally `marvell_gic_data` structure definition should be a `const` but it is - * kept as modifiable for overwriting with different GICD and GICC base when - * running on FVP with VE memory map. - */ -static gicv2_driver_data_t marvell_gic_data = { - .gicd_base = PLAT_MARVELL_GICD_BASE, - .gicc_base = PLAT_MARVELL_GICC_BASE, - .interrupt_props = marvell_interrupt_props, - .interrupt_props_num = ARRAY_SIZE(marvell_interrupt_props), - .target_masks = target_mask_array, - .target_masks_num = ARRAY_SIZE(target_mask_array), -}; - -/* - * ARM common helper to initialize the GICv2 only driver. - */ -void plat_marvell_gic_driver_init(void) -{ - gicv2_driver_init(&marvell_gic_data); -} - -static uint64_t a7k8k_pmu_interrupt_handler(uint32_t id, - uint32_t flags, - void *handle, - void *cookie) -{ - unsigned int idx = plat_my_core_pos(); - uint32_t irq; - - bakery_lock_get(&a7k8k_irq_lock); - - /* Acknowledge IRQ */ - irq = plat_ic_acknowledge_interrupt(); - - plat_ic_end_of_interrupt(irq); - - if (irq != MARVELL_IRQ_PIC0) { - bakery_lock_release(&a7k8k_irq_lock); - return 0; - } - - /* Acknowledge PMU overflow IRQ in PIC0 */ - mmio_setbits_32(A7K8K_PIC_CAUSE_REG, A7K8K_PIC_PMUOF_IRQ_MASK); - - /* Trigger ODMI Frame IRQ */ - mmio_write_32(A7K8K_ODMIN_SET_REG, A7K8K_ODMI_PMU_IRQ(idx)); - - bakery_lock_release(&a7k8k_irq_lock); - - return 0; -} - -void mvebu_pmu_interrupt_enable(void) -{ - unsigned int idx; - uint32_t flags; - int32_t rc; - - /* Reset PIC */ - mmio_write_32(A7K8K_PIC_CAUSE_REG, A7K8K_PIC_MAX_IRQ_MASK); - /* Unmask PMU overflow IRQ in PIC0 */ - mmio_clrbits_32(A7K8K_PIC0_MASK_REG, A7K8K_PIC_PMUOF_IRQ_MASK); - - /* Configure ODMI Frame IRQs as edge triggered */ - for (idx = 0; idx < PLATFORM_CORE_COUNT; idx++) - gicv2_interrupt_set_cfg(A7K8K_ODMI_PMU_GIC_IRQ(idx), - GIC_INTR_CFG_EDGE); - - /* - * Register IRQ handler as INTR_TYPE_S_EL1 as its the only valid type - * for GICv2 in ARM-TF. - */ - flags = 0U; - set_interrupt_rm_flag((flags), (NON_SECURE)); - rc = register_interrupt_type_handler(INTR_TYPE_S_EL1, - a7k8k_pmu_interrupt_handler, - flags); - if (rc != 0) - panic(); -} - -void mvebu_pmu_interrupt_disable(void) -{ - /* Reset PIC */ - mmio_write_32(A7K8K_PIC_CAUSE_REG, A7K8K_PIC_MAX_IRQ_MASK); - /* Mask PMU overflow IRQ in PIC0 */ - mmio_setbits_32(A7K8K_PIC0_MASK_REG, A7K8K_PIC_PMUOF_IRQ_MASK); -} - -void plat_marvell_gic_init(void) -{ - gicv2_distif_init(); - gicv2_pcpu_distif_init(); - gicv2_set_pe_target_mask(plat_my_core_pos()); - gicv2_cpuif_enable(); -} diff --git a/plat/marvell/common/marvell_gicv3.c b/plat/marvell/common/marvell_gicv3.c deleted file mode 100644 index 0bd554570..000000000 --- a/plat/marvell/common/marvell_gicv3.c +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -#include -#include -#include -#include - -#include -#include - -/****************************************************************************** - * The following functions are defined as weak to allow a platform to override - * the way the GICv3 driver is initialised and used. - ****************************************************************************** - */ -#pragma weak plat_marvell_gic_driver_init -#pragma weak plat_marvell_gic_init -#pragma weak plat_marvell_gic_cpuif_enable -#pragma weak plat_marvell_gic_cpuif_disable -#pragma weak plat_marvell_gic_pcpu_init - -/* The GICv3 driver only needs to be initialized in EL3 */ -static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT]; - -static const interrupt_prop_t marvell_interrupt_props[] = { - PLAT_MARVELL_G1S_IRQ_PROPS(INTR_GROUP1S), - PLAT_MARVELL_G0_IRQ_PROPS(INTR_GROUP0) -}; - -/* - * We save and restore the GICv3 context on system suspend. Allocate the - * data in the designated EL3 Secure carve-out memory - */ -static gicv3_redist_ctx_t rdist_ctx __section("arm_el3_tzc_dram"); -static gicv3_dist_ctx_t dist_ctx __section("arm_el3_tzc_dram"); - -/* - * MPIDR hashing function for translating MPIDRs read from GICR_TYPER register - * to core position. - * - * Calculating core position is dependent on MPIDR_EL1.MT bit. However, affinity - * values read from GICR_TYPER don't have an MT field. To reuse the same - * translation used for CPUs, we insert MT bit read from the PE's MPIDR into - * that read from GICR_TYPER. - * - * Assumptions: - * - * - All CPUs implemented in the system have MPIDR_EL1.MT bit set; - * - No CPUs implemented in the system use affinity level 3. - */ -static unsigned int marvell_gicv3_mpidr_hash(u_register_t mpidr) -{ - mpidr |= (read_mpidr_el1() & MPIDR_MT_MASK); - return plat_marvell_calc_core_pos(mpidr); -} - -const gicv3_driver_data_t marvell_gic_data = { - .gicd_base = PLAT_MARVELL_GICD_BASE, - .gicr_base = PLAT_MARVELL_GICR_BASE, - .interrupt_props = marvell_interrupt_props, - .interrupt_props_num = ARRAY_SIZE(marvell_interrupt_props), - .rdistif_num = PLATFORM_CORE_COUNT, - .rdistif_base_addrs = rdistif_base_addrs, - .mpidr_to_core_pos = marvell_gicv3_mpidr_hash -}; - -void plat_marvell_gic_driver_init(void) -{ - /* - * The GICv3 driver is initialized in EL3 and does not need - * to be initialized again in SEL1. This is because the S-EL1 - * can use GIC system registers to manage interrupts and does - * not need GIC interface base addresses to be configured. - */ -#if IMAGE_BL31 - gicv3_driver_init(&marvell_gic_data); -#endif -} - -/****************************************************************************** - * Marvell common helper to initialize the GIC. Only invoked by BL31 - ****************************************************************************** - */ -void plat_marvell_gic_init(void) -{ - /* Initialize GIC-600 Multi Chip feature, - * only if the maximum number of north bridges - * is more than 1 - otherwise no need for multi - * chip feature initialization - */ -#if (PLAT_MARVELL_NORTHB_COUNT > 1) - if (gic600_multi_chip_init()) - ERROR("GIC-600 Multi Chip initialization failed\n"); -#endif - gicv3_distif_init(); - gicv3_rdistif_init(plat_my_core_pos()); - gicv3_cpuif_enable(plat_my_core_pos()); -} - -/****************************************************************************** - * Marvell common helper to enable the GIC CPU interface - ****************************************************************************** - */ -void plat_marvell_gic_cpuif_enable(void) -{ - gicv3_cpuif_enable(plat_my_core_pos()); -} - -/****************************************************************************** - * Marvell common helper to disable the GIC CPU interface - ****************************************************************************** - */ -void plat_marvell_gic_cpuif_disable(void) -{ - gicv3_cpuif_disable(plat_my_core_pos()); -} - -/****************************************************************************** - * Marvell common helper to init. the per-cpu redistributor interface in GICv3 - ****************************************************************************** - */ -void plat_marvell_gic_pcpu_init(void) -{ - gicv3_rdistif_init(plat_my_core_pos()); -} - -/****************************************************************************** - * Marvell common helper to save SPI irq states in GICv3 - ****************************************************************************** - */ -void plat_marvell_gic_irq_save(void) -{ - - /* - * If an ITS is available, save its context before - * the Redistributor using: - * gicv3_its_save_disable(gits_base, &its_ctx[i]) - * Additionally, an implementation-defined sequence may - * be required to save the whole ITS state. - */ - - /* - * Save the GIC Redistributors and ITS contexts before the - * Distributor context. As we only handle SYSTEM SUSPEND API, - * we only need to save the context of the CPU that is issuing - * the SYSTEM SUSPEND call, i.e. the current CPU. - */ - gicv3_rdistif_save(plat_my_core_pos(), &rdist_ctx); - - /* Save the GIC Distributor context */ - gicv3_distif_save(&dist_ctx); - - /* - * From here, all the components of the GIC can be safely powered down - * as long as there is an alternate way to handle wakeup interrupt - * sources. - */ -} - -/****************************************************************************** - * Marvell common helper to restore SPI irq states in GICv3 - ****************************************************************************** - */ -void plat_marvell_gic_irq_restore(void) -{ - /* Restore the GIC Distributor context */ - gicv3_distif_init_restore(&dist_ctx); - - /* - * Restore the GIC Redistributor and ITS contexts after the - * Distributor context. As we only handle SYSTEM SUSPEND API, - * we only need to restore the context of the CPU that issued - * the SYSTEM SUSPEND call. - */ - gicv3_rdistif_init_restore(plat_my_core_pos(), &rdist_ctx); - - /* - * If an ITS is available, restore its context after - * the Redistributor using: - * gicv3_its_restore(gits_base, &its_ctx[i]) - * An implementation-defined sequence may be required to - * restore the whole ITS state. The ITS must also be - * re-enabled after this sequence has been executed. - */ -} - -/****************************************************************************** - * Marvell common helper to save per-cpu PPI irq states in GICv3 - ****************************************************************************** - */ -void plat_marvell_gic_irq_pcpu_save(void) -{ - gicv3_rdistif_save(plat_my_core_pos(), &rdist_ctx); -} - -/****************************************************************************** - * Marvell common helper to restore per-cpu PPI irq states in GICv3 - ****************************************************************************** - */ -void plat_marvell_gic_irq_pcpu_restore(void) -{ - gicv3_rdistif_init_restore(plat_my_core_pos(), &rdist_ctx); -} diff --git a/plat/marvell/common/marvell_image_load.c b/plat/marvell/common/marvell_image_load.c deleted file mode 100644 index be16b0898..000000000 --- a/plat/marvell/common/marvell_image_load.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include -#include -#include - -/******************************************************************************* - * This function flushes the data structures so that they are visible - * in memory for the next BL image. - ******************************************************************************/ -void plat_flush_next_bl_params(void) -{ - flush_bl_params_desc(); -} - -/******************************************************************************* - * This function returns the list of loadable images. - ******************************************************************************/ -bl_load_info_t *plat_get_bl_image_load_info(void) -{ - return get_bl_load_info_from_mem_params_desc(); -} - -/******************************************************************************* - * This function returns the list of executable images. - ******************************************************************************/ -bl_params_t *plat_get_next_bl_params(void) -{ - return get_next_bl_params_from_mem_params_desc(); -} diff --git a/plat/marvell/common/marvell_io_storage.c b/plat/marvell/common/marvell_io_storage.c deleted file mode 100644 index 065f95688..000000000 --- a/plat/marvell/common/marvell_io_storage.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -/* IO devices */ -static const io_dev_connector_t *fip_dev_con; -static uintptr_t fip_dev_handle; -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 = PLAT_MARVELL_FIP_BASE, - .length = PLAT_MARVELL_FIP_MAX_SIZE -}; - -static const io_uuid_spec_t bl2_uuid_spec = { - .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2, -}; - -static const io_uuid_spec_t scp_bl2_uuid_spec = { - .uuid = UUID_SCP_FIRMWARE_SCP_BL2, -}; - -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 bl33_uuid_spec = { - .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33, -}; - -static int open_fip(const uintptr_t spec); -static int open_memmap(const uintptr_t spec); - -struct plat_io_policy { - uintptr_t *dev_handle; - uintptr_t image_spec; - int (*check)(const uintptr_t spec); -}; - -/* By default, Marvell platforms load images from the FIP */ -static const struct plat_io_policy policies[] = { - [FIP_IMAGE_ID] = { - &memmap_dev_handle, - (uintptr_t)&fip_block_spec, - open_memmap - }, - [BL2_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&bl2_uuid_spec, - open_fip - }, - [SCP_BL2_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&scp_bl2_uuid_spec, - open_fip - }, - [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 - }, - [BL33_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&bl33_uuid_spec, - open_fip - }, -}; - - -/* Weak definitions may be overridden in specific ARM standard platform */ -#pragma weak plat_marvell_io_setup -#pragma weak plat_marvell_get_alt_image_source - - -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; -} - - -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; -} - - -void marvell_io_setup(void) -{ - int io_result; - - io_result = register_io_dev_fip(&fip_dev_con); - assert(io_result == 0); - - io_result = register_io_dev_memmap(&memmap_dev_con); - assert(io_result == 0); - - /* Open connections to devices and cache the handles */ - io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, - &fip_dev_handle); - assert(io_result == 0); - - io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, - &memmap_dev_handle); - assert(io_result == 0); - - /* Ignore improbable errors in release builds */ - (void)io_result; -} - -void plat_marvell_io_setup(void) -{ - marvell_io_setup(); -} - -int plat_marvell_get_alt_image_source( - unsigned int image_id __attribute__((unused)), - uintptr_t *dev_handle __attribute__((unused)), - uintptr_t *image_spec __attribute__((unused))) -{ - /* By default do not try an alternative */ - return -ENOENT; -} - -/* - * 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 result; - const struct plat_io_policy *policy; - - assert(image_id < ARRAY_SIZE(policies)); - - policy = &policies[image_id]; - result = policy->check(policy->image_spec); - if (result == 0) { - *image_spec = policy->image_spec; - *dev_handle = *(policy->dev_handle); - } else { - VERBOSE("Trying alternative IO\n"); - result = plat_marvell_get_alt_image_source(image_id, dev_handle, - image_spec); - } - - return result; -} - -/* - * See if a Firmware Image Package is available, - * by checking if TOC is valid or not. - */ -int marvell_io_is_toc_valid(void) -{ - int result; - - result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); - - return result == 0; -} diff --git a/plat/marvell/common/marvell_pm.c b/plat/marvell/common/marvell_pm.c deleted file mode 100644 index 3c675b296..000000000 --- a/plat/marvell/common/marvell_pm.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -#include -#include - -#include - -/* Standard ARM platforms are expected to export plat_arm_psci_pm_ops */ -extern const plat_psci_ops_t plat_arm_psci_pm_ops; - -/***************************************************************************** - * Private function to program the mailbox for a cpu before it is released - * from reset. This function assumes that the mail box base is within - * the MARVELL_SHARED_RAM region - ***************************************************************************** - */ -void marvell_program_mailbox(uintptr_t address) -{ - uintptr_t *mailbox = (void *)PLAT_MARVELL_MAILBOX_BASE; - - /* - * Ensure that the PLAT_MARVELL_MAILBOX_BASE is within - * MARVELL_SHARED_RAM region. - */ - assert((PLAT_MARVELL_MAILBOX_BASE >= MARVELL_SHARED_RAM_BASE) && - ((PLAT_MARVELL_MAILBOX_BASE + sizeof(*mailbox)) <= - (MARVELL_SHARED_RAM_BASE + MARVELL_SHARED_RAM_SIZE))); - - mailbox[MBOX_IDX_MAGIC] = MVEBU_MAILBOX_MAGIC_NUM; - mailbox[MBOX_IDX_SEC_ADDR] = address; - - /* Flush data cache if the mail box shared RAM is cached */ -#if PLAT_MARVELL_SHARED_RAM_CACHED - flush_dcache_range((uintptr_t)PLAT_MARVELL_MAILBOX_BASE + - 8 * MBOX_IDX_MAGIC, - 2 * sizeof(uint64_t)); -#endif -} - -/***************************************************************************** - * The ARM Standard platform definition of platform porting API - * `plat_setup_psci_ops`. - ***************************************************************************** - */ -int plat_setup_psci_ops(uintptr_t sec_entrypoint, - const plat_psci_ops_t **psci_ops) -{ - *psci_ops = &plat_arm_psci_pm_ops; - - /* Setup mailbox with entry point. */ - marvell_program_mailbox(sec_entrypoint); - return 0; -} diff --git a/plat/marvell/common/marvell_topology.c b/plat/marvell/common/marvell_topology.c deleted file mode 100644 index a40ff6f50..000000000 --- a/plat/marvell/common/marvell_topology.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -/* The power domain tree descriptor */ -unsigned char marvell_power_domain_tree_desc[PLAT_MARVELL_CLUSTER_COUNT + 1]; - -/***************************************************************************** - * This function dynamically constructs the topology according to - * PLAT_MARVELL_CLUSTER_COUNT and returns it. - ***************************************************************************** - */ -const unsigned char *plat_get_power_domain_tree_desc(void) -{ - int i; - - /* - * The power domain tree does not have a single system level power - * domain i.e. a single root node. The first entry in the power domain - * descriptor specifies the number of power domains at the highest power - * level. - * For Marvell Platform this is the number of cluster power domains. - */ - marvell_power_domain_tree_desc[0] = PLAT_MARVELL_CLUSTER_COUNT; - - for (i = 0; i < PLAT_MARVELL_CLUSTER_COUNT; i++) - marvell_power_domain_tree_desc[i + 1] = - PLAT_MARVELL_CLUSTER_CORE_COUNT; - - return marvell_power_domain_tree_desc; -} - -/***************************************************************************** - * This function validates an MPIDR by checking whether it falls within the - * acceptable bounds. An error code (-1) is returned if an incorrect mpidr - * is passed. - ***************************************************************************** - */ -int marvell_check_mpidr(u_register_t mpidr) -{ - unsigned int nb_id, cluster_id, cpu_id; - - mpidr &= MPIDR_AFFINITY_MASK; - - if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK | - MPIDR_AFFLVL_MASK << MPIDR_AFF2_SHIFT)) - return -1; - - /* Get north bridge ID */ - nb_id = MPIDR_AFFLVL3_VAL(mpidr); - cluster_id = MPIDR_AFFLVL1_VAL(mpidr); - cpu_id = MPIDR_AFFLVL0_VAL(mpidr); - - if (nb_id >= PLAT_MARVELL_CLUSTER_COUNT) - return -1; - - if (cluster_id >= PLAT_MARVELL_CLUSTER_COUNT) - return -1; - - if (cpu_id >= PLAT_MARVELL_CLUSTER_CORE_COUNT) - return -1; - - return 0; -} - -/***************************************************************************** - * This function implements a part of the critical interface between the PSCI - * generic layer and the platform that allows the former to query the platform - * to convert an MPIDR to a unique linear index. An error code (-1) is returned - * in case the MPIDR is invalid. - ***************************************************************************** - */ -int plat_core_pos_by_mpidr(u_register_t mpidr) -{ - if (marvell_check_mpidr(mpidr) == -1) - return -1; - - return plat_marvell_calc_core_pos(mpidr); -} diff --git a/plat/marvell/common/mrvl_sip_svc.c b/plat/marvell/common/mrvl_sip_svc.c deleted file mode 100644 index 0291024d7..000000000 --- a/plat/marvell/common/mrvl_sip_svc.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include -#include -#include -#include - -#include -#include - -#include "comphy/phy-comphy-cp110.h" -#include - -/* #define DEBUG_COMPHY */ -#ifdef DEBUG_COMPHY -#define debug(format...) NOTICE(format) -#else -#define debug(format, arg...) -#endif - -/* Comphy related FID's */ -#define MV_SIP_COMPHY_POWER_ON 0x82000001 -#define MV_SIP_COMPHY_POWER_OFF 0x82000002 -#define MV_SIP_COMPHY_PLL_LOCK 0x82000003 -#define MV_SIP_COMPHY_XFI_TRAIN 0x82000004 -#define MV_SIP_COMPHY_DIG_RESET 0x82000005 - -/* Miscellaneous FID's' */ -#define MV_SIP_DRAM_SIZE 0x82000010 -#define MV_SIP_LLC_ENABLE 0x82000011 -#define MV_SIP_PMU_IRQ_ENABLE 0x82000012 -#define MV_SIP_PMU_IRQ_DISABLE 0x82000013 - -#define MAX_LANE_NR 6 -#define MVEBU_COMPHY_OFFSET 0x441000 -#define MVEBU_CP_BASE_MASK (~0xffffff) - -/* This macro is used to identify COMPHY related calls from SMC function ID */ -#define is_comphy_fid(fid) \ - ((fid) >= MV_SIP_COMPHY_POWER_ON && (fid) <= MV_SIP_COMPHY_DIG_RESET) - -_Bool is_cp_range_valid(u_register_t *addr) -{ - int cp_nr; - - *addr &= MVEBU_CP_BASE_MASK; - for (cp_nr = 0; cp_nr < CP_NUM; cp_nr++) { - if (*addr == MVEBU_CP_REGS_BASE(cp_nr)) - return true; - } - - return false; -} - -uintptr_t mrvl_sip_smc_handler(uint32_t smc_fid, - u_register_t x1, - u_register_t x2, - u_register_t x3, - u_register_t x4, - void *cookie, - void *handle, - u_register_t flags) -{ - u_register_t ret; - int i; - - debug("%s: got SMC (0x%x) x1 0x%lx, x2 0x%lx, x3 0x%lx\n", - __func__, smc_fid, x1, x2, x3); - - if (is_comphy_fid(smc_fid)) { - /* validate address passed via x1 */ - if (!is_cp_range_valid(&x1)) { - ERROR("%s: Wrong smc (0x%x) address: %lx\n", - __func__, smc_fid, x1); - SMC_RET1(handle, SMC_UNK); - } - - x1 += MVEBU_COMPHY_OFFSET; - - if (x2 >= MAX_LANE_NR) { - ERROR("%s: Wrong smc (0x%x) lane nr: %lx\n", - __func__, smc_fid, x2); - SMC_RET1(handle, SMC_UNK); - } - } - - switch (smc_fid) { - - /* Comphy related FID's */ - case MV_SIP_COMPHY_POWER_ON: - /* x1: comphy_base, x2: comphy_index, x3: comphy_mode */ - ret = mvebu_cp110_comphy_power_on(x1, x2, x3); - SMC_RET1(handle, ret); - case MV_SIP_COMPHY_POWER_OFF: - /* x1: comphy_base, x2: comphy_index */ - ret = mvebu_cp110_comphy_power_off(x1, x2, x3); - SMC_RET1(handle, ret); - case MV_SIP_COMPHY_PLL_LOCK: - /* x1: comphy_base, x2: comphy_index */ - ret = mvebu_cp110_comphy_is_pll_locked(x1, x2); - SMC_RET1(handle, ret); - case MV_SIP_COMPHY_XFI_TRAIN: - /* x1: comphy_base, x2: comphy_index */ - ret = mvebu_cp110_comphy_xfi_rx_training(x1, x2); - SMC_RET1(handle, ret); - case MV_SIP_COMPHY_DIG_RESET: - /* x1: comphy_base, x2: comphy_index, x3: mode, x4: command */ - ret = mvebu_cp110_comphy_digital_reset(x1, x2, x3, x4); - SMC_RET1(handle, ret); - - /* Miscellaneous FID's' */ - case MV_SIP_DRAM_SIZE: - ret = mvebu_get_dram_size(MVEBU_REGS_BASE); - SMC_RET1(handle, ret); - case MV_SIP_LLC_ENABLE: - for (i = 0; i < ap_get_count(); i++) - llc_runtime_enable(i); - - SMC_RET1(handle, 0); -#ifdef MVEBU_PMU_IRQ_WA - case MV_SIP_PMU_IRQ_ENABLE: - mvebu_pmu_interrupt_enable(); - SMC_RET1(handle, 0); - case MV_SIP_PMU_IRQ_DISABLE: - mvebu_pmu_interrupt_disable(); - SMC_RET1(handle, 0); -#endif - - default: - ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid); - SMC_RET1(handle, SMC_UNK); - } -} - -/* Define a runtime service descriptor for fast SMC calls */ -DECLARE_RT_SVC( - marvell_sip_svc, - OEN_SIP_START, - OEN_SIP_END, - SMC_TYPE_FAST, - NULL, - mrvl_sip_smc_handler -); diff --git a/plat/marvell/common/mss/mss_common.mk b/plat/marvell/common/mss/mss_common.mk deleted file mode 100644 index 898b6dccc..000000000 --- a/plat/marvell/common/mss/mss_common.mk +++ /dev/null @@ -1,20 +0,0 @@ -# -# Copyright (C) 2018 Marvell International Ltd. -# -# SPDX-License-Identifier: BSD-3-Clause -# https://spdx.org/licenses -# - - -PLAT_MARVELL := plat/marvell -MSS_SOURCE := $(PLAT_MARVELL)/common/mss - -BL2_SOURCES += $(MSS_SOURCE)/mss_scp_bootloader.c \ - $(PLAT_MARVELL)/common/plat_delay_timer.c \ - drivers/delay_timer/delay_timer.c \ - $(MARVELL_DRV) \ - $(PLAT_FAMILY_BASE)/$(PLAT)/board/marvell_plat_config.c - -BL31_SOURCES += $(MSS_SOURCE)/mss_ipc_drv.c - -PLAT_INCLUDES += -I$(MSS_SOURCE) diff --git a/plat/marvell/common/mss/mss_ipc_drv.c b/plat/marvell/common/mss/mss_ipc_drv.c deleted file mode 100644 index 70ccfa5ac..000000000 --- a/plat/marvell/common/mss/mss_ipc_drv.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -#include -#include - -#include -#include - -#define IPC_MSG_BASE_MASK MVEBU_REGS_BASE_MASK - -#define IPC_CH_NUM_OF_MSG (16) -#define IPC_CH_MSG_IDX (-1) - -unsigned long mv_pm_ipc_msg_base; -unsigned int mv_pm_ipc_queue_size; - -unsigned int msg_sync; -int msg_index = IPC_CH_MSG_IDX; - -/****************************************************************************** - * mss_pm_ipc_init - * - * DESCRIPTION: Initialize PM IPC infrastructure - ****************************************************************************** - */ -int mv_pm_ipc_init(unsigned long ipc_control_addr) -{ - struct mss_pm_ipc_ctrl *ipc_control = - (struct mss_pm_ipc_ctrl *)ipc_control_addr; - - /* Initialize PM IPC control block */ - mv_pm_ipc_msg_base = ipc_control->msg_base_address | - IPC_MSG_BASE_MASK; - mv_pm_ipc_queue_size = ipc_control->queue_size; - - return 0; -} - -/****************************************************************************** - * mv_pm_ipc_queue_addr_get - * - * DESCRIPTION: Returns the IPC queue address - ****************************************************************************** - */ -unsigned int mv_pm_ipc_queue_addr_get(void) -{ - unsigned int addr; - - inv_dcache_range((uint64_t)&msg_index, sizeof(msg_index)); - msg_index = msg_index + 1; - if (msg_index >= IPC_CH_NUM_OF_MSG) - msg_index = 0; - - addr = (unsigned int)(mv_pm_ipc_msg_base + - (msg_index * mv_pm_ipc_queue_size)); - - flush_dcache_range((uint64_t)&msg_index, sizeof(msg_index)); - - return addr; -} - -/****************************************************************************** - * mv_pm_ipc_msg_rx - * - * DESCRIPTION: Retrieve message from IPC channel - ****************************************************************************** - */ -int mv_pm_ipc_msg_rx(unsigned int channel_id, struct mss_pm_ipc_msg *msg) -{ - unsigned int addr = mv_pm_ipc_queue_addr_get(); - - msg->msg_reply = mmio_read_32(addr + IPC_MSG_REPLY_LOC); - - return 0; -} - -/****************************************************************************** - * mv_pm_ipc_msg_tx - * - * DESCRIPTION: Send message via IPC channel - ****************************************************************************** - */ -int mv_pm_ipc_msg_tx(unsigned int channel_id, unsigned int msg_id, - unsigned int cluster_power_state) -{ - unsigned int addr = mv_pm_ipc_queue_addr_get(); - - /* Validate the entry for message placed by the host is free */ - if (mmio_read_32(addr + IPC_MSG_STATE_LOC) == IPC_MSG_FREE) { - inv_dcache_range((uint64_t)&msg_sync, sizeof(msg_sync)); - msg_sync = msg_sync + 1; - flush_dcache_range((uint64_t)&msg_sync, sizeof(msg_sync)); - - mmio_write_32(addr + IPC_MSG_SYNC_ID_LOC, msg_sync); - mmio_write_32(addr + IPC_MSG_ID_LOC, msg_id); - mmio_write_32(addr + IPC_MSG_CPU_ID_LOC, channel_id); - mmio_write_32(addr + IPC_MSG_POWER_STATE_LOC, - cluster_power_state); - mmio_write_32(addr + IPC_MSG_STATE_LOC, IPC_MSG_OCCUPY); - - } else { - ERROR("%s: FAILED\n", __func__); - } - - return 0; -} diff --git a/plat/marvell/common/mss/mss_ipc_drv.h b/plat/marvell/common/mss/mss_ipc_drv.h deleted file mode 100644 index bcb4b2d8f..000000000 --- a/plat/marvell/common/mss/mss_ipc_drv.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef MSS_IPC_DRV_H -#define MSS_IPC_DRV_H - -#include - -#define MV_PM_FW_IPC_VERSION_MAGIC (0xCA530000) /* Do NOT change */ -/* Increament for each version */ -#define MV_PM_FW_IPC_VERSION_SEQ (0x00000001) -#define MV_PM_FW_IPC_VERSION (MV_PM_FW_IPC_VERSION_MAGIC | \ - MV_PM_FW_IPC_VERSION_SEQ) - -#define IPC_MSG_STATE_LOC (0x0) -#define IPC_MSG_SYNC_ID_LOC (0x4) -#define IPC_MSG_ID_LOC (0x8) -#define IPC_MSG_RET_CH_ID_LOC (0xC) -#define IPC_MSG_CPU_ID_LOC (0x10) -#define IPC_MSG_CLUSTER_ID_LOC (0x14) -#define IPC_MSG_SYSTEM_ID_LOC (0x18) -#define IPC_MSG_POWER_STATE_LOC (0x1C) -#define IPC_MSG_REPLY_LOC (0x20) -#define IPC_MSG_RESERVED_LOC (0x24) - -/* IPC initialization state */ -enum mss_pm_ipc_init_state { - IPC_UN_INITIALIZED = 1, - IPC_INITIALIZED = 2 -}; - -/* IPC queue direction */ -enum mss_pm_ipc_init_msg_dir { - IPC_MSG_TX = 0, - IPC_MSG_RX = 1 -}; - -/* IPC message state */ -enum mss_pm_ipc_msg_state { - IPC_MSG_FREE = 1, - IPC_MSG_OCCUPY = 2 - -}; - -/* IPC control block */ -struct mss_pm_ipc_ctrl { - unsigned int ctrl_base_address; - unsigned int msg_base_address; - unsigned int num_of_channels; - unsigned int channel_size; - unsigned int queue_size; -}; - -/* IPC message types */ -enum mss_pm_msg_id { - PM_IPC_MSG_CPU_SUSPEND = 1, - PM_IPC_MSG_CPU_OFF = 2, - PM_IPC_MSG_CPU_ON = 3, - PM_IPC_MSG_SYSTEM_RESET = 4, - PM_IPC_MSG_SYSTEM_SUSPEND = 5, - PM_IPC_MAX_MSG -}; - -struct mss_pm_ipc_msg { - unsigned int msg_sync_id; /* - * Sync number, validate message - * reply corresponding to message - * received - */ - unsigned int msg_id; /* Message Id */ - unsigned int ret_channel_id; /* IPC channel reply */ - unsigned int cpu_id; /* CPU Id */ - unsigned int cluster_id; /* Cluster Id */ - unsigned int system_id; /* System Id */ - unsigned int power_state; - unsigned int msg_reply; /* Message reply */ -}; - -/* IPC queue */ -struct mss_pm_ipc_queue { - unsigned int state; - struct mss_pm_ipc_msg msg; -}; - -/* IPC channel */ -struct mss_pm_ipc_ch { - struct mss_pm_ipc_queue *tx_queue; - struct mss_pm_ipc_queue *rx_queue; -}; - -/***************************************************************************** - * mv_pm_ipc_init - * - * DESCRIPTION: Initialize PM IPC infrastructure - ***************************************************************************** - */ -int mv_pm_ipc_init(unsigned long ipc_control_addr); - -/***************************************************************************** - * mv_pm_ipc_msg_rx - * - * DESCRIPTION: Retrieve message from IPC channel - ***************************************************************************** - */ -int mv_pm_ipc_msg_rx(unsigned int channel_id, struct mss_pm_ipc_msg *msg); - -/***************************************************************************** - * mv_pm_ipc_msg_tx - * - * DESCRIPTION: Send message via IPC channel - ***************************************************************************** - */ -int mv_pm_ipc_msg_tx(unsigned int channel_id, unsigned int msg_id, - unsigned int cluster_power_state); - -#endif /* MSS_IPC_DRV_H */ diff --git a/plat/marvell/common/mss/mss_mem.h b/plat/marvell/common/mss/mss_mem.h deleted file mode 100644 index 5d68ac788..000000000 --- a/plat/marvell/common/mss/mss_mem.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef MSS_MEM_H -#define MSS_MEM_H - -/* MSS SRAM Memory base */ -#define MSS_SRAM_PM_CONTROL_BASE (MVEBU_REGS_BASE + 0x520000) - -enum mss_pm_ctrl_handshake { - MSS_UN_INITIALIZED = 0, - MSS_COMPATIBILITY_ERROR = 1, - MSS_ACKNOWLEDGMENT = 2, - HOST_ACKNOWLEDGMENT = 3 -}; - -enum mss_pm_ctrl_rtos_env { - MSS_MULTI_PROCESS_ENV = 0, - MSS_SINGLE_PROCESS_ENV = 1, - MSS_MAX_PROCESS_ENV -}; - -struct mss_pm_ctrl_block { - /* This field is used to synchronize the Host - * and MSS initialization sequence - * Valid Values - * 0 - Un-Initialized - * 1 - Compatibility Error - * 2 - MSS Acknowledgment - * 3 - Host Acknowledgment - */ - unsigned int handshake; - - /* - * This field include Host IPC version. Once received by the MSS - * It will be compared to MSS IPC version and set MSS Acknowledge to - * "compatibility error" in case there is no match - */ - unsigned int ipc_version; - unsigned int ipc_base_address; - unsigned int ipc_state; - - /* Following fields defines firmware core architecture */ - unsigned int num_of_cores; - unsigned int num_of_clusters; - unsigned int num_of_cores_per_cluster; - - /* Following fields define pm trace debug base address */ - unsigned int pm_trace_ctrl_base_address; - unsigned int pm_trace_info_base_address; - unsigned int pm_trace_info_core_size; - - unsigned int ctrl_blk_size; -}; - -#endif /* MSS_MEM_H */ diff --git a/plat/marvell/common/mss/mss_scp_bl2_format.h b/plat/marvell/common/mss/mss_scp_bl2_format.h deleted file mode 100644 index 7150f0a06..000000000 --- a/plat/marvell/common/mss/mss_scp_bl2_format.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef MSS_SCP_BL2_FORMAT_H -#define MSS_SCP_BL2_FORMAT_H - -#define MAX_NR_OF_FILES 8 -#define FILE_MAGIC 0xddd01ff -#define HEADER_VERSION 0x1 - -#define MSS_IDRAM_SIZE 0x10000 /* 64KB */ -#define MG_SRAM_SIZE 0x20000 /* 128KB */ - -/* Types definitions */ -typedef struct file_header { - /* Magic specific for concatenated file (used for validation) */ - uint32_t magic; - uint32_t nr_of_imgs; /* Number of images concatenated */ -} file_header_t; - -/* Types definitions */ -enum cm3_t { - MSS_AP, - MSS_CP0, - MSS_CP1, - MSS_CP2, - MSS_CP3, - MG_CP0, - MG_CP1, - MG_CP2, -}; - -typedef struct img_header { - uint32_t type; /* CM3 type, can be one of cm3_t */ - uint32_t length; /* Image length */ - uint32_t version; /* For sanity checks and future - * extended functionality - */ -} img_header_t; - -#endif /* MSS_SCP_BL2_FORMAT_H */ diff --git a/plat/marvell/common/mss/mss_scp_bootloader.c b/plat/marvell/common/mss/mss_scp_bootloader.c deleted file mode 100644 index 4473d81e1..000000000 --- a/plat/marvell/common/mss/mss_scp_bootloader.c +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#define MSS_DMA_SRCBR(base) (base + 0xC0) -#define MSS_DMA_DSTBR(base) (base + 0xC4) -#define MSS_DMA_CTRLR(base) (base + 0xC8) -#define MSS_M3_RSTCR(base) (base + 0xFC) - -#define MSS_DMA_CTRLR_SIZE_OFFSET (0) -#define MSS_DMA_CTRLR_REQ_OFFSET (15) -#define MSS_DMA_CTRLR_REQ_SET (1) -#define MSS_DMA_CTRLR_ACK_OFFSET (12) -#define MSS_DMA_CTRLR_ACK_MASK (0x1) -#define MSS_DMA_CTRLR_ACK_READY (1) -#define MSS_M3_RSTCR_RST_OFFSET (0) -#define MSS_M3_RSTCR_RST_OFF (1) - -#define MSS_DMA_TIMEOUT 1000 -#define MSS_EXTERNAL_SPACE 0x50000000 -#define MSS_EXTERNAL_ADDR_MASK 0xfffffff - -#define DMA_SIZE 128 - -#define MSS_HANDSHAKE_TIMEOUT 50 - -#define MG_CM3_SRAM_BASE(CP) (MVEBU_CP_REGS_BASE(CP) + 0x100000) - -static int mss_check_image_ready(volatile struct mss_pm_ctrl_block *mss_pm_crtl) -{ - int timeout = MSS_HANDSHAKE_TIMEOUT; - - /* Wait for SCP to signal it's ready */ - while ((mss_pm_crtl->handshake != MSS_ACKNOWLEDGMENT) && - (timeout-- > 0)) - mdelay(1); - - if (mss_pm_crtl->handshake != MSS_ACKNOWLEDGMENT) - return -1; - - mss_pm_crtl->handshake = HOST_ACKNOWLEDGMENT; - - return 0; -} - -static int mg_image_load(uintptr_t src_addr, uint32_t size, uintptr_t mg_regs) -{ - if (size > MG_SRAM_SIZE) { - ERROR("image is too big to fit into MG CM3 memory\n"); - return 1; - } - - NOTICE("Loading MG image from address 0x%lx Size 0x%x to MG at 0x%lx\n", - src_addr, size, mg_regs); - - /* Copy image to MG CM3 SRAM */ - memcpy((void *)mg_regs, (void *)src_addr, size); - - /* - * Don't release MG CM3 from reset - it will be done by next step - * bootloader (e.g. U-Boot), when appriopriate device-tree setup (which - * has enabeld 802.3. auto-neg) will be choosen. - */ - - return 0; -} - -static int mss_image_load(uint32_t src_addr, uint32_t size, uintptr_t mss_regs) -{ - uint32_t i, loop_num, timeout; - - /* Check if the img size is not bigger than ID-RAM size of MSS CM3 */ - if (size > MSS_IDRAM_SIZE) { - ERROR("image is too big to fit into MSS CM3 memory\n"); - return 1; - } - - NOTICE("Loading MSS image from addr. 0x%x Size 0x%x to MSS at 0x%lx\n", - src_addr, size, mss_regs); - /* load image to MSS RAM using DMA */ - loop_num = (size / DMA_SIZE) + (((size & (DMA_SIZE - 1)) == 0) ? 0 : 1); - - for (i = 0; i < loop_num; i++) { - /* write destination and source addresses */ - mmio_write_32(MSS_DMA_SRCBR(mss_regs), - MSS_EXTERNAL_SPACE | - ((src_addr & MSS_EXTERNAL_ADDR_MASK) + - (i * DMA_SIZE))); - mmio_write_32(MSS_DMA_DSTBR(mss_regs), (i * DMA_SIZE)); - - dsb(); /* make sure DMA data is ready before triggering it */ - - /* set the DMA control register */ - mmio_write_32(MSS_DMA_CTRLR(mss_regs), ((MSS_DMA_CTRLR_REQ_SET - << MSS_DMA_CTRLR_REQ_OFFSET) | - (DMA_SIZE << MSS_DMA_CTRLR_SIZE_OFFSET))); - - /* Poll DMA_ACK at MSS_DMACTLR until it is ready */ - timeout = MSS_DMA_TIMEOUT; - while (timeout) { - if ((mmio_read_32(MSS_DMA_CTRLR(mss_regs)) >> - MSS_DMA_CTRLR_ACK_OFFSET & MSS_DMA_CTRLR_ACK_MASK) - == MSS_DMA_CTRLR_ACK_READY) { - break; - } - - udelay(50); - timeout--; - } - - if (timeout == 0) { - ERROR("\nDMA failed to load MSS image\n"); - return 1; - } - } - - bl2_plat_configure_mss_windows(mss_regs); - - /* Release M3 from reset */ - mmio_write_32(MSS_M3_RSTCR(mss_regs), (MSS_M3_RSTCR_RST_OFF << - MSS_M3_RSTCR_RST_OFFSET)); - - NOTICE("Done\n"); - - return 0; -} - -/* Load image to MSS AP and do PM related initialization - * Note that this routine is different than other CM3 loading routines, because - * firmware for AP is dedicated for PM and therefore some additional PM - * initialization is required - */ -static int mss_ap_load_image(uintptr_t single_img, - uint32_t image_size, uint32_t ap_idx) -{ - volatile struct mss_pm_ctrl_block *mss_pm_crtl; - int ret; - - /* TODO: add PM Control Info from platform */ - mss_pm_crtl = (struct mss_pm_ctrl_block *)MSS_SRAM_PM_CONTROL_BASE; - mss_pm_crtl->ipc_version = MV_PM_FW_IPC_VERSION; - mss_pm_crtl->num_of_clusters = PLAT_MARVELL_CLUSTER_COUNT; - mss_pm_crtl->num_of_cores_per_cluster = - PLAT_MARVELL_CLUSTER_CORE_COUNT; - mss_pm_crtl->num_of_cores = PLAT_MARVELL_CLUSTER_COUNT * - PLAT_MARVELL_CLUSTER_CORE_COUNT; - mss_pm_crtl->pm_trace_ctrl_base_address = AP_MSS_ATF_CORE_CTRL_BASE; - mss_pm_crtl->pm_trace_info_base_address = AP_MSS_ATF_CORE_INFO_BASE; - mss_pm_crtl->pm_trace_info_core_size = AP_MSS_ATF_CORE_INFO_SIZE; - VERBOSE("MSS Control Block = 0x%x\n", MSS_SRAM_PM_CONTROL_BASE); - VERBOSE("mss_pm_crtl->ipc_version = 0x%x\n", - mss_pm_crtl->ipc_version); - VERBOSE("mss_pm_crtl->num_of_cores = 0x%x\n", - mss_pm_crtl->num_of_cores); - VERBOSE("mss_pm_crtl->num_of_clusters = 0x%x\n", - mss_pm_crtl->num_of_clusters); - VERBOSE("mss_pm_crtl->num_of_cores_per_cluster = 0x%x\n", - mss_pm_crtl->num_of_cores_per_cluster); - VERBOSE("mss_pm_crtl->pm_trace_ctrl_base_address = 0x%x\n", - mss_pm_crtl->pm_trace_ctrl_base_address); - VERBOSE("mss_pm_crtl->pm_trace_info_base_address = 0x%x\n", - mss_pm_crtl->pm_trace_info_base_address); - VERBOSE("mss_pm_crtl->pm_trace_info_core_size = 0x%x\n", - mss_pm_crtl->pm_trace_info_core_size); - - /* TODO: add checksum to image */ - VERBOSE("Send info about the SCP_BL2 image to be transferred to SCP\n"); - - ret = mss_image_load(single_img, image_size, - bl2_plat_get_ap_mss_regs(ap_idx)); - if (ret != 0) { - ERROR("SCP Image load failed\n"); - return -1; - } - - /* check that the image was loaded successfully */ - ret = mss_check_image_ready(mss_pm_crtl); - if (ret != 0) - NOTICE("SCP Image doesn't contain PM firmware\n"); - - return 0; -} - -/* Load CM3 image (single_img) to CM3 pointed by cm3_type */ -static int load_img_to_cm3(enum cm3_t cm3_type, - uintptr_t single_img, uint32_t image_size) -{ - int ret, ap_idx, cp_index; - uint32_t ap_count = bl2_plat_get_ap_count(); - - switch (cm3_type) { - case MSS_AP: - for (ap_idx = 0; ap_idx < ap_count; ap_idx++) { - NOTICE("Load image to AP%d MSS\n", ap_idx); - ret = mss_ap_load_image(single_img, image_size, ap_idx); - if (ret != 0) - return ret; - } - break; - case MSS_CP0: - case MSS_CP1: - case MSS_CP2: - case MSS_CP3: - /* MSS_AP = 0 - * MSS_CP1 = 1 - * . - * . - * MSS_CP3 = 4 - * Actual CP index is MSS_CPX - 1 - */ - cp_index = cm3_type - 1; - for (ap_idx = 0; ap_idx < ap_count; ap_idx++) { - /* Check if we should load this image - * according to number of CPs - */ - if (bl2_plat_get_cp_count(ap_idx) <= cp_index) { - NOTICE("Skipping MSS CP%d related image\n", - cp_index); - break; - } - - NOTICE("Load image to CP%d MSS AP%d\n", - cp_index, ap_idx); - ret = mss_image_load(single_img, image_size, - bl2_plat_get_cp_mss_regs( - ap_idx, cp_index)); - if (ret != 0) { - ERROR("SCP Image load failed\n"); - return -1; - } - } - break; - case MG_CP0: - case MG_CP1: - case MG_CP2: - cp_index = cm3_type - MG_CP0; - if (bl2_plat_get_cp_count(0) <= cp_index) { - NOTICE("Skipping MG CP%d related image\n", - cp_index); - break; - } - NOTICE("Load image to CP%d MG\n", cp_index); - ret = mg_image_load(single_img, image_size, - MG_CM3_SRAM_BASE(cp_index)); - if (ret != 0) { - ERROR("SCP Image load failed\n"); - return -1; - } - break; - default: - ERROR("SCP_BL2 wrong img format (cm3_type=%d)\n", cm3_type); - break; - } - - return 0; -} - -/* The Armada 8K has 5 service CPUs and Armada 7K has 3. Therefore it was - * required to provide a method for loading firmware to all of the service CPUs. - * To achieve that, the scp_bl2 image in fact is file containing up to 5 - * concatenated firmwares and this routine splits concatenated image into single - * images dedicated for appropriate service CPU and then load them. - */ -static int split_and_load_bl2_image(void *image) -{ - file_header_t *file_hdr; - img_header_t *img_hdr; - uintptr_t single_img; - int i; - - file_hdr = (file_header_t *)image; - - if (file_hdr->magic != FILE_MAGIC) { - ERROR("SCP_BL2 wrong img format\n"); - return -1; - } - - if (file_hdr->nr_of_imgs > MAX_NR_OF_FILES) { - ERROR("SCP_BL2 concatenated image contains too many images\n"); - return -1; - } - - img_hdr = (img_header_t *)((uintptr_t)image + sizeof(file_header_t)); - single_img = (uintptr_t)image + sizeof(file_header_t) + - sizeof(img_header_t) * file_hdr->nr_of_imgs; - - NOTICE("SCP_BL2 contains %d concatenated images\n", - file_hdr->nr_of_imgs); - for (i = 0; i < file_hdr->nr_of_imgs; i++) { - - /* Before loading make sanity check on header */ - if (img_hdr->version != HEADER_VERSION) { - ERROR("Wrong header, img corrupted exiting\n"); - return -1; - } - - load_img_to_cm3(img_hdr->type, single_img, img_hdr->length); - - /* Prepare offsets for next run */ - single_img += img_hdr->length; - img_hdr++; - } - - return 0; -} - -int scp_bootloader_transfer(void *image, unsigned int image_size) -{ -#ifdef SCP_BL2_BASE - assert((uintptr_t) image == SCP_BL2_BASE); -#endif - - VERBOSE("Concatenated img size %d\n", image_size); - - if (image_size == 0) { - ERROR("SCP_BL2 image size can't be 0 (current size = 0x%x)\n", - image_size); - return -1; - } - - if (split_and_load_bl2_image(image)) - return -1; - - return 0; -} diff --git a/plat/marvell/common/mss/mss_scp_bootloader.h b/plat/marvell/common/mss/mss_scp_bootloader.h deleted file mode 100644 index 4950d2472..000000000 --- a/plat/marvell/common/mss/mss_scp_bootloader.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef MSS_SCP_BOOTLOADER_H -#define MSS_SCP_BOOTLOADER_H - -int scp_bootloader_transfer(void *image, unsigned int image_size); -uintptr_t bl2_plat_get_cp_mss_regs(int ap_idx, int cp_idx); -uintptr_t bl2_plat_get_ap_mss_regs(int ap_idx); -uint32_t bl2_plat_get_cp_count(int ap_idx); -uint32_t bl2_plat_get_ap_count(void); -void bl2_plat_configure_mss_windows(uintptr_t mss_regs); -int bl2_plat_mss_check_image_ready(void); - -#endif /* MSS_SCP_BOOTLOADER_H */ diff --git a/plat/marvell/common/plat_delay_timer.c b/plat/marvell/common/plat_delay_timer.c deleted file mode 100644 index 253975264..000000000 --- a/plat/marvell/common/plat_delay_timer.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include - -#include - -#define SYS_COUNTER_FREQ_IN_MHZ (COUNTER_FREQUENCY/1000000) - -static uint32_t plat_get_timer_value(void) -{ - /* - * Generic delay timer implementation expects the timer to be a down - * counter. We apply bitwise NOT operator to the tick values returned - * by read_cntpct_el0() to simulate the down counter. - */ - return (uint32_t)(~read_cntpct_el0()); -} - -static const timer_ops_t plat_timer_ops = { - .get_timer_value = plat_get_timer_value, - .clk_mult = 1, - .clk_div = SYS_COUNTER_FREQ_IN_MHZ -}; - -void plat_delay_timer_init(void) -{ - timer_init(&plat_timer_ops); -} -- cgit v1.2.3 From 613bbde09e48874658af5a00612fe2a0b0388523 Mon Sep 17 00:00:00 2001 From: Grzegorz Jaszczyk Date: Sun, 9 Dec 2018 23:11:20 +0100 Subject: plat: marvell: armada: make a8k_common.mk and mss_common.mk more generic As a preparation for upcoming support for CN9130 platform, which is classified as OcteonTx2 product but inherits functionality from a8k, allow to use a8k_common.mk and mss_common.mk from outside of PLAT_FAMILY_BASE. Above is done by introducing BOARD_DIR which needs to be set by each platform, before including a8k_common.mk and mss_common.mk. This will allow to use mentioned mk files not only for platforms located under previously defined PLAT_FAMILY_BASE. Change-Id: I22356c99bc0419a40ae11e42f37acd50943ea134 Signed-off-by: Grzegorz Jaszczyk --- plat/marvell/armada/a8k/a70x0/platform.mk | 1 + plat/marvell/armada/a8k/a70x0_amc/platform.mk | 1 + plat/marvell/armada/a8k/a80x0/platform.mk | 2 +- plat/marvell/armada/a8k/a80x0_mcbin/platform.mk | 1 + plat/marvell/armada/a8k/common/a8k_common.mk | 11 +++++------ plat/marvell/armada/common/mss/mss_common.mk | 2 +- 6 files changed, 10 insertions(+), 8 deletions(-) diff --git a/plat/marvell/armada/a8k/a70x0/platform.mk b/plat/marvell/armada/a8k/a70x0/platform.mk index a77e34985..39eb71254 100644 --- a/plat/marvell/armada/a8k/a70x0/platform.mk +++ b/plat/marvell/armada/a8k/a70x0/platform.mk @@ -14,6 +14,7 @@ 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/a70x0_amc/platform.mk b/plat/marvell/armada/a8k/a70x0_amc/platform.mk index a77e34985..39eb71254 100644 --- a/plat/marvell/armada/a8k/a70x0_amc/platform.mk +++ b/plat/marvell/armada/a8k/a70x0_amc/platform.mk @@ -14,6 +14,7 @@ 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/a80x0/platform.mk b/plat/marvell/armada/a8k/a80x0/platform.mk index 56c4117d6..115dd4a82 100644 --- a/plat/marvell/armada/a8k/a80x0/platform.mk +++ b/plat/marvell/armada/a8k/a80x0/platform.mk @@ -14,7 +14,7 @@ DOIMAGE_SEC := tools/doimage/secure/sec_img_8K.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 -PLAT_INCLUDES += -Iplat/marvell/armada/a8k/a80x0/board diff --git a/plat/marvell/armada/a8k/a80x0_mcbin/platform.mk b/plat/marvell/armada/a8k/a80x0_mcbin/platform.mk index d962b3d2a..115dd4a82 100644 --- a/plat/marvell/armada/a8k/a80x0_mcbin/platform.mk +++ b/plat/marvell/armada/a8k/a80x0_mcbin/platform.mk @@ -14,6 +14,7 @@ DOIMAGE_SEC := tools/doimage/secure/sec_img_8K.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 471bc82c6..8731aa64b 100644 --- a/plat/marvell/armada/a8k/common/a8k_common.mk +++ b/plat/marvell/armada/a8k/common/a8k_common.mk @@ -7,9 +7,8 @@ include tools/marvell/doimage/doimage.mk PLAT_FAMILY := a8k -PLAT_FAMILY_BASE := plat/marvell/armada/$(PLAT_FAMILY) PLAT_INCLUDE_BASE := include/plat/marvell/armada/$(PLAT_FAMILY) -PLAT_COMMON_BASE := $(PLAT_FAMILY_BASE)/common +PLAT_COMMON_BASE := plat/marvell/armada/a8k/common MARVELL_DRV_BASE := drivers/marvell MARVELL_COMMON_BASE := plat/marvell/armada/common @@ -52,15 +51,15 @@ MARVELL_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ drivers/arm/gic/v2/gicv2_helpers.c \ plat/common/plat_gicv2.c -PLAT_INCLUDES := -I$(PLAT_FAMILY_BASE)/$(PLAT) \ +PLAT_INCLUDES := -I$(BOARD_DIR) \ -I$(PLAT_COMMON_BASE)/include \ -I$(PLAT_INCLUDE_BASE)/common PLAT_BL_COMMON_SOURCES := $(PLAT_COMMON_BASE)/aarch64/a8k_common.c \ drivers/ti/uart/aarch64/16550_console.S -BLE_PORTING_SOURCES := $(PLAT_FAMILY_BASE)/$(PLAT)/board/dram_port.c \ - $(PLAT_FAMILY_BASE)/$(PLAT)/board/marvell_plat_config.c +BLE_PORTING_SOURCES := $(BOARD_DIR)/board/dram_port.c \ + $(BOARD_DIR)/board/marvell_plat_config.c MARVELL_MOCHI_DRV += $(MARVELL_DRV_BASE)/mochi/cp110_setup.c @@ -87,7 +86,7 @@ MARVELL_DRV := $(MARVELL_DRV_BASE)/io_win.c \ $(MARVELL_DRV_BASE)/comphy/phy-comphy-cp110.c \ $(MARVELL_DRV_BASE)/mc_trustzone/mc_trustzone.c -BL31_PORTING_SOURCES := $(PLAT_FAMILY_BASE)/$(PLAT)/board/marvell_plat_config.c +BL31_PORTING_SOURCES := $(BOARD_DIR)/board/marvell_plat_config.c ifeq ($(SYSTEM_POWER_SUPPORT),1) BL31_PORTING_SOURCES += $(PLAT_FAMILY_BASE)/$(PLAT)/board/system_power.c diff --git a/plat/marvell/armada/common/mss/mss_common.mk b/plat/marvell/armada/common/mss/mss_common.mk index 050d88d2a..4ab43596c 100644 --- a/plat/marvell/armada/common/mss/mss_common.mk +++ b/plat/marvell/armada/common/mss/mss_common.mk @@ -13,7 +13,7 @@ BL2_SOURCES += $(MSS_SOURCE)/mss_scp_bootloader.c \ $(PLAT_MARVELL)/common/plat_delay_timer.c \ drivers/delay_timer/delay_timer.c \ $(MARVELL_DRV) \ - $(PLAT_FAMILY_BASE)/$(PLAT)/board/marvell_plat_config.c + $(BOARD_DIR)/board/marvell_plat_config.c BL31_SOURCES += $(MSS_SOURCE)/mss_ipc_drv.c -- cgit v1.2.3 From dc402531eff62ca54c3f9f360be50c1c113d16f9 Mon Sep 17 00:00:00 2001 From: Grzegorz Jaszczyk Date: Thu, 20 Dec 2018 17:13:19 +0100 Subject: plat: marvell: add support for PLL 2.2GHz mode Change-Id: Icb8fe14417665d6aadd5a5ee2b77547b4ef78773 Signed-off-by: Grzegorz Jaszczyk --- drivers/marvell/ap807_clocks_init.c | 5 +++++ include/drivers/marvell/aro.h | 6 ++++++ plat/marvell/armada/a8k/common/plat_ble_setup.c | 21 +++++++++++++++++++-- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/marvell/ap807_clocks_init.c b/drivers/marvell/ap807_clocks_init.c index 04c256b61..5604453bb 100644 --- a/drivers/marvell/ap807_clocks_init.c +++ b/drivers/marvell/ap807_clocks_init.c @@ -96,6 +96,11 @@ void ap807_clocks_init(unsigned int freq_option) case CPU_2000_DDR_1200_RCLK_1200: pll_set_freq(PLL_FREQ_2000); break; +#ifdef MVEBU_SOC_AP807 + case CPU_2200_DDR_1200_RCLK_1200: + pll_set_freq(PLL_FREQ_2200); + break; +#endif default: break; } diff --git a/include/drivers/marvell/aro.h b/include/drivers/marvell/aro.h index c16f62538..c9dd36e4f 100644 --- a/include/drivers/marvell/aro.h +++ b/include/drivers/marvell/aro.h @@ -21,11 +21,17 @@ enum hws_freq { DDR_FREQ_SAR }; +#include + enum cpu_clock_freq_mode { CPU_2000_DDR_1200_RCLK_1200 = 0x0, CPU_2000_DDR_1050_RCLK_1050 = 0x1, CPU_1600_DDR_800_RCLK_800 = 0x4, +#ifdef MVEBU_SOC_AP807 + CPU_2200_DDR_1200_RCLK_1200 = 0x6, +#else CPU_1800_DDR_1200_RCLK_1200 = 0x6, +#endif CPU_1800_DDR_1050_RCLK_1050 = 0x7, CPU_1600_DDR_900_RCLK_900 = 0x0B, CPU_1600_DDR_1050_RCLK_1050 = 0x0D, diff --git a/plat/marvell/armada/a8k/common/plat_ble_setup.c b/plat/marvell/armada/a8k/common/plat_ble_setup.c index 7f9e24278..166f18b86 100644 --- a/plat/marvell/armada/a8k/common/plat_ble_setup.c +++ b/plat/marvell/armada/a8k/common/plat_ble_setup.c @@ -89,6 +89,12 @@ (0x1 << AVS_SOFT_RESET_OFFSET) | \ (0x1 << AVS_ENABLE_OFFSET)) +#define AVS_CN9130_HIGH_CLK_VALUE ((0x80 << 24) | \ + (0x2dc << 13) | \ + (0x2dc << 3) | \ + (0x1 << AVS_SOFT_RESET_OFFSET) | \ + (0x1 << AVS_ENABLE_OFFSET)) + #define MVEBU_AP_EFUSE_SRV_CTRL_REG (MVEBU_AP_GEN_MGMT_BASE + 0x8) #define EFUSE_SRV_CTRL_LD_SELECT_OFFS 6 #define EFUSE_SRV_CTRL_LD_SEL_USER_MASK (1 << EFUSE_SRV_CTRL_LD_SELECT_OFFS) @@ -224,10 +230,19 @@ static void ble_plat_avs_config(void) /* Check which SoC is running and act accordingly */ if (ble_get_ap_type() == CHIP_ID_AP807) { /* Increase CPU voltage for higher CPU clock */ - if (freq_mode == CPU_2000_DDR_1200_RCLK_1200) + switch (freq_mode) { + case CPU_2000_DDR_1200_RCLK_1200: avs_val = AVS_A3900_HIGH_CLK_VALUE; - else + break; +#ifdef MVEBU_SOC_AP807 + case CPU_2200_DDR_1200_RCLK_1200: + avs_val = AVS_CN9130_HIGH_CLK_VALUE; + break; +#endif + default: avs_val = AVS_A3900_CLK_VALUE; + } + } else { /* Check which SoC is running and act accordingly */ device_id = cp110_device_id_get(MVEBU_CP_REGS_BASE(0)); @@ -463,7 +478,9 @@ static void ble_plat_svc_config(void) NOTICE("SVC: DEV ID: %s, FREQ Mode: 0x%x\n", single_cluster == 0 ? "8040" : "8020", freq_pidi_mode); switch (freq_pidi_mode) { +#ifndef MVEBU_SOC_AP807 case CPU_1800_DDR_1200_RCLK_1200: +#endif case CPU_1800_DDR_1050_RCLK_1050: if (perr[1]) goto perror; -- cgit v1.2.3 From 2da75ae1174205b43f80b64bb7deae42ea6b70a1 Mon Sep 17 00:00:00 2001 From: Grzegorz Jaszczyk Date: Sun, 13 Jan 2019 15:29:10 +0200 Subject: plat: marvell: ap807: use correct address for MCIx4 register The AP807 uses different register offset for MCIx4 register, reflect it in the code. Change-Id: Ic7e44fede3c69083e8629741e7c440b1ae08c35f Signed-off-by: Grzegorz Jaszczyk --- drivers/marvell/mochi/ap807_setup.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/marvell/mochi/ap807_setup.c b/drivers/marvell/mochi/ap807_setup.c index 864c9230a..132fffc9e 100644 --- a/drivers/marvell/mochi/ap807_setup.c +++ b/drivers/marvell/mochi/ap807_setup.c @@ -31,6 +31,11 @@ #define DSS_CR0 (MVEBU_RFU_BASE + 0x100) #define DVM_48BIT_VA_ENABLE (1 << 21) + +/* SoC RFU / IHBx4 Control */ +#define MCIX4_807_REG_START_ADDR_REG(unit_id) (MVEBU_RFU_BASE + \ + 0x4258 + (unit_id * 0x4)) + /* Secure MoChi incoming access */ #define SEC_MOCHI_IN_ACC_REG (MVEBU_RFU_BASE + 0x4738) #define SEC_MOCHI_IN_ACC_IHB0_EN (1) @@ -124,7 +129,7 @@ static void mci_remap_indirect_access_base(void) uint32_t mci; for (mci = 0; mci < MCI_MAX_UNIT_ID; mci++) - mmio_write_32(MCIX4_REG_START_ADDRESS_REG(mci), + mmio_write_32(MCIX4_807_REG_START_ADDR_REG(mci), MVEBU_MCI_REG_BASE_REMAP(mci) >> MCI_REMAP_OFF_SHIFT); } -- cgit v1.2.3 From c3c51b3283bf76552beb649c6cfc95110a1231d9 Mon Sep 17 00:00:00 2001 From: Grzegorz Jaszczyk Date: Sun, 13 Jan 2019 17:33:45 +0200 Subject: plat: marvell: ap807: update configuration space of each CP By default all external CPs start with configuration address space set to 0xf200_0000. To overcome this issue, go in the loop and initialize the CP one by one, using temporary window configuration which allows to access each CP and update its configuration space according to decoding windows scheme defined for each platform. In case of cn9130 after this procedure bellow addresses will be used: CP0 - f2000000 CP1 - f4000000 CP2 - f6000000 When the re-configuration is done there is need to restore previous decoding window configuration(init_io_win). Change-Id: I1a652bfbd0bf7106930a7a4e949094dc9078a981 Signed-off-by: Grzegorz Jaszczyk --- drivers/marvell/mochi/ap807_setup.c | 33 ++++++++++++++++++++++++ drivers/marvell/mochi/apn806_setup.c | 3 +++ include/drivers/marvell/mochi/ap_setup.h | 1 + plat/marvell/armada/a8k/common/plat_bl31_setup.c | 11 +++++++- 4 files changed, 47 insertions(+), 1 deletion(-) diff --git a/drivers/marvell/mochi/ap807_setup.c b/drivers/marvell/mochi/ap807_setup.c index 132fffc9e..7b6819512 100644 --- a/drivers/marvell/mochi/ap807_setup.c +++ b/drivers/marvell/mochi/ap807_setup.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -191,6 +192,38 @@ static void misc_soc_configurations(void) mmio_write_32(MVEBU_SYSRST_OUT_CONFIG_REG, reg); } +/* + * By default all external CPs start with configuration address space set to + * 0xf200_0000. To overcome this issue, go in the loop and initialize the + * CP one by one, using temporary window configuration which allows to access + * each CP and update its configuration space according to decoding + * windows scheme defined for each platform. + */ +void update_cp110_default_win(int cp_id) +{ + int mci_id = cp_id - 1; + uintptr_t cp110_base, cp110_temp_base; + + /* CP110 default configuration address space */ + cp110_temp_base = MVEBU_AP_IO_BASE(MVEBU_AP0); + + struct addr_map_win iowin_temp_win = { + .base_addr = cp110_temp_base, + .win_size = MVEBU_CP_OFFSET, + }; + + iowin_temp_win.target_id = mci_id; + iow_temp_win_insert(0, &iowin_temp_win, 1); + + /* Calculate the new CP110 - base address */ + cp110_base = MVEBU_CP_REGS_BASE(cp_id); + /* Go and update the CP110 configuration address space */ + iob_cfg_space_update(0, cp_id, cp110_temp_base, cp110_base); + + /* Remove the temporary IO-WIN window */ + iow_temp_win_remove(0, &iowin_temp_win, 1); +} + void ap_init(void) { /* Setup Aurora2. */ diff --git a/drivers/marvell/mochi/apn806_setup.c b/drivers/marvell/mochi/apn806_setup.c index 1e91c4317..1a02bd4ef 100644 --- a/drivers/marvell/mochi/apn806_setup.c +++ b/drivers/marvell/mochi/apn806_setup.c @@ -250,3 +250,6 @@ int ap_get_count(void) return 1; } +void update_cp110_default_win(int cp_id) +{ +} diff --git a/include/drivers/marvell/mochi/ap_setup.h b/include/drivers/marvell/mochi/ap_setup.h index eff447325..5b0e75f46 100644 --- a/include/drivers/marvell/mochi/ap_setup.h +++ b/include/drivers/marvell/mochi/ap_setup.h @@ -13,5 +13,6 @@ void ap_init(void); void ap_ble_init(void); int ap_get_count(void); +void update_cp110_default_win(int cp_id); #endif /* AP_SETUP_H */ diff --git a/plat/marvell/armada/a8k/common/plat_bl31_setup.c b/plat/marvell/armada/a8k/common/plat_bl31_setup.c index 98b3966ae..0a8a00cc7 100644 --- a/plat/marvell/armada/a8k/common/plat_bl31_setup.c +++ b/plat/marvell/armada/a8k/common/plat_bl31_setup.c @@ -117,8 +117,11 @@ void bl31_plat_arch_setup(void) for (cp = 0; cp < CP_COUNT; cp++) { /* configure cp110 for CP0*/ - if (cp == 1) + if (cp >= 1) { mci_initialize(MVEBU_MCI0); + update_cp110_default_win(cp); + } + /* initialize MCI & CP1 */ cp110_init(MVEBU_CP_REGS_BASE(cp), @@ -128,6 +131,12 @@ void bl31_plat_arch_setup(void) marvell_bl31_mpp_init(cp); } + /* + * There is need to configure IO_WIN windows again to overwrite + * temporary configuration done during update_cp110_default_win + */ + init_io_win(MVEBU_AP0); + /* initialize IPC between MSS and ATF */ if (mailbox[MBOX_IDX_MAGIC] != MVEBU_MAILBOX_MAGIC_NUM || mailbox[MBOX_IDX_SUSPEND_MAGIC] != MVEBU_MAILBOX_SUSPEND_STATE) -- cgit v1.2.3 From 38a7e6cdbd7cf3fe0a9cb752f364f13a55c89a9a Mon Sep 17 00:00:00 2001 From: Grzegorz Jaszczyk Date: Wed, 23 Jan 2019 15:47:57 +0100 Subject: plat: marvell: ap807: enable snoop filter for ap807 Snoop filter needs to be enabled once per cluster. Change-Id: I241e72f21982142ba290c7547df6f434e6a6a98d Signed-off-by: Grzegorz Jaszczyk --- .../armada/a8k/common/aarch64/plat_arch_config.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/plat/marvell/armada/a8k/common/aarch64/plat_arch_config.c b/plat/marvell/armada/a8k/common/aarch64/plat_arch_config.c index 06dc84115..9facdbc25 100644 --- a/plat/marvell/armada/a8k/common/aarch64/plat_arch_config.c +++ b/plat/marvell/armada/a8k/common/aarch64/plat_arch_config.c @@ -13,7 +13,21 @@ #define CCU_HTC_ASET (MVEBU_CCU_BASE(MVEBU_AP0) + 0x264) #define MVEBU_IO_AFFINITY (0xF00) +#define MVEBU_SF_REG (MVEBU_REGS_BASE + 0x40) +#define MVEBU_SF_EN BIT(8) +#ifdef MVEBU_SOC_AP807 +static void plat_enable_snoop_filter(void) +{ + int cpu_id = plat_my_core_pos(); + + /* Snoop filter needs to be enabled once per cluster */ + if (cpu_id % 2) + return; + + mmio_setbits_32(MVEBU_SF_REG, MVEBU_SF_EN); +} +#endif static void plat_enable_affinity(void) { @@ -42,4 +56,8 @@ void marvell_psci_arch_init(int die_index) /* Enable Affinity */ plat_enable_affinity(); + +#ifdef MVEBU_SOC_AP807 + plat_enable_snoop_filter(); +#endif } -- cgit v1.2.3 From 5c7c40f77bb0e30883d19c0db6f9fcacfeb9e7a0 Mon Sep 17 00:00:00 2001 From: Grzegorz Jaszczyk Date: Wed, 6 Feb 2019 15:58:42 +0100 Subject: plat: marvell: a8k: remove wrong or unnecessary comments Change-Id: Id702c070c433f8439faad115830e71b2873ab70a Signed-off-by: Grzegorz Jaszczyk --- plat/marvell/armada/a8k/common/plat_bl31_setup.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/plat/marvell/armada/a8k/common/plat_bl31_setup.c b/plat/marvell/armada/a8k/common/plat_bl31_setup.c index 0a8a00cc7..9d3affca5 100644 --- a/plat/marvell/armada/a8k/common/plat_bl31_setup.c +++ b/plat/marvell/armada/a8k/common/plat_bl31_setup.c @@ -116,18 +116,15 @@ void bl31_plat_arch_setup(void) marvell_bl31_plat_arch_setup(); for (cp = 0; cp < CP_COUNT; cp++) { - /* configure cp110 for CP0*/ if (cp >= 1) { mci_initialize(MVEBU_MCI0); update_cp110_default_win(cp); } - /* initialize MCI & CP1 */ cp110_init(MVEBU_CP_REGS_BASE(cp), STREAM_ID_BASE + (cp * MAX_STREAM_ID_PER_CP)); - /* Should be called only after setting IOB windows */ marvell_bl31_mpp_init(cp); } -- cgit v1.2.3 From 93574e7e6d733ca0e018445eaeb0432ee86e2057 Mon Sep 17 00:00:00 2001 From: Grzegorz Jaszczyk Date: Thu, 7 Feb 2019 15:15:14 +0100 Subject: plat: marvell: mci: use more meaningful name for mci link tuning The mci_initialize function name was misleading. The function itself doesn't initialize MCI in general but performs MCI link tuning for performance improvement. Change-Id: I13094ad2235182a14984035bbe58013ebde84a7e Signed-off-by: Grzegorz Jaszczyk --- drivers/marvell/mci.c | 2 +- include/drivers/marvell/mci.h | 2 +- plat/marvell/armada/a8k/common/plat_bl31_setup.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/marvell/mci.c b/drivers/marvell/mci.c index 06fe88e13..bd62a30e8 100644 --- a/drivers/marvell/mci.c +++ b/drivers/marvell/mci.c @@ -819,7 +819,7 @@ void mci_turn_link_on(void) } /* Initialize MCI for performance improvements */ -int mci_initialize(int mci_index) +int mci_link_tune(int mci_index) { int ret; diff --git a/include/drivers/marvell/mci.h b/include/drivers/marvell/mci.h index 8ef023459..af5d62066 100644 --- a/include/drivers/marvell/mci.h +++ b/include/drivers/marvell/mci.h @@ -10,7 +10,7 @@ #ifndef MCI_H #define MCI_H -int mci_initialize(int mci_index); +int mci_link_tune(int mci_index); void mci_turn_link_down(void); void mci_turn_link_on(void); int mci_get_link_status(void); diff --git a/plat/marvell/armada/a8k/common/plat_bl31_setup.c b/plat/marvell/armada/a8k/common/plat_bl31_setup.c index 9d3affca5..90e6672db 100644 --- a/plat/marvell/armada/a8k/common/plat_bl31_setup.c +++ b/plat/marvell/armada/a8k/common/plat_bl31_setup.c @@ -117,7 +117,7 @@ void bl31_plat_arch_setup(void) for (cp = 0; cp < CP_COUNT; cp++) { if (cp >= 1) { - mci_initialize(MVEBU_MCI0); + mci_link_tune(MVEBU_MCI0); update_cp110_default_win(cp); } -- cgit v1.2.3 From 56ad8612f610cea74c6132a07aa43a5967022ab4 Mon Sep 17 00:00:00 2001 From: Grzegorz Jaszczyk Date: Wed, 6 Feb 2019 14:16:51 +0100 Subject: plat: marvell: mci: perform mci link tuning for all mci interfaces This commit introduces two changes: - remove hardcoded references to mci0 from the driver - perform mci optimization for all mci interfaces It fixes performance issues observed on cn9132 CP2. Change-Id: I4e040cd54ff95c9134035ac89b87d8feb28e9eba Signed-off-by: Grzegorz Jaszczyk --- drivers/marvell/mci.c | 25 ++++++++++++------------ plat/marvell/armada/a8k/common/plat_bl31_setup.c | 8 ++++---- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/drivers/marvell/mci.c b/drivers/marvell/mci.c index bd62a30e8..2b5470042 100644 --- a/drivers/marvell/mci.c +++ b/drivers/marvell/mci.c @@ -571,21 +571,21 @@ static int mci_enable_simultaneous_transactions(int mci_index) debug_enter(); /* ID assignment (assigning global ID offset to CP) */ - mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(0), + mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index), MCI_DID_GLOBAL_ASSIGN_REQ_MCI_LOCAL_ID(2) | MCI_DID_GLOBAL_ASSIGN_REQ_MCI_COUNT(2) | MCI_DID_GLOBAL_ASSIGN_REQ_HOPS_NUM(2)); - mci_mmio_write_32(MCI_ACCESS_CMD_REG(0), + mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index), MCI_INDIRECT_REG_CTRL_ADDR( MCI_DID_GLOBAL_ASSIGNMENT_REQUEST_REG) | MCI_INDIRECT_CTRL_ASSIGN_CMD); ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE); /* Assigning dest. ID=3 to all transactions entering from AXI at AP */ - mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(0), + mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index), MCI_HB_CTRL_WIN0_DEST_VALID_FLAG(1) | MCI_HB_CTRL_WIN0_DEST_ID(3)); - mci_mmio_write_32(MCI_ACCESS_CMD_REG(0), + mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index), MCI_INDIRECT_REG_CTRL_ADDR( MCI_HB_CTRL_WIN0_DESTINATION_REG_NUM) | MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB) | @@ -593,10 +593,10 @@ static int mci_enable_simultaneous_transactions(int mci_index) ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE); /* Assigning dest. ID=1 to all transactions entering from AXI at CP */ - mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(0), + mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index), MCI_HB_CTRL_WIN0_DEST_VALID_FLAG(1) | MCI_HB_CTRL_WIN0_DEST_ID(1)); - mci_mmio_write_32(MCI_ACCESS_CMD_REG(0), + mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index), MCI_INDIRECT_REG_CTRL_ADDR( MCI_HB_CTRL_WIN0_DESTINATION_REG_NUM) | MCI_INDIRECT_CTRL_HOPID(GID_IHB_EXT) | @@ -607,8 +607,8 @@ static int mci_enable_simultaneous_transactions(int mci_index) * This will lead to get match for any AXI address * and receive destination ID=3 */ - mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(0), 0xffffffff); - mci_mmio_write_32(MCI_ACCESS_CMD_REG(0), + mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index), 0xffffffff); + mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index), MCI_INDIRECT_REG_CTRL_ADDR( MCI_HB_CTRL_WIN0_ADDRESS_MASK_REG_NUM) | MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB) | @@ -619,8 +619,8 @@ static int mci_enable_simultaneous_transactions(int mci_index) * This will lead to get match for any AXI address * and receive destination ID=1 */ - mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(0), 0xffffffff); - mci_mmio_write_32(MCI_ACCESS_CMD_REG(0), + mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index), 0xffffffff); + mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index), MCI_INDIRECT_REG_CTRL_ADDR( MCI_HB_CTRL_WIN0_ADDRESS_MASK_REG_NUM) | MCI_INDIRECT_CTRL_HOPID(GID_IHB_EXT) | @@ -653,7 +653,7 @@ static _Bool mci_simulatenous_trans_missing(int mci_index) * performed by BootROM. */ debug_enter(); - mci_mmio_write_32(MCI_ACCESS_CMD_REG(0), + mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index), MCI_INDIRECT_REG_CTRL_ADDR( MCI_HB_CTRL_WIN0_DESTINATION_REG_NUM) | MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB) | @@ -697,7 +697,8 @@ int mci_configure(int mci_index) * wasn't already enabled in bootrom. */ if (mci_simulatenous_trans_missing(mci_index)) { - VERBOSE("Enabling MCI simultaneous transaction\n"); + VERBOSE("Enabling MCI simultaneous transaction for mci%d\n", + mci_index); /* set MCI to support read/write transactions * to arrive at the same time */ diff --git a/plat/marvell/armada/a8k/common/plat_bl31_setup.c b/plat/marvell/armada/a8k/common/plat_bl31_setup.c index 90e6672db..621f43c63 100644 --- a/plat/marvell/armada/a8k/common/plat_bl31_setup.c +++ b/plat/marvell/armada/a8k/common/plat_bl31_setup.c @@ -116,11 +116,8 @@ void bl31_plat_arch_setup(void) marvell_bl31_plat_arch_setup(); for (cp = 0; cp < CP_COUNT; cp++) { - if (cp >= 1) { - mci_link_tune(MVEBU_MCI0); + if (cp >= 1) update_cp110_default_win(cp); - } - cp110_init(MVEBU_CP_REGS_BASE(cp), STREAM_ID_BASE + (cp * MAX_STREAM_ID_PER_CP)); @@ -134,6 +131,9 @@ void bl31_plat_arch_setup(void) */ init_io_win(MVEBU_AP0); + for (cp = 1; cp < CP_COUNT; cp++) + mci_link_tune(cp - 1); + /* initialize IPC between MSS and ATF */ if (mailbox[MBOX_IDX_MAGIC] != MVEBU_MAILBOX_MAGIC_NUM || mailbox[MBOX_IDX_SUSPEND_MAGIC] != MVEBU_MAILBOX_SUSPEND_STATE) -- cgit v1.2.3 From 57adbf37e6177eab79277ce5406a9bbde930ee3c Mon Sep 17 00:00:00 2001 From: Alex Leibovich Date: Mon, 25 Feb 2019 12:24:29 +0200 Subject: ddr: a80x0: add DDR 32-bit mode support This commit introduces 32-bit DDR topology map initialization. For that purpose a new DDR32 build flag is added, with according documentation update. Change-Id: I169ff358c2923afd984e27bc126dc551dcaefc01 Signed-off-by: Alex Leibovich --- docs/plat/marvell/armada/build.rst | 4 ++++ plat/marvell/armada/a8k/a80x0/board/dram_port.c | 5 +++++ plat/marvell/marvell.mk | 4 ++++ 3 files changed, 13 insertions(+) diff --git a/docs/plat/marvell/armada/build.rst b/docs/plat/marvell/armada/build.rst index 1b60fc554..6f28721d5 100644 --- a/docs/plat/marvell/armada/build.rst +++ b/docs/plat/marvell/armada/build.rst @@ -194,6 +194,10 @@ Special Build Flags can interrupt UART recovery process). This MACRO definition is set in ``plat/marvell/armada/a8k/common/include/platform_def.h`` file. +- DDR32 + In order to work in 32bit DDR, instead of the default 64bit ECC DDR, + this flag should be set to 1. + For more information about build options, please refer to the :ref:`Build Options` document. diff --git a/plat/marvell/armada/a8k/a80x0/board/dram_port.c b/plat/marvell/armada/a8k/a80x0/board/dram_port.c index 02f4ffb0a..7abd3436d 100644 --- a/plat/marvell/armada/a8k/a80x0/board/dram_port.c +++ b/plat/marvell/armada/a8k/a80x0/board/dram_port.c @@ -52,8 +52,13 @@ static struct mv_ddr_topology_map board_topology_map = { MV_DDR_FREQ_SAR, /* frequency */ 0, 0, /* cas_l, cas_wl */ MV_DDR_TEMP_LOW} }, /* temperature */ +#if DDR32 + MV_DDR_32BIT_ECC_PUP8_BUS_MASK, /* subphys mask */ + MV_DDR_CFG_DEFAULT, /* ddr configuration data source */ +#else MV_DDR_64BIT_ECC_PUP8_BUS_MASK, /* subphys mask */ MV_DDR_CFG_SPD, /* ddr configuration data source */ +#endif { {0} }, /* raw spd data */ {0}, /* timing parameters */ { /* electrical configuration */ diff --git a/plat/marvell/marvell.mk b/plat/marvell/marvell.mk index d8be0dd17..82457536d 100644 --- a/plat/marvell/marvell.mk +++ b/plat/marvell/marvell.mk @@ -16,6 +16,10 @@ $(eval $(call add_define,MARVELL_SECURE_BOOT)) PALLADIUM := 0 $(eval $(call add_define,PALLADIUM)) +# Set board to work with DDR 32bit +DDR32 := 0 +$(eval $(call add_define,DDR32)) + ifeq (${MARVELL_SECURE_BOOT},1) DOIMAGE_SEC_FLAGS := -c $(DOIMAGE_SEC) DOIMAGE_LIBS_CHECK = \ -- cgit v1.2.3 From 85d2ed150158e4c92f3238342a76dea4c30d7a95 Mon Sep 17 00:00:00 2001 From: Alex Leibovich Date: Sun, 10 Feb 2019 15:08:25 +0200 Subject: ble: ap807: clean-up PLL configuration sequence Remove pll powerdown from pll configuration sequence to improve stability. Remove redundant cases, which no longer exist. Also get rid of irrelevant definition of CPU_2200_DDR_1200_RCLK_1200, which is not used by 806/807. Change-Id: If911e7dee003dfb9a42fafd7ffe34662f026fd23 Signed-off-by: Alex Leibovich --- drivers/marvell/ap807_clocks_init.c | 25 ++++++------------------- include/drivers/marvell/aro.h | 4 ---- plat/marvell/armada/a8k/common/plat_ble_setup.c | 3 --- 3 files changed, 6 insertions(+), 26 deletions(-) diff --git a/drivers/marvell/ap807_clocks_init.c b/drivers/marvell/ap807_clocks_init.c index 5604453bb..d6a97b22b 100644 --- a/drivers/marvell/ap807_clocks_init.c +++ b/drivers/marvell/ap807_clocks_init.c @@ -46,11 +46,6 @@ static void pll_set_freq(unsigned int freq_val) int i; for (i = 0 ; i < AP807_CLUSTER_NUM ; i++) { - mmio_write_32(AP807_CPU_PLL_CFG(i), - AP807_CPU_PLL_CFG_USE_REG_FILE); - mmio_write_32(AP807_CPU_PLL_CFG(i), - AP807_CPU_PLL_CFG_USE_REG_FILE | - AP807_CPU_PLL_CFG_BYPASS_MODE); mmio_write_32(AP807_CPU_PLL_PARAM(i), freq_val); mmio_write_32(AP807_CPU_PLL_CFG(i), AP807_CPU_PLL_CFG_USE_REG_FILE); @@ -84,24 +79,16 @@ static void aro_to_pll(void) */ void ap807_clocks_init(unsigned int freq_option) { - /* Switch from ARO to PLL */ - aro_to_pll(); - /* Modifications in frequency table: * 0x0: 764x: change to 2000 MHz. * 0x2: 744x change to 1800 MHz, 764x change to 2200/2400. * 0x3: 3900/744x/764x change to 1200 MHz. */ - switch (freq_option) { - case CPU_2000_DDR_1200_RCLK_1200: - pll_set_freq(PLL_FREQ_2000); - break; -#ifdef MVEBU_SOC_AP807 - case CPU_2200_DDR_1200_RCLK_1200: + + if (freq_option == CPU_2200_DDR_1200_RCLK_1200) pll_set_freq(PLL_FREQ_2200); - break; -#endif - default: - break; - } + + /* Switch from ARO to PLL */ + aro_to_pll(); + } diff --git a/include/drivers/marvell/aro.h b/include/drivers/marvell/aro.h index c9dd36e4f..4d1094a65 100644 --- a/include/drivers/marvell/aro.h +++ b/include/drivers/marvell/aro.h @@ -27,11 +27,7 @@ enum cpu_clock_freq_mode { CPU_2000_DDR_1200_RCLK_1200 = 0x0, CPU_2000_DDR_1050_RCLK_1050 = 0x1, CPU_1600_DDR_800_RCLK_800 = 0x4, -#ifdef MVEBU_SOC_AP807 CPU_2200_DDR_1200_RCLK_1200 = 0x6, -#else - CPU_1800_DDR_1200_RCLK_1200 = 0x6, -#endif CPU_1800_DDR_1050_RCLK_1050 = 0x7, CPU_1600_DDR_900_RCLK_900 = 0x0B, CPU_1600_DDR_1050_RCLK_1050 = 0x0D, diff --git a/plat/marvell/armada/a8k/common/plat_ble_setup.c b/plat/marvell/armada/a8k/common/plat_ble_setup.c index 166f18b86..f11b5ac17 100644 --- a/plat/marvell/armada/a8k/common/plat_ble_setup.c +++ b/plat/marvell/armada/a8k/common/plat_ble_setup.c @@ -478,9 +478,6 @@ static void ble_plat_svc_config(void) NOTICE("SVC: DEV ID: %s, FREQ Mode: 0x%x\n", single_cluster == 0 ? "8040" : "8020", freq_pidi_mode); switch (freq_pidi_mode) { -#ifndef MVEBU_SOC_AP807 - case CPU_1800_DDR_1200_RCLK_1200: -#endif case CPU_1800_DDR_1050_RCLK_1050: if (perr[1]) goto perror; -- cgit v1.2.3 From 615d859b2e59d3c7f5f218c768340a3a3de0b8dc Mon Sep 17 00:00:00 2001 From: Alex Leibovich Date: Mon, 25 Feb 2019 13:13:48 +0200 Subject: ble: ap807: improve PLL configuration sequence Update PLL configuration according to HW team guidelines. Change-Id: I23cac4fb4a638e7416965a5399ce6947e08d0711 Signed-off-by: Alex Leibovich --- drivers/marvell/ap807_clocks_init.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/marvell/ap807_clocks_init.c b/drivers/marvell/ap807_clocks_init.c index d6a97b22b..c1f861909 100644 --- a/drivers/marvell/ap807_clocks_init.c +++ b/drivers/marvell/ap807_clocks_init.c @@ -39,14 +39,29 @@ #define AP807_CPU_PLL_PARAM(cluster) AP807_CPU_PLL_CTRL(cluster) #define AP807_CPU_PLL_CFG(cluster) (AP807_CPU_PLL_CTRL(cluster) + 0x4) #define AP807_CPU_PLL_CFG_BYPASS_MODE (0x1) +#define AP807_CPU_PLL_FRC_DSCHG (0x2) #define AP807_CPU_PLL_CFG_USE_REG_FILE (0x1 << 9) static void pll_set_freq(unsigned int freq_val) { int i; + if (freq_val != PLL_FREQ_2200) + return; + for (i = 0 ; i < AP807_CLUSTER_NUM ; i++) { + /* Set parameter of cluster i PLL to 2.2GHz */ mmio_write_32(AP807_CPU_PLL_PARAM(i), freq_val); + /* Set apll_lpf_frc_dschg - Control + * voltage of internal VCO is discharged + */ + mmio_write_32(AP807_CPU_PLL_CFG(i), + AP807_CPU_PLL_FRC_DSCHG); + /* Set use_rf_conf load PLL parameter from register */ + mmio_write_32(AP807_CPU_PLL_CFG(i), + AP807_CPU_PLL_FRC_DSCHG | + AP807_CPU_PLL_CFG_USE_REG_FILE); + /* Un-set apll_lpf_frc_dschg */ mmio_write_32(AP807_CPU_PLL_CFG(i), AP807_CPU_PLL_CFG_USE_REG_FILE); } -- cgit v1.2.3 From 32b3b99918ec2b1d3d490a7f7151d4d1af76518f Mon Sep 17 00:00:00 2001 From: Alex Leibovich Date: Sun, 10 Mar 2019 16:45:02 +0200 Subject: ddr: a80x0: add DDR 32-bit ECC mode support Change a topology map from internal database to SPD based for 32bit bus width mode Change-Id: I803166893ddc2fd916fc8a1c27fffd34b6ec0c72 Signed-off-by: Alex Leibovich --- plat/marvell/armada/a8k/a80x0/board/dram_port.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plat/marvell/armada/a8k/a80x0/board/dram_port.c b/plat/marvell/armada/a8k/a80x0/board/dram_port.c index 7abd3436d..017d8a734 100644 --- a/plat/marvell/armada/a8k/a80x0/board/dram_port.c +++ b/plat/marvell/armada/a8k/a80x0/board/dram_port.c @@ -54,11 +54,10 @@ static struct mv_ddr_topology_map board_topology_map = { MV_DDR_TEMP_LOW} }, /* temperature */ #if DDR32 MV_DDR_32BIT_ECC_PUP8_BUS_MASK, /* subphys mask */ - MV_DDR_CFG_DEFAULT, /* ddr configuration data source */ #else MV_DDR_64BIT_ECC_PUP8_BUS_MASK, /* subphys mask */ - MV_DDR_CFG_SPD, /* ddr configuration data source */ #endif + MV_DDR_CFG_SPD, /* ddr configuration data source */ { {0} }, /* raw spd data */ {0}, /* timing parameters */ { /* electrical configuration */ -- cgit v1.2.3 From 81de5bf7fb2f5822c0c6ce37bde9a082a11a4044 Mon Sep 17 00:00:00 2001 From: Manish Pandey Date: Mon, 8 Jun 2020 14:48:09 +0100 Subject: plat/arm: do not include export header directly As per "include/export/README", TF-A code should never include export headers directly. Instead, it should include a wrapper header that ensures the export header is included in the right manner. "tbbr_img_def_exp.h" is directly included in TF-A code, this patch replaces it with its wrapper header "tbbr_img_def.h". Signed-off-by: Manish Pandey Change-Id: I31c1a42e6a7bcac4c396bb17e8548567ecd8147d --- plat/arm/board/a5ds/fdts/a5ds_fw_config.dts | 2 +- plat/arm/board/fvp/fdts/fvp_fw_config.dts | 2 +- plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts | 2 +- plat/arm/board/juno/fdts/juno_fw_config.dts | 2 +- plat/arm/board/rddaniel/fdts/rddaniel_fw_config.dts | 2 +- plat/arm/board/rddanielxlr/fdts/rddanielxlr_fw_config.dts | 2 +- plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts | 2 +- plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts | 2 +- plat/arm/board/sgi575/fdts/sgi575_fw_config.dts | 2 +- plat/arm/board/sgm775/fdts/sgm775_fw_config.dts | 2 +- plat/arm/board/tc0/fdts/tc0_fw_config.dts | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts b/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts index ff079ab6f..b9d905388 100644 --- a/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts +++ b/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include +#include /dts-v1/; diff --git a/plat/arm/board/fvp/fdts/fvp_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_fw_config.dts index 7c111085d..8f87f7c62 100644 --- a/plat/arm/board/fvp/fdts/fvp_fw_config.dts +++ b/plat/arm/board/fvp/fdts/fvp_fw_config.dts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include +#include /dts-v1/; diff --git a/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts b/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts index 1727e2e24..d4f98d940 100644 --- a/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts +++ b/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include +#include /dts-v1/; diff --git a/plat/arm/board/juno/fdts/juno_fw_config.dts b/plat/arm/board/juno/fdts/juno_fw_config.dts index 4e460aa78..60ca60daa 100644 --- a/plat/arm/board/juno/fdts/juno_fw_config.dts +++ b/plat/arm/board/juno/fdts/juno_fw_config.dts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include +#include /dts-v1/; diff --git a/plat/arm/board/rddaniel/fdts/rddaniel_fw_config.dts b/plat/arm/board/rddaniel/fdts/rddaniel_fw_config.dts index bb544a410..b9265ad9e 100644 --- a/plat/arm/board/rddaniel/fdts/rddaniel_fw_config.dts +++ b/plat/arm/board/rddaniel/fdts/rddaniel_fw_config.dts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include +#include /dts-v1/; diff --git a/plat/arm/board/rddanielxlr/fdts/rddanielxlr_fw_config.dts b/plat/arm/board/rddanielxlr/fdts/rddanielxlr_fw_config.dts index bb544a410..b9265ad9e 100644 --- a/plat/arm/board/rddanielxlr/fdts/rddanielxlr_fw_config.dts +++ b/plat/arm/board/rddanielxlr/fdts/rddanielxlr_fw_config.dts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include +#include /dts-v1/; diff --git a/plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts b/plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts index a5b4a583d..09b9867e3 100644 --- a/plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts +++ b/plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include +#include /dts-v1/; diff --git a/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts b/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts index 1f460f185..88d8e99d8 100644 --- a/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts +++ b/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include +#include /dts-v1/; / { diff --git a/plat/arm/board/sgi575/fdts/sgi575_fw_config.dts b/plat/arm/board/sgi575/fdts/sgi575_fw_config.dts index da933e546..94d0e39a8 100644 --- a/plat/arm/board/sgi575/fdts/sgi575_fw_config.dts +++ b/plat/arm/board/sgi575/fdts/sgi575_fw_config.dts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include +#include /dts-v1/; diff --git a/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts b/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts index 306bd89b9..c92c1d055 100644 --- a/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts +++ b/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include +#include /dts-v1/; diff --git a/plat/arm/board/tc0/fdts/tc0_fw_config.dts b/plat/arm/board/tc0/fdts/tc0_fw_config.dts index 8d7faf8b4..0128f0b6f 100644 --- a/plat/arm/board/tc0/fdts/tc0_fw_config.dts +++ b/plat/arm/board/tc0/fdts/tc0_fw_config.dts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include +#include /dts-v1/; -- cgit v1.2.3 From 0792dd7d64d1056fae05eab8cebe91ffc993923e Mon Sep 17 00:00:00 2001 From: Manish Pandey Date: Fri, 22 May 2020 12:27:28 +0100 Subject: cert_create: add SiP owned secure partitions support Add support to generate certificate "sip-sp-cert" for Secure Partitions(SP) owned by Silicon provider(SiP). To avoid deviation from TBBR specification the support is only added for dualroot CoT and not for TBBR CoT. A single certificate file is generated containing hash of individual packages. Maximum 8 secure partitions are supported. Following new options added to cert_tool: --sip-sp-cert --> SiP owned Secure Partition Content Certificate --sp-pkg1 --> Secure Partition Package1 file --sp-pkg2 ..... --sp-pkg8 Trusted world key pair is used for signing. Going forward, this feature can be extended for Platfrom owned Partitions, if required. Signed-off-by: Manish Pandey Change-Id: Ia6dfbc1447cfb41b1fcbd12cf2bf7b88f409bd8d --- include/tools_share/dualroot_oid.h | 12 ++++ include/tools_share/firmware_image_package.h | 2 + lib/debugfs/devfip.c | 3 +- make_helpers/tbbr/tbbr_tools.mk | 5 ++ tools/cert_create/include/cert.h | 2 +- tools/cert_create/include/dualroot/cot.h | 9 +++ tools/cert_create/src/dualroot/cot.c | 103 +++++++++++++++++++++++++++ tools/fiptool/tbbr_config.c | 5 ++ 8 files changed, 139 insertions(+), 2 deletions(-) diff --git a/include/tools_share/dualroot_oid.h b/include/tools_share/dualroot_oid.h index 3e88a6d22..da367da92 100644 --- a/include/tools_share/dualroot_oid.h +++ b/include/tools_share/dualroot_oid.h @@ -16,4 +16,16 @@ */ #define PROT_PK_OID "1.3.6.1.4.1.4128.2100.1102" +/* + * Secure Partitions Content Certificate + */ +#define SP_PKG1_HASH_OID "1.3.6.1.4.1.4128.2100.1301" +#define SP_PKG2_HASH_OID "1.3.6.1.4.1.4128.2100.1302" +#define SP_PKG3_HASH_OID "1.3.6.1.4.1.4128.2100.1303" +#define SP_PKG4_HASH_OID "1.3.6.1.4.1.4128.2100.1304" +#define SP_PKG5_HASH_OID "1.3.6.1.4.1.4128.2100.1305" +#define SP_PKG6_HASH_OID "1.3.6.1.4.1.4128.2100.1306" +#define SP_PKG7_HASH_OID "1.3.6.1.4.1.4128.2100.1307" +#define SP_PKG8_HASH_OID "1.3.6.1.4.1.4128.2100.1308" + #endif /* DUALROOT_OID_H */ diff --git a/include/tools_share/firmware_image_package.h b/include/tools_share/firmware_image_package.h index 598d5c258..75f3cc6a6 100644 --- a/include/tools_share/firmware_image_package.h +++ b/include/tools_share/firmware_image_package.h @@ -64,6 +64,8 @@ {{0xa4, 0x9f, 0x44, 0x11}, {0x5e, 0x63}, {0xe4, 0x11}, 0x87, 0x28, {0x3f, 0x05, 0x72, 0x2a, 0xf3, 0x3d} } #define UUID_NON_TRUSTED_FW_CONTENT_CERT \ {{0x8e, 0xc4, 0xc1, 0xf3}, {0x5d, 0x63}, {0xe4, 0x11}, 0xa7, 0xa9, {0x87, 0xee, 0x40, 0xb2, 0x3f, 0xa7} } +#define UUID_SIP_SECURE_PARTITION_CONTENT_CERT \ + {{0x77, 0x6d, 0xfd, 0x44}, {0x86, 0x97}, {0x4c, 0x3b}, 0x91, 0xeb, {0xc1, 0x3e, 0x02, 0x5a, 0x2a, 0x6f} } /* Dynamic configs */ #define UUID_HW_CONFIG \ {{0x08, 0xb8, 0xf1, 0xd9}, {0xc9, 0xcf}, {0x93, 0x49}, 0xa9, 0x62, {0x6f, 0xbc, 0x6b, 0x72, 0x65, 0xcc} } diff --git a/lib/debugfs/devfip.c b/lib/debugfs/devfip.c index fc14e707e..70ac3bc04 100644 --- a/lib/debugfs/devfip.c +++ b/lib/debugfs/devfip.c @@ -74,7 +74,8 @@ static const struct uuidnames uuidnames[] = { {"tos-fw.cfg", UUID_TOS_FW_CONFIG}, {"nt-fw.cfg", UUID_NT_FW_CONFIG}, {"rot-k.crt", UUID_ROT_KEY_CERT}, - {"nt-k.crt", UUID_NON_TRUSTED_WORLD_KEY_CERT} + {"nt-k.crt", UUID_NON_TRUSTED_WORLD_KEY_CERT}, + {"sip-sp.crt", UUID_SIP_SECURE_PARTITION_CONTENT_CERT} }; /******************************************************************************* diff --git a/make_helpers/tbbr/tbbr_tools.mk b/make_helpers/tbbr/tbbr_tools.mk index f0adfe1ce..952093443 100644 --- a/make_helpers/tbbr/tbbr_tools.mk +++ b/make_helpers/tbbr/tbbr_tools.mk @@ -99,3 +99,8 @@ ifneq (${COT},dualroot) $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/nt_fw_key.crt,--nt-fw-key-cert)) endif endif + +# Add SiP owned Secure Partitions CoT (image cert) +ifneq (${SP_LAYOUT_FILE},) + $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/sip_sp_content.crt,--sip-sp-cert)) +endif diff --git a/tools/cert_create/include/cert.h b/tools/cert_create/include/cert.h index 6db9b579d..daf27a78a 100644 --- a/tools/cert_create/include/cert.h +++ b/tools/cert_create/include/cert.h @@ -12,7 +12,7 @@ #include "ext.h" #include "key.h" -#define CERT_MAX_EXT 5 +#define CERT_MAX_EXT 9 /* * This structure contains information related to the generation of the diff --git a/tools/cert_create/include/dualroot/cot.h b/tools/cert_create/include/dualroot/cot.h index 570120682..47e371fe1 100644 --- a/tools/cert_create/include/dualroot/cot.h +++ b/tools/cert_create/include/dualroot/cot.h @@ -18,6 +18,7 @@ enum { SOC_FW_CONTENT_CERT, TRUSTED_OS_FW_KEY_CERT, TRUSTED_OS_FW_CONTENT_CERT, + SIP_SECURE_PARTITION_CONTENT_CERT, FWU_CERT, /* Certificates owned by the platform owner. */ @@ -42,6 +43,14 @@ enum { TRUSTED_OS_FW_EXTRA1_HASH_EXT, TRUSTED_OS_FW_EXTRA2_HASH_EXT, TRUSTED_OS_FW_CONFIG_HASH_EXT, + SP_PKG1_HASH_EXT, + SP_PKG2_HASH_EXT, + SP_PKG3_HASH_EXT, + SP_PKG4_HASH_EXT, + SP_PKG5_HASH_EXT, + SP_PKG6_HASH_EXT, + SP_PKG7_HASH_EXT, + SP_PKG8_HASH_EXT, SCP_FWU_CFG_HASH_EXT, AP_FWU_CFG_HASH_EXT, FWU_HASH_EXT, diff --git a/tools/cert_create/src/dualroot/cot.c b/tools/cert_create/src/dualroot/cot.c index 8117ffc16..29658281c 100644 --- a/tools/cert_create/src/dualroot/cot.c +++ b/tools/cert_create/src/dualroot/cot.c @@ -137,6 +137,28 @@ static cert_t cot_certs[] = { .num_ext = 5 }, + [SIP_SECURE_PARTITION_CONTENT_CERT] = { + .id = SIP_SECURE_PARTITION_CONTENT_CERT, + .opt = "sip-sp-cert", + .help_msg = "SiP owned Secure Partition Content Certificate (output file)", + .fn = NULL, + .cn = "SiP owned Secure Partition Content Certificate", + .key = TRUSTED_WORLD_KEY, + .issuer = SIP_SECURE_PARTITION_CONTENT_CERT, + .ext = { + TRUSTED_FW_NVCOUNTER_EXT, + SP_PKG1_HASH_EXT, + SP_PKG2_HASH_EXT, + SP_PKG3_HASH_EXT, + SP_PKG4_HASH_EXT, + SP_PKG5_HASH_EXT, + SP_PKG6_HASH_EXT, + SP_PKG7_HASH_EXT, + SP_PKG8_HASH_EXT, + }, + .num_ext = 9 + }, + [FWU_CERT] = { .id = FWU_CERT, .opt = "fwu-cert", @@ -327,6 +349,87 @@ static ext_t cot_ext[] = { .optional = 1 }, + [SP_PKG1_HASH_EXT] = { + .oid = SP_PKG1_HASH_OID, + .opt = "sp-pkg1", + .help_msg = "Secure Partition Package1 file", + .sn = "SPPkg1Hash", + .ln = "SP Pkg1 hash (SHA256)", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_HASH, + .optional = 1 + }, + [SP_PKG2_HASH_EXT] = { + .oid = SP_PKG2_HASH_OID, + .opt = "sp-pkg2", + .help_msg = "Secure Partition Package2 file", + .sn = "SPPkg2Hash", + .ln = "SP Pkg2 hash (SHA256)", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_HASH, + .optional = 1 + }, + [SP_PKG3_HASH_EXT] = { + .oid = SP_PKG3_HASH_OID, + .opt = "sp-pkg3", + .help_msg = "Secure Partition Package3 file", + .sn = "SPPkg3Hash", + .ln = "SP Pkg3 hash (SHA256)", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_HASH, + .optional = 1 + }, + [SP_PKG4_HASH_EXT] = { + .oid = SP_PKG4_HASH_OID, + .opt = "sp-pkg4", + .help_msg = "Secure Partition Package4 file", + .sn = "SPPkg4Hash", + .ln = "SP Pkg4 hash (SHA256)", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_HASH, + .optional = 1 + }, + [SP_PKG5_HASH_EXT] = { + .oid = SP_PKG5_HASH_OID, + .opt = "sp-pkg5", + .help_msg = "Secure Partition Package5 file", + .sn = "SPPkg5Hash", + .ln = "SP Pkg5 hash (SHA256)", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_HASH, + .optional = 1 + }, + [SP_PKG6_HASH_EXT] = { + .oid = SP_PKG6_HASH_OID, + .opt = "sp-pkg6", + .help_msg = "Secure Partition Package6 file", + .sn = "SPPkg6Hash", + .ln = "SP Pkg6 hash (SHA256)", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_HASH, + .optional = 1 + }, + [SP_PKG7_HASH_EXT] = { + .oid = SP_PKG7_HASH_OID, + .opt = "sp-pkg7", + .help_msg = "Secure Partition Package7 file", + .sn = "SPPkg7Hash", + .ln = "SP Pkg7 hash (SHA256)", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_HASH, + .optional = 1 + }, + [SP_PKG8_HASH_EXT] = { + .oid = SP_PKG8_HASH_OID, + .opt = "sp-pkg8", + .help_msg = "Secure Partition Package8 file", + .sn = "SPPkg8Hash", + .ln = "SP Pkg8 hash (SHA256)", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_HASH, + .optional = 1 + }, + [SCP_FWU_CFG_HASH_EXT] = { .oid = SCP_FWU_CFG_HASH_OID, .opt = "scp-fwu-cfg", diff --git a/tools/fiptool/tbbr_config.c b/tools/fiptool/tbbr_config.c index 86b8581f8..1c5ef5f59 100644 --- a/tools/fiptool/tbbr_config.c +++ b/tools/fiptool/tbbr_config.c @@ -151,6 +151,11 @@ toc_entry_t toc_entries[] = { .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT, .cmdline_name = "nt-fw-cert" }, + { + .name = "SiP owned Secure Partition content certificate", + .uuid = UUID_SIP_SECURE_PARTITION_CONTENT_CERT, + .cmdline_name = "sip-sp-cert" + }, { .name = NULL, .uuid = { {0} }, -- cgit v1.2.3 From 07c4447588ed53b526563d0a9f61e401d24d0952 Mon Sep 17 00:00:00 2001 From: Manish Pandey Date: Tue, 26 May 2020 23:59:36 +0100 Subject: sptool: append cert_tool arguments. To support secure boot of SP's update cert tool arguments while generating sp_gen.mk which in turn is consumed by build system. Signed-off-by: Manish Pandey Change-Id: I2293cee9b7c684c27d387aba18e0294c701fb1cc --- Makefile | 1 + tools/sptool/sp_mk_generator.py | 11 +++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 2f53cdf1b..f836fddb7 100644 --- a/Makefile +++ b/Makefile @@ -1010,6 +1010,7 @@ ifdef SP_LAYOUT_FILE endif -include $(BUILD_PLAT)/sp_gen.mk FIP_DEPS += sp + CRT_DEPS += sp NEED_SP_PKG := yes else ifeq (${SPMD_SPM_AT_SEL2},1) diff --git a/tools/sptool/sp_mk_generator.py b/tools/sptool/sp_mk_generator.py index 6b6fa1914..f2387f6b1 100755 --- a/tools/sptool/sp_mk_generator.py +++ b/tools/sptool/sp_mk_generator.py @@ -11,7 +11,8 @@ Layout file can exist outside of TF-A tree and the paths of Image and PM files must be relative to it. This script parses the layout file and generates a make file which updates -FDT_SOURCES, FIP_ARGS and SPTOOL_ARGS which are used in later build steps. +FDT_SOURCES, FIP_ARGS, CRT_ARGS and SPTOOL_ARGS which are used in later build +steps. This script also gets SP "uuid" from parsing its PM and converting it to a standard format. @@ -24,6 +25,7 @@ Secure Partition entry FDT_SOURCES += sp1.dts SPTOOL_ARGS += -i sp1.bin:sp1.dtb -o sp1.pkg FIP_ARGS += --blob uuid=XXXXX-XXX...,file=sp1.pkg + CRT_ARGS += --sp-pkg1 sp1.pkg A typical SP_LAYOUT_FILE file will look like { @@ -59,7 +61,7 @@ dtb_dir = out_dir + "/fdts/" print(dtb_dir) with open(gen_file, 'w') as out_file: - for key in data.keys(): + for idx, key in enumerate(data.keys()): """ Append FDT_SOURCES @@ -97,4 +99,9 @@ with open(gen_file, 'w') as out_file: Append FIP_ARGS """ out_file.write("FIP_ARGS += --blob uuid=" + uuid_std + ",file=" + dst + "\n") + + """ + Append CRT_ARGS + """ + out_file.write("CRT_ARGS += --sp-pkg" + str(idx + 1) + " " + dst + "\n") out_file.write("\n") -- cgit v1.2.3 From fa09d54454e91ee9fcb157a8134e18dd070ed957 Mon Sep 17 00:00:00 2001 From: Tien Hock Loh Date: Mon, 11 May 2020 01:11:23 -0700 Subject: plat: intel: Fix clock configuration bugs This fixes a few issues on the Agilex clock configuration: - Set clock manager into boot mode before configuring clock - Fix wrong divisor used when calculating vcocalib - PLL sync configuration should be read and then written - Wait PLL lock after PLL sync configuration is done - Clear interrupt bits instead of set interrupt bits after configuration Signed-off-by: Tien Hock Loh Change-Id: I54c1dc5fe9b102e3bbc1237a92d8471173b8af70 --- plat/intel/soc/agilex/soc/agilex_clock_manager.c | 76 +++++++++++++----------- 1 file changed, 42 insertions(+), 34 deletions(-) diff --git a/plat/intel/soc/agilex/soc/agilex_clock_manager.c b/plat/intel/soc/agilex/soc/agilex_clock_manager.c index c6c48baea..4efd7131d 100644 --- a/plat/intel/soc/agilex/soc/agilex_clock_manager.c +++ b/plat/intel/soc/agilex/soc/agilex_clock_manager.c @@ -47,14 +47,14 @@ uint32_t wait_fsm(void) return 0; } -uint32_t pll_source_sync_config(uint32_t pll_mem_offset) +uint32_t pll_source_sync_config(uint32_t pll_mem_offset, uint32_t data) { uint32_t val = 0; uint32_t count = 0; uint32_t req_status = 0; val = (CLKMGR_MEM_WR | CLKMGR_MEM_REQ | - CLKMGR_MEM_WDAT << CLKMGR_MEM_WDAT_OFFSET | CLKMGR_MEM_ADDR); + (data << CLKMGR_MEM_WDAT_OFFSET) | CLKMGR_MEM_ADDR); mmio_write_32(pll_mem_offset, val); do { @@ -89,14 +89,17 @@ uint32_t pll_source_sync_read(uint32_t pll_mem_offset) rdata = mmio_read_32(pll_mem_offset + 0x4); INFO("rdata (%x) = %x\n", pll_mem_offset + 0x4, rdata); - return 0; + return rdata; } void config_clkmgr_handoff(handoff *hoff_ptr) { uint32_t mdiv, mscnt, hscnt; - uint32_t arefclk_div, drefclk_div; + uint32_t drefclk_div, refclk_div, rdata; + /* Set clock maanger into boot mode before running configuration */ + mmio_setbits_32(CLKMGR_OFFSET + CLKMGR_CTRL, + CLKMGR_CTRL_BOOTMODE_SET_MSK); /* Bypass all mainpllgrp's clocks */ mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_BYPASS, 0x7); wait_fsm(); @@ -116,26 +119,24 @@ void config_clkmgr_handoff(handoff *hoff_ptr) /* Setup main PLL dividers */ mdiv = CLKMGR_PLLM_MDIV(hoff_ptr->main_pll_pllm); - arefclk_div = CLKMGR_PLLGLOB_AREFCLKDIV( - hoff_ptr->main_pll_pllglob); drefclk_div = CLKMGR_PLLGLOB_DREFCLKDIV( hoff_ptr->main_pll_pllglob); + refclk_div = CLKMGR_PLLGLOB_REFCLKDIV( + hoff_ptr->main_pll_pllglob); - mscnt = 100 / (mdiv / BIT(drefclk_div)); + mscnt = 100 / (mdiv * BIT(drefclk_div)); if (!mscnt) mscnt = 1; - hscnt = (mdiv * mscnt * BIT(drefclk_div) / arefclk_div) - 4; + hscnt = (mdiv * mscnt * BIT(drefclk_div) / refclk_div) - 4; - mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_VCOCALIB, - CLKMGR_VCOCALIB_HSCNT_SET(hscnt) | - CLKMGR_VCOCALIB_MSCNT_SET(mscnt)); - - mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_NOCDIV, - hoff_ptr->main_pll_nocdiv); mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLGLOB, - hoff_ptr->main_pll_pllglob); + hoff_ptr->main_pll_pllglob & + ~CLKMGR_PLLGLOB_RST_SET_MSK); mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_FDBCK, hoff_ptr->main_pll_fdbck); + mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_VCOCALIB, + CLKMGR_VCOCALIB_HSCNT_SET(hscnt) | + CLKMGR_VCOCALIB_MSCNT_SET(mscnt)); mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLC0, hoff_ptr->main_pll_pllc0); mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLC1, @@ -150,33 +151,33 @@ void config_clkmgr_handoff(handoff *hoff_ptr) hoff_ptr->main_pll_mpuclk); mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_NOCCLK, hoff_ptr->main_pll_nocclk); + mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_NOCDIV, + hoff_ptr->main_pll_nocdiv); /* Setup peripheral PLL dividers */ mdiv = CLKMGR_PLLM_MDIV(hoff_ptr->per_pll_pllm); - arefclk_div = CLKMGR_PLLGLOB_AREFCLKDIV( - hoff_ptr->per_pll_pllglob); drefclk_div = CLKMGR_PLLGLOB_DREFCLKDIV( hoff_ptr->per_pll_pllglob); + refclk_div = CLKMGR_PLLGLOB_REFCLKDIV( + hoff_ptr->per_pll_pllglob); - mscnt = 100 / (mdiv / BIT(drefclk_div)); + + mscnt = 100 / (mdiv * BIT(drefclk_div)); if (!mscnt) mscnt = 1; - hscnt = (mdiv * mscnt * BIT(drefclk_div) / arefclk_div) - 4; + hscnt = (mdiv * mscnt * BIT(drefclk_div) / refclk_div) - 4; + + mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_PLLGLOB, + hoff_ptr->per_pll_pllglob & + ~CLKMGR_PLLGLOB_RST_SET_MSK); + mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_FDBCK, + hoff_ptr->per_pll_fdbck); mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_VCOCALIB, CLKMGR_VCOCALIB_HSCNT_SET(hscnt) | CLKMGR_VCOCALIB_MSCNT_SET(mscnt)); - mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_EMACCTL, - hoff_ptr->per_pll_emacctl); - mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_GPIODIV, - CLKMGR_PERPLL_GPIODIV_GPIODBCLK_SET( - hoff_ptr->per_pll_gpiodiv)); - mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_PLLGLOB, - hoff_ptr->per_pll_pllglob); - mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_FDBCK, - hoff_ptr->per_pll_fdbck); mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_PLLC0, hoff_ptr->per_pll_pllc0); mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_PLLC1, @@ -187,6 +188,10 @@ void config_clkmgr_handoff(handoff *hoff_ptr) hoff_ptr->per_pll_pllc3); mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_PLLM, hoff_ptr->per_pll_pllm); + mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_EMACCTL, + hoff_ptr->per_pll_emacctl); + mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_GPIODIV, + hoff_ptr->per_pll_gpiodiv); /* Take both PLL out of reset and power up */ mmio_setbits_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLGLOB, @@ -196,13 +201,16 @@ void config_clkmgr_handoff(handoff *hoff_ptr) CLKMGR_PLLGLOB_PD_SET_MSK | CLKMGR_PLLGLOB_RST_SET_MSK); - wait_pll_lock(); + rdata = pll_source_sync_read(CLKMGR_MAINPLL + + CLKMGR_MAINPLL_MEM); + pll_source_sync_config(CLKMGR_MAINPLL + CLKMGR_MAINPLL_MEM, + rdata | 0x80); - pll_source_sync_config(CLKMGR_MAINPLL + CLKMGR_MAINPLL_MEM); - pll_source_sync_read(CLKMGR_MAINPLL + CLKMGR_MAINPLL_MEM); + rdata = pll_source_sync_read(CLKMGR_PERPLL + CLKMGR_PERPLL_MEM); + pll_source_sync_config(CLKMGR_PERPLL + CLKMGR_PERPLL_MEM, + rdata | 0x80); - pll_source_sync_config(CLKMGR_PERPLL + CLKMGR_PERPLL_MEM); - pll_source_sync_read(CLKMGR_PERPLL + CLKMGR_PERPLL_MEM); + wait_pll_lock(); /*Configure Ping Pong counters in altera group */ mmio_write_32(CLKMGR_ALTERA + CLKMGR_ALTERA_EMACACTR, @@ -241,7 +249,7 @@ void config_clkmgr_handoff(handoff *hoff_ptr) /* Clear loss lock interrupt status register that */ /* might be set during configuration */ - mmio_setbits_32(CLKMGR_OFFSET + CLKMGR_INTRCLR, + mmio_clrbits_32(CLKMGR_OFFSET + CLKMGR_INTRCLR, CLKMGR_INTRCLR_MAINLOCKLOST_SET_MSK | CLKMGR_INTRCLR_PERLOCKLOST_SET_MSK); -- cgit v1.2.3 From aea772dd7aa85681a9ead19cad4ead1732bbc003 Mon Sep 17 00:00:00 2001 From: Tien Hock Loh Date: Mon, 11 May 2020 01:11:39 -0700 Subject: plat: intel: set DRVSEL and SMPLSEL for DWMMC DRVSEL and SMPLSEL needs to be set so that it can properly go into full speed mode. This needs to be done in EL3 as the registers are secured. Signed-off-by: Tien Hock Loh Change-Id: Ia2f348e7742ff7b76da74d392ef1ce71e2f41677 --- plat/intel/soc/agilex/bl2_plat_setup.c | 2 ++ plat/intel/soc/agilex/include/agilex_clock_manager.h | 1 + plat/intel/soc/agilex/include/agilex_mmc.h | 7 +++++++ plat/intel/soc/agilex/platform.mk | 1 + plat/intel/soc/agilex/soc/agilex_mmc.c | 19 +++++++++++++++++++ .../intel/soc/common/include/socfpga_system_manager.h | 1 + 6 files changed, 31 insertions(+) create mode 100644 plat/intel/soc/agilex/include/agilex_mmc.h create mode 100644 plat/intel/soc/agilex/soc/agilex_mmc.c diff --git a/plat/intel/soc/agilex/bl2_plat_setup.c b/plat/intel/soc/agilex/bl2_plat_setup.c index a87dea8b3..f00294706 100644 --- a/plat/intel/soc/agilex/bl2_plat_setup.c +++ b/plat/intel/soc/agilex/bl2_plat_setup.c @@ -15,6 +15,7 @@ #include #include +#include "agilex_mmc.h" #include "agilex_clock_manager.h" #include "agilex_memory_controller.h" #include "agilex_pinmux.h" @@ -76,6 +77,7 @@ void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1, socfpga_emac_init(); init_hard_memory_controller(); mailbox_init(); + agx_mmc_init(); if (!intel_mailbox_is_fpga_not_ready()) socfpga_bridges_enable(); diff --git a/plat/intel/soc/agilex/include/agilex_clock_manager.h b/plat/intel/soc/agilex/include/agilex_clock_manager.h index 8af6a60bc..20667f014 100644 --- a/plat/intel/soc/agilex/include/agilex_clock_manager.h +++ b/plat/intel/soc/agilex/include/agilex_clock_manager.h @@ -89,6 +89,7 @@ /* Peripheral PLL Macros */ #define CLKMGR_PERPLL_EN_RESET 0x00000fff +#define CLKMGR_PERPLL_EN_SDMMCCLK BIT(5) #define CLKMGR_PERPLL_GPIODIV_GPIODBCLK_SET(x) (((x) << 0) & 0x0000ffff) /* Altera Macros */ diff --git a/plat/intel/soc/agilex/include/agilex_mmc.h b/plat/intel/soc/agilex/include/agilex_mmc.h new file mode 100644 index 000000000..00f4ca5a8 --- /dev/null +++ b/plat/intel/soc/agilex/include/agilex_mmc.h @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2020, Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +void agx_mmc_init(void); diff --git a/plat/intel/soc/agilex/platform.mk b/plat/intel/soc/agilex/platform.mk index 0a91c23dd..8f857d1e6 100644 --- a/plat/intel/soc/agilex/platform.mk +++ b/plat/intel/soc/agilex/platform.mk @@ -37,6 +37,7 @@ BL2_SOURCES += \ plat/intel/soc/agilex/bl2_plat_setup.c \ plat/intel/soc/agilex/soc/agilex_clock_manager.c \ plat/intel/soc/agilex/soc/agilex_memory_controller.c \ + plat/intel/soc/agilex/soc/agilex_mmc.c \ plat/intel/soc/agilex/soc/agilex_pinmux.c \ plat/intel/soc/common/bl2_plat_mem_params_desc.c \ plat/intel/soc/common/socfpga_delay_timer.c \ diff --git a/plat/intel/soc/agilex/soc/agilex_mmc.c b/plat/intel/soc/agilex/soc/agilex_mmc.c new file mode 100644 index 000000000..e05d92a03 --- /dev/null +++ b/plat/intel/soc/agilex/soc/agilex_mmc.c @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2020, Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include + +#include "socfpga_system_manager.h" +#include "agilex_clock_manager.h" + +void agx_mmc_init(void) +{ + mmio_clrbits_32(CLKMGR_PERPLL + CLKMGR_PERPLL_EN, + CLKMGR_PERPLL_EN_SDMMCCLK); + mmio_write_32(SOCFPGA_SYSMGR(SDMMC), + SYSMGR_SDMMC_SMPLSEL(0) | SYSMGR_SDMMC_DRVSEL(3)); + mmio_setbits_32(CLKMGR_PERPLL + CLKMGR_PERPLL_EN, + CLKMGR_PERPLL_EN_SDMMCCLK); +} diff --git a/plat/intel/soc/common/include/socfpga_system_manager.h b/plat/intel/soc/common/include/socfpga_system_manager.h index 76565bc93..93aa84655 100644 --- a/plat/intel/soc/common/include/socfpga_system_manager.h +++ b/plat/intel/soc/common/include/socfpga_system_manager.h @@ -32,6 +32,7 @@ /* Field Masking */ #define SYSMGR_SDMMC_DRVSEL(x) (((x) & 0x7) << 0) +#define SYSMGR_SDMMC_SMPLSEL(x) (((x) & 0x7) << 4) #define IDLE_DATA_LWSOC2FPGA BIT(0) #define IDLE_DATA_SOC2FPGA BIT(4) -- cgit v1.2.3 From e734ecd61de4245320e67802380ffd7bac67c1f3 Mon Sep 17 00:00:00 2001 From: Tien Hock Loh Date: Mon, 11 May 2020 01:11:48 -0700 Subject: plat: intel: Add FPGAINTF configuration to when configuring pinmux FPGAINTF wasn't enabled when configuring pinmux. This fixes the issue. Signed-off-by: Tien Hock Loh Change-Id: I5a6aacd504901b8f7327b2f4854b8a77d0c37019 --- plat/intel/soc/agilex/soc/agilex_pinmux.c | 8 ++++++++ plat/intel/soc/common/include/socfpga_system_manager.h | 2 ++ 2 files changed, 10 insertions(+) diff --git a/plat/intel/soc/agilex/soc/agilex_pinmux.c b/plat/intel/soc/agilex/soc/agilex_pinmux.c index eff19473c..0b908cfa3 100644 --- a/plat/intel/soc/agilex/soc/agilex_pinmux.c +++ b/plat/intel/soc/agilex/soc/agilex_pinmux.c @@ -7,6 +7,7 @@ #include #include "agilex_pinmux.h" +#include "socfpga_system_manager.h" const uint32_t sysmgr_pinmux_array_sel[] = { 0x00000000, 0x00000001, /* usb */ @@ -185,6 +186,12 @@ const uint32_t sysmgr_pinmux_array_iodelay[] = { 0x0000011c, 0x00000000 }; +void config_fpgaintf_mod(void) +{ + mmio_write_32(SOCFPGA_SYSMGR(FPGAINTF_EN_2), 1<<8); +} + + void config_pinmux(handoff *hoff_ptr) { unsigned int i; @@ -213,5 +220,6 @@ void config_pinmux(handoff *hoff_ptr) hoff_ptr->pinmux_iodelay_array[i+1]); } + config_fpgaintf_mod(); } diff --git a/plat/intel/soc/common/include/socfpga_system_manager.h b/plat/intel/soc/common/include/socfpga_system_manager.h index 93aa84655..8b42d47af 100644 --- a/plat/intel/soc/common/include/socfpga_system_manager.h +++ b/plat/intel/soc/common/include/socfpga_system_manager.h @@ -13,6 +13,8 @@ #define SOCFPGA_SYSMGR_SDMMC 0x28 +#define SOCFPGA_SYSMGR_FPGAINTF_EN_2 0x6c + #define SOCFPGA_SYSMGR_EMAC_0 0x44 #define SOCFPGA_SYSMGR_EMAC_1 0x48 #define SOCFPGA_SYSMGR_EMAC_2 0x4c -- cgit v1.2.3 From 8109f738ffa79a63735cba29da26e7c2859977b5 Mon Sep 17 00:00:00 2001 From: Hugh Cole-Baker Date: Mon, 8 Jun 2020 22:24:36 +0100 Subject: rockchip: increase FDT buffer size The size of buffer currently used to store the FDT passed from U-Boot as a platform parameter is not large enough to store some RK3399 device trees. The largest RK3399 device tree currently in U-Boot (for the Pinebook Pro) is about 70KB in size when passed to TF-A, so increase the buffer size to 128K which gives some headroom for possibly larger FDTs in future. Signed-off-by: Hugh Cole-Baker Change-Id: I414caf20683cd47c02ee470dfa988544f3809919 --- plat/rockchip/common/params_setup.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plat/rockchip/common/params_setup.c b/plat/rockchip/common/params_setup.c index b2fd2011e..2ff81eda7 100644 --- a/plat/rockchip/common/params_setup.c +++ b/plat/rockchip/common/params_setup.c @@ -37,7 +37,8 @@ static int dt_process_fdt(u_register_t param_from_bl2) static uint32_t rk_uart_base = PLAT_RK_UART_BASE; static uint32_t rk_uart_baudrate = PLAT_RK_UART_BAUDRATE; static uint32_t rk_uart_clock = PLAT_RK_UART_CLOCK; -static uint8_t fdt_buffer[0x10000]; +#define FDT_BUFFER_SIZE 0x20000 +static uint8_t fdt_buffer[FDT_BUFFER_SIZE]; void *plat_get_fdt(void) { @@ -136,7 +137,7 @@ static int dt_process_fdt(u_register_t param_from_bl2) void *fdt = plat_get_fdt(); int ret; - ret = fdt_open_into((void *)param_from_bl2, fdt, 0x10000); + ret = fdt_open_into((void *)param_from_bl2, fdt, FDT_BUFFER_SIZE); if (ret < 0) return ret; -- cgit v1.2.3 From 27cd1a4762c50eb461f74c7c43eee17b7bdde024 Mon Sep 17 00:00:00 2001 From: Tien Hock Loh Date: Mon, 11 May 2020 01:11:55 -0700 Subject: plat: intel: Fix CCU initialization for Agilex The CCU initialization loop uses the wrong units, this fixes that. This also fixes snoop filter register set bits should be used instead of overwriting the register Signed-off-by: Tien Hock Loh Change-Id: Ia15eeeae5569b00ad84120182170d353ee221b31 --- plat/intel/soc/common/drivers/ccu/ncore_ccu.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/plat/intel/soc/common/drivers/ccu/ncore_ccu.c b/plat/intel/soc/common/drivers/ccu/ncore_ccu.c index fce816b65..b4fce7b40 100644 --- a/plat/intel/soc/common/drivers/ccu/ncore_ccu.c +++ b/plat/intel/soc/common/drivers/ccu/ncore_ccu.c @@ -35,14 +35,12 @@ uint32_t directory_init(void) uint32_t dir, sf, ret; for (dir = 0; dir < subsystem_id.num_directory; dir++) { - - dir_sf_mtn = DIRECTORY_UNIT(dir, NCORE_DIRUSFMCR); - dir_sf_en = DIRECTORY_UNIT(dir, NCORE_DIRUSFER); - for (sf = 0; sf < subsystem_id.num_snoop_filter; sf++) { + dir_sf_mtn = DIRECTORY_UNIT(dir, NCORE_DIRUSFMCR); + dir_sf_en = DIRECTORY_UNIT(dir, NCORE_DIRUSFER); /* Initialize All Entries */ - mmio_write_32(dir_sf_mtn, SNOOP_FILTER_ID(sf)); + mmio_write_32(dir_sf_mtn, SNOOP_FILTER_ID(dir)); /* Poll Active Bit */ ret = poll_active_bit(dir); @@ -52,7 +50,7 @@ uint32_t directory_init(void) } /* Snoope Filter Enable */ - mmio_write_32(dir_sf_en, BIT(sf)); + mmio_setbits_32(dir_sf_en, BIT(sf)); } } @@ -64,11 +62,8 @@ uint32_t coherent_agent_intfc_init(void) uint32_t dir, ca, ca_id, ca_type, ca_snoop_en; for (dir = 0; dir < subsystem_id.num_directory; dir++) { - - ca_snoop_en = DIRECTORY_UNIT(dir, NCORE_DIRUCASER0); - for (ca = 0; ca < subsystem_id.num_coh_agent; ca++) { - + ca_snoop_en = DIRECTORY_UNIT(ca, NCORE_DIRUCASER0); ca_id = mmio_read_32(COH_AGENT_UNIT(ca, NCORE_CAIUIDR)); /* Coh Agent Snoop Enable */ -- cgit v1.2.3 From 811af8b768e3535899b642e0ee1f375dc8f0d417 Mon Sep 17 00:00:00 2001 From: Tien Hock Loh Date: Mon, 11 May 2020 01:12:03 -0700 Subject: plat: intel: Additional instruction required to enable global timer There are additional instruction needed to enable the global timer. This fixes the global timer initialization Signed-off-by: Tien Hock Loh Change-Id: Idaf2d23359aacc417e2b7d8cdf1688b5cd17ca98 --- plat/intel/soc/common/socfpga_delay_timer.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plat/intel/soc/common/socfpga_delay_timer.c b/plat/intel/soc/common/socfpga_delay_timer.c index ff8a556cf..c55cc9da6 100644 --- a/plat/intel/soc/common/socfpga_delay_timer.c +++ b/plat/intel/soc/common/socfpga_delay_timer.c @@ -36,4 +36,8 @@ void socfpga_delay_timer_init(void) { timer_init(&plat_timer_ops); mmio_write_32(SOCFPGA_GLOBAL_TIMER, SOCFPGA_GLOBAL_TIMER_EN); + + asm volatile("msr cntp_ctl_el0, %0" : : "r" (SOCFPGA_GLOBAL_TIMER_EN)); + asm volatile("msr cntp_tval_el0, %0" : : "r" (~0)); + } -- cgit v1.2.3 From 44f1aa8efe627e578c38fbc0623b083223109342 Mon Sep 17 00:00:00 2001 From: Manish Pandey Date: Wed, 27 May 2020 22:40:10 +0100 Subject: dualroot: add chain of trust for secure partitions A new certificate "sip-sp-cert" has been added for Silicon Provider(SiP) owned Secure Partitions(SP). A similar support for Platform owned SP can be added in future. The certificate is also protected against anti- rollback using the trusted Non-Volatile counter. To avoid deviating from TBBR spec, support for SP CoT is only provided in dualroot. Secure Partition content certificate is assigned image ID 31 and SP images follows after it. The CoT for secure partition look like below. +------------------+ +-------------------+ | ROTPK/ROTPK Hash |------>| Trusted Key | +------------------+ | Certificate | | (Auth Image) | /+-------------------+ / | / | / | / | L v +------------------+ +-------------------+ | Trusted World |------>| SiP owned SPs | | Public Key | | Content Cert | +------------------+ | (Auth Image) | / +-------------------+ / | / v| +------------------+ L +-------------------+ | SP_PKG1 Hash |------>| SP_PKG1 | | | | (Data Image) | +------------------+ +-------------------+ . . . . . . +------------------+ +-------------------+ | SP_PKG8 Hash |------>| SP_PKG8 | | | | (Data Image) | +------------------+ +-------------------+ Signed-off-by: Manish Pandey Change-Id: Ia31546bac1327a3e0b5d37e8b99c808442d5e53f --- drivers/auth/dualroot/cot.c | 128 ++++++++++++++++++++++++++ include/common/tbbr/cot_def.h | 5 +- include/common/tbbr/tbbr_img_def.h | 8 ++ include/drivers/auth/auth_mod.h | 18 ++++ include/export/common/tbbr/tbbr_img_def_exp.h | 9 +- plat/arm/board/fvp/fdts/fvp_fw_config.dts | 1 + plat/arm/common/fconf/arm_fconf_io.c | 15 ++- plat/arm/common/fconf/arm_fconf_sp.c | 2 +- 8 files changed, 176 insertions(+), 10 deletions(-) diff --git a/drivers/auth/dualroot/cot.c b/drivers/auth/dualroot/cot.c index 8aca2be6d..f28ddaa91 100644 --- a/drivers/auth/dualroot/cot.c +++ b/drivers/auth/dualroot/cot.c @@ -30,6 +30,9 @@ static unsigned char tos_fw_extra2_hash_buf[HASH_DER_LEN]; static unsigned char soc_fw_config_hash_buf[HASH_DER_LEN]; static unsigned char tos_fw_config_hash_buf[HASH_DER_LEN]; static unsigned char nt_fw_config_hash_buf[HASH_DER_LEN]; +#if defined(SPD_spmd) +static unsigned char sp_pkg_hash_buf[MAX_SP_IDS][HASH_DER_LEN]; +#endif /* SPD_spmd */ static unsigned char trusted_world_pk_buf[PK_DER_LEN]; static unsigned char content_pk_buf[PK_DER_LEN]; @@ -97,6 +100,24 @@ 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); +#if defined(SPD_spmd) +static auth_param_type_desc_t sp_pkg1_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG1_HASH_OID); +static auth_param_type_desc_t sp_pkg2_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG2_HASH_OID); +static auth_param_type_desc_t sp_pkg3_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG3_HASH_OID); +static auth_param_type_desc_t sp_pkg4_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG4_HASH_OID); +static auth_param_type_desc_t sp_pkg5_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG5_HASH_OID); +static auth_param_type_desc_t sp_pkg6_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG6_HASH_OID); +static auth_param_type_desc_t sp_pkg7_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG7_HASH_OID); +static auth_param_type_desc_t sp_pkg8_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG8_HASH_OID); +#endif /* SPD_spmd */ #endif /* IMAGE_BL2 */ @@ -642,6 +663,102 @@ static const auth_img_desc_t nt_fw_config = { } }; +/* + * Secure Partitions + */ +#if defined(SPD_spmd) +static const auth_img_desc_t sp_content_cert = { + .img_id = SP_CONTENT_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 = &trusted_world_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 = &sp_pkg1_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[0], + .len = (unsigned int)HASH_DER_LEN + } + }, + [1] = { + .type_desc = &sp_pkg2_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[1], + .len = (unsigned int)HASH_DER_LEN + } + }, + [2] = { + .type_desc = &sp_pkg3_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[2], + .len = (unsigned int)HASH_DER_LEN + } + }, + [3] = { + .type_desc = &sp_pkg4_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[3], + .len = (unsigned int)HASH_DER_LEN + } + }, + [4] = { + .type_desc = &sp_pkg5_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[4], + .len = (unsigned int)HASH_DER_LEN + } + }, + [5] = { + .type_desc = &sp_pkg6_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[5], + .len = (unsigned int)HASH_DER_LEN + } + }, + [6] = { + .type_desc = &sp_pkg7_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[6], + .len = (unsigned int)HASH_DER_LEN + } + }, + [7] = { + .type_desc = &sp_pkg8_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[7], + .len = (unsigned int)HASH_DER_LEN + } + } + } +}; + +DEFINE_SP_PKG(1); +DEFINE_SP_PKG(2); +DEFINE_SP_PKG(3); +DEFINE_SP_PKG(4); +DEFINE_SP_PKG(5); +DEFINE_SP_PKG(6); +DEFINE_SP_PKG(7); +DEFINE_SP_PKG(8); +#endif /* SPD_spmd */ + #else /* IMAGE_BL2 */ /* FWU auth descriptor */ @@ -769,6 +886,17 @@ static const auth_img_desc_t * const cot_desc[] = { [NON_TRUSTED_FW_CONTENT_CERT_ID] = &non_trusted_fw_content_cert, [BL33_IMAGE_ID] = &bl33_image, [NT_FW_CONFIG_ID] = &nt_fw_config, +#if defined(SPD_spmd) + [SP_CONTENT_CERT_ID] = &sp_content_cert, + [SP_CONTENT_CERT_ID + 1] = &sp_pkg1, + [SP_CONTENT_CERT_ID + 2] = &sp_pkg2, + [SP_CONTENT_CERT_ID + 3] = &sp_pkg3, + [SP_CONTENT_CERT_ID + 4] = &sp_pkg4, + [SP_CONTENT_CERT_ID + 5] = &sp_pkg5, + [SP_CONTENT_CERT_ID + 6] = &sp_pkg6, + [SP_CONTENT_CERT_ID + 7] = &sp_pkg7, + [SP_CONTENT_CERT_ID + 8] = &sp_pkg8, +#endif }; #endif diff --git a/include/common/tbbr/cot_def.h b/include/common/tbbr/cot_def.h index c41114692..6ce7f80c1 100644 --- a/include/common/tbbr/cot_def.h +++ b/include/common/tbbr/cot_def.h @@ -8,8 +8,11 @@ #define COT_DEF_H /* TBBR CoT definitions */ - +#if defined(SPD_spmd) +#define COT_MAX_VERIFIED_PARAMS 8 +#else #define COT_MAX_VERIFIED_PARAMS 4 +#endif /* * Maximum key and hash sizes (in DER format). diff --git a/include/common/tbbr/tbbr_img_def.h b/include/common/tbbr/tbbr_img_def.h index 1701995a7..1f9aab127 100644 --- a/include/common/tbbr/tbbr_img_def.h +++ b/include/common/tbbr/tbbr_img_def.h @@ -9,4 +9,12 @@ #include +#if defined(SPD_spmd) +#define SP_CONTENT_CERT_ID MAX_IMAGE_IDS +#define MAX_SP_IDS U(8) +#define MAX_NUMBER_IDS (MAX_IMAGE_IDS + MAX_SP_IDS + U(1)) +#else +#define MAX_NUMBER_IDS MAX_IMAGE_IDS +#endif + #endif /* TBBR_IMG_DEF_H */ diff --git a/include/drivers/auth/auth_mod.h b/include/drivers/auth/auth_mod.h index 1dc9ff441..01d144d2c 100644 --- a/include/drivers/auth/auth_mod.h +++ b/include/drivers/auth/auth_mod.h @@ -50,6 +50,24 @@ extern const auth_img_desc_t *const *const cot_desc_ptr; extern const size_t cot_desc_size; extern unsigned int auth_img_flags[MAX_NUMBER_IDS]; +#if defined(SPD_spmd) +#define DEFINE_SP_PKG(n) \ + static const auth_img_desc_t sp_pkg##n = { \ + .img_id = SP_CONTENT_CERT_ID + (n), \ + .img_type = IMG_RAW, \ + .parent = &sp_content_cert, \ + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { \ + [0] = { \ + .type = AUTH_METHOD_HASH, \ + .param.hash = { \ + .data = &raw_data, \ + .hash = &sp_pkg##n##_hash \ + } \ + } \ + } \ + } +#endif + #endif /* TRUSTED_BOARD_BOOT */ #endif /* AUTH_MOD_H */ diff --git a/include/export/common/tbbr/tbbr_img_def_exp.h b/include/export/common/tbbr/tbbr_img_def_exp.h index 89dbc58fe..a98c1b4f6 100644 --- a/include/export/common/tbbr/tbbr_img_def_exp.h +++ b/include/export/common/tbbr/tbbr_img_def_exp.h @@ -88,12 +88,7 @@ /* Encrypted image identifier */ #define ENC_IMAGE_ID U(30) -/* Define size of the array */ -#if defined(SPD_spmd) -#define MAX_SP_IDS U(8) -#define MAX_NUMBER_IDS MAX_SP_IDS + U(31) -#else -#define MAX_NUMBER_IDS U(31) -#endif +/* Max Images */ +#define MAX_IMAGE_IDS U(31) #endif /* ARM_TRUSTED_FIRMWARE_EXPORT_COMMON_TBBR_TBBR_IMG_DEF_EXP_H */ diff --git a/plat/arm/board/fvp/fdts/fvp_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_fw_config.dts index 7c111085d..5bd0edbf9 100644 --- a/plat/arm/board/fvp/fdts/fvp_fw_config.dts +++ b/plat/arm/board/fvp/fdts/fvp_fw_config.dts @@ -111,6 +111,7 @@ soc_fw_content_cert_uuid = <0x200cb2e2 0x11e4635e 0xccabe89c 0x66b62bf9>; tos_fw_content_cert_uuid = <0x11449fa4 0x11e4635e 0x53f2887 0x3df32a72>; nt_fw_content_cert_uuid = <0xf3c1c48e 0x11e4635d 0xee87a9a7 0xa73fb240>; + sp_content_cert_uuid = <0x44fd6d77 0x3b4c9786 0x3ec1eb91 0x6f2a5a02>; }; }; #endif /* ARM_IO_IN_DTB */ diff --git a/plat/arm/common/fconf/arm_fconf_io.c b/plat/arm/common/fconf/arm_fconf_io.c index 26e51b2a3..68cd9fb37 100644 --- a/plat/arm/common/fconf/arm_fconf_io.c +++ b/plat/arm/common/fconf/arm_fconf_io.c @@ -49,6 +49,9 @@ const io_uuid_spec_t arm_uuid_spec[MAX_NUMBER_IDS] = { [SOC_FW_CONTENT_CERT_ID] = {UUID_SOC_FW_CONTENT_CERT}, [TRUSTED_OS_FW_CONTENT_CERT_ID] = {UUID_TRUSTED_OS_FW_CONTENT_CERT}, [NON_TRUSTED_FW_CONTENT_CERT_ID] = {UUID_NON_TRUSTED_FW_CONTENT_CERT}, +#if defined(SPD_spmd) + [SP_CONTENT_CERT_ID] = {UUID_SIP_SECURE_PARTITION_CONTENT_CERT}, +#endif #endif /* ARM_IO_IN_DTB */ #endif /* TRUSTED_BOARD_BOOT */ }; @@ -174,6 +177,13 @@ struct plat_io_policy policies[MAX_NUMBER_IDS] = { (uintptr_t)&arm_uuid_spec[NON_TRUSTED_FW_CONTENT_CERT_ID], open_fip }, +#if defined(SPD_spmd) + [SP_CONTENT_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[SP_CONTENT_CERT_ID], + open_fip + }, +#endif #endif /* ARM_IO_IN_DTB */ #endif /* TRUSTED_BOARD_BOOT */ }; @@ -181,7 +191,7 @@ struct plat_io_policy policies[MAX_NUMBER_IDS] = { #ifdef IMAGE_BL2 #if TRUSTED_BOARD_BOOT -#define FCONF_ARM_IO_UUID_NUMBER U(19) +#define FCONF_ARM_IO_UUID_NUMBER U(20) #else #define FCONF_ARM_IO_UUID_NUMBER U(10) #endif @@ -216,6 +226,9 @@ static const struct policies_load_info load_info[FCONF_ARM_IO_UUID_NUMBER] = { {SOC_FW_CONTENT_CERT_ID, "soc_fw_content_cert_uuid"}, {TRUSTED_OS_FW_CONTENT_CERT_ID, "tos_fw_content_cert_uuid"}, {NON_TRUSTED_FW_CONTENT_CERT_ID, "nt_fw_content_cert_uuid"}, +#if defined(SPD_spmd) + {SP_CONTENT_CERT_ID, "sp_content_cert_uuid"}, +#endif #endif /* TRUSTED_BOARD_BOOT */ }; diff --git a/plat/arm/common/fconf/arm_fconf_sp.c b/plat/arm/common/fconf/arm_fconf_sp.c index 1b09bc8e5..64e873e7a 100644 --- a/plat/arm/common/fconf/arm_fconf_sp.c +++ b/plat/arm/common/fconf/arm_fconf_sp.c @@ -30,7 +30,7 @@ int fconf_populate_arm_sp(uintptr_t config) union uuid_helper_t uuid_helper; unsigned int index = 0; uint32_t val32; - const unsigned int sp_start_index = MAX_NUMBER_IDS - MAX_SP_IDS; + const unsigned int sp_start_index = SP_CONTENT_CERT_ID + 1; /* As libfdt use void *, we can't avoid this cast */ const void *dtb = (void *)config; -- cgit v1.2.3 From b4ad365a4642fb8b2ecb1df73dd69ee4caf58bd2 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Wed, 25 Mar 2020 15:50:38 +0000 Subject: GICv3: GIC-600: Detect GIC-600 at runtime The only difference between GIC-500 and GIC-600 relevant to TF-A is the differing power management sequence. A certain GIC implementation is detectable at runtime, for instance by checking the IIDR register. Let's add that test before initiating the GIC-600 specific sequence, so the code can be used on both GIC-600 and GIC-500 chips alike, without deciding on a GIC chip at compile time. This means that the GIC-500 "driver" is now redundant. To allow minimal platform support, add a switch to disable GIC-600 support. Change-Id: I17ea97d9fb05874772ebaa13e6678b4ba3415557 Signed-off-by: Andre Przywara --- docs/getting_started/build-options.rst | 6 +- docs/plat/arm/fvp/index.rst | 1 - drivers/arm/gic/v3/gic-x00.c | 162 +++++++++++++++++++++++++++++++++ drivers/arm/gic/v3/gic500.c | 22 ----- drivers/arm/gic/v3/gic600.c | 140 ---------------------------- drivers/arm/gic/v3/gicv3.mk | 17 ++-- include/drivers/arm/gicv3.h | 8 ++ plat/arm/board/arm_fpga/platform.mk | 4 +- plat/arm/board/fvp/platform.mk | 9 +- plat/arm/board/n1sdp/platform.mk | 2 +- plat/arm/board/tc0/platform.mk | 3 +- plat/arm/css/sgi/sgi-common.mk | 2 +- plat/arm/css/sgm/sgm-common.mk | 2 +- 13 files changed, 190 insertions(+), 188 deletions(-) create mode 100644 drivers/arm/gic/v3/gic-x00.c delete mode 100644 drivers/arm/gic/v3/gic500.c delete mode 100644 drivers/arm/gic/v3/gic600.c diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index c86307948..19b565384 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -711,8 +711,10 @@ GICv3 driver files are included using directive: The driver can be configured with the following options set in the platform makefile: -- ``GICV3_IMPL``: Selects between GIC-500 and GIC-600 variants of GICv3. - This option can take values GIC500 and GIC600 with default set to GIC500. +- ``GICV3_SUPPORT_GIC600``: Add support for the GIC-600 variants of GICv3. + Enabling this option will add runtime detection support for the + GIC-600, so is safe to select even for a GIC500 implementation. + This option defaults to 0. - ``GICV3_IMPL_GIC600_MULTICHIP``: Selects GIC-600 variant with multichip functionality. This option defaults to 0 diff --git a/docs/plat/arm/fvp/index.rst b/docs/plat/arm/fvp/index.rst index eb7eb0054..f23ec2804 100644 --- a/docs/plat/arm/fvp/index.rst +++ b/docs/plat/arm/fvp/index.rst @@ -116,7 +116,6 @@ Arm FVP Platform Specific Build Options - ``FVP_USE_GIC_DRIVER`` : Selects the GIC driver to be built. Options: - - ``FVP_GIC600`` : The GIC600 implementation of GICv3 is selected - ``FVP_GICV2`` : The GICv2 only driver is selected - ``FVP_GICV3`` : The GICv3 only driver is selected (default option) diff --git a/drivers/arm/gic/v3/gic-x00.c b/drivers/arm/gic/v3/gic-x00.c new file mode 100644 index 000000000..c1a9f0dc1 --- /dev/null +++ b/drivers/arm/gic/v3/gic-x00.c @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * Driver for GIC-500 and GIC-600 specific features. This driver only + * overrides APIs that are different to those generic ones in GICv3 + * driver. + * + * GIC-600 supports independently power-gating redistributor interface. + */ + +#include + +#include +#include + +#include "gicv3_private.h" + +/* GIC-600 specific register offsets */ +#define GICR_PWRR 0x24 +#define IIDR_MODEL_ARM_GIC_600 0x0200043b + +/* GICR_PWRR fields */ +#define PWRR_RDPD_SHIFT 0 +#define PWRR_RDAG_SHIFT 1 +#define PWRR_RDGPD_SHIFT 2 +#define PWRR_RDGPO_SHIFT 3 + +#define PWRR_RDPD (1 << PWRR_RDPD_SHIFT) +#define PWRR_RDAG (1 << PWRR_RDAG_SHIFT) +#define PWRR_RDGPD (1 << PWRR_RDGPD_SHIFT) +#define PWRR_RDGPO (1 << PWRR_RDGPO_SHIFT) + +/* + * Values to write to GICR_PWRR register to power redistributor + * for operating through the core (GICR_PWRR.RDAG = 0) + */ +#define PWRR_ON (0 << PWRR_RDPD_SHIFT) +#define PWRR_OFF (1 << PWRR_RDPD_SHIFT) + +#if GICV3_SUPPORT_GIC600 + +/* GIC-600 specific accessor functions */ +static void gicr_write_pwrr(uintptr_t base, unsigned int val) +{ + mmio_write_32(base + GICR_PWRR, val); +} + +static uint32_t gicr_read_pwrr(uintptr_t base) +{ + return mmio_read_32(base + GICR_PWRR); +} + +static void gicr_wait_group_not_in_transit(uintptr_t base) +{ + /* Check group not transitioning: RDGPD == RDGPO */ + while (((gicr_read_pwrr(base) & PWRR_RDGPD) >> PWRR_RDGPD_SHIFT) != + ((gicr_read_pwrr(base) & PWRR_RDGPO) >> PWRR_RDGPO_SHIFT)) + ; +} + +static void gic600_pwr_on(uintptr_t base) +{ + do { /* Wait until group not transitioning */ + gicr_wait_group_not_in_transit(base); + + /* Power on redistributor */ + gicr_write_pwrr(base, PWRR_ON); + + /* + * Wait until the power on state is reflected. + * If RDPD == 0 then powered on. + */ + } while ((gicr_read_pwrr(base) & PWRR_RDPD) != PWRR_ON); +} + +static void gic600_pwr_off(uintptr_t base) +{ + /* Wait until group not transitioning */ + gicr_wait_group_not_in_transit(base); + + /* Power off redistributor */ + gicr_write_pwrr(base, PWRR_OFF); + + /* + * If this is the last man, turning this redistributor frame off will + * result in the group itself being powered off and RDGPD = 1. + * In that case, wait as long as it's in transition, or has aborted + * the transition altogether for any reason. + */ + if ((gicr_read_pwrr(base) & PWRR_RDGPD) != 0) { + /* Wait until group not transitioning */ + gicr_wait_group_not_in_transit(base); + } +} + +static uintptr_t get_gicr_base(unsigned int proc_num) +{ + uintptr_t gicr_base; + + assert(gicv3_driver_data); + assert(proc_num < gicv3_driver_data->rdistif_num); + assert(gicv3_driver_data->rdistif_base_addrs); + + gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; + assert(gicr_base); + + return gicr_base; +} + +static bool gicv3_is_gic600(uintptr_t gicr_base) +{ + uint32_t reg = mmio_read_32(gicr_base + GICR_IIDR); + + return (reg & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_600; +} + +#endif + +void gicv3_distif_pre_save(unsigned int proc_num) +{ + arm_gicv3_distif_pre_save(proc_num); +} + +void gicv3_distif_post_restore(unsigned int proc_num) +{ + arm_gicv3_distif_post_restore(proc_num); +} + + +/* + * Power off GIC-600 redistributor (if configured and detected) + */ +void gicv3_rdistif_off(unsigned int proc_num) +{ +#if GICV3_SUPPORT_GIC600 + uintptr_t gicr_base = get_gicr_base(proc_num); + + /* Attempt to power redistributor off */ + if (gicv3_is_gic600(gicr_base)) { + gic600_pwr_off(gicr_base); + } +#endif +} + +/* + * Power on GIC-600 redistributor (if configured and detected) + */ +void gicv3_rdistif_on(unsigned int proc_num) +{ +#if GICV3_SUPPORT_GIC600 + uintptr_t gicr_base = get_gicr_base(proc_num); + + /* Power redistributor on */ + if (gicv3_is_gic600(gicr_base)) { + gic600_pwr_on(gicr_base); + } +#endif +} diff --git a/drivers/arm/gic/v3/gic500.c b/drivers/arm/gic/v3/gic500.c deleted file mode 100644 index f03e33f86..000000000 --- a/drivers/arm/gic/v3/gic500.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * Driver for GIC500-specific features. This driver only overrides APIs that are - * different to those generic ones in GICv3 driver. - */ -#include "gicv3_private.h" - -void gicv3_distif_pre_save(unsigned int proc_num) -{ - arm_gicv3_distif_pre_save(proc_num); -} - -void gicv3_distif_post_restore(unsigned int proc_num) -{ - arm_gicv3_distif_post_restore(proc_num); -} - diff --git a/drivers/arm/gic/v3/gic600.c b/drivers/arm/gic/v3/gic600.c deleted file mode 100644 index 59652da63..000000000 --- a/drivers/arm/gic/v3/gic600.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * Driver for GIC-600 specific features. This driver only overrides - * APIs that are different to those generic ones in GICv3 driver. - * - * GIC-600 supports independently power-gating redistributor interface. - */ - -#include - -#include -#include - -#include "gicv3_private.h" - -/* GIC-600 specific register offsets */ -#define GICR_PWRR 0x24 - -/* GICR_PWRR fields */ -#define PWRR_RDPD_SHIFT 0 -#define PWRR_RDAG_SHIFT 1 -#define PWRR_RDGPD_SHIFT 2 -#define PWRR_RDGPO_SHIFT 3 - -#define PWRR_RDPD (1 << PWRR_RDPD_SHIFT) -#define PWRR_RDAG (1 << PWRR_RDAG_SHIFT) -#define PWRR_RDGPD (1 << PWRR_RDGPD_SHIFT) -#define PWRR_RDGPO (1 << PWRR_RDGPO_SHIFT) - -/* - * Values to write to GICR_PWRR register to power redistributor - * for operating through the core (GICR_PWRR.RDAG = 0) - */ -#define PWRR_ON (0 << PWRR_RDPD_SHIFT) -#define PWRR_OFF (1 << PWRR_RDPD_SHIFT) - -/* GIC-600 specific accessor functions */ -static void gicr_write_pwrr(uintptr_t base, unsigned int val) -{ - mmio_write_32(base + GICR_PWRR, val); -} - -static uint32_t gicr_read_pwrr(uintptr_t base) -{ - return mmio_read_32(base + GICR_PWRR); -} - -static void gicr_wait_group_not_in_transit(uintptr_t base) -{ - /* Check group not transitioning: RDGPD == RDGPO */ - while (((gicr_read_pwrr(base) & PWRR_RDGPD) >> PWRR_RDGPD_SHIFT) != - ((gicr_read_pwrr(base) & PWRR_RDGPO) >> PWRR_RDGPO_SHIFT)) - ; -} - -static void gic600_pwr_on(uintptr_t base) -{ - do { /* Wait until group not transitioning */ - gicr_wait_group_not_in_transit(base); - - /* Power on redistributor */ - gicr_write_pwrr(base, PWRR_ON); - - /* - * Wait until the power on state is reflected. - * If RDPD == 0 then powered on. - */ - } while ((gicr_read_pwrr(base) & PWRR_RDPD) != PWRR_ON); -} - -static void gic600_pwr_off(uintptr_t base) -{ - /* Wait until group not transitioning */ - gicr_wait_group_not_in_transit(base); - - /* Power off redistributor */ - gicr_write_pwrr(base, PWRR_OFF); - - /* - * If this is the last man, turning this redistributor frame off will - * result in the group itself being powered off and RDGPD = 1. - * In that case, wait as long as it's in transition, or has aborted - * the transition altogether for any reason. - */ - if ((gicr_read_pwrr(base) & PWRR_RDGPD) != 0) { - /* Wait until group not transitioning */ - gicr_wait_group_not_in_transit(base); - } -} - -void gicv3_distif_pre_save(unsigned int proc_num) -{ - arm_gicv3_distif_pre_save(proc_num); -} - -void gicv3_distif_post_restore(unsigned int proc_num) -{ - arm_gicv3_distif_post_restore(proc_num); -} - -/* - * Power off GIC-600 redistributor - */ -void gicv3_rdistif_off(unsigned int proc_num) -{ - uintptr_t gicr_base; - - assert(gicv3_driver_data); - assert(proc_num < gicv3_driver_data->rdistif_num); - assert(gicv3_driver_data->rdistif_base_addrs); - - gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; - assert(gicr_base); - - /* Attempt to power redistributor off */ - gic600_pwr_off(gicr_base); -} - -/* - * Power on GIC-600 redistributor - */ -void gicv3_rdistif_on(unsigned int proc_num) -{ - uintptr_t gicr_base; - - assert(gicv3_driver_data); - assert(proc_num < gicv3_driver_data->rdistif_num); - assert(gicv3_driver_data->rdistif_base_addrs); - - gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; - assert(gicr_base); - - /* Power redistributor on */ - gic600_pwr_on(gicr_base); -} diff --git a/drivers/arm/gic/v3/gicv3.mk b/drivers/arm/gic/v3/gicv3.mk index 0f401035d..a2fc16f9c 100644 --- a/drivers/arm/gic/v3/gicv3.mk +++ b/drivers/arm/gic/v3/gicv3.mk @@ -5,7 +5,7 @@ # # Default configuration values -GICV3_IMPL ?= GIC500 +GICV3_SUPPORT_GIC600 ?= 0 GICV3_IMPL_GIC600_MULTICHIP ?= 0 GICV3_OVERRIDE_DISTIF_PWR_OPS ?= 0 GIC_ENABLE_V4_EXTN ?= 0 @@ -20,19 +20,14 @@ ifeq (${GICV3_OVERRIDE_DISTIF_PWR_OPS}, 0) GICV3_SOURCES += drivers/arm/gic/v3/arm_gicv3_common.c endif -# Either GIC-600 or GIC-500 can be selected at one time -ifeq (${GICV3_IMPL}, GIC600) -# GIC-600 sources -GICV3_SOURCES += drivers/arm/gic/v3/gic600.c +GICV3_SOURCES += drivers/arm/gic/v3/gic-x00.c ifeq (${GICV3_IMPL_GIC600_MULTICHIP}, 1) GICV3_SOURCES += drivers/arm/gic/v3/gic600_multichip.c endif -else ifeq (${GICV3_IMPL}, GIC500) -# GIC-500 sources -GICV3_SOURCES += drivers/arm/gic/v3/gic500.c -else -$(error "Incorrect GICV3_IMPL value ${GICV3_IMPL}") -endif + +# Set GIC-600 support +$(eval $(call assert_boolean,GICV3_SUPPORT_GIC600)) +$(eval $(call add_define,GICV3_SUPPORT_GIC600)) # Set GICv4 extension $(eval $(call assert_boolean,GIC_ENABLE_V4_EXTN)) diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h index 03596b96e..77dc350dd 100644 --- a/include/drivers/arm/gicv3.h +++ b/include/drivers/arm/gicv3.h @@ -222,6 +222,14 @@ #define TYPER_PPI_NUM_SHIFT U(27) #define TYPER_PPI_NUM_MASK U(0x1f) +/* GICR_IIDR bit definitions */ +#define IIDR_PRODUCT_ID_MASK 0xff000000 +#define IIDR_VARIANT_MASK 0x000f0000 +#define IIDR_REVISION_MASK 0x0000f000 +#define IIDR_IMPLEMENTER_MASK 0x00000fff +#define IIDR_MODEL_MASK (IIDR_PRODUCT_ID_MASK | \ + IIDR_IMPLEMENTER_MASK) + /******************************************************************************* * GICv3 and 3.1 CPU interface registers & constants ******************************************************************************/ diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk index 7039a6d04..34e50ea13 100644 --- a/plat/arm/board/arm_fpga/platform.mk +++ b/plat/arm/board/arm_fpga/platform.mk @@ -70,8 +70,8 @@ else lib/cpus/aarch64/cortex_a75.S endif -# GIC-600 configuration -GICV3_IMPL := GIC600 +# Allow detection of GIC-600 +GICV3_SUPPORT_GIC600 := 1 # Include GICv3 driver files include drivers/arm/gic/v3/gicv3.mk diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 024e682bc..528948a98 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -49,13 +49,10 @@ endif $(eval $(call add_define,FVP_INTERCONNECT_DRIVER)) # Choose the GIC sources depending upon the how the FVP will be invoked -ifeq (${FVP_USE_GIC_DRIVER},$(filter ${FVP_USE_GIC_DRIVER},FVP_GICV3 FVP_GIC600)) - - # GIC500 is the default option in case GICV3_IMPL is not set - ifeq (${FVP_USE_GIC_DRIVER}, FVP_GIC600) - GICV3_IMPL := GIC600 - endif +ifeq (${FVP_USE_GIC_DRIVER}, FVP_GICV3) +# The GIC model (GIC-600 or GIC-500) will be detected at runtime +GICV3_SUPPORT_GIC600 := 1 GICV3_OVERRIDE_DISTIF_PWR_OPS := 1 # Include GICv3 driver files diff --git a/plat/arm/board/n1sdp/platform.mk b/plat/arm/board/n1sdp/platform.mk index 44f7b8a52..0bd3a21cf 100644 --- a/plat/arm/board/n1sdp/platform.mk +++ b/plat/arm/board/n1sdp/platform.mk @@ -15,7 +15,7 @@ PLAT_INCLUDES := -I${N1SDP_BASE}/include N1SDP_CPU_SOURCES := lib/cpus/aarch64/neoverse_n1.S # GIC-600 configuration -GICV3_IMPL := GIC600 +GICV3_SUPPORT_GIC600 := 1 GICV3_IMPL_GIC600_MULTICHIP := 1 # Include GICv3 driver files diff --git a/plat/arm/board/tc0/platform.mk b/plat/arm/board/tc0/platform.mk index 265826f9f..7f514cc67 100644 --- a/plat/arm/board/tc0/platform.mk +++ b/plat/arm/board/tc0/platform.mk @@ -25,7 +25,8 @@ USE_COHERENT_MEM := 0 GIC_ENABLE_V4_EXTN := 1 # GIC-600 configuration -GICV3_IMPL := GIC600 +GICV3_SUPPORT_GIC600 := 1 + # Include GICv3 driver files include drivers/arm/gic/v3/gicv3.mk diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/css/sgi/sgi-common.mk index 250458144..6b9e0cda6 100644 --- a/plat/arm/css/sgi/sgi-common.mk +++ b/plat/arm/css/sgi/sgi-common.mk @@ -23,7 +23,7 @@ INTERCONNECT_SOURCES := ${CSS_ENT_BASE}/sgi_interconnect.c PLAT_INCLUDES += -I${CSS_ENT_BASE}/include # GIC-600 configuration -GICV3_IMPL := GIC600 +GICV3_SUPPORT_GIC600 := 1 # Include GICv3 driver files include drivers/arm/gic/v3/gicv3.mk diff --git a/plat/arm/css/sgm/sgm-common.mk b/plat/arm/css/sgm/sgm-common.mk index 60e9fb2e1..5b954f842 100644 --- a/plat/arm/css/sgm/sgm-common.mk +++ b/plat/arm/css/sgm/sgm-common.mk @@ -23,7 +23,7 @@ SGM_CPU_SOURCES := lib/cpus/aarch64/cortex_a55.S \ INTERCONNECT_SOURCES := ${CSS_SGM_BASE}/sgm_interconnect.c # GIC-600 configuration -GICV3_IMPL := GIC600 +GICV3_SUPPORT_GIC600 := 1 # Include GICv3 driver files include drivers/arm/gic/v3/gicv3.mk -- cgit v1.2.3 From 452d5e5ef11271df6ef8480eed900252fd330f10 Mon Sep 17 00:00:00 2001 From: Madhukar Pappireddy Date: Tue, 2 Jun 2020 09:26:30 -0500 Subject: plat/fvp: Add support for dynamic description of secure interrupts Using the fconf framework, the Group 0 and Group 1 secure interrupt descriptors are moved to device tree and retrieved in runtime. This feature is enabled by the build flag SEC_INT_DESC_IN_FCONF. Change-Id: I360c63a83286c7ecc2426cd1ff1b4746d61e633c Signed-off-by: Madhukar Pappireddy --- Makefile | 2 + docs/getting_started/build-options.rst | 6 ++ fdts/fvp-base-gicv3-psci-common.dtsi | 39 ++++++- include/plat/arm/common/fconf_sec_intr_config.h | 27 +++++ make_helpers/defaults.mk | 5 +- plat/arm/board/fvp/fvp_gicv3.c | 22 +++- plat/arm/board/fvp/platform.mk | 5 + plat/arm/board/fvp/sp_min/sp_min-fvp.mk | 5 + plat/arm/common/fconf/fconf_sec_intr_config.c | 131 ++++++++++++++++++++++++ 9 files changed, 236 insertions(+), 6 deletions(-) create mode 100644 include/plat/arm/common/fconf_sec_intr_config.h create mode 100644 plat/arm/common/fconf/fconf_sec_intr_config.c diff --git a/Makefile b/Makefile index 2f53cdf1b..76277971b 100644 --- a/Makefile +++ b/Makefile @@ -889,6 +889,7 @@ $(eval $(call assert_boolean,USE_COHERENT_MEM)) $(eval $(call assert_boolean,USE_DEBUGFS)) $(eval $(call assert_boolean,ARM_IO_IN_DTB)) $(eval $(call assert_boolean,SDEI_IN_FCONF)) +$(eval $(call assert_boolean,SEC_INT_DESC_IN_FCONF)) $(eval $(call assert_boolean,USE_ROMLIB)) $(eval $(call assert_boolean,USE_TBBR_DEFS)) $(eval $(call assert_boolean,WARMBOOT_ENABLE_DCACHE_EARLY)) @@ -969,6 +970,7 @@ $(eval $(call add_define,USE_COHERENT_MEM)) $(eval $(call add_define,USE_DEBUGFS)) $(eval $(call add_define,ARM_IO_IN_DTB)) $(eval $(call add_define,SDEI_IN_FCONF)) +$(eval $(call add_define,SEC_INT_DESC_IN_FCONF)) $(eval $(call add_define,USE_ROMLIB)) $(eval $(call add_define,USE_TBBR_DEFS)) $(eval $(call add_define,WARMBOOT_ENABLE_DCACHE_EARLY)) diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index c86307948..7ca1067a1 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -651,6 +651,12 @@ Common build options than static C structures at compile time. This is currently an experimental feature and 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. + - ``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 reduces SRAM usage. Refer to :ref:`Library at ROM` for further details. Default diff --git a/fdts/fvp-base-gicv3-psci-common.dtsi b/fdts/fvp-base-gicv3-psci-common.dtsi index 0deb8a2e7..192f5748a 100644 --- a/fdts/fvp-base-gicv3-psci-common.dtsi +++ b/fdts/fvp-base-gicv3-psci-common.dtsi @@ -6,6 +6,11 @@ #include +#define LEVEL 0 +#define EDGE 2 +#define SDEI_NORMAL 0x70 +#define HIGHEST_SEC 0 + /memreserve/ 0x80000000 0x00010000; / { @@ -38,8 +43,9 @@ max-pwr-lvl = <2>; }; -#if SDEI_IN_FCONF +#if SDEI_IN_FCONF || SEC_INT_DESC_IN_FCONF firmware { +#if SDEI_IN_FCONF sdei { compatible = "arm,sdei-1.0"; method = "smc"; @@ -59,9 +65,38 @@ <2001 SDEI_DYN_IRQ SDEI_MAPF_DYNAMIC>, <2002 SDEI_DYN_IRQ SDEI_MAPF_DYNAMIC>; }; - }; #endif /* SDEI_IN_FCONF */ +#if SEC_INT_DESC_IN_FCONF + sec_interrupts { + compatible = "arm,secure_interrupt_desc"; + /* Number of G0 and G1 secure interrupts defined by the platform */ + g0_intr_cnt = <2>; + g1s_intr_cnt = <9>; + /* + * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3 + * terminology. Each interrupt property descriptor has 3 fields: + * 1. Interrupt number + * 2. Interrupt priority + * 3. Type of interrupt (Edge or Level configured) + */ + g0_intr_desc = < 8 SDEI_NORMAL EDGE>, + <14 HIGHEST_SEC EDGE>; + + g1s_intr_desc = < 9 HIGHEST_SEC EDGE>, + <10 HIGHEST_SEC EDGE>, + <11 HIGHEST_SEC EDGE>, + <12 HIGHEST_SEC EDGE>, + <13 HIGHEST_SEC EDGE>, + <15 HIGHEST_SEC EDGE>, + <29 HIGHEST_SEC LEVEL>, + <56 HIGHEST_SEC LEVEL>, + <57 HIGHEST_SEC LEVEL>; + }; +#endif /* SEC_INT_DESC_IN_FCONF */ + }; +#endif /* SDEI_IN_FCONF || SEC_INT_DESC_IN_FCONF */ + cpus { #address-cells = <2>; #size-cells = <0>; diff --git a/include/plat/arm/common/fconf_sec_intr_config.h b/include/plat/arm/common/fconf_sec_intr_config.h new file mode 100644 index 000000000..5d6b594a9 --- /dev/null +++ b/include/plat/arm/common/fconf_sec_intr_config.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FCONF_SEC_INTR_CONFIG_H +#define FCONF_SEC_INTR_CONFIG_H + +#include + +#include + +#define hw_config__sec_intr_prop_getter(id) sec_intr_prop.id + +#define SEC_INT_COUNT_MAX U(15) + +struct sec_intr_prop_t { + interrupt_prop_t descriptor[SEC_INT_COUNT_MAX]; + uint32_t count; +}; + +int fconf_populate_sec_intr_config(uintptr_t config); + +extern struct sec_intr_prop_t sec_intr_prop; + +#endif /* FCONF_SEC_INTR_CONFIG_H */ diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index e5880d206..585f06fcc 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -226,7 +226,10 @@ USE_DEBUGFS := 0 ARM_IO_IN_DTB := 0 # Build option to support SDEI through fconf -SDEI_IN_FCONF :=0 +SDEI_IN_FCONF := 0 + +# Build option to support Secure Interrupt descriptors through fconf +SEC_INT_DESC_IN_FCONF := 0 # Build option to choose whether Trusted Firmware uses library at ROM USE_ROMLIB := 0 diff --git a/plat/arm/board/fvp/fvp_gicv3.c b/plat/arm/board/fvp/fvp_gicv3.c index a3ee8ef1b..3e04d6b67 100644 --- a/plat/arm/board/fvp/fvp_gicv3.c +++ b/plat/arm/board/fvp/fvp_gicv3.c @@ -12,6 +12,7 @@ #include #include #include +#include #include /* The GICv3 driver only needs to be initialized in EL3 */ @@ -23,10 +24,13 @@ static uint64_t fvp_gicr_base_addrs[2] = { 0U }; /* List of zero terminated GICR frame addresses which CPUs will probe */ static uint64_t *fvp_gicr_frames = fvp_gicr_base_addrs; +#if !(SEC_INT_DESC_IN_FCONF && ((!defined(__aarch64__) && defined(IMAGE_BL32)) || \ + (defined(__aarch64__) && defined(IMAGE_BL31)))) static const interrupt_prop_t fvp_interrupt_props[] = { PLAT_ARM_G1S_IRQ_PROPS(INTR_GROUP1S), PLAT_ARM_G0_IRQ_PROPS(INTR_GROUP0) }; +#endif /* * MPIDR hashing function for translating MPIDRs read from GICR_TYPER register @@ -52,8 +56,6 @@ static unsigned int fvp_gicv3_mpidr_hash(u_register_t mpidr) static gicv3_driver_data_t fvp_gic_data = { - .interrupt_props = fvp_interrupt_props, - .interrupt_props_num = ARRAY_SIZE(fvp_interrupt_props), .rdistif_num = PLATFORM_CORE_COUNT, .rdistif_base_addrs = fvp_rdistif_base_addrs, .mpidr_to_core_pos = fvp_gicv3_mpidr_hash @@ -61,7 +63,10 @@ static gicv3_driver_data_t fvp_gic_data = { void plat_arm_gic_driver_init(void) { - /* Get GICD and GICR base addressed through FCONF APIs */ + /* + * Get GICD and GICR base addressed through FCONF APIs. + * FCONF is not supported in BL32 for FVP. + */ #if (!defined(__aarch64__) && defined(IMAGE_BL32)) || \ (defined(__aarch64__) && defined(IMAGE_BL31)) fvp_gic_data.gicd_base = (uintptr_t)FCONF_GET_PROPERTY(hw_config, @@ -69,9 +74,20 @@ void plat_arm_gic_driver_init(void) gicd_base); fvp_gicr_base_addrs[0] = FCONF_GET_PROPERTY(hw_config, gicv3_config, gicr_base); +#if SEC_INT_DESC_IN_FCONF + fvp_gic_data.interrupt_props = FCONF_GET_PROPERTY(hw_config, + sec_intr_prop, descriptor); + fvp_gic_data.interrupt_props_num = FCONF_GET_PROPERTY(hw_config, + sec_intr_prop, count); +#else + fvp_gic_data.interrupt_props = fvp_interrupt_props; + fvp_gic_data.interrupt_props_num = ARRAY_SIZE(fvp_interrupt_props); +#endif #else fvp_gic_data.gicd_base = PLAT_ARM_GICD_BASE; fvp_gicr_base_addrs[0] = PLAT_ARM_GICR_BASE; + fvp_gic_data.interrupt_props = fvp_interrupt_props; + fvp_gic_data.interrupt_props_num = ARRAY_SIZE(fvp_interrupt_props); #endif /* diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 024e682bc..e605608da 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -221,6 +221,11 @@ ifeq ($(filter 1,${BL2_AT_EL3} ${RESET_TO_BL31}),) BL31_SOURCES += common/fdt_wrappers.c \ lib/fconf/fconf.c \ plat/arm/board/fvp/fconf/fconf_hw_config_getter.c + +ifeq (${SEC_INT_DESC_IN_FCONF},1) +BL31_SOURCES += plat/arm/common/fconf/fconf_sec_intr_config.c +endif + endif ifeq (${FVP_USE_SP804_TIMER},1) 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 ba6ceec4e..64cb7add5 100644 --- a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk +++ b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk @@ -25,6 +25,11 @@ ifeq ($(filter 1,${BL2_AT_EL3} ${RESET_TO_SP_MIN}),) BL32_SOURCES += common/fdt_wrappers.c \ lib/fconf/fconf.c \ plat/arm/board/fvp/fconf/fconf_hw_config_getter.c + +ifeq (${SEC_INT_DESC_IN_FCONF},1) +BL32_SOURCES += plat/arm/common/fconf/fconf_sec_intr_config.c +endif + endif include plat/arm/common/sp_min/arm_sp_min.mk diff --git a/plat/arm/common/fconf/fconf_sec_intr_config.c b/plat/arm/common/fconf/fconf_sec_intr_config.c new file mode 100644 index 000000000..f28be240e --- /dev/null +++ b/plat/arm/common/fconf/fconf_sec_intr_config.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include + +#include +#include +#include +#include + +#define G0_INTR_NUM(i) g0_intr_prop[3U * (i)] +#define G0_INTR_PRIORITY(i) g0_intr_prop[3U * (i) + 1] +#define G0_INTR_CONFIG(i) g0_intr_prop[3U * (i) + 2] + +#define G1S_INTR_NUM(i) g1s_intr_prop[3U * (i)] +#define G1S_INTR_PRIORITY(i) g1s_intr_prop[3U * (i) + 1] +#define G1S_INTR_CONFIG(i) g1s_intr_prop[3U * (i) + 2] + +struct sec_intr_prop_t sec_intr_prop; + +static void print_intr_prop(interrupt_prop_t prop) +{ + VERBOSE("FCONF: Secure Interrupt NUM: %d, PRI: %d, TYPE: %d\n", + prop.intr_num, prop.intr_pri, prop.intr_cfg); +} + +int fconf_populate_sec_intr_config(uintptr_t config) +{ + int node, err; + uint32_t g0_intr_count, g1s_intr_count; + uint32_t g0_intr_prop[SEC_INT_COUNT_MAX * 3]; + uint32_t g1s_intr_prop[SEC_INT_COUNT_MAX * 3]; + + /* Necessary to work with libfdt APIs */ + const void *hw_config_dtb = (const void *)config; + + node = fdt_node_offset_by_compatible(hw_config_dtb, -1, + "arm,secure_interrupt_desc"); + if (node < 0) { + ERROR("FCONF: Unable to locate node with %s compatible property\n", + "arm,secure_interrupt_desc"); + return node; + } + + /* Read number of Group 0 interrupts specified by platform */ + err = fdt_read_uint32(hw_config_dtb, node, "g0_intr_cnt", &g0_intr_count); + if (err < 0) { + ERROR("FCONF: Could not locate g0s_intr_cnt property\n"); + return err; + } + + /* At least 1 Group 0 interrupt description has to be provided*/ + if (g0_intr_count < 1U) { + ERROR("FCONF: Invalid number of Group 0 interrupts count specified\n"); + return -1; + } + + /* Read number of Group 1 secure interrupts specified by platform */ + err = fdt_read_uint32(hw_config_dtb, node, "g1s_intr_cnt", + &g1s_intr_count); + if (err < 0) { + ERROR("FCONF: Could not locate g1s_intr_cnt property\n"); + return err; + } + + /* At least one Group 1 interrupt description has to be provided*/ + if (g1s_intr_count < 1U) { + ERROR("FCONF: Invalid number of Group 1 secure interrupts count specified\n"); + return -1; + } + + /* + * Check if the total number of secure interrupts described are within + * the limit defined statically by the platform. + */ + if ((g0_intr_count + g1s_intr_count) > SEC_INT_COUNT_MAX) { + ERROR("FCONF: Total number of secure interrupts exceed limit the of %d\n", + SEC_INT_COUNT_MAX); + return -1; + } + + sec_intr_prop.count = g0_intr_count + g1s_intr_count; + + /* Read the Group 0 interrupt descriptors */ + err = fdt_read_uint32_array(hw_config_dtb, node, "g0_intr_desc", + g0_intr_count * 3, g0_intr_prop); + if (err < 0) { + ERROR("FCONF: Read cell failed for 'g0s_intr_desc': %d\n", err); + return err; + } + + /* Read the Group 1 secure interrupt descriptors */ + err = fdt_read_uint32_array(hw_config_dtb, node, "g1s_intr_desc", + g1s_intr_count * 3, g1s_intr_prop); + if (err < 0) { + ERROR("FCONF: Read cell failed for 'g1s_intr_desc': %d\n", err); + return err; + } + + /* Populate Group 0 interrupt descriptors into fconf based C struct */ + for (uint32_t i = 0; i < g0_intr_count; i++) { + interrupt_prop_t sec_intr_property; + + /* Secure Interrupt Group: INTR_GROUP0 i.e., 0x1 */ + sec_intr_property.intr_grp = 1; + sec_intr_property.intr_num = G0_INTR_NUM(i); + sec_intr_property.intr_pri = G0_INTR_PRIORITY(i); + sec_intr_property.intr_cfg = G0_INTR_CONFIG(i); + sec_intr_prop.descriptor[i] = sec_intr_property; + print_intr_prop(sec_intr_property); + } + + /* Populate G1 secure interrupt descriptors into fconf based C struct */ + for (uint32_t i = 0; i < g1s_intr_count; i++) { + interrupt_prop_t sec_intr_property; + + /* Secure Interrupt Group: INTR_GROUP1S i.e., 0x0 */ + sec_intr_property.intr_grp = 0; + sec_intr_property.intr_num = G1S_INTR_NUM(i); + sec_intr_property.intr_pri = G1S_INTR_PRIORITY(i); + sec_intr_property.intr_cfg = G1S_INTR_CONFIG(i); + sec_intr_prop.descriptor[i + g0_intr_count] = sec_intr_property; + print_intr_prop(sec_intr_property); + } + + return 0; +} + +FCONF_REGISTER_POPULATOR(HW_CONFIG, sec_intr_prop, fconf_populate_sec_intr_config); -- cgit v1.2.3 From c5c1af0db66fe09558f3158c5af3d5a7ca866140 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Sun, 24 May 2020 16:26:22 -0700 Subject: cpus: denver: disable cycle counter when event counting is prohibited The Denver CPUs implement support for PMUv3 for ARMv8.1 and expect the PMCR_EL0 to be saved in non-secure context. This patch disables cycle counter when event counting is prohibited immediately on entering the secure world to avoid leaking useful information about the PMU counters. The context saving code later saves the value of PMCR_EL0 to the non-secure world context. Verified with 'PMU Leakage' test suite. ******************************* Summary ******************************* > Test suite 'PMU Leakage' Passed ================================= Tests Skipped : 2 Tests Passed : 2 Tests Failed : 0 Tests Crashed : 0 Total tests : 4 ================================= Signed-off-by: Varun Wadekar Change-Id: I3675e2b99b44ed23d86e29a5af1b496e80324875 --- lib/cpus/aarch64/denver.S | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/cpus/aarch64/denver.S b/lib/cpus/aarch64/denver.S index e260f8d28..c050b02a7 100644 --- a/lib/cpus/aarch64/denver.S +++ b/lib/cpus/aarch64/denver.S @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -33,6 +34,12 @@ vector_base workaround_bpflush_runtime_exceptions .macro apply_workaround stp x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0] + /* Disable cycle counter when event counting is prohibited */ + mrs x1, pmcr_el0 + orr x0, x1, #PMCR_EL0_DP_BIT + msr pmcr_el0, x0 + isb + /* ------------------------------------------------- * A new write-only system register where a write of * 1 to bit 0 will cause the indirect branch predictor -- cgit v1.2.3 From 198a705f6ecf3457af2b2983e47b0e23ea6a45c5 Mon Sep 17 00:00:00 2001 From: Philipp Tomsich Date: Wed, 5 Jul 2017 12:20:44 +0200 Subject: rockchip: rk3368: fix PLAT_RK_CLST_TO_CPUID_SHIFT The RK3368 has two clusters of 4 cores and it's cluster id starts at bit 8 of the MPIDR. To convert from the cluster id (0 or 1) to the lowest CPU-ID in the respective cluster, we thus need to shift by 6 (i.e. shift by 8 to extract the cluster-id and multiply by 4). This change is required to ensure the PSCI support can index the per-cpu entry-address array correctly. Signed-off-by: Philipp Tomsich Signed-off-by: Heiko Stuebner Change-Id: I64a76038f090a85a47067f09f750e96e3946e756 --- plat/rockchip/rk3368/include/platform_def.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/rockchip/rk3368/include/platform_def.h b/plat/rockchip/rk3368/include/platform_def.h index 6fcf2ba82..519a025c9 100644 --- a/plat/rockchip/rk3368/include/platform_def.h +++ b/plat/rockchip/rk3368/include/platform_def.h @@ -48,7 +48,7 @@ PLATFORM_CLUSTER_COUNT + \ PLATFORM_CORE_COUNT) -#define PLAT_RK_CLST_TO_CPUID_SHIFT 8 +#define PLAT_RK_CLST_TO_CPUID_SHIFT 6 #define PLAT_MAX_PWR_LVL MPIDR_AFFLVL2 -- cgit v1.2.3 From a8818bbf75196d84b098170c2c0f98382308c50c Mon Sep 17 00:00:00 2001 From: Manish Pandey Date: Wed, 10 Jun 2020 15:50:36 +0100 Subject: cert_create: extend Secure partition support for tbbr CoT with sha 0792dd7, support to generate certificate for Secure Partitions was added for dualroot CoT only, this patch extends this support for tbbr CoT. Signed-off-by: Manish Pandey Change-Id: I451c0333536dd1cbe17861d454bdb0dc7a17c63f --- include/tools_share/dualroot_oid.h | 12 ----- include/tools_share/tbbr_oid.h | 12 +++++ tools/cert_create/include/tbbr/tbb_cert.h | 1 + tools/cert_create/include/tbbr/tbb_ext.h | 8 ++++ tools/cert_create/src/tbbr/tbb_cert.c | 21 ++++++++ tools/cert_create/src/tbbr/tbb_ext.c | 80 +++++++++++++++++++++++++++++++ 6 files changed, 122 insertions(+), 12 deletions(-) diff --git a/include/tools_share/dualroot_oid.h b/include/tools_share/dualroot_oid.h index da367da92..3e88a6d22 100644 --- a/include/tools_share/dualroot_oid.h +++ b/include/tools_share/dualroot_oid.h @@ -16,16 +16,4 @@ */ #define PROT_PK_OID "1.3.6.1.4.1.4128.2100.1102" -/* - * Secure Partitions Content Certificate - */ -#define SP_PKG1_HASH_OID "1.3.6.1.4.1.4128.2100.1301" -#define SP_PKG2_HASH_OID "1.3.6.1.4.1.4128.2100.1302" -#define SP_PKG3_HASH_OID "1.3.6.1.4.1.4128.2100.1303" -#define SP_PKG4_HASH_OID "1.3.6.1.4.1.4128.2100.1304" -#define SP_PKG5_HASH_OID "1.3.6.1.4.1.4128.2100.1305" -#define SP_PKG6_HASH_OID "1.3.6.1.4.1.4128.2100.1306" -#define SP_PKG7_HASH_OID "1.3.6.1.4.1.4128.2100.1307" -#define SP_PKG8_HASH_OID "1.3.6.1.4.1.4128.2100.1308" - #endif /* DUALROOT_OID_H */ diff --git a/include/tools_share/tbbr_oid.h b/include/tools_share/tbbr_oid.h index 6bccfdd1e..24a8f39ca 100644 --- a/include/tools_share/tbbr_oid.h +++ b/include/tools_share/tbbr_oid.h @@ -145,4 +145,16 @@ /* NonTrustedFirmwareConfigHash - NT_FW_CONFIG */ #define NON_TRUSTED_FW_CONFIG_HASH_OID "1.3.6.1.4.1.4128.2100.1202" +/* + * Secure Partitions Content Certificate + */ +#define SP_PKG1_HASH_OID "1.3.6.1.4.1.4128.2100.1301" +#define SP_PKG2_HASH_OID "1.3.6.1.4.1.4128.2100.1302" +#define SP_PKG3_HASH_OID "1.3.6.1.4.1.4128.2100.1303" +#define SP_PKG4_HASH_OID "1.3.6.1.4.1.4128.2100.1304" +#define SP_PKG5_HASH_OID "1.3.6.1.4.1.4128.2100.1305" +#define SP_PKG6_HASH_OID "1.3.6.1.4.1.4128.2100.1306" +#define SP_PKG7_HASH_OID "1.3.6.1.4.1.4128.2100.1307" +#define SP_PKG8_HASH_OID "1.3.6.1.4.1.4128.2100.1308" + #endif /* TBBR_OID_H */ diff --git a/tools/cert_create/include/tbbr/tbb_cert.h b/tools/cert_create/include/tbbr/tbb_cert.h index 628ef3a42..e5fa3a238 100644 --- a/tools/cert_create/include/tbbr/tbb_cert.h +++ b/tools/cert_create/include/tbbr/tbb_cert.h @@ -23,6 +23,7 @@ enum { TRUSTED_OS_FW_CONTENT_CERT, NON_TRUSTED_FW_KEY_CERT, NON_TRUSTED_FW_CONTENT_CERT, + SIP_SECURE_PARTITION_CONTENT_CERT, FWU_CERT }; diff --git a/tools/cert_create/include/tbbr/tbb_ext.h b/tools/cert_create/include/tbbr/tbb_ext.h index 462aafcfa..7ac97a513 100644 --- a/tools/cert_create/include/tbbr/tbb_ext.h +++ b/tools/cert_create/include/tbbr/tbb_ext.h @@ -30,6 +30,14 @@ enum { NON_TRUSTED_FW_CONTENT_CERT_PK_EXT, NON_TRUSTED_WORLD_BOOTLOADER_HASH_EXT, NON_TRUSTED_FW_CONFIG_HASH_EXT, + SP_PKG1_HASH_EXT, + SP_PKG2_HASH_EXT, + SP_PKG3_HASH_EXT, + SP_PKG4_HASH_EXT, + SP_PKG5_HASH_EXT, + SP_PKG6_HASH_EXT, + SP_PKG7_HASH_EXT, + SP_PKG8_HASH_EXT, SCP_FWU_CFG_HASH_EXT, AP_FWU_CFG_HASH_EXT, FWU_HASH_EXT diff --git a/tools/cert_create/src/tbbr/tbb_cert.c b/tools/cert_create/src/tbbr/tbb_cert.c index 7fb32d82c..b614e2e49 100644 --- a/tools/cert_create/src/tbbr/tbb_cert.c +++ b/tools/cert_create/src/tbbr/tbb_cert.c @@ -164,6 +164,27 @@ static cert_t tbb_certs[] = { }, .num_ext = 3 }, + [SIP_SECURE_PARTITION_CONTENT_CERT] = { + .id = SIP_SECURE_PARTITION_CONTENT_CERT, + .opt = "sip-sp-cert", + .help_msg = "SiP owned Secure Partition Content Certificate (output file)", + .fn = NULL, + .cn = "SiP owned Secure Partition Content Certificate", + .key = TRUSTED_WORLD_KEY, + .issuer = SIP_SECURE_PARTITION_CONTENT_CERT, + .ext = { + TRUSTED_FW_NVCOUNTER_EXT, + SP_PKG1_HASH_EXT, + SP_PKG2_HASH_EXT, + SP_PKG3_HASH_EXT, + SP_PKG4_HASH_EXT, + SP_PKG5_HASH_EXT, + SP_PKG6_HASH_EXT, + SP_PKG7_HASH_EXT, + SP_PKG8_HASH_EXT, + }, + .num_ext = 9 + }, [FWU_CERT] = { .id = FWU_CERT, .opt = "fwu-cert", diff --git a/tools/cert_create/src/tbbr/tbb_ext.c b/tools/cert_create/src/tbbr/tbb_ext.c index ee5377fe8..0068d3b4a 100644 --- a/tools/cert_create/src/tbbr/tbb_ext.c +++ b/tools/cert_create/src/tbbr/tbb_ext.c @@ -203,6 +203,86 @@ static ext_t tbb_ext[] = { .type = EXT_TYPE_HASH, .optional = 1 }, + [SP_PKG1_HASH_EXT] = { + .oid = SP_PKG1_HASH_OID, + .opt = "sp-pkg1", + .help_msg = "Secure Partition Package1 file", + .sn = "SPPkg1Hash", + .ln = "SP Pkg1 hash (SHA256)", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_HASH, + .optional = 1 + }, + [SP_PKG2_HASH_EXT] = { + .oid = SP_PKG2_HASH_OID, + .opt = "sp-pkg2", + .help_msg = "Secure Partition Package2 file", + .sn = "SPPkg2Hash", + .ln = "SP Pkg2 hash (SHA256)", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_HASH, + .optional = 1 + }, + [SP_PKG3_HASH_EXT] = { + .oid = SP_PKG3_HASH_OID, + .opt = "sp-pkg3", + .help_msg = "Secure Partition Package3 file", + .sn = "SPPkg3Hash", + .ln = "SP Pkg3 hash (SHA256)", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_HASH, + .optional = 1 + }, + [SP_PKG4_HASH_EXT] = { + .oid = SP_PKG4_HASH_OID, + .opt = "sp-pkg4", + .help_msg = "Secure Partition Package4 file", + .sn = "SPPkg4Hash", + .ln = "SP Pkg4 hash (SHA256)", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_HASH, + .optional = 1 + }, + [SP_PKG5_HASH_EXT] = { + .oid = SP_PKG5_HASH_OID, + .opt = "sp-pkg5", + .help_msg = "Secure Partition Package5 file", + .sn = "SPPkg5Hash", + .ln = "SP Pkg5 hash (SHA256)", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_HASH, + .optional = 1 + }, + [SP_PKG6_HASH_EXT] = { + .oid = SP_PKG6_HASH_OID, + .opt = "sp-pkg6", + .help_msg = "Secure Partition Package6 file", + .sn = "SPPkg6Hash", + .ln = "SP Pkg6 hash (SHA256)", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_HASH, + .optional = 1 + }, + [SP_PKG7_HASH_EXT] = { + .oid = SP_PKG7_HASH_OID, + .opt = "sp-pkg7", + .help_msg = "Secure Partition Package7 file", + .sn = "SPPkg7Hash", + .ln = "SP Pkg7 hash (SHA256)", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_HASH, + .optional = 1 + }, + [SP_PKG8_HASH_EXT] = { + .oid = SP_PKG8_HASH_OID, + .opt = "sp-pkg8", + .help_msg = "Secure Partition Package8 file", + .sn = "SPPkg8Hash", + .ln = "SP Pkg8 hash (SHA256)", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_HASH, + .optional = 1 + }, [SCP_FWU_CFG_HASH_EXT] = { .oid = SCP_FWU_CFG_HASH_OID, .opt = "scp-fwu-cfg", -- cgit v1.2.3 From 8ca61538a0fe3aed6764a012317cbf61f09ebb61 Mon Sep 17 00:00:00 2001 From: David Pu Date: Mon, 18 Mar 2019 15:14:49 -0700 Subject: Tegra194: add RAS exception handling This patch adds all Tegra194 RAS nodes definitions and support to handle all uncorrectable RAS errors. Change-Id: I109b5a8dbca91d92752dc282c4ca30f273c475f9 Signed-off-by: David Pu Signed-off-by: Varun Wadekar --- include/lib/extensions/ras.h | 2 + include/lib/extensions/ras_arch.h | 4 + lib/extensions/ras/ras_common.c | 42 +++ plat/nvidia/tegra/include/platform_def.h | 1 + .../tegra/include/t194/tegra194_ras_private.h | 260 +++++++++++++++++++ plat/nvidia/tegra/include/tegra_private.h | 6 +- plat/nvidia/tegra/soc/t194/plat_ras.c | 287 +++++++++++++++++++++ plat/nvidia/tegra/soc/t194/plat_setup.c | 5 + plat/nvidia/tegra/soc/t194/platform_t194.mk | 11 + 9 files changed, 617 insertions(+), 1 deletion(-) create mode 100644 plat/nvidia/tegra/include/t194/tegra194_ras_private.h create mode 100644 plat/nvidia/tegra/soc/t194/plat_ras.c diff --git a/include/lib/extensions/ras.h b/include/lib/extensions/ras.h index 4fc8f04b1..793ab9fac 100644 --- a/include/lib/extensions/ras.h +++ b/include/lib/extensions/ras.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -192,6 +193,7 @@ static inline int ras_err_ser_probe_sysreg(const struct err_record_info *info, probe_data); } +const char *ras_serr_to_str(unsigned int serr); int ras_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie, void *handle, uint64_t flags); void ras_init(void); diff --git a/include/lib/extensions/ras_arch.h b/include/lib/extensions/ras_arch.h index 0c98c4a0e..55760b06b 100644 --- a/include/lib/extensions/ras_arch.h +++ b/include/lib/extensions/ras_arch.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -151,6 +152,9 @@ #define ERROR_STATUS_SET_UC 0x2 /* Uncontainable */ #define ERROR_STATUS_SET_CE 0x3 /* Corrected */ +/* Number of architecturally-defined primary error codes */ +#define ERROR_STATUS_NUM_SERR U(22) + /* Implementation Defined Syndrome bit in ESR */ #define SERROR_IDS_BIT U(24) diff --git a/lib/extensions/ras/ras_common.c b/lib/extensions/ras/ras_common.c index 64a48524b..36f9a95b6 100644 --- a/lib/extensions/ras/ras_common.c +++ b/lib/extensions/ras/ras_common.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -18,6 +19,47 @@ # error Platform must define RAS priority value #endif +/* + * Function to convert architecturally-defined primary error code SERR, + * bits[7:0] from ERRSTATUS to its corresponding error string. + */ +const char *ras_serr_to_str(unsigned int serr) +{ + const char *str[ERROR_STATUS_NUM_SERR] = { + "No error", + "IMPLEMENTATION DEFINED error", + "Data value from (non-associative) internal memory", + "IMPLEMENTATION DEFINED pin", + "Assertion failure", + "Error detected on internal data path", + "Data value from associative memory", + "Address/control value from associative memory", + "Data value from a TLB", + "Address/control value from a TLB", + "Data value from producer", + "Address/control value from producer", + "Data value from (non-associative) external memory", + "Illegal address (software fault)", + "Illegal access (software fault)", + "Illegal state (software fault)", + "Internal data register", + "Internal control register", + "Error response from slave", + "External timeout", + "Internal timeout", + "Deferred error from slave not supported at master" + }; + + /* + * All other values are reserved. Reserved values might be defined + * in a future version of the architecture + */ + if (serr >= ERROR_STATUS_NUM_SERR) + return "unknown SERR"; + + return str[serr]; +} + /* Handler that receives External Aborts on RAS-capable systems */ int ras_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie, void *handle, uint64_t flags) diff --git a/plat/nvidia/tegra/include/platform_def.h b/plat/nvidia/tegra/include/platform_def.h index 678b15c14..2331869d2 100644 --- a/plat/nvidia/tegra/include/platform_def.h +++ b/plat/nvidia/tegra/include/platform_def.h @@ -95,6 +95,7 @@ * Platform macros to support exception handling framework ******************************************************************************/ #define PLAT_PRI_BITS U(3) +#define PLAT_RAS_PRI U(0x10) #define PLAT_SDEI_CRITICAL_PRI U(0x20) #define PLAT_SDEI_NORMAL_PRI U(0x30) #define PLAT_TEGRA_WDT_PRIO U(0x40) diff --git a/plat/nvidia/tegra/include/t194/tegra194_ras_private.h b/plat/nvidia/tegra/include/t194/tegra194_ras_private.h new file mode 100644 index 000000000..c867b9d2b --- /dev/null +++ b/plat/nvidia/tegra/include/t194/tegra194_ras_private.h @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef TEGRA194_RAS_PRIVATE +#define TEGRA194_RAS_PRIVATE + +#include + +/* Implementation defined RAS error and corresponding error message */ +struct ras_error { + const char *error_msg; + /* IERR(bits[15:8]) from ERRSTATUS */ + uint8_t error_code; +}; + +/* RAS error node-specific auxiliary data */ +struct ras_aux_data { + /* point to null-terminated ras_error array to convert error code to msg. */ + const struct ras_error *error_records; + /* + * function to return an value which needs to be programmed into ERXCTLR_EL1 + * to enable all specified RAS errors for current node. + */ + uint64_t (*err_ctrl)(void); +}; + +/* IFU Uncorrectable RAS ERROR */ +#define IFU_UNCORR_RAS_ERROR_LIST(X) + +/* JSR_RET Uncorrectable RAS ERROR */ +#define JSR_RET_UNCORR_RAS_ERROR_LIST(X) \ + /* Name, ERR_CTRL, IERR, ISA Desc */ \ + X(JSR_RET, 35, 0x13, "Floating Point Register File Parity Error") \ + X(JSR_RET, 34, 0x12, "Integer Register File Parity Error") \ + X(JSR_RET, 33, 0x11, "Garbage Bundle") \ + X(JSR_RET, 32, 0x10, "Bundle Completion Timeout") + +/* JSR_MTS Uncorrectable RAS ERROR */ +#define JSR_MTS_UNCORR_RAS_ERROR_LIST(X) \ + /* Name, ERR_CTRL, IERR, ISA Desc */ \ + X(JSR_MTS, 40, 0x28, "CoreSight Access Error") \ + X(JSR_MTS, 39, 0x27, "Dual Execution Uncorrectable Error") \ + X(JSR_MTS, 37, 0x25, "CTU MMIO Region") \ + X(JSR_MTS, 36, 0x24, "MTS MMCRAB Region Access") \ + X(JSR_MTS, 35, 0x23, "MTS_CARVEOUT Access from ARM SW") \ + X(JSR_MTS, 34, 0x22, "NAFLL PLL Failure to Lock") \ + X(JSR_MTS, 32, 0x20, "Internal Uncorrectable MTS Error") + +/* LSD_STQ Uncorrectable RAS ERROR */ +#define LSD_STQ_UNCORR_RAS_ERROR_LIST(X) \ + /* Name, ERR_CTRL, IERR, ISA Desc */ \ + X(LSD_STQ, 41, 0x39, "Coherent Cache Data Store Multi-Line ECC Error") \ + X(LSD_STQ, 40, 0x38, "Coherent Cache Data Store Uncorrectable ECC Error") \ + X(LSD_STQ, 38, 0x36, "Coherent Cache Data Load Uncorrectable ECC Error") \ + X(LSD_STQ, 33, 0x31, "Coherent Cache Tag Store Parity Error") \ + X(LSD_STQ, 32, 0x30, "Coherent Cache Tag Load Parity Error") + +/* LSD_DCC Uncorrectable RAS ERROR */ +#define LSD_DCC_UNCORR_RAS_ERROR_LIST(X) \ + /* Name, ERR_CTRL, IERR, ISA Desc */ \ + X(LSD_DCC, 41, 0x49, "BTU Copy Mini-Cache PPN Multi-Hit Error") \ + X(LSD_DCC, 39, 0x47, "Coherent Cache Data Uncorrectable ECC Error") \ + X(LSD_DCC, 37, 0x45, "Version Cache Byte-Enable Parity Error") \ + X(LSD_DCC, 36, 0x44, "Version Cache Data Uncorrectable ECC Error") \ + X(LSD_DCC, 33, 0x41, "BTU Copy Coherent Cache PPN Parity Error") \ + X(LSD_DCC, 32, 0x40, "BTU Copy Coherent Cache VPN Parity Error") + +/* LSD_L1HPF Uncorrectable RAS ERROR */ +#define LSD_L1HPF_UNCORR_RAS_ERROR_LIST(X) + +/* L2 Uncorrectable RAS ERROR */ +#define L2_UNCORR_RAS_ERROR_LIST(X) \ + /* Name, ERR_CTRL, IERR, ISA Desc */ \ + X(L2, 56, 0x68, "URT Timeout") \ + X(L2, 55, 0x67, "L2 Protocol Violation") \ + X(L2, 54, 0x66, "SCF to L2 Slave Error Read") \ + X(L2, 53, 0x65, "SCF to L2 Slave Error Write") \ + X(L2, 52, 0x64, "SCF to L2 Decode Error Read") \ + X(L2, 51, 0x63, "SCF to L2 Decode Error Write") \ + X(L2, 50, 0x62, "SCF to L2 Request Response Interface Parity Errors") \ + X(L2, 49, 0x61, "SCF to L2 Advance notice interface parity errors") \ + X(L2, 48, 0x60, "SCF to L2 Filldata Parity Errors") \ + X(L2, 47, 0x5F, "SCF to L2 UnCorrectable ECC Data Error on interface") \ + X(L2, 45, 0x5D, "Core 1 to L2 Parity Error") \ + X(L2, 44, 0x5C, "Core 0 to L2 Parity Error") \ + X(L2, 43, 0x5B, "L2 Multi-Hit") \ + X(L2, 42, 0x5A, "L2 URT Tag Parity Error") \ + X(L2, 41, 0x59, "L2 NTT Tag Parity Error") \ + X(L2, 40, 0x58, "L2 MLT Tag Parity Error") \ + X(L2, 39, 0x57, "L2 URD Data") \ + X(L2, 38, 0x56, "L2 NTP Data") \ + X(L2, 36, 0x54, "L2 MLC Uncorrectable Clean") \ + X(L2, 35, 0x53, "L2 URD Uncorrectable Dirty") \ + X(L2, 34, 0x52, "L2 MLC Uncorrectable Dirty") + +/* CLUSTER_CLOCKS Uncorrectable RAS ERROR */ +#define CLUSTER_CLOCKS_UNCORR_RAS_ERROR_LIST(X) \ + /* Name, ERR_CTRL, IERR, ISA Desc */ \ + X(CLUSTER_CLOCKS, 32, 0xE4, "Frequency Monitor Error") + +/* MMU Uncorrectable RAS ERROR */ +#define MMU_UNCORR_RAS_ERROR_LIST(X) + +/* L3 Uncorrectable RAS ERROR */ +#define L3_UNCORR_RAS_ERROR_LIST(X) \ + /* Name, ERR_CTRL, IERR, ISA Desc */ \ + X(L3, 43, 0x7B, "SNOC Interface Parity Error") \ + X(L3, 42, 0x7A, "MCF Interface Parity Error") \ + X(L3, 41, 0x79, "L3 Tag Parity Error") \ + X(L3, 40, 0x78, "L3 Dir Parity Error") \ + X(L3, 39, 0x77, "L3 Uncorrectable ECC Error") \ + X(L3, 37, 0x75, "Multi-Hit CAM Error") \ + X(L3, 36, 0x74, "Multi-Hit Tag Error") \ + X(L3, 35, 0x73, "Unrecognized Command Error") \ + X(L3, 34, 0x72, "L3 Protocol Error") + +/* CCPMU Uncorrectable RAS ERROR */ +#define CCPMU_UNCORR_RAS_ERROR_LIST(X) \ + /* Name, ERR_CTRL, IERR, ISA Desc */ \ + X(CCPMU, 40, 0x87, "CoreSight Access Error") \ + X(CCPMU, 36, 0x84, "MCE Ucode Error") \ + X(CCPMU, 35, 0x83, "MCE IL1 Parity Error") \ + X(CCPMU, 34, 0x82, "MCE Timeout Error") \ + X(CCPMU, 33, 0x81, "CRAB Access Error") \ + X(CCPMU, 32, 0x80, "MCE Memory Access Error") + +/* SCF_IOB Uncorrectable RAS ERROR */ +#define SCF_IOB_UNCORR_RAS_ERROR_LIST(X) \ + /* Name, ERR_CTRL, IERR, ISA Desc */ \ + X(SCF_IOB, 41, 0x99, "Request parity error") \ + X(SCF_IOB, 40, 0x98, "Putdata parity error") \ + X(SCF_IOB, 39, 0x97, "Uncorrectable ECC on Putdata") \ + X(SCF_IOB, 38, 0x96, "CBB Interface Error") \ + X(SCF_IOB, 37, 0x95, "MMCRAB Error") \ + X(SCF_IOB, 36, 0x94, "IHI Interface Error") \ + X(SCF_IOB, 35, 0x93, "CRI Error") \ + X(SCF_IOB, 34, 0x92, "TBX Interface Error") \ + X(SCF_IOB, 33, 0x91, "EVP Interface Error") + +/* SCF_SNOC Uncorrectable RAS ERROR */ +#define SCF_SNOC_UNCORR_RAS_ERROR_LIST(X) \ + /* Name, ERR_CTRL, IERR, ISA Desc */ \ + X(SCF_SNOC, 42, 0xAA, "Misc Client Parity Error") \ + X(SCF_SNOC, 41, 0xA9, "Misc Filldata Parity Error") \ + X(SCF_SNOC, 40, 0xA8, "Uncorrectable ECC Misc Client") \ + X(SCF_SNOC, 39, 0xA7, "DVMU Interface Parity Error") \ + X(SCF_SNOC, 38, 0xA6, "DVMU Interface Timeout Error") \ + X(SCF_SNOC, 37, 0xA5, "CPE Request Error") \ + X(SCF_SNOC, 36, 0xA4, "CPE Response Error") \ + X(SCF_SNOC, 35, 0xA3, "CPE Timeout Error") \ + X(SCF_SNOC, 34, 0xA2, "Uncorrectable Carveout Error") + +/* SCF_CTU Uncorrectable RAS ERROR */ +#define SCF_CTU_UNCORR_RAS_ERROR_LIST(X) \ + /* Name, ERR_CTRL, IERR, ISA Desc */ \ + X(SCF_CTU, 39, 0xB7, "Timeout error for TRC_DMA request") \ + X(SCF_CTU, 38, 0xB6, "Timeout error for CTU Snp") \ + X(SCF_CTU, 37, 0xB5, "Parity error in CTU TAG RAM") \ + X(SCF_CTU, 36, 0xB3, "Parity error in CTU DATA RAM") \ + X(SCF_CTU, 35, 0xB4, "Parity error for Cluster Rsp") \ + X(SCF_CTU, 34, 0xB2, "Parity error for TRL requests from 9 agents") \ + X(SCF_CTU, 33, 0xB1, "Parity error for MCF request") \ + X(SCF_CTU, 32, 0xB0, "TRC DMA fillsnoop parity error") + +/* CMU_CLOCKS Uncorrectable RAS ERROR */ +#define CMU_CLOCKS_UNCORR_RAS_ERROR_LIST(X) \ + /* Name, ERR_CTRL, IERR, ISA Desc */ \ + X(CMU_CLOCKS, 39, 0xC7, "Cluster 3 frequency monitor error") \ + X(CMU_CLOCKS, 38, 0xC6, "Cluster 2 frequency monitor error") \ + X(CMU_CLOCKS, 37, 0xC5, "Cluster 1 frequency monitor error") \ + X(CMU_CLOCKS, 36, 0xC3, "Cluster 0 frequency monitor error") \ + X(CMU_CLOCKS, 35, 0xC4, "Voltage error on ADC1 Monitored Logic") \ + X(CMU_CLOCKS, 34, 0xC2, "Voltage error on ADC0 Monitored Logic") \ + X(CMU_CLOCKS, 33, 0xC1, "Lookup Table 1 Parity Error") \ + X(CMU_CLOCKS, 32, 0xC0, "Lookup Table 0 Parity Error") + +/* + * Define one ras_error entry. + * + * This macro wille be used to to generate ras_error records for each node + * defined by _UNCORR_RAS_ERROR_LIST macro. + */ +#define DEFINE_ONE_RAS_ERROR_MSG(unit, ras_bit, ierr, msg) \ + { \ + .error_msg = (msg), \ + .error_code = (ierr) \ + }, + +/* + * Set one implementation defined bit in ERRCTLR + * + * This macro will be used to collect all defined ERR_CTRL bits for each node + * defined by _UNCORR_RAS_ERROR_LIST macro. + */ +#define DEFINE_ENABLE_RAS_BIT(unit, ras_bit, ierr, msg) \ + do { \ + val |= (1ULL << ras_bit##U); \ + } while (0); + +/* Represent one RAS node with 0 or more error bits (ERR_CTLR) enabled */ +#define DEFINE_ONE_RAS_NODE(node) \ +static const struct ras_error node##_uncorr_ras_errors[] = { \ + node##_UNCORR_RAS_ERROR_LIST(DEFINE_ONE_RAS_ERROR_MSG) \ + { \ + NULL, \ + 0U \ + }, \ +}; \ +static inline uint64_t node##_err_ctrl(void) \ +{ \ + uint64_t val = 0ULL; \ + node##_UNCORR_RAS_ERROR_LIST(DEFINE_ENABLE_RAS_BIT) \ + return val; \ +} + +#define DEFINE_ONE_RAS_AUX_DATA(node) \ + { \ + .error_records = node##_uncorr_ras_errors, \ + .err_ctrl = &node##_err_ctrl \ + }, + +#define PER_CORE_RAS_NODE_LIST(X) \ + X(IFU) \ + X(JSR_RET) \ + X(JSR_MTS) \ + X(LSD_STQ) \ + X(LSD_DCC) \ + X(LSD_L1HPF) + +#define PER_CORE_RAS_GROUP_NODES PER_CORE_RAS_NODE_LIST(DEFINE_ONE_RAS_AUX_DATA) + +#define PER_CLUSTER_RAS_NODE_LIST(X) \ + X(L2) \ + X(CLUSTER_CLOCKS) \ + X(MMU) + +#define PER_CLUSTER_RAS_GROUP_NODES PER_CLUSTER_RAS_NODE_LIST(DEFINE_ONE_RAS_AUX_DATA) + +#define SCF_L3_BANK_RAS_NODE_LIST(X) X(L3) + +/* we have 4 SCF_L3 nodes:3*256 + L3_Bank_ID(0-3) */ +#define SCF_L3_BANK_RAS_GROUP_NODES \ + SCF_L3_BANK_RAS_NODE_LIST(DEFINE_ONE_RAS_AUX_DATA) \ + SCF_L3_BANK_RAS_NODE_LIST(DEFINE_ONE_RAS_AUX_DATA) \ + SCF_L3_BANK_RAS_NODE_LIST(DEFINE_ONE_RAS_AUX_DATA) \ + SCF_L3_BANK_RAS_NODE_LIST(DEFINE_ONE_RAS_AUX_DATA) + +#define CCPLEX_RAS_NODE_LIST(X) \ + X(CCPMU) \ + X(SCF_IOB) \ + X(SCF_SNOC) \ + X(SCF_CTU) \ + X(CMU_CLOCKS) + +#define CCPLEX_RAS_GROUP_NODES CCPLEX_RAS_NODE_LIST(DEFINE_ONE_RAS_AUX_DATA) + +#endif /* TEGRA194_RAS_PRIVATE */ diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h index f72c9cf3c..a6d8e6886 100644 --- a/plat/nvidia/tegra/include/tegra_private.h +++ b/plat/nvidia/tegra/include/tegra_private.h @@ -89,7 +89,7 @@ int32_t plat_lock_cpu_vectors(void); /* Declarations for tegra_fiq_glue.c */ void tegra_fiq_handler_setup(void); -int tegra_fiq_get_intr_context(void); +int32_t tegra_fiq_get_intr_context(void); void tegra_fiq_set_ns_entrypoint(uint64_t entrypoint); /* Declarations for tegra_security.c */ @@ -157,4 +157,8 @@ int plat_sip_handler(uint32_t smc_fid, void *handle, uint64_t flags); +#if RAS_EXTENSION +void tegra194_ras_enable(void); +#endif + #endif /* TEGRA_PRIVATE_H */ diff --git a/plat/nvidia/tegra/soc/t194/plat_ras.c b/plat/nvidia/tegra/soc/t194/plat_ras.c new file mode 100644 index 000000000..f9ebb37e4 --- /dev/null +++ b/plat/nvidia/tegra/soc/t194/plat_ras.c @@ -0,0 +1,287 @@ +/* + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/* + * ERRFR bits[63:32], it indicates supported RAS errors which can be enabled + * by setting corresponding bits in ERRCTLR + */ +#define ERR_FR_EN_BITS_MASK 0xFFFFFFFF00000000ULL + +/* bakery lock for platform RAS handler. */ +static DEFINE_BAKERY_LOCK(ras_handler_lock); +#define ras_lock() bakery_lock_get(&ras_handler_lock) +#define ras_unlock() bakery_lock_release(&ras_handler_lock) + +/* + * Function to handle an External Abort received at EL3. + * This function is invoked by RAS framework. + */ +static void tegra194_ea_handler(unsigned int ea_reason, uint64_t syndrome, + void *cookie, void *handle, uint64_t flags) +{ + int32_t ret; + + ras_lock(); + + ERROR("exception reason=%u syndrome=0x%llx on 0x%lx at EL3.\n", + ea_reason, syndrome, read_mpidr_el1()); + + /* Call RAS EA handler */ + ret = ras_ea_handler(ea_reason, syndrome, cookie, handle, flags); + if (ret != 0) { + ERROR("RAS error handled!\n"); + ret = sdei_dispatch_event(TEGRA_SDEI_EP_EVENT_0 + + plat_my_core_pos()); + if (ret != 0) + ERROR("sdei_dispatch_event returned %d\n", ret); + } else { + ERROR("Not a RAS error!\n"); + } + + ras_unlock(); +} + +/* Function to enable uncorrectable errors as External abort (SError) */ +void tegra194_ras_enable(void) +{ + VERBOSE("%s\n", __func__); + + /* skip RAS enablement if not a silicon platform. */ + if (!tegra_platform_is_silicon()) { + return; + } + + /* + * Iterate for each group(num_idx ERRSELRs starting from idx_start) + * use normal for loop instead of for_each_err_record_info to get rid + * of MISRA noise.. + */ + for (uint32_t i = 0U; i < err_record_mappings.num_err_records; i++) { + + const struct err_record_info *info = &err_record_mappings.err_records[i]; + + uint32_t idx_start = info->sysreg.idx_start; + uint32_t num_idx = info->sysreg.num_idx; + const struct ras_aux_data *aux_data = (const struct ras_aux_data *)info->aux_data; + + assert(aux_data != NULL); + + for (uint32_t j = 0; j < num_idx; j++) { + uint64_t err_ctrl = 0ULL; + + /* enable SError reporting for uncorrectable error */ + ERR_CTLR_ENABLE_FIELD(err_ctrl, UE); + ERR_CTLR_ENABLE_FIELD(err_ctrl, ED); + + /* + * Catch error if something wrong with the RAS aux data + * record table. + */ + assert(aux_data[j].err_ctrl != NULL); + + /* enable the specified errors */ + err_ctrl |= aux_data[j].err_ctrl(); + + /* Write to ERRSELR_EL1 to select the error record */ + ser_sys_select_record(idx_start + j); + + /* enable specified errors */ + write_erxctlr_el1(err_ctrl); + + /* + * Check if all the bit settings have been enabled to detect + * uncorrected/corrected errors, if not assert. + */ + assert(read_erxctlr_el1() == err_ctrl); + } + } +} + +/* Function to probe an error from error record group. */ +static int32_t tegra194_ras_record_probe(const struct err_record_info *info, + int *probe_data) +{ + /* Skip probing if not a silicon platform */ + if (!tegra_platform_is_silicon()) { + return 0; + } + + return ser_probe_sysreg(info->sysreg.idx_start, info->sysreg.num_idx, probe_data); +} + +/* Function to handle error from one given node */ +static int32_t tegra194_ras_node_handler(const struct ras_error *errors, uint64_t status) +{ + bool found = false; + uint32_t ierr = (uint32_t)ERR_STATUS_GET_FIELD(status, IERR); + uint32_t serr = (uint32_t)ERR_STATUS_GET_FIELD(status, SERR); + + /* IERR to error message */ + for (uint32_t i = 0; errors[i].error_msg != NULL; i++) { + if (ierr == errors[i].error_code) { + ERROR("IERR = %s(0x%x)\n", + errors[i].error_msg, errors[i].error_code); + found = true; + break; + } + } + if (!found) { + ERROR("unknown IERR: 0x%x\n", ierr); + } + + ERROR("SERR = %s(0x%x)\n", ras_serr_to_str(serr), serr); + + /* Write to clear reported errors. */ + write_erxstatus_el1(status); + + return 0; +} + +/* Function to handle one error node from an error record group. */ +static int32_t tegra194_ras_record_handler(const struct err_record_info *info, + int probe_data, const struct err_handler_data *const data) +{ + uint32_t num_idx = info->sysreg.num_idx; + uint32_t idx_start = info->sysreg.idx_start; + const struct ras_aux_data *aux_data = info->aux_data; + + uint64_t status = 0ULL; + + VERBOSE("%s\n", __func__); + + assert(probe_data >= 0); + assert((uint32_t)probe_data < num_idx); + + uint32_t offset = (uint32_t)probe_data; + const struct ras_error *errors = aux_data[offset].error_records; + + assert(errors != NULL); + + /* Write to ERRSELR_EL1 to select the error record */ + ser_sys_select_record(idx_start + offset); + + /* Retrieve status register from the error record */ + status = read_erxstatus_el1(); + + assert(ERR_STATUS_GET_FIELD(status, V) != 0U); + assert(ERR_STATUS_GET_FIELD(status, UE) != 0U); + + return tegra194_ras_node_handler(errors, status); +} + + +/* Instantiate RAS nodes */ +PER_CORE_RAS_NODE_LIST(DEFINE_ONE_RAS_NODE) +PER_CLUSTER_RAS_NODE_LIST(DEFINE_ONE_RAS_NODE) +SCF_L3_BANK_RAS_NODE_LIST(DEFINE_ONE_RAS_NODE) +CCPLEX_RAS_NODE_LIST(DEFINE_ONE_RAS_NODE) + +/* Instantiate RAS node groups */ +static struct ras_aux_data per_core_ras_group[] = { + PER_CORE_RAS_GROUP_NODES +}; + +static struct ras_aux_data per_cluster_ras_group[] = { + PER_CLUSTER_RAS_GROUP_NODES +}; + +static struct ras_aux_data scf_l3_ras_group[] = { + SCF_L3_BANK_RAS_GROUP_NODES +}; + +static struct ras_aux_data ccplex_ras_group[] = { + CCPLEX_RAS_GROUP_NODES +}; + +/* + * We have same probe and handler for each error record group, use a macro to + * simply the record definition. + */ +#define ADD_ONE_ERR_GROUP(errselr_start, group) \ + ERR_RECORD_SYSREG_V1((errselr_start), (uint32_t)ARRAY_SIZE((group)), \ + &tegra194_ras_record_probe, \ + &tegra194_ras_record_handler, (group)) + +/* RAS error record group information */ +static struct err_record_info carmel_ras_records[] = { + /* + * Per core ras error records + * ERRSELR starts from 0*256 + Logical_CPU_ID*16 + 0 to + * 0*256 + Logical_CPU_ID*16 + 5 for each group. + * 8 cores/groups, 6 * 8 nodes in total. + */ + ADD_ONE_ERR_GROUP(0x000, per_core_ras_group), + ADD_ONE_ERR_GROUP(0x010, per_core_ras_group), + ADD_ONE_ERR_GROUP(0x020, per_core_ras_group), + ADD_ONE_ERR_GROUP(0x030, per_core_ras_group), + ADD_ONE_ERR_GROUP(0x040, per_core_ras_group), + ADD_ONE_ERR_GROUP(0x050, per_core_ras_group), + ADD_ONE_ERR_GROUP(0x060, per_core_ras_group), + ADD_ONE_ERR_GROUP(0x070, per_core_ras_group), + + /* + * Per cluster ras error records + * ERRSELR starts from 2*256 + Logical_Cluster_ID*16 + 0 to + * 2*256 + Logical_Cluster_ID*16 + 3. + * 4 clusters/groups, 3 * 4 nodes in total. + */ + ADD_ONE_ERR_GROUP(0x200, per_cluster_ras_group), + ADD_ONE_ERR_GROUP(0x210, per_cluster_ras_group), + ADD_ONE_ERR_GROUP(0x220, per_cluster_ras_group), + ADD_ONE_ERR_GROUP(0x230, per_cluster_ras_group), + + /* + * SCF L3_Bank ras error records + * ERRSELR: 3*256 + L3_Bank_ID, L3_Bank_ID: 0-3 + * 1 groups, 4 nodes in total. + */ + ADD_ONE_ERR_GROUP(0x300, scf_l3_ras_group), + + /* + * CCPLEX ras error records + * ERRSELR: 4*256 + Unit_ID, Unit_ID: 0 - 4 + * 1 groups, 5 nodes in total. + */ + ADD_ONE_ERR_GROUP(0x400, ccplex_ras_group), +}; + +REGISTER_ERR_RECORD_INFO(carmel_ras_records); + +/* dummy RAS interrupt */ +static struct ras_interrupt carmel_ras_interrupts[] = {}; +REGISTER_RAS_INTERRUPTS(carmel_ras_interrupts); + +/******************************************************************************* + * RAS handler for the platform + ******************************************************************************/ +void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie, + void *handle, uint64_t flags) +{ +#if RAS_EXTENSION + tegra194_ea_handler(ea_reason, syndrome, cookie, handle, flags); +#else + ERROR("Unhandled External Abort received on 0x%llx at EL3!\n", + read_mpidr_el1()); + ERROR(" exception reason=%u syndrome=0x%lx\n", ea_reason, syndrome); + panic(); +#endif +} diff --git a/plat/nvidia/tegra/soc/t194/plat_setup.c b/plat/nvidia/tegra/soc/t194/plat_setup.c index 5d6c60b6c..399aebb05 100644 --- a/plat/nvidia/tegra/soc/t194/plat_setup.c +++ b/plat/nvidia/tegra/soc/t194/plat_setup.c @@ -208,6 +208,11 @@ void plat_early_platform_setup(void) /* sanity check MCE firmware compatibility */ mce_verify_firmware_version(); +#if RAS_EXTENSION + /* Enable Uncorrectable RAS error */ + tegra194_ras_enable(); +#endif + /* * Program XUSB STREAMIDs * ====================== diff --git a/plat/nvidia/tegra/soc/t194/platform_t194.mk b/plat/nvidia/tegra/soc/t194/platform_t194.mk index c02128ccc..d7d15f556 100644 --- a/plat/nvidia/tegra/soc/t194/platform_t194.mk +++ b/plat/nvidia/tegra/soc/t194/platform_t194.mk @@ -30,6 +30,10 @@ $(eval $(call add_define,MAX_XLAT_TABLES)) MAX_MMAP_REGIONS := 30 $(eval $(call add_define,MAX_MMAP_REGIONS)) +# enable RAS handling +HANDLE_EA_EL3_FIRST := 1 +RAS_EXTENSION := 1 + # platform files PLAT_INCLUDES += -Iplat/nvidia/tegra/include/t194 \ -I${SOC_DIR}/drivers/include @@ -56,3 +60,10 @@ BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \ ifeq (${ENABLE_CONSOLE_SPE},1) BL31_SOURCES += ${COMMON_DIR}/drivers/spe/shared_console.S endif + +# RAS sources +ifeq (${RAS_EXTENSION},1) +BL31_SOURCES += lib/extensions/ras/std_err_record.c \ + lib/extensions/ras/ras_common.c \ + ${SOC_DIR}/plat_ras.c +endif -- cgit v1.2.3 From 0d8511953e19a5da80ac1a0ed9ec8e76b57a33a8 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Thu, 21 Mar 2019 08:23:05 -0700 Subject: Tegra194: SiP: clear RAS corrected error records This patch introduces a function ID to clear all the RAS error records for corrected errors. Per latest requirement, ARM RAS corrected errors will be reported to lower ELs via interrupts and cleared via SMC. This patch provides required function to clear RAS error status. This patch also sets up all required RAS Corrected errors in order to route RAS corrected errors to lower ELs. Change-Id: I554ba1d0797b736835aa27824782703682c91e51 Signed-off-by: Varun Wadekar Signed-off-by: David Pu --- plat/nvidia/tegra/include/tegra_private.h | 1 + .../tegra/soc/t194/drivers/include/mce_private.h | 2 + plat/nvidia/tegra/soc/t194/drivers/mce/mce.c | 8 ++ plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c | 12 ++ plat/nvidia/tegra/soc/t194/plat_ras.c | 145 ++++++++++++++++----- plat/nvidia/tegra/soc/t194/plat_sip_calls.c | 11 ++ 6 files changed, 149 insertions(+), 30 deletions(-) diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h index a6d8e6886..c181c3618 100644 --- a/plat/nvidia/tegra/include/tegra_private.h +++ b/plat/nvidia/tegra/include/tegra_private.h @@ -159,6 +159,7 @@ int plat_sip_handler(uint32_t smc_fid, #if RAS_EXTENSION void tegra194_ras_enable(void); +void tegra194_ras_corrected_err_clear(void); #endif #endif /* TEGRA_PRIVATE_H */ diff --git a/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h b/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h index 1fe3aad39..6dafeb246 100644 --- a/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h +++ b/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h @@ -58,6 +58,7 @@ int32_t nvg_roc_clean_cache_trbits(void); void nvg_enable_strict_checking_mode(void); void nvg_system_shutdown(void); void nvg_system_reboot(void); +void nvg_clear_hsm_corr_status(void); /* declarations for assembly functions */ void nvg_set_request_data(uint64_t req, uint64_t data); @@ -71,5 +72,6 @@ uint64_t nvg_cache_inval_all(void); void mce_enable_strict_checking(void); void mce_system_shutdown(void); void mce_system_reboot(void); +void mce_clear_hsm_corr_status(void); #endif /* MCE_PRIVATE_H */ diff --git a/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c b/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c index 7edd7a09e..4663a3d27 100644 --- a/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c +++ b/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c @@ -234,3 +234,11 @@ void mce_system_reboot(void) { nvg_system_reboot(); } + +/******************************************************************************* + * Handler to clear CCPLEX->HSM correctable RAS error signal. + ******************************************************************************/ +void mce_clear_hsm_corr_status(void) +{ + nvg_clear_hsm_corr_status(); +} diff --git a/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c b/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c index ef740a143..fdf94292c 100644 --- a/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c +++ b/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c @@ -236,3 +236,15 @@ void nvg_system_shutdown(void) nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_SHUTDOWN, (uint64_t)TEGRA_NVG_SHUTDOWN); } + +/* + * Request to clear CCPLEX->HSM correctable error signal. + * NVGDATA[1]: A write of 1 clears the CCPLEX->HSM correctable error signal, + * A write of 0 has no effect. + */ +void nvg_clear_hsm_corr_status(void) +{ + nvg_hsm_error_ctrl_channel_t status = { .bits = { .corr = 1U, }, }; + + nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_HSM_ERROR_CTRL, status.flat); +} diff --git a/plat/nvidia/tegra/soc/t194/plat_ras.c b/plat/nvidia/tegra/soc/t194/plat_ras.c index f9ebb37e4..eb896a4af 100644 --- a/plat/nvidia/tegra/soc/t194/plat_ras.c +++ b/plat/nvidia/tegra/soc/t194/plat_ras.c @@ -60,7 +60,12 @@ static void tegra194_ea_handler(unsigned int ea_reason, uint64_t syndrome, ras_unlock(); } -/* Function to enable uncorrectable errors as External abort (SError) */ +/* + * Function to enable all supported RAS error report. + * + * Uncorrected errors are set to report as External abort (SError) + * Corrected errors are set to report as interrupt. + */ void tegra194_ras_enable(void) { VERBOSE("%s\n", __func__); @@ -86,11 +91,15 @@ void tegra194_ras_enable(void) assert(aux_data != NULL); for (uint32_t j = 0; j < num_idx; j++) { - uint64_t err_ctrl = 0ULL; - /* enable SError reporting for uncorrectable error */ - ERR_CTLR_ENABLE_FIELD(err_ctrl, UE); - ERR_CTLR_ENABLE_FIELD(err_ctrl, ED); + /* ERRCTLR register value. */ + uint64_t err_ctrl = 0ULL; + /* all supported errors for this node. */ + uint64_t err_fr; + /* uncorrectable errors */ + uint64_t uncorr_errs; + /* correctable errors */ + uint64_t corr_errs; /* * Catch error if something wrong with the RAS aux data @@ -98,13 +107,37 @@ void tegra194_ras_enable(void) */ assert(aux_data[j].err_ctrl != NULL); - /* enable the specified errors */ - err_ctrl |= aux_data[j].err_ctrl(); - - /* Write to ERRSELR_EL1 to select the error record */ + /* + * Write to ERRSELR_EL1 to select the RAS error node. + * Always program this at first to select corresponding + * RAS node before any other RAS register r/w. + */ ser_sys_select_record(idx_start + j); - /* enable specified errors */ + err_fr = read_erxfr_el1() & ERR_FR_EN_BITS_MASK; + uncorr_errs = aux_data[j].err_ctrl(); + corr_errs = ~uncorr_errs & err_fr; + + /* enable error reporting */ + ERR_CTLR_ENABLE_FIELD(err_ctrl, ED); + + /* enable SError reporting for uncorrectable errors */ + if ((uncorr_errs & err_fr) != 0ULL) { + ERR_CTLR_ENABLE_FIELD(err_ctrl, UE); + } + + /* generate interrupt for corrected errors. */ + if (corr_errs != 0ULL) { + ERR_CTLR_ENABLE_FIELD(err_ctrl, CFI); + } + + /* enable the supported errors */ + err_ctrl |= err_fr; + + VERBOSE("errselr_el1:0x%x, erxfr:0x%llx, err_ctrl:0x%llx\n", + idx_start + j, err_fr, err_ctrl); + + /* enable specified errors, or set to 0 if no supported error */ write_erxctlr_el1(err_ctrl); /* @@ -116,6 +149,42 @@ void tegra194_ras_enable(void) } } +/* + * Function to clear RAS ERRSTATUS for corrected RAS error. + * This function ignores any new RAS error signaled during clearing; it is not + * multi-core safe(no ras_lock is taken to reduce overhead). + */ +void tegra194_ras_corrected_err_clear(void) +{ + uint64_t clear_ce_status = 0ULL; + + ERR_STATUS_SET_FIELD(clear_ce_status, AV, 0x1UL); + ERR_STATUS_SET_FIELD(clear_ce_status, V, 0x1UL); + ERR_STATUS_SET_FIELD(clear_ce_status, OF, 0x1UL); + ERR_STATUS_SET_FIELD(clear_ce_status, MV, 0x1UL); + ERR_STATUS_SET_FIELD(clear_ce_status, CE, 0x3UL); + + for (uint32_t i = 0U; i < err_record_mappings.num_err_records; i++) { + + const struct err_record_info *info = &err_record_mappings.err_records[i]; + uint32_t idx_start = info->sysreg.idx_start; + uint32_t num_idx = info->sysreg.num_idx; + + for (uint32_t j = 0U; j < num_idx; j++) { + + uint64_t status; + uint32_t err_idx = idx_start + j; + + write_errselr_el1(err_idx); + status = read_erxstatus_el1(); + + if (ERR_STATUS_GET_FIELD(status, CE) != 0U) { + write_erxstatus_el1(clear_ce_status); + } + } + } +} + /* Function to probe an error from error record group. */ static int32_t tegra194_ras_record_probe(const struct err_record_info *info, int *probe_data) @@ -129,26 +198,43 @@ static int32_t tegra194_ras_record_probe(const struct err_record_info *info, } /* Function to handle error from one given node */ -static int32_t tegra194_ras_node_handler(const struct ras_error *errors, uint64_t status) +static int32_t tegra194_ras_node_handler(uint32_t errselr, + const struct ras_error *errors, uint64_t status) { bool found = false; uint32_t ierr = (uint32_t)ERR_STATUS_GET_FIELD(status, IERR); uint32_t serr = (uint32_t)ERR_STATUS_GET_FIELD(status, SERR); - /* IERR to error message */ - for (uint32_t i = 0; errors[i].error_msg != NULL; i++) { - if (ierr == errors[i].error_code) { - ERROR("IERR = %s(0x%x)\n", - errors[i].error_msg, errors[i].error_code); - found = true; - break; - } - } - if (!found) { - ERROR("unknown IERR: 0x%x\n", ierr); + /* not a valid error. */ + if (ERR_STATUS_GET_FIELD(status, V) == 0U) { + return 0; } - ERROR("SERR = %s(0x%x)\n", ras_serr_to_str(serr), serr); + /* Print uncorrectable errror information. */ + if (ERR_STATUS_GET_FIELD(status, UE) != 0U) { + + /* IERR to error message */ + for (uint32_t i = 0; errors[i].error_msg != NULL; i++) { + if (ierr == errors[i].error_code) { + ERROR("ERRSELR_EL1:0x%x\n, IERR = %s(0x%x)\n", + errselr, errors[i].error_msg, + errors[i].error_code); + found = true; + break; + } + } + + if (!found) { + ERROR("unknown uncorrectable eror, " + "ERRSELR_EL1:0x%x, IERR: 0x%x\n", errselr, ierr); + } + + ERROR("SERR = %s(0x%x)\n", ras_serr_to_str(serr), serr); + } else { + /* For corrected error, simply clear it. */ + VERBOSE("corrected RAS error is cleared: ERRSELR_EL1:0x%x, " + "IERR:0x%x, SERR:0x%x\n", errselr, ierr, serr); + } /* Write to clear reported errors. */ write_erxstatus_el1(status); @@ -158,11 +244,13 @@ static int32_t tegra194_ras_node_handler(const struct ras_error *errors, uint64_ /* Function to handle one error node from an error record group. */ static int32_t tegra194_ras_record_handler(const struct err_record_info *info, - int probe_data, const struct err_handler_data *const data) + int probe_data, const struct err_handler_data *const data __unused) { uint32_t num_idx = info->sysreg.num_idx; uint32_t idx_start = info->sysreg.idx_start; const struct ras_aux_data *aux_data = info->aux_data; + const struct ras_error *errors; + uint32_t offset; uint64_t status = 0ULL; @@ -171,8 +259,8 @@ static int32_t tegra194_ras_record_handler(const struct err_record_info *info, assert(probe_data >= 0); assert((uint32_t)probe_data < num_idx); - uint32_t offset = (uint32_t)probe_data; - const struct ras_error *errors = aux_data[offset].error_records; + offset = (uint32_t)probe_data; + errors = aux_data[offset].error_records; assert(errors != NULL); @@ -182,10 +270,7 @@ static int32_t tegra194_ras_record_handler(const struct err_record_info *info, /* Retrieve status register from the error record */ status = read_erxstatus_el1(); - assert(ERR_STATUS_GET_FIELD(status, V) != 0U); - assert(ERR_STATUS_GET_FIELD(status, UE) != 0U); - - return tegra194_ras_node_handler(errors, status); + return tegra194_ras_node_handler(idx_start + offset, errors, status); } diff --git a/plat/nvidia/tegra/soc/t194/plat_sip_calls.c b/plat/nvidia/tegra/soc/t194/plat_sip_calls.c index 884762de7..a3f996d45 100644 --- a/plat/nvidia/tegra/soc/t194/plat_sip_calls.c +++ b/plat/nvidia/tegra/soc/t194/plat_sip_calls.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -23,6 +24,7 @@ * Tegra194 SiP SMCs ******************************************************************************/ #define TEGRA_SIP_GET_SMMU_PER 0xC200FF00U +#define TEGRA_SIP_CLEAR_RAS_CORRECTED_ERRORS 0xC200FF01U /******************************************************************************* * This function is responsible for handling all T194 SiP calls @@ -69,6 +71,15 @@ int32_t plat_sip_handler(uint32_t smc_fid, break; +#if RAS_EXTENSION + case TEGRA_SIP_CLEAR_RAS_CORRECTED_ERRORS: + /* clear all RAS error records for corrected errors at first. */ + tegra194_ras_corrected_err_clear(); + /* clear HSM corrected error status. */ + mce_clear_hsm_corr_status(); + break; +#endif + default: ret = -ENOTSUP; break; -- cgit v1.2.3 From fbc44bd1bbbafe01848afd009d507b595b264b5f Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Fri, 12 Jun 2020 10:11:28 -0700 Subject: Prevent RAS register access from lower ELs This patch adds a build config 'RAS_TRAP_LOWER_EL_ERR_ACCESS' to set SCR_EL3.TERR during CPU boot. This bit enables trapping RAS register accesses from EL1 or EL2 to EL3. RAS_TRAP_LOWER_EL_ERR_ACCESS is disabled by default. Signed-off-by: Varun Wadekar Change-Id: Ifb0fb0afedea7dd2a29a0b0491a1161ecd241438 --- Makefile | 2 ++ docs/components/ras.rst | 3 ++- docs/getting_started/build-options.rst | 4 ++++ include/arch/aarch64/arch.h | 1 + lib/el3_runtime/aarch64/context_mgmt.c | 8 ++++++++ make_helpers/defaults.mk | 3 +++ 6 files changed, 20 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index a0d2ae066..bc5604be2 100644 --- a/Makefile +++ b/Makefile @@ -900,6 +900,7 @@ $(eval $(call assert_boolean,USE_SPINLOCK_CAS)) $(eval $(call assert_boolean,ENCRYPT_BL31)) $(eval $(call assert_boolean,ENCRYPT_BL32)) $(eval $(call assert_boolean,ERRATA_SPECULATIVE_AT)) +$(eval $(call assert_boolean,RAS_TRAP_LOWER_EL_ERR_ACCESS)) $(eval $(call assert_numeric,ARM_ARCH_MAJOR)) $(eval $(call assert_numeric,ARM_ARCH_MINOR)) @@ -979,6 +980,7 @@ $(eval $(call add_define,BL2_IN_XIP_MEM)) $(eval $(call add_define,BL2_INV_DCACHE)) $(eval $(call add_define,USE_SPINLOCK_CAS)) $(eval $(call add_define,ERRATA_SPECULATIVE_AT)) +$(eval $(call add_define,RAS_TRAP_LOWER_EL_ERR_ACCESS)) ifeq (${SANITIZE_UB},trap) $(eval $(call add_define,MONITOR_TRAPS)) diff --git a/docs/components/ras.rst b/docs/components/ras.rst index 3d81f17e9..86529d740 100644 --- a/docs/components/ras.rst +++ b/docs/components/ras.rst @@ -32,7 +32,8 @@ introduced by the RAS extensions. The build option ``RAS_EXTENSION`` when set to ``1`` includes the RAS in run time firmware; ``EL3_EXCEPTION_HANDLING`` and ``HANDLE_EA_EL3_FIRST`` must also -be set ``1``. +be set ``1``. ``RAS_TRAP_LOWER_EL_ERR_ACCESS`` controls the access to the RAS +error record registers from lower ELs. .. _ras-figure: diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 920f934af..f207886fb 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -707,6 +707,10 @@ Common build options | 1530924 | Cortex-A53 | +---------+--------------+ +- ``RAS_TRAP_LOWER_EL_ERR_ACCESS``: This flag enables/disables the SCR_EL3.TERR + bit, to trap access to the RAS ERR and RAS ERX registers from lower ELs. + This flag is disabled by default. + GICv3 driver options -------------------- diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index 10fe926ea..90569c3cf 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -342,6 +342,7 @@ #define SCR_EEL2_BIT (U(1) << 18) #define SCR_API_BIT (U(1) << 17) #define SCR_APK_BIT (U(1) << 16) +#define SCR_TERR_BIT (U(1) << 15) #define SCR_TWE_BIT (U(1) << 13) #define SCR_TWI_BIT (U(1) << 12) #define SCR_ST_BIT (U(1) << 11) diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c index 53b4ea3e3..f4a34bfaa 100644 --- a/lib/el3_runtime/aarch64/context_mgmt.c +++ b/lib/el3_runtime/aarch64/context_mgmt.c @@ -108,6 +108,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 RAS_TRAP_LOWER_EL_ERR_ACCESS + /* + * SCR_EL3.TERR: Trap Error record accesses. Accesses to the RAS ERR + * and RAS ERX registers from EL1 and EL2 are trapped to EL3. + */ + scr_el3 |= SCR_TERR_BIT; +#endif + #if !HANDLE_EA_EL3_FIRST /* * SCR_EL3.EA: Do not route External Abort and SError Interrupt External diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index 585f06fcc..6db228f2d 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -302,3 +302,6 @@ SUPPORT_STACK_MEMTAG := no # Select workaround for AT speculative behaviour. ERRATA_SPECULATIVE_AT := 0 + +# Trap RAS error record access from lower EL +RAS_TRAP_LOWER_EL_ERR_ACCESS := 0 -- cgit v1.2.3 From fba5cdc69569a5b62cbd4303b91bb2d41d335566 Mon Sep 17 00:00:00 2001 From: David Pu Date: Thu, 16 May 2019 17:20:27 -0700 Subject: Tegra194: ras: verbose prints for SErrors This patch provides verbose prints for RAS SErrors handled by the firmware, for improved debugging. Change-Id: Iaad8d183054d884f606dc4621da2cc6b2375bcf9 Signed-off-by: David Pu Signed-off-by: Varun Wadekar --- .../tegra/include/t194/tegra194_ras_private.h | 3 + plat/nvidia/tegra/soc/t194/plat_ras.c | 68 ++++++++++++++++++---- 2 files changed, 60 insertions(+), 11 deletions(-) diff --git a/plat/nvidia/tegra/include/t194/tegra194_ras_private.h b/plat/nvidia/tegra/include/t194/tegra194_ras_private.h index c867b9d2b..336461af3 100644 --- a/plat/nvidia/tegra/include/t194/tegra194_ras_private.h +++ b/plat/nvidia/tegra/include/t194/tegra194_ras_private.h @@ -18,6 +18,8 @@ struct ras_error { /* RAS error node-specific auxiliary data */ struct ras_aux_data { + /* name for current RAS node. */ + const char *name; /* point to null-terminated ras_error array to convert error code to msg. */ const struct ras_error *error_records; /* @@ -218,6 +220,7 @@ static inline uint64_t node##_err_ctrl(void) \ #define DEFINE_ONE_RAS_AUX_DATA(node) \ { \ + .name = #node, \ .error_records = node##_uncorr_ras_errors, \ .err_ctrl = &node##_err_ctrl \ }, diff --git a/plat/nvidia/tegra/soc/t194/plat_ras.c b/plat/nvidia/tegra/soc/t194/plat_ras.c index eb896a4af..54c2924c7 100644 --- a/plat/nvidia/tegra/soc/t194/plat_ras.c +++ b/plat/nvidia/tegra/soc/t194/plat_ras.c @@ -42,8 +42,8 @@ static void tegra194_ea_handler(unsigned int ea_reason, uint64_t syndrome, ras_lock(); - ERROR("exception reason=%u syndrome=0x%llx on 0x%lx at EL3.\n", - ea_reason, syndrome, read_mpidr_el1()); + ERROR("MPIDR 0x%lx: exception reason=%u syndrome=0x%llx\n", + read_mpidr(), ea_reason, syndrome); /* Call RAS EA handler */ ret = ras_ea_handler(ea_reason, syndrome, cookie, handle, flags); @@ -198,47 +198,90 @@ static int32_t tegra194_ras_record_probe(const struct err_record_info *info, } /* Function to handle error from one given node */ -static int32_t tegra194_ras_node_handler(uint32_t errselr, +static int32_t tegra194_ras_node_handler(uint32_t errselr, const char *name, const struct ras_error *errors, uint64_t status) { bool found = false; uint32_t ierr = (uint32_t)ERR_STATUS_GET_FIELD(status, IERR); uint32_t serr = (uint32_t)ERR_STATUS_GET_FIELD(status, SERR); + uint64_t val = 0; /* not a valid error. */ if (ERR_STATUS_GET_FIELD(status, V) == 0U) { return 0; } + ERR_STATUS_SET_FIELD(val, V, 1); + + /* 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); + /* Print uncorrectable errror information. */ if (ERR_STATUS_GET_FIELD(status, UE) != 0U) { + ERR_STATUS_SET_FIELD(val, UE, 1); + ERR_STATUS_SET_FIELD(val, UET, 1); + /* IERR to error message */ for (uint32_t i = 0; errors[i].error_msg != NULL; i++) { if (ierr == errors[i].error_code) { - ERROR("ERRSELR_EL1:0x%x\n, IERR = %s(0x%x)\n", - errselr, errors[i].error_msg, - errors[i].error_code); + ERROR("\tIERR = %s: 0x%x\n", + errors[i].error_msg, ierr); + found = true; break; } } if (!found) { - ERROR("unknown uncorrectable eror, " - "ERRSELR_EL1:0x%x, IERR: 0x%x\n", errselr, ierr); + ERROR("\tUnknown IERR: 0x%x\n", ierr); + } + + ERROR("SERR = %s: 0x%x\n", ras_serr_to_str(serr), serr); + + /* Overflow, multiple errors have been detected. */ + if (ERR_STATUS_GET_FIELD(status, OF) != 0U) { + ERROR("\tOverflow (there may be more errors) - " + "Uncorrectable\n"); + ERR_STATUS_SET_FIELD(val, OF, 1); + } + + ERROR("\tUncorrectable (this is fatal)\n"); + + /* Miscellaneous Register Valid. */ + if (ERR_STATUS_GET_FIELD(status, MV) != 0U) { + ERROR("\tMISC0 = 0x%lx\n", read_erxmisc0_el1()); + ERROR("\tMISC1 = 0x%lx\n", read_erxmisc1_el1()); + ERR_STATUS_SET_FIELD(val, MV, 1); + } + + /* Address Valid. */ + if (ERR_STATUS_GET_FIELD(status, AV) != 0U) { + ERROR("\tADDR = 0x%lx\n", read_erxaddr_el1()); + ERR_STATUS_SET_FIELD(val, AV, 1); + } + + /* Deferred error */ + if (ERR_STATUS_GET_FIELD(status, DE) != 0U) { + ERROR("\tDeferred error\n"); + ERR_STATUS_SET_FIELD(val, DE, 1); } - ERROR("SERR = %s(0x%x)\n", ras_serr_to_str(serr), serr); } else { /* For corrected error, simply clear it. */ VERBOSE("corrected RAS error is cleared: ERRSELR_EL1:0x%x, " "IERR:0x%x, SERR:0x%x\n", errselr, ierr, serr); + ERR_STATUS_SET_FIELD(val, CE, 1); } + ERROR("**************************************\n"); + /* Write to clear reported errors. */ - write_erxstatus_el1(status); + write_erxstatus_el1(val); + /* error handled */ return 0; } @@ -251,6 +294,7 @@ static int32_t tegra194_ras_record_handler(const struct err_record_info *info, const struct ras_aux_data *aux_data = info->aux_data; const struct ras_error *errors; uint32_t offset; + const char *node_name; uint64_t status = 0ULL; @@ -261,6 +305,7 @@ static int32_t tegra194_ras_record_handler(const struct err_record_info *info, offset = (uint32_t)probe_data; errors = aux_data[offset].error_records; + node_name = aux_data[offset].name; assert(errors != NULL); @@ -270,7 +315,8 @@ static int32_t tegra194_ras_record_handler(const struct err_record_info *info, /* Retrieve status register from the error record */ status = read_erxstatus_el1(); - return tegra194_ras_node_handler(idx_start + offset, errors, status); + return tegra194_ras_node_handler(idx_start + offset, node_name, + errors, status); } -- cgit v1.2.3 From 68758dd60a582fb05e472d7ceceb18fca4ea880d Mon Sep 17 00:00:00 2001 From: Manish Pandey Date: Wed, 10 Jun 2020 16:19:53 +0100 Subject: tbbr: add chain of trust for Secure Partitions with sha 44f1aa8, support for Silicon Provider(SiP) owned Secure Partition(SP) was added for dualroot CoT. This patch extends this support for tbbr CoT. Earlier tbbr CoT for SPs was left to avoid adding new image types in TBBR which could possibly be seen as deviation from specification. But with further discussions it is understood that TBBR being a *minimal* set of requirements that can be extended as long as we don't violate any of the musts, which is the case with adding SP support. Signed-off-by: Manish Pandey Change-Id: I1b9e3ebdd7d653f1fd4cc3bd910a69871b55ecbb --- drivers/auth/tbbr/tbbr_cot_bl2.c | 125 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) diff --git a/drivers/auth/tbbr/tbbr_cot_bl2.c b/drivers/auth/tbbr/tbbr_cot_bl2.c index c47bf1aca..63c18fae0 100644 --- a/drivers/auth/tbbr/tbbr_cot_bl2.c +++ b/drivers/auth/tbbr/tbbr_cot_bl2.c @@ -27,6 +27,9 @@ static unsigned char content_pk_buf[PK_DER_LEN]; static unsigned char soc_fw_config_hash_buf[HASH_DER_LEN]; static unsigned char tos_fw_config_hash_buf[HASH_DER_LEN]; static unsigned char nt_fw_config_hash_buf[HASH_DER_LEN]; +#if defined(SPD_spmd) +static unsigned char sp_pkg_hash_buf[MAX_SP_IDS][HASH_DER_LEN]; +#endif /* SPD_spmd */ static auth_param_type_desc_t non_trusted_nv_ctr = AUTH_PARAM_TYPE_DESC( AUTH_PARAM_NV_CTR, NON_TRUSTED_FW_NVCOUNTER_OID); @@ -60,6 +63,24 @@ 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); +#if defined(SPD_spmd) +static auth_param_type_desc_t sp_pkg1_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG1_HASH_OID); +static auth_param_type_desc_t sp_pkg2_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG2_HASH_OID); +static auth_param_type_desc_t sp_pkg3_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG3_HASH_OID); +static auth_param_type_desc_t sp_pkg4_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG4_HASH_OID); +static auth_param_type_desc_t sp_pkg5_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG5_HASH_OID); +static auth_param_type_desc_t sp_pkg6_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG6_HASH_OID); +static auth_param_type_desc_t sp_pkg7_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG7_HASH_OID); +static auth_param_type_desc_t sp_pkg8_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG8_HASH_OID); +#endif /* SPD_spmd */ /* * Trusted key certificate @@ -535,6 +556,99 @@ static const auth_img_desc_t nt_fw_config = { } } }; +/* Secure Partitions */ +#if defined(SPD_spmd) +static const auth_img_desc_t sp_content_cert = { + .img_id = SP_CONTENT_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 = &trusted_world_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 = &sp_pkg1_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[0], + .len = (unsigned int)HASH_DER_LEN + } + }, + [1] = { + .type_desc = &sp_pkg2_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[1], + .len = (unsigned int)HASH_DER_LEN + } + }, + [2] = { + .type_desc = &sp_pkg3_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[2], + .len = (unsigned int)HASH_DER_LEN + } + }, + [3] = { + .type_desc = &sp_pkg4_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[3], + .len = (unsigned int)HASH_DER_LEN + } + }, + [4] = { + .type_desc = &sp_pkg5_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[4], + .len = (unsigned int)HASH_DER_LEN + } + }, + [5] = { + .type_desc = &sp_pkg6_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[5], + .len = (unsigned int)HASH_DER_LEN + } + }, + [6] = { + .type_desc = &sp_pkg7_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[6], + .len = (unsigned int)HASH_DER_LEN + } + }, + [7] = { + .type_desc = &sp_pkg8_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[7], + .len = (unsigned int)HASH_DER_LEN + } + } + } +}; + +DEFINE_SP_PKG(1); +DEFINE_SP_PKG(2); +DEFINE_SP_PKG(3); +DEFINE_SP_PKG(4); +DEFINE_SP_PKG(5); +DEFINE_SP_PKG(6); +DEFINE_SP_PKG(7); +DEFINE_SP_PKG(8); +#endif /* SPD_spmd */ static const auth_img_desc_t * const cot_desc[] = { [TRUSTED_BOOT_FW_CERT_ID] = &trusted_boot_fw_cert, @@ -557,6 +671,17 @@ static const auth_img_desc_t * const cot_desc[] = { [NON_TRUSTED_FW_CONTENT_CERT_ID] = &non_trusted_fw_content_cert, [BL33_IMAGE_ID] = &bl33_image, [NT_FW_CONFIG_ID] = &nt_fw_config, +#if defined(SPD_spmd) + [SP_CONTENT_CERT_ID] = &sp_content_cert, + [SP_CONTENT_CERT_ID + 1] = &sp_pkg1, + [SP_CONTENT_CERT_ID + 2] = &sp_pkg2, + [SP_CONTENT_CERT_ID + 3] = &sp_pkg3, + [SP_CONTENT_CERT_ID + 4] = &sp_pkg4, + [SP_CONTENT_CERT_ID + 5] = &sp_pkg5, + [SP_CONTENT_CERT_ID + 6] = &sp_pkg6, + [SP_CONTENT_CERT_ID + 7] = &sp_pkg7, + [SP_CONTENT_CERT_ID + 8] = &sp_pkg8, +#endif }; /* Register the CoT in the authentication module */ -- cgit v1.2.3 From 4f4fc18849c59951d294564622e36e464d913d46 Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Mon, 15 Jun 2020 15:54:12 +0200 Subject: Add Raghu Krishnamurthy as a TF-A maintainer Change-Id: I3726f42f8f3de0cd88bd77a0f9d92a710649d18c Signed-off-by: Sandrine Bailleux --- docs/about/maintainers.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst index 9d298d001..bf29186d5 100644 --- a/docs/about/maintainers.rst +++ b/docs/about/maintainers.rst @@ -43,6 +43,8 @@ Maintainers :G: `laurenw-arm`_ :M: Madhukar Pappireddy :G: `madhukar-Arm`_ +:M: Raghu Krishnamurthy +:G: `raghuncstate`_ .. _code owners: @@ -610,6 +612,7 @@ Build system .. _J-Alves: https://github.com/J-Alves .. _madhukar-Arm: https://github.com/madhukar-Arm .. _john-powell-arm: https://github.com/john-powell-arm +.. _raghuncstate: https://github.com/raghuncstate .. _Project Maintenance Process: https://developer.trustedfirmware.org/w/collaboration/project-maintenance-process/ -- cgit v1.2.3 From 158658704c8fe5c4b396d6a456946211807ef525 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Tue, 9 Jun 2020 09:09:39 +0100 Subject: plat/arm: Fix load address of TB_FW_CONFIG Load address of tb_fw_config is incorrectly mentioned in below device trees: 1. rdn1edge_fw_config.dts 2. tc0_fw_config.dts Till now, tb_fw_config load-address is not being retrieved from device tree and hence never exeprienced any issue for tc0 and rdn1edge platform. For tc0 and rdn1edge platform, Load-address of tb_fw_config should be the SRAM base address + 0x300 (size of fw_config device tree) Hence updated these platform's fw_config.dts accordingly to reflect this load address change. Change-Id: I2ef8b05d49be10767db31384329f516df11ca817 Signed-off-by: Manish V Badarkhe --- plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts | 2 +- plat/arm/board/tc0/fdts/tc0_fw_config.dts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts b/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts index 88d8e99d8..c9dee60d1 100644 --- a/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts +++ b/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts @@ -13,7 +13,7 @@ /* tb_fw_config is temporarily contained on this dtb */ tb_fw-config { - load-address = <0x0 0x80001010>; + load-address = <0x0 0x4001010>; max-size = <0x200>; id = ; }; diff --git a/plat/arm/board/tc0/fdts/tc0_fw_config.dts b/plat/arm/board/tc0/fdts/tc0_fw_config.dts index 0128f0b6f..8458e0889 100644 --- a/plat/arm/board/tc0/fdts/tc0_fw_config.dts +++ b/plat/arm/board/tc0/fdts/tc0_fw_config.dts @@ -14,7 +14,7 @@ /* tb_fw_config is temporarily contained in this dtb */ tb_fw-config { - load-address = <0x0 0x2001010>; + load-address = <0x0 0x4001010>; max-size = <0x200>; id = ; }; -- cgit v1.2.3 From 75366ccd9b757f6b4d3ef4c99e839385a9ed74f8 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Thu, 28 Nov 2019 09:13:34 +0100 Subject: drivers/scmi-msg: driver for processing scmi messages This change introduces drivers to allow a platform to create a basic SCMI service and register handlers for client request (SCMI agent) on system resources. This is the first piece of the drivers: an entry function, the SCMI base protocol support and helpers for create the response message. With this change, scmi_process_message() is the entry function to process an incoming SCMI message. The function expect the message is already copied from shared memory into secure memory. The message structure stores message reference and output buffer reference where response message shall be stored. scmi_process_message() calls the SCMI protocol driver according to the protocol ID in the message. The SCMI protocol driver will call defined platform handlers according to the message content. This change introduces only the SCMI base protocol as defined in SCMI specification v2.0 [1]. Not all the messages defined in the specification are supported. The SCMI message implementation is derived from the OP-TEE project [2] itself based on the SCP-firmware implementation [3] of the SCMI protocol server side. Link: [1] http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/DEN0056A_System_Control_and_Management_Interface.pdf Link: [2] https://github.com/OP-TEE/optee_os/commit/ae8c8068098d291e6e55744dbc237ec39fd9840a Link: [3] https://github.com/ARM-software/SCP-firmware/tree/v2.6.0 Change-Id: I639c4154a39fca60606264baf8d32452641f45e9 Signed-off-by: Etienne Carriere --- drivers/st/scmi-msg/base.c | 198 ++++++++++++++++++++++++++++++++++++++++++ drivers/st/scmi-msg/base.h | 75 ++++++++++++++++ drivers/st/scmi-msg/common.h | 120 +++++++++++++++++++++++++ drivers/st/scmi-msg/entry.c | 57 ++++++++++++ include/drivers/st/scmi-msg.h | 65 ++++++++++++++ include/drivers/st/scmi.h | 29 +++++++ 6 files changed, 544 insertions(+) create mode 100644 drivers/st/scmi-msg/base.c create mode 100644 drivers/st/scmi-msg/base.h create mode 100644 drivers/st/scmi-msg/common.h create mode 100644 drivers/st/scmi-msg/entry.c create mode 100644 include/drivers/st/scmi-msg.h create mode 100644 include/drivers/st/scmi.h diff --git a/drivers/st/scmi-msg/base.c b/drivers/st/scmi-msg/base.c new file mode 100644 index 000000000..e44bc529d --- /dev/null +++ b/drivers/st/scmi-msg/base.c @@ -0,0 +1,198 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Linaro Limited + */ +#include +#include + +#include +#include +#include +#include + +#include "common.h" + +static bool message_id_is_supported(unsigned int message_id); + +static void report_version(struct scmi_msg *msg) +{ + struct scmi_protocol_version_p2a return_values = { + .status = SCMI_SUCCESS, + .version = SCMI_PROTOCOL_VERSION_BASE, + }; + + if (msg->in_size != 0U) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void report_attributes(struct scmi_msg *msg) +{ + size_t protocol_count = plat_scmi_protocol_count(); + struct scmi_protocol_attributes_p2a return_values = { + .status = SCMI_SUCCESS, + /* Null agent count since agent discovery is not supported */ + .attributes = SCMI_BASE_PROTOCOL_ATTRIBUTES(protocol_count, 0U), + }; + + if (msg->in_size != 0U) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void report_message_attributes(struct scmi_msg *msg) +{ + struct scmi_protocol_message_attributes_a2p *in_args = (void *)msg->in; + struct scmi_protocol_message_attributes_p2a return_values = { + .status = SCMI_SUCCESS, + /* For this protocol, attributes shall be zero */ + .attributes = 0U, + }; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + if (!message_id_is_supported(in_args->message_id)) { + scmi_status_response(msg, SCMI_NOT_FOUND); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void discover_vendor(struct scmi_msg *msg) +{ + const char *name = plat_scmi_vendor_name(); + struct scmi_base_discover_vendor_p2a return_values = { + .status = SCMI_SUCCESS, + }; + + if (msg->in_size != 0U) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + COPY_NAME_IDENTIFIER(return_values.vendor_identifier, name); + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void discover_sub_vendor(struct scmi_msg *msg) +{ + const char *name = plat_scmi_sub_vendor_name(); + struct scmi_base_discover_sub_vendor_p2a return_values = { + .status = SCMI_SUCCESS, + }; + + if (msg->in_size != 0U) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + COPY_NAME_IDENTIFIER(return_values.sub_vendor_identifier, name); + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void discover_implementation_version(struct scmi_msg *msg) +{ + struct scmi_protocol_version_p2a return_values = { + .status = SCMI_SUCCESS, + .version = SCMI_IMPL_VERSION, + }; + + if (msg->in_size != 0U) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static unsigned int count_protocols_in_list(const uint8_t *protocol_list) +{ + unsigned int count = 0U; + + if (protocol_list != NULL) { + while (protocol_list[count] != 0U) { + count++; + } + } + + return count; +} + +#define MAX_PROTOCOL_IN_LIST 8U + +static void discover_list_protocols(struct scmi_msg *msg) +{ + const struct scmi_base_discover_list_protocols_a2p *a2p = NULL; + struct scmi_base_discover_list_protocols_p2a p2a = { + .status = SCMI_SUCCESS, + }; + uint8_t outargs[sizeof(p2a) + MAX_PROTOCOL_IN_LIST] = { 0U }; + const uint8_t *list = NULL; + unsigned int count = 0U; + + if (msg->in_size != sizeof(*a2p)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + assert(msg->out_size > sizeof(outargs)); + + a2p = (void *)msg->in; + + list = plat_scmi_protocol_list(msg->agent_id); + count = count_protocols_in_list(list); + if (count > a2p->skip) { + count = MIN(count - a2p->skip, MAX_PROTOCOL_IN_LIST); + } else { + count = 0U; + } + + p2a.num_protocols = count; + + memcpy(outargs, &p2a, sizeof(p2a)); + memcpy(outargs + sizeof(p2a), list + a2p->skip, count); + + scmi_write_response(msg, outargs, sizeof(outargs)); +} + +static const scmi_msg_handler_t scmi_base_handler_table[] = { + [SCMI_PROTOCOL_VERSION] = report_version, + [SCMI_PROTOCOL_ATTRIBUTES] = report_attributes, + [SCMI_PROTOCOL_MESSAGE_ATTRIBUTES] = report_message_attributes, + [SCMI_BASE_DISCOVER_VENDOR] = discover_vendor, + [SCMI_BASE_DISCOVER_SUB_VENDOR] = discover_sub_vendor, + [SCMI_BASE_DISCOVER_IMPLEMENTATION_VERSION] = + discover_implementation_version, + [SCMI_BASE_DISCOVER_LIST_PROTOCOLS] = discover_list_protocols, +}; + +static bool message_id_is_supported(unsigned int message_id) +{ + return (message_id < ARRAY_SIZE(scmi_base_handler_table)) && + (scmi_base_handler_table[message_id] != NULL); +} + +scmi_msg_handler_t scmi_msg_get_base_handler(struct scmi_msg *msg) +{ + unsigned int message_id = SPECULATION_SAFE_VALUE(msg->message_id); + + if (message_id >= ARRAY_SIZE(scmi_base_handler_table)) { + VERBOSE("Base handle not found %u\n", msg->message_id); + return NULL; + } + + return scmi_base_handler_table[message_id]; +} diff --git a/drivers/st/scmi-msg/base.h b/drivers/st/scmi-msg/base.h new file mode 100644 index 000000000..c4a9c64a4 --- /dev/null +++ b/drivers/st/scmi-msg/base.h @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Linaro Limited + */ + +#ifndef SCMI_MSG_BASE_H +#define SCMI_MSG_BASE_H + +#include + +#define SCMI_PROTOCOL_VERSION_BASE 0x20000U + +#define SCMI_DEFAULT_STRING_LENGTH 16U + +enum scmi_base_message_id { + SCMI_BASE_DISCOVER_VENDOR = 0x003, + SCMI_BASE_DISCOVER_SUB_VENDOR = 0x004, + SCMI_BASE_DISCOVER_IMPLEMENTATION_VERSION = 0x005, + SCMI_BASE_DISCOVER_LIST_PROTOCOLS = 0x006, + SCMI_BASE_DISCOVER_AGENT = 0x007, + SCMI_BASE_NOTIFY_ERRORS = 0x008, +}; + +/* + * PROTOCOL_ATTRIBUTES + */ + +#define SCMI_BASE_PROTOCOL_ATTRS_NUM_PROTOCOLS_POS 0 +#define SCMI_BASE_PROTOCOL_ATTRS_NUM_AGENTS_POS 8 + +#define SCMI_BASE_PROTOCOL_ATTRS_NUM_PROTOCOLS_MASK 0xFFU +#define SCMI_BASE_PROTOCOL_ATTRS_NUM_AGENTS_MASK 0xFF00U + +#define SCMI_BASE_PROTOCOL_ATTRIBUTES(NUM_PROTOCOLS, NUM_AGENTS) \ + ((((NUM_PROTOCOLS) << SCMI_BASE_PROTOCOL_ATTRS_NUM_PROTOCOLS_POS) & \ + SCMI_BASE_PROTOCOL_ATTRS_NUM_PROTOCOLS_MASK) | \ + (((NUM_AGENTS) << SCMI_BASE_PROTOCOL_ATTRS_NUM_AGENTS_POS) & \ + SCMI_BASE_PROTOCOL_ATTRS_NUM_AGENTS_MASK)) + +/* + * BASE_DISCOVER_VENDOR + */ +struct scmi_base_discover_vendor_p2a { + int32_t status; + char vendor_identifier[SCMI_DEFAULT_STRING_LENGTH]; +}; + +/* + * BASE_DISCOVER_SUB_VENDOR + */ +struct scmi_base_discover_sub_vendor_p2a { + int32_t status; + char sub_vendor_identifier[SCMI_DEFAULT_STRING_LENGTH]; +}; + +/* + * BASE_DISCOVER_IMPLEMENTATION_VERSION + * No special structure right now, see protocol_version. + */ + +/* + * BASE_DISCOVER_LIST_PROTOCOLS + */ +struct scmi_base_discover_list_protocols_a2p { + uint32_t skip; +}; + +struct scmi_base_discover_list_protocols_p2a { + int32_t status; + uint32_t num_protocols; + uint32_t protocols[]; +}; + +#endif /* SCMI_MSG_BASE_H */ diff --git a/drivers/st/scmi-msg/common.h b/drivers/st/scmi-msg/common.h new file mode 100644 index 000000000..4777dbe6e --- /dev/null +++ b/drivers/st/scmi-msg/common.h @@ -0,0 +1,120 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Linaro Limited + */ +#ifndef SCMI_MSG_COMMON_H +#define SCMI_MSG_COMMON_H + +#include +#include +#include +#include + +#include "base.h" + +#define SCMI_VERSION 0x20000U +#define SCMI_IMPL_VERSION 0U + +#define SCMI_PLAYLOAD_MAX 92U + +/* + * Copy name identifier in target buffer following the SCMI specification + * that state name identifier shall be a null terminated string. + */ +#define COPY_NAME_IDENTIFIER(_dst_array, _name) \ + do { \ + assert(strlen(_name) < sizeof(_dst_array)); \ + strlcpy((_dst_array), (_name), sizeof(_dst_array)); \ + } while (0) + +/* Common command identifiers shared by all procotols */ +enum scmi_common_message_id { + SCMI_PROTOCOL_VERSION = 0x000, + SCMI_PROTOCOL_ATTRIBUTES = 0x001, + SCMI_PROTOCOL_MESSAGE_ATTRIBUTES = 0x002 +}; + +/* Common platform-to-agent (p2a) PROTOCOL_VERSION structure */ +struct scmi_protocol_version_p2a { + int32_t status; + uint32_t version; +}; + +/* Generic platform-to-agent (p2a) PROTOCOL_ATTRIBUTES structure */ +struct scmi_protocol_attributes_p2a { + int32_t status; + uint32_t attributes; +}; + +/* Generic agent-to-platform (a2p) PROTOCOL_MESSAGE_ATTRIBUTES structure */ +struct scmi_protocol_message_attributes_a2p { + uint32_t message_id; +}; + +/* Generic platform-to-agent (p2a) PROTOCOL_MESSAGE_ATTRIBUTES structure */ +struct scmi_protocol_message_attributes_p2a { + int32_t status; + uint32_t attributes; +}; + +/* + * struct scmi_msg - SCMI message context + * + * @agent_id: SCMI agent ID, safely set from secure world + * @protocol_id: SCMI protocol ID for the related message, set by caller agent + * @message_id: SCMI message ID for the related message, set by caller agent + * @in: Address of the incoming message payload copied in secure memory + * @in_size: Byte length of the incoming message payload, set by caller agent + * @out: Address of of the output message payload message in non-secure memory + * @out_size: Byte length of the provisionned output buffer + * @out_size_out: Byte length of the output message payload + */ +struct scmi_msg { + unsigned int agent_id; + unsigned int protocol_id; + unsigned int message_id; + char *in; + size_t in_size; + char *out; + size_t out_size; + size_t out_size_out; +}; + +/* + * Type scmi_msg_handler_t is used by procotol drivers to safely find + * the handler function for the incoming message ID. + */ +typedef void (*scmi_msg_handler_t)(struct scmi_msg *msg); + +/* + * scmi_msg_get_base_handler - Return a handler for a base message + * @msg - message to process + * Return a function handler for the message or NULL + */ +scmi_msg_handler_t scmi_msg_get_base_handler(struct scmi_msg *msg); + +/* + * Process Read, process and write response for input SCMI message + * + * @msg: SCMI message context + */ +void scmi_process_message(struct scmi_msg *msg); + +/* + * Write SCMI response payload to output message shared memory + * + * @msg: SCMI message context + * @payload: Output message payload + * @size: Byte size of output message payload + */ +void scmi_write_response(struct scmi_msg *msg, void *payload, size_t size); + +/* + * Write status only SCMI response payload to output message shared memory + * + * @msg: SCMI message context + * @status: SCMI status value returned to caller + */ +void scmi_status_response(struct scmi_msg *msg, int32_t status); +#endif /* SCMI_MSG_COMMON_H */ diff --git a/drivers/st/scmi-msg/entry.c b/drivers/st/scmi-msg/entry.c new file mode 100644 index 000000000..cd62413df --- /dev/null +++ b/drivers/st/scmi-msg/entry.c @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Linaro Limited + */ + +#include + +#include +#include + +#include "common.h" + +void scmi_status_response(struct scmi_msg *msg, int32_t status) +{ + assert(msg->out && msg->out_size >= sizeof(int32_t)); + + memcpy(msg->out, &status, sizeof(int32_t)); + msg->out_size_out = sizeof(int32_t); +} + +void scmi_write_response(struct scmi_msg *msg, void *payload, size_t size) +{ + /* + * Output payload shall be at least the size of the status + * Output buffer shall be at least be the size of the status + * Output paylaod shall fit in output buffer + */ + assert(payload && size >= sizeof(int32_t) && size <= msg->out_size && + msg->out && msg->out_size >= sizeof(int32_t)); + + memcpy(msg->out, payload, size); + msg->out_size_out = size; +} + +void scmi_process_message(struct scmi_msg *msg) +{ + scmi_msg_handler_t handler = NULL; + + switch (msg->protocol_id) { + case SCMI_PROTOCOL_ID_BASE: + handler = scmi_msg_get_base_handler(msg); + break; + default: + break; + } + + if (handler) { + handler(msg); + return; + } + + ERROR("Agent %u Protocol 0x%x Message 0x%x: not supported", + msg->agent_id, msg->protocol_id, msg->message_id); + + scmi_status_response(msg, SCMI_NOT_SUPPORTED); +} diff --git a/include/drivers/st/scmi-msg.h b/include/drivers/st/scmi-msg.h new file mode 100644 index 000000000..af683e277 --- /dev/null +++ b/include/drivers/st/scmi-msg.h @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019, Linaro Limited + */ + +#ifndef SCMI_MSG_H +#define SCMI_MSG_H + +#include +#include +#include + +/* Minimum size expected for SMT based shared memory message buffers */ +#define SMT_BUF_SLOT_SIZE 128U + +/* A channel abstract a communication path between agent and server */ +struct scmi_msg_channel; + +/* + * struct scmi_msg_channel - Shared memory buffer for a agent-to-server channel + * + * @shm_addr: Address of the shared memory for the SCMI channel + * @shm_size: Byte size of the shared memory for the SCMI channel + * @busy: True when channel is busy, flase when channel is free + * @agent_name: Agent name, SCMI protocol exposes 16 bytes max, or NULL + */ +struct scmi_msg_channel { + uintptr_t shm_addr; + size_t shm_size; + bool busy; + const char *agent_name; +}; + +/* Platform callback functions */ + +/* + * Return the SCMI channel related to an agent + * @agent_id: SCMI agent ID + * Return a pointer to channel on success, NULL otherwise + */ +struct scmi_msg_channel *plat_scmi_get_channel(unsigned int agent_id); + +/* + * Return how many SCMI protocols supported by the platform + * According to the SCMI specification, this function does not target + * a specific agent ID and shall return all platform known capabilities. + */ +size_t plat_scmi_protocol_count(void); + +/* + * Get the count and list of SCMI protocols (but base) supported for an agent + * + * @agent_id: SCMI agent ID + * Return a pointer to a null terminated array supported protocol IDs. + */ +const uint8_t *plat_scmi_protocol_list(unsigned int agent_id); + +/* Get the name of the SCMI vendor for the platform */ +const char *plat_scmi_vendor_name(void); + +/* Get the name of the SCMI sub-vendor for the platform */ +const char *plat_scmi_sub_vendor_name(void); + +#endif /* SCMI_MSG_H */ diff --git a/include/drivers/st/scmi.h b/include/drivers/st/scmi.h new file mode 100644 index 000000000..ac5dc3871 --- /dev/null +++ b/include/drivers/st/scmi.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. + */ +#ifndef SCMI_MSG_SCMI_H +#define SCMI_MSG_SCMI_H + +#define SCMI_PROTOCOL_ID_BASE 0x10U +#define SCMI_PROTOCOL_ID_POWER_DOMAIN 0x11U +#define SCMI_PROTOCOL_ID_SYS_POWER 0x12U +#define SCMI_PROTOCOL_ID_PERF 0x13U +#define SCMI_PROTOCOL_ID_CLOCK 0x14U +#define SCMI_PROTOCOL_ID_SENSOR 0x15U +#define SCMI_PROTOCOL_ID_RESET_DOMAIN 0x16U + +/* SCMI error codes reported to agent through server-to-agent messages */ +#define SCMI_SUCCESS 0 +#define SCMI_NOT_SUPPORTED (-1) +#define SCMI_INVALID_PARAMETERS (-2) +#define SCMI_DENIED (-3) +#define SCMI_NOT_FOUND (-4) +#define SCMI_OUT_OF_RANGE (-5) +#define SCMI_BUSY (-6) +#define SCMI_COMMS_ERROR (-7) +#define SCMI_GENERIC_ERROR (-8) +#define SCMI_HARDWARE_ERROR (-9) +#define SCMI_PROTOCOL_ERROR (-10) + +#endif /* SCMI_MSG_SCMI_H */ -- cgit v1.2.3 From c9e8300012113df5d279dbef5435c77f6b6dea67 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Fri, 1 May 2020 10:32:02 +0200 Subject: drivers/scmi-msg: support for clock protocol Adds SCMI clock protocol support in the SCMI message drivers as defined in SCMI specification v2.0 [1] for clock protocol messages. Platform can provide one of the plat_scmi_clock_*() handler for the supported operations set/get state/rate and others. scmi_msg_get_clock_handler() sanitizes the message_id value against any speculative use of clock ID as a index since by SCMI specification, IDs are indices. This implementation is based on the OP-TEE project implementation [2] itself based on the SCP-firmware implementation [3] of the SCMI protocol server side. Link: [1] http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/DEN0056A_System_Control_and_Management_Interface.pdf Link: [2] https://github.com/OP-TEE/optee_os/commit/a7a9e3ba71dd908aafdc4c5ed9b29b15faa9692d Link: [3] https://github.com/ARM-software/SCP-firmware.git Change-Id: Ib56e096512042d4f7b9563d1e4181554eb8ed02c Signed-off-by: Etienne Carriere --- drivers/st/scmi-msg/clock.c | 381 ++++++++++++++++++++++++++++++++++++++++++ drivers/st/scmi-msg/clock.h | 150 +++++++++++++++++ drivers/st/scmi-msg/common.h | 8 + drivers/st/scmi-msg/entry.c | 3 + include/drivers/st/scmi-msg.h | 79 +++++++++ 5 files changed, 621 insertions(+) create mode 100644 drivers/st/scmi-msg/clock.c create mode 100644 drivers/st/scmi-msg/clock.h diff --git a/drivers/st/scmi-msg/clock.c b/drivers/st/scmi-msg/clock.c new file mode 100644 index 000000000..319557cd0 --- /dev/null +++ b/drivers/st/scmi-msg/clock.c @@ -0,0 +1,381 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Linaro Limited + */ +#include +#include + +#include +#include +#include + +#include "common.h" + +#pragma weak plat_scmi_clock_count +#pragma weak plat_scmi_clock_get_name +#pragma weak plat_scmi_clock_rates_array +#pragma weak plat_scmi_clock_rates_by_step +#pragma weak plat_scmi_clock_get_rate +#pragma weak plat_scmi_clock_set_rate +#pragma weak plat_scmi_clock_get_state +#pragma weak plat_scmi_clock_set_state + +static bool message_id_is_supported(unsigned int message_id); + +size_t plat_scmi_clock_count(unsigned int agent_id __unused) +{ + return 0U; +} + +const char *plat_scmi_clock_get_name(unsigned int agent_id __unused, + unsigned int scmi_id __unused) +{ + return NULL; +} + +int32_t plat_scmi_clock_rates_array(unsigned int agent_id __unused, + unsigned int scmi_id __unused, + unsigned long *rates __unused, + size_t *nb_elts __unused) +{ + return SCMI_NOT_SUPPORTED; +} + +int32_t plat_scmi_clock_rates_by_step(unsigned int agent_id __unused, + unsigned int scmi_id __unused, + unsigned long *steps __unused) +{ + return SCMI_NOT_SUPPORTED; +} + +unsigned long plat_scmi_clock_get_rate(unsigned int agent_id __unused, + unsigned int scmi_id __unused) +{ + return 0U; +} + +int32_t plat_scmi_clock_set_rate(unsigned int agent_id __unused, + unsigned int scmi_id __unused, + unsigned long rate __unused) +{ + return SCMI_NOT_SUPPORTED; +} + +int32_t plat_scmi_clock_get_state(unsigned int agent_id __unused, + unsigned int scmi_id __unused) +{ + return SCMI_NOT_SUPPORTED; +} + +int32_t plat_scmi_clock_set_state(unsigned int agent_id __unused, + unsigned int scmi_id __unused, + bool enable_not_disable __unused) +{ + return SCMI_NOT_SUPPORTED; +} + +static void report_version(struct scmi_msg *msg) +{ + struct scmi_protocol_version_p2a return_values = { + .status = SCMI_SUCCESS, + .version = SCMI_PROTOCOL_VERSION_CLOCK, + }; + + if (msg->in_size != 0) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void report_attributes(struct scmi_msg *msg) +{ + size_t agent_count = plat_scmi_clock_count(msg->agent_id); + struct scmi_protocol_attributes_p2a return_values = { + .status = SCMI_SUCCESS, + .attributes = SCMI_CLOCK_PROTOCOL_ATTRIBUTES(1U, agent_count), + }; + + if (msg->in_size != 0) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void report_message_attributes(struct scmi_msg *msg) +{ + struct scmi_protocol_message_attributes_a2p *in_args = (void *)msg->in; + struct scmi_protocol_message_attributes_p2a return_values = { + .status = SCMI_SUCCESS, + /* For this protocol, attributes shall be zero */ + .attributes = 0U, + }; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + if (!message_id_is_supported(in_args->message_id)) { + scmi_status_response(msg, SCMI_NOT_FOUND); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void scmi_clock_attributes(struct scmi_msg *msg) +{ + const struct scmi_clock_attributes_a2p *in_args = (void *)msg->in; + struct scmi_clock_attributes_p2a return_values = { + .status = SCMI_SUCCESS, + }; + const char *name = NULL; + unsigned int clock_id = 0U; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + clock_id = SPECULATION_SAFE_VALUE(in_args->clock_id); + + if (clock_id >= plat_scmi_clock_count(msg->agent_id)) { + scmi_status_response(msg, SCMI_INVALID_PARAMETERS); + return; + } + + + name = plat_scmi_clock_get_name(msg->agent_id, clock_id); + if (name == NULL) { + scmi_status_response(msg, SCMI_NOT_FOUND); + return; + } + + COPY_NAME_IDENTIFIER(return_values.clock_name, name); + + return_values.attributes = plat_scmi_clock_get_state(msg->agent_id, + clock_id); + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void scmi_clock_rate_get(struct scmi_msg *msg) +{ + const struct scmi_clock_rate_get_a2p *in_args = (void *)msg->in; + unsigned long rate = 0U; + struct scmi_clock_rate_get_p2a return_values = { + .status = SCMI_SUCCESS, + }; + unsigned int clock_id = 0U; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + clock_id = SPECULATION_SAFE_VALUE(in_args->clock_id); + + if (clock_id >= plat_scmi_clock_count(msg->agent_id)) { + scmi_status_response(msg, SCMI_INVALID_PARAMETERS); + return; + } + + rate = plat_scmi_clock_get_rate(msg->agent_id, clock_id); + + return_values.rate[0] = (uint32_t)rate; + return_values.rate[1] = (uint32_t)((uint64_t)rate >> 32); + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void scmi_clock_rate_set(struct scmi_msg *msg) +{ + const struct scmi_clock_rate_set_a2p *in_args = (void *)msg->in; + unsigned long rate = 0U; + int32_t status = 0; + unsigned int clock_id = 0U; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + clock_id = SPECULATION_SAFE_VALUE(in_args->clock_id); + + if (clock_id >= plat_scmi_clock_count(msg->agent_id)) { + scmi_status_response(msg, SCMI_INVALID_PARAMETERS); + return; + } + + rate = (unsigned long)(((uint64_t)in_args->rate[1] << 32) | + in_args->rate[0]); + + status = plat_scmi_clock_set_rate(msg->agent_id, clock_id, rate); + + scmi_status_response(msg, status); +} + +static void scmi_clock_config_set(struct scmi_msg *msg) +{ + const struct scmi_clock_config_set_a2p *in_args = (void *)msg->in; + int32_t status = SCMI_GENERIC_ERROR; + bool enable = false; + unsigned int clock_id = 0U; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + clock_id = SPECULATION_SAFE_VALUE(in_args->clock_id); + + if (clock_id >= plat_scmi_clock_count(msg->agent_id)) { + scmi_status_response(msg, SCMI_INVALID_PARAMETERS); + return; + } + + enable = in_args->attributes & SCMI_CLOCK_CONFIG_SET_ENABLE_MASK; + + status = plat_scmi_clock_set_state(msg->agent_id, clock_id, enable); + + scmi_status_response(msg, status); +} + +#define RATES_ARRAY_SIZE_MAX (SCMI_PLAYLOAD_MAX - \ + sizeof(struct scmi_clock_describe_rates_p2a)) + +#define SCMI_RATES_BY_ARRAY(_nb_rates, _rem_rates) \ + SCMI_CLOCK_DESCRIBE_RATES_NUM_RATES_FLAGS((_nb_rates), \ + SCMI_CLOCK_RATE_FORMAT_LIST, \ + (_rem_rates)) +#define SCMI_RATES_BY_STEP \ + SCMI_CLOCK_DESCRIBE_RATES_NUM_RATES_FLAGS(3U, \ + SCMI_CLOCK_RATE_FORMAT_RANGE, \ + 0U) + +#define RATE_DESC_SIZE sizeof(struct scmi_clock_rate) + +static void write_rate_desc_array_in_buffer(char *dest, unsigned long *rates, + size_t nb_elt) +{ + uint32_t *out = (uint32_t *)(uintptr_t)dest; + size_t n; + + ASSERT_SYM_PTR_ALIGN(out); + + for (n = 0U; n < nb_elt; n++) { + out[2 * n] = (uint32_t)rates[n]; + out[2 * n + 1] = (uint32_t)((uint64_t)rates[n] >> 32); + } +} + +static void scmi_clock_describe_rates(struct scmi_msg *msg) +{ + const struct scmi_clock_describe_rates_a2p *in_args = (void *)msg->in; + struct scmi_clock_describe_rates_p2a p2a = { + .status = SCMI_SUCCESS, + }; + size_t nb_rates; + int32_t status; + unsigned int clock_id; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + clock_id = SPECULATION_SAFE_VALUE(in_args->clock_id); + + if (clock_id >= plat_scmi_clock_count(msg->agent_id)) { + scmi_status_response(msg, SCMI_INVALID_PARAMETERS); + return; + } + + /* Platform may support array rate description */ + status = plat_scmi_clock_rates_array(msg->agent_id, clock_id, NULL, + &nb_rates); + if (status == SCMI_SUCCESS) { + /* Currently 12 cells mex, so it's affordable for the stack */ + unsigned long plat_rates[RATES_ARRAY_SIZE_MAX / RATE_DESC_SIZE]; + size_t max_nb = RATES_ARRAY_SIZE_MAX / RATE_DESC_SIZE; + size_t ret_nb = MIN(nb_rates - in_args->rate_index, max_nb); + size_t rem_nb = nb_rates - in_args->rate_index - ret_nb; + + status = plat_scmi_clock_rates_array(msg->agent_id, clock_id, + plat_rates, &ret_nb); + if (status == SCMI_SUCCESS) { + write_rate_desc_array_in_buffer(msg->out + sizeof(p2a), + plat_rates, ret_nb); + + p2a.num_rates_flags = SCMI_RATES_BY_ARRAY(ret_nb, + rem_nb); + p2a.status = SCMI_SUCCESS; + + memcpy(msg->out, &p2a, sizeof(p2a)); + msg->out_size_out = sizeof(p2a) + + ret_nb * RATE_DESC_SIZE; + } + } else if (status == SCMI_NOT_SUPPORTED) { + unsigned long triplet[3] = { 0U, 0U, 0U }; + + /* Platform may support min§max/step triplet description */ + status = plat_scmi_clock_rates_by_step(msg->agent_id, clock_id, + triplet); + if (status == SCMI_SUCCESS) { + write_rate_desc_array_in_buffer(msg->out + sizeof(p2a), + triplet, 3U); + + p2a.num_rates_flags = SCMI_RATES_BY_STEP; + p2a.status = SCMI_SUCCESS; + + memcpy(msg->out, &p2a, sizeof(p2a)); + msg->out_size_out = sizeof(p2a) + (3U * RATE_DESC_SIZE); + } + } else { + /* Fallthrough generic exit sequence below with error status */ + } + + if (status != SCMI_SUCCESS) { + scmi_status_response(msg, status); + } else { + /* + * Message payload is already writen to msg->out, and + * msg->out_size_out updated. + */ + } +} + +static const scmi_msg_handler_t scmi_clock_handler_table[] = { + [SCMI_PROTOCOL_VERSION] = report_version, + [SCMI_PROTOCOL_ATTRIBUTES] = report_attributes, + [SCMI_PROTOCOL_MESSAGE_ATTRIBUTES] = report_message_attributes, + [SCMI_CLOCK_ATTRIBUTES] = scmi_clock_attributes, + [SCMI_CLOCK_DESCRIBE_RATES] = scmi_clock_describe_rates, + [SCMI_CLOCK_RATE_SET] = scmi_clock_rate_set, + [SCMI_CLOCK_RATE_GET] = scmi_clock_rate_get, + [SCMI_CLOCK_CONFIG_SET] = scmi_clock_config_set, +}; + +static bool message_id_is_supported(size_t message_id) +{ + return (message_id < ARRAY_SIZE(scmi_clock_handler_table)) && + (scmi_clock_handler_table[message_id] != NULL); +} + +scmi_msg_handler_t scmi_msg_get_clock_handler(struct scmi_msg *msg) +{ + const size_t array_size = ARRAY_SIZE(scmi_clock_handler_table); + unsigned int message_id = SPECULATION_SAFE_VALUE(msg->message_id); + + if (message_id >= array_size) { + VERBOSE("Clock handle not found %u", msg->message_id); + return NULL; + } + + return scmi_clock_handler_table[message_id]; +} diff --git a/drivers/st/scmi-msg/clock.h b/drivers/st/scmi-msg/clock.h new file mode 100644 index 000000000..a637934ee --- /dev/null +++ b/drivers/st/scmi-msg/clock.h @@ -0,0 +1,150 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019, Linaro Limited + */ + +#ifndef SCMI_MSG_CLOCK_H +#define SCMI_MSG_CLOCK_H + +#include + +#include + +#define SCMI_PROTOCOL_VERSION_CLOCK 0x20000U + +/* + * Identifiers of the SCMI Clock Management Protocol commands + */ +enum scmi_clock_command_id { + SCMI_CLOCK_ATTRIBUTES = 0x003, + SCMI_CLOCK_DESCRIBE_RATES = 0x004, + SCMI_CLOCK_RATE_SET = 0x005, + SCMI_CLOCK_RATE_GET = 0x006, + SCMI_CLOCK_CONFIG_SET = 0x007, +}; + +/* Protocol attributes */ +#define SCMI_CLOCK_CLOCK_COUNT_MASK GENMASK(15, 0) +#define SCMI_CLOCK_MAX_PENDING_TRANSITIONS_MASK GENMASK(23, 16) + +#define SCMI_CLOCK_PROTOCOL_ATTRIBUTES(_max_pending, _clk_count) \ + ((((_max_pending) << 16) & SCMI_CLOCK_MAX_PENDING_TRANSITIONS_MASK) | \ + (((_clk_count) & SCMI_CLOCK_CLOCK_COUNT_MASK))) + +struct scmi_clock_attributes_a2p { + uint32_t clock_id; +}; + +#define SCMI_CLOCK_NAME_LENGTH_MAX 16U + +struct scmi_clock_attributes_p2a { + int32_t status; + uint32_t attributes; + char clock_name[SCMI_CLOCK_NAME_LENGTH_MAX]; +}; + +/* + * Clock Rate Get + */ + +struct scmi_clock_rate_get_a2p { + uint32_t clock_id; +}; + +struct scmi_clock_rate_get_p2a { + int32_t status; + uint32_t rate[2]; +}; + +/* + * Clock Rate Set + */ + +/* If set, set the new clock rate asynchronously */ +#define SCMI_CLOCK_RATE_SET_ASYNC_POS 0 +/* If set, do not send a delayed asynchronous response */ +#define SCMI_CLOCK_RATE_SET_NO_DELAYED_RESPONSE_POS 1 +/* Round up, if set, otherwise round down */ +#define SCMI_CLOCK_RATE_SET_ROUND_UP_POS 2 +/* If set, the platform chooses the appropriate rounding mode */ +#define SCMI_CLOCK_RATE_SET_ROUND_AUTO_POS 3 + +#define SCMI_CLOCK_RATE_SET_ASYNC_MASK \ + BIT(SCMI_CLOCK_RATE_SET_ASYNC_POS) +#define SCMI_CLOCK_RATE_SET_NO_DELAYED_RESPONSE_MASK \ + BIT(SCMI_CLOCK_RATE_SET_NO_DELAYED_RESPONSE_POS) +#define SCMI_CLOCK_RATE_SET_ROUND_UP_MASK \ + BIT(SCMI_CLOCK_RATE_SET_ROUND_UP_POS) +#define SCMI_CLOCK_RATE_SET_ROUND_AUTO_MASK \ + BIT(SCMI_CLOCK_RATE_SET_ROUND_AUTO_POS) + +struct scmi_clock_rate_set_a2p { + uint32_t flags; + uint32_t clock_id; + uint32_t rate[2]; +}; + +struct scmi_clock_rate_set_p2a { + int32_t status; +}; + +/* + * Clock Config Set + */ + +#define SCMI_CLOCK_CONFIG_SET_ENABLE_POS 0 + +#define SCMI_CLOCK_CONFIG_SET_ENABLE_MASK \ + BIT(SCMI_CLOCK_CONFIG_SET_ENABLE_POS) + +struct scmi_clock_config_set_a2p { + uint32_t clock_id; + uint32_t attributes; +}; + +struct scmi_clock_config_set_p2a { + int32_t status; +}; + +/* + * Clock Describe Rates + */ + +#define SCMI_CLOCK_RATE_FORMAT_RANGE 1U +#define SCMI_CLOCK_RATE_FORMAT_LIST 0U + +#define SCMI_CLOCK_DESCRIBE_RATES_REMAINING_MASK GENMASK_32(31, 16) +#define SCMI_CLOCK_DESCRIBE_RATES_REMAINING_POS 16 + +#define SCMI_CLOCK_DESCRIBE_RATES_FORMAT_MASK BIT(12) +#define SCMI_CLOCK_DESCRIBE_RATES_FORMAT_POS 12 + +#define SCMI_CLOCK_DESCRIBE_RATES_COUNT_MASK GENMASK_32(11, 0) + +#define SCMI_CLOCK_DESCRIBE_RATES_NUM_RATES_FLAGS(_count, _fmt, _rem_rates) \ + ( \ + ((_count) & SCMI_CLOCK_DESCRIBE_RATES_COUNT_MASK) | \ + (((_rem_rates) << SCMI_CLOCK_DESCRIBE_RATES_REMAINING_POS) & \ + SCMI_CLOCK_DESCRIBE_RATES_REMAINING_MASK) | \ + (((_fmt) << SCMI_CLOCK_DESCRIBE_RATES_FORMAT_POS) & \ + SCMI_CLOCK_DESCRIBE_RATES_FORMAT_MASK) \ + ) + +struct scmi_clock_rate { + uint32_t low; + uint32_t high; +}; + +struct scmi_clock_describe_rates_a2p { + uint32_t clock_id; + uint32_t rate_index; +}; + +struct scmi_clock_describe_rates_p2a { + int32_t status; + uint32_t num_rates_flags; + struct scmi_clock_rate rates[]; +}; + +#endif /* SCMI_MSG_CLOCK_H */ diff --git a/drivers/st/scmi-msg/common.h b/drivers/st/scmi-msg/common.h index 4777dbe6e..63b92aa0b 100644 --- a/drivers/st/scmi-msg/common.h +++ b/drivers/st/scmi-msg/common.h @@ -12,6 +12,7 @@ #include #include "base.h" +#include "clock.h" #define SCMI_VERSION 0x20000U #define SCMI_IMPL_VERSION 0U @@ -94,6 +95,13 @@ typedef void (*scmi_msg_handler_t)(struct scmi_msg *msg); */ scmi_msg_handler_t scmi_msg_get_base_handler(struct scmi_msg *msg); +/* + * scmi_msg_get_clock_handler - Return a handler for a clock message + * @msg - message to process + * Return a function handler for the message or NULL + */ +scmi_msg_handler_t scmi_msg_get_clock_handler(struct scmi_msg *msg); + /* * Process Read, process and write response for input SCMI message * diff --git a/drivers/st/scmi-msg/entry.c b/drivers/st/scmi-msg/entry.c index cd62413df..7b06f353e 100644 --- a/drivers/st/scmi-msg/entry.c +++ b/drivers/st/scmi-msg/entry.c @@ -41,6 +41,9 @@ void scmi_process_message(struct scmi_msg *msg) case SCMI_PROTOCOL_ID_BASE: handler = scmi_msg_get_base_handler(msg); break; + case SCMI_PROTOCOL_ID_CLOCK: + handler = scmi_msg_get_clock_handler(msg); + break; default: break; } diff --git a/include/drivers/st/scmi-msg.h b/include/drivers/st/scmi-msg.h index af683e277..48fac1685 100644 --- a/include/drivers/st/scmi-msg.h +++ b/include/drivers/st/scmi-msg.h @@ -62,4 +62,83 @@ const char *plat_scmi_vendor_name(void); /* Get the name of the SCMI sub-vendor for the platform */ const char *plat_scmi_sub_vendor_name(void); +/* Handlers for SCMI Clock protocol services */ + +/* + * Return number of clock controllers for an agent + * @agent_id: SCMI agent ID + * Return number of clock controllers + */ +size_t plat_scmi_clock_count(unsigned int agent_id); + +/* + * Get clock controller string ID (aka name) + * @agent_id: SCMI agent ID + * @scmi_id: SCMI clock ID + * Return pointer to name or NULL + */ +const char *plat_scmi_clock_get_name(unsigned int agent_id, + unsigned int scmi_id); + +/* + * Get clock possible rate as an array of frequencies in Hertz. + * + * @agent_id: SCMI agent ID + * @scmi_id: SCMI clock ID + * @rates: If NULL, function returns, else output rates array + * @nb_elts: Array size of @rates. + * Return an SCMI compliant error code + */ +int32_t plat_scmi_clock_rates_array(unsigned int agent_id, unsigned int scmi_id, + unsigned long *rates, size_t *nb_elts); + +/* + * Get clock possible rate as range with regular steps in Hertz + * + * @agent_id: SCMI agent ID + * @scmi_id: SCMI clock ID + * @min_max_step: 3 cell array for min, max and step rate data + * Return an SCMI compliant error code + */ +int32_t plat_scmi_clock_rates_by_step(unsigned int agent_id, + unsigned int scmi_id, + unsigned long *min_max_step); + +/* + * Get clock rate in Hertz + * @agent_id: SCMI agent ID + * @scmi_id: SCMI clock ID + * Return clock rate or 0 if not supported + */ +unsigned long plat_scmi_clock_get_rate(unsigned int agent_id, + unsigned int scmi_id); + +/* + * Set clock rate in Hertz + * @agent_id: SCMI agent ID + * @scmi_id: SCMI clock ID + * @rate: Target clock frequency in Hertz + * Return a compliant SCMI error code + */ +int32_t plat_scmi_clock_set_rate(unsigned int agent_id, unsigned int scmi_id, + unsigned long rate); + +/* + * Get clock state (enabled or disabled) + * @agent_id: SCMI agent ID + * @scmi_id: SCMI clock ID + * Return 1 if clock is enabled, 0 if disables, or a negative SCMI error code + */ +int32_t plat_scmi_clock_get_state(unsigned int agent_id, unsigned int scmi_id); + +/* + * Get clock state (enabled or disabled) + * @agent_id: SCMI agent ID + * @scmi_id: SCMI clock ID + * @enable_not_disable: Enable clock if true, disable clock otherwise + * Return a compliant SCMI error code + */ +int32_t plat_scmi_clock_set_state(unsigned int agent_id, unsigned int scmi_id, + bool enable_not_disable); + #endif /* SCMI_MSG_H */ -- cgit v1.2.3 From 6cc2c1cbed9535a0b9352388724eedfd92b43a7d Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Fri, 1 May 2020 10:33:22 +0200 Subject: drivers/scmi-msg: support for reset domain protocol Adds SCMI reset domain protocol support in the SCMI message drivers as defined in SCMI specification v2.0 [1]. Not all the messages defined in the specification are supported. scmi_msg_get_rd_handler() sanitizes the message_id value against any speculative use of reset domain ID as a index since by SCMI specification, IDs are indices. This implementation is based on the OP-TEE project implementation [2] itself based on the SCP-firmware implementation [3] of the SCMI protocol server side. Link: [1] http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/DEN0056A_System_Control_and_Management_Interface.pdf Link: [2] https://github.com/OP-TEE/optee_os/commit/56a1f10ed99d683ee3a8af29b6147a59a99ef3e0 Link: [3] https://github.com/ARM-software/SCP-firmware.git Change-Id: If7cf13de40a815dedb40dcd5af8b6bb6725d9078 Signed-off-by: Etienne Carriere --- drivers/st/scmi-msg/common.h | 8 ++ drivers/st/scmi-msg/entry.c | 3 + drivers/st/scmi-msg/reset_domain.c | 197 +++++++++++++++++++++++++++++++++++++ drivers/st/scmi-msg/reset_domain.h | 122 +++++++++++++++++++++++ include/drivers/st/scmi-msg.h | 37 +++++++ 5 files changed, 367 insertions(+) create mode 100644 drivers/st/scmi-msg/reset_domain.c create mode 100644 drivers/st/scmi-msg/reset_domain.h diff --git a/drivers/st/scmi-msg/common.h b/drivers/st/scmi-msg/common.h index 63b92aa0b..ef5953b3d 100644 --- a/drivers/st/scmi-msg/common.h +++ b/drivers/st/scmi-msg/common.h @@ -13,6 +13,7 @@ #include "base.h" #include "clock.h" +#include "reset_domain.h" #define SCMI_VERSION 0x20000U #define SCMI_IMPL_VERSION 0U @@ -102,6 +103,13 @@ scmi_msg_handler_t scmi_msg_get_base_handler(struct scmi_msg *msg); */ scmi_msg_handler_t scmi_msg_get_clock_handler(struct scmi_msg *msg); +/* + * scmi_msg_get_rstd_handler - Return a handler for a reset domain message + * @msg - message to process + * Return a function handler for the message or NULL + */ +scmi_msg_handler_t scmi_msg_get_rstd_handler(struct scmi_msg *msg); + /* * Process Read, process and write response for input SCMI message * diff --git a/drivers/st/scmi-msg/entry.c b/drivers/st/scmi-msg/entry.c index 7b06f353e..eefcb3100 100644 --- a/drivers/st/scmi-msg/entry.c +++ b/drivers/st/scmi-msg/entry.c @@ -44,6 +44,9 @@ void scmi_process_message(struct scmi_msg *msg) case SCMI_PROTOCOL_ID_CLOCK: handler = scmi_msg_get_clock_handler(msg); break; + case SCMI_PROTOCOL_ID_RESET_DOMAIN: + handler = scmi_msg_get_rstd_handler(msg); + break; default: break; } diff --git a/drivers/st/scmi-msg/reset_domain.c b/drivers/st/scmi-msg/reset_domain.c new file mode 100644 index 000000000..b4773029b --- /dev/null +++ b/drivers/st/scmi-msg/reset_domain.c @@ -0,0 +1,197 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Linaro Limited + */ +#include +#include + +#include +#include +#include +#include + +#include "common.h" + +static bool message_id_is_supported(unsigned int message_id); + +#pragma weak plat_scmi_rstd_count +#pragma weak plat_scmi_rstd_get_name +#pragma weak plat_scmi_rstd_autonomous +#pragma weak plat_scmi_rstd_set_state + +size_t plat_scmi_rstd_count(unsigned int agent_id __unused) +{ + return 0U; +} + +const char *plat_scmi_rstd_get_name(unsigned int agent_id __unused, + unsigned int scmi_id __unused) +{ + return NULL; +} + +int32_t plat_scmi_rstd_autonomous(unsigned int agent_id __unused, + unsigned int scmi_id __unused, + unsigned int state __unused) +{ + return SCMI_NOT_SUPPORTED; +} + +int32_t plat_scmi_rstd_set_state(unsigned int agent_id __unused, + unsigned int scmi_id __unused, + bool assert_not_deassert __unused) +{ + return SCMI_NOT_SUPPORTED; +} + +static void report_version(struct scmi_msg *msg) +{ + struct scmi_protocol_version_p2a return_values = { + .status = SCMI_SUCCESS, + .version = SCMI_PROTOCOL_VERSION_RESET_DOMAIN, + }; + + if (msg->in_size != 0U) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void report_attributes(struct scmi_msg *msg) +{ + struct scmi_protocol_attributes_p2a return_values = { + .status = SCMI_SUCCESS, + .attributes = plat_scmi_rstd_count(msg->agent_id), + }; + + if (msg->in_size != 0U) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void report_message_attributes(struct scmi_msg *msg) +{ + struct scmi_protocol_message_attributes_a2p *in_args = (void *)msg->in; + struct scmi_protocol_message_attributes_p2a return_values = { + .status = SCMI_SUCCESS, + /* For this protocol, attributes shall be zero */ + .attributes = 0U, + }; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + if (!message_id_is_supported(in_args->message_id)) { + scmi_status_response(msg, SCMI_NOT_FOUND); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void reset_domain_attributes(struct scmi_msg *msg) +{ + struct scmi_reset_domain_attributes_a2p *in_args = (void *)msg->in; + struct scmi_reset_domain_attributes_p2a return_values; + const char *name = NULL; + unsigned int domain_id = 0U; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + domain_id = SPECULATION_SAFE_VALUE(in_args->domain_id); + + if (domain_id >= plat_scmi_rstd_count(msg->agent_id)) { + scmi_status_response(msg, SCMI_INVALID_PARAMETERS); + return; + } + + name = plat_scmi_rstd_get_name(msg->agent_id, domain_id); + if (name == NULL) { + scmi_status_response(msg, SCMI_NOT_FOUND); + return; + } + + zeromem(&return_values, sizeof(return_values)); + COPY_NAME_IDENTIFIER(return_values.name, name); + return_values.status = SCMI_SUCCESS; + return_values.flags = 0U; /* Async and Notif are not supported */ + return_values.latency = SCMI_RESET_DOMAIN_ATTR_UNK_LAT; + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void reset_request(struct scmi_msg *msg) +{ + struct scmi_reset_domain_request_a2p *in_args = (void *)msg->in; + struct scmi_reset_domain_request_p2a out_args = { + .status = SCMI_SUCCESS, + }; + unsigned int domain_id = 0U; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + domain_id = SPECULATION_SAFE_VALUE(in_args->domain_id); + + if (domain_id >= plat_scmi_rstd_count(msg->agent_id)) { + scmi_status_response(msg, SCMI_NOT_FOUND); + return; + } + + if ((in_args->flags & SCMI_RESET_DOMAIN_AUTO) != 0U) { + out_args.status = plat_scmi_rstd_autonomous(msg->agent_id, + domain_id, + in_args->reset_state); + } else if ((in_args->flags & SCMI_RESET_DOMAIN_EXPLICIT) != 0U) { + out_args.status = plat_scmi_rstd_set_state(msg->agent_id, + domain_id, true); + } else { + out_args.status = plat_scmi_rstd_set_state(msg->agent_id, + domain_id, false); + } + + if (out_args.status != SCMI_SUCCESS) { + scmi_status_response(msg, out_args.status); + } else { + scmi_write_response(msg, &out_args, sizeof(out_args)); + } +} + +static const scmi_msg_handler_t scmi_rstd_handler_table[] = { + [SCMI_PROTOCOL_VERSION] = report_version, + [SCMI_PROTOCOL_ATTRIBUTES] = report_attributes, + [SCMI_PROTOCOL_MESSAGE_ATTRIBUTES] = report_message_attributes, + [SCMI_RESET_DOMAIN_ATTRIBUTES] = reset_domain_attributes, + [SCMI_RESET_DOMAIN_REQUEST] = reset_request, +}; + +static bool message_id_is_supported(unsigned int message_id) +{ + return (message_id < ARRAY_SIZE(scmi_rstd_handler_table)) && + (scmi_rstd_handler_table[message_id] != NULL); +} + +scmi_msg_handler_t scmi_msg_get_rstd_handler(struct scmi_msg *msg) +{ + unsigned int message_id = SPECULATION_SAFE_VALUE(msg->message_id); + + if (message_id >= ARRAY_SIZE(scmi_rstd_handler_table)) { + VERBOSE("Reset domain handle not found %u\n", msg->message_id); + return NULL; + } + + return scmi_rstd_handler_table[message_id]; +} diff --git a/drivers/st/scmi-msg/reset_domain.h b/drivers/st/scmi-msg/reset_domain.h new file mode 100644 index 000000000..47bee5e39 --- /dev/null +++ b/drivers/st/scmi-msg/reset_domain.h @@ -0,0 +1,122 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019, Linaro Limited + */ +#ifndef SCMI_MSG_RESET_DOMAIN_H +#define SCMI_MSG_RESET_DOMAIN_H + +#include +#include + +#include + +#define SCMI_PROTOCOL_VERSION_RESET_DOMAIN 0x10000U + +#define SCMI_RESET_STATE_ARCH BIT(31) +#define SCMI_RESET_STATE_IMPL 0U + +/* + * Identifiers of the SCMI Reset Domain Management Protocol commands + */ +enum scmi_reset_domain_command_id { + SCMI_RESET_DOMAIN_ATTRIBUTES = 0x03, + SCMI_RESET_DOMAIN_REQUEST = 0x04, + SCMI_RESET_DOMAIN_NOTIFY = 0x05, +}; + +/* + * Identifiers of the SCMI Reset Domain Management Protocol responses + */ +enum scmi_reset_domain_response_id { + SCMI_RESET_ISSUED = 0x00, + SCMI_RESET_COMPLETE = 0x04, +}; + +/* + * PROTOCOL_ATTRIBUTES + */ + +#define SCMI_RESET_DOMAIN_COUNT_MASK GENMASK_32(15, 0) + +struct scmi_reset_domain_protocol_attributes_p2a { + int32_t status; + uint32_t attributes; +}; + +/* Value for scmi_reset_domain_attributes_p2a:flags */ +#define SCMI_RESET_DOMAIN_ATTR_ASYNC BIT(31) +#define SCMI_RESET_DOMAIN_ATTR_NOTIF BIT(30) + +/* Value for scmi_reset_domain_attributes_p2a:latency */ +#define SCMI_RESET_DOMAIN_ATTR_UNK_LAT 0x7fffffffU +#define SCMI_RESET_DOMAIN_ATTR_MAX_LAT 0x7ffffffeU + +/* Macro for scmi_reset_domain_attributes_p2a:name */ +#define SCMI_RESET_DOMAIN_ATTR_NAME_SZ 16U + +struct scmi_reset_domain_attributes_a2p { + uint32_t domain_id; +}; + +struct scmi_reset_domain_attributes_p2a { + int32_t status; + uint32_t flags; + uint32_t latency; + char name[SCMI_RESET_DOMAIN_ATTR_NAME_SZ]; +}; + +/* + * RESET + */ + +/* Values for scmi_reset_domain_request_a2p:flags */ +#define SCMI_RESET_DOMAIN_ASYNC BIT(2) +#define SCMI_RESET_DOMAIN_EXPLICIT BIT(1) +#define SCMI_RESET_DOMAIN_AUTO BIT(0) + +struct scmi_reset_domain_request_a2p { + uint32_t domain_id; + uint32_t flags; + uint32_t reset_state; +}; + +struct scmi_reset_domain_request_p2a { + int32_t status; +}; + +/* + * RESET_NOTIFY + */ + +/* Values for scmi_reset_notify_p2a:flags */ +#define SCMI_RESET_DOMAIN_DO_NOTIFY BIT(0) + +struct scmi_reset_domain_notify_a2p { + uint32_t domain_id; + uint32_t notify_enable; +}; + +struct scmi_reset_domain_notify_p2a { + int32_t status; +}; + +/* + * RESET_COMPLETE + */ + +struct scmi_reset_domain_complete_p2a { + int32_t status; + uint32_t domain_id; +}; + +/* + * RESET_ISSUED + */ + +struct scmi_reset_domain_issued_p2a { + uint32_t domain_id; + uint32_t reset_state; +}; + +#endif /* SCMI_MSG_RESET_DOMAIN_H */ diff --git a/include/drivers/st/scmi-msg.h b/include/drivers/st/scmi-msg.h index 48fac1685..8f7a788a8 100644 --- a/include/drivers/st/scmi-msg.h +++ b/include/drivers/st/scmi-msg.h @@ -141,4 +141,41 @@ int32_t plat_scmi_clock_get_state(unsigned int agent_id, unsigned int scmi_id); int32_t plat_scmi_clock_set_state(unsigned int agent_id, unsigned int scmi_id, bool enable_not_disable); +/* Handlers for SCMI Reset Domain protocol services */ + +/* + * Return number of reset domains for the agent + * @agent_id: SCMI agent ID + * Return number of reset domains + */ +size_t plat_scmi_rstd_count(unsigned int agent_id); + +/* + * Get reset domain string ID (aka name) + * @agent_id: SCMI agent ID + * @scmi_id: SCMI reset domain ID + * Return pointer to name or NULL + */ +const char *plat_scmi_rstd_get_name(unsigned int agent_id, unsigned int scmi_id); + +/* + * Perform a reset cycle on a target reset domain + * @agent_id: SCMI agent ID + * @scmi_id: SCMI reset domain ID + * @state: Target reset state (see SCMI specification, 0 means context loss) + * Return a compliant SCMI error code + */ +int32_t plat_scmi_rstd_autonomous(unsigned int agent_id, unsigned int scmi_id, + unsigned int state); + +/* + * Assert or deassert target reset domain + * @agent_id: SCMI agent ID + * @scmi_id: SCMI reset domain ID + * @assert_not_deassert: Assert domain if true, otherwise deassert domain + * Return a compliant SCMI error code + */ +int32_t plat_scmi_rstd_set_state(unsigned int agent_id, unsigned int scmi_id, + bool assert_not_deassert); + #endif /* SCMI_MSG_H */ -- cgit v1.2.3 From 7d6fa6ecbe6212480ad656731eeddf84291aeba5 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Fri, 1 May 2020 10:36:03 +0200 Subject: drivers/scmi-msg: smt entry points for incoming messages This change implements SCMI channels for reading a SCMI message from a shared memory and call the SCMI message drivers to route the message to the target platform services. SMT refers to the shared memory management protocol which is used to get/put message/response in shared memory. SMT is a 28byte header stating shared memory state and exchanged protocol data. The processing entry for a SCMI message can be a secure interrupt or fastcall SMCCC invocation. SMT description in this implementation is based on the OP-TEE project [1] itself based in the SCP-firmware implementation [2]. Link: [1] https://github.com/OP-TEE/optee_os/commit/a58c4d706d2333d2b21a3eba7e2ec0cb257bca1d Link: [2] https://github.com/ARM-software/SCP-firmware.git Change-Id: I416c7dab5c67954c6fe80bae8d8cdfdcda66873e Signed-off-by: Etienne Carriere --- drivers/st/scmi-msg/smt.c | 206 ++++++++++++++++++++++++++++++++++++++++++ include/drivers/st/scmi-msg.h | 26 ++++++ 2 files changed, 232 insertions(+) create mode 100644 drivers/st/scmi-msg/smt.c diff --git a/drivers/st/scmi-msg/smt.c b/drivers/st/scmi-msg/smt.c new file mode 100644 index 000000000..2d5cd734f --- /dev/null +++ b/drivers/st/scmi-msg/smt.c @@ -0,0 +1,206 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Linaro Limited + */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" + +/* Legacy SMT/SCMI messages are 128 bytes at most including SMT header */ +#define SCMI_PLAYLOAD_MAX 92U +#define SCMI_PLAYLOAD_U32_MAX (SCMI_PLAYLOAD_MAX / sizeof(uint32_t)) + +/** + * struct smt_header - SMT formatted header for SMT base shared memory transfer + * + * @status: Bit flags, see SMT_STATUS_* + * @flags: Bit flags, see SMT_FLAG_* + * @length: Byte size of message payload (variable) + ::message_header (32bit) + * payload: SCMI message payload data + */ +struct smt_header { + uint32_t reserved0; + uint32_t status; + uint64_t reserved1; + uint32_t flags; + uint32_t length; /* message_header + payload */ + uint32_t message_header; + uint32_t payload[]; +}; + +CASSERT(SCMI_PLAYLOAD_MAX + sizeof(struct smt_header) <= SMT_BUF_SLOT_SIZE, + assert_scmi_message_max_length_fits_in_smt_buffer_slot); + +/* Flag set in smt_header::status when SMT does not contain pending message */ +#define SMT_STATUS_FREE BIT(0) +/* Flag set in smt_header::status when SMT reports an error */ +#define SMT_STATUS_ERROR BIT(1) + +/* Flag set in smt_header::flags when SMT uses interrupts */ +#define SMT_FLAG_INTR_ENABLED BIT(1) + +/* Bit fields packed in smt_header::message_header */ +#define SMT_MSG_ID_MASK GENMASK_32(7, 0) +#define SMT_HDR_MSG_ID(_hdr) ((_hdr) & SMT_MSG_ID_MASK) + +#define SMT_MSG_TYPE_MASK GENMASK_32(9, 8) +#define SMT_HDR_TYPE_ID(_hdr) (((_hdr) & SMT_MSG_TYPE_MASK) >> 8) + +#define SMT_MSG_PROT_ID_MASK GENMASK_32(17, 10) +#define SMT_HDR_PROT_ID(_hdr) (((_hdr) & SMT_MSG_PROT_ID_MASK) >> 10) + +/* + * Provision input message payload buffers for fastcall SMC context entries + * and for interrupt context execution entries. + */ +static uint32_t fast_smc_payload[PLATFORM_CORE_COUNT][SCMI_PLAYLOAD_U32_MAX]; +static uint32_t interrupt_payload[PLATFORM_CORE_COUNT][SCMI_PLAYLOAD_U32_MAX]; + +/* SMP protection on channel access */ +static struct spinlock smt_channels_lock; + +/* If channel is not busy, set busy and return true, otherwise return false */ +static bool channel_set_busy(struct scmi_msg_channel *chan) +{ + bool channel_is_busy; + + spin_lock(&smt_channels_lock); + + channel_is_busy = chan->busy; + + if (!channel_is_busy) { + chan->busy = true; + } + + spin_unlock(&smt_channels_lock); + + return !channel_is_busy; +} + +static void channel_release_busy(struct scmi_msg_channel *chan) +{ + chan->busy = false; +} + +static struct smt_header *channel_to_smt_hdr(struct scmi_msg_channel *chan) +{ + return (struct smt_header *)chan->shm_addr; +} + +/* + * Creates a SCMI message instance in secure memory and pushes it in the SCMI + * message drivers. Message structure contains SCMI protocol meta-data and + * references to input payload in secure memory and output message buffer + * in shared memory. + */ +static void scmi_proccess_smt(unsigned int agent_id, uint32_t *payload_buf) +{ + struct scmi_msg_channel *chan; + struct smt_header *smt_hdr; + size_t in_payload_size; + uint32_t smt_status; + struct scmi_msg msg; + bool error = true; + + chan = plat_scmi_get_channel(agent_id); + if (chan == NULL) { + return; + } + + smt_hdr = channel_to_smt_hdr(chan); + assert(smt_hdr); + + smt_status = __atomic_load_n(&smt_hdr->status, __ATOMIC_RELAXED); + + if (!channel_set_busy(chan)) { + VERBOSE("SCMI channel %u busy", agent_id); + goto out; + } + + in_payload_size = __atomic_load_n(&smt_hdr->length, __ATOMIC_RELAXED) - + sizeof(smt_hdr->message_header); + + if (in_payload_size > SCMI_PLAYLOAD_MAX) { + VERBOSE("SCMI payload too big %u", in_payload_size); + goto out; + } + + if ((smt_status & (SMT_STATUS_ERROR | SMT_STATUS_FREE)) != 0U) { + VERBOSE("SCMI channel bad status 0x%x", + smt_hdr->status & (SMT_STATUS_ERROR | SMT_STATUS_FREE)); + goto out; + } + + /* Fill message */ + zeromem(&msg, sizeof(msg)); + msg.in = (char *)payload_buf; + msg.in_size = in_payload_size; + msg.out = (char *)smt_hdr->payload; + msg.out_size = chan->shm_size - sizeof(*smt_hdr); + + assert((msg.out != NULL) && (msg.out_size >= sizeof(int32_t))); + + /* Here the payload is copied in secure memory */ + memcpy(msg.in, smt_hdr->payload, in_payload_size); + + msg.protocol_id = SMT_HDR_PROT_ID(smt_hdr->message_header); + msg.message_id = SMT_HDR_MSG_ID(smt_hdr->message_header); + msg.agent_id = agent_id; + + scmi_process_message(&msg); + + /* Update message length with the length of the response message */ + smt_hdr->length = msg.out_size_out + sizeof(smt_hdr->message_header); + + channel_release_busy(chan); + error = false; + +out: + if (error) { + VERBOSE("SCMI error"); + smt_hdr->status |= SMT_STATUS_ERROR | SMT_STATUS_FREE; + } else { + smt_hdr->status |= SMT_STATUS_FREE; + } +} + +void scmi_smt_fastcall_smc_entry(unsigned int agent_id) +{ + scmi_proccess_smt(agent_id, + fast_smc_payload[plat_my_core_pos()]); +} + +void scmi_smt_interrupt_entry(unsigned int agent_id) +{ + scmi_proccess_smt(agent_id, + interrupt_payload[plat_my_core_pos()]); +} + +/* Init a SMT header for a shared memory buffer: state it a free/no-error */ +void scmi_smt_init_agent_channel(struct scmi_msg_channel *chan) +{ + if (chan != NULL) { + struct smt_header *smt_header = channel_to_smt_hdr(chan); + + if (smt_header != NULL) { + memset(smt_header, 0, sizeof(*smt_header)); + smt_header->status = SMT_STATUS_FREE; + + return; + } + } + + panic(); +} diff --git a/include/drivers/st/scmi-msg.h b/include/drivers/st/scmi-msg.h index 8f7a788a8..a9a99cf52 100644 --- a/include/drivers/st/scmi-msg.h +++ b/include/drivers/st/scmi-msg.h @@ -32,6 +32,32 @@ struct scmi_msg_channel { const char *agent_name; }; +/* + * Initialize SMT memory buffer, called by platform at init for each + * agent channel using the SMT header format. + * + * @chan: Pointer to the channel shared memory to be initialized + */ +void scmi_smt_init_agent_channel(struct scmi_msg_channel *chan); + +/* + * Process SMT formatted message in a fastcall SMC execution context. + * Called by platform on SMC entry. When returning, output message is + * available in shared memory for agent to read the response. + * + * @agent_id: SCMI agent ID the SMT belongs to + */ +void scmi_smt_fastcall_smc_entry(unsigned int agent_id); + +/* + * Process SMT formatted message in a secure interrupt execution context. + * Called by platform interrupt handler. When returning, output message is + * available in shared memory for agent to read the response. + * + * @agent_id: SCMI agent ID the SMT belongs to + */ +void scmi_smt_interrupt_entry(unsigned int agent_id); + /* Platform callback functions */ /* -- cgit v1.2.3 From b5c850d48d49fd1afc3b8189bc2390f53770d4de Mon Sep 17 00:00:00 2001 From: Marcin Wojtas Date: Thu, 18 Jun 2020 19:50:47 +0200 Subject: plat: marvell: armada: modify PLAT_FAMILY name for 37xx SoCs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Marvell Armada 37xx SoCs-based platforms contain a bit awkward directory structure because the currently only one supported PLAT and PLAT_FAMILY are the same. Modify the latter to 'a3k' in order to improve it and keep plat/marvell/armada tree more consistent: plat/marvell/ ├── armada │   ├── a3k │   │   ├── a3700 [...] │   ├── a8k │   │   ├── a70x0 [...] Change-Id: I693a6ef88e6ce49a326a3328875c90bbc186066a Signed-off-by: Marcin Wojtas --- .../marvell/armada/a3700/common/armada_common.h | 17 - .../armada/a3700/common/board_marvell_def.h | 76 -- .../plat/marvell/armada/a3700/common/marvell_def.h | 177 ----- .../marvell/armada/a3700/common/plat_marvell.h | 103 --- .../plat/marvell/armada/a3k/common/armada_common.h | 17 + .../marvell/armada/a3k/common/board_marvell_def.h | 76 ++ .../plat/marvell/armada/a3k/common/marvell_def.h | 177 +++++ .../plat/marvell/armada/a3k/common/plat_marvell.h | 103 +++ plat/marvell/armada/a3700/a3700/board/pm_src.c | 37 - plat/marvell/armada/a3700/a3700/mvebu_def.h | 13 - plat/marvell/armada/a3700/a3700/plat_bl31_setup.c | 70 -- plat/marvell/armada/a3700/a3700/platform.mk | 10 - plat/marvell/armada/a3700/common/a3700_common.mk | 170 ----- plat/marvell/armada/a3700/common/a3700_ea.c | 23 - plat/marvell/armada/a3700/common/a3700_sip_svc.c | 84 --- .../armada/a3700/common/aarch64/a3700_common.c | 53 -- .../armada/a3700/common/aarch64/plat_helpers.S | 68 -- plat/marvell/armada/a3700/common/dram_win.c | 278 ------- .../armada/a3700/common/include/a3700_plat_def.h | 122 ---- .../marvell/armada/a3700/common/include/a3700_pm.h | 51 -- .../marvell/armada/a3700/common/include/ddr_info.h | 14 - .../marvell/armada/a3700/common/include/dram_win.h | 18 - .../armada/a3700/common/include/io_addr_dec.h | 66 -- .../armada/a3700/common/include/plat_macros.S | 26 - .../armada/a3700/common/include/platform_def.h | 232 ------ plat/marvell/armada/a3700/common/io_addr_dec.c | 179 ----- .../armada/a3700/common/marvell_plat_config.c | 34 - plat/marvell/armada/a3700/common/plat_pm.c | 807 --------------------- plat/marvell/armada/a3k/a3700/board/pm_src.c | 37 + plat/marvell/armada/a3k/a3700/mvebu_def.h | 13 + plat/marvell/armada/a3k/a3700/plat_bl31_setup.c | 70 ++ plat/marvell/armada/a3k/a3700/platform.mk | 10 + plat/marvell/armada/a3k/common/a3700_common.mk | 170 +++++ plat/marvell/armada/a3k/common/a3700_ea.c | 23 + plat/marvell/armada/a3k/common/a3700_sip_svc.c | 84 +++ .../armada/a3k/common/aarch64/a3700_common.c | 53 ++ .../armada/a3k/common/aarch64/plat_helpers.S | 68 ++ plat/marvell/armada/a3k/common/dram_win.c | 278 +++++++ .../armada/a3k/common/include/a3700_plat_def.h | 122 ++++ plat/marvell/armada/a3k/common/include/a3700_pm.h | 51 ++ plat/marvell/armada/a3k/common/include/ddr_info.h | 14 + plat/marvell/armada/a3k/common/include/dram_win.h | 18 + .../armada/a3k/common/include/io_addr_dec.h | 66 ++ .../armada/a3k/common/include/plat_macros.S | 26 + .../armada/a3k/common/include/platform_def.h | 232 ++++++ plat/marvell/armada/a3k/common/io_addr_dec.c | 179 +++++ .../armada/a3k/common/marvell_plat_config.c | 34 + plat/marvell/armada/a3k/common/plat_pm.c | 807 +++++++++++++++++++++ 48 files changed, 2728 insertions(+), 2728 deletions(-) delete mode 100644 include/plat/marvell/armada/a3700/common/armada_common.h delete mode 100644 include/plat/marvell/armada/a3700/common/board_marvell_def.h delete mode 100644 include/plat/marvell/armada/a3700/common/marvell_def.h delete mode 100644 include/plat/marvell/armada/a3700/common/plat_marvell.h create mode 100644 include/plat/marvell/armada/a3k/common/armada_common.h create mode 100644 include/plat/marvell/armada/a3k/common/board_marvell_def.h create mode 100644 include/plat/marvell/armada/a3k/common/marvell_def.h create mode 100644 include/plat/marvell/armada/a3k/common/plat_marvell.h delete mode 100644 plat/marvell/armada/a3700/a3700/board/pm_src.c delete mode 100644 plat/marvell/armada/a3700/a3700/mvebu_def.h delete mode 100644 plat/marvell/armada/a3700/a3700/plat_bl31_setup.c delete mode 100644 plat/marvell/armada/a3700/a3700/platform.mk delete mode 100644 plat/marvell/armada/a3700/common/a3700_common.mk delete mode 100644 plat/marvell/armada/a3700/common/a3700_ea.c delete mode 100644 plat/marvell/armada/a3700/common/a3700_sip_svc.c delete mode 100644 plat/marvell/armada/a3700/common/aarch64/a3700_common.c delete mode 100644 plat/marvell/armada/a3700/common/aarch64/plat_helpers.S delete mode 100644 plat/marvell/armada/a3700/common/dram_win.c delete mode 100644 plat/marvell/armada/a3700/common/include/a3700_plat_def.h delete mode 100644 plat/marvell/armada/a3700/common/include/a3700_pm.h delete mode 100644 plat/marvell/armada/a3700/common/include/ddr_info.h delete mode 100644 plat/marvell/armada/a3700/common/include/dram_win.h delete mode 100644 plat/marvell/armada/a3700/common/include/io_addr_dec.h delete mode 100644 plat/marvell/armada/a3700/common/include/plat_macros.S delete mode 100644 plat/marvell/armada/a3700/common/include/platform_def.h delete mode 100644 plat/marvell/armada/a3700/common/io_addr_dec.c delete mode 100644 plat/marvell/armada/a3700/common/marvell_plat_config.c delete mode 100644 plat/marvell/armada/a3700/common/plat_pm.c create mode 100644 plat/marvell/armada/a3k/a3700/board/pm_src.c create mode 100644 plat/marvell/armada/a3k/a3700/mvebu_def.h create mode 100644 plat/marvell/armada/a3k/a3700/plat_bl31_setup.c create mode 100644 plat/marvell/armada/a3k/a3700/platform.mk create mode 100644 plat/marvell/armada/a3k/common/a3700_common.mk create mode 100644 plat/marvell/armada/a3k/common/a3700_ea.c create mode 100644 plat/marvell/armada/a3k/common/a3700_sip_svc.c create mode 100644 plat/marvell/armada/a3k/common/aarch64/a3700_common.c create mode 100644 plat/marvell/armada/a3k/common/aarch64/plat_helpers.S create mode 100644 plat/marvell/armada/a3k/common/dram_win.c create mode 100644 plat/marvell/armada/a3k/common/include/a3700_plat_def.h create mode 100644 plat/marvell/armada/a3k/common/include/a3700_pm.h create mode 100644 plat/marvell/armada/a3k/common/include/ddr_info.h create mode 100644 plat/marvell/armada/a3k/common/include/dram_win.h create mode 100644 plat/marvell/armada/a3k/common/include/io_addr_dec.h create mode 100644 plat/marvell/armada/a3k/common/include/plat_macros.S create mode 100644 plat/marvell/armada/a3k/common/include/platform_def.h create mode 100644 plat/marvell/armada/a3k/common/io_addr_dec.c create mode 100644 plat/marvell/armada/a3k/common/marvell_plat_config.c create mode 100644 plat/marvell/armada/a3k/common/plat_pm.c diff --git a/include/plat/marvell/armada/a3700/common/armada_common.h b/include/plat/marvell/armada/a3700/common/armada_common.h deleted file mode 100644 index c6953fb71..000000000 --- a/include/plat/marvell/armada/a3700/common/armada_common.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef ARMADA_COMMON_H -#define ARMADA_COMMON_H - -#include - -#include - -int marvell_get_io_dec_win_conf(struct dec_win_config **win, uint32_t *size); - -#endif /* ARMADA_COMMON_H */ diff --git a/include/plat/marvell/armada/a3700/common/board_marvell_def.h b/include/plat/marvell/armada/a3700/common/board_marvell_def.h deleted file mode 100644 index 178259662..000000000 --- a/include/plat/marvell/armada/a3700/common/board_marvell_def.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef BOARD_MARVELL_DEF_H -#define BOARD_MARVELL_DEF_H - -/* - * Required platform porting definitions common to all ARM - * development platforms - */ - -/* Size of cacheable stacks */ -#if IMAGE_BL1 -#if TRUSTED_BOARD_BOOT -# define PLATFORM_STACK_SIZE 0x1000 -#else -# define PLATFORM_STACK_SIZE 0x440 -#endif -#elif IMAGE_BL2 -# if TRUSTED_BOARD_BOOT -# define PLATFORM_STACK_SIZE 0x1000 -# else -# define PLATFORM_STACK_SIZE 0x400 -# endif -#elif IMAGE_BL31 -# define PLATFORM_STACK_SIZE 0x400 -#elif IMAGE_BL32 -# define PLATFORM_STACK_SIZE 0x440 -#endif - -/* - * PLAT_MARVELL_MMAP_ENTRIES depends on the number of entries in the - * plat_arm_mmap array defined for each BL stage. - */ -#if IMAGE_BLE -# define PLAT_MARVELL_MMAP_ENTRIES 3 -#endif -#if IMAGE_BL1 -# if TRUSTED_BOARD_BOOT -# define PLAT_MARVELL_MMAP_ENTRIES 7 -# else -# define PLAT_MARVELL_MMAP_ENTRIES 6 -# endif /* TRUSTED_BOARD_BOOT */ -#endif -#if IMAGE_BL2 -# define PLAT_MARVELL_MMAP_ENTRIES 8 -#endif -#if IMAGE_BL31 -#define PLAT_MARVELL_MMAP_ENTRIES 5 -#endif - -/* - * Platform specific page table and MMU setup constants - */ -#if IMAGE_BL1 -#define MAX_XLAT_TABLES 4 -#elif IMAGE_BLE -# define MAX_XLAT_TABLES 4 -#elif IMAGE_BL2 -# define MAX_XLAT_TABLES 4 -#elif IMAGE_BL31 -# define MAX_XLAT_TABLES 4 -#elif IMAGE_BL32 -# define MAX_XLAT_TABLES 4 -#endif - -#define MAX_IO_DEVICES 3 -#define MAX_IO_HANDLES 4 - -#define PLAT_MARVELL_TRUSTED_SRAM_SIZE 0x80000 /* 512 KB */ - -#endif /* BOARD_MARVELL_DEF_H */ diff --git a/include/plat/marvell/armada/a3700/common/marvell_def.h b/include/plat/marvell/armada/a3700/common/marvell_def.h deleted file mode 100644 index eb13ba8af..000000000 --- a/include/plat/marvell/armada/a3700/common/marvell_def.h +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef MARVELL_DEF_H -#define MARVELL_DEF_H - -#include - -#include -#include -#include -#include - -/**************************************************************************** - * Definitions common to all MARVELL standard platforms - **************************************************************************** - */ -/* Special value used to verify platform parameters from BL2 to BL31 */ -#define MARVELL_BL31_PLAT_PARAM_VAL 0x0f1e2d3c4b5a6978ULL - -#define PLAT_MARVELL_NORTHB_COUNT 1 - -#define PLAT_MARVELL_CLUSTER_COUNT 1 - -#define MARVELL_CACHE_WRITEBACK_SHIFT 6 - -/* - * Macros mapping the MPIDR Affinity levels to MARVELL Platform Power levels. - * The power levels have a 1:1 mapping with the MPIDR affinity levels. - */ -#define MARVELL_PWR_LVL0 MPIDR_AFFLVL0 -#define MARVELL_PWR_LVL1 MPIDR_AFFLVL1 -#define MARVELL_PWR_LVL2 MPIDR_AFFLVL2 - -/* - * Macros for local power states in Marvell platforms encoded by State-ID field - * within the power-state parameter. - */ -/* Local power state for power domains in Run state. */ -#define MARVELL_LOCAL_STATE_RUN 0 -/* Local power state for retention. Valid only for CPU power domains */ -#define MARVELL_LOCAL_STATE_RET 1 -/* Local power state for OFF/power-down. - * Valid for CPU and cluster power domains - */ -#define MARVELL_LOCAL_STATE_OFF 2 - -/* The first 4KB of Trusted SRAM are used as shared memory */ -#define MARVELL_TRUSTED_SRAM_BASE PLAT_MARVELL_ATF_BASE -#define MARVELL_SHARED_RAM_BASE MARVELL_TRUSTED_SRAM_BASE -#define MARVELL_SHARED_RAM_SIZE 0x00001000 /* 4 KB */ - -/* The remaining Trusted SRAM is used to load the BL images */ -#define MARVELL_BL_RAM_BASE (MARVELL_SHARED_RAM_BASE + \ - MARVELL_SHARED_RAM_SIZE) -#define MARVELL_BL_RAM_SIZE (PLAT_MARVELL_TRUSTED_SRAM_SIZE - \ - MARVELL_SHARED_RAM_SIZE) - -#define MARVELL_DRAM_BASE ULL(0x0) -#define MARVELL_DRAM_SIZE ULL(0x20000000) -#define MARVELL_DRAM_END (MARVELL_DRAM_BASE + \ - MARVELL_DRAM_SIZE - 1) - -#define MARVELL_IRQ_SEC_PHY_TIMER 29 - -#define MARVELL_IRQ_SEC_SGI_0 8 -#define MARVELL_IRQ_SEC_SGI_1 9 -#define MARVELL_IRQ_SEC_SGI_2 10 -#define MARVELL_IRQ_SEC_SGI_3 11 -#define MARVELL_IRQ_SEC_SGI_4 12 -#define MARVELL_IRQ_SEC_SGI_5 13 -#define MARVELL_IRQ_SEC_SGI_6 14 -#define MARVELL_IRQ_SEC_SGI_7 15 - -#define MARVELL_MAP_SHARED_RAM MAP_REGION_FLAT( \ - MARVELL_SHARED_RAM_BASE, \ - MARVELL_SHARED_RAM_SIZE, \ - MT_MEMORY | MT_RW | MT_SECURE) - -#define MARVELL_MAP_DRAM MAP_REGION_FLAT( \ - MARVELL_DRAM_BASE, \ - MARVELL_DRAM_SIZE, \ - MT_MEMORY | MT_RW | MT_NS) - - -/* - * The number of regions like RO(code), coherent and data required by - * different BL stages which need to be mapped in the MMU. - */ -#if USE_COHERENT_MEM -#define MARVELL_BL_REGIONS 3 -#else -#define MARVELL_BL_REGIONS 2 -#endif - -#define MAX_MMAP_REGIONS (PLAT_MARVELL_MMAP_ENTRIES + \ - MARVELL_BL_REGIONS) - -#define MARVELL_CONSOLE_BAUDRATE 115200 - -/**************************************************************************** - * Required platform porting definitions common to all MARVELL std. platforms - **************************************************************************** - */ -#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) -#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) - -/* - * 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 MARVELL_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 MARVELL_LOCAL_STATE_OFF - - -#define PLATFORM_CORE_COUNT PLAT_MARVELL_CLUSTER_CORE_COUNT - -/* - * 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 << MARVELL_CACHE_WRITEBACK_SHIFT) - - -/***************************************************************************** - * BL1 specific defines. - * BL1 RW data is relocated from ROM to RAM at runtime so we need 2 sets of - * addresses. - ***************************************************************************** - */ -#define BL1_RO_BASE PLAT_MARVELL_TRUSTED_ROM_BASE -#define BL1_RO_LIMIT (PLAT_MARVELL_TRUSTED_ROM_BASE \ - + PLAT_MARVELL_TRUSTED_ROM_SIZE) -/* - * Put BL1 RW at the top of the Trusted SRAM. - */ -#define BL1_RW_BASE (MARVELL_BL_RAM_BASE + \ - MARVELL_BL_RAM_SIZE - \ - PLAT_MARVELL_MAX_BL1_RW_SIZE) -#define BL1_RW_LIMIT (MARVELL_BL_RAM_BASE + MARVELL_BL_RAM_SIZE) - -/***************************************************************************** - * BL2 specific defines. - ***************************************************************************** - */ -/* - * Put BL2 just below BL31. - */ -#define BL2_BASE (BL31_BASE - PLAT_MARVELL_MAX_BL2_SIZE) -#define BL2_LIMIT BL31_BASE - -/***************************************************************************** - * BL31 specific defines. - ***************************************************************************** - */ -/* - * Put BL31 at the top of the Trusted SRAM. - */ -#define BL31_BASE (MARVELL_BL_RAM_BASE + \ - MARVELL_BL_RAM_SIZE - \ - PLAT_MARVEL_MAX_BL31_SIZE) -#define BL31_PROGBITS_LIMIT BL1_RW_BASE -#define BL31_LIMIT (MARVELL_BL_RAM_BASE + \ - MARVELL_BL_RAM_SIZE) - - -#endif /* MARVELL_DEF_H */ diff --git a/include/plat/marvell/armada/a3700/common/plat_marvell.h b/include/plat/marvell/armada/a3700/common/plat_marvell.h deleted file mode 100644 index ea7cdcd4c..000000000 --- a/include/plat/marvell/armada/a3700/common/plat_marvell.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2016 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef PLAT_MARVELL_H -#define PLAT_MARVELL_H - -#include - -#include -#include -#include -#include - -/* - * Extern declarations common to Marvell standard platforms - */ -extern const mmap_region_t plat_marvell_mmap[]; - -#define MARVELL_CASSERT_MMAP \ - CASSERT((ARRAY_SIZE(plat_marvell_mmap) + MARVELL_BL_REGIONS) \ - <= MAX_MMAP_REGIONS, \ - assert_max_mmap_regions) - -/* - * Utility functions common to Marvell standard platforms - */ -void marvell_setup_page_tables(uintptr_t total_base, - size_t total_size, - uintptr_t code_start, - uintptr_t code_limit, - uintptr_t rodata_start, - uintptr_t rodata_limit -#if USE_COHERENT_MEM - , uintptr_t coh_start, - uintptr_t coh_limit -#endif -); - -/* Console utility functions */ -void marvell_console_boot_init(void); -void marvell_console_boot_end(void); -void marvell_console_runtime_init(void); -void marvell_console_runtime_end(void); - -/* IO storage utility functions */ -void marvell_io_setup(void); - -/* Systimer utility function */ -void marvell_configure_sys_timer(void); - -/* Topology utility function */ -int marvell_check_mpidr(u_register_t mpidr); - -/* BL1 utility functions */ -void marvell_bl1_early_platform_setup(void); -void marvell_bl1_platform_setup(void); -void marvell_bl1_plat_arch_setup(void); - -/* BL2 utility functions */ -void marvell_bl2_early_platform_setup(meminfo_t *mem_layout); -void marvell_bl2_platform_setup(void); -void marvell_bl2_plat_arch_setup(void); -uint32_t marvell_get_spsr_for_bl32_entry(void); -uint32_t marvell_get_spsr_for_bl33_entry(void); - -/* BL31 utility functions */ -void marvell_bl31_early_platform_setup(void *from_bl2, - uintptr_t soc_fw_config, - uintptr_t hw_config, - void *plat_params_from_bl2); -void marvell_bl31_platform_setup(void); -void marvell_bl31_plat_runtime_setup(void); -void marvell_bl31_plat_arch_setup(void); - -/* FIP TOC validity check */ -int marvell_io_is_toc_valid(void); - -/* - * PSCI functionality - */ -void marvell_psci_arch_init(int idx); -void plat_marvell_system_reset(void); - -/* - * Optional functions required in Marvell standard platforms - */ -void plat_marvell_io_setup(void); -int plat_marvell_get_alt_image_source( - unsigned int image_id, - uintptr_t *dev_handle, - uintptr_t *image_spec); -unsigned int plat_marvell_calc_core_pos(u_register_t mpidr); - -void plat_marvell_interconnect_init(void); -void plat_marvell_interconnect_enter_coherency(void); - -const mmap_region_t *plat_marvell_get_mmap(void); - -#endif /* PLAT_MARVELL_H */ diff --git a/include/plat/marvell/armada/a3k/common/armada_common.h b/include/plat/marvell/armada/a3k/common/armada_common.h new file mode 100644 index 000000000..c6953fb71 --- /dev/null +++ b/include/plat/marvell/armada/a3k/common/armada_common.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef ARMADA_COMMON_H +#define ARMADA_COMMON_H + +#include + +#include + +int marvell_get_io_dec_win_conf(struct dec_win_config **win, uint32_t *size); + +#endif /* ARMADA_COMMON_H */ diff --git a/include/plat/marvell/armada/a3k/common/board_marvell_def.h b/include/plat/marvell/armada/a3k/common/board_marvell_def.h new file mode 100644 index 000000000..178259662 --- /dev/null +++ b/include/plat/marvell/armada/a3k/common/board_marvell_def.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef BOARD_MARVELL_DEF_H +#define BOARD_MARVELL_DEF_H + +/* + * Required platform porting definitions common to all ARM + * development platforms + */ + +/* Size of cacheable stacks */ +#if IMAGE_BL1 +#if TRUSTED_BOARD_BOOT +# define PLATFORM_STACK_SIZE 0x1000 +#else +# define PLATFORM_STACK_SIZE 0x440 +#endif +#elif IMAGE_BL2 +# if TRUSTED_BOARD_BOOT +# define PLATFORM_STACK_SIZE 0x1000 +# else +# define PLATFORM_STACK_SIZE 0x400 +# endif +#elif IMAGE_BL31 +# define PLATFORM_STACK_SIZE 0x400 +#elif IMAGE_BL32 +# define PLATFORM_STACK_SIZE 0x440 +#endif + +/* + * PLAT_MARVELL_MMAP_ENTRIES depends on the number of entries in the + * plat_arm_mmap array defined for each BL stage. + */ +#if IMAGE_BLE +# define PLAT_MARVELL_MMAP_ENTRIES 3 +#endif +#if IMAGE_BL1 +# if TRUSTED_BOARD_BOOT +# define PLAT_MARVELL_MMAP_ENTRIES 7 +# else +# define PLAT_MARVELL_MMAP_ENTRIES 6 +# endif /* TRUSTED_BOARD_BOOT */ +#endif +#if IMAGE_BL2 +# define PLAT_MARVELL_MMAP_ENTRIES 8 +#endif +#if IMAGE_BL31 +#define PLAT_MARVELL_MMAP_ENTRIES 5 +#endif + +/* + * Platform specific page table and MMU setup constants + */ +#if IMAGE_BL1 +#define MAX_XLAT_TABLES 4 +#elif IMAGE_BLE +# define MAX_XLAT_TABLES 4 +#elif IMAGE_BL2 +# define MAX_XLAT_TABLES 4 +#elif IMAGE_BL31 +# define MAX_XLAT_TABLES 4 +#elif IMAGE_BL32 +# define MAX_XLAT_TABLES 4 +#endif + +#define MAX_IO_DEVICES 3 +#define MAX_IO_HANDLES 4 + +#define PLAT_MARVELL_TRUSTED_SRAM_SIZE 0x80000 /* 512 KB */ + +#endif /* BOARD_MARVELL_DEF_H */ diff --git a/include/plat/marvell/armada/a3k/common/marvell_def.h b/include/plat/marvell/armada/a3k/common/marvell_def.h new file mode 100644 index 000000000..eb13ba8af --- /dev/null +++ b/include/plat/marvell/armada/a3k/common/marvell_def.h @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef MARVELL_DEF_H +#define MARVELL_DEF_H + +#include + +#include +#include +#include +#include + +/**************************************************************************** + * Definitions common to all MARVELL standard platforms + **************************************************************************** + */ +/* Special value used to verify platform parameters from BL2 to BL31 */ +#define MARVELL_BL31_PLAT_PARAM_VAL 0x0f1e2d3c4b5a6978ULL + +#define PLAT_MARVELL_NORTHB_COUNT 1 + +#define PLAT_MARVELL_CLUSTER_COUNT 1 + +#define MARVELL_CACHE_WRITEBACK_SHIFT 6 + +/* + * Macros mapping the MPIDR Affinity levels to MARVELL Platform Power levels. + * The power levels have a 1:1 mapping with the MPIDR affinity levels. + */ +#define MARVELL_PWR_LVL0 MPIDR_AFFLVL0 +#define MARVELL_PWR_LVL1 MPIDR_AFFLVL1 +#define MARVELL_PWR_LVL2 MPIDR_AFFLVL2 + +/* + * Macros for local power states in Marvell platforms encoded by State-ID field + * within the power-state parameter. + */ +/* Local power state for power domains in Run state. */ +#define MARVELL_LOCAL_STATE_RUN 0 +/* Local power state for retention. Valid only for CPU power domains */ +#define MARVELL_LOCAL_STATE_RET 1 +/* Local power state for OFF/power-down. + * Valid for CPU and cluster power domains + */ +#define MARVELL_LOCAL_STATE_OFF 2 + +/* The first 4KB of Trusted SRAM are used as shared memory */ +#define MARVELL_TRUSTED_SRAM_BASE PLAT_MARVELL_ATF_BASE +#define MARVELL_SHARED_RAM_BASE MARVELL_TRUSTED_SRAM_BASE +#define MARVELL_SHARED_RAM_SIZE 0x00001000 /* 4 KB */ + +/* The remaining Trusted SRAM is used to load the BL images */ +#define MARVELL_BL_RAM_BASE (MARVELL_SHARED_RAM_BASE + \ + MARVELL_SHARED_RAM_SIZE) +#define MARVELL_BL_RAM_SIZE (PLAT_MARVELL_TRUSTED_SRAM_SIZE - \ + MARVELL_SHARED_RAM_SIZE) + +#define MARVELL_DRAM_BASE ULL(0x0) +#define MARVELL_DRAM_SIZE ULL(0x20000000) +#define MARVELL_DRAM_END (MARVELL_DRAM_BASE + \ + MARVELL_DRAM_SIZE - 1) + +#define MARVELL_IRQ_SEC_PHY_TIMER 29 + +#define MARVELL_IRQ_SEC_SGI_0 8 +#define MARVELL_IRQ_SEC_SGI_1 9 +#define MARVELL_IRQ_SEC_SGI_2 10 +#define MARVELL_IRQ_SEC_SGI_3 11 +#define MARVELL_IRQ_SEC_SGI_4 12 +#define MARVELL_IRQ_SEC_SGI_5 13 +#define MARVELL_IRQ_SEC_SGI_6 14 +#define MARVELL_IRQ_SEC_SGI_7 15 + +#define MARVELL_MAP_SHARED_RAM MAP_REGION_FLAT( \ + MARVELL_SHARED_RAM_BASE, \ + MARVELL_SHARED_RAM_SIZE, \ + MT_MEMORY | MT_RW | MT_SECURE) + +#define MARVELL_MAP_DRAM MAP_REGION_FLAT( \ + MARVELL_DRAM_BASE, \ + MARVELL_DRAM_SIZE, \ + MT_MEMORY | MT_RW | MT_NS) + + +/* + * The number of regions like RO(code), coherent and data required by + * different BL stages which need to be mapped in the MMU. + */ +#if USE_COHERENT_MEM +#define MARVELL_BL_REGIONS 3 +#else +#define MARVELL_BL_REGIONS 2 +#endif + +#define MAX_MMAP_REGIONS (PLAT_MARVELL_MMAP_ENTRIES + \ + MARVELL_BL_REGIONS) + +#define MARVELL_CONSOLE_BAUDRATE 115200 + +/**************************************************************************** + * Required platform porting definitions common to all MARVELL std. platforms + **************************************************************************** + */ +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) + +/* + * 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 MARVELL_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 MARVELL_LOCAL_STATE_OFF + + +#define PLATFORM_CORE_COUNT PLAT_MARVELL_CLUSTER_CORE_COUNT + +/* + * 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 << MARVELL_CACHE_WRITEBACK_SHIFT) + + +/***************************************************************************** + * BL1 specific defines. + * BL1 RW data is relocated from ROM to RAM at runtime so we need 2 sets of + * addresses. + ***************************************************************************** + */ +#define BL1_RO_BASE PLAT_MARVELL_TRUSTED_ROM_BASE +#define BL1_RO_LIMIT (PLAT_MARVELL_TRUSTED_ROM_BASE \ + + PLAT_MARVELL_TRUSTED_ROM_SIZE) +/* + * Put BL1 RW at the top of the Trusted SRAM. + */ +#define BL1_RW_BASE (MARVELL_BL_RAM_BASE + \ + MARVELL_BL_RAM_SIZE - \ + PLAT_MARVELL_MAX_BL1_RW_SIZE) +#define BL1_RW_LIMIT (MARVELL_BL_RAM_BASE + MARVELL_BL_RAM_SIZE) + +/***************************************************************************** + * BL2 specific defines. + ***************************************************************************** + */ +/* + * Put BL2 just below BL31. + */ +#define BL2_BASE (BL31_BASE - PLAT_MARVELL_MAX_BL2_SIZE) +#define BL2_LIMIT BL31_BASE + +/***************************************************************************** + * BL31 specific defines. + ***************************************************************************** + */ +/* + * Put BL31 at the top of the Trusted SRAM. + */ +#define BL31_BASE (MARVELL_BL_RAM_BASE + \ + MARVELL_BL_RAM_SIZE - \ + PLAT_MARVEL_MAX_BL31_SIZE) +#define BL31_PROGBITS_LIMIT BL1_RW_BASE +#define BL31_LIMIT (MARVELL_BL_RAM_BASE + \ + MARVELL_BL_RAM_SIZE) + + +#endif /* MARVELL_DEF_H */ diff --git a/include/plat/marvell/armada/a3k/common/plat_marvell.h b/include/plat/marvell/armada/a3k/common/plat_marvell.h new file mode 100644 index 000000000..ea7cdcd4c --- /dev/null +++ b/include/plat/marvell/armada/a3k/common/plat_marvell.h @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2016 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef PLAT_MARVELL_H +#define PLAT_MARVELL_H + +#include + +#include +#include +#include +#include + +/* + * Extern declarations common to Marvell standard platforms + */ +extern const mmap_region_t plat_marvell_mmap[]; + +#define MARVELL_CASSERT_MMAP \ + CASSERT((ARRAY_SIZE(plat_marvell_mmap) + MARVELL_BL_REGIONS) \ + <= MAX_MMAP_REGIONS, \ + assert_max_mmap_regions) + +/* + * Utility functions common to Marvell standard platforms + */ +void marvell_setup_page_tables(uintptr_t total_base, + size_t total_size, + uintptr_t code_start, + uintptr_t code_limit, + uintptr_t rodata_start, + uintptr_t rodata_limit +#if USE_COHERENT_MEM + , uintptr_t coh_start, + uintptr_t coh_limit +#endif +); + +/* Console utility functions */ +void marvell_console_boot_init(void); +void marvell_console_boot_end(void); +void marvell_console_runtime_init(void); +void marvell_console_runtime_end(void); + +/* IO storage utility functions */ +void marvell_io_setup(void); + +/* Systimer utility function */ +void marvell_configure_sys_timer(void); + +/* Topology utility function */ +int marvell_check_mpidr(u_register_t mpidr); + +/* BL1 utility functions */ +void marvell_bl1_early_platform_setup(void); +void marvell_bl1_platform_setup(void); +void marvell_bl1_plat_arch_setup(void); + +/* BL2 utility functions */ +void marvell_bl2_early_platform_setup(meminfo_t *mem_layout); +void marvell_bl2_platform_setup(void); +void marvell_bl2_plat_arch_setup(void); +uint32_t marvell_get_spsr_for_bl32_entry(void); +uint32_t marvell_get_spsr_for_bl33_entry(void); + +/* BL31 utility functions */ +void marvell_bl31_early_platform_setup(void *from_bl2, + uintptr_t soc_fw_config, + uintptr_t hw_config, + void *plat_params_from_bl2); +void marvell_bl31_platform_setup(void); +void marvell_bl31_plat_runtime_setup(void); +void marvell_bl31_plat_arch_setup(void); + +/* FIP TOC validity check */ +int marvell_io_is_toc_valid(void); + +/* + * PSCI functionality + */ +void marvell_psci_arch_init(int idx); +void plat_marvell_system_reset(void); + +/* + * Optional functions required in Marvell standard platforms + */ +void plat_marvell_io_setup(void); +int plat_marvell_get_alt_image_source( + unsigned int image_id, + uintptr_t *dev_handle, + uintptr_t *image_spec); +unsigned int plat_marvell_calc_core_pos(u_register_t mpidr); + +void plat_marvell_interconnect_init(void); +void plat_marvell_interconnect_enter_coherency(void); + +const mmap_region_t *plat_marvell_get_mmap(void); + +#endif /* PLAT_MARVELL_H */ diff --git a/plat/marvell/armada/a3700/a3700/board/pm_src.c b/plat/marvell/armada/a3700/a3700/board/pm_src.c deleted file mode 100644 index d6eca5d16..000000000 --- a/plat/marvell/armada/a3700/a3700/board/pm_src.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include - -/* This struct provides the PM wake up src configuration */ -static struct pm_wake_up_src_config wake_up_src_cfg = { - .wake_up_src_num = 3, - .wake_up_src[0] = { - .wake_up_src_type = WAKE_UP_SRC_GPIO, - .wake_up_data = { - .gpio_data.bank_num = 0, /* North Bridge */ - .gpio_data.gpio_num = 14 - } - }, - .wake_up_src[1] = { - .wake_up_src_type = WAKE_UP_SRC_GPIO, - .wake_up_data = { - .gpio_data.bank_num = 1, /* South Bridge */ - .gpio_data.gpio_num = 2 - } - }, - .wake_up_src[2] = { - .wake_up_src_type = WAKE_UP_SRC_UART1, - } -}; - -struct pm_wake_up_src_config *mv_wake_up_src_config_get(void) -{ - return &wake_up_src_cfg; -} - diff --git a/plat/marvell/armada/a3700/a3700/mvebu_def.h b/plat/marvell/armada/a3700/a3700/mvebu_def.h deleted file mode 100644 index dad1085f8..000000000 --- a/plat/marvell/armada/a3700/a3700/mvebu_def.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef MVEBU_DEF_H -#define MVEBU_DEF_H - -#include - -#endif /* MVEBU_DEF_H */ diff --git a/plat/marvell/armada/a3700/a3700/plat_bl31_setup.c b/plat/marvell/armada/a3700/a3700/plat_bl31_setup.c deleted file mode 100644 index 6862a8670..000000000 --- a/plat/marvell/armada/a3700/a3700/plat_bl31_setup.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -#include -#include -#include -#include -#include - -/* This routine does MPP initialization */ -static void marvell_bl31_mpp_init(void) -{ - mmio_clrbits_32(MVEBU_NB_GPIO_SEL_REG, 1 << MVEBU_GPIO_TW1_GPIO_EN_OFF); - - /* Set hidden GPIO setting for SPI. - * In north_bridge_pin_out_en_high register 13804, - * bit 28 is the one which enables CS, CLK pins to be - * output, need to set it to 1. - * The initial value of this bit is 1, but in UART boot mode - * initialization, this bit is disabled and the SPI CS and CLK pins - * are used for downloading image purpose; so after downloading, - * we should set this bit to 1 again to enable SPI CS and CLK pins. - * And anyway, this bit value should be 1 in all modes, - * so here we does not judge boot mode and set this bit to 1 always. - */ - mmio_setbits_32(MVEBU_NB_GPIO_OUTPUT_EN_HIGH_REG, - 1 << MVEBU_GPIO_NB_SPI_PIN_MODE_OFF); -} - -/* This function overruns the same function in marvell_bl31_setup.c */ -void bl31_plat_arch_setup(void) -{ - struct dec_win_config *io_dec_map; - uint32_t dec_win_num; - struct dram_win_map dram_wins_map; - - marvell_bl31_plat_arch_setup(); - - /* MPP init */ - marvell_bl31_mpp_init(); - - /* initialize the timer for delay functionality */ - plat_delay_timer_init(); - - /* CPU address decoder windows initialization. */ - cpu_wins_init(); - - /* fetch CPU-DRAM window mapping information by reading - * CPU-DRAM decode windows (only the enabled ones) - */ - dram_win_map_build(&dram_wins_map); - - /* Get IO address decoder windows */ - if (marvell_get_io_dec_win_conf(&io_dec_map, &dec_win_num)) { - printf("No IO address decoder windows configurations found!\n"); - return; - } - - /* IO address decoder init */ - if (init_io_addr_dec(&dram_wins_map, io_dec_map, dec_win_num)) { - printf("IO address decoder windows initialization failed!\n"); - return; - } -} diff --git a/plat/marvell/armada/a3700/a3700/platform.mk b/plat/marvell/armada/a3700/a3700/platform.mk deleted file mode 100644 index bd9464aae..000000000 --- a/plat/marvell/armada/a3700/a3700/platform.mk +++ /dev/null @@ -1,10 +0,0 @@ -# -# Copyright (C) 2018 Marvell International Ltd. -# -# SPDX-License-Identifier: BSD-3-Clause -# https://spdx.org/licenses -# - -include plat/marvell/armada/a3700/common/a3700_common.mk - -include plat/marvell/armada/common/marvell_common.mk diff --git a/plat/marvell/armada/a3700/common/a3700_common.mk b/plat/marvell/armada/a3700/common/a3700_common.mk deleted file mode 100644 index 36865a896..000000000 --- a/plat/marvell/armada/a3700/common/a3700_common.mk +++ /dev/null @@ -1,170 +0,0 @@ -# -# Copyright (C) 2018 Marvell International Ltd. -# -# SPDX-License-Identifier: BSD-3-Clause -# https://spdx.org/licenses -# - -MARVELL_PLAT_BASE := plat/marvell/armada -MARVELL_PLAT_INCLUDE_BASE := include/plat/marvell/armada -PLAT_FAMILY := a3700 -PLAT_FAMILY_BASE := $(MARVELL_PLAT_BASE)/$(PLAT_FAMILY) -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 - -#*********** A3700 ************* -DOIMAGEPATH := $(WTP) -DOIMAGETOOL := $(DOIMAGEPATH)/wtptp/linux/tbb_linux - -ifeq ($(MARVELL_SECURE_BOOT),1) -DOIMAGE_CFG := $(DOIMAGEPATH)/atf-tim.txt -IMAGESPATH := $(DOIMAGEPATH)/tim/trusted - -TIMNCFG := $(DOIMAGEPATH)/atf-timN.txt -TIMNSIG := $(IMAGESPATH)/timnsign.txt -TIM2IMGARGS := -i $(DOIMAGE_CFG) -n $(TIMNCFG) -TIMN_IMAGE := $$(grep "Image Filename:" -m 1 $(TIMNCFG) | cut -c 17-) -else #MARVELL_SECURE_BOOT -DOIMAGE_CFG := $(DOIMAGEPATH)/atf-ntim.txt -IMAGESPATH := $(DOIMAGEPATH)/tim/untrusted -TIM2IMGARGS := -i $(DOIMAGE_CFG) -endif #MARVELL_SECURE_BOOT - -TIMBUILD := $(DOIMAGEPATH)/script/buildtim.sh -TIM2IMG := $(DOIMAGEPATH)/script/tim2img.pl - -# WTMI_IMG is used to specify the customized RTOS image running over -# Service CPU (CM3 processor). By the default, it points to a -# baremetal binary of fuse programming in A3700_utils. -WTMI_IMG := $(DOIMAGEPATH)/wtmi/fuse/build/fuse.bin - -# WTMI_SYSINIT_IMG is used for the system early initialization, -# such as AVS settings, clock-tree setup and dynamic DDR PHY training. -# After the initialization is done, this image will be wiped out -# from the memory and CM3 will continue with RTOS image or other application. -WTMI_SYSINIT_IMG := $(DOIMAGEPATH)/wtmi/sys_init/build/sys_init.bin - -# WTMI_MULTI_IMG is composed of CM3 RTOS image (WTMI_IMG) -# and sys-init image (WTMI_SYSINIT_IMG). -WTMI_MULTI_IMG := $(DOIMAGEPATH)/wtmi/build/wtmi.bin - -WTMI_ENC_IMG := $(DOIMAGEPATH)/wtmi/build/wtmi-enc.bin -BUILD_UART := uart-images - -SRCPATH := $(dir $(BL33)) - -CLOCKSPRESET ?= CPU_800_DDR_800 - -DDR_TOPOLOGY ?= 0 - -BOOTDEV ?= SPINOR -PARTNUM ?= 0 - -TIM_IMAGE := $$(grep "Image Filename:" -m 1 $(DOIMAGE_CFG) | cut -c 17-) -TIMBLDARGS := $(MARVELL_SECURE_BOOT) $(BOOTDEV) $(IMAGESPATH) $(DOIMAGEPATH) $(CLOCKSPRESET) \ - $(DDR_TOPOLOGY) $(PARTNUM) $(DEBUG) $(DOIMAGE_CFG) $(TIMNCFG) $(TIMNSIG) 1 -TIMBLDUARTARGS := $(MARVELL_SECURE_BOOT) UART $(IMAGESPATH) $(DOIMAGEPATH) $(CLOCKSPRESET) \ - $(DDR_TOPOLOGY) 0 0 $(DOIMAGE_CFG) $(TIMNCFG) $(TIMNSIG) 0 -DOIMAGE_FLAGS := -r $(DOIMAGE_CFG) -v -D - -# GICV3 -$(eval $(call add_define,CONFIG_GICV3)) - -# CCI-400 -$(eval $(call add_define,USE_CCI)) - -# Include GICv3 driver files -include drivers/arm/gic/v3/gicv3.mk - -MARVELL_GIC_SOURCES := ${GICV3_SOURCES} \ - plat/common/plat_gicv3.c - -PLAT_INCLUDES := -I$(PLAT_FAMILY_BASE)/$(PLAT) \ - -I$(PLAT_COMMON_BASE)/include \ - -I$(PLAT_INCLUDE_BASE)/common \ - -I$(MARVELL_DRV_BASE) \ - -I$/drivers/arm/gic/common/ - -PLAT_BL_COMMON_SOURCES := $(PLAT_COMMON_BASE)/aarch64/a3700_common.c \ - $(MARVELL_COMMON_BASE)/marvell_cci.c \ - $(MARVELL_DRV_BASE)/uart/a3700_console.S - -BL1_SOURCES += $(PLAT_COMMON_BASE)/aarch64/plat_helpers.S \ - lib/cpus/aarch64/cortex_a53.S - -BL31_PORTING_SOURCES := $(PLAT_FAMILY_BASE)/$(PLAT)/board/pm_src.c - -MARVELL_DRV := $(MARVELL_DRV_BASE)/comphy/phy-comphy-3700.c - -BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \ - $(PLAT_COMMON_BASE)/aarch64/plat_helpers.S \ - $(PLAT_COMMON_BASE)/plat_pm.c \ - $(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_ddr_info.c \ - $(MARVELL_COMMON_BASE)/marvell_gicv3.c \ - $(MARVELL_GIC_SOURCES) \ - drivers/arm/cci/cci.c \ - $(BL31_PORTING_SOURCES) \ - $(PLAT_COMMON_BASE)/a3700_sip_svc.c \ - $(MARVELL_DRV) - -mrvl_flash: ${BUILD_PLAT}/${FIP_NAME} ${DOIMAGETOOL} - $(shell truncate -s %128K ${BUILD_PLAT}/bl1.bin) - $(shell cat ${BUILD_PLAT}/bl1.bin ${BUILD_PLAT}/${FIP_NAME} > ${BUILD_PLAT}/${BOOT_IMAGE}) - $(shell truncate -s %4 ${BUILD_PLAT}/${BOOT_IMAGE}) - $(shell truncate -s %4 $(WTMI_IMG)) - @echo - @echo "Building uart images" - $(TIMBUILD) $(TIMBLDUARTARGS) - @sed -i 's|WTMI_IMG|$(WTMI_MULTI_IMG)|1' $(DOIMAGE_CFG) - @sed -i 's|BOOT_IMAGE|$(BUILD_PLAT)/$(BOOT_IMAGE)|1' $(DOIMAGE_CFG) -ifeq ($(MARVELL_SECURE_BOOT),1) - @sed -i 's|WTMI_IMG|$(WTMI_MULTI_IMG)|1' $(TIMNCFG) - @sed -i 's|BOOT_IMAGE|$(BUILD_PLAT)/$(BOOT_IMAGE)|1' $(TIMNCFG) -endif - $(DOIMAGETOOL) $(DOIMAGE_FLAGS) - @if [ -e "$(TIMNCFG)" ]; then $(DOIMAGETOOL) -r $(TIMNCFG); fi - @rm -rf $(BUILD_PLAT)/$(BUILD_UART)* - @mkdir $(BUILD_PLAT)/$(BUILD_UART) - @mv -t $(BUILD_PLAT)/$(BUILD_UART) $(TIM_IMAGE) $(DOIMAGE_CFG) $(TIMN_IMAGE) $(TIMNCFG) - @find . -name "*_h.*" |xargs cp -ut $(BUILD_PLAT)/$(BUILD_UART) - @mv $(subst .bin,_h.bin,$(WTMI_MULTI_IMG)) $(BUILD_PLAT)/$(BUILD_UART)/wtmi_h.bin - @tar czf $(BUILD_PLAT)/$(BUILD_UART).tgz -C $(BUILD_PLAT) ./$(BUILD_UART) - @echo - @echo "Building flash image" - $(TIMBUILD) $(TIMBLDARGS) - sed -i 's|WTMI_IMG|$(WTMI_MULTI_IMG)|1' $(DOIMAGE_CFG) - sed -i 's|BOOT_IMAGE|$(BUILD_PLAT)/$(BOOT_IMAGE)|1' $(DOIMAGE_CFG) -ifeq ($(MARVELL_SECURE_BOOT),1) - @sed -i 's|WTMI_IMG|$(WTMI_MULTI_IMG)|1' $(TIMNCFG) - @sed -i 's|BOOT_IMAGE|$(BUILD_PLAT)/$(BOOT_IMAGE)|1' $(TIMNCFG) - @echo -e "\n\t=======================================================\n"; - @echo -e "\t Secure boot. Encrypting wtmi and boot-image \n"; - @echo -e "\t=======================================================\n"; - @truncate -s %16 $(WTMI_MULTI_IMG) - @openssl enc -aes-256-cbc -e -in $(WTMI_MULTI_IMG) \ - -out $(WTMI_ENC_IMG) \ - -K `cat $(IMAGESPATH)/aes-256.txt` -nosalt \ - -iv `cat $(IMAGESPATH)/iv.txt` -p - @truncate -s %16 $(BUILD_PLAT)/$(BOOT_IMAGE); - @openssl enc -aes-256-cbc -e -in $(BUILD_PLAT)/$(BOOT_IMAGE) \ - -out $(BUILD_PLAT)/$(BOOT_ENC_IMAGE) \ - -K `cat $(IMAGESPATH)/aes-256.txt` -nosalt \ - -iv `cat $(IMAGESPATH)/iv.txt` -p -endif - $(DOIMAGETOOL) $(DOIMAGE_FLAGS) - @if [ -e "$(TIMNCFG)" ]; then $(DOIMAGETOOL) -r $(TIMNCFG); fi - @if [ "$(MARVELL_SECURE_BOOT)" = "1" ]; then sed -i 's|$(WTMI_MULTI_IMG)|$(WTMI_ENC_IMG)|1;s|$(BOOT_IMAGE)|$(BOOT_ENC_IMAGE)|1;' $(TIMNCFG); fi - $(TIM2IMG) $(TIM2IMGARGS) -o $(BUILD_PLAT)/$(FLASH_IMAGE) - @mv -t $(BUILD_PLAT) $(TIM_IMAGE) $(DOIMAGE_CFG) $(TIMN_IMAGE) $(TIMNCFG) $(WTMI_IMG) $(WTMI_SYSINIT_IMG) $(WTMI_MULTI_IMG) - @if [ "$(MARVELL_SECURE_BOOT)" = "1" ]; then mv -t $(BUILD_PLAT) $(WTMI_ENC_IMG) OtpHash.txt; fi - @find . -name "*.txt" | grep -E "CSK[[:alnum:]]_KeyHash.txt|Tim_msg.txt|TIMHash.txt" | xargs rm -f diff --git a/plat/marvell/armada/a3700/common/a3700_ea.c b/plat/marvell/armada/a3700/common/a3700_ea.c deleted file mode 100644 index dd46beb55..000000000 --- a/plat/marvell/armada/a3700/common/a3700_ea.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2019 Repk repk@triplefau.lt - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ -#include -#include -#include - -#define ADVK_SERROR_SYNDROME 0xbf000002 - -void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie, - void *handle, uint64_t flags) -{ - if (syndrome != ADVK_SERROR_SYNDROME) { - ERROR("Unhandled External Abort received on 0x%lx at EL3!\n", - read_mpidr_el1()); - ERROR(" exception reason=%u syndrome=0x%llx\n", ea_reason, - syndrome); - panic(); - } -} diff --git a/plat/marvell/armada/a3700/common/a3700_sip_svc.c b/plat/marvell/armada/a3700/common/a3700_sip_svc.c deleted file mode 100644 index e8ac5fc08..000000000 --- a/plat/marvell/armada/a3700/common/a3700_sip_svc.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include -#include - -#include -#include - -#include "comphy/phy-comphy-3700.h" - -/* Comphy related FID's */ -#define MV_SIP_COMPHY_POWER_ON 0x82000001 -#define MV_SIP_COMPHY_POWER_OFF 0x82000002 -#define MV_SIP_COMPHY_PLL_LOCK 0x82000003 - -/* Miscellaneous FID's' */ -#define MV_SIP_DRAM_SIZE 0x82000010 - -/* This macro is used to identify COMPHY related calls from SMC function ID */ -#define is_comphy_fid(fid) \ - ((fid) >= MV_SIP_COMPHY_POWER_ON && (fid) <= MV_SIP_COMPHY_PLL_LOCK) - -uintptr_t mrvl_sip_smc_handler(uint32_t smc_fid, - u_register_t x1, - u_register_t x2, - u_register_t x3, - u_register_t x4, - void *cookie, - void *handle, - u_register_t flags) -{ - u_register_t ret; - - VERBOSE("%s: got SMC (0x%x) x1 0x%lx, x2 0x%lx\n", - __func__, smc_fid, x1, x2); - if (is_comphy_fid(smc_fid)) { - if (x1 >= MAX_LANE_NR) { - ERROR("%s: Wrong smc (0x%x) lane nr: %lx\n", - __func__, smc_fid, x2); - SMC_RET1(handle, SMC_UNK); - } - } - - switch (smc_fid) { - /* Comphy related FID's */ - case MV_SIP_COMPHY_POWER_ON: - /* x1: comphy_index, x2: comphy_mode */ - ret = mvebu_3700_comphy_power_on(x1, x2); - SMC_RET1(handle, ret); - case MV_SIP_COMPHY_POWER_OFF: - /* x1: comphy_index, x2: comphy_mode */ - ret = mvebu_3700_comphy_power_off(x1, x2); - SMC_RET1(handle, ret); - case MV_SIP_COMPHY_PLL_LOCK: - /* x1: comphy_index, x2: comphy_mode */ - ret = mvebu_3700_comphy_is_pll_locked(x1, x2); - SMC_RET1(handle, ret); - /* Miscellaneous FID's' */ - case MV_SIP_DRAM_SIZE: - /* x1: ap_base_addr */ - ret = mvebu_get_dram_size(MVEBU_REGS_BASE); - SMC_RET1(handle, ret); - - default: - ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid); - SMC_RET1(handle, SMC_UNK); - } -} - -/* Define a runtime service descriptor for fast SMC calls */ -DECLARE_RT_SVC( - marvell_sip_svc, - OEN_SIP_START, - OEN_SIP_END, - SMC_TYPE_FAST, - NULL, - mrvl_sip_smc_handler -); diff --git a/plat/marvell/armada/a3700/common/aarch64/a3700_common.c b/plat/marvell/armada/a3700/common/aarch64/a3700_common.c deleted file mode 100644 index 63512853c..000000000 --- a/plat/marvell/armada/a3700/common/aarch64/a3700_common.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ -#include - -/* MMU entry for internal (register) space access */ -#define MAP_DEVICE0 MAP_REGION_FLAT(DEVICE0_BASE, \ - DEVICE0_SIZE, \ - MT_DEVICE | MT_RW | MT_SECURE) - -/* - * Table of regions for various BL stages to map using the MMU. - */ -#if IMAGE_BL1 -const mmap_region_t plat_marvell_mmap[] = { - MARVELL_MAP_SHARED_RAM, - MAP_DEVICE0, - {0} -}; -#endif -#if IMAGE_BL2 -const mmap_region_t plat_marvell_mmap[] = { - MARVELL_MAP_SHARED_RAM, - MAP_DEVICE0, - MARVELL_MAP_DRAM, - {0} -}; -#endif -#if IMAGE_BL2U -const mmap_region_t plat_marvell_mmap[] = { - MAP_DEVICE0, - {0} -}; -#endif -#if IMAGE_BL31 -const mmap_region_t plat_marvell_mmap[] = { - MARVELL_MAP_SHARED_RAM, - MAP_DEVICE0, - MARVELL_MAP_DRAM, - {0} -}; -#endif -#if IMAGE_BL32 -const mmap_region_t plat_marvell_mmap[] = { - MAP_DEVICE0, - {0} -}; -#endif - -MARVELL_CASSERT_MMAP; diff --git a/plat/marvell/armada/a3700/common/aarch64/plat_helpers.S b/plat/marvell/armada/a3700/common/aarch64/plat_helpers.S deleted file mode 100644 index 90d76f08e..000000000 --- a/plat/marvell/armada/a3700/common/aarch64/plat_helpers.S +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include - - .globl plat_secondary_cold_boot_setup - .globl plat_get_my_entrypoint - .globl plat_is_my_cpu_primary - - /* ----------------------------------------------------- - * void plat_secondary_cold_boot_setup (void); - * - * This function performs any platform specific actions - * needed for a secondary cpu after a cold reset. Right - * now this is a stub function. - * ----------------------------------------------------- - */ -func plat_secondary_cold_boot_setup - mov x0, #0 - ret -endfunc plat_secondary_cold_boot_setup - - /* --------------------------------------------------------------------- - * unsigned long plat_get_my_entrypoint (void); - * - * Main job of this routine is to distinguish between cold and warm boot - * For a cold boot, return 0. - * For a warm boot, read the mailbox and return the address it contains. - * A magic number is placed before entrypoint to avoid mistake caused by - * uninitialized mailbox data area. - * --------------------------------------------------------------------- - */ -func plat_get_my_entrypoint - /* Read first word and compare it with magic num */ - mov_imm x0, PLAT_MARVELL_MAILBOX_BASE - ldr x1, [x0] - mov_imm x2, PLAT_MARVELL_MAILBOX_MAGIC_NUM - cmp x1, x2 - /* If compare failed, return 0, i.e. cold boot */ - beq entrypoint - mov x0, #0 - ret -entrypoint: - /* Second word contains the jump address */ - add x0, x0, #8 - ldr x0, [x0] - ret -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 - and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK) - cmp x0, #MVEBU_PRIMARY_CPU - cset w0, eq - ret -endfunc plat_is_my_cpu_primary diff --git a/plat/marvell/armada/a3700/common/dram_win.c b/plat/marvell/armada/a3700/common/dram_win.c deleted file mode 100644 index 694f6d480..000000000 --- a/plat/marvell/armada/a3700/common/dram_win.c +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -#include - -#include -#include -#include -#include - -/* Armada 3700 has 5 configurable windows */ -#define MV_CPU_WIN_NUM 5 - -#define CPU_WIN_DISABLED 0 -#define CPU_WIN_ENABLED 1 - -/* - * There are 2 different cpu decode window configuration cases: - * - DRAM size is not over 2GB; - * - DRAM size is 4GB. - */ -enum cpu_win_config_num { - CPU_WIN_CONFIG_DRAM_NOT_OVER_2GB = 0, - CPU_WIN_CONFIG_DRAM_4GB, - CPU_WIN_CONFIG_MAX -}; - -enum cpu_win_target { - CPU_WIN_TARGET_DRAM = 0, - CPU_WIN_TARGET_INTERNAL_REG, - CPU_WIN_TARGET_PCIE, - CPU_WIN_TARGET_PCIE_OVER_MCI, - CPU_WIN_TARGET_BOOT_ROM, - CPU_WIN_TARGET_MCI_EXTERNAL, - CPU_WIN_TARGET_RWTM_RAM = 7, - CPU_WIN_TARGET_CCI400_REG -}; - -struct cpu_win_configuration { - uint32_t enabled; - enum cpu_win_target target; - uint64_t base_addr; - uint64_t size; - uint64_t remap_addr; -}; - -struct cpu_win_configuration mv_cpu_wins[CPU_WIN_CONFIG_MAX][MV_CPU_WIN_NUM] = { - /* - * When total dram size is not over 2GB: - * DDR window 0 is configured in tim header, its size may be not 512MB, - * but the actual dram size, no need to configure it again; - * other cpu windows are kept as default. - */ - { - /* enabled - * target - * base - * size - * remap - */ - {CPU_WIN_ENABLED, - CPU_WIN_TARGET_DRAM, - 0x0, - 0x08000000, - 0x0}, - {CPU_WIN_ENABLED, - CPU_WIN_TARGET_MCI_EXTERNAL, - 0xe0000000, - 0x08000000, - 0xe0000000}, - {CPU_WIN_ENABLED, - CPU_WIN_TARGET_PCIE, - 0xe8000000, - 0x08000000, - 0xe8000000}, - {CPU_WIN_ENABLED, - CPU_WIN_TARGET_RWTM_RAM, - 0xf0000000, - 0x00020000, - 0x1fff0000}, - {CPU_WIN_ENABLED, - CPU_WIN_TARGET_PCIE_OVER_MCI, - 0x80000000, - 0x10000000, - 0x80000000}, - }, - - /* - * If total dram size is more than 2GB, now there is only one case - 4GB - * dram; we will use below cpu windows configurations: - * - Internal Regs, CCI-400, Boot Rom and PCIe windows are kept as - * default; - * - Use 4 CPU decode windows for DRAM, which cover 3.375GB DRAM; - * DDR window 0 is configured in tim header with 2GB size, no need to - * configure it again here; - * - * 0xFFFFFFFF ---> |-----------------------| - * | Boot ROM | 64KB - * 0xFFF00000 ---> +-----------------------+ - * : : - * 0xF0000000 ---> |-----------------------| - * | PCIE | 128 MB - * 0xE8000000 ---> |-----------------------| - * | DDR window 3 | 128 MB - * 0xE0000000 ---> +-----------------------+ - * : : - * 0xD8010000 ---> |-----------------------| - * | CCI Regs | 64 KB - * 0xD8000000 ---> +-----------------------+ - * : : - * : : - * 0xD2000000 ---> +-----------------------+ - * | Internal Regs | 32MB - * 0xD0000000 ---> |-----------------------| - * | DDR window 2 | 256 MB - * 0xC0000000 ---> |-----------------------| - * | | - * | DDR window 1 | 1 GB - * | | - * 0x80000000 ---> |-----------------------| - * | | - * | | - * | DDR window 0 | 2 GB - * | | - * | | - * 0x00000000 ---> +-----------------------+ - */ - { - /* win_id - * target - * base - * size - * remap - */ - {CPU_WIN_ENABLED, - CPU_WIN_TARGET_DRAM, - 0x0, - 0x80000000, - 0x0}, - {CPU_WIN_ENABLED, - CPU_WIN_TARGET_DRAM, - 0x80000000, - 0x40000000, - 0x80000000}, - {CPU_WIN_ENABLED, - CPU_WIN_TARGET_DRAM, - 0xc0000000, - 0x10000000, - 0xc0000000}, - {CPU_WIN_ENABLED, - CPU_WIN_TARGET_DRAM, - 0xe0000000, - 0x08000000, - 0xe0000000}, - {CPU_WIN_ENABLED, - CPU_WIN_TARGET_PCIE, - 0xe8000000, - 0x08000000, - 0xe8000000}, - }, -}; - -/* - * dram_win_map_build - * - * This function builds cpu dram windows mapping - * which includes base address and window size by - * reading cpu dram decode windows registers. - * - * @input: N/A - * - * @output: - * - win_map: cpu dram windows mapping - * - * @return: N/A - */ -void dram_win_map_build(struct dram_win_map *win_map) -{ - int32_t win_id; - struct dram_win *win; - uint32_t base_reg, ctrl_reg, size_reg, enabled, target; - - memset(win_map, 0, sizeof(struct dram_win_map)); - for (win_id = 0; win_id < DRAM_WIN_MAP_NUM_MAX; win_id++) { - ctrl_reg = mmio_read_32(CPU_DEC_WIN_CTRL_REG(win_id)); - target = (ctrl_reg & CPU_DEC_CR_WIN_TARGET_MASK) >> - CPU_DEC_CR_WIN_TARGET_OFFS; - enabled = ctrl_reg & CPU_DEC_CR_WIN_ENABLE; - /* Ignore invalid and non-dram windows*/ - if ((enabled == 0) || (target != DRAM_CPU_DEC_TARGET_NUM)) - continue; - - win = win_map->dram_windows + win_map->dram_win_num; - base_reg = mmio_read_32(CPU_DEC_WIN_BASE_REG(win_id)); - size_reg = mmio_read_32(CPU_DEC_WIN_SIZE_REG(win_id)); - /* Base reg [15:0] corresponds to transaction address [39:16] */ - win->base_addr = (base_reg & CPU_DEC_BR_BASE_MASK) >> - CPU_DEC_BR_BASE_OFFS; - win->base_addr *= CPU_DEC_CR_WIN_SIZE_ALIGNMENT; - /* - * Size reg [15:0] is programmed from LSB to MSB as a sequence - * of 1s followed by a sequence of 0s and the number of 1s - * specifies the size of the window in 64 KB granularity, - * for example, a value of 00FFh specifies 256 x 64 KB = 16 MB - */ - win->win_size = (size_reg & CPU_DEC_CR_WIN_SIZE_MASK) >> - CPU_DEC_CR_WIN_SIZE_OFFS; - win->win_size = (win->win_size + 1) * - CPU_DEC_CR_WIN_SIZE_ALIGNMENT; - - win_map->dram_win_num++; - } -} - -static void cpu_win_set(uint32_t win_id, struct cpu_win_configuration *win_cfg) -{ - uint32_t base_reg, ctrl_reg, size_reg, remap_reg; - - /* Disable window */ - ctrl_reg = mmio_read_32(CPU_DEC_WIN_CTRL_REG(win_id)); - ctrl_reg &= ~CPU_DEC_CR_WIN_ENABLE; - mmio_write_32(CPU_DEC_WIN_CTRL_REG(win_id), ctrl_reg); - - /* For an disabled window, only disable it. */ - if (!win_cfg->enabled) - return; - - /* Set Base Register */ - base_reg = (uint32_t)(win_cfg->base_addr / - CPU_DEC_CR_WIN_SIZE_ALIGNMENT); - base_reg <<= CPU_DEC_BR_BASE_OFFS; - base_reg &= CPU_DEC_BR_BASE_MASK; - mmio_write_32(CPU_DEC_WIN_BASE_REG(win_id), base_reg); - - /* Set Remap Register with the same value - * as the field in Base Register - */ - remap_reg = (uint32_t)(win_cfg->remap_addr / - CPU_DEC_CR_WIN_SIZE_ALIGNMENT); - remap_reg <<= CPU_DEC_RLR_REMAP_LOW_OFFS; - remap_reg &= CPU_DEC_RLR_REMAP_LOW_MASK; - mmio_write_32(CPU_DEC_REMAP_LOW_REG(win_id), remap_reg); - - /* Set Size Register */ - size_reg = (win_cfg->size / CPU_DEC_CR_WIN_SIZE_ALIGNMENT) - 1; - size_reg <<= CPU_DEC_CR_WIN_SIZE_OFFS; - size_reg &= CPU_DEC_CR_WIN_SIZE_MASK; - mmio_write_32(CPU_DEC_WIN_SIZE_REG(win_id), size_reg); - - /* Set Control Register - set target id and enable window */ - ctrl_reg &= ~CPU_DEC_CR_WIN_TARGET_MASK; - ctrl_reg |= (win_cfg->target << CPU_DEC_CR_WIN_TARGET_OFFS); - ctrl_reg |= CPU_DEC_CR_WIN_ENABLE; - mmio_write_32(CPU_DEC_WIN_CTRL_REG(win_id), ctrl_reg); -} - -void cpu_wins_init(void) -{ - uint32_t cfg_idx, win_id; - - if (mvebu_get_dram_size(MVEBU_REGS_BASE) <= _2GB_) - cfg_idx = CPU_WIN_CONFIG_DRAM_NOT_OVER_2GB; - else - cfg_idx = CPU_WIN_CONFIG_DRAM_4GB; - - /* Window 0 is configured always for DRAM in tim header - * already, no need to configure it again here - */ - for (win_id = 1; win_id < MV_CPU_WIN_NUM; win_id++) - cpu_win_set(win_id, &mv_cpu_wins[cfg_idx][win_id]); -} - diff --git a/plat/marvell/armada/a3700/common/include/a3700_plat_def.h b/plat/marvell/armada/a3700/common/include/a3700_plat_def.h deleted file mode 100644 index c7f40adc3..000000000 --- a/plat/marvell/armada/a3700/common/include/a3700_plat_def.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef A3700_PLAT_DEF_H -#define A3700_PLAT_DEF_H - -#include - - -#define MVEBU_MAX_CPUS_PER_CLUSTER 2 - -#define MVEBU_PRIMARY_CPU 0x0 - -/* - * The counter on A3700 is always fed from reference 25M clock (XTAL). - * However minimal CPU counter prescaler is 2, so the counter - * frequency will be divided by 2, the number is 12.5M - */ -#define COUNTER_FREQUENCY 12500000 - -#define MVEBU_REGS_BASE 0xD0000000 - -/***************************************************************************** - * MVEBU memory map related constants - ***************************************************************************** - */ -/* Aggregate of all devices in the first GB */ -#define DEVICE0_BASE MVEBU_REGS_BASE -#define DEVICE0_SIZE 0x10000000 - -/***************************************************************************** - * GIC-500 & interrupt handling related constants - ***************************************************************************** - */ -/* Base MVEBU compatible GIC memory map */ -#define MVEBU_GICD_BASE 0x1D00000 -#define MVEBU_GICR_BASE 0x1D40000 -#define MVEBU_GICC_BASE 0x1D80000 - -/* CCI-400 */ -#define MVEBU_CCI_BASE 0x8000000 - -/***************************************************************************** - * North and south bridge register base - ***************************************************************************** - */ -#define MVEBU_NB_REGS_BASE (MVEBU_REGS_BASE + 0x13000) -#define MVEBU_SB_REGS_BASE (MVEBU_REGS_BASE + 0x18000) - -/***************************************************************************** - * GPIO registers related constants - ***************************************************************************** - */ -/* North and south bridge GPIO register base address */ -#define MVEBU_NB_GPIO_REG_BASE (MVEBU_NB_REGS_BASE + 0x800) -#define MVEBU_NB_GPIO_IRQ_REG_BASE (MVEBU_NB_REGS_BASE + 0xC00) -#define MVEBU_SB_GPIO_REG_BASE (MVEBU_SB_REGS_BASE + 0x800) -#define MVEBU_SB_GPIO_IRQ_REG_BASE (MVEBU_SB_REGS_BASE + 0xC00) -#define MVEBU_NB_SB_IRQ_REG_BASE (MVEBU_REGS_BASE + 0x8A00) - -/* North Bridge GPIO selection register */ -#define MVEBU_NB_GPIO_SEL_REG (MVEBU_NB_GPIO_REG_BASE + 0x30) -#define MVEBU_NB_GPIO_OUTPUT_EN_HIGH_REG (MVEBU_NB_GPIO_REG_BASE + 0x04) -/* I2C1 GPIO Enable bit offset */ -#define MVEBU_GPIO_TW1_GPIO_EN_OFF (10) -/* SPI pins mode bit offset */ -#define MVEBU_GPIO_NB_SPI_PIN_MODE_OFF (28) - -/***************************************************************************** - * DRAM registers related constants - ***************************************************************************** - */ -#define MVEBU_DRAM_REG_BASE (MVEBU_REGS_BASE) - -/***************************************************************************** - * SB wake-up registers related constants - ***************************************************************************** - */ -#define MVEBU_SB_WAKEUP_REG_BASE (MVEBU_REGS_BASE + 0x19000) - -/***************************************************************************** - * PMSU registers related constants - ***************************************************************************** - */ -#define MVEBU_PMSU_REG_BASE (MVEBU_REGS_BASE + 0x14000) - -/***************************************************************************** - * North Bridge Step-Down Registers - ***************************************************************************** - */ -#define MVEBU_NB_STEP_DOWN_REG_BASE (MVEBU_REGS_BASE + 0x12800) - -/***************************************************************************** - * DRAM CS memory map register base - ***************************************************************************** - */ -#define MVEBU_CS_MMAP_REG_BASE (MVEBU_REGS_BASE + 0x200) - -/***************************************************************************** - * CPU decoder window registers related constants - ***************************************************************************** - */ -#define MVEBU_CPU_DEC_WIN_REG_BASE (MVEBU_REGS_BASE + 0xCF00) - -/***************************************************************************** - * AVS registers related constants - ***************************************************************************** - */ -#define MVEBU_AVS_REG_BASE (MVEBU_REGS_BASE + 0x11500) - - -/***************************************************************************** - * AVS registers related constants - ***************************************************************************** - */ -#define MVEBU_COMPHY_REG_BASE (MVEBU_REGS_BASE + 0x18300) - -#endif /* A3700_PLAT_DEF_H */ diff --git a/plat/marvell/armada/a3700/common/include/a3700_pm.h b/plat/marvell/armada/a3700/common/include/a3700_pm.h deleted file mode 100644 index cc6cf436a..000000000 --- a/plat/marvell/armada/a3700/common/include/a3700_pm.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2016 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef A3700_PM_H -#define A3700_PM_H - -#include - -/* supported wake up sources */ -enum pm_wake_up_src_type { - WAKE_UP_SRC_GPIO, - /* FOLLOWING SRC NOT SUPPORTED YET */ - WAKE_UP_SRC_TIMER, - WAKE_UP_SRC_UART0, - WAKE_UP_SRC_UART1, - WAKE_UP_SRC_MAX, -}; - -struct pm_gpio_data { - /* - * bank 0: North bridge GPIO - * bank 1: South bridge GPIO - */ - uint32_t bank_num; - uint32_t gpio_num; -}; - -union pm_wake_up_src_data { - struct pm_gpio_data gpio_data; - /* delay in seconds */ - uint32_t timer_delay; -}; - -struct pm_wake_up_src { - enum pm_wake_up_src_type wake_up_src_type; - - union pm_wake_up_src_data wake_up_data; -}; - -struct pm_wake_up_src_config { - uint32_t wake_up_src_num; - struct pm_wake_up_src wake_up_src[WAKE_UP_SRC_MAX]; -}; - -struct pm_wake_up_src_config *mv_wake_up_src_config_get(void); - -#endif /* A3700_PM_H */ diff --git a/plat/marvell/armada/a3700/common/include/ddr_info.h b/plat/marvell/armada/a3700/common/include/ddr_info.h deleted file mode 100644 index 254f78c1b..000000000 --- a/plat/marvell/armada/a3700/common/include/ddr_info.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef DDR_INFO_H -#define DDR_INFO_H - -#define DRAM_MAX_IFACE 1 -#define DRAM_CH0_MMAP_LOW_OFFSET 0x200 - -#endif /* DDR_INFO_H */ diff --git a/plat/marvell/armada/a3700/common/include/dram_win.h b/plat/marvell/armada/a3700/common/include/dram_win.h deleted file mode 100644 index 26a013784..000000000 --- a/plat/marvell/armada/a3700/common/include/dram_win.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef DRAM_WIN_H -#define DRAM_WIN_H - -#include - -#include - -void dram_win_map_build(struct dram_win_map *win_map); -void cpu_wins_init(void); - -#endif /* DRAM_WIN_H */ diff --git a/plat/marvell/armada/a3700/common/include/io_addr_dec.h b/plat/marvell/armada/a3700/common/include/io_addr_dec.h deleted file mode 100644 index 42ef30bc2..000000000 --- a/plat/marvell/armada/a3700/common/include/io_addr_dec.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef IO_ADDR_DEC_H -#define IO_ADDR_DEC_H - -#include - -/* There are 5 configurable cpu decoder windows. */ -#define DRAM_WIN_MAP_NUM_MAX 5 -/* Target number for dram in cpu decoder windows. */ -#define DRAM_CPU_DEC_TARGET_NUM 0 - -/* - * Not all configurable decode windows could be used for dram, some units have - * to reserve one decode window for other unit they have to communicate with; - * for example, DMA engineer has 3 configurable windows, but only two could be - * for dram while the last one has to be for pcie, so for DMA, its max_dram_win - * is 2. - */ -struct dec_win_config { - uint32_t dec_reg_base; /* IO address decoder register base address */ - uint32_t win_attr; /* IO address decoder windows attributes */ - /* How many configurable dram decoder windows that this unit has; */ - uint32_t max_dram_win; - /* The decoder windows number including remapping that this unit has */ - uint32_t max_remap; - /* The offset between continuous decode windows - * within the same unit, typically 0x10 - */ - uint32_t win_offset; -}; - -struct dram_win { - uintptr_t base_addr; - uintptr_t win_size; -}; - -struct dram_win_map { - int dram_win_num; - struct dram_win dram_windows[DRAM_WIN_MAP_NUM_MAX]; -}; - -/* - * init_io_addr_dec - * - * This function initializes io address decoder windows by - * cpu dram window mapping information - * - * @input: N/A - * - dram_wins_map: cpu dram windows mapping - * - io_dec_config: io address decoder windows configuration - * - io_unit_num: io address decoder unit number - * @output: N/A - * - * @return: 0 on success and others on failure - */ -int init_io_addr_dec(struct dram_win_map *dram_wins_map, - struct dec_win_config *io_dec_config, - uint32_t io_unit_num); - -#endif /* IO_ADDR_DEC_H */ diff --git a/plat/marvell/armada/a3700/common/include/plat_macros.S b/plat/marvell/armada/a3700/common/include/plat_macros.S deleted file mode 100644 index f689b4f39..000000000 --- a/plat/marvell/armada/a3700/common/include/plat_macros.S +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef PLAT_MACROS_S -#define PLAT_MACROS_S - -#include - -/* --------------------------------------------- - * The below macro prints out relevant GIC and - * CCI registers registers whenever an unhandled - * exception is taken in BL31. - * --------------------------------------------- - */ -.macro plat_crash_print_regs - mov_imm x17, MVEBU_GICC_BASE - mov_imm x16, MVEBU_GICD_BASE - marvell_print_gic_regs - print_cci_regs -.endm - -#endif /* PLAT_MACROS_S */ diff --git a/plat/marvell/armada/a3700/common/include/platform_def.h b/plat/marvell/armada/a3700/common/include/platform_def.h deleted file mode 100644 index e6660d407..000000000 --- a/plat/marvell/armada/a3700/common/include/platform_def.h +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright (C) 2016-2019 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#ifndef PLATFORM_DEF_H -#define PLATFORM_DEF_H - -#ifndef __ASSEMBLER__ -#include -#endif /* __ASSEMBLER__ */ - -#include -#include - -/* - * Most platform porting definitions provided by included headers - */ - -/* - * DRAM Memory layout: - * +-----------------------+ - * : : - * : Linux : - * 0x04X00000-->+-----------------------+ - * | BL3-3(u-boot) |>>}>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - * |-----------------------| } | - * | BL3-[0,1, 2] | }---------------------------------> | - * |-----------------------| } || | - * | BL2 | }->FIP (loaded by || | - * |-----------------------| } BootROM to DRAM) || | - * | FIP_TOC | } || | - * 0x04120000-->|-----------------------| || | - * | BL1 (RO) | || | - * 0x04100000-->+-----------------------+ || | - * : : || | - * : Trusted SRAM section : \/ | - * 0x04040000-->+-----------------------+ Replaced by BL2 +----------------+ | - * | BL1 (RW) | <<<<<<<<<<<<<<<< | BL3-1 NOBITS | | - * 0x04037000-->|-----------------------| <<<<<<<<<<<<<<<< |----------------| | - * | | <<<<<<<<<<<<<<<< | BL3-1 PROGBITS | | - * 0x04023000-->|-----------------------| +----------------+ | - * | BL2 | | - * |-----------------------| | - * | | | - * 0x04001000-->|-----------------------| | - * | Shared | | - * 0x04000000-->+-----------------------+ | - * : : | - * : Linux : | - * : : | - * |-----------------------| | - * | | U-Boot(BL3-3) Loaded by BL2 | - * | U-Boot | <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - * 0x00000000-->+-----------------------+ - * - * Trusted SRAM section 0x4000000..0x4200000: - * ---------------------------------------- - * SRAM_BASE = 0x4001000 - * BL2_BASE = 0x4006000 - * BL2_LIMIT = BL31_BASE - * BL31_BASE = 0x4023000 = (64MB + 256KB - 0x1D000) - * BL31_PROGBITS_LIMIT = BL1_RW_BASE - * BL1_RW_BASE = 0x4037000 = (64MB + 256KB - 0x9000) - * BL1_RW_LIMIT = BL31_LIMIT = 0x4040000 - * - * - * PLAT_MARVELL_FIP_BASE = 0x4120000 - */ - -#define PLAT_MARVELL_ATF_BASE 0x4000000 -#define PLAT_MARVELL_ATF_LOAD_ADDR \ - (PLAT_MARVELL_ATF_BASE + 0x100000) - -#define PLAT_MARVELL_FIP_BASE \ - (PLAT_MARVELL_ATF_LOAD_ADDR + 0x20000) -#define PLAT_MARVELL_FIP_MAX_SIZE 0x4000000 - -#define PLAT_MARVELL_CLUSTER_CORE_COUNT U(2) -/* DRAM[2MB..66MB] is used as Trusted ROM */ -#define PLAT_MARVELL_TRUSTED_ROM_BASE PLAT_MARVELL_ATF_LOAD_ADDR -/* 64 MB TODO: reduce this to minimum needed according to fip image size*/ -#define PLAT_MARVELL_TRUSTED_ROM_SIZE 0x04000000 -/* Reserve 16M for SCP (Secure PayLoad) Trusted DRAM */ -#define PLAT_MARVELL_TRUSTED_DRAM_BASE 0x04400000 -#define PLAT_MARVELL_TRUSTED_DRAM_SIZE 0x01000000 /* 16 MB */ - -/* - * PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size - * plus a little space for growth. - */ -#define PLAT_MARVELL_MAX_BL1_RW_SIZE 0xA000 - -/* - * PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a - * little space for growth. - */ -#define PLAT_MARVELL_MAX_BL2_SIZE 0xF000 - -/* - * PLAT_ARM_MAX_BL31_SIZE is calculated using the current BL31 debug size plus a - * little space for growth. - */ -#define PLAT_MARVEL_MAX_BL31_SIZE 0x5D000 - -#define PLAT_MARVELL_CPU_ENTRY_ADDR BL1_RO_BASE - -/* GIC related definitions */ -#define PLAT_MARVELL_GICD_BASE (MVEBU_REGS_BASE + MVEBU_GICD_BASE) -#define PLAT_MARVELL_GICR_BASE (MVEBU_REGS_BASE + MVEBU_GICR_BASE) -#define PLAT_MARVELL_GICC_BASE (MVEBU_REGS_BASE + MVEBU_GICC_BASE) - -#define PLAT_MARVELL_G0_IRQ_PROPS(grp) \ - INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_LEVEL) - -#define PLAT_MARVELL_G1S_IRQ_PROPS(grp) \ - INTR_PROP_DESC(MARVELL_IRQ_SEC_PHY_TIMER, \ - GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_LEVEL) - - -#define PLAT_MARVELL_SHARED_RAM_CACHED 1 - -/* CCI related constants */ -#define PLAT_MARVELL_CCI_BASE (MVEBU_REGS_BASE + MVEBU_CCI_BASE) -#define PLAT_MARVELL_CCI_CLUSTER0_SL_IFACE_IX 3 -#define PLAT_MARVELL_CCI_CLUSTER1_SL_IFACE_IX 4 - -/* - * Load address of BL3-3 for this platform port - */ -#define PLAT_MARVELL_NS_IMAGE_OFFSET 0x0 - -/* System Reference Clock*/ -#define PLAT_REF_CLK_IN_HZ COUNTER_FREQUENCY - -/* - * PL011 related constants - */ -#define PLAT_MARVELL_BOOT_UART_BASE (MVEBU_REGS_BASE + 0x12000) -#define PLAT_MARVELL_BOOT_UART_CLK_IN_HZ 25804800 - -#define PLAT_MARVELL_CRASH_UART_BASE PLAT_MARVELL_BOOT_UART_BASE -#define PLAT_MARVELL_CRASH_UART_CLK_IN_HZ PLAT_MARVELL_BOOT_UART_CLK_IN_HZ - -#define PLAT_MARVELL_BL31_RUN_UART_BASE PLAT_MARVELL_BOOT_UART_BASE -#define PLAT_MARVELL_BL31_RUN_UART_CLK_IN_HZ PLAT_MARVELL_BOOT_UART_CLK_IN_HZ - -/* Required platform porting definitions */ -#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL1 - -/* System timer related constants */ -#define PLAT_MARVELL_NSTIMER_FRAME_ID 1 - -/* Mailbox base address */ -#define PLAT_MARVELL_MAILBOX_BASE \ - (MARVELL_TRUSTED_SRAM_BASE + 0x400) -#define PLAT_MARVELL_MAILBOX_SIZE 0x100 -#define PLAT_MARVELL_MAILBOX_MAGIC_NUM 0x6D72766C /* mrvl */ - -/* DRAM CS memory map registers related constants */ -#define MVEBU_CS_MMAP_LOW(cs_num) \ - (MVEBU_CS_MMAP_REG_BASE + (cs_num) * 0x8) -#define MVEBU_CS_MMAP_ENABLE 0x1 -#define MVEBU_CS_MMAP_AREA_LEN_OFFS 16 -#define MVEBU_CS_MMAP_AREA_LEN_MASK \ - (0x1f << MVEBU_CS_MMAP_AREA_LEN_OFFS) -#define MVEBU_CS_MMAP_START_ADDR_LOW_OFFS 23 -#define MVEBU_CS_MMAP_START_ADDR_LOW_MASK \ - (0x1ff << MVEBU_CS_MMAP_START_ADDR_LOW_OFFS) - -#define MVEBU_CS_MMAP_HIGH(cs_num) \ - (MVEBU_CS_MMAP_REG_BASE + 0x4 + (cs_num) * 0x8) - -/* DRAM max CS number */ -#define MVEBU_MAX_CS_MMAP_NUM (2) - -/* CPU decoder window related constants */ -#define CPU_DEC_WIN_CTRL_REG(win_num) \ - (MVEBU_CPU_DEC_WIN_REG_BASE + (win_num) * 0x10) -#define CPU_DEC_CR_WIN_ENABLE 0x1 -#define CPU_DEC_CR_WIN_TARGET_OFFS 4 -#define CPU_DEC_CR_WIN_TARGET_MASK \ - (0xf << CPU_DEC_CR_WIN_TARGET_OFFS) - -#define CPU_DEC_WIN_SIZE_REG(win_num) \ - (MVEBU_CPU_DEC_WIN_REG_BASE + 0x4 + (win_num) * 0x10) -#define CPU_DEC_CR_WIN_SIZE_OFFS 0 -#define CPU_DEC_CR_WIN_SIZE_MASK \ - (0xffff << CPU_DEC_CR_WIN_SIZE_OFFS) -#define CPU_DEC_CR_WIN_SIZE_ALIGNMENT 0x10000 - -#define CPU_DEC_WIN_BASE_REG(win_num) \ - (MVEBU_CPU_DEC_WIN_REG_BASE + 0x8 + (win_num) * 0x10) -#define CPU_DEC_BR_BASE_OFFS 0 -#define CPU_DEC_BR_BASE_MASK \ - (0xffff << CPU_DEC_BR_BASE_OFFS) - -#define CPU_DEC_REMAP_LOW_REG(win_num) \ - (MVEBU_CPU_DEC_WIN_REG_BASE + 0xC + (win_num) * 0x10) -#define CPU_DEC_RLR_REMAP_LOW_OFFS 0 -#define CPU_DEC_RLR_REMAP_LOW_MASK \ - (0xffff << CPU_DEC_BR_BASE_OFFS) - -/* Securities */ -#define IRQ_SEC_OS_TICK_INT MARVELL_IRQ_SEC_PHY_TIMER - -#define TRUSTED_DRAM_BASE PLAT_MARVELL_TRUSTED_DRAM_BASE -#define TRUSTED_DRAM_SIZE PLAT_MARVELL_TRUSTED_DRAM_SIZE - -#ifdef BL32 -#define BL32_BASE TRUSTED_DRAM_BASE -#define BL32_LIMIT TRUSTED_DRAM_SIZE -#endif - -#endif /* PLATFORM_DEF_H */ diff --git a/plat/marvell/armada/a3700/common/io_addr_dec.c b/plat/marvell/armada/a3700/common/io_addr_dec.c deleted file mode 100644 index b27633cf2..000000000 --- a/plat/marvell/armada/a3700/common/io_addr_dec.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (C) 2016 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#include - -#include -#include - -#define MVEBU_DEC_WIN_CTRL_REG(base, win, off) (MVEBU_REGS_BASE + (base) + \ - (win) * (off)) -#define MVEBU_DEC_WIN_BASE_REG(base, win, off) (MVEBU_REGS_BASE + (base) + \ - (win) * (off) + 0x4) -#define MVEBU_DEC_WIN_REMAP_REG(base, win, off) (MVEBU_REGS_BASE + (base) + \ - (win) * (off) + 0x8) - -#define MVEBU_DEC_WIN_CTRL_SIZE_OFF (16) -#define MVEBU_DEC_WIN_ENABLE (0x1) -#define MVEBU_DEC_WIN_CTRL_ATTR_OFF (8) -#define MVEBU_DEC_WIN_CTRL_TARGET_OFF (4) -#define MVEBU_DEC_WIN_CTRL_EN_OFF (0) -#define MVEBU_DEC_WIN_BASE_OFF (16) - -#define MVEBU_WIN_BASE_SIZE_ALIGNMENT (0x10000) - -/* There are up to 14 IO unit which need address decode in Armada-3700 */ -#define IO_UNIT_NUM_MAX (14) - -#define MVEBU_MAX_ADDRSS_4GB (0x100000000ULL) - - -static void set_io_addr_dec_win(int win_id, uintptr_t base_addr, - uintptr_t win_size, - struct dec_win_config *dec_win) -{ - uint32_t ctrl = 0; - uint32_t base = 0; - - /* set size */ - ctrl = ((win_size / MVEBU_WIN_BASE_SIZE_ALIGNMENT) - 1) << - MVEBU_DEC_WIN_CTRL_SIZE_OFF; - /* set attr according to IO decode window */ - ctrl |= dec_win->win_attr << MVEBU_DEC_WIN_CTRL_ATTR_OFF; - /* set target */ - ctrl |= DRAM_CPU_DEC_TARGET_NUM << MVEBU_DEC_WIN_CTRL_TARGET_OFF; - /* set base */ - base = (base_addr / MVEBU_WIN_BASE_SIZE_ALIGNMENT) << - MVEBU_DEC_WIN_BASE_OFF; - - /* set base address*/ - mmio_write_32(MVEBU_DEC_WIN_BASE_REG(dec_win->dec_reg_base, - win_id, dec_win->win_offset), - base); - /* set remap window, some unit does not have remap window */ - if (win_id < dec_win->max_remap) - mmio_write_32(MVEBU_DEC_WIN_REMAP_REG(dec_win->dec_reg_base, - win_id, dec_win->win_offset), base); - /* set control register */ - mmio_write_32(MVEBU_DEC_WIN_CTRL_REG(dec_win->dec_reg_base, - win_id, dec_win->win_offset), ctrl); - /* enable the address decode window at last to make it effective */ - ctrl |= MVEBU_DEC_WIN_ENABLE << MVEBU_DEC_WIN_CTRL_EN_OFF; - mmio_write_32(MVEBU_DEC_WIN_CTRL_REG(dec_win->dec_reg_base, - win_id, dec_win->win_offset), ctrl); - - INFO("set_io_addr_dec %d result: ctrl(0x%x) base(0x%x)", - win_id, mmio_read_32(MVEBU_DEC_WIN_CTRL_REG(dec_win->dec_reg_base, - win_id, dec_win->win_offset)), - mmio_read_32(MVEBU_DEC_WIN_BASE_REG(dec_win->dec_reg_base, - win_id, dec_win->win_offset))); - if (win_id < dec_win->max_remap) - INFO(" remap(%x)\n", - mmio_read_32(MVEBU_DEC_WIN_REMAP_REG(dec_win->dec_reg_base, - win_id, dec_win->win_offset))); - else - INFO("\n"); -} - -/* Set io decode window */ -static int set_io_addr_dec(struct dram_win_map *win_map, - struct dec_win_config *dec_win) -{ - struct dram_win *win; - int id; - - /* disable all windows first */ - for (id = 0; id < dec_win->max_dram_win; id++) - mmio_write_32(MVEBU_DEC_WIN_CTRL_REG(dec_win->dec_reg_base, id, - dec_win->win_offset), 0); - - /* configure IO decode windows for DRAM, inheritate DRAM size, - * base and target from CPU-DRAM decode window and others - * from hard coded IO decode window settings array. - */ - if (win_map->dram_win_num > dec_win->max_dram_win) { - /* - * If cpu dram windows number exceeds the io decode windows - * max number, then fill the first io decode window - * with base(0) and size(4GB). - */ - set_io_addr_dec_win(0, 0, MVEBU_MAX_ADDRSS_4GB, dec_win); - - return 0; - } - - for (id = 0; id < win_map->dram_win_num; id++, win++) { - win = &win_map->dram_windows[id]; - set_io_addr_dec_win(id, win->base_addr, win->win_size, dec_win); - } - - return 0; -} - -/* - * init_io_addr_dec - * - * This function initializes io address decoder windows by - * cpu dram window mapping information - * - * @input: N/A - * - dram_wins_map: cpu dram windows mapping - * - io_dec_config: io address decoder windows configuration - * - io_unit_num: io address decoder unit number - * @output: N/A - * - * @return: 0 on success and others on failure - */ -int init_io_addr_dec(struct dram_win_map *dram_wins_map, - struct dec_win_config *io_dec_config, uint32_t io_unit_num) -{ - int32_t index; - struct dec_win_config *io_dec_win; - int32_t ret; - - INFO("Initializing IO address decode windows\n"); - - if (io_dec_config == NULL || io_unit_num == 0) { - ERROR("No IO address decoder windows configurations!\n"); - return -1; - } - - if (io_unit_num > IO_UNIT_NUM_MAX) { - ERROR("IO address decoder windows number %d is over max %d\n", - io_unit_num, IO_UNIT_NUM_MAX); - return -1; - } - - if (dram_wins_map == NULL) { - ERROR("No cpu dram decoder windows map!\n"); - return -1; - } - - for (index = 0; index < dram_wins_map->dram_win_num; index++) - INFO("DRAM mapping %d base(0x%lx) size(0x%lx)\n", - index, dram_wins_map->dram_windows[index].base_addr, - dram_wins_map->dram_windows[index].win_size); - - /* Set address decode window for each IO */ - for (index = 0; index < io_unit_num; index++) { - io_dec_win = io_dec_config + index; - ret = set_io_addr_dec(dram_wins_map, io_dec_win); - if (ret) { - ERROR("Failed to set IO address decode\n"); - return -1; - } - INFO("Set IO decode window successfully, base(0x%x)", - io_dec_win->dec_reg_base); - INFO(" win_attr(%x) max_dram_win(%d) max_remap(%d)", - io_dec_win->win_attr, io_dec_win->max_dram_win, - io_dec_win->max_remap); - INFO(" win_offset(%d)\n", io_dec_win->win_offset); - } - - return 0; -} diff --git a/plat/marvell/armada/a3700/common/marvell_plat_config.c b/plat/marvell/armada/a3700/common/marvell_plat_config.c deleted file mode 100644 index 3bf3d96bd..000000000 --- a/plat/marvell/armada/a3700/common/marvell_plat_config.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include - -#include -#include - -struct dec_win_config io_dec_win_conf[] = { - /* dec_reg_base win_attr max_dram_win max_remap win_offset */ - {0xc000, 0x3d, 2, 0, 0x08}, /* USB */ - {0xc100, 0x3d, 3, 0, 0x10}, /* USB3 */ - {0xc200, 0x3d, 2, 0, 0x10}, /* DMA */ - {0xc300, 0x3d, 2, 0, 0x10}, /* NETA0 */ - {0xc400, 0x3d, 2, 0, 0x10}, /* NETA1 */ - {0xc500, 0x3d, 2, 0, 0x10}, /* PCIe */ - {0xc800, 0x3d, 3, 0, 0x10}, /* SATA */ - {0xca00, 0x3d, 3, 0, 0x08}, /* SD */ - {0xcb00, 0x3d, 3, 0, 0x10}, /* eMMC */ - {0xce00, 0x3d, 2, 0, 0x08}, /* EIP97 */ -}; - -int marvell_get_io_dec_win_conf(struct dec_win_config **win, uint32_t *size) -{ - *win = io_dec_win_conf; - *size = sizeof(io_dec_win_conf)/sizeof(struct dec_win_config); - - return 0; -} - diff --git a/plat/marvell/armada/a3700/common/plat_pm.c b/plat/marvell/armada/a3700/common/plat_pm.c deleted file mode 100644 index f8ce6fe29..000000000 --- a/plat/marvell/armada/a3700/common/plat_pm.c +++ /dev/null @@ -1,807 +0,0 @@ -/* - * Copyright (C) 2018 Marvell International Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - * https://spdx.org/licenses - */ - -#include -#ifdef USE_CCI -#include -#endif -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Warm reset register */ -#define MVEBU_WARM_RESET_REG (MVEBU_NB_REGS_BASE + 0x840) -#define MVEBU_WARM_RESET_MAGIC 0x1D1E - -/* North Bridge GPIO1 SEL register */ -#define MVEBU_NB_GPIO1_SEL_REG (MVEBU_NB_REGS_BASE + 0x830) - #define MVEBU_NB_GPIO1_UART1_SEL BIT(19) - #define MVEBU_NB_GPIO1_GPIO_25_26_EN BIT(17) - #define MVEBU_NB_GPIO1_GPIO_19_EN BIT(14) - #define MVEBU_NB_GPIO1_GPIO_18_EN BIT(13) - -/* CPU 1 reset register */ -#define MVEBU_CPU_1_RESET_VECTOR (MVEBU_REGS_BASE + 0x14044) -#define MVEBU_CPU_1_RESET_REG (MVEBU_REGS_BASE + 0xD00C) -#define MVEBU_CPU_1_RESET_BIT 31 - -/* IRQ register */ -#define MVEBU_NB_IRQ_STATUS_1_REG (MVEBU_NB_SB_IRQ_REG_BASE) -#define MVEBU_NB_IRQ_STATUS_2_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ - 0x10) -#define MVEBU_NB_IRQ_MASK_2_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ - 0x18) -#define MVEBU_SB_IRQ_STATUS_1_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ - 0x40) -#define MVEBU_SB_IRQ_STATUS_2_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ - 0x50) -#define MVEBU_NB_GPIO_IRQ_MASK_1_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ - 0xC8) -#define MVEBU_NB_GPIO_IRQ_MASK_2_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ - 0xD8) -#define MVEBU_SB_GPIO_IRQ_MASK_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ - 0xE8) -#define MVEBU_NB_GPIO_IRQ_EN_LOW_REG (MVEBU_NB_GPIO_IRQ_REG_BASE) -#define MVEBU_NB_GPIO_IRQ_EN_HIGH_REG (MVEBU_NB_GPIO_IRQ_REG_BASE + \ - 0x04) -#define MVEBU_NB_GPIO_IRQ_STATUS_LOW_REG (MVEBU_NB_GPIO_IRQ_REG_BASE + \ - 0x10) -#define MVEBU_NB_GPIO_IRQ_STATUS_HIGH_REG (MVEBU_NB_GPIO_IRQ_REG_BASE + \ - 0x14) -#define MVEBU_NB_GPIO_IRQ_WK_LOW_REG (MVEBU_NB_GPIO_IRQ_REG_BASE + \ - 0x18) -#define MVEBU_NB_GPIO_IRQ_WK_HIGH_REG (MVEBU_NB_GPIO_IRQ_REG_BASE + \ - 0x1C) -#define MVEBU_SB_GPIO_IRQ_EN_REG (MVEBU_SB_GPIO_IRQ_REG_BASE) -#define MVEBU_SB_GPIO_IRQ_STATUS_REG (MVEBU_SB_GPIO_IRQ_REG_BASE + \ - 0x10) -#define MVEBU_SB_GPIO_IRQ_WK_REG (MVEBU_SB_GPIO_IRQ_REG_BASE + \ - 0x18) - -/* PMU registers */ -#define MVEBU_PM_NB_PWR_CTRL_REG (MVEBU_PMSU_REG_BASE) - #define MVEBU_PM_PWR_DN_CNT_SEL BIT(28) - #define MVEBU_PM_SB_PWR_DWN BIT(4) - #define MVEBU_PM_INTERFACE_IDLE BIT(0) -#define MVEBU_PM_NB_CPU_PWR_CTRL_REG (MVEBU_PMSU_REG_BASE + 0x4) - #define MVEBU_PM_L2_FLUSH_EN BIT(22) -#define MVEBU_PM_NB_PWR_OPTION_REG (MVEBU_PMSU_REG_BASE + 0x8) - #define MVEBU_PM_DDR_SR_EN BIT(29) - #define MVEBU_PM_DDR_CLK_DIS_EN BIT(28) - #define MVEBU_PM_WARM_RESET_EN BIT(27) - #define MVEBU_PM_DDRPHY_PWRDWN_EN BIT(23) - #define MVEBU_PM_DDRPHY_PAD_PWRDWN_EN BIT(22) - #define MVEBU_PM_OSC_OFF_EN BIT(21) - #define MVEBU_PM_TBG_OFF_EN BIT(20) - #define MVEBU_PM_CPU_VDDV_OFF_EN BIT(19) - #define MVEBU_PM_AVS_DISABLE_MODE BIT(14) - #define MVEBU_PM_AVS_VDD2_MODE BIT(13) - #define MVEBU_PM_AVS_HOLD_MODE BIT(12) - #define MVEBU_PM_L2_SRAM_LKG_PD_EN BIT(8) - #define MVEBU_PM_EIP_SRAM_LKG_PD_EN BIT(7) - #define MVEBU_PM_DDRMC_SRAM_LKG_PD_EN BIT(6) - #define MVEBU_PM_MCI_SRAM_LKG_PD_EN BIT(5) - #define MVEBU_PM_MMC_SRAM_LKG_PD_EN BIT(4) - #define MVEBU_PM_SATA_SRAM_LKG_PD_EN BIT(3) - #define MVEBU_PM_DMA_SRAM_LKG_PD_EN BIT(2) - #define MVEBU_PM_SEC_SRAM_LKG_PD_EN BIT(1) - #define MVEBU_PM_CPU_SRAM_LKG_PD_EN BIT(0) - #define MVEBU_PM_NB_SRAM_LKG_PD_EN (MVEBU_PM_L2_SRAM_LKG_PD_EN |\ - MVEBU_PM_EIP_SRAM_LKG_PD_EN | MVEBU_PM_DDRMC_SRAM_LKG_PD_EN |\ - MVEBU_PM_MCI_SRAM_LKG_PD_EN | MVEBU_PM_MMC_SRAM_LKG_PD_EN |\ - MVEBU_PM_SATA_SRAM_LKG_PD_EN | MVEBU_PM_DMA_SRAM_LKG_PD_EN |\ - MVEBU_PM_SEC_SRAM_LKG_PD_EN | MVEBU_PM_CPU_SRAM_LKG_PD_EN) -#define MVEBU_PM_NB_PWR_DEBUG_REG (MVEBU_PMSU_REG_BASE + 0xC) - #define MVEBU_PM_NB_FORCE_CLK_ON BIT(30) - #define MVEBU_PM_IGNORE_CM3_SLEEP BIT(21) - #define MVEBU_PM_IGNORE_CM3_DEEP BIT(20) -#define MVEBU_PM_NB_WAKE_UP_EN_REG (MVEBU_PMSU_REG_BASE + 0x2C) - #define MVEBU_PM_SB_WKP_NB_EN BIT(31) - #define MVEBU_PM_NB_GPIO_WKP_EN BIT(27) - #define MVEBU_PM_SOC_TIMER_WKP_EN BIT(26) - #define MVEBU_PM_UART_WKP_EN BIT(25) - #define MVEBU_PM_UART2_WKP_EN BIT(19) - #define MVEBU_PM_CPU_TIMER_WKP_EN BIT(17) - #define MVEBU_PM_NB_WKP_EN BIT(16) - #define MVEBU_PM_CORE1_FIQ_IRQ_WKP_EN BIT(13) - #define MVEBU_PM_CORE0_FIQ_IRQ_WKP_EN BIT(12) -#define MVEBU_PM_CPU_0_PWR_CTRL_REG (MVEBU_PMSU_REG_BASE + 0x34) -#define MVEBU_PM_CPU_1_PWR_CTRL_REG (MVEBU_PMSU_REG_BASE + 0x38) - #define MVEBU_PM_CORE_SOC_PD BIT(2) - #define MVEBU_PM_CORE_PROC_PD BIT(1) - #define MVEBU_PM_CORE_PD BIT(0) -#define MVEBU_PM_CORE_1_RETURN_ADDR_REG (MVEBU_PMSU_REG_BASE + 0x44) -#define MVEBU_PM_CPU_VDD_OFF_INFO_1_REG (MVEBU_PMSU_REG_BASE + 0x48) -#define MVEBU_PM_CPU_VDD_OFF_INFO_2_REG (MVEBU_PMSU_REG_BASE + 0x4C) - #define MVEBU_PM_LOW_POWER_STATE BIT(0) -#define MVEBU_PM_CPU_WAKE_UP_CONF_REG (MVEBU_PMSU_REG_BASE + 0x54) - #define MVEBU_PM_CORE1_WAKEUP BIT(13) - #define MVEBU_PM_CORE0_WAKEUP BIT(12) -#define MVEBU_PM_WAIT_DDR_RDY_VALUE (0x15) -#define MVEBU_PM_SB_CPU_PWR_CTRL_REG (MVEBU_SB_WAKEUP_REG_BASE) - #define MVEBU_PM_SB_PM_START BIT(0) -#define MVEBU_PM_SB_PWR_OPTION_REG (MVEBU_SB_WAKEUP_REG_BASE + 0x4) - #define MVEBU_PM_SDIO_PHY_PDWN_EN BIT(17) - #define MVEBU_PM_SB_VDDV_OFF_EN BIT(16) - #define MVEBU_PM_EBM_SRAM_LKG_PD_EN BIT(11) - #define MVEBU_PM_PCIE_SRAM_LKG_PD_EN BIT(10) - #define MVEBU_PM_GBE1_TX_SRAM_LKG_PD_EN BIT(9) - #define MVEBU_PM_GBE1_RX_SRAM_LKG_PD_EN BIT(8) - #define MVEBU_PM_GBE1_MIB_SRAM_LKG_PD_EN BIT(7) - #define MVEBU_PM_GBE0_TX_SRAM_LKG_PD_EN BIT(6) - #define MVEBU_PM_GBE0_RX_SRAM_LKG_PD_EN BIT(5) - #define MVEBU_PM_GBE0_MIB_SRAM_LKG_PD_EN BIT(4) - #define MVEBU_PM_SDIO_SRAM_LKG_PD_EN BIT(3) - #define MVEBU_PM_USB2_SRAM_LKG_PD_EN BIT(2) - #define MVEBU_PM_USB3_H_SRAM_LKG_PD_EN BIT(1) - #define MVEBU_PM_SB_SRAM_LKG_PD_EN (MVEBU_PM_EBM_SRAM_LKG_PD_EN |\ - MVEBU_PM_PCIE_SRAM_LKG_PD_EN | MVEBU_PM_GBE1_TX_SRAM_LKG_PD_EN |\ - MVEBU_PM_GBE1_RX_SRAM_LKG_PD_EN | MVEBU_PM_GBE1_MIB_SRAM_LKG_PD_EN |\ - MVEBU_PM_GBE0_TX_SRAM_LKG_PD_EN | MVEBU_PM_GBE0_RX_SRAM_LKG_PD_EN |\ - MVEBU_PM_GBE0_MIB_SRAM_LKG_PD_EN | MVEBU_PM_SDIO_SRAM_LKG_PD_EN |\ - MVEBU_PM_USB2_SRAM_LKG_PD_EN | MVEBU_PM_USB3_H_SRAM_LKG_PD_EN) -#define MVEBU_PM_SB_WK_EN_REG (MVEBU_SB_WAKEUP_REG_BASE + 0x10) - #define MVEBU_PM_SB_GPIO_WKP_EN BIT(24) - #define MVEBU_PM_SB_WKP_EN BIT(20) - -/* DRAM registers */ -#define MVEBU_DRAM_STATS_CH0_REG (MVEBU_DRAM_REG_BASE + 0x4) - #define MVEBU_DRAM_WCP_EMPTY BIT(19) -#define MVEBU_DRAM_CMD_0_REG (MVEBU_DRAM_REG_BASE + 0x20) - #define MVEBU_DRAM_CH0_CMD0 BIT(28) - #define MVEBU_DRAM_CS_CMD0 BIT(24) - #define MVEBU_DRAM_WCB_DRAIN_REQ BIT(1) -#define MVEBU_DRAM_PWR_CTRL_REG (MVEBU_DRAM_REG_BASE + 0x54) - #define MVEBU_DRAM_PHY_CLK_GATING_EN BIT(1) - #define MVEBU_DRAM_PHY_AUTO_AC_OFF_EN BIT(0) - -/* AVS registers */ -#define MVEBU_AVS_CTRL_2_REG (MVEBU_AVS_REG_BASE + 0x8) - #define MVEBU_LOW_VDD_MODE_EN BIT(6) - -/* Clock registers */ -#define MVEBU_NB_CLOCK_SEL_REG (MVEBU_NB_REGS_BASE + 0x10) - #define MVEBU_A53_CPU_CLK_SEL BIT(15) - -/* North Bridge Step-Down Registers */ -#define MVEBU_NB_STEP_DOWN_INT_EN_REG MVEBU_NB_STEP_DOWN_REG_BASE - #define MVEBU_NB_GPIO_INT_WAKE_WCPU_CLK BIT(8) - -#define MVEBU_NB_GPIO_18 18 -#define MVEBU_NB_GPIO_19 19 -#define MVEBU_NB_GPIO_25 25 -#define MVEBU_NB_GPIO_26 26 - -typedef int (*wake_up_src_func)(union pm_wake_up_src_data *); - -struct wake_up_src_func_map { - enum pm_wake_up_src_type type; - wake_up_src_func func; -}; - -void marvell_psci_arch_init(int die_index) -{ -} - -static void a3700_pm_ack_irq(void) -{ - uint32_t reg; - - reg = mmio_read_32(MVEBU_NB_IRQ_STATUS_1_REG); - if (reg) - mmio_write_32(MVEBU_NB_IRQ_STATUS_1_REG, reg); - - reg = mmio_read_32(MVEBU_NB_IRQ_STATUS_2_REG); - if (reg) - mmio_write_32(MVEBU_NB_IRQ_STATUS_2_REG, reg); - - reg = mmio_read_32(MVEBU_SB_IRQ_STATUS_1_REG); - if (reg) - mmio_write_32(MVEBU_SB_IRQ_STATUS_1_REG, reg); - - reg = mmio_read_32(MVEBU_SB_IRQ_STATUS_2_REG); - if (reg) - mmio_write_32(MVEBU_SB_IRQ_STATUS_2_REG, reg); - - reg = mmio_read_32(MVEBU_NB_GPIO_IRQ_STATUS_LOW_REG); - if (reg) - mmio_write_32(MVEBU_NB_GPIO_IRQ_STATUS_LOW_REG, reg); - - reg = mmio_read_32(MVEBU_NB_GPIO_IRQ_STATUS_HIGH_REG); - if (reg) - mmio_write_32(MVEBU_NB_GPIO_IRQ_STATUS_HIGH_REG, reg); - - reg = mmio_read_32(MVEBU_SB_GPIO_IRQ_STATUS_REG); - if (reg) - mmio_write_32(MVEBU_SB_GPIO_IRQ_STATUS_REG, reg); -} - -/***************************************************************************** - * A3700 handler called to check the validity of the power state - * parameter. - ***************************************************************************** - */ -int a3700_validate_power_state(unsigned int power_state, - psci_power_state_t *req_state) -{ - ERROR("%s needs to be implemented\n", __func__); - panic(); -} - -/***************************************************************************** - * A3700 handler called when a CPU is about to enter standby. - ***************************************************************************** - */ -void a3700_cpu_standby(plat_local_state_t cpu_state) -{ - ERROR("%s needs to be implemented\n", __func__); - panic(); -} - -/***************************************************************************** - * A3700 handler called when a power domain is about to be turned on. The - * mpidr determines the CPU to be turned on. - ***************************************************************************** - */ -int a3700_pwr_domain_on(u_register_t mpidr) -{ - /* Set barrier */ - dsbsy(); - - /* Set the cpu start address to BL1 entry point */ - mmio_write_32(MVEBU_CPU_1_RESET_VECTOR, - PLAT_MARVELL_CPU_ENTRY_ADDR >> 2); - - /* Get the cpu out of reset */ - mmio_clrbits_32(MVEBU_CPU_1_RESET_REG, BIT(MVEBU_CPU_1_RESET_BIT)); - mmio_setbits_32(MVEBU_CPU_1_RESET_REG, BIT(MVEBU_CPU_1_RESET_BIT)); - - return 0; -} - -/***************************************************************************** - * A3700 handler called to validate the entry point. - ***************************************************************************** - */ -int a3700_validate_ns_entrypoint(uintptr_t entrypoint) -{ - return PSCI_E_SUCCESS; -} - -/***************************************************************************** - * A3700 handler called when a power domain is about to be turned off. The - * target_state encodes the power state that each level should transition to. - ***************************************************************************** - */ -void a3700_pwr_domain_off(const psci_power_state_t *target_state) -{ - /* Prevent interrupts from spuriously waking up this cpu */ - plat_marvell_gic_cpuif_disable(); - - /* Core can not be powered down with pending IRQ, - * acknowledge all the pending IRQ - */ - a3700_pm_ack_irq(); -} - -static void a3700_set_gen_pwr_off_option(void) -{ - /* Enable L2 flush -> processor state-machine option */ - mmio_setbits_32(MVEBU_PM_NB_CPU_PWR_CTRL_REG, MVEBU_PM_L2_FLUSH_EN); - - /* - * North bridge cannot be VDD off (always ON). - * The NB state machine support low power mode by its state machine. - * This bit MUST be set for north bridge power down, e.g., - * OSC input cutoff(NOT TEST), SRAM power down, PMIC, etc. - * It is not related to CPU VDD OFF!! - */ - mmio_clrbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_CPU_VDDV_OFF_EN); - - /* - * MUST: Switch CPU/AXI clock to OSC - * NB state machine clock is always connected to OSC (slow clock). - * But Core0/1/processor state machine's clock are connected to AXI - * clock. Now, AXI clock takes the TBG as clock source. - * If using AXI clock, Core0/1/processor state machine may much faster - * than NB state machine. It will cause problem in this case if cores - * are released before north bridge gets ready. - */ - mmio_clrbits_32(MVEBU_NB_CLOCK_SEL_REG, MVEBU_A53_CPU_CLK_SEL); - - /* - * These register bits will trigger north bridge - * power-down state machine regardless CM3 status. - */ - mmio_setbits_32(MVEBU_PM_NB_PWR_DEBUG_REG, MVEBU_PM_IGNORE_CM3_SLEEP); - mmio_setbits_32(MVEBU_PM_NB_PWR_DEBUG_REG, MVEBU_PM_IGNORE_CM3_DEEP); - - /* - * SRAM => controlled by north bridge state machine. - * Core VDD OFF is not related to CPU SRAM power down. - */ - mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_NB_SRAM_LKG_PD_EN); - - /* - * Idle AXI interface in order to get L2_WFI - * L2 WFI is only asserted after CORE-0 and CORE-1 WFI asserted. - * (only both core-0/1in WFI, L2 WFI will be issued by CORE.) - * Once L2 WFI asserted, this bit is used for signalling assertion - * to AXI IO masters. - */ - mmio_setbits_32(MVEBU_PM_NB_PWR_CTRL_REG, MVEBU_PM_INTERFACE_IDLE); - - /* Enable core0 and core1 VDD_OFF */ - mmio_setbits_32(MVEBU_PM_CPU_0_PWR_CTRL_REG, MVEBU_PM_CORE_PD); - mmio_setbits_32(MVEBU_PM_CPU_1_PWR_CTRL_REG, MVEBU_PM_CORE_PD); - - /* Enable North bridge power down - - * Both Cores MUST enable this bit to power down north bridge! - */ - mmio_setbits_32(MVEBU_PM_CPU_0_PWR_CTRL_REG, MVEBU_PM_CORE_SOC_PD); - mmio_setbits_32(MVEBU_PM_CPU_1_PWR_CTRL_REG, MVEBU_PM_CORE_SOC_PD); - - /* CA53 (processor domain) power down */ - mmio_setbits_32(MVEBU_PM_CPU_0_PWR_CTRL_REG, MVEBU_PM_CORE_PROC_PD); - mmio_setbits_32(MVEBU_PM_CPU_1_PWR_CTRL_REG, MVEBU_PM_CORE_PROC_PD); -} - -static void a3700_en_ddr_self_refresh(void) -{ - /* - * Both count is 16 bits and configurable. By default, osc stb cnt - * is 0xFFF for lower 12 bits. - * Thus, powerdown count is smaller than osc count. - * This count is used for exiting DDR SR mode on wakeup event. - * The powerdown count also has impact on the following - * state changes: idle -> count-down -> ... (power-down, vdd off, etc) - * Here, make stable counter shorter - * Use power down count value instead of osc_stb_cnt to speed up - * DDR self refresh exit - */ - mmio_setbits_32(MVEBU_PM_NB_PWR_CTRL_REG, MVEBU_PM_PWR_DN_CNT_SEL); - - /* - * Enable DDR SR mode => controlled by north bridge state machine - * Therefore, we must powerdown north bridge to trigger the DDR SR - * mode switching. - */ - mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_DDR_SR_EN); - /* Disable DDR clock, otherwise DDR will not enter into SR mode. */ - mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_DDR_CLK_DIS_EN); - /* Power down DDR PHY (PAD) */ - mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_DDRPHY_PWRDWN_EN); - mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, - MVEBU_PM_DDRPHY_PAD_PWRDWN_EN); - - /* Set wait time for DDR ready in ROM code */ - mmio_write_32(MVEBU_PM_CPU_VDD_OFF_INFO_1_REG, - MVEBU_PM_WAIT_DDR_RDY_VALUE); - - /* DDR flush write buffer - mandatory */ - mmio_write_32(MVEBU_DRAM_CMD_0_REG, MVEBU_DRAM_CH0_CMD0 | - MVEBU_DRAM_CS_CMD0 | MVEBU_DRAM_WCB_DRAIN_REQ); - while ((mmio_read_32(MVEBU_DRAM_STATS_CH0_REG) & - MVEBU_DRAM_WCP_EMPTY) != MVEBU_DRAM_WCP_EMPTY) - ; - - /* Trigger PHY reset after ddr out of self refresh => - * supply reset pulse for DDR phy after wake up - */ - mmio_setbits_32(MVEBU_DRAM_PWR_CTRL_REG, MVEBU_DRAM_PHY_CLK_GATING_EN | - MVEBU_DRAM_PHY_AUTO_AC_OFF_EN); -} - -static void a3700_pwr_dn_avs(void) -{ - /* - * AVS power down - controlled by north bridge statemachine - * Enable AVS power down by clear the AVS disable bit. - */ - mmio_clrbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_AVS_DISABLE_MODE); - /* - * Should set BIT[12:13] to powerdown AVS. - * 1. Enable AVS VDD2 mode - * 2. After power down AVS, we must hold AVS output voltage. - * 3. We can choose the lower VDD for AVS power down. - */ - mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_AVS_VDD2_MODE); - mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_AVS_HOLD_MODE); - - /* Enable low VDD mode, AVS will set CPU to lowest core VDD 747mV */ - mmio_setbits_32(MVEBU_AVS_CTRL_2_REG, MVEBU_LOW_VDD_MODE_EN); -} - -static void a3700_pwr_dn_tbg(void) -{ - /* Power down TBG */ - mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_TBG_OFF_EN); -} - -static void a3700_pwr_dn_sb(void) -{ - /* Enable south bridge power down option */ - mmio_setbits_32(MVEBU_PM_NB_PWR_CTRL_REG, MVEBU_PM_SB_PWR_DWN); - - /* Enable SDIO_PHY_PWRDWN */ - mmio_setbits_32(MVEBU_PM_SB_PWR_OPTION_REG, MVEBU_PM_SDIO_PHY_PDWN_EN); - - /* Enable SRAM LRM on SB */ - mmio_setbits_32(MVEBU_PM_SB_PWR_OPTION_REG, MVEBU_PM_SB_SRAM_LKG_PD_EN); - - /* Enable SB Power Off */ - mmio_setbits_32(MVEBU_PM_SB_PWR_OPTION_REG, MVEBU_PM_SB_VDDV_OFF_EN); - - /* Kick off South Bridge Power Off */ - mmio_setbits_32(MVEBU_PM_SB_CPU_PWR_CTRL_REG, MVEBU_PM_SB_PM_START); -} - -static void a3700_set_pwr_off_option(void) -{ - /* Set general power off option */ - a3700_set_gen_pwr_off_option(); - - /* Enable DDR self refresh in low power mode */ - a3700_en_ddr_self_refresh(); - - /* Power down AVS */ - a3700_pwr_dn_avs(); - - /* Power down TBG */ - a3700_pwr_dn_tbg(); - - /* Power down south bridge, pay attention south bridge setting - * should be done before - */ - a3700_pwr_dn_sb(); -} - -static void a3700_set_wake_up_option(void) -{ - /* - * Enable the wakeup event for NB SOC => north-bridge - * state-machine enablement on wake-up event - */ - mmio_setbits_32(MVEBU_PM_NB_WAKE_UP_EN_REG, MVEBU_PM_NB_WKP_EN); - - /* Enable both core0 and core1 wakeup on demand */ - mmio_setbits_32(MVEBU_PM_CPU_WAKE_UP_CONF_REG, - MVEBU_PM_CORE1_WAKEUP | MVEBU_PM_CORE0_WAKEUP); - - /* Enable warm reset in low power mode */ - mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_WARM_RESET_EN); -} - -static void a3700_pm_en_nb_gpio(uint32_t gpio) -{ - /* For GPIO1 interrupt -- North bridge only */ - if (gpio >= 32) { - /* GPIO int mask */ - mmio_clrbits_32(MVEBU_NB_GPIO_IRQ_MASK_2_REG, BIT(gpio - 32)); - - /* NB_CPU_WAKE-up ENABLE GPIO int */ - mmio_setbits_32(MVEBU_NB_GPIO_IRQ_EN_HIGH_REG, BIT(gpio - 32)); - } else { - /* GPIO int mask */ - mmio_clrbits_32(MVEBU_NB_GPIO_IRQ_MASK_1_REG, BIT(gpio)); - - /* NB_CPU_WAKE-up ENABLE GPIO int */ - mmio_setbits_32(MVEBU_NB_GPIO_IRQ_EN_LOW_REG, BIT(gpio)); - } - - mmio_setbits_32(MVEBU_NB_STEP_DOWN_INT_EN_REG, - MVEBU_NB_GPIO_INT_WAKE_WCPU_CLK); - - /* Enable using GPIO as wakeup event - * (actually not only for north bridge) - */ - mmio_setbits_32(MVEBU_PM_NB_WAKE_UP_EN_REG, MVEBU_PM_NB_GPIO_WKP_EN | - MVEBU_PM_NB_WKP_EN | MVEBU_PM_CORE1_FIQ_IRQ_WKP_EN | - MVEBU_PM_CORE0_FIQ_IRQ_WKP_EN); -} - -static void a3700_pm_en_sb_gpio(uint32_t gpio) -{ - /* Enable using GPIO as wakeup event */ - mmio_setbits_32(MVEBU_PM_NB_WAKE_UP_EN_REG, MVEBU_PM_SB_WKP_NB_EN | - MVEBU_PM_NB_WKP_EN | MVEBU_PM_CORE1_FIQ_IRQ_WKP_EN | - MVEBU_PM_CORE0_FIQ_IRQ_WKP_EN); - - /* SB GPIO Wake UP | South Bridge Wake Up Enable */ - mmio_setbits_32(MVEBU_PM_SB_WK_EN_REG, MVEBU_PM_SB_GPIO_WKP_EN | - MVEBU_PM_SB_GPIO_WKP_EN); - - /* GPIO int mask */ - mmio_clrbits_32(MVEBU_SB_GPIO_IRQ_MASK_REG, BIT(gpio)); - - /* NB_CPU_WAKE-up ENABLE GPIO int */ - mmio_setbits_32(MVEBU_SB_GPIO_IRQ_EN_REG, BIT(gpio)); -} - -int a3700_pm_src_gpio(union pm_wake_up_src_data *src_data) -{ - if (src_data->gpio_data.bank_num == 0) - /* North Bridge GPIO */ - a3700_pm_en_nb_gpio(src_data->gpio_data.gpio_num); - else - a3700_pm_en_sb_gpio(src_data->gpio_data.gpio_num); - return 0; -} - -int a3700_pm_src_uart1(union pm_wake_up_src_data *src_data) -{ - /* Clear Uart1 select */ - mmio_clrbits_32(MVEBU_NB_GPIO1_SEL_REG, MVEBU_NB_GPIO1_UART1_SEL); - /* set pin 19 gpio usage*/ - mmio_setbits_32(MVEBU_NB_GPIO1_SEL_REG, MVEBU_NB_GPIO1_GPIO_19_EN); - /* Enable gpio wake-up*/ - a3700_pm_en_nb_gpio(MVEBU_NB_GPIO_19); - /* set pin 18 gpio usage*/ - mmio_setbits_32(MVEBU_NB_GPIO1_SEL_REG, MVEBU_NB_GPIO1_GPIO_18_EN); - /* Enable gpio wake-up*/ - a3700_pm_en_nb_gpio(MVEBU_NB_GPIO_18); - - return 0; -} - -int a3700_pm_src_uart0(union pm_wake_up_src_data *src_data) -{ - /* set pin 25/26 gpio usage*/ - mmio_setbits_32(MVEBU_NB_GPIO1_SEL_REG, MVEBU_NB_GPIO1_GPIO_25_26_EN); - /* Enable gpio wake-up*/ - a3700_pm_en_nb_gpio(MVEBU_NB_GPIO_25); - /* Enable gpio wake-up*/ - a3700_pm_en_nb_gpio(MVEBU_NB_GPIO_26); - - return 0; -} - -struct wake_up_src_func_map src_func_table[WAKE_UP_SRC_MAX] = { - {WAKE_UP_SRC_GPIO, a3700_pm_src_gpio}, - {WAKE_UP_SRC_UART1, a3700_pm_src_uart1}, - {WAKE_UP_SRC_UART0, a3700_pm_src_uart0}, - /* FOLLOWING SRC NOT SUPPORTED YET */ - {WAKE_UP_SRC_TIMER, NULL} -}; - -static wake_up_src_func a3700_get_wake_up_src_func( - enum pm_wake_up_src_type type) -{ - uint32_t loop; - - for (loop = 0; loop < WAKE_UP_SRC_MAX; loop++) { - if (src_func_table[loop].type == type) - return src_func_table[loop].func; - } - return NULL; -} - -static void a3700_set_wake_up_source(void) -{ - struct pm_wake_up_src_config *wake_up_src; - uint32_t loop; - wake_up_src_func src_func = NULL; - - wake_up_src = mv_wake_up_src_config_get(); - for (loop = 0; loop < wake_up_src->wake_up_src_num; loop++) { - src_func = a3700_get_wake_up_src_func( - wake_up_src->wake_up_src[loop].wake_up_src_type); - if (src_func) - src_func( - &(wake_up_src->wake_up_src[loop].wake_up_data)); - } -} - -static void a3700_pm_save_lp_flag(void) -{ - /* Save the flag for enter the low power mode */ - mmio_setbits_32(MVEBU_PM_CPU_VDD_OFF_INFO_2_REG, - MVEBU_PM_LOW_POWER_STATE); -} - -static void a3700_pm_clear_lp_flag(void) -{ - /* Clear the flag for enter the low power mode */ - mmio_clrbits_32(MVEBU_PM_CPU_VDD_OFF_INFO_2_REG, - MVEBU_PM_LOW_POWER_STATE); -} - -static uint32_t a3700_pm_get_lp_flag(void) -{ - /* Get the flag for enter the low power mode */ - return mmio_read_32(MVEBU_PM_CPU_VDD_OFF_INFO_2_REG) & - MVEBU_PM_LOW_POWER_STATE; -} - -/***************************************************************************** - * A3700 handler called when a power domain is about to be suspended. The - * target_state encodes the power state that each level should transition to. - ***************************************************************************** - */ -void a3700_pwr_domain_suspend(const psci_power_state_t *target_state) -{ - /* Prevent interrupts from spuriously waking up this cpu */ - plat_marvell_gic_cpuif_disable(); - - /* Save IRQ states */ - plat_marvell_gic_irq_save(); - - /* Set wake up options */ - a3700_set_wake_up_option(); - - /* Set wake up sources */ - a3700_set_wake_up_source(); - - /* SoC can not be powered down with pending IRQ, - * acknowledge all the pending IRQ - */ - a3700_pm_ack_irq(); - - /* Set power off options */ - a3700_set_pwr_off_option(); - - /* Save the flag for enter the low power mode */ - a3700_pm_save_lp_flag(); - - isb(); -} - -/***************************************************************************** - * A3700 handler called when a power domain has just been powered on after - * being turned off earlier. The target_state encodes the low power state that - * each level has woken up from. - ***************************************************************************** - */ -void a3700_pwr_domain_on_finish(const psci_power_state_t *target_state) -{ - /* arch specific configuration */ - marvell_psci_arch_init(0); - - /* Per-CPU interrupt initialization */ - plat_marvell_gic_pcpu_init(); - plat_marvell_gic_cpuif_enable(); - - /* Restore the per-cpu IRQ state */ - if (a3700_pm_get_lp_flag()) - plat_marvell_gic_irq_pcpu_restore(); -} - -/***************************************************************************** - * A3700 handler called when a power domain has just been powered on after - * having been suspended earlier. The target_state encodes the low power state - * that each level has woken up from. - * TODO: At the moment we reuse the on finisher and reinitialize the secure - * context. Need to implement a separate suspend finisher. - ***************************************************************************** - */ -void a3700_pwr_domain_suspend_finish(const psci_power_state_t *target_state) -{ - struct dec_win_config *io_dec_map; - uint32_t dec_win_num; - struct dram_win_map dram_wins_map; - - /* arch specific configuration */ - marvell_psci_arch_init(0); - - /* Interrupt initialization */ - plat_marvell_gic_init(); - - /* Restore IRQ states */ - plat_marvell_gic_irq_restore(); - - /* - * Initialize CCI for this cluster after resume from suspend state. - * No need for locks as no other CPU is active. - */ - plat_marvell_interconnect_init(); - /* - * Enable CCI coherency for the primary CPU's cluster. - * Platform specific PSCI code will enable coherency for other - * clusters. - */ - plat_marvell_interconnect_enter_coherency(); - - /* CPU address decoder windows initialization. */ - cpu_wins_init(); - - /* fetch CPU-DRAM window mapping information by reading - * CPU-DRAM decode windows (only the enabled ones) - */ - dram_win_map_build(&dram_wins_map); - - /* Get IO address decoder windows */ - if (marvell_get_io_dec_win_conf(&io_dec_map, &dec_win_num)) { - printf("No IO address decoder windows configurations found!\n"); - return; - } - - /* IO address decoder init */ - if (init_io_addr_dec(&dram_wins_map, io_dec_map, dec_win_num)) { - printf("IO address decoder windows initialization failed!\n"); - return; - } - - /* Clear low power mode flag */ - a3700_pm_clear_lp_flag(); -} - -/***************************************************************************** - * This handler is called by the PSCI implementation during the `SYSTEM_SUSPEND - * call to get the `power_state` parameter. This allows the platform to encode - * the appropriate State-ID field within the `power_state` parameter which can - * be utilized in `pwr_domain_suspend()` to suspend to system affinity level. - ***************************************************************************** - */ -void a3700_get_sys_suspend_power_state(psci_power_state_t *req_state) -{ - /* lower affinities use PLAT_MAX_OFF_STATE */ - for (int i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++) - req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE; -} - -/***************************************************************************** - * A3700 handlers to shutdown/reboot the system - ***************************************************************************** - */ -static void __dead2 a3700_system_off(void) -{ - ERROR("%s needs to be implemented\n", __func__); - panic(); -} - -/***************************************************************************** - * A3700 handlers to reset the system - ***************************************************************************** - */ -static void __dead2 a3700_system_reset(void) -{ - /* Clean the mailbox magic number to let it as act like cold boot */ - mmio_write_32(PLAT_MARVELL_MAILBOX_BASE, 0x0); - - dsbsy(); - - /* Flush data cache if the mail box shared RAM is cached */ -#if PLAT_MARVELL_SHARED_RAM_CACHED - flush_dcache_range((uintptr_t)PLAT_MARVELL_MAILBOX_BASE, - 2 * sizeof(uint64_t)); -#endif - - /* Trigger the warm reset */ - mmio_write_32(MVEBU_WARM_RESET_REG, MVEBU_WARM_RESET_MAGIC); - - /* Shouldn't get to this point */ - panic(); -} - -/***************************************************************************** - * Export the platform handlers via plat_arm_psci_pm_ops. The ARM Standard - * platform layer will take care of registering the handlers with PSCI. - ***************************************************************************** - */ -const plat_psci_ops_t plat_arm_psci_pm_ops = { - .cpu_standby = a3700_cpu_standby, - .pwr_domain_on = a3700_pwr_domain_on, - .pwr_domain_off = a3700_pwr_domain_off, - .pwr_domain_suspend = a3700_pwr_domain_suspend, - .pwr_domain_on_finish = a3700_pwr_domain_on_finish, - .pwr_domain_suspend_finish = a3700_pwr_domain_suspend_finish, - .get_sys_suspend_power_state = a3700_get_sys_suspend_power_state, - .system_off = a3700_system_off, - .system_reset = a3700_system_reset, - .validate_power_state = a3700_validate_power_state, - .validate_ns_entrypoint = a3700_validate_ns_entrypoint -}; diff --git a/plat/marvell/armada/a3k/a3700/board/pm_src.c b/plat/marvell/armada/a3k/a3700/board/pm_src.c new file mode 100644 index 000000000..d6eca5d16 --- /dev/null +++ b/plat/marvell/armada/a3k/a3700/board/pm_src.c @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include + +/* This struct provides the PM wake up src configuration */ +static struct pm_wake_up_src_config wake_up_src_cfg = { + .wake_up_src_num = 3, + .wake_up_src[0] = { + .wake_up_src_type = WAKE_UP_SRC_GPIO, + .wake_up_data = { + .gpio_data.bank_num = 0, /* North Bridge */ + .gpio_data.gpio_num = 14 + } + }, + .wake_up_src[1] = { + .wake_up_src_type = WAKE_UP_SRC_GPIO, + .wake_up_data = { + .gpio_data.bank_num = 1, /* South Bridge */ + .gpio_data.gpio_num = 2 + } + }, + .wake_up_src[2] = { + .wake_up_src_type = WAKE_UP_SRC_UART1, + } +}; + +struct pm_wake_up_src_config *mv_wake_up_src_config_get(void) +{ + return &wake_up_src_cfg; +} + diff --git a/plat/marvell/armada/a3k/a3700/mvebu_def.h b/plat/marvell/armada/a3k/a3700/mvebu_def.h new file mode 100644 index 000000000..dad1085f8 --- /dev/null +++ b/plat/marvell/armada/a3k/a3700/mvebu_def.h @@ -0,0 +1,13 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef MVEBU_DEF_H +#define MVEBU_DEF_H + +#include + +#endif /* MVEBU_DEF_H */ diff --git a/plat/marvell/armada/a3k/a3700/plat_bl31_setup.c b/plat/marvell/armada/a3k/a3700/plat_bl31_setup.c new file mode 100644 index 000000000..6862a8670 --- /dev/null +++ b/plat/marvell/armada/a3k/a3700/plat_bl31_setup.c @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include +#include +#include +#include +#include + +/* This routine does MPP initialization */ +static void marvell_bl31_mpp_init(void) +{ + mmio_clrbits_32(MVEBU_NB_GPIO_SEL_REG, 1 << MVEBU_GPIO_TW1_GPIO_EN_OFF); + + /* Set hidden GPIO setting for SPI. + * In north_bridge_pin_out_en_high register 13804, + * bit 28 is the one which enables CS, CLK pins to be + * output, need to set it to 1. + * The initial value of this bit is 1, but in UART boot mode + * initialization, this bit is disabled and the SPI CS and CLK pins + * are used for downloading image purpose; so after downloading, + * we should set this bit to 1 again to enable SPI CS and CLK pins. + * And anyway, this bit value should be 1 in all modes, + * so here we does not judge boot mode and set this bit to 1 always. + */ + mmio_setbits_32(MVEBU_NB_GPIO_OUTPUT_EN_HIGH_REG, + 1 << MVEBU_GPIO_NB_SPI_PIN_MODE_OFF); +} + +/* This function overruns the same function in marvell_bl31_setup.c */ +void bl31_plat_arch_setup(void) +{ + struct dec_win_config *io_dec_map; + uint32_t dec_win_num; + struct dram_win_map dram_wins_map; + + marvell_bl31_plat_arch_setup(); + + /* MPP init */ + marvell_bl31_mpp_init(); + + /* initialize the timer for delay functionality */ + plat_delay_timer_init(); + + /* CPU address decoder windows initialization. */ + cpu_wins_init(); + + /* fetch CPU-DRAM window mapping information by reading + * CPU-DRAM decode windows (only the enabled ones) + */ + dram_win_map_build(&dram_wins_map); + + /* Get IO address decoder windows */ + if (marvell_get_io_dec_win_conf(&io_dec_map, &dec_win_num)) { + printf("No IO address decoder windows configurations found!\n"); + return; + } + + /* IO address decoder init */ + if (init_io_addr_dec(&dram_wins_map, io_dec_map, dec_win_num)) { + printf("IO address decoder windows initialization failed!\n"); + return; + } +} diff --git a/plat/marvell/armada/a3k/a3700/platform.mk b/plat/marvell/armada/a3k/a3700/platform.mk new file mode 100644 index 000000000..050af4199 --- /dev/null +++ b/plat/marvell/armada/a3k/a3700/platform.mk @@ -0,0 +1,10 @@ +# +# Copyright (C) 2018 Marvell International Ltd. +# +# SPDX-License-Identifier: BSD-3-Clause +# https://spdx.org/licenses +# + +include plat/marvell/armada/a3k/common/a3700_common.mk + +include plat/marvell/armada/common/marvell_common.mk diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk new file mode 100644 index 000000000..996556719 --- /dev/null +++ b/plat/marvell/armada/a3k/common/a3700_common.mk @@ -0,0 +1,170 @@ +# +# Copyright (C) 2018 Marvell International Ltd. +# +# SPDX-License-Identifier: BSD-3-Clause +# https://spdx.org/licenses +# + +MARVELL_PLAT_BASE := plat/marvell/armada +MARVELL_PLAT_INCLUDE_BASE := include/plat/marvell/armada +PLAT_FAMILY := a3k +PLAT_FAMILY_BASE := $(MARVELL_PLAT_BASE)/$(PLAT_FAMILY) +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 + +#*********** A3700 ************* +DOIMAGEPATH := $(WTP) +DOIMAGETOOL := $(DOIMAGEPATH)/wtptp/linux/tbb_linux + +ifeq ($(MARVELL_SECURE_BOOT),1) +DOIMAGE_CFG := $(DOIMAGEPATH)/atf-tim.txt +IMAGESPATH := $(DOIMAGEPATH)/tim/trusted + +TIMNCFG := $(DOIMAGEPATH)/atf-timN.txt +TIMNSIG := $(IMAGESPATH)/timnsign.txt +TIM2IMGARGS := -i $(DOIMAGE_CFG) -n $(TIMNCFG) +TIMN_IMAGE := $$(grep "Image Filename:" -m 1 $(TIMNCFG) | cut -c 17-) +else #MARVELL_SECURE_BOOT +DOIMAGE_CFG := $(DOIMAGEPATH)/atf-ntim.txt +IMAGESPATH := $(DOIMAGEPATH)/tim/untrusted +TIM2IMGARGS := -i $(DOIMAGE_CFG) +endif #MARVELL_SECURE_BOOT + +TIMBUILD := $(DOIMAGEPATH)/script/buildtim.sh +TIM2IMG := $(DOIMAGEPATH)/script/tim2img.pl + +# WTMI_IMG is used to specify the customized RTOS image running over +# Service CPU (CM3 processor). By the default, it points to a +# baremetal binary of fuse programming in A3700_utils. +WTMI_IMG := $(DOIMAGEPATH)/wtmi/fuse/build/fuse.bin + +# WTMI_SYSINIT_IMG is used for the system early initialization, +# such as AVS settings, clock-tree setup and dynamic DDR PHY training. +# After the initialization is done, this image will be wiped out +# from the memory and CM3 will continue with RTOS image or other application. +WTMI_SYSINIT_IMG := $(DOIMAGEPATH)/wtmi/sys_init/build/sys_init.bin + +# WTMI_MULTI_IMG is composed of CM3 RTOS image (WTMI_IMG) +# and sys-init image (WTMI_SYSINIT_IMG). +WTMI_MULTI_IMG := $(DOIMAGEPATH)/wtmi/build/wtmi.bin + +WTMI_ENC_IMG := $(DOIMAGEPATH)/wtmi/build/wtmi-enc.bin +BUILD_UART := uart-images + +SRCPATH := $(dir $(BL33)) + +CLOCKSPRESET ?= CPU_800_DDR_800 + +DDR_TOPOLOGY ?= 0 + +BOOTDEV ?= SPINOR +PARTNUM ?= 0 + +TIM_IMAGE := $$(grep "Image Filename:" -m 1 $(DOIMAGE_CFG) | cut -c 17-) +TIMBLDARGS := $(MARVELL_SECURE_BOOT) $(BOOTDEV) $(IMAGESPATH) $(DOIMAGEPATH) $(CLOCKSPRESET) \ + $(DDR_TOPOLOGY) $(PARTNUM) $(DEBUG) $(DOIMAGE_CFG) $(TIMNCFG) $(TIMNSIG) 1 +TIMBLDUARTARGS := $(MARVELL_SECURE_BOOT) UART $(IMAGESPATH) $(DOIMAGEPATH) $(CLOCKSPRESET) \ + $(DDR_TOPOLOGY) 0 0 $(DOIMAGE_CFG) $(TIMNCFG) $(TIMNSIG) 0 +DOIMAGE_FLAGS := -r $(DOIMAGE_CFG) -v -D + +# GICV3 +$(eval $(call add_define,CONFIG_GICV3)) + +# CCI-400 +$(eval $(call add_define,USE_CCI)) + +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk + +MARVELL_GIC_SOURCES := ${GICV3_SOURCES} \ + plat/common/plat_gicv3.c + +PLAT_INCLUDES := -I$(PLAT_FAMILY_BASE)/$(PLAT) \ + -I$(PLAT_COMMON_BASE)/include \ + -I$(PLAT_INCLUDE_BASE)/common \ + -I$(MARVELL_DRV_BASE) \ + -I$/drivers/arm/gic/common/ + +PLAT_BL_COMMON_SOURCES := $(PLAT_COMMON_BASE)/aarch64/a3700_common.c \ + $(MARVELL_COMMON_BASE)/marvell_cci.c \ + $(MARVELL_DRV_BASE)/uart/a3700_console.S + +BL1_SOURCES += $(PLAT_COMMON_BASE)/aarch64/plat_helpers.S \ + lib/cpus/aarch64/cortex_a53.S + +BL31_PORTING_SOURCES := $(PLAT_FAMILY_BASE)/$(PLAT)/board/pm_src.c + +MARVELL_DRV := $(MARVELL_DRV_BASE)/comphy/phy-comphy-3700.c + +BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \ + $(PLAT_COMMON_BASE)/aarch64/plat_helpers.S \ + $(PLAT_COMMON_BASE)/plat_pm.c \ + $(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_ddr_info.c \ + $(MARVELL_COMMON_BASE)/marvell_gicv3.c \ + $(MARVELL_GIC_SOURCES) \ + drivers/arm/cci/cci.c \ + $(BL31_PORTING_SOURCES) \ + $(PLAT_COMMON_BASE)/a3700_sip_svc.c \ + $(MARVELL_DRV) + +mrvl_flash: ${BUILD_PLAT}/${FIP_NAME} ${DOIMAGETOOL} + $(shell truncate -s %128K ${BUILD_PLAT}/bl1.bin) + $(shell cat ${BUILD_PLAT}/bl1.bin ${BUILD_PLAT}/${FIP_NAME} > ${BUILD_PLAT}/${BOOT_IMAGE}) + $(shell truncate -s %4 ${BUILD_PLAT}/${BOOT_IMAGE}) + $(shell truncate -s %4 $(WTMI_IMG)) + @echo + @echo "Building uart images" + $(TIMBUILD) $(TIMBLDUARTARGS) + @sed -i 's|WTMI_IMG|$(WTMI_MULTI_IMG)|1' $(DOIMAGE_CFG) + @sed -i 's|BOOT_IMAGE|$(BUILD_PLAT)/$(BOOT_IMAGE)|1' $(DOIMAGE_CFG) +ifeq ($(MARVELL_SECURE_BOOT),1) + @sed -i 's|WTMI_IMG|$(WTMI_MULTI_IMG)|1' $(TIMNCFG) + @sed -i 's|BOOT_IMAGE|$(BUILD_PLAT)/$(BOOT_IMAGE)|1' $(TIMNCFG) +endif + $(DOIMAGETOOL) $(DOIMAGE_FLAGS) + @if [ -e "$(TIMNCFG)" ]; then $(DOIMAGETOOL) -r $(TIMNCFG); fi + @rm -rf $(BUILD_PLAT)/$(BUILD_UART)* + @mkdir $(BUILD_PLAT)/$(BUILD_UART) + @mv -t $(BUILD_PLAT)/$(BUILD_UART) $(TIM_IMAGE) $(DOIMAGE_CFG) $(TIMN_IMAGE) $(TIMNCFG) + @find . -name "*_h.*" |xargs cp -ut $(BUILD_PLAT)/$(BUILD_UART) + @mv $(subst .bin,_h.bin,$(WTMI_MULTI_IMG)) $(BUILD_PLAT)/$(BUILD_UART)/wtmi_h.bin + @tar czf $(BUILD_PLAT)/$(BUILD_UART).tgz -C $(BUILD_PLAT) ./$(BUILD_UART) + @echo + @echo "Building flash image" + $(TIMBUILD) $(TIMBLDARGS) + sed -i 's|WTMI_IMG|$(WTMI_MULTI_IMG)|1' $(DOIMAGE_CFG) + sed -i 's|BOOT_IMAGE|$(BUILD_PLAT)/$(BOOT_IMAGE)|1' $(DOIMAGE_CFG) +ifeq ($(MARVELL_SECURE_BOOT),1) + @sed -i 's|WTMI_IMG|$(WTMI_MULTI_IMG)|1' $(TIMNCFG) + @sed -i 's|BOOT_IMAGE|$(BUILD_PLAT)/$(BOOT_IMAGE)|1' $(TIMNCFG) + @echo -e "\n\t=======================================================\n"; + @echo -e "\t Secure boot. Encrypting wtmi and boot-image \n"; + @echo -e "\t=======================================================\n"; + @truncate -s %16 $(WTMI_MULTI_IMG) + @openssl enc -aes-256-cbc -e -in $(WTMI_MULTI_IMG) \ + -out $(WTMI_ENC_IMG) \ + -K `cat $(IMAGESPATH)/aes-256.txt` -nosalt \ + -iv `cat $(IMAGESPATH)/iv.txt` -p + @truncate -s %16 $(BUILD_PLAT)/$(BOOT_IMAGE); + @openssl enc -aes-256-cbc -e -in $(BUILD_PLAT)/$(BOOT_IMAGE) \ + -out $(BUILD_PLAT)/$(BOOT_ENC_IMAGE) \ + -K `cat $(IMAGESPATH)/aes-256.txt` -nosalt \ + -iv `cat $(IMAGESPATH)/iv.txt` -p +endif + $(DOIMAGETOOL) $(DOIMAGE_FLAGS) + @if [ -e "$(TIMNCFG)" ]; then $(DOIMAGETOOL) -r $(TIMNCFG); fi + @if [ "$(MARVELL_SECURE_BOOT)" = "1" ]; then sed -i 's|$(WTMI_MULTI_IMG)|$(WTMI_ENC_IMG)|1;s|$(BOOT_IMAGE)|$(BOOT_ENC_IMAGE)|1;' $(TIMNCFG); fi + $(TIM2IMG) $(TIM2IMGARGS) -o $(BUILD_PLAT)/$(FLASH_IMAGE) + @mv -t $(BUILD_PLAT) $(TIM_IMAGE) $(DOIMAGE_CFG) $(TIMN_IMAGE) $(TIMNCFG) $(WTMI_IMG) $(WTMI_SYSINIT_IMG) $(WTMI_MULTI_IMG) + @if [ "$(MARVELL_SECURE_BOOT)" = "1" ]; then mv -t $(BUILD_PLAT) $(WTMI_ENC_IMG) OtpHash.txt; fi + @find . -name "*.txt" | grep -E "CSK[[:alnum:]]_KeyHash.txt|Tim_msg.txt|TIMHash.txt" | xargs rm -f diff --git a/plat/marvell/armada/a3k/common/a3700_ea.c b/plat/marvell/armada/a3k/common/a3700_ea.c new file mode 100644 index 000000000..dd46beb55 --- /dev/null +++ b/plat/marvell/armada/a3k/common/a3700_ea.c @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2019 Repk repk@triplefau.lt + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ +#include +#include +#include + +#define ADVK_SERROR_SYNDROME 0xbf000002 + +void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie, + void *handle, uint64_t flags) +{ + if (syndrome != ADVK_SERROR_SYNDROME) { + ERROR("Unhandled External Abort received on 0x%lx at EL3!\n", + read_mpidr_el1()); + ERROR(" exception reason=%u syndrome=0x%llx\n", ea_reason, + syndrome); + panic(); + } +} diff --git a/plat/marvell/armada/a3k/common/a3700_sip_svc.c b/plat/marvell/armada/a3k/common/a3700_sip_svc.c new file mode 100644 index 000000000..e8ac5fc08 --- /dev/null +++ b/plat/marvell/armada/a3k/common/a3700_sip_svc.c @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include +#include + +#include +#include + +#include "comphy/phy-comphy-3700.h" + +/* Comphy related FID's */ +#define MV_SIP_COMPHY_POWER_ON 0x82000001 +#define MV_SIP_COMPHY_POWER_OFF 0x82000002 +#define MV_SIP_COMPHY_PLL_LOCK 0x82000003 + +/* Miscellaneous FID's' */ +#define MV_SIP_DRAM_SIZE 0x82000010 + +/* This macro is used to identify COMPHY related calls from SMC function ID */ +#define is_comphy_fid(fid) \ + ((fid) >= MV_SIP_COMPHY_POWER_ON && (fid) <= MV_SIP_COMPHY_PLL_LOCK) + +uintptr_t mrvl_sip_smc_handler(uint32_t smc_fid, + u_register_t x1, + u_register_t x2, + u_register_t x3, + u_register_t x4, + void *cookie, + void *handle, + u_register_t flags) +{ + u_register_t ret; + + VERBOSE("%s: got SMC (0x%x) x1 0x%lx, x2 0x%lx\n", + __func__, smc_fid, x1, x2); + if (is_comphy_fid(smc_fid)) { + if (x1 >= MAX_LANE_NR) { + ERROR("%s: Wrong smc (0x%x) lane nr: %lx\n", + __func__, smc_fid, x2); + SMC_RET1(handle, SMC_UNK); + } + } + + switch (smc_fid) { + /* Comphy related FID's */ + case MV_SIP_COMPHY_POWER_ON: + /* x1: comphy_index, x2: comphy_mode */ + ret = mvebu_3700_comphy_power_on(x1, x2); + SMC_RET1(handle, ret); + case MV_SIP_COMPHY_POWER_OFF: + /* x1: comphy_index, x2: comphy_mode */ + ret = mvebu_3700_comphy_power_off(x1, x2); + SMC_RET1(handle, ret); + case MV_SIP_COMPHY_PLL_LOCK: + /* x1: comphy_index, x2: comphy_mode */ + ret = mvebu_3700_comphy_is_pll_locked(x1, x2); + SMC_RET1(handle, ret); + /* Miscellaneous FID's' */ + case MV_SIP_DRAM_SIZE: + /* x1: ap_base_addr */ + ret = mvebu_get_dram_size(MVEBU_REGS_BASE); + SMC_RET1(handle, ret); + + default: + ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid); + SMC_RET1(handle, SMC_UNK); + } +} + +/* Define a runtime service descriptor for fast SMC calls */ +DECLARE_RT_SVC( + marvell_sip_svc, + OEN_SIP_START, + OEN_SIP_END, + SMC_TYPE_FAST, + NULL, + mrvl_sip_smc_handler +); diff --git a/plat/marvell/armada/a3k/common/aarch64/a3700_common.c b/plat/marvell/armada/a3k/common/aarch64/a3700_common.c new file mode 100644 index 000000000..63512853c --- /dev/null +++ b/plat/marvell/armada/a3k/common/aarch64/a3700_common.c @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ +#include + +/* MMU entry for internal (register) space access */ +#define MAP_DEVICE0 MAP_REGION_FLAT(DEVICE0_BASE, \ + DEVICE0_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +/* + * Table of regions for various BL stages to map using the MMU. + */ +#if IMAGE_BL1 +const mmap_region_t plat_marvell_mmap[] = { + MARVELL_MAP_SHARED_RAM, + MAP_DEVICE0, + {0} +}; +#endif +#if IMAGE_BL2 +const mmap_region_t plat_marvell_mmap[] = { + MARVELL_MAP_SHARED_RAM, + MAP_DEVICE0, + MARVELL_MAP_DRAM, + {0} +}; +#endif +#if IMAGE_BL2U +const mmap_region_t plat_marvell_mmap[] = { + MAP_DEVICE0, + {0} +}; +#endif +#if IMAGE_BL31 +const mmap_region_t plat_marvell_mmap[] = { + MARVELL_MAP_SHARED_RAM, + MAP_DEVICE0, + MARVELL_MAP_DRAM, + {0} +}; +#endif +#if IMAGE_BL32 +const mmap_region_t plat_marvell_mmap[] = { + MAP_DEVICE0, + {0} +}; +#endif + +MARVELL_CASSERT_MMAP; diff --git a/plat/marvell/armada/a3k/common/aarch64/plat_helpers.S b/plat/marvell/armada/a3k/common/aarch64/plat_helpers.S new file mode 100644 index 000000000..90d76f08e --- /dev/null +++ b/plat/marvell/armada/a3k/common/aarch64/plat_helpers.S @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include + + .globl plat_secondary_cold_boot_setup + .globl plat_get_my_entrypoint + .globl plat_is_my_cpu_primary + + /* ----------------------------------------------------- + * void plat_secondary_cold_boot_setup (void); + * + * This function performs any platform specific actions + * needed for a secondary cpu after a cold reset. Right + * now this is a stub function. + * ----------------------------------------------------- + */ +func plat_secondary_cold_boot_setup + mov x0, #0 + ret +endfunc plat_secondary_cold_boot_setup + + /* --------------------------------------------------------------------- + * unsigned long plat_get_my_entrypoint (void); + * + * Main job of this routine is to distinguish between cold and warm boot + * For a cold boot, return 0. + * For a warm boot, read the mailbox and return the address it contains. + * A magic number is placed before entrypoint to avoid mistake caused by + * uninitialized mailbox data area. + * --------------------------------------------------------------------- + */ +func plat_get_my_entrypoint + /* Read first word and compare it with magic num */ + mov_imm x0, PLAT_MARVELL_MAILBOX_BASE + ldr x1, [x0] + mov_imm x2, PLAT_MARVELL_MAILBOX_MAGIC_NUM + cmp x1, x2 + /* If compare failed, return 0, i.e. cold boot */ + beq entrypoint + mov x0, #0 + ret +entrypoint: + /* Second word contains the jump address */ + add x0, x0, #8 + ldr x0, [x0] + ret +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 + and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK) + cmp x0, #MVEBU_PRIMARY_CPU + cset w0, eq + ret +endfunc plat_is_my_cpu_primary diff --git a/plat/marvell/armada/a3k/common/dram_win.c b/plat/marvell/armada/a3k/common/dram_win.c new file mode 100644 index 000000000..694f6d480 --- /dev/null +++ b/plat/marvell/armada/a3k/common/dram_win.c @@ -0,0 +1,278 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include + +#include +#include +#include +#include + +/* Armada 3700 has 5 configurable windows */ +#define MV_CPU_WIN_NUM 5 + +#define CPU_WIN_DISABLED 0 +#define CPU_WIN_ENABLED 1 + +/* + * There are 2 different cpu decode window configuration cases: + * - DRAM size is not over 2GB; + * - DRAM size is 4GB. + */ +enum cpu_win_config_num { + CPU_WIN_CONFIG_DRAM_NOT_OVER_2GB = 0, + CPU_WIN_CONFIG_DRAM_4GB, + CPU_WIN_CONFIG_MAX +}; + +enum cpu_win_target { + CPU_WIN_TARGET_DRAM = 0, + CPU_WIN_TARGET_INTERNAL_REG, + CPU_WIN_TARGET_PCIE, + CPU_WIN_TARGET_PCIE_OVER_MCI, + CPU_WIN_TARGET_BOOT_ROM, + CPU_WIN_TARGET_MCI_EXTERNAL, + CPU_WIN_TARGET_RWTM_RAM = 7, + CPU_WIN_TARGET_CCI400_REG +}; + +struct cpu_win_configuration { + uint32_t enabled; + enum cpu_win_target target; + uint64_t base_addr; + uint64_t size; + uint64_t remap_addr; +}; + +struct cpu_win_configuration mv_cpu_wins[CPU_WIN_CONFIG_MAX][MV_CPU_WIN_NUM] = { + /* + * When total dram size is not over 2GB: + * DDR window 0 is configured in tim header, its size may be not 512MB, + * but the actual dram size, no need to configure it again; + * other cpu windows are kept as default. + */ + { + /* enabled + * target + * base + * size + * remap + */ + {CPU_WIN_ENABLED, + CPU_WIN_TARGET_DRAM, + 0x0, + 0x08000000, + 0x0}, + {CPU_WIN_ENABLED, + CPU_WIN_TARGET_MCI_EXTERNAL, + 0xe0000000, + 0x08000000, + 0xe0000000}, + {CPU_WIN_ENABLED, + CPU_WIN_TARGET_PCIE, + 0xe8000000, + 0x08000000, + 0xe8000000}, + {CPU_WIN_ENABLED, + CPU_WIN_TARGET_RWTM_RAM, + 0xf0000000, + 0x00020000, + 0x1fff0000}, + {CPU_WIN_ENABLED, + CPU_WIN_TARGET_PCIE_OVER_MCI, + 0x80000000, + 0x10000000, + 0x80000000}, + }, + + /* + * If total dram size is more than 2GB, now there is only one case - 4GB + * dram; we will use below cpu windows configurations: + * - Internal Regs, CCI-400, Boot Rom and PCIe windows are kept as + * default; + * - Use 4 CPU decode windows for DRAM, which cover 3.375GB DRAM; + * DDR window 0 is configured in tim header with 2GB size, no need to + * configure it again here; + * + * 0xFFFFFFFF ---> |-----------------------| + * | Boot ROM | 64KB + * 0xFFF00000 ---> +-----------------------+ + * : : + * 0xF0000000 ---> |-----------------------| + * | PCIE | 128 MB + * 0xE8000000 ---> |-----------------------| + * | DDR window 3 | 128 MB + * 0xE0000000 ---> +-----------------------+ + * : : + * 0xD8010000 ---> |-----------------------| + * | CCI Regs | 64 KB + * 0xD8000000 ---> +-----------------------+ + * : : + * : : + * 0xD2000000 ---> +-----------------------+ + * | Internal Regs | 32MB + * 0xD0000000 ---> |-----------------------| + * | DDR window 2 | 256 MB + * 0xC0000000 ---> |-----------------------| + * | | + * | DDR window 1 | 1 GB + * | | + * 0x80000000 ---> |-----------------------| + * | | + * | | + * | DDR window 0 | 2 GB + * | | + * | | + * 0x00000000 ---> +-----------------------+ + */ + { + /* win_id + * target + * base + * size + * remap + */ + {CPU_WIN_ENABLED, + CPU_WIN_TARGET_DRAM, + 0x0, + 0x80000000, + 0x0}, + {CPU_WIN_ENABLED, + CPU_WIN_TARGET_DRAM, + 0x80000000, + 0x40000000, + 0x80000000}, + {CPU_WIN_ENABLED, + CPU_WIN_TARGET_DRAM, + 0xc0000000, + 0x10000000, + 0xc0000000}, + {CPU_WIN_ENABLED, + CPU_WIN_TARGET_DRAM, + 0xe0000000, + 0x08000000, + 0xe0000000}, + {CPU_WIN_ENABLED, + CPU_WIN_TARGET_PCIE, + 0xe8000000, + 0x08000000, + 0xe8000000}, + }, +}; + +/* + * dram_win_map_build + * + * This function builds cpu dram windows mapping + * which includes base address and window size by + * reading cpu dram decode windows registers. + * + * @input: N/A + * + * @output: + * - win_map: cpu dram windows mapping + * + * @return: N/A + */ +void dram_win_map_build(struct dram_win_map *win_map) +{ + int32_t win_id; + struct dram_win *win; + uint32_t base_reg, ctrl_reg, size_reg, enabled, target; + + memset(win_map, 0, sizeof(struct dram_win_map)); + for (win_id = 0; win_id < DRAM_WIN_MAP_NUM_MAX; win_id++) { + ctrl_reg = mmio_read_32(CPU_DEC_WIN_CTRL_REG(win_id)); + target = (ctrl_reg & CPU_DEC_CR_WIN_TARGET_MASK) >> + CPU_DEC_CR_WIN_TARGET_OFFS; + enabled = ctrl_reg & CPU_DEC_CR_WIN_ENABLE; + /* Ignore invalid and non-dram windows*/ + if ((enabled == 0) || (target != DRAM_CPU_DEC_TARGET_NUM)) + continue; + + win = win_map->dram_windows + win_map->dram_win_num; + base_reg = mmio_read_32(CPU_DEC_WIN_BASE_REG(win_id)); + size_reg = mmio_read_32(CPU_DEC_WIN_SIZE_REG(win_id)); + /* Base reg [15:0] corresponds to transaction address [39:16] */ + win->base_addr = (base_reg & CPU_DEC_BR_BASE_MASK) >> + CPU_DEC_BR_BASE_OFFS; + win->base_addr *= CPU_DEC_CR_WIN_SIZE_ALIGNMENT; + /* + * Size reg [15:0] is programmed from LSB to MSB as a sequence + * of 1s followed by a sequence of 0s and the number of 1s + * specifies the size of the window in 64 KB granularity, + * for example, a value of 00FFh specifies 256 x 64 KB = 16 MB + */ + win->win_size = (size_reg & CPU_DEC_CR_WIN_SIZE_MASK) >> + CPU_DEC_CR_WIN_SIZE_OFFS; + win->win_size = (win->win_size + 1) * + CPU_DEC_CR_WIN_SIZE_ALIGNMENT; + + win_map->dram_win_num++; + } +} + +static void cpu_win_set(uint32_t win_id, struct cpu_win_configuration *win_cfg) +{ + uint32_t base_reg, ctrl_reg, size_reg, remap_reg; + + /* Disable window */ + ctrl_reg = mmio_read_32(CPU_DEC_WIN_CTRL_REG(win_id)); + ctrl_reg &= ~CPU_DEC_CR_WIN_ENABLE; + mmio_write_32(CPU_DEC_WIN_CTRL_REG(win_id), ctrl_reg); + + /* For an disabled window, only disable it. */ + if (!win_cfg->enabled) + return; + + /* Set Base Register */ + base_reg = (uint32_t)(win_cfg->base_addr / + CPU_DEC_CR_WIN_SIZE_ALIGNMENT); + base_reg <<= CPU_DEC_BR_BASE_OFFS; + base_reg &= CPU_DEC_BR_BASE_MASK; + mmio_write_32(CPU_DEC_WIN_BASE_REG(win_id), base_reg); + + /* Set Remap Register with the same value + * as the field in Base Register + */ + remap_reg = (uint32_t)(win_cfg->remap_addr / + CPU_DEC_CR_WIN_SIZE_ALIGNMENT); + remap_reg <<= CPU_DEC_RLR_REMAP_LOW_OFFS; + remap_reg &= CPU_DEC_RLR_REMAP_LOW_MASK; + mmio_write_32(CPU_DEC_REMAP_LOW_REG(win_id), remap_reg); + + /* Set Size Register */ + size_reg = (win_cfg->size / CPU_DEC_CR_WIN_SIZE_ALIGNMENT) - 1; + size_reg <<= CPU_DEC_CR_WIN_SIZE_OFFS; + size_reg &= CPU_DEC_CR_WIN_SIZE_MASK; + mmio_write_32(CPU_DEC_WIN_SIZE_REG(win_id), size_reg); + + /* Set Control Register - set target id and enable window */ + ctrl_reg &= ~CPU_DEC_CR_WIN_TARGET_MASK; + ctrl_reg |= (win_cfg->target << CPU_DEC_CR_WIN_TARGET_OFFS); + ctrl_reg |= CPU_DEC_CR_WIN_ENABLE; + mmio_write_32(CPU_DEC_WIN_CTRL_REG(win_id), ctrl_reg); +} + +void cpu_wins_init(void) +{ + uint32_t cfg_idx, win_id; + + if (mvebu_get_dram_size(MVEBU_REGS_BASE) <= _2GB_) + cfg_idx = CPU_WIN_CONFIG_DRAM_NOT_OVER_2GB; + else + cfg_idx = CPU_WIN_CONFIG_DRAM_4GB; + + /* Window 0 is configured always for DRAM in tim header + * already, no need to configure it again here + */ + for (win_id = 1; win_id < MV_CPU_WIN_NUM; win_id++) + cpu_win_set(win_id, &mv_cpu_wins[cfg_idx][win_id]); +} + diff --git a/plat/marvell/armada/a3k/common/include/a3700_plat_def.h b/plat/marvell/armada/a3k/common/include/a3700_plat_def.h new file mode 100644 index 000000000..c7f40adc3 --- /dev/null +++ b/plat/marvell/armada/a3k/common/include/a3700_plat_def.h @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef A3700_PLAT_DEF_H +#define A3700_PLAT_DEF_H + +#include + + +#define MVEBU_MAX_CPUS_PER_CLUSTER 2 + +#define MVEBU_PRIMARY_CPU 0x0 + +/* + * The counter on A3700 is always fed from reference 25M clock (XTAL). + * However minimal CPU counter prescaler is 2, so the counter + * frequency will be divided by 2, the number is 12.5M + */ +#define COUNTER_FREQUENCY 12500000 + +#define MVEBU_REGS_BASE 0xD0000000 + +/***************************************************************************** + * MVEBU memory map related constants + ***************************************************************************** + */ +/* Aggregate of all devices in the first GB */ +#define DEVICE0_BASE MVEBU_REGS_BASE +#define DEVICE0_SIZE 0x10000000 + +/***************************************************************************** + * GIC-500 & interrupt handling related constants + ***************************************************************************** + */ +/* Base MVEBU compatible GIC memory map */ +#define MVEBU_GICD_BASE 0x1D00000 +#define MVEBU_GICR_BASE 0x1D40000 +#define MVEBU_GICC_BASE 0x1D80000 + +/* CCI-400 */ +#define MVEBU_CCI_BASE 0x8000000 + +/***************************************************************************** + * North and south bridge register base + ***************************************************************************** + */ +#define MVEBU_NB_REGS_BASE (MVEBU_REGS_BASE + 0x13000) +#define MVEBU_SB_REGS_BASE (MVEBU_REGS_BASE + 0x18000) + +/***************************************************************************** + * GPIO registers related constants + ***************************************************************************** + */ +/* North and south bridge GPIO register base address */ +#define MVEBU_NB_GPIO_REG_BASE (MVEBU_NB_REGS_BASE + 0x800) +#define MVEBU_NB_GPIO_IRQ_REG_BASE (MVEBU_NB_REGS_BASE + 0xC00) +#define MVEBU_SB_GPIO_REG_BASE (MVEBU_SB_REGS_BASE + 0x800) +#define MVEBU_SB_GPIO_IRQ_REG_BASE (MVEBU_SB_REGS_BASE + 0xC00) +#define MVEBU_NB_SB_IRQ_REG_BASE (MVEBU_REGS_BASE + 0x8A00) + +/* North Bridge GPIO selection register */ +#define MVEBU_NB_GPIO_SEL_REG (MVEBU_NB_GPIO_REG_BASE + 0x30) +#define MVEBU_NB_GPIO_OUTPUT_EN_HIGH_REG (MVEBU_NB_GPIO_REG_BASE + 0x04) +/* I2C1 GPIO Enable bit offset */ +#define MVEBU_GPIO_TW1_GPIO_EN_OFF (10) +/* SPI pins mode bit offset */ +#define MVEBU_GPIO_NB_SPI_PIN_MODE_OFF (28) + +/***************************************************************************** + * DRAM registers related constants + ***************************************************************************** + */ +#define MVEBU_DRAM_REG_BASE (MVEBU_REGS_BASE) + +/***************************************************************************** + * SB wake-up registers related constants + ***************************************************************************** + */ +#define MVEBU_SB_WAKEUP_REG_BASE (MVEBU_REGS_BASE + 0x19000) + +/***************************************************************************** + * PMSU registers related constants + ***************************************************************************** + */ +#define MVEBU_PMSU_REG_BASE (MVEBU_REGS_BASE + 0x14000) + +/***************************************************************************** + * North Bridge Step-Down Registers + ***************************************************************************** + */ +#define MVEBU_NB_STEP_DOWN_REG_BASE (MVEBU_REGS_BASE + 0x12800) + +/***************************************************************************** + * DRAM CS memory map register base + ***************************************************************************** + */ +#define MVEBU_CS_MMAP_REG_BASE (MVEBU_REGS_BASE + 0x200) + +/***************************************************************************** + * CPU decoder window registers related constants + ***************************************************************************** + */ +#define MVEBU_CPU_DEC_WIN_REG_BASE (MVEBU_REGS_BASE + 0xCF00) + +/***************************************************************************** + * AVS registers related constants + ***************************************************************************** + */ +#define MVEBU_AVS_REG_BASE (MVEBU_REGS_BASE + 0x11500) + + +/***************************************************************************** + * AVS registers related constants + ***************************************************************************** + */ +#define MVEBU_COMPHY_REG_BASE (MVEBU_REGS_BASE + 0x18300) + +#endif /* A3700_PLAT_DEF_H */ diff --git a/plat/marvell/armada/a3k/common/include/a3700_pm.h b/plat/marvell/armada/a3k/common/include/a3700_pm.h new file mode 100644 index 000000000..cc6cf436a --- /dev/null +++ b/plat/marvell/armada/a3k/common/include/a3700_pm.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2016 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef A3700_PM_H +#define A3700_PM_H + +#include + +/* supported wake up sources */ +enum pm_wake_up_src_type { + WAKE_UP_SRC_GPIO, + /* FOLLOWING SRC NOT SUPPORTED YET */ + WAKE_UP_SRC_TIMER, + WAKE_UP_SRC_UART0, + WAKE_UP_SRC_UART1, + WAKE_UP_SRC_MAX, +}; + +struct pm_gpio_data { + /* + * bank 0: North bridge GPIO + * bank 1: South bridge GPIO + */ + uint32_t bank_num; + uint32_t gpio_num; +}; + +union pm_wake_up_src_data { + struct pm_gpio_data gpio_data; + /* delay in seconds */ + uint32_t timer_delay; +}; + +struct pm_wake_up_src { + enum pm_wake_up_src_type wake_up_src_type; + + union pm_wake_up_src_data wake_up_data; +}; + +struct pm_wake_up_src_config { + uint32_t wake_up_src_num; + struct pm_wake_up_src wake_up_src[WAKE_UP_SRC_MAX]; +}; + +struct pm_wake_up_src_config *mv_wake_up_src_config_get(void); + +#endif /* A3700_PM_H */ diff --git a/plat/marvell/armada/a3k/common/include/ddr_info.h b/plat/marvell/armada/a3k/common/include/ddr_info.h new file mode 100644 index 000000000..254f78c1b --- /dev/null +++ b/plat/marvell/armada/a3k/common/include/ddr_info.h @@ -0,0 +1,14 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef DDR_INFO_H +#define DDR_INFO_H + +#define DRAM_MAX_IFACE 1 +#define DRAM_CH0_MMAP_LOW_OFFSET 0x200 + +#endif /* DDR_INFO_H */ diff --git a/plat/marvell/armada/a3k/common/include/dram_win.h b/plat/marvell/armada/a3k/common/include/dram_win.h new file mode 100644 index 000000000..26a013784 --- /dev/null +++ b/plat/marvell/armada/a3k/common/include/dram_win.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef DRAM_WIN_H +#define DRAM_WIN_H + +#include + +#include + +void dram_win_map_build(struct dram_win_map *win_map); +void cpu_wins_init(void); + +#endif /* DRAM_WIN_H */ diff --git a/plat/marvell/armada/a3k/common/include/io_addr_dec.h b/plat/marvell/armada/a3k/common/include/io_addr_dec.h new file mode 100644 index 000000000..42ef30bc2 --- /dev/null +++ b/plat/marvell/armada/a3k/common/include/io_addr_dec.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef IO_ADDR_DEC_H +#define IO_ADDR_DEC_H + +#include + +/* There are 5 configurable cpu decoder windows. */ +#define DRAM_WIN_MAP_NUM_MAX 5 +/* Target number for dram in cpu decoder windows. */ +#define DRAM_CPU_DEC_TARGET_NUM 0 + +/* + * Not all configurable decode windows could be used for dram, some units have + * to reserve one decode window for other unit they have to communicate with; + * for example, DMA engineer has 3 configurable windows, but only two could be + * for dram while the last one has to be for pcie, so for DMA, its max_dram_win + * is 2. + */ +struct dec_win_config { + uint32_t dec_reg_base; /* IO address decoder register base address */ + uint32_t win_attr; /* IO address decoder windows attributes */ + /* How many configurable dram decoder windows that this unit has; */ + uint32_t max_dram_win; + /* The decoder windows number including remapping that this unit has */ + uint32_t max_remap; + /* The offset between continuous decode windows + * within the same unit, typically 0x10 + */ + uint32_t win_offset; +}; + +struct dram_win { + uintptr_t base_addr; + uintptr_t win_size; +}; + +struct dram_win_map { + int dram_win_num; + struct dram_win dram_windows[DRAM_WIN_MAP_NUM_MAX]; +}; + +/* + * init_io_addr_dec + * + * This function initializes io address decoder windows by + * cpu dram window mapping information + * + * @input: N/A + * - dram_wins_map: cpu dram windows mapping + * - io_dec_config: io address decoder windows configuration + * - io_unit_num: io address decoder unit number + * @output: N/A + * + * @return: 0 on success and others on failure + */ +int init_io_addr_dec(struct dram_win_map *dram_wins_map, + struct dec_win_config *io_dec_config, + uint32_t io_unit_num); + +#endif /* IO_ADDR_DEC_H */ diff --git a/plat/marvell/armada/a3k/common/include/plat_macros.S b/plat/marvell/armada/a3k/common/include/plat_macros.S new file mode 100644 index 000000000..f689b4f39 --- /dev/null +++ b/plat/marvell/armada/a3k/common/include/plat_macros.S @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef PLAT_MACROS_S +#define PLAT_MACROS_S + +#include + +/* --------------------------------------------- + * The below macro prints out relevant GIC and + * CCI registers registers whenever an unhandled + * exception is taken in BL31. + * --------------------------------------------- + */ +.macro plat_crash_print_regs + mov_imm x17, MVEBU_GICC_BASE + mov_imm x16, MVEBU_GICD_BASE + marvell_print_gic_regs + print_cci_regs +.endm + +#endif /* PLAT_MACROS_S */ diff --git a/plat/marvell/armada/a3k/common/include/platform_def.h b/plat/marvell/armada/a3k/common/include/platform_def.h new file mode 100644 index 000000000..e6660d407 --- /dev/null +++ b/plat/marvell/armada/a3k/common/include/platform_def.h @@ -0,0 +1,232 @@ +/* + * Copyright (C) 2016-2019 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +#ifndef __ASSEMBLER__ +#include +#endif /* __ASSEMBLER__ */ + +#include +#include + +/* + * Most platform porting definitions provided by included headers + */ + +/* + * DRAM Memory layout: + * +-----------------------+ + * : : + * : Linux : + * 0x04X00000-->+-----------------------+ + * | BL3-3(u-boot) |>>}>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + * |-----------------------| } | + * | BL3-[0,1, 2] | }---------------------------------> | + * |-----------------------| } || | + * | BL2 | }->FIP (loaded by || | + * |-----------------------| } BootROM to DRAM) || | + * | FIP_TOC | } || | + * 0x04120000-->|-----------------------| || | + * | BL1 (RO) | || | + * 0x04100000-->+-----------------------+ || | + * : : || | + * : Trusted SRAM section : \/ | + * 0x04040000-->+-----------------------+ Replaced by BL2 +----------------+ | + * | BL1 (RW) | <<<<<<<<<<<<<<<< | BL3-1 NOBITS | | + * 0x04037000-->|-----------------------| <<<<<<<<<<<<<<<< |----------------| | + * | | <<<<<<<<<<<<<<<< | BL3-1 PROGBITS | | + * 0x04023000-->|-----------------------| +----------------+ | + * | BL2 | | + * |-----------------------| | + * | | | + * 0x04001000-->|-----------------------| | + * | Shared | | + * 0x04000000-->+-----------------------+ | + * : : | + * : Linux : | + * : : | + * |-----------------------| | + * | | U-Boot(BL3-3) Loaded by BL2 | + * | U-Boot | <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + * 0x00000000-->+-----------------------+ + * + * Trusted SRAM section 0x4000000..0x4200000: + * ---------------------------------------- + * SRAM_BASE = 0x4001000 + * BL2_BASE = 0x4006000 + * BL2_LIMIT = BL31_BASE + * BL31_BASE = 0x4023000 = (64MB + 256KB - 0x1D000) + * BL31_PROGBITS_LIMIT = BL1_RW_BASE + * BL1_RW_BASE = 0x4037000 = (64MB + 256KB - 0x9000) + * BL1_RW_LIMIT = BL31_LIMIT = 0x4040000 + * + * + * PLAT_MARVELL_FIP_BASE = 0x4120000 + */ + +#define PLAT_MARVELL_ATF_BASE 0x4000000 +#define PLAT_MARVELL_ATF_LOAD_ADDR \ + (PLAT_MARVELL_ATF_BASE + 0x100000) + +#define PLAT_MARVELL_FIP_BASE \ + (PLAT_MARVELL_ATF_LOAD_ADDR + 0x20000) +#define PLAT_MARVELL_FIP_MAX_SIZE 0x4000000 + +#define PLAT_MARVELL_CLUSTER_CORE_COUNT U(2) +/* DRAM[2MB..66MB] is used as Trusted ROM */ +#define PLAT_MARVELL_TRUSTED_ROM_BASE PLAT_MARVELL_ATF_LOAD_ADDR +/* 64 MB TODO: reduce this to minimum needed according to fip image size*/ +#define PLAT_MARVELL_TRUSTED_ROM_SIZE 0x04000000 +/* Reserve 16M for SCP (Secure PayLoad) Trusted DRAM */ +#define PLAT_MARVELL_TRUSTED_DRAM_BASE 0x04400000 +#define PLAT_MARVELL_TRUSTED_DRAM_SIZE 0x01000000 /* 16 MB */ + +/* + * PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size + * plus a little space for growth. + */ +#define PLAT_MARVELL_MAX_BL1_RW_SIZE 0xA000 + +/* + * PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a + * little space for growth. + */ +#define PLAT_MARVELL_MAX_BL2_SIZE 0xF000 + +/* + * PLAT_ARM_MAX_BL31_SIZE is calculated using the current BL31 debug size plus a + * little space for growth. + */ +#define PLAT_MARVEL_MAX_BL31_SIZE 0x5D000 + +#define PLAT_MARVELL_CPU_ENTRY_ADDR BL1_RO_BASE + +/* GIC related definitions */ +#define PLAT_MARVELL_GICD_BASE (MVEBU_REGS_BASE + MVEBU_GICD_BASE) +#define PLAT_MARVELL_GICR_BASE (MVEBU_REGS_BASE + MVEBU_GICR_BASE) +#define PLAT_MARVELL_GICC_BASE (MVEBU_REGS_BASE + MVEBU_GICC_BASE) + +#define PLAT_MARVELL_G0_IRQ_PROPS(grp) \ + INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL) + +#define PLAT_MARVELL_G1S_IRQ_PROPS(grp) \ + INTR_PROP_DESC(MARVELL_IRQ_SEC_PHY_TIMER, \ + GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL) + + +#define PLAT_MARVELL_SHARED_RAM_CACHED 1 + +/* CCI related constants */ +#define PLAT_MARVELL_CCI_BASE (MVEBU_REGS_BASE + MVEBU_CCI_BASE) +#define PLAT_MARVELL_CCI_CLUSTER0_SL_IFACE_IX 3 +#define PLAT_MARVELL_CCI_CLUSTER1_SL_IFACE_IX 4 + +/* + * Load address of BL3-3 for this platform port + */ +#define PLAT_MARVELL_NS_IMAGE_OFFSET 0x0 + +/* System Reference Clock*/ +#define PLAT_REF_CLK_IN_HZ COUNTER_FREQUENCY + +/* + * PL011 related constants + */ +#define PLAT_MARVELL_BOOT_UART_BASE (MVEBU_REGS_BASE + 0x12000) +#define PLAT_MARVELL_BOOT_UART_CLK_IN_HZ 25804800 + +#define PLAT_MARVELL_CRASH_UART_BASE PLAT_MARVELL_BOOT_UART_BASE +#define PLAT_MARVELL_CRASH_UART_CLK_IN_HZ PLAT_MARVELL_BOOT_UART_CLK_IN_HZ + +#define PLAT_MARVELL_BL31_RUN_UART_BASE PLAT_MARVELL_BOOT_UART_BASE +#define PLAT_MARVELL_BL31_RUN_UART_CLK_IN_HZ PLAT_MARVELL_BOOT_UART_CLK_IN_HZ + +/* Required platform porting definitions */ +#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL1 + +/* System timer related constants */ +#define PLAT_MARVELL_NSTIMER_FRAME_ID 1 + +/* Mailbox base address */ +#define PLAT_MARVELL_MAILBOX_BASE \ + (MARVELL_TRUSTED_SRAM_BASE + 0x400) +#define PLAT_MARVELL_MAILBOX_SIZE 0x100 +#define PLAT_MARVELL_MAILBOX_MAGIC_NUM 0x6D72766C /* mrvl */ + +/* DRAM CS memory map registers related constants */ +#define MVEBU_CS_MMAP_LOW(cs_num) \ + (MVEBU_CS_MMAP_REG_BASE + (cs_num) * 0x8) +#define MVEBU_CS_MMAP_ENABLE 0x1 +#define MVEBU_CS_MMAP_AREA_LEN_OFFS 16 +#define MVEBU_CS_MMAP_AREA_LEN_MASK \ + (0x1f << MVEBU_CS_MMAP_AREA_LEN_OFFS) +#define MVEBU_CS_MMAP_START_ADDR_LOW_OFFS 23 +#define MVEBU_CS_MMAP_START_ADDR_LOW_MASK \ + (0x1ff << MVEBU_CS_MMAP_START_ADDR_LOW_OFFS) + +#define MVEBU_CS_MMAP_HIGH(cs_num) \ + (MVEBU_CS_MMAP_REG_BASE + 0x4 + (cs_num) * 0x8) + +/* DRAM max CS number */ +#define MVEBU_MAX_CS_MMAP_NUM (2) + +/* CPU decoder window related constants */ +#define CPU_DEC_WIN_CTRL_REG(win_num) \ + (MVEBU_CPU_DEC_WIN_REG_BASE + (win_num) * 0x10) +#define CPU_DEC_CR_WIN_ENABLE 0x1 +#define CPU_DEC_CR_WIN_TARGET_OFFS 4 +#define CPU_DEC_CR_WIN_TARGET_MASK \ + (0xf << CPU_DEC_CR_WIN_TARGET_OFFS) + +#define CPU_DEC_WIN_SIZE_REG(win_num) \ + (MVEBU_CPU_DEC_WIN_REG_BASE + 0x4 + (win_num) * 0x10) +#define CPU_DEC_CR_WIN_SIZE_OFFS 0 +#define CPU_DEC_CR_WIN_SIZE_MASK \ + (0xffff << CPU_DEC_CR_WIN_SIZE_OFFS) +#define CPU_DEC_CR_WIN_SIZE_ALIGNMENT 0x10000 + +#define CPU_DEC_WIN_BASE_REG(win_num) \ + (MVEBU_CPU_DEC_WIN_REG_BASE + 0x8 + (win_num) * 0x10) +#define CPU_DEC_BR_BASE_OFFS 0 +#define CPU_DEC_BR_BASE_MASK \ + (0xffff << CPU_DEC_BR_BASE_OFFS) + +#define CPU_DEC_REMAP_LOW_REG(win_num) \ + (MVEBU_CPU_DEC_WIN_REG_BASE + 0xC + (win_num) * 0x10) +#define CPU_DEC_RLR_REMAP_LOW_OFFS 0 +#define CPU_DEC_RLR_REMAP_LOW_MASK \ + (0xffff << CPU_DEC_BR_BASE_OFFS) + +/* Securities */ +#define IRQ_SEC_OS_TICK_INT MARVELL_IRQ_SEC_PHY_TIMER + +#define TRUSTED_DRAM_BASE PLAT_MARVELL_TRUSTED_DRAM_BASE +#define TRUSTED_DRAM_SIZE PLAT_MARVELL_TRUSTED_DRAM_SIZE + +#ifdef BL32 +#define BL32_BASE TRUSTED_DRAM_BASE +#define BL32_LIMIT TRUSTED_DRAM_SIZE +#endif + +#endif /* PLATFORM_DEF_H */ diff --git a/plat/marvell/armada/a3k/common/io_addr_dec.c b/plat/marvell/armada/a3k/common/io_addr_dec.c new file mode 100644 index 000000000..b27633cf2 --- /dev/null +++ b/plat/marvell/armada/a3k/common/io_addr_dec.c @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2016 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include + +#include +#include + +#define MVEBU_DEC_WIN_CTRL_REG(base, win, off) (MVEBU_REGS_BASE + (base) + \ + (win) * (off)) +#define MVEBU_DEC_WIN_BASE_REG(base, win, off) (MVEBU_REGS_BASE + (base) + \ + (win) * (off) + 0x4) +#define MVEBU_DEC_WIN_REMAP_REG(base, win, off) (MVEBU_REGS_BASE + (base) + \ + (win) * (off) + 0x8) + +#define MVEBU_DEC_WIN_CTRL_SIZE_OFF (16) +#define MVEBU_DEC_WIN_ENABLE (0x1) +#define MVEBU_DEC_WIN_CTRL_ATTR_OFF (8) +#define MVEBU_DEC_WIN_CTRL_TARGET_OFF (4) +#define MVEBU_DEC_WIN_CTRL_EN_OFF (0) +#define MVEBU_DEC_WIN_BASE_OFF (16) + +#define MVEBU_WIN_BASE_SIZE_ALIGNMENT (0x10000) + +/* There are up to 14 IO unit which need address decode in Armada-3700 */ +#define IO_UNIT_NUM_MAX (14) + +#define MVEBU_MAX_ADDRSS_4GB (0x100000000ULL) + + +static void set_io_addr_dec_win(int win_id, uintptr_t base_addr, + uintptr_t win_size, + struct dec_win_config *dec_win) +{ + uint32_t ctrl = 0; + uint32_t base = 0; + + /* set size */ + ctrl = ((win_size / MVEBU_WIN_BASE_SIZE_ALIGNMENT) - 1) << + MVEBU_DEC_WIN_CTRL_SIZE_OFF; + /* set attr according to IO decode window */ + ctrl |= dec_win->win_attr << MVEBU_DEC_WIN_CTRL_ATTR_OFF; + /* set target */ + ctrl |= DRAM_CPU_DEC_TARGET_NUM << MVEBU_DEC_WIN_CTRL_TARGET_OFF; + /* set base */ + base = (base_addr / MVEBU_WIN_BASE_SIZE_ALIGNMENT) << + MVEBU_DEC_WIN_BASE_OFF; + + /* set base address*/ + mmio_write_32(MVEBU_DEC_WIN_BASE_REG(dec_win->dec_reg_base, + win_id, dec_win->win_offset), + base); + /* set remap window, some unit does not have remap window */ + if (win_id < dec_win->max_remap) + mmio_write_32(MVEBU_DEC_WIN_REMAP_REG(dec_win->dec_reg_base, + win_id, dec_win->win_offset), base); + /* set control register */ + mmio_write_32(MVEBU_DEC_WIN_CTRL_REG(dec_win->dec_reg_base, + win_id, dec_win->win_offset), ctrl); + /* enable the address decode window at last to make it effective */ + ctrl |= MVEBU_DEC_WIN_ENABLE << MVEBU_DEC_WIN_CTRL_EN_OFF; + mmio_write_32(MVEBU_DEC_WIN_CTRL_REG(dec_win->dec_reg_base, + win_id, dec_win->win_offset), ctrl); + + INFO("set_io_addr_dec %d result: ctrl(0x%x) base(0x%x)", + win_id, mmio_read_32(MVEBU_DEC_WIN_CTRL_REG(dec_win->dec_reg_base, + win_id, dec_win->win_offset)), + mmio_read_32(MVEBU_DEC_WIN_BASE_REG(dec_win->dec_reg_base, + win_id, dec_win->win_offset))); + if (win_id < dec_win->max_remap) + INFO(" remap(%x)\n", + mmio_read_32(MVEBU_DEC_WIN_REMAP_REG(dec_win->dec_reg_base, + win_id, dec_win->win_offset))); + else + INFO("\n"); +} + +/* Set io decode window */ +static int set_io_addr_dec(struct dram_win_map *win_map, + struct dec_win_config *dec_win) +{ + struct dram_win *win; + int id; + + /* disable all windows first */ + for (id = 0; id < dec_win->max_dram_win; id++) + mmio_write_32(MVEBU_DEC_WIN_CTRL_REG(dec_win->dec_reg_base, id, + dec_win->win_offset), 0); + + /* configure IO decode windows for DRAM, inheritate DRAM size, + * base and target from CPU-DRAM decode window and others + * from hard coded IO decode window settings array. + */ + if (win_map->dram_win_num > dec_win->max_dram_win) { + /* + * If cpu dram windows number exceeds the io decode windows + * max number, then fill the first io decode window + * with base(0) and size(4GB). + */ + set_io_addr_dec_win(0, 0, MVEBU_MAX_ADDRSS_4GB, dec_win); + + return 0; + } + + for (id = 0; id < win_map->dram_win_num; id++, win++) { + win = &win_map->dram_windows[id]; + set_io_addr_dec_win(id, win->base_addr, win->win_size, dec_win); + } + + return 0; +} + +/* + * init_io_addr_dec + * + * This function initializes io address decoder windows by + * cpu dram window mapping information + * + * @input: N/A + * - dram_wins_map: cpu dram windows mapping + * - io_dec_config: io address decoder windows configuration + * - io_unit_num: io address decoder unit number + * @output: N/A + * + * @return: 0 on success and others on failure + */ +int init_io_addr_dec(struct dram_win_map *dram_wins_map, + struct dec_win_config *io_dec_config, uint32_t io_unit_num) +{ + int32_t index; + struct dec_win_config *io_dec_win; + int32_t ret; + + INFO("Initializing IO address decode windows\n"); + + if (io_dec_config == NULL || io_unit_num == 0) { + ERROR("No IO address decoder windows configurations!\n"); + return -1; + } + + if (io_unit_num > IO_UNIT_NUM_MAX) { + ERROR("IO address decoder windows number %d is over max %d\n", + io_unit_num, IO_UNIT_NUM_MAX); + return -1; + } + + if (dram_wins_map == NULL) { + ERROR("No cpu dram decoder windows map!\n"); + return -1; + } + + for (index = 0; index < dram_wins_map->dram_win_num; index++) + INFO("DRAM mapping %d base(0x%lx) size(0x%lx)\n", + index, dram_wins_map->dram_windows[index].base_addr, + dram_wins_map->dram_windows[index].win_size); + + /* Set address decode window for each IO */ + for (index = 0; index < io_unit_num; index++) { + io_dec_win = io_dec_config + index; + ret = set_io_addr_dec(dram_wins_map, io_dec_win); + if (ret) { + ERROR("Failed to set IO address decode\n"); + return -1; + } + INFO("Set IO decode window successfully, base(0x%x)", + io_dec_win->dec_reg_base); + INFO(" win_attr(%x) max_dram_win(%d) max_remap(%d)", + io_dec_win->win_attr, io_dec_win->max_dram_win, + io_dec_win->max_remap); + INFO(" win_offset(%d)\n", io_dec_win->win_offset); + } + + return 0; +} diff --git a/plat/marvell/armada/a3k/common/marvell_plat_config.c b/plat/marvell/armada/a3k/common/marvell_plat_config.c new file mode 100644 index 000000000..3bf3d96bd --- /dev/null +++ b/plat/marvell/armada/a3k/common/marvell_plat_config.c @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include +#include + +struct dec_win_config io_dec_win_conf[] = { + /* dec_reg_base win_attr max_dram_win max_remap win_offset */ + {0xc000, 0x3d, 2, 0, 0x08}, /* USB */ + {0xc100, 0x3d, 3, 0, 0x10}, /* USB3 */ + {0xc200, 0x3d, 2, 0, 0x10}, /* DMA */ + {0xc300, 0x3d, 2, 0, 0x10}, /* NETA0 */ + {0xc400, 0x3d, 2, 0, 0x10}, /* NETA1 */ + {0xc500, 0x3d, 2, 0, 0x10}, /* PCIe */ + {0xc800, 0x3d, 3, 0, 0x10}, /* SATA */ + {0xca00, 0x3d, 3, 0, 0x08}, /* SD */ + {0xcb00, 0x3d, 3, 0, 0x10}, /* eMMC */ + {0xce00, 0x3d, 2, 0, 0x08}, /* EIP97 */ +}; + +int marvell_get_io_dec_win_conf(struct dec_win_config **win, uint32_t *size) +{ + *win = io_dec_win_conf; + *size = sizeof(io_dec_win_conf)/sizeof(struct dec_win_config); + + return 0; +} + diff --git a/plat/marvell/armada/a3k/common/plat_pm.c b/plat/marvell/armada/a3k/common/plat_pm.c new file mode 100644 index 000000000..f8ce6fe29 --- /dev/null +++ b/plat/marvell/armada/a3k/common/plat_pm.c @@ -0,0 +1,807 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#ifdef USE_CCI +#include +#endif +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Warm reset register */ +#define MVEBU_WARM_RESET_REG (MVEBU_NB_REGS_BASE + 0x840) +#define MVEBU_WARM_RESET_MAGIC 0x1D1E + +/* North Bridge GPIO1 SEL register */ +#define MVEBU_NB_GPIO1_SEL_REG (MVEBU_NB_REGS_BASE + 0x830) + #define MVEBU_NB_GPIO1_UART1_SEL BIT(19) + #define MVEBU_NB_GPIO1_GPIO_25_26_EN BIT(17) + #define MVEBU_NB_GPIO1_GPIO_19_EN BIT(14) + #define MVEBU_NB_GPIO1_GPIO_18_EN BIT(13) + +/* CPU 1 reset register */ +#define MVEBU_CPU_1_RESET_VECTOR (MVEBU_REGS_BASE + 0x14044) +#define MVEBU_CPU_1_RESET_REG (MVEBU_REGS_BASE + 0xD00C) +#define MVEBU_CPU_1_RESET_BIT 31 + +/* IRQ register */ +#define MVEBU_NB_IRQ_STATUS_1_REG (MVEBU_NB_SB_IRQ_REG_BASE) +#define MVEBU_NB_IRQ_STATUS_2_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ + 0x10) +#define MVEBU_NB_IRQ_MASK_2_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ + 0x18) +#define MVEBU_SB_IRQ_STATUS_1_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ + 0x40) +#define MVEBU_SB_IRQ_STATUS_2_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ + 0x50) +#define MVEBU_NB_GPIO_IRQ_MASK_1_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ + 0xC8) +#define MVEBU_NB_GPIO_IRQ_MASK_2_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ + 0xD8) +#define MVEBU_SB_GPIO_IRQ_MASK_REG (MVEBU_NB_SB_IRQ_REG_BASE + \ + 0xE8) +#define MVEBU_NB_GPIO_IRQ_EN_LOW_REG (MVEBU_NB_GPIO_IRQ_REG_BASE) +#define MVEBU_NB_GPIO_IRQ_EN_HIGH_REG (MVEBU_NB_GPIO_IRQ_REG_BASE + \ + 0x04) +#define MVEBU_NB_GPIO_IRQ_STATUS_LOW_REG (MVEBU_NB_GPIO_IRQ_REG_BASE + \ + 0x10) +#define MVEBU_NB_GPIO_IRQ_STATUS_HIGH_REG (MVEBU_NB_GPIO_IRQ_REG_BASE + \ + 0x14) +#define MVEBU_NB_GPIO_IRQ_WK_LOW_REG (MVEBU_NB_GPIO_IRQ_REG_BASE + \ + 0x18) +#define MVEBU_NB_GPIO_IRQ_WK_HIGH_REG (MVEBU_NB_GPIO_IRQ_REG_BASE + \ + 0x1C) +#define MVEBU_SB_GPIO_IRQ_EN_REG (MVEBU_SB_GPIO_IRQ_REG_BASE) +#define MVEBU_SB_GPIO_IRQ_STATUS_REG (MVEBU_SB_GPIO_IRQ_REG_BASE + \ + 0x10) +#define MVEBU_SB_GPIO_IRQ_WK_REG (MVEBU_SB_GPIO_IRQ_REG_BASE + \ + 0x18) + +/* PMU registers */ +#define MVEBU_PM_NB_PWR_CTRL_REG (MVEBU_PMSU_REG_BASE) + #define MVEBU_PM_PWR_DN_CNT_SEL BIT(28) + #define MVEBU_PM_SB_PWR_DWN BIT(4) + #define MVEBU_PM_INTERFACE_IDLE BIT(0) +#define MVEBU_PM_NB_CPU_PWR_CTRL_REG (MVEBU_PMSU_REG_BASE + 0x4) + #define MVEBU_PM_L2_FLUSH_EN BIT(22) +#define MVEBU_PM_NB_PWR_OPTION_REG (MVEBU_PMSU_REG_BASE + 0x8) + #define MVEBU_PM_DDR_SR_EN BIT(29) + #define MVEBU_PM_DDR_CLK_DIS_EN BIT(28) + #define MVEBU_PM_WARM_RESET_EN BIT(27) + #define MVEBU_PM_DDRPHY_PWRDWN_EN BIT(23) + #define MVEBU_PM_DDRPHY_PAD_PWRDWN_EN BIT(22) + #define MVEBU_PM_OSC_OFF_EN BIT(21) + #define MVEBU_PM_TBG_OFF_EN BIT(20) + #define MVEBU_PM_CPU_VDDV_OFF_EN BIT(19) + #define MVEBU_PM_AVS_DISABLE_MODE BIT(14) + #define MVEBU_PM_AVS_VDD2_MODE BIT(13) + #define MVEBU_PM_AVS_HOLD_MODE BIT(12) + #define MVEBU_PM_L2_SRAM_LKG_PD_EN BIT(8) + #define MVEBU_PM_EIP_SRAM_LKG_PD_EN BIT(7) + #define MVEBU_PM_DDRMC_SRAM_LKG_PD_EN BIT(6) + #define MVEBU_PM_MCI_SRAM_LKG_PD_EN BIT(5) + #define MVEBU_PM_MMC_SRAM_LKG_PD_EN BIT(4) + #define MVEBU_PM_SATA_SRAM_LKG_PD_EN BIT(3) + #define MVEBU_PM_DMA_SRAM_LKG_PD_EN BIT(2) + #define MVEBU_PM_SEC_SRAM_LKG_PD_EN BIT(1) + #define MVEBU_PM_CPU_SRAM_LKG_PD_EN BIT(0) + #define MVEBU_PM_NB_SRAM_LKG_PD_EN (MVEBU_PM_L2_SRAM_LKG_PD_EN |\ + MVEBU_PM_EIP_SRAM_LKG_PD_EN | MVEBU_PM_DDRMC_SRAM_LKG_PD_EN |\ + MVEBU_PM_MCI_SRAM_LKG_PD_EN | MVEBU_PM_MMC_SRAM_LKG_PD_EN |\ + MVEBU_PM_SATA_SRAM_LKG_PD_EN | MVEBU_PM_DMA_SRAM_LKG_PD_EN |\ + MVEBU_PM_SEC_SRAM_LKG_PD_EN | MVEBU_PM_CPU_SRAM_LKG_PD_EN) +#define MVEBU_PM_NB_PWR_DEBUG_REG (MVEBU_PMSU_REG_BASE + 0xC) + #define MVEBU_PM_NB_FORCE_CLK_ON BIT(30) + #define MVEBU_PM_IGNORE_CM3_SLEEP BIT(21) + #define MVEBU_PM_IGNORE_CM3_DEEP BIT(20) +#define MVEBU_PM_NB_WAKE_UP_EN_REG (MVEBU_PMSU_REG_BASE + 0x2C) + #define MVEBU_PM_SB_WKP_NB_EN BIT(31) + #define MVEBU_PM_NB_GPIO_WKP_EN BIT(27) + #define MVEBU_PM_SOC_TIMER_WKP_EN BIT(26) + #define MVEBU_PM_UART_WKP_EN BIT(25) + #define MVEBU_PM_UART2_WKP_EN BIT(19) + #define MVEBU_PM_CPU_TIMER_WKP_EN BIT(17) + #define MVEBU_PM_NB_WKP_EN BIT(16) + #define MVEBU_PM_CORE1_FIQ_IRQ_WKP_EN BIT(13) + #define MVEBU_PM_CORE0_FIQ_IRQ_WKP_EN BIT(12) +#define MVEBU_PM_CPU_0_PWR_CTRL_REG (MVEBU_PMSU_REG_BASE + 0x34) +#define MVEBU_PM_CPU_1_PWR_CTRL_REG (MVEBU_PMSU_REG_BASE + 0x38) + #define MVEBU_PM_CORE_SOC_PD BIT(2) + #define MVEBU_PM_CORE_PROC_PD BIT(1) + #define MVEBU_PM_CORE_PD BIT(0) +#define MVEBU_PM_CORE_1_RETURN_ADDR_REG (MVEBU_PMSU_REG_BASE + 0x44) +#define MVEBU_PM_CPU_VDD_OFF_INFO_1_REG (MVEBU_PMSU_REG_BASE + 0x48) +#define MVEBU_PM_CPU_VDD_OFF_INFO_2_REG (MVEBU_PMSU_REG_BASE + 0x4C) + #define MVEBU_PM_LOW_POWER_STATE BIT(0) +#define MVEBU_PM_CPU_WAKE_UP_CONF_REG (MVEBU_PMSU_REG_BASE + 0x54) + #define MVEBU_PM_CORE1_WAKEUP BIT(13) + #define MVEBU_PM_CORE0_WAKEUP BIT(12) +#define MVEBU_PM_WAIT_DDR_RDY_VALUE (0x15) +#define MVEBU_PM_SB_CPU_PWR_CTRL_REG (MVEBU_SB_WAKEUP_REG_BASE) + #define MVEBU_PM_SB_PM_START BIT(0) +#define MVEBU_PM_SB_PWR_OPTION_REG (MVEBU_SB_WAKEUP_REG_BASE + 0x4) + #define MVEBU_PM_SDIO_PHY_PDWN_EN BIT(17) + #define MVEBU_PM_SB_VDDV_OFF_EN BIT(16) + #define MVEBU_PM_EBM_SRAM_LKG_PD_EN BIT(11) + #define MVEBU_PM_PCIE_SRAM_LKG_PD_EN BIT(10) + #define MVEBU_PM_GBE1_TX_SRAM_LKG_PD_EN BIT(9) + #define MVEBU_PM_GBE1_RX_SRAM_LKG_PD_EN BIT(8) + #define MVEBU_PM_GBE1_MIB_SRAM_LKG_PD_EN BIT(7) + #define MVEBU_PM_GBE0_TX_SRAM_LKG_PD_EN BIT(6) + #define MVEBU_PM_GBE0_RX_SRAM_LKG_PD_EN BIT(5) + #define MVEBU_PM_GBE0_MIB_SRAM_LKG_PD_EN BIT(4) + #define MVEBU_PM_SDIO_SRAM_LKG_PD_EN BIT(3) + #define MVEBU_PM_USB2_SRAM_LKG_PD_EN BIT(2) + #define MVEBU_PM_USB3_H_SRAM_LKG_PD_EN BIT(1) + #define MVEBU_PM_SB_SRAM_LKG_PD_EN (MVEBU_PM_EBM_SRAM_LKG_PD_EN |\ + MVEBU_PM_PCIE_SRAM_LKG_PD_EN | MVEBU_PM_GBE1_TX_SRAM_LKG_PD_EN |\ + MVEBU_PM_GBE1_RX_SRAM_LKG_PD_EN | MVEBU_PM_GBE1_MIB_SRAM_LKG_PD_EN |\ + MVEBU_PM_GBE0_TX_SRAM_LKG_PD_EN | MVEBU_PM_GBE0_RX_SRAM_LKG_PD_EN |\ + MVEBU_PM_GBE0_MIB_SRAM_LKG_PD_EN | MVEBU_PM_SDIO_SRAM_LKG_PD_EN |\ + MVEBU_PM_USB2_SRAM_LKG_PD_EN | MVEBU_PM_USB3_H_SRAM_LKG_PD_EN) +#define MVEBU_PM_SB_WK_EN_REG (MVEBU_SB_WAKEUP_REG_BASE + 0x10) + #define MVEBU_PM_SB_GPIO_WKP_EN BIT(24) + #define MVEBU_PM_SB_WKP_EN BIT(20) + +/* DRAM registers */ +#define MVEBU_DRAM_STATS_CH0_REG (MVEBU_DRAM_REG_BASE + 0x4) + #define MVEBU_DRAM_WCP_EMPTY BIT(19) +#define MVEBU_DRAM_CMD_0_REG (MVEBU_DRAM_REG_BASE + 0x20) + #define MVEBU_DRAM_CH0_CMD0 BIT(28) + #define MVEBU_DRAM_CS_CMD0 BIT(24) + #define MVEBU_DRAM_WCB_DRAIN_REQ BIT(1) +#define MVEBU_DRAM_PWR_CTRL_REG (MVEBU_DRAM_REG_BASE + 0x54) + #define MVEBU_DRAM_PHY_CLK_GATING_EN BIT(1) + #define MVEBU_DRAM_PHY_AUTO_AC_OFF_EN BIT(0) + +/* AVS registers */ +#define MVEBU_AVS_CTRL_2_REG (MVEBU_AVS_REG_BASE + 0x8) + #define MVEBU_LOW_VDD_MODE_EN BIT(6) + +/* Clock registers */ +#define MVEBU_NB_CLOCK_SEL_REG (MVEBU_NB_REGS_BASE + 0x10) + #define MVEBU_A53_CPU_CLK_SEL BIT(15) + +/* North Bridge Step-Down Registers */ +#define MVEBU_NB_STEP_DOWN_INT_EN_REG MVEBU_NB_STEP_DOWN_REG_BASE + #define MVEBU_NB_GPIO_INT_WAKE_WCPU_CLK BIT(8) + +#define MVEBU_NB_GPIO_18 18 +#define MVEBU_NB_GPIO_19 19 +#define MVEBU_NB_GPIO_25 25 +#define MVEBU_NB_GPIO_26 26 + +typedef int (*wake_up_src_func)(union pm_wake_up_src_data *); + +struct wake_up_src_func_map { + enum pm_wake_up_src_type type; + wake_up_src_func func; +}; + +void marvell_psci_arch_init(int die_index) +{ +} + +static void a3700_pm_ack_irq(void) +{ + uint32_t reg; + + reg = mmio_read_32(MVEBU_NB_IRQ_STATUS_1_REG); + if (reg) + mmio_write_32(MVEBU_NB_IRQ_STATUS_1_REG, reg); + + reg = mmio_read_32(MVEBU_NB_IRQ_STATUS_2_REG); + if (reg) + mmio_write_32(MVEBU_NB_IRQ_STATUS_2_REG, reg); + + reg = mmio_read_32(MVEBU_SB_IRQ_STATUS_1_REG); + if (reg) + mmio_write_32(MVEBU_SB_IRQ_STATUS_1_REG, reg); + + reg = mmio_read_32(MVEBU_SB_IRQ_STATUS_2_REG); + if (reg) + mmio_write_32(MVEBU_SB_IRQ_STATUS_2_REG, reg); + + reg = mmio_read_32(MVEBU_NB_GPIO_IRQ_STATUS_LOW_REG); + if (reg) + mmio_write_32(MVEBU_NB_GPIO_IRQ_STATUS_LOW_REG, reg); + + reg = mmio_read_32(MVEBU_NB_GPIO_IRQ_STATUS_HIGH_REG); + if (reg) + mmio_write_32(MVEBU_NB_GPIO_IRQ_STATUS_HIGH_REG, reg); + + reg = mmio_read_32(MVEBU_SB_GPIO_IRQ_STATUS_REG); + if (reg) + mmio_write_32(MVEBU_SB_GPIO_IRQ_STATUS_REG, reg); +} + +/***************************************************************************** + * A3700 handler called to check the validity of the power state + * parameter. + ***************************************************************************** + */ +int a3700_validate_power_state(unsigned int power_state, + psci_power_state_t *req_state) +{ + ERROR("%s needs to be implemented\n", __func__); + panic(); +} + +/***************************************************************************** + * A3700 handler called when a CPU is about to enter standby. + ***************************************************************************** + */ +void a3700_cpu_standby(plat_local_state_t cpu_state) +{ + ERROR("%s needs to be implemented\n", __func__); + panic(); +} + +/***************************************************************************** + * A3700 handler called when a power domain is about to be turned on. The + * mpidr determines the CPU to be turned on. + ***************************************************************************** + */ +int a3700_pwr_domain_on(u_register_t mpidr) +{ + /* Set barrier */ + dsbsy(); + + /* Set the cpu start address to BL1 entry point */ + mmio_write_32(MVEBU_CPU_1_RESET_VECTOR, + PLAT_MARVELL_CPU_ENTRY_ADDR >> 2); + + /* Get the cpu out of reset */ + mmio_clrbits_32(MVEBU_CPU_1_RESET_REG, BIT(MVEBU_CPU_1_RESET_BIT)); + mmio_setbits_32(MVEBU_CPU_1_RESET_REG, BIT(MVEBU_CPU_1_RESET_BIT)); + + return 0; +} + +/***************************************************************************** + * A3700 handler called to validate the entry point. + ***************************************************************************** + */ +int a3700_validate_ns_entrypoint(uintptr_t entrypoint) +{ + return PSCI_E_SUCCESS; +} + +/***************************************************************************** + * A3700 handler called when a power domain is about to be turned off. The + * target_state encodes the power state that each level should transition to. + ***************************************************************************** + */ +void a3700_pwr_domain_off(const psci_power_state_t *target_state) +{ + /* Prevent interrupts from spuriously waking up this cpu */ + plat_marvell_gic_cpuif_disable(); + + /* Core can not be powered down with pending IRQ, + * acknowledge all the pending IRQ + */ + a3700_pm_ack_irq(); +} + +static void a3700_set_gen_pwr_off_option(void) +{ + /* Enable L2 flush -> processor state-machine option */ + mmio_setbits_32(MVEBU_PM_NB_CPU_PWR_CTRL_REG, MVEBU_PM_L2_FLUSH_EN); + + /* + * North bridge cannot be VDD off (always ON). + * The NB state machine support low power mode by its state machine. + * This bit MUST be set for north bridge power down, e.g., + * OSC input cutoff(NOT TEST), SRAM power down, PMIC, etc. + * It is not related to CPU VDD OFF!! + */ + mmio_clrbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_CPU_VDDV_OFF_EN); + + /* + * MUST: Switch CPU/AXI clock to OSC + * NB state machine clock is always connected to OSC (slow clock). + * But Core0/1/processor state machine's clock are connected to AXI + * clock. Now, AXI clock takes the TBG as clock source. + * If using AXI clock, Core0/1/processor state machine may much faster + * than NB state machine. It will cause problem in this case if cores + * are released before north bridge gets ready. + */ + mmio_clrbits_32(MVEBU_NB_CLOCK_SEL_REG, MVEBU_A53_CPU_CLK_SEL); + + /* + * These register bits will trigger north bridge + * power-down state machine regardless CM3 status. + */ + mmio_setbits_32(MVEBU_PM_NB_PWR_DEBUG_REG, MVEBU_PM_IGNORE_CM3_SLEEP); + mmio_setbits_32(MVEBU_PM_NB_PWR_DEBUG_REG, MVEBU_PM_IGNORE_CM3_DEEP); + + /* + * SRAM => controlled by north bridge state machine. + * Core VDD OFF is not related to CPU SRAM power down. + */ + mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_NB_SRAM_LKG_PD_EN); + + /* + * Idle AXI interface in order to get L2_WFI + * L2 WFI is only asserted after CORE-0 and CORE-1 WFI asserted. + * (only both core-0/1in WFI, L2 WFI will be issued by CORE.) + * Once L2 WFI asserted, this bit is used for signalling assertion + * to AXI IO masters. + */ + mmio_setbits_32(MVEBU_PM_NB_PWR_CTRL_REG, MVEBU_PM_INTERFACE_IDLE); + + /* Enable core0 and core1 VDD_OFF */ + mmio_setbits_32(MVEBU_PM_CPU_0_PWR_CTRL_REG, MVEBU_PM_CORE_PD); + mmio_setbits_32(MVEBU_PM_CPU_1_PWR_CTRL_REG, MVEBU_PM_CORE_PD); + + /* Enable North bridge power down - + * Both Cores MUST enable this bit to power down north bridge! + */ + mmio_setbits_32(MVEBU_PM_CPU_0_PWR_CTRL_REG, MVEBU_PM_CORE_SOC_PD); + mmio_setbits_32(MVEBU_PM_CPU_1_PWR_CTRL_REG, MVEBU_PM_CORE_SOC_PD); + + /* CA53 (processor domain) power down */ + mmio_setbits_32(MVEBU_PM_CPU_0_PWR_CTRL_REG, MVEBU_PM_CORE_PROC_PD); + mmio_setbits_32(MVEBU_PM_CPU_1_PWR_CTRL_REG, MVEBU_PM_CORE_PROC_PD); +} + +static void a3700_en_ddr_self_refresh(void) +{ + /* + * Both count is 16 bits and configurable. By default, osc stb cnt + * is 0xFFF for lower 12 bits. + * Thus, powerdown count is smaller than osc count. + * This count is used for exiting DDR SR mode on wakeup event. + * The powerdown count also has impact on the following + * state changes: idle -> count-down -> ... (power-down, vdd off, etc) + * Here, make stable counter shorter + * Use power down count value instead of osc_stb_cnt to speed up + * DDR self refresh exit + */ + mmio_setbits_32(MVEBU_PM_NB_PWR_CTRL_REG, MVEBU_PM_PWR_DN_CNT_SEL); + + /* + * Enable DDR SR mode => controlled by north bridge state machine + * Therefore, we must powerdown north bridge to trigger the DDR SR + * mode switching. + */ + mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_DDR_SR_EN); + /* Disable DDR clock, otherwise DDR will not enter into SR mode. */ + mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_DDR_CLK_DIS_EN); + /* Power down DDR PHY (PAD) */ + mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_DDRPHY_PWRDWN_EN); + mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, + MVEBU_PM_DDRPHY_PAD_PWRDWN_EN); + + /* Set wait time for DDR ready in ROM code */ + mmio_write_32(MVEBU_PM_CPU_VDD_OFF_INFO_1_REG, + MVEBU_PM_WAIT_DDR_RDY_VALUE); + + /* DDR flush write buffer - mandatory */ + mmio_write_32(MVEBU_DRAM_CMD_0_REG, MVEBU_DRAM_CH0_CMD0 | + MVEBU_DRAM_CS_CMD0 | MVEBU_DRAM_WCB_DRAIN_REQ); + while ((mmio_read_32(MVEBU_DRAM_STATS_CH0_REG) & + MVEBU_DRAM_WCP_EMPTY) != MVEBU_DRAM_WCP_EMPTY) + ; + + /* Trigger PHY reset after ddr out of self refresh => + * supply reset pulse for DDR phy after wake up + */ + mmio_setbits_32(MVEBU_DRAM_PWR_CTRL_REG, MVEBU_DRAM_PHY_CLK_GATING_EN | + MVEBU_DRAM_PHY_AUTO_AC_OFF_EN); +} + +static void a3700_pwr_dn_avs(void) +{ + /* + * AVS power down - controlled by north bridge statemachine + * Enable AVS power down by clear the AVS disable bit. + */ + mmio_clrbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_AVS_DISABLE_MODE); + /* + * Should set BIT[12:13] to powerdown AVS. + * 1. Enable AVS VDD2 mode + * 2. After power down AVS, we must hold AVS output voltage. + * 3. We can choose the lower VDD for AVS power down. + */ + mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_AVS_VDD2_MODE); + mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_AVS_HOLD_MODE); + + /* Enable low VDD mode, AVS will set CPU to lowest core VDD 747mV */ + mmio_setbits_32(MVEBU_AVS_CTRL_2_REG, MVEBU_LOW_VDD_MODE_EN); +} + +static void a3700_pwr_dn_tbg(void) +{ + /* Power down TBG */ + mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_TBG_OFF_EN); +} + +static void a3700_pwr_dn_sb(void) +{ + /* Enable south bridge power down option */ + mmio_setbits_32(MVEBU_PM_NB_PWR_CTRL_REG, MVEBU_PM_SB_PWR_DWN); + + /* Enable SDIO_PHY_PWRDWN */ + mmio_setbits_32(MVEBU_PM_SB_PWR_OPTION_REG, MVEBU_PM_SDIO_PHY_PDWN_EN); + + /* Enable SRAM LRM on SB */ + mmio_setbits_32(MVEBU_PM_SB_PWR_OPTION_REG, MVEBU_PM_SB_SRAM_LKG_PD_EN); + + /* Enable SB Power Off */ + mmio_setbits_32(MVEBU_PM_SB_PWR_OPTION_REG, MVEBU_PM_SB_VDDV_OFF_EN); + + /* Kick off South Bridge Power Off */ + mmio_setbits_32(MVEBU_PM_SB_CPU_PWR_CTRL_REG, MVEBU_PM_SB_PM_START); +} + +static void a3700_set_pwr_off_option(void) +{ + /* Set general power off option */ + a3700_set_gen_pwr_off_option(); + + /* Enable DDR self refresh in low power mode */ + a3700_en_ddr_self_refresh(); + + /* Power down AVS */ + a3700_pwr_dn_avs(); + + /* Power down TBG */ + a3700_pwr_dn_tbg(); + + /* Power down south bridge, pay attention south bridge setting + * should be done before + */ + a3700_pwr_dn_sb(); +} + +static void a3700_set_wake_up_option(void) +{ + /* + * Enable the wakeup event for NB SOC => north-bridge + * state-machine enablement on wake-up event + */ + mmio_setbits_32(MVEBU_PM_NB_WAKE_UP_EN_REG, MVEBU_PM_NB_WKP_EN); + + /* Enable both core0 and core1 wakeup on demand */ + mmio_setbits_32(MVEBU_PM_CPU_WAKE_UP_CONF_REG, + MVEBU_PM_CORE1_WAKEUP | MVEBU_PM_CORE0_WAKEUP); + + /* Enable warm reset in low power mode */ + mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_WARM_RESET_EN); +} + +static void a3700_pm_en_nb_gpio(uint32_t gpio) +{ + /* For GPIO1 interrupt -- North bridge only */ + if (gpio >= 32) { + /* GPIO int mask */ + mmio_clrbits_32(MVEBU_NB_GPIO_IRQ_MASK_2_REG, BIT(gpio - 32)); + + /* NB_CPU_WAKE-up ENABLE GPIO int */ + mmio_setbits_32(MVEBU_NB_GPIO_IRQ_EN_HIGH_REG, BIT(gpio - 32)); + } else { + /* GPIO int mask */ + mmio_clrbits_32(MVEBU_NB_GPIO_IRQ_MASK_1_REG, BIT(gpio)); + + /* NB_CPU_WAKE-up ENABLE GPIO int */ + mmio_setbits_32(MVEBU_NB_GPIO_IRQ_EN_LOW_REG, BIT(gpio)); + } + + mmio_setbits_32(MVEBU_NB_STEP_DOWN_INT_EN_REG, + MVEBU_NB_GPIO_INT_WAKE_WCPU_CLK); + + /* Enable using GPIO as wakeup event + * (actually not only for north bridge) + */ + mmio_setbits_32(MVEBU_PM_NB_WAKE_UP_EN_REG, MVEBU_PM_NB_GPIO_WKP_EN | + MVEBU_PM_NB_WKP_EN | MVEBU_PM_CORE1_FIQ_IRQ_WKP_EN | + MVEBU_PM_CORE0_FIQ_IRQ_WKP_EN); +} + +static void a3700_pm_en_sb_gpio(uint32_t gpio) +{ + /* Enable using GPIO as wakeup event */ + mmio_setbits_32(MVEBU_PM_NB_WAKE_UP_EN_REG, MVEBU_PM_SB_WKP_NB_EN | + MVEBU_PM_NB_WKP_EN | MVEBU_PM_CORE1_FIQ_IRQ_WKP_EN | + MVEBU_PM_CORE0_FIQ_IRQ_WKP_EN); + + /* SB GPIO Wake UP | South Bridge Wake Up Enable */ + mmio_setbits_32(MVEBU_PM_SB_WK_EN_REG, MVEBU_PM_SB_GPIO_WKP_EN | + MVEBU_PM_SB_GPIO_WKP_EN); + + /* GPIO int mask */ + mmio_clrbits_32(MVEBU_SB_GPIO_IRQ_MASK_REG, BIT(gpio)); + + /* NB_CPU_WAKE-up ENABLE GPIO int */ + mmio_setbits_32(MVEBU_SB_GPIO_IRQ_EN_REG, BIT(gpio)); +} + +int a3700_pm_src_gpio(union pm_wake_up_src_data *src_data) +{ + if (src_data->gpio_data.bank_num == 0) + /* North Bridge GPIO */ + a3700_pm_en_nb_gpio(src_data->gpio_data.gpio_num); + else + a3700_pm_en_sb_gpio(src_data->gpio_data.gpio_num); + return 0; +} + +int a3700_pm_src_uart1(union pm_wake_up_src_data *src_data) +{ + /* Clear Uart1 select */ + mmio_clrbits_32(MVEBU_NB_GPIO1_SEL_REG, MVEBU_NB_GPIO1_UART1_SEL); + /* set pin 19 gpio usage*/ + mmio_setbits_32(MVEBU_NB_GPIO1_SEL_REG, MVEBU_NB_GPIO1_GPIO_19_EN); + /* Enable gpio wake-up*/ + a3700_pm_en_nb_gpio(MVEBU_NB_GPIO_19); + /* set pin 18 gpio usage*/ + mmio_setbits_32(MVEBU_NB_GPIO1_SEL_REG, MVEBU_NB_GPIO1_GPIO_18_EN); + /* Enable gpio wake-up*/ + a3700_pm_en_nb_gpio(MVEBU_NB_GPIO_18); + + return 0; +} + +int a3700_pm_src_uart0(union pm_wake_up_src_data *src_data) +{ + /* set pin 25/26 gpio usage*/ + mmio_setbits_32(MVEBU_NB_GPIO1_SEL_REG, MVEBU_NB_GPIO1_GPIO_25_26_EN); + /* Enable gpio wake-up*/ + a3700_pm_en_nb_gpio(MVEBU_NB_GPIO_25); + /* Enable gpio wake-up*/ + a3700_pm_en_nb_gpio(MVEBU_NB_GPIO_26); + + return 0; +} + +struct wake_up_src_func_map src_func_table[WAKE_UP_SRC_MAX] = { + {WAKE_UP_SRC_GPIO, a3700_pm_src_gpio}, + {WAKE_UP_SRC_UART1, a3700_pm_src_uart1}, + {WAKE_UP_SRC_UART0, a3700_pm_src_uart0}, + /* FOLLOWING SRC NOT SUPPORTED YET */ + {WAKE_UP_SRC_TIMER, NULL} +}; + +static wake_up_src_func a3700_get_wake_up_src_func( + enum pm_wake_up_src_type type) +{ + uint32_t loop; + + for (loop = 0; loop < WAKE_UP_SRC_MAX; loop++) { + if (src_func_table[loop].type == type) + return src_func_table[loop].func; + } + return NULL; +} + +static void a3700_set_wake_up_source(void) +{ + struct pm_wake_up_src_config *wake_up_src; + uint32_t loop; + wake_up_src_func src_func = NULL; + + wake_up_src = mv_wake_up_src_config_get(); + for (loop = 0; loop < wake_up_src->wake_up_src_num; loop++) { + src_func = a3700_get_wake_up_src_func( + wake_up_src->wake_up_src[loop].wake_up_src_type); + if (src_func) + src_func( + &(wake_up_src->wake_up_src[loop].wake_up_data)); + } +} + +static void a3700_pm_save_lp_flag(void) +{ + /* Save the flag for enter the low power mode */ + mmio_setbits_32(MVEBU_PM_CPU_VDD_OFF_INFO_2_REG, + MVEBU_PM_LOW_POWER_STATE); +} + +static void a3700_pm_clear_lp_flag(void) +{ + /* Clear the flag for enter the low power mode */ + mmio_clrbits_32(MVEBU_PM_CPU_VDD_OFF_INFO_2_REG, + MVEBU_PM_LOW_POWER_STATE); +} + +static uint32_t a3700_pm_get_lp_flag(void) +{ + /* Get the flag for enter the low power mode */ + return mmio_read_32(MVEBU_PM_CPU_VDD_OFF_INFO_2_REG) & + MVEBU_PM_LOW_POWER_STATE; +} + +/***************************************************************************** + * A3700 handler called when a power domain is about to be suspended. The + * target_state encodes the power state that each level should transition to. + ***************************************************************************** + */ +void a3700_pwr_domain_suspend(const psci_power_state_t *target_state) +{ + /* Prevent interrupts from spuriously waking up this cpu */ + plat_marvell_gic_cpuif_disable(); + + /* Save IRQ states */ + plat_marvell_gic_irq_save(); + + /* Set wake up options */ + a3700_set_wake_up_option(); + + /* Set wake up sources */ + a3700_set_wake_up_source(); + + /* SoC can not be powered down with pending IRQ, + * acknowledge all the pending IRQ + */ + a3700_pm_ack_irq(); + + /* Set power off options */ + a3700_set_pwr_off_option(); + + /* Save the flag for enter the low power mode */ + a3700_pm_save_lp_flag(); + + isb(); +} + +/***************************************************************************** + * A3700 handler called when a power domain has just been powered on after + * being turned off earlier. The target_state encodes the low power state that + * each level has woken up from. + ***************************************************************************** + */ +void a3700_pwr_domain_on_finish(const psci_power_state_t *target_state) +{ + /* arch specific configuration */ + marvell_psci_arch_init(0); + + /* Per-CPU interrupt initialization */ + plat_marvell_gic_pcpu_init(); + plat_marvell_gic_cpuif_enable(); + + /* Restore the per-cpu IRQ state */ + if (a3700_pm_get_lp_flag()) + plat_marvell_gic_irq_pcpu_restore(); +} + +/***************************************************************************** + * A3700 handler called when a power domain has just been powered on after + * having been suspended earlier. The target_state encodes the low power state + * that each level has woken up from. + * TODO: At the moment we reuse the on finisher and reinitialize the secure + * context. Need to implement a separate suspend finisher. + ***************************************************************************** + */ +void a3700_pwr_domain_suspend_finish(const psci_power_state_t *target_state) +{ + struct dec_win_config *io_dec_map; + uint32_t dec_win_num; + struct dram_win_map dram_wins_map; + + /* arch specific configuration */ + marvell_psci_arch_init(0); + + /* Interrupt initialization */ + plat_marvell_gic_init(); + + /* Restore IRQ states */ + plat_marvell_gic_irq_restore(); + + /* + * Initialize CCI for this cluster after resume from suspend state. + * No need for locks as no other CPU is active. + */ + plat_marvell_interconnect_init(); + /* + * Enable CCI coherency for the primary CPU's cluster. + * Platform specific PSCI code will enable coherency for other + * clusters. + */ + plat_marvell_interconnect_enter_coherency(); + + /* CPU address decoder windows initialization. */ + cpu_wins_init(); + + /* fetch CPU-DRAM window mapping information by reading + * CPU-DRAM decode windows (only the enabled ones) + */ + dram_win_map_build(&dram_wins_map); + + /* Get IO address decoder windows */ + if (marvell_get_io_dec_win_conf(&io_dec_map, &dec_win_num)) { + printf("No IO address decoder windows configurations found!\n"); + return; + } + + /* IO address decoder init */ + if (init_io_addr_dec(&dram_wins_map, io_dec_map, dec_win_num)) { + printf("IO address decoder windows initialization failed!\n"); + return; + } + + /* Clear low power mode flag */ + a3700_pm_clear_lp_flag(); +} + +/***************************************************************************** + * This handler is called by the PSCI implementation during the `SYSTEM_SUSPEND + * call to get the `power_state` parameter. This allows the platform to encode + * the appropriate State-ID field within the `power_state` parameter which can + * be utilized in `pwr_domain_suspend()` to suspend to system affinity level. + ***************************************************************************** + */ +void a3700_get_sys_suspend_power_state(psci_power_state_t *req_state) +{ + /* lower affinities use PLAT_MAX_OFF_STATE */ + for (int i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++) + req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE; +} + +/***************************************************************************** + * A3700 handlers to shutdown/reboot the system + ***************************************************************************** + */ +static void __dead2 a3700_system_off(void) +{ + ERROR("%s needs to be implemented\n", __func__); + panic(); +} + +/***************************************************************************** + * A3700 handlers to reset the system + ***************************************************************************** + */ +static void __dead2 a3700_system_reset(void) +{ + /* Clean the mailbox magic number to let it as act like cold boot */ + mmio_write_32(PLAT_MARVELL_MAILBOX_BASE, 0x0); + + dsbsy(); + + /* Flush data cache if the mail box shared RAM is cached */ +#if PLAT_MARVELL_SHARED_RAM_CACHED + flush_dcache_range((uintptr_t)PLAT_MARVELL_MAILBOX_BASE, + 2 * sizeof(uint64_t)); +#endif + + /* Trigger the warm reset */ + mmio_write_32(MVEBU_WARM_RESET_REG, MVEBU_WARM_RESET_MAGIC); + + /* Shouldn't get to this point */ + panic(); +} + +/***************************************************************************** + * Export the platform handlers via plat_arm_psci_pm_ops. The ARM Standard + * platform layer will take care of registering the handlers with PSCI. + ***************************************************************************** + */ +const plat_psci_ops_t plat_arm_psci_pm_ops = { + .cpu_standby = a3700_cpu_standby, + .pwr_domain_on = a3700_pwr_domain_on, + .pwr_domain_off = a3700_pwr_domain_off, + .pwr_domain_suspend = a3700_pwr_domain_suspend, + .pwr_domain_on_finish = a3700_pwr_domain_on_finish, + .pwr_domain_suspend_finish = a3700_pwr_domain_suspend_finish, + .get_sys_suspend_power_state = a3700_get_sys_suspend_power_state, + .system_off = a3700_system_off, + .system_reset = a3700_system_reset, + .validate_power_state = a3700_validate_power_state, + .validate_ns_entrypoint = a3700_validate_ns_entrypoint +}; -- cgit v1.2.3 From a7749acc107a12ff868b30d2f8b87929eff968b4 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Tue, 2 Jun 2020 21:08:38 -0700 Subject: Tegra: memctrl_v2: fixup sequence to resize video memory The previous sequence used by the driver to program the new memory aperture settings and clear the non-overlapping memory was faulty. The sequence locked the non-overlapping regions twice, leading to faults when trying to clear it. This patch modifies the sequence to follow these steps: * move the previous memory region to a new firewall register * program the new memory aperture settings * clean the non-overlapping memory This patch also maps the non-overlapping memory as Device memory to follow guidance from the arch. team. Signed-off-by: Varun Wadekar Change-Id: I7cf6e05b2dd372103dc7229e37b1b3fc269a57ae --- .../tegra/common/drivers/memctrl/memctrl_v2.c | 89 +++++++++++----------- 1 file changed, 46 insertions(+), 43 deletions(-) diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c index 5555f5df3..4d69ccca3 100644 --- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c +++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c @@ -280,56 +280,32 @@ static void tegra_clear_videomem(uintptr_t non_overlap_area_start, { int ret; + INFO("Cleaning previous Video Memory Carveout\n"); + /* * Map the NS memory first, clean it and then unmap it. */ ret = mmap_add_dynamic_region(non_overlap_area_start, /* PA */ non_overlap_area_start, /* VA */ non_overlap_area_size, /* size */ - MT_NS | MT_RW | MT_EXECUTE_NEVER | - MT_NON_CACHEABLE); /* attrs */ + MT_DEVICE | MT_RW | MT_NS); /* attrs */ assert(ret == 0); - zero_normalmem((void *)non_overlap_area_start, non_overlap_area_size); + zeromem((void *)non_overlap_area_start, non_overlap_area_size); flush_dcache_range(non_overlap_area_start, non_overlap_area_size); - (void)mmap_remove_dynamic_region(non_overlap_area_start, + ret = mmap_remove_dynamic_region(non_overlap_area_start, non_overlap_area_size); + assert(ret == 0); } -/* - * Program the Video Memory carveout region - * - * phys_base = physical base of aperture - * size_in_bytes = size of aperture in bytes - */ -void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes) +static void tegra_clear_videomem_nonoverlap(uintptr_t phys_base, + unsigned long size_in_bytes) { uintptr_t vmem_end_old = video_mem_base + (video_mem_size_mb << 20); uintptr_t vmem_end_new = phys_base + size_in_bytes; unsigned long long non_overlap_area_size; - /* - * Setup the Memory controller to restrict CPU accesses to the Video - * Memory region - */ - INFO("Configuring Video Memory Carveout\n"); - - /* - * Configure Memory Controller directly for the first time. - */ - if (video_mem_base == 0U) - goto done; - - /* - * Lock the non overlapping memory being cleared so that other masters - * do not accidently write to it. The memory would be unlocked once - * the non overlapping region is cleared and the new memory - * settings take effect. - */ - tegra_lock_videomem_nonoverlap(video_mem_base, - video_mem_size_mb << 20); - /* * Clear the old regions now being exposed. The following cases * can occur - @@ -338,8 +314,6 @@ void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes) * 2. clear old sub-region below new base * 3. clear old sub-region above new end */ - INFO("Cleaning previous Video Memory Carveout\n"); - if ((phys_base > vmem_end_old) || (video_mem_base > vmem_end_new)) { tegra_clear_videomem(video_mem_base, video_mem_size_mb << 20U); @@ -353,26 +327,55 @@ void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes) tegra_clear_videomem(vmem_end_new, non_overlap_area_size); } } +} + +/* + * Program the Video Memory carveout region + * + * phys_base = physical base of aperture + * size_in_bytes = size of aperture in bytes + */ +void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes) +{ + /* + * Setup the Memory controller to restrict CPU accesses to the Video + * Memory region + */ + + INFO("Configuring Video Memory Carveout\n"); + + if (video_mem_base != 0U) { + /* + * Lock the non overlapping memory being cleared so that + * other masters do not accidently write to it. The memory + * would be unlocked once the non overlapping region is + * cleared and the new memory settings take effect. + */ + tegra_lock_videomem_nonoverlap(video_mem_base, + video_mem_size_mb << 20); + } -done: /* program the Videomem aperture */ tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO, (uint32_t)phys_base); tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI, (uint32_t)(phys_base >> 32)); tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, size_in_bytes >> 20); - /* unlock the previous locked nonoverlapping aperture */ - tegra_unlock_videomem_nonoverlap(); - - /* store new values */ - video_mem_base = phys_base; - video_mem_size_mb = size_in_bytes >> 20; - /* * MCE propagates the VideoMem configuration values across the * CCPLEX. */ - mce_update_gsc_videomem(); + (void)mce_update_gsc_videomem(); + + /* Clear the non-overlapping memory */ + if (video_mem_base != 0U) { + tegra_clear_videomem_nonoverlap(phys_base, size_in_bytes); + tegra_unlock_videomem_nonoverlap(); + } + + /* store new values */ + video_mem_base = phys_base; + video_mem_size_mb = (uint64_t)size_in_bytes >> 20; } /* -- cgit v1.2.3 From 5e1b83aa742efbacda3dd83a26f9fd329046a098 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Thu, 11 Jun 2020 21:53:09 -0700 Subject: Tegra: introduce support for GICv3 This patch provides the platform level support to enable GICv3 drivers on future Tegra platforms. Signed-off-by: Varun Wadekar Change-Id: I966a4502b2a4a7bd1ce66da843997c9ed605c59f --- plat/nvidia/tegra/common/tegra_common.mk | 6 +++ plat/nvidia/tegra/common/tegra_gicv3.c | 79 ++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 plat/nvidia/tegra/common/tegra_gicv3.c diff --git a/plat/nvidia/tegra/common/tegra_common.mk b/plat/nvidia/tegra/common/tegra_common.mk index a86a31535..82dd60697 100644 --- a/plat/nvidia/tegra/common/tegra_common.mk +++ b/plat/nvidia/tegra/common/tegra_common.mk @@ -14,6 +14,12 @@ PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS} COMMON_DIR := plat/nvidia/tegra/common +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk +TEGRA_GICv3_SOURCES := $(GICV3_SOURCES) \ + plat/common/plat_gicv3.c \ + ${COMMON_DIR}/tegra_gicv3.c + TEGRA_GICv2_SOURCES := drivers/arm/gic/common/gic_common.c \ drivers/arm/gic/v2/gicv2_main.c \ drivers/arm/gic/v2/gicv2_helpers.c \ diff --git a/plat/nvidia/tegra/common/tegra_gicv3.c b/plat/nvidia/tegra/common/tegra_gicv3.c new file mode 100644 index 000000000..cba2f9b95 --- /dev/null +++ b/plat/nvidia/tegra/common/tegra_gicv3.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +/* The GICv3 driver only needs to be initialized in EL3 */ +static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT]; + +static unsigned int plat_tegra_mpidr_to_core_pos(unsigned long mpidr) +{ + return (unsigned int)plat_core_pos_by_mpidr(mpidr); +} + +/****************************************************************************** + * Tegra common helper to setup the GICv3 driver data. + *****************************************************************************/ +void tegra_gic_setup(const interrupt_prop_t *interrupt_props, + unsigned int interrupt_props_num) +{ + /* + * Tegra GIC configuration settings + */ + static gicv3_driver_data_t tegra_gic_data; + + /* + * Register Tegra GICv3 driver + */ + tegra_gic_data.gicd_base = TEGRA_GICD_BASE; + tegra_gic_data.gicr_base = TEGRA_GICR_BASE; + tegra_gic_data.rdistif_num = PLATFORM_CORE_COUNT; + tegra_gic_data.rdistif_base_addrs = rdistif_base_addrs; + tegra_gic_data.mpidr_to_core_pos = plat_tegra_mpidr_to_core_pos; + tegra_gic_data.interrupt_props = interrupt_props; + tegra_gic_data.interrupt_props_num = interrupt_props_num; + gicv3_driver_init(&tegra_gic_data); + + /* initialize the GICD and GICR */ + tegra_gic_init(); +} + +/****************************************************************************** + * Tegra common helper to initialize the GICv3 only driver. + *****************************************************************************/ +void tegra_gic_init(void) +{ + gicv3_distif_init(); + gicv3_rdistif_init(plat_my_core_pos()); + gicv3_cpuif_enable(plat_my_core_pos()); +} + +/****************************************************************************** + * Tegra common helper to disable the GICv3 CPU interface + *****************************************************************************/ +void tegra_gic_cpuif_deactivate(void) +{ + gicv3_cpuif_disable(plat_my_core_pos()); +} + +/****************************************************************************** + * Tegra common helper to initialize the per cpu distributor interface + * in GICv3 + *****************************************************************************/ +void tegra_gic_pcpu_init(void) +{ + gicv3_rdistif_init(plat_my_core_pos()); + gicv3_cpuif_enable(plat_my_core_pos()); +} -- cgit v1.2.3 From 3768fecf8f70443a8d3a8b6e3b3a7aedfad84f57 Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Fri, 19 Jun 2020 14:33:49 +0100 Subject: TF-A: Add ARMv8.5 'bti' build option This patch adds BRANCH_PROTECTION = 4 'bti' build option which turns on branch target identification mechanism. Change-Id: I32464a6b51726a100519f449a95aea5331f0e82d Signed-off-by: Alexei Fedorov --- Makefile | 4 ++++ docs/getting_started/build-options.rst | 3 +++ 2 files changed, 7 insertions(+) diff --git a/Makefile b/Makefile index bc5604be2..160cd44cc 100644 --- a/Makefile +++ b/Makefile @@ -121,6 +121,10 @@ else ifeq (${BRANCH_PROTECTION},3) # Extend the signing to include leaf functions BP_OPTION := pac-ret+leaf ENABLE_PAUTH := 1 +else ifeq (${BRANCH_PROTECTION},4) + # Turn on branch target identification mechanism + BP_OPTION := bti + ENABLE_BTI := 1 else $(error Unknown BRANCH_PROTECTION value ${BRANCH_PROTECTION}) endif diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index f207886fb..81903e140 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -88,6 +88,7 @@ Common build options - 1: Enables all types of branch protection features - 2: Return address signing to its standard level - 3: Extend the signing to include leaf functions +- 4: Turn on branch target identification mechanism The table below summarizes ``BRANCH_PROTECTION`` values, GCC compilation options and resulting PAuth/BTI features. @@ -103,6 +104,8 @@ Common build options +-------+--------------+-------+-----+ | 3 | pac-ret+leaf | Y | N | +-------+--------------+-------+-----+ + | 4 | bti | N | Y | + +-------+--------------+-------+-----+ This option defaults to 0 and this is an experimental feature. Note that Pointer Authentication is enabled for Non-secure world -- cgit v1.2.3 From ed84fe88296e2ca7ed87af24bd82008d8843d3d7 Mon Sep 17 00:00:00 2001 From: Grzegorz Jaszczyk Date: Fri, 12 Apr 2019 12:56:07 +0200 Subject: plat: marvell: armada: configure amb for all CPs Before this patch the configuration took place only for CP0 and CP1, but since new platforms can contains up to 3 CPs update is required. Change-Id: Iebd50bbe7b9772063e2c4efb3a7ecbfd593e950d Signed-off-by: Grzegorz Jaszczyk --- plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c b/plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c index 09b8446fa..3b81814f9 100644 --- a/plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c +++ b/plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c @@ -75,10 +75,8 @@ static int bl2_plat_mmap_init(void) mmio_write_32(MVEBU_IO_WIN_BASE(MVEBU_AP0) + IOW_GCR_OFFSET, PIDI_TID); /* Open AMB bridge required for MG access */ - cp110_amb_init(MVEBU_CP_REGS_BASE(0)); - - if (CP_COUNT == 2) - cp110_amb_init(MVEBU_CP_REGS_BASE(1)); + for (cp = 0; cp < CP_COUNT; cp++) + cp110_amb_init(MVEBU_CP_REGS_BASE(cp)); return 0; } -- cgit v1.2.3 From 8e8ec8cff7facb5c76ebf1af09e93fa25360a621 Mon Sep 17 00:00:00 2001 From: Grzegorz Jaszczyk Date: Fri, 8 Mar 2019 19:51:21 +0100 Subject: marvell: comphy: update rx_training procedure 1) Relay only on rx training, remove parts responsible for tx training (trx training). 2) Add extra steps e.g. preconfigure FFE before starting training. 3) Remove some unnecessary steps like RRBS31 loopback setting which shouldn't be relevant for tx_training. Change-Id: Ib1e8567714f9ce33578186a262c339aa4b1c51f2 Signed-off-by: Grzegorz Jaszczyk --- drivers/marvell/comphy/comphy-cp110.h | 56 +++++++++-- drivers/marvell/comphy/phy-comphy-cp110.c | 148 ++++++++++-------------------- 2 files changed, 97 insertions(+), 107 deletions(-) diff --git a/drivers/marvell/comphy/comphy-cp110.h b/drivers/marvell/comphy/comphy-cp110.h index 6eb7fd0d2..3678c90fb 100644 --- a/drivers/marvell/comphy/comphy-cp110.h +++ b/drivers/marvell/comphy/comphy-cp110.h @@ -659,18 +659,32 @@ (0x3f << HPIPE_SAVED_DFE_VALUES_SAV_F0D_OFFSET) #define HPIPE_CDR_CONTROL_REG 0x418 -#define HPIPE_CDR_RX_MAX_DFE_ADAPT_0_OFFSET 14 -#define HPIPE_CDR_RX_MAX_DFE_ADAPT_0_MASK \ - (0x3 << HPIPE_CDR_RX_MAX_DFE_ADAPT_0_OFFSET) -#define HPIPE_CDR_RX_MAX_DFE_ADAPT_1_OFFSET 12 -#define HPIPE_CDR_RX_MAX_DFE_ADAPT_1_MASK \ - (0x3 << HPIPE_CDR_RX_MAX_DFE_ADAPT_1_OFFSET) -#define HPIPE_CDR_MAX_DFE_ADAPT_0_OFFSET 9 -#define HPIPE_CDR_MAX_DFE_ADAPT_0_MASK \ - (0x7 << HPIPE_CDR_MAX_DFE_ADAPT_0_OFFSET) +#define HPIPE_CRD_MIDPOINT_PHASE_OS_OFFSET 0 +#define HPIPE_CRD_MIDPOINT_PHASE_OS_MASK \ + (0x3f << HPIPE_CRD_MIDPOINT_PHASE_OS_OFFSET) #define HPIPE_CDR_MAX_DFE_ADAPT_1_OFFSET 6 #define HPIPE_CDR_MAX_DFE_ADAPT_1_MASK \ (0x7 << HPIPE_CDR_MAX_DFE_ADAPT_1_OFFSET) +#define HPIPE_CDR_MAX_DFE_ADAPT_0_OFFSET 9 +#define HPIPE_CDR_MAX_DFE_ADAPT_0_MASK \ + (0x7 << HPIPE_CDR_MAX_DFE_ADAPT_0_OFFSET) +#define HPIPE_CDR_RX_MAX_DFE_ADAPT_1_OFFSET 12 +#define HPIPE_CDR_RX_MAX_DFE_ADAPT_1_MASK \ + (0x3 << HPIPE_CDR_RX_MAX_DFE_ADAPT_1_OFFSET) +#define HPIPE_CDR_RX_MAX_DFE_ADAPT_0_OFFSET 14 +#define HPIPE_CDR_RX_MAX_DFE_ADAPT_0_MASK \ + (0x3 << HPIPE_CDR_RX_MAX_DFE_ADAPT_0_OFFSET) + + +#define HPIPE_CDR_CONTROL1_REG 0x41c +#define HPIPE_CRD2_CRD_MIDPOINT_SMALL_THRES_K_OFF 12 +#define HPIPE_CRD2_CRD_MIDPOINT_SMALL_THRES_K_MASK \ + (0xf << HPIPE_CRD2_CRD_MIDPOINT_SMALL_THRES_K_OFF) + +#define HPIPE_CDR_CONTROL2_REG 0x420 +#define HPIPE_CRD2_CRD_MIDPOINT_LARGE_THRES_K_OFF 12 +#define HPIPE_CRD2_CRD_MIDPOINT_LARGE_THRES_K_MASK \ + (0xf << HPIPE_CRD2_CRD_MIDPOINT_LARGE_THRES_K_OFF) #define HPIPE_TX_TRAIN_CTRL_11_REG 0x438 #define HPIPE_TX_STATUS_CHECK_MODE_OFFSET 6 @@ -749,6 +763,30 @@ #define HPIPE_DFE_CTRL_28_PIPE4_MASK \ (0x1 << HPIPE_DFE_CTRL_28_PIPE4_OFFSET) +#define HPIPE_TRX0_REG 0x4cc /*in doc 0x133*4*/ +#define HPIPE_TRX0_GAIN_TRAIN_WITH_SAMPLER_OFF 2 +#define HPIPE_TRX0_GAIN_TRAIN_WITH_SAMPLER_MASK \ + (0x1 << HPIPE_TRX0_GAIN_TRAIN_WITH_SAMPLER_OFF) +#define HPIPE_TRX0_GAIN_TRAIN_WITH_C_OFF 0 +#define HPIPE_TRX0_GAIN_TRAIN_WITH_C_MASK \ + (0x1 << HPIPE_TRX0_GAIN_TRAIN_WITH_C_OFF) + +#define HPIPE_TRX_REG1 0x4d0 /*in doc 0x134*4*/ +#define HPIPE_TRX_REG1_MIN_BOOST_MODE_OFF 3 +#define HPIPE_TRX_REG1_MIN_BOOST_MODE_MASK \ + (0x1 << HPIPE_TRX_REG1_MIN_BOOST_MODE_OFF) +#define HPIPE_TRX_REG1_SUMFTAP_EN_OFF 10 +#define HPIPE_TRX_REG1_SUMFTAP_EN_MASK \ + (0x3f << HPIPE_TRX_REG1_SUMFTAP_EN_OFF) + +#define HPIPE_TRX_REG2 0x4d8 /*in doc 0x136*4*/ +#define HPIPE_TRX_REG2_SUMF_BOOST_TARGET_C_OFF 11 +#define HPIPE_TRX_REG2_SUMF_BOOST_TARGET_C_MASK \ + (0x1f << HPIPE_TRX_REG2_SUMF_BOOST_TARGET_C_OFF) +#define HPIPE_TRX_REG2_SUMF_BOOST_TARGET_K_OFF 7 +#define HPIPE_TRX_REG2_SUMF_BOOST_TARGET_K_MASK \ + (0xf << HPIPE_TRX_REG2_SUMF_BOOST_TARGET_K_OFF) + #define HPIPE_G1_SETTING_5_REG 0x538 #define HPIPE_G1_SETTING_5_G1_ICP_OFFSET 0 #define HPIPE_G1_SETTING_5_G1_ICP_MASK \ diff --git a/drivers/marvell/comphy/phy-comphy-cp110.c b/drivers/marvell/comphy/phy-comphy-cp110.c index b68208629..3313a42cb 100644 --- a/drivers/marvell/comphy/phy-comphy-cp110.c +++ b/drivers/marvell/comphy/phy-comphy-cp110.c @@ -2012,12 +2012,58 @@ static int mvebu_cp110_comphy_usb3_power_on(uint64_t comphy_base, return ret; } +static void rx_pre_train(uint64_t comphy_base, uint8_t comphy_index) +{ + uintptr_t hpipe_addr; + uint32_t mask, data; + + hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base), + comphy_index); + + debug("rx_training preparation\n\n"); + + mask = HPIPE_TRX0_GAIN_TRAIN_WITH_C_MASK; + data = (0x1 << HPIPE_TRX0_GAIN_TRAIN_WITH_C_OFF); + mask |= HPIPE_TRX0_GAIN_TRAIN_WITH_SAMPLER_MASK; + data |= (0x0 << HPIPE_TRX0_GAIN_TRAIN_WITH_SAMPLER_OFF); + reg_set(hpipe_addr + HPIPE_TRX0_REG, data, mask); + + + mask = HPIPE_TRX_REG2_SUMF_BOOST_TARGET_C_MASK; + data = (0x1e << HPIPE_TRX_REG2_SUMF_BOOST_TARGET_C_OFF); + mask |= HPIPE_TRX_REG2_SUMF_BOOST_TARGET_K_MASK; + data |= (0x0 << HPIPE_TRX_REG2_SUMF_BOOST_TARGET_K_OFF); + reg_set(hpipe_addr + HPIPE_TRX_REG2, data, mask); + + mask = HPIPE_TRX_REG1_MIN_BOOST_MODE_MASK; + data = (0x1 << HPIPE_TRX_REG1_MIN_BOOST_MODE_OFF); + reg_set(hpipe_addr + HPIPE_TRX_REG1, data, mask); + + mask = HPIPE_CRD2_CRD_MIDPOINT_SMALL_THRES_K_MASK; + data = (0x8 << HPIPE_CRD2_CRD_MIDPOINT_SMALL_THRES_K_OFF); + reg_set(hpipe_addr + HPIPE_CDR_CONTROL1_REG, data, mask); + + mask = HPIPE_CRD2_CRD_MIDPOINT_LARGE_THRES_K_MASK; + data = (0x8 << HPIPE_CRD2_CRD_MIDPOINT_LARGE_THRES_K_OFF); + reg_set(hpipe_addr + HPIPE_CDR_CONTROL2_REG, data, mask); + + mask = HPIPE_CRD_MIDPOINT_PHASE_OS_MASK; + data = (0x0 << HPIPE_CRD_MIDPOINT_PHASE_OS_OFFSET); + reg_set(hpipe_addr + HPIPE_CDR_CONTROL_REG, data, mask); + + mask = HPIPE_TRX_REG1_SUMFTAP_EN_MASK; + data = (0x38 << HPIPE_TRX_REG1_SUMFTAP_EN_OFF); + mask |= HPIPE_TRX_REG2_SUMF_BOOST_TARGET_C_MASK; + data |= (0x1e << HPIPE_TRX_REG2_SUMF_BOOST_TARGET_C_OFF); + reg_set(hpipe_addr + HPIPE_TRX_REG1, data, mask); +} + int mvebu_cp110_comphy_xfi_rx_training(uint64_t comphy_base, uint8_t comphy_index) { uint32_t mask, data, timeout; uint32_t g1_ffe_cap_sel, g1_ffe_res_sel, align90, g1_dfe_res; - uintptr_t hpipe_addr, sd_ip_addr; + uintptr_t hpipe_addr; uint8_t ap_nr, cp_nr; @@ -2025,30 +2071,10 @@ int mvebu_cp110_comphy_xfi_rx_training(uint64_t comphy_base, hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base), comphy_index); - sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base), - comphy_index); debug_enter(); - debug("stage: RF Reset\n"); - - /* Release from hard reset */ - mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK; - data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET; - mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK; - data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET; - mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK; - data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET; - reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask); - - mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK; - data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET; - mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK; - data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET; - reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask); - - /* Wait 50ms - until band gap and ref clock ready */ - mdelay(50); + rx_pre_train(comphy_base, comphy_index); debug("Preparation for rx_training\n\n"); @@ -2068,34 +2094,10 @@ int mvebu_cp110_comphy_xfi_rx_training(uint64_t comphy_base, data = 0 << HPIPE_DFE_RES_FORCE_OFFSET; reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask); - debug("PRBS31 loppback\n\n"); - - /* Configure PRBS counters */ - mask = HPIPE_PHY_TEST_PATTERN_SEL_MASK; - data = 0xe << HPIPE_PHY_TEST_PATTERN_SEL_OFFSET; - reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask); - - mask = HPIPE_PHY_TEST_DATA_MASK; - data = 0xc4 << HPIPE_PHY_TEST_DATA_OFFSET; - reg_set(hpipe_addr + HPIPE_PHY_TEST_DATA_REG, data, mask); - - mask = HPIPE_PHY_TEST_EN_MASK; - data = 0x1 << HPIPE_PHY_TEST_EN_OFFSET; - reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask); - - mdelay(10); - debug("Enable TX/RX training\n\n"); + debug("Enable RX training\n\n"); mask = HPIPE_TRX_RX_TRAIN_EN_MASK; data = 0x1 << HPIPE_TRX_RX_TRAIN_EN_OFFSET; - mask |= HPIPE_TRX_RX_ANA_IF_CLK_ENE_MASK; - data |= 0x1 << HPIPE_TRX_RX_ANA_IF_CLK_ENE_OFFSET; - mask |= HPIPE_TRX_TX_CTRL_CLK_EN_MASK; - data |= 0x1 << HPIPE_TRX_TX_CTRL_CLK_EN_OFFSET; - mask |= HPIPE_TRX_UPDATE_THEN_HOLD_MASK; - data |= 0x1 << HPIPE_TRX_UPDATE_THEN_HOLD_OFFSET; - mask |= HPIPE_TRX_TX_F0T_EO_BASED_MASK; - data |= 0x1 << HPIPE_TRX_TX_F0T_EO_BASED_OFFSET; reg_set(hpipe_addr + HPIPE_TRX_TRAIN_CTRL_0_REG, data, mask); /* Check the result of RX training */ @@ -2180,21 +2182,9 @@ int mvebu_cp110_comphy_xfi_rx_training(uint64_t comphy_base, data = 1 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET; reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask); - /* Use the value from CAL_OS_PH_EXT */ - mask = HPIPE_CAL_RXCLKALIGN_90_EXT_EN_MASK; - data = 1 << HPIPE_CAL_RXCLKALIGN_90_EXT_EN_OFFSET; - reg_set(hpipe_addr + HPIPE_RX_CLK_ALIGN90_AND_TX_IDLE_CALIB_CTRL_REG, - data, mask); - - /* Update align90 */ - mask = HPIPE_CAL_OS_PH_EXT_MASK; - data = align90 << HPIPE_CAL_OS_PH_EXT_OFFSET; - reg_set(hpipe_addr + HPIPE_RX_CLK_ALIGN90_AND_TX_IDLE_CALIB_CTRL_REG, - data, mask); - /* Force DFE resolution (use gen table value) */ mask = HPIPE_DFE_RES_FORCE_MASK; - data = 0x0 << HPIPE_DFE_RES_FORCE_OFFSET; + data = 0x1 << HPIPE_DFE_RES_FORCE_OFFSET; reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask); /* 0x111-G1 DFE_Setting_4 */ @@ -2202,38 +2192,6 @@ int mvebu_cp110_comphy_xfi_rx_training(uint64_t comphy_base, data = g1_dfe_res << HPIPE_G1_SETTINGS_4_G1_DFE_RES_OFFSET; reg_set(hpipe_addr + HPIPE_G1_SETTINGS_4_REG, data, mask); - debug("PRBS31 loppback\n\n"); - - mask = HPIPE_PHY_TEST_PT_TESTMODE_MASK; - data = 0x1 << HPIPE_PHY_TEST_PT_TESTMODE_OFFSET; - reg_set(hpipe_addr + HPIPE_PHY_TEST_OOB_0_REGISTER, data, mask); - - /* Configure PRBS counters */ - mask = HPIPE_PHY_TEST_PATTERN_SEL_MASK; - data = 0xe << HPIPE_PHY_TEST_PATTERN_SEL_OFFSET; - reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask); - - mask = HPIPE_PHY_TEST_DATA_MASK; - data = 0xc4 << HPIPE_PHY_TEST_DATA_OFFSET; - reg_set(hpipe_addr + HPIPE_PHY_TEST_DATA_REG, data, mask); - - mask = HPIPE_PHY_TEST_EN_MASK; - data = 0x1 << HPIPE_PHY_TEST_EN_OFFSET; - reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask); - - /* Reset PRBS error counter */ - mask = HPIPE_PHY_TEST_PATTERN_SEL_MASK; - data = 0x1 << HPIPE_PHY_TEST_RESET_OFFSET; - reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask); - - mask = HPIPE_PHY_TEST_PATTERN_SEL_MASK; - data = 0x0 << HPIPE_PHY_TEST_RESET_OFFSET; - reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask); - - mask = HPIPE_PHY_TEST_PT_TESTMODE_MASK; - data = 0x1 << HPIPE_PHY_TEST_PT_TESTMODE_OFFSET; - reg_set(hpipe_addr + HPIPE_PHY_TEST_OOB_0_REGISTER, data, mask); - printf("########################################################\n"); printf("# To use trained values update the ATF sources:\n"); printf("# plat/marvell/armada/a8k//board/phy-porting-layer.h "); @@ -2252,12 +2210,6 @@ int mvebu_cp110_comphy_xfi_rx_training(uint64_t comphy_base, printf("};\n\n"); printf("########################################################\n"); - /* check */ - debug("PRBS error counter[0x%lx] 0x%x\n\n", - hpipe_addr + HPIPE_PHY_TEST_PRBS_ERROR_COUNTER_1_REG, - mmio_read_32(hpipe_addr + - HPIPE_PHY_TEST_PRBS_ERROR_COUNTER_1_REG)); - rx_trainng_done[ap_nr][cp_nr][comphy_index] = 1; return 0; -- cgit v1.2.3 From 050eb19c7e1a9115fce31cac4283bf1ef12df3d1 Mon Sep 17 00:00:00 2001 From: Grzegorz Jaszczyk Date: Thu, 28 Mar 2019 13:02:42 +0100 Subject: marvell: comphy: initialize common phy selector for AP mode Configuring common phy selector which was missing for AP mode. Change-Id: I15be1ba50b8aafe9094734abec139d72c18bb224 Signed-off-by: Grzegorz Jaszczyk --- drivers/marvell/comphy/phy-comphy-cp110.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/marvell/comphy/phy-comphy-cp110.c b/drivers/marvell/comphy/phy-comphy-cp110.c index 3313a42cb..2760f4603 100644 --- a/drivers/marvell/comphy/phy-comphy-cp110.c +++ b/drivers/marvell/comphy/phy-comphy-cp110.c @@ -209,8 +209,10 @@ static void mvebu_cp110_comphy_set_phy_selector(uint64_t comphy_base, * as SFI1/XFI1 available only for CP115. */ if ((mode == COMPHY_SGMII_MODE || - mode == COMPHY_HS_SGMII_MODE || - mode == COMPHY_SFI_MODE || mode == COMPHY_XFI_MODE) + mode == COMPHY_HS_SGMII_MODE || + mode == COMPHY_SFI_MODE || + mode == COMPHY_XFI_MODE || + mode == COMPHY_AP_MODE) && COMPHY_GET_ID(comphy_mode) == 1) reg |= COMMON_SELECTOR_COMPHY4_PORT1 << comphy_offset; @@ -2225,12 +2227,16 @@ int mvebu_cp110_comphy_xfi_rx_training(uint64_t comphy_base, * the network registers like: MG, AP, MAC, PCS, Serdes etc.) */ static int mvebu_cp110_comphy_ap_power_on(uint64_t comphy_base, - uint8_t comphy_index) + uint8_t comphy_index, + uint32_t comphy_mode) { uint32_t mask, data; uintptr_t comphy_addr = comphy_addr = COMPHY_ADDR(comphy_base, comphy_index); + /* configure phy selector for XFI/SFI */ + mvebu_cp110_comphy_set_phy_selector(comphy_base, comphy_index, + comphy_mode); debug_enter(); debug("stage: RFU configurations - hard reset comphy\n"); /* RFU configurations - hard reset comphy */ @@ -2323,7 +2329,8 @@ int mvebu_cp110_comphy_power_on(uint64_t comphy_base, uint8_t comphy_index, comphy_mode); break; case (COMPHY_AP_MODE): - err = mvebu_cp110_comphy_ap_power_on(comphy_base, comphy_index); + err = mvebu_cp110_comphy_ap_power_on(comphy_base, comphy_index, + comphy_mode); break; default: ERROR("comphy%d: unsupported comphy mode\n", comphy_index); -- cgit v1.2.3 From 814ce2f9ef9f35c1b33c07d08eea72c3f5322bf7 Mon Sep 17 00:00:00 2001 From: Grzegorz Jaszczyk Date: Thu, 28 Mar 2019 16:09:38 +0100 Subject: plat: marvell: a8k: extend includes to take advantage of the phy_porting_layer The phy porting layer uses defaults defined in "phy-default-porting-layer.h" when board specific file "phy-porting-layer.h" is not found. Because of the regression the board specific directory was not included, therefore all boards used default parameters. Change-Id: I66e5e6eb8a39cca5aeeb4de6dab2ceddc39c1e31 Signed-off-by: Grzegorz Jaszczyk --- plat/marvell/armada/a8k/common/a8k_common.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/plat/marvell/armada/a8k/common/a8k_common.mk b/plat/marvell/armada/a8k/common/a8k_common.mk index 8731aa64b..dcbf9a66e 100644 --- a/plat/marvell/armada/a8k/common/a8k_common.mk +++ b/plat/marvell/armada/a8k/common/a8k_common.mk @@ -52,6 +52,7 @@ MARVELL_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ plat/common/plat_gicv2.c PLAT_INCLUDES := -I$(BOARD_DIR) \ + -I$(BOARD_DIR)/board \ -I$(PLAT_COMMON_BASE)/include \ -I$(PLAT_INCLUDE_BASE)/common -- cgit v1.2.3 From cdfbbfefcb485d68799249fe7d5585bd844ed17d Mon Sep 17 00:00:00 2001 From: Konstantin Porotchkin Date: Thu, 14 Mar 2019 17:24:40 +0200 Subject: plat: marvell: armada: re-enable BL32_BASE definition As a preparation to support proper loading the OPTEE OS image, enable the BL32 specific defines in case the SPD is used. On the occasion move two BL32-related macros to marvell_def.h and fix BL32_LIMIT definition. Change-Id: Id4e2d81833bc1895650cca8b0fc0bfc341cf77f3 Signed-off-by: Konstantin Porotchkin Signed-off-by: Marcin Wojtas --- include/plat/marvell/armada/a3k/common/marvell_def.h | 10 ++++++++++ include/plat/marvell/armada/a8k/common/marvell_def.h | 9 +++++++++ plat/marvell/armada/a3k/common/include/platform_def.h | 8 -------- plat/marvell/armada/a8k/common/include/platform_def.h | 8 -------- 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/include/plat/marvell/armada/a3k/common/marvell_def.h b/include/plat/marvell/armada/a3k/common/marvell_def.h index eb13ba8af..3581a1c6e 100644 --- a/include/plat/marvell/armada/a3k/common/marvell_def.h +++ b/include/plat/marvell/armada/a3k/common/marvell_def.h @@ -173,5 +173,15 @@ #define BL31_LIMIT (MARVELL_BL_RAM_BASE + \ MARVELL_BL_RAM_SIZE) +/***************************************************************************** + * BL32 specific defines. + ***************************************************************************** + */ +#define BL32_BASE PLAT_MARVELL_TRUSTED_DRAM_BASE +#define BL32_LIMIT (BL32_BASE + PLAT_MARVELL_TRUSTED_DRAM_SIZE) + +#ifdef SPD_none +#undef BL32_BASE +#endif /* SPD_none */ #endif /* MARVELL_DEF_H */ diff --git a/include/plat/marvell/armada/a8k/common/marvell_def.h b/include/plat/marvell/armada/a8k/common/marvell_def.h index 4eda01f1e..1a417db84 100644 --- a/include/plat/marvell/armada/a8k/common/marvell_def.h +++ b/include/plat/marvell/armada/a8k/common/marvell_def.h @@ -177,5 +177,14 @@ #define BL31_LIMIT (MARVELL_BL_RAM_BASE + \ MARVELL_BL_RAM_SIZE) +/******************************************************************************* + * BL32 specific defines. + ******************************************************************************/ +#define BL32_BASE PLAT_MARVELL_TRUSTED_DRAM_BASE +#define BL32_LIMIT (BL32_BASE + PLAT_MARVELL_TRUSTED_DRAM_SIZE) + +#ifdef SPD_none +#undef BL32_BASE +#endif /* SPD_none */ #endif /* MARVELL_DEF_H */ diff --git a/plat/marvell/armada/a3k/common/include/platform_def.h b/plat/marvell/armada/a3k/common/include/platform_def.h index e6660d407..c20885553 100644 --- a/plat/marvell/armada/a3k/common/include/platform_def.h +++ b/plat/marvell/armada/a3k/common/include/platform_def.h @@ -221,12 +221,4 @@ /* Securities */ #define IRQ_SEC_OS_TICK_INT MARVELL_IRQ_SEC_PHY_TIMER -#define TRUSTED_DRAM_BASE PLAT_MARVELL_TRUSTED_DRAM_BASE -#define TRUSTED_DRAM_SIZE PLAT_MARVELL_TRUSTED_DRAM_SIZE - -#ifdef BL32 -#define BL32_BASE TRUSTED_DRAM_BASE -#define BL32_LIMIT TRUSTED_DRAM_SIZE -#endif - #endif /* PLATFORM_DEF_H */ diff --git a/plat/marvell/armada/a8k/common/include/platform_def.h b/plat/marvell/armada/a8k/common/include/platform_def.h index ec1c9036c..06e781464 100644 --- a/plat/marvell/armada/a8k/common/include/platform_def.h +++ b/plat/marvell/armada/a8k/common/include/platform_def.h @@ -190,14 +190,6 @@ /* Securities */ #define IRQ_SEC_OS_TICK_INT MARVELL_IRQ_SEC_PHY_TIMER -#define TRUSTED_DRAM_BASE PLAT_MARVELL_TRUSTED_DRAM_BASE -#define TRUSTED_DRAM_SIZE PLAT_MARVELL_TRUSTED_DRAM_SIZE - -#ifdef BL32 -#define BL32_BASE TRUSTED_DRAM_BASE -#define BL32_LIMIT TRUSTED_DRAM_SIZE -#endif - #define MVEBU_PMU_IRQ_WA #endif /* PLATFORM_DEF_H */ -- cgit v1.2.3 From e825176f1c499c6bedfe7eb887350a5e2ccbe239 Mon Sep 17 00:00:00 2001 From: Ben Peled Date: Tue, 26 Mar 2019 19:06:24 +0200 Subject: plat: marvell: a8k: move address config of cp1/2 to BL2 The configuration space of each standalone CP was updated in BL31. Loading FW procedure take places earlier in SCP_BL2. It needs to be done after access to each CP is provided. Moving the proper configuration from BL31 to BL2 solves it. Change-Id: I44cf88dfd4ebf09130544332bfdd3d16ef2674ea Signed-off-by: Ben Peled --- plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c | 16 ++++++++++------ plat/marvell/armada/a8k/common/plat_bl31_setup.c | 9 --------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c b/plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c index 3b81814f9..cdbae9df1 100644 --- a/plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c +++ b/plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -18,9 +19,6 @@ #include "mss_scp_bootloader.h" -/* IO windows configuration */ -#define IOW_GCR_OFFSET (0x70) - /* MSS windows configuration */ #define MSS_AEBR(base) (base + 0x160) #define MSS_AIBR(base) (base + 0x164) @@ -51,7 +49,7 @@ struct addr_map_win ccu_mem_map[] = { */ static int bl2_plat_mmap_init(void) { - int cfg_num, win_id, cfg_idx; + int cfg_num, win_id, cfg_idx, cp; cfg_num = ARRAY_SIZE(ccu_mem_map); @@ -71,8 +69,14 @@ static int bl2_plat_mmap_init(void) ccu_enable_win(MVEBU_AP0, &ccu_mem_map[cfg_idx], win_id); } - /* Set the default target id to PIDI */ - mmio_write_32(MVEBU_IO_WIN_BASE(MVEBU_AP0) + IOW_GCR_OFFSET, PIDI_TID); + /* Config address for each cp other than cp0 */ + for (cp = 1; cp < CP_COUNT; cp++) + update_cp110_default_win(cp); + + /* There is need to configure IO_WIN windows again to overwrite + * temporary configuration done during update_cp110_default_win + */ + init_io_win(MVEBU_AP0); /* Open AMB bridge required for MG access */ for (cp = 0; cp < CP_COUNT; cp++) diff --git a/plat/marvell/armada/a8k/common/plat_bl31_setup.c b/plat/marvell/armada/a8k/common/plat_bl31_setup.c index 621f43c63..552c9b298 100644 --- a/plat/marvell/armada/a8k/common/plat_bl31_setup.c +++ b/plat/marvell/armada/a8k/common/plat_bl31_setup.c @@ -116,21 +116,12 @@ void bl31_plat_arch_setup(void) marvell_bl31_plat_arch_setup(); for (cp = 0; cp < CP_COUNT; cp++) { - if (cp >= 1) - update_cp110_default_win(cp); - cp110_init(MVEBU_CP_REGS_BASE(cp), STREAM_ID_BASE + (cp * MAX_STREAM_ID_PER_CP)); marvell_bl31_mpp_init(cp); } - /* - * There is need to configure IO_WIN windows again to overwrite - * temporary configuration done during update_cp110_default_win - */ - init_io_win(MVEBU_AP0); - for (cp = 1; cp < CP_COUNT; cp++) mci_link_tune(cp - 1); -- cgit v1.2.3 From 772aa5ba75f38930e8e9c3f370a4e2aa9f5f417c Mon Sep 17 00:00:00 2001 From: Konstantin Porotchkin Date: Mon, 25 Mar 2019 15:35:41 +0200 Subject: drivers: marvell: align and extend llc macros Make all LLC-related macros to start with the same prefix Add more LLC control registers definitions This patch is a preparation step for LLC SRAM support Change-Id: I0a4f0fc83e8ef35be93dd239a85f2a9f88d1ab19 Signed-off-by: Konstantin Porotchkin --- drivers/marvell/cache_llc.c | 6 +++--- include/drivers/marvell/cache_llc.h | 19 ++++++++++++++----- plat/marvell/armada/common/aarch64/marvell_helpers.S | 2 +- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/drivers/marvell/cache_llc.c b/drivers/marvell/cache_llc.c index 3df93a43b..9b614c496 100644 --- a/drivers/marvell/cache_llc.c +++ b/drivers/marvell/cache_llc.c @@ -31,19 +31,19 @@ void llc_cache_sync(int ap_index) void llc_flush_all(int ap_index) { - mmio_write_32(L2X0_CLEAN_INV_WAY(ap_index), LLC_WAY_MASK); + mmio_write_32(LLC_CLEAN_INV_WAY(ap_index), LLC_ALL_WAYS_MASK); llc_cache_sync(ap_index); } void llc_clean_all(int ap_index) { - mmio_write_32(L2X0_CLEAN_WAY(ap_index), LLC_WAY_MASK); + mmio_write_32(LLC_CLEAN_WAY(ap_index), LLC_ALL_WAYS_MASK); llc_cache_sync(ap_index); } void llc_inv_all(int ap_index) { - mmio_write_32(L2X0_INV_WAY(ap_index), LLC_WAY_MASK); + mmio_write_32(LLC_INV_WAY(ap_index), LLC_ALL_WAYS_MASK); llc_cache_sync(ap_index); } diff --git a/include/drivers/marvell/cache_llc.h b/include/drivers/marvell/cache_llc.h index 85babb8d4..d8eca9fbf 100644 --- a/include/drivers/marvell/cache_llc.h +++ b/include/drivers/marvell/cache_llc.h @@ -14,18 +14,27 @@ #define LLC_CTRL(ap) (MVEBU_LLC_BASE(ap) + 0x100) #define LLC_SYNC(ap) (MVEBU_LLC_BASE(ap) + 0x700) -#define L2X0_INV_WAY(ap) (MVEBU_LLC_BASE(ap) + 0x77C) -#define L2X0_CLEAN_WAY(ap) (MVEBU_LLC_BASE(ap) + 0x7BC) -#define L2X0_CLEAN_INV_WAY(ap) (MVEBU_LLC_BASE(ap) + 0x7FC) +#define LLC_BANKED_MNT_AHR(ap) (MVEBU_LLC_BASE(ap) + 0x724) +#define LLC_INV_WAY(ap) (MVEBU_LLC_BASE(ap) + 0x77C) +#define LLC_BLK_ALOC(ap) (MVEBU_LLC_BASE(ap) + 0x78c) +#define LLC_CLEAN_WAY(ap) (MVEBU_LLC_BASE(ap) + 0x7BC) +#define LLC_CLEAN_INV_WAY(ap) (MVEBU_LLC_BASE(ap) + 0x7FC) #define LLC_TC0_LOCK(ap) (MVEBU_LLC_BASE(ap) + 0x920) #define MASTER_LLC_CTRL LLC_CTRL(MVEBU_AP0) -#define MASTER_L2X0_INV_WAY L2X0_INV_WAY(MVEBU_AP0) +#define MASTER_LLC_INV_WAY LLC_INV_WAY(MVEBU_AP0) #define MASTER_LLC_TC0_LOCK LLC_TC0_LOCK(MVEBU_AP0) #define LLC_CTRL_EN 1 #define LLC_EXCLUSIVE_EN 0x100 -#define LLC_WAY_MASK 0xFFFFFFFF +#define LLC_ALL_WAYS_MASK 0xFFFFFFFF + +/* AP806/AP807 - 1MB 8-ways LLC */ +#define LLC_WAYS 8 +#define LLC_WAY_MASK ((1 << LLC_WAYS) - 1) +#define LLC_SIZE (1024 * 1024) +#define LLC_WAY_SIZE (LLC_SIZE / LLC_WAYS) + #ifndef __ASSEMBLER__ void llc_cache_sync(int ap_index); diff --git a/plat/marvell/armada/common/aarch64/marvell_helpers.S b/plat/marvell/armada/common/aarch64/marvell_helpers.S index 6f625b95d..4ddc73db5 100644 --- a/plat/marvell/armada/common/aarch64/marvell_helpers.S +++ b/plat/marvell/armada/common/aarch64/marvell_helpers.S @@ -185,7 +185,7 @@ func disable_sram /* Invalidate all ways */ ldr w1, =LLC_WAY_MASK - ldr x0, =MASTER_L2X0_INV_WAY + ldr x0, =MASTER_LLC_INV_WAY str w1, [x0] /* Finally disable LLC */ -- cgit v1.2.3 From 957a5add638b1269210eac3a655e6b15e6fdb92e Mon Sep 17 00:00:00 2001 From: Konstantin Porotchkin Date: Sun, 31 Mar 2019 17:20:19 +0300 Subject: drivers: marvell: add CCU driver API for window state checking Add ccu_is_win_enabled() API for checking the CCU window state using AP and window indexes. Change-Id: Ib955a2cac28b2729b0a763f3bbbea28b476a2fe4 Signed-off-by: Konstantin Porotchkin --- drivers/marvell/ccu.c | 10 ++++++++-- include/drivers/marvell/ccu.h | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/marvell/ccu.c b/drivers/marvell/ccu.c index 1e4ab44da..c73516eae 100644 --- a/drivers/marvell/ccu.c +++ b/drivers/marvell/ccu.c @@ -54,8 +54,8 @@ static void dump_ccu(int ap_index) win_id)); start = ((uint64_t)alr << ADDRESS_SHIFT); end = (((uint64_t)ahr + 0x10) << ADDRESS_SHIFT); - printf("\tccu %02x 0x%016llx 0x%016llx\n", - target_id, start, end); + printf("\tccu%d %02x 0x%016llx 0x%016llx\n", + win_id, target_id, start, end); } } win_cr = mmio_read_32(CCU_WIN_GCR_OFFSET(ap_index)); @@ -81,6 +81,12 @@ void ccu_win_check(struct addr_map_win *win) } } +int ccu_is_win_enabled(int ap_index, uint32_t win_id) +{ + return mmio_read_32(CCU_WIN_CR_OFFSET(ap_index, win_id)) & + WIN_ENABLE_BIT; +} + void ccu_enable_win(int ap_index, struct addr_map_win *win, uint32_t win_id) { uint32_t ccu_win_reg; diff --git a/include/drivers/marvell/ccu.h b/include/drivers/marvell/ccu.h index b0d1ec984..413ffb972 100644 --- a/include/drivers/marvell/ccu.h +++ b/include/drivers/marvell/ccu.h @@ -46,6 +46,7 @@ void ccu_dram_win_config(int ap_index, struct addr_map_win *win); void ccu_dram_target_set(int ap_index, uint32_t target); void ccu_save_win_all(int ap_id); void ccu_restore_win_all(int ap_id); +int ccu_is_win_enabled(int ap_index, uint32_t win_id); #endif #endif /* CCU_H */ -- cgit v1.2.3 From c96aa7fb3d9b306d50d71659a3c3d036ac9e3673 Mon Sep 17 00:00:00 2001 From: Konstantin Porotchkin Date: Sun, 31 Mar 2019 17:22:53 +0300 Subject: plat: marvell: armada: a8k: check CCU window state before loading MSS BL2 Make sure the current CCU window is not in use before adding a new address map during MSS BL2 image load preparations. At BL2 stage the CCU Win-2 points to DRAM. If additional mapping is added to MSS BL2 stage initialization, the DDR entry will be destroyed and lead to the system hang. Change-Id: I215e83508acc37d54dab6954d791b9a74cc883ca Signed-off-by: Konstantin Porotchkin --- plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c b/plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c index cdbae9df1..c2cd93357 100644 --- a/plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c +++ b/plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c @@ -63,10 +63,15 @@ static int bl2_plat_mmap_init(void) * Do not touch CCU window 0, * it's used for the internal registers access */ - for (cfg_idx = 0, win_id = 1; cfg_idx < cfg_num; cfg_idx++, win_id++) { + for (cfg_idx = 0, win_id = 1; + (win_id < MVEBU_CCU_MAX_WINS) && (cfg_idx < cfg_num); win_id++) { + /* Skip already enabled CCU windows */ + if (ccu_is_win_enabled(MVEBU_AP0, win_id)) + continue; /* Enable required CCU windows */ ccu_win_check(&ccu_mem_map[cfg_idx]); ccu_enable_win(MVEBU_AP0, &ccu_mem_map[cfg_idx], win_id); + cfg_idx++; } /* Config address for each cp other than cp0 */ -- cgit v1.2.3 From 63a0b12794ca38d0bdf8982ae4009b78350c43e5 Mon Sep 17 00:00:00 2001 From: Konstantin Porotchkin Date: Fri, 19 Jun 2020 17:48:48 +0200 Subject: plat: marvell: armada: platform definitions cleanup - Remove TRUSTED_DRAM_BASE TRUSTED_DRAM_SIZE MARVELL_TRUSTED_SRAM_BASE - Rename PLAT_MARVELL_TRUSTED_DRAM_* -> PLAT_MARVELL_TRUSTED_RAM_* PLAT_MARVELL_TRUSTED_SRAM_* -> MARVELL_TRUSTED_DRAM_* MARVELL_MAP_SHARED_RAM -> MARVELL_MAP_SECURE_RAM - Move MARVELL_TRUSTED_DRAM_SIZE to marvell_def.h - Enable MARVELL_MAP_SECURE_RAM region in BL2U memory map - Add dependency of MARVELL_MAP_SHARED_RAM on LLC_SRAM - Add minor style improvents Change-Id: Iebc03361e4f88489af1597f54e137b27c241814c Signed-off-by: Konstantin Porotchkin [Improve patch after rebase] Signed-off-by: Marcin Wojtas --- .../marvell/armada/a3k/common/board_marvell_def.h | 2 -- .../plat/marvell/armada/a3k/common/marvell_def.h | 15 ++++++----- .../marvell/armada/a8k/common/board_marvell_def.h | 3 --- .../plat/marvell/armada/a8k/common/marvell_def.h | 30 ++++++++++++++-------- .../armada/a3k/common/include/platform_def.h | 7 +++-- .../marvell/armada/a8k/common/aarch64/a8k_common.c | 8 +++--- .../armada/a8k/common/include/platform_def.h | 15 ++++++----- 7 files changed, 45 insertions(+), 35 deletions(-) diff --git a/include/plat/marvell/armada/a3k/common/board_marvell_def.h b/include/plat/marvell/armada/a3k/common/board_marvell_def.h index 178259662..bc3e04f00 100644 --- a/include/plat/marvell/armada/a3k/common/board_marvell_def.h +++ b/include/plat/marvell/armada/a3k/common/board_marvell_def.h @@ -71,6 +71,4 @@ #define MAX_IO_DEVICES 3 #define MAX_IO_HANDLES 4 -#define PLAT_MARVELL_TRUSTED_SRAM_SIZE 0x80000 /* 512 KB */ - #endif /* BOARD_MARVELL_DEF_H */ diff --git a/include/plat/marvell/armada/a3k/common/marvell_def.h b/include/plat/marvell/armada/a3k/common/marvell_def.h index 3581a1c6e..1394c05ab 100644 --- a/include/plat/marvell/armada/a3k/common/marvell_def.h +++ b/include/plat/marvell/armada/a3k/common/marvell_def.h @@ -49,15 +49,17 @@ */ #define MARVELL_LOCAL_STATE_OFF 2 +/* This leaves a gap between end of DRAM and start of ROM block */ +#define MARVELL_TRUSTED_DRAM_SIZE 0x80000 /* 512 KB */ + /* The first 4KB of Trusted SRAM are used as shared memory */ -#define MARVELL_TRUSTED_SRAM_BASE PLAT_MARVELL_ATF_BASE -#define MARVELL_SHARED_RAM_BASE MARVELL_TRUSTED_SRAM_BASE +#define MARVELL_SHARED_RAM_BASE PLAT_MARVELL_ATF_BASE #define MARVELL_SHARED_RAM_SIZE 0x00001000 /* 4 KB */ /* The remaining Trusted SRAM is used to load the BL images */ #define MARVELL_BL_RAM_BASE (MARVELL_SHARED_RAM_BASE + \ MARVELL_SHARED_RAM_SIZE) -#define MARVELL_BL_RAM_SIZE (PLAT_MARVELL_TRUSTED_SRAM_SIZE - \ +#define MARVELL_BL_RAM_SIZE (MARVELL_TRUSTED_DRAM_SIZE - \ MARVELL_SHARED_RAM_SIZE) #define MARVELL_DRAM_BASE ULL(0x0) @@ -65,7 +67,7 @@ #define MARVELL_DRAM_END (MARVELL_DRAM_BASE + \ MARVELL_DRAM_SIZE - 1) -#define MARVELL_IRQ_SEC_PHY_TIMER 29 +#define MARVELL_IRQ_SEC_PHY_TIMER 29 #define MARVELL_IRQ_SEC_SGI_0 8 #define MARVELL_IRQ_SEC_SGI_1 9 @@ -86,7 +88,6 @@ MARVELL_DRAM_SIZE, \ MT_MEMORY | MT_RW | MT_NS) - /* * The number of regions like RO(code), coherent and data required by * different BL stages which need to be mapped in the MMU. @@ -177,8 +178,8 @@ * BL32 specific defines. ***************************************************************************** */ -#define BL32_BASE PLAT_MARVELL_TRUSTED_DRAM_BASE -#define BL32_LIMIT (BL32_BASE + PLAT_MARVELL_TRUSTED_DRAM_SIZE) +#define BL32_BASE PLAT_MARVELL_TRUSTED_RAM_BASE +#define BL32_LIMIT (BL32_BASE + PLAT_MARVELL_TRUSTED_RAM_SIZE) #ifdef SPD_none #undef BL32_BASE diff --git a/include/plat/marvell/armada/a8k/common/board_marvell_def.h b/include/plat/marvell/armada/a8k/common/board_marvell_def.h index 0da56e7af..7e90f5f19 100644 --- a/include/plat/marvell/armada/a8k/common/board_marvell_def.h +++ b/include/plat/marvell/armada/a8k/common/board_marvell_def.h @@ -71,7 +71,4 @@ #define MAX_IO_DEVICES 3 #define MAX_IO_HANDLES 4 -#define PLAT_MARVELL_TRUSTED_SRAM_SIZE 0x80000 /* 512 KB */ - - #endif /* BOARD_MARVELL_DEF_H */ diff --git a/include/plat/marvell/armada/a8k/common/marvell_def.h b/include/plat/marvell/armada/a8k/common/marvell_def.h index 1a417db84..9fd972597 100644 --- a/include/plat/marvell/armada/a8k/common/marvell_def.h +++ b/include/plat/marvell/armada/a8k/common/marvell_def.h @@ -47,15 +47,17 @@ */ #define MARVELL_LOCAL_STATE_OFF 2 +/* This leaves a gap between end of DRAM and start of ROM block */ +#define MARVELL_TRUSTED_DRAM_SIZE 0x80000 /* 512 KB */ + /* The first 4KB of Trusted SRAM are used as shared memory */ -#define MARVELL_TRUSTED_SRAM_BASE PLAT_MARVELL_ATF_BASE -#define MARVELL_SHARED_RAM_BASE MARVELL_TRUSTED_SRAM_BASE +#define MARVELL_SHARED_RAM_BASE PLAT_MARVELL_ATF_BASE #define MARVELL_SHARED_RAM_SIZE 0x00001000 /* 4 KB */ /* The remaining Trusted SRAM is used to load the BL images */ #define MARVELL_BL_RAM_BASE (MARVELL_SHARED_RAM_BASE + \ MARVELL_SHARED_RAM_SIZE) -#define MARVELL_BL_RAM_SIZE (PLAT_MARVELL_TRUSTED_SRAM_SIZE - \ +#define MARVELL_BL_RAM_SIZE (MARVELL_TRUSTED_DRAM_SIZE - \ MARVELL_SHARED_RAM_SIZE) /* Non-shared DRAM */ #define MARVELL_DRAM_BASE ULL(0x0) @@ -75,17 +77,25 @@ #define MARVELL_IRQ_SEC_SGI_6 14 #define MARVELL_IRQ_SEC_SGI_7 15 -#define MARVELL_MAP_SHARED_RAM MAP_REGION_FLAT( \ - MARVELL_SHARED_RAM_BASE,\ - MARVELL_SHARED_RAM_SIZE,\ +#if LLC_SRAM +/* The entire LLC SRAM should be marked as secure in MMU tables, + * otherwise any access to it will produce exception + */ +#define MARVELL_MAP_SECURE_RAM MAP_REGION_FLAT( \ + PLAT_MARVELL_LLC_SRAM_BASE,\ + PLAT_MARVELL_LLC_SRAM_SIZE,\ MT_MEMORY | MT_RW | MT_SECURE) - +#else +#define MARVELL_MAP_SECURE_RAM MAP_REGION_FLAT( \ + MARVELL_SHARED_RAM_BASE, \ + MARVELL_SHARED_RAM_SIZE, \ + MT_MEMORY | MT_RW | MT_SECURE) +#endif #define MARVELL_MAP_DRAM MAP_REGION_FLAT( \ MARVELL_DRAM_BASE, \ MARVELL_DRAM_SIZE, \ MT_MEMORY | MT_RW | MT_NS) - /* * The number of regions like RO(code), coherent and data required by * different BL stages which need to be mapped in the MMU. @@ -180,8 +190,8 @@ /******************************************************************************* * BL32 specific defines. ******************************************************************************/ -#define BL32_BASE PLAT_MARVELL_TRUSTED_DRAM_BASE -#define BL32_LIMIT (BL32_BASE + PLAT_MARVELL_TRUSTED_DRAM_SIZE) +#define BL32_BASE PLAT_MARVELL_TRUSTED_RAM_BASE +#define BL32_LIMIT (BL32_BASE + PLAT_MARVELL_TRUSTED_RAM_SIZE) #ifdef SPD_none #undef BL32_BASE diff --git a/plat/marvell/armada/a3k/common/include/platform_def.h b/plat/marvell/armada/a3k/common/include/platform_def.h index c20885553..ed1b3f7c8 100644 --- a/plat/marvell/armada/a3k/common/include/platform_def.h +++ b/plat/marvell/armada/a3k/common/include/platform_def.h @@ -84,8 +84,8 @@ /* 64 MB TODO: reduce this to minimum needed according to fip image size*/ #define PLAT_MARVELL_TRUSTED_ROM_SIZE 0x04000000 /* Reserve 16M for SCP (Secure PayLoad) Trusted DRAM */ -#define PLAT_MARVELL_TRUSTED_DRAM_BASE 0x04400000 -#define PLAT_MARVELL_TRUSTED_DRAM_SIZE 0x01000000 /* 16 MB */ +#define PLAT_MARVELL_TRUSTED_RAM_BASE 0x04400000 +#define PLAT_MARVELL_TRUSTED_RAM_SIZE 0x01000000 /* 16 MB */ /* * PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size @@ -169,8 +169,7 @@ #define PLAT_MARVELL_NSTIMER_FRAME_ID 1 /* Mailbox base address */ -#define PLAT_MARVELL_MAILBOX_BASE \ - (MARVELL_TRUSTED_SRAM_BASE + 0x400) +#define PLAT_MARVELL_MAILBOX_BASE (MARVELL_SHARED_RAM_BASE + 0x400) #define PLAT_MARVELL_MAILBOX_SIZE 0x100 #define PLAT_MARVELL_MAILBOX_MAGIC_NUM 0x6D72766C /* mrvl */ diff --git a/plat/marvell/armada/a8k/common/aarch64/a8k_common.c b/plat/marvell/armada/a8k/common/aarch64/a8k_common.c index 7c2bf318f..a2e7402e6 100644 --- a/plat/marvell/armada/a8k/common/aarch64/a8k_common.c +++ b/plat/marvell/armada/a8k/common/aarch64/a8k_common.c @@ -18,14 +18,14 @@ */ #if IMAGE_BL1 const mmap_region_t plat_marvell_mmap[] = { - MARVELL_MAP_SHARED_RAM, + MARVELL_MAP_SECURE_RAM, MAP_DEVICE0, {0} }; #endif #if IMAGE_BL2 const mmap_region_t plat_marvell_mmap[] = { - MARVELL_MAP_SHARED_RAM, + MARVELL_MAP_SECURE_RAM, MAP_DEVICE0, MARVELL_MAP_DRAM, {0} @@ -34,6 +34,7 @@ const mmap_region_t plat_marvell_mmap[] = { #if IMAGE_BL2U const mmap_region_t plat_marvell_mmap[] = { + MARVELL_MAP_SECURE_RAM, MAP_DEVICE0, {0} }; @@ -48,7 +49,7 @@ const mmap_region_t plat_marvell_mmap[] = { #if IMAGE_BL31 const mmap_region_t plat_marvell_mmap[] = { - MARVELL_MAP_SHARED_RAM, + MARVELL_MAP_SECURE_RAM, MAP_DEVICE0, MARVELL_MAP_DRAM, {0} @@ -56,6 +57,7 @@ const mmap_region_t plat_marvell_mmap[] = { #endif #if IMAGE_BL32 const mmap_region_t plat_marvell_mmap[] = { + MARVELL_MAP_SECURE_RAM, MAP_DEVICE0, {0} }; diff --git a/plat/marvell/armada/a8k/common/include/platform_def.h b/plat/marvell/armada/a8k/common/include/platform_def.h index 06e781464..d0df06271 100644 --- a/plat/marvell/armada/a8k/common/include/platform_def.h +++ b/plat/marvell/armada/a8k/common/include/platform_def.h @@ -92,13 +92,16 @@ #define PLAT_MARVELL_CORE_COUNT (PLAT_MARVELL_CLUSTER_COUNT * \ PLAT_MARVELL_CLUSTER_CORE_COUNT) -/* DRAM[2MB..66MB] is used as Trusted ROM */ +/* Part of DRAM that is used as Trusted ROM */ #define PLAT_MARVELL_TRUSTED_ROM_BASE PLAT_MARVELL_ATF_LOAD_ADDR /* 64 MB TODO: reduce this to minimum needed according to fip image size */ #define PLAT_MARVELL_TRUSTED_ROM_SIZE 0x04000000 -/* Reserve 16M for SCP (Secure PayLoad) Trusted DRAM */ -#define PLAT_MARVELL_TRUSTED_DRAM_BASE 0x04400000 -#define PLAT_MARVELL_TRUSTED_DRAM_SIZE 0x01000000 /* 16 MB */ +/* Reserve 16M for SCP (Secure PayLoad) Trusted RAM */ +#define PLAT_MARVELL_TRUSTED_RAM_BASE 0x04400000 +#define PLAT_MARVELL_TRUSTED_RAM_SIZE 0x01000000 /* 16 MB DRAM */ + +#define PLAT_MARVELL_LLC_SRAM_BASE PLAT_MARVELL_TRUSTED_RAM_BASE +#define PLAT_MARVELL_LLC_SRAM_SIZE 0x00100000 /* 1 MB SRAM */ /* * PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size @@ -182,8 +185,8 @@ /* Mailbox base address (note the lower memory space * is reserved for BLE data) */ -#define PLAT_MARVELL_MAILBOX_BASE (MARVELL_TRUSTED_SRAM_BASE \ - + 0x400) +#define PLAT_MARVELL_MAILBOX_BASE (MARVELL_SHARED_RAM_BASE \ + + 0x400) #define PLAT_MARVELL_MAILBOX_SIZE 0x100 #define PLAT_MARVELL_MAILBOX_MAGIC_NUM 0x6D72766C /* mrvl */ -- cgit v1.2.3 From 94d6f48368d355406fc2f2e34333e905d7e6ea7c Mon Sep 17 00:00:00 2001 From: Marcin Wojtas Date: Fri, 19 Jun 2020 17:51:08 +0200 Subject: plat: marvell: armada: reduce memory size reserved for FIP image It is not needed to reserve 64MB for FIP. Limit this to 4MB for both supported Armada SoC families. Change-Id: I58a8ce4408a646fe1afd3c1ea1ed54007c8d205d Signed-off-by: Konstantin Porotchkin [Extract from bigger commit] Signed-off-by: Marcin Wojtas --- plat/marvell/armada/a3k/common/include/platform_def.h | 4 ++-- plat/marvell/armada/a8k/common/include/platform_def.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plat/marvell/armada/a3k/common/include/platform_def.h b/plat/marvell/armada/a3k/common/include/platform_def.h index ed1b3f7c8..7f8f79a45 100644 --- a/plat/marvell/armada/a3k/common/include/platform_def.h +++ b/plat/marvell/armada/a3k/common/include/platform_def.h @@ -81,8 +81,8 @@ #define PLAT_MARVELL_CLUSTER_CORE_COUNT U(2) /* DRAM[2MB..66MB] is used as Trusted ROM */ #define PLAT_MARVELL_TRUSTED_ROM_BASE PLAT_MARVELL_ATF_LOAD_ADDR -/* 64 MB TODO: reduce this to minimum needed according to fip image size*/ -#define PLAT_MARVELL_TRUSTED_ROM_SIZE 0x04000000 +/* 4 MB for FIP image */ +#define PLAT_MARVELL_TRUSTED_ROM_SIZE 0x00400000 /* Reserve 16M for SCP (Secure PayLoad) Trusted DRAM */ #define PLAT_MARVELL_TRUSTED_RAM_BASE 0x04400000 #define PLAT_MARVELL_TRUSTED_RAM_SIZE 0x01000000 /* 16 MB */ diff --git a/plat/marvell/armada/a8k/common/include/platform_def.h b/plat/marvell/armada/a8k/common/include/platform_def.h index d0df06271..b26e3ea1e 100644 --- a/plat/marvell/armada/a8k/common/include/platform_def.h +++ b/plat/marvell/armada/a8k/common/include/platform_def.h @@ -94,8 +94,8 @@ /* Part of DRAM that is used as Trusted ROM */ #define PLAT_MARVELL_TRUSTED_ROM_BASE PLAT_MARVELL_ATF_LOAD_ADDR -/* 64 MB TODO: reduce this to minimum needed according to fip image size */ -#define PLAT_MARVELL_TRUSTED_ROM_SIZE 0x04000000 +/* 4 MB for FIP image */ +#define PLAT_MARVELL_TRUSTED_ROM_SIZE 0x00400000 /* Reserve 16M for SCP (Secure PayLoad) Trusted RAM */ #define PLAT_MARVELL_TRUSTED_RAM_BASE 0x04400000 #define PLAT_MARVELL_TRUSTED_RAM_SIZE 0x01000000 /* 16 MB DRAM */ -- cgit v1.2.3 From 85440805d46646871dc9b2934a0a3932b44df7d4 Mon Sep 17 00:00:00 2001 From: Konstantin Porotchkin Date: Sun, 31 Mar 2019 17:16:35 +0300 Subject: plat: marvell: armada: add LLC SRAM CCU setup for AP806/AP807 platforms Extend the CCU tables with secure SRAM window in all board setups that uses SoCs based on AP806/AP807 North Bridges Change-Id: I4dc315e4ea847562ac8648d8a8739244b548c70e Signed-off-by: Konstantin Porotchkin --- plat/marvell/armada/a8k/a70x0/board/marvell_plat_config.c | 3 +++ plat/marvell/armada/a8k/a70x0_amc/board/marvell_plat_config.c | 3 +++ plat/marvell/armada/a8k/a80x0/board/marvell_plat_config.c | 3 +++ plat/marvell/armada/a8k/a80x0_mcbin/board/marvell_plat_config.c | 3 +++ 4 files changed, 12 insertions(+) diff --git a/plat/marvell/armada/a8k/a70x0/board/marvell_plat_config.c b/plat/marvell/armada/a8k/a70x0/board/marvell_plat_config.c index d126f5567..7d30ebe5a 100644 --- a/plat/marvell/armada/a8k/a70x0/board/marvell_plat_config.c +++ b/plat/marvell/armada/a8k/a70x0/board/marvell_plat_config.c @@ -102,6 +102,9 @@ struct addr_map_win ccu_memory_map[] = { /* IO window */ #ifdef IMAGE_BLE {0x00000000f2000000, 0x4000000, IO_0_TID}, /* IO window */ #else +#if LLC_SRAM + {PLAT_MARVELL_LLC_SRAM_BASE, PLAT_MARVELL_LLC_SRAM_SIZE, SRAM_TID}, +#endif {0x00000000f2000000, 0xe000000, IO_0_TID}, {0x00000000c0000000, 0x30000000, IO_0_TID}, /* IO window */ {0x0000000800000000, 0x100000000, IO_0_TID}, /* IO window */ diff --git a/plat/marvell/armada/a8k/a70x0_amc/board/marvell_plat_config.c b/plat/marvell/armada/a8k/a70x0_amc/board/marvell_plat_config.c index f8a1c40be..7fc33f1f9 100644 --- a/plat/marvell/armada/a8k/a70x0_amc/board/marvell_plat_config.c +++ b/plat/marvell/armada/a8k/a70x0_amc/board/marvell_plat_config.c @@ -93,6 +93,9 @@ struct addr_map_win ccu_memory_map[] = { #ifdef IMAGE_BLE {0x00000000f2000000, 0x4000000, IO_0_TID}, /* IO window */ #else +#if LLC_SRAM + {PLAT_MARVELL_LLC_SRAM_BASE, PLAT_MARVELL_LLC_SRAM_SIZE, SRAM_TID}, +#endif {0x00000000f2000000, 0xe000000, IO_0_TID}, {0x00000000c0000000, 0x30000000, IO_0_TID}, /* IO window */ {0x0000000800000000, 0x200000000, IO_0_TID}, /* IO window */ diff --git a/plat/marvell/armada/a8k/a80x0/board/marvell_plat_config.c b/plat/marvell/armada/a8k/a80x0/board/marvell_plat_config.c index 7901dd225..856c07a6e 100644 --- a/plat/marvell/armada/a8k/a80x0/board/marvell_plat_config.c +++ b/plat/marvell/armada/a8k/a80x0/board/marvell_plat_config.c @@ -131,6 +131,9 @@ struct addr_map_win ccu_memory_map[] = { #ifdef IMAGE_BLE {0x00000000f2000000, 0x4000000, IO_0_TID}, /* IO window */ #else +#if LLC_SRAM + {PLAT_MARVELL_LLC_SRAM_BASE, PLAT_MARVELL_LLC_SRAM_SIZE, SRAM_TID}, +#endif {0x00000000f2000000, 0xe000000, IO_0_TID}, /* IO window */ {0x00000000c0000000, 0x30000000, IO_0_TID}, /* IO window */ {0x0000000800000000, 0x100000000, IO_0_TID}, /* IO window */ diff --git a/plat/marvell/armada/a8k/a80x0_mcbin/board/marvell_plat_config.c b/plat/marvell/armada/a8k/a80x0_mcbin/board/marvell_plat_config.c index fa4e144c9..0edc97745 100644 --- a/plat/marvell/armada/a8k/a80x0_mcbin/board/marvell_plat_config.c +++ b/plat/marvell/armada/a8k/a80x0_mcbin/board/marvell_plat_config.c @@ -165,6 +165,9 @@ struct addr_map_win ccu_memory_map[] = { #ifdef IMAGE_BLE {0x00000000f2000000, 0x4000000, IO_0_TID}, /* IO window */ #else +#if LLC_SRAM + {PLAT_MARVELL_LLC_SRAM_BASE, PLAT_MARVELL_LLC_SRAM_SIZE, SRAM_TID}, +#endif {0x00000000f2000000, 0xe000000, IO_0_TID}, /* IO window */ {0x00000000c0000000, 0x30000000, IO_0_TID}, /* IO window */ {0x0000000800000000, 0x100000000, IO_0_TID}, /* IO window */ -- cgit v1.2.3 From 5a40d70f067b6238159142755e4e5cb27e292045 Mon Sep 17 00:00:00 2001 From: Konstantin Porotchkin Date: Sun, 31 Mar 2019 16:58:11 +0300 Subject: drivers: marvell: add support for mapping the entire LLC to SRAM Add llc_sram_enable() and llc_sram_disable() APIs to Marvell cache_lls driver. Add LLC_SRAM definition to Marvell common makefile - disabled by the default. Add description of LLC_SRAM flag to the build documentation. Change-Id: Ib348e09752ce1206d29268ef96c9018b781db182 Signed-off-by: Konstantin Porotchkin --- docs/plat/marvell/armada/build.rst | 7 +++++ drivers/marvell/cache_llc.c | 38 ++++++++++++++++++++++++++++ include/drivers/marvell/cache_llc.h | 17 ++++++++++--- plat/marvell/armada/common/marvell_common.mk | 13 ++++++++++ 4 files changed, 72 insertions(+), 3 deletions(-) diff --git a/docs/plat/marvell/armada/build.rst b/docs/plat/marvell/armada/build.rst index 6f28721d5..bec0bcbd4 100644 --- a/docs/plat/marvell/armada/build.rst +++ b/docs/plat/marvell/armada/build.rst @@ -77,6 +77,13 @@ There are several build options: Flag defining the LLC (L3) cache state. The cache is enabled by default (``LLC_ENABLE=1``). +- LLC_SRAM + + Flag defining the LLC (L3) cache SRAM support. The feature is + disabled by default (``LLC_ENABLE=0``). + When LLC SRAM is enabled, the secure payload (BL32) is loaded into this + SRAM area instead of the DRAM. + - MARVELL_SECURE_BOOT Build trusted(=1)/non trusted(=0) image, default is non trusted. diff --git a/drivers/marvell/cache_llc.c b/drivers/marvell/cache_llc.c index 9b614c496..836aae7b8 100644 --- a/drivers/marvell/cache_llc.c +++ b/drivers/marvell/cache_llc.c @@ -109,3 +109,41 @@ void llc_runtime_enable(int ap_index) reg |= (0x1 << CCU_SET_POC_OFFSET); mmio_write_32(CCU_HTC_CR(ap_index), reg); } + +#if LLC_SRAM +void llc_sram_enable(int ap_index) +{ + uint32_t tc, way; + uint32_t way_addr; + + /* Lockdown all available ways for all traffic classes */ + for (tc = 0; tc < LLC_TC_NUM; tc++) + mmio_write_32(LLC_TCN_LOCK(ap_index, tc), LLC_WAY_MASK); + + /* Clear the high bits of SRAM address */ + mmio_write_32(LLC_BANKED_MNT_AHR(ap_index), 0); + + way_addr = PLAT_MARVELL_TRUSTED_RAM_BASE; + for (way = 0; way < LLC_WAYS; way++) { + /* Trigger allocation block command */ + mmio_write_32(LLC_BLK_ALOC(ap_index), + LLC_BLK_ALOC_BASE_ADDR(way_addr) | + LLC_BLK_ALOC_WAY_DATA_CLR | + LLC_BLK_ALOC_WAY_ID(way)); + way_addr += LLC_WAY_SIZE; + } + llc_enable(ap_index, 1); +} + +void llc_sram_disable(int ap_index) +{ + uint32_t tc; + + /* Disable the line lockings */ + for (tc = 0; tc < LLC_TC_NUM; tc++) + mmio_write_32(LLC_TCN_LOCK(ap_index, tc), 0); + + /* Invalidate all ways */ + llc_inv_all(ap_index); +} +#endif /* LLC_SRAM */ diff --git a/include/drivers/marvell/cache_llc.h b/include/drivers/marvell/cache_llc.h index d8eca9fbf..b326474ee 100644 --- a/include/drivers/marvell/cache_llc.h +++ b/include/drivers/marvell/cache_llc.h @@ -13,17 +13,18 @@ #define CACHE_LLC_H #define LLC_CTRL(ap) (MVEBU_LLC_BASE(ap) + 0x100) +#define LLC_SECURE_CTRL(ap) (MVEBU_LLC_BASE(ap) + 0x10C) #define LLC_SYNC(ap) (MVEBU_LLC_BASE(ap) + 0x700) #define LLC_BANKED_MNT_AHR(ap) (MVEBU_LLC_BASE(ap) + 0x724) #define LLC_INV_WAY(ap) (MVEBU_LLC_BASE(ap) + 0x77C) #define LLC_BLK_ALOC(ap) (MVEBU_LLC_BASE(ap) + 0x78c) #define LLC_CLEAN_WAY(ap) (MVEBU_LLC_BASE(ap) + 0x7BC) #define LLC_CLEAN_INV_WAY(ap) (MVEBU_LLC_BASE(ap) + 0x7FC) -#define LLC_TC0_LOCK(ap) (MVEBU_LLC_BASE(ap) + 0x920) +#define LLC_TCN_LOCK(ap, tc) (MVEBU_LLC_BASE(ap) + 0x920 + 4 * (tc)) #define MASTER_LLC_CTRL LLC_CTRL(MVEBU_AP0) #define MASTER_LLC_INV_WAY LLC_INV_WAY(MVEBU_AP0) -#define MASTER_LLC_TC0_LOCK LLC_TC0_LOCK(MVEBU_AP0) +#define MASTER_LLC_TC0_LOCK LLC_TCN_LOCK(MVEBU_AP0, 0) #define LLC_CTRL_EN 1 #define LLC_EXCLUSIVE_EN 0x100 @@ -34,7 +35,13 @@ #define LLC_WAY_MASK ((1 << LLC_WAYS) - 1) #define LLC_SIZE (1024 * 1024) #define LLC_WAY_SIZE (LLC_SIZE / LLC_WAYS) +#define LLC_TC_NUM 15 +#define LLC_BLK_ALOC_WAY_ID(way) ((way) & 0x1f) +#define LLC_BLK_ALOC_WAY_DATA_DSBL (0x0 << 6) +#define LLC_BLK_ALOC_WAY_DATA_CLR (0x1 << 6) +#define LLC_BLK_ALOC_WAY_DATA_SET (0x3 << 6) +#define LLC_BLK_ALOC_BASE_ADDR(addr) ((addr) & (LLC_WAY_SIZE - 1)) #ifndef __ASSEMBLER__ void llc_cache_sync(int ap_index); @@ -45,6 +52,10 @@ void llc_disable(int ap_index); void llc_enable(int ap_index, int excl_mode); int llc_is_exclusive(int ap_index); void llc_runtime_enable(int ap_index); -#endif +#if LLC_SRAM +void llc_sram_enable(int ap_index); +void llc_sram_disable(int ap_index); +#endif /* LLC_SRAM */ +#endif /* __ASSEMBLY__ */ #endif /* CACHE_LLC_H */ diff --git a/plat/marvell/armada/common/marvell_common.mk b/plat/marvell/armada/common/marvell_common.mk index f5f0c416e..fcc97acd3 100644 --- a/plat/marvell/armada/common/marvell_common.mk +++ b/plat/marvell/armada/common/marvell_common.mk @@ -16,8 +16,21 @@ SEPARATE_CODE_AND_RODATA := 1 # flag to switch from PLL to ARO ARO_ENABLE := 0 $(eval $(call add_define,ARO_ENABLE)) + +# Convert LLC to secure SRAM +LLC_SRAM := 0 +$(eval $(call add_define,LLC_SRAM)) + # Enable/Disable LLC +ifeq (${LLC_SRAM}, 0) LLC_ENABLE := 1 +else +# When LLC_SRAM=1, the entire LLC converted to SRAM and enabled at BL1. +# All existing cases activating LLC at BL31 stage should be disabled. +# The below assignment does not allow changing the LLC_ENABLE +# value in the command line. +LLC_ENABLE = 0 +endif $(eval $(call add_define,LLC_ENABLE)) include lib/xlat_tables_v2/xlat_tables.mk -- cgit v1.2.3 From 47d1773f90c84065c939ee190bb85f6221cd9dda Mon Sep 17 00:00:00 2001 From: Konstantin Porotchkin Date: Mon, 15 Apr 2019 16:29:08 +0300 Subject: plat: marvell: armada: a8k: add OP-TEE OS MMU tables Adjust the latest OP-TEE memory definitions to the newest TF-A baseline. Change-Id: Ib9c82b85f868adaf3c7285eb340486bda9c59c36 Signed-off-by: Konstantin Porotchkin --- .../plat/marvell/armada/a8k/common/marvell_def.h | 38 +++++++++++++++++----- .../marvell/armada/a8k/common/aarch64/a8k_common.c | 4 +++ 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/include/plat/marvell/armada/a8k/common/marvell_def.h b/include/plat/marvell/armada/a8k/common/marvell_def.h index 9fd972597..1245b88a2 100644 --- a/include/plat/marvell/armada/a8k/common/marvell_def.h +++ b/include/plat/marvell/armada/a8k/common/marvell_def.h @@ -77,20 +77,42 @@ #define MARVELL_IRQ_SEC_SGI_6 14 #define MARVELL_IRQ_SEC_SGI_7 15 -#if LLC_SRAM -/* The entire LLC SRAM should be marked as secure in MMU tables, - * otherwise any access to it will produce exception +#ifdef SPD_opteed +/* + * BL2 needs to map 4MB at the end of TZC_DRAM1 in order to + * load/authenticate the trusted os extra image. The first 512KB of + * TZC_DRAM1 are reserved for trusted os (OPTEE). The extra image loading + * for OPTEE is paged image which only include the paging part using + * virtual memory but without "init" data. OPTEE will copy the "init" data + * (from pager image) to the first 512KB of TZC_DRAM, and then copy the + * extra image behind the "init" data. + */ +#define MARVELL_OPTEE_PAGEABLE_LOAD_BASE \ + (PLAT_MARVELL_TRUSTED_RAM_BASE + \ + PLAT_MARVELL_TRUSTED_RAM_SIZE - \ + MARVELL_OPTEE_PAGEABLE_LOAD_SIZE) +#define MARVELL_OPTEE_PAGEABLE_LOAD_SIZE 0x400000 +#define MARVELL_OPTEE_PAGEABLE_LOAD_MEM \ + MAP_REGION_FLAT( \ + MARVELL_OPTEE_PAGEABLE_LOAD_BASE, \ + MARVELL_OPTEE_PAGEABLE_LOAD_SIZE, \ + MT_MEMORY | MT_RW | MT_SECURE) + +/* + * Map the memory for the OP-TEE core (also known as OP-TEE pager when paging + * support is enabled). */ -#define MARVELL_MAP_SECURE_RAM MAP_REGION_FLAT( \ - PLAT_MARVELL_LLC_SRAM_BASE,\ - PLAT_MARVELL_LLC_SRAM_SIZE,\ +#define MARVELL_MAP_OPTEE_CORE_MEM MAP_REGION_FLAT( \ + BL32_BASE, \ + BL32_LIMIT - BL32_BASE, \ MT_MEMORY | MT_RW | MT_SECURE) -#else +#endif /* SPD_opteed */ + #define MARVELL_MAP_SECURE_RAM MAP_REGION_FLAT( \ MARVELL_SHARED_RAM_BASE, \ MARVELL_SHARED_RAM_SIZE, \ MT_MEMORY | MT_RW | MT_SECURE) -#endif + #define MARVELL_MAP_DRAM MAP_REGION_FLAT( \ MARVELL_DRAM_BASE, \ MARVELL_DRAM_SIZE, \ diff --git a/plat/marvell/armada/a8k/common/aarch64/a8k_common.c b/plat/marvell/armada/a8k/common/aarch64/a8k_common.c index a2e7402e6..4332a76ea 100644 --- a/plat/marvell/armada/a8k/common/aarch64/a8k_common.c +++ b/plat/marvell/armada/a8k/common/aarch64/a8k_common.c @@ -28,6 +28,10 @@ const mmap_region_t plat_marvell_mmap[] = { MARVELL_MAP_SECURE_RAM, MAP_DEVICE0, MARVELL_MAP_DRAM, +#ifdef SPD_opteed + MARVELL_MAP_OPTEE_CORE_MEM, + MARVELL_OPTEE_PAGEABLE_LOAD_MEM, +#endif {0} }; #endif -- cgit v1.2.3 From 685e56092d91d40645a11406f84c2335f1dbe37a Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Tue, 2 Jun 2020 21:16:00 -0700 Subject: Tegra: sanity check NS address and size before use This patch updates the 'bl31_check_ns_address()' helper function to check that the memory address and size passed by the NS world are not zero. The helper fucntion also returns the error code as soon as it detects inconsistencies, to avoid multiple error paths from kicking in for the same input parameters. Signed-off-by: Varun Wadekar Change-Id: I46264f913954614bedcbde12e47ea0c70cd19be0 --- plat/nvidia/tegra/common/tegra_bl31_setup.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c index 269afb196..40713b2c7 100644 --- a/plat/nvidia/tegra/common/tegra_bl31_setup.c +++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c @@ -367,7 +367,15 @@ void bl31_plat_arch_setup(void) int32_t bl31_check_ns_address(uint64_t base, uint64_t size_in_bytes) { uint64_t end = base + size_in_bytes - U(1); - int32_t ret = 0; + + /* + * Sanity check the input values + */ + if ((base == 0U) || (size_in_bytes == 0U)) { + ERROR("NS address 0x%llx (%lld bytes) is invalid\n", + base, size_in_bytes); + return -EINVAL; + } /* * Check if the NS DRAM address is valid @@ -376,7 +384,7 @@ int32_t bl31_check_ns_address(uint64_t base, uint64_t size_in_bytes) (end > TEGRA_DRAM_END)) { ERROR("NS address 0x%llx is out-of-bounds!\n", base); - ret = -EFAULT; + return -EFAULT; } /* @@ -385,9 +393,9 @@ int32_t bl31_check_ns_address(uint64_t base, uint64_t size_in_bytes) */ if ((base < (uint64_t)TZDRAM_END) && (end > tegra_bl31_phys_base)) { ERROR("NS address 0x%llx overlaps TZDRAM!\n", base); - ret = -ENOTSUP; + return -ENOTSUP; } /* valid NS address */ - return ret; + return 0; } -- cgit v1.2.3 From 49fe535bce258eb657ca32e34ef0c50667db044b Mon Sep 17 00:00:00 2001 From: Sheetal Tigadoli Date: Tue, 2 Jun 2020 18:28:09 +0530 Subject: Fix typo in file Header guard Signed-off-by: Sheetal Tigadoli Change-Id: Iaf6deaeee2069720518221157edbb052bc42850a --- include/drivers/brcm/scp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/drivers/brcm/scp.h b/include/drivers/brcm/scp.h index b7b5bad74..7806314fa 100644 --- a/include/drivers/brcm/scp.h +++ b/include/drivers/brcm/scp.h @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#ifndef SCP_H_ +#ifndef SCP_H #define SCP_H #include -- cgit v1.2.3 From 5eb16c4717ac08de7c627cb1ee47c3269f0ec363 Mon Sep 17 00:00:00 2001 From: Sandeep Tripathy Date: Fri, 5 Jun 2020 22:04:21 +0530 Subject: TF-A GIC driver: Add barrier before eoi It is desired to have the peripheral writes completed to clear the interrupt condition and de-assert the interrupt request to GIC before EOI write. Failing which spurious interrupt will occurred. A barrier is needed to ensure peripheral register write transfers are complete before EOI is done. GICv2 memory mapped DEVICE nGnR(n)E writes are ordered from core point of view. However these writes may pass over different interconnects, bridges, buffers leaving some rare chances for the actual write to complete out of order. GICv3 ICC EOI system register writes have no ordering against nGnR(n)E memory writes as they are over different interfaces. Hence a dsb can ensure from core no writes are issued before the previous writes are *complete*. Signed-off-by: Sandeep Tripathy Change-Id: Ie6362009e2f91955be99dca8ece14ade7b4811d6 --- drivers/arm/gic/v2/gicv2_main.c | 9 +++++++++ include/drivers/arm/gicv3.h | 24 ++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/drivers/arm/gic/v2/gicv2_main.c b/drivers/arm/gic/v2/gicv2_main.c index c5bced00d..4b21b920a 100644 --- a/drivers/arm/gic/v2/gicv2_main.c +++ b/drivers/arm/gic/v2/gicv2_main.c @@ -247,6 +247,15 @@ void gicv2_end_of_interrupt(unsigned int id) assert(driver_data != NULL); assert(driver_data->gicc_base != 0U); + /* + * Ensure the write to peripheral registers are *complete* before the write + * to GIC_EOIR. + * + * Note: The completion gurantee depends on various factors of system design + * and the barrier is the best core can do by which execution of further + * instructions waits till the barrier is alive. + */ + dsbishst(); gicc_write_EOIR(driver_data->gicc_base, id); } diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h index 77dc350dd..97b75b0da 100644 --- a/include/drivers/arm/gicv3.h +++ b/include/drivers/arm/gicv3.h @@ -332,6 +332,18 @@ static inline uint32_t gicv3_get_pending_interrupt_id_sel1(void) static inline void gicv3_end_of_interrupt_sel1(unsigned int id) { + /* + * Interrupt request deassertion from peripheral to GIC happens + * by clearing interrupt condition by a write to the peripheral + * register. It is desired that the write transfer is complete + * before the core tries to change GIC state from 'AP/Active' to + * a new state on seeing 'EOI write'. + * Since ICC interface writes are not ordered against Device + * memory writes, a barrier is required to ensure the ordering. + * The dsb will also ensure *completion* of previous writes with + * DEVICE nGnRnE attribute. + */ + dsbishst(); write_icc_eoir1_el1(id); } @@ -345,6 +357,18 @@ static inline uint32_t gicv3_acknowledge_interrupt(void) static inline void gicv3_end_of_interrupt(unsigned int id) { + /* + * Interrupt request deassertion from peripheral to GIC happens + * by clearing interrupt condition by a write to the peripheral + * register. It is desired that the write transfer is complete + * before the core tries to change GIC state from 'AP/Active' to + * a new state on seeing 'EOI write'. + * Since ICC interface writes are not ordered against Device + * memory writes, a barrier is required to ensure the ordering. + * The dsb will also ensure *completion* of previous writes with + * DEVICE nGnRnE attribute. + */ + dsbishst(); return write_icc_eoir0_el1(id); } -- cgit v1.2.3 From d7b08e69044611c13f2691011a0dc02383106474 Mon Sep 17 00:00:00 2001 From: johpow01 Date: Fri, 29 May 2020 14:17:38 -0500 Subject: Workaround for Cortex A76 erratum 1791580 Cortex A76 erratum 1791580 is a Cat B erratum present in earlier revisions of the Cortex A76. The workaround is to set a bit in the implementation defined CPUACTLR2 register, which forces atomic store operations to write-back memory to be performed in the L1 data cache. This errata is explained in this SDEN: https://static.docs.arm.com/sden885749/g/Arm_Cortex_A76_MP052_Software_Developer_Errata_Notice_v20.pdf Signed-off-by: John Powell Change-Id: Iefd58159b3f2e2286138993317b98e57dc361925 --- docs/design/cpu-specific-build-macros.rst | 3 +++ include/lib/cpus/aarch64/cortex_a76.h | 4 +++- lib/cpus/aarch64/cortex_a76.S | 33 +++++++++++++++++++++++++++++++ lib/cpus/cpu-ops.mk | 8 ++++++++ 4 files changed, 47 insertions(+), 1 deletion(-) diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst index 591f2f886..53da6885a 100644 --- a/docs/design/cpu-specific-build-macros.rst +++ b/docs/design/cpu-specific-build-macros.rst @@ -227,6 +227,9 @@ For Cortex-A76, the following errata build flags are defined : - ``ERRATA_A76_1275112``: This applies errata 1275112 workaround to Cortex-A76 CPU. This needs to be enabled only for revision <= r3p0 of the CPU. +- ``ERRATA_A76_1791580``: This applies errata 1791580 workaround to Cortex-A76 + CPU. This needs to be enabled only for revision <= r4p0 of the CPU. + For Cortex-A78, the following errata build flags are defined : - ``ERRATA_A78_1688305``: This applies errata 1688305 workaround to Cortex-A78 diff --git a/include/lib/cpus/aarch64/cortex_a76.h b/include/lib/cpus/aarch64/cortex_a76.h index 7dc7e068a..a61825f1b 100644 --- a/include/lib/cpus/aarch64/cortex_a76.h +++ b/include/lib/cpus/aarch64/cortex_a76.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -32,6 +32,8 @@ #define CORTEX_A76_CPUACTLR2_EL1 S3_0_C15_C1_1 +#define CORTEX_A76_CPUACTLR2_EL1_BIT_2 (ULL(1) << 2) + #define CORTEX_A76_CPUACTLR2_EL1_DISABLE_LOAD_PASS_STORE (ULL(1) << 16) #define CORTEX_A76_CPUACTLR3_EL1 S3_0_C15_C1_2 diff --git a/lib/cpus/aarch64/cortex_a76.S b/lib/cpus/aarch64/cortex_a76.S index baefa4676..3a0139a20 100644 --- a/lib/cpus/aarch64/cortex_a76.S +++ b/lib/cpus/aarch64/cortex_a76.S @@ -392,6 +392,33 @@ func check_errata_1286807 #endif endfunc check_errata_1286807 + /* -------------------------------------------------- + * Errata workaround for Cortex A76 Errata #1791580. + * This applies to revisions <= r4p0 of Cortex A76. + * Inputs: + * x0: variant[4:7] and revision[0:3] of current cpu. + * Shall clobber: x0-x17 + * -------------------------------------------------- + */ +func errata_a76_1791580_wa + /* Compare x0 against revision r4p0 */ + mov x17, x30 + bl check_errata_1791580 + cbz x0, 1f + mrs x1, CORTEX_A76_CPUACTLR2_EL1 + orr x1, x1, CORTEX_A76_CPUACTLR2_EL1_BIT_2 + msr CORTEX_A76_CPUACTLR2_EL1, x1 + isb +1: + ret x17 +endfunc errata_a76_1791580_wa + +func check_errata_1791580 + /* Applies to everything <=r4p0. */ + mov x1, #0x40 + b cpu_rev_var_ls +endfunc check_errata_1791580 + func check_errata_cve_2018_3639 #if WORKAROUND_CVE_2018_3639 mov x0, #ERRATA_APPLIES @@ -449,6 +476,11 @@ func cortex_a76_reset_func bl errata_a76_1262888_wa #endif +#if ERRATA_A76_1791580 + mov x0, x18 + bl errata_a76_1791580_wa +#endif + #if WORKAROUND_CVE_2018_3639 /* If the PE implements SSBS, we don't need the dynamic workaround */ mrs x0, id_aa64pfr1_el1 @@ -529,6 +561,7 @@ func cortex_a76_errata_report report_errata ERRATA_A76_1262888, cortex_a76, 1262888 report_errata ERRATA_A76_1275112, cortex_a76, 1275112 report_errata ERRATA_A76_1286807, cortex_a76, 1286807 + report_errata ERRATA_A76_1791580, cortex_a76, 1791580 report_errata WORKAROUND_CVE_2018_3639, cortex_a76, cve_2018_3639 report_errata ERRATA_DSU_798953, cortex_a76, dsu_798953 report_errata ERRATA_DSU_936184, cortex_a76, dsu_936184 diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk index 1bc082d82..97db7340c 100644 --- a/lib/cpus/cpu-ops.mk +++ b/lib/cpus/cpu-ops.mk @@ -250,6 +250,10 @@ ERRATA_A76_1275112 ?=0 # only to revision <= r3p0 of the Cortex A76 cpu. ERRATA_A76_1286807 ?=0 +# Flag to apply erratum 1791580 workaround during reset. This erratum applies +# only to revision <= r4p0 of the Cortex A76 cpu. +ERRATA_A76_1791580 ?=0 + # Flag to apply erratum 1688305 workaround during reset. This erratum applies # to revisions r0p0 - r1p0 of the A78 cpu. ERRATA_A78_1688305 ?=0 @@ -487,6 +491,10 @@ $(eval $(call add_define,ERRATA_A76_1275112)) $(eval $(call assert_boolean,ERRATA_A76_1286807)) $(eval $(call add_define,ERRATA_A76_1286807)) +# Process ERRATA_A76_1791580 flag +$(eval $(call assert_boolean,ERRATA_A76_1791580)) +$(eval $(call add_define,ERRATA_A76_1791580)) + # Process ERRATA_A78_1688305 flag $(eval $(call assert_boolean,ERRATA_A78_1688305)) $(eval $(call add_define,ERRATA_A78_1688305)) -- cgit v1.2.3 From dcbfbcb5de2c0110cf397dae62a4f6cf7ad2a6a2 Mon Sep 17 00:00:00 2001 From: johpow01 Date: Tue, 2 Jun 2020 15:02:28 -0500 Subject: Workaround for Cortex A76 erratum 1800710 Cortex A76 erratum 1800710 is a Cat B erratum, present in older revisions of the Cortex A76 processor core. The workaround is to set a bit in the ECTLR_EL1 system register, which disables allocation of splintered pages in the L2 TLB. This errata is explained in this SDEN: https://static.docs.arm.com/sden885749/g/Arm_Cortex_A76_MP052_Software_Developer_Errata_Notice_v20.pdf Signed-off-by: John Powell Change-Id: Ifc34f2e9e053dcee6a108cfb7df7ff7f497c9493 --- docs/design/cpu-specific-build-macros.rst | 3 +++ include/lib/cpus/aarch64/cortex_a76.h | 1 + lib/cpus/aarch64/cortex_a76.S | 35 +++++++++++++++++++++++++++++++ lib/cpus/cpu-ops.mk | 8 +++++++ 4 files changed, 47 insertions(+) diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst index 53da6885a..264d0c688 100644 --- a/docs/design/cpu-specific-build-macros.rst +++ b/docs/design/cpu-specific-build-macros.rst @@ -230,6 +230,9 @@ For Cortex-A76, the following errata build flags are defined : - ``ERRATA_A76_1791580``: This applies errata 1791580 workaround to Cortex-A76 CPU. This needs to be enabled only for revision <= r4p0 of the CPU. +- ``ERRATA_A76_1800710``: This applies errata 1800710 workaround to Cortex-A76 + CPU. This needs to be enabled only for revision <= r4p0 of the CPU. + For Cortex-A78, the following errata build flags are defined : - ``ERRATA_A78_1688305``: This applies errata 1688305 workaround to Cortex-A78 diff --git a/include/lib/cpus/aarch64/cortex_a76.h b/include/lib/cpus/aarch64/cortex_a76.h index a61825f1b..b522e8e11 100644 --- a/include/lib/cpus/aarch64/cortex_a76.h +++ b/include/lib/cpus/aarch64/cortex_a76.h @@ -20,6 +20,7 @@ #define CORTEX_A76_CPUECTLR_EL1_WS_THR_L2 (ULL(3) << 24) #define CORTEX_A76_CPUECTLR_EL1_BIT_51 (ULL(1) << 51) +#define CORTEX_A76_CPUECTLR_EL1_BIT_53 (ULL(1) << 53) /******************************************************************************* * CPU Auxiliary Control register specific definitions. diff --git a/lib/cpus/aarch64/cortex_a76.S b/lib/cpus/aarch64/cortex_a76.S index 3a0139a20..10011f754 100644 --- a/lib/cpus/aarch64/cortex_a76.S +++ b/lib/cpus/aarch64/cortex_a76.S @@ -419,6 +419,35 @@ func check_errata_1791580 b cpu_rev_var_ls endfunc check_errata_1791580 + /* -------------------------------------------------- + * Errata Workaround for Cortex A76 Errata #1800710. + * This applies to revision <= r4p0 of Cortex A76. + * Inputs: + * x0: variant[4:7] and revision[0:3] of current cpu. + * Shall clobber: x0-x17 + * -------------------------------------------------- + */ +func errata_a76_1800710_wa + /* Compare x0 against revision <= r4p0 */ + mov x17, x30 + bl check_errata_1800710 + cbz x0, 1f + + /* Disable allocation of splintered pages in the L2 TLB */ + mrs x1, CORTEX_A76_CPUECTLR_EL1 + orr x1, x1, CORTEX_A76_CPUECTLR_EL1_BIT_53 + msr CORTEX_A76_CPUECTLR_EL1, x1 + isb +1: + ret x17 +endfunc errata_a76_1800710_wa + +func check_errata_1800710 + /* Applies to everything <= r4p0 */ + mov x1, #0x40 + b cpu_rev_var_ls +endfunc check_errata_1800710 + func check_errata_cve_2018_3639 #if WORKAROUND_CVE_2018_3639 mov x0, #ERRATA_APPLIES @@ -481,6 +510,11 @@ func cortex_a76_reset_func bl errata_a76_1791580_wa #endif +#if ERRATA_A76_1800710 + mov x0, x18 + bl errata_a76_1800710_wa +#endif + #if WORKAROUND_CVE_2018_3639 /* If the PE implements SSBS, we don't need the dynamic workaround */ mrs x0, id_aa64pfr1_el1 @@ -562,6 +596,7 @@ func cortex_a76_errata_report report_errata ERRATA_A76_1275112, cortex_a76, 1275112 report_errata ERRATA_A76_1286807, cortex_a76, 1286807 report_errata ERRATA_A76_1791580, cortex_a76, 1791580 + report_errata ERRATA_A76_1800710, cortex_a76, 1800710 report_errata WORKAROUND_CVE_2018_3639, cortex_a76, cve_2018_3639 report_errata ERRATA_DSU_798953, cortex_a76, dsu_798953 report_errata ERRATA_DSU_936184, cortex_a76, dsu_936184 diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk index 97db7340c..e80900056 100644 --- a/lib/cpus/cpu-ops.mk +++ b/lib/cpus/cpu-ops.mk @@ -254,6 +254,10 @@ ERRATA_A76_1286807 ?=0 # only to revision <= r4p0 of the Cortex A76 cpu. ERRATA_A76_1791580 ?=0 +# Flag to apply erratum 1800710 workaround during reset. This erratum applies +# only to revision <= r4p0 of the Cortex A76 cpu. +ERRATA_A76_1800710 ?=0 + # Flag to apply erratum 1688305 workaround during reset. This erratum applies # to revisions r0p0 - r1p0 of the A78 cpu. ERRATA_A78_1688305 ?=0 @@ -495,6 +499,10 @@ $(eval $(call add_define,ERRATA_A76_1286807)) $(eval $(call assert_boolean,ERRATA_A76_1791580)) $(eval $(call add_define,ERRATA_A76_1791580)) +# Process ERRATA_A76_1800710 flag +$(eval $(call assert_boolean,ERRATA_A76_1800710)) +$(eval $(call add_define,ERRATA_A76_1800710)) + # Process ERRATA_A78_1688305 flag $(eval $(call assert_boolean,ERRATA_A78_1688305)) $(eval $(call add_define,ERRATA_A78_1688305)) -- cgit v1.2.3 From 47cf5d3f28f4d9bf1912c0470eac01599dd4a7c8 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Sun, 8 Dec 2019 08:14:03 +0100 Subject: stm32mp1: introduce shared resources support STM32MP1 SoC includes peripheral interfaces that can be assigned to the secure world, or that can be opened to the non-secure world. This change introduces the basics of a driver that manages such resources which assignation is done at run time. It currently offers API functions that state whether a service exposed to non-secure world has permission to access a targeted clock or reset controller. Change-Id: Iff20028f41586bc501085488c03546ffe31046d8 Signed-off-by: Etienne Carriere --- plat/st/common/include/stm32mp_shared_resources.h | 18 ++++++++++++++++++ plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk | 3 +++ plat/st/stm32mp1/stm32mp1_shared_resources.c | 19 +++++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 plat/st/common/include/stm32mp_shared_resources.h create mode 100644 plat/st/stm32mp1/stm32mp1_shared_resources.c diff --git a/plat/st/common/include/stm32mp_shared_resources.h b/plat/st/common/include/stm32mp_shared_resources.h new file mode 100644 index 000000000..2ab42ef45 --- /dev/null +++ b/plat/st/common/include/stm32mp_shared_resources.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef STM32MP_SHARED_RESOURCES_H +#define STM32MP_SHARED_RESOURCES_H + +#include + +/* Return true if @clock_id is shared by secure and non-secure worlds */ +bool stm32mp_nsec_can_access_clock(unsigned long clock_id); + +/* Return true if and only if @reset_id relates to a non-secure peripheral */ +bool stm32mp_nsec_can_access_reset(unsigned int reset_id); + +#endif /* STM32MP_SHARED_RESOURCES_H */ diff --git a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk index 180620e88..913a486e3 100644 --- a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk +++ b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk @@ -6,10 +6,13 @@ SP_MIN_WITH_SECURE_FIQ := 1 +BL32_CFLAGS += -DSTM32MP_SHARED_RESOURCES + BL32_SOURCES += drivers/st/etzpc/etzpc.c \ plat/common/aarch32/platform_mp_stack.S \ plat/st/stm32mp1/sp_min/sp_min_setup.c \ plat/st/stm32mp1/stm32mp1_pm.c \ + plat/st/stm32mp1/stm32mp1_shared_resources.c \ plat/st/stm32mp1/stm32mp1_topology.c # Generic GIC v2 diff --git a/plat/st/stm32mp1/stm32mp1_shared_resources.c b/plat/st/stm32mp1/stm32mp1_shared_resources.c new file mode 100644 index 000000000..a68615298 --- /dev/null +++ b/plat/st/stm32mp1/stm32mp1_shared_resources.c @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +/* Currently allow full access by non-secure to platform clock services */ +bool stm32mp_nsec_can_access_clock(unsigned long clock_id) +{ + return true; +} + +/* Currently allow full access by non-secure to platform reset services */ +bool stm32mp_nsec_can_access_reset(unsigned int reset_id) +{ + return true; +} -- cgit v1.2.3 From eafe0eb066239eef1dbb8f391774552bd91d4b90 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Mon, 2 Dec 2019 10:08:48 +0100 Subject: stm32mp1: shared resources: define resource identifiers Define enum stm32mp_shres for platform stm32mp1. The enumerated type defines all resources that can be assigned to secure or non-secure worlds at run time for the platform. Change-Id: I5de20d72735856645f1efd0993643278e8d35bcb Signed-off-by: Etienne Carriere --- .../stm32mp1/include/stm32mp1_shared_resources.h | 38 ++++++++++++++++++++++ plat/st/stm32mp1/stm32mp1_def.h | 1 + 2 files changed, 39 insertions(+) create mode 100644 plat/st/stm32mp1/include/stm32mp1_shared_resources.h diff --git a/plat/st/stm32mp1/include/stm32mp1_shared_resources.h b/plat/st/stm32mp1/include/stm32mp1_shared_resources.h new file mode 100644 index 000000000..3f6367ebe --- /dev/null +++ b/plat/st/stm32mp1/include/stm32mp1_shared_resources.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef STM32MP1_SHARED_RESOURCES_H +#define STM32MP1_SHARED_RESOURCES_H + +#include + +#define STM32MP1_SHRES_GPIOZ(i) (STM32MP1_SHRES_GPIOZ_0 + (i)) + +enum stm32mp_shres { + STM32MP1_SHRES_CRYP1, + STM32MP1_SHRES_GPIOZ_0, + STM32MP1_SHRES_GPIOZ_1, + STM32MP1_SHRES_GPIOZ_2, + STM32MP1_SHRES_GPIOZ_3, + STM32MP1_SHRES_GPIOZ_4, + STM32MP1_SHRES_GPIOZ_5, + STM32MP1_SHRES_GPIOZ_6, + STM32MP1_SHRES_GPIOZ_7, + STM32MP1_SHRES_HASH1, + STM32MP1_SHRES_I2C4, + STM32MP1_SHRES_I2C6, + STM32MP1_SHRES_IWDG1, + STM32MP1_SHRES_MCU, + STM32MP1_SHRES_MDMA, + STM32MP1_SHRES_PLL3, + STM32MP1_SHRES_RNG1, + STM32MP1_SHRES_RTC, + STM32MP1_SHRES_SPI6, + STM32MP1_SHRES_USART1, + + STM32MP1_SHRES_COUNT +}; +#endif /* STM32MP1_SHARED_RESOURCES_H */ diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h index 0a12b6e57..4d3c62b99 100644 --- a/plat/st/stm32mp1/stm32mp1_def.h +++ b/plat/st/stm32mp1/stm32mp1_def.h @@ -25,6 +25,7 @@ #include #include #include +#include #endif /******************************************************************************* -- cgit v1.2.3 From 722999e3b574ed90d03e12a4deea94d6f343c284 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Wed, 13 May 2020 10:13:54 +0200 Subject: stm32mp1: shared resources: count GPIOZ bank pins Get number of pins in the GPIOZ bank with helper function fdt_get_gpio_bank_pin_count(). Save the value in RAM to prevent parsing the FDT several time for the same information. Change-Id: Ie68e300804461ffce09914100a7d2962116023b5 Signed-off-by: Etienne Carriere --- plat/st/stm32mp1/stm32mp1_shared_resources.c | 37 ++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/plat/st/stm32mp1/stm32mp1_shared_resources.c b/plat/st/stm32mp1/stm32mp1_shared_resources.c index a68615298..18606818c 100644 --- a/plat/st/stm32mp1/stm32mp1_shared_resources.c +++ b/plat/st/stm32mp1/stm32mp1_shared_resources.c @@ -4,8 +4,45 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include +#include + +#include + +#include +#include + #include +/* GPIOZ pin count is saved in RAM to prevent parsing FDT several times */ +static int8_t gpioz_nbpin = -1; + +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))); + + return (unsigned int)count; + } + + if (gpioz_nbpin < 0) { + int count = fdt_get_gpio_bank_pin_count(GPIO_BANK_Z); + + assert((count == 0) || (count == STM32MP_GPIOZ_PIN_MAX_COUNT)); + + gpioz_nbpin = count; + } + + return (unsigned int)gpioz_nbpin; +} + +static unsigned int __unused get_gpioz_nbpin(void) +{ + return get_gpio_nbpin(GPIO_BANK_Z); +} + /* Currently allow full access by non-secure to platform clock services */ bool stm32mp_nsec_can_access_clock(unsigned long clock_id) { -- cgit v1.2.3 From 5f038ac6836359b3422a5b70e52733c6029f61b2 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Wed, 13 May 2020 10:07:45 +0200 Subject: stm32mp1: shared resources: apply registered configuration BL32/SP_MIN configures platform security hardening from the shared resources driver. At the end of SP_MIN initialization, all shared resources shall be assigned to secure or non-secure world by drivers. A lock prevent from further change on the resource assignation. By definition, resources not registered are assign to non-secure world since not claimed by any component on the BL. No functional change as all resources are currently in state SHRES_UNREGISTERED hence assigned to non-secure world as prior this change in stm32mp1_etzpc_early_setup() and sp_min_platform_setup(). Change-Id: Ic41fab47216c3b8b7a6a75b8358cfcec411ed941 Signed-off-by: Etienne Carriere --- plat/st/common/include/stm32mp_shared_resources.h | 3 + plat/st/stm32mp1/sp_min/sp_min_setup.c | 14 +- plat/st/stm32mp1/stm32mp1_shared_resources.c | 172 +++++++++++++++++++++- 3 files changed, 176 insertions(+), 13 deletions(-) diff --git a/plat/st/common/include/stm32mp_shared_resources.h b/plat/st/common/include/stm32mp_shared_resources.h index 2ab42ef45..b1486667f 100644 --- a/plat/st/common/include/stm32mp_shared_resources.h +++ b/plat/st/common/include/stm32mp_shared_resources.h @@ -15,4 +15,7 @@ bool stm32mp_nsec_can_access_clock(unsigned long clock_id); /* Return true if and only if @reset_id relates to a non-secure peripheral */ bool stm32mp_nsec_can_access_reset(unsigned int reset_id); +/* Consolidate peripheral states and lock against new peripheral registering */ +void stm32mp_lock_periph_registering(void); + #endif /* STM32MP_SHARED_RESOURCES_H */ diff --git a/plat/st/stm32mp1/sp_min/sp_min_setup.c b/plat/st/stm32mp1/sp_min/sp_min_setup.c index e1799eda6..e2c2b2060 100644 --- a/plat/st/stm32mp1/sp_min/sp_min_setup.c +++ b/plat/st/stm32mp1/sp_min/sp_min_setup.c @@ -82,19 +82,12 @@ entry_point_info_t *sp_min_plat_get_bl33_ep_info(void) static void stm32mp1_etzpc_early_setup(void) { - unsigned int n; - if (etzpc_init() != 0) { panic(); } etzpc_configure_tzma(STM32MP1_ETZPC_TZMA_ROM, TZMA0_SECURE_RANGE); etzpc_configure_tzma(STM32MP1_ETZPC_TZMA_SYSRAM, TZMA1_SECURE_RANGE); - - /* Release security on all shared resources */ - for (n = 0; n < STM32MP1_ETZPC_SEC_ID_LIMIT; n++) { - etzpc_configure_decprot(n, ETZPC_DECPROT_NS_RW); - } } /******************************************************************************* @@ -181,14 +174,11 @@ void sp_min_platform_setup(void) stm32mp1_gic_init(); - /* Set GPIO bank Z as non secure */ - for (uint32_t pin = 0U; pin < STM32MP_GPIOZ_PIN_MAX_COUNT; pin++) { - set_gpio_secure_cfg(GPIO_BANK_Z, pin, false); - } - if (stm32_iwdg_init() < 0) { panic(); } + + stm32mp_lock_periph_registering(); } void sp_min_plat_arch_setup(void) diff --git a/plat/st/stm32mp1/stm32mp1_shared_resources.c b/plat/st/stm32mp1/stm32mp1_shared_resources.c index 18606818c..268aa52c3 100644 --- a/plat/st/stm32mp1/stm32mp1_shared_resources.c +++ b/plat/st/stm32mp1/stm32mp1_shared_resources.c @@ -10,10 +10,59 @@ #include #include +#include #include #include +/* + * Once one starts to get the resource registering state, one cannot register + * new resources. This ensures resource state cannot change. + */ +static bool registering_locked; + +/* + * Shared peripherals and resources registration + * + * Each resource assignation is stored in a table. The state defaults + * to PERIPH_UNREGISTERED if the resource is not explicitly assigned. + * + * Resource driver that as not embedded (a.k.a their related CFG_xxx build + * directive is disabled) are assigned to the non-secure world. + * + * Each pin of the GPIOZ bank can be secure or non-secure. + * + * It is the platform responsibility the ensure resource assignation + * matches the access permission firewalls configuration. + */ +enum shres_state { + SHRES_UNREGISTERED = 0, + SHRES_SECURE, + SHRES_NON_SECURE, +}; + +/* Force uint8_t array for array of enum shres_state for size considerations */ +static uint8_t shres_state[STM32MP1_SHRES_COUNT]; + +/* Get resource state: these accesses lock the registering support */ +static void lock_registering(void) +{ + registering_locked = true; +} + +static bool periph_is_non_secure(enum stm32mp_shres id) +{ + lock_registering(); + + return (shres_state[id] == SHRES_NON_SECURE) || + (shres_state[id] == SHRES_UNREGISTERED); +} + +static bool periph_is_secure(enum stm32mp_shres id) +{ + return !periph_is_non_secure(id); +} + /* GPIOZ pin count is saved in RAM to prevent parsing FDT several times */ static int8_t gpioz_nbpin = -1; @@ -38,7 +87,7 @@ static unsigned int get_gpio_nbpin(unsigned int bank) return (unsigned int)gpioz_nbpin; } -static unsigned int __unused get_gpioz_nbpin(void) +static unsigned int get_gpioz_nbpin(void) { return get_gpio_nbpin(GPIO_BANK_Z); } @@ -54,3 +103,124 @@ bool stm32mp_nsec_can_access_reset(unsigned int reset_id) { return true; } + +static bool mckprot_protects_periph(enum stm32mp_shres id) +{ + switch (id) { + case STM32MP1_SHRES_MCU: + case STM32MP1_SHRES_PLL3: + return true; + default: + return false; + } +} + +/* ETZPC configuration at drivers initialization completion */ +static enum etzpc_decprot_attributes shres2decprot_attr(enum stm32mp_shres id) +{ + assert((id < STM32MP1_SHRES_GPIOZ(0)) || + (id > STM32MP1_SHRES_GPIOZ(7))); + + if (periph_is_non_secure(id)) { + return ETZPC_DECPROT_NS_RW; + } + + return ETZPC_DECPROT_S_RW; +} + +static void set_etzpc_secure_configuration(void) +{ + /* Some system peripherals shall be secure */ + etzpc_configure_decprot(STM32MP1_ETZPC_STGENC_ID, ETZPC_DECPROT_S_RW); + etzpc_configure_decprot(STM32MP1_ETZPC_BKPSRAM_ID, ETZPC_DECPROT_S_RW); + etzpc_configure_decprot(STM32MP1_ETZPC_DDRCTRL_ID, + ETZPC_DECPROT_NS_R_S_W); + etzpc_configure_decprot(STM32MP1_ETZPC_DDRPHYC_ID, + ETZPC_DECPROT_NS_R_S_W); + + /* Configure ETZPC with peripheral registering */ + etzpc_configure_decprot(STM32MP1_ETZPC_CRYP1_ID, + shres2decprot_attr(STM32MP1_SHRES_CRYP1)); + etzpc_configure_decprot(STM32MP1_ETZPC_HASH1_ID, + shres2decprot_attr(STM32MP1_SHRES_HASH1)); + etzpc_configure_decprot(STM32MP1_ETZPC_I2C4_ID, + shres2decprot_attr(STM32MP1_SHRES_I2C4)); + etzpc_configure_decprot(STM32MP1_ETZPC_I2C6_ID, + shres2decprot_attr(STM32MP1_SHRES_I2C6)); + etzpc_configure_decprot(STM32MP1_ETZPC_IWDG1_ID, + shres2decprot_attr(STM32MP1_SHRES_IWDG1)); + etzpc_configure_decprot(STM32MP1_ETZPC_RNG1_ID, + shres2decprot_attr(STM32MP1_SHRES_RNG1)); + etzpc_configure_decprot(STM32MP1_ETZPC_USART1_ID, + shres2decprot_attr(STM32MP1_SHRES_USART1)); + etzpc_configure_decprot(STM32MP1_ETZPC_SPI6_ID, + shres2decprot_attr(STM32MP1_SHRES_SPI6)); +} + +static void check_rcc_secure_configuration(void) +{ + uint32_t n; + uint32_t error = 0U; + bool mckprot = stm32mp1_rcc_is_mckprot(); + bool secure = stm32mp1_rcc_is_secure(); + + for (n = 0U; n < ARRAY_SIZE(shres_state); n++) { + if (shres_state[n] != SHRES_SECURE) { + continue; + } + + if (!secure || (mckprot_protects_periph(n) && (!mckprot))) { + ERROR("RCC %s MCKPROT %s and %u secure\n", + secure ? "secure" : "non-secure", + mckprot ? "set" : "not set", + n); + error++; + } + } + + if (error != 0U) { + panic(); + } +} + +static void set_gpio_secure_configuration(void) +{ + uint32_t pin; + + for (pin = 0U; pin < get_gpioz_nbpin(); pin++) { + bool secure_state = periph_is_secure(STM32MP1_SHRES_GPIOZ(pin)); + + set_gpio_secure_cfg(GPIO_BANK_Z, pin, secure_state); + } +} + +static void print_shared_resources_state(void) +{ + unsigned int id; + + for (id = 0U; id < STM32MP1_SHRES_COUNT; id++) { + switch (shres_state[id]) { + case SHRES_SECURE: + INFO("stm32mp1 %u is secure\n", id); + break; + case SHRES_NON_SECURE: + case SHRES_UNREGISTERED: + VERBOSE("stm32mp %u is non-secure\n", id); + break; + default: + VERBOSE("stm32mp %u is invalid\n", id); + panic(); + } + } +} + +void stm32mp_lock_periph_registering(void) +{ + registering_locked = true; + + print_shared_resources_state(); + + check_rcc_secure_configuration(); + set_etzpc_secure_configuration(); + set_gpio_secure_configuration(); +} -- cgit v1.2.3 From e4ee1ab934e24f644f16935ab2007e36cbabd361 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Fri, 10 Apr 2020 18:51:54 +0200 Subject: stm32mp1: disable neon in sp_min Disable use of Neon VFP support for platform stm32mp1 when building with SP_MIN runtime services as these can conflict with non-secure world use of NEON support. This is preferred over a systematic backup/restore of NEON context when switching between non-secure and secure worlds. When NEON support is disabled, this is done for both BL2 and BL32 as build process uses common libraries built once for both binaries. Change-Id: I4e8808dcb6ef58fc839e6f85fd6e45cfbaa34be0 Signed-off-by: Etienne Carriere --- plat/st/stm32mp1/platform.mk | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk index b0ba82abf..999823617 100644 --- a/plat/st/stm32mp1/platform.mk +++ b/plat/st/stm32mp1/platform.mk @@ -16,6 +16,11 @@ PLAT_XLAT_TABLES_DYNAMIC := 1 $(eval $(call assert_boolean,PLAT_XLAT_TABLES_DYNAMIC)) $(eval $(call add_define,PLAT_XLAT_TABLES_DYNAMIC)) +ifeq ($(AARCH32_SP),sp_min) +# Disable Neon support: sp_min runtime may conflict with non-secure world +TF_CFLAGS += -mfloat-abi=soft +endif + # Not needed for Cortex-A7 WORKAROUND_CVE_2017_5715:= 0 -- cgit v1.2.3 From 986419939a3fcddbb524dccd90c139473396d057 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Mon, 8 Jun 2020 20:25:08 +0200 Subject: stm32mp1: check stronger the secondary CPU entry point When using SP_min as monitor, only sp_min_warm_entrypoint() is a valid secure entry point. Change-Id: I440cec798e901b11a34dd482c33b2e378a8328ab Signed-off-by: Etienne Carriere Signed-off-by: Nicolas Toromanoff --- plat/st/stm32mp1/stm32mp1_pm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plat/st/stm32mp1/stm32mp1_pm.c b/plat/st/stm32mp1/stm32mp1_pm.c index cf9fa8e69..31a9ae7f1 100644 --- a/plat/st/stm32mp1/stm32mp1_pm.c +++ b/plat/st/stm32mp1/stm32mp1_pm.c @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -68,9 +69,8 @@ static int stm32_pwr_domain_on(u_register_t mpidr) return PSCI_E_INVALID_PARAMS; } - if ((stm32_sec_entrypoint < STM32MP_SYSRAM_BASE) || - (stm32_sec_entrypoint > (STM32MP_SYSRAM_BASE + - (STM32MP_SYSRAM_SIZE - 1)))) { + /* Only one valid entry point */ + if (stm32_sec_entrypoint != (uintptr_t)&sp_min_warm_entrypoint) { return PSCI_E_INVALID_ADDRESS; } -- cgit v1.2.3 From 0754143ac9934f201d60f1a67cf0348c13da2c44 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Sun, 8 Dec 2019 08:17:56 +0100 Subject: stm32mp1: use last page of SYSRAM as SCMI shared memory SCMI shared memory is used to exchange message payloads between secure SCMI services and non-secure SCMI agents. It is mapped uncached (device) mainly to conform to existing support in the Linux kernel. Note that executive messages are mostly short (few 32bit words) hence not using cache will not penalize much performances. Platform stm32mp1 shall configure ETZPC to harden properly the secure and non-secure areas of the SYSRAM address space, that before CPU accesses the shared memory when mapped non-secure. This change defines STM32MP_SEC_SYSRAM_BASE/STM32MP_SEC_SYSRAM_SIZE and STM32MP_NS_SYSRAM_BASE/STM32MP_NS_SYSRAM_SIZE. Change-Id: I71ff02a359b9668ae1c5a71b5f102cf3d310f289 Signed-off-by: Etienne Carriere --- plat/st/stm32mp1/sp_min/sp_min_setup.c | 18 ++++++++++++++++++ plat/st/stm32mp1/stm32mp1_def.h | 19 ++++++++++++++----- plat/st/stm32mp1/stm32mp1_private.c | 24 +++++++++++++++++++++--- 3 files changed, 53 insertions(+), 8 deletions(-) diff --git a/plat/st/stm32mp1/sp_min/sp_min_setup.c b/plat/st/stm32mp1/sp_min/sp_min_setup.c index e1799eda6..1f96239c8 100644 --- a/plat/st/stm32mp1/sp_min/sp_min_setup.c +++ b/plat/st/stm32mp1/sp_min/sp_min_setup.c @@ -77,7 +77,25 @@ entry_point_info_t *sp_min_plat_get_bl33_ep_info(void) return next_image_info; } +CASSERT((STM32MP_SEC_SYSRAM_BASE == STM32MP_SYSRAM_BASE) && + ((STM32MP_SEC_SYSRAM_BASE + STM32MP_SEC_SYSRAM_SIZE) <= + (STM32MP_SYSRAM_BASE + STM32MP_SYSRAM_SIZE)), + assert_secure_sysram_fits_at_begining_of_sysram); + +#ifdef STM32MP_NS_SYSRAM_BASE +CASSERT((STM32MP_NS_SYSRAM_BASE >= STM32MP_SEC_SYSRAM_BASE) && + ((STM32MP_NS_SYSRAM_BASE + STM32MP_NS_SYSRAM_SIZE) == + (STM32MP_SYSRAM_BASE + STM32MP_SYSRAM_SIZE)), + assert_non_secure_sysram_fits_at_end_of_sysram); + +CASSERT((STM32MP_NS_SYSRAM_BASE & (PAGE_SIZE_4KB - U(1))) == 0U, + assert_non_secure_sysram_base_is_4kbyte_aligned); + +#define TZMA1_SECURE_RANGE \ + (((STM32MP_NS_SYSRAM_BASE - STM32MP_SYSRAM_BASE) >> FOUR_KB_SHIFT) - 1U) +#else #define TZMA1_SECURE_RANGE STM32MP1_ETZPC_TZMA_ALL_SECURE +#endif /* STM32MP_NS_SYSRAM_BASE */ #define TZMA0_SECURE_RANGE STM32MP1_ETZPC_TZMA_ALL_SECURE static void stm32mp1_etzpc_early_setup(void) diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h index 0a12b6e57..4fae2d70c 100644 --- a/plat/st/stm32mp1/stm32mp1_def.h +++ b/plat/st/stm32mp1/stm32mp1_def.h @@ -56,6 +56,15 @@ #define STM32MP_SYSRAM_BASE U(0x2FFC0000) #define STM32MP_SYSRAM_SIZE U(0x00040000) +#define STM32MP_NS_SYSRAM_SIZE PAGE_SIZE +#define STM32MP_NS_SYSRAM_BASE (STM32MP_SYSRAM_BASE + \ + STM32MP_SYSRAM_SIZE - \ + STM32MP_NS_SYSRAM_SIZE) + +#define STM32MP_SEC_SYSRAM_BASE STM32MP_SYSRAM_BASE +#define STM32MP_SEC_SYSRAM_SIZE (STM32MP_SYSRAM_SIZE - \ + STM32MP_NS_SYSRAM_SIZE) + /* DDR configuration */ #define STM32MP_DDR_BASE U(0xC0000000) #define STM32MP_DDR_MAX_SIZE U(0x40000000) /* Max 1GB */ @@ -81,18 +90,18 @@ enum ddr_type { /* 256 Octets reserved for header */ #define STM32MP_HEADER_SIZE U(0x00000100) -#define STM32MP_BINARY_BASE (STM32MP_SYSRAM_BASE + \ +#define STM32MP_BINARY_BASE (STM32MP_SEC_SYSRAM_BASE + \ STM32MP_PARAM_LOAD_SIZE + \ STM32MP_HEADER_SIZE) -#define STM32MP_BINARY_SIZE (STM32MP_SYSRAM_SIZE - \ +#define STM32MP_BINARY_SIZE (STM32MP_SEC_SYSRAM_SIZE - \ (STM32MP_PARAM_LOAD_SIZE + \ STM32MP_HEADER_SIZE)) #ifdef AARCH32_SP_OPTEE #define STM32MP_BL32_SIZE U(0) -#define STM32MP_OPTEE_BASE STM32MP_SYSRAM_BASE +#define STM32MP_OPTEE_BASE STM32MP_SEC_SYSRAM_BASE #define STM32MP_OPTEE_SIZE (STM32MP_DTB_BASE - \ STM32MP_OPTEE_BASE) @@ -104,8 +113,8 @@ enum ddr_type { #endif #endif -#define STM32MP_BL32_BASE (STM32MP_SYSRAM_BASE + \ - STM32MP_SYSRAM_SIZE - \ +#define STM32MP_BL32_BASE (STM32MP_SEC_SYSRAM_BASE + \ + STM32MP_SEC_SYSRAM_SIZE - \ STM32MP_BL32_SIZE) #ifdef AARCH32_SP_OPTEE diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c index 779228d4a..fd60db282 100644 --- a/plat/st/stm32mp1/stm32mp1_private.c +++ b/plat/st/stm32mp1/stm32mp1_private.c @@ -30,12 +30,29 @@ BOARD_ID_REVISION_SHIFT) #define BOARD_ID2BOM(_id) ((_id) & BOARD_ID_BOM_MASK) -#define MAP_SRAM MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \ +#if defined(IMAGE_BL2) +#define MAP_SEC_SYSRAM MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \ STM32MP_SYSRAM_SIZE, \ MT_MEMORY | \ MT_RW | \ MT_SECURE | \ MT_EXECUTE_NEVER) +#elif defined(IMAGE_BL32) +#define MAP_SEC_SYSRAM MAP_REGION_FLAT(STM32MP_SEC_SYSRAM_BASE, \ + STM32MP_SEC_SYSRAM_SIZE, \ + MT_MEMORY | \ + MT_RW | \ + MT_SECURE | \ + MT_EXECUTE_NEVER) + +/* Non-secure SYSRAM is used a uncached memory for SCMI message transfer */ +#define MAP_NS_SYSRAM MAP_REGION_FLAT(STM32MP_NS_SYSRAM_BASE, \ + STM32MP_NS_SYSRAM_SIZE, \ + MT_DEVICE | \ + MT_RW | \ + MT_NS | \ + MT_EXECUTE_NEVER) +#endif #define MAP_DEVICE1 MAP_REGION_FLAT(STM32MP1_DEVICE1_BASE, \ STM32MP1_DEVICE1_SIZE, \ @@ -53,7 +70,7 @@ #if defined(IMAGE_BL2) static const mmap_region_t stm32mp1_mmap[] = { - MAP_SRAM, + MAP_SEC_SYSRAM, MAP_DEVICE1, MAP_DEVICE2, {0} @@ -61,7 +78,8 @@ static const mmap_region_t stm32mp1_mmap[] = { #endif #if defined(IMAGE_BL32) static const mmap_region_t stm32mp1_mmap[] = { - MAP_SRAM, + MAP_SEC_SYSRAM, + MAP_NS_SYSRAM, MAP_DEVICE1, MAP_DEVICE2, {0} -- cgit v1.2.3 From 450e15a78e74b86f7404f5968a614114532f7d6d Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Tue, 23 Jun 2020 09:26:15 +0200 Subject: stm32mp1: SP_MIN embeds Arm Architecture services Embed Arch Architecture SMCCC services in stm32mp1 SP_MIN. This service is needed by Linux kernel to setup the SMCCC conduit used by its SCMI SMC transport driver. Change-Id: I454a7ef3048a77ab73fff945e8115b60445d5841 Signed-off-by: Etienne Carriere --- plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk index 180620e88..de54e0945 100644 --- a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk +++ b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk @@ -25,3 +25,6 @@ BL32_SOURCES += plat/common/plat_psci_common.c # stm32mp1 specific services BL32_SOURCES += plat/st/stm32mp1/services/bsec_svc.c \ plat/st/stm32mp1/services/stm32mp1_svc_setup.c + +# Arm Archtecture services +BL32_SOURCES += services/arm_arch_svc/arm_arch_svc_setup.c -- cgit v1.2.3 From 4388f28f0fdbc8deba4e786c776a56ae2c4d4887 Mon Sep 17 00:00:00 2001 From: J-Alves Date: Tue, 26 May 2020 14:03:05 +0100 Subject: FFA Version interface update Change handler of FFA version interface: - Return SPMD's version if the origin of the call is secure; - Return SPMC's version if origin is non-secure. Signed-off-by: J-Alves Change-Id: I0d1554da79b72b1e02da6cc363a2288119c32f44 --- include/services/ffa_svc.h | 12 +++++++----- services/std_svc/spmd/spmd_main.c | 24 +++++++++++++++++------- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/include/services/ffa_svc.h b/include/services/ffa_svc.h index fe321750a..728507749 100644 --- a/include/services/ffa_svc.h +++ b/include/services/ffa_svc.h @@ -12,13 +12,13 @@ #include /* FFA error codes. */ -#define FFA_ERROR_NOT_SUPPORTED -1 +#define FFA_ERROR_NOT_SUPPORTED -1 #define FFA_ERROR_INVALID_PARAMETER -2 #define FFA_ERROR_NO_MEMORY -3 #define FFA_ERROR_BUSY -4 #define FFA_ERROR_INTERRUPTED -5 #define FFA_ERROR_DENIED -6 -#define FFA_ERROR_RETRY -7 +#define FFA_ERROR_RETRY -7 /* The macros below are used to identify FFA calls from the SMC function ID */ #define FFA_FNUM_MIN_VALUE U(0x60) @@ -30,13 +30,15 @@ /* FFA_VERSION helpers */ #define FFA_VERSION_MAJOR U(1) -#define FFA_VERSION_MAJOR_SHIFT 16 +#define FFA_VERSION_MAJOR_SHIFT 16 #define FFA_VERSION_MAJOR_MASK U(0x7FFF) #define FFA_VERSION_MINOR U(0) -#define FFA_VERSION_MINOR_SHIFT 0 +#define FFA_VERSION_MINOR_SHIFT 0 #define FFA_VERSION_MINOR_MASK U(0xFFFF) +#define FFA_VERSION_BIT31_MASK U(0x1u << 31) -#define MAKE_FFA_VERSION(major, minor) \ + +#define MAKE_FFA_VERSION(major, minor) \ ((((major) & FFA_VERSION_MAJOR_MASK) << FFA_VERSION_MAJOR_SHIFT) | \ (((minor) & FFA_VERSION_MINOR_MASK) << FFA_VERSION_MINOR_SHIFT)) #define FFA_VERSION_COMPILED MAKE_FFA_VERSION(FFA_VERSION_MAJOR, \ diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c index a818037cb..4c2b58df2 100644 --- a/services/std_svc/spmd/spmd_main.c +++ b/services/std_svc/spmd/spmd_main.c @@ -350,6 +350,7 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, spmd_spm_core_context_t *ctx = spmd_get_context(); bool secure_origin; int32_t ret; + uint32_t input_version; /* Determine which security state this SMC originated from */ secure_origin = is_caller_secure(flags); @@ -375,15 +376,24 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, break; /* not reached */ case FFA_VERSION: + input_version = (uint32_t)(0xFFFFFFFF & x1); /* - * TODO: This is an optimization that the version information - * provided by the SPM Core manifest is returned by the SPM - * dispatcher. It might be a better idea to simply forward this - * call to the SPM Core and wash our hands completely. + * If caller is secure and SPMC was initialized, + * return FFA_VERSION of SPMD. + * If caller is non secure and SPMC was initialized, + * return SPMC's version. + * Sanity check to "input_version". */ - ret = MAKE_FFA_VERSION(spmc_attrs.major_version, - spmc_attrs.minor_version); - SMC_RET8(handle, FFA_SUCCESS_SMC32, FFA_TARGET_INFO_MBZ, ret, + if ((input_version & FFA_VERSION_BIT31_MASK) || + (ctx->state == SPMC_STATE_RESET)) { + ret = FFA_ERROR_NOT_SUPPORTED; + } else if (!secure_origin) { + ret = MAKE_FFA_VERSION(spmc_attrs.major_version, spmc_attrs.minor_version); + } else { + ret = MAKE_FFA_VERSION(FFA_VERSION_MAJOR, FFA_VERSION_MINOR); + } + + SMC_RET8(handle, ret, FFA_TARGET_INFO_MBZ, FFA_TARGET_INFO_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ); break; /* not reached */ -- cgit v1.2.3 From ebd34bea0b61fce98f4b98e04a2879d1699ddbdf Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Tue, 23 Jun 2020 10:30:42 +0100 Subject: doc: Add a binding document for COT descriptors Added a binding document for COT descriptors which is going to be used in order to create COT desciptors at run-time. Signed-off-by: Manish V Badarkhe Change-Id: Ic54519b0e16d145cd1609274a00b137a9194e8dd --- docs/components/cot-binding.rst | 287 ++++++++++++++++++++++++++++++++++++++++ docs/components/index.rst | 1 + 2 files changed, 288 insertions(+) create mode 100644 docs/components/cot-binding.rst diff --git a/docs/components/cot-binding.rst b/docs/components/cot-binding.rst new file mode 100644 index 000000000..cc69d79b4 --- /dev/null +++ b/docs/components/cot-binding.rst @@ -0,0 +1,287 @@ +Chain of trust bindings +======================= + +The device tree allows to describes the chain of trust with the help of +certificates and images nodes, which in turn contains number of sub-nodes +(i.e. certificate and image) mentioning properties for every certificate +and image respectively. +Also, this binding allows to describe OID of non-volatile counters, memory +mapped address and size of non-volatile counter register. + +Convention used in this document +-------------------------------- + +This document follows the conventions described in the Device-tree +Specification + +certificates, certificate and extension node bindings definition +---------------------------------------------------------------- + +- Certificates node + Description: Container of certificate nodes. + + PROPERTIES + + - compatible: + Usage: required + + Value type: + + Definition: must be "arm, certificate-descriptors" + +- Certificate node + Description: Describes certificate properties which are used + during the authentication process. + + PROPERTIES + + - root-certificate + Usage: Required for the certificate with no parent. + In other words, Certificates which are validated + using root of trust public key. + + Value type: + + - image-id + Usage: Required for every certificate with unique id. + + Value type: + + - parent + Usage: It refers to their parent image, which typically contains + information to authenticate the certificate. + This property is required for all non-root certificates. + + This property is not required for root-certificates + as it is validated using root of trust public key + provided by platform. + + Value type: + + - signing-key + Usage: This property is used to refer extension node present in + parent certificate and it is required property for all non- + root certificates which are authenticated using public-key + present in parent certificate. + + This property is not required for root-certificates + as root-certificates are validated using root of trust + public key provided by platform. + + Value type: + + - antirollback-counter + Usage: This property is used by all certificates which are protected + against rollback attacks using a non-volatile counter and it + is optional property. + + This property is used to refer trusted or non-trusted + non-volatile counter node. + + Value type: + + SUBNODES + + - extensions node + Description: This is sub-node of certificate node. + Describes OIDs present in the certificate which will + be used during authentication process to extract + hash/public key information from this certificate. + OIDs in extension node are represented using number of + sub-nodes which contains 'oid' as property + + PROPERTIES + + - oid + Usage: This property provides the Object ID of an extension + provided in the certificate. + + Value type: + +Example: + +.. code:: c + + certificates { + compatible = "arm, certificate-descriptors” + + trusted-key-cert: trusted-key-cert { + root-certificate; + image-id = ; + antirollback-counter = <&trusted_nv_counter>; + extensions { + trusted-world-pk: trusted-world-pk { + oid = TRUSTED_WORLD_PK_OID; + }; + non-trusted-world-pk: non-trusted-world-pk { + oid = NON_TRUSTED_WORLD_PK_OID; + }; + }; + }; + + scp_fw_key_cert: scp_fw_key_cert { + image-id = ; + parent = <&trusted-key-cert>; + signing-key = <&trusted_world_pk>; + antirollback-counter = <&trusted_nv_counter>; + extensions { + scp_fw_content_pk: scp_fw_content_pk { + oid = SCP_FW_CONTENT_CERT_PK_OID; + }; + }; + }; + + . + . + . + + next-cert { + + }; + }; + +Images and image node bindings definition +----------------------------------------- + +- Images node + Description: Container of image nodes + + PROPERTIES + + - compatible: + Usage: required + + Value type: + + Definition: must be "arm, image-descriptors" + +- Image node + Description: Describes image properties which will be used during + authentication process. + + PROPERTIES + + - image-id + Usage: Required for every image with unique id. + + Value type: + + - parent + Usage: Required for every image to provide a reference to + it's parent image, which contains the necessary information + to authenticate it. + + Value type: + + - hash + Usage: Required for all images which are validated using + hash method. This property is used to refer extension + node present in parent certificate and it is required + property for all images. + + Value type: + + Note: Currently, all images are validated using "hash" + method. In future, there may be multiple methods can + be used to validate the image. + +Example: + +.. code:: c + + images { + compatible = "arm, imgage-descriptors"; + + scp_bl2_image { + image-id = ; + parent = <&scp_fw_content_cert>; + hash = <&scp_fw_hash>; + }; + + . + . + . + + next-img { + }; + }; + +non-volatile counter node binding definition +-------------------------------------------- + +- non-volatile counters node + Description: Contains properties for non-volatile counters. + + PROPERTIES + + - compatible: + Usage: required + + Value type: + + Definition: must be "arm, non-volatile-counter" + + - #address-cells + Usage: required + + Value type: + + Definition: Must be set according to address size + of non-volatile counter register + + - #size-cells + Usage: required + + Value type: + + Definition: must be set to 0 + + SUBNODE + - counters node + Description: Contains various non-volatile counters present in the platform. + + PROPERTIES + + - reg + Usage: Register base address of non-volatile counter and it is required + property. + + Value type: + + - oid + Usage: This property provides the Object ID of non-volatile counter + provided in the certificate and it is required property. + + Value type: + +Example: +Below is non-volatile counters example for ARM platform + +.. code:: c + + non-volatile-counters { + compatible = "arm, non-volatile-counter"; + #address-cells = <1>; + #size-cells = <0>; + + counters { + trusted-nv-counter: trusted_nv_counter { + reg = ; + oid = TRUSTED_FW_NVCOUNTER_OID; + }; + non_trusted_nv_counter: non_trusted_nv_counter { + reg = ; + oid = NON_TRUSTED_FW_NVCOUNTER_OID; + + }; + }; + }; + +Future update to chain of trust binding +--------------------------------------- + +This binding document need to be revisited to generalise some terminologies +like Object IDs, extensions etc which are currently specific to X.509 +certificates. + +*Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.* diff --git a/docs/components/index.rst b/docs/components/index.rst index c5f6264e1..18b1e38bb 100644 --- a/docs/components/index.rst +++ b/docs/components/index.rst @@ -19,3 +19,4 @@ Components secure-partition-manager-design psa-ffa-manifest-binding xlat-tables-lib-v2-design + cot-binding -- cgit v1.2.3 From 5703c7379ea51eb5a3a4111b5ad551f8b0e94d32 Mon Sep 17 00:00:00 2001 From: Sheetal Tigadoli Date: Tue, 23 Jun 2020 21:12:28 +0530 Subject: Fix usage of incorrect function name Signed-off-by: Sheetal Tigadoli Change-Id: Ic387630c096361ea9a963cde0018a0efb63e3bd2 --- plat/brcm/board/stingray/src/bl31_setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/brcm/board/stingray/src/bl31_setup.c b/plat/brcm/board/stingray/src/bl31_setup.c index d94755184..a2a274dcd 100644 --- a/plat/brcm/board/stingray/src/bl31_setup.c +++ b/plat/brcm/board/stingray/src/bl31_setup.c @@ -923,7 +923,7 @@ void plat_bcm_bl31_early_platform_setup(void *from_bl2, scp_image_info.image_base = PRELOADED_SCP_BASE; scp_image_info.image_size = PRELOADED_SCP_SIZE; - bcm_bl2_plat_handle_scp_bl2(&scp_image_info); + plat_bcm_bl2_plat_handle_scp_bl2(&scp_image_info); #endif /* * In BL31, logs are saved to DDR and we have much larger space to -- cgit v1.2.3 From 3cb84a54258e148ba0240fc5fbe4ef828339c13d Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Sun, 31 May 2020 08:53:40 +0100 Subject: plat/arm: Rentroduce tb_fw_config device tree Moved BL2 configuration nodes from fw_config to newly created tb_fw_config device tree. fw_config device tree's main usage is to hold properties shared across all BLx images. An example is the "dtb-registry" node, which contains the information about the other device tree configurations (load-address, size). Also, Updated load-address of tb_fw_config which is now located after fw_config in SRAM. Signed-off-by: Manish V Badarkhe Change-Id: Ic398c86a4d822dacd55b5e25fd41d4fe3888d79a --- lib/fconf/fconf_dyn_cfg_getter.c | 2 +- plat/arm/board/a5ds/fdts/a5ds_fw_config.dts | 10 +-- plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts | 16 ++++ plat/arm/board/a5ds/platform.mk | 8 +- plat/arm/board/fvp/fdts/fvp_fw_config.dts | 82 +------------------- plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts | 88 ++++++++++++++++++++++ plat/arm/board/fvp/platform.mk | 6 +- plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts | 10 +-- plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts | 16 ++++ plat/arm/board/fvp_ve/platform.mk | 8 +- plat/arm/board/juno/fdts/juno_fw_config.dts | 21 +----- plat/arm/board/juno/fdts/juno_tb_fw_config.dts | 26 +++++++ plat/arm/board/juno/platform.mk | 9 ++- .../arm/board/rddaniel/fdts/rddaniel_fw_config.dts | 22 +----- .../board/rddaniel/fdts/rddaniel_tb_fw_config.dts | 28 +++++++ plat/arm/board/rddaniel/platform.mk | 8 +- .../rddanielxlr/fdts/rddanielxlr_fw_config.dts | 22 +----- .../rddanielxlr/fdts/rddanielxlr_tb_fw_config.dts | 28 +++++++ plat/arm/board/rddanielxlr/platform.mk | 8 +- .../arm/board/rde1edge/fdts/rde1edge_fw_config.dts | 22 +----- .../board/rde1edge/fdts/rde1edge_tb_fw_config.dts | 28 +++++++ plat/arm/board/rde1edge/platform.mk | 8 +- .../arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts | 22 +----- .../board/rdn1edge/fdts/rdn1edge_tb_fw_config.dts | 27 +++++++ plat/arm/board/rdn1edge/platform.mk | 8 +- plat/arm/board/sgi575/fdts/sgi575_fw_config.dts | 22 +----- plat/arm/board/sgi575/fdts/sgi575_tb_fw_config.dts | 28 +++++++ plat/arm/board/sgi575/platform.mk | 9 ++- plat/arm/board/sgm775/fdts/sgm775_fw_config.dts | 22 +----- plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts | 28 +++++++ plat/arm/board/sgm775/platform.mk | 8 +- plat/arm/board/tc0/fdts/tc0_fw_config.dts | 21 +----- plat/arm/board/tc0/fdts/tc0_tb_fw_config.dts | 27 +++++++ plat/arm/board/tc0/platform.mk | 8 +- plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts | 2 +- 35 files changed, 420 insertions(+), 288 deletions(-) create mode 100644 plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts create mode 100644 plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts create mode 100644 plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts create mode 100644 plat/arm/board/juno/fdts/juno_tb_fw_config.dts create mode 100644 plat/arm/board/rddaniel/fdts/rddaniel_tb_fw_config.dts create mode 100644 plat/arm/board/rddanielxlr/fdts/rddanielxlr_tb_fw_config.dts create mode 100644 plat/arm/board/rde1edge/fdts/rde1edge_tb_fw_config.dts create mode 100644 plat/arm/board/rdn1edge/fdts/rdn1edge_tb_fw_config.dts create mode 100644 plat/arm/board/sgi575/fdts/sgi575_tb_fw_config.dts create mode 100644 plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts create mode 100644 plat/arm/board/tc0/fdts/tc0_tb_fw_config.dts diff --git a/lib/fconf/fconf_dyn_cfg_getter.c b/lib/fconf/fconf_dyn_cfg_getter.c index 7b5bd6ec9..f1004fad5 100644 --- a/lib/fconf/fconf_dyn_cfg_getter.c +++ b/lib/fconf/fconf_dyn_cfg_getter.c @@ -98,4 +98,4 @@ int fconf_populate_dtb_registry(uintptr_t config) return 0; } -FCONF_REGISTER_POPULATOR(TB_FW, dyn_cfg, fconf_populate_dtb_registry); +FCONF_REGISTER_POPULATOR(FW_CONFIG, dyn_cfg, fconf_populate_dtb_registry); diff --git a/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts b/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts index b9d905388..b9ff8bff1 100644 --- a/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts +++ b/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts @@ -12,9 +12,8 @@ dtb-registry { compatible = "fconf,dyn_cfg-dtb_registry"; - /* tb_fw_config is temporarily contained in this dtb */ tb_fw-config { - load-address = <0x0 0x2001010>; + load-address = <0x0 0x2001300>; max-size = <0x200>; id = ; }; @@ -25,11 +24,4 @@ id = ; }; }; - - tb_fw-config { - compatible = "arm,tb_fw"; - - /* Disable authentication for development */ - disable_auth = <0x0>; - }; }; diff --git a/plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts b/plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts new file mode 100644 index 000000000..c66186f64 --- /dev/null +++ b/plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +/ { + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + }; +}; diff --git a/plat/arm/board/a5ds/platform.mk b/plat/arm/board/a5ds/platform.mk index 3a4d5e56d..7693e46e1 100644 --- a/plat/arm/board/a5ds/platform.mk +++ b/plat/arm/board/a5ds/platform.mk @@ -72,10 +72,13 @@ BL2_SOURCES += lib/aarch32/arm32_aeabi_divmod.c \ # Add the FDT_SOURCES and options for Dynamic Config (only for Unix env) ifdef UNIX_MK -FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/a5ds_fw_config.dtb +FW_CONFIG := ${BUILD_PLAT}/fdts/a5ds_fw_config.dtb +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/a5ds_tb_fw_config.dtb # Add the TB_FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) +# Add the FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config)) $(eval FVP_HW_CONFIG := ${BUILD_PLAT}/$(patsubst %.dts,%.dtb, \ fdts/$(notdir ${FVP_HW_CONFIG_DTS}))) @@ -83,6 +86,7 @@ $(eval FVP_HW_CONFIG := ${BUILD_PLAT}/$(patsubst %.dts,%.dtb, \ $(eval $(call TOOL_ADD_PAYLOAD,${FVP_HW_CONFIG},--hw-config)) FDT_SOURCES += plat/arm/board/a5ds/fdts/a5ds_fw_config.dts \ + plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts \ ${FVP_HW_CONFIG_DTS} endif diff --git a/plat/arm/board/fvp/fdts/fvp_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_fw_config.dts index 5f89284ee..605b70c2d 100644 --- a/plat/arm/board/fvp/fdts/fvp_fw_config.dts +++ b/plat/arm/board/fvp/fdts/fvp_fw_config.dts @@ -12,9 +12,8 @@ dtb-registry { compatible = "fconf,dyn_cfg-dtb_registry"; - /* tb_fw_config is temporarily contained on this dtb */ tb_fw-config { - load-address = <0x0 0x4001010>; + load-address = <0x0 0x4001300>; max-size = <0x200>; id = ; }; @@ -49,83 +48,4 @@ id = ; }; }; - - tb_fw-config { - compatible = "arm,tb_fw"; - - /* Disable authentication for development */ - disable_auth = <0x0>; - - /* - * The following two entries are placeholders for Mbed TLS - * heap information. The default values don't matter since - * they will be overwritten by BL1. - * In case of having shared Mbed TLS heap between BL1 and BL2, - * BL1 will populate these two properties with the respective - * info about the shared heap. This info will be available for - * BL2 in order to locate and re-use the heap. - */ - 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 */ - }; - - /* - * Though TF-A is UUID RFC 4122 compliant meaning fields are stored in - * network order (big endian), UUID's mentioned in this file are are - * stored in machine order (little endian). - * This will be fixed in future. - */ -#if ARM_IO_IN_DTB - arm-io_policies { - fip-handles { - compatible = "arm,io-fip-handle"; - scp_bl2_uuid = <0x3dfd6697 0x49e8be89 0xa1785dae 0x13826040>; - bl31_uuid = <0x6d08d447 0x4698fe4c 0x5029959b 0x005abdcb>; - bl32_uuid = <0x89e1d005 0x4713dc53 0xa502b8d 0x383e7a4b>; - bl32_extra1_uuid = <0x9bc2700b 0x40785a2a 0x560a659f 0x88827382>; - bl32_extra2_uuid = <0xb17ba88e 0x4d3fa2cf 0xbbe7fd85 0xd92002a5>; - bl33_uuid = <0xa7eed0d6 0x4bd5eafc 0x34998297 0xe4b634f2>; - hw_cfg_uuid = <0xd9f1b808 0x4993cfc9 0xbc6f62a9 0xcc65726b>; - soc_fw_cfg_uuid = <0x4b817999 0x46fb7603 0x268d8e8c 0xe059787f>; - tos_fw_cfg_uuid = <0x1a7c2526 0x477fc6db 0xc4c4968d 0x218024b0>; - nt_fw_cfg_uuid = <0x1598da28 0x447ee893 0xaf1a66ac 0xf9501580>; - t_key_cert_uuid = <0x90e87e82 0x11e460f8 0x7a77b4a1 0x4cf9b421>; - scp_fw_key_uuid = <0xa1214202 0x11e460f8 0x3cf39b8d 0x14a0150e>; - soc_fw_key_uuid = <0xccbeb88a 0x11e460f9 0x48ebd09a 0xf8dcd822>; - tos_fw_key_cert_uuid = <0x3d67794 0x11e460fb 0x10b7dd85 0x4ee8c5b>; - nt_fw_key_cert_uuid = <0x2a83d58a 0x11e460fb 0x30dfaf8a 0x5998c4bb>; - scp_fw_content_cert_uuid = <0x046fbe44 0x11e4635e 0xd8738bb2 0x5696aeea>; - soc_fw_content_cert_uuid = <0x200cb2e2 0x11e4635e 0xccabe89c 0x66b62bf9>; - tos_fw_content_cert_uuid = <0x11449fa4 0x11e4635e 0x53f2887 0x3df32a72>; - nt_fw_content_cert_uuid = <0xf3c1c48e 0x11e4635d 0xee87a9a7 0xa73fb240>; - sp_content_cert_uuid = <0x44fd6d77 0x3b4c9786 0x3ec1eb91 0x6f2a5a02>; - }; - }; -#endif /* ARM_IO_IN_DTB */ - - secure-partitions { - compatible = "arm,sp"; - cactus-primary { - uuid = <0x1e67b5b4 0xe14f904a 0x13fb1fb8 0xcbdae1da>; - load-address = <0x7000000>; - }; - - cactus-secondary { - uuid = <0x092358d1 0xb94723f0 0x64447c82 0xc88f57f5>; - load-address = <0x7100000>; - }; - }; }; diff --git a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts new file mode 100644 index 000000000..9cffad310 --- /dev/null +++ b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +/ { + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + + /* + * The following two entries are placeholders for Mbed TLS + * heap information. The default values don't matter since + * they will be overwritten by BL1. + * In case of having shared Mbed TLS heap between BL1 and BL2, + * BL1 will populate these two properties with the respective + * info about the shared heap. This info will be available for + * BL2 in order to locate and re-use the heap. + */ + 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 */ + }; + + /* + * Though TF-A is UUID RFC 4122 compliant meaning fields are stored in + * network order (big endian), UUID's mentioned in this file are are + * stored in machine order (little endian). + * This will be fixed in future. + */ +#if ARM_IO_IN_DTB + arm-io_policies { + fip-handles { + compatible = "arm,io-fip-handle"; + scp_bl2_uuid = <0x3dfd6697 0x49e8be89 0xa1785dae 0x13826040>; + bl31_uuid = <0x6d08d447 0x4698fe4c 0x5029959b 0x005abdcb>; + bl32_uuid = <0x89e1d005 0x4713dc53 0xa502b8d 0x383e7a4b>; + bl32_extra1_uuid = <0x9bc2700b 0x40785a2a 0x560a659f 0x88827382>; + bl32_extra2_uuid = <0xb17ba88e 0x4d3fa2cf 0xbbe7fd85 0xd92002a5>; + bl33_uuid = <0xa7eed0d6 0x4bd5eafc 0x34998297 0xe4b634f2>; + hw_cfg_uuid = <0xd9f1b808 0x4993cfc9 0xbc6f62a9 0xcc65726b>; + soc_fw_cfg_uuid = <0x4b817999 0x46fb7603 0x268d8e8c 0xe059787f>; + tos_fw_cfg_uuid = <0x1a7c2526 0x477fc6db 0xc4c4968d 0x218024b0>; + nt_fw_cfg_uuid = <0x1598da28 0x447ee893 0xaf1a66ac 0xf9501580>; + t_key_cert_uuid = <0x90e87e82 0x11e460f8 0x7a77b4a1 0x4cf9b421>; + scp_fw_key_uuid = <0xa1214202 0x11e460f8 0x3cf39b8d 0x14a0150e>; + soc_fw_key_uuid = <0xccbeb88a 0x11e460f9 0x48ebd09a 0xf8dcd822>; + tos_fw_key_cert_uuid = <0x3d67794 0x11e460fb 0x10b7dd85 0x4ee8c5b>; + nt_fw_key_cert_uuid = <0x2a83d58a 0x11e460fb 0x30dfaf8a 0x5998c4bb>; + scp_fw_content_cert_uuid = <0x046fbe44 0x11e4635e 0xd8738bb2 0x5696aeea>; + soc_fw_content_cert_uuid = <0x200cb2e2 0x11e4635e 0xccabe89c 0x66b62bf9>; + tos_fw_content_cert_uuid = <0x11449fa4 0x11e4635e 0x53f2887 0x3df32a72>; + nt_fw_content_cert_uuid = <0xf3c1c48e 0x11e4635d 0xee87a9a7 0xa73fb240>; + sp_content_cert_uuid = <0x44fd6d77 0x3b4c9786 0x3ec1eb91 0x6f2a5a02>; + }; + }; +#endif /* ARM_IO_IN_DTB */ + + secure-partitions { + compatible = "arm,sp"; + cactus-primary { + uuid = <0x1e67b5b4 0xe14f904a 0x13fb1fb8 0xcbdae1da>; + load-address = <0x7000000>; + }; + + cactus-secondary { + uuid = <0x092358d1 0xb94723f0 0x64447c82 0xc88f57f5>; + load-address = <0x7100000>; + }; + }; +}; diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 7d670accc..4925865a5 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -236,11 +236,13 @@ ifdef UNIX_MK FVP_HW_CONFIG_DTS := fdts/${FVP_DT_PREFIX}.dts FDT_SOURCES += $(addprefix plat/arm/board/fvp/fdts/, \ ${PLAT}_fw_config.dts \ + ${PLAT}_tb_fw_config.dts \ ${PLAT}_soc_fw_config.dts \ ${PLAT}_nt_fw_config.dts \ ) -FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +FVP_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb FVP_SOC_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_soc_fw_config.dtb FVP_NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb @@ -260,6 +262,8 @@ FVP_TOS_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_spmc_manifest.dtb $(eval $(call TOOL_ADD_PAYLOAD,${FVP_TOS_FW_CONFIG},--tos-fw-config)) endif +# Add the FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FVP_FW_CONFIG},--fw-config)) # Add the TB_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config)) # Add the SOC_FW_CONFIG to FIP and specify the same to certtool diff --git a/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts b/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts index d4f98d940..6e5691bd9 100644 --- a/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts +++ b/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts @@ -12,9 +12,8 @@ dtb-registry { compatible = "fconf,dyn_cfg-dtb_registry"; - /* tb_fw_config is temporarily contained on this dtb */ tb_fw-config { - load-address = <0x0 0x80001010>; + load-address = <0x0 0x80001300>; max-size = <0x200>; id = ; }; @@ -25,11 +24,4 @@ id = ; }; }; - - tb_fw-config { - compatible = "arm,tb_fw"; - - /* Disable authentication for development */ - disable_auth = <0x0>; - }; }; diff --git a/plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts b/plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts new file mode 100644 index 000000000..c66186f64 --- /dev/null +++ b/plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +/ { + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + }; +}; diff --git a/plat/arm/board/fvp_ve/platform.mk b/plat/arm/board/fvp_ve/platform.mk index 9ada86bf1..62981c529 100644 --- a/plat/arm/board/fvp_ve/platform.mk +++ b/plat/arm/board/fvp_ve/platform.mk @@ -74,10 +74,14 @@ BL2_SOURCES += plat/arm/board/fvp_ve/fvp_ve_bl2_setup.c \ # Add the FDT_SOURCES and options for Dynamic Config (only for Unix env) ifdef UNIX_MK -FDT_SOURCES += plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts +FDT_SOURCES += plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts \ + plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts -FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/fvp_ve_fw_config.dtb +FVP_FW_CONFIG := ${BUILD_PLAT}/fdts/fvp_ve_fw_config.dtb +FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/fvp_ve_tb_fw_config.dtb +# Add the FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FVP_FW_CONFIG},--fw-config)) # Add the TB_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config)) diff --git a/plat/arm/board/juno/fdts/juno_fw_config.dts b/plat/arm/board/juno/fdts/juno_fw_config.dts index 60ca60daa..c0538f863 100644 --- a/plat/arm/board/juno/fdts/juno_fw_config.dts +++ b/plat/arm/board/juno/fdts/juno_fw_config.dts @@ -12,29 +12,10 @@ dtb-registry { compatible = "fconf,dyn_cfg-dtb_registry"; - /* tb_fw_config is temporarily contained on this dtb */ tb_fw-config { - load-address = <0x0 0x4001010>; + load-address = <0x0 0x4001300>; max-size = <0x200>; id = ; }; }; - - tb_fw-config { - /* Platform Config */ - compatible = "arm,tb_fw"; - /* Disable authentication for development */ - disable_auth = <0x0>; - /* - * The following two entries are placeholders for Mbed TLS - * heap information. The default values don't matter since - * they will be overwritten by BL1. - * In case of having shared Mbed TLS heap between BL1 and BL2, - * BL1 will populate these two properties with the respective - * info about the shared heap. This info will be available for - * BL2 in order to locate and re-use the heap. - */ - mbedtls_heap_addr = <0x0 0x0>; - mbedtls_heap_size = <0x0>; - }; }; diff --git a/plat/arm/board/juno/fdts/juno_tb_fw_config.dts b/plat/arm/board/juno/fdts/juno_tb_fw_config.dts new file mode 100644 index 000000000..80cfa3ea1 --- /dev/null +++ b/plat/arm/board/juno/fdts/juno_tb_fw_config.dts @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +/ { + tb_fw-config { + compatible = "arm,tb_fw"; + /* Disable authentication for development */ + disable_auth = <0x0>; + /* + * The following two entries are placeholders for Mbed TLS + * heap information. The default values don't matter since + * they will be overwritten by BL1. + * In case of having shared Mbed TLS heap between BL1 and BL2, + * BL1 will populate these two properties with the respective + * info about the shared heap. This info will be available for + * BL2 in order to locate and re-use the heap. + */ + mbedtls_heap_addr = <0x0 0x0>; + mbedtls_heap_size = <0x0>; + }; +}; diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk index a871e81ac..8ca7f6120 100644 --- a/plat/arm/board/juno/platform.mk +++ b/plat/arm/board/juno/platform.mk @@ -164,9 +164,14 @@ ifeq (${ALLOW_RO_XLAT_TABLES}, 1) endif # Add the FDT_SOURCES and options for Dynamic Config -FDT_SOURCES += plat/arm/board/juno/fdts/${PLAT}_fw_config.dts -TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +FDT_SOURCES += plat/arm/board/juno/fdts/${PLAT}_fw_config.dts \ + plat/arm/board/juno/fdts/${PLAT}_tb_fw_config.dts +FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb + +# Add the FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config)) # Add the TB_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) diff --git a/plat/arm/board/rddaniel/fdts/rddaniel_fw_config.dts b/plat/arm/board/rddaniel/fdts/rddaniel_fw_config.dts index b9265ad9e..9c9cefe87 100644 --- a/plat/arm/board/rddaniel/fdts/rddaniel_fw_config.dts +++ b/plat/arm/board/rddaniel/fdts/rddaniel_fw_config.dts @@ -12,9 +12,8 @@ dtb-registry { compatible = "fconf,dyn_cfg-dtb_registry"; - /* tb_fw_config is temporarily contained on this dtb */ tb_fw-config { - load-address = <0x0 0x4001010>; + load-address = <0x0 0x4001300>; max-size = <0x200>; id = ; }; @@ -25,23 +24,4 @@ id = ; }; }; - - tb_fw-config { - compatible = "arm,tb_fw"; - - /* Disable authentication for development */ - disable_auth = <0x0>; - - /* - * The following two entries are placeholders for Mbed TLS - * heap information. The default values don't matter since - * they will be overwritten by BL1. - * In case of having shared Mbed TLS heap between BL1 and BL2, - * BL1 will populate these two properties with the respective - * info about the shared heap. This info will be available for - * BL2 in order to locate and re-use the heap. - */ - mbedtls_heap_addr = <0x0 0x0>; - mbedtls_heap_size = <0x0>; - }; }; diff --git a/plat/arm/board/rddaniel/fdts/rddaniel_tb_fw_config.dts b/plat/arm/board/rddaniel/fdts/rddaniel_tb_fw_config.dts new file mode 100644 index 000000000..49eda2735 --- /dev/null +++ b/plat/arm/board/rddaniel/fdts/rddaniel_tb_fw_config.dts @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +/ { + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + + /* + * The following two entries are placeholders for Mbed TLS + * heap information. The default values don't matter since + * they will be overwritten by BL1. + * In case of having shared Mbed TLS heap between BL1 and BL2, + * BL1 will populate these two properties with the respective + * info about the shared heap. This info will be available for + * BL2 in order to locate and re-use the heap. + */ + mbedtls_heap_addr = <0x0 0x0>; + mbedtls_heap_size = <0x0>; + }; +}; diff --git a/plat/arm/board/rddaniel/platform.mk b/plat/arm/board/rddaniel/platform.mk index 94a3928f8..bdf20ca3d 100644 --- a/plat/arm/board/rddaniel/platform.mk +++ b/plat/arm/board/rddaniel/platform.mk @@ -33,9 +33,13 @@ BL31_SOURCES += ${SGI_CPU_SOURCES} \ plat/arm/common/arm_nor_psci_mem_protect.c # Add the FDT_SOURCES and options for Dynamic Config -FDT_SOURCES += ${RDDANIEL_BASE}/fdts/${PLAT}_fw_config.dts -TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +FDT_SOURCES += ${RDDANIEL_BASE}/fdts/${PLAT}_fw_config.dts \ + ${RDDANIEL_BASE}/fdts/${PLAT}_tb_fw_config.dts +FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb +# Add the FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config)) # Add the TB_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) diff --git a/plat/arm/board/rddanielxlr/fdts/rddanielxlr_fw_config.dts b/plat/arm/board/rddanielxlr/fdts/rddanielxlr_fw_config.dts index b9265ad9e..9c9cefe87 100644 --- a/plat/arm/board/rddanielxlr/fdts/rddanielxlr_fw_config.dts +++ b/plat/arm/board/rddanielxlr/fdts/rddanielxlr_fw_config.dts @@ -12,9 +12,8 @@ dtb-registry { compatible = "fconf,dyn_cfg-dtb_registry"; - /* tb_fw_config is temporarily contained on this dtb */ tb_fw-config { - load-address = <0x0 0x4001010>; + load-address = <0x0 0x4001300>; max-size = <0x200>; id = ; }; @@ -25,23 +24,4 @@ id = ; }; }; - - tb_fw-config { - compatible = "arm,tb_fw"; - - /* Disable authentication for development */ - disable_auth = <0x0>; - - /* - * The following two entries are placeholders for Mbed TLS - * heap information. The default values don't matter since - * they will be overwritten by BL1. - * In case of having shared Mbed TLS heap between BL1 and BL2, - * BL1 will populate these two properties with the respective - * info about the shared heap. This info will be available for - * BL2 in order to locate and re-use the heap. - */ - mbedtls_heap_addr = <0x0 0x0>; - mbedtls_heap_size = <0x0>; - }; }; diff --git a/plat/arm/board/rddanielxlr/fdts/rddanielxlr_tb_fw_config.dts b/plat/arm/board/rddanielxlr/fdts/rddanielxlr_tb_fw_config.dts new file mode 100644 index 000000000..49eda2735 --- /dev/null +++ b/plat/arm/board/rddanielxlr/fdts/rddanielxlr_tb_fw_config.dts @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +/ { + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + + /* + * The following two entries are placeholders for Mbed TLS + * heap information. The default values don't matter since + * they will be overwritten by BL1. + * In case of having shared Mbed TLS heap between BL1 and BL2, + * BL1 will populate these two properties with the respective + * info about the shared heap. This info will be available for + * BL2 in order to locate and re-use the heap. + */ + mbedtls_heap_addr = <0x0 0x0>; + mbedtls_heap_size = <0x0>; + }; +}; diff --git a/plat/arm/board/rddanielxlr/platform.mk b/plat/arm/board/rddanielxlr/platform.mk index 36a00993a..1482c814f 100644 --- a/plat/arm/board/rddanielxlr/platform.mk +++ b/plat/arm/board/rddanielxlr/platform.mk @@ -36,9 +36,13 @@ BL31_SOURCES += ${SGI_CPU_SOURCES} \ BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC # Add the FDT_SOURCES and options for Dynamic Config -FDT_SOURCES += ${RDDANIELXLR_BASE}/fdts/${PLAT}_fw_config.dts -TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +FDT_SOURCES += ${RDDANIELXLR_BASE}/fdts/${PLAT}_fw_config.dts \ + ${RDDANIELXLR_BASE}/fdts/${PLAT}_tb_fw_config.dts +FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb +# Add the FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config)) # Add the TB_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) diff --git a/plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts b/plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts index 09b9867e3..69fb0d498 100644 --- a/plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts +++ b/plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts @@ -12,9 +12,8 @@ dtb-registry { compatible = "fconf,dyn_cfg-dtb_registry"; - /* tb_fw_config is temporarily contained on this dtb */ tb_fw-config { - load-address = <0x0 0x4001010>; + load-address = <0x0 0x4001300>; max-size = <0x200>; id = ; }; @@ -25,23 +24,4 @@ id = ; }; }; - - tb_fw-config { - compatible = "arm,tb_fw"; - - /* Disable authentication for development */ - disable_auth = <0x0>; - - /* - * The following two entries are placeholders for Mbed TLS - * heap information. The default values don't matter since - * they will be overwritten by BL1. - * In case of having shared Mbed TLS heap between BL1 and BL2, - * BL1 will populate these two properties with the respective - * info about the shared heap. This info will be available for - * BL2 in order to locate and re-use the heap. - */ - mbedtls_heap_addr = <0x0 0x0>; - mbedtls_heap_size = <0x0>; - }; }; diff --git a/plat/arm/board/rde1edge/fdts/rde1edge_tb_fw_config.dts b/plat/arm/board/rde1edge/fdts/rde1edge_tb_fw_config.dts new file mode 100644 index 000000000..dba91e535 --- /dev/null +++ b/plat/arm/board/rde1edge/fdts/rde1edge_tb_fw_config.dts @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +/ { + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + + /* + * The following two entries are placeholders for Mbed TLS + * heap information. The default values don't matter since + * they will be overwritten by BL1. + * In case of having shared Mbed TLS heap between BL1 and BL2, + * BL1 will populate these two properties with the respective + * info about the shared heap. This info will be available for + * BL2 in order to locate and re-use the heap. + */ + mbedtls_heap_addr = <0x0 0x0>; + mbedtls_heap_size = <0x0>; + }; +}; diff --git a/plat/arm/board/rde1edge/platform.mk b/plat/arm/board/rde1edge/platform.mk index 1a4dd17d1..e09afcad3 100644 --- a/plat/arm/board/rde1edge/platform.mk +++ b/plat/arm/board/rde1edge/platform.mk @@ -35,9 +35,13 @@ BL2_SOURCES += ${RDE1EDGE_BASE}/rde1edge_trusted_boot.c endif # Add the FDT_SOURCES and options for Dynamic Config -FDT_SOURCES += ${RDE1EDGE_BASE}/fdts/${PLAT}_fw_config.dts -TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +FDT_SOURCES += ${RDE1EDGE_BASE}/fdts/${PLAT}_fw_config.dts \ + ${RDE1EDGE_BASE}/fdts/${PLAT}_tb_fw_config.dts +FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb +# Add the FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config)) # Add the TB_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) diff --git a/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts b/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts index c9dee60d1..d3b7fba49 100644 --- a/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts +++ b/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts @@ -11,9 +11,8 @@ dtb-registry { compatible = "fconf,dyn_cfg-dtb_registry"; - /* tb_fw_config is temporarily contained on this dtb */ tb_fw-config { - load-address = <0x0 0x4001010>; + load-address = <0x0 0x4001300>; max-size = <0x200>; id = ; }; @@ -24,24 +23,5 @@ id = ; }; }; - - tb_fw-config { - compatible = "arm,tb_fw"; - - /* Disable authentication for development */ - disable_auth = <0x0>; - - /* - * The following two entries are placeholders for Mbed TLS - * heap information. The default values don't matter since - * they will be overwritten by BL1. - * In case of having shared Mbed TLS heap between BL1 and BL2, - * BL1 will populate these two properties with the respective - * info about the shared heap. This info will be available for - * BL2 in order to locate and re-use the heap. - */ - mbedtls_heap_addr = <0x0 0x0>; - mbedtls_heap_size = <0x0>; - }; }; diff --git a/plat/arm/board/rdn1edge/fdts/rdn1edge_tb_fw_config.dts b/plat/arm/board/rdn1edge/fdts/rdn1edge_tb_fw_config.dts new file mode 100644 index 000000000..257ef4a3f --- /dev/null +++ b/plat/arm/board/rdn1edge/fdts/rdn1edge_tb_fw_config.dts @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; +/ { + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + + /* + * The following two entries are placeholders for Mbed TLS + * heap information. The default values don't matter since + * they will be overwritten by BL1. + * In case of having shared Mbed TLS heap between BL1 and BL2, + * BL1 will populate these two properties with the respective + * info about the shared heap. This info will be available for + * BL2 in order to locate and re-use the heap. + */ + mbedtls_heap_addr = <0x0 0x0>; + mbedtls_heap_size = <0x0>; + }; +}; diff --git a/plat/arm/board/rdn1edge/platform.mk b/plat/arm/board/rdn1edge/platform.mk index e43654292..3f0cc7f4a 100644 --- a/plat/arm/board/rdn1edge/platform.mk +++ b/plat/arm/board/rdn1edge/platform.mk @@ -41,9 +41,13 @@ endif BL31_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC # Add the FDT_SOURCES and options for Dynamic Config -FDT_SOURCES += ${RDN1EDGE_BASE}/fdts/${PLAT}_fw_config.dts -TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +FDT_SOURCES += ${RDN1EDGE_BASE}/fdts/${PLAT}_fw_config.dts \ + ${RDN1EDGE_BASE}/fdts/${PLAT}_tb_fw_config.dts +FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb +# Add the FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config)) # Add the TB_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) diff --git a/plat/arm/board/sgi575/fdts/sgi575_fw_config.dts b/plat/arm/board/sgi575/fdts/sgi575_fw_config.dts index 94d0e39a8..84fc1ad5f 100644 --- a/plat/arm/board/sgi575/fdts/sgi575_fw_config.dts +++ b/plat/arm/board/sgi575/fdts/sgi575_fw_config.dts @@ -12,9 +12,8 @@ dtb-registry { compatible = "fconf,dyn_cfg-dtb_registry"; - /* tb_fw_config is temporarily contained on this dtb */ tb_fw-config { - load-address = <0x0 0x4001010>; + load-address = <0x0 0x4001300>; max-size = <0x200>; id = ; }; @@ -25,23 +24,4 @@ id = ; }; }; - - tb_fw-config { - compatible = "arm,tb_fw"; - - /* Disable authentication for development */ - disable_auth = <0x0>; - - /* - * The following two entries are placeholders for Mbed TLS - * heap information. The default values don't matter since - * they will be overwritten by BL1. - * In case of having shared Mbed TLS heap between BL1 and BL2, - * BL1 will populate these two properties with the respective - * info about the shared heap. This info will be available for - * BL2 in order to locate and re-use the heap. - */ - mbedtls_heap_addr = <0x0 0x0>; - mbedtls_heap_size = <0x0>; - }; }; diff --git a/plat/arm/board/sgi575/fdts/sgi575_tb_fw_config.dts b/plat/arm/board/sgi575/fdts/sgi575_tb_fw_config.dts new file mode 100644 index 000000000..49eda2735 --- /dev/null +++ b/plat/arm/board/sgi575/fdts/sgi575_tb_fw_config.dts @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +/ { + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + + /* + * The following two entries are placeholders for Mbed TLS + * heap information. The default values don't matter since + * they will be overwritten by BL1. + * In case of having shared Mbed TLS heap between BL1 and BL2, + * BL1 will populate these two properties with the respective + * info about the shared heap. This info will be available for + * BL2 in order to locate and re-use the heap. + */ + mbedtls_heap_addr = <0x0 0x0>; + mbedtls_heap_size = <0x0>; + }; +}; diff --git a/plat/arm/board/sgi575/platform.mk b/plat/arm/board/sgi575/platform.mk index d91f829ee..f5d547dd1 100644 --- a/plat/arm/board/sgi575/platform.mk +++ b/plat/arm/board/sgi575/platform.mk @@ -35,9 +35,14 @@ BL2_SOURCES += ${SGI575_BASE}/sgi575_trusted_boot.c endif # Add the FDT_SOURCES and options for Dynamic Config -FDT_SOURCES += ${SGI575_BASE}/fdts/${PLAT}_fw_config.dts -TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +FDT_SOURCES += ${SGI575_BASE}/fdts/${PLAT}_fw_config.dts \ + ${SGI575_BASE}/fdts/${PLAT}_tb_fw_config.dts +FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb + +# Add the FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config)) # Add the TB_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) diff --git a/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts b/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts index c92c1d055..5d478e9a5 100644 --- a/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts +++ b/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts @@ -12,30 +12,10 @@ dtb-registry { compatible = "fconf,dyn_cfg-dtb_registry"; - /* tb_fw_config is temporarily contained on this dtb */ tb_fw-config { - load-address = <0x0 0x4001010>; + load-address = <0x0 0x4001300>; max-size = <0x200>; id = ; }; }; - - tb_fw-config { - compatible = "arm,tb_fw"; - - /* Disable authentication for development */ - disable_auth = <0x0>; - - /* - * The following two entries are placeholders for Mbed TLS - * heap information. The default values don't matter since - * they will be overwritten by BL1. - * In case of having shared Mbed TLS heap between BL1 and BL2, - * BL1 will populate these two properties with the respective - * info about the shared heap. This info will be available for - * BL2 in order to locate and re-use the heap. - */ - mbedtls_heap_addr = <0x0 0x0>; - mbedtls_heap_size = <0x0>; - }; }; diff --git a/plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts b/plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts new file mode 100644 index 000000000..49eda2735 --- /dev/null +++ b/plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +/ { + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + + /* + * The following two entries are placeholders for Mbed TLS + * heap information. The default values don't matter since + * they will be overwritten by BL1. + * In case of having shared Mbed TLS heap between BL1 and BL2, + * BL1 will populate these two properties with the respective + * info about the shared heap. This info will be available for + * BL2 in order to locate and re-use the heap. + */ + mbedtls_heap_addr = <0x0 0x0>; + mbedtls_heap_size = <0x0>; + }; +}; diff --git a/plat/arm/board/sgm775/platform.mk b/plat/arm/board/sgm775/platform.mk index 57edb923d..26bc25dec 100644 --- a/plat/arm/board/sgm775/platform.mk +++ b/plat/arm/board/sgm775/platform.mk @@ -9,9 +9,13 @@ include plat/arm/css/sgm/sgm-common.mk SGM775_BASE= plat/arm/board/sgm775 # Add the FDT_SOURCES and options for Dynamic Config -FDT_SOURCES += ${SGM775_BASE}/fdts/${PLAT}_fw_config.dts -TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +FDT_SOURCES += ${SGM775_BASE}/fdts/${PLAT}_fw_config.dts \ + ${SGM775_BASE}/fdts/${PLAT}_tb_fw_config.dts +FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb +# Add the FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config)) # Add the TB_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) diff --git a/plat/arm/board/tc0/fdts/tc0_fw_config.dts b/plat/arm/board/tc0/fdts/tc0_fw_config.dts index 8458e0889..381ce1fcb 100644 --- a/plat/arm/board/tc0/fdts/tc0_fw_config.dts +++ b/plat/arm/board/tc0/fdts/tc0_fw_config.dts @@ -12,9 +12,8 @@ dtb-registry { compatible = "fconf,dyn_cfg-dtb_registry"; - /* tb_fw_config is temporarily contained in this dtb */ tb_fw-config { - load-address = <0x0 0x4001010>; + load-address = <0x0 0x4001300>; max-size = <0x200>; id = ; }; @@ -25,22 +24,4 @@ id = ; }; }; - - tb_fw-config { - compatible = "arm,tb_fw"; - - /* Disable authentication for development */ - disable_auth = <0x0>; - /* - * The following two entries are placeholders for Mbed TLS - * heap information. The default values don't matter since - * they will be overwritten by BL1. - * In case of having shared Mbed TLS heap between BL1 and BL2, - * BL1 will populate these two properties with the respective - * info about the shared heap. This info will be available for - * BL2 in order to locate and re-use the heap. - */ - mbedtls_heap_addr = <0x0 0x0>; - mbedtls_heap_size = <0x0>; - }; }; diff --git a/plat/arm/board/tc0/fdts/tc0_tb_fw_config.dts b/plat/arm/board/tc0/fdts/tc0_tb_fw_config.dts new file mode 100644 index 000000000..2fd25d9b4 --- /dev/null +++ b/plat/arm/board/tc0/fdts/tc0_tb_fw_config.dts @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +/ { + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + /* + * The following two entries are placeholders for Mbed TLS + * heap information. The default values don't matter since + * they will be overwritten by BL1. + * In case of having shared Mbed TLS heap between BL1 and BL2, + * BL1 will populate these two properties with the respective + * info about the shared heap. This info will be available for + * BL2 in order to locate and re-use the heap. + */ + mbedtls_heap_addr = <0x0 0x0>; + mbedtls_heap_size = <0x0>; + }; +}; diff --git a/plat/arm/board/tc0/platform.mk b/plat/arm/board/tc0/platform.mk index 7f514cc67..0bf18e437 100644 --- a/plat/arm/board/tc0/platform.mk +++ b/plat/arm/board/tc0/platform.mk @@ -73,9 +73,13 @@ BL31_SOURCES += ${INTERCONNECT_SOURCES} \ plat/arm/common/arm_nor_psci_mem_protect.c # Add the FDT_SOURCES and options for Dynamic Config -FDT_SOURCES += ${TC0_BASE}/fdts/${PLAT}_fw_config.dts -TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +FDT_SOURCES += ${TC0_BASE}/fdts/${PLAT}_fw_config.dts \ + ${TC0_BASE}/fdts/${PLAT}_tb_fw_config.dts +FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb +# Add the FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config)) # Add the TB_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) diff --git a/plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts b/plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts index d48101842..e41654048 100644 --- a/plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts +++ b/plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ -- cgit v1.2.3 From ce10f9f4629181ce9cb0b574c9cde1fad94a5027 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Thu, 11 Jun 2020 21:02:03 +0100 Subject: fiptool: Add fw_config in FIP Added support in fiptool to include fw_config image in FIP. Signed-off-by: Manish V Badarkhe Change-Id: Ibbd14723a4141598d9d7f6bfcf88a0ef92cf87bc --- include/tools_share/firmware_image_package.h | 4 +++- lib/debugfs/devfip.c | 1 + tools/fiptool/tbbr_config.c | 7 ++++++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/include/tools_share/firmware_image_package.h b/include/tools_share/firmware_image_package.h index 75f3cc6a6..7342c0ced 100644 --- a/include/tools_share/firmware_image_package.h +++ b/include/tools_share/firmware_image_package.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -77,6 +77,8 @@ {{0x26, 0x25, 0x7c, 0x1a}, {0xdb, 0xc6}, {0x7f, 0x47}, 0x8d, 0x96, {0xc4, 0xc4, 0xb0, 0x24, 0x80, 0x21} } #define UUID_NT_FW_CONFIG \ {{0x28, 0xda, 0x98, 0x15}, {0x93, 0xe8}, {0x7e, 0x44}, 0xac, 0x66, {0x1a, 0xaf, 0x80, 0x15, 0x50, 0xf9} } +#define UUID_FW_CONFIG \ + {{0x58, 0x07, 0xe1, 0x6a}, {0x84, 0x59}, {0x47, 0xbe}, 0x8e, 0xd5, {0x64, 0x8e, 0x8d, 0xdd, 0xab, 0x0e} } typedef struct fip_toc_header { uint32_t name; diff --git a/lib/debugfs/devfip.c b/lib/debugfs/devfip.c index 70ac3bc04..b0ee39a11 100644 --- a/lib/debugfs/devfip.c +++ b/lib/debugfs/devfip.c @@ -73,6 +73,7 @@ static const struct uuidnames uuidnames[] = { {"soc-fw.cfg", UUID_SOC_FW_CONFIG}, {"tos-fw.cfg", UUID_TOS_FW_CONFIG}, {"nt-fw.cfg", UUID_NT_FW_CONFIG}, + {"fw.cfg", UUID_FW_CONFIG}, {"rot-k.crt", UUID_ROT_KEY_CERT}, {"nt-k.crt", UUID_NON_TRUSTED_WORLD_KEY_CERT}, {"sip-sp.crt", UUID_SIP_SECURE_PARTITION_CONTENT_CERT} diff --git a/tools/fiptool/tbbr_config.c b/tools/fiptool/tbbr_config.c index 1c5ef5f59..bf721c1fa 100644 --- a/tools/fiptool/tbbr_config.c +++ b/tools/fiptool/tbbr_config.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -68,6 +68,11 @@ toc_entry_t toc_entries[] = { .cmdline_name = "nt-fw" }, /* Dynamic Configs */ + { + .name = "FW_CONFIG", + .uuid = UUID_FW_CONFIG, + .cmdline_name = "fw-config" + }, { .name = "HW_CONFIG", .uuid = UUID_HW_CONFIG, -- cgit v1.2.3 From 9b3ca9b120b2bd4ea15114872aba06229422770e Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Thu, 11 Jun 2020 21:08:45 +0100 Subject: cert_tool: Update cert_tool for fw_config image support Updated cert_tool to add hash information of fw_config image into the existing "trusted boot fw" certificate. Signed-off-by: Manish V Badarkhe Change-Id: I720319225925806a2a9f50a1ac9c8a464be975f0 --- include/tools_share/tbbr_oid.h | 3 ++- tools/cert_create/include/dualroot/cot.h | 1 + tools/cert_create/include/tbbr/tbb_ext.h | 3 ++- tools/cert_create/src/dualroot/cot.c | 16 ++++++++++++++-- tools/cert_create/src/tbbr/tbb_cert.c | 7 ++++--- tools/cert_create/src/tbbr/tbb_ext.c | 12 +++++++++++- 6 files changed, 34 insertions(+), 8 deletions(-) diff --git a/include/tools_share/tbbr_oid.h b/include/tools_share/tbbr_oid.h index 24a8f39ca..37d87d307 100644 --- a/include/tools_share/tbbr_oid.h +++ b/include/tools_share/tbbr_oid.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -43,6 +43,7 @@ #define TRUSTED_BOOT_FW_HASH_OID "1.3.6.1.4.1.4128.2100.201" #define TRUSTED_BOOT_FW_CONFIG_HASH_OID "1.3.6.1.4.1.4128.2100.202" #define HW_CONFIG_HASH_OID "1.3.6.1.4.1.4128.2100.203" +#define FW_CONFIG_HASH_OID "1.3.6.1.4.1.4128.2100.204" /* * Trusted Key Certificate diff --git a/tools/cert_create/include/dualroot/cot.h b/tools/cert_create/include/dualroot/cot.h index 47e371fe1..1d959d465 100644 --- a/tools/cert_create/include/dualroot/cot.h +++ b/tools/cert_create/include/dualroot/cot.h @@ -32,6 +32,7 @@ enum { TRUSTED_BOOT_FW_HASH_EXT, TRUSTED_BOOT_FW_CONFIG_HASH_EXT, HW_CONFIG_HASH_EXT, + FW_CONFIG_HASH_EXT, TRUSTED_WORLD_PK_EXT, SCP_FW_CONTENT_CERT_PK_EXT, SCP_FW_HASH_EXT, diff --git a/tools/cert_create/include/tbbr/tbb_ext.h b/tools/cert_create/include/tbbr/tbb_ext.h index 7ac97a513..692b2d4d3 100644 --- a/tools/cert_create/include/tbbr/tbb_ext.h +++ b/tools/cert_create/include/tbbr/tbb_ext.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -15,6 +15,7 @@ enum { TRUSTED_BOOT_FW_HASH_EXT, TRUSTED_BOOT_FW_CONFIG_HASH_EXT, HW_CONFIG_HASH_EXT, + FW_CONFIG_HASH_EXT, TRUSTED_WORLD_PK_EXT, NON_TRUSTED_WORLD_PK_EXT, SCP_FW_CONTENT_CERT_PK_EXT, diff --git a/tools/cert_create/src/dualroot/cot.c b/tools/cert_create/src/dualroot/cot.c index 29658281c..a12ea21ff 100644 --- a/tools/cert_create/src/dualroot/cot.c +++ b/tools/cert_create/src/dualroot/cot.c @@ -30,9 +30,10 @@ static cert_t cot_certs[] = { TRUSTED_FW_NVCOUNTER_EXT, TRUSTED_BOOT_FW_HASH_EXT, TRUSTED_BOOT_FW_CONFIG_HASH_EXT, - HW_CONFIG_HASH_EXT + HW_CONFIG_HASH_EXT, + FW_CONFIG_HASH_EXT }, - .num_ext = 4 + .num_ext = 5 }, [TRUSTED_KEY_CERT] = { @@ -239,6 +240,17 @@ static ext_t cot_ext[] = { .optional = 1 }, + [FW_CONFIG_HASH_EXT] = { + .oid = FW_CONFIG_HASH_OID, + .opt = "fw-config", + .help_msg = "Firmware Config file", + .sn = "FirmwareConfigHash", + .ln = "Firmware Config hash", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_HASH, + .optional = 1 + }, + [TRUSTED_WORLD_PK_EXT] = { .oid = TRUSTED_WORLD_PK_OID, .sn = "TrustedWorldPublicKey", diff --git a/tools/cert_create/src/tbbr/tbb_cert.c b/tools/cert_create/src/tbbr/tbb_cert.c index b614e2e49..f4fe63dc3 100644 --- a/tools/cert_create/src/tbbr/tbb_cert.c +++ b/tools/cert_create/src/tbbr/tbb_cert.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -28,9 +28,10 @@ static cert_t tbb_certs[] = { TRUSTED_FW_NVCOUNTER_EXT, TRUSTED_BOOT_FW_HASH_EXT, TRUSTED_BOOT_FW_CONFIG_HASH_EXT, - HW_CONFIG_HASH_EXT + HW_CONFIG_HASH_EXT, + FW_CONFIG_HASH_EXT }, - .num_ext = 4 + .num_ext = 5 }, [TRUSTED_KEY_CERT] = { .id = TRUSTED_KEY_CERT, diff --git a/tools/cert_create/src/tbbr/tbb_ext.c b/tools/cert_create/src/tbbr/tbb_ext.c index 0068d3b4a..60bafb4be 100644 --- a/tools/cert_create/src/tbbr/tbb_ext.c +++ b/tools/cert_create/src/tbbr/tbb_ext.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -69,6 +69,16 @@ static ext_t tbb_ext[] = { .type = EXT_TYPE_HASH, .optional = 1 }, + [FW_CONFIG_HASH_EXT] = { + .oid = FW_CONFIG_HASH_OID, + .opt = "fw-config", + .help_msg = "Firmware Config file", + .sn = "FirmwareConfigHash", + .ln = "Firmware Config hash", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_HASH, + .optional = 1 + }, [TRUSTED_WORLD_PK_EXT] = { .oid = TRUSTED_WORLD_PK_OID, .sn = "TrustedWorldPublicKey", -- cgit v1.2.3 From 243875eaf9df591aec14c20075c70cb5af7dd9e9 Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Thu, 11 Jun 2020 21:15:15 +0100 Subject: tbbr/dualroot: Add fw_config image in chain of trust fw_config image is authenticated using secure boot framework by adding it into the single root and dual root chain of trust. The COT for fw_config image looks as below: +------------------+ +-------------------+ | ROTPK/ROTPK Hash |------>| Trusted Boot fw | +------------------+ | Certificate | | (Auth Image) | /+-------------------+ / | / | / | / | L v +------------------+ +-------------------+ | fw_config hash |------>| fw_config | | | | (Data Image) | +------------------+ +-------------------+ Signed-off-by: Louis Mayencourt Signed-off-by: Manish V Badarkhe Change-Id: I08fc8ee95c29a95bb140c807dd06e772474c7367 --- drivers/auth/dualroot/cot.c | 27 +++++++++++++++++++++++++++ drivers/auth/tbbr/tbbr_cot_bl1.c | 16 ++++++++++++++++ drivers/auth/tbbr/tbbr_cot_common.c | 16 +++++++++++++--- include/drivers/auth/tbbr_cot_common.h | 4 +--- include/export/common/tbbr/tbbr_img_def_exp.h | 7 +++++-- plat/arm/common/fconf/arm_fconf_io.c | 6 ++++++ 6 files changed, 68 insertions(+), 8 deletions(-) diff --git a/drivers/auth/dualroot/cot.c b/drivers/auth/dualroot/cot.c index f28ddaa91..31e5d65f4 100644 --- a/drivers/auth/dualroot/cot.c +++ b/drivers/auth/dualroot/cot.c @@ -16,6 +16,7 @@ * Allocate static buffers to store the authentication parameters extracted from * the certificates. */ +static unsigned char fw_config_hash_buf[HASH_DER_LEN]; static unsigned char tb_fw_hash_buf[HASH_DER_LEN]; static unsigned char tb_fw_config_hash_buf[HASH_DER_LEN]; static unsigned char hw_config_hash_buf[HASH_DER_LEN]; @@ -58,6 +59,8 @@ static auth_param_type_desc_t tb_fw_config_hash = AUTH_PARAM_TYPE_DESC( AUTH_PARAM_HASH, TRUSTED_BOOT_FW_CONFIG_HASH_OID); static auth_param_type_desc_t hw_config_hash = AUTH_PARAM_TYPE_DESC( AUTH_PARAM_HASH, HW_CONFIG_HASH_OID); +static auth_param_type_desc_t fw_config_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, FW_CONFIG_HASH_OID); #ifdef IMAGE_BL1 static auth_param_type_desc_t scp_bl2u_hash = AUTH_PARAM_TYPE_DESC( AUTH_PARAM_HASH, SCP_FWU_CFG_HASH_OID); @@ -165,6 +168,13 @@ static const auth_img_desc_t trusted_boot_fw_cert = { .ptr = (void *)hw_config_hash_buf, .len = (unsigned int)HASH_DER_LEN } + }, + [3] = { + .type_desc = &fw_config_hash, + .data = { + .ptr = (void *)fw_config_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } } } }; @@ -218,6 +228,22 @@ static const auth_img_desc_t tb_fw_config = { } } }; + +static const auth_img_desc_t fw_config = { + .img_id = FW_CONFIG_ID, + .img_type = IMG_RAW, + .parent = &trusted_boot_fw_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &fw_config_hash + } + } + } +}; + #endif /* IMAGE_BL1 */ #ifdef IMAGE_BL2 @@ -860,6 +886,7 @@ static const auth_img_desc_t * const cot_desc[] = { [BL2_IMAGE_ID] = &bl2_image, [HW_CONFIG_ID] = &hw_config, [TB_FW_CONFIG_ID] = &tb_fw_config, + [FW_CONFIG_ID] = &fw_config, [FWU_CERT_ID] = &fwu_cert, [SCP_BL2U_IMAGE_ID] = &scp_bl2u_image, [BL2U_IMAGE_ID] = &bl2u_image, diff --git a/drivers/auth/tbbr/tbbr_cot_bl1.c b/drivers/auth/tbbr/tbbr_cot_bl1.c index f3bb37674..e4c92213a 100644 --- a/drivers/auth/tbbr/tbbr_cot_bl1.c +++ b/drivers/auth/tbbr/tbbr_cot_bl1.c @@ -150,6 +150,21 @@ static const auth_img_desc_t tb_fw_config = { } }; +static const auth_img_desc_t fw_config = { + .img_id = FW_CONFIG_ID, + .img_type = IMG_RAW, + .parent = &trusted_boot_fw_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &fw_config_hash + } + } + } +}; + /* * TBBR Chain of trust definition */ @@ -158,6 +173,7 @@ static const auth_img_desc_t * const cot_desc[] = { [BL2_IMAGE_ID] = &bl2_image, [HW_CONFIG_ID] = &hw_config, [TB_FW_CONFIG_ID] = &tb_fw_config, + [FW_CONFIG_ID] = &fw_config, [FWU_CERT_ID] = &fwu_cert, [SCP_BL2U_IMAGE_ID] = &scp_bl2u_image, [BL2U_IMAGE_ID] = &bl2u_image, diff --git a/drivers/auth/tbbr/tbbr_cot_common.c b/drivers/auth/tbbr/tbbr_cot_common.c index 0a4b75e00..ff3f22de1 100644 --- a/drivers/auth/tbbr/tbbr_cot_common.c +++ b/drivers/auth/tbbr/tbbr_cot_common.c @@ -23,9 +23,10 @@ * established, we can reuse some of the buffers on different stages */ +static unsigned char fw_config_hash_buf[HASH_DER_LEN]; +static unsigned char tb_fw_config_hash_buf[HASH_DER_LEN]; +static unsigned char hw_config_hash_buf[HASH_DER_LEN]; unsigned char tb_fw_hash_buf[HASH_DER_LEN]; -unsigned char tb_fw_config_hash_buf[HASH_DER_LEN]; -unsigned char hw_config_hash_buf[HASH_DER_LEN]; unsigned char scp_fw_hash_buf[HASH_DER_LEN]; unsigned char nt_world_bl_hash_buf[HASH_DER_LEN]; @@ -48,7 +49,9 @@ auth_param_type_desc_t tb_fw_hash = AUTH_PARAM_TYPE_DESC( AUTH_PARAM_HASH, TRUSTED_BOOT_FW_HASH_OID); auth_param_type_desc_t tb_fw_config_hash = AUTH_PARAM_TYPE_DESC( AUTH_PARAM_HASH, TRUSTED_BOOT_FW_CONFIG_HASH_OID); -auth_param_type_desc_t hw_config_hash = AUTH_PARAM_TYPE_DESC( +auth_param_type_desc_t fw_config_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, FW_CONFIG_HASH_OID); +static auth_param_type_desc_t hw_config_hash = AUTH_PARAM_TYPE_DESC( AUTH_PARAM_HASH, HW_CONFIG_HASH_OID); /* trusted_boot_fw_cert */ @@ -95,6 +98,13 @@ const auth_img_desc_t trusted_boot_fw_cert = { .ptr = (void *)hw_config_hash_buf, .len = (unsigned int)HASH_DER_LEN } + }, + [3] = { + .type_desc = &fw_config_hash, + .data = { + .ptr = (void *)fw_config_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } } } }; diff --git a/include/drivers/auth/tbbr_cot_common.h b/include/drivers/auth/tbbr_cot_common.h index 0ea5f6575..a51faee1a 100644 --- a/include/drivers/auth/tbbr_cot_common.h +++ b/include/drivers/auth/tbbr_cot_common.h @@ -10,8 +10,6 @@ #include extern unsigned char tb_fw_hash_buf[HASH_DER_LEN]; -extern unsigned char tb_fw_config_hash_buf[HASH_DER_LEN]; -extern unsigned char hw_config_hash_buf[HASH_DER_LEN]; extern unsigned char scp_fw_hash_buf[HASH_DER_LEN]; extern unsigned char nt_world_bl_hash_buf[HASH_DER_LEN]; @@ -23,7 +21,7 @@ extern auth_param_type_desc_t raw_data; extern auth_param_type_desc_t tb_fw_hash; extern auth_param_type_desc_t tb_fw_config_hash; -extern auth_param_type_desc_t hw_config_hash; +extern auth_param_type_desc_t fw_config_hash; extern const auth_img_desc_t trusted_boot_fw_cert; extern const auth_img_desc_t hw_config; diff --git a/include/export/common/tbbr/tbbr_img_def_exp.h b/include/export/common/tbbr/tbbr_img_def_exp.h index a98c1b4f6..18f012513 100644 --- a/include/export/common/tbbr/tbbr_img_def_exp.h +++ b/include/export/common/tbbr/tbbr_img_def_exp.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -88,7 +88,10 @@ /* Encrypted image identifier */ #define ENC_IMAGE_ID U(30) +/* FW_CONFIG */ +#define FW_CONFIG_ID U(31) + /* Max Images */ -#define MAX_IMAGE_IDS U(31) +#define MAX_IMAGE_IDS U(32) #endif /* ARM_TRUSTED_FIRMWARE_EXPORT_COMMON_TBBR_TBBR_IMG_DEF_EXP_H */ diff --git a/plat/arm/common/fconf/arm_fconf_io.c b/plat/arm/common/fconf/arm_fconf_io.c index 68cd9fb37..48cc4fee3 100644 --- a/plat/arm/common/fconf/arm_fconf_io.c +++ b/plat/arm/common/fconf/arm_fconf_io.c @@ -25,6 +25,7 @@ const io_block_spec_t fip_block_spec = { const io_uuid_spec_t arm_uuid_spec[MAX_NUMBER_IDS] = { [BL2_IMAGE_ID] = {UUID_TRUSTED_BOOT_FIRMWARE_BL2}, [TB_FW_CONFIG_ID] = {UUID_TB_FW_CONFIG}, + [FW_CONFIG_ID] = {UUID_FW_CONFIG}, #if !ARM_IO_IN_DTB [SCP_BL2_IMAGE_ID] = {UUID_SCP_FIRMWARE_SCP_BL2}, [BL31_IMAGE_ID] = {UUID_EL3_RUNTIME_FIRMWARE_BL31}, @@ -73,6 +74,11 @@ struct plat_io_policy policies[MAX_NUMBER_IDS] = { (uintptr_t)&arm_uuid_spec[TB_FW_CONFIG_ID], open_fip }, + [FW_CONFIG_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[FW_CONFIG_ID], + open_fip + }, #if !ARM_IO_IN_DTB [SCP_BL2_IMAGE_ID] = { &fip_dev_handle, -- cgit v1.2.3 From 04e06973e1fef87849c498c7f045aa2be8aada1c Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Sun, 31 May 2020 10:17:59 +0100 Subject: fconf: Clean confused naming between TB_FW and FW_CONFIG Cleaned up confused naming between TB_FW and FW_CONFIG. Signed-off-by: Louis Mayencourt Signed-off-by: Manish V Badarkhe Change-Id: I9e9f6e6ca076d38fee0388f97d370431ae067f08 --- drivers/arm/css/scp/css_bom_bootloader.c | 8 ++++---- include/drivers/arm/css/css_scp.h | 8 ++++---- include/plat/arm/common/arm_def.h | 16 ++++++++-------- lib/fconf/fconf.c | 4 ++-- plat/arm/board/a5ds/include/platform_def.h | 8 ++++---- plat/arm/board/corstone700/include/platform_def.h | 6 +++--- plat/arm/board/fvp_ve/include/platform_def.h | 8 ++++---- plat/arm/board/juno/include/platform_def.h | 2 +- plat/arm/common/arm_bl2_setup.c | 10 +++++----- plat/arm/common/arm_bl31_setup.c | 4 ++-- plat/arm/common/arm_dyn_cfg.c | 4 ++-- plat/arm/common/sp_min/arm_sp_min_setup.c | 4 ++-- plat/arm/css/sgm/include/sgm_base_platform_def.h | 2 +- 13 files changed, 42 insertions(+), 42 deletions(-) diff --git a/drivers/arm/css/scp/css_bom_bootloader.c b/drivers/arm/css/scp/css_bom_bootloader.c index 1fc1270ba..74121b487 100644 --- a/drivers/arm/css/scp/css_bom_bootloader.c +++ b/drivers/arm/css/scp/css_bom_bootloader.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -51,13 +51,13 @@ typedef struct { * All CSS platforms load SCP_BL2/SCP_BL2U just below BL2 (this is where BL31 * usually resides except when ARM_BL31_IN_DRAM is * set). Ensure that SCP_BL2/SCP_BL2U do not overflow into shared RAM and - * the tb_fw_config. + * the fw_config. */ CASSERT(SCP_BL2_LIMIT <= BL2_BASE, assert_scp_bl2_overwrite_bl2); CASSERT(SCP_BL2U_LIMIT <= BL2_BASE, assert_scp_bl2u_overwrite_bl2); -CASSERT(SCP_BL2_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_scp_bl2_overflow); -CASSERT(SCP_BL2U_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_scp_bl2u_overflow); +CASSERT(SCP_BL2_BASE >= ARM_FW_CONFIG_LIMIT, assert_scp_bl2_overflow); +CASSERT(SCP_BL2U_BASE >= ARM_FW_CONFIG_LIMIT, assert_scp_bl2u_overflow); static void scp_boot_message_start(void) { diff --git a/include/drivers/arm/css/css_scp.h b/include/drivers/arm/css/css_scp.h index f3c08c52f..2b506eaaf 100644 --- a/include/drivers/arm/css/css_scp.h +++ b/include/drivers/arm/css/css_scp.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -40,13 +40,13 @@ int css_scp_boot_ready(void); /* * All CSS platforms load SCP_BL2/SCP_BL2U just below BL2 (this is where BL31 * usually resides except when ARM_BL31_IN_DRAM is - * set). Ensure that SCP_BL2/SCP_BL2U do not overflow into tb_fw_config. + * set). Ensure that SCP_BL2/SCP_BL2U do not overflow into fw_config. */ CASSERT(SCP_BL2_LIMIT <= BL2_BASE, assert_scp_bl2_overwrite_bl2); CASSERT(SCP_BL2U_LIMIT <= BL2_BASE, assert_scp_bl2u_overwrite_bl2); -CASSERT(SCP_BL2_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_scp_bl2_overflow); -CASSERT(SCP_BL2U_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_scp_bl2u_overflow); +CASSERT(SCP_BL2_BASE >= ARM_FW_CONFIG_LIMIT, assert_scp_bl2_overflow); +CASSERT(SCP_BL2U_BASE >= ARM_FW_CONFIG_LIMIT, assert_scp_bl2u_overflow); #endif #endif /* CSS_SCP_H */ diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index 89f7c6146..a6b6b2eab 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -346,24 +346,24 @@ #define CACHE_WRITEBACK_GRANULE (U(1) << ARM_CACHE_WRITEBACK_SHIFT) /* - * To enable TB_FW_CONFIG to be loaded by BL1, define the corresponding base + * To enable FW_CONFIG to be loaded by BL1, define the corresponding base * and limit. Leave enough space of BL2 meminfo. */ -#define ARM_TB_FW_CONFIG_BASE (ARM_BL_RAM_BASE + sizeof(meminfo_t)) -#define ARM_TB_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + (PAGE_SIZE / 2U)) +#define ARM_FW_CONFIG_BASE (ARM_BL_RAM_BASE + sizeof(meminfo_t)) +#define ARM_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + (PAGE_SIZE / 2U)) /* * Boot parameters passed from BL2 to BL31/BL32 are stored here */ -#define ARM_BL2_MEM_DESC_BASE ARM_TB_FW_CONFIG_LIMIT +#define ARM_BL2_MEM_DESC_BASE ARM_FW_CONFIG_LIMIT #define ARM_BL2_MEM_DESC_LIMIT (ARM_BL2_MEM_DESC_BASE + \ (PAGE_SIZE / 2U)) /* * Define limit of firmware configuration memory: - * ARM_TB_FW_CONFIG + ARM_BL2_MEM_DESC memory + * ARM_FW_CONFIG + ARM_BL2_MEM_DESC memory */ -#define ARM_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + PAGE_SIZE) +#define ARM_FW_CONFIGS_LIMIT (ARM_BL_RAM_BASE + PAGE_SIZE) /******************************************************************************* * BL1 specific defines. @@ -461,7 +461,7 @@ * SP_MIN is the only BL image in SRAM. Allocate the whole of SRAM (excluding * the page reserved for fw_configs) to BL32 */ -# define BL32_BASE ARM_FW_CONFIG_LIMIT +# define BL32_BASE ARM_FW_CONFIGS_LIMIT # define BL32_LIMIT (ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE) # else /* Put BL32 below BL2 in the Trusted SRAM.*/ @@ -505,7 +505,7 @@ # define TSP_SEC_MEM_BASE ARM_BL_RAM_BASE # define TSP_SEC_MEM_SIZE ARM_BL_RAM_SIZE # define TSP_PROGBITS_LIMIT BL31_BASE -# define BL32_BASE ARM_FW_CONFIG_LIMIT +# define BL32_BASE ARM_FW_CONFIGS_LIMIT # define BL32_LIMIT BL31_BASE # elif ARM_TSP_RAM_LOCATION_ID == ARM_TRUSTED_DRAM_ID # define TSP_SEC_MEM_BASE PLAT_ARM_TRUSTED_DRAM_BASE diff --git a/lib/fconf/fconf.c b/lib/fconf/fconf.c index a5ec14300..b99e7f0fa 100644 --- a/lib/fconf/fconf.c +++ b/lib/fconf/fconf.c @@ -24,9 +24,9 @@ void fconf_load_config(void) .h.version = (uint8_t)VERSION_2, .h.size = (uint16_t)sizeof(image_info_t), .h.attr = 0, - .image_base = ARM_TB_FW_CONFIG_BASE, + .image_base = ARM_FW_CONFIG_BASE, .image_max_size = (uint32_t) - (ARM_TB_FW_CONFIG_LIMIT - ARM_TB_FW_CONFIG_BASE) + (ARM_FW_CONFIG_LIMIT - ARM_FW_CONFIG_BASE) }; VERBOSE("FCONF: Loading FW_CONFIG\n"); diff --git a/plat/arm/board/a5ds/include/platform_def.h b/plat/arm/board/a5ds/include/platform_def.h index ab0ff5859..07453166a 100644 --- a/plat/arm/board/a5ds/include/platform_def.h +++ b/plat/arm/board/a5ds/include/platform_def.h @@ -188,11 +188,11 @@ #define CACHE_WRITEBACK_GRANULE (U(1) << ARM_CACHE_WRITEBACK_SHIFT) /* - * To enable TB_FW_CONFIG to be loaded by BL1, define the corresponding base + * To enable FW_CONFIG to be loaded by BL1, define the corresponding base * and limit. Leave enough space of BL2 meminfo. */ -#define ARM_TB_FW_CONFIG_BASE (ARM_BL_RAM_BASE + sizeof(meminfo_t)) -#define ARM_TB_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + PAGE_SIZE) +#define ARM_FW_CONFIG_BASE (ARM_BL_RAM_BASE + sizeof(meminfo_t)) +#define ARM_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + PAGE_SIZE) /******************************************************************************* * BL1 specific defines. @@ -220,7 +220,7 @@ #define BL2_LIMIT BL1_RW_BASE /* Put BL32 below BL2 in NS DRAM.*/ -#define ARM_BL2_MEM_DESC_BASE ARM_TB_FW_CONFIG_LIMIT +#define ARM_BL2_MEM_DESC_BASE ARM_FW_CONFIG_LIMIT #define BL32_BASE ((ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE)\ - PLAT_ARM_MAX_BL32_SIZE) diff --git a/plat/arm/board/corstone700/include/platform_def.h b/plat/arm/board/corstone700/include/platform_def.h index cc4dc3a59..7799cec00 100644 --- a/plat/arm/board/corstone700/include/platform_def.h +++ b/plat/arm/board/corstone700/include/platform_def.h @@ -83,11 +83,11 @@ #define ARM_CACHE_WRITEBACK_SHIFT 6 /* - * To enable TB_FW_CONFIG to be loaded by BL1, define the corresponding base + * To enable FW_CONFIG to be loaded by BL1, define the corresponding base * and limit. Leave enough space for BL2 meminfo. */ -#define ARM_TB_FW_CONFIG_BASE (ARM_BL_RAM_BASE + sizeof(meminfo_t)) -#define ARM_TB_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + (PAGE_SIZE / 2U)) +#define ARM_FW_CONFIG_BASE (ARM_BL_RAM_BASE + sizeof(meminfo_t)) +#define ARM_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + (PAGE_SIZE / 2U)) /* * The max number of regions like RO(code), coherent and data required by diff --git a/plat/arm/board/fvp_ve/include/platform_def.h b/plat/arm/board/fvp_ve/include/platform_def.h index 70a12ea53..3591b4d6d 100644 --- a/plat/arm/board/fvp_ve/include/platform_def.h +++ b/plat/arm/board/fvp_ve/include/platform_def.h @@ -169,11 +169,11 @@ #define CACHE_WRITEBACK_GRANULE (U(1) << ARM_CACHE_WRITEBACK_SHIFT) /* - * To enable TB_FW_CONFIG to be loaded by BL1, define the corresponding base + * To enable FW_CONFIG to be loaded by BL1, define the corresponding base * and limit. Leave enough space of BL2 meminfo. */ -#define ARM_TB_FW_CONFIG_BASE (ARM_BL_RAM_BASE + sizeof(meminfo_t)) -#define ARM_TB_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + PAGE_SIZE) +#define ARM_FW_CONFIG_BASE (ARM_BL_RAM_BASE + sizeof(meminfo_t)) +#define ARM_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + PAGE_SIZE) /******************************************************************************* * BL1 specific defines. @@ -204,7 +204,7 @@ /* Put BL32 below BL2 in NS DRAM.*/ -#define ARM_BL2_MEM_DESC_BASE ARM_TB_FW_CONFIG_LIMIT +#define ARM_BL2_MEM_DESC_BASE ARM_FW_CONFIG_LIMIT #define BL32_BASE ((ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE)\ - PLAT_ARM_MAX_BL32_SIZE) diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h index 67802d487..cd961554a 100644 --- a/plat/arm/board/juno/include/platform_def.h +++ b/plat/arm/board/juno/include/platform_def.h @@ -254,7 +254,7 @@ * BL31 is loaded over the top. */ #define PLAT_CSS_MAX_SCP_BL2_SIZE \ - ((SCP_BL2_LIMIT - ARM_TB_FW_CONFIG_LIMIT) & ~PAGE_SIZE_MASK) + ((SCP_BL2_LIMIT - ARM_FW_CONFIG_LIMIT) & ~PAGE_SIZE_MASK) #define PLAT_CSS_MAX_SCP_BL2U_SIZE PLAT_CSS_MAX_SCP_BL2_SIZE diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c index 6c3f64fb6..9d5526f1b 100644 --- a/plat/arm/common/arm_bl2_setup.c +++ b/plat/arm/common/arm_bl2_setup.c @@ -26,10 +26,10 @@ static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE); /* - * Check that BL2_BASE is above ARM_TB_FW_CONFIG_LIMIT. This reserved page is + * Check that BL2_BASE is above ARM_FW_CONFIG_LIMIT. This reserved page is * for `meminfo_t` data structure and fw_configs passed from BL1. */ -CASSERT(BL2_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_bl2_base_overflows); +CASSERT(BL2_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl2_base_overflows); /* Weak definitions may be overridden in specific ARM standard platform */ #pragma weak bl2_early_platform_setup2 @@ -50,7 +50,7 @@ CASSERT(BL2_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_bl2_base_overflows); * in x0. This memory layout is sitting at the base of the free trusted SRAM. * Copy it to a safe location before its reclaimed by later BL2 functionality. ******************************************************************************/ -void arm_bl2_early_platform_setup(uintptr_t tb_fw_config, +void arm_bl2_early_platform_setup(uintptr_t fw_config, struct meminfo *mem_layout) { /* Initialize the console to provide early debug support */ @@ -60,8 +60,8 @@ void arm_bl2_early_platform_setup(uintptr_t tb_fw_config, bl2_tzram_layout = *mem_layout; /* Fill the properties struct with the info from the config dtb */ - if (tb_fw_config != 0U) { - fconf_populate("TB_FW", tb_fw_config); + if (fw_config != 0U) { + fconf_populate("TB_FW", fw_config); } /* Initialise the IO layer and register platform IO devices */ diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c index 85535c11a..ded8f895e 100644 --- a/plat/arm/common/arm_bl31_setup.c +++ b/plat/arm/common/arm_bl31_setup.c @@ -28,10 +28,10 @@ static entry_point_info_t bl33_image_ep_info; #if !RESET_TO_BL31 /* - * Check that BL31_BASE is above ARM_TB_FW_CONFIG_LIMIT. The reserved page + * Check that BL31_BASE is above ARM_FW_CONFIG_LIMIT. The reserved page * is required for SOC_FW_CONFIG/TOS_FW_CONFIG passed from BL2. */ -CASSERT(BL31_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_bl31_base_overflows); +CASSERT(BL31_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl31_base_overflows); #endif /* Weak definitions may be overridden in specific ARM standard platform */ diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c index ffa2a64d8..416cd1234 100644 --- a/plat/arm/common/arm_dyn_cfg.c +++ b/plat/arm/common/arm_dyn_cfg.c @@ -170,8 +170,8 @@ void arm_bl1_set_bl2_hash(image_desc_t *image_desc) /* * BL2 utility function to initialize dynamic configuration specified by - * TB_FW_CONFIG. Populate the bl_mem_params_node_t of other FW_CONFIGs if - * specified in TB_FW_CONFIG. + * FW_CONFIG. Populate the bl_mem_params_node_t of other FW_CONFIGs if + * specified in FW_CONFIG. */ void arm_bl2_dyn_cfg_init(void) { diff --git a/plat/arm/common/sp_min/arm_sp_min_setup.c b/plat/arm/common/sp_min/arm_sp_min_setup.c index 2904ad942..6100b7834 100644 --- a/plat/arm/common/sp_min/arm_sp_min_setup.c +++ b/plat/arm/common/sp_min/arm_sp_min_setup.c @@ -29,10 +29,10 @@ static entry_point_info_t bl33_image_ep_info; MT_MEMORY | MT_RW | MT_SECURE) /* - * Check that BL32_BASE is above ARM_TB_FW_CONFIG_LIMIT. The reserved page + * Check that BL32_BASE is above ARM_FW_CONFIG_LIMIT. The reserved page * is required for SOC_FW_CONFIG/TOS_FW_CONFIG passed from BL2. */ -CASSERT(BL32_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_bl32_base_overflows); +CASSERT(BL32_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl32_base_overflows); /******************************************************************************* * Return a pointer to the 'entry_point_info' structure of the next image for the diff --git a/plat/arm/css/sgm/include/sgm_base_platform_def.h b/plat/arm/css/sgm/include/sgm_base_platform_def.h index 8be0b344f..2d8e6778f 100644 --- a/plat/arm/css/sgm/include/sgm_base_platform_def.h +++ b/plat/arm/css/sgm/include/sgm_base_platform_def.h @@ -138,7 +138,7 @@ * BL31 is loaded over the top. */ #define PLAT_CSS_MAX_SCP_BL2_SIZE \ - ((SCP_BL2_LIMIT - ARM_TB_FW_CONFIG_LIMIT) & ~PAGE_SIZE_MASK) + ((SCP_BL2_LIMIT - ARM_FW_CONFIG_LIMIT) & ~PAGE_SIZE_MASK) #define PLAT_CSS_MAX_SCP_BL2U_SIZE PLAT_CSS_MAX_SCP_BL2_SIZE -- cgit v1.2.3 From 9233dd09ca3ea96aee6d3a4bfdc798eb4938c1b5 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Thu, 11 Jun 2020 22:17:30 +0100 Subject: fconf: Allow fconf to load additional firmware configuration Modified the `fconf_load_config` function so that it can additionally support loading of tb_fw_config along with fw_config. Signed-off-by: Louis Mayencourt Signed-off-by: Manish V Badarkhe Change-Id: Ie060121d367ba12e3fcac5b8ff169d415a5c2bcd --- include/lib/fconf/fconf.h | 4 ++-- lib/fconf/fconf.c | 47 +++++++++++++++------------------------- lib/fconf/fconf.mk | 2 +- lib/fconf/fconf_dyn_cfg_getter.c | 29 ++++++++++++++++++++++--- 4 files changed, 47 insertions(+), 35 deletions(-) diff --git a/include/lib/fconf/fconf.h b/include/lib/fconf/fconf.h index 09d2b59aa..7020f8698 100644 --- a/include/lib/fconf/fconf.h +++ b/include/lib/fconf/fconf.h @@ -43,8 +43,8 @@ struct fconf_populator { int (*populate)(uintptr_t config); }; -/* Load firmware configuration dtb */ -void fconf_load_config(void); +/* This function supports to load tb_fw_config and fw_config dtb */ +void fconf_load_config(unsigned int image_id); /* Top level populate function * diff --git a/lib/fconf/fconf.c b/lib/fconf/fconf.c index b99e7f0fa..ff16f676a 100644 --- a/lib/fconf/fconf.c +++ b/lib/fconf/fconf.c @@ -9,48 +9,40 @@ #include #include #include +#include #include #include #include -struct fconf_dtb_info_t fconf_dtb_info; - -void fconf_load_config(void) +void fconf_load_config(unsigned int image_id) { int err; - /* fconf FW_CONFIG and TB_FW_CONFIG are currently the same DTB */ - image_info_t arm_tb_fw_info = { + struct dyn_cfg_dtb_info_t *config_info; + + assert((image_id == FW_CONFIG_ID) || (image_id == TB_FW_CONFIG_ID)); + + image_info_t image_info = { .h.type = (uint8_t)PARAM_IMAGE_BINARY, .h.version = (uint8_t)VERSION_2, .h.size = (uint16_t)sizeof(image_info_t), - .h.attr = 0, - .image_base = ARM_FW_CONFIG_BASE, - .image_max_size = (uint32_t) - (ARM_FW_CONFIG_LIMIT - ARM_FW_CONFIG_BASE) + .h.attr = 0 }; - VERBOSE("FCONF: Loading FW_CONFIG\n"); - err = load_auth_image(TB_FW_CONFIG_ID, &arm_tb_fw_info); + config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, image_id); + image_info.image_base = config_info->config_addr; + image_info.image_max_size = config_info->config_max_size; + + VERBOSE("FCONF: Loading config with image ID: %d\n", image_id); + err = load_auth_image(image_id, &image_info); if (err != 0) { - /* Return if FW_CONFIG is not loaded */ - VERBOSE("FW_CONFIG not loaded, continuing without it\n"); + VERBOSE("Failed to load config %d, continuing without it\n", + image_id); return; } - /* At this point we know that a DTB is indeed available */ - fconf_dtb_info.base_addr = arm_tb_fw_info.image_base; - fconf_dtb_info.size = (size_t)arm_tb_fw_info.image_size; + INFO("FCONF: Config file with image ID:%d loaded at address = 0x%lx\n", + image_id, image_info.image_base); -#if !BL2_AT_EL3 - image_desc_t *desc; - - /* The BL2 ep_info arg0 is modified to point to FW_CONFIG */ - desc = bl1_plat_get_image_desc(BL2_IMAGE_ID); - assert(desc != NULL); - desc->ep_info.args.arg0 = arm_tb_fw_info.image_base; -#endif - - INFO("FCONF: FW_CONFIG loaded at address = 0x%lx\n", arm_tb_fw_info.image_base); } void fconf_populate(const char *config_type, uintptr_t config) @@ -81,7 +73,4 @@ void fconf_populate(const char *config_type, uintptr_t config) } } } - - /* save local pointer to the config dtb */ - fconf_dtb_info.base_addr = config; } diff --git a/lib/fconf/fconf.mk b/lib/fconf/fconf.mk index c087102d7..b01dc6fea 100644 --- a/lib/fconf/fconf.mk +++ b/lib/fconf/fconf.mk @@ -8,5 +8,5 @@ FCONF_SOURCES := lib/fconf/fconf.c FCONF_DYN_SOURCES := lib/fconf/fconf_dyn_cfg_getter.c -BL1_SOURCES += ${FCONF_SOURCES} +BL1_SOURCES += ${FCONF_SOURCES} ${FCONF_DYN_SOURCES} BL2_SOURCES += ${FCONF_SOURCES} ${FCONF_DYN_SOURCES} diff --git a/lib/fconf/fconf_dyn_cfg_getter.c b/lib/fconf/fconf_dyn_cfg_getter.c index f1004fad5..1828a80bf 100644 --- a/lib/fconf/fconf_dyn_cfg_getter.c +++ b/lib/fconf/fconf_dyn_cfg_getter.c @@ -12,11 +12,25 @@ #include #include -/* We currently use TB_FW, SOC_FW, TOS_FW, NS_fw and HW configs */ -#define MAX_DTB_INFO U(5) - +/* We currently use FW, TB_FW, SOC_FW, TOS_FW, NS_fw and HW configs */ +#define MAX_DTB_INFO U(6) + +#ifdef IMAGE_BL1 +static struct dyn_cfg_dtb_info_t dtb_infos[MAX_DTB_INFO] = { + [0] = { + .config_addr = ARM_FW_CONFIG_BASE, + .config_max_size = (uint32_t) + (ARM_FW_CONFIG_LIMIT - ARM_FW_CONFIG_BASE), + .config_id = FW_CONFIG_ID + }, +}; +/* Create an object pool starting at the second element */ +static OBJECT_POOL(dtb_info_pool, &dtb_infos[1], + sizeof(struct dyn_cfg_dtb_info_t), MAX_DTB_INFO-1); +#else static struct dyn_cfg_dtb_info_t dtb_infos[MAX_DTB_INFO]; static OBJECT_POOL_ARRAY(dtb_info_pool, dtb_infos); +#endif struct dyn_cfg_dtb_info_t *dyn_cfg_dtb_info_getter(unsigned int config_id) { @@ -56,6 +70,15 @@ int fconf_populate_dtb_registry(uintptr_t config) return node; } +#ifndef IMAGE_BL1 + /* Save config dtb information */ + dtb_info = pool_alloc(&dtb_info_pool); + + dtb_info->config_addr = config; + dtb_info->config_max_size = fdt_totalsize(dtb); + dtb_info->config_id = FW_CONFIG_ID; +#endif + fdt_for_each_subnode(child, dtb, node) { uint32_t val32; uint64_t val64; -- cgit v1.2.3 From fe6fd3e4e05ed3cf7f1a34cf04ee1dab259cab0c Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Thu, 11 Jun 2020 22:09:10 +0100 Subject: plat/arm: Update the fw_config load call and populate it's information Modified the code to do below changes: 1. Migrates the Arm platforms to the API changes introduced in the previous patches by fixing the fconf_load_config() call. 2. Retrieve dynamically the address of tb_fw_config using fconf getter api which is subsequently used to write mbedTLS heap address and BL2 hash data in the tb_fw_config DTB. Signed-off-by: Manish V Badarkhe Signed-off-by: Louis Mayencourt Change-Id: I3c9d9345dcbfb99127c61d5589b4aa1532fbf4be --- plat/arm/common/arm_bl1_setup.c | 4 ++-- plat/arm/common/arm_dyn_cfg.c | 10 ++++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c index c2f49c211..4011dc9fc 100644 --- a/plat/arm/common/arm_bl1_setup.c +++ b/plat/arm/common/arm_bl1_setup.c @@ -145,8 +145,8 @@ void arm_bl1_platform_setup(void) /* Initialise the IO layer and register platform IO devices */ plat_arm_io_setup(); - /* Load fw config */ - fconf_load_config(); + /* Fill the properties struct with the info from the config dtb */ + fconf_load_config(FW_CONFIG_ID); #if TRUSTED_BOARD_BOOT /* Share the Mbed TLS heap info with other images */ diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c index 416cd1234..a28e0ccff 100644 --- a/plat/arm/common/arm_dyn_cfg.c +++ b/plat/arm/common/arm_dyn_cfg.c @@ -77,6 +77,7 @@ void arm_bl1_set_mbedtls_heap(void) { int err; uintptr_t tb_fw_cfg_dtb; + const struct dyn_cfg_dtb_info_t *tb_fw_config_info; /* * If tb_fw_cfg_dtb==NULL then DTB is not present for the current @@ -91,8 +92,8 @@ void arm_bl1_set_mbedtls_heap(void) * the default heap's address and size. */ - /* fconf FW_CONFIG and TB_FW_CONFIG are currently the same DTB */ - tb_fw_cfg_dtb = FCONF_GET_PROPERTY(fconf, dtb, base_addr); + tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID); + tb_fw_cfg_dtb = tb_fw_config_info->config_addr; if ((tb_fw_cfg_dtb != 0UL) && (mbedtls_heap_addr != NULL)) { /* As libfdt use void *, we can't avoid this cast */ @@ -130,9 +131,10 @@ void arm_bl1_set_bl2_hash(image_desc_t *image_desc) 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; - /* fconf FW_CONFIG and TB_FW_CONFIG are currently the same DTB */ - tb_fw_cfg_dtb = FCONF_GET_PROPERTY(fconf, dtb, base_addr); + tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID); + tb_fw_cfg_dtb = tb_fw_config_info->config_addr; /* * If tb_fw_cfg_dtb==NULL then DTB is not present for the current -- cgit v1.2.3 From f17ae7b0a92b83f5e230baee1f1a11b3cbfb2910 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Thu, 11 Jun 2020 22:25:53 +0100 Subject: fconf: Handle error from fconf_load_config Updated 'fconf_load_config' function to return the error. Error from 'fconf_load_config" gets handled by BL1 in subsequent patches. Signed-off-by: Manish V Badarkhe Change-Id: I4360f4df850e355b5762bb2d9666eb285101bc68 --- include/lib/fconf/fconf.h | 2 +- lib/fconf/fconf.c | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/include/lib/fconf/fconf.h b/include/lib/fconf/fconf.h index 7020f8698..917e053bd 100644 --- a/include/lib/fconf/fconf.h +++ b/include/lib/fconf/fconf.h @@ -44,7 +44,7 @@ struct fconf_populator { }; /* This function supports to load tb_fw_config and fw_config dtb */ -void fconf_load_config(unsigned int image_id); +int fconf_load_config(unsigned int image_id); /* Top level populate function * diff --git a/lib/fconf/fconf.c b/lib/fconf/fconf.c index ff16f676a..affec54db 100644 --- a/lib/fconf/fconf.c +++ b/lib/fconf/fconf.c @@ -14,14 +14,14 @@ #include #include -void fconf_load_config(unsigned int image_id) +int fconf_load_config(unsigned int image_id) { int err; - struct dyn_cfg_dtb_info_t *config_info; + const struct dyn_cfg_dtb_info_t *config_info; assert((image_id == FW_CONFIG_ID) || (image_id == TB_FW_CONFIG_ID)); - image_info_t image_info = { + image_info_t config_image_info = { .h.type = (uint8_t)PARAM_IMAGE_BINARY, .h.version = (uint8_t)VERSION_2, .h.size = (uint16_t)sizeof(image_info_t), @@ -29,20 +29,20 @@ void fconf_load_config(unsigned int image_id) }; config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, image_id); - image_info.image_base = config_info->config_addr; - image_info.image_max_size = config_info->config_max_size; + config_image_info.image_base = config_info->config_addr; + config_image_info.image_max_size = (uint32_t)config_info->config_max_size; VERBOSE("FCONF: Loading config with image ID: %d\n", image_id); - err = load_auth_image(image_id, &image_info); + err = load_auth_image(image_id, &config_image_info); if (err != 0) { - VERBOSE("Failed to load config %d, continuing without it\n", - image_id); - return; + VERBOSE("Failed to load config %d\n", image_id); + return err; } INFO("FCONF: Config file with image ID:%d loaded at address = 0x%lx\n", - image_id, image_info.image_base); + image_id, config_image_info.image_base); + return 0; } void fconf_populate(const char *config_type, uintptr_t config) -- cgit v1.2.3 From 1367cc19f189d95cc214d3f7c9055e6acd81c79d Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Mon, 22 Jun 2020 12:11:47 +0200 Subject: Redirect security incident report to TrustedFirmware.org All projects under the TrustedFirmware.org project now use the same security incident process, therefore update the disclosure/vulnerability reporting information in the TF-A documentation. ------------------------------------------------------------------------ /!\ IMPORTANT /!\ Please note that the email address to send these reports to has changed. Please do *not* use trusted-firmware-security@arm.com anymore. Similarly, the PGP key provided to encrypt emails to the security email alias has changed as well. Please do *not* use the former one provided in the TF-A source tree. It is recommended to remove it from your keyring to avoid any mistake. Please use the new key provided on TrustedFirmware.org from now on. ------------------------------------------------------------------------ Change-Id: I14eb61017ab99182f1c45d1e156b96d5764934c1 Signed-off-by: Sandrine Bailleux --- docs/process/security-reporting.asc | 45 --------------------------------- docs/process/security.rst | 50 +++++++++---------------------------- 2 files changed, 12 insertions(+), 83 deletions(-) delete mode 100644 docs/process/security-reporting.asc diff --git a/docs/process/security-reporting.asc b/docs/process/security-reporting.asc deleted file mode 100644 index 8c41f7bf6..000000000 --- a/docs/process/security-reporting.asc +++ /dev/null @@ -1,45 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: PGP Desktop 10.2.0 (Build 2317) - -mQENBFey/QMBCACyxJaLsMYU794ZfzLdY172tHXRJfP0X3b34HU35G7kYl1zNiYc -/NoygtQdtDv/aW1B2A/YTNhGge+gX4BWAREd5CYDbdPEoMWC395/qbnmMmez7YNY -PEJ9Iq9e5AayAWwZTL1zgKwdvE+WTwWok/nMbsifJSEdhdrOIHNqRcZgplUUyZ2R -sDqFtSbACO3xj4Psk8KJ23Ax7UZgULouZOJaHOnyq8F9V/U7zWvX4Odf96XaC1Em -cUTsG0kQfa7Y4Hqqjzowq366I4k2o2LAtuLPWNCvq5jjEceLs2+qV4cNLgyL2dzO -wtUL6EdkrGfkxsPHpsVKXig4wjeX9ehCSqRlABEBAAG0PVRydXN0ZWQgRmlybXdh -cmUgU2VjdXJpdHkgPHRydXN0ZWQtZmlybXdhcmUtc2VjdXJpdHlAYXJtLmNvbT6J -AYwEEAECAHYFAley/SEwFIAAAAAAIAAHcHJlZmVycmVkLWVtYWlsLWVuY29kaW5n -QHBncC5jb21wZ3BtaW1lCAsJCAcDAgEKAhkBGRhsZGFwOi8va2V5c2VydmVyLnBn -cC5jb20FGwMAAAAFFgADAgEFHgEAAAAGFQgJCgMCAAoJEDq378tFoN/QFJsH/0ly -H91LYYzKIQrbolQw7Rp47lgzH88uN1rInYpW2GaTbjwPffAhYJ4VsN8RaiFskD9m -DjMg4vY8p0jPTCUX1Acq20Wq0Ybv3HcrtjUp4ie0+rLUi3043yJyKFMWkJC2Kr+p -SobnxSrAie4HDFUgSaPoh9Qf1zXEzOavdgcziMiyS5iVUf6NXYZ9z82OTZ6TdPKS -u+L5zOHTdrV3+hD54w00Xa+EIE7u4v0to6Uwm977508hyGuvpOVq+u7+S3qJQvnY -+JheStbgLsm6CyoRjyrlTE01ujAD6hI6Ef9yMgEljOBEy4phKAJ67SCRLEOiCp5U -YHFCULwhzIyg2y3WmZSJASIEEAECAAwFAlezAnwFAwASdQAACgkQlxC4m8pXrXzd -GAf/T8YEICI9qQt2vnCtCbBvVaTc2sAphVZ51kZVDqCDPB7znDtJYRBpi/9IPELt -mYwIElMx2mqmahVaeUghmbzmcLZe8QHUi8GanO1mh+ook6uyjRojSIq6VUVV5uUf -tuscfhpilOvUclqMqYEIgXfl08YwS40Kmmj0qokwad0co0zGQ8GEhlgMi2yvJfiG -fPS0Xcn1J0980E/VgJQCAKwZvukrbb32WVwuhgepqs/4/62PZNxglcErioFt6P0A -ik4t9Hr0uErqCeEKiYtmEw5e9ioRdX7CV+tJgIk907Tpv6E0iDFRJHmJBvmsz82O -stOazS3wZ5Xck7asTqkvoyo9Z7kBDQRXsv0DAQgAsmL1UUIWyoNmYJWixSPDmclP -0ul3T1FCOsIlWTeVeshnHByYdgZOfce78ETCUoq8G7qvYm4GRrEDpqVbxqTxJioP -4Li05WDdNCKzSoqWd8ADA48gYnnJEu2NhA7ZkEC6u3+Mdbmd3M0J6nsAWeE0BV1p -F5zI600sJuoH2QNWB7Kv5N3GCFE4IgCIH8MwDo4Y4FTZtygx4GjEtSExiOIz+bpX -2+GkFCQGpIyLHLP4FmQmrsNzsIdEyFuG0IdoVuQ2PtNLiw+Wkm7CXWgRmFx/dtPN -eVnOFWdbTtjBWVv/Z6zbANos2knfc75KR4FCQ6pWRvVeJuMuMopUDkfFDMtR8QAR -AQABiQJBBBgBAgErBQJXsv0EBRsMAAAAwF0gBBkBCAAGBQJXsv0DAAoJENaB8ph8 -s9hu/nsH/Rx696ZR+1vZi5qCTUwo6s0Qa15x4OuyJEM85VgMLVY7/MZpp1Y8If6u -A5BynQpy4QIPxIRsRx6twduW9/gb8UVhpMRPyuJ+5sSv0/KeUqkPbKSUGro2zGlR -sjqPrchi6uafWZqOR/y/DNkEvkgZZaP+f9xs2qWKuoF08yTioo76QoroA4DVuVAT -MkDFe9d3natAmfmjO4kvxuthg3y7R+sdXrCHpYYJZdbiR6gyj7e8whlSLwHQT3lz -7QBL/CvVvL/dmhu5pk8fsksbehepMQTkCJ6GGEamOPEhwh7IvlzhEt97U4uzjuMd -BPjqOCes+4QTmn/+lMTySG0kXxnHOEUACgkQOrfvy0Wg39D8Jgf/Uf3epkMOJ9xm -N1l5vW8tQQ6RR055YQxQ9P6JMyCQGEJmGOcvrasCho69wMQDy4AYVtJaZd25LH/3 -LX/lcyDOP4C9VYXM+IxlcaRmjBKqWx9UzQeeioIkfmjMpJFU846ZP1dacge0lPx8 -p6ocPbM0rkv0xuF/dwkDQd4BPSmv4/3/UM8FRoYo8Q7SHkDR98wJ8FCm6k9wRtWC -K/jzmBswY2TewAHom3jLzTM0FZ/n5Sini3EGAI2EvnQrxWRpeE7ZOkHKqLHEOaHl -zeST4U/cUgxhwgnhbGJ7zmrFsHpYnnZYM3mIKfQ3/EhksZ68TF9IB1tfUiQTij4r -9jWa0ybRdQ== -=nZZb ------END PGP PUBLIC KEY BLOCK----- diff --git a/docs/process/security.rst b/docs/process/security.rst index c3935daa1..516eb98d7 100644 --- a/docs/process/security.rst +++ b/docs/process/security.rst @@ -20,40 +20,13 @@ Found a Security Issue? Although we try to keep TF-A secure, we can only do so with the help of the community of developers and security researchers. -If you think you have found a security vulnerability, please **do not** report it -in the `issue tracker`_. Instead send an email to -trusted-firmware-security@arm.com - -Please include: - -* Trusted Firmware-A version (or commit) affected - -* A description of the concern or vulnerability - -* Details on how to replicate the vulnerability, including: - - - Configuration details - - - Proof of concept exploit code - - - Any additional software or tools required - -We recommend using :download:`this PGP/GPG key <./security-reporting.asc>` for -encrypting the information. This key is also available at -http://keyserver.pgp.com and LDAP port 389 of the same server. - -The fingerprint for this key is: - -:: - - 1309 2C19 22B4 8E87 F17B FE5C 3AB7 EFCB 45A0 DFD0 - -If you would like replies to be encrypted, please provide your public key. - -Please give us the time to respond to you and fix the vulnerability before going -public. We do our best to respond and fix any issues quickly. We also need to -ensure providers of products that use TF-A have a chance to consider the -implications of the vulnerability and its remedy. +If you think you have found a security vulnerability, please **do not** report +it in the `issue tracker`_. Instead, please follow the `TrustedFirmware.org +security incident process`_. One of the goals of this process is to ensure +providers of products that use TF-A have a chance to consider the implications +of the vulnerability and its remedy before it is made public. As such, please +follow the disclosure plan outlined in the process. We do our best to respond +and fix any issues quickly. Afterwards, we encourage you to write-up your findings about the TF-A source code. @@ -61,8 +34,8 @@ code. Attribution ----------- -We will name and thank you in the :ref:`Change Log & Release Notes` distributed with the source -code and in any published security advisory. +We will name and thank you in the :ref:`Change Log & Release Notes` distributed +with the source code and in any published security advisory. Security Advisories ------------------- @@ -96,7 +69,6 @@ Security Advisories +-----------+------------------------------------------------------------------+ .. _issue tracker: https://developer.trustedfirmware.org/project/board/1/ -.. _this PGP/GPG key: security-reporting.asc .. |TFV-1| replace:: :ref:`Advisory TFV-1 (CVE-2016-10319)` .. |TFV-2| replace:: :ref:`Advisory TFV-2 (CVE-2017-7564)` @@ -107,6 +79,8 @@ Security Advisories .. |TFV-7| replace:: :ref:`Advisory TFV-7 (CVE-2018-3639)` .. |TFV-8| replace:: :ref:`Advisory TFV-8 (CVE-2018-19440)` +.. _TrustedFirmware.org security incident process: https://developer.trustedfirmware.org/w/collaboration/security_center/ + -------------- -*Copyright (c) 2019, Arm Limited. All rights reserved.* +*Copyright (c) 2019-2020, Arm Limited. All rights reserved.* -- cgit v1.2.3 From 8aa374b9fe998ef2e06bab665001051f829dfafb Mon Sep 17 00:00:00 2001 From: laurenw-arm Date: Thu, 6 Feb 2020 11:42:18 -0600 Subject: fconf: Extract Timer clock freq from HW_CONFIG dtb Extract Timer clock frequency from the timer node in HW_CONFIG dtb. The first timer is a per-core architected timer attached to a GIC to deliver its per-processor interrupts via PPIs. Signed-off-by: Lauren Wehrmeister Change-Id: I2f4b27c48e4c79208dab9f03c768d9221ba6ca86 --- plat/arm/board/fvp/fconf/fconf_hw_config_getter.c | 28 ++++++++++++++++++++++ .../arm/board/fvp/include/fconf_hw_config_getter.h | 10 +++++--- 2 files changed, 35 insertions(+), 3 deletions(-) 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 8172a6ebe..35a777b6f 100644 --- a/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c +++ b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c @@ -14,6 +14,7 @@ struct gicv3_config_t gicv3_config; struct hw_topology_t soc_topology; struct uart_serial_config_t uart_serial_config; +struct cpu_timer_t cpu_timer; #define ILLEGAL_ADDR ULL(~0) @@ -260,9 +261,36 @@ int fconf_populate_uart_config(uintptr_t config) VERBOSE("FCONF: UART serial device clk frequency: %x\n", uart_serial_config.uart_clk); + + return 0; +} + +int fconf_populate_cpu_timer(uintptr_t config) +{ + int err, node; + + /* Necessary to work with libfdt APIs */ + const void *hw_config_dtb = (const void *)config; + + /* Find the node offset point to "arm,armv8-timer" compatible property, + * a per-core architected timer attached to a GIC to deliver its per-processor + * interrupts via PPIs */ + node = fdt_node_offset_by_compatible(hw_config_dtb, -1, "arm,armv8-timer"); + if (node < 0) { + ERROR("FCONF: Unrecognized hardware configuration dtb (%d)\n", node); + return node; + } + + /* Locate the cell holding the clock-frequency, an optional field */ + err = fdt_read_uint32(hw_config_dtb, node, "clock-frequency", &cpu_timer.clock_freq); + if (err < 0) { + WARN("FCONF failed to read clock-frequency property\n"); + } + return 0; } FCONF_REGISTER_POPULATOR(HW_CONFIG, gicv3_config, fconf_populate_gicv3_config); FCONF_REGISTER_POPULATOR(HW_CONFIG, topology, fconf_populate_topology); FCONF_REGISTER_POPULATOR(HW_CONFIG, uart_config, fconf_populate_uart_config); +FCONF_REGISTER_POPULATOR(HW_CONFIG, cpu_timer, fconf_populate_cpu_timer); diff --git a/plat/arm/board/fvp/include/fconf_hw_config_getter.h b/plat/arm/board/fvp/include/fconf_hw_config_getter.h index b53e00ae1..ca85f7a70 100644 --- a/plat/arm/board/fvp/include/fconf_hw_config_getter.h +++ b/plat/arm/board/fvp/include/fconf_hw_config_getter.h @@ -11,10 +11,9 @@ /* Hardware Config related getter */ #define hw_config__gicv3_config_getter(prop) gicv3_config.prop - #define hw_config__topology_getter(prop) soc_topology.prop - #define hw_config__uart_serial_config_getter(prop) uart_serial_config.prop +#define hw_config__cpu_timer_getter(prop) cpu_timer.prop struct gicv3_config_t { uint64_t gicd_base; @@ -33,12 +32,17 @@ struct uart_serial_config_t { uint32_t uart_clk; }; +struct cpu_timer_t { + uint32_t clock_freq; +}; + int fconf_populate_gicv3_config(uintptr_t config); int fconf_populate_topology(uintptr_t config); int fconf_populate_uart_config(uintptr_t config); +int fconf_populate_cpu_timer(uintptr_t config); extern struct gicv3_config_t gicv3_config; extern struct hw_topology_t soc_topology; extern struct uart_serial_config_t uart_serial_config; - +extern struct cpu_timer_t cpu_timer; #endif /* FCONF_HW_CONFIG_GETTER_H */ -- cgit v1.2.3 From 156dbdd46425d7a33c77d463aab29821dba66366 Mon Sep 17 00:00:00 2001 From: laurenw-arm Date: Wed, 10 Jun 2020 16:33:18 -0500 Subject: plat/fvp: Dynamic description of clock freq Query clock frequency in runtime using FCONF getter API Signed-off-by: Lauren Wehrmeister Change-Id: Ie6a8a62d8d190b9994feffb167a1d48829913e9b --- plat/arm/board/fvp/fvp_bl31_setup.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/plat/arm/board/fvp/fvp_bl31_setup.c b/plat/arm/board/fvp/fvp_bl31_setup.c index dc7bfa2dc..4cc1c1b93 100644 --- a/plat/arm/board/fvp/fvp_bl31_setup.c +++ b/plat/arm/board/fvp/fvp_bl31_setup.c @@ -7,7 +7,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -65,3 +67,26 @@ void __init bl31_plat_arch_setup(void) fconf_populate("HW_CONFIG", hw_config_dtb); #endif } + +unsigned int plat_get_syscnt_freq2(void) +{ + unsigned int counter_base_frequency; + +#if !RESET_TO_BL31 && !BL2_AT_EL3 + /* Get the frequency through FCONF API for HW_CONFIG */ + counter_base_frequency = FCONF_GET_PROPERTY(hw_config, cpu_timer, clock_freq); + if (counter_base_frequency > 0U) { + return counter_base_frequency; + } +#endif + + /* Read the frequency from Frequency modes table */ + counter_base_frequency = mmio_read_32(ARM_SYS_CNTCTL_BASE + CNTFID_OFF); + + /* The first entry of the frequency modes table must not be 0 */ + if (counter_base_frequency == 0U) { + panic(); + } + + return counter_base_frequency; +} -- cgit v1.2.3 From 8286967552bbf1c1e08e51cd98c22d27ca8fa44c Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Thu, 11 Jun 2020 22:32:11 +0100 Subject: plat/arm: Load and populate fw_config and tb_fw_config Modified the code to do below changes: 1. Load tb_fw_config along with fw_config by BL1. 2. Populate fw_config device tree information in the BL1 to load tb_fw_config. 3. In BL2, populate fw_config information to retrieve the address of tb_fw_config and then tb_fw_config gets populated using retrieved address. 4. Avoid processing of configuration file in case of error value returned from "fw_config_load" function. 5. Updated entrypoint information for BL2 image so that it's arg0 should point to fw_config address. Signed-off-by: Manish V Badarkhe Signed-off-by: Louis Mayencourt Change-Id: Ife6f7b673a074e7f544ee3d1bda7645fd5b2886c --- include/lib/fconf/fconf_dyn_cfg_getter.h | 3 ++ include/plat/arm/common/plat_arm.h | 2 +- lib/fconf/fconf.c | 5 ++- lib/fconf/fconf_dyn_cfg_getter.c | 62 ++++++++++++++++++++------------ plat/arm/common/arm_bl1_setup.c | 52 +++++++++++++++++++++++++-- plat/arm/common/arm_bl2_setup.c | 10 +++++- 6 files changed, 106 insertions(+), 28 deletions(-) diff --git a/include/lib/fconf/fconf_dyn_cfg_getter.h b/include/lib/fconf/fconf_dyn_cfg_getter.h index 0fda8c9b2..9816d6fe0 100644 --- a/include/lib/fconf/fconf_dyn_cfg_getter.h +++ b/include/lib/fconf/fconf_dyn_cfg_getter.h @@ -21,4 +21,7 @@ struct dyn_cfg_dtb_info_t { struct dyn_cfg_dtb_info_t *dyn_cfg_dtb_info_getter(unsigned int config_id); int fconf_populate_dtb_registry(uintptr_t config); +/* Set fw_config information in global DTB array */ +void set_fw_config_info(uintptr_t config_addr, uint32_t config_max_size); + #endif /* FCONF_DYN_CFG_GETTER_H */ diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index 1b5979529..36255300e 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -190,7 +190,7 @@ void arm_bl1_platform_setup(void); void arm_bl1_plat_arch_setup(void); /* BL2 utility functions */ -void arm_bl2_early_platform_setup(uintptr_t tb_fw_config, struct meminfo *mem_layout); +void arm_bl2_early_platform_setup(uintptr_t fw_config, struct meminfo *mem_layout); void arm_bl2_platform_setup(void); void arm_bl2_plat_arch_setup(void); uint32_t arm_get_spsr_for_bl32_entry(void); diff --git a/lib/fconf/fconf.c b/lib/fconf/fconf.c index affec54db..bc4fa8ea8 100644 --- a/lib/fconf/fconf.c +++ b/lib/fconf/fconf.c @@ -29,8 +29,11 @@ int fconf_load_config(unsigned int image_id) }; config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, image_id); + assert(config_info != NULL); + config_image_info.image_base = config_info->config_addr; - config_image_info.image_max_size = (uint32_t)config_info->config_max_size; + config_image_info.image_max_size = + (uint32_t)config_info->config_max_size; VERBOSE("FCONF: Loading config with image ID: %d\n", image_id); err = load_auth_image(image_id, &config_image_info); diff --git a/lib/fconf/fconf_dyn_cfg_getter.c b/lib/fconf/fconf_dyn_cfg_getter.c index 1828a80bf..902c07d95 100644 --- a/lib/fconf/fconf_dyn_cfg_getter.c +++ b/lib/fconf/fconf_dyn_cfg_getter.c @@ -15,22 +15,23 @@ /* We currently use FW, TB_FW, SOC_FW, TOS_FW, NS_fw and HW configs */ #define MAX_DTB_INFO U(6) -#ifdef IMAGE_BL1 -static struct dyn_cfg_dtb_info_t dtb_infos[MAX_DTB_INFO] = { - [0] = { - .config_addr = ARM_FW_CONFIG_BASE, - .config_max_size = (uint32_t) - (ARM_FW_CONFIG_LIMIT - ARM_FW_CONFIG_BASE), - .config_id = FW_CONFIG_ID - }, -}; -/* Create an object pool starting at the second element */ -static OBJECT_POOL(dtb_info_pool, &dtb_infos[1], - sizeof(struct dyn_cfg_dtb_info_t), MAX_DTB_INFO-1); -#else static struct dyn_cfg_dtb_info_t dtb_infos[MAX_DTB_INFO]; static OBJECT_POOL_ARRAY(dtb_info_pool, dtb_infos); -#endif + +/* + * This function is used to alloc memory for fw config information from + * global pool and set fw configuration information. + * Specifically used by BL1 to set fw_config information in global array + */ +void set_fw_config_info(uintptr_t config_addr, uint32_t config_max_size) +{ + struct dyn_cfg_dtb_info_t *dtb_info; + + dtb_info = pool_alloc(&dtb_info_pool); + dtb_info->config_addr = config_addr; + dtb_info->config_max_size = config_max_size; + dtb_info->config_id = FW_CONFIG_ID; +} struct dyn_cfg_dtb_info_t *dyn_cfg_dtb_info_getter(unsigned int config_id) { @@ -62,6 +63,30 @@ int fconf_populate_dtb_registry(uintptr_t config) /* As libfdt use void *, we can't avoid this cast */ const void *dtb = (void *)config; + /* + * Compile time assert if FW_CONFIG_ID is 0 which is more + * unlikely as 0 is a valid image id for FIP as per the current + * code but still to avoid code breakage in case of unlikely + * event when image ids gets changed. + */ + CASSERT(FW_CONFIG_ID != 0, assert_invalid_fw_config_id); + + /* + * In case of BL1, fw_config dtb information is already + * populated in global dtb_infos array by 'set_fw_config_info' + * function, Below check is present to avoid re-population of + * fw_config information. + * + * Other BLs, satisfy below check and populate fw_config information + * in global dtb_infos array. + */ + if (dtb_infos[0].config_id == 0) { + dtb_info = pool_alloc(&dtb_info_pool); + dtb_info->config_addr = config; + dtb_info->config_max_size = fdt_totalsize(dtb); + dtb_info->config_id = FW_CONFIG_ID; + } + /* Find the node offset point to "fconf,dyn_cfg-dtb_registry" compatible property */ const char *compatible_str = "fconf,dyn_cfg-dtb_registry"; node = fdt_node_offset_by_compatible(dtb, -1, compatible_str); @@ -70,15 +95,6 @@ int fconf_populate_dtb_registry(uintptr_t config) return node; } -#ifndef IMAGE_BL1 - /* Save config dtb information */ - dtb_info = pool_alloc(&dtb_info_pool); - - dtb_info->config_addr = config; - dtb_info->config_max_size = fdt_totalsize(dtb); - dtb_info->config_id = FW_CONFIG_ID; -#endif - fdt_for_each_subnode(child, dtb, node) { uint32_t val32; uint64_t val64; diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c index 4011dc9fc..6b630b980 100644 --- a/plat/arm/common/arm_bl1_setup.c +++ b/plat/arm/common/arm_bl1_setup.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -142,11 +143,58 @@ void bl1_plat_arch_setup(void) */ void arm_bl1_platform_setup(void) { + const struct dyn_cfg_dtb_info_t *fw_config_info; + image_desc_t *desc; + uint32_t fw_config_max_size; + int err = -1; + /* Initialise the IO layer and register platform IO devices */ plat_arm_io_setup(); - /* Fill the properties struct with the info from the config dtb */ - fconf_load_config(FW_CONFIG_ID); + /* Check if we need FWU before further processing */ + err = plat_arm_bl1_fwu_needed(); + if (err) { + 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_fw_config_info(ARM_FW_CONFIG_BASE, fw_config_max_size); + + /* Fill the device tree information struct with the info from the config dtb */ + err = fconf_load_config(FW_CONFIG_ID); + if (err < 0) { + ERROR("Loading of FW_CONFIG failed %d\n", err); + plat_error_handler(err); + } + + /* + * FW_CONFIG loaded successfully. If FW_CONFIG device tree parsing + * is successful then load TB_FW_CONFIG device tree. + */ + fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, FW_CONFIG_ID); + if (fw_config_info != NULL) { + err = fconf_populate_dtb_registry(fw_config_info->config_addr); + if (err < 0) { + ERROR("Parsing of FW_CONFIG failed %d\n", err); + plat_error_handler(err); + } + /* load TB_FW_CONFIG */ + err = fconf_load_config(TB_FW_CONFIG_ID); + if (err < 0) { + ERROR("Loading of TB_FW_CONFIG failed %d\n", err); + plat_error_handler(err); + } + } else { + ERROR("Invalid FW_CONFIG address\n"); + plat_error_handler(err); + } + + /* The BL2 ep_info arg0 is modified to point to FW_CONFIG */ + desc = bl1_plat_get_image_desc(BL2_IMAGE_ID); + assert(desc != NULL); + desc->ep_info.args.arg0 = fw_config_info->config_addr; #if TRUSTED_BOARD_BOOT /* Share the Mbed TLS heap info with other images */ diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c index 9d5526f1b..e4a4f8724 100644 --- a/plat/arm/common/arm_bl2_setup.c +++ b/plat/arm/common/arm_bl2_setup.c @@ -15,6 +15,7 @@ #include #include #include +#include #ifdef SPD_opteed #include #endif @@ -53,6 +54,7 @@ CASSERT(BL2_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl2_base_overflows); void arm_bl2_early_platform_setup(uintptr_t fw_config, struct meminfo *mem_layout) { + const struct dyn_cfg_dtb_info_t *tb_fw_config_info; /* Initialize the console to provide early debug support */ arm_console_boot_init(); @@ -61,7 +63,13 @@ void arm_bl2_early_platform_setup(uintptr_t fw_config, /* Fill the properties struct with the info from the config dtb */ if (fw_config != 0U) { - fconf_populate("TB_FW", fw_config); + fconf_populate("FW_CONFIG", fw_config); + } + + /* TB_FW_CONFIG was also loaded by BL1 */ + tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID); + if (tb_fw_config_info != NULL) { + fconf_populate("TB_FW", tb_fw_config_info->config_addr); } /* Initialise the IO layer and register platform IO devices */ -- cgit v1.2.3 From ce4ca1a8b8eb62d0aa2ce9ed23747fb705d9517a Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Tue, 9 Jun 2020 11:31:17 +0100 Subject: plat/arm: Increase size of firmware configuration area Increased the size of firmware configuration area to accommodate all configs. Updated maximum size of following bootloaders due to increase in firmware configs size and addition of the code in the BL2. 1. Increased maximum size of BL2 for Juno platform in no optimisation case. 2. Reduced maximum size of BL31 for fvp and Juno platform. 3. Reduced maximum size of BL32 for Juno platform. Change-Id: Ifba0564df0d1fe86175bed9fae87fdcf013b1831 Signed-off-by: Manish V Badarkhe --- include/plat/arm/common/arm_def.h | 4 ++-- plat/arm/board/fvp/include/platform_def.h | 2 +- plat/arm/board/juno/include/platform_def.h | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index a6b6b2eab..5c11e5fe1 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -350,7 +350,7 @@ * and limit. Leave enough space of BL2 meminfo. */ #define ARM_FW_CONFIG_BASE (ARM_BL_RAM_BASE + sizeof(meminfo_t)) -#define ARM_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + (PAGE_SIZE / 2U)) +#define ARM_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + PAGE_SIZE) /* * Boot parameters passed from BL2 to BL31/BL32 are stored here @@ -363,7 +363,7 @@ * Define limit of firmware configuration memory: * ARM_FW_CONFIG + ARM_BL2_MEM_DESC memory */ -#define ARM_FW_CONFIGS_LIMIT (ARM_BL_RAM_BASE + PAGE_SIZE) +#define ARM_FW_CONFIGS_LIMIT (ARM_BL_RAM_BASE + (PAGE_SIZE * 2)) /******************************************************************************* * BL1 specific defines. diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h index 62ede9ab8..7222c5519 100644 --- a/plat/arm/board/fvp/include/platform_def.h +++ b/plat/arm/board/fvp/include/platform_def.h @@ -133,7 +133,7 @@ * calculated using the current BL31 PROGBITS debug size plus the sizes of * BL2 and BL1-RW */ -#define PLAT_ARM_MAX_BL31_SIZE UL(0x3E000) +#define PLAT_ARM_MAX_BL31_SIZE UL(0x3D000) #endif /* RESET_TO_BL31 */ #ifndef __aarch64__ diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h index cd961554a..91c3ae7e0 100644 --- a/plat/arm/board/juno/include/platform_def.h +++ b/plat/arm/board/juno/include/platform_def.h @@ -139,7 +139,7 @@ # define PLAT_ARM_MAX_BL2_SIZE (UL(0x1D000) - JUNO_BL2_ROMLIB_OPTIMIZATION) #endif #else -# define PLAT_ARM_MAX_BL2_SIZE (UL(0x11000) - JUNO_BL2_ROMLIB_OPTIMIZATION) +# define PLAT_ARM_MAX_BL2_SIZE (UL(0x13000) - JUNO_BL2_ROMLIB_OPTIMIZATION) #endif /* @@ -148,7 +148,7 @@ * BL2 and BL1-RW. SCP_BL2 image is loaded into the space BL31 -> BL2_BASE. * Hence the BL31 PROGBITS size should be >= PLAT_CSS_MAX_SCP_BL2_SIZE. */ -#define PLAT_ARM_MAX_BL31_SIZE UL(0x3E000) +#define PLAT_ARM_MAX_BL31_SIZE UL(0x3D000) #if JUNO_AARCH32_EL3_RUNTIME /* @@ -157,7 +157,7 @@ * BL2 and BL1-RW. SCP_BL2 image is loaded into the space BL32 -> BL2_BASE. * Hence the BL32 PROGBITS size should be >= PLAT_CSS_MAX_SCP_BL2_SIZE. */ -#define PLAT_ARM_MAX_BL32_SIZE UL(0x3E000) +#define PLAT_ARM_MAX_BL32_SIZE UL(0x3D000) #endif /* -- cgit v1.2.3 From 089fc6241259d6a07aa3b4c4eee5ff3fbe5d2cfe Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Sat, 13 Jun 2020 09:42:28 +0100 Subject: doc: Update memory layout for firmware configuration area Captured the increase in firmware configuration area from 4KB to 8kB in memory layout document. Updated the documentation to provide details about fw_config separately. Signed-off-by: Manish V Badarkhe Change-Id: Ifbec443ced479301be65827b49ff4fe447e9109f --- docs/design/firmware-design.rst | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst index b336b38e7..891a9a29b 100644 --- a/docs/design/firmware-design.rst +++ b/docs/design/firmware-design.rst @@ -83,6 +83,10 @@ Each of the Boot Loader stages may be dynamically configured if required by the platform. The Boot Loader stage may optionally specify a firmware configuration file and/or hardware configuration file as listed below: +- FW_CONFIG - The firmware configuration file. Holds properties shared across + all BLx images. + An example is the "dtb-registry" node, which contains the information about + the other device tree configurations (load-address, size, image_id). - HW_CONFIG - The hardware configuration file. Can be shared by all Boot Loader stages and also by the Normal World Rich OS. - TB_FW_CONFIG - Trusted Boot Firmware configuration file. Shared between BL1 @@ -109,8 +113,8 @@ convention: the generic hardware configuration is passed the next available argument. For example, - - If TB_FW_CONFIG is loaded by BL1, then its address is passed in ``arg0`` - to BL2. + - FW_CONFIG is loaded by BL1, then its address is passed in ``arg0`` to BL2. + - TB_FW_CONFIG address is retrieved by BL2 from FW_CONFIG device tree. - If HW_CONFIG is loaded by BL1, then its address is passed in ``arg2`` to BL2. Note, ``arg1`` is already used for meminfo_t. - If SOC_FW_CONFIG is loaded by BL2, then its address is passed in ``arg1`` @@ -1732,7 +1736,7 @@ CONFIG section in memory layouts shown below contains: ``bl2_mem_params_descs`` contains parameters passed from BL2 to next the BL image during boot. -``fw_configs`` includes soc_fw_config, tos_fw_config and tb_fw_config. +``fw_configs`` includes soc_fw_config, tos_fw_config, tb_fw_config and fw_config. **FVP with TSP in Trusted SRAM with firmware configs :** (These diagrams only cover the AArch64 case) @@ -1757,7 +1761,7 @@ BL image during boot. | | <<<<<<<<<<<<< | BL31 PROGBITS | | | <<<<<<<<<<<<< |----------------| | | <<<<<<<<<<<<< | BL32 | - 0x04002000 +----------+ +----------------+ + 0x04003000 +----------+ +----------------+ | CONFIG | 0x04001000 +----------+ | Shared | @@ -1794,7 +1798,7 @@ BL image during boot. |--------------| <<<<<<<<<<<<< |----------------| | | <<<<<<<<<<<<< | BL31 PROGBITS | | | +----------------+ - +--------------+ + 0x04003000 +--------------+ | CONFIG | 0x04001000 +--------------+ | Shared | @@ -1828,7 +1832,7 @@ BL image during boot. |----------| <<<<<<<<<<<<< |----------------| | | <<<<<<<<<<<<< | BL31 PROGBITS | | | +----------------+ - 0x04002000 +----------+ + 0x04003000 +----------+ | CONFIG | 0x04001000 +----------+ | Shared | -- cgit v1.2.3 From 62bbfe82c8b29834e9f278bc6eefdf386c39aecd Mon Sep 17 00:00:00 2001 From: johpow01 Date: Wed, 3 Jun 2020 15:23:31 -0500 Subject: Workaround for Cortex A77 erratum 1800714 Cortex A77 erratum 1800714 is a Cat B erratum, present in older revisions of the Cortex A77 processor core. The workaround is to set a bit in the ECTLR_EL1 system register, which disables allocation of splintered pages in the L2 TLB. Since this is the first errata workaround implemented for Cortex A77, this patch also adds the required cortex_a77_reset_func in the file lib/cpus/aarch64/cortex_a77.S. This errata is explained in this SDEN: https://static.docs.arm.com/101992/0010/Arm_Cortex_A77_MP074_Software_Developer_Errata_Notice_v10.pdf Signed-off-by: John Powell Change-Id: I844de34ee1bd0268f80794e2d9542de2f30fd3ad --- docs/design/cpu-specific-build-macros.rst | 5 +++ include/lib/cpus/aarch64/cortex_a77.h | 3 +- lib/cpus/aarch64/cortex_a77.S | 63 ++++++++++++++++++++++++++++++- lib/cpus/cpu-ops.mk | 8 ++++ 4 files changed, 76 insertions(+), 3 deletions(-) diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst index 264d0c688..6b6c63933 100644 --- a/docs/design/cpu-specific-build-macros.rst +++ b/docs/design/cpu-specific-build-macros.rst @@ -233,6 +233,11 @@ For Cortex-A76, the following errata build flags are defined : - ``ERRATA_A76_1800710``: This applies errata 1800710 workaround to Cortex-A76 CPU. This needs to be enabled only for revision <= r4p0 of the CPU. +For Cortex-A77, the following errata build flags are defined : + +- ``ERRATA_A77_1800714``: This applies errata 1800714 workaround to Cortex-A77 + CPU. This needs to be enabled only for revision <= r1p1 of the CPU. + For Cortex-A78, the following errata build flags are defined : - ``ERRATA_A78_1688305``: This applies errata 1688305 workaround to Cortex-A78 diff --git a/include/lib/cpus/aarch64/cortex_a77.h b/include/lib/cpus/aarch64/cortex_a77.h index 0467ef3bb..bbd647c60 100644 --- a/include/lib/cpus/aarch64/cortex_a77.h +++ b/include/lib/cpus/aarch64/cortex_a77.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -16,6 +16,7 @@ * CPU Extended Control register specific definitions. ******************************************************************************/ #define CORTEX_A77_CPUECTLR_EL1 S3_0_C15_C1_4 +#define CORTEX_A77_CPUECTLR_EL1_BIT_53 (ULL(1) << 53) /******************************************************************************* * CPU Power Control register specific definitions. diff --git a/lib/cpus/aarch64/cortex_a77.S b/lib/cpus/aarch64/cortex_a77.S index f3fd5e196..0c30460d4 100644 --- a/lib/cpus/aarch64/cortex_a77.S +++ b/lib/cpus/aarch64/cortex_a77.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -21,6 +21,53 @@ #error "Cortex-A77 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0" #endif + /* -------------------------------------------------- + * Errata Workaround for Cortex A77 Errata #1800714. + * This applies to revision <= r1p1 of Cortex A77. + * Inputs: + * x0: variant[4:7] and revision[0:3] of current cpu. + * Shall clobber: x0-x17 + * -------------------------------------------------- + */ +func errata_a77_1800714_wa + /* Compare x0 against revision <= r1p1 */ + mov x17, x30 + bl check_errata_1800714 + cbz x0, 1f + + /* Disable allocation of splintered pages in the L2 TLB */ + mrs x1, CORTEX_A77_CPUECTLR_EL1 + orr x1, x1, CORTEX_A77_CPUECTLR_EL1_BIT_53 + msr CORTEX_A77_CPUECTLR_EL1, x1 + isb +1: + ret x17 +endfunc errata_a77_1800714_wa + +func check_errata_1800714 + /* Applies to everything <= r1p1 */ + mov x1, #0x11 + b cpu_rev_var_ls +endfunc check_errata_1800714 + + /* ------------------------------------------------- + * The CPU Ops reset function for Cortex-A77. + * Shall clobber: x0-x19 + * ------------------------------------------------- + */ +func cortex_a77_reset_func + mov x19, x30 + bl cpu_get_rev_var + mov x18, x0 + +#if ERRATA_A77_1800714 + mov x0, x18 + bl errata_a77_1800714_wa +#endif + + ret x19 +endfunc cortex_a77_reset_func + /* --------------------------------------------- * HW will do the cache maintenance while powering down * --------------------------------------------- @@ -42,6 +89,18 @@ endfunc cortex_a77_core_pwr_dwn * Errata printing function for Cortex-A77. Must follow AAPCS. */ func cortex_a77_errata_report + stp x8, x30, [sp, #-16]! + + bl cpu_get_rev_var + mov x8, x0 + + /* + * Report all errata. The revision-variant information is passed to + * checking functions of each errata. + */ + report_errata ERRATA_A77_1800714, cortex_a77, 1800714 + + ldp x8, x30, [sp], #16 ret endfunc cortex_a77_errata_report #endif @@ -67,5 +126,5 @@ func cortex_a77_cpu_reg_dump endfunc cortex_a77_cpu_reg_dump declare_cpu_ops cortex_a77, CORTEX_A77_MIDR, \ - CPU_NO_RESET_FUNC, \ + cortex_a77_reset_func, \ cortex_a77_core_pwr_dwn diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk index e80900056..e49437569 100644 --- a/lib/cpus/cpu-ops.mk +++ b/lib/cpus/cpu-ops.mk @@ -258,6 +258,10 @@ ERRATA_A76_1791580 ?=0 # only to revision <= r4p0 of the Cortex A76 cpu. ERRATA_A76_1800710 ?=0 +# Flag to apply erratum 1800714 workaround during reset. This erratum applies +# only to revision <= r1p1 of the Cortex A77 cpu. +ERRATA_A77_1800714 ?=0 + # Flag to apply erratum 1688305 workaround during reset. This erratum applies # to revisions r0p0 - r1p0 of the A78 cpu. ERRATA_A78_1688305 ?=0 @@ -503,6 +507,10 @@ $(eval $(call add_define,ERRATA_A76_1791580)) $(eval $(call assert_boolean,ERRATA_A76_1800710)) $(eval $(call add_define,ERRATA_A76_1800710)) +# Process ERRATA_A77_1800714 flag +$(eval $(call assert_boolean,ERRATA_A77_1800714)) +$(eval $(call add_define,ERRATA_A77_1800714)) + # Process ERRATA_A78_1688305 flag $(eval $(call assert_boolean,ERRATA_A78_1688305)) $(eval $(call add_define,ERRATA_A78_1688305)) -- cgit v1.2.3 From 0e0521bdfce73be7dbded23e560b3dab1ff1af2d Mon Sep 17 00:00:00 2001 From: johpow01 Date: Tue, 2 Jun 2020 13:14:11 -0500 Subject: Workaround for Neoverse N1 erratum 1800710 Neoverse N1 erratum 1800710 is a Cat B erratum, present in older revisions of the Neoverse N1 processor core. The workaround is to set a bit in the ECTLR_EL1 system register, which disables allocation of splintered pages in the L2 TLB. This errata is explained in this SDEN: https://static.docs.arm.com/sden885747/f/Arm_Neoverse_N1_MP050_Software_Developer_Errata_Notice_v21.pdf Signed-off-by: John Powell Change-Id: Ie5b15c8bc3235e474a06a57c3ec70684361857a6 --- docs/design/cpu-specific-build-macros.rst | 3 +++ include/lib/cpus/aarch64/neoverse_n1.h | 1 + lib/cpus/aarch64/neoverse_n1.S | 35 +++++++++++++++++++++++++++++++ lib/cpus/cpu-ops.mk | 8 +++++++ 4 files changed, 47 insertions(+) diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst index 6b6c63933..78a80f645 100644 --- a/docs/design/cpu-specific-build-macros.rst +++ b/docs/design/cpu-specific-build-macros.rst @@ -278,6 +278,9 @@ For Neoverse N1, the following errata build flags are defined : - ``ERRATA_N1_1542419``: This applies errata 1542419 workaround to Neoverse-N1 CPU. This needs to be enabled only for revisions r3p0 - r4p0 of the CPU. +- ``ERRATA_N1_1800710``: This applies errata 1800710 workaround to Neoverse-N1 + CPU. This needs to be enabled only for revisions <= r4p0 of the CPU. + DSU Errata Workarounds ---------------------- diff --git a/include/lib/cpus/aarch64/neoverse_n1.h b/include/lib/cpus/aarch64/neoverse_n1.h index b50befa8d..155a90e0d 100644 --- a/include/lib/cpus/aarch64/neoverse_n1.h +++ b/include/lib/cpus/aarch64/neoverse_n1.h @@ -35,6 +35,7 @@ #define NEOVERSE_N1_WS_THR_L2_MASK (ULL(3) << 24) #define NEOVERSE_N1_CPUECTLR_EL1_MM_TLBPF_DIS_BIT (ULL(1) << 51) +#define NEOVERSE_N1_CPUECTLR_EL1_BIT_53 (ULL(1) << 53) #define NEOVERSE_N1_CPUECTLR_EL1_EXTLLC_BIT (ULL(1) << 0) /******************************************************************************* diff --git a/lib/cpus/aarch64/neoverse_n1.S b/lib/cpus/aarch64/neoverse_n1.S index d537ed6a8..0f80de143 100644 --- a/lib/cpus/aarch64/neoverse_n1.S +++ b/lib/cpus/aarch64/neoverse_n1.S @@ -375,6 +375,35 @@ func check_errata_1542419 b cpu_rev_var_range endfunc check_errata_1542419 +/* -------------------------------------------------- + * Errata Workaround for Neoverse N1 Erratum 1800710. + * This applies to revisions <= r4p0 of Neoverse N1 + * Inputs: + * x0: variant[4:7] and revision[0:3] of current cpu. + * Shall clobber: x0-x17 + * -------------------------------------------------- + */ +func errata_n1_1800710_wa + /* Compare x0 against revision <= r4p0 */ + mov x17, x30 + bl check_errata_1800710 + cbz x0, 1f + + /* Disable allocation of splintered pages in the L2 TLB */ + mrs x1, NEOVERSE_N1_CPUECTLR_EL1 + orr x1, x1, NEOVERSE_N1_CPUECTLR_EL1_BIT_53 + msr NEOVERSE_N1_CPUECTLR_EL1, x1 + isb +1: + ret x17 +endfunc errata_n1_1800710_wa + +func check_errata_1800710 + /* Applies to everything <= r4p0 */ + mov x1, #0x40 + b cpu_rev_var_ls +endfunc check_errata_1800710 + func neoverse_n1_reset_func mov x19, x30 @@ -449,6 +478,11 @@ func neoverse_n1_reset_func bl errata_n1_1542419_wa #endif +#if ERRATA_N1_1800710 + mov x0, x18 + bl errata_n1_1800710_wa +#endif + #if ENABLE_AMU /* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */ mrs x0, actlr_el3 @@ -522,6 +556,7 @@ func neoverse_n1_errata_report report_errata ERRATA_N1_1275112, neoverse_n1, 1275112 report_errata ERRATA_N1_1315703, neoverse_n1, 1315703 report_errata ERRATA_N1_1542419, neoverse_n1, 1542419 + report_errata ERRATA_N1_1800710, neoverse_n1, 1800710 report_errata ERRATA_DSU_936184, neoverse_n1, dsu_936184 ldp x8, x30, [sp], #16 diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk index e49437569..3c895f585 100644 --- a/lib/cpus/cpu-ops.mk +++ b/lib/cpus/cpu-ops.mk @@ -314,6 +314,10 @@ ERRATA_N1_1315703 ?=0 # to revisions r3p0 - r4p0 of the Neoverse N1 cpu. ERRATA_N1_1542419 ?=0 +# Flag to apply erratum 1800710 workaround during reset. This erratum applies +# to revisions <= r4p0 of the Neoverse N1 cpu. +ERRATA_N1_1800710 ?=0 + # Flag to apply DSU erratum 798953. This erratum applies to DSUs revision r0p0. # Applying the workaround results in higher DSU power consumption on idle. ERRATA_DSU_798953 ?=0 @@ -563,6 +567,10 @@ $(eval $(call add_define,ERRATA_N1_1315703)) $(eval $(call assert_boolean,ERRATA_N1_1542419)) $(eval $(call add_define,ERRATA_N1_1542419)) +# Process ERRATA_N1_1800710 flag +$(eval $(call assert_boolean,ERRATA_N1_1800710)) +$(eval $(call add_define,ERRATA_N1_1800710)) + # Process ERRATA_DSU_798953 flag $(eval $(call assert_boolean,ERRATA_DSU_798953)) $(eval $(call add_define,ERRATA_DSU_798953)) -- cgit v1.2.3 From 7fb9bcd846bac26d5382175fe39e0344665456f7 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Sat, 30 May 2020 17:40:44 +0100 Subject: plat/arm: Use only fw_config between bl2 and bl31 Passed the address of fw_config instead of soc_fw_config as arg1 to BL31 from BL2 for ARM fvp platform. BL31 then retrieve load-address of other device trees from fw_config device tree. Signed-off-by: Louis Mayencourt Signed-off-by: Manish V Badarkhe Change-Id: Ib7e9581cd765d76111dcc3b7e0dafc12503c83c1 --- plat/arm/board/fvp/fdts/fvp_fw_config.dts | 6 ++--- plat/arm/board/fvp/fvp_bl2_setup.c | 43 +++++++++++++++++++++++++++++++ plat/arm/board/fvp/fvp_bl31_setup.c | 27 ++++++++++++++----- plat/arm/board/fvp/platform.mk | 1 + 4 files changed, 67 insertions(+), 10 deletions(-) diff --git a/plat/arm/board/fvp/fdts/fvp_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_fw_config.dts index 605b70c2d..09f2730d9 100644 --- a/plat/arm/board/fvp/fdts/fvp_fw_config.dts +++ b/plat/arm/board/fvp/fdts/fvp_fw_config.dts @@ -31,14 +31,14 @@ * is loaded at base of DRAM. */ soc_fw-config { - load-address = <0x0 0x04001000>; + load-address = <0x0 0x04001300>; max-size = <0x200>; id = ; }; tos_fw-config { - load-address = <0x0 0x04001200>; - max-size = <0x1000>; + load-address = <0x0 0x04001500>; + max-size = <0xB00>; id = ; }; diff --git a/plat/arm/board/fvp/fvp_bl2_setup.c b/plat/arm/board/fvp/fvp_bl2_setup.c index 43b137481..d5618d99b 100644 --- a/plat/arm/board/fvp/fvp_bl2_setup.c +++ b/plat/arm/board/fvp/fvp_bl2_setup.c @@ -4,7 +4,13 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include + +#include #include +#include +#include + #include #include #include @@ -26,3 +32,40 @@ void bl2_platform_setup(void) /* Initialize System level generic or SP804 timer */ fvp_timer_init(); } + +/******************************************************************************* + * This function returns the list of executable images + ******************************************************************************/ +struct bl_params *plat_get_next_bl_params(void) +{ + struct bl_params *arm_bl_params; + + arm_bl_params = arm_get_next_bl_params(); + +#if __aarch64__ && !BL2_AT_EL3 + 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; +#endif /* __aarch64__ && !BL2_AT_EL3 */ + + return arm_bl_params; +} diff --git a/plat/arm/board/fvp/fvp_bl31_setup.c b/plat/arm/board/fvp/fvp_bl31_setup.c index 4cc1c1b93..f9ee4492f 100644 --- a/plat/arm/board/fvp/fvp_bl31_setup.c +++ b/plat/arm/board/fvp/fvp_bl31_setup.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -16,11 +17,22 @@ #include "fvp_private.h" -uintptr_t hw_config_dtb; - void __init bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { +#if !RESET_TO_BL31 && !BL2_AT_EL3 + const struct dyn_cfg_dtb_info_t *soc_fw_config_info; + + INFO("BL31 FCONF: FW_CONFIG address = %lx\n", (uintptr_t)arg1); + /* Fill the properties struct with the info from the config dtb */ + fconf_populate("FW_CONFIG", arg1); + + soc_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, SOC_FW_CONFIG_ID); + if (soc_fw_config_info != NULL) { + arg1 = soc_fw_config_info->config_addr; + } +#endif /* !RESET_TO_BL31 && !BL2_AT_EL3 */ + arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3); /* Initialize the platform config for future decision making */ @@ -47,8 +59,6 @@ void __init bl31_early_platform_setup2(u_register_t arg0, /* On FVP RevC, initialize SMMUv3 */ if ((arm_config.flags & ARM_CONFIG_FVP_HAS_SMMUV3) != 0U) smmuv3_init(PLAT_FVP_SMMUV3_BASE); - - hw_config_dtb = arg2; } void __init bl31_plat_arch_setup(void) @@ -61,10 +71,13 @@ void __init bl31_plat_arch_setup(void) * control is passed to BL31. */ #if !RESET_TO_BL31 && !BL2_AT_EL3 - assert(hw_config_dtb != 0U); + /* 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); - INFO("BL31 FCONF: HW_CONFIG address = %p\n", (void *)hw_config_dtb); - fconf_populate("HW_CONFIG", hw_config_dtb); + fconf_populate("HW_CONFIG", hw_config_info->config_addr); #endif } diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 4925865a5..c3b49bb58 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -217,6 +217,7 @@ BL31_SOURCES += drivers/arm/fvp/fvp_pwrc.c \ ifeq ($(filter 1,${BL2_AT_EL3} ${RESET_TO_BL31}),) BL31_SOURCES += common/fdt_wrappers.c \ lib/fconf/fconf.c \ + lib/fconf/fconf_dyn_cfg_getter.c \ plat/arm/board/fvp/fconf/fconf_hw_config_getter.c ifeq (${SEC_INT_DESC_IN_FCONF},1) -- cgit v1.2.3 From e555787b66dfa2a1e3b9145a5c55763850ae66dc Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Sun, 21 Jun 2020 05:41:11 +0100 Subject: doc: Update BL1 and BL2 boot flow Updated the document for BL1 and BL2 boot flow to capture below changes made in FCONF 1. Loading of fw_config and tb_fw_config images by BL1. 2. Population of fw_config and tb_fw_config by BL2. Signed-off-by: Manish V Badarkhe Change-Id: Ifea5c61d520ff1de834c279ce1759b53448303ba --- docs/components/fconf/index.rst | 11 +++-- .../diagrams/plantuml/fconf_bl1_load_config.puml | 52 ++++++++++++++++------ .../diagrams/plantuml/fconf_bl2_populate.puml | 12 ++++- 3 files changed, 56 insertions(+), 19 deletions(-) diff --git a/docs/components/fconf/index.rst b/docs/components/fconf/index.rst index 0da56ec3b..902063356 100644 --- a/docs/components/fconf/index.rst +++ b/docs/components/fconf/index.rst @@ -49,8 +49,10 @@ Hence each ``populate()`` function must be registered with a specific configuration properties which is usually a device tree file. Example: + - FW_CONFIG: properties related to base address, maximum size and image id + of other DTBs etc. - TB_FW: properties related to trusted firmware such as IO policies, - base address of other DTBs, mbedtls heap info etc. + mbedtls heap info etc. - HW_CONFIG: properties related to hardware configuration of the SoC such as topology, GIC controller, PSCI hooks, CPU ID etc. @@ -88,9 +90,10 @@ explain how the properties are described for a specific backend. Refer to the Loading the property device tree ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The ``fconf_load_config()`` must be called to load the device tree containing -the properties' values. This must be done after the io layer is initialized, as -the |DTB| is stored on an external device (FIP). +The ``fconf_load_config(image_id)`` must be called to load fw_config and +tb_fw_config devices tree containing the properties' values. This must be done +after the io layer is initialized, as the |DTB| is stored on an external +device (FIP). .. uml:: ../../resources/diagrams/plantuml/fconf_bl1_load_config.puml diff --git a/docs/resources/diagrams/plantuml/fconf_bl1_load_config.puml b/docs/resources/diagrams/plantuml/fconf_bl1_load_config.puml index e613eefd0..e513ed4c3 100644 --- a/docs/resources/diagrams/plantuml/fconf_bl1_load_config.puml +++ b/docs/resources/diagrams/plantuml/fconf_bl1_load_config.puml @@ -13,6 +13,7 @@ end box box "platform common code" participant plat_bl1_common + participant fconf_dyn_cfg_getter participant fconf end box @@ -20,12 +21,17 @@ bl1_main -> fvp_bl1_setup : bl1_platform_setup() fvp_bl1_setup -> arm_bl1_setup : arm_bl1_platform_setup() arm_bl1_setup -> arm_io_storage : plat_arm_io_setup() note over arm_io_storage : register and setup fip -arm_bl1_setup -> fconf : fconf_load_config() +arm_bl1_setup -> fconf : set_fw_config_info(fw_config_base, max_size) +note over fconf + set fw_config information + (address, size, image_id) + in global dtb_infos array. +end note activate fconf - note over fconf - create and populate an - image_desc_t for FW_CONFIG - end note + arm_bl1_setup -> fconf : fconf_load_config(FW_CONFIG_ID) + fconf -> fconf : FCONF_GET_PROPERTY(dyn_cfg, dtb, FW_CONFIG_ID) + fconf -> fconf_dyn_cfg_getter: dyn_cfg_dtb_info_getter(FW_CONFIG_ID) + fconf_dyn_cfg_getter -> fconf: fw_config_info fconf -> bl_common : load_auth_image(FW_CONFIG_ID, &image_info) activate bl_common note over bl_common @@ -33,18 +39,38 @@ activate fconf with info from plat_io_policy end note bl_common -> arm_io_storage - arm_io_storage -> fconf: FCONF_GET_PROPERTY(arm, arm_io_policies, tb_fw_cfg) - note over fconf: use staticaly defined policies in bl1 + arm_io_storage -> fconf: FCONF_GET_PROPERTY(arm, arm_io_policies, FW_CONFIG_ID) + note over fconf: use statically defined policies in bl1 + fconf <- bl_common : image_info + deactivate bl_common + note over fconf : get fw_config_dtb from image_info + arm_bl1_setup -> fconf: FCONF_GET_PROPERTY(dyn_cfg, dtb, FW_CONFIG_ID) + fconf -> fconf_dyn_cfg_getter: dyn_cfg_dtb_info_getter(FW_CONFIG_ID) + fconf_dyn_cfg_getter -> arm_bl1_setup: fw_config_info + arm_bl1_setup -> fconf_dyn_cfg_getter: populate_dtb_registry(uintptr_t dtb) + arm_bl1_setup -> fconf: fconf_load_config(TB_FW_CONFIG_ID) + fconf -> fconf : FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID) + fconf -> fconf_dyn_cfg_getter: dyn_cfg_dtb_info_getter(TB_FW_CONFIG_ID) + fconf_dyn_cfg_getter -> fconf: tb_fw_config_info + fconf -> bl_common : load_auth_image(TB_FW_CONFIG_ID, &image_info) + activate bl_common + note over bl_common + load and auth image from fip + with info from plat_io_policy + end note + bl_common -> arm_io_storage + arm_io_storage -> fconf: FCONF_GET_PROPERTY(arm, arm_io_policies, TB_FW_CONFIG_ID) + note over fconf: use statically defined policies in bl1 fconf <- bl_common : image_info deactivate bl_common note over fconf : get tb_fw_config_dtb from image_info - fconf -> plat_bl1_common : bl1_plat_get_image_desc(BL2_IMAGE_ID) - fconf <- plat_bl1_common : BL2_IMAGE_DESC - note over fconf - set ep_info.args.arg0 of BL2_IMAGE_DESC - to FW_CONFIG base address + fconf -> arm_bl1_setup + arm_bl1_setup -> plat_bl1_common : bl1_plat_get_image_desc(BL2_IMAGE_ID) + arm_bl1_setup <- plat_bl1_common : BL2_IMAGE_DESC + note over arm_bl1_setup + set ep_info.args.arg0 of BL2_IMAGE_DESC + to FW_CONFIG base address end note -arm_bl1_setup <- fconf deactivate fconf == load & auth, prepare and jump to BL2 == diff --git a/docs/resources/diagrams/plantuml/fconf_bl2_populate.puml b/docs/resources/diagrams/plantuml/fconf_bl2_populate.puml index 881f25343..c536ee090 100644 --- a/docs/resources/diagrams/plantuml/fconf_bl2_populate.puml +++ b/docs/resources/diagrams/plantuml/fconf_bl2_populate.puml @@ -8,6 +8,7 @@ end box box "platform common code" participant fconf participant fconf_tbbr_getter +participant fconf_dyn_cfg_getter end box box "arm platform code" #LightBlue @@ -25,10 +26,17 @@ note over arm_bl2_setup end note arm_bl2_setup -> arm_bl2_setup : arm_bl2_early_platform_setup(\n\t fw_config, mem_layout) activate arm_bl2_setup - arm_bl2_setup -> fconf: fconf_polulate("TB_FW", fw_config) + arm_bl2_setup -> fconf: fconf_populate("FW_CONFIG", fw_config) activate fconf + fconf -> fconf_dyn_cfg_getter: populate_dtb_registry(uintptr_t dtb) + note over fconf_dyn_cfg_getter: read dtb_registry properties from dtb + fconf_dyn_cfg_getter -> arm_bl2_setup + arm_bl2_setup -> fconf: FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID) + fconf -> fconf_dyn_cfg_getter: dyn_cfg_dtb_info_getter(TB_FW_CONFIG_ID) + fconf_dyn_cfg_getter -> arm_bl2_setup: tb_fw_config_info + arm_bl2_setup -> fconf: fconf_populate("TB_FW_CONFIG", tb_fw_config) fconf -> fconf_tbbr_getter: fconf_populate_tbbr_dyn_config(uintptr_t dtb) - note over fconf_tbbr_getter: read tbbr propeties from dtb + note over fconf_tbbr_getter: read tbbr properties from dtb fconf -> arm_fconf_io: fconf_populate_arm_io_policies(uintptr_t dtb) note over arm_fconf_io: read arm io propeties from dtb deactivate fconf -- cgit v1.2.3 From d1c54e5b7c93252dfdb1185bafcd3e6926a303f4 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Wed, 24 Jun 2020 15:58:38 +0100 Subject: doc: Update arg usage for BL2 and BL31 setup functions Updated the porting guide for the usage of received arguments in BL2 and BL32 setup functions in case of Arm platform. Signed-off-by: Manish V Badarkhe Change-Id: Ia83a5607fed999819d25e49322b3bfb5db9425c0 --- docs/getting_started/porting-guide.rst | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst index b7a93e40a..45c27ade0 100644 --- a/docs/getting_started/porting-guide.rst +++ b/docs/getting_started/porting-guide.rst @@ -1424,7 +1424,7 @@ are platform specific. On Arm standard platforms, the arguments received are : - arg0 - Points to load address of HW_CONFIG if present + arg0 - Points to load address of FW_CONFIG arg1 - ``meminfo`` structure populated by BL1. The platform copies the contents of ``meminfo`` as it may be subsequently overwritten by BL2. @@ -1736,6 +1736,10 @@ In Arm standard platforms, the arguments received are : which is list of executable images following BL31, arg1 - Points to load address of SOC_FW_CONFIG if present + except in case of Arm FVP platform. + + In case of Arm FVP platform, Points to load address + of FW_CONFIG. arg2 - Points to load address of HW_CONFIG if present -- cgit v1.2.3 From 53baf7f049d250bb96f59050fcff657455241cad Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 25 Jun 2020 13:10:13 +0100 Subject: arm_fpga: Fix MPIDR topology checks The plat_core_pos_by_mpidr() implementation for the Arm FPGA port has some issues, which leads to problems when matching GICv3 redistributors with cores: - The power domain tree was not taking multithreading into account, so we ended up with the wrong mapping between MPIDRs and core IDs. - Before even considering an MPIDR, we try to make sure Aff2 is 0. Unfortunately this is the cluster ID when the MT bit is set. - We mask off the MT bit in MPIDR, before basing decisions on it. - When detecting the MT bit, we are properly calculating the thread ID, but don't account for the shift in the core and cluster ID checks. Those problems lead to early rejections of MPIDRs values, in particular when called from the GIC code. As a result, CPU_ON for secondary cores was failing for most of the cores. Fix this by properly handling the MT bit in plat_core_pos_by_mpidr(), also pulling in FPGA_MAX_PE_PER_CPU when populating the power domain tree. Change-Id: I71b2255fc0d27bfe5806511df479ab38e4e33fc4 Signed-off-by: Andre Przywara --- plat/arm/board/arm_fpga/fpga_topology.c | 38 +++++++++++++++++---------------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/plat/arm/board/arm_fpga/fpga_topology.c b/plat/arm/board/arm_fpga/fpga_topology.c index a705429ac..a2908d727 100644 --- a/plat/arm/board/arm_fpga/fpga_topology.c +++ b/plat/arm/board/arm_fpga/fpga_topology.c @@ -26,7 +26,7 @@ const unsigned char *plat_get_power_domain_tree_desc(void) fpga_power_domain_tree_desc[1] = FPGA_MAX_CLUSTER_COUNT; for (i = 0; i < FPGA_MAX_CLUSTER_COUNT; i++) { - fpga_power_domain_tree_desc[i + 2] = FPGA_MAX_CPUS_PER_CLUSTER; + fpga_power_domain_tree_desc[i + 2] = FPGA_MAX_CPUS_PER_CLUSTER * FPGA_MAX_PE_PER_CPU; } return fpga_power_domain_tree_desc; @@ -36,35 +36,37 @@ int plat_core_pos_by_mpidr(u_register_t mpidr) { unsigned int cluster_id, cpu_id, thread_id; - mpidr &= MPIDR_AFFINITY_MASK; - if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) { - return -1; - } + /* + * The image running on the FPGA may or may not implement + * multithreading, and it shouldn't be assumed this is consistent + * across all CPUs. + * This ensures that any passed mpidr values reflect the status of the + * primary CPU's MT bit. + */ + mpidr |= (read_mpidr_el1() & MPIDR_MT_MASK); + mpidr &= MPID_MASK; if (mpidr & MPIDR_MT_MASK) { thread_id = MPIDR_AFFLVL0_VAL(mpidr); + cpu_id = MPIDR_AFFLVL1_VAL(mpidr); + cluster_id = MPIDR_AFFLVL2_VAL(mpidr); } else { thread_id = 0; + cpu_id = MPIDR_AFFLVL0_VAL(mpidr); + cluster_id = MPIDR_AFFLVL1_VAL(mpidr); } - cpu_id = MPIDR_AFFLVL1_VAL(mpidr); - cluster_id = MPIDR_AFFLVL2_VAL(mpidr); - if (cluster_id >= FPGA_MAX_CLUSTER_COUNT) { return -1; - } else if (cpu_id >= FPGA_MAX_CPUS_PER_CLUSTER) { - return -1; - } else if (thread_id >= FPGA_MAX_PE_PER_CPU) { + } + + if (cpu_id >= FPGA_MAX_CPUS_PER_CLUSTER) { return -1; } - /* - * The image running on the FPGA may or may not implement multithreading, - * and it shouldn't be assumed this is consistent across all CPUs. - * This ensures that any passed mpidr values reflect the status of the - * primary CPU's MT bit. - */ - mpidr |= (read_mpidr_el1() & MPIDR_MT_MASK); + if (thread_id >= FPGA_MAX_PE_PER_CPU) { + return -1; + } /* Calculate the correct core, catering for multi-threaded images */ return (int) plat_fpga_calc_core_pos(mpidr); -- cgit v1.2.3 From 243ce5d5e574a92b5cc92b6e257471fb390d87f7 Mon Sep 17 00:00:00 2001 From: Madhukar Pappireddy Date: Mon, 15 Jun 2020 17:19:09 -0500 Subject: Upgrade libfdt source files This version corresponds to the following commit <7be250b> libfdt: Correct condition for reordering blocks Also, updated the Juno romlib jumptable with fdt APIs. Change-Id: Ib6d28c1aea81c2144a263958f0792cc4daea7a1f Signed-off-by: Madhukar Pappireddy --- include/lib/libfdt/fdt.h | 49 +------ include/lib/libfdt/libfdt.h | 290 +++++++++++++++++++++++++++++++--------- include/lib/libfdt/libfdt_env.h | 49 +------ lib/libfdt/fdt.c | 186 +++++++++++++++++--------- lib/libfdt/fdt_addresses.c | 133 +++++++++--------- lib/libfdt/fdt_empty_tree.c | 47 +------ lib/libfdt/fdt_overlay.c | 91 +++++-------- lib/libfdt/fdt_ro.c | 280 ++++++++++++++++++++++++-------------- lib/libfdt/fdt_rw.c | 133 +++++++++--------- lib/libfdt/fdt_strerror.c | 47 +------ lib/libfdt/fdt_sw.c | 241 ++++++++++++++++++++++----------- lib/libfdt/fdt_wip.c | 47 +------ lib/libfdt/libfdt_internal.h | 180 ++++++++++++++++++------- plat/arm/board/juno/jmptbl.i | 2 + 14 files changed, 996 insertions(+), 779 deletions(-) diff --git a/include/lib/libfdt/fdt.h b/include/lib/libfdt/fdt.h index ef7c86b6d..eb9edb72f 100644 --- a/include/lib/libfdt/fdt.h +++ b/include/lib/libfdt/fdt.h @@ -1,55 +1,10 @@ +/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */ #ifndef FDT_H #define FDT_H /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2006 David Gibson, IBM Corporation. * Copyright 2012 Kim Phillips, Freescale Semiconductor. - * - * libfdt is dual licensed: you can use it either under the terms of - * the GPL, or the BSD license, at your option. - * - * a) This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * Alternatively, - * - * b) Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef __ASSEMBLER__ @@ -90,7 +45,7 @@ struct fdt_property { char data[0]; }; -#endif /* !__ASSEMBLER__ */ +#endif /* !__ASSEMBLER__*/ #define FDT_MAGIC 0xd00dfeed /* 4: version, 4: total size */ #define FDT_TAGSIZE sizeof(fdt32_t) diff --git a/include/lib/libfdt/libfdt.h b/include/lib/libfdt/libfdt.h index c8c00fa86..48f375c9c 100644 --- a/include/lib/libfdt/libfdt.h +++ b/include/lib/libfdt/libfdt.h @@ -1,54 +1,9 @@ +/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */ #ifndef LIBFDT_H #define LIBFDT_H /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2006 David Gibson, IBM Corporation. - * - * libfdt is dual licensed: you can use it either under the terms of - * the GPL, or the BSD license, at your option. - * - * a) This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * Alternatively, - * - * b) Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include @@ -90,8 +45,9 @@ /* Error codes: codes for bad device tree blobs */ #define FDT_ERR_TRUNCATED 8 - /* FDT_ERR_TRUNCATED: Structure block of the given device tree - * ends without an FDT_END tag. */ + /* FDT_ERR_TRUNCATED: FDT or a sub-block is improperly + * terminated (overflows, goes outside allowed bounds, or + * isn't properly terminated). */ #define FDT_ERR_BADMAGIC 9 /* FDT_ERR_BADMAGIC: Given "device tree" appears not to be a * device tree at all - it is missing the flattened device @@ -137,7 +93,15 @@ /* FDT_ERR_NOPHANDLES: The device tree doesn't have any * phandle available anymore without causing an overflow */ -#define FDT_ERR_MAX 17 +#define FDT_ERR_BADFLAGS 18 + /* FDT_ERR_BADFLAGS: The function was passed a flags field that + * contains invalid flags or an invalid combination of flags. */ + +#define FDT_ERR_MAX 18 + +/* constants */ +#define FDT_MAX_PHANDLE 0xfffffffe + /* Valid values for phandles range from 1 to 2^32-2. */ /**********************************************************************/ /* Low-level functions (you probably don't need these) */ @@ -153,6 +117,61 @@ static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen) uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset); +/* + * Alignment helpers: + * These helpers access words from a device tree blob. They're + * built to work even with unaligned pointers on platforms (ike + * ARM) that don't like unaligned loads and stores + */ + +static inline uint32_t fdt32_ld(const fdt32_t *p) +{ + const uint8_t *bp = (const uint8_t *)p; + + return ((uint32_t)bp[0] << 24) + | ((uint32_t)bp[1] << 16) + | ((uint32_t)bp[2] << 8) + | bp[3]; +} + +static inline void fdt32_st(void *property, uint32_t value) +{ + uint8_t *bp = (uint8_t *)property; + + bp[0] = value >> 24; + bp[1] = (value >> 16) & 0xff; + bp[2] = (value >> 8) & 0xff; + bp[3] = value & 0xff; +} + +static inline uint64_t fdt64_ld(const fdt64_t *p) +{ + const uint8_t *bp = (const uint8_t *)p; + + return ((uint64_t)bp[0] << 56) + | ((uint64_t)bp[1] << 48) + | ((uint64_t)bp[2] << 40) + | ((uint64_t)bp[3] << 32) + | ((uint64_t)bp[4] << 24) + | ((uint64_t)bp[5] << 16) + | ((uint64_t)bp[6] << 8) + | bp[7]; +} + +static inline void fdt64_st(void *property, uint64_t value) +{ + uint8_t *bp = (uint8_t *)property; + + bp[0] = value >> 56; + bp[1] = (value >> 48) & 0xff; + bp[2] = (value >> 40) & 0xff; + bp[3] = (value >> 32) & 0xff; + bp[4] = (value >> 24) & 0xff; + bp[5] = (value >> 16) & 0xff; + bp[6] = (value >> 8) & 0xff; + bp[7] = value & 0xff; +} + /**********************************************************************/ /* Traversal functions */ /**********************************************************************/ @@ -195,7 +214,7 @@ int fdt_next_subnode(const void *fdt, int offset); * ... * } * - * if ((node < 0) && (node != -FDT_ERR_NOT_FOUND)) { + * if ((node < 0) && (node != -FDT_ERR_NOTFOUND)) { * Error handling * } * @@ -213,7 +232,7 @@ int fdt_next_subnode(const void *fdt, int offset); /* General functions */ /**********************************************************************/ #define fdt_get_header(fdt, field) \ - (fdt32_to_cpu(((const struct fdt_header *)(fdt))->field)) + (fdt32_ld(&((const struct fdt_header *)(fdt))->field)) #define fdt_magic(fdt) (fdt_get_header(fdt, magic)) #define fdt_totalsize(fdt) (fdt_get_header(fdt, totalsize)) #define fdt_off_dt_struct(fdt) (fdt_get_header(fdt, off_dt_struct)) @@ -244,18 +263,32 @@ fdt_set_hdr_(size_dt_struct); #undef fdt_set_hdr_ /** - * fdt_check_header - sanity check a device tree or possible device tree + * fdt_header_size - return the size of the tree's header + * @fdt: pointer to a flattened device tree + */ +size_t fdt_header_size(const void *fdt); + +/** + * fdt_header_size_ - internal function which takes a version number + */ +size_t fdt_header_size_(uint32_t version); + +/** + * fdt_check_header - sanity check a device tree header + * @fdt: pointer to data which might be a flattened device tree * * fdt_check_header() checks that the given buffer contains what - * appears to be a flattened device tree with sane information in its - * header. + * appears to be a flattened device tree, and that the header contains + * valid information (to the extent that can be determined from the + * header alone). * * returns: * 0, if the buffer appears to contain a valid device tree * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, standard meanings, as above + * -FDT_ERR_BADSTATE, + * -FDT_ERR_TRUNCATED, standard meanings, as above */ int fdt_check_header(const void *fdt); @@ -284,6 +317,24 @@ int fdt_move(const void *fdt, void *buf, int bufsize); /* Read-only functions */ /**********************************************************************/ +int fdt_check_full(const void *fdt, size_t bufsize); + +/** + * fdt_get_string - retrieve a string from the strings block of a device tree + * @fdt: pointer to the device tree blob + * @stroffset: offset of the string within the strings block (native endian) + * @lenp: optional pointer to return the string's length + * + * fdt_get_string() retrieves a pointer to a single string from the + * strings block of the device tree blob at fdt, and optionally also + * returns the string's length in *lenp. + * + * returns: + * a pointer to the string, on success + * NULL, if stroffset is out of bounds, or doesn't point to a valid string + */ +const char *fdt_get_string(const void *fdt, int stroffset, int *lenp); + /** * fdt_string - retrieve a string from the strings block of a device tree * @fdt: pointer to the device tree blob @@ -294,10 +345,24 @@ int fdt_move(const void *fdt, void *buf, int bufsize); * * returns: * a pointer to the string, on success - * NULL, if stroffset is out of bounds + * NULL, if stroffset is out of bounds, or doesn't point to a valid string */ const char *fdt_string(const void *fdt, int stroffset); +/** + * fdt_find_max_phandle - find and return the highest phandle in a tree + * @fdt: pointer to the device tree blob + * @phandle: return location for the highest phandle value found in the tree + * + * fdt_find_max_phandle() finds the highest phandle value in the given device + * tree. The value returned in @phandle is only valid if the function returns + * success. + * + * returns: + * 0 on success or a negative error code on failure + */ +int fdt_find_max_phandle(const void *fdt, uint32_t *phandle); + /** * fdt_get_max_phandle - retrieves the highest phandle in a tree * @fdt: pointer to the device tree blob @@ -306,12 +371,39 @@ const char *fdt_string(const void *fdt, int stroffset); * device tree. This will ignore badly formatted phandles, or phandles * with a value of 0 or -1. * + * This function is deprecated in favour of fdt_find_max_phandle(). + * * returns: * the highest phandle on success * 0, if no phandle was found in the device tree * -1, if an error occurred */ -uint32_t fdt_get_max_phandle(const void *fdt); +static inline uint32_t fdt_get_max_phandle(const void *fdt) +{ + uint32_t phandle; + int err; + + err = fdt_find_max_phandle(fdt, &phandle); + if (err < 0) + return (uint32_t)-1; + + return phandle; +} + +/** + * fdt_generate_phandle - return a new, unused phandle for a device tree blob + * @fdt: pointer to the device tree blob + * @phandle: return location for the new phandle + * + * Walks the device tree blob and looks for the highest phandle value. On + * success, the new, unused phandle value (one higher than the previously + * highest phandle value in the device tree blob) will be returned in the + * @phandle parameter. + * + * Returns: + * 0 on success or a negative error-code on failure + */ +int fdt_generate_phandle(const void *fdt, uint32_t *phandle); /** * fdt_num_mem_rsv - retrieve the number of memory reserve map entries @@ -503,7 +595,7 @@ int fdt_next_property_offset(const void *fdt, int offset); * ... * } * - * if ((property < 0) && (property != -FDT_ERR_NOT_FOUND)) { + * if ((property < 0) && (property != -FDT_ERR_NOTFOUND)) { * Error handling * } * @@ -606,7 +698,7 @@ static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset, /** * fdt_getprop_by_offset - retrieve the value of a property at a given offset * @fdt: pointer to the device tree blob - * @ffset: offset of the property to read + * @offset: offset of the property to read * @namep: pointer to a string variable (will be overwritten) or NULL * @lenp: pointer to an integer variable (will be overwritten) or NULL * @@ -1090,7 +1182,7 @@ int fdt_address_cells(const void *fdt, int nodeoffset); * * returns: * 0 <= n < FDT_MAX_NCELLS, on success - * 2, if the node has no #address-cells property + * 1, if the node has no #size-cells property * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid * #size-cells property * -FDT_ERR_BADMAGIC, @@ -1297,7 +1389,45 @@ int fdt_nop_node(void *fdt, int nodeoffset); /* Sequential write functions */ /**********************************************************************/ +/* fdt_create_with_flags flags */ +#define FDT_CREATE_FLAG_NO_NAME_DEDUP 0x1 + /* FDT_CREATE_FLAG_NO_NAME_DEDUP: Do not try to de-duplicate property + * names in the fdt. This can result in faster creation times, but + * a larger fdt. */ + +#define FDT_CREATE_FLAGS_ALL (FDT_CREATE_FLAG_NO_NAME_DEDUP) + +/** + * fdt_create_with_flags - begin creation of a new fdt + * @fdt: pointer to memory allocated where fdt will be created + * @bufsize: size of the memory space at fdt + * @flags: a valid combination of FDT_CREATE_FLAG_ flags, or 0. + * + * fdt_create_with_flags() begins the process of creating a new fdt with + * the sequential write interface. + * + * fdt creation process must end with fdt_finished() to produce a valid fdt. + * + * returns: + * 0, on success + * -FDT_ERR_NOSPACE, bufsize is insufficient for a minimal fdt + * -FDT_ERR_BADFLAGS, flags is not valid + */ +int fdt_create_with_flags(void *buf, int bufsize, uint32_t flags); + +/** + * fdt_create - begin creation of a new fdt + * @fdt: pointer to memory allocated where fdt will be created + * @bufsize: size of the memory space at fdt + * + * fdt_create() is equivalent to fdt_create_with_flags() with flags=0. + * + * returns: + * 0, on success + * -FDT_ERR_NOSPACE, bufsize is insufficient for a minimal fdt + */ int fdt_create(void *buf, int bufsize); + int fdt_resize(void *fdt, void *buf, int bufsize); int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size); int fdt_finish_reservemap(void *fdt); @@ -1313,10 +1443,13 @@ static inline int fdt_property_u64(void *fdt, const char *name, uint64_t val) fdt64_t tmp = cpu_to_fdt64(val); return fdt_property(fdt, name, &tmp, sizeof(tmp)); } + +#ifndef SWIG /* Not available in Python */ static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val) { return fdt_property_u32(fdt, name, val); } +#endif /** * fdt_property_placeholder - add a new property and return a ptr to its value @@ -1765,6 +1898,43 @@ static inline int fdt_appendprop_cell(void *fdt, int nodeoffset, #define fdt_appendprop_string(fdt, nodeoffset, name, str) \ fdt_appendprop((fdt), (nodeoffset), (name), (str), strlen(str)+1) +/** + * fdt_appendprop_addrrange - append a address range property + * @fdt: pointer to the device tree blob + * @parent: offset of the parent node + * @nodeoffset: offset of the node to add a property at + * @name: name of property + * @addr: start address of a given range + * @size: size of a given range + * + * fdt_appendprop_addrrange() appends an address range value (start + * address and size) to the value of the named property in the given + * node, or creates a new property with that value if it does not + * already exist. + * If "name" is not specified, a default "reg" is used. + * Cell sizes are determined by parent's #address-cells and #size-cells. + * + * This function may insert data into the blob, and will therefore + * change the offsets of some existing nodes. + * + * returns: + * 0, on success + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid + * #address-cells property + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADVALUE, addr or size doesn't fit to respective cells size + * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to + * contain a new property + * -FDT_ERR_TRUNCATED, standard meanings + */ +int fdt_appendprop_addrrange(void *fdt, int parent, int nodeoffset, + const char *name, uint64_t addr, uint64_t size); + /** * fdt_delprop - delete a property * @fdt: pointer to the device tree blob diff --git a/include/lib/libfdt/libfdt_env.h b/include/lib/libfdt/libfdt_env.h index bd2474628..73b6d4045 100644 --- a/include/lib/libfdt/libfdt_env.h +++ b/include/lib/libfdt/libfdt_env.h @@ -1,61 +1,18 @@ +/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */ #ifndef LIBFDT_ENV_H #define LIBFDT_ENV_H /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2006 David Gibson, IBM Corporation. * Copyright 2012 Kim Phillips, Freescale Semiconductor. - * - * libfdt is dual licensed: you can use it either under the terms of - * the GPL, or the BSD license, at your option. - * - * a) This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * Alternatively, - * - * b) Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include #include #include #include +#include #ifdef __CHECKER__ #define FDT_FORCE __attribute__((force)) diff --git a/lib/libfdt/fdt.c b/lib/libfdt/fdt.c index 7855a1787..c28fcc115 100644 --- a/lib/libfdt/fdt.c +++ b/lib/libfdt/fdt.c @@ -1,52 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2006 David Gibson, IBM Corporation. - * - * libfdt is dual licensed: you can use it either under the terms of - * the GPL, or the BSD license, at your option. - * - * a) This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * Alternatively, - * - * b) Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "libfdt_env.h" @@ -55,22 +10,125 @@ #include "libfdt_internal.h" -int fdt_check_header(const void *fdt) +/* + * Minimal sanity check for a read-only tree. fdt_ro_probe_() checks + * that the given buffer contains what appears to be a flattened + * device tree with sane information in its header. + */ +int32_t fdt_ro_probe_(const void *fdt) { + uint32_t totalsize = fdt_totalsize(fdt); + + if (can_assume(VALID_DTB)) + return totalsize; + if (fdt_magic(fdt) == FDT_MAGIC) { /* Complete tree */ - if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION) - return -FDT_ERR_BADVERSION; - if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION) - return -FDT_ERR_BADVERSION; + if (!can_assume(LATEST)) { + if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION) + return -FDT_ERR_BADVERSION; + if (fdt_last_comp_version(fdt) > + FDT_LAST_SUPPORTED_VERSION) + return -FDT_ERR_BADVERSION; + } } else if (fdt_magic(fdt) == FDT_SW_MAGIC) { /* Unfinished sequential-write blob */ - if (fdt_size_dt_struct(fdt) == 0) + if (!can_assume(VALID_INPUT) && fdt_size_dt_struct(fdt) == 0) return -FDT_ERR_BADSTATE; } else { return -FDT_ERR_BADMAGIC; } + if (totalsize < INT32_MAX) + return totalsize; + else + return -FDT_ERR_TRUNCATED; +} + +static int check_off_(uint32_t hdrsize, uint32_t totalsize, uint32_t off) +{ + return (off >= hdrsize) && (off <= totalsize); +} + +static int check_block_(uint32_t hdrsize, uint32_t totalsize, + uint32_t base, uint32_t size) +{ + if (!check_off_(hdrsize, totalsize, base)) + return 0; /* block start out of bounds */ + if ((base + size) < base) + return 0; /* overflow */ + if (!check_off_(hdrsize, totalsize, base + size)) + return 0; /* block end out of bounds */ + return 1; +} + +size_t fdt_header_size_(uint32_t version) +{ + if (version <= 1) + return FDT_V1_SIZE; + else if (version <= 2) + return FDT_V2_SIZE; + else if (version <= 3) + return FDT_V3_SIZE; + else if (version <= 16) + return FDT_V16_SIZE; + else + return FDT_V17_SIZE; +} + +size_t fdt_header_size(const void *fdt) +{ + return can_assume(LATEST) ? FDT_V17_SIZE : + fdt_header_size_(fdt_version(fdt)); +} + +int fdt_check_header(const void *fdt) +{ + size_t hdrsize; + + if (fdt_magic(fdt) != FDT_MAGIC) + return -FDT_ERR_BADMAGIC; + if (!can_assume(LATEST)) { + if ((fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION) + || (fdt_last_comp_version(fdt) > + FDT_LAST_SUPPORTED_VERSION)) + return -FDT_ERR_BADVERSION; + if (fdt_version(fdt) < fdt_last_comp_version(fdt)) + return -FDT_ERR_BADVERSION; + } + hdrsize = fdt_header_size(fdt); + if (!can_assume(VALID_DTB)) { + + if ((fdt_totalsize(fdt) < hdrsize) + || (fdt_totalsize(fdt) > INT_MAX)) + return -FDT_ERR_TRUNCATED; + + /* Bounds check memrsv block */ + if (!check_off_(hdrsize, fdt_totalsize(fdt), + fdt_off_mem_rsvmap(fdt))) + return -FDT_ERR_TRUNCATED; + } + + if (!can_assume(VALID_DTB)) { + /* Bounds check structure block */ + if (!can_assume(LATEST) && fdt_version(fdt) < 17) { + if (!check_off_(hdrsize, fdt_totalsize(fdt), + fdt_off_dt_struct(fdt))) + return -FDT_ERR_TRUNCATED; + } else { + if (!check_block_(hdrsize, fdt_totalsize(fdt), + fdt_off_dt_struct(fdt), + fdt_size_dt_struct(fdt))) + return -FDT_ERR_TRUNCATED; + } + + /* Bounds check strings block */ + if (!check_block_(hdrsize, fdt_totalsize(fdt), + fdt_off_dt_strings(fdt), + fdt_size_dt_strings(fdt))) + return -FDT_ERR_TRUNCATED; + } + return 0; } @@ -78,12 +136,13 @@ const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len) { unsigned absoffset = offset + fdt_off_dt_struct(fdt); - if ((absoffset < offset) - || ((absoffset + len) < absoffset) - || (absoffset + len) > fdt_totalsize(fdt)) - return NULL; + if (!can_assume(VALID_INPUT)) + if ((absoffset < offset) + || ((absoffset + len) < absoffset) + || (absoffset + len) > fdt_totalsize(fdt)) + return NULL; - if (fdt_version(fdt) >= 0x11) + if (can_assume(LATEST) || fdt_version(fdt) >= 0x11) if (((offset + len) < offset) || ((offset + len) > fdt_size_dt_struct(fdt))) return NULL; @@ -100,7 +159,7 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) *nextoffset = -FDT_ERR_TRUNCATED; tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE); - if (!tagp) + if (!can_assume(VALID_DTB) && !tagp) return FDT_END; /* premature end */ tag = fdt32_to_cpu(*tagp); offset += FDT_TAGSIZE; @@ -112,18 +171,19 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) do { p = fdt_offset_ptr(fdt, offset++, 1); } while (p && (*p != '\0')); - if (!p) + if (!can_assume(VALID_DTB) && !p) return FDT_END; /* premature end */ break; case FDT_PROP: lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp)); - if (!lenp) + if (!can_assume(VALID_DTB) && !lenp) return FDT_END; /* premature end */ /* skip-name offset, length and value */ offset += sizeof(struct fdt_property) - FDT_TAGSIZE + fdt32_to_cpu(*lenp); - if (fdt_version(fdt) < 0x10 && fdt32_to_cpu(*lenp) >= 8 && + if (!can_assume(LATEST) && + fdt_version(fdt) < 0x10 && fdt32_to_cpu(*lenp) >= 8 && ((offset - fdt32_to_cpu(*lenp)) % 8) != 0) offset += 4; break; @@ -146,6 +206,8 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) int fdt_check_node_offset_(const void *fdt, int offset) { + if (can_assume(VALID_INPUT)) + return offset; if ((offset < 0) || (offset % FDT_TAGSIZE) || (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE)) return -FDT_ERR_BADOFFSET; @@ -244,7 +306,7 @@ const char *fdt_find_string_(const char *strtab, int tabsize, const char *s) int fdt_move(const void *fdt, void *buf, int bufsize) { - FDT_CHECK_HEADER(fdt); + FDT_RO_PROBE(fdt); if (fdt_totalsize(fdt) > bufsize) return -FDT_ERR_NOSPACE; diff --git a/lib/libfdt/fdt_addresses.c b/lib/libfdt/fdt_addresses.c index eff4dbcc7..9a82cd0ba 100644 --- a/lib/libfdt/fdt_addresses.c +++ b/lib/libfdt/fdt_addresses.c @@ -1,52 +1,8 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2014 David Gibson - * - * libfdt is dual licensed: you can use it either under the terms of - * the GPL, or the BSD license, at your option. - * - * a) This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * Alternatively, - * - * b) Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * Copyright (C) 2018 embedded brains GmbH */ #include "libfdt_env.h" @@ -55,42 +11,91 @@ #include "libfdt_internal.h" -int fdt_address_cells(const void *fdt, int nodeoffset) +static int fdt_cells(const void *fdt, int nodeoffset, const char *name) { - const fdt32_t *ac; - int val; + const fdt32_t *c; + uint32_t val; int len; - ac = fdt_getprop(fdt, nodeoffset, "#address-cells", &len); - if (!ac) - return 2; + c = fdt_getprop(fdt, nodeoffset, name, &len); + if (!c) + return len; - if (len != sizeof(*ac)) + if (len != sizeof(*c)) return -FDT_ERR_BADNCELLS; - val = fdt32_to_cpu(*ac); - if ((val <= 0) || (val > FDT_MAX_NCELLS)) + val = fdt32_to_cpu(*c); + if (val > FDT_MAX_NCELLS) return -FDT_ERR_BADNCELLS; + return (int)val; +} + +int fdt_address_cells(const void *fdt, int nodeoffset) +{ + int val; + + val = fdt_cells(fdt, nodeoffset, "#address-cells"); + if (val == 0) + return -FDT_ERR_BADNCELLS; + if (val == -FDT_ERR_NOTFOUND) + return 2; return val; } int fdt_size_cells(const void *fdt, int nodeoffset) { - const fdt32_t *sc; int val; - int len; - sc = fdt_getprop(fdt, nodeoffset, "#size-cells", &len); - if (!sc) - return 2; + val = fdt_cells(fdt, nodeoffset, "#size-cells"); + if (val == -FDT_ERR_NOTFOUND) + return 1; + return val; +} + +/* This function assumes that [address|size]_cells is 1 or 2 */ +int fdt_appendprop_addrrange(void *fdt, int parent, int nodeoffset, + const char *name, uint64_t addr, uint64_t size) +{ + int addr_cells, size_cells, ret; + uint8_t data[sizeof(fdt64_t) * 2], *prop; - if (len != sizeof(*sc)) + ret = fdt_address_cells(fdt, parent); + if (ret < 0) + return ret; + addr_cells = ret; + + ret = fdt_size_cells(fdt, parent); + if (ret < 0) + return ret; + size_cells = ret; + + /* check validity of address */ + prop = data; + if (addr_cells == 1) { + if ((addr > UINT32_MAX) || ((UINT32_MAX + 1 - addr) < size)) + return -FDT_ERR_BADVALUE; + + fdt32_st(prop, (uint32_t)addr); + } else if (addr_cells == 2) { + fdt64_st(prop, addr); + } else { return -FDT_ERR_BADNCELLS; + } - val = fdt32_to_cpu(*sc); - if ((val < 0) || (val > FDT_MAX_NCELLS)) + /* check validity of size */ + prop += addr_cells * sizeof(fdt32_t); + if (size_cells == 1) { + if (size > UINT32_MAX) + return -FDT_ERR_BADVALUE; + + fdt32_st(prop, (uint32_t)size); + } else if (size_cells == 2) { + fdt64_st(prop, size); + } else { return -FDT_ERR_BADNCELLS; + } - return val; + return fdt_appendprop(fdt, nodeoffset, name, data, + (addr_cells + size_cells) * sizeof(fdt32_t)); } diff --git a/lib/libfdt/fdt_empty_tree.c b/lib/libfdt/fdt_empty_tree.c index f2ae9b77c..49d54d44b 100644 --- a/lib/libfdt/fdt_empty_tree.c +++ b/lib/libfdt/fdt_empty_tree.c @@ -1,52 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2012 David Gibson, IBM Corporation. - * - * libfdt is dual licensed: you can use it either under the terms of - * the GPL, or the BSD license, at your option. - * - * a) This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * Alternatively, - * - * b) Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "libfdt_env.h" diff --git a/lib/libfdt/fdt_overlay.c b/lib/libfdt/fdt_overlay.c index bf75388ec..b310e49a6 100644 --- a/lib/libfdt/fdt_overlay.c +++ b/lib/libfdt/fdt_overlay.c @@ -1,53 +1,8 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2016 Free Electrons * Copyright (C) 2016 NextThing Co. - * - * libfdt is dual licensed: you can use it either under the terms of - * the GPL, or the BSD license, at your option. - * - * a) This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * Alternatively, - * - * b) Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "libfdt_env.h" @@ -93,11 +48,11 @@ static uint32_t overlay_get_target_phandle(const void *fdto, int fragment) * @pathp: pointer which receives the path of the target (or NULL) * * overlay_get_target() retrieves the target offset in the base - * device tree of a fragment, no matter how the actual targetting is + * device tree of a fragment, no matter how the actual targeting is * done (through a phandle or a path) * * returns: - * the targetted node offset in the base device tree + * the targeted node offset in the base device tree * Negative error code on error */ static int overlay_get_target(const void *fdt, const void *fdto, @@ -697,7 +652,7 @@ static int get_path_len(const void *fdt, int nodeoffset) int len = 0, namelen; const char *name; - FDT_CHECK_HEADER(fdt); + FDT_RO_PROBE(fdt); for (;;) { name = fdt_get_name(fdt, nodeoffset, &namelen); @@ -778,26 +733,36 @@ static int overlay_symbol_update(void *fdt, void *fdto) /* keep end marker to avoid strlen() */ e = path + path_len; - /* format: //__overlay__/ */ - if (*path != '/') return -FDT_ERR_BADVALUE; /* get fragment name first */ s = strchr(path + 1, '/'); - if (!s) - return -FDT_ERR_BADOVERLAY; + if (!s) { + /* Symbol refers to something that won't end + * up in the target tree */ + continue; + } frag_name = path + 1; frag_name_len = s - path - 1; /* verify format; safe since "s" lies in \0 terminated prop */ len = sizeof("/__overlay__/") - 1; - if ((e - s) < len || memcmp(s, "/__overlay__/", len)) - return -FDT_ERR_BADOVERLAY; - - rel_path = s + len; - rel_path_len = e - rel_path; + if ((e - s) > len && (memcmp(s, "/__overlay__/", len) == 0)) { + /* //__overlay__/ */ + rel_path = s + len; + rel_path_len = e - rel_path - 1; + } else if ((e - s) == len + && (memcmp(s, "/__overlay__", len - 1) == 0)) { + /* //__overlay__ */ + rel_path = ""; + rel_path_len = 0; + } else { + /* Symbol refers to something that won't end + * up in the target tree */ + continue; + } /* find the fragment index in which the symbol lies */ ret = fdt_subnode_offset_namelen(fdto, 0, frag_name, @@ -863,11 +828,15 @@ static int overlay_symbol_update(void *fdt, void *fdto) int fdt_overlay_apply(void *fdt, void *fdto) { - uint32_t delta = fdt_get_max_phandle(fdt); + uint32_t delta; int ret; - FDT_CHECK_HEADER(fdt); - FDT_CHECK_HEADER(fdto); + FDT_RO_PROBE(fdt); + FDT_RO_PROBE(fdto); + + ret = fdt_find_max_phandle(fdt, &delta); + if (ret) + goto err; ret = overlay_adjust_local_phandles(fdto, delta); if (ret) diff --git a/lib/libfdt/fdt_ro.c b/lib/libfdt/fdt_ro.c index dfb3236da..e03570a56 100644 --- a/lib/libfdt/fdt_ro.c +++ b/lib/libfdt/fdt_ro.c @@ -1,52 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2006 David Gibson, IBM Corporation. - * - * libfdt is dual licensed: you can use it either under the terms of - * the GPL, or the BSD license, at your option. - * - * a) This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * Alternatively, - * - * b) Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "libfdt_env.h" @@ -76,60 +31,169 @@ static int fdt_nodename_eq_(const void *fdt, int offset, return 0; } +const char *fdt_get_string(const void *fdt, int stroffset, int *lenp) +{ + int32_t totalsize; + uint32_t absoffset; + size_t len; + int err; + const char *s, *n; + + if (can_assume(VALID_INPUT)) { + s = (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset; + + if (lenp) + *lenp = strlen(s); + return s; + } + totalsize = fdt_ro_probe_(fdt); + err = totalsize; + if (totalsize < 0) + goto fail; + + err = -FDT_ERR_BADOFFSET; + absoffset = stroffset + fdt_off_dt_strings(fdt); + if (absoffset >= totalsize) + goto fail; + len = totalsize - absoffset; + + if (fdt_magic(fdt) == FDT_MAGIC) { + if (stroffset < 0) + goto fail; + if (can_assume(LATEST) || fdt_version(fdt) >= 17) { + if (stroffset >= fdt_size_dt_strings(fdt)) + goto fail; + if ((fdt_size_dt_strings(fdt) - stroffset) < len) + len = fdt_size_dt_strings(fdt) - stroffset; + } + } else if (fdt_magic(fdt) == FDT_SW_MAGIC) { + if ((stroffset >= 0) + || (stroffset < -fdt_size_dt_strings(fdt))) + goto fail; + if ((-stroffset) < len) + len = -stroffset; + } else { + err = -FDT_ERR_INTERNAL; + goto fail; + } + + s = (const char *)fdt + absoffset; + n = memchr(s, '\0', len); + if (!n) { + /* missing terminating NULL */ + err = -FDT_ERR_TRUNCATED; + goto fail; + } + + if (lenp) + *lenp = n - s; + return s; + +fail: + if (lenp) + *lenp = err; + return NULL; +} + const char *fdt_string(const void *fdt, int stroffset) { - return (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset; + return fdt_get_string(fdt, stroffset, NULL); } static int fdt_string_eq_(const void *fdt, int stroffset, const char *s, int len) { - const char *p = fdt_string(fdt, stroffset); + int slen; + const char *p = fdt_get_string(fdt, stroffset, &slen); - return (strlen(p) == len) && (memcmp(p, s, len) == 0); + return p && (slen == len) && (memcmp(p, s, len) == 0); } -uint32_t fdt_get_max_phandle(const void *fdt) +int fdt_find_max_phandle(const void *fdt, uint32_t *phandle) { - uint32_t max_phandle = 0; - int offset; + uint32_t max = 0; + int offset = -1; - for (offset = fdt_next_node(fdt, -1, NULL);; - offset = fdt_next_node(fdt, offset, NULL)) { - uint32_t phandle; + while (true) { + uint32_t value; - if (offset == -FDT_ERR_NOTFOUND) - return max_phandle; + offset = fdt_next_node(fdt, offset, NULL); + if (offset < 0) { + if (offset == -FDT_ERR_NOTFOUND) + break; - if (offset < 0) - return (uint32_t)-1; + return offset; + } - phandle = fdt_get_phandle(fdt, offset); - if (phandle == (uint32_t)-1) - continue; + value = fdt_get_phandle(fdt, offset); - if (phandle > max_phandle) - max_phandle = phandle; + if (value > max) + max = value; } + if (phandle) + *phandle = max; + return 0; } +int fdt_generate_phandle(const void *fdt, uint32_t *phandle) +{ + uint32_t max; + int err; + + err = fdt_find_max_phandle(fdt, &max); + if (err < 0) + return err; + + if (max == FDT_MAX_PHANDLE) + return -FDT_ERR_NOPHANDLES; + + if (phandle) + *phandle = max + 1; + + return 0; +} + +static const struct fdt_reserve_entry *fdt_mem_rsv(const void *fdt, int n) +{ + int offset = n * sizeof(struct fdt_reserve_entry); + int absoffset = fdt_off_mem_rsvmap(fdt) + offset; + + if (!can_assume(VALID_INPUT)) { + if (absoffset < fdt_off_mem_rsvmap(fdt)) + return NULL; + if (absoffset > fdt_totalsize(fdt) - + sizeof(struct fdt_reserve_entry)) + return NULL; + } + return fdt_mem_rsv_(fdt, n); +} + int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size) { - FDT_CHECK_HEADER(fdt); - *address = fdt64_to_cpu(fdt_mem_rsv_(fdt, n)->address); - *size = fdt64_to_cpu(fdt_mem_rsv_(fdt, n)->size); + const struct fdt_reserve_entry *re; + + FDT_RO_PROBE(fdt); + re = fdt_mem_rsv(fdt, n); + if (!can_assume(VALID_INPUT) && !re) + return -FDT_ERR_BADOFFSET; + + *address = fdt64_ld(&re->address); + *size = fdt64_ld(&re->size); return 0; } int fdt_num_mem_rsv(const void *fdt) { - int i = 0; + int i; + const struct fdt_reserve_entry *re; - while (fdt64_to_cpu(fdt_mem_rsv_(fdt, i)->size) != 0) - i++; - return i; + for (i = 0; (re = fdt_mem_rsv(fdt, i)) != NULL; i++) { + if (fdt64_ld(&re->size) == 0) + return i; + } + return -FDT_ERR_TRUNCATED; } static int nextprop_(const void *fdt, int offset) @@ -161,7 +225,7 @@ int fdt_subnode_offset_namelen(const void *fdt, int offset, { int depth; - FDT_CHECK_HEADER(fdt); + FDT_RO_PROBE(fdt); for (depth = 0; (offset >= 0) && (depth >= 0); @@ -187,7 +251,7 @@ int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen) const char *p = path; int offset = 0; - FDT_CHECK_HEADER(fdt); + FDT_RO_PROBE(fdt); /* see if we have an alias */ if (*path != '/') { @@ -237,13 +301,13 @@ const char *fdt_get_name(const void *fdt, int nodeoffset, int *len) const char *nameptr; int err; - if (((err = fdt_check_header(fdt)) != 0) + if (((err = fdt_ro_probe_(fdt)) < 0) || ((err = fdt_check_node_offset_(fdt, nodeoffset)) < 0)) goto fail; nameptr = nh->name; - if (fdt_version(fdt) < 0x10) { + if (!can_assume(LATEST) && fdt_version(fdt) < 0x10) { /* * For old FDT versions, match the naming conventions of V16: * give only the leaf name (after all /). The actual tree @@ -294,7 +358,8 @@ static const struct fdt_property *fdt_get_property_by_offset_(const void *fdt, int err; const struct fdt_property *prop; - if ((err = fdt_check_prop_offset_(fdt, offset)) < 0) { + if (!can_assume(VALID_INPUT) && + (err = fdt_check_prop_offset_(fdt, offset)) < 0) { if (lenp) *lenp = err; return NULL; @@ -303,7 +368,7 @@ static const struct fdt_property *fdt_get_property_by_offset_(const void *fdt, prop = fdt_offset_ptr_(fdt, offset); if (lenp) - *lenp = fdt32_to_cpu(prop->len); + *lenp = fdt32_ld(&prop->len); return prop; } @@ -315,7 +380,7 @@ const struct fdt_property *fdt_get_property_by_offset(const void *fdt, /* Prior to version 16, properties may need realignment * and this API does not work. fdt_getprop_*() will, however. */ - if (fdt_version(fdt) < 0x10) { + if (!can_assume(LATEST) && fdt_version(fdt) < 0x10) { if (lenp) *lenp = -FDT_ERR_BADVERSION; return NULL; @@ -336,11 +401,12 @@ static const struct fdt_property *fdt_get_property_namelen_(const void *fdt, (offset = fdt_next_property_offset(fdt, offset))) { const struct fdt_property *prop; - if (!(prop = fdt_get_property_by_offset_(fdt, offset, lenp))) { + prop = fdt_get_property_by_offset_(fdt, offset, lenp); + if (!can_assume(LIBFDT_FLAWLESS) && !prop) { offset = -FDT_ERR_INTERNAL; break; } - if (fdt_string_eq_(fdt, fdt32_to_cpu(prop->nameoff), + if (fdt_string_eq_(fdt, fdt32_ld(&prop->nameoff), name, namelen)) { if (poffset) *poffset = offset; @@ -361,7 +427,7 @@ const struct fdt_property *fdt_get_property_namelen(const void *fdt, { /* Prior to version 16, properties may need realignment * and this API does not work. fdt_getprop_*() will, however. */ - if (fdt_version(fdt) < 0x10) { + if (!can_assume(LATEST) && fdt_version(fdt) < 0x10) { if (lenp) *lenp = -FDT_ERR_BADVERSION; return NULL; @@ -392,8 +458,8 @@ const void *fdt_getprop_namelen(const void *fdt, int nodeoffset, return NULL; /* Handle realignment */ - if (fdt_version(fdt) < 0x10 && (poffset + sizeof(*prop)) % 8 && - fdt32_to_cpu(prop->len) >= 8) + if (!can_assume(LATEST) && fdt_version(fdt) < 0x10 && + (poffset + sizeof(*prop)) % 8 && fdt32_ld(&prop->len) >= 8) return prop->data + 4; return prop->data; } @@ -406,12 +472,27 @@ const void *fdt_getprop_by_offset(const void *fdt, int offset, prop = fdt_get_property_by_offset_(fdt, offset, lenp); if (!prop) return NULL; - if (namep) - *namep = fdt_string(fdt, fdt32_to_cpu(prop->nameoff)); + if (namep) { + const char *name; + int namelen; + + if (!can_assume(VALID_INPUT)) { + name = fdt_get_string(fdt, fdt32_ld(&prop->nameoff), + &namelen); + if (!name) { + if (lenp) + *lenp = namelen; + return NULL; + } + *namep = name; + } else { + *namep = fdt_string(fdt, fdt32_ld(&prop->nameoff)); + } + } /* Handle realignment */ - if (fdt_version(fdt) < 0x10 && (offset + sizeof(*prop)) % 8 && - fdt32_to_cpu(prop->len) >= 8) + if (!can_assume(LATEST) && fdt_version(fdt) < 0x10 && + (offset + sizeof(*prop)) % 8 && fdt32_ld(&prop->len) >= 8) return prop->data + 4; return prop->data; } @@ -436,7 +517,7 @@ uint32_t fdt_get_phandle(const void *fdt, int nodeoffset) return 0; } - return fdt32_to_cpu(*php); + return fdt32_ld(php); } const char *fdt_get_alias_namelen(const void *fdt, @@ -462,7 +543,7 @@ int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen) int offset, depth, namelen; const char *name; - FDT_CHECK_HEADER(fdt); + FDT_RO_PROBE(fdt); if (buflen < 2) return -FDT_ERR_NOSPACE; @@ -514,7 +595,7 @@ int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset, int offset, depth; int supernodeoffset = -FDT_ERR_INTERNAL; - FDT_CHECK_HEADER(fdt); + FDT_RO_PROBE(fdt); if (supernodedepth < 0) return -FDT_ERR_NOTFOUND; @@ -536,10 +617,12 @@ int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset, } } - if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0)) - return -FDT_ERR_BADOFFSET; - else if (offset == -FDT_ERR_BADOFFSET) - return -FDT_ERR_BADSTRUCTURE; + if (!can_assume(VALID_INPUT)) { + if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0)) + return -FDT_ERR_BADOFFSET; + else if (offset == -FDT_ERR_BADOFFSET) + return -FDT_ERR_BADSTRUCTURE; + } return offset; /* error from fdt_next_node() */ } @@ -551,7 +634,8 @@ int fdt_node_depth(const void *fdt, int nodeoffset) err = fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, &nodedepth); if (err) - return (err < 0) ? err : -FDT_ERR_INTERNAL; + return (can_assume(LIBFDT_FLAWLESS) || err < 0) ? err : + -FDT_ERR_INTERNAL; return nodedepth; } @@ -573,7 +657,7 @@ int fdt_node_offset_by_prop_value(const void *fdt, int startoffset, const void *val; int len; - FDT_CHECK_HEADER(fdt); + FDT_RO_PROBE(fdt); /* FIXME: The algorithm here is pretty horrible: we scan each * property of a node in fdt_getprop(), then if that didn't @@ -599,7 +683,7 @@ int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle) if ((phandle == 0) || (phandle == -1)) return -FDT_ERR_BADPHANDLE; - FDT_CHECK_HEADER(fdt); + FDT_RO_PROBE(fdt); /* FIXME: The algorithm here is pretty horrible: we * potentially scan each property of a node in @@ -752,7 +836,7 @@ int fdt_node_offset_by_compatible(const void *fdt, int startoffset, { int offset, err; - FDT_CHECK_HEADER(fdt); + FDT_RO_PROBE(fdt); /* FIXME: The algorithm here is pretty horrible: we scan each * property of a node in fdt_node_check_compatible(), then if diff --git a/lib/libfdt/fdt_rw.c b/lib/libfdt/fdt_rw.c index 9b829051e..93e4a2b56 100644 --- a/lib/libfdt/fdt_rw.c +++ b/lib/libfdt/fdt_rw.c @@ -1,52 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2006 David Gibson, IBM Corporation. - * - * libfdt is dual licensed: you can use it either under the terms of - * the GPL, or the BSD license, at your option. - * - * a) This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * Alternatively, - * - * b) Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "libfdt_env.h" @@ -67,29 +22,31 @@ static int fdt_blocks_misordered_(const void *fdt, (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt))); } -static int fdt_rw_check_header_(void *fdt) +static int fdt_rw_probe_(void *fdt) { - FDT_CHECK_HEADER(fdt); + if (can_assume(VALID_DTB)) + return 0; + FDT_RO_PROBE(fdt); - if (fdt_version(fdt) < 17) + if (!can_assume(LATEST) && fdt_version(fdt) < 17) return -FDT_ERR_BADVERSION; if (fdt_blocks_misordered_(fdt, sizeof(struct fdt_reserve_entry), fdt_size_dt_struct(fdt))) return -FDT_ERR_BADLAYOUT; - if (fdt_version(fdt) > 17) + if (!can_assume(LATEST) && fdt_version(fdt) > 17) fdt_set_version(fdt, 17); return 0; } -#define FDT_RW_CHECK_HEADER(fdt) \ +#define FDT_RW_PROBE(fdt) \ { \ int err_; \ - if ((err_ = fdt_rw_check_header_(fdt)) != 0) \ + if ((err_ = fdt_rw_probe_(fdt)) != 0) \ return err_; \ } -static inline int fdt_data_size_(void *fdt) +static inline unsigned int fdt_data_size_(void *fdt) { return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt); } @@ -97,15 +54,16 @@ static inline int fdt_data_size_(void *fdt) static int fdt_splice_(void *fdt, void *splicepoint, int oldlen, int newlen) { char *p = splicepoint; - char *end = (char *)fdt + fdt_data_size_(fdt); + unsigned int dsize = fdt_data_size_(fdt); + size_t soff = p - (char *)fdt; - if (((p + oldlen) < p) || ((p + oldlen) > end)) + if ((oldlen < 0) || (soff + oldlen < soff) || (soff + oldlen > dsize)) return -FDT_ERR_BADOFFSET; - if ((p < (char *)fdt) || ((end - oldlen + newlen) < (char *)fdt)) + if ((p < (char *)fdt) || (dsize + newlen < oldlen)) return -FDT_ERR_BADOFFSET; - if ((end - oldlen + newlen) > ((char *)fdt + fdt_totalsize(fdt))) + if (dsize - oldlen + newlen > fdt_totalsize(fdt)) return -FDT_ERR_NOSPACE; - memmove(p + newlen, p + oldlen, end - p - oldlen); + memmove(p + newlen, p + oldlen, ((char *)fdt + dsize) - (p + oldlen)); return 0; } @@ -136,6 +94,14 @@ static int fdt_splice_struct_(void *fdt, void *p, return 0; } +/* Must only be used to roll back in case of error */ +static void fdt_del_last_string_(void *fdt, const char *s) +{ + int newlen = strlen(s) + 1; + + fdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) - newlen); +} + static int fdt_splice_string_(void *fdt, int newlen) { void *p = (char *)fdt @@ -149,7 +115,16 @@ static int fdt_splice_string_(void *fdt, int newlen) return 0; } -static int fdt_find_add_string_(void *fdt, const char *s) +/** + * fdt_find_add_string_() - Find or allocate a string + * + * @fdt: pointer to the device tree to check/adjust + * @s: string to find/add + * @allocated: Set to 0 if the string was found, 1 if not found and so + * allocated. Ignored if can_assume(NO_ROLLBACK) + * @return offset of string in the string table (whether found or added) + */ +static int fdt_find_add_string_(void *fdt, const char *s, int *allocated) { char *strtab = (char *)fdt + fdt_off_dt_strings(fdt); const char *p; @@ -157,6 +132,9 @@ static int fdt_find_add_string_(void *fdt, const char *s) int len = strlen(s) + 1; int err; + if (!can_assume(NO_ROLLBACK)) + *allocated = 0; + p = fdt_find_string_(strtab, fdt_size_dt_strings(fdt), s); if (p) /* found it */ @@ -167,6 +145,9 @@ static int fdt_find_add_string_(void *fdt, const char *s) if (err) return err; + if (!can_assume(NO_ROLLBACK)) + *allocated = 1; + memcpy(new, s, len); return (new - strtab); } @@ -176,7 +157,7 @@ int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size) struct fdt_reserve_entry *re; int err; - FDT_RW_CHECK_HEADER(fdt); + FDT_RW_PROBE(fdt); re = fdt_mem_rsv_w_(fdt, fdt_num_mem_rsv(fdt)); err = fdt_splice_mem_rsv_(fdt, re, 0, 1); @@ -192,7 +173,7 @@ int fdt_del_mem_rsv(void *fdt, int n) { struct fdt_reserve_entry *re = fdt_mem_rsv_w_(fdt, n); - FDT_RW_CHECK_HEADER(fdt); + FDT_RW_PROBE(fdt); if (n >= fdt_num_mem_rsv(fdt)) return -FDT_ERR_NOTFOUND; @@ -225,11 +206,12 @@ static int fdt_add_property_(void *fdt, int nodeoffset, const char *name, int nextoffset; int namestroff; int err; + int allocated; if ((nextoffset = fdt_check_node_offset_(fdt, nodeoffset)) < 0) return nextoffset; - namestroff = fdt_find_add_string_(fdt, name); + namestroff = fdt_find_add_string_(fdt, name, &allocated); if (namestroff < 0) return namestroff; @@ -237,8 +219,12 @@ static int fdt_add_property_(void *fdt, int nodeoffset, const char *name, proplen = sizeof(**prop) + FDT_TAGALIGN(len); err = fdt_splice_struct_(fdt, *prop, 0, proplen); - if (err) + if (err) { + /* Delete the string if we failed to add it */ + if (!can_assume(NO_ROLLBACK) && allocated) + fdt_del_last_string_(fdt, name); return err; + } (*prop)->tag = cpu_to_fdt32(FDT_PROP); (*prop)->nameoff = cpu_to_fdt32(namestroff); @@ -252,7 +238,7 @@ int fdt_set_name(void *fdt, int nodeoffset, const char *name) int oldlen, newlen; int err; - FDT_RW_CHECK_HEADER(fdt); + FDT_RW_PROBE(fdt); namep = (char *)(uintptr_t)fdt_get_name(fdt, nodeoffset, &oldlen); if (!namep) @@ -275,7 +261,7 @@ int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name, struct fdt_property *prop; int err; - FDT_RW_CHECK_HEADER(fdt); + FDT_RW_PROBE(fdt); err = fdt_resize_property_(fdt, nodeoffset, name, len, &prop); if (err == -FDT_ERR_NOTFOUND) @@ -308,7 +294,7 @@ int fdt_appendprop(void *fdt, int nodeoffset, const char *name, struct fdt_property *prop; int err, oldlen, newlen; - FDT_RW_CHECK_HEADER(fdt); + FDT_RW_PROBE(fdt); prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen); if (prop) { @@ -334,7 +320,7 @@ int fdt_delprop(void *fdt, int nodeoffset, const char *name) struct fdt_property *prop; int len, proplen; - FDT_RW_CHECK_HEADER(fdt); + FDT_RW_PROBE(fdt); prop = fdt_get_property_w(fdt, nodeoffset, name, &len); if (!prop) @@ -354,7 +340,7 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset, uint32_t tag; fdt32_t *endtag; - FDT_RW_CHECK_HEADER(fdt); + FDT_RW_PROBE(fdt); offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen); if (offset >= 0) @@ -394,7 +380,7 @@ int fdt_del_node(void *fdt, int nodeoffset) { int endoffset; - FDT_RW_CHECK_HEADER(fdt); + FDT_RW_PROBE(fdt); endoffset = fdt_node_end_offset_(fdt, nodeoffset); if (endoffset < 0) @@ -435,12 +421,12 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize) const char *fdtend = fdtstart + fdt_totalsize(fdt); char *tmp; - FDT_CHECK_HEADER(fdt); + FDT_RO_PROBE(fdt); mem_rsv_size = (fdt_num_mem_rsv(fdt)+1) * sizeof(struct fdt_reserve_entry); - if (fdt_version(fdt) >= 17) { + if (can_assume(LATEST) || fdt_version(fdt) >= 17) { struct_size = fdt_size_dt_struct(fdt); } else { struct_size = 0; @@ -450,7 +436,8 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize) return struct_size; } - if (!fdt_blocks_misordered_(fdt, mem_rsv_size, struct_size)) { + if (can_assume(LIBFDT_ORDER) || + !fdt_blocks_misordered_(fdt, mem_rsv_size, struct_size)) { /* no further work necessary */ err = fdt_move(fdt, buf, bufsize); if (err) @@ -494,7 +481,7 @@ int fdt_pack(void *fdt) { int mem_rsv_size; - FDT_RW_CHECK_HEADER(fdt); + FDT_RW_PROBE(fdt); mem_rsv_size = (fdt_num_mem_rsv(fdt)+1) * sizeof(struct fdt_reserve_entry); diff --git a/lib/libfdt/fdt_strerror.c b/lib/libfdt/fdt_strerror.c index 9677a1887..768db66ea 100644 --- a/lib/libfdt/fdt_strerror.c +++ b/lib/libfdt/fdt_strerror.c @@ -1,51 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2006 David Gibson, IBM Corporation. - * - * libfdt is dual licensed: you can use it either under the terms of - * the GPL, or the BSD license, at your option. - * - * a) This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * Alternatively, - * - * b) Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "libfdt_env.h" @@ -82,6 +38,7 @@ static struct fdt_errtabent fdt_errtable[] = { FDT_ERRTABENT(FDT_ERR_BADVALUE), FDT_ERRTABENT(FDT_ERR_BADOVERLAY), FDT_ERRTABENT(FDT_ERR_NOPHANDLES), + FDT_ERRTABENT(FDT_ERR_BADFLAGS), }; #define FDT_ERRTABSIZE (sizeof(fdt_errtable) / sizeof(fdt_errtable[0])) diff --git a/lib/libfdt/fdt_sw.c b/lib/libfdt/fdt_sw.c index 6d33cc29d..26759d5df 100644 --- a/lib/libfdt/fdt_sw.c +++ b/lib/libfdt/fdt_sw.c @@ -1,52 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2006 David Gibson, IBM Corporation. - * - * libfdt is dual licensed: you can use it either under the terms of - * the GPL, or the BSD license, at your option. - * - * a) This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * Alternatively, - * - * b) Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "libfdt_env.h" @@ -55,21 +10,87 @@ #include "libfdt_internal.h" -static int fdt_sw_check_header_(void *fdt) +static int fdt_sw_probe_(void *fdt) { - if (fdt_magic(fdt) != FDT_SW_MAGIC) - return -FDT_ERR_BADMAGIC; - /* FIXME: should check more details about the header state */ + if (!can_assume(VALID_INPUT)) { + if (fdt_magic(fdt) == FDT_MAGIC) + return -FDT_ERR_BADSTATE; + else if (fdt_magic(fdt) != FDT_SW_MAGIC) + return -FDT_ERR_BADMAGIC; + } + return 0; } -#define FDT_SW_CHECK_HEADER(fdt) \ +#define FDT_SW_PROBE(fdt) \ { \ int err; \ - if ((err = fdt_sw_check_header_(fdt)) != 0) \ + if ((err = fdt_sw_probe_(fdt)) != 0) \ return err; \ } +/* 'memrsv' state: Initial state after fdt_create() + * + * Allowed functions: + * fdt_add_reservmap_entry() + * fdt_finish_reservemap() [moves to 'struct' state] + */ +static int fdt_sw_probe_memrsv_(void *fdt) +{ + int err = fdt_sw_probe_(fdt); + if (err) + return err; + + if (!can_assume(VALID_INPUT) && fdt_off_dt_strings(fdt) != 0) + return -FDT_ERR_BADSTATE; + return 0; +} + +#define FDT_SW_PROBE_MEMRSV(fdt) \ + { \ + int err; \ + if ((err = fdt_sw_probe_memrsv_(fdt)) != 0) \ + return err; \ + } + +/* 'struct' state: Enter this state after fdt_finish_reservemap() + * + * Allowed functions: + * fdt_begin_node() + * fdt_end_node() + * fdt_property*() + * fdt_finish() [moves to 'complete' state] + */ +static int fdt_sw_probe_struct_(void *fdt) +{ + int err = fdt_sw_probe_(fdt); + if (err) + return err; + + if (!can_assume(VALID_INPUT) && + fdt_off_dt_strings(fdt) != fdt_totalsize(fdt)) + return -FDT_ERR_BADSTATE; + return 0; +} + +#define FDT_SW_PROBE_STRUCT(fdt) \ + { \ + int err; \ + if ((err = fdt_sw_probe_struct_(fdt)) != 0) \ + return err; \ + } + +static inline uint32_t sw_flags(void *fdt) +{ + /* assert: (fdt_magic(fdt) == FDT_SW_MAGIC) */ + return fdt_last_comp_version(fdt); +} + +/* 'complete' state: Enter this state after fdt_finish() + * + * Allowed functions: none + */ + static void *fdt_grab_space_(void *fdt, size_t len) { int offset = fdt_size_dt_struct(fdt); @@ -85,38 +106,59 @@ static void *fdt_grab_space_(void *fdt, size_t len) return fdt_offset_ptr_w_(fdt, offset); } -int fdt_create(void *buf, int bufsize) +int fdt_create_with_flags(void *buf, int bufsize, uint32_t flags) { + const size_t hdrsize = FDT_ALIGN(sizeof(struct fdt_header), + sizeof(struct fdt_reserve_entry)); void *fdt = buf; - if (bufsize < sizeof(struct fdt_header)) + if (bufsize < hdrsize) return -FDT_ERR_NOSPACE; + if (flags & ~FDT_CREATE_FLAGS_ALL) + return -FDT_ERR_BADFLAGS; + memset(buf, 0, bufsize); + /* + * magic and last_comp_version keep intermediate state during the fdt + * creation process, which is replaced with the proper FDT format by + * fdt_finish(). + * + * flags should be accessed with sw_flags(). + */ fdt_set_magic(fdt, FDT_SW_MAGIC); fdt_set_version(fdt, FDT_LAST_SUPPORTED_VERSION); - fdt_set_last_comp_version(fdt, FDT_FIRST_SUPPORTED_VERSION); + fdt_set_last_comp_version(fdt, flags); + fdt_set_totalsize(fdt, bufsize); - fdt_set_off_mem_rsvmap(fdt, FDT_ALIGN(sizeof(struct fdt_header), - sizeof(struct fdt_reserve_entry))); + fdt_set_off_mem_rsvmap(fdt, hdrsize); fdt_set_off_dt_struct(fdt, fdt_off_mem_rsvmap(fdt)); - fdt_set_off_dt_strings(fdt, bufsize); + fdt_set_off_dt_strings(fdt, 0); return 0; } +int fdt_create(void *buf, int bufsize) +{ + return fdt_create_with_flags(buf, bufsize, 0); +} + int fdt_resize(void *fdt, void *buf, int bufsize) { size_t headsize, tailsize; char *oldtail, *newtail; - FDT_SW_CHECK_HEADER(fdt); + FDT_SW_PROBE(fdt); - headsize = fdt_off_dt_struct(fdt); + headsize = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt); tailsize = fdt_size_dt_strings(fdt); + if (!can_assume(VALID_DTB) && + headsize + tailsize > fdt_totalsize(fdt)) + return -FDT_ERR_INTERNAL; + if ((headsize + tailsize) > bufsize) return -FDT_ERR_NOSPACE; @@ -133,8 +175,9 @@ int fdt_resize(void *fdt, void *buf, int bufsize) memmove(buf, fdt, headsize); } - fdt_set_off_dt_strings(buf, bufsize); fdt_set_totalsize(buf, bufsize); + if (fdt_off_dt_strings(buf)) + fdt_set_off_dt_strings(buf, bufsize); return 0; } @@ -144,10 +187,7 @@ int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size) struct fdt_reserve_entry *re; int offset; - FDT_SW_CHECK_HEADER(fdt); - - if (fdt_size_dt_struct(fdt)) - return -FDT_ERR_BADSTATE; + FDT_SW_PROBE_MEMRSV(fdt); offset = fdt_off_dt_struct(fdt); if ((offset + sizeof(*re)) > fdt_totalsize(fdt)) @@ -164,16 +204,23 @@ int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size) int fdt_finish_reservemap(void *fdt) { - return fdt_add_reservemap_entry(fdt, 0, 0); + int err = fdt_add_reservemap_entry(fdt, 0, 0); + + if (err) + return err; + + fdt_set_off_dt_strings(fdt, fdt_totalsize(fdt)); + return 0; } int fdt_begin_node(void *fdt, const char *name) { struct fdt_node_header *nh; - int namelen = strlen(name) + 1; + int namelen; - FDT_SW_CHECK_HEADER(fdt); + FDT_SW_PROBE_STRUCT(fdt); + namelen = strlen(name) + 1; nh = fdt_grab_space_(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen)); if (! nh) return -FDT_ERR_NOSPACE; @@ -187,7 +234,7 @@ int fdt_end_node(void *fdt) { fdt32_t *en; - FDT_SW_CHECK_HEADER(fdt); + FDT_SW_PROBE_STRUCT(fdt); en = fdt_grab_space_(fdt, FDT_TAGSIZE); if (! en) @@ -197,19 +244,13 @@ int fdt_end_node(void *fdt) return 0; } -static int fdt_find_add_string_(void *fdt, const char *s) +static int fdt_add_string_(void *fdt, const char *s) { char *strtab = (char *)fdt + fdt_totalsize(fdt); - const char *p; int strtabsize = fdt_size_dt_strings(fdt); int len = strlen(s) + 1; int struct_top, offset; - p = fdt_find_string_(strtab - strtabsize, strtabsize, s); - if (p) - return p - strtab; - - /* Add it */ offset = -strtabsize - len; struct_top = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt); if (fdt_totalsize(fdt) + offset < struct_top) @@ -220,20 +261,56 @@ static int fdt_find_add_string_(void *fdt, const char *s) return offset; } +/* Must only be used to roll back in case of error */ +static void fdt_del_last_string_(void *fdt, const char *s) +{ + int strtabsize = fdt_size_dt_strings(fdt); + int len = strlen(s) + 1; + + fdt_set_size_dt_strings(fdt, strtabsize - len); +} + +static int fdt_find_add_string_(void *fdt, const char *s, int *allocated) +{ + char *strtab = (char *)fdt + fdt_totalsize(fdt); + int strtabsize = fdt_size_dt_strings(fdt); + const char *p; + + *allocated = 0; + + p = fdt_find_string_(strtab - strtabsize, strtabsize, s); + if (p) + return p - strtab; + + *allocated = 1; + + return fdt_add_string_(fdt, s); +} + int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp) { struct fdt_property *prop; int nameoff; + int allocated; - FDT_SW_CHECK_HEADER(fdt); + FDT_SW_PROBE_STRUCT(fdt); - nameoff = fdt_find_add_string_(fdt, name); + /* String de-duplication can be slow, _NO_NAME_DEDUP skips it */ + if (sw_flags(fdt) & FDT_CREATE_FLAG_NO_NAME_DEDUP) { + allocated = 1; + nameoff = fdt_add_string_(fdt, name); + } else { + nameoff = fdt_find_add_string_(fdt, name, &allocated); + } if (nameoff == 0) return -FDT_ERR_NOSPACE; prop = fdt_grab_space_(fdt, sizeof(*prop) + FDT_TAGALIGN(len)); - if (! prop) + if (! prop) { + if (allocated) + fdt_del_last_string_(fdt, name); return -FDT_ERR_NOSPACE; + } prop->tag = cpu_to_fdt32(FDT_PROP); prop->nameoff = cpu_to_fdt32(nameoff); @@ -262,7 +339,7 @@ int fdt_finish(void *fdt) uint32_t tag; int offset, nextoffset; - FDT_SW_CHECK_HEADER(fdt); + FDT_SW_PROBE_STRUCT(fdt); /* Add terminator */ end = fdt_grab_space_(fdt, sizeof(*end)); @@ -295,6 +372,10 @@ int fdt_finish(void *fdt) /* Finally, adjust the header */ fdt_set_totalsize(fdt, newstroffset + fdt_size_dt_strings(fdt)); + + /* And fix up fields that were keeping intermediate state. */ + fdt_set_last_comp_version(fdt, FDT_FIRST_SUPPORTED_VERSION); fdt_set_magic(fdt, FDT_MAGIC); + return 0; } diff --git a/lib/libfdt/fdt_wip.c b/lib/libfdt/fdt_wip.c index 534c1cbbb..f64139e0b 100644 --- a/lib/libfdt/fdt_wip.c +++ b/lib/libfdt/fdt_wip.c @@ -1,52 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2006 David Gibson, IBM Corporation. - * - * libfdt is dual licensed: you can use it either under the terms of - * the GPL, or the BSD license, at your option. - * - * a) This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * Alternatively, - * - * b) Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "libfdt_env.h" diff --git a/lib/libfdt/libfdt_internal.h b/lib/libfdt/libfdt_internal.h index 7681e1922..d4e0bd49c 100644 --- a/lib/libfdt/libfdt_internal.h +++ b/lib/libfdt/libfdt_internal.h @@ -1,65 +1,21 @@ +/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */ #ifndef LIBFDT_INTERNAL_H #define LIBFDT_INTERNAL_H /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2006 David Gibson, IBM Corporation. - * - * libfdt is dual licensed: you can use it either under the terms of - * the GPL, or the BSD license, at your option. - * - * a) This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * Alternatively, - * - * b) Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #define FDT_ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) #define FDT_TAGALIGN(x) (FDT_ALIGN((x), FDT_TAGSIZE)) -#define FDT_CHECK_HEADER(fdt) \ - { \ - int err_; \ - if ((err_ = fdt_check_header(fdt)) != 0) \ - return err_; \ +int32_t fdt_ro_probe_(const void *fdt); +#define FDT_RO_PROBE(fdt) \ + { \ + int32_t totalsize_; \ + if ((totalsize_ = fdt_ro_probe_(fdt)) < 0) \ + return totalsize_; \ } int fdt_check_node_offset_(const void *fdt, int offset); @@ -92,4 +48,126 @@ static inline struct fdt_reserve_entry *fdt_mem_rsv_w_(void *fdt, int n) #define FDT_SW_MAGIC (~FDT_MAGIC) +/**********************************************************************/ +/* Checking controls */ +/**********************************************************************/ + +#ifndef FDT_ASSUME_MASK +#define FDT_ASSUME_MASK 0 +#endif + +/* + * Defines assumptions which can be enabled. Each of these can be enabled + * individually. For maximum safety, don't enable any assumptions! + * + * For minimal code size and no safety, use ASSUME_PERFECT at your own risk. + * You should have another method of validating the device tree, such as a + * signature or hash check before using libfdt. + * + * For situations where security is not a concern it may be safe to enable + * ASSUME_SANE. + */ +enum { + /* + * This does essentially no checks. Only the latest device-tree + * version is correctly handled. Inconsistencies or errors in the device + * tree may cause undefined behaviour or crashes. Invalid parameters + * passed to libfdt may do the same. + * + * If an error occurs when modifying the tree it may leave the tree in + * an intermediate (but valid) state. As an example, adding a property + * where there is insufficient space may result in the property name + * being added to the string table even though the property itself is + * not added to the struct section. + * + * Only use this if you have a fully validated device tree with + * the latest supported version and wish to minimise code size. + */ + ASSUME_PERFECT = 0xff, + + /* + * This assumes that the device tree is sane. i.e. header metadata + * and basic hierarchy are correct. + * + * With this assumption enabled, normal device trees produced by libfdt + * and the compiler should be handled safely. Malicious device trees and + * complete garbage may cause libfdt to behave badly or crash. Truncated + * device trees (e.g. those only partially loaded) can also cause + * problems. + * + * Note: Only checks that relate exclusively to the device tree itself + * (not the parameters passed to libfdt) are disabled by this + * assumption. This includes checking headers, tags and the like. + */ + ASSUME_VALID_DTB = 1 << 0, + + /* + * This builds on ASSUME_VALID_DTB and further assumes that libfdt + * functions are called with valid parameters, i.e. not trigger + * FDT_ERR_BADOFFSET or offsets that are out of bounds. It disables any + * extensive checking of parameters and the device tree, making various + * assumptions about correctness. + * + * It doesn't make sense to enable this assumption unless + * ASSUME_VALID_DTB is also enabled. + */ + ASSUME_VALID_INPUT = 1 << 1, + + /* + * This disables checks for device-tree version and removes all code + * which handles older versions. + * + * Only enable this if you know you have a device tree with the latest + * version. + */ + ASSUME_LATEST = 1 << 2, + + /* + * This assumes that it is OK for a failed addition to the device tree, + * due to lack of space or some other problem, to skip any rollback + * steps (such as dropping the property name from the string table). + * This is safe to enable in most circumstances, even though it may + * leave the tree in a sub-optimal state. + */ + ASSUME_NO_ROLLBACK = 1 << 3, + + /* + * This assumes that the device tree components appear in a 'convenient' + * order, i.e. the memory reservation block first, then the structure + * block and finally the string block. + * + * This order is not specified by the device-tree specification, + * but is expected by libfdt. The device-tree compiler always created + * device trees with this order. + * + * This assumption disables a check in fdt_open_into() and removes the + * ability to fix the problem there. This is safe if you know that the + * device tree is correctly ordered. See fdt_blocks_misordered_(). + */ + ASSUME_LIBFDT_ORDER = 1 << 4, + + /* + * This assumes that libfdt itself does not have any internal bugs. It + * drops certain checks that should never be needed unless libfdt has an + * undiscovered bug. + * + * This can generally be considered safe to enable. + */ + ASSUME_LIBFDT_FLAWLESS = 1 << 5, +}; + +/** + * can_assume_() - check if a particular assumption is enabled + * + * @mask: Mask to check (ASSUME_...) + * @return true if that assumption is enabled, else false + */ +static inline bool can_assume_(int mask) +{ + return FDT_ASSUME_MASK & mask; +} + +/** helper macros for checking assumptions */ +#define can_assume(_assume) can_assume_(ASSUME_ ## _assume) + #endif /* LIBFDT_INTERNAL_H */ diff --git a/plat/arm/board/juno/jmptbl.i b/plat/arm/board/juno/jmptbl.i index 20ed2c73c..393a64816 100644 --- a/plat/arm/board/juno/jmptbl.i +++ b/plat/arm/board/juno/jmptbl.i @@ -29,6 +29,8 @@ fdt fdt_stringlist_search fdt fdt_get_alias_namelen fdt fdt_path_offset fdt fdt_path_offset_namelen +fdt fdt_address_cells +fdt fdt_size_cells fdt fdt_get_name fdt fdt_get_alias fdt fdt_node_offset_by_phandle -- cgit v1.2.3 From e8ad6168b0153e09f1a54ee887555db7833019df Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 22 Apr 2020 11:27:55 +0900 Subject: linker_script: move .rela.dyn section to bl_common.ld.h The .rela.dyn section is the same for BL2-AT-EL3, BL31, TSP. Move it to the common header file. I slightly changed the definition so that we can do "RELA_SECTION >RAM". It still produced equivalent elf images. Please note I got rid of '.' from the VMA field. Otherwise, if the end of previous .data section is not 8-byte aligned, it fails to link. aarch64-linux-gnu-ld.bfd: warning: changing start of section .rela.dyn by 4 bytes aarch64-linux-gnu-ld.bfd: warning: changing start of section .rela.dyn by 4 bytes aarch64-linux-gnu-ld.bfd: warning: changing start of section .rela.dyn by 4 bytes make: *** [Makefile:1071: build/qemu/release/bl31/bl31.elf] Error 1 Change-Id: Iba7422d99c0374d4d9e97e6fd47bae129dba5cc9 Signed-off-by: Masahiro Yamada --- bl2/bl2_el3.ld.S | 12 +----------- bl31/bl31.ld.S | 12 +----------- bl32/tsp/tsp.ld.S | 12 +----------- include/common/bl_common.ld.h | 11 +++++++++++ 4 files changed, 14 insertions(+), 33 deletions(-) diff --git a/bl2/bl2_el3.ld.S b/bl2/bl2_el3.ld.S index 8c45d9898..bc1794c06 100644 --- a/bl2/bl2_el3.ld.S +++ b/bl2/bl2_el3.ld.S @@ -105,17 +105,7 @@ SECTIONS __DATA_RAM_START__ = __DATA_START__; __DATA_RAM_END__ = __DATA_END__; - /* - * .rela.dyn needs to come after .data for the read-elf utility to parse - * this section correctly. Ensure 8-byte alignment so that the fields of - * RELA data structure are aligned. - */ - . = ALIGN(8); - __RELA_START__ = .; - .rela.dyn . : { - } >RAM - __RELA_END__ = .; - + RELA_SECTION >RAM STACK_SECTION >RAM BSS_SECTION >RAM XLAT_TABLE_SECTION >RAM diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S index 11e86a3c1..502650097 100644 --- a/bl31/bl31.ld.S +++ b/bl31/bl31.ld.S @@ -115,17 +115,7 @@ SECTIONS __RW_START__ = . ; DATA_SECTION >RAM - - /* - * .rela.dyn needs to come after .data for the read-elf utility to parse - * this section correctly. Ensure 8-byte alignment so that the fields of - * RELA data structure are aligned. - */ - . = ALIGN(8); - __RELA_START__ = .; - .rela.dyn . : { - } >RAM - __RELA_END__ = .; + RELA_SECTION >RAM #ifdef BL31_PROGBITS_LIMIT ASSERT(. <= BL31_PROGBITS_LIMIT, "BL31 progbits has exceeded its limit.") diff --git a/bl32/tsp/tsp.ld.S b/bl32/tsp/tsp.ld.S index bdcd2cf70..d86ae5587 100644 --- a/bl32/tsp/tsp.ld.S +++ b/bl32/tsp/tsp.ld.S @@ -71,17 +71,7 @@ SECTIONS __RW_START__ = . ; DATA_SECTION >RAM - - /* - * .rela.dyn needs to come after .data for the read-elf utility to parse - * this section correctly. Ensure 8-byte alignment so that the fields of - * RELA data structure are aligned. - */ - . = ALIGN(8); - __RELA_START__ = .; - .rela.dyn . : { - } >RAM - __RELA_END__ = .; + RELA_SECTION >RAM #ifdef TSP_PROGBITS_LIMIT ASSERT(. <= TSP_PROGBITS_LIMIT, "TSP progbits has exceeded its limit.") diff --git a/include/common/bl_common.ld.h b/include/common/bl_common.ld.h index 208e3d681..ab3391aa2 100644 --- a/include/common/bl_common.ld.h +++ b/include/common/bl_common.ld.h @@ -101,6 +101,17 @@ __DATA_END__ = .; \ } +/* + * .rela.dyn needs to come after .data for the read-elf utility to parse + * this section correctly. + */ +#define RELA_SECTION \ + .rela.dyn : ALIGN(STRUCT_ALIGN) { \ + __RELA_START__ = .; \ + *(.rela*) \ + __RELA_END__ = .; \ + } + #if !(defined(IMAGE_BL31) && RECLAIM_INIT_CODE) #define STACK_SECTION \ stacks (NOLOAD) : { \ -- cgit v1.2.3 From 39784f2af5a51e9fb387c331b6faa2cb6ee41ad1 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 5 Jun 2020 10:29:17 +0900 Subject: uniphier: increase BL33 max size and GZIP temporary buffer size The current BL33 size is large enough for U-Boot, but we need to increase the limit to use other boot loaders such as edk2. Increase the buffer size used for GZIP decompression too. BL33 max size (UNIPHIER_BL33_MAX_SIZE): 1MB -> 8MB GZIP buffer (UNIPHIER_IMAGE_BUF_SIZE): 1MB -> 8MB Increasing the block buffer size (UNIPHIER_BLOCK_BUF_SIZE) is not required, but I increased it too to make it work more efficiently. Change-Id: I4fa6d795bed9ab9ada7f8f616c7d47076139e3a8 Signed-off-by: Masahiro Yamada --- plat/socionext/uniphier/uniphier_bl2_setup.c | 4 ++-- plat/socionext/uniphier/uniphier_image_desc.c | 4 ++-- plat/socionext/uniphier/uniphier_io_storage.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/plat/socionext/uniphier/uniphier_bl2_setup.c b/plat/socionext/uniphier/uniphier_bl2_setup.c index 679f14d0a..4524610c0 100644 --- a/plat/socionext/uniphier/uniphier_bl2_setup.c +++ b/plat/socionext/uniphier/uniphier_bl2_setup.c @@ -21,8 +21,8 @@ #include "uniphier.h" -#define UNIPHIER_IMAGE_BUF_OFFSET 0x04300000UL -#define UNIPHIER_IMAGE_BUF_SIZE 0x00100000UL +#define UNIPHIER_IMAGE_BUF_OFFSET 0x03800000UL +#define UNIPHIER_IMAGE_BUF_SIZE 0x00800000UL static uintptr_t uniphier_mem_base = UNIPHIER_MEM_BASE; static unsigned int uniphier_soc = UNIPHIER_SOC_UNKNOWN; diff --git a/plat/socionext/uniphier/uniphier_image_desc.c b/plat/socionext/uniphier/uniphier_image_desc.c index 8c232ba31..dd62d1ebb 100644 --- a/plat/socionext/uniphier/uniphier_image_desc.c +++ b/plat/socionext/uniphier/uniphier_image_desc.c @@ -14,9 +14,9 @@ #include "uniphier.h" #define UNIPHIER_BL33_OFFSET 0x04000000UL -#define UNIPHIER_BL33_MAX_SIZE 0x00100000UL +#define UNIPHIER_BL33_MAX_SIZE 0x00800000UL -#define UNIPHIER_SCP_OFFSET 0x04100000UL +#define UNIPHIER_SCP_OFFSET 0x04800000UL #define UNIPHIER_SCP_MAX_SIZE 0x00020000UL static struct bl_mem_params_node uniphier_image_descs[] = { diff --git a/plat/socionext/uniphier/uniphier_io_storage.c b/plat/socionext/uniphier/uniphier_io_storage.c index 77d1eaf00..92e15b09a 100644 --- a/plat/socionext/uniphier/uniphier_io_storage.c +++ b/plat/socionext/uniphier/uniphier_io_storage.c @@ -25,8 +25,8 @@ #define UNIPHIER_OCM_REGION_SIZE 0x00040000ULL -#define UNIPHIER_BLOCK_BUF_OFFSET 0x04200000UL -#define UNIPHIER_BLOCK_BUF_SIZE 0x00100000UL +#define UNIPHIER_BLOCK_BUF_OFFSET 0x03000000UL +#define UNIPHIER_BLOCK_BUF_SIZE 0x00800000UL static const io_dev_connector_t *uniphier_fip_dev_con; static uintptr_t uniphier_fip_dev_handle; -- cgit v1.2.3 From 506ffe50dedf53882b5c0ba9f82cd4f448e94d4f Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sun, 29 Dec 2019 16:12:12 -0600 Subject: allwinner: Disable NS access to PRCM power control registers The non-secure world has no business accessing the CPU power switches in the PRCM; those are handled by TF-A or the SCP. Only allow access to the clock control part of the PRCM. Signed-off-by: Samuel Holland Change-Id: I657b97f4ea8a0073448ad3343fbc66ba168ed89e --- plat/allwinner/common/sunxi_security.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plat/allwinner/common/sunxi_security.c b/plat/allwinner/common/sunxi_security.c index 1f16a0b72..92c83b06e 100644 --- a/plat/allwinner/common/sunxi_security.c +++ b/plat/allwinner/common/sunxi_security.c @@ -39,8 +39,8 @@ void sunxi_security_setup(void) /* set MBUS clocks, bus clocks (AXI/AHB/APB) and PLLs to non-secure */ mmio_write_32(SUNXI_CCU_SEC_SWITCH_REG, 0x7); - /* set R_PRCM clocks to non-secure */ - mmio_write_32(SUNXI_R_PRCM_BASE + R_PRCM_SEC_SWITCH_REG, 0x7); + /* Set R_PRCM bus clocks to non-secure */ + mmio_write_32(SUNXI_R_PRCM_BASE + R_PRCM_SEC_SWITCH_REG, 0x1); /* Set all DMA channels (16 max.) to non-secure */ mmio_write_32(SUNXI_DMA_BASE + DMA_SEC_REG, 0xffff); -- cgit v1.2.3 From 1d60052e995b13ec49ba0b320a5056ce8e7a962a Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Mon, 29 Jun 2020 07:17:24 +0100 Subject: plat/arm: Add assert for the valid address of dtb information Added assert in the code to check valid address of dtb information structure retrieved from fw_config device tree. This patch fixes coverity defect:360213. Also, removed conditional calling of "fconf_populate" as "fconf_populate" function already checks the validity of the device tree address received and go to panic in case of address is NULL. Signed-off-by: Manish V Badarkhe Change-Id: Ib83e4e84a95e2456a12c7a2bb3fe70461d882cba --- plat/arm/common/arm_bl2_setup.c | 10 ++++------ plat/arm/common/arm_dyn_cfg.c | 4 ++++ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c index e4a4f8724..fd60c2bd3 100644 --- a/plat/arm/common/arm_bl2_setup.c +++ b/plat/arm/common/arm_bl2_setup.c @@ -62,15 +62,13 @@ void arm_bl2_early_platform_setup(uintptr_t fw_config, bl2_tzram_layout = *mem_layout; /* Fill the properties struct with the info from the config dtb */ - if (fw_config != 0U) { - fconf_populate("FW_CONFIG", fw_config); - } + fconf_populate("FW_CONFIG", fw_config); /* TB_FW_CONFIG was also loaded by BL1 */ tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID); - if (tb_fw_config_info != NULL) { - fconf_populate("TB_FW", tb_fw_config_info->config_addr); - } + assert(tb_fw_config_info != NULL); + + fconf_populate("TB_FW", tb_fw_config_info->config_addr); /* Initialise the IO layer and register platform IO devices */ plat_arm_io_setup(); diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c index a28e0ccff..633445bad 100644 --- a/plat/arm/common/arm_dyn_cfg.c +++ b/plat/arm/common/arm_dyn_cfg.c @@ -93,6 +93,8 @@ void arm_bl1_set_mbedtls_heap(void) */ 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 != 0UL) && (mbedtls_heap_addr != NULL)) { @@ -134,6 +136,8 @@ void arm_bl1_set_bl2_hash(image_desc_t *image_desc) 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; /* -- cgit v1.2.3 From 4a565bd88896944bf5f457f7bd6b148151fbf4dc Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Thu, 23 Apr 2020 09:28:37 +0100 Subject: Fix makefile to build on a Windows host PC The TF-A firmware build system is capable of building on both Unix like and Windows host PCs. The commit ID 7ff088 "Enable MTE support" updated the Makefile to conditionally enable the MTE support if the AArch64 architecture revision was greater than 8.5. However, the Makefile changes were dependent on shell commands that are only available on unix shells, resulting in build failures on a Windows host PC. This patch fixes the Makefile by using a more portable approach for comparing the architecture revision. Change-Id: Icb56cbecd8af5b0b9056d105970ff4a6edd1755a Signed-off-by: Sami Mujawar --- Makefile | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 160cd44cc..becbf0341 100644 --- a/Makefile +++ b/Makefile @@ -197,10 +197,8 @@ endif # Memory tagging is supported in architecture Armv8.5-A AArch64 and onwards ifeq ($(ARCH), aarch64) -ifeq ($(shell test $(ARM_ARCH_MAJOR) -gt 8; echo $$?),0) -mem_tag_arch_support = yes -else ifeq ($(shell test $(ARM_ARCH_MAJOR) -eq 8 -a $(ARM_ARCH_MINOR) -ge 5; \ - echo $$?),0) +# Check if revision is greater than or equal to 8.5 +ifeq "8.5" "$(word 1, $(sort 8.5 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))" mem_tag_arch_support = yes endif endif -- cgit v1.2.3 From c3233c11c4a009d1d4c895056c0ca674e4228330 Mon Sep 17 00:00:00 2001 From: Manish Pandey Date: Tue, 30 Jun 2020 00:46:08 +0100 Subject: doc: RAS: fixing broken links There were some links in the file "ras.rst" which were broken, this patch fixes all the broken links in this file. Signed-off-by: Manish Pandey Change-Id: I00cf080e9338af5786239a4843cb4c2e0cc9d99d --- docs/components/exception-handling.rst | 4 +++ docs/components/ras.rst | 41 ++++++++++++------------------ docs/design/interrupt-framework-design.rst | 2 ++ docs/getting_started/porting-guide.rst | 2 ++ 4 files changed, 24 insertions(+), 25 deletions(-) diff --git a/docs/components/exception-handling.rst b/docs/components/exception-handling.rst index 4cca5f40b..4c63a8b47 100644 --- a/docs/components/exception-handling.rst +++ b/docs/components/exception-handling.rst @@ -176,6 +176,8 @@ dispatcher may register more than one priority level. Dispatchers are assigned interrupt priority levels in two steps: +.. _Partitioning priority levels: + Partitioning priority levels ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -365,6 +367,8 @@ assign interrupts to fictitious dispatchers: See also the `Build-time flow`_ and the `Run-time flow`_. +.. _Activating and Deactivating priorities: + Activating and Deactivating priorities -------------------------------------- diff --git a/docs/components/ras.rst b/docs/components/ras.rst index 86529d740..02207d8b7 100644 --- a/docs/components/ras.rst +++ b/docs/components/ras.rst @@ -9,10 +9,8 @@ In conjunction with the |EHF|, support for RAS extension enables firmware-first paradigm for handling platform errors: exceptions resulting from errors are routed to and handled in EL3. Said errors are Synchronous External Abort (SEA), Asynchronous External Abort (signalled as SErrors), Fault Handling and Error -Recovery interrupts. The |EHF| document mentions various `error handling -use-cases`__. - -.. __: exception-handling.rst#delegation-use-cases +Recovery interrupts. The |EHF| document mentions various :ref:`error handling +use-cases ` . For the description of Arm RAS extensions, Standard Error Records, and the precise definition of RAS terminology, please refer to the Arm Architecture @@ -46,9 +44,7 @@ Platform APIs The RAS framework allows the platform to define handlers for External Abort, Uncontainable Errors, Double Fault, and errors rising from EL3 execution. Please -refer to the porting guide for the `RAS platform API descriptions`__. - -.. __: ../getting_started/porting-guide.rst#external-abort-handling-and-ras-support +refer to :ref:`RAS Porting Guide `. Registering RAS error records ----------------------------- @@ -114,9 +110,8 @@ The error handler must have the following prototype: The ``data`` constant parameter describes the various properties of the error, including the reason for the error, exception syndrome, and also ``flags``, -``cookie``, and ``handle`` parameters from the `top-level exception handler`__. - -.. __: interrupt-framework-design.rst#el3-interrupts +``cookie``, and ``handle`` parameters from the :ref:`top-level exception handler +`. The platform is expected populate an array using the macros above, and register the it with the RAS framework using the macro ``REGISTER_ERR_RECORD_INFO()``, @@ -229,21 +224,17 @@ Interaction with Exception Handling Framework As mentioned in earlier sections, RAS framework interacts with the |EHF| to arbitrate handling of RAS exceptions with others that are routed to EL3. This -means that the platform must partition a `priority level`__ for handling RAS -exceptions. The platform must then define the macro ``PLAT_RAS_PRI`` to the -priority level used for RAS exceptions. Platforms would typically want to -allocate the highest secure priority for RAS handling. - -.. __: exception-handling.rst#partitioning-priority-levels - -Handling of both `interrupt`__ and `non-interrupt`__ exceptions follow the -sequences outlined in the |EHF| documentation. I.e., for interrupts, the -priority management is implicit; but for non-interrupt exceptions, they're -explicit using `EHF APIs`__. - -.. __: exception-handling.rst#interrupt-flow -.. __: exception-handling.rst#non-interrupt-flow -.. __: exception-handling.rst#activating-and-deactivating-priorities +means that the platform must partition a :ref:`priority level ` for handling RAS exceptions. The platform must then define +the macro ``PLAT_RAS_PRI`` to the priority level used for RAS exceptions. +Platforms would typically want to allocate the highest secure priority for +RAS handling. + +Handling of both :ref:`interrupt ` and :ref:`non-interrupt +` exceptions follow the sequences outlined in the |EHF| +documentation. I.e., for interrupts, the priority management is implicit; but +for non-interrupt exceptions, they're explicit using :ref:`EHF APIs +`. -------------- diff --git a/docs/design/interrupt-framework-design.rst b/docs/design/interrupt-framework-design.rst index 14f7227d7..2e200aa3f 100644 --- a/docs/design/interrupt-framework-design.rst +++ b/docs/design/interrupt-framework-design.rst @@ -138,6 +138,8 @@ Non-secure interrupts reason to route the interrupt to EL3 software and then hand it back to non-secure software for handling. +.. _EL3 interrupts: + EL3 interrupts ^^^^^^^^^^^^^^ diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst index 45c27ade0..c98f3cc04 100644 --- a/docs/getting_started/porting-guide.rst +++ b/docs/getting_started/porting-guide.rst @@ -2729,6 +2729,8 @@ data on the designated crash console. It should only use general purpose registers x0 through x5 to do its work. The return value is 0 on successful completion; otherwise the return value is -1. +.. _External Abort handling and RAS Support: + External Abort handling and RAS Support --------------------------------------- -- cgit v1.2.3 From 0396bcbc6ae75a71489c078ae43f6f549abd5be4 Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Wed, 1 Jul 2020 13:53:07 +0200 Subject: doc: Fix some broken links Fix all external broken links reported by Sphinx linkcheck tool. This does not take care of broken cross-references between internal TF-A documentation files. These will be fixed in a future patch. Change-Id: I2a740a3ec0b688c14aad575a6c2ac71e72ce051e Signed-off-by: Sandrine Bailleux --- docs/perf/psci-performance-juno.rst | 4 ++-- docs/plat/allwinner.rst | 2 +- docs/plat/meson-axg.rst | 2 +- docs/plat/meson-g12a.rst | 4 ++-- docs/plat/meson-gxl.rst | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/perf/psci-performance-juno.rst b/docs/perf/psci-performance-juno.rst index c127c1c4a..eab3e4d2b 100644 --- a/docs/perf/psci-performance-juno.rst +++ b/docs/perf/psci-performance-juno.rst @@ -286,7 +286,7 @@ effects, given that these measurements are at the nano-second level. -------------- -*Copyright (c) 2019, Arm Limited and Contributors. All rights reserved.* +*Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.* -.. _Juno R1 platform: https://www.arm.com/files/pdf/Juno_r1_ARM_Dev_datasheet.pdf +.. _Juno R1 platform: https://static.docs.arm.com/100122/0100/arm_versatile_express_juno_r1_development_platform_(v2m_juno_r1)_technical_reference_manual_100122_0100_05_en.pdf .. _TF master as of 31/01/2017: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/?id=c38b36d diff --git a/docs/plat/allwinner.rst b/docs/plat/allwinner.rst index a1e06590a..d82380ddf 100644 --- a/docs/plat/allwinner.rst +++ b/docs/plat/allwinner.rst @@ -34,7 +34,7 @@ To build for machines with an H6 SoC: make CROSS_COMPILE=aarch64-linux-gnu- PLAT=sun50i_h6 DEBUG=1 bl31 -.. _U-Boot documentation: http://git.denx.de/?p=u-boot.git;f=board/sunxi/README.sunxi64;hb=HEAD +.. _U-Boot documentation: https://gitlab.denx.de/u-boot/u-boot/-/blob/master/board/sunxi/README.sunxi64 Trusted OS dispatcher --------------------- diff --git a/docs/plat/meson-axg.rst b/docs/plat/meson-axg.rst index 1e4b2c207..6f6732e95 100644 --- a/docs/plat/meson-axg.rst +++ b/docs/plat/meson-axg.rst @@ -24,4 +24,4 @@ This port has been tested on a A113D board. After building it, follow the instructions in the `U-Boot repository`_, replacing the mentioned **bl31.img** by the one built from this port. -.. _U-Boot repository: https://github.com/u-boot/u-boot/blob/master/board/amlogic/s400/README +.. _U-Boot repository: https://github.com/u-boot/u-boot/blob/master/doc/board/amlogic/s400.rst diff --git a/docs/plat/meson-g12a.rst b/docs/plat/meson-g12a.rst index 7cd1bf746..9588ec498 100644 --- a/docs/plat/meson-g12a.rst +++ b/docs/plat/meson-g12a.rst @@ -20,8 +20,8 @@ In order to build it: CROSS_COMPILE=aarch64-linux-gnu- make DEBUG=1 PLAT=g12a This port has been tested on a SEI510 board. After building it, follow the -instructions in the `gxlimg repository` or `U-Boot repository`_, replacing the +instructions in the `gxlimg repository`_ or `U-Boot repository`_, replacing the mentioned **bl31.img** by the one built from this port. .. _gxlimg repository: https://github.com/repk/gxlimg/blob/master/README.g12a -.. _U-Boot repository: https://github.com/u-boot/u-boot/blob/master/board/amlogic/sei510/README +.. _U-Boot repository: https://github.com/u-boot/u-boot/blob/master/doc/board/amlogic/sei510.rst diff --git a/docs/plat/meson-gxl.rst b/docs/plat/meson-gxl.rst index c6d850446..0751f1d00 100644 --- a/docs/plat/meson-gxl.rst +++ b/docs/plat/meson-gxl.rst @@ -20,8 +20,8 @@ In order to build it: CROSS_COMPILE=aarch64-linux-gnu- make DEBUG=1 PLAT=gxl This port has been tested on a Lepotato. After building it, follow the -instructions in the `gxlimg repository` or `U-Boot repository`_, replacing the +instructions in the `gxlimg repository`_ or `U-Boot repository`_, replacing the mentioned **bl31.img** by the one built from this port. .. _gxlimg repository: https://github.com/repk/gxlimg/blob/master/README -.. _U-Boot repository: https://github.com/u-boot/u-boot/blob/master/board/amlogic/p212/README.libretech-cc +.. _U-Boot repository: https://github.com/u-boot/u-boot/blob/master/doc/board/amlogic/p212.rst -- cgit v1.2.3 From 148798cd15579f936d50d86e1c537a002179bed9 Mon Sep 17 00:00:00 2001 From: Luka Kovacic Date: Fri, 3 Jul 2020 17:02:54 +0200 Subject: plat: marvell: armada: a8k: common: Fix a8k_common.mk to use BOARD_DIR variable Use the BOARD_DIR variable instead of PLAT_FAMILY_BASE variable for determening the path of the system_power.c file. The variable was not updated, when it was deprecated in a8k_common.mk in commit 613bbde09e48874658af5a00612fe2a0b0388523. Signed-off-by: Luka Kovacic Cc: Luka Perkov Change-Id: I9b4659a19ba3cd5c869d44c5d834b220f49136e8 --- plat/marvell/armada/a8k/common/a8k_common.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plat/marvell/armada/a8k/common/a8k_common.mk b/plat/marvell/armada/a8k/common/a8k_common.mk index dcbf9a66e..8e7d76c4b 100644 --- a/plat/marvell/armada/a8k/common/a8k_common.mk +++ b/plat/marvell/armada/a8k/common/a8k_common.mk @@ -37,7 +37,7 @@ ROM_BIN_EXT ?= $(BUILD_PLAT)/ble.bin DOIMAGE_FLAGS += -b $(ROM_BIN_EXT) $(NAND_DOIMAGE_FLAGS) $(DOIMAGE_SEC_FLAGS) # Check whether to build system_power.c for the platform -ifneq ("$(wildcard $(PLAT_FAMILY_BASE)/$(PLAT)/board/system_power.c)","") +ifneq ("$(wildcard $(BOARD_DIR)/board/system_power.c)","") SYSTEM_POWER_SUPPORT = 1 else SYSTEM_POWER_SUPPORT = 0 @@ -90,7 +90,7 @@ MARVELL_DRV := $(MARVELL_DRV_BASE)/io_win.c \ BL31_PORTING_SOURCES := $(BOARD_DIR)/board/marvell_plat_config.c ifeq ($(SYSTEM_POWER_SUPPORT),1) -BL31_PORTING_SOURCES += $(PLAT_FAMILY_BASE)/$(PLAT)/board/system_power.c +BL31_PORTING_SOURCES += $(BOARD_DIR)/board/system_power.c endif BL31_SOURCES += lib/cpus/aarch64/cortex_a72.S \ -- cgit v1.2.3 From 70ec0d72b6edf1966a77d328b6ebfcaf2bf6d114 Mon Sep 17 00:00:00 2001 From: Luka Kovacic Date: Wed, 4 Dec 2019 21:46:37 +0100 Subject: plat: marvell: armada: a8k: Add support for iEi Puzzle-M801 board Add support for the iEi Puzzle-M801 board that is based on the Marvell Armada 88F8040 SoC. It supports 1 x 288-pin DIMM, DDR4 2400MHz up to 16 GB (ECC). The iEi Puzzle-M801 board is using a custom MCU to handle board power management. The MCU is managing the boards power LEDs, fans and some other periferals. It's using UART for communication. Signed-off-by: Luka Kovacic Cc: Luka Perkov Change-Id: I0826ef8bf651b69aad5803184f20930ac7212ef8 --- .../armada/a8k/a80x0_puzzle/board/dram_port.c | 139 ++++++++++++++ .../a8k/a80x0_puzzle/board/marvell_plat_config.c | 201 +++++++++++++++++++++ .../armada/a8k/a80x0_puzzle/board/system_power.c | 59 ++++++ plat/marvell/armada/a8k/a80x0_puzzle/mvebu_def.h | 17 ++ plat/marvell/armada/a8k/a80x0_puzzle/platform.mk | 20 ++ 5 files changed, 436 insertions(+) create mode 100644 plat/marvell/armada/a8k/a80x0_puzzle/board/dram_port.c create mode 100644 plat/marvell/armada/a8k/a80x0_puzzle/board/marvell_plat_config.c create mode 100644 plat/marvell/armada/a8k/a80x0_puzzle/board/system_power.c create mode 100644 plat/marvell/armada/a8k/a80x0_puzzle/mvebu_def.h create mode 100644 plat/marvell/armada/a8k/a80x0_puzzle/platform.mk diff --git a/plat/marvell/armada/a8k/a80x0_puzzle/board/dram_port.c b/plat/marvell/armada/a8k/a80x0_puzzle/board/dram_port.c new file mode 100644 index 000000000..46a9a26b9 --- /dev/null +++ b/plat/marvell/armada/a8k/a80x0_puzzle/board/dram_port.c @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include +#include +#include + +#include +#include +#include + +#define MVEBU_AP_MPP_CTRL0_7_REG MVEBU_AP_MPP_REGS(0) +#define MVEBU_AP_MPP_CTRL4_OFFS 16 +#define MVEBU_AP_MPP_CTRL5_OFFS 20 +#define MVEBU_AP_MPP_CTRL4_I2C0_SDA_ENA 0x3 +#define MVEBU_AP_MPP_CTRL5_I2C0_SCK_ENA 0x3 + +#define MVEBU_CP_MPP_CTRL37_OFFS 20 +#define MVEBU_CP_MPP_CTRL38_OFFS 24 +#define MVEBU_CP_MPP_CTRL37_I2C0_SCK_ENA 0x2 +#define MVEBU_CP_MPP_CTRL38_I2C0_SDA_ENA 0x2 + +#define MVEBU_MPP_CTRL_MASK 0xf + +/* + * This struct provides the DRAM training code with + * the appropriate board DRAM configuration + */ +static struct mv_ddr_topology_map board_topology_map = { + /* Board with 1CS 8Gb x4 devices of Micron 2400T */ + DEBUG_LEVEL_ERROR, + 0x1, /* active interfaces */ + /* cs_mask, mirror, dqs_swap, ck_swap X subphys */ + { { { {0x1, 0x0, 0, 0}, /* FIXME: change the cs mask for all 64 bit */ + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0} }, + /* TODO: double check if the speed bin is 2400T */ + SPEED_BIN_DDR_2400T, /* 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 */ + MV_DDR_64BIT_BUS_MASK, /* subphys mask */ + MV_DDR_CFG_SPD, /* ddr configuration data source */ + { {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 */ + }, + } +}; + +struct mv_ddr_topology_map *mv_ddr_topology_map_get(void) +{ + /* Return the board topology as defined in the board code */ + return &board_topology_map; +} + +static void mpp_config(void) +{ + uint32_t val; + uintptr_t reg; + + /* configure ap mmps 4, 5 to I2C */ + reg = MVEBU_AP_MPP_CTRL0_7_REG; + + val = mmio_read_32(reg); + val &= ~((MVEBU_MPP_CTRL_MASK << MVEBU_AP_MPP_CTRL4_OFFS) | + (MVEBU_MPP_CTRL_MASK << MVEBU_AP_MPP_CTRL5_OFFS)); + val |= ((MVEBU_AP_MPP_CTRL4_I2C0_SDA_ENA << MVEBU_AP_MPP_CTRL4_OFFS) | + (MVEBU_AP_MPP_CTRL5_I2C0_SCK_ENA << MVEBU_AP_MPP_CTRL5_OFFS)); + + mmio_write_32(reg, val); +} + +/* + * 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) +{ + struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); + + INFO("Gathering DRAM information\n"); + + if (tm->cfg_src == MV_DDR_CFG_SPD) { + /* configure MPPs to enable i2c */ + mpp_config(); + /* initialize the MVEBU_AP_I2C_BASE I2C bus */ + i2c_init((void *)MVEBU_AP_I2C_BASE); + /* select SPD memory page 0 to access DRAM configuration */ + i2c_write(I2C_SPD_P0_ADDR, 0x0, 1, tm->spd_data.all_bytes, 1); + /* read data from spd */ + i2c_read(I2C_SPD_ADDR, 0x0, 1, tm->spd_data.all_bytes, + sizeof(tm->spd_data.all_bytes)); + } +} diff --git a/plat/marvell/armada/a8k/a80x0_puzzle/board/marvell_plat_config.c b/plat/marvell/armada/a8k/a80x0_puzzle/board/marvell_plat_config.c new file mode 100644 index 000000000..0edc97745 --- /dev/null +++ b/plat/marvell/armada/a8k/a80x0_puzzle/board/marvell_plat_config.c @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include + +#include + +/* + * If bootrom is currently at BLE there's no need to include the memory + * maps structure at this point + */ +#include +#ifndef IMAGE_BLE + +/***************************************************************************** + * GPIO Configuration + ***************************************************************************** + */ +#define MPP_CONTROL_REGISTER 0xf2440018 +#define MPP_CONTROL_MPP_SEL_52_MASK 0xf0000 +#define GPIO_DATA_OUT1_REGISTER 0xf2440140 +#define GPIO_DATA_OUT_EN_CTRL1_REGISTER 0xf2440144 +#define GPIO52_MASK 0x100000 + +/* Reset PCIe via GPIO number 52 */ +int marvell_gpio_config(void) +{ + uint32_t reg; + + reg = mmio_read_32(MPP_CONTROL_REGISTER); + reg |= MPP_CONTROL_MPP_SEL_52_MASK; + mmio_write_32(MPP_CONTROL_REGISTER, reg); + + reg = mmio_read_32(GPIO_DATA_OUT1_REGISTER); + reg |= GPIO52_MASK; + mmio_write_32(GPIO_DATA_OUT1_REGISTER, reg); + + reg = mmio_read_32(GPIO_DATA_OUT_EN_CTRL1_REGISTER); + reg &= ~GPIO52_MASK; + mmio_write_32(GPIO_DATA_OUT_EN_CTRL1_REGISTER, reg); + udelay(100); + + return 0; +} + +/***************************************************************************** + * AMB Configuration + ***************************************************************************** + */ +struct addr_map_win amb_memory_map[] = { + /* CP1 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[] = { + /* CP1 (MCI0) internal regs */ + {0x00000000f4000000, 0x2000000, MCI_0_TID}, +#ifndef IMAGE_BLE + /* PCIe0 and SPI1_CS0 (RUNIT) on CP1*/ + {0x00000000f9000000, 0x2000000, MCI_0_TID}, + /* PCIe1 on CP1*/ + {0x00000000fb000000, 0x1000000, MCI_0_TID}, + /* PCIe2 on CP1*/ + {0x00000000fc000000, 0x1000000, MCI_0_TID}, + /* 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_cp0[] = { + /* CP0 */ + /* PEX1_X1 window */ + {0x00000000f7000000, 0x1000000, PEX1_TID}, + /* PEX2_X1 window */ + {0x00000000f8000000, 0x1000000, PEX2_TID}, + /* PEX0_X4 window */ + {0x00000000f6000000, 0x1000000, PEX0_TID}, + {0x00000000c0000000, 0x30000000, PEX0_TID}, + {0x0000000800000000, 0x100000000, PEX0_TID}, +}; + +struct addr_map_win iob_memory_map_cp1[] = { + /* CP1 */ + /* SPI1_CS0 (RUNIT) window */ + {0x00000000f9000000, 0x1000000, RUNIT_TID}, + /* PEX1_X1 window */ + {0x00000000fb000000, 0x1000000, PEX1_TID}, + /* PEX2_X1 window */ + {0x00000000fc000000, 0x1000000, PEX2_TID}, + /* PEX0_X4 window */ + {0x00000000fa000000, 0x1000000, PEX0_TID} +}; + +int marvell_get_iob_memory_map(struct addr_map_win **win, uint32_t *size, + uintptr_t base) +{ + switch (base) { + case MVEBU_CP_REGS_BASE(0): + *win = iob_memory_map_cp0; + *size = ARRAY_SIZE(iob_memory_map_cp0); + return 0; + case MVEBU_CP_REGS_BASE(1): + *win = iob_memory_map_cp1; + *size = ARRAY_SIZE(iob_memory_map_cp1); + return 0; + default: + *size = 0; + *win = 0; + return 1; + } +} +#endif + +/***************************************************************************** + * CCU Configuration + ***************************************************************************** + */ +struct addr_map_win ccu_memory_map[] = { +#ifdef IMAGE_BLE + {0x00000000f2000000, 0x4000000, IO_0_TID}, /* IO window */ +#else +#if LLC_SRAM + {PLAT_MARVELL_LLC_SRAM_BASE, PLAT_MARVELL_LLC_SRAM_SIZE, SRAM_TID}, +#endif + {0x00000000f2000000, 0xe000000, IO_0_TID}, /* IO window */ + {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; +} + +/* In reference to #ifndef IMAGE_BLE, this part is used for BLE only. */ + +/***************************************************************************** + * SKIP IMAGE Configuration + ***************************************************************************** + */ +void *plat_marvell_get_skip_image_data(void) +{ + /* No recovery button on A8k-MCBIN board */ + return NULL; +} diff --git a/plat/marvell/armada/a8k/a80x0_puzzle/board/system_power.c b/plat/marvell/armada/a8k/a80x0_puzzle/board/system_power.c new file mode 100644 index 000000000..5147dd519 --- /dev/null +++ b/plat/marvell/armada/a8k/a80x0_puzzle/board/system_power.c @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2020 Sartura Ltd. + * Author: Luka Kovacic + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include +#include +#include +#include +#include + +/***************************************************************************** + * Platform specific power off functions + * Power off PSU / Send command to power management MCU / ... + ***************************************************************************** + */ + +unsigned char add_xor_checksum(unsigned char *buf, unsigned char xor_len) +{ + unsigned char xor_sum = 0; + unsigned int i; + + for (i = 0; i < xor_len; i++) + xor_sum ^= buf[i]; + + return xor_sum; +} + +int system_power_off(void) +{ + static console_t console; + + /* WT61P803 MCU system_off_now command */ + unsigned char system_off_now[4] = { '@', 'C', '0' }; + int i, len; + + len = sizeof(system_off_now); + system_off_now[len - 1] = add_xor_checksum(system_off_now, len); + + console_16550_register(PLAT_MARVELL_BOOT_UART_BASE + 0x100, + PLAT_MARVELL_BOOT_UART_CLK_IN_HZ, 115200, &console); + + /* Send system_off_now to console */ + for (i = 0; i < len; i++) { + console.putc(system_off_now[i], &console); + udelay(1000); + } + + console.flush(&console); + (void)console_unregister(&console); + + mdelay(100); + + return 0; +} diff --git a/plat/marvell/armada/a8k/a80x0_puzzle/mvebu_def.h b/plat/marvell/armada/a8k/a80x0_puzzle/mvebu_def.h new file mode 100644 index 000000000..3fa119af6 --- /dev/null +++ b/plat/marvell/armada/a8k/a80x0_puzzle/mvebu_def.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2018 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 2 /* A80x0 has both CP0 & CP1 */ +#define I2C_SPD_ADDR 0x53 /* Access SPD data */ +#define I2C_SPD_P0_ADDR 0x36 /* Select SPD data page 0 */ + +#endif /* MVEBU_DEF_H */ diff --git a/plat/marvell/armada/a8k/a80x0_puzzle/platform.mk b/plat/marvell/armada/a8k/a80x0_puzzle/platform.mk new file mode 100644 index 000000000..3378d53d7 --- /dev/null +++ b/plat/marvell/armada/a8k/a80x0_puzzle/platform.mk @@ -0,0 +1,20 @@ +# +# Copyright (C) 2018 Marvell International Ltd. +# +# SPDX-License-Identifier: BSD-3-Clause +# https://spdx.org/licenses +# + +PCI_EP_SUPPORT := 0 + +CP_NUM := 2 +$(eval $(call add_define,CP_NUM)) + +DOIMAGE_SEC := tools/doimage/secure/sec_img_8K.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 -- cgit v1.2.3 From a66f0309e5ac56c8223414542874a657768eec03 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 4 Jul 2020 16:12:55 +0900 Subject: docs: qemu: add build instructions for QEMU_EFI.fd and rootfs.cpio.gz This commit solves the limitation, "No build instructions for QEMU_EFI.fd and rootfs-arm64.cpio.gz" Document the steps to build them. Change-Id: Ic6d895617cf71fe969f4aa9820dad25cc6182023 Signed-off-by: Masahiro Yamada --- docs/plat/qemu.rst | 43 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/docs/plat/qemu.rst b/docs/plat/qemu.rst index afa32c11b..368300d86 100644 --- a/docs/plat/qemu.rst +++ b/docs/plat/qemu.rst @@ -20,11 +20,46 @@ provided as it's generated by QEMU. Current limitations: - Only cold boot is supported -- No build instructions for QEMU\_EFI.fd and rootfs-arm64.cpio.gz -``QEMU_EFI.fd`` can be dowloaded from +Getting non-TF images +--------------------- + +``QEMU_EFI.fd`` can be downloaded from http://snapshots.linaro.org/components/kernel/leg-virt-tianocore-edk2-upstream/latest/QEMU-KERNEL-AARCH64/RELEASE_GCC5/QEMU_EFI.fd +or, can be built as follows: + +.. code:: shell + + git clone https://github.com/tianocore/edk2.git + cd edk2 + git submodule update --init + make -C BaseTools + source edksetup.sh + export GCC5_AARCH64_PREFIX=aarch64-linux-gnu- + build -a AARCH64 -t GCC5 -p ArmVirtPkg/ArmVirtQemuKernel.dsc + +```` + +Then, you will get ``Build/ArmVirtQemuKernel-AARCH64/DEBUG_GCC5/FV/QEMU_EFI.fd`` + +Please note you do not need to use GCC 5 in spite of the environment variable +``GCC5_AARCH64_PREFIX`` + +The rootfs can be built by using Buildroot as follows: + +.. code:: shell + + git clone git://git.buildroot.net/buildroot.git + cd buildroot + make qemu_aarch64_virt_defconfig + utils/config -e BR2_TARGET_ROOTFS_CPIO + utils/config -e BR2_TARGET_ROOTFS_CPIO_GZIP + make olddefconfig + make + +Then, you will get ``output/images/rootfs.cpio.gz``. + Booting via semi-hosting option ------------------------------- @@ -50,7 +85,7 @@ To start (QEMU v4.1.0): qemu-system-aarch64 -nographic -machine virt,secure=on -cpu cortex-a57 \ -kernel Image \ -append "console=ttyAMA0,38400 keep_bootcon root=/dev/vda2" \ - -initrd rootfs-arm64.cpio.gz -smp 2 -m 1024 -bios bl1.bin \ + -initrd rootfs.cpio.gz -smp 2 -m 1024 -bios bl1.bin \ -d unimp -semihosting-config enable,target=native Booting via flash based firmwares @@ -99,5 +134,5 @@ To start (QEMU v2.6.0): qemu-system-aarch64 -nographic -machine virt,secure=on -cpu cortex-a57 \ -kernel Image -no-acpi \ -append 'console=ttyAMA0,38400 keep_bootcon root=/dev/vda2' \ - -initrd rootfs-arm64.cpio.gz -smp 2 -m 1024 -bios flash.bin \ + -initrd rootfs.cpio.gz -smp 2 -m 1024 -bios flash.bin \ -d unimp -- cgit v1.2.3 From 624120e05c7a864b90848c7a31c881f2b98c5b74 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 4 Jul 2020 17:10:25 +0900 Subject: docs: qemu: remove unneeded root=/dev/vda2 kernel parameter In my understanding, /dev/vda2 does not exist unless you add virtio drive to the qemu command line. The rootfs is already specified by '-initrd rootfs.cpio.gz'. Change-Id: Ifdca5d4f3819d87ef7e8a08ed870872d24b86370 Signed-off-by: Masahiro Yamada --- docs/plat/qemu.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/plat/qemu.rst b/docs/plat/qemu.rst index 368300d86..3f79d76eb 100644 --- a/docs/plat/qemu.rst +++ b/docs/plat/qemu.rst @@ -84,7 +84,7 @@ To start (QEMU v4.1.0): qemu-system-aarch64 -nographic -machine virt,secure=on -cpu cortex-a57 \ -kernel Image \ - -append "console=ttyAMA0,38400 keep_bootcon root=/dev/vda2" \ + -append "console=ttyAMA0,38400 keep_bootcon" \ -initrd rootfs.cpio.gz -smp 2 -m 1024 -bios bl1.bin \ -d unimp -semihosting-config enable,target=native @@ -133,6 +133,6 @@ To start (QEMU v2.6.0): qemu-system-aarch64 -nographic -machine virt,secure=on -cpu cortex-a57 \ -kernel Image -no-acpi \ - -append 'console=ttyAMA0,38400 keep_bootcon root=/dev/vda2' \ + -append 'console=ttyAMA0,38400 keep_bootcon' \ -initrd rootfs.cpio.gz -smp 2 -m 1024 -bios flash.bin \ -d unimp -- cgit v1.2.3 From 231d0b351d42266da9814d025f1a0b7c6a856bb3 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 4 Jul 2020 17:15:44 +0900 Subject: docs: qemu: bump to QEMU 5.0.0 Fix the version inconsistency in the same file. I tested QEMU 5.0.0, and it worked for me. Change-Id: I9d8ca9aae1e413410eb5676927e13ae4aee9fad8 Signed-off-by: Masahiro Yamada --- docs/plat/qemu.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/plat/qemu.rst b/docs/plat/qemu.rst index 3f79d76eb..66b82473c 100644 --- a/docs/plat/qemu.rst +++ b/docs/plat/qemu.rst @@ -78,7 +78,7 @@ To build: make CROSS_COMPILE=aarch64-none-elf- PLAT=qemu -To start (QEMU v4.1.0): +To start (QEMU v5.0.0): .. code:: shell @@ -127,7 +127,7 @@ To build flash.bin: dd if=build/qemu/release/bl1.bin of=flash.bin bs=4096 conv=notrunc dd if=build/qemu/release/fip.bin of=flash.bin seek=64 bs=4096 conv=notrunc -To start (QEMU v2.6.0): +To start (QEMU v5.0.0): .. code:: shell -- cgit v1.2.3 From e7b586987c0a46660aa8402f19d626a5489fe449 Mon Sep 17 00:00:00 2001 From: Thomas Hebb Date: Sun, 5 Apr 2020 02:33:37 -0400 Subject: rockchip: don't crash if we get an FDT we can't parse When we parse the param from BL2, we try to parse it as a FDT and then, if that fails, as aux params. However, we don't sufficiently distinguish between failure modes in the first step: specifically, if we are given an FDT with good magic that we can't parse for some other reason (e.g. not enough space in our buffer), we still attempt to parse it as aux params even though that's guaranteed to fatal. Instead, we should either fail with a more descriptive message or continue to boot without parsing the FDT. This patch takes the latter approach, since all we currently get from the FDT is non-critical UART params. Signed-off-by: Thomas Hebb Change-Id: I1e98f1fcda4f78e6b45e86956288bafe58b113e4 --- plat/rockchip/common/params_setup.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/plat/rockchip/common/params_setup.c b/plat/rockchip/common/params_setup.c index 2ff81eda7..aec53eee2 100644 --- a/plat/rockchip/common/params_setup.c +++ b/plat/rockchip/common/params_setup.c @@ -230,12 +230,27 @@ static bool rk_aux_param_handler(struct bl_aux_param_header *param) void params_early_setup(u_register_t plat_param_from_bl2) { + int ret; + /* * Test if this is a FDT passed as a platform-specific parameter * block. */ - if (!dt_process_fdt(plat_param_from_bl2)) + ret = dt_process_fdt(plat_param_from_bl2); + if (!ret) { + return; + } else if (ret != -FDT_ERR_BADMAGIC) { + /* + * If we found an FDT but couldn't parse it (e.g. corrupt, not + * enough space), return and don't attempt to parse the param + * as something else, since we know that will also fail. All + * we're doing is setting up UART, this doesn't need to be + * fatal. + */ + WARN("%s: found FDT but could not parse: error %d\n", + __func__, ret); return; + } bl_aux_params_parse(plat_param_from_bl2, rk_aux_param_handler); } -- cgit v1.2.3 From 4e5005254e7e4e8eba1e20fb4893ca077e3a1aad Mon Sep 17 00:00:00 2001 From: Leonardo Sandoval Date: Mon, 29 Jun 2020 18:09:24 -0500 Subject: fiptool: return zero status on help and help Querying the 'fiptool' for help or help should return 0 return status (success) and not 1 (failure). In the other hand, if tool is executed with any other command (not help) where command's parameters are either missing or wrong, then the tool should return non-zero (failure). Now, the 'usage' function caller is the one that passes the return status. Change-Id: Id5eea91037cd810fb1e34a42e8199ef504f5daa4 Signed-off-by: Leonardo Sandoval --- tools/fiptool/fiptool.c | 74 ++++++++++++++++++++++++------------------------- tools/fiptool/fiptool.h | 2 +- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/tools/fiptool/fiptool.c b/tools/fiptool/fiptool.c index 80b498e47..8c5b04a55 100644 --- a/tools/fiptool/fiptool.c +++ b/tools/fiptool/fiptool.c @@ -24,17 +24,17 @@ #define OPT_ALIGN 2 static int info_cmd(int argc, char *argv[]); -static void info_usage(void); +static void info_usage(int); static int create_cmd(int argc, char *argv[]); -static void create_usage(void); +static void create_usage(int); static int update_cmd(int argc, char *argv[]); -static void update_usage(void); +static void update_usage(int); static int unpack_cmd(int argc, char *argv[]); -static void unpack_usage(void); +static void unpack_usage(int); static int remove_cmd(int argc, char *argv[]); -static void remove_usage(void); +static void remove_usage(int); static int version_cmd(int argc, char *argv[]); -static void version_usage(void); +static void version_usage(int); static int help_cmd(int argc, char *argv[]); static void usage(void); @@ -448,7 +448,7 @@ static int info_cmd(int argc, char *argv[]) fip_toc_header_t toc_header; if (argc != 2) - info_usage(); + info_usage(EXIT_FAILURE); argc--, argv++; parse_fip(argv[0], &toc_header); @@ -487,10 +487,10 @@ static int info_cmd(int argc, char *argv[]) return 0; } -static void info_usage(void) +static void info_usage(int exit_status) { printf("fiptool info FIP_FILENAME\n"); - exit(1); + exit(exit_status); } static int pack_images(const char *filename, uint64_t toc_flags, unsigned long align) @@ -669,7 +669,7 @@ static int create_cmd(int argc, char *argv[]) unsigned long align = 1; if (argc < 2) - create_usage(); + create_usage(EXIT_FAILURE); opts = fill_common_opts(opts, &nr_opts, required_argument); opts = add_opt(opts, &nr_opts, "plat-toc-flags", required_argument, @@ -710,7 +710,7 @@ static int create_cmd(int argc, char *argv[]) if (memcmp(&uuid, &uuid_null, sizeof(uuid_t)) == 0 || filename[0] == '\0') - create_usage(); + create_usage(EXIT_FAILURE); desc = lookup_image_desc_from_uuid(&uuid); if (desc == NULL) { @@ -722,7 +722,7 @@ static int create_cmd(int argc, char *argv[]) break; } default: - create_usage(); + create_usage(EXIT_FAILURE); } } argc -= optind; @@ -730,7 +730,7 @@ static int create_cmd(int argc, char *argv[]) free(opts); if (argc == 0) - create_usage(); + create_usage(EXIT_SUCCESS); update_fip(); @@ -738,7 +738,7 @@ static int create_cmd(int argc, char *argv[]) return 0; } -static void create_usage(void) +static void create_usage(int exit_status) { toc_entry_t *toc_entry = toc_entries; @@ -753,7 +753,7 @@ static void create_usage(void) for (; toc_entry->cmdline_name != NULL; toc_entry++) printf(" --%-16s FILENAME\t%s\n", toc_entry->cmdline_name, toc_entry->name); - exit(1); + exit(exit_status); } static int update_cmd(int argc, char *argv[]) @@ -767,7 +767,7 @@ static int update_cmd(int argc, char *argv[]) int pflag = 0; if (argc < 2) - update_usage(); + update_usage(EXIT_FAILURE); opts = fill_common_opts(opts, &nr_opts, required_argument); opts = add_opt(opts, &nr_opts, "align", required_argument, OPT_ALIGN); @@ -807,7 +807,7 @@ static int update_cmd(int argc, char *argv[]) if (memcmp(&uuid, &uuid_null, sizeof(uuid_t)) == 0 || filename[0] == '\0') - update_usage(); + update_usage(EXIT_FAILURE); desc = lookup_image_desc_from_uuid(&uuid); if (desc == NULL) { @@ -825,7 +825,7 @@ static int update_cmd(int argc, char *argv[]) snprintf(outfile, sizeof(outfile), "%s", optarg); break; default: - update_usage(); + update_usage(EXIT_FAILURE); } } argc -= optind; @@ -833,7 +833,7 @@ static int update_cmd(int argc, char *argv[]) free(opts); if (argc == 0) - update_usage(); + update_usage(EXIT_SUCCESS); if (outfile[0] == '\0') snprintf(outfile, sizeof(outfile), "%s", argv[0]); @@ -851,7 +851,7 @@ static int update_cmd(int argc, char *argv[]) return 0; } -static void update_usage(void) +static void update_usage(int exit_status) { toc_entry_t *toc_entry = toc_entries; @@ -867,7 +867,7 @@ static void update_usage(void) for (; toc_entry->cmdline_name != NULL; toc_entry++) printf(" --%-16s FILENAME\t%s\n", toc_entry->cmdline_name, toc_entry->name); - exit(1); + exit(exit_status); } static int unpack_cmd(int argc, char *argv[]) @@ -880,7 +880,7 @@ static int unpack_cmd(int argc, char *argv[]) int unpack_all = 1; if (argc < 2) - unpack_usage(); + unpack_usage(EXIT_FAILURE); opts = fill_common_opts(opts, &nr_opts, required_argument); opts = add_opt(opts, &nr_opts, "blob", required_argument, 'b'); @@ -915,7 +915,7 @@ static int unpack_cmd(int argc, char *argv[]) if (memcmp(&uuid, &uuid_null, sizeof(uuid_t)) == 0 || filename[0] == '\0') - unpack_usage(); + unpack_usage(EXIT_FAILURE); desc = lookup_image_desc_from_uuid(&uuid); if (desc == NULL) { @@ -934,7 +934,7 @@ static int unpack_cmd(int argc, char *argv[]) snprintf(outdir, sizeof(outdir), "%s", optarg); break; default: - unpack_usage(); + unpack_usage(EXIT_FAILURE); } } argc -= optind; @@ -942,7 +942,7 @@ static int unpack_cmd(int argc, char *argv[]) free(opts); if (argc == 0) - unpack_usage(); + unpack_usage(EXIT_SUCCESS); parse_fip(argv[0], NULL); @@ -986,7 +986,7 @@ static int unpack_cmd(int argc, char *argv[]) return 0; } -static void unpack_usage(void) +static void unpack_usage(int exit_status) { toc_entry_t *toc_entry = toc_entries; @@ -1003,7 +1003,7 @@ static void unpack_usage(void) toc_entry->name); printf("\n"); printf("If no options are provided, all images will be unpacked.\n"); - exit(1); + exit(exit_status); } static int remove_cmd(int argc, char *argv[]) @@ -1017,7 +1017,7 @@ static int remove_cmd(int argc, char *argv[]) int fflag = 0; if (argc < 2) - remove_usage(); + remove_usage(EXIT_FAILURE); opts = fill_common_opts(opts, &nr_opts, no_argument); opts = add_opt(opts, &nr_opts, "align", required_argument, OPT_ALIGN); @@ -1053,7 +1053,7 @@ static int remove_cmd(int argc, char *argv[]) filename, sizeof(filename)); if (memcmp(&uuid, &uuid_null, sizeof(uuid_t)) == 0) - remove_usage(); + remove_usage(EXIT_FAILURE); desc = lookup_image_desc_from_uuid(&uuid); if (desc == NULL) { @@ -1071,7 +1071,7 @@ static int remove_cmd(int argc, char *argv[]) snprintf(outfile, sizeof(outfile), "%s", optarg); break; default: - remove_usage(); + remove_usage(EXIT_FAILURE); } } argc -= optind; @@ -1079,7 +1079,7 @@ static int remove_cmd(int argc, char *argv[]) free(opts); if (argc == 0) - remove_usage(); + remove_usage(EXIT_SUCCESS); if (outfile[0] != '\0' && access(outfile, F_OK) == 0 && !fflag) log_errx("File %s already exists, use --force to overwrite it", @@ -1110,7 +1110,7 @@ static int remove_cmd(int argc, char *argv[]) return 0; } -static void remove_usage(void) +static void remove_usage(int exit_status) { toc_entry_t *toc_entry = toc_entries; @@ -1126,7 +1126,7 @@ static void remove_usage(void) for (; toc_entry->cmdline_name != NULL; toc_entry++) printf(" --%-16s\t%s\n", toc_entry->cmdline_name, toc_entry->name); - exit(1); + exit(exit_status); } static int version_cmd(int argc, char *argv[]) @@ -1140,10 +1140,10 @@ static int version_cmd(int argc, char *argv[]) return 0; } -static void version_usage(void) +static void version_usage(int exit_status) { printf("fiptool version\n"); - exit(1); + exit(exit_status); } static int help_cmd(int argc, char *argv[]) @@ -1157,7 +1157,7 @@ static int help_cmd(int argc, char *argv[]) for (i = 0; i < NELEM(cmds); i++) { if (strcmp(cmds[i].name, argv[0]) == 0 && cmds[i].usage != NULL) - cmds[i].usage(); + cmds[i].usage(EXIT_SUCCESS); } if (i == NELEM(cmds)) printf("No help for subcommand '%s'\n", argv[0]); @@ -1178,7 +1178,7 @@ static void usage(void) printf(" remove\tRemove images from FIP.\n"); printf(" version\tShow fiptool version.\n"); printf(" help\t\tShow help for given command.\n"); - exit(1); + exit(EXIT_SUCCESS); } int main(int argc, char *argv[]) diff --git a/tools/fiptool/fiptool.h b/tools/fiptool/fiptool.h index af3fcbdee..88c4a7edb 100644 --- a/tools/fiptool/fiptool.h +++ b/tools/fiptool/fiptool.h @@ -48,7 +48,7 @@ typedef struct image { typedef struct cmd { char *name; int (*handler)(int, char **); - void (*usage)(void); + void (*usage)(int); } cmd_t; #endif /* FIPTOOL_H */ -- cgit v1.2.3 From ef93cfa3a2591084307a41e64f1cbba327310749 Mon Sep 17 00:00:00 2001 From: Abdellatif El Khlifi Date: Mon, 6 Jul 2020 16:15:23 +0100 Subject: corstone700: splitting the platform support into FVP and FPGA This patch performs the following: - Creating two corstone700 platforms under corstone700 board: fvp and fpga - Since the FVP and FPGA have IP differences, this commit provides a specific DTS for each platform - The platform can be specified using the TARGET_PLATFORM Makefile variable (possible values are: fvp or fpga) - Allowing to use u-boot by: - Enabling NEED_BL33 option - Fixing non-secure image base: For no preloaded bl33 we want to have the NS base set on shared ram. Setup a memory map region for NS in shared map and set the bl33 address in the area. - Setting the SYS_COUNTER_FREQ_IN_TICKS based on the selected platform - Setting ARM_MAP_SHARED_RAM and ARM_MAP_NS_SHARED_RAM to use MT_MEMORY Change-Id: I4c8ac3387acb1693ab617bcccab00d80e340c163 Signed-off-by: Rui Miguel Silva Signed-off-by: Abdellatif El Khlifi --- fdts/corstone700.dts | 153 ------------ fdts/corstone700.dtsi | 161 +++++++++++++ fdts/corstone700_fpga.dts | 27 +++ fdts/corstone700_fvp.dts | 40 ++++ .../board/corstone700/common/corstone700_helpers.S | 100 ++++++++ .../board/corstone700/common/corstone700_plat.c | 39 +++ plat/arm/board/corstone700/common/corstone700_pm.c | 22 ++ .../corstone700/common/corstone700_security.c | 16 ++ .../common/corstone700_stack_protector.c | 35 +++ .../corstone700/common/corstone700_topology.c | 43 ++++ .../arm/board/corstone700/common/drivers/mhu/mhu.c | 117 +++++++++ .../arm/board/corstone700/common/drivers/mhu/mhu.h | 37 +++ .../corstone700/common/include/platform_def.h | 261 +++++++++++++++++++++ plat/arm/board/corstone700/corstone700_helpers.S | 100 -------- plat/arm/board/corstone700/corstone700_plat.c | 37 --- plat/arm/board/corstone700/corstone700_pm.c | 22 -- plat/arm/board/corstone700/corstone700_security.c | 16 -- .../corstone700/corstone700_stack_protector.c | 35 --- plat/arm/board/corstone700/corstone700_topology.c | 43 ---- plat/arm/board/corstone700/drivers/mhu/mhu.c | 117 --------- plat/arm/board/corstone700/drivers/mhu/mhu.h | 37 --- plat/arm/board/corstone700/include/platform_def.h | 247 ------------------- plat/arm/board/corstone700/platform.mk | 20 +- .../board/corstone700/sp_min/sp_min-corstone700.mk | 12 +- 24 files changed, 919 insertions(+), 818 deletions(-) delete mode 100644 fdts/corstone700.dts create mode 100644 fdts/corstone700.dtsi create mode 100644 fdts/corstone700_fpga.dts create mode 100644 fdts/corstone700_fvp.dts create mode 100644 plat/arm/board/corstone700/common/corstone700_helpers.S create mode 100644 plat/arm/board/corstone700/common/corstone700_plat.c create mode 100644 plat/arm/board/corstone700/common/corstone700_pm.c create mode 100644 plat/arm/board/corstone700/common/corstone700_security.c create mode 100644 plat/arm/board/corstone700/common/corstone700_stack_protector.c create mode 100644 plat/arm/board/corstone700/common/corstone700_topology.c create mode 100644 plat/arm/board/corstone700/common/drivers/mhu/mhu.c create mode 100644 plat/arm/board/corstone700/common/drivers/mhu/mhu.h create mode 100644 plat/arm/board/corstone700/common/include/platform_def.h delete mode 100644 plat/arm/board/corstone700/corstone700_helpers.S delete mode 100644 plat/arm/board/corstone700/corstone700_plat.c delete mode 100644 plat/arm/board/corstone700/corstone700_pm.c delete mode 100644 plat/arm/board/corstone700/corstone700_security.c delete mode 100644 plat/arm/board/corstone700/corstone700_stack_protector.c delete mode 100644 plat/arm/board/corstone700/corstone700_topology.c delete mode 100644 plat/arm/board/corstone700/drivers/mhu/mhu.c delete mode 100644 plat/arm/board/corstone700/drivers/mhu/mhu.h delete mode 100644 plat/arm/board/corstone700/include/platform_def.h diff --git a/fdts/corstone700.dts b/fdts/corstone700.dts deleted file mode 100644 index 851f5e625..000000000 --- a/fdts/corstone700.dts +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/dts-v1/; - -/ { - model = "corstone700"; - compatible = "arm,Corstone-700"; - interrupt-parent = <&gic>; - #address-cells = <1>; - #size-cells = <1>; - - chosen { - bootargs = "console=ttyAMA0 \ - loglevel=9"; - }; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - - cpu@0 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0>; - next-level-cache = <&L2_0>; - }; - - }; - - memory@80000000 { - device_type = "memory"; - reg = <0x80000000 0x80000000>; - }; - - gic: interrupt-controller@1c000000 { - compatible = "arm,gic-400"; - #interrupt-cells = <3>; - #address-cells = <0>; - interrupt-controller; - reg = <0x1c010000 0x1000>, - <0x1c02f000 0x2000>, - <0x1c04f000 0x1000>, - <0x1c06f000 0x2000>; - interrupts = <1 9 0xf08>; - }; - - L2_0: l2-cache0 { - compatible = "cache"; - }; - - refclk100mhz: refclk100mhz { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <100000000>; - clock-output-names = "apb_pclk"; - }; - - smbclk: refclk24mhzx2 { - /* Reference 24MHz clock x 2 */ - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <48000000>; - clock-output-names = "smclk"; - }; - - uartclk: uartclk { - /* UART clock - 32MHz */ - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <32000000>; - clock-output-names = "uartclk"; - }; - - serial0: uart@1a510000 { - compatible = "arm,pl011", "arm,primecell"; - reg = <0x1a510000 0x1000>; - interrupt-parent = <&gic>; - interrupts = <0 19 4>; - clocks = <&uartclk>, <&refclk100mhz>; - clock-names = "uartclk", "apb_pclk"; - }; - - serial1: uart@1a520000 { - compatible = "arm,pl011", "arm,primecell"; - reg = <0x1a520000 0x1000>; - interrupt-parent = <&gic>; - interrupts = <0 20 4>; - clocks = <&uartclk>, <&refclk100mhz>; - clock-names = "uartclk", "apb_pclk"; - }; - - timer { - compatible = "arm,armv8-timer"; - interrupts = <1 13 0xf08>, - <1 14 0xf08>, - <1 11 0xf08>, - <1 10 0xf08>; - }; - - mbox_es0mhu0: mhu@1b000000 { - compatible = "arm,mhuv2","arm,primecell"; - reg = <0x1b000000 0x1000>, - <0x1b010000 0x1000>; - clocks = <&refclk100mhz>; - clock-names = "apb_pclk"; - interrupts = <0 12 4>; - interrupt-names = "mhu_rx"; - #mbox-cells = <1>; - mbox-name = "arm-es0-mhu0"; - }; - - mbox_es0mhu1: mhu@1b020000 { - compatible = "arm,mhuv2","arm,primecell"; - reg = <0x1b020000 0x1000>, - <0x1b030000 0x1000>; - clocks = <&refclk100mhz>; - clock-names = "apb_pclk"; - interrupts = <0 47 4>; - interrupt-names = "mhu_rx"; - #mbox-cells = <1>; - mbox-name = "arm-es0-mhu1"; - }; - - mbox_semhu1: mhu@1b820000 { - compatible = "arm,mhuv2","arm,primecell"; - reg = <0x1b820000 0x1000>, - <0x1b830000 0x1000>; - clocks = <&refclk100mhz>; - clock-names = "apb_pclk"; - interrupts = <0 45 4>; - interrupt-names = "mhu_rx"; - #mbox-cells = <1>; - mbox-name = "arm-se-mhu1"; - }; - - client { - compatible = "arm,client"; - mboxes = <&mbox_es0mhu0 0>, <&mbox_es0mhu1 0>, <&mbox_semhu1 0>; - mbox-names = "es0mhu0", "es0mhu1", "semhu1"; - }; - - extsys0: extsys@1A010310 { - compatible = "arm,extsys_ctrl"; - reg = <0x1A010310 0x4>, - <0x1A010314 0x4>; - reg-names = "rstreg", "streg"; - }; - -}; diff --git a/fdts/corstone700.dtsi b/fdts/corstone700.dtsi new file mode 100644 index 000000000..2372207c6 --- /dev/null +++ b/fdts/corstone700.dtsi @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +/ { + compatible = "arm,Corstone-700"; + interrupt-parent = <&gic>; + #address-cells = <1>; + #size-cells = <1>; + + chosen { }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0>; + next-level-cache = <&L2_0>; + }; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x80000000 0x80000000>; + }; + + gic: interrupt-controller@1c000000 { + compatible = "arm,gic-400"; + #interrupt-cells = <3>; + #address-cells = <0>; + interrupt-controller; + reg = <0x1c010000 0x1000>, + <0x1c02f000 0x2000>, + <0x1c04f000 0x1000>, + <0x1c06f000 0x2000>; + interrupts = <1 9 0xf08>; + }; + + L2_0: l2-cache0 { + compatible = "cache"; + }; + + refclk100mhz: refclk100mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <100000000>; + clock-output-names = "apb_pclk"; + }; + + smbclk: refclk24mhzx2 { + /* Reference 24MHz clock x 2 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <48000000>; + clock-output-names = "smclk"; + }; + + uartclk: uartclk { + /* UART clock - 32MHz */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32000000>; + clock-output-names = "uartclk"; + }; + + serial0: uart@1a510000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x1a510000 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 19 4>; + clocks = <&uartclk>, <&refclk100mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + + serial1: uart@1a520000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x1a520000 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 20 4>; + clocks = <&uartclk>, <&refclk100mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <1 13 0xf08>, + <1 14 0xf08>, + <1 11 0xf08>, + <1 10 0xf08>; + }; + + refclk: refclk@1a220000 { + compatible = "arm,armv7-timer-mem"; + reg = <0x1a220000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + frame@1a230000 { + frame-number = <0>; + interrupts = <0 2 0xf04>; + reg = <0x1a230000 0x1000>; + }; + }; + + mbox_es0mhu0: mhu@1b000000 { + compatible = "arm,mhuv2","arm,primecell"; + reg = <0x1b000000 0x1000>, + <0x1b010000 0x1000>; + clocks = <&refclk100mhz>; + clock-names = "apb_pclk"; + interrupts = <0 12 4>; + interrupt-names = "mhu_rx"; + #mbox-cells = <1>; + mbox-name = "arm-es0-mhu0"; + }; + + mbox_es0mhu1: mhu@1b020000 { + compatible = "arm,mhuv2","arm,primecell"; + reg = <0x1b020000 0x1000>, + <0x1b030000 0x1000>; + clocks = <&refclk100mhz>; + clock-names = "apb_pclk"; + interrupts = <0 47 4>; + interrupt-names = "mhu_rx"; + #mbox-cells = <1>; + mbox-name = "arm-es0-mhu1"; + }; + + mbox_semhu1: mhu@1b820000 { + compatible = "arm,mhuv2","arm,primecell"; + reg = <0x1b820000 0x1000>, + <0x1b830000 0x1000>; + clocks = <&refclk100mhz>; + clock-names = "apb_pclk"; + interrupts = <0 45 4>; + interrupt-names = "mhu_rx"; + #mbox-cells = <1>; + mbox-name = "arm-se-mhu1"; + }; + + client { + compatible = "arm,client"; + mboxes = <&mbox_es0mhu0 0>, <&mbox_es0mhu1 0>, <&mbox_semhu1 0>; + mbox-names = "es0mhu0", "es0mhu1", "semhu1"; + }; + + extsys0: extsys@1A010310 { + compatible = "arm,extsys_ctrl"; + reg = <0x1A010310 0x4>, + <0x1A010314 0x4>; + reg-names = "rstreg", "streg"; + }; +}; diff --git a/fdts/corstone700_fpga.dts b/fdts/corstone700_fpga.dts new file mode 100644 index 000000000..814d6a862 --- /dev/null +++ b/fdts/corstone700_fpga.dts @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +#include "corstone700.dtsi" + +/ { + model = "corstone700-fpga"; + + ethernet: eth@40100000 { + compatible = "smsc,lan9115"; + reg = <0x40100000 0x10000>; + phy-mode = "mii"; + interrupt-parent = <&gic>; + interrupts = ; + reg-io-width = <2>; + smsc,irq-push-pull; + }; +}; + +&refclk { + clock-frequency = <32000000>; +}; diff --git a/fdts/corstone700_fvp.dts b/fdts/corstone700_fvp.dts new file mode 100644 index 000000000..3b1202d01 --- /dev/null +++ b/fdts/corstone700_fvp.dts @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +#include "corstone700.dtsi" + +/ { + model = "corstone700-fvp"; + + /* + * Intel StrataFlash J3 NOR flash: 2 x 16-bit interleaved components + * Flash total size: 32 MB + * Allocated flash space: 8 MB + */ + + flash@8500000 { + compatible = "cfi-flash"; + reg = <0x8500000 0x800000>; + bank-width = <4>; + device-width= <2>; + }; + + ethernet: eth@4010000 { + compatible = "smsc,lan91c111"; + reg = <0x40100000 0x10000>; + phy-mode = "mii"; + interrupt-parent = <&gic>; + interrupts = ; + reg-io-width = <2>; + smsc,irq-push-pull; + }; +}; + +&refclk { + clock-frequency = <50000000>; +}; diff --git a/plat/arm/board/corstone700/common/corstone700_helpers.S b/plat/arm/board/corstone700/common/corstone700_helpers.S new file mode 100644 index 000000000..c713f4f1a --- /dev/null +++ b/plat/arm/board/corstone700/common/corstone700_helpers.S @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2019, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#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); + * + * For AArch32, cold-booting secondary CPUs is not yet + * implemented and they panic. + * -------------------------------------------------------------------- + */ +func plat_secondary_cold_boot_setup +cb_panic: + b cb_panic +endfunc plat_secondary_cold_boot_setup + + /* --------------------------------------------------------------------- + * unsigned long plat_get_my_entrypoint (void); + * + * Main job of this routine is to distinguish between a cold and warm + * boot. On Corstone700, 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, Not yet supported. + * + * 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 + /* TODO support warm boot */ + /* Cold reset */ + mov r0, #0 + bx lr +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 + ldcopr r0, MPIDR + ldr r1, =MPIDR_AFFINITY_MASK + and r0, r1 + cmp r0, #0 + moveq r0, #1 + movne r0, #0 + bx lr +endfunc plat_is_my_cpu_primary + + /* --------------------------------------------------------------------- + * unsigned int plat_arm_calc_core_pos(u_register_t mpidr) + * + * Function to calculate the core position on Corstone700. + * + * (ClusterId * MAX_CPUS_PER_CLUSTER * MAX_PE_PER_CPU) + + * (CPUId * MAX_PE_PER_CPU) + + * ThreadId + * + * which can be simplified as: + * + * ((ClusterId * MAX_CPUS_PER_CLUSTER + CPUId) * MAX_PE_PER_CPU) + * + ThreadId + * --------------------------------------------------------------------- + */ +func plat_arm_calc_core_pos + mov r3, r0 + + /* Extract individual affinity fields from MPIDR */ + ubfx r0, r3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS + ubfx r1, r3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS + ubfx r2, r3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS + + /* Compute linear position */ + mov r3, #CORSTONE700_MAX_CPUS_PER_CLUSTER + mla r1, r2, r3, r1 + mov r3, #CORSTONE700_MAX_PE_PER_CPU + mla r0, r1, r3, r0 + + bx lr +endfunc plat_arm_calc_core_pos diff --git a/plat/arm/board/corstone700/common/corstone700_plat.c b/plat/arm/board/corstone700/common/corstone700_plat.c new file mode 100644 index 000000000..629f076ba --- /dev/null +++ b/plat/arm/board/corstone700/common/corstone700_plat.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include + +/* + * Table of regions to map using the MMU. + * Replace or extend the below regions as required + */ + +const mmap_region_t plat_arm_mmap[] = { + ARM_MAP_SHARED_RAM, + ARM_MAP_NS_SHARED_RAM, + ARM_MAP_NS_DRAM1, + CORSTONE700_MAP_DEVICE, + {0} +}; + +/* Corstone700 only has one always-on power domain and there + * is no power control present + */ +void __init plat_arm_pwrc_setup(void) +{ + mhu_secure_init(); +} + +unsigned int plat_get_syscnt_freq2(void) +{ + /* Returning the Generic Timer Frequency */ + return SYS_COUNTER_FREQ_IN_TICKS; +} diff --git a/plat/arm/board/corstone700/common/corstone700_pm.c b/plat/arm/board/corstone700/common/corstone700_pm.c new file mode 100644 index 000000000..4884ea519 --- /dev/null +++ b/plat/arm/board/corstone700/common/corstone700_pm.c @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2019, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +/******************************************************************************* + * Export the platform handlers via plat_arm_psci_pm_ops. The ARM Standard + * platform layer will take care of registering the handlers with PSCI. + ******************************************************************************/ +plat_psci_ops_t plat_arm_psci_pm_ops = { + /* dummy struct */ + .validate_ns_entrypoint = NULL +}; + +const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops) +{ + return ops; +} diff --git a/plat/arm/board/corstone700/common/corstone700_security.c b/plat/arm/board/corstone700/common/corstone700_security.c new file mode 100644 index 000000000..39b2fc902 --- /dev/null +++ b/plat/arm/board/corstone700/common/corstone700_security.c @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2019, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * We assume that all security programming is done by the primary core. + */ +void plat_arm_security_setup(void) +{ + /* + * If the platform had additional peripheral specific security + * configurations, those would be configured here. + */ +} diff --git a/plat/arm/board/corstone700/common/corstone700_stack_protector.c b/plat/arm/board/corstone700/common/corstone700_stack_protector.c new file mode 100644 index 000000000..6fd09da5b --- /dev/null +++ b/plat/arm/board/corstone700/common/corstone700_stack_protector.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include + +static uint32_t plat_generate_random_number(void) +{ + uintptr_t return_addr = (uintptr_t)__builtin_return_address(0U); + uintptr_t frame_addr = (uintptr_t)__builtin_frame_address(0U); + uint64_t cntpct = read_cntpct_el0(); + + /* Generate 32-bit pattern: saving the 2 least significant bytes + * in random_lo and random_hi + */ + uint16_t random_lo = (uint16_t)( + (((uint64_t)return_addr) << 13) ^ frame_addr ^ cntpct + ); + + uint16_t random_hi = (uint16_t)( + (((uint64_t)frame_addr) << 15) ^ return_addr ^ cntpct + ); + + return (((uint32_t)random_hi) << 16) | random_lo; +} + +u_register_t plat_get_stack_protector_canary(void) +{ + return plat_generate_random_number(); /* a 32-bit pattern is returned */ +} diff --git a/plat/arm/board/corstone700/common/corstone700_topology.c b/plat/arm/board/corstone700/common/corstone700_topology.c new file mode 100644 index 000000000..904f5ab3a --- /dev/null +++ b/plat/arm/board/corstone700/common/corstone700_topology.c @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +/* The Corstone700 power domain tree descriptor */ +static unsigned char corstone700_power_domain_tree_desc[PLAT_ARM_CLUSTER_COUNT + + 2]; +/******************************************************************************* + * This function dynamically constructs the topology according to + * CLUSTER_COUNT and returns it. + ******************************************************************************/ +const unsigned char *plat_get_power_domain_tree_desc(void) +{ + int i; + + /* + * The highest level is the system level. The next level is constituted + * by clusters and then cores in clusters. + */ + corstone700_power_domain_tree_desc[0] = 1; + corstone700_power_domain_tree_desc[1] = PLAT_ARM_CLUSTER_COUNT; + + for (i = 0; i < PLAT_ARM_CLUSTER_COUNT; i++) + corstone700_power_domain_tree_desc[i + 2] = PLATFORM_CORE_COUNT; + + return corstone700_power_domain_tree_desc; +} + +/****************************************************************************** + * This function implements a part of the critical interface between the PSCI + * generic layer and the platform that allows the former to query the platform + * to convert an MPIDR to a unique linear index. An error code (-1) is + * returned in case the MPIDR is invalid. + *****************************************************************************/ +int plat_core_pos_by_mpidr(u_register_t mpidr) +{ + return plat_arm_calc_core_pos(mpidr); +} diff --git a/plat/arm/board/corstone700/common/drivers/mhu/mhu.c b/plat/arm/board/corstone700/common/drivers/mhu/mhu.c new file mode 100644 index 000000000..2231d1173 --- /dev/null +++ b/plat/arm/board/corstone700/common/drivers/mhu/mhu.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2019-2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include +#include + +#include "mhu.h" +#include +#include + +ARM_INSTANTIATE_LOCK; + +#pragma weak plat_arm_pwrc_setup + +/* + * Slot 31 is reserved because the MHU hardware uses this register bit to + * indicate a non-secure access attempt. The total number of available slots is + * therefore 31 [30:0]. + */ +#define MHU_MAX_SLOT_ID 30 + +void mhu_secure_message_start(uintptr_t address, unsigned int slot_id) +{ + unsigned int intr_stat_check; + uint64_t timeout_cnt; + volatile uint8_t expiration; + + assert(slot_id <= MHU_MAX_SLOT_ID); + arm_lock_get(); + + /* + * Make sure any previous command has finished + * and polling timeout not expired + */ + + timeout_cnt = timeout_init_us(MHU_POLL_INTR_STAT_TIMEOUT); + + do { + intr_stat_check = (mmio_read_32(address + CPU_INTR_S_STAT) & + (1 << slot_id)); + + expiration = timeout_elapsed(timeout_cnt); + + } while ((intr_stat_check != 0U) && (expiration == 0U)); + + /* + * Note: No risk of timer overflows while waiting + * for the timeout expiration. + * According to Armv8 TRM: System counter roll-over + * time of not less than 40 years + */ +} + +void mhu_secure_message_send(uintptr_t address, + unsigned int slot_id, + unsigned int message) +{ + unsigned char access_ready; + uint64_t timeout_cnt; + volatile uint8_t expiration; + + assert(slot_id <= MHU_MAX_SLOT_ID); + assert((mmio_read_32(address + CPU_INTR_S_STAT) & + (1 << slot_id)) == 0U); + + MHU_V2_ACCESS_REQUEST(address); + + timeout_cnt = timeout_init_us(MHU_POLL_INTR_STAT_TIMEOUT); + + do { + access_ready = MHU_V2_IS_ACCESS_READY(address); + expiration = timeout_elapsed(timeout_cnt); + + } while ((access_ready == 0U) && (expiration == 0U)); + + /* + * Note: No risk of timer overflows while waiting + * for the timeout expiration. + * According to Armv8 TRM: System counter roll-over + * time of not less than 40 years + */ + + mmio_write_32(address + CPU_INTR_S_SET, message); +} + +void mhu_secure_message_end(uintptr_t address, unsigned int slot_id) +{ + assert(slot_id <= MHU_MAX_SLOT_ID); + /* + * Clear any response we got by writing one in the relevant slot bit to + * the CLEAR register + */ + MHU_V2_CLEAR_REQUEST(address); + + arm_lock_release(); +} + +void __init mhu_secure_init(void) +{ + arm_lock_init(); + + /* + * The STAT register resets to zero. Ensure it is in the expected state, + * as a stale or garbage value would make us think it's a message we've + * already sent. + */ + + assert(mmio_read_32(PLAT_SDK700_MHU0_SEND + CPU_INTR_S_STAT) == 0); +} diff --git a/plat/arm/board/corstone700/common/drivers/mhu/mhu.h b/plat/arm/board/corstone700/common/drivers/mhu/mhu.h new file mode 100644 index 000000000..3808746e9 --- /dev/null +++ b/plat/arm/board/corstone700/common/drivers/mhu/mhu.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2019-2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MHU_H +#define MHU_H + +#define MHU_POLL_INTR_STAT_TIMEOUT 50000 /*timeout value in us*/ + +/* CPU MHU secure channel registers */ +#define CPU_INTR_S_STAT 0x00 +#define CPU_INTR_S_SET 0x0C + +/* MHUv2 Control Registers Offsets */ +#define MHU_V2_MSG_CFG_OFFSET 0xF80 +#define MHU_V2_ACCESS_REQ_OFFSET 0xF88 +#define MHU_V2_ACCESS_READY_OFFSET 0xF8C + +#define MHU_V2_ACCESS_REQUEST(addr) \ + mmio_write_32((addr) + MHU_V2_ACCESS_REQ_OFFSET, 0x1) + +#define MHU_V2_CLEAR_REQUEST(addr) \ + mmio_write_32((addr) + MHU_V2_ACCESS_REQ_OFFSET, 0x0) + +#define MHU_V2_IS_ACCESS_READY(addr) \ + (mmio_read_32((addr) + MHU_V2_ACCESS_READY_OFFSET) & 0x1) + +void mhu_secure_message_start(uintptr_t address, unsigned int slot_id); +void mhu_secure_message_send(uintptr_t address, + unsigned int slot_id, + unsigned int message); +void mhu_secure_message_end(uintptr_t address, unsigned int slot_id); +void mhu_secure_init(void); + +#endif /* MHU_H */ diff --git a/plat/arm/board/corstone700/common/include/platform_def.h b/plat/arm/board/corstone700/common/include/platform_def.h new file mode 100644 index 000000000..c92086c18 --- /dev/null +++ b/plat/arm/board/corstone700/common/include/platform_def.h @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +#include +#include +#include +#include +#include +#include + +/* PL011 UART related constants */ +#ifdef V2M_IOFPGA_UART0_CLK_IN_HZ +#undef V2M_IOFPGA_UART0_CLK_IN_HZ +#endif + +#ifdef V2M_IOFPGA_UART1_CLK_IN_HZ +#undef V2M_IOFPGA_UART1_CLK_IN_HZ +#endif + +#define V2M_IOFPGA_UART0_CLK_IN_HZ 32000000 +#define V2M_IOFPGA_UART1_CLK_IN_HZ 32000000 + +/* Core/Cluster/Thread counts for Corstone700 */ +#define CORSTONE700_CLUSTER_COUNT U(1) +#define CORSTONE700_MAX_CPUS_PER_CLUSTER U(4) +#define CORSTONE700_MAX_PE_PER_CPU U(1) + +#define PLAT_ARM_CLUSTER_COUNT CORSTONE700_CLUSTER_COUNT + +#define PLATFORM_CORE_COUNT (PLAT_ARM_CLUSTER_COUNT * \ + CORSTONE700_MAX_CPUS_PER_CLUSTER * \ + CORSTONE700_MAX_PE_PER_CPU) + + +/* UART related constants */ +#define PLAT_ARM_BOOT_UART_BASE 0x1a510000 +#define PLAT_ARM_BOOT_UART_CLK_IN_HZ V2M_IOFPGA_UART0_CLK_IN_HZ +#define PLAT_ARM_RUN_UART_BASE 0x1a520000 +#define PLAT_ARM_RUN_UART_CLK_IN_HZ V2M_IOFPGA_UART1_CLK_IN_HZ +#define ARM_CONSOLE_BAUDRATE 115200 +#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 + +/* Memory related constants */ +#define ARM_DRAM1_BASE UL(0x80000000) +#define ARM_DRAM1_SIZE UL(0x80000000) +#define ARM_DRAM1_END (ARM_DRAM1_BASE + \ + ARM_DRAM1_SIZE - 1) +#define ARM_NS_DRAM1_BASE ARM_DRAM1_BASE +#define ARM_NS_DRAM1_SIZE ARM_DRAM1_SIZE +#define ARM_NS_DRAM1_END (ARM_NS_DRAM1_BASE + \ + ARM_NS_DRAM1_SIZE - 1) +#define ARM_TRUSTED_SRAM_BASE UL(0x02000000) +#define ARM_SHARED_RAM_BASE ARM_TRUSTED_SRAM_BASE +#define ARM_SHARED_RAM_SIZE UL(0x00001000) /* 4 KB */ +#define PLAT_ARM_TRUSTED_SRAM_SIZE 0x00040000 /* 256 KB */ + +/* The remaining Trusted SRAM is used to load the BL images */ +#define ARM_BL_RAM_BASE (ARM_SHARED_RAM_BASE + \ + ARM_SHARED_RAM_SIZE) +#define ARM_BL_RAM_SIZE (PLAT_ARM_TRUSTED_SRAM_SIZE - \ + ARM_SHARED_RAM_SIZE) + +#define ARM_NS_SHARED_RAM_BASE ARM_TRUSTED_SRAM_BASE + UL(0x00100000) +#define ARM_NS_SHARED_RAM_SIZE 0x00300000 + +/* + * SP_MIN is the only BL image in SRAM. Allocate the whole of SRAM (excluding + * the page reserved for fw_configs) to BL32 + */ +#define BL32_BASE (ARM_BL_RAM_BASE + PAGE_SIZE) +#define BL32_LIMIT (ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE) + +/* + * 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 (U(1) << ARM_CACHE_WRITEBACK_SHIFT) +#define ARM_CACHE_WRITEBACK_SHIFT 6 + +/* + * To enable FW_CONFIG to be loaded by BL1, define the corresponding base + * and limit. Leave enough space for BL2 meminfo. + */ +#define ARM_FW_CONFIG_BASE (ARM_BL_RAM_BASE + sizeof(meminfo_t)) +#define ARM_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + (PAGE_SIZE / 2U)) + +/* + * The max number of regions like RO(code), coherent and data required by + * different BL stages which need to be mapped in the MMU. + */ +#define ARM_BL_REGIONS 2 +#define PLAT_ARM_MMAP_ENTRIES 8 +#define MAX_XLAT_TABLES 5 +#define MAX_MMAP_REGIONS (PLAT_ARM_MMAP_ENTRIES + \ + ARM_BL_REGIONS) + +/* GIC related constants */ +#define PLAT_ARM_GICD_BASE 0x1C010000 +#define PLAT_ARM_GICC_BASE 0x1C02F000 + +/* MHUv2 Secure Channel receiver and sender */ +#define PLAT_SDK700_MHU0_SEND 0x1B800000 +#define PLAT_SDK700_MHU0_RECV 0x1B810000 + +/* Timer/watchdog related constants */ +#define ARM_SYS_CNTCTL_BASE UL(0x1a200000) +#define ARM_SYS_CNTREAD_BASE UL(0x1a210000) +#define ARM_SYS_TIMCTL_BASE UL(0x1a220000) + +#ifdef TARGET_PLATFORM_FVP +#define SYS_COUNTER_FREQ_IN_TICKS UL(50000000) /* 50MHz */ +#else +#define SYS_COUNTER_FREQ_IN_TICKS UL(32000000) /* 32MHz */ +#endif + +#define CORSTONE700_IRQ_TZ_WDOG 32 +#define CORSTONE700_IRQ_SEC_SYS_TIMER 34 + +#define PLAT_MAX_PWR_LVL 2 +/* + * Macros mapping the MPIDR Affinity levels to ARM Platform Power levels. The + * power levels have a 1:1 mapping with the MPIDR affinity levels. + */ +#define ARM_PWR_LVL0 MPIDR_AFFLVL0 +#define ARM_PWR_LVL1 MPIDR_AFFLVL1 +#define ARM_PWR_LVL2 MPIDR_AFFLVL2 + +/* + * Macros for local power states in ARM platforms encoded by State-ID field + * within the power-state parameter. + */ +/* Local power state for power domains in Run state. */ +#define ARM_LOCAL_STATE_RUN U(0) +/* Local power state for retention. Valid only for CPU power domains */ +#define ARM_LOCAL_STATE_RET U(1) +/* Local power state for OFF/power-down. Valid for CPU and cluster + * power domains + */ +#define ARM_LOCAL_STATE_OFF U(2) + +#define PLAT_ARM_TRUSTED_MAILBOX_BASE ARM_TRUSTED_SRAM_BASE +#define PLAT_ARM_NSTIMER_FRAME_ID U(1) + +#define PLAT_ARM_NS_IMAGE_BASE (ARM_NS_SHARED_RAM_BASE) + +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) + +/* + * 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 1 + +/* + * This macro defines the deepest power down states possible. Any state ID + * higher than this is invalid. + */ +#define PLAT_MAX_OFF_STATE 2 + +#define PLATFORM_STACK_SIZE UL(0x440) + +#define ARM_MAP_SHARED_RAM MAP_REGION_FLAT( \ + ARM_SHARED_RAM_BASE, \ + ARM_SHARED_RAM_SIZE, \ + MT_MEMORY | MT_RW | MT_SECURE) + +#define ARM_MAP_NS_SHARED_RAM MAP_REGION_FLAT( \ + ARM_NS_SHARED_RAM_BASE, \ + ARM_NS_SHARED_RAM_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_BL_RO MAP_REGION_FLAT( \ + BL_CODE_BASE, \ + BL_CODE_END \ + - BL_CODE_BASE, \ + MT_CODE | MT_SECURE), \ + MAP_REGION_FLAT( \ + BL_RO_DATA_BASE, \ + BL_RO_DATA_END \ + - BL_RO_DATA_BASE, \ + MT_RO_DATA | MT_SECURE) +#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) +#endif + +#define CORSTONE700_DEVICE_BASE (0x1A000000) +#define CORSTONE700_DEVICE_SIZE (0x26000000) +#define CORSTONE700_MAP_DEVICE MAP_REGION_FLAT( \ + CORSTONE700_DEVICE_BASE,\ + CORSTONE700_DEVICE_SIZE,\ + MT_DEVICE | MT_RW | MT_SECURE) + +#define ARM_IRQ_SEC_PHY_TIMER 29 + +#define ARM_IRQ_SEC_SGI_0 8 +#define ARM_IRQ_SEC_SGI_1 9 +#define ARM_IRQ_SEC_SGI_2 10 +#define ARM_IRQ_SEC_SGI_3 11 +#define ARM_IRQ_SEC_SGI_4 12 +#define ARM_IRQ_SEC_SGI_5 13 +#define ARM_IRQ_SEC_SGI_6 14 +#define ARM_IRQ_SEC_SGI_7 15 + +/* + * Define a list of Group 1 Secure and Group 0 interrupt properties as per GICv3 + * terminology. On a GICv2 system or mode, the lists will be merged and treated + * as Group 0 interrupts. + */ +#define ARM_G1S_IRQ_PROPS(grp) \ + INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, \ + (grp), GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, \ + (grp), GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, \ + (grp), GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, \ + (grp), GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, \ + (grp), GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, \ + (grp), GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, \ + (grp), GIC_INTR_CFG_EDGE) + +#define ARM_G0_IRQ_PROPS(grp) \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, (grp), \ + GIC_INTR_CFG_EDGE) + +/* + * Define a list 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_ARM_G1S_IRQ_PROPS(grp) \ + ARM_G1S_IRQ_PROPS(grp), \ + INTR_PROP_DESC(CORSTONE700_IRQ_TZ_WDOG, GIC_HIGHEST_SEC_PRIORITY, \ + (grp), GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(CORSTONE700_IRQ_SEC_SYS_TIMER, \ + GIC_HIGHEST_SEC_PRIORITY, (grp), GIC_INTR_CFG_LEVEL) + +#define PLAT_ARM_G0_IRQ_PROPS(grp) ARM_G0_IRQ_PROPS(grp) + +#endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/corstone700/corstone700_helpers.S b/plat/arm/board/corstone700/corstone700_helpers.S deleted file mode 100644 index c713f4f1a..000000000 --- a/plat/arm/board/corstone700/corstone700_helpers.S +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2019, Arm Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#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); - * - * For AArch32, cold-booting secondary CPUs is not yet - * implemented and they panic. - * -------------------------------------------------------------------- - */ -func plat_secondary_cold_boot_setup -cb_panic: - b cb_panic -endfunc plat_secondary_cold_boot_setup - - /* --------------------------------------------------------------------- - * unsigned long plat_get_my_entrypoint (void); - * - * Main job of this routine is to distinguish between a cold and warm - * boot. On Corstone700, 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, Not yet supported. - * - * 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 - /* TODO support warm boot */ - /* Cold reset */ - mov r0, #0 - bx lr -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 - ldcopr r0, MPIDR - ldr r1, =MPIDR_AFFINITY_MASK - and r0, r1 - cmp r0, #0 - moveq r0, #1 - movne r0, #0 - bx lr -endfunc plat_is_my_cpu_primary - - /* --------------------------------------------------------------------- - * unsigned int plat_arm_calc_core_pos(u_register_t mpidr) - * - * Function to calculate the core position on Corstone700. - * - * (ClusterId * MAX_CPUS_PER_CLUSTER * MAX_PE_PER_CPU) + - * (CPUId * MAX_PE_PER_CPU) + - * ThreadId - * - * which can be simplified as: - * - * ((ClusterId * MAX_CPUS_PER_CLUSTER + CPUId) * MAX_PE_PER_CPU) - * + ThreadId - * --------------------------------------------------------------------- - */ -func plat_arm_calc_core_pos - mov r3, r0 - - /* Extract individual affinity fields from MPIDR */ - ubfx r0, r3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS - ubfx r1, r3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS - ubfx r2, r3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS - - /* Compute linear position */ - mov r3, #CORSTONE700_MAX_CPUS_PER_CLUSTER - mla r1, r2, r3, r1 - mov r3, #CORSTONE700_MAX_PE_PER_CPU - mla r0, r1, r3, r0 - - bx lr -endfunc plat_arm_calc_core_pos diff --git a/plat/arm/board/corstone700/corstone700_plat.c b/plat/arm/board/corstone700/corstone700_plat.c deleted file mode 100644 index e2ade7098..000000000 --- a/plat/arm/board/corstone700/corstone700_plat.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include -#include -#include -#include - -/* - * Table of regions to map using the MMU. - * Replace or extend the below regions as required - */ - -const mmap_region_t plat_arm_mmap[] = { - ARM_MAP_SHARED_RAM, - ARM_MAP_NS_DRAM1, - CORSTONE700_MAP_DEVICE, - {0} -}; - -/* Corstone700 only has one always-on power domain and there - * is no power control present - */ -void __init plat_arm_pwrc_setup(void) -{ - mhu_secure_init(); -} - -unsigned int plat_get_syscnt_freq2(void) -{ - return CORSTONE700_TIMER_BASE_FREQUENCY; -} diff --git a/plat/arm/board/corstone700/corstone700_pm.c b/plat/arm/board/corstone700/corstone700_pm.c deleted file mode 100644 index 4884ea519..000000000 --- a/plat/arm/board/corstone700/corstone700_pm.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2019, Arm Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include - -/******************************************************************************* - * Export the platform handlers via plat_arm_psci_pm_ops. The ARM Standard - * platform layer will take care of registering the handlers with PSCI. - ******************************************************************************/ -plat_psci_ops_t plat_arm_psci_pm_ops = { - /* dummy struct */ - .validate_ns_entrypoint = NULL -}; - -const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops) -{ - return ops; -} diff --git a/plat/arm/board/corstone700/corstone700_security.c b/plat/arm/board/corstone700/corstone700_security.c deleted file mode 100644 index 39b2fc902..000000000 --- a/plat/arm/board/corstone700/corstone700_security.c +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2019, Arm Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * We assume that all security programming is done by the primary core. - */ -void plat_arm_security_setup(void) -{ - /* - * If the platform had additional peripheral specific security - * configurations, those would be configured here. - */ -} diff --git a/plat/arm/board/corstone700/corstone700_stack_protector.c b/plat/arm/board/corstone700/corstone700_stack_protector.c deleted file mode 100644 index 6fd09da5b..000000000 --- a/plat/arm/board/corstone700/corstone700_stack_protector.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include -#include - -static uint32_t plat_generate_random_number(void) -{ - uintptr_t return_addr = (uintptr_t)__builtin_return_address(0U); - uintptr_t frame_addr = (uintptr_t)__builtin_frame_address(0U); - uint64_t cntpct = read_cntpct_el0(); - - /* Generate 32-bit pattern: saving the 2 least significant bytes - * in random_lo and random_hi - */ - uint16_t random_lo = (uint16_t)( - (((uint64_t)return_addr) << 13) ^ frame_addr ^ cntpct - ); - - uint16_t random_hi = (uint16_t)( - (((uint64_t)frame_addr) << 15) ^ return_addr ^ cntpct - ); - - return (((uint32_t)random_hi) << 16) | random_lo; -} - -u_register_t plat_get_stack_protector_canary(void) -{ - return plat_generate_random_number(); /* a 32-bit pattern is returned */ -} diff --git a/plat/arm/board/corstone700/corstone700_topology.c b/plat/arm/board/corstone700/corstone700_topology.c deleted file mode 100644 index 904f5ab3a..000000000 --- a/plat/arm/board/corstone700/corstone700_topology.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include - -/* The Corstone700 power domain tree descriptor */ -static unsigned char corstone700_power_domain_tree_desc[PLAT_ARM_CLUSTER_COUNT - + 2]; -/******************************************************************************* - * This function dynamically constructs the topology according to - * CLUSTER_COUNT and returns it. - ******************************************************************************/ -const unsigned char *plat_get_power_domain_tree_desc(void) -{ - int i; - - /* - * The highest level is the system level. The next level is constituted - * by clusters and then cores in clusters. - */ - corstone700_power_domain_tree_desc[0] = 1; - corstone700_power_domain_tree_desc[1] = PLAT_ARM_CLUSTER_COUNT; - - for (i = 0; i < PLAT_ARM_CLUSTER_COUNT; i++) - corstone700_power_domain_tree_desc[i + 2] = PLATFORM_CORE_COUNT; - - return corstone700_power_domain_tree_desc; -} - -/****************************************************************************** - * This function implements a part of the critical interface between the PSCI - * generic layer and the platform that allows the former to query the platform - * to convert an MPIDR to a unique linear index. An error code (-1) is - * returned in case the MPIDR is invalid. - *****************************************************************************/ -int plat_core_pos_by_mpidr(u_register_t mpidr) -{ - return plat_arm_calc_core_pos(mpidr); -} diff --git a/plat/arm/board/corstone700/drivers/mhu/mhu.c b/plat/arm/board/corstone700/drivers/mhu/mhu.c deleted file mode 100644 index 2231d1173..000000000 --- a/plat/arm/board/corstone700/drivers/mhu/mhu.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2019-2020, ARM Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include -#include -#include -#include -#include - -#include "mhu.h" -#include -#include - -ARM_INSTANTIATE_LOCK; - -#pragma weak plat_arm_pwrc_setup - -/* - * Slot 31 is reserved because the MHU hardware uses this register bit to - * indicate a non-secure access attempt. The total number of available slots is - * therefore 31 [30:0]. - */ -#define MHU_MAX_SLOT_ID 30 - -void mhu_secure_message_start(uintptr_t address, unsigned int slot_id) -{ - unsigned int intr_stat_check; - uint64_t timeout_cnt; - volatile uint8_t expiration; - - assert(slot_id <= MHU_MAX_SLOT_ID); - arm_lock_get(); - - /* - * Make sure any previous command has finished - * and polling timeout not expired - */ - - timeout_cnt = timeout_init_us(MHU_POLL_INTR_STAT_TIMEOUT); - - do { - intr_stat_check = (mmio_read_32(address + CPU_INTR_S_STAT) & - (1 << slot_id)); - - expiration = timeout_elapsed(timeout_cnt); - - } while ((intr_stat_check != 0U) && (expiration == 0U)); - - /* - * Note: No risk of timer overflows while waiting - * for the timeout expiration. - * According to Armv8 TRM: System counter roll-over - * time of not less than 40 years - */ -} - -void mhu_secure_message_send(uintptr_t address, - unsigned int slot_id, - unsigned int message) -{ - unsigned char access_ready; - uint64_t timeout_cnt; - volatile uint8_t expiration; - - assert(slot_id <= MHU_MAX_SLOT_ID); - assert((mmio_read_32(address + CPU_INTR_S_STAT) & - (1 << slot_id)) == 0U); - - MHU_V2_ACCESS_REQUEST(address); - - timeout_cnt = timeout_init_us(MHU_POLL_INTR_STAT_TIMEOUT); - - do { - access_ready = MHU_V2_IS_ACCESS_READY(address); - expiration = timeout_elapsed(timeout_cnt); - - } while ((access_ready == 0U) && (expiration == 0U)); - - /* - * Note: No risk of timer overflows while waiting - * for the timeout expiration. - * According to Armv8 TRM: System counter roll-over - * time of not less than 40 years - */ - - mmio_write_32(address + CPU_INTR_S_SET, message); -} - -void mhu_secure_message_end(uintptr_t address, unsigned int slot_id) -{ - assert(slot_id <= MHU_MAX_SLOT_ID); - /* - * Clear any response we got by writing one in the relevant slot bit to - * the CLEAR register - */ - MHU_V2_CLEAR_REQUEST(address); - - arm_lock_release(); -} - -void __init mhu_secure_init(void) -{ - arm_lock_init(); - - /* - * The STAT register resets to zero. Ensure it is in the expected state, - * as a stale or garbage value would make us think it's a message we've - * already sent. - */ - - assert(mmio_read_32(PLAT_SDK700_MHU0_SEND + CPU_INTR_S_STAT) == 0); -} diff --git a/plat/arm/board/corstone700/drivers/mhu/mhu.h b/plat/arm/board/corstone700/drivers/mhu/mhu.h deleted file mode 100644 index 3808746e9..000000000 --- a/plat/arm/board/corstone700/drivers/mhu/mhu.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2019-2020, ARM Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef MHU_H -#define MHU_H - -#define MHU_POLL_INTR_STAT_TIMEOUT 50000 /*timeout value in us*/ - -/* CPU MHU secure channel registers */ -#define CPU_INTR_S_STAT 0x00 -#define CPU_INTR_S_SET 0x0C - -/* MHUv2 Control Registers Offsets */ -#define MHU_V2_MSG_CFG_OFFSET 0xF80 -#define MHU_V2_ACCESS_REQ_OFFSET 0xF88 -#define MHU_V2_ACCESS_READY_OFFSET 0xF8C - -#define MHU_V2_ACCESS_REQUEST(addr) \ - mmio_write_32((addr) + MHU_V2_ACCESS_REQ_OFFSET, 0x1) - -#define MHU_V2_CLEAR_REQUEST(addr) \ - mmio_write_32((addr) + MHU_V2_ACCESS_REQ_OFFSET, 0x0) - -#define MHU_V2_IS_ACCESS_READY(addr) \ - (mmio_read_32((addr) + MHU_V2_ACCESS_READY_OFFSET) & 0x1) - -void mhu_secure_message_start(uintptr_t address, unsigned int slot_id); -void mhu_secure_message_send(uintptr_t address, - unsigned int slot_id, - unsigned int message); -void mhu_secure_message_end(uintptr_t address, unsigned int slot_id); -void mhu_secure_init(void); - -#endif /* MHU_H */ diff --git a/plat/arm/board/corstone700/include/platform_def.h b/plat/arm/board/corstone700/include/platform_def.h deleted file mode 100644 index 7799cec00..000000000 --- a/plat/arm/board/corstone700/include/platform_def.h +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef PLATFORM_DEF_H -#define PLATFORM_DEF_H - -#include -#include -#include -#include -#include -#include - -/* PL011 UART related constants */ -#ifdef V2M_IOFPGA_UART0_CLK_IN_HZ -#undef V2M_IOFPGA_UART0_CLK_IN_HZ -#endif - -#ifdef V2M_IOFPGA_UART1_CLK_IN_HZ -#undef V2M_IOFPGA_UART1_CLK_IN_HZ -#endif - -#define V2M_IOFPGA_UART0_CLK_IN_HZ 32000000 -#define V2M_IOFPGA_UART1_CLK_IN_HZ 32000000 - -/* Core/Cluster/Thread counts for Corstone700 */ -#define CORSTONE700_CLUSTER_COUNT U(1) -#define CORSTONE700_MAX_CPUS_PER_CLUSTER U(4) -#define CORSTONE700_MAX_PE_PER_CPU U(1) - -#define PLAT_ARM_CLUSTER_COUNT CORSTONE700_CLUSTER_COUNT - -#define PLATFORM_CORE_COUNT (PLAT_ARM_CLUSTER_COUNT * \ - CORSTONE700_MAX_CPUS_PER_CLUSTER * \ - CORSTONE700_MAX_PE_PER_CPU) - - -/* UART related constants */ -#define PLAT_ARM_BOOT_UART_BASE 0x1a510000 -#define PLAT_ARM_BOOT_UART_CLK_IN_HZ V2M_IOFPGA_UART0_CLK_IN_HZ -#define PLAT_ARM_RUN_UART_BASE 0x1a520000 -#define PLAT_ARM_RUN_UART_CLK_IN_HZ V2M_IOFPGA_UART1_CLK_IN_HZ -#define ARM_CONSOLE_BAUDRATE 115200 -#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 - -/* Memory related constants */ -#define ARM_DRAM1_BASE UL(0x80000000) -#define ARM_DRAM1_SIZE UL(0x80000000) -#define ARM_DRAM1_END (ARM_DRAM1_BASE + \ - ARM_DRAM1_SIZE - 1) -#define ARM_NS_DRAM1_BASE ARM_DRAM1_BASE -#define ARM_NS_DRAM1_SIZE ARM_DRAM1_SIZE -#define ARM_NS_DRAM1_END (ARM_NS_DRAM1_BASE + \ - ARM_NS_DRAM1_SIZE - 1) -#define ARM_TRUSTED_SRAM_BASE UL(0x02000000) -#define ARM_SHARED_RAM_BASE ARM_TRUSTED_SRAM_BASE -#define ARM_SHARED_RAM_SIZE UL(0x00001000) /* 4 KB */ -#define PLAT_ARM_TRUSTED_SRAM_SIZE 0x00040000 /* 256 KB */ - -/* The remaining Trusted SRAM is used to load the BL images */ -#define ARM_BL_RAM_BASE (ARM_SHARED_RAM_BASE + \ - ARM_SHARED_RAM_SIZE) -#define ARM_BL_RAM_SIZE (PLAT_ARM_TRUSTED_SRAM_SIZE - \ - ARM_SHARED_RAM_SIZE) - -/* - * SP_MIN is the only BL image in SRAM. Allocate the whole of SRAM (excluding - * the page reserved for fw_configs) to BL32 - */ -#define BL32_BASE (ARM_BL_RAM_BASE + PAGE_SIZE) -#define BL32_LIMIT (ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE) - -/* - * 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 (U(1) << ARM_CACHE_WRITEBACK_SHIFT) -#define ARM_CACHE_WRITEBACK_SHIFT 6 - -/* - * To enable FW_CONFIG to be loaded by BL1, define the corresponding base - * and limit. Leave enough space for BL2 meminfo. - */ -#define ARM_FW_CONFIG_BASE (ARM_BL_RAM_BASE + sizeof(meminfo_t)) -#define ARM_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + (PAGE_SIZE / 2U)) - -/* - * The max number of regions like RO(code), coherent and data required by - * different BL stages which need to be mapped in the MMU. - */ -#define ARM_BL_REGIONS 2 -#define PLAT_ARM_MMAP_ENTRIES 8 -#define MAX_XLAT_TABLES 5 -#define MAX_MMAP_REGIONS (PLAT_ARM_MMAP_ENTRIES + \ - ARM_BL_REGIONS) - -/* GIC related constants */ -#define PLAT_ARM_GICD_BASE 0x1C010000 -#define PLAT_ARM_GICC_BASE 0x1C02F000 - -/* MHUv2 Secure Channel receiver and sender */ -#define PLAT_SDK700_MHU0_SEND 0x1B800000 -#define PLAT_SDK700_MHU0_RECV 0x1B810000 - -/* Timer/watchdog related constants */ -#define ARM_SYS_CNTCTL_BASE UL(0x1a200000) -#define ARM_SYS_CNTREAD_BASE UL(0x1a210000) -#define ARM_SYS_TIMCTL_BASE UL(0x1a220000) -#define CORSTONE700_TIMER_BASE_FREQUENCY UL(24000000) -#define CORSTONE700_IRQ_TZ_WDOG 32 -#define CORSTONE700_IRQ_SEC_SYS_TIMER 34 - -#define PLAT_MAX_PWR_LVL 2 -/* - * Macros mapping the MPIDR Affinity levels to ARM Platform Power levels. The - * power levels have a 1:1 mapping with the MPIDR affinity levels. - */ -#define ARM_PWR_LVL0 MPIDR_AFFLVL0 -#define ARM_PWR_LVL1 MPIDR_AFFLVL1 -#define ARM_PWR_LVL2 MPIDR_AFFLVL2 - -/* - * Macros for local power states in ARM platforms encoded by State-ID field - * within the power-state parameter. - */ -/* Local power state for power domains in Run state. */ -#define ARM_LOCAL_STATE_RUN U(0) -/* Local power state for retention. Valid only for CPU power domains */ -#define ARM_LOCAL_STATE_RET U(1) -/* Local power state for OFF/power-down. Valid for CPU and cluster - * power domains - */ -#define ARM_LOCAL_STATE_OFF U(2) - -#define PLAT_ARM_TRUSTED_MAILBOX_BASE ARM_TRUSTED_SRAM_BASE -#define PLAT_ARM_NSTIMER_FRAME_ID U(1) - -#define PLAT_ARM_NS_IMAGE_OFFSET (ARM_DRAM1_BASE + UL(0x8000000)) - -#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) -#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) - -/* - * 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 1 - -/* - * This macro defines the deepest power down states possible. Any state ID - * higher than this is invalid. - */ -#define PLAT_MAX_OFF_STATE 2 - -#define PLATFORM_STACK_SIZE UL(0x440) - -#define ARM_MAP_SHARED_RAM MAP_REGION_FLAT( \ - ARM_SHARED_RAM_BASE, \ - ARM_SHARED_RAM_SIZE, \ - MT_DEVICE | MT_RW | MT_SECURE) - -#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_BL_RO MAP_REGION_FLAT( \ - BL_CODE_BASE, \ - BL_CODE_END \ - - BL_CODE_BASE, \ - MT_CODE | MT_SECURE), \ - MAP_REGION_FLAT( \ - BL_RO_DATA_BASE, \ - BL_RO_DATA_END \ - - BL_RO_DATA_BASE, \ - MT_RO_DATA | MT_SECURE) -#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) -#endif - -#define CORSTONE700_DEVICE_BASE (0x1A000000) -#define CORSTONE700_DEVICE_SIZE (0x26000000) -#define CORSTONE700_MAP_DEVICE MAP_REGION_FLAT( \ - CORSTONE700_DEVICE_BASE,\ - CORSTONE700_DEVICE_SIZE,\ - MT_DEVICE | MT_RW | MT_SECURE) - -#define ARM_IRQ_SEC_PHY_TIMER 29 - -#define ARM_IRQ_SEC_SGI_0 8 -#define ARM_IRQ_SEC_SGI_1 9 -#define ARM_IRQ_SEC_SGI_2 10 -#define ARM_IRQ_SEC_SGI_3 11 -#define ARM_IRQ_SEC_SGI_4 12 -#define ARM_IRQ_SEC_SGI_5 13 -#define ARM_IRQ_SEC_SGI_6 14 -#define ARM_IRQ_SEC_SGI_7 15 - -/* - * Define a list of Group 1 Secure and Group 0 interrupt properties as per GICv3 - * terminology. On a GICv2 system or mode, the lists will be merged and treated - * as Group 0 interrupts. - */ -#define ARM_G1S_IRQ_PROPS(grp) \ - INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, \ - (grp), GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(ARM_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, \ - (grp), GIC_INTR_CFG_EDGE), \ - INTR_PROP_DESC(ARM_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, \ - (grp), GIC_INTR_CFG_EDGE), \ - INTR_PROP_DESC(ARM_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, \ - (grp), GIC_INTR_CFG_EDGE), \ - INTR_PROP_DESC(ARM_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, \ - (grp), GIC_INTR_CFG_EDGE), \ - INTR_PROP_DESC(ARM_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, \ - (grp), GIC_INTR_CFG_EDGE), \ - INTR_PROP_DESC(ARM_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, \ - (grp), GIC_INTR_CFG_EDGE) - -#define ARM_G0_IRQ_PROPS(grp) \ - INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, (grp), \ - GIC_INTR_CFG_EDGE) - -/* - * Define a list 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_ARM_G1S_IRQ_PROPS(grp) \ - ARM_G1S_IRQ_PROPS(grp), \ - INTR_PROP_DESC(CORSTONE700_IRQ_TZ_WDOG, GIC_HIGHEST_SEC_PRIORITY, \ - (grp), GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(CORSTONE700_IRQ_SEC_SYS_TIMER, \ - GIC_HIGHEST_SEC_PRIORITY, (grp), GIC_INTR_CFG_LEVEL) - -#define PLAT_ARM_G0_IRQ_PROPS(grp) ARM_G0_IRQ_PROPS(grp) - -#endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/corstone700/platform.mk b/plat/arm/board/corstone700/platform.mk index a4d4f2227..3398fba2c 100644 --- a/plat/arm/board/corstone700/platform.mk +++ b/plat/arm/board/corstone700/platform.mk @@ -4,6 +4,11 @@ # SPDX-License-Identifier: BSD-3-Clause # +# Making sure the corstone700 platform type is specified +ifeq ($(filter ${TARGET_PLATFORM}, fpga fvp),) + $(error TARGET_PLATFORM must be fpga or fvp) +endif + CORSTONE700_CPU_LIBS += lib/cpus/aarch32/cortex_a32.S BL32_SOURCES += plat/arm/common/aarch32/arm_helpers.S \ @@ -12,11 +17,11 @@ BL32_SOURCES += plat/arm/common/aarch32/arm_helpers.S \ lib/xlat_tables/aarch32/xlat_tables.c \ lib/xlat_tables/xlat_tables_common.c \ ${CORSTONE700_CPU_LIBS} \ - plat/arm/board/corstone700/drivers/mhu/mhu.c + plat/arm/board/corstone700/common/drivers/mhu/mhu.c -PLAT_INCLUDES := -Iplat/arm/board/corstone700/include \ +PLAT_INCLUDES := -Iplat/arm/board/corstone700/common/include \ -Iinclude/plat/arm/common \ - -Iplat/arm/board/corstone700/drivers/mhu + -Iplat/arm/board/corstone700/common/drivers/mhu NEED_BL32 := yes @@ -30,13 +35,14 @@ CORSTONE700_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ override NEED_BL1 := no override NEED_BL2 := no override NEED_BL2U := no +override NEED_BL33 := yes #TFA for Corstone700 starts from BL32 override RESET_TO_SP_MIN := 1 #Device tree -CORSTONE700_HW_CONFIG_DTS := fdts/corstone700.dts -CORSTONE700_HW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}.dtb +CORSTONE700_HW_CONFIG_DTS := fdts/corstone700_${TARGET_PLATFORM}.dts +CORSTONE700_HW_CONFIG := ${BUILD_PLAT}/fdts/corstone700_${TARGET_PLATFORM}.dtb FDT_SOURCES += ${CORSTONE700_HW_CONFIG_DTS} $(eval CORSTONE700_HW_CONFIG := ${BUILD_PLAT}/$(patsubst %.dts,%.dtb,$(CORSTONE700_HW_CONFIG_DTS))) @@ -49,4 +55,8 @@ $(eval $(call add_define,ARM_LINUX_KERNEL_AS_BL33)) $(error "ARM_PRELOADED_DTB_BASE must be set if ARM_LINUX_KERNEL_AS_BL33 is used.") endif $(eval $(call add_define,ARM_PRELOADED_DTB_BASE)) + +# Adding TARGET_PLATFORM as a GCC define (-D option) +$(eval $(call add_define,TARGET_PLATFORM_$(call uppercase,${TARGET_PLATFORM}))) + include plat/arm/board/common/board_common.mk diff --git a/plat/arm/board/corstone700/sp_min/sp_min-corstone700.mk b/plat/arm/board/corstone700/sp_min/sp_min-corstone700.mk index acee6c39c..75dc0f10c 100644 --- a/plat/arm/board/corstone700/sp_min/sp_min-corstone700.mk +++ b/plat/arm/board/corstone700/sp_min/sp_min-corstone700.mk @@ -7,17 +7,17 @@ # SP_MIN source files specific to FVP platform BL32_SOURCES += drivers/cfi/v2m/v2m_flash.c \ lib/utils/mem_region.c \ - plat/arm/board/corstone700/corstone700_helpers.S \ - plat/arm/board/corstone700/corstone700_topology.c \ - plat/arm/board/corstone700/corstone700_security.c \ - plat/arm/board/corstone700/corstone700_plat.c \ - plat/arm/board/corstone700/corstone700_pm.c \ + plat/arm/board/corstone700/common/corstone700_helpers.S \ + plat/arm/board/corstone700/common/corstone700_topology.c \ + plat/arm/board/corstone700/common/corstone700_security.c \ + plat/arm/board/corstone700/common/corstone700_plat.c \ + plat/arm/board/corstone700/common/corstone700_pm.c \ plat/arm/board/corstone700/sp_min/corstone700_sp_min_setup.c \ ${CORSTONE700_GIC_SOURCES} ifneq (${ENABLE_STACK_PROTECTOR},0) ifneq (${ENABLE_STACK_PROTECTOR},none) - BL32_SOURCES += plat/arm/board/corstone700/corstone700_stack_protector.c + BL32_SOURCES += plat/arm/board/corstone700/common/corstone700_stack_protector.c endif endif -- cgit v1.2.3 From 8e570b71d8773bcf220253e39d48f1fa00ec4aaa Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Sun, 5 Jul 2020 13:12:28 -0700 Subject: drivers: arm: gicv3: auto-detect presence of GIC600-AE This patch adds the IIDR value for GIC600-AE to the gicv3_is_gic600() helper function. This helps platforms supporting this version of the GIC600 interrupt controller to function with the generic GIC driver. Verified with tftf-validation test suite ******************************* Summary ******************************* > Test suite 'Framework Validation' Passed > Test suite 'Timer framework Validation' Passed ================================= Tests Skipped : 0 Tests Passed : 6 Tests Failed : 0 Tests Crashed : 0 Total tests : 6 ================================= NOTICE: Exiting tests. Signed-off-by: Varun Wadekar Change-Id: I518ae7b56f7f372e374e453287d76ca370fc3574 --- drivers/arm/gic/v3/gic-x00.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/drivers/arm/gic/v3/gic-x00.c b/drivers/arm/gic/v3/gic-x00.c index c1a9f0dc1..cc9717451 100644 --- a/drivers/arm/gic/v3/gic-x00.c +++ b/drivers/arm/gic/v3/gic-x00.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -20,26 +21,27 @@ #include "gicv3_private.h" /* GIC-600 specific register offsets */ -#define GICR_PWRR 0x24 -#define IIDR_MODEL_ARM_GIC_600 0x0200043b +#define GICR_PWRR 0x24 +#define IIDR_MODEL_ARM_GIC_600 (0x0200043b) +#define IIDR_MODEL_ARM_GIC_600AE (0x0300043b) /* GICR_PWRR fields */ -#define PWRR_RDPD_SHIFT 0 -#define PWRR_RDAG_SHIFT 1 -#define PWRR_RDGPD_SHIFT 2 -#define PWRR_RDGPO_SHIFT 3 +#define PWRR_RDPD_SHIFT 0 +#define PWRR_RDAG_SHIFT 1 +#define PWRR_RDGPD_SHIFT 2 +#define PWRR_RDGPO_SHIFT 3 -#define PWRR_RDPD (1 << PWRR_RDPD_SHIFT) -#define PWRR_RDAG (1 << PWRR_RDAG_SHIFT) -#define PWRR_RDGPD (1 << PWRR_RDGPD_SHIFT) -#define PWRR_RDGPO (1 << PWRR_RDGPO_SHIFT) +#define PWRR_RDPD (1 << PWRR_RDPD_SHIFT) +#define PWRR_RDAG (1 << PWRR_RDAG_SHIFT) +#define PWRR_RDGPD (1 << PWRR_RDGPD_SHIFT) +#define PWRR_RDGPO (1 << PWRR_RDGPO_SHIFT) /* * Values to write to GICR_PWRR register to power redistributor * for operating through the core (GICR_PWRR.RDAG = 0) */ -#define PWRR_ON (0 << PWRR_RDPD_SHIFT) -#define PWRR_OFF (1 << PWRR_RDPD_SHIFT) +#define PWRR_ON (0 << PWRR_RDPD_SHIFT) +#define PWRR_OFF (1 << PWRR_RDPD_SHIFT) #if GICV3_SUPPORT_GIC600 @@ -115,7 +117,8 @@ static bool gicv3_is_gic600(uintptr_t gicr_base) { uint32_t reg = mmio_read_32(gicr_base + GICR_IIDR); - return (reg & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_600; + return (((reg & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_600) || + ((reg & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_600AE)); } #endif -- cgit v1.2.3 From a2150c33edf50a41e99df76eab6eeab9fd9b9215 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Wed, 13 May 2020 15:51:56 +0200 Subject: stm32mp1: shared resources: add trace messages Define from helper functions to get a human readable string identifier from a shared resource enumerated ID. Use them to make debug traces more friendly peripheral registering functions. Change-Id: I9e207b8ce1d1e9250e242ca7e15461b9a1532f40 Signed-off-by: Etienne Carriere --- plat/st/stm32mp1/stm32mp1_shared_resources.c | 53 +++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 5 deletions(-) diff --git a/plat/st/stm32mp1/stm32mp1_shared_resources.c b/plat/st/stm32mp1/stm32mp1_shared_resources.c index 268aa52c3..d4ab39d3c 100644 --- a/plat/st/stm32mp1/stm32mp1_shared_resources.c +++ b/plat/st/stm32mp1/stm32mp1_shared_resources.c @@ -44,6 +44,49 @@ enum shres_state { /* Force uint8_t array for array of enum shres_state for size considerations */ static uint8_t shres_state[STM32MP1_SHRES_COUNT]; +static const char *shres2str_id_tbl[STM32MP1_SHRES_COUNT] __unused = { + [STM32MP1_SHRES_GPIOZ(0)] = "GPIOZ0", + [STM32MP1_SHRES_GPIOZ(1)] = "GPIOZ1", + [STM32MP1_SHRES_GPIOZ(2)] = "GPIOZ2", + [STM32MP1_SHRES_GPIOZ(3)] = "GPIOZ3", + [STM32MP1_SHRES_GPIOZ(4)] = "GPIOZ4", + [STM32MP1_SHRES_GPIOZ(5)] = "GPIOZ5", + [STM32MP1_SHRES_GPIOZ(6)] = "GPIOZ6", + [STM32MP1_SHRES_GPIOZ(7)] = "GPIOZ7", + [STM32MP1_SHRES_IWDG1] = "IWDG1", + [STM32MP1_SHRES_USART1] = "USART1", + [STM32MP1_SHRES_SPI6] = "SPI6", + [STM32MP1_SHRES_I2C4] = "I2C4", + [STM32MP1_SHRES_RNG1] = "RNG1", + [STM32MP1_SHRES_HASH1] = "HASH1", + [STM32MP1_SHRES_CRYP1] = "CRYP1", + [STM32MP1_SHRES_I2C6] = "I2C6", + [STM32MP1_SHRES_RTC] = "RTC", + [STM32MP1_SHRES_MCU] = "MCU", + [STM32MP1_SHRES_MDMA] = "MDMA", + [STM32MP1_SHRES_PLL3] = "PLL3", +}; + +static const char __unused *shres2str_id(enum stm32mp_shres id) +{ + assert(id < ARRAY_SIZE(shres2str_id_tbl)); + + return shres2str_id_tbl[id]; +} + +static const char __unused *shres2str_state_tbl[] = { + [SHRES_UNREGISTERED] = "unregistered", + [SHRES_NON_SECURE] = "non-secure", + [SHRES_SECURE] = "secure", +}; + +static const char __unused *shres2str_state(unsigned int state) +{ + assert(state < ARRAY_SIZE(shres2str_state_tbl)); + + return shres2str_state_tbl[state]; +} + /* Get resource state: these accesses lock the registering support */ static void lock_registering(void) { @@ -170,10 +213,10 @@ static void check_rcc_secure_configuration(void) } if (!secure || (mckprot_protects_periph(n) && (!mckprot))) { - ERROR("RCC %s MCKPROT %s and %u secure\n", + ERROR("RCC %s MCKPROT %s and %s secure\n", secure ? "secure" : "non-secure", mckprot ? "set" : "not set", - n); + shres2str_id(n)); error++; } } @@ -201,14 +244,14 @@ static void print_shared_resources_state(void) for (id = 0U; id < STM32MP1_SHRES_COUNT; id++) { switch (shres_state[id]) { case SHRES_SECURE: - INFO("stm32mp1 %u is secure\n", id); + INFO("stm32mp1 %s is secure\n", shres2str_id(id)); break; case SHRES_NON_SECURE: case SHRES_UNREGISTERED: - VERBOSE("stm32mp %u is non-secure\n", id); + VERBOSE("stm32mp %s is non-secure\n", shres2str_id(id)); break; default: - VERBOSE("stm32mp %u is invalid\n", id); + VERBOSE("stm32mp %s is invalid\n", shres2str_id(id)); panic(); } } -- cgit v1.2.3 From 37e8295abdc96831dc1ee983c41bad94770628f5 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Wed, 13 May 2020 11:49:49 +0200 Subject: drivers: st: clock: register parent of secure clocks Introduce stm32mp1_register_clock_parents_secure() in stm32mp1 clock driver to allow platform shared resources to register as secure the parent clocks of a clock registered as secure. Change-Id: I53a9ab6aa78ee840ededce67e7b12a84e08ee843 Signed-off-by: Etienne Carriere --- drivers/st/clk/stm32mp1_clk.c | 196 ++++++++++++++++++++++++++++++++++++++ include/drivers/st/stm32mp1_clk.h | 3 + 2 files changed, 199 insertions(+) diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c index 2f4dcadfc..d6cd8b1ce 100644 --- a/drivers/st/clk/stm32mp1_clk.c +++ b/drivers/st/clk/stm32mp1_clk.c @@ -577,6 +577,43 @@ static const uint8_t stm32mp1_axi_div[8] = { 1, 2, 3, 4, 4, 4, 4, 4 }; +static const char * const stm32mp1_clk_parent_name[_PARENT_NB] __unused = { + [_HSI] = "HSI", + [_HSE] = "HSE", + [_CSI] = "CSI", + [_LSI] = "LSI", + [_LSE] = "LSE", + [_I2S_CKIN] = "I2S_CKIN", + [_HSI_KER] = "HSI_KER", + [_HSE_KER] = "HSE_KER", + [_HSE_KER_DIV2] = "HSE_KER_DIV2", + [_CSI_KER] = "CSI_KER", + [_PLL1_P] = "PLL1_P", + [_PLL1_Q] = "PLL1_Q", + [_PLL1_R] = "PLL1_R", + [_PLL2_P] = "PLL2_P", + [_PLL2_Q] = "PLL2_Q", + [_PLL2_R] = "PLL2_R", + [_PLL3_P] = "PLL3_P", + [_PLL3_Q] = "PLL3_Q", + [_PLL3_R] = "PLL3_R", + [_PLL4_P] = "PLL4_P", + [_PLL4_Q] = "PLL4_Q", + [_PLL4_R] = "PLL4_R", + [_ACLK] = "ACLK", + [_PCLK1] = "PCLK1", + [_PCLK2] = "PCLK2", + [_PCLK3] = "PCLK3", + [_PCLK4] = "PCLK4", + [_PCLK5] = "PCLK5", + [_HCLK6] = "KCLK6", + [_HCLK2] = "HCLK2", + [_CK_PER] = "CK_PER", + [_CK_MPU] = "CK_MPU", + [_CK_MCU] = "CK_MCU", + [_USB_PHY_48] = "USB_PHY_48", +}; + /* RCC clock device driver private */ static unsigned long stm32mp1_osc[NB_OSC]; static struct spinlock reg_lock; @@ -2007,6 +2044,165 @@ static void stm32mp1_osc_init(void) } } +#ifdef STM32MP_SHARED_RESOURCES +/* + * Get the parent ID of the target parent clock, for tagging as secure + * shared clock dependencies. + */ +static int get_parent_id_parent(unsigned int parent_id) +{ + enum stm32mp1_parent_sel s = _UNKNOWN_SEL; + enum stm32mp1_pll_id pll_id; + uint32_t p_sel; + uintptr_t rcc_base = stm32mp_rcc_base(); + + switch (parent_id) { + case _ACLK: + case _PCLK4: + case _PCLK5: + s = _AXIS_SEL; + break; + case _PLL1_P: + case _PLL1_Q: + case _PLL1_R: + pll_id = _PLL1; + break; + case _PLL2_P: + case _PLL2_Q: + case _PLL2_R: + pll_id = _PLL2; + break; + case _PLL3_P: + case _PLL3_Q: + case _PLL3_R: + pll_id = _PLL3; + break; + case _PLL4_P: + case _PLL4_Q: + case _PLL4_R: + pll_id = _PLL4; + break; + case _PCLK1: + case _PCLK2: + case _HCLK2: + case _HCLK6: + case _CK_PER: + case _CK_MPU: + case _CK_MCU: + case _USB_PHY_48: + /* We do not expect to access these */ + panic(); + break; + default: + /* Other parents have no parent */ + return -1; + } + + if (s != _UNKNOWN_SEL) { + const struct stm32mp1_clk_sel *sel = clk_sel_ref(s); + + p_sel = (mmio_read_32(rcc_base + sel->offset) >> sel->src) & + sel->msk; + + if (p_sel < sel->nb_parent) { + return (int)sel->parent[p_sel]; + } + } else { + const struct stm32mp1_clk_pll *pll = pll_ref(pll_id); + + p_sel = mmio_read_32(rcc_base + pll->rckxselr) & + RCC_SELR_REFCLK_SRC_MASK; + + if (pll->refclk[p_sel] != _UNKNOWN_OSC_ID) { + return (int)pll->refclk[p_sel]; + } + } + + VERBOSE("No parent selected for %s\n", + stm32mp1_clk_parent_name[parent_id]); + + return -1; +} + +static void secure_parent_clocks(unsigned long parent_id) +{ + int grandparent_id; + + switch (parent_id) { + case _PLL3_P: + case _PLL3_Q: + case _PLL3_R: + stm32mp_register_secure_periph(STM32MP1_SHRES_PLL3); + break; + + /* These clocks are always secure when RCC is secure */ + case _ACLK: + case _HCLK2: + case _HCLK6: + case _PCLK4: + case _PCLK5: + case _PLL1_P: + case _PLL1_Q: + case _PLL1_R: + case _PLL2_P: + case _PLL2_Q: + case _PLL2_R: + case _HSI: + case _HSI_KER: + case _LSI: + case _CSI: + case _CSI_KER: + case _HSE: + case _HSE_KER: + case _HSE_KER_DIV2: + case _LSE: + break; + + default: + VERBOSE("Cannot secure parent clock %s\n", + stm32mp1_clk_parent_name[parent_id]); + panic(); + } + + grandparent_id = get_parent_id_parent(parent_id); + if (grandparent_id >= 0) { + secure_parent_clocks(grandparent_id); + } +} + +void stm32mp1_register_clock_parents_secure(unsigned long clock_id) +{ + int parent_id; + + if (!stm32mp1_rcc_is_secure()) { + return; + } + + switch (clock_id) { + case PLL1: + case PLL2: + /* PLL1/PLL2 are always secure: nothing to do */ + break; + case PLL3: + stm32mp_register_secure_periph(STM32MP1_SHRES_PLL3); + break; + case PLL4: + ERROR("PLL4 cannot be secured\n"); + panic(); + break; + default: + /* Others are expected gateable clock */ + parent_id = stm32mp1_clk_get_parent(clock_id); + if (parent_id < 0) { + INFO("No parent found for clock %lu\n", clock_id); + } else { + secure_parent_clocks(parent_id); + } + break; + } +} +#endif /* STM32MP_SHARED_RESOURCES */ + static void sync_earlyboot_clocks_state(void) { unsigned int idx; diff --git a/include/drivers/st/stm32mp1_clk.h b/include/drivers/st/stm32mp1_clk.h index 1ebd39ff7..c46892b78 100644 --- a/include/drivers/st/stm32mp1_clk.h +++ b/include/drivers/st/stm32mp1_clk.h @@ -59,4 +59,7 @@ void stm32mp1_clk_rcc_regs_unlock(void); void stm32mp1_stgen_increment(unsigned long long offset_in_ms); +#ifdef STM32MP_SHARED_RESOURCES +void stm32mp1_register_clock_parents_secure(unsigned long id); +#endif #endif /* STM32MP1_CLK_H */ -- cgit v1.2.3 From 68450c9437bde3a20de65347aed7c2124ae4e021 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Wed, 13 May 2020 14:22:01 +0200 Subject: stm32mp1: shared resources: peripheral registering Define helper functions stm32mp_register_secure_periph() and stm32mp_register_non_secure_periph() for platform drivers to register a shared resource assigned to respectively secure or non-secure world. Some resources are related to clock resources. When a resource is registered as secure, ensure its clock dependencies are also registered as secure. Registering a non-secure resource does not mandate its clock dependencies are also registered as non-secure. Change-Id: I74975be8976b8d3bf18dcc807541a072803af6e3 Signed-off-by: Etienne Carriere --- plat/st/common/include/stm32mp_shared_resources.h | 11 ++- plat/st/stm32mp1/stm32mp1_shared_resources.c | 98 +++++++++++++++++++++++ 2 files changed, 108 insertions(+), 1 deletion(-) diff --git a/plat/st/common/include/stm32mp_shared_resources.h b/plat/st/common/include/stm32mp_shared_resources.h index b1486667f..220593685 100644 --- a/plat/st/common/include/stm32mp_shared_resources.h +++ b/plat/st/common/include/stm32mp_shared_resources.h @@ -9,13 +9,22 @@ #include +#ifdef STM32MP_SHARED_RESOURCES +enum stm32mp_shres; + /* Return true if @clock_id is shared by secure and non-secure worlds */ bool stm32mp_nsec_can_access_clock(unsigned long clock_id); /* Return true if and only if @reset_id relates to a non-secure peripheral */ bool stm32mp_nsec_can_access_reset(unsigned int reset_id); +/* Register a shared resource assigned to the secure world */ +void stm32mp_register_secure_periph(enum stm32mp_shres id); + +/* Register a shared resource assigned to the non-secure world */ +void stm32mp_register_non_secure_periph(enum stm32mp_shres id); + /* Consolidate peripheral states and lock against new peripheral registering */ void stm32mp_lock_periph_registering(void); - +#endif /* STM32MP_SHARED_RESOURCES */ #endif /* STM32MP_SHARED_RESOURCES_H */ diff --git a/plat/st/stm32mp1/stm32mp1_shared_resources.c b/plat/st/stm32mp1/stm32mp1_shared_resources.c index d4ab39d3c..158393b0d 100644 --- a/plat/st/stm32mp1/stm32mp1_shared_resources.c +++ b/plat/st/stm32mp1/stm32mp1_shared_resources.c @@ -135,6 +135,104 @@ static unsigned int get_gpioz_nbpin(void) return get_gpio_nbpin(GPIO_BANK_Z); } +static void register_periph(enum stm32mp_shres id, unsigned int state) +{ + assert((id < STM32MP1_SHRES_COUNT) && + ((state == SHRES_SECURE) || (state == SHRES_NON_SECURE))); + + if (registering_locked) { + if (shres_state[id] == state) { + return; + } + panic(); + } + + if ((shres_state[id] != SHRES_UNREGISTERED) && + (shres_state[id] != state)) { + VERBOSE("Cannot change %s from %s to %s\n", + shres2str_id(id), + shres2str_state(shres_state[id]), + shres2str_state(state)); + panic(); + } + + if (shres_state[id] == SHRES_UNREGISTERED) { + VERBOSE("Register %s as %s\n", + shres2str_id(id), shres2str_state(state)); + } + + if ((id >= STM32MP1_SHRES_GPIOZ(0)) && + (id <= STM32MP1_SHRES_GPIOZ(7)) && + ((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(); + } + + shres_state[id] = (uint8_t)state; + + /* Explore clock tree to lock dependencies */ + if (state == SHRES_SECURE) { + enum stm32mp_shres clock_res_id; + + switch (id) { + case STM32MP1_SHRES_GPIOZ(0): + case STM32MP1_SHRES_GPIOZ(1): + case STM32MP1_SHRES_GPIOZ(2): + case STM32MP1_SHRES_GPIOZ(3): + case STM32MP1_SHRES_GPIOZ(4): + case STM32MP1_SHRES_GPIOZ(5): + case STM32MP1_SHRES_GPIOZ(6): + case STM32MP1_SHRES_GPIOZ(7): + clock_res_id = GPIOZ; + break; + case STM32MP1_SHRES_IWDG1: + clock_res_id = IWDG1; + break; + case STM32MP1_SHRES_USART1: + clock_res_id = USART1_K; + break; + case STM32MP1_SHRES_SPI6: + clock_res_id = SPI6_K; + break; + case STM32MP1_SHRES_I2C4: + clock_res_id = I2C4_K; + break; + case STM32MP1_SHRES_RNG1: + clock_res_id = RNG1_K; + break; + case STM32MP1_SHRES_HASH1: + clock_res_id = HASH1; + break; + case STM32MP1_SHRES_CRYP1: + clock_res_id = CRYP1; + break; + case STM32MP1_SHRES_I2C6: + clock_res_id = I2C6_K; + break; + case STM32MP1_SHRES_RTC: + clock_res_id = RTC; + break; + default: + /* No clock resource dependency */ + return; + } + + stm32mp1_register_clock_parents_secure(clock_res_id); + } +} + +/* Register resource by ID */ +void stm32mp_register_secure_periph(enum stm32mp_shres id) +{ + register_periph(id, SHRES_SECURE); +} + +void stm32mp_register_non_secure_periph(enum stm32mp_shres id) +{ + register_periph(id, SHRES_NON_SECURE); +} + /* Currently allow full access by non-secure to platform clock services */ bool stm32mp_nsec_can_access_clock(unsigned long clock_id) { -- cgit v1.2.3 From 082c773131354ead8f3d98ec424f7493684f00e0 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Wed, 13 May 2020 10:20:34 +0200 Subject: stm32mp1: allow non-secure access to clocks upon periph registration Update implementation of stm32mp_nsec_can_access_clock() based on the registering of the shared resources. Querying registering state locks further registration of peripherals. Change-Id: If68f6d4a52c4742ba66244c6ea2d9afa08404137 Signed-off-by: Etienne Carriere --- plat/st/stm32mp1/stm32mp1_shared_resources.c | 77 +++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 2 deletions(-) diff --git a/plat/st/stm32mp1/stm32mp1_shared_resources.c b/plat/st/stm32mp1/stm32mp1_shared_resources.c index 158393b0d..22f8605df 100644 --- a/plat/st/stm32mp1/stm32mp1_shared_resources.c +++ b/plat/st/stm32mp1/stm32mp1_shared_resources.c @@ -233,10 +233,83 @@ void stm32mp_register_non_secure_periph(enum stm32mp_shres id) register_periph(id, SHRES_NON_SECURE); } -/* Currently allow full access by non-secure to platform clock services */ +static bool stm32mp_gpio_bank_is_secure(unsigned int bank) +{ + unsigned int secure = 0U; + unsigned int i; + + lock_registering(); + + if (bank != GPIO_BANK_Z) { + return false; + } + + for (i = 0U; i < get_gpioz_nbpin(); i++) { + if (periph_is_secure(STM32MP1_SHRES_GPIOZ(i))) { + secure++; + } + } + + return secure == get_gpioz_nbpin(); +} + bool stm32mp_nsec_can_access_clock(unsigned long clock_id) { - return true; + enum stm32mp_shres shres_id = STM32MP1_SHRES_COUNT; + + switch (clock_id) { + case CK_CSI: + case CK_HSE: + case CK_HSE_DIV2: + case CK_HSI: + case CK_LSE: + case CK_LSI: + case PLL1_P: + case PLL1_Q: + case PLL1_R: + case PLL2_P: + case PLL2_Q: + case PLL2_R: + case PLL3_P: + case PLL3_Q: + case PLL3_R: + case RTCAPB: + return true; + case GPIOZ: + /* Allow clock access if at least one pin is non-secure */ + return !stm32mp_gpio_bank_is_secure(GPIO_BANK_Z); + case CRYP1: + shres_id = STM32MP1_SHRES_CRYP1; + break; + case HASH1: + shres_id = STM32MP1_SHRES_HASH1; + break; + case I2C4_K: + shres_id = STM32MP1_SHRES_I2C4; + break; + case I2C6_K: + shres_id = STM32MP1_SHRES_I2C6; + break; + case IWDG1: + shres_id = STM32MP1_SHRES_IWDG1; + break; + case RNG1_K: + shres_id = STM32MP1_SHRES_RNG1; + break; + case RTC: + shres_id = STM32MP1_SHRES_RTC; + break; + case SPI6_K: + shres_id = STM32MP1_SHRES_SPI6; + break; + case USART1_K: + shres_id = STM32MP1_SHRES_USART1; + break; + default: + return false; + } + + return periph_is_non_secure(shres_id); } /* Currently allow full access by non-secure to platform reset services */ -- cgit v1.2.3 From b2707a6968deb8be29e3db1aa2e207aad242a95b Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Wed, 13 May 2020 13:53:15 +0200 Subject: stm32mp1: allow non-secure access to reset upon periph registration Update implementation of stm32mp_nsec_can_access_reset() based on the registering of the shared resources. Querying registering state locks further registration of peripherals. Change-Id: I5f38f2a3481780b9a71939d95984c4821c537aa4 Signed-off-by: Etienne Carriere --- plat/st/stm32mp1/stm32mp1_shared_resources.c | 60 +++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/plat/st/stm32mp1/stm32mp1_shared_resources.c b/plat/st/stm32mp1/stm32mp1_shared_resources.c index 22f8605df..6d778ad59 100644 --- a/plat/st/stm32mp1/stm32mp1_shared_resources.c +++ b/plat/st/stm32mp1/stm32mp1_shared_resources.c @@ -233,6 +233,26 @@ void stm32mp_register_non_secure_periph(enum stm32mp_shres id) register_periph(id, SHRES_NON_SECURE); } +static bool stm32mp_gpio_bank_is_non_secure(unsigned int bank) +{ + unsigned int non_secure = 0U; + unsigned int i; + + lock_registering(); + + if (bank != GPIO_BANK_Z) { + return true; + } + + for (i = 0U; i < get_gpioz_nbpin(); i++) { + if (periph_is_non_secure(STM32MP1_SHRES_GPIOZ(i))) { + non_secure++; + } + } + + return non_secure == get_gpioz_nbpin(); +} + static bool stm32mp_gpio_bank_is_secure(unsigned int bank) { unsigned int secure = 0U; @@ -312,10 +332,46 @@ bool stm32mp_nsec_can_access_clock(unsigned long clock_id) return periph_is_non_secure(shres_id); } -/* Currently allow full access by non-secure to platform reset services */ bool stm32mp_nsec_can_access_reset(unsigned int reset_id) { - return true; + enum stm32mp_shres shres_id = STM32MP1_SHRES_COUNT; + + switch (reset_id) { + case CRYP1_R: + shres_id = STM32MP1_SHRES_CRYP1; + break; + case GPIOZ_R: + /* GPIOZ reset mandates all pins are non-secure */ + return stm32mp_gpio_bank_is_non_secure(GPIO_BANK_Z); + case HASH1_R: + shres_id = STM32MP1_SHRES_HASH1; + break; + case I2C4_R: + shres_id = STM32MP1_SHRES_I2C4; + break; + case I2C6_R: + shres_id = STM32MP1_SHRES_I2C6; + break; + case MCU_R: + shres_id = STM32MP1_SHRES_MCU; + break; + case MDMA_R: + shres_id = STM32MP1_SHRES_MDMA; + break; + case RNG1_R: + shres_id = STM32MP1_SHRES_RNG1; + break; + case SPI6_R: + shres_id = STM32MP1_SHRES_SPI6; + break; + case USART1_R: + shres_id = STM32MP1_SHRES_USART1; + break; + default: + return false; + } + + return periph_is_non_secure(shres_id); } static bool mckprot_protects_periph(enum stm32mp_shres id) -- cgit v1.2.3 From 0651b5b77ab3dcf526f6979ec631eb7781d4dad5 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Wed, 13 May 2020 10:16:21 +0200 Subject: stm32mp1: register shared resource per IOMEM address Introduce helper functions stm32mp_register_secure_periph_iomem() and stm32mp_register_non_secure_periph_iomem() for drivers to register a resource as secure or non-secure based on its SoC interface registers base address. These functions are stubbed when shared resources driver is not embedded (!STM32MP_SHARED_RESOURCES) so that drivers embedded in other BL stages do not bother whether they shall register or not their resources. Change-Id: Icebd05a930afc5964bc4677357da5d1b23666066 Signed-off-by: Etienne Carriere --- plat/st/common/include/stm32mp_shared_resources.h | 14 ++++ plat/st/stm32mp1/stm32mp1_def.h | 14 ++-- plat/st/stm32mp1/stm32mp1_shared_resources.c | 78 +++++++++++++++++++++++ 3 files changed, 100 insertions(+), 6 deletions(-) diff --git a/plat/st/common/include/stm32mp_shared_resources.h b/plat/st/common/include/stm32mp_shared_resources.h index 220593685..3160db0dc 100644 --- a/plat/st/common/include/stm32mp_shared_resources.h +++ b/plat/st/common/include/stm32mp_shared_resources.h @@ -8,6 +8,7 @@ #define STM32MP_SHARED_RESOURCES_H #include +#include #ifdef STM32MP_SHARED_RESOURCES enum stm32mp_shres; @@ -24,7 +25,20 @@ void stm32mp_register_secure_periph(enum stm32mp_shres id); /* Register a shared resource assigned to the non-secure world */ void stm32mp_register_non_secure_periph(enum stm32mp_shres id); +/* Register a peripheral as secure or non-secure based on IO base address */ +void stm32mp_register_secure_periph_iomem(uintptr_t base); +void stm32mp_register_non_secure_periph_iomem(uintptr_t base); + /* Consolidate peripheral states and lock against new peripheral registering */ void stm32mp_lock_periph_registering(void); +#else +static inline void stm32mp_register_secure_periph_iomem(uintptr_t base __unused) +{ +} + +static inline +void stm32mp_register_non_secure_periph_iomem(uintptr_t base __unused) +{ +} #endif /* STM32MP_SHARED_RESOURCES */ #endif /* STM32MP_SHARED_RESOURCES_H */ diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h index ef82d5edf..bce599447 100644 --- a/plat/st/stm32mp1/stm32mp1_def.h +++ b/plat/st/stm32mp1/stm32mp1_def.h @@ -494,14 +494,16 @@ static inline uint32_t tamp_bkpr(uint32_t idx) #define IWDG2_BASE U(0x5A002000) /******************************************************************************* - * STM32MP1 I2C4 - ******************************************************************************/ -#define I2C4_BASE U(0x5C002000) - -/******************************************************************************* - * STM32MP1 DBGMCU + * Miscellaneous STM32MP1 peripherals base address ******************************************************************************/ +#define CRYP1_BASE U(0x54001000) #define DBGMCU_BASE U(0x50081000) +#define HASH1_BASE U(0x54002000) +#define I2C4_BASE U(0x5C002000) +#define I2C6_BASE U(0x5c009000) +#define RNG1_BASE U(0x54003000) +#define RTC_BASE U(0x5c004000) +#define SPI6_BASE U(0x5c001000) /******************************************************************************* * Device Tree defines diff --git a/plat/st/stm32mp1/stm32mp1_shared_resources.c b/plat/st/stm32mp1/stm32mp1_shared_resources.c index 6d778ad59..32e61d9cd 100644 --- a/plat/st/stm32mp1/stm32mp1_shared_resources.c +++ b/plat/st/stm32mp1/stm32mp1_shared_resources.c @@ -233,6 +233,84 @@ void stm32mp_register_non_secure_periph(enum stm32mp_shres id) register_periph(id, SHRES_NON_SECURE); } +static void register_periph_iomem(uintptr_t base, unsigned int state) +{ + enum stm32mp_shres id; + + switch (base) { + case CRYP1_BASE: + id = STM32MP1_SHRES_CRYP1; + break; + case HASH1_BASE: + id = STM32MP1_SHRES_HASH1; + break; + case I2C4_BASE: + id = STM32MP1_SHRES_I2C4; + break; + case I2C6_BASE: + id = STM32MP1_SHRES_I2C6; + break; + case IWDG1_BASE: + id = STM32MP1_SHRES_IWDG1; + break; + case RNG1_BASE: + id = STM32MP1_SHRES_RNG1; + break; + case RTC_BASE: + id = STM32MP1_SHRES_RTC; + break; + case SPI6_BASE: + id = STM32MP1_SHRES_SPI6; + break; + case USART1_BASE: + id = STM32MP1_SHRES_USART1; + break; + + case GPIOA_BASE: + case GPIOB_BASE: + case GPIOC_BASE: + case GPIOD_BASE: + case GPIOE_BASE: + case GPIOF_BASE: + case GPIOG_BASE: + case GPIOH_BASE: + case GPIOI_BASE: + case GPIOJ_BASE: + case GPIOK_BASE: + case USART2_BASE: + case USART3_BASE: + case UART4_BASE: + case UART5_BASE: + case USART6_BASE: + case UART7_BASE: + case UART8_BASE: + case IWDG2_BASE: + /* Allow drivers to register some non-secure resources */ + VERBOSE("IO for non-secure resource 0x%x\n", + (unsigned int)base); + if (state != SHRES_NON_SECURE) { + panic(); + } + + return; + + default: + panic(); + } + + register_periph(id, state); +} + +void stm32mp_register_secure_periph_iomem(uintptr_t base) +{ + register_periph_iomem(base, SHRES_SECURE); +} + +void stm32mp_register_non_secure_periph_iomem(uintptr_t base) +{ + register_periph_iomem(base, SHRES_NON_SECURE); +} + static bool stm32mp_gpio_bank_is_non_secure(unsigned int bank) { unsigned int non_secure = 0U; -- cgit v1.2.3 From ec8f4212ac68da5b60bf9e180b5ace42482d4e39 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Wed, 13 May 2020 10:19:50 +0200 Subject: stm32mp1: register shared resource per GPIO bank/pin Introduce helper functions stm32mp_register_secure_gpio() and stm32mp_register_non_secure_gpio() for drivers to register a GPIO pin as secure or non-secure. These functions are stubbed when shared resource driver is not embedded in the BL image so that drivers do not bother whether they shall register or not their resources. Change-Id: I1fe98576c072ae31f75427c9ac5c9f6c4f1b6ed1 Signed-off-by: Etienne Carriere --- plat/st/common/include/stm32mp_shared_resources.h | 14 ++++++++++++++ plat/st/stm32mp1/stm32mp1_shared_resources.c | 23 +++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/plat/st/common/include/stm32mp_shared_resources.h b/plat/st/common/include/stm32mp_shared_resources.h index 3160db0dc..13f4b137a 100644 --- a/plat/st/common/include/stm32mp_shared_resources.h +++ b/plat/st/common/include/stm32mp_shared_resources.h @@ -29,6 +29,10 @@ void stm32mp_register_non_secure_periph(enum stm32mp_shres id); void stm32mp_register_secure_periph_iomem(uintptr_t base); void stm32mp_register_non_secure_periph_iomem(uintptr_t base); +/* Register a GPIO as secure or non-secure based on its bank and pin numbers */ +void stm32mp_register_secure_gpio(unsigned int bank, unsigned int pin); +void stm32mp_register_non_secure_gpio(unsigned int bank, unsigned int pin); + /* Consolidate peripheral states and lock against new peripheral registering */ void stm32mp_lock_periph_registering(void); #else @@ -40,5 +44,15 @@ static inline void stm32mp_register_non_secure_periph_iomem(uintptr_t base __unused) { } + +static inline void stm32mp_register_secure_gpio(unsigned int bank __unused, + unsigned int pin __unused) +{ +} + +static inline void stm32mp_register_non_secure_gpio(unsigned int bank __unused, + unsigned int pin __unused) +{ +} #endif /* STM32MP_SHARED_RESOURCES */ #endif /* STM32MP_SHARED_RESOURCES_H */ diff --git a/plat/st/stm32mp1/stm32mp1_shared_resources.c b/plat/st/stm32mp1/stm32mp1_shared_resources.c index 32e61d9cd..208e34a8b 100644 --- a/plat/st/stm32mp1/stm32mp1_shared_resources.c +++ b/plat/st/stm32mp1/stm32mp1_shared_resources.c @@ -311,6 +311,29 @@ void stm32mp_register_non_secure_periph_iomem(uintptr_t base) register_periph_iomem(base, SHRES_NON_SECURE); } +void stm32mp_register_secure_gpio(unsigned int bank, unsigned int pin) +{ + switch (bank) { + case GPIO_BANK_Z: + register_periph(STM32MP1_SHRES_GPIOZ(pin), SHRES_SECURE); + break; + default: + ERROR("GPIO bank %u cannot be secured\n", bank); + panic(); + } +} + +void stm32mp_register_non_secure_gpio(unsigned int bank, unsigned int pin) +{ + switch (bank) { + case GPIO_BANK_Z: + register_periph(STM32MP1_SHRES_GPIOZ(pin), SHRES_NON_SECURE); + break; + default: + break; + } +} + static bool stm32mp_gpio_bank_is_non_secure(unsigned int bank) { unsigned int non_secure = 0U; -- cgit v1.2.3 From f564d439a957b96de24cc3c2e2bb5f2e8a052384 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Mon, 2 Dec 2019 10:10:08 +0100 Subject: drivers/stm32mp_pmic: register PMIC resources as secure or not Register in the shared resources driver the secure or non-secure state of the PMIC. Change-Id: Ic1f172ba62785018f8e9bb321782d725e2d2f434 Signed-off-by: Etienne Carriere --- drivers/st/pmic/stm32mp_pmic.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/st/pmic/stm32mp_pmic.c b/drivers/st/pmic/stm32mp_pmic.c index 9e9dddc4d..b2bb482f9 100644 --- a/drivers/st/pmic/stm32mp_pmic.c +++ b/drivers/st/pmic/stm32mp_pmic.c @@ -54,6 +54,15 @@ int dt_pmic_status(void) return fdt_get_status(node); } +static bool dt_pmic_is_secure(void) +{ + int status = dt_pmic_status(); + + return (status >= 0) && + (status == DT_SECURE) && + (i2c_handle.dt_status == DT_SECURE); +} + /* * Get PMIC and its I2C bus configuration from the device tree. * Return 0 on success, negative on error, 1 if no PMIC node is found. @@ -223,6 +232,19 @@ bool initialize_pmic_i2c(void) return true; } +static void register_pmic_shared_peripherals(void) +{ + uintptr_t i2c_base = i2c_handle.i2c_base_addr; + + if (dt_pmic_is_secure()) { + stm32mp_register_secure_periph_iomem(i2c_base); + } else { + if (i2c_base != 0U) { + stm32mp_register_non_secure_periph_iomem(i2c_base); + } + } +} + void initialize_pmic(void) { unsigned long pmic_version; @@ -232,6 +254,8 @@ void initialize_pmic(void) return; } + register_pmic_shared_peripherals(); + if (stpmic1_get_version(&pmic_version) != 0) { ERROR("Failed to access PMIC\n"); panic(); -- cgit v1.2.3 From bcc360f7e0dfd9933d45cbdca1245d8634487751 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Mon, 2 Dec 2019 10:10:36 +0100 Subject: drivers/stm32_iwdg: register IWDG resources as secure or not Register in the shared resources driver the secure or non-secure state of the IWDG instances. Change-Id: I3a3bc9525447f6a2a465891ca3a3fd5fe664ca07 Signed-off-by: Etienne Carriere --- drivers/st/iwdg/stm32_iwdg.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/st/iwdg/stm32_iwdg.c b/drivers/st/iwdg/stm32_iwdg.c index ea6fbb2b9..c052b4dfb 100644 --- a/drivers/st/iwdg/stm32_iwdg.c +++ b/drivers/st/iwdg/stm32_iwdg.c @@ -137,6 +137,12 @@ int stm32_iwdg_init(void) ((dt_info.status & DT_NON_SECURE) != 0) ? "non-" : ""); + if ((dt_info.status & DT_NON_SECURE) != 0) { + stm32mp_register_non_secure_periph_iomem(iwdg->base); + } else { + stm32mp_register_secure_periph_iomem(iwdg->base); + } + #if defined(IMAGE_BL2) if (stm32_iwdg_shadow_update(idx, iwdg->flags) != BSEC_OK) { return -1; -- cgit v1.2.3 From 66de6f3c30b223b40f31d321a18f50d446898e66 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Mon, 2 Dec 2019 10:11:32 +0100 Subject: drivers/stm32_gpio: register GPIO resources as secure or not Register in the shared resources driver the secure or non-secure state of the GPIO pins. Change-Id: Ifda473bcbbb0af799be6587961d6641edf887605 Signed-off-by: Etienne Carriere --- drivers/st/gpio/stm32_gpio.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/st/gpio/stm32_gpio.c b/drivers/st/gpio/stm32_gpio.c index a13c341a8..bb77371bf 100644 --- a/drivers/st/gpio/stm32_gpio.c +++ b/drivers/st/gpio/stm32_gpio.c @@ -254,6 +254,15 @@ void set_gpio(uint32_t bank, uint32_t pin, uint32_t mode, uint32_t speed, mmio_read_32(base + GPIO_AFRH_OFFSET)); stm32mp_clk_disable(clock); + + if (status == DT_SECURE) { + stm32mp_register_secure_gpio(bank, pin); + set_gpio_secure_cfg(bank, pin, true); + + } else { + stm32mp_register_non_secure_gpio(bank, pin); + set_gpio_secure_cfg(bank, pin, false); + } } void set_gpio_secure_cfg(uint32_t bank, uint32_t pin, bool secure) -- cgit v1.2.3 From 3d0d0a1b4c9a995042bbfda0165ac59ed3bad873 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Mon, 2 Dec 2019 10:13:12 +0100 Subject: drivers/stm32_hash: register resources as secure or not Register in the shared resources driver the secure or non-secure state of the HASH instances. Note that only BL32 needs to register the shared peripheral because BL2 does not embed the shared resources driver. Change-Id: I7f78fa8e47da71d48ef8b1dfe4d6f040fe918d8b Signed-off-by: Etienne Carriere --- drivers/st/crypto/stm32_hash.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/st/crypto/stm32_hash.c b/drivers/st/crypto/stm32_hash.c index 3184df9de..515947c10 100644 --- a/drivers/st/crypto/stm32_hash.c +++ b/drivers/st/crypto/stm32_hash.c @@ -300,7 +300,9 @@ int stm32_hash_register(void) break; } #else + /* BL32 uses hash if it is assigned only to secure world */ if (hash_info.status == DT_SECURE) { + stm32mp_register_secure_periph_iomem(hash_info.base); break; } #endif -- cgit v1.2.3 From b5fb69173b82d1c60ae9614eb27ebfa37ba8b38a Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Tue, 30 Jun 2020 04:04:05 +0100 Subject: doc: Update CoT binding to make it more generic Updated the CoT binding document to show chain of trust relationship with the help of 'authentication method' and 'authentication data' instead of showing content of certificate and fixed rendering issue while creating html page using this document. Signed-off-by: Manish V Badarkhe Change-Id: Ib48279cfe786d149ab69ddc711caa381a50f9e2b --- docs/components/cot-binding.rst | 257 +++++++++++++++++++++++----------------- 1 file changed, 149 insertions(+), 108 deletions(-) diff --git a/docs/components/cot-binding.rst b/docs/components/cot-binding.rst index cc69d79b4..46915db23 100644 --- a/docs/components/cot-binding.rst +++ b/docs/components/cot-binding.rst @@ -1,23 +1,23 @@ Chain of trust bindings ======================= -The device tree allows to describes the chain of trust with the help of -certificates and images nodes, which in turn contains number of sub-nodes -(i.e. certificate and image) mentioning properties for every certificate -and image respectively. -Also, this binding allows to describe OID of non-volatile counters, memory -mapped address and size of non-volatile counter register. +The device tree allows to describe the chain of trust with the help of +'cot' node which contain 'manifests' and 'images' as sub-nodes. +'manifests' and 'images' nodes contains number of sub-nodes (i.e. 'certificate' +and 'image' nodes) mentioning properties of the certificate and image respectively. -Convention used in this document --------------------------------- +Also, device tree describes 'non-volatile-counters' node which contains number of +sub-nodes mentioning properties of all non-volatile-counters used in the chain of trust. -This document follows the conventions described in the Device-tree -Specification +cot +------------------------------------------------------------------ +This is root node which contains 'manifests' and 'images' as sub-nodes -certificates, certificate and extension node bindings definition + +Manifests and Certificate node bindings definition ---------------------------------------------------------------- -- Certificates node +- Manifests node Description: Container of certificate nodes. PROPERTIES @@ -27,20 +27,24 @@ certificates, certificate and extension node bindings definition Value type: - Definition: must be "arm, certificate-descriptors" + Definition: must be "arm, cert-descs" - Certificate node - Description: Describes certificate properties which are used - during the authentication process. + Description: + + Describes certificate properties which are used + during the authentication process. PROPERTIES - root-certificate - Usage: Required for the certificate with no parent. - In other words, Certificates which are validated - using root of trust public key. + Usage: + + Required for the certificate with no parent. + In other words, certificates which are validated + using root of trust public key. - Value type: + Value type: - image-id Usage: Required for every certificate with unique id. @@ -48,99 +52,121 @@ certificates, certificate and extension node bindings definition Value type: - parent - Usage: It refers to their parent image, which typically contains - information to authenticate the certificate. - This property is required for all non-root certificates. + Usage: - This property is not required for root-certificates - as it is validated using root of trust public key - provided by platform. + It refers to their parent image, which typically contains + information to authenticate the certificate. + This property is required for all non-root certificates. + + This property is not required for root-certificates + as root-certificates are validated using root of trust + public key provided by platform. Value type: - signing-key - Usage: This property is used to refer extension node present in - parent certificate and it is required property for all non- - root certificates which are authenticated using public-key - present in parent certificate. + Usage: + + This property is used to refer public key node present in + parent certificate node and it is required property for all + non-root certificates which are authenticated using public-key + present in parent certificate. - This property is not required for root-certificates - as root-certificates are validated using root of trust - public key provided by platform. + This property is not required for root-certificates + as root-certificates are validated using root of trust + public key provided by platform. Value type: - antirollback-counter - Usage: This property is used by all certificates which are protected - against rollback attacks using a non-volatile counter and it - is optional property. + Usage: - This property is used to refer trusted or non-trusted - non-volatile counter node. + This property is used by all certificates which are + protected against rollback attacks using a non-volatile + counter and it is an optional property. + + This property is used to refer one of the non-volatile + counter sub-node present in 'non-volatile counters' node. Value type: + SUBNODES + - Description: - - extensions node - Description: This is sub-node of certificate node. - Describes OIDs present in the certificate which will - be used during authentication process to extract - hash/public key information from this certificate. - OIDs in extension node are represented using number of - sub-nodes which contains 'oid' as property + Hash and public key information present in the certificate + are shown by these nodes. - PROPERTIES + - public key node + Description: Provide public key information in the certificate. - - oid - Usage: This property provides the Object ID of an extension - provided in the certificate. + PROPERTIES + + - oid + Usage: - Value type: + This property provides the Object ID of public key + provided in the certificate which the help of which + public key information can be extracted. + + Value type: + + - hash node + Description: Provide the hash information in the certificate. + + PROPERTIES + + - oid + Usage: + + This property provides the Object ID of hash provided in + the certificate which the help of which hash information + can be extracted. + + Value type: Example: .. code:: c - certificates { - compatible = "arm, certificate-descriptors” + cot { + manifests { + compatible = "arm, cert-descs” trusted-key-cert: trusted-key-cert { - root-certificate; - image-id = ; - antirollback-counter = <&trusted_nv_counter>; - extensions { - trusted-world-pk: trusted-world-pk { - oid = TRUSTED_WORLD_PK_OID; - }; - non-trusted-world-pk: non-trusted-world-pk { - oid = NON_TRUSTED_WORLD_PK_OID; - }; - }; - }; + root-certificate; + image-id = ; + antirollback-counter = <&trusted_nv_counter>; - scp_fw_key_cert: scp_fw_key_cert { - image-id = ; - parent = <&trusted-key-cert>; - signing-key = <&trusted_world_pk>; - antirollback-counter = <&trusted_nv_counter>; - extensions { - scp_fw_content_pk: scp_fw_content_pk { - oid = SCP_FW_CONTENT_CERT_PK_OID; - }; - }; - }; + trusted-world-pk: trusted-world-pk { + oid = TRUSTED_WORLD_PK_OID; + }; + non-trusted-world-pk: non-trusted-world-pk { + oid = NON_TRUSTED_WORLD_PK_OID; + }; + }; - . - . - . + scp_fw_key_cert: scp_fw_key_cert { + image-id = ; + parent = <&trusted-key-cert>; + signing-key = <&trusted_world_pk>; + antirollback-counter = <&trusted_nv_counter>; - next-cert { + scp_fw_content_pk: scp_fw_content_pk { + oid = SCP_FW_CONTENT_CERT_PK_OID; + }; + }; + . + . + . - }; + next-certificate { + + }; + }; }; -Images and image node bindings definition +Images and Image node bindings definition ----------------------------------------- - Images node @@ -153,11 +179,13 @@ Images and image node bindings definition Value type: - Definition: must be "arm, image-descriptors" + Definition: must be "arm, img-descs" - Image node - Description: Describes image properties which will be used during - authentication process. + Description: + + Describes image properties which will be used during + authentication process. PROPERTIES @@ -167,35 +195,41 @@ Images and image node bindings definition Value type: - parent - Usage: Required for every image to provide a reference to - it's parent image, which contains the necessary information - to authenticate it. + Usage: + + Required for every image to provide a reference to + its parent image, which contains the necessary information + to authenticate it. Value type: - hash - Usage: Required for all images which are validated using - hash method. This property is used to refer extension - node present in parent certificate and it is required - property for all images. + Usage: + + Required for all images which are validated using + hash method. This property is used to refer hash + node present in parent certificate node. Value type: - Note: Currently, all images are validated using "hash" - method. In future, there may be multiple methods can - be used to validate the image. + Note: + + Currently, all images are validated using 'hash' + method. In future, there may be multiple methods can + be used to validate the image. Example: .. code:: c - images { - compatible = "arm, imgage-descriptors"; + cot { + images { + compatible = "arm, img-descs"; scp_bl2_image { - image-id = ; - parent = <&scp_fw_content_cert>; - hash = <&scp_fw_hash>; + image-id = ; + parent = <&scp_fw_content_cert>; + hash = <&scp_fw_hash>; }; . @@ -203,7 +237,9 @@ Example: . next-img { + }; + }; }; non-volatile counter node binding definition @@ -226,8 +262,10 @@ non-volatile counter node binding definition Value type: - Definition: Must be set according to address size - of non-volatile counter register + Definition: + + Must be set according to address size + of non-volatile counter register - #size-cells Usage: required @@ -243,14 +281,18 @@ non-volatile counter node binding definition PROPERTIES - reg - Usage: Register base address of non-volatile counter and it is required - property. + Usage: + + Register base address of non-volatile counter and it is required + property. Value type: - oid - Usage: This property provides the Object ID of non-volatile counter - provided in the certificate and it is required property. + Usage: + + This property provides the Object ID of non-volatile counter + provided in the certificate and it is required property. Value type: @@ -280,8 +322,7 @@ Below is non-volatile counters example for ARM platform Future update to chain of trust binding --------------------------------------- -This binding document need to be revisited to generalise some terminologies -like Object IDs, extensions etc which are currently specific to X.509 -certificates. +This binding document needs to be revisited to generalise some terminologies +which are currently specific to X.509 certificates for e.g. Object IDs. -*Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.* +*Copyright (c) 2020, Arm Limited. All rights reserved.* -- cgit v1.2.3 From 84ef9cd812faba6c52f7dc78544c0b5f45781759 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Mon, 29 Jun 2020 10:32:53 +0100 Subject: make, doc: Add build option to create chain of trust at runtime Added a build option 'COT_DESC_IN_DTB' to create chain of trust at runtime using fconf. Signed-off-by: Manish V Badarkhe Change-Id: I92b257ac4ece8bbf56f05a41d1e4056e2422ab89 --- Makefile | 6 ++++++ docs/getting_started/build-options.rst | 7 +++++++ make_helpers/defaults.mk | 3 +++ 3 files changed, 16 insertions(+) diff --git a/Makefile b/Makefile index becbf0341..65ebb9372 100644 --- a/Makefile +++ b/Makefile @@ -659,6 +659,10 @@ $(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) +endif + # If pointer authentication is used in the firmware, make sure that all the # registers associated to it are also saved and restored. # Not doing it would leak the value of the keys used by EL3 to EL1 and S-EL1. @@ -903,6 +907,7 @@ $(eval $(call assert_boolean,ENCRYPT_BL31)) $(eval $(call assert_boolean,ENCRYPT_BL32)) $(eval $(call assert_boolean,ERRATA_SPECULATIVE_AT)) $(eval $(call assert_boolean,RAS_TRAP_LOWER_EL_ERR_ACCESS)) +$(eval $(call assert_boolean,COT_DESC_IN_DTB)) $(eval $(call assert_numeric,ARM_ARCH_MAJOR)) $(eval $(call assert_numeric,ARM_ARCH_MINOR)) @@ -983,6 +988,7 @@ $(eval $(call add_define,BL2_INV_DCACHE)) $(eval $(call add_define,USE_SPINLOCK_CAS)) $(eval $(call add_define,ERRATA_SPECULATIVE_AT)) $(eval $(call add_define,RAS_TRAP_LOWER_EL_ERR_ACCESS)) +$(eval $(call add_define,COT_DESC_IN_DTB)) ifeq (${SANITIZE_UB},trap) $(eval $(call add_define,MONITOR_TRAPS)) diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 81903e140..bfc50dfe7 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -648,6 +648,13 @@ Common build options 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. + - ``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 diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index 6db228f2d..9a6fd58fb 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -305,3 +305,6 @@ ERRATA_SPECULATIVE_AT := 0 # Trap RAS error record access from lower EL RAS_TRAP_LOWER_EL_ERR_ACCESS := 0 + +# Build option to create cot descriptors using fconf +COT_DESC_IN_DTB := 0 -- cgit v1.2.3 From 9a65ba851018769db10e72d7784db85a95cfbb65 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 25 Jun 2020 13:10:38 +0100 Subject: arm_fpga: Support more CPU clusters The maximum number of clusters is currently set to 2, which is quite limiting. As there are FPGA images with 4 clusters, let's increase the limit to 4. Change-Id: I9a85ca07ebbd2a018ad9668536d867ad6b75e537 Signed-off-by: Andre Przywara --- plat/arm/board/arm_fpga/fpga_def.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/arm/board/arm_fpga/fpga_def.h b/plat/arm/board/arm_fpga/fpga_def.h index 03787293c..5f1951f79 100644 --- a/plat/arm/board/arm_fpga/fpga_def.h +++ b/plat/arm/board/arm_fpga/fpga_def.h @@ -18,7 +18,7 @@ * that are present will still be indexed appropriately regardless of any empty * entries in the array used to represent the topology. */ -#define FPGA_MAX_CLUSTER_COUNT 2 +#define FPGA_MAX_CLUSTER_COUNT 4 #define FPGA_MAX_CPUS_PER_CLUSTER 8 #define FPGA_MAX_PE_PER_CPU 4 -- cgit v1.2.3 From 2c13ef906132973e0dfb33eda6028770e6bda73c Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 25 Jun 2020 13:10:38 +0100 Subject: arm_fpga: Add Klein and Matterhorn support To support FPGAs with those cores as well, as the respective cpulib files to the Makefile. Change-Id: I1a60867d5937be88b32b210c7817be4274554a76 Signed-off-by: Andre Przywara --- plat/arm/board/arm_fpga/platform.mk | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk index 34e50ea13..399f97748 100644 --- a/plat/arm/board/arm_fpga/platform.mk +++ b/plat/arm/board/arm_fpga/platform.mk @@ -64,7 +64,10 @@ else lib/cpus/aarch64/neoverse_zeus.S \ lib/cpus/aarch64/cortex_hercules_ae.S \ lib/cpus/aarch64/cortex_a65.S \ - lib/cpus/aarch64/cortex_a65ae.S + lib/cpus/aarch64/cortex_a65ae.S \ + lib/cpus/aarch64/cortex_klein.S \ + lib/cpus/aarch64/cortex_matterhorn.S + # AArch64/AArch32 cores FPGA_CPU_LIBS += lib/cpus/aarch64/cortex_a55.S \ lib/cpus/aarch64/cortex_a75.S -- cgit v1.2.3 From c5346ed5e5498b0ea0352785ed21c0f2d794c13f Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Wed, 8 Jul 2020 13:01:00 +0100 Subject: arm_fpga: Predefine DTB and BL33 load addresses The memory layout for the FPGA is fairly uniform for most of the FPGA images, and we already assume that DRAM starts at 2GB by default. Prepopulate PRELOADED_BL33_BASE and FPGA_PRELOADED_DTB_BASE to some sane default values, to simplify building some stock image. If people want to deviate from that, they can always override those addresses on the make command line. Change-Id: I2238fafb3f8253a01ad2d88d45827c141d9b29dd Signed-off-by: Andre Przywara --- plat/arm/board/arm_fpga/platform.mk | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk index 399f97748..e57912cfe 100644 --- a/plat/arm/board/arm_fpga/platform.mk +++ b/plat/arm/board/arm_fpga/platform.mk @@ -24,15 +24,10 @@ ifeq (${TRUSTED_BOARD_BOOT}, 1) $(error "TRUSTED_BOARD_BOOT must be disabled") endif -ifndef PRELOADED_BL33_BASE -$(error "PRELOADED_BL33_BASE is not set") -endif +PRELOADED_BL33_BASE := 0x80080000 -ifndef FPGA_PRELOADED_DTB_BASE -$(error "FPGA_PRELOADED_DTB_BASE is not set") -else +FPGA_PRELOADED_DTB_BASE := 0x80070000 $(eval $(call add_define,FPGA_PRELOADED_DTB_BASE)) -endif # Treating this as a memory-constrained port for now USE_COHERENT_MEM := 0 -- cgit v1.2.3 From a1ab463a9d6834c4b15db6594e86eecb55973cae Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 9 Jul 2020 22:26:37 +0900 Subject: io_storage: remove redundant assigments The assignments to 'result' are unneeded. Change-Id: I18899f10bf9bd7f219f0e47a981683d8b4701bde Signed-off-by: Masahiro Yamada --- drivers/io/io_storage.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/drivers/io/io_storage.c b/drivers/io/io_storage.c index b8c1d6479..ba6f094c4 100644 --- a/drivers/io/io_storage.c +++ b/drivers/io/io_storage.c @@ -34,8 +34,7 @@ static unsigned int dev_count; /* Return a boolean value indicating whether a device connector is valid */ static int is_valid_dev_connector(const io_dev_connector_t *dev_con) { - int result = (dev_con != NULL) && (dev_con->dev_open != NULL); - return result; + return (dev_con != NULL) && (dev_con->dev_open != NULL); } @@ -43,10 +42,10 @@ static int is_valid_dev_connector(const io_dev_connector_t *dev_con) static int is_valid_dev(const uintptr_t dev_handle) { const io_dev_info_t *dev = (io_dev_info_t *)dev_handle; - int result = (dev != NULL) && (dev->funcs != NULL) && + + return (dev != NULL) && (dev->funcs != NULL) && (dev->funcs->type != NULL) && (dev->funcs->type() < IO_TYPE_MAX); - return result; } @@ -54,9 +53,9 @@ static int is_valid_dev(const uintptr_t dev_handle) static int is_valid_entity(const uintptr_t handle) { const io_entity_t *entity = (io_entity_t *)handle; - int result = (entity != NULL) && + + return (entity != NULL) && (is_valid_dev((uintptr_t)entity->dev_handle)); - return result; } @@ -74,12 +73,10 @@ static int is_valid_seek_mode(io_seek_mode_t mode) static int dev_open(const io_dev_connector_t *dev_con, const uintptr_t dev_spec, io_dev_info_t **dev_info) { - int result; assert(dev_info != NULL); assert(is_valid_dev_connector(dev_con)); - result = dev_con->dev_open(dev_spec, dev_info); - return result; + return dev_con->dev_open(dev_spec, dev_info); } @@ -163,11 +160,9 @@ int io_register_device(const io_dev_info_t *dev_info) int io_dev_open(const io_dev_connector_t *dev_con, const uintptr_t dev_spec, uintptr_t *handle) { - int result; assert(handle != NULL); - result = dev_open(dev_con, dev_spec, (io_dev_info_t **)handle); - return result; + return dev_open(dev_con, dev_spec, (io_dev_info_t **)handle); } -- cgit v1.2.3 From 9e5c3e92ab15aed9f6e40d13c1d0a2e7f1b9b9de Mon Sep 17 00:00:00 2001 From: Jacky Bai Date: Wed, 3 Jun 2020 14:24:38 +0800 Subject: plat: imx8m: Move the gpc hw reg to a separate header file Although the GPC provides the similar functions for all the i.MX8M SoC family, the HW register offset and bit defines still have some slight difference, so move the hw reg offset & most of the bitfield defines in 'gpc_reg.h' that is specific to each SoC. Signed-off-by: Jacky Bai Change-Id: I291c435fe98c2f6e6ff8fe0c715ff3a83daa6a0f --- plat/imx/imx8m/imx8mm/include/gpc_reg.h | 127 ++++++++++++++++++++++++++++++++ plat/imx/imx8m/imx8mn/include/gpc_reg.h | 109 +++++++++++++++++++++++++++ plat/imx/imx8m/imx8mq/include/gpc_reg.h | 87 ++++++++++++++++++++++ plat/imx/imx8m/include/gpc.h | 71 +----------------- 4 files changed, 325 insertions(+), 69 deletions(-) create mode 100644 plat/imx/imx8m/imx8mm/include/gpc_reg.h create mode 100644 plat/imx/imx8m/imx8mn/include/gpc_reg.h create mode 100644 plat/imx/imx8m/imx8mq/include/gpc_reg.h diff --git a/plat/imx/imx8m/imx8mm/include/gpc_reg.h b/plat/imx/imx8m/imx8mm/include/gpc_reg.h new file mode 100644 index 000000000..c697af29b --- /dev/null +++ b/plat/imx/imx8m/imx8mm/include/gpc_reg.h @@ -0,0 +1,127 @@ +/* + * Copyright 2020 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef GPC_REG_H +#define GPC_REG_H + +#define LPCR_A53_BSC 0x0 +#define LPCR_A53_BSC2 0x108 +#define LPCR_A53_AD 0x4 +#define LPCR_M4 0x8 +#define SLPCR 0x14 +#define MST_CPU_MAPPING 0x18 +#define MLPCR 0x20 +#define PGC_ACK_SEL_A53 0x24 +#define IMR1_CORE0_A53 0x30 +#define IMR1_CORE1_A53 0x40 +#define IMR1_CORE2_A53 0x1C0 +#define IMR1_CORE3_A53 0x1D0 +#define IMR1_CORE0_M4 0x50 +#define SLT0_CFG 0xB0 +#define GPC_PU_PWRHSK 0x1FC +#define PGC_CPU_0_1_MAPPING 0xEC +#define CPU_PGC_UP_TRG 0xF0 +#define PU_PGC_UP_TRG 0xF8 +#define CPU_PGC_DN_TRG 0xFC +#define PU_PGC_DN_TRG 0x104 +#define LPS_CPU1 0x114 +#define A53_CORE0_PGC 0x800 +#define A53_PLAT_PGC 0x900 +#define PLAT_PGC_PCR 0x900 +#define NOC_PGC_PCR 0xa40 +#define PGC_SCU_TIMING 0x910 + +#define MASK_DSM_TRIGGER_A53 BIT(31) +#define IRQ_SRC_A53_WUP BIT(30) +#define IRQ_SRC_A53_WUP_SHIFT 30 +#define IRQ_SRC_C1 BIT(29) +#define IRQ_SRC_C0 BIT(28) +#define IRQ_SRC_C3 BIT(23) +#define IRQ_SRC_C2 BIT(22) +#define CPU_CLOCK_ON_LPM BIT(14) +#define A53_CLK_ON_LPM BIT(14) +#define MASTER0_LPM_HSK BIT(6) +#define MASTER1_LPM_HSK BIT(7) +#define MASTER2_LPM_HSK BIT(8) + +#define L2PGE BIT(31) +#define EN_L2_WFI_PDN BIT(5) +#define EN_PLAT_PDN BIT(4) + +#define SLPCR_EN_DSM BIT(31) +#define SLPCR_RBC_EN BIT(30) +#define SLPCR_A53_FASTWUP_STOP_MODE BIT(17) +#define SLPCR_A53_FASTWUP_WAIT_MODE BIT(16) +#define SLPCR_VSTBY BIT(2) +#define SLPCR_SBYOS BIT(1) +#define SLPCR_BYPASS_PMIC_READY BIT(0) +#define SLPCR_RBC_COUNT_SHIFT 24 +#define SLPCR_STBY_COUNT_SHFT 3 + +#define A53_DUMMY_PDN_ACK BIT(15) +#define A53_DUMMY_PUP_ACK BIT(31) +#define A53_PLAT_PDN_ACK BIT(2) +#define A53_PLAT_PUP_ACK BIT(18) +#define NOC_PDN_SLT_CTRL BIT(10) +#define NOC_PUP_SLT_CTRL BIT(11) +#define NOC_PGC_PDN_ACK BIT(3) +#define NOC_PGC_PUP_ACK BIT(19) + +#define PLAT_PUP_SLT_CTRL BIT(9) +#define PLAT_PDN_SLT_CTRL BIT(8) + +#define SLT_PLAT_PDN BIT(8) +#define SLT_PLAT_PUP BIT(9) + +#define MASTER1_MAPPING BIT(1) +#define MASTER2_MAPPING BIT(2) + +#define MIPI_PWR_REQ BIT(0) +#define PCIE_PWR_REQ BIT(1) +#define OTG1_PWR_REQ BIT(2) +#define OTG2_PWR_REQ BIT(3) +#define HSIOMIX_PWR_REQ BIT(4) +#define DDRMIX_PWR_REQ BIT(5) +#define GPU2D_PWR_REQ BIT(6) +#define GPUMIX_PWR_REQ BIT(7) +#define VPUMIX_PWR_REQ BIT(8) +#define GPU3D_PWR_REQ BIT(9) +#define DISPMIX_PWR_REQ BIT(10) +#define VPU_G1_PWR_REQ BIT(11) +#define VPU_G2_PWR_REQ BIT(12) +#define VPU_H1_PWR_REQ BIT(13) + +#define DDRMIX_ADB400_SYNC BIT(2) +#define HSIOMIX_ADB400_SYNC (0x3 << 5) +#define DISPMIX_ADB400_SYNC BIT(7) +#define VPUMIX_ADB400_SYNC BIT(8) +#define GPU3D_ADB400_SYNC BIT(9) +#define GPU2D_ADB400_SYNC BIT(10) +#define GPUMIX_ADB400_SYNC BIT(11) +#define DDRMIX_ADB400_ACK BIT(20) +#define HSIOMIX_ADB400_ACK (0x3 << 23) +#define DISPMIX_ADB400_ACK BIT(25) +#define VPUMIX_ADB400_ACK BIT(26) +#define GPU3D_ADB400_ACK BIT(27) +#define GPU2D_ADB400_ACK BIT(28) +#define GPUMIX_ADB400_ACK BIT(29) + +#define MIPI_PGC 0xc00 +#define PCIE_PGC 0xc40 +#define OTG1_PGC 0xc80 +#define OTG2_PGC 0xcc0 +#define HSIOMIX_PGC 0xd00 +#define DDRMIX_PGC 0xd40 +#define GPU2D_PGC 0xd80 +#define GPUMIX_PGC 0xdc0 +#define VPUMIX_PGC 0xe00 +#define GPU3D_PGC 0xe40 +#define DISPMIX_PGC 0xe80 +#define VPU_G1_PGC 0xec0 +#define VPU_G2_PGC 0xf00 +#define VPU_H1_PGC 0xf40 + +#endif /* GPC_REG_H */ diff --git a/plat/imx/imx8m/imx8mn/include/gpc_reg.h b/plat/imx/imx8m/imx8mn/include/gpc_reg.h new file mode 100644 index 000000000..fd10438a4 --- /dev/null +++ b/plat/imx/imx8m/imx8mn/include/gpc_reg.h @@ -0,0 +1,109 @@ +/* + * Copyright 2020 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef GPC_REG_H +#define GPC_REG_H + +#define LPCR_A53_BSC 0x0 +#define LPCR_A53_BSC2 0x108 +#define LPCR_A53_AD 0x4 +#define LPCR_M4 0x8 +#define SLPCR 0x14 +#define MST_CPU_MAPPING 0x18 +#define MLPCR 0x20 +#define PGC_ACK_SEL_A53 0x24 +#define IMR1_CORE0_A53 0x30 +#define IMR1_CORE1_A53 0x40 +#define IMR1_CORE2_A53 0x1C0 +#define IMR1_CORE3_A53 0x1D0 +#define IMR1_CORE0_M4 0x50 +#define SLT0_CFG 0xB0 +#define GPC_PU_PWRHSK 0x1FC +#define PGC_CPU_0_1_MAPPING 0xEC +#define CPU_PGC_UP_TRG 0xF0 +#define PU_PGC_UP_TRG 0xF8 +#define CPU_PGC_DN_TRG 0xFC +#define PU_PGC_DN_TRG 0x104 +#define LPS_CPU1 0x114 +#define A53_CORE0_PGC 0x800 +#define A53_PLAT_PGC 0x900 +#define PLAT_PGC_PCR 0x900 +#define NOC_PGC_PCR 0xa40 +#define PGC_SCU_TIMING 0x910 + +#define MASK_DSM_TRIGGER_A53 BIT(31) +#define IRQ_SRC_A53_WUP BIT(30) +#define IRQ_SRC_A53_WUP_SHIFT 30 +#define IRQ_SRC_C1 BIT(29) +#define IRQ_SRC_C0 BIT(28) +#define IRQ_SRC_C3 BIT(23) +#define IRQ_SRC_C2 BIT(22) +#define CPU_CLOCK_ON_LPM BIT(14) +#define A53_CLK_ON_LPM BIT(14) +#define MASTER0_LPM_HSK BIT(6) +#define MASTER1_LPM_HSK BIT(7) +#define MASTER2_LPM_HSK BIT(8) + +#define L2PGE BIT(31) +#define EN_L2_WFI_PDN BIT(5) +#define EN_PLAT_PDN BIT(4) + +#define SLPCR_EN_DSM BIT(31) +#define SLPCR_RBC_EN BIT(30) +#define SLPCR_A53_FASTWUP_STOP_MODE BIT(17) +#define SLPCR_A53_FASTWUP_WAIT_MODE BIT(16) +#define SLPCR_VSTBY BIT(2) +#define SLPCR_SBYOS BIT(1) +#define SLPCR_BYPASS_PMIC_READY BIT(0) +#define SLPCR_RBC_COUNT_SHIFT 24 +#define SLPCR_STBY_COUNT_SHFT 3 + +#define A53_DUMMY_PDN_ACK BIT(15) +#define A53_DUMMY_PUP_ACK BIT(31) +#define A53_PLAT_PDN_ACK BIT(2) +#define A53_PLAT_PUP_ACK BIT(18) +#define NOC_PDN_SLT_CTRL BIT(10) +#define NOC_PUP_SLT_CTRL BIT(11) +#define NOC_PGC_PDN_ACK BIT(3) +#define NOC_PGC_PUP_ACK BIT(19) + +#define PLAT_PUP_SLT_CTRL BIT(9) +#define PLAT_PDN_SLT_CTRL BIT(8) + +#define SLT_PLAT_PDN BIT(8) +#define SLT_PLAT_PUP BIT(9) + +#define MASTER1_MAPPING BIT(1) +#define MASTER2_MAPPING BIT(2) + +#define TMR_TCD2_SHIFT 0 +#define TMC_TMR_SHIFT 10 +#define TRC1_TMC_SHIFT 20 + +#define MIPI_PWR_REQ BIT(0) +#define OTG1_PWR_REQ BIT(2) +#define HSIOMIX_PWR_REQ BIT(4) +#define DDRMIX_PWR_REQ BIT(5) +#define GPUMIX_PWR_REQ BIT(7) +#define DISPMIX_PWR_REQ BIT(10) + +#define DDRMIX_ADB400_SYNC BIT(2) +#define HSIOMIX_ADB400_SYNC BIT(5) +#define DISPMIX_ADB400_SYNC BIT(7) +#define GPUMIX_ADB400_SYNC (0x5 << 9) +#define DDRMIX_ADB400_ACK BIT(20) +#define HSIOMIX_ADB400_ACK BIT(23) +#define DISPMIX_ADB400_ACK BIT(25) +#define GPUMIX_ADB400_ACK (0x5 << 27) + +#define MIPI_PGC 0xc00 +#define OTG1_PGC 0xc80 +#define HSIOMIX_PGC 0xd00 +#define DDRMIX_PGC 0xd40 +#define GPUMIX_PGC 0xdc0 +#define DISPMIX_PGC 0xe80 + +#endif /* GPC_REG_H */ diff --git a/plat/imx/imx8m/imx8mq/include/gpc_reg.h b/plat/imx/imx8m/imx8mq/include/gpc_reg.h new file mode 100644 index 000000000..9f472d609 --- /dev/null +++ b/plat/imx/imx8m/imx8mq/include/gpc_reg.h @@ -0,0 +1,87 @@ +/* + * Copyright 2020 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef GPC_REG_H +#define GPC_REG_H + +#define LPCR_A53_BSC 0x0 +#define LPCR_A53_BSC2 0x108 +#define LPCR_A53_AD 0x4 +#define LPCR_M4 0x8 +#define SLPCR 0x14 +#define MST_CPU_MAPPING 0x18 +#define MLPCR 0x20 +#define PGC_ACK_SEL_A53 0x24 +#define IMR1_CORE0_A53 0x30 +#define IMR1_CORE1_A53 0x40 +#define IMR1_CORE2_A53 0x1C0 +#define IMR1_CORE3_A53 0x1D0 +#define IMR1_CORE0_M4 0x50 +#define SLT0_CFG 0xB0 +#define GPC_PU_PWRHSK 0x1FC +#define PGC_CPU_0_1_MAPPING 0xEC +#define CPU_PGC_UP_TRG 0xF0 +#define PU_PGC_UP_TRG 0xF8 +#define CPU_PGC_DN_TRG 0xFC +#define PU_PGC_DN_TRG 0x104 +#define LPS_CPU1 0x114 +#define A53_CORE0_PGC 0x800 +#define A53_PLAT_PGC 0x900 +#define PLAT_PGC_PCR 0x900 +#define NOC_PGC_PCR 0xa40 +#define PGC_SCU_TIMING 0x910 + +#define MASK_DSM_TRIGGER_A53 BIT(31) +#define IRQ_SRC_A53_WUP BIT(30) +#define IRQ_SRC_A53_WUP_SHIFT 30 +#define IRQ_SRC_C1 BIT(29) +#define IRQ_SRC_C0 BIT(28) +#define IRQ_SRC_C3 BIT(23) +#define IRQ_SRC_C2 BIT(22) +#define CPU_CLOCK_ON_LPM BIT(14) +#define A53_CLK_ON_LPM BIT(14) +#define MASTER0_LPM_HSK BIT(6) +#define MASTER1_LPM_HSK BIT(7) +#define MASTER2_LPM_HSK BIT(8) + +#define L2PGE BIT(31) +#define EN_L2_WFI_PDN BIT(5) +#define EN_PLAT_PDN BIT(4) + +#define SLPCR_EN_DSM BIT(31) +#define SLPCR_RBC_EN BIT(30) +#define SLPCR_A53_FASTWUP_STOP_MODE BIT(17) +#define SLPCR_A53_FASTWUP_WAIT_MODE BIT(16) +#define SLPCR_VSTBY BIT(2) +#define SLPCR_SBYOS BIT(1) +#define SLPCR_BYPASS_PMIC_READY BIT(0) +#define SLPCR_RBC_COUNT_SHIFT 24 +#define SLPCR_STBY_COUNT_SHFT 3 + +#define A53_DUMMY_PDN_ACK BIT(15) +#define A53_DUMMY_PUP_ACK BIT(31) +#define A53_PLAT_PDN_ACK BIT(2) +#define A53_PLAT_PUP_ACK BIT(18) +#define NOC_PDN_SLT_CTRL BIT(10) +#define NOC_PUP_SLT_CTRL BIT(11) +#define NOC_PGC_PDN_ACK BIT(3) +#define NOC_PGC_PUP_ACK BIT(19) + +#define DDRMIX_PWR_REQ BIT(5) +#define DDRMIX_ADB400_SYNC BIT(1) +#define DDRMIX_ADB400_ACK BIT(18) +#define DDRMIX_PGC 0xd40 + +#define PLAT_PUP_SLT_CTRL BIT(9) +#define PLAT_PDN_SLT_CTRL BIT(8) + +#define SLT_PLAT_PDN BIT(8) +#define SLT_PLAT_PUP BIT(9) + +#define MASTER1_MAPPING BIT(1) +#define MASTER2_MAPPING BIT(2) + +#endif /* GPC_REG_H */ diff --git a/plat/imx/imx8m/include/gpc.h b/plat/imx/imx8m/include/gpc.h index 6033b0d7c..864c8cc5f 100644 --- a/plat/imx/imx8m/include/gpc.h +++ b/plat/imx/imx8m/include/gpc.h @@ -7,74 +7,7 @@ #ifndef IMX8M_GPC_H #define IMX8M_GPC_H -#define LPCR_A53_BSC 0x0 -#define LPCR_A53_BSC2 0x108 -#define LPCR_A53_AD 0x4 -#define LPCR_M4 0x8 -#define SLPCR 0x14 -#define MST_CPU_MAPPING 0x18 -#define MLPCR 0x20 -#define PGC_ACK_SEL_A53 0x24 -#define IMR1_CORE0_A53 0x30 -#define IMR1_CORE1_A53 0x40 -#define IMR1_CORE2_A53 0x1C0 -#define IMR1_CORE3_A53 0x1D0 -#define IMR1_CORE0_M4 0x50 -#define SLT0_CFG 0xB0 -#define GPC_PU_PWRHSK 0x1FC -#define PGC_CPU_0_1_MAPPING 0xEC -#define CPU_PGC_UP_TRG 0xF0 -#define PU_PGC_UP_TRG 0xF8 -#define CPU_PGC_DN_TRG 0xFC -#define PU_PGC_DN_TRG 0x104 -#define A53_CORE0_PGC 0x800 -#define A53_PLAT_PGC 0x900 -#define PLAT_PGC_PCR 0x900 -#define PGC_SCU_TIMING 0x910 - -#define MASK_DSM_TRIGGER_A53 BIT(31) -#define IRQ_SRC_A53_WUP BIT(30) -#define IRQ_SRC_A53_WUP_SHIFT 30 -#define IRQ_SRC_C1 BIT(29) -#define IRQ_SRC_C0 BIT(28) -#define IRQ_SRC_C3 BIT(23) -#define IRQ_SRC_C2 BIT(22) -#define CORE_WKUP_FROM_GIC (IRQ_SRC_C0 | IRQ_SRC_C1 | IRQ_SRC_C2 | IRQ_SRC_C3) -#define CPU_CLOCK_ON_LPM BIT(14) -#define A53_CLK_ON_LPM BIT(14) -#define MASTER0_LPM_HSK BIT(6) - -#define L2PGE BIT(31) -#define EN_L2_WFI_PDN BIT(5) -#define EN_PLAT_PDN BIT(4) - -#define SLPCR_EN_DSM BIT(31) -#define SLPCR_RBC_EN BIT(30) -#define SLPCR_A53_FASTWUP_STOP_MODE BIT(17) -#define SLPCR_A53_FASTWUP_WAIT_MODE BIT(16) -#define SLPCR_VSTBY BIT(2) -#define SLPCR_SBYOS BIT(1) -#define SLPCR_BYPASS_PMIC_READY BIT(0) -#define SLPCR_RBC_COUNT_SHIFT 24 -#define SLPCR_STBY_COUNT_SHFT 3 - -#define A53_DUMMY_PDN_ACK BIT(15) -#define A53_DUMMY_PUP_ACK BIT(31) -#define A53_PLAT_PDN_ACK BIT(2) -#define A53_PLAT_PUP_ACK BIT(18) - -#define PLAT_PUP_SLT_CTRL BIT(9) -#define PLAT_PDN_SLT_CTRL BIT(8) - -#define SLT_PLAT_PDN BIT(8) -#define SLT_PLAT_PUP BIT(9) - -#define MASTER1_MAPPING BIT(1) -#define MASTER2_MAPPING BIT(2) - -#define TMR_TCD2_SHIFT 0 -#define TMC_TMR_SHIFT 10 -#define TRC1_TMC_SHIFT 20 +#include /* helper macro */ #define A53_LPM_MASK U(0xF) @@ -83,7 +16,7 @@ #define LPM_MODE(local_state) ((local_state) == PLAT_WAIT_RET_STATE ? A53_LPM_WAIT : A53_LPM_STOP) #define DSM_MODE_MASK BIT(31) - +#define CORE_WKUP_FROM_GIC (IRQ_SRC_C0 | IRQ_SRC_C1 | IRQ_SRC_C2 | IRQ_SRC_C3) #define A53_CORE_WUP_SRC(core_id) (1 << ((core_id) < 2 ? 28 + (core_id) : 22 + (core_id) - 2)) #define COREx_PGC_PCR(core_id) (0x800 + (core_id) * 0x40) #define COREx_WFI_PDN(core_id) (1 << ((core_id) < 2 ? (core_id) * 2 : ((core_id) - 2) * 2 + 16)) -- cgit v1.2.3 From 567bfe5114e009136368b365d74a875a5284a96a Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Mon, 29 Jun 2020 11:12:12 +0100 Subject: dts: Add CoT descriptor nodes and properties in device tree Added CoT descriptor nodes and properties in device tree. Currently, CoT descriptors which are used by BL2 are added as part of device tree. Signed-off-by: Manish V Badarkhe Change-Id: Iff23cff843e5489fac18bcee5f5d6a71de5ad0d0 --- fdts/cot_descriptors.dtsi | 318 +++++++++++++++++++++++++++++++++++++ include/common/tbbr/tbbr_img_def.h | 8 + 2 files changed, 326 insertions(+) create mode 100644 fdts/cot_descriptors.dtsi diff --git a/fdts/cot_descriptors.dtsi b/fdts/cot_descriptors.dtsi new file mode 100644 index 000000000..753d56ace --- /dev/null +++ b/fdts/cot_descriptors.dtsi @@ -0,0 +1,318 @@ +/* + * Copyright (c) 2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +cot { + manifests { + compatible = "arm, cert-descs"; + + trusted_boot_fw_cert: trusted_boot_fw_cert { + root-certificate; + image-id =; + antirollback-counter = <&trusted_nv_counter>; + + tb_fw_hash: tb_fw_hash { + oid = TRUSTED_BOOT_FW_HASH_OID; + }; + tb_fw_config_hash: tb_fw_config_hash { + oid = TRUSTED_BOOT_FW_CONFIG_HASH_OID; + }; + hw_config_hash: hw_config_hash { + oid = HW_CONFIG_HASH_OID; + }; + fw_config_hash: fw_config_hash { + oid = FW_CONFIG_HASH_OID; + }; + }; + + trusted_key_cert: trusted_key_cert { + root-certificate; + image-id = ; + antirollback-counter = <&trusted_nv_counter>; + + trusted_world_pk: trusted_world_pk { + oid = TRUSTED_WORLD_PK_OID; + }; + non_trusted_world_pk: non_trusted_world_pk { + oid = NON_TRUSTED_WORLD_PK_OID; + }; + }; + + scp_fw_key_cert: scp_fw_key_cert { + image-id = ; + parent = <&trusted_key_cert>; + signing-key = <&trusted_world_pk>; + antirollback-counter = <&trusted_nv_counter>; + + scp_fw_content_pk: scp_fw_content_pk { + oid = SCP_FW_CONTENT_CERT_PK_OID; + }; + }; + + scp_fw_content_cert: scp_fw_content_cert { + image-id = ; + parent = <&scp_fw_key_cert>; + signing-key = <&scp_fw_content_pk>; + antirollback-counter = <&trusted_nv_counter>; + + scp_fw_hash: scp_fw_hash { + oid = SCP_FW_HASH_OID; + }; + }; + + soc_fw_key_cert: soc_fw_key_cert { + image-id = ; + parent = <&trusted_key_cert>; + signing-key = <&trusted_world_pk>; + antirollback-counter = <&trusted_nv_counter>; + soc_fw_content_pk: soc_fw_content_pk { + oid = SOC_FW_CONTENT_CERT_PK_OID; + }; + }; + + soc_fw_content_cert: soc_fw_content_cert { + image-id = ; + parent = <&soc_fw_key_cert>; + signing-key = <&soc_fw_content_pk>; + antirollback-counter = <&trusted_nv_counter>; + + soc_fw_hash: soc_fw_hash { + oid = SOC_AP_FW_HASH_OID; + }; + soc_fw_config_hash: soc_fw_config_hash { + oid = SOC_FW_CONFIG_HASH_OID; + }; + }; + + trusted_os_fw_key_cert: trusted_os_fw_key_cert { + image-id = ; + parent = <&trusted_key_cert>; + signing-key = <&trusted_world_pk>; + antirollback-counter = <&trusted_nv_counter>; + + tos_fw_content_pk: tos_fw_content_pk { + oid = TRUSTED_OS_FW_CONTENT_CERT_PK_OID; + }; + }; + + trusted_os_fw_content_cert: trusted_os_fw_content_cert { + image-id = ; + parent = <&trusted_os_fw_key_cert>; + signing-key = <&tos_fw_content_pk>; + antirollback-counter = <&trusted_nv_counter>; + + tos_fw_hash: tos_fw_hash { + oid = TRUSTED_OS_FW_HASH_OID; + }; + tos_fw_extra1_hash: tos_fw_extra1_hash { + oid = TRUSTED_OS_FW_EXTRA1_HASH_OID; + }; + tos_fw_extra2_hash: tos_fw_extra2_hash { + oid = TRUSTED_OS_FW_EXTRA2_HASH_OID; + }; + tos_fw_config_hash: tos_fw_config_hash { + oid = TRUSTED_OS_FW_CONFIG_HASH_OID; + }; + }; + + non_trusted_fw_key_cert: non_trusted_fw_key_cert { + image-id = ; + parent = <&trusted_key_cert>; + signing-key = <&non_trusted_world_pk>; + antirollback-counter = <&non_trusted_nv_counter>; + + nt_fw_content_pk: nt_fw_content_pk { + oid = NON_TRUSTED_FW_CONTENT_CERT_PK_OID; + }; + }; + + non_trusted_fw_content_cert: non_trusted_fw_content_cert { + image-id = ; + parent = <&non_trusted_fw_key_cert>; + signing-key = <&nt_fw_content_pk>; + antirollback-counter = <&non_trusted_nv_counter>; + + nt_world_bl_hash: nt_world_bl_hash { + oid = NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID; + }; + nt_fw_config_hash: nt_fw_config_hash { + oid = NON_TRUSTED_FW_CONFIG_HASH_OID; + }; + }; + +#if defined(SPD_spmd) + sp_content_cert: sp_content_cert { + image-id = ; + parent = <&trusted_key_cert>; + signing-key = <&trusted_world_pk>; + antirollback-counter = <&trusted_nv_counter>; + + sp_pkg1_hash: sp_pkg1_hash { + oid = SP_PKG1_HASH_OID; + }; + sp_pkg2_hash: sp_pkg2_hash { + oid = SP_PKG2_HASH_OID; + }; + sp_pkg3_hash: sp_pkg3_hash { + oid = SP_PKG3_HASH_OID; + }; + sp_pkg4_hash: sp_pkg4_hash { + oid = SP_PKG4_HASH_OID; + }; + sp_pkg5_hash: sp_pkg5_hash { + oid = SP_PKG5_HASH_OID; + }; + sp_pkg6_hash: sp_pkg6_hash { + oid = SP_PKG6_HASH_OID; + }; + sp_pkg7_hash: sp_pkg7_hash { + oid = SP_PKG7_HASH_OID; + }; + sp_pkg8_hash: sp_pkg8_hash { + oid = SP_PKG8_HASH_OID; + }; + }; +#endif + }; + + images { + compatible = "arm, img-descs"; + + hw_config { + image-id = ; + parent = <&trusted_boot_fw_cert>; + hash = <&hw_config_hash>; + }; + + tb_fw_config { + image-id = ; + parent = <&trusted_boot_fw_cert>; + hash = <&tb_fw_config_hash>; + }; + + scp_bl2_image { + image-id = ; + parent = <&scp_fw_content_cert>; + hash = <&scp_fw_hash>; + }; + + bl31_image { + image-id = ; + parent = <&soc_fw_content_cert>; + hash = <&soc_fw_hash>; + }; + + soc_fw_config { + image-id = ; + parent = <&soc_fw_content_cert>; + hash = <&soc_fw_config_hash>; + }; + + bl32_image { + image-id = ; + parent = <&trusted_os_fw_content_cert>; + hash = <&tos_fw_hash>; + }; + + bl32_extra1_image { + image-id = ; + parent = <&trusted_os_fw_content_cert>; + hash = <&tos_fw_extra1_hash>; + }; + + bl32_extra2_image { + image-id = ; + parent = <&trusted_os_fw_content_cert>; + hash = <&tos_fw_extra2_hash>; + }; + + tos_fw_config { + image-id = ; + parent = <&trusted_os_fw_content_cert>; + hash = <&tos_fw_config_hash>; + }; + + bl33_image { + image-id = ; + parent = <&non_trusted_fw_content_cert>; + hash = <&nt_world_bl_hash>; + }; + + nt_fw_config { + image-id = ; + parent = <&non_trusted_fw_content_cert>; + hash = <&nt_fw_config_hash>; + }; + +#if defined(SPD_spmd) + sp_pkg1 { + image-id = ; + parent = <&sp_content_cert>; + hash = <&sp_pkg1_hash>; + }; + + sp_pkg2 { + image-id = ; + parent = <&sp_content_cert>; + hash = <&sp_pkg2_hash>; + }; + + sp_pkg3 { + image-id = ; + parent = <&sp_content_cert>; + hash = <&sp_pkg3_hash>; + }; + + sp_pkg4 { + image-id = ; + parent = <&sp_content_cert>; + hash = <&sp_pkg4_hash>; + }; + + sp_pkg5 { + image-id = ; + parent = <&sp_content_cert>; + hash = <&sp_pkg5_hash>; + }; + + sp_pkg6 { + image-id = ; + parent = <&sp_content_cert>; + hash = <&sp_pkg6_hash>; + }; + + sp_pkg7 { + image-id = ; + parent = <&sp_content_cert>; + hash = <&sp_pkg7_hash>; + }; + + sp_pkg8 { + image-id = ; + parent = <&sp_content_cert>; + hash = <&sp_pkg8_hash>; + }; +#endif + }; +}; + +non-volatile-counters { + compatible = "arm, non-volatile-counter"; + + #address-cells = <1>; + #size-cells = <0>; + + counters { + trusted_nv_counter: trusted_nv_counter { + oid = TRUSTED_FW_NVCOUNTER_OID; + }; + non_trusted_nv_counter: non_trusted_nv_counter { + oid = NON_TRUSTED_FW_NVCOUNTER_OID; + }; + }; +}; diff --git a/include/common/tbbr/tbbr_img_def.h b/include/common/tbbr/tbbr_img_def.h index 1f9aab127..e057891a2 100644 --- a/include/common/tbbr/tbbr_img_def.h +++ b/include/common/tbbr/tbbr_img_def.h @@ -11,6 +11,14 @@ #if defined(SPD_spmd) #define SP_CONTENT_CERT_ID MAX_IMAGE_IDS +#define SP_PKG1_ID (MAX_IMAGE_IDS + 1) +#define SP_PKG2_ID (MAX_IMAGE_IDS + 2) +#define SP_PKG3_ID (MAX_IMAGE_IDS + 3) +#define SP_PKG4_ID (MAX_IMAGE_IDS + 4) +#define SP_PKG5_ID (MAX_IMAGE_IDS + 5) +#define SP_PKG6_ID (MAX_IMAGE_IDS + 6) +#define SP_PKG7_ID (MAX_IMAGE_IDS + 7) +#define SP_PKG8_ID (MAX_IMAGE_IDS + 8) #define MAX_SP_IDS U(8) #define MAX_NUMBER_IDS (MAX_IMAGE_IDS + MAX_SP_IDS + U(1)) #else -- cgit v1.2.3 From 2a0ef943b658a82b4b1265097e99d7b9367167ad Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Mon, 29 Jun 2020 11:14:07 +0100 Subject: plat/arm, dts: Update platform device tree for CoT Included cot_descriptors.dtsi in platform device tree (fvp_tb_fw_config.dts). Also, updated the maximum size of tb_fw_config to 0x1800 in order to accomodate the device tree for CoT descriptors. Follow up patch will parse the device tree for these CoT descriptors and fill the CoT descriptor structures at runtime instead of using static CoT descriptor structures in the code base. Signed-off-by: Manish V Badarkhe Change-Id: I90122bc713f6842b82fb019b04caf42629b4f45a --- include/plat/arm/common/arm_def.h | 9 +++++---- plat/arm/board/fvp/fdts/fvp_fw_config.dts | 2 +- plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts | 18 ++++++++++++++++++ 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index 5c11e5fe1..680d35432 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -350,14 +350,15 @@ * and limit. Leave enough space of BL2 meminfo. */ #define ARM_FW_CONFIG_BASE (ARM_BL_RAM_BASE + sizeof(meminfo_t)) -#define ARM_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + PAGE_SIZE) +#define ARM_FW_CONFIG_LIMIT ((ARM_BL_RAM_BASE + PAGE_SIZE) \ + + (PAGE_SIZE / 2U)) /* * Boot parameters passed from BL2 to BL31/BL32 are stored here */ -#define ARM_BL2_MEM_DESC_BASE ARM_FW_CONFIG_LIMIT -#define ARM_BL2_MEM_DESC_LIMIT (ARM_BL2_MEM_DESC_BASE + \ - (PAGE_SIZE / 2U)) +#define ARM_BL2_MEM_DESC_BASE (ARM_FW_CONFIG_LIMIT) +#define ARM_BL2_MEM_DESC_LIMIT (ARM_BL2_MEM_DESC_BASE \ + + (PAGE_SIZE / 2U)) /* * Define limit of firmware configuration memory: diff --git a/plat/arm/board/fvp/fdts/fvp_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_fw_config.dts index 09f2730d9..9fb566b1e 100644 --- a/plat/arm/board/fvp/fdts/fvp_fw_config.dts +++ b/plat/arm/board/fvp/fdts/fvp_fw_config.dts @@ -14,7 +14,7 @@ tb_fw-config { load-address = <0x0 0x4001300>; - max-size = <0x200>; + max-size = <0x1800>; id = ; }; 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 9cffad310..8b9e41ce3 100644 --- a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts +++ b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts @@ -85,4 +85,22 @@ load-address = <0x7100000>; }; }; + +#if COT_DESC_IN_DTB + #include "cot_descriptors.dtsi" +#endif + +}; + +#if COT_DESC_IN_DTB + +#include "../fvp_def.h" + +&trusted_nv_counter { + reg = ; +}; + +&non_trusted_nv_counter { + reg = ; }; +#endif -- cgit v1.2.3 From a775ef25c3127ae9175f48aa0092432c08e6fab6 Mon Sep 17 00:00:00 2001 From: Jacky Bai Date: Wed, 3 Jun 2020 14:28:45 +0800 Subject: plat: imx8mp: Add the basic support for i.MX8MP The i.MX 8MP Media Applications Processor is part of the growing i.MX8M family targeting the consumer and industrial market. It brings an effective Machine Learning and AI accelerator that enables a new class of applications. It is built in 14LPP to achieve both high performance and low power consumption and relies on a powerful fully coherent core complex based on a quad core Arm Cortex-A53 cluster and Cortex-M7 low-power coprocessor, audio digital signal processor, machine learning and graphics accelerators. Signed-off-by: Jacky Bai Change-Id: I98311ebc32bee20af05031492e9fc24d06e55f4a --- docs/plat/imx8m.rst | 1 + plat/imx/imx8m/imx8mp/gpc.c | 379 +++++++++++++++++++++++++++ plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c | 187 +++++++++++++ plat/imx/imx8m/imx8mp/imx8mp_psci.c | 44 ++++ plat/imx/imx8m/imx8mp/include/gpc_reg.h | 149 +++++++++++ plat/imx/imx8m/imx8mp/include/platform_def.h | 154 +++++++++++ plat/imx/imx8m/imx8mp/platform.mk | 56 ++++ plat/imx/imx8m/include/gpc.h | 27 ++ 8 files changed, 997 insertions(+) create mode 100644 plat/imx/imx8m/imx8mp/gpc.c create mode 100644 plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c create mode 100644 plat/imx/imx8m/imx8mp/imx8mp_psci.c create mode 100644 plat/imx/imx8m/imx8mp/include/gpc_reg.h create mode 100644 plat/imx/imx8m/imx8mp/include/platform_def.h create mode 100644 plat/imx/imx8m/imx8mp/platform.mk diff --git a/docs/plat/imx8m.rst b/docs/plat/imx8m.rst index ba087a2a3..f184b6990 100644 --- a/docs/plat/imx8m.rst +++ b/docs/plat/imx8m.rst @@ -33,6 +33,7 @@ Build Procedure Target_SoC should be "imx8mq" for i.MX8MQ SoC. Target_SoC should be "imx8mm" for i.MX8MM SoC. Target_SoC should be "imx8mn" for i.MX8MN SoC. + Target_SoC should be "imx8mp" for i.MX8MP SoC. Deploy TF-A Images ~~~~~~~~~~~~~~~~~~ diff --git a/plat/imx/imx8m/imx8mp/gpc.c b/plat/imx/imx8m/imx8mp/gpc.c new file mode 100644 index 000000000..d660e3d88 --- /dev/null +++ b/plat/imx/imx8m/imx8mp/gpc.c @@ -0,0 +1,379 @@ +/* + * Copyright 2019-2020 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define CCGR(x) (0x4000 + (x) * 0x10) +#define IMR_NUM U(5) + +struct imx_noc_setting { + uint32_t domain_id; + uint32_t start; + uint32_t end; + uint32_t prioriy; + uint32_t mode; + uint32_t socket_qos_en; +}; + +enum clk_type { + CCM_ROOT_SLICE, + CCM_CCGR, +}; + +struct clk_setting { + uint32_t offset; + uint32_t val; + enum clk_type type; +}; + +enum pu_domain_id { + /* hsio ss */ + HSIOMIX, + PCIE_PHY, + USB1_PHY, + USB2_PHY, + MLMIX, + AUDIOMIX, + /* gpu ss */ + GPUMIX, + GPU2D, + GPU3D, + /* vpu ss */ + VPUMIX, + VPU_G1, + VPU_G2, + VPU_H1, + /* media ss */ + MEDIAMIX, + MEDIAMIX_ISPDWP, + MIPI_PHY1, + MIPI_PHY2, + /* HDMI ss */ + HDMIMIX, + HDMI_PHY, + DDRMIX, +}; + +/* PU domain, add some hole to minimize the uboot change */ +static struct imx_pwr_domain pu_domains[20] = { + [MIPI_PHY1] = IMX_PD_DOMAIN(MIPI_PHY1, false), + [PCIE_PHY] = IMX_PD_DOMAIN(PCIE_PHY, false), + [USB1_PHY] = IMX_PD_DOMAIN(USB1_PHY, true), + [USB2_PHY] = IMX_PD_DOMAIN(USB2_PHY, true), + [MLMIX] = IMX_MIX_DOMAIN(MLMIX, false), + [AUDIOMIX] = IMX_MIX_DOMAIN(AUDIOMIX, false), + [GPU2D] = IMX_PD_DOMAIN(GPU2D, false), + [GPUMIX] = IMX_MIX_DOMAIN(GPUMIX, false), + [VPUMIX] = IMX_MIX_DOMAIN(VPUMIX, false), + [GPU3D] = IMX_PD_DOMAIN(GPU3D, false), + [MEDIAMIX] = IMX_MIX_DOMAIN(MEDIAMIX, false), + [VPU_G1] = IMX_PD_DOMAIN(VPU_G1, false), + [VPU_G2] = IMX_PD_DOMAIN(VPU_G2, false), + [VPU_H1] = IMX_PD_DOMAIN(VPU_H1, false), + [HDMIMIX] = IMX_MIX_DOMAIN(HDMIMIX, false), + [HDMI_PHY] = IMX_PD_DOMAIN(HDMI_PHY, false), + [MIPI_PHY2] = IMX_PD_DOMAIN(MIPI_PHY2, false), + [HSIOMIX] = IMX_MIX_DOMAIN(HSIOMIX, false), + [MEDIAMIX_ISPDWP] = IMX_PD_DOMAIN(MEDIAMIX_ISPDWP, false), +}; + +static struct imx_noc_setting noc_setting[] = { + {MLMIX, 0x180, 0x180, 0x80000303, 0x0, 0x0}, + {AUDIOMIX, 0x200, 0x200, 0x80000303, 0x0, 0x0}, + {AUDIOMIX, 0x280, 0x480, 0x80000404, 0x0, 0x0}, + {GPUMIX, 0x500, 0x580, 0x80000303, 0x0, 0x0}, + {HDMIMIX, 0x600, 0x680, 0x80000202, 0x0, 0x1}, + {HDMIMIX, 0x700, 0x700, 0x80000505, 0x0, 0x0}, + {HSIOMIX, 0x780, 0x900, 0x80000303, 0x0, 0x0}, + {MEDIAMIX, 0x980, 0xb80, 0x80000202, 0x0, 0x1}, + {MEDIAMIX_ISPDWP, 0xc00, 0xd00, 0x80000505, 0x0, 0x0}, + {VPU_G1, 0xd80, 0xd80, 0x80000303, 0x0, 0x0}, + {VPU_G2, 0xe00, 0xe00, 0x80000303, 0x0, 0x0}, + {VPU_H1, 0xe80, 0xe80, 0x80000303, 0x0, 0x0} +}; + +static struct clk_setting hsiomix_clk[] = { + { 0x8380, 0x0, CCM_ROOT_SLICE }, + { 0x44d0, 0x0, CCM_CCGR }, + { 0x45c0, 0x0, CCM_CCGR }, +}; + +static struct aipstz_cfg aipstz5[] = { + {IMX_AIPSTZ5, 0x77777777, 0x77777777, .opacr = {0x0, 0x0, 0x0, 0x0, 0x0}, }, + {0}, +}; + +static unsigned int pu_domain_status; + +static void imx_noc_qos(unsigned int domain_id) +{ + unsigned int i; + uint32_t hurry; + + if (domain_id == HDMIMIX) { + mmio_write_32(IMX_HDMI_CTL_BASE + TX_CONTROL1, 0x22018); + mmio_write_32(IMX_HDMI_CTL_BASE + TX_CONTROL1, 0x22010); + + /* set GPR to make lcdif read hurry level 0x7 */ + hurry = mmio_read_32(IMX_HDMI_CTL_BASE + TX_CONTROL0); + hurry |= 0x00077000; + mmio_write_32(IMX_HDMI_CTL_BASE + TX_CONTROL0, hurry); + } + + if (domain_id == MEDIAMIX) { + /* handle mediamix special */ + mmio_write_32(IMX_MEDIAMIX_CTL_BASE + RSTn_CSR, 0x1FFFFFF); + mmio_write_32(IMX_MEDIAMIX_CTL_BASE + CLK_EN_CSR, 0x1FFFFFF); + mmio_write_32(IMX_MEDIAMIX_CTL_BASE + RST_DIV, 0x40030000); + + /* set GPR to make lcdif read hurry level 0x7 */ + hurry = mmio_read_32(IMX_MEDIAMIX_CTL_BASE + LCDIF_ARCACHE_CTRL); + hurry |= 0xfc00; + mmio_write_32(IMX_MEDIAMIX_CTL_BASE + LCDIF_ARCACHE_CTRL, hurry); + /* set GPR to make isi write hurry level 0x7 */ + hurry = mmio_read_32(IMX_MEDIAMIX_CTL_BASE + ISI_CACHE_CTRL); + hurry |= 0x1ff00000; + mmio_write_32(IMX_MEDIAMIX_CTL_BASE + ISI_CACHE_CTRL, hurry); + } + + /* set MIX NoC */ + for (i = 0; i < ARRAY_SIZE(noc_setting); i++) { + if (noc_setting[i].domain_id == domain_id) { + udelay(50); + uint32_t offset = noc_setting[i].start; + + while (offset <= noc_setting[i].end) { + mmio_write_32(IMX_NOC_BASE + offset + 0x8, noc_setting[i].prioriy); + mmio_write_32(IMX_NOC_BASE + offset + 0xc, noc_setting[i].mode); + mmio_write_32(IMX_NOC_BASE + offset + 0x18, noc_setting[i].socket_qos_en); + offset += 0x80; + } + } + } +} + +static void imx_gpc_pm_domain_enable(uint32_t domain_id, bool on) +{ + struct imx_pwr_domain *pwr_domain = &pu_domains[domain_id]; + unsigned int i; + + if (domain_id == HSIOMIX) { + for (i = 0; i < ARRAY_SIZE(hsiomix_clk); i++) { + hsiomix_clk[i].val = mmio_read_32(IMX_CCM_BASE + hsiomix_clk[i].offset); + mmio_setbits_32(IMX_CCM_BASE + hsiomix_clk[i].offset, + hsiomix_clk[i].type == CCM_ROOT_SLICE ? BIT(28) : 0x3); + } + } + + if (on) { + if (pwr_domain->need_sync) { + pu_domain_status |= (1 << domain_id); + } + + if (domain_id == HDMIMIX) { + /* assert the reset */ + mmio_write_32(IMX_HDMI_CTL_BASE + RTX_RESET_CTL0, 0x0); + /* enable all th function clock */ + mmio_write_32(IMX_HDMI_CTL_BASE + RTX_CLK_CTL0, 0xFFFFFFFF); + mmio_write_32(IMX_HDMI_CTL_BASE + RTX_CLK_CTL1, 0x7ffff87e); + } + + /* clear the PGC bit */ + mmio_clrbits_32(IMX_GPC_BASE + pwr_domain->pgc_offset, 0x1); + + /* power up the domain */ + mmio_setbits_32(IMX_GPC_BASE + PU_PGC_UP_TRG, pwr_domain->pwr_req); + + /* wait for power request done */ + while (mmio_read_32(IMX_GPC_BASE + PU_PGC_UP_TRG) & pwr_domain->pwr_req) + ; + + if (domain_id == HDMIMIX) { + /* wait for memory repair done for HDMIMIX */ + while (!(mmio_read_32(IMX_SRC_BASE + 0x94) & BIT(8))) + ; + /* disable all the function clock */ + mmio_write_32(IMX_HDMI_CTL_BASE + RTX_CLK_CTL0, 0x0); + mmio_write_32(IMX_HDMI_CTL_BASE + RTX_CLK_CTL1, 0x0); + /* deassert the reset */ + mmio_write_32(IMX_HDMI_CTL_BASE + RTX_RESET_CTL0, 0xffffffff); + /* enable all the clock again */ + mmio_write_32(IMX_HDMI_CTL_BASE + RTX_CLK_CTL0, 0xFFFFFFFF); + mmio_write_32(IMX_HDMI_CTL_BASE + RTX_CLK_CTL1, 0x7ffff87e); + } + + if (domain_id == HSIOMIX) { + /* enable HSIOMIX clock */ + mmio_write_32(IMX_HSIOMIX_CTL_BASE, 0x2); + } + + /* handle the ADB400 sync */ + if (pwr_domain->need_sync) { + /* clear adb power down request */ + mmio_setbits_32(IMX_GPC_BASE + GPC_PU_PWRHSK, pwr_domain->adb400_sync); + + /* wait for adb power request ack */ + while (!(mmio_read_32(IMX_GPC_BASE + GPC_PU_PWRHSK) & pwr_domain->adb400_ack)) + ; + } + + imx_noc_qos(domain_id); + + /* AIPS5 config is lost when audiomix is off, so need to re-init it */ + if (domain_id == AUDIOMIX) { + imx_aipstz_init(aipstz5); + } + } else { + if (pwr_domain->always_on) { + return; + } + + if (pwr_domain->need_sync) { + pu_domain_status &= ~(1 << domain_id); + } + + /* handle the ADB400 sync */ + if (pwr_domain->need_sync) { + /* set adb power down request */ + mmio_clrbits_32(IMX_GPC_BASE + GPC_PU_PWRHSK, pwr_domain->adb400_sync); + + /* wait for adb power request ack */ + while ((mmio_read_32(IMX_GPC_BASE + GPC_PU_PWRHSK) & pwr_domain->adb400_ack)) + ; + } + + /* set the PGC bit */ + mmio_setbits_32(IMX_GPC_BASE + pwr_domain->pgc_offset, 0x1); + + /* + * leave the G1, G2, H1 power domain on until VPUMIX power off, + * otherwise system will hang due to VPUMIX ACK + */ + if (domain_id == VPU_H1 || domain_id == VPU_G1 || domain_id == VPU_G2) { + return; + } + + if (domain_id == VPUMIX) { + mmio_write_32(IMX_GPC_BASE + PU_PGC_DN_TRG, VPU_G1_PWR_REQ | + VPU_G2_PWR_REQ | VPU_H1_PWR_REQ); + + while (mmio_read_32(IMX_GPC_BASE + PU_PGC_DN_TRG) & (VPU_G1_PWR_REQ | + VPU_G2_PWR_REQ | VPU_H1_PWR_REQ)) + ; + } + + /* power down the domain */ + mmio_setbits_32(IMX_GPC_BASE + PU_PGC_DN_TRG, pwr_domain->pwr_req); + + /* wait for power request done */ + while (mmio_read_32(IMX_GPC_BASE + PU_PGC_DN_TRG) & pwr_domain->pwr_req) + ; + + if (domain_id == HDMIMIX) { + /* disable all the clocks of HDMIMIX */ + mmio_write_32(IMX_HDMI_CTL_BASE + 0x40, 0x0); + mmio_write_32(IMX_HDMI_CTL_BASE + 0x50, 0x0); + } + } + + if (domain_id == HSIOMIX) { + for (i = 0; i < ARRAY_SIZE(hsiomix_clk); i++) { + mmio_write_32(IMX_CCM_BASE + hsiomix_clk[i].offset, hsiomix_clk[i].val); + } + } +} + +void imx_gpc_init(void) +{ + uint32_t val; + unsigned int i; + + /* mask all the wakeup irq by default */ + for (i = 0; i < IMR_NUM; i++) { + mmio_write_32(IMX_GPC_BASE + IMR1_CORE0_A53 + i * 4, ~0x0); + mmio_write_32(IMX_GPC_BASE + IMR1_CORE1_A53 + i * 4, ~0x0); + mmio_write_32(IMX_GPC_BASE + IMR1_CORE2_A53 + i * 4, ~0x0); + mmio_write_32(IMX_GPC_BASE + IMR1_CORE3_A53 + i * 4, ~0x0); + mmio_write_32(IMX_GPC_BASE + IMR1_CORE0_M4 + i * 4, ~0x0); + } + + val = mmio_read_32(IMX_GPC_BASE + LPCR_A53_BSC); + /* use GIC wake_request to wakeup C0~C3 from LPM */ + val |= CORE_WKUP_FROM_GIC; + /* clear the MASTER0 LPM handshake */ + val &= ~MASTER0_LPM_HSK; + mmio_write_32(IMX_GPC_BASE + LPCR_A53_BSC, val); + + /* clear MASTER1 & MASTER2 mapping in CPU0(A53) */ + mmio_clrbits_32(IMX_GPC_BASE + MST_CPU_MAPPING, (MASTER1_MAPPING | + MASTER2_MAPPING)); + + /* set all mix/PU in A53 domain */ + mmio_write_32(IMX_GPC_BASE + PGC_CPU_0_1_MAPPING, 0x3fffff); + + /* + * Set the CORE & SCU power up timing: + * SW = 0x1, SW2ISO = 0x1; + * the CPU CORE and SCU power up timming counter + * is drived by 32K OSC, each domain's power up + * latency is (SW + SW2ISO) / 32768 + */ + mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(0) + 0x4, 0x401); + mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(1) + 0x4, 0x401); + mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(2) + 0x4, 0x401); + mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(3) + 0x4, 0x401); + mmio_write_32(IMX_GPC_BASE + PLAT_PGC_PCR + 0x4, 0x401); + mmio_write_32(IMX_GPC_BASE + PGC_SCU_TIMING, + (0x59 << TMC_TMR_SHIFT) | 0x5B | (0x2 << TRC1_TMC_SHIFT)); + + /* set DUMMY PDN/PUP ACK by default for A53 domain */ + mmio_write_32(IMX_GPC_BASE + PGC_ACK_SEL_A53, + A53_DUMMY_PUP_ACK | A53_DUMMY_PDN_ACK); + + /* clear DSM by default */ + val = mmio_read_32(IMX_GPC_BASE + SLPCR); + val &= ~SLPCR_EN_DSM; + /* enable the fast wakeup wait/stop mode */ + val |= SLPCR_A53_FASTWUP_WAIT_MODE; + val |= SLPCR_A53_FASTWUP_STOP_MODE; + /* clear the RBC */ + val &= ~(0x3f << SLPCR_RBC_COUNT_SHIFT); + /* set the STBY_COUNT to 0x5, (128 * 30)us */ + val &= ~(0x7 << SLPCR_STBY_COUNT_SHFT); + val |= (0x5 << SLPCR_STBY_COUNT_SHFT); + mmio_write_32(IMX_GPC_BASE + SLPCR, val); + + /* + * USB PHY power up needs to make sure RESET bit in SRC is clear, + * otherwise, the PU power up bit in GPC will NOT self-cleared. + * only need to do it once. + */ + mmio_clrbits_32(IMX_SRC_BASE + SRC_OTG1PHY_SCR, 0x1); + mmio_clrbits_32(IMX_SRC_BASE + SRC_OTG2PHY_SCR, 0x1); + + /* enable all the power domain by default */ + for (i = 0; i < 101; i++) { + mmio_write_32(IMX_CCM_BASE + CCGR(i), 0x3); + } + + for (i = 0; i < 20; i++) { + imx_gpc_pm_domain_enable(i, true); + } +} diff --git a/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c b/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c new file mode 100644 index 000000000..22fbd5e4b --- /dev/null +++ b/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c @@ -0,0 +1,187 @@ +/* + * Copyright 2020 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 +#include +#include + +static const mmap_region_t imx_mmap[] = { + GIC_MAP, AIPS_MAP, OCRAM_S_MAP, DDRC_MAP, + NOC_MAP, {0}, +}; + +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}, +}; + +static const struct imx_rdc_cfg rdc[] = { + /* Master domain assignment */ + RDC_MDAn(0x1, DID1), + + /* peripherals domain permission */ + + /* memory region */ + + /* Sentinel */ + {0}, +}; + +static entry_point_info_t bl32_image_ep_info; +static entry_point_info_t bl33_image_ep_info; + +/* get SPSR for BL33 entry */ +static uint32_t get_spsr_for_bl33_entry(void) +{ + unsigned long el_status; + unsigned long mode; + uint32_t spsr; + + /* figure out what mode we enter the non-secure world */ + el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT; + el_status &= ID_AA64PFR0_ELX_MASK; + + mode = (el_status) ? MODE_EL2 : MODE_EL1; + + spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); + return spsr; +} + +static void bl31_tzc380_setup(void) +{ + unsigned int val; + + val = mmio_read_32(IMX_IOMUX_GPR_BASE + 0x28); + if ((val & GPR_TZASC_EN) != GPR_TZASC_EN) + return; + + tzc380_init(IMX_TZASC_BASE); + + /* + * Need to substact offset 0x40000000 from CPU address when + * programming tzasc region for i.mx8mp. + */ + + /* Enable 1G-5G S/NS RW */ + tzc380_configure_region(0, 0x00000000, TZC_ATTR_REGION_SIZE(TZC_REGION_SIZE_4G) | + TZC_ATTR_REGION_EN_MASK | TZC_ATTR_SP_ALL); +} + +void bl31_early_platform_setup2(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 = 0; i < 64; i++) { + mmio_write_32(IMX_CSU_BASE + i * 4, 0x00ff00ff); + } + + imx_aipstz_init(aipstz); + + imx_rdc_init(rdc); + + imx8m_caam_init(); + + console_imx_uart_register(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ, + IMX_CONSOLE_BAUDRATE, &console); + /* This console is only used for boot stage */ + console_set_scope(&console, CONSOLE_FLAG_BOOT); + + /* + * tell BL3-1 where the non-secure software image is located + * and the entry state information. + */ + bl33_image_ep_info.pc = PLAT_NS_IMAGE_OFFSET; + bl33_image_ep_info.spsr = get_spsr_for_bl33_entry(); + SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); + +#ifdef SPD_opteed + /* Populate entry point information for BL32 */ + SET_PARAM_HEAD(&bl32_image_ep_info, PARAM_EP, VERSION_1, 0); + SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE); + bl32_image_ep_info.pc = BL32_BASE; + bl32_image_ep_info.spsr = 0; + + /* Pass TEE base and size to bl33 */ + bl33_image_ep_info.args.arg1 = BL32_BASE; + bl33_image_ep_info.args.arg2 = BL32_SIZE; +#endif + + bl31_tzc380_setup(); +} + +void bl31_plat_arch_setup(void) +{ + mmap_add_region(BL31_BASE, BL31_BASE, (BL31_LIMIT - BL31_BASE), + MT_MEMORY | MT_RW | MT_SECURE); + mmap_add_region(BL_CODE_BASE, BL_CODE_BASE, (BL_CODE_END - BL_CODE_BASE), + MT_MEMORY | MT_RO | MT_SECURE); +#if USE_COHERENT_MEM + mmap_add_region(BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_BASE, + (BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE), + MT_DEVICE | MT_RW | MT_SECURE); +#endif + mmap_add(imx_mmap); + + init_xlat_tables(); + + enable_mmu_el3(0); +} + +void bl31_platform_setup(void) +{ + generic_delay_timer_init(); + + /* select the CKIL source to 32K OSC */ + mmio_write_32(IMX_ANAMIX_BASE + ANAMIX_MISC_CTL, 0x1); + + plat_gic_driver_init(); + plat_gic_init(); + + imx_gpc_init(); +} + +entry_point_info_t *bl31_plat_get_next_image_ep_info(unsigned int type) +{ + if (type == NON_SECURE) { + return &bl33_image_ep_info; + } + + if (type == SECURE) { + return &bl32_image_ep_info; + } + + return NULL; +} + +unsigned int plat_get_syscnt_freq2(void) +{ + return COUNTER_FREQUENCY; +} diff --git a/plat/imx/imx8m/imx8mp/imx8mp_psci.c b/plat/imx/imx8m/imx8mp/imx8mp_psci.c new file mode 100644 index 000000000..bc7b24679 --- /dev/null +++ b/plat/imx/imx8m/imx8mp/imx8mp_psci.c @@ -0,0 +1,44 @@ +/* + * Copyright 2020 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +static const plat_psci_ops_t imx_plat_psci_ops = { + .pwr_domain_on = imx_pwr_domain_on, + .pwr_domain_on_finish = imx_pwr_domain_on_finish, + .pwr_domain_off = imx_pwr_domain_off, + .validate_ns_entrypoint = imx_validate_ns_entrypoint, + .validate_power_state = imx_validate_power_state, + .cpu_standby = imx_cpu_standby, + .pwr_domain_suspend = imx_domain_suspend, + .pwr_domain_suspend_finish = imx_domain_suspend_finish, + .pwr_domain_pwr_down_wfi = imx_pwr_domain_pwr_down_wfi, + .get_sys_suspend_power_state = imx_get_sys_suspend_power_state, + .system_reset = imx_system_reset, + .system_off = imx_system_off, +}; + +/* export the platform specific psci ops */ +int plat_setup_psci_ops(uintptr_t sec_entrypoint, + const plat_psci_ops_t **psci_ops) +{ + /* sec_entrypoint is used for warm reset */ + imx_mailbox_init(sec_entrypoint); + + *psci_ops = &imx_plat_psci_ops; + + return 0; +} diff --git a/plat/imx/imx8m/imx8mp/include/gpc_reg.h b/plat/imx/imx8m/imx8mp/include/gpc_reg.h new file mode 100644 index 000000000..12da6ac7e --- /dev/null +++ b/plat/imx/imx8m/imx8mp/include/gpc_reg.h @@ -0,0 +1,149 @@ +/* + * Copyright 2020 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef GPC_REG_H +#define GPC_REG_H + +#define LPCR_A53_BSC 0x0 +#define LPCR_A53_BSC2 0x180 +#define LPCR_A53_AD 0x4 +#define LPCR_M4 0x8 +#define SLPCR 0x14 +#define MST_CPU_MAPPING 0x18 +#define MLPCR 0x20 +#define PGC_ACK_SEL_A53 0x24 +#define IMR1_CORE0_A53 0x30 +#define IMR1_CORE1_A53 0x44 +#define IMR1_CORE2_A53 0x194 +#define IMR1_CORE3_A53 0x1A8 +#define IMR1_CORE0_M4 0x58 + +#define SLT0_CFG 0x200 +#define GPC_PU_PWRHSK 0x190 +#define PGC_CPU_0_1_MAPPING 0x1CC +#define CPU_PGC_UP_TRG 0xD0 +#define PU_PGC_UP_TRG 0xD8 +#define CPU_PGC_DN_TRG 0xDC +#define PU_PGC_DN_TRG 0xE4 +#define LPS_CPU1 0xEC + +#define A53_CORE0_PGC 0x800 +#define A53_PLAT_PGC 0x900 +#define PLAT_PGC_PCR 0x900 +#define NOC_PGC_PCR 0xa40 +#define PGC_SCU_TIMING 0x910 + +#define MASK_DSM_TRIGGER_A53 BIT(31) +#define IRQ_SRC_A53_WUP BIT(30) +#define IRQ_SRC_A53_WUP_SHIFT 30 +#define IRQ_SRC_C1 BIT(29) +#define IRQ_SRC_C0 BIT(28) +#define IRQ_SRC_C3 BIT(23) +#define IRQ_SRC_C2 BIT(22) +#define CPU_CLOCK_ON_LPM BIT(14) +#define A53_CLK_ON_LPM BIT(14) +#define MASTER0_LPM_HSK BIT(6) +#define MASTER1_LPM_HSK BIT(7) +#define MASTER2_LPM_HSK BIT(8) + +#define L2PGE BIT(31) +#define EN_L2_WFI_PDN BIT(5) +#define EN_PLAT_PDN BIT(4) + +#define SLPCR_EN_DSM BIT(31) +#define SLPCR_RBC_EN BIT(30) +#define SLPCR_A53_FASTWUP_STOP_MODE BIT(17) +#define SLPCR_A53_FASTWUP_WAIT_MODE BIT(16) +#define SLPCR_VSTBY BIT(2) +#define SLPCR_SBYOS BIT(1) +#define SLPCR_BYPASS_PMIC_READY BIT(0) +#define SLPCR_RBC_COUNT_SHIFT 24 +#define SLPCR_STBY_COUNT_SHFT 3 + +#define A53_DUMMY_PDN_ACK BIT(30) +#define A53_DUMMY_PUP_ACK BIT(31) +#define A53_PLAT_PDN_ACK BIT(8) +#define A53_PLAT_PUP_ACK BIT(9) + +#define NOC_PDN_SLT_CTRL BIT(12) +#define NOC_PUP_SLT_CTRL BIT(13) +#define NOC_PGC_PDN_ACK BIT(12) +#define NOC_PGC_PUP_ACK BIT(13) + +#define PLAT_PUP_SLT_CTRL BIT(9) +#define PLAT_PDN_SLT_CTRL BIT(8) + +#define SLT_PLAT_PDN BIT(8) +#define SLT_PLAT_PUP BIT(9) + +#define MASTER1_MAPPING BIT(1) +#define MASTER2_MAPPING BIT(2) + +#define TMR_TCD2_SHIFT 0 +#define TMC_TMR_SHIFT 10 +#define TRC1_TMC_SHIFT 20 + +#define MIPI_PHY1_PWR_REQ BIT(0) +#define PCIE_PHY_PWR_REQ BIT(1) +#define USB1_PHY_PWR_REQ BIT(2) +#define USB2_PHY_PWR_REQ BIT(3) +#define MLMIX_PWR_REQ BIT(4) +#define AUDIOMIX_PWR_REQ BIT(5) +#define GPU2D_PWR_REQ BIT(6) +#define GPUMIX_PWR_REQ BIT(7) +#define VPUMIX_PWR_REQ BIT(8) +#define GPU3D_PWR_REQ BIT(9) +#define MEDIAMIX_PWR_REQ BIT(10) +#define VPU_G1_PWR_REQ BIT(11) +#define VPU_G2_PWR_REQ BIT(12) +#define VPU_H1_PWR_REQ BIT(13) +#define HDMIMIX_PWR_REQ BIT(14) +#define HDMI_PHY_PWR_REQ BIT(15) +#define MIPI_PHY2_PWR_REQ BIT(16) +#define HSIOMIX_PWR_REQ BIT(17) +#define MEDIAMIX_ISPDWP_PWR_REQ BIT(18) +#define DDRMIX_PWR_REQ BIT(19) + +#define AUDIOMIX_ADB400_SYNC (BIT(4) | BIT(15)) +#define MLMIX_ADB400_SYNC (BIT(7) | BIT(8)) +#define GPUMIX_ADB400_SYNC BIT(9) +#define VPUMIX_ADB400_SYNC BIT(10) +#define DDRMIX_ADB400_SYNC BIT(11) +#define HSIOMIX_ADB400_SYNC BIT(12) +#define HDMIMIX_ADB400_SYNC BIT(13) +#define MEDIAMIX_ADB400_SYNC BIT(14) + +#define AUDIOMIX_ADB400_ACK (BIT(20) | BIT(31)) +#define MLMIX_ADB400_ACK (BIT(23) | BIT(24)) +#define GPUMIX_ADB400_ACK BIT(25) +#define VPUMIX_ADB400_ACK BIT(26) +#define DDRMIX_ADB400_ACK BIT(27) +#define HSIOMIX_ADB400_ACK BIT(28) +#define HDMIMIX_ADB400_ACK BIT(29) +#define MEDIAMIX_ADB400_ACK BIT(30) + +#define MIPI_PHY1_PGC 0xb00 +#define PCIE_PHY_PGC 0xb40 +#define USB1_PHY_PGC 0xb80 +#define USB2_PHY_PGC 0xbc0 +#define MLMIX_PGC 0xc00 +#define AUDIOMIX_PGC 0xc40 +#define GPU2D_PGC 0xc80 +#define GPUMIX_PGC 0xcc0 +#define VPUMIX_PGC 0xd00 +#define GPU3D_PGC 0xd40 +#define MEDIAMIX_PGC 0xd80 +#define VPU_G1_PGC 0xdc0 +#define VPU_G2_PGC 0xe00 +#define VPU_H1_PGC 0xe40 +#define HDMIMIX_PGC 0xe80 +#define HDMI_PHY_PGC 0xec0 +#define MIPI_PHY2_PGC 0xf00 +#define HSIOMIX_PGC 0xf40 +#define MEDIAMIX_ISPDWP_PGC 0xf80 +#define DDRMIX_PGC 0xfc0 + +#endif /* GPC_REG_H */ diff --git a/plat/imx/imx8m/imx8mp/include/platform_def.h b/plat/imx/imx8m/imx8mp/include/platform_def.h new file mode 100644 index 000000000..644adc771 --- /dev/null +++ b/plat/imx/imx8m/imx8mp/include/platform_def.h @@ -0,0 +1,154 @@ +/* + * Copyright 2020 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +#include +#include + +#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64" +#define PLATFORM_LINKER_ARCH aarch64 + +#define PLATFORM_STACK_SIZE 0xB00 +#define CACHE_WRITEBACK_GRANULE 64 + +#define PLAT_PRIMARY_CPU U(0x0) +#define PLATFORM_MAX_CPU_PER_CLUSTER U(4) +#define PLATFORM_CLUSTER_COUNT U(1) +#define PLATFORM_CLUSTER0_CORE_COUNT U(4) +#define PLATFORM_CLUSTER1_CORE_COUNT U(0) +#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER0_CORE_COUNT) + +#define IMX_PWR_LVL0 MPIDR_AFFLVL0 +#define IMX_PWR_LVL1 MPIDR_AFFLVL1 +#define IMX_PWR_LVL2 MPIDR_AFFLVL2 + +#define PWR_DOMAIN_AT_MAX_LVL U(1) +#define PLAT_MAX_PWR_LVL U(2) +#define PLAT_MAX_OFF_STATE U(4) +#define PLAT_MAX_RET_STATE U(2) + +#define PLAT_WAIT_RET_STATE U(1) +#define PLAT_STOP_OFF_STATE U(3) + +#define BL31_BASE U(0x960000) +#define BL31_LIMIT U(0x980000) + +/* non-secure uboot base */ +#define PLAT_NS_IMAGE_OFFSET U(0x40200000) + +/* GICv3 base address */ +#define PLAT_GICD_BASE U(0x38800000) +#define PLAT_GICR_BASE U(0x38880000) + +#define PLAT_VIRT_ADDR_SPACE_SIZE (ULL(1) << 32) +#define PLAT_PHY_ADDR_SPACE_SIZE (ULL(1) << 32) + +#define MAX_XLAT_TABLES 8 +#define MAX_MMAP_REGIONS 16 + +#define HAB_RVT_BASE U(0x00000900) /* HAB_RVT for i.MX8MM */ + +#define IMX_BOOT_UART_CLK_IN_HZ 24000000 /* Select 24MHz oscillator */ +#define PLAT_CRASH_UART_BASE IMX_BOOT_UART_BASE +#define PLAT_CRASH_UART_CLK_IN_HZ 24000000 +#define IMX_CONSOLE_BAUDRATE 115200 + +#define IMX_AIPSTZ1 U(0x301f0000) +#define IMX_AIPSTZ2 U(0x305f0000) +#define IMX_AIPSTZ3 U(0x309f0000) +#define IMX_AIPSTZ4 U(0x32df0000) +#define IMX_AIPSTZ5 U(0x30df0000) + +#define IMX_AIPS_BASE U(0x30000000) +#define IMX_AIPS_SIZE U(0x3000000) +#define IMX_GPV_BASE U(0x32000000) +#define IMX_GPV_SIZE U(0x800000) +#define IMX_AIPS1_BASE U(0x30200000) +#define IMX_AIPS4_BASE U(0x32c00000) +#define IMX_ANAMIX_BASE U(0x30360000) +#define IMX_CCM_BASE U(0x30380000) +#define IMX_SRC_BASE U(0x30390000) +#define IMX_GPC_BASE U(0x303a0000) +#define IMX_RDC_BASE U(0x303d0000) +#define IMX_CSU_BASE U(0x303e0000) +#define IMX_WDOG_BASE U(0x30280000) +#define IMX_SNVS_BASE U(0x30370000) +#define IMX_NOC_BASE U(0x32700000) +#define IMX_NOC_SIZE U(0x100000) +#define IMX_TZASC_BASE U(0x32F80000) +#define IMX_IOMUX_GPR_BASE U(0x30340000) +#define IMX_CAAM_BASE U(0x30900000) +#define IMX_DDRC_BASE U(0x3d400000) +#define IMX_DDRPHY_BASE U(0x3c000000) +#define IMX_DDR_IPS_BASE U(0x3d000000) +#define IMX_DDR_IPS_SIZE U(0x1800000) +#define IMX_ROM_BASE U(0x0) + +#define IMX_GIC_BASE PLAT_GICD_BASE +#define IMX_GIC_SIZE U(0x200000) + +#define IMX_HSIOMIX_CTL_BASE U(0x32f10000) +#define IMX_HDMI_CTL_BASE U(0x32fc0000) +#define RTX_RESET_CTL0 U(0x20) +#define RTX_CLK_CTL0 U(0x40) +#define RTX_CLK_CTL1 U(0x50) +#define TX_CONTROL0 U(0x200) +#define TX_CONTROL1 U(0x220) + +#define IMX_MEDIAMIX_CTL_BASE U(0x32ec0000) +#define RSTn_CSR U(0x0) +#define CLK_EN_CSR U(0x4) +#define RST_DIV U(0x8) +#define LCDIF_ARCACHE_CTRL U(0x4c) +#define ISI_CACHE_CTRL U(0x50) + +#define WDOG_WSR U(0x2) +#define WDOG_WCR_WDZST BIT(0) +#define WDOG_WCR_WDBG BIT(1) +#define WDOG_WCR_WDE BIT(2) +#define WDOG_WCR_WDT BIT(3) +#define WDOG_WCR_SRS BIT(4) +#define WDOG_WCR_WDA BIT(5) +#define WDOG_WCR_SRE BIT(6) +#define WDOG_WCR_WDW BIT(7) + +#define SRC_A53RCR0 U(0x4) +#define SRC_A53RCR1 U(0x8) +#define SRC_OTG1PHY_SCR U(0x20) +#define SRC_OTG2PHY_SCR U(0x24) +#define SRC_GPR1_OFFSET U(0x74) + +#define SNVS_LPCR U(0x38) +#define SNVS_LPCR_SRTC_ENV BIT(0) +#define SNVS_LPCR_DP_EN BIT(5) +#define SNVS_LPCR_TOP BIT(6) + +#define IOMUXC_GPR10 U(0x28) +#define GPR_TZASC_EN BIT(0) +#define GPR_TZASC_EN_LOCK BIT(16) + +#define ANAMIX_MISC_CTL U(0x124) +#define DRAM_PLL_CTRL (IMX_ANAMIX_BASE + 0x50) + +#define MAX_CSU_NUM U(64) + +#define OCRAM_S_BASE U(0x00180000) +#define OCRAM_S_SIZE U(0x8000) +#define OCRAM_S_LIMIT (OCRAM_S_BASE + OCRAM_S_SIZE) +#define SAVED_DRAM_TIMING_BASE OCRAM_S_BASE + +#define COUNTER_FREQUENCY 8000000 /* 8MHz */ + +#define IMX_WDOG_B_RESET + +#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 */ +#define DDRC_MAP MAP_REGION_FLAT(IMX_DDRPHY_BASE, IMX_DDR_IPS_SIZE, MT_DEVICE | MT_RW) /* DDRMIX */ +#define NOC_MAP MAP_REGION_FLAT(IMX_NOC_BASE, IMX_NOC_SIZE, MT_DEVICE | MT_RW) /* NOC QoS */ + +#endif /* platform_def.h */ diff --git a/plat/imx/imx8m/imx8mp/platform.mk b/plat/imx/imx8m/imx8mp/platform.mk new file mode 100644 index 000000000..1d11e3df4 --- /dev/null +++ b/plat/imx/imx8m/imx8mp/platform.mk @@ -0,0 +1,56 @@ +# +# Copyright 2019-2020 NXP +# +# SPDX-License-Identifier: BSD-3-Clause +# + +PLAT_INCLUDES := -Iplat/imx/common/include \ + -Iplat/imx/imx8m/include \ + -Iplat/imx/imx8m/imx8mp/include +# Translation tables library +include lib/xlat_tables_v2/xlat_tables.mk + +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk + +IMX_GIC_SOURCES := ${GICV3_SOURCES} \ + plat/common/plat_gicv3.c \ + plat/common/plat_psci_common.c \ + plat/imx/common/plat_imx8_gic.c + +BL31_SOURCES += plat/imx/common/imx8_helpers.S \ + plat/imx/imx8m/gpc_common.c \ + plat/imx/imx8m/imx_aipstz.c \ + plat/imx/imx8m/imx_rdc.c \ + plat/imx/imx8m/imx8m_caam.c \ + plat/imx/imx8m/imx8m_psci_common.c \ + plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c \ + plat/imx/imx8m/imx8mp/imx8mp_psci.c \ + plat/imx/imx8m/imx8mp/gpc.c \ + plat/imx/common/imx8_topology.c \ + plat/imx/common/imx_sip_handler.c \ + plat/imx/common/imx_sip_svc.c \ + plat/imx/common/imx_uart_console.S \ + lib/cpus/aarch64/cortex_a53.S \ + drivers/arm/tzc/tzc380.c \ + drivers/delay_timer/delay_timer.c \ + drivers/delay_timer/generic_delay_timer.c \ + ${IMX_GIC_SOURCES} \ + ${XLAT_TABLES_LIB_SRCS} + +USE_COHERENT_MEM := 1 +RESET_TO_BL31 := 1 +A53_DISABLE_NON_TEMPORAL_HINT := 0 + +ERRATA_A53_835769 := 1 +ERRATA_A53_843419 := 1 +ERRATA_A53_855873 := 1 + +BL32_BASE ?= 0x56000000 +$(eval $(call add_define,BL32_BASE)) + +BL32_SIZE ?= 0x2000000 +$(eval $(call add_define,BL32_SIZE)) + +IMX_BOOT_UART_BASE ?= 0x30890000 +$(eval $(call add_define,IMX_BOOT_UART_BASE)) diff --git a/plat/imx/imx8m/include/gpc.h b/plat/imx/imx8m/include/gpc.h index 864c8cc5f..89a0b9d39 100644 --- a/plat/imx/imx8m/include/gpc.h +++ b/plat/imx/imx8m/include/gpc.h @@ -28,6 +28,33 @@ #define IRQ_IMR_NUM 4 #define IMR_MASK_ALL 0xffffffff +#define IMX_PD_DOMAIN(name, on) \ + { \ + .pwr_req = name##_PWR_REQ, \ + .pgc_offset = name##_PGC, \ + .need_sync = false, \ + .always_on = true, \ + } + +#define IMX_MIX_DOMAIN(name, on) \ + { \ + .pwr_req = name##_PWR_REQ, \ + .pgc_offset = name##_PGC, \ + .adb400_sync = name##_ADB400_SYNC, \ + .adb400_ack = name##_ADB400_ACK, \ + .need_sync = true, \ + .always_on = true, \ + } + +struct imx_pwr_domain { + uint32_t pwr_req; + uint32_t adb400_sync; + uint32_t adb400_ack; + uint32_t pgc_offset; + bool need_sync; + bool always_on; +}; + /* function declare */ void imx_gpc_init(void); void imx_set_cpu_secure_entry(unsigned int core_index, uintptr_t sec_entrypoint); -- cgit v1.2.3 From a79df348a54a7c959eeb8aed0fb93d6aad7faf1f Mon Sep 17 00:00:00 2001 From: Konstantin Porotchkin Date: Wed, 1 May 2019 17:08:18 +0300 Subject: tools: doimage: migrate to mbedtls v2.8 APIs Replace deprecated mbedtls_sha256 with mbedtls_sha256_ret The mbedtls_pk_parse_key does not work correctly anymore with the DER buffer embedded in the secure image extentson using the buffer size as the the key length. Move to mbedtls_pk_parse_subpubkey API that handles such case correctly. The DER format already contains the key length, so there is no particular reason to supply it to the key parser. Update the doimage version to 3.3 Change-Id: I0ec5ee84b7d1505b43138e0b7a6bdba44a6702b6 Signed-off-by: Konstantin Porotchkin --- tools/marvell/doimage/doimage.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/tools/marvell/doimage/doimage.c b/tools/marvell/doimage/doimage.c index 82fd375f1..deb0cbdb8 100644 --- a/tools/marvell/doimage/doimage.c +++ b/tools/marvell/doimage/doimage.c @@ -51,7 +51,7 @@ /* Number of address pairs in control array */ #define CP_CTRL_EL_ARRAY_SZ 32 -#define VERSION_STRING "Marvell(C) doimage utility version 3.2" +#define VERSION_STRING "Marvell(C) doimage utility version 3.3" /* A8K definitions */ @@ -303,7 +303,7 @@ int create_rsa_signature(mbedtls_pk_context *pk_ctx, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256); /* First compute the SHA256 hash for the input blob */ - mbedtls_sha256(input, ilen, hash, 0); + mbedtls_sha256_ret(input, ilen, hash, 0); /* Then calculate the hash signature */ rval = mbedtls_rsa_rsassa_pss_sign(mbedtls_pk_rsa(*pk_ctx), @@ -354,6 +354,7 @@ int verify_rsa_signature(const unsigned char *pub_key, mbedtls_pk_context pk_ctx; unsigned char hash[32]; int rval; + unsigned char *pkey = (unsigned char *)pub_key; /* Not sure this is required, * but it's safer to start with empty buffer @@ -373,8 +374,7 @@ int verify_rsa_signature(const unsigned char *pub_key, } /* Check ability to read the public key */ - rval = mbedtls_pk_parse_public_key(&pk_ctx, pub_key, - MAX_RSA_DER_BYTE_LEN); + rval = mbedtls_pk_parse_subpubkey(&pkey, pub_key + klen, &pk_ctx); if (rval != 0) { fprintf(stderr, " Failed in pk_parse_public_key (%#x)!\n", rval); @@ -387,7 +387,7 @@ int verify_rsa_signature(const unsigned char *pub_key, MBEDTLS_MD_SHA256); /* Compute the SHA256 hash for the input buffer */ - mbedtls_sha256(input, ilen, hash, 0); + mbedtls_sha256_ret(input, ilen, hash, 0); rval = mbedtls_rsa_rsassa_pss_verify(mbedtls_pk_rsa(pk_ctx), mbedtls_ctr_drbg_random, @@ -458,7 +458,7 @@ int image_encrypt(uint8_t *buf, uint32_t blen) /* compute SHA-256 digest of the results * and use it as the init vector (IV) */ - mbedtls_sha256(IV, AES_BLOCK_SZ, digest, 0); + mbedtls_sha256_ret(IV, AES_BLOCK_SZ, digest, 0); memcpy(IV, digest, AES_BLOCK_SZ); mbedtls_aes_setkey_enc(&aes_ctx, opts.sec_opts->aes_key, AES_KEY_BIT_LEN); @@ -880,11 +880,13 @@ int format_sec_ext(char *filename, FILE *out_fd) fname); return 1; } + /* Data in the output buffer is aligned to the buffer end */ der_buf_start = output_buf + sizeof(output_buf) - output_len; /* In the header DER data is aligned * to the start of appropriate field */ + bzero(out_der_key, MAX_RSA_DER_BYTE_LEN); memcpy(out_der_key, der_buf_start, output_len); } /* for every private key file */ @@ -899,8 +901,10 @@ int format_sec_ext(char *filename, FILE *out_fd) fprintf(stderr, "Failed to sign CSK keys block!\n"); return 1; } + /* Check that everything is correct */ - if (verify_rsa_signature(sec_ext.kak_key, MAX_RSA_DER_BYTE_LEN, + if (verify_rsa_signature(sec_ext.kak_key, + MAX_RSA_DER_BYTE_LEN, &sec_ext.csk_keys[0][0], sizeof(sec_ext.csk_keys), opts.sec_opts->kak_key_file, @@ -1333,7 +1337,7 @@ int parse_image(uint8_t *buf, int size) goto error; } - mbedtls_sha256(sec_entry->kak_key, + mbedtls_sha256_ret(sec_entry->kak_key, MAX_RSA_DER_BYTE_LEN, hash, 0); fprintf(stdout, ">>>>>>>>>> KAK KEY HASH >>>>>>>>>>\n"); -- cgit v1.2.3 From 5985a1e4264ac50f0b3408315c43ac65f3f5c631 Mon Sep 17 00:00:00 2001 From: Konstantin Porotchkin Date: Thu, 2 May 2019 15:10:07 +0300 Subject: tools: doimage: change the binary image alignment to 16 Change the binary image alignment from 4 to 16. The PKCS signature verification fails for unaligned images. Change-Id: Ieb08dc3ea128790f542ad93e3c948117567a65af Signed-off-by: Konstantin Porotchkin --- tools/marvell/doimage/doimage.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/tools/marvell/doimage/doimage.c b/tools/marvell/doimage/doimage.c index deb0cbdb8..e08b82072 100644 --- a/tools/marvell/doimage/doimage.c +++ b/tools/marvell/doimage/doimage.c @@ -1563,13 +1563,9 @@ error: int write_boot_image(uint8_t *buf, uint32_t image_size, FILE *out_fd) { - int aligned_size; int written; - /* Image size must be aligned to 4 bytes */ - aligned_size = (image_size + 3) & (~0x3); - - written = fwrite(buf, aligned_size, 1, out_fd); + written = fwrite(buf, image_size, 1, out_fd); if (written != 1) { fprintf(stderr, "Error: Failed to write boot image\n"); goto error; @@ -1591,7 +1587,7 @@ int main(int argc, char *argv[]) int ext_cnt = 0; int opt; int ret = 0; - int image_size; + int image_size, file_size; uint8_t *image_buf = NULL; int read; size_t len; @@ -1687,16 +1683,18 @@ int main(int argc, char *argv[]) goto main_exit; } - /* Read the input file to buffer */ - image_size = get_file_size(in_file); - image_buf = calloc((image_size + AES_BLOCK_SZ - 1) & - ~(AES_BLOCK_SZ - 1), 1); + /* Read the input file to buffer + * Always align the image to 16 byte boundary + */ + file_size = get_file_size(in_file); + image_size = (file_size + AES_BLOCK_SZ - 1) & ~(AES_BLOCK_SZ - 1); + image_buf = calloc(image_size, 1); if (image_buf == NULL) { fprintf(stderr, "Error: failed allocating input buffer\n"); return 1; } - read = fread(image_buf, image_size, 1, in_fd); + read = fread(image_buf, file_size, 1, in_fd); if (read != 1) { fprintf(stderr, "Error: failed to read input file\n"); goto main_exit; -- cgit v1.2.3 From 9b88367323a3217c22f3114acad6c8cf1db539c8 Mon Sep 17 00:00:00 2001 From: Grzegorz Jaszczyk Date: Fri, 12 Apr 2019 16:53:49 +0200 Subject: drivers: marvell: mg_conf_cm3: add basic driver Implement function which will allow to start AP FW. Change-Id: Ie0fc8ad138bf56b10809cdc92d1e5e96a2aaf33f Signed-off-by: Grzegorz Jaszczyk --- drivers/marvell/mg_conf_cm3/mg_conf_cm3.c | 33 ++++++++++++++++++++++++++++ drivers/marvell/mg_conf_cm3/mg_conf_cm3.h | 8 +++++++ plat/marvell/armada/a8k/common/a8k_common.mk | 3 ++- 3 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 drivers/marvell/mg_conf_cm3/mg_conf_cm3.c create mode 100644 drivers/marvell/mg_conf_cm3/mg_conf_cm3.h diff --git a/drivers/marvell/mg_conf_cm3/mg_conf_cm3.c b/drivers/marvell/mg_conf_cm3/mg_conf_cm3.c new file mode 100644 index 000000000..e249b5b38 --- /dev/null +++ b/drivers/marvell/mg_conf_cm3/mg_conf_cm3.c @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2019 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include +#include +#include + +/* CONFI REGISTERS */ +#define MG_CM3_CONFI_BASE(CP) (MVEBU_CP_REGS_BASE(CP) + 0x100000) +#define MG_CM3_CONFI_GLOB_CFG_REG(CP) (MG_CM3_CONFI_BASE(CP) + 0x2B500) +#define CM3_CPU_EN_BIT BIT(28) +#define MG_CM3_MG_INT_MFX_REG(CP) (MG_CM3_CONFI_BASE(CP) + 0x2B054) +#define CM3_SYS_RESET_BIT BIT(0) + +void mg_start_ap_fw(int cp_nr) +{ + if (mmio_read_32(MG_CM3_CONFI_GLOB_CFG_REG(cp_nr)) & CM3_CPU_EN_BIT) { + VERBOSE("cm3 already running\n"); + return; /* cm3 already running */ + } + + mmio_setbits_32(MG_CM3_CONFI_GLOB_CFG_REG(cp_nr), CM3_CPU_EN_BIT); + mmio_setbits_32(MG_CM3_MG_INT_MFX_REG(cp_nr), CM3_SYS_RESET_BIT); + + /* TODO: add some routine for checking if ap process is running, if not + * disable cm3. + */ +} diff --git a/drivers/marvell/mg_conf_cm3/mg_conf_cm3.h b/drivers/marvell/mg_conf_cm3/mg_conf_cm3.h new file mode 100644 index 000000000..44c7b698a --- /dev/null +++ b/drivers/marvell/mg_conf_cm3/mg_conf_cm3.h @@ -0,0 +1,8 @@ +/* + * Copyright (C) 2019 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +void mg_start_ap_fw(int cp_nr); diff --git a/plat/marvell/armada/a8k/common/a8k_common.mk b/plat/marvell/armada/a8k/common/a8k_common.mk index dcbf9a66e..0446b8de7 100644 --- a/plat/marvell/armada/a8k/common/a8k_common.mk +++ b/plat/marvell/armada/a8k/common/a8k_common.mk @@ -85,7 +85,8 @@ MARVELL_DRV := $(MARVELL_DRV_BASE)/io_win.c \ $(MARVELL_DRV_BASE)/ccu.c \ $(MARVELL_DRV_BASE)/cache_llc.c \ $(MARVELL_DRV_BASE)/comphy/phy-comphy-cp110.c \ - $(MARVELL_DRV_BASE)/mc_trustzone/mc_trustzone.c + $(MARVELL_DRV_BASE)/mc_trustzone/mc_trustzone.c \ + $(MARVELL_DRV_BASE)/mg_conf_cm3/mg_conf_cm3.c BL31_PORTING_SOURCES := $(BOARD_DIR)/board/marvell_plat_config.c -- cgit v1.2.3 From 5a9e46e69c154ee8f77dbec5e036774622b66ad3 Mon Sep 17 00:00:00 2001 From: Grzegorz Jaszczyk Date: Fri, 12 Apr 2019 16:57:14 +0200 Subject: marvell: comphy: start AP FW when comphy AP mode selected After configuring comphy to AP mode also start AP FW. Change-Id: Ib28977d7ee643575a818ba17f69dea0b7e8e0df4 Signed-off-by: Grzegorz Jaszczyk --- drivers/marvell/comphy/phy-comphy-cp110.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/marvell/comphy/phy-comphy-cp110.c b/drivers/marvell/comphy/phy-comphy-cp110.c index 2760f4603..7ca746070 100644 --- a/drivers/marvell/comphy/phy-comphy-cp110.c +++ b/drivers/marvell/comphy/phy-comphy-cp110.c @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -2231,6 +2232,7 @@ static int mvebu_cp110_comphy_ap_power_on(uint64_t comphy_base, uint32_t comphy_mode) { uint32_t mask, data; + uint8_t ap_nr, cp_nr; uintptr_t comphy_addr = comphy_addr = COMPHY_ADDR(comphy_base, comphy_index); @@ -2247,6 +2249,10 @@ static int mvebu_cp110_comphy_ap_power_on(uint64_t comphy_base, reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask); debug_exit(); + /* Start AP Firmware */ + mvebu_cp110_get_ap_and_cp_nr(&ap_nr, &cp_nr, comphy_base); + mg_start_ap_fw(cp_nr); + return 0; } -- cgit v1.2.3 From 0081cdd1c6d52b2d8b8ae15e16e096f428e2c499 Mon Sep 17 00:00:00 2001 From: Grzegorz Jaszczyk Date: Wed, 17 Apr 2019 11:24:43 +0200 Subject: plat: marvell: armada: move mg conf related code to appropriate driver Now when mg_conf_cm3 driver is present - move all relevant code there. Change-Id: I444d9e877c450d6ee69ca3a49b547e4c3aeac0be Signed-off-by: Grzegorz Jaszczyk --- drivers/marvell/mg_conf_cm3/mg_conf_cm3.c | 28 +++++++++++++++++++++- drivers/marvell/mg_conf_cm3/mg_conf_cm3.h | 1 + .../marvell/armada/common/mss/mss_scp_bl2_format.h | 1 - .../marvell/armada/common/mss/mss_scp_bootloader.c | 28 ++-------------------- 4 files changed, 30 insertions(+), 28 deletions(-) diff --git a/drivers/marvell/mg_conf_cm3/mg_conf_cm3.c b/drivers/marvell/mg_conf_cm3/mg_conf_cm3.c index e249b5b38..0efa30e93 100644 --- a/drivers/marvell/mg_conf_cm3/mg_conf_cm3.c +++ b/drivers/marvell/mg_conf_cm3/mg_conf_cm3.c @@ -8,15 +8,41 @@ #include #include #include -#include +#include /* CONFI REGISTERS */ #define MG_CM3_CONFI_BASE(CP) (MVEBU_CP_REGS_BASE(CP) + 0x100000) +#define MG_CM3_SRAM_BASE(CP) MG_CM3_CONFI_BASE(CP) #define MG_CM3_CONFI_GLOB_CFG_REG(CP) (MG_CM3_CONFI_BASE(CP) + 0x2B500) #define CM3_CPU_EN_BIT BIT(28) #define MG_CM3_MG_INT_MFX_REG(CP) (MG_CM3_CONFI_BASE(CP) + 0x2B054) #define CM3_SYS_RESET_BIT BIT(0) +#define MG_SRAM_SIZE 0x20000 /* 128KB */ + +int mg_image_load(uintptr_t src_addr, uint32_t size, int cp_index) +{ + uintptr_t mg_regs = MG_CM3_SRAM_BASE(cp_index); + + if (size > MG_SRAM_SIZE) { + ERROR("image is too big to fit into MG CM3 memory\n"); + return 1; + } + + NOTICE("Loading MG image from address 0x%lx Size 0x%x to MG at 0x%lx\n", + src_addr, size, mg_regs); + + /* Copy image to MG CM3 SRAM */ + memcpy((void *)mg_regs, (void *)src_addr, size); + + /* Don't release MG CM3 from reset - it will be done by next step + * bootloader (e.g. U-Boot), when appriopriate device-tree setup (which + * has enabeld 802.3. auto-neg) will be choosen. + */ + + return 0; +} + void mg_start_ap_fw(int cp_nr) { if (mmio_read_32(MG_CM3_CONFI_GLOB_CFG_REG(cp_nr)) & CM3_CPU_EN_BIT) { diff --git a/drivers/marvell/mg_conf_cm3/mg_conf_cm3.h b/drivers/marvell/mg_conf_cm3/mg_conf_cm3.h index 44c7b698a..8dfaa32db 100644 --- a/drivers/marvell/mg_conf_cm3/mg_conf_cm3.h +++ b/drivers/marvell/mg_conf_cm3/mg_conf_cm3.h @@ -6,3 +6,4 @@ */ void mg_start_ap_fw(int cp_nr); +int mg_image_load(uintptr_t src_addr, uint32_t size, int cp_index); diff --git a/plat/marvell/armada/common/mss/mss_scp_bl2_format.h b/plat/marvell/armada/common/mss/mss_scp_bl2_format.h index 7150f0a06..74dddc645 100644 --- a/plat/marvell/armada/common/mss/mss_scp_bl2_format.h +++ b/plat/marvell/armada/common/mss/mss_scp_bl2_format.h @@ -13,7 +13,6 @@ #define HEADER_VERSION 0x1 #define MSS_IDRAM_SIZE 0x10000 /* 64KB */ -#define MG_SRAM_SIZE 0x20000 /* 128KB */ /* Types definitions */ typedef struct file_header { diff --git a/plat/marvell/armada/common/mss/mss_scp_bootloader.c b/plat/marvell/armada/common/mss/mss_scp_bootloader.c index 4473d81e1..adf570ea9 100644 --- a/plat/marvell/armada/common/mss/mss_scp_bootloader.c +++ b/plat/marvell/armada/common/mss/mss_scp_bootloader.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -42,8 +43,6 @@ #define MSS_HANDSHAKE_TIMEOUT 50 -#define MG_CM3_SRAM_BASE(CP) (MVEBU_CP_REGS_BASE(CP) + 0x100000) - static int mss_check_image_ready(volatile struct mss_pm_ctrl_block *mss_pm_crtl) { int timeout = MSS_HANDSHAKE_TIMEOUT; @@ -61,28 +60,6 @@ static int mss_check_image_ready(volatile struct mss_pm_ctrl_block *mss_pm_crtl) return 0; } -static int mg_image_load(uintptr_t src_addr, uint32_t size, uintptr_t mg_regs) -{ - if (size > MG_SRAM_SIZE) { - ERROR("image is too big to fit into MG CM3 memory\n"); - return 1; - } - - NOTICE("Loading MG image from address 0x%lx Size 0x%x to MG at 0x%lx\n", - src_addr, size, mg_regs); - - /* Copy image to MG CM3 SRAM */ - memcpy((void *)mg_regs, (void *)src_addr, size); - - /* - * Don't release MG CM3 from reset - it will be done by next step - * bootloader (e.g. U-Boot), when appriopriate device-tree setup (which - * has enabeld 802.3. auto-neg) will be choosen. - */ - - return 0; -} - static int mss_image_load(uint32_t src_addr, uint32_t size, uintptr_t mss_regs) { uint32_t i, loop_num, timeout; @@ -258,8 +235,7 @@ static int load_img_to_cm3(enum cm3_t cm3_type, break; } NOTICE("Load image to CP%d MG\n", cp_index); - ret = mg_image_load(single_img, image_size, - MG_CM3_SRAM_BASE(cp_index)); + ret = mg_image_load(single_img, image_size, cp_index); if (ret != 0) { ERROR("SCP Image load failed\n"); return -1; -- cgit v1.2.3 From 2cae4a8586e253c00b3040152fd58b52168d89cd Mon Sep 17 00:00:00 2001 From: Grzegorz Jaszczyk Date: Tue, 18 Jun 2019 14:43:02 +0200 Subject: drivers: marvell: mg_conf_cm3: pass comphy lane number to AP FW Since the AP process can be enabled on different setups, the information about used comphy lane should be passed to AP FW. For instance: - A8K development board uses comphy lane 2 for eth 0 - cn913x development board uses comphy lane 4 for eth 0 Change-Id: Icf001fb3eea4d9c24c09384e49844ecaf8655ad2 Signed-off-by: Grzegorz Jaszczyk --- drivers/marvell/comphy/phy-comphy-cp110.c | 2 +- drivers/marvell/mg_conf_cm3/mg_conf_cm3.c | 46 ++++++++++++++++++++++++++++--- drivers/marvell/mg_conf_cm3/mg_conf_cm3.h | 2 +- 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/drivers/marvell/comphy/phy-comphy-cp110.c b/drivers/marvell/comphy/phy-comphy-cp110.c index 7ca746070..1d5b6f564 100644 --- a/drivers/marvell/comphy/phy-comphy-cp110.c +++ b/drivers/marvell/comphy/phy-comphy-cp110.c @@ -2251,7 +2251,7 @@ static int mvebu_cp110_comphy_ap_power_on(uint64_t comphy_base, /* Start AP Firmware */ mvebu_cp110_get_ap_and_cp_nr(&ap_nr, &cp_nr, comphy_base); - mg_start_ap_fw(cp_nr); + mg_start_ap_fw(cp_nr, comphy_index); return 0; } diff --git a/drivers/marvell/mg_conf_cm3/mg_conf_cm3.c b/drivers/marvell/mg_conf_cm3/mg_conf_cm3.c index 0efa30e93..98e189687 100644 --- a/drivers/marvell/mg_conf_cm3/mg_conf_cm3.c +++ b/drivers/marvell/mg_conf_cm3/mg_conf_cm3.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -18,8 +19,25 @@ #define MG_CM3_MG_INT_MFX_REG(CP) (MG_CM3_CONFI_BASE(CP) + 0x2B054) #define CM3_SYS_RESET_BIT BIT(0) +#define MG_CM3_SHARED_MEM_BASE(CP) (MG_CM3_SRAM_BASE(CP) + 0x1FC00ULL) + #define MG_SRAM_SIZE 0x20000 /* 128KB */ +#define MG_ACK_TIMEOUT 10 + +/** + * struct ap_sharedmem_ctrl - used to pass information between the HOST and CM3 + * @init_done: Set by CM3 when ap_proces initialzied. Host check if CM3 set + * this flag to confirm that the process is running + * @lane_nr: Set by Host to mark which comphy lane should be configure. E.g.: + * - A8K development board uses comphy lane 2 for eth0 + * - CN913x development board uses comphy lane 4 for eth0 + */ +struct ap_sharedmem_ctrl { + uint32_t init_done; + uint32_t lane_nr; +}; + int mg_image_load(uintptr_t src_addr, uint32_t size, int cp_index) { uintptr_t mg_regs = MG_CM3_SRAM_BASE(cp_index); @@ -43,17 +61,37 @@ int mg_image_load(uintptr_t src_addr, uint32_t size, int cp_index) return 0; } -void mg_start_ap_fw(int cp_nr) +void mg_start_ap_fw(int cp_nr, uint8_t comphy_index) { + volatile struct ap_sharedmem_ctrl *ap_shared_ctrl = + (void *)MG_CM3_SHARED_MEM_BASE(cp_nr); + int timeout = MG_ACK_TIMEOUT; + if (mmio_read_32(MG_CM3_CONFI_GLOB_CFG_REG(cp_nr)) & CM3_CPU_EN_BIT) { VERBOSE("cm3 already running\n"); return; /* cm3 already running */ } + /* + * Mark which comphy lane should be used - it will be read via shared + * mem by ap process + */ + ap_shared_ctrl->lane_nr = comphy_index; + /* Make sure it took place before enabling cm3 */ + dmbst(); + mmio_setbits_32(MG_CM3_CONFI_GLOB_CFG_REG(cp_nr), CM3_CPU_EN_BIT); mmio_setbits_32(MG_CM3_MG_INT_MFX_REG(cp_nr), CM3_SYS_RESET_BIT); - /* TODO: add some routine for checking if ap process is running, if not - * disable cm3. - */ + /* Check for ap process initialization by fw */ + while (ap_shared_ctrl->init_done != 1 && timeout--) + VERBOSE("Waiting for ap process ack, timeout %d\n", timeout); + + if (timeout == 0) { + ERROR("AP process failed, disabling cm3\n"); + mmio_clrbits_32(MG_CM3_MG_INT_MFX_REG(cp_nr), + CM3_SYS_RESET_BIT); + mmio_clrbits_32(MG_CM3_CONFI_GLOB_CFG_REG(cp_nr), + CM3_CPU_EN_BIT); + } } diff --git a/drivers/marvell/mg_conf_cm3/mg_conf_cm3.h b/drivers/marvell/mg_conf_cm3/mg_conf_cm3.h index 8dfaa32db..e2756de9c 100644 --- a/drivers/marvell/mg_conf_cm3/mg_conf_cm3.h +++ b/drivers/marvell/mg_conf_cm3/mg_conf_cm3.h @@ -5,5 +5,5 @@ * https://spdx.org/licenses */ -void mg_start_ap_fw(int cp_nr); +void mg_start_ap_fw(int cp_nr, uint8_t comphy_index); int mg_image_load(uintptr_t src_addr, uint32_t size, int cp_index); -- cgit v1.2.3 From 0eb3d1fc75e3929d2a29a934bdbe858177b26e07 Mon Sep 17 00:00:00 2001 From: Konstantin Porotchkin Date: Mon, 15 Apr 2019 16:25:59 +0300 Subject: plat: marvell: armada: adjust trusted DRAM size to match OP-TEE OS Area used as trusted DRAM is 12MB in Marvell OP-TEE OS module. It is followed by 4MB of shared memory. Change-Id: If8edeeec5861b529408baca25f78c06a0a440d8c Signed-off-by: Konstantin Porotchkin --- plat/marvell/armada/a3k/common/include/platform_def.h | 6 ++++-- plat/marvell/armada/a8k/common/include/platform_def.h | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/plat/marvell/armada/a3k/common/include/platform_def.h b/plat/marvell/armada/a3k/common/include/platform_def.h index 7f8f79a45..61c7dfe70 100644 --- a/plat/marvell/armada/a3k/common/include/platform_def.h +++ b/plat/marvell/armada/a3k/common/include/platform_def.h @@ -83,9 +83,11 @@ #define PLAT_MARVELL_TRUSTED_ROM_BASE PLAT_MARVELL_ATF_LOAD_ADDR /* 4 MB for FIP image */ #define PLAT_MARVELL_TRUSTED_ROM_SIZE 0x00400000 -/* Reserve 16M for SCP (Secure PayLoad) Trusted DRAM */ +/* Reserve 12M for SCP (Secure PayLoad) Trusted RAM + * OP-TEE SHMEM follows this region + */ #define PLAT_MARVELL_TRUSTED_RAM_BASE 0x04400000 -#define PLAT_MARVELL_TRUSTED_RAM_SIZE 0x01000000 /* 16 MB */ +#define PLAT_MARVELL_TRUSTED_RAM_SIZE 0x00C00000 /* 12 MB DRAM */ /* * PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size diff --git a/plat/marvell/armada/a8k/common/include/platform_def.h b/plat/marvell/armada/a8k/common/include/platform_def.h index b26e3ea1e..cbef3a173 100644 --- a/plat/marvell/armada/a8k/common/include/platform_def.h +++ b/plat/marvell/armada/a8k/common/include/platform_def.h @@ -96,9 +96,11 @@ #define PLAT_MARVELL_TRUSTED_ROM_BASE PLAT_MARVELL_ATF_LOAD_ADDR /* 4 MB for FIP image */ #define PLAT_MARVELL_TRUSTED_ROM_SIZE 0x00400000 -/* Reserve 16M for SCP (Secure PayLoad) Trusted RAM */ +/* Reserve 12M for SCP (Secure PayLoad) Trusted RAM + * OP-TEE SHMEM follows this region + */ #define PLAT_MARVELL_TRUSTED_RAM_BASE 0x04400000 -#define PLAT_MARVELL_TRUSTED_RAM_SIZE 0x01000000 /* 16 MB DRAM */ +#define PLAT_MARVELL_TRUSTED_RAM_SIZE 0x00C00000 /* 12 MB DRAM */ #define PLAT_MARVELL_LLC_SRAM_BASE PLAT_MARVELL_TRUSTED_RAM_BASE #define PLAT_MARVELL_LLC_SRAM_SIZE 0x00100000 /* 1 MB SRAM */ -- cgit v1.2.3 From 0a977b9b8bfc0356830d88e3602e2e5ef4a1ac06 Mon Sep 17 00:00:00 2001 From: Konstantin Porotchkin Date: Mon, 15 Apr 2019 16:32:59 +0300 Subject: plat: marvell: armada: a8k: change CCU LLC SRAM mapping MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The LLC SRAM will be enabled in OP-TEE OS for usage as secure storage. The CCU have to prepare SRAM window, but point to the DRAM-0 target until the SRAM is actually enabled. This patch changes CCU SRAM window target to DRAM-0 Remove dependence between LLC_SRAM and LLC_ENABLE and update the build documentation. The SRAМ base moved to follow the OP-TEE SHMEM area (0x05400000) Change-Id: I85c2434a3d515ec37da5ae8eb729e3280f91c456 Signed-off-by: Konstantin Porotchkin --- docs/plat/marvell/armada/build.rst | 10 ++++++---- plat/marvell/armada/a8k/a70x0/board/marvell_plat_config.c | 5 ++++- plat/marvell/armada/a8k/a70x0_amc/board/marvell_plat_config.c | 5 ++++- plat/marvell/armada/a8k/a80x0/board/marvell_plat_config.c | 5 ++++- .../marvell/armada/a8k/a80x0_mcbin/board/marvell_plat_config.c | 5 ++++- plat/marvell/armada/a8k/common/include/platform_def.h | 6 +++--- plat/marvell/armada/common/marvell_common.mk | 8 -------- 7 files changed, 25 insertions(+), 19 deletions(-) diff --git a/docs/plat/marvell/armada/build.rst b/docs/plat/marvell/armada/build.rst index bec0bcbd4..da4ba565a 100644 --- a/docs/plat/marvell/armada/build.rst +++ b/docs/plat/marvell/armada/build.rst @@ -79,10 +79,12 @@ There are several build options: - LLC_SRAM - Flag defining the LLC (L3) cache SRAM support. The feature is - disabled by default (``LLC_ENABLE=0``). - When LLC SRAM is enabled, the secure payload (BL32) is loaded into this - SRAM area instead of the DRAM. + Flag enabling the LLC (L3) cache SRAM support. The LLC SRAM is activated and used + by Trusted OS (OP-TEE OS, BL32). The TF-A only prepares CCU address translation windows + for SRAM address range at BL31 execution stage with window target set to DRAM-0. + When Trusted OS activates LLC SRAM, the CCU window target is changed to SRAM. + There is no reason to enable this feature if OP-TEE OS built with CFG_WITH_PAGER=n. + Only set LLC_SRAM=1 if OP-TEE OS is built with CFG_WITH_PAGER=y. - MARVELL_SECURE_BOOT diff --git a/plat/marvell/armada/a8k/a70x0/board/marvell_plat_config.c b/plat/marvell/armada/a8k/a70x0/board/marvell_plat_config.c index 7d30ebe5a..a40926102 100644 --- a/plat/marvell/armada/a8k/a70x0/board/marvell_plat_config.c +++ b/plat/marvell/armada/a8k/a70x0/board/marvell_plat_config.c @@ -103,7 +103,10 @@ struct addr_map_win ccu_memory_map[] = { /* IO window */ {0x00000000f2000000, 0x4000000, IO_0_TID}, /* IO window */ #else #if LLC_SRAM - {PLAT_MARVELL_LLC_SRAM_BASE, PLAT_MARVELL_LLC_SRAM_SIZE, SRAM_TID}, + /* 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 */ diff --git a/plat/marvell/armada/a8k/a70x0_amc/board/marvell_plat_config.c b/plat/marvell/armada/a8k/a70x0_amc/board/marvell_plat_config.c index 7fc33f1f9..3b68e91ba 100644 --- a/plat/marvell/armada/a8k/a70x0_amc/board/marvell_plat_config.c +++ b/plat/marvell/armada/a8k/a70x0_amc/board/marvell_plat_config.c @@ -94,7 +94,10 @@ struct addr_map_win ccu_memory_map[] = { {0x00000000f2000000, 0x4000000, IO_0_TID}, /* IO window */ #else #if LLC_SRAM - {PLAT_MARVELL_LLC_SRAM_BASE, PLAT_MARVELL_LLC_SRAM_SIZE, SRAM_TID}, + /* 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 */ diff --git a/plat/marvell/armada/a8k/a80x0/board/marvell_plat_config.c b/plat/marvell/armada/a8k/a80x0/board/marvell_plat_config.c index 856c07a6e..4ccda14e9 100644 --- a/plat/marvell/armada/a8k/a80x0/board/marvell_plat_config.c +++ b/plat/marvell/armada/a8k/a80x0/board/marvell_plat_config.c @@ -132,7 +132,10 @@ struct addr_map_win ccu_memory_map[] = { {0x00000000f2000000, 0x4000000, IO_0_TID}, /* IO window */ #else #if LLC_SRAM - {PLAT_MARVELL_LLC_SRAM_BASE, PLAT_MARVELL_LLC_SRAM_SIZE, SRAM_TID}, + /* 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}, /* IO window */ {0x00000000c0000000, 0x30000000, IO_0_TID}, /* IO window */ diff --git a/plat/marvell/armada/a8k/a80x0_mcbin/board/marvell_plat_config.c b/plat/marvell/armada/a8k/a80x0_mcbin/board/marvell_plat_config.c index 0edc97745..b9329675f 100644 --- a/plat/marvell/armada/a8k/a80x0_mcbin/board/marvell_plat_config.c +++ b/plat/marvell/armada/a8k/a80x0_mcbin/board/marvell_plat_config.c @@ -166,7 +166,10 @@ struct addr_map_win ccu_memory_map[] = { {0x00000000f2000000, 0x4000000, IO_0_TID}, /* IO window */ #else #if LLC_SRAM - {PLAT_MARVELL_LLC_SRAM_BASE, PLAT_MARVELL_LLC_SRAM_SIZE, SRAM_TID}, + /* 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}, /* IO window */ {0x00000000c0000000, 0x30000000, IO_0_TID}, /* IO window */ diff --git a/plat/marvell/armada/a8k/common/include/platform_def.h b/plat/marvell/armada/a8k/common/include/platform_def.h index cbef3a173..944a1517b 100644 --- a/plat/marvell/armada/a8k/common/include/platform_def.h +++ b/plat/marvell/armada/a8k/common/include/platform_def.h @@ -96,13 +96,13 @@ #define PLAT_MARVELL_TRUSTED_ROM_BASE PLAT_MARVELL_ATF_LOAD_ADDR /* 4 MB for FIP image */ #define PLAT_MARVELL_TRUSTED_ROM_SIZE 0x00400000 -/* Reserve 12M for SCP (Secure PayLoad) Trusted RAM - * OP-TEE SHMEM follows this region +/* Reserve 12MB for SCP (Secure PayLoad) Trusted RAM + * OP-TEE 4MB SHMEM follows this region */ #define PLAT_MARVELL_TRUSTED_RAM_BASE 0x04400000 #define PLAT_MARVELL_TRUSTED_RAM_SIZE 0x00C00000 /* 12 MB DRAM */ -#define PLAT_MARVELL_LLC_SRAM_BASE PLAT_MARVELL_TRUSTED_RAM_BASE +#define PLAT_MARVELL_LLC_SRAM_BASE 0x05400000 #define PLAT_MARVELL_LLC_SRAM_SIZE 0x00100000 /* 1 MB SRAM */ /* diff --git a/plat/marvell/armada/common/marvell_common.mk b/plat/marvell/armada/common/marvell_common.mk index fcc97acd3..5c8c7db2d 100644 --- a/plat/marvell/armada/common/marvell_common.mk +++ b/plat/marvell/armada/common/marvell_common.mk @@ -22,15 +22,7 @@ LLC_SRAM := 0 $(eval $(call add_define,LLC_SRAM)) # Enable/Disable LLC -ifeq (${LLC_SRAM}, 0) LLC_ENABLE := 1 -else -# When LLC_SRAM=1, the entire LLC converted to SRAM and enabled at BL1. -# All existing cases activating LLC at BL31 stage should be disabled. -# The below assignment does not allow changing the LLC_ENABLE -# value in the command line. -LLC_ENABLE = 0 -endif $(eval $(call add_define,LLC_ENABLE)) include lib/xlat_tables_v2/xlat_tables.mk -- cgit v1.2.3 From 506ff4c0c1d850c3fc18959a44c8280c46788734 Mon Sep 17 00:00:00 2001 From: Konstantin Porotchkin Date: Thu, 4 Apr 2019 10:02:20 +0300 Subject: drivers: marvell: Fix the LLC SRAM driver - Fix the line address macro - LLC invalidate and enable before ways lock for allocation - Add support for limited SRAM size allocation - Add SRAM RW test function Change-Id: I1867ece3047566ddd7931bd7472e1f47fb42c8d4 Signed-off-by: Konstantin Porotchkin --- drivers/marvell/cache_llc.c | 52 ++++++++++++++++++++++++++++++++----- include/drivers/marvell/cache_llc.h | 5 ++-- 2 files changed, 49 insertions(+), 8 deletions(-) diff --git a/drivers/marvell/cache_llc.c b/drivers/marvell/cache_llc.c index 836aae7b8..4b06b4752 100644 --- a/drivers/marvell/cache_llc.c +++ b/drivers/marvell/cache_llc.c @@ -111,28 +111,36 @@ void llc_runtime_enable(int ap_index) } #if LLC_SRAM -void llc_sram_enable(int ap_index) +int llc_sram_enable(int ap_index, int size) { - uint32_t tc, way; + uint32_t tc, way, ways_to_allocate; uint32_t way_addr; + if ((size <= 0) || (size > LLC_SIZE) || (size % LLC_WAY_SIZE)) + return -1; + + llc_enable(ap_index, 1); + llc_inv_all(ap_index); + + ways_to_allocate = size / LLC_WAY_SIZE; + /* Lockdown all available ways for all traffic classes */ for (tc = 0; tc < LLC_TC_NUM; tc++) - mmio_write_32(LLC_TCN_LOCK(ap_index, tc), LLC_WAY_MASK); + mmio_write_32(LLC_TCN_LOCK(ap_index, tc), LLC_ALL_WAYS_MASK); /* Clear the high bits of SRAM address */ mmio_write_32(LLC_BANKED_MNT_AHR(ap_index), 0); way_addr = PLAT_MARVELL_TRUSTED_RAM_BASE; - for (way = 0; way < LLC_WAYS; way++) { + for (way = 0; way < ways_to_allocate; way++) { /* Trigger allocation block command */ mmio_write_32(LLC_BLK_ALOC(ap_index), LLC_BLK_ALOC_BASE_ADDR(way_addr) | - LLC_BLK_ALOC_WAY_DATA_CLR | + LLC_BLK_ALOC_WAY_DATA_SET | LLC_BLK_ALOC_WAY_ID(way)); way_addr += LLC_WAY_SIZE; } - llc_enable(ap_index, 1); + return 0; } void llc_sram_disable(int ap_index) @@ -146,4 +154,36 @@ void llc_sram_disable(int ap_index) /* Invalidate all ways */ llc_inv_all(ap_index); } + +int llc_sram_test(int ap_index, int size, char *msg) +{ + uintptr_t addr, end_addr; + uint32_t data = 0; + + if ((size <= 0) || (size > LLC_SIZE)) + return -1; + + INFO("=== LLC SRAM WRITE test %s\n", msg); + for (addr = PLAT_MARVELL_TRUSTED_RAM_BASE, + end_addr = PLAT_MARVELL_TRUSTED_RAM_BASE + size; + addr < end_addr; addr += 4) { + mmio_write_32(addr, addr); + } + INFO("=== LLC SRAM WRITE test %s PASSED\n", msg); + INFO("=== LLC SRAM READ test %s\n", msg); + for (addr = PLAT_MARVELL_TRUSTED_RAM_BASE, + end_addr = PLAT_MARVELL_TRUSTED_RAM_BASE + size; + addr < end_addr; addr += 4) { + data = mmio_read_32(addr); + if (data != addr) { + INFO("=== LLC SRAM READ test %s FAILED @ 0x%08lx)\n", + msg, addr); + return -1; + } + } + INFO("=== LLC SRAM READ test %s PASSED (last read = 0x%08x)\n", + msg, data); + return 0; +} + #endif /* LLC_SRAM */ diff --git a/include/drivers/marvell/cache_llc.h b/include/drivers/marvell/cache_llc.h index b326474ee..d6dd65382 100644 --- a/include/drivers/marvell/cache_llc.h +++ b/include/drivers/marvell/cache_llc.h @@ -41,7 +41,7 @@ #define LLC_BLK_ALOC_WAY_DATA_DSBL (0x0 << 6) #define LLC_BLK_ALOC_WAY_DATA_CLR (0x1 << 6) #define LLC_BLK_ALOC_WAY_DATA_SET (0x3 << 6) -#define LLC_BLK_ALOC_BASE_ADDR(addr) ((addr) & (LLC_WAY_SIZE - 1)) +#define LLC_BLK_ALOC_BASE_ADDR(addr) ((addr) & ~(LLC_WAY_SIZE - 1)) #ifndef __ASSEMBLER__ void llc_cache_sync(int ap_index); @@ -53,8 +53,9 @@ void llc_enable(int ap_index, int excl_mode); int llc_is_exclusive(int ap_index); void llc_runtime_enable(int ap_index); #if LLC_SRAM -void llc_sram_enable(int ap_index); +int llc_sram_enable(int ap_index, int size); void llc_sram_disable(int ap_index); +int llc_sram_test(int ap_index, int size, char *msg); #endif /* LLC_SRAM */ #endif /* __ASSEMBLY__ */ -- cgit v1.2.3 From 41e8c6fcd1afcbbd13ed7af9ac9239ad0349dde7 Mon Sep 17 00:00:00 2001 From: Marcin Wojtas Date: Wed, 13 Nov 2019 13:31:48 +0100 Subject: plat: marvell: armada: fix BL32 extra parameters usage Update missing code releated to the BL32 payload. Change-Id: I5cbe71921467c53c45be5510f950cefdacc110e1 Signed-off-by: Marcin Wojtas --- .../common/aarch64/marvell_bl2_mem_params_desc.c | 39 ++++++++++++++++++++++ plat/marvell/armada/common/marvell_bl2_setup.c | 23 +++++++++++++ plat/marvell/armada/common/marvell_common.mk | 13 ++++++++ plat/marvell/armada/common/marvell_io_storage.c | 19 +++++++++++ 4 files changed, 94 insertions(+) diff --git a/plat/marvell/armada/common/aarch64/marvell_bl2_mem_params_desc.c b/plat/marvell/armada/common/aarch64/marvell_bl2_mem_params_desc.c index 6a8e11c90..8d909dc59 100644 --- a/plat/marvell/armada/common/aarch64/marvell_bl2_mem_params_desc.c +++ b/plat/marvell/armada/common/aarch64/marvell_bl2_mem_params_desc.c @@ -100,6 +100,45 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = { .next_handoff_image_id = BL33_IMAGE_ID, }, + + /* + * Fill BL32 external 1 related information. + * A typical use for extra1 image is with OP-TEE + * where it is the pager image. + */ + { + .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_LIMIT - BL32_BASE, + + .next_handoff_image_id = INVALID_IMAGE_ID, + }, + + /* + * Fill BL32 external 2 related information. + * A typical use for extra2 image is with OP-TEE, + * where it is the paged image. + */ + { + .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), +#ifdef SPD_opteed + .image_info.image_base = MARVELL_OPTEE_PAGEABLE_LOAD_BASE, + .image_info.image_max_size = MARVELL_OPTEE_PAGEABLE_LOAD_SIZE, +#endif + .next_handoff_image_id = INVALID_IMAGE_ID, + }, # endif /* BL32_BASE */ /* Fill BL33 related information */ diff --git a/plat/marvell/armada/common/marvell_bl2_setup.c b/plat/marvell/armada/common/marvell_bl2_setup.c index 3c1c39112..3dfa82e0e 100644 --- a/plat/marvell/armada/common/marvell_bl2_setup.c +++ b/plat/marvell/armada/common/marvell_bl2_setup.c @@ -17,6 +17,9 @@ #include #include +#ifdef SPD_opteed +#include +#endif #include #include @@ -97,9 +100,29 @@ int marvell_bl2_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); +#ifdef SPD_opteed + bl_mem_params_node_t *pager_mem_params = NULL; + bl_mem_params_node_t *paged_mem_params = NULL; +#endif /* SPD_opteed */ assert(bl_mem_params); switch (image_id) { + case BL32_IMAGE_ID: +#ifdef SPD_opteed + 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"); +#endif /* SPD_opteed */ + bl_mem_params->ep_info.spsr = marvell_get_spsr_for_bl32_entry(); + break; case BL33_IMAGE_ID: /* BL33 expects to receive the primary CPU MPID (through r0) */ diff --git a/plat/marvell/armada/common/marvell_common.mk b/plat/marvell/armada/common/marvell_common.mk index 5c8c7db2d..2e96e2f84 100644 --- a/plat/marvell/armada/common/marvell_common.mk +++ b/plat/marvell/armada/common/marvell_common.mk @@ -58,6 +58,10 @@ BL2_SOURCES += drivers/io/io_fip.c \ $(MARVELL_PLAT_BASE)/common/aarch64/marvell_bl2_mem_params_desc.c \ $(MARVELL_PLAT_BASE)/common/marvell_image_load.c +ifeq (${SPD},opteed) +PLAT_INCLUDES += -Iinclude/lib +BL2_SOURCES += lib/optee/optee_utils.c +endif BL31_SOURCES += $(MARVELL_PLAT_BASE)/common/marvell_bl31_setup.c \ $(MARVELL_PLAT_BASE)/common/marvell_pm.c \ @@ -69,6 +73,15 @@ BL31_SOURCES += $(MARVELL_PLAT_BASE)/common/marvell_bl31_setup.c \ # PSCI functionality $(eval $(call add_define,CONFIG_ARM64)) +# 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 + # MSS (SCP) build ifeq (${MSS_SUPPORT}, 1) include $(MARVELL_PLAT_BASE)/common/mss/mss_common.mk diff --git a/plat/marvell/armada/common/marvell_io_storage.c b/plat/marvell/armada/common/marvell_io_storage.c index 065f95688..2627ba4ef 100644 --- a/plat/marvell/armada/common/marvell_io_storage.c +++ b/plat/marvell/armada/common/marvell_io_storage.c @@ -43,6 +43,15 @@ static const io_uuid_spec_t bl31_uuid_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, }; @@ -83,6 +92,16 @@ static const struct plat_io_policy policies[] = { (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, -- cgit v1.2.3 From a5de4319ac4957ed42f9e7e774c6eb965ac819ed Mon Sep 17 00:00:00 2001 From: Grzegorz Jaszczyk Date: Mon, 10 Jun 2019 17:01:05 +0200 Subject: plat: marvell: armada: mcbin: squash several IO windows into one There is no need to open tree different IO window when there is possibility of having one covering required range. Change-Id: I9feae1fc583df1f7d97d28161cf7601f43513856 Signed-off-by: Grzegorz Jaszczyk --- plat/marvell/armada/a8k/a80x0_mcbin/board/marvell_plat_config.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/plat/marvell/armada/a8k/a80x0_mcbin/board/marvell_plat_config.c b/plat/marvell/armada/a8k/a80x0_mcbin/board/marvell_plat_config.c index b9329675f..75a1b0c30 100644 --- a/plat/marvell/armada/a8k/a80x0_mcbin/board/marvell_plat_config.c +++ b/plat/marvell/armada/a8k/a80x0_mcbin/board/marvell_plat_config.c @@ -78,12 +78,8 @@ struct addr_map_win io_win_memory_map[] = { /* CP1 (MCI0) internal regs */ {0x00000000f4000000, 0x2000000, MCI_0_TID}, #ifndef IMAGE_BLE - /* PCIe0 and SPI1_CS0 (RUNIT) on CP1*/ - {0x00000000f9000000, 0x2000000, MCI_0_TID}, - /* PCIe1 on CP1*/ - {0x00000000fb000000, 0x1000000, MCI_0_TID}, - /* PCIe2 on CP1*/ - {0x00000000fc000000, 0x1000000, MCI_0_TID}, + /* PCIe0-2 and SPI1_CS0 (RUNIT) on CP1*/ + {0x00000000f9000000, 0x4000000, MCI_0_TID}, /* MCI 0 indirect window */ {MVEBU_MCI_REG_BASE_REMAP(0), 0x100000, MCI_0_TID}, /* MCI 1 indirect window */ -- cgit v1.2.3 From fdf50a25ec8014378937e0a8d535d3f7d5753cc9 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Fri, 10 Jul 2020 09:44:21 +0100 Subject: plat/arm: Fix build failure due to increase in BL2 size BL2 size gets increased due to the libfdt library update and that eventually cause no-optimization build failure for BL2 as below: aarch64-none-elf-ld.bfd: BL2 image has exceeded its limit. aarch64-none-elf-ld.bfd: region `RAM' overflowed by 4096 bytes Makefile:1070: recipe for target 'build/fvp/debug/bl2/bl2.elf' failed make: *** [build/fvp/debug/bl2/bl2.elf] Error 1 Fixed build failure by increasing BL2 image size limit by 4Kb. Signed-off-by: Manish V Badarkhe Change-Id: I92a57eb4db601561a98e254b64994bb921a88db3 --- 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 7222c5519..f8fb821b3 100644 --- a/plat/arm/board/fvp/include/platform_def.h +++ b/plat/arm/board/fvp/include/platform_def.h @@ -120,7 +120,7 @@ #if TRUSTED_BOARD_BOOT # define PLAT_ARM_MAX_BL2_SIZE (UL(0x1D000) - FVP_BL2_ROMLIB_OPTIMIZATION) #else -# define PLAT_ARM_MAX_BL2_SIZE (UL(0x12000) - FVP_BL2_ROMLIB_OPTIMIZATION) +# define PLAT_ARM_MAX_BL2_SIZE (UL(0x13000) - FVP_BL2_ROMLIB_OPTIMIZATION) #endif #if RESET_TO_BL31 -- cgit v1.2.3 From f0e2e66ac6131e86b5f643aab4bc01e292d0d989 Mon Sep 17 00:00:00 2001 From: Javier Almansa Sobrino Date: Fri, 10 Jul 2020 10:34:04 +0100 Subject: Add myself and Andre Przywara as code owners for the Arm FPGA platform port Signed-off-by: Javier Almansa Sobrino Change-Id: I6d3949a971fada5a086b788dbe274f8451fcfc0d --- docs/about/maintainers.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst index bf29186d5..ea9a4f58a 100644 --- a/docs/about/maintainers.rst +++ b/docs/about/maintainers.rst @@ -320,6 +320,14 @@ Amlogic Meson A113D (AXG) platform port :F: docs/plat/meson-axg.rst :F: plat/amlogic/axg/ +Arm FPGA platform port +^^^^^^^^^^^^^^^^^^^^^^ +:M: Andre Przywara +:G: `Andre-ARM`_ +:M: Javier Almansa Sobrino +:G: `javieralso-arm`_ +:F: plat/arm/board/arm_fpga + Arm System Guidance for Infrastructure / Mobile FVP platforms ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :M: Nariman Poushin -- cgit v1.2.3 From 6eb75a1a2febdf089c2a432dc46c94a0da16520d Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 9 Jul 2020 23:05:45 +0900 Subject: io_fip: return -ENFILE when a file is already open The cause of failure is not memory shortage. The comment for ENFILE in include/lib/libc/errno.h /* Too many open files in system */ ... is a better match to the warning message here. Change-Id: I45a1740995d464edd8b3e32b93f1f92ba17e5874 Signed-off-by: Masahiro Yamada --- drivers/io/io_fip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/io/io_fip.c b/drivers/io/io_fip.c index 02f85d603..7aa717da8 100644 --- a/drivers/io/io_fip.c +++ b/drivers/io/io_fip.c @@ -302,7 +302,7 @@ static int fip_file_open(io_dev_info_t *dev_info, const uintptr_t spec, */ if (current_file.entry.offset_address != 0) { WARN("fip_file_open : Only one open file at a time.\n"); - return -ENOMEM; + return -ENFILE; } /* Attempt to access the FIP image */ -- cgit v1.2.3 From cefde213f2568c906c217375934518c6903fdba4 Mon Sep 17 00:00:00 2001 From: Roman Bacik Date: Mon, 6 Jul 2020 15:31:29 -0700 Subject: plat/brcm: Define RNG base address Change-Id: I4f5efcd7638a25c317382b51f05e6b9aa283d068 Signed-off-by: Roman Bacik Signed-off-by: Bharat Gooty --- plat/brcm/board/stingray/include/sr_def.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plat/brcm/board/stingray/include/sr_def.h b/plat/brcm/board/stingray/include/sr_def.h index ac3ee782e..be0dee127 100644 --- a/plat/brcm/board/stingray/include/sr_def.h +++ b/plat/brcm/board/stingray/include/sr_def.h @@ -291,6 +291,11 @@ #define ICFG_PKA_MEM_PWR_CTRL__ARRPOWEROKOUT BIT(7) #define ICFG_PKA_MEM_PWR_CTRL__ISO BIT(8) +/******************************************************************************* + * RNG constants + ******************************************************************************/ +#define RNG_BASE_ADDR 0x68b20000 + /******************************************************************************* * Trusted Watchdog constants ******************************************************************************/ -- cgit v1.2.3 From c10563ba421b0a7ea085b3137b0dd1c7f1de89e6 Mon Sep 17 00:00:00 2001 From: Bharat Gooty Date: Mon, 13 Jul 2020 17:58:29 +0530 Subject: driver: brcm: add RNG driver Signed-off-by: Bharat Gooty Change-Id: I490d7e4d49bd9f5a62d343a264a1e14c2066ceca --- drivers/brcm/rng.c | 97 ++++++++++++++++++++++++++++++++++ plat/brcm/board/common/board_common.mk | 6 +++ 2 files changed, 103 insertions(+) create mode 100644 drivers/brcm/rng.c diff --git a/drivers/brcm/rng.c b/drivers/brcm/rng.c new file mode 100644 index 000000000..ee2e6561e --- /dev/null +++ b/drivers/brcm/rng.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2017 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +#define RNG_CTRL_REG (RNG_BASE_ADDR + 0x00) +#define RNG_CTRL_MASK 0x00001FFF +#define RNG_CTRL_ENABLE 0x00000001 +#define RNG_CTRL_DISABLE 0x00000000 + +#define RNG_SOFT_RESET_REG (RNG_BASE_ADDR + 0x04) +#define RNG_SOFT_RESET_MASK 0x00000001 + +#define RNG_FIFO_DATA_REG (RNG_BASE_ADDR + 0x20) + +#define RNG_FIFO_COUNT_REG (RNG_BASE_ADDR + 0x24) +#define RNG_FIFO_COUNT_MASK 0x000000FF + +#define RNG_FIFO_WORDS_MAX 16 +#define MAX_WAIT_COUNT_50US 20000 + + +static void rng_reset(void) +{ + /* Disable RBG */ + mmio_clrbits_32(RNG_CTRL_REG, RNG_CTRL_MASK); + + /* Reset RNG and RBG */ + mmio_setbits_32(RNG_SOFT_RESET_REG, RNG_SOFT_RESET_MASK); + + /* Take all out of reset */ + mmio_clrbits_32(RNG_SOFT_RESET_REG, RNG_SOFT_RESET_MASK); +} + +static void rng_enable(void) +{ + /* Setup RNG. */ + mmio_clrsetbits_32(RNG_CTRL_REG, RNG_CTRL_MASK, RNG_CTRL_ENABLE); +} + +int rng_init(void) +{ + rng_reset(); + + rng_enable(); + + return 0; +} + +int rng_read(uint32_t *p_out, uint32_t *words_read) +{ + uint32_t available_words; + uint32_t i; + uint32_t word_processed = 0; + uint32_t wait_count = MAX_WAIT_COUNT_50US; + + if (*words_read == 0) { + ERROR("RNG Parameter: No word requested\n"); + return -1; + } + + do { + available_words = mmio_read_32(RNG_FIFO_COUNT_REG); + available_words &= RNG_FIFO_COUNT_MASK; + + if (available_words != 0) { + available_words = MIN(available_words, + *words_read - word_processed); + + for (i = 0; i < available_words; i++) + p_out[word_processed + i] = + mmio_read_32(RNG_FIFO_DATA_REG); + word_processed += available_words; + } else { + udelay(50); + } + + if (word_processed == *words_read) + break; + + } while (--wait_count); + + if (word_processed != *words_read) { + ERROR("RNG Timeout: requested %d word(s) got %d\n", + *words_read, word_processed); + *words_read = word_processed; + return -1; + } + + return 0; +} diff --git a/plat/brcm/board/common/board_common.mk b/plat/brcm/board/common/board_common.mk index 808a10741..3069f914b 100644 --- a/plat/brcm/board/common/board_common.mk +++ b/plat/brcm/board/common/board_common.mk @@ -133,6 +133,12 @@ PLAT_BL_COMMON_SOURCES += plat/brcm/common/brcm_common.c \ plat/brcm/board/common/sbl_util.c \ drivers/arm/sp805/sp805.c +# Add RNG driver +DRIVER_RNG_ENABLE := 1 +ifeq (${DRIVER_RNG_ENABLE},1) +PLAT_BL_COMMON_SOURCES += drivers/brcm/rng.c +endif + # Add eMMC driver ifeq (${DRIVER_EMMC_ENABLE},1) $(eval $(call add_define,DRIVER_EMMC_ENABLE)) -- cgit v1.2.3 From fdd5f9e6d6172f012b216d6af609fd528dd25836 Mon Sep 17 00:00:00 2001 From: Manish Pandey Date: Thu, 9 Jul 2020 00:39:16 +0100 Subject: SPMD: fix boundary check if manifest is page aligned while mapping SPMC manifest page in the SPMD translation regime the mapped size was resolved to zero if SPMC manifest base address is PAGE aligned, causing SPMD to abort. To fix the problem change mapped size to PAGE_SIZE if manifest base is PAGE aligned. Signed-off-by: Manish Pandey Change-Id: I06cd39dbefaf492682d9bbb0c82b950dd31fb416 --- plat/common/plat_spmd_manifest.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/plat/common/plat_spmd_manifest.c b/plat/common/plat_spmd_manifest.c index 455b9808b..e65980bc8 100644 --- a/plat/common/plat_spmd_manifest.c +++ b/plat/common/plat_spmd_manifest.c @@ -128,7 +128,13 @@ int plat_spm_core_manifest_load(spmc_manifest_attribute_t *manifest, */ pm_base = (uintptr_t)pm_addr; pm_base_align = page_align(pm_base, UP); - mapped_size = pm_base_align - pm_base; + + if (pm_base == pm_base_align) { + /* Page aligned */ + mapped_size = PAGE_SIZE; + } else { + mapped_size = pm_base_align - pm_base; + } /* Check space within the page at least maps the FDT header */ if (mapped_size < sizeof(struct fdt_header)) { -- cgit v1.2.3 From 0aa9f3c0f2f2ff675c3c12ae5ac6ceb475d6a16f Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Tue, 14 Jul 2020 12:26:19 +0100 Subject: TF-A: Redefine true/false definitions This patch redefines 'true' and 'false' definitions in 'include/lib/libc/stdbool.h' to fix defect reported by MISRA C-2012 Rule 10.1 "The expression \"0\" of non-boolean essential type is being interpreted as a boolean value for the operator \"? :\"." Change-Id: Ie1b16e5826e5427cc272bd753e15d4d283e1ee4c Signed-off-by: Alexei Fedorov --- include/lib/libc/stdbool.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/lib/libc/stdbool.h b/include/lib/libc/stdbool.h index e39aef7d3..b58334cd0 100644 --- a/include/lib/libc/stdbool.h +++ b/include/lib/libc/stdbool.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,8 +9,8 @@ #define bool _Bool -#define true 1 -#define false 0 +#define true (0 < 1) +#define false (0 > 1) #define __bool_true_false_are_defined 1 -- cgit v1.2.3 From 08826b6cf8a052fc68685a47f352dc95e95c6304 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Sun, 8 Dec 2019 08:12:52 +0100 Subject: dts: bindings: stm32mp1: define SCMI clock and reset domain IDs Define the platform SCMI clocks and reset domains for stm32mp1 family. SCMI agent 0 accesses clock/reset controllers under RCC TZEN hardening. SCMI agent 1 accesses clock controllers under RCC MCKPROT hardening. Change-Id: I52e906f846d445a3e6850e5f2e1584da14692553 Signed-off-by: Etienne Carriere --- include/dt-bindings/clock/stm32mp1-clks.h | 27 +++++++++++++++++++++++++++ include/dt-bindings/reset/stm32mp1-resets.h | 13 +++++++++++++ 2 files changed, 40 insertions(+) diff --git a/include/dt-bindings/clock/stm32mp1-clks.h b/include/dt-bindings/clock/stm32mp1-clks.h index 18bdb57f3..67e66b23f 100644 --- a/include/dt-bindings/clock/stm32mp1-clks.h +++ b/include/dt-bindings/clock/stm32mp1-clks.h @@ -248,4 +248,31 @@ #define STM32MP1_LAST_CLK 232 +/* SCMI clock identifiers */ +#define CK_SCMI0_HSE 0 +#define CK_SCMI0_HSI 1 +#define CK_SCMI0_CSI 2 +#define CK_SCMI0_LSE 3 +#define CK_SCMI0_LSI 4 +#define CK_SCMI0_PLL2_Q 5 +#define CK_SCMI0_PLL2_R 6 +#define CK_SCMI0_MPU 7 +#define CK_SCMI0_AXI 8 +#define CK_SCMI0_BSEC 9 +#define CK_SCMI0_CRYP1 10 +#define CK_SCMI0_GPIOZ 11 +#define CK_SCMI0_HASH1 12 +#define CK_SCMI0_I2C4 13 +#define CK_SCMI0_I2C6 14 +#define CK_SCMI0_IWDG1 15 +#define CK_SCMI0_RNG1 16 +#define CK_SCMI0_RTC 17 +#define CK_SCMI0_RTCAPB 18 +#define CK_SCMI0_SPI6 19 +#define CK_SCMI0_USART1 20 + +#define CK_SCMI1_PLL3_Q 0 +#define CK_SCMI1_PLL3_R 1 +#define CK_SCMI1_MCU 2 + #endif /* _DT_BINDINGS_STM32MP1_CLKS_H_ */ diff --git a/include/dt-bindings/reset/stm32mp1-resets.h b/include/dt-bindings/reset/stm32mp1-resets.h index f0c3aaef6..bc71924fa 100644 --- a/include/dt-bindings/reset/stm32mp1-resets.h +++ b/include/dt-bindings/reset/stm32mp1-resets.h @@ -105,4 +105,17 @@ #define GPIOJ_R 19785 #define GPIOK_R 19786 +/* SCMI reset domain identifiers */ +#define RST_SCMI0_SPI6 0 +#define RST_SCMI0_I2C4 1 +#define RST_SCMI0_I2C6 2 +#define RST_SCMI0_USART1 3 +#define RST_SCMI0_STGEN 4 +#define RST_SCMI0_GPIOZ 5 +#define RST_SCMI0_CRYP1 6 +#define RST_SCMI0_HASH1 7 +#define RST_SCMI0_RNG1 8 +#define RST_SCMI0_MDMA 9 +#define RST_SCMI0_MCU 10 + #endif /* _DT_BINDINGS_STM32MP1_RESET_H_ */ -- cgit v1.2.3 From fdaaaeb4312532c60bf98b891ecf01e79ecd71f2 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Thu, 16 Jul 2020 17:36:18 +0200 Subject: stm32mp1: SCMI clock and reset service in SP_MIN This change implements platform services for stm32mp1 to expose clock and reset controllers over SCMI clock and reset domain protocols in sp_min firmware. Requests execution use a fastcall SMC context using a SiP function ID. The setup allows the create SCMI channels by assigning a specific SiP SMC function ID for each channel/agent identifier defined. In this change, stm32mp1 exposes a single channel and hence expects single agent at a time. The input payload in copied in secure memory before the message in passed through the SCMI server drivers. BL32/sp_min is invoked for a single SCMI message processing and always returns with a synchronous response message passed back to the caller agent. This change fixes and updates STM32_COMMON_SIP_NUM_CALLS that was previously wrongly set 4 whereas only 1 SiP SMC function ID was to be counted. STM32_COMMON_SIP_NUM_CALLS is now set to 3 since the 2 added SiP SMC function IDs for SCMI services. Change-Id: Icb428775856b9aec00538172aea4cf11e609b033 Signed-off-by: Etienne Carriere --- plat/st/stm32mp1/include/platform_def.h | 7 + plat/st/stm32mp1/include/stm32mp1_private.h | 2 + plat/st/stm32mp1/include/stm32mp1_smc.h | 12 +- plat/st/stm32mp1/services/stm32mp1_svc_setup.c | 8 + plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk | 10 +- plat/st/stm32mp1/sp_min/sp_min_setup.c | 2 + plat/st/stm32mp1/stm32mp1_def.h | 3 + plat/st/stm32mp1/stm32mp1_scmi.c | 478 +++++++++++++++++++++++++ 8 files changed, 520 insertions(+), 2 deletions(-) create mode 100644 plat/st/stm32mp1/stm32mp1_scmi.c diff --git a/plat/st/stm32mp1/include/platform_def.h b/plat/st/stm32mp1/include/platform_def.h index 27ba6f7f9..7076a7105 100644 --- a/plat/st/stm32mp1/include/platform_def.h +++ b/plat/st/stm32mp1/include/platform_def.h @@ -196,4 +196,11 @@ ******************************************************************************/ #define PLAT_PCPU_DATA_SIZE 2 +/******************************************************************************* + * Number of parallel entry slots in SMT SCMI server entry context. For this + * platform, SCMI server is reached through SMC only, hence the number of + * entry slots. + ******************************************************************************/ +#define PLAT_SMT_ENTRY_COUNT PLATFORM_CORE_COUNT + #endif /* PLATFORM_DEF_H */ diff --git a/plat/st/stm32mp1/include/stm32mp1_private.h b/plat/st/stm32mp1/include/stm32mp1_private.h index 2da64acbc..b6cb91efa 100644 --- a/plat/st/stm32mp1/include/stm32mp1_private.h +++ b/plat/st/stm32mp1/include/stm32mp1_private.h @@ -22,4 +22,6 @@ void stm32mp1_syscfg_enable_io_compensation(void); void stm32mp1_syscfg_disable_io_compensation(void); uint32_t stm32mp_get_ddr_ns_size(void); + +void stm32mp1_init_scmi_server(void); #endif /* STM32MP1_PRIVATE_H */ diff --git a/plat/st/stm32mp1/include/stm32mp1_smc.h b/plat/st/stm32mp1/include/stm32mp1_smc.h index b87275839..57240bcaf 100644 --- a/plat/st/stm32mp1/include/stm32mp1_smc.h +++ b/plat/st/stm32mp1/include/stm32mp1_smc.h @@ -29,6 +29,16 @@ */ #define STM32_SMC_BSEC 0x82001003 +/* + * STM32_SIP_SMC_SCMI_AGENT0 + * STM32_SIP_SMC_SCMI_AGENT1 + * Process SCMI message pending in SCMI shared memory buffer. + * + * Argument a0: (input) SMCC ID + */ +#define STM32_SIP_SMC_SCMI_AGENT0 0x82002000 +#define STM32_SIP_SMC_SCMI_AGENT1 0x82002001 + /* SMC function IDs for SiP Service queries */ #define STM32_SIP_SVC_CALL_COUNT 0x8200ff00 #define STM32_SIP_SVC_UID 0x8200ff01 @@ -40,7 +50,7 @@ #define STM32_SIP_SVC_VERSION_MINOR 0x1 /* Number of STM32 SiP Calls implemented */ -#define STM32_COMMON_SIP_NUM_CALLS 4 +#define STM32_COMMON_SIP_NUM_CALLS 3 /* Service for BSEC */ #define STM32_SMC_READ_SHADOW 0x01 diff --git a/plat/st/stm32mp1/services/stm32mp1_svc_setup.c b/plat/st/stm32mp1/services/stm32mp1_svc_setup.c index 72af9ff33..49375a62d 100644 --- a/plat/st/stm32mp1/services/stm32mp1_svc_setup.c +++ b/plat/st/stm32mp1/services/stm32mp1_svc_setup.c @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -65,6 +66,13 @@ static uintptr_t stm32mp1_svc_smc_handler(uint32_t smc_fid, u_register_t x1, ret2_enabled = true; break; + case STM32_SIP_SMC_SCMI_AGENT0: + scmi_smt_fastcall_smc_entry(0); + break; + case STM32_SIP_SMC_SCMI_AGENT1: + scmi_smt_fastcall_smc_entry(1); + break; + default: WARN("Unimplemented STM32MP1 Service Call: 0x%x\n", smc_fid); ret1 = SMC_UNK; diff --git a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk index 7327eefde..5d7d495f0 100644 --- a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk +++ b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk @@ -25,9 +25,17 @@ BL32_SOURCES += drivers/arm/gic/common/gic_common.c \ # Generic PSCI BL32_SOURCES += plat/common/plat_psci_common.c +# SCMI server drivers +BL32_SOURCES += drivers/st/scmi-msg/base.c \ + drivers/st/scmi-msg/clock.c \ + drivers/st/scmi-msg/entry.c \ + drivers/st/scmi-msg/reset_domain.c \ + drivers/st/scmi-msg/smt.c + # stm32mp1 specific services BL32_SOURCES += plat/st/stm32mp1/services/bsec_svc.c \ - plat/st/stm32mp1/services/stm32mp1_svc_setup.c + plat/st/stm32mp1/services/stm32mp1_svc_setup.c \ + plat/st/stm32mp1/stm32mp1_scmi.c # Arm Archtecture services BL32_SOURCES += services/arm_arch_svc/arm_arch_svc_setup.c diff --git a/plat/st/stm32mp1/sp_min/sp_min_setup.c b/plat/st/stm32mp1/sp_min/sp_min_setup.c index 9b4c2d2e1..b639fcb35 100644 --- a/plat/st/stm32mp1/sp_min/sp_min_setup.c +++ b/plat/st/stm32mp1/sp_min/sp_min_setup.c @@ -197,6 +197,8 @@ void sp_min_platform_setup(void) } stm32mp_lock_periph_registering(); + + stm32mp1_init_scmi_server(); } void sp_min_plat_arch_setup(void) diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h index bce599447..ea18a3031 100644 --- a/plat/st/stm32mp1/stm32mp1_def.h +++ b/plat/st/stm32mp1/stm32mp1_def.h @@ -62,6 +62,9 @@ STM32MP_SYSRAM_SIZE - \ STM32MP_NS_SYSRAM_SIZE) +#define STM32MP_SCMI_NS_SHM_BASE STM32MP_NS_SYSRAM_BASE +#define STM32MP_SCMI_NS_SHM_SIZE STM32MP_NS_SYSRAM_SIZE + #define STM32MP_SEC_SYSRAM_BASE STM32MP_SYSRAM_BASE #define STM32MP_SEC_SYSRAM_SIZE (STM32MP_SYSRAM_SIZE - \ STM32MP_NS_SYSRAM_SIZE) diff --git a/plat/st/stm32mp1/stm32mp1_scmi.c b/plat/st/stm32mp1/stm32mp1_scmi.c new file mode 100644 index 000000000..80faf0c6e --- /dev/null +++ b/plat/st/stm32mp1/stm32mp1_scmi.c @@ -0,0 +1,478 @@ +/* + * Copyright (c) 2019-2020, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#define TIMEOUT_US_1MS 1000U + +#define SCMI_CLOCK_NAME_SIZE 16U +#define SCMI_RSTD_NAME_SIZE 16U + +/* + * struct stm32_scmi_clk - Data for the exposed clock + * @clock_id: Clock identifier in RCC clock driver + * @name: Clock string ID exposed to agent + * @enabled: State of the SCMI clock + */ +struct stm32_scmi_clk { + unsigned long clock_id; + const char *name; + bool enabled; +}; + +/* + * struct stm32_scmi_rstd - Data for the exposed reset controller + * @reset_id: Reset identifier in RCC reset driver + * @name: Reset string ID exposed to agent + */ +struct stm32_scmi_rstd { + unsigned long reset_id; + const char *name; +}; + +/* Locate all non-secure SMT message buffers in last page of SYSRAM */ +#define SMT_BUFFER_BASE STM32MP_SCMI_NS_SHM_BASE +#define SMT_BUFFER0_BASE SMT_BUFFER_BASE +#define SMT_BUFFER1_BASE (SMT_BUFFER_BASE + 0x200) + +CASSERT((STM32MP_SCMI_NS_SHM_BASE + STM32MP_SCMI_NS_SHM_SIZE) >= + (SMT_BUFFER1_BASE + SMT_BUF_SLOT_SIZE), + assert_scmi_non_secure_shm_fits_scmi_overall_buffer_size); + +static struct scmi_msg_channel scmi_channel[] = { + [0] = { + .shm_addr = SMT_BUFFER0_BASE, + .shm_size = SMT_BUF_SLOT_SIZE, + }, + [1] = { + .shm_addr = SMT_BUFFER1_BASE, + .shm_size = SMT_BUF_SLOT_SIZE, + }, +}; + +struct scmi_msg_channel *plat_scmi_get_channel(unsigned int agent_id) +{ + assert(agent_id < ARRAY_SIZE(scmi_channel)); + + return &scmi_channel[agent_id]; +} + +#define CLOCK_CELL(_scmi_id, _id, _name, _init_enabled) \ + [_scmi_id] = { \ + .clock_id = _id, \ + .name = _name, \ + .enabled = _init_enabled, \ + } + +static struct stm32_scmi_clk stm32_scmi0_clock[] = { + CLOCK_CELL(CK_SCMI0_HSE, CK_HSE, "ck_hse", true), + CLOCK_CELL(CK_SCMI0_HSI, CK_HSI, "ck_hsi", true), + CLOCK_CELL(CK_SCMI0_CSI, CK_CSI, "ck_csi", true), + CLOCK_CELL(CK_SCMI0_LSE, CK_LSE, "ck_lse", true), + CLOCK_CELL(CK_SCMI0_LSI, CK_LSI, "ck_lsi", true), + CLOCK_CELL(CK_SCMI0_PLL2_Q, PLL2_Q, "pll2_q", true), + CLOCK_CELL(CK_SCMI0_PLL2_R, PLL2_R, "pll2_r", true), + CLOCK_CELL(CK_SCMI0_MPU, CK_MPU, "ck_mpu", true), + CLOCK_CELL(CK_SCMI0_AXI, CK_AXI, "ck_axi", true), + CLOCK_CELL(CK_SCMI0_BSEC, BSEC, "bsec", true), + CLOCK_CELL(CK_SCMI0_CRYP1, CRYP1, "cryp1", false), + CLOCK_CELL(CK_SCMI0_GPIOZ, GPIOZ, "gpioz", false), + CLOCK_CELL(CK_SCMI0_HASH1, HASH1, "hash1", false), + CLOCK_CELL(CK_SCMI0_I2C4, I2C4_K, "i2c4_k", false), + CLOCK_CELL(CK_SCMI0_I2C6, I2C6_K, "i2c6_k", false), + CLOCK_CELL(CK_SCMI0_IWDG1, IWDG1, "iwdg1", false), + CLOCK_CELL(CK_SCMI0_RNG1, RNG1_K, "rng1_k", true), + CLOCK_CELL(CK_SCMI0_RTC, RTC, "ck_rtc", true), + CLOCK_CELL(CK_SCMI0_RTCAPB, RTCAPB, "rtcapb", true), + CLOCK_CELL(CK_SCMI0_SPI6, SPI6_K, "spi6_k", false), + CLOCK_CELL(CK_SCMI0_USART1, USART1_K, "usart1_k", false), +}; + +static struct stm32_scmi_clk stm32_scmi1_clock[] = { + CLOCK_CELL(CK_SCMI1_PLL3_Q, PLL3_Q, "pll3_q", true), + CLOCK_CELL(CK_SCMI1_PLL3_R, PLL3_R, "pll3_r", true), + CLOCK_CELL(CK_SCMI1_MCU, CK_MCU, "ck_mcu", false), +}; + +#define RESET_CELL(_scmi_id, _id, _name) \ + [_scmi_id] = { \ + .reset_id = _id, \ + .name = _name, \ + } + +static struct stm32_scmi_rstd stm32_scmi0_reset_domain[] = { + RESET_CELL(RST_SCMI0_SPI6, SPI6_R, "spi6"), + RESET_CELL(RST_SCMI0_I2C4, I2C4_R, "i2c4"), + RESET_CELL(RST_SCMI0_I2C6, I2C6_R, "i2c6"), + RESET_CELL(RST_SCMI0_USART1, USART1_R, "usart1"), + RESET_CELL(RST_SCMI0_STGEN, STGEN_R, "stgen"), + RESET_CELL(RST_SCMI0_GPIOZ, GPIOZ_R, "gpioz"), + RESET_CELL(RST_SCMI0_CRYP1, CRYP1_R, "cryp1"), + RESET_CELL(RST_SCMI0_HASH1, HASH1_R, "hash1"), + RESET_CELL(RST_SCMI0_RNG1, RNG1_R, "rng1"), + RESET_CELL(RST_SCMI0_MDMA, MDMA_R, "mdma"), + RESET_CELL(RST_SCMI0_MCU, MCU_R, "mcu"), +}; + +struct scmi_agent_resources { + struct stm32_scmi_clk *clock; + size_t clock_count; + struct stm32_scmi_rstd *rstd; + size_t rstd_count; +}; + +static const struct scmi_agent_resources agent_resources[] = { + [0] = { + .clock = stm32_scmi0_clock, + .clock_count = ARRAY_SIZE(stm32_scmi0_clock), + .rstd = stm32_scmi0_reset_domain, + .rstd_count = ARRAY_SIZE(stm32_scmi0_reset_domain), + }, + [1] = { + .clock = stm32_scmi1_clock, + .clock_count = ARRAY_SIZE(stm32_scmi1_clock), + }, +}; + +static const struct scmi_agent_resources *find_resource(unsigned int agent_id) +{ + assert(agent_id < ARRAY_SIZE(agent_resources)); + + return &agent_resources[agent_id]; +} + +#if ENABLE_ASSERTIONS +static size_t plat_scmi_protocol_count_paranoid(void) +{ + unsigned int n = 0U; + unsigned int count = 0U; + + for (n = 0U; n < ARRAY_SIZE(agent_resources); n++) { + if (agent_resources[n].clock_count) { + count++; + break; + } + } + + for (n = 0U; n < ARRAY_SIZE(agent_resources); n++) { + if (agent_resources[n].rstd_count) { + count++; + break; + } + } + + return count; +} +#endif + +static const char vendor[] = "ST"; +static const char sub_vendor[] = ""; + +const char *plat_scmi_vendor_name(void) +{ + return vendor; +} + +const char *plat_scmi_sub_vendor_name(void) +{ + return sub_vendor; +} + +/* Currently supporting Clocks and Reset Domains */ +static const uint8_t plat_protocol_list[] = { + SCMI_PROTOCOL_ID_CLOCK, + SCMI_PROTOCOL_ID_RESET_DOMAIN, + 0U /* Null termination */ +}; + +size_t plat_scmi_protocol_count(void) +{ + const size_t count = ARRAY_SIZE(plat_protocol_list) - 1U; + + assert(count == plat_scmi_protocol_count_paranoid()); + + return count; +} + +const uint8_t *plat_scmi_protocol_list(unsigned int agent_id __unused) +{ + assert(plat_scmi_protocol_count_paranoid() == + (ARRAY_SIZE(plat_protocol_list) - 1U)); + + return plat_protocol_list; +} + +/* + * Platform SCMI clocks + */ +static struct stm32_scmi_clk *find_clock(unsigned int agent_id, + unsigned int scmi_id) +{ + const struct scmi_agent_resources *resource = find_resource(agent_id); + size_t n = 0U; + + if (resource != NULL) { + for (n = 0U; n < resource->clock_count; n++) { + if (n == scmi_id) { + return &resource->clock[n]; + } + } + } + + return NULL; +} + +size_t plat_scmi_clock_count(unsigned int agent_id) +{ + const struct scmi_agent_resources *resource = find_resource(agent_id); + + if (resource == NULL) { + return 0U; + } + + return resource->clock_count; +} + +const char *plat_scmi_clock_get_name(unsigned int agent_id, + unsigned int scmi_id) +{ + struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id); + + if ((clock == NULL) || + !stm32mp_nsec_can_access_clock(clock->clock_id)) { + return NULL; + } + + return clock->name; +} + +int32_t plat_scmi_clock_rates_array(unsigned int agent_id, unsigned int scmi_id, + unsigned long *array, size_t *nb_elts) +{ + struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id); + + if (clock == NULL) { + return SCMI_NOT_FOUND; + } + + if (!stm32mp_nsec_can_access_clock(clock->clock_id)) { + return SCMI_DENIED; + } + + if (array == NULL) { + *nb_elts = 1U; + } else if (*nb_elts == 1U) { + *array = stm32mp_clk_get_rate(clock->clock_id); + } else { + return SCMI_GENERIC_ERROR; + } + + return SCMI_SUCCESS; +} + +unsigned long plat_scmi_clock_get_rate(unsigned int agent_id, + unsigned int scmi_id) +{ + struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id); + + if ((clock == NULL) || + !stm32mp_nsec_can_access_clock(clock->clock_id)) { + return 0U; + } + + return stm32mp_clk_get_rate(clock->clock_id); +} + +int32_t plat_scmi_clock_get_state(unsigned int agent_id, unsigned int scmi_id) +{ + struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id); + + if ((clock == NULL) || + !stm32mp_nsec_can_access_clock(clock->clock_id)) { + return 0U; + } + + return (int32_t)clock->enabled; +} + +int32_t plat_scmi_clock_set_state(unsigned int agent_id, unsigned int scmi_id, + bool enable_not_disable) +{ + struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id); + + if (clock == NULL) { + return SCMI_NOT_FOUND; + } + + if (!stm32mp_nsec_can_access_clock(clock->clock_id)) { + return SCMI_DENIED; + } + + if (enable_not_disable) { + if (!clock->enabled) { + VERBOSE("SCMI clock %u enable\n", scmi_id); + stm32mp_clk_enable(clock->clock_id); + clock->enabled = true; + } + } else { + if (clock->enabled) { + VERBOSE("SCMI clock %u disable\n", scmi_id); + stm32mp_clk_disable(clock->clock_id); + clock->enabled = false; + } + } + + return SCMI_SUCCESS; +} + +/* + * Platform SCMI reset domains + */ +static struct stm32_scmi_rstd *find_rstd(unsigned int agent_id, + unsigned int scmi_id) +{ + const struct scmi_agent_resources *resource = find_resource(agent_id); + size_t n; + + if (resource != NULL) { + for (n = 0U; n < resource->rstd_count; n++) { + if (n == scmi_id) { + return &resource->rstd[n]; + } + } + } + + return NULL; +} + +const char *plat_scmi_rstd_get_name(unsigned int agent_id, unsigned int scmi_id) +{ + const struct stm32_scmi_rstd *rstd = find_rstd(agent_id, scmi_id); + + if (rstd == NULL) { + return NULL; + } + + return rstd->name; +} + +size_t plat_scmi_rstd_count(unsigned int agent_id) +{ + const struct scmi_agent_resources *resource = find_resource(agent_id); + + if (resource == NULL) { + return 0U; + } + + return resource->rstd_count; +} + +int32_t plat_scmi_rstd_autonomous(unsigned int agent_id, unsigned int scmi_id, + uint32_t state) +{ + const struct stm32_scmi_rstd *rstd = find_rstd(agent_id, scmi_id); + + if (rstd == NULL) { + return SCMI_NOT_FOUND; + } + + if (!stm32mp_nsec_can_access_reset(rstd->reset_id)) { + return SCMI_DENIED; + } + + /* Supports only reset with context loss */ + if (state != 0U) { + return SCMI_NOT_SUPPORTED; + } + + VERBOSE("SCMI reset %lu cycle\n", rstd->reset_id); + + if (stm32mp_reset_assert(rstd->reset_id, TIMEOUT_US_1MS)) { + return SCMI_HARDWARE_ERROR; + } + + if (stm32mp_reset_deassert(rstd->reset_id, TIMEOUT_US_1MS)) { + return SCMI_HARDWARE_ERROR; + } + + return SCMI_SUCCESS; +} + +int32_t plat_scmi_rstd_set_state(unsigned int agent_id, unsigned int scmi_id, + bool assert_not_deassert) +{ + const struct stm32_scmi_rstd *rstd = find_rstd(agent_id, scmi_id); + + if (rstd == NULL) { + return SCMI_NOT_FOUND; + } + + if (!stm32mp_nsec_can_access_reset(rstd->reset_id)) { + return SCMI_DENIED; + } + + if (assert_not_deassert) { + VERBOSE("SCMI reset %lu set\n", rstd->reset_id); + stm32mp_reset_set(rstd->reset_id); + } else { + VERBOSE("SCMI reset %lu release\n", rstd->reset_id); + stm32mp_reset_release(rstd->reset_id); + } + + return SCMI_SUCCESS; +} + +/* + * Initialize platform SCMI resources + */ +void stm32mp1_init_scmi_server(void) +{ + size_t i; + + for (i = 0U; i < ARRAY_SIZE(scmi_channel); i++) { + scmi_smt_init_agent_channel(&scmi_channel[i]); + } + + for (i = 0U; i < ARRAY_SIZE(agent_resources); i++) { + const struct scmi_agent_resources *res = &agent_resources[i]; + size_t j; + + for (j = 0U; j < res->clock_count; j++) { + struct stm32_scmi_clk *clk = &res->clock[j]; + + if ((clk->name == NULL) || + (strlen(clk->name) >= SCMI_CLOCK_NAME_SIZE)) { + ERROR("Invalid SCMI clock name\n"); + panic(); + } + + /* Sync SCMI clocks with their targeted initial state */ + if (clk->enabled && + stm32mp_nsec_can_access_clock(clk->clock_id)) { + stm32mp_clk_enable(clk->clock_id); + } + } + + for (j = 0U; j < res->rstd_count; j++) { + struct stm32_scmi_rstd *rstd = &res->rstd[j]; + + if ((rstd->name == NULL) || + (strlen(rstd->name) >= SCMI_RSTD_NAME_SIZE)) { + ERROR("Invalid SCMI reset domain name\n"); + panic(); + } + } + } +} -- cgit v1.2.3 From d471bd9cfc58bce8efa8fa2d355a20950022f44d Mon Sep 17 00:00:00 2001 From: johpow01 Date: Wed, 1 Jul 2020 17:09:57 -0500 Subject: IO Driver Misra Cleanup This patch cleans up MISRA C violations in the IO driver files. Some things did not make sense to fix or would require sweeping changes but the simple issues have been resolved. Defects Fixed File Line Rule drivers/io/io_fip.c 39 MISRA C-2012 Rule 5.6 (required) drivers/io/io_fip.c 52 MISRA C-2012 Rule 8.9 (advisory) drivers/io/io_fip.c 60 MISRA C-2012 Rule 5.9 (advisory) drivers/io/io_fip.c 285 MISRA C-2012 Rule 8.9 (advisory) drivers/io/io_fip.c 336 MISRA C-2012 Rule 15.4 (advisory) drivers/io/io_fip.c 340 MISRA C-2012 Rule 15.4 (advisory) drivers/io/io_fip.c 342 MISRA C-2012 Rule 15.4 (advisory) drivers/io/io_memmap.c 30 MISRA C-2012 Rule 5.6 (required) drivers/io/io_memmap.c 32 MISRA C-2012 Rule 5.9 (advisory) drivers/io/io_memmap.c 85 MISRA C-2012 Rule 11.8 (required) drivers/io/io_semihosting.c 66 MISRA C-2012 Rule 11.8 (required) drivers/io/io_storage.c 73 MISRA C-2012 Rule 5.9 (advisory) drivers/io/io_storage.c 116 MISRA C-2012 Rule 13.4 (advisory) Signed-off-by: John Powell Change-Id: Id9b1b2b684588d4eaab674ed4ed04f3950dd21f4 --- drivers/io/io_fip.c | 39 ++++++++++++++++++++------------------- drivers/io/io_memmap.c | 39 +++++++++++++++++++-------------------- drivers/io/io_semihosting.c | 7 +++---- drivers/io/io_storage.c | 20 ++++++++++---------- 4 files changed, 52 insertions(+), 53 deletions(-) diff --git a/drivers/io/io_fip.c b/drivers/io/io_fip.c index 02f85d603..c11ef115a 100644 --- a/drivers/io/io_fip.c +++ b/drivers/io/io_fip.c @@ -36,7 +36,7 @@ typedef struct { unsigned int file_pos; fip_toc_entry_t entry; -} file_state_t; +} fip_file_state_t; /* * Maintain dev_spec per FIP Device @@ -49,7 +49,6 @@ typedef struct { uint16_t plat_toc_flag; } fip_dev_state_t; -static const uuid_t uuid_null; /* * Only one file can be open across all FIP device * as backends like io_memmap don't support @@ -57,7 +56,7 @@ static const uuid_t uuid_null; * backend handle should be maintained per FIP device * if the same support is available in the backend */ -static file_state_t current_file = {0}; +static fip_file_state_t current_fip_file = {0}; static uintptr_t backend_dev_handle; static uintptr_t backend_image_spec; @@ -288,6 +287,7 @@ static int fip_file_open(io_dev_info_t *dev_info, const uintptr_t spec, int result; uintptr_t backend_handle; const io_uuid_spec_t *uuid_spec = (io_uuid_spec_t *)spec; + static const uuid_t uuid_null = { {0} }; /* Double braces for clang */ size_t bytes_read; int found_file = 0; @@ -300,7 +300,7 @@ static int fip_file_open(io_dev_info_t *dev_info, const uintptr_t spec, * When the system supports dynamic memory allocation we can allow more * than one open file at a time if needed. */ - if (current_file.entry.offset_address != 0) { + if (current_fip_file.entry.offset_address != 0U) { WARN("fip_file_open : Only one open file at a time.\n"); return -ENOMEM; } @@ -326,31 +326,32 @@ static int fip_file_open(io_dev_info_t *dev_info, const uintptr_t spec, found_file = 0; do { result = io_read(backend_handle, - (uintptr_t)¤t_file.entry, - sizeof(current_file.entry), + (uintptr_t)¤t_fip_file.entry, + sizeof(current_fip_file.entry), &bytes_read); if (result == 0) { - if (compare_uuids(¤t_file.entry.uuid, + if (compare_uuids(¤t_fip_file.entry.uuid, &uuid_spec->uuid) == 0) { found_file = 1; - break; } } else { WARN("Failed to read FIP (%i)\n", result); goto fip_file_open_close; } - } while (compare_uuids(¤t_file.entry.uuid, &uuid_null) != 0); + } while ((found_file == 0) && + (compare_uuids(¤t_fip_file.entry.uuid, + &uuid_null) != 0)); if (found_file == 1) { /* All fine. Update entity info with file state and return. Set - * the file position to 0. The 'current_file.entry' holds the - * base and size of the file. + * the file position to 0. The 'current_fip_file.entry' holds + * the base and size of the file. */ - current_file.file_pos = 0; - entity->info = (uintptr_t)¤t_file; + current_fip_file.file_pos = 0; + entity->info = (uintptr_t)¤t_fip_file; } else { /* Did not find the file in the FIP. */ - current_file.entry.offset_address = 0; + current_fip_file.entry.offset_address = 0; result = -ENOENT; } @@ -368,7 +369,7 @@ static int fip_file_len(io_entity_t *entity, size_t *length) assert(entity != NULL); assert(length != NULL); - *length = ((file_state_t *)entity->info)->entry.size; + *length = ((fip_file_state_t *)entity->info)->entry.size; return 0; } @@ -379,7 +380,7 @@ static int fip_file_read(io_entity_t *entity, uintptr_t buffer, size_t length, size_t *length_read) { int result; - file_state_t *fp; + fip_file_state_t *fp; size_t file_offset; size_t bytes_read; uintptr_t backend_handle; @@ -397,7 +398,7 @@ static int fip_file_read(io_entity_t *entity, uintptr_t buffer, size_t length, goto fip_file_read_exit; } - fp = (file_state_t *)entity->info; + fp = (fip_file_state_t *)entity->info; /* Seek to the position in the FIP where the payload lives */ file_offset = fp->entry.offset_address + fp->file_pos; @@ -436,8 +437,8 @@ static int fip_file_close(io_entity_t *entity) /* Clear our current file pointer. * If we had malloc() we would free() here. */ - if (current_file.entry.offset_address != 0) { - zeromem(¤t_file, sizeof(current_file)); + if (current_fip_file.entry.offset_address != 0U) { + zeromem(¤t_fip_file, sizeof(current_fip_file)); } /* Clear the Entity info. */ diff --git a/drivers/io/io_memmap.c b/drivers/io/io_memmap.c index eed50cc08..eb69163b7 100644 --- a/drivers/io/io_memmap.c +++ b/drivers/io/io_memmap.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -27,9 +27,9 @@ typedef struct { uintptr_t base; unsigned long long file_pos; unsigned long long size; -} file_state_t; +} memmap_file_state_t; -static file_state_t current_file = {0}; +static memmap_file_state_t current_memmap_file = {0}; /* Identify the device type as memmap */ static io_type_t device_type_memmap(void) @@ -71,7 +71,7 @@ static const io_dev_funcs_t memmap_dev_funcs = { /* No state associated with this device so structure can be const */ -static const io_dev_info_t memmap_dev_info = { +static io_dev_info_t memmap_dev_info = { .funcs = &memmap_dev_funcs, .info = (uintptr_t)NULL }; @@ -82,8 +82,7 @@ static int memmap_dev_open(const uintptr_t dev_spec __unused, io_dev_info_t **dev_info) { assert(dev_info != NULL); - *dev_info = (io_dev_info_t *)&memmap_dev_info; /* cast away const */ - + *dev_info = &memmap_dev_info; return 0; } @@ -109,16 +108,16 @@ static int memmap_block_open(io_dev_info_t *dev_info, const uintptr_t spec, * spec at a time. When we have dynamic memory we can malloc and set * entity->info. */ - if (current_file.in_use == 0) { + if (current_memmap_file.in_use == 0) { assert(block_spec != NULL); assert(entity != NULL); - current_file.in_use = 1; - current_file.base = block_spec->offset; + current_memmap_file.in_use = 1; + current_memmap_file.base = block_spec->offset; /* File cursor offset for seek and incremental reads etc. */ - current_file.file_pos = 0; - current_file.size = block_spec->length; - entity->info = (uintptr_t)¤t_file; + current_memmap_file.file_pos = 0; + current_memmap_file.size = block_spec->length; + entity->info = (uintptr_t)¤t_memmap_file; result = 0; } else { WARN("A Memmap device is already active. Close first.\n"); @@ -133,13 +132,13 @@ static int memmap_block_seek(io_entity_t *entity, int mode, signed long long offset) { int result = -ENOENT; - file_state_t *fp; + memmap_file_state_t *fp; /* We only support IO_SEEK_SET for the moment. */ if (mode == IO_SEEK_SET) { assert(entity != NULL); - fp = (file_state_t *) entity->info; + fp = (memmap_file_state_t *) entity->info; /* Assert that new file position is valid */ assert((offset >= 0) && @@ -160,7 +159,7 @@ static int memmap_block_len(io_entity_t *entity, size_t *length) assert(entity != NULL); assert(length != NULL); - *length = (size_t)((file_state_t *)entity->info)->size; + *length = (size_t)((memmap_file_state_t *)entity->info)->size; return 0; } @@ -170,13 +169,13 @@ static int memmap_block_len(io_entity_t *entity, size_t *length) static int memmap_block_read(io_entity_t *entity, uintptr_t buffer, size_t length, size_t *length_read) { - file_state_t *fp; + memmap_file_state_t *fp; unsigned long long pos_after; assert(entity != NULL); assert(length_read != NULL); - fp = (file_state_t *) entity->info; + fp = (memmap_file_state_t *) entity->info; /* Assert that file position is valid for this read operation */ pos_after = fp->file_pos + length; @@ -198,13 +197,13 @@ static int memmap_block_read(io_entity_t *entity, uintptr_t buffer, static int memmap_block_write(io_entity_t *entity, const uintptr_t buffer, size_t length, size_t *length_written) { - file_state_t *fp; + memmap_file_state_t *fp; unsigned long long pos_after; assert(entity != NULL); assert(length_written != NULL); - fp = (file_state_t *) entity->info; + fp = (memmap_file_state_t *) entity->info; /* Assert that file position is valid for this write operation */ pos_after = fp->file_pos + length; @@ -230,7 +229,7 @@ static int memmap_block_close(io_entity_t *entity) entity->info = 0; /* This would be a mem free() if we had malloc.*/ - zeromem((void *)¤t_file, sizeof(current_file)); + zeromem((void *)¤t_memmap_file, sizeof(current_memmap_file)); return 0; } diff --git a/drivers/io/io_semihosting.c b/drivers/io/io_semihosting.c index 4ceddc6cc..1c2f84d54 100644 --- a/drivers/io/io_semihosting.c +++ b/drivers/io/io_semihosting.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -51,8 +51,7 @@ static const io_dev_funcs_t sh_dev_funcs = { }; -/* No state associated with this device so structure can be const */ -static const io_dev_info_t sh_dev_info = { +static io_dev_info_t sh_dev_info = { .funcs = &sh_dev_funcs, .info = (uintptr_t)NULL }; @@ -63,7 +62,7 @@ static int sh_dev_open(const uintptr_t dev_spec __unused, io_dev_info_t **dev_info) { assert(dev_info != NULL); - *dev_info = (io_dev_info_t *)&sh_dev_info; /* cast away const */ + *dev_info = &sh_dev_info; return 0; } diff --git a/drivers/io/io_storage.c b/drivers/io/io_storage.c index ba6f094c4..053426891 100644 --- a/drivers/io/io_storage.c +++ b/drivers/io/io_storage.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -32,14 +32,13 @@ static unsigned int dev_count; #if ENABLE_ASSERTIONS /* Return a boolean value indicating whether a device connector is valid */ -static int is_valid_dev_connector(const io_dev_connector_t *dev_con) +static bool is_valid_dev_connector(const io_dev_connector_t *dev_con) { return (dev_con != NULL) && (dev_con->dev_open != NULL); } - /* Return a boolean value indicating whether a device handle is valid */ -static int is_valid_dev(const uintptr_t dev_handle) +static bool is_valid_dev(const uintptr_t dev_handle) { const io_dev_info_t *dev = (io_dev_info_t *)dev_handle; @@ -50,7 +49,7 @@ static int is_valid_dev(const uintptr_t dev_handle) /* Return a boolean value indicating whether an IO entity is valid */ -static int is_valid_entity(const uintptr_t handle) +static bool is_valid_entity(const uintptr_t handle) { const io_entity_t *entity = (io_entity_t *)handle; @@ -60,7 +59,7 @@ static int is_valid_entity(const uintptr_t handle) /* Return a boolean value indicating whether a seek mode is valid */ -static int is_valid_seek_mode(io_seek_mode_t mode) +static bool is_valid_seek_mode(io_seek_mode_t mode) { return ((mode != IO_SEEK_INVALID) && (mode < IO_SEEK_MAX)); } @@ -70,7 +69,8 @@ static int is_valid_seek_mode(io_seek_mode_t mode) /* Open a connection to a specific device */ -static int dev_open(const io_dev_connector_t *dev_con, const uintptr_t dev_spec, +static int io_storage_dev_open(const io_dev_connector_t *dev_con, + const uintptr_t dev_spec, io_dev_info_t **dev_info) { assert(dev_info != NULL); @@ -113,7 +113,8 @@ static int allocate_entity(io_entity_t **entity) unsigned int index = 0; result = find_first_entity(NULL, &index); assert(result == 0); - *entity = entity_map[index] = &entity_pool[index]; + *entity = &entity_pool[index]; + entity_map[index] = &entity_pool[index]; ++entity_count; } @@ -161,8 +162,7 @@ int io_dev_open(const io_dev_connector_t *dev_con, const uintptr_t dev_spec, uintptr_t *handle) { assert(handle != NULL); - - return dev_open(dev_con, dev_spec, (io_dev_info_t **)handle); + return io_storage_dev_open(dev_con, dev_spec, (io_dev_info_t **)handle); } -- cgit v1.2.3 From 5a430c0219681afde74a8362665fe583473f0b0f Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 9 Jul 2020 12:33:17 +0100 Subject: rpi4/fdt: Move dtb_size() function to fdt_wrappers.h Getting the actual size of a DTB blob is useful beyond the Raspberry Pi port, so let's move this helper to a common header. Change-Id: Ia5be46e9353ca859a1e5ad9e3c057a322dfe22e2 Signed-off-by: Andre Przywara --- include/common/fdt_wrappers.h | 9 +++++++++ plat/rpi/rpi4/rpi4_bl31_setup.c | 10 ++-------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/include/common/fdt_wrappers.h b/include/common/fdt_wrappers.h index 1d8da1823..a571092e3 100644 --- a/include/common/fdt_wrappers.h +++ b/include/common/fdt_wrappers.h @@ -9,6 +9,8 @@ #ifndef FDT_WRAPPERS_H #define FDT_WRAPPERS_H +#include + /* Number of cells, given total length in bytes. Each cell is 4 bytes long */ #define NCELLS(len) ((len) / 4U) @@ -37,4 +39,11 @@ int fdt_get_stdout_node_offset(const void *dtb); uint64_t fdtw_translate_address(const void *dtb, int bus_node, uint64_t base_address); +static inline uint32_t fdt_blob_size(const void *dtb) +{ + const uint32_t *dtb_header = dtb; + + return fdt32_to_cpu(dtb_header[1]); +} + #endif /* FDT_WRAPPERS_H */ diff --git a/plat/rpi/rpi4/rpi4_bl31_setup.c b/plat/rpi/rpi4/rpi4_bl31_setup.c index 0a49d81b2..cfacd1fe1 100644 --- a/plat/rpi/rpi4/rpi4_bl31_setup.c +++ b/plat/rpi/rpi4/rpi4_bl31_setup.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -200,13 +201,6 @@ void bl31_plat_arch_setup(void) enable_mmu_el3(0); } -static uint32_t dtb_size(const void *dtb) -{ - const uint32_t *dtb_header = dtb; - - return fdt32_to_cpu(dtb_header[1]); -} - static void rpi4_prepare_dtb(void) { void *dtb = (void *)rpi4_get_dtb_address(); @@ -250,7 +244,7 @@ static void rpi4_prepare_dtb(void) if (ret < 0) ERROR("Failed to pack Device Tree at %p: error %d\n", dtb, ret); - clean_dcache_range((uintptr_t)dtb, dtb_size(dtb)); + clean_dcache_range((uintptr_t)dtb, fdt_blob_size(dtb)); INFO("Changed device tree to advertise PSCI.\n"); } -- cgit v1.2.3 From 7be2b9838c3d0ff617eecb1c54749229ecd7ac2f Mon Sep 17 00:00:00 2001 From: Leonardo Sandoval Date: Wed, 10 Jun 2020 18:26:28 -0500 Subject: doc: use docker to build documentation docker (container) is another way to build the documentation and fortunately there is already a docker image (sphinxdoc/sphinx) with sphinx so we can use it to generate the documentation. Change-Id: I06b0621cd7509a8279655e828680b92241b9fde4 Signed-off-by: Leonardo Sandoval --- docs/getting_started/docs-build.rst | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/docs/getting_started/docs-build.rst b/docs/getting_started/docs-build.rst index 91b1b3a39..87c677fcd 100644 --- a/docs/getting_started/docs-build.rst +++ b/docs/getting_started/docs-build.rst @@ -67,7 +67,7 @@ Output from the build process will be placed in: :: - docs/build/html/ + docs/build/html We also support building documentation in other formats. From the ``docs`` directory of the project, run the following command to see the supported @@ -79,6 +79,31 @@ top-level Makefile for |TF-A| itself. make help +Building rendered documentation from a container +------------------------------------------------ + +There may be cases where you can not either install or upgrade required +dependencies to generate the documents, so in this case, one way to +create the documentation is through a docker container. The first step is +to check if `docker`_ is installed in your host, otherwise check main docker +page for installation instructions. Once installed, run the following script +from project root directory + +.. code:: shell + + docker run --rm -v $PWD:/TF sphinxdoc/sphinx \ + bash -c 'cd /TF && \ + pip3 install plantuml -r ./docs/requirements.txt && make doc' + +The above command fetches the ``sphinxdoc/sphinx`` container from `docker +hub`_, launches the container, installs documentation requirements and finally +creates the documentation. Once done, exit the container and output from the +build process will be placed in: + +:: + + docs/build/html + -------------- *Copyright (c) 2019, Arm Limited. All rights reserved.* @@ -86,3 +111,5 @@ top-level Makefile for |TF-A| itself. .. _Sphinx: http://www.sphinx-doc.org/en/master/ .. _pip homepage: https://pip.pypa.io/en/stable/ .. _Dia: https://wiki.gnome.org/Apps/Dia +.. _docker: https://www.docker.com/ +.. _docker hub: https://hub.docker.com/repository/docker/sphinxdoc/sphinx -- cgit v1.2.3 From 1322dc94f7064652f33c7374cdd44be1b40d7d39 Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Tue, 14 Jul 2020 10:47:25 +0100 Subject: TF-A GICv2 driver: Introduce makefile This patch moves all GICv2 driver files into new added 'gicv2.mk' makefile for the benefit of the generic driver which can evolve in the future without affecting platforms. NOTE: Usage of 'drivers/arm/gic/common/gic_common.c' file is now deprecated and platforms with GICv2 driver need to be modified to include 'drivers/arm/gic/v2/gicv2.mk' in their makefiles. Change-Id: Ib10e71bdda0e5c7e80a049ddce2de1dd839602d1 Signed-off-by: Alexei Fedorov --- drivers/arm/gic/common/gic_common.c | 4 +- drivers/arm/gic/v2/gicdv2_helpers.c | 340 +++++++++++++++++++++++++++++++ drivers/arm/gic/v2/gicv2.mk | 15 ++ plat/arm/board/a5ds/platform.mk | 7 +- plat/arm/board/corstone700/platform.mk | 7 +- plat/arm/board/fvp/platform.mk | 9 +- plat/arm/board/fvp_ve/platform.mk | 9 +- plat/arm/board/juno/platform.mk | 7 +- plat/nvidia/tegra/common/tegra_common.mk | 9 +- 9 files changed, 383 insertions(+), 24 deletions(-) create mode 100644 drivers/arm/gic/v2/gicdv2_helpers.c create mode 100644 drivers/arm/gic/v2/gicv2.mk diff --git a/drivers/arm/gic/common/gic_common.c b/drivers/arm/gic/common/gic_common.c index 38b2f6719..bf6405f7f 100644 --- a/drivers/arm/gic/common/gic_common.c +++ b/drivers/arm/gic/common/gic_common.c @@ -1,9 +1,11 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ +#pragma message __FILE__ " is deprecated, use gicv2.mk instead" + #include #include diff --git a/drivers/arm/gic/v2/gicdv2_helpers.c b/drivers/arm/gic/v2/gicdv2_helpers.c new file mode 100644 index 000000000..db9ba87c4 --- /dev/null +++ b/drivers/arm/gic/v2/gicdv2_helpers.c @@ -0,0 +1,340 @@ +/* + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include + +#include "../common/gic_common_private.h" + +/******************************************************************************* + * GIC Distributor interface accessors for reading entire registers + ******************************************************************************/ +/* + * Accessor to read the GIC Distributor IGROUPR corresponding to the interrupt + * `id`, 32 interrupt ids at a time. + */ +unsigned int gicd_read_igroupr(uintptr_t base, unsigned int id) +{ + unsigned int n = id >> IGROUPR_SHIFT; + + return mmio_read_32(base + GICD_IGROUPR + (n << 2)); +} + +/* + * Accessor to read the GIC Distributor ISENABLER corresponding to the + * interrupt `id`, 32 interrupt ids at a time. + */ +unsigned int gicd_read_isenabler(uintptr_t base, unsigned int id) +{ + unsigned int n = id >> ISENABLER_SHIFT; + + return mmio_read_32(base + GICD_ISENABLER + (n << 2)); +} + +/* + * Accessor to read the GIC Distributor ICENABLER corresponding to the + * interrupt `id`, 32 interrupt IDs at a time. + */ +unsigned int gicd_read_icenabler(uintptr_t base, unsigned int id) +{ + unsigned int n = id >> ICENABLER_SHIFT; + + return mmio_read_32(base + GICD_ICENABLER + (n << 2)); +} + +/* + * Accessor to read the GIC Distributor ISPENDR corresponding to the + * interrupt `id`, 32 interrupt IDs at a time. + */ +unsigned int gicd_read_ispendr(uintptr_t base, unsigned int id) +{ + unsigned int n = id >> ISPENDR_SHIFT; + + return mmio_read_32(base + GICD_ISPENDR + (n << 2)); +} + +/* + * Accessor to read the GIC Distributor ICPENDR corresponding to the + * interrupt `id`, 32 interrupt IDs at a time. + */ +unsigned int gicd_read_icpendr(uintptr_t base, unsigned int id) +{ + unsigned int n = id >> ICPENDR_SHIFT; + + return mmio_read_32(base + GICD_ICPENDR + (n << 2)); +} + +/* + * Accessor to read the GIC Distributor ISACTIVER corresponding to the + * interrupt `id`, 32 interrupt IDs at a time. + */ +unsigned int gicd_read_isactiver(uintptr_t base, unsigned int id) +{ + unsigned int n = id >> ISACTIVER_SHIFT; + + return mmio_read_32(base + GICD_ISACTIVER + (n << 2)); +} + +/* + * Accessor to read the GIC Distributor ICACTIVER corresponding to the + * interrupt `id`, 32 interrupt IDs at a time. + */ +unsigned int gicd_read_icactiver(uintptr_t base, unsigned int id) +{ + unsigned int n = id >> ICACTIVER_SHIFT; + + return mmio_read_32(base + GICD_ICACTIVER + (n << 2)); +} + +/* + * Accessor to read the GIC Distributor IPRIORITYR corresponding to the + * interrupt `id`, 4 interrupt IDs at a time. + */ +unsigned int gicd_read_ipriorityr(uintptr_t base, unsigned int id) +{ + unsigned int n = id >> IPRIORITYR_SHIFT; + + return mmio_read_32(base + GICD_IPRIORITYR + (n << 2)); +} + +/* + * Accessor to read the GIC Distributor ICGFR corresponding to the + * interrupt `id`, 16 interrupt IDs at a time. + */ +unsigned int gicd_read_icfgr(uintptr_t base, unsigned int id) +{ + unsigned int n = id >> ICFGR_SHIFT; + + return mmio_read_32(base + GICD_ICFGR + (n << 2)); +} + +/* + * Accessor to read the GIC Distributor NSACR corresponding to the + * interrupt `id`, 16 interrupt IDs at a time. + */ +unsigned int gicd_read_nsacr(uintptr_t base, unsigned int id) +{ + unsigned int n = id >> NSACR_SHIFT; + + return mmio_read_32(base + GICD_NSACR + (n << 2)); +} + +/******************************************************************************* + * GIC Distributor interface accessors for writing entire registers + ******************************************************************************/ +/* + * Accessor to write the GIC Distributor IGROUPR corresponding to the + * interrupt `id`, 32 interrupt IDs at a time. + */ +void gicd_write_igroupr(uintptr_t base, unsigned int id, unsigned int val) +{ + unsigned int n = id >> IGROUPR_SHIFT; + + mmio_write_32(base + GICD_IGROUPR + (n << 2), val); +} + +/* + * Accessor to write the GIC Distributor ISENABLER corresponding to the + * interrupt `id`, 32 interrupt IDs at a time. + */ +void gicd_write_isenabler(uintptr_t base, unsigned int id, unsigned int val) +{ + unsigned int n = id >> ISENABLER_SHIFT; + + mmio_write_32(base + GICD_ISENABLER + (n << 2), val); +} + +/* + * Accessor to write the GIC Distributor ICENABLER corresponding to the + * interrupt `id`, 32 interrupt IDs at a time. + */ +void gicd_write_icenabler(uintptr_t base, unsigned int id, unsigned int val) +{ + unsigned int n = id >> ICENABLER_SHIFT; + + mmio_write_32(base + GICD_ICENABLER + (n << 2), val); +} + +/* + * Accessor to write the GIC Distributor ISPENDR corresponding to the + * interrupt `id`, 32 interrupt IDs at a time. + */ +void gicd_write_ispendr(uintptr_t base, unsigned int id, unsigned int val) +{ + unsigned int n = id >> ISPENDR_SHIFT; + + mmio_write_32(base + GICD_ISPENDR + (n << 2), val); +} + +/* + * Accessor to write the GIC Distributor ICPENDR corresponding to the + * interrupt `id`, 32 interrupt IDs at a time. + */ +void gicd_write_icpendr(uintptr_t base, unsigned int id, unsigned int val) +{ + unsigned int n = id >> ICPENDR_SHIFT; + + mmio_write_32(base + GICD_ICPENDR + (n << 2), val); +} + +/* + * Accessor to write the GIC Distributor ISACTIVER corresponding to the + * interrupt `id`, 32 interrupt IDs at a time. + */ +void gicd_write_isactiver(uintptr_t base, unsigned int id, unsigned int val) +{ + unsigned int n = id >> ISACTIVER_SHIFT; + + mmio_write_32(base + GICD_ISACTIVER + (n << 2), val); +} + +/* + * Accessor to write the GIC Distributor ICACTIVER corresponding to the + * interrupt `id`, 32 interrupt IDs at a time. + */ +void gicd_write_icactiver(uintptr_t base, unsigned int id, unsigned int val) +{ + unsigned int n = id >> ICACTIVER_SHIFT; + + mmio_write_32(base + GICD_ICACTIVER + (n << 2), val); +} + +/* + * Accessor to write the GIC Distributor IPRIORITYR corresponding to the + * interrupt `id`, 4 interrupt IDs at a time. + */ +void gicd_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val) +{ + unsigned int n = id >> IPRIORITYR_SHIFT; + + mmio_write_32(base + GICD_IPRIORITYR + (n << 2), val); +} + +/* + * Accessor to write the GIC Distributor ICFGR corresponding to the + * interrupt `id`, 16 interrupt IDs at a time. + */ +void gicd_write_icfgr(uintptr_t base, unsigned int id, unsigned int val) +{ + unsigned int n = id >> ICFGR_SHIFT; + + mmio_write_32(base + GICD_ICFGR + (n << 2), val); +} + +/* + * Accessor to write the GIC Distributor NSACR corresponding to the + * interrupt `id`, 16 interrupt IDs at a time. + */ +void gicd_write_nsacr(uintptr_t base, unsigned int id, unsigned int val) +{ + unsigned int n = id >> NSACR_SHIFT; + + mmio_write_32(base + GICD_NSACR + (n << 2), val); +} + +/******************************************************************************* + * GIC Distributor functions for accessing the GIC registers + * corresponding to a single interrupt ID. These functions use bitwise + * operations or appropriate register accesses to modify or return + * the bit-field corresponding the single interrupt ID. + ******************************************************************************/ +unsigned int gicd_get_igroupr(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U); + unsigned int reg_val = gicd_read_igroupr(base, id); + + return (reg_val >> bit_num) & 0x1U; +} + +void gicd_set_igroupr(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U); + unsigned int reg_val = gicd_read_igroupr(base, id); + + gicd_write_igroupr(base, id, reg_val | (1U << bit_num)); +} + +void gicd_clr_igroupr(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U); + unsigned int reg_val = gicd_read_igroupr(base, id); + + gicd_write_igroupr(base, id, reg_val & ~(1U << bit_num)); +} + +void gicd_set_isenabler(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << ISENABLER_SHIFT) - 1U); + + gicd_write_isenabler(base, id, (1U << bit_num)); +} + +void gicd_set_icenabler(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << ICENABLER_SHIFT) - 1U); + + gicd_write_icenabler(base, id, (1U << bit_num)); +} + +void gicd_set_ispendr(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << ISPENDR_SHIFT) - 1U); + + gicd_write_ispendr(base, id, (1U << bit_num)); +} + +void gicd_set_icpendr(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << ICPENDR_SHIFT) - 1U); + + gicd_write_icpendr(base, id, (1U << bit_num)); +} + +unsigned int gicd_get_isactiver(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << ISACTIVER_SHIFT) - 1U); + unsigned int reg_val = gicd_read_isactiver(base, id); + + return (reg_val >> bit_num) & 0x1U; +} + +void gicd_set_isactiver(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << ISACTIVER_SHIFT) - 1U); + + gicd_write_isactiver(base, id, (1U << bit_num)); +} + +void gicd_set_icactiver(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << ICACTIVER_SHIFT) - 1U); + + gicd_write_icactiver(base, id, (1U << bit_num)); +} + +void gicd_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri) +{ + uint8_t val = pri & GIC_PRI_MASK; + + mmio_write_8(base + GICD_IPRIORITYR + id, val); +} + +void gicd_set_icfgr(uintptr_t base, unsigned int id, unsigned int cfg) +{ + /* Interrupt configuration is a 2-bit field */ + unsigned int bit_num = id & ((1U << ICFGR_SHIFT) - 1U); + unsigned int bit_shift = bit_num << 1; + + uint32_t reg_val = gicd_read_icfgr(base, id); + + /* Clear the field, and insert required configuration */ + reg_val &= ~(GIC_CFG_MASK << bit_shift); + reg_val |= ((cfg & GIC_CFG_MASK) << bit_shift); + + gicd_write_icfgr(base, id, reg_val); +} diff --git a/drivers/arm/gic/v2/gicv2.mk b/drivers/arm/gic/v2/gicv2.mk new file mode 100644 index 000000000..49996bb51 --- /dev/null +++ b/drivers/arm/gic/v2/gicv2.mk @@ -0,0 +1,15 @@ +# +# Copyright (c) 2020, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# No support for extended PPI and SPI range +GIC_EXT_INTID := 0 + +GICV2_SOURCES += drivers/arm/gic/v2/gicv2_main.c \ + drivers/arm/gic/v2/gicv2_helpers.c \ + drivers/arm/gic/v2/gicdv2_helpers.c + +# Set GICv2 build option +$(eval $(call add_define,GIC_EXT_INTID)) \ No newline at end of file diff --git a/plat/arm/board/a5ds/platform.mk b/plat/arm/board/a5ds/platform.mk index 7693e46e1..5d610f49c 100644 --- a/plat/arm/board/a5ds/platform.mk +++ b/plat/arm/board/a5ds/platform.mk @@ -14,9 +14,10 @@ DYN_CFG_SOURCES += plat/arm/common/arm_dyn_cfg.c \ plat/arm/common/arm_dyn_cfg_helpers.c \ common/fdt_wrappers.c -A5DS_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v2/gicv2_main.c \ - drivers/arm/gic/v2/gicv2_helpers.c \ +# Include GICv2 driver files +include drivers/arm/gic/v2/gicv2.mk + +A5DS_GIC_SOURCES := ${GICV2_SOURCES} \ plat/common/plat_gicv2.c \ plat/arm/common/arm_gicv2.c diff --git a/plat/arm/board/corstone700/platform.mk b/plat/arm/board/corstone700/platform.mk index 3398fba2c..513af3c20 100644 --- a/plat/arm/board/corstone700/platform.mk +++ b/plat/arm/board/corstone700/platform.mk @@ -25,9 +25,10 @@ PLAT_INCLUDES := -Iplat/arm/board/corstone700/common/include \ NEED_BL32 := yes -CORSTONE700_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v2/gicv2_main.c \ - drivers/arm/gic/v2/gicv2_helpers.c \ +# Include GICv2 driver files +include drivers/arm/gic/v2/gicv2.mk + +CORSTONE700_GIC_SOURCES := ${GICV2_SOURCES} \ plat/common/plat_gicv2.c \ plat/arm/common/arm_gicv2.c diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index c3b49bb58..9b8fccc55 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -72,13 +72,10 @@ else ifeq (${FVP_USE_GIC_DRIVER}, FVP_GICV2) GIC_ENABLE_V4_EXTN := 0 $(eval $(call add_define,GIC_ENABLE_V4_EXTN)) -# No support for extended PPI and SPI range -GIC_EXT_INTID := 0 -$(eval $(call add_define,GIC_EXT_INTID)) +# Include GICv2 driver files +include drivers/arm/gic/v2/gicv2.mk -FVP_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v2/gicv2_main.c \ - drivers/arm/gic/v2/gicv2_helpers.c \ +FVP_GIC_SOURCES := ${GICV2_SOURCES} \ plat/common/plat_gicv2.c \ plat/arm/common/arm_gicv2.c diff --git a/plat/arm/board/fvp_ve/platform.mk b/plat/arm/board/fvp_ve/platform.mk index 62981c529..f8e38ffc0 100644 --- a/plat/arm/board/fvp_ve/platform.mk +++ b/plat/arm/board/fvp_ve/platform.mk @@ -11,10 +11,11 @@ $(eval $(call add_define,FVP_VE_USE_SP804_TIMER)) BL2_SOURCES += drivers/arm/sp804/sp804_delay_timer.c endif -FVP_VE_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v2/gicv2_main.c \ - drivers/arm/gic/v2/gicv2_helpers.c \ - plat/common/plat_gicv2.c \ +# Include GICv2 driver files +include drivers/arm/gic/v2/gicv2.mk + +FVP_VE_GIC_SOURCES := ${GICV2_SOURCES} \ + plat/common/plat_gicv2.c \ plat/arm/common/arm_gicv2.c FVP_VE_SECURITY_SOURCES := plat/arm/board/fvp_ve/fvp_ve_security.c diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk index 8ca7f6120..196d3c044 100644 --- a/plat/arm/board/juno/platform.mk +++ b/plat/arm/board/juno/platform.mk @@ -4,9 +4,10 @@ # SPDX-License-Identifier: BSD-3-Clause # -JUNO_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v2/gicv2_main.c \ - drivers/arm/gic/v2/gicv2_helpers.c \ +# Include GICv2 driver files +include drivers/arm/gic/v2/gicv2.mk + +JUNO_GIC_SOURCES := ${GICV2_SOURCES} \ plat/common/plat_gicv2.c \ plat/arm/common/arm_gicv2.c diff --git a/plat/nvidia/tegra/common/tegra_common.mk b/plat/nvidia/tegra/common/tegra_common.mk index 82dd60697..f412a80b8 100644 --- a/plat/nvidia/tegra/common/tegra_common.mk +++ b/plat/nvidia/tegra/common/tegra_common.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. # Copyright (c) 2020, NVIDIA Corporation. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause @@ -20,9 +20,10 @@ TEGRA_GICv3_SOURCES := $(GICV3_SOURCES) \ plat/common/plat_gicv3.c \ ${COMMON_DIR}/tegra_gicv3.c -TEGRA_GICv2_SOURCES := drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v2/gicv2_main.c \ - drivers/arm/gic/v2/gicv2_helpers.c \ +# Include GICv2 driver files +include drivers/arm/gic/v2/gicv2.mk + +TEGRA_GICv2_SOURCES := ${GICV2_SOURCES} \ plat/common/plat_gicv2.c \ ${COMMON_DIR}/tegra_gicv2.c -- cgit v1.2.3 From 91879af72e9c9dc17bd6b1db630d31d80f89109b Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Mon, 20 Jul 2020 13:26:49 +0100 Subject: FVP Doc: Update list of supported FVP platforms This patch adds the following models FVP_Base_Neoverse-E1x1 FVP_Base_Neoverse-E1x2 FVP_Base_Neoverse-E1x4 to the list of supported FVP platforms. Change-Id: Ib526a2a735f17724af3a874b06bf69b4ca85d0dd Signed-off-by: Alexei Fedorov --- docs/plat/arm/fvp/index.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/plat/arm/fvp/index.rst b/docs/plat/arm/fvp/index.rst index f23ec2804..a6ff19a25 100644 --- a/docs/plat/arm/fvp/index.rst +++ b/docs/plat/arm/fvp/index.rst @@ -37,6 +37,9 @@ Arm FVPs without shifted affinities, and that do not support threaded CPU cores - ``FVP_Base_Cortex-A76AEx4`` - ``FVP_Base_Cortex-A76AEx8`` - ``FVP_Base_Cortex-A77x4`` +- ``FVP_Base_Neoverse-E1x1`` +- ``FVP_Base_Neoverse-E1x2`` +- ``FVP_Base_Neoverse-E1x4`` - ``FVP_Base_Neoverse-N1x4`` - ``FVP_Base_Zeusx4`` - ``FVP_CSS_SGI-575`` (Version 11.10 build 25) -- cgit v1.2.3 From e270e6751131d5af3e783ee21913d4dcc73014fb Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Fri, 26 Jun 2020 10:30:33 +0100 Subject: gicv3: Do power management on Arm GIC-Clayton as well The Arm GIC-Clayton IP has the same power management requirements as the GIC-600, when it comes to powering up the redistributors before using them. Add the IIDR value to the existing list of implementations requiring the power sequence. Change-Id: Ib965dfe278c40a4fff94f65a8d445c27a2ae6fd2 Signed-off-by: Andre Przywara --- drivers/arm/gic/v3/gic-x00.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/arm/gic/v3/gic-x00.c b/drivers/arm/gic/v3/gic-x00.c index cc9717451..c9e9cb98f 100644 --- a/drivers/arm/gic/v3/gic-x00.c +++ b/drivers/arm/gic/v3/gic-x00.c @@ -24,6 +24,7 @@ #define GICR_PWRR 0x24 #define IIDR_MODEL_ARM_GIC_600 (0x0200043b) #define IIDR_MODEL_ARM_GIC_600AE (0x0300043b) +#define IIDR_MODEL_ARM_GIC_CLAYTON (0x0400043b) /* GICR_PWRR fields */ #define PWRR_RDPD_SHIFT 0 @@ -45,7 +46,7 @@ #if GICV3_SUPPORT_GIC600 -/* GIC-600 specific accessor functions */ +/* GIC-600/Clayton specific accessor functions */ static void gicr_write_pwrr(uintptr_t base, unsigned int val) { mmio_write_32(base + GICR_PWRR, val); @@ -113,12 +114,17 @@ static uintptr_t get_gicr_base(unsigned int proc_num) return gicr_base; } -static bool gicv3_is_gic600(uintptr_t gicr_base) +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 + * 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_600AE) || + ((reg & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_CLAYTON)); } #endif @@ -143,7 +149,7 @@ void gicv3_rdistif_off(unsigned int proc_num) uintptr_t gicr_base = get_gicr_base(proc_num); /* Attempt to power redistributor off */ - if (gicv3_is_gic600(gicr_base)) { + if (gicv3_redists_need_power_mgmt(gicr_base)) { gic600_pwr_off(gicr_base); } #endif @@ -158,7 +164,7 @@ void gicv3_rdistif_on(unsigned int proc_num) uintptr_t gicr_base = get_gicr_base(proc_num); /* Power redistributor on */ - if (gicv3_is_gic600(gicr_base)) { + if (gicv3_redists_need_power_mgmt(gicr_base)) { gic600_pwr_on(gicr_base); } #endif -- cgit v1.2.3 From 98e9dcf5437fc2d82702cdd20f19d78478fe3f2d Mon Sep 17 00:00:00 2001 From: Vijayenthiran Subramaniam Date: Tue, 14 Jul 2020 15:22:14 +0530 Subject: plat/arm/rddaniel: add platform function to return ROTPK TBBR authentication framework depends on the plat_get_rotpk_info() function to return the pointer to the Root of Trust Public Key (ROTPK) stored in the platform along with its length. Add this function for RD-Daniel platform to support Trusted Board Boot. The function makes use of the wrapper function provided by the arm common trusted board boot function to get the ROTPK hash. Change-Id: I6c2826a7898664afea19fd62432684cfddd9319a Signed-off-by: Vijayenthiran Subramaniam --- plat/arm/board/rddaniel/platform.mk | 5 +++++ plat/arm/board/rddaniel/rddaniel_trusted_boot.c | 26 +++++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 plat/arm/board/rddaniel/rddaniel_trusted_boot.c diff --git a/plat/arm/board/rddaniel/platform.mk b/plat/arm/board/rddaniel/platform.mk index bdf20ca3d..81632a5f1 100644 --- a/plat/arm/board/rddaniel/platform.mk +++ b/plat/arm/board/rddaniel/platform.mk @@ -32,6 +32,11 @@ BL31_SOURCES += ${SGI_CPU_SOURCES} \ lib/utils/mem_region.c \ plat/arm/common/arm_nor_psci_mem_protect.c +ifeq (${TRUSTED_BOARD_BOOT}, 1) +BL1_SOURCES += ${RDDANIEL_BASE}/rddaniel_trusted_boot.c +BL2_SOURCES += ${RDDANIEL_BASE}/rddaniel_trusted_boot.c +endif + # Add the FDT_SOURCES and options for Dynamic Config FDT_SOURCES += ${RDDANIEL_BASE}/fdts/${PLAT}_fw_config.dts \ ${RDDANIEL_BASE}/fdts/${PLAT}_tb_fw_config.dts diff --git a/plat/arm/board/rddaniel/rddaniel_trusted_boot.c b/plat/arm/board/rddaniel/rddaniel_trusted_boot.c new file mode 100644 index 000000000..4592b8fba --- /dev/null +++ b/plat/arm/board/rddaniel/rddaniel_trusted_boot.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#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); +} -- cgit v1.2.3 From 0ae9bc270c41a3d8824354fa6d9343f35ae0c924 Mon Sep 17 00:00:00 2001 From: Vijayenthiran Subramaniam Date: Tue, 14 Jul 2020 15:51:37 +0530 Subject: plat/arm/rddanielxlr: add platform function to return ROTPK TBBR authentication framework depends on the plat_get_rotpk_info() function to return the pointer to the Root of Trust Public Key (ROTPK) stored in the platform along with its length. Add this function for RD-Daniel Config-XLR platform to support Trusted Board Boot. The function makes use of the wrapper function provided by the arm common trusted board boot function to get the ROTPK hash. Change-Id: I509e2f7e88cc2167e1732a971d71dc131d3d4b01 Signed-off-by: Vijayenthiran Subramaniam --- plat/arm/board/rddanielxlr/platform.mk | 5 +++++ .../board/rddanielxlr/rddanielxlr_trusted_boot.c | 26 ++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 plat/arm/board/rddanielxlr/rddanielxlr_trusted_boot.c diff --git a/plat/arm/board/rddanielxlr/platform.mk b/plat/arm/board/rddanielxlr/platform.mk index 1482c814f..93967ad28 100644 --- a/plat/arm/board/rddanielxlr/platform.mk +++ b/plat/arm/board/rddanielxlr/platform.mk @@ -32,6 +32,11 @@ BL31_SOURCES += ${SGI_CPU_SOURCES} \ lib/utils/mem_region.c \ plat/arm/common/arm_nor_psci_mem_protect.c +ifeq (${TRUSTED_BOARD_BOOT}, 1) +BL1_SOURCES += ${RDDANIELXLR_BASE}/rddanielxlr_trusted_boot.c +BL2_SOURCES += ${RDDANIELXLR_BASE}/rddanielxlr_trusted_boot.c +endif + # Enable dynamic addition of MMAP regions in BL31 BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC diff --git a/plat/arm/board/rddanielxlr/rddanielxlr_trusted_boot.c b/plat/arm/board/rddanielxlr/rddanielxlr_trusted_boot.c new file mode 100644 index 000000000..4592b8fba --- /dev/null +++ b/plat/arm/board/rddanielxlr/rddanielxlr_trusted_boot.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#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); +} -- cgit v1.2.3 From 294d7bf2bc0331e5cf205c68032e64b0421a8262 Mon Sep 17 00:00:00 2001 From: Javier Almansa Sobrino Date: Mon, 20 Jul 2020 13:17:45 +0100 Subject: Add myself and Alexei Fedorov as Measured Boot code owners Signed-off-by: Javier Almansa Sobrino Change-Id: Ib327bda239bb5163c60764bae90b0739589dcf66 --- docs/about/maintainers.rst | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst index ea9a4f58a..60ad42edf 100644 --- a/docs/about/maintainers.rst +++ b/docs/about/maintainers.rst @@ -21,7 +21,7 @@ Maintainers :G: `soby-mathew`_ :M: Sandrine Bailleux :G: `sandrine-bailleux-arm`_ -:M: Alexei Fedorov +:M: Alexei Fedorov :G: `AlexeiFedorov`_ :M: Manish Pandey :G: `manish-pandey-arm`_ @@ -185,7 +185,7 @@ Reliability Availability Serviceabilty (RAS) framework Activity Monitors Unit (AMU) extensions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -:M: Alexei Fedorov +:M: Alexei Fedorov :G: `AlexeiFedorov`_ :F: lib/extensions/amu/ @@ -199,7 +199,7 @@ Memory Partitioning And Monitoring (MPAM) extensions Pointer Authentication (PAuth) and Branch Target Identification (BTI) extensions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -:M: Alexei Fedorov +:M: Alexei Fedorov :G: `AlexeiFedorov`_ :M: Zelalem Aweke :G: `zelalem-aweke`_ @@ -221,7 +221,7 @@ Scalable Vector Extension (SVE) Standard C library ^^^^^^^^^^^^^^^^^^ -:M: Alexei Fedorov +:M: Alexei Fedorov :G: `AlexeiFedorov`_ :M: John Powell :G: `john-powell-arm`_ @@ -251,7 +251,7 @@ IO abstraction layer GIC driver ^^^^^^^^^^ -:M: Alexei Fedorov +:M: Alexei Fedorov :G: `AlexeiFedorov`_ :M: Manish Pandey :G: `manish-pandey-arm`_ @@ -277,6 +277,15 @@ Firmware Encryption Framework :F: include/drivers/io/io_encrypted.h :F: include/tools_share/firmware_encrypted.h +Measured Boot +^^^^^^^^^^^^^ +:M: Alexei Fedorov +:G: `AlexeiFedorov`_ +:M: Javier Almansa Sobrino +:G: `javieralso-arm`_ +:F: drivers/measured_boot +:F: include/drivers/measured_boot +:F: plat/arm/board/fvp/fvp_measured_boot.c Platform Ports ~~~~~~~~~~~~~~ -- cgit v1.2.3 From fcb1398ff1cefe747cd8c5a0e6cef8d11153009e Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Thu, 2 Apr 2020 15:38:02 +0200 Subject: doc: secure partition manager design Former EL3 Secure Partition Manager using MM protocol is renamed Secure Partition Manager (MM). A new Secure Partition Manager document covers TF-A support for the PSA FF-A compliant implementation. Signed-off-by: Olivier Deprez Change-Id: I9763359c2e96181e1726c8ad72738de293b80eb4 --- docs/components/index.rst | 3 +- .../components/secure-partition-manager-design.rst | 819 ------------------- docs/components/secure-partition-manager-mm.rst | 836 ++++++++++++++++++++ docs/components/secure-partition-manager.rst | 867 +++++++++++++++++++++ docs/resources/diagrams/ff-a-spm-sel2.png | Bin 0 -> 83369 bytes .../diagrams/plantuml/bl2-loading-sp.puml | 44 ++ .../diagrams/plantuml/fip-secure-partitions.puml | 122 +++ 7 files changed, 1871 insertions(+), 820 deletions(-) delete mode 100644 docs/components/secure-partition-manager-design.rst create mode 100644 docs/components/secure-partition-manager-mm.rst create mode 100644 docs/components/secure-partition-manager.rst create mode 100644 docs/resources/diagrams/ff-a-spm-sel2.png create mode 100644 docs/resources/diagrams/plantuml/bl2-loading-sp.puml create mode 100644 docs/resources/diagrams/plantuml/fip-secure-partitions.puml diff --git a/docs/components/index.rst b/docs/components/index.rst index 18b1e38bb..861a85d96 100644 --- a/docs/components/index.rst +++ b/docs/components/index.rst @@ -16,7 +16,8 @@ Components ras romlib-design sdei - secure-partition-manager-design + secure-partition-manager + secure-partition-manager-mm psa-ffa-manifest-binding xlat-tables-lib-v2-design cot-binding diff --git a/docs/components/secure-partition-manager-design.rst b/docs/components/secure-partition-manager-design.rst deleted file mode 100644 index 4f6718594..000000000 --- a/docs/components/secure-partition-manager-design.rst +++ /dev/null @@ -1,819 +0,0 @@ -Secure Partition Manager -************************ - -Background -========== - -In some market segments that primarily deal with client-side devices like mobile -phones, tablets, STBs and embedded devices, a Trusted OS instantiates trusted -applications to provide security services like DRM, secure payment and -authentication. The Global Platform TEE Client API specification defines the API -used by Non-secure world applications to access these services. A Trusted OS -fulfils the requirements of a security service as described above. - -Management services are typically implemented at the highest level of privilege -in the system, i.e. EL3 in Trusted Firmware-A (TF-A). The service requirements are -fulfilled by the execution environment provided by TF-A. - -The following diagram illustrates the corresponding software stack: - -|Image 1| - -In other market segments that primarily deal with server-side devices (e.g. data -centres and enterprise servers) the secure software stack typically does not -include a Global Platform Trusted OS. Security functions are accessed through -other interfaces (e.g. ACPI TCG TPM interface, UEFI runtime variable service). - -Placement of management and security functions with diverse requirements in a -privileged Exception Level (i.e. EL3 or S-EL1) makes security auditing of -firmware more difficult and does not allow isolation of unrelated services from -each other either. - -Introduction -============ - -A **Secure Partition** is a software execution environment instantiated in -S-EL0 that can be used to implement simple management and security services. -Since S-EL0 is an unprivileged Exception Level, a Secure Partition relies on -privileged firmware (i.e. TF-A) to be granted access to system and processor -resources. Essentially, it is a software sandbox in the Secure world that runs -under the control of privileged software, provides one or more services and -accesses the following system resources: - -- Memory and device regions in the system address map. - -- PE system registers. - -- A range of synchronous exceptions (e.g. SMC function identifiers). - -Note that currently TF-A only supports handling one Secure Partition. - -A Secure Partition enables TF-A to implement only the essential secure -services in EL3 and instantiate the rest in a partition in S-EL0. -Furthermore, multiple Secure Partitions can be used to isolate unrelated -services from each other. - -The following diagram illustrates the place of a Secure Partition in a typical -Armv8-A software stack. A single or multiple Secure Partitions provide secure -services to software components in the Non-secure world and other Secure -Partitions. - -|Image 2| - -The TF-A build system is responsible for including the Secure Partition image -in the FIP. During boot, BL2 includes support to authenticate and load the -Secure Partition image. A BL31 component called **Secure Partition Manager -(SPM)** is responsible for managing the partition. This is semantically -similar to a hypervisor managing a virtual machine. - -The SPM is responsible for the following actions during boot: - -- Allocate resources requested by the Secure Partition. - -- Perform architectural and system setup required by the Secure Partition to - fulfil a service request. - -- Implement a standard interface that is used for initialising a Secure - Partition. - -The SPM is responsible for the following actions during runtime: - -- Implement a standard interface that is used by a Secure Partition to fulfil - service requests. - -- Implement a standard interface that is used by the Non-secure world for - accessing the services exported by a Secure Partition. A service can be - invoked through a SMC. - -Alternatively, a partition can be viewed as a thread of execution running under -the control of the SPM. Hence common programming concepts described below are -applicable to a partition. - -Description -=========== - -The previous section introduced some general aspects of the software -architecture of a Secure Partition. This section describes the specific choices -made in the current implementation of this software architecture. Subsequent -revisions of the implementation will include a richer set of features that -enable a more flexible architecture. - -Building TF-A with Secure Partition support -------------------------------------------- - -SPM is supported on the Arm FVP exclusively at the moment. The current -implementation supports inclusion of only a single Secure Partition in which a -service always runs to completion (e.g. the requested services cannot be -preempted to give control back to the Normal world). - -It is not currently possible for BL31 to integrate SPM support and a Secure -Payload Dispatcher (SPD) at the same time; they are mutually exclusive. In the -SPM bootflow, a Secure Partition image executing at S-EL0 replaces the Secure -Payload image executing at S-EL1 (e.g. a Trusted OS). Both are referred to as -BL32. - -A working prototype of a SP has been implemented by re-purposing the EDK2 code -and tools, leveraging the concept of the *Standalone Management Mode (MM)* in -the UEFI specification (see the PI v1.6 Volume 4: Management Mode Core -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 -location of the binary that contains the BL32 image -(``BL32=path/to/image.bin``) must be specified. - -First, build the Standalone MM Secure Partition. To build it, refer to the -`instructions in the EDK2 repository`_. - -Then build TF-A with SPM support and include the Standalone MM Secure Partition -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 - -Describing Secure Partition resources -------------------------------------- - -TF-A exports a porting interface that enables a platform to specify the system -resources required by the Secure Partition. Some instructions are given below. -However, this interface is under development and it may change as new features -are implemented. - -- A Secure Partition is considered a BL32 image, so the same defines that apply - to BL32 images apply to a Secure Partition: ``BL32_BASE`` and ``BL32_LIMIT``. - -- The following defines are needed to allocate space for the translation tables - used by the Secure Partition: ``PLAT_SP_IMAGE_MMAP_REGIONS`` and - ``PLAT_SP_IMAGE_MAX_XLAT_TABLES``. - -- The functions ``plat_get_secure_partition_mmap()`` and - ``plat_get_secure_partition_boot_info()`` have to be implemented. The file - ``plat/arm/board/fvp/fvp_common.c`` can be used as an example. It uses the - defines in ``include/plat/arm/common/arm_spm_def.h``. - - - ``plat_get_secure_partition_mmap()`` returns an array of mmap regions that - describe the memory regions that the SPM needs to allocate for a Secure - Partition. - - - ``plat_get_secure_partition_boot_info()`` returns a - ``spm_mm_boot_info_t`` struct that is populated by the platform - with information about the memory map of the Secure Partition. - -For an example of all the changes in context, you may refer to commit -``e29efeb1b4``, in which the port for FVP was introduced. - -Accessing Secure Partition services ------------------------------------ - -The `SMC Calling Convention`_ (*Arm DEN 0028B*) describes SMCs as a conduit for -accessing services implemented in the Secure world. The ``MM_COMMUNICATE`` -interface defined in the `Management Mode Interface Specification`_ (*Arm DEN -0060A*) is used to invoke a Secure Partition service as a Fast Call. - -The mechanism used to identify a service within the partition depends on the -service implementation. It is assumed that the caller of the service will be -able to discover this mechanism through standard platform discovery mechanisms -like ACPI and Device Trees. For example, *Volume 4: Platform Initialisation -Specification v1.6. Management Mode Core Interface* specifies that a GUID is -used to identify a management mode service. A client populates the GUID in the -``EFI_MM_COMMUNICATE_HEADER``. The header is populated in the communication -buffer shared with the Secure Partition. - -A Fast Call appears to be atomic from the perspective of the caller and returns -when the requested operation has completed. A service invoked through the -``MM_COMMUNICATE`` SMC will run to completion in the partition on a given CPU. -The SPM is responsible for guaranteeing this behaviour. This means that there -can only be a single outstanding Fast Call in a partition on a given CPU. - -Exchanging data with the Secure Partition ------------------------------------------ - -The exchange of data between the Non-secure world and the partition takes place -through a shared memory region. The location of data in the shared memory area -is passed as a parameter to the ``MM_COMMUNICATE`` SMC. The shared memory area -is statically allocated by the SPM and is expected to be either implicitly known -to the Non-secure world or discovered through a platform discovery mechanism -e.g. ACPI table or device tree. It is possible for the Non-secure world to -exchange data with a partition only if it has been populated in this shared -memory area. The shared memory area is implemented as per the guidelines -specified in Section 3.2.3 of the `Management Mode Interface Specification`_ -(*Arm DEN 0060A*). - -The format of data structures used to encapsulate data in the shared memory is -agreed between the Non-secure world and the Secure Partition. For example, in -the `Management Mode Interface specification`_ (*Arm DEN 0060A*), Section 4 -describes that the communication buffer shared between the Non-secure world and -the Management Mode (MM) in the Secure world must be of the type -``EFI_MM_COMMUNICATE_HEADER``. This data structure is defined in *Volume 4: -Platform Initialisation Specification v1.6. Management Mode Core Interface*. -Any caller of a MM service will have to use the ``EFI_MM_COMMUNICATE_HEADER`` -data structure. - -Runtime model of the Secure Partition -===================================== - -This section describes how the Secure Partition interfaces with the SPM. - -Interface with SPM ------------------- - -In order to instantiate one or more secure services in the Secure Partition in -S-EL0, the SPM should define the following types of interfaces: - -- Interfaces that enable access to privileged operations from S-EL0. These - operations typically require access to system resources that are either shared - amongst multiple software components in the Secure world or cannot be directly - accessed from an unprivileged Exception Level. - -- Interfaces that establish the control path between the SPM and the Secure - Partition. - -This section describes the APIs currently exported by the SPM that enable a -Secure Partition to initialise itself and export its services in S-EL0. These -interfaces are not accessible from the Non-secure world. - -Conduit -^^^^^^^ - -The `SMC Calling Convention`_ (*Arm DEN 0028B*) specification describes the SMC -and HVC conduits for accessing firmware services and their availability -depending on the implemented Exception levels. In S-EL0, the Supervisor Call -exception (SVC) is the only architectural mechanism available for unprivileged -software to make a request for an operation implemented in privileged software. -Hence, the SVC conduit must be used by the Secure Partition to access interfaces -implemented by the SPM. - -A SVC causes an exception to be taken to S-EL1. TF-A assumes ownership of S-EL1 -and installs a simple exception vector table in S-EL1 that relays a SVC request -from a Secure Partition as a SMC request to the SPM in EL3. Upon servicing the -SMC request, Trusted Firmware-A returns control directly to S-EL0 through an -ERET instruction. - -Calling conventions -^^^^^^^^^^^^^^^^^^^ - -The `SMC Calling Convention`_ (*Arm DEN 0028B*) specification describes the -32-bit and 64-bit calling conventions for the SMC and HVC conduits. The SVC -conduit introduces the concept of SVC32 and SVC64 calling conventions. The SVC32 -and SVC64 calling conventions are equivalent to the 32-bit (SMC32) and the -64-bit (SMC64) calling conventions respectively. - -Communication initiated by SPM -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -A service request is initiated from the SPM through an exception return -instruction (ERET) to S-EL0. Later, the Secure Partition issues an SVC -instruction to signal completion of the request. Some example use cases are -given below: - -- A request to initialise the Secure Partition during system boot. - -- A request to handle a runtime service request. - -Communication initiated by Secure Partition -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -A request is initiated from the Secure Partition by executing a SVC instruction. -An ERET instruction is used by TF-A to return to S-EL0 with the result of the -request. - -For instance, a request to perform privileged operations on behalf of a -partition (e.g. management of memory attributes in the translation tables for -the Secure EL1&0 translation regime). - -Interfaces -^^^^^^^^^^ - -The current implementation reserves function IDs for Fast Calls in the Standard -Secure Service calls range (see `SMC Calling Convention`_ (*Arm DEN 0028B*) -specification) for each API exported by the SPM. This section defines the -function prototypes for each function ID. The function IDs specify whether one -or both of the SVC32 and SVC64 calling conventions can be used to invoke the -corresponding interface. - -Secure Partition Event Management -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The Secure Partition provides an Event Management interface that is used by the -SPM to delegate service requests to the Secure Partition. The interface also -allows the Secure Partition to: - -- Register with the SPM a service that it provides. -- Indicate completion of a service request delegated by the SPM - -Miscellaneous interfaces ------------------------- - -``SPM_MM_VERSION_AARCH32`` -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- Description - - Returns the version of the interface exported by SPM. - -- Parameters - - - **uint32** - Function ID - - - SVC32 Version: **0x84000060** - -- Return parameters - - - **int32** - Status - - On success, the format of the value is as follows: - - - Bit [31]: Must be 0 - - Bits [30:16]: Major Version. Must be 0 for this revision of the SPM - interface. - - Bits [15:0]: Minor Version. Must be 1 for this revision of the SPM - interface. - - On error, the format of the value is as follows: - - - ``NOT_SUPPORTED``: SPM interface is not supported or not available for the - client. - -- Usage - - This function returns the version of the Secure Partition Manager - implementation. The major version is 0 and the minor version is 1. The version - number is a 31-bit unsigned integer, with the upper 15 bits denoting the major - revision, and the lower 16 bits denoting the minor revision. The following - rules apply to the version numbering: - - - Different major revision values indicate possibly incompatible functions. - - - For two revisions, A and B, for which the major revision values are - identical, if the minor revision value of revision B is greater than the - minor revision value of revision A, then every function in revision A must - work in a compatible way with revision B. However, it is possible for - revision B to have a higher function count than revision A. - -- Implementation responsibilities - - If this function returns a valid version number, all the functions that are - described subsequently must be implemented, unless it is explicitly stated - that a function is optional. - -See `Error Codes`_ for integer values that are associated with each return -code. - -Secure Partition Initialisation -------------------------------- - -The SPM is responsible for initialising the architectural execution context to -enable initialisation of a service in S-EL0. The responsibilities of the SPM are -listed below. At the end of initialisation, the partition issues a -``MM_SP_EVENT_COMPLETE_AARCH64`` call (described later) to signal readiness for -handling requests for services implemented by the Secure Partition. The -initialisation event is executed as a Fast Call. - -Entry point invocation -^^^^^^^^^^^^^^^^^^^^^^ - -The entry point for service requests that should be handled as Fast Calls is -used as the target of the ERET instruction to start initialisation of the Secure -Partition. - -Architectural Setup -^^^^^^^^^^^^^^^^^^^ - -At cold boot, system registers accessible from S-EL0 will be in their reset -state unless otherwise specified. The SPM will perform the following -architectural setup to enable execution in S-EL0 - -MMU setup -^^^^^^^^^ - -The platform port of a Secure Partition specifies to the SPM a list of regions -that it needs access to and their attributes. The SPM validates this resource -description and initialises the Secure EL1&0 translation regime as follows. - -1. Device regions are mapped with nGnRE attributes and Execute Never - instruction access permissions. - -2. Code memory regions are mapped with RO data and Executable instruction access - permissions. - -3. Read Only data memory regions are mapped with RO data and Execute Never - instruction access permissions. - -4. Read Write data memory regions are mapped with RW data and Execute Never - instruction access permissions. - -5. If the resource description does not explicitly describe the type of memory - regions then all memory regions will be marked with Code memory region - attributes. - -6. The ``UXN`` and ``PXN`` bits are set for regions that are not executable by - S-EL0 or S-EL1. - -System Register Setup -^^^^^^^^^^^^^^^^^^^^^ - -System registers that influence software execution in S-EL0 are setup by the SPM -as follows: - -1. ``SCTLR_EL1`` - - - ``UCI=1`` - - ``EOE=0`` - - ``WXN=1`` - - ``nTWE=1`` - - ``nTWI=1`` - - ``UCT=1`` - - ``DZE=1`` - - ``I=1`` - - ``UMA=0`` - - ``SA0=1`` - - ``C=1`` - - ``A=1`` - - ``M=1`` - -2. ``CPACR_EL1`` - - - ``FPEN=b'11`` - -3. ``PSTATE`` - - - ``D,A,I,F=1`` - - ``CurrentEL=0`` (EL0) - - ``SpSel=0`` (Thread mode) - - ``NRW=0`` (AArch64) - -General Purpose Register Setup -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -SPM will invoke the entry point of a service by executing an ERET instruction. -This transition into S-EL0 is special since it is not in response to a previous -request through a SVC instruction. This is the first entry into S-EL0. The -general purpose register usage at the time of entry will be as specified in the -"Return State" column of Table 3-1 in Section 3.1 "Register use in AArch64 SMC -calls" of the `SMC Calling Convention`_ (*Arm DEN 0028B*) specification. In -addition, certain other restrictions will be applied as described below. - -1. ``SP_EL0`` - - A non-zero value will indicate that the SPM has initialised the stack pointer - for the current CPU. - - The value will be 0 otherwise. - -2. ``X4-X30`` - - The values of these registers will be 0. - -3. ``X0-X3`` - - Parameters passed by the SPM. - - - ``X0``: Virtual address of a buffer shared between EL3 and S-EL0. The - buffer will be mapped in the Secure EL1&0 translation regime with read-only - memory attributes described earlier. - - - ``X1``: Size of the buffer in bytes. - - - ``X2``: Cookie value (*IMPLEMENTATION DEFINED*). - - - ``X3``: Cookie value (*IMPLEMENTATION DEFINED*). - -Runtime Event Delegation ------------------------- - -The SPM receives requests for Secure Partition services through a synchronous -invocation (i.e. a SMC from the Non-secure world). These requests are delegated -to the partition by programming a return from the last -``MM_SP_EVENT_COMPLETE_AARCH64`` call received from the partition. The last call -was made to signal either completion of Secure Partition initialisation or -completion of a partition service request. - -``MM_SP_EVENT_COMPLETE_AARCH64`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- Description - - Signal completion of the last SP service request. - -- Parameters - - - **uint32** - Function ID - - - SVC64 Version: **0xC4000061** - - - **int32** - Event Status Code - - Zero or a positive value indicates that the event was handled successfully. - The values depend upon the original event that was delegated to the Secure - partition. They are described as follows. - - - ``SUCCESS`` : Used to indicate that the Secure Partition was initialised - or a runtime request was handled successfully. - - - Any other value greater than 0 is used to pass a specific Event Status - code in response to a runtime event. - - A negative value indicates an error. The values of Event Status code depend - on the original event. - -- Return parameters - - - **int32** - Event ID/Return Code - - Zero or a positive value specifies the unique ID of the event being - delegated to the partition by the SPM. - - In the current implementation, this parameter contains the function ID of - the ``MM_COMMUNICATE`` SMC. This value indicates to the partition that an - event has been delegated to it in response to an ``MM_COMMUNICATE`` request - from the Non-secure world. - - A negative value indicates an error. The format of the value is as follows: - - - ``NOT_SUPPORTED``: Function was called from the Non-secure world. - - See `Error Codes`_ for integer values that are associated with each return - code. - - - **uint32** - Event Context Address - - Address of a buffer shared between the SPM and Secure Partition to pass - event specific information. The format of the data populated in the buffer - is implementation defined. - - The buffer is mapped in the Secure EL1&0 translation regime with read-only - memory attributes described earlier. - - For the SVC64 version, this parameter is a 64-bit Virtual Address (VA). - - For the SVC32 version, this parameter is a 32-bit Virtual Address (VA). - - - **uint32** - Event context size - - Size of the memory starting at Event Address. - - - **uint32/uint64** - Event Cookie - - This is an optional parameter. If unused its value is SBZ. - -- Usage - - This function signals to the SPM that the handling of the last event delegated - to a partition has completed. The partition is ready to handle its next event. - A return from this function is in response to the next event that will be - delegated to the partition. The return parameters describe the next event. - -- Caller responsibilities - - A Secure Partition must only call ``MM_SP_EVENT_COMPLETE_AARCH64`` to signal - completion of a request that was delegated to it by the SPM. - -- Callee responsibilities - - When the SPM receives this call from a Secure Partition, the corresponding - syndrome information can be used to return control through an ERET - instruction, to the instruction immediately after the call in the Secure - Partition context. This syndrome information comprises of general purpose and - system register values when the call was made. - - The SPM must save this syndrome information and use it to delegate the next - event to the Secure Partition. The return parameters of this interface must - specify the properties of the event and be populated in ``X0-X3/W0-W3`` - registers. - -Secure Partition Memory Management ----------------------------------- - -A Secure Partition executes at S-EL0, which is an unprivileged Exception Level. -The SPM is responsible for enabling access to regions of memory in the system -address map from a Secure Partition. This is done by mapping these regions in -the Secure EL1&0 Translation regime with appropriate memory attributes. -Attributes refer to memory type, permission, cacheability and shareability -attributes used in the Translation tables. The definitions of these attributes -and their usage can be found in the `Armv8-A ARM`_ (*Arm DDI 0487*). - -All memory required by the Secure Partition is allocated upfront in the SPM, -even before handing over to the Secure Partition for the first time. The initial -access permissions of the memory regions are statically provided by the platform -port and should allow the Secure Partition to run its initialisation code. - -However, they might not suit the final needs of the Secure Partition because its -final memory layout might not be known until the Secure Partition initialises -itself. As the Secure Partition initialises its runtime environment it might, -for example, load dynamically some modules. For instance, a Secure Partition -could implement a loader for a standard executable file format (e.g. an PE-COFF -loader for loading executable files at runtime). These executable files will be -a part of the Secure Partition image. The location of various sections in an -executable file and their permission attributes (e.g. read-write data, read-only -data and code) will be known only when the file is loaded into memory. - -In this case, the Secure Partition needs a way to change the access permissions -of its memory regions. The SPM provides this feature through the -``MM_SP_MEMORY_ATTRIBUTES_SET_AARCH64`` SVC interface. This interface is -available to the Secure Partition during a specific time window: from the first -entry into the Secure Partition up to the first ``SP_EVENT_COMPLETE`` call that -signals the Secure Partition has finished its initialisation. Once the -initialisation is complete, the SPM does not allow changes to the memory -attributes. - -This section describes the standard SVC interface that is implemented by the SPM -to determine and change permission attributes of memory regions that belong to a -Secure Partition. - -``MM_SP_MEMORY_ATTRIBUTES_GET_AARCH64`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- Description - - Request the permission attributes of a memory region from S-EL0. - -- Parameters - - - **uint32** Function ID - - - SVC64 Version: **0xC4000064** - - - **uint64** Base Address - - This parameter is a 64-bit Virtual Address (VA). - - There are no alignment restrictions on the Base Address. The permission - attributes of the translation granule it lies in are returned. - -- Return parameters - - - **int32** - Memory Attributes/Return Code - - On success the format of the Return Code is as follows: - - - Bits[1:0] : Data access permission - - - b'00 : No access - - b'01 : Read-Write access - - b'10 : Reserved - - b'11 : Read-only access - - - Bit[2]: Instruction access permission - - - b'0 : Executable - - b'1 : Non-executable - - - Bit[30:3] : Reserved. SBZ. - - - Bit[31] : Must be 0 - - On failure the following error codes are returned: - - - ``INVALID_PARAMETERS``: The Secure Partition is not allowed to access the - memory region the Base Address lies in. - - - ``NOT_SUPPORTED`` : The SPM does not support retrieval of attributes of - any memory page that is accessible by the Secure Partition, or the - function was called from the Non-secure world. Also returned if it is - used after ``MM_SP_EVENT_COMPLETE_AARCH64``. - - See `Error Codes`_ for integer values that are associated with each return - code. - -- Usage - - This function is used to request the permission attributes for S-EL0 on a - memory region accessible from a Secure Partition. The size of the memory - region is equal to the Translation Granule size used in the Secure EL1&0 - translation regime. Requests to retrieve other memory region attributes are - not currently supported. - -- Caller responsibilities - - The caller must obtain the Translation Granule Size of the Secure EL1&0 - translation regime from the SPM through an implementation defined method. - -- Callee responsibilities - - The SPM must not return the memory access controls for a page of memory that - is not accessible from a Secure Partition. - -``MM_SP_MEMORY_ATTRIBUTES_SET_AARCH64`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- Description - - Set the permission attributes of a memory region from S-EL0. - -- Parameters - - - **uint32** - Function ID - - - SVC64 Version: **0xC4000065** - - - **uint64** - Base Address - - This parameter is a 64-bit Virtual Address (VA). - - The alignment of the Base Address must be greater than or equal to the size - of the Translation Granule Size used in the Secure EL1&0 translation - regime. - - - **uint32** - Page count - - Number of pages starting from the Base Address whose memory attributes - should be changed. The page size is equal to the Translation Granule Size. - - - **uint32** - Memory Access Controls - - - Bits[1:0] : Data access permission - - - b'00 : No access - - b'01 : Read-Write access - - b'10 : Reserved - - b'11 : Read-only access - - - Bit[2] : Instruction access permission - - - b'0 : Executable - - b'1 : Non-executable - - - Bits[31:3] : Reserved. SBZ. - - A combination of attributes that mark the region with RW and Executable - permissions is prohibited. A request to mark a device memory region with - Executable permissions is prohibited. - -- Return parameters - - - **int32** - Return Code - - - ``SUCCESS``: The Memory Access Controls were changed successfully. - - - ``DENIED``: The SPM is servicing a request to change the attributes of a - memory region that overlaps with the region specified in this request. - - - ``INVALID_PARAMETER``: An invalid combination of Memory Access Controls - has been specified. The Base Address is not correctly aligned. The Secure - Partition is not allowed to access part or all of the memory region - specified in the call. - - - ``NO_MEMORY``: The SPM does not have memory resources to change the - attributes of the memory region in the translation tables. - - - ``NOT_SUPPORTED``: The SPM does not permit change of attributes of any - memory region that is accessible by the Secure Partition. Function was - called from the Non-secure world. Also returned if it is used after - ``MM_SP_EVENT_COMPLETE_AARCH64``. - - See `Error Codes`_ for integer values that are associated with each return - code. - -- Usage - - This function is used to change the permission attributes for S-EL0 on a - memory region accessible from a Secure Partition. The size of the memory - region is equal to the Translation Granule size used in the Secure EL1&0 - translation regime. Requests to change other memory region attributes are not - currently supported. - - This function is only available at boot time. This interface is revoked after - the Secure Partition sends the first ``MM_SP_EVENT_COMPLETE_AARCH64`` to - signal that it is initialised and ready to receive run-time requests. - -- Caller responsibilities - - The caller must obtain the Translation Granule Size of the Secure EL1&0 - translation regime from the SPM through an implementation defined method. - -- Callee responsibilities - - The SPM must preserve the original memory access controls of the region of - memory in case of an unsuccessful call.  The SPM must preserve the consistency - of the S-EL1 translation regime if this function is called on different PEs - concurrently and the memory regions specified overlap. - -Error Codes ------------ - -.. csv-table:: - :header: "Name", "Value" - - ``SUCCESS``,0 - ``NOT_SUPPORTED``,-1 - ``INVALID_PARAMETER``,-2 - ``DENIED``,-3 - ``NO_MEMORY``,-5 - ``NOT_PRESENT``,-7 - --------------- - -*Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.* - -.. _Armv8-A ARM: https://developer.arm.com/docs/ddi0487/latest/arm-architecture-reference-manual-armv8-for-armv8-a-architecture-profile -.. _instructions in the EDK2 repository: https://github.com/tianocore/edk2-staging/blob/AArch64StandaloneMm/HowtoBuild.MD -.. _Management Mode Interface Specification: http://infocenter.arm.com/help/topic/com.arm.doc.den0060a/DEN0060A_ARM_MM_Interface_Specification.pdf -.. _SDEI Specification: http://infocenter.arm.com/help/topic/com.arm.doc.den0054a/ARM_DEN0054A_Software_Delegated_Exception_Interface.pdf -.. _SMC Calling Convention: https://developer.arm.com/docs/den0028/latest - -.. |Image 1| image:: ../resources/diagrams/secure_sw_stack_tos.png -.. |Image 2| image:: ../resources/diagrams/secure_sw_stack_sp.png diff --git a/docs/components/secure-partition-manager-mm.rst b/docs/components/secure-partition-manager-mm.rst new file mode 100644 index 000000000..87fc91df3 --- /dev/null +++ b/docs/components/secure-partition-manager-mm.rst @@ -0,0 +1,836 @@ +Secure Partition Manager (MM) +***************************** + +Foreword +======== + +Two implementations of a Secure Partition Manager co-exist in the TF-A codebase: + +- SPM based on the PSA FF-A specification (`Secure Partition Manager`__). +- SPM based on the MM interface. + +.. __: secure-partition-manager.html + +Both implementations differ in their architectures and only one can be selected +at build time. + +This document describes the latter implementation where the Secure Partition Manager +resides at EL3 and management services run from isolated Secure Partitions at S-EL0. +The communication protocol is established through the Management Mode (MM) interface. + +Background +========== + +In some market segments that primarily deal with client-side devices like mobile +phones, tablets, STBs and embedded devices, a Trusted OS instantiates trusted +applications to provide security services like DRM, secure payment and +authentication. The Global Platform TEE Client API specification defines the API +used by Non-secure world applications to access these services. A Trusted OS +fulfils the requirements of a security service as described above. + +Management services are typically implemented at the highest level of privilege +in the system, i.e. EL3 in Trusted Firmware-A (TF-A). The service requirements are +fulfilled by the execution environment provided by TF-A. + +The following diagram illustrates the corresponding software stack: + +|Image 1| + +In other market segments that primarily deal with server-side devices (e.g. data +centres and enterprise servers) the secure software stack typically does not +include a Global Platform Trusted OS. Security functions are accessed through +other interfaces (e.g. ACPI TCG TPM interface, UEFI runtime variable service). + +Placement of management and security functions with diverse requirements in a +privileged Exception Level (i.e. EL3 or S-EL1) makes security auditing of +firmware more difficult and does not allow isolation of unrelated services from +each other either. + +Introduction +============ + +A **Secure Partition** is a software execution environment instantiated in +S-EL0 that can be used to implement simple management and security services. +Since S-EL0 is an unprivileged Exception Level, a Secure Partition relies on +privileged firmware (i.e. TF-A) to be granted access to system and processor +resources. Essentially, it is a software sandbox in the Secure world that runs +under the control of privileged software, provides one or more services and +accesses the following system resources: + +- Memory and device regions in the system address map. + +- PE system registers. + +- A range of synchronous exceptions (e.g. SMC function identifiers). + +Note that currently TF-A only supports handling one Secure Partition. + +A Secure Partition enables TF-A to implement only the essential secure +services in EL3 and instantiate the rest in a partition in S-EL0. +Furthermore, multiple Secure Partitions can be used to isolate unrelated +services from each other. + +The following diagram illustrates the place of a Secure Partition in a typical +Armv8-A software stack. A single or multiple Secure Partitions provide secure +services to software components in the Non-secure world and other Secure +Partitions. + +|Image 2| + +The TF-A build system is responsible for including the Secure Partition image +in the FIP. During boot, BL2 includes support to authenticate and load the +Secure Partition image. A BL31 component called **Secure Partition Manager +(SPM)** is responsible for managing the partition. This is semantically +similar to a hypervisor managing a virtual machine. + +The SPM is responsible for the following actions during boot: + +- Allocate resources requested by the Secure Partition. + +- Perform architectural and system setup required by the Secure Partition to + fulfil a service request. + +- Implement a standard interface that is used for initialising a Secure + Partition. + +The SPM is responsible for the following actions during runtime: + +- Implement a standard interface that is used by a Secure Partition to fulfil + service requests. + +- Implement a standard interface that is used by the Non-secure world for + accessing the services exported by a Secure Partition. A service can be + invoked through a SMC. + +Alternatively, a partition can be viewed as a thread of execution running under +the control of the SPM. Hence common programming concepts described below are +applicable to a partition. + +Description +=========== + +The previous section introduced some general aspects of the software +architecture of a Secure Partition. This section describes the specific choices +made in the current implementation of this software architecture. Subsequent +revisions of the implementation will include a richer set of features that +enable a more flexible architecture. + +Building TF-A with Secure Partition support +------------------------------------------- + +SPM is supported on the Arm FVP exclusively at the moment. The current +implementation supports inclusion of only a single Secure Partition in which a +service always runs to completion (e.g. the requested services cannot be +preempted to give control back to the Normal world). + +It is not currently possible for BL31 to integrate SPM support and a Secure +Payload Dispatcher (SPD) at the same time; they are mutually exclusive. In the +SPM bootflow, a Secure Partition image executing at S-EL0 replaces the Secure +Payload image executing at S-EL1 (e.g. a Trusted OS). Both are referred to as +BL32. + +A working prototype of a SP has been implemented by re-purposing the EDK2 code +and tools, leveraging the concept of the *Standalone Management Mode (MM)* in +the UEFI specification (see the PI v1.6 Volume 4: Management Mode Core +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 +location of the binary that contains the BL32 image +(``BL32=path/to/image.bin``) must be specified. + +First, build the Standalone MM Secure Partition. To build it, refer to the +`instructions in the EDK2 repository`_. + +Then build TF-A with SPM support and include the Standalone MM Secure Partition +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 + +Describing Secure Partition resources +------------------------------------- + +TF-A exports a porting interface that enables a platform to specify the system +resources required by the Secure Partition. Some instructions are given below. +However, this interface is under development and it may change as new features +are implemented. + +- A Secure Partition is considered a BL32 image, so the same defines that apply + to BL32 images apply to a Secure Partition: ``BL32_BASE`` and ``BL32_LIMIT``. + +- The following defines are needed to allocate space for the translation tables + used by the Secure Partition: ``PLAT_SP_IMAGE_MMAP_REGIONS`` and + ``PLAT_SP_IMAGE_MAX_XLAT_TABLES``. + +- The functions ``plat_get_secure_partition_mmap()`` and + ``plat_get_secure_partition_boot_info()`` have to be implemented. The file + ``plat/arm/board/fvp/fvp_common.c`` can be used as an example. It uses the + defines in ``include/plat/arm/common/arm_spm_def.h``. + + - ``plat_get_secure_partition_mmap()`` returns an array of mmap regions that + describe the memory regions that the SPM needs to allocate for a Secure + Partition. + + - ``plat_get_secure_partition_boot_info()`` returns a + ``spm_mm_boot_info_t`` struct that is populated by the platform + with information about the memory map of the Secure Partition. + +For an example of all the changes in context, you may refer to commit +``e29efeb1b4``, in which the port for FVP was introduced. + +Accessing Secure Partition services +----------------------------------- + +The `SMC Calling Convention`_ (*Arm DEN 0028B*) describes SMCs as a conduit for +accessing services implemented in the Secure world. The ``MM_COMMUNICATE`` +interface defined in the `Management Mode Interface Specification`_ (*Arm DEN +0060A*) is used to invoke a Secure Partition service as a Fast Call. + +The mechanism used to identify a service within the partition depends on the +service implementation. It is assumed that the caller of the service will be +able to discover this mechanism through standard platform discovery mechanisms +like ACPI and Device Trees. For example, *Volume 4: Platform Initialisation +Specification v1.6. Management Mode Core Interface* specifies that a GUID is +used to identify a management mode service. A client populates the GUID in the +``EFI_MM_COMMUNICATE_HEADER``. The header is populated in the communication +buffer shared with the Secure Partition. + +A Fast Call appears to be atomic from the perspective of the caller and returns +when the requested operation has completed. A service invoked through the +``MM_COMMUNICATE`` SMC will run to completion in the partition on a given CPU. +The SPM is responsible for guaranteeing this behaviour. This means that there +can only be a single outstanding Fast Call in a partition on a given CPU. + +Exchanging data with the Secure Partition +----------------------------------------- + +The exchange of data between the Non-secure world and the partition takes place +through a shared memory region. The location of data in the shared memory area +is passed as a parameter to the ``MM_COMMUNICATE`` SMC. The shared memory area +is statically allocated by the SPM and is expected to be either implicitly known +to the Non-secure world or discovered through a platform discovery mechanism +e.g. ACPI table or device tree. It is possible for the Non-secure world to +exchange data with a partition only if it has been populated in this shared +memory area. The shared memory area is implemented as per the guidelines +specified in Section 3.2.3 of the `Management Mode Interface Specification`_ +(*Arm DEN 0060A*). + +The format of data structures used to encapsulate data in the shared memory is +agreed between the Non-secure world and the Secure Partition. For example, in +the `Management Mode Interface specification`_ (*Arm DEN 0060A*), Section 4 +describes that the communication buffer shared between the Non-secure world and +the Management Mode (MM) in the Secure world must be of the type +``EFI_MM_COMMUNICATE_HEADER``. This data structure is defined in *Volume 4: +Platform Initialisation Specification v1.6. Management Mode Core Interface*. +Any caller of a MM service will have to use the ``EFI_MM_COMMUNICATE_HEADER`` +data structure. + +Runtime model of the Secure Partition +===================================== + +This section describes how the Secure Partition interfaces with the SPM. + +Interface with SPM +------------------ + +In order to instantiate one or more secure services in the Secure Partition in +S-EL0, the SPM should define the following types of interfaces: + +- Interfaces that enable access to privileged operations from S-EL0. These + operations typically require access to system resources that are either shared + amongst multiple software components in the Secure world or cannot be directly + accessed from an unprivileged Exception Level. + +- Interfaces that establish the control path between the SPM and the Secure + Partition. + +This section describes the APIs currently exported by the SPM that enable a +Secure Partition to initialise itself and export its services in S-EL0. These +interfaces are not accessible from the Non-secure world. + +Conduit +^^^^^^^ + +The `SMC Calling Convention`_ (*Arm DEN 0028B*) specification describes the SMC +and HVC conduits for accessing firmware services and their availability +depending on the implemented Exception levels. In S-EL0, the Supervisor Call +exception (SVC) is the only architectural mechanism available for unprivileged +software to make a request for an operation implemented in privileged software. +Hence, the SVC conduit must be used by the Secure Partition to access interfaces +implemented by the SPM. + +A SVC causes an exception to be taken to S-EL1. TF-A assumes ownership of S-EL1 +and installs a simple exception vector table in S-EL1 that relays a SVC request +from a Secure Partition as a SMC request to the SPM in EL3. Upon servicing the +SMC request, Trusted Firmware-A returns control directly to S-EL0 through an +ERET instruction. + +Calling conventions +^^^^^^^^^^^^^^^^^^^ + +The `SMC Calling Convention`_ (*Arm DEN 0028B*) specification describes the +32-bit and 64-bit calling conventions for the SMC and HVC conduits. The SVC +conduit introduces the concept of SVC32 and SVC64 calling conventions. The SVC32 +and SVC64 calling conventions are equivalent to the 32-bit (SMC32) and the +64-bit (SMC64) calling conventions respectively. + +Communication initiated by SPM +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +A service request is initiated from the SPM through an exception return +instruction (ERET) to S-EL0. Later, the Secure Partition issues an SVC +instruction to signal completion of the request. Some example use cases are +given below: + +- A request to initialise the Secure Partition during system boot. + +- A request to handle a runtime service request. + +Communication initiated by Secure Partition +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +A request is initiated from the Secure Partition by executing a SVC instruction. +An ERET instruction is used by TF-A to return to S-EL0 with the result of the +request. + +For instance, a request to perform privileged operations on behalf of a +partition (e.g. management of memory attributes in the translation tables for +the Secure EL1&0 translation regime). + +Interfaces +^^^^^^^^^^ + +The current implementation reserves function IDs for Fast Calls in the Standard +Secure Service calls range (see `SMC Calling Convention`_ (*Arm DEN 0028B*) +specification) for each API exported by the SPM. This section defines the +function prototypes for each function ID. The function IDs specify whether one +or both of the SVC32 and SVC64 calling conventions can be used to invoke the +corresponding interface. + +Secure Partition Event Management +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The Secure Partition provides an Event Management interface that is used by the +SPM to delegate service requests to the Secure Partition. The interface also +allows the Secure Partition to: + +- Register with the SPM a service that it provides. +- Indicate completion of a service request delegated by the SPM + +Miscellaneous interfaces +------------------------ + +``SPM_MM_VERSION_AARCH32`` +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Description + + Returns the version of the interface exported by SPM. + +- Parameters + + - **uint32** - Function ID + + - SVC32 Version: **0x84000060** + +- Return parameters + + - **int32** - Status + + On success, the format of the value is as follows: + + - Bit [31]: Must be 0 + - Bits [30:16]: Major Version. Must be 0 for this revision of the SPM + interface. + - Bits [15:0]: Minor Version. Must be 1 for this revision of the SPM + interface. + + On error, the format of the value is as follows: + + - ``NOT_SUPPORTED``: SPM interface is not supported or not available for the + client. + +- Usage + + This function returns the version of the Secure Partition Manager + implementation. The major version is 0 and the minor version is 1. The version + number is a 31-bit unsigned integer, with the upper 15 bits denoting the major + revision, and the lower 16 bits denoting the minor revision. The following + rules apply to the version numbering: + + - Different major revision values indicate possibly incompatible functions. + + - For two revisions, A and B, for which the major revision values are + identical, if the minor revision value of revision B is greater than the + minor revision value of revision A, then every function in revision A must + work in a compatible way with revision B. However, it is possible for + revision B to have a higher function count than revision A. + +- Implementation responsibilities + + If this function returns a valid version number, all the functions that are + described subsequently must be implemented, unless it is explicitly stated + that a function is optional. + +See `Error Codes`_ for integer values that are associated with each return +code. + +Secure Partition Initialisation +------------------------------- + +The SPM is responsible for initialising the architectural execution context to +enable initialisation of a service in S-EL0. The responsibilities of the SPM are +listed below. At the end of initialisation, the partition issues a +``MM_SP_EVENT_COMPLETE_AARCH64`` call (described later) to signal readiness for +handling requests for services implemented by the Secure Partition. The +initialisation event is executed as a Fast Call. + +Entry point invocation +^^^^^^^^^^^^^^^^^^^^^^ + +The entry point for service requests that should be handled as Fast Calls is +used as the target of the ERET instruction to start initialisation of the Secure +Partition. + +Architectural Setup +^^^^^^^^^^^^^^^^^^^ + +At cold boot, system registers accessible from S-EL0 will be in their reset +state unless otherwise specified. The SPM will perform the following +architectural setup to enable execution in S-EL0 + +MMU setup +^^^^^^^^^ + +The platform port of a Secure Partition specifies to the SPM a list of regions +that it needs access to and their attributes. The SPM validates this resource +description and initialises the Secure EL1&0 translation regime as follows. + +1. Device regions are mapped with nGnRE attributes and Execute Never + instruction access permissions. + +2. Code memory regions are mapped with RO data and Executable instruction access + permissions. + +3. Read Only data memory regions are mapped with RO data and Execute Never + instruction access permissions. + +4. Read Write data memory regions are mapped with RW data and Execute Never + instruction access permissions. + +5. If the resource description does not explicitly describe the type of memory + regions then all memory regions will be marked with Code memory region + attributes. + +6. The ``UXN`` and ``PXN`` bits are set for regions that are not executable by + S-EL0 or S-EL1. + +System Register Setup +^^^^^^^^^^^^^^^^^^^^^ + +System registers that influence software execution in S-EL0 are setup by the SPM +as follows: + +1. ``SCTLR_EL1`` + + - ``UCI=1`` + - ``EOE=0`` + - ``WXN=1`` + - ``nTWE=1`` + - ``nTWI=1`` + - ``UCT=1`` + - ``DZE=1`` + - ``I=1`` + - ``UMA=0`` + - ``SA0=1`` + - ``C=1`` + - ``A=1`` + - ``M=1`` + +2. ``CPACR_EL1`` + + - ``FPEN=b'11`` + +3. ``PSTATE`` + + - ``D,A,I,F=1`` + - ``CurrentEL=0`` (EL0) + - ``SpSel=0`` (Thread mode) + - ``NRW=0`` (AArch64) + +General Purpose Register Setup +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +SPM will invoke the entry point of a service by executing an ERET instruction. +This transition into S-EL0 is special since it is not in response to a previous +request through a SVC instruction. This is the first entry into S-EL0. The +general purpose register usage at the time of entry will be as specified in the +"Return State" column of Table 3-1 in Section 3.1 "Register use in AArch64 SMC +calls" of the `SMC Calling Convention`_ (*Arm DEN 0028B*) specification. In +addition, certain other restrictions will be applied as described below. + +1. ``SP_EL0`` + + A non-zero value will indicate that the SPM has initialised the stack pointer + for the current CPU. + + The value will be 0 otherwise. + +2. ``X4-X30`` + + The values of these registers will be 0. + +3. ``X0-X3`` + + Parameters passed by the SPM. + + - ``X0``: Virtual address of a buffer shared between EL3 and S-EL0. The + buffer will be mapped in the Secure EL1&0 translation regime with read-only + memory attributes described earlier. + + - ``X1``: Size of the buffer in bytes. + + - ``X2``: Cookie value (*IMPLEMENTATION DEFINED*). + + - ``X3``: Cookie value (*IMPLEMENTATION DEFINED*). + +Runtime Event Delegation +------------------------ + +The SPM receives requests for Secure Partition services through a synchronous +invocation (i.e. a SMC from the Non-secure world). These requests are delegated +to the partition by programming a return from the last +``MM_SP_EVENT_COMPLETE_AARCH64`` call received from the partition. The last call +was made to signal either completion of Secure Partition initialisation or +completion of a partition service request. + +``MM_SP_EVENT_COMPLETE_AARCH64`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Description + + Signal completion of the last SP service request. + +- Parameters + + - **uint32** - Function ID + + - SVC64 Version: **0xC4000061** + + - **int32** - Event Status Code + + Zero or a positive value indicates that the event was handled successfully. + The values depend upon the original event that was delegated to the Secure + partition. They are described as follows. + + - ``SUCCESS`` : Used to indicate that the Secure Partition was initialised + or a runtime request was handled successfully. + + - Any other value greater than 0 is used to pass a specific Event Status + code in response to a runtime event. + + A negative value indicates an error. The values of Event Status code depend + on the original event. + +- Return parameters + + - **int32** - Event ID/Return Code + + Zero or a positive value specifies the unique ID of the event being + delegated to the partition by the SPM. + + In the current implementation, this parameter contains the function ID of + the ``MM_COMMUNICATE`` SMC. This value indicates to the partition that an + event has been delegated to it in response to an ``MM_COMMUNICATE`` request + from the Non-secure world. + + A negative value indicates an error. The format of the value is as follows: + + - ``NOT_SUPPORTED``: Function was called from the Non-secure world. + + See `Error Codes`_ for integer values that are associated with each return + code. + + - **uint32** - Event Context Address + + Address of a buffer shared between the SPM and Secure Partition to pass + event specific information. The format of the data populated in the buffer + is implementation defined. + + The buffer is mapped in the Secure EL1&0 translation regime with read-only + memory attributes described earlier. + + For the SVC64 version, this parameter is a 64-bit Virtual Address (VA). + + For the SVC32 version, this parameter is a 32-bit Virtual Address (VA). + + - **uint32** - Event context size + + Size of the memory starting at Event Address. + + - **uint32/uint64** - Event Cookie + + This is an optional parameter. If unused its value is SBZ. + +- Usage + + This function signals to the SPM that the handling of the last event delegated + to a partition has completed. The partition is ready to handle its next event. + A return from this function is in response to the next event that will be + delegated to the partition. The return parameters describe the next event. + +- Caller responsibilities + + A Secure Partition must only call ``MM_SP_EVENT_COMPLETE_AARCH64`` to signal + completion of a request that was delegated to it by the SPM. + +- Callee responsibilities + + When the SPM receives this call from a Secure Partition, the corresponding + syndrome information can be used to return control through an ERET + instruction, to the instruction immediately after the call in the Secure + Partition context. This syndrome information comprises of general purpose and + system register values when the call was made. + + The SPM must save this syndrome information and use it to delegate the next + event to the Secure Partition. The return parameters of this interface must + specify the properties of the event and be populated in ``X0-X3/W0-W3`` + registers. + +Secure Partition Memory Management +---------------------------------- + +A Secure Partition executes at S-EL0, which is an unprivileged Exception Level. +The SPM is responsible for enabling access to regions of memory in the system +address map from a Secure Partition. This is done by mapping these regions in +the Secure EL1&0 Translation regime with appropriate memory attributes. +Attributes refer to memory type, permission, cacheability and shareability +attributes used in the Translation tables. The definitions of these attributes +and their usage can be found in the `Armv8-A ARM`_ (*Arm DDI 0487*). + +All memory required by the Secure Partition is allocated upfront in the SPM, +even before handing over to the Secure Partition for the first time. The initial +access permissions of the memory regions are statically provided by the platform +port and should allow the Secure Partition to run its initialisation code. + +However, they might not suit the final needs of the Secure Partition because its +final memory layout might not be known until the Secure Partition initialises +itself. As the Secure Partition initialises its runtime environment it might, +for example, load dynamically some modules. For instance, a Secure Partition +could implement a loader for a standard executable file format (e.g. an PE-COFF +loader for loading executable files at runtime). These executable files will be +a part of the Secure Partition image. The location of various sections in an +executable file and their permission attributes (e.g. read-write data, read-only +data and code) will be known only when the file is loaded into memory. + +In this case, the Secure Partition needs a way to change the access permissions +of its memory regions. The SPM provides this feature through the +``MM_SP_MEMORY_ATTRIBUTES_SET_AARCH64`` SVC interface. This interface is +available to the Secure Partition during a specific time window: from the first +entry into the Secure Partition up to the first ``SP_EVENT_COMPLETE`` call that +signals the Secure Partition has finished its initialisation. Once the +initialisation is complete, the SPM does not allow changes to the memory +attributes. + +This section describes the standard SVC interface that is implemented by the SPM +to determine and change permission attributes of memory regions that belong to a +Secure Partition. + +``MM_SP_MEMORY_ATTRIBUTES_GET_AARCH64`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Description + + Request the permission attributes of a memory region from S-EL0. + +- Parameters + + - **uint32** Function ID + + - SVC64 Version: **0xC4000064** + + - **uint64** Base Address + + This parameter is a 64-bit Virtual Address (VA). + + There are no alignment restrictions on the Base Address. The permission + attributes of the translation granule it lies in are returned. + +- Return parameters + + - **int32** - Memory Attributes/Return Code + + On success the format of the Return Code is as follows: + + - Bits[1:0] : Data access permission + + - b'00 : No access + - b'01 : Read-Write access + - b'10 : Reserved + - b'11 : Read-only access + + - Bit[2]: Instruction access permission + + - b'0 : Executable + - b'1 : Non-executable + + - Bit[30:3] : Reserved. SBZ. + + - Bit[31] : Must be 0 + + On failure the following error codes are returned: + + - ``INVALID_PARAMETERS``: The Secure Partition is not allowed to access the + memory region the Base Address lies in. + + - ``NOT_SUPPORTED`` : The SPM does not support retrieval of attributes of + any memory page that is accessible by the Secure Partition, or the + function was called from the Non-secure world. Also returned if it is + used after ``MM_SP_EVENT_COMPLETE_AARCH64``. + + See `Error Codes`_ for integer values that are associated with each return + code. + +- Usage + + This function is used to request the permission attributes for S-EL0 on a + memory region accessible from a Secure Partition. The size of the memory + region is equal to the Translation Granule size used in the Secure EL1&0 + translation regime. Requests to retrieve other memory region attributes are + not currently supported. + +- Caller responsibilities + + The caller must obtain the Translation Granule Size of the Secure EL1&0 + translation regime from the SPM through an implementation defined method. + +- Callee responsibilities + + The SPM must not return the memory access controls for a page of memory that + is not accessible from a Secure Partition. + +``MM_SP_MEMORY_ATTRIBUTES_SET_AARCH64`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Description + + Set the permission attributes of a memory region from S-EL0. + +- Parameters + + - **uint32** - Function ID + + - SVC64 Version: **0xC4000065** + + - **uint64** - Base Address + + This parameter is a 64-bit Virtual Address (VA). + + The alignment of the Base Address must be greater than or equal to the size + of the Translation Granule Size used in the Secure EL1&0 translation + regime. + + - **uint32** - Page count + + Number of pages starting from the Base Address whose memory attributes + should be changed. The page size is equal to the Translation Granule Size. + + - **uint32** - Memory Access Controls + + - Bits[1:0] : Data access permission + + - b'00 : No access + - b'01 : Read-Write access + - b'10 : Reserved + - b'11 : Read-only access + + - Bit[2] : Instruction access permission + + - b'0 : Executable + - b'1 : Non-executable + + - Bits[31:3] : Reserved. SBZ. + + A combination of attributes that mark the region with RW and Executable + permissions is prohibited. A request to mark a device memory region with + Executable permissions is prohibited. + +- Return parameters + + - **int32** - Return Code + + - ``SUCCESS``: The Memory Access Controls were changed successfully. + + - ``DENIED``: The SPM is servicing a request to change the attributes of a + memory region that overlaps with the region specified in this request. + + - ``INVALID_PARAMETER``: An invalid combination of Memory Access Controls + has been specified. The Base Address is not correctly aligned. The Secure + Partition is not allowed to access part or all of the memory region + specified in the call. + + - ``NO_MEMORY``: The SPM does not have memory resources to change the + attributes of the memory region in the translation tables. + + - ``NOT_SUPPORTED``: The SPM does not permit change of attributes of any + memory region that is accessible by the Secure Partition. Function was + called from the Non-secure world. Also returned if it is used after + ``MM_SP_EVENT_COMPLETE_AARCH64``. + + See `Error Codes`_ for integer values that are associated with each return + code. + +- Usage + + This function is used to change the permission attributes for S-EL0 on a + memory region accessible from a Secure Partition. The size of the memory + region is equal to the Translation Granule size used in the Secure EL1&0 + translation regime. Requests to change other memory region attributes are not + currently supported. + + This function is only available at boot time. This interface is revoked after + the Secure Partition sends the first ``MM_SP_EVENT_COMPLETE_AARCH64`` to + signal that it is initialised and ready to receive run-time requests. + +- Caller responsibilities + + The caller must obtain the Translation Granule Size of the Secure EL1&0 + translation regime from the SPM through an implementation defined method. + +- Callee responsibilities + + The SPM must preserve the original memory access controls of the region of + memory in case of an unsuccessful call.  The SPM must preserve the consistency + of the S-EL1 translation regime if this function is called on different PEs + concurrently and the memory regions specified overlap. + +Error Codes +----------- + +.. csv-table:: + :header: "Name", "Value" + + ``SUCCESS``,0 + ``NOT_SUPPORTED``,-1 + ``INVALID_PARAMETER``,-2 + ``DENIED``,-3 + ``NO_MEMORY``,-5 + ``NOT_PRESENT``,-7 + +-------------- + +*Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.* + +.. _Armv8-A ARM: https://developer.arm.com/docs/ddi0487/latest/arm-architecture-reference-manual-armv8-for-armv8-a-architecture-profile +.. _instructions in the EDK2 repository: https://github.com/tianocore/edk2-staging/blob/AArch64StandaloneMm/HowtoBuild.MD +.. _Management Mode Interface Specification: http://infocenter.arm.com/help/topic/com.arm.doc.den0060a/DEN0060A_ARM_MM_Interface_Specification.pdf +.. _SDEI Specification: http://infocenter.arm.com/help/topic/com.arm.doc.den0054a/ARM_DEN0054A_Software_Delegated_Exception_Interface.pdf +.. _SMC Calling Convention: https://developer.arm.com/docs/den0028/latest + +.. |Image 1| image:: ../resources/diagrams/secure_sw_stack_tos.png +.. |Image 2| image:: ../resources/diagrams/secure_sw_stack_sp.png diff --git a/docs/components/secure-partition-manager.rst b/docs/components/secure-partition-manager.rst new file mode 100644 index 000000000..2169f30a0 --- /dev/null +++ b/docs/components/secure-partition-manager.rst @@ -0,0 +1,867 @@ +Secure Partition Manager +************************ + +.. contents:: + +Acronyms +======== + ++--------+-----------------------------------+ +| DTB | Device Tree Blob | ++--------+-----------------------------------+ +| DTS | Device Tree Source | ++--------+-----------------------------------+ +| EC | Execution Context | ++--------+-----------------------------------+ +| FIP | Firmware Image Package | ++--------+-----------------------------------+ +| FF-A | Firmware Framework for A-class | ++--------+-----------------------------------+ +| IPA | Intermediate Physical Address | ++--------+-----------------------------------+ +| NWd | Normal World | ++--------+-----------------------------------+ +| ODM | Original Design Manufacturer | ++--------+-----------------------------------+ +| OEM | Original Equipment Manufacturer | ++--------+-----------------------------------+ +| PA | Physical Address | ++--------+-----------------------------------+ +| PE | Processing Element | ++--------+-----------------------------------+ +| PVM | Primary VM | ++--------+-----------------------------------+ +| PSA | Platform Security Architecture | ++--------+-----------------------------------+ +| SP | Secure Partition | ++--------+-----------------------------------+ +| 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 +======== + +Two implementations of a Secure Partition Manager co-exist in the TF-A codebase: + +- SPM based on the PSA FF-A specification `[1]`_. +- SPM based on the MM interface to communicate with an S-EL0 partition `[2]`_. + +Both implementations differ in their architectures and only one can be selected +at build time. + +This document: + +- describes the PSA FF-A implementation where the Secure Partition Manager + resides at EL3 and S-EL2 (or EL3 and S-EL1). +- is not an architecture specification and it might provide assumptions + on sections mandated as implementation-defined in the specification. +- covers the implications to TF-A used as a bootloader, and Hafnium + used as a reference code base for an S-EL2 secure firmware on + platforms implementing Armv8.4-SecEL2. + +Terminology +----------- + +- Hypervisor refers to the NS-EL2 component managing Virtual Machines (or + partitions) in the Normal World. +- SPMC refers to the S-EL2 component managing Virtual Machines (or Secure + Partitions) in the Secure World when Armv8.4-SecEL2 extension is implemented. +- Alternatively, SPMC can refer to an S-EL1 component, itself being a Secure + Partition and implementing the FF-A ABI on pre-Armv8.4 platforms. +- VM refers to a Normal World Virtual Machine managed by an Hypervisor. +- SP refers to a Secure World "Virtual Machine" managed by the SPMC component. + +Support for legacy platforms +---------------------------- + +In the implementation, the SPM is split into SPMD and SPMC components +(although not strictly mandated by the specification). SPMD is located +at EL3 and principally relays FF-A messages from NWd (Hypervisor or OS +kernel) to SPMC located either at S-EL1 or S-EL2. + +Hence TF-A must support both cases where SPMC is either located at: + +- S-EL1 supporting pre-Armv8.4 platforms. SPMD conveys FF-A protocol + from EL3 to S-EL1. +- S-EL2 supporting platforms implementing Armv8.4-SecEL2 extension. + SPMD conveys FF-A protocol from EL3 to S-EL2. + +The same SPMD component is used to support both configurations. The SPMC +execution level is a build time choice. + +Sample reference stack +====================== + +The following diagram illustrates a possible configuration with SPMD and SPMC, +one or multiple Secure Partitions, with or without an optional Hypervisor: + +.. image:: ../resources/diagrams/ff-a-spm-sel2.png + +TF-A build options +================== + +The following TF-A build options are provisioned: + +- **SPD=spmd**: this option selects the SPMD component to relay FF-A + protocol from NWd to SWd back and forth. It is not possible to + enable another Secure Payload Dispatcher when this option is chosen. +- **SPMD_SPM_AT_SEL2**: this option adjusts the SPMC execution + level to being S-EL1 or S-EL2. It defaults to enabled (value 1) when + SPD=spmd is chosen. +- **CTX_INCLUDE_EL2_REGS**: this option permits saving (resp. + restoring) the EL2 system register context before entering (resp. + after leaving) the SPMC. It is mandatory when ``SPMD_SPM_AT_SEL2`` is + enabled. The context save/restore routine and exhaustive list of + registers is visible at `[4] <#References>`__. +- **SP_LAYOUT_FILE**: this option provides a text description file + providing paths to SP binary images and DTS format manifests + (see `Specifying partition binary image and DT`_). It + is required when ``SPMD_SPM_AT_SEL2`` is enabled hence when multiple + secure partitions are to be loaded on behalf of SPMC. + ++------------------------------+----------------------+------------------+ +| | CTX_INCLUDE_EL2_REGS | SPMD_SPM_AT_SEL2 | ++------------------------------+----------------------+------------------+ +| SPMC at S-EL1 (e.g. OP-TEE) | 0 | 0 | ++------------------------------+----------------------+------------------+ +| SPMC at S-EL2 (e.g. Hafnium) | 1 | 1 (default when | +| | | SPD=spmd) | ++------------------------------+----------------------+------------------+ + +Other combinations of such build options either break the build or are not +supported. + +Note, the ``CTX_INCLUDE_EL2_REGS`` option provides the generic support for +barely saving/restoring EL2 registers from an Arm arch perspective. As such +it is decoupled from the ``SPD=spmd`` option. + +BL32 option is re-purposed to specify the SPMC image. It can specify either the +Hafnium binary path (built for the secure world) or the path to a TEE binary +implementing the FF-A protocol. + +BL33 option can specify either: + +- the TFTF binary or +- the Hafnium binary path (built for the normal world) if VMs were loaded by + TF-A beforehand or +- a minimal loader performing the loading of VMs and Hafnium. + +Sample TF-A build command line when SPMC is located at S-EL1 +(typically pre-Armv8.4): + +.. code:: shell + + make \ + CROSS_COMPILE=aarch64-none-elf- \ + SPD=spmd \ + SPMD_SPM_AT_SEL2=0 \ + BL32= \ + BL33= \ + PLAT=fvp \ + all fip + +Sample TF-A build command line for an Armv8.4-SecEL2 enabled system +where SPMC is located at S-EL2: + +.. code:: shell + + make \ + CROSS_COMPILE=aarch64-none-elf- \ + SPD=spmd \ + CTX_INCLUDE_EL2_REGS=1 \ + ARM_ARCH_MINOR=4 \ + BL32= + BL33= \ + SP_LAYOUT_FILE=sp_layout.json \ + PLAT=fvp \ + all fip + +Build options to enable secure boot: + +.. code:: shell + + make \ + CROSS_COMPILE=aarch64-none-elf- \ + SPD=spmd \ + CTX_INCLUDE_EL2_REGS=1 \ + ARM_ARCH_MINOR=4 \ + BL32= + BL33= \ + SP_LAYOUT_FILE=../tf-a-tests/build/fvp/debug/sp_layout.json \ + MBEDTLS_DIR= \ + TRUSTED_BOARD_BOOT=1 \ + COT=dualroot \ + ARM_ROTPK_LOCATION=devel_rsa \ + ROT_KEY=plat/arm/board/common/rotpk/arm_rotprivk_rsa.pem \ + GENERATE_COT=1 \ + PLAT=fvp \ + all fip + +Boot process +============ + +Loading Hafnium and Secure Partitions in the secure world +--------------------------------------------------------- + +The Hafnium implementation in normal world requires VMs to be loaded in +memory prior to booting. The mechanism upon which VMs are loaded and +exposed to Hafnium are either: + +- by supplying a ramdisk image where VM images are concatenated (1) +- or by providing VM load addresses within Hafnium manifest (2) + +TF-A is the bootlader for the Hafnium and SPs in the secure world. TF-A +does not provide tooling or libraries manipulating ramdisks as required +by (1). Thus BL2 loads SPs payloads independently. +SPs may be signed by different parties (SiP, OEM/ODM, TOS vendor, etc.). +Thus they are supplied as distinct “self-contained” signed entities within +the FIP flash image. The FIP image itself is not signed hence providing +ability to upgrade SPs in the field. + +Booting through TF-A +-------------------- + +SP manifests +~~~~~~~~~~~~ + +An SP manifest describes SP attributes as defined in `[1]`_ +section 3.1 (partition manifest at virtual FF-A instance) in DTS text format. It +is represented as a single file associated with the SP. A sample is +provided by `[5]`_. A binding document is provided by `[6]`_. + +Secure Partition packages +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Secure Partitions are bundled as independent package files consisting +of: + +- a header +- a DTB +- an image payload + +The header starts with a magic value and offset values to SP DTB and +image payload. Each SP package is loaded independently by BL2 loader +and verified for authenticity and integrity. + +The SP package identified by its UUID (matching FF-A uuid) is inserted +as a single entry into the FIP at end of the TF-A build flow as shown: + +.. code:: shell + + Trusted Boot Firmware BL2: offset=0x1F0, size=0x8AE1, cmdline="--tb-fw" + EL3 Runtime Firmware BL31: offset=0x8CD1, size=0x13000, cmdline="--soc-fw" + Secure Payload BL32 (Trusted OS): offset=0x1BCD1, size=0x15270, cmdline="--tos-fw" + Non-Trusted Firmware BL33: offset=0x30F41, size=0x92E0, cmdline="--nt-fw" + HW_CONFIG: offset=0x3A221, size=0x2348, cmdline="--hw-config" + TB_FW_CONFIG: offset=0x3C569, size=0x37A, cmdline="--tb-fw-config" + SOC_FW_CONFIG: offset=0x3C8E3, size=0x48, cmdline="--soc-fw-config" + TOS_FW_CONFIG: offset=0x3C92B, size=0x427, cmdline="--tos-fw-config" + NT_FW_CONFIG: offset=0x3CD52, size=0x48, cmdline="--nt-fw-config" + B4B5671E-4A90-4FE1-B81F-FB13DAE1DACB: offset=0x3CD9A, size=0xC168, cmdline="--blob" + D1582309-F023-47B9-827C-4464F5578FC8: offset=0x48F02, size=0xC168, cmdline="--blob" + +.. uml:: ../resources/diagrams/plantuml/fip-secure-partitions.puml + +Specifying partition binary image and DT +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A description file (json format) is passed to the build flow specifying +paths to the SP binary image and associated DTS partition manifest file. +The latter is going through the dtc compiler to generate the dtb fed into +the SP package. + +.. code:: shell + + { + "tee1" : { + "image": "tee1.bin", + "pm": "tee1.dts" + }, + + "tee2" : { + "image": "tee2.bin", + "pm": "tee2.dts" + } + } + +SPMC manifest +~~~~~~~~~~~~~ + +This manifest contains an SPMC attributes node consumed by SPMD at boot time. It +is implementing the description from `[1]`_ section 3.2 (SP manifest at physical +FF-A instance). The SP manifest at physical FF-A instance is used by the SPMD to +setup a SP that co-resides with the SPMC and executes at S-EL1 or Secure +Supervisor mode. + +In this implementation its usage is extended to the secure physical FF-A +instance where SPMC executes at S-EL2. + +.. code:: shell + + attribute { + spmc_id = <0x8000>; + maj_ver = <0x1>; + min_ver = <0x0>; + exec_state = <0x0>; + load_address = <0x0 0x6000000>; + entrypoint = <0x0 0x6000000>; + binary_size = <0x60000>; + }; + +- *spmc_id* defines the endpoint ID value that SPMC can query through + ``FFA_ID_GET``. +- *maj_ver/min_ver*. SPMD checks provided version versus its internal + version and aborts if not matching. +- *exec_state* defines SPMC execution state (can be AArch64 for + Hafnium, or AArch64/AArch32 for OP-TEE at S-EL1). +- *load_address* and *binary_size* are mostly used to verify secondary + entry points fit into the loaded binary image. +- *entrypoint* defines the cold boot primary core entry point used by + SPMD (currently matches ``BL32_BASE``) + +Other nodes in the manifest are consumed by Hafnium in the secure world. +A sample can be found at [7]: + +- The *chosen* node is currently unused in SWd. It is meant for NWd to + specify the init ramdisk image. +- The *hypervisor* node describes SPs. *is_ffa_partition* boolean + attribute indicates an SP. Load-addr field specifies the load address + at which TF-A loaded the SP package. +- *cpus* node provide the platform topology and allows MPIDR to VMPIDR + mapping. Notice with current implementation primary cpu is declared + first, then secondary cpus must be declared in reverse order. + +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. + +BL2 passes the SPMC manifest address to BL31 through a register. + +BL31(SPMD) runs from primary core, initializes the core contexts and +launches BL32 passing the SPMC manifest address through a register. + +Loading of SPs +~~~~~~~~~~~~~~ + +.. uml:: ../resources/diagrams/plantuml/bl2-loading-sp.puml + + +Notice this boot flow is an implementation sample on Arm's FVP platform. Platforms +not using FW_CONFIG would adjust to a different implementation. + +Secure boot +~~~~~~~~~~~ + +The SP content certificate is inserted as a separate FIP item so that BL2 loads SPMC, +SPMC manifest and Secure Partitions and verifies them for authenticity and integrity. +Refer to TBBR specification `[3]`_. + +The multiple-signing domain feature (in current state dual signing domain) allows +the use of two root keys namely S-ROTPK and NS-ROTPK (see `[8]`_): + +- SPMC(BL32), SPMC manifest, SPs may be signed by the SiP using the S-ROTPK. +- BL33 may be signed by the OEM using NS-ROTPK. + +Longer term multiple signing domain will allow additional signing keys, e.g. +if SPs originate from different parties. + +See `TF-A build options`_ for a sample build command line. + +Hafnium in the secure world +=========================== + +**NOTE: this section is work in progress. Descriptions and implementation choices +are subject to evolve.** + +General considerations +---------------------- + +Build platform for the secure world +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The implementation might add specific code parts only relevant to the +secure world. Such code parts might be isolated into different files +and/or conditional code enclosed by a ``SECURE_WORLD`` macro. + +Secure Partitions CPU scheduling +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In the normal world, VMs are scheduled by the FFA_RUN ABI invoked from the +primary scheduler (in the primary VM), or by a direct message request or +response. + +With the FF-A EAC specification, Secure Partitions are scheduled by direct +message invocations from a NWd VM or another SP. + +Platform topology +~~~~~~~~~~~~~~~~~ + +As stated in `[1]`_ section 4.4.1 the SPMC implementation assumes the +following SP types: + +- Pinned MP SPs: an Execution Context id matches a physical PE id. MP + SPs must implement the same number of ECs as the number of PEs in the + platform. Hence the *execution-ctx-count* as defined by + `[1]`_ (or NWd-Hafnium *vcpu_count*) can only take the + value of one or the number of physical PEs. +- Migratable UP SPs: a single execution context can run and be migrated + on any physical PE. It declares a single EC in its SP manifest. An UP + SP can receive a direct message request on any physical core. + +Usage of PSCI services in the secure world +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- The normal world Hypervisor (optional) or OS kernel issues PSCI service + invocations e.g. to request PSCI version, wake-up a secondary core, or request + core suspend. This happens at the non-secure physical FF-A instance. In the + example case of Hafnium in the normal world, it boots on the primary core and + one of the first initialization step is to request the PSCI version. It then + launches the primary VM. The primary VM upon initializing performs PSCI service + calls (at non-secure virtual FF-A instance) which are trapped by the + Hypervisor. Invocation from OS Kernel ends straight at EL3. The PVM issues + ``PSCI_CPU_ON`` service calls to wake-up secondary cores by passing an + ``MPIDR``, entry point address and a CPU context address. The EL3 PSCI layer + then performs an exception return to the secondary core entry point on the + targeted core. Other PSCI calls can happen at run-time from the PVM e.g. to + request core suspend. +- In the existing TF-A PSCI standard library, PSCI service calls are filtered at + EL3 to only originate from the NWd. Thus concerning the SPMC (at secure + physical FF-A instance) the PSCI service invocations cannot happen as in the + normal world. For example, a ``PSCI_CPU_ON`` service invocation from the SPMC + does not reach the PSCI layer. + +Parsing SP partition manifests +------------------------------ + +Hafnium must be able to consume SP manifests as defined in +`[1]`_ section 3.1, at least for the mandatory fields. + +The SP manifest may contain memory and device regions nodes. + +- Memory regions shall be mapped in the SP Stage-2 translation regime at + load time. A memory region node can specify RX/TX buffer regions in which + case it is not necessary for an SP to explicitly call the ``FFA_RXTX_MAP`` + service. +- Device regions shall be mapped in SP Stage-2 translation regime as + peripherals and possibly allocate additional resources (e.g. interrupts) + +Base addresses for memory and device region nodes are IPAs provided SPMC +identity maps IPAs to PAs within SP Stage-2 translation regime. + +Note: currently both VTTBR_EL2 and VSTTBR_EL2 resolve to the same set of page +tables. It is still open whether two sets of page tables shall be provided per +SP. The memory region node as defined in the spec (section 3.1 Table 10) +provides a memory security attribute hinting to map either to the secure or +non-secure stage-2 table. + +Passing boot data to the SP +--------------------------- + +`[1]`_ Section 3.4.2 “Protocol for passing data” defines a +method to passing boot data to SPs (not currently implemented). + +Provided that the whole Secure Partition package image (see `Secure +Partition packages`_) is mapped to the SP's secure Stage-2 translation +regime, an SP can access its own manifest DTB blob and extract its partition +manifest properties. + +SP Boot order +------------- + +SP manifests provide an optional boot order attribute meant to resolve +dependencies such as an SP providing a service required to properly boot +another SP. + +Boot phases +----------- + +Primary core boot-up +~~~~~~~~~~~~~~~~~~~~ + +The SPMC performs its platform initializations then loads and creates +secure partitions based on SP packages and manifests. Then each secure +partition is launched in sequence (see `SP Boot order`_) on their primary +Execution Context. + +Notice the primary physical core may not be core 0. Hence if the primary +core linear id is N, the 1:1 mapping requires MP SPs are launched using +EC[N] on PE[N] (see `Platform topology`_). + +The SP's primary Execution Context (or the EC used when the partition is booted) +exits through ``FFA_MSG_WAIT`` to indicate successful initialization. + +Secondary physical core boot-up +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Upon boot-up, the SPMC running on the primary core performs +implementation-defined SPMD service calls at secure physical FF-A instance +to register the secondary physical cores entry points and context information: + +- This is done through a direct message request invocation to the SPMD + (``SET_ENTRY_POINT``). This service call does not wake-up the targeted + core immediately. The secondary core is woken up later by a NWd + ``PSCI_CPU_ON`` service invocation. A notification is passed from EL3 + PSCI layer to the SPMD, and then to SPMC through an implementation-defined + interface. +- The SPMC/SPMD interface can consist of FF-A direct message requests/responses + transporting PM events. + +If there is no Hypervisor in the normal world, the OS Kernel issues +``PSCI_CPU_ON`` calls that are directly trapped to EL3. + +When a secondary physical core wakes-up the SPMD notifies the SPMC which updates +its internal states reflecting current physical core is being turned on. +It might then return straight to the SPMD and then to the NWd. + +*(under discussion)* There may be possibility that an SP registers "PM events" +(during primary EC boot stage) through an ad-hoc interface. Such events would +be relayed by SPMC to one or more registered SPs on need basis +(see `Power management`_). + +Secondary virtual core boot-up +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In the example case where Hafnium exists in the normal world, secondary VMs +issue a ``PSCI_CPU_ON`` service call which is trapped to the Hypervisor. The +latter then enables the vCPU context for the targeted core, and switches to +the PVM down to the kernel driver with an ``HF_WAKE_UP`` message. The NWd +driver in PVM can then schedule the newly woken up vCPU context. + +In the secure world the primary EC of a given SP passes the secondary EC entry +point and context. The SMC service call is trapped into the SPMC. This can be +either *(under discussion)*: + +- a specific interface registering the secondary EC entry point, + similarly to above ``SET_ENTRY_POINT`` service. +- Re-purposing the ``PSCI_CPU_ON`` function id. It is + assumed that even if the input arguments are the same as the ones defined in + the PSCI standard, the usage deviates by the fact the secondary EC is not + woken up immediately. At least for the PSA-FF-A EAC where only + direct messaging is allowed, it is only after the first direct + message invocation that the secondary EC is entered. This option + might be preferred when the same code base is re-used for a VM or + an SP. The ABI to wake-up a secondary EC can remain similar. + +SPs are always scheduled from the NWd, this paradigm did not change from legacy +TEEs. There must always be some logic (or driver) in the NWd to relinquish CPU +cycles to the SWd. If primary core is 0, an SP EC[x>0] entry point is supplied +by the SP EC[0] when the system boots in SWd. But this EC[x] is not immediately +entered at boot. Later in the boot process when NWd is up, a direct message +request issued from physical core 1 ends up in SP EC[1], and only at this stage +this context is effectively scheduled. + +It should be possible for an SP to call into another SP through direct message +provided the latter SP has been booted already. The "boot-order" field in +partition manifests (`SP Boot order`_) fulfills the dependency towards availability +of a service within an SP offered to another SP. + +Mandatory interfaces +-------------------- + +The following interfaces must be exposed to any VM or SP: + +- ``FFA_STATUS`` +- ``FFA_ERROR`` +- ``FFA_INTERRUPT`` +- ``FFA_VERSION`` +- ``FFA_FEATURES`` +- ``FFA_RX_RELEASE`` +- ``FFA_RXTX_MAP`` +- ``FFA_RXTX_UNMAP`` +- ``FFA_PARTITION_INFO_GET`` +- ``FFA_ID_GET`` + +FFA_VERSION +~~~~~~~~~~~ + +Per `[1]`_ section 8.1 ``FFA_VERSION`` requires a +*requested_version* parameter from the caller. + +In the current implementation when ``FFA_VERSION`` is invoked from: + +- Hypervisor in NS-EL2: the SPMD returns the SPMC version specified + in the SPMC manifest. +- OS kernel in NS-EL1 when NS-EL2 is not present: the SPMD returns the + SPMC version specified in the SPMC manifest. +- VM in NWd: the Hypervisor returns its implemented version. +- SP in SWd: the SPMC returns its implemented version. +- SPMC at S-EL1/S-EL2: the SPMD returns its implemented version. + +FFA_FEATURES +~~~~~~~~~~~~ + +FF-A features may be discovered by Secure Partitions while booting +through the SPMC. However, SPMC cannot get features from Hypervisor +early at boot time as NS world is not setup yet. + +The Hypervisor may decide to gather FF-A features from SPMC through SPMD +once at boot time and store the result. Later when a VM requests FF-A +features, the Hypervisor can adjust its own set of features with what +SPMC advertised, if necessary. Another approach is to always forward FF-A +features to the SPMC when a VM requests it to the Hypervisor. Although +the result is not supposed to change over time so there may not be added +value doing the systematic forwarding. + +FFA_RXTX_MAP/FFA_RXTX_UNMAP +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +VM mailboxes are re-purposed to serve as SP RX/TX buffers. The RX/TX +map API maps the send and receive buffer IPAs to the SP Stage-2 translation regime. + +Hafnium in the normal world defines VMs and their attributes as logical structures, +including a mailbox used for FF-A indirect messaging, memory sharing, or the +`FFA_PARTITION_INFO_GET`_ ABI. +This same mailbox structure is re-used in the SPMC. `[1]`_ states only direct +messaging is allowed to SPs. Thus mailbox usage is restricted to implementing +`FFA_PARTITION_INFO_GET`_ and memory sharing ABIs. + +FFA_PARTITION_INFO_GET +~~~~~~~~~~~~~~~~~~~~~~ + +Partition info get service call can originate: + +- from SP to SPM +- from VM to Hypervisor +- from Hypervisor to SPM + +For the latter case, the service call must be forwarded through the SPMD. + +FFA_ID_GET +~~~~~~~~~~ + +The SPMD returns: + +- a default zero value on invocation from the Hypervisor. +- The ``spmc_id`` value specified in the SPMC manifest on invocation from + the SPMC (see `SPMC manifest`_) + +The FF-A id space is split into a non-secure space and secure space: + +- FF-A id with bit 15 clear refer to normal world VMs. +- FF-A id with bit 15 set refer to secure world SPs + +Such convention helps the SPMC discriminating the origin and destination worlds +in an FF-A service invocation. In particular the SPMC shall filter unauthorized +transactions in its world switch routine. It must not be permitted for a VM to +use a secure FF-A id as origin world through spoofing: + +- A VM-to-SP messaging passing shall have an origin world being non-secure + (FF-A id bit 15 clear) and destination world being secure (FF-A id bit 15 + set). +- Similarly, an SP-to-SP message shall have FF-A id bit 15 set for both origin + and destination ids. + +An incoming direct message request arriving at SPMD from NWd is forwarded to +SPMC without a specific check. The SPMC is resumed through eret and "knows" the +message is coming from normal world in this specific code path. Thus the origin +endpoint id must be checked by SPMC for being a normal world id. + +An SP sending a direct message request must have bit 15 set in its origin +endpoint id and this can be checked by the SPMC when the SP invokes the ABI. + +The SPMC shall reject the direct message if the claimed world in origin endpoint +id is not consistent: + +- It is either forwarded by SPMD and thus origin endpoint id must be a "normal + world id", +- or initiated by an SP and thus origin endpoint id must be a "secure world id". + +Direct messaging +---------------- + +This is a mandatory interface for Secure Partitions consisting in direct +message request and responses. + +The ``ffa_handler`` Hafnium function may: + +- trigger a world change e.g. when an SP invokes the direct message + response ABI to a VM. +- handle multiple requests from the NWd without resuming an SP. + +SP-to-SP +~~~~~~~~ + +- An SP can send a direct message request to another SP +- An SP can receive a direct message response from another SP. + +VM-to-SP +~~~~~~~~ + +- A VM can send a direct message request to an SP +- An SP can send a direct message response to a VM + +SPMC-SPMD messaging +~~~~~~~~~~~~~~~~~~~ + +Specific implementation-defined endpoint IDs are allocated to the SPMC and SPMD. +Referring those IDs in source/destination fields of a direct message +request/response permits SPMD to SPMC messaging back and forth. + +Per `[1]`_ Table 114 Config No. 1 (physical FF-A instance): + +- SPMC=>SPMD direct message request uses SMC conduit +- SPMD=>SPMC direct message request uses ERET conduit + +Per `[1]`_ Table 118 Config No. 1 (physical FF-A instance): + +- SPMC=>SPMD direct message response uses SMC conduit +- SPMD=>SPMC direct message response uses ERET conduit + +Memory management +----------------- + +This section only deals with the PE MMU configuration. + +Hafnium in the normal world deals with NS buffers only and provisions +a single root page table directory to VMs. In context of S-EL2 enabled +firmware, two IPA spaces are output from Stage-1 translation (secure +and non-secure). The Stage-2 translation handles: + +- A single secure IPA space when an SP Stage-1 MMU is disabled. +- Two IPA spaces (secure and non-secure) when Stage-1 MMU is enabled. + +``VTCR_EL2`` and ``VSTCR_EL2`` provide additional bits for controlling the +NS/S IPA translations (``VSTCR_EL2.SW``, ``VSTCR_EL2.SA``, ``VTCR_EL2.NSW``, +``VTCR_EL2.NSA``). There may be two approaches: + +- secure and non-secure mappings are rooted as two separate root page + tables +- secure and non-secure mappings use the same root page table. Access + from S-EL1 to an NS region translates to a secure physical address + space access. + +Interrupt management +-------------------- + +Road to a para-virtualized interface +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Current Hafnium implementation uses an ad-hoc mechanism for a VM to get +a pending interrupt number through an hypercall. The PVM injects +interrupts to VMs by delegation from the Hypervisor. The PVM probes a +pending interrupt directly from the GIC distributor. + +The short-term plan is to have Hafnium/SPMC in the secure world owner +of the GIC configuration. + +The SPMC fully owns the GIC configuration at S-EL2. The SPMC manages +interrupt resources and allocates interrupt ID based on SP manifests. +The SPMC acknowledges physical interrupts and injects virtual interrupts +by setting the vIRQ bit when resuming an SP. A Secure Partition gathers +the interrupt number through an hypercall. + +Notice the SPMC/SPMD has to handle Group0 secure interrupts in addition +to Group1 S/NS interrupts. + +Power management +---------------- + +Assumption on the Nwd: + +- NWd is the best candidate to own the platform Power Management + policy. It is master to invoking PSCI service calls from physical + CPUs. +- EL3 monitor is in charge of the PM control part (its PSCI layer + actually writing to platform registers). +- It is fine for the Hypervisor to trap PSCI calls and relay to EL3, or + OS kernel driver to emit PSCI service calls. + +PSCI notification are relayed through the SPMD/SPD PM hooks to the SPMC. +This can either be through re-use of PSCI FIDs or an FF-A direct message +from SPMD to SPMC. + +The SPMD performs an exception return to the SPMC which is resumed to +its ``eret_handler`` routine. It is then either consuming a PSCI FID or +an FF-A FID. Depending on the servicing, the SPMC may return directly to +the SPMD (and then NWd) without resuming an SP at this stage. An example +of this is invocation of ``FFA_PARTITION_INFO_GET`` from NWd relayed by +the SPMD to the SPMC. The SPMC returns the needed partition information +to the SPMD (then NWd) without actually resuming a partition in secure world. + +*(under discussion)* +About using PSCI FIDs from SPMD to SPMC to notify of PM events, it is still +questioned what to use as the return code from the SPMC. +If the function ID used by the SPMC is not an FF-A ID when doing SMC, then the +EL3 std svc handler won't route the response to the SPMD. That's where comes the +idea to embed the notification into an FF-A message. The SPMC can discriminate +this message as being a PSCI event, process it, and reply with an FF-A return +message that the SPMD receives as an acknowledgement. + +SP notification +--------------- + +Power management notifications are conveyed from PSCI library to the +SPMD / SPD hooks. A range of events can be relayed to SPMC. + +SPs may need to be notified about specific PM events. + +- SPs might register PM events to the SPMC +- On SPMD to SPMC notification, a limited range of SPs may be notified + through a direct message. +- This assumes the mentioned SPs supports managed exit. + +The SPMC is the first to be notified about PM events from the SPMD. It is up +to the SPMC to arbitrate to which SP it needs to send PM events. +An SP explicitly registers to receive notifications to specific PM events. +The register operation can either be an implementation-defined service call +to the SPMC when the primary SP EC boots, or be supplied through the SP +manifest. + +References +========== + +.. _[1]: + +[1] `Platform Security Architecture Firmware Framework for Arm® v8-A 1.0 Platform Design Document `__ + +.. _[2]: + +[2] `Secure Partition Manager using MM interface`__ + +.. __: secure-partition-manager-mm.html + +.. _[3]: + +[3] `Trusted Boot Board Requirements +Client `__ + +.. _[4]: + +[4] https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/lib/el3_runtime/aarch64/context.S#n45 + +.. _[5]: + +[5] https://git.trustedfirmware.org/TF-A/tf-a-tests.git/tree/spm/cactus/cactus.dts + +.. _[6]: + +[6] https://trustedfirmware-a.readthedocs.io/en/latest/components/psa-ffa-manifest-binding.html + +.. _[7]: + +[7] https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts + +.. _[8]: + +[8] https://developer.trustedfirmware.org/w/tf_a/poc-multiple-signing-domains/ + +-------------- + +*Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.* diff --git a/docs/resources/diagrams/ff-a-spm-sel2.png b/docs/resources/diagrams/ff-a-spm-sel2.png new file mode 100644 index 000000000..6479ff559 Binary files /dev/null and b/docs/resources/diagrams/ff-a-spm-sel2.png differ diff --git a/docs/resources/diagrams/plantuml/bl2-loading-sp.puml b/docs/resources/diagrams/plantuml/bl2-loading-sp.puml new file mode 100644 index 000000000..3cf7c3620 --- /dev/null +++ b/docs/resources/diagrams/plantuml/bl2-loading-sp.puml @@ -0,0 +1,44 @@ +/' + ' Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + ' + ' SPDX-License-Identifier: BSD-3-Clause + '/ + +@startuml +participant bl1 +participant FIP + +bl1 -> FIP : read(FW_CONFIG) +create FW_CONFIG +bl1 -> FW_CONFIG : load + +bl1 -> FIP : read(bl2) +create bl2 +bl1 -> bl2 : load +bl1 --> bl2 : hand off (FW_CONFIG) + +bl2 -> FW_CONFIG : read_node(SPKs) +loop for each spkg subnode + bl2 -> FW_CONFIG : read(UUID) + bl2 -> FW_CONFIG : read(load_address) + bl2 -> FIP : read(spkg@UUID) + create SPKG + bl2 -> SPKG : load +end loop + +bl2 -> FW_CONFIG : read_node(TOS_FW_CONFIG) +create TOS_FW_CONFIG +bl2 -> TOS_FW_CONFIG : load + +bl2 -> FIP : read(bl32/SPMC) +create SPMC +bl2 -> SPMC : load + +bl2 -> FIP : read(bl31) +create bl31 +bl2 -> bl31 : load +bl2 --> bl31 : hand off (TOS_FW_CONFIG) + +bl31 --> SPMC : hand off (TOS_FW_CONFIG) + +@enduml diff --git a/docs/resources/diagrams/plantuml/fip-secure-partitions.puml b/docs/resources/diagrams/plantuml/fip-secure-partitions.puml new file mode 100644 index 000000000..40621dbed --- /dev/null +++ b/docs/resources/diagrams/plantuml/fip-secure-partitions.puml @@ -0,0 +1,122 @@ +/' + ' Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + ' + ' SPDX-License-Identifier: BSD-3-Clause + '/ + +@startuml + +folder SP_vendor_1 { + artifact sp_binary_1 + artifact sp_manifest_1 [ + sp_manifest_1 + === + UUID = xxx + load_address = 0xaaa + ... + ] +} + +folder SP_vendor_2 { + artifact sp_binary_2 + artifact sp_manifest_2 [ + sp_manifest_2 + === + UUID = yyy + load_address = 0xbbb + ] +} + +artifact config.json [ + SP_LAYOUT.json + === + path to sp_binary_1 + path to sp_manifest_1 + --- + path to sp_binary_2 + path to sp_manifest_2 + --- + ... +] + +control sp_mk_generator + +artifact fconf_node [ + fconf_sp.dts + === + spkg_1 UUID + spkg_1 load_address + --- + spkg_2 UUID + spkg_2 load_address +] + +artifact sp_gen [ + sp_gen.mk + === + FDT_SOURCE = ... + SPTOOL_ARGS = ... + FIP_ARG = ... +] + +control dtc +control sptool + +artifact FW_CONFIG + +artifact spkg_1 [ + spkg_1.bin + === + header + --- + manifest + --- + binary +] + +artifact spkg_2 [ + spkg_2.bin + === + header + --- + manifest + --- + binary +] + +control fiptool + +artifact fip [ + fip.bin + === + FW_CONFIG.dtb + --- + ... + --- + SPKG1 + --- + SPKG2 + --- + ... +] + +config.json .up.> SP_vendor_1 +config.json .up.> SP_vendor_2 +config.json --> sp_mk_generator +sp_mk_generator --> fconf_node +sp_mk_generator --> sp_gen + +sp_gen --> sptool +sptool --> spkg_1 +sptool --> spkg_2 + +fconf_node -down-> dtc +dtc --> FW_CONFIG + +sp_gen --> fiptool +FW_CONFIG --> fiptool +spkg_1 -down-> fiptool +spkg_2 -down-> fiptool +fiptool -down-> fip + +@enduml -- cgit v1.2.3 From 578bf9f50e7c86cc9a52e7e2200e1b7e176ea197 Mon Sep 17 00:00:00 2001 From: Javier Almansa Sobrino Date: Fri, 10 Jul 2020 11:00:03 +0100 Subject: Add myself and Jack Bond-Preston as code owners for the CMake build definitions Signed-off-by: Javier Almansa Sobrino Change-Id: I1c5cc8af34c02a6294ffc44a26152fb8984927fc --- docs/about/maintainers.rst | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst index ea9a4f58a..444ad0085 100644 --- a/docs/about/maintainers.rst +++ b/docs/about/maintainers.rst @@ -60,6 +60,14 @@ Armv7-A architecture port :M: Etienne Carriere :G: `etienne-lms`_ +Build Definitions for CMake Build System +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:M: Javier Almansa Sobrino +:G: `javieralso-arm`_ +:M: Jack Bond-Preston +:G: `jackbondpreston-arm`_ +:F: / + Software Delegated Exception Interface (SDEI) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :M: Mark Dykes @@ -621,6 +629,6 @@ Build system .. _madhukar-Arm: https://github.com/madhukar-Arm .. _john-powell-arm: https://github.com/john-powell-arm .. _raghuncstate: https://github.com/raghuncstate - +.. _jackbondpreston-arm: https://github.com/jackbondpreston-arm .. _Project Maintenance Process: https://developer.trustedfirmware.org/w/collaboration/project-maintenance-process/ -- cgit v1.2.3 From 7b4e1fbb8f5c2d0e18326223aa0a945d6e7c3a55 Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Mon, 13 Jul 2020 12:11:05 +0100 Subject: TF-A: Add support for Measured Boot driver This patch adds support for Measured Boot driver functionality in common Arm platform code. Change-Id: If049dcf8d847c39023b77c0d805a8cf5b8bcaa3e Signed-off-by: Alexei Fedorov --- include/lib/fconf/fconf_tbbr_getter.h | 3 + include/plat/arm/common/arm_def.h | 12 +-- include/plat/arm/common/plat_arm.h | 14 ++- include/plat/common/platform.h | 15 ++- plat/arm/common/arm_bl2_setup.c | 11 ++ plat/arm/common/arm_dyn_cfg.c | 54 +++++++--- plat/arm/common/arm_dyn_cfg_helpers.c | 193 ++++++++++++++++++++++++++++++++-- 7 files changed, 266 insertions(+), 36 deletions(-) diff --git a/include/lib/fconf/fconf_tbbr_getter.h b/include/lib/fconf/fconf_tbbr_getter.h index db98b68b0..6066af6df 100644 --- a/include/lib/fconf/fconf_tbbr_getter.h +++ b/include/lib/fconf/fconf_tbbr_getter.h @@ -23,6 +23,9 @@ 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_def.h b/include/plat/arm/common/arm_def.h index 680d35432..139145b6b 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -81,7 +81,7 @@ ARM_SCP_TZC_DRAM1_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 - 1) + ARM_SCP_TZC_DRAM1_SIZE - 1U) /* * Define a 2MB region within the TZC secured DRAM for use by EL3 runtime @@ -92,7 +92,7 @@ #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 */ #define ARM_EL3_TZC_DRAM1_END (ARM_EL3_TZC_DRAM1_BASE + \ - ARM_EL3_TZC_DRAM1_SIZE - 1) + ARM_EL3_TZC_DRAM1_SIZE - 1U) #define ARM_AP_TZC_DRAM1_BASE (ARM_DRAM1_BASE + \ ARM_DRAM1_SIZE - \ @@ -101,7 +101,7 @@ (ARM_SCP_TZC_DRAM1_SIZE + \ ARM_EL3_TZC_DRAM1_SIZE)) #define ARM_AP_TZC_DRAM1_END (ARM_AP_TZC_DRAM1_BASE + \ - ARM_AP_TZC_DRAM1_SIZE - 1) + ARM_AP_TZC_DRAM1_SIZE - 1U) /* Define the Access permissions for Secure peripherals to NS_DRAM */ #if ARM_CRYPTOCELL_INTEG @@ -148,17 +148,17 @@ #define ARM_NS_DRAM1_SIZE (ARM_DRAM1_SIZE - \ ARM_TZC_DRAM1_SIZE) #define ARM_NS_DRAM1_END (ARM_NS_DRAM1_BASE + \ - ARM_NS_DRAM1_SIZE - 1) + ARM_NS_DRAM1_SIZE - 1U) #define ARM_DRAM1_BASE ULL(0x80000000) #define ARM_DRAM1_SIZE ULL(0x80000000) #define ARM_DRAM1_END (ARM_DRAM1_BASE + \ - ARM_DRAM1_SIZE - 1) + ARM_DRAM1_SIZE - 1U) #define ARM_DRAM2_BASE PLAT_ARM_DRAM2_BASE #define ARM_DRAM2_SIZE PLAT_ARM_DRAM2_SIZE #define ARM_DRAM2_END (ARM_DRAM2_BASE + \ - ARM_DRAM2_SIZE - 1) + ARM_DRAM2_SIZE - 1U) #define ARM_IRQ_SEC_PHY_TIMER 29 diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index 36255300e..95fc18ed8 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -235,8 +235,20 @@ 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(image_desc_t *image_desc); +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, +/* + * Currently OP-TEE does not support reading DTBs from Secure memory + * and this option should be removed when feature is supported. + */ +#ifdef SPD_opteed + uintptr_t log_addr, #endif + size_t log_size, uintptr_t *ns_log_addr); +#endif /* MEASURED_BOOT */ /* * Free the memory storing initialization code only used during an images boot diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h index 720c259b8..658b42380 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.h @@ -175,6 +175,14 @@ __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 ******************************************************************************/ @@ -190,11 +198,13 @@ struct meminfo *bl2_plat_sec_mem_layout(void); int bl2_plat_handle_pre_image_load(unsigned int image_id); 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); +#endif /******************************************************************************* * Mandatory BL2 at EL3 functions: Must be implemented if BL2_AT_EL3 image is @@ -204,7 +214,6 @@ void bl2_el3_early_platform_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3); void bl2_el3_plat_arch_setup(void); - /******************************************************************************* * Optional BL2 at EL3 functions (may be overridden) ******************************************************************************/ diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c index fd60c2bd3..80f3b32ee 100644 --- a/plat/arm/common/arm_bl2_setup.c +++ b/plat/arm/common/arm_bl2_setup.c @@ -37,6 +37,9 @@ 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 #define MAP_BL2_TOTAL MAP_REGION_FLAT( \ bl2_tzram_layout.total_base, \ @@ -225,3 +228,11 @@ 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 633445bad..b31870b6d 100644 --- a/plat/arm/common/arm_dyn_cfg.c +++ b/plat/arm/common/arm_dyn_cfg.c @@ -23,6 +23,7 @@ #include #include #include + #include #include @@ -98,13 +99,14 @@ void arm_bl1_set_mbedtls_heap(void) tb_fw_cfg_dtb = tb_fw_config_info->config_addr; if ((tb_fw_cfg_dtb != 0UL) && (mbedtls_heap_addr != NULL)) { - /* As libfdt use void *, we can't avoid this cast */ + /* As libfdt uses void *, we can't avoid this cast */ void *dtb = (void *)tb_fw_cfg_dtb; err = arm_set_dtb_mbedtls_heap_info(dtb, mbedtls_heap_addr, mbedtls_heap_size); if (err < 0) { - ERROR("BL1: unable to write shared Mbed TLS heap information to DTB\n"); + ERROR("%swrite shared Mbed TLS heap information%s", + "BL1: unable to ", " to DTB\n"); panic(); } #if !MEASURED_BOOT @@ -124,13 +126,13 @@ void arm_bl1_set_mbedtls_heap(void) #if MEASURED_BOOT /* - * Puts the BL2 hash data to TB_FW_CONFIG DTB. + * Calculates and writes BL2 hash data to TB_FW_CONFIG DTB. * Executed only from BL1. */ -void arm_bl1_set_bl2_hash(image_desc_t *image_desc) +void arm_bl1_set_bl2_hash(const image_desc_t *image_desc) { unsigned char hash_data[MBEDTLS_MD_MAX_SIZE]; - image_info_t image_info = image_desc->image_info; + 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; @@ -154,13 +156,15 @@ void arm_bl1_set_bl2_hash(image_desc_t *image_desc) (void *)image_info.image_base, image_info.image_size, hash_data); if (err != 0) { - ERROR("BL1: unable to calculate BL2 hash\n"); + 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("BL1: unable to write BL2 hash data to DTB\n"); + ERROR("%swrite%sdata%s\n", "BL1: unable to ", + " BL2 hash ", "to DTB\n"); panic(); } @@ -171,6 +175,21 @@ void arm_bl1_set_bl2_hash(image_desc_t *image_desc) */ 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 */ @@ -202,14 +221,15 @@ void arm_bl2_dyn_cfg_init(void) /* Get the config load address and size from TB_FW_CONFIG */ cfg_mem_params = get_bl_mem_params_node(config_ids[i]); if (cfg_mem_params == NULL) { - VERBOSE("Couldn't find HW_CONFIG in bl_mem_params_node\n"); + VERBOSE("%sHW_CONFIG in bl_mem_params_node\n", + "Couldn't find "); continue; } dtb_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, config_ids[i]); if (dtb_info == NULL) { - VERBOSE("Couldn't find config_id %d load info in TB_FW_CONFIG\n", - config_ids[i]); + VERBOSE("%sconfig_id %d load info in TB_FW_CONFIG\n", + "Couldn't find ", config_ids[i]); continue; } @@ -223,30 +243,32 @@ void arm_bl2_dyn_cfg_init(void) */ if (config_ids[i] != HW_CONFIG_ID) { - if (check_uptr_overflow(image_base, image_size)) + if (check_uptr_overflow(image_base, image_size)) { continue; - + } #ifdef BL31_BASE /* Ensure the configs don't overlap with BL31 */ if ((image_base >= BL31_BASE) && - (image_base <= BL31_LIMIT)) + (image_base <= BL31_LIMIT)) { continue; + } #endif /* Ensure the configs are loaded in a valid address */ - if (image_base < ARM_BL_RAM_BASE) + if (image_base < ARM_BL_RAM_BASE) { continue; + } #ifdef BL32_BASE /* * If BL32 is present, ensure that the configs don't * overlap with it. */ if ((image_base >= BL32_BASE) && - (image_base <= BL32_LIMIT)) + (image_base <= BL32_LIMIT)) { continue; + } #endif } - cfg_mem_params->image_info.image_base = image_base; cfg_mem_params->image_info.image_max_size = (uint32_t)image_size; diff --git a/plat/arm/common/arm_dyn_cfg_helpers.c b/plat/arm/common/arm_dyn_cfg_helpers.c index f110e3bb6..5f20c8d48 100644 --- a/plat/arm/common/arm_dyn_cfg_helpers.c +++ b/plat/arm/common/arm_dyn_cfg_helpers.c @@ -6,9 +6,13 @@ #include +#if MEASURED_BOOT +#include +#endif +#include + #include -#include #include #include @@ -17,6 +21,15 @@ #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 +#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 */ @@ -37,18 +50,19 @@ int arm_dyn_tb_fw_cfg_init(void *dtb, int *node) /* Check if the pointer to DT is correct */ if (fdt_check_header(dtb) != 0) { - WARN("Invalid DTB file passed as TB_FW_CONFIG\n"); + WARN("Invalid DTB file passed as%s\n", " TB_FW_CONFIG"); return -1; } /* Assert the node offset point to "arm,tb_fw" compatible property */ *node = fdt_node_offset_by_compatible(dtb, -1, "arm,tb_fw"); if (*node < 0) { - WARN("The compatible property `arm,tb_fw` not found in the config\n"); + WARN("The compatible property '%s' not%s", "arm,tb_fw", + " found in the config\n"); return -1; } - VERBOSE("Dyn cfg: Found \"arm,tb_fw\" in the config\n"); + VERBOSE("Dyn cfg: '%s'%s", "arm,tb_fw", " found in the config\n"); return 0; } @@ -76,7 +90,8 @@ int arm_set_dtb_mbedtls_heap_info(void *dtb, void *heap_addr, size_t heap_size) */ int err = arm_dyn_tb_fw_cfg_init(dtb, &dtb_root); if (err < 0) { - ERROR("Invalid TB_FW_CONFIG loaded. Unable to get root node\n"); + ERROR("Invalid%s loaded. Unable to get root node\n", + " TB_FW_CONFIG"); return -1; } @@ -90,16 +105,16 @@ int arm_set_dtb_mbedtls_heap_info(void *dtb, void *heap_addr, size_t heap_size) err = fdtw_write_inplace_cells(dtb, dtb_root, DTB_PROP_MBEDTLS_HEAP_ADDR, 2, &heap_addr); if (err < 0) { - ERROR("Unable to write DTB property %s\n", - DTB_PROP_MBEDTLS_HEAP_ADDR); + ERROR("%sDTB property '%s'\n", + "Unable to write ", DTB_PROP_MBEDTLS_HEAP_ADDR); return -1; } err = fdtw_write_inplace_cells(dtb, dtb_root, DTB_PROP_MBEDTLS_HEAP_SIZE, 1, &heap_size); if (err < 0) { - ERROR("Unable to write DTB property %s\n", - DTB_PROP_MBEDTLS_HEAP_SIZE); + ERROR("%sDTB property '%s'\n", + "Unable to write ", DTB_PROP_MBEDTLS_HEAP_SIZE); return -1; } @@ -124,7 +139,165 @@ int arm_set_bl2_hash_info(void *dtb, void *data) /* * Write the BL2 hash data in the DTB. */ - return fdtw_write_inplace_bytes(dtb, dtb_root, DTB_PROP_BL2_HASH_DATA, + 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. + * + * This function is supposed to be called only by BL2. + * + * Returns: + * 0 = success + * < 0 = error + */ +static int arm_set_event_log_info(uintptr_t config_base, +#ifdef SPD_opteed + uintptr_t sm_log_addr, +#endif + uintptr_t log_addr, size_t log_size) +{ + /* As libfdt uses void *, we can't avoid this cast */ + void *dtb = (void *)config_base; + const char *compatible = "arm,tpm_event_log"; + int err, node; + + /* + * Verify that the DTB is valid, before attempting to write to it, + * and get the DTB root node. + */ + + /* Check if the pointer to DT is correct */ + err = fdt_check_header(dtb); + if (err < 0) { + WARN("Invalid DTB file passed\n"); + return err; + } + + /* 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' not%s", compatible, + " found in the config\n"); + return node; + } + + VERBOSE("Dyn cfg: '%s'%s", compatible, " found in the config\n"); + +#ifdef SPD_opteed + if (sm_log_addr != 0UL) { + err = fdtw_write_inplace_cells(dtb, node, + DTB_PROP_HW_SM_LOG_ADDR, 2, &sm_log_addr); + if (err < 0) { + ERROR("%sDTB property '%s'\n", + "Unable to write ", DTB_PROP_HW_SM_LOG_ADDR); + return err; + } + } +#endif + err = fdtw_write_inplace_cells(dtb, node, + DTB_PROP_HW_LOG_ADDR, 2, &log_addr); + if (err < 0) { + ERROR("%sDTB property '%s'\n", + "Unable to write ", DTB_PROP_HW_LOG_ADDR); + return err; + } + + err = fdtw_write_inplace_cells(dtb, node, + DTB_PROP_HW_LOG_SIZE, 1, &log_size); + if (err < 0) { + ERROR("%sDTB property '%s'\n", + "Unable to write ", DTB_PROP_HW_LOG_SIZE); + } else { + /* + * Ensure that the info written to the DTB is visible + * to other images. + */ + flush_dcache_range(config_base, fdt_totalsize(dtb)); + } + + return err; +} + +/* + * This function writes the Event Log address and its size + * in the TOS_FW_CONFIG DTB. + * + * This function is supposed to be called only by BL2. + * + * Returns: + * 0 = success + * < 0 = error + */ +int arm_set_tos_fw_info(uintptr_t config_base, uintptr_t log_addr, + size_t log_size) +{ + int err; + + assert(config_base != 0UL); + assert(log_addr != 0UL); + + /* Write the Event Log address and its size in the DTB */ + err = arm_set_event_log_info(config_base, +#ifdef SPD_opteed + 0UL, +#endif + log_addr, log_size); + if (err < 0) { + ERROR("%sEvent Log data to TOS_FW_CONFIG\n", + "Unable to write "); + } + + return err; +} + +/* + * This function writes the Event Log address and its size + * in the NT_FW_CONFIG DTB. + * + * This function is supposed to be called only by BL2. + * + * Returns: + * 0 = success + * < 0 = error + */ +int arm_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) +{ + 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); + + /* 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; + + /* Check for memory space */ + if ((uint64_t)(ns_addr + log_size) > ARM_NS_DRAM1_END) { + return -1; + } + + /* Write the Event Log address and its size in the DTB */ + err = arm_set_event_log_info(config_base, +#ifdef SPD_opteed + log_addr, +#endif + ns_addr, log_size); + + /* Return Event Log address in Non-secure memory */ + *ns_log_addr = (err < 0) ? 0UL : ns_addr; + return err; +} #endif /* MEASURED_BOOT */ -- cgit v1.2.3 From d686fa3b97af3a5e5b7de484ec8a0c7724cd54ce Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Mon, 13 Jul 2020 13:58:06 +0100 Subject: TF-A: Add Event Log for Measured Boot This patch adds support for Event Log generation required for Measured Boot functionality. Change-Id: I34f05a33565e6659e78499d62cc6fb00b7d6c2dc Signed-off-by: Alexei Fedorov --- drivers/auth/mbedtls/mbedtls_common.mk | 14 - drivers/measured_boot/event_log.c | 406 ++++++++++++++++++++++++++ drivers/measured_boot/event_print.c | 264 +++++++++++++++++ drivers/measured_boot/measured_boot.c | 39 +++ drivers/measured_boot/measured_boot.mk | 45 +++ include/drivers/measured_boot/event_log.h | 99 +++++++ include/drivers/measured_boot/measured_boot.h | 21 ++ include/drivers/measured_boot/tcg.h | 304 +++++++++++++++++++ plat/arm/common/arm_common.mk | 6 + 9 files changed, 1184 insertions(+), 14 deletions(-) create mode 100644 drivers/measured_boot/event_log.c create mode 100644 drivers/measured_boot/event_print.c create mode 100644 drivers/measured_boot/measured_boot.c create mode 100644 drivers/measured_boot/measured_boot.mk create mode 100644 include/drivers/measured_boot/event_log.h create mode 100644 include/drivers/measured_boot/measured_boot.h create mode 100644 include/drivers/measured_boot/tcg.h diff --git a/drivers/auth/mbedtls/mbedtls_common.mk b/drivers/auth/mbedtls/mbedtls_common.mk index 564a4c932..94f2f59e1 100644 --- a/drivers/auth/mbedtls/mbedtls_common.mk +++ b/drivers/auth/mbedtls/mbedtls_common.mk @@ -75,19 +75,10 @@ endif ifeq (${HASH_ALG}, sha384) TF_MBEDTLS_HASH_ALG_ID := TF_MBEDTLS_SHA384 - MBEDTLS_MD_ID := MBEDTLS_MD_SHA384 - TPM_ALG_ID := TPM_ALG_SHA384 - TCG_DIGEST_SIZE := 48 else ifeq (${HASH_ALG}, sha512) TF_MBEDTLS_HASH_ALG_ID := TF_MBEDTLS_SHA512 - MBEDTLS_MD_ID := MBEDTLS_MD_SHA512 - TPM_ALG_ID := TPM_ALG_SHA512 - TCG_DIGEST_SIZE := 64 else TF_MBEDTLS_HASH_ALG_ID := TF_MBEDTLS_SHA256 - MBEDTLS_MD_ID := MBEDTLS_MD_SHA256 - TPM_ALG_ID := TPM_ALG_SHA256 - TCG_DIGEST_SIZE := 32 endif ifeq (${TF_MBEDTLS_KEY_ALG},ecdsa) @@ -112,11 +103,6 @@ $(eval $(call add_define,TF_MBEDTLS_KEY_SIZE)) $(eval $(call add_define,TF_MBEDTLS_HASH_ALG_ID)) $(eval $(call add_define,TF_MBEDTLS_USE_AES_GCM)) -# Set definitions for measured boot driver -$(eval $(call add_define,MBEDTLS_MD_ID)) -$(eval $(call add_define,TPM_ALG_ID)) -$(eval $(call add_define,TCG_DIGEST_SIZE)) - $(eval $(call MAKE_LIB,mbedtls)) endif diff --git a/drivers/measured_boot/event_log.c b/drivers/measured_boot/event_log.c new file mode 100644 index 000000000..0042c9699 --- /dev/null +++ b/drivers/measured_boot/event_log.c @@ -0,0 +1,406 @@ +/* + * Copyright (c) 2020, 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 + } +}; + +/* Platform's table with platform specific image IDs, names and PCRs */ +static const image_data_t plat_images_data[] = { + { BL2_IMAGE_ID, BL2_STRING, PCR_0 }, /* Reserved for BL2 */ + { INVALID_ID, NULL, (unsigned int)(-1) } /* Terminator */ +}; + +static const measured_boot_data_t plat_measured_boot_data = { + plat_images_data, + NULL, /* platform_set_nt_fw_info */ + NULL /* platform_set_tos_fw_info */ +}; + +/* + * Function retuns pointer to platform's measured_boot_data_t structure + * + * Must be overridden in the platform code + */ +#pragma weak plat_get_measured_boot_data + +const measured_boot_data_t *plat_get_measured_boot_data(void) +{ + return &plat_measured_boot_data; +} + +/* + * 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 + * @return: + * 0 = success + * < 0 = error code + */ +static int add_event2(const uint8_t *hash, const image_data_t *image_ptr) +{ + void *ptr = log_ptr; + uint32_t name_len; + uint32_t size_of_event; + + assert(image_ptr != NULL); + assert(image_ptr->name != NULL); + + name_len = (uint32_t)strlen(image_ptr->name) + 1U; + size_of_event = name_len + (uint32_t)EVENT2_HDR_SIZE; + + /* Check for space in Event Log buffer */ + if (((uintptr_t)ptr + size_of_event) > EVENT_LOG_END) { + ERROR("%s(): Event Log is short of memory", __func__); + return -ENOMEM; + } + + /* + * 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 *)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 *)ptr + offsetof(tpmt_ha, digest); + + /* Check for space in Event Log buffer */ + if (((uintptr_t)ptr + TCG_DIGEST_SIZE) > EVENT_LOG_END) { + ERROR("%s(): Event Log is short of memory", __func__); + return -ENOMEM; + } + + 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 *)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 *)ptr + offsetof(event2_data_t, event) + name_len; + + return 0; +} + +/* + * 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; + const uint8_t *start_ptr; + 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 *)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 *)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 *)ptr + offsetof(id_event_struct_data_t, vendor_info); + if ((uintptr_t)ptr != ((uintptr_t)event_log + ID_EVENT_SIZE)) { + panic(); + } + + start_ptr = (uint8_t *)ptr; + + /* + * 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 *)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 *)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 *)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 *)ptr + sizeof(startup_locality_event_t); + if ((uintptr_t)ptr != ((uintptr_t)start_ptr + LOC_EVENT_SIZE)) { + panic(); + } + + log_ptr = (uint8_t *)ptr; + + /* Add BL2 event */ + if (add_event2(NULL, plat_data_ptr->images_data) != 0) { + panic(); + } +} + +/* + * 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 tpm_record_measurement(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; + + /* Check if image_id is supported */ + while (data_ptr->id != data_id) { + if ((data_ptr++)->id == INVALID_ID) { + ERROR("%s(): image_id %u not supported\n", + __func__, data_id); + return -EINVAL; + } + } + + 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; + } + + return add_event2(hash_data, data_ptr); +} + +/* + * 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_print.c b/drivers/measured_boot/event_print.c new file mode 100644 index 000000000..ed970b870 --- /dev/null +++ b/drivers/measured_boot/event_print.c @@ -0,0 +1,264 @@ +/* + * 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 = *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(((uint8_t *)alg_ptr + digest_len) <= 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 *)alg_ptr + digest_len; + assert(info_size_ptr <= end_ptr); + + info_size = *info_size_ptr++; + LOG_EVENT(" VendorInfoSize : %u\n", info_size); + + /* Check VendorInfo end address */ + assert((info_size_ptr + info_size) <= 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 = *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(((uint8_t *)ptr + offsetof(tpmt_ha, digest)) <= 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 *)ptr + offsetof(tpmt_ha, digest); + assert(((uint8_t *)ptr + sha_size) <= 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(((uint8_t *)ptr + offsetof(event2_data_t, event)) <= 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 *)ptr + offsetof(event2_data_t, event); + + /* End of TCG_PCR_EVENT2.Event[EventSize] */ + assert(((uint8_t *)ptr + event_size) <= 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.c b/drivers/measured_boot/measured_boot.c new file mode 100644 index 000000000..37fddfbdc --- /dev/null +++ b/drivers/measured_boot/measured_boot.c @@ -0,0 +1,39 @@ +/* + * 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 new file mode 100644 index 000000000..fc005d5ed --- /dev/null +++ b/drivers/measured_boot/measured_boot.mk @@ -0,0 +1,45 @@ +# +# Copyright (c) 2020, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# 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_define,MBEDTLS_MD_ID)) +$(eval $(call add_define,TPM_ALG_ID)) +$(eval $(call add_define,TCG_DIGEST_SIZE)) +$(eval $(call add_define,EVENT_LOG_SIZE)) + +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}measured_boot.c \ + ${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 new file mode 100644 index 000000000..10dfbb39d --- /dev/null +++ b/include/drivers/measured_boot/event_log.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2020, 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 + */ +#define EVENT_LOG_LEVEL LOG_LEVEL_INFO + +#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 tpm_record_measurement(uintptr_t data_base, uint32_t data_size, + uint32_t data_id); +#endif /* EVENT_LOG_H */ diff --git a/include/drivers/measured_boot/measured_boot.h b/include/drivers/measured_boot/measured_boot.h new file mode 100644 index 000000000..f8769ab43 --- /dev/null +++ b/include/drivers/measured_boot/measured_boot.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MEASURED_BOOT_H +#define MEASURED_BOOT_H + +#include + +#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); + +#endif /* MEASURED_BOOT_H */ diff --git a/include/drivers/measured_boot/tcg.h b/include/drivers/measured_boot/tcg.h new file mode 100644 index 000000000..ab27a0844 --- /dev/null +++ b/include/drivers/measured_boot/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/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index a92bf2578..96ab2d300 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -337,3 +337,9 @@ ifeq (${RECLAIM_INIT_CODE}, 1) $(error "To reclaim init code xlat tables v2 must be used") endif endif + +ifeq (${MEASURED_BOOT},1) + MEASURED_BOOT_MK := drivers/measured_boot/measured_boot.mk + $(info Including ${MEASURED_BOOT_MK}) + include ${MEASURED_BOOT_MK} +endif -- cgit v1.2.3 From 3f498b0dc282f6229b0a894ba61dc1948c4fb384 Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Mon, 13 Jul 2020 14:06:47 +0100 Subject: TF-A: Add support for Measured Boot driver in BL1 and BL2 This patch adds support for Measured Boot driver functionality in BL1 and BL2 code. Change-Id: I7239a94c3e32b0a3e9e73768a0140e0b52ab0361 Signed-off-by: Alexei Fedorov --- bl2/bl2_main.c | 18 ++++++++++++++++-- plat/common/plat_bl1_common.c | 15 +++++++++++++-- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/bl2/bl2_main.c b/bl2/bl2_main.c index 802c17464..203e1d4b1 100644 --- a/bl2/bl2_main.c +++ b/bl2/bl2_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -14,6 +14,9 @@ #include #include #include +#if MEASURED_BOOT +#include +#endif #include #include @@ -88,14 +91,25 @@ 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 boot source */ + /* 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 */ + #if !BL2_AT_EL3 #ifndef __aarch64__ /* diff --git a/plat/common/plat_bl1_common.c b/plat/common/plat_bl1_common.c index 5733781ac..2baa29aba 100644 --- a/plat/common/plat_bl1_common.c +++ b/plat/common/plat_bl1_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -27,7 +27,9 @@ #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) { @@ -116,3 +118,12 @@ int bl1_plat_handle_post_image_load(unsigned int image_id) (void *) bl2_tzram_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 c3825c9bb77d55d218210fd26f250f9102c3b461 Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Mon, 13 Jul 2020 14:10:00 +0100 Subject: TF-A: Add support for Measured Boot driver to FCONF This patch adds support for Measured Boot driver functionality to FCONF library code. Change-Id: I81cdb06f1950f7e6e58f938a1b9c2f74f7cfdf88 Signed-off-by: Alexei Fedorov --- lib/fconf/fconf_dyn_cfg_getter.c | 2 +- lib/fconf/fconf_tbbr_getter.c | 48 ++++++++++++++++++++++++++++------------ 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/lib/fconf/fconf_dyn_cfg_getter.c b/lib/fconf/fconf_dyn_cfg_getter.c index 902c07d95..16bbe42c8 100644 --- a/lib/fconf/fconf_dyn_cfg_getter.c +++ b/lib/fconf/fconf_dyn_cfg_getter.c @@ -12,7 +12,7 @@ #include #include -/* We currently use FW, TB_FW, SOC_FW, TOS_FW, NS_fw and HW configs */ +/* We currently use FW, TB_FW, SOC_FW, TOS_FW, NT_FW and HW configs */ #define MAX_DTB_INFO U(6) static struct dyn_cfg_dtb_info_t dtb_infos[MAX_DTB_INFO]; diff --git a/lib/fconf/fconf_tbbr_getter.c b/lib/fconf/fconf_tbbr_getter.c index 21278019e..9a20ced4e 100644 --- a/lib/fconf/fconf_tbbr_getter.c +++ b/lib/fconf/fconf_tbbr_getter.c @@ -27,20 +27,25 @@ int fconf_populate_tbbr_dyn_config(uintptr_t config) const char *compatible_str = "arm,tb_fw"; 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); + ERROR("FCONF: Can't find `%s` compatible in dtb\n", + compatible_str); return node; } /* Locate the disable_auth cell and read the value */ - err = fdt_read_uint32(dtb, node, "disable_auth", &tbbr_dyn_config.disable_auth); + err = fdt_read_uint32(dtb, node, "disable_auth", + &tbbr_dyn_config.disable_auth); if (err < 0) { - WARN("FCONF: Read cell failed for `disable_auth`\n"); + WARN("FCONF: Read %s failed for `%s`\n", + "cell", "disable_auth"); return err; } /* Check if the value is boolean */ - if ((tbbr_dyn_config.disable_auth != 0U) && (tbbr_dyn_config.disable_auth != 1U)) { - WARN("Invalid value for `disable_auth` cell %d\n", tbbr_dyn_config.disable_auth); + if ((tbbr_dyn_config.disable_auth != 0U) && + (tbbr_dyn_config.disable_auth != 1U)) { + WARN("Invalid value for `%s` cell %d\n", + "disable_auth", tbbr_dyn_config.disable_auth); return -1; } @@ -52,25 +57,40 @@ int fconf_populate_tbbr_dyn_config(uintptr_t config) /* Retrieve the Mbed TLS heap details from the DTB */ err = fdt_read_uint64(dtb, node, "mbedtls_heap_addr", &val64); if (err < 0) { - ERROR("FCONF: Read cell failed for mbedtls_heap\n"); + ERROR("FCONF: Read %s failed for `%s`\n", + "cell", "mbedtls_heap_addr"); return err; } tbbr_dyn_config.mbedtls_heap_addr = (void *)(uintptr_t)val64; err = fdt_read_uint32(dtb, node, "mbedtls_heap_size", &val32); if (err < 0) { - ERROR("FCONF: Read cell failed for mbedtls_heap\n"); + ERROR("FCONF: Read %s failed for `%s`\n", + "cell", "mbedtls_heap_size"); return err; } tbbr_dyn_config.mbedtls_heap_size = val32; - VERBOSE("FCONF:tbbr.disable_auth cell found with value = %d\n", - tbbr_dyn_config.disable_auth); - VERBOSE("FCONF:tbbr.mbedtls_heap_addr cell found with value = %p\n", - tbbr_dyn_config.mbedtls_heap_addr); - VERBOSE("FCONF:tbbr.mbedtls_heap_size cell found with value = %zu\n", - tbbr_dyn_config.mbedtls_heap_size); - +#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; } -- cgit v1.2.3 From 4a0ac3e38e51cb05217d1feef1816fc3738074be Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Fri, 10 Jul 2020 14:18:01 +0800 Subject: plat: imx: common: implement IMX_SIP_AARCH32 Implement IMX_SIP_AARCH32 to let AArch64 Bootloader could issue SIP call to switch to AArch32 mode to run OS. Signed-off-by: Peng Fan Change-Id: I38b04ef909a6dbfba5ded12a7bb6e799a3935a66 --- plat/imx/common/imx_sip_handler.c | 36 +++++++++++++++++++++++++++++++++++ plat/imx/common/imx_sip_svc.c | 3 +++ plat/imx/common/include/imx_sip_svc.h | 5 +++++ 3 files changed, 44 insertions(+) diff --git a/plat/imx/common/imx_sip_handler.c b/plat/imx/common/imx_sip_handler.c index 62048b696..f9f5577c4 100644 --- a/plat/imx/common/imx_sip_handler.c +++ b/plat/imx/common/imx_sip_handler.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include #include #include #include @@ -12,6 +13,7 @@ #include #include #include +#include #include #if defined(PLAT_imx8qm) || defined(PLAT_imx8qx) @@ -185,3 +187,37 @@ uint64_t imx_buildinfo_handler(uint32_t smc_fid, return ret; } + +int imx_kernel_entry_handler(uint32_t smc_fid, + u_register_t x1, + u_register_t x2, + u_register_t x3, + u_register_t x4) +{ + static entry_point_info_t bl33_image_ep_info; + entry_point_info_t *next_image_info; + unsigned int mode; + + if (x1 < (PLAT_NS_IMAGE_OFFSET & 0xF0000000)) + return SMC_UNK; + + mode = MODE32_svc; + + next_image_info = &bl33_image_ep_info; + + next_image_info->pc = x1; + + next_image_info->spsr = SPSR_MODE32(mode, SPSR_T_ARM, SPSR_E_LITTLE, + (DAIF_FIQ_BIT | DAIF_IRQ_BIT | DAIF_ABT_BIT)); + + next_image_info->args.arg0 = 0; + next_image_info->args.arg1 = 0; + next_image_info->args.arg2 = x3; + + SET_SECURITY_STATE(next_image_info->h.attr, NON_SECURE); + + cm_init_my_context(next_image_info); + cm_prepare_el3_exit(NON_SECURE); + + return 0; +} diff --git a/plat/imx/common/imx_sip_svc.c b/plat/imx/common/imx_sip_svc.c index 4893b9fa5..20e1479fb 100644 --- a/plat/imx/common/imx_sip_svc.c +++ b/plat/imx/common/imx_sip_svc.c @@ -26,6 +26,9 @@ static uintptr_t imx_sip_handler(unsigned int smc_fid, u_register_t flags) { switch (smc_fid) { + case IMX_SIP_AARCH32: + SMC_RET1(handle, imx_kernel_entry_handler(smc_fid, x1, x2, x3, x4)); + break; #if defined(PLAT_imx8mq) case IMX_SIP_GET_SOC_INFO: SMC_RET1(handle, imx_soc_info_handler(smc_fid, x1, x2, x3)); diff --git a/plat/imx/common/include/imx_sip_svc.h b/plat/imx/common/include/imx_sip_svc.h index 5898f7a81..0a2d750f9 100644 --- a/plat/imx/common/include/imx_sip_svc.h +++ b/plat/imx/common/include/imx_sip_svc.h @@ -28,6 +28,11 @@ #define IMX_SIP_MISC_SET_TEMP 0xC200000C +#define IMX_SIP_AARCH32 0xC20000FD + +int imx_kernel_entry_handler(uint32_t smc_fid, u_register_t x1, + u_register_t x2, u_register_t x3, + u_register_t x4); #if defined(PLAT_imx8mq) int imx_soc_info_handler(uint32_t smc_fid, u_register_t x1, u_register_t x2, u_register_t x3); -- cgit v1.2.3 From 4a135bc33e4d22c6666167a2df67bf10caa30d0a Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Mon, 13 Jul 2020 14:59:02 +0100 Subject: plat/arm/board/fvp: Add support for Measured Boot This patch adds support for Measured Boot functionality to FVP platform code. It also defines new properties in 'tpm_event_log' node to store Event Log address and it size 'tpm_event_log_sm_addr' 'tpm_event_log_addr' 'tpm_event_log_size' in 'event_log.dtsi' included in 'fvp_tsp_fw_config.dts' and 'fvp_nt_fw_config.dts'. The node and its properties are described in binding document 'docs\components\measured_boot\event_log.rst'. Change-Id: I087e1423afcb269d6cfe79c1af9c348931991292 Signed-off-by: Alexei Fedorov --- docs/components/index.rst | 1 + docs/components/measured_boot/event_log.rst | 35 ++++++++++++ docs/components/measured_boot/index.rst | 12 ++++ plat/arm/board/fvp/fconf/fconf_nt_config_getter.c | 64 ++++++++++++++++++++++ plat/arm/board/fvp/fdts/event_log.dtsi | 12 ++++ plat/arm/board/fvp/fdts/fvp_nt_fw_config.dts | 10 +++- plat/arm/board/fvp/fdts/fvp_tsp_fw_config.dts | 6 +- plat/arm/board/fvp/fvp_bl1_setup.c | 10 +++- plat/arm/board/fvp/fvp_bl2_setup.c | 46 ++++++++++++++++ plat/arm/board/fvp/fvp_measured_boot.c | 40 ++++++++++++++ .../arm/board/fvp/include/fconf_nt_config_getter.h | 27 +++++++++ plat/arm/board/fvp/include/platform_def.h | 4 +- plat/arm/board/fvp/platform.mk | 5 ++ 13 files changed, 266 insertions(+), 6 deletions(-) create mode 100644 docs/components/measured_boot/event_log.rst create mode 100644 docs/components/measured_boot/index.rst create mode 100644 plat/arm/board/fvp/fconf/fconf_nt_config_getter.c create mode 100644 plat/arm/board/fvp/fdts/event_log.dtsi create mode 100644 plat/arm/board/fvp/fvp_measured_boot.c create mode 100644 plat/arm/board/fvp/include/fconf_nt_config_getter.h diff --git a/docs/components/index.rst b/docs/components/index.rst index 18b1e38bb..b4d8c14f9 100644 --- a/docs/components/index.rst +++ b/docs/components/index.rst @@ -12,6 +12,7 @@ Components exception-handling fconf/index firmware-update + measured_boot/index platform-interrupt-controller-API ras romlib-design diff --git a/docs/components/measured_boot/event_log.rst b/docs/components/measured_boot/event_log.rst new file mode 100644 index 000000000..5347dcc19 --- /dev/null +++ b/docs/components/measured_boot/event_log.rst @@ -0,0 +1,35 @@ +DTB binding for Event Log properties +==================================== + +This document describes the device tree format of Event Log properties. +These properties are not related to a specific platform and can be queried +from common code. + +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: + +- compatible [mandatory] + - value type: + - Must be the string "arm,tpm_event_log". + +Then a list of properties representing Event Log configuration, which +can be used by Measured Boot driver. Each property is named according +to the information it contains: + +- tpm_event_log_sm_addr [fvp_nt_fw_config.dts with OP-TEE] + - value type: + - Event Log base address in secure memory. + +Note. Currently OP-TEE does not support reading DTBs from Secure memory +and this property should be removed when this feature is supported. + +- tpm_event_log_addr [mandatory] + - value type: + - Event Log base address in non-secure memory. + +- tpm_event_log_size [mandatory] + - value type: + - Event Log size. diff --git a/docs/components/measured_boot/index.rst b/docs/components/measured_boot/index.rst new file mode 100644 index 000000000..e7f2634bb --- /dev/null +++ b/docs/components/measured_boot/index.rst @@ -0,0 +1,12 @@ +Measured Boot Driver (MBD) +========================== + +.. _measured-boot-document: + +Properties binding information +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. toctree:: + :maxdepth: 1 + + event_log diff --git a/plat/arm/board/fvp/fconf/fconf_nt_config_getter.c b/plat/arm/board/fvp/fconf/fconf_nt_config_getter.c new file mode 100644 index 000000000..e25801520 --- /dev/null +++ b/plat/arm/board/fvp/fconf/fconf_nt_config_getter.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include + +#include + +struct event_log_config_t event_log_config; + +int fconf_populate_event_log_config(uintptr_t config) +{ + int err; + int node; + + /* Necessary to work with libfdt APIs */ + const void *dtb = (const void *)config; + + /* + * Find the offset of the node containing "arm,tpm_event_log" + * compatible property + */ + const char *compatible_str = "arm,tpm_event_log"; + + 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; + } + + /* Retrieve Event Log details from the DTB */ +#ifdef SPD_opteed + err = fdtw_read_cells(dtb, node, "tpm_event_log_sm_addr", 2, + &event_log_config.tpm_event_log_sm_addr); + if (err < 0) { + ERROR("FCONF: Read cell failed for 'tpm_event_log_sm_addr'\n"); + return err; + } +#endif + err = fdtw_read_cells(dtb, node, + "tpm_event_log_addr", 2, &event_log_config.tpm_event_log_addr); + if (err < 0) { + ERROR("FCONF: Read cell failed for 'tpm_event_log_addr'\n"); + return err; + } + + err = fdtw_read_cells(dtb, node, + "tpm_event_log_size", 1, &event_log_config.tpm_event_log_size); + if (err < 0) { + ERROR("FCONF: Read cell failed for 'tpm_event_log_size'\n"); + } + + return err; +} + +FCONF_REGISTER_POPULATOR(NT_CONFIG, event_log_config, + fconf_populate_event_log_config); diff --git a/plat/arm/board/fvp/fdts/event_log.dtsi b/plat/arm/board/fvp/fdts/event_log.dtsi new file mode 100644 index 000000000..47af672df --- /dev/null +++ b/plat/arm/board/fvp/fdts/event_log.dtsi @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* TPM Event Log Config */ +event_log: tpm_event_log { + compatible = "arm,tpm_event_log"; + tpm_event_log_addr = <0x0 0x0>; + tpm_event_log_size = <0x0>; +}; diff --git a/plat/arm/board/fvp/fdts/fvp_nt_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_nt_fw_config.dts index 7ab980b1b..8f32b9880 100644 --- a/plat/arm/board/fvp/fdts/fvp_nt_fw_config.dts +++ b/plat/arm/board/fvp/fdts/fvp_nt_fw_config.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,5 +7,13 @@ /dts-v1/; / { +#if MEASURED_BOOT +#include "event_log.dtsi" +#endif +}; +#if MEASURED_BOOT && defined(SPD_opteed) +&event_log { + tpm_event_log_sm_addr = <0x0 0x0>; }; +#endif diff --git a/plat/arm/board/fvp/fdts/fvp_tsp_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_tsp_fw_config.dts index 7ab980b1b..7bed6cb3b 100644 --- a/plat/arm/board/fvp/fdts/fvp_tsp_fw_config.dts +++ b/plat/arm/board/fvp/fdts/fvp_tsp_fw_config.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,5 +7,7 @@ /dts-v1/; / { - +#if MEASURED_BOOT +#include "event_log.dtsi" +#endif }; diff --git a/plat/arm/board/fvp/fvp_bl1_setup.c b/plat/arm/board/fvp/fvp_bl1_setup.c index d13cc81f3..0e77c4dcc 100644 --- a/plat/arm/board/fvp/fvp_bl1_setup.c +++ b/plat/arm/board/fvp/fvp_bl1_setup.c @@ -69,6 +69,14 @@ __dead2 void bl1_plat_fwu_done(void *client_cookie, void *reserved) } #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 @@ -90,7 +98,7 @@ int bl1_plat_handle_post_image_load(unsigned int image_id) assert(image_desc != NULL); /* Calculate BL2 hash and set it in TB_FW_CONFIG */ - arm_bl1_set_bl2_hash(image_desc); + bl1_plat_set_bl2_hash(image_desc); /* Get the entry point info */ ep_info = &image_desc->ep_info; diff --git a/plat/arm/board/fvp/fvp_bl2_setup.c b/plat/arm/board/fvp/fvp_bl2_setup.c index d5618d99b..f2f21432d 100644 --- a/plat/arm/board/fvp/fvp_bl2_setup.c +++ b/plat/arm/board/fvp/fvp_bl2_setup.c @@ -6,8 +6,12 @@ #include +#include #include #include +#if MEASURED_BOOT +#include +#endif #include #include @@ -69,3 +73,45 @@ 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 = tpm_record_measurement(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 new file mode 100644 index 000000000..b145aae58 --- /dev/null +++ b/plat/arm/board/fvp/fvp_measured_boot.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +/* 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 */ + { 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 }, + { GPT_IMAGE_ID, GPT_IMAGE_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 }, + { STM32_IMAGE_ID, STM32_IMAGE_STRING, PCR_0 }, + { TOS_FW_CONFIG_ID, TOS_FW_CONFIG_STRING, PCR_0 }, + { 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) +{ + return &fvp_measured_boot_data; +} diff --git a/plat/arm/board/fvp/include/fconf_nt_config_getter.h b/plat/arm/board/fvp/include/fconf_nt_config_getter.h new file mode 100644 index 000000000..0824c3509 --- /dev/null +++ b/plat/arm/board/fvp/include/fconf_nt_config_getter.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FCONF_NT_CONFIG_GETTER_H +#define FCONF_NT_CONFIG_GETTER_H + +#include + +/* NT Firmware Config related getter */ +#define nt_config__event_log_config_getter(prop) event_log.prop + +struct event_log_config_t { +#ifdef SPD_opteed + void *tpm_event_log_sm_addr; +#endif + void *tpm_event_log_addr; + size_t tpm_event_log_size; +}; + +int fconf_populate_event_log_config(uintptr_t config); + +extern struct event_log_config_t event_log_config; + +#endif /* FCONF_NT_CONFIG_GETTER_H */ diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h index f8fb821b3..a9860174a 100644 --- a/plat/arm/board/fvp/include/platform_def.h +++ b/plat/arm/board/fvp/include/platform_def.h @@ -243,8 +243,8 @@ /* * GIC related constants to cater for both GICv2 and GICv3 instances of an - * FVP. They could be overriden at runtime in case the FVP implements the legacy - * VE memory map. + * FVP. They could be overridden at runtime in case the FVP implements the + * legacy VE memory map. */ #define PLAT_ARM_GICD_BASE BASE_GICD_BASE #define PLAT_ARM_GICR_BASE BASE_GICR_BASE diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 9b8fccc55..98c70c956 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -354,6 +354,11 @@ include plat/arm/common/arm_common.mk ifeq (${TRUSTED_BOARD_BOOT}, 1) 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 +endif + # FVP being a development platform, enable capability to disable Authentication # dynamically if TRUSTED_BOARD_BOOT is set. DYN_DISABLE_AUTH := 1 -- cgit v1.2.3 From e09559fd7d1eabe78863849e113b389f79728858 Mon Sep 17 00:00:00 2001 From: Vijayenthiran Subramaniam Date: Wed, 22 Jul 2020 22:08:28 +0530 Subject: docs/fvp: update SGI and RD FVP list Update SGI-575, RD-E1-Edge and RD-N1-Edge FVP versions to 11.10/36 and add RD-N1-Edge-Dual to the list of supported Arm Fixed Virtual Platforms. Change-Id: I9e7e5662324eeefc80d799ca5341b5bc4dc39cbb Signed-off-by: Vijayenthiran Subramaniam --- docs/plat/arm/fvp/index.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/plat/arm/fvp/index.rst b/docs/plat/arm/fvp/index.rst index a6ff19a25..fd658bbff 100644 --- a/docs/plat/arm/fvp/index.rst +++ b/docs/plat/arm/fvp/index.rst @@ -42,10 +42,11 @@ Arm FVPs without shifted affinities, and that do not support threaded CPU cores - ``FVP_Base_Neoverse-E1x4`` - ``FVP_Base_Neoverse-N1x4`` - ``FVP_Base_Zeusx4`` -- ``FVP_CSS_SGI-575`` (Version 11.10 build 25) +- ``FVP_CSS_SGI-575`` (Version 11.10 build 36) - ``FVP_CSS_SGM-775`` -- ``FVP_RD_E1Edge`` -- ``FVP_RD_N1Edge`` (Version 11.10 build 25) +- ``FVP_RD_E1_edge`` (Version 11.10 build 36) +- ``FVP_RD_N1_edge`` (Version 11.10 build 36) +- ``FVP_RD_N1_edge_dual`` (Version 11.10 build 36) - ``Foundation_Platform`` The latest version of the AArch32 build of TF-A has been tested on the -- cgit v1.2.3 From d958f37d509e3a3b986f6eae09314b4d860274ce Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Tue, 14 Jul 2020 11:16:02 +0100 Subject: plat/arm: sgm: Use consistent name for tb fw config node Renamed node for trusted boot fw config from 'plat_arm_bl2' to 'tb_fw-config'. Change-Id: I2e16b6f4d272292ec1855daafd014e851436dd9b Signed-off-by: Manish V Badarkhe --- plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts b/plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts index e41654048..54b2423c1 100644 --- a/plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts +++ b/plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts @@ -8,7 +8,7 @@ / { /* Platform Config */ - plat_arm_bl2 { + tb_fw-config { compatible = "arm,tb_fw"; hw_config_addr = <0x0 0x83000000>; hw_config_max_size = <0x01000000>; -- cgit v1.2.3 From a249a9d9e7b4a48c4080abad02b748479dafef52 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Tue, 14 Jul 2020 11:28:36 +0100 Subject: plat/arm: Check the need for firmware update only once Currently, the need for firmware update is being checked twice in the code hence modifications are done to do this check only once and set the global variable. Then this global variable helps to decide whether to go for normal boot or firmware update flow. Change-Id: I8469284555a8039786f34670f9dc4830f87aecc1 Signed-off-by: Manish V Badarkhe --- plat/arm/common/arm_bl1_setup.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c index 6b630b980..af4b4c917 100644 --- a/plat/arm/common/arm_bl1_setup.c +++ b/plat/arm/common/arm_bl1_setup.c @@ -54,6 +54,9 @@ /* Data structure which holds the extents of the trusted SRAM for BL1*/ static meminfo_t bl1_tzram_layout; +/* Boolean variable to hold condition whether firmware update needed or not */ +static bool is_fwu_needed; + struct meminfo *bl1_plat_sec_mem_layout(void) { return &bl1_tzram_layout; @@ -152,8 +155,8 @@ void arm_bl1_platform_setup(void) plat_arm_io_setup(); /* Check if we need FWU before further processing */ - err = plat_arm_bl1_fwu_needed(); - if (err) { + is_fwu_needed = plat_arm_bl1_fwu_needed(); + if (is_fwu_needed) { ERROR("Skip platform setup as FWU detected\n"); return; } @@ -247,5 +250,5 @@ bool plat_arm_bl1_fwu_needed(void) ******************************************************************************/ unsigned int bl1_plat_get_next_image_id(void) { - return plat_arm_bl1_fwu_needed() ? NS_BL1U_IMAGE_ID : BL2_IMAGE_ID; + return is_fwu_needed ? NS_BL1U_IMAGE_ID : BL2_IMAGE_ID; } -- cgit v1.2.3 From a4ff9d7e1ee4ccd66824c1e4be08727012c99123 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Wed, 15 Jul 2020 04:27:57 +0100 Subject: lib/fconf: Update data type of config max size Update the data type of the member 'config_max_size' present in the structure 'dyn_cfg_dtb_info_t' to uint32_t. This change is being done so that dyn_cfg_dtb_info_t and image_info structure should use same data type for maximum size. Change-Id: I9b5927a47eb8351bbf3664b8b1e047ae1ae5a260 Signed-off-by: Manish V Badarkhe --- include/lib/fconf/fconf_dyn_cfg_getter.h | 2 +- lib/fconf/fconf.c | 3 +-- lib/fconf/fconf_dyn_cfg_getter.c | 2 +- plat/arm/common/arm_dyn_cfg.c | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/include/lib/fconf/fconf_dyn_cfg_getter.h b/include/lib/fconf/fconf_dyn_cfg_getter.h index 9816d6fe0..6e0e7fd59 100644 --- a/include/lib/fconf/fconf_dyn_cfg_getter.h +++ b/include/lib/fconf/fconf_dyn_cfg_getter.h @@ -14,7 +14,7 @@ struct dyn_cfg_dtb_info_t { uintptr_t config_addr; - size_t config_max_size; + uint32_t config_max_size; unsigned int config_id; }; diff --git a/lib/fconf/fconf.c b/lib/fconf/fconf.c index bc4fa8ea8..24b6bcc55 100644 --- a/lib/fconf/fconf.c +++ b/lib/fconf/fconf.c @@ -32,8 +32,7 @@ int fconf_load_config(unsigned int image_id) assert(config_info != NULL); config_image_info.image_base = config_info->config_addr; - config_image_info.image_max_size = - (uint32_t)config_info->config_max_size; + config_image_info.image_max_size = config_info->config_max_size; VERBOSE("FCONF: Loading config with image ID: %d\n", image_id); err = load_auth_image(image_id, &config_image_info); diff --git a/lib/fconf/fconf_dyn_cfg_getter.c b/lib/fconf/fconf_dyn_cfg_getter.c index 16bbe42c8..38a85f526 100644 --- a/lib/fconf/fconf_dyn_cfg_getter.c +++ b/lib/fconf/fconf_dyn_cfg_getter.c @@ -125,7 +125,7 @@ int fconf_populate_dtb_registry(uintptr_t config) VERBOSE("FCONF: dyn_cfg.dtb_registry cell found with:\n"); VERBOSE("\tload-address = %lx\n", dtb_info->config_addr); - VERBOSE("\tmax-size = 0x%zx\n", dtb_info->config_max_size); + VERBOSE("\tmax-size = 0x%x\n", dtb_info->config_max_size); VERBOSE("\tconfig-id = %u\n", dtb_info->config_id); } diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c index b31870b6d..6b3a61180 100644 --- a/plat/arm/common/arm_dyn_cfg.c +++ b/plat/arm/common/arm_dyn_cfg.c @@ -203,7 +203,7 @@ void arm_bl2_dyn_cfg_init(void) unsigned int i; bl_mem_params_node_t *cfg_mem_params = NULL; uintptr_t image_base; - size_t image_size; + uint32_t image_size; const unsigned int config_ids[] = { HW_CONFIG_ID, SOC_FW_CONFIG_ID, -- cgit v1.2.3 From f441718936a6b72583d03eebf8057bbf29446989 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Wed, 15 Jul 2020 05:08:37 +0100 Subject: lib/fconf: Update 'set_fw_config_info' function Updated the function 'set_fw_config_info' to make it generic by doing below changes: 1. Rename function name from 'set_fw_config_info' to 'set_config_info' 2. Take image_id as an argument so that this function can set any config information. Signed-off-by: Manish V Badarkhe Change-Id: Icf29e19d3e9996d8154d84dbbbc76712fab0f0c1 --- include/lib/fconf/fconf_dyn_cfg_getter.h | 5 ++- lib/fconf/fconf_dyn_cfg_getter.c | 68 ++++++++++++++------------------ plat/arm/common/arm_bl1_setup.c | 2 +- 3 files changed, 33 insertions(+), 42 deletions(-) diff --git a/include/lib/fconf/fconf_dyn_cfg_getter.h b/include/lib/fconf/fconf_dyn_cfg_getter.h index 6e0e7fd59..6f8da0d78 100644 --- a/include/lib/fconf/fconf_dyn_cfg_getter.h +++ b/include/lib/fconf/fconf_dyn_cfg_getter.h @@ -21,7 +21,8 @@ struct dyn_cfg_dtb_info_t { struct dyn_cfg_dtb_info_t *dyn_cfg_dtb_info_getter(unsigned int config_id); int fconf_populate_dtb_registry(uintptr_t config); -/* Set fw_config information in global DTB array */ -void set_fw_config_info(uintptr_t config_addr, uint32_t config_max_size); +/* Set config information in global DTB array */ +void set_config_info(uintptr_t config_addr, uint32_t config_max_size, + unsigned int config_id); #endif /* FCONF_DYN_CFG_GETTER_H */ diff --git a/lib/fconf/fconf_dyn_cfg_getter.c b/lib/fconf/fconf_dyn_cfg_getter.c index 38a85f526..25dd7f9ed 100644 --- a/lib/fconf/fconf_dyn_cfg_getter.c +++ b/lib/fconf/fconf_dyn_cfg_getter.c @@ -14,63 +14,56 @@ /* We currently use FW, TB_FW, SOC_FW, TOS_FW, NT_FW and HW configs */ #define MAX_DTB_INFO U(6) +/* + * Compile time assert if FW_CONFIG_ID is 0 which is more + * unlikely as 0 is a valid image ID for FIP as per the current + * code but still to avoid code breakage in case of unlikely + * event when image IDs get changed. + */ +CASSERT(FW_CONFIG_ID != U(0), assert_invalid_fw_config_id); static struct dyn_cfg_dtb_info_t dtb_infos[MAX_DTB_INFO]; static OBJECT_POOL_ARRAY(dtb_info_pool, dtb_infos); /* - * This function is used to alloc memory for fw config information from - * global pool and set fw configuration information. - * Specifically used by BL1 to set fw_config information in global array + * This function is used to alloc memory for config information from + * global pool and set the configuration information. */ -void set_fw_config_info(uintptr_t config_addr, uint32_t config_max_size) +void set_config_info(uintptr_t config_addr, uint32_t config_max_size, + unsigned int config_id) { struct dyn_cfg_dtb_info_t *dtb_info; dtb_info = pool_alloc(&dtb_info_pool); dtb_info->config_addr = config_addr; dtb_info->config_max_size = config_max_size; - dtb_info->config_id = FW_CONFIG_ID; + dtb_info->config_id = config_id; } struct dyn_cfg_dtb_info_t *dyn_cfg_dtb_info_getter(unsigned int config_id) { unsigned int index; - struct dyn_cfg_dtb_info_t *info; /* Positions index to the proper config-id */ - for (index = 0; index < MAX_DTB_INFO; index++) { + for (index = 0U; index < MAX_DTB_INFO; index++) { if (dtb_infos[index].config_id == config_id) { - info = &dtb_infos[index]; - break; + return &dtb_infos[index]; } } - if (index == MAX_DTB_INFO) { - WARN("FCONF: Invalid config id %u\n", config_id); - info = NULL; - } + WARN("FCONF: Invalid config id %u\n", config_id); - return info; + return NULL; } int fconf_populate_dtb_registry(uintptr_t config) { int rc; int node, child; - struct dyn_cfg_dtb_info_t *dtb_info; /* As libfdt use void *, we can't avoid this cast */ const void *dtb = (void *)config; - /* - * Compile time assert if FW_CONFIG_ID is 0 which is more - * unlikely as 0 is a valid image id for FIP as per the current - * code but still to avoid code breakage in case of unlikely - * event when image ids gets changed. - */ - CASSERT(FW_CONFIG_ID != 0, assert_invalid_fw_config_id); - /* * In case of BL1, fw_config dtb information is already * populated in global dtb_infos array by 'set_fw_config_info' @@ -80,11 +73,9 @@ int fconf_populate_dtb_registry(uintptr_t config) * Other BLs, satisfy below check and populate fw_config information * in global dtb_infos array. */ - if (dtb_infos[0].config_id == 0) { - dtb_info = pool_alloc(&dtb_info_pool); - dtb_info->config_addr = config; - dtb_info->config_max_size = fdt_totalsize(dtb); - dtb_info->config_id = FW_CONFIG_ID; + if (dtb_infos[0].config_id == 0U) { + uint32_t config_max_size = fdt_totalsize(dtb); + set_config_info(config, config_max_size, FW_CONFIG_ID); } /* Find the node offset point to "fconf,dyn_cfg-dtb_registry" compatible property */ @@ -96,37 +87,36 @@ int fconf_populate_dtb_registry(uintptr_t config) } fdt_for_each_subnode(child, dtb, node) { - uint32_t val32; + uint32_t config_max_size, config_id; + uintptr_t config_addr; uint64_t val64; - dtb_info = pool_alloc(&dtb_info_pool); - /* Read configuration dtb information */ rc = fdt_read_uint64(dtb, child, "load-address", &val64); if (rc < 0) { ERROR("FCONF: Incomplete configuration property in dtb-registry.\n"); return rc; } - dtb_info->config_addr = (uintptr_t)val64; + config_addr = (uintptr_t)val64; - rc = fdt_read_uint32(dtb, child, "max-size", &val32); + rc = fdt_read_uint32(dtb, child, "max-size", &config_max_size); if (rc < 0) { ERROR("FCONF: Incomplete configuration property in dtb-registry.\n"); return rc; } - dtb_info->config_max_size = val32; - rc = fdt_read_uint32(dtb, child, "id", &val32); + rc = fdt_read_uint32(dtb, child, "id", &config_id); if (rc < 0) { ERROR("FCONF: Incomplete configuration property in dtb-registry.\n"); return rc; } - dtb_info->config_id = val32; VERBOSE("FCONF: dyn_cfg.dtb_registry cell found with:\n"); - VERBOSE("\tload-address = %lx\n", dtb_info->config_addr); - VERBOSE("\tmax-size = 0x%x\n", dtb_info->config_max_size); - VERBOSE("\tconfig-id = %u\n", dtb_info->config_id); + VERBOSE("\tload-address = %lx\n", config_addr); + VERBOSE("\tmax-size = 0x%x\n", config_max_size); + VERBOSE("\tconfig-id = %u\n", config_id); + + set_config_info(config_addr, config_max_size, config_id); } if ((child < 0) && (child != -FDT_ERR_NOTFOUND)) { diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c index af4b4c917..4b2a062f9 100644 --- a/plat/arm/common/arm_bl1_setup.c +++ b/plat/arm/common/arm_bl1_setup.c @@ -163,7 +163,7 @@ void arm_bl1_platform_setup(void) /* Set global DTB info for fixed fw_config information */ fw_config_max_size = ARM_FW_CONFIG_LIMIT - ARM_FW_CONFIG_BASE; - set_fw_config_info(ARM_FW_CONFIG_BASE, fw_config_max_size); + set_config_info(ARM_FW_CONFIG_BASE, fw_config_max_size, FW_CONFIG_ID); /* Fill the device tree information struct with the info from the config dtb */ err = fconf_load_config(FW_CONFIG_ID); -- cgit v1.2.3 From a07c101a4dfa530b64288b27ac38958b0490b5c4 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Thu, 16 Jul 2020 05:45:25 +0100 Subject: plat/arm: Move fconf population after the enablement of MMU In BL2, fw_config's population happened before the cache gets enabled. Hence to boost the performance, moved fw_config's population after cache gets enabled (i.e. after MMU gets enabled). Signed-off-by: Manish V Badarkhe Change-Id: I2e75cabd76b1cb7a660f6b72f409ab40d2877284 --- include/plat/arm/common/arm_def.h | 9 +++++++- plat/arm/board/a5ds/include/platform_def.h | 18 +++++++++++++++- .../corstone700/common/include/platform_def.h | 23 +++++++++++++++++++- plat/arm/board/fvp_ve/include/platform_def.h | 22 +++++++++++++++++-- plat/arm/common/arm_bl2_setup.c | 25 ++++++++++++++-------- 5 files changed, 83 insertions(+), 14 deletions(-) diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index 139145b6b..293e7ce6f 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -294,12 +294,19 @@ #define ARM_V2M_MAP_MEM_PROTECT MAP_REGION_FLAT(PLAT_ARM_MEM_PROT_ADDR, \ V2M_FLASH_BLOCK_SIZE, \ MT_DEVICE | MT_RW | MT_SECURE) +/* + * Map the region for device tree configuration with read and write permissions + */ +#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) /* * The max number of regions like RO(code), coherent and data required by * different BL stages which need to be mapped in the MMU. */ -#define ARM_BL_REGIONS 5 +#define ARM_BL_REGIONS 6 #define MAX_MMAP_REGIONS (PLAT_ARM_MMAP_ENTRIES + \ ARM_BL_REGIONS) diff --git a/plat/arm/board/a5ds/include/platform_def.h b/plat/arm/board/a5ds/include/platform_def.h index 07453166a..792a754fa 100644 --- a/plat/arm/board/a5ds/include/platform_def.h +++ b/plat/arm/board/a5ds/include/platform_def.h @@ -151,11 +151,19 @@ MT_DEVICE | MT_RW | MT_SECURE) #endif +/* + * Map the region for device tree configuration with read and write permissions + */ +#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) + /* * The max number of regions like RO(code), coherent and data required by * different BL stages which need to be mapped in the MMU. */ -#define ARM_BL_REGIONS 5 +#define ARM_BL_REGIONS 6 #define MAX_MMAP_REGIONS (PLAT_ARM_MMAP_ENTRIES + \ ARM_BL_REGIONS) @@ -194,6 +202,12 @@ #define ARM_FW_CONFIG_BASE (ARM_BL_RAM_BASE + sizeof(meminfo_t)) #define ARM_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + PAGE_SIZE) +/* + * Define limit of firmware configuration memory: + * ARM_FW_CONFIG + ARM_BL2_MEM_DESC memory + */ +#define ARM_FW_CONFIGS_LIMIT (ARM_BL_RAM_BASE + (PAGE_SIZE * 2)) + /******************************************************************************* * BL1 specific defines. * BL1 RW data is relocated from ROM to RAM at runtime so we need 2 sets of @@ -221,6 +235,8 @@ /* Put BL32 below BL2 in NS DRAM.*/ #define ARM_BL2_MEM_DESC_BASE ARM_FW_CONFIG_LIMIT +#define ARM_BL2_MEM_DESC_LIMIT (ARM_BL2_MEM_DESC_BASE \ + + (PAGE_SIZE / 2U)) #define BL32_BASE ((ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE)\ - PLAT_ARM_MAX_BL32_SIZE) diff --git a/plat/arm/board/corstone700/common/include/platform_def.h b/plat/arm/board/corstone700/common/include/platform_def.h index c92086c18..57b0551b3 100644 --- a/plat/arm/board/corstone700/common/include/platform_def.h +++ b/plat/arm/board/corstone700/common/include/platform_def.h @@ -92,11 +92,24 @@ #define ARM_FW_CONFIG_BASE (ARM_BL_RAM_BASE + sizeof(meminfo_t)) #define ARM_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + (PAGE_SIZE / 2U)) +/* + * Boot parameters passed from BL2 to BL31/BL32 are stored here + */ +#define ARM_BL2_MEM_DESC_BASE (ARM_FW_CONFIG_LIMIT) +#define ARM_BL2_MEM_DESC_LIMIT (ARM_BL2_MEM_DESC_BASE \ + + (PAGE_SIZE / 2U)) + +/* + * Define limit of firmware configuration memory: + * ARM_FW_CONFIG + ARM_BL2_MEM_DESC memory + */ +#define ARM_FW_CONFIGS_LIMIT (ARM_BL_RAM_BASE + (PAGE_SIZE * 2)) + /* * The max number of regions like RO(code), coherent and data required by * different BL stages which need to be mapped in the MMU. */ -#define ARM_BL_REGIONS 2 +#define ARM_BL_REGIONS 3 #define PLAT_ARM_MMAP_ENTRIES 8 #define MAX_XLAT_TABLES 5 #define MAX_MMAP_REGIONS (PLAT_ARM_MMAP_ENTRIES + \ @@ -201,6 +214,14 @@ MT_DEVICE | MT_RW | MT_SECURE) #endif +/* + * Map the region for device tree configuration with read and write permissions + */ +#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) + #define CORSTONE700_DEVICE_BASE (0x1A000000) #define CORSTONE700_DEVICE_SIZE (0x26000000) #define CORSTONE700_MAP_DEVICE MAP_REGION_FLAT( \ diff --git a/plat/arm/board/fvp_ve/include/platform_def.h b/plat/arm/board/fvp_ve/include/platform_def.h index 3591b4d6d..3f2fcee58 100644 --- a/plat/arm/board/fvp_ve/include/platform_def.h +++ b/plat/arm/board/fvp_ve/include/platform_def.h @@ -120,11 +120,20 @@ MT_DEVICE | MT_RW | MT_SECURE) #endif +/* + * Map the region for device tree configuration with read and write permissions + */ +#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) + + /* * The max number of regions like RO(code), coherent and data required by * different BL stages which need to be mapped in the MMU. */ -#define ARM_BL_REGIONS 5 +#define ARM_BL_REGIONS 6 #define MAX_MMAP_REGIONS (PLAT_ARM_MMAP_ENTRIES + \ ARM_BL_REGIONS) @@ -173,7 +182,14 @@ * and limit. Leave enough space of BL2 meminfo. */ #define ARM_FW_CONFIG_BASE (ARM_BL_RAM_BASE + sizeof(meminfo_t)) -#define ARM_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + PAGE_SIZE) +#define ARM_FW_CONFIG_LIMIT ((ARM_BL_RAM_BASE + PAGE_SIZE) \ + + (PAGE_SIZE / 2U)) + +/* + * Define limit of firmware configuration memory: + * ARM_FW_CONFIG + ARM_BL2_MEM_DESC memory + */ +#define ARM_FW_CONFIGS_LIMIT (ARM_BL_RAM_BASE + (PAGE_SIZE * 2)) /******************************************************************************* * BL1 specific defines. @@ -205,6 +221,8 @@ /* Put BL32 below BL2 in NS DRAM.*/ #define ARM_BL2_MEM_DESC_BASE ARM_FW_CONFIG_LIMIT +#define ARM_BL2_MEM_DESC_LIMIT (ARM_BL2_MEM_DESC_BASE \ + + (PAGE_SIZE / 2U)) #define BL32_BASE ((ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE)\ - PLAT_ARM_MAX_BL32_SIZE) diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c index 80f3b32ee..60d8f6ef3 100644 --- a/plat/arm/common/arm_bl2_setup.c +++ b/plat/arm/common/arm_bl2_setup.c @@ -26,6 +26,9 @@ /* Data structure which holds the extents of the trusted SRAM for BL2 */ static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE); +/* Base address of fw_config received from BL1 */ +static uintptr_t fw_config_base; + /* * Check that BL2_BASE is above ARM_FW_CONFIG_LIMIT. This reserved page is * for `meminfo_t` data structure and fw_configs passed from BL1. @@ -57,21 +60,13 @@ CASSERT(BL2_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl2_base_overflows); void arm_bl2_early_platform_setup(uintptr_t fw_config, struct meminfo *mem_layout) { - const struct dyn_cfg_dtb_info_t *tb_fw_config_info; /* Initialize the console to provide early debug support */ arm_console_boot_init(); /* Setup the BL2 memory layout */ bl2_tzram_layout = *mem_layout; - /* Fill the properties struct with the info from the config dtb */ - fconf_populate("FW_CONFIG", fw_config); - - /* TB_FW_CONFIG was also loaded by BL1 */ - tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID); - assert(tb_fw_config_info != NULL); - - fconf_populate("TB_FW", tb_fw_config_info->config_addr); + fw_config_base = fw_config; /* Initialise the IO layer and register platform IO devices */ plat_arm_io_setup(); @@ -135,6 +130,7 @@ void arm_bl2_plat_arch_setup(void) #if ARM_CRYPTOCELL_INTEG ARM_MAP_BL_COHERENT_RAM, #endif + ARM_MAP_BL_CONFIG_REGION, {0} }; @@ -151,7 +147,18 @@ void arm_bl2_plat_arch_setup(void) void bl2_plat_arch_setup(void) { + const struct dyn_cfg_dtb_info_t *tb_fw_config_info; + arm_bl2_plat_arch_setup(); + + /* Fill the properties struct with the info from the config dtb */ + fconf_populate("FW_CONFIG", fw_config_base); + + /* TB_FW_CONFIG was also loaded by BL1 */ + tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID); + assert(tb_fw_config_info != NULL); + + fconf_populate("TB_FW", tb_fw_config_info->config_addr); } int arm_bl2_handle_post_image_load(unsigned int image_id) -- cgit v1.2.3 From e6e7d71285936ca8fb7c804df2c8d63d9f077b0f Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Thu, 23 Jul 2020 18:35:49 +0100 Subject: TF-A Aarch32: optimise memcpy4() This patch makes optimisation of Aarch32 memcpy4() function. Change-Id: If9cdaa4a1224f88fb14df8a308a645344b6c4f1c Signed-off-by: Alexei Fedorov --- lib/aarch32/misc_helpers.S | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/aarch32/misc_helpers.S b/lib/aarch32/misc_helpers.S index 6d2ec1c52..e9734ac2c 100644 --- a/lib/aarch32/misc_helpers.S +++ b/lib/aarch32/misc_helpers.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -149,17 +149,16 @@ m_loop4: blo m_loop1 ldr r3, [r1], #4 str r3, [r0], #4 - sub r2, r2, #4 - b m_loop4 + subs r2, r2, #4 + bne m_loop4 + bx lr + /* copy byte per byte */ m_loop1: - cmp r2,#0 - beq m_end ldrb r3, [r1], #1 strb r3, [r0], #1 subs r2, r2, #1 bne m_loop1 -m_end: bx lr endfunc memcpy4 -- cgit v1.2.3 From f0bbaebc7ec00950908083e41352e856b65057f4 Mon Sep 17 00:00:00 2001 From: johpow01 Date: Thu, 23 Jul 2020 13:05:45 -0500 Subject: Revert workaround for Neoverse N1 erratum 1800710 This reverts commit 11af40b6308ac75c83e874129bb79bc3a58060bf, reversing changes made to 2afcf1d4b845272791b75c8285108c4dcd91e2b9. This errata workaround did not work as intended so we are reverting this change. In the future, when the corrected workaround is published in an SDEN, we will push a new workaround. This is the patch being reverted: https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/4750 Signed-off-by: John Powell Change-Id: I20aa064c1bac9671939e657bec269d32b9e75a97 --- docs/design/cpu-specific-build-macros.rst | 3 --- include/lib/cpus/aarch64/neoverse_n1.h | 1 - lib/cpus/aarch64/neoverse_n1.S | 35 ------------------------------- lib/cpus/cpu-ops.mk | 8 ------- 4 files changed, 47 deletions(-) diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst index 78a80f645..6b6c63933 100644 --- a/docs/design/cpu-specific-build-macros.rst +++ b/docs/design/cpu-specific-build-macros.rst @@ -278,9 +278,6 @@ For Neoverse N1, the following errata build flags are defined : - ``ERRATA_N1_1542419``: This applies errata 1542419 workaround to Neoverse-N1 CPU. This needs to be enabled only for revisions r3p0 - r4p0 of the CPU. -- ``ERRATA_N1_1800710``: This applies errata 1800710 workaround to Neoverse-N1 - CPU. This needs to be enabled only for revisions <= r4p0 of the CPU. - DSU Errata Workarounds ---------------------- diff --git a/include/lib/cpus/aarch64/neoverse_n1.h b/include/lib/cpus/aarch64/neoverse_n1.h index 155a90e0d..b50befa8d 100644 --- a/include/lib/cpus/aarch64/neoverse_n1.h +++ b/include/lib/cpus/aarch64/neoverse_n1.h @@ -35,7 +35,6 @@ #define NEOVERSE_N1_WS_THR_L2_MASK (ULL(3) << 24) #define NEOVERSE_N1_CPUECTLR_EL1_MM_TLBPF_DIS_BIT (ULL(1) << 51) -#define NEOVERSE_N1_CPUECTLR_EL1_BIT_53 (ULL(1) << 53) #define NEOVERSE_N1_CPUECTLR_EL1_EXTLLC_BIT (ULL(1) << 0) /******************************************************************************* diff --git a/lib/cpus/aarch64/neoverse_n1.S b/lib/cpus/aarch64/neoverse_n1.S index 0f80de143..d537ed6a8 100644 --- a/lib/cpus/aarch64/neoverse_n1.S +++ b/lib/cpus/aarch64/neoverse_n1.S @@ -375,35 +375,6 @@ func check_errata_1542419 b cpu_rev_var_range endfunc check_errata_1542419 -/* -------------------------------------------------- - * Errata Workaround for Neoverse N1 Erratum 1800710. - * This applies to revisions <= r4p0 of Neoverse N1 - * Inputs: - * x0: variant[4:7] and revision[0:3] of current cpu. - * Shall clobber: x0-x17 - * -------------------------------------------------- - */ -func errata_n1_1800710_wa - /* Compare x0 against revision <= r4p0 */ - mov x17, x30 - bl check_errata_1800710 - cbz x0, 1f - - /* Disable allocation of splintered pages in the L2 TLB */ - mrs x1, NEOVERSE_N1_CPUECTLR_EL1 - orr x1, x1, NEOVERSE_N1_CPUECTLR_EL1_BIT_53 - msr NEOVERSE_N1_CPUECTLR_EL1, x1 - isb -1: - ret x17 -endfunc errata_n1_1800710_wa - -func check_errata_1800710 - /* Applies to everything <= r4p0 */ - mov x1, #0x40 - b cpu_rev_var_ls -endfunc check_errata_1800710 - func neoverse_n1_reset_func mov x19, x30 @@ -478,11 +449,6 @@ func neoverse_n1_reset_func bl errata_n1_1542419_wa #endif -#if ERRATA_N1_1800710 - mov x0, x18 - bl errata_n1_1800710_wa -#endif - #if ENABLE_AMU /* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */ mrs x0, actlr_el3 @@ -556,7 +522,6 @@ func neoverse_n1_errata_report report_errata ERRATA_N1_1275112, neoverse_n1, 1275112 report_errata ERRATA_N1_1315703, neoverse_n1, 1315703 report_errata ERRATA_N1_1542419, neoverse_n1, 1542419 - report_errata ERRATA_N1_1800710, neoverse_n1, 1800710 report_errata ERRATA_DSU_936184, neoverse_n1, dsu_936184 ldp x8, x30, [sp], #16 diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk index 3c895f585..e49437569 100644 --- a/lib/cpus/cpu-ops.mk +++ b/lib/cpus/cpu-ops.mk @@ -314,10 +314,6 @@ ERRATA_N1_1315703 ?=0 # to revisions r3p0 - r4p0 of the Neoverse N1 cpu. ERRATA_N1_1542419 ?=0 -# Flag to apply erratum 1800710 workaround during reset. This erratum applies -# to revisions <= r4p0 of the Neoverse N1 cpu. -ERRATA_N1_1800710 ?=0 - # Flag to apply DSU erratum 798953. This erratum applies to DSUs revision r0p0. # Applying the workaround results in higher DSU power consumption on idle. ERRATA_DSU_798953 ?=0 @@ -567,10 +563,6 @@ $(eval $(call add_define,ERRATA_N1_1315703)) $(eval $(call assert_boolean,ERRATA_N1_1542419)) $(eval $(call add_define,ERRATA_N1_1542419)) -# Process ERRATA_N1_1800710 flag -$(eval $(call assert_boolean,ERRATA_N1_1800710)) -$(eval $(call add_define,ERRATA_N1_1800710)) - # Process ERRATA_DSU_798953 flag $(eval $(call assert_boolean,ERRATA_DSU_798953)) $(eval $(call add_define,ERRATA_DSU_798953)) -- cgit v1.2.3 From 727bbf680d9bc7c340cd42421d7aeb1711e89505 Mon Sep 17 00:00:00 2001 From: Javier Almansa Sobrino Date: Wed, 13 May 2020 14:09:58 +0100 Subject: arm_fpga: Add support for topology self-discovery As secondary cores show up, they populate an array to announce themselves so plat_core_pos_by_mpidr() can return an invalid COREID code for any non-existing MPIDR that it is queried about. The Power Domain Tree Description is populated with a topology based on the maximum harcoded values. Signed-off-by: Javier Almansa Sobrino Change-Id: I8fd64761a2296714ce0f37c46544f3e6f13b5f61 --- plat/arm/board/arm_fpga/aarch64/fpga_helpers.S | 63 +++++++++++++++++++---- plat/arm/board/arm_fpga/fpga_bl31_setup.c | 51 ++++++++++++++++--- plat/arm/board/arm_fpga/fpga_def.h | 1 + plat/arm/board/arm_fpga/fpga_private.h | 15 +++++- plat/arm/board/arm_fpga/fpga_topology.c | 70 ++++++++++++++------------ plat/arm/board/arm_fpga/include/platform_def.h | 9 ++-- 6 files changed, 154 insertions(+), 55 deletions(-) diff --git a/plat/arm/board/arm_fpga/aarch64/fpga_helpers.S b/plat/arm/board/arm_fpga/aarch64/fpga_helpers.S index aeed3108e..20120c9c3 100644 --- a/plat/arm/board/arm_fpga/aarch64/fpga_helpers.S +++ b/plat/arm/board/arm_fpga/aarch64/fpga_helpers.S @@ -7,6 +7,8 @@ #include #include #include +#include "../fpga_private.h" + #include .globl plat_get_my_entrypoint @@ -14,10 +16,10 @@ .globl plat_is_my_cpu_primary .globl platform_mem_init .globl plat_my_core_pos - .globl plat_fpga_calc_core_pos .globl plat_crash_console_init .globl plat_crash_console_putc .globl plat_crash_console_flush + .globl plat_fpga_calc_core_pos /* ----------------------------------------------------------------------- * Indicate a cold boot for every CPU - warm boot is unsupported for the @@ -34,23 +36,59 @@ endfunc plat_get_my_entrypoint * ----------------------------------------------------------------------- */ func plat_secondary_cold_boot_setup + + /* + * Wait for the primary processor to initialise the .BSS segment + * to avoid a race condition that would erase fpga_valid_mpids + * if it is populated before the C runtime is ready. + * + * We cannot use the current spin-lock implementation until the + * runtime is up and we should not rely on sevl/wfe instructions as + * it is optional whether they are implemented or not, so we use + * a global variable as lock and wait for the primary processor to + * finish the C runtime bring-up. + */ + + ldr w0, =C_RUNTIME_READY_KEY + adrp x1, secondary_core_spinlock + add x1, x1, :lo12:secondary_core_spinlock +1: + wfe + ldr w2, [x1] + cmp w2, w0 + b.ne 1b + /* Prevent reordering of the store into fpga_valid_mpids below */ + dmb ish + + mov x10, x30 + bl plat_my_core_pos + mov x30, x10 + + adrp x4, fpga_valid_mpids + add x4, x4, :lo12:fpga_valid_mpids + mov x5, #VALID_MPID + strb w5, [x4, x0] + /* * Poll the CPU's hold entry until it indicates to jump * to the entrypoint address. */ - bl plat_my_core_pos - lsl x0, x0, #PLAT_FPGA_HOLD_ENTRY_SHIFT - ldr x1, =hold_base - ldr x2, =fpga_sec_entrypoint + + adrp x1, hold_base + add x1, x1, :lo12:hold_base poll_hold_entry: - ldr x3, [x1, x0] + ldr x3, [x1, x0, LSL #PLAT_FPGA_HOLD_ENTRY_SHIFT] cmp x3, #PLAT_FPGA_HOLD_STATE_GO b.ne 1f + + adrp x2, fpga_sec_entrypoint + add x2, x2, :lo12:fpga_sec_entrypoint ldr x3, [x2] br x3 1: wfe b poll_hold_entry + endfunc plat_secondary_cold_boot_setup /* ----------------------------------------------------------------------- @@ -73,12 +111,16 @@ func platform_mem_init endfunc platform_mem_init func plat_my_core_pos + ldr x1, =(MPID_MASK & ~(MPIDR_AFFLVL_MASK << MPIDR_AFF3_SHIFT)) mrs x0, mpidr_el1 + and x0, x0, x1 b plat_fpga_calc_core_pos + endfunc plat_my_core_pos /* ----------------------------------------------------------------------- - * unsigned int plat_fpga_calc_core_pos(u_register_t mpidr) + * unsigned int plat_fpga_calc_core_pos (uint32_t mpid) + * Clobber registers: x0 to x5 * ----------------------------------------------------------------------- */ func plat_fpga_calc_core_pos @@ -88,6 +130,7 @@ func plat_fpga_calc_core_pos * * 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 @@ -98,11 +141,13 @@ func plat_fpga_calc_core_pos ubfx x1, x3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS ubfx x2, x3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS - /* Compute linear position */ mov x4, #FPGA_MAX_CPUS_PER_CLUSTER - madd x1, x2, x4, x1 mov x5, #FPGA_MAX_PE_PER_CPU + + /* Compute linear position */ + madd x1, x2, x4, x1 madd x0, x1, x5, x0 + ret endfunc plat_fpga_calc_core_pos diff --git a/plat/arm/board/arm_fpga/fpga_bl31_setup.c b/plat/arm/board/arm_fpga/fpga_bl31_setup.c index e4b9767d4..6eeff451c 100644 --- a/plat/arm/board/arm_fpga/fpga_bl31_setup.c +++ b/plat/arm/board/arm_fpga/fpga_bl31_setup.c @@ -7,23 +7,23 @@ #include #include +#include #include -#include #include +#include "fpga_private.h" #include #include -#include "fpga_private.h" - static entry_point_info_t bl33_image_ep_info; +volatile uint32_t secondary_core_spinlock; uintptr_t plat_get_ns_image_entrypoint(void) { #ifdef PRELOADED_BL33_BASE return PRELOADED_BL33_BASE; #else - return 0; + return 0ULL; #endif } @@ -35,6 +35,17 @@ uint32_t fpga_get_spsr_for_bl33_entry(void) void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { + /* Add this core to the VALID mpids list */ + fpga_valid_mpids[plat_my_core_pos()] = VALID_MPID; + + /* + * Notify the secondary CPUs that the C runtime is ready + * so they can announce themselves. + */ + secondary_core_spinlock = C_RUNTIME_READY_KEY; + dsbish(); + sev(); + fpga_console_init(); bl33_image_ep_info.pc = plat_get_ns_image_entrypoint(); @@ -54,11 +65,37 @@ void bl31_plat_arch_setup(void) void bl31_platform_setup(void) { - /* Initialize the GIC driver, cpu and distributor interfaces */ - plat_fpga_gic_init(); - /* Write frequency to CNTCRL and initialize timer */ generic_delay_timer_init(); + + /* + * Before doing anything else, wait for some time to ensure that + * the secondary CPUs have populated the fpga_valid_mpids array. + * As the number of secondary cores is unknown and can even be 0, + * it is not possible to rely on any signal from them, so use a + * delay instead. + */ + mdelay(5); + + /* + * On the event of a cold reset issued by, for instance, a reset pin + * assertion, we cannot guarantee memory to be initialized to zero. + * In such scenario, if the secondary cores reached + * plat_secondary_cold_boot_setup before the primary one initialized + * .BSS, we could end up having a race condition if the spinlock + * was not cleared before. + * + * Similarly, if there were a reset before the spinlock had been + * cleared, the secondary cores would find the lock opened before + * .BSS is cleared, causing another race condition. + * + * So clean the spinlock as soon as we think it is safe to reduce the + * chances of any race condition on a reset. + */ + secondary_core_spinlock = 0UL; + + /* Initialize the GIC driver, cpu and distributor interfaces */ + plat_fpga_gic_init(); } entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) diff --git a/plat/arm/board/arm_fpga/fpga_def.h b/plat/arm/board/arm_fpga/fpga_def.h index 5f1951f79..2884ea6d4 100644 --- a/plat/arm/board/arm_fpga/fpga_def.h +++ b/plat/arm/board/arm_fpga/fpga_def.h @@ -18,6 +18,7 @@ * that are present will still be indexed appropriately regardless of any empty * entries in the array used to represent the topology. */ + #define FPGA_MAX_CLUSTER_COUNT 4 #define FPGA_MAX_CPUS_PER_CLUSTER 8 #define FPGA_MAX_PE_PER_CPU 4 diff --git a/plat/arm/board/arm_fpga/fpga_private.h b/plat/arm/board/arm_fpga/fpga_private.h index 7545bd17e..46287adea 100644 --- a/plat/arm/board/arm_fpga/fpga_private.h +++ b/plat/arm/board/arm_fpga/fpga_private.h @@ -7,12 +7,23 @@ #ifndef FPGA_PRIVATE_H #define FPGA_PRIVATE_H -unsigned int plat_fpga_calc_core_pos(u_register_t mpidr); +#include "../fpga_def.h" +#include + +#define C_RUNTIME_READY_KEY (0xaa55aa55) +#define VALID_MPID (1U) + +#ifndef __ASSEMBLER__ + +extern unsigned char fpga_valid_mpids[PLATFORM_CORE_COUNT]; void fpga_console_init(void); void plat_fpga_gic_init(void); void fpga_pwr_gic_on_finish(void); void fpga_pwr_gic_off(void); +unsigned int plat_fpga_calc_core_pos(uint32_t mpid); + +#endif /* __ASSEMBLER__ */ -#endif +#endif /* FPGA_PRIVATE_H */ diff --git a/plat/arm/board/arm_fpga/fpga_topology.c b/plat/arm/board/arm_fpga/fpga_topology.c index a2908d727..7fead869b 100644 --- a/plat/arm/board/arm_fpga/fpga_topology.c +++ b/plat/arm/board/arm_fpga/fpga_topology.c @@ -5,15 +5,20 @@ */ #include +#include +#include #include "fpga_private.h" +#include #include -static unsigned char fpga_power_domain_tree_desc[FPGA_MAX_CLUSTER_COUNT + 2]; +unsigned char fpga_power_domain_tree_desc[FPGA_MAX_CLUSTER_COUNT + 2]; +unsigned char fpga_valid_mpids[PLATFORM_CORE_COUNT]; const unsigned char *plat_get_power_domain_tree_desc(void) { - int i; + unsigned int i; + /* * The highest level is the system level. The next level is constituted * by clusters and then cores in clusters. @@ -21,12 +26,26 @@ const unsigned char *plat_get_power_domain_tree_desc(void) * This description of the power domain topology is aligned with the CPU * indices returned by the plat_core_pos_by_mpidr() and plat_my_core_pos() * APIs. + * + * A description of the topology tree can be found at + * https://trustedfirmware-a.readthedocs.io/en/latest/design/psci-pd-tree.html#design */ - fpga_power_domain_tree_desc[0] = 1; - fpga_power_domain_tree_desc[1] = FPGA_MAX_CLUSTER_COUNT; - for (i = 0; i < FPGA_MAX_CLUSTER_COUNT; i++) { - fpga_power_domain_tree_desc[i + 2] = FPGA_MAX_CPUS_PER_CLUSTER * FPGA_MAX_PE_PER_CPU; + if (fpga_power_domain_tree_desc[0] == 0U) { + /* + * As fpga_power_domain_tree_desc[0] == 0, assume that the + * Power Domain Topology Tree has not been initialized, so + * perform the initialization here. + */ + + fpga_power_domain_tree_desc[0] = 1U; + fpga_power_domain_tree_desc[1] = FPGA_MAX_CLUSTER_COUNT; + + for (i = 0U; i < FPGA_MAX_CLUSTER_COUNT; i++) { + fpga_power_domain_tree_desc[2 + i] = + (FPGA_MAX_CPUS_PER_CLUSTER * + FPGA_MAX_PE_PER_CPU); + } } return fpga_power_domain_tree_desc; @@ -34,40 +53,25 @@ const unsigned char *plat_get_power_domain_tree_desc(void) int plat_core_pos_by_mpidr(u_register_t mpidr) { - unsigned int cluster_id, cpu_id, thread_id; + unsigned int core_pos; - /* - * The image running on the FPGA may or may not implement - * multithreading, and it shouldn't be assumed this is consistent - * across all CPUs. - * This ensures that any passed mpidr values reflect the status of the - * primary CPU's MT bit. - */ + mpidr &= (MPID_MASK & ~(MPIDR_AFFLVL_MASK << MPIDR_AFF3_SHIFT)); mpidr |= (read_mpidr_el1() & MPIDR_MT_MASK); - mpidr &= MPID_MASK; - if (mpidr & MPIDR_MT_MASK) { - thread_id = MPIDR_AFFLVL0_VAL(mpidr); - cpu_id = MPIDR_AFFLVL1_VAL(mpidr); - cluster_id = MPIDR_AFFLVL2_VAL(mpidr); - } else { - thread_id = 0; - cpu_id = MPIDR_AFFLVL0_VAL(mpidr); - cluster_id = MPIDR_AFFLVL1_VAL(mpidr); + if ((MPIDR_AFFLVL2_VAL(mpidr) >= FPGA_MAX_CLUSTER_COUNT) || + (MPIDR_AFFLVL1_VAL(mpidr) >= FPGA_MAX_CPUS_PER_CLUSTER) || + (MPIDR_AFFLVL0_VAL(mpidr) >= FPGA_MAX_PE_PER_CPU)) { + ERROR ("Invalid mpidr: 0x%08x\n", (uint32_t)mpidr); + panic(); } - if (cluster_id >= FPGA_MAX_CLUSTER_COUNT) { - return -1; - } - - if (cpu_id >= FPGA_MAX_CPUS_PER_CLUSTER) { - return -1; - } + /* Calculate the core position, based on the maximum topology. */ + core_pos = plat_fpga_calc_core_pos(mpidr); - if (thread_id >= FPGA_MAX_PE_PER_CPU) { + /* Check whether this core is actually present. */ + if (fpga_valid_mpids[core_pos] != VALID_MPID) { return -1; } - /* Calculate the correct core, catering for multi-threaded images */ - return (int) plat_fpga_calc_core_pos(mpidr); + return core_pos; } diff --git a/plat/arm/board/arm_fpga/include/platform_def.h b/plat/arm/board/arm_fpga/include/platform_def.h index 31fc9870c..411b936da 100644 --- a/plat/arm/board/arm_fpga/include/platform_def.h +++ b/plat/arm/board/arm_fpga/include/platform_def.h @@ -21,11 +21,12 @@ #define CACHE_WRITEBACK_SHIFT U(6) #define CACHE_WRITEBACK_GRANULE (U(1) << CACHE_WRITEBACK_SHIFT) -#define PLATFORM_CORE_COUNT \ - (FPGA_MAX_CLUSTER_COUNT * FPGA_MAX_CPUS_PER_CLUSTER * FPGA_MAX_PE_PER_CPU) +#define PLATFORM_CORE_COUNT \ + (FPGA_MAX_CLUSTER_COUNT * \ + FPGA_MAX_CPUS_PER_CLUSTER * \ + FPGA_MAX_PE_PER_CPU) -#define PLAT_NUM_PWR_DOMAINS (FPGA_MAX_CLUSTER_COUNT + \ - PLATFORM_CORE_COUNT) + 1 +#define PLAT_NUM_PWR_DOMAINS (FPGA_MAX_CLUSTER_COUNT + PLATFORM_CORE_COUNT + 1) #if !ENABLE_PIE #define BL31_BASE UL(0x80000000) -- cgit v1.2.3 From cc9cb29ae79519ecc810e975960f973c80fa6fc0 Mon Sep 17 00:00:00 2001 From: Manish Pandey Date: Thu, 16 Jul 2020 00:38:59 +0100 Subject: plat/arm: spm: add support for RESET_TO_BL31 SPM(BL32) and hafnium(BL33) expect their manifest base address in x0 register, which is updated during BL2 stage by parsing fw_config. In case of RESET_TO_BL31 it has to be updated while populating entry point information. Signed-off-by: Manish Pandey Change-Id: I6f4a97f3405029bd6ba25f0935e2d1f74bb95517 --- plat/arm/common/arm_bl31_setup.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c index ded8f895e..58ccf0e51 100644 --- a/plat/arm/common/arm_bl31_setup.c +++ b/plat/arm/common/arm_bl31_setup.c @@ -114,6 +114,18 @@ void __init arm_bl31_early_platform_setup(void *from_bl2, uintptr_t soc_fw_confi SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE); bl32_image_ep_info.pc = BL32_BASE; bl32_image_ep_info.spsr = arm_get_spsr_for_bl32_entry(); + +#if defined(SPD_spmd) + /* SPM (hafnium in secure world) expects SPM Core manifest base address + * in x0, which in !RESET_TO_BL31 case loaded after base of non shared + * SRAM(after 4KB offset of SRAM). But in RESET_TO_BL31 case all non + * shared SRAM is allocated to BL31, so to avoid overwriting of manifest + * keep it in the last page. + */ + bl32_image_ep_info.args.arg0 = ARM_TRUSTED_SRAM_BASE + + PLAT_ARM_TRUSTED_SRAM_SIZE - PAGE_SIZE; +#endif + # endif /* BL32_BASE */ /* Populate entry point information for BL33 */ @@ -130,6 +142,14 @@ void __init arm_bl31_early_platform_setup(void *from_bl2, uintptr_t soc_fw_confi bl33_image_ep_info.spsr = arm_get_spsr_for_bl33_entry(); SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); +#if defined(SPD_spmd) && !(ARM_LINUX_KERNEL_AS_BL33) + /* + * Hafnium in normal world expects its manifest address in x0, which + * is loaded at base of DRAM. + */ + bl33_image_ep_info.args.arg0 = (u_register_t)ARM_DRAM1_BASE; +#endif + # if ARM_LINUX_KERNEL_AS_BL33 /* * According to the file ``Documentation/arm64/booting.txt`` of the -- cgit v1.2.3 From 6f0a2f04abd6f75c8f9e16c3f06c27609c49568a Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Thu, 23 Jul 2020 20:23:01 +0100 Subject: SMCCC: Introduce function to check SMCCC function availability Currently, 'SMCCC_ARCH_FEATURES' SMC call handler unconditionally returns 'SMC_OK' for 'SMCCC_ARCH_SOC_ID' function. This seems to be not correct for the platform which doesn't implement soc-id functionality i.e. functions to retrieve both soc-version and soc-revision. Hence introduced a platform function which will check whether SMCCC feature is available for the platform. Also, updated porting guide for the newly added platform function. Change-Id: I389f0ef6b0837bb24c712aa995b7176117bc7961 Signed-off-by: Manish V Badarkhe --- docs/getting_started/porting-guide.rst | 13 +++++++++++++ include/plat/common/platform.h | 5 +++++ plat/common/plat_bl_common.c | 7 +++++++ services/arm_arch_svc/arm_arch_svc_setup.c | 3 ++- 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst index c98f3cc04..7aaeae2f4 100644 --- a/docs/getting_started/porting-guide.rst +++ b/docs/getting_started/porting-guide.rst @@ -1130,6 +1130,7 @@ This function returns soc version which mainly consist of below fields soc_version[30:24] = JEP-106 continuation code for the SiP soc_version[23:16] = JEP-106 identification code with parity bit for the SiP + soc_version[15:0] = Implementation defined SoC ID Function : plat_get_soc_revision() ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1145,6 +1146,18 @@ This function returns soc revision in below format soc_revision[0:30] = SOC revision of specific SOC +Function : plat_is_smccc_feature_available() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : u_register_t + Return : int32_t + +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. + Modifications specific to a Boot Loader stage --------------------------------------------- diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h index 658b42380..2c1a180c8 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.h @@ -341,4 +341,9 @@ int32_t plat_get_soc_version(void); */ int32_t plat_get_soc_revision(void); +/* + * Optional function to check for SMCCC function availability for platform + */ +int32_t plat_is_smccc_feature_available(u_register_t fid); + #endif /* PLATFORM_H */ diff --git a/plat/common/plat_bl_common.c b/plat/common/plat_bl_common.c index d38fc6f75..89b77ba6c 100644 --- a/plat/common/plat_bl_common.c +++ b/plat/common/plat_bl_common.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -25,6 +26,7 @@ #pragma weak bl2_plat_handle_post_image_load #pragma weak plat_try_next_boot_source #pragma weak plat_get_enc_key_info +#pragma weak plat_is_smccc_feature_available #pragma weak plat_get_soc_version #pragma weak plat_get_soc_revision @@ -38,6 +40,11 @@ int32_t plat_get_soc_revision(void) return SMC_ARCH_CALL_NOT_SUPPORTED; } +int32_t plat_is_smccc_feature_available(u_register_t fid __unused) +{ + return SMC_ARCH_CALL_NOT_SUPPORTED; +} + void bl2_el3_plat_prepare_exit(void) { } diff --git a/services/arm_arch_svc/arm_arch_svc_setup.c b/services/arm_arch_svc/arm_arch_svc_setup.c index 588656d57..37bfc62e2 100644 --- a/services/arm_arch_svc/arm_arch_svc_setup.c +++ b/services/arm_arch_svc/arm_arch_svc_setup.c @@ -24,8 +24,9 @@ static int32_t smccc_arch_features(u_register_t arg1) switch (arg1) { case SMCCC_VERSION: case SMCCC_ARCH_FEATURES: + return SMC_ARCH_CALL_SUCCESS; case SMCCC_ARCH_SOC_ID: - return SMC_OK; + return plat_is_smccc_feature_available(arg1); #if WORKAROUND_CVE_2017_5715 case SMCCC_ARCH_WORKAROUND_1: if (check_wa_cve_2017_5715() == ERRATA_NOT_APPLIES) -- cgit v1.2.3 From c7bacd40d8f260ff69952158c907819f3510e36a Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Fri, 24 Jul 2020 03:26:05 +0100 Subject: plat/arm: Disable SMCCC_ARCH_SOC_ID feature Currently, soc-revision information is not available for arm platforms hence disabled 'SMCCC_ARCH_SOC_ID' feature for all arm platforms. Change-Id: I1ab878c6a4c8fecfff63bc6dde83e3ecefe20279 Signed-off-by: Manish V Badarkhe --- plat/arm/common/arm_common.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c index 60c777ed8..e2b99a3d6 100644 --- a/plat/arm/common/arm_common.c +++ b/plat/arm/common/arm_common.c @@ -13,7 +13,9 @@ #include #include #include +#include #include +#include #include #include @@ -235,6 +237,23 @@ int plat_sdei_validate_entry_point(uintptr_t ep, unsigned int client_mode) } #endif +/***************************************************************************** + * plat_is_smccc_feature_available() - This function checks whether SMCCC + * feature is availabile for platform. + * @fid: SMCCC function id + * + * Return SMC_OK if SMCCC feature is available and SMC_ARCH_CALL_NOT_SUPPORTED + * otherwise. + *****************************************************************************/ +int32_t plat_is_smccc_feature_available(u_register_t fid) +{ + switch (fid) { + case SMCCC_ARCH_SOC_ID: + default: + return SMC_ARCH_CALL_NOT_SUPPORTED; + } +} + /* * Weak function to get ARM platform SOC-ID, Always return SOC-ID=0 * ToDo: Get proper SOC-ID for every ARM platform and define this -- cgit v1.2.3 From 0a2126a572190d28c01534ac2c716c778fecd7b0 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Fri, 24 Jul 2020 02:05:24 +0100 Subject: plat/nvidia: tegra: Enable SMCCC_ARCH_SOC_ID feature Enabled 'SMCCC_ARCH_SOC_ID' feature for Nvidia Tegra platforms. Change-Id: If17415f42304c6518aeead8dfe5909c378aaa777 Signed-off-by: Manish V Badarkhe --- plat/nvidia/tegra/common/tegra_platform.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/plat/nvidia/tegra/common/tegra_platform.c b/plat/nvidia/tegra/common/tegra_platform.c index e4338b963..080413575 100644 --- a/plat/nvidia/tegra/common/tegra_platform.c +++ b/plat/nvidia/tegra/common/tegra_platform.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include #include #include @@ -286,3 +288,21 @@ int32_t plat_get_soc_revision(void) { return (int32_t)((tegra_get_chipid_major() << 8) | tegra_get_chipid_minor()); } + +/***************************************************************************** + * plat_smccc_feature_available() - This function checks whether SMCCC feature + * is availabile for the platform or not. + * @fid: SMCCC function id + * + * Return SMC_ARCH_CALL_SUCCESS if SMCCC feature is available and + * SMC_ARCH_CALL_NOT_SUPPORTED otherwise. + *****************************************************************************/ +int32_t plat_smccc_feature_available(u_register_t fid) +{ + switch (fid) { + case SMCCC_ARCH_SOC_ID: + return SMC_ARCH_CALL_SUCCESS; + default: + return SMC_ARCH_CALL_NOT_SUPPORTED; + } +} -- cgit v1.2.3 From 858e69e85e3a2021d053cdf1e4cc6b03e429561e Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Mon, 27 Jul 2020 15:04:14 +0100 Subject: TZ DMC620 driver: Fix MISRA-2012 defects This patch fixes defects 10.3, 10.4, 10.7, 20.7 reported by MISRA-2012 scan and adds braces for conditional statements according to the TF-A coding style. Change-Id: If84ed31cdd55bc8e7cdd2a5f48c0dacc25792112 Signed-off-by: Alexei Fedorov --- drivers/arm/tzc/tzc_dmc620.c | 35 ++++++++++++++++++----------------- include/drivers/arm/tzc_dmc620.h | 10 +++++----- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/drivers/arm/tzc/tzc_dmc620.c b/drivers/arm/tzc/tzc_dmc620.c index 64ec5abee..7e307ee50 100644 --- a/drivers/arm/tzc/tzc_dmc620.c +++ b/drivers/arm/tzc/tzc_dmc620.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -17,7 +17,7 @@ /* Helper macro for getting dmc_base addr of a dmc_inst */ #define DMC_BASE(plat_data, dmc_inst) \ - ((uintptr_t)(plat_data->dmc_base[dmc_inst])) + ((uintptr_t)((plat_data)->dmc_base[(dmc_inst)])) /* Pointer to the tzc_dmc620_config_data structure populated by the platform */ static const tzc_dmc620_config_data_t *g_plat_config_data; @@ -31,8 +31,7 @@ static const tzc_dmc620_config_data_t *g_plat_config_data; static void tzc_dmc620_validate_plat_driver_data( const tzc_dmc620_driver_data_t *plat_driver_data) { - uint8_t dmc_inst, dmc_count; - unsigned int dmc_id; + unsigned int dmc_inst, dmc_count, dmc_id; uintptr_t base; assert(plat_driver_data != NULL); @@ -59,7 +58,7 @@ static void tzc_dmc620_configure_region(int region_no, { uint32_t min_31_00, min_47_32; uint32_t max_31_00, max_47_32; - uint8_t dmc_inst, dmc_count; + unsigned int dmc_inst, dmc_count; uintptr_t base; const tzc_dmc620_driver_data_t *plat_driver_data; @@ -67,19 +66,19 @@ static void tzc_dmc620_configure_region(int region_no, assert(plat_driver_data != NULL); /* Do range checks on regions. */ - assert((region_no >= 0U) && (region_no <= DMC620_ACC_ADDR_COUNT)); + assert((region_no >= 0) && (region_no <= DMC620_ACC_ADDR_COUNT)); /* region_base and (region_top + 1) must be 4KB aligned */ assert(((region_base | (region_top + 1U)) & (4096U - 1U)) == 0U); dmc_count = plat_driver_data->dmc_count; for (dmc_inst = 0U; dmc_inst < dmc_count; dmc_inst++) { - min_31_00 = (region_base & MASK_31_16) | sec_attr; - min_47_32 = (region_base & MASK_47_32) - >> DMC620_ACC_ADDR_WIDTH; - max_31_00 = (region_top & MASK_31_16); - max_47_32 = (region_top & MASK_47_32) - >> DMC620_ACC_ADDR_WIDTH; + min_31_00 = (uint32_t)((region_base & MASK_31_16) | sec_attr); + min_47_32 = (uint32_t)((region_base & MASK_47_32) + >> DMC620_ACC_ADDR_WIDTH); + max_31_00 = (uint32_t)(region_top & MASK_31_16); + max_47_32 = (uint32_t)((region_top & MASK_47_32) + >> DMC620_ACC_ADDR_WIDTH); /* Extract the base address of the DMC-620 instance */ base = DMC_BASE(plat_driver_data, dmc_inst); @@ -100,7 +99,7 @@ static void tzc_dmc620_configure_region(int region_no, */ static void tzc_dmc620_set_action(void) { - uint8_t dmc_inst, dmc_count; + unsigned int dmc_inst, dmc_count; uintptr_t base; const tzc_dmc620_driver_data_t *plat_driver_data; @@ -123,7 +122,7 @@ static void tzc_dmc620_set_action(void) */ static void tzc_dmc620_verify_complete(void) { - uint8_t dmc_inst, dmc_count; + unsigned int dmc_inst, dmc_count; uintptr_t base; const tzc_dmc620_driver_data_t *plat_driver_data; @@ -133,8 +132,9 @@ static void tzc_dmc620_verify_complete(void) /* Extract the base address of the DMC-620 instance */ base = DMC_BASE(plat_driver_data, dmc_inst); while ((mmio_read_32(base + DMC620_MEMC_STATUS) & - DMC620_MEMC_CMD_MASK) != DMC620_MEMC_CMD_GO) + DMC620_MEMC_CMD_MASK) != DMC620_MEMC_CMD_GO) { continue; + } } } @@ -145,7 +145,7 @@ static void tzc_dmc620_verify_complete(void) */ void arm_tzc_dmc620_setup(const tzc_dmc620_config_data_t *plat_config_data) { - int i; + uint8_t i; /* Check if valid pointer is passed */ assert(plat_config_data != NULL); @@ -164,11 +164,12 @@ void arm_tzc_dmc620_setup(const tzc_dmc620_config_data_t *plat_config_data) g_plat_config_data = plat_config_data; INFO("Configuring DMC-620 TZC settings\n"); - for (i = 0U; i < g_plat_config_data->acc_addr_count; i++) + for (i = 0U; i < g_plat_config_data->acc_addr_count; i++) { tzc_dmc620_configure_region(i, g_plat_config_data->plat_acc_addr_data[i].region_base, g_plat_config_data->plat_acc_addr_data[i].region_top, g_plat_config_data->plat_acc_addr_data[i].sec_attr); + } tzc_dmc620_set_action(); tzc_dmc620_verify_complete(); diff --git a/include/drivers/arm/tzc_dmc620.h b/include/drivers/arm/tzc_dmc620.h index e0e6760b2..26c444d10 100644 --- a/include/drivers/arm/tzc_dmc620.h +++ b/include/drivers/arm/tzc_dmc620.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -32,16 +32,16 @@ /* Address offsets of access address next registers */ #define DMC620_ACC_ADDR_MIN_31_00_NEXT(region_no) \ (DMC620_ACC_ADDR_MIN_31_00_NEXT_BASE + \ - (region_no * DMC620_ACC_ADDR_NEXT_SIZE)) + ((region_no) * DMC620_ACC_ADDR_NEXT_SIZE)) #define DMC620_ACC_ADDR_MIN_47_32_NEXT(region_no) \ (DMC620_ACC_ADDR_MIN_47_32_NEXT_BASE + \ - (region_no * DMC620_ACC_ADDR_NEXT_SIZE)) + ((region_no) * DMC620_ACC_ADDR_NEXT_SIZE)) #define DMC620_ACC_ADDR_MAX_31_00_NEXT(region_no) \ (DMC620_ACC_ADDR_MAX_31_00_NEXT_BASE + \ - (region_no * DMC620_ACC_ADDR_NEXT_SIZE)) + ((region_no) * DMC620_ACC_ADDR_NEXT_SIZE)) #define DMC620_ACC_ADDR_MAX_47_32_NEXT(region_no) \ (DMC620_ACC_ADDR_MAX_47_32_NEXT_BASE + \ - (region_no * DMC620_ACC_ADDR_NEXT_SIZE)) + ((region_no) * DMC620_ACC_ADDR_NEXT_SIZE)) /* Number of TZC address regions in DMC-620 */ #define DMC620_ACC_ADDR_COUNT U(8) -- cgit v1.2.3 From 526f2bddd5e9fc6848ba241c83fc49a5cfff3ae7 Mon Sep 17 00:00:00 2001 From: johpow01 Date: Tue, 28 Jul 2020 13:07:25 -0500 Subject: Fix broken link in documentation The link to the exception handling framework page on the System Design / Firmware Design / Section 4.3 just links to itself, so I changed it to link to the exception handling framework component document. Signed-off-by: John Powell Change-Id: I6711b423a789b2b3d1921671e8497fffa8ba33d1 --- docs/design/firmware-design.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst index 891a9a29b..ae6dd469d 100644 --- a/docs/design/firmware-design.rst +++ b/docs/design/firmware-design.rst @@ -988,7 +988,7 @@ before restoring the stack and CPU state and returning from the original SMC. Exception Handling Framework ---------------------------- -Please refer to the `Exception Handling Framework`_ document. +Please refer to the :ref:`Exception Handling Framework` document. Power State Coordination Interface ---------------------------------- -- cgit v1.2.3 From 77a386907aaf89175faa7f5c97ae49430b2ca51f Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Tue, 28 Jul 2020 12:26:36 +0100 Subject: Aarch32 xlat_tables lib: Fix MISRA-2012 defects This patch fixes violation of Rules 2.1, 7.3, 10.1, 10.4, 12.1, 14.3, 14.4, 17.7, 20.9 reported by MISRA-2012 scan and adds braces for conditional statements according to the TF-A coding style. Change-Id: Ib2463601fb43d955c3d901102b6dceaaad6614f3 Signed-off-by: Alexei Fedorov --- lib/xlat_tables/aarch32/nonlpae_tables.c | 193 +++++++++++++++++-------------- 1 file changed, 104 insertions(+), 89 deletions(-) diff --git a/lib/xlat_tables/aarch32/nonlpae_tables.c b/lib/xlat_tables/aarch32/nonlpae_tables.c index b8c268665..7cd509d56 100644 --- a/lib/xlat_tables/aarch32/nonlpae_tables.c +++ b/lib/xlat_tables/aarch32/nonlpae_tables.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2016-2017, Linaro Limited. All rights reserved. - * Copyright (c) 2014-2019, Arm Limited. All rights reserved. + * Copyright (c) 2014-2020, Arm Limited. All rights reserved. * Copyright (c) 2014, STMicroelectronics International N.V. * All rights reserved. * @@ -30,8 +30,8 @@ This module is to be used when LPAE is not supported" CASSERT(PLAT_VIRT_ADDR_SPACE_SIZE == (1ULL << 32), invalid_vaddr_space_size); CASSERT(PLAT_PHY_ADDR_SPACE_SIZE == (1ULL << 32), invalid_paddr_space_size); -#define MMU32B_UNSET_DESC ~0ul -#define MMU32B_INVALID_DESC 0ul +#define MMU32B_UNSET_DESC ~0UL +#define MMU32B_INVALID_DESC 0UL #define MT_UNKNOWN ~0U @@ -40,38 +40,38 @@ CASSERT(PLAT_PHY_ADDR_SPACE_SIZE == (1ULL << 32), invalid_paddr_space_size); */ /* Sharable */ -#define MMU32B_TTB_S (1 << 1) +#define MMU32B_TTB_S (1U << 1) /* Not Outer Sharable */ -#define MMU32B_TTB_NOS (1 << 5) +#define MMU32B_TTB_NOS (1U << 5) /* Normal memory, Inner Non-cacheable */ -#define MMU32B_TTB_IRGN_NC 0 +#define MMU32B_TTB_IRGN_NC 0U /* Normal memory, Inner Write-Back Write-Allocate Cacheable */ -#define MMU32B_TTB_IRGN_WBWA (1 << 6) +#define MMU32B_TTB_IRGN_WBWA (1U << 6) /* Normal memory, Inner Write-Through Cacheable */ -#define MMU32B_TTB_IRGN_WT 1 +#define MMU32B_TTB_IRGN_WT 1U /* Normal memory, Inner Write-Back no Write-Allocate Cacheable */ -#define MMU32B_TTB_IRGN_WB (1 | (1 << 6)) +#define MMU32B_TTB_IRGN_WB (1U | (1U << 6)) /* Normal memory, Outer Write-Back Write-Allocate Cacheable */ -#define MMU32B_TTB_RNG_WBWA (1 << 3) +#define MMU32B_TTB_RNG_WBWA (1U << 3) #define MMU32B_DEFAULT_ATTRS \ (MMU32B_TTB_S | MMU32B_TTB_NOS | \ MMU32B_TTB_IRGN_WBWA | MMU32B_TTB_RNG_WBWA) /* armv7 memory mapping attributes: section mapping */ -#define SECTION_SECURE (0 << 19) -#define SECTION_NOTSECURE (1 << 19) -#define SECTION_SHARED (1 << 16) -#define SECTION_NOTGLOBAL (1 << 17) -#define SECTION_ACCESS_FLAG (1 << 10) -#define SECTION_UNPRIV (1 << 11) -#define SECTION_RO (1 << 15) +#define SECTION_SECURE (0U << 19) +#define SECTION_NOTSECURE (1U << 19) +#define SECTION_SHARED (1U << 16) +#define SECTION_NOTGLOBAL (1U << 17) +#define SECTION_ACCESS_FLAG (1U << 10) +#define SECTION_UNPRIV (1U << 11) +#define SECTION_RO (1U << 15) #define SECTION_TEX(tex) ((((tex) >> 2) << 12) | \ ((((tex) >> 1) & 0x1) << 3) | \ (((tex) & 0x1) << 2)) @@ -80,16 +80,16 @@ CASSERT(PLAT_PHY_ADDR_SPACE_SIZE == (1ULL << 32), invalid_paddr_space_size); #define SECTION_NORMAL_CACHED \ SECTION_TEX(MMU32B_ATTR_IWBWA_OWBWA_INDEX) -#define SECTION_XN (1 << 4) -#define SECTION_PXN (1 << 0) -#define SECTION_SECTION (2 << 0) +#define SECTION_XN (1U << 4) +#define SECTION_PXN (1U << 0) +#define SECTION_SECTION (2U << 0) -#define SECTION_PT_NOTSECURE (1 << 3) -#define SECTION_PT_PT (1 << 0) +#define SECTION_PT_NOTSECURE (1U << 3) +#define SECTION_PT_PT (1U << 0) -#define SMALL_PAGE_SMALL_PAGE (1 << 1) -#define SMALL_PAGE_SHARED (1 << 10) -#define SMALL_PAGE_NOTGLOBAL (1 << 11) +#define SMALL_PAGE_SMALL_PAGE (1U << 1) +#define SMALL_PAGE_SHARED (1U << 10) +#define SMALL_PAGE_NOTGLOBAL (1U << 11) #define SMALL_PAGE_TEX(tex) ((((tex) >> 2) << 6) | \ ((((tex) >> 1) & 0x1) << 3) | \ (((tex) & 0x1) << 2)) @@ -99,39 +99,39 @@ CASSERT(PLAT_PHY_ADDR_SPACE_SIZE == (1ULL << 32), invalid_paddr_space_size); SMALL_PAGE_TEX(MMU32B_ATTR_DEVICE_INDEX) #define SMALL_PAGE_NORMAL_CACHED \ SMALL_PAGE_TEX(MMU32B_ATTR_IWBWA_OWBWA_INDEX) -#define SMALL_PAGE_ACCESS_FLAG (1 << 4) -#define SMALL_PAGE_UNPRIV (1 << 5) -#define SMALL_PAGE_RO (1 << 9) -#define SMALL_PAGE_XN (1 << 0) +#define SMALL_PAGE_ACCESS_FLAG (1U << 4) +#define SMALL_PAGE_UNPRIV (1U << 5) +#define SMALL_PAGE_RO (1U << 9) +#define SMALL_PAGE_XN (1U << 0) /* The TEX, C and B bits concatenated */ -#define MMU32B_ATTR_DEVICE_INDEX 0x0 -#define MMU32B_ATTR_IWBWA_OWBWA_INDEX 0x1 +#define MMU32B_ATTR_DEVICE_INDEX 0U +#define MMU32B_ATTR_IWBWA_OWBWA_INDEX 1U #define MMU32B_PRRR_IDX(idx, tr, nos) (((tr) << (2 * (idx))) | \ ((uint32_t)(nos) << ((idx) + 24))) #define MMU32B_NMRR_IDX(idx, ir, or) (((ir) << (2 * (idx))) | \ ((uint32_t)(or) << (2 * (idx) + 16))) -#define MMU32B_PRRR_DS0 (1 << 16) -#define MMU32B_PRRR_DS1 (1 << 17) -#define MMU32B_PRRR_NS0 (1 << 18) -#define MMU32B_PRRR_NS1 (1 << 19) +#define MMU32B_PRRR_DS0 (1U << 16) +#define MMU32B_PRRR_DS1 (1U << 17) +#define MMU32B_PRRR_NS0 (1U << 18) +#define MMU32B_PRRR_NS1 (1U << 19) #define DACR_DOMAIN(num, perm) ((perm) << ((num) * 2)) -#define DACR_DOMAIN_PERM_NO_ACCESS 0x0 -#define DACR_DOMAIN_PERM_CLIENT 0x1 -#define DACR_DOMAIN_PERM_MANAGER 0x3 +#define DACR_DOMAIN_PERM_NO_ACCESS 0U +#define DACR_DOMAIN_PERM_CLIENT 1U +#define DACR_DOMAIN_PERM_MANAGER 3U -#define NUM_1MB_IN_4GB (1U << 12) -#define NUM_4K_IN_1MB (1U << 8) +#define NUM_1MB_IN_4GB (1UL << 12) +#define NUM_4K_IN_1MB (1UL << 8) #define ONE_MB_SHIFT 20 /* mmu 32b integration */ #define MMU32B_L1_TABLE_SIZE (NUM_1MB_IN_4GB * 4) #define MMU32B_L2_TABLE_SIZE (NUM_4K_IN_1MB * 4) -#define MMU32B_L1_TABLE_ALIGN (1 << 14) -#define MMU32B_L2_TABLE_ALIGN (1 << 10) +#define MMU32B_L1_TABLE_ALIGN (1U << 14) +#define MMU32B_L2_TABLE_ALIGN (1U << 10) static unsigned int next_xlat; static unsigned long long xlat_max_pa; @@ -190,8 +190,9 @@ void mmap_add_region(unsigned long long base_pa, uintptr_t base_va, assert(IS_PAGE_ALIGNED(base_va)); assert(IS_PAGE_ALIGNED(size)); - if (size == 0U) + if (size == 0U) { return; + } assert(base_pa < end_pa); /* Check for overflows */ assert(base_va < end_va); @@ -249,8 +250,9 @@ void mmap_add_region(unsigned long long base_pa, uintptr_t base_va, #endif /* ENABLE_ASSERTIONS */ /* Find correct place in mmap to insert new region */ - while ((mm->base_va < base_va) && (mm->size != 0U)) + while ((mm->base_va < base_va) && (mm->size != 0U)) { ++mm; + } /* * If a section is contained inside another one with the same base @@ -263,8 +265,9 @@ void mmap_add_region(unsigned long long base_pa, uintptr_t base_va, * This is required for mmap_region_attr() to get the attributes of the * small region correctly. */ - while ((mm->base_va == base_va) && (mm->size > size)) + while ((mm->base_va == base_va) && (mm->size > size)) { ++mm; + } /* Make room for new region by moving other regions up by one place */ (void)memmove(mm + 1, mm, (uintptr_t)mm_last - (uintptr_t)mm); @@ -277,10 +280,12 @@ void mmap_add_region(unsigned long long base_pa, uintptr_t base_va, mm->size = size; mm->attr = attr; - if (end_pa > xlat_max_pa) + if (end_pa > xlat_max_pa) { xlat_max_pa = end_pa; - if (end_va > xlat_max_va) + } + if (end_va > xlat_max_va) { xlat_max_va = end_va; + } } /* map all memory as shared/global/domain0/no-usr access */ @@ -290,42 +295,44 @@ static uint32_t mmap_desc(unsigned attr, unsigned int addr_pa, uint32_t desc; switch (level) { - case 1: - assert(!(addr_pa & (MMU32B_L1_TABLE_ALIGN - 1))); + case 1U: + assert((addr_pa & (MMU32B_L1_TABLE_ALIGN - 1)) == 0U); desc = SECTION_SECTION | SECTION_SHARED; - desc |= attr & MT_NS ? SECTION_NOTSECURE : 0; + desc |= (attr & MT_NS) != 0U ? SECTION_NOTSECURE : 0U; desc |= SECTION_ACCESS_FLAG; - desc |= attr & MT_RW ? 0 : SECTION_RO; + desc |= (attr & MT_RW) != 0U ? 0U : SECTION_RO; - desc |= attr & MT_MEMORY ? + desc |= (attr & MT_MEMORY) != 0U ? SECTION_NORMAL_CACHED : SECTION_DEVICE; - if ((attr & MT_RW) || !(attr & MT_MEMORY)) + if (((attr & MT_RW) != 0U) || ((attr & MT_MEMORY) == 0U)) { desc |= SECTION_XN; + } break; - case 2: - assert(!(addr_pa & (MMU32B_L2_TABLE_ALIGN - 1))); + case 2U: + assert((addr_pa & (MMU32B_L2_TABLE_ALIGN - 1)) == 0U); desc = SMALL_PAGE_SMALL_PAGE | SMALL_PAGE_SHARED; desc |= SMALL_PAGE_ACCESS_FLAG; - desc |= attr & MT_RW ? 0 : SMALL_PAGE_RO; + desc |= (attr & MT_RW) != 0U ? 0U : SMALL_PAGE_RO; - desc |= attr & MT_MEMORY ? + desc |= (attr & MT_MEMORY) != 0U ? SMALL_PAGE_NORMAL_CACHED : SMALL_PAGE_DEVICE; - if ((attr & MT_RW) || !(attr & MT_MEMORY)) + if (((attr & MT_RW) != 0U) || ((attr & MT_MEMORY) == 0U)) { desc |= SMALL_PAGE_XN; + } break; default: panic(); } #if LOG_LEVEL >= LOG_LEVEL_VERBOSE /* dump only the non-lpae level 2 tables */ - if (level == 2) { + if (level == 2U) { printf(attr & MT_MEMORY ? "MEM" : "dev"); printf(attr & MT_RW ? "-rw" : "-RO"); printf(attr & MT_NS ? "-NS" : "-S"); @@ -357,26 +364,31 @@ static unsigned int mmap_region_attr(const mmap_region_t *mm, uintptr_t base_va, */ for ( ; ; ++mm) { - if (mm->size == 0U) + if (mm->size == 0U) { return ret; /* Reached end of list */ + } - if (mm->base_va > (base_va + size - 1U)) + if (mm->base_va > (base_va + size - 1U)) { return ret; /* Next region is after area so end */ + } - if ((mm->base_va + mm->size - 1U) < base_va) + if ((mm->base_va + mm->size - 1U) < base_va) { continue; /* Next region has already been overtaken */ + } - if ((ret == 0U) && (mm->attr == *attr)) + if ((ret == 0U) && (mm->attr == *attr)) { continue; /* Region doesn't override attribs so skip */ + } if ((mm->base_va > base_va) || - ((mm->base_va + mm->size - 1U) < (base_va + size - 1U))) + ((mm->base_va + mm->size - 1U) < + (base_va + size - 1U))) { return MT_UNKNOWN; /* Region doesn't fully cover area */ + } *attr = mm->attr; ret = 0U; } - return ret; } static mmap_region_t *init_xlation_table_inner(mmap_region_t *mm, @@ -384,16 +396,16 @@ static mmap_region_t *init_xlation_table_inner(mmap_region_t *mm, uint32_t *table, unsigned int level) { - unsigned int level_size_shift = (level == 1) ? + unsigned int level_size_shift = (level == 1U) ? ONE_MB_SHIFT : FOUR_KB_SHIFT; - unsigned int level_size = 1 << level_size_shift; - unsigned int level_index_mask = (level == 1) ? + unsigned int level_size = 1U << level_size_shift; + unsigned int level_index_mask = (level == 1U) ? (NUM_1MB_IN_4GB - 1) << ONE_MB_SHIFT : (NUM_4K_IN_1MB - 1) << FOUR_KB_SHIFT; - assert(level == 1 || level == 2); + assert((level == 1U) || (level == 2U)); - VERBOSE("init xlat table at %p (level%1d)\n", (void *)table, level); + VERBOSE("init xlat table at %p (level%1u)\n", (void *)table, level); do { uint32_t desc = MMU32B_UNSET_DESC; @@ -405,15 +417,17 @@ static mmap_region_t *init_xlation_table_inner(mmap_region_t *mm, } #if LOG_LEVEL >= LOG_LEVEL_VERBOSE /* dump only non-lpae level 2 tables content */ - if (level == 2) + if (level == 2U) { printf(" 0x%lx %x " + 6 - 2 * level, base_va, level_size); + } #endif if (mm->base_va >= base_va + level_size) { /* Next region is after area so nothing to map yet */ desc = MMU32B_INVALID_DESC; - } else if (mm->base_va <= base_va && mm->base_va + mm->size >= - base_va + level_size) { + } else if ((mm->base_va <= base_va) && + (mm->base_va + mm->size) >= + (base_va + level_size)) { /* Next region covers all of area */ unsigned int attr = mm->attr; unsigned int r = mmap_region_attr(mm, base_va, @@ -436,8 +450,8 @@ static mmap_region_t *init_xlation_table_inner(mmap_region_t *mm, */ if (*table) { assert((*table & 3) == SECTION_PT_PT); - assert(!(*table & SECTION_PT_NOTSECURE) == - !(mm->attr & MT_NS)); + assert(((*table & SECTION_PT_NOTSECURE) == 0U) + == ((mm->attr & MT_NS) == 0U)); xlat_table = (*table) & ~(MMU32B_L1_TABLE_ALIGN - 1); @@ -447,11 +461,11 @@ static mmap_region_t *init_xlation_table_inner(mmap_region_t *mm, next_xlat * MMU32B_L2_TABLE_SIZE; next_xlat++; assert(next_xlat <= MAX_XLAT_TABLES); - memset((char *)xlat_table, 0, + (void)memset((char *)xlat_table, 0, MMU32B_L2_TABLE_SIZE); desc = xlat_table | SECTION_PT_PT; - desc |= mm->attr & MT_NS ? + desc |= (mm->attr & MT_NS) != 0U ? SECTION_PT_NOTSECURE : 0; } /* Recurse to fill in new table */ @@ -461,12 +475,13 @@ static mmap_region_t *init_xlation_table_inner(mmap_region_t *mm, } #if LOG_LEVEL >= LOG_LEVEL_VERBOSE /* dump only non-lpae level 2 tables content */ - if (level == 2) + if (level == 2U) { printf("\n"); + } #endif *table++ = desc; base_va += level_size; - } while (mm->size && (base_va & level_index_mask)); + } while ((mm->size != 0U) && ((base_va & level_index_mask) != 0U)); return mm; } @@ -475,17 +490,16 @@ void init_xlat_tables(void) { print_mmap(); - assert(!((unsigned int)mmu_l1_base & (MMU32B_L1_TABLE_ALIGN - 1))); - assert(!((unsigned int)mmu_l2_base & (MMU32B_L2_TABLE_ALIGN - 1))); + assert(((unsigned int)mmu_l1_base & (MMU32B_L1_TABLE_ALIGN - 1)) == 0U); + assert(((unsigned int)mmu_l2_base & (MMU32B_L2_TABLE_ALIGN - 1)) == 0U); - memset(mmu_l1_base, 0, MMU32B_L1_TABLE_SIZE); + (void)memset(mmu_l1_base, 0, MMU32B_L1_TABLE_SIZE); init_xlation_table_inner(mmap, 0, (uint32_t *)mmu_l1_base, 1); VERBOSE("init xlat - max_va=%p, max_pa=%llx\n", (void *)xlat_max_va, xlat_max_pa); - assert(xlat_max_va <= PLAT_VIRT_ADDR_SPACE_SIZE - 1); - assert(xlat_max_pa <= PLAT_VIRT_ADDR_SPACE_SIZE - 1); + assert(xlat_max_pa <= (PLAT_VIRT_ADDR_SPACE_SIZE - 1)); } /******************************************************************************* @@ -499,7 +513,7 @@ void enable_mmu_svc_mon(unsigned int flags) unsigned int sctlr; assert(IS_IN_SECURE()); - assert((read_sctlr() & SCTLR_M_BIT) == 0); + assert((read_sctlr() & SCTLR_M_BIT) == 0U); /* Enable Access flag (simplified access permissions) and TEX remap */ write_sctlr(read_sctlr() | SCTLR_AFE_BIT | SCTLR_TRE_BIT); @@ -522,7 +536,7 @@ void enable_mmu_svc_mon(unsigned int flags) /* set MMU base xlat table entry (use only TTBR0) */ write_ttbr0((uint32_t)mmu_l1_base | MMU32B_DEFAULT_ATTRS); - write_ttbr1(0); + write_ttbr1(0U); /* * Ensure all translation table writes have drained @@ -535,14 +549,15 @@ void enable_mmu_svc_mon(unsigned int flags) sctlr = read_sctlr(); sctlr |= SCTLR_M_BIT; -#if ARMV7_SUPPORTS_VIRTUALIZATION +#ifdef ARMV7_SUPPORTS_VIRTUALIZATION sctlr |= SCTLR_WXN_BIT; #endif - if (flags & DISABLE_DCACHE) + if ((flags & DISABLE_DCACHE) != 0U) { sctlr &= ~SCTLR_C_BIT; - else + } else { sctlr |= SCTLR_C_BIT; + } write_sctlr(sctlr); -- cgit v1.2.3 From b29c350cdaebb11124f0e3db153dd973ac70cac5 Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Wed, 29 Jul 2020 15:16:36 +0100 Subject: GIC-600: Fix MISRA-2012 defects This patch fixes violation of Rules 10.1, 10.4, 11.9 and 13.2 reported by MISRA-2012 scan. Change-Id: Ibe9190cb0f26ae85d9a31db8e92fbd32f1740e25 Signed-off-by: Alexei Fedorov --- drivers/arm/gic/v3/gic-x00.c | 43 +++++++++++++++++++++++-------------------- include/drivers/arm/gicv3.h | 8 ++++---- 2 files changed, 27 insertions(+), 24 deletions(-) diff --git a/drivers/arm/gic/v3/gic-x00.c b/drivers/arm/gic/v3/gic-x00.c index c9e9cb98f..6e106babf 100644 --- a/drivers/arm/gic/v3/gic-x00.c +++ b/drivers/arm/gic/v3/gic-x00.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -21,10 +21,10 @@ #include "gicv3_private.h" /* GIC-600 specific register offsets */ -#define GICR_PWRR 0x24 -#define IIDR_MODEL_ARM_GIC_600 (0x0200043b) -#define IIDR_MODEL_ARM_GIC_600AE (0x0300043b) -#define IIDR_MODEL_ARM_GIC_CLAYTON (0x0400043b) +#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) /* GICR_PWRR fields */ #define PWRR_RDPD_SHIFT 0 @@ -32,17 +32,17 @@ #define PWRR_RDGPD_SHIFT 2 #define PWRR_RDGPO_SHIFT 3 -#define PWRR_RDPD (1 << PWRR_RDPD_SHIFT) -#define PWRR_RDAG (1 << PWRR_RDAG_SHIFT) -#define PWRR_RDGPD (1 << PWRR_RDGPD_SHIFT) -#define PWRR_RDGPO (1 << PWRR_RDGPO_SHIFT) +#define PWRR_RDPD (1U << PWRR_RDPD_SHIFT) +#define PWRR_RDAG (1U << PWRR_RDAG_SHIFT) +#define PWRR_RDGPD (1U << PWRR_RDGPD_SHIFT) +#define PWRR_RDGPO (1U << PWRR_RDGPO_SHIFT) /* * Values to write to GICR_PWRR register to power redistributor * for operating through the core (GICR_PWRR.RDAG = 0) */ -#define PWRR_ON (0 << PWRR_RDPD_SHIFT) -#define PWRR_OFF (1 << PWRR_RDPD_SHIFT) +#define PWRR_ON (0U << PWRR_RDPD_SHIFT) +#define PWRR_OFF (1U << PWRR_RDPD_SHIFT) #if GICV3_SUPPORT_GIC600 @@ -59,10 +59,14 @@ static uint32_t gicr_read_pwrr(uintptr_t base) static void gicr_wait_group_not_in_transit(uintptr_t base) { + uint32_t pwrr; + + do { + pwrr = gicr_read_pwrr(base); + /* Check group not transitioning: RDGPD == RDGPO */ - while (((gicr_read_pwrr(base) & PWRR_RDGPD) >> PWRR_RDGPD_SHIFT) != - ((gicr_read_pwrr(base) & PWRR_RDGPO) >> PWRR_RDGPO_SHIFT)) - ; + } while (((pwrr & PWRR_RDGPD) >> PWRR_RDGPD_SHIFT) != + ((pwrr & PWRR_RDGPO) >> PWRR_RDGPO_SHIFT)); } static void gic600_pwr_on(uintptr_t base) @@ -94,7 +98,7 @@ static void gic600_pwr_off(uintptr_t base) * In that case, wait as long as it's in transition, or has aborted * the transition altogether for any reason. */ - if ((gicr_read_pwrr(base) & PWRR_RDGPD) != 0) { + if ((gicr_read_pwrr(base) & PWRR_RDGPD) != 0U) { /* Wait until group not transitioning */ gicr_wait_group_not_in_transit(base); } @@ -104,12 +108,12 @@ static uintptr_t get_gicr_base(unsigned int proc_num) { uintptr_t gicr_base; - assert(gicv3_driver_data); + assert(gicv3_driver_data != NULL); assert(proc_num < gicv3_driver_data->rdistif_num); - assert(gicv3_driver_data->rdistif_base_addrs); + assert(gicv3_driver_data->rdistif_base_addrs != NULL); gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; - assert(gicr_base); + assert(gicr_base != 0UL); return gicr_base; } @@ -127,7 +131,7 @@ static bool gicv3_redists_need_power_mgmt(uintptr_t gicr_base) ((reg & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_CLAYTON)); } -#endif +#endif /* GICV3_SUPPORT_GIC600 */ void gicv3_distif_pre_save(unsigned int proc_num) { @@ -139,7 +143,6 @@ void gicv3_distif_post_restore(unsigned int proc_num) arm_gicv3_distif_post_restore(proc_num); } - /* * Power off GIC-600 redistributor (if configured and detected) */ diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h index 97b75b0da..18d5b73e2 100644 --- a/include/drivers/arm/gicv3.h +++ b/include/drivers/arm/gicv3.h @@ -223,10 +223,10 @@ #define TYPER_PPI_NUM_MASK U(0x1f) /* GICR_IIDR bit definitions */ -#define IIDR_PRODUCT_ID_MASK 0xff000000 -#define IIDR_VARIANT_MASK 0x000f0000 -#define IIDR_REVISION_MASK 0x0000f000 -#define IIDR_IMPLEMENTER_MASK 0x00000fff +#define IIDR_PRODUCT_ID_MASK U(0xff000000) +#define IIDR_VARIANT_MASK U(0x000f0000) +#define IIDR_REVISION_MASK U(0x0000f000) +#define IIDR_IMPLEMENTER_MASK U(0x00000fff) #define IIDR_MODEL_MASK (IIDR_PRODUCT_ID_MASK | \ IIDR_IMPLEMENTER_MASK) -- cgit v1.2.3 From bef0192a2ee1e1e98199bef4e461d87f022f997a Mon Sep 17 00:00:00 2001 From: Manish Pandey Date: Mon, 27 Jul 2020 13:00:38 +0100 Subject: fconf: spm: minor bug fix This patch fixes a bug where wrong panic was caused when the number of SP was same as max limit. Signed-off-by: Manish Pandey Change-Id: I9ace62d8d5bcdc410eeacdd9d33d55a7be5fcc8e --- plat/arm/common/fconf/arm_fconf_sp.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/plat/arm/common/fconf/arm_fconf_sp.c b/plat/arm/common/fconf/arm_fconf_sp.c index 64e873e7a..3522dcf9d 100644 --- a/plat/arm/common/fconf/arm_fconf_sp.c +++ b/plat/arm/common/fconf/arm_fconf_sp.c @@ -45,6 +45,11 @@ int fconf_populate_arm_sp(uintptr_t config) } fdt_for_each_subnode(sp_node, dtb, node) { + if (index == MAX_SP_IDS) { + ERROR("FCONF: Reached max number of SPs\n"); + return -1; + } + err = fdt_read_uint32_array(dtb, sp_node, "uuid", 4, uuid_helper.word); if (err < 0) { @@ -87,15 +92,10 @@ int fconf_populate_arm_sp(uintptr_t config) policies[sp_start_index + index].check = open_fip; index++; - - if (index >= MAX_SP_IDS) { - ERROR("FCONF: reached max number of SPs\n"); - return -1; - } } if ((sp_node < 0) && (sp_node != -FDT_ERR_NOTFOUND)) { - ERROR("%d: fdt_for_each_subnode(): %d\n", __LINE__, node); + ERROR("%u: fdt_for_each_subnode(): %d\n", __LINE__, node); return sp_node; } -- cgit v1.2.3 From 000653b467fbea2c0981c4d196e472374e1099b9 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 6 Jul 2020 11:19:41 +0530 Subject: fdts: n1sdp: DTS file for single-chip and multi-chip environment. N1SDP supports both single-chip and multi-chip environment. Added DTS file for both type of environment. Enabled DTS files compilation for N1SDP platform. Change-Id: I66af88dcfb841893eb6ed2ca18d3025de81236a0 Co-authored-by: Robin Murphy Co-authored-by: Sayanta Pattanayak Co-authored-by: Manoj Kumar Co-authored-by: Anurag Koul Signed-off-by: Sayanta Pattanayak --- fdts/n1sdp-multi-chip.dts | 63 ++++++++++++ fdts/n1sdp-single-chip.dts | 92 +++++++++++++++++ fdts/n1sdp.dtsi | 210 +++++++++++++++++++++++++++++++++++++++ plat/arm/board/n1sdp/platform.mk | 2 + 4 files changed, 367 insertions(+) create mode 100644 fdts/n1sdp-multi-chip.dts create mode 100644 fdts/n1sdp-single-chip.dts create mode 100644 fdts/n1sdp.dtsi diff --git a/fdts/n1sdp-multi-chip.dts b/fdts/n1sdp-multi-chip.dts new file mode 100644 index 000000000..b58d9d8fb --- /dev/null +++ b/fdts/n1sdp-multi-chip.dts @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: (GPL-2.0 or BSD-3-Clause) +/* + * Copyright (c) 2019-2020, Arm Limited. + */ + +#include "n1sdp-single-chip.dts" + +/ { + cpus { + cpu4@100000000 { + compatible = "arm,neoverse-n1"; + reg = <0x1 0x0>; + device_type = "cpu"; + enable-method = "psci"; + numa-node-id = <1>; + }; + cpu5@100000100 { + compatible = "arm,neoverse-n1"; + reg = <0x1 0x00000100>; + device_type = "cpu"; + enable-method = "psci"; + numa-node-id = <1>; + }; + cpu6@100010000 { + compatible = "arm,neoverse-n1"; + reg = <0x1 0x00010000>; + device_type = "cpu"; + enable-method = "psci"; + numa-node-id = <1>; + }; + cpu7@100010100 { + compatible = "arm,neoverse-n1"; + reg = <0x1 0x00010100>; + device_type = "cpu"; + enable-method = "psci"; + numa-node-id = <1>; + }; + }; + + /* Remote N1SDP board address is mapped at offset 4TB. + * First DRAM Bank of remote N1SDP board is mapped at 4TB + 2GB. + */ + memory@40080000000 { + device_type = "memory"; + reg = <0x00000400 0x80000000 0x0 0x80000000>, + <0x00000480 0x80000000 0x3 0x80000000>; + numa-node-id = <1>; + }; + + distance-map { + compatible = "numa-distance-map-v1"; + distance-matrix = <0 0 10>, + <0 1 20>, + <1 1 10>; + }; +}; + +&gic { + #redistributor-regions = <2>; + reg = <0x0 0x30000000 0 0x10000>, /* GICD */ + <0x0 0x300c0000 0 0x80000>, /* GICR */ + <0x400 0x300c0000 0 0x80000>; /* GICR */ +}; diff --git a/fdts/n1sdp-single-chip.dts b/fdts/n1sdp-single-chip.dts new file mode 100644 index 000000000..bd4827381 --- /dev/null +++ b/fdts/n1sdp-single-chip.dts @@ -0,0 +1,92 @@ +// SPDX-License-Identifier: (GPL-2.0 or BSD-3-Clause) +/* + * Copyright (c) 2019-2020, Arm Limited. + */ + +/dts-v1/; + +#include "n1sdp.dtsi" + +/ { + model = "Arm Neoverse N1 System Development Platform"; + compatible = "arm,neoverse-n1-sdp", "arm,neoverse-n1-soc"; + + aliases { + serial0 = &soc_uart0; + }; + + chosen { + stdout-path = "soc_uart0:115200n8"; + }; + + /* This configuration assumes that standard setup with two DIMM modules. + * In the first 2GB of DRAM bank the top 16MB are reserved by firmware as secure memory. + * This configuration assumes 16GB of total DRAM being populated. + */ + memory@80000000 { + device_type = "memory"; + reg = <0x00000000 0x80000000 0x0 0x7f000000>, + <0x00000080 0x80000000 0x3 0x80000000>; + numa-node-id = <0>; + }; + + soc_refclk60mhz: refclk60mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <60000000>; + clock-output-names = "iofpga_clk"; + }; + + soc_hdlcdclk: hdlcdclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <23750000>; + clock-output-names = "hdlcdclk"; + }; + + hdlcd: hdlcd@1c050000 { + compatible = "arm,hdlcd"; + reg = <0 0x1c050000 0 0x1000>; + interrupts = ; + clocks = <&soc_hdlcdclk>; + clock-names = "pxlclk"; + + port { + hdlcd0_output: endpoint { + remote-endpoint = <&tda998x_0_input>; + }; + }; + }; + + i2c@1c0f0000 { + compatible = "arm,versatile-i2c"; + reg = <0x0 0x1c0f0000 0x0 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = <400000>; + i2c-sda-hold-time-ns = <500>; + clocks = <&soc_refclk60mhz>; + + hdmi-transmitter@70 { + compatible = "nxp,tda998x"; + reg = <0x70>; + port { + tda998x_0_input: endpoint { + remote-endpoint = <&hdlcd0_output>; + }; + }; + }; + }; +}; + +&pcie_ctlr { + status = "okay"; +}; + +&ccix_pcie_ctlr { + status = "okay"; +}; + +&soc_uart0 { + status = "okay"; +}; diff --git a/fdts/n1sdp.dtsi b/fdts/n1sdp.dtsi new file mode 100644 index 000000000..88f8734cb --- /dev/null +++ b/fdts/n1sdp.dtsi @@ -0,0 +1,210 @@ +// SPDX-License-Identifier: (GPL-2.0 or BSD-3-Clause) +/* + * Copyright (c) 2019-2020, Arm Limited. + */ + +#include + +/ { + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu0@0 { + compatible = "arm,neoverse-n1"; + reg = <0x0 0x0>; + device_type = "cpu"; + enable-method = "psci"; + numa-node-id = <0>; + }; + cpu1@100 { + compatible = "arm,neoverse-n1"; + reg = <0x0 0x100>; + device_type = "cpu"; + enable-method = "psci"; + numa-node-id = <0>; + }; + cpu2@10000 { + compatible = "arm,neoverse-n1"; + reg = <0x0 0x10000>; + device_type = "cpu"; + enable-method = "psci"; + numa-node-id = <0>; + }; + cpu3@10100 { + compatible = "arm,neoverse-n1"; + reg = <0x0 0x10100>; + device_type = "cpu"; + enable-method = "psci"; + numa-node-id = <0>; + }; + }; + + pmu { + compatible = "arm,armv8-pmuv3"; + interrupts = ; + }; + + spe-pmu { + compatible = "arm,statistical-profiling-extension-v1"; + interrupts = ; + }; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = , + , + , + ; + }; + + soc_refclk100mhz: refclk100mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <100000000>; + clock-output-names = "apb_pclk"; + }; + + soc_uartclk: uartclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <50000000>; + clock-output-names = "uartclk"; + }; + + soc { + compatible = "arm,neoverse-n1-soc", "simple-bus"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + gic: interrupt-controller@30000000 { + compatible = "arm,gic-v3"; + #address-cells = <2>; + #interrupt-cells = <3>; + #size-cells = <2>; + ranges; + interrupt-controller; + reg = <0x0 0x30000000 0 0x10000>, /* GICD */ + <0x0 0x300c0000 0 0x80000>; /* GICR */ + + interrupts = ; + + its1: its@30040000 { + compatible = "arm,gic-v3-its"; + msi-controller; + #msi-cells = <1>; + reg = <0x0 0x30040000 0x0 0x20000>; + }; + + its2: its@30060000 { + compatible = "arm,gic-v3-its"; + msi-controller; + #msi-cells = <1>; + reg = <0x0 0x30060000 0x0 0x20000>; + }; + + its_ccix: its@30080000 { + compatible = "arm,gic-v3-its"; + msi-controller; + #msi-cells = <1>; + reg = <0x0 0x30080000 0x0 0x20000>; + }; + + its_pcie: its@300a0000 { + compatible = "arm,gic-v3-its"; + msi-controller; + #msi-cells = <1>; + reg = <0x0 0x300a0000 0x0 0x20000>; + }; + }; + + smmu_ccix: iommu@4f000000 { + compatible = "arm,smmu-v3"; + reg = <0 0x4f000000 0 0x40000>; + interrupts = , + , + ; + interrupt-names = "eventq", "cmdq-sync", "gerror"; + msi-parent = <&its1 0>; + #iommu-cells = <1>; + dma-coherent; + }; + + smmu_pcie: iommu@4f400000 { + compatible = "arm,smmu-v3"; + reg = <0 0x4f400000 0 0x40000>; + interrupts = , + , + ; + interrupt-names = "eventq", "cmdq-sync", "gerror"; + msi-parent = <&its2 0>; + #iommu-cells = <1>; + dma-coherent; + }; + + pcie_ctlr: pcie@70000000 { + compatible = "arm,n1sdp-pcie"; + device_type = "pci"; + reg = <0 0x70000000 0 0x1200000>; + bus-range = <0 17>; + linux,pci-domain = <0>; + #address-cells = <3>; + #size-cells = <2>; + dma-coherent; + ranges = <0x01000000 0x00 0x00000000 0x00 0x75200000 0x00 0x00010000>, + <0x02000000 0x00 0x71200000 0x00 0x71200000 0x00 0x04000000>, + <0x42000000 0x09 0x00000000 0x09 0x00000000 0x20 0x00000000>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &gic 0 0 0 169 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &gic 0 0 0 170 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &gic 0 0 0 171 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &gic 0 0 0 172 IRQ_TYPE_LEVEL_HIGH>; + msi-map = <0 &its_pcie 0 0x10000>; + iommu-map = <0 &smmu_pcie 0 0x10000>; + status = "disabled"; + }; + + ccix_pcie_ctlr: pcie@68000000 { + compatible = "arm,n1sdp-pcie"; + device_type = "pci"; + reg = <0 0x68000000 0 0x1200000>; + bus-range = <0 17>; + linux,pci-domain = <1>; + #address-cells = <3>; + #size-cells = <2>; + dma-coherent; + ranges = <0x01000000 0x00 0x00000000 0x00 0x6d200000 0x00 0x00010000>, + <0x02000000 0x00 0x69200000 0x00 0x69200000 0x00 0x04000000>, + <0x42000000 0x29 0x00000000 0x29 0x00000000 0x20 0x00000000>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &gic 0 0 0 201 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &gic 0 0 0 202 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &gic 0 0 0 203 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &gic 0 0 0 204 IRQ_TYPE_LEVEL_HIGH>; + msi-map = <0 &its_ccix 0 0x10000>; + iommu-map = <0 &smmu_ccix 0 0x10000>; + status = "disabled"; + }; + + soc_uart0: serial@2a400000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0 0x2a400000 0x0 0x1000>; + interrupts = ; + clocks = <&soc_uartclk>, <&soc_refclk100mhz>; + clock-names = "uartclk", "apb_pclk"; + status = "disabled"; + }; + }; +}; diff --git a/plat/arm/board/n1sdp/platform.mk b/plat/arm/board/n1sdp/platform.mk index 0bd3a21cf..4b621e3c0 100644 --- a/plat/arm/board/n1sdp/platform.mk +++ b/plat/arm/board/n1sdp/platform.mk @@ -38,6 +38,8 @@ BL31_SOURCES := ${N1SDP_CPU_SOURCES} \ ${N1SDP_BASE}/n1sdp_security.c \ drivers/arm/css/sds/sds.c +FDT_SOURCES += fdts/${PLAT}-single-chip.dts \ + fdts/${PLAT}-multi-chip.dts # TF-A not required to load the SCP Images override CSS_LOAD_SCP_IMAGES := 0 -- cgit v1.2.3 From 482706898901b5dcc3f70b49b6dd9f36000950af Mon Sep 17 00:00:00 2001 From: Moti Buskila Date: Sun, 6 Oct 2019 16:36:27 +0300 Subject: plat: marvell: armada: add support for twin-die combined memory device the twin-die combined memory device should be treated as X8 device and not as X16 one. This patch is required to re-enable compilation after BLE (mv-ddr-marvell) firmware upgrade. Change-Id: I41257ff2825164ebca85a84bbb8462d7b3447b97 Signed-off-by: Moti Buskila Signed-off-by: Marcin Wojtas --- plat/marvell/armada/a8k/a70x0/board/dram_port.c | 1 + plat/marvell/armada/a8k/a70x0_amc/board/dram_port.c | 1 + plat/marvell/armada/a8k/a80x0/board/dram_port.c | 1 + plat/marvell/armada/a8k/a80x0_mcbin/board/dram_port.c | 1 + plat/marvell/armada/a8k/a80x0_puzzle/board/dram_port.c | 1 + 5 files changed, 5 insertions(+) diff --git a/plat/marvell/armada/a8k/a70x0/board/dram_port.c b/plat/marvell/armada/a8k/a70x0/board/dram_port.c index 4fca7e383..355770b65 100644 --- a/plat/marvell/armada/a8k/a70x0/board/dram_port.c +++ b/plat/marvell/armada/a8k/a70x0/board/dram_port.c @@ -46,6 +46,7 @@ static struct mv_ddr_topology_map board_topology_map = { MV_DDR_TEMP_LOW} }, /* temperature */ MV_DDR_32BIT_ECC_PUP8_BUS_MASK, /* 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 */ diff --git a/plat/marvell/armada/a8k/a70x0_amc/board/dram_port.c b/plat/marvell/armada/a8k/a70x0_amc/board/dram_port.c index aecf6c567..9c8c97e09 100644 --- a/plat/marvell/armada/a8k/a70x0_amc/board/dram_port.c +++ b/plat/marvell/armada/a8k/a70x0_amc/board/dram_port.c @@ -46,6 +46,7 @@ static struct mv_ddr_topology_map board_topology_map = { MV_DDR_TEMP_LOW} }, /* temperature */ MV_DDR_32BIT_ECC_PUP8_BUS_MASK, /* 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 */ diff --git a/plat/marvell/armada/a8k/a80x0/board/dram_port.c b/plat/marvell/armada/a8k/a80x0/board/dram_port.c index 017d8a734..381c87150 100644 --- a/plat/marvell/armada/a8k/a80x0/board/dram_port.c +++ b/plat/marvell/armada/a8k/a80x0/board/dram_port.c @@ -58,6 +58,7 @@ static struct mv_ddr_topology_map board_topology_map = { MV_DDR_64BIT_ECC_PUP8_BUS_MASK, /* subphys mask */ #endif MV_DDR_CFG_SPD, /* ddr configuration data source */ + NOT_COMBINED, /* ddr twin-die combined*/ { {0} }, /* raw spd data */ {0}, /* timing parameters */ { /* electrical configuration */ diff --git a/plat/marvell/armada/a8k/a80x0_mcbin/board/dram_port.c b/plat/marvell/armada/a8k/a80x0_mcbin/board/dram_port.c index 25808523c..50a68b3a2 100644 --- a/plat/marvell/armada/a8k/a80x0_mcbin/board/dram_port.c +++ b/plat/marvell/armada/a8k/a80x0_mcbin/board/dram_port.c @@ -48,6 +48,7 @@ static struct mv_ddr_topology_map board_topology_map = { MV_DDR_TEMP_LOW} }, /* temperature */ MV_DDR_64BIT_BUS_MASK, /* subphys mask */ MV_DDR_CFG_SPD, /* ddr configuration data source */ + NOT_COMBINED, /* ddr twin-die combined*/ { {0} }, /* raw spd data */ {0}, /* timing parameters */ { /* electrical configuration */ diff --git a/plat/marvell/armada/a8k/a80x0_puzzle/board/dram_port.c b/plat/marvell/armada/a8k/a80x0_puzzle/board/dram_port.c index 46a9a26b9..3879c983a 100644 --- a/plat/marvell/armada/a8k/a80x0_puzzle/board/dram_port.c +++ b/plat/marvell/armada/a8k/a80x0_puzzle/board/dram_port.c @@ -54,6 +54,7 @@ static struct mv_ddr_topology_map board_topology_map = { MV_DDR_TEMP_LOW} }, /* temperature */ MV_DDR_64BIT_BUS_MASK, /* subphys mask */ MV_DDR_CFG_SPD, /* ddr configuration data source */ + NOT_COMBINED, /* ddr twin-die combined*/ { {0} }, /* raw spd data */ {0}, /* timing parameters */ { /* electrical configuration */ -- cgit v1.2.3 From ebf307bfefccf57f3cbdc1a03c3d37afa1896193 Mon Sep 17 00:00:00 2001 From: Alex Evraev Date: Sun, 11 Aug 2019 13:38:15 +0300 Subject: plat: marvell: armada: a7k: add support to SVC validation mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for “AVS reduction” feature at this mode for 7040 Dual Cluster operation mode at CPU=1600MHz Change-Id: Ia72b10e0ccfad07568bf4c089ea3990173ae24b2 Signed-off-by: Alex Evraev --- plat/marvell/armada/a8k/common/plat_ble_setup.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/plat/marvell/armada/a8k/common/plat_ble_setup.c b/plat/marvell/armada/a8k/common/plat_ble_setup.c index f11b5ac17..ccc8eadfb 100644 --- a/plat/marvell/armada/a8k/common/plat_ble_setup.c +++ b/plat/marvell/armada/a8k/common/plat_ble_setup.c @@ -554,8 +554,18 @@ static void ble_plat_svc_config(void) if (perr[0]) goto perror; avs_workpoint = svc[0]; - } else + } else { +#if MARVELL_SVC_TEST + reg_val = mmio_read_32(AVS_EN_CTRL_REG); + avs_workpoint = (reg_val & + AVS_VDD_LOW_LIMIT_MASK) >> + AVS_LOW_VDD_LIMIT_OFFSET; + NOTICE("7040 1600Mhz, avs = 0x%x\n", + avs_workpoint); +#else avs_workpoint = 0; +#endif + } break; } } else if (device_id == MVEBU_3900_DEV_ID) { -- cgit v1.2.3 From 5bc3643e57963c9b61a40be2fe5ae6166fd6fdb8 Mon Sep 17 00:00:00 2001 From: Ben Peled Date: Wed, 27 Mar 2019 16:26:02 +0200 Subject: plat: marvell: t9130: pass actual CP count for load_image Add CN913x case to bl2_plat_get_cp_count. Fix loading of cp1/2 image. This is a preparation patch for adding CN913x SoC family support. Change-Id: Id84a30203d20572fc0dfd3f91ea395c199a85fe9 Signed-off-by: Ben Peled --- include/drivers/marvell/mochi/cp110_setup.h | 1 + plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/include/drivers/marvell/mochi/cp110_setup.h b/include/drivers/marvell/mochi/cp110_setup.h index f8cd26b12..11dc4e020 100644 --- a/include/drivers/marvell/mochi/cp110_setup.h +++ b/include/drivers/marvell/mochi/cp110_setup.h @@ -24,6 +24,7 @@ #define MVEBU_3900_DEV_ID (0x6025) #define MVEBU_80X0_DEV_ID (0x8040) #define MVEBU_80X0_CP115_DEV_ID (0x8045) +#define MVEBU_CN9130_DEV_ID (0x7025) #define MVEBU_CP110_SA_DEV_ID (0x110) #define MVEBU_CP110_REF_ID_A1 1 #define MVEBU_CP110_REF_ID_A2 2 diff --git a/plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c b/plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c index c2cd93357..b919cb337 100644 --- a/plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c +++ b/plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c @@ -138,6 +138,8 @@ uint32_t bl2_plat_get_cp_count(int ap_idx) if (revision == MVEBU_80X0_DEV_ID || revision == MVEBU_80X0_CP115_DEV_ID) return 2; + else if (revision == MVEBU_CN9130_DEV_ID) + return CP_COUNT; else return 1; } -- cgit v1.2.3 From 885cd821f82e8912081a22a79357a638a9c4bc6c Mon Sep 17 00:00:00 2001 From: Grzegorz Jaszczyk Date: Thu, 24 Jan 2019 10:18:33 +0100 Subject: plat: marvell: t9130: update AVS settings Update AVS settings and remove unused macros. This is a preparation patch for adding CN913x SoC family support. Change-Id: Ib1dd70885a316ed5763d0f4730d0e4734da117b7 Signed-off-by: Grzegorz Jaszczyk --- plat/marvell/armada/a8k/common/plat_ble_setup.c | 32 +++---------------------- 1 file changed, 3 insertions(+), 29 deletions(-) diff --git a/plat/marvell/armada/a8k/common/plat_ble_setup.c b/plat/marvell/armada/a8k/common/plat_ble_setup.c index ccc8eadfb..23d695558 100644 --- a/plat/marvell/armada/a8k/common/plat_ble_setup.c +++ b/plat/marvell/armada/a8k/common/plat_ble_setup.c @@ -74,22 +74,9 @@ (0x24 << AVS_LOW_VDD_LIMIT_OFFSET) | \ (0x1 << AVS_SOFT_RESET_OFFSET) | \ (0x1 << AVS_ENABLE_OFFSET)) -/* VDD limit is 0.82V for all A3900 devices - * AVS offsets are not the same as in A70x0 - */ -#define AVS_A3900_CLK_VALUE ((0x80u << 24) | \ - (0x2c2 << 13) | \ - (0x2c2 << 3) | \ - (0x1 << AVS_SOFT_RESET_OFFSET) | \ - (0x1 << AVS_ENABLE_OFFSET)) -/* VDD is 0.88V for 2GHz clock */ -#define AVS_A3900_HIGH_CLK_VALUE ((0x80u << 24) | \ - (0x2f5 << 13) | \ - (0x2f5 << 3) | \ - (0x1 << AVS_SOFT_RESET_OFFSET) | \ - (0x1 << AVS_ENABLE_OFFSET)) -#define AVS_CN9130_HIGH_CLK_VALUE ((0x80 << 24) | \ +/* VDD is 0.88V for 2GHz clock on CN913x devices */ +#define AVS_AP807_CLK_VALUE ((0x80UL << 24) | \ (0x2dc << 13) | \ (0x2dc << 3) | \ (0x1 << AVS_SOFT_RESET_OFFSET) | \ @@ -229,20 +216,7 @@ static void ble_plat_avs_config(void) FREQ_MODE_AP_SAR_REG_NUM))); /* Check which SoC is running and act accordingly */ if (ble_get_ap_type() == CHIP_ID_AP807) { - /* Increase CPU voltage for higher CPU clock */ - switch (freq_mode) { - case CPU_2000_DDR_1200_RCLK_1200: - avs_val = AVS_A3900_HIGH_CLK_VALUE; - break; -#ifdef MVEBU_SOC_AP807 - case CPU_2200_DDR_1200_RCLK_1200: - avs_val = AVS_CN9130_HIGH_CLK_VALUE; - break; -#endif - default: - avs_val = AVS_A3900_CLK_VALUE; - } - + avs_val = AVS_AP807_CLK_VALUE; } else { /* Check which SoC is running and act accordingly */ device_id = cp110_device_id_get(MVEBU_CP_REGS_BASE(0)); -- cgit v1.2.3 From 12c66c6b4863a1481e457c4837caa4e06a829173 Mon Sep 17 00:00:00 2001 From: Alex Evraev Date: Mon, 6 May 2019 13:15:07 +0300 Subject: plat: marvell: t9130: add SVC support As the preparation for adding the CN913x SoC family support introduce code that enable SVC and the frequency handling specific for the AP807 North Bridge. Change-Id: Ibe34a511b49cd9671a2e53b77bdcfc644bb915e3 Signed-off-by: Alex Evraev --- plat/marvell/armada/a8k/common/plat_ble_setup.c | 64 ++++++++++++++++++++----- 1 file changed, 52 insertions(+), 12 deletions(-) diff --git a/plat/marvell/armada/a8k/common/plat_ble_setup.c b/plat/marvell/armada/a8k/common/plat_ble_setup.c index 23d695558..e4e09fb41 100644 --- a/plat/marvell/armada/a8k/common/plat_ble_setup.c +++ b/plat/marvell/armada/a8k/common/plat_ble_setup.c @@ -110,7 +110,6 @@ #define EFUSE_AP_LD0_REVID_MASK 0xF #define EFUSE_AP_LD0_BIN_OFFS 16 /* LD0[80:79] */ #define EFUSE_AP_LD0_BIN_MASK 0x3 -#define EFUSE_AP_LD0_SWREV_OFFS 50 /* LD0[115:113] */ #define EFUSE_AP_LD0_SWREV_MASK 0x7 #ifndef MVEBU_SOC_AP807 @@ -124,16 +123,18 @@ #define EFUSE_AP_LD0_SVC2_OFFS 26 /* LD0[96:89] */ #define EFUSE_AP_LD0_SVC3_OFFS 34 /* LD0[104:97] */ #define EFUSE_AP_LD0_WP_MASK 0xFF + #define EFUSE_AP_LD0_SWREV_OFFS 50 /* LD0[115:113] */ #else /* AP807 AVS work points in the LD0 eFuse * SVC1 work point: LD0[91:81] * SVC2 work point: LD0[102:92] * SVC3 work point: LD0[113:103] */ - #define EFUSE_AP_LD0_SVC1_OFFS 17 /* LD0[91:81] */ - #define EFUSE_AP_LD0_SVC2_OFFS 28 /* LD0[102:92] */ - #define EFUSE_AP_LD0_SVC3_OFFS 39 /* LD0[113:103] */ - #define EFUSE_AP_LD0_WP_MASK 0x3FF + #define EFUSE_AP_LD0_SVC1_OFFS 18 /* LD0[91:81] */ + #define EFUSE_AP_LD0_SVC2_OFFS 29 /* LD0[102:92] */ + #define EFUSE_AP_LD0_SVC3_OFFS 40 /* LD0[113:103] */ + #define EFUSE_AP_LD0_WP_MASK 0x7FF /* 10 data,1 parity */ + #define EFUSE_AP_LD0_SWREV_OFFS 51 /* LD0[116:114] */ #endif #define EFUSE_AP_LD0_SVC4_OFFS 42 /* LD0[112:105] */ @@ -216,7 +217,9 @@ static void ble_plat_avs_config(void) FREQ_MODE_AP_SAR_REG_NUM))); /* Check which SoC is running and act accordingly */ if (ble_get_ap_type() == CHIP_ID_AP807) { + avs_val = AVS_AP807_CLK_VALUE; + } else { /* Check which SoC is running and act accordingly */ device_id = cp110_device_id_get(MVEBU_CP_REGS_BASE(0)); @@ -370,6 +373,7 @@ static void ble_plat_svc_config(void) uint64_t efuse; uint32_t device_id, single_cluster; uint16_t svc[4], perr[4], i, sw_ver; + uint8_t avs_data_bits, min_sw_ver, svc_fields; unsigned int ap_type; /* Set access to LD0 */ @@ -423,22 +427,28 @@ static void ble_plat_svc_config(void) & EFUSE_AP_LD0_WP_MASK; INFO("SVC: Efuse WP: [0]=0x%x, [1]=0x%x, [2]=0x%x, [3]=0x%x\n", svc[0], svc[1], svc[2], svc[3]); + avs_data_bits = 7; + min_sw_ver = 2; /* parity check from sw revision 2 */ + svc_fields = 4; } else { INFO("SVC: Efuse WP: [0]=0x%x, [1]=0x%x, [2]=0x%x\n", svc[0], svc[1], svc[2]); + avs_data_bits = 10; + min_sw_ver = 1; /* parity check required from sw revision 1 */ + svc_fields = 3; } /* Validate parity of SVC workpoint values */ - for (i = 0; i < 4; i++) { + for (i = 0; i < svc_fields; i++) { uint8_t parity, bit; - perr[i] = 0; - for (bit = 1, parity = svc[i] & 1; bit < 7; bit++) + for (bit = 1, parity = (svc[i] & 1); bit < avs_data_bits; bit++) parity ^= (svc[i] >> bit) & 1; - /* Starting from SW version 2, the parity check is mandatory */ - if ((sw_ver > 1) && (parity != ((svc[i] >> 7) & 1))) + /* From SW version 1 or 2 (AP806/AP807), check parity */ + if ((sw_ver >= min_sw_ver) && + (parity != ((svc[i] >> avs_data_bits) & 1))) perr[i] = 1; /* register the error */ } @@ -537,7 +547,8 @@ static void ble_plat_svc_config(void) NOTICE("7040 1600Mhz, avs = 0x%x\n", avs_workpoint); #else - avs_workpoint = 0; + NOTICE("SVC: AVS work point not changed\n"); + return; #endif } break; @@ -562,6 +573,31 @@ static void ble_plat_svc_config(void) avs_workpoint = svc[0]; break; } + } else if (device_id == MVEBU_CN9130_DEV_ID) { + NOTICE("SVC: DEV ID: %s, FREQ Mode: 0x%x\n", + "CN913x", freq_pidi_mode); + switch (freq_pidi_mode) { + case CPU_2200_DDR_1200_RCLK_1200: + if (perr[0]) + goto perror; + avs_workpoint = svc[0]; + break; + case CPU_2000_DDR_1200_RCLK_1200: + if (perr[1]) + goto perror; + avs_workpoint = svc[1]; + break; + case CPU_1600_DDR_1200_RCLK_1200: + if (perr[2]) + goto perror; + avs_workpoint = svc[2]; + break; + default: + ERROR("SVC: Unsupported Frequency 0x%x\n", + freq_pidi_mode); + return; + + } } else { ERROR("SVC: Unsupported Device ID 0x%x\n", device_id); return; @@ -569,13 +605,17 @@ static void ble_plat_svc_config(void) /* Set AVS control if needed */ if (avs_workpoint == 0) { - ERROR("SVC: AVS work point not changed\n"); + ERROR("SVC: You are using a frequency setup which is\n"); + ERROR("Not supported by this device\n"); + ERROR("This may result in malfunction of the device\n"); return; } /* Remove parity bit */ if (ap_type != CHIP_ID_AP807) avs_workpoint &= 0x7F; + else + avs_workpoint &= 0x3FF; /* Update WP from EEPROM if needed */ avs_workpoint = avs_update_from_eeprom(avs_workpoint); -- cgit v1.2.3 From 2c9d263682961c7f7efc815d1884fe0e71bcf30f Mon Sep 17 00:00:00 2001 From: Grzegorz Jaszczyk Date: Sun, 9 Dec 2018 22:08:20 +0100 Subject: plat: marvell: octeontx: add support for t9130 CN-9130 has single CP0 inside the package and 2 additional one from MoChi interface. In case of db-9130-modular board the MCI interface is routed to: - on-board CP115 (MCI0) - extension board CP115 (MCI1) The board is based on DIMM DDR. The 9130 has up to 3CP, and decoding windows looks like below: (free for further use) .----------. 0xf800 0000 | CP2 CFG | '----------' 0xf600 0000 | CP1 CFG | '----------' 0xf400 0000 | CP0 CFG | '----------' 0xf200 0000 | AP CFG | '----------' 0xf000 0000 (free for further use) .----------. 0xec00 0000 | SPI | | MEM_MAP | (Currently not opened) '----------' 0xe800 0000 | PEX2_CP2 | '----------' 0xe700 0000 | PEX1_CP2 | '----------' 0xe600 0000 | PEX0-CP2 | '----------' .----------. 0xe500 0000 | PEX2_CP1 | '----------' 0xe400 0000 | PEX1_CP1 | '----------' 0xe300 0000 | PEX0-CP1 | '----------' .----------. 0xe200 0000 | PEX2-CP0 | '----------' 0xe100 0000 | PEX1-CP0 | '----------' 0xe000 0000 | PEX0-CP0 | | 512MB | '----------' 0xc000 0000 Change-Id: Ia8eee4f96c1043753f74f9da437b9f72ce2d6eb0 Signed-off-by: Grzegorz Jaszczyk --- .../octeontx/otx2/t91/t9130/board/dram_port.c | 158 +++++++++++++++++ .../otx2/t91/t9130/board/marvell_plat_config.c | 188 +++++++++++++++++++++ .../otx2/t91/t9130/board/phy-porting-layer.h | 138 +++++++++++++++ plat/marvell/octeontx/otx2/t91/t9130/mvebu_def.h | 25 +++ plat/marvell/octeontx/otx2/t91/t9130/platform.mk | 20 +++ 5 files changed, 529 insertions(+) create mode 100644 plat/marvell/octeontx/otx2/t91/t9130/board/dram_port.c create mode 100644 plat/marvell/octeontx/otx2/t91/t9130/board/marvell_plat_config.c create mode 100644 plat/marvell/octeontx/otx2/t91/t9130/board/phy-porting-layer.h create mode 100644 plat/marvell/octeontx/otx2/t91/t9130/mvebu_def.h create mode 100644 plat/marvell/octeontx/otx2/t91/t9130/platform.mk diff --git a/plat/marvell/octeontx/otx2/t91/t9130/board/dram_port.c b/plat/marvell/octeontx/otx2/t91/t9130/board/dram_port.c new file mode 100644 index 000000000..0befadfc6 --- /dev/null +++ b/plat/marvell/octeontx/otx2/t91/t9130/board/dram_port.c @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include +#include +#include + +#include +#include +#include + +#define MVEBU_CP_MPP_CTRL37_OFFS 20 +#define MVEBU_CP_MPP_CTRL38_OFFS 24 +#define MVEBU_CP_MPP_CTRL37_I2C0_SCK_ENA 0x2 +#define MVEBU_CP_MPP_CTRL38_I2C0_SDA_ENA 0x2 + +#define MVEBU_MPP_CTRL_MASK 0xf + +/* + * This struct provides the DRAM training code with + * the appropriate board DRAM configuration + */ +struct mv_ddr_iface dram_iface_ap0 = { + .ap_base = MVEBU_REGS_BASE_AP(0), + .state = MV_DDR_IFACE_NRDY, + .validation = MV_DDR_MEMORY_CHECK, + .sscg = SSCG_EN, + .id = 0, + .iface_base_addr = 0, + .tm = { + DEBUG_LEVEL_ERROR, + 0x1, /* active interfaces */ + /* cs_mask, mirror, dqs_swap, ck_swap X subphys */ + { { { {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0}, + {0x1, 0x0, 0, 0} }, + SPEED_BIN_DDR_2400T, /* 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 */ +#if DDR32 + MV_DDR_32BIT_ECC_PUP8_BUS_MASK, /* subphys mask */ +#else + MV_DDR_64BIT_ECC_PUP8_BUS_MASK, /* subphys mask */ +#endif + MV_DDR_CFG_SPD, /* ddr configuration data src */ + 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 */ + { /* rtt_park 1cs */ + MV_DDR_RTT_NOM_PARK_RZQ_DIV4, + /* rtt_park 2cs */ + MV_DDR_RTT_NOM_PARK_RZQ_DIV1 + }, + { /* rtt_wr 1cs */ + MV_DDR_RTT_WR_DYN_ODT_OFF, + /* rtt_wr 2cs */ + MV_DDR_RTT_WR_RZQ_DIV2 + }, + 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 */ + }, + }, + }, +}; + +/* Pointer to the first DRAM interface in the system */ +struct mv_ddr_iface *ptr_iface = &dram_iface_ap0; + +struct mv_ddr_iface *mv_ddr_iface_get(void) +{ + /* Return current ddr interface */ + return ptr_iface; +} + +struct mv_ddr_topology_map *mv_ddr_topology_map_get(void) +{ + /* Return the board topology as defined in the board code */ + return &ptr_iface->tm; +} + +static void mpp_config(void) +{ + uintptr_t reg; + uint32_t val; + + reg = MVEBU_CP_MPP_REGS(0, 4); + /* configure CP0 MPP 37 and 38 to i2c */ + val = mmio_read_32(reg); + val &= ~((MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL37_OFFS) | + (MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL38_OFFS)); + val |= (MVEBU_CP_MPP_CTRL37_I2C0_SCK_ENA << + MVEBU_CP_MPP_CTRL37_OFFS) | + (MVEBU_CP_MPP_CTRL38_I2C0_SDA_ENA << + MVEBU_CP_MPP_CTRL38_OFFS); + mmio_write_32(reg, val); +} + +/* + * 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) +{ + struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); + + INFO("Gathering DRAM information\n"); + + if (tm->cfg_src == MV_DDR_CFG_SPD) { + /* configure MPPs to enable i2c */ + mpp_config(); + + /* initialize i2c */ + i2c_init((void *)MVEBU_CP0_I2C_BASE); + + /* select SPD memory page 0 to access DRAM configuration */ + i2c_write(I2C_SPD_P0_ADDR, 0x0, 1, tm->spd_data.all_bytes, 1); + + /* read data from spd */ + i2c_read(I2C_SPD_ADDR, 0x0, 1, tm->spd_data.all_bytes, + sizeof(tm->spd_data.all_bytes)); + } +} diff --git a/plat/marvell/octeontx/otx2/t91/t9130/board/marvell_plat_config.c b/plat/marvell/octeontx/otx2/t91/t9130/board/marvell_plat_config.c new file mode 100644 index 000000000..7debd6582 --- /dev/null +++ b/plat/marvell/octeontx/otx2/t91/t9130/board/marvell_plat_config.c @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include + +/* + * If bootrom is currently at BLE there's no need to include the memory + * maps structure at this point + */ +#ifndef IMAGE_BLE + +/***************************************************************************** + * AMB Configuration + ***************************************************************************** + */ +struct addr_map_win amb_memory_map_cp0[] = { + /* CP0 SPI1 CS0 Direct Mode access */ + {0xe800, 0x2000000, AMB_SPI1_CS0_ID}, +}; + +int marvell_get_amb_memory_map(struct addr_map_win **win, uint32_t *size, + uintptr_t base) +{ + switch (base) { + case MVEBU_CP_REGS_BASE(0): + *win = amb_memory_map_cp0; + *size = ARRAY_SIZE(amb_memory_map_cp0); + return 0; + case MVEBU_CP_REGS_BASE(1): + case MVEBU_CP_REGS_BASE(2): + default: + *size = 0; + *win = 0; + return 1; + } +} +#endif + +/***************************************************************************** + * IO WIN Configuration + ***************************************************************************** + */ +struct addr_map_win io_win_memory_map[] = { +#ifndef IMAGE_BLE + /* SB (MCi0) PCIe0-2 on CP1 */ + {0x00000000e2000000, 0x3000000, MCI_0_TID}, + /* SB (MCi1) PCIe0-2 on CP2 */ + {0x00000000e5000000, 0x3000000, MCI_1_TID}, + /* SB (MCi0) internal regs */ + {0x00000000f4000000, 0x2000000, MCI_0_TID}, + /* SB (MCi1) internal regs */ + {0x00000000f6000000, 0x2000000, MCI_1_TID}, + /* 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 +}; + +/* Global Control Register - window default target */ +uint32_t marvell_get_io_win_gcr_target(int ap_index) +{ + /* + * PIDI == iMCIP AP to SB internal MoChi connection. + * In other words CP0 + */ + 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_cp0[] = { + /* SPI1_CS0 (RUNIT) window */ + {0x00000000e8000000, 0x2000000, RUNIT_TID}, + /* PEX2_X1 window */ + {0x00000000e1000000, 0x1000000, PEX2_TID}, + /* PEX1_X1 window */ + {0x00000000e0000000, 0x1000000, PEX1_TID}, + /* PEX0_X4 window */ + {0x00000000c0000000, 0x20000000, PEX0_TID}, +}; + +struct addr_map_win iob_memory_map_cp1[] = { + + /* PEX2_X1 window */ + {0x00000000e4000000, 0x1000000, PEX2_TID}, + /* PEX1_X1 window */ + {0x00000000e3000000, 0x1000000, PEX1_TID}, + /* PEX0_X4 window */ + {0x00000000e2000000, 0x1000000, PEX0_TID}, +}; + +struct addr_map_win iob_memory_map_cp2[] = { + + /* PEX2_X1 window */ + {0x00000000e7000000, 0x1000000, PEX2_TID}, + /* PEX1_X1 window */ + {0x00000000e6000000, 0x1000000, PEX1_TID}, + /* PEX0_X4 window */ + {0x00000000e5000000, 0x1000000, PEX0_TID}, +}; + +int marvell_get_iob_memory_map(struct addr_map_win **win, uint32_t *size, + uintptr_t base) +{ + switch (base) { + case MVEBU_CP_REGS_BASE(0): + *win = iob_memory_map_cp0; + *size = ARRAY_SIZE(iob_memory_map_cp0); + return 0; + case MVEBU_CP_REGS_BASE(1): + *win = iob_memory_map_cp1; + *size = ARRAY_SIZE(iob_memory_map_cp1); + return 0; + case MVEBU_CP_REGS_BASE(2): + *win = iob_memory_map_cp2; + *size = ARRAY_SIZE(iob_memory_map_cp2); + return 0; + default: + *size = 0; + *win = 0; + return 1; + } +} +#endif + +/***************************************************************************** + * CCU Configuration + ***************************************************************************** + */ +struct addr_map_win ccu_memory_map[] = { /* IO window */ +#ifdef IMAGE_BLE + {0x00000000f2000000, 0x6000000, IO_0_TID}, /* IO window */ +#else +#if LLC_SRAM + {PLAT_MARVELL_LLC_SRAM_BASE, PLAT_MARVELL_LLC_SRAM_SIZE, DRAM_0_TID}, +#endif + {0x00000000f2000000, 0xe000000, IO_0_TID}, /* IO window */ + {0x00000000c0000000, 0x30000000, IO_0_TID}, /* IO window */ + {0x0000002000000000, 0x70e000000, IO_0_TID}, /* IO for CV-OS */ +#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 + ***************************************************************************** + */ +void *plat_get_skip_image_data(void) +{ + /* No recovery button on CN-9130 board? */ + return NULL; +} +#endif diff --git a/plat/marvell/octeontx/otx2/t91/t9130/board/phy-porting-layer.h b/plat/marvell/octeontx/otx2/t91/t9130/board/phy-porting-layer.h new file mode 100644 index 000000000..a8660552e --- /dev/null +++ b/plat/marvell/octeontx/otx2/t91/t9130/board/phy-porting-layer.h @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2018 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 +#define XFI_PARAMS static const struct xfi_params + + +XFI_PARAMS xfi_static_values_tab[AP_NUM][CP_NUM][MAX_LANE_NR] = { + /* AP0 */ + { + /* CP 0 */ + { + { 0 }, /* Comphy0 not relevant*/ + { 0 }, /* Comphy1 not relevant*/ + { .g1_ffe_res_sel = 0x3, .g1_ffe_cap_sel = 0xf, + .align90 = 0x5f, + .g1_dfe_res = 0x2, .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 }, /* Comphy2 */ + { 0 }, /* Comphy3 not relevant*/ + { .g1_ffe_res_sel = 0x3, .g1_ffe_cap_sel = 0xf, + .align90 = 0x5f, + .g1_dfe_res = 0x2, .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 not relevant*/ + }, +#if CP_NUM > 1 + /* CP 1 */ + { + { 0 }, /* Comphy0 not relevant*/ + { 0 }, /* Comphy1 not relevant*/ + { .g1_ffe_res_sel = 0x3, .g1_ffe_cap_sel = 0xf, + .align90 = 0x5f, + .g1_dfe_res = 0x2, .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 }, /* Comphy2 */ + { 0 }, /* Comphy3 not relevant*/ + /* different from defaults */ + { .g1_ffe_res_sel = 0x3, .g1_ffe_cap_sel = 0xf, + .align90 = 0x5f, + .g1_dfe_res = 0x2, .g1_amp = 0xc, + .g1_emph = 0x5, + .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 not relevant*/ + }, +#if CP_NUM > 2 + /* CP 2 */ + { + { 0 }, /* Comphy0 not relevant*/ + { 0 }, /* Comphy1 not relevant*/ + { .g1_ffe_res_sel = 0x3, .g1_ffe_cap_sel = 0xf, + .align90 = 0x5f, + .g1_dfe_res = 0x2, .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 }, /* Comphy2 */ + { 0 }, /* Comphy3 not relevant*/ + { .g1_ffe_res_sel = 0x3, .g1_ffe_cap_sel = 0xf, + .align90 = 0x5f, + .g1_dfe_res = 0x2, .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 not relevant*/ + }, +#endif +#endif + }, +}; + +#define SATA_PARAMS static const struct sata_params +SATA_PARAMS sata_static_values_tab[AP_NUM][CP_NUM][MAX_LANE_NR] = { + [0 ... AP_NUM-1][0 ... CP_NUM-1][0 ... MAX_LANE_NR-1] = { + .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, + .valid = 0x1 + }, +}; + +#endif /* __PHY_PORTING_LAYER_H */ diff --git a/plat/marvell/octeontx/otx2/t91/t9130/mvebu_def.h b/plat/marvell/octeontx/otx2/t91/t9130/mvebu_def.h new file mode 100644 index 000000000..490be7350 --- /dev/null +++ b/plat/marvell/octeontx/otx2/t91/t9130/mvebu_def.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef __MVEBU_DEF_H__ +#define __MVEBU_DEF_H__ + +#include + +/* + * CN-9130 has single CP0 inside the package and 2 additional one + * from MoChi interface. In case of db-9130-modular board the MCI interface + * is routed to: + * - on-board CP115 (MCI0) + * - extension board CP115 (MCI1) + */ +#define CP_COUNT CP_NUM +#define MVEBU_SOC_AP807 1 +#define I2C_SPD_ADDR 0x53 /* Access SPD data */ +#define I2C_SPD_P0_ADDR 0x36 /* Select SPD data page 0 */ + +#endif /* __MVEBU_DEF_H__ */ diff --git a/plat/marvell/octeontx/otx2/t91/t9130/platform.mk b/plat/marvell/octeontx/otx2/t91/t9130/platform.mk new file mode 100644 index 000000000..1e2716df0 --- /dev/null +++ b/plat/marvell/octeontx/otx2/t91/t9130/platform.mk @@ -0,0 +1,20 @@ +# +# Copyright (C) 2018 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/ap807_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 -- cgit v1.2.3 From eed02440afd123689b44fb2da657a2b7e1f4a33d Mon Sep 17 00:00:00 2001 From: Konstantin Porotchkin Date: Tue, 19 Feb 2019 10:40:33 +0200 Subject: docs: marvell: update build instructions with CN913x Add references to the OcteonTX2 CN913x family. Change-Id: I172a8e3d061086bf4843acad014c113c80359e01 Signed-off-by: Konstantin Porotchkin --- docs/plat/marvell/armada/build.rst | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/docs/plat/marvell/armada/build.rst b/docs/plat/marvell/armada/build.rst index da4ba565a..6b9054c7c 100644 --- a/docs/plat/marvell/armada/build.rst +++ b/docs/plat/marvell/armada/build.rst @@ -26,7 +26,7 @@ BL33 should be ``~/project/u-boot/u-boot.bin`` *u-boot.bin* should be used and not *u-boot-spl.bin* -Set MSS/SCP image path (mandatory only for Armada80x0) +Set MSS/SCP image path (mandatory only for A7K/8K/CN913x) .. code:: shell @@ -92,22 +92,31 @@ There are several build options: - BLE_PATH - Points to BLE (Binary ROM extension) sources folder. Only required for A8K builds. + Points to BLE (Binary ROM extension) sources folder. + Only required for A7K/8K/CN913x builds. The parameter is optional, its default value is ``plat/marvell/armada/a8k/common/ble``. - MV_DDR_PATH - For A7/8K, use this parameter to point to mv_ddr driver sources to allow BLE build. For A37x0, + For A7K/8K/CN913x, use this parameter to point to mv_ddr driver sources to allow BLE build. For A37x0, it is used for ddr_tool build. Usage example: MV_DDR_PATH=path/to/mv_ddr - The parameter is optional for A7/8K, when this parameter is not set, the mv_ddr + The parameter is optional for A7K/8K/CN913x, when this parameter is not set, the mv_ddr sources are expected to be located at: drivers/marvell/mv_ddr. However, the parameter is necessary for A37x0. For the mv_ddr source location, check the section "Tools and external components installation" +- CP_NUM + + Total amount of CPs (South Bridge) connected to AP. When the parameter is omitted, + the build uses the default number of CPs, which is a number of embedded CPs inside the + package: 1 or 2 depending on the SoC used. The parameter is valid for OcteonTX2 CN913x SoC + family (PLAT=t9130), which can have external CPs connected to the MCI ports. Valid + values with CP_NUM are in a range of 1 to 3. + - DDR_TOPOLOGY For Armada37x0 only, the DDR topology map index/name, default is 0. @@ -191,7 +200,8 @@ There are several build options: - a70x0 - a70x0_amc (for AMC board) - a80x0 - - a80x0_mcbin (for MacciatoBin) + - a80x0_mcbin (for MacchiatoBin) + - t9130 (OcteonTX2 CN913x) Special Build Flags -------------------- @@ -199,7 +209,7 @@ Special Build Flags - PLAT_RECOVERY_IMAGE_ENABLE When set this option to enable secondary recovery function when build atf. In order to build UART recovery image this operation should be disabled for - a70x0 and a80x0 because of hardware limitation (boot from secondary image + A7K/8K/CN913x because of hardware limitation (boot from secondary image can interrupt UART recovery process). This MACRO definition is set in ``plat/marvell/armada/a8k/common/include/platform_def.h`` file. -- cgit v1.2.3 From 663f6bcfe8ebb041f57674655deaeba6368bb025 Mon Sep 17 00:00:00 2001 From: Grzegorz Jaszczyk Date: Mon, 10 Dec 2018 12:01:29 +0100 Subject: docs: marvell: update path in marvell documentation Change-Id: I0cebbaa900aa518700f13cbf02f8a97e0c76b21c Signed-off-by: Grzegorz Jaszczyk --- docs/plat/marvell/armada/porting.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/plat/marvell/armada/porting.rst b/docs/plat/marvell/armada/porting.rst index 1723ebb57..e3fc9ba73 100644 --- a/docs/plat/marvell/armada/porting.rst +++ b/docs/plat/marvell/armada/porting.rst @@ -36,7 +36,7 @@ memory map is required. .. note:: For a detailed information on how CCU, IOWIN, AXI-MBUS & IOB work, please refer to the SoC functional spec, and under - ``docs/marvell/misc/mvebu-[ccu/iob/amb/io-win].txt`` files. + ``docs/plat/marvell/armada/misc/mvebu-[ccu/iob/amb/io-win].rst`` files. boot loader recovery (marvell_plat_config.c) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- cgit v1.2.3 From 3045dfe10c3daaf3eb93f22090e62e062b19b981 Mon Sep 17 00:00:00 2001 From: Grzegorz Jaszczyk Date: Fri, 22 Mar 2019 11:38:56 +0100 Subject: docs: marvell: update PHY porting layer description The purpose of rx_training had changed after last update. Currently it is not supposed to help with providing static parameters for porting layer. Instead, it aims to suit the parameters per connection. Change-Id: I2a146b71e2e20bd264c090a9a627d0b6bc56e052 Signed-off-by: Grzegorz Jaszczyk --- docs/plat/marvell/armada/porting.rst | 5 ----- 1 file changed, 5 deletions(-) diff --git a/docs/plat/marvell/armada/porting.rst b/docs/plat/marvell/armada/porting.rst index e3fc9ba73..ba8736dc6 100644 --- a/docs/plat/marvell/armada/porting.rst +++ b/docs/plat/marvell/armada/porting.rst @@ -110,11 +110,6 @@ Comphy Porting (phy-porting-layer.h or phy-default-porting-layer.h) parameters need to be suited and the board designer should provide relevant values. - .. seealso:: - For XFI/SFI comphy type there is procedure "rx_training" which eases - process of suiting some of the parameters. Please see *uboot_cmd* - section: rx_training. - The PHY porting layer simplifies updating static values per board type, which are now grouped in one place. -- cgit v1.2.3 From 582e4e7b2852ae31f1a7f55bd45c412508b952a6 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Wed, 29 Jul 2020 10:58:44 +0100 Subject: Makefile, doc: Make OPENSSL_DIR variable as build option for tools Openssl directory path is hardcoded to '/usr' in the makefile of certificate generation and firmware encryption tool using 'OPENSSL_DIR' variable. Hence changes are done to make 'OPENSSL_DIR' variable as a build option so that user can provide openssl directory path while building the certificate generation and firmware encryption tool. Also, updated the document for this newly created build option Change-Id: Ib1538370d2c59263417f5db3746d1087ee1c1339 Signed-off-by: Manish V Badarkhe --- Makefile | 4 ++-- docs/getting_started/build-options.rst | 4 ++++ make_helpers/defaults.mk | 3 +++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 65ebb9372..fa711e26a 100644 --- a/Makefile +++ b/Makefile @@ -1201,7 +1201,7 @@ certtool: ${CRTTOOL} .PHONY: ${CRTTOOL} ${CRTTOOL}: - ${Q}${MAKE} PLAT=${PLAT} USE_TBBR_DEFS=${USE_TBBR_DEFS} COT=${COT} --no-print-directory -C ${CRTTOOLPATH} + ${Q}${MAKE} PLAT=${PLAT} USE_TBBR_DEFS=${USE_TBBR_DEFS} COT=${COT} OPENSSL_DIR=${OPENSSL_DIR} --no-print-directory -C ${CRTTOOLPATH} @${ECHO_BLANK_LINE} @echo "Built $@ successfully" @${ECHO_BLANK_LINE} @@ -1267,7 +1267,7 @@ enctool: ${ENCTOOL} .PHONY: ${ENCTOOL} ${ENCTOOL}: - ${Q}${MAKE} PLAT=${PLAT} BUILD_INFO=0 --no-print-directory -C ${ENCTOOLPATH} + ${Q}${MAKE} PLAT=${PLAT} BUILD_INFO=0 OPENSSL_DIR=${OPENSSL_DIR} --no-print-directory -C ${ENCTOOLPATH} @${ECHO_BLANK_LINE} @echo "Built $@ successfully" @${ECHO_BLANK_LINE} diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index bfc50dfe7..630d86119 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -721,6 +721,10 @@ Common build options bit, to trap access to the RAS ERR and RAS ERX registers from lower ELs. This flag is disabled by default. +- ``OPENSSL_DIR``: This flag is used to provide the installed openssl directory + path on the host machine which is used to build certificate generation and + firmware encryption tool. + GICv3 driver options -------------------- diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index 9a6fd58fb..caf5990f2 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -308,3 +308,6 @@ RAS_TRAP_LOWER_EL_ERR_ACCESS := 0 # Build option to create cot descriptors using fconf COT_DESC_IN_DTB := 0 + +# Build option to provide openssl directory path +OPENSSL_DIR := /usr -- cgit v1.2.3 From db1ef41a78235fe228bbe28fb298ad4e3f9d644d Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Wed, 1 Apr 2020 21:28:26 +0200 Subject: SPM: build OP-TEE as an S-EL1 Secure Partition Provide manifest and build options to boot OP-TEE as a guest S-EL1 Secure Partition on top of Hafnium in S-EL2. Increase ARM_SP_MAX_SIZE to cope with OP-TEE debug build image. Signed-off-by: Olivier Deprez Change-Id: Idd2686fa689a78fe2d05ed92b1d23c65e2edd4cb --- Makefile | 4 ++ docs/plat/arm/arm-build-options.rst | 3 + fdts/optee_sp_manifest.dts | 33 +++++++++++ include/plat/arm/common/fconf_arm_sp_getter.h | 2 +- .../board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts | 68 ++++++++++++++++++++++ plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts | 7 +++ plat/arm/board/fvp/platform.mk | 9 ++- 7 files changed, 123 insertions(+), 3 deletions(-) create mode 100644 fdts/optee_sp_manifest.dts create mode 100644 plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts diff --git a/Makefile b/Makefile index 65ebb9372..14fc85ae4 100644 --- a/Makefile +++ b/Makefile @@ -484,6 +484,10 @@ ifneq (${SPD},none) $(error SPMD with SPM at S-EL2 requires CTX_INCLUDE_EL2_REGS option) endif endif + + ifeq ($(findstring optee_sp,$(ARM_SPMC_MANIFEST_DTS)),optee_sp) + DTC_CPPFLAGS += -DOPTEE_SP_FW_CONFIG + 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 9622de65d..2e50068f6 100644 --- a/docs/plat/arm/arm-build-options.rst +++ b/docs/plat/arm/arm-build-options.rst @@ -91,6 +91,9 @@ Arm Platform Build Options platforms. If this option is specified, then the path to the CryptoCell SBROM library must be specified via ``CCSBROM_LIB_PATH`` flag. +- ``ARM_SPMC_MANIFEST_DTS`` : path to an alternate manifest file used as the + SPMC Core manifest. Valid when ``SPD=spmd`` is selected. + For a better understanding of these options, the Arm development platform memory map is explained in the :ref:`Firmware Design`. diff --git a/fdts/optee_sp_manifest.dts b/fdts/optee_sp_manifest.dts new file mode 100644 index 000000000..02a5ef340 --- /dev/null +++ b/fdts/optee_sp_manifest.dts @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * This file is a Partition Manifest (PM) for a minimal Secure Partition (SP) + * that has additional optional properties defined. + * + */ + +/dts-v1/; + +/ { + compatible = "arm,ffa-manifest-1.0"; + + /* Properties */ + description = "op-tee"; + ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */ + uuid = <0x486178e0 0xe7f811e3 0xbc5e0002 0xa5d5c51b>; + id = <1>; + execution-ctx-count = <8>; + exception-level = <2>; /* S-EL1 */ + execution-state = <0>; /* AARCH64 */ + load-address = <0x6280000>; + entrypoint-offset = <0x1000>; + xlat-granule = <0>; /* 4KiB */ + boot-order = <0>; + messaging-method = <0>; /* Direct messaging only */ + run-time-model = <1>; /* Run to completion */ + + /* Boot protocol */ + gp-register-num = <0x0>; +}; diff --git a/include/plat/arm/common/fconf_arm_sp_getter.h b/include/plat/arm/common/fconf_arm_sp_getter.h index 38c30fbf9..236254bd2 100644 --- a/include/plat/arm/common/fconf_arm_sp_getter.h +++ b/include/plat/arm/common/fconf_arm_sp_getter.h @@ -13,7 +13,7 @@ /* arm_sp getter */ #define arm__sp_getter(prop) arm_sp.prop -#define ARM_SP_MAX_SIZE U(0x10000) +#define ARM_SP_MAX_SIZE U(0x80000) struct arm_sp_t { unsigned int number_of_sp; diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts new file mode 100644 index 000000000..f5b31b43c --- /dev/null +++ b/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +/dts-v1/; + +#define AFF 00 + +#include "fvp-defs.dtsi" +#undef POST +#define POST \ + }; + +/ { + compatible = "arm,ffa-core-manifest-1.0"; + #address-cells = <2>; + #size-cells = <1>; + + attribute { + spmc_id = <0x8000>; + maj_ver = <0x1>; + min_ver = <0x0>; + exec_state = <0x0>; + load_address = <0x0 0x6000000>; + entrypoint = <0x0 0x6000000>; + binary_size = <0x80000>; + }; + + chosen { + linux,initrd-start = <0>; + linux,initrd-end = <0>; + }; + + hypervisor { + compatible = "hafnium,hafnium"; + vm1 { + is_ffa_partition; + debug_name = "op-tee"; + load_address = <0x6280000>; + smc_whitelist = <0xbe000000>; + }; + }; + + cpus { + #address-cells = <0x2>; + #size-cells = <0x0>; + + CPU_0 + + /* + * SPMC(Hafnium) requires secondary core nodes are declared + * in descending order. + */ + CPU_7 + CPU_6 + CPU_5 + CPU_4 + CPU_3 + CPU_2 + CPU_1 + }; + + memory@60000000 { + device_type = "memory"; + reg = <0x0 0x6000000 0x2000000>; /* Trusted DRAM */ + }; +}; 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 8b9e41ce3..280a64aad 100644 --- a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts +++ b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts @@ -75,6 +75,12 @@ secure-partitions { compatible = "arm,sp"; +#ifdef OPTEE_SP_FW_CONFIG + op-tee { + uuid = <0xe0786148 0xe311f8e7 0x02005ebc 0x1bc5d5a5>; + load-address = <0x6280000>; + }; +#else cactus-primary { uuid = <0x1e67b5b4 0xe14f904a 0x13fb1fb8 0xcbdae1da>; load-address = <0x7000000>; @@ -84,6 +90,7 @@ uuid = <0x092358d1 0xb94723f0 0x64447c82 0xc88f57f5>; load-address = <0x7100000>; }; +#endif }; #if COT_DESC_IN_DTB diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 98c70c956..f75f556a8 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -253,8 +253,13 @@ $(eval $(call TOOL_ADD_PAYLOAD,${FVP_TOS_FW_CONFIG},--tos-fw-config)) endif ifeq (${SPD},spmd) -FDT_SOURCES += plat/arm/board/fvp/fdts/${PLAT}_spmc_manifest.dts -FVP_TOS_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_spmc_manifest.dtb + +ifeq ($(ARM_SPMC_MANIFEST_DTS),) +ARM_SPMC_MANIFEST_DTS := plat/arm/board/fvp/fdts/${PLAT}_spmc_manifest.dts +endif + +FDT_SOURCES += ${ARM_SPMC_MANIFEST_DTS} +FVP_TOS_FW_CONFIG := ${BUILD_PLAT}/fdts/$(notdir $(basename ${ARM_SPMC_MANIFEST_DTS})).dtb # Add the TOS_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${FVP_TOS_FW_CONFIG},--tos-fw-config)) -- cgit v1.2.3 From fa30f73b37b498273ec0b315048c06315c7c25e3 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Tue, 7 Jul 2020 10:40:46 +0100 Subject: arm_fpga: Support uploading a custom command line The command line for BL33 payloads is typically taken from the DTB. On "normal" systems the bootloader will put the right version in there, but we typically don't use one on the FPGAs. To avoid editing (and possibly re-packaging) the DTB for every change in the command line, try to read it from some "magic" memory location instead. It can be easily placed there by the tool that uploads the other payloads to the FPGA's memory. BL31 will then replace the existing command line in the DTB with that new string. To avoid reading garbage, check the memory location for containing a magic value. This is conveniently chosen to be a simple ASCII string, so it can just preceed the actual command line in a text file: -------------------------------- CMD:console=ttyAMA0,38400n8 debug loglevel=8 -------------------------------- Change-Id: I5923a80332c9fac3b4afd1a6aaa321233d0f60da Signed-off-by: Andre Przywara --- plat/arm/board/arm_fpga/fpga_bl31_setup.c | 78 +++++++++++++++++++++++++++++++ plat/arm/board/arm_fpga/fpga_private.h | 1 + plat/arm/board/arm_fpga/platform.mk | 3 ++ 3 files changed, 82 insertions(+) diff --git a/plat/arm/board/arm_fpga/fpga_bl31_setup.c b/plat/arm/board/arm_fpga/fpga_bl31_setup.c index 6eeff451c..9db107cc8 100644 --- a/plat/arm/board/arm_fpga/fpga_bl31_setup.c +++ b/plat/arm/board/arm_fpga/fpga_bl31_setup.c @@ -128,6 +128,84 @@ unsigned int plat_get_syscnt_freq2(void) FPGA_DEFAULT_TIMER_FREQUENCY); } +static void fpga_prepare_dtb(void) +{ + void *fdt = (void *)(uintptr_t)FPGA_PRELOADED_DTB_BASE; + const char *cmdline = (void *)(uintptr_t)FPGA_PRELOADED_CMD_LINE; + int err; + + err = fdt_open_into(fdt, fdt, FPGA_MAX_DTB_SIZE); + if (err < 0) { + ERROR("cannot open devicetree at %p: %d\n", fdt, err); + panic(); + } + + /* 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); + } 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); + } + } + } + + err = fdt_pack(fdt); + if (err < 0) { + ERROR("Failed to pack Device Tree at %p: error %d\n", fdt, err); + } + + clean_dcache_range((uintptr_t)fdt, fdt_blob_size(fdt)); +} + +void bl31_plat_runtime_setup(void) +{ + fpga_prepare_dtb(); +} + void bl31_plat_enable_mmu(uint32_t flags) { /* TODO: determine if MMU needs to be enabled */ diff --git a/plat/arm/board/arm_fpga/fpga_private.h b/plat/arm/board/arm_fpga/fpga_private.h index 46287adea..47059d64a 100644 --- a/plat/arm/board/arm_fpga/fpga_private.h +++ b/plat/arm/board/arm_fpga/fpga_private.h @@ -12,6 +12,7 @@ #define C_RUNTIME_READY_KEY (0xaa55aa55) #define VALID_MPID (1U) +#define FPGA_MAX_DTB_SIZE 0x10000 #ifndef __ASSEMBLER__ diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk index e57912cfe..1e7badf50 100644 --- a/plat/arm/board/arm_fpga/platform.mk +++ b/plat/arm/board/arm_fpga/platform.mk @@ -29,6 +29,9 @@ PRELOADED_BL33_BASE := 0x80080000 FPGA_PRELOADED_DTB_BASE := 0x80070000 $(eval $(call add_define,FPGA_PRELOADED_DTB_BASE)) +FPGA_PRELOADED_CMD_LINE := 0x1000 +$(eval $(call add_define,FPGA_PRELOADED_CMD_LINE)) + # Treating this as a memory-constrained port for now USE_COHERENT_MEM := 0 -- cgit v1.2.3 From f85f37d4f78c8c81fb0d6402b5f98b2428a9ab54 Mon Sep 17 00:00:00 2001 From: Nina Wu Date: Fri, 17 Apr 2020 17:14:23 +0800 Subject: Initialize platform for MediaTek mt8192 - Add basic platform setup - Add mt8192 documentation at docs/plat/ - Add generic CPU helper functions - Add basic register address Change-Id: Ife34622105404a8227441aab939e3c55c96374e9 Signed-off-by: Nina Wu --- docs/plat/index.rst | 1 + docs/plat/mt8192.rst | 21 ++++++ plat/mediatek/mt8192/aarch64/plat_helpers.S | 49 +++++++++++++ plat/mediatek/mt8192/aarch64/platform_common.c | 46 ++++++++++++ plat/mediatek/mt8192/bl31_plat_setup.c | 94 ++++++++++++++++++++++++ plat/mediatek/mt8192/include/plat_helpers.h | 12 ++++ plat/mediatek/mt8192/include/plat_macros.S | 38 ++++++++++ plat/mediatek/mt8192/include/plat_private.h | 18 +++++ plat/mediatek/mt8192/include/platform_def.h | 98 ++++++++++++++++++++++++++ plat/mediatek/mt8192/plat_pm.c | 26 +++++++ plat/mediatek/mt8192/plat_topology.c | 73 +++++++++++++++++++ plat/mediatek/mt8192/platform.mk | 50 +++++++++++++ 12 files changed, 526 insertions(+) create mode 100644 docs/plat/mt8192.rst create mode 100644 plat/mediatek/mt8192/aarch64/plat_helpers.S create mode 100644 plat/mediatek/mt8192/aarch64/platform_common.c create mode 100644 plat/mediatek/mt8192/bl31_plat_setup.c create mode 100644 plat/mediatek/mt8192/include/plat_helpers.h create mode 100644 plat/mediatek/mt8192/include/plat_macros.S create mode 100644 plat/mediatek/mt8192/include/plat_private.h create mode 100644 plat/mediatek/mt8192/include/platform_def.h create mode 100644 plat/mediatek/mt8192/plat_pm.c create mode 100644 plat/mediatek/mt8192/plat_topology.c create mode 100644 plat/mediatek/mt8192/platform.mk diff --git a/docs/plat/index.rst b/docs/plat/index.rst index 7969003c9..6a38113fc 100644 --- a/docs/plat/index.rst +++ b/docs/plat/index.rst @@ -19,6 +19,7 @@ Platform Ports intel-stratix10 marvell/index mt8183 + mt8192 nvidia-tegra warp7 imx8 diff --git a/docs/plat/mt8192.rst b/docs/plat/mt8192.rst new file mode 100644 index 000000000..369afcfb7 --- /dev/null +++ b/docs/plat/mt8192.rst @@ -0,0 +1,21 @@ +MediaTek 8192 +============= + +MediaTek 8192 (MT8192) is a 64-bit ARM SoC introduced by MediaTek in 2020. +The chip incorporates eight cores - four Cortex-A55 little cores and Cortex-A76. +Cortex-A76 can operate at up to 2.2 GHz. +Cortex-A55 can operate at up to 2 GHz. + +Boot Sequence +------------- + +:: + + Boot Rom --> Coreboot --> TF-A BL31 --> Depthcharge --> Linux Kernel + +How to Build +------------ + +.. code:: shell + + make CROSS_COMPILE=aarch64-linux-gnu- PLAT=mt8192 DEBUG=1 COREBOOT=1 diff --git a/plat/mediatek/mt8192/aarch64/plat_helpers.S b/plat/mediatek/mt8192/aarch64/plat_helpers.S new file mode 100644 index 000000000..99274dec4 --- /dev/null +++ b/plat/mediatek/mt8192/aarch64/plat_helpers.S @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + + .globl plat_is_my_cpu_primary + .globl plat_my_core_pos + .globl plat_mediatek_calc_core_pos + +func plat_is_my_cpu_primary + mrs x0, mpidr_el1 + and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK) + cmp x0, #PLAT_PRIMARY_CPU + cset x0, eq + ret +endfunc plat_is_my_cpu_primary + + /* ----------------------------------------------------- + * unsigned int plat_my_core_pos(void) + * This function uses the plat_mediatek_calc_core_pos() + * definition to get the index of the calling CPU. + * ----------------------------------------------------- + */ +func plat_my_core_pos + mrs x0, mpidr_el1 + b plat_mediatek_calc_core_pos +endfunc plat_my_core_pos + + /* ----------------------------------------------------- + * unsigned int plat_mediatek_calc_core_pos(u_register_t mpidr); + * + * In ARMv8.2, AFF2 is cluster id, AFF1 is core id and + * AFF0 is thread id. There is only one cluster in ARMv8.2 + * and one thread in current implementation. + * + * With this function: CorePos = CoreID (AFF1) + * we do it with x0 = (x0 >> 8) & 0xff + * ----------------------------------------------------- + */ +func plat_mediatek_calc_core_pos + mov x1, #MPIDR_AFFLVL_MASK + and x0, x1, x0, lsr #MPIDR_AFF1_SHIFT + ret +endfunc plat_mediatek_calc_core_pos diff --git a/plat/mediatek/mt8192/aarch64/platform_common.c b/plat/mediatek/mt8192/aarch64/platform_common.c new file mode 100644 index 000000000..eb1bb4486 --- /dev/null +++ b/plat/mediatek/mt8192/aarch64/platform_common.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* Project Includes */ +#include + +/* Platform Includes */ +#include + +/* Table of regions to map using the MMU. */ +const mmap_region_t plat_mmap[] = { + /* for TF text, RO, RW */ + MAP_REGION_FLAT(MTK_DEV_RNG0_BASE, MTK_DEV_RNG0_SIZE, + MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(MTK_DEV_RNG1_BASE, MTK_DEV_RNG1_SIZE, + MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(MTK_DEV_RNG2_BASE, MTK_DEV_RNG2_SIZE, + MT_DEVICE | MT_RW | MT_SECURE), + { 0 } +}; + +/******************************************************************************* + * Macro generating the code for the function setting up the pagetables as per + * the platform memory map & initialize the mmu, for the given exception level + ******************************************************************************/ +void plat_configure_mmu_el3(uintptr_t total_base, + uintptr_t total_size, + uintptr_t ro_start, + uintptr_t ro_limit) +{ + mmap_add_region(total_base, total_base, total_size, + MT_RW_DATA | MT_SECURE); + mmap_add_region(ro_start, ro_start, ro_limit - ro_start, + MT_CODE | MT_SECURE); + mmap_add(plat_mmap); + init_xlat_tables(); + enable_mmu_el3(0); +} + +unsigned int plat_get_syscnt_freq2(void) +{ + return SYS_COUNTER_FREQ_IN_TICKS; +} diff --git a/plat/mediatek/mt8192/bl31_plat_setup.c b/plat/mediatek/mt8192/bl31_plat_setup.c new file mode 100644 index 000000000..4378c5a12 --- /dev/null +++ b/plat/mediatek/mt8192/bl31_plat_setup.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* System Includes */ +#include + +/* Project Includes */ +#include +#include +#include +#include +#include + +/* Platform Includes */ +#include +#include + +static entry_point_info_t bl32_ep_info; +static entry_point_info_t bl33_ep_info; + +/******************************************************************************* + * Return a pointer to the 'entry_point_info' structure of the next image for + * the security state specified. BL33 corresponds to the non-secure image type + * while BL32 corresponds to the secure image type. A NULL pointer is returned + * if the image does not exist. + ******************************************************************************/ +entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) +{ + entry_point_info_t *next_image_info; + + next_image_info = (type == NON_SECURE) ? &bl33_ep_info : &bl32_ep_info; + assert(next_image_info->h.type == PARAM_EP); + + /* None of the images on this platform can have 0x0 as the entrypoint */ + if (next_image_info->pc) { + return next_image_info; + } else { + return NULL; + } +} + +/******************************************************************************* + * Perform any BL31 early platform setup. Here is an opportunity to copy + * parameters passed by the calling EL (S-EL1 in BL2 & S-EL3 in BL1) before they + * are lost (potentially). This needs to be done before the MMU is initialized + * so that the memory layout can be used while creating page tables. + * BL2 has flushed this information to memory, so we are guaranteed to pick up + * good data. + ******************************************************************************/ +void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, + u_register_t arg2, u_register_t arg3) +{ + static console_t console; + + params_early_setup(arg1); + +#if COREBOOT + if (coreboot_serial.type) { + console_16550_register(coreboot_serial.baseaddr, + coreboot_serial.input_hertz, + coreboot_serial.baud, + &console); + } +#else + console_16550_register(UART0_BASE, UART_CLOCK, UART_BAUDRATE, &console); +#endif + + NOTICE("MT8192 bl31_setup\n"); + + bl31_params_parse_helper(arg0, &bl32_ep_info, &bl33_ep_info); +} + + +/******************************************************************************* + * Perform any BL31 platform setup code + ******************************************************************************/ +void bl31_platform_setup(void) +{ +} + +/******************************************************************************* + * Perform the very early platform specific architectural setup here. At the + * moment this is only intializes the mmu in a quick and dirty way. + ******************************************************************************/ +void bl31_plat_arch_setup(void) +{ + plat_configure_mmu_el3(BL31_START, + BL31_END - BL31_START, + BL_CODE_BASE, + BL_CODE_END); +} diff --git a/plat/mediatek/mt8192/include/plat_helpers.h b/plat/mediatek/mt8192/include/plat_helpers.h new file mode 100644 index 000000000..9b550ee25 --- /dev/null +++ b/plat/mediatek/mt8192/include/plat_helpers.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __PLAT_HELPERS_H__ +#define __PLAT_HELPERS_H__ + +unsigned int plat_mediatek_calc_core_pos(u_register_t mpidr); + +#endif /* __PLAT_HELPERS_H__ */ diff --git a/plat/mediatek/mt8192/include/plat_macros.S b/plat/mediatek/mt8192/include/plat_macros.S new file mode 100644 index 000000000..92cda0775 --- /dev/null +++ b/plat/mediatek/mt8192/include/plat_macros.S @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef PLAT_MACROS_S +#define PLAT_MACROS_S + +#include + +.section .rodata.gic_reg_name, "aS" +gicc_regs: + .asciz "gicc_hppir", "gicc_ahppir", "gicc_ctlr", "" +gicd_pend_reg: + .asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n" \ + " Offset:\t\t\tvalue\n" +newline: + .asciz "\n" +spacer: + .asciz ":\t\t0x" + +.section .rodata.cci_reg_name, "aS" +cci_iface_regs: + .asciz "cci_snoop_ctrl_cluster0", "cci_snoop_ctrl_cluster1" , "" + + /* --------------------------------------------- + * The below macro prints out relevant GIC and + * CCI registers whenever an unhandled exception + * is taken in BL31. + * Clobbers: x0 - x10, x26, x27, sp + * --------------------------------------------- + */ + .macro plat_crash_print_regs + /* To-do: GIC owner */ + /* To-do: CCI owner */ + .endm + +#endif /* PLAT_MACROS_S */ diff --git a/plat/mediatek/mt8192/include/plat_private.h b/plat/mediatek/mt8192/include/plat_private.h new file mode 100644 index 000000000..42ca415f9 --- /dev/null +++ b/plat/mediatek/mt8192/include/plat_private.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLAT_PRIVATE_H +#define PLAT_PRIVATE_H + +/******************************************************************************* + * Function and variable prototypes + ******************************************************************************/ +void plat_configure_mmu_el3(uintptr_t total_base, + uintptr_t total_size, + uintptr_t ro_start, + uintptr_t ro_limit); + +#endif /* PLAT_PRIVATE_H */ diff --git a/plat/mediatek/mt8192/include/platform_def.h b/plat/mediatek/mt8192/include/platform_def.h new file mode 100644 index 000000000..e1f0faf60 --- /dev/null +++ b/plat/mediatek/mt8192/include/platform_def.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + + +#define PLAT_PRIMARY_CPU 0x0 + +#define MT_GIC_BASE 0x0c000000 +#define PLAT_MT_CCI_BASE 0x0c500000 +#define MCUCFG_BASE 0x0c530000 + +#define IO_PHYS 0x10000000 + +/* Aggregate of all devices for MMU mapping */ +#define MTK_DEV_RNG0_BASE IO_PHYS +#define MTK_DEV_RNG0_SIZE 0x10000000 +#define MTK_DEV_RNG1_BASE (IO_PHYS + 0x10000000) +#define MTK_DEV_RNG1_SIZE 0x10000000 +#define MTK_DEV_RNG2_BASE 0x0c000000 +#define MTK_DEV_RNG2_SIZE 0x600000 + +/******************************************************************************* + * UART related constants + ******************************************************************************/ +#define UART0_BASE (IO_PHYS + 0x01002000) +#define UART1_BASE (IO_PHYS + 0x01003000) + +#define UART_BAUDRATE 115200 + +/******************************************************************************* + * System counter frequency related constants + ******************************************************************************/ +#define SYS_COUNTER_FREQ_IN_TICKS 13000000 +#define SYS_COUNTER_FREQ_IN_MHZ 13 + +/******************************************************************************* + * Platform binary types for linking + ******************************************************************************/ +#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64" +#define PLATFORM_LINKER_ARCH aarch64 + +/******************************************************************************* + * Generic platform constants + ******************************************************************************/ +#define PLATFORM_STACK_SIZE 0x800 + +#define PLAT_MAX_PWR_LVL U(2) +#define PLAT_MAX_RET_STATE U(1) +#define PLAT_MAX_OFF_STATE U(2) + +#define PLATFORM_SYSTEM_COUNT U(1) +#define PLATFORM_CLUSTER_COUNT U(1) +#define PLATFORM_CLUSTER0_CORE_COUNT U(8) +#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER0_CORE_COUNT) +#define PLATFORM_MAX_CPUS_PER_CLUSTER U(8) + +/******************************************************************************* + * Platform memory map related constants + ******************************************************************************/ +#define TZRAM_BASE 0x54600000 +#define TZRAM_SIZE 0x00030000 + +/******************************************************************************* + * BL31 specific defines. + ******************************************************************************/ +/* + * Put BL31 at the top of the Trusted SRAM (just below the shared memory, if + * present). BL31_BASE is calculated using the current BL31 debug size plus a + * little space for growth. + */ +#define BL31_BASE (TZRAM_BASE + 0x1000) +#define BL31_LIMIT (TZRAM_BASE + TZRAM_SIZE) + +/******************************************************************************* + * Platform specific page table and MMU setup constants + ******************************************************************************/ +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) +#define MAX_XLAT_TABLES 16 +#define MAX_MMAP_REGIONS 16 + +/******************************************************************************* + * Declarations and constants to access the mailboxes safely. Each mailbox is + * 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. Such alignment ensures that two maiboxes do not sit on the same cache + * line at any cache level. They could belong to different cpus/clusters & + * get written while being protected by different locks causing corruption of + * a valid mailbox address. + ******************************************************************************/ +#define CACHE_WRITEBACK_SHIFT 6 +#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT) +#endif /* PLATFORM_DEF_H */ diff --git a/plat/mediatek/mt8192/plat_pm.c b/plat/mediatek/mt8192/plat_pm.c new file mode 100644 index 000000000..81a170dd7 --- /dev/null +++ b/plat/mediatek/mt8192/plat_pm.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* common headers */ +#include + +/* mediatek platform specific headers */ + + +/******************************************************************************* + * MTK_platform handler called when an affinity instance is about to be turned + * on. The level and mpidr determine the affinity instance. + ******************************************************************************/ +static const plat_psci_ops_t plat_plat_pm_ops = { +}; + +int plat_setup_psci_ops(uintptr_t sec_entrypoint, + const plat_psci_ops_t **psci_ops) +{ + *psci_ops = &plat_plat_pm_ops; + + return 0; +} diff --git a/plat/mediatek/mt8192/plat_topology.c b/plat/mediatek/mt8192/plat_topology.c new file mode 100644 index 000000000..aa4975e80 --- /dev/null +++ b/plat/mediatek/mt8192/plat_topology.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* Project Includes */ +#include +#include +#include + +/* Platform Includes */ +#include +#include + +const unsigned char mtk_power_domain_tree_desc[] = { + /* Number of root nodes */ + PLATFORM_SYSTEM_COUNT, + /* Number of children for the root node */ + PLATFORM_CLUSTER_COUNT, + /* Number of children for the first cluster node */ + PLATFORM_CLUSTER0_CORE_COUNT, +}; + +/******************************************************************************* + * This function returns the MT8192 default topology tree information. + ******************************************************************************/ +const unsigned char *plat_get_power_domain_tree_desc(void) +{ + return mtk_power_domain_tree_desc; +} + +/******************************************************************************* + * This function implements a part of the critical interface between the psci + * generic layer and the platform that allows the former to query the platform + * to convert an MPIDR to a unique linear index. An error code (-1) is returned + * in case the MPIDR is invalid. + ******************************************************************************/ +int plat_core_pos_by_mpidr(u_register_t mpidr) +{ + unsigned int cluster_id, cpu_id; + + if (read_mpidr() & MPIDR_MT_MASK) { + /* ARMv8.2 arch */ + if (mpidr & (MPIDR_AFFLVL_MASK << MPIDR_AFF0_SHIFT)) { + return -1; + } + return plat_mediatek_calc_core_pos(mpidr); + } + + mpidr &= MPIDR_AFFINITY_MASK; + + if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) { + return -1; + } + + cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK; + cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK; + + if (cluster_id >= PLATFORM_CLUSTER_COUNT) { + return -1; + } + + /* + * Validate cpu_id by checking whether it represents a CPU in + * one of the two clusters present on the platform. + */ + if (cpu_id >= PLATFORM_MAX_CPUS_PER_CLUSTER) { + return -1; + } + + return (cpu_id + (cluster_id * 8)); +} diff --git a/plat/mediatek/mt8192/platform.mk b/plat/mediatek/mt8192/platform.mk new file mode 100644 index 000000000..f4ee7e7f4 --- /dev/null +++ b/plat/mediatek/mt8192/platform.mk @@ -0,0 +1,50 @@ +# +# Copyright (c) 2020, MediaTek Inc. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +MTK_PLAT := plat/mediatek +MTK_PLAT_SOC := ${MTK_PLAT}/${PLAT} + +PLAT_INCLUDES := -I${MTK_PLAT}/common/ \ + -I${MTK_PLAT_SOC}/include/ + +include drivers/arm/gic/v3/gicv3.mk +include lib/xlat_tables_v2/xlat_tables.mk + +PLAT_BL_COMMON_SOURCES := ${GICV3_SOURCES} \ + ${XLAT_TABLES_LIB_SRCS} \ + plat/common/aarch64/crash_console_helpers.S \ + plat/common/plat_psci_common.c + +BL31_SOURCES += common/desc_image_load.c \ + drivers/ti/uart/aarch64/16550_console.S \ + lib/bl_aux_params/bl_aux_params.c \ + lib/cpus/aarch64/cortex_a55.S \ + lib/cpus/aarch64/cortex_a76.S \ + plat/common/plat_gicv3.c \ + ${MTK_PLAT}/common/mtk_plat_common.c \ + ${MTK_PLAT}/common/params_setup.c \ + ${MTK_PLAT_SOC}/aarch64/platform_common.c \ + ${MTK_PLAT_SOC}/aarch64/plat_helpers.S \ + ${MTK_PLAT_SOC}/bl31_plat_setup.c \ + ${MTK_PLAT_SOC}/plat_pm.c \ + ${MTK_PLAT_SOC}/plat_topology.c + + +# Configs for A76 and A55 +HW_ASSISTED_COHERENCY := 1 +USE_COHERENT_MEM := 0 +CTX_INCLUDE_AARCH32_REGS := 0 + +# indicate the reset vector address can be programmed +PROGRAMMABLE_RESET_ADDRESS := 1 + +COLD_BOOT_SINGLE_CPU := 1 + +MACH_MT8192 := 1 +$(eval $(call add_define,MACH_MT8192)) + +include lib/coreboot/coreboot.mk + -- cgit v1.2.3 From 9d9ae9766ef305ac1acefd2b7999676245caa335 Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Thu, 30 Jul 2020 17:18:33 +0200 Subject: spm-mm: fix MISRA C-2012 Rule 2.3 spm_mm_boot_info_t defined but never used. Following merge of patchset [1] the spm_mm_boot_info_t structure is included in few platform files unconditionally even when SPM_MM option is disabled. [1] https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/2647 Signed-off-by: Olivier Deprez Change-Id: I68bc034c9348b5d9bcfd2e5217b781df5ad1b369 --- plat/arm/board/fvp/fvp_common.c | 3 +++ plat/arm/board/tc0/tc0_plat.c | 3 +++ plat/arm/css/sgi/sgi_plat.c | 5 ++++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c index c5fae56d7..cb717e053 100644 --- a/plat/arm/board/fvp/fvp_common.c +++ b/plat/arm/board/fvp/fvp_common.c @@ -18,7 +18,10 @@ #include #include #include + +#if SPM_MM #include +#endif #include "fvp_private.h" diff --git a/plat/arm/board/tc0/tc0_plat.c b/plat/arm/board/tc0/tc0_plat.c index b1ec39b58..05461928d 100644 --- a/plat/arm/board/tc0/tc0_plat.c +++ b/plat/arm/board/tc0/tc0_plat.c @@ -15,7 +15,10 @@ #include #include #include + +#if SPM_MM #include +#endif /* * Table of regions for different BL stages to map using the MMU. diff --git a/plat/arm/css/sgi/sgi_plat.c b/plat/arm/css/sgi/sgi_plat.c index b611eaff5..a2117f6c1 100644 --- a/plat/arm/css/sgi/sgi_plat.c +++ b/plat/arm/css/sgi/sgi_plat.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -15,7 +15,10 @@ #include #include #include + +#if SPM_MM #include +#endif #define SGI_MAP_FLASH0_RO MAP_REGION_FLAT(V2M_FLASH0_BASE,\ V2M_FLASH0_SIZE, \ -- cgit v1.2.3 From 03a5225c6a9371d57c14b2909c48762d07842ef6 Mon Sep 17 00:00:00 2001 From: Manish Pandey Date: Thu, 23 Jul 2020 16:54:30 +0100 Subject: tbbr/dualroot: rename SP package certificate file Currently only single signing domain is supported for SP packages but there is plan to support dual signing domains if CoT is dualroot. SP_CONTENT_CERT_ID is the certificate file which is currently generated and signed with trusted world key which in-turn is derived from Silicon provider RoT key. To allow dual signing domain for SP packages, other certificate file will be derived from Platform owned RoT key. This patch renames "SP_CONTENT_CERT_ID" to "SIP_SP_CONTENT_CERT_ID" and does other related changes. Signed-off-by: Manish Pandey Change-Id: I0bc445a3ab257e2dac03faa64f46e36a9fed5e93 --- drivers/auth/dualroot/cot.c | 38 ++++++++++++++++++------------------ drivers/auth/tbbr/tbbr_cot_bl2.c | 38 ++++++++++++++++++------------------ fdts/cot_descriptors.dtsi | 36 +++++++++++++++++----------------- include/common/tbbr/tbbr_img_def.h | 2 +- include/drivers/auth/auth_mod.h | 6 +++--- plat/arm/common/fconf/arm_fconf_io.c | 8 ++++---- plat/arm/common/fconf/arm_fconf_sp.c | 2 +- 7 files changed, 65 insertions(+), 65 deletions(-) diff --git a/drivers/auth/dualroot/cot.c b/drivers/auth/dualroot/cot.c index 31e5d65f4..68f3d467f 100644 --- a/drivers/auth/dualroot/cot.c +++ b/drivers/auth/dualroot/cot.c @@ -693,8 +693,8 @@ static const auth_img_desc_t nt_fw_config = { * Secure Partitions */ #if defined(SPD_spmd) -static const auth_img_desc_t sp_content_cert = { - .img_id = SP_CONTENT_CERT_ID, +static const auth_img_desc_t sip_sp_content_cert = { + .img_id = SIP_SP_CONTENT_CERT_ID, .img_type = IMG_CERT, .parent = &trusted_key_cert, .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { @@ -775,14 +775,14 @@ static const auth_img_desc_t sp_content_cert = { } }; -DEFINE_SP_PKG(1); -DEFINE_SP_PKG(2); -DEFINE_SP_PKG(3); -DEFINE_SP_PKG(4); -DEFINE_SP_PKG(5); -DEFINE_SP_PKG(6); -DEFINE_SP_PKG(7); -DEFINE_SP_PKG(8); +DEFINE_SIP_SP_PKG(1); +DEFINE_SIP_SP_PKG(2); +DEFINE_SIP_SP_PKG(3); +DEFINE_SIP_SP_PKG(4); +DEFINE_SIP_SP_PKG(5); +DEFINE_SIP_SP_PKG(6); +DEFINE_SIP_SP_PKG(7); +DEFINE_SIP_SP_PKG(8); #endif /* SPD_spmd */ #else /* IMAGE_BL2 */ @@ -914,15 +914,15 @@ static const auth_img_desc_t * const cot_desc[] = { [BL33_IMAGE_ID] = &bl33_image, [NT_FW_CONFIG_ID] = &nt_fw_config, #if defined(SPD_spmd) - [SP_CONTENT_CERT_ID] = &sp_content_cert, - [SP_CONTENT_CERT_ID + 1] = &sp_pkg1, - [SP_CONTENT_CERT_ID + 2] = &sp_pkg2, - [SP_CONTENT_CERT_ID + 3] = &sp_pkg3, - [SP_CONTENT_CERT_ID + 4] = &sp_pkg4, - [SP_CONTENT_CERT_ID + 5] = &sp_pkg5, - [SP_CONTENT_CERT_ID + 6] = &sp_pkg6, - [SP_CONTENT_CERT_ID + 7] = &sp_pkg7, - [SP_CONTENT_CERT_ID + 8] = &sp_pkg8, + [SIP_SP_CONTENT_CERT_ID] = &sip_sp_content_cert, + [SP_PKG1_ID] = &sp_pkg1, + [SP_PKG2_ID] = &sp_pkg2, + [SP_PKG3_ID] = &sp_pkg3, + [SP_PKG4_ID] = &sp_pkg4, + [SP_PKG5_ID] = &sp_pkg5, + [SP_PKG6_ID] = &sp_pkg6, + [SP_PKG7_ID] = &sp_pkg7, + [SP_PKG8_ID] = &sp_pkg8, #endif }; #endif diff --git a/drivers/auth/tbbr/tbbr_cot_bl2.c b/drivers/auth/tbbr/tbbr_cot_bl2.c index 63c18fae0..65a0478ab 100644 --- a/drivers/auth/tbbr/tbbr_cot_bl2.c +++ b/drivers/auth/tbbr/tbbr_cot_bl2.c @@ -558,8 +558,8 @@ static const auth_img_desc_t nt_fw_config = { }; /* Secure Partitions */ #if defined(SPD_spmd) -static const auth_img_desc_t sp_content_cert = { - .img_id = SP_CONTENT_CERT_ID, +static const auth_img_desc_t sip_sp_content_cert = { + .img_id = SIP_SP_CONTENT_CERT_ID, .img_type = IMG_CERT, .parent = &trusted_key_cert, .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { @@ -640,14 +640,14 @@ static const auth_img_desc_t sp_content_cert = { } }; -DEFINE_SP_PKG(1); -DEFINE_SP_PKG(2); -DEFINE_SP_PKG(3); -DEFINE_SP_PKG(4); -DEFINE_SP_PKG(5); -DEFINE_SP_PKG(6); -DEFINE_SP_PKG(7); -DEFINE_SP_PKG(8); +DEFINE_SIP_SP_PKG(1); +DEFINE_SIP_SP_PKG(2); +DEFINE_SIP_SP_PKG(3); +DEFINE_SIP_SP_PKG(4); +DEFINE_SIP_SP_PKG(5); +DEFINE_SIP_SP_PKG(6); +DEFINE_SIP_SP_PKG(7); +DEFINE_SIP_SP_PKG(8); #endif /* SPD_spmd */ static const auth_img_desc_t * const cot_desc[] = { @@ -672,15 +672,15 @@ static const auth_img_desc_t * const cot_desc[] = { [BL33_IMAGE_ID] = &bl33_image, [NT_FW_CONFIG_ID] = &nt_fw_config, #if defined(SPD_spmd) - [SP_CONTENT_CERT_ID] = &sp_content_cert, - [SP_CONTENT_CERT_ID + 1] = &sp_pkg1, - [SP_CONTENT_CERT_ID + 2] = &sp_pkg2, - [SP_CONTENT_CERT_ID + 3] = &sp_pkg3, - [SP_CONTENT_CERT_ID + 4] = &sp_pkg4, - [SP_CONTENT_CERT_ID + 5] = &sp_pkg5, - [SP_CONTENT_CERT_ID + 6] = &sp_pkg6, - [SP_CONTENT_CERT_ID + 7] = &sp_pkg7, - [SP_CONTENT_CERT_ID + 8] = &sp_pkg8, + [SIP_SP_CONTENT_CERT_ID] = &sip_sp_content_cert, + [SP_PKG1_ID] = &sp_pkg1, + [SP_PKG2_ID] = &sp_pkg2, + [SP_PKG3_ID] = &sp_pkg3, + [SP_PKG4_ID] = &sp_pkg4, + [SP_PKG5_ID] = &sp_pkg5, + [SP_PKG6_ID] = &sp_pkg6, + [SP_PKG7_ID] = &sp_pkg7, + [SP_PKG8_ID] = &sp_pkg8, #endif }; diff --git a/fdts/cot_descriptors.dtsi b/fdts/cot_descriptors.dtsi index 753d56ace..9308e1789 100644 --- a/fdts/cot_descriptors.dtsi +++ b/fdts/cot_descriptors.dtsi @@ -146,8 +146,8 @@ cot { }; #if defined(SPD_spmd) - sp_content_cert: sp_content_cert { - image-id = ; + sip_sp_content_cert: sip_sp_content_cert { + image-id = ; parent = <&trusted_key_cert>; signing-key = <&trusted_world_pk>; antirollback-counter = <&trusted_nv_counter>; @@ -251,50 +251,50 @@ cot { #if defined(SPD_spmd) sp_pkg1 { - image-id = ; - parent = <&sp_content_cert>; + image-id = ; + parent = <&sip_sp_content_cert>; hash = <&sp_pkg1_hash>; }; sp_pkg2 { - image-id = ; - parent = <&sp_content_cert>; + image-id = ; + parent = <&sip_sp_content_cert>; hash = <&sp_pkg2_hash>; }; sp_pkg3 { - image-id = ; - parent = <&sp_content_cert>; + image-id = ; + parent = <&sip_sp_content_cert>; hash = <&sp_pkg3_hash>; }; sp_pkg4 { - image-id = ; - parent = <&sp_content_cert>; + image-id = ; + parent = <&sip_sp_content_cert>; hash = <&sp_pkg4_hash>; }; sp_pkg5 { - image-id = ; - parent = <&sp_content_cert>; + image-id = ; + parent = <&sip_sp_content_cert>; hash = <&sp_pkg5_hash>; }; sp_pkg6 { - image-id = ; - parent = <&sp_content_cert>; + image-id = ; + parent = <&sip_sp_content_cert>; hash = <&sp_pkg6_hash>; }; sp_pkg7 { - image-id = ; - parent = <&sp_content_cert>; + image-id = ; + parent = <&sip_sp_content_cert>; hash = <&sp_pkg7_hash>; }; sp_pkg8 { - image-id = ; - parent = <&sp_content_cert>; + image-id = ; + parent = <&sip_sp_content_cert>; hash = <&sp_pkg8_hash>; }; #endif diff --git a/include/common/tbbr/tbbr_img_def.h b/include/common/tbbr/tbbr_img_def.h index e057891a2..b29b1354c 100644 --- a/include/common/tbbr/tbbr_img_def.h +++ b/include/common/tbbr/tbbr_img_def.h @@ -10,7 +10,7 @@ #include #if defined(SPD_spmd) -#define SP_CONTENT_CERT_ID MAX_IMAGE_IDS +#define SIP_SP_CONTENT_CERT_ID MAX_IMAGE_IDS #define SP_PKG1_ID (MAX_IMAGE_IDS + 1) #define SP_PKG2_ID (MAX_IMAGE_IDS + 2) #define SP_PKG3_ID (MAX_IMAGE_IDS + 3) diff --git a/include/drivers/auth/auth_mod.h b/include/drivers/auth/auth_mod.h index 01d144d2c..504e53939 100644 --- a/include/drivers/auth/auth_mod.h +++ b/include/drivers/auth/auth_mod.h @@ -51,11 +51,11 @@ extern const size_t cot_desc_size; extern unsigned int auth_img_flags[MAX_NUMBER_IDS]; #if defined(SPD_spmd) -#define DEFINE_SP_PKG(n) \ +#define DEFINE_SIP_SP_PKG(n) \ static const auth_img_desc_t sp_pkg##n = { \ - .img_id = SP_CONTENT_CERT_ID + (n), \ + .img_id = SP_PKG##n##_ID, \ .img_type = IMG_RAW, \ - .parent = &sp_content_cert, \ + .parent = &sip_sp_content_cert, \ .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { \ [0] = { \ .type = AUTH_METHOD_HASH, \ diff --git a/plat/arm/common/fconf/arm_fconf_io.c b/plat/arm/common/fconf/arm_fconf_io.c index 48cc4fee3..350ecd1b6 100644 --- a/plat/arm/common/fconf/arm_fconf_io.c +++ b/plat/arm/common/fconf/arm_fconf_io.c @@ -51,7 +51,7 @@ const io_uuid_spec_t arm_uuid_spec[MAX_NUMBER_IDS] = { [TRUSTED_OS_FW_CONTENT_CERT_ID] = {UUID_TRUSTED_OS_FW_CONTENT_CERT}, [NON_TRUSTED_FW_CONTENT_CERT_ID] = {UUID_NON_TRUSTED_FW_CONTENT_CERT}, #if defined(SPD_spmd) - [SP_CONTENT_CERT_ID] = {UUID_SIP_SECURE_PARTITION_CONTENT_CERT}, + [SIP_SP_CONTENT_CERT_ID] = {UUID_SIP_SECURE_PARTITION_CONTENT_CERT}, #endif #endif /* ARM_IO_IN_DTB */ #endif /* TRUSTED_BOARD_BOOT */ @@ -184,9 +184,9 @@ struct plat_io_policy policies[MAX_NUMBER_IDS] = { open_fip }, #if defined(SPD_spmd) - [SP_CONTENT_CERT_ID] = { + [SIP_SP_CONTENT_CERT_ID] = { &fip_dev_handle, - (uintptr_t)&arm_uuid_spec[SP_CONTENT_CERT_ID], + (uintptr_t)&arm_uuid_spec[SIP_SP_CONTENT_CERT_ID], open_fip }, #endif @@ -233,7 +233,7 @@ static const struct policies_load_info load_info[FCONF_ARM_IO_UUID_NUMBER] = { {TRUSTED_OS_FW_CONTENT_CERT_ID, "tos_fw_content_cert_uuid"}, {NON_TRUSTED_FW_CONTENT_CERT_ID, "nt_fw_content_cert_uuid"}, #if defined(SPD_spmd) - {SP_CONTENT_CERT_ID, "sp_content_cert_uuid"}, + {SIP_SP_CONTENT_CERT_ID, "sip_sp_content_cert_uuid"}, #endif #endif /* TRUSTED_BOARD_BOOT */ }; diff --git a/plat/arm/common/fconf/arm_fconf_sp.c b/plat/arm/common/fconf/arm_fconf_sp.c index 3522dcf9d..4459264c7 100644 --- a/plat/arm/common/fconf/arm_fconf_sp.c +++ b/plat/arm/common/fconf/arm_fconf_sp.c @@ -30,7 +30,7 @@ int fconf_populate_arm_sp(uintptr_t config) union uuid_helper_t uuid_helper; unsigned int index = 0; uint32_t val32; - const unsigned int sp_start_index = SP_CONTENT_CERT_ID + 1; + const unsigned int sp_start_index = SP_PKG1_ID; /* As libfdt use void *, we can't avoid this cast */ const void *dtb = (void *)config; -- cgit v1.2.3 From c2e3b3bb167f0866b2c5f15690860b11d15aaa33 Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Fri, 31 Jul 2020 15:23:55 +0100 Subject: BL31: Fix relocation error for PIE This patch fixes BL31 linker error "relocation R_AARCH64_ABS32 against `a local symbol' can not be used when making a shared object" when Position Independent Executable (PIE) support is enabled with ENABLE_PIE=1 build option. Change-Id: I2692269676db3f3b27eed499fc029fffb67969be Signed-off-by: Alexei Fedorov --- plat/common/aarch64/platform_mp_stack.S | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plat/common/aarch64/platform_mp_stack.S b/plat/common/aarch64/platform_mp_stack.S index e2d71da7a..ee0dbb4f6 100644 --- a/plat/common/aarch64/platform_mp_stack.S +++ b/plat/common/aarch64/platform_mp_stack.S @@ -59,7 +59,8 @@ func plat_get_my_stack bic x0, x0, #(CACHE_WRITEBACK_GRANULE - 1) ret x10 #endif - .word platform_normal_stacks + /* Prevent linker from removal of stack section */ + .quad platform_normal_stacks #else /* !(IMAGE_BL31 && RECLAIM_INIT_CODE) */ mov x10, x30 -- cgit v1.2.3 From 6844c3477b862195c12660f136e22313e84d4306 Mon Sep 17 00:00:00 2001 From: Madhukar Pappireddy Date: Wed, 29 Jul 2020 09:37:25 -0500 Subject: Fix broken links to various sections across docs These broken links were found with the help of this command: $> sphinx-build -M linkcheck . build A sample broken link is reported as follows: (line 80) -local- firmware-design.rst#secure-el1-payloads-and-dispatchers Change-Id: I5dcefdd4b8040908658115647e957f6c2c5da7c2 Signed-off-by: Madhukar Pappireddy --- docs/components/debugfs-design.rst | 4 +- docs/components/exception-handling.rst | 58 +++++++++------------- .../platform-interrupt-controller-API.rst | 2 + docs/components/sdei.rst | 2 + docs/components/secure-partition-manager-mm.rst | 4 +- docs/components/secure-partition-manager.rst | 4 +- docs/design/firmware-design.rst | 4 ++ docs/design/interrupt-framework-design.rst | 18 +++---- docs/getting_started/build-options.rst | 6 +-- docs/getting_started/porting-guide.rst | 8 +-- docs/plat/arm/fvp/index.rst | 2 +- 11 files changed, 50 insertions(+), 62 deletions(-) diff --git a/docs/components/debugfs-design.rst b/docs/components/debugfs-design.rst index 2096bdbb7..253651513 100644 --- a/docs/components/debugfs-design.rst +++ b/docs/components/debugfs-design.rst @@ -80,8 +80,8 @@ SMC interface The communication with the 9p layer in BL31 is made through an SMC conduit (`SMC Calling Convention`_), using a specific SiP Function Id. An NS shared buffer is used to pass path string parameters, or e.g. to exchange -data on a read operation. Refer to `ARM SiP Services`_ for a description -of the SMC interface. +data on a read operation. Refer to :ref:`ARM SiP Services ` +for a description of the SMC interface. Security considerations ----------------------- diff --git a/docs/components/exception-handling.rst b/docs/components/exception-handling.rst index 4c63a8b47..86ed87ce4 100644 --- a/docs/components/exception-handling.rst +++ b/docs/components/exception-handling.rst @@ -10,13 +10,9 @@ of the following exceptions when targeted at EL3: - Asynchronous External Aborts |TF-A|'s handling of synchronous ``SMC`` exceptions raised from lower ELs is -described in the `Firmware Design document`__. However, the |EHF| changes the -semantics of `interrupt handling`__ and `synchronous exceptions`__ other than -SMCs. - -.. __: firmware-design.rst#handling-an-smc -.. __: `Interrupt handling`_ -.. __: `Effect on SMC calls`_ +described in the :ref:`Firmware Design document `. However, the +|EHF| changes the semantics of `Interrupt handling`_ and :ref:`synchronous +exceptions ` other than SMCs. The |EHF| is selected by setting the build option ``EL3_EXCEPTION_HANDLING`` to ``1``, and is only available for AArch64 systems. @@ -77,10 +73,9 @@ On any given system, all of the above handling models may be employed independently depending on platform choice and the nature of the exception received. -.. [#spd] Not to be confused with `Secure Payload Dispatcher`__, which is an - EL3 component that operates in EL3 on behalf of Secure OS. - -.. __: firmware-design.rst#secure-el1-payloads-and-dispatchers +.. [#spd] Not to be confused with :ref:`Secure Payload Dispatcher + `, which is an EL3 component that operates in EL3 + on behalf of Secure OS. The role of Exception Handling Framework ---------------------------------------- @@ -139,6 +134,8 @@ unstacked in strictly the reverse order. For interrupts, the GIC ensures this is the case; for non-interrupts, the |EHF| monitors and asserts this. See `Transition of priority levels`_. +.. _interrupt-handling: + Interrupt handling ------------------ @@ -151,15 +148,12 @@ implications: sufficient priority are signalled as FIQs, and therefore will be routed to EL3. As a result, S-EL1 software cannot expect to handle Non-secure interrupts at S-EL1. Essentially, this deprecates the routing mode described - as `CSS=0, TEL3=0`__. - - .. __: interrupt-framework-design.rst#el3-interrupts + as :ref:`CSS=0, TEL3=0 `. In order for S-EL1 software to handle Non-secure interrupts while having |EHF| enabled, the dispatcher must adopt a model where Non-secure interrupts - are received at EL3, but are then `synchronously`__ handled over to S-EL1. - - .. __: interrupt-framework-design.rst#secure-payload + are received at EL3, but are then :ref:`synchronously ` + handled over to S-EL1. - On GICv2 systems, it's required that the build option ``GICV2_G0_FOR_EL3`` is set to ``1`` so that *Group 0* interrupts target EL3. @@ -283,15 +277,13 @@ The interrupt handler should have the following signature: typedef int (*ehf_handler_t)(uint32_t intr_raw, uint32_t flags, void *handle, void *cookie); -The parameters are as obtained from the top-level `EL3 interrupt handler`__. - -.. __: interrupt-framework-design.rst#el3-runtime-firmware +The parameters are as obtained from the top-level :ref:`EL3 interrupt handler +`. -The `SDEI dispatcher`__, for example, expects the platform to allocate two -different priority levels—``PLAT_SDEI_CRITICAL_PRI``, and -``PLAT_SDEI_NORMAL_PRI``—and registers the same handler to handle both levels. - -.. __: sdei.rst +The :ref:`SDEI dispatcher`, for +example, expects the platform to allocate two different priority levels— +``PLAT_SDEI_CRITICAL_PRI``, and ``PLAT_SDEI_NORMAL_PRI`` —and registers the +same handler to handle both levels. Interrupt handling example -------------------------- @@ -374,11 +366,9 @@ Activating and Deactivating priorities A priority level is said to be *active* when an exception of that priority is being handled: for interrupts, this is implied when the interrupt is -acknowledged; for non-interrupt exceptions, such as SErrors or `SDEI explicit -dispatches`__, this has to be done via calling ``ehf_activate_priority()``. See -`Run-time flow`_. - -.. __: sdei.rst#explicit-dispatch-of-events +acknowledged; for non-interrupt exceptions, such as SErrors or :ref:`SDEI +explicit dispatches `, this has to be done via +calling ``ehf_activate_priority()``. See `Run-time flow`_. Conversely, when the dispatcher has reached a logical resolution for the cause of the exception, the corresponding priority level ought to be deactivated. As @@ -457,6 +447,8 @@ calls to these APIs are subject to the following conditions: If these are violated, a panic will result. +.. _Effect on SMC calls: + Effect on SMC calls ------------------- @@ -542,10 +534,8 @@ The following is an example flow for interrupts: interrupts belonging to different dispatchers. #. The |EHF|, during its initialisation, registers a top-level interrupt handler - with the `Interrupt Management Framework`__ for EL3 interrupts. This also - results in setting the routing bits in ``SCR_EL3``. - - .. __: interrupt-framework-design.rst#el3-runtime-firmware + with the :ref:`Interrupt Management Framework` for EL3 + interrupts. This also results in setting the routing bits in ``SCR_EL3``. #. When an interrupt belonging to a dispatcher fires, GIC raises an EL3/Group 0 interrupt, and is taken to EL3. diff --git a/docs/components/platform-interrupt-controller-API.rst b/docs/components/platform-interrupt-controller-API.rst index 9d02f45c0..069c87b84 100644 --- a/docs/components/platform-interrupt-controller-API.rst +++ b/docs/components/platform-interrupt-controller-API.rst @@ -286,6 +286,8 @@ inserts to order memory updates before updating mask, then writes to the GIC *Priority Mask Register*, and make sure memory updates are visible before potential trigger due to mask update. +.. _plat_ic_get_interrupt_id: + Function: unsigned int plat_ic_get_interrupt_id(unsigned int raw); [optional] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/components/sdei.rst b/docs/components/sdei.rst index c5275a0b7..60259c830 100644 --- a/docs/components/sdei.rst +++ b/docs/components/sdei.rst @@ -205,6 +205,8 @@ will only allow SDEI calls to be made from: See the function ``sdei_client_el()`` in ``sdei_private.h``. +.. _explicit-dispatch-of-events: + Explicit dispatch of events --------------------------- diff --git a/docs/components/secure-partition-manager-mm.rst b/docs/components/secure-partition-manager-mm.rst index 87fc91df3..d53290102 100644 --- a/docs/components/secure-partition-manager-mm.rst +++ b/docs/components/secure-partition-manager-mm.rst @@ -6,11 +6,9 @@ Foreword Two implementations of a Secure Partition Manager co-exist in the TF-A codebase: -- SPM based on the PSA FF-A specification (`Secure Partition Manager`__). +- SPM based on the PSA FF-A specification (:ref:`Secure Partition Manager`). - SPM based on the MM interface. -.. __: secure-partition-manager.html - Both implementations differ in their architectures and only one can be selected at build time. diff --git a/docs/components/secure-partition-manager.rst b/docs/components/secure-partition-manager.rst index 2169f30a0..e09da53f3 100644 --- a/docs/components/secure-partition-manager.rst +++ b/docs/components/secure-partition-manager.rst @@ -833,9 +833,7 @@ References .. _[2]: -[2] `Secure Partition Manager using MM interface`__ - -.. __: secure-partition-manager-mm.html +[2] :ref:`Secure Partition Manager using MM interface` .. _[3]: diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst index ae6dd469d..a357d5858 100644 --- a/docs/design/firmware-design.rst +++ b/docs/design/firmware-design.rst @@ -957,6 +957,8 @@ Function ID call type and OEN onto a specific service handler in the |Image 1| +.. _handling-an-smc: + Handling an SMC ~~~~~~~~~~~~~~~ @@ -1300,6 +1302,8 @@ In other words, the reset handler should be able to detect whether an action has already been performed and act as appropriate. Possible courses of actions are, e.g. skip the action the second time, or undo/redo it. +.. _configuring-secure-interrupts: + Configuring secure interrupts ----------------------------- diff --git a/docs/design/interrupt-framework-design.rst b/docs/design/interrupt-framework-design.rst index 2e200aa3f..dfb2eac8e 100644 --- a/docs/design/interrupt-framework-design.rst +++ b/docs/design/interrupt-framework-design.rst @@ -150,10 +150,8 @@ EL3 interrupts However, when ``EL3_EXCEPTION_HANDLING`` is ``1``, this routing model is invalid as EL3 interrupts are unconditionally routed to EL3, and EL3 - interrupts will always preempt Secure EL1/EL0 execution. See `exception - handling`__ documentation. - - .. __: exception-handling.rst#interrupt-handling + interrupts will always preempt Secure EL1/EL0 execution. See :ref:`exception + handling` documentation. #. **CSS=0, TEL3=1**. Interrupt is routed to EL3 when execution is in Secure-EL1/Secure-EL0. This is a valid routing model as secure software @@ -303,6 +301,8 @@ This section describes in detail the role of each software component (see `Software components`_) during the registration of a handler for an interrupt type. +.. _el3-runtime-firmware: + EL3 runtime firmware ~~~~~~~~~~~~~~~~~~~~ @@ -901,14 +901,14 @@ it is generated during execution in the TSP with ``PSTATE.I`` = 0 when the |Image 2| -Secure payload -~~~~~~~~~~~~~~ +.. _sp-synchronous-int: + +Secure payload interrupt handling +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The SP should implement one or both of the synchronous and asynchronous interrupt handling models depending upon the interrupt routing model it has -chosen (as described in section `Secure Payload`__). - -.. __: #sp-int-registration +chosen (as described in section :ref:`Secure Payload `). In the synchronous model, it should begin handling a Secure-EL1 interrupt after receiving control from the SPD service at an entrypoint agreed upon during build diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 630d86119..b15ea1b52 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -346,16 +346,14 @@ Common build options - ``GICV2_G0_FOR_EL3``: Unlike GICv3, the GICv2 architecture doesn't have inherent support for specific EL3 type interrupts. Setting this build option to ``1`` assumes GICv2 *Group 0* interrupts are expected to target EL3, both - by `platform abstraction layer`__ and `Interrupt Management Framework`__. + by :ref:`platform abstraction layer` and + :ref:`Interrupt Management Framework`. This allows GICv2 platforms to enable features requiring EL3 interrupt type. This also means that all GICv2 Group 0 interrupts are delivered to EL3, and the Secure Payload interrupts needs to be synchronously handed over to Secure EL1 for handling. The default value of this option is ``0``, which means the Group 0 interrupts are assumed to be handled by Secure EL1. - .. __: platform-interrupt-controller-API.rst - .. __: interrupt-framework-design.rst - - ``HANDLE_EA_EL3_FIRST``: When set to ``1``, External Aborts and SError Interrupts will be always trapped in EL3 i.e. in BL31 at runtime. When set to ``0`` (default), these exceptions will be trapped in the current exception diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst index 7aaeae2f4..6b8bbc634 100644 --- a/docs/getting_started/porting-guide.rst +++ b/docs/getting_started/porting-guide.rst @@ -2482,9 +2482,7 @@ FVP can be configured to use either GICv2 or GICv3 depending on the build flag ``FVP_USE_GIC_DRIVER`` (See :ref:`build_options_arm_fvp_platform` for more details). -See also: `Interrupt Controller Abstraction APIs`__. - -.. __: ../design/platform-interrupt-controller-API.rst +See also: :ref:`Interrupt Controller Abstraction APIs`. Function : plat_interrupt_type_to_line() [mandatory] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2609,9 +2607,7 @@ This API is used by the CPU to indicate to the platform IC that processing of the highest pending interrupt has begun. It should return the raw, unmodified value obtained from the interrupt controller when acknowledging an interrupt. The actual interrupt number shall be extracted from this raw value using the API -`plat_ic_get_interrupt_id()`__. - -.. __: ../design/platform-interrupt-controller-API.rst#function-unsigned-int-plat-ic-get-interrupt-id-unsigned-int-raw-optional +`plat_ic_get_interrupt_id()`. This function in Arm standard platforms using GICv2, reads the *Interrupt Acknowledge Register* (``GICC_IAR``). This changes the state of the highest diff --git a/docs/plat/arm/fvp/index.rst b/docs/plat/arm/fvp/index.rst index fd658bbff..745e31f9e 100644 --- a/docs/plat/arm/fvp/index.rst +++ b/docs/plat/arm/fvp/index.rst @@ -635,7 +635,7 @@ boot Linux with 4 CPUs using the AArch32 build of TF-A. *Copyright (c) 2019-2020, Arm Limited. All rights reserved.* -.. _TB_FW_CONFIG for FVP: ../plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts +.. _TB_FW_CONFIG for FVP: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts .. _Arm's website: `FVP models`_ .. _FVP models: https://developer.arm.com/products/system-design/fixed-virtual-platforms .. _Linaro Release 19.06: http://releases.linaro.org/members/arm/platforms/19.06 -- cgit v1.2.3 From 29214e95c444b53f544b97127b3e70583d356bee Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 30 Jul 2020 08:50:10 +0100 Subject: Use abspath to dereference $BUILD_BASE If the user tries to change BUILD_BASE to put the build products outside the build tree the compile will fail due to hard coded assumptions that $BUILD_BASE is a relative path. Fix by using $(abspath $(BUILD_BASE)) to rationalize to an absolute path every time and remove the relative path assumptions. This patch also adds documentation that BUILD_BASE can be specified by the user. Signed-off-by: Grant Likely Signed-off-by: Manish Pandey Change-Id: Ib1af874de658484aaffc672f30029b852d2489c8 --- Makefile | 6 ++++-- docs/getting_started/build-options.rst | 2 ++ lib/romlib/Makefile | 8 ++++---- plat/marvell/armada/a8k/common/ble/ble.mk | 8 ++++---- plat/nvidia/tegra/platform.mk | 2 +- plat/ti/k3/platform.mk | 2 +- tools/sptool/sp_mk_generator.py | 4 ++-- 7 files changed, 18 insertions(+), 14 deletions(-) diff --git a/Makefile b/Makefile index fa711e26a..6e14bdc3b 100644 --- a/Makefile +++ b/Makefile @@ -451,8 +451,10 @@ include common/backtrace/backtrace.mk include ${MAKE_HELPERS_DIRECTORY}plat_helpers.mk -BUILD_BASE := ./build -BUILD_PLAT := ${BUILD_BASE}/${PLAT}/${BUILD_TYPE} +ifeq (${BUILD_BASE},) + BUILD_BASE := ./build +endif +BUILD_PLAT := $(abspath ${BUILD_BASE})/${PLAT}/${BUILD_TYPE} SPDS := $(sort $(filter-out none, $(patsubst services/spd/%,%,$(wildcard services/spd/*)))) diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 630d86119..153dc3927 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -119,6 +119,8 @@ Common build options - ``BUILD_STRING``: Input string for VERSION_STRING, which allows the TF-A build to be uniquely identified. Defaults to the current git commit id. +- ``BUILD_BASE``: Output directory for the build. Defaults to ``./build`` + - ``CFLAGS``: Extra user options appended on the compiler's command line in addition to the options set by the build system. diff --git a/lib/romlib/Makefile b/lib/romlib/Makefile index cec94043d..2ff480bd4 100644 --- a/lib/romlib/Makefile +++ b/lib/romlib/Makefile @@ -10,14 +10,14 @@ LD = $(CROSS_COMPILE)ld OC = $(CROSS_COMPILE)objcopy CPP = $(CROSS_COMPILE)cpp ROMLIB_GEN = ./romlib_generator.py -BUILD_DIR = ../../$(BUILD_PLAT)/romlib -LIB_DIR = ../../$(BUILD_PLAT)/lib -WRAPPER_DIR = ../../$(BUILD_PLAT)/libwrapper +BUILD_DIR = $(BUILD_PLAT)/romlib +LIB_DIR = $(BUILD_PLAT)/lib +WRAPPER_DIR = $(BUILD_PLAT)/libwrapper LIBS = -lmbedtls -lfdt -lc INC = $(INCLUDES:-I%=-I../../%) PPFLAGS = $(INC) $(DEFINES) -P -x assembler-with-cpp -D__LINKER__ -MD -MP -MT $(BUILD_DIR)/romlib.ld OBJS = $(BUILD_DIR)/jmptbl.o $(BUILD_DIR)/init.o -MAPFILE = ../../$(BUILD_PLAT)/romlib/romlib.map +MAPFILE = $(BUILD_PLAT)/romlib/romlib.map ifneq ($(PLAT_DIR),) WRAPPER_SOURCES = $(shell $(ROMLIB_GEN) genwrappers -b $(WRAPPER_DIR) --list ../../$(PLAT_DIR)/jmptbl.i) diff --git a/plat/marvell/armada/a8k/common/ble/ble.mk b/plat/marvell/armada/a8k/common/ble/ble.mk index 82ac09882..60fbf5f1d 100644 --- a/plat/marvell/armada/a8k/common/ble/ble.mk +++ b/plat/marvell/armada/a8k/common/ble/ble.mk @@ -5,9 +5,9 @@ MV_DDR_PATH ?= drivers/marvell/mv_ddr -MV_DDR_LIB = $(CURDIR)/$(BUILD_PLAT)/ble/mv_ddr_lib.a -LIBC_LIB = $(CURDIR)/$(BUILD_PLAT)/lib/libc.a -BLE_LIBS = $(MV_DDR_LIB) $(LIBC_LIB) +MV_DDR_LIB = $(BUILD_PLAT)/ble/mv_ddr_lib.a +LIBC_LIB = $(BUILD_PLAT)/lib/libc.a +BLE_LIBS = $(MV_DDR_LIB) $(LIBC_LIB) PLAT_MARVELL = plat/marvell/armada BLE_SOURCES += $(BLE_PATH)/ble_main.c \ @@ -29,4 +29,4 @@ BLE_LINKERFILE := $(BLE_PATH)/ble.ld.S FORCE: $(MV_DDR_LIB): FORCE - @+make -C $(MV_DDR_PATH) --no-print-directory PLAT_INCLUDES="$(PLAT_INCLUDES)" PLATFORM=$(PLAT) ARCH=AARCH64 OBJ_DIR=$(CURDIR)/$(BUILD_PLAT)/ble + @+make -C $(MV_DDR_PATH) --no-print-directory PLAT_INCLUDES="$(PLAT_INCLUDES)" PLATFORM=$(PLAT) ARCH=AARCH64 OBJ_DIR=$(BUILD_PLAT)/ble diff --git a/plat/nvidia/tegra/platform.mk b/plat/nvidia/tegra/platform.mk index 3d61f0656..a4724e64b 100644 --- a/plat/nvidia/tegra/platform.mk +++ b/plat/nvidia/tegra/platform.mk @@ -62,7 +62,7 @@ $(eval $(call add_define,ENABLE_TEGRA_WDT_LEGACY_FIQ_HANDLING)) $(eval $(call add_define,RELOCATE_BL32_IMAGE)) # modify BUILD_PLAT to point to SoC specific build directory -BUILD_PLAT := ${BUILD_BASE}/${PLAT}/${TARGET_SOC}/${BUILD_TYPE} +BUILD_PLAT := $(abspath ${BUILD_BASE})/${PLAT}/${TARGET_SOC}/${BUILD_TYPE} # platform cflags (enable signed comparisons, disable stdlib) TF_CFLAGS += -Wsign-compare -nostdlib diff --git a/plat/ti/k3/platform.mk b/plat/ti/k3/platform.mk index 65d5cc2a4..2de21aa7b 100644 --- a/plat/ti/k3/platform.mk +++ b/plat/ti/k3/platform.mk @@ -11,4 +11,4 @@ include ${PLAT_PATH}/common/plat_common.mk include ${PLAT_PATH}/board/${TARGET_BOARD}/board.mk # modify BUILD_PLAT to point to board specific build directory -BUILD_PLAT := ${BUILD_BASE}/${PLAT}/${TARGET_BOARD}/${BUILD_TYPE} +BUILD_PLAT := $(abspath ${BUILD_BASE})/${PLAT}/${TARGET_BOARD}/${BUILD_TYPE} diff --git a/tools/sptool/sp_mk_generator.py b/tools/sptool/sp_mk_generator.py index f2387f6b1..2153a5651 100755 --- a/tools/sptool/sp_mk_generator.py +++ b/tools/sptool/sp_mk_generator.py @@ -55,8 +55,8 @@ with open(sys.argv[2],'r') as in_file: data = json.load(in_file) json_file = os.path.abspath(sys.argv[2]) json_dir = os.path.dirname(json_file) -gen_file = sys.argv[1] -out_dir = sys.argv[3][2:] +gen_file = os.path.abspath(sys.argv[1]) +out_dir = os.path.abspath(sys.argv[3]) dtb_dir = out_dir + "/fdts/" print(dtb_dir) -- cgit v1.2.3 From 8567103ef94b1abb52f9fb053bd6118913878d74 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Mon, 27 Jul 2020 21:22:14 +0800 Subject: plat: imx: add sdei support for i.MX8MM Add sdei support for i.MX8MM, this is to let jailhouse Hypervisor could use SDEI to do hypervisor management, after physical IRQ has been disabled routing. Signed-off-by: Peng Fan Change-Id: I5fd697fee22df151e13d0f1335e8ac8a7bae6189 --- plat/imx/common/imx_ehf.c | 22 +++++++++++++++++++ plat/imx/common/imx_sdei.c | 32 ++++++++++++++++++++++++++++ plat/imx/common/plat_imx8_gic.c | 4 ++++ plat/imx/imx8m/imx8mm/include/platform_def.h | 5 +++++ plat/imx/imx8m/imx8mm/platform.mk | 5 +++++ 5 files changed, 68 insertions(+) create mode 100644 plat/imx/common/imx_ehf.c create mode 100644 plat/imx/common/imx_sdei.c diff --git a/plat/imx/common/imx_ehf.c b/plat/imx/common/imx_ehf.c new file mode 100644 index 000000000..a9396cd5e --- /dev/null +++ b/plat/imx/common/imx_ehf.c @@ -0,0 +1,22 @@ +/* + * Copyright 2020 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include + +ehf_pri_desc_t imx_exceptions[] = { +#if SDEI_SUPPORT + /* Critical priority SDEI */ + EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_SDEI_CRITICAL_PRI), + + /* Normal priority SDEI */ + EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_SDEI_NORMAL_PRI), +#endif +}; + +/* Plug in ARM exceptions to Exception Handling Framework. */ +EHF_REGISTER_PRIORITIES(imx_exceptions, ARRAY_SIZE(imx_exceptions), PLAT_PRI_BITS); diff --git a/plat/imx/common/imx_sdei.c b/plat/imx/common/imx_sdei.c new file mode 100644 index 000000000..4b6033fb6 --- /dev/null +++ b/plat/imx/common/imx_sdei.c @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. + * Copyright 2020 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* SDEI configuration for ARM platforms */ + +#include +#include +#include +#include + +#include + +/* Private event mappings */ +static sdei_ev_map_t imx_sdei_private[] = { + SDEI_DEFINE_EVENT_0(PLAT_SDEI_SGI_PRIVATE), +}; + +/* Shared event mappings */ +static sdei_ev_map_t imx_sdei_shared[] = { +}; + +void plat_sdei_setup(void) +{ + INFO("SDEI platform setup\n"); +} + +/* Export ARM SDEI events */ +REGISTER_SDEI_MAP(imx_sdei_private, imx_sdei_shared); diff --git a/plat/imx/common/plat_imx8_gic.c b/plat/imx/common/plat_imx8_gic.c index afb9d1f1a..150e81e7d 100644 --- a/plat/imx/common/plat_imx8_gic.c +++ b/plat/imx/common/plat_imx8_gic.c @@ -22,6 +22,10 @@ uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT]; static const interrupt_prop_t g01s_interrupt_props[] = { INTR_PROP_DESC(8, GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0, GIC_INTR_CFG_LEVEL), +#if SDEI_SUPPORT + INTR_PROP_DESC(PLAT_SDEI_SGI_PRIVATE, PLAT_SDEI_NORMAL_PRI, + INTR_GROUP0, GIC_INTR_CFG_LEVEL), +#endif }; static unsigned int plat_imx_mpidr_to_core_pos(unsigned long mpidr) diff --git a/plat/imx/imx8m/imx8mm/include/platform_def.h b/plat/imx/imx8m/imx8mm/include/platform_def.h index f25ceb034..1041459c8 100644 --- a/plat/imx/imx8m/imx8mm/include/platform_def.h +++ b/plat/imx/imx8m/imx8mm/include/platform_def.h @@ -29,6 +29,11 @@ #define PLAT_WAIT_RET_STATE U(1) #define PLAT_STOP_OFF_STATE U(3) +#define PLAT_PRI_BITS U(3) +#define PLAT_SDEI_CRITICAL_PRI 0x10 +#define PLAT_SDEI_NORMAL_PRI 0x20 +#define PLAT_SDEI_SGI_PRIVATE U(9) + #define BL31_BASE U(0x920000) #define BL31_LIMIT U(0x940000) diff --git a/plat/imx/imx8m/imx8mm/platform.mk b/plat/imx/imx8m/imx8mm/platform.mk index 3ead7b0b2..ac636fa8f 100644 --- a/plat/imx/imx8m/imx8mm/platform.mk +++ b/plat/imx/imx8m/imx8mm/platform.mk @@ -29,6 +29,8 @@ BL31_SOURCES += plat/imx/common/imx8_helpers.S \ plat/imx/common/imx_sip_handler.c \ plat/imx/common/imx_sip_svc.c \ plat/imx/common/imx_uart_console.S \ + plat/imx/common/imx_ehf.c \ + plat/imx/common/imx_sdei.c \ lib/xlat_tables/aarch64/xlat_tables.c \ lib/xlat_tables/xlat_tables_common.c \ lib/cpus/aarch64/cortex_a53.S \ @@ -53,3 +55,6 @@ $(eval $(call add_define,BL32_SIZE)) IMX_BOOT_UART_BASE ?= 0x30890000 $(eval $(call add_define,IMX_BOOT_UART_BASE)) + +EL3_EXCEPTION_HANDLING := 1 +SDEI_SUPPORT := 1 -- cgit v1.2.3 From a4075bb55b4d36a9674d58528f0e6cd3a8cab5ae Mon Sep 17 00:00:00 2001 From: Madhukar Pappireddy Date: Thu, 6 Aug 2020 12:36:17 -0500 Subject: Fix broken links in docs Change-Id: If82aaba9f2a5a74cfb5e4381f968166037a70037 Signed-off-by: Madhukar Pappireddy --- docs/components/exception-handling.rst | 11 +++++------ docs/components/secure-partition-manager.rst | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/docs/components/exception-handling.rst b/docs/components/exception-handling.rst index 86ed87ce4..6f223c675 100644 --- a/docs/components/exception-handling.rst +++ b/docs/components/exception-handling.rst @@ -233,12 +233,11 @@ The text in `Partitioning priority levels`_ only describes how the platform expresses the required levels of priority. It however doesn't choose interrupts nor program the required priority in GIC. -The `Firmware Design guide`__ explains methods for configuring secure -interrupts. |EHF| requires the platform to enumerate interrupt properties (as -opposed to just numbers) of Secure interrupts. The priority of secure interrupts -must match that as determined in the `Partitioning priority levels`_ section above. - -.. __: firmware-design.rst#configuring-secure-interrupts +The :ref:`Firmware Design guide` explains methods +for configuring secure interrupts. |EHF| requires the platform to enumerate +interrupt properties (as opposed to just numbers) of Secure interrupts. The +priority of secure interrupts must match that as determined in the +`Partitioning priority levels`_ section above. See `Limitations`_, and also refer to `Interrupt handling example`_ for illustration. diff --git a/docs/components/secure-partition-manager.rst b/docs/components/secure-partition-manager.rst index e09da53f3..c58cd0801 100644 --- a/docs/components/secure-partition-manager.rst +++ b/docs/components/secure-partition-manager.rst @@ -126,7 +126,7 @@ The following TF-A build options are provisioned: restoring) the EL2 system register context before entering (resp. after leaving) the SPMC. It is mandatory when ``SPMD_SPM_AT_SEL2`` is enabled. The context save/restore routine and exhaustive list of - registers is visible at `[4] <#References>`__. + registers is visible at `[4]`_. - **SP_LAYOUT_FILE**: this option provides a text description file providing paths to SP binary images and DTS format manifests (see `Specifying partition binary image and DT`_). It -- cgit v1.2.3 From 633fa4cd1fc8ef7f1b79bc4068b91c97fe4af4ef Mon Sep 17 00:00:00 2001 From: johpow01 Date: Thu, 30 Jul 2020 17:11:03 -0500 Subject: MISRA cleanup in mem_region and semihosting files MISRA defect cleanup and general code cleanup in mem_region.c and semihosting.c. This task also called for cleanup of the ARM NOR flash driver but that was removed at some point since the Jira task was created. This patch fixes all MISRA defects in these files except for a few "Calling function "console_flush()" which returns error information without testing the error information." errors which can't really be avoided. Defects Fixed File Line Rule lib/semihosting/semihosting.c 70 MISRA C-2012 Rule 14.4 (required) lib/semihosting/semihosting.c 197 MISRA C-2012 Rule 14.3 (required) lib/semihosting/semihosting.c 210 MISRA C-2012 Rule 14.4 (required) lib/utils/mem_region.c 128 MISRA C-2012 Rule 12.1 (advisory) Signed-off-by: John Powell Change-Id: I21a039d1cfccd6aa4301da09daec15e373305a80 --- lib/semihosting/semihosting.c | 77 ++++++++++++++++++++++--------------------- lib/utils/mem_region.c | 35 +++++++++++--------- 2 files changed, 60 insertions(+), 52 deletions(-) diff --git a/lib/semihosting/semihosting.c b/lib/semihosting/semihosting.c index 60fc52a00..e0845c1a5 100644 --- a/lib/semihosting/semihosting.c +++ b/lib/semihosting/semihosting.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -14,8 +14,7 @@ #define SEMIHOSTING_SUPPORTED 1 #endif -long semihosting_call(unsigned long operation, - uintptr_t system_block_address); +long semihosting_call(unsigned long operation, uintptr_t system_block_address); typedef struct { const char *file_name; @@ -52,8 +51,7 @@ long semihosting_file_open(const char *file_name, size_t mode) open_block.mode = mode; open_block.name_length = strlen(file_name); - return semihosting_call(SEMIHOSTING_SYS_OPEN, - (uintptr_t) &open_block); + return semihosting_call(SEMIHOSTING_SYS_OPEN, (uintptr_t)&open_block); } long semihosting_file_seek(long file_handle, ssize_t offset) @@ -64,11 +62,11 @@ long semihosting_file_seek(long file_handle, ssize_t offset) seek_block.handle = file_handle; seek_block.location = offset; - result = semihosting_call(SEMIHOSTING_SYS_SEEK, - (uintptr_t) &seek_block); + result = semihosting_call(SEMIHOSTING_SYS_SEEK, (uintptr_t)&seek_block); - if (result) + if (result != 0) { result = semihosting_call(SEMIHOSTING_SYS_ERRNO, 0); + } return result; } @@ -78,41 +76,42 @@ long semihosting_file_read(long file_handle, size_t *length, uintptr_t buffer) smh_file_read_write_block_t read_block; long result = -EINVAL; - if ((length == NULL) || (buffer == (uintptr_t)NULL)) + if ((length == NULL) || (buffer == (uintptr_t)NULL)) { return result; + } read_block.handle = file_handle; read_block.buffer = buffer; read_block.length = *length; - result = semihosting_call(SEMIHOSTING_SYS_READ, - (uintptr_t) &read_block); + result = semihosting_call(SEMIHOSTING_SYS_READ, (uintptr_t)&read_block); if (result == *length) { return -EINVAL; } else if (result < *length) { *length -= result; return 0; - } else + } else { return result; + } } -long semihosting_file_write(long file_handle, - size_t *length, - const uintptr_t buffer) +long semihosting_file_write(long file_handle, size_t *length, + const uintptr_t buffer) { smh_file_read_write_block_t write_block; long result = -EINVAL; - if ((length == NULL) || (buffer == (uintptr_t)NULL)) + if ((length == NULL) || (buffer == (uintptr_t)NULL)) { return -EINVAL; + } write_block.handle = file_handle; write_block.buffer = (uintptr_t)buffer; /* cast away const */ write_block.length = *length; result = semihosting_call(SEMIHOSTING_SYS_WRITE, - (uintptr_t) &write_block); + (uintptr_t)&write_block); *length = result; @@ -121,14 +120,12 @@ long semihosting_file_write(long file_handle, long semihosting_file_close(long file_handle) { - return semihosting_call(SEMIHOSTING_SYS_CLOSE, - (uintptr_t) &file_handle); + return semihosting_call(SEMIHOSTING_SYS_CLOSE, (uintptr_t)&file_handle); } long semihosting_file_length(long file_handle) { - return semihosting_call(SEMIHOSTING_SYS_FLEN, - (uintptr_t) &file_handle); + return semihosting_call(SEMIHOSTING_SYS_FLEN, (uintptr_t)&file_handle); } char semihosting_read_char(void) @@ -138,12 +135,12 @@ char semihosting_read_char(void) void semihosting_write_char(char character) { - semihosting_call(SEMIHOSTING_SYS_WRITEC, (uintptr_t) &character); + semihosting_call(SEMIHOSTING_SYS_WRITEC, (uintptr_t)&character); } void semihosting_write_string(char *string) { - semihosting_call(SEMIHOSTING_SYS_WRITE0, (uintptr_t) string); + semihosting_call(SEMIHOSTING_SYS_WRITE0, (uintptr_t)string); } long semihosting_system(char *command_line) @@ -154,7 +151,7 @@ long semihosting_system(char *command_line) system_block.command_length = strlen(command_line); return semihosting_call(SEMIHOSTING_SYS_SYSTEM, - (uintptr_t) &system_block); + (uintptr_t)&system_block); } long semihosting_get_flen(const char *file_name) @@ -162,16 +159,17 @@ long semihosting_get_flen(const char *file_name) long file_handle; long length; - assert(semihosting_connection_supported()); + assert(semihosting_connection_supported() != 0); file_handle = semihosting_file_open(file_name, FOPEN_MODE_RB); - if (file_handle == -1) + if (file_handle == -1) { return file_handle; + } /* Find the length of the file */ length = semihosting_file_length(file_handle); - return semihosting_file_close(file_handle) ? -1 : length; + return (semihosting_file_close(file_handle) != 0) ? -1 : length; } long semihosting_download_file(const char *file_name, @@ -183,23 +181,27 @@ long semihosting_download_file(const char *file_name, long file_handle; /* Null pointer check */ - if (!buf) + if (buf == 0U) { return ret; + } - assert(semihosting_connection_supported()); + assert(semihosting_connection_supported() != 0); file_handle = semihosting_file_open(file_name, FOPEN_MODE_RB); - if (file_handle == -1) + if (file_handle == -1) { return ret; + } /* Find the actual length of the file */ length = semihosting_file_length(file_handle); - if (length == -1) + if (length == (size_t)(-1)) { goto semihosting_fail; + } /* Signal error if we do not have enough space for the file */ - if (length > buf_size) + if (length > buf_size) { goto semihosting_fail; + } /* * A successful read will return 0 in which case we pass back @@ -207,10 +209,11 @@ long semihosting_download_file(const char *file_name, * value indicating an error. */ ret = semihosting_file_read(file_handle, &length, buf); - if (ret) + if (ret != 0) { goto semihosting_fail; - else - ret = length; + } else { + ret = (long)length; + } semihosting_fail: semihosting_file_close(file_handle); @@ -222,9 +225,9 @@ void semihosting_exit(uint32_t reason, uint32_t subcode) #ifdef __aarch64__ uint64_t parameters[] = {reason, subcode}; - (void) semihosting_call(SEMIHOSTING_SYS_EXIT, (uintptr_t) ¶meters); + (void)semihosting_call(SEMIHOSTING_SYS_EXIT, (uintptr_t)¶meters); #else /* The subcode is not supported on AArch32. */ - (void) semihosting_call(SEMIHOSTING_SYS_EXIT, reason); + (void)semihosting_call(SEMIHOSTING_SYS_EXIT, reason); #endif } diff --git a/lib/utils/mem_region.c b/lib/utils/mem_region.c index 6bd78ba82..fec086b8c 100644 --- a/lib/utils/mem_region.c +++ b/lib/utils/mem_region.c @@ -33,7 +33,7 @@ void clear_mem_regions(mem_region_t *tbl, size_t nregions) size_t i; assert(tbl != NULL); - assert(nregions > 0); + assert(nregions > 0U); for (i = 0; i < nregions; i++) { assert(tbl->nbytes > 0); @@ -64,28 +64,32 @@ void clear_map_dyn_mem_regions(struct mem_region *regions, const unsigned int attr = MT_MEMORY | MT_RW | MT_NS; assert(regions != NULL); - assert(nregions > 0 && chunk > 0); - - for ( ; nregions--; regions++) { - begin = regions->base; - size = regions->nbytes; - if ((begin & (chunk-1)) != 0 || (size & (chunk-1)) != 0) { + assert(nregions != 0U); + assert(chunk != 0U); + + for (unsigned int i = 0U; i < nregions; i++) { + begin = regions[i].base; + size = regions[i].nbytes; + if (((begin & (chunk-1U)) != 0U) || + ((size & (chunk-1U)) != 0U)) { INFO("PSCI: Not correctly aligned region\n"); panic(); } - while (size > 0) { + while (size > 0U) { r = mmap_add_dynamic_region(begin, va, chunk, attr); if (r != 0) { - INFO("PSCI: mmap_add_dynamic_region failed with %d\n", r); + INFO("PSCI: %s failed with %d\n", + "mmap_add_dynamic_region", r); panic(); } - zero_normalmem((void *) va, chunk); + zero_normalmem((void *)va, chunk); r = mmap_remove_dynamic_region(va, chunk); if (r != 0) { - INFO("PSCI: mmap_remove_dynamic_region failed with %d\n", r); + INFO("PSCI: %s failed with %d\n", + "mmap_remove_dynamic_region", r); panic(); } @@ -115,18 +119,19 @@ int mem_region_in_array_chk(mem_region_t *tbl, size_t nregions, size_t i; assert(tbl != NULL); - assert(nbytes > 0); + assert(nbytes != 0U); assert(!check_uptr_overflow(addr, nbytes-1)); region_start = addr; - region_end = addr + (nbytes - 1); - for (i = 0; i < nregions; i++) { + region_end = addr + (nbytes - 1U); + for (i = 0U; i < nregions; i++) { assert(tbl->nbytes > 0); assert(!check_uptr_overflow(tbl->base, tbl->nbytes-1)); start = tbl->base; end = start + (tbl->nbytes - 1); - if (region_start >= start && region_end <= end) + if ((region_start >= start) && (region_end <= end)) { return 0; + } tbl++; } -- cgit v1.2.3 From 5112e603285e3a27f0de25e02910deabc3653cbc Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Thu, 13 Jun 2019 11:55:05 -0700 Subject: lib: cpus: denver: mark exception vectors as private This patch removes the 'workaround_bpflush_runtime_exceptions' exception vector table base address from the globals list as it gets used only by the Denver CPU implementation. Change-Id: I6ef94989f6dc4535d464493cc8621d32795ee1f6 Signed-off-by: Varun Wadekar --- lib/cpus/aarch64/denver.S | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/cpus/aarch64/denver.S b/lib/cpus/aarch64/denver.S index c050b02a7..bdca4c343 100644 --- a/lib/cpus/aarch64/denver.S +++ b/lib/cpus/aarch64/denver.S @@ -27,8 +27,6 @@ * table. * ------------------------------------------------- */ - .globl workaround_bpflush_runtime_exceptions - vector_base workaround_bpflush_runtime_exceptions .macro apply_workaround -- cgit v1.2.3 From e2469d823bfc633a32782a8c018d3b55eb2b23a1 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Thu, 13 Jun 2019 15:32:11 -0700 Subject: Tegra: reorganize drivers and lib folders This patch moves the 'drivers' and the 'lib' folders out of the 'common' folder. This way the 'common' folder shall contain only the platform support required for all Tegra platforms. Change-Id: I2f238572d0a078d60c6b458a559538dc8a4d1856 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/drivers/bpmp/bpmp.c | 231 -------- plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c | 345 ----------- plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h | 127 ---- plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.c | 654 --------------------- plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h | 50 -- .../tegra/common/drivers/flowctrl/flowctrl.c | 322 ---------- plat/nvidia/tegra/common/drivers/gpcdma/gpcdma.c | 188 ------ .../tegra/common/drivers/memctrl/memctrl_v1.c | 225 ------- .../tegra/common/drivers/memctrl/memctrl_v2.c | 392 ------------ plat/nvidia/tegra/common/drivers/pmc/pmc.c | 153 ----- plat/nvidia/tegra/common/drivers/smmu/smmu.c | 65 -- .../tegra/common/drivers/spe/shared_console.S | 188 ------ plat/nvidia/tegra/common/lib/debug/profiler.c | 144 ----- plat/nvidia/tegra/common/tegra_common.mk | 39 +- plat/nvidia/tegra/drivers/bpmp/bpmp.c | 231 ++++++++ plat/nvidia/tegra/drivers/bpmp_ipc/intf.c | 345 +++++++++++ plat/nvidia/tegra/drivers/bpmp_ipc/intf.h | 127 ++++ plat/nvidia/tegra/drivers/bpmp_ipc/ivc.c | 654 +++++++++++++++++++++ plat/nvidia/tegra/drivers/bpmp_ipc/ivc.h | 50 ++ plat/nvidia/tegra/drivers/flowctrl/flowctrl.c | 322 ++++++++++ plat/nvidia/tegra/drivers/gpcdma/gpcdma.c | 188 ++++++ plat/nvidia/tegra/drivers/memctrl/memctrl_v1.c | 225 +++++++ plat/nvidia/tegra/drivers/memctrl/memctrl_v2.c | 392 ++++++++++++ plat/nvidia/tegra/drivers/pmc/pmc.c | 153 +++++ plat/nvidia/tegra/drivers/smmu/smmu.c | 65 ++ plat/nvidia/tegra/drivers/spe/shared_console.S | 188 ++++++ plat/nvidia/tegra/lib/debug/profiler.c | 144 +++++ plat/nvidia/tegra/soc/t132/platform_t132.mk | 6 +- plat/nvidia/tegra/soc/t186/platform_t186.mk | 12 +- plat/nvidia/tegra/soc/t194/platform_t194.mk | 15 +- plat/nvidia/tegra/soc/t210/platform_t210.mk | 12 +- 31 files changed, 3132 insertions(+), 3120 deletions(-) delete mode 100644 plat/nvidia/tegra/common/drivers/bpmp/bpmp.c delete mode 100644 plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c delete mode 100644 plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h delete mode 100644 plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.c delete mode 100644 plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h delete mode 100644 plat/nvidia/tegra/common/drivers/flowctrl/flowctrl.c delete mode 100644 plat/nvidia/tegra/common/drivers/gpcdma/gpcdma.c delete mode 100644 plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c delete mode 100644 plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c delete mode 100644 plat/nvidia/tegra/common/drivers/pmc/pmc.c delete mode 100644 plat/nvidia/tegra/common/drivers/smmu/smmu.c delete mode 100644 plat/nvidia/tegra/common/drivers/spe/shared_console.S delete mode 100644 plat/nvidia/tegra/common/lib/debug/profiler.c create mode 100644 plat/nvidia/tegra/drivers/bpmp/bpmp.c create mode 100644 plat/nvidia/tegra/drivers/bpmp_ipc/intf.c create mode 100644 plat/nvidia/tegra/drivers/bpmp_ipc/intf.h create mode 100644 plat/nvidia/tegra/drivers/bpmp_ipc/ivc.c create mode 100644 plat/nvidia/tegra/drivers/bpmp_ipc/ivc.h create mode 100644 plat/nvidia/tegra/drivers/flowctrl/flowctrl.c create mode 100644 plat/nvidia/tegra/drivers/gpcdma/gpcdma.c create mode 100644 plat/nvidia/tegra/drivers/memctrl/memctrl_v1.c create mode 100644 plat/nvidia/tegra/drivers/memctrl/memctrl_v2.c create mode 100644 plat/nvidia/tegra/drivers/pmc/pmc.c create mode 100644 plat/nvidia/tegra/drivers/smmu/smmu.c create mode 100644 plat/nvidia/tegra/drivers/spe/shared_console.S create mode 100644 plat/nvidia/tegra/lib/debug/profiler.c diff --git a/plat/nvidia/tegra/common/drivers/bpmp/bpmp.c b/plat/nvidia/tegra/common/drivers/bpmp/bpmp.c deleted file mode 100644 index d7db604cc..000000000 --- a/plat/nvidia/tegra/common/drivers/bpmp/bpmp.c +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define BPMP_TIMEOUT 500 /* 500ms */ - -static uint32_t channel_base[NR_CHANNELS]; -static uint32_t bpmp_init_state = BPMP_INIT_PENDING; - -static uint32_t channel_field(unsigned int ch) -{ - return mmio_read_32(TEGRA_RES_SEMA_BASE + STA_OFFSET) & CH_MASK(ch); -} - -static bool master_free(unsigned int ch) -{ - return channel_field(ch) == MA_FREE(ch); -} - -static bool master_acked(unsigned int ch) -{ - return channel_field(ch) == MA_ACKD(ch); -} - -static void signal_slave(unsigned int ch) -{ - mmio_write_32(TEGRA_RES_SEMA_BASE + CLR_OFFSET, CH_MASK(ch)); -} - -static void free_master(unsigned int ch) -{ - mmio_write_32(TEGRA_RES_SEMA_BASE + CLR_OFFSET, - MA_ACKD(ch) ^ MA_FREE(ch)); -} - -/* should be called with local irqs disabled */ -int32_t tegra_bpmp_send_receive_atomic(int mrq, const void *ob_data, int ob_sz, - void *ib_data, int ib_sz) -{ - unsigned int ch = (unsigned int)plat_my_core_pos(); - mb_data_t *p = (mb_data_t *)(uintptr_t)channel_base[ch]; - int32_t ret = -ETIMEDOUT, timeout = 0; - - if (bpmp_init_state == BPMP_INIT_COMPLETE) { - - /* loop until BPMP is free */ - for (timeout = 0; timeout < BPMP_TIMEOUT; timeout++) { - if (master_free(ch) == true) { - break; - } - - mdelay(1); - } - - if (timeout != BPMP_TIMEOUT) { - - /* generate the command struct */ - p->code = mrq; - p->flags = DO_ACK; - (void)memcpy((void *)p->data, ob_data, (size_t)ob_sz); - - /* signal command ready to the BPMP */ - signal_slave(ch); - mmio_write_32(TEGRA_PRI_ICTLR_BASE + CPU_IEP_FIR_SET, - (1U << INT_SHR_SEM_OUTBOX_FULL)); - - /* loop until the command is executed */ - for (timeout = 0; timeout < BPMP_TIMEOUT; timeout++) { - if (master_acked(ch) == true) { - break; - } - - mdelay(1); - } - - if (timeout != BPMP_TIMEOUT) { - - /* get the command response */ - (void)memcpy(ib_data, (const void *)p->data, - (size_t)ib_sz); - - /* return error code */ - ret = p->code; - - /* free this channel */ - free_master(ch); - } - } - - } else { - /* return error code */ - ret = -EINVAL; - } - - if (timeout == BPMP_TIMEOUT) { - ERROR("Timed out waiting for bpmp's response\n"); - } - - return ret; -} - -int tegra_bpmp_init(void) -{ - uint32_t val, base, timeout = BPMP_TIMEOUT; - unsigned int ch; - int ret = 0; - - if (bpmp_init_state == BPMP_INIT_PENDING) { - - /* check if the bpmp processor is alive. */ - do { - val = mmio_read_32(TEGRA_RES_SEMA_BASE + STA_OFFSET); - if (val != SIGN_OF_LIFE) { - mdelay(1); - timeout--; - } - - } while ((val != SIGN_OF_LIFE) && (timeout > 0U)); - - if (val == SIGN_OF_LIFE) { - - /* check if clock for the atomics block is enabled */ - val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_ENB_V); - if ((val & CAR_ENABLE_ATOMICS) == 0) { - ERROR("Clock to the atomics block is disabled\n"); - } - - /* check if the atomics block is out of reset */ - val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEV_CLR_V); - if ((val & CAR_ENABLE_ATOMICS) == CAR_ENABLE_ATOMICS) { - ERROR("Reset to the atomics block is asserted\n"); - } - - /* base address to get the result from Atomics */ - base = TEGRA_ATOMICS_BASE + RESULT0_REG_OFFSET; - - /* channel area is setup by BPMP before signaling handshake */ - for (ch = 0; ch < NR_CHANNELS; ch++) { - - /* issue command to get the channel base address */ - mmio_write_32(base, (ch << TRIGGER_ID_SHIFT) | - ATOMIC_CMD_GET); - - /* get the base address for the channel */ - channel_base[ch] = mmio_read_32(base); - - /* increment result register offset */ - base += 4U; - } - - /* mark state as "initialized" */ - bpmp_init_state = BPMP_INIT_COMPLETE; - - /* the channel values have to be visible across all cpus */ - flush_dcache_range((uint64_t)channel_base, - sizeof(channel_base)); - flush_dcache_range((uint64_t)&bpmp_init_state, - sizeof(bpmp_init_state)); - - INFO("%s: done\n", __func__); - - } else { - ERROR("BPMP not powered on\n"); - - /* bpmp is not present in the system */ - bpmp_init_state = BPMP_NOT_PRESENT; - - /* communication timed out */ - ret = -ETIMEDOUT; - } - } - - return ret; -} - -void tegra_bpmp_suspend(void) -{ - /* freeze the interface */ - if (bpmp_init_state == BPMP_INIT_COMPLETE) { - bpmp_init_state = BPMP_SUSPEND_ENTRY; - flush_dcache_range((uint64_t)&bpmp_init_state, - sizeof(bpmp_init_state)); - } -} - -void tegra_bpmp_resume(void) -{ - uint32_t val, timeout = 0; - - if (bpmp_init_state == BPMP_SUSPEND_ENTRY) { - - /* check if the bpmp processor is alive. */ - do { - - val = mmio_read_32(TEGRA_RES_SEMA_BASE + STA_OFFSET); - if (val != SIGN_OF_LIFE) { - mdelay(1); - timeout++; - } - - } while ((val != SIGN_OF_LIFE) && (timeout < BPMP_TIMEOUT)); - - if (val == SIGN_OF_LIFE) { - - INFO("%s: BPMP took %d ms to resume\n", __func__, timeout); - - /* mark state as "initialized" */ - bpmp_init_state = BPMP_INIT_COMPLETE; - - /* state has to be visible across all cpus */ - flush_dcache_range((uint64_t)&bpmp_init_state, - sizeof(bpmp_init_state)); - } else { - ERROR("BPMP not powered on\n"); - } - } -} diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c deleted file mode 100644 index 2e90d2547..000000000 --- a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c +++ /dev/null @@ -1,345 +0,0 @@ -/* - * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "intf.h" -#include "ivc.h" - -/** - * Holds IVC channel data - */ -struct ccplex_bpmp_channel_data { - /* Buffer for incoming data */ - struct frame_data *ib; - - /* Buffer for outgoing data */ - struct frame_data *ob; -}; - -static struct ccplex_bpmp_channel_data s_channel; -static struct ivc ivc_ccplex_bpmp_channel; - -/* - * Helper functions to access the HSP doorbell registers - */ -static inline uint32_t hsp_db_read(uint32_t reg) -{ - return mmio_read_32((uint32_t)(TEGRA_HSP_DBELL_BASE + reg)); -} - -static inline void hsp_db_write(uint32_t reg, uint32_t val) -{ - mmio_write_32((uint32_t)(TEGRA_HSP_DBELL_BASE + reg), val); -} - -/******************************************************************************* - * IVC wrappers for CCPLEX <-> BPMP communication. - ******************************************************************************/ - -static void tegra_bpmp_ring_bpmp_doorbell(void); - -/* - * Get the next frame where data can be written. - */ -static struct frame_data *tegra_bpmp_get_next_out_frame(void) -{ - struct frame_data *frame; - const struct ivc *ch = &ivc_ccplex_bpmp_channel; - - frame = (struct frame_data *)tegra_ivc_write_get_next_frame(ch); - if (frame == NULL) { - ERROR("%s: Error in getting next frame, exiting\n", __func__); - } else { - s_channel.ob = frame; - } - - return frame; -} - -static void tegra_bpmp_signal_slave(void) -{ - (void)tegra_ivc_write_advance(&ivc_ccplex_bpmp_channel); - tegra_bpmp_ring_bpmp_doorbell(); -} - -static int32_t tegra_bpmp_free_master(void) -{ - return tegra_ivc_read_advance(&ivc_ccplex_bpmp_channel); -} - -static bool tegra_bpmp_slave_acked(void) -{ - struct frame_data *frame; - bool ret = true; - - frame = (struct frame_data *)tegra_ivc_read_get_next_frame(&ivc_ccplex_bpmp_channel); - if (frame == NULL) { - ret = false; - } else { - s_channel.ib = frame; - } - - return ret; -} - -static struct frame_data *tegra_bpmp_get_cur_in_frame(void) -{ - return s_channel.ib; -} - -/* - * Enables BPMP to ring CCPlex doorbell - */ -static void tegra_bpmp_enable_ccplex_doorbell(void) -{ - uint32_t reg; - - reg = hsp_db_read(HSP_DBELL_1_ENABLE); - reg |= HSP_MASTER_BPMP_BIT; - hsp_db_write(HSP_DBELL_1_ENABLE, reg); -} - -/* - * CCPlex rings the BPMP doorbell - */ -static void tegra_bpmp_ring_bpmp_doorbell(void) -{ - /* - * Any writes to this register has the same effect, - * uses master ID of the write transaction and set - * corresponding flag. - */ - hsp_db_write(HSP_DBELL_3_TRIGGER, HSP_MASTER_CCPLEX_BIT); -} - -/* - * Returns true if CCPLex can ring BPMP doorbell, otherwise false. - * This also signals that BPMP is up and ready. - */ -static bool tegra_bpmp_can_ccplex_ring_doorbell(void) -{ - uint32_t reg; - - /* check if ccplex can communicate with bpmp */ - reg = hsp_db_read(HSP_DBELL_3_ENABLE); - - return ((reg & HSP_MASTER_CCPLEX_BIT) != 0U); -} - -static int32_t tegra_bpmp_wait_for_slave_ack(void) -{ - uint32_t timeout = TIMEOUT_RESPONSE_FROM_BPMP_US; - - while (!tegra_bpmp_slave_acked() && (timeout != 0U)) { - udelay(1); - timeout--; - }; - - return ((timeout == 0U) ? -ETIMEDOUT : 0); -} - -/* - * Notification from the ivc layer - */ -static void tegra_bpmp_ivc_notify(const struct ivc *ivc) -{ - (void)(ivc); - - tegra_bpmp_ring_bpmp_doorbell(); -} - -/* - * Atomic send/receive API, which means it waits until slave acks - */ -static int32_t tegra_bpmp_ipc_send_req_atomic(uint32_t mrq, void *p_out, - uint32_t size_out, void *p_in, uint32_t size_in) -{ - struct frame_data *frame = tegra_bpmp_get_next_out_frame(); - const struct frame_data *f_in = NULL; - int32_t ret = 0; - void *p_fdata; - - if ((p_out == NULL) || (size_out > IVC_DATA_SZ_BYTES) || - (frame == NULL)) { - ERROR("%s: invalid parameters, exiting\n", __func__); - return -EINVAL; - } - - /* prepare the command frame */ - frame->mrq = mrq; - frame->flags = FLAG_DO_ACK; - p_fdata = frame->data; - (void)memcpy(p_fdata, p_out, (size_t)size_out); - - /* signal the slave */ - tegra_bpmp_signal_slave(); - - /* wait for slave to ack */ - ret = tegra_bpmp_wait_for_slave_ack(); - if (ret < 0) { - ERROR("%s: wait for slave failed (%d)\n", __func__, ret); - return ret; - } - - /* retrieve the response frame */ - if ((size_in <= IVC_DATA_SZ_BYTES) && (p_in != NULL)) { - - f_in = tegra_bpmp_get_cur_in_frame(); - if (f_in != NULL) { - ERROR("Failed to get next input frame!\n"); - } else { - (void)memcpy(p_in, p_fdata, (size_t)size_in); - } - } - - ret = tegra_bpmp_free_master(); - if (ret < 0) { - ERROR("%s: free master failed (%d)\n", __func__, ret); - } - - return ret; -} - -/* - * Initializes the BPMP<--->CCPlex communication path. - */ -int32_t tegra_bpmp_ipc_init(void) -{ - size_t msg_size; - uint32_t frame_size, timeout; - int32_t error = 0; - - /* allow bpmp to ring CCPLEX's doorbell */ - tegra_bpmp_enable_ccplex_doorbell(); - - /* wait for BPMP to actually ring the doorbell */ - timeout = TIMEOUT_RESPONSE_FROM_BPMP_US; - while ((timeout != 0U) && !tegra_bpmp_can_ccplex_ring_doorbell()) { - udelay(1); /* bpmp turn-around time */ - timeout--; - } - - if (timeout == 0U) { - ERROR("%s: BPMP firmware is not ready\n", __func__); - return -ENOTSUP; - } - - INFO("%s: BPMP handshake completed\n", __func__); - - msg_size = tegra_ivc_align(IVC_CMD_SZ_BYTES); - frame_size = (uint32_t)tegra_ivc_total_queue_size(msg_size); - if (frame_size > TEGRA_BPMP_IPC_CH_MAP_SIZE) { - ERROR("%s: carveout size is not sufficient\n", __func__); - return -EINVAL; - } - - error = tegra_ivc_init(&ivc_ccplex_bpmp_channel, - (uint32_t)TEGRA_BPMP_IPC_RX_PHYS_BASE, - (uint32_t)TEGRA_BPMP_IPC_TX_PHYS_BASE, - 1U, frame_size, tegra_bpmp_ivc_notify); - if (error != 0) { - - ERROR("%s: IVC init failed (%d)\n", __func__, error); - - } else { - - /* reset channel */ - tegra_ivc_channel_reset(&ivc_ccplex_bpmp_channel); - - /* wait for notification from BPMP */ - while (tegra_ivc_channel_notified(&ivc_ccplex_bpmp_channel) != 0) { - /* - * Interrupt BPMP with doorbell each time after - * tegra_ivc_channel_notified() returns non zero - * value. - */ - tegra_bpmp_ring_bpmp_doorbell(); - } - - INFO("%s: All communication channels initialized\n", __func__); - } - - return error; -} - -/* Handler to reset a hardware module */ -int32_t tegra_bpmp_ipc_reset_module(uint32_t rst_id) -{ - int32_t ret; - struct mrq_reset_request req = { - .cmd = (uint32_t)CMD_RESET_MODULE, - .reset_id = rst_id - }; - - /* only GPCDMA/XUSB_PADCTL resets are supported */ - assert((rst_id == TEGRA_RESET_ID_XUSB_PADCTL) || - (rst_id == TEGRA_RESET_ID_GPCDMA)); - - ret = tegra_bpmp_ipc_send_req_atomic(MRQ_RESET, &req, - (uint32_t)sizeof(req), NULL, 0); - if (ret != 0) { - ERROR("%s: failed for module %d with error %d\n", __func__, - rst_id, ret); - } - - return ret; -} - -int tegra_bpmp_ipc_enable_clock(uint32_t clk_id) -{ - int ret; - struct mrq_clk_request req; - - /* only SE clocks are supported */ - if (clk_id != TEGRA_CLK_SE) { - return -ENOTSUP; - } - - /* prepare the MRQ_CLK command */ - req.cmd_and_id = make_mrq_clk_cmd(CMD_CLK_ENABLE, clk_id); - - ret = tegra_bpmp_ipc_send_req_atomic(MRQ_CLK, &req, (uint32_t)sizeof(req), - NULL, 0); - if (ret != 0) { - ERROR("%s: failed for module %d with error %d\n", __func__, - clk_id, ret); - } - - return ret; -} - -int tegra_bpmp_ipc_disable_clock(uint32_t clk_id) -{ - int ret; - struct mrq_clk_request req; - - /* only SE clocks are supported */ - if (clk_id != TEGRA_CLK_SE) { - return -ENOTSUP; - } - - /* prepare the MRQ_CLK command */ - req.cmd_and_id = make_mrq_clk_cmd(CMD_CLK_DISABLE, clk_id); - - ret = tegra_bpmp_ipc_send_req_atomic(MRQ_CLK, &req, (uint32_t)sizeof(req), - NULL, 0); - if (ret != 0) { - ERROR("%s: failed for module %d with error %d\n", __func__, - clk_id, ret); - } - - return ret; -} diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h deleted file mode 100644 index d85b906b8..000000000 --- a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef BPMP_INTF_H -#define BPMP_INTF_H - -/** - * Flags used in IPC req - */ -#define FLAG_DO_ACK (U(1) << 0) -#define FLAG_RING_DOORBELL (U(1) << 1) - -/* Bit 1 is designated for CCPlex in secure world */ -#define HSP_MASTER_CCPLEX_BIT (U(1) << 1) -/* Bit 19 is designated for BPMP in non-secure world */ -#define HSP_MASTER_BPMP_BIT (U(1) << 19) -/* Timeout to receive response from BPMP is 1 sec */ -#define TIMEOUT_RESPONSE_FROM_BPMP_US U(1000000) /* in microseconds */ - -/** - * IVC protocol defines and command/response frame - */ - -/** - * IVC specific defines - */ -#define IVC_CMD_SZ_BYTES U(128) -#define IVC_DATA_SZ_BYTES U(120) - -/** - * Holds frame data for an IPC request - */ -struct frame_data { - /* Identification as to what kind of data is being transmitted */ - uint32_t mrq; - - /* Flags for slave as to how to respond back */ - uint32_t flags; - - /* Actual data being sent */ - uint8_t data[IVC_DATA_SZ_BYTES]; -}; - -/** - * Commands send to the BPMP firmware - */ - -/** - * MRQ command codes - */ -#define MRQ_RESET U(20) -#define MRQ_CLK U(22) - -/** - * Reset sub-commands - */ -#define CMD_RESET_ASSERT U(1) -#define CMD_RESET_DEASSERT U(2) -#define CMD_RESET_MODULE U(3) - -/** - * Used by the sender of an #MRQ_RESET message to request BPMP to - * assert or deassert a given reset line. - */ -struct __attribute__((packed)) mrq_reset_request { - /* reset action to perform (mrq_reset_commands) */ - uint32_t cmd; - /* id of the reset to affected */ - uint32_t reset_id; -}; - -/** - * MRQ_CLK sub-commands - * - */ -enum { - CMD_CLK_GET_RATE = U(1), - CMD_CLK_SET_RATE = U(2), - CMD_CLK_ROUND_RATE = U(3), - CMD_CLK_GET_PARENT = U(4), - CMD_CLK_SET_PARENT = U(5), - CMD_CLK_IS_ENABLED = U(6), - CMD_CLK_ENABLE = U(7), - CMD_CLK_DISABLE = U(8), - CMD_CLK_GET_ALL_INFO = U(14), - CMD_CLK_GET_MAX_CLK_ID = U(15), - CMD_CLK_MAX, -}; - -/** - * Used by the sender of an #MRQ_CLK message to control clocks. The - * clk_request is split into several sub-commands. Some sub-commands - * require no additional data. Others have a sub-command specific - * payload - * - * |sub-command |payload | - * |----------------------------|-----------------------| - * |CMD_CLK_GET_RATE |- | - * |CMD_CLK_SET_RATE |clk_set_rate | - * |CMD_CLK_ROUND_RATE |clk_round_rate | - * |CMD_CLK_GET_PARENT |- | - * |CMD_CLK_SET_PARENT |clk_set_parent | - * |CMD_CLK_IS_ENABLED |- | - * |CMD_CLK_ENABLE |- | - * |CMD_CLK_DISABLE |- | - * |CMD_CLK_GET_ALL_INFO |- | - * |CMD_CLK_GET_MAX_CLK_ID |- | - * - */ -struct mrq_clk_request { - /** - * sub-command and clock id concatenated to 32-bit word. - * - bits[31..24] is the sub-cmd. - * - bits[23..0] is the clock id - */ - uint32_t cmd_and_id; -}; - -/** - * Macro to prepare the MRQ_CLK sub-command - */ -#define make_mrq_clk_cmd(cmd, id) (((cmd) << 24) | (id & 0xFFFFFF)) - -#endif /* BPMP_INTF_H */ diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.c b/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.c deleted file mode 100644 index d964fc001..000000000 --- a/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.c +++ /dev/null @@ -1,654 +0,0 @@ -/* - * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "ivc.h" - -/* - * IVC channel reset protocol. - * - * Each end uses its tx_channel.state to indicate its synchronization state. - */ -enum { - /* - * This value is zero for backwards compatibility with services that - * assume channels to be initially zeroed. Such channels are in an - * initially valid state, but cannot be asynchronously reset, and must - * maintain a valid state at all times. - * - * The transmitting end can enter the established state from the sync or - * ack state when it observes the receiving endpoint in the ack or - * established state, indicating that has cleared the counters in our - * rx_channel. - */ - ivc_state_established = U(0), - - /* - * If an endpoint is observed in the sync state, the remote endpoint is - * allowed to clear the counters it owns asynchronously with respect to - * the current endpoint. Therefore, the current endpoint is no longer - * allowed to communicate. - */ - ivc_state_sync = U(1), - - /* - * When the transmitting end observes the receiving end in the sync - * state, it can clear the w_count and r_count and transition to the ack - * state. If the remote endpoint observes us in the ack state, it can - * return to the established state once it has cleared its counters. - */ - ivc_state_ack = U(2) -}; - -/* - * This structure is divided into two-cache aligned parts, the first is only - * written through the tx_channel pointer, while the second is only written - * through the rx_channel pointer. This delineates ownership of the cache lines, - * which is critical to performance and necessary in non-cache coherent - * implementations. - */ -struct ivc_channel_header { - struct { - /* fields owned by the transmitting end */ - uint32_t w_count; - uint32_t state; - uint32_t w_rsvd[IVC_CHHDR_TX_FIELDS - 2]; - }; - struct { - /* fields owned by the receiving end */ - uint32_t r_count; - uint32_t r_rsvd[IVC_CHHDR_RX_FIELDS - 1]; - }; -}; - -static inline bool ivc_channel_empty(const struct ivc *ivc, - volatile const struct ivc_channel_header *ch) -{ - /* - * This function performs multiple checks on the same values with - * security implications, so sample the counters' current values in - * shared memory to ensure that these checks use the same values. - */ - uint32_t wr_count = ch->w_count; - uint32_t rd_count = ch->r_count; - bool ret = false; - - (void)ivc; - - /* - * Perform an over-full check to prevent denial of service attacks where - * a server could be easily fooled into believing that there's an - * extremely large number of frames ready, since receivers are not - * expected to check for full or over-full conditions. - * - * Although the channel isn't empty, this is an invalid case caused by - * a potentially malicious peer, so returning empty is safer, because it - * gives the impression that the channel has gone silent. - */ - if (((wr_count - rd_count) > ivc->nframes) || (wr_count == rd_count)) { - ret = true; - } - - return ret; -} - -static inline bool ivc_channel_full(const struct ivc *ivc, - volatile const struct ivc_channel_header *ch) -{ - uint32_t wr_count = ch->w_count; - uint32_t rd_count = ch->r_count; - - (void)ivc; - - /* - * Invalid cases where the counters indicate that the queue is over - * capacity also appear full. - */ - return ((wr_count - rd_count) >= ivc->nframes); -} - -static inline uint32_t ivc_channel_avail_count(const struct ivc *ivc, - volatile const struct ivc_channel_header *ch) -{ - uint32_t wr_count = ch->w_count; - uint32_t rd_count = ch->r_count; - - (void)ivc; - - /* - * This function isn't expected to be used in scenarios where an - * over-full situation can lead to denial of service attacks. See the - * comment in ivc_channel_empty() for an explanation about special - * over-full considerations. - */ - return (wr_count - rd_count); -} - -static inline void ivc_advance_tx(struct ivc *ivc) -{ - ivc->tx_channel->w_count++; - - if (ivc->w_pos == (ivc->nframes - (uint32_t)1U)) { - ivc->w_pos = 0U; - } else { - ivc->w_pos++; - } -} - -static inline void ivc_advance_rx(struct ivc *ivc) -{ - ivc->rx_channel->r_count++; - - if (ivc->r_pos == (ivc->nframes - (uint32_t)1U)) { - ivc->r_pos = 0U; - } else { - ivc->r_pos++; - } -} - -static inline int32_t ivc_check_read(const struct ivc *ivc) -{ - /* - * tx_channel->state is set locally, so it is not synchronized with - * state from the remote peer. The remote peer cannot reset its - * transmit counters until we've acknowledged its synchronization - * request, so no additional synchronization is required because an - * asynchronous transition of rx_channel->state to ivc_state_ack is not - * allowed. - */ - if (ivc->tx_channel->state != ivc_state_established) { - return -ECONNRESET; - } - - /* - * Avoid unnecessary invalidations when performing repeated accesses to - * an IVC channel by checking the old queue pointers first. - * Synchronization is only necessary when these pointers indicate empty - * or full. - */ - if (!ivc_channel_empty(ivc, ivc->rx_channel)) { - return 0; - } - - return ivc_channel_empty(ivc, ivc->rx_channel) ? -ENOMEM : 0; -} - -static inline int32_t ivc_check_write(const struct ivc *ivc) -{ - if (ivc->tx_channel->state != ivc_state_established) { - return -ECONNRESET; - } - - if (!ivc_channel_full(ivc, ivc->tx_channel)) { - return 0; - } - - return ivc_channel_full(ivc, ivc->tx_channel) ? -ENOMEM : 0; -} - -bool tegra_ivc_can_read(const struct ivc *ivc) -{ - return ivc_check_read(ivc) == 0; -} - -bool tegra_ivc_can_write(const struct ivc *ivc) -{ - return ivc_check_write(ivc) == 0; -} - -bool tegra_ivc_tx_empty(const struct ivc *ivc) -{ - return ivc_channel_empty(ivc, ivc->tx_channel); -} - -static inline uintptr_t calc_frame_offset(uint32_t frame_index, - uint32_t frame_size, uint32_t frame_offset) -{ - return ((uintptr_t)frame_index * (uintptr_t)frame_size) + - (uintptr_t)frame_offset; -} - -static void *ivc_frame_pointer(const struct ivc *ivc, - volatile const struct ivc_channel_header *ch, - uint32_t frame) -{ - assert(frame < ivc->nframes); - return (void *)((uintptr_t)(&ch[1]) + - calc_frame_offset(frame, ivc->frame_size, 0)); -} - -int32_t tegra_ivc_read(struct ivc *ivc, void *buf, size_t max_read) -{ - const void *src; - int32_t result; - - if (buf == NULL) { - return -EINVAL; - } - - if (max_read > ivc->frame_size) { - return -E2BIG; - } - - result = ivc_check_read(ivc); - if (result != 0) { - return result; - } - - /* - * Order observation of w_pos potentially indicating new data before - * data read. - */ - dmbish(); - - src = ivc_frame_pointer(ivc, ivc->rx_channel, ivc->r_pos); - - (void)memcpy(buf, src, max_read); - - ivc_advance_rx(ivc); - - /* - * Ensure our write to r_pos occurs before our read from w_pos. - */ - dmbish(); - - /* - * Notify only upon transition from full to non-full. - * The available count can only asynchronously increase, so the - * worst possible side-effect will be a spurious notification. - */ - if (ivc_channel_avail_count(ivc, ivc->rx_channel) == (ivc->nframes - (uint32_t)1U)) { - ivc->notify(ivc); - } - - return (int32_t)max_read; -} - -/* directly peek at the next frame rx'ed */ -void *tegra_ivc_read_get_next_frame(const struct ivc *ivc) -{ - if (ivc_check_read(ivc) != 0) { - return NULL; - } - - /* - * Order observation of w_pos potentially indicating new data before - * data read. - */ - dmbld(); - - return ivc_frame_pointer(ivc, ivc->rx_channel, ivc->r_pos); -} - -int32_t tegra_ivc_read_advance(struct ivc *ivc) -{ - /* - * No read barriers or synchronization here: the caller is expected to - * have already observed the channel non-empty. This check is just to - * catch programming errors. - */ - int32_t result = ivc_check_read(ivc); - if (result != 0) { - return result; - } - - ivc_advance_rx(ivc); - - /* - * Ensure our write to r_pos occurs before our read from w_pos. - */ - dmbish(); - - /* - * Notify only upon transition from full to non-full. - * The available count can only asynchronously increase, so the - * worst possible side-effect will be a spurious notification. - */ - if (ivc_channel_avail_count(ivc, ivc->rx_channel) == (ivc->nframes - (uint32_t)1U)) { - ivc->notify(ivc); - } - - return 0; -} - -int32_t tegra_ivc_write(struct ivc *ivc, const void *buf, size_t size) -{ - void *p; - int32_t result; - - if ((buf == NULL) || (ivc == NULL)) { - return -EINVAL; - } - - if (size > ivc->frame_size) { - return -E2BIG; - } - - result = ivc_check_write(ivc); - if (result != 0) { - return result; - } - - p = ivc_frame_pointer(ivc, ivc->tx_channel, ivc->w_pos); - - (void)memset(p, 0, ivc->frame_size); - (void)memcpy(p, buf, size); - - /* - * Ensure that updated data is visible before the w_pos counter - * indicates that it is ready. - */ - dmbst(); - - ivc_advance_tx(ivc); - - /* - * Ensure our write to w_pos occurs before our read from r_pos. - */ - dmbish(); - - /* - * Notify only upon transition from empty to non-empty. - * The available count can only asynchronously decrease, so the - * worst possible side-effect will be a spurious notification. - */ - if (ivc_channel_avail_count(ivc, ivc->tx_channel) == 1U) { - ivc->notify(ivc); - } - - return (int32_t)size; -} - -/* directly poke at the next frame to be tx'ed */ -void *tegra_ivc_write_get_next_frame(const struct ivc *ivc) -{ - if (ivc_check_write(ivc) != 0) { - return NULL; - } - - return ivc_frame_pointer(ivc, ivc->tx_channel, ivc->w_pos); -} - -/* advance the tx buffer */ -int32_t tegra_ivc_write_advance(struct ivc *ivc) -{ - int32_t result = ivc_check_write(ivc); - - if (result != 0) { - return result; - } - - /* - * Order any possible stores to the frame before update of w_pos. - */ - dmbst(); - - ivc_advance_tx(ivc); - - /* - * Ensure our write to w_pos occurs before our read from r_pos. - */ - dmbish(); - - /* - * Notify only upon transition from empty to non-empty. - * The available count can only asynchronously decrease, so the - * worst possible side-effect will be a spurious notification. - */ - if (ivc_channel_avail_count(ivc, ivc->tx_channel) == (uint32_t)1U) { - ivc->notify(ivc); - } - - return 0; -} - -void tegra_ivc_channel_reset(const struct ivc *ivc) -{ - ivc->tx_channel->state = ivc_state_sync; - ivc->notify(ivc); -} - -/* - * =============================================================== - * IVC State Transition Table - see tegra_ivc_channel_notified() - * =============================================================== - * - * local remote action - * ----- ------ ----------------------------------- - * SYNC EST - * SYNC ACK reset counters; move to EST; notify - * SYNC SYNC reset counters; move to ACK; notify - * ACK EST move to EST; notify - * ACK ACK move to EST; notify - * ACK SYNC reset counters; move to ACK; notify - * EST EST - * EST ACK - * EST SYNC reset counters; move to ACK; notify - * - * =============================================================== - */ -int32_t tegra_ivc_channel_notified(struct ivc *ivc) -{ - uint32_t peer_state; - - /* Copy the receiver's state out of shared memory. */ - peer_state = ivc->rx_channel->state; - - if (peer_state == (uint32_t)ivc_state_sync) { - /* - * Order observation of ivc_state_sync before stores clearing - * tx_channel. - */ - dmbld(); - - /* - * Reset tx_channel counters. The remote end is in the SYNC - * state and won't make progress until we change our state, - * so the counters are not in use at this time. - */ - ivc->tx_channel->w_count = 0U; - ivc->rx_channel->r_count = 0U; - - ivc->w_pos = 0U; - ivc->r_pos = 0U; - - /* - * Ensure that counters appear cleared before new state can be - * observed. - */ - dmbst(); - - /* - * Move to ACK state. We have just cleared our counters, so it - * is now safe for the remote end to start using these values. - */ - ivc->tx_channel->state = ivc_state_ack; - - /* - * Notify remote end to observe state transition. - */ - ivc->notify(ivc); - - } else if ((ivc->tx_channel->state == (uint32_t)ivc_state_sync) && - (peer_state == (uint32_t)ivc_state_ack)) { - /* - * Order observation of ivc_state_sync before stores clearing - * tx_channel. - */ - dmbld(); - - /* - * Reset tx_channel counters. The remote end is in the ACK - * state and won't make progress until we change our state, - * so the counters are not in use at this time. - */ - ivc->tx_channel->w_count = 0U; - ivc->rx_channel->r_count = 0U; - - ivc->w_pos = 0U; - ivc->r_pos = 0U; - - /* - * Ensure that counters appear cleared before new state can be - * observed. - */ - dmbst(); - - /* - * Move to ESTABLISHED state. We know that the remote end has - * already cleared its counters, so it is safe to start - * writing/reading on this channel. - */ - ivc->tx_channel->state = ivc_state_established; - - /* - * Notify remote end to observe state transition. - */ - ivc->notify(ivc); - - } else if (ivc->tx_channel->state == (uint32_t)ivc_state_ack) { - /* - * At this point, we have observed the peer to be in either - * the ACK or ESTABLISHED state. Next, order observation of - * peer state before storing to tx_channel. - */ - dmbld(); - - /* - * Move to ESTABLISHED state. We know that we have previously - * cleared our counters, and we know that the remote end has - * cleared its counters, so it is safe to start writing/reading - * on this channel. - */ - ivc->tx_channel->state = ivc_state_established; - - /* - * Notify remote end to observe state transition. - */ - ivc->notify(ivc); - - } else { - /* - * There is no need to handle any further action. Either the - * channel is already fully established, or we are waiting for - * the remote end to catch up with our current state. Refer - * to the diagram in "IVC State Transition Table" above. - */ - } - - return ((ivc->tx_channel->state == (uint32_t)ivc_state_established) ? 0 : -EAGAIN); -} - -size_t tegra_ivc_align(size_t size) -{ - return (size + (IVC_ALIGN - 1U)) & ~(IVC_ALIGN - 1U); -} - -size_t tegra_ivc_total_queue_size(size_t queue_size) -{ - if ((queue_size & (IVC_ALIGN - 1U)) != 0U) { - ERROR("queue_size (%d) must be %d-byte aligned\n", - (int32_t)queue_size, IVC_ALIGN); - return 0; - } - return queue_size + sizeof(struct ivc_channel_header); -} - -static int32_t check_ivc_params(uintptr_t queue_base1, uintptr_t queue_base2, - uint32_t nframes, uint32_t frame_size) -{ - assert((offsetof(struct ivc_channel_header, w_count) - & (IVC_ALIGN - 1U)) == 0U); - assert((offsetof(struct ivc_channel_header, r_count) - & (IVC_ALIGN - 1U)) == 0U); - assert((sizeof(struct ivc_channel_header) & (IVC_ALIGN - 1U)) == 0U); - - if (((uint64_t)nframes * (uint64_t)frame_size) >= 0x100000000ULL) { - ERROR("nframes * frame_size overflows\n"); - return -EINVAL; - } - - /* - * The headers must at least be aligned enough for counters - * to be accessed atomically. - */ - if ((queue_base1 & (IVC_ALIGN - 1U)) != 0U) { - ERROR("ivc channel start not aligned: %lx\n", queue_base1); - return -EINVAL; - } - if ((queue_base2 & (IVC_ALIGN - 1U)) != 0U) { - ERROR("ivc channel start not aligned: %lx\n", queue_base2); - return -EINVAL; - } - - if ((frame_size & (IVC_ALIGN - 1U)) != 0U) { - ERROR("frame size not adequately aligned: %u\n", - frame_size); - return -EINVAL; - } - - if (queue_base1 < queue_base2) { - if ((queue_base1 + ((uint64_t)frame_size * nframes)) > queue_base2) { - ERROR("queue regions overlap: %lx + %x, %x\n", - queue_base1, frame_size, - frame_size * nframes); - return -EINVAL; - } - } else { - if ((queue_base2 + ((uint64_t)frame_size * nframes)) > queue_base1) { - ERROR("queue regions overlap: %lx + %x, %x\n", - queue_base2, frame_size, - frame_size * nframes); - return -EINVAL; - } - } - - return 0; -} - -int32_t tegra_ivc_init(struct ivc *ivc, uintptr_t rx_base, uintptr_t tx_base, - uint32_t nframes, uint32_t frame_size, - ivc_notify_function notify) -{ - int32_t result; - - /* sanity check input params */ - if ((ivc == NULL) || (notify == NULL)) { - return -EINVAL; - } - - result = check_ivc_params(rx_base, tx_base, nframes, frame_size); - if (result != 0) { - return result; - } - - /* - * All sizes that can be returned by communication functions should - * fit in a 32-bit integer. - */ - if (frame_size > (1u << 31)) { - return -E2BIG; - } - - ivc->rx_channel = (struct ivc_channel_header *)rx_base; - ivc->tx_channel = (struct ivc_channel_header *)tx_base; - ivc->notify = notify; - ivc->frame_size = frame_size; - ivc->nframes = nframes; - ivc->w_pos = 0U; - ivc->r_pos = 0U; - - INFO("%s: done\n", __func__); - - return 0; -} diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h b/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h deleted file mode 100644 index 1b318213b..000000000 --- a/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2017-2020, NVIDIA Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef BPMP_IVC_H -#define BPMP_IVC_H - -#include -#include -#include - -#define IVC_ALIGN U(64) -#define IVC_CHHDR_TX_FIELDS U(16) -#define IVC_CHHDR_RX_FIELDS U(16) - -struct ivc_channel_header; - -struct ivc { - struct ivc_channel_header *rx_channel; - struct ivc_channel_header *tx_channel; - uint32_t w_pos; - uint32_t r_pos; - void (*notify)(const struct ivc *); - uint32_t nframes; - uint32_t frame_size; -}; - -/* callback handler for notify on receiving a response */ -typedef void (* ivc_notify_function)(const struct ivc *); - -int32_t tegra_ivc_init(struct ivc *ivc, uintptr_t rx_base, uintptr_t tx_base, - uint32_t nframes, uint32_t frame_size, - ivc_notify_function notify); -size_t tegra_ivc_total_queue_size(size_t queue_size); -size_t tegra_ivc_align(size_t size); -int32_t tegra_ivc_channel_notified(struct ivc *ivc); -void tegra_ivc_channel_reset(const struct ivc *ivc); -int32_t tegra_ivc_write_advance(struct ivc *ivc); -void *tegra_ivc_write_get_next_frame(const struct ivc *ivc); -int32_t tegra_ivc_write(struct ivc *ivc, const void *buf, size_t size); -int32_t tegra_ivc_read_advance(struct ivc *ivc); -void *tegra_ivc_read_get_next_frame(const struct ivc *ivc); -int32_t tegra_ivc_read(struct ivc *ivc, void *buf, size_t max_read); -bool tegra_ivc_tx_empty(const struct ivc *ivc); -bool tegra_ivc_can_write(const struct ivc *ivc); -bool tegra_ivc_can_read(const struct ivc *ivc); - -#endif /* BPMP_IVC_H */ diff --git a/plat/nvidia/tegra/common/drivers/flowctrl/flowctrl.c b/plat/nvidia/tegra/common/drivers/flowctrl/flowctrl.c deleted file mode 100644 index 8f5555459..000000000 --- a/plat/nvidia/tegra/common/drivers/flowctrl/flowctrl.c +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#define CLK_RST_DEV_L_SET 0x300 -#define CLK_RST_DEV_L_CLR 0x304 -#define CLK_BPMP_RST (1 << 1) - -#define EVP_BPMP_RESET_VECTOR 0x200 - -static const uint64_t flowctrl_offset_cpu_csr[4] = { - (TEGRA_FLOWCTRL_BASE + FLOWCTRL_CPU0_CSR), - (TEGRA_FLOWCTRL_BASE + FLOWCTRL_CPU1_CSR), - (TEGRA_FLOWCTRL_BASE + FLOWCTRL_CPU1_CSR + 8), - (TEGRA_FLOWCTRL_BASE + FLOWCTRL_CPU1_CSR + 16) -}; - -static const uint64_t flowctrl_offset_halt_cpu[4] = { - (TEGRA_FLOWCTRL_BASE + FLOWCTRL_HALT_CPU0_EVENTS), - (TEGRA_FLOWCTRL_BASE + FLOWCTRL_HALT_CPU1_EVENTS), - (TEGRA_FLOWCTRL_BASE + FLOWCTRL_HALT_CPU1_EVENTS + 8), - (TEGRA_FLOWCTRL_BASE + FLOWCTRL_HALT_CPU1_EVENTS + 16) -}; - -static const uint64_t flowctrl_offset_cc4_ctrl[4] = { - (TEGRA_FLOWCTRL_BASE + FLOWCTRL_CC4_CORE0_CTRL), - (TEGRA_FLOWCTRL_BASE + FLOWCTRL_CC4_CORE0_CTRL + 4), - (TEGRA_FLOWCTRL_BASE + FLOWCTRL_CC4_CORE0_CTRL + 8), - (TEGRA_FLOWCTRL_BASE + FLOWCTRL_CC4_CORE0_CTRL + 12) -}; - -static inline void tegra_fc_cc4_ctrl(int cpu_id, uint32_t val) -{ - mmio_write_32(flowctrl_offset_cc4_ctrl[cpu_id], val); - val = mmio_read_32(flowctrl_offset_cc4_ctrl[cpu_id]); -} - -static inline void tegra_fc_cpu_csr(int cpu_id, uint32_t val) -{ - mmio_write_32(flowctrl_offset_cpu_csr[cpu_id], val); - val = mmio_read_32(flowctrl_offset_cpu_csr[cpu_id]); -} - -static inline void tegra_fc_halt_cpu(int cpu_id, uint32_t val) -{ - mmio_write_32(flowctrl_offset_halt_cpu[cpu_id], val); - val = mmio_read_32(flowctrl_offset_halt_cpu[cpu_id]); -} - -static void tegra_fc_prepare_suspend(int cpu_id, uint32_t csr) -{ - uint32_t val; - - val = FLOWCTRL_HALT_GIC_IRQ | FLOWCTRL_HALT_GIC_FIQ | - FLOWCTRL_HALT_LIC_IRQ | FLOWCTRL_HALT_LIC_FIQ | - FLOWCTRL_WAITEVENT; - tegra_fc_halt_cpu(cpu_id, val); - - val = FLOWCTRL_CSR_INTR_FLAG | FLOWCTRL_CSR_EVENT_FLAG | - FLOWCTRL_CSR_ENABLE | (FLOWCTRL_WAIT_WFI_BITMAP << cpu_id); - tegra_fc_cpu_csr(cpu_id, val | csr); -} - -/******************************************************************************* - * After this, no core can wake from C7 until the action is reverted. - * If a wake up event is asserted, the FC state machine will stall until - * the action is reverted. - ******************************************************************************/ -void tegra_fc_ccplex_pgexit_lock(void) -{ - unsigned int i, cpu = read_mpidr() & MPIDR_CPU_MASK; - uint32_t flags = tegra_fc_read_32(FLOWCTRL_FC_SEQ_INTERCEPT) & ~INTERCEPT_IRQ_PENDING;; - uint32_t icept_cpu_flags[] = { - INTERCEPT_EXIT_PG_CORE0, - INTERCEPT_EXIT_PG_CORE1, - INTERCEPT_EXIT_PG_CORE2, - INTERCEPT_EXIT_PG_CORE3 - }; - - /* set the intercept flags */ - for (i = 0; i < ARRAY_SIZE(icept_cpu_flags); i++) { - - /* skip current CPU */ - if (i == cpu) - continue; - - /* enable power gate exit intercept locks */ - flags |= icept_cpu_flags[i]; - } - - tegra_fc_write_32(FLOWCTRL_FC_SEQ_INTERCEPT, flags); - (void)tegra_fc_read_32(FLOWCTRL_FC_SEQ_INTERCEPT); -} - -/******************************************************************************* - * Revert the ccplex powergate exit locks - ******************************************************************************/ -void tegra_fc_ccplex_pgexit_unlock(void) -{ - /* clear lock bits, clear pending interrupts */ - tegra_fc_write_32(FLOWCTRL_FC_SEQ_INTERCEPT, INTERCEPT_IRQ_PENDING); - (void)tegra_fc_read_32(FLOWCTRL_FC_SEQ_INTERCEPT); -} - -/******************************************************************************* - * Powerdn the current CPU - ******************************************************************************/ -void tegra_fc_cpu_powerdn(uint32_t mpidr) -{ - int cpu = mpidr & MPIDR_CPU_MASK; - - VERBOSE("CPU%d powering down...\n", cpu); - tegra_fc_prepare_suspend(cpu, 0); -} - -/******************************************************************************* - * Suspend the current CPU cluster - ******************************************************************************/ -void tegra_fc_cluster_idle(uint32_t mpidr) -{ - int cpu = mpidr & MPIDR_CPU_MASK; - uint32_t val; - - VERBOSE("Entering cluster idle state...\n"); - - tegra_fc_cc4_ctrl(cpu, 0); - - /* hardware L2 flush is faster for A53 only */ - tegra_fc_write_32(FLOWCTRL_L2_FLUSH_CONTROL, - !!MPIDR_AFFLVL1_VAL(mpidr)); - - /* suspend the CPU cluster */ - val = FLOWCTRL_PG_CPU_NONCPU << FLOWCTRL_ENABLE_EXT; - tegra_fc_prepare_suspend(cpu, val); -} - -/******************************************************************************* - * Power down the current CPU cluster - ******************************************************************************/ -void tegra_fc_cluster_powerdn(uint32_t mpidr) -{ - int cpu = mpidr & MPIDR_CPU_MASK; - uint32_t val; - - VERBOSE("Entering cluster powerdn state...\n"); - - tegra_fc_cc4_ctrl(cpu, 0); - - /* hardware L2 flush is faster for A53 only */ - tegra_fc_write_32(FLOWCTRL_L2_FLUSH_CONTROL, - read_midr() == CORTEX_A53_MIDR); - - /* power down the CPU cluster */ - val = FLOWCTRL_TURNOFF_CPURAIL << FLOWCTRL_ENABLE_EXT; - tegra_fc_prepare_suspend(cpu, val); -} - -/******************************************************************************* - * Check if cluster idle or power down state is allowed from this CPU - ******************************************************************************/ -bool tegra_fc_is_ccx_allowed(void) -{ - unsigned int i, cpu = read_mpidr() & MPIDR_CPU_MASK; - uint32_t val; - bool ccx_allowed = true; - - for (i = 0; i < ARRAY_SIZE(flowctrl_offset_cpu_csr); i++) { - - /* skip current CPU */ - if (i == cpu) - continue; - - /* check if all other CPUs are already halted */ - val = mmio_read_32(flowctrl_offset_cpu_csr[i]); - if ((val & FLOWCTRL_CSR_HALT_MASK) == 0U) { - ccx_allowed = false; - } - } - - return ccx_allowed; -} - -/******************************************************************************* - * Suspend the entire SoC - ******************************************************************************/ -void tegra_fc_soc_powerdn(uint32_t mpidr) -{ - int cpu = mpidr & MPIDR_CPU_MASK; - uint32_t val; - - VERBOSE("Entering SoC powerdn state...\n"); - - tegra_fc_cc4_ctrl(cpu, 0); - - tegra_fc_write_32(FLOWCTRL_L2_FLUSH_CONTROL, 1); - - val = FLOWCTRL_TURNOFF_CPURAIL << FLOWCTRL_ENABLE_EXT; - tegra_fc_prepare_suspend(cpu, val); - - /* overwrite HALT register */ - tegra_fc_halt_cpu(cpu, FLOWCTRL_WAITEVENT); -} - -/******************************************************************************* - * Power up the CPU - ******************************************************************************/ -void tegra_fc_cpu_on(int cpu) -{ - tegra_fc_cpu_csr(cpu, FLOWCTRL_CSR_ENABLE); - tegra_fc_halt_cpu(cpu, FLOWCTRL_WAITEVENT | FLOWCTRL_HALT_SCLK); -} - -/******************************************************************************* - * Power down the CPU - ******************************************************************************/ -void tegra_fc_cpu_off(int cpu) -{ - uint32_t val; - - /* - * Flow controller powers down the CPU during wfi. The CPU would be - * powered on when it receives any interrupt. - */ - val = FLOWCTRL_CSR_INTR_FLAG | FLOWCTRL_CSR_EVENT_FLAG | - FLOWCTRL_CSR_ENABLE | (FLOWCTRL_WAIT_WFI_BITMAP << cpu); - tegra_fc_cpu_csr(cpu, val); - tegra_fc_halt_cpu(cpu, FLOWCTRL_WAITEVENT); - tegra_fc_cc4_ctrl(cpu, 0); -} - -/******************************************************************************* - * Inform the BPMP that we have completed the cluster power up - ******************************************************************************/ -void tegra_fc_lock_active_cluster(void) -{ - uint32_t val; - - val = tegra_fc_read_32(FLOWCTRL_BPMP_CLUSTER_CONTROL); - val |= FLOWCTRL_BPMP_CLUSTER_PWRON_LOCK; - tegra_fc_write_32(FLOWCTRL_BPMP_CLUSTER_CONTROL, val); - val = tegra_fc_read_32(FLOWCTRL_BPMP_CLUSTER_CONTROL); -} - -/******************************************************************************* - * Power ON BPMP processor - ******************************************************************************/ -void tegra_fc_bpmp_on(uint32_t entrypoint) -{ - /* halt BPMP */ - tegra_fc_write_32(FLOWCTRL_HALT_BPMP_EVENTS, FLOWCTRL_WAITEVENT); - - /* Assert BPMP reset */ - mmio_write_32(TEGRA_CAR_RESET_BASE + CLK_RST_DEV_L_SET, CLK_BPMP_RST); - - /* Set reset address (stored in PMC_SCRATCH39) */ - mmio_write_32(TEGRA_EVP_BASE + EVP_BPMP_RESET_VECTOR, entrypoint); - while (entrypoint != mmio_read_32(TEGRA_EVP_BASE + EVP_BPMP_RESET_VECTOR)) - ; /* wait till value reaches EVP_BPMP_RESET_VECTOR */ - - /* Wait for 2us before de-asserting the reset signal. */ - udelay(2); - - /* De-assert BPMP reset */ - mmio_write_32(TEGRA_CAR_RESET_BASE + CLK_RST_DEV_L_CLR, CLK_BPMP_RST); - - /* Un-halt BPMP */ - tegra_fc_write_32(FLOWCTRL_HALT_BPMP_EVENTS, 0); -} - -/******************************************************************************* - * Power OFF BPMP processor - ******************************************************************************/ -void tegra_fc_bpmp_off(void) -{ - /* halt BPMP */ - tegra_fc_write_32(FLOWCTRL_HALT_BPMP_EVENTS, FLOWCTRL_WAITEVENT); - - /* Assert BPMP reset */ - mmio_write_32(TEGRA_CAR_RESET_BASE + CLK_RST_DEV_L_SET, CLK_BPMP_RST); - - /* Clear reset address */ - mmio_write_32(TEGRA_EVP_BASE + EVP_BPMP_RESET_VECTOR, 0); - while (0 != mmio_read_32(TEGRA_EVP_BASE + EVP_BPMP_RESET_VECTOR)) - ; /* wait till value reaches EVP_BPMP_RESET_VECTOR */ -} - -/******************************************************************************* - * Route legacy FIQ to the GICD - ******************************************************************************/ -void tegra_fc_enable_fiq_to_ccplex_routing(void) -{ - uint32_t val = tegra_fc_read_32(FLOW_CTLR_FLOW_DBG_QUAL); - - /* set the bit to pass FIQs to the GICD */ - tegra_fc_write_32(FLOW_CTLR_FLOW_DBG_QUAL, val | FLOWCTRL_FIQ2CCPLEX_ENABLE); -} - -/******************************************************************************* - * Disable routing legacy FIQ to the GICD - ******************************************************************************/ -void tegra_fc_disable_fiq_to_ccplex_routing(void) -{ - uint32_t val = tegra_fc_read_32(FLOW_CTLR_FLOW_DBG_QUAL); - - /* clear the bit to pass FIQs to the GICD */ - tegra_fc_write_32(FLOW_CTLR_FLOW_DBG_QUAL, val & ~FLOWCTRL_FIQ2CCPLEX_ENABLE); -} diff --git a/plat/nvidia/tegra/common/drivers/gpcdma/gpcdma.c b/plat/nvidia/tegra/common/drivers/gpcdma/gpcdma.c deleted file mode 100644 index d68cdfd4b..000000000 --- a/plat/nvidia/tegra/common/drivers/gpcdma/gpcdma.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* DMA channel registers */ -#define DMA_CH_CSR U(0x0) -#define DMA_CH_CSR_WEIGHT_SHIFT U(10) -#define DMA_CH_CSR_XFER_MODE_SHIFT U(21) -#define DMA_CH_CSR_DMA_MODE_MEM2MEM U(4) -#define DMA_CH_CSR_DMA_MODE_FIXEDPATTERN U(6) -#define DMA_CH_CSR_IRQ_MASK_ENABLE (U(1) << 15) -#define DMA_CH_CSR_RUN_ONCE (U(1) << 27) -#define DMA_CH_CSR_ENABLE (U(1) << 31) - -#define DMA_CH_STAT U(0x4) -#define DMA_CH_STAT_BUSY (U(1) << 31) - -#define DMA_CH_SRC_PTR U(0xC) - -#define DMA_CH_DST_PTR U(0x10) - -#define DMA_CH_HI_ADR_PTR U(0x14) -#define DMA_CH_HI_ADR_PTR_SRC_MASK U(0xFF) -#define DMA_CH_HI_ADR_PTR_DST_SHIFT U(16) -#define DMA_CH_HI_ADR_PTR_DST_MASK U(0xFF) - -#define DMA_CH_MC_SEQ U(0x18) -#define DMA_CH_MC_SEQ_REQ_CNT_SHIFT U(25) -#define DMA_CH_MC_SEQ_REQ_CNT_VAL U(0x10) -#define DMA_CH_MC_SEQ_BURST_SHIFT U(23) -#define DMA_CH_MC_SEQ_BURST_16_WORDS U(0x3) - -#define DMA_CH_WORD_COUNT U(0x20) -#define DMA_CH_FIXED_PATTERN U(0x34) -#define DMA_CH_TZ U(0x38) -#define DMA_CH_TZ_ACCESS_ENABLE U(0) -#define DMA_CH_TZ_ACCESS_DISABLE U(3) - -#define MAX_TRANSFER_SIZE (1U*1024U*1024U*1024U) /* 1GB */ -#define GPCDMA_TIMEOUT_MS U(100) -#define GPCDMA_RESET_BIT (U(1) << 1) - -static bool init_done; - -static void tegra_gpcdma_write32(uint32_t offset, uint32_t val) -{ - mmio_write_32(TEGRA_GPCDMA_BASE + offset, val); -} - -static uint32_t tegra_gpcdma_read32(uint32_t offset) -{ - return mmio_read_32(TEGRA_GPCDMA_BASE + offset); -} - -static void tegra_gpcdma_init(void) -{ - /* assert reset for DMA engine */ - mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_GPCDMA_RST_SET_REG_OFFSET, - GPCDMA_RESET_BIT); - - udelay(2); - - /* de-assert reset for DMA engine */ - mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_GPCDMA_RST_CLR_REG_OFFSET, - GPCDMA_RESET_BIT); -} - -static void tegra_gpcdma_memcpy_priv(uint64_t dst_addr, uint64_t src_addr, - uint32_t num_bytes, uint32_t mode) -{ - uint32_t val, timeout = 0; - int32_t ret = 0; - - /* sanity check byte count */ - if ((num_bytes > MAX_TRANSFER_SIZE) || ((num_bytes & 0x3U) != U(0))) { - ret = -EINVAL; - } - - /* initialise GPCDMA block */ - if (!init_done) { - tegra_gpcdma_init(); - init_done = true; - } - - /* make sure channel isn't busy */ - val = tegra_gpcdma_read32(DMA_CH_STAT); - if ((val & DMA_CH_STAT_BUSY) == DMA_CH_STAT_BUSY) { - ERROR("DMA channel is busy\n"); - ret = -EBUSY; - } - - if (ret == 0) { - - /* disable any DMA transfers */ - tegra_gpcdma_write32(DMA_CH_CSR, 0); - - /* enable DMA access to TZDRAM */ - tegra_gpcdma_write32(DMA_CH_TZ, DMA_CH_TZ_ACCESS_ENABLE); - - /* configure MC sequencer */ - val = (DMA_CH_MC_SEQ_REQ_CNT_VAL << DMA_CH_MC_SEQ_REQ_CNT_SHIFT) | - (DMA_CH_MC_SEQ_BURST_16_WORDS << DMA_CH_MC_SEQ_BURST_SHIFT); - tegra_gpcdma_write32(DMA_CH_MC_SEQ, val); - - /* reset fixed pattern */ - tegra_gpcdma_write32(DMA_CH_FIXED_PATTERN, 0); - - /* populate src and dst address registers */ - tegra_gpcdma_write32(DMA_CH_SRC_PTR, (uint32_t)src_addr); - tegra_gpcdma_write32(DMA_CH_DST_PTR, (uint32_t)dst_addr); - - val = (uint32_t)((src_addr >> 32) & DMA_CH_HI_ADR_PTR_SRC_MASK); - val |= (uint32_t)(((dst_addr >> 32) & DMA_CH_HI_ADR_PTR_DST_MASK) << - DMA_CH_HI_ADR_PTR_DST_SHIFT); - tegra_gpcdma_write32(DMA_CH_HI_ADR_PTR, val); - - /* transfer size (in words) */ - tegra_gpcdma_write32(DMA_CH_WORD_COUNT, ((num_bytes >> 2) - 1U)); - - /* populate value for CSR */ - val = (mode << DMA_CH_CSR_XFER_MODE_SHIFT) | - DMA_CH_CSR_RUN_ONCE | (U(1) << DMA_CH_CSR_WEIGHT_SHIFT) | - DMA_CH_CSR_IRQ_MASK_ENABLE; - tegra_gpcdma_write32(DMA_CH_CSR, val); - - /* enable transfer */ - val = tegra_gpcdma_read32(DMA_CH_CSR); - val |= DMA_CH_CSR_ENABLE; - tegra_gpcdma_write32(DMA_CH_CSR, val); - - /* wait till transfer completes */ - do { - - /* read the status */ - val = tegra_gpcdma_read32(DMA_CH_STAT); - if ((val & DMA_CH_STAT_BUSY) != DMA_CH_STAT_BUSY) { - break; - } - - mdelay(1); - timeout++; - - } while (timeout < GPCDMA_TIMEOUT_MS); - - /* flag timeout error */ - if (timeout == GPCDMA_TIMEOUT_MS) { - ERROR("DMA transfer timed out\n"); - } - - dsbsy(); - - /* disable DMA access to TZDRAM */ - tegra_gpcdma_write32(DMA_CH_TZ, DMA_CH_TZ_ACCESS_DISABLE); - isb(); - } -} - -/******************************************************************************* - * Memcpy using GPCDMA block (Mem2Mem copy) - ******************************************************************************/ -void tegra_gpcdma_memcpy(uint64_t dst_addr, uint64_t src_addr, - uint32_t num_bytes) -{ - tegra_gpcdma_memcpy_priv(dst_addr, src_addr, num_bytes, - DMA_CH_CSR_DMA_MODE_MEM2MEM); -} - -/******************************************************************************* - * Memset using GPCDMA block (Fixed pattern write) - ******************************************************************************/ -void tegra_gpcdma_zeromem(uint64_t dst_addr, uint32_t num_bytes) -{ - tegra_gpcdma_memcpy_priv(dst_addr, 0, num_bytes, - DMA_CH_CSR_DMA_MODE_FIXEDPATTERN); -} diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c deleted file mode 100644 index c3f95db4d..000000000 --- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -/* Video Memory base and size (live values) */ -static uint64_t video_mem_base; -static uint64_t video_mem_size; - -/* - * Init SMMU. - */ -void tegra_memctrl_setup(void) -{ - /* - * Setup the Memory controller to allow only secure accesses to - * the TZDRAM carveout - */ - INFO("Tegra Memory Controller (v1)\n"); - - /* allow translations for all MC engines */ - tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_0_0, - (unsigned int)MC_SMMU_TRANSLATION_ENABLE); - tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_1_0, - (unsigned int)MC_SMMU_TRANSLATION_ENABLE); - tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_2_0, - (unsigned int)MC_SMMU_TRANSLATION_ENABLE); - tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_3_0, - (unsigned int)MC_SMMU_TRANSLATION_ENABLE); - tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_4_0, - (unsigned int)MC_SMMU_TRANSLATION_ENABLE); - - tegra_mc_write_32(MC_SMMU_ASID_SECURITY_0, MC_SMMU_ASID_SECURITY); - - tegra_mc_write_32(MC_SMMU_TLB_CONFIG_0, MC_SMMU_TLB_CONFIG_0_RESET_VAL); - tegra_mc_write_32(MC_SMMU_PTC_CONFIG_0, MC_SMMU_PTC_CONFIG_0_RESET_VAL); - - /* flush PTC and TLB */ - tegra_mc_write_32(MC_SMMU_PTC_FLUSH_0, MC_SMMU_PTC_FLUSH_ALL); - (void)tegra_mc_read_32(MC_SMMU_CONFIG_0); /* read to flush writes */ - tegra_mc_write_32(MC_SMMU_TLB_FLUSH_0, MC_SMMU_TLB_FLUSH_ALL); - - /* enable SMMU */ - tegra_mc_write_32(MC_SMMU_CONFIG_0, - MC_SMMU_CONFIG_0_SMMU_ENABLE_ENABLE); - (void)tegra_mc_read_32(MC_SMMU_CONFIG_0); /* read to flush writes */ - - /* video memory carveout */ - tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI, - (uint32_t)(video_mem_base >> 32)); - tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO, (uint32_t)video_mem_base); - tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, video_mem_size); -} - -/* - * Restore Memory Controller settings after "System Suspend" - */ -void tegra_memctrl_restore_settings(void) -{ - tegra_memctrl_setup(); -} - -/* - * Secure the BL31 DRAM aperture. - * - * phys_base = physical base of TZDRAM aperture - * size_in_bytes = size of aperture in bytes - */ -void tegra_memctrl_tzdram_setup(uint64_t phys_base, uint32_t size_in_bytes) -{ - /* - * Setup the Memory controller to allow only secure accesses to - * the TZDRAM carveout - */ - INFO("Configuring TrustZone DRAM Memory Carveout\n"); - - tegra_mc_write_32(MC_SECURITY_CFG0_0, phys_base); - tegra_mc_write_32(MC_SECURITY_CFG1_0, size_in_bytes >> 20); -} - -/* - * Secure the BL31 TZRAM aperture. - * - * phys_base = physical base of TZRAM aperture - * size_in_bytes = size of aperture in bytes - */ -void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes) -{ - /* - * The v1 hardware controller does not have any registers - * for setting up the on-chip TZRAM. - */ -} - -static void tegra_clear_videomem(uintptr_t non_overlap_area_start, - unsigned long long non_overlap_area_size) -{ - int ret; - - /* - * Map the NS memory first, clean it and then unmap it. - */ - ret = mmap_add_dynamic_region(non_overlap_area_start, /* PA */ - non_overlap_area_start, /* VA */ - non_overlap_area_size, /* size */ - MT_NS | MT_RW | MT_EXECUTE_NEVER | - MT_NON_CACHEABLE); /* attrs */ - assert(ret == 0); - - zeromem((void *)non_overlap_area_start, non_overlap_area_size); - flush_dcache_range(non_overlap_area_start, non_overlap_area_size); - - mmap_remove_dynamic_region(non_overlap_area_start, - non_overlap_area_size); -} - -/* - * Program the Video Memory carveout region - * - * phys_base = physical base of aperture - * size_in_bytes = size of aperture in bytes - */ -void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes) -{ - uintptr_t vmem_end_old = video_mem_base + (video_mem_size << 20); - uintptr_t vmem_end_new = phys_base + size_in_bytes; - unsigned long long non_overlap_area_size; - - /* - * Setup the Memory controller to restrict CPU accesses to the Video - * Memory region - */ - INFO("Configuring Video Memory Carveout\n"); - - /* - * Configure Memory Controller directly for the first time. - */ - if (video_mem_base == 0) - goto done; - - /* - * Clear the old regions now being exposed. The following cases - * can occur - - * - * 1. clear whole old region (no overlap with new region) - * 2. clear old sub-region below new base - * 3. clear old sub-region above new end - */ - INFO("Cleaning previous Video Memory Carveout\n"); - - if (phys_base > vmem_end_old || video_mem_base > vmem_end_new) { - tegra_clear_videomem(video_mem_base, video_mem_size << 20); - } else { - if (video_mem_base < phys_base) { - non_overlap_area_size = phys_base - video_mem_base; - tegra_clear_videomem(video_mem_base, non_overlap_area_size); - } - if (vmem_end_old > vmem_end_new) { - non_overlap_area_size = vmem_end_old - vmem_end_new; - tegra_clear_videomem(vmem_end_new, non_overlap_area_size); - } - } - -done: - tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI, (uint32_t)(phys_base >> 32)); - tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO, (uint32_t)phys_base); - tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, size_in_bytes >> 20); - - /* store new values */ - video_mem_base = phys_base; - video_mem_size = size_in_bytes >> 20; -} - -/* - * During boot, USB3 and flash media (SDMMC/SATA) devices need access to - * IRAM. Because these clients connect to the MC and do not have a direct - * path to the IRAM, the MC implements AHB redirection during boot to allow - * path to IRAM. In this mode, accesses to a programmed memory address aperture - * are directed to the AHB bus, allowing access to the IRAM. The AHB aperture - * is defined by the IRAM_BASE_LO and IRAM_BASE_HI registers, which are - * initialized to disable this aperture. - * - * Once bootup is complete, we must program IRAM base to 0xffffffff and - * IRAM top to 0x00000000, thus disabling access to IRAM. DRAM is then - * potentially accessible in this address range. These aperture registers - * also have an access_control/lock bit. After disabling the aperture, the - * access_control register should be programmed to lock the registers. - */ -void tegra_memctrl_disable_ahb_redirection(void) -{ - /* program the aperture registers */ - tegra_mc_write_32(MC_IRAM_BASE_LO, 0xFFFFFFFF); - tegra_mc_write_32(MC_IRAM_TOP_LO, 0); - tegra_mc_write_32(MC_IRAM_BASE_TOP_HI, 0); - - /* lock the aperture registers */ - tegra_mc_write_32(MC_IRAM_REG_CTRL, MC_DISABLE_IRAM_CFG_WRITES); -} - -void tegra_memctrl_clear_pending_interrupts(void) -{ - uint32_t mcerr; - - /* check if there are any pending interrupts */ - mcerr = mmio_read_32(TEGRA_MC_BASE + MC_INTSTATUS); - - if (mcerr != (uint32_t)0U) { /* should not see error here */ - WARN("MC_INTSTATUS = 0x%x (should be zero)\n", mcerr); - mmio_write_32((TEGRA_MC_BASE + MC_INTSTATUS), mcerr); - } -} diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c deleted file mode 100644 index 4d69ccca3..000000000 --- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c +++ /dev/null @@ -1,392 +0,0 @@ -/* - * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. - * Copyright (c) 2019-2020, NVIDIA Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -/* Video Memory base and size (live values) */ -static uint64_t video_mem_base; -static uint64_t video_mem_size_mb; - -/* - * Init Memory controller during boot. - */ -void tegra_memctrl_setup(void) -{ - uint32_t val; - const uint32_t *mc_streamid_override_regs; - uint32_t num_streamid_override_regs; - const mc_streamid_security_cfg_t *mc_streamid_sec_cfgs; - uint32_t num_streamid_sec_cfgs; - const tegra_mc_settings_t *plat_mc_settings = tegra_get_mc_settings(); - uint32_t i; - - INFO("Tegra Memory Controller (v2)\n"); - - /* Program the SMMU pagesize */ - tegra_smmu_init(); - - /* Get the settings from the platform */ - assert(plat_mc_settings != NULL); - mc_streamid_override_regs = plat_mc_settings->streamid_override_cfg; - num_streamid_override_regs = plat_mc_settings->num_streamid_override_cfgs; - mc_streamid_sec_cfgs = plat_mc_settings->streamid_security_cfg; - num_streamid_sec_cfgs = plat_mc_settings->num_streamid_security_cfgs; - - /* Program all the Stream ID overrides */ - for (i = 0; i < num_streamid_override_regs; i++) - tegra_mc_streamid_write_32(mc_streamid_override_regs[i], - MC_STREAM_ID_MAX); - - /* Program the security config settings for all Stream IDs */ - for (i = 0; i < num_streamid_sec_cfgs; i++) { - val = mc_streamid_sec_cfgs[i].override_enable << 16 | - mc_streamid_sec_cfgs[i].override_client_inputs << 8 | - mc_streamid_sec_cfgs[i].override_client_ns_flag << 0; - tegra_mc_streamid_write_32(mc_streamid_sec_cfgs[i].offset, val); - } - - /* - * All requests at boot time, and certain requests during - * normal run time, are physically addressed and must bypass - * the SMMU. The client hub logic implements a hardware bypass - * path around the Translation Buffer Units (TBU). During - * boot-time, the SMMU_BYPASS_CTRL register (which defaults to - * TBU_BYPASS mode) will be used to steer all requests around - * the uninitialized TBUs. During normal operation, this register - * is locked into TBU_BYPASS_SID config, which routes requests - * with special StreamID 0x7f on the bypass path and all others - * through the selected TBU. This is done to disable SMMU Bypass - * mode, as it could be used to circumvent SMMU security checks. - */ - tegra_mc_write_32(MC_SMMU_BYPASS_CONFIG, - MC_SMMU_BYPASS_CONFIG_SETTINGS); - - /* - * Re-configure MSS to allow ROC to deal with ordering of the - * Memory Controller traffic. This is needed as the Memory Controller - * boots with MSS having all control, but ROC provides a performance - * boost as compared to MSS. - */ - if (plat_mc_settings->reconfig_mss_clients != NULL) { - plat_mc_settings->reconfig_mss_clients(); - } - - /* Program overrides for MC transactions */ - if (plat_mc_settings->set_txn_overrides != NULL) { - plat_mc_settings->set_txn_overrides(); - } -} - -/* - * Restore Memory Controller settings after "System Suspend" - */ -void tegra_memctrl_restore_settings(void) -{ - const tegra_mc_settings_t *plat_mc_settings = tegra_get_mc_settings(); - - assert(plat_mc_settings != NULL); - - /* - * Re-configure MSS to allow ROC to deal with ordering of the - * Memory Controller traffic. This is needed as the Memory Controller - * resets during System Suspend with MSS having all control, but ROC - * provides a performance boost as compared to MSS. - */ - if (plat_mc_settings->reconfig_mss_clients != NULL) { - plat_mc_settings->reconfig_mss_clients(); - } - - /* Program overrides for MC transactions */ - if (plat_mc_settings->set_txn_overrides != NULL) { - plat_mc_settings->set_txn_overrides(); - } - - /* video memory carveout region */ - if (video_mem_base != 0ULL) { - tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO, - (uint32_t)video_mem_base); - tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI, - (uint32_t)(video_mem_base >> 32)); - tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, video_mem_size_mb); - - /* - * MCE propagates the VideoMem configuration values across the - * CCPLEX. - */ - mce_update_gsc_videomem(); - } -} - -/* - * Secure the BL31 DRAM aperture. - * - * phys_base = physical base of TZDRAM aperture - * size_in_bytes = size of aperture in bytes - */ -void tegra_memctrl_tzdram_setup(uint64_t phys_base, uint32_t size_in_bytes) -{ - /* - * Perform platform specific steps. - */ - plat_memctrl_tzdram_setup(phys_base, size_in_bytes); -} - -/* - * Secure the BL31 TZRAM aperture. - * - * phys_base = physical base of TZRAM aperture - * size_in_bytes = size of aperture in bytes - */ -void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes) -{ - ; /* do nothing */ -} - -/* - * Save MC settings before "System Suspend" to TZDRAM - */ -void tegra_mc_save_context(uint64_t mc_ctx_addr) -{ - const tegra_mc_settings_t *plat_mc_settings = tegra_get_mc_settings(); - uint32_t i, num_entries = 0; - mc_regs_t *mc_ctx_regs; - const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); - uint64_t tzdram_base = params_from_bl2->tzdram_base; - uint64_t tzdram_end = tzdram_base + params_from_bl2->tzdram_size; - - assert((mc_ctx_addr >= tzdram_base) && (mc_ctx_addr <= tzdram_end)); - - /* get MC context table */ - mc_ctx_regs = plat_mc_settings->get_mc_system_suspend_ctx(); - assert(mc_ctx_regs != NULL); - - /* - * mc_ctx_regs[0].val contains the size of the context table minus - * the last entry. Sanity check the table size before we start with - * the context save operation. - */ - while (mc_ctx_regs[num_entries].reg != 0xFFFFFFFFU) { - num_entries++; - } - - /* panic if the sizes do not match */ - if (num_entries != mc_ctx_regs[0].val) { - ERROR("MC context size mismatch!"); - panic(); - } - - /* save MC register values */ - for (i = 1U; i < num_entries; i++) { - mc_ctx_regs[i].val = mmio_read_32(mc_ctx_regs[i].reg); - } - - /* increment by 1 to take care of the last entry */ - num_entries++; - - /* Save MC config settings */ - (void)memcpy((void *)mc_ctx_addr, mc_ctx_regs, - sizeof(mc_regs_t) * num_entries); - - /* save the MC table address */ - mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_MC_TABLE_ADDR_LO, - (uint32_t)mc_ctx_addr); - mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_MC_TABLE_ADDR_HI, - (uint32_t)(mc_ctx_addr >> 32)); -} - -static void tegra_lock_videomem_nonoverlap(uint64_t phys_base, - uint64_t size_in_bytes) -{ - uint32_t index; - uint64_t total_128kb_blocks = size_in_bytes >> 17; - uint64_t residual_4kb_blocks = (size_in_bytes & (uint32_t)0x1FFFF) >> 12; - uint64_t val; - - /* - * Reset the access configuration registers to restrict access to - * old Videomem aperture - */ - for (index = MC_VIDEO_PROTECT_CLEAR_ACCESS_CFG0; - index < ((uint32_t)MC_VIDEO_PROTECT_CLEAR_ACCESS_CFG0 + (uint32_t)MC_GSC_CONFIG_REGS_SIZE); - index += 4U) { - tegra_mc_write_32(index, 0); - } - - /* - * Set the base. It must be 4k aligned, at least. - */ - assert((phys_base & (uint64_t)0xFFF) == 0U); - tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_BASE_LO, (uint32_t)phys_base); - tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_BASE_HI, - (uint32_t)(phys_base >> 32) & (uint32_t)MC_GSC_BASE_HI_MASK); - - /* - * Set the aperture size - * - * total size = (number of 128KB blocks) + (number of remaining 4KB - * blocks) - * - */ - val = (uint32_t)((residual_4kb_blocks << MC_GSC_SIZE_RANGE_4KB_SHIFT) | - total_128kb_blocks); - tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_SIZE, (uint32_t)val); - - /* - * Lock the configuration settings by enabling TZ-only lock and - * locking the configuration against any future changes from NS - * world. - */ - tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_CFG, - (uint32_t)MC_GSC_ENABLE_TZ_LOCK_BIT); - - /* - * MCE propagates the GSC configuration values across the - * CCPLEX. - */ -} - -static void tegra_unlock_videomem_nonoverlap(void) -{ - /* Clear the base */ - tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_BASE_LO, 0); - tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_BASE_HI, 0); - - /* Clear the size */ - tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_SIZE, 0); -} - -static void tegra_clear_videomem(uintptr_t non_overlap_area_start, - unsigned long long non_overlap_area_size) -{ - int ret; - - INFO("Cleaning previous Video Memory Carveout\n"); - - /* - * Map the NS memory first, clean it and then unmap it. - */ - ret = mmap_add_dynamic_region(non_overlap_area_start, /* PA */ - non_overlap_area_start, /* VA */ - non_overlap_area_size, /* size */ - MT_DEVICE | MT_RW | MT_NS); /* attrs */ - assert(ret == 0); - - zeromem((void *)non_overlap_area_start, non_overlap_area_size); - flush_dcache_range(non_overlap_area_start, non_overlap_area_size); - - ret = mmap_remove_dynamic_region(non_overlap_area_start, - non_overlap_area_size); - assert(ret == 0); -} - -static void tegra_clear_videomem_nonoverlap(uintptr_t phys_base, - unsigned long size_in_bytes) -{ - uintptr_t vmem_end_old = video_mem_base + (video_mem_size_mb << 20); - uintptr_t vmem_end_new = phys_base + size_in_bytes; - unsigned long long non_overlap_area_size; - - /* - * Clear the old regions now being exposed. The following cases - * can occur - - * - * 1. clear whole old region (no overlap with new region) - * 2. clear old sub-region below new base - * 3. clear old sub-region above new end - */ - if ((phys_base > vmem_end_old) || (video_mem_base > vmem_end_new)) { - tegra_clear_videomem(video_mem_base, - video_mem_size_mb << 20U); - } else { - if (video_mem_base < phys_base) { - non_overlap_area_size = phys_base - video_mem_base; - tegra_clear_videomem(video_mem_base, non_overlap_area_size); - } - if (vmem_end_old > vmem_end_new) { - non_overlap_area_size = vmem_end_old - vmem_end_new; - tegra_clear_videomem(vmem_end_new, non_overlap_area_size); - } - } -} - -/* - * Program the Video Memory carveout region - * - * phys_base = physical base of aperture - * size_in_bytes = size of aperture in bytes - */ -void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes) -{ - /* - * Setup the Memory controller to restrict CPU accesses to the Video - * Memory region - */ - - INFO("Configuring Video Memory Carveout\n"); - - if (video_mem_base != 0U) { - /* - * Lock the non overlapping memory being cleared so that - * other masters do not accidently write to it. The memory - * would be unlocked once the non overlapping region is - * cleared and the new memory settings take effect. - */ - tegra_lock_videomem_nonoverlap(video_mem_base, - video_mem_size_mb << 20); - } - - /* program the Videomem aperture */ - tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO, (uint32_t)phys_base); - tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI, - (uint32_t)(phys_base >> 32)); - tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, size_in_bytes >> 20); - - /* - * MCE propagates the VideoMem configuration values across the - * CCPLEX. - */ - (void)mce_update_gsc_videomem(); - - /* Clear the non-overlapping memory */ - if (video_mem_base != 0U) { - tegra_clear_videomem_nonoverlap(phys_base, size_in_bytes); - tegra_unlock_videomem_nonoverlap(); - } - - /* store new values */ - video_mem_base = phys_base; - video_mem_size_mb = (uint64_t)size_in_bytes >> 20; -} - -/* - * This feature exists only for v1 of the Tegra Memory Controller. - */ -void tegra_memctrl_disable_ahb_redirection(void) -{ - ; /* do nothing */ -} - -void tegra_memctrl_clear_pending_interrupts(void) -{ - ; /* do nothing */ -} diff --git a/plat/nvidia/tegra/common/drivers/pmc/pmc.c b/plat/nvidia/tegra/common/drivers/pmc/pmc.c deleted file mode 100644 index 6c5a73baf..000000000 --- a/plat/nvidia/tegra/common/drivers/pmc/pmc.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include -#include -#include - -#include -#include - -#define RESET_ENABLE 0x10U - -/* Module IDs used during power ungate procedure */ -static const uint32_t pmc_cpu_powergate_id[4] = { - 14, /* CPU 0 */ - 9, /* CPU 1 */ - 10, /* CPU 2 */ - 11 /* CPU 3 */ -}; - -/******************************************************************************* - * Power ungate CPU to start the boot process. CPU reset vectors must be - * populated before calling this function. - ******************************************************************************/ -void tegra_pmc_cpu_on(int32_t cpu) -{ - uint32_t val; - - /* - * Check if CPU is already power ungated - */ - val = tegra_pmc_read_32(PMC_PWRGATE_STATUS); - if ((val & (1U << pmc_cpu_powergate_id[cpu])) == 0U) { - /* - * The PMC deasserts the START bit when it starts the power - * ungate process. Loop till no power toggle is in progress. - */ - do { - val = tegra_pmc_read_32(PMC_PWRGATE_TOGGLE); - } while ((val & PMC_TOGGLE_START) != 0U); - - /* - * Start the power ungate procedure - */ - val = pmc_cpu_powergate_id[cpu] | PMC_TOGGLE_START; - tegra_pmc_write_32(PMC_PWRGATE_TOGGLE, val); - - /* - * The PMC deasserts the START bit when it starts the power - * ungate process. Loop till powergate START bit is asserted. - */ - do { - val = tegra_pmc_read_32(PMC_PWRGATE_TOGGLE); - } while ((val & (1U << 8)) != 0U); - - /* loop till the CPU is power ungated */ - do { - val = tegra_pmc_read_32(PMC_PWRGATE_STATUS); - } while ((val & (1U << pmc_cpu_powergate_id[cpu])) == 0U); - } -} - -/******************************************************************************* - * Setup CPU vectors for resume from deep sleep - ******************************************************************************/ -void tegra_pmc_cpu_setup(uint64_t reset_addr) -{ - uint32_t val; - - tegra_pmc_write_32(PMC_SECURE_SCRATCH34, - ((uint32_t)reset_addr & 0xFFFFFFFFU) | 1U); - val = (uint32_t)(reset_addr >> 32U); - tegra_pmc_write_32(PMC_SECURE_SCRATCH35, val & 0x7FFU); -} - -/******************************************************************************* - * Lock CPU vectors to restrict further writes - ******************************************************************************/ -void tegra_pmc_lock_cpu_vectors(void) -{ - uint32_t val; - - /* lock PMC_SECURE_SCRATCH22 */ - val = tegra_pmc_read_32(PMC_SECURE_DISABLE2); - val |= PMC_SECURE_DISABLE2_WRITE22_ON; - tegra_pmc_write_32(PMC_SECURE_DISABLE2, val); - - /* lock PMC_SECURE_SCRATCH34/35 */ - val = tegra_pmc_read_32(PMC_SECURE_DISABLE3); - val |= (PMC_SECURE_DISABLE3_WRITE34_ON | - PMC_SECURE_DISABLE3_WRITE35_ON); - tegra_pmc_write_32(PMC_SECURE_DISABLE3, val); -} - -/******************************************************************************* - * Find out if this is the last standing CPU - ******************************************************************************/ -bool tegra_pmc_is_last_on_cpu(void) -{ - int i, cpu = read_mpidr() & MPIDR_CPU_MASK; - uint32_t val = tegra_pmc_read_32(PMC_PWRGATE_STATUS);; - bool status = true; - - /* check if this is the last standing CPU */ - for (i = 0; i < PLATFORM_MAX_CPUS_PER_CLUSTER; i++) { - - /* skip the current CPU */ - if (i == cpu) - continue; - - /* are other CPUs already power gated? */ - if ((val & ((uint32_t)1 << pmc_cpu_powergate_id[i])) != 0U) { - status = false; - } - } - - return status; -} - -/******************************************************************************* - * Handler to be called on exiting System suspend. Right now only DPD registers - * are cleared. - ******************************************************************************/ -void tegra_pmc_resume(void) -{ - - /* Clear DPD sample */ - mmio_write_32((TEGRA_PMC_BASE + PMC_IO_DPD_SAMPLE), 0x0); - - /* Clear DPD Enable */ - mmio_write_32((TEGRA_PMC_BASE + PMC_DPD_ENABLE_0), 0x0); -} - -/******************************************************************************* - * Restart the system - ******************************************************************************/ -__dead2 void tegra_pmc_system_reset(void) -{ - uint32_t reg; - - reg = tegra_pmc_read_32(PMC_CONFIG); - reg |= RESET_ENABLE; /* restart */ - tegra_pmc_write_32(PMC_CONFIG, reg); - wfi(); - - ERROR("Tegra System Reset: operation not handled.\n"); - panic(); -} diff --git a/plat/nvidia/tegra/common/drivers/smmu/smmu.c b/plat/nvidia/tegra/common/drivers/smmu/smmu.c deleted file mode 100644 index a4a4354e8..000000000 --- a/plat/nvidia/tegra/common/drivers/smmu/smmu.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. - * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include - -#include - -#include -#include - -#include -#include - -extern void memcpy16(void *dest, const void *src, unsigned int length); - -#define SMMU_NUM_CONTEXTS 64U -#define SMMU_CONTEXT_BANK_MAX_IDX 64U - -/* - * Init SMMU during boot or "System Suspend" exit - */ -void tegra_smmu_init(void) -{ - uint32_t val, cb_idx, smmu_id, ctx_base; - uint32_t smmu_counter = plat_get_num_smmu_devices(); - - for (smmu_id = 0U; smmu_id < smmu_counter; smmu_id++) { - /* Program the SMMU pagesize and reset CACHE_LOCK bit */ - val = tegra_smmu_read_32(smmu_id, SMMU_GSR0_SECURE_ACR); - val |= SMMU_GSR0_PGSIZE_64K; - val &= (uint32_t)~SMMU_ACR_CACHE_LOCK_ENABLE_BIT; - tegra_smmu_write_32(smmu_id, SMMU_GSR0_SECURE_ACR, val); - - /* reset CACHE LOCK bit for NS Aux. Config. Register */ - val = tegra_smmu_read_32(smmu_id, SMMU_GNSR_ACR); - val &= (uint32_t)~SMMU_ACR_CACHE_LOCK_ENABLE_BIT; - tegra_smmu_write_32(smmu_id, SMMU_GNSR_ACR, val); - - /* disable TCU prefetch for all contexts */ - ctx_base = (SMMU_GSR0_PGSIZE_64K * SMMU_NUM_CONTEXTS) - + SMMU_CBn_ACTLR; - for (cb_idx = 0; cb_idx < SMMU_CONTEXT_BANK_MAX_IDX; cb_idx++) { - val = tegra_smmu_read_32(smmu_id, - ctx_base + (SMMU_GSR0_PGSIZE_64K * cb_idx)); - val &= (uint32_t)~SMMU_CBn_ACTLR_CPRE_BIT; - tegra_smmu_write_32(smmu_id, ctx_base + - (SMMU_GSR0_PGSIZE_64K * cb_idx), val); - } - - /* set CACHE LOCK bit for NS Aux. Config. Register */ - val = tegra_smmu_read_32(smmu_id, SMMU_GNSR_ACR); - val |= (uint32_t)SMMU_ACR_CACHE_LOCK_ENABLE_BIT; - tegra_smmu_write_32(smmu_id, SMMU_GNSR_ACR, val); - - /* set CACHE LOCK bit for S Aux. Config. Register */ - val = tegra_smmu_read_32(smmu_id, SMMU_GSR0_SECURE_ACR); - val |= (uint32_t)SMMU_ACR_CACHE_LOCK_ENABLE_BIT; - tegra_smmu_write_32(smmu_id, SMMU_GSR0_SECURE_ACR, val); - } -} diff --git a/plat/nvidia/tegra/common/drivers/spe/shared_console.S b/plat/nvidia/tegra/common/drivers/spe/shared_console.S deleted file mode 100644 index 6df73ec24..000000000 --- a/plat/nvidia/tegra/common/drivers/spe/shared_console.S +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. - * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ -#include -#include - -#define CONSOLE_NUM_BYTES_SHIFT 24 -#define CONSOLE_FLUSH_DATA_TO_PORT (1 << 26) -#define CONSOLE_RING_DOORBELL (1 << 31) -#define CONSOLE_IS_BUSY (1 << 31) -#define CONSOLE_TIMEOUT 0xC000 /* approx. 50 ms */ -#define CONSOLE_WRITE (CONSOLE_RING_DOORBELL | CONSOLE_FLUSH_DATA_TO_PORT) - - /* - * This file contains a driver implementation to make use of the - * real console implementation provided by the SPE firmware running - * SoCs after Tegra186. - * - * This console is shared by multiple components and the SPE firmware - * finally displays everything on the UART port. - */ - - .globl console_spe_core_init - .globl console_spe_core_putc - .globl console_spe_core_getc - .globl console_spe_core_flush - .globl console_spe_putc - .globl console_spe_getc - .globl console_spe_flush - .globl console_spe_register - -.macro check_if_console_is_ready base, tmp1, tmp2, label - /* wait until spe is ready or timeout expires */ - mrs \tmp2, cntps_tval_el1 -1: ldr \tmp1, [\base] - and \tmp1, \tmp1, #CONSOLE_IS_BUSY - cbz \tmp1, 2f - mrs \tmp1, cntps_tval_el1 - sub \tmp1, \tmp2, \tmp1 - cmp \tmp1, #CONSOLE_TIMEOUT - b.lt 1b - b \label -2: -.endm - - /* ------------------------------------------------- - * int console_spe_register(uintptr_t baseaddr, - * uint32_t clock, uint32_t baud, - * console_t *console); - * Function to initialize and register a new spe - * console. Storage passed in for the console struct - * *must* be persistent (i.e. not from the stack). - * In: x0 - UART register base address - * w1 - UART clock in Hz - * w2 - Baud rate - * x3 - pointer to empty console_t struct - * Out: return 1 on success, 0 on error - * Clobber list : x0, x1, x2, x6, x7, x14 - * ------------------------------------------------- - */ -func console_spe_register - /* Check the input base address */ - cbz x0, register_fail - - /* Dont use clock or baud rate, so ok to overwrite them */ - check_if_console_is_ready x0, x1, x2, register_fail - - cbz x3, register_fail - str x0, [x3, #CONSOLE_T_BASE] - mov x0, x3 - finish_console_register spe putc=1, getc=1, flush=1 - -register_fail: - mov w0, wzr - ret -endfunc console_spe_register - - /* -------------------------------------------------------- - * int console_spe_core_putc(int c, uintptr_t base_addr) - * Function to output a character over the console. It - * returns the character printed on success or -1 on error. - * In : w0 - character to be printed - * x1 - console base address - * Out : return -1 on error else return character. - * Clobber list : x2, x3 - * -------------------------------------------------------- - */ -func console_spe_core_putc - /* Check the input parameter */ - cbz x1, putc_error - - /* Prepend '\r' to '\n' */ - cmp w0, #0xA - b.ne not_eol - - check_if_console_is_ready x1, x2, x3, putc_error - - /* spe is ready */ - mov w2, #0xD /* '\r' */ - and w2, w2, #0xFF - mov w3, #(CONSOLE_WRITE | (1 << CONSOLE_NUM_BYTES_SHIFT)) - orr w2, w2, w3 - str w2, [x1] - -not_eol: - check_if_console_is_ready x1, x2, x3, putc_error - - /* spe is ready */ - mov w2, w0 - and w2, w2, #0xFF - mov w3, #(CONSOLE_WRITE | (1 << CONSOLE_NUM_BYTES_SHIFT)) - orr w2, w2, w3 - str w2, [x1] - - ret -putc_error: - mov w0, #-1 - ret -endfunc console_spe_core_putc - - /* -------------------------------------------------------- - * int console_spe_putc(int c, console_t *console) - * Function to output a character over the console. It - * returns the character printed on success or -1 on error. - * In : w0 - character to be printed - * x1 - pointer to console_t structure - * Out : return -1 on error else return character. - * Clobber list : x2 - * -------------------------------------------------------- - */ -func console_spe_putc - ldr x1, [x1, #CONSOLE_T_BASE] - b console_spe_core_putc -endfunc console_spe_putc - - /* --------------------------------------------- - * int console_spe_getc(console_t *console) - * Function to get a character from the console. - * It returns the character grabbed on success - * or -1 if no character is available. - * In : x0 - pointer to console_t structure - * Out: w0 - character if available, else -1 - * Clobber list : x0, x1 - * --------------------------------------------- - */ -func console_spe_getc - mov w0, #-1 - ret -endfunc console_spe_getc - - /* ------------------------------------------------- - * int console_spe_core_flush(uintptr_t base_addr) - * Function to force a write of all buffered - * data that hasn't been output. - * In : x0 - console base address - * Out : return -1 on error else return 0. - * Clobber list : x0, x1 - * ------------------------------------------------- - */ -func console_spe_core_flush - cbz x0, flush_error - - /* flush console */ - mov w1, #CONSOLE_WRITE - str w1, [x0] - mov w0, #0 - ret -flush_error: - mov w0, #-1 - ret -endfunc console_spe_core_flush - - /* --------------------------------------------- - * int console_spe_flush(console_t *console) - * Function to force a write of all buffered - * data that hasn't been output. - * In : x0 - pointer to console_t structure - * Out : return -1 on error else return 0. - * Clobber list : x0, x1 - * --------------------------------------------- - */ -func console_spe_flush - ldr x0, [x0, #CONSOLE_T_BASE] - b console_spe_core_flush -endfunc console_spe_flush diff --git a/plat/nvidia/tegra/common/lib/debug/profiler.c b/plat/nvidia/tegra/common/lib/debug/profiler.c deleted file mode 100644 index dd76a4e96..000000000 --- a/plat/nvidia/tegra/common/lib/debug/profiler.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/******************************************************************************* - * The profiler stores the timestamps captured during cold boot to the shared - * memory for the non-secure world. The non-secure world driver parses the - * shared memory block and writes the contents to a file on the device, which - * can be later extracted for analysis. - * - * Profiler memory map - * - * TOP --------------------------- --- - * Trusted OS timestamps 3KB - * --------------------------- --- - * Trusted Firmware timestamps 1KB - * BASE --------------------------- --- - * - ******************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static uint64_t shmem_base_addr; - -#define MAX_PROFILER_RECORDS U(16) -#define TAG_LEN_BYTES U(56) - -/******************************************************************************* - * Profiler entry format - ******************************************************************************/ -typedef struct { - /* text explaining the timestamp location in code */ - uint8_t tag[TAG_LEN_BYTES]; - /* timestamp value */ - uint64_t timestamp; -} profiler_rec_t; - -static profiler_rec_t *head, *cur, *tail; -static uint32_t tmr; -static bool is_shmem_buf_mapped; - -/******************************************************************************* - * Initialise the profiling library - ******************************************************************************/ -void boot_profiler_init(uint64_t shmem_base, uint32_t tmr_base) -{ - uint64_t shmem_end_base; - - assert(shmem_base != ULL(0)); - assert(tmr_base != U(0)); - - /* store the buffer address */ - shmem_base_addr = shmem_base; - - /* calculate the base address of the last record */ - shmem_end_base = shmem_base + (sizeof(profiler_rec_t) * - (MAX_PROFILER_RECORDS - U(1))); - - /* calculate the head, tail and cur values */ - head = (profiler_rec_t *)shmem_base; - tail = (profiler_rec_t *)shmem_end_base; - cur = head; - - /* timer used to get the current timestamp */ - tmr = tmr_base; -} - -/******************************************************************************* - * Add tag and timestamp to profiler - ******************************************************************************/ -void boot_profiler_add_record(const char *str) -{ - unsigned int len; - - /* calculate the length of the tag */ - if (((unsigned int)strlen(str) + U(1)) > TAG_LEN_BYTES) { - len = TAG_LEN_BYTES; - } else { - len = (unsigned int)strlen(str) + U(1); - } - - if (head != NULL) { - - /* - * The profiler runs with/without MMU enabled. Check - * if MMU is enabled and memmap the shmem buffer, in - * case it is. - */ - if ((!is_shmem_buf_mapped) && - ((read_sctlr_el3() & SCTLR_M_BIT) != U(0))) { - - (void)mmap_add_dynamic_region(shmem_base_addr, - shmem_base_addr, - PROFILER_SIZE_BYTES, - (MT_NS | MT_RW | MT_EXECUTE_NEVER)); - - is_shmem_buf_mapped = true; - } - - /* write the tag and timestamp to buffer */ - (void)snprintf((char *)cur->tag, len, "%s", str); - cur->timestamp = mmio_read_32(tmr); - - /* start from head if we reached the end */ - if (cur == tail) { - cur = head; - } else { - cur++; - } - } -} - -/******************************************************************************* - * Deinint the profiler - ******************************************************************************/ -void boot_profiler_deinit(void) -{ - if (shmem_base_addr != ULL(0)) { - - /* clean up resources */ - cur = NULL; - head = NULL; - tail = NULL; - - /* flush the shmem for it to be visible to the NS world */ - flush_dcache_range(shmem_base_addr, PROFILER_SIZE_BYTES); - - /* unmap the shmem buffer */ - if (is_shmem_buf_mapped) { - (void)mmap_remove_dynamic_region(shmem_base_addr, - PROFILER_SIZE_BYTES); - } - } -} diff --git a/plat/nvidia/tegra/common/tegra_common.mk b/plat/nvidia/tegra/common/tegra_common.mk index f412a80b8..bb8bd7d89 100644 --- a/plat/nvidia/tegra/common/tegra_common.mk +++ b/plat/nvidia/tegra/common/tegra_common.mk @@ -12,37 +12,46 @@ PLAT_INCLUDES := -Iplat/nvidia/tegra/include/drivers \ include lib/xlat_tables_v2/xlat_tables.mk PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS} -COMMON_DIR := plat/nvidia/tegra/common +TEGRA_COMMON := plat/nvidia/tegra/common +TEGRA_DRIVERS := plat/nvidia/tegra/drivers +TEGRA_LIBS := plat/nvidia/tegra/lib # Include GICv3 driver files include drivers/arm/gic/v3/gicv3.mk TEGRA_GICv3_SOURCES := $(GICV3_SOURCES) \ plat/common/plat_gicv3.c \ - ${COMMON_DIR}/tegra_gicv3.c + ${TEGRA_COMMON}/tegra_gicv3.c # Include GICv2 driver files include drivers/arm/gic/v2/gicv2.mk TEGRA_GICv2_SOURCES := ${GICV2_SOURCES} \ plat/common/plat_gicv2.c \ - ${COMMON_DIR}/tegra_gicv2.c + ${TEGRA_COMMON}/tegra_gicv2.c + +TEGRA_GICv3_SOURCES := drivers/arm/gic/common/gic_common.c \ + drivers/arm/gic/v3/arm_gicv3_common.c \ + drivers/arm/gic/v3/gicv3_main.c \ + drivers/arm/gic/v3/gicv3_helpers.c \ + plat/common/plat_gicv3.c \ + ${TEGRA_COMMON}/tegra_gicv3.c BL31_SOURCES += drivers/delay_timer/delay_timer.c \ drivers/io/io_storage.c \ plat/common/aarch64/crash_console_helpers.S \ ${TEGRA_GICv2_SOURCES} \ - ${COMMON_DIR}/aarch64/tegra_helpers.S \ - ${COMMON_DIR}/lib/debug/profiler.c \ - ${COMMON_DIR}/tegra_bl31_setup.c \ - ${COMMON_DIR}/tegra_delay_timer.c \ - ${COMMON_DIR}/tegra_ehf.c \ - ${COMMON_DIR}/tegra_fiq_glue.c \ - ${COMMON_DIR}/tegra_io_storage.c \ - ${COMMON_DIR}/tegra_platform.c \ - ${COMMON_DIR}/tegra_pm.c \ - ${COMMON_DIR}/tegra_sip_calls.c \ - ${COMMON_DIR}/tegra_sdei.c + ${TEGRA_COMMON}/aarch64/tegra_helpers.S \ + ${TEGRA_LIBS}/debug/profiler.c \ + ${TEGRA_COMMON}/tegra_bl31_setup.c \ + ${TEGRA_COMMON}/tegra_delay_timer.c \ + ${TEGRA_COMMON}/tegra_ehf.c \ + ${TEGRA_COMMON}/tegra_fiq_glue.c \ + ${TEGRA_COMMON}/tegra_io_storage.c \ + ${TEGRA_COMMON}/tegra_platform.c \ + ${TEGRA_COMMON}/tegra_pm.c \ + ${TEGRA_COMMON}/tegra_sip_calls.c \ + ${TEGRA_COMMON}/tegra_sdei.c ifneq ($(ENABLE_STACK_PROTECTOR), 0) -BL31_SOURCES += ${COMMON_DIR}/tegra_stack_protector.c +BL31_SOURCES += ${TEGRA_COMMON}/tegra_stack_protector.c endif diff --git a/plat/nvidia/tegra/drivers/bpmp/bpmp.c b/plat/nvidia/tegra/drivers/bpmp/bpmp.c new file mode 100644 index 000000000..d7db604cc --- /dev/null +++ b/plat/nvidia/tegra/drivers/bpmp/bpmp.c @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BPMP_TIMEOUT 500 /* 500ms */ + +static uint32_t channel_base[NR_CHANNELS]; +static uint32_t bpmp_init_state = BPMP_INIT_PENDING; + +static uint32_t channel_field(unsigned int ch) +{ + return mmio_read_32(TEGRA_RES_SEMA_BASE + STA_OFFSET) & CH_MASK(ch); +} + +static bool master_free(unsigned int ch) +{ + return channel_field(ch) == MA_FREE(ch); +} + +static bool master_acked(unsigned int ch) +{ + return channel_field(ch) == MA_ACKD(ch); +} + +static void signal_slave(unsigned int ch) +{ + mmio_write_32(TEGRA_RES_SEMA_BASE + CLR_OFFSET, CH_MASK(ch)); +} + +static void free_master(unsigned int ch) +{ + mmio_write_32(TEGRA_RES_SEMA_BASE + CLR_OFFSET, + MA_ACKD(ch) ^ MA_FREE(ch)); +} + +/* should be called with local irqs disabled */ +int32_t tegra_bpmp_send_receive_atomic(int mrq, const void *ob_data, int ob_sz, + void *ib_data, int ib_sz) +{ + unsigned int ch = (unsigned int)plat_my_core_pos(); + mb_data_t *p = (mb_data_t *)(uintptr_t)channel_base[ch]; + int32_t ret = -ETIMEDOUT, timeout = 0; + + if (bpmp_init_state == BPMP_INIT_COMPLETE) { + + /* loop until BPMP is free */ + for (timeout = 0; timeout < BPMP_TIMEOUT; timeout++) { + if (master_free(ch) == true) { + break; + } + + mdelay(1); + } + + if (timeout != BPMP_TIMEOUT) { + + /* generate the command struct */ + p->code = mrq; + p->flags = DO_ACK; + (void)memcpy((void *)p->data, ob_data, (size_t)ob_sz); + + /* signal command ready to the BPMP */ + signal_slave(ch); + mmio_write_32(TEGRA_PRI_ICTLR_BASE + CPU_IEP_FIR_SET, + (1U << INT_SHR_SEM_OUTBOX_FULL)); + + /* loop until the command is executed */ + for (timeout = 0; timeout < BPMP_TIMEOUT; timeout++) { + if (master_acked(ch) == true) { + break; + } + + mdelay(1); + } + + if (timeout != BPMP_TIMEOUT) { + + /* get the command response */ + (void)memcpy(ib_data, (const void *)p->data, + (size_t)ib_sz); + + /* return error code */ + ret = p->code; + + /* free this channel */ + free_master(ch); + } + } + + } else { + /* return error code */ + ret = -EINVAL; + } + + if (timeout == BPMP_TIMEOUT) { + ERROR("Timed out waiting for bpmp's response\n"); + } + + return ret; +} + +int tegra_bpmp_init(void) +{ + uint32_t val, base, timeout = BPMP_TIMEOUT; + unsigned int ch; + int ret = 0; + + if (bpmp_init_state == BPMP_INIT_PENDING) { + + /* check if the bpmp processor is alive. */ + do { + val = mmio_read_32(TEGRA_RES_SEMA_BASE + STA_OFFSET); + if (val != SIGN_OF_LIFE) { + mdelay(1); + timeout--; + } + + } while ((val != SIGN_OF_LIFE) && (timeout > 0U)); + + if (val == SIGN_OF_LIFE) { + + /* check if clock for the atomics block is enabled */ + val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_ENB_V); + if ((val & CAR_ENABLE_ATOMICS) == 0) { + ERROR("Clock to the atomics block is disabled\n"); + } + + /* check if the atomics block is out of reset */ + val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEV_CLR_V); + if ((val & CAR_ENABLE_ATOMICS) == CAR_ENABLE_ATOMICS) { + ERROR("Reset to the atomics block is asserted\n"); + } + + /* base address to get the result from Atomics */ + base = TEGRA_ATOMICS_BASE + RESULT0_REG_OFFSET; + + /* channel area is setup by BPMP before signaling handshake */ + for (ch = 0; ch < NR_CHANNELS; ch++) { + + /* issue command to get the channel base address */ + mmio_write_32(base, (ch << TRIGGER_ID_SHIFT) | + ATOMIC_CMD_GET); + + /* get the base address for the channel */ + channel_base[ch] = mmio_read_32(base); + + /* increment result register offset */ + base += 4U; + } + + /* mark state as "initialized" */ + bpmp_init_state = BPMP_INIT_COMPLETE; + + /* the channel values have to be visible across all cpus */ + flush_dcache_range((uint64_t)channel_base, + sizeof(channel_base)); + flush_dcache_range((uint64_t)&bpmp_init_state, + sizeof(bpmp_init_state)); + + INFO("%s: done\n", __func__); + + } else { + ERROR("BPMP not powered on\n"); + + /* bpmp is not present in the system */ + bpmp_init_state = BPMP_NOT_PRESENT; + + /* communication timed out */ + ret = -ETIMEDOUT; + } + } + + return ret; +} + +void tegra_bpmp_suspend(void) +{ + /* freeze the interface */ + if (bpmp_init_state == BPMP_INIT_COMPLETE) { + bpmp_init_state = BPMP_SUSPEND_ENTRY; + flush_dcache_range((uint64_t)&bpmp_init_state, + sizeof(bpmp_init_state)); + } +} + +void tegra_bpmp_resume(void) +{ + uint32_t val, timeout = 0; + + if (bpmp_init_state == BPMP_SUSPEND_ENTRY) { + + /* check if the bpmp processor is alive. */ + do { + + val = mmio_read_32(TEGRA_RES_SEMA_BASE + STA_OFFSET); + if (val != SIGN_OF_LIFE) { + mdelay(1); + timeout++; + } + + } while ((val != SIGN_OF_LIFE) && (timeout < BPMP_TIMEOUT)); + + if (val == SIGN_OF_LIFE) { + + INFO("%s: BPMP took %d ms to resume\n", __func__, timeout); + + /* mark state as "initialized" */ + bpmp_init_state = BPMP_INIT_COMPLETE; + + /* state has to be visible across all cpus */ + flush_dcache_range((uint64_t)&bpmp_init_state, + sizeof(bpmp_init_state)); + } else { + ERROR("BPMP not powered on\n"); + } + } +} diff --git a/plat/nvidia/tegra/drivers/bpmp_ipc/intf.c b/plat/nvidia/tegra/drivers/bpmp_ipc/intf.c new file mode 100644 index 000000000..2e90d2547 --- /dev/null +++ b/plat/nvidia/tegra/drivers/bpmp_ipc/intf.c @@ -0,0 +1,345 @@ +/* + * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "intf.h" +#include "ivc.h" + +/** + * Holds IVC channel data + */ +struct ccplex_bpmp_channel_data { + /* Buffer for incoming data */ + struct frame_data *ib; + + /* Buffer for outgoing data */ + struct frame_data *ob; +}; + +static struct ccplex_bpmp_channel_data s_channel; +static struct ivc ivc_ccplex_bpmp_channel; + +/* + * Helper functions to access the HSP doorbell registers + */ +static inline uint32_t hsp_db_read(uint32_t reg) +{ + return mmio_read_32((uint32_t)(TEGRA_HSP_DBELL_BASE + reg)); +} + +static inline void hsp_db_write(uint32_t reg, uint32_t val) +{ + mmio_write_32((uint32_t)(TEGRA_HSP_DBELL_BASE + reg), val); +} + +/******************************************************************************* + * IVC wrappers for CCPLEX <-> BPMP communication. + ******************************************************************************/ + +static void tegra_bpmp_ring_bpmp_doorbell(void); + +/* + * Get the next frame where data can be written. + */ +static struct frame_data *tegra_bpmp_get_next_out_frame(void) +{ + struct frame_data *frame; + const struct ivc *ch = &ivc_ccplex_bpmp_channel; + + frame = (struct frame_data *)tegra_ivc_write_get_next_frame(ch); + if (frame == NULL) { + ERROR("%s: Error in getting next frame, exiting\n", __func__); + } else { + s_channel.ob = frame; + } + + return frame; +} + +static void tegra_bpmp_signal_slave(void) +{ + (void)tegra_ivc_write_advance(&ivc_ccplex_bpmp_channel); + tegra_bpmp_ring_bpmp_doorbell(); +} + +static int32_t tegra_bpmp_free_master(void) +{ + return tegra_ivc_read_advance(&ivc_ccplex_bpmp_channel); +} + +static bool tegra_bpmp_slave_acked(void) +{ + struct frame_data *frame; + bool ret = true; + + frame = (struct frame_data *)tegra_ivc_read_get_next_frame(&ivc_ccplex_bpmp_channel); + if (frame == NULL) { + ret = false; + } else { + s_channel.ib = frame; + } + + return ret; +} + +static struct frame_data *tegra_bpmp_get_cur_in_frame(void) +{ + return s_channel.ib; +} + +/* + * Enables BPMP to ring CCPlex doorbell + */ +static void tegra_bpmp_enable_ccplex_doorbell(void) +{ + uint32_t reg; + + reg = hsp_db_read(HSP_DBELL_1_ENABLE); + reg |= HSP_MASTER_BPMP_BIT; + hsp_db_write(HSP_DBELL_1_ENABLE, reg); +} + +/* + * CCPlex rings the BPMP doorbell + */ +static void tegra_bpmp_ring_bpmp_doorbell(void) +{ + /* + * Any writes to this register has the same effect, + * uses master ID of the write transaction and set + * corresponding flag. + */ + hsp_db_write(HSP_DBELL_3_TRIGGER, HSP_MASTER_CCPLEX_BIT); +} + +/* + * Returns true if CCPLex can ring BPMP doorbell, otherwise false. + * This also signals that BPMP is up and ready. + */ +static bool tegra_bpmp_can_ccplex_ring_doorbell(void) +{ + uint32_t reg; + + /* check if ccplex can communicate with bpmp */ + reg = hsp_db_read(HSP_DBELL_3_ENABLE); + + return ((reg & HSP_MASTER_CCPLEX_BIT) != 0U); +} + +static int32_t tegra_bpmp_wait_for_slave_ack(void) +{ + uint32_t timeout = TIMEOUT_RESPONSE_FROM_BPMP_US; + + while (!tegra_bpmp_slave_acked() && (timeout != 0U)) { + udelay(1); + timeout--; + }; + + return ((timeout == 0U) ? -ETIMEDOUT : 0); +} + +/* + * Notification from the ivc layer + */ +static void tegra_bpmp_ivc_notify(const struct ivc *ivc) +{ + (void)(ivc); + + tegra_bpmp_ring_bpmp_doorbell(); +} + +/* + * Atomic send/receive API, which means it waits until slave acks + */ +static int32_t tegra_bpmp_ipc_send_req_atomic(uint32_t mrq, void *p_out, + uint32_t size_out, void *p_in, uint32_t size_in) +{ + struct frame_data *frame = tegra_bpmp_get_next_out_frame(); + const struct frame_data *f_in = NULL; + int32_t ret = 0; + void *p_fdata; + + if ((p_out == NULL) || (size_out > IVC_DATA_SZ_BYTES) || + (frame == NULL)) { + ERROR("%s: invalid parameters, exiting\n", __func__); + return -EINVAL; + } + + /* prepare the command frame */ + frame->mrq = mrq; + frame->flags = FLAG_DO_ACK; + p_fdata = frame->data; + (void)memcpy(p_fdata, p_out, (size_t)size_out); + + /* signal the slave */ + tegra_bpmp_signal_slave(); + + /* wait for slave to ack */ + ret = tegra_bpmp_wait_for_slave_ack(); + if (ret < 0) { + ERROR("%s: wait for slave failed (%d)\n", __func__, ret); + return ret; + } + + /* retrieve the response frame */ + if ((size_in <= IVC_DATA_SZ_BYTES) && (p_in != NULL)) { + + f_in = tegra_bpmp_get_cur_in_frame(); + if (f_in != NULL) { + ERROR("Failed to get next input frame!\n"); + } else { + (void)memcpy(p_in, p_fdata, (size_t)size_in); + } + } + + ret = tegra_bpmp_free_master(); + if (ret < 0) { + ERROR("%s: free master failed (%d)\n", __func__, ret); + } + + return ret; +} + +/* + * Initializes the BPMP<--->CCPlex communication path. + */ +int32_t tegra_bpmp_ipc_init(void) +{ + size_t msg_size; + uint32_t frame_size, timeout; + int32_t error = 0; + + /* allow bpmp to ring CCPLEX's doorbell */ + tegra_bpmp_enable_ccplex_doorbell(); + + /* wait for BPMP to actually ring the doorbell */ + timeout = TIMEOUT_RESPONSE_FROM_BPMP_US; + while ((timeout != 0U) && !tegra_bpmp_can_ccplex_ring_doorbell()) { + udelay(1); /* bpmp turn-around time */ + timeout--; + } + + if (timeout == 0U) { + ERROR("%s: BPMP firmware is not ready\n", __func__); + return -ENOTSUP; + } + + INFO("%s: BPMP handshake completed\n", __func__); + + msg_size = tegra_ivc_align(IVC_CMD_SZ_BYTES); + frame_size = (uint32_t)tegra_ivc_total_queue_size(msg_size); + if (frame_size > TEGRA_BPMP_IPC_CH_MAP_SIZE) { + ERROR("%s: carveout size is not sufficient\n", __func__); + return -EINVAL; + } + + error = tegra_ivc_init(&ivc_ccplex_bpmp_channel, + (uint32_t)TEGRA_BPMP_IPC_RX_PHYS_BASE, + (uint32_t)TEGRA_BPMP_IPC_TX_PHYS_BASE, + 1U, frame_size, tegra_bpmp_ivc_notify); + if (error != 0) { + + ERROR("%s: IVC init failed (%d)\n", __func__, error); + + } else { + + /* reset channel */ + tegra_ivc_channel_reset(&ivc_ccplex_bpmp_channel); + + /* wait for notification from BPMP */ + while (tegra_ivc_channel_notified(&ivc_ccplex_bpmp_channel) != 0) { + /* + * Interrupt BPMP with doorbell each time after + * tegra_ivc_channel_notified() returns non zero + * value. + */ + tegra_bpmp_ring_bpmp_doorbell(); + } + + INFO("%s: All communication channels initialized\n", __func__); + } + + return error; +} + +/* Handler to reset a hardware module */ +int32_t tegra_bpmp_ipc_reset_module(uint32_t rst_id) +{ + int32_t ret; + struct mrq_reset_request req = { + .cmd = (uint32_t)CMD_RESET_MODULE, + .reset_id = rst_id + }; + + /* only GPCDMA/XUSB_PADCTL resets are supported */ + assert((rst_id == TEGRA_RESET_ID_XUSB_PADCTL) || + (rst_id == TEGRA_RESET_ID_GPCDMA)); + + ret = tegra_bpmp_ipc_send_req_atomic(MRQ_RESET, &req, + (uint32_t)sizeof(req), NULL, 0); + if (ret != 0) { + ERROR("%s: failed for module %d with error %d\n", __func__, + rst_id, ret); + } + + return ret; +} + +int tegra_bpmp_ipc_enable_clock(uint32_t clk_id) +{ + int ret; + struct mrq_clk_request req; + + /* only SE clocks are supported */ + if (clk_id != TEGRA_CLK_SE) { + return -ENOTSUP; + } + + /* prepare the MRQ_CLK command */ + req.cmd_and_id = make_mrq_clk_cmd(CMD_CLK_ENABLE, clk_id); + + ret = tegra_bpmp_ipc_send_req_atomic(MRQ_CLK, &req, (uint32_t)sizeof(req), + NULL, 0); + if (ret != 0) { + ERROR("%s: failed for module %d with error %d\n", __func__, + clk_id, ret); + } + + return ret; +} + +int tegra_bpmp_ipc_disable_clock(uint32_t clk_id) +{ + int ret; + struct mrq_clk_request req; + + /* only SE clocks are supported */ + if (clk_id != TEGRA_CLK_SE) { + return -ENOTSUP; + } + + /* prepare the MRQ_CLK command */ + req.cmd_and_id = make_mrq_clk_cmd(CMD_CLK_DISABLE, clk_id); + + ret = tegra_bpmp_ipc_send_req_atomic(MRQ_CLK, &req, (uint32_t)sizeof(req), + NULL, 0); + if (ret != 0) { + ERROR("%s: failed for module %d with error %d\n", __func__, + clk_id, ret); + } + + return ret; +} diff --git a/plat/nvidia/tegra/drivers/bpmp_ipc/intf.h b/plat/nvidia/tegra/drivers/bpmp_ipc/intf.h new file mode 100644 index 000000000..d85b906b8 --- /dev/null +++ b/plat/nvidia/tegra/drivers/bpmp_ipc/intf.h @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef BPMP_INTF_H +#define BPMP_INTF_H + +/** + * Flags used in IPC req + */ +#define FLAG_DO_ACK (U(1) << 0) +#define FLAG_RING_DOORBELL (U(1) << 1) + +/* Bit 1 is designated for CCPlex in secure world */ +#define HSP_MASTER_CCPLEX_BIT (U(1) << 1) +/* Bit 19 is designated for BPMP in non-secure world */ +#define HSP_MASTER_BPMP_BIT (U(1) << 19) +/* Timeout to receive response from BPMP is 1 sec */ +#define TIMEOUT_RESPONSE_FROM_BPMP_US U(1000000) /* in microseconds */ + +/** + * IVC protocol defines and command/response frame + */ + +/** + * IVC specific defines + */ +#define IVC_CMD_SZ_BYTES U(128) +#define IVC_DATA_SZ_BYTES U(120) + +/** + * Holds frame data for an IPC request + */ +struct frame_data { + /* Identification as to what kind of data is being transmitted */ + uint32_t mrq; + + /* Flags for slave as to how to respond back */ + uint32_t flags; + + /* Actual data being sent */ + uint8_t data[IVC_DATA_SZ_BYTES]; +}; + +/** + * Commands send to the BPMP firmware + */ + +/** + * MRQ command codes + */ +#define MRQ_RESET U(20) +#define MRQ_CLK U(22) + +/** + * Reset sub-commands + */ +#define CMD_RESET_ASSERT U(1) +#define CMD_RESET_DEASSERT U(2) +#define CMD_RESET_MODULE U(3) + +/** + * Used by the sender of an #MRQ_RESET message to request BPMP to + * assert or deassert a given reset line. + */ +struct __attribute__((packed)) mrq_reset_request { + /* reset action to perform (mrq_reset_commands) */ + uint32_t cmd; + /* id of the reset to affected */ + uint32_t reset_id; +}; + +/** + * MRQ_CLK sub-commands + * + */ +enum { + CMD_CLK_GET_RATE = U(1), + CMD_CLK_SET_RATE = U(2), + CMD_CLK_ROUND_RATE = U(3), + CMD_CLK_GET_PARENT = U(4), + CMD_CLK_SET_PARENT = U(5), + CMD_CLK_IS_ENABLED = U(6), + CMD_CLK_ENABLE = U(7), + CMD_CLK_DISABLE = U(8), + CMD_CLK_GET_ALL_INFO = U(14), + CMD_CLK_GET_MAX_CLK_ID = U(15), + CMD_CLK_MAX, +}; + +/** + * Used by the sender of an #MRQ_CLK message to control clocks. The + * clk_request is split into several sub-commands. Some sub-commands + * require no additional data. Others have a sub-command specific + * payload + * + * |sub-command |payload | + * |----------------------------|-----------------------| + * |CMD_CLK_GET_RATE |- | + * |CMD_CLK_SET_RATE |clk_set_rate | + * |CMD_CLK_ROUND_RATE |clk_round_rate | + * |CMD_CLK_GET_PARENT |- | + * |CMD_CLK_SET_PARENT |clk_set_parent | + * |CMD_CLK_IS_ENABLED |- | + * |CMD_CLK_ENABLE |- | + * |CMD_CLK_DISABLE |- | + * |CMD_CLK_GET_ALL_INFO |- | + * |CMD_CLK_GET_MAX_CLK_ID |- | + * + */ +struct mrq_clk_request { + /** + * sub-command and clock id concatenated to 32-bit word. + * - bits[31..24] is the sub-cmd. + * - bits[23..0] is the clock id + */ + uint32_t cmd_and_id; +}; + +/** + * Macro to prepare the MRQ_CLK sub-command + */ +#define make_mrq_clk_cmd(cmd, id) (((cmd) << 24) | (id & 0xFFFFFF)) + +#endif /* BPMP_INTF_H */ diff --git a/plat/nvidia/tegra/drivers/bpmp_ipc/ivc.c b/plat/nvidia/tegra/drivers/bpmp_ipc/ivc.c new file mode 100644 index 000000000..d964fc001 --- /dev/null +++ b/plat/nvidia/tegra/drivers/bpmp_ipc/ivc.c @@ -0,0 +1,654 @@ +/* + * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "ivc.h" + +/* + * IVC channel reset protocol. + * + * Each end uses its tx_channel.state to indicate its synchronization state. + */ +enum { + /* + * This value is zero for backwards compatibility with services that + * assume channels to be initially zeroed. Such channels are in an + * initially valid state, but cannot be asynchronously reset, and must + * maintain a valid state at all times. + * + * The transmitting end can enter the established state from the sync or + * ack state when it observes the receiving endpoint in the ack or + * established state, indicating that has cleared the counters in our + * rx_channel. + */ + ivc_state_established = U(0), + + /* + * If an endpoint is observed in the sync state, the remote endpoint is + * allowed to clear the counters it owns asynchronously with respect to + * the current endpoint. Therefore, the current endpoint is no longer + * allowed to communicate. + */ + ivc_state_sync = U(1), + + /* + * When the transmitting end observes the receiving end in the sync + * state, it can clear the w_count and r_count and transition to the ack + * state. If the remote endpoint observes us in the ack state, it can + * return to the established state once it has cleared its counters. + */ + ivc_state_ack = U(2) +}; + +/* + * This structure is divided into two-cache aligned parts, the first is only + * written through the tx_channel pointer, while the second is only written + * through the rx_channel pointer. This delineates ownership of the cache lines, + * which is critical to performance and necessary in non-cache coherent + * implementations. + */ +struct ivc_channel_header { + struct { + /* fields owned by the transmitting end */ + uint32_t w_count; + uint32_t state; + uint32_t w_rsvd[IVC_CHHDR_TX_FIELDS - 2]; + }; + struct { + /* fields owned by the receiving end */ + uint32_t r_count; + uint32_t r_rsvd[IVC_CHHDR_RX_FIELDS - 1]; + }; +}; + +static inline bool ivc_channel_empty(const struct ivc *ivc, + volatile const struct ivc_channel_header *ch) +{ + /* + * This function performs multiple checks on the same values with + * security implications, so sample the counters' current values in + * shared memory to ensure that these checks use the same values. + */ + uint32_t wr_count = ch->w_count; + uint32_t rd_count = ch->r_count; + bool ret = false; + + (void)ivc; + + /* + * Perform an over-full check to prevent denial of service attacks where + * a server could be easily fooled into believing that there's an + * extremely large number of frames ready, since receivers are not + * expected to check for full or over-full conditions. + * + * Although the channel isn't empty, this is an invalid case caused by + * a potentially malicious peer, so returning empty is safer, because it + * gives the impression that the channel has gone silent. + */ + if (((wr_count - rd_count) > ivc->nframes) || (wr_count == rd_count)) { + ret = true; + } + + return ret; +} + +static inline bool ivc_channel_full(const struct ivc *ivc, + volatile const struct ivc_channel_header *ch) +{ + uint32_t wr_count = ch->w_count; + uint32_t rd_count = ch->r_count; + + (void)ivc; + + /* + * Invalid cases where the counters indicate that the queue is over + * capacity also appear full. + */ + return ((wr_count - rd_count) >= ivc->nframes); +} + +static inline uint32_t ivc_channel_avail_count(const struct ivc *ivc, + volatile const struct ivc_channel_header *ch) +{ + uint32_t wr_count = ch->w_count; + uint32_t rd_count = ch->r_count; + + (void)ivc; + + /* + * This function isn't expected to be used in scenarios where an + * over-full situation can lead to denial of service attacks. See the + * comment in ivc_channel_empty() for an explanation about special + * over-full considerations. + */ + return (wr_count - rd_count); +} + +static inline void ivc_advance_tx(struct ivc *ivc) +{ + ivc->tx_channel->w_count++; + + if (ivc->w_pos == (ivc->nframes - (uint32_t)1U)) { + ivc->w_pos = 0U; + } else { + ivc->w_pos++; + } +} + +static inline void ivc_advance_rx(struct ivc *ivc) +{ + ivc->rx_channel->r_count++; + + if (ivc->r_pos == (ivc->nframes - (uint32_t)1U)) { + ivc->r_pos = 0U; + } else { + ivc->r_pos++; + } +} + +static inline int32_t ivc_check_read(const struct ivc *ivc) +{ + /* + * tx_channel->state is set locally, so it is not synchronized with + * state from the remote peer. The remote peer cannot reset its + * transmit counters until we've acknowledged its synchronization + * request, so no additional synchronization is required because an + * asynchronous transition of rx_channel->state to ivc_state_ack is not + * allowed. + */ + if (ivc->tx_channel->state != ivc_state_established) { + return -ECONNRESET; + } + + /* + * Avoid unnecessary invalidations when performing repeated accesses to + * an IVC channel by checking the old queue pointers first. + * Synchronization is only necessary when these pointers indicate empty + * or full. + */ + if (!ivc_channel_empty(ivc, ivc->rx_channel)) { + return 0; + } + + return ivc_channel_empty(ivc, ivc->rx_channel) ? -ENOMEM : 0; +} + +static inline int32_t ivc_check_write(const struct ivc *ivc) +{ + if (ivc->tx_channel->state != ivc_state_established) { + return -ECONNRESET; + } + + if (!ivc_channel_full(ivc, ivc->tx_channel)) { + return 0; + } + + return ivc_channel_full(ivc, ivc->tx_channel) ? -ENOMEM : 0; +} + +bool tegra_ivc_can_read(const struct ivc *ivc) +{ + return ivc_check_read(ivc) == 0; +} + +bool tegra_ivc_can_write(const struct ivc *ivc) +{ + return ivc_check_write(ivc) == 0; +} + +bool tegra_ivc_tx_empty(const struct ivc *ivc) +{ + return ivc_channel_empty(ivc, ivc->tx_channel); +} + +static inline uintptr_t calc_frame_offset(uint32_t frame_index, + uint32_t frame_size, uint32_t frame_offset) +{ + return ((uintptr_t)frame_index * (uintptr_t)frame_size) + + (uintptr_t)frame_offset; +} + +static void *ivc_frame_pointer(const struct ivc *ivc, + volatile const struct ivc_channel_header *ch, + uint32_t frame) +{ + assert(frame < ivc->nframes); + return (void *)((uintptr_t)(&ch[1]) + + calc_frame_offset(frame, ivc->frame_size, 0)); +} + +int32_t tegra_ivc_read(struct ivc *ivc, void *buf, size_t max_read) +{ + const void *src; + int32_t result; + + if (buf == NULL) { + return -EINVAL; + } + + if (max_read > ivc->frame_size) { + return -E2BIG; + } + + result = ivc_check_read(ivc); + if (result != 0) { + return result; + } + + /* + * Order observation of w_pos potentially indicating new data before + * data read. + */ + dmbish(); + + src = ivc_frame_pointer(ivc, ivc->rx_channel, ivc->r_pos); + + (void)memcpy(buf, src, max_read); + + ivc_advance_rx(ivc); + + /* + * Ensure our write to r_pos occurs before our read from w_pos. + */ + dmbish(); + + /* + * Notify only upon transition from full to non-full. + * The available count can only asynchronously increase, so the + * worst possible side-effect will be a spurious notification. + */ + if (ivc_channel_avail_count(ivc, ivc->rx_channel) == (ivc->nframes - (uint32_t)1U)) { + ivc->notify(ivc); + } + + return (int32_t)max_read; +} + +/* directly peek at the next frame rx'ed */ +void *tegra_ivc_read_get_next_frame(const struct ivc *ivc) +{ + if (ivc_check_read(ivc) != 0) { + return NULL; + } + + /* + * Order observation of w_pos potentially indicating new data before + * data read. + */ + dmbld(); + + return ivc_frame_pointer(ivc, ivc->rx_channel, ivc->r_pos); +} + +int32_t tegra_ivc_read_advance(struct ivc *ivc) +{ + /* + * No read barriers or synchronization here: the caller is expected to + * have already observed the channel non-empty. This check is just to + * catch programming errors. + */ + int32_t result = ivc_check_read(ivc); + if (result != 0) { + return result; + } + + ivc_advance_rx(ivc); + + /* + * Ensure our write to r_pos occurs before our read from w_pos. + */ + dmbish(); + + /* + * Notify only upon transition from full to non-full. + * The available count can only asynchronously increase, so the + * worst possible side-effect will be a spurious notification. + */ + if (ivc_channel_avail_count(ivc, ivc->rx_channel) == (ivc->nframes - (uint32_t)1U)) { + ivc->notify(ivc); + } + + return 0; +} + +int32_t tegra_ivc_write(struct ivc *ivc, const void *buf, size_t size) +{ + void *p; + int32_t result; + + if ((buf == NULL) || (ivc == NULL)) { + return -EINVAL; + } + + if (size > ivc->frame_size) { + return -E2BIG; + } + + result = ivc_check_write(ivc); + if (result != 0) { + return result; + } + + p = ivc_frame_pointer(ivc, ivc->tx_channel, ivc->w_pos); + + (void)memset(p, 0, ivc->frame_size); + (void)memcpy(p, buf, size); + + /* + * Ensure that updated data is visible before the w_pos counter + * indicates that it is ready. + */ + dmbst(); + + ivc_advance_tx(ivc); + + /* + * Ensure our write to w_pos occurs before our read from r_pos. + */ + dmbish(); + + /* + * Notify only upon transition from empty to non-empty. + * The available count can only asynchronously decrease, so the + * worst possible side-effect will be a spurious notification. + */ + if (ivc_channel_avail_count(ivc, ivc->tx_channel) == 1U) { + ivc->notify(ivc); + } + + return (int32_t)size; +} + +/* directly poke at the next frame to be tx'ed */ +void *tegra_ivc_write_get_next_frame(const struct ivc *ivc) +{ + if (ivc_check_write(ivc) != 0) { + return NULL; + } + + return ivc_frame_pointer(ivc, ivc->tx_channel, ivc->w_pos); +} + +/* advance the tx buffer */ +int32_t tegra_ivc_write_advance(struct ivc *ivc) +{ + int32_t result = ivc_check_write(ivc); + + if (result != 0) { + return result; + } + + /* + * Order any possible stores to the frame before update of w_pos. + */ + dmbst(); + + ivc_advance_tx(ivc); + + /* + * Ensure our write to w_pos occurs before our read from r_pos. + */ + dmbish(); + + /* + * Notify only upon transition from empty to non-empty. + * The available count can only asynchronously decrease, so the + * worst possible side-effect will be a spurious notification. + */ + if (ivc_channel_avail_count(ivc, ivc->tx_channel) == (uint32_t)1U) { + ivc->notify(ivc); + } + + return 0; +} + +void tegra_ivc_channel_reset(const struct ivc *ivc) +{ + ivc->tx_channel->state = ivc_state_sync; + ivc->notify(ivc); +} + +/* + * =============================================================== + * IVC State Transition Table - see tegra_ivc_channel_notified() + * =============================================================== + * + * local remote action + * ----- ------ ----------------------------------- + * SYNC EST + * SYNC ACK reset counters; move to EST; notify + * SYNC SYNC reset counters; move to ACK; notify + * ACK EST move to EST; notify + * ACK ACK move to EST; notify + * ACK SYNC reset counters; move to ACK; notify + * EST EST + * EST ACK + * EST SYNC reset counters; move to ACK; notify + * + * =============================================================== + */ +int32_t tegra_ivc_channel_notified(struct ivc *ivc) +{ + uint32_t peer_state; + + /* Copy the receiver's state out of shared memory. */ + peer_state = ivc->rx_channel->state; + + if (peer_state == (uint32_t)ivc_state_sync) { + /* + * Order observation of ivc_state_sync before stores clearing + * tx_channel. + */ + dmbld(); + + /* + * Reset tx_channel counters. The remote end is in the SYNC + * state and won't make progress until we change our state, + * so the counters are not in use at this time. + */ + ivc->tx_channel->w_count = 0U; + ivc->rx_channel->r_count = 0U; + + ivc->w_pos = 0U; + ivc->r_pos = 0U; + + /* + * Ensure that counters appear cleared before new state can be + * observed. + */ + dmbst(); + + /* + * Move to ACK state. We have just cleared our counters, so it + * is now safe for the remote end to start using these values. + */ + ivc->tx_channel->state = ivc_state_ack; + + /* + * Notify remote end to observe state transition. + */ + ivc->notify(ivc); + + } else if ((ivc->tx_channel->state == (uint32_t)ivc_state_sync) && + (peer_state == (uint32_t)ivc_state_ack)) { + /* + * Order observation of ivc_state_sync before stores clearing + * tx_channel. + */ + dmbld(); + + /* + * Reset tx_channel counters. The remote end is in the ACK + * state and won't make progress until we change our state, + * so the counters are not in use at this time. + */ + ivc->tx_channel->w_count = 0U; + ivc->rx_channel->r_count = 0U; + + ivc->w_pos = 0U; + ivc->r_pos = 0U; + + /* + * Ensure that counters appear cleared before new state can be + * observed. + */ + dmbst(); + + /* + * Move to ESTABLISHED state. We know that the remote end has + * already cleared its counters, so it is safe to start + * writing/reading on this channel. + */ + ivc->tx_channel->state = ivc_state_established; + + /* + * Notify remote end to observe state transition. + */ + ivc->notify(ivc); + + } else if (ivc->tx_channel->state == (uint32_t)ivc_state_ack) { + /* + * At this point, we have observed the peer to be in either + * the ACK or ESTABLISHED state. Next, order observation of + * peer state before storing to tx_channel. + */ + dmbld(); + + /* + * Move to ESTABLISHED state. We know that we have previously + * cleared our counters, and we know that the remote end has + * cleared its counters, so it is safe to start writing/reading + * on this channel. + */ + ivc->tx_channel->state = ivc_state_established; + + /* + * Notify remote end to observe state transition. + */ + ivc->notify(ivc); + + } else { + /* + * There is no need to handle any further action. Either the + * channel is already fully established, or we are waiting for + * the remote end to catch up with our current state. Refer + * to the diagram in "IVC State Transition Table" above. + */ + } + + return ((ivc->tx_channel->state == (uint32_t)ivc_state_established) ? 0 : -EAGAIN); +} + +size_t tegra_ivc_align(size_t size) +{ + return (size + (IVC_ALIGN - 1U)) & ~(IVC_ALIGN - 1U); +} + +size_t tegra_ivc_total_queue_size(size_t queue_size) +{ + if ((queue_size & (IVC_ALIGN - 1U)) != 0U) { + ERROR("queue_size (%d) must be %d-byte aligned\n", + (int32_t)queue_size, IVC_ALIGN); + return 0; + } + return queue_size + sizeof(struct ivc_channel_header); +} + +static int32_t check_ivc_params(uintptr_t queue_base1, uintptr_t queue_base2, + uint32_t nframes, uint32_t frame_size) +{ + assert((offsetof(struct ivc_channel_header, w_count) + & (IVC_ALIGN - 1U)) == 0U); + assert((offsetof(struct ivc_channel_header, r_count) + & (IVC_ALIGN - 1U)) == 0U); + assert((sizeof(struct ivc_channel_header) & (IVC_ALIGN - 1U)) == 0U); + + if (((uint64_t)nframes * (uint64_t)frame_size) >= 0x100000000ULL) { + ERROR("nframes * frame_size overflows\n"); + return -EINVAL; + } + + /* + * The headers must at least be aligned enough for counters + * to be accessed atomically. + */ + if ((queue_base1 & (IVC_ALIGN - 1U)) != 0U) { + ERROR("ivc channel start not aligned: %lx\n", queue_base1); + return -EINVAL; + } + if ((queue_base2 & (IVC_ALIGN - 1U)) != 0U) { + ERROR("ivc channel start not aligned: %lx\n", queue_base2); + return -EINVAL; + } + + if ((frame_size & (IVC_ALIGN - 1U)) != 0U) { + ERROR("frame size not adequately aligned: %u\n", + frame_size); + return -EINVAL; + } + + if (queue_base1 < queue_base2) { + if ((queue_base1 + ((uint64_t)frame_size * nframes)) > queue_base2) { + ERROR("queue regions overlap: %lx + %x, %x\n", + queue_base1, frame_size, + frame_size * nframes); + return -EINVAL; + } + } else { + if ((queue_base2 + ((uint64_t)frame_size * nframes)) > queue_base1) { + ERROR("queue regions overlap: %lx + %x, %x\n", + queue_base2, frame_size, + frame_size * nframes); + return -EINVAL; + } + } + + return 0; +} + +int32_t tegra_ivc_init(struct ivc *ivc, uintptr_t rx_base, uintptr_t tx_base, + uint32_t nframes, uint32_t frame_size, + ivc_notify_function notify) +{ + int32_t result; + + /* sanity check input params */ + if ((ivc == NULL) || (notify == NULL)) { + return -EINVAL; + } + + result = check_ivc_params(rx_base, tx_base, nframes, frame_size); + if (result != 0) { + return result; + } + + /* + * All sizes that can be returned by communication functions should + * fit in a 32-bit integer. + */ + if (frame_size > (1u << 31)) { + return -E2BIG; + } + + ivc->rx_channel = (struct ivc_channel_header *)rx_base; + ivc->tx_channel = (struct ivc_channel_header *)tx_base; + ivc->notify = notify; + ivc->frame_size = frame_size; + ivc->nframes = nframes; + ivc->w_pos = 0U; + ivc->r_pos = 0U; + + INFO("%s: done\n", __func__); + + return 0; +} diff --git a/plat/nvidia/tegra/drivers/bpmp_ipc/ivc.h b/plat/nvidia/tegra/drivers/bpmp_ipc/ivc.h new file mode 100644 index 000000000..1b318213b --- /dev/null +++ b/plat/nvidia/tegra/drivers/bpmp_ipc/ivc.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2017-2020, NVIDIA Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef BPMP_IVC_H +#define BPMP_IVC_H + +#include +#include +#include + +#define IVC_ALIGN U(64) +#define IVC_CHHDR_TX_FIELDS U(16) +#define IVC_CHHDR_RX_FIELDS U(16) + +struct ivc_channel_header; + +struct ivc { + struct ivc_channel_header *rx_channel; + struct ivc_channel_header *tx_channel; + uint32_t w_pos; + uint32_t r_pos; + void (*notify)(const struct ivc *); + uint32_t nframes; + uint32_t frame_size; +}; + +/* callback handler for notify on receiving a response */ +typedef void (* ivc_notify_function)(const struct ivc *); + +int32_t tegra_ivc_init(struct ivc *ivc, uintptr_t rx_base, uintptr_t tx_base, + uint32_t nframes, uint32_t frame_size, + ivc_notify_function notify); +size_t tegra_ivc_total_queue_size(size_t queue_size); +size_t tegra_ivc_align(size_t size); +int32_t tegra_ivc_channel_notified(struct ivc *ivc); +void tegra_ivc_channel_reset(const struct ivc *ivc); +int32_t tegra_ivc_write_advance(struct ivc *ivc); +void *tegra_ivc_write_get_next_frame(const struct ivc *ivc); +int32_t tegra_ivc_write(struct ivc *ivc, const void *buf, size_t size); +int32_t tegra_ivc_read_advance(struct ivc *ivc); +void *tegra_ivc_read_get_next_frame(const struct ivc *ivc); +int32_t tegra_ivc_read(struct ivc *ivc, void *buf, size_t max_read); +bool tegra_ivc_tx_empty(const struct ivc *ivc); +bool tegra_ivc_can_write(const struct ivc *ivc); +bool tegra_ivc_can_read(const struct ivc *ivc); + +#endif /* BPMP_IVC_H */ diff --git a/plat/nvidia/tegra/drivers/flowctrl/flowctrl.c b/plat/nvidia/tegra/drivers/flowctrl/flowctrl.c new file mode 100644 index 000000000..8f5555459 --- /dev/null +++ b/plat/nvidia/tegra/drivers/flowctrl/flowctrl.c @@ -0,0 +1,322 @@ +/* + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define CLK_RST_DEV_L_SET 0x300 +#define CLK_RST_DEV_L_CLR 0x304 +#define CLK_BPMP_RST (1 << 1) + +#define EVP_BPMP_RESET_VECTOR 0x200 + +static const uint64_t flowctrl_offset_cpu_csr[4] = { + (TEGRA_FLOWCTRL_BASE + FLOWCTRL_CPU0_CSR), + (TEGRA_FLOWCTRL_BASE + FLOWCTRL_CPU1_CSR), + (TEGRA_FLOWCTRL_BASE + FLOWCTRL_CPU1_CSR + 8), + (TEGRA_FLOWCTRL_BASE + FLOWCTRL_CPU1_CSR + 16) +}; + +static const uint64_t flowctrl_offset_halt_cpu[4] = { + (TEGRA_FLOWCTRL_BASE + FLOWCTRL_HALT_CPU0_EVENTS), + (TEGRA_FLOWCTRL_BASE + FLOWCTRL_HALT_CPU1_EVENTS), + (TEGRA_FLOWCTRL_BASE + FLOWCTRL_HALT_CPU1_EVENTS + 8), + (TEGRA_FLOWCTRL_BASE + FLOWCTRL_HALT_CPU1_EVENTS + 16) +}; + +static const uint64_t flowctrl_offset_cc4_ctrl[4] = { + (TEGRA_FLOWCTRL_BASE + FLOWCTRL_CC4_CORE0_CTRL), + (TEGRA_FLOWCTRL_BASE + FLOWCTRL_CC4_CORE0_CTRL + 4), + (TEGRA_FLOWCTRL_BASE + FLOWCTRL_CC4_CORE0_CTRL + 8), + (TEGRA_FLOWCTRL_BASE + FLOWCTRL_CC4_CORE0_CTRL + 12) +}; + +static inline void tegra_fc_cc4_ctrl(int cpu_id, uint32_t val) +{ + mmio_write_32(flowctrl_offset_cc4_ctrl[cpu_id], val); + val = mmio_read_32(flowctrl_offset_cc4_ctrl[cpu_id]); +} + +static inline void tegra_fc_cpu_csr(int cpu_id, uint32_t val) +{ + mmio_write_32(flowctrl_offset_cpu_csr[cpu_id], val); + val = mmio_read_32(flowctrl_offset_cpu_csr[cpu_id]); +} + +static inline void tegra_fc_halt_cpu(int cpu_id, uint32_t val) +{ + mmio_write_32(flowctrl_offset_halt_cpu[cpu_id], val); + val = mmio_read_32(flowctrl_offset_halt_cpu[cpu_id]); +} + +static void tegra_fc_prepare_suspend(int cpu_id, uint32_t csr) +{ + uint32_t val; + + val = FLOWCTRL_HALT_GIC_IRQ | FLOWCTRL_HALT_GIC_FIQ | + FLOWCTRL_HALT_LIC_IRQ | FLOWCTRL_HALT_LIC_FIQ | + FLOWCTRL_WAITEVENT; + tegra_fc_halt_cpu(cpu_id, val); + + val = FLOWCTRL_CSR_INTR_FLAG | FLOWCTRL_CSR_EVENT_FLAG | + FLOWCTRL_CSR_ENABLE | (FLOWCTRL_WAIT_WFI_BITMAP << cpu_id); + tegra_fc_cpu_csr(cpu_id, val | csr); +} + +/******************************************************************************* + * After this, no core can wake from C7 until the action is reverted. + * If a wake up event is asserted, the FC state machine will stall until + * the action is reverted. + ******************************************************************************/ +void tegra_fc_ccplex_pgexit_lock(void) +{ + unsigned int i, cpu = read_mpidr() & MPIDR_CPU_MASK; + uint32_t flags = tegra_fc_read_32(FLOWCTRL_FC_SEQ_INTERCEPT) & ~INTERCEPT_IRQ_PENDING;; + uint32_t icept_cpu_flags[] = { + INTERCEPT_EXIT_PG_CORE0, + INTERCEPT_EXIT_PG_CORE1, + INTERCEPT_EXIT_PG_CORE2, + INTERCEPT_EXIT_PG_CORE3 + }; + + /* set the intercept flags */ + for (i = 0; i < ARRAY_SIZE(icept_cpu_flags); i++) { + + /* skip current CPU */ + if (i == cpu) + continue; + + /* enable power gate exit intercept locks */ + flags |= icept_cpu_flags[i]; + } + + tegra_fc_write_32(FLOWCTRL_FC_SEQ_INTERCEPT, flags); + (void)tegra_fc_read_32(FLOWCTRL_FC_SEQ_INTERCEPT); +} + +/******************************************************************************* + * Revert the ccplex powergate exit locks + ******************************************************************************/ +void tegra_fc_ccplex_pgexit_unlock(void) +{ + /* clear lock bits, clear pending interrupts */ + tegra_fc_write_32(FLOWCTRL_FC_SEQ_INTERCEPT, INTERCEPT_IRQ_PENDING); + (void)tegra_fc_read_32(FLOWCTRL_FC_SEQ_INTERCEPT); +} + +/******************************************************************************* + * Powerdn the current CPU + ******************************************************************************/ +void tegra_fc_cpu_powerdn(uint32_t mpidr) +{ + int cpu = mpidr & MPIDR_CPU_MASK; + + VERBOSE("CPU%d powering down...\n", cpu); + tegra_fc_prepare_suspend(cpu, 0); +} + +/******************************************************************************* + * Suspend the current CPU cluster + ******************************************************************************/ +void tegra_fc_cluster_idle(uint32_t mpidr) +{ + int cpu = mpidr & MPIDR_CPU_MASK; + uint32_t val; + + VERBOSE("Entering cluster idle state...\n"); + + tegra_fc_cc4_ctrl(cpu, 0); + + /* hardware L2 flush is faster for A53 only */ + tegra_fc_write_32(FLOWCTRL_L2_FLUSH_CONTROL, + !!MPIDR_AFFLVL1_VAL(mpidr)); + + /* suspend the CPU cluster */ + val = FLOWCTRL_PG_CPU_NONCPU << FLOWCTRL_ENABLE_EXT; + tegra_fc_prepare_suspend(cpu, val); +} + +/******************************************************************************* + * Power down the current CPU cluster + ******************************************************************************/ +void tegra_fc_cluster_powerdn(uint32_t mpidr) +{ + int cpu = mpidr & MPIDR_CPU_MASK; + uint32_t val; + + VERBOSE("Entering cluster powerdn state...\n"); + + tegra_fc_cc4_ctrl(cpu, 0); + + /* hardware L2 flush is faster for A53 only */ + tegra_fc_write_32(FLOWCTRL_L2_FLUSH_CONTROL, + read_midr() == CORTEX_A53_MIDR); + + /* power down the CPU cluster */ + val = FLOWCTRL_TURNOFF_CPURAIL << FLOWCTRL_ENABLE_EXT; + tegra_fc_prepare_suspend(cpu, val); +} + +/******************************************************************************* + * Check if cluster idle or power down state is allowed from this CPU + ******************************************************************************/ +bool tegra_fc_is_ccx_allowed(void) +{ + unsigned int i, cpu = read_mpidr() & MPIDR_CPU_MASK; + uint32_t val; + bool ccx_allowed = true; + + for (i = 0; i < ARRAY_SIZE(flowctrl_offset_cpu_csr); i++) { + + /* skip current CPU */ + if (i == cpu) + continue; + + /* check if all other CPUs are already halted */ + val = mmio_read_32(flowctrl_offset_cpu_csr[i]); + if ((val & FLOWCTRL_CSR_HALT_MASK) == 0U) { + ccx_allowed = false; + } + } + + return ccx_allowed; +} + +/******************************************************************************* + * Suspend the entire SoC + ******************************************************************************/ +void tegra_fc_soc_powerdn(uint32_t mpidr) +{ + int cpu = mpidr & MPIDR_CPU_MASK; + uint32_t val; + + VERBOSE("Entering SoC powerdn state...\n"); + + tegra_fc_cc4_ctrl(cpu, 0); + + tegra_fc_write_32(FLOWCTRL_L2_FLUSH_CONTROL, 1); + + val = FLOWCTRL_TURNOFF_CPURAIL << FLOWCTRL_ENABLE_EXT; + tegra_fc_prepare_suspend(cpu, val); + + /* overwrite HALT register */ + tegra_fc_halt_cpu(cpu, FLOWCTRL_WAITEVENT); +} + +/******************************************************************************* + * Power up the CPU + ******************************************************************************/ +void tegra_fc_cpu_on(int cpu) +{ + tegra_fc_cpu_csr(cpu, FLOWCTRL_CSR_ENABLE); + tegra_fc_halt_cpu(cpu, FLOWCTRL_WAITEVENT | FLOWCTRL_HALT_SCLK); +} + +/******************************************************************************* + * Power down the CPU + ******************************************************************************/ +void tegra_fc_cpu_off(int cpu) +{ + uint32_t val; + + /* + * Flow controller powers down the CPU during wfi. The CPU would be + * powered on when it receives any interrupt. + */ + val = FLOWCTRL_CSR_INTR_FLAG | FLOWCTRL_CSR_EVENT_FLAG | + FLOWCTRL_CSR_ENABLE | (FLOWCTRL_WAIT_WFI_BITMAP << cpu); + tegra_fc_cpu_csr(cpu, val); + tegra_fc_halt_cpu(cpu, FLOWCTRL_WAITEVENT); + tegra_fc_cc4_ctrl(cpu, 0); +} + +/******************************************************************************* + * Inform the BPMP that we have completed the cluster power up + ******************************************************************************/ +void tegra_fc_lock_active_cluster(void) +{ + uint32_t val; + + val = tegra_fc_read_32(FLOWCTRL_BPMP_CLUSTER_CONTROL); + val |= FLOWCTRL_BPMP_CLUSTER_PWRON_LOCK; + tegra_fc_write_32(FLOWCTRL_BPMP_CLUSTER_CONTROL, val); + val = tegra_fc_read_32(FLOWCTRL_BPMP_CLUSTER_CONTROL); +} + +/******************************************************************************* + * Power ON BPMP processor + ******************************************************************************/ +void tegra_fc_bpmp_on(uint32_t entrypoint) +{ + /* halt BPMP */ + tegra_fc_write_32(FLOWCTRL_HALT_BPMP_EVENTS, FLOWCTRL_WAITEVENT); + + /* Assert BPMP reset */ + mmio_write_32(TEGRA_CAR_RESET_BASE + CLK_RST_DEV_L_SET, CLK_BPMP_RST); + + /* Set reset address (stored in PMC_SCRATCH39) */ + mmio_write_32(TEGRA_EVP_BASE + EVP_BPMP_RESET_VECTOR, entrypoint); + while (entrypoint != mmio_read_32(TEGRA_EVP_BASE + EVP_BPMP_RESET_VECTOR)) + ; /* wait till value reaches EVP_BPMP_RESET_VECTOR */ + + /* Wait for 2us before de-asserting the reset signal. */ + udelay(2); + + /* De-assert BPMP reset */ + mmio_write_32(TEGRA_CAR_RESET_BASE + CLK_RST_DEV_L_CLR, CLK_BPMP_RST); + + /* Un-halt BPMP */ + tegra_fc_write_32(FLOWCTRL_HALT_BPMP_EVENTS, 0); +} + +/******************************************************************************* + * Power OFF BPMP processor + ******************************************************************************/ +void tegra_fc_bpmp_off(void) +{ + /* halt BPMP */ + tegra_fc_write_32(FLOWCTRL_HALT_BPMP_EVENTS, FLOWCTRL_WAITEVENT); + + /* Assert BPMP reset */ + mmio_write_32(TEGRA_CAR_RESET_BASE + CLK_RST_DEV_L_SET, CLK_BPMP_RST); + + /* Clear reset address */ + mmio_write_32(TEGRA_EVP_BASE + EVP_BPMP_RESET_VECTOR, 0); + while (0 != mmio_read_32(TEGRA_EVP_BASE + EVP_BPMP_RESET_VECTOR)) + ; /* wait till value reaches EVP_BPMP_RESET_VECTOR */ +} + +/******************************************************************************* + * Route legacy FIQ to the GICD + ******************************************************************************/ +void tegra_fc_enable_fiq_to_ccplex_routing(void) +{ + uint32_t val = tegra_fc_read_32(FLOW_CTLR_FLOW_DBG_QUAL); + + /* set the bit to pass FIQs to the GICD */ + tegra_fc_write_32(FLOW_CTLR_FLOW_DBG_QUAL, val | FLOWCTRL_FIQ2CCPLEX_ENABLE); +} + +/******************************************************************************* + * Disable routing legacy FIQ to the GICD + ******************************************************************************/ +void tegra_fc_disable_fiq_to_ccplex_routing(void) +{ + uint32_t val = tegra_fc_read_32(FLOW_CTLR_FLOW_DBG_QUAL); + + /* clear the bit to pass FIQs to the GICD */ + tegra_fc_write_32(FLOW_CTLR_FLOW_DBG_QUAL, val & ~FLOWCTRL_FIQ2CCPLEX_ENABLE); +} diff --git a/plat/nvidia/tegra/drivers/gpcdma/gpcdma.c b/plat/nvidia/tegra/drivers/gpcdma/gpcdma.c new file mode 100644 index 000000000..d68cdfd4b --- /dev/null +++ b/plat/nvidia/tegra/drivers/gpcdma/gpcdma.c @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* DMA channel registers */ +#define DMA_CH_CSR U(0x0) +#define DMA_CH_CSR_WEIGHT_SHIFT U(10) +#define DMA_CH_CSR_XFER_MODE_SHIFT U(21) +#define DMA_CH_CSR_DMA_MODE_MEM2MEM U(4) +#define DMA_CH_CSR_DMA_MODE_FIXEDPATTERN U(6) +#define DMA_CH_CSR_IRQ_MASK_ENABLE (U(1) << 15) +#define DMA_CH_CSR_RUN_ONCE (U(1) << 27) +#define DMA_CH_CSR_ENABLE (U(1) << 31) + +#define DMA_CH_STAT U(0x4) +#define DMA_CH_STAT_BUSY (U(1) << 31) + +#define DMA_CH_SRC_PTR U(0xC) + +#define DMA_CH_DST_PTR U(0x10) + +#define DMA_CH_HI_ADR_PTR U(0x14) +#define DMA_CH_HI_ADR_PTR_SRC_MASK U(0xFF) +#define DMA_CH_HI_ADR_PTR_DST_SHIFT U(16) +#define DMA_CH_HI_ADR_PTR_DST_MASK U(0xFF) + +#define DMA_CH_MC_SEQ U(0x18) +#define DMA_CH_MC_SEQ_REQ_CNT_SHIFT U(25) +#define DMA_CH_MC_SEQ_REQ_CNT_VAL U(0x10) +#define DMA_CH_MC_SEQ_BURST_SHIFT U(23) +#define DMA_CH_MC_SEQ_BURST_16_WORDS U(0x3) + +#define DMA_CH_WORD_COUNT U(0x20) +#define DMA_CH_FIXED_PATTERN U(0x34) +#define DMA_CH_TZ U(0x38) +#define DMA_CH_TZ_ACCESS_ENABLE U(0) +#define DMA_CH_TZ_ACCESS_DISABLE U(3) + +#define MAX_TRANSFER_SIZE (1U*1024U*1024U*1024U) /* 1GB */ +#define GPCDMA_TIMEOUT_MS U(100) +#define GPCDMA_RESET_BIT (U(1) << 1) + +static bool init_done; + +static void tegra_gpcdma_write32(uint32_t offset, uint32_t val) +{ + mmio_write_32(TEGRA_GPCDMA_BASE + offset, val); +} + +static uint32_t tegra_gpcdma_read32(uint32_t offset) +{ + return mmio_read_32(TEGRA_GPCDMA_BASE + offset); +} + +static void tegra_gpcdma_init(void) +{ + /* assert reset for DMA engine */ + mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_GPCDMA_RST_SET_REG_OFFSET, + GPCDMA_RESET_BIT); + + udelay(2); + + /* de-assert reset for DMA engine */ + mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_GPCDMA_RST_CLR_REG_OFFSET, + GPCDMA_RESET_BIT); +} + +static void tegra_gpcdma_memcpy_priv(uint64_t dst_addr, uint64_t src_addr, + uint32_t num_bytes, uint32_t mode) +{ + uint32_t val, timeout = 0; + int32_t ret = 0; + + /* sanity check byte count */ + if ((num_bytes > MAX_TRANSFER_SIZE) || ((num_bytes & 0x3U) != U(0))) { + ret = -EINVAL; + } + + /* initialise GPCDMA block */ + if (!init_done) { + tegra_gpcdma_init(); + init_done = true; + } + + /* make sure channel isn't busy */ + val = tegra_gpcdma_read32(DMA_CH_STAT); + if ((val & DMA_CH_STAT_BUSY) == DMA_CH_STAT_BUSY) { + ERROR("DMA channel is busy\n"); + ret = -EBUSY; + } + + if (ret == 0) { + + /* disable any DMA transfers */ + tegra_gpcdma_write32(DMA_CH_CSR, 0); + + /* enable DMA access to TZDRAM */ + tegra_gpcdma_write32(DMA_CH_TZ, DMA_CH_TZ_ACCESS_ENABLE); + + /* configure MC sequencer */ + val = (DMA_CH_MC_SEQ_REQ_CNT_VAL << DMA_CH_MC_SEQ_REQ_CNT_SHIFT) | + (DMA_CH_MC_SEQ_BURST_16_WORDS << DMA_CH_MC_SEQ_BURST_SHIFT); + tegra_gpcdma_write32(DMA_CH_MC_SEQ, val); + + /* reset fixed pattern */ + tegra_gpcdma_write32(DMA_CH_FIXED_PATTERN, 0); + + /* populate src and dst address registers */ + tegra_gpcdma_write32(DMA_CH_SRC_PTR, (uint32_t)src_addr); + tegra_gpcdma_write32(DMA_CH_DST_PTR, (uint32_t)dst_addr); + + val = (uint32_t)((src_addr >> 32) & DMA_CH_HI_ADR_PTR_SRC_MASK); + val |= (uint32_t)(((dst_addr >> 32) & DMA_CH_HI_ADR_PTR_DST_MASK) << + DMA_CH_HI_ADR_PTR_DST_SHIFT); + tegra_gpcdma_write32(DMA_CH_HI_ADR_PTR, val); + + /* transfer size (in words) */ + tegra_gpcdma_write32(DMA_CH_WORD_COUNT, ((num_bytes >> 2) - 1U)); + + /* populate value for CSR */ + val = (mode << DMA_CH_CSR_XFER_MODE_SHIFT) | + DMA_CH_CSR_RUN_ONCE | (U(1) << DMA_CH_CSR_WEIGHT_SHIFT) | + DMA_CH_CSR_IRQ_MASK_ENABLE; + tegra_gpcdma_write32(DMA_CH_CSR, val); + + /* enable transfer */ + val = tegra_gpcdma_read32(DMA_CH_CSR); + val |= DMA_CH_CSR_ENABLE; + tegra_gpcdma_write32(DMA_CH_CSR, val); + + /* wait till transfer completes */ + do { + + /* read the status */ + val = tegra_gpcdma_read32(DMA_CH_STAT); + if ((val & DMA_CH_STAT_BUSY) != DMA_CH_STAT_BUSY) { + break; + } + + mdelay(1); + timeout++; + + } while (timeout < GPCDMA_TIMEOUT_MS); + + /* flag timeout error */ + if (timeout == GPCDMA_TIMEOUT_MS) { + ERROR("DMA transfer timed out\n"); + } + + dsbsy(); + + /* disable DMA access to TZDRAM */ + tegra_gpcdma_write32(DMA_CH_TZ, DMA_CH_TZ_ACCESS_DISABLE); + isb(); + } +} + +/******************************************************************************* + * Memcpy using GPCDMA block (Mem2Mem copy) + ******************************************************************************/ +void tegra_gpcdma_memcpy(uint64_t dst_addr, uint64_t src_addr, + uint32_t num_bytes) +{ + tegra_gpcdma_memcpy_priv(dst_addr, src_addr, num_bytes, + DMA_CH_CSR_DMA_MODE_MEM2MEM); +} + +/******************************************************************************* + * Memset using GPCDMA block (Fixed pattern write) + ******************************************************************************/ +void tegra_gpcdma_zeromem(uint64_t dst_addr, uint32_t num_bytes) +{ + tegra_gpcdma_memcpy_priv(dst_addr, 0, num_bytes, + DMA_CH_CSR_DMA_MODE_FIXEDPATTERN); +} diff --git a/plat/nvidia/tegra/drivers/memctrl/memctrl_v1.c b/plat/nvidia/tegra/drivers/memctrl/memctrl_v1.c new file mode 100644 index 000000000..c3f95db4d --- /dev/null +++ b/plat/nvidia/tegra/drivers/memctrl/memctrl_v1.c @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +/* Video Memory base and size (live values) */ +static uint64_t video_mem_base; +static uint64_t video_mem_size; + +/* + * Init SMMU. + */ +void tegra_memctrl_setup(void) +{ + /* + * Setup the Memory controller to allow only secure accesses to + * the TZDRAM carveout + */ + INFO("Tegra Memory Controller (v1)\n"); + + /* allow translations for all MC engines */ + tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_0_0, + (unsigned int)MC_SMMU_TRANSLATION_ENABLE); + tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_1_0, + (unsigned int)MC_SMMU_TRANSLATION_ENABLE); + tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_2_0, + (unsigned int)MC_SMMU_TRANSLATION_ENABLE); + tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_3_0, + (unsigned int)MC_SMMU_TRANSLATION_ENABLE); + tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_4_0, + (unsigned int)MC_SMMU_TRANSLATION_ENABLE); + + tegra_mc_write_32(MC_SMMU_ASID_SECURITY_0, MC_SMMU_ASID_SECURITY); + + tegra_mc_write_32(MC_SMMU_TLB_CONFIG_0, MC_SMMU_TLB_CONFIG_0_RESET_VAL); + tegra_mc_write_32(MC_SMMU_PTC_CONFIG_0, MC_SMMU_PTC_CONFIG_0_RESET_VAL); + + /* flush PTC and TLB */ + tegra_mc_write_32(MC_SMMU_PTC_FLUSH_0, MC_SMMU_PTC_FLUSH_ALL); + (void)tegra_mc_read_32(MC_SMMU_CONFIG_0); /* read to flush writes */ + tegra_mc_write_32(MC_SMMU_TLB_FLUSH_0, MC_SMMU_TLB_FLUSH_ALL); + + /* enable SMMU */ + tegra_mc_write_32(MC_SMMU_CONFIG_0, + MC_SMMU_CONFIG_0_SMMU_ENABLE_ENABLE); + (void)tegra_mc_read_32(MC_SMMU_CONFIG_0); /* read to flush writes */ + + /* video memory carveout */ + tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI, + (uint32_t)(video_mem_base >> 32)); + tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO, (uint32_t)video_mem_base); + tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, video_mem_size); +} + +/* + * Restore Memory Controller settings after "System Suspend" + */ +void tegra_memctrl_restore_settings(void) +{ + tegra_memctrl_setup(); +} + +/* + * Secure the BL31 DRAM aperture. + * + * phys_base = physical base of TZDRAM aperture + * size_in_bytes = size of aperture in bytes + */ +void tegra_memctrl_tzdram_setup(uint64_t phys_base, uint32_t size_in_bytes) +{ + /* + * Setup the Memory controller to allow only secure accesses to + * the TZDRAM carveout + */ + INFO("Configuring TrustZone DRAM Memory Carveout\n"); + + tegra_mc_write_32(MC_SECURITY_CFG0_0, phys_base); + tegra_mc_write_32(MC_SECURITY_CFG1_0, size_in_bytes >> 20); +} + +/* + * Secure the BL31 TZRAM aperture. + * + * phys_base = physical base of TZRAM aperture + * size_in_bytes = size of aperture in bytes + */ +void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes) +{ + /* + * The v1 hardware controller does not have any registers + * for setting up the on-chip TZRAM. + */ +} + +static void tegra_clear_videomem(uintptr_t non_overlap_area_start, + unsigned long long non_overlap_area_size) +{ + int ret; + + /* + * Map the NS memory first, clean it and then unmap it. + */ + ret = mmap_add_dynamic_region(non_overlap_area_start, /* PA */ + non_overlap_area_start, /* VA */ + non_overlap_area_size, /* size */ + MT_NS | MT_RW | MT_EXECUTE_NEVER | + MT_NON_CACHEABLE); /* attrs */ + assert(ret == 0); + + zeromem((void *)non_overlap_area_start, non_overlap_area_size); + flush_dcache_range(non_overlap_area_start, non_overlap_area_size); + + mmap_remove_dynamic_region(non_overlap_area_start, + non_overlap_area_size); +} + +/* + * Program the Video Memory carveout region + * + * phys_base = physical base of aperture + * size_in_bytes = size of aperture in bytes + */ +void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes) +{ + uintptr_t vmem_end_old = video_mem_base + (video_mem_size << 20); + uintptr_t vmem_end_new = phys_base + size_in_bytes; + unsigned long long non_overlap_area_size; + + /* + * Setup the Memory controller to restrict CPU accesses to the Video + * Memory region + */ + INFO("Configuring Video Memory Carveout\n"); + + /* + * Configure Memory Controller directly for the first time. + */ + if (video_mem_base == 0) + goto done; + + /* + * Clear the old regions now being exposed. The following cases + * can occur - + * + * 1. clear whole old region (no overlap with new region) + * 2. clear old sub-region below new base + * 3. clear old sub-region above new end + */ + INFO("Cleaning previous Video Memory Carveout\n"); + + if (phys_base > vmem_end_old || video_mem_base > vmem_end_new) { + tegra_clear_videomem(video_mem_base, video_mem_size << 20); + } else { + if (video_mem_base < phys_base) { + non_overlap_area_size = phys_base - video_mem_base; + tegra_clear_videomem(video_mem_base, non_overlap_area_size); + } + if (vmem_end_old > vmem_end_new) { + non_overlap_area_size = vmem_end_old - vmem_end_new; + tegra_clear_videomem(vmem_end_new, non_overlap_area_size); + } + } + +done: + tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI, (uint32_t)(phys_base >> 32)); + tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO, (uint32_t)phys_base); + tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, size_in_bytes >> 20); + + /* store new values */ + video_mem_base = phys_base; + video_mem_size = size_in_bytes >> 20; +} + +/* + * During boot, USB3 and flash media (SDMMC/SATA) devices need access to + * IRAM. Because these clients connect to the MC and do not have a direct + * path to the IRAM, the MC implements AHB redirection during boot to allow + * path to IRAM. In this mode, accesses to a programmed memory address aperture + * are directed to the AHB bus, allowing access to the IRAM. The AHB aperture + * is defined by the IRAM_BASE_LO and IRAM_BASE_HI registers, which are + * initialized to disable this aperture. + * + * Once bootup is complete, we must program IRAM base to 0xffffffff and + * IRAM top to 0x00000000, thus disabling access to IRAM. DRAM is then + * potentially accessible in this address range. These aperture registers + * also have an access_control/lock bit. After disabling the aperture, the + * access_control register should be programmed to lock the registers. + */ +void tegra_memctrl_disable_ahb_redirection(void) +{ + /* program the aperture registers */ + tegra_mc_write_32(MC_IRAM_BASE_LO, 0xFFFFFFFF); + tegra_mc_write_32(MC_IRAM_TOP_LO, 0); + tegra_mc_write_32(MC_IRAM_BASE_TOP_HI, 0); + + /* lock the aperture registers */ + tegra_mc_write_32(MC_IRAM_REG_CTRL, MC_DISABLE_IRAM_CFG_WRITES); +} + +void tegra_memctrl_clear_pending_interrupts(void) +{ + uint32_t mcerr; + + /* check if there are any pending interrupts */ + mcerr = mmio_read_32(TEGRA_MC_BASE + MC_INTSTATUS); + + if (mcerr != (uint32_t)0U) { /* should not see error here */ + WARN("MC_INTSTATUS = 0x%x (should be zero)\n", mcerr); + mmio_write_32((TEGRA_MC_BASE + MC_INTSTATUS), mcerr); + } +} diff --git a/plat/nvidia/tegra/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/drivers/memctrl/memctrl_v2.c new file mode 100644 index 000000000..4d69ccca3 --- /dev/null +++ b/plat/nvidia/tegra/drivers/memctrl/memctrl_v2.c @@ -0,0 +1,392 @@ +/* + * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, NVIDIA Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/* Video Memory base and size (live values) */ +static uint64_t video_mem_base; +static uint64_t video_mem_size_mb; + +/* + * Init Memory controller during boot. + */ +void tegra_memctrl_setup(void) +{ + uint32_t val; + const uint32_t *mc_streamid_override_regs; + uint32_t num_streamid_override_regs; + const mc_streamid_security_cfg_t *mc_streamid_sec_cfgs; + uint32_t num_streamid_sec_cfgs; + const tegra_mc_settings_t *plat_mc_settings = tegra_get_mc_settings(); + uint32_t i; + + INFO("Tegra Memory Controller (v2)\n"); + + /* Program the SMMU pagesize */ + tegra_smmu_init(); + + /* Get the settings from the platform */ + assert(plat_mc_settings != NULL); + mc_streamid_override_regs = plat_mc_settings->streamid_override_cfg; + num_streamid_override_regs = plat_mc_settings->num_streamid_override_cfgs; + mc_streamid_sec_cfgs = plat_mc_settings->streamid_security_cfg; + num_streamid_sec_cfgs = plat_mc_settings->num_streamid_security_cfgs; + + /* Program all the Stream ID overrides */ + for (i = 0; i < num_streamid_override_regs; i++) + tegra_mc_streamid_write_32(mc_streamid_override_regs[i], + MC_STREAM_ID_MAX); + + /* Program the security config settings for all Stream IDs */ + for (i = 0; i < num_streamid_sec_cfgs; i++) { + val = mc_streamid_sec_cfgs[i].override_enable << 16 | + mc_streamid_sec_cfgs[i].override_client_inputs << 8 | + mc_streamid_sec_cfgs[i].override_client_ns_flag << 0; + tegra_mc_streamid_write_32(mc_streamid_sec_cfgs[i].offset, val); + } + + /* + * All requests at boot time, and certain requests during + * normal run time, are physically addressed and must bypass + * the SMMU. The client hub logic implements a hardware bypass + * path around the Translation Buffer Units (TBU). During + * boot-time, the SMMU_BYPASS_CTRL register (which defaults to + * TBU_BYPASS mode) will be used to steer all requests around + * the uninitialized TBUs. During normal operation, this register + * is locked into TBU_BYPASS_SID config, which routes requests + * with special StreamID 0x7f on the bypass path and all others + * through the selected TBU. This is done to disable SMMU Bypass + * mode, as it could be used to circumvent SMMU security checks. + */ + tegra_mc_write_32(MC_SMMU_BYPASS_CONFIG, + MC_SMMU_BYPASS_CONFIG_SETTINGS); + + /* + * Re-configure MSS to allow ROC to deal with ordering of the + * Memory Controller traffic. This is needed as the Memory Controller + * boots with MSS having all control, but ROC provides a performance + * boost as compared to MSS. + */ + if (plat_mc_settings->reconfig_mss_clients != NULL) { + plat_mc_settings->reconfig_mss_clients(); + } + + /* Program overrides for MC transactions */ + if (plat_mc_settings->set_txn_overrides != NULL) { + plat_mc_settings->set_txn_overrides(); + } +} + +/* + * Restore Memory Controller settings after "System Suspend" + */ +void tegra_memctrl_restore_settings(void) +{ + const tegra_mc_settings_t *plat_mc_settings = tegra_get_mc_settings(); + + assert(plat_mc_settings != NULL); + + /* + * Re-configure MSS to allow ROC to deal with ordering of the + * Memory Controller traffic. This is needed as the Memory Controller + * resets during System Suspend with MSS having all control, but ROC + * provides a performance boost as compared to MSS. + */ + if (plat_mc_settings->reconfig_mss_clients != NULL) { + plat_mc_settings->reconfig_mss_clients(); + } + + /* Program overrides for MC transactions */ + if (plat_mc_settings->set_txn_overrides != NULL) { + plat_mc_settings->set_txn_overrides(); + } + + /* video memory carveout region */ + if (video_mem_base != 0ULL) { + tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO, + (uint32_t)video_mem_base); + tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI, + (uint32_t)(video_mem_base >> 32)); + tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, video_mem_size_mb); + + /* + * MCE propagates the VideoMem configuration values across the + * CCPLEX. + */ + mce_update_gsc_videomem(); + } +} + +/* + * Secure the BL31 DRAM aperture. + * + * phys_base = physical base of TZDRAM aperture + * size_in_bytes = size of aperture in bytes + */ +void tegra_memctrl_tzdram_setup(uint64_t phys_base, uint32_t size_in_bytes) +{ + /* + * Perform platform specific steps. + */ + plat_memctrl_tzdram_setup(phys_base, size_in_bytes); +} + +/* + * Secure the BL31 TZRAM aperture. + * + * phys_base = physical base of TZRAM aperture + * size_in_bytes = size of aperture in bytes + */ +void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes) +{ + ; /* do nothing */ +} + +/* + * Save MC settings before "System Suspend" to TZDRAM + */ +void tegra_mc_save_context(uint64_t mc_ctx_addr) +{ + const tegra_mc_settings_t *plat_mc_settings = tegra_get_mc_settings(); + uint32_t i, num_entries = 0; + mc_regs_t *mc_ctx_regs; + const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); + uint64_t tzdram_base = params_from_bl2->tzdram_base; + uint64_t tzdram_end = tzdram_base + params_from_bl2->tzdram_size; + + assert((mc_ctx_addr >= tzdram_base) && (mc_ctx_addr <= tzdram_end)); + + /* get MC context table */ + mc_ctx_regs = plat_mc_settings->get_mc_system_suspend_ctx(); + assert(mc_ctx_regs != NULL); + + /* + * mc_ctx_regs[0].val contains the size of the context table minus + * the last entry. Sanity check the table size before we start with + * the context save operation. + */ + while (mc_ctx_regs[num_entries].reg != 0xFFFFFFFFU) { + num_entries++; + } + + /* panic if the sizes do not match */ + if (num_entries != mc_ctx_regs[0].val) { + ERROR("MC context size mismatch!"); + panic(); + } + + /* save MC register values */ + for (i = 1U; i < num_entries; i++) { + mc_ctx_regs[i].val = mmio_read_32(mc_ctx_regs[i].reg); + } + + /* increment by 1 to take care of the last entry */ + num_entries++; + + /* Save MC config settings */ + (void)memcpy((void *)mc_ctx_addr, mc_ctx_regs, + sizeof(mc_regs_t) * num_entries); + + /* save the MC table address */ + mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_MC_TABLE_ADDR_LO, + (uint32_t)mc_ctx_addr); + mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_MC_TABLE_ADDR_HI, + (uint32_t)(mc_ctx_addr >> 32)); +} + +static void tegra_lock_videomem_nonoverlap(uint64_t phys_base, + uint64_t size_in_bytes) +{ + uint32_t index; + uint64_t total_128kb_blocks = size_in_bytes >> 17; + uint64_t residual_4kb_blocks = (size_in_bytes & (uint32_t)0x1FFFF) >> 12; + uint64_t val; + + /* + * Reset the access configuration registers to restrict access to + * old Videomem aperture + */ + for (index = MC_VIDEO_PROTECT_CLEAR_ACCESS_CFG0; + index < ((uint32_t)MC_VIDEO_PROTECT_CLEAR_ACCESS_CFG0 + (uint32_t)MC_GSC_CONFIG_REGS_SIZE); + index += 4U) { + tegra_mc_write_32(index, 0); + } + + /* + * Set the base. It must be 4k aligned, at least. + */ + assert((phys_base & (uint64_t)0xFFF) == 0U); + tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_BASE_LO, (uint32_t)phys_base); + tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_BASE_HI, + (uint32_t)(phys_base >> 32) & (uint32_t)MC_GSC_BASE_HI_MASK); + + /* + * Set the aperture size + * + * total size = (number of 128KB blocks) + (number of remaining 4KB + * blocks) + * + */ + val = (uint32_t)((residual_4kb_blocks << MC_GSC_SIZE_RANGE_4KB_SHIFT) | + total_128kb_blocks); + tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_SIZE, (uint32_t)val); + + /* + * Lock the configuration settings by enabling TZ-only lock and + * locking the configuration against any future changes from NS + * world. + */ + tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_CFG, + (uint32_t)MC_GSC_ENABLE_TZ_LOCK_BIT); + + /* + * MCE propagates the GSC configuration values across the + * CCPLEX. + */ +} + +static void tegra_unlock_videomem_nonoverlap(void) +{ + /* Clear the base */ + tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_BASE_LO, 0); + tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_BASE_HI, 0); + + /* Clear the size */ + tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_SIZE, 0); +} + +static void tegra_clear_videomem(uintptr_t non_overlap_area_start, + unsigned long long non_overlap_area_size) +{ + int ret; + + INFO("Cleaning previous Video Memory Carveout\n"); + + /* + * Map the NS memory first, clean it and then unmap it. + */ + ret = mmap_add_dynamic_region(non_overlap_area_start, /* PA */ + non_overlap_area_start, /* VA */ + non_overlap_area_size, /* size */ + MT_DEVICE | MT_RW | MT_NS); /* attrs */ + assert(ret == 0); + + zeromem((void *)non_overlap_area_start, non_overlap_area_size); + flush_dcache_range(non_overlap_area_start, non_overlap_area_size); + + ret = mmap_remove_dynamic_region(non_overlap_area_start, + non_overlap_area_size); + assert(ret == 0); +} + +static void tegra_clear_videomem_nonoverlap(uintptr_t phys_base, + unsigned long size_in_bytes) +{ + uintptr_t vmem_end_old = video_mem_base + (video_mem_size_mb << 20); + uintptr_t vmem_end_new = phys_base + size_in_bytes; + unsigned long long non_overlap_area_size; + + /* + * Clear the old regions now being exposed. The following cases + * can occur - + * + * 1. clear whole old region (no overlap with new region) + * 2. clear old sub-region below new base + * 3. clear old sub-region above new end + */ + if ((phys_base > vmem_end_old) || (video_mem_base > vmem_end_new)) { + tegra_clear_videomem(video_mem_base, + video_mem_size_mb << 20U); + } else { + if (video_mem_base < phys_base) { + non_overlap_area_size = phys_base - video_mem_base; + tegra_clear_videomem(video_mem_base, non_overlap_area_size); + } + if (vmem_end_old > vmem_end_new) { + non_overlap_area_size = vmem_end_old - vmem_end_new; + tegra_clear_videomem(vmem_end_new, non_overlap_area_size); + } + } +} + +/* + * Program the Video Memory carveout region + * + * phys_base = physical base of aperture + * size_in_bytes = size of aperture in bytes + */ +void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes) +{ + /* + * Setup the Memory controller to restrict CPU accesses to the Video + * Memory region + */ + + INFO("Configuring Video Memory Carveout\n"); + + if (video_mem_base != 0U) { + /* + * Lock the non overlapping memory being cleared so that + * other masters do not accidently write to it. The memory + * would be unlocked once the non overlapping region is + * cleared and the new memory settings take effect. + */ + tegra_lock_videomem_nonoverlap(video_mem_base, + video_mem_size_mb << 20); + } + + /* program the Videomem aperture */ + tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO, (uint32_t)phys_base); + tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI, + (uint32_t)(phys_base >> 32)); + tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, size_in_bytes >> 20); + + /* + * MCE propagates the VideoMem configuration values across the + * CCPLEX. + */ + (void)mce_update_gsc_videomem(); + + /* Clear the non-overlapping memory */ + if (video_mem_base != 0U) { + tegra_clear_videomem_nonoverlap(phys_base, size_in_bytes); + tegra_unlock_videomem_nonoverlap(); + } + + /* store new values */ + video_mem_base = phys_base; + video_mem_size_mb = (uint64_t)size_in_bytes >> 20; +} + +/* + * This feature exists only for v1 of the Tegra Memory Controller. + */ +void tegra_memctrl_disable_ahb_redirection(void) +{ + ; /* do nothing */ +} + +void tegra_memctrl_clear_pending_interrupts(void) +{ + ; /* do nothing */ +} diff --git a/plat/nvidia/tegra/drivers/pmc/pmc.c b/plat/nvidia/tegra/drivers/pmc/pmc.c new file mode 100644 index 000000000..6c5a73baf --- /dev/null +++ b/plat/nvidia/tegra/drivers/pmc/pmc.c @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include + +#include +#include + +#define RESET_ENABLE 0x10U + +/* Module IDs used during power ungate procedure */ +static const uint32_t pmc_cpu_powergate_id[4] = { + 14, /* CPU 0 */ + 9, /* CPU 1 */ + 10, /* CPU 2 */ + 11 /* CPU 3 */ +}; + +/******************************************************************************* + * Power ungate CPU to start the boot process. CPU reset vectors must be + * populated before calling this function. + ******************************************************************************/ +void tegra_pmc_cpu_on(int32_t cpu) +{ + uint32_t val; + + /* + * Check if CPU is already power ungated + */ + val = tegra_pmc_read_32(PMC_PWRGATE_STATUS); + if ((val & (1U << pmc_cpu_powergate_id[cpu])) == 0U) { + /* + * The PMC deasserts the START bit when it starts the power + * ungate process. Loop till no power toggle is in progress. + */ + do { + val = tegra_pmc_read_32(PMC_PWRGATE_TOGGLE); + } while ((val & PMC_TOGGLE_START) != 0U); + + /* + * Start the power ungate procedure + */ + val = pmc_cpu_powergate_id[cpu] | PMC_TOGGLE_START; + tegra_pmc_write_32(PMC_PWRGATE_TOGGLE, val); + + /* + * The PMC deasserts the START bit when it starts the power + * ungate process. Loop till powergate START bit is asserted. + */ + do { + val = tegra_pmc_read_32(PMC_PWRGATE_TOGGLE); + } while ((val & (1U << 8)) != 0U); + + /* loop till the CPU is power ungated */ + do { + val = tegra_pmc_read_32(PMC_PWRGATE_STATUS); + } while ((val & (1U << pmc_cpu_powergate_id[cpu])) == 0U); + } +} + +/******************************************************************************* + * Setup CPU vectors for resume from deep sleep + ******************************************************************************/ +void tegra_pmc_cpu_setup(uint64_t reset_addr) +{ + uint32_t val; + + tegra_pmc_write_32(PMC_SECURE_SCRATCH34, + ((uint32_t)reset_addr & 0xFFFFFFFFU) | 1U); + val = (uint32_t)(reset_addr >> 32U); + tegra_pmc_write_32(PMC_SECURE_SCRATCH35, val & 0x7FFU); +} + +/******************************************************************************* + * Lock CPU vectors to restrict further writes + ******************************************************************************/ +void tegra_pmc_lock_cpu_vectors(void) +{ + uint32_t val; + + /* lock PMC_SECURE_SCRATCH22 */ + val = tegra_pmc_read_32(PMC_SECURE_DISABLE2); + val |= PMC_SECURE_DISABLE2_WRITE22_ON; + tegra_pmc_write_32(PMC_SECURE_DISABLE2, val); + + /* lock PMC_SECURE_SCRATCH34/35 */ + val = tegra_pmc_read_32(PMC_SECURE_DISABLE3); + val |= (PMC_SECURE_DISABLE3_WRITE34_ON | + PMC_SECURE_DISABLE3_WRITE35_ON); + tegra_pmc_write_32(PMC_SECURE_DISABLE3, val); +} + +/******************************************************************************* + * Find out if this is the last standing CPU + ******************************************************************************/ +bool tegra_pmc_is_last_on_cpu(void) +{ + int i, cpu = read_mpidr() & MPIDR_CPU_MASK; + uint32_t val = tegra_pmc_read_32(PMC_PWRGATE_STATUS);; + bool status = true; + + /* check if this is the last standing CPU */ + for (i = 0; i < PLATFORM_MAX_CPUS_PER_CLUSTER; i++) { + + /* skip the current CPU */ + if (i == cpu) + continue; + + /* are other CPUs already power gated? */ + if ((val & ((uint32_t)1 << pmc_cpu_powergate_id[i])) != 0U) { + status = false; + } + } + + return status; +} + +/******************************************************************************* + * Handler to be called on exiting System suspend. Right now only DPD registers + * are cleared. + ******************************************************************************/ +void tegra_pmc_resume(void) +{ + + /* Clear DPD sample */ + mmio_write_32((TEGRA_PMC_BASE + PMC_IO_DPD_SAMPLE), 0x0); + + /* Clear DPD Enable */ + mmio_write_32((TEGRA_PMC_BASE + PMC_DPD_ENABLE_0), 0x0); +} + +/******************************************************************************* + * Restart the system + ******************************************************************************/ +__dead2 void tegra_pmc_system_reset(void) +{ + uint32_t reg; + + reg = tegra_pmc_read_32(PMC_CONFIG); + reg |= RESET_ENABLE; /* restart */ + tegra_pmc_write_32(PMC_CONFIG, reg); + wfi(); + + ERROR("Tegra System Reset: operation not handled.\n"); + panic(); +} diff --git a/plat/nvidia/tegra/drivers/smmu/smmu.c b/plat/nvidia/tegra/drivers/smmu/smmu.c new file mode 100644 index 000000000..a4a4354e8 --- /dev/null +++ b/plat/nvidia/tegra/drivers/smmu/smmu.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include + +#include +#include + +#include +#include + +extern void memcpy16(void *dest, const void *src, unsigned int length); + +#define SMMU_NUM_CONTEXTS 64U +#define SMMU_CONTEXT_BANK_MAX_IDX 64U + +/* + * Init SMMU during boot or "System Suspend" exit + */ +void tegra_smmu_init(void) +{ + uint32_t val, cb_idx, smmu_id, ctx_base; + uint32_t smmu_counter = plat_get_num_smmu_devices(); + + for (smmu_id = 0U; smmu_id < smmu_counter; smmu_id++) { + /* Program the SMMU pagesize and reset CACHE_LOCK bit */ + val = tegra_smmu_read_32(smmu_id, SMMU_GSR0_SECURE_ACR); + val |= SMMU_GSR0_PGSIZE_64K; + val &= (uint32_t)~SMMU_ACR_CACHE_LOCK_ENABLE_BIT; + tegra_smmu_write_32(smmu_id, SMMU_GSR0_SECURE_ACR, val); + + /* reset CACHE LOCK bit for NS Aux. Config. Register */ + val = tegra_smmu_read_32(smmu_id, SMMU_GNSR_ACR); + val &= (uint32_t)~SMMU_ACR_CACHE_LOCK_ENABLE_BIT; + tegra_smmu_write_32(smmu_id, SMMU_GNSR_ACR, val); + + /* disable TCU prefetch for all contexts */ + ctx_base = (SMMU_GSR0_PGSIZE_64K * SMMU_NUM_CONTEXTS) + + SMMU_CBn_ACTLR; + for (cb_idx = 0; cb_idx < SMMU_CONTEXT_BANK_MAX_IDX; cb_idx++) { + val = tegra_smmu_read_32(smmu_id, + ctx_base + (SMMU_GSR0_PGSIZE_64K * cb_idx)); + val &= (uint32_t)~SMMU_CBn_ACTLR_CPRE_BIT; + tegra_smmu_write_32(smmu_id, ctx_base + + (SMMU_GSR0_PGSIZE_64K * cb_idx), val); + } + + /* set CACHE LOCK bit for NS Aux. Config. Register */ + val = tegra_smmu_read_32(smmu_id, SMMU_GNSR_ACR); + val |= (uint32_t)SMMU_ACR_CACHE_LOCK_ENABLE_BIT; + tegra_smmu_write_32(smmu_id, SMMU_GNSR_ACR, val); + + /* set CACHE LOCK bit for S Aux. Config. Register */ + val = tegra_smmu_read_32(smmu_id, SMMU_GSR0_SECURE_ACR); + val |= (uint32_t)SMMU_ACR_CACHE_LOCK_ENABLE_BIT; + tegra_smmu_write_32(smmu_id, SMMU_GSR0_SECURE_ACR, val); + } +} diff --git a/plat/nvidia/tegra/drivers/spe/shared_console.S b/plat/nvidia/tegra/drivers/spe/shared_console.S new file mode 100644 index 000000000..6df73ec24 --- /dev/null +++ b/plat/nvidia/tegra/drivers/spe/shared_console.S @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include +#include + +#define CONSOLE_NUM_BYTES_SHIFT 24 +#define CONSOLE_FLUSH_DATA_TO_PORT (1 << 26) +#define CONSOLE_RING_DOORBELL (1 << 31) +#define CONSOLE_IS_BUSY (1 << 31) +#define CONSOLE_TIMEOUT 0xC000 /* approx. 50 ms */ +#define CONSOLE_WRITE (CONSOLE_RING_DOORBELL | CONSOLE_FLUSH_DATA_TO_PORT) + + /* + * This file contains a driver implementation to make use of the + * real console implementation provided by the SPE firmware running + * SoCs after Tegra186. + * + * This console is shared by multiple components and the SPE firmware + * finally displays everything on the UART port. + */ + + .globl console_spe_core_init + .globl console_spe_core_putc + .globl console_spe_core_getc + .globl console_spe_core_flush + .globl console_spe_putc + .globl console_spe_getc + .globl console_spe_flush + .globl console_spe_register + +.macro check_if_console_is_ready base, tmp1, tmp2, label + /* wait until spe is ready or timeout expires */ + mrs \tmp2, cntps_tval_el1 +1: ldr \tmp1, [\base] + and \tmp1, \tmp1, #CONSOLE_IS_BUSY + cbz \tmp1, 2f + mrs \tmp1, cntps_tval_el1 + sub \tmp1, \tmp2, \tmp1 + cmp \tmp1, #CONSOLE_TIMEOUT + b.lt 1b + b \label +2: +.endm + + /* ------------------------------------------------- + * int console_spe_register(uintptr_t baseaddr, + * uint32_t clock, uint32_t baud, + * console_t *console); + * Function to initialize and register a new spe + * console. Storage passed in for the console struct + * *must* be persistent (i.e. not from the stack). + * In: x0 - UART register base address + * w1 - UART clock in Hz + * w2 - Baud rate + * x3 - pointer to empty console_t struct + * Out: return 1 on success, 0 on error + * Clobber list : x0, x1, x2, x6, x7, x14 + * ------------------------------------------------- + */ +func console_spe_register + /* Check the input base address */ + cbz x0, register_fail + + /* Dont use clock or baud rate, so ok to overwrite them */ + check_if_console_is_ready x0, x1, x2, register_fail + + cbz x3, register_fail + str x0, [x3, #CONSOLE_T_BASE] + mov x0, x3 + finish_console_register spe putc=1, getc=1, flush=1 + +register_fail: + mov w0, wzr + ret +endfunc console_spe_register + + /* -------------------------------------------------------- + * int console_spe_core_putc(int c, uintptr_t base_addr) + * Function to output a character over the console. It + * returns the character printed on success or -1 on error. + * In : w0 - character to be printed + * x1 - console base address + * Out : return -1 on error else return character. + * Clobber list : x2, x3 + * -------------------------------------------------------- + */ +func console_spe_core_putc + /* Check the input parameter */ + cbz x1, putc_error + + /* Prepend '\r' to '\n' */ + cmp w0, #0xA + b.ne not_eol + + check_if_console_is_ready x1, x2, x3, putc_error + + /* spe is ready */ + mov w2, #0xD /* '\r' */ + and w2, w2, #0xFF + mov w3, #(CONSOLE_WRITE | (1 << CONSOLE_NUM_BYTES_SHIFT)) + orr w2, w2, w3 + str w2, [x1] + +not_eol: + check_if_console_is_ready x1, x2, x3, putc_error + + /* spe is ready */ + mov w2, w0 + and w2, w2, #0xFF + mov w3, #(CONSOLE_WRITE | (1 << CONSOLE_NUM_BYTES_SHIFT)) + orr w2, w2, w3 + str w2, [x1] + + ret +putc_error: + mov w0, #-1 + ret +endfunc console_spe_core_putc + + /* -------------------------------------------------------- + * int console_spe_putc(int c, console_t *console) + * Function to output a character over the console. It + * returns the character printed on success or -1 on error. + * In : w0 - character to be printed + * x1 - pointer to console_t structure + * Out : return -1 on error else return character. + * Clobber list : x2 + * -------------------------------------------------------- + */ +func console_spe_putc + ldr x1, [x1, #CONSOLE_T_BASE] + b console_spe_core_putc +endfunc console_spe_putc + + /* --------------------------------------------- + * int console_spe_getc(console_t *console) + * Function to get a character from the console. + * It returns the character grabbed on success + * or -1 if no character is available. + * In : x0 - pointer to console_t structure + * Out: w0 - character if available, else -1 + * Clobber list : x0, x1 + * --------------------------------------------- + */ +func console_spe_getc + mov w0, #-1 + ret +endfunc console_spe_getc + + /* ------------------------------------------------- + * int console_spe_core_flush(uintptr_t base_addr) + * Function to force a write of all buffered + * data that hasn't been output. + * In : x0 - console base address + * Out : return -1 on error else return 0. + * Clobber list : x0, x1 + * ------------------------------------------------- + */ +func console_spe_core_flush + cbz x0, flush_error + + /* flush console */ + mov w1, #CONSOLE_WRITE + str w1, [x0] + mov w0, #0 + ret +flush_error: + mov w0, #-1 + ret +endfunc console_spe_core_flush + + /* --------------------------------------------- + * int console_spe_flush(console_t *console) + * Function to force a write of all buffered + * data that hasn't been output. + * In : x0 - pointer to console_t structure + * Out : return -1 on error else return 0. + * Clobber list : x0, x1 + * --------------------------------------------- + */ +func console_spe_flush + ldr x0, [x0, #CONSOLE_T_BASE] + b console_spe_core_flush +endfunc console_spe_flush diff --git a/plat/nvidia/tegra/lib/debug/profiler.c b/plat/nvidia/tegra/lib/debug/profiler.c new file mode 100644 index 000000000..dd76a4e96 --- /dev/null +++ b/plat/nvidia/tegra/lib/debug/profiler.c @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/******************************************************************************* + * The profiler stores the timestamps captured during cold boot to the shared + * memory for the non-secure world. The non-secure world driver parses the + * shared memory block and writes the contents to a file on the device, which + * can be later extracted for analysis. + * + * Profiler memory map + * + * TOP --------------------------- --- + * Trusted OS timestamps 3KB + * --------------------------- --- + * Trusted Firmware timestamps 1KB + * BASE --------------------------- --- + * + ******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static uint64_t shmem_base_addr; + +#define MAX_PROFILER_RECORDS U(16) +#define TAG_LEN_BYTES U(56) + +/******************************************************************************* + * Profiler entry format + ******************************************************************************/ +typedef struct { + /* text explaining the timestamp location in code */ + uint8_t tag[TAG_LEN_BYTES]; + /* timestamp value */ + uint64_t timestamp; +} profiler_rec_t; + +static profiler_rec_t *head, *cur, *tail; +static uint32_t tmr; +static bool is_shmem_buf_mapped; + +/******************************************************************************* + * Initialise the profiling library + ******************************************************************************/ +void boot_profiler_init(uint64_t shmem_base, uint32_t tmr_base) +{ + uint64_t shmem_end_base; + + assert(shmem_base != ULL(0)); + assert(tmr_base != U(0)); + + /* store the buffer address */ + shmem_base_addr = shmem_base; + + /* calculate the base address of the last record */ + shmem_end_base = shmem_base + (sizeof(profiler_rec_t) * + (MAX_PROFILER_RECORDS - U(1))); + + /* calculate the head, tail and cur values */ + head = (profiler_rec_t *)shmem_base; + tail = (profiler_rec_t *)shmem_end_base; + cur = head; + + /* timer used to get the current timestamp */ + tmr = tmr_base; +} + +/******************************************************************************* + * Add tag and timestamp to profiler + ******************************************************************************/ +void boot_profiler_add_record(const char *str) +{ + unsigned int len; + + /* calculate the length of the tag */ + if (((unsigned int)strlen(str) + U(1)) > TAG_LEN_BYTES) { + len = TAG_LEN_BYTES; + } else { + len = (unsigned int)strlen(str) + U(1); + } + + if (head != NULL) { + + /* + * The profiler runs with/without MMU enabled. Check + * if MMU is enabled and memmap the shmem buffer, in + * case it is. + */ + if ((!is_shmem_buf_mapped) && + ((read_sctlr_el3() & SCTLR_M_BIT) != U(0))) { + + (void)mmap_add_dynamic_region(shmem_base_addr, + shmem_base_addr, + PROFILER_SIZE_BYTES, + (MT_NS | MT_RW | MT_EXECUTE_NEVER)); + + is_shmem_buf_mapped = true; + } + + /* write the tag and timestamp to buffer */ + (void)snprintf((char *)cur->tag, len, "%s", str); + cur->timestamp = mmio_read_32(tmr); + + /* start from head if we reached the end */ + if (cur == tail) { + cur = head; + } else { + cur++; + } + } +} + +/******************************************************************************* + * Deinint the profiler + ******************************************************************************/ +void boot_profiler_deinit(void) +{ + if (shmem_base_addr != ULL(0)) { + + /* clean up resources */ + cur = NULL; + head = NULL; + tail = NULL; + + /* flush the shmem for it to be visible to the NS world */ + flush_dcache_range(shmem_base_addr, PROFILER_SIZE_BYTES); + + /* unmap the shmem buffer */ + if (is_shmem_buf_mapped) { + (void)mmap_remove_dynamic_region(shmem_base_addr, + PROFILER_SIZE_BYTES); + } + } +} diff --git a/plat/nvidia/tegra/soc/t132/platform_t132.mk b/plat/nvidia/tegra/soc/t132/platform_t132.mk index 16bd0ead2..3d76be9ed 100644 --- a/plat/nvidia/tegra/soc/t132/platform_t132.mk +++ b/plat/nvidia/tegra/soc/t132/platform_t132.mk @@ -25,9 +25,9 @@ PLAT_INCLUDES += -Iplat/nvidia/tegra/include/t132 BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \ lib/cpus/aarch64/denver.S \ - ${COMMON_DIR}/drivers/flowctrl/flowctrl.c \ - ${COMMON_DIR}/drivers/memctrl/memctrl_v1.c \ - ${COMMON_DIR}/drivers/pmc/pmc.c \ + ${TEGRA_DRIVERS}/flowctrl/flowctrl.c \ + ${TEGRA_DRIVERS}/memctrl/memctrl_v1.c \ + ${TEGRA_DRIVERS}/pmc/pmc.c \ ${SOC_DIR}/plat_psci_handlers.c \ ${SOC_DIR}/plat_sip_calls.c \ ${SOC_DIR}/plat_setup.c \ diff --git a/plat/nvidia/tegra/soc/t186/platform_t186.mk b/plat/nvidia/tegra/soc/t186/platform_t186.mk index d320aac2f..6739c50d1 100644 --- a/plat/nvidia/tegra/soc/t186/platform_t186.mk +++ b/plat/nvidia/tegra/soc/t186/platform_t186.mk @@ -43,16 +43,16 @@ PLAT_INCLUDES += -Iplat/nvidia/tegra/include/t186 \ BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \ lib/cpus/aarch64/denver.S \ lib/cpus/aarch64/cortex_a57.S \ - ${COMMON_DIR}/drivers/bpmp_ipc/intf.c \ - ${COMMON_DIR}/drivers/bpmp_ipc/ivc.c \ - ${COMMON_DIR}/drivers/gpcdma/gpcdma.c \ - ${COMMON_DIR}/drivers/memctrl/memctrl_v2.c \ - ${COMMON_DIR}/drivers/smmu/smmu.c \ + ${TEGRA_DRIVERS}/bpmp_ipc/intf.c \ + ${TEGRA_DRIVERS}/bpmp_ipc/ivc.c \ + ${TEGRA_DRIVERS}/gpcdma/gpcdma.c \ + ${TEGRA_DRIVERS}/memctrl/memctrl_v2.c \ + ${TEGRA_DRIVERS}/smmu/smmu.c \ ${SOC_DIR}/drivers/mce/mce.c \ ${SOC_DIR}/drivers/mce/ari.c \ ${SOC_DIR}/drivers/mce/nvg.c \ ${SOC_DIR}/drivers/mce/aarch64/nvg_helpers.S \ - $(SOC_DIR)/drivers/se/se.c \ + $(SOC_DIR)/drivers/se/se.c \ ${SOC_DIR}/plat_memctrl.c \ ${SOC_DIR}/plat_psci_handlers.c \ ${SOC_DIR}/plat_setup.c \ diff --git a/plat/nvidia/tegra/soc/t194/platform_t194.mk b/plat/nvidia/tegra/soc/t194/platform_t194.mk index d7d15f556..7573ed23b 100644 --- a/plat/nvidia/tegra/soc/t194/platform_t194.mk +++ b/plat/nvidia/tegra/soc/t194/platform_t194.mk @@ -40,11 +40,10 @@ PLAT_INCLUDES += -Iplat/nvidia/tegra/include/t194 \ BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \ lib/cpus/aarch64/denver.S \ - ${COMMON_DIR}/drivers/bpmp_ipc/intf.c \ - ${COMMON_DIR}/drivers/bpmp_ipc/ivc.c \ - ${COMMON_DIR}/drivers/gpcdma/gpcdma.c \ - ${COMMON_DIR}/drivers/memctrl/memctrl_v2.c \ - ${COMMON_DIR}/drivers/smmu/smmu.c \ + ${TEGRA_DRIVERS}/bpmp_ipc/intf.c \ + ${TEGRA_DRIVERS}/bpmp_ipc/ivc.c \ + ${TEGRA_DRIVERS}/memctrl/memctrl_v2.c \ + ${TEGRA_DRIVERS}/smmu/smmu.c \ ${SOC_DIR}/drivers/mce/mce.c \ ${SOC_DIR}/drivers/mce/nvg.c \ ${SOC_DIR}/drivers/mce/aarch64/nvg_helpers.S \ @@ -57,8 +56,12 @@ BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \ ${SOC_DIR}/plat_smmu.c \ ${SOC_DIR}/plat_trampoline.S +ifeq (${USE_GPC_DMA}, 1) +BL31_SOURCES += ${TEGRA_DRIVERS}/gpcdma/gpcdma.c +endif + ifeq (${ENABLE_CONSOLE_SPE},1) -BL31_SOURCES += ${COMMON_DIR}/drivers/spe/shared_console.S +BL31_SOURCES += ${TEGRA_DRIVERS}/spe/shared_console.S endif # RAS sources diff --git a/plat/nvidia/tegra/soc/t210/platform_t210.mk b/plat/nvidia/tegra/soc/t210/platform_t210.mk index 14e3324a8..6c4c17510 100644 --- a/plat/nvidia/tegra/soc/t210/platform_t210.mk +++ b/plat/nvidia/tegra/soc/t210/platform_t210.mk @@ -25,20 +25,20 @@ $(eval $(call add_define,MAX_MMAP_REGIONS)) ENABLE_TEGRA_WDT_LEGACY_FIQ_HANDLING := 1 -PLAT_INCLUDES += -Iplat/nvidia/tegra/include/t210 \ +PLAT_INCLUDES += -Iplat/nvidia/tegra/include/t210 \ -I${SOC_DIR}/drivers/se BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \ lib/cpus/aarch64/cortex_a53.S \ lib/cpus/aarch64/cortex_a57.S \ - ${COMMON_DIR}/drivers/bpmp/bpmp.c \ - ${COMMON_DIR}/drivers/flowctrl/flowctrl.c \ - ${COMMON_DIR}/drivers/memctrl/memctrl_v1.c \ - ${COMMON_DIR}/drivers/pmc/pmc.c \ + ${TEGRA_DRIVERS}/bpmp/bpmp.c \ + ${TEGRA_DRIVERS}/flowctrl/flowctrl.c \ + ${TEGRA_DRIVERS}/memctrl/memctrl_v1.c \ + ${TEGRA_DRIVERS}/pmc/pmc.c \ ${SOC_DIR}/plat_psci_handlers.c \ ${SOC_DIR}/plat_setup.c \ ${SOC_DIR}/drivers/se/security_engine.c \ - ${SOC_DIR}/plat_secondary.c \ + ${SOC_DIR}/plat_secondary.c \ ${SOC_DIR}/plat_sip_calls.c # Enable workarounds for selected Cortex-A57 erratas. -- cgit v1.2.3 From 66e0b947c4c4fb851b70b38c757b14f6093faeee Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Mon, 17 Jun 2019 11:45:11 -0700 Subject: Tegra: memctrl: remove unused TZRAM setup function This patch removes the unused TZRAM setup function from the memory controller driver. Change-Id: Ic16f21fb84c47df71be6ab3e1e286640daa39291 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/tegra_bl31_setup.c | 6 ------ plat/nvidia/tegra/common/tegra_pm.c | 5 ----- plat/nvidia/tegra/drivers/memctrl/memctrl_v1.c | 15 +-------------- plat/nvidia/tegra/include/drivers/memctrl.h | 2 +- 4 files changed, 2 insertions(+), 26 deletions(-) diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c index 40713b2c7..e56909dcd 100644 --- a/plat/nvidia/tegra/common/tegra_bl31_setup.c +++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c @@ -247,12 +247,6 @@ void bl31_platform_setup(void) */ tegra_memctrl_setup(); - /* - * Set up the TZRAM memory aperture to allow only secure world - * access - */ - tegra_memctrl_tzram_setup(TEGRA_TZRAM_BASE, TEGRA_TZRAM_SIZE); - /* * Late setup handler to allow platforms to performs additional * functionality. diff --git a/plat/nvidia/tegra/common/tegra_pm.c b/plat/nvidia/tegra/common/tegra_pm.c index 0430048e2..78e96cf3e 100644 --- a/plat/nvidia/tegra/common/tegra_pm.c +++ b/plat/nvidia/tegra/common/tegra_pm.c @@ -180,11 +180,6 @@ void tegra_pwr_domain_on_finish(const psci_power_state_t *target_state) tegra_memctrl_tzdram_setup(plat_params->tzdram_base, (uint32_t)plat_params->tzdram_size); - /* - * Set up the TZRAM memory aperture to allow only secure world - * access - */ - tegra_memctrl_tzram_setup(TEGRA_TZRAM_BASE, TEGRA_TZRAM_SIZE); } else { /* * Initialize the GIC cpu and distributor interfaces diff --git a/plat/nvidia/tegra/drivers/memctrl/memctrl_v1.c b/plat/nvidia/tegra/drivers/memctrl/memctrl_v1.c index c3f95db4d..b3dcd2a4b 100644 --- a/plat/nvidia/tegra/drivers/memctrl/memctrl_v1.c +++ b/plat/nvidia/tegra/drivers/memctrl/memctrl_v1.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -92,20 +93,6 @@ void tegra_memctrl_tzdram_setup(uint64_t phys_base, uint32_t size_in_bytes) tegra_mc_write_32(MC_SECURITY_CFG1_0, size_in_bytes >> 20); } -/* - * Secure the BL31 TZRAM aperture. - * - * phys_base = physical base of TZRAM aperture - * size_in_bytes = size of aperture in bytes - */ -void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes) -{ - /* - * The v1 hardware controller does not have any registers - * for setting up the on-chip TZRAM. - */ -} - static void tegra_clear_videomem(uintptr_t non_overlap_area_start, unsigned long long non_overlap_area_size) { diff --git a/plat/nvidia/tegra/include/drivers/memctrl.h b/plat/nvidia/tegra/include/drivers/memctrl.h index d5ef60d0c..cc8509526 100644 --- a/plat/nvidia/tegra/include/drivers/memctrl.h +++ b/plat/nvidia/tegra/include/drivers/memctrl.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -10,7 +11,6 @@ void tegra_memctrl_setup(void); void tegra_memctrl_restore_settings(void); void tegra_memctrl_tzdram_setup(uint64_t phys_base, uint32_t size_in_bytes); -void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes); void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes); void tegra_memctrl_disable_ahb_redirection(void); void tegra_memctrl_clear_pending_interrupts(void); -- cgit v1.2.3 From a4a9547c82b07465d736f25ebdea8b584112addb Mon Sep 17 00:00:00 2001 From: Alex Van Brunt Date: Tue, 23 Jul 2019 10:00:42 -0700 Subject: lib: cpus: denver: add some MIDR values This patch adds support for additional Denver MIDRs to cover all the current SKUs. Change-Id: I85d0ffe9b3cb351f430ca7d7065a2609968a7a28 Signed-off-by: Alex Van Brunt Signed-off-by: Varun Wadekar --- include/lib/cpus/aarch64/denver.h | 4 ++++ lib/cpus/aarch64/denver.S | 28 ++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/include/lib/cpus/aarch64/denver.h b/include/lib/cpus/aarch64/denver.h index b98abdf4d..b665bc799 100644 --- a/include/lib/cpus/aarch64/denver.h +++ b/include/lib/cpus/aarch64/denver.h @@ -13,6 +13,10 @@ #define DENVER_MIDR_PN2 U(0x4E0F0020) #define DENVER_MIDR_PN3 U(0x4E0F0030) #define DENVER_MIDR_PN4 U(0x4E0F0040) +#define DENVER_MIDR_PN5 U(0x4E0F0050) +#define DENVER_MIDR_PN6 U(0x4E0F0060) +#define DENVER_MIDR_PN7 U(0x4E0F0070) +#define DENVER_MIDR_PN8 U(0x4E0F0080) /* Implementer code in the MIDR register */ #define DENVER_IMPL U(0x4E) diff --git a/lib/cpus/aarch64/denver.S b/lib/cpus/aarch64/denver.S index bdca4c343..d662e7f89 100644 --- a/lib/cpus/aarch64/denver.S +++ b/lib/cpus/aarch64/denver.S @@ -387,3 +387,31 @@ declare_cpu_ops_wa denver, DENVER_MIDR_PN4, \ CPU_NO_EXTRA2_FUNC, \ denver_core_pwr_dwn, \ denver_cluster_pwr_dwn + +declare_cpu_ops_wa denver, DENVER_MIDR_PN5, \ + denver_reset_func, \ + check_errata_cve_2017_5715, \ + CPU_NO_EXTRA2_FUNC, \ + denver_core_pwr_dwn, \ + denver_cluster_pwr_dwn + +declare_cpu_ops_wa denver, DENVER_MIDR_PN6, \ + denver_reset_func, \ + check_errata_cve_2017_5715, \ + CPU_NO_EXTRA2_FUNC, \ + denver_core_pwr_dwn, \ + denver_cluster_pwr_dwn + +declare_cpu_ops_wa denver, DENVER_MIDR_PN7, \ + denver_reset_func, \ + check_errata_cve_2017_5715, \ + CPU_NO_EXTRA2_FUNC, \ + denver_core_pwr_dwn, \ + denver_cluster_pwr_dwn + +declare_cpu_ops_wa denver, DENVER_MIDR_PN8, \ + denver_reset_func, \ + check_errata_cve_2017_5715, \ + CPU_NO_EXTRA2_FUNC, \ + denver_core_pwr_dwn, \ + denver_cluster_pwr_dwn -- cgit v1.2.3 From 5bd9c17d023288e6b819fa3eecc01b7981399cfa Mon Sep 17 00:00:00 2001 From: Saurabh Gorecha Date: Wed, 22 Apr 2020 21:31:24 +0530 Subject: sc7180 platform support Adding support for QTI CHIP SC7180 on ATF Change-Id: I0d82d3a378036003fbd0bc4784f61464bb76ea82 Signed-off-by: Saurabh Gorecha Co-authored-by: Maulik Shah --- docs/about/maintainers.rst | 10 + docs/plat/index.rst | 1 + docs/plat/qti.rst | 41 +++ plat/qti/common/inc/aarch64/plat_macros.S | 106 +++++++ plat/qti/common/inc/qti_board_def.h | 29 ++ plat/qti/common/inc/qti_cpu.h | 16 + plat/qti/common/inc/qti_interrupt_svc.h | 12 + plat/qti/common/inc/qti_plat.h | 53 ++++ plat/qti/common/inc/qti_uart_console.h | 19 ++ plat/qti/common/src/aarch64/qti_helpers.S | 88 ++++++ plat/qti/common/src/aarch64/qti_kryo4_gold.S | 83 +++++ plat/qti/common/src/aarch64/qti_kryo4_silver.S | 79 +++++ plat/qti/common/src/aarch64/qti_uart_console.S | 102 +++++++ plat/qti/common/src/qti_bl31_setup.c | 155 ++++++++++ plat/qti/common/src/qti_common.c | 148 +++++++++ plat/qti/common/src/qti_gic_v3.c | 159 ++++++++++ plat/qti/common/src/qti_interrupt_svc.c | 65 ++++ plat/qti/common/src/qti_pm.c | 274 +++++++++++++++++ plat/qti/common/src/qti_stack_protector.c | 24 ++ plat/qti/common/src/qti_syscall.c | 333 +++++++++++++++++++++ plat/qti/common/src/qti_topology.c | 48 +++ plat/qti/qtiseclib/inc/qtiseclib_cb_interface.h | 54 ++++ plat/qti/qtiseclib/inc/qtiseclib_defs.h | 104 +++++++ plat/qti/qtiseclib/inc/qtiseclib_interface.h | 88 ++++++ .../qti/qtiseclib/inc/sc7180/qtiseclib_defs_plat.h | 41 +++ plat/qti/qtiseclib/src/qtiseclib_cb_interface.c | 187 ++++++++++++ plat/qti/qtiseclib/src/qtiseclib_interface_stub.c | 137 +++++++++ plat/qti/sc7180/inc/platform_def.h | 176 +++++++++++ plat/qti/sc7180/inc/qti_secure_io_cfg.h | 30 ++ plat/qti/sc7180/platform.mk | 116 +++++++ 30 files changed, 2778 insertions(+) create mode 100644 docs/plat/qti.rst create mode 100644 plat/qti/common/inc/aarch64/plat_macros.S create mode 100644 plat/qti/common/inc/qti_board_def.h create mode 100644 plat/qti/common/inc/qti_cpu.h create mode 100644 plat/qti/common/inc/qti_interrupt_svc.h create mode 100644 plat/qti/common/inc/qti_plat.h create mode 100644 plat/qti/common/inc/qti_uart_console.h create mode 100644 plat/qti/common/src/aarch64/qti_helpers.S create mode 100644 plat/qti/common/src/aarch64/qti_kryo4_gold.S create mode 100644 plat/qti/common/src/aarch64/qti_kryo4_silver.S create mode 100644 plat/qti/common/src/aarch64/qti_uart_console.S create mode 100644 plat/qti/common/src/qti_bl31_setup.c create mode 100644 plat/qti/common/src/qti_common.c create mode 100644 plat/qti/common/src/qti_gic_v3.c create mode 100644 plat/qti/common/src/qti_interrupt_svc.c create mode 100644 plat/qti/common/src/qti_pm.c create mode 100644 plat/qti/common/src/qti_stack_protector.c create mode 100644 plat/qti/common/src/qti_syscall.c create mode 100644 plat/qti/common/src/qti_topology.c create mode 100644 plat/qti/qtiseclib/inc/qtiseclib_cb_interface.h create mode 100644 plat/qti/qtiseclib/inc/qtiseclib_defs.h create mode 100644 plat/qti/qtiseclib/inc/qtiseclib_interface.h create mode 100644 plat/qti/qtiseclib/inc/sc7180/qtiseclib_defs_plat.h create mode 100644 plat/qti/qtiseclib/src/qtiseclib_cb_interface.c create mode 100644 plat/qti/qtiseclib/src/qtiseclib_interface_stub.c create mode 100644 plat/qti/sc7180/inc/platform_def.h create mode 100644 plat/qti/sc7180/inc/qti_secure_io_cfg.h create mode 100644 plat/qti/sc7180/platform.mk diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst index d40134f81..d6fafe4de 100644 --- a/docs/about/maintainers.rst +++ b/docs/about/maintainers.rst @@ -228,6 +228,15 @@ QEMU platform port :F: docs/plat/qemu.rst :F: plat/qemu/ +QTI platform port +^^^^^^^^^^^^^^^^^ +:M: Saurabh Gorecha +:G: `sgorecha`_ +:M: Debasish Mandal +:M: QTI TF Maintainers +:F: docs/plat/qti.rst +:F: plat/qti/ + Raspberry Pi 3 platform port ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :M: Ying-Chun Liu (PaulLiu) @@ -356,6 +365,7 @@ TLK/Trusty secure payloads .. _remi-triplefault: https://github.com/repk .. _rockchip-linux: https://github.com/rockchip-linux .. _sandrine-bailleux-arm: https://github.com/sandrine-bailleux-arm +.. _sgorecha: https://github.com/sgorecha .. _shawnguo2: https://github.com/shawnguo2 .. _sivadur: https://github.com/sivadur .. _smaeul: https://github.com/smaeul diff --git a/docs/plat/index.rst b/docs/plat/index.rst index 7969003c9..553d8b53e 100644 --- a/docs/plat/index.rst +++ b/docs/plat/index.rst @@ -27,6 +27,7 @@ Platform Ports poplar qemu qemu-sbsa + qti rpi3 rpi4 rcar-gen3 diff --git a/docs/plat/qti.rst b/docs/plat/qti.rst new file mode 100644 index 000000000..814e6726a --- /dev/null +++ b/docs/plat/qti.rst @@ -0,0 +1,41 @@ +Qualcomm Technologies, Inc. +=========================== + +Trusted Firmware-A (TF-A) implements the EL3 firmware layer for QTI SC7180. + + +Boot Trace +------------- + +Bootrom --> BL1/BL2 --> BL31 --> BL33 --> Linux kernel + +BL1/2 and BL33 can currently be supplied from Coreboot + Depthcharge + +How to build +------------ + +Code Locations +~~~~~~~~~~~~~~ + +- Trusted Firmware-A: + `link `__ + +Build Procedure +~~~~~~~~~~~~~~~ + +QTI SoC expects TF-A's BL31 to get integrated with other boot software +Coreboot, so only bl31.elf need to get build from the TF-A repository. + +The build command looks like + + make CROSS_COMPILE=aarch64-linux-gnu- PLAT=sc7180 COREBOOT=1 + +update value of CROSS_COMPILE argument with your cross-compilation toolchain. + +Additional QTISECLIB_PATH= can be added in build command. +if QTISECLIB_PATH is not added in build command stub implementation of qtiseclib +is picked. qtiseclib with stub implementation doesn't boot device. This was +added to satisfy compilation. + +QTISELIB for SC7180 is available at +`link `__ diff --git a/plat/qti/common/inc/aarch64/plat_macros.S b/plat/qti/common/inc/aarch64/plat_macros.S new file mode 100644 index 000000000..2e292fb19 --- /dev/null +++ b/plat/qti/common/inc/aarch64/plat_macros.S @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018,2020, The Linux Foundation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __PLAT_MACROS_S__ +#define __PLAT_MACROS_S__ + +#include +#include +#include + +#include + +.section .rodata.gic_reg_name, "aS" +/* Applicable only to GICv2 and GICv3 with SRE disabled (legacy mode) */ +gicc_regs: + .asciz "gicc_hppir", "gicc_ahppir", "gicc_ctlr", "" + +/* Applicable only to GICv3 with SRE enabled */ +icc_regs: + .asciz "icc_hppir0_el1", "icc_hppir1_el1", "icc_ctlr_el3", "" + +/* Registers common to both GICv2 and GICv3 */ +gicd_pend_reg: + .asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n" \ + " Offset:\t\t\tvalue\n" +newline: + .asciz "\n" +spacer: + .asciz ":\t\t0x" + +/** Macro : plat_crash_print_regs + * This macro allows the crash reporting routine to print GIC registers + * in case of an unhandled exception in BL31. This aids in debugging and + * this macro can be defined to be empty in case GIC register reporting is + * not desired. + * The below required platform porting macro + * prints out relevant GIC registers whenever an + * unhandled exception is taken in BL31. + * Clobbers: x0 - x10, x26, x27, sp + * --------------------------------------------- + */ + .macro plat_crash_print_regs +print_gic_regs: + ldr x26, =QTI_GICD_BASE + ldr x27, =QTI_GICC_BASE + + /* Check for GICv3 system register access */ + mrs x7, id_aa64pfr0_el1 + ubfx x7, x7, #ID_AA64PFR0_GIC_SHIFT, #ID_AA64PFR0_GIC_WIDTH + cmp x7, #1 + b.ne print_gicv2 + + /* Check for SRE enable */ + mrs x8, ICC_SRE_EL3 + tst x8, #ICC_SRE_SRE_BIT + b.eq print_gicv2 + + /* Load the icc reg list to x6 */ + adr x6, icc_regs + /* Load the icc regs to gp regs used by str_in_crash_buf_print */ + mrs x8, ICC_HPPIR0_EL1 + mrs x9, ICC_HPPIR1_EL1 + mrs x10, ICC_CTLR_EL3 + /* Store to the crash buf and print to console */ + bl str_in_crash_buf_print + b print_gic_common + +print_gicv2: + /* Load the gicc reg list to x6 */ + adr x6, gicc_regs + /* Load the gicc regs to gp regs used by str_in_crash_buf_print */ + ldr w8, [x27, #GICC_HPPIR] + ldr w9, [x27, #GICC_AHPPIR] + ldr w10, [x27, #GICC_CTLR] + /* Store to the crash buf and print to console */ + bl str_in_crash_buf_print + +print_gic_common: + /* Print the GICD_ISPENDR regs */ + add x7, x26, #GICD_ISPENDR + adr x4, gicd_pend_reg + bl asm_print_str +gicd_ispendr_loop: + sub x4, x7, x26 + cmp x4, #0x280 + b.eq exit_print_gic_regs + bl asm_print_hex + + adr x4, spacer + bl asm_print_str + + ldr x4, [x7], #8 + bl asm_print_hex + + adr x4, newline + bl asm_print_str + b gicd_ispendr_loop +exit_print_gic_regs: + + .endm + +#endif /* __PLAT_MACROS_S__ */ diff --git a/plat/qti/common/inc/qti_board_def.h b/plat/qti/common/inc/qti_board_def.h new file mode 100644 index 000000000..4c84661b7 --- /dev/null +++ b/plat/qti/common/inc/qti_board_def.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef QTI_BOARD_DEF_H +#define QTI_BOARD_DEF_H + +/* + * Required platform porting definitions common to all ARM + * development platforms + */ + +/* Size of cacheable stacks */ +#define PLATFORM_STACK_SIZE 0x1000 + +/* + * PLAT_QTI_MMAP_ENTRIES depends on the number of entries in the + * plat_qti_mmap array defined for each BL stage. + */ +#define PLAT_QTI_MMAP_ENTRIES 12 + +/* + * Platform specific page table and MMU setup constants + */ +#define MAX_XLAT_TABLES 12 + +#endif /* QTI_BOARD_DEF_H */ diff --git a/plat/qti/common/inc/qti_cpu.h b/plat/qti/common/inc/qti_cpu.h new file mode 100644 index 000000000..3eda02bbb --- /dev/null +++ b/plat/qti/common/inc/qti_cpu.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QTI_CPU_H +#define QTI_CPU_H + +/* KRYO-4xx Gold MIDR */ +#define QTI_KRYO4_GOLD_MIDR 0x517F804D + +/* KRYO-4xx Silver MIDR */ +#define QTI_KRYO4_SILVER_MIDR 0x517F805D + +#endif /* QTI_CPU_H */ diff --git a/plat/qti/common/inc/qti_interrupt_svc.h b/plat/qti/common/inc/qti_interrupt_svc.h new file mode 100644 index 000000000..59bde8681 --- /dev/null +++ b/plat/qti/common/inc/qti_interrupt_svc.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2018,2020, The Linux Foundation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QTI_INTERRUPT_SVC_H +#define QTI_INTERRUPT_SVC_H + +int qti_interrupt_svc_init(void); + +#endif /* QTI_INTERRUPT_SVC_H */ diff --git a/plat/qti/common/inc/qti_plat.h b/plat/qti/common/inc/qti_plat.h new file mode 100644 index 000000000..0e867be79 --- /dev/null +++ b/plat/qti/common/inc/qti_plat.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QTI_PLAT_H +#define QTI_PLAT_H + +#include + +#include +#include +#include +#include + +/* + * Utility functions common to QTI platforms + */ +int qti_mmap_add_dynamic_region(uintptr_t base_pa, size_t size, + unsigned int attr); +int qti_mmap_remove_dynamic_region(uintptr_t base_va, size_t size); + +/* + * Utility functions common to ARM standard platforms + */ +void qti_setup_page_tables(uintptr_t total_base, + size_t total_size, + uintptr_t code_start, + uintptr_t code_limit, + uintptr_t rodata_start, + uintptr_t rodata_limit, + uintptr_t coh_start, uintptr_t coh_limit); + +/* + * Mandatory functions required in ARM standard platforms + */ +void plat_qti_gic_driver_init(void); +void plat_qti_gic_init(void); +void plat_qti_gic_cpuif_enable(void); +void plat_qti_gic_cpuif_disable(void); +void plat_qti_gic_pcpu_init(void); + +/* + * Optional functions required in ARM standard platforms + */ +unsigned int plat_qti_core_pos_by_mpidr(u_register_t mpidr); +unsigned int plat_qti_my_cluster_pos(void); + +void gic_set_spi_routing(unsigned int id, unsigned int irm, u_register_t mpidr); + +#endif /* QTI_PLAT_H */ diff --git a/plat/qti/common/inc/qti_uart_console.h b/plat/qti/common/inc/qti_uart_console.h new file mode 100644 index 000000000..c5a65d618 --- /dev/null +++ b/plat/qti/common/inc/qti_uart_console.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018,2020 The Linux Foundation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QTI_UART_CONSOLE_H +#define QTI_UART_CONSOLE_H + +#include + +#ifndef __ASSEMBLER__ + +int qti_console_uart_register(console_t *console, uintptr_t uart_base_addr); + +#endif /* __ASSEMBLER__ */ + +#endif /* QTI_UART_CONSOLE_H */ diff --git a/plat/qti/common/src/aarch64/qti_helpers.S b/plat/qti/common/src/aarch64/qti_helpers.S new file mode 100644 index 000000000..c1ea7b32f --- /dev/null +++ b/plat/qti/common/src/aarch64/qti_helpers.S @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018,2020, The Linux Foundation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include + +#include + + .globl plat_my_core_pos + .globl plat_qti_core_pos_by_mpidr + .globl plat_reset_handler + .globl plat_panic_handler + + /* ----------------------------------------------------- + * unsigned int plat_qti_core_pos_by_mpidr(uint64_t mpidr) + * Helper function to calculate the core position. + * With this function: + * CorePos = (ClusterId * 4) + CoreId + * - In ARM v8 (MPIDR_EL1[24]=0) + * ClusterId = MPIDR_EL1[15:8] + * CoreId = MPIDR_EL1[7:0] + * - In ARM v8.1 (MPIDR_EL1[24]=1) + * ClusterId = MPIDR_EL1[23:15] + * CoreId = MPIDR_EL1[15:8] + * Clobbers: x0 & x1. + * ----------------------------------------------------- + */ +func plat_qti_core_pos_by_mpidr + mrs x1, mpidr_el1 + tst x1, #MPIDR_MT_MASK + beq plat_qti_core_pos_by_mpidr_no_mt + /* Right shift mpidr by one affinity level when MT=1. */ + lsr x0, x0, #MPIDR_AFFINITY_BITS +plat_qti_core_pos_by_mpidr_no_mt: + and x1, x0, #MPIDR_CPU_MASK + and x0, x0, #MPIDR_CLUSTER_MASK + add x0, x1, x0, LSR #6 + ret +endfunc plat_qti_core_pos_by_mpidr + + /* -------------------------------------------------------------------- + * void plat_panic_handler(void) + * calls SDI and reset system + * -------------------------------------------------------------------- + */ +func plat_panic_handler + msr spsel, #0 + bl plat_set_my_stack + b qtiseclib_panic +endfunc plat_panic_handler + + /* ----------------------------------------------------- + * unsigned int plat_my_core_pos(void) + * This function uses the plat_qti_calc_core_pos() + * definition to get the index of the calling CPU + * Clobbers: x0 & x1. + * ----------------------------------------------------- + */ +func plat_my_core_pos + mrs x0, mpidr_el1 + b plat_qti_core_pos_by_mpidr +endfunc plat_my_core_pos + +func plat_reset_handler + /* save the lr */ + mov x18, x30 + + /* Serialize CPUSS boot setup. Multi core enter simultaneously. */ + ldr x0, =g_qti_cpuss_boot_lock + bl spin_lock + + /* pass cold boot status. */ + ldr w0, g_qti_bl31_cold_booted + /* Execuete CPUSS boot set up on every core. */ + bl qtiseclib_cpuss_reset_asm + + ldr x0, =g_qti_cpuss_boot_lock + bl spin_unlock + + ret x18 +endfunc plat_reset_handler diff --git a/plat/qti/common/src/aarch64/qti_kryo4_gold.S b/plat/qti/common/src/aarch64/qti_kryo4_gold.S new file mode 100644 index 000000000..a1b40c8d1 --- /dev/null +++ b/plat/qti/common/src/aarch64/qti_kryo4_gold.S @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, 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_kryo4_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_kryo4_gold_reset_asm + + ret x19 + +endfunc qti_kryo4_gold_reset_func + +/* ---------------------------------------------------- + * The CPU Ops core power down function for Kryo-3 Gold + * ---------------------------------------------------- + */ +func qti_kryo4_gold_core_pwr_dwn + ret +endfunc qti_kryo4_gold_core_pwr_dwn + +/* ------------------------------------------------------- + * The CPU Ops cluster power down function for Kryo-3 Gold + * ------------------------------------------------------- + */ +func qti_kryo4_gold_cluster_pwr_dwn + ret +endfunc qti_kryo4_gold_cluster_pwr_dwn + +#if REPORT_ERRATA +/* + * Errata printing function for Kryo4 Gold. Must follow AAPCS. + */ +func qti_kryo4_gold_errata_report + /* TODO : Need to add support. Required only for debug bl31 image.*/ + ret +endfunc qti_kryo4_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_kryo4_gold_regs: /* The ASCII list of register names to be reported */ + .asciz "" + +func qti_kryo4_gold_cpu_reg_dump + adr x6, qti_kryo4_gold_regs + ret +endfunc qti_kryo4_gold_cpu_reg_dump + +declare_cpu_ops qti_kryo4_gold, QTI_KRYO4_GOLD_MIDR, \ + qti_kryo4_gold_reset_func, \ + qti_kryo4_gold_core_pwr_dwn, \ + qti_kryo4_gold_cluster_pwr_dwn diff --git a/plat/qti/common/src/aarch64/qti_kryo4_silver.S b/plat/qti/common/src/aarch64/qti_kryo4_silver.S new file mode 100644 index 000000000..183eeb0fa --- /dev/null +++ b/plat/qti/common/src/aarch64/qti_kryo4_silver.S @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, 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_kryo4_silver_reset_func + mov x19, x30 + + bl qtiseclib_kryo4_silver_reset_asm + + ret x19 + +endfunc qti_kryo4_silver_reset_func + +/* ------------------------------------------------------ + * The CPU Ops core power down function for Kryo-3 Silver + * ------------------------------------------------------ + */ +func qti_kryo4_silver_core_pwr_dwn + ret +endfunc qti_kryo4_silver_core_pwr_dwn + +/* --------------------------------------------------------- + * The CPU Ops cluster power down function for Kryo-3 Silver + * --------------------------------------------------------- + */ +func qti_kryo4_silver_cluster_pwr_dwn + ret +endfunc qti_kryo4_silver_cluster_pwr_dwn + +#if REPORT_ERRATA +/* + * Errata printing function for Kryo4 Silver. Must follow AAPCS. + */ +func qti_kryo4_silver_errata_report + /* TODO : Need to add support. Required only for debug bl31 image.*/ + ret +endfunc qti_kryo4_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_kryo4_silver_regs: /* The ASCII list of register names to be reported */ + .asciz "" + +func qti_kryo4_silver_cpu_reg_dump + adr x6, qti_kryo4_silver_regs + ret +endfunc qti_kryo4_silver_cpu_reg_dump + + +declare_cpu_ops qti_kryo4_silver, QTI_KRYO4_SILVER_MIDR, \ + qti_kryo4_silver_reset_func, \ + qti_kryo4_silver_core_pwr_dwn, \ + qti_kryo4_silver_cluster_pwr_dwn diff --git a/plat/qti/common/src/aarch64/qti_uart_console.S b/plat/qti/common/src/aarch64/qti_uart_console.S new file mode 100644 index 000000000..2eb33d97a --- /dev/null +++ b/plat/qti/common/src/aarch64/qti_uart_console.S @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018,2020 The Linux Foundation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include + +/* + * This driver implements console logging into a ring buffer. + */ + + .globl qti_console_uart_register + + /* ----------------------------------------------- + * int qti_console_uart_register(console_t *console, + * uintptr_t uart_base_addr) + * Registers uart console instance. + * In: x0 - pointer to empty console_t struct + * x1 - start address of uart block. + * Out: x0 - 1 to indicate success + * Clobber list: x0, x1, x14 + * ----------------------------------------------- + */ +func qti_console_uart_register + str x1, [x0, #CONSOLE_T_BASE] /* Save UART base. */ + finish_console_register uart putc=1, flush=1 +endfunc qti_console_uart_register + + /* ----------------------------------------------- + * int qti_console_uart_puts(int c, console_t *console) + * Writes a character to the UART console. + * The character must be preserved in x0. + * In: x0 - character to be stored + * x1 - pointer to console_t struct + * Clobber list: x1, x2 + * ----------------------------------------------- + */ +func console_uart_putc + /* set x1 = UART base. */ + ldr x1, [x1, #CONSOLE_T_BASE] + + /* Loop until M_GENI_CMD_ACTIVE bit not clear. */ +1: ldr w2, [x1, #GENI_STATUS_REG] + and w2, w2, #GENI_STATUS_M_GENI_CMD_ACTIVE_MASK + cmp w2, #GENI_STATUS_M_GENI_CMD_ACTIVE_MASK + b.eq 1b + + /* Transmit data. */ + cmp w0, #0xA + b.ne 3f + + /* Add '\r' when input char is '\n' */ + mov w2, #0x1 + mov w0, #0xD + str w2, [x1, #UART_TX_TRANS_LEN_REG] + mov w2, #GENI_M_CMD_TX + str w2, [x1, #GENI_M_CMD0_REG] + str w0, [x1, #GENI_TX_FIFOn_REG] + mov w0, #0xA + + /* Loop until M_GENI_CMD_ACTIVE bit not clear. */ +2: ldr w2, [x1, #GENI_STATUS_REG] + and w2, w2, #GENI_STATUS_M_GENI_CMD_ACTIVE_MASK + cmp w2, #GENI_STATUS_M_GENI_CMD_ACTIVE_MASK + b.eq 2b + + /* Transmit i/p data. */ +3: mov w2, #0x1 + str w2, [x1, #UART_TX_TRANS_LEN_REG] + mov w2, #GENI_M_CMD_TX + str w2, [x1, #GENI_M_CMD0_REG] + str w0, [x1, #GENI_TX_FIFOn_REG] + + ret +endfunc console_uart_putc + + /* ----------------------------------------------- + * int qti_console_uart_flush(console_t *console) + * In: x0 - pointer to console_t struct + * Out: x0 - 0 for success + * Clobber list: x0, x1 + * ----------------------------------------------- + */ +func console_uart_flush + /* set x0 = UART base. */ + ldr x0, [x0, #CONSOLE_T_BASE] + + /* Loop until M_GENI_CMD_ACTIVE bit not clear. */ +1: ldr w1, [x0, #GENI_STATUS_REG] + and w1, w1, #GENI_STATUS_M_GENI_CMD_ACTIVE_MASK + cmp w1, #GENI_STATUS_M_GENI_CMD_ACTIVE_MASK + b.eq 1b + + mov w0, #0 + ret +endfunc console_uart_flush diff --git a/plat/qti/common/src/qti_bl31_setup.c b/plat/qti/common/src/qti_bl31_setup.c new file mode 100644 index 000000000..b2bc5436f --- /dev/null +++ b/plat/qti/common/src/qti_bl31_setup.c @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* + * Placeholder variables for copying the arguments that have been passed to + * BL31 from BL2. + */ +static entry_point_info_t bl33_image_ep_info; + +/* + * Variable to hold counter frequency for the CPU's generic timer. In this + * platform coreboot image configure counter frequency for boot core before + * reaching TF-A. + */ +static uint64_t g_qti_cpu_cntfrq; + +/* + * Lock variable to serialize cpuss reset execution. + */ +spinlock_t g_qti_cpuss_boot_lock __attribute__ ((section("tzfw_coherent_mem"), + aligned(CACHE_WRITEBACK_GRANULE))) = {0x0}; + +/* + * Variable to hold bl31 cold boot status. Default value 0x0 means yet to boot. + * Any other value means cold booted. + */ +uint32_t g_qti_bl31_cold_booted __attribute__ ((section("tzfw_coherent_mem"))) = 0x0; + +/******************************************************************************* + * Perform any BL31 early platform setup common to ARM standard platforms. + * Here is an opportunity to copy parameters passed by the calling EL (S-EL1 + * in BL2 & S-EL3 in BL1) before they are lost (potentially). This needs to be + * done before the MMU is initialized so that the memory layout can be used + * while creating page tables. BL2 has flushed this information to memory, so + * we are guaranteed to pick up good data. + ******************************************************************************/ +void bl31_early_platform_setup(u_register_t from_bl2, + u_register_t plat_params_from_bl2) +{ + + g_qti_cpu_cntfrq = read_cntfrq_el0(); + + bl_aux_params_parse(plat_params_from_bl2, NULL); + +#if COREBOOT + if (coreboot_serial.baseaddr != 0) { + static console_t g_qti_console_uart; + + qti_console_uart_register(&g_qti_console_uart, + coreboot_serial.baseaddr); + } +#endif + + /* + * Tell BL31 where the non-trusted software image + * is located and the entry state information + */ + bl31_params_parse_helper(from_bl2, NULL, &bl33_image_ep_info); +} + +void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, + u_register_t arg2, u_register_t arg3) +{ + bl31_early_platform_setup(arg0, arg1); +} + +/******************************************************************************* + * Perform the very early platform specific architectural setup here. At the + * moment this only intializes the mmu in a quick and dirty way. + ******************************************************************************/ +void bl31_plat_arch_setup(void) +{ + qti_setup_page_tables(BL_CODE_BASE, + BL_COHERENT_RAM_END - BL_CODE_BASE, + BL_CODE_BASE, + BL_CODE_END, + BL_RO_DATA_BASE, + BL_RO_DATA_END, + BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_END); + enable_mmu_el3(0); +} + +/******************************************************************************* + * Perform any BL31 platform setup common to ARM standard platforms + ******************************************************************************/ +void bl31_platform_setup(void) +{ + generic_delay_timer_init(); + /* Initialize the GIC driver, CPU and distributor interfaces */ + plat_qti_gic_driver_init(); + plat_qti_gic_init(); + qti_interrupt_svc_init(); + qtiseclib_bl31_platform_setup(); + + /* set boot state to cold boot complete. */ + g_qti_bl31_cold_booted = 0x1; +} + +/******************************************************************************* + * Return a pointer to the 'entry_point_info' structure of the next image for the + * security state specified. BL33 corresponds to the non-secure image type + * while BL32 corresponds to the secure image type. A NULL pointer is returned + * if the image does not exist. + ******************************************************************************/ +entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) +{ + /* QTI platform don't have BL32 implementation. */ + assert(type == NON_SECURE); + assert(bl33_image_ep_info.h.type == PARAM_EP); + assert(bl33_image_ep_info.h.attr == NON_SECURE); + /* + * None of the images on the platforms can have 0x0 + * as the entrypoint. + */ + if (bl33_image_ep_info.pc) { + return &bl33_image_ep_info; + } else { + return NULL; + } +} + +/******************************************************************************* + * This function is used by the architecture setup code to retrieve the counter + * frequency for the CPU's generic timer. This value will be programmed into the + * CNTFRQ_EL0 register. In Arm standard platforms, it returns the base frequency + * of the system counter, which is retrieved from the first entry in the + * frequency modes table. This will be used later in warm boot (psci_arch_setup) + * of CPUs to set when CPU frequency. + ******************************************************************************/ +unsigned int plat_get_syscnt_freq2(void) +{ + assert(g_qti_cpu_cntfrq != 0); + return g_qti_cpu_cntfrq; +} diff --git a/plat/qti/common/src/qti_common.c b/plat/qti/common/src/qti_common.c new file mode 100644 index 000000000..ff0fa3060 --- /dev/null +++ b/plat/qti/common/src/qti_common.c @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +/* + * Table of regions for various BL stages to map using the MMU. + * This doesn't include TZRAM as the 'mem_layout' argument passed to + * qti_configure_mmu_elx() will give the available subset of that, + */ + +const mmap_region_t plat_qti_mmap[] = { + MAP_REGION_FLAT(QTI_DEVICE_BASE, QTI_DEVICE_SIZE, + MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(QTI_AOP_CMD_DB_BASE, QTI_AOP_CMD_DB_SIZE, + MT_NS | MT_RO | MT_EXECUTE_NEVER), + {0} +}; + +CASSERT(ARRAY_SIZE(plat_qti_mmap) <= MAX_MMAP_REGIONS, assert_max_mmap_regions); + + +bool qti_is_overlap_atf_rg(unsigned long long addr, size_t size) +{ + if (addr > addr + size + || (BL31_BASE < addr + size && BL31_LIMIT > addr)) { + return true; + } + return false; +} + +/* + * unsigned int plat_qti_my_cluster_pos(void) + * definition to get the cluster index of the calling CPU. + * - In ARM v8 (MPIDR_EL1[24]=0) + * ClusterId = MPIDR_EL1[15:8] + * - In ARM v8.1 & Later version (MPIDR_EL1[24]=1) + * ClusterId = MPIDR_EL1[23:15] + */ +unsigned int plat_qti_my_cluster_pos(void) +{ + unsigned int mpidr, cluster_id; + + mpidr = read_mpidr_el1(); + if ((mpidr & MPIDR_MT_MASK) == 0) { /* MT not supported */ + cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK; + } else { /* MT supported */ + cluster_id = (mpidr >> MPIDR_AFF2_SHIFT) & MPIDR_AFFLVL_MASK; + } + assert(cluster_id < PLAT_CLUSTER_COUNT); + return cluster_id; +} + +/* + * Set up the page tables for the generic and platform-specific memory regions. + * The extents of the generic memory regions are specified by the function + * arguments and consist of: + * - Trusted SRAM seen by the BL image; + * - Code section; + * - Read-only data section; + * - Coherent memory region, if applicable. + */ +void qti_setup_page_tables(uintptr_t total_base, + size_t total_size, + uintptr_t code_start, + uintptr_t code_limit, + uintptr_t rodata_start, + uintptr_t rodata_limit, + uintptr_t coh_start, uintptr_t coh_limit) +{ + /* + * Map the Trusted SRAM with appropriate memory attributes. + * Subsequent mappings will adjust the attributes for specific regions. + */ + VERBOSE("Trusted SRAM seen by this BL image: %p - %p\n", + (void *)total_base, (void *)(total_base + total_size)); + mmap_add_region(total_base, total_base, + total_size, MT_MEMORY | MT_RW | MT_SECURE); + + /* Re-map the code section */ + VERBOSE("Code region: %p - %p\n", + (void *)code_start, (void *)code_limit); + mmap_add_region(code_start, code_start, + code_limit - code_start, MT_CODE | MT_SECURE); + + /* Re-map the read-only data section */ + VERBOSE("Read-only data region: %p - %p\n", + (void *)rodata_start, (void *)rodata_limit); + mmap_add_region(rodata_start, rodata_start, + rodata_limit - rodata_start, MT_RO_DATA | MT_SECURE); + + /* Re-map the coherent memory region */ + VERBOSE("Coherent region: %p - %p\n", + (void *)coh_start, (void *)coh_limit); + mmap_add_region(coh_start, coh_start, + coh_limit - coh_start, MT_DEVICE | MT_RW | MT_SECURE); + + /* Now (re-)map the platform-specific memory regions */ + mmap_add(plat_qti_mmap); + + /* Create the page tables to reflect the above mappings */ + init_xlat_tables(); +} + +static inline void qti_align_mem_region(uintptr_t addr, size_t size, + uintptr_t *aligned_addr, + size_t *aligned_size) +{ + *aligned_addr = round_down(addr, PAGE_SIZE); + *aligned_size = round_up(addr - *aligned_addr + size, PAGE_SIZE); +} + +int qti_mmap_add_dynamic_region(uintptr_t base_pa, size_t size, + unsigned int attr) +{ + uintptr_t aligned_pa; + size_t aligned_size; + + qti_align_mem_region(base_pa, size, &aligned_pa, &aligned_size); + + if (qti_is_overlap_atf_rg(base_pa, size)) { + /* Memory shouldn't overlap with TF-A range. */ + return -EPERM; + } + + return mmap_add_dynamic_region(aligned_pa, aligned_pa, aligned_size, + attr); +} + +int qti_mmap_remove_dynamic_region(uintptr_t base_va, size_t size) +{ + qti_align_mem_region(base_va, size, &base_va, &size); + return mmap_remove_dynamic_region(base_va, size); +} diff --git a/plat/qti/common/src/qti_gic_v3.c b/plat/qti/common/src/qti_gic_v3.c new file mode 100644 index 000000000..a5e0ae7b0 --- /dev/null +++ b/plat/qti/common/src/qti_gic_v3.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include +#include +#include +#include + +/* The GICv3 driver only needs to be initialized in EL3 */ +static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT]; + +/* Array of interrupts to be configured by the gic driver */ +static const interrupt_prop_t qti_interrupt_props[] = { + INTR_PROP_DESC(QTISECLIB_INT_ID_CPU_WAKEUP_SGI, + GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0, + GIC_INTR_CFG_EDGE), + INTR_PROP_DESC(QTISECLIB_INT_ID_RESET_SGI, GIC_HIGHEST_SEC_PRIORITY, + INTR_GROUP0, + GIC_INTR_CFG_EDGE), + INTR_PROP_DESC(QTISECLIB_INT_ID_SEC_WDOG_BARK, GIC_HIGHEST_SEC_PRIORITY, + INTR_GROUP0, + GIC_INTR_CFG_EDGE), + INTR_PROP_DESC(QTISECLIB_INT_ID_NON_SEC_WDOG_BITE, + GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0, + GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(QTISECLIB_INT_ID_VMIDMT_ERR_CLT_SEC, + GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0, + GIC_INTR_CFG_EDGE), + INTR_PROP_DESC(QTISECLIB_INT_ID_VMIDMT_ERR_CLT_NONSEC, + GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0, + GIC_INTR_CFG_EDGE), + INTR_PROP_DESC(QTISECLIB_INT_ID_VMIDMT_ERR_CFG_SEC, + GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0, + GIC_INTR_CFG_EDGE), + INTR_PROP_DESC(QTISECLIB_INT_ID_VMIDMT_ERR_CFG_NONSEC, + GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0, + GIC_INTR_CFG_EDGE), + INTR_PROP_DESC(QTISECLIB_INT_ID_XPU_SEC, GIC_HIGHEST_SEC_PRIORITY, + INTR_GROUP0, + GIC_INTR_CFG_EDGE), + INTR_PROP_DESC(QTISECLIB_INT_ID_XPU_NON_SEC, GIC_HIGHEST_SEC_PRIORITY, + INTR_GROUP0, + GIC_INTR_CFG_EDGE), +#ifdef QTISECLIB_INT_ID_A1_NOC_ERROR + INTR_PROP_DESC(QTISECLIB_INT_ID_A1_NOC_ERROR, GIC_HIGHEST_SEC_PRIORITY, + INTR_GROUP0, + GIC_INTR_CFG_EDGE), +#endif + INTR_PROP_DESC(QTISECLIB_INT_ID_A2_NOC_ERROR, GIC_HIGHEST_SEC_PRIORITY, + INTR_GROUP0, + GIC_INTR_CFG_EDGE), + INTR_PROP_DESC(QTISECLIB_INT_ID_CONFIG_NOC_ERROR, + GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0, + GIC_INTR_CFG_EDGE), + INTR_PROP_DESC(QTISECLIB_INT_ID_DC_NOC_ERROR, GIC_HIGHEST_SEC_PRIORITY, + INTR_GROUP0, + GIC_INTR_CFG_EDGE), + INTR_PROP_DESC(QTISECLIB_INT_ID_MEM_NOC_ERROR, GIC_HIGHEST_SEC_PRIORITY, + INTR_GROUP0, + GIC_INTR_CFG_EDGE), + INTR_PROP_DESC(QTISECLIB_INT_ID_SYSTEM_NOC_ERROR, + GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0, + GIC_INTR_CFG_EDGE), + INTR_PROP_DESC(QTISECLIB_INT_ID_MMSS_NOC_ERROR, + GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0, + GIC_INTR_CFG_EDGE), +}; + +const gicv3_driver_data_t qti_gic_data = { + .gicd_base = QTI_GICD_BASE, + .gicr_base = QTI_GICR_BASE, + .interrupt_props = qti_interrupt_props, + .interrupt_props_num = ARRAY_SIZE(qti_interrupt_props), + .rdistif_num = PLATFORM_CORE_COUNT, + .rdistif_base_addrs = rdistif_base_addrs, + .mpidr_to_core_pos = plat_qti_core_pos_by_mpidr +}; + +void plat_qti_gic_driver_init(void) +{ + /* + * The GICv3 driver is initialized in EL3 and does not need + * to be initialized again in SEL1. This is because the S-EL1 + * can use GIC system registers to manage interrupts and does + * not need GIC interface base addresses to be configured. + */ + gicv3_driver_init(&qti_gic_data); +} + +/****************************************************************************** + * ARM common helper to initialize the GIC. Only invoked by BL31 + *****************************************************************************/ +void plat_qti_gic_init(void) +{ + unsigned int i; + + gicv3_distif_init(); + gicv3_rdistif_init(plat_my_core_pos()); + gicv3_cpuif_enable(plat_my_core_pos()); + + /* Route secure spi interrupt to ANY. */ + for (i = 0; i < ARRAY_SIZE(qti_interrupt_props); i++) { + unsigned int int_id = qti_interrupt_props[i].intr_num; + + if (plat_ic_is_spi(int_id)) { + gicv3_set_spi_routing(int_id, GICV3_IRM_ANY, 0x0); + } + } +} + +void gic_set_spi_routing(unsigned int id, unsigned int irm, u_register_t target) +{ + gicv3_set_spi_routing(id, irm, target); +} + +/****************************************************************************** + * ARM common helper to enable the GIC CPU interface + *****************************************************************************/ +void plat_qti_gic_cpuif_enable(void) +{ + gicv3_cpuif_enable(plat_my_core_pos()); +} + +/****************************************************************************** + * ARM common helper to disable the GIC CPU interface + *****************************************************************************/ +void plat_qti_gic_cpuif_disable(void) +{ + gicv3_cpuif_disable(plat_my_core_pos()); +} + +/****************************************************************************** + * ARM common helper to initialize the per-CPU redistributor interface in GICv3 + *****************************************************************************/ +void plat_qti_gic_pcpu_init(void) +{ + gicv3_rdistif_init(plat_my_core_pos()); +} + +/****************************************************************************** + * ARM common helpers to power GIC redistributor interface + *****************************************************************************/ +void plat_qti_gic_redistif_on(void) +{ + gicv3_rdistif_on(plat_my_core_pos()); +} + +void plat_qti_gic_redistif_off(void) +{ + gicv3_rdistif_off(plat_my_core_pos()); +} diff --git a/plat/qti/common/src/qti_interrupt_svc.c b/plat/qti/common/src/qti_interrupt_svc.c new file mode 100644 index 000000000..89cd7b555 --- /dev/null +++ b/plat/qti/common/src/qti_interrupt_svc.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018,2020, The Linux Foundation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#define QTI_INTR_INVALID_INT_NUM 0xFFFFFFFFU + +/* + * Top-level EL3 interrupt handler. + */ +static uint64_t qti_el3_interrupt_handler(uint32_t id, uint32_t flags, + void *handle, void *cookie) +{ + uint32_t irq = QTI_INTR_INVALID_INT_NUM; + + /* + * EL3 non-interruptible. Interrupt shouldn't occur when we are at + * EL3 / Secure. + */ + assert(handle != cm_get_context(SECURE)); + + irq = plat_ic_acknowledge_interrupt(); + + qtiseclib_invoke_isr(irq, handle); + + /* End of Interrupt. */ + if (irq < 1022U) { + plat_ic_end_of_interrupt(irq); + } + + return (uint64_t) handle; +} + +int qti_interrupt_svc_init(void) +{ + int ret; + uint64_t flags = 0U; + + /* + * Route EL3 interrupts to EL3 when in Non-secure. + * Note: EL3 won't have interrupt enable + * & we don't have S-EL1 support. + */ + set_interrupt_rm_flag(flags, NON_SECURE); + + /* Register handler for EL3 interrupts */ + ret = register_interrupt_type_handler(INTR_TYPE_EL3, + qti_el3_interrupt_handler, flags); + assert(ret == 0); + + return ret; +} diff --git a/plat/qti/common/src/qti_pm.c b/plat/qti/common/src/qti_pm.c new file mode 100644 index 000000000..4a5877c5b --- /dev/null +++ b/plat/qti/common/src/qti_pm.c @@ -0,0 +1,274 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define QTI_LOCAL_PSTATE_WIDTH 4 +#define QTI_LOCAL_PSTATE_MASK ((1 << QTI_LOCAL_PSTATE_WIDTH) - 1) + +/* Make composite power state parameter till level 0 */ +#define qti_make_pwrstate_lvl0(lvl0_state, type) \ + (((lvl0_state) << PSTATE_ID_SHIFT) | ((type) << PSTATE_TYPE_SHIFT)) + +/* Make composite power state parameter till level 1 */ +#define qti_make_pwrstate_lvl1(lvl1_state, lvl0_state, type) \ + (((lvl1_state) << QTI_LOCAL_PSTATE_WIDTH) | \ + qti_make_pwrstate_lvl0(lvl0_state, type)) + +/* Make composite power state parameter till level 2 */ +#define qti_make_pwrstate_lvl2(lvl2_state, lvl1_state, lvl0_state, type) \ + (((lvl2_state) << (QTI_LOCAL_PSTATE_WIDTH * 2)) | \ + qti_make_pwrstate_lvl1(lvl1_state, lvl0_state, type)) + +/* Make composite power state parameter till level 3 */ +#define qti_make_pwrstate_lvl3(lvl3_state, lvl2_state, lvl1_state, lvl0_state, type) \ + (((lvl3_state) << (QTI_LOCAL_PSTATE_WIDTH * 3)) | \ + qti_make_pwrstate_lvl2(lvl2_state, lvl1_state, lvl0_state, type)) + +/* QTI_CORE_PWRDN_EN_MASK happens to be same across all CPUs */ +#define QTI_CORE_PWRDN_EN_MASK 1 + +/* cpu power control happens to be same across all CPUs */ +_DEFINE_SYSREG_WRITE_FUNC(cpu_pwrctrl_val, S3_0_C15_C2_7) +_DEFINE_SYSREG_READ_FUNC(cpu_pwrctrl_val, S3_0_C15_C2_7) + +const unsigned int qti_pm_idle_states[] = { + qti_make_pwrstate_lvl0(QTI_LOCAL_STATE_OFF, + PSTATE_TYPE_POWERDOWN), + qti_make_pwrstate_lvl0(QTI_LOCAL_STATE_DEEPOFF, + PSTATE_TYPE_POWERDOWN), + qti_make_pwrstate_lvl1(QTI_LOCAL_STATE_DEEPOFF, + QTI_LOCAL_STATE_DEEPOFF, + PSTATE_TYPE_POWERDOWN), + qti_make_pwrstate_lvl2(QTI_LOCAL_STATE_OFF, + QTI_LOCAL_STATE_DEEPOFF, + QTI_LOCAL_STATE_DEEPOFF, + PSTATE_TYPE_POWERDOWN), + qti_make_pwrstate_lvl3(QTI_LOCAL_STATE_OFF, + QTI_LOCAL_STATE_DEEPOFF, + QTI_LOCAL_STATE_DEEPOFF, + QTI_LOCAL_STATE_DEEPOFF, + PSTATE_TYPE_POWERDOWN), + 0, +}; + +/******************************************************************************* + * QTI standard platform handler called to check the validity of the power + * state parameter. The power state parameter has to be a composite power + * state. + ******************************************************************************/ +int qti_validate_power_state(unsigned int power_state, + psci_power_state_t *req_state) +{ + unsigned int state_id; + int i; + + assert(req_state); + + /* + * Currently we are using a linear search for finding the matching + * entry in the idle power state array. This can be made a binary + * search if the number of entries justify the additional complexity. + */ + for (i = 0; !!qti_pm_idle_states[i]; i++) { + if (power_state == qti_pm_idle_states[i]) + break; + } + + /* Return error if entry not found in the idle state array */ + if (!qti_pm_idle_states[i]) + return PSCI_E_INVALID_PARAMS; + + i = 0; + state_id = psci_get_pstate_id(power_state); + + /* Parse the State ID and populate the state info parameter */ + while (state_id) { + req_state->pwr_domain_state[i++] = state_id & + QTI_LOCAL_PSTATE_MASK; + state_id >>= QTI_LOCAL_PSTATE_WIDTH; + } + + return PSCI_E_SUCCESS; +} + +/******************************************************************************* + * PLATFORM FUNCTIONS + ******************************************************************************/ + +static void qti_set_cpupwrctlr_val(void) +{ + unsigned long val; + + val = read_cpu_pwrctrl_val(); + val |= QTI_CORE_PWRDN_EN_MASK; + write_cpu_pwrctrl_val(val); + + isb(); +} + +/** + * CPU power on function - ideally we want a wrapper since this function is + * target specific. But to unblock teams. + */ +static int qti_cpu_power_on(u_register_t mpidr) +{ + int core_pos = plat_core_pos_by_mpidr(mpidr); + + /* If not valid mpidr, return error */ + if (core_pos < 0 || core_pos >= QTISECLIB_PLAT_CORE_COUNT) { + return PSCI_E_INVALID_PARAMS; + } + + return qtiseclib_psci_node_power_on(mpidr); +} + +static bool is_cpu_off(const psci_power_state_t *target_state) +{ + if ((target_state->pwr_domain_state[QTI_PWR_LVL0] == + QTI_LOCAL_STATE_OFF) || + (target_state->pwr_domain_state[QTI_PWR_LVL0] == + QTI_LOCAL_STATE_DEEPOFF)) { + return true; + } else { + return false; + } +} + +static void qti_cpu_power_on_finish(const psci_power_state_t *target_state) +{ + const uint8_t *pwr_states = + (const uint8_t *)target_state->pwr_domain_state; + qtiseclib_psci_node_on_finish(pwr_states); + + if (is_cpu_off(target_state)) { + plat_qti_gic_cpuif_enable(); + } +} + +static void qti_cpu_standby(plat_local_state_t cpu_state) +{ +} + +static void qti_node_power_off(const psci_power_state_t *target_state) +{ + qtiseclib_psci_node_power_off((const uint8_t *) + target_state->pwr_domain_state); + if (is_cpu_off(target_state)) { + plat_qti_gic_cpuif_disable(); + qti_set_cpupwrctlr_val(); + } +} + +static void qti_node_suspend(const psci_power_state_t *target_state) +{ + qtiseclib_psci_node_suspend((const uint8_t *)target_state-> + pwr_domain_state); + if (is_cpu_off(target_state)) { + plat_qti_gic_cpuif_disable(); + qti_set_cpupwrctlr_val(); + } +} + +static void qti_node_suspend_finish(const psci_power_state_t *target_state) +{ + const uint8_t *pwr_states = + (const uint8_t *)target_state->pwr_domain_state; + qtiseclib_psci_node_suspend_finish(pwr_states); + if (is_cpu_off(target_state)) { + plat_qti_gic_cpuif_enable(); + } +} + +__dead2 void qti_domain_power_down_wfi(const psci_power_state_t *target_state) +{ + + /* For now just do WFI - add any target specific handling if needed */ + psci_power_down_wfi(); + /* We should never reach here */ +} + +__dead2 void qti_system_off(void) +{ + qtiseclib_psci_system_off(); +} + +__dead2 void qti_system_reset(void) +{ + qtiseclib_psci_system_reset(); +} + +void qti_get_sys_suspend_power_state(psci_power_state_t *req_state) +{ + int i = 0; + unsigned int state_id, power_state; + int size = ARRAY_SIZE(qti_pm_idle_states); + + /* + * Find deepest state. + * The arm_pm_idle_states[] array has last element by default 0, + * so the real deepest state is second last element of that array. + */ + power_state = qti_pm_idle_states[size - 2]; + state_id = psci_get_pstate_id(power_state); + + /* Parse the State ID and populate the state info parameter */ + while (state_id) { + req_state->pwr_domain_state[i++] = + state_id & QTI_LOCAL_PSTATE_MASK; + state_id >>= QTI_LOCAL_PSTATE_WIDTH; + } +} + +/* + * Structure containing platform specific PSCI operations. Common + * PSCI layer will use this. + */ +const plat_psci_ops_t plat_qti_psci_pm_ops = { + .pwr_domain_on = qti_cpu_power_on, + .pwr_domain_on_finish = qti_cpu_power_on_finish, + .cpu_standby = qti_cpu_standby, + .pwr_domain_off = qti_node_power_off, + .pwr_domain_suspend = qti_node_suspend, + .pwr_domain_suspend_finish = qti_node_suspend_finish, + .pwr_domain_pwr_down_wfi = qti_domain_power_down_wfi, + .system_off = qti_system_off, + .system_reset = qti_system_reset, + .get_node_hw_state = NULL, + .translate_power_state_by_mpidr = NULL, + .get_sys_suspend_power_state = qti_get_sys_suspend_power_state, + .validate_power_state = qti_validate_power_state, +}; + +/** + * The QTI Standard platform definition of platform porting API + * `plat_setup_psci_ops`. + */ +int plat_setup_psci_ops(uintptr_t sec_entrypoint, + const plat_psci_ops_t **psci_ops) +{ + int err; + + err = qtiseclib_psci_init((uintptr_t)bl31_warm_entrypoint); + if (err == PSCI_E_SUCCESS) { + *psci_ops = &plat_qti_psci_pm_ops; + } + + return err; +} diff --git a/plat/qti/common/src/qti_stack_protector.c b/plat/qti/common/src/qti_stack_protector.c new file mode 100644 index 000000000..b2dbfb001 --- /dev/null +++ b/plat/qti/common/src/qti_stack_protector.c @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include +#include + +u_register_t plat_get_stack_protector_canary(void) +{ + u_register_t random = 0x0; + + /* get random data , the below API doesn't return random = 0 in success + * case */ + qtiseclib_prng_get_data((uint8_t *) &random, sizeof(random)); + assert(0x0 != random); + + return random; +} diff --git a/plat/qti/common/src/qti_syscall.c b/plat/qti/common/src/qti_syscall.c new file mode 100644 index 000000000..27c48959f --- /dev/null +++ b/plat/qti/common/src/qti_syscall.c @@ -0,0 +1,333 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +/* + * SIP service - SMC function IDs for SiP Service queries + * + */ +#define QTI_SIP_SVC_CALL_COUNT_ID U(0x0200ff00) +#define QTI_SIP_SVC_UID_ID U(0x0200ff01) +/* 0x8200ff02 is reserved */ +#define QTI_SIP_SVC_VERSION_ID U(0x0200ff03) + +/* + * Syscall's to allow Non Secure world accessing peripheral/IO memory + * those are secure/proteced BUT not required to be secure. + */ +#define QTI_SIP_SVC_SECURE_IO_READ_ID U(0x02000501) +#define QTI_SIP_SVC_SECURE_IO_WRITE_ID U(0x02000502) + +/* + * Syscall's to assigns a list of intermediate PAs from a + * source Virtual Machine (VM) to a destination VM. + */ +#define QTI_SIP_SVC_MEM_ASSIGN_ID U(0x02000C16) + +#define QTI_SIP_SVC_SECURE_IO_READ_PARAM_ID U(0x1) +#define QTI_SIP_SVC_SECURE_IO_WRITE_PARAM_ID U(0x2) +#define QTI_SIP_SVC_MEM_ASSIGN_PARAM_ID U(0x1117) + +#define QTI_SIP_SVC_CALL_COUNT U(0x3) +#define QTI_SIP_SVC_VERSION_MAJOR U(0x0) +#define QTI_SIP_SVC_VERSION_MINOR U(0x0) + +#define QTI_VM_LAST U(44) +#define SIZE4K U(0x1000) +#define QTI_VM_MAX_LIST_SIZE U(0x20) + +#define FUNCID_OEN_NUM_MASK ((FUNCID_OEN_MASK << FUNCID_OEN_SHIFT)\ + |(FUNCID_NUM_MASK << FUNCID_NUM_SHIFT)) + +enum { + QTI_SIP_SUCCESS = 0, + QTI_SIP_NOT_SUPPORTED = -1, + QTI_SIP_PREEMPTED = -2, + QTI_SIP_INVALID_PARAM = -3, +}; + +/* QTI SiP Service UUID */ +DEFINE_SVC_UUID2(qti_sip_svc_uid, + 0x43864748, 0x217f, 0x41ad, 0xaa, 0x5a, + 0xba, 0xe7, 0x0f, 0xa5, 0x52, 0xaf); + +static bool qti_is_secure_io_access_allowed(u_register_t addr) +{ + int i = 0; + + for (i = 0; i < ARRAY_SIZE(qti_secure_io_allowed_regs); i++) { + if ((uintptr_t) addr == qti_secure_io_allowed_regs[i]) { + return true; + } + } + + return false; +} + +bool qti_mem_assign_validate_param(memprot_info_t *mem_info, + u_register_t u_num_mappings, + uint32_t *source_vm_list, + u_register_t src_vm_list_cnt, + memprot_dst_vm_perm_info_t *dest_vm_list, + u_register_t dst_vm_list_cnt) +{ + int i; + + if (!source_vm_list || !dest_vm_list || !mem_info + || (src_vm_list_cnt == 0) + || (src_vm_list_cnt >= QTI_VM_LAST) || (dst_vm_list_cnt == 0) + || (dst_vm_list_cnt >= QTI_VM_LAST) || (u_num_mappings == 0) + || u_num_mappings > QTI_VM_MAX_LIST_SIZE) { + return false; + } + for (i = 0; i < u_num_mappings; i++) { + if ((mem_info[i].mem_addr & (SIZE4K - 1)) + || (mem_info[i].mem_size & (SIZE4K - 1))) { + return false; + } + + if ((mem_info[i].mem_addr + mem_info[i].mem_size) < + mem_info[i].mem_addr) { + return false; + } + if (coreboot_get_memory_type(mem_info[i].mem_addr) != + CB_MEM_RAM) { + return false; + } + + if (coreboot_get_memory_type + (mem_info[i].mem_addr + mem_info[i].mem_size) != + CB_MEM_RAM) { + return false; + } + + } + for (i = 0; i < src_vm_list_cnt; i++) { + if (source_vm_list[i] >= QTI_VM_LAST) { + return false; + } + } + for (i = 0; i < dst_vm_list_cnt; i++) { + if (dest_vm_list[i].dst_vm >= QTI_VM_LAST) { + return false; + } + } + return true; +} + +static uintptr_t qti_sip_mem_assign(void *handle, uint32_t smc_cc, + u_register_t x1, + u_register_t x2, + u_register_t x3, u_register_t x4) +{ + uintptr_t dyn_map_start = 0, dyn_map_end = 0; + size_t dyn_map_size = 0; + u_register_t x6, x7; + int ret = QTI_SIP_NOT_SUPPORTED; + u_register_t x5 = read_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X5); + + if (smc_cc == SMC_32) { + x5 = (uint32_t) x5; + } + /* Validate input arg count & retrieve arg3-6 from NS Buffer. */ + if ((x1 != QTI_SIP_SVC_MEM_ASSIGN_PARAM_ID) || (x5 == 0x0)) { + goto unmap_return; + } + + /* Map NS Buffer. */ + dyn_map_start = x5; + dyn_map_size = + (smc_cc == + SMC_32) ? (sizeof(uint32_t) * 4) : (sizeof(uint64_t) * 4); + if (qti_mmap_add_dynamic_region(dyn_map_start, dyn_map_size, + (MT_NS | MT_RO_DATA)) != 0) { + goto unmap_return; + } + /* Retrieve indirect args. */ + if (smc_cc == SMC_32) { + x6 = *((uint32_t *) x5 + 1); + x7 = *((uint32_t *) x5 + 2); + x5 = *(uint32_t *) x5; + } else { + x6 = *((uint64_t *) x5 + 1); + x7 = *((uint64_t *) x5 + 2); + x5 = *(uint64_t *) x5; + } + /* Un-Map NS Buffer. */ + if (qti_mmap_remove_dynamic_region(dyn_map_start, dyn_map_size) != 0) { + goto unmap_return; + } + + /* + * Map NS Buffers. + * arg0,2,4 points to buffers & arg1,3,5 hold sizes. + * MAP api's fail to map if it's already mapped. Let's + * find lowest start & highest end address, then map once. + */ + dyn_map_start = MIN(x2, x4); + dyn_map_start = MIN(dyn_map_start, x6); + dyn_map_end = MAX((x2 + x3), (x4 + x5)); + dyn_map_end = MAX(dyn_map_end, (x6 + x7)); + dyn_map_size = dyn_map_end - dyn_map_start; + + if (qti_mmap_add_dynamic_region(dyn_map_start, dyn_map_size, + (MT_NS | MT_RO_DATA)) != 0) { + goto unmap_return; + } + memprot_info_t *mem_info_p = (memprot_info_t *) x2; + uint32_t u_num_mappings = x3 / sizeof(memprot_info_t); + uint32_t *source_vm_list_p = (uint32_t *) x4; + uint32_t src_vm_list_cnt = x5 / sizeof(uint32_t); + memprot_dst_vm_perm_info_t *dest_vm_list_p = + (memprot_dst_vm_perm_info_t *) x6; + uint32_t dst_vm_list_cnt = + x7 / sizeof(memprot_dst_vm_perm_info_t); + if (qti_mem_assign_validate_param(mem_info_p, u_num_mappings, + source_vm_list_p, src_vm_list_cnt, + dest_vm_list_p, + dst_vm_list_cnt) != true) { + goto unmap_return; + } + + memprot_info_t mem_info[QTI_VM_MAX_LIST_SIZE]; + /* Populating the arguments */ + for (int i = 0; i < u_num_mappings; i++) { + mem_info[i].mem_addr = mem_info_p[i].mem_addr; + mem_info[i].mem_size = mem_info_p[i].mem_size; + } + + memprot_dst_vm_perm_info_t dest_vm_list[QTI_VM_LAST]; + + for (int i = 0; i < dst_vm_list_cnt; i++) { + dest_vm_list[i].dst_vm = dest_vm_list_p[i].dst_vm; + dest_vm_list[i].dst_vm_perm = + dest_vm_list_p[i].dst_vm_perm; + dest_vm_list[i].ctx = dest_vm_list_p[i].ctx; + dest_vm_list[i].ctx_size = dest_vm_list_p[i].ctx_size; + } + + uint32_t source_vm_list[QTI_VM_LAST]; + + for (int i = 0; i < src_vm_list_cnt; i++) { + source_vm_list[i] = source_vm_list_p[i]; + } + /* Un-Map NS Buffers. */ + if (qti_mmap_remove_dynamic_region(dyn_map_start, + dyn_map_size) != 0) { + goto unmap_return; + } + /* Invoke API lib api. */ + ret = qtiseclib_mem_assign(mem_info, u_num_mappings, + source_vm_list, src_vm_list_cnt, + dest_vm_list, dst_vm_list_cnt); + + if (ret == 0) { + SMC_RET2(handle, QTI_SIP_SUCCESS, ret); + } +unmap_return: + /* Un-Map NS Buffers if mapped */ + if (dyn_map_start && dyn_map_size) { + qti_mmap_remove_dynamic_region(dyn_map_start, dyn_map_size); + } + + SMC_RET2(handle, QTI_SIP_INVALID_PARAM, ret); +} + +/* + * This function handles QTI specific syscalls. Currently only SiP calls are present. + * Both FAST & YIELD type call land here. + */ +static uintptr_t qti_sip_handler(uint32_t smc_fid, + u_register_t x1, + u_register_t x2, + u_register_t x3, + u_register_t x4, + void *cookie, void *handle, u_register_t flags) +{ + uint32_t l_smc_fid = smc_fid & FUNCID_OEN_NUM_MASK; + + if (GET_SMC_CC(smc_fid) == SMC_32) { + x1 = (uint32_t) x1; + x2 = (uint32_t) x2; + x3 = (uint32_t) x3; + x4 = (uint32_t) x4; + } + + switch (l_smc_fid) { + case QTI_SIP_SVC_CALL_COUNT_ID: + { + SMC_RET1(handle, QTI_SIP_SVC_CALL_COUNT); + break; + } + case QTI_SIP_SVC_UID_ID: + { + /* Return UID to the caller */ + SMC_UUID_RET(handle, qti_sip_svc_uid); + break; + } + case QTI_SIP_SVC_VERSION_ID: + { + /* Return the version of current implementation */ + SMC_RET2(handle, QTI_SIP_SVC_VERSION_MAJOR, + QTI_SIP_SVC_VERSION_MINOR); + break; + } + case QTI_SIP_SVC_SECURE_IO_READ_ID: + { + if ((x1 == QTI_SIP_SVC_SECURE_IO_READ_PARAM_ID) && + qti_is_secure_io_access_allowed(x2)) { + SMC_RET2(handle, QTI_SIP_SUCCESS, + *((volatile uint32_t *)x2)); + } + SMC_RET1(handle, QTI_SIP_INVALID_PARAM); + break; + } + case QTI_SIP_SVC_SECURE_IO_WRITE_ID: + { + if ((x1 == QTI_SIP_SVC_SECURE_IO_WRITE_PARAM_ID) && + qti_is_secure_io_access_allowed(x2)) { + *((volatile uint32_t *)x2) = x3; + SMC_RET1(handle, QTI_SIP_SUCCESS); + } + SMC_RET1(handle, QTI_SIP_INVALID_PARAM); + break; + } + case QTI_SIP_SVC_MEM_ASSIGN_ID: + { + return qti_sip_mem_assign(handle, GET_SMC_CC(smc_fid), + x1, x2, x3, x4); + break; + } + default: + { + SMC_RET1(handle, QTI_SIP_NOT_SUPPORTED); + } + } + return (uintptr_t) handle; +} + +/* Define a runtime service descriptor for both fast & yield SiP calls */ +DECLARE_RT_SVC(qti_sip_fast_svc, OEN_SIP_START, + OEN_SIP_END, SMC_TYPE_FAST, NULL, qti_sip_handler); + +DECLARE_RT_SVC(qti_sip_yield_svc, OEN_SIP_START, + OEN_SIP_END, SMC_TYPE_YIELD, NULL, qti_sip_handler); diff --git a/plat/qti/common/src/qti_topology.c b/plat/qti/common/src/qti_topology.c new file mode 100644 index 000000000..bf2e3f3b7 --- /dev/null +++ b/plat/qti/common/src/qti_topology.c @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018,2020 The Linux Foundation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include + +/* The QTI power domain tree descriptor */ +const unsigned char qti_power_domain_tree_desc[] = { + /* One domain to represent PDC */ + PLAT_PDC_COUNT, + /* One domain to represent RSC */ + PLAT_RSC_COUNT, + /* There is one top-level FCM cluster */ + PLAT_CLUSTER_COUNT, + /* No. of cores in the FCM cluster */ + PLAT_CLUSTER0_CORE_COUNT +}; + +/******************************************************************************* + * This function returns the ARM default topology tree information. + ******************************************************************************/ +const unsigned char *plat_get_power_domain_tree_desc(void) +{ + return qti_power_domain_tree_desc; +} + +/** Function: plat_core_pos_by_mpidr + * This function implements a part of the critical interface between the psci + * generic layer and the platform that allows the former to query the platform + * to convert an MPIDR to a unique linear index. An error code (-1) is returned + * in case the MPIDR is invalid. + */ +int plat_core_pos_by_mpidr(u_register_t mpidr) +{ + int core_linear_index = plat_qti_core_pos_by_mpidr(mpidr); + + if (core_linear_index < PLATFORM_CORE_COUNT) { + return core_linear_index; + } else { + return -1; + } +} diff --git a/plat/qti/qtiseclib/inc/qtiseclib_cb_interface.h b/plat/qti/qtiseclib/inc/qtiseclib_cb_interface.h new file mode 100644 index 000000000..9c4a7247b --- /dev/null +++ b/plat/qti/qtiseclib/inc/qtiseclib_cb_interface.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QTISECLIB_CB_INTERFACE_H +#define QTISECLIB_CB_INTERFACE_H + +#include +#include +#include +#include + +#include + +/* Standard Library API's */ +void *qtiseclib_cb_memcpy(void *dst, const void *src, size_t len); + +#define QTISECLIB_CB_ERROR(...) qtiseclib_cb_log(QTISECLIB_LOG_LEVEL_ERROR, __VA_ARGS__) +#define QTISECLIB_CB_NOTICE(...) qtiseclib_cb_log(QTISECLIB_LOG_LEVEL_NOTICE, __VA_ARGS__) +#define QTISECLIB_CB_WARN(...) qtiseclib_cb_log(QTISECLIB_LOG_LEVEL_WARNING, __VA_ARGS__) +#define QTISECLIB_CB_INFO(...) qtiseclib_cb_log(QTISECLIB_LOG_LEVEL_INFO, __VA_ARGS__) + +void qtiseclib_cb_log(unsigned int loglvl, const char *fmt, ...); + +void qtiseclib_cb_spin_lock(qtiseclib_cb_spinlock_t *lock); +void qtiseclib_cb_spin_unlock(qtiseclib_cb_spinlock_t *lock); + +unsigned int qtiseclib_cb_plat_my_core_pos(void); +int qtiseclib_cb_plat_core_pos_by_mpidr(u_register_t mpidr); +unsigned int qtiseclib_cb_plat_my_cluster_pos(void); + +/* GIC platform wrappers */ +void qtiseclib_cb_gic_pcpu_init(void); +void qtiseclib_cb_ic_raise_sgi(int sgi_num, u_register_t target); +void qtiseclib_cb_set_spi_routing(unsigned int id, unsigned int irm, + u_register_t target); +/* Crash reporting api's wrappers */ +void qtiseclib_cb_switch_console_to_crash_state(void); + +void qtiseclib_cb_udelay(uint32_t usec); + +#if QTI_SDI_BUILD +int qtiseclib_cb_mmap_remove_dynamic_region(uintptr_t base_va, size_t size); +int qtiseclib_cb_mmap_add_dynamic_region(unsigned long long base_pa, + size_t size, + qtiseclib_mmap_attr_t attr); + +void qtiseclib_cb_flush_dcache_all(void); +void qtiseclib_cb_get_ns_ctx(qtiseclib_dbg_a64_ctxt_regs_type *ns_ctx); +#endif + +#endif /* QTISECLIB_CB_INTERFACE_H */ diff --git a/plat/qti/qtiseclib/inc/qtiseclib_defs.h b/plat/qti/qtiseclib/inc/qtiseclib_defs.h new file mode 100644 index 000000000..2afefe1c8 --- /dev/null +++ b/plat/qti/qtiseclib/inc/qtiseclib_defs.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QTISECLIB_DEFS_H +#define QTISECLIB_DEFS_H + +#include + +#ifndef u_register_t +typedef uintptr_t u_register_t; +#endif + +/* + * Different Log Level supported in qtiseclib. + * TODO: Currently no filtering done on QTISECLIB logs. + */ +#define QTISECLIB_LOG_LEVEL_NONE 0 +#define QTISECLIB_LOG_LEVEL_ERROR 10 +#define QTISECLIB_LOG_LEVEL_NOTICE 20 +#define QTISECLIB_LOG_LEVEL_WARNING 30 +#define QTISECLIB_LOG_LEVEL_INFO 40 +#define QTISECLIB_LOG_LEVEL_VERBOSE 50 + +#define QTI_GICV3_IRM_PE 0 +#define QTI_GICV3_IRM_ANY 1 + +/* Common interrupt number/ID defs. */ +#define QTISECLIB_INT_ID_RESET_SGI (0xf) +#define QTISECLIB_INT_ID_CPU_WAKEUP_SGI (0x8) + +#define QTISECLIB_INT_INVALID_INT_NUM (0xFFFFFFFFU) + +typedef struct qtiseclib_cb_spinlock { + volatile uint32_t lock; +} qtiseclib_cb_spinlock_t; + +#if QTI_SDI_BUILD +/* External CPU Dump Structure - 64 bit EL */ +typedef struct { + uint64_t x0; + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + uint64_t x6; + uint64_t x7; + uint64_t x8; + uint64_t x9; + uint64_t x10; + uint64_t x11; + uint64_t x12; + uint64_t x13; + uint64_t x14; + uint64_t x15; + uint64_t x16; + uint64_t x17; + uint64_t x18; + uint64_t x19; + uint64_t x20; + uint64_t x21; + uint64_t x22; + uint64_t x23; + uint64_t x24; + uint64_t x25; + uint64_t x26; + uint64_t x27; + uint64_t x28; + uint64_t x29; + uint64_t x30; + uint64_t pc; + uint64_t currentEL; + uint64_t sp_el3; + uint64_t elr_el3; + uint64_t spsr_el3; + uint64_t sp_el2; + uint64_t elr_el2; + uint64_t spsr_el2; + uint64_t sp_el1; + uint64_t elr_el1; + uint64_t spsr_el1; + uint64_t sp_el0; + uint64_t __reserved1; + uint64_t __reserved2; + uint64_t __reserved3; + uint64_t __reserved4; + uint64_t __reserved5; + uint64_t __reserved6; + uint64_t __reserved7; + uint64_t __reserved8; +} qtiseclib_dbg_a64_ctxt_regs_type; + +typedef enum qtiseclib_mmap_attr_s { + QTISECLIB_MAP_NS_RO_XN_DATA = 1, + QTISECLIB_MAP_RW_XN_NC_DATA = 2, + QTISECLIB_MAP_RW_XN_DATA = 3, +} qtiseclib_mmap_attr_t; + +#endif /* QTI_SDI_BUILD */ + +#endif /* QTISECLIB_DEFS_H */ diff --git a/plat/qti/qtiseclib/inc/qtiseclib_interface.h b/plat/qti/qtiseclib/inc/qtiseclib_interface.h new file mode 100644 index 000000000..edabc5b69 --- /dev/null +++ b/plat/qti/qtiseclib/inc/qtiseclib_interface.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QTISECLIB_INTERFACE_H +#define QTISECLIB_INTERFACE_H + +#include +#include + +#include + +typedef struct memprot_ipa_info_s { + uint64_t mem_addr; + uint64_t mem_size; +} memprot_info_t; + +typedef struct memprot_dst_vm_perm_info_s { + uint32_t dst_vm; + uint32_t dst_vm_perm; + uint64_t ctx; + uint32_t ctx_size; +} memprot_dst_vm_perm_info_t; + +/* + * QTISECLIB Published API's. + */ + +/* + * Assembly API's + */ + +/* + * CPUSS common reset handler for all CPU wake up (both cold & warm boot). + * Executes on all core. This API assume serialization across CPU + * already taken care before invoking. + * + * Clobbers: x0 - x17, x30 + */ +void qtiseclib_cpuss_reset_asm(uint32_t bl31_cold_boot_state); + +/* + * Execute CPU (Kryo4 gold) specific reset handler / system initialization. + * This takes care of executing required CPU errata's. + * + * Clobbers: x0 - x16 + */ +void qtiseclib_kryo4_gold_reset_asm(void); + +/* + * Execute CPU (Kryo4 silver) specific reset handler / system initialization. + * This takes care of executing required CPU errata's. + * + * Clobbers: x0 - x16 + */ +void qtiseclib_kryo4_silver_reset_asm(void); + +/* + * C Api's + */ +void qtiseclib_bl31_platform_setup(void); +void qtiseclib_invoke_isr(uint32_t irq, void *handle); +void qtiseclib_panic(void); +int qtiseclib_prng_get_data(uint8_t *out, uint32_t out_len); + +int qtiseclib_mem_assign(const memprot_info_t *mem_info, + uint32_t mem_info_list_cnt, + const uint32_t *source_vm_list, + uint32_t src_vm_list_cnt, + const memprot_dst_vm_perm_info_t *dest_vm_list, + uint32_t dst_vm_list_cnt); + +int qtiseclib_psci_init(uintptr_t warmboot_entry); +int qtiseclib_psci_node_power_on(u_register_t mpidr); +void qtiseclib_psci_node_on_finish(const uint8_t *states); +void qtiseclib_psci_cpu_standby(uint8_t pwr_state); +void qtiseclib_psci_node_power_off(const uint8_t *states); +void qtiseclib_psci_node_suspend(const uint8_t *states); +void qtiseclib_psci_node_suspend_finish(const uint8_t *states); +__attribute__ ((noreturn)) +void qtiseclib_psci_system_off(void); +__attribute__ ((noreturn)) +void qtiseclib_psci_system_reset(void); +void qtiseclib_disable_cluster_coherency(uint8_t state); + +#endif /* QTISECLIB_INTERFACE_H */ diff --git a/plat/qti/qtiseclib/inc/sc7180/qtiseclib_defs_plat.h b/plat/qti/qtiseclib/inc/sc7180/qtiseclib_defs_plat.h new file mode 100644 index 000000000..c695c190d --- /dev/null +++ b/plat/qti/qtiseclib/inc/sc7180/qtiseclib_defs_plat.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2018-2020, 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 0x80b00000 +#define BL31_SIZE 0x00100000 + +/*----------------------------------------------------------------------------*/ +/* AOP CMD DB address space for mapping */ +/*----------------------------------------------------------------------------*/ +#define QTI_AOP_CMD_DB_BASE 0x80820000 +#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) + +#define QTISECLIB_INT_ID_A2_NOC_ERROR (0x194) +#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 (0xC6) +#define QTISECLIB_INT_ID_MMSS_NOC_ERROR (0xBA) + +#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 new file mode 100644 index 000000000..1b1393e1e --- /dev/null +++ b/plat/qti/qtiseclib/src/qtiseclib_cb_interface.c @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2018-2020, The Linux Foundation. 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 + +void *qtiseclib_cb_memcpy(void *dst, const void *src, size_t len) +{ + return memcpy(dst, src, len); +} + +/* Printing logs below or equal LOG_LEVEL from QTISECLIB. */ +void qtiseclib_cb_log(unsigned int loglvl, const char *fmt, ...) +{ + if (loglvl <= LOG_LEVEL) { + va_list argp; + static spinlock_t qti_log_lock; + uint64_t uptime = read_cntpct_el0(); + + va_start(argp, fmt); + + spin_lock(&qti_log_lock); + printf("QTISECLIB [%x%08x]", + (uint32_t) ((uptime >> 32) & 0xFFFFFFFF), + (uint32_t) (uptime & 0xFFFFFFFF)); + vprintf(fmt, argp); + putchar('\n'); + spin_unlock(&qti_log_lock); + + va_end(argp); + } +} + +void qtiseclib_cb_spin_lock(qtiseclib_cb_spinlock_t *lock) +{ + spin_lock((spinlock_t *) lock); +} + +void qtiseclib_cb_spin_unlock(qtiseclib_cb_spinlock_t *lock) +{ + spin_unlock((spinlock_t *) lock); +} + +unsigned int qtiseclib_cb_plat_my_core_pos(void) +{ + return plat_my_core_pos(); +} + +int qtiseclib_cb_plat_core_pos_by_mpidr(u_register_t mpidr) +{ + return plat_core_pos_by_mpidr(mpidr); +} + +unsigned int qtiseclib_cb_plat_my_cluster_pos(void) +{ + return plat_qti_my_cluster_pos(); +} + +/* GIC platform functions */ +void qtiseclib_cb_gic_pcpu_init(void) +{ + plat_qti_gic_pcpu_init(); +} + +void qtiseclib_cb_ic_raise_sgi(int sgi_num, u_register_t target) +{ + plat_ic_raise_el3_sgi(sgi_num, target); +} + +void qtiseclib_cb_set_spi_routing(unsigned int id, unsigned int irm, + u_register_t target) +{ + assert(QTI_GICV3_IRM_PE == GICV3_IRM_PE); + assert(QTI_GICV3_IRM_ANY == GICV3_IRM_ANY); + gic_set_spi_routing(id, irm, target); +} + +/* Crash reporting api's wrappers */ +void qtiseclib_cb_switch_console_to_crash_state(void) +{ + console_switch_state(CONSOLE_FLAG_CRASH); +} + +void qtiseclib_cb_udelay(uint32_t usec) +{ + udelay(usec); +} + +#if QTI_SDI_BUILD +void qtiseclib_cb_get_ns_ctx(qtiseclib_dbg_a64_ctxt_regs_type *qti_ns_ctx) +{ + void *ctx; + + ctx = cm_get_context(NON_SECURE); + + qti_ns_ctx->spsr_el3 = + read_ctx_reg(get_el3state_ctx(ctx), CTX_SPSR_EL3); + qti_ns_ctx->elr_el3 = read_ctx_reg(get_el3state_ctx(ctx), CTX_ELR_EL3); + + qti_ns_ctx->spsr_el1 = + read_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_SPSR_EL1); + qti_ns_ctx->elr_el1 = + read_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_ELR_EL1); + qti_ns_ctx->sp_el1 = read_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_SP_EL1); + + qti_ns_ctx->x0 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X0); + qti_ns_ctx->x1 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X1); + qti_ns_ctx->x2 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X2); + qti_ns_ctx->x3 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X3); + qti_ns_ctx->x4 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X4); + qti_ns_ctx->x5 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X5); + qti_ns_ctx->x6 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X6); + qti_ns_ctx->x7 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X7); + qti_ns_ctx->x8 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X8); + qti_ns_ctx->x9 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X9); + qti_ns_ctx->x10 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X10); + qti_ns_ctx->x11 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X11); + qti_ns_ctx->x12 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X12); + qti_ns_ctx->x13 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X13); + qti_ns_ctx->x14 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X14); + qti_ns_ctx->x15 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X15); + qti_ns_ctx->x16 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X16); + qti_ns_ctx->x17 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X17); + qti_ns_ctx->x18 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X18); + qti_ns_ctx->x19 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X19); + qti_ns_ctx->x20 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X20); + qti_ns_ctx->x21 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X21); + qti_ns_ctx->x22 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X22); + qti_ns_ctx->x23 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X23); + qti_ns_ctx->x24 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X24); + qti_ns_ctx->x25 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X25); + qti_ns_ctx->x26 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X26); + qti_ns_ctx->x27 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X27); + qti_ns_ctx->x28 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X28); + qti_ns_ctx->x29 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X29); + qti_ns_ctx->x30 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_LR); + qti_ns_ctx->sp_el0 = + read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_SP_EL0); +} + +void qtiseclib_cb_flush_dcache_all(void) +{ + dcsw_op_all(DCCISW); +} + +int qtiseclib_cb_mmap_add_dynamic_region(unsigned long long base_pa, + size_t size, + qtiseclib_mmap_attr_t attr) +{ + unsigned int l_attr = 0; + + if (attr == QTISECLIB_MAP_NS_RO_XN_DATA) { + l_attr = MT_NS | MT_RO | MT_EXECUTE_NEVER; + } else if (attr == QTISECLIB_MAP_RW_XN_NC_DATA) { + l_attr = MT_RW | MT_NON_CACHEABLE | MT_EXECUTE_NEVER; + } else if (attr == QTISECLIB_MAP_RW_XN_DATA) { + l_attr = MT_RW | MT_EXECUTE_NEVER; + } + return qti_mmap_add_dynamic_region(base_pa, size, l_attr); +} + +int qtiseclib_cb_mmap_remove_dynamic_region(uintptr_t base_va, size_t size) +{ + return qti_mmap_remove_dynamic_region(base_va, size); +} +#endif + diff --git a/plat/qti/qtiseclib/src/qtiseclib_interface_stub.c b/plat/qti/qtiseclib/src/qtiseclib_interface_stub.c new file mode 100644 index 000000000..494083b58 --- /dev/null +++ b/plat/qti/qtiseclib/src/qtiseclib_interface_stub.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include + +#include +#include + +/* + * This file contains dummy implementation of QTISECLIB Published API's. + * which will be used to compile PLATFORM successfully when + * qtiseclib is not available + */ + +/* + * CPUSS common reset handler for all CPU wake up (both cold & warm boot). + * Executes on all core. This API assume serialization across CPU + * already taken care before invoking. + * + * Clobbers: x0 - x17, x30 + */ +void qtiseclib_cpuss_reset_asm(uint32_t bl31_cold_boot_state) +{ +} + +/* + * Execute CPU (Kryo4 gold) specific reset handler / system initialization. + * This takes care of executing required CPU errata's. + * + * Clobbers: x0 - x16 + */ +void qtiseclib_kryo4_gold_reset_asm(void) +{ +} + +/* + * Execute CPU (Kryo4 silver) specific reset handler / system initialization. + * This takes care of executing required CPU errata's. + * + * Clobbers: x0 - x16 + */ +void qtiseclib_kryo4_silver_reset_asm(void) +{ +} + +/* + * C Api's + */ +void qtiseclib_bl31_platform_setup(void) +{ + ERROR("Please use QTISECLIB_PATH while building TF-A\n"); + ERROR("Please refer docs/plat/qti.rst for more details.\n"); + panic(); +} + +void qtiseclib_invoke_isr(uint32_t irq, void *handle) +{ +} + +void qtiseclib_panic(void) +{ +} + +int qtiseclib_prng_get_data(uint8_t *out, uint32_t out_len) +{ + /* fill dummy data to avoid assert and print + * stub implementation in setup call + */ + for (int i = 0; i < out_len; i++) { + out[i] = 0x11; + } + return 0; +} + +int +qtiseclib_mem_assign(const memprot_info_t *mem_info, + uint32_t mem_info_list_cnt, + const uint32_t *source_vm_list, + uint32_t src_vm_list_cnt, + const memprot_dst_vm_perm_info_t *dest_vm_list, + uint32_t dst_vm_list_cnt) +{ + return 0; +} + +int qtiseclib_psci_init(uintptr_t warmboot_entry) +{ + return 0; +} + +int qtiseclib_psci_node_power_on(u_register_t mpidr) +{ + return 0; +} + +void qtiseclib_psci_node_on_finish(const uint8_t *states) +{ +} + +void qtiseclib_psci_cpu_standby(uint8_t pwr_state) +{ +} + +void qtiseclib_psci_node_power_off(const uint8_t *states) +{ +} + +void qtiseclib_psci_node_suspend(const uint8_t *states) +{ +} + +void qtiseclib_psci_node_suspend_finish(const uint8_t *states) +{ +} + +void qtiseclib_psci_system_off(void) +{ + while (1) { + }; +} + +void qtiseclib_psci_system_reset(void) +{ + while (1) { + }; +} + +void qtiseclib_disable_cluster_coherency(uint8_t state) +{ +} + diff --git a/plat/qti/sc7180/inc/platform_def.h b/plat/qti/sc7180/inc/platform_def.h new file mode 100644 index 000000000..d95b365dc --- /dev/null +++ b/plat/qti/sc7180/inc/platform_def.h @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, 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) + +#endif /* PLATFORM_DEF_H */ diff --git a/plat/qti/sc7180/inc/qti_secure_io_cfg.h b/plat/qti/sc7180/inc/qti_secure_io_cfg.h new file mode 100644 index 000000000..3de636ddd --- /dev/null +++ b/plat/qti/sc7180/inc/qti_secure_io_cfg.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2019-2020, 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/sc7180/platform.mk b/plat/qti/sc7180/platform.mk new file mode 100644 index 000000000..45e6b3347 --- /dev/null +++ b/plat/qti/sc7180/platform.mk @@ -0,0 +1,116 @@ +# +# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# Make for SC7180 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 sc7180 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_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/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)/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_IMPL := GIC600 +# 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 fa1fdb223cdc0b01ef944b5fe9664a16867dfa34 Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Tue, 21 Jul 2020 17:07:45 +0100 Subject: plat/arm: Reduce size of BL31 binary BL31 binary size is aligned to 4KB because of the code in include\plat\arm\common\arm_reclaim_init.ld.S: __INIT_CODE_UNALIGNED__ = .; . = ALIGN(PAGE_SIZE); __INIT_CODE_END__ = .; with all the zero data after the last instruction of BL31 code to the end of the page. This causes increase in size of BL31 binary stored in FIP and its loading time by BL2. This patch reduces the size of BL31 image by moving page alignment from __INIT_CODE_END__ to __STACKS_END__ which also increases the stack size for secondary CPUs. Change-Id: Ie2ec503fc774c22c12ec506d74fd3ef2b0b183a9 Signed-off-by: Alexei Fedorov --- include/plat/arm/common/arm_reclaim_init.ld.S | 3 +-- plat/arm/common/arm_bl31_setup.c | 5 ++++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/include/plat/arm/common/arm_reclaim_init.ld.S b/include/plat/arm/common/arm_reclaim_init.ld.S index 03976f34f..e4d4f1254 100644 --- a/include/plat/arm/common/arm_reclaim_init.ld.S +++ b/include/plat/arm/common/arm_reclaim_init.ld.S @@ -13,8 +13,6 @@ SECTIONS . = ALIGN(PAGE_SIZE); __INIT_CODE_START__ = .; *(*text.init*); - __INIT_CODE_UNALIGNED__ = .; - . = ALIGN(PAGE_SIZE); __INIT_CODE_END__ = .; } >RAM @@ -42,6 +40,7 @@ SECTIONS /* Offset mask */ \ MASK = ABS(SIGN >> 63) - 1; \ . += ABS(OFFSET) & ABS(MASK); \ + . = ALIGN(PAGE_SIZE); \ __STACKS_END__ = .; \ /* Total stack size */ \ SIZE = ABS(. - __STACKS_START__); \ diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c index 58ccf0e51..fc238b1d8 100644 --- a/plat/arm/common/arm_bl31_setup.c +++ b/plat/arm/common/arm_bl31_setup.c @@ -46,7 +46,10 @@ CASSERT(BL31_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl31_base_overflows); MT_MEMORY | MT_RW | MT_SECURE) #if RECLAIM_INIT_CODE IMPORT_SYM(unsigned long, __INIT_CODE_START__, BL_INIT_CODE_BASE); -IMPORT_SYM(unsigned long, __INIT_CODE_END__, BL_INIT_CODE_END); +IMPORT_SYM(unsigned long, __INIT_CODE_END__, BL_CODE_END_UNALIGNED); + +#define BL_INIT_CODE_END ((BL_CODE_END_UNALIGNED + PAGE_SIZE - 1) & \ + ~(PAGE_SIZE - 1)) #define MAP_BL_INIT_CODE MAP_REGION_FLAT( \ BL_INIT_CODE_BASE, \ -- cgit v1.2.3 From f3ccf036ecb1ae16287817833ebb07a26dcc0230 Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Tue, 14 Jul 2020 08:17:56 +0100 Subject: TF-A AMU extension: fix detection of group 1 counters. This patch fixes the bug when AMUv1 group1 counters was always assumed being implemented without checking for its presence which was causing exception otherwise. The AMU extension code was also modified as listed below: - Added detection of AMUv1 for ARMv8.6 - 'PLAT_AMU_GROUP1_NR_COUNTERS' build option is removed and number of group1 counters 'AMU_GROUP1_NR_COUNTERS' is now calculated based on 'AMU_GROUP1_COUNTERS_MASK' value - Added bit fields definitions and access functions for AMCFGR_EL0/AMCFGR and AMCGCR_EL0/AMCGCR registers - Unification of amu.c Aarch64 and Aarch32 source files - Bug fixes and TF-A coding style compliant changes. Change-Id: I14e407be62c3026ebc674ec7045e240ccb71e1fb Signed-off-by: Alexei Fedorov --- docs/getting_started/porting-guide.rst | 11 +- include/arch/aarch32/arch.h | 10 ++ include/arch/aarch32/arch_helpers.h | 5 + include/arch/aarch64/arch.h | 7 +- include/arch/aarch64/arch_helpers.h | 3 +- include/lib/extensions/amu.h | 67 +++++++++--- include/lib/extensions/amu_private.h | 12 +-- lib/extensions/amu/aarch32/amu.c | 179 ++++++++++++++++++++++++--------- lib/extensions/amu/aarch64/amu.c | 168 +++++++++++++++++++++---------- 9 files changed, 331 insertions(+), 131 deletions(-) diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst index 6b8bbc634..f3316164b 100644 --- a/docs/getting_started/porting-guide.rst +++ b/docs/getting_started/porting-guide.rst @@ -562,21 +562,14 @@ 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 constants +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. If the platform defines this mask, the following - constant needs to also be defined. - -- **PLAT_AMU_GROUP1_NR_COUNTERS** - This value is used to allocate an array to save and restore the counters - specified by ``PLAT_AMU_GROUP1_COUNTERS_MASK`` on CPU suspend. - This value should be equal to the highest bit position set in the - mask, plus 1. The maximum number of group 1 counters in AMUv1 is 16. + counters are enabled. File : plat_macros.S [mandatory] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/include/arch/aarch32/arch.h b/include/arch/aarch32/arch.h index a11d55e08..1032e1373 100644 --- a/include/arch/aarch32/arch.h +++ b/include/arch/aarch32/arch.h @@ -701,6 +701,16 @@ #define AMEVTYPER1E p15, 0, c13, c15, 6 #define AMEVTYPER1F p15, 0, c13, c15, 7 +/* AMCFGR definitions */ +#define AMCFGR_NCG_SHIFT U(28) +#define AMCFGR_NCG_MASK U(0xf) +#define AMCFGR_N_SHIFT U(0) +#define AMCFGR_N_MASK U(0xff) + +/* AMCGCR definitions */ +#define AMCGCR_CG1NC_SHIFT U(8) +#define AMCGCR_CG1NC_MASK U(0xff) + /******************************************************************************* * Definitions for DynamicIQ Shared Unit registers ******************************************************************************/ diff --git a/include/arch/aarch32/arch_helpers.h b/include/arch/aarch32/arch_helpers.h index eed56e219..94cf7ea9d 100644 --- a/include/arch/aarch32/arch_helpers.h +++ b/include/arch/aarch32/arch_helpers.h @@ -300,11 +300,16 @@ DEFINE_COPROCR_RW_FUNCS(prrr, PRRR) DEFINE_COPROCR_RW_FUNCS(nmrr, NMRR) DEFINE_COPROCR_RW_FUNCS(dacr, DACR) +/* Coproc registers for 32bit AMU support */ +DEFINE_COPROCR_READ_FUNC(amcfgr, AMCFGR) +DEFINE_COPROCR_READ_FUNC(amcgcr, AMCGCR) + DEFINE_COPROCR_RW_FUNCS(amcntenset0, AMCNTENSET0) DEFINE_COPROCR_RW_FUNCS(amcntenset1, AMCNTENSET1) DEFINE_COPROCR_RW_FUNCS(amcntenclr0, AMCNTENCLR0) DEFINE_COPROCR_RW_FUNCS(amcntenclr1, AMCNTENCLR1) +/* Coproc registers for 64bit AMU support */ DEFINE_COPROCR_RW_FUNCS_64(amevcntr00, AMEVCNTR00) DEFINE_COPROCR_RW_FUNCS_64(amevcntr01, AMEVCNTR01) DEFINE_COPROCR_RW_FUNCS_64(amevcntr02, AMEVCNTR02) diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index 90569c3cf..ebe1a244a 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -898,9 +898,14 @@ #define AMEVTYPER1E_EL0 S3_3_C13_C15_6 #define AMEVTYPER1F_EL0 S3_3_C13_C15_7 +/* AMCFGR_EL0 definitions */ +#define AMCFGR_EL0_NCG_SHIFT U(28) +#define AMCFGR_EL0_NCG_MASK U(0xf) +#define AMCFGR_EL0_N_SHIFT U(0) +#define AMCFGR_EL0_N_MASK U(0xff) + /* AMCGCR_EL0 definitions */ #define AMCGCR_EL0_CG1NC_SHIFT U(8) -#define AMCGCR_EL0_CG1NC_LENGTH U(8) #define AMCGCR_EL0_CG1NC_MASK U(0xff) /* MPAM register definitions */ diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h index 09059ca80..4bff0f6f0 100644 --- a/include/arch/aarch64/arch_helpers.h +++ b/include/arch/aarch64/arch_helpers.h @@ -482,7 +482,8 @@ DEFINE_RENAME_SYSREG_WRITE_FUNC(icc_eoir1_el1, ICC_EOIR1_EL1) DEFINE_RENAME_SYSREG_WRITE_FUNC(icc_sgi0r_el1, ICC_SGI0R_EL1) DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sgi1r, ICC_SGI1R) -DEFINE_RENAME_SYSREG_RW_FUNCS(amcgcr_el0, AMCGCR_EL0) +DEFINE_RENAME_SYSREG_READ_FUNC(amcfgr_el0, AMCFGR_EL0) +DEFINE_RENAME_SYSREG_READ_FUNC(amcgcr_el0, AMCGCR_EL0) DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenclr0_el0, AMCNTENCLR0_EL0) DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenset0_el0, AMCNTENSET0_EL0) DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenclr1_el0, AMCNTENCLR1_EL0) diff --git a/include/lib/extensions/amu.h b/include/lib/extensions/amu.h index 99ecfccbb..dcbdd5a67 100644 --- a/include/lib/extensions/amu.h +++ b/include/lib/extensions/amu.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -10,13 +10,14 @@ #include #include -#include - #include #include +#include + /* All group 0 counters */ #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 @@ -24,25 +25,67 @@ #define AMU_GROUP1_COUNTERS_MASK U(0) #endif -#ifdef PLAT_AMU_GROUP1_NR_COUNTERS -#define AMU_GROUP1_NR_COUNTERS PLAT_AMU_GROUP1_NR_COUNTERS +/* 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 U(0) +#define AMU_GROUP1_NR_COUNTERS 0U #endif CASSERT(AMU_GROUP1_COUNTERS_MASK <= 0xffff, invalid_amu_group1_counters_mask); -CASSERT(AMU_GROUP1_NR_COUNTERS <= 16, invalid_amu_group1_nr_counters); + +struct amu_ctx { + uint64_t group0_cnts[AMU_GROUP0_NR_COUNTERS]; + +#if AMU_GROUP1_NR_COUNTERS + uint64_t group1_cnts[AMU_GROUP1_NR_COUNTERS]; +#endif +}; bool amu_supported(void); void amu_enable(bool el2_unused); /* Group 0 configuration helpers */ -uint64_t amu_group0_cnt_read(int idx); -void amu_group0_cnt_write(int idx, uint64_t val); +uint64_t amu_group0_cnt_read(unsigned int idx); +void amu_group0_cnt_write(unsigned int idx, uint64_t val); + +#if AMU_GROUP1_NR_COUNTERS +bool amu_group1_supported(void); /* Group 1 configuration helpers */ -uint64_t amu_group1_cnt_read(int idx); -void amu_group1_cnt_write(int idx, uint64_t val); -void amu_group1_set_evtype(int idx, unsigned int val); +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); +#endif #endif /* AMU_H */ diff --git a/include/lib/extensions/amu_private.h b/include/lib/extensions/amu_private.h index ab4e6aaba..30ce59d3b 100644 --- a/include/lib/extensions/amu_private.h +++ b/include/lib/extensions/amu_private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,11 +9,11 @@ #include -uint64_t amu_group0_cnt_read_internal(int idx); -void amu_group0_cnt_write_internal(int idx, uint64_t val); +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(int idx); -void amu_group1_cnt_write_internal(int idx, uint64_t val); -void amu_group1_set_evtype_internal(int idx, unsigned int 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); #endif /* AMU_PRIVATE_H */ diff --git a/lib/extensions/amu/aarch32/amu.c b/lib/extensions/amu/aarch32/amu.c index 82d2e1864..7e004de31 100644 --- a/lib/extensions/amu/aarch32/amu.c +++ b/lib/extensions/amu/aarch32/amu.c @@ -1,39 +1,74 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ +#include #include #include #include + #include #include #include -#include - -#define AMU_GROUP0_NR_COUNTERS 4 -struct amu_ctx { - uint64_t group0_cnts[AMU_GROUP0_NR_COUNTERS]; - uint64_t group1_cnts[AMU_GROUP1_NR_COUNTERS]; -}; +#include static struct amu_ctx amu_ctxs[PLATFORM_CORE_COUNT]; +/* Check if AMUv1 for Armv8.4 or 8.6 is implemented */ bool amu_supported(void) { - uint64_t features; + uint32_t features = read_id_pfr0() >> ID_PFR0_AMU_SHIFT; - features = read_id_pfr0() >> ID_PFR0_AMU_SHIFT; - return (features & ID_PFR0_AMU_MASK) == 1U; + features &= ID_PFR0_AMU_MASK; + return ((features == 1U) || (features == 2U)); } +#if AMU_GROUP1_NR_COUNTERS +/* Check if group 1 counters is implemented */ +bool amu_group1_supported(void) +{ + uint32_t features = read_amcfgr() >> AMCFGR_NCG_SHIFT; + + return (features & AMCFGR_NCG_MASK) == 1U; +} +#endif + +/* + * 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()) + if (!amu_supported()) { + INFO("AMU is not implemented\n"); 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(); + } + + /* Check number of group 1 counters */ + uint32_t cnt_num = (read_amcgcr() >> AMCGCR_CG1NC_SHIFT) & + AMCGCR_CG1NC_MASK; + 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) { uint64_t v; @@ -49,112 +84,156 @@ void amu_enable(bool el2_unused) /* Enable group 0 counters */ write_amcntenset0(AMU_GROUP0_COUNTERS_MASK); +#if AMU_GROUP1_NR_COUNTERS /* Enable group 1 counters */ write_amcntenset1(AMU_GROUP1_COUNTERS_MASK); +#endif } /* Read the group 0 counter identified by the given `idx`. */ -uint64_t amu_group0_cnt_read(int idx) +uint64_t amu_group0_cnt_read(unsigned int idx) { assert(amu_supported()); - assert((idx >= 0) && (idx < AMU_GROUP0_NR_COUNTERS)); + assert(idx < AMU_GROUP0_NR_COUNTERS); return amu_group0_cnt_read_internal(idx); } -/* Write the group 0 counter identified by the given `idx` with `val`. */ -void amu_group0_cnt_write(int idx, uint64_t val) +/* Write the group 0 counter identified by the given `idx` with `val` */ +void amu_group0_cnt_write(unsigned int idx, uint64_t val) { assert(amu_supported()); - assert((idx >= 0) && (idx < AMU_GROUP0_NR_COUNTERS)); + assert(idx < AMU_GROUP0_NR_COUNTERS); amu_group0_cnt_write_internal(idx, val); isb(); } -/* Read the group 1 counter identified by the given `idx`. */ -uint64_t amu_group1_cnt_read(int idx) +#if AMU_GROUP1_NR_COUNTERS +/* Read the group 1 counter identified by the given `idx` */ +uint64_t amu_group1_cnt_read(unsigned int idx) { assert(amu_supported()); - assert((idx >= 0) && (idx < AMU_GROUP1_NR_COUNTERS)); + assert(amu_group1_supported()); + assert(idx < AMU_GROUP1_NR_COUNTERS); return amu_group1_cnt_read_internal(idx); } -/* Write the group 1 counter identified by the given `idx` with `val`. */ -void amu_group1_cnt_write(int idx, uint64_t val) +/* Write the group 1 counter identified by the given `idx` with `val` */ +void amu_group1_cnt_write(unsigned int idx, uint64_t val) { assert(amu_supported()); - assert((idx >= 0) && (idx < AMU_GROUP1_NR_COUNTERS)); + assert(amu_group1_supported()); + assert(idx < AMU_GROUP1_NR_COUNTERS); amu_group1_cnt_write_internal(idx, val); isb(); } -void amu_group1_set_evtype(int idx, unsigned int val) +/* + * 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_supported()); - assert((idx >= 0) && (idx < AMU_GROUP1_NR_COUNTERS)); + 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) { - struct amu_ctx *ctx; - int i; + struct amu_ctx *ctx = &amu_ctxs[plat_my_core_pos()]; + unsigned int i; - if (!amu_supported()) + if (!amu_supported()) { return (void *)-1; + } - ctx = &amu_ctxs[plat_my_core_pos()]; - - /* Assert that group 0 counter configuration is what we expect */ - assert(read_amcntenset0() == AMU_GROUP0_COUNTERS_MASK && - read_amcntenset1() == AMU_GROUP1_COUNTERS_MASK); +#if AMU_GROUP1_NR_COUNTERS + if (!amu_group1_supported()) { + return (void *)-1; + } +#endif + /* Assert that group 0/1 counter configuration is what we expect */ + assert(read_amcntenset0_el0() == AMU_GROUP0_COUNTERS_MASK); +#if AMU_GROUP1_NR_COUNTERS + assert(read_amcntenset1_el0() == AMU_GROUP1_COUNTERS_MASK); +#endif /* - * Disable group 0 counters to avoid other observers like SCP sampling + * 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); + +#if AMU_GROUP1_NR_COUNTERS write_amcntenclr1(AMU_GROUP1_COUNTERS_MASK); +#endif isb(); - for (i = 0; i < AMU_GROUP0_NR_COUNTERS; i++) + /* Save all group 0 counters */ + for (i = 0U; i < AMU_GROUP0_NR_COUNTERS; i++) { ctx->group0_cnts[i] = amu_group0_cnt_read(i); + } - for (i = 0; i < AMU_GROUP1_NR_COUNTERS; i++) - ctx->group1_cnts[i] = amu_group1_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); + } + } +#endif return (void *)0; } static void *amu_context_restore(const void *arg) { - struct amu_ctx *ctx; - int i; + struct amu_ctx *ctx = &amu_ctxs[plat_my_core_pos()]; + unsigned int i; - if (!amu_supported()) + if (!amu_supported()) { return (void *)-1; + } - ctx = &amu_ctxs[plat_my_core_pos()]; - +#if AMU_GROUP1_NR_COUNTERS + if (!amu_group1_supported()) { + return (void *)-1; + } +#endif /* Counters were disabled in `amu_context_save()` */ - assert((read_amcntenset0() == 0U) && (read_amcntenset1() == 0U)); + assert(read_amcntenset0_el0() == 0U); + +#if AMU_GROUP1_NR_COUNTERS + assert(read_amcntenset1_el0() == 0U); +#endif - /* Restore group 0 counters */ - for (i = 0; i < AMU_GROUP0_NR_COUNTERS; i++) + /* Restore all group 0 counters */ + for (i = 0U; i < AMU_GROUP0_NR_COUNTERS; i++) { amu_group0_cnt_write(i, ctx->group0_cnts[i]); - for (i = 0; i < AMU_GROUP1_NR_COUNTERS; i++) - amu_group1_cnt_write(i, ctx->group1_cnts[i]); + } - /* Enable group 0 counters */ + /* Restore group 0 counter configuration */ write_amcntenset0(AMU_GROUP0_COUNTERS_MASK); - /* Enable group 1 counters */ +#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]); + } + } + + /* Restore group 1 counter configuration */ write_amcntenset1(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 85f7007aa..28529f44e 100644 --- a/lib/extensions/amu/aarch64/amu.c +++ b/lib/extensions/amu/aarch64/amu.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,38 +9,68 @@ #include #include + #include #include #include -#include -#define AMU_GROUP0_NR_COUNTERS 4 - -struct amu_ctx { - uint64_t group0_cnts[AMU_GROUP0_NR_COUNTERS]; - uint64_t group1_cnts[AMU_GROUP1_NR_COUNTERS]; -}; +#include static struct amu_ctx amu_ctxs[PLATFORM_CORE_COUNT]; +/* Check if AMUv1 for Armv8.4 or 8.6 is implemented */ bool amu_supported(void) { - uint64_t features; + uint64_t features = read_id_aa64pfr0_el1() >> ID_AA64PFR0_AMU_SHIFT; + + features &= ID_AA64PFR0_AMU_MASK; + return ((features == 1U) || (features == 2U)); +} + +#if AMU_GROUP1_NR_COUNTERS +/* Check if group 1 counters is implemented */ +bool amu_group1_supported(void) +{ + uint64_t features = read_amcfgr_el0() >> AMCFGR_EL0_NCG_SHIFT; - features = read_id_aa64pfr0_el1() >> ID_AA64PFR0_AMU_SHIFT; - return (features & ID_AA64PFR0_AMU_MASK) == 1U; + return (features & AMCFGR_EL0_NCG_MASK) == 1U; } +#endif /* - * Enable counters. This function is meant to be invoked + * Enable counters. This function is meant to be invoked * by the context management library before exiting from EL3. */ void amu_enable(bool el2_unused) { uint64_t v; - if (!amu_supported()) + if (!amu_supported()) { + INFO("AMU is not implemented\n"); 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(); + } + + /* Check number of group 1 counters */ + uint64_t cnt_num = (read_amcgcr_el0() >> AMCGCR_EL0_CG1NC_SHIFT) & + AMCGCR_EL0_CG1NC_MASK; + 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) { /* @@ -62,43 +92,49 @@ void amu_enable(bool el2_unused) /* Enable group 0 counters */ write_amcntenset0_el0(AMU_GROUP0_COUNTERS_MASK); + +#if AMU_GROUP1_NR_COUNTERS /* Enable group 1 counters */ write_amcntenset1_el0(AMU_GROUP1_COUNTERS_MASK); +#endif } /* Read the group 0 counter identified by the given `idx`. */ -uint64_t amu_group0_cnt_read(int idx) +uint64_t amu_group0_cnt_read(unsigned int idx) { assert(amu_supported()); - assert((idx >= 0) && (idx < AMU_GROUP0_NR_COUNTERS)); + assert(idx < AMU_GROUP0_NR_COUNTERS); return amu_group0_cnt_read_internal(idx); } -/* Write the group 0 counter identified by the given `idx` with `val`. */ -void amu_group0_cnt_write(int idx, uint64_t val) +/* Write the group 0 counter identified by the given `idx` with `val` */ +void amu_group0_cnt_write(unsigned int idx, uint64_t val) { assert(amu_supported()); - assert((idx >= 0) && (idx < AMU_GROUP0_NR_COUNTERS)); + assert(idx < AMU_GROUP0_NR_COUNTERS); amu_group0_cnt_write_internal(idx, val); isb(); } -/* Read the group 1 counter identified by the given `idx`. */ -uint64_t amu_group1_cnt_read(int idx) +#if AMU_GROUP1_NR_COUNTERS +/* Read the group 1 counter identified by the given `idx` */ +uint64_t amu_group1_cnt_read(unsigned int idx) { assert(amu_supported()); - assert((idx >= 0) && (idx < AMU_GROUP1_NR_COUNTERS)); + assert(amu_group1_supported()); + assert(idx < AMU_GROUP1_NR_COUNTERS); return amu_group1_cnt_read_internal(idx); } -/* Write the group 1 counter identified by the given `idx` with `val`. */ -void amu_group1_cnt_write(int idx, uint64_t val) +/* Write the group 1 counter identified by the given `idx` with `val` */ +void amu_group1_cnt_write(unsigned int idx, uint64_t val) { assert(amu_supported()); - assert((idx >= 0) && (idx < AMU_GROUP1_NR_COUNTERS)); + assert(amu_group1_supported()); + assert(idx < AMU_GROUP1_NR_COUNTERS); amu_group1_cnt_write_internal(idx, val); isb(); @@ -106,78 +142,106 @@ void amu_group1_cnt_write(int idx, uint64_t val) /* * Program the event type register for the given `idx` with - * the event number `val`. + * the event number `val` */ -void amu_group1_set_evtype(int idx, unsigned int val) +void amu_group1_set_evtype(unsigned int idx, unsigned int val) { assert(amu_supported()); - assert((idx >= 0) && (idx < AMU_GROUP1_NR_COUNTERS)); + 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) { struct amu_ctx *ctx = &amu_ctxs[plat_my_core_pos()]; - int i; + unsigned int i; - if (!amu_supported()) + if (!amu_supported()) { return (void *)-1; + } +#if AMU_GROUP1_NR_COUNTERS + if (!amu_group1_supported()) { + return (void *)-1; + } +#endif /* Assert that group 0/1 counter configuration is what we expect */ - assert((read_amcntenset0_el0() == AMU_GROUP0_COUNTERS_MASK) && - (read_amcntenset1_el0() == AMU_GROUP1_COUNTERS_MASK)); - - assert(((sizeof(int) * 8) - __builtin_clz(AMU_GROUP1_COUNTERS_MASK)) - <= AMU_GROUP1_NR_COUNTERS); + assert(read_amcntenset0_el0() == AMU_GROUP0_COUNTERS_MASK); +#if AMU_GROUP1_NR_COUNTERS + assert(read_amcntenset1_el0() == 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); + +#if AMU_GROUP1_NR_COUNTERS write_amcntenclr1_el0(AMU_GROUP1_COUNTERS_MASK); +#endif isb(); - /* Save group 0 counters */ - for (i = 0; i < AMU_GROUP0_NR_COUNTERS; i++) + /* Save all group 0 counters */ + for (i = 0U; i < AMU_GROUP0_NR_COUNTERS; i++) { ctx->group0_cnts[i] = amu_group0_cnt_read(i); + } +#if AMU_GROUP1_NR_COUNTERS /* Save group 1 counters */ - for (i = 0; i < AMU_GROUP1_NR_COUNTERS; i++) - ctx->group1_cnts[i] = amu_group1_cnt_read(i); - + 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; } static void *amu_context_restore(const void *arg) { struct amu_ctx *ctx = &amu_ctxs[plat_my_core_pos()]; - int i; + unsigned int i; - if (!amu_supported()) + if (!amu_supported()) { return (void *)-1; + } +#if AMU_GROUP1_NR_COUNTERS + if (!amu_group1_supported()) { + return (void *)-1; + } +#endif /* Counters were disabled in `amu_context_save()` */ - assert((read_amcntenset0_el0() == 0U) && (read_amcntenset1_el0() == 0U)); + assert(read_amcntenset0_el0() == 0U); - assert(((sizeof(int) * 8U) - __builtin_clz(AMU_GROUP1_COUNTERS_MASK)) - <= AMU_GROUP1_NR_COUNTERS); +#if AMU_GROUP1_NR_COUNTERS + assert(read_amcntenset1_el0() == 0U); +#endif - /* Restore group 0 counters */ - for (i = 0; i < AMU_GROUP0_NR_COUNTERS; i++) - if ((AMU_GROUP0_COUNTERS_MASK & (1U << i)) != 0U) - amu_group0_cnt_write(i, ctx->group0_cnts[i]); + /* Restore all group 0 counters */ + for (i = 0U; i < AMU_GROUP0_NR_COUNTERS; i++) { + amu_group0_cnt_write(i, ctx->group0_cnts[i]); + } + /* Restore group 0 counter configuration */ + write_amcntenset0_el0(AMU_GROUP0_COUNTERS_MASK); + +#if AMU_GROUP1_NR_COUNTERS /* Restore group 1 counters */ - for (i = 0; i < AMU_GROUP1_NR_COUNTERS; i++) - if ((AMU_GROUP1_COUNTERS_MASK & (1U << i)) != 0U) + 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 0/1 counter configuration */ - write_amcntenset0_el0(AMU_GROUP0_COUNTERS_MASK); + /* Restore group 1 counter configuration */ write_amcntenset1_el0(AMU_GROUP1_COUNTERS_MASK); +#endif return (void *)0; } -- cgit v1.2.3 From 5e4c97d035a92302f8bce9cec29676306af560a6 Mon Sep 17 00:00:00 2001 From: Stefan Chulski Date: Tue, 25 Jun 2019 15:41:47 +0300 Subject: plat: marvell: ap807: implement workaround for errata-id 3033912 ERRATA ID: RES-3033912 - Internal Address Space Init state causes a hang upon accesses to [0xf070_0000, 0xf07f_ffff] Workaround: Boot Firmware (ATF) should configure CCU_RGF_WIN(4) to split [0x6e_0000, 0xff_ffff] to values [0x6e_0000, 0x6f_ffff] and [0x80_0000, 0xff_ffff] that cause accesses to the segment of [0xf070_0000, 0xf07f_ffff] to act as RAZWI. Reuse common work-around code for both AP806 and AP807. Change-Id: Ia91a4802d02917d1682faa0c81571093d1687d97 Signed-off-by: Stefan Chulski --- drivers/marvell/ccu.c | 17 +++++++++++++++++ drivers/marvell/mochi/ap807_setup.c | 2 ++ drivers/marvell/mochi/apn806_setup.c | 19 +------------------ include/drivers/marvell/ccu.h | 1 + 4 files changed, 21 insertions(+), 18 deletions(-) diff --git a/drivers/marvell/ccu.c b/drivers/marvell/ccu.c index c73516eae..ecf5091b4 100644 --- a/drivers/marvell/ccu.c +++ b/drivers/marvell/ccu.c @@ -30,6 +30,9 @@ ((tgt) == DRAM_1_TID) || \ ((tgt) == RAR_TID)) ? 1 : 0) +#define CCU_RGF(win) (MVEBU_CCU_BASE(MVEBU_AP0) + \ + 0x90 + 4 * (win)) + /* For storage of CR, SCR, ALR, AHR abd GCR */ static uint32_t ccu_regs_save[MVEBU_CCU_MAX_WINS * 4 + 1]; @@ -366,3 +369,17 @@ int init_ccu(int ap_index) return 0; } + +void errata_wa_init(void) +{ + /* + * EERATA ID: RES-3033912 - Internal Address Space Init state causes + * a hang upon accesses to [0xf070_0000, 0xf07f_ffff] + * Workaround: Boot Firmware (ATF) should configure CCU_RGF_WIN(4) to + * split [0x6e_0000, 0xff_ffff] to values [0x6e_0000, 0x6f_ffff] and + * [0x80_0000, 0xff_ffff] that cause accesses to the + * segment of [0xf070_0000, 0xf07f_ffff] to act as RAZWI. + */ + mmio_write_32(CCU_RGF(4), 0x37f9b809); + mmio_write_32(CCU_RGF(5), 0x7ffa0009); +} diff --git a/drivers/marvell/mochi/ap807_setup.c b/drivers/marvell/mochi/ap807_setup.c index 7b6819512..7cdfe051e 100644 --- a/drivers/marvell/mochi/ap807_setup.c +++ b/drivers/marvell/mochi/ap807_setup.c @@ -117,6 +117,8 @@ static void init_aurora2(void) reg |= (0x1 << CCU_SET_POC_OFFSET); mmio_write_32(CCU_HTC_CR, reg); #endif /* LLC_ENABLE */ + + errata_wa_init(); } diff --git a/drivers/marvell/mochi/apn806_setup.c b/drivers/marvell/mochi/apn806_setup.c index 1a02bd4ef..b8925d9f2 100644 --- a/drivers/marvell/mochi/apn806_setup.c +++ b/drivers/marvell/mochi/apn806_setup.c @@ -28,9 +28,6 @@ 0x200) #define CCU_SET_POC_OFFSET 5 -#define CCU_RGF(win) (MVEBU_CCU_BASE(MVEBU_AP0) + \ - 0x90 + 4 * (win)) - #define DSS_CR0 (MVEBU_RFU_BASE + 0x100) #define DVM_48BIT_VA_ENABLE (1 << 21) @@ -95,20 +92,6 @@ static void setup_smmu(void) mmio_write_32(SMMU_sACR, reg); } -static void apn806_errata_wa_init(void) -{ - /* - * ERRATA ID: RES-3033912 - Internal Address Space Init state causes - * a hang upon accesses to [0xf070_0000, 0xf07f_ffff] - * Workaround: Boot Firmware (ATF) should configure CCU_RGF_WIN(4) to - * split [0x6e_0000, 0xff_ffff] to values [0x6e_0000, 0x6f_ffff] and - * [0x80_0000, 0xff_ffff] that cause accesses to the - * segment of [0xf070_0000, 0xf07f_ffff] to act as RAZWI. - */ - mmio_write_32(CCU_RGF(4), 0x37f9b809); - mmio_write_32(CCU_RGF(5), 0x7ffa0009); -} - static void init_aurora2(void) { uint32_t reg; @@ -131,7 +114,7 @@ static void init_aurora2(void) mmio_write_32(CCU_HTC_CR, reg); #endif /* LLC_ENABLE */ - apn806_errata_wa_init(); + errata_wa_init(); } diff --git a/include/drivers/marvell/ccu.h b/include/drivers/marvell/ccu.h index 413ffb972..f8f0adf67 100644 --- a/include/drivers/marvell/ccu.h +++ b/include/drivers/marvell/ccu.h @@ -47,6 +47,7 @@ void ccu_dram_target_set(int ap_index, uint32_t target); void ccu_save_win_all(int ap_id); void ccu_restore_win_all(int ap_id); int ccu_is_win_enabled(int ap_index, uint32_t win_id); +void errata_wa_init(void); #endif #endif /* CCU_H */ -- cgit v1.2.3 From 23d5f03ad00a7a815555d52a15f34fdcc958cccd Mon Sep 17 00:00:00 2001 From: Manish Pandey Date: Fri, 24 Jul 2020 16:43:54 +0100 Subject: cert_create: add Platform owned secure partitions support Add support to generate a certificate named "plat-sp-cert" for Secure Partitions(SP) owned by Platform. Earlier a single certificate file "sip-sp-cert" was generated which contained hash of all 8 SPs, with this change SPs are divided into two categories viz "SiP owned" and "Plat owned" containing 4 SPs each. Platform RoT key pair is used for signing. Signed-off-by: Manish Pandey Change-Id: I5bd493cfce4cf3fc14b87c8ed1045f633d0c92b6 --- include/tools_share/firmware_image_package.h | 2 ++ lib/debugfs/devfip.c | 3 ++- make_helpers/tbbr/tbbr_tools.mk | 3 +++ tools/cert_create/include/dualroot/cot.h | 1 + tools/cert_create/src/dualroot/cot.c | 17 ++++++++++++++++- tools/fiptool/tbbr_config.c | 5 +++++ 6 files changed, 29 insertions(+), 2 deletions(-) diff --git a/include/tools_share/firmware_image_package.h b/include/tools_share/firmware_image_package.h index 7342c0ced..bcde04fd1 100644 --- a/include/tools_share/firmware_image_package.h +++ b/include/tools_share/firmware_image_package.h @@ -66,6 +66,8 @@ {{0x8e, 0xc4, 0xc1, 0xf3}, {0x5d, 0x63}, {0xe4, 0x11}, 0xa7, 0xa9, {0x87, 0xee, 0x40, 0xb2, 0x3f, 0xa7} } #define UUID_SIP_SECURE_PARTITION_CONTENT_CERT \ {{0x77, 0x6d, 0xfd, 0x44}, {0x86, 0x97}, {0x4c, 0x3b}, 0x91, 0xeb, {0xc1, 0x3e, 0x02, 0x5a, 0x2a, 0x6f} } +#define UUID_PLAT_SECURE_PARTITION_CONTENT_CERT \ + {{0xdd, 0xcb, 0xbf, 0x4a}, {0xca, 0xd6}, {0x11, 0xea}, 0x87, 0xd0, {0x02, 0x42, 0xac, 0x13, 0x00, 0x03} } /* Dynamic configs */ #define UUID_HW_CONFIG \ {{0x08, 0xb8, 0xf1, 0xd9}, {0xc9, 0xcf}, {0x93, 0x49}, 0xa9, 0x62, {0x6f, 0xbc, 0x6b, 0x72, 0x65, 0xcc} } diff --git a/lib/debugfs/devfip.c b/lib/debugfs/devfip.c index b0ee39a11..d8b83b7a4 100644 --- a/lib/debugfs/devfip.c +++ b/lib/debugfs/devfip.c @@ -76,7 +76,8 @@ static const struct uuidnames uuidnames[] = { {"fw.cfg", UUID_FW_CONFIG}, {"rot-k.crt", UUID_ROT_KEY_CERT}, {"nt-k.crt", UUID_NON_TRUSTED_WORLD_KEY_CERT}, - {"sip-sp.crt", UUID_SIP_SECURE_PARTITION_CONTENT_CERT} + {"sip-sp.crt", UUID_SIP_SECURE_PARTITION_CONTENT_CERT}, + {"plat-sp.crt", UUID_PLAT_SECURE_PARTITION_CONTENT_CERT} }; /******************************************************************************* diff --git a/make_helpers/tbbr/tbbr_tools.mk b/make_helpers/tbbr/tbbr_tools.mk index 952093443..9c92d3ffb 100644 --- a/make_helpers/tbbr/tbbr_tools.mk +++ b/make_helpers/tbbr/tbbr_tools.mk @@ -103,4 +103,7 @@ endif # Add SiP owned Secure Partitions CoT (image cert) ifneq (${SP_LAYOUT_FILE},) $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/sip_sp_content.crt,--sip-sp-cert)) +ifeq (${COT},dualroot) + $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/plat_sp_content.crt,--plat-sp-cert)) +endif endif diff --git a/tools/cert_create/include/dualroot/cot.h b/tools/cert_create/include/dualroot/cot.h index 1d959d465..3e50c8986 100644 --- a/tools/cert_create/include/dualroot/cot.h +++ b/tools/cert_create/include/dualroot/cot.h @@ -23,6 +23,7 @@ enum { /* Certificates owned by the platform owner. */ NON_TRUSTED_FW_CONTENT_CERT, + PLAT_SECURE_PARTITION_CONTENT_CERT, }; /* Certificate extensions. */ diff --git a/tools/cert_create/src/dualroot/cot.c b/tools/cert_create/src/dualroot/cot.c index a12ea21ff..4dd4cf033 100644 --- a/tools/cert_create/src/dualroot/cot.c +++ b/tools/cert_create/src/dualroot/cot.c @@ -152,12 +152,27 @@ static cert_t cot_certs[] = { SP_PKG2_HASH_EXT, SP_PKG3_HASH_EXT, SP_PKG4_HASH_EXT, + }, + .num_ext = 5 + }, + + [PLAT_SECURE_PARTITION_CONTENT_CERT] = { + .id = PLAT_SECURE_PARTITION_CONTENT_CERT, + .opt = "plat-sp-cert", + .help_msg = "Platform owned Secure Partition Content Certificate (output file)", + .fn = NULL, + .cn = "Platform owned Secure Partition Content Certificate", + .key = PROT_KEY, + .issuer = PLAT_SECURE_PARTITION_CONTENT_CERT, + .ext = { + NON_TRUSTED_FW_NVCOUNTER_EXT, SP_PKG5_HASH_EXT, SP_PKG6_HASH_EXT, SP_PKG7_HASH_EXT, SP_PKG8_HASH_EXT, + PROT_PK_EXT, }, - .num_ext = 9 + .num_ext = 6 }, [FWU_CERT] = { diff --git a/tools/fiptool/tbbr_config.c b/tools/fiptool/tbbr_config.c index bf721c1fa..c1e5217f0 100644 --- a/tools/fiptool/tbbr_config.c +++ b/tools/fiptool/tbbr_config.c @@ -161,6 +161,11 @@ toc_entry_t toc_entries[] = { .uuid = UUID_SIP_SECURE_PARTITION_CONTENT_CERT, .cmdline_name = "sip-sp-cert" }, + { + .name = "Platform owned Secure Partition content certificate", + .uuid = UUID_PLAT_SECURE_PARTITION_CONTENT_CERT, + .cmdline_name = "plat-sp-cert" + }, { .name = NULL, .uuid = { {0} }, -- cgit v1.2.3 From 2947412d547307019c919e8131353538511f83d9 Mon Sep 17 00:00:00 2001 From: Manish Pandey Date: Fri, 31 Jul 2020 16:25:17 +0100 Subject: dualroot: add chain of trust for Platform owned SPs For dualroot CoT there are two sets of SP certificates, one owned by Silicon Provider(SiP) and other owned by Platform. Each certificate can have a maximum of 4 SPs. This patch reduces the number of SiP owned SPs from 8 to 4 and adds the remaining 4 to Plat owned SP. Plat owned SP certificate is signed using Platform RoT key and protected against anti-rollback using the Non-trusted Non-volatile counter. Change-Id: Idc3ddd87d6d85a5506a7435f45a6ec17c4c50425 Signed-off-by: Manish Pandey --- drivers/auth/dualroot/cot.c | 52 +++++++++++++++++++++++++++++--------- include/common/tbbr/tbbr_img_def.h | 19 +++++++------- include/drivers/auth/auth_mod.h | 9 +++++-- 3 files changed, 57 insertions(+), 23 deletions(-) diff --git a/drivers/auth/dualroot/cot.c b/drivers/auth/dualroot/cot.c index 68f3d467f..e1e47bca0 100644 --- a/drivers/auth/dualroot/cot.c +++ b/drivers/auth/dualroot/cot.c @@ -743,29 +743,60 @@ static const auth_img_desc_t sip_sp_content_cert = { .ptr = (void *)sp_pkg_hash_buf[3], .len = (unsigned int)HASH_DER_LEN } + } + } +}; + +DEFINE_SIP_SP_PKG(1); +DEFINE_SIP_SP_PKG(2); +DEFINE_SIP_SP_PKG(3); +DEFINE_SIP_SP_PKG(4); + +static const auth_img_desc_t plat_sp_content_cert = { + .img_id = PLAT_SP_CONTENT_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 = &prot_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } }, - [4] = { + [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 = &sp_pkg5_hash, .data = { .ptr = (void *)sp_pkg_hash_buf[4], .len = (unsigned int)HASH_DER_LEN } }, - [5] = { + [1] = { .type_desc = &sp_pkg6_hash, .data = { .ptr = (void *)sp_pkg_hash_buf[5], .len = (unsigned int)HASH_DER_LEN } }, - [6] = { + [2] = { .type_desc = &sp_pkg7_hash, .data = { .ptr = (void *)sp_pkg_hash_buf[6], .len = (unsigned int)HASH_DER_LEN } }, - [7] = { + [3] = { .type_desc = &sp_pkg8_hash, .data = { .ptr = (void *)sp_pkg_hash_buf[7], @@ -775,14 +806,10 @@ static const auth_img_desc_t sip_sp_content_cert = { } }; -DEFINE_SIP_SP_PKG(1); -DEFINE_SIP_SP_PKG(2); -DEFINE_SIP_SP_PKG(3); -DEFINE_SIP_SP_PKG(4); -DEFINE_SIP_SP_PKG(5); -DEFINE_SIP_SP_PKG(6); -DEFINE_SIP_SP_PKG(7); -DEFINE_SIP_SP_PKG(8); +DEFINE_PLAT_SP_PKG(5); +DEFINE_PLAT_SP_PKG(6); +DEFINE_PLAT_SP_PKG(7); +DEFINE_PLAT_SP_PKG(8); #endif /* SPD_spmd */ #else /* IMAGE_BL2 */ @@ -915,6 +942,7 @@ static const auth_img_desc_t * const cot_desc[] = { [NT_FW_CONFIG_ID] = &nt_fw_config, #if defined(SPD_spmd) [SIP_SP_CONTENT_CERT_ID] = &sip_sp_content_cert, + [PLAT_SP_CONTENT_CERT_ID] = &plat_sp_content_cert, [SP_PKG1_ID] = &sp_pkg1, [SP_PKG2_ID] = &sp_pkg2, [SP_PKG3_ID] = &sp_pkg3, diff --git a/include/common/tbbr/tbbr_img_def.h b/include/common/tbbr/tbbr_img_def.h index b29b1354c..bd125e672 100644 --- a/include/common/tbbr/tbbr_img_def.h +++ b/include/common/tbbr/tbbr_img_def.h @@ -11,16 +11,17 @@ #if defined(SPD_spmd) #define SIP_SP_CONTENT_CERT_ID MAX_IMAGE_IDS -#define SP_PKG1_ID (MAX_IMAGE_IDS + 1) -#define SP_PKG2_ID (MAX_IMAGE_IDS + 2) -#define SP_PKG3_ID (MAX_IMAGE_IDS + 3) -#define SP_PKG4_ID (MAX_IMAGE_IDS + 4) -#define SP_PKG5_ID (MAX_IMAGE_IDS + 5) -#define SP_PKG6_ID (MAX_IMAGE_IDS + 6) -#define SP_PKG7_ID (MAX_IMAGE_IDS + 7) -#define SP_PKG8_ID (MAX_IMAGE_IDS + 8) +#define PLAT_SP_CONTENT_CERT_ID (MAX_IMAGE_IDS + 1) +#define SP_PKG1_ID (MAX_IMAGE_IDS + 2) +#define SP_PKG2_ID (MAX_IMAGE_IDS + 3) +#define SP_PKG3_ID (MAX_IMAGE_IDS + 4) +#define SP_PKG4_ID (MAX_IMAGE_IDS + 5) +#define SP_PKG5_ID (MAX_IMAGE_IDS + 6) +#define SP_PKG6_ID (MAX_IMAGE_IDS + 7) +#define SP_PKG7_ID (MAX_IMAGE_IDS + 8) +#define SP_PKG8_ID (MAX_IMAGE_IDS + 9) #define MAX_SP_IDS U(8) -#define MAX_NUMBER_IDS (MAX_IMAGE_IDS + MAX_SP_IDS + U(1)) +#define MAX_NUMBER_IDS (MAX_IMAGE_IDS + MAX_SP_IDS + U(2)) #else #define MAX_NUMBER_IDS MAX_IMAGE_IDS #endif diff --git a/include/drivers/auth/auth_mod.h b/include/drivers/auth/auth_mod.h index 504e53939..3965b58e7 100644 --- a/include/drivers/auth/auth_mod.h +++ b/include/drivers/auth/auth_mod.h @@ -51,11 +51,15 @@ extern const size_t cot_desc_size; extern unsigned int auth_img_flags[MAX_NUMBER_IDS]; #if defined(SPD_spmd) -#define DEFINE_SIP_SP_PKG(n) \ + +#define DEFINE_SIP_SP_PKG(n) DEFINE_SP_PKG(n, sip_sp_content_cert) +#define DEFINE_PLAT_SP_PKG(n) DEFINE_SP_PKG(n, plat_sp_content_cert) + +#define DEFINE_SP_PKG(n, cert) \ static const auth_img_desc_t sp_pkg##n = { \ .img_id = SP_PKG##n##_ID, \ .img_type = IMG_RAW, \ - .parent = &sip_sp_content_cert, \ + .parent = &cert, \ .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { \ [0] = { \ .type = AUTH_METHOD_HASH, \ @@ -66,6 +70,7 @@ extern unsigned int auth_img_flags[MAX_NUMBER_IDS]; } \ } \ } + #endif #endif /* TRUSTED_BOARD_BOOT */ -- cgit v1.2.3 From e82eb8c8d9adeafb6af70fd6cd37d33747454a8a Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Thu, 13 Aug 2020 12:55:54 +0200 Subject: TF-A AMU: remove AMU enable info print Following f3ccf036ecb1ae1628 the INFO print in amu_enable is causing a lot of print outs on UART1 in DEBUG mode especially on PSCI test cases because CPU_ON or SUSPEND operations call: cm_prepare_el3_exit => enable_extensions_nonsecure => amu_enable. PSCI SUSPEND is also very frequent in linux boot cases causing test timeout failures. Signed-off-by: Olivier Deprez Change-Id: I63581f8fa489d44b3b1d10af3b7f6fdf3af44720 --- lib/extensions/amu/aarch32/amu.c | 1 - lib/extensions/amu/aarch64/amu.c | 1 - 2 files changed, 2 deletions(-) diff --git a/lib/extensions/amu/aarch32/amu.c b/lib/extensions/amu/aarch32/amu.c index 7e004de31..0f75f0791 100644 --- a/lib/extensions/amu/aarch32/amu.c +++ b/lib/extensions/amu/aarch32/amu.c @@ -44,7 +44,6 @@ bool amu_group1_supported(void) void amu_enable(bool el2_unused) { if (!amu_supported()) { - INFO("AMU is not implemented\n"); return; } diff --git a/lib/extensions/amu/aarch64/amu.c b/lib/extensions/amu/aarch64/amu.c index 28529f44e..499736345 100644 --- a/lib/extensions/amu/aarch64/amu.c +++ b/lib/extensions/amu/aarch64/amu.c @@ -46,7 +46,6 @@ void amu_enable(bool el2_unused) uint64_t v; if (!amu_supported()) { - INFO("AMU is not implemented\n"); return; } -- cgit v1.2.3 From 905f93c7700828986444287ccb4dfa538d1b3d2b Mon Sep 17 00:00:00 2001 From: Saurabh Gorecha Date: Thu, 9 Jul 2020 02:20:08 +0530 Subject: qti: Add RNG driver This patch adds RNG driver and use it to generate random number for stack protection. Change-Id: I73d79e68d08b5aa902dc7fad48e17a03f996178d Signed-off-by: Saurabh Gorecha --- plat/qti/common/inc/qti_rng.h | 14 ++++++ plat/qti/common/src/qti_rng.c | 53 +++++++++++++++++++++++ plat/qti/common/src/qti_stack_protector.c | 12 ++--- plat/qti/qtiseclib/inc/qtiseclib_interface.h | 1 - plat/qti/qtiseclib/src/qtiseclib_interface_stub.c | 11 ----- plat/qti/sc7180/inc/qti_rng_io.h | 15 +++++++ plat/qti/sc7180/platform.mk | 1 + 7 files changed, 90 insertions(+), 17 deletions(-) create mode 100644 plat/qti/common/inc/qti_rng.h create mode 100644 plat/qti/common/src/qti_rng.c create mode 100644 plat/qti/sc7180/inc/qti_rng_io.h diff --git a/plat/qti/common/inc/qti_rng.h b/plat/qti/common/inc/qti_rng.h new file mode 100644 index 000000000..c933dea12 --- /dev/null +++ b/plat/qti/common/inc/qti_rng.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QTI_RNG_H +#define QTI_RNG_H + +#include + +int qti_rng_get_data(uint8_t *out, uint32_t out_len); + +#endif /* QTI_RNG_H */ diff --git a/plat/qti/common/src/qti_rng.c b/plat/qti/common/src/qti_rng.c new file mode 100644 index 000000000..a904209be --- /dev/null +++ b/plat/qti/common/src/qti_rng.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include +#include + +#include + +#include + +int qti_rng_get_data(uint8_t *out, uint32_t out_len) +{ + uint32_t tmp_rndm = 0; + uint32_t bytes_left = out_len; + int i = 0; + + if (NULL == out || 0 == out_len) { + return -1; + } + + /* + * RNG HW initialized at previous boot image. + * RNG clocks are expected to be ON. + */ + + do { + /* There is no data to read */ + if ((mmio_read_32(SEC_PRNG_STATUS) & + SEC_PRNG_STATUS_DATA_AVAIL_BMSK) == 0) { + continue; + } + + while ((tmp_rndm = mmio_read_32(SEC_PRNG_DATA_OUT)) == 0) { + ; + } + + for (i = 0; i < 4; i++) { + *out = (uint8_t) (tmp_rndm >> (8 * i)); + + out++; + bytes_left--; + + if (bytes_left == 0) { + break; + } + } + + } while (bytes_left != 0); + + return 0; +} diff --git a/plat/qti/common/src/qti_stack_protector.c b/plat/qti/common/src/qti_stack_protector.c index b2dbfb001..572830f9c 100644 --- a/plat/qti/common/src/qti_stack_protector.c +++ b/plat/qti/common/src/qti_stack_protector.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,16 +9,18 @@ #include #include +#include #include u_register_t plat_get_stack_protector_canary(void) { u_register_t random = 0x0; - /* get random data , the below API doesn't return random = 0 in success - * case */ - qtiseclib_prng_get_data((uint8_t *) &random, sizeof(random)); - assert(0x0 != random); + /* + * get random data , the below API doesn't return random = 0 on success + */ + qti_rng_get_data((uint8_t *) &random, sizeof(random)); + assert(random != 0x0); return random; } diff --git a/plat/qti/qtiseclib/inc/qtiseclib_interface.h b/plat/qti/qtiseclib/inc/qtiseclib_interface.h index edabc5b69..357bb6a2d 100644 --- a/plat/qti/qtiseclib/inc/qtiseclib_interface.h +++ b/plat/qti/qtiseclib/inc/qtiseclib_interface.h @@ -63,7 +63,6 @@ void qtiseclib_kryo4_silver_reset_asm(void); void qtiseclib_bl31_platform_setup(void); void qtiseclib_invoke_isr(uint32_t irq, void *handle); void qtiseclib_panic(void); -int qtiseclib_prng_get_data(uint8_t *out, uint32_t out_len); int qtiseclib_mem_assign(const memprot_info_t *mem_info, uint32_t mem_info_list_cnt, diff --git a/plat/qti/qtiseclib/src/qtiseclib_interface_stub.c b/plat/qti/qtiseclib/src/qtiseclib_interface_stub.c index 494083b58..70485fe90 100644 --- a/plat/qti/qtiseclib/src/qtiseclib_interface_stub.c +++ b/plat/qti/qtiseclib/src/qtiseclib_interface_stub.c @@ -67,17 +67,6 @@ void qtiseclib_panic(void) { } -int qtiseclib_prng_get_data(uint8_t *out, uint32_t out_len) -{ - /* fill dummy data to avoid assert and print - * stub implementation in setup call - */ - for (int i = 0; i < out_len; i++) { - out[i] = 0x11; - } - return 0; -} - int qtiseclib_mem_assign(const memprot_info_t *mem_info, uint32_t mem_info_list_cnt, diff --git a/plat/qti/sc7180/inc/qti_rng_io.h b/plat/qti/sc7180/inc/qti_rng_io.h new file mode 100644 index 000000000..f50234f2b --- /dev/null +++ b/plat/qti/sc7180/inc/qti_rng_io.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2020, 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 0x00791004 +#define SEC_PRNG_STATUS_DATA_AVAIL_BMSK 0x1 +#define SEC_PRNG_DATA_OUT 0x00791000 + + +#endif /* QTI_RNG_IO_H */ + diff --git a/plat/qti/sc7180/platform.mk b/plat/qti/sc7180/platform.mk index 45e6b3347..e55135567 100644 --- a/plat/qti/sc7180/platform.mk +++ b/plat/qti/sc7180/platform.mk @@ -59,6 +59,7 @@ QTI_BL31_SOURCES := $(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_helpers.S \ $(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)/qtiseclib/src/qtiseclib_cb_interface.c \ -- cgit v1.2.3 From d74c6b833616a9e3398352990af78098ea14cffa Mon Sep 17 00:00:00 2001 From: Jimmy Brisson Date: Wed, 5 Aug 2020 14:05:53 -0500 Subject: Prevent colliding identifiers There was a collision between the name of the typedef in the CASSERT and something else, so we make the name of the typedef unique to the invocation of DEFFINE_SVC_UUID2 by appending the name that's passed into the macro. This eliminates the following MISRA violation: bl1/bl1_main.c:233:[MISRA C-2012 Rule 5.6 (required)] Identifier "invalid_svc_uuid" is already used to represent a typedef. This also resolves MISRA rule 5.9. These renamings are as follows: * tzram -> secram. This matches the function call name as it has sec_mem in it's name * fw_config_base -> config_base. This file does not mess with hw_conig, so there's little chance of confusion Change-Id: I8734ba0956140c8e29b89d0596d10d61a6ef351e Signed-off-by: Jimmy Brisson --- include/lib/smccc.h | 3 ++- plat/arm/common/arm_bl2_setup.c | 6 +++--- plat/common/plat_bl1_common.c | 14 +++++++------- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/include/lib/smccc.h b/include/lib/smccc.h index 26509aeca..366f0560b 100644 --- a/include/lib/smccc.h +++ b/include/lib/smccc.h @@ -122,7 +122,8 @@ */ #define DEFINE_SVC_UUID2(_name, _tl, _tm, _th, _cl, _ch, \ _n0, _n1, _n2, _n3, _n4, _n5) \ - CASSERT((uint32_t)(_tl) != (uint32_t)SMC_UNK, invalid_svc_uuid);\ + CASSERT((uint32_t)(_tl) != (uint32_t)SMC_UNK, \ + invalid_svc_uuid_##_name); \ static const uuid_t _name = { \ {((_tl) >> 24) & 0xFF, \ ((_tl) >> 16) & 0xFF, \ diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c index 60d8f6ef3..c90e93cd8 100644 --- a/plat/arm/common/arm_bl2_setup.c +++ b/plat/arm/common/arm_bl2_setup.c @@ -27,7 +27,7 @@ static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE); /* Base address of fw_config received from BL1 */ -static uintptr_t fw_config_base; +static uintptr_t config_base; /* * Check that BL2_BASE is above ARM_FW_CONFIG_LIMIT. This reserved page is @@ -66,7 +66,7 @@ void arm_bl2_early_platform_setup(uintptr_t fw_config, /* Setup the BL2 memory layout */ bl2_tzram_layout = *mem_layout; - fw_config_base = fw_config; + config_base = fw_config; /* Initialise the IO layer and register platform IO devices */ plat_arm_io_setup(); @@ -152,7 +152,7 @@ void bl2_plat_arch_setup(void) arm_bl2_plat_arch_setup(); /* Fill the properties struct with the info from the config dtb */ - fconf_populate("FW_CONFIG", fw_config_base); + fconf_populate("FW_CONFIG", config_base); /* TB_FW_CONFIG was also loaded by BL1 */ tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID); diff --git a/plat/common/plat_bl1_common.c b/plat/common/plat_bl1_common.c index 2baa29aba..d29a27faa 100644 --- a/plat/common/plat_bl1_common.c +++ b/plat/common/plat_bl1_common.c @@ -83,8 +83,8 @@ int bl1_plat_mem_check(uintptr_t mem_base, unsigned int mem_size, */ int bl1_plat_handle_post_image_load(unsigned int image_id) { - meminfo_t *bl2_tzram_layout; - meminfo_t *bl1_tzram_layout; + meminfo_t *bl2_secram_layout; + meminfo_t *bl1_secram_layout; image_desc_t *image_desc; entry_point_info_t *ep_info; @@ -99,7 +99,7 @@ int bl1_plat_handle_post_image_load(unsigned int image_id) 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(); + bl1_secram_layout = bl1_plat_sec_mem_layout(); /* * Create a new layout of memory for BL2 as seen by BL1 i.e. @@ -108,14 +108,14 @@ int bl1_plat_handle_post_image_load(unsigned int image_id) * 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; + bl2_secram_layout = (meminfo_t *) bl1_secram_layout->total_base; - bl1_calc_bl2_mem_layout(bl1_tzram_layout, bl2_tzram_layout); + bl1_calc_bl2_mem_layout(bl1_secram_layout, bl2_secram_layout); - ep_info->args.arg1 = (uintptr_t)bl2_tzram_layout; + ep_info->args.arg1 = (uintptr_t)bl2_secram_layout; VERBOSE("BL1: BL2 memory layout address = %p\n", - (void *) bl2_tzram_layout); + (void *) bl2_secram_layout); return 0; } -- cgit v1.2.3 From e1d5be56ba0f159534f20137401676f6ea697828 Mon Sep 17 00:00:00 2001 From: Jimmy Brisson Date: Wed, 5 Aug 2020 15:33:40 -0500 Subject: Specify signed-ness of constants We relyed on the default signed-ness of constants, which is usually signed. This can create MISRA violations, such as: bl1/bl1_main.c:257:[MISRA C-2012 10.8 (required)] Cast of composite expression off essential type signed to essential type unsigned These constants were only used as unsigned, so this patch makes them explicitly unsigned. Change-Id: I5f1310c881e936077035fbb1d5ffb449b45de3ad Signed-off-by: Jimmy Brisson --- include/bl1/bl1.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/bl1/bl1.h b/include/bl1/bl1.h index e6447f25b..21d3ae7b7 100644 --- a/include/bl1/bl1.h +++ b/include/bl1/bl1.h @@ -26,8 +26,8 @@ /* * BL1 SMC version */ -#define BL1_SMC_MAJOR_VER 0x0 -#define BL1_SMC_MINOR_VER 0x1 +#define BL1_SMC_MAJOR_VER UL(0x0) +#define BL1_SMC_MINOR_VER UL(0x1) /* * Defines for FWU SMC function ids. -- cgit v1.2.3 From 92069086d6f635766fd774084354fbea59a9c43a Mon Sep 17 00:00:00 2001 From: Jimmy Brisson Date: Thu, 6 Aug 2020 10:50:15 -0500 Subject: Use true instead of 1 in while This resolves MISRA defects such as: plat/common/plat_bl1_common.c:63:[MISRA C-2012 Rule 14.4 (required)] The condition expression "1" does not have an essentially boolean type. Change-Id: I679411980ad661191fbc834a44a5eca5494fd0e2 Signed-off-by: Jimmy Brisson --- plat/arm/board/a5ds/a5ds_err.c | 4 ++-- plat/arm/board/fvp/fvp_bl1_setup.c | 2 +- plat/arm/board/fvp_ve/fvp_ve_err.c | 4 ++-- plat/arm/board/juno/juno_bl1_setup.c | 2 +- plat/arm/board/rde1edge/rde1edge_err.c | 4 ++-- plat/arm/board/rdn1edge/rdn1edge_err.c | 4 ++-- plat/arm/board/sgi575/sgi575_err.c | 4 ++-- plat/arm/board/sgm775/sgm775_err.c | 4 ++-- plat/arm/board/tc0/tc0_err.c | 2 +- plat/common/plat_bl1_common.c | 2 +- 10 files changed, 16 insertions(+), 16 deletions(-) diff --git a/plat/arm/board/a5ds/a5ds_err.c b/plat/arm/board/a5ds/a5ds_err.c index 65b41dd4c..feb9fdfaa 100644 --- a/plat/arm/board/a5ds/a5ds_err.c +++ b/plat/arm/board/a5ds/a5ds_err.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Arm Limited. All rights reserved. + * Copyright (c) 2019-2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,7 +11,7 @@ */ void __dead2 plat_arm_error_handler(int err) { - while (1) { + while (true) { wfi(); } } diff --git a/plat/arm/board/fvp/fvp_bl1_setup.c b/plat/arm/board/fvp/fvp_bl1_setup.c index 0e77c4dcc..e713bbc44 100644 --- a/plat/arm/board/fvp/fvp_bl1_setup.c +++ b/plat/arm/board/fvp/fvp_bl1_setup.c @@ -64,7 +64,7 @@ __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 (1) + while (true) wfi(); } diff --git a/plat/arm/board/fvp_ve/fvp_ve_err.c b/plat/arm/board/fvp_ve/fvp_ve_err.c index 7f9d2f7ed..8d3568850 100644 --- a/plat/arm/board/fvp_ve/fvp_ve_err.c +++ b/plat/arm/board/fvp_ve/fvp_ve_err.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Arm Limited. All rights reserved. + * Copyright (c) 2019-2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,7 +11,7 @@ */ void __dead2 plat_arm_error_handler(int err) { - while (1) { + while (true) { wfi(); } } diff --git a/plat/arm/board/juno/juno_bl1_setup.c b/plat/arm/board/juno/juno_bl1_setup.c index 25a27da07..2234055d4 100644 --- a/plat/arm/board/juno/juno_bl1_setup.c +++ b/plat/arm/board/juno/juno_bl1_setup.c @@ -97,7 +97,7 @@ __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 (1) + while (true) wfi(); } diff --git a/plat/arm/board/rde1edge/rde1edge_err.c b/plat/arm/board/rde1edge/rde1edge_err.c index e344d8268..c72c18ced 100644 --- a/plat/arm/board/rde1edge/rde1edge_err.c +++ b/plat/arm/board/rde1edge/rde1edge_err.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Arm Limited. All rights reserved. + * Copyright (c) 2019-2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,7 +11,7 @@ */ void __dead2 plat_arm_error_handler(int err) { - while (1) { + while (true) { wfi(); } } diff --git a/plat/arm/board/rdn1edge/rdn1edge_err.c b/plat/arm/board/rdn1edge/rdn1edge_err.c index cdcbf256a..46d318c7b 100644 --- a/plat/arm/board/rdn1edge/rdn1edge_err.c +++ b/plat/arm/board/rdn1edge/rdn1edge_err.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Arm Limited. All rights reserved. + * Copyright (c) 2019-2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,7 +11,7 @@ */ void __dead2 plat_arm_error_handler(int err) { - while (1) { + while (true) { wfi(); } } diff --git a/plat/arm/board/sgi575/sgi575_err.c b/plat/arm/board/sgi575/sgi575_err.c index c1cc1a7fd..21bfcb73a 100644 --- a/plat/arm/board/sgi575/sgi575_err.c +++ b/plat/arm/board/sgi575/sgi575_err.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Arm Limited. All rights reserved. + * Copyright (c) 2019-2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,7 +11,7 @@ */ void __dead2 plat_arm_error_handler(int err) { - while (1) { + while (true) { wfi(); } } diff --git a/plat/arm/board/sgm775/sgm775_err.c b/plat/arm/board/sgm775/sgm775_err.c index e1e05860d..dc114f07f 100644 --- a/plat/arm/board/sgm775/sgm775_err.c +++ b/plat/arm/board/sgm775/sgm775_err.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Arm Limited. All rights reserved. + * Copyright (c) 2019-2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,7 +11,7 @@ */ void __dead2 plat_arm_error_handler(int err) { - while (1) { + while (true) { wfi(); } } diff --git a/plat/arm/board/tc0/tc0_err.c b/plat/arm/board/tc0/tc0_err.c index 4fc050526..83f2e9f6a 100644 --- a/plat/arm/board/tc0/tc0_err.c +++ b/plat/arm/board/tc0/tc0_err.c @@ -11,7 +11,7 @@ */ void __dead2 plat_arm_error_handler(int err) { - while (1) { + while (true) { wfi(); } } diff --git a/plat/common/plat_bl1_common.c b/plat/common/plat_bl1_common.c index d29a27faa..1c6d68b2b 100644 --- a/plat/common/plat_bl1_common.c +++ b/plat/common/plat_bl1_common.c @@ -60,7 +60,7 @@ struct image_desc *bl1_plat_get_image_desc(unsigned int image_id) __dead2 void bl1_plat_fwu_done(void *client_cookie, void *reserved) { - while (1) + while (true) wfi(); } -- cgit v1.2.3 From a88b3c296ab99fb7080de199a0b6291d2b44fceb Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Mon, 3 Aug 2020 10:27:19 +0200 Subject: doc: Stop advising the creation of Phabricator issues We have noticed that Phabricator (the ticketing system on tf.org [1]) has far less visibility within the community than the mailing list [2]. For this reason, let's drop usage of Phabricator for anything else than bug reports. For the rest, advise contributors to start a discussion on the mailing list, where they are more likely to get feedback. [1] https://developer.trustedfirmware.org/project/board/1/ [2] https://lists.trustedfirmware.org/mailman/listinfo/tf-a Change-Id: I7d2d3d305ad0a0f8aacc2a2f25eb5ff429853a3f Signed-off-by: Sandrine Bailleux --- docs/about/contact.rst | 8 ++++---- docs/process/contributing.rst | 17 ++++++++++------- docs/process/security.rst | 13 +++++++------ 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/docs/about/contact.rst b/docs/about/contact.rst index 9cb25ef47..7c6a5de78 100644 --- a/docs/about/contact.rst +++ b/docs/about/contact.rst @@ -27,9 +27,9 @@ You can see a `summary of all the lists`_ on the TrustedFirmware.org website. Issue Tracker ^^^^^^^^^^^^^ -Specific issues may be raised using the `issue tracker`_ on the -TrustedFirmware.org website. Using this tracker makes it easy for the -maintainers to prioritise and respond to your ticket. +Bug reports may be filed on the `issue tracker`_ on the TrustedFirmware.org +website. Using this tracker gives everyone visibility of the known issues in +TF-A. Arm Licensees ^^^^^^^^^^^^^ @@ -44,4 +44,4 @@ via their partner managers. -------------- -*Copyright (c) 2019, Arm Limited. All rights reserved.* +*Copyright (c) 2019-2020, Arm Limited. All rights reserved.* diff --git a/docs/process/contributing.rst b/docs/process/contributing.rst index 7886cf4f5..5e490a967 100644 --- a/docs/process/contributing.rst +++ b/docs/process/contributing.rst @@ -6,12 +6,16 @@ Getting Started - Make sure you have a Github account and you are logged on both `developer.trustedfirmware.org`_ and `review.trustedfirmware.org`_. -- Create an `issue`_ for your work if one does not already exist. This gives - everyone visibility of whether others are working on something similar. - - If you intend to include Third Party IP in your contribution, please - raise a separate `issue`_ for this and ensure that the changes that - include Third Party IP are made on a separate topic branch. +- If you plan to contribute a major piece of work, it is usually a good idea to + start a discussion around it on the mailing list. This gives everyone + visibility of what is coming up, you might learn that somebody else is + already working on something similar or the community might be able to + provide some early input to help shaping the design of the feature. + + If you intend to include Third Party IP in your contribution, please mention + it explicitly in the email thread and ensure that the changes that include + Third Party IP are made in a separate patch (or patch series). - Clone `Trusted Firmware-A`_ on your own machine as described in :ref:`prerequisites_get_source`. @@ -29,8 +33,7 @@ Making Changes Makefile target is provided for convenience. - Keep the commits on topic. If you need to fix another bug or make another - enhancement, please create a separate `issue`_ and address it on a separate - topic branch. + enhancement, please address it on a separate topic branch. - 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. - Make sure your commit messages are in the proper format. If a commit fixes diff --git a/docs/process/security.rst b/docs/process/security.rst index 516eb98d7..0d59e723c 100644 --- a/docs/process/security.rst +++ b/docs/process/security.rst @@ -21,12 +21,12 @@ Although we try to keep TF-A secure, we can only do so with the help of the community of developers and security researchers. If you think you have found a security vulnerability, please **do not** report -it in the `issue tracker`_. Instead, please follow the `TrustedFirmware.org -security incident process`_. One of the goals of this process is to ensure -providers of products that use TF-A have a chance to consider the implications -of the vulnerability and its remedy before it is made public. As such, please -follow the disclosure plan outlined in the process. We do our best to respond -and fix any issues quickly. +it in the `issue tracker`_ or on the `mailing list`_. Instead, please follow the +`TrustedFirmware.org security incident process`_. One of the goals of this +process is to ensure providers of products that use TF-A have a chance to +consider the implications of the vulnerability and its remedy before it is made +public. As such, please follow the disclosure plan outlined in the process. We +do our best to respond and fix any issues quickly. Afterwards, we encourage you to write-up your findings about the TF-A source code. @@ -69,6 +69,7 @@ Security Advisories +-----------+------------------------------------------------------------------+ .. _issue tracker: https://developer.trustedfirmware.org/project/board/1/ +.. _mailing list: https://lists.trustedfirmware.org/mailman/listinfo/tf-a .. |TFV-1| replace:: :ref:`Advisory TFV-1 (CVE-2016-10319)` .. |TFV-2| replace:: :ref:`Advisory TFV-2 (CVE-2017-7564)` -- cgit v1.2.3 From ecad5b8966dd098fdc37dc448d66841bc6148131 Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Wed, 12 Aug 2020 10:52:32 +0200 Subject: doc: Emphasize that security issues must not be reported as normal bugs Change-Id: I43e452c9993a8608b20ec029562982f5dcf8e6b2 Signed-off-by: Sandrine Bailleux --- docs/process/security.rst | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/docs/process/security.rst b/docs/process/security.rst index 0d59e723c..a3b9971e4 100644 --- a/docs/process/security.rst +++ b/docs/process/security.rst @@ -20,13 +20,15 @@ Found a Security Issue? Although we try to keep TF-A secure, we can only do so with the help of the community of developers and security researchers. -If you think you have found a security vulnerability, please **do not** report -it in the `issue tracker`_ or on the `mailing list`_. Instead, please follow the -`TrustedFirmware.org security incident process`_. One of the goals of this -process is to ensure providers of products that use TF-A have a chance to -consider the implications of the vulnerability and its remedy before it is made -public. As such, please follow the disclosure plan outlined in the process. We -do our best to respond and fix any issues quickly. +.. warning:: + If you think you have found a security vulnerability, please **do not** + report it in the `issue tracker`_ or on the `mailing list`_. Instead, please + follow the `TrustedFirmware.org security incident process`_. + +One of the goals of this process is to ensure providers of products that use +TF-A have a chance to consider the implications of the vulnerability and its +remedy before it is made public. As such, please follow the disclosure plan +outlined in the process. We do our best to respond and fix any issues quickly. Afterwards, we encourage you to write-up your findings about the TF-A source code. -- cgit v1.2.3 From 155eac294a9e27e177339a36eeabbaf5025795d1 Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Wed, 12 Aug 2020 13:41:41 +0200 Subject: doc: Mention the TF-A Tech Forum as a way to contact developers Change-Id: Ib4ad853ebb6e28adcf9ed14714d43799f9370343 Signed-off-by: Sandrine Bailleux --- docs/about/contact.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/about/contact.rst b/docs/about/contact.rst index 7c6a5de78..4440a371a 100644 --- a/docs/about/contact.rst +++ b/docs/about/contact.rst @@ -24,6 +24,15 @@ The relevant lists for the TF-A project are: You can see a `summary of all the lists`_ on the TrustedFirmware.org website. +Open Tech Forum Call +^^^^^^^^^^^^^^^^^^^^ + +Every other week, we organize a call with all interested TF-A contributors. +Anyone is welcome to join. This is an opportunity to discuss any technical +topic within the community. More details can be found `here`_. + +.. _here: https://www.trustedfirmware.org/meetings/tf-a-technical-forum/ + Issue Tracker ^^^^^^^^^^^^^ -- cgit v1.2.3 From e256cc63ae6a577af24b184783b54cc38e5ecc55 Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Wed, 12 Aug 2020 11:29:46 +0200 Subject: doc: Refactor the contribution guidelines Ensuring that each file changed by a patch has the correct copyright and license information does not only apply to documentation files but to all files within the source tree. Move the guidance for copyright and license headers out of the paragraph about updating the documentation to avoid any confusion. Also do some cosmetic changes (adding empty lines, fitting in longer lines in the 80-column limit, ...) to improve the readability of the RST file. Change-Id: I241a2089ca9db70f5a9f26b7070b947674b43265 Signed-off-by: Sandrine Bailleux --- docs/process/contributing.rst | 49 +++++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/docs/process/contributing.rst b/docs/process/contributing.rst index 5e490a967..bdfb6d6aa 100644 --- a/docs/process/contributing.rst +++ b/docs/process/contributing.rst @@ -19,6 +19,7 @@ Getting Started - Clone `Trusted Firmware-A`_ on your own machine as described in :ref:`prerequisites_get_source`. + - Create a local topic branch based on the `Trusted Firmware-A`_ ``master`` branch. @@ -27,6 +28,7 @@ Making Changes - Make commits of logical units. See these general `Git guidelines`_ for contributing to a project. + - Follow the :ref:`Coding Style` and :ref:`Coding Guidelines`. - Use the checkpatch.pl script provided with the Linux source tree. A @@ -34,36 +36,43 @@ Making Changes - Keep the commits on topic. If you need to fix another bug or make another enhancement, please address it on a separate topic branch. + - 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. + - Make sure your commit messages are in the proper format. If a commit fixes an `issue`_, include a reference. -- Where appropriate, please update the documentation. - - - Consider whether the :ref:`Porting Guide`, - :ref:`Firmware Design` document or other in-source documentation needs - updating. - - Ensure that each changed file has the correct copyright and license - information. Files that entirely consist of contributions to this - project should have a copyright notice and BSD-3-Clause SPDX license - identifier of the form as shown in :ref:`license`. Files that contain - changes to imported Third Party IP files should retain their original - copyright and license notices. For significant contributions you may - add your own copyright notice in following format: - :: +- Where appropriate, please update the documentation. - Portions copyright (c) [XXXX-]YYYY, . All rights reserved. + - Consider whether the :ref:`Porting Guide`, :ref:`Firmware Design` document + or other in-source documentation needs updating. - where XXXX is the year of first contribution (if different to YYYY) and - YYYY is the year of most recent contribution. is your name or - your company name. - If you are submitting new files that you intend to be the code owner for (for example, a new platform port), then also update the :ref:`code owners` file. - - For topics with multiple commits, you should make all documentation - changes (and nothing else) in the last commit of the series. Otherwise, - include the documentation changes within the single commit. + + - For topics with multiple commits, you should make all documentation changes + (and nothing else) in the last commit of the series. Otherwise, include + the documentation changes within the single commit. + +- Ensure that each changed file has the correct copyright and license + information. Files that entirely consist of contributions to this project + should have a copyright notice and BSD-3-Clause SPDX license identifier of + the form as shown in :ref:`license`. Files that contain changes to imported + Third Party IP files should retain their original copyright and license + notices. + + For significant contributions you may add your own copyright notice in the + following format: + + :: + + Portions copyright (c) [XXXX-]YYYY, . All rights reserved. + + where XXXX is the year of first contribution (if different to YYYY) and YYYY + is the year of most recent contribution. is your name or your company + name. - Please test your changes. As a minimum, ensure that Linux boots on the Foundation FVP. See :ref:`Arm Fixed Virtual Platforms (FVP)` for more -- cgit v1.2.3 From 990d972f1bd7c0c26102fa9876e5baabf648d4f5 Mon Sep 17 00:00:00 2001 From: Manish Pandey Date: Fri, 31 Jul 2020 16:15:16 +0100 Subject: plat/arm: enable support for Plat owned SPs For Arm platforms SPs are loaded by parsing tb_fw_config.dts and adding them to SP structure sequentially, which in-turn is appended to loadable image list. With recently introduced dualroot CoT for SPs where they are owned either by SiP or by Platform. SiP owned SPs index starts at SP_PKG1_ID and Plat owned SPs index starts at SP_PKG5_ID. As the start index of SP depends on the owner, there should be a mechanism to parse owner of a SP and put it at the correct index in SP structure. This patch adds support for parsing a new optional field "owner" and based on it put SP details(UUID & Load-address) at the correct index in SP structure. Change-Id: Ibd255b60d5c45023cc7fdb10971bef6626cb560b Signed-off-by: Manish Pandey --- include/plat/arm/common/fconf_arm_sp_getter.h | 2 + plat/arm/common/fconf/arm_fconf_io.c | 9 +++- plat/arm/common/fconf/arm_fconf_sp.c | 76 ++++++++++++++++++++------- 3 files changed, 66 insertions(+), 21 deletions(-) diff --git a/include/plat/arm/common/fconf_arm_sp_getter.h b/include/plat/arm/common/fconf_arm_sp_getter.h index 236254bd2..c6315bee2 100644 --- a/include/plat/arm/common/fconf_arm_sp_getter.h +++ b/include/plat/arm/common/fconf_arm_sp_getter.h @@ -14,11 +14,13 @@ #define arm__sp_getter(prop) arm_sp.prop #define ARM_SP_MAX_SIZE U(0x80000) +#define ARM_SP_OWNER_NAME_LEN U(8) struct arm_sp_t { unsigned int number_of_sp; union uuid_helper_t uuids[MAX_SP_IDS]; uintptr_t load_addr[MAX_SP_IDS]; + char owner[MAX_SP_IDS][ARM_SP_OWNER_NAME_LEN]; }; int fconf_populate_arm_sp(uintptr_t config); diff --git a/plat/arm/common/fconf/arm_fconf_io.c b/plat/arm/common/fconf/arm_fconf_io.c index 350ecd1b6..5f125d3d5 100644 --- a/plat/arm/common/fconf/arm_fconf_io.c +++ b/plat/arm/common/fconf/arm_fconf_io.c @@ -52,6 +52,7 @@ const io_uuid_spec_t arm_uuid_spec[MAX_NUMBER_IDS] = { [NON_TRUSTED_FW_CONTENT_CERT_ID] = {UUID_NON_TRUSTED_FW_CONTENT_CERT}, #if defined(SPD_spmd) [SIP_SP_CONTENT_CERT_ID] = {UUID_SIP_SECURE_PARTITION_CONTENT_CERT}, + [PLAT_SP_CONTENT_CERT_ID] = {UUID_PLAT_SECURE_PARTITION_CONTENT_CERT}, #endif #endif /* ARM_IO_IN_DTB */ #endif /* TRUSTED_BOARD_BOOT */ @@ -189,6 +190,11 @@ struct plat_io_policy policies[MAX_NUMBER_IDS] = { (uintptr_t)&arm_uuid_spec[SIP_SP_CONTENT_CERT_ID], open_fip }, + [PLAT_SP_CONTENT_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[PLAT_SP_CONTENT_CERT_ID], + open_fip + }, #endif #endif /* ARM_IO_IN_DTB */ #endif /* TRUSTED_BOARD_BOOT */ @@ -197,7 +203,7 @@ struct plat_io_policy policies[MAX_NUMBER_IDS] = { #ifdef IMAGE_BL2 #if TRUSTED_BOARD_BOOT -#define FCONF_ARM_IO_UUID_NUMBER U(20) +#define FCONF_ARM_IO_UUID_NUMBER U(21) #else #define FCONF_ARM_IO_UUID_NUMBER U(10) #endif @@ -234,6 +240,7 @@ static const struct policies_load_info load_info[FCONF_ARM_IO_UUID_NUMBER] = { {NON_TRUSTED_FW_CONTENT_CERT_ID, "nt_fw_content_cert_uuid"}, #if defined(SPD_spmd) {SIP_SP_CONTENT_CERT_ID, "sip_sp_content_cert_uuid"}, + {PLAT_SP_CONTENT_CERT_ID, "plat_sp_content_cert_uuid"}, #endif #endif /* TRUSTED_BOARD_BOOT */ }; diff --git a/plat/arm/common/fconf/arm_fconf_sp.c b/plat/arm/common/fconf/arm_fconf_sp.c index 4459264c7..50a9dd4d5 100644 --- a/plat/arm/common/fconf/arm_fconf_sp.c +++ b/plat/arm/common/fconf/arm_fconf_sp.c @@ -30,7 +30,13 @@ int fconf_populate_arm_sp(uintptr_t config) union uuid_helper_t uuid_helper; unsigned int index = 0; uint32_t val32; - const unsigned int sp_start_index = SP_PKG1_ID; + bool is_plat_owned = false; + const unsigned int sip_start = SP_PKG1_ID; + unsigned int sip_index = sip_start; + const unsigned int sip_end = sip_start + MAX_SP_IDS / 2; + const unsigned int plat_start = SP_PKG5_ID; + unsigned int plat_index = plat_start; + const unsigned int plat_end = plat_start + MAX_SP_IDS / 2; /* As libfdt use void *, we can't avoid this cast */ const void *dtb = (void *)config; @@ -45,27 +51,20 @@ int fconf_populate_arm_sp(uintptr_t config) } fdt_for_each_subnode(sp_node, dtb, node) { - if (index == MAX_SP_IDS) { + if ((index == MAX_SP_IDS) || (sip_index == sip_end) + || (plat_index == plat_end)) { ERROR("FCONF: Reached max number of SPs\n"); return -1; } + /* Read UUID */ err = fdt_read_uint32_array(dtb, sp_node, "uuid", 4, uuid_helper.word); if (err < 0) { ERROR("FCONF: cannot read SP uuid\n"); return -1; } - arm_sp.uuids[index] = uuid_helper; - - 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 %x-%x-%x-%x load_addr=%lx\n", __func__, uuid_helper.word[0], @@ -74,8 +73,52 @@ int fconf_populate_arm_sp(uintptr_t config) uuid_helper.word[3], arm_sp.load_addr[index]); - /* Add SP information in mem param descriptor */ - sp_mem_params_descs[index].image_id = sp_start_index + 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 */ + fdtw_read_string(dtb, sp_node, "owner", + arm_sp.owner[index], ARM_SP_OWNER_NAME_LEN); +#endif + /* If owner is empty mark it as SiP owned */ + if ((strncmp(arm_sp.owner[index], "SiP", + ARM_SP_OWNER_NAME_LEN) == 0) || + (strncmp(arm_sp.owner[index], "", + ARM_SP_OWNER_NAME_LEN) == 0)) { + is_plat_owned = false; + } else if (strcmp(arm_sp.owner[index], "Plat") == 0) { + is_plat_owned = true; + } else { + ERROR("FCONF: %s is not a valid SP owner\n", + arm_sp.owner[index]); + return -1; + } + /* + * Add SP information in mem param descriptor and IO policies + * structure. + */ + if (is_plat_owned) { + sp_mem_params_descs[index].image_id = plat_index; + policies[plat_index].image_spec = + (uintptr_t)&arm_sp.uuids[index]; + policies[plat_index].dev_handle = &fip_dev_handle; + policies[plat_index].check = open_fip; + plat_index++; + } else { + sp_mem_params_descs[index].image_id = sip_index; + policies[sip_index].image_spec = + (uintptr_t)&arm_sp.uuids[index]; + policies[sip_index].dev_handle = &fip_dev_handle; + policies[sip_index].check = open_fip; + sip_index++; + } SET_PARAM_HEAD(&sp_mem_params_descs[index].image_info, PARAM_IMAGE_BINARY, VERSION_2, 0); sp_mem_params_descs[index].image_info.image_max_size = @@ -84,13 +127,6 @@ int fconf_populate_arm_sp(uintptr_t config) INVALID_IMAGE_ID; sp_mem_params_descs[index].image_info.image_base = arm_sp.load_addr[index]; - - /* Add SP information in IO policies structure */ - policies[sp_start_index + index].image_spec = - (uintptr_t)&arm_sp.uuids[index]; - policies[sp_start_index + index].dev_handle = &fip_dev_handle; - policies[sp_start_index + index].check = open_fip; - index++; } -- cgit v1.2.3 From 1e7528ec378eb633125e67ddf1b1089eba149945 Mon Sep 17 00:00:00 2001 From: Ruari Phipps Date: Fri, 24 Jul 2020 16:20:57 +0100 Subject: SPM: Alter sp_gen.mk entry depending on owner of partition With recently introduced dualroot CoT for SPs where they are owned either by SiP or by Platform. SiP owned SPs index starts at SP_PKG1_ID while Plat owned SPs index starts at SP_PKG5_ID. This patch modifies SP makefile generator script to take CoT as an argument and if it is "dualroot" then generates SP_PKG in order mentioned above, otherwise generates it sequentially. Signed-off-by: Ruari Phipps Change-Id: Iffad1131787be650a9462f6f8cc09b603cddb3b8 --- Makefile | 2 +- tools/sptool/sp_mk_generator.py | 36 +++++++++++++++++++++++++++++++++--- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index f4589d9b2..05b296922 100644 --- a/Makefile +++ b/Makefile @@ -1135,7 +1135,7 @@ endif # Add Secure Partition packages ifeq (${NEED_SP_PKG},yes) $(BUILD_PLAT)/sp_gen.mk: ${SP_MK_GEN} ${SP_LAYOUT_FILE} | ${BUILD_PLAT} - ${Q}${PYTHON} "$<" "$@" $(filter-out $<,$^) $(BUILD_PLAT) + ${Q}${PYTHON} "$<" "$@" $(filter-out $<,$^) $(BUILD_PLAT) ${COT} sp: $(SPTOOL) $(DTBS) $(BUILD_PLAT)/sp_gen.mk ${Q}$(SPTOOL) $(SPTOOL_ARGS) @${ECHO_BLANK_LINE} diff --git a/tools/sptool/sp_mk_generator.py b/tools/sptool/sp_mk_generator.py index 2153a5651..a37e702bb 100755 --- a/tools/sptool/sp_mk_generator.py +++ b/tools/sptool/sp_mk_generator.py @@ -19,6 +19,7 @@ standard format. param1: Generated mk file "sp_gen.mk" param2: "SP_LAYOUT_FILE", json file containing platform provided information param3: plat out directory +param4: CoT parameter Generated "sp_gen.mk" file contains triplet of following information for each Secure Partition entry @@ -58,11 +59,39 @@ json_dir = os.path.dirname(json_file) gen_file = os.path.abspath(sys.argv[1]) out_dir = os.path.abspath(sys.argv[3]) dtb_dir = out_dir + "/fdts/" +MAX_SP = 8 +dualroot = sys.argv[4].lower() == "dualroot" +split = int(MAX_SP / 2) print(dtb_dir) +platform_count = 1 +sip_count = 1 with open(gen_file, 'w') as out_file: for idx, key in enumerate(data.keys()): + pkg_num = idx + 1 + + if (pkg_num > MAX_SP): + print("WARNING: Too many secure partitions\n") + exit(-1) + + if dualroot: + owner = data[key].get('owner') + if owner == "Plat": + if (platform_count > split): + print("WARNING: Maximum Secure partitions by Plat " + + "have been exceeded (" + str(split) + ")\n") + exit(-1) + pkg_num = split + platform_count + platform_count += 1 + elif (sip_count > split): + print("WARNING: Maximum Secure partitions by SiP " + + "have been exceeded (" + str(split) + ")\n") + exit(-1) + else: + pkg_num = sip_count + sip_count += 1 + """ Append FDT_SOURCES """ @@ -81,10 +110,10 @@ with open(gen_file, 'w') as out_file: Extract uuid from partition manifest """ pm_file = open(dts) - key = "uuid" + uuid_key = "uuid" for line in pm_file: - if key in line: + if uuid_key in line: uuid_hex = re.findall(r'\<(.+?)\>', line)[0]; # PM has uuid in format 0xABC... 0x... 0x... 0x... @@ -103,5 +132,6 @@ with open(gen_file, 'w') as out_file: """ Append CRT_ARGS """ - out_file.write("CRT_ARGS += --sp-pkg" + str(idx + 1) + " " + dst + "\n") + + out_file.write("CRT_ARGS += --sp-pkg" + str(pkg_num) + " " + dst + "\n") out_file.write("\n") -- cgit v1.2.3 From ad86d35aa073b64bcfaed9bf8c283fa99c458408 Mon Sep 17 00:00:00 2001 From: Ruari Phipps Date: Tue, 11 Aug 2020 15:28:03 +0100 Subject: SPM: Add owner field to cactus secure partitions For supporting dualroot CoT for Secure Partitions a new optional field "owner" is introduced which will be used to sign the SP with corresponding signing domain. To demonstrate its usage, this patch adds owners to cactus Secure Partitions. Signed-off-by: Ruari Phipps Change-Id: I7b760580355fc92edf5402cecc38c38125dc1cae --- plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts | 2 ++ 1 file changed, 2 insertions(+) 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 280a64aad..1ee728546 100644 --- a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts +++ b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts @@ -84,11 +84,13 @@ cactus-primary { uuid = <0x1e67b5b4 0xe14f904a 0x13fb1fb8 0xcbdae1da>; load-address = <0x7000000>; + owner = "SiP"; }; cactus-secondary { uuid = <0x092358d1 0xb94723f0 0x64447c82 0xc88f57f5>; load-address = <0x7100000>; + owner = "Plat"; }; #endif }; -- cgit v1.2.3 From 33c91baf902d1865f70625fb57a0872baeb745f0 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Fri, 7 Aug 2020 09:48:30 +0200 Subject: stm32mp1: use newly introduced GICv2 makefile Include the GICv2 makefile in STM32MP1 SP_min makefile, and use ${GICV2_SOURCES} instead of taking drivers/arm/gic files directly. Change-Id: Ibcaed5b0bd17f6d8cf200e208c11cc10cd6d2ee5 Signed-off-by: Yann Gautier --- plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk index 5d7d495f0..8866fb556 100644 --- a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk +++ b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk @@ -16,9 +16,9 @@ BL32_SOURCES += drivers/st/etzpc/etzpc.c \ plat/st/stm32mp1/stm32mp1_topology.c # Generic GIC v2 -BL32_SOURCES += drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v2/gicv2_helpers.c \ - drivers/arm/gic/v2/gicv2_main.c \ +include drivers/arm/gic/v2/gicv2.mk + +BL32_SOURCES += ${GICV2_SOURCES} \ plat/common/plat_gicv2.c \ plat/st/stm32mp1/stm32mp1_gic.c -- cgit v1.2.3 From 9bc28a5eb2f650648babaea62b6da871819370de Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 3 Aug 2020 00:25:03 +0100 Subject: plat/allwinner: Use common gicv2.mk Compiling BL31 for the Allwinner platform now produces a message about the deprecation of gic_common.c. Follow the advice and use include gicv2.mk instead. Collect all includes at the beginning of the file on the way. Change-Id: Iee46e21a630bfa831d28059f09aa7b049eb554bb Signed-off-by: Andre Przywara --- plat/allwinner/common/allwinner-common.mk | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/plat/allwinner/common/allwinner-common.mk b/plat/allwinner/common/allwinner-common.mk index e60ebc6f2..997aaa6f7 100644 --- a/plat/allwinner/common/allwinner-common.mk +++ b/plat/allwinner/common/allwinner-common.mk @@ -5,6 +5,8 @@ # include lib/xlat_tables_v2/xlat_tables.mk +include lib/libfdt/libfdt.mk +include drivers/arm/gic/v2/gicv2.mk AW_PLAT := plat/allwinner @@ -12,8 +14,6 @@ PLAT_INCLUDES := -Iinclude/plat/arm/common/aarch64 \ -I${AW_PLAT}/common/include \ -I${AW_PLAT}/${PLAT}/include -include lib/libfdt/libfdt.mk - PLAT_BL_COMMON_SOURCES := drivers/ti/uart/${ARCH}/16550_console.S \ ${XLAT_TABLES_LIB_SRCS} \ ${AW_PLAT}/common/plat_helpers.S \ @@ -22,9 +22,7 @@ PLAT_BL_COMMON_SOURCES := drivers/ti/uart/${ARCH}/16550_console.S \ BL31_SOURCES += drivers/allwinner/axp/common.c \ drivers/allwinner/sunxi_msgbox.c \ drivers/arm/css/scpi/css_scpi.c \ - drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v2/gicv2_helpers.c \ - drivers/arm/gic/v2/gicv2_main.c \ + ${GICV2_SOURCES} \ drivers/delay_timer/delay_timer.c \ drivers/delay_timer/generic_delay_timer.c \ lib/cpus/${ARCH}/cortex_a53.S \ -- cgit v1.2.3 From 93fa305c0ae39813a6f4971997aacd2a428305f9 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 3 Aug 2020 00:25:21 +0100 Subject: plat/allwinner: Only enable DRIVEVBUS if really needed The DRIVEVBUS power rail of the AXP803 PMIC is mostly used to supply the USB bus power on micro USB sockets, when used in host mode. As this is a dynamic operation, and mostly we want micro USB sockets to act in client mode initially, BL31 should not actually enable this power line. However, on some boards DRIVEVBUS is used to supply power to normal USB-A sockets. Failing to activate this line there results in non-functional USB in U-Boot on those boards. For that reason we were enabling DRIVEVBUS so far, as it did not seem to cause any harm to the other boards. However it turns out that on the Pinephone (and other systems with a battery), actually enabling DRIVEVBUS unconditionally causes serious problems (reboot loop). To accommodate both use cases, without reverting to a build time option, check the default OTG configuration in the devicetree. For boards with USB-A sockets this is set to "host", on boards with micro-B sockets to "otg". Depending on this setting, we either enable DRIVEVBUS or leave it alone. This fixes TF-A on the Pinephone and potentially other battery powered devices. Change-Id: Iec0e07f218b2b4393bf4e05c3386261f8ed19e9f Signed-off-by: Andre Przywara --- drivers/allwinner/axp/common.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/allwinner/axp/common.c b/drivers/allwinner/axp/common.c index 13437fec8..e98b16fdb 100644 --- a/drivers/allwinner/axp/common.c +++ b/drivers/allwinner/axp/common.c @@ -105,6 +105,25 @@ static bool should_enable_regulator(const void *fdt, int node) return false; } +static bool board_uses_usb0_host_mode(const void *fdt) +{ + int node, length; + const char *prop; + + node = fdt_node_offset_by_compatible(fdt, -1, + "allwinner,sun8i-a33-musb"); + if (node < 0) { + return false; + } + + prop = fdt_getprop(fdt, node, "dr_mode", &length); + if (!prop) { + return false; + } + + return !strncmp(prop, "host", length); +} + void axp_setup_regulators(const void *fdt) { int node; @@ -121,7 +140,8 @@ void axp_setup_regulators(const void *fdt) } /* This applies to AXP803 only. */ - if (fdt_getprop(fdt, node, "x-powers,drive-vbus-en", NULL)) { + if (fdt_getprop(fdt, node, "x-powers,drive-vbus-en", NULL) && + board_uses_usb0_host_mode(fdt)) { axp_clrbits(0x8f, BIT(4)); axp_setbits(0x30, BIT(2)); INFO("PMIC: Enabling DRIVEVBUS\n"); -- cgit v1.2.3 From fddfb3baf7c9e6e5e6d3462e71df6ba9d292f142 Mon Sep 17 00:00:00 2001 From: Madhukar Pappireddy Date: Wed, 12 Aug 2020 13:18:19 -0500 Subject: plat/arm: Use common build flag for using generic sp804 driver SP804 TIMER is not platform specific, and current code base adds multiple defines to use this driver. Like FVP_USE_SP804_TIMER and FVP_VE_USE_SP804_TIMER. This patch removes platform specific build flag and adds generic flag `USE_SP804_TIMER` to be set to 1 by platform if needed. Change-Id: I5ab792c189885fd1b98ddd187f3a38ebdd0baba2 Signed-off-by: Madhukar Pappireddy --- Makefile | 2 ++ docs/getting_started/build-options.rst | 4 ++++ docs/plat/arm/fvp/index.rst | 4 ---- make_helpers/defaults.mk | 3 +++ plat/arm/board/fvp/fvp_common.c | 4 ++-- plat/arm/board/fvp/platform.mk | 14 ++++---------- plat/arm/board/fvp_ve/fvp_ve_bl2_setup.c | 4 ++-- plat/arm/board/fvp_ve/platform.mk | 3 +-- 8 files changed, 18 insertions(+), 20 deletions(-) diff --git a/Makefile b/Makefile index f4589d9b2..1b986c4f5 100644 --- a/Makefile +++ b/Makefile @@ -914,6 +914,7 @@ $(eval $(call assert_boolean,ENCRYPT_BL32)) $(eval $(call assert_boolean,ERRATA_SPECULATIVE_AT)) $(eval $(call assert_boolean,RAS_TRAP_LOWER_EL_ERR_ACCESS)) $(eval $(call assert_boolean,COT_DESC_IN_DTB)) +$(eval $(call assert_boolean,USE_SP804_TIMER)) $(eval $(call assert_numeric,ARM_ARCH_MAJOR)) $(eval $(call assert_numeric,ARM_ARCH_MINOR)) @@ -995,6 +996,7 @@ $(eval $(call add_define,USE_SPINLOCK_CAS)) $(eval $(call add_define,ERRATA_SPECULATIVE_AT)) $(eval $(call add_define,RAS_TRAP_LOWER_EL_ERR_ACCESS)) $(eval $(call add_define,COT_DESC_IN_DTB)) +$(eval $(call add_define,USE_SP804_TIMER)) ifeq (${SANITIZE_UB},trap) $(eval $(call add_define,MONITOR_TRAPS)) diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 0acc8867b..ae328c779 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -725,6 +725,10 @@ Common build options path on the host machine which is used to build certificate generation and firmware encryption tool. +- ``USE_SP804_TIMER``: Use the SP804 timer instead of the Generic Timer for + functions that wait for an arbitrary time length (udelay and mdelay). The + default value is 0. + GICv3 driver options -------------------- diff --git a/docs/plat/arm/fvp/index.rst b/docs/plat/arm/fvp/index.rst index 745e31f9e..e3bf42ad9 100644 --- a/docs/plat/arm/fvp/index.rst +++ b/docs/plat/arm/fvp/index.rst @@ -123,10 +123,6 @@ Arm FVP Platform Specific Build Options - ``FVP_GICV2`` : The GICv2 only driver is selected - ``FVP_GICV3`` : The GICv3 only driver is selected (default option) -- ``FVP_USE_SP804_TIMER`` : Use the SP804 timer instead of the Generic Timer - for functions that wait for an arbitrary time length (udelay and mdelay). - The default value is 0. - - ``FVP_HW_CONFIG_DTS`` : Specify the path to the DTS file to be compiled to DTB and packaged in FIP as the HW_CONFIG. See :ref:`Firmware Design` for details on HW_CONFIG. By default, this is initialized to a sensible DTS diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index caf5990f2..27f8f2a51 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -311,3 +311,6 @@ COT_DESC_IN_DTB := 0 # Build option to provide openssl directory path OPENSSL_DIR := /usr + +# Build option to use the SP804 timer instead of the generic one +USE_SP804_TIMER := 0 diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c index cb717e053..6f439b8e2 100644 --- a/plat/arm/board/fvp/fvp_common.c +++ b/plat/arm/board/fvp/fvp_common.c @@ -420,7 +420,7 @@ int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size) void fvp_timer_init(void) { -#if FVP_USE_SP804_TIMER +#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. */ @@ -435,5 +435,5 @@ void fvp_timer_init(void) /* Enable System level generic timer */ mmio_write_32(ARM_SYS_CNTCTL_BASE + CNTCR_OFF, CNTCR_FCREQ(0U) | CNTCR_EN); -#endif /* FVP_USE_SP804_TIMER */ +#endif /* USE_SP804_TIMER */ } diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index f75f556a8..a7d18252d 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -7,9 +7,6 @@ # Use the GICv3 driver on the FVP by default FVP_USE_GIC_DRIVER := FVP_GICV3 -# Use the SP804 timer instead of the generic one -FVP_USE_SP804_TIMER := 0 - # Default cluster count for FVP FVP_CLUSTER_COUNT := 2 @@ -21,9 +18,6 @@ FVP_MAX_PE_PER_CPU := 1 FVP_DT_PREFIX := fvp-base-gicv3-psci -$(eval $(call assert_boolean,FVP_USE_SP804_TIMER)) -$(eval $(call add_define,FVP_USE_SP804_TIMER)) - # The FVP platform depends on this macro to build with correct GIC driver. $(eval $(call add_define,FVP_USE_GIC_DRIVER)) @@ -155,7 +149,7 @@ BL1_SOURCES += drivers/arm/smmu/smmu_v3.c \ ${FVP_CPU_LIBS} \ ${FVP_INTERCONNECT_SOURCES} -ifeq (${FVP_USE_SP804_TIMER},1) +ifeq (${USE_SP804_TIMER},1) BL1_SOURCES += drivers/arm/sp804/sp804_delay_timer.c else BL1_SOURCES += drivers/delay_timer/generic_delay_timer.c @@ -182,14 +176,14 @@ BL2_SOURCES += plat/arm/board/fvp/${ARCH}/fvp_helpers.S \ ${FVP_INTERCONNECT_SOURCES} endif -ifeq (${FVP_USE_SP804_TIMER},1) +ifeq (${USE_SP804_TIMER},1) BL2_SOURCES += drivers/arm/sp804/sp804_delay_timer.c endif BL2U_SOURCES += plat/arm/board/fvp/fvp_bl2u_setup.c \ ${FVP_SECURITY_SOURCES} -ifeq (${FVP_USE_SP804_TIMER},1) +ifeq (${USE_SP804_TIMER},1) BL2U_SOURCES += drivers/arm/sp804/sp804_delay_timer.c endif @@ -223,7 +217,7 @@ endif endif -ifeq (${FVP_USE_SP804_TIMER},1) +ifeq (${USE_SP804_TIMER},1) BL31_SOURCES += drivers/arm/sp804/sp804_delay_timer.c else BL31_SOURCES += drivers/delay_timer/generic_delay_timer.c diff --git a/plat/arm/board/fvp_ve/fvp_ve_bl2_setup.c b/plat/arm/board/fvp_ve/fvp_ve_bl2_setup.c index 25e096417..4ccae27a2 100644 --- a/plat/arm/board/fvp_ve/fvp_ve_bl2_setup.c +++ b/plat/arm/board/fvp_ve/fvp_ve_bl2_setup.c @@ -25,7 +25,7 @@ void bl2_platform_setup(void) { arm_bl2_platform_setup(); -#ifdef FVP_VE_USE_SP804_TIMER +#if USE_SP804_TIMER /* * Enable the clock override for SP804 timer 0, which means that no * clock dividers are applied and the raw (35 MHz) clock will be used @@ -37,5 +37,5 @@ void bl2_platform_setup(void) SP804_TIMER_CLKMULT, SP804_TIMER_CLKDIV); #else generic_delay_timer_init(); -#endif /* FVP_VE_USE_SP804_TIMER */ +#endif /* USE_SP804_TIMER */ } diff --git a/plat/arm/board/fvp_ve/platform.mk b/plat/arm/board/fvp_ve/platform.mk index f8e38ffc0..0aa1de4b8 100644 --- a/plat/arm/board/fvp_ve/platform.mk +++ b/plat/arm/board/fvp_ve/platform.mk @@ -6,8 +6,7 @@ ifdef ARM_CORTEX_A5 # Use the SP804 timer instead of the generic one -FVP_VE_USE_SP804_TIMER := 1 -$(eval $(call add_define,FVP_VE_USE_SP804_TIMER)) +USE_SP804_TIMER := 1 BL2_SOURCES += drivers/arm/sp804/sp804_delay_timer.c endif -- cgit v1.2.3 From 752ff3bfd8bd654dad61b10e80c400433e8095eb Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Mon, 17 Aug 2020 06:44:20 +0100 Subject: plat: qti: Fix build failure Fixed build failure due to the commit:905f93c77 by removing the inclusion of non-existent 'stdinit.h' file. Signed-off-by: Manish V Badarkhe Change-Id: I8e3ca69c016b7a2354c58c4d384a492631c36286 --- plat/qti/common/inc/qti_rng.h | 2 +- plat/qti/common/src/qti_rng.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plat/qti/common/inc/qti_rng.h b/plat/qti/common/inc/qti_rng.h index c933dea12..62c31f36c 100644 --- a/plat/qti/common/inc/qti_rng.h +++ b/plat/qti/common/inc/qti_rng.h @@ -7,7 +7,7 @@ #ifndef QTI_RNG_H #define QTI_RNG_H -#include +#include int qti_rng_get_data(uint8_t *out, uint32_t out_len); diff --git a/plat/qti/common/src/qti_rng.c b/plat/qti/common/src/qti_rng.c index a904209be..f63f3b85d 100644 --- a/plat/qti/common/src/qti_rng.c +++ b/plat/qti/common/src/qti_rng.c @@ -4,10 +4,10 @@ * SPDX-License-Identifier: BSD-3-Clause */ #include -#include #include +#include #include int qti_rng_get_data(uint8_t *out, uint32_t out_len) -- cgit v1.2.3 From 7f03d80d40dea5fefecfe7d7abd35d21791f6195 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Tue, 4 Aug 2020 16:55:58 +0100 Subject: plat/arm: remove common code for soc-id feature Removed common code for soc-id feature which is applicable for all arm platforms. In subsequent patches, added a platform based functions for FVP and Juno to retrieve the soc-id information. Change-Id: Idb632a935758a6caff2ca03a6eab8f663da8a93a Signed-off-by: Manish V Badarkhe --- plat/arm/common/arm_common.c | 35 ----------------------------------- 1 file changed, 35 deletions(-) diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c index e2b99a3d6..f7ee7a8e4 100644 --- a/plat/arm/common/arm_common.c +++ b/plat/arm/common/arm_common.c @@ -237,38 +237,3 @@ int plat_sdei_validate_entry_point(uintptr_t ep, unsigned int client_mode) } #endif -/***************************************************************************** - * plat_is_smccc_feature_available() - This function checks whether SMCCC - * feature is availabile for platform. - * @fid: SMCCC function id - * - * Return SMC_OK if SMCCC feature is available and SMC_ARCH_CALL_NOT_SUPPORTED - * otherwise. - *****************************************************************************/ -int32_t plat_is_smccc_feature_available(u_register_t fid) -{ - switch (fid) { - case SMCCC_ARCH_SOC_ID: - default: - return SMC_ARCH_CALL_NOT_SUPPORTED; - } -} - -/* - * Weak function to get ARM platform SOC-ID, Always return SOC-ID=0 - * ToDo: Get proper SOC-ID for every ARM platform and define this - * function separately for every ARM platform. - */ -uint32_t plat_arm_get_soc_id(void) -{ - return 0U; -} - -/* 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) - | plat_arm_get_soc_id()); -} -- cgit v1.2.3 From ed9653ffa901b277e4e87f769f832104bab7042c Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Tue, 4 Aug 2020 17:09:10 +0100 Subject: plat/arm: fvp: Implement methods to retrieve soc-id information Implemented platform functions to retrieve the soc-id information for FVP platform. Change-Id: Id3df02ab290a210310e8d34ec9d706a59d817517 Signed-off-by: Manish V Badarkhe --- plat/arm/board/fvp/fvp_common.c | 47 +++++++++++++++++++++++++++++++++++++---- plat/arm/board/fvp/fvp_def.h | 5 +++++ 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c index 6f439b8e2..6e479ac4f 100644 --- a/plat/arm/board/fvp/fvp_common.c +++ b/plat/arm/board/fvp/fvp_common.c @@ -13,16 +13,18 @@ #include #include #include +#include #include -#include -#include -#include #include - +#include #if SPM_MM #include #endif +#include +#include +#include + #include "fvp_private.h" /* Defines for GIC Driver build time selection */ @@ -437,3 +439,40 @@ void fvp_timer_init(void) CNTCR_FCREQ(0U) | CNTCR_EN); #endif /* USE_SP804_TIMER */ } + +/***************************************************************************** + * plat_is_smccc_feature_available() - This function checks whether SMCCC + * feature is availabile for platform. + * @fid: SMCCC function id + * + * Return SMC_ARCH_CALL_SUCCESS if SMCCC feature is available and + * SMC_ARCH_CALL_NOT_SUPPORTED otherwise. + *****************************************************************************/ +int32_t plat_is_smccc_feature_available(u_register_t fid) +{ + switch (fid) { + case SMCCC_ARCH_SOC_ID: + return SMC_ARCH_CALL_SUCCESS; + default: + return SMC_ARCH_CALL_NOT_SUPPORTED; + } +} + +/* 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_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/fvp_def.h b/plat/arm/board/fvp/fvp_def.h index c5d156858..4efe69258 100644 --- a/plat/arm/board/fvp/fvp_def.h +++ b/plat/arm/board/fvp/fvp_def.h @@ -27,6 +27,11 @@ #define FVP_CCI 1 #define FVP_CCN 2 +/****************************************************************************** + * Definition of platform soc id + *****************************************************************************/ +#define FVP_SOC_ID 0 + /******************************************************************************* * FVP memory map related constants ******************************************************************************/ -- cgit v1.2.3 From 3f34663ffd7339d97d40c71f941bdc1c1634b43b Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Tue, 4 Aug 2020 17:13:14 +0100 Subject: plat/arm: juno: Implement methods to retrieve soc-id information Implemented platform functions to retrieve the soc-id information for juno platform Change-Id: Ie677120710b45e202a2d63a954459ece8a64b353 Signed-off-by: Manish V Badarkhe --- plat/arm/board/juno/juno_common.c | 42 ++++++++++++++++++++++++++++++++++++++- plat/arm/board/juno/juno_def.h | 7 ++++++- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/plat/arm/board/juno/juno_common.c b/plat/arm/board/juno/juno_common.c index 9570d2d4c..da4918cf2 100644 --- a/plat/arm/board/juno/juno_common.c +++ b/plat/arm/board/juno/juno_common.c @@ -1,10 +1,13 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ +#include #include +#include + #include /* @@ -91,3 +94,40 @@ const mmap_region_t plat_arm_mmap[] = { #endif ARM_CASSERT_MMAP + +/***************************************************************************** + * plat_is_smccc_feature_available() - This function checks whether SMCCC + * feature is availabile for platform. + * @fid: SMCCC function id + * + * Return SMC_ARCH_CALL_SUCCESS if SMCCC feature is available and + * SMC_ARCH_CALL_NOT_SUPPORTED otherwise. + *****************************************************************************/ +int32_t plat_is_smccc_feature_available(u_register_t fid) +{ + switch (fid) { + case SMCCC_ARCH_SOC_ID: + return SMC_ARCH_CALL_SUCCESS; + default: + return SMC_ARCH_CALL_NOT_SUPPORTED; + } +} + +/* 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) + | JUNO_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/juno/juno_def.h b/plat/arm/board/juno/juno_def.h index 3b34a9f6a..ddf99dcdb 100644 --- a/plat/arm/board/juno/juno_def.h +++ b/plat/arm/board/juno/juno_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,6 +9,11 @@ #include +/****************************************************************************** + * Definition of platform soc id + *****************************************************************************/ +#define JUNO_SOC_ID 1 + /******************************************************************************* * Juno memory map related constants ******************************************************************************/ -- cgit v1.2.3 From fb2072b03d4ef872b30e1c9691ed401b9d124fe1 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Tue, 28 Jul 2020 07:12:56 +0100 Subject: el3_runtime: Update context save and restore routines for EL1 and EL2 As per latest mailing communication [1], we decided not to update SCTLR and TCR registers in EL1 and EL2 context restore routine when AT speculative workaround is enabled hence reverted the changes done as part of this commit: 45aecff00. [1]: https://lists.trustedfirmware.org/pipermail/tf-a/2020-July/000586.html Change-Id: I8c5f31d81fcd53770a610e302a5005d98772b71f Signed-off-by: Manish V Badarkhe --- lib/el3_runtime/aarch64/context.S | 218 +++++++++++++++----------------------- 1 file changed, 86 insertions(+), 132 deletions(-) diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S index 1568ef05b..548f97794 100644 --- a/lib/el3_runtime/aarch64/context.S +++ b/lib/el3_runtime/aarch64/context.S @@ -233,21 +233,6 @@ endfunc el2_sysregs_context_save */ func el2_sysregs_context_restore -#if ERRATA_SPECULATIVE_AT -/* Clear EPD0 and EPD1 bit and M bit to disable PTW */ - mrs x9, hcr_el2 - tst x9, #HCR_E2H_BIT - bne 1f - mrs x9, tcr_el2 - orr x9, x9, #TCR_EPD0_BIT - orr x9, x9, #TCR_EPD1_BIT - msr tcr_el2, x9 -1: mrs x9, sctlr_el2 - bic x9, x9, #SCTLR_M_BIT - msr sctlr_el2, x9 - isb -#endif - ldp x9, x10, [x0, #CTX_ACTLR_EL2] msr actlr_el2, x9 msr afsr0_el2, x10 @@ -296,136 +281,127 @@ func el2_sysregs_context_restore msr mdcr_el2, x15 msr PMSCR_EL2, x16 - ldp x17, x9, [x0, #CTX_SPSR_EL2] - msr spsr_el2, x17 - msr sp_el2, x9 + ldp x17, x9, [x0, #CTX_SCTLR_EL2] + msr sctlr_el2, x17 + msr spsr_el2, x9 + + ldp x10, x11, [x0, #CTX_SP_EL2] + msr sp_el2, x10 + msr tcr_el2, x11 - ldp x10, x11, [x0, #CTX_TPIDR_EL2] - msr tpidr_el2, x10 - msr ttbr0_el2, x11 + ldp x12, x13, [x0, #CTX_TPIDR_EL2] + msr tpidr_el2, x12 + msr ttbr0_el2, x13 - ldp x12, x13, [x0, #CTX_VBAR_EL2] - msr vbar_el2, x12 - msr vmpidr_el2, x13 + ldp x13, x14, [x0, #CTX_VBAR_EL2] + msr vbar_el2, x13 + msr vmpidr_el2, x14 - ldp x14, x15, [x0, #CTX_VPIDR_EL2] - msr vpidr_el2, x14 - msr vtcr_el2, x15 + ldp x15, x16, [x0, #CTX_VPIDR_EL2] + msr vpidr_el2, x15 + msr vtcr_el2, x16 - ldr x16, [x0, #CTX_VTTBR_EL2] - msr vttbr_el2, x16 + ldr x17, [x0, #CTX_VTTBR_EL2] + msr vttbr_el2, x17 #if CTX_INCLUDE_MTE_REGS - ldr x17, [x0, #CTX_TFSR_EL2] - msr TFSR_EL2, x17 + ldr x9, [x0, #CTX_TFSR_EL2] + msr TFSR_EL2, x9 #endif #if ENABLE_MPAM_FOR_LOWER_ELS - ldp x9, x10, [x0, #CTX_MPAM2_EL2] - msr MPAM2_EL2, x9 - msr MPAMHCR_EL2, x10 + ldp x10, x11, [x0, #CTX_MPAM2_EL2] + msr MPAM2_EL2, x10 + msr MPAMHCR_EL2, x11 - ldp x11, x12, [x0, #CTX_MPAMVPM0_EL2] - msr MPAMVPM0_EL2, x11 - msr MPAMVPM1_EL2, x12 + ldp x12, x13, [x0, #CTX_MPAMVPM0_EL2] + msr MPAMVPM0_EL2, x12 + msr MPAMVPM1_EL2, x13 - ldp x13, x14, [x0, #CTX_MPAMVPM2_EL2] - msr MPAMVPM2_EL2, x13 - msr MPAMVPM3_EL2, x14 + ldp x14, x15, [x0, #CTX_MPAMVPM2_EL2] + msr MPAMVPM2_EL2, x14 + msr MPAMVPM3_EL2, x15 - ldp x15, x16, [x0, #CTX_MPAMVPM4_EL2] - msr MPAMVPM4_EL2, x15 - msr MPAMVPM5_EL2, x16 + ldp x16, x17, [x0, #CTX_MPAMVPM4_EL2] + msr MPAMVPM4_EL2, x16 + msr MPAMVPM5_EL2, x17 - ldp x17, x9, [x0, #CTX_MPAMVPM6_EL2] - msr MPAMVPM6_EL2, x17 - msr MPAMVPM7_EL2, x9 + ldp x9, x10, [x0, #CTX_MPAMVPM6_EL2] + msr MPAMVPM6_EL2, x9 + msr MPAMVPM7_EL2, x10 - ldr x10, [x0, #CTX_MPAMVPMV_EL2] - msr MPAMVPMV_EL2, x10 + ldr x11, [x0, #CTX_MPAMVPMV_EL2] + msr MPAMVPMV_EL2, x11 #endif #if ARM_ARCH_AT_LEAST(8, 6) - ldp x11, x12, [x0, #CTX_HAFGRTR_EL2] - msr HAFGRTR_EL2, x11 - msr HDFGRTR_EL2, x12 + ldp x12, x13, [x0, #CTX_HAFGRTR_EL2] + msr HAFGRTR_EL2, x12 + msr HDFGRTR_EL2, x13 - ldp x13, x14, [x0, #CTX_HDFGWTR_EL2] - msr HDFGWTR_EL2, x13 - msr HFGITR_EL2, x14 + ldp x14, x15, [x0, #CTX_HDFGWTR_EL2] + msr HDFGWTR_EL2, x14 + msr HFGITR_EL2, x15 - ldp x15, x16, [x0, #CTX_HFGRTR_EL2] - msr HFGRTR_EL2, x15 - msr HFGWTR_EL2, x16 + ldp x16, x17, [x0, #CTX_HFGRTR_EL2] + msr HFGRTR_EL2, x16 + msr HFGWTR_EL2, x17 - ldr x17, [x0, #CTX_CNTPOFF_EL2] - msr CNTPOFF_EL2, x17 + ldr x9, [x0, #CTX_CNTPOFF_EL2] + msr CNTPOFF_EL2, x9 #endif #if ARM_ARCH_AT_LEAST(8, 4) - ldp x9, x10, [x0, #CTX_CNTHPS_CTL_EL2] - msr cnthps_ctl_el2, x9 - msr cnthps_cval_el2, x10 + ldp x10, x11, [x0, #CTX_CNTHPS_CTL_EL2] + msr cnthps_ctl_el2, x10 + msr cnthps_cval_el2, x11 - ldp x11, x12, [x0, #CTX_CNTHPS_TVAL_EL2] - msr cnthps_tval_el2, x11 - msr cnthvs_ctl_el2, x12 + ldp x12, x13, [x0, #CTX_CNTHPS_TVAL_EL2] + msr cnthps_tval_el2, x12 + msr cnthvs_ctl_el2, x13 - ldp x13, x14, [x0, #CTX_CNTHVS_CVAL_EL2] - msr cnthvs_cval_el2, x13 - msr cnthvs_tval_el2, x14 + ldp x14, x15, [x0, #CTX_CNTHVS_CVAL_EL2] + msr cnthvs_cval_el2, x14 + msr cnthvs_tval_el2, x15 - ldp x15, x16, [x0, #CTX_CNTHV_CTL_EL2] - msr cnthv_ctl_el2, x15 - msr cnthv_cval_el2, x16 + ldp x16, x17, [x0, #CTX_CNTHV_CTL_EL2] + msr cnthv_ctl_el2, x16 + msr cnthv_cval_el2, x17 - ldp x17, x9, [x0, #CTX_CNTHV_TVAL_EL2] - msr cnthv_tval_el2, x17 - msr contextidr_el2, x9 + ldp x9, x10, [x0, #CTX_CNTHV_TVAL_EL2] + msr cnthv_tval_el2, x9 + msr contextidr_el2, x10 - ldr x10, [x0, #CTX_SDER32_EL2] - msr sder32_el2, x10 + ldr x11, [x0, #CTX_SDER32_EL2] + msr sder32_el2, x11 - ldr x11, [x0, #CTX_TTBR1_EL2] - msr ttbr1_el2, x11 + ldr x12, [x0, #CTX_TTBR1_EL2] + msr ttbr1_el2, x12 - ldr x12, [x0, #CTX_VDISR_EL2] - msr vdisr_el2, x12 + ldr x13, [x0, #CTX_VDISR_EL2] + msr vdisr_el2, x13 - ldr x13, [x0, #CTX_VNCR_EL2] - msr vncr_el2, x13 + ldr x14, [x0, #CTX_VNCR_EL2] + msr vncr_el2, x14 - ldr x14, [x0, #CTX_VSESR_EL2] - msr vsesr_el2, x14 + ldr x15, [x0, #CTX_VSESR_EL2] + msr vsesr_el2, x15 - ldr x15, [x0, #CTX_VSTCR_EL2] - msr vstcr_el2, x15 + ldr x16, [x0, #CTX_VSTCR_EL2] + msr vstcr_el2, x16 - ldr x16, [x0, #CTX_VSTTBR_EL2] - msr vsttbr_el2, x16 + ldr x17, [x0, #CTX_VSTTBR_EL2] + msr vsttbr_el2, x17 - ldr x17, [x0, #CTX_TRFCR_EL2] - msr TRFCR_EL2, x17 + ldr x9, [x0, #CTX_TRFCR_EL2] + msr TRFCR_EL2, x9 #endif #if ARM_ARCH_AT_LEAST(8, 5) - ldr x9, [x0, #CTX_SCXTNUM_EL2] - msr scxtnum_el2, x9 -#endif - -#if ERRATA_SPECULATIVE_AT -/* - * Make sure all registers are stored successfully except - * SCTLR_EL2 and TCR_EL2 - */ - isb + ldr x10, [x0, #CTX_SCXTNUM_EL2] + msr scxtnum_el2, x10 #endif - ldr x9, [x0, #CTX_SCTLR_EL2] - msr sctlr_el2, x9 - ldr x9, [x0, #CTX_TCR_EL2] - msr tcr_el2, x9 - ret endfunc el2_sysregs_context_restore @@ -537,22 +513,12 @@ endfunc el1_sysregs_context_save */ func el1_sysregs_context_restore -#if ERRATA_SPECULATIVE_AT - mrs x9, tcr_el1 - orr x9, x9, #TCR_EPD0_BIT - orr x9, x9, #TCR_EPD1_BIT - msr tcr_el1, x9 - mrs x9, sctlr_el1 - bic x9, x9, #SCTLR_M_BIT - msr sctlr_el1, x9 - isb -#endif - ldp x9, x10, [x0, #CTX_SPSR_EL1] msr spsr_el1, x9 msr elr_el1, x10 - ldr x16, [x0, #CTX_ACTLR_EL1] + ldp x15, x16, [x0, #CTX_SCTLR_EL1] + msr sctlr_el1, x15 msr actlr_el1, x16 ldp x17, x9, [x0, #CTX_CPACR_EL1] @@ -571,8 +537,9 @@ func el1_sysregs_context_restore msr mair_el1, x14 msr amair_el1, x15 - ldr x16,[x0, #CTX_TPIDR_EL1] - msr tpidr_el1, x16 + ldp x16, x17, [x0, #CTX_TCR_EL1] + msr tcr_el1, x16 + msr tpidr_el1, x17 ldp x9, x10, [x0, #CTX_TPIDR_EL0] msr tpidr_el0, x9 @@ -628,19 +595,6 @@ func el1_sysregs_context_restore msr GCR_EL1, x14 #endif -#if ERRATA_SPECULATIVE_AT -/* - * Make sure all registers are stored successfully except - * SCTLR_EL1 and TCR_EL1 - */ - isb -#endif - - ldr x9, [x0, #CTX_SCTLR_EL1] - msr sctlr_el1, x9 - ldr x9, [x0, #CTX_TCR_EL1] - msr tcr_el1, x9 - /* No explict ISB required here as ERET covers it */ ret endfunc el1_sysregs_context_restore -- cgit v1.2.3 From 86ba585300aa784160bbcb8441ace3df8e06e1bd Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Tue, 14 Jul 2020 14:43:12 +0100 Subject: Add wrapper for AT instruction In case of AT speculative workaround applied, page table walk is disabled for lower ELs (EL1 and EL0) in EL3. Hence added a wrapper function which temporarily enables page table walk to execute AT instruction for lower ELs and then disables page table walk. Execute AT instructions directly for lower ELs (EL1 and EL0) assuming page table walk is enabled always when AT speculative workaround is not applied. Change-Id: I4ad4c0bcbb761448af257e9f72ae979473c0dde8 Signed-off-by: Manish V Badarkhe --- common/backtrace/backtrace.c | 2 +- include/arch/aarch64/arch_helpers.h | 20 ++++++++++++++++++++ plat/arm/common/arm_common.c | 2 +- services/spd/tlkd/tlkd_common.c | 8 ++++---- 4 files changed, 26 insertions(+), 6 deletions(-) diff --git a/common/backtrace/backtrace.c b/common/backtrace/backtrace.c index ef575006f..a07c066ce 100644 --- a/common/backtrace/backtrace.c +++ b/common/backtrace/backtrace.c @@ -70,7 +70,7 @@ static bool is_address_readable(uintptr_t addr) } else if (el == 2U) { ats1e2r(addr); } else { - ats1e1r(addr); + AT(ats1e1r, addr); } isb(); diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h index 4bff0f6f0..1f2f4a923 100644 --- a/include/arch/aarch64/arch_helpers.h +++ b/include/arch/aarch64/arch_helpers.h @@ -590,4 +590,24 @@ static inline uint64_t el_implemented(unsigned int el) #define read_clusterpwrdn() read_clusterpwrdn_el1() #define write_clusterpwrdn(_v) write_clusterpwrdn_el1(_v) +#if ERRATA_SPECULATIVE_AT +/* + * Assuming SCTLR.M bit is already enabled + * 1. Enable page table walk by clearing TCR_EL1.EPDx bits + * 2. Execute AT instruction for lower EL1/0 + * 3. Disable page table walk by setting TCR_EL1.EPDx bits + */ +#define AT(_at_inst, _va) \ +{ \ + assert((read_sctlr_el1() & SCTLR_M_BIT) != 0ULL); \ + write_tcr_el1(read_tcr_el1() & ~(TCR_EPD0_BIT | TCR_EPD1_BIT)); \ + isb(); \ + _at_inst(_va); \ + write_tcr_el1(read_tcr_el1() | (TCR_EPD0_BIT | TCR_EPD1_BIT)); \ + isb(); \ +} +#else +#define AT(_at_inst, _va) _at_inst(_va); +#endif + #endif /* ARCH_HELPERS_H */ diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c index e2b99a3d6..e55ea90f8 100644 --- a/plat/arm/common/arm_common.c +++ b/plat/arm/common/arm_common.c @@ -216,7 +216,7 @@ int plat_sdei_validate_entry_point(uintptr_t ep, unsigned int client_mode) * Translate entry point to Physical Address using the EL1&0 * translation regime, including stage 2. */ - ats12e1r(ep); + AT(ats12e1r, ep); } isb(); par = read_par_el1(); diff --git a/services/spd/tlkd/tlkd_common.c b/services/spd/tlkd/tlkd_common.c index dbe6c2e34..820bd8a72 100644 --- a/services/spd/tlkd/tlkd_common.c +++ b/services/spd/tlkd/tlkd_common.c @@ -38,16 +38,16 @@ uint64_t tlkd_va_translate(uintptr_t va, int type) int at = type & AT_MASK; switch (at) { case 0: - ats12e1r(va); + AT(ats12e1r, va); break; case 1: - ats12e1w(va); + AT(ats12e1w, va); break; case 2: - ats12e0r(va); + AT(ats12e0r, va); break; case 3: - ats12e0w(va); + AT(ats12e0w, va); break; default: assert(0); /* Unreachable */ -- cgit v1.2.3 From e1c493337222e35311d7aaef612f5974b5de4ec6 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Mon, 3 Aug 2020 18:43:14 +0100 Subject: lib/cpus: Report AT speculative erratum workaround Reported the status (applies, missing) of AT speculative workaround which is applicable for below CPUs. +---------+--------------+ | Errata | CPU | +=========+==============+ | 1165522 | Cortex-A76 | +---------+--------------+ | 1319367 | Cortex-A72 | +---------+--------------+ | 1319537 | Cortex-A57 | +---------+--------------+ | 1530923 | Cortex-A55 | +---------+--------------+ | 1530924 | Cortex-A53 | +---------+--------------+ Also, changes are done to enable common macro 'ERRATA_SPECULATIVE_AT' if AT speculative errata workaround is enabled for any of the above CPUs using 'ERRATA_*' CPU specific build macro. Signed-off-by: Manish V Badarkhe Change-Id: I3e6a5316a2564071f3920c3ce9ae9a29adbe435b --- lib/cpus/aarch64/cortex_a53.S | 17 +++++++++++++++- lib/cpus/aarch64/cortex_a55.S | 17 +++++++++++++++- lib/cpus/aarch64/cortex_a57.S | 17 +++++++++++++++- lib/cpus/aarch64/cortex_a72.S | 17 +++++++++++++++- lib/cpus/aarch64/cortex_a76.S | 18 +++++++++++++++++ lib/cpus/cpu-ops.mk | 47 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 129 insertions(+), 4 deletions(-) diff --git a/lib/cpus/aarch64/cortex_a53.S b/lib/cpus/aarch64/cortex_a53.S index b105de26b..df11d8690 100644 --- a/lib/cpus/aarch64/cortex_a53.S +++ b/lib/cpus/aarch64/cortex_a53.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -239,6 +239,20 @@ exit_check_errata_843419: ret endfunc check_errata_843419 + /* -------------------------------------------------- + * Errata workaround for Cortex A53 Errata #1530924. + * This applies to all revisions of Cortex A53. + * -------------------------------------------------- + */ +func check_errata_1530924 +#if ERRATA_A53_1530924 + mov x0, #ERRATA_APPLIES +#else + mov x0, #ERRATA_MISSING +#endif + ret +endfunc check_errata_1530924 + /* ------------------------------------------------- * The CPU Ops reset function for Cortex-A53. * Shall clobber: x0-x19 @@ -359,6 +373,7 @@ func cortex_a53_errata_report report_errata ERRATA_A53_836870, cortex_a53, disable_non_temporal_hint report_errata ERRATA_A53_843419, cortex_a53, 843419 report_errata ERRATA_A53_855873, cortex_a53, 855873 + report_errata ERRATA_A53_1530924, cortex_a53, 1530924 ldp x8, x30, [sp], #16 ret diff --git a/lib/cpus/aarch64/cortex_a55.S b/lib/cpus/aarch64/cortex_a55.S index 8e138244b..783830450 100644 --- a/lib/cpus/aarch64/cortex_a55.S +++ b/lib/cpus/aarch64/cortex_a55.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -222,6 +222,20 @@ func check_errata_1221012 b cpu_rev_var_ls endfunc check_errata_1221012 + /* -------------------------------------------------- + * Errata workaround for Cortex A55 Errata #1530923. + * This applies to all revisions of Cortex A55. + * -------------------------------------------------- + */ +func check_errata_1530923 +#if ERRATA_A55_1530923 + mov x0, #ERRATA_APPLIES +#else + mov x0, #ERRATA_MISSING +#endif + ret +endfunc check_errata_1530923 + func cortex_a55_reset_func mov x19, x30 @@ -306,6 +320,7 @@ func cortex_a55_errata_report report_errata ERRATA_A55_846532, cortex_a55, 846532 report_errata ERRATA_A55_903758, cortex_a55, 903758 report_errata ERRATA_A55_1221012, cortex_a55, 1221012 + report_errata ERRATA_A55_1530923, cortex_a55, 1530923 ldp x8, x30, [sp], #16 ret diff --git a/lib/cpus/aarch64/cortex_a57.S b/lib/cpus/aarch64/cortex_a57.S index 3fee4704e..8ef0f922a 100644 --- a/lib/cpus/aarch64/cortex_a57.S +++ b/lib/cpus/aarch64/cortex_a57.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -396,6 +396,20 @@ func check_errata_cve_2018_3639 ret endfunc check_errata_cve_2018_3639 + /* -------------------------------------------------- + * Errata workaround for Cortex A57 Errata #1319537. + * This applies to all revisions of Cortex A57. + * -------------------------------------------------- + */ +func check_errata_1319537 +#if ERRATA_A57_1319537 + mov x0, #ERRATA_APPLIES +#else + mov x0, #ERRATA_MISSING +#endif + ret +endfunc check_errata_1319537 + /* ------------------------------------------------- * The CPU Ops reset function for Cortex-A57. * Shall clobber: x0-x19 @@ -613,6 +627,7 @@ func cortex_a57_errata_report report_errata ERRATA_A57_829520, cortex_a57, 829520 report_errata ERRATA_A57_833471, cortex_a57, 833471 report_errata ERRATA_A57_859972, cortex_a57, 859972 + report_errata ERRATA_A57_1319537, cortex_a57, 1319537 report_errata WORKAROUND_CVE_2017_5715, cortex_a57, cve_2017_5715 report_errata WORKAROUND_CVE_2018_3639, cortex_a57, cve_2018_3639 diff --git a/lib/cpus/aarch64/cortex_a72.S b/lib/cpus/aarch64/cortex_a72.S index 38b76b940..aff6072a0 100644 --- a/lib/cpus/aarch64/cortex_a72.S +++ b/lib/cpus/aarch64/cortex_a72.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -119,6 +119,20 @@ func check_errata_cve_2018_3639 ret endfunc check_errata_cve_2018_3639 + /* -------------------------------------------------- + * Errata workaround for Cortex A72 Errata #1319367. + * This applies to all revisions of Cortex A72. + * -------------------------------------------------- + */ +func check_errata_1319367 +#if ERRATA_A72_1319367 + mov x0, #ERRATA_APPLIES +#else + mov x0, #ERRATA_MISSING +#endif + ret +endfunc check_errata_1319367 + /* ------------------------------------------------- * The CPU Ops reset function for Cortex-A72. * ------------------------------------------------- @@ -282,6 +296,7 @@ func cortex_a72_errata_report * checking functions of each errata. */ report_errata ERRATA_A72_859971, cortex_a72, 859971 + report_errata ERRATA_A72_1319367, cortex_a72, 1319367 report_errata WORKAROUND_CVE_2017_5715, cortex_a72, cve_2017_5715 report_errata WORKAROUND_CVE_2018_3639, cortex_a72, cve_2018_3639 diff --git a/lib/cpus/aarch64/cortex_a76.S b/lib/cpus/aarch64/cortex_a76.S index 10011f754..0895946e4 100644 --- a/lib/cpus/aarch64/cortex_a76.S +++ b/lib/cpus/aarch64/cortex_a76.S @@ -465,6 +465,23 @@ func cortex_a76_disable_wa_cve_2018_3639 ret endfunc cortex_a76_disable_wa_cve_2018_3639 + /* -------------------------------------------------------------- + * Errata Workaround for Cortex A76 Errata #1165522. + * This applies only to revisions <= r3p0 of Cortex A76. + * Due to the nature of the errata it is applied unconditionally + * when built in, report it as applicable in this case + * -------------------------------------------------------------- + */ +func check_errata_1165522 +#if ERRATA_A76_1165522 + mov x0, #ERRATA_APPLIES + ret +#else + mov x1, #0x30 + b cpu_rev_var_ls +#endif +endfunc check_errata_1165522 + /* ------------------------------------------------- * The CPU Ops reset function for Cortex-A76. * Shall clobber: x0-x19 @@ -597,6 +614,7 @@ func cortex_a76_errata_report report_errata ERRATA_A76_1286807, cortex_a76, 1286807 report_errata ERRATA_A76_1791580, cortex_a76, 1791580 report_errata ERRATA_A76_1800710, cortex_a76, 1800710 + report_errata ERRATA_A76_1165522, cortex_a76, 1165522 report_errata WORKAROUND_CVE_2018_3639, cortex_a76, cve_2018_3639 report_errata ERRATA_DSU_798953, cortex_a76, dsu_798953 report_errata ERRATA_DSU_936184, cortex_a76, dsu_936184 diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk index e49437569..8fc3b6063 100644 --- a/lib/cpus/cpu-ops.mk +++ b/lib/cpus/cpu-ops.mk @@ -130,6 +130,10 @@ ERRATA_A53_843419 ?=0 # of by the rich OS. ERRATA_A53_855873 ?=0 +# Flag to apply erratum 1530924 workaround during reset. This erratum applies +# to all revisions of Cortex A53 cpu. +ERRATA_A53_1530924 ?=0 + # Flag to apply erratum 768277 workaround during reset. This erratum applies # only to revision r0p0 of the Cortex A55 cpu. ERRATA_A55_768277 ?=0 @@ -154,6 +158,10 @@ ERRATA_A55_903758 ?=0 # only to revision <= r1p0 of the Cortex A55 cpu. ERRATA_A55_1221012 ?=0 +# Flag to apply erratum 1530923 workaround during reset. This erratum applies +# to all revisions of Cortex A55 cpu. +ERRATA_A55_1530923 ?=0 + # Flag to apply erratum 806969 workaround during reset. This erratum applies # only to revision r0p0 of the Cortex A57 cpu. ERRATA_A57_806969 ?=0 @@ -198,10 +206,18 @@ ERRATA_A57_833471 ?=0 # only to revision <= r1p3 of the Cortex A57 cpu. ERRATA_A57_859972 ?=0 +# Flag to apply erratum 1319537 workaround during reset. This erratum applies +# to all revisions of Cortex A57 cpu. +ERRATA_A57_1319537 ?=0 + # Flag to apply erratum 855971 workaround during reset. This erratum applies # only to revision <= r0p3 of the Cortex A72 cpu. ERRATA_A72_859971 ?=0 +# Flag to apply erratum 1319367 workaround during reset. This erratum applies +# to all revisions of Cortex A72 cpu. +ERRATA_A72_1319367 ?=0 + # Flag to apply erratum 852427 workaround during reset. This erratum applies # only to revision r0p0 of the Cortex A73 cpu. ERRATA_A73_852427 ?=0 @@ -258,6 +274,10 @@ ERRATA_A76_1791580 ?=0 # only to revision <= r4p0 of the Cortex A76 cpu. ERRATA_A76_1800710 ?=0 +# Flag to apply erratum 1165522 workaround during reset. This erratum applies +# to all revisions of Cortex A76 cpu. +ERRATA_A76_1165522 ?=0 + # Flag to apply erratum 1800714 workaround during reset. This erratum applies # only to revision <= r1p1 of the Cortex A77 cpu. ERRATA_A77_1800714 ?=0 @@ -379,6 +399,10 @@ $(eval $(call add_define,ERRATA_A53_843419)) $(eval $(call assert_boolean,ERRATA_A53_855873)) $(eval $(call add_define,ERRATA_A53_855873)) +# Process ERRATA_A53_1530924 flag +$(eval $(call assert_boolean,ERRATA_A53_1530924)) +$(eval $(call add_define,ERRATA_A53_1530924)) + # Process ERRATA_A55_768277 flag $(eval $(call assert_boolean,ERRATA_A55_768277)) $(eval $(call add_define,ERRATA_A55_768277)) @@ -403,6 +427,10 @@ $(eval $(call add_define,ERRATA_A55_903758)) $(eval $(call assert_boolean,ERRATA_A55_1221012)) $(eval $(call add_define,ERRATA_A55_1221012)) +# Process ERRATA_A55_1530923 flag +$(eval $(call assert_boolean,ERRATA_A55_1530923)) +$(eval $(call add_define,ERRATA_A55_1530923)) + # Process ERRATA_A57_806969 flag $(eval $(call assert_boolean,ERRATA_A57_806969)) $(eval $(call add_define,ERRATA_A57_806969)) @@ -447,10 +475,18 @@ $(eval $(call add_define,ERRATA_A57_833471)) $(eval $(call assert_boolean,ERRATA_A57_859972)) $(eval $(call add_define,ERRATA_A57_859972)) +# Process ERRATA_A57_1319537 flag +$(eval $(call assert_boolean,ERRATA_A57_1319537)) +$(eval $(call add_define,ERRATA_A57_1319537)) + # Process ERRATA_A72_859971 flag $(eval $(call assert_boolean,ERRATA_A72_859971)) $(eval $(call add_define,ERRATA_A72_859971)) +# Process ERRATA_A72_1319367 flag +$(eval $(call assert_boolean,ERRATA_A72_1319367)) +$(eval $(call add_define,ERRATA_A72_1319367)) + # Process ERRATA_A73_852427 flag $(eval $(call assert_boolean,ERRATA_A73_852427)) $(eval $(call add_define,ERRATA_A73_852427)) @@ -507,6 +543,10 @@ $(eval $(call add_define,ERRATA_A76_1791580)) $(eval $(call assert_boolean,ERRATA_A76_1800710)) $(eval $(call add_define,ERRATA_A76_1800710)) +# Process ERRATA_A76_1165522 flag +$(eval $(call assert_boolean,ERRATA_A76_1165522)) +$(eval $(call add_define,ERRATA_A76_1165522)) + # Process ERRATA_A77_1800714 flag $(eval $(call assert_boolean,ERRATA_A77_1800714)) $(eval $(call add_define,ERRATA_A77_1800714)) @@ -580,3 +620,10 @@ ifneq (${ERRATA_A53_835769},0) TF_CFLAGS_aarch64 += -mfix-cortex-a53-835769 TF_LDFLAGS_aarch64 += --fix-cortex-a53-835769 endif + +ifneq ($(filter 1,${ERRATA_A53_1530924} ${ERRATA_A55_1530923} \ + ${ERRATA_A57_1319537} ${ERRATA_A72_1319367} ${ERRATA_A76_1165522}),) +ERRATA_SPECULATIVE_AT := 1 +else +ERRATA_SPECULATIVE_AT := 0 +endif -- cgit v1.2.3 From cb55615c506d6bff3f1a9223182e190abbbf6fc5 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Tue, 28 Jul 2020 07:22:30 +0100 Subject: el3_runtime: Rearrange context offset of EL1 sys registers SCTLR and TCR registers of EL1 plays role in enabling/disabling of page table walk for lower ELs (EL0 and EL1). Hence re-arranged EL1 context offsets to have SCTLR and TCR registers values one after another in the stack so that these registers values can be saved and restored using stp and ldp instruction respectively. Change-Id: Iaa28fd9eba82a60932b6b6d85ec8857a9acd5f8b Signed-off-by: Manish V Badarkhe --- include/lib/el3_runtime/aarch64/context.h | 4 ++-- lib/el3_runtime/aarch64/context.S | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h index 90807cec6..349041432 100644 --- a/include/lib/el3_runtime/aarch64/context.h +++ b/include/lib/el3_runtime/aarch64/context.h @@ -72,7 +72,7 @@ #define CTX_SPSR_EL1 U(0x0) #define CTX_ELR_EL1 U(0x8) #define CTX_SCTLR_EL1 U(0x10) -#define CTX_ACTLR_EL1 U(0x18) +#define CTX_TCR_EL1 U(0x18) #define CTX_CPACR_EL1 U(0x20) #define CTX_CSSELR_EL1 U(0x28) #define CTX_SP_EL1 U(0x30) @@ -81,7 +81,7 @@ #define CTX_TTBR1_EL1 U(0x48) #define CTX_MAIR_EL1 U(0x50) #define CTX_AMAIR_EL1 U(0x58) -#define CTX_TCR_EL1 U(0x60) +#define CTX_ACTLR_EL1 U(0x60) #define CTX_TPIDR_EL1 U(0x68) #define CTX_TPIDR_EL0 U(0x70) #define CTX_TPIDRRO_EL0 U(0x78) diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S index 548f97794..12e5d4958 100644 --- a/lib/el3_runtime/aarch64/context.S +++ b/lib/el3_runtime/aarch64/context.S @@ -421,7 +421,7 @@ func el1_sysregs_context_save stp x9, x10, [x0, #CTX_SPSR_EL1] mrs x15, sctlr_el1 - mrs x16, actlr_el1 + mrs x16, tcr_el1 stp x15, x16, [x0, #CTX_SCTLR_EL1] mrs x17, cpacr_el1 @@ -440,9 +440,9 @@ func el1_sysregs_context_save mrs x15, amair_el1 stp x14, x15, [x0, #CTX_MAIR_EL1] - mrs x16, tcr_el1 + mrs x16, actlr_el1 mrs x17, tpidr_el1 - stp x16, x17, [x0, #CTX_TCR_EL1] + stp x16, x17, [x0, #CTX_ACTLR_EL1] mrs x9, tpidr_el0 mrs x10, tpidrro_el0 @@ -519,7 +519,7 @@ func el1_sysregs_context_restore ldp x15, x16, [x0, #CTX_SCTLR_EL1] msr sctlr_el1, x15 - msr actlr_el1, x16 + msr tcr_el1, x16 ldp x17, x9, [x0, #CTX_CPACR_EL1] msr cpacr_el1, x17 @@ -537,8 +537,8 @@ func el1_sysregs_context_restore msr mair_el1, x14 msr amair_el1, x15 - ldp x16, x17, [x0, #CTX_TCR_EL1] - msr tcr_el1, x16 + ldp x16, x17, [x0, #CTX_ACTLR_EL1] + msr actlr_el1, x16 msr tpidr_el1, x17 ldp x9, x10, [x0, #CTX_TPIDR_EL0] -- cgit v1.2.3 From 3b8456bd1c9fd2303483f0675786e3fbda81a0af Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Thu, 23 Jul 2020 12:43:25 +0100 Subject: runtime_exceptions: Update AT speculative workaround As per latest mailing communication [1], we decided to update AT speculative workaround implementation in order to disable page table walk for lower ELs(EL1 or EL0) immediately after context switching to EL3 from lower ELs. Previous implementation of AT speculative workaround is available here: 45aecff00 AT speculative workaround is updated as below: 1. Avoid saving and restoring of SCTLR and TCR registers for EL1 in context save and restore routine respectively. 2. On EL3 entry, save SCTLR and TCR registers for EL1. 3. On EL3 entry, update EL1 system registers to disable stage 1 page table walk for lower ELs (EL1 and EL0) and enable EL1 MMU. 4. On EL3 exit, restore SCTLR and TCR registers for EL1 which are saved in step 2. [1]: https://lists.trustedfirmware.org/pipermail/tf-a/2020-July/000586.html Change-Id: Iee8de16f81dc970a8f492726f2ddd57e7bd9ffb5 Signed-off-by: Manish V Badarkhe --- bl31/aarch64/runtime_exceptions.S | 11 +++++++ include/arch/aarch64/el3_common_macros.S | 39 +++++++++++++++++++++++++ lib/el3_runtime/aarch64/context.S | 50 ++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+) diff --git a/bl31/aarch64/runtime_exceptions.S b/bl31/aarch64/runtime_exceptions.S index 5b3738868..bfe13f312 100644 --- a/bl31/aarch64/runtime_exceptions.S +++ b/bl31/aarch64/runtime_exceptions.S @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -285,21 +286,25 @@ vector_entry sync_exception_aarch64 * to a valid cpu context where the general purpose and system register * state can be saved. */ + apply_at_speculative_wa check_and_unmask_ea handle_sync_exception end_vector_entry sync_exception_aarch64 vector_entry irq_aarch64 + apply_at_speculative_wa check_and_unmask_ea handle_interrupt_exception irq_aarch64 end_vector_entry irq_aarch64 vector_entry fiq_aarch64 + apply_at_speculative_wa check_and_unmask_ea handle_interrupt_exception fiq_aarch64 end_vector_entry fiq_aarch64 vector_entry serror_aarch64 + apply_at_speculative_wa msr daifclr, #DAIF_ABT_BIT b enter_lower_el_async_ea end_vector_entry serror_aarch64 @@ -315,21 +320,25 @@ vector_entry sync_exception_aarch32 * to a valid cpu context where the general purpose and system register * state can be saved. */ + apply_at_speculative_wa check_and_unmask_ea handle_sync_exception end_vector_entry sync_exception_aarch32 vector_entry irq_aarch32 + apply_at_speculative_wa check_and_unmask_ea handle_interrupt_exception irq_aarch32 end_vector_entry irq_aarch32 vector_entry fiq_aarch32 + apply_at_speculative_wa check_and_unmask_ea handle_interrupt_exception fiq_aarch32 end_vector_entry fiq_aarch32 vector_entry serror_aarch32 + apply_at_speculative_wa msr daifclr, #DAIF_ABT_BIT b enter_lower_el_async_ea end_vector_entry serror_aarch32 @@ -455,6 +464,8 @@ smc_unknown: b el3_exit smc_prohibited: + restore_ptw_el1_sys_regs + ldp x28, x29, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X28] ldr x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR] mov x0, #SMC_UNK exception_return diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S index 0708de689..17a4efaf6 100644 --- a/include/arch/aarch64/el3_common_macros.S +++ b/include/arch/aarch64/el3_common_macros.S @@ -9,6 +9,7 @@ #include #include +#include #include /* @@ -443,4 +444,42 @@ #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 /* EL3_COMMON_MACROS_S */ diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S index 12e5d4958..1cb527d99 100644 --- a/lib/el3_runtime/aarch64/context.S +++ b/lib/el3_runtime/aarch64/context.S @@ -8,6 +8,7 @@ #include #include #include +#include #if CTX_INCLUDE_EL2_REGS .global el2_sysregs_context_save @@ -22,6 +23,7 @@ #endif .global save_gp_pmcr_pauth_regs .global restore_gp_pmcr_pauth_regs + .global save_and_update_ptw_el1_sys_regs .global el3_exit #if CTX_INCLUDE_EL2_REGS @@ -420,9 +422,11 @@ func el1_sysregs_context_save mrs x10, elr_el1 stp x9, x10, [x0, #CTX_SPSR_EL1] +#if !ERRATA_SPECULATIVE_AT mrs x15, sctlr_el1 mrs x16, tcr_el1 stp x15, x16, [x0, #CTX_SCTLR_EL1] +#endif mrs x17, cpacr_el1 mrs x9, csselr_el1 @@ -517,9 +521,11 @@ func el1_sysregs_context_restore msr spsr_el1, x9 msr elr_el1, x10 +#if !ERRATA_SPECULATIVE_AT ldp x15, x16, [x0, #CTX_SCTLR_EL1] msr sctlr_el1, x15 msr tcr_el1, x16 +#endif ldp x17, x9, [x0, #CTX_CPACR_EL1] msr cpacr_el1, x17 @@ -859,6 +865,48 @@ func restore_gp_pmcr_pauth_regs ret endfunc restore_gp_pmcr_pauth_regs +/* + * In case of ERRATA_SPECULATIVE_AT, save SCTLR_EL1 and TCR_EL1 + * registers and update EL1 registers to disable stage1 and stage2 + * page table walk + */ +func save_and_update_ptw_el1_sys_regs + /* ---------------------------------------------------------- + * Save only sctlr_el1 and tcr_el1 registers + * ---------------------------------------------------------- + */ + mrs x29, sctlr_el1 + str x29, [sp, #(CTX_EL1_SYSREGS_OFFSET + CTX_SCTLR_EL1)] + mrs x29, tcr_el1 + str x29, [sp, #(CTX_EL1_SYSREGS_OFFSET + CTX_TCR_EL1)] + + /* ------------------------------------------------------------ + * Must follow below order in order to disable page table + * walk for lower ELs (EL1 and EL0). First step ensures that + * page table walk is disabled for stage1 and second step + * ensures that page table walker should use TCR_EL1.EPDx + * bits to perform address translation. ISB ensures that CPU + * does these 2 steps in order. + * + * 1. Update TCR_EL1.EPDx bits to disable page table walk by + * stage1. + * 2. Enable MMU bit to avoid identity mapping via stage2 + * and force TCR_EL1.EPDx to be used by the page table + * walker. + * ------------------------------------------------------------ + */ + orr x29, x29, #(TCR_EPD0_BIT) + orr x29, x29, #(TCR_EPD1_BIT) + msr tcr_el1, x29 + isb + mrs x29, sctlr_el1 + orr x29, x29, #SCTLR_M_BIT + msr sctlr_el1, x29 + isb + + ret +endfunc save_and_update_ptw_el1_sys_regs + /* ------------------------------------------------------------------ * This routine assumes that the SP_EL3 is pointing to a valid * context structure from where the gp regs and other special @@ -903,6 +951,8 @@ func el3_exit blr x17 1: #endif + restore_ptw_el1_sys_regs + /* ---------------------------------------------------------- * Restore general purpose (including x30), PMCR_EL0 and * ARMv8.3-PAuth registers. -- cgit v1.2.3 From e008a29a18e2602f6b90686be8cedcfb119a68ae Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Fri, 31 Jul 2020 08:38:49 +0100 Subject: doc: Update description for AT speculative workaround Documented the CPU specific build macros created for AT speculative workaround. Updated the description of 'ERRATA_SPECULATIVE_AT' errata workaround option. Signed-off-by: Manish V Badarkhe Change-Id: Ie46a80d4e8183c1d5c8b153f08742a04d41a2af2 --- docs/design/cpu-specific-build-macros.rst | 16 +++++++++++ docs/getting_started/build-options.rst | 46 ++++++++++++++++++------------- docs/glossary.rst | 3 ++ 3 files changed, 46 insertions(+), 19 deletions(-) diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst index 6b6c63933..33b509083 100644 --- a/docs/design/cpu-specific-build-macros.rst +++ b/docs/design/cpu-specific-build-macros.rst @@ -127,6 +127,9 @@ For Cortex-A53, the following errata build flags are defined : Earlier revisions of the CPU have other errata which require the same workaround in software, so they should be covered anyway. +- ``ERRATA_A53_1530924``: This applies errata 1530924 workaround to all + revisions of Cortex-A53 CPU. + For Cortex-A55, the following errata build flags are defined : - ``ERRATA_A55_768277``: This applies errata 768277 workaround to Cortex-A55 @@ -147,6 +150,9 @@ For Cortex-A55, the following errata build flags are defined : - ``ERRATA_A55_1221012``: This applies errata 1221012 workaround to Cortex-A55 CPU. This needs to be enabled only for revision <= r1p0 of the CPU. +- ``ERRATA_A55_1530923``: This applies errata 1530923 workaround to all + revisions of Cortex-A55 CPU. + For Cortex-A57, the following errata build flags are defined : - ``ERRATA_A57_806969``: This applies errata 806969 workaround to Cortex-A57 @@ -182,12 +188,17 @@ For Cortex-A57, the following errata build flags are defined : - ``ERRATA_A57_859972``: This applies errata 859972 workaround to Cortex-A57 CPU. This needs to be enabled only for revision <= r1p3 of the CPU. +- ``ERRATA_A57_1319537``: This applies errata 1319537 workaround to all + revisions of Cortex-A57 CPU. For Cortex-A72, the following errata build flags are defined : - ``ERRATA_A72_859971``: This applies errata 859971 workaround to Cortex-A72 CPU. This needs to be enabled only for revision <= r0p3 of the CPU. +- ``ERRATA_A72_1319367``: This applies errata 1319367 workaround to all + revisions of Cortex-A72 CPU. + For Cortex-A73, the following errata build flags are defined : - ``ERRATA_A73_852427``: This applies errata 852427 workaround to Cortex-A73 @@ -233,6 +244,11 @@ For Cortex-A76, the following errata build flags are defined : - ``ERRATA_A76_1800710``: This applies errata 1800710 workaround to Cortex-A76 CPU. This needs to be enabled only for revision <= r4p0 of the CPU. +- ``ERRATA_A76_1165522``: This applies errata 1165522 workaround to all + revisions of Cortex-A76 CPU. This errata is fixed in r3p0 but due to + limitation of errata framework this errata is applied to all revisions + of Cortex-A76 CPU. + For Cortex-A77, the following errata build flags are defined : - ``ERRATA_A77_1800714``: This applies errata 1800714 workaround to Cortex-A77 diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index ae328c779..b4fe40436 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -694,28 +694,36 @@ Common build options default value of this flag is ``no``. Note this option must be enabled only for ARM architecture greater than Armv8.5-A. -- ``ERRATA_SPECULATIVE_AT``: This flag enables/disables page table walk during - context restore as speculative AT instructions using an out-of-context - translation regime could cause subsequent requests to generate an incorrect - translation. - System registers are not updated during context save, hence this workaround - need not be applied in the context save path. +- ``ERRATA_SPECULATIVE_AT``: This flag determines whether to enable ``AT`` + speculative errata workaround or not. It accepts 2 values: ``1`` and ``0``. + The default value of this flag is ``0``. + + ``AT`` speculative errata workaround disables stage1 page table walk for + lower ELs (EL1 and EL0) in EL3 so that ``AT`` speculative fetch at any point + produces either the correct result or failure without TLB allocation. This boolean option enables errata for all below CPUs. - +---------+--------------+ - | Errata | CPU | - +=========+==============+ - | 1165522 | Cortex-A76 | - +---------+--------------+ - | 1319367 | Cortex-A72 | - +---------+--------------+ - | 1319537 | Cortex-A57 | - +---------+--------------+ - | 1530923 | Cortex-A55 | - +---------+--------------+ - | 1530924 | Cortex-A53 | - +---------+--------------+ + +---------+--------------+-------------------------+ + | Errata | CPU | Workaround Define | + +=========+==============+=========================+ + | 1165522 | Cortex-A76 | ``ERRATA_A76_1165522`` | + +---------+--------------+-------------------------+ + | 1319367 | Cortex-A72 | ``ERRATA_A72_1319367`` | + +---------+--------------+-------------------------+ + | 1319537 | Cortex-A57 | ``ERRATA_A57_1319537`` | + +---------+--------------+-------------------------+ + | 1530923 | Cortex-A55 | ``ERRATA_A55_1530923`` | + +---------+--------------+-------------------------+ + | 1530924 | Cortex-A53 | ``ERRATA_A53_1530924`` | + +---------+--------------+-------------------------+ + + .. note:: + This option is enabled by build only if platform sets any of above defines + mentioned in ’Workaround Define' column in the table. + If this option is enabled for the EL3 software then EL2 software also must + implement this workaround due to the behaviour of the errata mentioned + in new SDEN document which will get published soon. - ``RAS_TRAP_LOWER_EL_ERR_ACCESS``: This flag enables/disables the SCR_EL3.TERR bit, to trap access to the RAS ERR and RAS ERX registers from lower ELs. diff --git a/docs/glossary.rst b/docs/glossary.rst index e08707946..08add3a70 100644 --- a/docs/glossary.rst +++ b/docs/glossary.rst @@ -18,6 +18,9 @@ You can find additional definitions in the `Arm Glossary`_. API Application Programming Interface + AT + Address Translation + BTI Branch Target Identification. An Armv8.5 extension providing additional control flow integrity around indirect branches and their targets. -- cgit v1.2.3 From 6a2426a94f78815e9390835db4b6c9b4a29facf7 Mon Sep 17 00:00:00 2001 From: Masahisa Kojima Date: Thu, 11 Jun 2020 21:46:44 +0900 Subject: qemu/qemu_sbsa: enable SPM support Enable the spm_mm framework for the qemu_sbsa platform. Memory layout required for spm_mm is created in secure SRAM. Co-developed-by: Fu Wei Signed-off-by: Fu Wei Signed-off-by: Masahisa Kojima Change-Id: I104a623e8bc1e44d035b95f014a13b3f8b33a62a --- docs/plat/qemu-sbsa.rst | 12 ++- plat/qemu/common/qemu_common.c | 11 ++- plat/qemu/common/qemu_spm.c | 81 +++++++++++++++++ plat/qemu/qemu_sbsa/include/platform_def.h | 138 ++++++++++++++++++++++++++--- plat/qemu/qemu_sbsa/platform.mk | 11 ++- 5 files changed, 236 insertions(+), 17 deletions(-) create mode 100644 plat/qemu/common/qemu_spm.c diff --git a/docs/plat/qemu-sbsa.rst b/docs/plat/qemu-sbsa.rst index 51fe41404..bc82ae526 100644 --- a/docs/plat/qemu-sbsa.rst +++ b/docs/plat/qemu-sbsa.rst @@ -19,7 +19,6 @@ and also enable methods for the CPUs. Current limitations: - Only cold boot is supported -- No instructions for how to load a BL32 (Secure Payload) To build TF-A: @@ -27,9 +26,18 @@ To build TF-A: git clone https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git tfa cd tfa - export CROSS_COMPILE=aarch64-linux-gnu- + export CROSS_COMPILE=aarch64-none-elf- make PLAT=qemu_sbsa all fip +To build TF-A with BL32 and SPM enabled(StandaloneMM as a Secure Payload): + +:: + + git clone https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git tfa + cd tfa + export CROSS_COMPILE=aarch64-none-elf- + make PLAT=qemu_sbsa BL32=../STANDALONE_MM.fd SPM_MM=1 EL3_EXCEPTION_HANDLING=1 all fip + Images will be placed at build/qemu_sbsa/release (bl1.bin and fip.bin). Need to copy them into top directory for EDK2 compilation. diff --git a/plat/qemu/common/qemu_common.c b/plat/qemu/common/qemu_common.c index 365cfb7f0..7f8e4c494 100644 --- a/plat/qemu/common/qemu_common.c +++ b/plat/qemu/common/qemu_common.c @@ -1,5 +1,6 @@ + /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -77,7 +78,11 @@ static const mmap_region_t plat_qemu_mmap[] = { MAP_DEVICE2, #endif MAP_NS_DRAM0, +#if SPM_MM + QEMU_SP_IMAGE_MMAP, +#else MAP_BL32_MEM, +#endif {0} }; #endif @@ -88,7 +93,11 @@ static const mmap_region_t plat_qemu_mmap[] = { #ifdef MAP_DEVICE1 MAP_DEVICE1, #endif +#if SPM_MM + QEMU_SPM_BUF_EL3_MMAP, +#else MAP_BL32_MEM, +#endif {0} }; #endif diff --git a/plat/qemu/common/qemu_spm.c b/plat/qemu/common/qemu_spm.c new file mode 100644 index 000000000..e9ab1a5c3 --- /dev/null +++ b/plat/qemu/common/qemu_spm.c @@ -0,0 +1,81 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 2020, Linaro Limited and Contributors. All rights reserved. + */ + +#include +#include +#include + +#include + +/* Region equivalent to MAP_DEVICE1 suitable for mapping at EL0 */ +#define MAP_DEVICE1_EL0 MAP_REGION_FLAT(DEVICE1_BASE, \ + DEVICE1_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE | MT_USER) + +const mmap_region_t plat_qemu_secure_partition_mmap[] = { + MAP_DEVICE1_EL0, /* for the UART */ + QEMU_SP_IMAGE_MMAP, + QEMU_SPM_BUF_EL0_MMAP, + QEMU_SP_IMAGE_NS_BUF_MMAP, + QEMU_SP_IMAGE_RW_MMAP, + {0} +}; + +/* + * Boot information passed to a secure partition during initialisation. + * Linear indices in MP information will be filled at runtime. + */ +static spm_mm_mp_info_t sp_mp_info[] = { + [0] = {0x80000000, 0}, + [1] = {0x80000001, 0}, + [2] = {0x80000002, 0}, + [3] = {0x80000003, 0}, + [4] = {0x80000004, 0}, + [5] = {0x80000005, 0}, + [6] = {0x80000006, 0}, + [7] = {0x80000007, 0} +}; + +const spm_mm_boot_info_t plat_qemu_secure_partition_boot_info = { + .h.type = PARAM_SP_IMAGE_BOOT_INFO, + .h.version = VERSION_1, + .h.size = sizeof(spm_mm_boot_info_t), + .h.attr = 0, + .sp_mem_base = PLAT_QEMU_SP_IMAGE_BASE, + .sp_mem_limit = BL32_LIMIT, + .sp_image_base = PLAT_QEMU_SP_IMAGE_BASE, + .sp_stack_base = PLAT_SP_IMAGE_STACK_BASE, + .sp_heap_base = PLAT_QEMU_SP_IMAGE_HEAP_BASE, + .sp_ns_comm_buf_base = PLAT_QEMU_SP_IMAGE_NS_BUF_BASE, + .sp_shared_buf_base = PLAT_SPM_BUF_BASE, + .sp_image_size = PLAT_QEMU_SP_IMAGE_SIZE, + .sp_pcpu_stack_size = PLAT_SP_IMAGE_STACK_PCPU_SIZE, + .sp_heap_size = PLAT_QEMU_SP_IMAGE_HEAP_SIZE, + .sp_ns_comm_buf_size = PLAT_QEMU_SP_IMAGE_NS_BUF_SIZE, + .sp_shared_buf_size = PLAT_SPM_BUF_SIZE, + .num_sp_mem_regions = PLAT_QEMU_SP_IMAGE_NUM_MEM_REGIONS, + .num_cpus = PLATFORM_CORE_COUNT, + .mp_info = sp_mp_info +}; + +/* Enumeration of priority levels on QEMU platforms. */ +ehf_pri_desc_t qemu_exceptions[] = { + EHF_PRI_DESC(QEMU_PRI_BITS, PLAT_SP_PRI) +}; + +/* Plug in QEMU exceptions to Exception Handling Framework. */ +EHF_REGISTER_PRIORITIES(qemu_exceptions, ARRAY_SIZE(qemu_exceptions), + QEMU_PRI_BITS); + +const mmap_region_t *plat_get_secure_partition_mmap(void *cookie) +{ + return plat_qemu_secure_partition_mmap; +} + +const spm_mm_boot_info_t * +plat_get_secure_partition_boot_info(void *cookie) +{ + return &plat_qemu_secure_partition_boot_info; +} diff --git a/plat/qemu/qemu_sbsa/include/platform_def.h b/plat/qemu/qemu_sbsa/include/platform_def.h index d0a56cf14..76340051a 100644 --- a/plat/qemu/qemu_sbsa/include/platform_def.h +++ b/plat/qemu/qemu_sbsa/include/platform_def.h @@ -1,10 +1,11 @@ /* SPDX-License-Identifier: BSD-3-Clause * - * Copyright (c) 2019, Linaro Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Linaro Limited and Contributors. + * All rights reserved. */ -#ifndef __PLATFORM_DEF_H__ -#define __PLATFORM_DEF_H__ +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H #include #include @@ -107,9 +108,10 @@ * Put BL1 RW at the top of the Secure SRAM. BL1_RW_BASE is calculated using * the current BL1 RW debug size plus a little space for growth. */ +#define BL1_SIZE 0x12000 #define BL1_RO_BASE SEC_ROM_BASE #define BL1_RO_LIMIT (SEC_ROM_BASE + SEC_ROM_SIZE) -#define BL1_RW_BASE (BL1_RW_LIMIT - 0x12000) +#define BL1_RW_BASE (BL1_RW_LIMIT - BL1_SIZE) #define BL1_RW_LIMIT (BL_RAM_BASE + BL_RAM_SIZE) /* @@ -118,7 +120,8 @@ * Put BL2 just below BL3-1. BL2_BASE is calculated using the current BL2 debug * size plus a little space for growth. */ -#define BL2_BASE (BL31_BASE - 0x1D000) +#define BL2_SIZE 0x1D000 +#define BL2_BASE (BL31_BASE - BL2_SIZE) #define BL2_LIMIT BL31_BASE /* @@ -127,8 +130,9 @@ * Put BL3-1 at the top of the Trusted SRAM. BL31_BASE is calculated using the * current BL3-1 debug size plus a little space for growth. */ -#define BL31_BASE (BL31_LIMIT - 0x20000) -#define BL31_LIMIT (BL_RAM_BASE + BL_RAM_SIZE) +#define BL31_SIZE 0x50000 +#define BL31_BASE (BL31_LIMIT - BL31_SIZE) +#define BL31_LIMIT (BL1_RW_BASE) #define BL31_PROGBITS_LIMIT BL1_RW_BASE @@ -138,12 +142,11 @@ * BL3-2 can execute from Secure SRAM, or Secure DRAM. */ #define BL32_SRAM_BASE BL_RAM_BASE -#define BL32_SRAM_LIMIT BL31_BASE -#define BL32_DRAM_BASE SEC_DRAM_BASE -#define BL32_DRAM_LIMIT (SEC_DRAM_BASE + SEC_DRAM_SIZE) +#define BL32_SRAM_LIMIT BL2_BASE #define BL32_MEM_BASE BL_RAM_BASE -#define BL32_MEM_SIZE BL_RAM_SIZE +#define BL32_MEM_SIZE (BL_RAM_SIZE - BL1_SIZE - \ + BL2_SIZE - BL31_SIZE) #define BL32_BASE BL32_SRAM_BASE #define BL32_LIMIT BL32_SRAM_LIMIT @@ -152,11 +155,21 @@ #define PLAT_PHY_ADDR_SPACE_SIZE (1ull << 42) #define PLAT_VIRT_ADDR_SPACE_SIZE (1ull << 42) +#if SPM_MM +#define MAX_MMAP_REGIONS 12 +#define MAX_XLAT_TABLES 11 +#else #define MAX_MMAP_REGIONS 11 #define MAX_XLAT_TABLES 10 +#endif #define MAX_IO_DEVICES 3 #define MAX_IO_HANDLES 4 +#if SPM_MM && defined(IMAGE_BL31) +# define PLAT_SP_IMAGE_MMAP_REGIONS 30 +# define PLAT_SP_IMAGE_MAX_XLAT_TABLES 20 +#endif + /* * PL011 related constants */ @@ -165,6 +178,10 @@ #define UART0_CLK_IN_HZ 1 #define UART1_CLK_IN_HZ 1 +/* Secure UART */ +#define UART2_BASE 0x60040000 +#define UART2_CLK_IN_HZ 1 + #define PLAT_QEMU_BOOT_UART_BASE UART0_BASE #define PLAT_QEMU_BOOT_UART_CLK_IN_HZ UART0_CLK_IN_HZ @@ -179,7 +196,7 @@ #define QEMU_FLASH1_SIZE 0x10000000 #define PLAT_QEMU_FIP_BASE 0x00008000 -#define PLAT_QEMU_FIP_MAX_SIZE 0x00020000 +#define PLAT_QEMU_FIP_MAX_SIZE 0x00400000 /* This is map from GIC_DIST up to last CPU (255) GIC_REDISTR */ #define DEVICE0_BASE 0x40000000 @@ -240,4 +257,99 @@ */ #define SYS_COUNTER_FREQ_IN_TICKS ((1000 * 1000 * 1000) / 16) -#endif /* __PLATFORM_DEF_H__ */ +#if SPM_MM +#define PLAT_QEMU_SP_IMAGE_BASE BL_RAM_BASE +#define PLAT_QEMU_SP_IMAGE_SIZE ULL(0x300000) + +#ifdef IMAGE_BL2 +/* In BL2 all memory allocated to the SPM Payload image is marked as RW. */ +# define QEMU_SP_IMAGE_MMAP MAP_REGION_FLAT( \ + PLAT_QEMU_SP_IMAGE_BASE, \ + PLAT_QEMU_SP_IMAGE_SIZE, \ + MT_MEMORY | MT_RW | \ + MT_SECURE) +#elif IMAGE_BL31 +/* All SPM Payload memory is marked as code in S-EL0 */ +# define QEMU_SP_IMAGE_MMAP MAP_REGION2(PLAT_QEMU_SP_IMAGE_BASE, \ + PLAT_QEMU_SP_IMAGE_BASE, \ + PLAT_QEMU_SP_IMAGE_SIZE, \ + MT_CODE | MT_SECURE | \ + MT_USER, \ + PAGE_SIZE) +#endif + +/* + * EL3 -> S-EL0 secure shared memory + */ +#define PLAT_SPM_BUF_PCPU_SIZE ULL(0x10000) +#define PLAT_SPM_BUF_SIZE (PLATFORM_CORE_COUNT * \ + PLAT_SPM_BUF_PCPU_SIZE) +#define PLAT_SPM_BUF_BASE (BL32_LIMIT - PLAT_SPM_BUF_SIZE) + +#define QEMU_SPM_BUF_EL3_MMAP MAP_REGION_FLAT(PLAT_SPM_BUF_BASE, \ + PLAT_SPM_BUF_SIZE, \ + MT_RW_DATA | MT_SECURE) + +#define QEMU_SPM_BUF_EL0_MMAP MAP_REGION2(PLAT_SPM_BUF_BASE, \ + PLAT_SPM_BUF_BASE, \ + PLAT_SPM_BUF_SIZE, \ + MT_RO_DATA | MT_SECURE | \ + MT_USER, \ + PAGE_SIZE) + +/* + * Shared memory between Normal world and S-EL0 for + * passing data during service requests. It will be marked as RW and NS. + */ +#define PLAT_QEMU_SP_IMAGE_NS_BUF_BASE (PLAT_QEMU_DT_BASE + \ + PLAT_QEMU_DT_MAX_SIZE) +#define PLAT_QEMU_SP_IMAGE_NS_BUF_SIZE ULL(0x10000) +#define QEMU_SP_IMAGE_NS_BUF_MMAP MAP_REGION2( \ + PLAT_QEMU_SP_IMAGE_NS_BUF_BASE, \ + PLAT_QEMU_SP_IMAGE_NS_BUF_BASE, \ + PLAT_QEMU_SP_IMAGE_NS_BUF_SIZE, \ + MT_RW_DATA | MT_NS | \ + MT_USER, \ + PAGE_SIZE) + +#define PLAT_SP_IMAGE_NS_BUF_BASE PLAT_QEMU_SP_IMAGE_NS_BUF_BASE +#define PLAT_SP_IMAGE_NS_BUF_SIZE PLAT_QEMU_SP_IMAGE_NS_BUF_SIZE + +#define PLAT_QEMU_SP_IMAGE_HEAP_BASE (PLAT_QEMU_SP_IMAGE_BASE + \ + PLAT_QEMU_SP_IMAGE_SIZE) +#define PLAT_QEMU_SP_IMAGE_HEAP_SIZE ULL(0x800000) + +#define PLAT_SP_IMAGE_STACK_BASE (PLAT_QEMU_SP_IMAGE_HEAP_BASE + \ + PLAT_QEMU_SP_IMAGE_HEAP_SIZE) +#define PLAT_SP_IMAGE_STACK_PCPU_SIZE ULL(0x10000) +#define QEMU_SP_IMAGE_STACK_TOTAL_SIZE (PLATFORM_CORE_COUNT * \ + PLAT_SP_IMAGE_STACK_PCPU_SIZE) + +#define QEMU_SP_IMAGE_RW_MMAP MAP_REGION2( \ + PLAT_QEMU_SP_IMAGE_HEAP_BASE, \ + PLAT_QEMU_SP_IMAGE_HEAP_BASE, \ + (QEMU_SP_IMAGE_STACK_TOTAL_SIZE + \ + PLAT_QEMU_SP_IMAGE_HEAP_SIZE), \ + MT_RW_DATA | MT_SECURE | \ + MT_USER, \ + PAGE_SIZE) + +/* Total number of memory regions with distinct properties */ +#define PLAT_QEMU_SP_IMAGE_NUM_MEM_REGIONS 6 + +/* + * Name of the section to put the translation tables used by the S-EL1/S-EL0 + * context of a Secure Partition. + */ +#define PLAT_SP_IMAGE_XLAT_SECTION_NAME "qemu_sp_xlat_table" +#define PLAT_SP_IMAGE_BASE_XLAT_SECTION_NAME "qemu_sp_xlat_table" + +/* Cookies passed to the Secure Partition at boot. Not used by QEMU platforms.*/ +#define PLAT_SPM_COOKIE_0 ULL(0) +#define PLAT_SPM_COOKIE_1 ULL(0) +#endif + +#define QEMU_PRI_BITS 2 +#define PLAT_SP_PRI 0x20 + +#endif /* PLATFORM_DEF_H */ diff --git a/plat/qemu/qemu_sbsa/platform.mk b/plat/qemu/qemu_sbsa/platform.mk index 09856d641..3aa7cbe5a 100644 --- a/plat/qemu/qemu_sbsa/platform.mk +++ b/plat/qemu/qemu_sbsa/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2019, Linaro Limited and Contributors. All rights reserved. +# Copyright (c) 2019-2020, Linaro Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -8,6 +8,12 @@ CRASH_REPORTING := 1 include lib/libfdt/libfdt.mk +ifeq (${SPM_MM},1) +NEED_BL32 := yes +EL3_EXCEPTION_HANDLING := 1 +GICV2_G0_FOR_EL3 := 1 +endif + # Enable new version of image loading on QEMU platforms LOAD_IMAGE_V2 := 1 @@ -80,6 +86,9 @@ BL31_SOURCES += lib/cpus/aarch64/aem_generic.S \ ${PLAT_QEMU_COMMON_PATH}/aarch64/plat_helpers.S \ ${PLAT_QEMU_COMMON_PATH}/qemu_bl31_setup.c \ ${QEMU_GIC_SOURCES} +ifeq (${SPM_MM},1) + BL31_SOURCES += ${PLAT_QEMU_COMMON_PATH}/qemu_spm.c +endif SEPARATE_CODE_AND_RODATA := 1 ENABLE_STACK_PROTECTOR := 0 -- cgit v1.2.3 From 57e92daf76b008c914677cc8574be5e78497104f Mon Sep 17 00:00:00 2001 From: David Pu Date: Thu, 8 Aug 2019 14:20:03 -0700 Subject: Tegra: common: make plat_psci_ops routines static This patch makes Tegra platform psci ops routines to static. These routines are called by PSCI framework and no external linkage is necessary. This patch also fixes MISRA C-2012 Rule 8.6 violations. Change-Id: Idd2381809f76dc0fd578c1c92c0f8eea124f2e88 Signed-off-by: David Pu --- plat/nvidia/tegra/common/tegra_pm.c | 24 ++++++++++++------------ plat/nvidia/tegra/include/tegra_private.h | 13 ------------- 2 files changed, 12 insertions(+), 25 deletions(-) diff --git a/plat/nvidia/tegra/common/tegra_pm.c b/plat/nvidia/tegra/common/tegra_pm.c index 78e96cf3e..6019182a1 100644 --- a/plat/nvidia/tegra/common/tegra_pm.c +++ b/plat/nvidia/tegra/common/tegra_pm.c @@ -34,7 +34,7 @@ extern uint64_t tegra_sec_entry_point; * the appropriate State-ID field within the `power_state` parameter which can * be utilized in `pwr_domain_suspend()` to suspend to system affinity level. ******************************************************************************/ -void tegra_get_sys_suspend_power_state(psci_power_state_t *req_state) +static void tegra_get_sys_suspend_power_state(psci_power_state_t *req_state) { /* all affinities use system suspend state id */ for (uint32_t i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++) { @@ -45,7 +45,7 @@ void tegra_get_sys_suspend_power_state(psci_power_state_t *req_state) /******************************************************************************* * Handler called when an affinity instance is about to enter standby. ******************************************************************************/ -void tegra_cpu_standby(plat_local_state_t cpu_state) +static void tegra_cpu_standby(plat_local_state_t cpu_state) { u_register_t saved_scr_el3; @@ -84,7 +84,7 @@ void tegra_cpu_standby(plat_local_state_t cpu_state) * Handler called when an affinity instance is about to be turned on. The * level and mpidr determine the affinity instance. ******************************************************************************/ -int32_t tegra_pwr_domain_on(u_register_t mpidr) +static int32_t tegra_pwr_domain_on(u_register_t mpidr) { return tegra_soc_pwr_domain_on(mpidr); } @@ -93,7 +93,7 @@ int32_t tegra_pwr_domain_on(u_register_t mpidr) * Handler called when a power domain is about to be turned off. The * target_state encodes the power state that each level should transition to. ******************************************************************************/ -void tegra_pwr_domain_off(const psci_power_state_t *target_state) +static void tegra_pwr_domain_off(const psci_power_state_t *target_state) { (void)tegra_soc_pwr_domain_off(target_state); } @@ -113,7 +113,7 @@ void tegra_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_sta * Handler called when a power domain is about to be suspended. The * target_state encodes the power state that each level should transition to. ******************************************************************************/ -void tegra_pwr_domain_suspend(const psci_power_state_t *target_state) +static void tegra_pwr_domain_suspend(const psci_power_state_t *target_state) { (void)tegra_soc_pwr_domain_suspend(target_state); @@ -132,7 +132,7 @@ void tegra_pwr_domain_suspend(const psci_power_state_t *target_state) * Handler called at the end of the power domain suspend sequence. The * target_state encodes the power state that each level should transition to. ******************************************************************************/ -__dead2 void tegra_pwr_domain_power_down_wfi(const psci_power_state_t +static __dead2 void tegra_pwr_domain_power_down_wfi(const psci_power_state_t *target_state) { /* call the chip's power down handler */ @@ -147,7 +147,7 @@ __dead2 void tegra_pwr_domain_power_down_wfi(const psci_power_state_t * being turned off earlier. The target_state encodes the low power state that * each level has woken up from. ******************************************************************************/ -void tegra_pwr_domain_on_finish(const psci_power_state_t *target_state) +static void tegra_pwr_domain_on_finish(const psci_power_state_t *target_state) { const plat_params_from_bl2_t *plat_params; @@ -198,7 +198,7 @@ void tegra_pwr_domain_on_finish(const psci_power_state_t *target_state) * having been suspended earlier. The target_state encodes the low power state * that each level has woken up from. ******************************************************************************/ -void tegra_pwr_domain_suspend_finish(const psci_power_state_t *target_state) +static void tegra_pwr_domain_suspend_finish(const psci_power_state_t *target_state) { tegra_pwr_domain_on_finish(target_state); } @@ -206,7 +206,7 @@ void tegra_pwr_domain_suspend_finish(const psci_power_state_t *target_state) /******************************************************************************* * Handler called when the system wants to be powered off ******************************************************************************/ -__dead2 void tegra_system_off(void) +static __dead2 void tegra_system_off(void) { INFO("Powering down system...\n"); @@ -216,7 +216,7 @@ __dead2 void tegra_system_off(void) /******************************************************************************* * Handler called when the system wants to be restarted. ******************************************************************************/ -__dead2 void tegra_system_reset(void) +static __dead2 void tegra_system_reset(void) { INFO("Restarting system...\n"); @@ -232,7 +232,7 @@ __dead2 void tegra_system_reset(void) /******************************************************************************* * Handler called to check the validity of the power state parameter. ******************************************************************************/ -int32_t tegra_validate_power_state(uint32_t power_state, +static int32_t tegra_validate_power_state(uint32_t power_state, psci_power_state_t *req_state) { assert(req_state != NULL); @@ -243,7 +243,7 @@ int32_t tegra_validate_power_state(uint32_t power_state, /******************************************************************************* * Platform handler called to check the validity of the non secure entrypoint. ******************************************************************************/ -int32_t tegra_validate_ns_entrypoint(uintptr_t entrypoint) +static int32_t tegra_validate_ns_entrypoint(uintptr_t entrypoint) { int32_t ret = PSCI_E_INVALID_ADDRESS; diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h index c181c3618..b638c818b 100644 --- a/plat/nvidia/tegra/include/tegra_private.h +++ b/plat/nvidia/tegra/include/tegra_private.h @@ -112,19 +112,6 @@ __dead2 void tegra_soc_prepare_system_off(void); plat_local_state_t tegra_soc_get_target_pwr_state(uint32_t lvl, const plat_local_state_t *states, uint32_t ncpu); -void tegra_get_sys_suspend_power_state(psci_power_state_t *req_state); -void tegra_cpu_standby(plat_local_state_t cpu_state); -int32_t tegra_pwr_domain_on(u_register_t mpidr); -void tegra_pwr_domain_off(const psci_power_state_t *target_state); -void tegra_pwr_domain_suspend(const psci_power_state_t *target_state); -void __dead2 tegra_pwr_domain_power_down_wfi(const psci_power_state_t *target_state); -void tegra_pwr_domain_on_finish(const psci_power_state_t *target_state); -void tegra_pwr_domain_suspend_finish(const psci_power_state_t *target_state); -__dead2 void tegra_system_off(void); -__dead2 void tegra_system_reset(void); -int32_t tegra_validate_power_state(uint32_t power_state, - psci_power_state_t *req_state); -int32_t tegra_validate_ns_entrypoint(uintptr_t entrypoint); /* Declarations for tegraXXX_pm.c */ int tegra_prepare_cpu_suspend(unsigned int id, unsigned int afflvl); -- cgit v1.2.3 From 43d22073d495bd435f9b441c582aef29e9b59930 Mon Sep 17 00:00:00 2001 From: David Pu Date: Mon, 5 Aug 2019 17:00:31 -0700 Subject: Tegra: platform: add function to check t194 chip This patch adds tegra_chipid_is_t194() function to check if it is a Tegra 194 chip. Change-Id: I6da6d3a2c9676b748931e42fde1b174cbcb4fd40 Signed-off-by: David Pu --- plat/nvidia/tegra/common/tegra_platform.c | 7 +++++++ plat/nvidia/tegra/include/tegra_platform.h | 2 ++ 2 files changed, 9 insertions(+) diff --git a/plat/nvidia/tegra/common/tegra_platform.c b/plat/nvidia/tegra/common/tegra_platform.c index 080413575..7c73e8fe1 100644 --- a/plat/nvidia/tegra/common/tegra_platform.c +++ b/plat/nvidia/tegra/common/tegra_platform.c @@ -108,6 +108,13 @@ bool tegra_chipid_is_t210_b01(void) return (tegra_chipid_is_t210() && (tegra_get_chipid_major() == 0x2U)); } +bool tegra_chipid_is_t194(void) +{ + uint32_t chip_id = (tegra_get_chipid() >> CHIP_ID_SHIFT) & CHIP_ID_MASK; + + return (chip_id == TEGRA_CHIPID_TEGRA19); +} + /* * Read the chip ID value and derive the platform */ diff --git a/plat/nvidia/tegra/include/tegra_platform.h b/plat/nvidia/tegra/include/tegra_platform.h index 7dfa4d089..b8297fd93 100644 --- a/plat/nvidia/tegra/include/tegra_platform.h +++ b/plat/nvidia/tegra/include/tegra_platform.h @@ -30,6 +30,7 @@ #define TEGRA_CHIPID_TEGRA13 U(0x13) #define TEGRA_CHIPID_TEGRA21 U(0x21) #define TEGRA_CHIPID_TEGRA18 U(0x18) +#define TEGRA_CHIPID_TEGRA19 U(0x19) /******************************************************************************* * JEDEC Standard Manufacturer's Identification Code and Bank ID @@ -52,6 +53,7 @@ bool tegra_chipid_is_t132(void); bool tegra_chipid_is_t186(void); bool tegra_chipid_is_t210(void); bool tegra_chipid_is_t210_b01(void); +bool tegra_chipid_is_t194(void); /* * Tegra platform identifiers -- cgit v1.2.3 From 5a32a03332aabb45f9efdca8c3c8105158a32777 Mon Sep 17 00:00:00 2001 From: "Abdul Halim, Muhammad Hadi Asyrafi" Date: Wed, 19 Aug 2020 14:50:01 +0800 Subject: intel: platform: Include GICv2 makefile This patch update each Intel's platform makefiles to include GICv2 makefile instead of manually sourcing individual c files. This aligns with latest changes from commit #1322dc94f7. Signed-off-by: Abdul Halim, Muhammad Hadi Asyrafi Change-Id: Ib1f446a6fc578f73a9ef86f9708ddf12d7d75f48 --- plat/intel/soc/agilex/platform.mk | 12 ++++++++---- plat/intel/soc/stratix10/platform.mk | 12 ++++++++---- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/plat/intel/soc/agilex/platform.mk b/plat/intel/soc/agilex/platform.mk index 8f857d1e6..814d9c663 100644 --- a/plat/intel/soc/agilex/platform.mk +++ b/plat/intel/soc/agilex/platform.mk @@ -10,16 +10,20 @@ PLAT_INCLUDES := \ -Iplat/intel/soc/common/drivers/ \ -Iplat/intel/soc/common/include/ +# Include GICv2 driver files +include drivers/arm/gic/v2/gicv2.mk +AGX_GICv2_SOURCES := \ + ${GICV2_SOURCES} \ + plat/common/plat_gicv2.c + + PLAT_BL_COMMON_SOURCES := \ - drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v2/gicv2_main.c \ - drivers/arm/gic/v2/gicv2_helpers.c \ + ${AGX_GICv2_SOURCES} \ drivers/delay_timer/delay_timer.c \ drivers/delay_timer/generic_delay_timer.c \ drivers/ti/uart/aarch64/16550_console.S \ lib/xlat_tables/aarch64/xlat_tables.c \ lib/xlat_tables/xlat_tables_common.c \ - plat/common/plat_gicv2.c \ plat/intel/soc/common/aarch64/platform_common.c \ plat/intel/soc/common/aarch64/plat_helpers.S diff --git a/plat/intel/soc/stratix10/platform.mk b/plat/intel/soc/stratix10/platform.mk index 112317b7b..3bd6af9ce 100644 --- a/plat/intel/soc/stratix10/platform.mk +++ b/plat/intel/soc/stratix10/platform.mk @@ -10,16 +10,20 @@ PLAT_INCLUDES := \ -Iplat/intel/soc/common/drivers/ \ -Iplat/intel/soc/common/include/ +# Include GICv2 driver files +include drivers/arm/gic/v2/gicv2.mk +AGX_GICv2_SOURCES := \ + ${GICV2_SOURCES} \ + plat/common/plat_gicv2.c + + PLAT_BL_COMMON_SOURCES := \ - drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v2/gicv2_main.c \ - drivers/arm/gic/v2/gicv2_helpers.c \ + ${AGX_GICv2_SOURCES} \ drivers/delay_timer/delay_timer.c \ drivers/delay_timer/generic_delay_timer.c \ drivers/ti/uart/aarch64/16550_console.S \ lib/xlat_tables/aarch64/xlat_tables.c \ lib/xlat_tables/xlat_tables_common.c \ - plat/common/plat_gicv2.c \ plat/intel/soc/common/aarch64/platform_common.c \ plat/intel/soc/common/aarch64/plat_helpers.S -- cgit v1.2.3 From 9eb1bb63e1d51dd85402227f7d904ae004ef49d9 Mon Sep 17 00:00:00 2001 From: Jacky Bai Date: Mon, 9 Dec 2019 09:53:28 +0800 Subject: plat: imx8m: Keep A53 PLAT on in wait mode(ret) Keep A53 PLAT(SCU) power domain on in wait mode(ret). RBC count only need to be set in PLAT OFF mode, so change it accordingly. Signed-off-by: Jacky Bai Change-Id: Ie55e25c8210d298506fc4dca7a9653583db45e0c --- plat/imx/imx8m/gpc_common.c | 8 +++----- plat/imx/imx8m/imx8m_psci_common.c | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/plat/imx/imx8m/gpc_common.c b/plat/imx/imx8m/gpc_common.c index eb2801cea..8aae1a62b 100644 --- a/plat/imx/imx8m/gpc_common.c +++ b/plat/imx/imx8m/gpc_common.c @@ -133,14 +133,12 @@ void imx_set_cluster_powerdown(unsigned int last_core, uint8_t power_state) val = mmio_read_32(IMX_GPC_BASE + LPCR_A53_AD); val &= ~EN_L2_WFI_PDN; /* L2 cache memory is on in WAIT mode */ - if (is_local_state_off(power_state)) + if (is_local_state_off(power_state)) { val |= (L2PGE | EN_PLAT_PDN); - else - val |= EN_PLAT_PDN; + imx_a53_plat_slot_config(true); + } mmio_write_32(IMX_GPC_BASE + LPCR_A53_AD, val); - - imx_a53_plat_slot_config(true); } else { /* clear the slot and ack for cluster power down */ imx_a53_plat_slot_config(false); diff --git a/plat/imx/imx8m/imx8m_psci_common.c b/plat/imx/imx8m/imx8m_psci_common.c index d6416288e..dbb772dc1 100644 --- a/plat/imx/imx8m/imx8m_psci_common.c +++ b/plat/imx/imx8m/imx8m_psci_common.c @@ -192,7 +192,7 @@ void __dead2 imx_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state) * drived by the 32K OSC, so delay 30us to make sure the counter * is really running. */ - if (!is_local_state_run(CLUSTER_PWR_STATE(target_state))) { + if (is_local_state_off(CLUSTER_PWR_STATE(target_state))) { imx_set_rbc_count(); udelay(30); } -- cgit v1.2.3 From fb9212be174810096b88d8b8e8686bac17f9c401 Mon Sep 17 00:00:00 2001 From: Jacky Bai Date: Wed, 22 Jul 2020 16:00:50 +0800 Subject: plat: imx8m: Correct the imr mask reg offset The number of gpc imr mask reg & the offset is different on some SOC, so correct it & replace the magic number with macro define. Signed-off-by: Jacky Bai Change-Id: Ic701675cdd92e043dcd7f06722f2e871068aec74 --- plat/imx/imx8m/gpc_common.c | 2 +- plat/imx/imx8m/imx8mm/include/gpc_reg.h | 2 ++ plat/imx/imx8m/imx8mn/include/gpc_reg.h | 2 ++ plat/imx/imx8m/imx8mp/include/gpc_reg.h | 2 ++ plat/imx/imx8m/imx8mq/include/gpc_reg.h | 2 ++ plat/imx/imx8m/include/gpc.h | 1 - 6 files changed, 9 insertions(+), 2 deletions(-) diff --git a/plat/imx/imx8m/gpc_common.c b/plat/imx/imx8m/gpc_common.c index 8aae1a62b..babcecff0 100644 --- a/plat/imx/imx8m/gpc_common.c +++ b/plat/imx/imx8m/gpc_common.c @@ -16,7 +16,7 @@ #include #include -static uint32_t gpc_imr_offset[] = { 0x30, 0x40, 0x1c0, 0x1d0, }; +static uint32_t gpc_imr_offset[] = { IMR1_CORE0_A53, IMR1_CORE1_A53, IMR1_CORE2_A53, IMR1_CORE3_A53, }; #pragma weak imx_set_cpu_pwr_off #pragma weak imx_set_cpu_pwr_on diff --git a/plat/imx/imx8m/imx8mm/include/gpc_reg.h b/plat/imx/imx8m/imx8mm/include/gpc_reg.h index c697af29b..1a4eae546 100644 --- a/plat/imx/imx8m/imx8mm/include/gpc_reg.h +++ b/plat/imx/imx8m/imx8mm/include/gpc_reg.h @@ -124,4 +124,6 @@ #define VPU_G2_PGC 0xf00 #define VPU_H1_PGC 0xf40 +#define IRQ_IMR_NUM U(4) + #endif /* GPC_REG_H */ diff --git a/plat/imx/imx8m/imx8mn/include/gpc_reg.h b/plat/imx/imx8m/imx8mn/include/gpc_reg.h index fd10438a4..8a8136814 100644 --- a/plat/imx/imx8m/imx8mn/include/gpc_reg.h +++ b/plat/imx/imx8m/imx8mn/include/gpc_reg.h @@ -106,4 +106,6 @@ #define GPUMIX_PGC 0xdc0 #define DISPMIX_PGC 0xe80 +#define IRQ_IMR_NUM U(4) + #endif /* GPC_REG_H */ diff --git a/plat/imx/imx8m/imx8mp/include/gpc_reg.h b/plat/imx/imx8m/imx8mp/include/gpc_reg.h index 12da6ac7e..7909937b2 100644 --- a/plat/imx/imx8m/imx8mp/include/gpc_reg.h +++ b/plat/imx/imx8m/imx8mp/include/gpc_reg.h @@ -146,4 +146,6 @@ #define MEDIAMIX_ISPDWP_PGC 0xf80 #define DDRMIX_PGC 0xfc0 +#define IRQ_IMR_NUM U(5) + #endif /* GPC_REG_H */ diff --git a/plat/imx/imx8m/imx8mq/include/gpc_reg.h b/plat/imx/imx8m/imx8mq/include/gpc_reg.h index 9f472d609..f171bd9d0 100644 --- a/plat/imx/imx8m/imx8mq/include/gpc_reg.h +++ b/plat/imx/imx8m/imx8mq/include/gpc_reg.h @@ -84,4 +84,6 @@ #define MASTER1_MAPPING BIT(1) #define MASTER2_MAPPING BIT(2) +#define IRQ_IMR_NUM U(4) + #endif /* GPC_REG_H */ diff --git a/plat/imx/imx8m/include/gpc.h b/plat/imx/imx8m/include/gpc.h index 89a0b9d39..6f86e1d6b 100644 --- a/plat/imx/imx8m/include/gpc.h +++ b/plat/imx/imx8m/include/gpc.h @@ -25,7 +25,6 @@ #define SLTx_CFG(n) ((SLT0_CFG + ((n) * 4))) #define SLT_COREx_PUP(core_id) (0x2 << ((core_id) * 2)) -#define IRQ_IMR_NUM 4 #define IMR_MASK_ALL 0xffffffff #define IMX_PD_DOMAIN(name, on) \ -- cgit v1.2.3 From 6b704da34b66e5239b7f570842df614db94af521 Mon Sep 17 00:00:00 2001 From: Ruari Phipps Date: Tue, 28 Jul 2020 11:26:29 +0100 Subject: SPM: Change condition on saving/restoring EL2 registers Make this more scalable by explicitly checking internal and hardware states at run_time Signed-off-by: Ruari Phipps Change-Id: I1c6ed1c1badb3538a93bff3ac5b5189b59cccfa1 --- lib/el3_runtime/aarch64/context_mgmt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c index f4a34bfaa..e5434eb13 100644 --- a/lib/el3_runtime/aarch64/context_mgmt.c +++ b/lib/el3_runtime/aarch64/context_mgmt.c @@ -585,7 +585,7 @@ void cm_el2_sysregs_context_save(uint32_t security_state) * S-EL2 context if S-EL2 is enabled. */ if ((security_state == NON_SECURE) || - ((scr_el3 & SCR_EEL2_BIT) != 0U)) { + ((security_state == SECURE) && ((scr_el3 & SCR_EEL2_BIT) != 0U))) { cpu_context_t *ctx; ctx = cm_get_context(security_state); @@ -607,7 +607,7 @@ void cm_el2_sysregs_context_restore(uint32_t security_state) * S-EL2 context if S-EL2 is enabled. */ if ((security_state == NON_SECURE) || - ((scr_el3 & SCR_EEL2_BIT) != 0U)) { + ((security_state == SECURE) && ((scr_el3 & SCR_EEL2_BIT) != 0U))) { cpu_context_t *ctx; ctx = cm_get_context(security_state); -- cgit v1.2.3 From 9de91c7542c8a8970dacf324af7f7681855bcdd1 Mon Sep 17 00:00:00 2001 From: Ruari Phipps Date: Fri, 17 Jul 2020 16:43:50 +0100 Subject: SPM: Add third cactus partition to manifests Add information about the third partition so it can be loaded into SPM when running the tests Signed-off-by: Ruari Phipps Change-Id: I5544e88df391ef294ddf6b5750d468d3e74892b1 --- plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts | 7 +++++++ plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts index a1c909449..90fb3474c 100644 --- a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts +++ b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts @@ -38,6 +38,13 @@ vcpu_count = <2>; mem_size = <1048576>; }; + vm3 { + is_ffa_partition; + debug_name = "cactus-tertiary"; + load_address = <0x7200000>; + vcpu_count = <2>; + mem_size = <1048576>; + }; }; cpus { 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 1ee728546..692f5a9cb 100644 --- a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts +++ b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts @@ -92,6 +92,11 @@ load-address = <0x7100000>; owner = "Plat"; }; + + cactus-tertiary { + uuid = <0x735cb579 0xb9448c1d 0xe1619385 0xd2d80a77>; + load-address = <0x7200000>; + }; #endif }; -- cgit v1.2.3 From e7d344de01ad11b856233634717aafe9312697e4 Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Sun, 16 Aug 2020 16:01:13 +0100 Subject: libc/memset: Implement function in assembler Trace analysis of FVP_Base_AEMv8A model running in Aarch32 mode with the build options listed below: TRUSTED_BOARD_BOOT=1 GENERATE_COT=1 ARM_ROTPK_LOCATION=devel_ecdsa KEY_ALG=ecdsa ROT_KEY=plat/arm/board/common/rotpk/arm_rotprivk_ecdsa.pem shows that when auth_signature() gets called 71.84% of CPU execution time is spent in memset() function written in C using single byte write operations, see lib\libc\memset.c. This patch replaces C memset() implementation with assembler version giving the following results: - for Aarch32 in auth_signature() call memset() CPU time reduced to 24.84%. - Number of CPU instructions executed during TF-A boot stage before start of BL33 in RELEASE builds: ---------------------------------------------- | Arch | C | assembler | % | ---------------------------------------------- | Aarch32 | 2073275460 | 1487400003 | -28.25 | | Aarch64 | 2056807158 | 1244898303 | -39.47 | ---------------------------------------------- The patch also replaces memset.c with aarch64/memset.S in plat\nvidia\tegra\platform.mk. Change-Id: Ifbf085a2f577a25491e2d28446ee95a4ac891597 Signed-off-by: Alexei Fedorov --- lib/libc/aarch32/memset.S | 74 ++++++++++++++++++++++++++++++++++++++++ lib/libc/aarch64/memset.S | 79 +++++++++++++++++++++++++++++++++++++++++++ lib/libc/libc.mk | 9 +++-- lib/libc/memset.c | 18 ---------- plat/nvidia/tegra/platform.mk | 4 +-- 5 files changed, 162 insertions(+), 22 deletions(-) create mode 100644 lib/libc/aarch32/memset.S create mode 100644 lib/libc/aarch64/memset.S delete mode 100644 lib/libc/memset.c diff --git a/lib/libc/aarch32/memset.S b/lib/libc/aarch32/memset.S new file mode 100644 index 000000000..0b69897fd --- /dev/null +++ b/lib/libc/aarch32/memset.S @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + + .syntax unified + .global memset + +/* ----------------------------------------------------------------------- + * void memset(void *dst, int val, size_t count) + * + * Copy the value of 'val' (converted to an unsigned char) into + * each of the first 'count' characters of the object pointed to by 'dst'. + * + * Returns the value of 'dst'. + * ----------------------------------------------------------------------- + */ +func memset + cmp r2, #0 + bxeq lr /* return if 'count' = 0 */ + mov r12, r0 /* keep r0 */ + tst r0, #3 + beq aligned /* 4-bytes aligned */ + + /* Unaligned 'dst' */ +unaligned: + strb r1, [r12], #1 + subs r2, r2, #1 + bxeq lr /* return if 0 */ + tst r12, #3 + bne unaligned /* continue while unaligned */ + + /* 4-bytes aligned */ +aligned:bfi r1, r1, #8, #8 /* propagate 'val' */ + bfi r1, r1, #16, #16 + + mov r3, r1 + + cmp r2, #16 + blo less_16 + + push {r4, lr} + mov r4, r1 + mov lr, r1 + + cmp r2, #32 + blo less_32 + +write_32: + stmia r12!, {r1, r3, r4, lr} /* write 32 bytes in a loop */ + stmia r12!, {r1, r3, r4, lr} + subs r2, r2, #32 + popeq {r4, pc} /* return if 0 */ + cmp r2, #32 + bhs write_32 + +less_32:cmp r2, #16 + stmiahs r12!, {r1, r3, r4, lr} /* write 16 bytes */ + popeq {r4, pc} /* return if 16 */ + pop {r4, lr} + +less_16:lsls r2, r2, #29 /* C = r2[3]; N = r2[2]; Z = r2[2:0] */ + stmiacs r12!, {r1, r3} /* write 8 bytes */ + bxeq lr /* return if 8 */ + strmi r1, [r12], #4 /* write 4 bytes */ + lsls r2, r2, #1 /* N = r2[1]; Z = r2[0] */ + strhmi r1, [r12], #2 /* write 2 bytes */ + strbne r1, [r12] /* write 1 byte */ + bx lr + +endfunc memset diff --git a/lib/libc/aarch64/memset.S b/lib/libc/aarch64/memset.S new file mode 100644 index 000000000..8c65760ce --- /dev/null +++ b/lib/libc/aarch64/memset.S @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + + .global memset + +/* ----------------------------------------------------------------------- + * void memset(void *dst, int val, size_t count) + * + * Copy the value of 'val' (converted to an unsigned char) into + * each of the first 'count' characters of the object pointed to by 'dst'. + * + * Returns the value of 'dst'. + * ----------------------------------------------------------------------- + */ +func memset + cbz w2, exit /* exit if 'count' = 0 */ + mov x3, x0 /* keep x0 */ + tst x0, #7 + b.eq aligned /* 8-bytes aligned */ + + /* Unaligned 'dst' */ +unaligned: + strb w1, [x3], #1 + subs w2, w2, #1 + b.eq exit /* exit if 0 */ + tst x3, #7 + b.ne unaligned /* continue while unaligned */ + + /* 8-bytes aligned */ +aligned:cbz x1, x1_zero + bfi w1, w1, #8, #8 /* propagate 'val' */ + bfi w1, w1, #16, #16 + bfi x1, x1, #32, #32 + +x1_zero:ands w4, w2, #~0x3f + b.eq less_64 + +write_64: + .rept 4 + stp x1, x1, [x3], #16 /* write 64 bytes in a loop */ + .endr + subs w4, w4, #64 + b.ne write_64 + ands w2, w2, #0x3f + b.eq exit /* exit if 0 */ + +less_64:tbz w2, #5, less_32 /* < 32 bytes */ + stp x1, x1, [x3], #16 /* write 32 bytes */ + stp x1, x1, [x3], #16 + ands w2, w2, #0x1f + b.eq exit + +less_32:tbz w2, #4, less_16 /* < 16 bytes */ + stp x1, x1, [x3], #16 /* write 16 bytes */ + ands w2, w2, #0xf + b.eq exit + +less_16:tbz w2, #3, less_8 /* < 8 bytes */ + str x1, [x3], #8 /* write 8 bytes */ + ands w2, w2, #7 + b.eq exit + +less_8: tbz w2, #2, less_4 /* < 4 bytes */ + str w1, [x3], #4 /* write 4 bytes */ + ands w2, w2, #3 + b.eq exit + +less_4: tbz w2, #1, less_2 /* < 2 bytes */ + strh w1, [x3], #2 /* write 2 bytes */ + tbz w2, #0, exit +less_2: strb w1, [x3] /* write 1 byte */ +exit: ret + +endfunc memset diff --git a/lib/libc/libc.mk b/lib/libc/libc.mk index 93d30d035..90a2a1e16 100644 --- a/lib/libc/libc.mk +++ b/lib/libc/libc.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -13,7 +13,6 @@ LIBC_SRCS := $(addprefix lib/libc/, \ memcpy.c \ memmove.c \ memrchr.c \ - memset.c \ printf.c \ putchar.c \ puts.c \ @@ -28,8 +27,14 @@ LIBC_SRCS := $(addprefix lib/libc/, \ ifeq (${ARCH},aarch64) LIBC_SRCS += $(addprefix lib/libc/aarch64/, \ + memset.S \ setjmp.S) endif +ifeq (${ARCH},aarch32) +LIBC_SRCS += $(addprefix lib/libc/aarch32/, \ + memset.S) +endif + INCLUDES += -Iinclude/lib/libc \ -Iinclude/lib/libc/$(ARCH) \ diff --git a/lib/libc/memset.c b/lib/libc/memset.c deleted file mode 100644 index d8007d8e9..000000000 --- a/lib/libc/memset.c +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include - -void *memset(void *dst, int val, size_t count) -{ - char *ptr = dst; - - while (count--) - *ptr++ = val; - - return dst; -} diff --git a/plat/nvidia/tegra/platform.mk b/plat/nvidia/tegra/platform.mk index a4724e64b..5cac46f64 100644 --- a/plat/nvidia/tegra/platform.mk +++ b/plat/nvidia/tegra/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. # Copyright (c) 2020, NVIDIA Corporation. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause @@ -69,11 +69,11 @@ TF_CFLAGS += -Wsign-compare -nostdlib # override with necessary libc files for the Tegra platform override LIBC_SRCS := $(addprefix lib/libc/, \ + aarch64/memset.S \ aarch64/setjmp.S \ assert.c \ memcpy.c \ memmove.c \ - memset.c \ printf.c \ putchar.c \ strlen.c \ -- cgit v1.2.3 From 9061c0c9ab70bea29a56f1ea73f8f0f8859f0bab Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Thu, 20 Aug 2020 10:41:36 +0200 Subject: doc: Minor formatting improvement in the coding guidelines document Change-Id: I5362780db422772fd547dc8e68e459109edccdd0 Signed-off-by: Sandrine Bailleux --- docs/process/coding-guidelines.rst | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/process/coding-guidelines.rst b/docs/process/coding-guidelines.rst index f7d53a97e..97086047d 100644 --- a/docs/process/coding-guidelines.rst +++ b/docs/process/coding-guidelines.rst @@ -95,10 +95,13 @@ By default, all logging statements with a log level ``<= LOG_LEVEL_INFO`` will be compiled into debug builds and all statements with a log level ``<= LOG_LEVEL_NOTICE`` will be compiled into release builds. This can be overridden from the command line or by the platform makefile (although it may be -necessary to clean the build directory first). For example, to enable -``VERBOSE`` logging on FVP: +necessary to clean the build directory first). -``make PLAT=fvp LOG_LEVEL=50 all`` +For example, to enable ``VERBOSE`` logging on FVP: + +.. code:: shell + + make PLAT=fvp LOG_LEVEL=50 all Use const data where possible ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- cgit v1.2.3 From fe5e1c145a43f4a07c306535e3f295d88f5a5ec9 Mon Sep 17 00:00:00 2001 From: Jacky Bai Date: Tue, 7 Jan 2020 11:05:22 +0800 Subject: plat: imx8m: Fix the race condition during cpu hotplug CPU hotplug & cpuidle have some race condition when doing CPU hotplug stress test. different CPU cores have the chance to access the same GPC register(A53_AD), so lock is necessary to do exlusive access. Signed-off-by: Jacky Bai Change-Id: I1296592e05fa78429c3f0fac066951521db755e3 --- plat/imx/imx8m/gpc_common.c | 17 +++++++++++++++++ plat/imx/imx8m/imx8mq/gpc.c | 9 +++++++++ plat/imx/imx8m/include/gpc.h | 2 ++ 3 files changed, 28 insertions(+) diff --git a/plat/imx/imx8m/gpc_common.c b/plat/imx/imx8m/gpc_common.c index babcecff0..1e55f058d 100644 --- a/plat/imx/imx8m/gpc_common.c +++ b/plat/imx/imx8m/gpc_common.c @@ -18,6 +18,8 @@ static uint32_t gpc_imr_offset[] = { IMR1_CORE0_A53, IMR1_CORE1_A53, IMR1_CORE2_A53, IMR1_CORE3_A53, }; +DEFINE_BAKERY_LOCK(gpc_lock); + #pragma weak imx_set_cpu_pwr_off #pragma weak imx_set_cpu_pwr_on #pragma weak imx_set_cpu_lpm @@ -38,16 +40,27 @@ void imx_set_cpu_secure_entry(unsigned int core_id, uintptr_t sec_entrypoint) void imx_set_cpu_pwr_off(unsigned int core_id) { + + bakery_lock_get(&gpc_lock); + /* enable the wfi power down of the core */ mmio_setbits_32(IMX_GPC_BASE + LPCR_A53_AD, COREx_WFI_PDN(core_id)); + + bakery_lock_release(&gpc_lock); + /* assert the pcg pcr bit of the core */ mmio_setbits_32(IMX_GPC_BASE + COREx_PGC_PCR(core_id), 0x1); } void imx_set_cpu_pwr_on(unsigned int core_id) { + bakery_lock_get(&gpc_lock); + /* clear the wfi power down bit of the core */ mmio_clrbits_32(IMX_GPC_BASE + LPCR_A53_AD, COREx_WFI_PDN(core_id)); + + bakery_lock_release(&gpc_lock); + /* assert the ncpuporeset */ mmio_clrbits_32(IMX_SRC_BASE + SRC_A53RCR1, (1 << core_id)); /* assert the pcg pcr bit of the core */ @@ -67,6 +80,8 @@ void imx_set_cpu_pwr_on(unsigned int core_id) void imx_set_cpu_lpm(unsigned int core_id, bool pdn) { + bakery_lock_get(&gpc_lock); + if (pdn) { /* enable the core WFI PDN & IRQ PUP */ mmio_setbits_32(IMX_GPC_BASE + LPCR_A53_AD, COREx_WFI_PDN(core_id) | @@ -80,6 +95,8 @@ void imx_set_cpu_lpm(unsigned int core_id, bool pdn) /* deassert the pcg pcr bit of the core */ mmio_clrbits_32(IMX_GPC_BASE + COREx_PGC_PCR(core_id), 0x1); } + + bakery_lock_release(&gpc_lock); } /* diff --git a/plat/imx/imx8m/imx8mq/gpc.c b/plat/imx/imx8m/imx8mq/gpc.c index 942ae459c..367c9411d 100644 --- a/plat/imx/imx8m/imx8mq/gpc.c +++ b/plat/imx/imx8m/imx8mq/gpc.c @@ -19,9 +19,14 @@ /* use wfi power down the core */ void imx_set_cpu_pwr_off(unsigned int core_id) { + bakery_lock_get(&gpc_lock); + /* enable the wfi power down of the core */ mmio_setbits_32(IMX_GPC_BASE + LPCR_A53_AD, COREx_WFI_PDN(core_id) | (1 << (core_id + 20))); + + bakery_lock_release(&gpc_lock); + /* assert the pcg pcr bit of the core */ mmio_setbits_32(IMX_GPC_BASE + COREx_PGC_PCR(core_id), 0x1); }; @@ -29,6 +34,8 @@ void imx_set_cpu_pwr_off(unsigned int core_id) /* if out of lpm, we need to do reverse steps */ void imx_set_cpu_lpm(unsigned int core_id, bool pdn) { + bakery_lock_get(&gpc_lock); + if (pdn) { /* enable the core WFI PDN & IRQ PUP */ mmio_setbits_32(IMX_GPC_BASE + LPCR_A53_AD, COREx_WFI_PDN(core_id) | @@ -42,6 +49,8 @@ void imx_set_cpu_lpm(unsigned int core_id, bool pdn) /* deassert the pcg pcr bit of the core */ mmio_setbits_32(IMX_GPC_BASE + COREx_PGC_PCR(core_id), 0x1); } + + bakery_lock_release(&gpc_lock); } void imx_pup_pdn_slot_config(int last_core, bool pdn) diff --git a/plat/imx/imx8m/include/gpc.h b/plat/imx/imx8m/include/gpc.h index 6f86e1d6b..075da91b1 100644 --- a/plat/imx/imx8m/include/gpc.h +++ b/plat/imx/imx8m/include/gpc.h @@ -54,6 +54,8 @@ struct imx_pwr_domain { bool always_on; }; +DECLARE_BAKERY_LOCK(gpc_lock); + /* function declare */ void imx_gpc_init(void); void imx_set_cpu_secure_entry(unsigned int core_index, uintptr_t sec_entrypoint); -- cgit v1.2.3 From 06ffa16694b315380c9b2ebafe06d83873f2a78d Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Thu, 20 Aug 2020 11:17:41 +0200 Subject: doc: Recommend using C rather than assembly language Add a section for that in the coding guidelines. Change-Id: Ie6819c4df5889a861460eb96acf2bc9c0cfb494e Signed-off-by: Sandrine Bailleux --- docs/process/coding-guidelines.rst | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/docs/process/coding-guidelines.rst b/docs/process/coding-guidelines.rst index 97086047d..a8a84549a 100644 --- a/docs/process/coding-guidelines.rst +++ b/docs/process/coding-guidelines.rst @@ -441,6 +441,25 @@ unsigned integer on all systems, cast it to ``unsigned int``. These guidelines should be updated if additional types are needed. +Favor C language over assembly language +--------------------------------------- + +Generally, prefer code written in C over assembly. Assembly code is less +portable, harder to understand, maintain and audit security wise. Also, static +analysis tools generally don't analyze assembly code. + +There are, however, legitimate uses of assembly language. These include: + + - Early boot code executed before the C runtime environment is setup. + + - Exception handling code. + + - Low-level code where the exact sequence of instructions executed on the CPU + matters, such as CPU reset sequences. + + - Low-level code where specific system-level instructions must be used, such + as cache maintenance operations. + -------------- *Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.* -- cgit v1.2.3 From c0267cc9947ac04478f6f0e54dbbfc7f8c02f6a0 Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Mon, 28 Oct 2019 08:52:45 +0000 Subject: SPMD: entry point info get helper This patch provides a helper to get the entry_point_info structure used by the boot CPU as it is used to initialise the SPMC context on secondary CPUs. Change-Id: I99087dc7a86a7258e545d24a2ff06aa25170f00c Signed-off-by: Olivier Deprez --- services/std_svc/spmd/spmd_main.c | 8 ++++++++ services/std_svc/spmd/spmd_private.h | 3 +++ 2 files changed, 11 insertions(+) diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c index 4c2b58df2..b551add01 100644 --- a/services/std_svc/spmd/spmd_main.c +++ b/services/std_svc/spmd/spmd_main.c @@ -51,6 +51,14 @@ spmd_spm_core_context_t *spmd_get_context(void) return &spm_core_context[linear_id]; } +/******************************************************************************* + * SPM Core entry point information get helper. + ******************************************************************************/ +entry_point_info_t *spmd_spmc_ep_info_get(void) +{ + return spmc_ep_info; +} + /******************************************************************************* * Static function declaration. ******************************************************************************/ diff --git a/services/std_svc/spmd/spmd_private.h b/services/std_svc/spmd/spmd_private.h index 494630907..da66ee3c2 100644 --- a/services/std_svc/spmd/spmd_private.h +++ b/services/std_svc/spmd/spmd_private.h @@ -65,6 +65,9 @@ __dead2 void spmd_spm_core_sync_exit(uint64_t rc); uint64_t spmd_spm_core_enter(uint64_t *c_rt_ctx); void __dead2 spmd_spm_core_exit(uint64_t c_rt_ctx, uint64_t ret); +/* SPMC entry point information helper */ +entry_point_info_t *spmd_spmc_ep_info_get(void); + /* SPMC context on current CPU get helper */ spmd_spm_core_context_t *spmd_get_context(void); -- cgit v1.2.3 From 9dcf63dd8bb02fca8f781c06e610f2012e5dc690 Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Mon, 28 Oct 2019 09:03:13 +0000 Subject: SPMD: enhance SPMC internal boot states This patch adds SPMC states used by the SPMD to track SPMC boot phases specifically on secondary cores. Change-Id: If97af7352dda7f04a8e46a56892a2aeddcfab91b Signed-off-by: Olivier Deprez Signed-off-by: Max Shvetsov --- services/std_svc/spmd/spmd_main.c | 18 ++++++++++++++---- services/std_svc/spmd/spmd_private.h | 4 +++- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c index b551add01..02b73c649 100644 --- a/services/std_svc/spmd/spmd_main.c +++ b/services/std_svc/spmd/spmd_main.c @@ -133,9 +133,18 @@ 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_RESET; + ctx->state = SPMC_STATE_ON_PENDING; + + /* Set the SPMC context state on other CPUs to OFF */ + for (core_id = 0; core_id < PLATFORM_CORE_COUNT; core_id++) { + if (core_id != linear_id) { + spm_core_context[core_id].state = SPMC_STATE_OFF; + } + } rc = spmd_spm_core_sync_entry(ctx); if (rc != 0ULL) { @@ -143,7 +152,8 @@ static int32_t spmd_init(void) return 0; } - ctx->state = SPMC_STATE_IDLE; + ctx->state = SPMC_STATE_ON; + VERBOSE("SPM Core init end.\n"); return 1; @@ -375,7 +385,7 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, * this CPU. If so, then indicate that the SPM Core initialised * unsuccessfully. */ - if (secure_origin && (ctx->state == SPMC_STATE_RESET)) { + if (secure_origin && (ctx->state == SPMC_STATE_ON_PENDING)) { spmd_spm_core_sync_exit(x2); } @@ -508,7 +518,7 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, * this CPU from the Secure world. If so, then indicate that the * SPM Core initialised successfully. */ - if (secure_origin && (ctx->state == SPMC_STATE_RESET)) { + if (secure_origin && (ctx->state == SPMC_STATE_ON_PENDING)) { spmd_spm_core_sync_exit(0); } diff --git a/services/std_svc/spmd/spmd_private.h b/services/std_svc/spmd/spmd_private.h index da66ee3c2..6e08c180f 100644 --- a/services/std_svc/spmd/spmd_private.h +++ b/services/std_svc/spmd/spmd_private.h @@ -35,7 +35,9 @@ typedef enum spmc_state { SPMC_STATE_RESET = 0, - SPMC_STATE_IDLE + SPMC_STATE_OFF, + SPMC_STATE_ON_PENDING, + SPMC_STATE_ON } spmc_state_t; /* -- cgit v1.2.3 From b058f20a7e587e4362413cf8e4544dcc0bcaab96 Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Mon, 28 Oct 2019 09:07:50 +0000 Subject: SPMD: add generic SPD PM handlers This patch defines and registers the SPMD PM handler hooks. This is intended to relay boot and PM events to the SPMC. Change-Id: If5a758d22b8d2152cbbb83a0cad563b5e1c6bd49 Signed-off-by: Olivier Deprez Signed-off-by: Max Shvetsov --- services/std_svc/spmd/spmd_pm.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 services/std_svc/spmd/spmd_pm.c diff --git a/services/std_svc/spmd/spmd_pm.c b/services/std_svc/spmd/spmd_pm.c new file mode 100644 index 000000000..eff59adb1 --- /dev/null +++ b/services/std_svc/spmd/spmd_pm.c @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include "spmd_private.h" + +/******************************************************************************* + * This CPU has been turned on. Enter SPMC to initialise S-EL1 or S-EL2. As part + * of the SPMC initialization path, they will initialize any SPs that they + * manage. Entry into SPMC is done after initialising minimal architectural + * state that guarantees safe execution. + ******************************************************************************/ +static void spmd_cpu_on_finish_handler(u_register_t unused) +{ + unsigned int linear_id = plat_my_core_pos(); + spmd_spm_core_context_t *ctx = spmd_get_context(); + int rc; + + assert(ctx->state != SPMC_STATE_ON); + + rc = spmd_spm_core_sync_entry(ctx); + if (rc != 0) { + ERROR("SPMC initialisation failed (%d) on CPU%u\n", rc, + linear_id); + ctx->state = SPMC_STATE_OFF; + return; + } + + ctx->state = SPMC_STATE_ON; +} + +/******************************************************************************* + * Structure populated by the SPM Dispatcher to perform any bookkeeping before + * PSCI executes a power mgmt. operation. + ******************************************************************************/ +const spd_pm_ops_t spmd_pm = { + .svc_on_finish = spmd_cpu_on_finish_handler, +}; -- cgit v1.2.3 From a334c4e6915d111ba48da60f898d4922c01a16b3 Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Mon, 28 Oct 2019 09:15:52 +0000 Subject: SPMD: register the SPD PM hooks Change-Id: If88d64c0e3d60accd2638a55f9f3299ec700a8c8 Signed-off-by: Olivier Deprez --- services/std_svc/spmd/spmd.mk | 1 + services/std_svc/spmd/spmd_main.c | 3 +++ services/std_svc/spmd/spmd_private.h | 7 ++++++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/services/std_svc/spmd/spmd.mk b/services/std_svc/spmd/spmd.mk index 38d43f167..73f7c85dd 100644 --- a/services/std_svc/spmd/spmd.mk +++ b/services/std_svc/spmd/spmd.mk @@ -10,6 +10,7 @@ endif SPMD_SOURCES += $(addprefix services/std_svc/spmd/, \ ${ARCH}/spmd_helpers.S \ + spmd_pm.c \ spmd_main.c) # Let the top-level Makefile know that we intend to include a BL32 image diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c index 02b73c649..93a0203c5 100644 --- a/services/std_svc/spmd/spmd_main.c +++ b/services/std_svc/spmd/spmd_main.c @@ -266,6 +266,9 @@ static int spmd_spmc_init(void *pm_addr) INFO("SPM Core setup done.\n"); + /* Register power management hooks with PSCI */ + psci_register_spd_pm_hook(&spmd_pm); + /* Register init function for deferred init. */ bl31_register_bl32_init(&spmd_init); diff --git a/services/std_svc/spmd/spmd_private.h b/services/std_svc/spmd/spmd_private.h index 6e08c180f..e13a5f021 100644 --- a/services/std_svc/spmd/spmd_private.h +++ b/services/std_svc/spmd/spmd_private.h @@ -30,8 +30,10 @@ #define SPMD_C_RT_CTX_ENTRIES (SPMD_C_RT_CTX_SIZE >> DWORD_SHIFT) #ifndef __ASSEMBLER__ -#include #include +#include +#include +#include typedef enum spmc_state { SPMC_STATE_RESET = 0, @@ -67,6 +69,9 @@ __dead2 void spmd_spm_core_sync_exit(uint64_t rc); uint64_t spmd_spm_core_enter(uint64_t *c_rt_ctx); void __dead2 spmd_spm_core_exit(uint64_t c_rt_ctx, uint64_t ret); +/* SPMD SPD power management handlers */ +extern const spd_pm_ops_t spmd_pm; + /* SPMC entry point information helper */ entry_point_info_t *spmd_spmc_ep_info_get(void); -- cgit v1.2.3 From c2901419b54ae5334b666bc8f4fc35c36246daac Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Thu, 16 Apr 2020 16:59:21 +0200 Subject: SPMD: introduce SPMC to SPMD messages FF-A interface to handle SPMC to SPMD direct messages requests. Signed-off-by: Olivier Deprez Signed-off-by: Max Shvetsov Change-Id: Ia707a308c55561a31dcfa86e554ea1c9e23f862a --- include/services/ffa_svc.h | 39 ++++++++++++++++++++++++++++++++++++ services/std_svc/spmd/spmd_main.c | 13 ++++++++++-- services/std_svc/spmd/spmd_private.h | 11 ++++++---- 3 files changed, 57 insertions(+), 6 deletions(-) diff --git a/include/services/ffa_svc.h b/include/services/ffa_svc.h index 728507749..0513eab5e 100644 --- a/include/services/ffa_svc.h +++ b/include/services/ffa_svc.h @@ -138,4 +138,43 @@ */ #define FFA_PARAM_MBZ U(0x0) +/* + * Maximum FF-A endpoint id value + */ +#define FFA_ENDPOINT_ID_MAX U(1 << 16) + +/* + * Mask for source and destination endpoint id in + * a direct message request/response. + */ +#define FFA_DIRECT_MSG_ENDPOINT_ID_MASK U(0xffff) + +/* + * Bit shift for destination endpoint id in a direct message request/response. + */ +#define FFA_DIRECT_MSG_DESTINATION_SHIFT U(0) + +/* + * Bit shift for source endpoint id in a direct message request/response. + */ +#define FFA_DIRECT_MSG_SOURCE_SHIFT U(16) + +/****************************************************************************** + * ffa_endpoint_destination + *****************************************************************************/ +static inline uint16_t ffa_endpoint_destination(unsigned int ep) +{ + return (ep >> FFA_DIRECT_MSG_DESTINATION_SHIFT) & + FFA_DIRECT_MSG_ENDPOINT_ID_MASK; +} + +/****************************************************************************** + * ffa_endpoint_source + *****************************************************************************/ +static inline uint16_t ffa_endpoint_source(unsigned int ep) +{ + return (ep >> FFA_DIRECT_MSG_SOURCE_SHIFT) & + FFA_DIRECT_MSG_ENDPOINT_ID_MASK; +} + #endif /* FFA_SVC_H */ diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c index 93a0203c5..cdbb9ca6e 100644 --- a/services/std_svc/spmd/spmd_main.c +++ b/services/std_svc/spmd/spmd_main.c @@ -322,8 +322,8 @@ static uint64_t spmd_smc_forward(uint32_t smc_fid, uint64_t x4, void *handle) { - uint32_t secure_state_in = (secure_origin) ? SECURE : NON_SECURE; - uint32_t secure_state_out = (!secure_origin) ? SECURE : NON_SECURE; + unsigned int secure_state_in = (secure_origin) ? SECURE : NON_SECURE; + unsigned int secure_state_out = (!secure_origin) ? SECURE : NON_SECURE; /* Save incoming security state */ cm_el1_sysregs_context_save(secure_state_in); @@ -355,6 +355,15 @@ static uint64_t spmd_ffa_error_return(void *handle, int error_code) FFA_PARAM_MBZ, FFA_PARAM_MBZ); } +/****************************************************************************** + * spmd_is_spmc_message + *****************************************************************************/ +static bool spmd_is_spmc_message(unsigned int ep) +{ + return ((ffa_endpoint_destination(ep) == SPMD_DIRECT_MSG_ENDPOINT_ID) + && (ffa_endpoint_source(ep) == spmc_attrs.spmc_id)); +} + /******************************************************************************* * This function handles all SMCs in the range reserved for FFA. Each call is * either forwarded to the other security state or handled by the SPM dispatcher diff --git a/services/std_svc/spmd/spmd_private.h b/services/std_svc/spmd/spmd_private.h index e13a5f021..7d5f47662 100644 --- a/services/std_svc/spmd/spmd_private.h +++ b/services/std_svc/spmd/spmd_private.h @@ -55,11 +55,14 @@ typedef struct spmd_spm_core_context { /* * Reserve ID for NS physical FFA Endpoint. */ -#define FFA_NS_ENDPOINT_ID U(0) +#define FFA_NS_ENDPOINT_ID U(0) -/* Mask and shift to check valid secure FFA Endpoint ID. */ -#define SPMC_SECURE_ID_MASK U(1) -#define SPMC_SECURE_ID_SHIFT U(15) +/* Mask and shift to check valid secure FF-A Endpoint ID. */ +#define SPMC_SECURE_ID_MASK U(1) +#define SPMC_SECURE_ID_SHIFT U(15) + +#define SPMD_DIRECT_MSG_ENDPOINT_ID U(FFA_ENDPOINT_ID_MAX - 1) +#define SPMD_DIRECT_MSG_SET_ENTRY_POINT U(1) /* Functions used to enter/exit SPMC synchronously */ uint64_t spmd_spm_core_sync_entry(spmd_spm_core_context_t *ctx); -- cgit v1.2.3 From f0d743dbcd43c4bc5972210a117c5c6d2a4b6d1b Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Thu, 16 Apr 2020 17:54:27 +0200 Subject: SPMD: handle SPMC message to register secondary core entry point Upon booting, the SPMC running on the primary core shall register the secondary core entry points to which a given secondary core being woken up shall jump to into the SPMC . The current implementation assumes the SPMC calls a registering service implemented in the SPMD for each core identified by its MPIDR. This can typically happen in a simple loop implemented in the early SPMC initialization routines by passing each core identifier associated with an entry point address and context information. This service is implemented on top of a more generic SPMC<=>SPMD interface using direct request/response message passing as defined by the FF-A specification. Signed-off-by: Olivier Deprez Signed-off-by: Max Shvetsov Change-Id: I1f70163b6b5cee0880bd2004e1fec41e3780ba35 --- services/std_svc/spmd/spmd_main.c | 64 ++++++++++++++++++++++++++++++++++-- services/std_svc/spmd/spmd_pm.c | 48 +++++++++++++++++++++++++++ services/std_svc/spmd/spmd_private.h | 4 +++ 3 files changed, 113 insertions(+), 3 deletions(-) diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c index cdbb9ca6e..30509574b 100644 --- a/services/std_svc/spmd/spmd_main.c +++ b/services/std_svc/spmd/spmd_main.c @@ -140,7 +140,7 @@ static int32_t spmd_init(void) ctx->state = SPMC_STATE_ON_PENDING; /* Set the SPMC context state on other CPUs to OFF */ - for (core_id = 0; core_id < PLATFORM_CORE_COUNT; core_id++) { + 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; } @@ -355,6 +355,17 @@ static uint64_t spmd_ffa_error_return(void *handle, int error_code) FFA_PARAM_MBZ, FFA_PARAM_MBZ); } +/******************************************************************************* + * spmd_check_address_in_binary_image + ******************************************************************************/ +bool spmd_check_address_in_binary_image(uint64_t address) +{ + assert(!check_uptr_overflow(spmc_attrs.load_address, spmc_attrs.binary_size)); + + return ((address >= spmc_attrs.load_address) && + (address < (spmc_attrs.load_address + spmc_attrs.binary_size))); +} + /****************************************************************************** * spmd_is_spmc_message *****************************************************************************/ @@ -364,6 +375,26 @@ static bool spmd_is_spmc_message(unsigned int ep) && (ffa_endpoint_source(ep) == spmc_attrs.spmc_id)); } +/****************************************************************************** + * spmd_handle_spmc_message + *****************************************************************************/ +static int32_t spmd_handle_spmc_message(uint64_t msg, uint64_t parm1, + uint64_t parm2, uint64_t parm3, + uint64_t parm4) +{ + VERBOSE("%s %llx %llx %llx %llx %llx\n", __func__, + msg, parm1, parm2, parm3, parm4); + + switch (msg) { + case SPMD_DIRECT_MSG_SET_ENTRY_POINT: + return spmd_pm_secondary_core_set_ep(parm1, parm2, parm3); + default: + break; + } + + return -EINVAL; +} + /******************************************************************************* * This function handles all SMCs in the range reserved for FFA. Each call is * either forwarded to the other security state or handled by the SPM dispatcher @@ -481,6 +512,35 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, break; /* not reached */ + case FFA_MSG_SEND_DIRECT_REQ_SMC32: + if (secure_origin && spmd_is_spmc_message(x1)) { + ret = spmd_handle_spmc_message(x3, x4, + SMC_GET_GP(handle, CTX_GPREG_X5), + SMC_GET_GP(handle, CTX_GPREG_X6), + SMC_GET_GP(handle, CTX_GPREG_X7)); + + SMC_RET8(handle, FFA_SUCCESS_SMC32, + FFA_TARGET_INFO_MBZ, ret, + FFA_PARAM_MBZ, FFA_PARAM_MBZ, + FFA_PARAM_MBZ, FFA_PARAM_MBZ, + FFA_PARAM_MBZ); + } else { + /* Forward direct message to the other world */ + return spmd_smc_forward(smc_fid, secure_origin, + x1, x2, x3, x4, handle); + } + break; /* Not reached */ + + case FFA_MSG_SEND_DIRECT_RESP_SMC32: + if (secure_origin && spmd_is_spmc_message(x1)) { + spmd_spm_core_sync_exit(0); + } else { + /* Forward direct message to the other world */ + return spmd_smc_forward(smc_fid, secure_origin, + x1, x2, x3, x4, handle); + } + break; /* Not reached */ + case FFA_RX_RELEASE: case FFA_RXTX_MAP_SMC32: case FFA_RXTX_MAP_SMC64: @@ -496,9 +556,7 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, case FFA_PARTITION_INFO_GET: case FFA_MSG_SEND: - case FFA_MSG_SEND_DIRECT_REQ_SMC32: case FFA_MSG_SEND_DIRECT_REQ_SMC64: - case FFA_MSG_SEND_DIRECT_RESP_SMC32: case FFA_MSG_SEND_DIRECT_RESP_SMC64: case FFA_MEM_DONATE_SMC32: case FFA_MEM_DONATE_SMC64: diff --git a/services/std_svc/spmd/spmd_pm.c b/services/std_svc/spmd/spmd_pm.c index eff59adb1..13c638c38 100644 --- a/services/std_svc/spmd/spmd_pm.c +++ b/services/std_svc/spmd/spmd_pm.c @@ -5,8 +5,56 @@ */ #include +#include #include "spmd_private.h" +struct spmd_pm_secondary_ep_t { + uintptr_t entry_point; + uintptr_t context; + bool locked; +}; + +static struct spmd_pm_secondary_ep_t spmd_pm_secondary_ep[PLATFORM_CORE_COUNT]; + +/******************************************************************************* + * spmd_pm_secondary_core_set_ep + ******************************************************************************/ +int32_t spmd_pm_secondary_core_set_ep(uint64_t mpidr, uintptr_t entry_point, + uint64_t context) +{ + int id = plat_core_pos_by_mpidr(mpidr); + + if ((id < 0) || (id >= PLATFORM_CORE_COUNT)) { + ERROR("%s inconsistent MPIDR (%llx)\n", __func__, mpidr); + return -EINVAL; + } + + if (spmd_pm_secondary_ep[id].locked) { + ERROR("%s entry locked (%llx)\n", __func__, mpidr); + return -EINVAL; + } + + /* + * Check entry_point address is a PA within + * load_address <= entry_point < load_address + binary_size + */ + if (!spmd_check_address_in_binary_image(entry_point)) { + ERROR("%s entry point is not within image boundaries (%llx)\n", + __func__, mpidr); + return -EINVAL; + } + + /* Fill new entry to corresponding secondary core id and lock it */ + spmd_pm_secondary_ep[id].entry_point = entry_point; + spmd_pm_secondary_ep[id].context = context; + spmd_pm_secondary_ep[id].locked = true; + + VERBOSE("%s %d %llx %lx %llx\n", + __func__, id, mpidr, entry_point, context); + + return 0; +} + /******************************************************************************* * This CPU has been turned on. Enter SPMC to initialise S-EL1 or S-EL2. As part * of the SPMC initialization path, they will initialize any SPs that they diff --git a/services/std_svc/spmd/spmd_private.h b/services/std_svc/spmd/spmd_private.h index 7d5f47662..0d78f53a4 100644 --- a/services/std_svc/spmd/spmd_private.h +++ b/services/std_svc/spmd/spmd_private.h @@ -81,6 +81,10 @@ entry_point_info_t *spmd_spmc_ep_info_get(void); /* SPMC context on current CPU get helper */ spmd_spm_core_context_t *spmd_get_context(void); +int32_t spmd_pm_secondary_core_set_ep(uint64_t mpidr, uintptr_t entry_point, + uint64_t context); +bool spmd_check_address_in_binary_image(uint64_t address); + #endif /* __ASSEMBLER__ */ #endif /* SPMD_PRIVATE_H */ -- cgit v1.2.3 From a92bc73b8e93d24a9813c2a6a6c841b3d5cc836c Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Mon, 23 Mar 2020 09:53:06 +0100 Subject: SPMD: secondary cores PM on and off SPD hooks relayed to SPMC Define SPMD PM hooks for warm boot and off events. svc_on_finish handler enters the SPMC at the entry point defined by the secondary EP register service. The svc_off handler notifies the SPMC that a physical core is being turned off through a notification message. Signed-off-by: Olivier Deprez Change-Id: I2609a75a0c6ffb9f6313fc09553be2b29a41de59 --- services/std_svc/spmd/spmd_main.c | 14 ++++-- services/std_svc/spmd/spmd_pm.c | 83 +++++++++++++++++++++++++++++++++--- services/std_svc/spmd/spmd_private.h | 7 ++- 3 files changed, 94 insertions(+), 10 deletions(-) diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c index 30509574b..edcb5feb9 100644 --- a/services/std_svc/spmd/spmd_main.c +++ b/services/std_svc/spmd/spmd_main.c @@ -59,6 +59,14 @@ entry_point_info_t *spmd_spmc_ep_info_get(void) return spmc_ep_info; } +/******************************************************************************* + * SPM Core ID getter. + ******************************************************************************/ +uint16_t spmd_spmc_id_get(void) +{ + return spmc_attrs.spmc_id; +} + /******************************************************************************* * Static function declaration. ******************************************************************************/ @@ -378,9 +386,9 @@ static bool spmd_is_spmc_message(unsigned int ep) /****************************************************************************** * spmd_handle_spmc_message *****************************************************************************/ -static int32_t spmd_handle_spmc_message(uint64_t msg, uint64_t parm1, - uint64_t parm2, uint64_t parm3, - uint64_t parm4) +static int spmd_handle_spmc_message(unsigned long long msg, + unsigned long long parm1, unsigned long long parm2, + unsigned long long parm3, unsigned long long parm4) { VERBOSE("%s %llx %llx %llx %llx %llx\n", __func__, msg, parm1, parm2, parm3, parm4); diff --git a/services/std_svc/spmd/spmd_pm.c b/services/std_svc/spmd/spmd_pm.c index 13c638c38..390419673 100644 --- a/services/std_svc/spmd/spmd_pm.c +++ b/services/std_svc/spmd/spmd_pm.c @@ -6,6 +6,7 @@ #include #include +#include #include "spmd_private.h" struct spmd_pm_secondary_ep_t { @@ -16,11 +17,26 @@ struct spmd_pm_secondary_ep_t { static struct spmd_pm_secondary_ep_t spmd_pm_secondary_ep[PLATFORM_CORE_COUNT]; +/******************************************************************************* + * spmd_build_spmc_message + * + * Builds an SPMD to SPMC direct message request. + ******************************************************************************/ +static void spmd_build_spmc_message(gp_regs_t *gpregs, unsigned long long message) +{ + write_ctx_reg(gpregs, CTX_GPREG_X0, FFA_MSG_SEND_DIRECT_REQ_SMC32); + write_ctx_reg(gpregs, CTX_GPREG_X1, + (SPMD_DIRECT_MSG_ENDPOINT_ID << FFA_DIRECT_MSG_SOURCE_SHIFT) | + spmd_spmc_id_get()); + write_ctx_reg(gpregs, CTX_GPREG_X2, FFA_PARAM_MBZ); + write_ctx_reg(gpregs, CTX_GPREG_X3, message); +} + /******************************************************************************* * spmd_pm_secondary_core_set_ep ******************************************************************************/ -int32_t spmd_pm_secondary_core_set_ep(uint64_t mpidr, uintptr_t entry_point, - uint64_t context) +int spmd_pm_secondary_core_set_ep(unsigned long long mpidr, + uintptr_t entry_point, unsigned long long context) { int id = plat_core_pos_by_mpidr(mpidr); @@ -63,21 +79,77 @@ int32_t spmd_pm_secondary_core_set_ep(uint64_t mpidr, uintptr_t entry_point, ******************************************************************************/ static void spmd_cpu_on_finish_handler(u_register_t unused) { - unsigned int linear_id = plat_my_core_pos(); + 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(); int rc; + assert(ctx != NULL); assert(ctx->state != SPMC_STATE_ON); + assert(spmc_ep_info != NULL); + + /* + * TODO: this might require locking the spmc_ep_info structure, + * or provisioning one structure per cpu + */ + if (spmd_pm_secondary_ep[linear_id].entry_point == 0) { + goto exit; + } + + spmc_ep_info->pc = spmd_pm_secondary_ep[linear_id].entry_point; + cm_setup_context(&ctx->cpu_ctx, spmc_ep_info); + write_ctx_reg(get_gpregs_ctx(&ctx->cpu_ctx), CTX_GPREG_X0, + spmd_pm_secondary_ep[linear_id].context); + + /* Mark CPU as initiating ON operation */ + ctx->state = SPMC_STATE_ON_PENDING; rc = spmd_spm_core_sync_entry(ctx); if (rc != 0) { - ERROR("SPMC initialisation failed (%d) on CPU%u\n", rc, - linear_id); + ERROR("%s failed failed (%d) on CPU%u\n", __func__, rc, + linear_id); ctx->state = SPMC_STATE_OFF; return; } +exit: ctx->state = SPMC_STATE_ON; + + VERBOSE("CPU %u on!\n", linear_id); +} + +/******************************************************************************* + * spmd_cpu_off_handler + ******************************************************************************/ +static int32_t spmd_cpu_off_handler(u_register_t unused) +{ + spmd_spm_core_context_t *ctx = spmd_get_context(); + unsigned int linear_id = plat_my_core_pos(); + int32_t rc; + + assert(ctx != NULL); + assert(ctx->state != SPMC_STATE_OFF); + + if (spmd_pm_secondary_ep[linear_id].entry_point == 0) { + goto exit; + } + + /* Build an SPMD to SPMC direct message request. */ + spmd_build_spmc_message(get_gpregs_ctx(&ctx->cpu_ctx), PSCI_CPU_OFF); + + rc = spmd_spm_core_sync_entry(ctx); + if (rc != 0) { + ERROR("%s failed (%d) on CPU%u\n", __func__, rc, linear_id); + } + + /* TODO expect FFA_DIRECT_MSG_RESP returned from SPMC */ + +exit: + ctx->state = SPMC_STATE_OFF; + + VERBOSE("CPU %u off!\n", linear_id); + + return 0; } /******************************************************************************* @@ -86,4 +158,5 @@ static void spmd_cpu_on_finish_handler(u_register_t unused) ******************************************************************************/ const spd_pm_ops_t spmd_pm = { .svc_on_finish = spmd_cpu_on_finish_handler, + .svc_off = spmd_cpu_off_handler }; diff --git a/services/std_svc/spmd/spmd_private.h b/services/std_svc/spmd/spmd_private.h index 0d78f53a4..a9dc1d311 100644 --- a/services/std_svc/spmd/spmd_private.h +++ b/services/std_svc/spmd/spmd_private.h @@ -78,11 +78,14 @@ extern const spd_pm_ops_t spmd_pm; /* SPMC entry point information helper */ entry_point_info_t *spmd_spmc_ep_info_get(void); +/* SPMC ID getter */ +uint16_t spmd_spmc_id_get(void); + /* SPMC context on current CPU get helper */ spmd_spm_core_context_t *spmd_get_context(void); -int32_t spmd_pm_secondary_core_set_ep(uint64_t mpidr, uintptr_t entry_point, - uint64_t context); +int spmd_pm_secondary_core_set_ep(unsigned long long mpidr, + uintptr_t entry_point, unsigned long long context); bool spmd_check_address_in_binary_image(uint64_t address); #endif /* __ASSEMBLER__ */ -- cgit v1.2.3 From 2111b0024cfe10697b0919f1c0042b6cfded5c88 Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Fri, 12 Jun 2020 18:10:28 +0200 Subject: SPMC: manifest changes to support multicore boot Signed-off-by: Olivier Deprez Signed-off-by: Max Shvetsov Change-Id: Icf90c2ccce75257908ba3d4703926041d64b1dd3 --- include/services/spm_core_manifest.h | 2 +- plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts | 34 ++++++++++++++------------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/include/services/spm_core_manifest.h b/include/services/spm_core_manifest.h index 64ecce005..453b21c0b 100644 --- a/include/services/spm_core_manifest.h +++ b/include/services/spm_core_manifest.h @@ -44,7 +44,7 @@ typedef struct spm_core_manifest_sect_attribute { uint32_t binary_size; /* - * ID of the SPMD (mandatory) + * ID of the SPMC (mandatory) */ uint16_t spmc_id; diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts index 90fb3474c..ca42da0bc 100644 --- a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts +++ b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts @@ -5,6 +5,14 @@ */ /dts-v1/; +#define AFF 00 + +#include "fvp-defs.dtsi" +#undef POST +#define POST \ + enable-method = "psci"; \ + }; + / { compatible = "arm,ffa-core-manifest-1.0"; #address-cells = <2>; @@ -17,6 +25,7 @@ exec_state = <0x0>; load_address = <0x0 0x6000000>; entrypoint = <0x0 0x6000000>; + binary_size = <0x80000>; }; chosen { @@ -51,22 +60,15 @@ #address-cells = <0x2>; #size-cells = <0x0>; - cpu-map { - cluster0 { - core0 { - cpu = <0x2>; - }; - }; - }; - - cpu@0 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x0>; - enable-method = "psci"; - next-level-cache = <0xc>; - phandle = <0x2>; - }; + CPU_0 + /* SPM(Hafnium) requires secondary cpu nodes are declared in descending order */ + CPU_7 + CPU_6 + CPU_5 + CPU_4 + CPU_3 + CPU_2 + CPU_1 }; memory@60000000 { -- cgit v1.2.3 From 02d50bb018181d942e6278984e8bca950a49b1d6 Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Fri, 19 Jun 2020 15:33:41 +0200 Subject: SPMC: embed secondary core ep info into to SPMC context Signed-off-by: Olivier Deprez Signed-off-by: Max Shvetsov Change-Id: Icdb15b8664fb3467ffd55b44d1f0660457192586 --- services/std_svc/spmd/spmd_main.c | 13 +++++++--- services/std_svc/spmd/spmd_pm.c | 46 ++++++++++++++++-------------------- services/std_svc/spmd/spmd_private.h | 10 ++++++++ 3 files changed, 40 insertions(+), 29 deletions(-) diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c index edcb5feb9..6ed2098c1 100644 --- a/services/std_svc/spmd/spmd_main.c +++ b/services/std_svc/spmd/spmd_main.c @@ -41,14 +41,20 @@ static spmc_manifest_attribute_t spmc_attrs; ******************************************************************************/ static entry_point_info_t *spmc_ep_info; +/******************************************************************************* + * SPM Core context on CPU based on mpidr. + ******************************************************************************/ +spmd_spm_core_context_t *spmd_get_context_by_mpidr(uint64_t mpidr) +{ + return &spm_core_context[plat_core_pos_by_mpidr(mpidr)]; +} + /******************************************************************************* * SPM Core context on current CPU get helper. ******************************************************************************/ spmd_spm_core_context_t *spmd_get_context(void) { - unsigned int linear_id = plat_my_core_pos(); - - return &spm_core_context[linear_id]; + return spmd_get_context_by_mpidr(read_mpidr()); } /******************************************************************************* @@ -151,6 +157,7 @@ static int32_t spmd_init(void) 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; + spm_core_context[core_id].secondary_ep.entry_point = 0UL; } } diff --git a/services/std_svc/spmd/spmd_pm.c b/services/std_svc/spmd/spmd_pm.c index 390419673..64ddbe5f4 100644 --- a/services/std_svc/spmd/spmd_pm.c +++ b/services/std_svc/spmd/spmd_pm.c @@ -9,14 +9,6 @@ #include #include "spmd_private.h" -struct spmd_pm_secondary_ep_t { - uintptr_t entry_point; - uintptr_t context; - bool locked; -}; - -static struct spmd_pm_secondary_ep_t spmd_pm_secondary_ep[PLATFORM_CORE_COUNT]; - /******************************************************************************* * spmd_build_spmc_message * @@ -45,11 +37,6 @@ int spmd_pm_secondary_core_set_ep(unsigned long long mpidr, return -EINVAL; } - if (spmd_pm_secondary_ep[id].locked) { - ERROR("%s entry locked (%llx)\n", __func__, mpidr); - return -EINVAL; - } - /* * Check entry_point address is a PA within * load_address <= entry_point < load_address + binary_size @@ -60,10 +47,17 @@ int spmd_pm_secondary_core_set_ep(unsigned long long mpidr, return -EINVAL; } + spmd_spm_core_context_t *ctx = spmd_get_context_by_mpidr(mpidr); + spmd_pm_secondary_ep_t *secondary_ep = &ctx->secondary_ep; + if (secondary_ep->locked) { + ERROR("%s entry locked (%llx)\n", __func__, mpidr); + return -EINVAL; + } + /* Fill new entry to corresponding secondary core id and lock it */ - spmd_pm_secondary_ep[id].entry_point = entry_point; - spmd_pm_secondary_ep[id].context = context; - spmd_pm_secondary_ep[id].locked = true; + secondary_ep->entry_point = entry_point; + secondary_ep->context = context; + secondary_ep->locked = true; VERBOSE("%s %d %llx %lx %llx\n", __func__, id, mpidr, entry_point, context); @@ -82,7 +76,7 @@ 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(); - int rc; + uint64_t rc; assert(ctx != NULL); assert(ctx->state != SPMC_STATE_ON); @@ -92,21 +86,21 @@ static void spmd_cpu_on_finish_handler(u_register_t unused) * TODO: this might require locking the spmc_ep_info structure, * or provisioning one structure per cpu */ - if (spmd_pm_secondary_ep[linear_id].entry_point == 0) { + if (ctx->secondary_ep.entry_point == 0UL) { goto exit; } - spmc_ep_info->pc = spmd_pm_secondary_ep[linear_id].entry_point; + spmc_ep_info->pc = ctx->secondary_ep.entry_point; cm_setup_context(&ctx->cpu_ctx, spmc_ep_info); write_ctx_reg(get_gpregs_ctx(&ctx->cpu_ctx), CTX_GPREG_X0, - spmd_pm_secondary_ep[linear_id].context); + ctx->secondary_ep.context); /* Mark CPU as initiating ON operation */ ctx->state = SPMC_STATE_ON_PENDING; rc = spmd_spm_core_sync_entry(ctx); - if (rc != 0) { - ERROR("%s failed failed (%d) on CPU%u\n", __func__, rc, + if (rc != 0ULL) { + ERROR("%s failed (%llu) on CPU%u\n", __func__, rc, linear_id); ctx->state = SPMC_STATE_OFF; return; @@ -125,12 +119,12 @@ static int32_t spmd_cpu_off_handler(u_register_t unused) { spmd_spm_core_context_t *ctx = spmd_get_context(); unsigned int linear_id = plat_my_core_pos(); - int32_t rc; + int64_t rc; assert(ctx != NULL); assert(ctx->state != SPMC_STATE_OFF); - if (spmd_pm_secondary_ep[linear_id].entry_point == 0) { + if (ctx->secondary_ep.entry_point == 0UL) { goto exit; } @@ -138,8 +132,8 @@ static int32_t spmd_cpu_off_handler(u_register_t unused) spmd_build_spmc_message(get_gpregs_ctx(&ctx->cpu_ctx), PSCI_CPU_OFF); rc = spmd_spm_core_sync_entry(ctx); - if (rc != 0) { - ERROR("%s failed (%d) on CPU%u\n", __func__, rc, linear_id); + if (rc != 0ULL) { + ERROR("%s failed (%llu) on CPU%u\n", __func__, rc, linear_id); } /* TODO expect FFA_DIRECT_MSG_RESP returned from SPMC */ diff --git a/services/std_svc/spmd/spmd_private.h b/services/std_svc/spmd/spmd_private.h index a9dc1d311..eff0dd9f2 100644 --- a/services/std_svc/spmd/spmd_private.h +++ b/services/std_svc/spmd/spmd_private.h @@ -42,6 +42,12 @@ typedef enum spmc_state { SPMC_STATE_ON } spmc_state_t; +typedef struct spmd_pm_secondary_ep { + uintptr_t entry_point; + uintptr_t context; + bool locked; +} spmd_pm_secondary_ep_t; + /* * Data structure used by the SPM dispatcher (SPMD) in EL3 to track context of * the SPM core (SPMC) at the next lower EL. @@ -50,6 +56,7 @@ typedef struct spmd_spm_core_context { uint64_t c_rt_ctx; cpu_context_t cpu_ctx; spmc_state_t state; + spmd_pm_secondary_ep_t secondary_ep; } spmd_spm_core_context_t; /* @@ -81,6 +88,9 @@ entry_point_info_t *spmd_spmc_ep_info_get(void); /* SPMC ID getter */ uint16_t spmd_spmc_id_get(void); +/* SPMC context on CPU based on mpidr */ +spmd_spm_core_context_t *spmd_get_context_by_mpidr(uint64_t mpidr); + /* SPMC context on current CPU get helper */ spmd_spm_core_context_t *spmd_get_context(void); -- cgit v1.2.3 From 545b8eb33e5ba0aa286278560a288353a18b9e5b Mon Sep 17 00:00:00 2001 From: Ruari Phipps Date: Tue, 28 Jul 2020 10:33:35 +0100 Subject: SPMD: Dont forward PARTITION_INFO_GET from secure FF-A instance Signed-off-by: Ruari Phipps Change-Id: I4e9fbfcfda4ed4b87d5ece1c609c57c73d617d4c --- services/std_svc/spmd/spmd_main.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c index 6ed2098c1..6f0d9b1dc 100644 --- a/services/std_svc/spmd/spmd_main.c +++ b/services/std_svc/spmd/spmd_main.c @@ -560,16 +560,22 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, case FFA_RXTX_MAP_SMC32: case FFA_RXTX_MAP_SMC64: case FFA_RXTX_UNMAP: + case FFA_PARTITION_INFO_GET: + /* + * Should not be allowed to forward FFA_PARTITION_INFO_GET + * from Secure world to Normal world + * + * Fall through to forward the call to the other world + */ case FFA_MSG_RUN: /* This interface must be invoked only by the Normal world */ + if (secure_origin) { return spmd_ffa_error_return(handle, - FFA_ERROR_NOT_SUPPORTED); + FFA_ERROR_NOT_SUPPORTED); } /* Fall through to forward the call to the other world */ - - case FFA_PARTITION_INFO_GET: case FFA_MSG_SEND: case FFA_MSG_SEND_DIRECT_REQ_SMC64: case FFA_MSG_SEND_DIRECT_RESP_SMC64: -- cgit v1.2.3 From f5402ef7a86dce7e7b5b05704d113e69d3387105 Mon Sep 17 00:00:00 2001 From: Mark Dykes Date: Wed, 19 Aug 2020 19:11:33 +0000 Subject: Revert "libc/memset: Implement function in assembler" This reverts commit e7d344de01ad11b856233634717aafe9312697e4. This reverts the patch https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/5313 due to a timing issue with the merge. The merge occurred at the same time as the additional comments and thusly were were not seen until the merge was done. This reverts the change and additional patches from Alexei will follow to address the concerns expressed in the orignal patch. Change-Id: Iae5f6403c93ac13ceeda29463883fcd4c437f2b7 --- lib/libc/aarch32/memset.S | 74 ---------------------------------------- lib/libc/aarch64/memset.S | 79 ------------------------------------------- lib/libc/libc.mk | 9 ++--- lib/libc/memset.c | 18 ++++++++++ plat/nvidia/tegra/platform.mk | 4 +-- 5 files changed, 22 insertions(+), 162 deletions(-) delete mode 100644 lib/libc/aarch32/memset.S delete mode 100644 lib/libc/aarch64/memset.S create mode 100644 lib/libc/memset.c diff --git a/lib/libc/aarch32/memset.S b/lib/libc/aarch32/memset.S deleted file mode 100644 index 0b69897fd..000000000 --- a/lib/libc/aarch32/memset.S +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2020, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - - .syntax unified - .global memset - -/* ----------------------------------------------------------------------- - * void memset(void *dst, int val, size_t count) - * - * Copy the value of 'val' (converted to an unsigned char) into - * each of the first 'count' characters of the object pointed to by 'dst'. - * - * Returns the value of 'dst'. - * ----------------------------------------------------------------------- - */ -func memset - cmp r2, #0 - bxeq lr /* return if 'count' = 0 */ - mov r12, r0 /* keep r0 */ - tst r0, #3 - beq aligned /* 4-bytes aligned */ - - /* Unaligned 'dst' */ -unaligned: - strb r1, [r12], #1 - subs r2, r2, #1 - bxeq lr /* return if 0 */ - tst r12, #3 - bne unaligned /* continue while unaligned */ - - /* 4-bytes aligned */ -aligned:bfi r1, r1, #8, #8 /* propagate 'val' */ - bfi r1, r1, #16, #16 - - mov r3, r1 - - cmp r2, #16 - blo less_16 - - push {r4, lr} - mov r4, r1 - mov lr, r1 - - cmp r2, #32 - blo less_32 - -write_32: - stmia r12!, {r1, r3, r4, lr} /* write 32 bytes in a loop */ - stmia r12!, {r1, r3, r4, lr} - subs r2, r2, #32 - popeq {r4, pc} /* return if 0 */ - cmp r2, #32 - bhs write_32 - -less_32:cmp r2, #16 - stmiahs r12!, {r1, r3, r4, lr} /* write 16 bytes */ - popeq {r4, pc} /* return if 16 */ - pop {r4, lr} - -less_16:lsls r2, r2, #29 /* C = r2[3]; N = r2[2]; Z = r2[2:0] */ - stmiacs r12!, {r1, r3} /* write 8 bytes */ - bxeq lr /* return if 8 */ - strmi r1, [r12], #4 /* write 4 bytes */ - lsls r2, r2, #1 /* N = r2[1]; Z = r2[0] */ - strhmi r1, [r12], #2 /* write 2 bytes */ - strbne r1, [r12] /* write 1 byte */ - bx lr - -endfunc memset diff --git a/lib/libc/aarch64/memset.S b/lib/libc/aarch64/memset.S deleted file mode 100644 index 8c65760ce..000000000 --- a/lib/libc/aarch64/memset.S +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2020, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - - .global memset - -/* ----------------------------------------------------------------------- - * void memset(void *dst, int val, size_t count) - * - * Copy the value of 'val' (converted to an unsigned char) into - * each of the first 'count' characters of the object pointed to by 'dst'. - * - * Returns the value of 'dst'. - * ----------------------------------------------------------------------- - */ -func memset - cbz w2, exit /* exit if 'count' = 0 */ - mov x3, x0 /* keep x0 */ - tst x0, #7 - b.eq aligned /* 8-bytes aligned */ - - /* Unaligned 'dst' */ -unaligned: - strb w1, [x3], #1 - subs w2, w2, #1 - b.eq exit /* exit if 0 */ - tst x3, #7 - b.ne unaligned /* continue while unaligned */ - - /* 8-bytes aligned */ -aligned:cbz x1, x1_zero - bfi w1, w1, #8, #8 /* propagate 'val' */ - bfi w1, w1, #16, #16 - bfi x1, x1, #32, #32 - -x1_zero:ands w4, w2, #~0x3f - b.eq less_64 - -write_64: - .rept 4 - stp x1, x1, [x3], #16 /* write 64 bytes in a loop */ - .endr - subs w4, w4, #64 - b.ne write_64 - ands w2, w2, #0x3f - b.eq exit /* exit if 0 */ - -less_64:tbz w2, #5, less_32 /* < 32 bytes */ - stp x1, x1, [x3], #16 /* write 32 bytes */ - stp x1, x1, [x3], #16 - ands w2, w2, #0x1f - b.eq exit - -less_32:tbz w2, #4, less_16 /* < 16 bytes */ - stp x1, x1, [x3], #16 /* write 16 bytes */ - ands w2, w2, #0xf - b.eq exit - -less_16:tbz w2, #3, less_8 /* < 8 bytes */ - str x1, [x3], #8 /* write 8 bytes */ - ands w2, w2, #7 - b.eq exit - -less_8: tbz w2, #2, less_4 /* < 4 bytes */ - str w1, [x3], #4 /* write 4 bytes */ - ands w2, w2, #3 - b.eq exit - -less_4: tbz w2, #1, less_2 /* < 2 bytes */ - strh w1, [x3], #2 /* write 2 bytes */ - tbz w2, #0, exit -less_2: strb w1, [x3] /* write 1 byte */ -exit: ret - -endfunc memset diff --git a/lib/libc/libc.mk b/lib/libc/libc.mk index 90a2a1e16..93d30d035 100644 --- a/lib/libc/libc.mk +++ b/lib/libc/libc.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -13,6 +13,7 @@ LIBC_SRCS := $(addprefix lib/libc/, \ memcpy.c \ memmove.c \ memrchr.c \ + memset.c \ printf.c \ putchar.c \ puts.c \ @@ -27,14 +28,8 @@ LIBC_SRCS := $(addprefix lib/libc/, \ ifeq (${ARCH},aarch64) LIBC_SRCS += $(addprefix lib/libc/aarch64/, \ - memset.S \ setjmp.S) endif -ifeq (${ARCH},aarch32) -LIBC_SRCS += $(addprefix lib/libc/aarch32/, \ - memset.S) -endif - INCLUDES += -Iinclude/lib/libc \ -Iinclude/lib/libc/$(ARCH) \ diff --git a/lib/libc/memset.c b/lib/libc/memset.c new file mode 100644 index 000000000..d8007d8e9 --- /dev/null +++ b/lib/libc/memset.c @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +void *memset(void *dst, int val, size_t count) +{ + char *ptr = dst; + + while (count--) + *ptr++ = val; + + return dst; +} diff --git a/plat/nvidia/tegra/platform.mk b/plat/nvidia/tegra/platform.mk index 5cac46f64..a4724e64b 100644 --- a/plat/nvidia/tegra/platform.mk +++ b/plat/nvidia/tegra/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. # Copyright (c) 2020, NVIDIA Corporation. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause @@ -69,11 +69,11 @@ TF_CFLAGS += -Wsign-compare -nostdlib # override with necessary libc files for the Tegra platform override LIBC_SRCS := $(addprefix lib/libc/, \ - aarch64/memset.S \ aarch64/setjmp.S \ assert.c \ memcpy.c \ memmove.c \ + memset.c \ printf.c \ putchar.c \ strlen.c \ -- cgit v1.2.3 From fafd3ec9c954cbc5430dc24bdf5c46b97034c832 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Thu, 13 Aug 2020 05:56:33 +0100 Subject: tools: Get the tool's binary name from the main makefile Currently, the tool's makefile override the tool's binary name which is already been defined in the main makefile. Hence fix is provided so that the tool's makefile get the tool's binary name from the main makefile instead of overriding it. Change-Id: I8af2bd391a96bba2dbcddef711338a94ebf5f038 Signed-off-by: Manish V Badarkhe --- Makefile | 8 ++++---- tools/cert_create/Makefile | 3 +-- tools/encrypt_fw/Makefile | 5 ++--- tools/fiptool/Makefile | 4 ++-- tools/sptool/Makefile | 4 ++-- 5 files changed, 11 insertions(+), 13 deletions(-) diff --git a/Makefile b/Makefile index 61593c191..af829f2bd 100644 --- a/Makefile +++ b/Makefile @@ -1209,7 +1209,7 @@ certtool: ${CRTTOOL} .PHONY: ${CRTTOOL} ${CRTTOOL}: - ${Q}${MAKE} PLAT=${PLAT} USE_TBBR_DEFS=${USE_TBBR_DEFS} COT=${COT} OPENSSL_DIR=${OPENSSL_DIR} --no-print-directory -C ${CRTTOOLPATH} + ${Q}${MAKE} PLAT=${PLAT} USE_TBBR_DEFS=${USE_TBBR_DEFS} COT=${COT} OPENSSL_DIR=${OPENSSL_DIR} CRTTOOL=${CRTTOOL} --no-print-directory -C ${CRTTOOLPATH} @${ECHO_BLANK_LINE} @echo "Built $@ successfully" @${ECHO_BLANK_LINE} @@ -1252,12 +1252,12 @@ fwu_fip: ${BUILD_PLAT}/${FWU_FIP_NAME} .PHONY: ${FIPTOOL} ${FIPTOOL}: - ${Q}${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" --no-print-directory -C ${FIPTOOLPATH} + ${Q}${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" FIPTOOL=${FIPTOOL} --no-print-directory -C ${FIPTOOLPATH} sptool: ${SPTOOL} .PHONY: ${SPTOOL} ${SPTOOL}: - ${Q}${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" --no-print-directory -C ${SPTOOLPATH} + ${Q}${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" SPTOOL=${SPTOOL} --no-print-directory -C ${SPTOOLPATH} .PHONY: libraries romlib.bin: libraries @@ -1275,7 +1275,7 @@ enctool: ${ENCTOOL} .PHONY: ${ENCTOOL} ${ENCTOOL}: - ${Q}${MAKE} PLAT=${PLAT} BUILD_INFO=0 OPENSSL_DIR=${OPENSSL_DIR} --no-print-directory -C ${ENCTOOLPATH} + ${Q}${MAKE} PLAT=${PLAT} BUILD_INFO=0 OPENSSL_DIR=${OPENSSL_DIR} ENCTOOL=${ENCTOOL} --no-print-directory -C ${ENCTOOLPATH} @${ECHO_BLANK_LINE} @echo "Built $@ successfully" @${ECHO_BLANK_LINE} diff --git a/tools/cert_create/Makefile b/tools/cert_create/Makefile index 19f736f07..418e06cf3 100644 --- a/tools/cert_create/Makefile +++ b/tools/cert_create/Makefile @@ -4,11 +4,10 @@ # SPDX-License-Identifier: BSD-3-Clause # -PROJECT := cert_create PLAT := none V ?= 0 DEBUG := 0 -BINARY := ${PROJECT}${BIN_EXT} +BINARY := $(notdir ${CRTTOOL}) OPENSSL_DIR := /usr COT := tbbr diff --git a/tools/encrypt_fw/Makefile b/tools/encrypt_fw/Makefile index cb81d0b2e..ebbc66a8e 100644 --- a/tools/encrypt_fw/Makefile +++ b/tools/encrypt_fw/Makefile @@ -1,14 +1,13 @@ # -# Copyright (c) 2019, Linaro Limited. All rights reserved. +# Copyright (c) 2019-2020, Linaro Limited. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # -PROJECT := encrypt_fw V ?= 0 BUILD_INFO ?= 1 DEBUG := 0 -BINARY := ${PROJECT}${BIN_EXT} +BINARY := $(notdir ${ENCTOOL}) OPENSSL_DIR := /usr OBJECTS := src/encrypt.o \ diff --git a/tools/fiptool/Makefile b/tools/fiptool/Makefile index ef3501432..0ede6cebb 100644 --- a/tools/fiptool/Makefile +++ b/tools/fiptool/Makefile @@ -1,5 +1,5 @@ # -# Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -8,7 +8,7 @@ MAKE_HELPERS_DIRECTORY := ../../make_helpers/ include ${MAKE_HELPERS_DIRECTORY}build_macros.mk include ${MAKE_HELPERS_DIRECTORY}build_env.mk -PROJECT := fiptool${BIN_EXT} +PROJECT := $(notdir ${FIPTOOL}) OBJECTS := fiptool.o tbbr_config.o V ?= 0 diff --git a/tools/sptool/Makefile b/tools/sptool/Makefile index 9325207c4..f724c265a 100644 --- a/tools/sptool/Makefile +++ b/tools/sptool/Makefile @@ -1,5 +1,5 @@ # -# Copyright (c) 2018, Arm Limited. All rights reserved. +# Copyright (c) 2018-2020, Arm Limited. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -8,7 +8,7 @@ MAKE_HELPERS_DIRECTORY := ../../make_helpers/ include ${MAKE_HELPERS_DIRECTORY}build_macros.mk include ${MAKE_HELPERS_DIRECTORY}build_env.mk -PROJECT := sptool${BIN_EXT} +PROJECT := $(notdir ${SPTOOL}) OBJECTS := sptool.o V ?= 0 -- cgit v1.2.3 From 0df3eb70ffc4c274ec7a339de84dbdd341e46375 Mon Sep 17 00:00:00 2001 From: Sayanta Pattanayak Date: Fri, 31 Jul 2020 12:59:24 +0530 Subject: n1sdp: remote chip SPI numbering for multichip GIC routing Allocated 512-959 SPI numbers for remote n1sdp chip and same has been referenced for GIC routing table. Change-Id: Id79ea493fd665ed93fe9644a59e363ec10441098 Signed-off-by: Sayanta Pattanayak --- plat/arm/board/n1sdp/n1sdp_bl31_setup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c index 136287a8d..d7003e951 100644 --- a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c +++ b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c @@ -63,8 +63,8 @@ static struct gic600_multichip_data n1sdp_multichip_data __init = { PLAT_ARM_GICD_BASE >> 16 }, .spi_ids = { - {32, 255}, - {0, 0} + {32, 479}, + {512, 959} } }; -- cgit v1.2.3 From fbcd053cb456c8f72baffff38093f58721ae65eb Mon Sep 17 00:00:00 2001 From: kalyanic Date: Fri, 13 Sep 2019 14:49:39 -0700 Subject: Tegra: verify platform compatibility This patch verifies that the binary image is compatible with chip ID of the platform. Change-Id: I28db221b4442aa8827a092faadf32f110d7c5cb4 Signed-off-by: kalyanic --- plat/nvidia/tegra/soc/t132/plat_setup.c | 4 +++- plat/nvidia/tegra/soc/t186/plat_setup.c | 3 +++ plat/nvidia/tegra/soc/t194/plat_setup.c | 3 +++ plat/nvidia/tegra/soc/t210/plat_setup.c | 3 +++ 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/plat/nvidia/tegra/soc/t132/plat_setup.c b/plat/nvidia/tegra/soc/t132/plat_setup.c index 43acdd642..f7b134d15 100644 --- a/plat/nvidia/tegra/soc/t132/plat_setup.c +++ b/plat/nvidia/tegra/soc/t132/plat_setup.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -144,7 +145,8 @@ plat_params_from_bl2_t *plat_get_bl31_plat_params(void) ******************************************************************************/ void plat_early_platform_setup(void) { - ; /* do nothing */ + /* Verify chip id is t132 */ + assert(tegra_chipid_is_t132()); } /******************************************************************************* diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c index c216b5d51..03182d789 100644 --- a/plat/nvidia/tegra/soc/t186/plat_setup.c +++ b/plat/nvidia/tegra/soc/t186/plat_setup.c @@ -186,6 +186,9 @@ void plat_early_platform_setup(void) uint64_t impl, val; const plat_params_from_bl2_t *plat_params = bl31_get_plat_params(); + /* Verify chip id is t186 */ + assert(tegra_chipid_is_t186()); + /* sanity check MCE firmware compatibility */ mce_verify_firmware_version(); diff --git a/plat/nvidia/tegra/soc/t194/plat_setup.c b/plat/nvidia/tegra/soc/t194/plat_setup.c index 399aebb05..09611787b 100644 --- a/plat/nvidia/tegra/soc/t194/plat_setup.c +++ b/plat/nvidia/tegra/soc/t194/plat_setup.c @@ -205,6 +205,9 @@ void plat_early_platform_setup(void) uint8_t enable_ccplex_lock_step = params_from_bl2->enable_ccplex_lock_step; uint64_t actlr_elx; + /* Verify chip id is t194 */ + assert(tegra_chipid_is_t194()); + /* sanity check MCE firmware compatibility */ mce_verify_firmware_version(); diff --git a/plat/nvidia/tegra/soc/t210/plat_setup.c b/plat/nvidia/tegra/soc/t210/plat_setup.c index f2b267b21..a16f302a6 100644 --- a/plat/nvidia/tegra/soc/t210/plat_setup.c +++ b/plat/nvidia/tegra/soc/t210/plat_setup.c @@ -165,6 +165,9 @@ void plat_early_platform_setup(void) const plat_params_from_bl2_t *plat_params = bl31_get_plat_params(); uint64_t val; + /* Verify chip id is t210 */ + assert(tegra_chipid_is_t210()); + /* platform parameter passed by the previous bootloader */ if (plat_params->l2_ecc_parity_prot_dis != 1) { /* Enable ECC Parity Protection for Cortex-A57 CPUs */ -- cgit v1.2.3 From 64b2a237aaf06a472506d70fe9ccf809f8ac1b49 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Fri, 13 Sep 2019 16:31:09 -0700 Subject: Tegra: spe: do not flush console in console_putc SPE no longer requires the flush bit to be set to start transmitting characters over the physical uart. Therefore, the flush bit is no longer required when calling console_core_putc. However, flushing the console still requires the flush bit. This patch removes the flush bit from the mailbox messages in console_core_putc to improve ACK latency. Original change by: Mustafa Bilgen Change-Id: I5b7d1f3ea69ea2ce308566dbaae222b04e4c373d Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/drivers/spe/shared_console.S | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/plat/nvidia/tegra/drivers/spe/shared_console.S b/plat/nvidia/tegra/drivers/spe/shared_console.S index 6df73ec24..9196c1cd1 100644 --- a/plat/nvidia/tegra/drivers/spe/shared_console.S +++ b/plat/nvidia/tegra/drivers/spe/shared_console.S @@ -11,8 +11,7 @@ #define CONSOLE_FLUSH_DATA_TO_PORT (1 << 26) #define CONSOLE_RING_DOORBELL (1 << 31) #define CONSOLE_IS_BUSY (1 << 31) -#define CONSOLE_TIMEOUT 0xC000 /* approx. 50 ms */ -#define CONSOLE_WRITE (CONSOLE_RING_DOORBELL | CONSOLE_FLUSH_DATA_TO_PORT) +#define CONSOLE_TIMEOUT 0xC000 /* 50 ms */ /* * This file contains a driver implementation to make use of the @@ -101,7 +100,7 @@ func console_spe_core_putc /* spe is ready */ mov w2, #0xD /* '\r' */ and w2, w2, #0xFF - mov w3, #(CONSOLE_WRITE | (1 << CONSOLE_NUM_BYTES_SHIFT)) + mov w3, #(CONSOLE_RING_DOORBELL | (1 << CONSOLE_NUM_BYTES_SHIFT)) orr w2, w2, w3 str w2, [x1] @@ -111,7 +110,7 @@ not_eol: /* spe is ready */ mov w2, w0 and w2, w2, #0xFF - mov w3, #(CONSOLE_WRITE | (1 << CONSOLE_NUM_BYTES_SHIFT)) + mov w3, #(CONSOLE_RING_DOORBELL | (1 << CONSOLE_NUM_BYTES_SHIFT)) orr w2, w2, w3 str w2, [x1] @@ -164,7 +163,7 @@ func console_spe_core_flush cbz x0, flush_error /* flush console */ - mov w1, #CONSOLE_WRITE + mov w1, #(CONSOLE_RING_DOORBELL | CONSOLE_FLUSH_DATA_TO_PORT) str w1, [x0] mov w0, #0 ret -- cgit v1.2.3 From 601e3ed209eb508c9e46a5ef18a562613338dcc8 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Tue, 1 Oct 2019 09:34:10 -0700 Subject: lib: cpus: sanity check pointers before use The cpu_ops structure contains a lot of function pointers. It is a good idea to verify that the function pointer is not NULL before executing it. This patch sanity checks each pointer before use to prevent any unforeseen crashes. These checks have been enabled for debug builds only. Change-Id: Ib208331c20e60f0c7c582a20eb3d8cc40fb99d21 Signed-off-by: Varun Wadekar --- lib/cpus/aarch64/cpu_helpers.S | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/lib/cpus/aarch64/cpu_helpers.S b/lib/cpus/aarch64/cpu_helpers.S index 808c7f807..da663be0e 100644 --- a/lib/cpus/aarch64/cpu_helpers.S +++ b/lib/cpus/aarch64/cpu_helpers.S @@ -78,6 +78,10 @@ func prepare_cpu_pwr_dwn mov x1, #CPU_PWR_DWN_OPS add x1, x1, x2, lsl #3 ldr x1, [x0, x1] +#if ENABLE_ASSERTIONS + cmp x1, #0 + ASM_ASSERT(ne) +#endif br x1 endfunc prepare_cpu_pwr_dwn @@ -171,6 +175,10 @@ func get_cpu_ops_ptr /* Subtract the increment and offset to get the cpu-ops pointer */ sub x0, x4, #(CPU_OPS_SIZE + CPU_MIDR) +#if ENABLE_ASSERTIONS + cmp x0, #0 + ASM_ASSERT(ne) +#endif error_exit: ret endfunc get_cpu_ops_ptr @@ -276,7 +284,15 @@ func print_errata_status * turn. */ mrs x0, tpidr_el3 +#if ENABLE_ASSERTIONS + cmp x0, #0 + ASM_ASSERT(ne) +#endif ldr x1, [x0, #CPU_DATA_CPU_OPS_PTR] +#if ENABLE_ASSERTIONS + cmp x1, #0 + ASM_ASSERT(ne) +#endif ldr x0, [x1, #CPU_ERRATA_FUNC] cbz x0, .Lnoprint @@ -326,6 +342,10 @@ func check_wa_cve_2017_5715 ASM_ASSERT(ne) #endif ldr x0, [x0, #CPU_DATA_CPU_OPS_PTR] +#if ENABLE_ASSERTIONS + cmp x0, #0 + ASM_ASSERT(ne) +#endif ldr x0, [x0, #CPU_EXTRA1_FUNC] /* * If the reserved function pointer is NULL, this CPU @@ -359,6 +379,10 @@ func wa_cve_2018_3639_get_disable_ptr ASM_ASSERT(ne) #endif ldr x0, [x0, #CPU_DATA_CPU_OPS_PTR] +#if ENABLE_ASSERTIONS + cmp x0, #0 + ASM_ASSERT(ne) +#endif ldr x0, [x0, #CPU_EXTRA2_FUNC] ret endfunc wa_cve_2018_3639_get_disable_ptr -- cgit v1.2.3 From 7cd336ab9f43eecbba7765afa18d1ca7e26ce8b3 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Fri, 4 Oct 2019 11:40:56 -0700 Subject: Tegra: print GICC registers conditionally The GICC interface exists only on the interrupt controllers following the GICv2 specification. This patch prints the GICC register contents from the platform's macro, plat_crash_print_regs' only when TEGRA_GICC_BASE is defined. This allows platforms using future versions of the GIC specification to still use this macro. Change-Id: Ia5762d0a1ae28c832664d69362a7776e46a22ad1 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/include/plat_macros.S | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plat/nvidia/tegra/include/plat_macros.S b/plat/nvidia/tegra/include/plat_macros.S index 4f01e3306..2dc3b4152 100644 --- a/plat/nvidia/tegra/include/plat_macros.S +++ b/plat/nvidia/tegra/include/plat_macros.S @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -27,6 +28,7 @@ spacer: * --------------------------------------------- */ .macro plat_crash_print_regs +#ifdef TEGRA_GICC_BASE mov_imm x16, TEGRA_GICC_BASE /* gicc base address is now in x16 */ @@ -37,7 +39,7 @@ spacer: ldr w10, [x16, #GICC_CTLR] /* Store to the crash buf and print to cosole */ bl str_in_crash_buf_print - +#endif /* Print the GICD_ISPENDR regs */ mov_imm x16, TEGRA_GICD_BASE add x7, x16, #GICD_ISPENDR -- cgit v1.2.3 From f41dc86c1eeaa835e85ed576aae6fef056b0861b Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Wed, 16 Oct 2019 10:43:33 -0700 Subject: Tegra: remove "platform_get_core_pos" function This patch removes the deprecated 'plat_core_pos_by_mpidr' function from the Tegra platform port. Change-Id: I32e06cb7269e4fbfaf9ad6c26d0722201f982f9e Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/aarch64/tegra_helpers.S | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S index 5f01416d8..bd2bebb40 100644 --- a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S +++ b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S @@ -166,23 +166,6 @@ func plat_get_my_entrypoint ret endfunc plat_get_my_entrypoint - /* ----------------------------------------------------- - * int platform_get_core_pos(int mpidr); - * - * result: CorePos = (ClusterId * cpus per cluster) + - * CoreId - * ----------------------------------------------------- - */ -func platform_get_core_pos - and x1, x0, #MPIDR_CPU_MASK - and x0, x0, #MPIDR_CLUSTER_MASK - lsr x0, x0, #MPIDR_AFFINITY_BITS - mov x2, #PLATFORM_MAX_CPUS_PER_CLUSTER - mul x0, x0, x2 - add x0, x1, x0 - ret -endfunc platform_get_core_pos - /* ----------------------------------------------------- * void plat_secondary_cold_boot_setup (void); * -- cgit v1.2.3 From 13fed5a7b4eff961a61259a0978d567d062b14fb Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Thu, 22 Aug 2019 11:52:36 -0700 Subject: Tegra: TZDRAM setup from soc specific early_boot handlers TZDRAM setup is not required for all Tegra SoCs. The previous bootloader can enable the TZDRAM fence due to architectural improvements in the newer chips. This patch moves the TZDRAM setup to early_boot handlers for SoCs to handle this scenario. Change-Id: I6481b4f848a4dadc20cb83852cd8e19a242b3a34 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/tegra_bl31_setup.c | 15 --------------- plat/nvidia/tegra/soc/t132/plat_setup.c | 9 +++++++++ plat/nvidia/tegra/soc/t186/plat_setup.c | 15 +++++++++++++++ plat/nvidia/tegra/soc/t210/plat_setup.c | 6 ++++++ 4 files changed, 30 insertions(+), 15 deletions(-) diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c index e56909dcd..a787e3342 100644 --- a/plat/nvidia/tegra/common/tegra_bl31_setup.c +++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c @@ -179,21 +179,6 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, /* Early platform setup for Tegra SoCs */ plat_early_platform_setup(); - /* - * Do initial security configuration to allow DRAM/device access. - */ - tegra_memctrl_tzdram_setup(plat_bl31_params_from_bl2.tzdram_base, - (uint32_t)plat_bl31_params_from_bl2.tzdram_size); - -#if RELOCATE_BL32_IMAGE - /* - * The previous bootloader might not have placed the BL32 image - * inside the TZDRAM. Platform handler to allow relocation of BL32 - * image to TZDRAM memory. This behavior might change per platform. - */ - plat_relocate_bl32_image(arg_from_bl2->bl32_image_info); -#endif - /* * Add timestamp for platform early setup exit. */ diff --git a/plat/nvidia/tegra/soc/t132/plat_setup.c b/plat/nvidia/tegra/soc/t132/plat_setup.c index f7b134d15..9f9abac7f 100644 --- a/plat/nvidia/tegra/soc/t132/plat_setup.c +++ b/plat/nvidia/tegra/soc/t132/plat_setup.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -145,8 +146,16 @@ plat_params_from_bl2_t *plat_get_bl31_plat_params(void) ******************************************************************************/ void plat_early_platform_setup(void) { + plat_params_from_bl2_t *plat_params = bl31_get_plat_params(); + /* Verify chip id is t132 */ assert(tegra_chipid_is_t132()); + + /* + * Do initial security configuration to allow DRAM/device access. + */ + tegra_memctrl_tzdram_setup(plat_params->tzdram_base, + (uint32_t)plat_params->tzdram_size); } /******************************************************************************* diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c index 03182d789..ab374a4e0 100644 --- a/plat/nvidia/tegra/soc/t186/plat_setup.c +++ b/plat/nvidia/tegra/soc/t186/plat_setup.c @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -185,6 +186,7 @@ void plat_early_platform_setup(void) { uint64_t impl, val; const plat_params_from_bl2_t *plat_params = bl31_get_plat_params(); + const struct tegra_bl31_params *arg_from_bl2 = plat_get_bl31_params(); /* Verify chip id is t186 */ assert(tegra_chipid_is_t186()); @@ -192,6 +194,12 @@ void plat_early_platform_setup(void) /* sanity check MCE firmware compatibility */ mce_verify_firmware_version(); + /* + * Do initial security configuration to allow DRAM/device access. + */ + tegra_memctrl_tzdram_setup(plat_params->tzdram_base, + (uint32_t)plat_params->tzdram_size); + impl = (read_midr() >> MIDR_IMPL_SHIFT) & (uint64_t)MIDR_IMPL_MASK; /* @@ -205,6 +213,13 @@ void plat_early_platform_setup(void) val |= CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT; write_l2ctlr_el1(val); } + + /* + * The previous bootloader might not have placed the BL32 image + * inside the TZDRAM. Platform handler to allow relocation of BL32 + * image to TZDRAM memory. This behavior might change per platform. + */ + plat_relocate_bl32_image(arg_from_bl2->bl32_image_info); } /******************************************************************************* diff --git a/plat/nvidia/tegra/soc/t210/plat_setup.c b/plat/nvidia/tegra/soc/t210/plat_setup.c index a16f302a6..20dde3b9c 100644 --- a/plat/nvidia/tegra/soc/t210/plat_setup.c +++ b/plat/nvidia/tegra/soc/t210/plat_setup.c @@ -168,6 +168,12 @@ void plat_early_platform_setup(void) /* Verify chip id is t210 */ assert(tegra_chipid_is_t210()); + /* + * Do initial security configuration to allow DRAM/device access. + */ + tegra_memctrl_tzdram_setup(plat_params->tzdram_base, + (uint32_t)plat_params->tzdram_size); + /* platform parameter passed by the previous bootloader */ if (plat_params->l2_ecc_parity_prot_dis != 1) { /* Enable ECC Parity Protection for Cortex-A57 CPUs */ -- cgit v1.2.3 From 21ec61a904d8003ab9b0f0092c24ecdd69327587 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Thu, 26 Sep 2019 08:26:41 -0700 Subject: Tegra: smmu: add smmu_verify function The SMMU configuration can get corrupted or updated by external clients during boot without our knowledge. This patch introduces a "verify" function for the SMMU driver, to check that the boot configuration settings are intact. Usually, this function should be called at the end of the boot cycle. This function only calls panic() on silicon platforms. Change-Id: I2ab45a7f228781e71c73ba1f4ffc49353effe146 Signed-off-by: George Bauernschmidt --- plat/nvidia/tegra/common/tegra_bl31_setup.c | 8 ++++ plat/nvidia/tegra/drivers/smmu/smmu.c | 62 ++++++++++++++++++++++++-- plat/nvidia/tegra/include/drivers/memctrl_v2.h | 2 + plat/nvidia/tegra/include/drivers/smmu.h | 1 + 4 files changed, 70 insertions(+), 3 deletions(-) diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c index a787e3342..d5297ee0a 100644 --- a/plat/nvidia/tegra/common/tegra_bl31_setup.c +++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -272,6 +273,13 @@ void bl31_plat_runtime_setup(void) */ tegra_memctrl_disable_ahb_redirection(); +#if defined(TEGRA_SMMU0_BASE) + /* + * Verify the integrity of the previously configured SMMU(s) settings + */ + tegra_smmu_verify(); +#endif + /* * Add final timestamp before exiting BL31. */ diff --git a/plat/nvidia/tegra/drivers/smmu/smmu.c b/plat/nvidia/tegra/drivers/smmu/smmu.c index a4a4354e8..4189b00b1 100644 --- a/plat/nvidia/tegra/drivers/smmu/smmu.c +++ b/plat/nvidia/tegra/drivers/smmu/smmu.c @@ -14,6 +14,7 @@ #include #include +#include #include extern void memcpy16(void *dest, const void *src, unsigned int length); @@ -21,15 +22,17 @@ extern void memcpy16(void *dest, const void *src, unsigned int length); #define SMMU_NUM_CONTEXTS 64U #define SMMU_CONTEXT_BANK_MAX_IDX 64U +#define MISMATCH_DETECTED 0x55AA55AAU + /* * Init SMMU during boot or "System Suspend" exit */ void tegra_smmu_init(void) { uint32_t val, cb_idx, smmu_id, ctx_base; - uint32_t smmu_counter = plat_get_num_smmu_devices(); + uint32_t num_smmu_devices = plat_get_num_smmu_devices(); - for (smmu_id = 0U; smmu_id < smmu_counter; smmu_id++) { + for (smmu_id = 0U; smmu_id < num_smmu_devices; smmu_id++) { /* Program the SMMU pagesize and reset CACHE_LOCK bit */ val = tegra_smmu_read_32(smmu_id, SMMU_GSR0_SECURE_ACR); val |= SMMU_GSR0_PGSIZE_64K; @@ -44,7 +47,7 @@ void tegra_smmu_init(void) /* disable TCU prefetch for all contexts */ ctx_base = (SMMU_GSR0_PGSIZE_64K * SMMU_NUM_CONTEXTS) + SMMU_CBn_ACTLR; - for (cb_idx = 0; cb_idx < SMMU_CONTEXT_BANK_MAX_IDX; cb_idx++) { + for (cb_idx = 0U; cb_idx < SMMU_CONTEXT_BANK_MAX_IDX; cb_idx++) { val = tegra_smmu_read_32(smmu_id, ctx_base + (SMMU_GSR0_PGSIZE_64K * cb_idx)); val &= (uint32_t)~SMMU_CBn_ACTLR_CPRE_BIT; @@ -63,3 +66,56 @@ void tegra_smmu_init(void) tegra_smmu_write_32(smmu_id, SMMU_GSR0_SECURE_ACR, val); } } + +/* + * Verify SMMU settings have not been altered during boot + */ +void tegra_smmu_verify(void) +{ + uint32_t cb_idx, ctx_base, smmu_id, val; + uint32_t num_smmu_devices = plat_get_num_smmu_devices(); + uint32_t mismatch = 0U; + + for (smmu_id = 0U; smmu_id < num_smmu_devices; smmu_id++) { + /* check PGSIZE_64K bit inr S Aux. Config. Register */ + val = tegra_smmu_read_32(smmu_id, SMMU_GSR0_SECURE_ACR); + if (0U == (val & SMMU_GSR0_PGSIZE_64K)) { + ERROR("%s: PGSIZE_64K Mismatch - smmu_id=%d, GSR0_SECURE_ACR=%x\n", + __func__, smmu_id, val); + mismatch = MISMATCH_DETECTED; + } + + /* check CACHE LOCK bit in S Aux. Config. Register */ + if (0U == (val & SMMU_ACR_CACHE_LOCK_ENABLE_BIT)) { + ERROR("%s: CACHE_LOCK Mismatch - smmu_id=%d, GSR0_SECURE_ACR=%x\n", + __func__, smmu_id, val); + mismatch = MISMATCH_DETECTED; + } + + /* check CACHE LOCK bit in NS Aux. Config. Register */ + val = tegra_smmu_read_32(smmu_id, SMMU_GNSR_ACR); + if (0U == (val & SMMU_ACR_CACHE_LOCK_ENABLE_BIT)) { + ERROR("%s: Mismatch - smmu_id=%d, GNSR_ACR=%x\n", + __func__, smmu_id, val); + mismatch = MISMATCH_DETECTED; + } + + /* verify TCU prefetch for all contexts is disabled */ + ctx_base = (SMMU_GSR0_PGSIZE_64K * SMMU_NUM_CONTEXTS) + + SMMU_CBn_ACTLR; + for (cb_idx = 0U; cb_idx < SMMU_CONTEXT_BANK_MAX_IDX; cb_idx++) { + val = tegra_smmu_read_32(smmu_id, + ctx_base + (SMMU_GSR0_PGSIZE_64K * cb_idx)); + if (0U != (val & SMMU_CBn_ACTLR_CPRE_BIT)) { + ERROR("%s: Mismatch - smmu_id=%d, cb_idx=%d, GSR0_PGSIZE_64K=%x\n", + __func__, smmu_id, cb_idx, val); + mismatch = MISMATCH_DETECTED; + } + } + } + + /* Treat configuration mismatch as fatal */ + if ((mismatch == MISMATCH_DETECTED) && tegra_platform_is_silicon()) { + panic(); + } +} diff --git a/plat/nvidia/tegra/include/drivers/memctrl_v2.h b/plat/nvidia/tegra/include/drivers/memctrl_v2.h index 509fe32bb..e15762ba5 100644 --- a/plat/nvidia/tegra/include/drivers/memctrl_v2.h +++ b/plat/nvidia/tegra/include/drivers/memctrl_v2.h @@ -144,6 +144,7 @@ static inline void tegra_mc_write_32(uint32_t off, uint32_t val) mmio_write_32(TEGRA_MC_BASE + off, val); } +#if defined(TEGRA_MC_STREAMID_BASE) static inline uint32_t tegra_mc_streamid_read_32(uint32_t off) { return mmio_read_32(TEGRA_MC_STREAMID_BASE + off); @@ -153,6 +154,7 @@ static inline void tegra_mc_streamid_write_32(uint32_t off, uint32_t val) { mmio_write_32(TEGRA_MC_STREAMID_BASE + off, val); } +#endif #define mc_set_pcfifo_unordered_boot_so_mss(id, client) \ ((uint32_t)~MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_MASK | \ diff --git a/plat/nvidia/tegra/include/drivers/smmu.h b/plat/nvidia/tegra/include/drivers/smmu.h index 601864fb5..1de9af6e5 100644 --- a/plat/nvidia/tegra/include/drivers/smmu.h +++ b/plat/nvidia/tegra/include/drivers/smmu.h @@ -86,6 +86,7 @@ static inline void tegra_smmu_write_32(uint32_t smmu_id, } void tegra_smmu_init(void); +void tegra_smmu_verify(void); uint32_t plat_get_num_smmu_devices(void); #endif /* SMMU_H */ -- cgit v1.2.3 From be41aac7a72412797046a64b126cc0408f1a87a3 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Mon, 17 Feb 2020 15:29:57 -0800 Subject: Tegra194: remove AON_WDT IRQ mapping This patch removes the unused interrupt mapping for AON_WDT for all Tegra194 platforms. Signed-off-by: Varun Wadekar Change-Id: I475a1e83f809c740e62464b5b4e93cb0a2e33d6b --- plat/nvidia/tegra/soc/t194/plat_setup.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/plat/nvidia/tegra/soc/t194/plat_setup.c b/plat/nvidia/tegra/soc/t194/plat_setup.c index 09611787b..c0f2fb017 100644 --- a/plat/nvidia/tegra/soc/t194/plat_setup.c +++ b/plat/nvidia/tegra/soc/t194/plat_setup.c @@ -286,8 +286,6 @@ static const interrupt_prop_t tegra194_interrupt_props[] = { INTR_PROP_DESC(TEGRA_SDEI_SGI_PRIVATE, PLAT_SDEI_CRITICAL_PRI, GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE), INTR_PROP_DESC(TEGRA194_TOP_WDT_IRQ, PLAT_TEGRA_WDT_PRIO, - GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE), - INTR_PROP_DESC(TEGRA194_AON_WDT_IRQ, PLAT_TEGRA_WDT_PRIO, GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE) }; -- cgit v1.2.3 From cb7b9db19db5750d38762ad7a11219a57a740d17 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Sun, 19 Jul 2020 21:28:10 -0700 Subject: plat: common: include "bl_common.h" from plat_spmd_manifest.c This patch includes the bl_common.h from plat_spmd_manifest.c to fix the following compilation errors plat/common/plat_spmd_manifest.c: In function 'plat_spm_core_manifest_load': plat/common/plat_spmd_manifest.c:130:18: error: implicit declaration of function 'page_align' [-Werror=implicit-function-declaration] 130 | pm_base_align = page_align(pm_base, UP); | ^~~~~~~~~~ plat/common/plat_spmd_manifest.c:130:38: error: 'UP' undeclared (first use in this function); did you mean 'UL'? 130 | pm_base_align = page_align(pm_base, UP); | ^~ | UL plat/common/plat_spmd_manifest.c:130:38: note: each undeclared identifier is reported only once for each function it appears in plat/common/plat_spmd_manifest.c:146:38: error: 'DOWN' undeclared (first use in this function) 146 | pm_base_align = page_align(pm_base, DOWN); | ^~~~ cc1: all warnings being treated as errors Signed-off-by: Varun Wadekar Change-Id: Ib8edb36c6a80a23df2462e708c513c966aab1fef --- plat/common/plat_spmd_manifest.c | 1 + 1 file changed, 1 insertion(+) diff --git a/plat/common/plat_spmd_manifest.c b/plat/common/plat_spmd_manifest.c index e65980bc8..8f4018c7c 100644 --- a/plat/common/plat_spmd_manifest.c +++ b/plat/common/plat_spmd_manifest.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include -- cgit v1.2.3 From 8d51439e936b3d257112a73485657d8b9f179d75 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Mon, 24 Aug 2020 16:57:03 -0700 Subject: Tegra: disable signed comparison libfdt does not support the -Wsign-compare compiler option and the right patch will eventually be pushed upstream. This patch disables the -Wsign-compare compiler option to allow libfdt compilation for Tegra platforms until the actual issue is fixed. Signed-off-by: Varun Wadekar Change-Id: Ib7a93946cad1ea9ec1b46751edb79a74c08ed0ac --- plat/nvidia/tegra/platform.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/nvidia/tegra/platform.mk b/plat/nvidia/tegra/platform.mk index a4724e64b..6beaa05de 100644 --- a/plat/nvidia/tegra/platform.mk +++ b/plat/nvidia/tegra/platform.mk @@ -65,7 +65,7 @@ $(eval $(call add_define,RELOCATE_BL32_IMAGE)) BUILD_PLAT := $(abspath ${BUILD_BASE})/${PLAT}/${TARGET_SOC}/${BUILD_TYPE} # platform cflags (enable signed comparisons, disable stdlib) -TF_CFLAGS += -Wsign-compare -nostdlib +TF_CFLAGS += -nostdlib # override with necessary libc files for the Tegra platform override LIBC_SRCS := $(addprefix lib/libc/, \ -- cgit v1.2.3 From eb7e5087dce18d697be5e803c46751d9e01c1b6a Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Sun, 19 Jul 2020 21:17:57 -0700 Subject: Tegra: introduce backend support to compile libfdt This patch includes the following files from libc to compile libfdt: * memchr.c * memcmp.c * strrchr.c The BUILD_PLAT macro is evaluated earlier to allow libfdt installation to the right directory. Signed-off-by: Varun Wadekar Change-Id: Ie43fcf701dc051670e6372e21b3a84a6416c1735 --- plat/nvidia/tegra/platform.mk | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/plat/nvidia/tegra/platform.mk b/plat/nvidia/tegra/platform.mk index 6beaa05de..abe94e4d2 100644 --- a/plat/nvidia/tegra/platform.mk +++ b/plat/nvidia/tegra/platform.mk @@ -55,15 +55,15 @@ ENABLE_STACK_PROTECTOR := strong # Enable SDEI SDEI_SUPPORT := 1 +# modify BUILD_PLAT to point to SoC specific build directory +BUILD_PLAT := ${BUILD_BASE}/${PLAT}/${TARGET_SOC}/${BUILD_TYPE} + include plat/nvidia/tegra/common/tegra_common.mk include ${SOC_DIR}/platform_${TARGET_SOC}.mk $(eval $(call add_define,ENABLE_TEGRA_WDT_LEGACY_FIQ_HANDLING)) $(eval $(call add_define,RELOCATE_BL32_IMAGE)) -# modify BUILD_PLAT to point to SoC specific build directory -BUILD_PLAT := $(abspath ${BUILD_BASE})/${PLAT}/${TARGET_SOC}/${BUILD_TYPE} - # platform cflags (enable signed comparisons, disable stdlib) TF_CFLAGS += -nostdlib @@ -71,11 +71,14 @@ TF_CFLAGS += -nostdlib override LIBC_SRCS := $(addprefix lib/libc/, \ aarch64/setjmp.S \ assert.c \ + memchr.c \ + memcmp.c \ memcpy.c \ memmove.c \ memset.c \ printf.c \ putchar.c \ + strrchr.c \ strlen.c \ snprintf.c) -- cgit v1.2.3 From 670306d340487ff5109c768a7dba1276cd9b28a9 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Sun, 19 Jul 2020 21:30:54 -0700 Subject: Tegra194: introduce support for `SPD=spmd` This patch introduces the following changes to enable compilation for `SPD=spmd` command line option. * compile plat_spmd_manifest.c * compile libfdt source files Verified with the `SPD=spmd` command line option for Tegra194 platforms. Signed-off-by: Varun Wadekar Change-Id: I7f57aa4f1756b19f78d87415bb80794417174bc8 --- plat/nvidia/tegra/soc/t194/platform_t194.mk | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/plat/nvidia/tegra/soc/t194/platform_t194.mk b/plat/nvidia/tegra/soc/t194/platform_t194.mk index 7573ed23b..9705a7fe4 100644 --- a/plat/nvidia/tegra/soc/t194/platform_t194.mk +++ b/plat/nvidia/tegra/soc/t194/platform_t194.mk @@ -70,3 +70,13 @@ BL31_SOURCES += lib/extensions/ras/std_err_record.c \ lib/extensions/ras/ras_common.c \ ${SOC_DIR}/plat_ras.c 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} +endif -- cgit v1.2.3 From 2acf00433023a16ff5f076e2d551961567c022d5 Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Mon, 24 Aug 2020 18:34:38 -0700 Subject: qti/sc7180: Fix GIC-600 support setting The patch adding platform support for sc7180 landed around roughly the same time as the patch that changed GICV3_IMPL to GICV3_SUPPORT_GIC600. Thus the sc7180 Makefile is still using the old variable name which now no longer does anything, and it hangs on boot due to the lacking GIC-600 support. This patch fixes the issue. Signed-off-by: Julius Werner Change-Id: Id76ada1445c3c5ac9a5a3697b4e749088b89d796 --- plat/qti/sc7180/platform.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/qti/sc7180/platform.mk b/plat/qti/sc7180/platform.mk index e55135567..562fe7cd8 100644 --- a/plat/qti/sc7180/platform.mk +++ b/plat/qti/sc7180/platform.mk @@ -79,7 +79,7 @@ include lib/coreboot/coreboot.mk PSCI_SOURCES := plat/common/plat_psci_common.c \ # GIC-600 configuration -GICV3_IMPL := GIC600 +GICV3_SUPPORT_GIC600 := 1 # Include GICv3 driver files include drivers/arm/gic/v3/gicv3.mk -- cgit v1.2.3 From f40008a4be26dc43cbf50f68c4f20803ea735807 Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Wed, 5 Jun 2019 12:40:35 -0700 Subject: qti: Add SPMI PMIC arbitrator driver This patch adds a very rudimentary driver for the SPMI arbitrator used to access the PMIC. It doesn't support all the controller's actual arbitration features, so it should probably not be used concurrently with a running kernel (and it's also not optimized for performance). But it can be used to set a few registers during boot or on shutdown to control reset handling, which is all we need it for. Change-Id: I8631c34a2a89ac71aa1ec9b8266e818c922fe34a Signed-off-by: Julius Werner --- plat/qti/common/inc/spmi_arb.h | 23 +++++++++ plat/qti/common/src/spmi_arb.c | 113 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 plat/qti/common/inc/spmi_arb.h create mode 100644 plat/qti/common/src/spmi_arb.c diff --git a/plat/qti/common/inc/spmi_arb.h b/plat/qti/common/inc/spmi_arb.h new file mode 100644 index 000000000..362f7406c --- /dev/null +++ b/plat/qti/common/inc/spmi_arb.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2020, Google LLC. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SPMI_ARB_H +#define SPMI_ARB_H + +#include + +/******************************************************************************* + * WARNING: This driver does not arbitrate access with the kernel. These APIs + * must only be called when the kernel is known to be quiesced (such as before + * boot or while the system is shutting down). + ******************************************************************************/ + +/* 32-bit addresses combine (U)SID, PID and register address. */ + +int spmi_arb_read8(uint32_t addr); +int spmi_arb_write8(uint32_t addr, uint8_t data); + +#endif /* SPMI_ARB_H */ diff --git a/plat/qti/common/src/spmi_arb.c b/plat/qti/common/src/spmi_arb.c new file mode 100644 index 000000000..81cc57729 --- /dev/null +++ b/plat/qti/common/src/spmi_arb.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2020, Google LLC. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include + +#define REG_APID_MAP(apid) (0x0C440900 + 4 * i) +#define NUM_APID 0x80 + +#define PPID_MASK (0xfff << 8) + +#define REG_ARB_CMD(apid) (0x0C600000 + 0x10000 * apid) +/* These are opcodes specific to this SPMI arbitrator, *not* SPMI commands. */ +#define OPC_EXT_WRITEL 0 +#define OPC_EXT_READL 1 + +#define REG_ARB_STATUS(apid) (0x0C600008 + 0x10000 * apid) +#define ARB_STATUS_DONE BIT(0) +#define ARB_STATUS_FAILURE BIT(1) +#define ARB_STATUS_DENIED BIT(2) +#define ARB_STATUS_DROPPED BIT(3) + +/* Fake status to report driver errors. */ +#define ARB_FAKE_STATUS_TIMEOUT BIT(8) + +#define REG_ARB_RDATA0(apid) (0x0C600018 + 0x10000 * apid) +#define REG_ARB_WDATA0(apid) (0x0C600010 + 0x10000 * apid) + +static int addr_to_apid(uint32_t addr) +{ + unsigned int i; + + for (i = 0U; i < NUM_APID; i++) { + uint32_t reg = mmio_read_32(REG_APID_MAP(i)); + if ((reg != 0U) && ((addr & PPID_MASK) == (reg & PPID_MASK))) { + return i; + } + } + + return -1; +} + +static int wait_for_done(uint16_t apid) +{ + unsigned int timeout = 100; + + while (timeout-- != 0U) { + uint32_t status = mmio_read_32(REG_ARB_STATUS(apid)); + if ((status & ARB_STATUS_DONE) != 0U) { + if ((status & ARB_STATUS_FAILURE) != 0U || + (status & ARB_STATUS_DENIED) != 0U || + (status & ARB_STATUS_DROPPED) != 0U) { + return status & 0xff; + } + return 0; + } + mdelay(1); + } + ERROR("SPMI_ARB timeout!\n"); + return ARB_FAKE_STATUS_TIMEOUT; +} + +static void arb_command(uint16_t apid, uint8_t opcode, uint32_t addr, + uint8_t bytes) +{ + mmio_write_32(REG_ARB_CMD(apid), (uint32_t)opcode << 27 | + (addr & 0xff) << 4 | (bytes - 1)); +} + +int spmi_arb_read8(uint32_t addr) +{ + int apid = addr_to_apid(addr); + + if (apid < 0) { + return apid; + } + + arb_command(apid, OPC_EXT_READL, addr, 1); + + int ret = wait_for_done(apid); + if (ret != 0) { + ERROR("SPMI_ARB read error [0x%x]: 0x%x\n", addr, ret); + return ret; + } + + return mmio_read_32(REG_ARB_RDATA0(apid)) & 0xff; +} + +int spmi_arb_write8(uint32_t addr, uint8_t data) +{ + int apid = addr_to_apid(addr); + + if (apid < 0) { + return apid; + } + + mmio_write_32(REG_ARB_WDATA0(apid), data); + arb_command(apid, OPC_EXT_WRITEL, addr, 1); + + int ret = wait_for_done(apid); + if (ret != 0) { + ERROR("SPMI_ARB write error [0x%x] = 0x%x: 0x%x\n", + addr, data, ret); + } + + return ret; +} -- cgit v1.2.3 From 522a22771f0e40866a7361b2f8e416b8cb716a1c Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Wed, 20 Feb 2019 17:33:23 -0800 Subject: qti/sc7180: Do shutdown handling outside qtiseclib With an open source SPMI driver we can now remove qtiseclib involvement in reset and shutdown handling by setting the required registers directly. Change-Id: I6bf1db15734048df583daa2a4ee98701c6ece621 Signed-off-by: Julius Werner --- plat/qti/common/inc/qti_plat.h | 3 ++ plat/qti/common/src/pm8998.c | 43 +++++++++++++++++++++++ plat/qti/common/src/qti_pm.c | 17 +++++++-- plat/qti/qtiseclib/inc/qtiseclib_interface.h | 4 --- plat/qti/qtiseclib/src/qtiseclib_interface_stub.c | 12 ------- plat/qti/sc7180/inc/platform_def.h | 6 ++++ plat/qti/sc7180/platform.mk | 2 ++ 7 files changed, 69 insertions(+), 18 deletions(-) create mode 100644 plat/qti/common/src/pm8998.c diff --git a/plat/qti/common/inc/qti_plat.h b/plat/qti/common/inc/qti_plat.h index 0e867be79..4d9d3204a 100644 --- a/plat/qti/common/inc/qti_plat.h +++ b/plat/qti/common/inc/qti_plat.h @@ -50,4 +50,7 @@ unsigned int plat_qti_my_cluster_pos(void); void gic_set_spi_routing(unsigned int id, unsigned int irm, u_register_t mpidr); +void qti_pmic_prepare_reset(void); +void qti_pmic_prepare_shutdown(void); + #endif /* QTI_PLAT_H */ diff --git a/plat/qti/common/src/pm8998.c b/plat/qti/common/src/pm8998.c new file mode 100644 index 000000000..b189a8b86 --- /dev/null +++ b/plat/qti/common/src/pm8998.c @@ -0,0 +1,43 @@ +/* + * 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/qti_pm.c b/plat/qti/common/src/qti_pm.c index 4a5877c5b..5f1b7aa1d 100644 --- a/plat/qti/common/src/qti_pm.c +++ b/plat/qti/common/src/qti_pm.c @@ -9,6 +9,8 @@ #include #include #include +#include +#include #include #include @@ -204,14 +206,25 @@ __dead2 void qti_domain_power_down_wfi(const psci_power_state_t *target_state) /* We should never reach here */ } +static __dead2 void assert_ps_hold(void) +{ + mmio_write_32(QTI_PS_HOLD_REG, 0); + mdelay(1000); + + /* Should be dead before reaching this. */ + panic(); +} + __dead2 void qti_system_off(void) { - qtiseclib_psci_system_off(); + qti_pmic_prepare_shutdown(); + assert_ps_hold(); } __dead2 void qti_system_reset(void) { - qtiseclib_psci_system_reset(); + qti_pmic_prepare_reset(); + assert_ps_hold(); } void qti_get_sys_suspend_power_state(psci_power_state_t *req_state) diff --git a/plat/qti/qtiseclib/inc/qtiseclib_interface.h b/plat/qti/qtiseclib/inc/qtiseclib_interface.h index 357bb6a2d..315bd6bc7 100644 --- a/plat/qti/qtiseclib/inc/qtiseclib_interface.h +++ b/plat/qti/qtiseclib/inc/qtiseclib_interface.h @@ -78,10 +78,6 @@ void qtiseclib_psci_cpu_standby(uint8_t pwr_state); void qtiseclib_psci_node_power_off(const uint8_t *states); void qtiseclib_psci_node_suspend(const uint8_t *states); void qtiseclib_psci_node_suspend_finish(const uint8_t *states); -__attribute__ ((noreturn)) -void qtiseclib_psci_system_off(void); -__attribute__ ((noreturn)) -void qtiseclib_psci_system_reset(void); void qtiseclib_disable_cluster_coherency(uint8_t state); #endif /* QTISECLIB_INTERFACE_H */ diff --git a/plat/qti/qtiseclib/src/qtiseclib_interface_stub.c b/plat/qti/qtiseclib/src/qtiseclib_interface_stub.c index 70485fe90..9c93d51da 100644 --- a/plat/qti/qtiseclib/src/qtiseclib_interface_stub.c +++ b/plat/qti/qtiseclib/src/qtiseclib_interface_stub.c @@ -108,18 +108,6 @@ void qtiseclib_psci_node_suspend_finish(const uint8_t *states) { } -void qtiseclib_psci_system_off(void) -{ - while (1) { - }; -} - -void qtiseclib_psci_system_reset(void) -{ - while (1) { - }; -} - void qtiseclib_disable_cluster_coherency(uint8_t state) { } diff --git a/plat/qti/sc7180/inc/platform_def.h b/plat/qti/sc7180/inc/platform_def.h index d95b365dc..17e1310b0 100644 --- a/plat/qti/sc7180/inc/platform_def.h +++ b/plat/qti/sc7180/inc/platform_def.h @@ -173,4 +173,10 @@ */ #define BL31_LIMIT (BL31_BASE + BL31_SIZE) +/*----------------------------------------------------------------------------*/ +/* AOSS registers */ +/*----------------------------------------------------------------------------*/ +#define QTI_PS_HOLD_REG 0x0C264000 +/*----------------------------------------------------------------------------*/ + #endif /* PLATFORM_DEF_H */ diff --git a/plat/qti/sc7180/platform.mk b/plat/qti/sc7180/platform.mk index 562fe7cd8..ec560d036 100644 --- a/plat/qti/sc7180/platform.mk +++ b/plat/qti/sc7180/platform.mk @@ -51,6 +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/qti_stack_protector.c \ $(QTI_PLAT_PATH)/common/src/qti_common.c \ $(QTI_PLAT_PATH)/common/src/qti_bl31_setup.c \ @@ -60,6 +61,7 @@ QTI_BL31_SOURCES := $(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_helpers.S \ $(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 \ -- cgit v1.2.3 From 524eecc6a2a279d685755d5b39557ebcd78bb2cf Mon Sep 17 00:00:00 2001 From: Javier Almansa Sobrino Date: Fri, 21 Aug 2020 17:32:03 +0100 Subject: Add support for hexadecimal and pointer format specifiers to snprintf() The current implementation of snprintf() does not support pointer and hexadecimal format specifiers, which can be needed, for instance, for DTB manipulations. This patch adds that functionality by borrowing some code from the printf() implementation. Signed-off-by: Javier Almansa Sobrino Change-Id: I2076ea46693a73a04890982bf20e3c633c2767fb --- lib/libc/snprintf.c | 119 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 103 insertions(+), 16 deletions(-) diff --git a/lib/libc/snprintf.c b/lib/libc/snprintf.c index 38ad1c71a..268632722 100644 --- a/lib/libc/snprintf.c +++ b/lib/libc/snprintf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -24,27 +24,55 @@ static void string_print(char **s, size_t n, size_t *chars_printed, } } -static void unsigned_dec_print(char **s, size_t n, size_t *chars_printed, - unsigned int unum) +static void unsigned_num_print(char **s, size_t n, size_t *chars_printed, + unsigned long long int unum, + unsigned int radix, char padc, int padn, + bool capitalise) { - /* Enough for a 32-bit unsigned decimal integer (4294967295). */ - char num_buf[10]; + /* Just need enough space to store 64 bit decimal integer */ + char num_buf[20]; int i = 0; + int width; unsigned int rem; + char ascii_a = capitalise ? 'A' : 'a'; do { - rem = unum % 10U; - num_buf[i++] = '0' + rem; - unum /= 10U; + rem = unum % radix; + if (rem < 10U) { + num_buf[i] = '0' + rem; + } else { + num_buf[i] = ascii_a + (rem - 10U); + } + i++; + unum /= radix; } while (unum > 0U); - while (--i >= 0) { - if (*chars_printed < n) { - *(*s) = num_buf[i]; - (*s)++; + width = i; + if (padn > width) { + (*chars_printed) += (size_t)padn; + } else { + (*chars_printed) += (size_t)width; + } + + if (*chars_printed < n) { + + if (padn > 0) { + while (width < padn) { + *(*s)++ = padc; + padn--; + } } - (*chars_printed)++; + while (--i >= 0) { + *(*s)++ = num_buf[i]; + } + + if (padn < 0) { + while (width < -padn) { + *(*s)++ = padc; + padn++; + } + } } } @@ -52,9 +80,16 @@ static void unsigned_dec_print(char **s, size_t n, size_t *chars_printed, * Reduced snprintf to be used for Trusted firmware. * The following type specifiers are supported: * + * %x (or %X) - hexadecimal format * %d or %i - signed decimal format * %s - string format * %u - unsigned decimal format + * %p - pointer format + * + * The following padding specifiers are supported by this print + * %0NN - Left-pad the number with 0s (NN is a decimal number) + * %NN - Left-pad the number or string with spaces (NN is a decimal number) + * %-NN - Right-pad the number or string with spaces (NN is a decimal number) * * The function panics on all other formats specifiers. * @@ -66,8 +101,12 @@ int snprintf(char *s, size_t n, const char *fmt, ...) { va_list args; int num; - unsigned int unum; + unsigned long long int unum; char *str; + char padc; /* Padding character */ + int padn; /* Number of characters to pad */ + bool left; + bool capitalise; size_t chars_printed = 0U; if (n == 0U) { @@ -83,11 +122,39 @@ int snprintf(char *s, size_t n, const char *fmt, ...) va_start(args, fmt); while (*fmt != '\0') { + left = false; + padc ='\0'; + padn = 0; + capitalise = false; if (*fmt == '%') { fmt++; /* Check the format specifier. */ +loop: switch (*fmt) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + padc = (*fmt == '0') ? '0' : ' '; + for (padn = 0; *fmt >= '0' && *fmt <= '9'; fmt++) { + padn = (padn * 10) + (*fmt - '0'); + } + if (left) { + padn = -padn; + } + goto loop; + case '-': + left = true; + fmt++; + goto loop; + case 'i': case 'd': num = va_arg(args, int); @@ -104,7 +171,8 @@ int snprintf(char *s, size_t n, const char *fmt, ...) unum = (unsigned int)num; } - unsigned_dec_print(&s, n, &chars_printed, unum); + unsigned_num_print(&s, n, &chars_printed, + unum, 10, padc, padn, false); break; case 's': str = va_arg(args, char *); @@ -112,8 +180,27 @@ int snprintf(char *s, size_t n, const char *fmt, ...) break; case 'u': unum = va_arg(args, unsigned int); - unsigned_dec_print(&s, n, &chars_printed, unum); + unsigned_num_print(&s, n, &chars_printed, + unum, 10, padc, padn, false); break; + case 'p': + unum = (uintptr_t)va_arg(args, void *); + if (unum > 0U) { + string_print(&s, n, &chars_printed, "0x"); + padn -= 2; + } + unsigned_num_print(&s, n, &chars_printed, + unum, 16, padc, padn, false); + break; + case 'X': + capitalise = true; + case 'x': + unum = va_arg(args, unsigned int); + unsigned_num_print(&s, n, &chars_printed, + unum, 16, padc, padn, + capitalise); + break; + default: /* Panic on any other format specifier. */ ERROR("snprintf: specifier with ASCII code '%d' not supported.", -- cgit v1.2.3 From 262aceaac48b56eebf1dcf69601c98c01f6ae38d Mon Sep 17 00:00:00 2001 From: Sandeep Tripathy Date: Wed, 12 Aug 2020 18:42:13 +0530 Subject: ehf: use common priority level enumuration 'EHF' is used by RAS, SDEI, SPM_MM common frameworks. If platform needs to plug-in specific handlers then 'PLAT_EHF_DESC' can be used to populate platform specific priority levels. Signed-off-by: Sandeep Tripathy Change-Id: I37af7e0e48111f87b6982604bf5c15db3e05755d --- include/plat/arm/common/arm_def.h | 2 +- plat/arm/common/aarch64/arm_ehf.c | 33 --------------------------------- plat/arm/common/arm_common.mk | 2 +- plat/common/aarch64/plat_ehf.c | 37 +++++++++++++++++++++++++++++++++++++ 4 files changed, 39 insertions(+), 35 deletions(-) delete mode 100644 plat/arm/common/aarch64/arm_ehf.c create mode 100644 plat/common/aarch64/plat_ehf.c diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index 293e7ce6f..c01864306 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -568,7 +568,7 @@ #define PLAT_SDEI_NORMAL_PRI 0x70 /* ARM platforms use 3 upper bits of secure interrupt priority */ -#define ARM_PRI_BITS 3 +#define PLAT_PRI_BITS 3 /* SGI used for SDEI signalling */ #define ARM_SDEI_SGI ARM_IRQ_SEC_SGI_0 diff --git a/plat/arm/common/aarch64/arm_ehf.c b/plat/arm/common/aarch64/arm_ehf.c deleted file mode 100644 index 69ebd798f..000000000 --- a/plat/arm/common/aarch64/arm_ehf.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include - -/* - * Enumeration of priority levels on ARM platforms. - */ -ehf_pri_desc_t arm_exceptions[] = { -#if RAS_EXTENSION - /* RAS Priority */ - EHF_PRI_DESC(ARM_PRI_BITS, PLAT_RAS_PRI), -#endif - -#if SDEI_SUPPORT - /* Critical priority SDEI */ - EHF_PRI_DESC(ARM_PRI_BITS, PLAT_SDEI_CRITICAL_PRI), - - /* Normal priority SDEI */ - EHF_PRI_DESC(ARM_PRI_BITS, PLAT_SDEI_NORMAL_PRI), -#endif -#if SPM_MM - EHF_PRI_DESC(ARM_PRI_BITS, PLAT_SP_PRI), -#endif -}; - -/* Plug in ARM exceptions to Exception Handling Framework. */ -EHF_REGISTER_PRIORITIES(arm_exceptions, ARRAY_SIZE(arm_exceptions), ARM_PRI_BITS); diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index 96ab2d300..78c0153d9 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -258,7 +258,7 @@ endif endif ifeq (${EL3_EXCEPTION_HANDLING},1) -BL31_SOURCES += plat/arm/common/aarch64/arm_ehf.c +BL31_SOURCES += plat/common/aarch64/plat_ehf.c endif ifeq (${SDEI_SUPPORT},1) diff --git a/plat/common/aarch64/plat_ehf.c b/plat/common/aarch64/plat_ehf.c new file mode 100644 index 000000000..da768843e --- /dev/null +++ b/plat/common/aarch64/plat_ehf.c @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, Broadcom + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include + +/* + * Enumeration of priority levels on ARM platforms. + */ +ehf_pri_desc_t plat_exceptions[] = { +#if RAS_EXTENSION + /* RAS Priority */ + EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_RAS_PRI), +#endif + +#if SDEI_SUPPORT + /* Critical priority SDEI */ + EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_SDEI_CRITICAL_PRI), + + /* Normal priority SDEI */ + EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_SDEI_NORMAL_PRI), +#endif +#if SPM_MM + EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_SP_PRI), +#endif + /* Plaform specific exceptions description */ +#ifdef PLAT_EHF_DESC + PLAT_EHF_DESC, +#endif +}; + +/* Plug in ARM exceptions to Exception Handling Framework. */ +EHF_REGISTER_PRIORITIES(plat_exceptions, ARRAY_SIZE(plat_exceptions), PLAT_PRI_BITS); -- cgit v1.2.3 From 7969747e7f7819b6c66977d85b776c0a9a169c1b Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Fri, 14 Aug 2020 15:58:50 +0200 Subject: doc: Improve contribution guidelines - Add some guidance about the type of information a patch author should provide to facilitate the review (and for future reference). - Make a number of implicit expectations explicit: - Every patch must compile. - All CI tests must pass. - Mention that the patch author is expected to add reviewers and explain how to choose them. - Explain the patch submission rules in terms of Gerrit labels. Also do some cosmetic changes, like adding empty lines, shuffling some paragraphs around. Change-Id: I6dac486684310b5a35aac7353e10fe5474a81ec5 Signed-off-by: Sandrine Bailleux --- docs/process/coding-guidelines.rst | 1 + docs/process/contributing.rst | 124 +++++++++++++++++++++++++++++-------- 2 files changed, 98 insertions(+), 27 deletions(-) diff --git a/docs/process/coding-guidelines.rst b/docs/process/coding-guidelines.rst index 97086047d..2c8620d15 100644 --- a/docs/process/coding-guidelines.rst +++ b/docs/process/coding-guidelines.rst @@ -19,6 +19,7 @@ support its functionality through plugins. Use of the EditorConfig file is suggested but is not required. +.. _automatic-compliance-checking: Automatic Compliance Checking ----------------------------- diff --git a/docs/process/contributing.rst b/docs/process/contributing.rst index bdfb6d6aa..0b3b848f4 100644 --- a/docs/process/contributing.rst +++ b/docs/process/contributing.rst @@ -29,19 +29,53 @@ Making Changes - Make commits of logical units. See these general `Git guidelines`_ for contributing to a project. -- Follow the :ref:`Coding Style` and :ref:`Coding Guidelines`. - - - Use the checkpatch.pl script provided with the Linux source tree. A - Makefile target is provided for convenience. - - Keep the commits on topic. If you need to fix another bug or make another enhancement, please address it on a separate topic branch. +- Split the patch in manageable units. Small patches are usually easier to + review so this will speed up the review process. + - 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. -- Make sure your commit messages are in the proper format. If a commit fixes - an `issue`_, include a reference. +- 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 + Makefile target is provided for convenience, see :ref:`this + section` for more details. - Where appropriate, please update the documentation. @@ -74,49 +108,85 @@ Making Changes is the year of most recent contribution. is your name or your company name. +- Ensure that each patch in the patch series compiles in all supported + configurations. Patches which do not compile will not be merged. + - Please test your changes. As a minimum, ensure that Linux boots on the Foundation FVP. See :ref:`Arm Fixed Virtual Platforms (FVP)` for more information. For more extensive testing, consider running the `TF-A Tests`_ against your patches. +- Ensure that all CI automated tests pass. Failures should be fixed. They might + block a patch, depending on how critical they are. + Submitting Changes ------------------ -- 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 ``Author:`` lines must match. If anyone else - contributes to the commit, they must also add their own ``Signed-off-by:`` - line. By adding this line the contributor certifies the contribution is made - under the terms of the - :download:`Developer Certificate of Origin <../../dco.txt>`. +- Submit your changes for review at https://review.trustedfirmware.org + targeting the ``integration`` branch. - More details may be found in the `Gerrit Signed-off-by Lines guidelines`_. +- Add reviewers for your patch: -- 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. + - At least one code owner for each module modified by the patch. See the list + of modules and their :ref:`code owners`. - More details may be found in the `Gerrit Change-Ids documentation`_. + - At least one maintainer. See the list of :ref:`maintainers`. -- Submit your changes for review at https://review.trustedfirmware.org - targeting the ``integration`` branch. + - If some module has no code owner, try to identify a suitable (non-code + owner) reviewer. Running ``git blame`` on the module's source code can + help, as it shows who has been working the most recently on this area of + the code. - - The changes will then undergo further review and testing by the - :ref:`code owners` and :ref:`maintainers`. Any review comments will be - made directly on your patch. This may require you to do some rework. For - controversial changes, the discussion might be moved to the `TF-A mailing - list`_ to involve more of the community. + Alternatively, if it is impractical to identify such a reviewer, you might + send an email to the `TF-A mailing list`_ to broadcast your review request + to the community. + + Note that self-reviewing a patch is prohibited, even if the patch author is + the only code owner of a module modified by the patch. Getting a second pair + of eyes on the code is essential to keep up with the quality standards the + project aspires to. + +- The changes will then undergo further review by the designated people. Any + review comments will be made directly on your patch. This may require you to + do some rework. For controversial changes, the discussion might be moved to + the `TF-A mailing list`_ to involve more of the community. Refer to the `Gerrit Uploading Changes documentation`_ for more details. +- The patch submission rules are the following. For a patch to be approved + and merged in the tree, it must get: + + - One ``Code-Owner-Review+1`` for each of the modules modified by the patch. + - A ``Maintainer-Review+1``. + + In the case where a code owner could not be found for a given module, + ``Code-Owner-Review+1`` is substituted by ``Code-Review+1``. + + In addition to these various code review labels, the patch must also get a + ``Verified+1``. This is usually set by the Continuous Integration (CI) bot + when all automated tests passed on the patch. Sometimes, some of these + automated tests may fail for reasons unrelated to the patch. In this case, + the maintainers might (after analysis of the failures) override the CI bot + score to certify that the patch has been correctly tested. + + In the event where the CI system lacks proper tests for a patch, the patch + author or a reviewer might agree to perform additional manual tests + in their review and the reviewer incorporates the review of the additional + testing in the ``Code-Review+1`` or ``Code-Owner-Review+1`` as applicable to + attest that the patch works as expected. Where possible additional tests should + be added to the CI system as a follow up task. For example, for a + platform-dependent patch where the said platform is not available in the CI + system's board farm. + - When the changes are accepted, the :ref:`maintainers` will integrate them. - Typically, the :ref:`maintainers` will merge the changes into the ``integration`` branch. + - If the changes are not based on a sufficiently-recent commit, or if they cannot be automatically rebased, then the :ref:`maintainers` may rebase it on the ``integration`` branch or ask you to do so. + - After final integration testing, the changes will make their way into the ``master`` branch. If a problem is found during integration, the :ref:`maintainers` will request your help to solve the issue. They may -- cgit v1.2.3 From a41973a9dae17d38980b2062f5452353e38855cc Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Wed, 10 Jun 2020 16:27:53 +0100 Subject: fdts: tc0: Add node for mmc The pl180 mmc uses 3.3V fixed regulator and vexpress sysreg for card detection and write protect. Change-Id: I2513cfcb97217e282a081a700f3a9f723e8207ff Signed-off-by: Usama Arif --- fdts/tc0.dts | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/fdts/tc0.dts b/fdts/tc0.dts index e736e4975..140f47f82 100644 --- a/fdts/tc0.dts +++ b/fdts/tc0.dts @@ -272,6 +272,35 @@ interrupts = <0 204 4>; }; + sysreg: sysreg@1c010000 { + compatible = "arm,vexpress-sysreg"; + reg = <0x0 0x001c010000 0x0 0x1000>; + gpio-controller; + #gpio-cells = <2>; + }; + + fixed_3v3: v2m-3v3 { + compatible = "regulator-fixed"; + regulator-name = "3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + mmci@1c050000 { + compatible = "arm,pl180", "arm,primecell"; + reg = <0x0 0x001c050000 0x0 0x1000>; + interrupts = <0 107 0x4>, + <0 108 0x4>; + cd-gpios = <&sysreg 0 0>; + wp-gpios = <&sysreg 1 0>; + bus-width = <8>; + max-frequency = <12000000>; + vmmc-supply = <&fixed_3v3>; + clocks = <&bp_clock24mhz>, <&bp_clock24mhz>; + clock-names = "mclk", "apb_pclk"; + }; + dp0: display@2cc00000 { #address-cells = <1>; #size-cells = <0>; -- cgit v1.2.3 From 8ea4f80a7cb49b1cbdb81561224916173c317b13 Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Wed, 12 Aug 2020 17:14:37 +0100 Subject: fdts: tc0: add support for cpu-idle-states This includes both cpu and cluster sleep parameters. Change-Id: I6a9e90b88508d6d2acd2538007cbbdd1cf976442 Signed-off-by: Usama Arif --- fdts/tc0.dts | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/fdts/tc0.dts b/fdts/tc0.dts index 140f47f82..cab39a770 100644 --- a/fdts/tc0.dts +++ b/fdts/tc0.dts @@ -41,12 +41,38 @@ }; }; + /* + * The timings below are just to demonstrate working cpuidle. + * These values may be inaccurate. + */ + idle-states { + entry-method = "arm,psci"; + + CPU_SLEEP_0: cpu-sleep-0 { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x0010000>; + local-timer-stop; + entry-latency-us = <300>; + exit-latency-us = <1200>; + min-residency-us = <2000>; + }; + CLUSTER_SLEEP_0: cluster-sleep-0 { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x1010000>; + local-timer-stop; + entry-latency-us = <400>; + exit-latency-us = <1200>; + min-residency-us = <2500>; + }; + }; + CPU0:cpu@0 { device_type = "cpu"; compatible = "arm,armv8"; reg = <0x0>; enable-method = "psci"; clocks = <&scmi_dvfs 0>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; }; CPU1:cpu@100 { @@ -55,6 +81,7 @@ reg = <0x100>; enable-method = "psci"; clocks = <&scmi_dvfs 0>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; }; CPU2:cpu@200 { @@ -63,6 +90,7 @@ reg = <0x200>; enable-method = "psci"; clocks = <&scmi_dvfs 0>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; }; CPU3:cpu@300 { @@ -71,6 +99,7 @@ reg = <0x300>; enable-method = "psci"; clocks = <&scmi_dvfs 0>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; }; }; -- cgit v1.2.3 From 9694c2104cd247aab0e6462e0bc6acabe808b470 Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Thu, 27 Aug 2020 16:30:44 -0700 Subject: qti: spmi_arb: Fix coverity integer conversion warnings Coverity warns about the risk of unintended sign-exension in some of the calculations in spmi_arb.c. While the actual numbers used are small enough that this cannot happen in practice, it's still a good idea to clean them up by explicitly making the constants used unsigned. Signed-off-by: Julius Werner Change-Id: Ia169e0f7c6b01b8041e8029e8c8d30ee596ba30d --- plat/qti/common/src/spmi_arb.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/plat/qti/common/src/spmi_arb.c b/plat/qti/common/src/spmi_arb.c index 81cc57729..16e85a6fc 100644 --- a/plat/qti/common/src/spmi_arb.c +++ b/plat/qti/common/src/spmi_arb.c @@ -10,17 +10,17 @@ #include -#define REG_APID_MAP(apid) (0x0C440900 + 4 * i) +#define REG_APID_MAP(apid) (0x0C440900U + 4U * i) #define NUM_APID 0x80 -#define PPID_MASK (0xfff << 8) +#define PPID_MASK (0xfffU << 8) -#define REG_ARB_CMD(apid) (0x0C600000 + 0x10000 * apid) +#define REG_ARB_CMD(apid) (0x0C600000U + 0x10000U * apid) /* These are opcodes specific to this SPMI arbitrator, *not* SPMI commands. */ #define OPC_EXT_WRITEL 0 #define OPC_EXT_READL 1 -#define REG_ARB_STATUS(apid) (0x0C600008 + 0x10000 * apid) +#define REG_ARB_STATUS(apid) (0x0C600008U + 0x10000U * apid) #define ARB_STATUS_DONE BIT(0) #define ARB_STATUS_FAILURE BIT(1) #define ARB_STATUS_DENIED BIT(2) @@ -29,8 +29,8 @@ /* Fake status to report driver errors. */ #define ARB_FAKE_STATUS_TIMEOUT BIT(8) -#define REG_ARB_RDATA0(apid) (0x0C600018 + 0x10000 * apid) -#define REG_ARB_WDATA0(apid) (0x0C600010 + 0x10000 * apid) +#define REG_ARB_RDATA0(apid) (0x0C600018U + 0x10000U * apid) +#define REG_ARB_WDATA0(apid) (0x0C600010U + 0x10000U * apid) static int addr_to_apid(uint32_t addr) { -- cgit v1.2.3 From 22e4f948bccd53a8b63013ceeed956fc22f9d1ac Mon Sep 17 00:00:00 2001 From: Kalyani Chidambaram Vaidyanathan Date: Wed, 2 Oct 2019 13:57:23 -0700 Subject: Tegra194: verify firewall settings before resource use The firewall settings for the hardware resources are present in the Security Configuration Registers. The firewall settings are programmed by other software components and so must be verified for correctness before touching the hardware resources they protect. This patch reads the firewall settings during early boot and asserts if the settings mismatch. Change-Id: I53cc9aeadad32e54e460db0fa2c38e46bcc92066 Signed-off-by: Kalyani Chidambaram Vaidyanathan Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/include/t194/tegra_def.h | 22 +++++++++++++++ plat/nvidia/tegra/soc/t194/plat_setup.c | 44 ++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/plat/nvidia/tegra/include/t194/tegra_def.h b/plat/nvidia/tegra/include/t194/tegra_def.h index e39f9cad6..6f44da619 100644 --- a/plat/nvidia/tegra/include/t194/tegra_def.h +++ b/plat/nvidia/tegra/include/t194/tegra_def.h @@ -294,4 +294,26 @@ #define TEGRA_SID_XUSB_VF2 U(0x5f) #define TEGRA_SID_XUSB_VF3 U(0x60) +/******************************************************************************* + * SCR addresses and expected settings + ******************************************************************************/ +#define SCRATCH_RSV68_SCR U(0x0C398110) +#define SCRATCH_RSV68_SCR_VAL U(0x38000101) +#define SCRATCH_RSV71_SCR U(0x0C39811C) +#define SCRATCH_RSV71_SCR_VAL U(0x38000101) +#define SCRATCH_RSV72_SCR U(0x0C398120) +#define SCRATCH_RSV72_SCR_VAL U(0x38000101) +#define SCRATCH_RSV75_SCR U(0x0C39812C) +#define SCRATCH_RSV75_SCR_VAL U(0x3A000005) +#define SCRATCH_RSV81_SCR U(0x0C398144) +#define SCRATCH_RSV81_SCR_VAL U(0x3A000105) +#define SCRATCH_RSV97_SCR U(0x0C398184) +#define SCRATCH_RSV97_SCR_VAL U(0x38000101) +#define SCRATCH_RSV99_SCR U(0x0C39818C) +#define SCRATCH_RSV99_SCR_VAL U(0x38000101) +#define SCRATCH_RSV109_SCR U(0x0C3981B4) +#define SCRATCH_RSV109_SCR_VAL U(0x38000101) +#define MISCREG_SCR_SCRTZWELCK U(0x00109000) +#define MISCREG_SCR_SCRTZWELCK_VAL U(0x30000100) + #endif /* TEGRA_DEF_H */ diff --git a/plat/nvidia/tegra/soc/t194/plat_setup.c b/plat/nvidia/tegra/soc/t194/plat_setup.c index c0f2fb017..cb3d6b449 100644 --- a/plat/nvidia/tegra/soc/t194/plat_setup.c +++ b/plat/nvidia/tegra/soc/t194/plat_setup.c @@ -31,6 +31,27 @@ /* ID for spe-console */ #define TEGRA_CONSOLE_SPE_ID 0xFE +/******************************************************************************* + * Structure to store the SCR addresses and its expected settings. + ******************************************************************************* + */ +typedef struct { + uint32_t scr_addr; + uint32_t scr_val; +} scr_settings_t; + +static const scr_settings_t t194_scr_settings[] = { + { SCRATCH_RSV68_SCR, SCRATCH_RSV68_SCR_VAL }, + { SCRATCH_RSV71_SCR, SCRATCH_RSV71_SCR_VAL }, + { SCRATCH_RSV72_SCR, SCRATCH_RSV72_SCR_VAL }, + { SCRATCH_RSV75_SCR, SCRATCH_RSV75_SCR_VAL }, + { SCRATCH_RSV81_SCR, SCRATCH_RSV81_SCR_VAL }, + { SCRATCH_RSV97_SCR, SCRATCH_RSV97_SCR_VAL }, + { SCRATCH_RSV99_SCR, SCRATCH_RSV99_SCR_VAL }, + { SCRATCH_RSV109_SCR, SCRATCH_RSV109_SCR_VAL }, + { MISCREG_SCR_SCRTZWELCK, MISCREG_SCR_SCRTZWELCK_VAL } +}; + /******************************************************************************* * The Tegra power domain tree has a single system level power domain i.e. a * single root node. The first entry in the power domain descriptor specifies @@ -196,6 +217,24 @@ void plat_enable_console(int32_t id) #endif } +/******************************************************************************* + * Verify SCR settings + ******************************************************************************/ +static inline bool tegra194_is_scr_valid(void) +{ + uint32_t scr_val; + bool ret = true; + + for (uint8_t i = 0U; i < ARRAY_SIZE(t194_scr_settings); i++) { + scr_val = mmio_read_32((uintptr_t)t194_scr_settings[i].scr_addr); + if (scr_val != t194_scr_settings[i].scr_val) { + ERROR("Mismatch at SCR addr = 0x%x\n", t194_scr_settings[i].scr_addr); + ret = false; + } + } + return ret; +} + /******************************************************************************* * Handler for early platform setup ******************************************************************************/ @@ -208,6 +247,11 @@ void plat_early_platform_setup(void) /* Verify chip id is t194 */ assert(tegra_chipid_is_t194()); + /* Verify SCR settings */ + if (tegra_platform_is_silicon()) { + assert(tegra194_is_scr_valid()); + } + /* sanity check MCE firmware compatibility */ mce_verify_firmware_version(); -- cgit v1.2.3 From e26810aab476783af4c45f8bebb89506aad30478 Mon Sep 17 00:00:00 2001 From: Kalyani Chidambaram Vaidyanathan Date: Thu, 7 Nov 2019 13:31:19 -0800 Subject: Tegra194: report failure to enable dual execution During boot the platform enables dual execution for Xavier CPUs. This patch reads back the ACTLR_ELx register to verify that the bit is actually set. It asserts if the bit is not set. Change-Id: I5ba9491ced86285d307b95efa647a427ff77c79e Signed-off-by: Kalyani Chidambaram Vaidyanathan --- plat/nvidia/tegra/soc/t194/plat_setup.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plat/nvidia/tegra/soc/t194/plat_setup.c b/plat/nvidia/tegra/soc/t194/plat_setup.c index cb3d6b449..bb1595a3a 100644 --- a/plat/nvidia/tegra/soc/t194/plat_setup.c +++ b/plat/nvidia/tegra/soc/t194/plat_setup.c @@ -314,14 +314,20 @@ void plat_early_platform_setup(void) actlr_elx = read_actlr_el3(); actlr_elx |= DENVER_CPU_ENABLE_DUAL_EXEC_EL3; write_actlr_el3(actlr_elx); + /* check if the bit is actually set */ + assert((read_actlr_el3() & DENVER_CPU_ENABLE_DUAL_EXEC_EL3) != 0ULL); actlr_elx = read_actlr_el2(); actlr_elx |= DENVER_CPU_ENABLE_DUAL_EXEC_EL2; write_actlr_el2(actlr_elx); + /* check if the bit is actually set */ + assert((read_actlr_el2() & DENVER_CPU_ENABLE_DUAL_EXEC_EL2) != 0ULL); actlr_elx = read_actlr_el1(); actlr_elx |= DENVER_CPU_ENABLE_DUAL_EXEC_EL1; write_actlr_el1(actlr_elx); + /* check if the bit is actually set */ + assert((read_actlr_el1() & DENVER_CPU_ENABLE_DUAL_EXEC_EL1) != 0ULL); } } -- cgit v1.2.3 From a69a11124b2ffcfa164ba3d0c034b8357746397b Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Mon, 18 Nov 2019 11:55:02 -0800 Subject: Tegra: remove unused cortex_a53.h This patch removes the unused cortex_a53.h header file from common Tegra files. This change fixes the violation of CERTC Rule: DCL23. Change-Id: Iaf7c34cc6323b78028258e188c00724c52afba85 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/aarch64/tegra_helpers.S | 5 +++-- plat/nvidia/tegra/common/tegra_bl31_setup.c | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S index bd2bebb40..64d21b49c 100644 --- a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S +++ b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S @@ -4,12 +4,13 @@ * * SPDX-License-Identifier: BSD-3-Clause */ + #include #include #include -#include -#include #include +#include + #include #include #include diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c index d5297ee0a..c8bce052a 100644 --- a/plat/nvidia/tegra/common/tegra_bl31_setup.c +++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3 From 2561cb50f163e8c47b02dc9d9e66405823045660 Mon Sep 17 00:00:00 2001 From: Anthony Zhou Date: Wed, 13 Nov 2019 18:36:07 +0800 Subject: Tegra194: add redundancy checks for MMIO writes MMIO writes should verify that the writes actually went through. Read the value back after the write operation, perform assert if the read back value is not same as the write value. Change-Id: Id2ceb014116f3aa6a9e86505ca1ae9911470a679 Signed-off-by: Anthony Zhou --- plat/nvidia/tegra/drivers/memctrl/memctrl_v2.c | 6 ++++++ plat/nvidia/tegra/include/drivers/memctrl_v2.h | 3 +++ plat/nvidia/tegra/soc/t194/plat_psci_handlers.c | 12 ++++++++++++ plat/nvidia/tegra/soc/t194/plat_secondary.c | 11 ++++++++++- plat/nvidia/tegra/soc/t194/plat_setup.c | 12 ++++++++++++ 5 files changed, 43 insertions(+), 1 deletion(-) diff --git a/plat/nvidia/tegra/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/drivers/memctrl/memctrl_v2.c index 4d69ccca3..95bdada11 100644 --- a/plat/nvidia/tegra/drivers/memctrl/memctrl_v2.c +++ b/plat/nvidia/tegra/drivers/memctrl/memctrl_v2.c @@ -80,6 +80,8 @@ void tegra_memctrl_setup(void) */ tegra_mc_write_32(MC_SMMU_BYPASS_CONFIG, MC_SMMU_BYPASS_CONFIG_SETTINGS); + assert(tegra_mc_read_32(MC_SMMU_BYPASS_CONFIG) + == MC_SMMU_BYPASS_CONFIG_SETTINGS); /* * Re-configure MSS to allow ROC to deal with ordering of the @@ -210,8 +212,12 @@ void tegra_mc_save_context(uint64_t mc_ctx_addr) /* save the MC table address */ mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_MC_TABLE_ADDR_LO, (uint32_t)mc_ctx_addr); + assert(mmio_read_32(TEGRA_SCRATCH_BASE + SCRATCH_MC_TABLE_ADDR_LO) + == (uint32_t)mc_ctx_addr); mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_MC_TABLE_ADDR_HI, (uint32_t)(mc_ctx_addr >> 32)); + assert(mmio_read_32(TEGRA_SCRATCH_BASE + SCRATCH_MC_TABLE_ADDR_HI) + == (uint32_t)(mc_ctx_addr >> 32)); } static void tegra_lock_videomem_nonoverlap(uint64_t phys_base, diff --git a/plat/nvidia/tegra/include/drivers/memctrl_v2.h b/plat/nvidia/tegra/include/drivers/memctrl_v2.h index e15762ba5..4239fea34 100644 --- a/plat/nvidia/tegra/include/drivers/memctrl_v2.h +++ b/plat/nvidia/tegra/include/drivers/memctrl_v2.h @@ -84,6 +84,8 @@ typedef struct mc_streamid_security_cfg { .override_enable = OVERRIDE_ ## access \ } +#include + typedef struct mc_regs { uint32_t reg; uint32_t val; @@ -153,6 +155,7 @@ static inline uint32_t tegra_mc_streamid_read_32(uint32_t off) static inline void tegra_mc_streamid_write_32(uint32_t off, uint32_t val) { mmio_write_32(TEGRA_MC_STREAMID_BASE + off, val); + assert(mmio_read_32(TEGRA_MC_STREAMID_BASE + off) == val); } #endif diff --git a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c index e226372ee..41a85ee7c 100644 --- a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c @@ -418,16 +418,28 @@ int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state) mmio_write_32(TEGRA_XUSB_PADCTL_BASE + XUSB_PADCTL_HOST_AXI_STREAMID_PF_0, TEGRA_SID_XUSB_HOST); + assert(mmio_read_32(TEGRA_XUSB_PADCTL_BASE + + XUSB_PADCTL_HOST_AXI_STREAMID_PF_0) == TEGRA_SID_XUSB_HOST); mmio_write_32(TEGRA_XUSB_PADCTL_BASE + XUSB_PADCTL_HOST_AXI_STREAMID_VF_0, TEGRA_SID_XUSB_VF0); + assert(mmio_read_32(TEGRA_XUSB_PADCTL_BASE + + XUSB_PADCTL_HOST_AXI_STREAMID_VF_0) == TEGRA_SID_XUSB_VF0); mmio_write_32(TEGRA_XUSB_PADCTL_BASE + XUSB_PADCTL_HOST_AXI_STREAMID_VF_1, TEGRA_SID_XUSB_VF1); + assert(mmio_read_32(TEGRA_XUSB_PADCTL_BASE + + XUSB_PADCTL_HOST_AXI_STREAMID_VF_1) == TEGRA_SID_XUSB_VF1); mmio_write_32(TEGRA_XUSB_PADCTL_BASE + XUSB_PADCTL_HOST_AXI_STREAMID_VF_2, TEGRA_SID_XUSB_VF2); + assert(mmio_read_32(TEGRA_XUSB_PADCTL_BASE + + XUSB_PADCTL_HOST_AXI_STREAMID_VF_2) == TEGRA_SID_XUSB_VF2); mmio_write_32(TEGRA_XUSB_PADCTL_BASE + XUSB_PADCTL_HOST_AXI_STREAMID_VF_3, TEGRA_SID_XUSB_VF3); + assert(mmio_read_32(TEGRA_XUSB_PADCTL_BASE + + XUSB_PADCTL_HOST_AXI_STREAMID_VF_3) == TEGRA_SID_XUSB_VF3); mmio_write_32(TEGRA_XUSB_PADCTL_BASE + XUSB_PADCTL_DEV_AXI_STREAMID_PF_0, TEGRA_SID_XUSB_DEV); + assert(mmio_read_32(TEGRA_XUSB_PADCTL_BASE + + XUSB_PADCTL_DEV_AXI_STREAMID_PF_0) == TEGRA_SID_XUSB_DEV); } } diff --git a/plat/nvidia/tegra/soc/t194/plat_secondary.c b/plat/nvidia/tegra/soc/t194/plat_secondary.c index 0882142a1..1cb14add0 100644 --- a/plat/nvidia/tegra/soc/t194/plat_secondary.c +++ b/plat/nvidia/tegra/soc/t194/plat_secondary.c @@ -4,11 +4,14 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include +#include + #include #include #include + #include -#include #include #include #include @@ -52,15 +55,21 @@ void plat_secondary_setup(void) /* write lower 32 bits first, then the upper 11 bits */ mmio_write_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_LOW, addr_low); + assert(mmio_read_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_LOW) == addr_low); mmio_write_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_HIGH, addr_high); + assert(mmio_read_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_HIGH) == addr_high); /* save reset vector to be used during SYSTEM_SUSPEND exit */ mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_LO, addr_low); + assert(mmio_read_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_LO) == addr_low); mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_HI, addr_high); + assert(mmio_read_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_HI) == addr_high); mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV72_LO, (uint32_t)tzdram_addr); + assert(mmio_read_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV72_LO) == (uint32_t)tzdram_addr); mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV72_HI, (uint32_t)src_len_bytes); + assert(mmio_read_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV72_HI) == (uint32_t)src_len_bytes); } diff --git a/plat/nvidia/tegra/soc/t194/plat_setup.c b/plat/nvidia/tegra/soc/t194/plat_setup.c index bb1595a3a..ba4b8dd73 100644 --- a/plat/nvidia/tegra/soc/t194/plat_setup.c +++ b/plat/nvidia/tegra/soc/t194/plat_setup.c @@ -295,16 +295,28 @@ void plat_early_platform_setup(void) mmio_write_32(TEGRA_XUSB_PADCTL_BASE + XUSB_PADCTL_HOST_AXI_STREAMID_PF_0, TEGRA_SID_XUSB_HOST); + assert(mmio_read_32(TEGRA_XUSB_PADCTL_BASE + + XUSB_PADCTL_HOST_AXI_STREAMID_PF_0) == TEGRA_SID_XUSB_HOST); mmio_write_32(TEGRA_XUSB_PADCTL_BASE + XUSB_PADCTL_HOST_AXI_STREAMID_VF_0, TEGRA_SID_XUSB_VF0); + assert(mmio_read_32(TEGRA_XUSB_PADCTL_BASE + + XUSB_PADCTL_HOST_AXI_STREAMID_VF_0) == TEGRA_SID_XUSB_VF0); mmio_write_32(TEGRA_XUSB_PADCTL_BASE + XUSB_PADCTL_HOST_AXI_STREAMID_VF_1, TEGRA_SID_XUSB_VF1); + assert(mmio_read_32(TEGRA_XUSB_PADCTL_BASE + + XUSB_PADCTL_HOST_AXI_STREAMID_VF_1) == TEGRA_SID_XUSB_VF1); mmio_write_32(TEGRA_XUSB_PADCTL_BASE + XUSB_PADCTL_HOST_AXI_STREAMID_VF_2, TEGRA_SID_XUSB_VF2); + assert(mmio_read_32(TEGRA_XUSB_PADCTL_BASE + + XUSB_PADCTL_HOST_AXI_STREAMID_VF_2) == TEGRA_SID_XUSB_VF2); mmio_write_32(TEGRA_XUSB_PADCTL_BASE + XUSB_PADCTL_HOST_AXI_STREAMID_VF_3, TEGRA_SID_XUSB_VF3); + assert(mmio_read_32(TEGRA_XUSB_PADCTL_BASE + + XUSB_PADCTL_HOST_AXI_STREAMID_VF_3) == TEGRA_SID_XUSB_VF3); mmio_write_32(TEGRA_XUSB_PADCTL_BASE + XUSB_PADCTL_DEV_AXI_STREAMID_PF_0, TEGRA_SID_XUSB_DEV); + assert(mmio_read_32(TEGRA_XUSB_PADCTL_BASE + + XUSB_PADCTL_DEV_AXI_STREAMID_PF_0) == TEGRA_SID_XUSB_DEV); } /* -- cgit v1.2.3 From e9b9c2c830f4f65a121876e00c61f3167501f5b7 Mon Sep 17 00:00:00 2001 From: Anthony Zhou Date: Wed, 4 Dec 2019 14:58:23 +0800 Subject: Tegra: sip: add VPR resize enabled check The Memory Controller provides a control register to check if the video memory can be resized. The previous bootloader might have locked this feature, which will be reflected by this register. This patch reads the control register before processing a video memory resize request. An error code, -ENOTSUP, is returned if the feature is locked. Change-Id: Ia1d67f7a94aa15c6b18ff5c9b9b952e179596ae3 Signed-off-by: Anthony Zhou --- plat/nvidia/tegra/common/tegra_sip_calls.c | 6 ++++++ plat/nvidia/tegra/drivers/memctrl/memctrl_v2.c | 17 ++++++++++++++++- plat/nvidia/tegra/include/t132/tegra_def.h | 2 ++ plat/nvidia/tegra/include/t186/tegra_def.h | 2 ++ plat/nvidia/tegra/include/t194/tegra_def.h | 2 ++ plat/nvidia/tegra/include/t210/tegra_def.h | 2 ++ 6 files changed, 30 insertions(+), 1 deletion(-) diff --git a/plat/nvidia/tegra/common/tegra_sip_calls.c b/plat/nvidia/tegra/common/tegra_sip_calls.c index 1d48cc01b..80a2c4d0c 100644 --- a/plat/nvidia/tegra/common/tegra_sip_calls.c +++ b/plat/nvidia/tegra/common/tegra_sip_calls.c @@ -52,6 +52,12 @@ uintptr_t tegra_sip_handler(uint32_t smc_fid, switch (smc_fid) { case TEGRA_SIP_NEW_VIDEOMEM_REGION: + /* Check whether Video memory resize is enabled */ + if (mmio_read_32(TEGRA_MC_BASE + MC_VIDEO_PROTECT_REG_CTRL) + != MC_VIDEO_PROTECT_WRITE_ACCESS_ENABLED) { + ERROR("Video Memory Resize isn't enabled! \n"); + SMC_RET1(handle, (uint64_t)-ENOTSUP); + } /* * Check if Video Memory overlaps TZDRAM (contains bl31/bl32) diff --git a/plat/nvidia/tegra/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/drivers/memctrl/memctrl_v2.c index 95bdada11..45c97fcc0 100644 --- a/plat/nvidia/tegra/drivers/memctrl/memctrl_v2.c +++ b/plat/nvidia/tegra/drivers/memctrl/memctrl_v2.c @@ -127,9 +127,16 @@ void tegra_memctrl_restore_settings(void) if (video_mem_base != 0ULL) { tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO, (uint32_t)video_mem_base); + assert(tegra_mc_read_32(MC_VIDEO_PROTECT_BASE_LO) + == (uint32_t)video_mem_base); tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI, (uint32_t)(video_mem_base >> 32)); - tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, video_mem_size_mb); + assert(tegra_mc_read_32(MC_VIDEO_PROTECT_BASE_HI) + == (uint32_t)(video_mem_base >> 32)); + tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, + (uint32_t)video_mem_size_mb); + assert(tegra_mc_read_32(MC_VIDEO_PROTECT_SIZE_MB) + == (uint32_t)video_mem_size_mb); /* * MCE propagates the VideoMem configuration values across the @@ -367,6 +374,14 @@ void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes) (uint32_t)(phys_base >> 32)); tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, size_in_bytes >> 20); + /* Redundancy check for Video Protect setting */ + assert(tegra_mc_read_32(MC_VIDEO_PROTECT_BASE_LO) + == (uint32_t)phys_base); + assert(tegra_mc_read_32(MC_VIDEO_PROTECT_BASE_HI) + == (uint32_t)(phys_base >> 32)); + assert(tegra_mc_read_32(MC_VIDEO_PROTECT_SIZE_MB) + == (size_in_bytes >> 20)); + /* * MCE propagates the VideoMem configuration values across the * CCPLEX. diff --git a/plat/nvidia/tegra/include/t132/tegra_def.h b/plat/nvidia/tegra/include/t132/tegra_def.h index 8e6c1fd2b..afdcd3691 100644 --- a/plat/nvidia/tegra/include/t132/tegra_def.h +++ b/plat/nvidia/tegra/include/t132/tegra_def.h @@ -104,6 +104,8 @@ #define MC_VIDEO_PROTECT_BASE_HI U(0x978) #define MC_VIDEO_PROTECT_BASE_LO U(0x648) #define MC_VIDEO_PROTECT_SIZE_MB U(0x64c) +#define MC_VIDEO_PROTECT_REG_CTRL U(0x650) +#define MC_VIDEO_PROTECT_WRITE_ACCESS_ENABLED U(3) /******************************************************************************* * Tegra TZRAM constants diff --git a/plat/nvidia/tegra/include/t186/tegra_def.h b/plat/nvidia/tegra/include/t186/tegra_def.h index 1da9b4639..33b21021b 100644 --- a/plat/nvidia/tegra/include/t186/tegra_def.h +++ b/plat/nvidia/tegra/include/t186/tegra_def.h @@ -163,6 +163,8 @@ #define MC_VIDEO_PROTECT_BASE_HI U(0x978) #define MC_VIDEO_PROTECT_BASE_LO U(0x648) #define MC_VIDEO_PROTECT_SIZE_MB U(0x64C) +#define MC_VIDEO_PROTECT_REG_CTRL U(0x650) +#define MC_VIDEO_PROTECT_WRITE_ACCESS_ENABLED U(3) /* * Carveout (MC_SECURITY_CARVEOUT24) registers used to clear the diff --git a/plat/nvidia/tegra/include/t194/tegra_def.h b/plat/nvidia/tegra/include/t194/tegra_def.h index 6f44da619..2d8b88c93 100644 --- a/plat/nvidia/tegra/include/t194/tegra_def.h +++ b/plat/nvidia/tegra/include/t194/tegra_def.h @@ -105,6 +105,8 @@ #define MC_VIDEO_PROTECT_BASE_HI U(0x978) #define MC_VIDEO_PROTECT_BASE_LO U(0x648) #define MC_VIDEO_PROTECT_SIZE_MB U(0x64c) +#define MC_VIDEO_PROTECT_REG_CTRL U(0x650) +#define MC_VIDEO_PROTECT_WRITE_ACCESS_ENABLED U(3) /* * Carveout (MC_SECURITY_CARVEOUT24) registers used to clear the diff --git a/plat/nvidia/tegra/include/t210/tegra_def.h b/plat/nvidia/tegra/include/t210/tegra_def.h index f3013a8a5..32fcb4bd8 100644 --- a/plat/nvidia/tegra/include/t210/tegra_def.h +++ b/plat/nvidia/tegra/include/t210/tegra_def.h @@ -240,6 +240,8 @@ #define MC_VIDEO_PROTECT_BASE_HI U(0x978) #define MC_VIDEO_PROTECT_BASE_LO U(0x648) #define MC_VIDEO_PROTECT_SIZE_MB U(0x64c) +#define MC_VIDEO_PROTECT_REG_CTRL U(0x650) +#define MC_VIDEO_PROTECT_WRITE_ACCESS_ENABLED U(3) /* SMMU configuration registers*/ #define MC_SMMU_PPCS_ASID_0 0x270U -- cgit v1.2.3 From 1740ed127574e0f6974fa4ff7e18d442c920ffd2 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Fri, 15 Nov 2019 15:46:14 -0800 Subject: Tegra194: add memory barriers during DRAM to SysRAM copy This patch adds memory barriers to the trampoline code copying TZDRAM contents to SysRAM during exit from System Suspend. These barriers make sure that all the copies go through before we start executing in SysRAM. Reported by: Nathan Tuck Change-Id: I3fd2964086b6c0e044cc4165051a4801440db9cd Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/soc/t194/plat_trampoline.S | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/plat/nvidia/tegra/soc/t194/plat_trampoline.S b/plat/nvidia/tegra/soc/t194/plat_trampoline.S index 819920f02..0ff5407e3 100644 --- a/plat/nvidia/tegra/soc/t194/plat_trampoline.S +++ b/plat/nvidia/tegra/soc/t194/plat_trampoline.S @@ -58,6 +58,13 @@ m_loop1: subs x2, x2, #1 b.ne m_loop1 + /* + * Synchronization barriers to make sure that memory is flushed out + * before we start execution in SysRAM. + */ + dsb sy + isb + boot_cpu: adr x0, __tegra194_cpu_reset_handler_data ldr x0, [x0] -- cgit v1.2.3 From 7581dc8958c79949b3e3d0a7897669b38d3f3e4a Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Wed, 26 Feb 2020 14:52:01 -0800 Subject: Tegra: platform specific GIC sources The TEGRA_GICv2_SOURCES contains the list of GIC sources required to compile the GICv2 support for platforms. This patch includes the TEGRA_GICv2_SOURCES macro from individual makefiles to allow future platforms to use suport for GICv3. Signed-off-by: Varun Wadekar Change-Id: I429b1a0c7764ab370675f873a50cecda871110cb --- plat/nvidia/tegra/common/tegra_common.mk | 2 +- plat/nvidia/tegra/soc/t132/platform_t132.mk | 5 +++-- plat/nvidia/tegra/soc/t186/platform_t186.mk | 3 ++- plat/nvidia/tegra/soc/t194/platform_t194.mk | 3 ++- plat/nvidia/tegra/soc/t210/platform_t210.mk | 3 ++- 5 files changed, 10 insertions(+), 6 deletions(-) diff --git a/plat/nvidia/tegra/common/tegra_common.mk b/plat/nvidia/tegra/common/tegra_common.mk index bb8bd7d89..136f82429 100644 --- a/plat/nvidia/tegra/common/tegra_common.mk +++ b/plat/nvidia/tegra/common/tegra_common.mk @@ -39,7 +39,7 @@ TEGRA_GICv3_SOURCES := drivers/arm/gic/common/gic_common.c \ BL31_SOURCES += drivers/delay_timer/delay_timer.c \ drivers/io/io_storage.c \ plat/common/aarch64/crash_console_helpers.S \ - ${TEGRA_GICv2_SOURCES} \ + ${TEGRA_LIBS}/debug/profiler.c \ ${TEGRA_COMMON}/aarch64/tegra_helpers.S \ ${TEGRA_LIBS}/debug/profiler.c \ ${TEGRA_COMMON}/tegra_bl31_setup.c \ diff --git a/plat/nvidia/tegra/soc/t132/platform_t132.mk b/plat/nvidia/tegra/soc/t132/platform_t132.mk index 3d76be9ed..9534c07b9 100644 --- a/plat/nvidia/tegra/soc/t132/platform_t132.mk +++ b/plat/nvidia/tegra/soc/t132/platform_t132.mk @@ -23,11 +23,12 @@ $(eval $(call add_define,MAX_MMAP_REGIONS)) # platform files PLAT_INCLUDES += -Iplat/nvidia/tegra/include/t132 -BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \ +BL31_SOURCES += ${TEGRA_GICv2_SOURCES} \ + drivers/ti/uart/aarch64/16550_console.S \ lib/cpus/aarch64/denver.S \ ${TEGRA_DRIVERS}/flowctrl/flowctrl.c \ ${TEGRA_DRIVERS}/memctrl/memctrl_v1.c \ - ${TEGRA_DRIVERS}/pmc/pmc.c \ + ${TEGRA_DRIVERS}/pmc/pmc.c \ ${SOC_DIR}/plat_psci_handlers.c \ ${SOC_DIR}/plat_sip_calls.c \ ${SOC_DIR}/plat_setup.c \ diff --git a/plat/nvidia/tegra/soc/t186/platform_t186.mk b/plat/nvidia/tegra/soc/t186/platform_t186.mk index 6739c50d1..5275b8e65 100644 --- a/plat/nvidia/tegra/soc/t186/platform_t186.mk +++ b/plat/nvidia/tegra/soc/t186/platform_t186.mk @@ -40,7 +40,8 @@ $(eval $(call add_define,MAX_MMAP_REGIONS)) PLAT_INCLUDES += -Iplat/nvidia/tegra/include/t186 \ -I${SOC_DIR}/drivers/include -BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \ +BL31_SOURCES += ${TEGRA_GICv2_SOURCES} \ + drivers/ti/uart/aarch64/16550_console.S \ lib/cpus/aarch64/denver.S \ lib/cpus/aarch64/cortex_a57.S \ ${TEGRA_DRIVERS}/bpmp_ipc/intf.c \ diff --git a/plat/nvidia/tegra/soc/t194/platform_t194.mk b/plat/nvidia/tegra/soc/t194/platform_t194.mk index 9705a7fe4..339375f83 100644 --- a/plat/nvidia/tegra/soc/t194/platform_t194.mk +++ b/plat/nvidia/tegra/soc/t194/platform_t194.mk @@ -38,7 +38,8 @@ RAS_EXTENSION := 1 PLAT_INCLUDES += -Iplat/nvidia/tegra/include/t194 \ -I${SOC_DIR}/drivers/include -BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \ +BL31_SOURCES += ${TEGRA_GICv2_SOURCES} \ + drivers/ti/uart/aarch64/16550_console.S \ lib/cpus/aarch64/denver.S \ ${TEGRA_DRIVERS}/bpmp_ipc/intf.c \ ${TEGRA_DRIVERS}/bpmp_ipc/ivc.c \ diff --git a/plat/nvidia/tegra/soc/t210/platform_t210.mk b/plat/nvidia/tegra/soc/t210/platform_t210.mk index 6c4c17510..724cfc3c0 100644 --- a/plat/nvidia/tegra/soc/t210/platform_t210.mk +++ b/plat/nvidia/tegra/soc/t210/platform_t210.mk @@ -28,7 +28,8 @@ ENABLE_TEGRA_WDT_LEGACY_FIQ_HANDLING := 1 PLAT_INCLUDES += -Iplat/nvidia/tegra/include/t210 \ -I${SOC_DIR}/drivers/se -BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \ +BL31_SOURCES += ${TEGRA_GICv2_SOURCES} \ + drivers/ti/uart/aarch64/16550_console.S \ lib/cpus/aarch64/cortex_a53.S \ lib/cpus/aarch64/cortex_a57.S \ ${TEGRA_DRIVERS}/bpmp/bpmp.c \ -- cgit v1.2.3 From ebd720d0b048409fcb8ab35342a1e3894b18d680 Mon Sep 17 00:00:00 2001 From: David Pu Date: Fri, 7 Jun 2019 15:30:17 -0700 Subject: Tegra194: ras: split up RAS error clear SMC call. In order to make sure SMC call is within 25us, this patch reduces number of RAS errors accessed to 8 at most for each SMC call and takes a input/output parameter to specify in progress RAS error record index. The measured SMC call latency is about 20us under Linux test kernel driver. Change-Id: Ia1b57c8673e0193dc341a36af0b5c09fb48f965f Signed-off-by: David Pu --- plat/nvidia/tegra/include/tegra_private.h | 2 +- plat/nvidia/tegra/soc/t194/plat_ras.c | 93 +++++++++++++++++++++++++++-- plat/nvidia/tegra/soc/t194/plat_sip_calls.c | 22 +++++-- 3 files changed, 107 insertions(+), 10 deletions(-) diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h index b638c818b..debd832fa 100644 --- a/plat/nvidia/tegra/include/tegra_private.h +++ b/plat/nvidia/tegra/include/tegra_private.h @@ -146,7 +146,7 @@ int plat_sip_handler(uint32_t smc_fid, #if RAS_EXTENSION void tegra194_ras_enable(void); -void tegra194_ras_corrected_err_clear(void); +void tegra194_ras_corrected_err_clear(uint64_t *cookie); #endif #endif /* TEGRA_PRIVATE_H */ diff --git a/plat/nvidia/tegra/soc/t194/plat_ras.c b/plat/nvidia/tegra/soc/t194/plat_ras.c index 54c2924c7..0c4c6fad6 100644 --- a/plat/nvidia/tegra/soc/t194/plat_ras.c +++ b/plat/nvidia/tegra/soc/t194/plat_ras.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -26,6 +27,17 @@ */ #define ERR_FR_EN_BITS_MASK 0xFFFFFFFF00000000ULL +/* + * Number of RAS errors will be cleared per 'tegra194_ras_corrected_err_clear' + * function call. + */ +#define RAS_ERRORS_PER_CALL 8 + +/* + * the max possible RAS node index value. + */ +#define RAS_NODE_INDEX_MAX 0x1FFFFFFFU + /* bakery lock for platform RAS handler. */ static DEFINE_BAKERY_LOCK(ras_handler_lock); #define ras_lock() bakery_lock_get(&ras_handler_lock) @@ -151,12 +163,41 @@ void tegra194_ras_enable(void) /* * Function to clear RAS ERRSTATUS for corrected RAS error. - * This function ignores any new RAS error signaled during clearing; it is not - * multi-core safe(no ras_lock is taken to reduce overhead). + * + * This function clears number of 'RAS_ERRORS_PER_CALL' RAS errors at most. + * 'cookie' - in/out cookie parameter to specify/store last visited RAS + * error record index. it is set to '0' to indicate no more RAS + * error record to clear. */ -void tegra194_ras_corrected_err_clear(void) +void tegra194_ras_corrected_err_clear(uint64_t *cookie) { + /* + * 'last_node' and 'last_idx' represent last visited RAS node index from + * previous function call. they are set to 0 when first smc call is made + * or all RAS error are visited by followed multipile smc calls. + */ + union prev_record { + struct record { + uint32_t last_node; + uint32_t last_idx; + } rec; + uint64_t value; + } prev; + uint64_t clear_ce_status = 0ULL; + int32_t nerrs_per_call = RAS_ERRORS_PER_CALL; + uint32_t i; + + if (cookie == NULL) { + return; + } + + prev.value = *cookie; + + if ((prev.rec.last_node >= RAS_NODE_INDEX_MAX) || + (prev.rec.last_idx >= RAS_NODE_INDEX_MAX)) { + return; + } ERR_STATUS_SET_FIELD(clear_ce_status, AV, 0x1UL); ERR_STATUS_SET_FIELD(clear_ce_status, V, 0x1UL); @@ -164,25 +205,56 @@ void tegra194_ras_corrected_err_clear(void) ERR_STATUS_SET_FIELD(clear_ce_status, MV, 0x1UL); ERR_STATUS_SET_FIELD(clear_ce_status, CE, 0x3UL); - for (uint32_t i = 0U; i < err_record_mappings.num_err_records; i++) { + + for (i = prev.rec.last_node; i < err_record_mappings.num_err_records; i++) { const struct err_record_info *info = &err_record_mappings.err_records[i]; uint32_t idx_start = info->sysreg.idx_start; uint32_t num_idx = info->sysreg.num_idx; - for (uint32_t j = 0U; j < num_idx; j++) { + uint32_t j; + + j = (i == prev.rec.last_node && prev.value != 0UL) ? + (prev.rec.last_idx + 1U) : 0U; + + for (; j < num_idx; j++) { uint64_t status; uint32_t err_idx = idx_start + j; + if (err_idx >= RAS_NODE_INDEX_MAX) { + return; + } + write_errselr_el1(err_idx); status = read_erxstatus_el1(); if (ERR_STATUS_GET_FIELD(status, CE) != 0U) { write_erxstatus_el1(clear_ce_status); } + + --nerrs_per_call; + + /* only clear 'nerrs_per_call' errors each time. */ + if (nerrs_per_call <= 0) { + prev.rec.last_idx = j; + prev.rec.last_node = i; + /* save last visited error record index + * into cookie. + */ + *cookie = prev.value; + + return; + } } } + + /* + * finish if all ras error records are checked or provided index is out + * of range. + */ + *cookie = 0ULL; + return; } /* Function to probe an error from error record group. */ @@ -330,18 +402,26 @@ CCPLEX_RAS_NODE_LIST(DEFINE_ONE_RAS_NODE) static struct ras_aux_data per_core_ras_group[] = { PER_CORE_RAS_GROUP_NODES }; +CASSERT(ARRAY_SIZE(per_core_ras_group) < RAS_NODE_INDEX_MAX, + assert_max_per_core_ras_group_size); static struct ras_aux_data per_cluster_ras_group[] = { PER_CLUSTER_RAS_GROUP_NODES }; +CASSERT(ARRAY_SIZE(per_cluster_ras_group) < RAS_NODE_INDEX_MAX, + assert_max_per_cluster_ras_group_size); static struct ras_aux_data scf_l3_ras_group[] = { SCF_L3_BANK_RAS_GROUP_NODES }; +CASSERT(ARRAY_SIZE(scf_l3_ras_group) < RAS_NODE_INDEX_MAX, + assert_max_scf_l3_ras_group_size); static struct ras_aux_data ccplex_ras_group[] = { CCPLEX_RAS_GROUP_NODES }; +CASSERT(ARRAY_SIZE(ccplex_ras_group) < RAS_NODE_INDEX_MAX, + assert_max_ccplex_ras_group_size); /* * We have same probe and handler for each error record group, use a macro to @@ -395,6 +475,9 @@ static struct err_record_info carmel_ras_records[] = { ADD_ONE_ERR_GROUP(0x400, ccplex_ras_group), }; +CASSERT(ARRAY_SIZE(carmel_ras_records) < RAS_NODE_INDEX_MAX, + assert_max_carmel_ras_records_size); + REGISTER_ERR_RECORD_INFO(carmel_ras_records); /* dummy RAS interrupt */ diff --git a/plat/nvidia/tegra/soc/t194/plat_sip_calls.c b/plat/nvidia/tegra/soc/t194/plat_sip_calls.c index a3f996d45..1eef55912 100644 --- a/plat/nvidia/tegra/soc/t194/plat_sip_calls.c +++ b/plat/nvidia/tegra/soc/t194/plat_sip_calls.c @@ -73,11 +73,25 @@ int32_t plat_sip_handler(uint32_t smc_fid, #if RAS_EXTENSION case TEGRA_SIP_CLEAR_RAS_CORRECTED_ERRORS: - /* clear all RAS error records for corrected errors at first. */ - tegra194_ras_corrected_err_clear(); - /* clear HSM corrected error status. */ - mce_clear_hsm_corr_status(); + { + /* + * clear all RAS error records for corrected errors at first. + * x1 shall be 0 for first SMC call after FHI is asserted. + * */ + uint64_t local_x1 = x1; + + tegra194_ras_corrected_err_clear(&local_x1); + if (local_x1 == 0ULL) { + /* clear HSM corrected error status after all corrected + * RAS errors are cleared. + */ + mce_clear_hsm_corr_status(); + } + + write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X1, local_x1); + break; + } #endif default: -- cgit v1.2.3 From 7e491133fcf8368a6ff202197f6fd81ac320538d Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Mon, 22 Apr 2019 16:12:30 -0700 Subject: Tegra194: memctrl: update TZDRAM base at 1MB granularity The Memory controller expects the TZDRAM base value at 1MB granularity and the current driver does not respect that limitation. This patch fixes that anomaly. Change-Id: I6b72270f331ba5081e19811df4a78623e457341a Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/soc/t194/plat_memctrl.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plat/nvidia/tegra/soc/t194/plat_memctrl.c b/plat/nvidia/tegra/soc/t194/plat_memctrl.c index 9a4d22e68..078c72ab9 100644 --- a/plat/nvidia/tegra/soc/t194/plat_memctrl.c +++ b/plat/nvidia/tegra/soc/t194/plat_memctrl.c @@ -447,6 +447,8 @@ tegra_mc_settings_t *tegra_get_mc_settings(void) void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes) { uint32_t sec_reg_ctrl = tegra_mc_read_32(MC_SECURITY_CFG_REG_CTRL_0); + uint32_t phys_base_lo = (uint32_t)phys_base & 0xFFF00000; + uint32_t phys_base_hi = (uint32_t)(phys_base >> 32); /* * Check TZDRAM carveout register access status. Setup TZDRAM fence @@ -461,8 +463,8 @@ void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes) */ INFO("Configuring TrustZone DRAM Memory Carveout\n"); - tegra_mc_write_32(MC_SECURITY_CFG0_0, (uint32_t)phys_base); - tegra_mc_write_32(MC_SECURITY_CFG3_0, (uint32_t)(phys_base >> 32)); + tegra_mc_write_32(MC_SECURITY_CFG0_0, phys_base_lo); + tegra_mc_write_32(MC_SECURITY_CFG3_0, phys_base_hi); tegra_mc_write_32(MC_SECURITY_CFG1_0, (uint32_t)(size_in_bytes >> 20)); /* -- cgit v1.2.3 From 5ce05d6b9d7e9fcf611353dd39bd6f5cfdcab6c1 Mon Sep 17 00:00:00 2001 From: Anthony Zhou Date: Wed, 5 Feb 2020 20:42:36 +0800 Subject: Tegra194: add strict checking mode verification After enabling the strict checking mode, verify that the strict mode has really been enabled by querying the MCE. If the mode is found to be disabled, the code should assert. Change-Id: I113ec8decb737f8208059a2a3ba3076fad77890e Signed-off-by: Anthony Zhou --- plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h | 2 ++ plat/nvidia/tegra/soc/t194/drivers/mce/mce.c | 9 +++++++++ plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c | 14 +++++++++++++- plat/nvidia/tegra/soc/t194/plat_setup.c | 1 + 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h b/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h index 6dafeb246..ef169808e 100644 --- a/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h +++ b/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h @@ -56,6 +56,7 @@ int32_t nvg_update_ccplex_gsc(uint32_t gsc_idx); int32_t nvg_enter_cstate(uint32_t state, uint32_t wake_time); int32_t nvg_roc_clean_cache_trbits(void); void nvg_enable_strict_checking_mode(void); +void nvg_verify_strict_checking_mode(void); void nvg_system_shutdown(void); void nvg_system_reboot(void); void nvg_clear_hsm_corr_status(void); @@ -70,6 +71,7 @@ uint64_t nvg_cache_inval_all(void); /* MCE helper functions */ void mce_enable_strict_checking(void); +void mce_verify_strict_checking(void); void mce_system_shutdown(void); void mce_system_reboot(void); void mce_clear_hsm_corr_status(void); diff --git a/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c b/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c index 4663a3d27..e3d5bd513 100644 --- a/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c +++ b/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c @@ -217,6 +217,15 @@ void mce_enable_strict_checking(void) nvg_enable_strict_checking_mode(); } } +void mce_verify_strict_checking(void) +{ + bool is_silicon = tegra_platform_is_silicon(); + bool is_fpga = tegra_platform_is_fpga(); + + if (is_silicon || is_fpga) { + nvg_verify_strict_checking_mode(); + } +} #endif /******************************************************************************* diff --git a/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c b/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c index fdf94292c..f76ab14a6 100644 --- a/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c +++ b/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c @@ -4,12 +4,15 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include +#include + #include #include #include #include -#include #include + #include #include #include @@ -211,6 +214,15 @@ void nvg_enable_strict_checking_mode(void) nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_SECURITY_CONFIG, params); } + +void nvg_verify_strict_checking_mode(void) +{ + uint64_t params = (uint64_t)(STRICT_CHECKING_ENABLED_SET | + STRICT_CHECKING_LOCKED_SET); + + nvg_set_request((uint64_t)TEGRA_NVG_CHANNEL_SECURITY_CONFIG); + assert(params == (uint64_t)nvg_get_result()); +} #endif /* diff --git a/plat/nvidia/tegra/soc/t194/plat_setup.c b/plat/nvidia/tegra/soc/t194/plat_setup.c index ba4b8dd73..41cc311d6 100644 --- a/plat/nvidia/tegra/soc/t194/plat_setup.c +++ b/plat/nvidia/tegra/soc/t194/plat_setup.c @@ -406,6 +406,7 @@ void plat_late_platform_setup(void) * enabling TZSRAM and TZDRAM */ mce_enable_strict_checking(); + mce_verify_strict_checking(); #endif } -- cgit v1.2.3 From 0ce729b1feea3fe0546ad062216ac871aa3596e4 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Wed, 11 Dec 2019 13:22:21 -0800 Subject: Tegra: debug prints indicating SC7 entry sequence completion This patch adds prints to display the completion of System Suspend programming sequence for Tegra platforms. The console needs to be kept alive until the very end of the System Suspend sequence as a result. Change-Id: I8e0e2054a272665d0a067bb894dda1605a9d2eb7 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/tegra_pm.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/plat/nvidia/tegra/common/tegra_pm.c b/plat/nvidia/tegra/common/tegra_pm.c index 6019182a1..d0191d07d 100644 --- a/plat/nvidia/tegra/common/tegra_pm.c +++ b/plat/nvidia/tegra/common/tegra_pm.c @@ -117,13 +117,6 @@ static void tegra_pwr_domain_suspend(const psci_power_state_t *target_state) { (void)tegra_soc_pwr_domain_suspend(target_state); - /* Disable console if we are entering deep sleep. */ - if (target_state->pwr_domain_state[PLAT_MAX_PWR_LVL] == - PSTATE_ID_SOC_POWERDN) { - (void)console_flush(); - console_switch_state(0); - } - /* disable GICC */ tegra_gic_cpuif_deactivate(); } @@ -138,6 +131,14 @@ static __dead2 void tegra_pwr_domain_power_down_wfi(const psci_power_state_t /* call the chip's power down handler */ (void)tegra_soc_pwr_domain_power_down_wfi(target_state); + /* Disable console if we are entering deep sleep. */ + if (target_state->pwr_domain_state[PLAT_MAX_PWR_LVL] == + PSTATE_ID_SOC_POWERDN) { + INFO("%s: complete. Entering System Suspend...\n", __func__); + (void)console_flush(); + console_switch_state(0); + } + wfi(); panic(); } -- cgit v1.2.3 From bdd61c16d56bf7907c16636a4d2861d06cfda5f4 Mon Sep 17 00:00:00 2001 From: Pritesh Raithatha Date: Sun, 28 Apr 2019 14:34:32 +0530 Subject: Tegra194: memctrl: remove streamid override cfg registers The stream ID override configuration is saved during System Suspend as part MB1 bct. This change removes the same support from the Tegra194 platform code as a result. Change-Id: I4c19dc0d8b29190908673fb5ed7ed892af8906ab Signed-off-by: Pritesh Raithatha --- plat/nvidia/tegra/soc/t194/plat_memctrl.c | 248 ------------------------------ 1 file changed, 248 deletions(-) diff --git a/plat/nvidia/tegra/soc/t194/plat_memctrl.c b/plat/nvidia/tegra/soc/t194/plat_memctrl.c index 078c72ab9..f92d40a60 100644 --- a/plat/nvidia/tegra/soc/t194/plat_memctrl.c +++ b/plat/nvidia/tegra/soc/t194/plat_memctrl.c @@ -160,254 +160,6 @@ const static mc_streamid_security_cfg_t tegra194_streamid_sec_cfgs[] = { ******************************************************************************/ static __attribute__((aligned(16))) mc_regs_t tegra194_mc_context[] = { _START_OF_TABLE_, - mc_make_sid_security_cfg(HDAR), - mc_make_sid_security_cfg(HOST1XDMAR), - mc_make_sid_security_cfg(NVENCSRD), - mc_make_sid_security_cfg(SATAR), - mc_make_sid_security_cfg(NVENCSWR), - mc_make_sid_security_cfg(HDAW), - mc_make_sid_security_cfg(SATAW), - mc_make_sid_security_cfg(ISPRA), - mc_make_sid_security_cfg(ISPFALR), - mc_make_sid_security_cfg(ISPWA), - mc_make_sid_security_cfg(ISPWB), - mc_make_sid_security_cfg(XUSB_HOSTR), - mc_make_sid_security_cfg(XUSB_HOSTW), - mc_make_sid_security_cfg(XUSB_DEVR), - mc_make_sid_security_cfg(XUSB_DEVW), - mc_make_sid_security_cfg(TSECSRD), - mc_make_sid_security_cfg(TSECSWR), - mc_make_sid_security_cfg(SDMMCRA), - mc_make_sid_security_cfg(SDMMCR), - mc_make_sid_security_cfg(SDMMCRAB), - mc_make_sid_security_cfg(SDMMCWA), - mc_make_sid_security_cfg(SDMMCW), - mc_make_sid_security_cfg(SDMMCWAB), - mc_make_sid_security_cfg(VICSRD), - mc_make_sid_security_cfg(VICSWR), - mc_make_sid_security_cfg(VIW), - mc_make_sid_security_cfg(NVDECSRD), - mc_make_sid_security_cfg(NVDECSWR), - mc_make_sid_security_cfg(APER), - mc_make_sid_security_cfg(APEW), - mc_make_sid_security_cfg(NVJPGSRD), - mc_make_sid_security_cfg(NVJPGSWR), - mc_make_sid_security_cfg(SESRD), - mc_make_sid_security_cfg(SESWR), - mc_make_sid_security_cfg(AXIAPR), - mc_make_sid_security_cfg(AXIAPW), - mc_make_sid_security_cfg(ETRR), - mc_make_sid_security_cfg(ETRW), - mc_make_sid_security_cfg(TSECSRDB), - mc_make_sid_security_cfg(TSECSWRB), - mc_make_sid_security_cfg(AXISR), - mc_make_sid_security_cfg(AXISW), - mc_make_sid_security_cfg(EQOSR), - mc_make_sid_security_cfg(EQOSW), - mc_make_sid_security_cfg(UFSHCR), - mc_make_sid_security_cfg(UFSHCW), - mc_make_sid_security_cfg(NVDISPLAYR), - mc_make_sid_security_cfg(BPMPR), - mc_make_sid_security_cfg(BPMPW), - mc_make_sid_security_cfg(BPMPDMAR), - mc_make_sid_security_cfg(BPMPDMAW), - mc_make_sid_security_cfg(AONR), - mc_make_sid_security_cfg(AONW), - mc_make_sid_security_cfg(AONDMAR), - mc_make_sid_security_cfg(AONDMAW), - mc_make_sid_security_cfg(SCER), - mc_make_sid_security_cfg(SCEW), - mc_make_sid_security_cfg(SCEDMAR), - mc_make_sid_security_cfg(SCEDMAW), - mc_make_sid_security_cfg(APEDMAR), - mc_make_sid_security_cfg(APEDMAW), - mc_make_sid_security_cfg(NVDISPLAYR1), - mc_make_sid_security_cfg(VICSRD1), - mc_make_sid_security_cfg(NVDECSRD1), - mc_make_sid_security_cfg(VIFALR), - mc_make_sid_security_cfg(VIFALW), - mc_make_sid_security_cfg(DLA0RDA), - mc_make_sid_security_cfg(DLA0FALRDB), - mc_make_sid_security_cfg(DLA0WRA), - mc_make_sid_security_cfg(DLA0FALWRB), - mc_make_sid_security_cfg(DLA1RDA), - mc_make_sid_security_cfg(DLA1FALRDB), - mc_make_sid_security_cfg(DLA1WRA), - mc_make_sid_security_cfg(DLA1FALWRB), - mc_make_sid_security_cfg(PVA0RDA), - mc_make_sid_security_cfg(PVA0RDB), - mc_make_sid_security_cfg(PVA0RDC), - mc_make_sid_security_cfg(PVA0WRA), - mc_make_sid_security_cfg(PVA0WRB), - mc_make_sid_security_cfg(PVA0WRC), - mc_make_sid_security_cfg(PVA1RDA), - mc_make_sid_security_cfg(PVA1RDB), - mc_make_sid_security_cfg(PVA1RDC), - mc_make_sid_security_cfg(PVA1WRA), - mc_make_sid_security_cfg(PVA1WRB), - mc_make_sid_security_cfg(PVA1WRC), - mc_make_sid_security_cfg(RCER), - mc_make_sid_security_cfg(RCEW), - mc_make_sid_security_cfg(RCEDMAR), - mc_make_sid_security_cfg(RCEDMAW), - mc_make_sid_security_cfg(NVENC1SRD), - mc_make_sid_security_cfg(NVENC1SWR), - mc_make_sid_security_cfg(PCIE0R), - mc_make_sid_security_cfg(PCIE0W), - mc_make_sid_security_cfg(PCIE1R), - mc_make_sid_security_cfg(PCIE1W), - mc_make_sid_security_cfg(PCIE2AR), - mc_make_sid_security_cfg(PCIE2AW), - mc_make_sid_security_cfg(PCIE3R), - mc_make_sid_security_cfg(PCIE3W), - mc_make_sid_security_cfg(PCIE4R), - mc_make_sid_security_cfg(PCIE4W), - mc_make_sid_security_cfg(PCIE5R), - mc_make_sid_security_cfg(PCIE5W), - mc_make_sid_security_cfg(ISPFALW), - mc_make_sid_security_cfg(DLA0RDA1), - mc_make_sid_security_cfg(DLA1RDA1), - mc_make_sid_security_cfg(PVA0RDA1), - mc_make_sid_security_cfg(PVA0RDB1), - mc_make_sid_security_cfg(PVA1RDA1), - mc_make_sid_security_cfg(PVA1RDB1), - mc_make_sid_security_cfg(PCIE5R1), - mc_make_sid_security_cfg(NVENCSRD1), - mc_make_sid_security_cfg(NVENC1SRD1), - mc_make_sid_security_cfg(ISPRA1), - mc_make_sid_security_cfg(PCIE0R1), - mc_make_sid_security_cfg(MIU0R), - mc_make_sid_security_cfg(MIU0W), - mc_make_sid_security_cfg(MIU1R), - mc_make_sid_security_cfg(MIU1W), - mc_make_sid_security_cfg(MIU2R), - mc_make_sid_security_cfg(MIU2W), - mc_make_sid_security_cfg(MIU3R), - mc_make_sid_security_cfg(MIU3W), - mc_make_sid_override_cfg(HDAR), - mc_make_sid_override_cfg(HOST1XDMAR), - mc_make_sid_override_cfg(NVENCSRD), - mc_make_sid_override_cfg(SATAR), - mc_make_sid_override_cfg(NVENCSWR), - mc_make_sid_override_cfg(HDAW), - mc_make_sid_override_cfg(SATAW), - mc_make_sid_override_cfg(ISPRA), - mc_make_sid_override_cfg(ISPFALR), - mc_make_sid_override_cfg(ISPWA), - mc_make_sid_override_cfg(ISPWB), - mc_make_sid_override_cfg(XUSB_HOSTR), - mc_make_sid_override_cfg(XUSB_HOSTW), - mc_make_sid_override_cfg(XUSB_DEVR), - mc_make_sid_override_cfg(XUSB_DEVW), - mc_make_sid_override_cfg(TSECSRD), - mc_make_sid_override_cfg(TSECSWR), - mc_make_sid_override_cfg(SDMMCRA), - mc_make_sid_override_cfg(SDMMCR), - mc_make_sid_override_cfg(SDMMCRAB), - mc_make_sid_override_cfg(SDMMCWA), - mc_make_sid_override_cfg(SDMMCW), - mc_make_sid_override_cfg(SDMMCWAB), - mc_make_sid_override_cfg(VICSRD), - mc_make_sid_override_cfg(VICSWR), - mc_make_sid_override_cfg(VIW), - mc_make_sid_override_cfg(NVDECSRD), - mc_make_sid_override_cfg(NVDECSWR), - mc_make_sid_override_cfg(APER), - mc_make_sid_override_cfg(APEW), - mc_make_sid_override_cfg(NVJPGSRD), - mc_make_sid_override_cfg(NVJPGSWR), - mc_make_sid_override_cfg(SESRD), - mc_make_sid_override_cfg(SESWR), - mc_make_sid_override_cfg(AXIAPR), - mc_make_sid_override_cfg(AXIAPW), - mc_make_sid_override_cfg(ETRR), - mc_make_sid_override_cfg(ETRW), - mc_make_sid_override_cfg(TSECSRDB), - mc_make_sid_override_cfg(TSECSWRB), - mc_make_sid_override_cfg(AXISR), - mc_make_sid_override_cfg(AXISW), - mc_make_sid_override_cfg(EQOSR), - mc_make_sid_override_cfg(EQOSW), - mc_make_sid_override_cfg(UFSHCR), - mc_make_sid_override_cfg(UFSHCW), - mc_make_sid_override_cfg(NVDISPLAYR), - mc_make_sid_override_cfg(BPMPR), - mc_make_sid_override_cfg(BPMPW), - mc_make_sid_override_cfg(BPMPDMAR), - mc_make_sid_override_cfg(BPMPDMAW), - mc_make_sid_override_cfg(AONR), - mc_make_sid_override_cfg(AONW), - mc_make_sid_override_cfg(AONDMAR), - mc_make_sid_override_cfg(AONDMAW), - mc_make_sid_override_cfg(SCER), - mc_make_sid_override_cfg(SCEW), - mc_make_sid_override_cfg(SCEDMAR), - mc_make_sid_override_cfg(SCEDMAW), - mc_make_sid_override_cfg(APEDMAR), - mc_make_sid_override_cfg(APEDMAW), - mc_make_sid_override_cfg(NVDISPLAYR1), - mc_make_sid_override_cfg(VICSRD1), - mc_make_sid_override_cfg(NVDECSRD1), - mc_make_sid_override_cfg(VIFALR), - mc_make_sid_override_cfg(VIFALW), - mc_make_sid_override_cfg(DLA0RDA), - mc_make_sid_override_cfg(DLA0FALRDB), - mc_make_sid_override_cfg(DLA0WRA), - mc_make_sid_override_cfg(DLA0FALWRB), - mc_make_sid_override_cfg(DLA1RDA), - mc_make_sid_override_cfg(DLA1FALRDB), - mc_make_sid_override_cfg(DLA1WRA), - mc_make_sid_override_cfg(DLA1FALWRB), - mc_make_sid_override_cfg(PVA0RDA), - mc_make_sid_override_cfg(PVA0RDB), - mc_make_sid_override_cfg(PVA0RDC), - mc_make_sid_override_cfg(PVA0WRA), - mc_make_sid_override_cfg(PVA0WRB), - mc_make_sid_override_cfg(PVA0WRC), - mc_make_sid_override_cfg(PVA1RDA), - mc_make_sid_override_cfg(PVA1RDB), - mc_make_sid_override_cfg(PVA1RDC), - mc_make_sid_override_cfg(PVA1WRA), - mc_make_sid_override_cfg(PVA1WRB), - mc_make_sid_override_cfg(PVA1WRC), - mc_make_sid_override_cfg(RCER), - mc_make_sid_override_cfg(RCEW), - mc_make_sid_override_cfg(RCEDMAR), - mc_make_sid_override_cfg(RCEDMAW), - mc_make_sid_override_cfg(NVENC1SRD), - mc_make_sid_override_cfg(NVENC1SWR), - mc_make_sid_override_cfg(PCIE0R), - mc_make_sid_override_cfg(PCIE0W), - mc_make_sid_override_cfg(PCIE1R), - mc_make_sid_override_cfg(PCIE1W), - mc_make_sid_override_cfg(PCIE2AR), - mc_make_sid_override_cfg(PCIE2AW), - mc_make_sid_override_cfg(PCIE3R), - mc_make_sid_override_cfg(PCIE3W), - mc_make_sid_override_cfg(PCIE4R), - mc_make_sid_override_cfg(PCIE4W), - mc_make_sid_override_cfg(PCIE5R), - mc_make_sid_override_cfg(PCIE5W), - mc_make_sid_override_cfg(ISPFALW), - mc_make_sid_override_cfg(DLA0RDA1), - mc_make_sid_override_cfg(DLA1RDA1), - mc_make_sid_override_cfg(PVA0RDA1), - mc_make_sid_override_cfg(PVA0RDB1), - mc_make_sid_override_cfg(PVA1RDA1), - mc_make_sid_override_cfg(PVA1RDB1), - mc_make_sid_override_cfg(PCIE5R1), - mc_make_sid_override_cfg(NVENCSRD1), - mc_make_sid_override_cfg(NVENC1SRD1), - mc_make_sid_override_cfg(ISPRA1), - mc_make_sid_override_cfg(PCIE0R1), - mc_make_sid_override_cfg(MIU0R), - mc_make_sid_override_cfg(MIU0W), - mc_make_sid_override_cfg(MIU1R), - mc_make_sid_override_cfg(MIU1W), - mc_make_sid_override_cfg(MIU2R), - mc_make_sid_override_cfg(MIU2W), - mc_make_sid_override_cfg(MIU3R), - mc_make_sid_override_cfg(MIU3W), mc_smmu_bypass_cfg, /* TBU settings */ _END_OF_TABLE_, }; -- cgit v1.2.3 From 872a1c52b8030ef724e861cc0b76079497b6a076 Mon Sep 17 00:00:00 2001 From: Pritesh Raithatha Date: Thu, 11 Apr 2019 16:47:53 +0530 Subject: Tegra194: memctrl: remove streamid security cfg registers The stream ID security configuration settings shall be done by the previous level bootloader. This change removes the same settings from the Tegra194 platform code as a result. Change-Id: Ia170ca4c2119db8f1d0251f1c193add006f81004 Signed-off-by: Pritesh Raithatha --- plat/nvidia/tegra/soc/t194/plat_memctrl.c | 146 ------------------------------ 1 file changed, 146 deletions(-) diff --git a/plat/nvidia/tegra/soc/t194/plat_memctrl.c b/plat/nvidia/tegra/soc/t194/plat_memctrl.c index f92d40a60..f223f7ba2 100644 --- a/plat/nvidia/tegra/soc/t194/plat_memctrl.c +++ b/plat/nvidia/tegra/soc/t194/plat_memctrl.c @@ -11,150 +11,6 @@ #include #include -/******************************************************************************* - * Array to hold the security configs for stream IDs - ******************************************************************************/ -const static mc_streamid_security_cfg_t tegra194_streamid_sec_cfgs[] = { - mc_make_sec_cfg(PTCR, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(HDAR, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(HOST1XDMAR, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(NVENCSRD, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(SATAR, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(MPCORER, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(NVENCSWR, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(HDAW, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(MPCOREW, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(SATAW, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(ISPRA, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(ISPFALR, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(ISPWA, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(ISPWB, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(XUSB_HOSTR, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(XUSB_HOSTW, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(XUSB_DEVR, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(XUSB_DEVW, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(TSECSRD, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(TSECSWR, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(SDMMCRA, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(SDMMCR, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(SDMMCRAB, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(SDMMCWA, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(SDMMCW, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(SDMMCWAB, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(VICSRD, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(VICSWR, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(VIW, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(NVDECSRD, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(NVDECSWR, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(APER, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(APEW, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(NVJPGSRD, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(NVJPGSWR, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(SESRD, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(SESWR, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(AXIAPR, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(AXIAPW, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(ETRR, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(ETRW, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(TSECSRDB, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(TSECSWRB, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(AXISR, SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(AXISW, SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(EQOSR, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(EQOSW, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(UFSHCR, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(UFSHCW, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(NVDISPLAYR, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(BPMPR, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(BPMPW, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(BPMPDMAR, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(BPMPDMAW, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(AONR, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(AONW, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(AONDMAR, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(AONDMAW, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(SCER, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(SCEW, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(SCEDMAR, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(SCEDMAW, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(APEDMAR, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(APEDMAW, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(NVDISPLAYR1, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(VICSRD1, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(NVDECSRD1, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(VIFALR, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(VIFALW, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(DLA0RDA, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(DLA0FALRDB, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(DLA0WRA, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(DLA0FALWRB, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(DLA1RDA, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(DLA1FALRDB, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(DLA1WRA, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(DLA1FALWRB, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(PVA0RDA, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(PVA0RDB, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(PVA0RDC, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(PVA0WRA, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(PVA0WRB, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(PVA0WRC, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(PVA1RDA, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(PVA1RDB, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(PVA1RDC, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(PVA1WRA, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(PVA1WRB, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(PVA1WRC, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(RCER, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(RCEW, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(RCEDMAR, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(RCEDMAW, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(NVENC1SRD, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(NVENC1SWR, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(PCIE0R, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(PCIE0W, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(PCIE1R, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(PCIE1W, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(PCIE2AR, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(PCIE2AW, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(PCIE3R, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(PCIE3W, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(PCIE4R, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(PCIE4W, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(PCIE5R, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(PCIE5W, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(ISPFALW, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(DLA0RDA1, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(DLA1RDA1, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(PVA0RDA1, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(PVA0RDB1, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(PVA1RDA1, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(PVA1RDB1, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(PCIE5R1, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(NVENCSRD1, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(NVENC1SRD1, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(ISPRA1, NON_SECURE, NO_OVERRIDE, ENABLE), - mc_make_sec_cfg(PCIE0R1, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(NVDEC1SRD, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(NVDEC1SRD1, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(NVDEC1SWR, NON_SECURE, NO_OVERRIDE, DISABLE), - mc_make_sec_cfg(MIU0R, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(MIU0W, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(MIU1R, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(MIU1W, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(MIU2R, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(MIU2W, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(MIU3R, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(MIU3W, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(MIU4R, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(MIU4W, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(MIU5R, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(MIU5W, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(MIU6R, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(MIU6W, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(MIU7R, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(MIU7W, NON_SECURE, OVERRIDE, DISABLE) -}; - /******************************************************************************* * Array to hold MC context for Tegra194 ******************************************************************************/ @@ -179,8 +35,6 @@ static mc_regs_t *tegra194_get_mc_system_suspend_ctx(void) * Struct to hold the memory controller settings ******************************************************************************/ static tegra_mc_settings_t tegra194_mc_settings = { - .streamid_security_cfg = tegra194_streamid_sec_cfgs, - .num_streamid_security_cfgs = (uint32_t)ARRAY_SIZE(tegra194_streamid_sec_cfgs), .get_mc_system_suspend_ctx = tegra194_get_mc_system_suspend_ctx }; -- cgit v1.2.3 From 08e60f803ff1bf4c6b96848544ed428681439f8e Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Mon, 26 Aug 2019 10:20:53 -0700 Subject: Tegra: memctrl: platform setup handler functions The driver initially contained the setup steps to help Tegra186 and Tegra194 SoCs. In order to support future SoCs and make sure that the driver remains generic enough, some code should be moved to SoC. This patch creates a setup handler for a platform to implement its initialization sequence. Change-Id: I8bab7fd07f25e0457ead8e2d2713efe54782a59b Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/drivers/memctrl/memctrl_v2.c | 71 ++---------- plat/nvidia/tegra/include/drivers/memctrl_v2.h | 143 +++---------------------- plat/nvidia/tegra/include/t186/tegra_mc_def.h | 115 +++++++++++++++++++- plat/nvidia/tegra/include/tegra_private.h | 5 + plat/nvidia/tegra/soc/t186/plat_memctrl.c | 77 +++++++------ plat/nvidia/tegra/soc/t194/plat_memctrl.c | 18 ++-- 6 files changed, 194 insertions(+), 235 deletions(-) diff --git a/plat/nvidia/tegra/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/drivers/memctrl/memctrl_v2.c index 45c97fcc0..92120b527 100644 --- a/plat/nvidia/tegra/drivers/memctrl/memctrl_v2.c +++ b/plat/nvidia/tegra/drivers/memctrl/memctrl_v2.c @@ -32,38 +32,13 @@ static uint64_t video_mem_size_mb; */ void tegra_memctrl_setup(void) { - uint32_t val; - const uint32_t *mc_streamid_override_regs; - uint32_t num_streamid_override_regs; - const mc_streamid_security_cfg_t *mc_streamid_sec_cfgs; - uint32_t num_streamid_sec_cfgs; - const tegra_mc_settings_t *plat_mc_settings = tegra_get_mc_settings(); - uint32_t i; - INFO("Tegra Memory Controller (v2)\n"); - /* Program the SMMU pagesize */ + /* Initialize the System memory management unit */ tegra_smmu_init(); - /* Get the settings from the platform */ - assert(plat_mc_settings != NULL); - mc_streamid_override_regs = plat_mc_settings->streamid_override_cfg; - num_streamid_override_regs = plat_mc_settings->num_streamid_override_cfgs; - mc_streamid_sec_cfgs = plat_mc_settings->streamid_security_cfg; - num_streamid_sec_cfgs = plat_mc_settings->num_streamid_security_cfgs; - - /* Program all the Stream ID overrides */ - for (i = 0; i < num_streamid_override_regs; i++) - tegra_mc_streamid_write_32(mc_streamid_override_regs[i], - MC_STREAM_ID_MAX); - - /* Program the security config settings for all Stream IDs */ - for (i = 0; i < num_streamid_sec_cfgs; i++) { - val = mc_streamid_sec_cfgs[i].override_enable << 16 | - mc_streamid_sec_cfgs[i].override_client_inputs << 8 | - mc_streamid_sec_cfgs[i].override_client_ns_flag << 0; - tegra_mc_streamid_write_32(mc_streamid_sec_cfgs[i].offset, val); - } + /* allow platforms to program custom memory controller settings */ + plat_memctrl_setup(); /* * All requests at boot time, and certain requests during @@ -80,23 +55,6 @@ void tegra_memctrl_setup(void) */ tegra_mc_write_32(MC_SMMU_BYPASS_CONFIG, MC_SMMU_BYPASS_CONFIG_SETTINGS); - assert(tegra_mc_read_32(MC_SMMU_BYPASS_CONFIG) - == MC_SMMU_BYPASS_CONFIG_SETTINGS); - - /* - * Re-configure MSS to allow ROC to deal with ordering of the - * Memory Controller traffic. This is needed as the Memory Controller - * boots with MSS having all control, but ROC provides a performance - * boost as compared to MSS. - */ - if (plat_mc_settings->reconfig_mss_clients != NULL) { - plat_mc_settings->reconfig_mss_clients(); - } - - /* Program overrides for MC transactions */ - if (plat_mc_settings->set_txn_overrides != NULL) { - plat_mc_settings->set_txn_overrides(); - } } /* @@ -104,24 +62,8 @@ void tegra_memctrl_setup(void) */ void tegra_memctrl_restore_settings(void) { - const tegra_mc_settings_t *plat_mc_settings = tegra_get_mc_settings(); - - assert(plat_mc_settings != NULL); - - /* - * Re-configure MSS to allow ROC to deal with ordering of the - * Memory Controller traffic. This is needed as the Memory Controller - * resets during System Suspend with MSS having all control, but ROC - * provides a performance boost as compared to MSS. - */ - if (plat_mc_settings->reconfig_mss_clients != NULL) { - plat_mc_settings->reconfig_mss_clients(); - } - - /* Program overrides for MC transactions */ - if (plat_mc_settings->set_txn_overrides != NULL) { - plat_mc_settings->set_txn_overrides(); - } + /* restore platform's memory controller settings */ + plat_memctrl_restore(); /* video memory carveout region */ if (video_mem_base != 0ULL) { @@ -176,7 +118,6 @@ void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes) */ void tegra_mc_save_context(uint64_t mc_ctx_addr) { - const tegra_mc_settings_t *plat_mc_settings = tegra_get_mc_settings(); uint32_t i, num_entries = 0; mc_regs_t *mc_ctx_regs; const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); @@ -186,7 +127,7 @@ void tegra_mc_save_context(uint64_t mc_ctx_addr) assert((mc_ctx_addr >= tzdram_base) && (mc_ctx_addr <= tzdram_end)); /* get MC context table */ - mc_ctx_regs = plat_mc_settings->get_mc_system_suspend_ctx(); + mc_ctx_regs = plat_memctrl_get_sys_suspend_ctx(); assert(mc_ctx_regs != NULL); /* diff --git a/plat/nvidia/tegra/include/drivers/memctrl_v2.h b/plat/nvidia/tegra/include/drivers/memctrl_v2.h index 4239fea34..1e153063a 100644 --- a/plat/nvidia/tegra/include/drivers/memctrl_v2.h +++ b/plat/nvidia/tegra/include/drivers/memctrl_v2.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,58 +8,9 @@ #ifndef MEMCTRL_V2_H #define MEMCTRL_V2_H -#include - -#ifndef __ASSEMBLER__ - -#include -#include - -/******************************************************************************* - * Structure to hold the transaction override settings to use to override - * client inputs - ******************************************************************************/ -typedef struct mc_txn_override_cfg { - uint32_t offset; - uint8_t cgid_tag; -} mc_txn_override_cfg_t; - -#define mc_make_txn_override_cfg(off, val) \ - { \ - .offset = MC_TXN_OVERRIDE_CONFIG_ ## off, \ - .cgid_tag = MC_TXN_OVERRIDE_ ## val \ - } - -/******************************************************************************* - * Structure to hold the Stream ID to use to override client inputs - ******************************************************************************/ -typedef struct mc_streamid_override_cfg { - uint32_t offset; - uint8_t stream_id; -} mc_streamid_override_cfg_t; +#include -/******************************************************************************* - * Structure to hold the Stream ID Security Configuration settings - ******************************************************************************/ -typedef struct mc_streamid_security_cfg { - char *name; - uint32_t offset; - int override_enable; - int override_client_inputs; - int override_client_ns_flag; -} mc_streamid_security_cfg_t; - -#define OVERRIDE_DISABLE 1U -#define OVERRIDE_ENABLE 0U -#define CLIENT_FLAG_SECURE 0U -#define CLIENT_FLAG_NON_SECURE 1U -#define CLIENT_INPUTS_OVERRIDE 1U -#define CLIENT_INPUTS_NO_OVERRIDE 0U -/******************************************************************************* - * StreamID to indicate no SMMU translations (requests to be steered on the - * SMMU bypass path) - ******************************************************************************/ -#define MC_STREAM_ID_MAX 0x7FU +#include /******************************************************************************* * Memory Controller SMMU Bypass config register @@ -74,15 +26,7 @@ typedef struct mc_streamid_security_cfg { #define MC_SMMU_BYPASS_CONFIG_SETTINGS (MC_SMMU_BYPASS_CONFIG_WRITE_ACCESS_BIT | \ MC_SMMU_CTRL_TBU_BYPASS_SPL_STREAMID) -#define mc_make_sec_cfg(off, ns, ovrrd, access) \ - { \ - .name = # off, \ - .offset = MC_STREAMID_OVERRIDE_TO_SECURITY_CFG( \ - MC_STREAMID_OVERRIDE_CFG_ ## off), \ - .override_client_ns_flag = CLIENT_FLAG_ ## ns, \ - .override_client_inputs = CLIENT_INPUTS_ ## ovrrd, \ - .override_enable = OVERRIDE_ ## access \ - } +#ifndef __ASSEMBLY__ #include @@ -91,18 +35,6 @@ typedef struct mc_regs { uint32_t val; } mc_regs_t; -#define mc_make_sid_override_cfg(name) \ - { \ - .reg = TEGRA_MC_STREAMID_BASE + MC_STREAMID_OVERRIDE_CFG_ ## name, \ - .val = 0x00000000U, \ - } - -#define mc_make_sid_security_cfg(name) \ - { \ - .reg = TEGRA_MC_STREAMID_BASE + MC_STREAMID_OVERRIDE_TO_SECURITY_CFG(MC_STREAMID_OVERRIDE_CFG_ ## name), \ - .val = 0x00000000U, \ - } - #define mc_smmu_bypass_cfg \ { \ .reg = TEGRA_MC_BASE + MC_SMMU_BYPASS_CONFIG, \ @@ -121,20 +53,11 @@ typedef struct mc_regs { .val = 0xFFFFFFFFU, \ } -/******************************************************************************* - * Structure to hold Memory Controller's Configuration settings - ******************************************************************************/ -typedef struct tegra_mc_settings { - const uint32_t *streamid_override_cfg; - uint32_t num_streamid_override_cfgs; - const mc_streamid_security_cfg_t *streamid_security_cfg; - uint32_t num_streamid_security_cfgs; - const mc_txn_override_cfg_t *txn_override_cfg; - uint32_t num_txn_override_cfgs; - void (*reconfig_mss_clients)(void); - void (*set_txn_overrides)(void); - mc_regs_t* (*get_mc_system_suspend_ctx)(void); -} tegra_mc_settings_t; +#endif /* __ASSEMBLY__ */ + +#ifndef __ASSEMBLY__ + +#include static inline uint32_t tegra_mc_read_32(uint32_t off) { @@ -159,52 +82,10 @@ static inline void tegra_mc_streamid_write_32(uint32_t off, uint32_t val) } #endif -#define mc_set_pcfifo_unordered_boot_so_mss(id, client) \ - ((uint32_t)~MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_MASK | \ - MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_UNORDERED) - -#define mc_set_pcfifo_ordered_boot_so_mss(id, client) \ - MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_ORDERED - -#define mc_set_tsa_passthrough(client) \ - { \ - mmio_write_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSW_##client, \ - (TSA_CONFIG_STATIC0_CSW_##client##_RESET & \ - (uint32_t)~TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK) | \ - (uint32_t)TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU); \ - } +void plat_memctrl_setup(void); -#define mc_set_tsa_w_passthrough(client) \ - { \ - mmio_write_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSW_##client, \ - (TSA_CONFIG_STATIC0_CSW_RESET_W & \ - (uint32_t)~TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK) | \ - (uint32_t)TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU); \ - } - -#define mc_set_tsa_r_passthrough(client) \ - { \ - mmio_write_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSR_##client, \ - (TSA_CONFIG_STATIC0_CSR_RESET_R & \ - (uint32_t)~TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK) | \ - (uint32_t)TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU); \ - } - -#define mc_set_txn_override(client, normal_axi_id, so_dev_axi_id, normal_override, so_dev_override) \ - { \ - tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_##client, \ - MC_TXN_OVERRIDE_##normal_axi_id | \ - MC_TXN_OVERRIDE_CONFIG_COH_PATH_##so_dev_override##_SO_DEV | \ - MC_TXN_OVERRIDE_CONFIG_COH_PATH_##normal_override##_NORMAL | \ - MC_TXN_OVERRIDE_CONFIG_CGID_##so_dev_axi_id); \ - } - -/******************************************************************************* - * Handler to read memory configuration settings - * - * Implemented by SoCs under tegra/soc/txxx - ******************************************************************************/ -tegra_mc_settings_t *tegra_get_mc_settings(void); +void plat_memctrl_restore(void); +mc_regs_t *plat_memctrl_get_sys_suspend_ctx(void); /******************************************************************************* * Handler to save MC settings before "System Suspend" to TZDRAM diff --git a/plat/nvidia/tegra/include/t186/tegra_mc_def.h b/plat/nvidia/tegra/include/t186/tegra_mc_def.h index d051a150a..398453eb9 100644 --- a/plat/nvidia/tegra/include/t186/tegra_mc_def.h +++ b/plat/nvidia/tegra/include/t186/tegra_mc_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -282,4 +282,117 @@ #define MC_CLIENT_HOTRESET_CTRL1_SCE_FLUSH_ENB (1U << 24) #define MC_CLIENT_HOTRESET_STATUS1 0x974U +#ifndef __ASSEMBLY__ + +/******************************************************************************* + * Structure to hold the transaction override settings to use to override + * client inputs + ******************************************************************************/ +typedef struct mc_txn_override_cfg { + uint32_t offset; + uint8_t cgid_tag; +} mc_txn_override_cfg_t; + +#define mc_make_txn_override_cfg(off, val) \ + { \ + .offset = MC_TXN_OVERRIDE_CONFIG_ ## off, \ + .cgid_tag = MC_TXN_OVERRIDE_ ## val \ + } + +/******************************************************************************* + * Structure to hold the Stream ID to use to override client inputs + ******************************************************************************/ +typedef struct mc_streamid_override_cfg { + uint32_t offset; + uint8_t stream_id; +} mc_streamid_override_cfg_t; + +/******************************************************************************* + * Structure to hold the Stream ID Security Configuration settings + ******************************************************************************/ +typedef struct mc_streamid_security_cfg { + char *name; + uint32_t offset; + uint32_t override_enable; + uint32_t override_client_inputs; + uint32_t override_client_ns_flag; +} mc_streamid_security_cfg_t; + +#define OVERRIDE_DISABLE 1U +#define OVERRIDE_ENABLE 0U +#define CLIENT_FLAG_SECURE 0U +#define CLIENT_FLAG_NON_SECURE 1U +#define CLIENT_INPUTS_OVERRIDE 1U +#define CLIENT_INPUTS_NO_OVERRIDE 0U + +/******************************************************************************* + * StreamID to indicate no SMMU translations (requests to be steered on the + * SMMU bypass path) + ******************************************************************************/ +#define MC_STREAM_ID_MAX 0x7FU + +#define mc_make_sec_cfg(off, ns, ovrrd, access) \ + { \ + .name = # off, \ + .offset = MC_STREAMID_OVERRIDE_TO_SECURITY_CFG( \ + MC_STREAMID_OVERRIDE_CFG_ ## off), \ + .override_client_ns_flag = CLIENT_FLAG_ ## ns, \ + .override_client_inputs = CLIENT_INPUTS_ ## ovrrd, \ + .override_enable = OVERRIDE_ ## access \ + } + +#define mc_make_sid_override_cfg(name) \ + { \ + .reg = TEGRA_MC_STREAMID_BASE + MC_STREAMID_OVERRIDE_CFG_ ## name, \ + .val = 0x00000000U, \ + } + +#define mc_make_sid_security_cfg(name) \ + { \ + .reg = TEGRA_MC_STREAMID_BASE + MC_STREAMID_OVERRIDE_TO_SECURITY_CFG(MC_STREAMID_OVERRIDE_CFG_ ## name), \ + .val = 0x00000000U, \ + } + +#define mc_set_pcfifo_unordered_boot_so_mss(id, client) \ + ((uint32_t)~MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_MASK | \ + MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_UNORDERED) + +#define mc_set_pcfifo_ordered_boot_so_mss(id, client) \ + MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_ORDERED + +#define mc_set_tsa_passthrough(client) \ + do { \ + mmio_write_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSW_##client, \ + (TSA_CONFIG_STATIC0_CSW_##client##_RESET & \ + (uint32_t)~TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK) | \ + (uint32_t)TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU); \ + } while (0) + +#define mc_set_tsa_w_passthrough(client) \ + do { \ + mmio_write_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSW_##client, \ + (TSA_CONFIG_STATIC0_CSW_RESET_W & \ + (uint32_t)~TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK) | \ + (uint32_t)TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU); \ + } while (0) + +#define mc_set_tsa_r_passthrough(client) \ + { \ + mmio_write_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSR_##client, \ + (TSA_CONFIG_STATIC0_CSR_RESET_R & \ + (uint32_t)~TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK) | \ + (uint32_t)TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU); \ + } while (0) + +#define mc_set_txn_override(client, normal_axi_id, so_dev_axi_id, normal_override, so_dev_override) \ + do { \ + tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_##client, \ + MC_TXN_OVERRIDE_##normal_axi_id | \ + MC_TXN_OVERRIDE_CONFIG_COH_PATH_##so_dev_override##_SO_DEV | \ + MC_TXN_OVERRIDE_CONFIG_COH_PATH_##normal_override##_NORMAL | \ + MC_TXN_OVERRIDE_CONFIG_CGID_##so_dev_axi_id); \ + } while (0) + +#endif /* __ASSEMBLY__ */ + #endif /* TEGRA_MC_DEF_H */ diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h index debd832fa..f1a4948f9 100644 --- a/plat/nvidia/tegra/include/tegra_private.h +++ b/plat/nvidia/tegra/include/tegra_private.h @@ -68,6 +68,11 @@ struct tegra_bl31_params { image_info_t *bl33_image_info; }; +/******************************************************************************* +* To suppress Coverity MISRA C-2012 Rule 2.2 violations +*******************************************************************************/ +#define UNUSED_FUNC_NOP() asm("nop") + /* Declarations for plat_psci_handlers.c */ int32_t tegra_soc_validate_power_state(uint32_t power_state, psci_power_state_t *req_state); diff --git a/plat/nvidia/tegra/soc/t186/plat_memctrl.c b/plat/nvidia/tegra/soc/t186/plat_memctrl.c index 4eb68e44a..81de674bc 100644 --- a/plat/nvidia/tegra/soc/t186/plat_memctrl.c +++ b/plat/nvidia/tegra/soc/t186/plat_memctrl.c @@ -402,16 +402,8 @@ static void tegra186_memctrl_reconfig_mss_clients(void) static void tegra186_memctrl_set_overrides(void) { - const tegra_mc_settings_t *plat_mc_settings = tegra_get_mc_settings(); - const mc_txn_override_cfg_t *mc_txn_override_cfgs; - uint32_t num_txn_override_cfgs; uint32_t i, val; - /* Get the settings from the platform */ - assert(plat_mc_settings != NULL); - mc_txn_override_cfgs = plat_mc_settings->txn_override_cfg; - num_txn_override_cfgs = plat_mc_settings->num_txn_override_cfgs; - /* * Set the MC_TXN_OVERRIDE registers for write clients. */ @@ -443,11 +435,11 @@ static void tegra186_memctrl_set_overrides(void) /* * Settings for Tegra186 silicon rev. A02 and onwards. */ - for (i = 0; i < num_txn_override_cfgs; i++) { - val = tegra_mc_read_32(mc_txn_override_cfgs[i].offset); + for (i = 0; i < ARRAY_SIZE(tegra186_txn_override_cfgs); i++) { + val = tegra_mc_read_32(tegra186_txn_override_cfgs[i].offset); val &= (uint32_t)~MC_TXN_OVERRIDE_CGID_TAG_MASK; - tegra_mc_write_32(mc_txn_override_cfgs[i].offset, - val | mc_txn_override_cfgs[i].cgid_tag); + tegra_mc_write_32(tegra186_txn_override_cfgs[i].offset, + val | tegra186_txn_override_cfgs[i].cgid_tag); } } } @@ -609,7 +601,7 @@ static __attribute__((aligned(16))) mc_regs_t tegra186_mc_context[] = { /******************************************************************************* * Handler to return the pointer to the MC's context struct ******************************************************************************/ -static mc_regs_t *tegra186_get_mc_system_suspend_ctx(void) +mc_regs_t *plat_memctrl_get_sys_suspend_ctx(void) { /* index of _END_OF_TABLE_ */ tegra186_mc_context[0].val = (uint32_t)(ARRAY_SIZE(tegra186_mc_context)) - 1U; @@ -617,27 +609,52 @@ static mc_regs_t *tegra186_get_mc_system_suspend_ctx(void) return tegra186_mc_context; } -/******************************************************************************* - * Struct to hold the memory controller settings - ******************************************************************************/ -static tegra_mc_settings_t tegra186_mc_settings = { - .streamid_override_cfg = tegra186_streamid_override_regs, - .num_streamid_override_cfgs = (uint32_t)ARRAY_SIZE(tegra186_streamid_override_regs), - .streamid_security_cfg = tegra186_streamid_sec_cfgs, - .num_streamid_security_cfgs = (uint32_t)ARRAY_SIZE(tegra186_streamid_sec_cfgs), - .txn_override_cfg = tegra186_txn_override_cfgs, - .num_txn_override_cfgs = (uint32_t)ARRAY_SIZE(tegra186_txn_override_cfgs), - .reconfig_mss_clients = tegra186_memctrl_reconfig_mss_clients, - .set_txn_overrides = tegra186_memctrl_set_overrides, - .get_mc_system_suspend_ctx = tegra186_get_mc_system_suspend_ctx, -}; +void plat_memctrl_setup(void) +{ + uint32_t val; + unsigned int i; + + /* Program all the Stream ID overrides */ + for (i = 0U; i < ARRAY_SIZE(tegra186_streamid_override_regs); i++) { + tegra_mc_streamid_write_32(tegra186_streamid_override_regs[i], + MC_STREAM_ID_MAX); + } + + /* Program the security config settings for all Stream IDs */ + for (i = 0U; i < ARRAY_SIZE(tegra186_streamid_sec_cfgs); i++) { + val = (tegra186_streamid_sec_cfgs[i].override_enable << 16) | + (tegra186_streamid_sec_cfgs[i].override_client_inputs << 8) | + (tegra186_streamid_sec_cfgs[i].override_client_ns_flag << 0); + tegra_mc_streamid_write_32(tegra186_streamid_sec_cfgs[i].offset, val); + } + + /* + * Re-configure MSS to allow ROC to deal with ordering of the + * Memory Controller traffic. This is needed as the Memory Controller + * boots with MSS having all control, but ROC provides a performance + * boost as compared to MSS. + */ + tegra186_memctrl_reconfig_mss_clients(); + + /* Program overrides for MC transactions */ + tegra186_memctrl_set_overrides(); +} /******************************************************************************* - * Handler to return the pointer to the memory controller's settings struct + * Handler to restore platform specific settings to the memory controller ******************************************************************************/ -tegra_mc_settings_t *tegra_get_mc_settings(void) +void plat_memctrl_restore(void) { - return &tegra186_mc_settings; + /* + * Re-configure MSS to allow ROC to deal with ordering of the + * Memory Controller traffic. This is needed as the Memory Controller + * boots with MSS having all control, but ROC provides a performance + * boost as compared to MSS. + */ + tegra186_memctrl_reconfig_mss_clients(); + + /* Program overrides for MC transactions */ + tegra186_memctrl_set_overrides(); } /******************************************************************************* diff --git a/plat/nvidia/tegra/soc/t194/plat_memctrl.c b/plat/nvidia/tegra/soc/t194/plat_memctrl.c index f223f7ba2..d6226b486 100644 --- a/plat/nvidia/tegra/soc/t194/plat_memctrl.c +++ b/plat/nvidia/tegra/soc/t194/plat_memctrl.c @@ -10,6 +10,7 @@ #include #include #include +#include /******************************************************************************* * Array to hold MC context for Tegra194 @@ -23,7 +24,7 @@ static __attribute__((aligned(16))) mc_regs_t tegra194_mc_context[] = { /******************************************************************************* * Handler to return the pointer to the MC's context struct ******************************************************************************/ -static mc_regs_t *tegra194_get_mc_system_suspend_ctx(void) +mc_regs_t *plat_memctrl_get_sys_suspend_ctx(void) { /* index of _END_OF_TABLE_ */ tegra194_mc_context[0].val = (uint32_t)ARRAY_SIZE(tegra194_mc_context) - 1U; @@ -32,18 +33,19 @@ static mc_regs_t *tegra194_get_mc_system_suspend_ctx(void) } /******************************************************************************* - * Struct to hold the memory controller settings + * Handler to restore platform specific settings to the memory controller ******************************************************************************/ -static tegra_mc_settings_t tegra194_mc_settings = { - .get_mc_system_suspend_ctx = tegra194_get_mc_system_suspend_ctx -}; +void plat_memctrl_restore(void) +{ + UNUSED_FUNC_NOP(); /* do nothing */ +} /******************************************************************************* - * Handler to return the pointer to the memory controller's settings struct + * Handler to program platform specific settings to the memory controller ******************************************************************************/ -tegra_mc_settings_t *tegra_get_mc_settings(void) +void plat_memctrl_setup(void) { - return &tegra194_mc_settings; + UNUSED_FUNC_NOP(); /* do nothing */ } /******************************************************************************* -- cgit v1.2.3 From 837df4856c6185079c9c7a69974b050084c4b560 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Thu, 24 Oct 2019 15:02:11 -0700 Subject: Tegra194: remove unused tegra_mc_defs header This patch removes the unused header from the Tegra194 platform files. As a result, the TSA MMIO would be removed from the memory map too. Change-Id: I2d38b3da7a119f5dfd6cfd429e481f4e6ad3481e Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/include/t194/tegra_mc_def.h | 685 -------------------------- plat/nvidia/tegra/soc/t194/plat_memctrl.c | 1 - plat/nvidia/tegra/soc/t194/plat_setup.c | 3 - 3 files changed, 689 deletions(-) delete mode 100644 plat/nvidia/tegra/include/t194/tegra_mc_def.h diff --git a/plat/nvidia/tegra/include/t194/tegra_mc_def.h b/plat/nvidia/tegra/include/t194/tegra_mc_def.h deleted file mode 100644 index 34bdd7557..000000000 --- a/plat/nvidia/tegra/include/t194/tegra_mc_def.h +++ /dev/null @@ -1,685 +0,0 @@ -/* - * Copyright (c) 2019-2020, NVIDIA Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef TEGRA_MC_DEF_H -#define TEGRA_MC_DEF_H - -/******************************************************************************* - * Memory Controller Order_id registers - ******************************************************************************/ -#define MC_CLIENT_ORDER_ID_9 U(0x2a24) -#define MC_CLIENT_ORDER_ID_9_RESET_VAL 0x00000000U -#define MC_CLIENT_ORDER_ID_9_XUSB_HOSTW_MASK (0x3U << 12) -#define MC_CLIENT_ORDER_ID_9_XUSB_HOSTW_ORDER_ID (3U << 12) - -#define MC_CLIENT_ORDER_ID_27 U(0x2a6c) -#define MC_CLIENT_ORDER_ID_27_RESET_VAL 0x00000000U -#define MC_CLIENT_ORDER_ID_27_PCIE0W_MASK (0x3U << 4) -#define MC_CLIENT_ORDER_ID_27_PCIE0W_ORDER_ID (2U << 4) - -#define MC_CLIENT_ORDER_ID_28 U(0x2a70) -#define MC_CLIENT_ORDER_ID_28_RESET_VAL 0x00000000U -#define MC_CLIENT_ORDER_ID_28_PCIE4W_MASK (0x3U << 4) -#define MC_CLIENT_ORDER_ID_28_PCIE4W_ORDER_ID (3U << 4) -#define MC_CLIENT_ORDER_ID_28_PCIE5W_MASK (0x3U << 12) -#define MC_CLIENT_ORDER_ID_28_PCIE5W_ORDER_ID (1U << 12) - -#define mc_client_order_id(val, id, client) \ - ((val & ~MC_CLIENT_ORDER_ID_##id##_##client##_MASK) | \ - MC_CLIENT_ORDER_ID_##id##_##client##_ORDER_ID) - -/******************************************************************************* - * Memory Controller's VC ID configuration registers - ******************************************************************************/ -#define VC_NISO 0U -#define VC_SISO 1U -#define VC_ISO 2U - -#define MC_HUB_PC_VC_ID_0 U(0x2a78) -#define MC_HUB_PC_VC_ID_0_RESET_VAL 0x00020100U -#define MC_HUB_PC_VC_ID_0_APB_VC_ID_MASK (0x3U << 8) -#define MC_HUB_PC_VC_ID_0_APB_VC_ID (VC_NISO << 8) - -#define MC_HUB_PC_VC_ID_2 U(0x2a80) -#define MC_HUB_PC_VC_ID_2_RESET_VAL 0x10001000U -#define MC_HUB_PC_VC_ID_2_SD_VC_ID_MASK (0x3U << 28) -#define MC_HUB_PC_VC_ID_2_SD_VC_ID (VC_NISO << 28) - -#define MC_HUB_PC_VC_ID_4 U(0x2a88) -#define MC_HUB_PC_VC_ID_4_RESET_VAL 0x10020011U -#define MC_HUB_PC_VC_ID_4_NIC_VC_ID_MASK (0x3U << 28) -#define MC_HUB_PC_VC_ID_4_NIC_VC_ID (VC_NISO << 28) - -#define MC_HUB_PC_VC_ID_12 U(0x2aa8) -#define MC_HUB_PC_VC_ID_12_RESET_VAL 0x11001011U -#define MC_HUB_PC_VC_ID_12_UFSHCPC2_VC_ID_MASK (0x3U << 12) -#define MC_HUB_PC_VC_ID_12_UFSHCPC2_VC_ID (VC_NISO << 12) - -#define mc_hub_vc_id(val, id, client) \ - ((val & ~MC_HUB_PC_VC_ID_##id##_##client##_VC_ID_MASK) | \ - MC_HUB_PC_VC_ID_##id##_##client##_VC_ID) - -/******************************************************************************* - * Memory Controller's PCFIFO client configuration registers - ******************************************************************************/ -#define MC_PCFIFO_CLIENT_CONFIG0 0xdd0U - -#define MC_PCFIFO_CLIENT_CONFIG1 0xdd4U -#define MC_PCFIFO_CLIENT_CONFIG1_RESET_VAL 0x20200000U -#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_AFIW_UNORDERED (0U << 17) -#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_AFIW_MASK (1U << 17) -#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_HDAW_UNORDERED (0U << 21) -#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_HDAW_MASK (1U << 21) -#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_UNORDERED (0U << 29) -#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_ORDERED (1U << 29) -#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_MASK (1U << 29) - -#define MC_PCFIFO_CLIENT_CONFIG2 0xdd8U -#define MC_PCFIFO_CLIENT_CONFIG2_RESET_VAL 0x00002800U -#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_HOSTW_UNORDERED (0U << 11) -#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_HOSTW_MASK (1U << 11) -#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_UNORDERED (0U << 13) -#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_ORDERED (1U << 13) -#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_MASK (1U << 13) -#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_TSECSWR_UNORDERED (0U << 21) -#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_TSECSWR_MASK (1U << 21) - -#define MC_PCFIFO_CLIENT_CONFIG3 0xddcU -#define MC_PCFIFO_CLIENT_CONFIG3_RESET_VAL 0x08000080U -#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWA_UNORDERED (0U << 4) -#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWA_MASK (1U << 4) -#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCW_UNORDERED (0U << 6) -#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCW_MASK (1U << 6) -#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_UNORDERED (0U << 7) -#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_MASK (1U << 7) -#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_VICSWR_UNORDERED (0U << 13) -#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_VICSWR_MASK (1U << 13) -#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_APEW_UNORDERED (0U << 27) -#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_APEW_MASK (1U << 27) - -#define MC_PCFIFO_CLIENT_CONFIG4 0xde0U -#define MC_PCFIFO_CLIENT_CONFIG4_RESET_VAL 0x5552a022U -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SESWR_UNORDERED (0U << 1) -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SESWR_MASK (1U << 1) -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_ETRW_UNORDERED (0U << 5) -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_ETRW_MASK (1U << 5) -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_TSECSWRB_UNORDERED (0U << 7) -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_TSECSWRB_MASK (1U << 7) -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AXISW_UNORDERED (0U << 13) -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AXISW_MASK (1U << 13) -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_UNORDERED (0U << 15) -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_MASK (1U << 15) -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_UFSHCW_UNORDERED (0U << 17) -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_UFSHCW_MASK (1U << 17) -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPW_UNORDERED (0U << 20) -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPW_MASK (1U << 20) -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_UNORDERED (0U << 22) -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_MASK (1U << 22) -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONW_UNORDERED (0U << 24) -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONW_MASK (1U << 24) -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONDMAW_UNORDERED (0U << 26) -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONDMAW_MASK (1U << 26) -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEW_UNORDERED (0U << 28) -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEW_MASK (1U << 28) -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEDMAW_UNORDERED (0U << 30) -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEDMAW_MASK (1U << 30) - -#define MC_PCFIFO_CLIENT_CONFIG5 0xbf4U -#define MC_PCFIFO_CLIENT_CONFIG5_RESET_VAL 0x20000001U -#define MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_UNORDERED (0U << 0) -#define MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_MASK (1U << 0) -#define MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_VIFALW_UNORDERED (0U << 30) -#define MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_VIFALW_MASK (1U << 30) - -#define MC_PCFIFO_CLIENT_CONFIG6 0xb90U -#define MC_PCFIFO_CLIENT_CONFIG6_RESET_VAL 0xaa280000U -#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_RCEW_UNORDERED (0U << 19) -#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_RCEW_MASK (1U << 19) -#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_RCEDMAW_UNORDERED (0U << 21) -#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_RCEDMAW_MASK (1U << 21) -#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE0W_UNORDERED (0U << 25) -#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE0W_MASK (1U << 25) -#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE1W_ORDERED (1U << 27) -#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE1W_MASK (1U << 27) -#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE2W_ORDERED (1U << 29) -#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE2W_MASK (1U << 29) -#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE3W_ORDERED (1U << 31) -#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE3W_MASK (1U << 31) - -#define MC_PCFIFO_CLIENT_CONFIG7 0xaccU -#define MC_PCFIFO_CLIENT_CONFIG7_RESET_VAL 0x0000000aU -#define MC_PCFIFO_CLIENT_CONFIG7_PCFIFO_PCIE4W_UNORDERED (0U << 1) -#define MC_PCFIFO_CLIENT_CONFIG7_PCFIFO_PCIE4W_MASK (1U << 1) -#define MC_PCFIFO_CLIENT_CONFIG7_PCFIFO_PCIE5W_UNORDERED (0U << 3) -#define MC_PCFIFO_CLIENT_CONFIG7_PCFIFO_PCIE5W_MASK (1U << 3) - -/******************************************************************************* - * StreamID to indicate no SMMU translations (requests to be steered on the - * SMMU bypass path) - ******************************************************************************/ -#define MC_STREAM_ID_MAX 0x7FU - -/******************************************************************************* - * Stream ID Override Config registers - ******************************************************************************/ -#define MC_STREAMID_OVERRIDE_CFG_PVA1RDA 0x660U -#define MC_STREAMID_OVERRIDE_CFG_NVENCSRD 0xe0U -#define MC_STREAMID_OVERRIDE_CFG_NVJPGSWR 0x3f8U -#define MC_STREAMID_OVERRIDE_CFG_PVA0RDA1 0x758U -#define MC_STREAMID_OVERRIDE_CFG_PVA0RDC 0x640U -#define MC_STREAMID_OVERRIDE_CFG_DLA0RDA 0x5f0U -#define MC_STREAMID_OVERRIDE_CFG_BPMPR 0x498U -#define MC_STREAMID_OVERRIDE_CFG_APEDMAR 0x4f8U -#define MC_STREAMID_OVERRIDE_CFG_AXISR 0x460U -#define MC_STREAMID_OVERRIDE_CFG_TSECSRD 0x2a0U -#define MC_STREAMID_OVERRIDE_CFG_DLA0FALRDB 0x5f8U -#define MC_STREAMID_OVERRIDE_CFG_NVENC1SRD1 0x788U -#define MC_STREAMID_OVERRIDE_CFG_MPCOREW 0x1c8U -#define MC_STREAMID_OVERRIDE_CFG_NVENCSRD1 0x780U -#define MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTR 0x250U -#define MC_STREAMID_OVERRIDE_CFG_MIU1R 0x540U -#define MC_STREAMID_OVERRIDE_CFG_MIU0R 0x530U -#define MC_STREAMID_OVERRIDE_CFG_PCIE1W 0x6d8U -#define MC_STREAMID_OVERRIDE_CFG_PVA1WRA 0x678U -#define MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTW 0x258U -#define MC_STREAMID_OVERRIDE_CFG_AXIAPW 0x418U -#define MC_STREAMID_OVERRIDE_CFG_SDMMCWAB 0x338U -#define MC_STREAMID_OVERRIDE_CFG_SATAW 0x1e8U -#define MC_STREAMID_OVERRIDE_CFG_DLA0WRA 0x600U -#define MC_STREAMID_OVERRIDE_CFG_PCIE3R 0x6f0U -#define MC_STREAMID_OVERRIDE_CFG_MIU3W 0x588U -#define MC_STREAMID_OVERRIDE_CFG_SCEDMAR 0x4e8U -#define MC_STREAMID_OVERRIDE_CFG_HOST1XDMAR 0xb0U -#define MC_STREAMID_OVERRIDE_CFG_SDMMCWA 0x320U -#define MC_STREAMID_OVERRIDE_CFG_MIU2R 0x570U -#define MC_STREAMID_OVERRIDE_CFG_APEDMAW 0x500U -#define MC_STREAMID_OVERRIDE_CFG_PCIE2AW 0x6e8U -#define MC_STREAMID_OVERRIDE_CFG_SESWR 0x408U -#define MC_STREAMID_OVERRIDE_CFG_PVA1RDB1 0x770U -#define MC_STREAMID_OVERRIDE_CFG_AXISW 0x468U -#define MC_STREAMID_OVERRIDE_CFG_DLA1FALRDB 0x618U -#define MC_STREAMID_OVERRIDE_CFG_AONDMAW 0x4d0U -#define MC_STREAMID_OVERRIDE_CFG_TSECSWRB 0x438U -#define MC_STREAMID_OVERRIDE_CFG_ISPWB 0x238U -#define MC_STREAMID_OVERRIDE_CFG_HDAR 0xa8U -#define MC_STREAMID_OVERRIDE_CFG_SDMMCRA 0x300U -#define MC_STREAMID_OVERRIDE_CFG_ETRW 0x428U -#define MC_STREAMID_OVERRIDE_CFG_RCEDMAW 0x6a8U -#define MC_STREAMID_OVERRIDE_CFG_TSECSWR 0x2a8U -#define MC_STREAMID_OVERRIDE_CFG_ETRR 0x420U -#define MC_STREAMID_OVERRIDE_CFG_SDMMCR 0x310U -#define MC_STREAMID_OVERRIDE_CFG_NVJPGSRD 0x3f0U -#define MC_STREAMID_OVERRIDE_CFG_AONDMAR 0x4c8U -#define MC_STREAMID_OVERRIDE_CFG_SCER 0x4d8U -#define MC_STREAMID_OVERRIDE_CFG_MIU5W 0x7e8U -#define MC_STREAMID_OVERRIDE_CFG_NVENC1SRD 0x6b0U -#define MC_STREAMID_OVERRIDE_CFG_PCIE4R 0x700U -#define MC_STREAMID_OVERRIDE_CFG_ISPWA 0x230U -#define MC_STREAMID_OVERRIDE_CFG_PCIE0W 0x6c8U -#define MC_STREAMID_OVERRIDE_CFG_PCIE5R1 0x778U -#define MC_STREAMID_OVERRIDE_CFG_DLA1RDA 0x610U -#define MC_STREAMID_OVERRIDE_CFG_VICSWR 0x368U -#define MC_STREAMID_OVERRIDE_CFG_SESRD 0x400U -#define MC_STREAMID_OVERRIDE_CFG_SDMMCW 0x330U -#define MC_STREAMID_OVERRIDE_CFG_SDMMCRAB 0x318U -#define MC_STREAMID_OVERRIDE_CFG_ISPFALW 0x720U -#define MC_STREAMID_OVERRIDE_CFG_EQOSW 0x478U -#define MC_STREAMID_OVERRIDE_CFG_RCEDMAR 0x6a0U -#define MC_STREAMID_OVERRIDE_CFG_RCER 0x690U -#define MC_STREAMID_OVERRIDE_CFG_NVDECSWR 0x3c8U -#define MC_STREAMID_OVERRIDE_CFG_UFSHCR 0x480U -#define MC_STREAMID_OVERRIDE_CFG_PCIE4W 0x708U -#define MC_STREAMID_OVERRIDE_CFG_VICSRD 0x360U -#define MC_STREAMID_OVERRIDE_CFG_APER 0x3d0U -#define MC_STREAMID_OVERRIDE_CFG_MIU7R 0x8U -#define MC_STREAMID_OVERRIDE_CFG_NVDEC1SRD 0x7c8U -#define MC_STREAMID_OVERRIDE_CFG_MIU7W 0x10U -#define MC_STREAMID_OVERRIDE_CFG_PVA1RDA1 0x768U -#define MC_STREAMID_OVERRIDE_CFG_PVA1WRC 0x688U -#define MC_STREAMID_OVERRIDE_CFG_AONW 0x4c0U -#define MC_STREAMID_OVERRIDE_CFG_MIU4W 0x598U -#define MC_STREAMID_OVERRIDE_CFG_HDAW 0x1a8U -#define MC_STREAMID_OVERRIDE_CFG_BPMPW 0x4a0U -#define MC_STREAMID_OVERRIDE_CFG_DLA1WRA 0x620U -#define MC_STREAMID_OVERRIDE_CFG_DLA0RDA1 0x748U -#define MC_STREAMID_OVERRIDE_CFG_MIU1W 0x548U -#define MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR1 0x508U -#define MC_STREAMID_OVERRIDE_CFG_VICSRD1 0x510U -#define MC_STREAMID_OVERRIDE_CFG_BPMPDMAW 0x4b0U -#define MC_STREAMID_OVERRIDE_CFG_NVDEC1SWR 0x7d8U -#define MC_STREAMID_OVERRIDE_CFG_PVA0WRC 0x658U -#define MC_STREAMID_OVERRIDE_CFG_PCIE5R 0x710U -#define MC_STREAMID_OVERRIDE_CFG_XUSB_DEVR 0x260U -#define MC_STREAMID_OVERRIDE_CFG_UFSHCW 0x488U -#define MC_STREAMID_OVERRIDE_CFG_PVA1WRB 0x680U -#define MC_STREAMID_OVERRIDE_CFG_PVA0WRB 0x650U -#define MC_STREAMID_OVERRIDE_CFG_DLA1FALWRB 0x628U -#define MC_STREAMID_OVERRIDE_CFG_NVENC1SWR 0x6b8U -#define MC_STREAMID_OVERRIDE_CFG_PCIE0R 0x6c0U -#define MC_STREAMID_OVERRIDE_CFG_PCIE3W 0x6f8U -#define MC_STREAMID_OVERRIDE_CFG_PVA0RDA 0x630U -#define MC_STREAMID_OVERRIDE_CFG_MIU6W 0x7f8U -#define MC_STREAMID_OVERRIDE_CFG_PCIE1R 0x6d0U -#define MC_STREAMID_OVERRIDE_CFG_NVDEC1SRD1 0x7d0U -#define MC_STREAMID_OVERRIDE_CFG_DLA0FALWRB 0x608U -#define MC_STREAMID_OVERRIDE_CFG_PVA1RDC 0x670U -#define MC_STREAMID_OVERRIDE_CFG_MIU0W 0x538U -#define MC_STREAMID_OVERRIDE_CFG_MIU2W 0x578U -#define MC_STREAMID_OVERRIDE_CFG_MPCORER 0x138U -#define MC_STREAMID_OVERRIDE_CFG_AXIAPR 0x410U -#define MC_STREAMID_OVERRIDE_CFG_AONR 0x4b8U -#define MC_STREAMID_OVERRIDE_CFG_BPMPDMAR 0x4a8U -#define MC_STREAMID_OVERRIDE_CFG_PVA0RDB 0x638U -#define MC_STREAMID_OVERRIDE_CFG_VIFALW 0x5e8U -#define MC_STREAMID_OVERRIDE_CFG_MIU6R 0x7f0U -#define MC_STREAMID_OVERRIDE_CFG_EQOSR 0x470U -#define MC_STREAMID_OVERRIDE_CFG_NVDECSRD 0x3c0U -#define MC_STREAMID_OVERRIDE_CFG_TSECSRDB 0x430U -#define MC_STREAMID_OVERRIDE_CFG_NVDECSRD1 0x518U -#define MC_STREAMID_OVERRIDE_CFG_PVA0RDB1 0x760U -#define MC_STREAMID_OVERRIDE_CFG_PCIE0R1 0x798U -#define MC_STREAMID_OVERRIDE_CFG_SCEDMAW 0x4f0U -#define MC_STREAMID_OVERRIDE_CFG_APEW 0x3d8U -#define MC_STREAMID_OVERRIDE_CFG_MIU5R 0x7e0U -#define MC_STREAMID_OVERRIDE_CFG_DLA1RDA1 0x750U -#define MC_STREAMID_OVERRIDE_CFG_PVA0WRA 0x648U -#define MC_STREAMID_OVERRIDE_CFG_ISPFALR 0x228U -#define MC_STREAMID_OVERRIDE_CFG_PTCR 0x0U -#define MC_STREAMID_OVERRIDE_CFG_MIU4R 0x590U -#define MC_STREAMID_OVERRIDE_CFG_ISPRA 0x220U -#define MC_STREAMID_OVERRIDE_CFG_VIFALR 0x5e0U -#define MC_STREAMID_OVERRIDE_CFG_PCIE2AR 0x6e0U -#define MC_STREAMID_OVERRIDE_CFG_RCEW 0x698U -#define MC_STREAMID_OVERRIDE_CFG_ISPRA1 0x790U -#define MC_STREAMID_OVERRIDE_CFG_SCEW 0x4e0U -#define MC_STREAMID_OVERRIDE_CFG_MIU3R 0x580U -#define MC_STREAMID_OVERRIDE_CFG_XUSB_DEVW 0x268U -#define MC_STREAMID_OVERRIDE_CFG_SATAR 0xf8U -#define MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR 0x490U -#define MC_STREAMID_OVERRIDE_CFG_PVA1RDB 0x668U -#define MC_STREAMID_OVERRIDE_CFG_VIW 0x390U -#define MC_STREAMID_OVERRIDE_CFG_NVENCSWR 0x158U -#define MC_STREAMID_OVERRIDE_CFG_PCIE5W 0x718U - -/******************************************************************************* - * Macro to calculate Security cfg register addr from StreamID Override register - ******************************************************************************/ -#define MC_STREAMID_OVERRIDE_TO_SECURITY_CFG(addr) ((addr) + (uint32_t)sizeof(uint32_t)) - -#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_NO_OVERRIDE_SO_DEV (0U << 4) -#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_NON_COHERENT_SO_DEV (1U << 4) -#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SO_DEV (2U << 4) -#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SNOOP_SO_DEV (3U << 4) - -#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_NO_OVERRIDE_NORMAL (0U << 8) -#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_NON_COHERENT_NORMAL (1U << 8) -#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_NORMAL (2U << 8) -#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SNOOP_NORMAL (3U << 8) - -#define MC_TXN_OVERRIDE_CONFIG_CGID_SO_DEV_ZERO (0U << 12) -#define MC_TXN_OVERRIDE_CONFIG_CGID_SO_DEV_CLIENT_AXI_ID (1U << 12) - -/******************************************************************************* - * Memory Controller transaction override config registers - ******************************************************************************/ -#define MC_TXN_OVERRIDE_CONFIG_HDAR 0x10a8U -#define MC_TXN_OVERRIDE_CONFIG_DLA1WRA 0x1624U -#define MC_TXN_OVERRIDE_CONFIG_PCIE1W 0x16dcU -#define MC_TXN_OVERRIDE_CONFIG_PVA0RDC 0x1644U -#define MC_TXN_OVERRIDE_CONFIG_PTCR 0x1000U -#define MC_TXN_OVERRIDE_CONFIG_EQOSW 0x1478U -#define MC_TXN_OVERRIDE_CONFIG_MPCOREW 0x11c8U -#define MC_TXN_OVERRIDE_CONFIG_DLA1FALWRB 0x162cU -#define MC_TXN_OVERRIDE_CONFIG_AXISR 0x1460U -#define MC_TXN_OVERRIDE_CONFIG_PVA0WRB 0x1654U -#define MC_TXN_OVERRIDE_CONFIG_MIU6R 0x17f4U -#define MC_TXN_OVERRIDE_CONFIG_MIU5R 0x17e4U -#define MC_TXN_OVERRIDE_CONFIG_NVENCSRD1 0x1784U -#define MC_TXN_OVERRIDE_CONFIG_PCIE0R 0x16c4U -#define MC_TXN_OVERRIDE_CONFIG_EQOSR 0x1470U -#define MC_TXN_OVERRIDE_CONFIG_NVENCSRD 0x10e0U -#define MC_TXN_OVERRIDE_CONFIG_NVENC1SRD1 0x178cU -#define MC_TXN_OVERRIDE_CONFIG_PVA1RDB1 0x1774U -#define MC_TXN_OVERRIDE_CONFIG_NVENC1SWR 0x16bcU -#define MC_TXN_OVERRIDE_CONFIG_VICSRD1 0x1510U -#define MC_TXN_OVERRIDE_CONFIG_BPMPDMAR 0x14a8U -#define MC_TXN_OVERRIDE_CONFIG_VIW 0x1390U -#define MC_TXN_OVERRIDE_CONFIG_PCIE5R 0x1714U -#define MC_TXN_OVERRIDE_CONFIG_AXISW 0x1468U -#define MC_TXN_OVERRIDE_CONFIG_MIU6W 0x17fcU -#define MC_TXN_OVERRIDE_CONFIG_UFSHCR 0x1480U -#define MC_TXN_OVERRIDE_CONFIG_PCIE0R1 0x179cU -#define MC_TXN_OVERRIDE_CONFIG_PVA0RDB1 0x1764U -#define MC_TXN_OVERRIDE_CONFIG_TSECSWR 0x12a8U -#define MC_TXN_OVERRIDE_CONFIG_MIU7R 0x1008U -#define MC_TXN_OVERRIDE_CONFIG_SATAR 0x10f8U -#define MC_TXN_OVERRIDE_CONFIG_XUSB_HOSTW 0x1258U -#define MC_TXN_OVERRIDE_CONFIG_DLA0RDA 0x15f4U -#define MC_TXN_OVERRIDE_CONFIG_TSECSWRB 0x1438U -#define MC_TXN_OVERRIDE_CONFIG_NVDEC1SWR 0x17dcU -#define MC_TXN_OVERRIDE_CONFIG_PVA1RDA1 0x176cU -#define MC_TXN_OVERRIDE_CONFIG_PVA1RDB 0x166cU -#define MC_TXN_OVERRIDE_CONFIG_AONDMAW 0x14d0U -#define MC_TXN_OVERRIDE_CONFIG_AONW 0x14c0U -#define MC_TXN_OVERRIDE_CONFIG_ETRR 0x1420U -#define MC_TXN_OVERRIDE_CONFIG_PCIE2AW 0x16ecU -#define MC_TXN_OVERRIDE_CONFIG_PCIE1R 0x16d4U -#define MC_TXN_OVERRIDE_CONFIG_PVA1RDC 0x1674U -#define MC_TXN_OVERRIDE_CONFIG_PVA0WRA 0x164cU -#define MC_TXN_OVERRIDE_CONFIG_TSECSRDB 0x1430U -#define MC_TXN_OVERRIDE_CONFIG_MIU1W 0x1548U -#define MC_TXN_OVERRIDE_CONFIG_PCIE0W 0x16ccU -#define MC_TXN_OVERRIDE_CONFIG_NVDEC1SRD 0x17ccU -#define MC_TXN_OVERRIDE_CONFIG_MIU7W 0x1010U -#define MC_TXN_OVERRIDE_CONFIG_NVDECSRD1 0x1518U -#define MC_TXN_OVERRIDE_CONFIG_MIU3R 0x1580U -#define MC_TXN_OVERRIDE_CONFIG_MIU3W 0x158cU -#define MC_TXN_OVERRIDE_CONFIG_XUSB_HOSTR 0x1250U -#define MC_TXN_OVERRIDE_CONFIG_SESRD 0x1400U -#define MC_TXN_OVERRIDE_CONFIG_SCER 0x14d8U -#define MC_TXN_OVERRIDE_CONFIG_MPCORER 0x1138U -#define MC_TXN_OVERRIDE_CONFIG_SDMMCWA 0x1320U -#define MC_TXN_OVERRIDE_CONFIG_HDAW 0x11a8U -#define MC_TXN_OVERRIDE_CONFIG_NVDECSWR 0x13c8U -#define MC_TXN_OVERRIDE_CONFIG_PVA0RDA 0x1634U -#define MC_TXN_OVERRIDE_CONFIG_AONDMAR 0x14c8U -#define MC_TXN_OVERRIDE_CONFIG_SDMMCWAB 0x1338U -#define MC_TXN_OVERRIDE_CONFIG_ISPFALR 0x1228U -#define MC_TXN_OVERRIDE_CONFIG_PVA0RDA1 0x175cU -#define MC_TXN_OVERRIDE_CONFIG_NVENC1SRD 0x16b4U -#define MC_TXN_OVERRIDE_CONFIG_NVDISPLAYR1 0x1508U -#define MC_TXN_OVERRIDE_CONFIG_PVA1RDA 0x1664U -#define MC_TXN_OVERRIDE_CONFIG_DLA0RDA1 0x174cU -#define MC_TXN_OVERRIDE_CONFIG_ISPWB 0x1238U -#define MC_TXN_OVERRIDE_CONFIG_APEW 0x13d8U -#define MC_TXN_OVERRIDE_CONFIG_AXIAPR 0x1410U -#define MC_TXN_OVERRIDE_CONFIG_PCIE2AR 0x16e4U -#define MC_TXN_OVERRIDE_CONFIG_ISPFALW 0x1724U -#define MC_TXN_OVERRIDE_CONFIG_SDMMCR 0x1310U -#define MC_TXN_OVERRIDE_CONFIG_MIU2W 0x1578U -#define MC_TXN_OVERRIDE_CONFIG_RCER 0x1694U -#define MC_TXN_OVERRIDE_CONFIG_PCIE4W 0x170cU -#define MC_TXN_OVERRIDE_CONFIG_BPMPW 0x14a0U -#define MC_TXN_OVERRIDE_CONFIG_NVDISPLAYR 0x1490U -#define MC_TXN_OVERRIDE_CONFIG_ISPRA 0x1220U -#define MC_TXN_OVERRIDE_CONFIG_NVJPGSWR 0x13f8U -#define MC_TXN_OVERRIDE_CONFIG_VICSRD 0x1360U -#define MC_TXN_OVERRIDE_CONFIG_NVDEC1SRD1 0x17d4U -#define MC_TXN_OVERRIDE_CONFIG_DLA1RDA 0x1614U -#define MC_TXN_OVERRIDE_CONFIG_SCEDMAW 0x14f0U -#define MC_TXN_OVERRIDE_CONFIG_SDMMCW 0x1330U -#define MC_TXN_OVERRIDE_CONFIG_DLA1FALRDB 0x161cU -#define MC_TXN_OVERRIDE_CONFIG_APEDMAR 0x14f8U -#define MC_TXN_OVERRIDE_CONFIG_RCEW 0x169cU -#define MC_TXN_OVERRIDE_CONFIG_SDMMCRAB 0x1318U -#define MC_TXN_OVERRIDE_CONFIG_DLA0WRA 0x1604U -#define MC_TXN_OVERRIDE_CONFIG_VIFALR 0x15e4U -#define MC_TXN_OVERRIDE_CONFIG_PCIE3R 0x16f4U -#define MC_TXN_OVERRIDE_CONFIG_MIU1R 0x1540U -#define MC_TXN_OVERRIDE_CONFIG_PCIE5W 0x171cU -#define MC_TXN_OVERRIDE_CONFIG_XUSB_DEVR 0x1260U -#define MC_TXN_OVERRIDE_CONFIG_MIU0W 0x1538U -#define MC_TXN_OVERRIDE_CONFIG_DLA0FALWRB 0x160cU -#define MC_TXN_OVERRIDE_CONFIG_VIFALW 0x15ecU -#define MC_TXN_OVERRIDE_CONFIG_DLA0FALRDB 0x15fcU -#define MC_TXN_OVERRIDE_CONFIG_PCIE3W 0x16fcU -#define MC_TXN_OVERRIDE_CONFIG_MIU0R 0x1530U -#define MC_TXN_OVERRIDE_CONFIG_PVA0WRC 0x165cU -#define MC_TXN_OVERRIDE_CONFIG_SCEDMAR 0x14e8U -#define MC_TXN_OVERRIDE_CONFIG_APEDMAW 0x1500U -#define MC_TXN_OVERRIDE_CONFIG_HOST1XDMAR 0x10b0U -#define MC_TXN_OVERRIDE_CONFIG_SESWR 0x1408U -#define MC_TXN_OVERRIDE_CONFIG_AXIAPW 0x1418U -#define MC_TXN_OVERRIDE_CONFIG_MIU4R 0x1594U -#define MC_TXN_OVERRIDE_CONFIG_MIU4W 0x159cU -#define MC_TXN_OVERRIDE_CONFIG_NVJPGSRD 0x13f0U -#define MC_TXN_OVERRIDE_CONFIG_NVDECSRD 0x13c0U -#define MC_TXN_OVERRIDE_CONFIG_BPMPDMAW 0x14b0U -#define MC_TXN_OVERRIDE_CONFIG_APER 0x13d0U -#define MC_TXN_OVERRIDE_CONFIG_DLA1RDA1 0x1754U -#define MC_TXN_OVERRIDE_CONFIG_PVA1WRB 0x1684U -#define MC_TXN_OVERRIDE_CONFIG_ISPWA 0x1230U -#define MC_TXN_OVERRIDE_CONFIG_PVA1WRC 0x168cU -#define MC_TXN_OVERRIDE_CONFIG_RCEDMAR 0x16a4U -#define MC_TXN_OVERRIDE_CONFIG_ISPRA1 0x1794U -#define MC_TXN_OVERRIDE_CONFIG_AONR 0x14b8U -#define MC_TXN_OVERRIDE_CONFIG_RCEDMAW 0x16acU -#define MC_TXN_OVERRIDE_CONFIG_UFSHCW 0x1488U -#define MC_TXN_OVERRIDE_CONFIG_ETRW 0x1428U -#define MC_TXN_OVERRIDE_CONFIG_SATAW 0x11e8U -#define MC_TXN_OVERRIDE_CONFIG_VICSWR 0x1368U -#define MC_TXN_OVERRIDE_CONFIG_NVENCSWR 0x1158U -#define MC_TXN_OVERRIDE_CONFIG_PCIE5R1 0x177cU -#define MC_TXN_OVERRIDE_CONFIG_PVA0RDB 0x163cU -#define MC_TXN_OVERRIDE_CONFIG_SDMMCRA 0x1300U -#define MC_TXN_OVERRIDE_CONFIG_PVA1WRA 0x167cU -#define MC_TXN_OVERRIDE_CONFIG_MIU5W 0x17ecU -#define MC_TXN_OVERRIDE_CONFIG_BPMPR 0x1498U -#define MC_TXN_OVERRIDE_CONFIG_MIU2R 0x1570U -#define MC_TXN_OVERRIDE_CONFIG_XUSB_DEVW 0x1268U -#define MC_TXN_OVERRIDE_CONFIG_TSECSRD 0x12a0U -#define MC_TXN_OVERRIDE_CONFIG_PCIE4R 0x1704U -#define MC_TXN_OVERRIDE_CONFIG_SCEW 0x14e0U - -#define MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_CGID (1U << 0) -#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_OVERRIDE_SO_DEV (2U << 4) -#define MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_SO_DEV_CGID_SO_DEV_CLIENT (1U << 12) - -/******************************************************************************* - * Non-SO_DEV transactions override values for CGID_TAG bitfield for the - * MC_TXN_OVERRIDE_CONFIG_{module} registers - ******************************************************************************/ -#define MC_TXN_OVERRIDE_CGID_TAG_DEFAULT 0U -#define MC_TXN_OVERRIDE_CGID_TAG_CLIENT_AXI_ID 1U -#define MC_TXN_OVERRIDE_CGID_TAG_ZERO 2U -#define MC_TXN_OVERRIDE_CGID_TAG_ADR 3U -#define MC_TXN_OVERRIDE_CGID_TAG_MASK 3ULL - -/******************************************************************************* - * Memory Controller Reset Control registers - ******************************************************************************/ -#define MC_CLIENT_HOTRESET_CTRL0 0x200U -#define MC_CLIENT_HOTRESET_CTRL0_RESET_VAL 0U -#define MC_CLIENT_HOTRESET_CTRL0_AFI_FLUSH_ENB (1U << 0) -#define MC_CLIENT_HOTRESET_CTRL0_HC_FLUSH_ENB (1U << 6) -#define MC_CLIENT_HOTRESET_CTRL0_HDA_FLUSH_ENB (1U << 7) -#define MC_CLIENT_HOTRESET_CTRL0_ISP2_FLUSH_ENB (1U << 8) -#define MC_CLIENT_HOTRESET_CTRL0_MPCORE_FLUSH_ENB (1U << 9) -#define MC_CLIENT_HOTRESET_CTRL0_NVENC_FLUSH_ENB (1U << 11) -#define MC_CLIENT_HOTRESET_CTRL0_SATA_FLUSH_ENB (1U << 15) -#define MC_CLIENT_HOTRESET_CTRL0_VI_FLUSH_ENB (1U << 17) -#define MC_CLIENT_HOTRESET_CTRL0_VIC_FLUSH_ENB (1U << 18) -#define MC_CLIENT_HOTRESET_CTRL0_XUSB_HOST_FLUSH_ENB (1U << 19) -#define MC_CLIENT_HOTRESET_CTRL0_XUSB_DEV_FLUSH_ENB (1U << 20) -#define MC_CLIENT_HOTRESET_CTRL0_TSEC_FLUSH_ENB (1U << 22) -#define MC_CLIENT_HOTRESET_CTRL0_SDMMC1A_FLUSH_ENB (1U << 29) -#define MC_CLIENT_HOTRESET_CTRL0_SDMMC2A_FLUSH_ENB (1U << 30) -#define MC_CLIENT_HOTRESET_CTRL0_SDMMC3A_FLUSH_ENB (1U << 31) -#define MC_CLIENT_HOTRESET_STATUS0 0x204U -#define MC_CLIENT_HOTRESET_CTRL1 0x970U -#define MC_CLIENT_HOTRESET_CTRL1_RESET_VAL 0U -#define MC_CLIENT_HOTRESET_CTRL1_SDMMC4A_FLUSH_ENB (1U << 0) -#define MC_CLIENT_HOTRESET_CTRL1_GPU_FLUSH_ENB (1U << 2) -#define MC_CLIENT_HOTRESET_CTRL1_NVDEC_FLUSH_ENB (1U << 5) -#define MC_CLIENT_HOTRESET_CTRL1_APE_FLUSH_ENB (1U << 6) -#define MC_CLIENT_HOTRESET_CTRL1_SE_FLUSH_ENB (1U << 7) -#define MC_CLIENT_HOTRESET_CTRL1_NVJPG_FLUSH_ENB (1U << 8) -#define MC_CLIENT_HOTRESET_CTRL1_ETR_FLUSH_ENB (1U << 12) -#define MC_CLIENT_HOTRESET_CTRL1_TSECB_FLUSH_ENB (1U << 13) -#define MC_CLIENT_HOTRESET_CTRL1_AXIS_FLUSH_ENB (1U << 17) -#define MC_CLIENT_HOTRESET_CTRL1_EQOS_FLUSH_ENB (1U << 18) -#define MC_CLIENT_HOTRESET_CTRL1_UFSHC_FLUSH_ENB (1U << 19) -#define MC_CLIENT_HOTRESET_CTRL1_NVDISPLAY_FLUSH_ENB (1U << 20) -#define MC_CLIENT_HOTRESET_CTRL1_BPMP_FLUSH_ENB (1U << 21) -#define MC_CLIENT_HOTRESET_CTRL1_AON_FLUSH_ENB (1U << 22) -#define MC_CLIENT_HOTRESET_CTRL1_SCE_FLUSH_ENB (1U << 23) -#define MC_CLIENT_HOTRESET_CTRL1_VIFAL_FLUSH_ENB (1U << 26) -#define MC_CLIENT_HOTRESET_CTRL1_RCE_FLUSH_ENB (1U << 31) -#define MC_CLIENT_HOTRESET_STATUS1 0x974U -#define MC_CLIENT_HOTRESET_CTRL2 0x97cU -#define MC_CLIENT_HOTRESET_CTRL2_RESET_VAL 0U -#define MC_CLIENT_HOTRESET_CTRL2_RCEDMA_FLUSH_ENB (1U << 0) -#define MC_CLIENT_HOTRESET_CTRL2_PCIE_FLUSH_ENB (1U << 2) -#define MC_CLIENT_HOTRESET_CTRL2_PCIE5A_FLUSH_ENB (1U << 4) -#define MC_CLIENT_HOTRESET_CTRL2_AONDMA_FLUSH_ENB (1U << 9) -#define MC_CLIENT_HOTRESET_CTRL2_BPMPDMA_FLUSH_ENB (1U << 10) -#define MC_CLIENT_HOTRESET_CTRL2_SCEDMA_FLUSH_ENB (1U << 11) -#define MC_CLIENT_HOTRESET_CTRL2_APEDMA_FLUSH_ENB (1U << 14) -#define MC_CLIENT_HOTRESET_CTRL2_PCIE3A_FLUSH_ENB (1U << 16) -#define MC_CLIENT_HOTRESET_CTRL2_PCIE3_FLUSH_ENB (1U << 17) -#define MC_CLIENT_HOTRESET_CTRL2_PCIE0A_FLUSH_ENB (1U << 22) -#define MC_CLIENT_HOTRESET_CTRL2_PCIE0A2_FLUSH_ENB (1U << 23) -#define MC_CLIENT_HOTRESET_CTRL2_PCIE4A_FLUSH_ENB (1U << 25) -#define MC_CLIENT_HOTRESET_STATUS2 0x1898U - -#define MC_COALESCE_CTRL 0x2930U -#define MC_COALESCE_CTRL_COALESCER_ENABLE (1U << 31) -#define MC_COALESCE_CONFIG_6_0 0x294cU -#define MC_COALESCE_CONFIG_6_0_PVA0RDC_COALESCER_ENABLED (1U << 8) -#define MC_COALESCE_CONFIG_6_0_PVA1RDC_COALESCER_ENABLED (1U << 14) - -/******************************************************************************* - * Tegra TSA Controller constants - ******************************************************************************/ -#define TEGRA_TSA_BASE U(0x02000000) - -#define TSA_CONFIG_STATIC0_CSR_RESET_R 0x20000000U -#define TSA_CONFIG_STATIC0_CSW_RESET_W 0x20001000U -#define TSA_CONFIG_STATIC0_CSW_RESET_SO_DEV 0x20001000U - -#define TSA_CONFIG_STATIC0_CSW_PCIE1W 0x1004U -#define TSA_CONFIG_STATIC0_CSW_PCIE2AW 0x1008U -#define TSA_CONFIG_STATIC0_CSW_PCIE3W 0x100cU -#define TSA_CONFIG_STATIC0_CSW_PCIE4W 0x1028U -#define TSA_CONFIG_STATIC0_CSW_XUSB_DEVW 0x2004U -#define TSA_CONFIG_STATIC0_CSR_SATAR 0x2010U -#define TSA_CONFIG_STATIC0_CSW_SATAW 0x2014U -#define TSA_CONFIG_STATIC0_CSW_PCIE0W 0x2020U -#define TSA_CONFIG_STATIC0_CSW_XUSB_HOSTW 0x202cU -#define TSA_CONFIG_STATIC0_CSW_NVENC1SWR 0x3004U -#define TSA_CONFIG_STATIC0_CSW_NVENCSWR 0x3010U -#define TSA_CONFIG_STATIC0_CSW_NVDEC1SWR 0x4004U -#define TSA_CONFIG_STATIC0_CSR_ISPFALR 0x4010U -#define TSA_CONFIG_STATIC0_CSW_ISPWA 0x4014U -#define TSA_CONFIG_STATIC0_CSW_ISPWB 0x4018U -#define TSA_CONFIG_STATIC0_CSW_ISPFALW 0x401cU -#define TSA_CONFIG_STATIC0_CSW_NVDECSWR 0x5004U -#define TSA_CONFIG_STATIC0_CSR_EQOSR 0x5010U -#define TSA_CONFIG_STATIC0_CSW_EQOSW 0x5014U -#define TSA_CONFIG_STATIC0_CSR_SDMMCRAB 0x5020U -#define TSA_CONFIG_STATIC0_CSW_SDMMCWAB 0x5024U -#define TSA_CONFIG_STATIC0_CSW_UFSHCW 0x6004U -#define TSA_CONFIG_STATIC0_CSR_SDMMCR 0x6010U -#define TSA_CONFIG_STATIC0_CSR_SDMMCRA 0x6014U -#define TSA_CONFIG_STATIC0_CSW_SDMMCW 0x6018U -#define TSA_CONFIG_STATIC0_CSW_SDMMCWA 0x601cU -#define TSA_CONFIG_STATIC0_CSR_RCER 0x6030U -#define TSA_CONFIG_STATIC0_CSR_RCEDMAR 0x6034U -#define TSA_CONFIG_STATIC0_CSW_RCEW 0x6038U -#define TSA_CONFIG_STATIC0_CSW_RCEDMAW 0x603cU -#define TSA_CONFIG_STATIC0_CSR_SCER 0x6050U -#define TSA_CONFIG_STATIC0_CSR_SCEDMAR 0x6054U -#define TSA_CONFIG_STATIC0_CSW_SCEW 0x6058U -#define TSA_CONFIG_STATIC0_CSW_SCEDMAW 0x605cU -#define TSA_CONFIG_STATIC0_CSR_AXIAPR 0x7004U -#define TSA_CONFIG_STATIC0_CSR_ETRR 0x7008U -#define TSA_CONFIG_STATIC0_CSR_HOST1XDMAR 0x700cU -#define TSA_CONFIG_STATIC0_CSW_AXIAPW 0x7010U -#define TSA_CONFIG_STATIC0_CSW_ETRW 0x7014U -#define TSA_CONFIG_STATIC0_CSR_NVJPGSRD 0x8004U -#define TSA_CONFIG_STATIC0_CSW_NVJPGSWR 0x8008U -#define TSA_CONFIG_STATIC0_CSR_AXISR 0x8014U -#define TSA_CONFIG_STATIC0_CSW_AXISW 0x8018U -#define TSA_CONFIG_STATIC0_CSR_BPMPR 0x9004U -#define TSA_CONFIG_STATIC0_CSR_BPMPDMAR 0x9008U -#define TSA_CONFIG_STATIC0_CSW_BPMPW 0x900cU -#define TSA_CONFIG_STATIC0_CSW_BPMPDMAW 0x9010U -#define TSA_CONFIG_STATIC0_CSR_SESRD 0x9024U -#define TSA_CONFIG_STATIC0_CSR_TSECSRD 0x9028U -#define TSA_CONFIG_STATIC0_CSR_TSECSRDB 0x902cU -#define TSA_CONFIG_STATIC0_CSW_SESWR 0x9030U -#define TSA_CONFIG_STATIC0_CSW_TSECSWR 0x9034U -#define TSA_CONFIG_STATIC0_CSW_TSECSWRB 0x9038U -#define TSA_CONFIG_STATIC0_CSW_PCIE5W 0xb004U -#define TSA_CONFIG_STATIC0_CSW_VICSWR 0xc004U -#define TSA_CONFIG_STATIC0_CSR_APER 0xd004U -#define TSA_CONFIG_STATIC0_CSR_APEDMAR 0xd008U -#define TSA_CONFIG_STATIC0_CSW_APEW 0xd00cU -#define TSA_CONFIG_STATIC0_CSW_APEDMAW 0xd010U -#define TSA_CONFIG_STATIC0_CSR_HDAR 0xf004U -#define TSA_CONFIG_STATIC0_CSW_HDAW 0xf008U -#define TSA_CONFIG_STATIC0_CSR_NVDISPLAYR 0xf014U -#define TSA_CONFIG_STATIC0_CSR_VIFALR 0x10004U -#define TSA_CONFIG_STATIC0_CSW_VIW 0x10008U -#define TSA_CONFIG_STATIC0_CSW_VIFALW 0x1000cU -#define TSA_CONFIG_STATIC0_CSR_AONR 0x12004U -#define TSA_CONFIG_STATIC0_CSR_AONDMAR 0x12008U -#define TSA_CONFIG_STATIC0_CSW_AONW 0x1200cU -#define TSA_CONFIG_STATIC0_CSW_AONDMAW 0x12010U -#define TSA_CONFIG_STATIC0_CSR_PCIE1R 0x14004U -#define TSA_CONFIG_STATIC0_CSR_PCIE2AR 0x14008U -#define TSA_CONFIG_STATIC0_CSR_PCIE3R 0x1400cU -#define TSA_CONFIG_STATIC0_CSR_PCIE4R 0x14028U -#define TSA_CONFIG_STATIC0_CSR_XUSB_DEVR 0x15004U -#define TSA_CONFIG_STATIC0_CSR_XUSB_HOSTR 0x15010U -#define TSA_CONFIG_STATIC0_CSR_UFSHCR 0x16004U -#define TSA_CONFIG_STATIC0_CSW_DLA1WRA 0x18004U -#define TSA_CONFIG_STATIC0_CSR_DLA1FALRDB 0x18010U -#define TSA_CONFIG_STATIC0_CSW_DLA1FALWRB 0x18014U -#define TSA_CONFIG_STATIC0_CSW_DLA0WRA 0x19004U -#define TSA_CONFIG_STATIC0_CSR_DLA0FALRDB 0x19010U -#define TSA_CONFIG_STATIC0_CSW_DLA0FALWRB 0x19014U -#define TSA_CONFIG_STATIC0_CSR_PVA1RDC 0x1a004U -#define TSA_CONFIG_STATIC0_CSW_PVA1WRC 0x1a008U -#define TSA_CONFIG_STATIC0_CSW_PVA1WRA 0x1a014U -#define TSA_CONFIG_STATIC0_CSW_PVA1WRB 0x1a020U -#define TSA_CONFIG_STATIC0_CSW_PVA0WRB 0x1b004U -#define TSA_CONFIG_STATIC0_CSR_PVA0RDC 0x1b010U -#define TSA_CONFIG_STATIC0_CSW_PVA0WRC 0x1b014U -#define TSA_CONFIG_STATIC0_CSW_PVA0WRA 0x1b020U -#define TSA_CONFIG_STATIC0_CSR_NVENC1SRD 0x1d004U -#define TSA_CONFIG_STATIC0_CSR_NVENCSRD 0x1d010U -#define TSA_CONFIG_STATIC0_CSR_NVDEC1SRD 0x1e004U -#define TSA_CONFIG_STATIC0_CSR_ISPRA 0x1e010U -#define TSA_CONFIG_STATIC0_CSR_NVDECSRD 0x1f004U -#define TSA_CONFIG_STATIC0_CSR_PCIE0R 0x21004U -#define TSA_CONFIG_STATIC0_CSR_PCIE5R 0x23004U -#define TSA_CONFIG_STATIC0_CSR_VICSRD 0x24004U -#define TSA_CONFIG_STATIC0_CSR_DLA1RDA 0x26004U -#define TSA_CONFIG_STATIC0_CSR_DLA0RDA 0x27004U -#define TSA_CONFIG_STATIC0_CSR_PVA1RDA 0x28004U -#define TSA_CONFIG_STATIC0_CSR_PVA1RDB 0x28010U -#define TSA_CONFIG_STATIC0_CSR_PVA0RDB 0x29004U -#define TSA_CONFIG_STATIC0_CSR_PVA0RDA 0x29010U - -#define TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK (ULL(0x3) << 11) -#define TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU (ULL(0) << 11) -#define TSA_CONFIG_CSW_SO_DEV_HUBID_MASK (ULL(0x3) << 15) -#define TSA_CONFIG_CSW_SO_DEV_HUB2 (ULL(2) << 15) - -#define REORDER_DEPTH_LIMIT 16 -#define TSA_CONFIG_CSW_REORDER_DEPTH_LIMIT_MASK (ULL(0x7FF) << 21) -#define reorder_depth_limit(limit) (ULL(limit) << 21) - -#define tsa_read_32(client) \ - mmio_read_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSW_##client) - -#define mc_set_tsa_hub2(val, client) \ - { \ - mmio_write_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSW_##client, \ - ((val & ~TSA_CONFIG_CSW_SO_DEV_HUBID_MASK) | \ - TSA_CONFIG_CSW_SO_DEV_HUB2)); \ - } - -#define mc_set_tsa_depth_limit(limit, client) \ - { \ - uint32_t val = mmio_read_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSW_##client); \ - mmio_write_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSW_##client, \ - ((val & ~TSA_CONFIG_CSW_REORDER_DEPTH_LIMIT_MASK) | \ - reorder_depth_limit(limit))); \ - } - -#endif /* TEGRA_MC_DEF_H */ diff --git a/plat/nvidia/tegra/soc/t194/plat_memctrl.c b/plat/nvidia/tegra/soc/t194/plat_memctrl.c index d6226b486..9ddcacf31 100644 --- a/plat/nvidia/tegra/soc/t194/plat_memctrl.c +++ b/plat/nvidia/tegra/soc/t194/plat_memctrl.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include diff --git a/plat/nvidia/tegra/soc/t194/plat_setup.c b/plat/nvidia/tegra/soc/t194/plat_setup.c index 41cc311d6..1998e9c60 100644 --- a/plat/nvidia/tegra/soc/t194/plat_setup.c +++ b/plat/nvidia/tegra/soc/t194/plat_setup.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -87,8 +86,6 @@ const uint8_t *plat_get_power_domain_tree_desc(void) static const mmap_region_t tegra_mmap[] = { MAP_REGION_FLAT(TEGRA_MISC_BASE, 0x4000U, /* 16KB */ (uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE), - MAP_REGION_FLAT(TEGRA_TSA_BASE, 0x20000U, /* 128KB */ - (uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE), MAP_REGION_FLAT(TEGRA_GPCDMA_BASE, 0x10000U, /* 64KB */ (uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE), MAP_REGION_FLAT(TEGRA_MC_STREAMID_BASE, 0x8000U, /* 32KB */ -- cgit v1.2.3 From e87c823102f5d439be896d4238dd92807c9d5825 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Sun, 23 Aug 2020 09:46:06 +0100 Subject: doc: Update the cot-binding for nv-counter node Updated the cot-binding documentation to add 'id' property for the trusted and non-trusted nv-counters. Signed-off-by: Manish V Badarkhe Change-Id: If1c628c5b90fe403dd96c7cd0cd04f37288c965c --- docs/components/cot-binding.rst | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/docs/components/cot-binding.rst b/docs/components/cot-binding.rst index 46915db23..4f8c8b725 100644 --- a/docs/components/cot-binding.rst +++ b/docs/components/cot-binding.rst @@ -279,6 +279,10 @@ non-volatile counter node binding definition Description: Contains various non-volatile counters present in the platform. PROPERTIES + - id + Usage: Required for every nv-counter with unique id. + + Value type: - reg Usage: @@ -301,21 +305,21 @@ Below is non-volatile counters example for ARM platform .. code:: c - non-volatile-counters { + non_volatile_counters: non_volatile_counters { compatible = "arm, non-volatile-counter"; #address-cells = <1>; #size-cells = <0>; - counters { - trusted-nv-counter: trusted_nv_counter { - reg = ; - oid = TRUSTED_FW_NVCOUNTER_OID; - }; - non_trusted_nv_counter: non_trusted_nv_counter { - reg = ; - oid = NON_TRUSTED_FW_NVCOUNTER_OID; + trusted-nv-counter: trusted_nv_counter { + id = ; + reg = ; + oid = TRUSTED_FW_NVCOUNTER_OID; + }; - }; + non_trusted_nv_counter: non_trusted_nv_counter { + id = ; + reg = ; + oid = NON_TRUSTED_FW_NVCOUNTER_OID; }; }; -- cgit v1.2.3 From 699d8a12658f4024e35a39325d8253baa20a5773 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Sun, 23 Aug 2020 09:47:02 +0100 Subject: dtsi: Update the nv-counter node in the device tree Created a header file defining the id of the various nv-counters used in the system. Also, updated the device tree to add 'id' property for the trusted and non-trusted nv-counters. Signed-off-by: Manish V Badarkhe Change-Id: Ia41a557f7e56ad4ed536aee11c7a59e078ae07c0 --- fdts/cot_descriptors.dtsi | 18 ++++++++++-------- include/common/nv_cntr_ids.h | 9 +++++++++ 2 files changed, 19 insertions(+), 8 deletions(-) create mode 100644 include/common/nv_cntr_ids.h diff --git a/fdts/cot_descriptors.dtsi b/fdts/cot_descriptors.dtsi index 9308e1789..411bae6c1 100644 --- a/fdts/cot_descriptors.dtsi +++ b/fdts/cot_descriptors.dtsi @@ -6,6 +6,7 @@ #include #include +#include cot { manifests { @@ -301,18 +302,19 @@ cot { }; }; -non-volatile-counters { +non_volatile_counters: non_volatile_counters { compatible = "arm, non-volatile-counter"; #address-cells = <1>; #size-cells = <0>; - counters { - trusted_nv_counter: trusted_nv_counter { - oid = TRUSTED_FW_NVCOUNTER_OID; - }; - non_trusted_nv_counter: non_trusted_nv_counter { - oid = NON_TRUSTED_FW_NVCOUNTER_OID; - }; + trusted_nv_counter: trusted_nv_counter { + id = ; + oid = TRUSTED_FW_NVCOUNTER_OID; + }; + + non_trusted_nv_counter: non_trusted_nv_counter { + id = ; + oid = NON_TRUSTED_FW_NVCOUNTER_OID; }; }; diff --git a/include/common/nv_cntr_ids.h b/include/common/nv_cntr_ids.h new file mode 100644 index 000000000..a15c431d0 --- /dev/null +++ b/include/common/nv_cntr_ids.h @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#define TRUSTED_NV_CTR_ID U(0) +#define NON_TRUSTED_NV_CTR_ID U(1) +#define MAX_NV_CTR_IDS U(2) -- cgit v1.2.3 From 14d095c3446e2fd7316f696b8391df7d9520b514 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Sun, 23 Aug 2020 09:58:44 +0100 Subject: plat/arm: Get the base address of nv-counters from device tree Using the Fconf, register base address of the various nv-counters (currently, trusted, non-trusted nv-counters) are moved to the device tree and retrieved during run-time. This feature is enabled using the build option COT_DESC_IN_DTB. Signed-off-by: Manish V Badarkhe Change-Id: I236f532e63cea63b179f60892cb406fc05cd5830 --- include/plat/arm/common/fconf_nv_cntr_getter.h | 17 +++++++ plat/arm/board/common/board_arm_trusted_boot.c | 18 +++++++- plat/arm/board/fvp/fvp_trusted_boot.c | 8 +++- plat/arm/board/fvp/platform.mk | 3 ++ plat/arm/common/fconf/fconf_nv_cntr_getter.c | 62 ++++++++++++++++++++++++++ 5 files changed, 104 insertions(+), 4 deletions(-) create mode 100644 include/plat/arm/common/fconf_nv_cntr_getter.h create mode 100644 plat/arm/common/fconf/fconf_nv_cntr_getter.c diff --git a/include/plat/arm/common/fconf_nv_cntr_getter.h b/include/plat/arm/common/fconf_nv_cntr_getter.h new file mode 100644 index 000000000..80a600049 --- /dev/null +++ b/include/plat/arm/common/fconf_nv_cntr_getter.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FCONF_NV_CNTR_GETTER_H +#define FCONF_NV_CNTR_GETTER_H + +#include +#include + +#define cot__nv_cntr_addr_getter(id) nv_cntr_base_addr[id] + +extern uintptr_t nv_cntr_base_addr[MAX_NV_CTR_IDS]; + +#endif /* FCONF_NV_CNTR_GETTER_H */ diff --git a/plat/arm/board/common/board_arm_trusted_boot.c b/plat/arm/board/common/board_arm_trusted_boot.c index 38cbba9e9..8239e0d1a 100644 --- a/plat/arm/board/common/board_arm_trusted_boot.c +++ b/plat/arm/board/common/board_arm_trusted_boot.c @@ -12,7 +12,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -29,6 +31,16 @@ #endif #endif +#if COT_DESC_IN_DTB && defined(IMAGE_BL2) +uintptr_t nv_cntr_base_addr[MAX_NV_CTR_IDS]; +#else +uintptr_t nv_cntr_base_addr[MAX_NV_CTR_IDS] = { + TFW_NVCTR_BASE, + NTFW_CTR_BASE +}; +#endif + + /* Weak definition may be overridden in specific platform */ #pragma weak plat_get_nv_ctr #pragma weak plat_set_nv_ctr @@ -183,9 +195,11 @@ int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr) oid = (const char *)cookie; if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) { - nv_ctr_addr = (uint32_t *)TFW_NVCTR_BASE; + nv_ctr_addr = (uint32_t *)FCONF_GET_PROPERTY(cot, nv_cntr_addr, + TRUSTED_NV_CTR_ID); } else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) { - nv_ctr_addr = (uint32_t *)NTFW_CTR_BASE; + nv_ctr_addr = (uint32_t *)FCONF_GET_PROPERTY(cot, nv_cntr_addr, + NON_TRUSTED_NV_CTR_ID); } else { return 1; } diff --git a/plat/arm/board/fvp/fvp_trusted_boot.c b/plat/arm/board/fvp/fvp_trusted_boot.c index 8825198a1..1ea37f7a3 100644 --- a/plat/arm/board/fvp/fvp_trusted_boot.c +++ b/plat/arm/board/fvp/fvp_trusted_boot.c @@ -9,7 +9,9 @@ #include #include +#include #include +#include #include #include #include @@ -50,9 +52,11 @@ int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr) oid = (const char *)cookie; if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) { - nv_ctr_addr = TFW_NVCTR_BASE; + 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 = NTFW_CTR_BASE; + nv_ctr_addr = FCONF_GET_PROPERTY(cot, nv_cntr_addr, + NON_TRUSTED_NV_CTR_ID); } else { return 1; } diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index a7d18252d..b6a9dae19 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -168,6 +168,9 @@ BL2_SOURCES += drivers/arm/sp805/sp805.c \ ${FVP_SECURITY_SOURCES} +ifeq (${COT_DESC_IN_DTB},1) +BL2_SOURCES += plat/arm/common/fconf/fconf_nv_cntr_getter.c +endif ifeq (${BL2_AT_EL3},1) BL2_SOURCES += plat/arm/board/fvp/${ARCH}/fvp_helpers.S \ diff --git a/plat/arm/common/fconf/fconf_nv_cntr_getter.c b/plat/arm/common/fconf/fconf_nv_cntr_getter.c new file mode 100644 index 000000000..8d645ef3d --- /dev/null +++ b/plat/arm/common/fconf/fconf_nv_cntr_getter.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include + +#include + +#include + +/******************************************************************************* + * fconf_populate_cot_descs() - Populate available nv-counters and update global + * structure. + * @config[in]: Pointer to the device tree blob in memory + * + * Return 0 on success or an error value otherwise. + ******************************************************************************/ +static int fconf_populate_nv_cntrs(uintptr_t config) +{ + int rc, node, child; + uint32_t id; + uintptr_t reg; + + /* As libfdt uses void *, we can't avoid this cast */ + const void *dtb = (void *)config; + const char *compatible_str = "arm, non-volatile-counter"; + + node = fdt_node_offset_by_compatible(dtb, -1, compatible_str); + if (node < 0) { + ERROR("FCONF: Can't find %s compatible in node\n", + compatible_str); + return node; + } + + fdt_for_each_subnode(child, dtb, node) { + + rc = fdt_read_uint32(dtb, child, "id", &id); + if (rc < 0) { + ERROR("FCONF: Can't find %s property in node\n", "id"); + return rc; + } + + assert(id < MAX_NV_CTR_IDS); + + rc = fdt_get_reg_props_by_index(dtb, child, 0, ®, NULL); + if (rc < 0) { + ERROR("FCONF: Can't find %s property in node\n", "reg"); + return rc; + } + + nv_cntr_base_addr[id] = reg; + } + + return 0; +} + +FCONF_REGISTER_POPULATOR(TB_FW, nv_cntrs, fconf_populate_nv_cntrs); -- cgit v1.2.3 From ae0e09bb216b4f76cbb86e58f7a6d784efdafd73 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Thu, 27 Aug 2020 13:16:21 +0100 Subject: sp_min: Avoid platform security reconfiguration In the case of Juno AArch32, platform security configuration gets done from both BL2 and SP_MIN(BL32) components when JUNO_AARCH32_EL3_RUNTIME and RESET_TO_SP_MIN build options are set. Fix is provided to avoid Platform security configuration from SP_MIN when it is already done in BL2. Signed-off-by: Manish V Badarkhe Change-Id: I702e91dacb4cdd2d10e339ddeaea91289bef3229 --- plat/arm/common/sp_min/arm_sp_min_setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/arm/common/sp_min/arm_sp_min_setup.c b/plat/arm/common/sp_min/arm_sp_min_setup.c index 6100b7834..270093c4e 100644 --- a/plat/arm/common/sp_min/arm_sp_min_setup.c +++ b/plat/arm/common/sp_min/arm_sp_min_setup.c @@ -186,7 +186,7 @@ void sp_min_platform_setup(void) * Do initial security configuration to allow DRAM/device access * (if earlier BL has not already done so). */ -#if RESET_TO_SP_MIN +#if RESET_TO_SP_MIN && !JUNO_AARCH32_EL3_RUNTIME plat_arm_security_setup(); #if defined(PLAT_ARM_MEM_PROT_ADDR) -- cgit v1.2.3 From fd1fe2d530d63162f6829ccb326e34c88853cb73 Mon Sep 17 00:00:00 2001 From: Javier Almansa Sobrino Date: Fri, 28 Aug 2020 15:19:32 +0100 Subject: Remove Jack Bond-Preston as CMake Build Definitions code owner Signed-off-by: Javier Almansa Sobrino Change-Id: I542ec3cf1bb929a5656dda6dbad816b69837c646 --- docs/about/maintainers.rst | 3 --- 1 file changed, 3 deletions(-) diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst index a62870452..50abc814f 100644 --- a/docs/about/maintainers.rst +++ b/docs/about/maintainers.rst @@ -64,8 +64,6 @@ Build Definitions for CMake Build System ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :M: Javier Almansa Sobrino :G: `javieralso-arm`_ -:M: Jack Bond-Preston -:G: `jackbondpreston-arm`_ :F: / Software Delegated Exception Interface (SDEI) @@ -648,6 +646,5 @@ Build system .. _madhukar-Arm: https://github.com/madhukar-Arm .. _john-powell-arm: https://github.com/john-powell-arm .. _raghuncstate: https://github.com/raghuncstate -.. _jackbondpreston-arm: https://github.com/jackbondpreston-arm .. _Project Maintenance Process: https://developer.trustedfirmware.org/w/collaboration/project-maintenance-process/ -- cgit v1.2.3 From 8a737ee4c40cb1b67534b3df78429dbe64d9a4f2 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 29 Aug 2020 14:53:27 +0900 Subject: maintainers: step down as code owner of UniPhier platform I am leaving Socionext. Orphan the UniPhier platform until somebody takes the role. Change-Id: I54d3da6d49c1ccaaa475431654db578b683db88a Signed-off-by: Masahiro Yamada --- docs/about/maintainers.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst index a62870452..87826e563 100644 --- a/docs/about/maintainers.rst +++ b/docs/about/maintainers.rst @@ -523,8 +523,7 @@ Texas Instruments platform port UniPhier platform port ^^^^^^^^^^^^^^^^^^^^^^ -:M: Masahiro Yamada -:G: `masahir0y`_ +:M: Orphan :F: docs/plat/socionext-uniphier.rst :F: plat/socionext/uniphier/ -- cgit v1.2.3 From a14988c6613d396293fd13eb052178a7e8e0d036 Mon Sep 17 00:00:00 2001 From: Jimmy Brisson Date: Tue, 4 Aug 2020 16:27:51 -0500 Subject: Move static vars into functions in bl1 This reduces the scope of these variables and resolves Misra violations such as: bl1/aarch64/bl1_context_mgmt.c:21:[MISRA C-2012 Rule 8.9 (advisory)] "bl1_cpu_context" should be defined at block scope. Signed-off-by: Jimmy Brisson Change-Id: I9b0b26395bce07e10e61d10158c67f9c22ecce44 --- bl1/aarch64/bl1_context_mgmt.c | 13 +++++++------ bl1/bl1_main.c | 10 +++++----- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/bl1/aarch64/bl1_context_mgmt.c b/bl1/aarch64/bl1_context_mgmt.c index fec513db8..87e367ce8 100644 --- a/bl1/aarch64/bl1_context_mgmt.c +++ b/bl1/aarch64/bl1_context_mgmt.c @@ -14,12 +14,6 @@ #include "../bl1_private.h" -/* - * 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]; - /* Following contains the cpu context pointers. */ static void *bl1_cpu_context_ptr[2]; @@ -42,6 +36,13 @@ void cm_set_context(void *context, uint32_t security_state) ******************************************************************************/ 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; diff --git a/bl1/bl1_main.c b/bl1/bl1_main.c index 1479a967b..fd602324f 100644 --- a/bl1/bl1_main.c +++ b/bl1/bl1_main.c @@ -24,11 +24,6 @@ #include "bl1_private.h" -/* BL1 Service UUID */ -DEFINE_SVC_UUID2(bl1_svc_uid, - U(0xd46739fd), 0xcb72, 0x9a4d, 0xb5, 0x75, - 0x67, 0x15, 0xd6, 0xf4, 0xbb, 0x4a); - static void bl1_load_bl2(void); #if ENABLE_PAUTH @@ -234,6 +229,11 @@ u_register_t bl1_smc_handler(unsigned int smc_fid, void *handle, unsigned int flags) { + /* BL1 Service UUID */ + DEFINE_SVC_UUID2(bl1_svc_uid, + U(0xd46739fd), 0xcb72, 0x9a4d, 0xb5, 0x75, + 0x67, 0x15, 0xd6, 0xf4, 0xbb, 0x4a); + #if TRUSTED_BOARD_BOOT /* -- cgit v1.2.3 From 9b624a7deba7c23ba92589979f2b390f7d73dfd7 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Fri, 28 Aug 2020 14:00:15 -0700 Subject: cpus: denver: introduce macro to declare cpu_ops This patch introduces a macro to declare cpu_op for all Denver SKUs. Signed-off-by: Varun Wadekar Change-Id: Ibcf88c3256fc5dcaa1be855749ebd2c5c396c977 --- lib/cpus/aarch64/denver.S | 81 +++++++++++------------------------------------ 1 file changed, 19 insertions(+), 62 deletions(-) diff --git a/lib/cpus/aarch64/denver.S b/lib/cpus/aarch64/denver.S index d662e7f89..834546bf6 100644 --- a/lib/cpus/aarch64/denver.S +++ b/lib/cpus/aarch64/denver.S @@ -353,65 +353,22 @@ func denver_cpu_reg_dump ret endfunc denver_cpu_reg_dump -declare_cpu_ops_wa denver, DENVER_MIDR_PN0, \ - denver_reset_func, \ - check_errata_cve_2017_5715, \ - CPU_NO_EXTRA2_FUNC, \ - denver_core_pwr_dwn, \ - denver_cluster_pwr_dwn - -declare_cpu_ops_wa denver, DENVER_MIDR_PN1, \ - denver_reset_func, \ - check_errata_cve_2017_5715, \ - CPU_NO_EXTRA2_FUNC, \ - denver_core_pwr_dwn, \ - denver_cluster_pwr_dwn - -declare_cpu_ops_wa denver, DENVER_MIDR_PN2, \ - denver_reset_func, \ - check_errata_cve_2017_5715, \ - CPU_NO_EXTRA2_FUNC, \ - denver_core_pwr_dwn, \ - denver_cluster_pwr_dwn - -declare_cpu_ops_wa denver, DENVER_MIDR_PN3, \ - denver_reset_func, \ - check_errata_cve_2017_5715, \ - CPU_NO_EXTRA2_FUNC, \ - denver_core_pwr_dwn, \ - denver_cluster_pwr_dwn - -declare_cpu_ops_wa denver, DENVER_MIDR_PN4, \ - denver_reset_func, \ - check_errata_cve_2017_5715, \ - CPU_NO_EXTRA2_FUNC, \ - denver_core_pwr_dwn, \ - denver_cluster_pwr_dwn - -declare_cpu_ops_wa denver, DENVER_MIDR_PN5, \ - denver_reset_func, \ - check_errata_cve_2017_5715, \ - CPU_NO_EXTRA2_FUNC, \ - denver_core_pwr_dwn, \ - denver_cluster_pwr_dwn - -declare_cpu_ops_wa denver, DENVER_MIDR_PN6, \ - denver_reset_func, \ - check_errata_cve_2017_5715, \ - CPU_NO_EXTRA2_FUNC, \ - denver_core_pwr_dwn, \ - denver_cluster_pwr_dwn - -declare_cpu_ops_wa denver, DENVER_MIDR_PN7, \ - denver_reset_func, \ - check_errata_cve_2017_5715, \ - CPU_NO_EXTRA2_FUNC, \ - denver_core_pwr_dwn, \ - denver_cluster_pwr_dwn - -declare_cpu_ops_wa denver, DENVER_MIDR_PN8, \ - denver_reset_func, \ - check_errata_cve_2017_5715, \ - CPU_NO_EXTRA2_FUNC, \ - denver_core_pwr_dwn, \ - denver_cluster_pwr_dwn +/* macro to declare cpu_ops for Denver SKUs */ +.macro denver_cpu_ops_wa midr + declare_cpu_ops_wa denver, \midr, \ + denver_reset_func, \ + check_errata_cve_2017_5715, \ + CPU_NO_EXTRA2_FUNC, \ + denver_core_pwr_dwn, \ + denver_cluster_pwr_dwn +.endm + +denver_cpu_ops_wa DENVER_MIDR_PN0 +denver_cpu_ops_wa DENVER_MIDR_PN1 +denver_cpu_ops_wa DENVER_MIDR_PN2 +denver_cpu_ops_wa DENVER_MIDR_PN3 +denver_cpu_ops_wa DENVER_MIDR_PN4 +denver_cpu_ops_wa DENVER_MIDR_PN5 +denver_cpu_ops_wa DENVER_MIDR_PN6 +denver_cpu_ops_wa DENVER_MIDR_PN7 +denver_cpu_ops_wa DENVER_MIDR_PN8 -- cgit v1.2.3 From c6d25c00420844e77f85bdad18abf9a79234330f Mon Sep 17 00:00:00 2001 From: Hemant Nigam Date: Tue, 17 Dec 2019 14:21:38 -0800 Subject: lib: cpus: denver: add MIDR PN9 variant This patch introduces support for PN9 variant for some Denver based platforms. Original change by: Hemant Nigam Signed-off-by: Kalyani Chidambaram Vaidyanathan Change-Id: I331cd3a083721fd1cd1b03f4a11b32fd306a21f3 --- include/lib/cpus/aarch64/denver.h | 1 + lib/cpus/aarch64/denver.S | 1 + 2 files changed, 2 insertions(+) diff --git a/include/lib/cpus/aarch64/denver.h b/include/lib/cpus/aarch64/denver.h index b665bc799..24b6a870c 100644 --- a/include/lib/cpus/aarch64/denver.h +++ b/include/lib/cpus/aarch64/denver.h @@ -17,6 +17,7 @@ #define DENVER_MIDR_PN6 U(0x4E0F0060) #define DENVER_MIDR_PN7 U(0x4E0F0070) #define DENVER_MIDR_PN8 U(0x4E0F0080) +#define DENVER_MIDR_PN9 U(0x4E0F0090) /* Implementer code in the MIDR register */ #define DENVER_IMPL U(0x4E) diff --git a/lib/cpus/aarch64/denver.S b/lib/cpus/aarch64/denver.S index 834546bf6..83427b84f 100644 --- a/lib/cpus/aarch64/denver.S +++ b/lib/cpus/aarch64/denver.S @@ -372,3 +372,4 @@ denver_cpu_ops_wa DENVER_MIDR_PN5 denver_cpu_ops_wa DENVER_MIDR_PN6 denver_cpu_ops_wa DENVER_MIDR_PN7 denver_cpu_ops_wa DENVER_MIDR_PN8 +denver_cpu_ops_wa DENVER_MIDR_PN9 -- cgit v1.2.3 From 0da7e2dd8edbd122580b10dd6a3e53e8f4fc81b2 Mon Sep 17 00:00:00 2001 From: Kalyani Chidambaram Vaidyanathan Date: Mon, 6 Apr 2020 17:34:37 -0700 Subject: Tegra: remove ENABLE_SVE_FOR_NS = 0 The SVE CPU extension library reads the id_aa64pfr0_el1 register to check if SVE is enabled. Tegra platforms disabled ENABLE_SVE_FOR_NS for pre-8.2 platforms, but this flag can safely be enabled now that the library can enable the feature at runtime. This patch updates the makefile to remove "ENABLE_SVE_FOR_NS = 0" as a result. Change-Id: Ia2a89ac90644f8c0d39b41d321e04458ff6be6e1 Signed-off-by: Kalyani Chidambaram Vaidyanathan --- plat/nvidia/tegra/platform.mk | 3 --- 1 file changed, 3 deletions(-) diff --git a/plat/nvidia/tegra/platform.mk b/plat/nvidia/tegra/platform.mk index abe94e4d2..6ed1cdf0b 100644 --- a/plat/nvidia/tegra/platform.mk +++ b/plat/nvidia/tegra/platform.mk @@ -33,9 +33,6 @@ SEPARATE_CODE_AND_RODATA := 1 # do not use coherent memory USE_COHERENT_MEM := 0 -# do not enable SVE -ENABLE_SVE_FOR_NS := 0 - # enable D-cache early during CPU warmboot WARMBOOT_ENABLE_DCACHE_EARLY := 1 -- cgit v1.2.3 From 3ff448f9a70254152b4debf8a52c5342052f7ebc Mon Sep 17 00:00:00 2001 From: Kalyani Chidambaram Vaidyanathan Date: Mon, 15 Jun 2020 16:48:53 -0700 Subject: Tegra: add platform specific 'runtime_setup' handler Tegra SoCs would like the flexibility to perform chip specific actions before we complete cold boot. This patch introduces a platform specific 'runtime_setup' handler to provide that flexibility. Change-Id: I13b2489f631f775cae6f92acf51a240cd036ef11 Signed-off-by: Kalyani Chidambaram Vaidyanathan --- plat/nvidia/tegra/common/tegra_bl31_setup.c | 26 ++--------------------- plat/nvidia/tegra/include/tegra_private.h | 1 + plat/nvidia/tegra/soc/t132/plat_setup.c | 26 +++++++++++++++++++++++ plat/nvidia/tegra/soc/t186/plat_setup.c | 32 ++++++++++++++++++++++++++++ plat/nvidia/tegra/soc/t194/plat_setup.c | 33 +++++++++++++++++++++++++++++ plat/nvidia/tegra/soc/t210/plat_setup.c | 25 ++++++++++++++++++++++ 6 files changed, 119 insertions(+), 24 deletions(-) diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c index c8bce052a..cb4886f1a 100644 --- a/plat/nvidia/tegra/common/tegra_bl31_setup.c +++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c @@ -253,31 +253,9 @@ void bl31_platform_setup(void) void bl31_plat_runtime_setup(void) { /* - * During cold boot, it is observed that the arbitration - * bit is set in the Memory controller leading to false - * error interrupts in the non-secure world. To avoid - * this, clean the interrupt status register before - * booting into the non-secure world + * Platform specific runtime setup */ - tegra_memctrl_clear_pending_interrupts(); - - /* - * During boot, USB3 and flash media (SDMMC/SATA) devices need - * access to IRAM. Because these clients connect to the MC and - * do not have a direct path to the IRAM, the MC implements AHB - * redirection during boot to allow path to IRAM. In this mode - * accesses to a programmed memory address aperture are directed - * to the AHB bus, allowing access to the IRAM. This mode must be - * disabled before we jump to the non-secure world. - */ - tegra_memctrl_disable_ahb_redirection(); - -#if defined(TEGRA_SMMU0_BASE) - /* - * Verify the integrity of the previously configured SMMU(s) settings - */ - tegra_smmu_verify(); -#endif + plat_runtime_setup(); /* * Add final timestamp before exiting BL31. diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h index f1a4948f9..cc2ad869c 100644 --- a/plat/nvidia/tegra/include/tegra_private.h +++ b/plat/nvidia/tegra/include/tegra_private.h @@ -87,6 +87,7 @@ void plat_early_platform_setup(void); void plat_late_platform_setup(void); void plat_relocate_bl32_image(const image_info_t *bl32_img_info); bool plat_supports_system_suspend(void); +void plat_runtime_setup(void); /* Declarations for plat_secondary.c */ void plat_secondary_setup(void); diff --git a/plat/nvidia/tegra/soc/t132/plat_setup.c b/plat/nvidia/tegra/soc/t132/plat_setup.c index 9f9abac7f..49e8b5d88 100644 --- a/plat/nvidia/tegra/soc/t132/plat_setup.c +++ b/plat/nvidia/tegra/soc/t132/plat_setup.c @@ -173,3 +173,29 @@ bool plat_supports_system_suspend(void) { return true; } + +/******************************************************************************* + * Platform specific runtime setup. + ******************************************************************************/ +void plat_runtime_setup(void) +{ + /* + * During cold boot, it is observed that the arbitration + * bit is set in the Memory controller leading to false + * error interrupts in the non-secure world. To avoid + * this, clean the interrupt status register before + * booting into the non-secure world + */ + tegra_memctrl_clear_pending_interrupts(); + + /* + * During boot, USB3 and flash media (SDMMC/SATA) devices need + * access to IRAM. Because these clients connect to the MC and + * do not have a direct path to the IRAM, the MC implements AHB + * redirection during boot to allow path to IRAM. In this mode + * accesses to a programmed memory address aperture are directed + * to the AHB bus, allowing access to the IRAM. This mode must be + * disabled before we jump to the non-secure world. + */ + tegra_memctrl_disable_ahb_redirection(); +} diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c index ab374a4e0..d6d090aba 100644 --- a/plat/nvidia/tegra/soc/t186/plat_setup.c +++ b/plat/nvidia/tegra/soc/t186/plat_setup.c @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -363,3 +364,34 @@ bool plat_supports_system_suspend(void) { return true; } +/******************************************************************************* + * Platform specific runtime setup. + ******************************************************************************/ +void plat_runtime_setup(void) +{ + /* + * During cold boot, it is observed that the arbitration + * bit is set in the Memory controller leading to false + * error interrupts in the non-secure world. To avoid + * this, clean the interrupt status register before + * booting into the non-secure world + */ + tegra_memctrl_clear_pending_interrupts(); + + /* + * During boot, USB3 and flash media (SDMMC/SATA) devices need + * access to IRAM. Because these clients connect to the MC and + * do not have a direct path to the IRAM, the MC implements AHB + * redirection during boot to allow path to IRAM. In this mode + * accesses to a programmed memory address aperture are directed + * to the AHB bus, allowing access to the IRAM. This mode must be + * disabled before we jump to the non-secure world. + */ + tegra_memctrl_disable_ahb_redirection(); + + /* + * Verify the integrity of the previously configured SMMU(s) + * settings + */ + tegra_smmu_verify(); +} diff --git a/plat/nvidia/tegra/soc/t194/plat_setup.c b/plat/nvidia/tegra/soc/t194/plat_setup.c index 1998e9c60..8f7d1e9a1 100644 --- a/plat/nvidia/tegra/soc/t194/plat_setup.c +++ b/plat/nvidia/tegra/soc/t194/plat_setup.c @@ -20,7 +20,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -414,3 +416,34 @@ bool plat_supports_system_suspend(void) { return true; } + +/******************************************************************************* + * Platform specific runtime setup. + ******************************************************************************/ +void plat_runtime_setup(void) +{ + /* + * During cold boot, it is observed that the arbitration + * bit is set in the Memory controller leading to false + * error interrupts in the non-secure world. To avoid + * this, clean the interrupt status register before + * booting into the non-secure world + */ + tegra_memctrl_clear_pending_interrupts(); + + /* + * During boot, USB3 and flash media (SDMMC/SATA) devices need + * access to IRAM. Because these clients connect to the MC and + * do not have a direct path to the IRAM, the MC implements AHB + * redirection during boot to allow path to IRAM. In this mode + * accesses to a programmed memory address aperture are directed + * to the AHB bus, allowing access to the IRAM. This mode must be + * disabled before we jump to the non-secure world. + */ + tegra_memctrl_disable_ahb_redirection(); + + /* + * Verify the integrity of the previously configured SMMU(s) settings + */ + tegra_smmu_verify(); +} diff --git a/plat/nvidia/tegra/soc/t210/plat_setup.c b/plat/nvidia/tegra/soc/t210/plat_setup.c index 20dde3b9c..68cd38ec3 100644 --- a/plat/nvidia/tegra/soc/t210/plat_setup.c +++ b/plat/nvidia/tegra/soc/t210/plat_setup.c @@ -291,3 +291,28 @@ bool plat_supports_system_suspend(void) return false; } } +/******************************************************************************* + * Platform specific runtime setup. + ******************************************************************************/ +void plat_runtime_setup(void) +{ + /* + * During cold boot, it is observed that the arbitration + * bit is set in the Memory controller leading to false + * error interrupts in the non-secure world. To avoid + * this, clean the interrupt status register before + * booting into the non-secure world + */ + tegra_memctrl_clear_pending_interrupts(); + + /* + * During boot, USB3 and flash media (SDMMC/SATA) devices need + * access to IRAM. Because these clients connect to the MC and + * do not have a direct path to the IRAM, the MC implements AHB + * redirection during boot to allow path to IRAM. In this mode + * accesses to a programmed memory address aperture are directed + * to the AHB bus, allowing access to the IRAM. This mode must be + * disabled before we jump to the non-secure world. + */ + tegra_memctrl_disable_ahb_redirection(); +} -- cgit v1.2.3 From 923c221b6d94c16678abca04ab76b633b052b585 Mon Sep 17 00:00:00 2001 From: anzhou Date: Fri, 26 Jun 2020 15:21:10 +0800 Subject: Tegra: fixup CNTPS_TVAL_EL1 delay timer reads The delay_timer driver for Tegra uses the CNTPS_TVAL_EL1 secure, physical, decrementing timer as the source. The current logic incorrectly marks this as an incrementing timer, by negating the timer value. This patch fixes the anomaly and updates the driver to remove this logic. Signed-off-by: anzhou Change-Id: I60490bdcaf0b66bf4553a6de3f4e4e32109017f4 --- plat/nvidia/tegra/common/tegra_delay_timer.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/plat/nvidia/tegra/common/tegra_delay_timer.c b/plat/nvidia/tegra/common/tegra_delay_timer.c index cfd9a15e3..d9547c4a3 100644 --- a/plat/nvidia/tegra/common/tegra_delay_timer.c +++ b/plat/nvidia/tegra/common/tegra_delay_timer.c @@ -22,11 +22,9 @@ static uint32_t tegra_timer_get_value(void) /* * Generic delay timer implementation expects the timer to be a down - * counter. We apply bitwise NOT operator to the tick values returned - * by read_cntps_tval_el1() to simulate the down counter. The value is - * clipped from 64 to 32 bits. + * counter. The value is clipped from 64 to 32 bits. */ - return (uint32_t)(~read_cntps_tval_el1()); + return (uint32_t)(read_cntps_tval_el1()); } /* -- cgit v1.2.3 From 26c22a5e3368157fae6c4e905d3779b445e41cc5 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Thu, 23 Jul 2020 10:31:42 -0700 Subject: Tegra186: sanity check power state type This patch sanity checks the power state type before use, from the platform's PSCI handler. Verified with TFTF Standard Test Suite. Change-Id: Icd45faac6c023d4ce7f3597b698d01b91a218124 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/soc/t186/plat_psci_handlers.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c index 6f58427b3..af4182e24 100644 --- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c @@ -72,6 +72,11 @@ int32_t tegra_soc_validate_power_state(uint32_t power_state, case PSTATE_ID_CORE_IDLE: case PSTATE_ID_CORE_POWERDN: + if (psci_get_pstate_type(power_state) != PSTATE_TYPE_POWERDOWN) { + ret = PSCI_E_INVALID_PARAMS; + break; + } + /* Core powerdown request */ req_state->pwr_domain_state[MPIDR_AFFLVL0] = state_id; req_state->pwr_domain_state[MPIDR_AFFLVL1] = state_id; -- cgit v1.2.3 From 5a22eb421d30093a44ca8ef04325ebb9c2472ca3 Mon Sep 17 00:00:00 2001 From: anzhou Date: Tue, 21 Jul 2020 16:22:44 +0800 Subject: Tegra: platform specific BL31_SIZE This patch moves the BL31_SIZE to the Tegra SoC specific tegra_def.h. This helps newer platforms configure the size of the memory available for BL31. Signed-off-by: anzhou Change-Id: I43c60b82fa7e43d5b05d87fbe7d673d729380d82 --- plat/nvidia/tegra/include/platform_def.h | 1 - plat/nvidia/tegra/include/t132/tegra_def.h | 5 +++++ plat/nvidia/tegra/include/t186/tegra_def.h | 5 +++++ plat/nvidia/tegra/include/t194/tegra_def.h | 5 +++++ plat/nvidia/tegra/include/t210/tegra_def.h | 5 +++++ 5 files changed, 20 insertions(+), 1 deletion(-) diff --git a/plat/nvidia/tegra/include/platform_def.h b/plat/nvidia/tegra/include/platform_def.h index 2331869d2..2bfd79782 100644 --- a/plat/nvidia/tegra/include/platform_def.h +++ b/plat/nvidia/tegra/include/platform_def.h @@ -66,7 +66,6 @@ /******************************************************************************* * BL31 specific defines. ******************************************************************************/ -#define BL31_SIZE U(0x40000) #define BL31_BASE TZDRAM_BASE #define BL31_LIMIT (TZDRAM_BASE + BL31_SIZE - 1) #define BL32_BASE (TZDRAM_BASE + BL31_SIZE) diff --git a/plat/nvidia/tegra/include/t132/tegra_def.h b/plat/nvidia/tegra/include/t132/tegra_def.h index afdcd3691..6b87655e3 100644 --- a/plat/nvidia/tegra/include/t132/tegra_def.h +++ b/plat/nvidia/tegra/include/t132/tegra_def.h @@ -10,6 +10,11 @@ #include +/******************************************************************************* + * Platform BL31 specific defines. + ******************************************************************************/ +#define BL31_SIZE U(0x40000) + /******************************************************************************* * This value is used by the PSCI implementation during the `SYSTEM_SUSPEND` * call as the `state-id` field in the 'power state' parameter. diff --git a/plat/nvidia/tegra/include/t186/tegra_def.h b/plat/nvidia/tegra/include/t186/tegra_def.h index 33b21021b..a971cec93 100644 --- a/plat/nvidia/tegra/include/t186/tegra_def.h +++ b/plat/nvidia/tegra/include/t186/tegra_def.h @@ -10,6 +10,11 @@ #include +/******************************************************************************* + * Platform BL31 specific defines. + ******************************************************************************/ +#define BL31_SIZE U(0x40000) + /******************************************************************************* * MCE apertures used by the ARI interface * diff --git a/plat/nvidia/tegra/include/t194/tegra_def.h b/plat/nvidia/tegra/include/t194/tegra_def.h index 2d8b88c93..abe193fcd 100644 --- a/plat/nvidia/tegra/include/t194/tegra_def.h +++ b/plat/nvidia/tegra/include/t194/tegra_def.h @@ -9,6 +9,11 @@ #include +/******************************************************************************* + * Platform BL31 specific defines. + ******************************************************************************/ +#define BL31_SIZE U(0x40000) + /******************************************************************************* * Chip specific cluster and cpu numbers ******************************************************************************/ diff --git a/plat/nvidia/tegra/include/t210/tegra_def.h b/plat/nvidia/tegra/include/t210/tegra_def.h index 32fcb4bd8..81b25e036 100644 --- a/plat/nvidia/tegra/include/t210/tegra_def.h +++ b/plat/nvidia/tegra/include/t210/tegra_def.h @@ -10,6 +10,11 @@ #include +/******************************************************************************* + * Platform BL31 specific defines. + ******************************************************************************/ +#define BL31_SIZE U(0x40000) + /******************************************************************************* * Power down state IDs ******************************************************************************/ -- cgit v1.2.3 From 5f902752e5c78112ebc8103b6d313171791ab755 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Wed, 5 Aug 2020 23:10:40 -0700 Subject: cpus: denver: skip DCO enable/disable for recent SKUs DCO is not supported by the SKUs released after MIDR_PN4. This patch skips enabling or disabling the DCO on these SKUs. Change-Id: Ic31a829de3ae560314d0fb5c5e867689d4ba243b Signed-off-by: Varun Wadekar --- lib/cpus/aarch64/denver.S | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/lib/cpus/aarch64/denver.S b/lib/cpus/aarch64/denver.S index 83427b84f..224ee2676 100644 --- a/lib/cpus/aarch64/denver.S +++ b/lib/cpus/aarch64/denver.S @@ -161,13 +161,19 @@ endfunc denver_disable_ext_debug * ---------------------------------------------------- */ func denver_enable_dco + /* DCO is not supported on PN5 and later */ + mrs x1, midr_el1 + mov_imm x2, DENVER_MIDR_PN4 + cmp x1, x2 + b.hi 1f + mov x18, x30 bl plat_my_core_pos mov x1, #1 lsl x1, x1, x0 msr s3_0_c15_c0_2, x1 mov x30, x18 - ret +1: ret endfunc denver_enable_dco /* ---------------------------------------------------- @@ -175,10 +181,14 @@ endfunc denver_enable_dco * ---------------------------------------------------- */ func denver_disable_dco - - mov x18, x30 + /* DCO is not supported on PN5 and later */ + mrs x1, midr_el1 + mov_imm x2, DENVER_MIDR_PN4 + cmp x1, x2 + b.hi 2f /* turn off background work */ + mov x18, x30 bl plat_my_core_pos mov x1, #1 lsl x1, x1, x0 @@ -194,7 +204,7 @@ func denver_disable_dco cbnz x2, 1b mov x30, x18 - ret +2: ret endfunc denver_disable_dco func check_errata_cve_2017_5715 -- cgit v1.2.3 From c23f5e1cb920bbf6d623a6f91719eb98a5292e52 Mon Sep 17 00:00:00 2001 From: anzhou Date: Wed, 5 Aug 2020 22:34:13 +0800 Subject: Tegra: common: disable GICC after domain off The the GIC CPU interface should be disabled after cpu off. The Tegra power management code should mark the connected core as asleep as part of the CPU off sequence. This patch disables the GICC after CPU off as a result. Signed-off-by: anzhou Change-Id: Ib1a3d8903f5e6d55bd2ee0c16134dbe2562235ea --- plat/nvidia/tegra/common/tegra_pm.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plat/nvidia/tegra/common/tegra_pm.c b/plat/nvidia/tegra/common/tegra_pm.c index d0191d07d..27dd3a290 100644 --- a/plat/nvidia/tegra/common/tegra_pm.c +++ b/plat/nvidia/tegra/common/tegra_pm.c @@ -96,6 +96,9 @@ static int32_t tegra_pwr_domain_on(u_register_t mpidr) static void tegra_pwr_domain_off(const psci_power_state_t *target_state) { (void)tegra_soc_pwr_domain_off(target_state); + + /* disable GICC */ + tegra_gic_cpuif_deactivate(); } /******************************************************************************* -- cgit v1.2.3 From a565d16cd17090e30b6632e9ca56481def0b6395 Mon Sep 17 00:00:00 2001 From: anzhou Date: Tue, 4 Aug 2020 22:05:19 +0800 Subject: Tegra: common: fixup the bl31 code size to be copied at reset If the CPU doesn't run from BL31_BASE, the firmware needs to be copied from load address to BL31_BASE during cold boot. The size should be the actual size of the code, which is indicated by the __RELA_END__ linker variable. This patch updates the copy routine to use this variable as a result. Signed-off-by: anzhou Change-Id: Ie3a48dd54cda1dc152204903d609da3117a0ced9 --- plat/nvidia/tegra/common/aarch64/tegra_helpers.S | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S index 64d21b49c..6c8c4f018 100644 --- a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S +++ b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S @@ -215,7 +215,8 @@ func plat_reset_handler */ mov x0, x17 mov x1, x18 - mov x2, #BL31_SIZE + adr x2, __RELA_END__ + sub x2, x2, x18 _loop16: cmp x2, #16 b.lo _loop1 -- cgit v1.2.3 From fc19818874f1f18c3617df9e426fc27e3425c910 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Tue, 17 Sep 2019 15:29:05 -0700 Subject: spd: trusty: allow clients to retrieve service UUID This patch implements support for the 64-bit and 32-bit versions of 0xBF00FF01 SMC function ID, as documented by the SMCCC, to allow non-secure world clients to query SPD's UUID. In order to service this FID, the Trusty SPD now increases the range of SMCs that it services. To restrict Trusty from receiving the extra SMC FIDs, this patch drops any unsupported FID. Verified with TFTF tests for UID query and internal gtest for Trusty. Change-Id: If96fe4993f7e641595cfe67cc6b4210a0d52403f Signed-off-by: Varun Wadekar --- services/spd/trusty/smcall.h | 8 ++++++++ services/spd/trusty/trusty.c | 21 ++++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/services/spd/trusty/smcall.h b/services/spd/trusty/smcall.h index 9c1c38c74..c66f7db86 100644 --- a/services/spd/trusty/smcall.h +++ b/services/spd/trusty/smcall.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -71,4 +72,11 @@ #define SMC_YC_VDEV_KICK_VQ SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 24U) #define SMC_YC_SET_ROT_PARAMS SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 65535U) +/* + * Standard Trusted OS Function IDs that fall under Trusted OS call range + * according to SMC calling convention + */ +#define SMC_FC64_GET_UUID SMC_FASTCALL64_NR(63U, 0xFF01U) /* Implementation UID */ +#define SMC_FC_GET_UUID SMC_FASTCALL_NR(63U, 0xFF01U) /* Implementation.UID */ + #endif /* SMCALL_H */ diff --git a/services/spd/trusty/trusty.c b/services/spd/trusty/trusty.c index b10da7679..e102b8228 100644 --- a/services/spd/trusty/trusty.c +++ b/services/spd/trusty/trusty.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -16,11 +17,18 @@ #include #include #include +#include #include +#include #include "sm_err.h" #include "smcall.h" +/* Trusty UID: RFC-4122 compliant UUID version 4 */ +DEFINE_SVC_UUID2(trusty_uuid, + 0x40ee25f0, 0xa2bc, 0x304c, 0x8c, 0x4c, + 0xa1, 0x73, 0xc5, 0x7d, 0x8a, 0xf1); + /* macro to check if Hypervisor is enabled in the HCR_EL2 register */ #define HYP_ENABLE_FLAG 0x286001U @@ -256,6 +264,11 @@ static uintptr_t trusty_smc_handler(uint32_t smc_fid, SMC_RET1(handle, SMC_UNK); } else { switch (smc_fid) { + case SMC_FC64_GET_UUID: + case SMC_FC_GET_UUID: + /* provide the UUID for the service to the client */ + SMC_UUID_RET(handle, trusty_uuid); + break; case SMC_FC64_SET_FIQ_HANDLER: return trusty_set_fiq_handler(handle, x1, x2, x3); case SMC_FC64_GET_FIQ_REGS: @@ -263,6 +276,12 @@ static uintptr_t trusty_smc_handler(uint32_t smc_fid, case SMC_FC_FIQ_EXIT: return trusty_fiq_exit(handle, x1, x2, x3); default: + /* Not all OENs greater than SMC_ENTITY_SECURE_MONITOR are supported */ + if (SMC_ENTITY(smc_fid) > SMC_ENTITY_SECURE_MONITOR) { + VERBOSE("%s: unsupported SMC FID (0x%x)\n", __func__, smc_fid); + SMC_RET1(handle, SMC_UNK); + } + if (is_hypervisor_mode()) vmid = SMC_GET_GP(handle, CTX_GPREG_X7); @@ -502,7 +521,7 @@ DECLARE_RT_SVC( trusty_fast, OEN_TOS_START, - SMC_ENTITY_SECURE_MONITOR, + OEN_TOS_END, SMC_TYPE_FAST, trusty_setup, trusty_smc_handler -- cgit v1.2.3 From 74a3460039854aa5694b8fae79af558b81d32e27 Mon Sep 17 00:00:00 2001 From: Hsin-Yi Wang Date: Thu, 27 Aug 2020 13:48:48 +0800 Subject: mediatek: Add jedec info Add jedec info for mt8173, mt8183, and mt8192. [1] http://www.softnology.biz/pdf/JEP106AV.pdf Signed-off-by: Hsin-Yi Wang Change-Id: Iab36fd580131f0b09b27223fba0e9d1e187d9196 --- plat/mediatek/common/mtk_plat_common.c | 32 +++++++++++++++++++++++++++++ plat/mediatek/common/mtk_plat_common.h | 3 +++ plat/mediatek/mt8173/include/platform_def.h | 2 ++ plat/mediatek/mt8183/include/platform_def.h | 2 ++ plat/mediatek/mt8192/include/platform_def.h | 2 ++ 5 files changed, 41 insertions(+) diff --git a/plat/mediatek/common/mtk_plat_common.c b/plat/mediatek/common/mtk_plat_common.c index a07a2981a..f57e4357d 100644 --- a/plat/mediatek/common/mtk_plat_common.c +++ b/plat/mediatek/common/mtk_plat_common.c @@ -10,8 +10,10 @@ #include #include #include +#include #include #include +#include #include #include @@ -116,3 +118,33 @@ uint32_t plat_get_spsr_for_bl33_entry(void) spsr = SPSR_MODE32(mode, 0, ee, daif); return spsr; } + +/***************************************************************************** + * plat_is_smccc_feature_available() - This function checks whether SMCCC + * feature is availabile for platform. + * @fid: SMCCC function id + * + * Return SMC_OK if SMCCC feature is available and SMC_ARCH_CALL_NOT_SUPPORTED + * otherwise. + *****************************************************************************/ +int32_t plat_is_smccc_feature_available(u_register_t fid) +{ + switch (fid) { + case SMCCC_ARCH_SOC_ID: + return SMC_ARCH_CALL_SUCCESS; + default: + return SMC_ARCH_CALL_NOT_SUPPORTED; + } +} + +int32_t plat_get_soc_version(void) +{ + uint32_t manfid = (JEDEC_MTK_BKID << 24U) | (JEDEC_MTK_MFID << 16U); + + return (int32_t)(manfid | (SOC_CHIP_ID & 0xFFFFU)); +} + +int32_t plat_get_soc_revision(void) +{ + return 0; +} diff --git a/plat/mediatek/common/mtk_plat_common.h b/plat/mediatek/common/mtk_plat_common.h index 55f4c516e..919c17358 100644 --- a/plat/mediatek/common/mtk_plat_common.h +++ b/plat/mediatek/common/mtk_plat_common.h @@ -18,6 +18,9 @@ #define LINUX_KERNEL_32 0 #define SMC32_PARAM_MASK (0xFFFFFFFF) +#define JEDEC_MTK_BKID U(4) +#define JEDEC_MTK_MFID U(0x26) + struct atf_arg_t { unsigned int atf_magic; unsigned int tee_support; diff --git a/plat/mediatek/mt8173/include/platform_def.h b/plat/mediatek/mt8173/include/platform_def.h index 22129db13..d34042218 100644 --- a/plat/mediatek/mt8173/include/platform_def.h +++ b/plat/mediatek/mt8173/include/platform_def.h @@ -51,6 +51,8 @@ PLATFORM_CLUSTER_COUNT + \ PLATFORM_CORE_COUNT) +#define SOC_CHIP_ID U(0x8173) + /******************************************************************************* * Platform memory map related constants ******************************************************************************/ diff --git a/plat/mediatek/mt8183/include/platform_def.h b/plat/mediatek/mt8183/include/platform_def.h index 49a0f805e..25ccfbc52 100644 --- a/plat/mediatek/mt8183/include/platform_def.h +++ b/plat/mediatek/mt8183/include/platform_def.h @@ -279,6 +279,8 @@ INTR_PROP_DESC(MT_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, grp, \ PLATFORM_CLUSTER_COUNT + \ PLATFORM_CORE_COUNT) +#define SOC_CHIP_ID U(0x8183) + /******************************************************************************* * Platform memory map related constants ******************************************************************************/ diff --git a/plat/mediatek/mt8192/include/platform_def.h b/plat/mediatek/mt8192/include/platform_def.h index e1f0faf60..f68015a97 100644 --- a/plat/mediatek/mt8192/include/platform_def.h +++ b/plat/mediatek/mt8192/include/platform_def.h @@ -59,6 +59,8 @@ #define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER0_CORE_COUNT) #define PLATFORM_MAX_CPUS_PER_CLUSTER U(8) +#define SOC_CHIP_ID U(0x8192) + /******************************************************************************* * Platform memory map related constants ******************************************************************************/ -- cgit v1.2.3 From 780dd2b310facce54188b190d683f21123b5148e Mon Sep 17 00:00:00 2001 From: Javier Almansa Sobrino Date: Tue, 25 Aug 2020 16:16:29 +0100 Subject: Add support to export a /cpus node to the device tree. This patch creates and populates the /cpus node in a device tree based on the existing topology. It uses the minimum required nodes and properties to satisfy the binding as specified in https://www.kernel.org/doc/Documentation/devicetree/bindings/arm/cpus.txt Signed-off-by: Javier Almansa Sobrino Change-Id: I03bf4e9a6427da0a3b8ed013f93d7bc43b5c4df0 --- common/fdt_fixup.c | 171 ++++++++++++++++++++++++++++++++++++++++++++- include/common/fdt_fixup.h | 4 +- 2 files changed, 172 insertions(+), 3 deletions(-) diff --git a/common/fdt_fixup.c b/common/fdt_fixup.c index d518eb2a4..980e60d45 100644 --- a/common/fdt_fixup.c +++ b/common/fdt_fixup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -14,15 +14,20 @@ * that. */ +#include +#include #include #include +#include #include +#include +#include #include #include +#include -#include static int append_psci_compatible(void *fdt, int offs, const char *str) { @@ -210,3 +215,165 @@ int fdt_add_reserved_memory(void *dtb, const char *node_name, return 0; } + +/******************************************************************************* + * fdt_add_cpu() Add a new CPU node to the DT + * @dtb: Pointer to the device tree blob in memory + * @parent: Offset of the parent node + * @mpidr: MPIDR for the current CPU + * + * Create and add a new cpu node to a DTB. + * + * Return the offset of the new node or a negative value in case of error + ******************************************************************************/ + +static int fdt_add_cpu(void *dtb, int parent, u_register_t mpidr) +{ + int cpu_offs; + int err; + char snode_name[15]; + uint64_t reg_prop; + + reg_prop = mpidr & MPID_MASK & ~MPIDR_MT_MASK; + + snprintf(snode_name, sizeof(snode_name), "cpu@%x", + (unsigned int)reg_prop); + + cpu_offs = fdt_add_subnode(dtb, parent, snode_name); + if (cpu_offs < 0) { + ERROR ("FDT: add subnode \"%s\" failed: %i\n", + snode_name, cpu_offs); + return cpu_offs; + } + + err = fdt_setprop_string(dtb, cpu_offs, "compatible", "arm,armv8"); + if (err < 0) { + ERROR ("FDT: write to \"%s\" property of node at offset %i failed\n", + "compatible", cpu_offs); + return err; + } + + err = fdt_setprop_u64(dtb, cpu_offs, "reg", reg_prop); + if (err < 0) { + ERROR ("FDT: write to \"%s\" property of node at offset %i failed\n", + "reg", cpu_offs); + return err; + } + + err = fdt_setprop_string(dtb, cpu_offs, "device_type", "cpu"); + if (err < 0) { + ERROR ("FDT: write to \"%s\" property of node at offset %i failed\n", + "device_type", cpu_offs); + return err; + } + + err = fdt_setprop_string(dtb, cpu_offs, "enable-method", "psci"); + if (err < 0) { + ERROR ("FDT: write to \"%s\" property of node at offset %i failed\n", + "enable-method", cpu_offs); + return err; + } + + return cpu_offs; +} + +/****************************************************************************** + * fdt_add_cpus_node() - Add the cpus node to the DTB + * @dtb: pointer to the device tree blob in memory + * @afflv0: Maximum number of threads per core (affinity level 0). + * @afflv1: Maximum number of CPUs per cluster (affinity level 1). + * @afflv2: Maximum number of clusters (affinity level 2). + * + * Iterate over all the possible MPIDs given the maximum affinity levels and + * add a cpus node to the DTB with all the valid CPUs on the system. + * If there is already a /cpus node, exit gracefully + * + * A system with two CPUs would generate a node equivalent or similar to: + * + * cpus { + * #address-cells = <2>; + * #size-cells = <0>; + * + * cpu0: cpu@0 { + * compatible = "arm,armv8"; + * reg = <0x0 0x0>; + * device_type = "cpu"; + * enable-method = "psci"; + * }; + * cpu1: cpu@10000 { + * compatible = "arm,armv8"; + * reg = <0x0 0x100>; + * device_type = "cpu"; + * enable-method = "psci"; + * }; + * }; + * + * Full documentation about the CPU bindings can be found at: + * https://www.kernel.org/doc/Documentation/devicetree/bindings/arm/cpus.txt + * + * Return the offset of the node or a negative value on error. + ******************************************************************************/ + +int fdt_add_cpus_node(void *dtb, unsigned int afflv0, + unsigned int afflv1, unsigned int afflv2) +{ + int offs; + int err; + unsigned int i, j, k; + u_register_t mpidr; + int cpuid; + + if (fdt_path_offset(dtb, "/cpus") >= 0) { + return -EEXIST; + } + + offs = fdt_add_subnode(dtb, 0, "cpus"); + if (offs < 0) { + ERROR ("FDT: add subnode \"cpus\" node to parent node failed"); + return offs; + } + + err = fdt_setprop_u32(dtb, offs, "#address-cells", 2); + if (err < 0) { + ERROR ("FDT: write to \"%s\" property of node at offset %i failed\n", + "#address-cells", offs); + return err; + } + + err = fdt_setprop_u32(dtb, offs, "#size-cells", 0); + if (err < 0) { + ERROR ("FDT: write to \"%s\" property of node at offset %i failed\n", + "#size-cells", offs); + return err; + } + + /* + * Populate the node with the CPUs. + * As libfdt prepends subnodes within a node, reverse the index count + * so the CPU nodes would be better ordered. + */ + for (i = afflv2; i > 0U; i--) { + for (j = afflv1; j > 0U; j--) { + for (k = afflv0; k > 0U; k--) { + mpidr = ((i - 1) << MPIDR_AFF2_SHIFT) | + ((j - 1) << MPIDR_AFF1_SHIFT) | + ((k - 1) << MPIDR_AFF0_SHIFT) | + (read_mpidr_el1() & MPIDR_MT_MASK); + + cpuid = plat_core_pos_by_mpidr(mpidr); + if (cpuid >= 0) { + /* Valid MPID found */ + err = fdt_add_cpu(dtb, offs, mpidr); + if (err < 0) { + ERROR ("FDT: %s 0x%08x\n", + "error adding CPU", + (uint32_t)mpidr); + return err; + } + } + } + } + } + + return offs; +} diff --git a/include/common/fdt_fixup.h b/include/common/fdt_fixup.h index 0248de9cf..29d8b3aa0 100644 --- a/include/common/fdt_fixup.h +++ b/include/common/fdt_fixup.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,5 +11,7 @@ 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); #endif /* FDT_FIXUP_H */ -- cgit v1.2.3 From 75e1dfa038fd2f88959dd7b618984e54ee4fa594 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Tue, 1 Sep 2020 14:16:44 -0700 Subject: spmd: remove assert for SPMC PC value This patch removes the assert that expects the SPMC PC value to be same as BL32_BASE. This assumption is not true for all platforms e.g. Tegra, and so will be removed from the SPMD. Platforms can always add this check to the platform files, if required. Change-Id: Ic40620b43d160feb4f72f4af18e6d01861d4bf37 Signed-off-by: Varun Wadekar --- services/std_svc/spmd/spmd_main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c index 6f0d9b1dc..7d207ea15 100644 --- a/services/std_svc/spmd/spmd_main.c +++ b/services/std_svc/spmd/spmd_main.c @@ -249,7 +249,6 @@ static int spmd_spmc_init(void *pm_addr) } SET_PARAM_HEAD(spmc_ep_info, PARAM_EP, VERSION_1, ep_attr); - assert(spmc_ep_info->pc == BL32_BASE); /* * Populate SPSR for SPM Core based upon validated parameters from the -- cgit v1.2.3 From 3ab336a12511dc46f5a1aad1c68e927e195f418a Mon Sep 17 00:00:00 2001 From: Anders Dellien Date: Sun, 23 Aug 2020 19:32:48 +0100 Subject: plat/arm: Add dependencies to configuration files This patch adds dependencies to the generated configuration files that are included in the FIP. This fixes occasional build errors that occur when the FIP happens to be built first. Change-Id: I5a2bf724ba3aee13954403b141f2f19b4fd51d1b Signed-off-by: Anders Dellien --- plat/arm/board/a5ds/platform.mk | 6 +++--- plat/arm/board/corstone700/platform.mk | 2 +- plat/arm/board/fvp/platform.mk | 14 +++++++------- plat/arm/board/fvp_ve/platform.mk | 6 +++--- plat/arm/board/juno/platform.mk | 4 ++-- plat/arm/board/rddaniel/platform.mk | 6 +++--- plat/arm/board/rddanielxlr/platform.mk | 6 +++--- plat/arm/board/rde1edge/platform.mk | 6 +++--- plat/arm/board/rdn1edge/platform.mk | 6 +++--- plat/arm/board/sgi575/platform.mk | 6 +++--- plat/arm/board/sgm775/platform.mk | 4 ++-- plat/arm/board/tc0/platform.mk | 6 +++--- 12 files changed, 36 insertions(+), 36 deletions(-) diff --git a/plat/arm/board/a5ds/platform.mk b/plat/arm/board/a5ds/platform.mk index 5d610f49c..8b0dc5cf3 100644 --- a/plat/arm/board/a5ds/platform.mk +++ b/plat/arm/board/a5ds/platform.mk @@ -77,14 +77,14 @@ FW_CONFIG := ${BUILD_PLAT}/fdts/a5ds_fw_config.dtb TB_FW_CONFIG := ${BUILD_PLAT}/fdts/a5ds_tb_fw_config.dtb # Add the TB_FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG})) # Add the FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG})) $(eval FVP_HW_CONFIG := ${BUILD_PLAT}/$(patsubst %.dts,%.dtb, \ fdts/$(notdir ${FVP_HW_CONFIG_DTS}))) # Add the HW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${FVP_HW_CONFIG},--hw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${FVP_HW_CONFIG},--hw-config,${FVP_HW_CONFIG})) FDT_SOURCES += plat/arm/board/a5ds/fdts/a5ds_fw_config.dts \ plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts \ diff --git a/plat/arm/board/corstone700/platform.mk b/plat/arm/board/corstone700/platform.mk index 513af3c20..9a8d38c11 100644 --- a/plat/arm/board/corstone700/platform.mk +++ b/plat/arm/board/corstone700/platform.mk @@ -48,7 +48,7 @@ FDT_SOURCES += ${CORSTONE700_HW_CONFIG_DTS} $(eval CORSTONE700_HW_CONFIG := ${BUILD_PLAT}/$(patsubst %.dts,%.dtb,$(CORSTONE700_HW_CONFIG_DTS))) # Add the HW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${CORSTONE700_HW_CONFIG},--hw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${CORSTONE700_HW_CONFIG},--hw-config,${CORSTONE700_HW_CONFIG})) # Check for Linux kernel as a BL33 image by default $(eval $(call add_define,ARM_LINUX_KERNEL_AS_BL33)) diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index a7d18252d..5affea967 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -243,7 +243,7 @@ FDT_SOURCES += plat/arm/board/fvp/fdts/${PLAT}_tsp_fw_config.dts FVP_TOS_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tsp_fw_config.dtb # Add the TOS_FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TOS_FW_CONFIG},--tos-fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TOS_FW_CONFIG},--tos-fw-config,${FVP_TOS_FW_CONFIG})) endif ifeq (${SPD},spmd) @@ -256,23 +256,23 @@ FDT_SOURCES += ${ARM_SPMC_MANIFEST_DTS} FVP_TOS_FW_CONFIG := ${BUILD_PLAT}/fdts/$(notdir $(basename ${ARM_SPMC_MANIFEST_DTS})).dtb # Add the TOS_FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TOS_FW_CONFIG},--tos-fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TOS_FW_CONFIG},--tos-fw-config,${FVP_TOS_FW_CONFIG})) endif # Add the FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${FVP_FW_CONFIG},--fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${FVP_FW_CONFIG},--fw-config,${FVP_FW_CONFIG})) # Add the TB_FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config,${FVP_TB_FW_CONFIG})) # Add the SOC_FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${FVP_SOC_FW_CONFIG},--soc-fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${FVP_SOC_FW_CONFIG},--soc-fw-config,${FVP_SOC_FW_CONFIG})) # Add the NT_FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${FVP_NT_FW_CONFIG},--nt-fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${FVP_NT_FW_CONFIG},--nt-fw-config,${FVP_NT_FW_CONFIG})) FDT_SOURCES += ${FVP_HW_CONFIG_DTS} $(eval FVP_HW_CONFIG := ${BUILD_PLAT}/$(patsubst %.dts,%.dtb,$(FVP_HW_CONFIG_DTS))) # Add the HW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${FVP_HW_CONFIG},--hw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${FVP_HW_CONFIG},--hw-config,${FVP_HW_CONFIG})) endif # Enable Activity Monitor Unit extensions by default diff --git a/plat/arm/board/fvp_ve/platform.mk b/plat/arm/board/fvp_ve/platform.mk index 0aa1de4b8..ac45d57ee 100644 --- a/plat/arm/board/fvp_ve/platform.mk +++ b/plat/arm/board/fvp_ve/platform.mk @@ -81,15 +81,15 @@ FVP_FW_CONFIG := ${BUILD_PLAT}/fdts/fvp_ve_fw_config.dtb FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/fvp_ve_tb_fw_config.dtb # Add the FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${FVP_FW_CONFIG},--fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${FVP_FW_CONFIG},--fw-config,${FVP_FW_CONFIG})) # Add the TB_FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config,${FVP_TB_FW_CONFIG})) FDT_SOURCES += ${FVP_HW_CONFIG_DTS} $(eval FVP_HW_CONFIG := ${BUILD_PLAT}/$(patsubst %.dts,%.dtb, \ fdts/$(notdir ${FVP_HW_CONFIG_DTS}))) # Add the HW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${FVP_HW_CONFIG},--hw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${FVP_HW_CONFIG},--hw-config,${FVP_HW_CONFIG})) endif NEED_BL32 := yes diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk index 196d3c044..78704b583 100644 --- a/plat/arm/board/juno/platform.mk +++ b/plat/arm/board/juno/platform.mk @@ -172,9 +172,9 @@ FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb # Add the FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG})) # Add the TB_FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG})) include plat/arm/board/common/board_common.mk include plat/arm/common/arm_common.mk diff --git a/plat/arm/board/rddaniel/platform.mk b/plat/arm/board/rddaniel/platform.mk index 81632a5f1..8909b551c 100644 --- a/plat/arm/board/rddaniel/platform.mk +++ b/plat/arm/board/rddaniel/platform.mk @@ -44,14 +44,14 @@ FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb # Add the FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG})) # Add the TB_FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG})) FDT_SOURCES += ${RDDANIEL_BASE}/fdts/${PLAT}_nt_fw_config.dts NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb # Add the NT_FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config,${NT_FW_CONFIG})) override CTX_INCLUDE_AARCH32_REGS := 0 diff --git a/plat/arm/board/rddanielxlr/platform.mk b/plat/arm/board/rddanielxlr/platform.mk index 93967ad28..61af81aab 100644 --- a/plat/arm/board/rddanielxlr/platform.mk +++ b/plat/arm/board/rddanielxlr/platform.mk @@ -47,9 +47,9 @@ FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb # Add the FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG})) # Add the TB_FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG})) $(eval $(call CREATE_SEQ,SEQ,4)) ifneq ($(CSS_SGI_CHIP_COUNT),$(filter $(CSS_SGI_CHIP_COUNT),$(SEQ))) @@ -61,6 +61,6 @@ FDT_SOURCES += ${RDDANIELXLR_BASE}/fdts/${PLAT}_nt_fw_config.dts NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb # Add the NT_FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config,${NT_FW_CONFIG})) override CTX_INCLUDE_AARCH32_REGS := 0 diff --git a/plat/arm/board/rde1edge/platform.mk b/plat/arm/board/rde1edge/platform.mk index e09afcad3..a7c043413 100644 --- a/plat/arm/board/rde1edge/platform.mk +++ b/plat/arm/board/rde1edge/platform.mk @@ -41,15 +41,15 @@ FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb # Add the FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG})) # Add the TB_FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG})) FDT_SOURCES += ${RDE1EDGE_BASE}/fdts/${PLAT}_nt_fw_config.dts NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb # Add the NT_FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config,${NT_FW_CONFIG})) ifneq ($(CSS_SGI_CHIP_COUNT),1) $(error "Chip count for RDE1Edge should be 1, currently set to \ diff --git a/plat/arm/board/rdn1edge/platform.mk b/plat/arm/board/rdn1edge/platform.mk index 3f0cc7f4a..819e892f6 100644 --- a/plat/arm/board/rdn1edge/platform.mk +++ b/plat/arm/board/rdn1edge/platform.mk @@ -47,15 +47,15 @@ FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb # Add the FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config),${FW_CONFIG}) # Add the TB_FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG})) FDT_SOURCES += ${RDN1EDGE_BASE}/fdts/${PLAT}_nt_fw_config.dts NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb # Add the NT_FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config,${NT_FW_CONFIG})) $(eval $(call CREATE_SEQ,SEQ,2)) ifneq ($(CSS_SGI_CHIP_COUNT),$(filter $(CSS_SGI_CHIP_COUNT),$(SEQ))) diff --git a/plat/arm/board/sgi575/platform.mk b/plat/arm/board/sgi575/platform.mk index f5d547dd1..56f5733f1 100644 --- a/plat/arm/board/sgi575/platform.mk +++ b/plat/arm/board/sgi575/platform.mk @@ -42,15 +42,15 @@ FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb # Add the FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG})) # Add the TB_FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG})) FDT_SOURCES += ${SGI575_BASE}/fdts/${PLAT}_nt_fw_config.dts NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb # Add the NT_FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config,${NT_FW_CONFIG})) ifneq ($(CSS_SGI_CHIP_COUNT),1) $(error "Chip count for SGI575 should be 1, currently set to \ diff --git a/plat/arm/board/sgm775/platform.mk b/plat/arm/board/sgm775/platform.mk index 26bc25dec..a649939de 100644 --- a/plat/arm/board/sgm775/platform.mk +++ b/plat/arm/board/sgm775/platform.mk @@ -15,9 +15,9 @@ FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb # Add the FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG})) # Add the TB_FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG})) PLAT_INCLUDES +=-I${SGM775_BASE}/include/ diff --git a/plat/arm/board/tc0/platform.mk b/plat/arm/board/tc0/platform.mk index 0bf18e437..903fabfb0 100644 --- a/plat/arm/board/tc0/platform.mk +++ b/plat/arm/board/tc0/platform.mk @@ -79,9 +79,9 @@ FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb # Add the FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG})) # Add the TB_FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG})) #Device tree TC0_HW_CONFIG_DTS := fdts/tc0.dts @@ -90,7 +90,7 @@ FDT_SOURCES += ${TC0_HW_CONFIG_DTS} $(eval TC0_HW_CONFIG := ${BUILD_PLAT}/$(patsubst %.dts,%.dtb,$(TC0_HW_CONFIG_DTS))) # Add the HW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${TC0_HW_CONFIG},--hw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${TC0_HW_CONFIG},--hw-config,${TC0_HW_CONFIG})) override CTX_INCLUDE_AARCH32_REGS := 0 -- cgit v1.2.3 From 20ff991e92de860237080fb4936e9dc28fde0810 Mon Sep 17 00:00:00 2001 From: Javier Almansa Sobrino Date: Thu, 4 Jun 2020 19:01:48 +0100 Subject: arm_fpga: Add support to populate the CPU nodes in the DTB At the moment BL31 dynamically discovers the CPU topology of an FPGA system at runtime, but does not export it to the non-secure world. Any BL33 user would typically looks at the devicetree to learn about existing CPUs. This patch exports a minimum /cpus node in a devicetree to satisfy the binding. This means that no cpumaps or caches are described. This could be added later if needed. An existing /cpus node in the DT will make the code bail out with a message. Signed-off-by: Javier Almansa Sobrino Change-Id: I589a2b3412411a3660134bdcef3a65e8200e1d7e --- plat/arm/board/arm_fpga/fpga_bl31_setup.c | 20 ++++++++++++++++++++ plat/arm/board/arm_fpga/platform.mk | 1 + 2 files changed, 21 insertions(+) diff --git a/plat/arm/board/arm_fpga/fpga_bl31_setup.c b/plat/arm/board/arm_fpga/fpga_bl31_setup.c index 9db107cc8..de6d9d5e3 100644 --- a/plat/arm/board/arm_fpga/fpga_bl31_setup.c +++ b/plat/arm/board/arm_fpga/fpga_bl31_setup.c @@ -5,7 +5,9 @@ */ #include +#include +#include #include #include #include @@ -193,6 +195,24 @@ static void fpga_prepare_dtb(void) } } + if (err < 0) { + ERROR("Error %d extending Device Tree\n", err); + panic(); + } + + err = fdt_add_cpus_node(fdt, FPGA_MAX_PE_PER_CPU, + FPGA_MAX_CPUS_PER_CLUSTER, + FPGA_MAX_CLUSTER_COUNT); + + if (err == -EEXIST) { + WARN("Not overwriting already existing /cpus node in DTB\n"); + } else { + if (err < 0) { + ERROR("Error %d creating the /cpus DT node\n", err); + panic(); + } + } + 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/platform.mk b/plat/arm/board/arm_fpga/platform.mk index 1e7badf50..890433983 100644 --- a/plat/arm/board/arm_fpga/platform.mk +++ b/plat/arm/board/arm_fpga/platform.mk @@ -86,6 +86,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 \ drivers/delay_timer/delay_timer.c \ drivers/delay_timer/generic_delay_timer.c \ drivers/arm/pl011/${ARCH}/pl011_console.S \ -- cgit v1.2.3 From 942013e1dd57429432cd71cfe121d702e3c52465 Mon Sep 17 00:00:00 2001 From: Pramod Kumar Date: Wed, 5 Feb 2020 11:27:57 +0530 Subject: lib: cpu: Check SCU presence in DSU before accessing DSU registers The DSU contains system control registers in the SCU and L3 logic to control the functionality of the cluster. If "DIRECT CONNECT" L3 memory system variant is used, there won't be any L3 cache, snoop filter, and SCU logic present hence no system control register will be present. Hence check SCU presence before accessing DSU register for DSU_936184 errata. Signed-off-by: Pramod Kumar Change-Id: I1ffa8afb0447ae3bd1032c9dd678d68021fe5a63 --- include/lib/cpus/aarch64/neoverse_n1.h | 8 +++++++ lib/cpus/aarch64/dsu_helpers.S | 38 +++++++++++++++++++++++++--------- lib/cpus/aarch64/neoverse_n1.S | 13 ++++++++++++ 3 files changed, 49 insertions(+), 10 deletions(-) diff --git a/include/lib/cpus/aarch64/neoverse_n1.h b/include/lib/cpus/aarch64/neoverse_n1.h index b50befa8d..9998b93f2 100644 --- a/include/lib/cpus/aarch64/neoverse_n1.h +++ b/include/lib/cpus/aarch64/neoverse_n1.h @@ -64,4 +64,12 @@ #define CPUPOR_EL3 S3_6_C15_C8_2 #define CPUPMR_EL3 S3_6_C15_C8_3 +/****************************************************************************** + * CPU Configuration register definitions. + *****************************************************************************/ +#define CPUCFR_EL1 S3_0_C15_C0_0 + +/* SCU bit of CPU Configuration Register, EL1 */ +#define SCU_SHIFT U(2) + #endif /* NEOVERSE_N1_H */ diff --git a/lib/cpus/aarch64/dsu_helpers.S b/lib/cpus/aarch64/dsu_helpers.S index 100ffaa97..da052d5c9 100644 --- a/lib/cpus/aarch64/dsu_helpers.S +++ b/lib/cpus/aarch64/dsu_helpers.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -72,18 +72,36 @@ endfunc errata_dsu_798953_wa * This function is called from both assembly and C environment. So it * follows AAPCS. * - * Clobbers: x0-x3 + * Clobbers: x0-x15 * ----------------------------------------------------------------------- */ .globl check_errata_dsu_936184 .globl errata_dsu_936184_wa + .weak is_scu_present_in_dsu + + /* -------------------------------------------------------------------- + * Default behaviour respresents SCU is always present with DSU. + * CPUs can override this definition if required. + * + * Can clobber only: x0-x14 + * -------------------------------------------------------------------- + */ +func is_scu_present_in_dsu + mov x0, #1 + ret +endfunc is_scu_present_in_dsu func check_errata_dsu_936184 - mov x2, #ERRATA_NOT_APPLIES - mov x3, #ERRATA_APPLIES + mov x15, x30 + bl is_scu_present_in_dsu + cmp x0, xzr + /* Default error status */ + mov x0, #ERRATA_NOT_APPLIES + + /* If SCU is not present, return without applying patch */ + b.eq 1f /* Erratum applies only if DSU has the ACP interface */ - mov x0, x2 mrs x1, CLUSTERCFR_EL1 ubfx x1, x1, #CLUSTERCFR_ACP_SHIFT, #1 cbz x1, 1f @@ -92,13 +110,13 @@ func check_errata_dsu_936184 mrs x1, CLUSTERIDR_EL1 /* DSU variant and revision bitfields in CLUSTERIDR are adjacent */ - ubfx x0, x1, #CLUSTERIDR_REV_SHIFT,\ + ubfx x2, x1, #CLUSTERIDR_REV_SHIFT,\ #(CLUSTERIDR_REV_BITS + CLUSTERIDR_VAR_BITS) - mov x1, #(0x2 << CLUSTERIDR_VAR_SHIFT) - cmp x0, x1 - csel x0, x2, x3, hs + cmp x2, #(0x2 << CLUSTERIDR_VAR_SHIFT) + b.hs 1f + mov x0, #ERRATA_APPLIES 1: - ret + ret x15 endfunc check_errata_dsu_936184 /* -------------------------------------------------- diff --git a/lib/cpus/aarch64/neoverse_n1.S b/lib/cpus/aarch64/neoverse_n1.S index d537ed6a8..5a2b5e452 100644 --- a/lib/cpus/aarch64/neoverse_n1.S +++ b/lib/cpus/aarch64/neoverse_n1.S @@ -22,6 +22,19 @@ #endif .global neoverse_n1_errata_ic_trap_handler + .global is_scu_present_in_dsu + +/* + * Check DSU is configured with SCU and L3 unit + * 1-> SCU present + * 0-> SCU not present + */ +func is_scu_present_in_dsu + mrs x0, CPUCFR_EL1 + ubfx x0, x0, #SCU_SHIFT, #1 + eor x0, x0, #1 + ret +endfunc is_scu_present_in_dsu /* -------------------------------------------------- * Errata Workaround for Neoverse N1 Erratum 1043202. -- cgit v1.2.3 From e3f2b1a93211811567a2db0938b814758401b358 Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Tue, 1 Sep 2020 15:38:32 +0100 Subject: plat/arm: Introduce and use libc_asm.mk makefile Trace analysis of FVP_Base_AEMv8A 0.0/6063 model running in Aarch32 mode with the build options listed below: TRUSTED_BOARD_BOOT=1 GENERATE_COT=1 ARM_ROTPK_LOCATION=devel_ecdsa KEY_ALG=ecdsa ROT_KEY=plat/arm/board/common/rotpk/arm_rotprivk_ecdsa.pem shows that when auth_signature() gets called 71.99% of CPU execution time is spent in memset() function written in C using single byte write operations, see lib\libc\memset.c. This patch introduces new libc_asm.mk makefile which replaces C memset() implementation with assembler version giving the following results: - for Aarch32 in auth_signature() call memset() CPU time reduced to 20.56%. The number of CPU instructions (Inst) executed during TF-A boot stage before start of BL33 in RELEASE builds for different versions is presented in the tables below, where: - C TF-A: existing TF-A C code; - C musl: "lightweight code" C "implementation of the standard library for Linux-based systems" https://git.musl-libc.org/cgit/musl/tree/src/string/memset.c - Asm Opt: assemler version from "Arm Optimized Routines" project https://github.com/ARM-software/optimized-routines/blob/ master/string/arm/memset.S - Asm Linux: assembler version from Linux kernel https://github.com/torvalds/linux/blob/master/arch/arm/lib/memset.S - Asm TF-A: assembler version from this patch Aarch32: +-----------+------+------+--------------+----------+ | Variant | Set | Size | Inst | Ratio | +-----------+------+------+--------------+----------+ | C TF-A | T32 | 16 | 2122110003 | 1.000000 | | C musl | T32 | 156 | 1643917668 | 0.774662 | | Asm Opt | T32 | 84 | 1604810003 | 0.756233 | | Asm Linux | A32 | 168 | 1566255018 | 0.738065 | | Asm TF-A | A32 | 160 | 1525865101 | 0.719032 | +-----------+------+------+--------------+----------+ AArch64: +-----------+------+------------+----------+ | Variant | Size | Inst | Ratio | +-----------+------+------------+----------+ | C TF-A | 28 | 2732497518 | 1.000000 | | C musl | 212 | 1802999999 | 0.659836 | | Asm TF-A | 140 | 1680260003 | 0.614917 | +-----------+------+------------+----------+ This patch modifies 'plat\arm\common\arm_common.mk' by overriding libc.mk makefile with libc_asm.mk and does not effect other platforms. Change-Id: Ie89dd0b74ba1079420733a0d76b7366ad0157c2e Signed-off-by: Alexei Fedorov --- lib/libc/aarch32/memset.S | 74 +++++++++++++++++++++++++++++++++++++++++++ lib/libc/aarch64/memset.S | 64 +++++++++++++++++++++++++++++++++++++ lib/libc/libc_asm.mk | 38 ++++++++++++++++++++++ plat/arm/common/arm_common.mk | 6 ++++ 4 files changed, 182 insertions(+) create mode 100644 lib/libc/aarch32/memset.S create mode 100644 lib/libc/aarch64/memset.S create mode 100644 lib/libc/libc_asm.mk diff --git a/lib/libc/aarch32/memset.S b/lib/libc/aarch32/memset.S new file mode 100644 index 000000000..880ba8382 --- /dev/null +++ b/lib/libc/aarch32/memset.S @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + + .syntax unified + .global memset + +/* ----------------------------------------------------------------------- + * void *memset(void *dst, int val, size_t count) + * + * Copy the value of 'val' (converted to an unsigned char) into + * each of the first 'count' characters of the object pointed to by 'dst'. + * + * Returns the value of 'dst'. + * ----------------------------------------------------------------------- + */ +func memset + mov r12, r0 /* keep r0 */ + tst r0, #3 + beq aligned /* 4-bytes aligned */ + + /* Unaligned 'dst' */ +unaligned: + subs r2, r2, #1 + strbhs r1, [r12], #1 + bxls lr /* return if 0 */ + tst r12, #3 + bne unaligned /* continue while unaligned */ + + /* 4-bytes aligned */ +aligned:bfi r1, r1, #8, #8 /* propagate 'val' */ + bfi r1, r1, #16, #16 + + mov r3, r1 + + cmp r2, #16 + blo less_16 /* < 16 */ + + push {r4, lr} + mov r4, r1 + mov lr, r1 + +write_32: + subs r2, r2, #32 + stmiahs r12!, {r1, r3, r4, lr} + stmiahs r12!, {r1, r3, r4, lr} + bhi write_32 /* write 32 bytes in a loop */ + popeq {r4, pc} /* return if 0 */ + lsls r2, r2, #28 /* C = r2[4]; N = r2[3]; Z = r2[3:0] */ + stmiacs r12!, {r1, r3, r4, lr} /* write 16 bytes */ + popeq {r4, pc} /* return if 16 */ + stmiami r12!, {r1, r3} /* write 8 bytes */ + lsls r2, r2, #2 /* C = r2[2]; N = r2[1]; Z = r2[1:0] */ + strcs r1, [r12], #4 /* write 4 bytes */ + popeq {r4, pc} /* return if 8 or 4 */ + strhmi r1, [r12], #2 /* write 2 bytes */ + lsls r2, r2, #1 /* N = Z = r2[0] */ + strbmi r1, [r12] /* write 1 byte */ + pop {r4, pc} + +less_16:lsls r2, r2, #29 /* C = r2[3]; N = r2[2]; Z = r2[2:0] */ + stmiacs r12!, {r1, r3} /* write 8 bytes */ + bxeq lr /* return if 8 */ + strmi r1, [r12], #4 /* write 4 bytes */ + lsls r2, r2, #2 /* C = r2[1]; N = Z = r2[0] */ + strhcs r1, [r12], #2 /* write 2 bytes */ + strbmi r1, [r12] /* write 1 byte */ + bx lr + +endfunc memset diff --git a/lib/libc/aarch64/memset.S b/lib/libc/aarch64/memset.S new file mode 100644 index 000000000..05437041d --- /dev/null +++ b/lib/libc/aarch64/memset.S @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + + .global memset + +/* ----------------------------------------------------------------------- + * void *memset(void *dst, int val, size_t count) + * + * Copy the value of 'val' (converted to an unsigned char) into + * each of the first 'count' characters of the object pointed to by 'dst'. + * + * Returns the value of 'dst'. + * ----------------------------------------------------------------------- + */ +func memset + cbz x2, exit /* exit if 'count' = 0 */ + mov x3, x0 /* keep x0 */ + tst x0, #7 + b.eq aligned /* 8-bytes aligned */ + + /* Unaligned 'dst' */ +unaligned: + strb w1, [x3], #1 + subs x2, x2, #1 + b.eq exit /* exit if 0 */ + tst x3, #7 + b.ne unaligned /* continue while unaligned */ + + /* 8-bytes aligned */ +aligned:cbz x1, x1_zero + bfi w1, w1, #8, #8 /* propagate 'val' */ + bfi w1, w1, #16, #16 + bfi x1, x1, #32, #32 + +x1_zero:ands x4, x2, #~0x3f + b.eq less_64 + +write_64: + .rept 4 + stp x1, x1, [x3], #16 /* write 64 bytes in a loop */ + .endr + subs x4, x4, #64 + b.ne write_64 +less_64:tbz w2, #5, less_32 /* < 32 bytes */ + stp x1, x1, [x3], #16 /* write 32 bytes */ + stp x1, x1, [x3], #16 +less_32:tbz w2, #4, less_16 /* < 16 bytes */ + stp x1, x1, [x3], #16 /* write 16 bytes */ +less_16:tbz w2, #3, less_8 /* < 8 bytes */ + str x1, [x3], #8 /* write 8 bytes */ +less_8: tbz w2, #2, less_4 /* < 4 bytes */ + str w1, [x3], #4 /* write 4 bytes */ +less_4: tbz w2, #1, less_2 /* < 2 bytes */ + strh w1, [x3], #2 /* write 2 bytes */ +less_2: tbz w2, #0, exit + strb w1, [x3] /* write 1 byte */ +exit: ret + +endfunc memset diff --git a/lib/libc/libc_asm.mk b/lib/libc/libc_asm.mk new file mode 100644 index 000000000..6416a3c84 --- /dev/null +++ b/lib/libc/libc_asm.mk @@ -0,0 +1,38 @@ +# +# Copyright (c) 2020, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +LIBC_SRCS := $(addprefix lib/libc/, \ + abort.c \ + assert.c \ + exit.c \ + memchr.c \ + memcmp.c \ + memcpy.c \ + memmove.c \ + memrchr.c \ + printf.c \ + putchar.c \ + puts.c \ + snprintf.c \ + strchr.c \ + strcmp.c \ + strlcpy.c \ + strlen.c \ + strncmp.c \ + strnlen.c \ + strrchr.c) + +ifeq (${ARCH},aarch64) +LIBC_SRCS += $(addprefix lib/libc/aarch64/, \ + memset.S \ + setjmp.S) +else +LIBC_SRCS += $(addprefix lib/libc/aarch32/, \ + memset.S) +endif + +INCLUDES += -Iinclude/lib/libc \ + -Iinclude/lib/libc/$(ARCH) \ diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index 96ab2d300..224de9d11 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -121,6 +121,12 @@ endif ENABLE_PSCI_STAT := 1 ENABLE_PMF := 1 +# Override the standard libc with optimised libc_asm +OVERRIDE_LIBC := 1 +ifeq (${OVERRIDE_LIBC},1) + include lib/libc/libc_asm.mk +endif + # On ARM platforms, separate the code and read-only data sections to allow # mapping the former as executable and the latter as execute-never. SEPARATE_CODE_AND_RODATA := 1 -- cgit v1.2.3 From 2274490945695c1da37bc5b708212a40073d7891 Mon Sep 17 00:00:00 2001 From: Sandeep Tripathy Date: Mon, 17 Aug 2020 20:22:13 +0530 Subject: psci: utility api to invoke stop for other cores The API can be used to invoke a 'stop_func' callback for all other cores from any initiating core. Optionally it can also wait for other cores to power down. There may be various use of such API by platform. Ex: Platform may use this to power down all other cores from a crashed core. Signed-off-by: Sandeep Tripathy Change-Id: I4f9dc8a38d419f299c021535d5f1bcc6883106f9 --- include/lib/psci/psci_lib.h | 2 ++ lib/psci/psci_common.c | 47 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/include/lib/psci/psci_lib.h b/include/lib/psci/psci_lib.h index 76c1a8dcf..1ac45adf7 100644 --- a/include/lib/psci/psci_lib.h +++ b/include/lib/psci/psci_lib.h @@ -89,6 +89,8 @@ void psci_warmboot_entrypoint(void); void psci_register_spd_pm_hook(const spd_pm_ops_t *pm); void psci_prepare_next_non_secure_ctx( entry_point_info_t *next_image_info); +int psci_stop_other_cores(unsigned int wait_ms, + void (*stop_func)(u_register_t mpidr)); #endif /* __ASSEMBLER__ */ #endif /* PSCI_LIB_H */ diff --git a/lib/psci/psci_common.c b/lib/psci/psci_common.c index cced2761f..6d813774d 100644 --- a/lib/psci/psci_common.c +++ b/lib/psci/psci_common.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -973,3 +974,49 @@ void psci_do_pwrdown_sequence(unsigned int power_level) psci_do_pwrdown_cache_maintenance(power_level); #endif } + +/******************************************************************************* + * This function invokes the callback 'stop_func()' with the 'mpidr' of each + * online PE. Caller can pass suitable method to stop a remote core. + * + * 'wait_ms' is the timeout value in milliseconds for the other cores to + * transition to power down state. Passing '0' makes it non-blocking. + * + * The function returns 'PSCI_E_DENIED' if some cores failed to stop within the + * given timeout. + ******************************************************************************/ +int psci_stop_other_cores(unsigned int wait_ms, + void (*stop_func)(u_register_t mpidr)) +{ + unsigned int idx, this_cpu_idx; + + this_cpu_idx = plat_my_core_pos(); + + /* Invoke stop_func for each core */ + for (idx = 0U; idx < psci_plat_core_count; idx++) { + /* skip current CPU */ + if (idx == this_cpu_idx) { + continue; + } + + /* Check if the CPU is ON */ + if (psci_get_aff_info_state_by_idx(idx) == AFF_STATE_ON) { + (*stop_func)(psci_cpu_pd_nodes[idx].mpidr); + } + } + + /* Need to wait for other cores to shutdown */ + if (wait_ms != 0U) { + while ((wait_ms-- != 0U) && (psci_is_last_on_cpu() != 0U)) { + mdelay(1U); + } + + if (psci_is_last_on_cpu() != 0U) { + WARN("Failed to stop all cores!\n"); + psci_print_power_domain_map(); + return PSCI_E_DENIED; + } + } + + return PSCI_E_SUCCESS; +} -- cgit v1.2.3 From aec40abcf9ec0b026171e0f062b03b1504883fb2 Mon Sep 17 00:00:00 2001 From: Javier Almansa Sobrino Date: Thu, 3 Sep 2020 10:29:24 +0100 Subject: Add Chris Kay as code owner for CMake Build Definitions. Signed-off-by: Javier Almansa Sobrino Change-Id: I69365d4aed1160af41e291f6e4b1dd31cbd12e02 --- docs/about/maintainers.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst index 50abc814f..8614ff874 100644 --- a/docs/about/maintainers.rst +++ b/docs/about/maintainers.rst @@ -64,6 +64,8 @@ Build Definitions for CMake Build System ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :M: Javier Almansa Sobrino :G: `javieralso-arm`_ +:M: Chris Kay +:G: `CJkay`_ :F: / Software Delegated Exception Interface (SDEI) @@ -646,5 +648,6 @@ Build system .. _madhukar-Arm: https://github.com/madhukar-Arm .. _john-powell-arm: https://github.com/john-powell-arm .. _raghuncstate: https://github.com/raghuncstate +.. _CJKay: https://github.com/cjkay .. _Project Maintenance Process: https://developer.trustedfirmware.org/w/collaboration/project-maintenance-process/ -- cgit v1.2.3 From 75fab6496e5fce9a11b4e3a160ad2e797acc6ee9 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 3 Sep 2020 11:04:39 +0100 Subject: libc: memset: improve performance by avoiding single byte writes Currently our memset() implementation is safe, but slow. The main reason for that seems to be the single byte writes that it issues, which can show horrible performance, depending on the implementation of the load/store subsystem. Improve the algorithm by trying to issue 64-bit writes. As this only works with aligned pointers, have a head and a tail section which covers unaligned pointers, and leave the bulk of the work to the middle section that does use 64-bit writes. Put through some unit tests, which exercise all combinations of nasty input parameters (pointers with various alignments, various odd and even sizes, corner cases of content to write (-1, 256)). Change-Id: I28ddd3d388cc4989030f1a70447581985368d5bb Signed-off-by: Andre Przywara --- lib/libc/memset.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/lib/libc/memset.c b/lib/libc/memset.c index d8007d8e9..f9dd4c5db 100644 --- a/lib/libc/memset.c +++ b/lib/libc/memset.c @@ -1,18 +1,48 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include #include +#include void *memset(void *dst, int val, size_t count) { char *ptr = dst; + uint64_t *ptr64; + uint64_t fill = (unsigned char)val; - while (count--) + /* Simplify code below by making sure we write at least one byte. */ + if (count == 0) { + return dst; + } + + /* Handle the first part, until the pointer becomes 64-bit aligned. */ + while (((uintptr_t)ptr & 7)) { + *ptr++ = val; + if (--count == 0) { + return dst; + } + } + + /* Duplicate the fill byte to the rest of the 64-bit word. */ + fill |= fill << 8; + fill |= fill << 16; + fill |= fill << 32; + + /* Use 64-bit writes for as long as possible. */ + ptr64 = (void *)ptr; + for (; count >= 8; count -= 8) { + *ptr64++ = fill; + } + + /* Handle the remaining part byte-per-byte. */ + ptr = (void *)ptr64; + while (count--) { *ptr++ = val; + } return dst; } -- cgit v1.2.3 From b13e3f9f98d08b8583db64d62acd947e727a1a4d Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Sat, 5 Sep 2020 04:40:41 +0100 Subject: tools: Set the tool's default binary name This patch: fafd3ec9c assumes that tools must build from the main makefile folder. This assumption leads to the error when somebody wants to build a tool from the tool's folder. Hence changes are done to provide the default binary name in the tool's makefile. Change-Id: Iae570a7f8d322151376b6feb19e739300eecc3fc Signed-off-by: Manish V Badarkhe --- tools/cert_create/Makefile | 1 + tools/encrypt_fw/Makefile | 1 + tools/fiptool/Makefile | 1 + tools/sptool/Makefile | 1 + 4 files changed, 4 insertions(+) diff --git a/tools/cert_create/Makefile b/tools/cert_create/Makefile index 418e06cf3..0ec08b054 100644 --- a/tools/cert_create/Makefile +++ b/tools/cert_create/Makefile @@ -7,6 +7,7 @@ PLAT := none V ?= 0 DEBUG := 0 +CRTTOOL ?= cert_create${BIN_EXT} BINARY := $(notdir ${CRTTOOL}) OPENSSL_DIR := /usr COT := tbbr diff --git a/tools/encrypt_fw/Makefile b/tools/encrypt_fw/Makefile index ebbc66a8e..6eb6fae7a 100644 --- a/tools/encrypt_fw/Makefile +++ b/tools/encrypt_fw/Makefile @@ -7,6 +7,7 @@ V ?= 0 BUILD_INFO ?= 1 DEBUG := 0 +ENCTOOL ?= encrypt_fw${BIN_EXT} BINARY := $(notdir ${ENCTOOL}) OPENSSL_DIR := /usr diff --git a/tools/fiptool/Makefile b/tools/fiptool/Makefile index 0ede6cebb..df8ab5c7b 100644 --- a/tools/fiptool/Makefile +++ b/tools/fiptool/Makefile @@ -8,6 +8,7 @@ MAKE_HELPERS_DIRECTORY := ../../make_helpers/ include ${MAKE_HELPERS_DIRECTORY}build_macros.mk include ${MAKE_HELPERS_DIRECTORY}build_env.mk +FIPTOOL ?= fiptool${BIN_EXT} PROJECT := $(notdir ${FIPTOOL}) OBJECTS := fiptool.o tbbr_config.o V ?= 0 diff --git a/tools/sptool/Makefile b/tools/sptool/Makefile index f724c265a..1fa85fb20 100644 --- a/tools/sptool/Makefile +++ b/tools/sptool/Makefile @@ -8,6 +8,7 @@ MAKE_HELPERS_DIRECTORY := ../../make_helpers/ include ${MAKE_HELPERS_DIRECTORY}build_macros.mk include ${MAKE_HELPERS_DIRECTORY}build_env.mk +SPTOOL ?= sptool${BIN_EXT} PROJECT := $(notdir ${SPTOOL}) OBJECTS := sptool.o V ?= 0 -- cgit v1.2.3 From dad2934c4914031019c6f4b7886820d0a6a9bc4b Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Thu, 3 Sep 2020 16:54:47 +0100 Subject: plat: Fix build issue for qemu and rpi3 platforms Coverity build periodically throws below errors(non-consistently) for 'QEMU' and 'RPI3' platforms. /bin/sh: 1: cannot create build/qemu/debug/rot_key.pem: Directory nonexistent plat/qemu/qemu/platform.mk:86: recipe for target 'build/qemu/debug/ rot_key.pem' failed make: *** [build/qemu/debug/rot_key.pem] Error 2 /bin/sh: 1: cannot create /work/workspace/workspace/tf-coverity/build /rpi3/debug/rot_key.pem: Directory nonexistent plat/rpi/rpi3/platform.mk:214: recipe for target '/work/workspace/ workspace/tf-coverity/build/rpi3/debug/rot_key.pem' failed make: *** [/work/workspace/workspace/tf-coverity/build/rpi3/debug/ rot_key.pem] Error 2 Issue seems to be occurred when 'ROT key' is generated before creating the platform build folder(for e.g.build/qemu/debug). Changes are made to fix this issue by adding orderly dependancy of the platform folder for the 'ROT key' creation which ensures that platform folder is created before generating 'ROT key'. Signed-off-by: Manish V Badarkhe Change-Id: I20c82172dde84e4c7f2373c0bd095d353f845d38 --- plat/qemu/qemu/platform.mk | 2 +- plat/rpi/rpi3/platform.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plat/qemu/qemu/platform.mk b/plat/qemu/qemu/platform.mk index 944143795..14bf049be 100644 --- a/plat/qemu/qemu/platform.mk +++ b/plat/qemu/qemu/platform.mk @@ -84,7 +84,7 @@ ifneq (${TRUSTED_BOARD_BOOT},0) certificates: $(ROT_KEY) - $(ROT_KEY): + $(ROT_KEY): | $(BUILD_PLAT) @echo " OPENSSL $@" $(Q)openssl genrsa 2048 > $@ 2>/dev/null diff --git a/plat/rpi/rpi3/platform.mk b/plat/rpi/rpi3/platform.mk index 4d627b8a5..6c239230d 100644 --- a/plat/rpi/rpi3/platform.mk +++ b/plat/rpi/rpi3/platform.mk @@ -210,7 +210,7 @@ ifneq (${TRUSTED_BOARD_BOOT},0) certificates: $(ROT_KEY) - $(ROT_KEY): + $(ROT_KEY): | $(BUILD_PLAT) @echo " OPENSSL $@" $(Q)openssl genrsa 2048 > $@ 2>/dev/null -- cgit v1.2.3 From 23875c3f63b9d83c923828315281c5083439e80f Mon Sep 17 00:00:00 2001 From: Rui Miguel Silva Date: Wed, 15 Jul 2020 10:08:55 +0100 Subject: fdts: corstone700: add NXP isp1763 node to device tree Add USB IP node as the MPS3 board has the NXP isp1763 host controller. Change-Id: I47c57e4c8345d244c46895b52fcaecc1c6f1b504 Signed-off-by: Rui Miguel Silva Signed-off-by: lakshmi Kailasanathan --- fdts/corstone700_fpga.dts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fdts/corstone700_fpga.dts b/fdts/corstone700_fpga.dts index 814d6a862..1ac0d4b84 100644 --- a/fdts/corstone700_fpga.dts +++ b/fdts/corstone700_fpga.dts @@ -20,6 +20,13 @@ reg-io-width = <2>; smsc,irq-push-pull; }; + + usb: usb@4020000 { + compatible = "nxp,usb-isp1763"; + reg = <0x40200000 0x100000>; + interrupt-parent = <&gic>; + interrupts = ; + }; }; &refclk { -- cgit v1.2.3 From f7fb0bf77f3434bfb67411cad65e704fdef27f76 Mon Sep 17 00:00:00 2001 From: Max Shvetsov Date: Tue, 25 Aug 2020 11:50:18 +0100 Subject: Fix: fixing coverity issue for SPM Core. spmd_get_context_by_mpidr was using potentially negative value as an array index. plat_core_pos_by_mpidr could return -1 on failure which is utilized by some platforms. Signed-off-by: Max Shvetsov Change-Id: I7f8827e77f18da389c9cafdc1fc841aba9f03120 --- services/std_svc/spmd/spmd_main.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c index 6f0d9b1dc..10da08ebe 100644 --- a/services/std_svc/spmd/spmd_main.c +++ b/services/std_svc/spmd/spmd_main.c @@ -46,7 +46,14 @@ static entry_point_info_t *spmc_ep_info; ******************************************************************************/ spmd_spm_core_context_t *spmd_get_context_by_mpidr(uint64_t mpidr) { - return &spm_core_context[plat_core_pos_by_mpidr(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); + panic(); + } + + return &spm_core_context[core_idx]; } /******************************************************************************* -- cgit v1.2.3 From 0dc522943c05eafe8fbf8344d4129604f0f0892f Mon Sep 17 00:00:00 2001 From: Avinash Mehta Date: Wed, 22 Jul 2020 16:40:07 +0100 Subject: Enabling DPU in dts file for TC0 This change replaces hdlcd with DPU in dts file for TC0 Change-Id: If25dfd3ddffc07279ab487f65e1bb82b27a26604 Signed-off-by: Avinash Mehta --- fdts/tc0.dts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/fdts/tc0.dts b/fdts/tc0.dts index cab39a770..ac097cdde 100644 --- a/fdts/tc0.dts +++ b/fdts/tc0.dts @@ -224,7 +224,7 @@ port { vencoder_in: endpoint { - remote-endpoint = <&hdlcd_out>; + remote-endpoint = <&dp_pl0_out0>; }; }; @@ -250,7 +250,7 @@ interrupts = <0x0 117 0x4>; clocks = <&fake_hdlcd_clk>; clock-names = "pxlclk"; - status = "ok"; + status = "disabled"; port { hdlcd_out: endpoint { @@ -339,7 +339,6 @@ interrupt-names = "DPU"; clocks = <&scmi_clk 0>; clock-names = "aclk"; - status = "disabled"; pl0: pipeline@0 { reg = <0>; clocks = <&scmi_clk 1>; -- cgit v1.2.3 From 9ac093b6518bb029d324b08590881ad78cfb1477 Mon Sep 17 00:00:00 2001 From: Saurabh Gorecha Date: Mon, 7 Sep 2020 14:52:20 +0530 Subject: Addition of standard APIs in qtiseclib interface Follwing APIs wrappers are exposed to qtiseclib * strcmp * memset * memmove Change-Id: I79d50f358239cfda607d5f1a53314aa3b8f430cb Signed-off-by: Saurabh Gorecha --- plat/qti/qtiseclib/inc/qtiseclib_cb_interface.h | 5 +++++ plat/qti/qtiseclib/src/qtiseclib_cb_interface.c | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/plat/qti/qtiseclib/inc/qtiseclib_cb_interface.h b/plat/qti/qtiseclib/inc/qtiseclib_cb_interface.h index 9c4a7247b..2252557a0 100644 --- a/plat/qti/qtiseclib/inc/qtiseclib_cb_interface.h +++ b/plat/qti/qtiseclib/inc/qtiseclib_cb_interface.h @@ -16,6 +16,9 @@ /* Standard Library API's */ void *qtiseclib_cb_memcpy(void *dst, const void *src, size_t len); +int qtiseclib_cb_strcmp(const char *s1, const char *s2); +void *qtiseclib_cb_memset(void *s, int c, size_t n); +void *qtiseclib_cb_memmove(void *dest, const void *src, size_t n); #define QTISECLIB_CB_ERROR(...) qtiseclib_cb_log(QTISECLIB_LOG_LEVEL_ERROR, __VA_ARGS__) #define QTISECLIB_CB_NOTICE(...) qtiseclib_cb_log(QTISECLIB_LOG_LEVEL_NOTICE, __VA_ARGS__) @@ -41,6 +44,8 @@ void qtiseclib_cb_switch_console_to_crash_state(void); void qtiseclib_cb_udelay(uint32_t usec); +int qtiseclib_cb_console_flush(void); + #if QTI_SDI_BUILD int qtiseclib_cb_mmap_remove_dynamic_region(uintptr_t base_va, size_t size); int qtiseclib_cb_mmap_add_dynamic_region(unsigned long long base_pa, diff --git a/plat/qti/qtiseclib/src/qtiseclib_cb_interface.c b/plat/qti/qtiseclib/src/qtiseclib_cb_interface.c index 1b1393e1e..331a104b2 100644 --- a/plat/qti/qtiseclib/src/qtiseclib_cb_interface.c +++ b/plat/qti/qtiseclib/src/qtiseclib_cb_interface.c @@ -29,6 +29,21 @@ void *qtiseclib_cb_memcpy(void *dst, const void *src, size_t len) return memcpy(dst, src, len); } +int qtiseclib_cb_strcmp(const char *s1, const char *s2) +{ + return strcmp(s1, s2); +} + +void *qtiseclib_cb_memset(void *s, int c, size_t n) +{ + return memset(s, c, n); +} + +void *qtiseclib_cb_memmove(void *dest, const void *src, size_t n) +{ + return memmove(dest, src, n); +} + /* Printing logs below or equal LOG_LEVEL from QTISECLIB. */ void qtiseclib_cb_log(unsigned int loglvl, const char *fmt, ...) { @@ -106,6 +121,11 @@ void qtiseclib_cb_udelay(uint32_t usec) udelay(usec); } +int qtiseclib_cb_console_flush(void) +{ + return console_flush(); +} + #if QTI_SDI_BUILD void qtiseclib_cb_get_ns_ctx(qtiseclib_dbg_a64_ctxt_regs_type *qti_ns_ctx) { -- cgit v1.2.3 From 1123a5e2f973dc9f0223467f4782f6b2df542620 Mon Sep 17 00:00:00 2001 From: Madhukar Pappireddy Date: Fri, 4 Sep 2020 14:04:23 -0500 Subject: libc: Import strlcat from FreeBSD project From commit: 21571b1d140ae7bb44e94c0afba2ec61456b275b Made small changes to fit into TF-A project Change-Id: I07fd7fe1037857f6b299c35367c104fb51fa5cfa Signed-off-by: Madhukar Pappireddy --- include/lib/libc/string.h | 3 ++- lib/libc/strlcat.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 lib/libc/strlcat.c diff --git a/include/lib/libc/string.h b/include/lib/libc/string.h index 71774b0c8..91cbafbb7 100644 --- a/include/lib/libc/string.h +++ b/include/lib/libc/string.h @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ /* - * Portions copyright (c) 2018-2019, ARM Limited and Contributors. + * Portions copyright (c) 2018-2020, ARM Limited and Contributors. * All rights reserved. */ @@ -26,5 +26,6 @@ size_t strlen(const char *s); size_t strnlen(const char *s, size_t maxlen); char *strrchr(const char *p, int ch); size_t strlcpy(char * dst, const char * src, size_t dsize); +size_t strlcat(char * dst, const char * src, size_t dsize); #endif /* STRING_H */ diff --git a/lib/libc/strlcat.c b/lib/libc/strlcat.c new file mode 100644 index 000000000..e60c863a5 --- /dev/null +++ b/lib/libc/strlcat.c @@ -0,0 +1,56 @@ +/* $OpenBSD: strlcat.c,v 1.15 2015/03/02 21:41:08 millert Exp $ */ + +/* + * SPDX-License-Identifier: ISC + * + * Copyright (c) 1998, 2015 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +/* + * Appends src to string dst of size dsize (unlike strncat, dsize is the + * full size of dst, not space left). At most dsize-1 characters + * will be copied. Always NUL terminates (unless dsize <= strlen(dst)). + * Returns strlen(src) + MIN(dsize, strlen(initial dst)). + * If retval >= dsize, truncation occurred. + */ +size_t +strlcat(char * dst, const char * src, size_t dsize) +{ + const char *odst = dst; + const char *osrc = src; + size_t n = dsize; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end. */ + while (n-- != 0 && *dst != '\0') + dst++; + dlen = dst - odst; + n = dsize - dlen; + + if (n-- == 0) + return(dlen + strlen(src)); + while (*src != '\0') { + if (n != 0) { + *dst++ = *src; + n--; + } + src++; + } + *dst = '\0'; + + return(dlen + (src - osrc)); /* count does not include NUL */ +} -- cgit v1.2.3 From 0d4120d87e9cb2f48374909068ad6b9325e25c9c Mon Sep 17 00:00:00 2001 From: Ruari Phipps Date: Mon, 10 Aug 2020 15:53:45 +0100 Subject: SPM: Get rid of uint32_t array representation of UUID UUID's in the device tree files were stored in little endian. So to keep all entries in these files RFC 4122 compliant, store them in big endian then convert it to little endian when they are read so they can be used in the UUID data structure. Signed-off-by: Ruari Phipps Change-Id: I5674159b82b245104381df10a4e3291160d9b3b5 --- plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts | 55 ++++++++++++++-------------- plat/arm/common/fconf/arm_fconf_io.c | 10 +++++ plat/arm/common/fconf/arm_fconf_sp.c | 11 ++++++ 3 files changed, 48 insertions(+), 28 deletions(-) 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 692f5a9cb..fe154e970 100644 --- a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts +++ b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts @@ -40,35 +40,34 @@ }; /* - * Though TF-A is UUID RFC 4122 compliant meaning fields are stored in - * network order (big endian), UUID's mentioned in this file are are - * stored in machine order (little endian). - * This will be fixed in future. + * UUID's here are UUID RFC 4122 compliant meaning fieds are stored in + * network order (big endian) */ + #if ARM_IO_IN_DTB arm-io_policies { fip-handles { compatible = "arm,io-fip-handle"; - scp_bl2_uuid = <0x3dfd6697 0x49e8be89 0xa1785dae 0x13826040>; - bl31_uuid = <0x6d08d447 0x4698fe4c 0x5029959b 0x005abdcb>; - bl32_uuid = <0x89e1d005 0x4713dc53 0xa502b8d 0x383e7a4b>; - bl32_extra1_uuid = <0x9bc2700b 0x40785a2a 0x560a659f 0x88827382>; - bl32_extra2_uuid = <0xb17ba88e 0x4d3fa2cf 0xbbe7fd85 0xd92002a5>; - bl33_uuid = <0xa7eed0d6 0x4bd5eafc 0x34998297 0xe4b634f2>; - hw_cfg_uuid = <0xd9f1b808 0x4993cfc9 0xbc6f62a9 0xcc65726b>; - soc_fw_cfg_uuid = <0x4b817999 0x46fb7603 0x268d8e8c 0xe059787f>; - tos_fw_cfg_uuid = <0x1a7c2526 0x477fc6db 0xc4c4968d 0x218024b0>; - nt_fw_cfg_uuid = <0x1598da28 0x447ee893 0xaf1a66ac 0xf9501580>; - t_key_cert_uuid = <0x90e87e82 0x11e460f8 0x7a77b4a1 0x4cf9b421>; - scp_fw_key_uuid = <0xa1214202 0x11e460f8 0x3cf39b8d 0x14a0150e>; - soc_fw_key_uuid = <0xccbeb88a 0x11e460f9 0x48ebd09a 0xf8dcd822>; - tos_fw_key_cert_uuid = <0x3d67794 0x11e460fb 0x10b7dd85 0x4ee8c5b>; - nt_fw_key_cert_uuid = <0x2a83d58a 0x11e460fb 0x30dfaf8a 0x5998c4bb>; - scp_fw_content_cert_uuid = <0x046fbe44 0x11e4635e 0xd8738bb2 0x5696aeea>; - soc_fw_content_cert_uuid = <0x200cb2e2 0x11e4635e 0xccabe89c 0x66b62bf9>; - tos_fw_content_cert_uuid = <0x11449fa4 0x11e4635e 0x53f2887 0x3df32a72>; - nt_fw_content_cert_uuid = <0xf3c1c48e 0x11e4635d 0xee87a9a7 0xa73fb240>; - sp_content_cert_uuid = <0x44fd6d77 0x3b4c9786 0x3ec1eb91 0x6f2a5a02>; + scp_bl2_uuid = <0x9766fd3d 0x89bee849 0xae5d78a1 0x40608213>; + bl31_uuid = <0x47d4086d 0x4cfe9846 0x9b952950 0xcbbd5a00>; + bl32_uuid = <0x05d0e189 0x53dc1347 0x8d2b500a 0x4b7a3e38>; + bl32_extra1_uuid = <0x0b70c28b 0x2a5a7840 0x9f650a56 0x82738288>; + bl32_extra2_uuid = <0x8ea87bb1 0xcfa23f4d 0x85fde7bb 0xa50220d9>; + bl33_uuid = <0xd6d0eea7 0xfcead54b 0x97829934 0xf234b6e4>; + hw_cfg_uuid = <0x08b8f1d9 0xc9cf9349 0xa9626fbc 0x6b7265cc>; + soc_fw_cfg_uuid = <0x9979814b 0x0376fb46 0x8c8e8d26 0x7f7859e0>; + tos_fw_cfg_uuid = <0x26257c1a 0xdbc67f47 0x8d96c4c4 0xb0248021>; + nt_fw_cfg_uuid = <0x28da9815 0x93e87e44 0xac661aaf 0x801550f9>; + t_key_cert_uuid = <0x827ee890 0xf860e411 0xa1b477a7 0x21b4f94c>; + scp_fw_key_uuid = <0x024221a1 0xf860e411 0x8d9bf33c 0x0e15a014>; + soc_fw_key_uuid = <0x8ab8becc 0xf960e411 0x9ad0eb48 0x22d8dcf8>; + tos_fw_key_cert_uuid = <0x9477d603 0xfb60e411 0x85ddb710 0x5b8cee04>; + nt_fw_key_cert_uuid = <0x8ad5832a 0xfb60e411 0x8aafdf30 0xbbc49859>; + scp_fw_content_cert_uuid = <0x44be6f04 0x5e63e411 0xb28b73d8 0xeaae9656>; + soc_fw_content_cert_uuid = <0xe2b20c20 0x5e63e411 0x9ce8abcc 0xf92bb666>; + tos_fw_content_cert_uuid = <0xa49f4411 0x5e63e411 0x87283f05 0x722af33d>; + nt_fw_content_cert_uuid = <0x8ec4c1f3 0x5d63e411 0xa7a987ee 0x40b23fa7>; + sp_content_cert_uuid = <0x776dfd44 0x86974c3b 0x91ebc13e 0x025a2a6f>; }; }; #endif /* ARM_IO_IN_DTB */ @@ -77,24 +76,24 @@ compatible = "arm,sp"; #ifdef OPTEE_SP_FW_CONFIG op-tee { - uuid = <0xe0786148 0xe311f8e7 0x02005ebc 0x1bc5d5a5>; + uuid = <0x486178e0 0xe7f811e3 0xbc5e0002 0xa5d5c51b>; load-address = <0x6280000>; }; #else cactus-primary { - uuid = <0x1e67b5b4 0xe14f904a 0x13fb1fb8 0xcbdae1da>; + uuid = <0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>; load-address = <0x7000000>; owner = "SiP"; }; cactus-secondary { - uuid = <0x092358d1 0xb94723f0 0x64447c82 0xc88f57f5>; + uuid = <0xd1582309 0xf02347b9 0x827c4464 0xf5578fc8>; load-address = <0x7100000>; owner = "Plat"; }; cactus-tertiary { - uuid = <0x735cb579 0xb9448c1d 0xe1619385 0xd2d80a77>; + uuid = <0x79b55c73 0x1d8c44b9 0x859361e1 0x770ad8d2>; load-address = <0x7200000>; }; #endif diff --git a/plat/arm/common/fconf/arm_fconf_io.c b/plat/arm/common/fconf/arm_fconf_io.c index 5f125d3d5..48286c2f2 100644 --- a/plat/arm/common/fconf/arm_fconf_io.c +++ b/plat/arm/common/fconf/arm_fconf_io.c @@ -249,6 +249,7 @@ int fconf_populate_arm_io_policies(uintptr_t config) { int err, node; unsigned int i; + unsigned int j; union uuid_helper_t uuid_helper; io_uuid_spec_t *uuid_ptr; @@ -274,6 +275,15 @@ int fconf_populate_arm_io_policies(uintptr_t config) return err; } + /* Convert uuid from big endian to little endian */ + for (j = 0U; j < 4U; j++) { + uuid_helper.word[j] = + ((uuid_helper.word[j] >> 24U) & 0xff) | + ((uuid_helper.word[j] << 8U) & 0xff0000) | + ((uuid_helper.word[j] >> 8U) & 0xff00) | + ((uuid_helper.word[j] << 24U) & 0xff000000); + } + VERBOSE("FCONF: arm-io_policies.%s cell found with value = 0x%x 0x%x 0x%x 0x%x\n", load_info[i].name, uuid_helper.word[0], uuid_helper.word[1], diff --git a/plat/arm/common/fconf/arm_fconf_sp.c b/plat/arm/common/fconf/arm_fconf_sp.c index 50a9dd4d5..7950e7f6d 100644 --- a/plat/arm/common/fconf/arm_fconf_sp.c +++ b/plat/arm/common/fconf/arm_fconf_sp.c @@ -37,6 +37,7 @@ int fconf_populate_arm_sp(uintptr_t config) const unsigned int plat_start = SP_PKG5_ID; unsigned int plat_index = plat_start; const unsigned int plat_end = plat_start + MAX_SP_IDS / 2; + unsigned int j; /* As libfdt use void *, we can't avoid this cast */ const void *dtb = (void *)config; @@ -64,6 +65,16 @@ int fconf_populate_arm_sp(uintptr_t config) ERROR("FCONF: cannot read SP uuid\n"); return -1; } + + /* Convert uuid from big endian to little endian */ + for (j = 0U; j < 4U; j++) { + uuid_helper.word[j] = + ((uuid_helper.word[j] >> 24U) & 0xff) | + ((uuid_helper.word[j] << 8U) & 0xff0000) | + ((uuid_helper.word[j] >> 8U) & 0xff00) | + ((uuid_helper.word[j] << 24U) & 0xff000000); + } + arm_sp.uuids[index] = uuid_helper; VERBOSE("FCONF: %s UUID %x-%x-%x-%x load_addr=%lx\n", __func__, -- cgit v1.2.3 From 3280033b2da6b60705612cf2c509eba61da0649e Mon Sep 17 00:00:00 2001 From: Anders Dellien Date: Thu, 10 Sep 2020 09:49:42 +0100 Subject: plat/arm: rdn1edge: Correct mismatched parenthesis in makefile This fixes build errors for rdn1edge Change-Id: I63f7ebff68679e1e859f8786d4def4960c0f2ddf Signed-off-by: Anders Dellien --- plat/arm/board/rdn1edge/platform.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/arm/board/rdn1edge/platform.mk b/plat/arm/board/rdn1edge/platform.mk index 819e892f6..b3134262e 100644 --- a/plat/arm/board/rdn1edge/platform.mk +++ b/plat/arm/board/rdn1edge/platform.mk @@ -47,7 +47,7 @@ FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb # Add the FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config),${FW_CONFIG}) +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG})) # Add the TB_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG})) -- cgit v1.2.3 From deb875b511acdfb02aed3142269162f23f4b57ee Mon Sep 17 00:00:00 2001 From: Sandeep Tripathy Date: Wed, 26 Aug 2020 19:54:41 +0530 Subject: plat: tegra: Use generic ehf defines Use common ehf file for generic frameworks like SDEI, RAS and extend plat specific defines using 'PLAT_EHF_DESC'. Signed-off-by: Sandeep Tripathy Change-Id: I8a8161c6030f8d226a8bdf0301e7fe6139f019a4 --- plat/nvidia/tegra/common/tegra_common.mk | 4 +++- plat/nvidia/tegra/common/tegra_ehf.c | 28 ---------------------------- plat/nvidia/tegra/include/platform_def.h | 3 +++ 3 files changed, 6 insertions(+), 29 deletions(-) delete mode 100644 plat/nvidia/tegra/common/tegra_ehf.c diff --git a/plat/nvidia/tegra/common/tegra_common.mk b/plat/nvidia/tegra/common/tegra_common.mk index bb8bd7d89..c41fcd045 100644 --- a/plat/nvidia/tegra/common/tegra_common.mk +++ b/plat/nvidia/tegra/common/tegra_common.mk @@ -44,7 +44,6 @@ BL31_SOURCES += drivers/delay_timer/delay_timer.c \ ${TEGRA_LIBS}/debug/profiler.c \ ${TEGRA_COMMON}/tegra_bl31_setup.c \ ${TEGRA_COMMON}/tegra_delay_timer.c \ - ${TEGRA_COMMON}/tegra_ehf.c \ ${TEGRA_COMMON}/tegra_fiq_glue.c \ ${TEGRA_COMMON}/tegra_io_storage.c \ ${TEGRA_COMMON}/tegra_platform.c \ @@ -55,3 +54,6 @@ BL31_SOURCES += drivers/delay_timer/delay_timer.c \ ifneq ($(ENABLE_STACK_PROTECTOR), 0) BL31_SOURCES += ${TEGRA_COMMON}/tegra_stack_protector.c endif +ifeq (${EL3_EXCEPTION_HANDLING},1) +BL31_SOURCES += plat/common/aarch64/plat_ehf.c +endif diff --git a/plat/nvidia/tegra/common/tegra_ehf.c b/plat/nvidia/tegra/common/tegra_ehf.c deleted file mode 100644 index ea6e443f3..000000000 --- a/plat/nvidia/tegra/common/tegra_ehf.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include - -/* - * Enumeration of priority levels on Tegra platforms. - */ -ehf_pri_desc_t tegra_exceptions[] = { - /* Watchdog priority */ - EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_TEGRA_WDT_PRIO), - -#if SDEI_SUPPORT - /* Critical priority SDEI */ - EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_SDEI_CRITICAL_PRI), - - /* Normal priority SDEI */ - EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_SDEI_NORMAL_PRI), -#endif -}; - -/* Plug in Tegra exceptions to Exception Handling Framework. */ -EHF_REGISTER_PRIORITIES(tegra_exceptions, ARRAY_SIZE(tegra_exceptions), PLAT_PRI_BITS); diff --git a/plat/nvidia/tegra/include/platform_def.h b/plat/nvidia/tegra/include/platform_def.h index 2331869d2..1176cde82 100644 --- a/plat/nvidia/tegra/include/platform_def.h +++ b/plat/nvidia/tegra/include/platform_def.h @@ -100,6 +100,9 @@ #define PLAT_SDEI_NORMAL_PRI U(0x30) #define PLAT_TEGRA_WDT_PRIO U(0x40) +#define PLAT_EHF_DESC EHF_PRI_DESC(PLAT_PRI_BITS,\ + PLAT_TEGRA_WDT_PRIO) + /******************************************************************************* * SDEI events ******************************************************************************/ -- cgit v1.2.3 From dd14887e15173406f0edb7c39d7f852e45e626f7 Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Mon, 7 Sep 2020 18:11:22 +0100 Subject: tc0: increase SCP_BL2 size to 128 kB The size of debug binaries of SCP has increased beyond the current limit of 80kB set in platform. Hence, increase it to 128kB. Change-Id: I5dbcf87f8fb35672b39abdb942c0691fb339444a Signed-off-by: Usama Arif --- plat/arm/board/tc0/include/platform_def.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plat/arm/board/tc0/include/platform_def.h b/plat/arm/board/tc0/include/platform_def.h index 56c71c16c..a8d471ee3 100644 --- a/plat/arm/board/tc0/include/platform_def.h +++ b/plat/arm/board/tc0/include/platform_def.h @@ -183,12 +183,12 @@ * PLAT_CSS_MAX_SCP_BL2_SIZE is calculated using the current * SCP_BL2 size plus a little space for growth. */ -#define PLAT_CSS_MAX_SCP_BL2_SIZE 0x14000 +#define PLAT_CSS_MAX_SCP_BL2_SIZE 0x20000 /* * PLAT_CSS_MAX_SCP_BL2U_SIZE is calculated using the current * SCP_BL2U size plus a little space for growth. */ -#define PLAT_CSS_MAX_SCP_BL2U_SIZE 0x14000 +#define PLAT_CSS_MAX_SCP_BL2U_SIZE 0x20000 #endif /* PLATFORM_DEF_H */ -- cgit v1.2.3 From ee15a17272abec0b969545dada4258a9e2a3721f Mon Sep 17 00:00:00 2001 From: Leonardo Sandoval Date: Thu, 18 Jun 2020 17:32:55 -0500 Subject: defaults.mk: default KEY_SIZE to 2048 in case of RSA algorithm According to the documentation [1], KEY_SIZE defaults to 2048 when RSA algorithm is chosen, so set this value on the make's defaults file. [1] https://trustedfirmware-a.readthedocs.io/en/latest/getting_started/build-options.html Change-Id: I030f98363198a752bc0dd03528f748de527d48d8 Signed-off-by: Leonardo Sandoval --- make_helpers/defaults.mk | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index 27f8f2a51..7220a5d76 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -157,6 +157,11 @@ HW_ASSISTED_COHERENCY := 0 # Set the default algorithm for the generation of Trusted Board Boot keys KEY_ALG := rsa +# Set the default key size in case KEY_ALG is rsa +ifeq ($(KEY_ALG),rsa) +KEY_SIZE := 2048 +endif + # Option to build TF with Measured Boot support MEASURED_BOOT := 0 -- cgit v1.2.3 From 61f0ffc40abf477bbaa2aaa0e3adee504c288c38 Mon Sep 17 00:00:00 2001 From: johpow01 Date: Wed, 5 Aug 2020 12:27:12 -0500 Subject: Workaround for Neoverse N1 erratum 1868343 Neoverse N1 erratum 1868343 is a Cat B erratum, present in older revisions of the Neoverse N1 processor core. The workaround is to set a bit in the CPUACTLR_EL1 system register, which delays instruction fetch after branch misprediction. This workaround will have a small impact on performance. SDEN can be found here: https://documentation-service.arm.com/static/5f2c130260a93e65927bc92f Signed-off-by: John Powell Change-Id: I37da2b3b2da697701b883bff9a1eff2772352844 --- docs/design/cpu-specific-build-macros.rst | 3 +++ lib/cpus/aarch64/neoverse_n1.S | 38 +++++++++++++++++++++++++++++++ lib/cpus/cpu-ops.mk | 8 +++++++ 3 files changed, 49 insertions(+) diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst index 33b509083..3c0e30f79 100644 --- a/docs/design/cpu-specific-build-macros.rst +++ b/docs/design/cpu-specific-build-macros.rst @@ -294,6 +294,9 @@ For Neoverse N1, the following errata build flags are defined : - ``ERRATA_N1_1542419``: This applies errata 1542419 workaround to Neoverse-N1 CPU. This needs to be enabled only for revisions r3p0 - r4p0 of the CPU. +- ``ERRATA_N1_1868343``: This applies errata 1868343 workaround to Neoverse-N1 + CPU. This needs to be enabled only for revision <= r4p0 of the CPU. + DSU Errata Workarounds ---------------------- diff --git a/lib/cpus/aarch64/neoverse_n1.S b/lib/cpus/aarch64/neoverse_n1.S index 5a2b5e452..03ee47209 100644 --- a/lib/cpus/aarch64/neoverse_n1.S +++ b/lib/cpus/aarch64/neoverse_n1.S @@ -388,6 +388,38 @@ func check_errata_1542419 b cpu_rev_var_range endfunc check_errata_1542419 + /* -------------------------------------------------- + * Errata Workaround for Neoverse N1 Errata #1868343. + * This applies to revision <= r4p0 of Neoverse N1. + * This workaround is the same as the workaround for + * errata 1262606 and 1275112 but applies to a wider + * revision range. + * Inputs: + * x0: variant[4:7] and revision[0:3] of current cpu. + * Shall clobber: x0-x17 + * -------------------------------------------------- + */ +func errata_n1_1868343_wa + /* + * Compare x0 against revision r4p0 + */ + mov x17, x30 + bl check_errata_1868343 + cbz x0, 1f + mrs x1, NEOVERSE_N1_CPUACTLR_EL1 + orr x1, x1, NEOVERSE_N1_CPUACTLR_EL1_BIT_13 + msr NEOVERSE_N1_CPUACTLR_EL1, x1 + isb +1: + ret x17 +endfunc errata_n1_1868343_wa + +func check_errata_1868343 + /* Applies to everything <= r4p0 */ + mov x1, #0x40 + b cpu_rev_var_ls +endfunc check_errata_1868343 + func neoverse_n1_reset_func mov x19, x30 @@ -462,6 +494,11 @@ func neoverse_n1_reset_func bl errata_n1_1542419_wa #endif +#if ERRATA_N1_1868343 + mov x0, x18 + bl errata_n1_1868343_wa +#endif + #if ENABLE_AMU /* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */ mrs x0, actlr_el3 @@ -535,6 +572,7 @@ func neoverse_n1_errata_report report_errata ERRATA_N1_1275112, neoverse_n1, 1275112 report_errata ERRATA_N1_1315703, neoverse_n1, 1315703 report_errata ERRATA_N1_1542419, neoverse_n1, 1542419 + report_errata ERRATA_N1_1868343, neoverse_n1, 1868343 report_errata ERRATA_DSU_936184, neoverse_n1, dsu_936184 ldp x8, x30, [sp], #16 diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk index 8fc3b6063..7cd8ed99e 100644 --- a/lib/cpus/cpu-ops.mk +++ b/lib/cpus/cpu-ops.mk @@ -334,6 +334,10 @@ ERRATA_N1_1315703 ?=0 # to revisions r3p0 - r4p0 of the Neoverse N1 cpu. ERRATA_N1_1542419 ?=0 +# Flag to apply erratum 1868343 workaround during reset. This erratum applies +# to revision <= r4p0 of the Neoverse N1 cpu. +ERRATA_N1_1868343 ?=0 + # Flag to apply DSU erratum 798953. This erratum applies to DSUs revision r0p0. # Applying the workaround results in higher DSU power consumption on idle. ERRATA_DSU_798953 ?=0 @@ -603,6 +607,10 @@ $(eval $(call add_define,ERRATA_N1_1315703)) $(eval $(call assert_boolean,ERRATA_N1_1542419)) $(eval $(call add_define,ERRATA_N1_1542419)) +# Process ERRATA_N1_1868343 flag +$(eval $(call assert_boolean,ERRATA_N1_1868343)) +$(eval $(call add_define,ERRATA_N1_1868343)) + # Process ERRATA_DSU_798953 flag $(eval $(call assert_boolean,ERRATA_DSU_798953)) $(eval $(call add_define,ERRATA_DSU_798953)) -- cgit v1.2.3 From 77648689ad2627911a3aa6fd69463e8043889532 Mon Sep 17 00:00:00 2001 From: Madhukar Pappireddy Date: Tue, 8 Sep 2020 19:00:00 -0500 Subject: libc: Add support for vsnprintf() It uses the existing implementation of snprintf() function Change-Id: Ie59418564c2e415222e819cf322c34e9a4d1f336 Signed-off-by: Madhukar Pappireddy --- include/lib/libc/stdio.h | 1 + lib/libc/snprintf.c | 44 +++++++++++++++++++++++++++++++++++++------- 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/include/lib/libc/stdio.h b/include/lib/libc/stdio.h index 2d9e6557b..ba13683e6 100644 --- a/include/lib/libc/stdio.h +++ b/include/lib/libc/stdio.h @@ -22,6 +22,7 @@ int snprintf(char *s, size_t n, const char *fmt, ...) __printflike(3, 4); #ifdef STDARG_H int vprintf(const char *fmt, va_list args); +int vsnprintf(char *s, size_t n, const char *fmt, va_list args); #endif int putchar(int c); diff --git a/lib/libc/snprintf.c b/lib/libc/snprintf.c index 268632722..6e80d8c03 100644 --- a/lib/libc/snprintf.c +++ b/lib/libc/snprintf.c @@ -77,7 +77,7 @@ static void unsigned_num_print(char **s, size_t n, size_t *chars_printed, } /******************************************************************* - * Reduced snprintf to be used for Trusted firmware. + * Reduced vsnprintf to be used for Trusted firmware. * The following type specifiers are supported: * * %x (or %X) - hexadecimal format @@ -97,9 +97,8 @@ static void unsigned_num_print(char **s, size_t n, size_t *chars_printed, * buffer was big enough. If it returns a value lower than n, the * whole string has been written. *******************************************************************/ -int snprintf(char *s, size_t n, const char *fmt, ...) +int vsnprintf(char *s, size_t n, const char *fmt, va_list args) { - va_list args; int num; unsigned long long int unum; char *str; @@ -120,7 +119,6 @@ int snprintf(char *s, size_t n, const char *fmt, ...) n--; } - va_start(args, fmt); while (*fmt != '\0') { left = false; padc ='\0'; @@ -221,10 +219,42 @@ loop: chars_printed++; } - va_end(args); - - if (n > 0U) + if (n > 0U) { *s = '\0'; + } return (int)chars_printed; } + +/******************************************************************* + * Reduced snprintf to be used for Trusted firmware. + * The following type specifiers are supported: + * + * %x (or %X) - hexadecimal format + * %d or %i - signed decimal format + * %s - string format + * %u - unsigned decimal format + * %p - pointer format + * + * The following padding specifiers are supported by this print + * %0NN - Left-pad the number with 0s (NN is a decimal number) + * %NN - Left-pad the number or string with spaces (NN is a decimal number) + * %-NN - Right-pad the number or string with spaces (NN is a decimal number) + * + * The function panics on all other formats specifiers. + * + * It returns the number of characters that would be written if the + * buffer was big enough. If it returns a value lower than n, the + * whole string has been written. + *******************************************************************/ +int snprintf(char *s, size_t n, const char *fmt, ...) +{ + int count; + va_list all_args; + + va_start(all_args, fmt); + count = vsnprintf(s, n, fmt, all_args); + va_end(all_args); + + return count; +} -- cgit v1.2.3 From 093ba62e14099ab4bd9c2452044d19e3589925d6 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Fri, 21 Aug 2020 10:47:17 +0800 Subject: doc: Correct CPACR.FPEN usage To avoid trapping from EL0/1, FPEN bits need to be set 0x3, not clearing. Signed-off-by: Peng Fan Change-Id: Ic34e9aeb876872883c5f040618ed6d50f21dacd0 --- docs/design/firmware-design.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst index a357d5858..c12e73f45 100644 --- a/docs/design/firmware-design.rst +++ b/docs/design/firmware-design.rst @@ -369,7 +369,7 @@ Architectural initialization For AArch64, BL2 performs the minimal architectural initialization required for subsequent stages of TF-A and normal world software. EL1 and EL0 are given -access to Floating Point and Advanced SIMD registers by clearing the +access to Floating Point and Advanced SIMD registers by setting the ``CPACR.FPEN`` bits. For AArch32, the minimal architectural initialization required for subsequent -- cgit v1.2.3 From cb5c08b6980bddc9dbe4c825da3914e4ae38a113 Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Thu, 30 Apr 2020 12:40:22 +0100 Subject: Fix fiptool packaging issue on windows Windows does not have a standard getopt implementation. To address this an equivalent implementation has been provided in win_posix.c However, the implementation has an issue with option processing as described below. Long option names may be abbreviated if the abbreviation is unique or an exact match for some defined option. Since some options can be substring of other options e.g. "scp-fw" option is a substring of "scp-fwu-cfg", we need to identify if an option is abbreviated and also check for uniqueness. Otherwise if a user passes --scp-fw as an option, the "scp-fwu-cfg" option may get selected, resulting in an incorrectly packaged FIP. This issue has been be fixed by: - First searching for an exact match. - If exact match was not found search for a abbreviated match. By doing this an incorrect option selection can be avoided. Change-Id: I22f4e7a683f3df857f5b6f0783bf9b03a64a0bcc Signed-off-by: Sami Mujawar --- tools/fiptool/win_posix.c | 91 +++++++++++++++++++++++++++++++---------------- tools/fiptool/win_posix.h | 8 +++-- 2 files changed, 66 insertions(+), 33 deletions(-) diff --git a/tools/fiptool/win_posix.c b/tools/fiptool/win_posix.c index 48feb162e..33b44d4c6 100644 --- a/tools/fiptool/win_posix.c +++ b/tools/fiptool/win_posix.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017 - 2020, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -137,7 +137,8 @@ int getopt(int argc, * Note that we only match over the shorter length of the pair, to allow * for abbreviation or say --match=value * Long option names may be abbreviated if the abbreviation is unique or an - * exact match for some defined option. + * exact match for some defined option. This function does not check that the + * abbreviations are unique and should be handled by the caller. * A long option may take a parameter, of the form --opt=param or --opt param. */ static @@ -160,42 +161,72 @@ int getopt_1long(const int argc, { int result = RET_UNKNOWN_OPT; size_t loptn = 0; + bool match_found = false; - while (longopts[loptn].name != 0) { - if (optmatch(optname, longopts[loptn].name) == 0) { - /* We found a match. */ - result = longopts[loptn].val; - if (indexptr != 0) - *indexptr = loptn; - switch (longopts[loptn].has_arg) { - case required_argument: - if ((optind + 1) >= argc) { - /* Missing argument. */ - optopt = result; - return RET_NO_PARAM; - } - /* Fallthrough to get option value. */ + /* + * Long option names may be abbreviated if the abbreviation + * is unique or an exact match for some defined option. + * To handle this: + * - First search for an exact match. + * - If exact match was not found search for a abbreviated match. + * By doing this an incorrect option selection can be avoided. + */ - case optional_argument: - if ((argc - optind) > 0) { - /* Found argument. */ - optarg = argv[++optind]; - } - /* Fallthrough to handle flag. */ + /* 1. Search for an exact match. */ + while (longopts[loptn].name != NULL) { + if (strcmp(optname, longopts[loptn].name) == 0) { + match_found = true; + break; + } + ++loptn; + } - case no_argument: - optind++; - if (longopts[loptn].flag != 0) { - *longopts[loptn].flag = result; - result = 0; - } + /* 2. If exact match was not found search for a abbreviated match. */ + if (!match_found) { + loptn = 0; + while (longopts[loptn].name != NULL) { + if (optmatch(optname, longopts[loptn].name) == 0) { + match_found = true; break; + } + ++loptn; + } + } + + if (match_found) { + /* We found a match. */ + result = longopts[loptn].val; + if (indexptr != 0) { + *indexptr = loptn; + } + switch (longopts[loptn].has_arg) { + case required_argument: + if ((optind + 1) >= argc) { + /* Missing argument. */ + optopt = result; + return RET_NO_PARAM; + } + /* Fallthrough to get option value. */ + case optional_argument: + if ((argc - optind) > 0) { + /* Found argument. */ + optarg = argv[++optind]; } - return result; + /* Fallthrough to handle flag. */ + + case no_argument: + optind++; + if (longopts[loptn].flag != 0) { + *longopts[loptn].flag = result; + result = 0; + } + break; + } - ++loptn; + return result; } + /* * If getopt finds an option character in argv that was not included * in options, ... it returns '?' and sets the external variable diff --git a/tools/fiptool/win_posix.h b/tools/fiptool/win_posix.h index 836ffed31..6f0d8e6b6 100644 --- a/tools/fiptool/win_posix.h +++ b/tools/fiptool/win_posix.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,13 +9,15 @@ #define _CRT_SECURE_NO_WARNINGS -#include -#include +#include #include #include #include #include +#include +#include + #include "uuid.h" /* Derive or provide Windows equivalents of Posix/GCC/Unix stuff. */ -- cgit v1.2.3 From 88a1cf1e4e8032580058745ba221abc5d8b90ef3 Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Thu, 30 Apr 2020 12:41:57 +0100 Subject: Update makefile to build fiptool for Windows Although support for building fiptool on a Windows host was present, the binary was not built when the top level makefile was invoked. This patch makes the necessary changes to the to support building of fiptool on a Windows host PC from the main makefile. Change-Id: I0c01ba237fa3010a027a1b324201131210cf4d7c Signed-off-by: Sami Mujawar --- Makefile | 21 ++++++++++++++ make_helpers/windows.mk | 4 ++- tools/fiptool/Makefile.msvc | 67 +++++++++++++++++++++++++-------------------- 3 files changed, 61 insertions(+), 31 deletions(-) diff --git a/Makefile b/Makefile index af829f2bd..6797c4d20 100644 --- a/Makefile +++ b/Makefile @@ -1157,7 +1157,13 @@ endif clean: @echo " CLEAN" $(call SHELL_REMOVE_DIR,${BUILD_PLAT}) +ifdef UNIX_MK ${Q}${MAKE} --no-print-directory -C ${FIPTOOLPATH} clean +else +# Clear the MAKEFLAGS as we do not want +# to pass the gnumake flags to nmake. + ${Q}set MAKEFLAGS= && ${MSVC_NMAKE} /nologo /f ${FIPTOOLPATH}/Makefile.msvc FIPTOOLPATH=$(subst /,\,$(FIPTOOLPATH)) FIPTOOL=$(subst /,\,$(FIPTOOL)) clean +endif ${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH} clean ${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${ENCTOOLPATH} clean ${Q}${MAKE} --no-print-directory -C ${ROMLIBPATH} clean @@ -1166,7 +1172,13 @@ realclean distclean: @echo " REALCLEAN" $(call SHELL_REMOVE_DIR,${BUILD_BASE}) $(call SHELL_DELETE_ALL, ${CURDIR}/cscope.*) +ifdef UNIX_MK ${Q}${MAKE} --no-print-directory -C ${FIPTOOLPATH} clean +else +# Clear the MAKEFLAGS as we do not want +# to pass the gnumake flags to nmake. + ${Q}set MAKEFLAGS= && ${MSVC_NMAKE} /nologo /f ${FIPTOOLPATH}/Makefile.msvc FIPTOOLPATH=$(subst /,\,$(FIPTOOLPATH)) FIPTOOL=$(subst /,\,$(FIPTOOL)) realclean +endif ${Q}${MAKE} --no-print-directory -C ${SPTOOLPATH} clean ${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH} clean ${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${ENCTOOLPATH} realclean @@ -1252,7 +1264,16 @@ fwu_fip: ${BUILD_PLAT}/${FWU_FIP_NAME} .PHONY: ${FIPTOOL} ${FIPTOOL}: + @${ECHO_BLANK_LINE} + @echo "Building $@" +ifdef UNIX_MK ${Q}${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" FIPTOOL=${FIPTOOL} --no-print-directory -C ${FIPTOOLPATH} +else +# Clear the MAKEFLAGS as we do not want +# to pass the gnumake flags to nmake. + ${Q}set MAKEFLAGS= && ${MSVC_NMAKE} /nologo /f ${FIPTOOLPATH}/Makefile.msvc FIPTOOLPATH=$(subst /,\,$(FIPTOOLPATH)) FIPTOOL=$(subst /,\,$(FIPTOOL)) +endif + @${ECHO_BLANK_LINE} sptool: ${SPTOOL} .PHONY: ${SPTOOL} diff --git a/make_helpers/windows.mk b/make_helpers/windows.mk index 5ab8bdc4f..26ea88ef0 100644 --- a/make_helpers/windows.mk +++ b/make_helpers/windows.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -86,3 +86,5 @@ define MAKE_BUILD_STRINGS $$(CC) $$(TF_CFLAGS) $$(CFLAGS) -x c -c - -o $1 endef +MSVC_NMAKE := nmake.exe + diff --git a/tools/fiptool/Makefile.msvc b/tools/fiptool/Makefile.msvc index 58dbb8973..9081bc64c 100644 --- a/tools/fiptool/Makefile.msvc +++ b/tools/fiptool/Makefile.msvc @@ -1,30 +1,37 @@ -# -# Copyright (c) 2019, Arm Limited. All rights reserved. -# -# SPDX-License-Identifier: BSD-3-Clause -# - -CC = cl.exe -LD = link.exe - -FIPTOOL = fiptool.exe -OBJECTS = fiptool.obj tbbr_config.obj win_posix.obj - -INC = -I. -I..\..\include\tools_share -CFLAGS = $(CFLAGS) /nologo /Za /Zi /c /O2 /MT - -all: $(FIPTOOL) - -$(FIPTOOL): $(OBJECTS) - $(LD) /INCREMENTAL:NO /debug /nodefaultlib:libc.lib /out:$@ $(LIBS) $** - -.PHONY: clean realclean - -clean: - del /f /q $(OBJECTS) > nul - -realclean: - del /f /q $(OBJECTS) $(FIPTOOL) > nul - -.c.obj: - $(CC) -c $(CFLAGS) $(INC) $< -Fo$@ +# +# Copyright (c) 2019-2020, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +CC = cl.exe +LD = link.exe + +# FIPTOOLPATH and FIPTOOL are passed from the main makefile. + +OBJECTS = $(FIPTOOLPATH)\fiptool.obj \ + $(FIPTOOLPATH)\tbbr_config.obj \ + $(FIPTOOLPATH)\win_posix.obj + +INC = -I$(FIPTOOLPATH) -Iinclude\tools_share + +CFLAGS = $(CFLAGS) /nologo /Za /Zi /c /O2 /MT + +all: $(FIPTOOL) + +$(FIPTOOL): $(OBJECTS) + $(LD) /nologo /INCREMENTAL:NO /debug /nodefaultlib:libc.lib /out:$@ $(LIBS) $** + +.PHONY: clean realclean + +clean: + -@del /f /q $(OBJECTS) > nul + -@del /f /q $(FIPTOOLPATH)\*.pdb > nul + +realclean: + -@del /f /q $(OBJECTS) > nul + -@del /f /q $(FIPTOOLPATH)\*.pdb > nul + -@del /f /q $(FIPTOOL) > nul + +.c.obj: + $(CC) -c $(CFLAGS) $(INC) $< -Fo$@ -- cgit v1.2.3 From 327131c4c7e41d57aca9f54fd2706ae59d735aaa Mon Sep 17 00:00:00 2001 From: Leonardo Sandoval Date: Thu, 10 Sep 2020 12:18:27 -0500 Subject: build_macros.mk: include assert and define loop macros Loop macros make it easier for developers to include new variables to assert or define and also help code code readability on makefiles. Change-Id: I0d21d6e67b3eca8976c4d856ac8ccc02c8bb5ffa Signed-off-by: Leonardo Sandoval --- Makefile | 263 +++++++++++++++++---------------- bl31/bl31.mk | 20 ++- drivers/auth/mbedtls/mbedtls_common.mk | 11 +- drivers/measured_boot/measured_boot.mk | 11 +- make_helpers/armv7-a-cpus.mk | 11 +- make_helpers/build_macros.mk | 19 +++ plat/st/stm32mp1/platform.mk | 27 ++-- 7 files changed, 206 insertions(+), 156 deletions(-) diff --git a/Makefile b/Makefile index af829f2bd..7ebccf9a8 100644 --- a/Makefile +++ b/Makefile @@ -855,71 +855,77 @@ endif # Build options checks ################################################################################ -$(eval $(call assert_boolean,ALLOW_RO_XLAT_TABLES)) -$(eval $(call assert_boolean,COLD_BOOT_SINGLE_CPU)) -$(eval $(call assert_boolean,CREATE_KEYS)) -$(eval $(call assert_boolean,CTX_INCLUDE_AARCH32_REGS)) -$(eval $(call assert_boolean,CTX_INCLUDE_FPREGS)) -$(eval $(call assert_boolean,CTX_INCLUDE_PAUTH_REGS)) -$(eval $(call assert_boolean,CTX_INCLUDE_MTE_REGS)) -$(eval $(call assert_boolean,CTX_INCLUDE_EL2_REGS)) -$(eval $(call assert_boolean,DEBUG)) -$(eval $(call assert_boolean,DYN_DISABLE_AUTH)) -$(eval $(call assert_boolean,EL3_EXCEPTION_HANDLING)) -$(eval $(call assert_boolean,ENABLE_AMU)) -$(eval $(call assert_boolean,ENABLE_ASSERTIONS)) -$(eval $(call assert_boolean,ENABLE_MPAM_FOR_LOWER_ELS)) -$(eval $(call assert_boolean,ENABLE_PIE)) -$(eval $(call assert_boolean,ENABLE_PMF)) -$(eval $(call assert_boolean,ENABLE_PSCI_STAT)) -$(eval $(call assert_boolean,ENABLE_RUNTIME_INSTRUMENTATION)) -$(eval $(call assert_boolean,ENABLE_SPE_FOR_LOWER_ELS)) -$(eval $(call assert_boolean,ENABLE_SVE_FOR_NS)) -$(eval $(call assert_boolean,ERROR_DEPRECATED)) -$(eval $(call assert_boolean,FAULT_INJECTION_SUPPORT)) -$(eval $(call assert_boolean,GENERATE_COT)) -$(eval $(call assert_boolean,GICV2_G0_FOR_EL3)) -$(eval $(call assert_boolean,HANDLE_EA_EL3_FIRST)) -$(eval $(call assert_boolean,HW_ASSISTED_COHERENCY)) -$(eval $(call assert_boolean,INVERTED_MEMMAP)) -$(eval $(call assert_boolean,MEASURED_BOOT)) -$(eval $(call assert_boolean,NS_TIMER_SWITCH)) -$(eval $(call assert_boolean,OVERRIDE_LIBC)) -$(eval $(call assert_boolean,PL011_GENERIC_UART)) -$(eval $(call assert_boolean,PROGRAMMABLE_RESET_ADDRESS)) -$(eval $(call assert_boolean,PSCI_EXTENDED_STATE_ID)) -$(eval $(call assert_boolean,RAS_EXTENSION)) -$(eval $(call assert_boolean,RESET_TO_BL31)) -$(eval $(call assert_boolean,SAVE_KEYS)) -$(eval $(call assert_boolean,SEPARATE_CODE_AND_RODATA)) -$(eval $(call assert_boolean,SEPARATE_NOBITS_REGION)) -$(eval $(call assert_boolean,SPIN_ON_BL1_EXIT)) -$(eval $(call assert_boolean,SPM_MM)) -$(eval $(call assert_boolean,SPMD_SPM_AT_SEL2)) -$(eval $(call assert_boolean,TRUSTED_BOARD_BOOT)) -$(eval $(call assert_boolean,USE_COHERENT_MEM)) -$(eval $(call assert_boolean,USE_DEBUGFS)) -$(eval $(call assert_boolean,ARM_IO_IN_DTB)) -$(eval $(call assert_boolean,SDEI_IN_FCONF)) -$(eval $(call assert_boolean,SEC_INT_DESC_IN_FCONF)) -$(eval $(call assert_boolean,USE_ROMLIB)) -$(eval $(call assert_boolean,USE_TBBR_DEFS)) -$(eval $(call assert_boolean,WARMBOOT_ENABLE_DCACHE_EARLY)) -$(eval $(call assert_boolean,BL2_AT_EL3)) -$(eval $(call assert_boolean,BL2_IN_XIP_MEM)) -$(eval $(call assert_boolean,BL2_INV_DCACHE)) -$(eval $(call assert_boolean,USE_SPINLOCK_CAS)) -$(eval $(call assert_boolean,ENCRYPT_BL31)) -$(eval $(call assert_boolean,ENCRYPT_BL32)) -$(eval $(call assert_boolean,ERRATA_SPECULATIVE_AT)) -$(eval $(call assert_boolean,RAS_TRAP_LOWER_EL_ERR_ACCESS)) -$(eval $(call assert_boolean,COT_DESC_IN_DTB)) -$(eval $(call assert_boolean,USE_SP804_TIMER)) - -$(eval $(call assert_numeric,ARM_ARCH_MAJOR)) -$(eval $(call assert_numeric,ARM_ARCH_MINOR)) -$(eval $(call assert_numeric,BRANCH_PROTECTION)) -$(eval $(call assert_numeric,FW_ENC_STATUS)) +$(eval $(call assert_booleans,\ + $(sort \ + ALLOW_RO_XLAT_TABLES \ + COLD_BOOT_SINGLE_CPU \ + CREATE_KEYS \ + CTX_INCLUDE_AARCH32_REGS \ + CTX_INCLUDE_FPREGS \ + CTX_INCLUDE_PAUTH_REGS \ + CTX_INCLUDE_MTE_REGS \ + CTX_INCLUDE_EL2_REGS \ + DEBUG \ + DYN_DISABLE_AUTH \ + EL3_EXCEPTION_HANDLING \ + ENABLE_AMU \ + ENABLE_ASSERTIONS \ + ENABLE_MPAM_FOR_LOWER_ELS \ + ENABLE_PIE \ + ENABLE_PMF \ + ENABLE_PSCI_STAT \ + ENABLE_RUNTIME_INSTRUMENTATION \ + ENABLE_SPE_FOR_LOWER_ELS \ + ENABLE_SVE_FOR_NS \ + ERROR_DEPRECATED \ + FAULT_INJECTION_SUPPORT \ + GENERATE_COT \ + GICV2_G0_FOR_EL3 \ + HANDLE_EA_EL3_FIRST \ + HW_ASSISTED_COHERENCY \ + INVERTED_MEMMAP \ + MEASURED_BOOT \ + NS_TIMER_SWITCH \ + OVERRIDE_LIBC \ + PL011_GENERIC_UART \ + PROGRAMMABLE_RESET_ADDRESS \ + PSCI_EXTENDED_STATE_ID \ + RAS_EXTENSION \ + RESET_TO_BL31 \ + SAVE_KEYS \ + SEPARATE_CODE_AND_RODATA \ + SEPARATE_NOBITS_REGION \ + SPIN_ON_BL1_EXIT \ + SPM_MM \ + SPMD_SPM_AT_SEL2 \ + TRUSTED_BOARD_BOOT \ + USE_COHERENT_MEM \ + USE_DEBUGFS \ + ARM_IO_IN_DTB \ + SDEI_IN_FCONF \ + SEC_INT_DESC_IN_FCONF \ + USE_ROMLIB \ + USE_TBBR_DEFS \ + WARMBOOT_ENABLE_DCACHE_EARLY \ + BL2_AT_EL3 \ + BL2_IN_XIP_MEM \ + BL2_INV_DCACHE \ + USE_SPINLOCK_CAS \ + ENCRYPT_BL31 \ + ENCRYPT_BL32 \ + ERRATA_SPECULATIVE_AT \ + RAS_TRAP_LOWER_EL_ERR_ACCESS \ + COT_DESC_IN_DTB \ + USE_SP804_TIMER \ +))) + +$(eval $(call assert_numerics,\ + $(sort \ + ARM_ARCH_MAJOR \ + ARM_ARCH_MINOR \ + BRANCH_PROTECTION \ + FW_ENC_STATUS \ +))) ifdef KEY_SIZE $(eval $(call assert_numeric,KEY_SIZE)) @@ -935,68 +941,71 @@ endif # platform to overwrite the default options ################################################################################ -$(eval $(call add_define,ALLOW_RO_XLAT_TABLES)) -$(eval $(call add_define,ARM_ARCH_MAJOR)) -$(eval $(call add_define,ARM_ARCH_MINOR)) -$(eval $(call add_define,COLD_BOOT_SINGLE_CPU)) -$(eval $(call add_define,CTX_INCLUDE_AARCH32_REGS)) -$(eval $(call add_define,CTX_INCLUDE_FPREGS)) -$(eval $(call add_define,CTX_INCLUDE_PAUTH_REGS)) -$(eval $(call add_define,EL3_EXCEPTION_HANDLING)) -$(eval $(call add_define,CTX_INCLUDE_MTE_REGS)) -$(eval $(call add_define,CTX_INCLUDE_EL2_REGS)) -$(eval $(call add_define,DECRYPTION_SUPPORT_${DECRYPTION_SUPPORT})) -$(eval $(call add_define,ENABLE_AMU)) -$(eval $(call add_define,ENABLE_ASSERTIONS)) -$(eval $(call add_define,ENABLE_BTI)) -$(eval $(call add_define,ENABLE_MPAM_FOR_LOWER_ELS)) -$(eval $(call add_define,ENABLE_PAUTH)) -$(eval $(call add_define,ENABLE_PIE)) -$(eval $(call add_define,ENABLE_PMF)) -$(eval $(call add_define,ENABLE_PSCI_STAT)) -$(eval $(call add_define,ENABLE_RUNTIME_INSTRUMENTATION)) -$(eval $(call add_define,ENABLE_SPE_FOR_LOWER_ELS)) -$(eval $(call add_define,ENABLE_SVE_FOR_NS)) -$(eval $(call add_define,ENCRYPT_BL31)) -$(eval $(call add_define,ENCRYPT_BL32)) -$(eval $(call add_define,ERROR_DEPRECATED)) -$(eval $(call add_define,FAULT_INJECTION_SUPPORT)) -$(eval $(call add_define,GICV2_G0_FOR_EL3)) -$(eval $(call add_define,HANDLE_EA_EL3_FIRST)) -$(eval $(call add_define,HW_ASSISTED_COHERENCY)) -$(eval $(call add_define,LOG_LEVEL)) -$(eval $(call add_define,MEASURED_BOOT)) -$(eval $(call add_define,NS_TIMER_SWITCH)) -$(eval $(call add_define,PL011_GENERIC_UART)) -$(eval $(call add_define,PLAT_${PLAT})) -$(eval $(call add_define,PROGRAMMABLE_RESET_ADDRESS)) -$(eval $(call add_define,PSCI_EXTENDED_STATE_ID)) -$(eval $(call add_define,RAS_EXTENSION)) -$(eval $(call add_define,RESET_TO_BL31)) -$(eval $(call add_define,SEPARATE_CODE_AND_RODATA)) -$(eval $(call add_define,SEPARATE_NOBITS_REGION)) -$(eval $(call add_define,RECLAIM_INIT_CODE)) -$(eval $(call add_define,SPD_${SPD})) -$(eval $(call add_define,SPIN_ON_BL1_EXIT)) -$(eval $(call add_define,SPM_MM)) -$(eval $(call add_define,SPMD_SPM_AT_SEL2)) -$(eval $(call add_define,TRUSTED_BOARD_BOOT)) -$(eval $(call add_define,USE_COHERENT_MEM)) -$(eval $(call add_define,USE_DEBUGFS)) -$(eval $(call add_define,ARM_IO_IN_DTB)) -$(eval $(call add_define,SDEI_IN_FCONF)) -$(eval $(call add_define,SEC_INT_DESC_IN_FCONF)) -$(eval $(call add_define,USE_ROMLIB)) -$(eval $(call add_define,USE_TBBR_DEFS)) -$(eval $(call add_define,WARMBOOT_ENABLE_DCACHE_EARLY)) -$(eval $(call add_define,BL2_AT_EL3)) -$(eval $(call add_define,BL2_IN_XIP_MEM)) -$(eval $(call add_define,BL2_INV_DCACHE)) -$(eval $(call add_define,USE_SPINLOCK_CAS)) -$(eval $(call add_define,ERRATA_SPECULATIVE_AT)) -$(eval $(call add_define,RAS_TRAP_LOWER_EL_ERR_ACCESS)) -$(eval $(call add_define,COT_DESC_IN_DTB)) -$(eval $(call add_define,USE_SP804_TIMER)) +$(eval $(call add_defines,\ + $(sort \ + ALLOW_RO_XLAT_TABLES \ + ARM_ARCH_MAJOR \ + ARM_ARCH_MINOR \ + COLD_BOOT_SINGLE_CPU \ + CTX_INCLUDE_AARCH32_REGS \ + CTX_INCLUDE_FPREGS \ + CTX_INCLUDE_PAUTH_REGS \ + EL3_EXCEPTION_HANDLING \ + CTX_INCLUDE_MTE_REGS \ + CTX_INCLUDE_EL2_REGS \ + DECRYPTION_SUPPORT_${DECRYPTION_SUPPORT} \ + ENABLE_AMU \ + ENABLE_ASSERTIONS \ + ENABLE_BTI \ + ENABLE_MPAM_FOR_LOWER_ELS \ + ENABLE_PAUTH \ + ENABLE_PIE \ + ENABLE_PMF \ + ENABLE_PSCI_STAT \ + ENABLE_RUNTIME_INSTRUMENTATION \ + ENABLE_SPE_FOR_LOWER_ELS \ + ENABLE_SVE_FOR_NS \ + ENCRYPT_BL31 \ + ENCRYPT_BL32 \ + ERROR_DEPRECATED \ + FAULT_INJECTION_SUPPORT \ + GICV2_G0_FOR_EL3 \ + HANDLE_EA_EL3_FIRST \ + HW_ASSISTED_COHERENCY \ + LOG_LEVEL \ + MEASURED_BOOT \ + NS_TIMER_SWITCH \ + PL011_GENERIC_UART \ + PLAT_${PLAT} \ + PROGRAMMABLE_RESET_ADDRESS \ + PSCI_EXTENDED_STATE_ID \ + RAS_EXTENSION \ + RESET_TO_BL31 \ + SEPARATE_CODE_AND_RODATA \ + SEPARATE_NOBITS_REGION \ + RECLAIM_INIT_CODE \ + SPD_${SPD} \ + SPIN_ON_BL1_EXIT \ + SPM_MM \ + SPMD_SPM_AT_SEL2 \ + TRUSTED_BOARD_BOOT \ + USE_COHERENT_MEM \ + USE_DEBUGFS \ + ARM_IO_IN_DTB \ + SDEI_IN_FCONF \ + SEC_INT_DESC_IN_FCONF \ + USE_ROMLIB \ + USE_TBBR_DEFS \ + WARMBOOT_ENABLE_DCACHE_EARLY \ + BL2_AT_EL3 \ + BL2_IN_XIP_MEM \ + BL2_INV_DCACHE \ + USE_SPINLOCK_CAS \ + ERRATA_SPECULATIVE_AT \ + RAS_TRAP_LOWER_EL_ERR_ACCESS \ + COT_DESC_IN_DTB \ + USE_SP804_TIMER \ +))) ifeq (${SANITIZE_UB},trap) $(eval $(call add_define,MONITOR_TRAPS)) diff --git a/bl31/bl31.mk b/bl31/bl31.mk index 0948e94e0..735d1fcfc 100644 --- a/bl31/bl31.mk +++ b/bl31/bl31.mk @@ -89,10 +89,16 @@ ifndef CRASH_REPORTING CRASH_REPORTING := $(DEBUG) endif -$(eval $(call assert_boolean,CRASH_REPORTING)) -$(eval $(call assert_boolean,EL3_EXCEPTION_HANDLING)) -$(eval $(call assert_boolean,SDEI_SUPPORT)) - -$(eval $(call add_define,CRASH_REPORTING)) -$(eval $(call add_define,EL3_EXCEPTION_HANDLING)) -$(eval $(call add_define,SDEI_SUPPORT)) +$(eval $(call assert_booleans,\ + $(sort \ + CRASH_REPORTING \ + EL3_EXCEPTION_HANDLING \ + SDEI_SUPPORT \ +))) + +$(eval $(call add_defines,\ + $(sort \ + CRASH_REPORTING \ + EL3_EXCEPTION_HANDLING \ + SDEI_SUPPORT \ +))) diff --git a/drivers/auth/mbedtls/mbedtls_common.mk b/drivers/auth/mbedtls/mbedtls_common.mk index 94f2f59e1..8454105c2 100644 --- a/drivers/auth/mbedtls/mbedtls_common.mk +++ b/drivers/auth/mbedtls/mbedtls_common.mk @@ -98,10 +98,13 @@ else endif # Needs to be set to drive mbed TLS configuration correctly -$(eval $(call add_define,TF_MBEDTLS_KEY_ALG_ID)) -$(eval $(call add_define,TF_MBEDTLS_KEY_SIZE)) -$(eval $(call add_define,TF_MBEDTLS_HASH_ALG_ID)) -$(eval $(call add_define,TF_MBEDTLS_USE_AES_GCM)) +$(eval $(call add_defines,\ + $(sort \ + TF_MBEDTLS_KEY_ALG_ID \ + TF_MBEDTLS_KEY_SIZE \ + TF_MBEDTLS_HASH_ALG_ID \ + TF_MBEDTLS_USE_AES_GCM \ +))) $(eval $(call MAKE_LIB,mbedtls)) diff --git a/drivers/measured_boot/measured_boot.mk b/drivers/measured_boot/measured_boot.mk index fc005d5ed..b7aa48bb9 100644 --- a/drivers/measured_boot/measured_boot.mk +++ b/drivers/measured_boot/measured_boot.mk @@ -25,10 +25,13 @@ endif EVENT_LOG_SIZE := 1024 # Set definitions for mbed TLS library and Measured Boot driver -$(eval $(call add_define,MBEDTLS_MD_ID)) -$(eval $(call add_define,TPM_ALG_ID)) -$(eval $(call add_define,TCG_DIGEST_SIZE)) -$(eval $(call add_define,EVENT_LOG_SIZE)) +$(eval $(call add_defines,\ + $(sort \ + MBEDTLS_MD_ID \ + TPM_ALG_ID \ + TCG_DIGEST_SIZE \ + EVENT_LOG_SIZE \ +))) ifeq (${HASH_ALG}, sha256) ifneq (${TPM_HASH_ALG}, sha256) diff --git a/make_helpers/armv7-a-cpus.mk b/make_helpers/armv7-a-cpus.mk index 5571ab0f7..eec85cc1e 100644 --- a/make_helpers/armv7-a-cpus.mk +++ b/make_helpers/armv7-a-cpus.mk @@ -44,10 +44,13 @@ endif # Defined if ARMv7 core supports the Generic Timer extension. ifeq ($(filter yes,$(ARM_CORTEX_A7) $(ARM_CORTEX_A12) $(ARM_CORTEX_A15) $(ARM_CORTEX_A17)),yes) -$(eval $(call add_define,ARMV7_SUPPORTS_LARGE_PAGE_ADDRESSING)) -$(eval $(call add_define,ARMV7_SUPPORTS_VIRTUALIZATION)) -$(eval $(call add_define,ARMV7_SUPPORTS_GENERIC_TIMER)) -$(eval $(call add_define,ARMV7_SUPPORTS_VFP)) +$(eval $(call add_defines,\ + $(sort \ + ARMV7_SUPPORTS_LARGE_PAGE_ADDRESSING \ + ARMV7_SUPPORTS_VIRTUALIZATION \ + ARMV7_SUPPORTS_GENERIC_TIMER \ + ARMV7_SUPPORTS_VFP \ +))) endif ifeq ($(ARM_CORTEX_A5),yes) diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk index 1c3d14d05..613fca23f 100644 --- a/make_helpers/build_macros.mk +++ b/make_helpers/build_macros.mk @@ -44,6 +44,13 @@ define add_define DEFINES += -D$(1)$(if $(value $(1)),=$(value $(1)),) endef + +# Convenience function for addding multiple build definitions +# $(eval $(call add_defines,FOO BOO)) +define add_defines + $(foreach def,$1,$(eval $(call add_define,$(def)))) +endef + # Convenience function for adding build definitions # $(eval $(call add_define_val,FOO,BAR)) will have: # -DFOO=BAR @@ -57,6 +64,12 @@ define assert_boolean $(if $(filter-out 0 1,$($1)),$(error $1 must be boolean)) endef +# Convenience function for verifying options have boolean values +# $(eval $(call assert_booleans,FOO BOO)) will assert FOO and BOO for 0 or 1 values +define assert_booleans + $(foreach bool,$1,$(eval $(call assert_boolean,$(bool)))) +endef + 0-9 := 0 1 2 3 4 5 6 7 8 9 # Function to verify that a given option $(1) contains a numeric value @@ -67,6 +80,12 @@ $(foreach d,$(0-9),$(eval __numeric := $(subst $(d),,$(__numeric)))) $(if $(__numeric),$(error $(1) must be numeric)) endef +# Convenience function for verifying options have numeric values +# $(eval $(call assert_numerics,FOO BOO)) will assert FOO and BOO contain numeric values +define assert_numerics + $(foreach num,$1,$(eval $(call assert_numeric,$(num)))) +endef + # CREATE_SEQ is a recursive function to create sequence of numbers from 1 to # $(2) and assign the sequence to $(1) define CREATE_SEQ diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk index 999823617..41eacc8fd 100644 --- a/plat/st/stm32mp1/platform.mk +++ b/plat/st/stm32mp1/platform.mk @@ -46,16 +46,23 @@ ifeq ($(filter 1,${STM32MP_EMMC} ${STM32MP_SDMMC} ${STM32MP_RAW_NAND} \ $(error "No boot device driver is enabled") endif -$(eval $(call assert_boolean,STM32MP_EMMC)) -$(eval $(call assert_boolean,STM32MP_SDMMC)) -$(eval $(call assert_boolean,STM32MP_RAW_NAND)) -$(eval $(call assert_boolean,STM32MP_SPI_NAND)) -$(eval $(call assert_boolean,STM32MP_SPI_NOR)) -$(eval $(call add_define,STM32MP_EMMC)) -$(eval $(call add_define,STM32MP_SDMMC)) -$(eval $(call add_define,STM32MP_RAW_NAND)) -$(eval $(call add_define,STM32MP_SPI_NAND)) -$(eval $(call add_define,STM32MP_SPI_NOR)) +$(eval $(call assert_booleans,\ + $(sort \ + STM32MP_EMMC \ + STM32MP_SDMMC \ + STM32MP_RAW_NAND \ + STM32MP_SPI_NAND \ + STM32MP_SPI_NOR \ +))) + +$(eval $(call add_defines,\ + $(sort \ + STM32MP_EMMC \ + STM32MP_SDMMC \ + STM32MP_RAW_NAND \ + STM32MP_SPI_NAND \ + STM32MP_SPI_NOR \ +))) PLAT_INCLUDES := -Iplat/st/common/include/ PLAT_INCLUDES += -Iplat/st/stm32mp1/include/ -- cgit v1.2.3 From b85359296c4ca6b8a931870a867d5cc658c778ff Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Fri, 11 Sep 2020 09:18:09 +0100 Subject: SPE: Fix feature detection Currently the feature test for the SPE extension requires the feature bits in the ID_AA64DFR0 register to read exactly 0b0001. However the architecture guarantees that any values greater than 0 indicate the presence of a feature, which is what we are after in our spe_supported() function. Change the comparison to include all values greater than 0. This fixes SPE support in non-secure world on implementations which include the Scalable Vector Extension (SVE), for instance on Zeus cores. Change-Id: If6cbd1b72d6abb8a303e2c0a7839d508f071cdbe Signed-off-by: Andre Przywara --- lib/extensions/spe/spe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/extensions/spe/spe.c b/lib/extensions/spe/spe.c index 78876c66b..f0d734223 100644 --- a/lib/extensions/spe/spe.c +++ b/lib/extensions/spe/spe.c @@ -25,7 +25,7 @@ bool spe_supported(void) uint64_t features; features = read_id_aa64dfr0_el1() >> ID_AA64DFR0_PMS_SHIFT; - return (features & ID_AA64DFR0_PMS_MASK) == 1U; + return (features & ID_AA64DFR0_PMS_MASK) > 0ULL; } void spe_enable(bool el2_unused) -- cgit v1.2.3 From 0901d3398d59d8aa9b7c3d0cdc2d0c833f4317cb Mon Sep 17 00:00:00 2001 From: Manish Pandey Date: Wed, 12 Aug 2020 17:06:25 +0100 Subject: doc: add description of "owner" field in SP layout file. Change-Id: Iedaa83ed546eb2476849a8d53f6e05b847a48b23 Signed-off-by: Manish Pandey --- docs/components/secure-partition-manager.rst | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/docs/components/secure-partition-manager.rst b/docs/components/secure-partition-manager.rst index c58cd0801..9a65e6400 100644 --- a/docs/components/secure-partition-manager.rst +++ b/docs/components/secure-partition-manager.rst @@ -283,18 +283,25 @@ A description file (json format) is passed to the build flow specifying paths to the SP binary image and associated DTS partition manifest file. The latter is going through the dtc compiler to generate the dtb fed into the SP package. +This file also specifies the owner of the SP, which is an optional field and +identifies the signing domain in case of dualroot CoT. +The possible owner of an SP could either be Silicon Provider or Platform, and +the corresponding "owner" field value could either be "SiP" or "Plat". +In absence of "owner" field, it defaults to "SiP". .. code:: shell { "tee1" : { "image": "tee1.bin", - "pm": "tee1.dts" + "pm": "tee1.dts", + "owner": "SiP" }, "tee2" : { "image": "tee2.bin", - "pm": "tee2.dts" + "pm": "tee2.dts", + "owner": "Plat" } } @@ -376,8 +383,9 @@ Refer to TBBR specification `[3]`_. The multiple-signing domain feature (in current state dual signing domain) allows the use of two root keys namely S-ROTPK and NS-ROTPK (see `[8]`_): -- SPMC(BL32), SPMC manifest, SPs may be signed by the SiP using the S-ROTPK. +- SPMC (BL32) and SPMC manifest are signed by the SiP using the S-ROTPK. - BL33 may be signed by the OEM using NS-ROTPK. +- An SP may be signed either by SiP (using S-ROTPK) or by OEM (using NS-ROTPK). Longer term multiple signing domain will allow additional signing keys, e.g. if SPs originate from different parties. -- cgit v1.2.3 From 28e9a55fc87a8e2c1152689f3edcde0e8e639747 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Thu, 23 Jul 2020 10:43:57 +0100 Subject: lib: fconf: Implement a parser to populate CoT Implemented a parser which populates the properties of the CoT descriptors as per the binding document [1]. 'COT_DESC_IN_DTB' build option is disabled by default and can be enabled in future for all Arm platforms by making necessary changes in the memory map. Currently, this parser is tested only for FVP platform. [1]: https://trustedfirmware-a.readthedocs.io/en/latest/components/cot-binding.html Change-Id: I2f911206087a1a2942aa728de151d2ac269d27cc Signed-off-by: Manish V Badarkhe --- include/drivers/auth/auth_mod.h | 14 +- include/tools_share/tbbr_oid.h | 2 + lib/fconf/fconf_cot_getter.c | 497 ++++++++++++++++++++++++++++++++++++++++ plat/arm/common/arm_common.mk | 11 +- 4 files changed, 520 insertions(+), 4 deletions(-) create mode 100644 lib/fconf/fconf_cot_getter.c diff --git a/include/drivers/auth/auth_mod.h b/include/drivers/auth/auth_mod.h index 3965b58e7..d1fd52c86 100644 --- a/include/drivers/auth/auth_mod.h +++ b/include/drivers/auth/auth_mod.h @@ -21,7 +21,18 @@ */ #define IMG_FLAG_AUTHENTICATED (1 << 0) - +#if COT_DESC_IN_DTB && !IMAGE_BL1 +/* + * Authentication image descriptor + */ +typedef struct auth_img_desc_s { + unsigned int img_id; + img_type_t img_type; + const struct auth_img_desc_s *parent; + auth_method_desc_t *img_auth_methods; + auth_param_desc_t *authenticated_data; +} auth_img_desc_t; +#else /* * Authentication image descriptor */ @@ -32,6 +43,7 @@ typedef struct auth_img_desc_s { const auth_method_desc_t *const img_auth_methods; const auth_param_desc_t *const authenticated_data; } auth_img_desc_t; +#endif /* COT_DESC_IN_DTB && !IMAGE_BL1 */ /* Public functions */ void auth_mod_init(void); diff --git a/include/tools_share/tbbr_oid.h b/include/tools_share/tbbr_oid.h index 37d87d307..c789f790f 100644 --- a/include/tools_share/tbbr_oid.h +++ b/include/tools_share/tbbr_oid.h @@ -7,6 +7,8 @@ #ifndef TBBR_OID_H #define TBBR_OID_H +#define MAX_OID_NAME_LEN 30 + /* * The following is a list of OID values defined and reserved by ARM, which * are used to define the extension fields of the certificate structure, as diff --git a/lib/fconf/fconf_cot_getter.c b/lib/fconf/fconf_cot_getter.c new file mode 100644 index 000000000..adfa5341c --- /dev/null +++ b/lib/fconf/fconf_cot_getter.c @@ -0,0 +1,497 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +/* static structures used during authentication process */ +static auth_param_type_desc_t sig = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_SIG, 0); +static auth_param_type_desc_t sig_alg = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_SIG_ALG, 0); +static auth_param_type_desc_t raw_data = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_RAW_DATA, 0); + +/* pointers to an array of CoT descriptors */ +static const auth_img_desc_t *cot_desc[MAX_NUMBER_IDS]; +/* array of CoT descriptors */ +static auth_img_desc_t auth_img_descs[MAX_NUMBER_IDS]; + +/* array of authentication methods structures */ +static auth_method_desc_t auth_methods[MAX_NUMBER_IDS * AUTH_METHOD_NUM]; +static OBJECT_POOL_ARRAY(auth_methods_pool, auth_methods); + +/* array of authentication params structures */ +static auth_param_desc_t auth_params[MAX_NUMBER_IDS * COT_MAX_VERIFIED_PARAMS]; +static OBJECT_POOL_ARRAY(auth_params_pool, auth_params); + +/* array of authentication param type structures */ +static auth_param_type_desc_t auth_param_type_descs[MAX_NUMBER_IDS]; +static OBJECT_POOL_ARRAY(auth_param_type_descs_pool, auth_param_type_descs); + +/* + * array of OIDs + * Object IDs are used to search hash, pk, counter values in certificate. + * As per binding we have below 2 combinations: + * 1. Certificates are validated using nv-cntr and pk + * 2. Raw images are authenticated using hash + * Hence in worst case, there are maximum 2 OIDs per image/certificate + */ +static unsigned char oids[(MAX_NUMBER_IDS * 2)][MAX_OID_NAME_LEN]; +static OBJECT_POOL_ARRAY(oid_pool, oids); + +/* An array of auth buffer which holds hashes and pk + * ToDo: Size decided with the current number of images and + * certificates which are available in CoT. Size of these buffers bound to + * increase in the future on the addition of images/certificates. + */ +static unsigned char hash_auth_bufs[20][HASH_DER_LEN]; +static OBJECT_POOL_ARRAY(hash_auth_buf_pool, hash_auth_bufs); +static unsigned char pk_auth_bufs[12][PK_DER_LEN]; +static OBJECT_POOL_ARRAY(pk_auth_buf_pool, pk_auth_bufs); + +/******************************************************************************* + * update_parent_auth_data() - Update authentication data structure + * @auth_desc[in]: Pointer to the auth image descriptor + * @type_desc[in]: Pointer to authentication parameter + * @auth_buf_size[in]: Buffer size to hold pk or hash + * + * Return 0 on success or an error value otherwise. + ******************************************************************************/ +static int update_parent_auth_data(const auth_img_desc_t *auth_desc, + auth_param_type_desc_t *type_desc, + unsigned int auth_buf_size) +{ + unsigned int i; + auth_param_desc_t *auth_data = &auth_desc->authenticated_data[0]; + unsigned char *auth_buf; + + for (i = 0U; i < COT_MAX_VERIFIED_PARAMS; i++) { + if (auth_data[i].type_desc == type_desc) { + return 0; + } + if (auth_data[i].type_desc == NULL) { + break; + } + } + + if (auth_buf_size == HASH_DER_LEN) { + auth_buf = pool_alloc(&hash_auth_buf_pool); + } else if (auth_buf_size == PK_DER_LEN) { + auth_buf = pool_alloc(&pk_auth_buf_pool); + } else { + return -1; + } + + if (i < COT_MAX_VERIFIED_PARAMS) { + auth_data[i].type_desc = type_desc; + auth_data[i].data.ptr = auth_buf; + auth_data[i].data.len = auth_buf_size; + } else { + ERROR("Out of authentication data array\n"); + return -1; + } + + return 0; +} + +/******************************************************************************* + * get_auth_param_type_desc() - Get pointer of authentication parameter + * @img_id[in]: Image Id + * @type_desc[out]: Pointer to authentication parameter + * @buf_size[out]: Buffer size which hold hash/pk + * + * Return 0 on success or an error value otherwise. + ******************************************************************************/ +static int get_auth_param_type_desc(unsigned int img_id, + auth_param_type_desc_t **type_desc, + unsigned int *buf_size) +{ + auth_method_desc_t *img_auth_method = NULL; + img_type_t type = auth_img_descs[img_id].img_type; + + if (type == IMG_CERT) { + img_auth_method = + &auth_img_descs[img_id].img_auth_methods[AUTH_METHOD_SIG]; + *type_desc = img_auth_method->param.sig.pk; + *buf_size = PK_DER_LEN; + } else if (type == IMG_RAW) { + img_auth_method = + &auth_img_descs[img_id].img_auth_methods[AUTH_METHOD_HASH]; + *type_desc = img_auth_method->param.hash.hash; + *buf_size = HASH_DER_LEN; + } else { + return -1; + } + + return 0; +} + +/******************************************************************************* + * set_auth_method() - Update global auth image descriptors with authentication + * method data + * @auth_method_type[in]: Type of authentication method + * @oid[in]: Object Idetifier for pk/hash search + * @auth_method[in]: Pointer to authentication method to set + ******************************************************************************/ +static void set_auth_method(auth_method_type_t auth_method_type, char *oid, + auth_method_desc_t *auth_method) +{ + auth_param_type_t auth_param_type = AUTH_PARAM_NONE; + auth_param_type_desc_t *auth_param_type_desc; + + assert(auth_method != NULL); + + auth_param_type_desc = pool_alloc(&auth_param_type_descs_pool); + auth_method->type = auth_method_type; + + if (auth_method_type == AUTH_METHOD_SIG) { + auth_param_type = AUTH_PARAM_PUB_KEY; + auth_method->param.sig.sig = &sig; + auth_method->param.sig.alg = &sig_alg; + auth_method->param.sig.data = &raw_data; + auth_method->param.sig.pk = auth_param_type_desc; + } else if (auth_method_type == AUTH_METHOD_HASH) { + auth_param_type = AUTH_PARAM_HASH; + auth_method->param.hash.data = &raw_data; + auth_method->param.hash.hash = auth_param_type_desc; + } else if (auth_method_type == AUTH_METHOD_NV_CTR) { + auth_param_type = AUTH_PARAM_NV_CTR; + auth_method->param.nv_ctr.cert_nv_ctr = auth_param_type_desc; + auth_method->param.nv_ctr.plat_nv_ctr = auth_param_type_desc; + } + + auth_param_type_desc->type = auth_param_type; + auth_param_type_desc->cookie = (void *)oid; +} + +/******************************************************************************* + * get_oid() - get object identifier from device tree + * @dtb[in]: Pointer to the device tree blob in memory + * @node[in]: Offset of the node + * @prop[in]: Property to read from the given node + * @oid[out]: Object Indentifier of key/hash/nv-counter in certificate + * + * Return 0 on success or an error value otherwise. + ******************************************************************************/ +static int get_oid(const void *dtb, int node, const char *prop, char **oid) +{ + uint32_t phandle; + int rc; + + rc = fdt_read_uint32(dtb, node, prop, &phandle); + if (rc < 0) { + return rc; + } + + node = fdt_node_offset_by_phandle(dtb, phandle); + if (node < 0) { + return node; + } + + *oid = pool_alloc(&oid_pool); + rc = fdtw_read_string(dtb, node, "oid", *oid, MAX_OID_NAME_LEN); + + return rc; +} + +/******************************************************************************* + * populate_and_set_auth_methods() - Populate auth method parameters from + * device tree and set authentication method + * structure. + * @dtb[in]: Pointer to the device tree blob in memory + * @node[in]: Offset of the node + * @img_id[in]: Image identifier + * @type[in]: Type of image + * @root_certificate[in]:Root certificate (authenticated by ROTPK) + * + * Return 0 on success or an error value otherwise. + ******************************************************************************/ +static int populate_and_set_auth_methods(const void *dtb, int node, + unsigned int img_id, img_type_t type, + bool root_certificate) +{ + auth_method_type_t auth_method_type = AUTH_METHOD_NONE; + int rc; + char *oid = NULL; + + auth_method_desc_t *auth_method = pool_alloc_n(&auth_methods_pool, + AUTH_METHOD_NUM); + + /* + * This is as per binding document where certificates are + * verified by signature and images are verified by hash. + */ + if (type == IMG_CERT) { + if (root_certificate) { + oid = NULL; + } else { + rc = get_oid(dtb, node, "signing-key", &oid); + if (rc < 0) { + ERROR("FCONF: Can't read %s property\n", + "signing-key"); + return rc; + } + } + auth_method_type = AUTH_METHOD_SIG; + } else if (type == IMG_RAW) { + rc = get_oid(dtb, node, "hash", &oid); + if (rc < 0) { + ERROR("FCONF: Can't read %s property\n", + "hash"); + return rc; + } + auth_method_type = AUTH_METHOD_HASH; + } else { + return -1; + } + + set_auth_method(auth_method_type, oid, + &auth_method[auth_method_type]); + + /* Retrieve the optional property */ + rc = get_oid(dtb, node, "antirollback-counter", &oid); + if (rc == 0) { + auth_method_type = AUTH_METHOD_NV_CTR; + set_auth_method(auth_method_type, oid, + &auth_method[auth_method_type]); + } + + auth_img_descs[img_id].img_auth_methods = &auth_method[0]; + + return 0; +} + +/******************************************************************************* + * get_parent_img_id() - Get parent image id for given child node + * @dtb[in]: Pointer to the device tree blob in memory + * @node[in]: Offset of the child node + * @parent_img_id[out]: Image id of parent + * + * Return 0 on success or an error value otherwise. + ******************************************************************************/ +static int get_parent_img_id(const void *dtb, int node, + unsigned int *parent_img_id) +{ + uint32_t phandle; + int err; + + err = fdt_read_uint32(dtb, node, "parent", &phandle); + if (err < 0) { + ERROR("FCONF: Could not read %s property in node\n", + "parent"); + return err; + } + + node = fdt_node_offset_by_phandle(dtb, phandle); + if (node < 0) { + ERROR("FCONF: Failed to locate node using its phandle\n"); + return node; + } + + err = fdt_read_uint32(dtb, node, "image-id", parent_img_id); + if (err < 0) { + ERROR("FCONF: Could not read %s property in node\n", + "image-id"); + } + + return err; +} + +/******************************************************************************* + * set_desc_data() - Update data in descriptor's structure + * @dtb[in]: Pointer to the device tree blob in memory + * @node[in]: Offset of the node + * @type[in]: Type of image (RAW/CERT) + * + * Return 0 on success or an error value otherwise. + ******************************************************************************/ +static int set_desc_data(const void *dtb, int node, img_type_t type) +{ + int rc; + bool root_certificate = false; + unsigned int img_id, parent_img_id; + + rc = fdt_read_uint32(dtb, node, "image-id", &img_id); + if (rc < 0) { + ERROR("FCONF: Can't find property %s in node\n", + "image-id"); + return rc; + } + + if (fdt_getprop(dtb, node, "root-certificate", + NULL) != NULL) { + root_certificate = true; + } + + if (!root_certificate) { + rc = get_parent_img_id(dtb, node, &parent_img_id); + if (rc < 0) { + return rc; + } + auth_img_descs[img_id].parent = &auth_img_descs[parent_img_id]; + } + + auth_img_descs[img_id].img_id = img_id; + auth_img_descs[img_id].img_type = type; + + rc = populate_and_set_auth_methods(dtb, node, img_id, type, + root_certificate); + if (rc < 0) { + return rc; + } + + if (type == IMG_CERT) { + auth_param_desc_t *auth_param = + pool_alloc_n(&auth_params_pool, + COT_MAX_VERIFIED_PARAMS); + auth_img_descs[img_id].authenticated_data = &auth_param[0]; + } + + cot_desc[img_id] = &auth_img_descs[img_id]; + + return rc; +} + +/******************************************************************************* + * populate_manifest_descs() - Populate CoT descriptors and update global + * certificate structures + * @dtb[in]: Pointer to the device tree blob in memory + * + * Return 0 on success or an error value otherwise. + ******************************************************************************/ +static int populate_manifest_descs(const void *dtb) +{ + int node, child; + int rc; + + /* + * Assert the node offset points to "arm, cert-descs" + * compatible property + */ + const char *compatible_str = "arm, cert-descs"; + + node = fdt_node_offset_by_compatible(dtb, -1, compatible_str); + if (node < 0) { + ERROR("FCONF: Can't find %s compatible in node\n", + compatible_str); + return node; + } + + fdt_for_each_subnode(child, dtb, node) { + rc = set_desc_data(dtb, child, IMG_CERT); + if (rc < 0) { + return rc; + } + } + + return 0; +} + +/******************************************************************************* + * populate_image_descs() - Populate CoT descriptors and update global + * image descriptor structures. + * @dtb[in]: Pointer to the device tree blob in memory + * + * Return 0 on success or an error value otherwise. + ******************************************************************************/ +static int populate_image_descs(const void *dtb) +{ + int node, child; + int rc; + + /* + * Assert the node offset points to "arm, img-descs" + * compatible property + */ + const char *compatible_str = "arm, img-descs"; + + node = fdt_node_offset_by_compatible(dtb, -1, compatible_str); + if (node < 0) { + ERROR("FCONF: Can't find %s compatible in node\n", + compatible_str); + return node; + } + + fdt_for_each_subnode(child, dtb, node) { + rc = set_desc_data(dtb, child, IMG_RAW); + if (rc < 0) { + return rc; + } + } + + return 0; +} + +/******************************************************************************* + * fconf_populate_cot_descs() - Populate CoT descriptors and update global + * structures + * @config[in]: Pointer to the device tree blob in memory + * + * Return 0 on success or an error value otherwise. + ******************************************************************************/ +static int fconf_populate_cot_descs(uintptr_t config) +{ + auth_param_type_desc_t *type_desc = NULL; + unsigned int auth_buf_size = 0U; + int rc; + + /* As libfdt uses void *, we can't avoid this cast */ + const void *dtb = (void *)config; + + /* populate manifest descs information */ + rc = populate_manifest_descs(dtb); + if (rc < 0) { + ERROR("FCONF: population of %s descs failed %d\n", + "manifest", rc); + return rc; + } + + /* populate image descs information */ + rc = populate_image_descs(dtb); + if (rc < 0) { + ERROR("FCONF: population of %s descs failed %d\n", + "images", rc); + return rc; + } + + /* update parent's authentication data */ + for (unsigned int i = 0U; i < MAX_NUMBER_IDS; i++) { + if (auth_img_descs[i].parent != NULL) { + rc = get_auth_param_type_desc(i, + &type_desc, + &auth_buf_size); + if (rc < 0) { + ERROR("FCONF: failed to get auth data %d\n", + rc); + return rc; + } + + rc = update_parent_auth_data(auth_img_descs[i].parent, + type_desc, + auth_buf_size); + if (rc < 0) { + ERROR("FCONF: auth data update failed %d\n", + rc); + return rc; + } + } + } + + return rc; +} + +FCONF_REGISTER_POPULATOR(TB_FW, cot_desc, fconf_populate_cot_descs); +REGISTER_COT(cot_desc); diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index 96ab2d300..bbcc95427 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -297,9 +297,14 @@ ifneq (${TRUSTED_BOARD_BOOT},0) # Include the selected chain of trust sources. ifeq (${COT},tbbr) - AUTH_SOURCES += drivers/auth/tbbr/tbbr_cot_common.c - BL1_SOURCES += drivers/auth/tbbr/tbbr_cot_bl1.c - BL2_SOURCES += drivers/auth/tbbr/tbbr_cot_bl2.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 + else + BL2_SOURCES += drivers/auth/tbbr/tbbr_cot_common.c \ + drivers/auth/tbbr/tbbr_cot_bl2.c + endif else ifeq (${COT},dualroot) AUTH_SOURCES += drivers/auth/dualroot/cot.c else -- cgit v1.2.3 From 70fb765396667176deb5aa1046b0b4be0699fd55 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Fri, 4 Sep 2020 15:01:30 +0100 Subject: plat/arm: fvp: Increase BL2 maximum size Increased BL2 maximum size when CoT descriptors are placed in device tree. Signed-off-by: Manish V Badarkhe Change-Id: I6466d2841e189e7f15eb4f1a8db070542893cb5b --- plat/arm/board/fvp/include/platform_def.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h index a9860174a..50f638924 100644 --- a/plat/arm/board/fvp/include/platform_def.h +++ b/plat/arm/board/fvp/include/platform_def.h @@ -118,7 +118,11 @@ * little space for growth. */ #if TRUSTED_BOARD_BOOT +#if COT_DESC_IN_DTB +# define PLAT_ARM_MAX_BL2_SIZE (UL(0x1E000) - FVP_BL2_ROMLIB_OPTIMIZATION) +#else # define PLAT_ARM_MAX_BL2_SIZE (UL(0x1D000) - FVP_BL2_ROMLIB_OPTIMIZATION) +#endif #else # define PLAT_ARM_MAX_BL2_SIZE (UL(0x13000) - FVP_BL2_ROMLIB_OPTIMIZATION) #endif -- cgit v1.2.3 From 95879319f551a00fd3a896e9165afd3e1f1c794d Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Tue, 15 Sep 2020 17:23:47 +0200 Subject: SPMC: adjust the number of EC context to max number of PEs According to [1] and in context of FF-A v1.0 a secure partition must have either one EC (migratable UP) or a number of ECs equal to the number of PEs (pinned MP). Adjust the SPMC manifest such that the number of ECs is equal to the number of PEs. [1] https://trustedfirmware-a.readthedocs.io/en/latest/components/ secure-partition-manager.html#platform-topology Signed-off-by: Olivier Deprez Change-Id: Ie8c7d96ae7107cb27f5b97882d8f476c18e026d4 --- plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts index ca42da0bc..934a01afc 100644 --- a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts +++ b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts @@ -44,14 +44,14 @@ is_ffa_partition; debug_name = "cactus-secondary"; load_address = <0x7100000>; - vcpu_count = <2>; + vcpu_count = <8>; mem_size = <1048576>; }; vm3 { is_ffa_partition; debug_name = "cactus-tertiary"; load_address = <0x7200000>; - vcpu_count = <2>; + vcpu_count = <8>; mem_size = <1048576>; }; }; -- cgit v1.2.3 From 35d626bb2710103951b05f82dfb02ad49e3e22a4 Mon Sep 17 00:00:00 2001 From: Sayanta Pattanayak Date: Fri, 31 Jul 2020 13:16:13 +0530 Subject: n1sdp: add support for remote chip pcie. Remote chip ITS, SMMU, PCIe nodes are added for enabling remote chip PCIe hierarchy. Change-Id: I5b3ca733715defa38e413588ccd13d0688cba271 Signed-off-by: Sayanta Pattanayak Signed-off-by: Khasim Syed Mohammed --- fdts/n1sdp-multi-chip.dts | 50 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/fdts/n1sdp-multi-chip.dts b/fdts/n1sdp-multi-chip.dts index b58d9d8fb..8932dfcbd 100644 --- a/fdts/n1sdp-multi-chip.dts +++ b/fdts/n1sdp-multi-chip.dts @@ -53,6 +53,42 @@ <0 1 20>, <1 1 10>; }; + + smmu_slave_pcie: iommu@4004f400000 { + compatible = "arm,smmu-v3"; + reg = <0x400 0x4f400000 0 0x40000>; + interrupts = , + , + ; + interrupt-names = "eventq", "cmdq-sync", "gerror"; + msi-parent = <&its2_slave 0>; + #iommu-cells = <1>; + dma-coherent; + }; + + pcie_slave_ctlr: pcie@40070000000 { + compatible = "arm,n1sdp-pcie"; + device_type = "pci"; + reg = <0x400 0x70000000 0 0x1200000>; + bus-range = <0 0xff>; + linux,pci-domain = <2>; + #address-cells = <3>; + #size-cells = <2>; + dma-coherent; + ranges = <0x01000000 0x00 0x00000000 0x400 0x75200000 0x00 0x00010000>, + <0x02000000 0x00 0x71200000 0x400 0x71200000 0x00 0x04000000>, + <0x42000000 0x09 0x00000000 0x409 0x00000000 0x20 0x00000000>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &gic 0 0 0 649 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &gic 0 0 0 650 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &gic 0 0 0 651 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &gic 0 0 0 652 IRQ_TYPE_LEVEL_HIGH>; + msi-map = <0 &its_slave_pcie 0 0x10000>; + iommu-map = <0 &smmu_slave_pcie 0 0x10000>; + status = "okay"; + }; + }; &gic { @@ -60,4 +96,18 @@ reg = <0x0 0x30000000 0 0x10000>, /* GICD */ <0x0 0x300c0000 0 0x80000>, /* GICR */ <0x400 0x300c0000 0 0x80000>; /* GICR */ + + its2_slave: its@40030060000 { + compatible = "arm,gic-v3-its"; + msi-controller; + #msi-cells = <1>; + reg = <0x400 0x30060000 0x0 0x20000>; + }; + + its_slave_pcie: its@400300a0000 { + compatible = "arm,gic-v3-its"; + msi-controller; + #msi-cells = <1>; + reg = <0x400 0x300a0000 0x0 0x20000>; + }; }; -- cgit v1.2.3 From 374eef025f4d4d407fb84dd83b1fef5d5477e991 Mon Sep 17 00:00:00 2001 From: Madhukar Pappireddy Date: Wed, 16 Sep 2020 18:58:49 -0500 Subject: libc: Import strtok_r from FreeBSD project From commit: 21571b1d140ae7bb44e94c0afba2ec61456b275b Made small changes to fit into TF-A project Change-Id: I991f653a7ace04f9c84bcda78ad8d7114ea18e93 Signed-off-by: Madhukar Pappireddy --- include/lib/libc/string.h | 1 + lib/libc/strtok.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 lib/libc/strtok.c diff --git a/include/lib/libc/string.h b/include/lib/libc/string.h index 91cbafbb7..989448318 100644 --- a/include/lib/libc/string.h +++ b/include/lib/libc/string.h @@ -27,5 +27,6 @@ size_t strnlen(const char *s, size_t maxlen); char *strrchr(const char *p, int ch); size_t strlcpy(char * dst, const char * src, size_t dsize); size_t strlcat(char * dst, const char * src, size_t dsize); +char *strtok_r(char *s, const char *delim, char **last); #endif /* STRING_H */ diff --git a/lib/libc/strtok.c b/lib/libc/strtok.c new file mode 100644 index 000000000..7e1a4d2f7 --- /dev/null +++ b/lib/libc/strtok.c @@ -0,0 +1,83 @@ +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 1998 Softweyr LLC. All rights reserved. + * + * strtok_r, from Berkeley strtok + * Oct 13, 1998 by Wes Peters + * + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notices, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notices, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY SOFTWEYR LLC, THE REGENTS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SOFTWEYR LLC, THE + * REGENTS, OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +char * +strtok_r(char *s, const char *delim, char **last) +{ + char *spanp, *tok; + int c, sc; + + if (s == NULL && (s = *last) == NULL) + return (NULL); + + /* + * Skip (span) leading delimiters (s += strspn(s, delim), sort of). + */ +cont: + c = *s++; + for (spanp = (char *)delim; (sc = *spanp++) != 0;) { + if (c == sc) + goto cont; + } + + if (c == 0) { /* no non-delimiter characters */ + *last = NULL; + return (NULL); + } + tok = s - 1; + + /* + * Scan token (scan for delimiters: s += strcspn(s, delim), sort of). + * Note that delim must have one NUL; we stop if we see that, too. + */ + for (;;) { + c = *s++; + spanp = (char *)delim; + do { + if ((sc = *spanp++) == c) { + if (c == 0) + s = NULL; + else + s[-1] = '\0'; + *last = s; + return (tok); + } + } while (sc != 0); + } + /* NOTREACHED */ +} -- cgit v1.2.3 From 00a55fe4c5d206e9ecec9d598dfb99a1ac8b296a Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Thu, 17 Sep 2020 15:15:27 +0200 Subject: Align AARCH32 version of debug.S with AARCH64 Re-order code (put panic and report_exception at the end of the file). Export asm_print_* functions. Add asm_print_line_dec macro, and asm_print_newline func. Align comments in both AARCH32 and AARCH64 files. Add blank lines in AARCH64 files to align with AARCH32. Change-Id: I8e299a27c1390f71f04e260cd4a0e59b2384eb19 Signed-off-by: Yann Gautier --- common/aarch32/debug.S | 161 +++++++++++++++++++++++++++---------------------- common/aarch64/debug.S | 15 +++-- 2 files changed, 99 insertions(+), 77 deletions(-) diff --git a/common/aarch32/debug.S b/common/aarch32/debug.S index f50635691..9d410df07 100644 --- a/common/aarch32/debug.S +++ b/common/aarch32/debug.S @@ -1,71 +1,25 @@ /* - * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include #include +#include + .globl asm_print_str + .globl asm_print_hex + .globl asm_print_hex_bits .globl asm_assert .globl do_panic .globl report_exception /* Since the max decimal input number is 65536 */ #define MAX_DEC_DIVISOR 10000 - /* The offset to add to get ascii for numerals '0 - 9' */ #define ASCII_OFFSET_NUM '0' - .section .rodata.panic_str, "aS" -panic_msg: - .asciz "PANIC at PC : 0x" -panic_end: - .asciz "\r\n" - - /*********************************************************** - * The common implementation of do_panic for all BL stages - ***********************************************************/ -func do_panic - /* Have LR copy point to PC at the time of panic */ - sub r6, lr, #4 - - /* Initialize crash console and verify success */ - bl plat_crash_console_init - cmp r0, #0 - beq 1f - - /* Print panic message */ - ldr r4, =panic_msg - bl asm_print_str - - /* Print LR in hex */ - mov r4, r6 - bl asm_print_hex - - /* Print new line */ - ldr r4, =panic_end - bl asm_print_str - - bl plat_crash_console_flush - -1: - mov lr, r6 - b plat_panic_handler -endfunc do_panic - - /*********************************************************** - * This function is called from the vector table for - * unhandled exceptions. It reads the current mode and - * passes it to platform. - ***********************************************************/ -func report_exception - mrs r0, cpsr - and r0, #MODE32_MASK - bl plat_report_exception - no_ret plat_panic_handler -endfunc report_exception - #if ENABLE_ASSERTIONS .section .rodata.assert_str, "aS" assert_msg1: @@ -79,6 +33,26 @@ assert_msg2: .asciz " Line 0x" #else .asciz " Line " + + /* + * This macro is intended to be used to print the + * line number in decimal. Used by asm_assert macro. + * The max number expected is 65536. + * In: r4 = the decimal to print. + * Clobber: lr, r0, r1, r2, r5, r6 + */ + .macro asm_print_line_dec + mov r6, #10 /* Divide by 10 after every loop iteration */ + ldr r5, =MAX_DEC_DIVISOR +dec_print_loop: + udiv r0, r4, r5 /* Get the quotient */ + mls r4, r0, r5, r4 /* Find the remainder */ + add r0, r0, #ASCII_OFFSET_NUM /* Convert to ascii */ + bl plat_crash_console_putc + udiv r5, r5, r6 /* Reduce divisor */ + cmp r5, #0 + bne dec_print_loop + .endm #endif /* --------------------------------------------------------------------------- @@ -100,25 +74,25 @@ func asm_assert mov r5, r0 mov r6, r1 - /* Initialize crash console and verify success */ + /* Ensure the console is initialized */ bl plat_crash_console_init + + /* Check if the console is initialized */ cmp r0, #0 - beq 1f + beq _assert_loop - /* Print file name */ + /* The console is initialized */ ldr r4, =assert_msg1 bl asm_print_str mov r4, r5 bl asm_print_str - - /* Print line number string */ ldr r4, =assert_msg2 bl asm_print_str - /* Test for maximum supported line number */ + /* Check if line number higher than max permitted */ ldr r4, =~0xffff tst r6, r4 - bne 1f + bne _assert_loop mov r4, r6 #if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION) @@ -128,22 +102,10 @@ func asm_assert ******************************************************************/ bl asm_print_hex #else - /* Print line number in decimal */ - mov r6, #10 /* Divide by 10 after every loop iteration */ - ldr r5, =MAX_DEC_DIVISOR -dec_print_loop: - udiv r0, r4, r5 /* Quotient */ - mls r4, r0, r5, r4 /* Remainder */ - add r0, r0, #ASCII_OFFSET_NUM /* Convert to ASCII */ - bl plat_crash_console_putc - udiv r5, r5, r6 /* Reduce divisor */ - cmp r5, #0 - bne dec_print_loop + asm_print_line_dec #endif - bl plat_crash_console_flush - -1: +_assert_loop: #endif /* LOG_LEVEL >= LOG_LEVEL_INFO */ no_ret plat_panic_handler endfunc asm_assert @@ -171,8 +133,11 @@ endfunc asm_print_str * Clobber: lr, r0 - r3, r5 */ func asm_print_hex - mov r3, lr mov r5, #32 /* No of bits to convert to ascii */ + + /* Convert to ascii number of bits in r5 */ +asm_print_hex_bits: + mov r3, lr 1: sub r5, r5, #4 lsr r0, r4, r5 @@ -190,3 +155,53 @@ func asm_print_hex bne 1b bx r3 endfunc asm_print_hex + + /*********************************************************** + * The common implementation of do_panic for all BL stages + ***********************************************************/ + +.section .rodata.panic_str, "aS" + panic_msg: .asciz "PANIC at PC : 0x" + panic_end: .asciz "\r\n" + +func do_panic + /* Have LR copy point to PC at the time of panic */ + sub r6, lr, #4 + + /* Initialize crash console and verify success */ + bl plat_crash_console_init + + /* Check if the console is initialized */ + cmp r0, #0 + beq _panic_handler + + /* The console is initialized */ + ldr r4, =panic_msg + bl asm_print_str + + /* Print LR in hex */ + mov r4, r6 + bl asm_print_hex + + /* Print new line */ + ldr r4, =panic_end + bl asm_print_str + + bl plat_crash_console_flush + +_panic_handler: + mov lr, r6 + b plat_panic_handler +endfunc do_panic + + /*********************************************************** + * This function is called from the vector table for + * unhandled exceptions. It reads the current mode and + * passes it to platform. + ***********************************************************/ +func report_exception + mrs r0, cpsr + and r0, #MODE32_MASK + bl plat_report_exception + no_ret plat_panic_handler +endfunc report_exception diff --git a/common/aarch64/debug.S b/common/aarch64/debug.S index 7db24396e..ad6acd9d2 100644 --- a/common/aarch64/debug.S +++ b/common/aarch64/debug.S @@ -38,11 +38,11 @@ assert_msg2: mov x6, #10 /* Divide by 10 after every loop iteration */ mov x5, #MAX_DEC_DIVISOR dec_print_loop: - udiv x0, x4, x5 /* Get the quotient */ - msub x4, x0, x5, x4 /* Find the remainder */ - add x0, x0, #ASCII_OFFSET_NUM /* Convert to ascii */ + udiv x0, x4, x5 /* Get the quotient */ + msub x4, x0, x5, x4 /* Find the remainder */ + add x0, x0, #ASCII_OFFSET_NUM /* Convert to ascii */ bl plat_crash_console_putc - udiv x5, x5, x6 /* Reduce divisor */ + udiv x5, x5, x6 /* Reduce divisor */ cbnz x5, dec_print_loop .endm @@ -64,10 +64,13 @@ func asm_assert */ mov x5, x0 mov x6, x1 + /* Ensure the console is initialized */ bl plat_crash_console_init + /* Check if the console is initialized */ cbz x0, _assert_loop + /* The console is initialized */ adr x4, assert_msg1 bl asm_print_str @@ -75,6 +78,7 @@ func asm_assert bl asm_print_str adr x4, assert_msg2 bl asm_print_str + /* Check if line number higher than max permitted */ tst x6, #~0xffff b.ne _assert_loop @@ -191,12 +195,15 @@ panic_common: el3_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 -- cgit v1.2.3 From a9eda77c22d045dc7f09272b3cba76225177f9f5 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Tue, 15 Sep 2020 12:24:46 +0200 Subject: stm32mp1: update plat_report_exception In case DEBUG is enabled, plat_report_exception will now display extra information of the cause of the exception. Change-Id: I72cc9d180959cbf31c13821dd051eaf4462b733e Signed-off-by: Yann Gautier --- plat/st/stm32mp1/stm32mp1_helper.S | 57 +++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/plat/st/stm32mp1/stm32mp1_helper.S b/plat/st/stm32mp1/stm32mp1_helper.S index bfcd991a3..b4b699ea4 100644 --- a/plat/st/stm32mp1/stm32mp1_helper.S +++ b/plat/st/stm32mp1/stm32mp1_helper.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -32,7 +32,48 @@ func platform_mem_init endfunc platform_mem_init func plat_report_exception +#if DEBUG + mov r8, lr + + /* Test if an abort occurred */ + cmp r0, #MODE32_abt + bne undef_inst_lbl + ldr r4, =abort_str + bl asm_print_str + mrs r4, lr_abt + sub r4, r4, #4 + b print_exception_info + +undef_inst_lbl: + /* Test for an undefined instruction */ + cmp r0, #MODE32_und + bne other_exception_lbl + ldr r4, =undefined_str + bl asm_print_str + mrs r4, lr_und + b print_exception_info + +other_exception_lbl: + /* Other exceptions */ + mov r9, r0 + ldr r4, =exception_start_str + bl asm_print_str + mov r4, r9 + bl asm_print_hex + ldr r4, =exception_end_str + bl asm_print_str + mov r4, r6 + +print_exception_info: + bl asm_print_hex + + ldr r4, =end_error_str + bl asm_print_str + + bx r8 +#else bx lr +#endif endfunc plat_report_exception func plat_reset_handler @@ -174,3 +215,17 @@ func plat_crash_console_putc ldr r1, =STM32MP_DEBUG_USART_BASE b console_stm32_core_putc endfunc plat_crash_console_putc + +#if DEBUG +.section .rodata.rev_err_str, "aS" +abort_str: + .asciz "\nAbort at: 0x" +undefined_str: + .asciz "\nUndefined instruction at: 0x" +exception_start_str: + .asciz "\nException mode=0x" +exception_end_str: + .asciz " at: 0x" +end_error_str: + .asciz "\n\r" +#endif -- cgit v1.2.3 From 6397423ed4a08adea3605f60a168a34c2a7ec526 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Tue, 15 Sep 2020 12:29:53 +0200 Subject: stm32mp1: add plat_panic_handler function The STM32MP1 implementation of this function will call plat_report_exception(). It displays more information about the panic if DEBUG is enabled. The LR register is also filled with R6 content, which hold the faulty address. This allows debugger to reconstruct the backtrace. Change-Id: I6710e8e2ab6658b05c5bbad2f3c545f07f355afb Signed-off-by: Yann Gautier --- plat/st/stm32mp1/stm32mp1_helper.S | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/plat/st/stm32mp1/stm32mp1_helper.S b/plat/st/stm32mp1/stm32mp1_helper.S index b4b699ea4..560e06e20 100644 --- a/plat/st/stm32mp1/stm32mp1_helper.S +++ b/plat/st/stm32mp1/stm32mp1_helper.S @@ -216,6 +216,23 @@ func plat_crash_console_putc b console_stm32_core_putc endfunc plat_crash_console_putc + /* ---------------------------------------------------------- + * void plat_panic_handler(void) __dead2; + * Report exception + endless loop. + * + * r6 holds the address where the fault occurred. + * Filling lr with this value allows debuggers to reconstruct + * the backtrace. + * ---------------------------------------------------------- + */ +func plat_panic_handler + mrs r0, cpsr + and r0, #MODE32_MASK + bl plat_report_exception + mov lr, r6 + b . +endfunc plat_panic_handler + #if DEBUG .section .rodata.rev_err_str, "aS" abort_str: -- cgit v1.2.3 From 4170079ae05a962a43962f426815e12d516fb3f9 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Tue, 25 Feb 2020 17:51:52 +0100 Subject: stm32mp1: correct crash console GPIO alternate configuration If GPIO port for UART TX is less than 8, the register GPIO_AFRL should be used to set the alternate. GPIO_AFRH is used if GPIO port is greater or equal to 8. The macro GPIO_TX_ALT_SHIFT is removed and the GPIO port number is tested against GPIO_ALT_LOWER_LIMIT (=8) in plat_crash_console_init() function. Change-Id: Ibb62223ed6bce589bbcab59a5e986b2677e6d118 Signed-off-by: Yann Gautier --- plat/st/stm32mp1/stm32mp1_helper.S | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/plat/st/stm32mp1/stm32mp1_helper.S b/plat/st/stm32mp1/stm32mp1_helper.S index 560e06e20..407eb3979 100644 --- a/plat/st/stm32mp1/stm32mp1_helper.S +++ b/plat/st/stm32mp1/stm32mp1_helper.S @@ -12,7 +12,6 @@ #include #define GPIO_TX_SHIFT (DEBUG_UART_TX_GPIO_PORT << 1) -#define GPIO_TX_ALT_SHIFT ((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2) .globl platform_mem_init .globl plat_report_exception @@ -170,10 +169,19 @@ func plat_crash_console_init bic r2, r2, #(GPIO_PULL_MASK << GPIO_TX_SHIFT) str r2, [r1, #GPIO_PUPD_OFFSET] /* Set alternate */ +#if DEBUG_UART_TX_GPIO_PORT >= GPIO_ALT_LOWER_LIMIT ldr r2, [r1, #GPIO_AFRH_OFFSET] - bic r2, r2, #(GPIO_ALTERNATE_MASK << GPIO_TX_ALT_SHIFT) - orr r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << GPIO_TX_ALT_SHIFT) + bic r2, r2, #(GPIO_ALTERNATE_MASK << \ + ((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2)) + orr r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << \ + ((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2)) str r2, [r1, #GPIO_AFRH_OFFSET] +#else + ldr r2, [r1, #GPIO_AFRL_OFFSET] + bic r2, r2, #(GPIO_ALTERNATE_MASK << (DEBUG_UART_TX_GPIO_PORT << 2)) + orr r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << (DEBUG_UART_TX_GPIO_PORT << 2)) + str r2, [r1, #GPIO_AFRL_OFFSET] +#endif /* Enable UART clock, with its source */ ldr r1, =(RCC_BASE + DEBUG_UART_TX_CLKSRC_REG) mov r2, #DEBUG_UART_TX_CLKSRC -- cgit v1.2.3 From 6ac269d16ccb83e4d2c33683366aa0c0e2a8aea0 Mon Sep 17 00:00:00 2001 From: Javier Almansa Sobrino Date: Fri, 18 Sep 2020 16:47:07 +0100 Subject: Select the Log Level for the Event Log Dump on Measured Boot at build time. Builds in Debug mode with Measured Boot enabled might run out of trusted SRAM. This patch allows to change the Log Level at which the Measured Boot driver will dump the event log, so the latter can be accessed even on Release builds if necessary, saving space on RAM. Signed-off-by: Javier Almansa Sobrino Change-Id: I133689e313776cb3f231b774c26cbca4760fa120 --- docs/getting_started/build-options.rst | 4 ++++ drivers/measured_boot/measured_boot.mk | 4 ++++ include/drivers/measured_boot/event_log.h | 2 -- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index b4fe40436..40fc5dbbc 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -300,6 +300,10 @@ Common build options handled at EL3, and a panic will result. This is supported only for AArch64 builds. +- ``EVENT_LOG_LEVEL``: Chooses the log level to use for Measured Boot when + ``MEASURED_BOOT`` is enabled. For a list of valid values, see ``LOG_LEVEL``. + Default value is 40 (LOG_LEVEL_INFO). + - ``FAULT_INJECTION_SUPPORT``: ARMv8.4 extensions introduced support for fault injection from lower ELs, and this build option enables lower ELs to use Error Records accessed via System Registers to inject faults. This is diff --git a/drivers/measured_boot/measured_boot.mk b/drivers/measured_boot/measured_boot.mk index b7aa48bb9..497fdbaae 100644 --- a/drivers/measured_boot/measured_boot.mk +++ b/drivers/measured_boot/measured_boot.mk @@ -4,6 +4,9 @@ # 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 @@ -31,6 +34,7 @@ $(eval $(call add_defines,\ TPM_ALG_ID \ TCG_DIGEST_SIZE \ EVENT_LOG_SIZE \ + EVENT_LOG_LEVEL \ ))) ifeq (${HASH_ALG}, sha256) diff --git a/include/drivers/measured_boot/event_log.h b/include/drivers/measured_boot/event_log.h index 10dfbb39d..efde11762 100644 --- a/include/drivers/measured_boot/event_log.h +++ b/include/drivers/measured_boot/event_log.h @@ -20,8 +20,6 @@ * LOG_LEVEL_WARNING * LOG_LEVEL_VERBOSE */ -#define EVENT_LOG_LEVEL LOG_LEVEL_INFO - #if EVENT_LOG_LEVEL == LOG_LEVEL_ERROR #define LOG_EVENT ERROR #elif EVENT_LOG_LEVEL == LOG_LEVEL_NOTICE -- cgit v1.2.3 From 8f734c6528430daa6a9282dd36b81e91626e35cd Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Tue, 18 Aug 2020 12:56:44 +0100 Subject: fdts: tc0: update MHUv2 interrupt number This is as part of the architecture change in TC0. Change-Id: I470241f67938e7998941d26f0e8bc05073234152 Signed-off-by: Usama Arif --- fdts/tc0.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdts/tc0.dts b/fdts/tc0.dts index ac097cdde..15c14cabd 100644 --- a/fdts/tc0.dts +++ b/fdts/tc0.dts @@ -134,7 +134,7 @@ clocks = <&soc_refclk100mhz>; clock-names = "apb_pclk"; #mbox-cells = <1>; - interrupts = <0 316 4>; + interrupts = <0 317 4>; interrupt-names = "mhu_rx"; mhu-protocol = "doorbell"; }; -- cgit v1.2.3 From 277d6af5616b270436219733a34ded2048c98702 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Fri, 18 Sep 2020 15:04:14 +0200 Subject: fdts: stm32mp1: realign device tree with kernel There is one dtsi file per SoC version: - STM32MP151: common part for all version, Single Cortex-A7 - STM32MP153: Dual Cortex-A7 - STM32MP157: + GPU and DSI, but not needed for TF-A The STM32MP15xC include a cryptography peripheral, add it in a dedicated file. There are 4 packages available, for which the IOs number change. Have one file for each package. The 2 packages AB and AD are added. STM32157A-DK1 and STM32MP157C-DK2 share most of their features, a common dkx file is then created. Some reordering is done in other files, and realign with kernel DT files. The DDR files are generated with our internal tool, no changes in the registers values. Change-Id: I9f2ef00306310abe34b94c2f10fc7a77a10493d1 Signed-off-by: Yann Gautier --- fdts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi | 49 ++- fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi | 49 ++- fdts/stm32mp15-pinctrl.dtsi | 292 +++++++++++++ fdts/stm32mp151.dtsi | 612 ++++++++++++++++++++++++++++ fdts/stm32mp153.dtsi | 19 + fdts/stm32mp157-pinctrl.dtsi | 373 ----------------- fdts/stm32mp157.dtsi | 7 + fdts/stm32mp157a-avenger96.dts | 140 ++++--- fdts/stm32mp157a-dk1.dts | 296 +------------- fdts/stm32mp157c-dk2.dts | 23 +- fdts/stm32mp157c-ed1.dts | 191 +++++---- fdts/stm32mp157c-security.dtsi | 41 -- fdts/stm32mp157c.dtsi | 374 ----------------- fdts/stm32mp157caa-pinctrl.dtsi | 90 ---- fdts/stm32mp157cac-pinctrl.dtsi | 78 ---- fdts/stm32mp15xc.dtsi | 18 + fdts/stm32mp15xx-dkx.dtsi | 350 ++++++++++++++++ fdts/stm32mp15xxaa-pinctrl.dtsi | 85 ++++ fdts/stm32mp15xxab-pinctrl.dtsi | 57 +++ fdts/stm32mp15xxac-pinctrl.dtsi | 73 ++++ fdts/stm32mp15xxad-pinctrl.dtsi | 57 +++ include/dt-bindings/pinctrl/stm32-pinfunc.h | 9 +- plat/st/stm32mp1/stm32mp1_def.h | 2 +- 23 files changed, 1835 insertions(+), 1450 deletions(-) create mode 100644 fdts/stm32mp15-pinctrl.dtsi create mode 100644 fdts/stm32mp151.dtsi create mode 100644 fdts/stm32mp153.dtsi delete mode 100644 fdts/stm32mp157-pinctrl.dtsi create mode 100644 fdts/stm32mp157.dtsi delete mode 100644 fdts/stm32mp157c-security.dtsi delete mode 100644 fdts/stm32mp157c.dtsi delete mode 100644 fdts/stm32mp157caa-pinctrl.dtsi delete mode 100644 fdts/stm32mp157cac-pinctrl.dtsi create mode 100644 fdts/stm32mp15xc.dtsi create mode 100644 fdts/stm32mp15xx-dkx.dtsi create mode 100644 fdts/stm32mp15xxaa-pinctrl.dtsi create mode 100644 fdts/stm32mp15xxab-pinctrl.dtsi create mode 100644 fdts/stm32mp15xxac-pinctrl.dtsi create mode 100644 fdts/stm32mp15xxad-pinctrl.dtsi diff --git a/fdts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi b/fdts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi index 11e8f2bef..c0fc1f772 100644 --- a/fdts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi +++ b/fdts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi @@ -1,24 +1,23 @@ // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause /* * Copyright (C) 2018, STMicroelectronics - All Rights Reserved + */ + +/* + * File generated by STMicroelectronics STM32CubeMX DDR Tool for MPUs + * DDR type: DDR3 / DDR3L + * DDR width: 16bits + * DDR density: 4Gb + * System frequency: 533000Khz + * Relaxed Timing Mode: false + * Address mapping type: RBC * - * STM32MP157C DK1/DK2 BOARD configuration - * 1x DDR3L 4Gb, 16-bit, 533MHz. - * Reference used NT5CC256M16DP-DI from NANYA - * - * DDR type / Platform DDR3/3L - * freq 533MHz - * width 16 - * datasheet 0 = MT41J256M16-187 / DDR3-1066 bin G - * DDR density 4 - * timing mode optimized - * Scheduling/QoS options : type = 2 - * address mapping : RBC - * Tc > + 85C : N + * Save Date: 2020.02.20, save Time: 18:45:20 */ -#define DDR_MEM_NAME "DDR3-1066/888 bin G 1x4Gb 533MHz v1.45" -#define DDR_MEM_SPEED 533000 -#define DDR_MEM_SIZE 0x20000000 + +#define DDR_MEM_NAME "DDR3-DDR3L 16bits 533000Khz" +#define DDR_MEM_SPEED 533000 +#define DDR_MEM_SIZE 0x20000000 #define DDR_MSTR 0x00041401 #define DDR_MRCTRL0 0x00000010 @@ -50,15 +49,6 @@ #define DDR_DFIUPD1 0x00000000 #define DDR_DFIUPD2 0x00000000 #define DDR_DFIPHYMSTR 0x00000000 -#define DDR_ADDRMAP1 0x00070707 -#define DDR_ADDRMAP2 0x00000000 -#define DDR_ADDRMAP3 0x1F000000 -#define DDR_ADDRMAP4 0x00001F1F -#define DDR_ADDRMAP5 0x06060606 -#define DDR_ADDRMAP6 0x0F060606 -#define DDR_ADDRMAP9 0x00000000 -#define DDR_ADDRMAP10 0x00000000 -#define DDR_ADDRMAP11 0x00000000 #define DDR_ODTCFG 0x06000600 #define DDR_ODTMAP 0x00000001 #define DDR_SCHED 0x00000C01 @@ -83,6 +73,15 @@ #define DDR_PCFGQOS1_1 0x00800040 #define DDR_PCFGWQOS0_1 0x01100C03 #define DDR_PCFGWQOS1_1 0x01000200 +#define DDR_ADDRMAP1 0x00070707 +#define DDR_ADDRMAP2 0x00000000 +#define DDR_ADDRMAP3 0x1F000000 +#define DDR_ADDRMAP4 0x00001F1F +#define DDR_ADDRMAP5 0x06060606 +#define DDR_ADDRMAP6 0x0F060606 +#define DDR_ADDRMAP9 0x00000000 +#define DDR_ADDRMAP10 0x00000000 +#define DDR_ADDRMAP11 0x00000000 #define DDR_PGCR 0x01442E02 #define DDR_PTR0 0x0022AA5B #define DDR_PTR1 0x04841104 diff --git a/fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi b/fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi index 4b70b6055..fc226d254 100644 --- a/fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi +++ b/fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi @@ -1,24 +1,23 @@ // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause /* * Copyright (C) 2018, STMicroelectronics - All Rights Reserved + */ + +/* + * File generated by STMicroelectronics STM32CubeMX DDR Tool for MPUs + * DDR type: DDR3 / DDR3L + * DDR width: 32bits + * DDR density: 8Gb + * System frequency: 533000Khz + * Relaxed Timing Mode: false + * Address mapping type: RBC * - * STM32MP157C ED1 BOARD configuration - * 2x DDR3L 4Gb each, 16-bit, 533MHz, Single Die Package in flyby topology. - * Reference used NT5CC256M16DP-DI from NANYA - * - * DDR type / Platform DDR3/3L - * freq 533MHz - * width 32 - * datasheet 0 = MT41J256M16-187 / DDR3-1066 bin G - * DDR density 8 - * timing mode optimized - * Scheduling/QoS options : type = 2 - * address mapping : RBC - * Tc > + 85C : N + * Save Date: 2020.02.20, save Time: 18:49:33 */ -#define DDR_MEM_NAME "DDR3-1066/888 bin G 2x4Gb 533MHz v1.45" -#define DDR_MEM_SPEED 533000 -#define DDR_MEM_SIZE 0x40000000 + +#define DDR_MEM_NAME "DDR3-DDR3L 32bits 533000Khz" +#define DDR_MEM_SPEED 533000 +#define DDR_MEM_SIZE 0x40000000 #define DDR_MSTR 0x00040401 #define DDR_MRCTRL0 0x00000010 @@ -50,15 +49,6 @@ #define DDR_DFIUPD1 0x00000000 #define DDR_DFIUPD2 0x00000000 #define DDR_DFIPHYMSTR 0x00000000 -#define DDR_ADDRMAP1 0x00080808 -#define DDR_ADDRMAP2 0x00000000 -#define DDR_ADDRMAP3 0x00000000 -#define DDR_ADDRMAP4 0x00001F1F -#define DDR_ADDRMAP5 0x07070707 -#define DDR_ADDRMAP6 0x0F070707 -#define DDR_ADDRMAP9 0x00000000 -#define DDR_ADDRMAP10 0x00000000 -#define DDR_ADDRMAP11 0x00000000 #define DDR_ODTCFG 0x06000600 #define DDR_ODTMAP 0x00000001 #define DDR_SCHED 0x00000C01 @@ -83,6 +73,15 @@ #define DDR_PCFGQOS1_1 0x00800040 #define DDR_PCFGWQOS0_1 0x01100C03 #define DDR_PCFGWQOS1_1 0x01000200 +#define DDR_ADDRMAP1 0x00080808 +#define DDR_ADDRMAP2 0x00000000 +#define DDR_ADDRMAP3 0x00000000 +#define DDR_ADDRMAP4 0x00001F1F +#define DDR_ADDRMAP5 0x07070707 +#define DDR_ADDRMAP6 0x0F070707 +#define DDR_ADDRMAP9 0x00000000 +#define DDR_ADDRMAP10 0x00000000 +#define DDR_ADDRMAP11 0x00000000 #define DDR_PGCR 0x01442E02 #define DDR_PTR0 0x0022AA5B #define DDR_PTR1 0x04841104 diff --git a/fdts/stm32mp15-pinctrl.dtsi b/fdts/stm32mp15-pinctrl.dtsi new file mode 100644 index 000000000..d3d1744ec --- /dev/null +++ b/fdts/stm32mp15-pinctrl.dtsi @@ -0,0 +1,292 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2017 - All Rights Reserved + * Author: Ludovic Barre for STMicroelectronics. + */ +#include + +&pinctrl { + fmc_pins_a: fmc-0 { + pins1 { + pinmux = , /* FMC_NOE */ + , /* FMC_NWE */ + , /* FMC_A16_FMC_CLE */ + , /* FMC_A17_FMC_ALE */ + , /* FMC_D0 */ + , /* FMC_D1 */ + , /* FMC_D2 */ + , /* FMC_D3 */ + , /* FMC_D4 */ + , /* FMC_D5 */ + , /* FMC_D6 */ + , /* FMC_D7 */ + ; /* FMC_NE2_FMC_NCE */ + bias-disable; + drive-push-pull; + slew-rate = <1>; + }; + pins2 { + pinmux = ; /* FMC_NWAIT */ + bias-pull-up; + }; + }; + + qspi_clk_pins_a: qspi-clk-0 { + pins { + pinmux = ; /* QSPI_CLK */ + bias-disable; + drive-push-pull; + slew-rate = <3>; + }; + }; + + qspi_bk1_pins_a: qspi-bk1-0 { + pins1 { + pinmux = , /* QSPI_BK1_IO0 */ + , /* QSPI_BK1_IO1 */ + , /* QSPI_BK1_IO2 */ + ; /* QSPI_BK1_IO3 */ + bias-disable; + drive-push-pull; + slew-rate = <1>; + }; + pins2 { + pinmux = ; /* QSPI_BK1_NCS */ + bias-pull-up; + drive-push-pull; + slew-rate = <1>; + }; + }; + + qspi_bk2_pins_a: qspi-bk2-0 { + pins1 { + pinmux = , /* QSPI_BK2_IO0 */ + , /* QSPI_BK2_IO1 */ + , /* QSPI_BK2_IO2 */ + ; /* QSPI_BK2_IO3 */ + bias-disable; + drive-push-pull; + slew-rate = <1>; + }; + pins2 { + pinmux = ; /* QSPI_BK2_NCS */ + bias-pull-up; + drive-push-pull; + slew-rate = <1>; + }; + }; + + 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 */ + , /* SDMMC1_D1 */ + , /* SDMMC1_D2 */ + , /* SDMMC1_D3 */ + ; /* SDMMC1_CMD */ + slew-rate = <1>; + drive-push-pull; + bias-disable; + }; + pins2 { + pinmux = ; /* SDMMC1_CK */ + slew-rate = <2>; + drive-push-pull; + bias-disable; + }; + }; + + sdmmc1_dir_pins_a: sdmmc1-dir-0 { + pins1 { + pinmux = , /* SDMMC1_D0DIR */ + , /* SDMMC1_D123DIR */ + ; /* SDMMC1_CDIR */ + slew-rate = <1>; + drive-push-pull; + bias-pull-up; + }; + pins2{ + pinmux = ; /* SDMMC1_CKIN */ + bias-pull-up; + }; + }; + + sdmmc2_b4_pins_a: sdmmc2-b4-0 { + pins1 { + pinmux = , /* SDMMC2_D0 */ + , /* SDMMC2_D1 */ + , /* SDMMC2_D2 */ + , /* SDMMC2_D3 */ + ; /* SDMMC2_CMD */ + slew-rate = <1>; + drive-push-pull; + bias-pull-up; + }; + pins2 { + pinmux = ; /* SDMMC2_CK */ + slew-rate = <2>; + drive-push-pull; + bias-pull-up; + }; + }; + + sdmmc2_b4_pins_b: sdmmc2-b4-1 { + pins1 { + pinmux = , /* SDMMC2_D0 */ + , /* SDMMC2_D1 */ + , /* SDMMC2_D2 */ + , /* SDMMC2_D3 */ + ; /* SDMMC2_CMD */ + slew-rate = <1>; + drive-push-pull; + bias-disable; + }; + pins2 { + pinmux = ; /* SDMMC2_CK */ + slew-rate = <2>; + drive-push-pull; + bias-disable; + }; + }; + + sdmmc2_d47_pins_a: sdmmc2-d47-0 { + pins { + pinmux = , /* SDMMC2_D4 */ + , /* SDMMC2_D5 */ + , /* SDMMC2_D6 */ + ; /* SDMMC2_D7 */ + slew-rate = <1>; + drive-push-pull; + bias-pull-up; + }; + }; + + uart4_pins_a: uart4-0 { + pins1 { + pinmux = ; /* UART4_TX */ + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins2 { + pinmux = ; /* UART4_RX */ + bias-disable; + }; + }; + + uart4_pins_b: uart4-1 { + pins1 { + pinmux = ; /* UART4_TX */ + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins2 { + pinmux = ; /* UART4_RX */ + bias-disable; + }; + }; + + uart7_pins_a: uart7-0 { + pins1 { + pinmux = ; /* UART4_TX */ + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins2 { + pinmux = , /* UART4_RX */ + , /* UART4_CTS */ + ; /* UART4_RTS */ + bias-disable; + }; + }; + + uart7_pins_b: uart7-1 { + pins1 { + pinmux = ; /* USART7_TX */ + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins2 { + pinmux = ; /* USART7_RX */ + bias-disable; + }; + }; + + usart2_pins_a: usart2-0 { + pins1 { + pinmux = , /* USART2_TX */ + ; /* USART2_RTS */ + bias-disable; + drive-push-pull; + slew-rate = <3>; + }; + pins2 { + pinmux = , /* USART2_RX */ + ; /* USART2_CTS_NSS */ + bias-disable; + }; + }; + + usart3_pins_a: usart3-0 { + pins1 { + pinmux = , /* USART3_TX */ + ; /* USART3_RTS */ + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins2 { + pinmux = , /* USART3_RX */ + ; /* USART3_CTS_NSS */ + bias-disable; + }; + }; + + usart3_pins_b: usart3-1 { + pins1 { + pinmux = , /* USART3_TX */ + ; /* USART3_RTS */ + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins2 { + pinmux = , /* USART3_RX */ + ; /* USART3_CTS_NSS */ + bias-disable; + }; + }; + + usbotg_hs_pins_a: usbotg_hs-0 { + pins { + pinmux = ; /* OTG_ID */ + }; + }; + + usbotg_fs_dp_dm_pins_a: usbotg-fs-dp-dm-0 { + pins { + pinmux = , /* OTG_FS_DM */ + ; /* OTG_FS_DP */ + }; + }; +}; + +&pinctrl_z { + i2c4_pins_a: i2c4-0 { + pins { + pinmux = , /* I2C4_SCL */ + ; /* I2C4_SDA */ + bias-disable; + drive-open-drain; + slew-rate = <0>; + }; + }; +}; diff --git a/fdts/stm32mp151.dtsi b/fdts/stm32mp151.dtsi new file mode 100644 index 000000000..2eb4a3943 --- /dev/null +++ b/fdts/stm32mp151.dtsi @@ -0,0 +1,612 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2017 - All Rights Reserved + * Author: Ludovic Barre for STMicroelectronics. + */ +#include +#include +#include + +/ { + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + compatible = "arm,cortex-a7"; + device_type = "cpu"; + reg = <0>; + }; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + intc: interrupt-controller@a0021000 { + compatible = "arm,cortex-a7-gic"; + #interrupt-cells = <3>; + interrupt-controller; + reg = <0xa0021000 0x1000>, + <0xa0022000 0x2000>; + }; + + clocks { + clk_hse: clk-hse { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <24000000>; + }; + + clk_hsi: clk-hsi { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <64000000>; + }; + + clk_lse: clk-lse { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <32768>; + }; + + clk_lsi: clk-lsi { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <32000>; + }; + + clk_csi: clk-csi { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <4000000>; + }; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&intc>; + ranges; + + timers12: timer@40006000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "st,stm32-timers"; + reg = <0x40006000 0x400>; + clocks = <&rcc TIM12_K>; + clock-names = "int"; + status = "disabled"; + }; + + usart2: serial@4000e000 { + compatible = "st,stm32h7-uart"; + reg = <0x4000e000 0x400>; + interrupts-extended = <&exti 27 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&rcc USART2_K>; + resets = <&rcc USART2_R>; + status = "disabled"; + }; + + usart3: serial@4000f000 { + compatible = "st,stm32h7-uart"; + reg = <0x4000f000 0x400>; + interrupts-extended = <&exti 28 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&rcc USART3_K>; + resets = <&rcc USART3_R>; + status = "disabled"; + }; + + uart4: serial@40010000 { + compatible = "st,stm32h7-uart"; + reg = <0x40010000 0x400>; + interrupts-extended = <&exti 30 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&rcc UART4_K>; + resets = <&rcc UART4_R>; + wakeup-source; + status = "disabled"; + }; + + uart5: serial@40011000 { + compatible = "st,stm32h7-uart"; + reg = <0x40011000 0x400>; + interrupts-extended = <&exti 31 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&rcc UART5_K>; + resets = <&rcc UART5_R>; + status = "disabled"; + }; + + uart7: serial@40018000 { + compatible = "st,stm32h7-uart"; + reg = <0x40018000 0x400>; + interrupts-extended = <&exti 32 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&rcc UART7_K>; + resets = <&rcc UART7_R>; + status = "disabled"; + }; + + uart8: serial@40019000 { + compatible = "st,stm32h7-uart"; + reg = <0x40019000 0x400>; + interrupts-extended = <&exti 33 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&rcc UART8_K>; + resets = <&rcc UART8_R>; + status = "disabled"; + }; + + usart6: serial@44003000 { + compatible = "st,stm32h7-uart"; + reg = <0x44003000 0x400>; + interrupts-extended = <&exti 29 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&rcc USART6_K>; + resets = <&rcc USART6_R>; + status = "disabled"; + }; + + timers15: timer@44006000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "st,stm32-timers"; + reg = <0x44006000 0x400>; + clocks = <&rcc TIM15_K>; + clock-names = "int"; + status = "disabled"; + }; + + usbotg_hs: usb-otg@49000000 { + compatible = "st,stm32mp1-hsotg", "snps,dwc2"; + reg = <0x49000000 0x10000>; + clocks = <&rcc USBO_K>; + clock-names = "otg"; + resets = <&rcc USBO_R>; + reset-names = "dwc2"; + interrupts-extended = <&exti 44 IRQ_TYPE_LEVEL_HIGH>; + g-rx-fifo-size = <512>; + g-np-tx-fifo-size = <32>; + g-tx-fifo-size = <256 16 16 16 16 16 16 16>; + dr_mode = "otg"; + usb33d-supply = <&usb33>; + status = "disabled"; + }; + + rcc: rcc@50000000 { + compatible = "st,stm32mp1-rcc", "syscon"; + reg = <0x50000000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + #clock-cells = <1>; + #reset-cells = <1>; + interrupts = ; + secure-interrupts = ; + secure-interrupt-names = "wakeup"; + }; + + pwr_regulators: pwr@50001000 { + compatible = "st,stm32mp1,pwr-reg"; + reg = <0x50001000 0x10>; + st,tzcr = <&rcc 0x0 0x1>; + + reg11: reg11 { + regulator-name = "reg11"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + }; + + reg18: reg18 { + regulator-name = "reg18"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + usb33: usb33 { + regulator-name = "usb33"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + }; + + pwr_mcu: pwr_mcu@50001014 { + compatible = "st,stm32mp151-pwr-mcu", "syscon"; + reg = <0x50001014 0x4>; + }; + + pwr_irq: pwr@50001020 { + compatible = "st,stm32mp1-pwr"; + reg = <0x50001020 0x100>; + interrupts = ; + interrupt-controller; + #interrupt-cells = <3>; + }; + + exti: interrupt-controller@5000d000 { + compatible = "st,stm32mp1-exti", "syscon"; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x5000d000 0x400>; + + /* exti_pwr is an extra interrupt controller used for + * EXTI 55 to 60. It's mapped on pwr interrupt + * controller. + */ + exti_pwr: exti-pwr { + interrupt-controller; + #interrupt-cells = <2>; + interrupt-parent = <&pwr_irq>; + st,irq-number = <6>; + }; + }; + + syscfg: syscon@50020000 { + compatible = "st,stm32mp157-syscfg", "syscon"; + reg = <0x50020000 0x400>; + clocks = <&rcc SYSCFG>; + }; + + hash1: hash@54002000 { + compatible = "st,stm32f756-hash"; + reg = <0x54002000 0x400>; + interrupts = ; + clocks = <&rcc HASH1>; + resets = <&rcc HASH1_R>; + status = "disabled"; + }; + + rng1: rng@54003000 { + compatible = "st,stm32-rng"; + reg = <0x54003000 0x400>; + clocks = <&rcc RNG1_K>; + resets = <&rcc RNG1_R>; + status = "disabled"; + }; + + fmc: nand-controller@58002000 { + compatible = "st,stm32mp15-fmc2"; + reg = <0x58002000 0x1000>, + <0x80000000 0x1000>, + <0x88010000 0x1000>, + <0x88020000 0x1000>, + <0x81000000 0x1000>, + <0x89010000 0x1000>, + <0x89020000 0x1000>; + interrupts = ; + clocks = <&rcc FMC_K>; + resets = <&rcc FMC_R>; + status = "disabled"; + }; + + qspi: spi@58003000 { + compatible = "st,stm32f469-qspi"; + reg = <0x58003000 0x1000>, <0x70000000 0x10000000>; + reg-names = "qspi", "qspi_mm"; + interrupts = ; + clocks = <&rcc QSPI_K>; + resets = <&rcc QSPI_R>; + status = "disabled"; + }; + + sdmmc1: sdmmc@58005000 { + compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell"; + arm,primecell-periphid = <0x00253180>; + reg = <0x58005000 0x1000>, <0x58006000 0x1000>; + interrupts = ; + interrupt-names = "cmd_irq"; + clocks = <&rcc SDMMC1_K>; + clock-names = "apb_pclk"; + resets = <&rcc SDMMC1_R>; + cap-sd-highspeed; + cap-mmc-highspeed; + max-frequency = <120000000>; + status = "disabled"; + }; + + sdmmc2: sdmmc@58007000 { + compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell"; + arm,primecell-periphid = <0x00253180>; + reg = <0x58007000 0x1000>, <0x58008000 0x1000>; + interrupts = ; + interrupt-names = "cmd_irq"; + clocks = <&rcc SDMMC2_K>; + clock-names = "apb_pclk"; + resets = <&rcc SDMMC2_R>; + cap-sd-highspeed; + cap-mmc-highspeed; + max-frequency = <120000000>; + status = "disabled"; + }; + + iwdg2: watchdog@5a002000 { + compatible = "st,stm32mp1-iwdg"; + reg = <0x5a002000 0x400>; + secure-interrupts = ; + clocks = <&rcc IWDG2>, <&rcc CK_LSI>; + clock-names = "pclk", "lsi"; + status = "disabled"; + }; + + usbphyc: usbphyc@5a006000 { + #address-cells = <1>; + #size-cells = <0>; + #clock-cells = <0>; + compatible = "st,stm32mp1-usbphyc"; + reg = <0x5a006000 0x1000>; + clocks = <&rcc USBPHY_K>; + resets = <&rcc USBPHY_R>; + vdda1v1-supply = <®11>; + vdda1v8-supply = <®18>; + status = "disabled"; + + usbphyc_port0: usb-phy@0 { + #phy-cells = <0>; + reg = <0>; + }; + + usbphyc_port1: usb-phy@1 { + #phy-cells = <1>; + reg = <1>; + }; + }; + + usart1: serial@5c000000 { + compatible = "st,stm32h7-uart"; + reg = <0x5c000000 0x400>; + interrupts = ; + clocks = <&rcc USART1_K>; + resets = <&rcc USART1_R>; + status = "disabled"; + }; + + spi6: spi@5c001000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "st,stm32h7-spi"; + reg = <0x5c001000 0x400>; + interrupts = ; + clocks = <&rcc SPI6_K>; + resets = <&rcc SPI6_R>; + status = "disabled"; + }; + + i2c4: i2c@5c002000 { + compatible = "st,stm32mp15-i2c"; + reg = <0x5c002000 0x400>; + interrupt-names = "event", "error"; + interrupts-extended = <&exti 24 IRQ_TYPE_LEVEL_HIGH>, + <&intc GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&rcc I2C4_K>; + resets = <&rcc I2C4_R>; + #address-cells = <1>; + #size-cells = <0>; + st,syscfg-fmp = <&syscfg 0x4 0x8>; + wakeup-source; + status = "disabled"; + }; + + iwdg1: watchdog@5c003000 { + compatible = "st,stm32mp1-iwdg"; + reg = <0x5C003000 0x400>; + interrupts = ; + clocks = <&rcc IWDG1>, <&rcc CK_LSI>; + clock-names = "pclk", "lsi"; + status = "disabled"; + }; + + rtc: rtc@5c004000 { + compatible = "st,stm32mp1-rtc"; + reg = <0x5c004000 0x400>; + clocks = <&rcc RTCAPB>, <&rcc RTC>; + clock-names = "pclk", "rtc_ck"; + interrupts-extended = <&exti 19 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + bsec: nvmem@5c005000 { + compatible = "st,stm32mp15-bsec"; + reg = <0x5c005000 0x400>; + #address-cells = <1>; + #size-cells = <1>; + ts_cal1: calib@5c { + reg = <0x5c 0x2>; + }; + ts_cal2: calib@5e { + reg = <0x5e 0x2>; + }; + }; + + etzpc: etzpc@5c007000 { + compatible = "st,stm32-etzpc"; + reg = <0x5C007000 0x400>; + clocks = <&rcc TZPC>; + status = "disabled"; + secure-status = "okay"; + }; + + stgen: stgen@5c008000 { + compatible = "st,stm32-stgen"; + reg = <0x5C008000 0x1000>; + }; + + i2c6: i2c@5c009000 { + compatible = "st,stm32mp15-i2c"; + reg = <0x5c009000 0x400>; + interrupt-names = "event", "error"; + interrupts-extended = <&exti 54 IRQ_TYPE_LEVEL_HIGH>, + <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&rcc I2C6_K>; + resets = <&rcc I2C6_R>; + #address-cells = <1>; + #size-cells = <0>; + st,syscfg-fmp = <&syscfg 0x4 0x20>; + wakeup-source; + status = "disabled"; + }; + + tamp: tamp@5c00a000 { + compatible = "st,stm32-tamp", "simple-bus", "syscon", "simple-mfd"; + reg = <0x5c00a000 0x400>; + secure-interrupts = ; + clocks = <&rcc RTCAPB>; + }; + + /* + * Break node order to solve dependency probe issue between + * pinctrl and exti. + */ + pinctrl: pin-controller@50002000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "st,stm32mp157-pinctrl"; + ranges = <0 0x50002000 0xa400>; + interrupt-parent = <&exti>; + st,syscfg = <&exti 0x60 0xff>; + pins-are-numbered; + + gpioa: gpio@50002000 { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x0 0x400>; + clocks = <&rcc GPIOA>; + st,bank-name = "GPIOA"; + status = "disabled"; + }; + + gpiob: gpio@50003000 { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x1000 0x400>; + clocks = <&rcc GPIOB>; + st,bank-name = "GPIOB"; + status = "disabled"; + }; + + gpioc: gpio@50004000 { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x2000 0x400>; + clocks = <&rcc GPIOC>; + st,bank-name = "GPIOC"; + status = "disabled"; + }; + + gpiod: gpio@50005000 { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x3000 0x400>; + clocks = <&rcc GPIOD>; + st,bank-name = "GPIOD"; + status = "disabled"; + }; + + gpioe: gpio@50006000 { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x4000 0x400>; + clocks = <&rcc GPIOE>; + st,bank-name = "GPIOE"; + status = "disabled"; + }; + + gpiof: gpio@50007000 { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x5000 0x400>; + clocks = <&rcc GPIOF>; + st,bank-name = "GPIOF"; + status = "disabled"; + }; + + gpiog: gpio@50008000 { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x6000 0x400>; + clocks = <&rcc GPIOG>; + st,bank-name = "GPIOG"; + status = "disabled"; + }; + + gpioh: gpio@50009000 { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x7000 0x400>; + clocks = <&rcc GPIOH>; + st,bank-name = "GPIOH"; + status = "disabled"; + }; + + gpioi: gpio@5000a000 { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x8000 0x400>; + clocks = <&rcc GPIOI>; + st,bank-name = "GPIOI"; + status = "disabled"; + }; + + gpioj: gpio@5000b000 { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x9000 0x400>; + clocks = <&rcc GPIOJ>; + st,bank-name = "GPIOJ"; + status = "disabled"; + }; + + gpiok: gpio@5000c000 { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0xa000 0x400>; + clocks = <&rcc GPIOK>; + st,bank-name = "GPIOK"; + status = "disabled"; + }; + }; + + pinctrl_z: pin-controller-z@54004000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "st,stm32mp157-z-pinctrl"; + ranges = <0 0x54004000 0x400>; + pins-are-numbered; + interrupt-parent = <&exti>; + st,syscfg = <&exti 0x60 0xff>; + + gpioz: gpio@54004000 { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0 0x400>; + clocks = <&rcc GPIOZ>; + st,bank-name = "GPIOZ"; + st,bank-ioport = <11>; + status = "disabled"; + }; + }; + }; +}; diff --git a/fdts/stm32mp153.dtsi b/fdts/stm32mp153.dtsi new file mode 100644 index 000000000..0a0bb8dc1 --- /dev/null +++ b/fdts/stm32mp153.dtsi @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved + * Author: Alexandre Torgue for STMicroelectronics. + */ + +#include "stm32mp151.dtsi" + +/ { + cpus { + cpu1: cpu@1 { + compatible = "arm,cortex-a7"; + device_type = "cpu"; + reg = <1>; + clocks = <&rcc CK_MPU>; + clock-names = "cpu"; + }; + }; +}; diff --git a/fdts/stm32mp157-pinctrl.dtsi b/fdts/stm32mp157-pinctrl.dtsi deleted file mode 100644 index 7fd902bd2..000000000 --- a/fdts/stm32mp157-pinctrl.dtsi +++ /dev/null @@ -1,373 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) -/* - * Copyright (C) STMicroelectronics 2017-2019 - All Rights Reserved - * Author: Ludovic Barre for STMicroelectronics. - */ -#include - -/ { - soc { - pinctrl: pin-controller@50002000 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "st,stm32mp157-pinctrl"; - ranges = <0 0x50002000 0xa400>; - pins-are-numbered; - - gpioa: gpio@50002000 { - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - reg = <0x0 0x400>; - clocks = <&rcc GPIOA>; - st,bank-name = "GPIOA"; - status = "disabled"; - }; - - gpiob: gpio@50003000 { - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - reg = <0x1000 0x400>; - clocks = <&rcc GPIOB>; - st,bank-name = "GPIOB"; - status = "disabled"; - }; - - gpioc: gpio@50004000 { - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - reg = <0x2000 0x400>; - clocks = <&rcc GPIOC>; - st,bank-name = "GPIOC"; - status = "disabled"; - }; - - gpiod: gpio@50005000 { - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - reg = <0x3000 0x400>; - clocks = <&rcc GPIOD>; - st,bank-name = "GPIOD"; - status = "disabled"; - }; - - gpioe: gpio@50006000 { - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - reg = <0x4000 0x400>; - clocks = <&rcc GPIOE>; - st,bank-name = "GPIOE"; - status = "disabled"; - }; - - gpiof: gpio@50007000 { - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - reg = <0x5000 0x400>; - clocks = <&rcc GPIOF>; - st,bank-name = "GPIOF"; - status = "disabled"; - }; - - gpiog: gpio@50008000 { - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - reg = <0x6000 0x400>; - clocks = <&rcc GPIOG>; - st,bank-name = "GPIOG"; - status = "disabled"; - }; - - gpioh: gpio@50009000 { - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - reg = <0x7000 0x400>; - clocks = <&rcc GPIOH>; - st,bank-name = "GPIOH"; - status = "disabled"; - }; - - gpioi: gpio@5000a000 { - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - reg = <0x8000 0x400>; - clocks = <&rcc GPIOI>; - st,bank-name = "GPIOI"; - status = "disabled"; - }; - - gpioj: gpio@5000b000 { - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - reg = <0x9000 0x400>; - clocks = <&rcc GPIOJ>; - st,bank-name = "GPIOJ"; - status = "disabled"; - }; - - gpiok: gpio@5000c000 { - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - reg = <0xa000 0x400>; - clocks = <&rcc GPIOK>; - st,bank-name = "GPIOK"; - status = "disabled"; - }; - - fmc_pins_a: fmc-0 { - pins1 { - pinmux = , /* FMC_NOE */ - , /* FMC_NWE */ - , /* FMC_A16_FMC_CLE */ - , /* FMC_A17_FMC_ALE */ - , /* FMC_D0 */ - , /* FMC_D1 */ - , /* FMC_D2 */ - , /* FMC_D3 */ - , /* FMC_D4 */ - , /* FMC_D5 */ - , /* FMC_D6 */ - , /* FMC_D7 */ - ; /* FMC_NE2_FMC_NCE */ - bias-disable; - drive-push-pull; - slew-rate = <1>; - }; - pins2 { - pinmux = ; /* FMC_NWAIT */ - bias-pull-up; - }; - }; - - qspi_bk1_pins_a: qspi-bk1-0 { - pins1 { - pinmux = , /* QSPI_BK1_IO0 */ - , /* QSPI_BK1_IO1 */ - , /* QSPI_BK1_IO2 */ - ; /* QSPI_BK1_IO3 */ - bias-disable; - drive-push-pull; - slew-rate = <1>; - }; - pins2 { - pinmux = ; /* QSPI_BK1_NCS */ - bias-pull-up; - drive-push-pull; - slew-rate = <1>; - }; - }; - - qspi_bk2_pins_a: qspi-bk2-0 { - pins1 { - pinmux = , /* QSPI_BK2_IO0 */ - , /* QSPI_BK2_IO1 */ - , /* QSPI_BK2_IO2 */ - ; /* QSPI_BK2_IO3 */ - bias-disable; - drive-push-pull; - slew-rate = <1>; - }; - pins2 { - pinmux = ; /* QSPI_BK2_NCS */ - bias-pull-up; - drive-push-pull; - slew-rate = <1>; - }; - }; - - qspi_clk_pins_a: qspi-clk-0 { - pins { - pinmux = ; /* QSPI_CLK */ - bias-disable; - drive-push-pull; - slew-rate = <3>; - }; - }; - - sdmmc1_b4_pins_a: sdmmc1-b4-0 { - pins1 { - pinmux = , /* SDMMC1_D0 */ - , /* SDMMC1_D1 */ - , /* SDMMC1_D2 */ - , /* SDMMC1_D3 */ - ; /* SDMMC1_CMD */ - slew-rate = <1>; - drive-push-pull; - bias-disable; - }; - pins2 { - pinmux = ; /* SDMMC1_CK */ - slew-rate = <2>; - drive-push-pull; - bias-disable; - }; - }; - - sdmmc1_dir_pins_a: sdmmc1-dir-0 { - pins1 { - pinmux = , /* SDMMC1_D0DIR */ - , /* SDMMC1_D123DIR */ - ; /* SDMMC1_CDIR */ - slew-rate = <1>; - drive-push-pull; - bias-pull-up; - }; - pins2{ - pinmux = ; /* SDMMC1_CKIN */ - bias-pull-up; - }; - }; - - sdmmc2_b4_pins_a: sdmmc2-b4-0 { - pins1 { - pinmux = , /* SDMMC2_D0 */ - , /* SDMMC2_D1 */ - , /* SDMMC2_D2 */ - , /* SDMMC2_D3 */ - ; /* SDMMC2_CMD */ - slew-rate = <1>; - drive-push-pull; - bias-pull-up; - }; - pins2 { - pinmux = ; /* SDMMC2_CK */ - slew-rate = <2>; - drive-push-pull; - bias-pull-up; - }; - }; - - sdmmc2_d47_pins_a: sdmmc2-d47-0 { - pins { - pinmux = , /* SDMMC2_D4 */ - , /* SDMMC2_D5 */ - , /* SDMMC2_D6 */ - ; /* SDMMC2_D7 */ - slew-rate = <1>; - drive-push-pull; - bias-pull-up; - }; - }; - - uart4_pins_a: uart4-0 { - pins1 { - pinmux = ; /* UART4_TX */ - bias-disable; - drive-push-pull; - slew-rate = <0>; - }; - pins2 { - pinmux = ; /* UART4_RX */ - bias-disable; - }; - }; - - uart4_pins_b: uart4-1 { - pins1 { - pinmux = ; /* UART4_TX */ - bias-disable; - drive-push-pull; - slew-rate = <0>; - }; - pins2 { - pinmux = ; /* UART4_RX */ - bias-disable; - }; - }; - - uart7_pins_a: uart7-0 { - pins1 { - pinmux = ; /* USART7_TX */ - bias-disable; - drive-push-pull; - slew-rate = <0>; - }; - pins2 { - pinmux = ; /* USART7_RX */ - bias-disable; - }; - }; - - usart3_pins_a: usart3-0 { - pins1 { - pinmux = , /* USART3_TX */ - ; /* USART3_RTS */ - bias-disable; - drive-push-pull; - slew-rate = <0>; - }; - pins2 { - pinmux = , /* USART3_RX */ - ; /* USART3_CTS_NSS */ - bias-disable; - }; - }; - - usart3_pins_b: usart3-1 { - pins1 { - pinmux = , /* USART3_TX */ - ; /* USART3_RTS */ - bias-disable; - drive-push-pull; - slew-rate = <0>; - }; - pins2 { - pinmux = , /* USART3_RX */ - ; /* USART3_CTS_NSS */ - bias-disable; - }; - }; - }; - - pinctrl_z: pin-controller-z@54004000 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "st,stm32mp157-z-pinctrl"; - ranges = <0 0x54004000 0x400>; - pins-are-numbered; - - gpioz: gpio@54004000 { - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - reg = <0 0x400>; - clocks = <&rcc GPIOZ>; - st,bank-name = "GPIOZ"; - st,bank-ioport = <11>; - status = "disabled"; - }; - - i2c4_pins_a: i2c4-0 { - pins { - pinmux = , /* I2C4_SCL */ - ; /* I2C4_SDA */ - bias-disable; - drive-open-drain; - slew-rate = <0>; - }; - }; - }; - }; -}; diff --git a/fdts/stm32mp157.dtsi b/fdts/stm32mp157.dtsi new file mode 100644 index 000000000..c83402907 --- /dev/null +++ b/fdts/stm32mp157.dtsi @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved + * Author: Alexandre Torgue for STMicroelectronics. + */ + +#include "stm32mp153.dtsi" diff --git a/fdts/stm32mp157a-avenger96.dts b/fdts/stm32mp157a-avenger96.dts index 907940c78..b967736e4 100644 --- a/fdts/stm32mp157a-avenger96.dts +++ b/fdts/stm32mp157a-avenger96.dts @@ -9,21 +9,30 @@ /dts-v1/; -#include "stm32mp157c.dtsi" -#include "stm32mp157cac-pinctrl.dtsi" +#include "stm32mp157.dtsi" +#include "stm32mp15-pinctrl.dtsi" +#include "stm32mp15xxac-pinctrl.dtsi" +#include +#include "stm32mp15-ddr3-2x4Gb-1066-binG.dtsi" / { model = "Arrow Electronics STM32MP157A Avenger96 board"; - compatible = "st,stm32mp157a-avenger96", "st,stm32mp157"; + compatible = "arrow,stm32mp157a-avenger96", "st,stm32mp157"; aliases { + mmc0 = &sdmmc1; serial0 = &uart4; + serial1 = &uart7; }; chosen { stdout-path = "serial0:115200n8"; }; + memory@c0000000 { + device_type = "memory"; + reg = <0xc0000000 0x40000000>; + }; }; &i2c4 { @@ -43,16 +52,17 @@ st,main-control-register = <0x04>; st,vin-control-register = <0xc0>; - st,usb-control-register = <0x20>; + st,usb-control-register = <0x30>; regulators { compatible = "st,stpmic1-regulators"; - ldo1-supply = <&v3v3>; ldo2-supply = <&v3v3>; ldo3-supply = <&vdd_ddr>; ldo5-supply = <&v3v3>; ldo6-supply = <&v3v3>; + pwr_sw1-supply = <&bst_out>; + pwr_sw2-supply = <&bst_out>; vddcore: buck1 { regulator-name = "vddcore"; @@ -135,6 +145,19 @@ regulator-always-on; regulator-over-current-protection; }; + + bst_out: boost { + regulator-name = "bst_out"; + }; + + vbus_otg: pwr_sw1 { + regulator-name = "vbus_otg"; + }; + + vbus_sw: pwr_sw2 { + regulator-name = "vbus_sw"; + regulator-active-discharge = <1>; + }; }; }; }; @@ -142,56 +165,14 @@ &iwdg2 { timeout-sec = <32>; status = "okay"; + secure-status = "okay"; }; -&rng1 { - status = "okay"; -}; - -&rtc { - status = "okay"; -}; - -&sdmmc1 { - pinctrl-names = "default"; - pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_a>; - broken-cd; - st,sig-dir; - st,neg-edge; - st,use-ckin; - bus-width = <4>; - vmmc-supply = <&vdda>; - status = "okay"; -}; - -&uart4 { - pinctrl-names = "default"; - pinctrl-0 = <&uart4_pins_b>; - status = "okay"; -}; - -/* ATF Specific */ -#include -#include "stm32mp15-ddr3-2x4Gb-1066-binG.dtsi" -#include "stm32mp157c-security.dtsi" - -/ { - aliases { - gpio0 = &gpioa; - gpio1 = &gpiob; - gpio2 = &gpioc; - gpio3 = &gpiod; - gpio4 = &gpioe; - gpio5 = &gpiof; - gpio6 = &gpiog; - gpio7 = &gpioh; - gpio8 = &gpioi; - gpio25 = &gpioz; - i2c3 = &i2c4; - }; +&pwr_regulators { + vdd-supply = <&vdd>; + vdd_3v3_usbfs-supply = <&vdd_usb>; }; -/* CLOCK init */ &rcc { secure-status = "disabled"; st,clksrc = < @@ -260,24 +241,67 @@ /* 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 = 480.0 MHz => P = 120, Q = 40, R = 96 */ pll4: st,pll@3 { - cfg = < 1 39 3 11 4 PQR(1,1,1) >; + compatible = "st,stm32mp1-pll"; + reg = <3>; + cfg = <1 39 3 11 4 PQR(1,1,1)>; }; }; + +&rng1 { + status = "okay"; +}; + +&rtc { + status = "okay"; +}; + +&sdmmc1 { + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_a>; + st,sig-dir; + st,neg-edge; + st,use-ckin; + bus-width = <4>; + vmmc-supply = <&vdd_sd>; + status = "okay"; +}; + +&uart4 { + /* On Low speed expansion header */ + label = "LS-UART1"; + pinctrl-names = "default"; + pinctrl-0 = <&uart4_pins_b>; + status = "okay"; +}; + +&uart7 { + /* On Low speed expansion header */ + label = "LS-UART0"; + pinctrl-names = "default"; + pinctrl-0 = <&uart7_pins_a>; + status = "okay"; +}; diff --git a/fdts/stm32mp157a-dk1.dts b/fdts/stm32mp157a-dk1.dts index 4ea83f7cd..a73bef8ee 100644 --- a/fdts/stm32mp157a-dk1.dts +++ b/fdts/stm32mp157a-dk1.dts @@ -1,13 +1,15 @@ // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) /* - * Copyright (C) STMicroelectronics 2018-2019 - All Rights Reserved - * Author: Alexandre Torgue . + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved + * Author: Alexandre Torgue for STMicroelectronics. */ /dts-v1/; -#include "stm32mp157c.dtsi" -#include "stm32mp157cac-pinctrl.dtsi" +#include "stm32mp157.dtsi" +#include "stm32mp15-pinctrl.dtsi" +#include "stm32mp15xxac-pinctrl.dtsi" +#include "stm32mp15xx-dkx.dtsi" / { model = "STMicroelectronics STM32MP157A-DK1 Discovery Board"; @@ -22,290 +24,4 @@ chosen { stdout-path = "serial0:115200n8"; }; - -}; - -&clk_hse { - st,digbypass; -}; - -&i2c4 { - pinctrl-names = "default"; - pinctrl-0 = <&i2c4_pins_a>; - i2c-scl-rising-time-ns = <185>; - i2c-scl-falling-time-ns = <20>; - status = "okay"; - - pmic: stpmic@33 { - compatible = "st,stpmic1"; - reg = <0x33>; - interrupts-extended = <&exti_pwr 55 IRQ_TYPE_EDGE_FALLING>; - interrupt-controller; - #interrupt-cells = <2>; - status = "okay"; - - st,main-control-register = <0x04>; - st,vin-control-register = <0xc0>; - st,usb-control-register = <0x20>; - - regulators { - compatible = "st,stpmic1-regulators"; - - ldo1-supply = <&v3v3>; - ldo3-supply = <&vdd_ddr>; - ldo6-supply = <&v3v3>; - - vddcore: buck1 { - regulator-name = "vddcore"; - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <1350000>; - regulator-always-on; - regulator-initial-mode = <0>; - regulator-over-current-protection; - }; - - vdd_ddr: buck2 { - regulator-name = "vdd_ddr"; - regulator-min-microvolt = <1350000>; - regulator-max-microvolt = <1350000>; - regulator-always-on; - regulator-initial-mode = <0>; - regulator-over-current-protection; - }; - - vdd: buck3 { - regulator-name = "vdd"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - regulator-always-on; - st,mask-reset; - regulator-initial-mode = <0>; - regulator-over-current-protection; - }; - - v3v3: buck4 { - regulator-name = "v3v3"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - regulator-always-on; - regulator-over-current-protection; - regulator-initial-mode = <0>; - }; - - v1v8_audio: ldo1 { - regulator-name = "v1v8_audio"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-always-on; - }; - - v3v3_hdmi: ldo2 { - regulator-name = "v3v3_hdmi"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - regulator-always-on; - }; - - vtt_ddr: ldo3 { - regulator-name = "vtt_ddr"; - regulator-min-microvolt = <500000>; - regulator-max-microvolt = <750000>; - regulator-always-on; - regulator-over-current-protection; - }; - - vdd_usb: ldo4 { - regulator-name = "vdd_usb"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - }; - - vdda: ldo5 { - regulator-name = "vdda"; - regulator-min-microvolt = <2900000>; - regulator-max-microvolt = <2900000>; - regulator-boot-on; - }; - - v1v2_hdmi: ldo6 { - regulator-name = "v1v2_hdmi"; - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <1200000>; - regulator-always-on; - }; - - vref_ddr: vref_ddr { - regulator-name = "vref_ddr"; - regulator-always-on; - regulator-over-current-protection; - }; - }; - }; -}; - -&iwdg2 { - timeout-sec = <32>; - status = "okay"; -}; - -&pwr { - pwr-regulators { - vdd-supply = <&vdd>; - }; -}; - -&rng1 { - status = "okay"; -}; - -&rtc { - status = "okay"; -}; - -&sdmmc1 { - pinctrl-names = "default"; - pinctrl-0 = <&sdmmc1_b4_pins_a>; - broken-cd; - st,neg-edge; - bus-width = <4>; - vmmc-supply = <&v3v3>; - status = "okay"; -}; - -&uart4 { - pinctrl-names = "default"; - pinctrl-0 = <&uart4_pins_a>; - status = "okay"; -}; - -&uart7 { - pinctrl-names = "default"; - pinctrl-0 = <&uart7_pins_a>; - status = "disabled"; -}; - -&usart3 { - pinctrl-names = "default"; - pinctrl-0 = <&usart3_pins_b>; - status = "disabled"; -}; - -/* ATF Specific */ -#include -#include "stm32mp15-ddr3-1x4Gb-1066-binG.dtsi" -#include "stm32mp157c-security.dtsi" - -/ { - aliases { - gpio0 = &gpioa; - gpio1 = &gpiob; - gpio2 = &gpioc; - gpio3 = &gpiod; - gpio4 = &gpioe; - gpio5 = &gpiof; - gpio6 = &gpiog; - gpio7 = &gpioh; - gpio8 = &gpioi; - gpio25 = &gpioz; - i2c3 = &i2c4; - }; -}; - -/* CLOCK init */ -&rcc { - secure-status = "disabled"; - st,clksrc = < - CLK_MPU_PLL1P - CLK_AXI_PLL2P - CLK_MCU_PLL3P - CLK_PLL12_HSE - CLK_PLL3_HSE - CLK_PLL4_HSE - CLK_RTC_LSE - CLK_MCO1_DISABLED - CLK_MCO2_DISABLED - >; - - st,clkdiv = < - 1 /*MPU*/ - 0 /*AXI*/ - 0 /*MCU*/ - 1 /*APB1*/ - 1 /*APB2*/ - 1 /*APB3*/ - 1 /*APB4*/ - 2 /*APB5*/ - 23 /*RTC*/ - 0 /*MCO1*/ - 0 /*MCO2*/ - >; - - st,pkcs = < - CLK_CKPER_HSE - CLK_FMC_ACLK - CLK_QSPI_ACLK - CLK_ETH_DISABLED - CLK_SDMMC12_PLL4P - CLK_DSI_DSIPLL - CLK_STGEN_HSE - CLK_USBPHY_HSE - CLK_SPI2S1_PLL3Q - CLK_SPI2S23_PLL3Q - CLK_SPI45_HSI - CLK_SPI6_HSI - CLK_I2C46_HSI - CLK_SDMMC3_PLL4P - CLK_USBO_USBPHY - CLK_ADC_CKPER - CLK_CEC_LSE - CLK_I2C12_HSI - CLK_I2C35_HSI - CLK_UART1_HSI - CLK_UART24_HSI - CLK_UART35_HSI - CLK_UART6_HSI - CLK_UART78_HSI - CLK_SPDIF_PLL4P - CLK_FDCAN_PLL4R - CLK_SAI1_PLL3Q - CLK_SAI2_PLL3Q - CLK_SAI3_PLL3Q - CLK_SAI4_PLL3Q - CLK_RNG1_LSI - CLK_RNG2_LSI - CLK_LPTIM1_PCLK1 - CLK_LPTIM23_PCLK3 - CLK_LPTIM45_LSE - >; - - /* VCO = 1300.0 MHz => P = 650 (CPU) */ - pll1: st,pll@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 >; - }; - - /* 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 >; - }; - - /* VCO = 594.0 MHz => P = 99, Q = 74, R = 74 */ - pll4: st,pll@3 { - cfg = < 3 98 5 7 7 PQR(1,1,1) >; - }; -}; - -&bsec { - board_id: board_id@ec { - reg = <0xec 0x4>; - status = "okay"; - secure-status = "okay"; - }; }; diff --git a/fdts/stm32mp157c-dk2.dts b/fdts/stm32mp157c-dk2.dts index fdcf4c802..be8300e9e 100644 --- a/fdts/stm32mp157c-dk2.dts +++ b/fdts/stm32mp157c-dk2.dts @@ -1,16 +1,33 @@ // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) /* - * Copyright (C) STMicroelectronics 2018 - All Rights Reserved - * Author: Alexandre Torgue . + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved + * Author: Alexandre Torgue for STMicroelectronics. */ /dts-v1/; -#include "stm32mp157a-dk1.dts" +#include "stm32mp157.dtsi" +#include "stm32mp15xc.dtsi" +#include "stm32mp15-pinctrl.dtsi" +#include "stm32mp15xxac-pinctrl.dtsi" +#include "stm32mp15xx-dkx.dtsi" / { model = "STMicroelectronics STM32MP157C-DK2 Discovery Board"; compatible = "st,stm32mp157c-dk2", "st,stm32mp157"; + aliases { + serial0 = &uart4; + serial1 = &usart3; + serial2 = &uart7; + serial3 = &usart2; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; }; +&cryp1 { + status = "okay"; +}; diff --git a/fdts/stm32mp157c-ed1.dts b/fdts/stm32mp157c-ed1.dts index 779492552..615e2cc07 100644 --- a/fdts/stm32mp157c-ed1.dts +++ b/fdts/stm32mp157c-ed1.dts @@ -5,8 +5,12 @@ */ /dts-v1/; -#include "stm32mp157c.dtsi" -#include "stm32mp157caa-pinctrl.dtsi" +#include "stm32mp157.dtsi" +#include "stm32mp15xc.dtsi" +#include "stm32mp15-pinctrl.dtsi" +#include "stm32mp15xxaa-pinctrl.dtsi" +#include +#include "stm32mp15-ddr3-2x4Gb-1066-binG.dtsi" / { model = "STMicroelectronics STM32MP157C eval daughter"; @@ -16,20 +20,47 @@ stdout-path = "serial0:115200n8"; }; + + memory@c0000000 { + device_type = "memory"; + reg = <0xC0000000 0x40000000>; + }; + aliases { serial0 = &uart4; }; }; +&bsec { + board_id: board_id@ec { + reg = <0xec 0x4>; + status = "okay"; + secure-status = "okay"; + }; +}; + &clk_hse { st,digbypass; }; +&cpu0 { + cpu-supply = <&vddcore>; +}; + +&cpu1 { + cpu-supply = <&vddcore>; +}; + +&cryp1 { + status="okay"; +}; + &i2c4 { pinctrl-names = "default"; pinctrl-0 = <&i2c4_pins_a>; i2c-scl-rising-time-ns = <185>; i2c-scl-falling-time-ns = <20>; + clock-frequency = <400000>; status = "okay"; pmic: stpmic@33 { @@ -40,18 +71,15 @@ #interrupt-cells = <2>; status = "okay"; - st,main-control-register = <0x04>; - st,vin-control-register = <0xc0>; - st,usb-control-register = <0x20>; - regulators { compatible = "st,stpmic1-regulators"; - ldo1-supply = <&v3v3>; ldo2-supply = <&v3v3>; ldo3-supply = <&vdd_ddr>; ldo5-supply = <&v3v3>; ldo6-supply = <&v3v3>; + pwr_sw1-supply = <&bst_out>; + pwr_sw2-supply = <&bst_out>; vddcore: buck1 { regulator-name = "vddcore"; @@ -112,8 +140,6 @@ vdd_usb: ldo4 { regulator-name = "vdd_usb"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; }; vdd_sd: ldo5 { @@ -132,92 +158,45 @@ vref_ddr: vref_ddr { regulator-name = "vref_ddr"; regulator-always-on; - regulator-over-current-protection; }; - }; - }; -}; - -&iwdg2 { - timeout-sec = <32>; - status = "okay"; -}; -&pwr { - pwr-regulators { - vdd-supply = <&vdd>; - }; -}; + bst_out: boost { + regulator-name = "bst_out"; + }; -&rng1 { - status = "okay"; -}; + vbus_otg: pwr_sw1 { + regulator-name = "vbus_otg"; + }; -&rtc { - status = "okay"; -}; + vbus_sw: pwr_sw2 { + regulator-name = "vbus_sw"; + regulator-active-discharge = <1>; + }; + }; -&sdmmc1 { - pinctrl-names = "default"; - pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_a>; - broken-cd; - st,sig-dir; - st,neg-edge; - st,use-ckin; - bus-width = <4>; - vmmc-supply = <&vdd_sd>; - sd-uhs-sdr12; - sd-uhs-sdr25; - sd-uhs-sdr50; - sd-uhs-ddr50; - sd-uhs-sdr104; - status = "okay"; -}; + onkey { + compatible = "st,stpmic1-onkey"; + power-off-time-sec = <10>; + status = "okay"; + }; -&sdmmc2 { - pinctrl-names = "default"; - pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_a>; - non-removable; - no-sd; - no-sdio; - st,neg-edge; - bus-width = <8>; - vmmc-supply = <&v3v3>; - vqmmc-supply = <&v3v3>; - mmc-ddr-3_3v; - status = "okay"; + watchdog { + compatible = "st,stpmic1-wdt"; + status = "disabled"; + }; + }; }; -&uart4 { - pinctrl-names = "default"; - pinctrl-0 = <&uart4_pins_a>; +&iwdg2 { + timeout-sec = <32>; status = "okay"; }; -/* ATF Specific */ -#include -#include "stm32mp15-ddr3-2x4Gb-1066-binG.dtsi" -#include "stm32mp157c-security.dtsi" - -/ { - aliases { - gpio0 = &gpioa; - gpio1 = &gpiob; - gpio2 = &gpioc; - gpio3 = &gpiod; - gpio4 = &gpioe; - gpio5 = &gpiof; - gpio6 = &gpiog; - gpio7 = &gpioh; - gpio8 = &gpioi; - gpio9 = &gpioj; - gpio10 = &gpiok; - gpio25 = &gpioz; - i2c3 = &i2c4; - }; +&pwr_regulators { + vdd-supply = <&vdd>; + vdd_3v3_usbfs-supply = <&vdd_usb>; }; -/* CLOCK init */ &rcc { secure-status = "disabled"; st,clksrc = < @@ -308,10 +287,46 @@ }; }; -&bsec { - board_id: board_id@ec { - reg = <0xec 0x4>; - status = "okay"; - secure-status = "okay"; - }; +&rng1 { + status = "okay"; +}; + +&rtc { + status = "okay"; +}; + +&sdmmc1 { + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_a>; + disable-wp; + st,sig-dir; + st,neg-edge; + st,use-ckin; + bus-width = <4>; + vmmc-supply = <&vdd_sd>; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-ddr50; + status = "okay"; +}; + +&sdmmc2 { + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_a>; + non-removable; + no-sd; + no-sdio; + st,neg-edge; + bus-width = <8>; + vmmc-supply = <&v3v3>; + vqmmc-supply = <&vdd>; + mmc-ddr-3_3v; + status = "okay"; +}; + +&uart4 { + pinctrl-names = "default"; + pinctrl-0 = <&uart4_pins_a>; + status = "okay"; }; diff --git a/fdts/stm32mp157c-security.dtsi b/fdts/stm32mp157c-security.dtsi deleted file mode 100644 index 165ffa0cb..000000000 --- a/fdts/stm32mp157c-security.dtsi +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved - * - * SPDX-License-Identifier: GPL-2.0+ BSD-3-Clause - */ - -/ { - soc { - stgen: stgen@5c008000 { - compatible = "st,stm32-stgen"; - reg = <0x5C008000 0x1000>; - status = "okay"; - }; - }; -}; - -&bsec { - mac_addr: mac_addr@e4 { - reg = <0xe4 0x6>; - status = "okay"; - secure-status = "okay"; - }; - /* Spare field to align on 32-bit OTP granularity */ - spare_ns_ea: spare_ns_ea@ea { - reg = <0xea 0x2>; - status = "okay"; - secure-status = "okay"; - }; -}; - -&hash1 { - secure-status = "okay"; -}; - -&sdmmc1 { - compatible = "st,stm32-sdmmc2"; -}; - -&sdmmc2 { - compatible = "st,stm32-sdmmc2"; -}; diff --git a/fdts/stm32mp157c.dtsi b/fdts/stm32mp157c.dtsi deleted file mode 100644 index 91b20fa4a..000000000 --- a/fdts/stm32mp157c.dtsi +++ /dev/null @@ -1,374 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) -/* - * Copyright (C) STMicroelectronics 2017-2019 - All Rights Reserved - * Author: Ludovic Barre for STMicroelectronics. - */ -#include -#include -#include - -/ { - #address-cells = <1>; - #size-cells = <1>; - - intc: interrupt-controller@a0021000 { - compatible = "arm,cortex-a7-gic"; - #interrupt-cells = <3>; - interrupt-controller; - reg = <0xa0021000 0x1000>, - <0xa0022000 0x2000>; - }; - - clocks { - clk_hse: clk-hse { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <24000000>; - }; - - clk_hsi: clk-hsi { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <64000000>; - }; - - clk_lse: clk-lse { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <32768>; - }; - - clk_lsi: clk-lsi { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <32000>; - }; - - clk_csi: clk-csi { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <4000000>; - }; - - clk_i2s_ckin: i2s_ckin { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <0>; - }; - - clk_dsi_phy: ck_dsi_phy { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <0>; - }; - }; - - soc { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - interrupt-parent = <&intc>; - ranges; - - timers12: timer@40006000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "st,stm32-timers"; - reg = <0x40006000 0x400>; - clocks = <&rcc TIM12_K>; - clock-names = "int"; - status = "disabled"; - }; - - usart2: serial@4000e000 { - compatible = "st,stm32h7-uart"; - reg = <0x4000e000 0x400>; - clocks = <&rcc USART2_K>; - resets = <&rcc USART2_R>; - status = "disabled"; - }; - - usart3: serial@4000f000 { - compatible = "st,stm32h7-uart"; - reg = <0x4000f000 0x400>; - clocks = <&rcc USART3_K>; - resets = <&rcc USART3_R>; - status = "disabled"; - }; - - uart4: serial@40010000 { - compatible = "st,stm32h7-uart"; - reg = <0x40010000 0x400>; - clocks = <&rcc UART4_K>; - resets = <&rcc UART4_R>; - status = "disabled"; - }; - - uart5: serial@40011000 { - compatible = "st,stm32h7-uart"; - reg = <0x40011000 0x400>; - clocks = <&rcc UART5_K>; - resets = <&rcc UART5_R>; - status = "disabled"; - }; - - - uart7: serial@40018000 { - compatible = "st,stm32h7-uart"; - reg = <0x40018000 0x400>; - clocks = <&rcc UART7_K>; - resets = <&rcc UART7_R>; - status = "disabled"; - }; - - uart8: serial@40019000 { - compatible = "st,stm32h7-uart"; - reg = <0x40019000 0x400>; - clocks = <&rcc UART8_K>; - resets = <&rcc UART8_R>; - status = "disabled"; - }; - - usart6: serial@44003000 { - compatible = "st,stm32h7-uart"; - reg = <0x44003000 0x400>; - clocks = <&rcc USART6_K>; - resets = <&rcc USART6_R>; - status = "disabled"; - }; - - timers15: timer@44006000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "st,stm32-timers"; - reg = <0x44006000 0x400>; - clocks = <&rcc TIM15_K>; - clock-names = "int"; - status = "disabled"; - }; - - sdmmc3: sdmmc@48004000 { - compatible = "arm,pl18x", "arm,primecell"; - arm,primecell-periphid = <0x00253180>; - reg = <0x48004000 0x400>, <0x48005000 0x400>; - clocks = <&rcc SDMMC3_K>; - clock-names = "apb_pclk"; - resets = <&rcc SDMMC3_R>; - cap-sd-highspeed; - cap-mmc-highspeed; - max-frequency = <120000000>; - status = "disabled"; - }; - - usbotg_hs: usb-otg@49000000 { - compatible = "st,stm32mp1-hsotg", "snps,dwc2"; - reg = <0x49000000 0x10000>; - clocks = <&rcc USBO_K>; - clock-names = "otg"; - resets = <&rcc USBO_R>; - reset-names = "dwc2"; - status = "disabled"; - }; - - rcc: rcc@50000000 { - compatible = "st,stm32mp1-rcc", "syscon"; - reg = <0x50000000 0x1000>; - #clock-cells = <1>; - #reset-cells = <1>; - interrupts = ; - }; - - pwr: pwr@50001000 { - compatible = "st,stm32mp1-pwr", "syscon", "simple-mfd"; - reg = <0x50001000 0x400>; - }; - - exti: interrupt-controller@5000d000 { - compatible = "st,stm32mp1-exti", "syscon"; - interrupt-controller; - #interrupt-cells = <2>; - reg = <0x5000d000 0x400>; - - /* exti_pwr is an extra interrupt controller used for - * EXTI 55 to 60. It's mapped on pwr interrupt - * controller. - */ - exti_pwr: exti-pwr { - interrupt-controller; - #interrupt-cells = <2>; - interrupt-parent = <&pwr>; - st,irq-number = <6>; - }; - }; - - syscfg: syscon@50020000 { - compatible = "st,stm32mp157-syscfg", "syscon"; - reg = <0x50020000 0x400>; - clocks = <&rcc SYSCFG>; - }; - - cryp1: cryp@54001000 { - compatible = "st,stm32mp1-cryp"; - reg = <0x54001000 0x400>; - interrupts = ; - clocks = <&rcc CRYP1>; - resets = <&rcc CRYP1_R>; - status = "disabled"; - }; - - hash1: hash@54002000 { - compatible = "st,stm32f756-hash"; - reg = <0x54002000 0x400>; - interrupts = ; - clocks = <&rcc HASH1>; - resets = <&rcc HASH1_R>; - status = "disabled"; - }; - - rng1: rng@54003000 { - compatible = "st,stm32-rng"; - reg = <0x54003000 0x400>; - clocks = <&rcc RNG1_K>; - resets = <&rcc RNG1_R>; - status = "disabled"; - }; - - fmc: nand-controller@58002000 { - compatible = "st,stm32mp15-fmc2"; - reg = <0x58002000 0x1000>, - <0x80000000 0x1000>, - <0x88010000 0x1000>, - <0x88020000 0x1000>, - <0x81000000 0x1000>, - <0x89010000 0x1000>, - <0x89020000 0x1000>; - clocks = <&rcc FMC_K>; - resets = <&rcc FMC_R>; - status = "disabled"; - }; - - qspi: qspi@58003000 { - compatible = "st,stm32f469-qspi"; - reg = <0x58003000 0x1000>, <0x70000000 0x10000000>; - reg-names = "qspi", "qspi_mm"; - clocks = <&rcc QSPI_K>; - resets = <&rcc QSPI_R>; - status = "disabled"; - }; - - sdmmc1: sdmmc@58005000 { - compatible = "arm,pl18x", "arm,primecell"; - arm,primecell-periphid = <0x00253180>; - reg = <0x58005000 0x1000>, <0x58006000 0x1000>; - clocks = <&rcc SDMMC1_K>; - clock-names = "apb_pclk"; - resets = <&rcc SDMMC1_R>; - cap-sd-highspeed; - cap-mmc-highspeed; - max-frequency = <120000000>; - status = "disabled"; - }; - - sdmmc2: sdmmc@58007000 { - compatible = "arm,pl18x", "arm,primecell"; - arm,primecell-periphid = <0x00253180>; - reg = <0x58007000 0x1000>, <0x58008000 0x1000>; - clocks = <&rcc SDMMC2_K>; - clock-names = "apb_pclk"; - resets = <&rcc SDMMC2_R>; - cap-sd-highspeed; - cap-mmc-highspeed; - max-frequency = <120000000>; - status = "disabled"; - }; - - iwdg2: watchdog@5a002000 { - compatible = "st,stm32mp1-iwdg"; - reg = <0x5a002000 0x400>; - clocks = <&rcc IWDG2>, <&rcc CK_LSI>; - clock-names = "pclk", "lsi"; - status = "disabled"; - }; - - usart1: serial@5c000000 { - compatible = "st,stm32h7-uart"; - reg = <0x5c000000 0x400>; - interrupt-names = "event", "wakeup"; - interrupts-extended = <&intc GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>, - <&exti 26 1>; - clocks = <&rcc USART1_K>; - resets = <&rcc USART1_R>; - status = "disabled"; - }; - - spi6: spi@5c001000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "st,stm32h7-spi"; - reg = <0x5c001000 0x400>; - interrupts = ; - clocks = <&rcc SPI6_K>; - resets = <&rcc SPI6_R>; - status = "disabled"; - }; - - i2c4: i2c@5c002000 { - compatible = "st,stm32f7-i2c"; - reg = <0x5c002000 0x400>; - interrupt-names = "event", "error", "wakeup"; - interrupts-extended = <&intc GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>, - <&intc GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>, - <&exti 24 1>; - clocks = <&rcc I2C4_K>; - resets = <&rcc I2C4_R>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; - - rtc: rtc@5c004000 { - compatible = "st,stm32mp1-rtc"; - reg = <0x5c004000 0x400>; - clocks = <&rcc RTCAPB>, <&rcc RTC>; - clock-names = "pclk", "rtc_ck"; - interrupts-extended = <&intc GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>, - <&exti 19 1>; - status = "disabled"; - }; - - bsec: nvmem@5c005000 { - compatible = "st,stm32mp15-bsec"; - reg = <0x5c005000 0x400>; - #address-cells = <1>; - #size-cells = <1>; - ts_cal1: calib@5c { - reg = <0x5c 0x2>; - }; - ts_cal2: calib@5e { - reg = <0x5e 0x2>; - }; - }; - - etzpc: etzpc@5c007000 { - compatible = "st,stm32-etzpc"; - reg = <0x5C007000 0x400>; - clocks = <&rcc TZPC>; - status = "disabled"; - secure-status = "okay"; - }; - - i2c6: i2c@5c009000 { - compatible = "st,stm32f7-i2c"; - reg = <0x5c009000 0x400>; - interrupt-names = "event", "error", "wakeup"; - interrupts-extended = <&intc GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>, - <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>, - <&exti 54 1>; - clocks = <&rcc I2C6_K>; - resets = <&rcc I2C6_R>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; - }; -}; diff --git a/fdts/stm32mp157caa-pinctrl.dtsi b/fdts/stm32mp157caa-pinctrl.dtsi deleted file mode 100644 index 9b9cd086c..000000000 --- a/fdts/stm32mp157caa-pinctrl.dtsi +++ /dev/null @@ -1,90 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) -/* - * Copyright (C) STMicroelectronics 2018 - All Rights Reserved - * Author: Alexandre Torgue - */ - -#include "stm32mp157-pinctrl.dtsi" -/ { - soc { - pinctrl: pin-controller@50002000 { - st,package = ; - - gpioa: gpio@50002000 { - status = "okay"; - ngpios = <16>; - gpio-ranges = <&pinctrl 0 0 16>; - }; - - gpiob: gpio@50003000 { - status = "okay"; - ngpios = <16>; - gpio-ranges = <&pinctrl 0 16 16>; - }; - - gpioc: gpio@50004000 { - status = "okay"; - ngpios = <16>; - gpio-ranges = <&pinctrl 0 32 16>; - }; - - gpiod: gpio@50005000 { - status = "okay"; - ngpios = <16>; - gpio-ranges = <&pinctrl 0 48 16>; - }; - - gpioe: gpio@50006000 { - status = "okay"; - ngpios = <16>; - gpio-ranges = <&pinctrl 0 64 16>; - }; - - gpiof: gpio@50007000 { - status = "okay"; - ngpios = <16>; - gpio-ranges = <&pinctrl 0 80 16>; - }; - - gpiog: gpio@50008000 { - status = "okay"; - ngpios = <16>; - gpio-ranges = <&pinctrl 0 96 16>; - }; - - gpioh: gpio@50009000 { - status = "okay"; - ngpios = <16>; - gpio-ranges = <&pinctrl 0 112 16>; - }; - - gpioi: gpio@5000a000 { - status = "okay"; - ngpios = <16>; - gpio-ranges = <&pinctrl 0 128 16>; - }; - - gpioj: gpio@5000b000 { - status = "okay"; - ngpios = <16>; - gpio-ranges = <&pinctrl 0 144 16>; - }; - - gpiok: gpio@5000c000 { - status = "okay"; - ngpios = <8>; - gpio-ranges = <&pinctrl 0 160 8>; - }; - }; - - pinctrl_z: pin-controller-z@54004000 { - st,package = ; - - gpioz: gpio@54004000 { - status = "okay"; - ngpios = <8>; - gpio-ranges = <&pinctrl_z 0 400 8>; - }; - }; - }; -}; diff --git a/fdts/stm32mp157cac-pinctrl.dtsi b/fdts/stm32mp157cac-pinctrl.dtsi deleted file mode 100644 index 777f9919d..000000000 --- a/fdts/stm32mp157cac-pinctrl.dtsi +++ /dev/null @@ -1,78 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) -/* - * Copyright (C) STMicroelectronics 2018 - All Rights Reserved - * Author: Alexandre Torgue - */ - -#include "stm32mp157-pinctrl.dtsi" -/ { - soc { - pinctrl: pin-controller@50002000 { - st,package = ; - - gpioa: gpio@50002000 { - status = "okay"; - ngpios = <16>; - gpio-ranges = <&pinctrl 0 0 16>; - }; - - gpiob: gpio@50003000 { - status = "okay"; - ngpios = <16>; - gpio-ranges = <&pinctrl 0 16 16>; - }; - - gpioc: gpio@50004000 { - status = "okay"; - ngpios = <16>; - gpio-ranges = <&pinctrl 0 32 16>; - }; - - gpiod: gpio@50005000 { - status = "okay"; - ngpios = <16>; - gpio-ranges = <&pinctrl 0 48 16>; - }; - - gpioe: gpio@50006000 { - status = "okay"; - ngpios = <16>; - gpio-ranges = <&pinctrl 0 64 16>; - }; - - gpiof: gpio@50007000 { - status = "okay"; - ngpios = <16>; - gpio-ranges = <&pinctrl 0 80 16>; - }; - - gpiog: gpio@50008000 { - status = "okay"; - ngpios = <16>; - gpio-ranges = <&pinctrl 0 96 16>; - }; - - gpioh: gpio@50009000 { - status = "okay"; - ngpios = <16>; - gpio-ranges = <&pinctrl 0 112 16>; - }; - - gpioi: gpio@5000a000 { - status = "okay"; - ngpios = <12>; - gpio-ranges = <&pinctrl 0 128 12>; - }; - }; - - pinctrl_z: pin-controller-z@54004000 { - st,package = ; - - gpioz: gpio@54004000 { - status = "okay"; - ngpios = <8>; - gpio-ranges = <&pinctrl_z 0 400 8>; - }; - }; - }; -}; diff --git a/fdts/stm32mp15xc.dtsi b/fdts/stm32mp15xc.dtsi new file mode 100644 index 000000000..b06a55a2f --- /dev/null +++ b/fdts/stm32mp15xc.dtsi @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved + * Author: Alexandre Torgue for STMicroelectronics. + */ + +/ { + soc { + cryp1: cryp@54001000 { + compatible = "st,stm32mp1-cryp"; + reg = <0x54001000 0x400>; + interrupts = ; + clocks = <&rcc CRYP1>; + resets = <&rcc CRYP1_R>; + status = "disabled"; + }; + }; +}; diff --git a/fdts/stm32mp15xx-dkx.dtsi b/fdts/stm32mp15xx-dkx.dtsi new file mode 100644 index 000000000..52b914b84 --- /dev/null +++ b/fdts/stm32mp15xx-dkx.dtsi @@ -0,0 +1,350 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved + * Author: Alexandre Torgue for STMicroelectronics. + */ + +#include +#include "stm32mp15-ddr3-1x4Gb-1066-binG.dtsi" + +/ { + memory@c0000000 { + device_type = "memory"; + reg = <0xc0000000 0x20000000>; + }; + + vin: vin { + compatible = "regulator-fixed"; + regulator-name = "vin"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; +}; + +&bsec { + board_id: board_id@ec { + reg = <0xec 0x4>; + st,non-secure-otp; + }; +}; + +&clk_hse { + st,digbypass; +}; + +&cpu0{ + cpu-supply = <&vddcore>; +}; + +&cpu1{ + cpu-supply = <&vddcore>; +}; + +&hash1 { + status = "okay"; +}; + +&i2c4 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c4_pins_a>; + i2c-scl-rising-time-ns = <185>; + i2c-scl-falling-time-ns = <20>; + clock-frequency = <400000>; + status = "okay"; + + pmic: stpmic@33 { + compatible = "st,stpmic1"; + reg = <0x33>; + interrupts-extended = <&exti_pwr 55 IRQ_TYPE_EDGE_FALLING>; + interrupt-controller; + #interrupt-cells = <2>; + status = "okay"; + + regulators { + compatible = "st,stpmic1-regulators"; + buck1-supply = <&vin>; + buck2-supply = <&vin>; + buck3-supply = <&vin>; + buck4-supply = <&vin>; + ldo1-supply = <&v3v3>; + ldo2-supply = <&vin>; + ldo3-supply = <&vdd_ddr>; + ldo4-supply = <&vin>; + ldo5-supply = <&vin>; + ldo6-supply = <&v3v3>; + vref_ddr-supply = <&vin>; + boost-supply = <&vin>; + pwr_sw1-supply = <&bst_out>; + pwr_sw2-supply = <&bst_out>; + + vddcore: buck1 { + regulator-name = "vddcore"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1350000>; + regulator-always-on; + regulator-initial-mode = <0>; + regulator-over-current-protection; + }; + + vdd_ddr: buck2 { + regulator-name = "vdd_ddr"; + regulator-min-microvolt = <1350000>; + regulator-max-microvolt = <1350000>; + regulator-always-on; + regulator-initial-mode = <0>; + regulator-over-current-protection; + }; + + vdd: buck3 { + regulator-name = "vdd"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + st,mask-reset; + regulator-initial-mode = <0>; + regulator-over-current-protection; + }; + + v3v3: buck4 { + regulator-name = "v3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-over-current-protection; + regulator-initial-mode = <0>; + }; + + v1v8_audio: ldo1 { + regulator-name = "v1v8_audio"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + v3v3_hdmi: ldo2 { + regulator-name = "v3v3_hdmi"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vtt_ddr: ldo3 { + regulator-name = "vtt_ddr"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <750000>; + regulator-always-on; + regulator-over-current-protection; + }; + + vdd_usb: ldo4 { + regulator-name = "vdd_usb"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vdda: ldo5 { + regulator-name = "vdda"; + regulator-min-microvolt = <2900000>; + regulator-max-microvolt = <2900000>; + regulator-boot-on; + }; + + v1v2_hdmi: ldo6 { + regulator-name = "v1v2_hdmi"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + }; + + vref_ddr: vref_ddr { + regulator-name = "vref_ddr"; + regulator-always-on; + regulator-over-current-protection; + }; + + bst_out: boost { + regulator-name = "bst_out"; + }; + + vbus_otg: pwr_sw1 { + regulator-name = "vbus_otg"; + }; + + vbus_sw: pwr_sw2 { + regulator-name = "vbus_sw"; + regulator-active-discharge = <1>; + }; + }; + }; +}; + +&iwdg2 { + timeout-sec = <32>; + status = "okay"; + secure-status = "okay"; +}; + +&pwr_regulators { + vdd-supply = <&vdd>; + vdd_3v3_usbfs-supply = <&vdd_usb>; +}; + +&rcc { + secure-status = "disabled"; + st,clksrc = < + CLK_MPU_PLL1P + CLK_AXI_PLL2P + CLK_MCU_PLL3P + CLK_PLL12_HSE + CLK_PLL3_HSE + CLK_PLL4_HSE + CLK_RTC_LSE + CLK_MCO1_DISABLED + CLK_MCO2_DISABLED + >; + + st,clkdiv = < + 1 /*MPU*/ + 0 /*AXI*/ + 0 /*MCU*/ + 1 /*APB1*/ + 1 /*APB2*/ + 1 /*APB3*/ + 1 /*APB4*/ + 2 /*APB5*/ + 23 /*RTC*/ + 0 /*MCO1*/ + 0 /*MCO2*/ + >; + + st,pkcs = < + CLK_CKPER_HSE + CLK_FMC_ACLK + CLK_QSPI_ACLK + CLK_ETH_DISABLED + CLK_SDMMC12_PLL4P + CLK_DSI_DSIPLL + CLK_STGEN_HSE + CLK_USBPHY_HSE + CLK_SPI2S1_PLL3Q + CLK_SPI2S23_PLL3Q + CLK_SPI45_HSI + CLK_SPI6_HSI + CLK_I2C46_HSI + CLK_SDMMC3_PLL4P + CLK_USBO_USBPHY + CLK_ADC_CKPER + CLK_CEC_LSE + CLK_I2C12_HSI + CLK_I2C35_HSI + CLK_UART1_HSI + CLK_UART24_HSI + CLK_UART35_HSI + CLK_UART6_HSI + CLK_UART78_HSI + CLK_SPDIF_PLL4P + CLK_FDCAN_PLL4R + CLK_SAI1_PLL3Q + CLK_SAI2_PLL3Q + CLK_SAI3_PLL3Q + CLK_SAI4_PLL3Q + CLK_RNG1_LSI + CLK_RNG2_LSI + CLK_LPTIM1_PCLK1 + CLK_LPTIM23_PCLK3 + CLK_LPTIM45_LSE + >; + + /* VCO = 1300.0 MHz => P = 650 (CPU) */ + pll1: st,pll@0 { + 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 { + 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 { + 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 { + compatible = "st,stm32mp1-pll"; + reg = <3>; + cfg = <3 98 5 7 7 PQR(1,1,1)>; + }; +}; + +&rng1 { + status = "okay"; +}; + +&rtc { + status = "okay"; +}; + +&sdmmc1 { + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc1_b4_pins_a>; + disable-wp; + st,neg-edge; + bus-width = <4>; + vmmc-supply = <&v3v3>; + status = "okay"; +}; + +&timers15 { + secure-status = "okay"; +}; + +&uart4 { + pinctrl-names = "default"; + pinctrl-0 = <&uart4_pins_a>; + status = "okay"; +}; + +&uart7 { + pinctrl-names = "default"; + pinctrl-0 = <&uart7_pins_b>; + status = "disabled"; +}; + +&usart3 { + pinctrl-names = "default"; + pinctrl-0 = <&usart3_pins_b>; + uart-has-rtscts; + status = "disabled"; +}; + +&usbotg_hs { + phys = <&usbphyc_port1 0>; + phy-names = "usb2-phy"; + usb-role-switch; + status = "okay"; +}; + +&usbphyc { + status = "okay"; +}; + +&usbphyc_port0 { + phy-supply = <&vdd_usb>; +}; + +&usbphyc_port1 { + phy-supply = <&vdd_usb>; +}; diff --git a/fdts/stm32mp15xxaa-pinctrl.dtsi b/fdts/stm32mp15xxaa-pinctrl.dtsi new file mode 100644 index 000000000..64e566bf8 --- /dev/null +++ b/fdts/stm32mp15xxaa-pinctrl.dtsi @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved + * Author: Alexandre Torgue + */ + +&pinctrl { + st,package = ; + + gpioa: gpio@50002000 { + status = "okay"; + ngpios = <16>; + gpio-ranges = <&pinctrl 0 0 16>; + }; + + gpiob: gpio@50003000 { + status = "okay"; + ngpios = <16>; + gpio-ranges = <&pinctrl 0 16 16>; + }; + + gpioc: gpio@50004000 { + status = "okay"; + ngpios = <16>; + gpio-ranges = <&pinctrl 0 32 16>; + }; + + gpiod: gpio@50005000 { + status = "okay"; + ngpios = <16>; + gpio-ranges = <&pinctrl 0 48 16>; + }; + + gpioe: gpio@50006000 { + status = "okay"; + ngpios = <16>; + gpio-ranges = <&pinctrl 0 64 16>; + }; + + gpiof: gpio@50007000 { + status = "okay"; + ngpios = <16>; + gpio-ranges = <&pinctrl 0 80 16>; + }; + + gpiog: gpio@50008000 { + status = "okay"; + ngpios = <16>; + gpio-ranges = <&pinctrl 0 96 16>; + }; + + gpioh: gpio@50009000 { + status = "okay"; + ngpios = <16>; + gpio-ranges = <&pinctrl 0 112 16>; + }; + + gpioi: gpio@5000a000 { + status = "okay"; + ngpios = <16>; + gpio-ranges = <&pinctrl 0 128 16>; + }; + + gpioj: gpio@5000b000 { + status = "okay"; + ngpios = <16>; + gpio-ranges = <&pinctrl 0 144 16>; + }; + + gpiok: gpio@5000c000 { + status = "okay"; + ngpios = <8>; + gpio-ranges = <&pinctrl 0 160 8>; + }; +}; + +&pinctrl_z { + st,package = ; + + gpioz: gpio@54004000 { + status = "okay"; + ngpios = <8>; + gpio-ranges = <&pinctrl_z 0 400 8>; + }; +}; diff --git a/fdts/stm32mp15xxab-pinctrl.dtsi b/fdts/stm32mp15xxab-pinctrl.dtsi new file mode 100644 index 000000000..d29af8986 --- /dev/null +++ b/fdts/stm32mp15xxab-pinctrl.dtsi @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved + * Author: Alexandre Torgue + */ + +&pinctrl { + st,package = ; + + gpioa: gpio@50002000 { + status = "okay"; + ngpios = <16>; + gpio-ranges = <&pinctrl 0 0 16>; + }; + + gpiob: gpio@50003000 { + status = "okay"; + ngpios = <16>; + gpio-ranges = <&pinctrl 0 16 16>; + }; + + gpioc: gpio@50004000 { + status = "okay"; + ngpios = <16>; + gpio-ranges = <&pinctrl 0 32 16>; + }; + + gpiod: gpio@50005000 { + status = "okay"; + ngpios = <16>; + gpio-ranges = <&pinctrl 0 48 16>; + }; + + gpioe: gpio@50006000 { + status = "okay"; + ngpios = <16>; + gpio-ranges = <&pinctrl 0 64 16>; + }; + + gpiof: gpio@50007000 { + status = "okay"; + ngpios = <6>; + gpio-ranges = <&pinctrl 6 86 6>; + }; + + gpiog: gpio@50008000 { + status = "okay"; + ngpios = <10>; + gpio-ranges = <&pinctrl 6 102 10>; + }; + + gpioh: gpio@50009000 { + status = "okay"; + ngpios = <2>; + gpio-ranges = <&pinctrl 0 112 2>; + }; +}; diff --git a/fdts/stm32mp15xxac-pinctrl.dtsi b/fdts/stm32mp15xxac-pinctrl.dtsi new file mode 100644 index 000000000..5d8199fd1 --- /dev/null +++ b/fdts/stm32mp15xxac-pinctrl.dtsi @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved + * Author: Alexandre Torgue + */ + +&pinctrl { + st,package = ; + + gpioa: gpio@50002000 { + status = "okay"; + ngpios = <16>; + gpio-ranges = <&pinctrl 0 0 16>; + }; + + gpiob: gpio@50003000 { + status = "okay"; + ngpios = <16>; + gpio-ranges = <&pinctrl 0 16 16>; + }; + + gpioc: gpio@50004000 { + status = "okay"; + ngpios = <16>; + gpio-ranges = <&pinctrl 0 32 16>; + }; + + gpiod: gpio@50005000 { + status = "okay"; + ngpios = <16>; + gpio-ranges = <&pinctrl 0 48 16>; + }; + + gpioe: gpio@50006000 { + status = "okay"; + ngpios = <16>; + gpio-ranges = <&pinctrl 0 64 16>; + }; + + gpiof: gpio@50007000 { + status = "okay"; + ngpios = <16>; + gpio-ranges = <&pinctrl 0 80 16>; + }; + + gpiog: gpio@50008000 { + status = "okay"; + ngpios = <16>; + gpio-ranges = <&pinctrl 0 96 16>; + }; + + gpioh: gpio@50009000 { + status = "okay"; + ngpios = <16>; + gpio-ranges = <&pinctrl 0 112 16>; + }; + + gpioi: gpio@5000a000 { + status = "okay"; + ngpios = <12>; + gpio-ranges = <&pinctrl 0 128 12>; + }; +}; + +&pinctrl_z { + st,package = ; + + gpioz: gpio@54004000 { + status = "okay"; + ngpios = <8>; + gpio-ranges = <&pinctrl_z 0 400 8>; + }; +}; diff --git a/fdts/stm32mp15xxad-pinctrl.dtsi b/fdts/stm32mp15xxad-pinctrl.dtsi new file mode 100644 index 000000000..023f5404c --- /dev/null +++ b/fdts/stm32mp15xxad-pinctrl.dtsi @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved + * Author: Alexandre Torgue + */ + +&pinctrl { + st,package = ; + + gpioa: gpio@50002000 { + status = "okay"; + ngpios = <16>; + gpio-ranges = <&pinctrl 0 0 16>; + }; + + gpiob: gpio@50003000 { + status = "okay"; + ngpios = <16>; + gpio-ranges = <&pinctrl 0 16 16>; + }; + + gpioc: gpio@50004000 { + status = "okay"; + ngpios = <16>; + gpio-ranges = <&pinctrl 0 32 16>; + }; + + gpiod: gpio@50005000 { + status = "okay"; + ngpios = <16>; + gpio-ranges = <&pinctrl 0 48 16>; + }; + + gpioe: gpio@50006000 { + status = "okay"; + ngpios = <16>; + gpio-ranges = <&pinctrl 0 64 16>; + }; + + gpiof: gpio@50007000 { + status = "okay"; + ngpios = <6>; + gpio-ranges = <&pinctrl 6 86 6>; + }; + + gpiog: gpio@50008000 { + status = "okay"; + ngpios = <10>; + gpio-ranges = <&pinctrl 6 102 10>; + }; + + gpioh: gpio@50009000 { + status = "okay"; + ngpios = <2>; + gpio-ranges = <&pinctrl 0 112 2>; + }; +}; diff --git a/include/dt-bindings/pinctrl/stm32-pinfunc.h b/include/dt-bindings/pinctrl/stm32-pinfunc.h index 7f6e4b94d..1bc2c40fc 100644 --- a/include/dt-bindings/pinctrl/stm32-pinfunc.h +++ b/include/dt-bindings/pinctrl/stm32-pinfunc.h @@ -26,6 +26,7 @@ #define AF14 0xf #define AF15 0x10 #define ANALOG 0x11 +#define RSVD 0x12 /* define Pins number*/ #define PIN_NO(port, line) (((port) - 'A') * 0x10 + (line)) @@ -33,9 +34,9 @@ #define STM32_PINMUX(port, line, mode) (((PIN_NO(port, line)) << 8) | (mode)) /* package information */ -#define STM32MP157CAA 0x1 -#define STM32MP157CAB 0x2 -#define STM32MP157CAC 0x4 -#define STM32MP157CAD 0x8 +#define STM32MP_PKG_AA 0x1 +#define STM32MP_PKG_AB 0x2 +#define STM32MP_PKG_AC 0x4 +#define STM32MP_PKG_AD 0x8 #endif /* _DT_BINDINGS_STM32_PINFUNC_H */ diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h index ea18a3031..369ba6921 100644 --- a/plat/st/stm32mp1/stm32mp1_def.h +++ b/plat/st/stm32mp1/stm32mp1_def.h @@ -513,7 +513,7 @@ static inline uint32_t tamp_bkpr(uint32_t idx) ******************************************************************************/ #define DT_BSEC_COMPAT "st,stm32mp15-bsec" #define DT_IWDG_COMPAT "st,stm32mp1-iwdg" -#define DT_PWR_COMPAT "st,stm32mp1-pwr" +#define DT_PWR_COMPAT "st,stm32mp1,pwr-reg" #define DT_RCC_CLK_COMPAT "st,stm32mp1-rcc" #define DT_SYSCFG_COMPAT "st,stm32mp157-syscfg" -- cgit v1.2.3 From 662c1f5c17d144f1228b97a551a4ff5370a11e64 Mon Sep 17 00:00:00 2001 From: Lionel Debieve Date: Fri, 31 Jan 2020 16:17:37 +0100 Subject: crypto: stm32_hash: fix issue when restarting computation While restarting a new hash computation, STR register is not cleared. It needs to be written before each computation. Change-Id: If65902dd21f9c139ec5da3ca87721232f73710db Signed-off-by: Lionel Debieve Signed-off-by: Yann Gautier --- drivers/st/crypto/stm32_hash.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/st/crypto/stm32_hash.c b/drivers/st/crypto/stm32_hash.c index 515947c10..317fd9eb8 100644 --- a/drivers/st/crypto/stm32_hash.c +++ b/drivers/st/crypto/stm32_hash.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, STMicroelectronics - All Rights Reserved + * Copyright (c) 2019-2020, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ @@ -252,6 +252,8 @@ int stm32_hash_final(uint8_t *digest) mmio_clrsetbits_32(hash_base() + HASH_STR, HASH_STR_NBLW_MASK, 8U * stm32_remain.length); zeromem(&stm32_remain, sizeof(stm32_remain)); + } else { + mmio_clrbits_32(hash_base() + HASH_STR, HASH_STR_NBLW_MASK); } mmio_setbits_32(hash_base() + HASH_STR, HASH_STR_DCAL); -- cgit v1.2.3 From 769a9904288266181450fc6071f7fab4dbd39d94 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Fri, 4 Sep 2020 13:25:27 +0200 Subject: gpio: stm32_gpio: check GPIO node status after checking DT The call to fdt_get_status(node) has to be done after the DT is found to be valid. Fixes: 1fc2130c5 stm32mp1: update device tree and gpio functions Change-Id: I70f803aae3dde128a9e740f54c8837b64cb1a244 Signed-off-by: Yann Gautier --- drivers/st/gpio/stm32_gpio.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/st/gpio/stm32_gpio.c b/drivers/st/gpio/stm32_gpio.c index bb77371bf..7d63262d7 100644 --- a/drivers/st/gpio/stm32_gpio.c +++ b/drivers/st/gpio/stm32_gpio.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved + * Copyright (c) 2016-2020, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ @@ -161,13 +161,14 @@ int dt_set_pinctrl_config(int node) const fdt32_t *cuint; int lenp = 0; uint32_t i; - uint8_t status = fdt_get_status(node); + uint8_t status; void *fdt; if (fdt_get_address(&fdt) == 0) { return -FDT_ERR_NOTFOUND; } + status = fdt_get_status(node); if (status == DT_DISABLED) { return -FDT_ERR_NOTFOUND; } -- cgit v1.2.3 From 6751b83652c1604a77aee9348a240656658d0102 Mon Sep 17 00:00:00 2001 From: Lionel Debieve Date: Mon, 27 Apr 2020 09:50:48 +0200 Subject: mtd: spi_nor: change message level on macronix detection Change the detection message from WARN to INFO when macronix NOR is detected. Change-Id: I488696f1fb75b823e85decfcd6cd32e7b36a6c2e Signed-off-by: Lionel Debieve Signed-off-by: Yann Gautier --- drivers/mtd/nor/spi_nor.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/nor/spi_nor.c b/drivers/mtd/nor/spi_nor.c index 22d3ae3d9..108f893d3 100644 --- a/drivers/mtd/nor/spi_nor.c +++ b/drivers/mtd/nor/spi_nor.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, STMicroelectronics - All Rights Reserved + * Copyright (c) 2019-2020, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ @@ -368,7 +368,7 @@ int spi_nor_init(unsigned long long *size, unsigned int *erase_size) if (nor_dev.read_op.data.buswidth == 4U) { switch (id) { case MACRONIX_ID: - WARN("Enable Macronix quad support\n"); + INFO("Enable Macronix quad support\n"); ret = spi_nor_macronix_quad_enable(); break; case MICRON_ID: -- cgit v1.2.3 From ea306945614b88f993947e6fbd77e2cd5f575879 Mon Sep 17 00:00:00 2001 From: Lionel Debieve Date: Wed, 26 Aug 2020 16:17:02 +0200 Subject: nand: raw_nand: fix timeout issue in nand_wait_ready nand_wait_ready is called with a millisecond delay but the timeout used a micro second. Fixing the conversion in the timeout call. The prototype of the function is also changed to use an unsigned int parameter. Change-Id: Ia3281be7980477dfbfdb842308d35ecd8b926fb8 Signed-off-by: Lionel Debieve Signed-off-by: Yann Gautier --- drivers/mtd/nand/raw_nand.c | 6 +++--- include/drivers/raw_nand.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/nand/raw_nand.c b/drivers/mtd/nand/raw_nand.c index 48131fcb2..1fb5facaf 100644 --- a/drivers/mtd/nand/raw_nand.c +++ b/drivers/mtd/nand/raw_nand.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, STMicroelectronics - All Rights Reserved + * Copyright (c) 2019-2020, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ @@ -190,7 +190,7 @@ static int nand_status(uint8_t *status) return ret; } -int nand_wait_ready(unsigned long delay) +int nand_wait_ready(unsigned int delay_ms) { uint8_t status; int ret; @@ -204,7 +204,7 @@ int nand_wait_ready(unsigned long delay) return ret; } - timeout = timeout_init_us(delay); + timeout = timeout_init_us(delay_ms * 1000U); while (!timeout_elapsed(timeout)) { ret = nand_read_data(&status, 1U, true); if (ret != 0) { diff --git a/include/drivers/raw_nand.h b/include/drivers/raw_nand.h index 9018f0242..715230094 100644 --- a/include/drivers/raw_nand.h +++ b/include/drivers/raw_nand.h @@ -169,7 +169,7 @@ struct rawnand_device { }; int nand_raw_init(unsigned long long *size, unsigned int *erase_size); -int nand_wait_ready(unsigned long delay); +int nand_wait_ready(unsigned int delay_ms); int nand_read_page_cmd(unsigned int page, unsigned int offset, uintptr_t buffer, unsigned int len); int nand_change_read_column_cmd(unsigned int offset, uintptr_t buffer, -- cgit v1.2.3 From 7d8e1218c28ec9c549b05e09210f72059d425012 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Fri, 12 Jun 2020 12:17:17 +0200 Subject: mmc: st: correct retries management The retries number should be 3. A warning message is added in mmc_block_read(), and the code is refactored. Change-Id: I577c7dd91c451c7580b1660042cb5fe26ee3fa12 Signed-off-by: Yann Gautier --- drivers/st/io/io_mmc.c | 21 ++++++++++++++------- drivers/st/mmc/stm32_sdmmc2.c | 18 +++++++++--------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/drivers/st/io/io_mmc.c b/drivers/st/io/io_mmc.c index 44b7d1907..0ed71540c 100644 --- a/drivers/st/io/io_mmc.c +++ b/drivers/st/io/io_mmc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -97,14 +97,21 @@ static int mmc_block_seek(io_entity_t *entity, int mode, static int mmc_block_read(io_entity_t *entity, uintptr_t buffer, size_t length, size_t *length_read) { - *length_read = mmc_read_blocks(seek_offset / MMC_BLOCK_SIZE, - buffer, length); - - if (*length_read != length) { - return -EIO; + uint8_t retries; + + for (retries = 0U; retries < 3U; retries++) { + *length_read = mmc_read_blocks(seek_offset / MMC_BLOCK_SIZE, + buffer, length); + + if (*length_read == length) { + return 0; + } + WARN("%s: length_read = %lu (!= %lu), retry %u\n", __func__, + (unsigned long)*length_read, (unsigned long)length, + retries + 1U); } - return 0; + return -EIO; } /* Close a file on the mmc device */ diff --git a/drivers/st/mmc/stm32_sdmmc2.c b/drivers/st/mmc/stm32_sdmmc2.c index 63fbb0747..2a8a4afc6 100644 --- a/drivers/st/mmc/stm32_sdmmc2.c +++ b/drivers/st/mmc/stm32_sdmmc2.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, STMicroelectronics - All Rights Reserved + * Copyright (c) 2018-2020, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ @@ -373,15 +373,15 @@ err_exit: static int stm32_sdmmc2_send_cmd(struct mmc_cmd *cmd) { - int8_t retry; - int err = 0; + uint8_t retry; + int err; assert(cmd != NULL); - for (retry = 0; retry <= 3; retry++) { + for (retry = 0U; retry < 3U; retry++) { err = stm32_sdmmc2_send_cmd_req(cmd); if (err == 0) { - return err; + return 0; } if ((cmd->cmd_idx == MMC_CMD(1)) || @@ -390,12 +390,12 @@ static int stm32_sdmmc2_send_cmd(struct mmc_cmd *cmd) } /* Command 8 is expected to fail for eMMC */ - if (!(cmd->cmd_idx == MMC_CMD(8))) { - WARN(" CMD%d, Retry: %d, Error: %d\n", - cmd->cmd_idx, retry, err); + if (cmd->cmd_idx != MMC_CMD(8)) { + WARN(" CMD%u, Retry: %u, Error: %d\n", + cmd->cmd_idx, retry + 1U, err); } - udelay(10); + udelay(10U); } return err; -- cgit v1.2.3 From 54019a35b817976793903f0030108148631aaace Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Fri, 12 Jun 2020 14:14:26 +0200 Subject: mmc: st: clear some flags before sending a command The ICR static flags are cleared before sending a command. The SDMMC_DCTRLR register is set to 0 if no data is expected on a given command or on the next command in case of CMD55. Change-Id: I5ae172a484218f53160e98b3684967c6960475a6 Signed-off-by: Yann Gautier --- drivers/st/mmc/stm32_sdmmc2.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/st/mmc/stm32_sdmmc2.c b/drivers/st/mmc/stm32_sdmmc2.c index 2a8a4afc6..cff3a344f 100644 --- a/drivers/st/mmc/stm32_sdmmc2.c +++ b/drivers/st/mmc/stm32_sdmmc2.c @@ -258,6 +258,18 @@ static int stm32_sdmmc2_send_cmd_req(struct mmc_cmd *cmd) break; } + mmio_write_32(base + SDMMC_ICR, SDMMC_STATIC_FLAGS); + + /* + * Clear the SDMMC_DCTRLR if the command does not await data. + * Skip CMD55 as the next command could be data related, and + * the register could have been set in prepare function. + */ + if (((cmd_reg & SDMMC_CMDR_CMDTRANS) == 0U) && + (cmd->cmd_idx != MMC_CMD(55))) { + mmio_write_32(base + SDMMC_DCTRLR, 0U); + } + if ((cmd->resp_type & MMC_RSP_BUSY) != 0U) { mmio_write_32(base + SDMMC_DTIMER, UINT32_MAX); } -- cgit v1.2.3 From 0adc87c75d3c8b67d70008af39ba256a68ae00f8 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Mon, 7 Sep 2020 13:46:04 +0200 Subject: drivers: st: add missing includes in ETZPC header Depending on compiler, the issue about bool or uint*_t not defined can appear. Correct this by adding stdbool.h and stdint.h includes in etzpc.h. Change-Id: If1419dc511efbe682459fa4a776481fa52a38aa3 Signed-off-by: Yann Gautier --- include/drivers/st/etzpc.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/drivers/st/etzpc.h b/include/drivers/st/etzpc.h index 6e3fec1ea..4cd2b4e0b 100644 --- a/include/drivers/st/etzpc.h +++ b/include/drivers/st/etzpc.h @@ -7,6 +7,9 @@ #ifndef DRIVERS_ST_ETZPC_H #define DRIVERS_ST_ETZPC_H +#include +#include + /* Define security level for each peripheral (DECPROT) */ enum etzpc_decprot_attributes { ETZPC_DECPROT_S_RW = 0, -- cgit v1.2.3 From 1bb9072ab46993d8c04c119250dfabbf945cfe72 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Wed, 5 Feb 2020 10:03:27 +0100 Subject: clk: stm32mp1: fix rcc mckprot status MCKPROT hardening in RCC mandates that both bits RCC[TZEN] and RCC[MCKPROT] are enabled. This change fixes stm32mp1_rcc_is_mckprot() to check both bits, not RCC[MCKPROT] only. This change also updates stm32mp1_rcc_is_secure() for consistency. Change-Id: If1f07babdcb5677906ddbf974d9dc17255d4e174 Signed-off-by: Etienne Carriere Signed-off-by: Yann Gautier --- drivers/st/clk/stm32mp1_clk.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c index d6cd8b1ce..f8bc5a217 100644 --- a/drivers/st/clk/stm32mp1_clk.c +++ b/drivers/st/clk/stm32mp1_clk.c @@ -653,15 +653,17 @@ static void stm32mp1_clk_unlock(struct spinlock *lock) bool stm32mp1_rcc_is_secure(void) { uintptr_t rcc_base = stm32mp_rcc_base(); + uint32_t mask = RCC_TZCR_TZEN; - return (mmio_read_32(rcc_base + RCC_TZCR) & RCC_TZCR_TZEN) != 0; + return (mmio_read_32(rcc_base + RCC_TZCR) & mask) == mask; } bool stm32mp1_rcc_is_mckprot(void) { uintptr_t rcc_base = stm32mp_rcc_base(); + uint32_t mask = RCC_TZCR_TZEN | RCC_TZCR_MCKPROT; - return (mmio_read_32(rcc_base + RCC_TZCR) & RCC_TZCR_MCKPROT) != 0; + return (mmio_read_32(rcc_base + RCC_TZCR) & mask) == mask; } void stm32mp1_clk_rcc_regs_lock(void) -- cgit v1.2.3 From 16796a25fefc4ecf780211bf554d3b8dc5436fa4 Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Tue, 18 Aug 2020 12:30:37 +0100 Subject: plat: tc0: enable TZC Change-Id: Ic2bb8482f0b602f6b7850d4fa553448bc4931edc Signed-off-by: Usama Arif --- plat/arm/board/tc0/include/platform_def.h | 17 ++++++++++++++++- plat/arm/board/tc0/platform.mk | 4 +++- plat/arm/board/tc0/tc0_security.c | 13 ++++++++++++- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/plat/arm/board/tc0/include/platform_def.h b/plat/arm/board/tc0/include/platform_def.h index a8d471ee3..075c4037b 100644 --- a/plat/arm/board/tc0/include/platform_def.h +++ b/plat/arm/board/tc0/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -191,4 +191,19 @@ */ #define PLAT_CSS_MAX_SCP_BL2U_SIZE 0x20000 +/* TZC Related Constants */ +#define PLAT_ARM_TZC_BASE UL(0x25000000) +#define PLAT_ARM_TZC_FILTERS TZC_400_REGION_ATTR_FILTER_BIT(0) + +#define TZC400_OFFSET UL(0x1000000) +#define TZC400_COUNT 4 + +#define TZC400_BASE(n) (PLAT_ARM_TZC_BASE + \ + (n * TZC400_OFFSET)) + +#define TZC_NSAID_DEFAULT U(0) + +#define PLAT_ARM_TZC_NS_DEV_ACCESS \ + (TZC_REGION_ACCESS_RDWR(TZC_NSAID_DEFAULT)) + #endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/tc0/platform.mk b/plat/arm/board/tc0/platform.mk index 903fabfb0..05d691ee2 100644 --- a/plat/arm/board/tc0/platform.mk +++ b/plat/arm/board/tc0/platform.mk @@ -1,4 +1,4 @@ -# Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2020, Arm Limited. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -61,6 +61,8 @@ BL2_SOURCES += ${TC0_BASE}/tc0_security.c \ ${TC0_BASE}/tc0_err.c \ ${TC0_BASE}/tc0_trusted_boot.c \ lib/utils/mem_region.c \ + drivers/arm/tzc/tzc400.c \ + plat/arm/common/arm_tzc400.c \ plat/arm/common/arm_nor_psci_mem_protect.c BL31_SOURCES += ${INTERCONNECT_SOURCES} \ diff --git a/plat/arm/board/tc0/tc0_security.c b/plat/arm/board/tc0/tc0_security.c index 6aa38c822..5f1cb1159 100644 --- a/plat/arm/board/tc0/tc0_security.c +++ b/plat/arm/board/tc0/tc0_security.c @@ -1,12 +1,23 @@ /* - * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ +#include #include +static const arm_tzc_regions_info_t tzc_regions[] = { + ARM_TZC_REGIONS_DEF, + {} +}; + /* Initialize the secure environment */ void plat_arm_security_setup(void) { + unsigned int i; + + for (i = 0U; i < TZC400_COUNT; i++) { + arm_tzc400_setup(TZC400_BASE(i), tzc_regions); + } } -- cgit v1.2.3 From 7c15a8c14fe3e971839b8a62206a5f15b9b27c53 Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Thu, 30 Apr 2020 15:50:34 +0100 Subject: plat/arm/css/sgi: Map flash used for mem_protect The SGI platform defines the macro PLAT_ARM_MEM_PROT_ADDR which indicates that the platform has mitigation for cold reboot attacks. However, the flash memory used for the mem_protect region was not mapped. This results in a crash when an OS calls PSCI MEM_PROTECT. To fix this map the flash region used for mem_protect. Change-Id: Ia494f924ecfe2ce835c045689ba8f942bf0941f4 Signed-off-by: Sami Mujawar --- plat/arm/css/sgi/include/sgi_base_platform_def.h | 4 ++-- plat/arm/css/sgi/sgi_plat.c | 8 +++++++- 2 files changed, 9 insertions(+), 3 deletions(-) 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 14cdb7e76..159084f95 100644 --- a/plat/arm/css/sgi/include/sgi_base_platform_def.h +++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -39,7 +39,7 @@ # define PLAT_SP_IMAGE_MAX_XLAT_TABLES 10 # else # define PLAT_ARM_MMAP_ENTRIES (5 + ((CSS_SGI_CHIP_COUNT - 1) * 3)) -# define MAX_XLAT_TABLES (5 + ((CSS_SGI_CHIP_COUNT - 1) * 3)) +# define MAX_XLAT_TABLES (6 + ((CSS_SGI_CHIP_COUNT - 1) * 3)) # endif #elif defined(IMAGE_BL32) # define PLAT_ARM_MMAP_ENTRIES 8 diff --git a/plat/arm/css/sgi/sgi_plat.c b/plat/arm/css/sgi/sgi_plat.c index a2117f6c1..39eb89eb8 100644 --- a/plat/arm/css/sgi/sgi_plat.c +++ b/plat/arm/css/sgi/sgi_plat.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -43,6 +43,9 @@ const mmap_region_t plat_arm_mmap[] = { const mmap_region_t plat_arm_mmap[] = { ARM_MAP_SHARED_RAM, SGI_MAP_FLASH0_RO, +#ifdef PLAT_ARM_MEM_PROT_ADDR + ARM_V2M_MAP_MEM_PROTECT, +#endif CSS_SGI_MAP_DEVICE, SOC_CSS_MAP_DEVICE, ARM_MAP_NS_DRAM1, @@ -63,6 +66,9 @@ const mmap_region_t plat_arm_mmap[] = { ARM_MAP_SHARED_RAM, V2M_MAP_IOFPGA, CSS_SGI_MAP_DEVICE, +#ifdef PLAT_ARM_MEM_PROT_ADDR + ARM_V2M_MAP_MEM_PROTECT, +#endif SOC_CSS_MAP_DEVICE, #if SPM_MM ARM_SPM_BUF_EL3_MMAP, -- cgit v1.2.3 From 74f72b1347a6e5f8cdb682010d9b77304aa4831b Mon Sep 17 00:00:00 2001 From: Greta Zhang Date: Tue, 9 Jun 2020 13:38:35 +0800 Subject: mediatek: mt8192: add GIC600 support 1. Implement GIC600 driver support and init 2. Remove unused debug info Signed-off-by: Greta Zhang Change-Id: I30c08c531e705debc029071e4e970048e261c386 --- plat/mediatek/mt8192/bl31_plat_setup.c | 4 + plat/mediatek/mt8192/include/mt_gic_v3.h | 24 ++++ plat/mediatek/mt8192/include/plat_macros.S | 4 +- plat/mediatek/mt8192/include/platform_def.h | 8 ++ plat/mediatek/mt8192/plat_mt_gic.c | 177 ++++++++++++++++++++++++++++ plat/mediatek/mt8192/platform.mk | 4 +- 6 files changed, 218 insertions(+), 3 deletions(-) create mode 100644 plat/mediatek/mt8192/include/mt_gic_v3.h create mode 100644 plat/mediatek/mt8192/plat_mt_gic.c diff --git a/plat/mediatek/mt8192/bl31_plat_setup.c b/plat/mediatek/mt8192/bl31_plat_setup.c index 4378c5a12..f96528196 100644 --- a/plat/mediatek/mt8192/bl31_plat_setup.c +++ b/plat/mediatek/mt8192/bl31_plat_setup.c @@ -15,6 +15,7 @@ #include /* Platform Includes */ +#include #include #include @@ -79,6 +80,9 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, ******************************************************************************/ void bl31_platform_setup(void) { + /* Initialize the GIC driver, CPU and distributor interfaces */ + mt_gic_driver_init(); + mt_gic_init(); } /******************************************************************************* diff --git a/plat/mediatek/mt8192/include/mt_gic_v3.h b/plat/mediatek/mt8192/include/mt_gic_v3.h new file mode 100644 index 000000000..34ba8a7e3 --- /dev/null +++ b/plat/mediatek/mt8192/include/mt_gic_v3.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MT_GIC_V3_H +#define MT_GIC_V3_H + +#include +#include + +void mt_gic_driver_init(void); +void mt_gic_init(void); +void mt_gic_set_pending(uint32_t irq); +void mt_gic_distif_save(void); +void mt_gic_distif_restore(void); +void mt_gic_rdistif_init(void); +void mt_gic_rdistif_save(void); +void mt_gic_rdistif_restore(void); +void mt_gic_rdistif_restore_all(void); +void gic_sgi_save_all(void); +void gic_sgi_restore_all(void); +#endif /* MT_GIC_V3_H */ diff --git a/plat/mediatek/mt8192/include/plat_macros.S b/plat/mediatek/mt8192/include/plat_macros.S index 92cda0775..7d17e360a 100644 --- a/plat/mediatek/mt8192/include/plat_macros.S +++ b/plat/mediatek/mt8192/include/plat_macros.S @@ -24,8 +24,8 @@ cci_iface_regs: .asciz "cci_snoop_ctrl_cluster0", "cci_snoop_ctrl_cluster1" , "" /* --------------------------------------------- - * The below macro prints out relevant GIC and - * CCI registers whenever an unhandled exception + * The below macro prints out relevant GIC + * registers whenever an unhandled exception * is taken in BL31. * Clobbers: x0 - x10, x26, x27, sp * --------------------------------------------- diff --git a/plat/mediatek/mt8192/include/platform_def.h b/plat/mediatek/mt8192/include/platform_def.h index f68015a97..5ff013ecc 100644 --- a/plat/mediatek/mt8192/include/platform_def.h +++ b/plat/mediatek/mt8192/include/platform_def.h @@ -38,6 +38,14 @@ #define SYS_COUNTER_FREQ_IN_TICKS 13000000 #define SYS_COUNTER_FREQ_IN_MHZ 13 +/******************************************************************************* + * GIC-400 & interrupt handling related constants + ******************************************************************************/ + +/* Base MTK_platform compatible GIC memory map */ +#define BASE_GICD_BASE MT_GIC_BASE +#define MT_GIC_RDIST_BASE (MT_GIC_BASE + 0x40000) + /******************************************************************************* * Platform binary types for linking ******************************************************************************/ diff --git a/plat/mediatek/mt8192/plat_mt_gic.c b/plat/mediatek/mt8192/plat_mt_gic.c new file mode 100644 index 000000000..593f5d04e --- /dev/null +++ b/plat/mediatek/mt8192/plat_mt_gic.c @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include "../drivers/arm/gic/v3/gicv3_private.h" +#include +#include +#include + +#include +#include +#include +#include +#include + +#define SGI_MASK 0xffff + +uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT]; +static uint32_t rdist_has_saved[PLATFORM_CORE_COUNT]; + +/* we save and restore the GICv3 context on system suspend */ +gicv3_dist_ctx_t dist_ctx; + +static unsigned int mt_mpidr_to_core_pos(u_register_t mpidr) +{ + return plat_core_pos_by_mpidr(mpidr); +} + +gicv3_driver_data_t mt_gicv3_data = { + .gicd_base = MT_GIC_BASE, + .gicr_base = MT_GIC_RDIST_BASE, + .rdistif_num = PLATFORM_CORE_COUNT, + .rdistif_base_addrs = rdistif_base_addrs, + .mpidr_to_core_pos = mt_mpidr_to_core_pos, +}; + +struct gic_chip_data { + /* All cores share the same configuration */ + unsigned int saved_group; + unsigned int saved_enable; + unsigned int saved_conf0; + unsigned int saved_conf1; + unsigned int saved_grpmod; + /* Per-core sgi */ + unsigned int saved_sgi[PLATFORM_CORE_COUNT]; +}; + +static struct gic_chip_data gic_data; + +void mt_gic_driver_init(void) +{ + gicv3_driver_init(&mt_gicv3_data); +} + +void mt_gic_set_pending(uint32_t irq) +{ + gicv3_set_interrupt_pending(irq, plat_my_core_pos()); +} + +void mt_gic_distif_save(void) +{ + gicv3_distif_save(&dist_ctx); +} + +void mt_gic_distif_restore(void) +{ + gicv3_distif_init_restore(&dist_ctx); +} + +void mt_gic_rdistif_init(void) +{ + unsigned int proc_num; + unsigned int index; + uintptr_t gicr_base; + + proc_num = plat_my_core_pos(); + gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; + + /* set all SGI/PPI as non-secure GROUP1 by default */ + mmio_write_32(gicr_base + GICR_IGROUPR0, ~0U); + mmio_write_32(gicr_base + GICR_IGRPMODR0, 0x0); + + /* setup the default PPI/SGI priorities */ + for (index = 0; index < TOTAL_PCPU_INTR_NUM; index += 4U) + gicr_write_ipriorityr(gicr_base, index, + GICD_IPRIORITYR_DEF_VAL); +} + +void mt_gic_rdistif_save(void) +{ + unsigned int proc_num; + uintptr_t gicr_base; + + proc_num = plat_my_core_pos(); + gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; + + gic_data.saved_group = mmio_read_32(gicr_base + GICR_IGROUPR0); + gic_data.saved_enable = mmio_read_32(gicr_base + GICR_ISENABLER0); + gic_data.saved_conf0 = mmio_read_32(gicr_base + GICR_ICFGR0); + gic_data.saved_conf1 = mmio_read_32(gicr_base + GICR_ICFGR1); + gic_data.saved_grpmod = mmio_read_32(gicr_base + GICR_IGRPMODR0); + + rdist_has_saved[proc_num] = 1; +} + +void mt_gic_rdistif_restore(void) +{ + unsigned int proc_num; + uintptr_t gicr_base; + + proc_num = plat_my_core_pos(); + if (rdist_has_saved[proc_num] == 1) { + gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; + mmio_write_32(gicr_base + GICR_IGROUPR0, gic_data.saved_group); + mmio_write_32(gicr_base + GICR_ISENABLER0, + gic_data.saved_enable); + mmio_write_32(gicr_base + GICR_ICFGR0, gic_data.saved_conf0); + mmio_write_32(gicr_base + GICR_ICFGR1, gic_data.saved_conf1); + mmio_write_32(gicr_base + GICR_IGRPMODR0, + gic_data.saved_grpmod); + } +} + +void mt_gic_rdistif_restore_all(void) +{ + unsigned int proc_num; + uintptr_t gicr_base; + + for (proc_num = 0; proc_num < PLATFORM_CORE_COUNT; proc_num++) { + gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; + mmio_write_32(gicr_base + GICR_IGROUPR0, gic_data.saved_group); + mmio_write_32(gicr_base + GICR_ISENABLER0, + gic_data.saved_enable); + mmio_write_32(gicr_base + GICR_ICFGR0, gic_data.saved_conf0); + mmio_write_32(gicr_base + GICR_ICFGR1, gic_data.saved_conf1); + mmio_write_32(gicr_base + GICR_IGRPMODR0, + gic_data.saved_grpmod); + } +} + +void gic_sgi_save_all(void) +{ + unsigned int proc_num; + uintptr_t gicr_base; + + for (proc_num = 0; proc_num < PLATFORM_CORE_COUNT; proc_num++) { + gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; + gic_data.saved_sgi[proc_num] = + mmio_read_32(gicr_base + GICR_ISPENDR0) & SGI_MASK; + } +} + +void gic_sgi_restore_all(void) +{ + unsigned int proc_num; + uintptr_t gicr_base; + + for (proc_num = 0; proc_num < PLATFORM_CORE_COUNT; proc_num++) { + gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; + mmio_write_32(gicr_base + GICR_ICPENDR0, SGI_MASK); + mmio_write_32(gicr_base + GICR_ISPENDR0, + gic_data.saved_sgi[proc_num] & SGI_MASK); + } +} + +void mt_gic_init(void) +{ + gicv3_distif_init(); + gicv3_rdistif_init(plat_my_core_pos()); + gicv3_cpuif_enable(plat_my_core_pos()); +} diff --git a/plat/mediatek/mt8192/platform.mk b/plat/mediatek/mt8192/platform.mk index f4ee7e7f4..c972ac61d 100644 --- a/plat/mediatek/mt8192/platform.mk +++ b/plat/mediatek/mt8192/platform.mk @@ -10,6 +10,7 @@ MTK_PLAT_SOC := ${MTK_PLAT}/${PLAT} PLAT_INCLUDES := -I${MTK_PLAT}/common/ \ -I${MTK_PLAT_SOC}/include/ +GICV3_SUPPORT_GIC600 := 1 include drivers/arm/gic/v3/gicv3.mk include lib/xlat_tables_v2/xlat_tables.mk @@ -30,7 +31,8 @@ BL31_SOURCES += common/desc_image_load.c \ ${MTK_PLAT_SOC}/aarch64/plat_helpers.S \ ${MTK_PLAT_SOC}/bl31_plat_setup.c \ ${MTK_PLAT_SOC}/plat_pm.c \ - ${MTK_PLAT_SOC}/plat_topology.c + ${MTK_PLAT_SOC}/plat_topology.c \ + ${MTK_PLAT_SOC}/plat_mt_gic.c # Configs for A76 and A55 -- cgit v1.2.3 From 1994e56221f06b47b3b38fba0a148ea505c940cd Mon Sep 17 00:00:00 2001 From: Javier Almansa Sobrino Date: Thu, 20 Aug 2020 18:48:09 +0100 Subject: arm_fpga: Add support for unknown MPIDs This patch allows the system to fallback to a default CPU library in case the MPID does not match with any of the supported ones. This feature can be enabled by setting SUPPORT_UNKNOWN_MPID build option to 1 (enabled by default only on arm_fpga platform). This feature can be very dangerous on a production image and therefore it MUST be disabled for Release images. Signed-off-by: Javier Almansa Sobrino Change-Id: I0df7ef2b012d7d60a4fd5de44dea1fbbb46881ba --- bl31/bl31.mk | 6 +++ bl31/bl31_main.c | 17 ++++++- include/lib/cpus/aarch64/generic.h | 18 ++++++++ lib/cpus/aarch64/cpu_helpers.S | 50 ++++++++++++++++----- lib/cpus/aarch64/generic.S | 89 +++++++++++++++++++++++++++++++++++++ plat/arm/board/arm_fpga/platform.mk | 10 ++++- 6 files changed, 178 insertions(+), 12 deletions(-) create mode 100644 include/lib/cpus/aarch64/generic.h create mode 100644 lib/cpus/aarch64/generic.S diff --git a/bl31/bl31.mk b/bl31/bl31.mk index 735d1fcfc..cd6549bff 100644 --- a/bl31/bl31.mk +++ b/bl31/bl31.mk @@ -7,6 +7,12 @@ ################################################################################ # Include Makefile for the SPM-MM implementation ################################################################################ +ifeq (${SUPPORT_UNKNOWN_MPID},1) + ifeq (${DEBUG},0) + $(warning WARNING: SUPPORT_UNKNOWN_MPID enabled) + endif +endif + ifeq (${SPM_MM},1) ifeq (${EL3_EXCEPTION_HANDLING},0) $(error EL3_EXCEPTION_HANDLING must be 1 for SPM-MM support) diff --git a/bl31/bl31_main.c b/bl31/bl31_main.c index 92a2027dd..44bf32cb7 100644 --- a/bl31/bl31_main.c +++ b/bl31/bl31_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -41,6 +41,15 @@ static int32_t (*bl32_init)(void); ******************************************************************************/ static uint32_t next_image_type = NON_SECURE; +#ifdef SUPPORT_UNKNOWN_MPID +/* + * Flag to know whether an unsupported MPID has been detected. To avoid having it + * landing on the .bss section, it is initialized to a non-zero value, this way + * we avoid potential WAW hazards during system bring up. + * */ +volatile uint32_t unsupported_mpid_flag = 1; +#endif + /* * Implement the ARM Standard Service function to get arguments for a * particular service. @@ -98,6 +107,12 @@ void bl31_main(void) NOTICE("BL31: %s\n", version_string); NOTICE("BL31: %s\n", build_message); +#ifdef SUPPORT_UNKNOWN_MPID + if (unsupported_mpid_flag == 0) { + NOTICE("Unsupported MPID detected!\n"); + } +#endif + /* Perform platform setup in BL31 */ bl31_platform_setup(); diff --git a/include/lib/cpus/aarch64/generic.h b/include/lib/cpus/aarch64/generic.h new file mode 100644 index 000000000..53df58761 --- /dev/null +++ b/include/lib/cpus/aarch64/generic.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserverd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef AARCH64_GENERIC_H +#define AARCH64_GENERIC_H + +#include + +/* + * 0x0 value on the MIDR implementer value is reserved for software use, + * so use an MIDR value of 0 for a default CPU library. + */ +#define AARCH64_GENERIC_MIDR U(0) + +#endif /* AARCH64_GENERIC_H */ diff --git a/lib/cpus/aarch64/cpu_helpers.S b/lib/cpus/aarch64/cpu_helpers.S index da663be0e..730b09beb 100644 --- a/lib/cpus/aarch64/cpu_helpers.S +++ b/lib/cpus/aarch64/cpu_helpers.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -140,6 +140,13 @@ endfunc do_cpu_reg_dump * midr of the core. It reads the MIDR_EL1 and finds the matching * entry in cpu_ops entries. Only the implementation and part number * are used to match the entries. + * + * If cpu_ops for the MIDR_EL1 cannot be found and + * SUPPORT_UNKNOWN_MPID is enabled, it will try to look for a + * default cpu_ops with an MIDR value of 0. + * (Implementation number 0x0 should be reseverd for software use + * and therefore no clashes should happen with that default value). + * * Return : * x0 - The matching cpu_ops pointer on Success * x0 - 0 on failure. @@ -147,23 +154,26 @@ endfunc do_cpu_reg_dump */ .globl get_cpu_ops_ptr func get_cpu_ops_ptr - /* Get the cpu_ops start and end locations */ - adr x4, (__CPU_OPS_START__ + CPU_MIDR) - adr x5, (__CPU_OPS_END__ + CPU_MIDR) - - /* Initialize the return parameter */ - mov x0, #0 - /* Read the MIDR_EL1 */ mrs x2, midr_el1 mov_imm x3, CPU_IMPL_PN_MASK /* Retain only the implementation and part number using mask */ and w2, w2, w3 + + /* Get the cpu_ops end location */ + adr x5, (__CPU_OPS_END__ + CPU_MIDR) + + /* Initialize the return parameter */ + mov x0, #0 1: + /* Get the cpu_ops start location */ + adr x4, (__CPU_OPS_START__ + CPU_MIDR) + +2: /* Check if we have reached end of list */ cmp x4, x5 - b.eq error_exit + b.eq search_def_ptr /* load the midr from the cpu_ops */ ldr x1, [x4], #CPU_OPS_SIZE @@ -171,7 +181,7 @@ func get_cpu_ops_ptr /* Check if midr matches to midr of this core */ cmp w1, w2 - b.ne 1b + b.ne 2b /* Subtract the increment and offset to get the cpu-ops pointer */ sub x0, x4, #(CPU_OPS_SIZE + CPU_MIDR) @@ -179,7 +189,27 @@ func get_cpu_ops_ptr cmp x0, #0 ASM_ASSERT(ne) #endif +#ifdef SUPPORT_UNKNOWN_MPID + cbnz x2, exit_mpid_found + /* Mark the unsupported MPID flag */ + adrp x1, unsupported_mpid_flag + add x1, x1, :lo12:unsupported_mpid_flag + str w2, [x1] +exit_mpid_found: +#endif + ret + + /* + * Search again for a default pointer (MIDR = 0x0) + * or return error if already searched. + */ +search_def_ptr: +#ifdef SUPPORT_UNKNOWN_MPID + cbz x2, error_exit + mov x2, #0 + b 1b error_exit: +#endif ret endfunc get_cpu_ops_ptr diff --git a/lib/cpus/aarch64/generic.S b/lib/cpus/aarch64/generic.S new file mode 100644 index 000000000..ef1f048a1 --- /dev/null +++ b/lib/cpus/aarch64/generic.S @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include + + /* --------------------------------------------- + * Disable L1 data cache and unified L2 cache + * --------------------------------------------- + */ +func generic_disable_dcache + mrs x1, sctlr_el3 + bic x1, x1, #SCTLR_C_BIT + msr sctlr_el3, x1 + isb + ret +endfunc generic_disable_dcache + +func generic_core_pwr_dwn + mov x18, x30 + + /* --------------------------------------------- + * Turn off caches. + * --------------------------------------------- + */ + bl generic_disable_dcache + + /* --------------------------------------------- + * Flush L1 caches. + * --------------------------------------------- + */ + mov x0, #DCCISW + bl dcsw_op_level1 + + ret x18 +endfunc generic_core_pwr_dwn + +func generic_cluster_pwr_dwn + mov x18, x30 + + /* --------------------------------------------- + * Turn off caches. + * --------------------------------------------- + */ + bl generic_disable_dcache + + /* --------------------------------------------- + * Flush L1 caches. + * --------------------------------------------- + */ + mov x0, #DCCISW + bl dcsw_op_level1 + + /* --------------------------------------------- + * Disable the optional ACP. + * --------------------------------------------- + */ + bl plat_disable_acp + + /* --------------------------------------------- + * Flush L2 caches. + * --------------------------------------------- + */ + mov x0, #DCCISW + bl dcsw_op_level2 + + ret x18 + +endfunc generic_cluster_pwr_dwn + +/* --------------------------------------------- + * Unimplemented functions. + * --------------------------------------------- + */ +.equ generic_errata_report, 0 +.equ generic_cpu_reg_dump, 0 +.equ generic_reset_func, 0 + +declare_cpu_ops generic, AARCH64_GENERIC_MIDR, \ + generic_reset_func, \ + generic_core_pwr_dwn, \ + generic_cluster_pwr_dwn diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk index 890433983..8f0ff0bb8 100644 --- a/plat/arm/board/arm_fpga/platform.mk +++ b/plat/arm/board/arm_fpga/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2020, Arm Limited. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -40,6 +40,8 @@ HW_ASSISTED_COHERENCY := 1 PL011_GENERIC_UART := 1 +SUPPORT_UNKNOWN_MPID ?= 1 + FPGA_CPU_LIBS := lib/cpus/${ARCH}/aem_generic.S # select a different set of CPU files, depending on whether we compile for @@ -71,6 +73,12 @@ else lib/cpus/aarch64/cortex_a75.S endif +ifeq (${SUPPORT_UNKNOWN_MPID}, 1) +# Add support for unknown/invalid MPIDs (aarch64 only) +$(eval $(call add_define,SUPPORT_UNKNOWN_MPID)) + FPGA_CPU_LIBS += lib/cpus/aarch64/generic.S +endif + # Allow detection of GIC-600 GICV3_SUPPORT_GIC600 := 1 -- cgit v1.2.3 From aa3efe3df81429ef696dfe7fcb9ad9ef7ce86f6c Mon Sep 17 00:00:00 2001 From: laurenw-arm Date: Tue, 14 Jul 2020 14:18:34 -0500 Subject: Workaround for Cortex A77 erratum 1508412 Cortex A77 erratum 1508412 is a Cat B Errata present in r0p0 and r1p0. The workaround is a write sequence to several implementation defined registers based on A77 revision. This errata is explained in this SDEN: https://static.docs.arm.com/101992/0010/Arm_Cortex_A77_MP074_Software_Developer_Errata_Notice_v10.pdf Signed-off-by: Lauren Wehrmeister Change-Id: I217993cffb3ac57c313db8490e7b8a7bb393379b --- docs/design/cpu-specific-build-macros.rst | 3 ++ include/lib/cpus/aarch64/cortex_a77.h | 7 ++++ lib/cpus/aarch64/cortex_a77.S | 70 +++++++++++++++++++++++++++++++ lib/cpus/cpu-ops.mk | 8 ++++ 4 files changed, 88 insertions(+) diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst index 3c0e30f79..e9ff17e8c 100644 --- a/docs/design/cpu-specific-build-macros.rst +++ b/docs/design/cpu-specific-build-macros.rst @@ -251,6 +251,9 @@ For Cortex-A76, the following errata build flags are defined : For Cortex-A77, the following errata build flags are defined : +- ``ERRATA_A77_1508412``: This applies errata 1508412 workaround to Cortex-A77 + CPU. This needs to be enabled only for revision <= r1p0 of the CPU. + - ``ERRATA_A77_1800714``: This applies errata 1800714 workaround to Cortex-A77 CPU. This needs to be enabled only for revision <= r1p1 of the CPU. diff --git a/include/lib/cpus/aarch64/cortex_a77.h b/include/lib/cpus/aarch64/cortex_a77.h index bbd647c60..41aced8d2 100644 --- a/include/lib/cpus/aarch64/cortex_a77.h +++ b/include/lib/cpus/aarch64/cortex_a77.h @@ -24,4 +24,11 @@ #define CORTEX_A77_CPUPWRCTLR_EL1 S3_0_C15_C2_7 #define CORTEX_A77_CPUPWRCTLR_EL1_CORE_PWRDN_BIT (U(1) << 0) +#define CORTEX_A77_CPUPSELR_EL3 S3_6_C15_C8_0 +#define CORTEX_A77_CPUPCR_EL3 S3_6_C15_C8_1 +#define CORTEX_A77_CPUPOR_EL3 S3_6_C15_C8_2 +#define CORTEX_A77_CPUPMR_EL3 S3_6_C15_C8_3 +#define CORTEX_A77_CPUPOR2_EL3 S3_6_C15_C8_4 +#define CORTEX_A77_CPUPMR2_EL3 S3_6_C15_C8_5 + #endif /* CORTEX_A77_H */ diff --git a/lib/cpus/aarch64/cortex_a77.S b/lib/cpus/aarch64/cortex_a77.S index 0c30460d4..ea219998f 100644 --- a/lib/cpus/aarch64/cortex_a77.S +++ b/lib/cpus/aarch64/cortex_a77.S @@ -21,6 +21,70 @@ #error "Cortex-A77 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0" #endif + /* -------------------------------------------------- + * Errata Workaround for Cortex A77 Errata #1508412. + * This applies only to revision <= r1p0 of Cortex A77. + * Inputs: + * x0: variant[4:7] and revision[0:3] of current cpu. + * Shall clobber: x0-x17 + * -------------------------------------------------- + */ +func errata_a77_1508412_wa + /* + * Compare x0 against revision r1p0 + */ + mov x17, x30 + bl check_errata_1508412 + cbz x0, 3f + /* + * Compare x0 against revision r0p0 + */ + bl check_errata_1508412_0 + cbz x0, 1f + ldr x0, =0x0 + msr CORTEX_A77_CPUPSELR_EL3, x0 + ldr x0, =0x00E8400000 + msr CORTEX_A77_CPUPOR_EL3, x0 + ldr x0, =0x00FFE00000 + msr CORTEX_A77_CPUPMR_EL3, x0 + ldr x0, =0x4004003FF + msr CORTEX_A77_CPUPCR_EL3, x0 + ldr x0, =0x1 + msr CORTEX_A77_CPUPSELR_EL3, x0 + ldr x0, =0x00E8C00040 + msr CORTEX_A77_CPUPOR_EL3, x0 + ldr x0, =0x00FFE00040 + msr CORTEX_A77_CPUPMR_EL3, x0 + b 2f +1: + ldr x0, =0x0 + msr CORTEX_A77_CPUPSELR_EL3, x0 + ldr x0, =0x00E8400000 + msr CORTEX_A77_CPUPOR_EL3, x0 + ldr x0, =0x00FF600000 + msr CORTEX_A77_CPUPMR_EL3, x0 + ldr x0, =0x00E8E00080 + msr CORTEX_A77_CPUPOR2_EL3, x0 + ldr x0, =0x00FFE000C0 + msr CORTEX_A77_CPUPMR2_EL3, x0 +2: + ldr x0, =0x04004003FF + msr CORTEX_A77_CPUPCR_EL3, x0 + isb +3: + ret x17 +endfunc errata_a77_1508412_wa + +func check_errata_1508412 + mov x1, #0x10 + b cpu_rev_var_ls +endfunc check_errata_1508412 + +func check_errata_1508412_0 + mov x1, #0x0 + b cpu_rev_var_ls +endfunc check_errata_1508412_0 + /* -------------------------------------------------- * Errata Workaround for Cortex A77 Errata #1800714. * This applies to revision <= r1p1 of Cortex A77. @@ -60,6 +124,11 @@ func cortex_a77_reset_func bl cpu_get_rev_var mov x18, x0 +#if ERRATA_A77_1508412 + mov x0, x18 + bl errata_a77_1508412_wa +#endif + #if ERRATA_A77_1800714 mov x0, x18 bl errata_a77_1800714_wa @@ -98,6 +167,7 @@ func cortex_a77_errata_report * Report all errata. The revision-variant information is passed to * checking functions of each errata. */ + report_errata ERRATA_A77_1508412, cortex_a77, 1508412 report_errata ERRATA_A77_1800714, cortex_a77, 1800714 ldp x8, x30, [sp], #16 diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk index 7cd8ed99e..5df94cce4 100644 --- a/lib/cpus/cpu-ops.mk +++ b/lib/cpus/cpu-ops.mk @@ -278,6 +278,10 @@ ERRATA_A76_1800710 ?=0 # to all revisions of Cortex A76 cpu. ERRATA_A76_1165522 ?=0 +# Flag to apply erratum 1508412 workaround during reset. This erratum applies +# only to revision <= r1p0 of the Cortex A77 cpu. +ERRATA_A77_1508412 ?=0 + # Flag to apply erratum 1800714 workaround during reset. This erratum applies # only to revision <= r1p1 of the Cortex A77 cpu. ERRATA_A77_1800714 ?=0 @@ -551,6 +555,10 @@ $(eval $(call add_define,ERRATA_A76_1800710)) $(eval $(call assert_boolean,ERRATA_A76_1165522)) $(eval $(call add_define,ERRATA_A76_1165522)) +# Process ERRATA_A77_1508412 flag +$(eval $(call assert_boolean,ERRATA_A77_1508412)) +$(eval $(call add_define,ERRATA_A77_1508412)) + # Process ERRATA_A77_1800714 flag $(eval $(call assert_boolean,ERRATA_A77_1800714)) $(eval $(call add_define,ERRATA_A77_1800714)) -- cgit v1.2.3 From 74ae4eef1c7243a1578954ac5ca3e959c880ab77 Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Mon, 28 Sep 2020 14:47:54 +0100 Subject: Measured Boot Driver: Fix MISRA-C 2012 defects This patch fixes MISRA C-2012 Pointers and Arrays Rule 18.4 defects reported by Coverity scan: "misra_c_2012_rule_18_4_violation: Using arithmetic on pointer " Change-Id: I06753b28467c473e346b9871c1657284fc43a3f3 Signed-off-by: Alexei Fedorov --- drivers/measured_boot/event_log.c | 26 +++++++++++++++----------- drivers/measured_boot/event_print.c | 25 +++++++++++++------------ 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/drivers/measured_boot/event_log.c b/drivers/measured_boot/event_log.c index 0042c9699..727bdf5f3 100644 --- a/drivers/measured_boot/event_log.c +++ b/drivers/measured_boot/event_log.c @@ -147,13 +147,14 @@ static int add_event2(const uint8_t *hash, const image_data_t *image_ptr) ((tpml_digest_values *)ptr)->count = HASH_ALG_COUNT; /* TCG_PCR_EVENT2.Digests[] */ - ptr = (uint8_t *)ptr + offsetof(tpml_digest_values, 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 *)ptr + offsetof(tpmt_ha, digest); + ptr = (uint8_t *)((uintptr_t)ptr + offsetof(tpmt_ha, digest)); /* Check for space in Event Log buffer */ if (((uintptr_t)ptr + TCG_DIGEST_SIZE) > EVENT_LOG_END) { @@ -170,7 +171,7 @@ static int add_event2(const uint8_t *hash, const image_data_t *image_ptr) } /* TCG_PCR_EVENT2.EventSize */ - ptr = (uint8_t *)ptr + TCG_DIGEST_SIZE; + 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 */ @@ -178,7 +179,8 @@ static int add_event2(const uint8_t *hash, const image_data_t *image_ptr) (const void *)image_ptr->name, name_len); /* End of event data */ - log_ptr = (uint8_t *)ptr + offsetof(event2_data_t, event) + name_len; + log_ptr = (uint8_t *)((uintptr_t)ptr + + offsetof(event2_data_t, event) + name_len); return 0; } @@ -205,19 +207,20 @@ void event_log_init(void) */ (void)memcpy(ptr, (const void *)&id_event_header, sizeof(id_event_header)); - ptr = (uint8_t *)ptr + 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 *)ptr + sizeof(id_event_algorithm_size_t); + 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 *)ptr + offsetof(id_event_struct_data_t, vendor_info); + ptr = (uint8_t *)((uintptr_t)ptr + + offsetof(id_event_struct_data_t, vendor_info)); if ((uintptr_t)ptr != ((uintptr_t)event_log + ID_EVENT_SIZE)) { panic(); } @@ -234,19 +237,20 @@ void event_log_init(void) /* Copy Startup Locality Event Header */ (void)memcpy(ptr, (const void *)&locality_event_header, sizeof(locality_event_header)); - ptr = (uint8_t *)ptr + 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 *)ptr + offsetof(tpmt_ha, digest) + TCG_DIGEST_SIZE; + 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 *)ptr + offsetof(event2_data_t, event); + ptr = (uint8_t *)((uintptr_t)ptr + offsetof(event2_data_t, event)); /* TCG_EfiStartupLocalityEvent.Signature */ (void)memcpy(ptr, (const void *)locality_signature, @@ -257,7 +261,7 @@ void event_log_init(void) * the platform's boot firmware */ ((startup_locality_event_t *)ptr)->startup_locality = 0U; - ptr = (uint8_t *)ptr + sizeof(startup_locality_event_t); + ptr = (uint8_t *)((uintptr_t)ptr + sizeof(startup_locality_event_t)); if ((uintptr_t)ptr != ((uintptr_t)start_ptr + LOC_EVENT_SIZE)) { panic(); } diff --git a/drivers/measured_boot/event_print.c b/drivers/measured_boot/event_print.c index ed970b870..84ed4b1cb 100644 --- a/drivers/measured_boot/event_print.c +++ b/drivers/measured_boot/event_print.c @@ -28,7 +28,7 @@ static void id_event_print(uint8_t **log_addr, size_t *log_size) uint32_t event_size, number_of_algorithms; size_t digest_len; #if ENABLE_ASSERTIONS - const uint8_t *end_ptr = *log_addr + *log_size; + const uint8_t *end_ptr = (uint8_t *)((uintptr_t)*log_addr + *log_size); bool valid = true; #endif @@ -90,7 +90,7 @@ static void id_event_print(uint8_t **log_addr, size_t *log_size) /* Size of DigestSizes[] */ digest_len = number_of_algorithms * sizeof(id_event_algorithm_size_t); - assert(((uint8_t *)alg_ptr + digest_len) <= end_ptr); + assert(((uintptr_t)alg_ptr + digest_len) <= (uintptr_t)end_ptr); LOG_EVENT(" DigestSizes :\n"); for (i = 0U; i < number_of_algorithms; ++i) { @@ -118,14 +118,14 @@ static void id_event_print(uint8_t **log_addr, size_t *log_size) } /* Address of VendorInfoSize */ - info_size_ptr = (uint8_t *)alg_ptr + digest_len; - assert(info_size_ptr <= end_ptr); + 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((info_size_ptr + info_size) <= end_ptr); + assert(((uintptr_t)info_size_ptr + info_size) <= (uintptr_t)end_ptr); /* Check EventSize */ assert(event_size == (sizeof(id_event_struct_t) + @@ -154,7 +154,7 @@ static void event2_print(uint8_t **log_addr, size_t *log_size) size_t sha_size, digests_size = 0U; void *ptr = *log_addr; #if ENABLE_ASSERTIONS - const uint8_t *end_ptr = *log_addr + *log_size; + const uint8_t *end_ptr = (uint8_t *)((uintptr_t)*log_addr + *log_size); #endif assert(*log_size >= sizeof(event2_header_t)); @@ -174,7 +174,8 @@ static void event2_print(uint8_t **log_addr, size_t *log_size) for (unsigned int i = 0U; i < count; ++i) { /* Check AlgorithmId address */ - assert(((uint8_t *)ptr + offsetof(tpmt_ha, digest)) <= end_ptr); + assert(((uintptr_t)ptr + + offsetof(tpmt_ha, digest)) <= (uintptr_t)end_ptr); LOG_EVENT(" #%u AlgorithmId : SHA", i); switch (((tpmt_ha *)ptr)->algorithm_id) { @@ -198,8 +199,8 @@ static void event2_print(uint8_t **log_addr, size_t *log_size) } /* End of Digest[] */ - ptr = (uint8_t *)ptr + offsetof(tpmt_ha, digest); - assert(((uint8_t *)ptr + sha_size) <= end_ptr); + 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; @@ -217,16 +218,16 @@ static void event2_print(uint8_t **log_addr, size_t *log_size) } /* TCG_PCR_EVENT2.EventSize */ - assert(((uint8_t *)ptr + offsetof(event2_data_t, event)) <= end_ptr); + 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 *)ptr + offsetof(event2_data_t, event); + ptr = (uint8_t *)((uintptr_t)ptr + offsetof(event2_data_t, event)); /* End of TCG_PCR_EVENT2.Event[EventSize] */ - assert(((uint8_t *)ptr + event_size) <= end_ptr); + 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)) { -- cgit v1.2.3 From 2b357c3159218b435276593109a816ffd7016f25 Mon Sep 17 00:00:00 2001 From: Manoj Kumar Date: Thu, 9 Jul 2020 09:56:02 +0100 Subject: lib/cpus: add support for Morello Rainier CPUs This patch adds CPU support for the Rainier CPU which is derived from Neoverse N1 r4p0 CPU and implements the Morello capability architecture. Change-Id: Ic6b796481da5a66504ecb0648879446edf4c69fb Signed-off-by: Manoj Kumar --- include/lib/cpus/aarch64/rainier.h | 66 +++++++++++ lib/cpus/aarch64/rainier.S | 218 +++++++++++++++++++++++++++++++++++++ 2 files changed, 284 insertions(+) create mode 100644 include/lib/cpus/aarch64/rainier.h create mode 100644 lib/cpus/aarch64/rainier.S diff --git a/include/lib/cpus/aarch64/rainier.h b/include/lib/cpus/aarch64/rainier.h new file mode 100644 index 000000000..9ff166956 --- /dev/null +++ b/include/lib/cpus/aarch64/rainier.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef RAINIER_H +#define RAINIER_H + +#include + +/* RAINIER MIDR for revision 0 */ +#define RAINIER_MIDR U(0x3f0f4100) + +/* Exception Syndrome register EC code for IC Trap */ +#define RAINIER_EC_IC_TRAP U(0x1f) + +/******************************************************************************* + * CPU Power Control register specific definitions. + ******************************************************************************/ +#define RAINIER_CPUPWRCTLR_EL1 S3_0_C15_C2_7 + +/* Definitions of register field mask in RAINIER_CPUPWRCTLR_EL1 */ +#define RAINIER_CORE_PWRDN_EN_MASK U(0x1) + +#define RAINIER_ACTLR_AMEN_BIT (U(1) << 4) + +#define RAINIER_AMU_NR_COUNTERS U(5) +#define RAINIER_AMU_GROUP0_MASK U(0x1f) + +/******************************************************************************* + * CPU Extended Control register specific definitions. + ******************************************************************************/ +#define RAINIER_CPUECTLR_EL1 S3_0_C15_C1_4 + +#define RAINIER_WS_THR_L2_MASK (ULL(3) << 24) +#define RAINIER_CPUECTLR_EL1_MM_TLBPF_DIS_BIT (ULL(1) << 51) + +/******************************************************************************* + * CPU Auxiliary Control register specific definitions. + ******************************************************************************/ +#define RAINIER_CPUACTLR_EL1 S3_0_C15_C1_0 + +#define RAINIER_CPUACTLR_EL1_BIT_6 (ULL(1) << 6) +#define RAINIER_CPUACTLR_EL1_BIT_13 (ULL(1) << 13) + +#define RAINIER_CPUACTLR2_EL1 S3_0_C15_C1_1 + +#define RAINIER_CPUACTLR2_EL1_BIT_0 (ULL(1) << 0) +#define RAINIER_CPUACTLR2_EL1_BIT_2 (ULL(1) << 2) +#define RAINIER_CPUACTLR2_EL1_BIT_11 (ULL(1) << 11) +#define RAINIER_CPUACTLR2_EL1_BIT_15 (ULL(1) << 15) +#define RAINIER_CPUACTLR2_EL1_BIT_16 (ULL(1) << 16) +#define RAINIER_CPUACTLR2_EL1_BIT_59 (ULL(1) << 59) + +#define RAINIER_CPUACTLR3_EL1 S3_0_C15_C1_2 + +#define RAINIER_CPUACTLR3_EL1_BIT_10 (ULL(1) << 10) + +/* Instruction patching registers */ +#define CPUPSELR_EL3 S3_6_C15_C8_0 +#define CPUPCR_EL3 S3_6_C15_C8_1 +#define CPUPOR_EL3 S3_6_C15_C8_2 +#define CPUPMR_EL3 S3_6_C15_C8_3 + +#endif /* RAINIER_H */ diff --git a/lib/cpus/aarch64/rainier.S b/lib/cpus/aarch64/rainier.S new file mode 100644 index 000000000..f7afd0ba1 --- /dev/null +++ b/lib/cpus/aarch64/rainier.S @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2020, 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 "Rainier CPU must be compiled with HW_ASSISTED_COHERENCY enabled" +#endif + +/* 64-bit only core */ +#if CTX_INCLUDE_AARCH32_REGS == 1 +#error "Rainier CPU supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0" +#endif + +#if ERRATA_RAINIER_IC_TRAP + .global rainier_errata_ic_trap_handler +#endif + +/* -------------------------------------------------- + * Disable speculative loads if Rainier supports + * SSBS. + * + * Shall clobber: x0. + * -------------------------------------------------- + */ +func rainier_disable_speculative_loads + /* Check if the PE implements SSBS */ + mrs x0, id_aa64pfr1_el1 + tst x0, #(ID_AA64PFR1_EL1_SSBS_MASK << ID_AA64PFR1_EL1_SSBS_SHIFT) + b.eq 1f + + /* Disable speculative loads */ + msr SSBS, xzr + +1: + ret +endfunc rainier_disable_speculative_loads + +/* -------------------------------------------------- + * Errata Workaround for Neoverse N1 Erratum 1542419. + * This applies to revisions r3p0 - r4p0 of Neoverse N1 + * Since Rainier core is based on Neoverse N1 r4p0, this + * errata applies to Rainier core r0p0 + * Inputs: + * x0: variant[4:7] and revision[0:3] of current cpu. + * Shall clobber: x0-x17 + * -------------------------------------------------- + */ +func errata_n1_1542419_wa + /* Compare x0 against revision r3p0 and r4p0 */ + mov x17, x30 + bl check_errata_1542419 + cbz x0, 1f + + /* Apply instruction patching sequence */ + mov x0, xzr + msr CPUPSELR_EL3, x0 + ldr x0, =0xEE670D35 + msr CPUPOR_EL3, x0 + ldr x0, =0xFFFF0FFF + msr CPUPMR_EL3, x0 + ldr x0, =0x08000020007D + msr CPUPCR_EL3, x0 + isb +1: + ret x17 +endfunc errata_n1_1542419_wa + +func check_errata_1542419 + /* Applies to Rainier core r0p0. */ + mov x1, #0x00 + b cpu_rev_var_ls +endfunc check_errata_1542419 + +func rainier_reset_func + mov x19, x30 + + bl rainier_disable_speculative_loads + + /* Forces all cacheable atomic instructions to be near */ + mrs x0, RAINIER_CPUACTLR2_EL1 + orr x0, x0, #RAINIER_CPUACTLR2_EL1_BIT_2 + msr RAINIER_CPUACTLR2_EL1, x0 + isb + + bl cpu_get_rev_var + mov x18, x0 + +#if ERRATA_N1_1542419 + mov x0, x18 + bl errata_n1_1542419_wa +#endif + +#if ENABLE_AMU + /* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */ + mrs x0, actlr_el3 + orr x0, x0, #RAINIER_ACTLR_AMEN_BIT + msr actlr_el3, x0 + + /* Make sure accesses from EL0/EL1 are not trapped to EL2 */ + mrs x0, actlr_el2 + orr x0, x0, #RAINIER_ACTLR_AMEN_BIT + msr actlr_el2, x0 + + /* Enable group0 counters */ + mov x0, #RAINIER_AMU_GROUP0_MASK + msr CPUAMCNTENSET_EL0, x0 +#endif + + isb + ret x19 +endfunc rainier_reset_func + + /* --------------------------------------------- + * HW will do the cache maintenance while powering down + * --------------------------------------------- + */ +func rainier_core_pwr_dwn + /* --------------------------------------------- + * Enable CPU power down bit in power control register + * --------------------------------------------- + */ + mrs x0, RAINIER_CPUPWRCTLR_EL1 + orr x0, x0, #RAINIER_CORE_PWRDN_EN_MASK + msr RAINIER_CPUPWRCTLR_EL1, x0 + isb + ret +endfunc rainier_core_pwr_dwn + +#if REPORT_ERRATA +/* + * Errata printing function for Rainier. Must follow AAPCS. + */ +func rainier_errata_report + stp x8, x30, [sp, #-16]! + + bl cpu_get_rev_var + mov x8, x0 + + /* + * Report all errata. The revision-variant information is passed to + * checking functions of each errata. + */ + report_errata ERRATA_N1_1542419, rainier, 1542419 + + ldp x8, x30, [sp], #16 + ret +endfunc rainier_errata_report +#endif + +/* + * Handle trap of EL0 IC IVAU instructions to EL3 by executing a TLB + * inner-shareable invalidation to an arbitrary address followed by a DSB. + * + * x1: Exception Syndrome + */ +func rainier_errata_ic_trap_handler + cmp x1, #RAINIER_EC_IC_TRAP + b.ne 1f + tlbi vae3is, xzr + dsb sy + + # Skip the IC instruction itself + mrs x3, elr_el3 + add x3, x3, #4 + msr elr_el3, x3 + + ldp x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0] + ldp x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2] + ldp x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4] + ldr x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR] + +#if IMAGE_BL31 && RAS_EXTENSION + /* + * Issue Error Synchronization Barrier to synchronize SErrors before + * exiting EL3. We're running with EAs unmasked, so any synchronized + * errors would be taken immediately; therefore no need to inspect + * DISR_EL1 register. + */ + esb +#endif + eret +1: + ret +endfunc rainier_errata_ic_trap_handler + + /* --------------------------------------------- + * This function provides Rainier 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.rainier_regs, "aS" +rainier_regs: /* The ascii list of register names to be reported */ + .asciz "cpuectlr_el1", "" + +func rainier_cpu_reg_dump + adr x6, rainier_regs + mrs x8, RAINIER_CPUECTLR_EL1 + ret +endfunc rainier_cpu_reg_dump + +declare_cpu_ops_eh rainier, RAINIER_MIDR, \ + rainier_reset_func, \ + rainier_errata_ic_trap_handler, \ + rainier_core_pwr_dwn -- cgit v1.2.3 From e1cbcf965faba453c4680b385e42b145d5358465 Mon Sep 17 00:00:00 2001 From: Manoj Kumar Date: Fri, 31 Jul 2020 12:32:36 +0100 Subject: fdts: add device tree sources for morello platform Change-Id: Ib5945c37983505f327a195bdb8b91ed1b7b90921 Signed-off-by: Manoj Kumar --- fdts/morello-fvp.dts | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++ fdts/morello.dtsi | 106 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 239 insertions(+) create mode 100644 fdts/morello-fvp.dts create mode 100644 fdts/morello.dtsi diff --git a/fdts/morello-fvp.dts b/fdts/morello-fvp.dts new file mode 100644 index 000000000..ecbed5ebd --- /dev/null +++ b/fdts/morello-fvp.dts @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; +#include "morello.dtsi" + +/ { + + chosen { + stdout-path = "soc_uart0:115200n8"; + }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + secure-firmware@ff000000 { + reg = <0 0xff000000 0 0x01000000>; + no-map; + }; + }; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + cpu0@0 { + compatible = "arm,armv8"; + reg = <0x0 0x0>; + device_type = "cpu"; + enable-method = "psci"; + clocks = <&scmi_dvfs 0>; + }; + cpu1@100 { + compatible = "arm,armv8"; + reg = <0x0 0x100>; + device_type = "cpu"; + enable-method = "psci"; + clocks = <&scmi_dvfs 0>; + }; + cpu2@10000 { + compatible = "arm,armv8"; + reg = <0x0 0x10000>; + device_type = "cpu"; + enable-method = "psci"; + clocks = <&scmi_dvfs 0>; + }; + cpu3@10100 { + compatible = "arm,armv8"; + reg = <0x0 0x10100>; + device_type = "cpu"; + enable-method = "psci"; + clocks = <&scmi_dvfs 0>; + }; + }; + + /* The first bank of memory, memory map is actually provided by UEFI. */ + memory@80000000 { + #address-cells = <2>; + #size-cells = <2>; + device_type = "memory"; + /* [0x80000000-0xffffffff] */ + reg = <0x00000000 0x80000000 0x0 0x80000000>; + }; + + memory@8080000000 { + #address-cells = <2>; + #size-cells = <2>; + device_type = "memory"; + /* [0x8080000000-0x83ffffffff] */ + reg = <0x00000080 0x80000000 0x1 0x80000000>; + }; + + virtio_block@1c170000 { + compatible = "virtio,mmio"; + reg = <0x0 0x1c170000 0x0 0x200>; + interrupts = ; + }; + + ethernet@1d100000 { + compatible = "smsc,lan91c111"; + reg = <0x0 0x1d100000 0x0 0x10000>; + interrupts = ; + }; + + kmi@1c150000 { + compatible = "arm,pl050", "arm,primecell"; + reg = <0x0 0x1c150000 0x0 0x1000>; + interrupts = ; + clocks = <&bp_clock24mhz>, <&bp_clock24mhz>; + clock-names = "KMIREFCLK", "apb_pclk"; + }; + + kmi@1c160000 { + compatible = "arm,pl050", "arm,primecell"; + reg = <0x0 0x1c160000 0x0 0x1000>; + interrupts = ; + clocks = <&bp_clock24mhz>, <&bp_clock24mhz>; + clock-names = "KMIREFCLK", "apb_pclk"; + }; + + firmware { + scmi { + compatible = "arm,scmi"; + mbox-names = "tx", "rx"; + mboxes = <&mailbox 1 0 &mailbox 1 1>; + shmem = <&cpu_scp_hpri0 &cpu_scp_hpri1>; + #address-cells = <1>; + #size-cells = <0>; + + scmi_dvfs: protocol@13 { + reg = <0x13>; + #clock-cells = <1>; + }; + }; + }; + + bp_clock24mhz: clock24mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24000000>; + clock-output-names = "bp:clock24mhz"; + }; +}; + +&gic { + reg = <0x0 0x30000000 0 0x10000>, /* GICD */ + <0x0 0x300c0000 0 0x80000>; /* GICR */ + interrupts = ; +}; diff --git a/fdts/morello.dtsi b/fdts/morello.dtsi new file mode 100644 index 000000000..52c04cd96 --- /dev/null +++ b/fdts/morello.dtsi @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +/ { + compatible = "arm,morello"; + + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + aliases { + serial0 = &soc_uart0; + }; + + gic: interrupt-controller@2c010000 { + compatible = "arm,gic-600", "arm,gic-v3"; + #address-cells = <2>; + #interrupt-cells = <3>; + #size-cells = <2>; + ranges; + interrupt-controller; + }; + + pmu { + compatible = "arm,armv8-pmuv3"; + interrupts = ; + }; + + spe-pmu { + compatible = "arm,statistical-profiling-extension-v1"; + interrupts = ; + }; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = , + , + , + ; + }; + + mailbox: mhu@45000000 { + compatible = "arm,mhu-doorbell", "arm,primecell"; + reg = <0x0 0x45000000 0x0 0x1000>; + interrupts = , + ; + interrupt-names = "mhu_lpri_rx", + "mhu_hpri_rx"; + #mbox-cells = <2>; + mbox-name = "ARM-MHU"; + clocks = <&soc_refclk100mhz>; + clock-names = "apb_pclk"; + }; + + sram: sram@45200000 { + compatible = "mmio-sram"; + reg = <0x0 0x45200000 0x0 0x8000>; + + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x0 0x45200000 0x8000>; + + cpu_scp_hpri0: scp-shmem@0 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0x80>; + }; + + cpu_scp_hpri1: scp-shmem@80 { + compatible = "arm,scmi-shmem"; + reg = <0x80 0x80>; + }; + }; + + soc_refclk100mhz: refclk100mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <100000000>; + clock-output-names = "apb_pclk"; + }; + + soc_uartclk: uartclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <50000000>; + clock-output-names = "uartclk"; + }; + + soc_uart0: uart@2a400000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0 0x2a400000 0x0 0x1000>; + interrupts = ; + clocks = <&soc_uartclk>, <&soc_refclk100mhz>; + clock-names = "uartclk", "apb_pclk"; + status = "okay"; + }; +}; -- cgit v1.2.3 From dfd5bfb097a694a136d067bb1b80133500adcfce Mon Sep 17 00:00:00 2001 From: Chandni Cherukuri Date: Tue, 22 Sep 2020 18:56:25 +0530 Subject: plat/arm: Add platform support for Morello This patch adds support for Morello platform. It is an initial port which includes only BL31 support as the System Control Processor (SCP) is expected to take the role of primary bootloader. Change-Id: I1ecbe5a14a2d487b2ecea3c1ca227f08473ed2dd Co-authored-by: Chandni Cherukuri Signed-off-by: Chandni Cherukuri Signed-off-by: Anurag Koul --- docs/plat/index.rst | 1 + plat/arm/board/morello/aarch64/morello_helper.S | 55 ++++++++++ plat/arm/board/morello/include/plat_macros.S | 25 +++++ plat/arm/board/morello/include/platform_def.h | 96 +++++++++++++++++ plat/arm/board/morello/morello_bl31_setup.c | 131 ++++++++++++++++++++++++ plat/arm/board/morello/morello_def.h | 33 ++++++ plat/arm/board/morello/morello_interconnect.c | 33 ++++++ plat/arm/board/morello/morello_plat.c | 22 ++++ plat/arm/board/morello/morello_security.c | 12 +++ plat/arm/board/morello/morello_topology.c | 60 +++++++++++ plat/arm/board/morello/platform.mk | 66 ++++++++++++ 11 files changed, 534 insertions(+) create mode 100644 plat/arm/board/morello/aarch64/morello_helper.S create mode 100644 plat/arm/board/morello/include/plat_macros.S create mode 100644 plat/arm/board/morello/include/platform_def.h create mode 100644 plat/arm/board/morello/morello_bl31_setup.c create mode 100644 plat/arm/board/morello/morello_def.h create mode 100644 plat/arm/board/morello/morello_interconnect.c create mode 100644 plat/arm/board/morello/morello_plat.c create mode 100644 plat/arm/board/morello/morello_security.c create mode 100644 plat/arm/board/morello/morello_topology.c create mode 100644 plat/arm/board/morello/platform.mk diff --git a/docs/plat/index.rst b/docs/plat/index.rst index bd2341010..fb60e5639 100644 --- a/docs/plat/index.rst +++ b/docs/plat/index.rst @@ -54,6 +54,7 @@ documentation associated with them. - Arm Neoverse Reference Design E1 Edge (RD-E1-Edge) FVP - Arm SGI-575 and SGM-775 - MediaTek MT6795 and MT8173 SoCs + - Arm Morello Platform -------------- diff --git a/plat/arm/board/morello/aarch64/morello_helper.S b/plat/arm/board/morello/aarch64/morello_helper.S new file mode 100644 index 000000000..60470a843 --- /dev/null +++ b/plat/arm/board/morello/aarch64/morello_helper.S @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +#include + + .globl plat_arm_calc_core_pos + .globl plat_reset_handler + + /* ----------------------------------------------------- + * unsigned int plat_arm_calc_core_pos(u_register_t mpidr) + * + * Helper function to calculate the core position. + * ((ChipId * MORELLO_MAX_CLUSTERS_PER_CHIP + ClusterId) * + * MORELLO_MAX_CPUS_PER_CLUSTER * MORELLO_MAX_PE_PER_CPU) + + * (CPUId * MORELLO_MAX_PE_PER_CPU) + ThreadId + * + * which can be simplified as: + * + * (((ChipId * MORELLO_MAX_CLUSTERS_PER_CHIP + ClusterId) * + * MORELLO_MAX_CPUS_PER_CLUSTER + CPUId) * MORELLO_MAX_PE_PER_CPU) + + * ThreadId + * ------------------------------------------------------ + */ + +func plat_arm_calc_core_pos + mov x4, x0 + + /* + * The MT bit in MPIDR is always set for morello and the + * affinity level 0 corresponds to thread affinity level. + */ + + /* Extract individual affinity fields from MPIDR */ + ubfx x0, x4, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS + ubfx x1, x4, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS + ubfx x2, x4, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS + ubfx x3, x4, #MPIDR_AFF3_SHIFT, #MPIDR_AFFINITY_BITS + + /* Compute linear position */ + mov x4, #MORELLO_MAX_CLUSTERS_PER_CHIP + madd x2, x3, x4, x2 + mov x4, #MORELLO_MAX_CPUS_PER_CLUSTER + madd x1, x2, x4, x1 + mov x4, #MORELLO_MAX_PE_PER_CPU + madd x0, x1, x4, x0 + ret +endfunc plat_arm_calc_core_pos diff --git a/plat/arm/board/morello/include/plat_macros.S b/plat/arm/board/morello/include/plat_macros.S new file mode 100644 index 000000000..195be8435 --- /dev/null +++ b/plat/arm/board/morello/include/plat_macros.S @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLAT_MACROS_S +#define PLAT_MACROS_S + +#include + +/* --------------------------------------------- + * The below required platform porting macro + * prints out relevant platform registers + * whenever an unhandled exception is taken in + * BL31. + * + * There are currently no platform specific regs + * to print. + * --------------------------------------------- + */ + .macro plat_crash_print_regs + .endm + +#endif /* PLAT_MACROS_S */ diff --git a/plat/arm/board/morello/include/platform_def.h b/plat/arm/board/morello/include/platform_def.h new file mode 100644 index 000000000..07c06a10c --- /dev/null +++ b/plat/arm/board/morello/include/platform_def.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +#include +#include +#include + +/* UART related constants */ +#define PLAT_ARM_BOOT_UART_BASE ULL(0x2A400000) +#define PLAT_ARM_BOOT_UART_CLK_IN_HZ U(50000000) + +#define PLAT_ARM_RUN_UART_BASE ULL(0x2A410000) +#define PLAT_ARM_RUN_UART_CLK_IN_HZ U(50000000) + +#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_DRAM2_BASE ULL(0x8080000000) +#define PLAT_ARM_DRAM2_SIZE ULL(0xF80000000) + +/* + * To access the complete DDR memory along with remote chip's DDR memory, + * which is at 4 TB offset, physical and virtual address space limits are + * extended to 43-bits. + */ +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 43) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 43) + +#if CSS_USE_SCMI_SDS_DRIVER +#define MORELLO_SCMI_PAYLOAD_BASE ULL(0x45400000) +#else +#define PLAT_CSS_SCP_COM_SHARED_MEM_BASE ULL(0x45400000) +#endif + +#define PLAT_ARM_TRUSTED_SRAM_SIZE UL(0x00080000) +#define PLAT_ARM_MAX_BL31_SIZE UL(0x20000) + +/******************************************************************************* + * MORELLO topology related constants + ******************************************************************************/ +#define MORELLO_MAX_CPUS_PER_CLUSTER U(2) +#define PLAT_ARM_CLUSTER_COUNT U(2) +#define PLAT_MORELLO_CHIP_COUNT U(1) +#define MORELLO_MAX_CLUSTERS_PER_CHIP U(2) +#define MORELLO_MAX_PE_PER_CPU U(1) + +#define PLATFORM_CORE_COUNT (PLAT_MORELLO_CHIP_COUNT * \ + PLAT_ARM_CLUSTER_COUNT * \ + MORELLO_MAX_CPUS_PER_CLUSTER * \ + MORELLO_MAX_PE_PER_CPU) + +/* System power domain level */ +#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL3 + +/* + * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the + * plat_arm_mmap array defined for each BL stage. + */ +#define PLAT_ARM_MMAP_ENTRIES U(9) +#define MAX_XLAT_TABLES U(10) + +#define PLATFORM_STACK_SIZE U(0x400) + +#define PLAT_ARM_NSTIMER_FRAME_ID U(0) +#define PLAT_CSS_MHU_BASE UL(0x45000000) +#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE +#define PLAT_MAX_PWR_LVL U(2) + +#define PLAT_ARM_G1S_IRQ_PROPS(grp) CSS_G1S_IRQ_PROPS(grp) +#define PLAT_ARM_G0_IRQ_PROPS(grp) ARM_G0_IRQ_PROPS(grp) + +#define MORELLO_DEVICE_BASE ULL(0x08000000) +#define MORELLO_DEVICE_SIZE ULL(0x48000000) + +#define MORELLO_MAP_DEVICE MAP_REGION_FLAT( \ + MORELLO_DEVICE_BASE, \ + MORELLO_DEVICE_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#define ARM_MAP_DRAM1 MAP_REGION_FLAT( \ + ARM_DRAM1_BASE, \ + ARM_DRAM1_SIZE, \ + MT_MEMORY | MT_RW | MT_NS) + +/* GIC related constants */ +#define PLAT_ARM_GICD_BASE UL(0x30000000) +#define PLAT_ARM_GICC_BASE UL(0x2C000000) +#define PLAT_ARM_GICR_BASE UL(0x300C0000) + +#endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/morello/morello_bl31_setup.c b/plat/arm/board/morello/morello_bl31_setup.c new file mode 100644 index 000000000..43f5f7fc7 --- /dev/null +++ b/plat/arm/board/morello/morello_bl31_setup.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include + +#include "morello_def.h" +#include + +/* + * Platform information structure stored in SDS. + * This structure holds information about platform's DDR + * size which is an information about multichip setup + * - multichip mode + * - slave_count + * - Local DDR size in GB, DDR memory in master board + * - Remote DDR size in GB, DDR memory in slave board + */ +struct morello_plat_info { + bool multichip_mode; + uint8_t slave_count; + uint8_t local_ddr_size; + uint8_t remote_ddr_size; +} __packed; + +/* + * BL33 image information structure stored in SDS. + * This structure holds the source & destination addresses and + * the size of the BL33 image which will be loaded by BL31. + */ +struct morello_bl33_info { + uint32_t bl33_src_addr; + uint32_t bl33_dst_addr; + uint32_t bl33_size; +}; + +static scmi_channel_plat_info_t morello_scmi_plat_info = { + .scmi_mbx_mem = MORELLO_SCMI_PAYLOAD_BASE, + .db_reg_addr = PLAT_CSS_MHU_BASE + CSS_SCMI_MHU_DB_REG_OFF, + .db_preserve_mask = 0xfffffffe, + .db_modify_mask = 0x1, + .ring_doorbell = &mhu_ring_doorbell +}; + +scmi_channel_plat_info_t *plat_css_get_scmi_info() +{ + return &morello_scmi_plat_info; +} + +const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops) +{ + return css_scmi_override_pm_ops(ops); +} + +static void copy_bl33(uint32_t src, uint32_t dst, uint32_t size) +{ + unsigned int i; + + INFO("Copying BL33 to DDR memory...\n"); + for (i = 0U; i < size; (i = i + 8U)) + mmio_write_64((dst + i), mmio_read_64(src + i)); + + for (i = 0U; i < size; (i = i + 8U)) { + if (mmio_read_64(src + i) != mmio_read_64(dst + i)) { + ERROR("Copy failed!\n"); + panic(); + } + } + INFO("done\n"); +} + +void bl31_platform_setup(void) +{ + int ret; + struct morello_plat_info plat_info; + struct morello_bl33_info bl33_info; + + ret = sds_init(); + if (ret != SDS_OK) { + ERROR("SDS initialization failed. ret:%d\n", ret); + panic(); + } + + ret = sds_struct_read(MORELLO_SDS_PLATFORM_INFO_STRUCT_ID, + MORELLO_SDS_PLATFORM_INFO_OFFSET, + &plat_info, + MORELLO_SDS_PLATFORM_INFO_SIZE, + SDS_ACCESS_MODE_NON_CACHED); + if (ret != SDS_OK) { + ERROR("Error getting platform info from SDS. ret:%d\n", ret); + panic(); + } + + /* Validate plat_info SDS */ + if ((plat_info.local_ddr_size == 0U) + || (plat_info.local_ddr_size > MORELLO_MAX_DDR_CAPACITY_GB) + || (plat_info.remote_ddr_size > MORELLO_MAX_DDR_CAPACITY_GB) + || (plat_info.slave_count > MORELLO_MAX_SLAVE_COUNT)) { + ERROR("platform info SDS is corrupted\n"); + panic(); + } + + arm_bl31_platform_setup(); + + ret = sds_struct_read(MORELLO_SDS_BL33_INFO_STRUCT_ID, + MORELLO_SDS_BL33_INFO_OFFSET, + &bl33_info, + MORELLO_SDS_BL33_INFO_SIZE, + SDS_ACCESS_MODE_NON_CACHED); + if (ret != SDS_OK) { + ERROR("Error getting BL33 info from SDS. ret:%d\n", ret); + panic(); + } + copy_bl33(bl33_info.bl33_src_addr, + bl33_info.bl33_dst_addr, + bl33_info.bl33_size); + /* + * Pass platform information to BL33. This method is followed as + * currently there is no BL1/BL2 involved in boot flow of MORELLO. + * When TBBR is implemented for MORELLO, this method should be removed + * and platform information should be passed to BL33 using NT_FW_CONFIG + * passing mechanism. + */ + mmio_write_32(MORELLO_PLATFORM_INFO_BASE, *(uint32_t *)&plat_info); +} diff --git a/plat/arm/board/morello/morello_def.h b/plat/arm/board/morello/morello_def.h new file mode 100644 index 000000000..09db3032b --- /dev/null +++ b/plat/arm/board/morello/morello_def.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MORELLO_DEF_H +#define MORELLO_DEF_H + +/* Non-secure SRAM MMU mapping */ +#define MORELLO_NS_SRAM_BASE UL(0x06000000) +#define MORELLO_NS_SRAM_SIZE UL(0x00010000) +#define MORELLO_MAP_NS_SRAM MAP_REGION_FLAT( \ + MORELLO_NS_SRAM_BASE, \ + MORELLO_NS_SRAM_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +/* SDS Platform information defines */ +#define MORELLO_SDS_PLATFORM_INFO_STRUCT_ID U(8) +#define MORELLO_SDS_PLATFORM_INFO_OFFSET U(0) +#define MORELLO_SDS_PLATFORM_INFO_SIZE U(4) +#define MORELLO_MAX_DDR_CAPACITY_GB U(64) +#define MORELLO_MAX_SLAVE_COUNT U(16) + +/* SDS BL33 image information defines */ +#define MORELLO_SDS_BL33_INFO_STRUCT_ID U(9) +#define MORELLO_SDS_BL33_INFO_OFFSET U(0) +#define MORELLO_SDS_BL33_INFO_SIZE U(12) + +/* Base address of non-secure SRAM where Platform information will be filled */ +#define MORELLO_PLATFORM_INFO_BASE UL(0x06008000) + +#endif /* MORELLO_DEF_H */ diff --git a/plat/arm/board/morello/morello_interconnect.c b/plat/arm/board/morello/morello_interconnect.c new file mode 100644 index 000000000..d941bfe0f --- /dev/null +++ b/plat/arm/board/morello/morello_interconnect.c @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + + +/* + * For MORELLO which supports FCM (with automatic interconnect enter/exit), + * we should not do anything in these interface functions. + * They are used to override the weak functions in cci drivers. + */ + +/****************************************************************************** + * Helper function to initialize ARM interconnect driver. + *****************************************************************************/ +void plat_arm_interconnect_init(void) +{ +} + +/****************************************************************************** + * Helper function to place current master into coherency + *****************************************************************************/ +void plat_arm_interconnect_enter_coherency(void) +{ +} + +/****************************************************************************** + * Helper function to remove current master from coherency + *****************************************************************************/ +void plat_arm_interconnect_exit_coherency(void) +{ +} diff --git a/plat/arm/board/morello/morello_plat.c b/plat/arm/board/morello/morello_plat.c new file mode 100644 index 000000000..3830687a3 --- /dev/null +++ b/plat/arm/board/morello/morello_plat.c @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include "morello_def.h" + +/* + * Table of regions to map using the MMU. + * Replace or extend the below regions as required + */ + +const mmap_region_t plat_arm_mmap[] = { + ARM_MAP_SHARED_RAM, + MORELLO_MAP_DEVICE, + MORELLO_MAP_NS_SRAM, + ARM_MAP_DRAM1, + {0} +}; diff --git a/plat/arm/board/morello/morello_security.c b/plat/arm/board/morello/morello_security.c new file mode 100644 index 000000000..a388a8099 --- /dev/null +++ b/plat/arm/board/morello/morello_security.c @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * TZC programming is currently not done. + */ +void plat_arm_security_setup(void) +{ +} diff --git a/plat/arm/board/morello/morello_topology.c b/plat/arm/board/morello/morello_topology.c new file mode 100644 index 000000000..ef2f7534f --- /dev/null +++ b/plat/arm/board/morello/morello_topology.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +/* Compile time assertion to ensure the core count is 4 */ +CASSERT(PLATFORM_CORE_COUNT == 4U, assert_invalid_platform_core_count); + +/* Topology */ +typedef struct morello_topology { + const unsigned char *power_tree; + unsigned int plat_cluster_core_count; +} morello_topology_t; + +/* + * The power domain tree descriptor. The cluster power domains are + * arranged so that when the PSCI generic code creates the power domain tree, + * the indices of the CPU power domain nodes it allocates match the linear + * indices returned by plat_core_pos_by_mpidr(). + */ +const unsigned char morello_pd_tree_desc[] = { + PLAT_MORELLO_CHIP_COUNT, + PLAT_ARM_CLUSTER_COUNT, + MORELLO_MAX_CPUS_PER_CLUSTER, + MORELLO_MAX_CPUS_PER_CLUSTER, +}; + +/* Topology configuration for morello */ +const morello_topology_t morello_topology = { + .power_tree = morello_pd_tree_desc, + .plat_cluster_core_count = MORELLO_MAX_CPUS_PER_CLUSTER +}; + +/******************************************************************************* + * This function returns the topology tree information. + ******************************************************************************/ +const unsigned char *plat_get_power_domain_tree_desc(void) +{ + return morello_topology.power_tree; +} + +/******************************************************************************* + * This function returns the core count within the cluster corresponding to + * `mpidr`. + ******************************************************************************/ +unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr) +{ + return morello_topology.plat_cluster_core_count; +} + +/******************************************************************************* + * The array mapping platform core position (implemented by plat_my_core_pos()) + * to the SCMI power domain ID implemented by SCP. + ******************************************************************************/ +const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[PLATFORM_CORE_COUNT] = { + 0, 1, 2, 3}; diff --git a/plat/arm/board/morello/platform.mk b/plat/arm/board/morello/platform.mk new file mode 100644 index 000000000..f62cd6749 --- /dev/null +++ b/plat/arm/board/morello/platform.mk @@ -0,0 +1,66 @@ +# +# Copyright (c) 2020, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +MORELLO_BASE := plat/arm/board/morello + +INTERCONNECT_SOURCES := ${MORELLO_BASE}/morello_interconnect.c + +PLAT_INCLUDES := -I${MORELLO_BASE}/include + +MORELLO_CPU_SOURCES := lib/cpus/aarch64/rainier.S + +MORELLO_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ + drivers/arm/gic/v3/gicv3_main.c \ + drivers/arm/gic/v3/gicv3_helpers.c \ + plat/common/plat_gicv3.c \ + plat/arm/common/arm_gicv3.c \ + drivers/arm/gic/v3/gic600.c + +PLAT_BL_COMMON_SOURCES := ${MORELLO_BASE}/morello_plat.c \ + ${MORELLO_BASE}/aarch64/morello_helper.S + +BL31_SOURCES := ${MORELLO_CPU_SOURCES} \ + ${INTERCONNECT_SOURCES} \ + ${MORELLO_GIC_SOURCES} \ + ${MORELLO_BASE}/morello_bl31_setup.c \ + ${MORELLO_BASE}/morello_topology.c \ + ${MORELLO_BASE}/morello_security.c \ + drivers/arm/css/sds/sds.c + +FDT_SOURCES += fdts/morello-fvp.dts + +# TF-A not required to load the SCP Images +override CSS_LOAD_SCP_IMAGES := 0 + +# BL1/BL2 Image not a part of the capsule Image for morello +override NEED_BL1 := no +override NEED_BL2 := no +override NEED_BL2U := no + +#TF-A for morello starts from BL31 +override RESET_TO_BL31 := 1 + +# 32 bit mode not supported +override CTX_INCLUDE_AARCH32_REGS := 0 + +override ARM_PLAT_MT := 1 + +# Select SCMI/SDS drivers instead of SCPI/BOM driver for communicating with the +# SCP during power management operations and for SCP RAM Firmware transfer. +CSS_USE_SCMI_SDS_DRIVER := 1 + +# System coherency is managed in hardware +HW_ASSISTED_COHERENCY := 1 + +# When building for systems with hardware-assisted coherency, there's no need to +# use USE_COHERENT_MEM. Require that USE_COHERENT_MEM must be set to 0 too. +USE_COHERENT_MEM := 0 + +include plat/arm/common/arm_common.mk +include plat/arm/css/common/css_common.mk +include plat/arm/board/common/board_common.mk + +override ERRATA_N1_1542419 := 1 -- cgit v1.2.3 From 79d89e3da078fa0e169a47bcc360c5e3308cdf42 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 7 Sep 2020 14:53:58 +0100 Subject: drivers: arm: gicv3: Allow detecting number of cores A GICv3 interrupt controller will be instantiated for a certain number of cores. This will result in the respective number of GICR frames. The last frame will have the "Last" bit set in its GICR_TYPER register. For platforms with a topology unknown at build time (the Arm FPGAs, for instance), we need to learn the number of used cores at runtime, to size the GICR region in the devicetree accordingly. Add a generic function that iterates over all GICR frames until it encounters one with the "Last" bit set. It returns the number of cores the GICv3 has been configured for. Change-Id: I79f033c50dfc1c275aba7122725868811abcc4f8 Signed-off-by: Andre Przywara --- drivers/arm/gic/v3/gicv3_helpers.c | 30 ++++++++++++++++++++++++++++++ include/drivers/arm/gicv3.h | 1 + 2 files changed, 31 insertions(+) diff --git a/drivers/arm/gic/v3/gicv3_helpers.c b/drivers/arm/gic/v3/gicv3_helpers.c index 09fa6786e..ff346f9df 100644 --- a/drivers/arm/gic/v3/gicv3_helpers.c +++ b/drivers/arm/gic/v3/gicv3_helpers.c @@ -326,3 +326,33 @@ unsigned int gicv3_secure_ppi_sgi_config_props(uintptr_t gicr_base, return ctlr_enable; } + +/** + * gicv3_rdistif_get_number_frames() - determine size of GICv3 GICR region + * @gicr_frame: base address of the GICR region to check + * + * This iterates over the GICR_TYPER registers of multiple GICR frames in + * a GICR region, to find the instance which has the LAST bit set. For most + * systems this corresponds to the number of cores handled by a redistributor, + * but there could be disabled cores among them. + * It assumes that each GICR region is fully accessible (till the LAST bit + * marks the end of the region). + * If a platform has multiple GICR regions, this function would need to be + * called multiple times, providing the respective GICR base address each time. + * + * Return: number of valid GICR frames (at least 1, up to PLATFORM_CORE_COUNT) + ******************************************************************************/ +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) { + break; + } + rdistif_base += (1U << GICR_PCPUBASE_SHIFT); + } + + return count; +} diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h index 18d5b73e2..d8ac4cb33 100644 --- a/include/drivers/arm/gicv3.h +++ b/include/drivers/arm/gicv3.h @@ -488,6 +488,7 @@ void gicv3_distif_init(void); void gicv3_rdistif_init(unsigned int proc_num); void gicv3_rdistif_on(unsigned int proc_num); void gicv3_rdistif_off(unsigned int proc_num); +unsigned int gicv3_rdistif_get_number_frames(const uintptr_t gicr_frame); void gicv3_cpuif_enable(unsigned int proc_num); void gicv3_cpuif_disable(unsigned int proc_num); unsigned int gicv3_get_pending_interrupt_type(void); -- cgit v1.2.3 From 9f7bab42a103a44246116d89a3cca20ed935467c Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 24 Aug 2020 18:28:44 +0100 Subject: fdt: Add function to adjust GICv3 redistributor size We now have code to detect the CPU topology at runtime, and can also populate the CPU nodes in a devicetree accordingly. This is used by the ARM FPGA port, for instance. But also a GICv3 compatible interrupt controller provides MMIO frames per core, so the size of this region needs to be adjusted in the DT, to match the number of cores as well. Provide a generic function to find the GICv3 interrupt controller in the DT, then adjust the "reg" entry to match the number of detected cores. Since the size of the GICR frame per cores differs between GICv4 and GICv3, this size is supplied as a parameter to the function. The caller should determine the applicable value by either hardcoding it or by observing GICR_TYPER.VLPIS. Change-Id: Ic2a6445c2c5381a36bf24263f52fcbefad378c05 Signed-off-by: Andre Przywara --- common/fdt_fixup.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++ include/common/fdt_fixup.h | 2 ++ 2 files changed, 63 insertions(+) diff --git a/common/fdt_fixup.c b/common/fdt_fixup.c index 980e60d45..a1604e74f 100644 --- a/common/fdt_fixup.c +++ b/common/fdt_fixup.c @@ -377,3 +377,64 @@ int fdt_add_cpus_node(void *dtb, unsigned int afflv0, return offs; } + +/** + * 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_frame_size: Size of the GICR frame per core + * + * On a GICv3 compatible interrupt controller, the redistributor provides + * a number of 64k pages per each supported core. So with a dynamic topology, + * this size cannot be known upfront and thus can't be hardcoded into the DTB. + * + * Find the DT node describing the GICv3 interrupt controller, and adjust + * the size of the redistributor to match the number of actual cores on + * this system. + * 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. + * + * Return: 0 on success, negative error value otherwise. + */ +int fdt_adjust_gic_redist(void *dtb, unsigned int nr_cores, + 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; + void *val; + int parent; + int ac, sc; + + if (offset < 0) { + return offset; + } + + parent = fdt_parent_offset(dtb, offset); + if (parent < 0) { + return parent; + } + ac = fdt_address_cells(dtb, parent); + sc = fdt_size_cells(dtb, parent); + if (ac < 0 || sc < 0) { + return -EINVAL; + } + + if (sc == 1) { + redist_size_32 = cpu_to_fdt32(nr_cores * gicr_frame_size); + val = &redist_size_32; + } else { + redist_size_64 = cpu_to_fdt64(nr_cores * gicr_frame_size); + val = &redist_size_64; + } + + /* + * The redistributor is described in the second "reg" entry. + * So we have to skip one address and one size cell, then another + * address cell to get to the second size cell. + */ + return fdt_setprop_inplace_namelen_partial(dtb, offset, "reg", 3, + (ac + sc + ac) * 4, + val, sc * 4); +} diff --git a/include/common/fdt_fixup.h b/include/common/fdt_fixup.h index 29d8b3aa0..2e9d49d53 100644 --- a/include/common/fdt_fixup.h +++ b/include/common/fdt_fixup.h @@ -13,5 +13,7 @@ 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, + unsigned int gicr_frame_size); #endif /* FDT_FIXUP_H */ -- cgit v1.2.3 From 283e5595afa28a5930ac5f0dcdf7c18804221070 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 24 Aug 2020 18:34:50 +0100 Subject: arm_fpga: Adjust GICR size in DT to match number of cores The size of a GICv3 redistributor region depends on the number of cores in the system. For the ARM FPGA port, we detect the topology at runtime, and adjust the CPU DT nodes accordingly. Now the size of the GICR region must also be adjusted, or Linux will fail to initialise the GICv3. Use the newly introduced function to overwrite the GICR size entry in the GICv3 reg property. We count the number of existing cores by iterating over the GICR frames until we find the LAST bit set in TYPER. Change-Id: Ib69565600859de9b1b15ceb8495172cd26d16fce Signed-off-by: Andre Przywara --- plat/arm/board/arm_fpga/fpga_bl31_setup.c | 11 +++++++++++ plat/arm/board/arm_fpga/fpga_gicv3.c | 5 +++++ plat/arm/board/arm_fpga/fpga_private.h | 1 + 3 files changed, 17 insertions(+) diff --git a/plat/arm/board/arm_fpga/fpga_bl31_setup.c b/plat/arm/board/arm_fpga/fpga_bl31_setup.c index de6d9d5e3..d5478d2d6 100644 --- a/plat/arm/board/arm_fpga/fpga_bl31_setup.c +++ b/plat/arm/board/arm_fpga/fpga_bl31_setup.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -210,6 +211,16 @@ static void fpga_prepare_dtb(void) if (err < 0) { ERROR("Error %d creating the /cpus DT node\n", err); panic(); + } else { + unsigned int nr_cores = fpga_get_nr_gic_cores(); + + INFO("Adjusting GICR DT region to cover %u cores\n", + nr_cores); + err = fdt_adjust_gic_redist(fdt, nr_cores, + 1U << GICR_PCPUBASE_SHIFT); + 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 9fb5fa935..bfc116bef 100644 --- a/plat/arm/board/arm_fpga/fpga_gicv3.c +++ b/plat/arm/board/arm_fpga/fpga_gicv3.c @@ -77,3 +77,8 @@ void fpga_pwr_gic_off(void) gicv3_cpuif_disable(plat_my_core_pos()); gicv3_rdistif_off(plat_my_core_pos()); } + +unsigned int fpga_get_nr_gic_cores(void) +{ + return gicv3_rdistif_get_number_frames(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 47059d64a..1ca241f26 100644 --- a/plat/arm/board/arm_fpga/fpga_private.h +++ b/plat/arm/board/arm_fpga/fpga_private.h @@ -24,6 +24,7 @@ void plat_fpga_gic_init(void); 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); #endif /* __ASSEMBLER__ */ -- cgit v1.2.3 From 40a0de1972bc9a12470b10bc08b7174e4990b30c Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 3 Aug 2020 12:55:28 +0100 Subject: arm_fpga: Remove SPE PMU DT node if SPE is not available The Statistical Profiling Extension (SPE) is an architectural feature we can safely detect at runtime. However it still relies on one piece of platform-specific information: the interrupt line it is connected to. This requires SPE to be described in a devicetree node. Since SPE support varies with the CPU cores found on an FPGA image, we should detect the presence of SPE at runtime, and remove a potentially existing SPE PMU node from the DT. This allows to always have the SPE node in a generic devicetree file, without risking exposing it on a CPU without this feature. Change-Id: I73d83ea8509b03fe7bba20b9cce8d1335035fa31 Signed-off-by: Andre Przywara --- plat/arm/board/arm_fpga/fpga_bl31_setup.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/plat/arm/board/arm_fpga/fpga_bl31_setup.c b/plat/arm/board/arm_fpga/fpga_bl31_setup.c index d5478d2d6..a5f5ea0f3 100644 --- a/plat/arm/board/arm_fpga/fpga_bl31_setup.c +++ b/plat/arm/board/arm_fpga/fpga_bl31_setup.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include "fpga_private.h" @@ -224,6 +225,16 @@ static void fpga_prepare_dtb(void) } } + /* 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, + "arm,statistical-profiling-extension-v1"); + + 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); -- cgit v1.2.3 From b48883c79a7abd1495ba55c3d0dcc95464c30c7e Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 3 Aug 2020 12:54:58 +0100 Subject: arm_fpga: Add devicetree file The FPGA images used in Arm Ltd. focus on CPU cores, so they share a common platform, with a minimal set of peripherals (interconnect, GIC, UART). This allows to support most platforms with a single devicetree file. The topology and number of CPU cores differ, but those will added at runtime, in BL31. Other adjustments (GICR size, SPE node, command line) are also done at this point. Add the common devicetree file to TF-A's build system, so it can be build together with BL31. At runtime, the resulting .dtb file should be uploaded to the address given with FPGA_PRELOADED_DTB_BASE at build time. Change-Id: I3206d6131059502ec96896e95329865452c9d83e Signed-off-by: Andre Przywara --- fdts/arm_fpga.dts | 102 ++++++++++++++++++++++++++++++++++++ plat/arm/board/arm_fpga/platform.mk | 2 + 2 files changed, 104 insertions(+) create mode 100644 fdts/arm_fpga.dts diff --git a/fdts/arm_fpga.dts b/fdts/arm_fpga.dts new file mode 100644 index 000000000..6a966fd85 --- /dev/null +++ b/fdts/arm_fpga.dts @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: (GPL-2.0 or BSD-3-Clause) +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * Devicetree for the Arm Ltd. FPGA platform + * Number and kind of CPU cores differs from image to image, so the + * topology is auto-detected by BL31, and the /cpus node is created and + * populated accordingly at runtime. + */ + +#include + +/dts-v1/; + +/ { + model = "ARM FPGA"; + compatible = "arm,fpga", "arm,vexpress"; + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + aliases { + serial0 = &dbg_uart; + }; + + chosen { + stdout-path = "serial0:38400n8"; + bootargs = "console=ttyAMA0,38400n8 earlycon"; + /* Allow to upload a generous 100MB initrd payload. */ + linux,initrd-start = <0x0 0x84000000>; + linux,initrd-end = <0x0 0x85400000>; + }; + + /* /cpus node will be added by BL31 at runtime. */ + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; + + timer { + compatible = "arm,armv8-timer"; + clock-frequency = <10000000>; + interrupts = , + , + , + ; + }; + + pmu { + compatible = "arm,armv8-pmuv3"; + interrupts = ; + }; + + /* This node will be removed at runtime on cores without SPE. */ + spe-pmu { + compatible = "arm,statistical-profiling-extension-v1"; + interrupts = ; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x0 0x80000000 0x0 0x80000000>, + <0x8 0x80000000 0x1 0x80000000>; + }; + + + bus_refclk: refclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <100000000>; + clock-output-names = "apb_pclk"; + }; + + uartclk: baudclock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <10000000>; + clock-output-names = "uartclk"; + }; + + dbg_uart: serial@7ff80000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0 0x7ff80000 0x0 0x00001000>; + interrupts = ; + clocks = <&uartclk>, <&bus_refclk>; + clock-names = "uartclk", "apb_pclk"; + }; + + gic: interrupt-controller@30000000 { + compatible = "arm,gic-v3"; + #address-cells = <2>; + #interrupt-cells = <3>; + #size-cells = <2>; + ranges; + interrupt-controller; + reg = <0x0 0x30000000 0x0 0x00010000>, /* GICD */ + /* The GICR size will be adjusted at runtime to match the cores. */ + <0x0 0x30040000 0x0 0x00020000>; /* GICR for one core */ + interrupts = ; + }; +}; diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk index 890433983..daf9f9f58 100644 --- a/plat/arm/board/arm_fpga/platform.mk +++ b/plat/arm/board/arm_fpga/platform.mk @@ -81,6 +81,8 @@ FPGA_GIC_SOURCES := ${GICV3_SOURCES} \ plat/common/plat_gicv3.c \ plat/arm/board/arm_fpga/fpga_gicv3.c +FDT_SOURCES := fdts/arm_fpga.dts + PLAT_INCLUDES := -Iplat/arm/board/arm_fpga/include PLAT_BL_COMMON_SOURCES := plat/arm/board/arm_fpga/${ARCH}/fpga_helpers.S -- cgit v1.2.3 From f45c6d8623309a256718212a1a2c72ad5efe925d Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 3 Aug 2020 13:06:38 +0100 Subject: arm_fpga: Add ROM trampoline The application cores of the FPGAs used in Arm Ltd. start execution at address 0x0. This is the location of some (emulated) ROM area (which can be written to by the uploading tool). Since the arm_fpga port is configured to run from DRAM, we load BL31 to the beginning of DRAM (mapped at 2GB). This requires some small trampoline code in the "ROM" to jump to the BL31 entry point. To avoid some extra magic binary, add a tiny assembly file with that trivial jump instruction to the tree, so this binary can be created alongside BL31. Change-Id: I9e4439fc0f093fa24dd49a8377c9edb030fbb477 Signed-off-by: Andre Przywara --- plat/arm/board/arm_fpga/platform.mk | 2 ++ plat/arm/board/arm_fpga/rom_trampoline.S | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 plat/arm/board/arm_fpga/rom_trampoline.S diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk index daf9f9f58..f3be3cd32 100644 --- a/plat/arm/board/arm_fpga/platform.mk +++ b/plat/arm/board/arm_fpga/platform.mk @@ -100,4 +100,6 @@ 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)) + all: bl31 diff --git a/plat/arm/board/arm_fpga/rom_trampoline.S b/plat/arm/board/arm_fpga/rom_trampoline.S new file mode 100644 index 000000000..cd66c7927 --- /dev/null +++ b/plat/arm/board/arm_fpga/rom_trampoline.S @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * The Arm Ltd. FPGA images start execution at address 0x0, which is + * mapped at an (emulated) ROM image. The payload uploader can write to + * this memory, but write access by the CPU cores is prohibited. + * + * Provide a simple trampoline to start BL31 execution at the actual + * load address. We put the DTB address in x0, so any code in DRAM could + * make use of that information (not yet used in BL31 right now). + */ + +#include +#include + +.text +.global _start + +_start: + mov_imm x1, BL31_BASE /* beginning of DRAM */ + mov_imm x0, FPGA_PRELOADED_DTB_BASE + br x1 -- cgit v1.2.3 From 01301b116ea32c6529a69bfc679cab2d2fdaa4d9 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Wed, 16 Sep 2020 17:13:33 +0100 Subject: arm_fpga: Add post-build linker script For the Arm Ltd. FPGAs to run, we need to load several payloads into the FPGA's memory: - Some trampoline code at address 0x0, to jump to BL31's entry point. - The actual BL31 binary at the beginning of DRAM. - The (generic) DTB image to describe the hardware. - The actual non-secure payloads (kernel, ramdisks, ...) The latter is application specific, but the first three blobs are rather generic. Since the uploader tool supports ELF binaries, it seems helpful to combine these three images into one .axf file, as this also simplifies the command line. Add a post-build linker script, that combines those three bits into one ELF file, together with their specific load addresses. Include a call to "ld" with this linker script in the platform Makefile, so it will be build automatically. The result will be called "bl31.axf". Change-Id: I4a90da16fa1e0e83b51d19e5b1daf61f5a0bbfca Signed-off-by: Andre Przywara --- plat/arm/board/arm_fpga/build_axf.ld.S | 47 ++++++++++++++++++++++++++++++++++ plat/arm/board/arm_fpga/platform.mk | 7 ++++- 2 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 plat/arm/board/arm_fpga/build_axf.ld.S diff --git a/plat/arm/board/arm_fpga/build_axf.ld.S b/plat/arm/board/arm_fpga/build_axf.ld.S new file mode 100644 index 000000000..d7cd00882 --- /dev/null +++ b/plat/arm/board/arm_fpga/build_axf.ld.S @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Linker script for the Arm Ltd. FPGA boards to generate an ELF file that + * contains the ROM trampoline, BL31 and the DTB. + * + * This allows to pass just one file to the uploader tool, and automatically + * provides the correct load addresses. + */ + +#include + +OUTPUT_FORMAT("elf64-littleaarch64") +OUTPUT_ARCH(aarch64) + +INPUT(./bl31/bl31.elf) +INPUT(./rom_trampoline.o) + +TARGET(binary) +INPUT(./fdts/arm_fpga.dtb) + +ENTRY(_start) + +SECTIONS +{ + .rom (0x0): { + *rom_trampoline.o(.text*) + KEEP(*(.rom)) + } + + .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): { + ASSERT(. == ALIGN(8), "DTB address is not 8-byte aligned"); + *arm_fpga.dtb + } + + /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 f3be3cd32..ad9001b56 100644 --- a/plat/arm/board/arm_fpga/platform.mk +++ b/plat/arm/board/arm_fpga/platform.mk @@ -101,5 +101,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_LD,$(BUILD_PLAT)/build_axf.ld,plat/arm/board/arm_fpga/build_axf.ld.S,31)) -all: bl31 +bl31.axf: bl31 dtbs ${BUILD_PLAT}/rom_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 + +all: bl31.axf -- cgit v1.2.3 From a6c07e0ddfa3658d7bc0ad1693b6e908293c1c96 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 27 Aug 2020 12:13:30 +0100 Subject: arm_fpga: Add platform documentation As the Arm Ltd. FPGA port is now working for all existing images, add some documentation file. Change-Id: I9e2c532ed15bbc121bb54b3dfc1bdfee8f1443a6 Signed-off-by: Andre Przywara --- docs/plat/arm/arm_fpga/index.rst | 97 ++++++++++++++++++++++++++++++++++++++++ docs/plat/arm/index.rst | 1 + 2 files changed, 98 insertions(+) create mode 100644 docs/plat/arm/arm_fpga/index.rst diff --git a/docs/plat/arm/arm_fpga/index.rst b/docs/plat/arm/arm_fpga/index.rst new file mode 100644 index 000000000..5427c1dde --- /dev/null +++ b/docs/plat/arm/arm_fpga/index.rst @@ -0,0 +1,97 @@ +Arm FPGA Platform +================= + +This platform supports FPGA images used internally in Arm Ltd., for +testing and bringup of new cores. With that focus, peripheral support is +minimal: there is no mass storage or display output, for instance. Also +this port ignores any power management features of the platform. +Some interconnect setup is done internally by the platform, so the TF-A code +just needs to setup UART and GIC. + +The FPGA platform requires to pass on a DTB for the non-secure payload +(mostly Linux), so we let TF-A use information from the DTB for dynamic +configuration: the UART and GIC base addresses are read from there. + +As a result this port is a fairly generic BL31-only port, which can serve +as a template for a minimal new (and possibly DT-based) platform port. + +The aim of this port is to support as many FPGA images as possible with +a single build. Image specific data must be described in the DTB or should +be auto-detected at runtime. + +As the number and topology layout of the CPU cores differs significantly +across the various images, this is detected at runtime by BL31. +The /cpus node in the DT will be added and filled accordingly, as long as +it does not exist already. + +Platform-specific build options +------------------------------- + +- ``SUPPORT_UNKNOWN_MPID`` : Boolean option to allow unknown MPIDR registers. + Normally TF-A panics if it encounters a MPID value not matched to its + internal list, but for new or experimental cores this creates a lot of + churn. With this option, the code will fall back to some basic CPU support + code (only architectural system registers, and no errata). + Default value of this flag is 1. + +- ``PRELOADED_BL33_BASE`` : Physical address of the BL33 non-secure payload. + It must have been loaded into DRAM already, typically this is done by + the script that also loads BL31 and the DTB. + It defaults to 0x80080000, which is the traditional load address for an + arm64 Linux kernel. + +- ``FPGA_PRELOADED_DTB_BASE`` : Physical address of the flattened device + tree blob (DTB). This DT will be used by TF-A for dynamic configuration, + so it must describe at least the UART and a GICv3 interrupt controller. + The DT gets amended by the code, to potentially add a command line and + fill the CPU topology nodes. It will also be passed on to BL33, by + putting its address into the x0 register before jumping to the entry + point (following the Linux kernel boot protocol). + It defaults to 0x80070000, which is 64KB before the BL33 load address. + +- ``FPGA_PRELOADED_CMD_LINE`` : Physical address of the command line to + put into the devicetree blob. Due to the lack of a proper bootloader, + a command line can be put somewhere into memory, so that BL31 will + detect it and copy it into the DTB passed on to BL33. + To avoid random garbage, there needs to be a "CMD:" signature before the + actual command line. + Defaults to 0x1000, which is normally in the "ROM" space of the typical + FPGA image (which can be written by the FPGA payload uploader, but is + read-only to the CPU). The FPGA payload tool should be given a text file + containing the desired command line, prefixed by the "CMD:" signature. + +Building the TF-A image +----------------------- + + .. code:: shell + + make PLAT=arm_fgpa DEBUG=1 + + This will use the default load addresses as described above. When those + addresses need to differ for a certain setup, they can be passed on the + make command line: + + .. code:: shell + + make PLAT=arm_fgpa DEBUG=1 PRELOADED_BL33_BASE=0x80200000 FPGA_PRELOADED_DTB_BASE=0x80180000 bl31 + +Running the TF-A image +---------------------- + +After building TF-A, the actual TF-A code will be located in ``bl31.bin`` in +the build directory. +Additionally there is a ``bl31.axf`` ELF file, which contains BL31, as well +as some simple ROM trampoline code (required by the Arm FPGA boot flow) and +a generic DTB to support most of the FPGA images. This can be simply handed +over to the FPGA payload uploader, which will take care of loading the +components at their respective load addresses. In addition to this file +you need at least a BL33 payload (typically a Linux kernel image), optionally +a Linux initrd image file and possibly a command line: + + .. code:: shell + + fpga-run ... -m bl31.axf -l auto -m Image -l 0x80080000 -m initrd.gz -l 0x84000000 -m cmdline.txt -l 0x1000 + +-------------- + +*Copyright (c) 2020, Arm Limited. All rights reserved.* diff --git a/docs/plat/arm/index.rst b/docs/plat/arm/index.rst index 1afe475c6..9c2fcb102 100644 --- a/docs/plat/arm/index.rst +++ b/docs/plat/arm/index.rst @@ -9,6 +9,7 @@ Arm Development Platforms fvp/index fvp-ve/index tc0/index + arm_fpga/index arm-build-options This chapter holds documentation related to Arm's development platforms, -- cgit v1.2.3 From ea14b51b838df0df1253df9259982bd57f26669e Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Mon, 21 Sep 2020 12:23:54 +0100 Subject: Crypto library: Migrate support to MbedTLS v2.24.0 This patch migrates the mbedcrypto dependency for TF-A to mbedTLS repo v2.24.0 which is the latest release tag. The relevant documentation is updated to reflect the use of new version. Change-Id: I116f44242e8c98e856416ea871d11abd3234dac1 Signed-off-by: Alexei Fedorov --- docs/getting_started/prerequisites.rst | 2 +- drivers/auth/mbedtls/mbedtls_common.mk | 3 +-- include/drivers/auth/mbedtls/mbedtls_config.h | 9 ++++++++- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/getting_started/prerequisites.rst b/docs/getting_started/prerequisites.rst index 13e25cd0e..91ecdf31c 100644 --- a/docs/getting_started/prerequisites.rst +++ b/docs/getting_started/prerequisites.rst @@ -60,7 +60,7 @@ supporting tools: The following libraries are required for Trusted Board Boot support: -- mbed TLS == 2.18.0 (tag: ``mbedtls-2.18.0``) +- mbed TLS == 2.24.0 (tag: ``mbedtls-2.24.0``) These tools are optional: diff --git a/drivers/auth/mbedtls/mbedtls_common.mk b/drivers/auth/mbedtls/mbedtls_common.mk index 8454105c2..53ebe30b6 100644 --- a/drivers/auth/mbedtls/mbedtls_common.mk +++ b/drivers/auth/mbedtls/mbedtls_common.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2015-2020, Arm Limited. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -35,7 +35,6 @@ LIBMBEDTLS_SRCS := $(addprefix ${MBEDTLS_DIR}/library/, \ bignum.c \ gcm.c \ md.c \ - md_wrap.c \ pk.c \ pk_wrap.c \ pkparse.c \ diff --git a/include/drivers/auth/mbedtls/mbedtls_config.h b/include/drivers/auth/mbedtls/mbedtls_config.h index dc00da7d6..ad39fa906 100644 --- a/include/drivers/auth/mbedtls/mbedtls_config.h +++ b/include/drivers/auth/mbedtls/mbedtls_config.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -63,6 +63,7 @@ #define MBEDTLS_ECDSA_C #define MBEDTLS_ECP_C #define MBEDTLS_ECP_DP_SECP256R1_ENABLED +#define MBEDTLS_ECP_NO_INTERNAL_RNG #endif #if TF_MBEDTLS_USE_RSA #define MBEDTLS_RSA_C @@ -101,6 +102,12 @@ /* Memory buffer allocator options */ #define MBEDTLS_MEMORY_ALIGN_MULTIPLE 8 +/* + * Prevent the use of 128-bit division which + * creates dependency on external libraries. + */ +#define MBEDTLS_NO_UDBL_DIVISION + #ifndef __ASSEMBLER__ /* System headers required to build mbed TLS with the current configuration */ #include -- cgit v1.2.3 From 6c07a9273b5e66d7234ecc52195f8eefbfe88205 Mon Sep 17 00:00:00 2001 From: Chandni Cherukuri Date: Thu, 1 Oct 2020 10:11:44 +0530 Subject: morello: Add changes to fix build of Morello Platform This patch makes changes required to get the morello platform working with the tip of TF-A. Change-Id: I095006615c9959bba49fcc75b52e1de7d7486309 Signed-off-by: Chandni Cherukuri --- plat/arm/board/morello/include/platform_def.h | 3 +++ plat/arm/board/morello/morello_bl31_setup.c | 2 +- plat/arm/board/morello/platform.mk | 11 +++++++---- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/plat/arm/board/morello/include/platform_def.h b/plat/arm/board/morello/include/platform_def.h index 07c06a10c..9ca75ffe7 100644 --- a/plat/arm/board/morello/include/platform_def.h +++ b/plat/arm/board/morello/include/platform_def.h @@ -93,4 +93,7 @@ #define PLAT_ARM_GICC_BASE UL(0x2C000000) #define PLAT_ARM_GICR_BASE UL(0x300C0000) +/* Number of SCMI channels on the platform */ +#define PLAT_ARM_SCMI_CHANNEL_COUNT U(1) + #endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/morello/morello_bl31_setup.c b/plat/arm/board/morello/morello_bl31_setup.c index 43f5f7fc7..5b91e87e1 100644 --- a/plat/arm/board/morello/morello_bl31_setup.c +++ b/plat/arm/board/morello/morello_bl31_setup.c @@ -48,7 +48,7 @@ static scmi_channel_plat_info_t morello_scmi_plat_info = { .ring_doorbell = &mhu_ring_doorbell }; -scmi_channel_plat_info_t *plat_css_get_scmi_info() +scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id) { return &morello_scmi_plat_info; } diff --git a/plat/arm/board/morello/platform.mk b/plat/arm/board/morello/platform.mk index f62cd6749..2a23bc60f 100644 --- a/plat/arm/board/morello/platform.mk +++ b/plat/arm/board/morello/platform.mk @@ -12,12 +12,15 @@ PLAT_INCLUDES := -I${MORELLO_BASE}/include MORELLO_CPU_SOURCES := lib/cpus/aarch64/rainier.S -MORELLO_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v3/gicv3_main.c \ - drivers/arm/gic/v3/gicv3_helpers.c \ +# GIC-600 configuration +GICV3_SUPPORT_GIC600 := 1 + +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk + +MORELLO_GIC_SOURCES := ${GICV3_SOURCES} \ plat/common/plat_gicv3.c \ plat/arm/common/arm_gicv3.c \ - drivers/arm/gic/v3/gic600.c PLAT_BL_COMMON_SOURCES := ${MORELLO_BASE}/morello_plat.c \ ${MORELLO_BASE}/aarch64/morello_helper.S -- cgit v1.2.3 From 219e45cdd2404c6553b475b315167dda51f74227 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Fri, 2 Oct 2020 10:07:00 +0200 Subject: doc: stm32mp1: Improve OP-TEE related documentation stm32mp15_optee_defconfig has been dropped from U-Boot as it became identical to stm32mp15_trusted_defconfig. Furthermore give a hint how OP-TEE is supposed to be installed. Signed-off-by: Jan Kiszka Change-Id: Id8f0bd84a87e3a62072dd4405aadddcdd3511213 --- docs/plat/stm32mp1.rst | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/plat/stm32mp1.rst b/docs/plat/stm32mp1.rst index 2c372a6a3..263867c25 100644 --- a/docs/plat/stm32mp1.rst +++ b/docs/plat/stm32mp1.rst @@ -101,7 +101,7 @@ To build TF-A with OP-TEE support for all bootable devices: cd make CROSS_COMPILE=arm-linux-gnueabihf- ARCH=arm PLATFORM=stm32mp1 CFG_EMBED_DTB_SOURCE_FILE=stm32mp157c-ev1.dts cd - make stm32mp15_optee_defconfig + make stm32mp15_trusted_defconfig make DEVICE_TREE=stm32mp157c-ev1 all @@ -121,5 +121,11 @@ It should contain at least those partitions: Usually, two copies of fsbl are used (fsbl1 and fsbl2) instead of one partition fsbl. +OP-TEE artifacts go into separate partitions as follows: + +- teeh: tee-header_v2.stm32 +- teed: tee-pageable_v2.stm32 +- teex: tee-pager_v2.stm32 + .. _STM32MP1 Series: https://www.st.com/en/microcontrollers-microprocessors/stm32mp1-series.html -- cgit v1.2.3 From ccf220adcbe393de148efc50462b157685478f13 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Fri, 2 Oct 2020 07:27:27 +0100 Subject: doc: Update list of supported FVP platforms Updated the list of supported FVP platform as per latest FVP platform release. Signed-off-by: Manish V Badarkhe Change-Id: I45ef79aff147ed598a3a92ab6f6b277f7f70604a --- docs/plat/arm/fvp/index.rst | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/plat/arm/fvp/index.rst b/docs/plat/arm/fvp/index.rst index e3bf42ad9..3a13268fa 100644 --- a/docs/plat/arm/fvp/index.rst +++ b/docs/plat/arm/fvp/index.rst @@ -12,8 +12,9 @@ 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.9 Build 41, unless otherwise stated. + The FVP models used are Version 11.12 Build 38, unless otherwise stated. +- ``FVP_Base_AEMvA`` - ``FVP_Base_AEMv8A-AEMv8A`` - ``FVP_Base_AEMv8A-AEMv8A-AEMv8A-AEMv8A-CCN502`` - ``FVP_Base_RevC-2xAEMv8A`` @@ -37,22 +38,26 @@ Arm FVPs without shifted affinities, and that do not support threaded CPU cores - ``FVP_Base_Cortex-A76AEx4`` - ``FVP_Base_Cortex-A76AEx8`` - ``FVP_Base_Cortex-A77x4`` +- ``FVP_Base_Cortex-A78x4`` - ``FVP_Base_Neoverse-E1x1`` - ``FVP_Base_Neoverse-E1x2`` - ``FVP_Base_Neoverse-E1x4`` - ``FVP_Base_Neoverse-N1x4`` -- ``FVP_Base_Zeusx4`` +- ``FVP_Base_Neoverse-V1x4`` - ``FVP_CSS_SGI-575`` (Version 11.10 build 36) - ``FVP_CSS_SGM-775`` -- ``FVP_RD_E1_edge`` (Version 11.10 build 36) +- ``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.10 build 36) +- ``FVP_TC0`` (Version 0.0 build 6114) - ``Foundation_Platform`` 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 CPU cores (64-bit host machine only). +- ``FVP_Base_AEMvA`` - ``FVP_Base_AEMv8A-AEMv8A`` - ``FVP_Base_Cortex-A32x4`` -- cgit v1.2.3 From 8445253e3ff0f17e04bb0dd8d0744548481cb795 Mon Sep 17 00:00:00 2001 From: Chandni Cherukuri Date: Thu, 1 Oct 2020 13:10:45 +0530 Subject: morello: Add Morello platform documentation Morello platform has a SCP which brings the primary Rainier CPU out of reset which starts executing at BL31. This patch provides documentation support for Morello platform. Signed-off-by: Chandni Cherukuri Change-Id: I38f596668e2b14862d543fabc04549ff34bfb8a2 --- docs/plat/arm/index.rst | 1 + docs/plat/arm/morello/index.rst | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 docs/plat/arm/morello/index.rst diff --git a/docs/plat/arm/index.rst b/docs/plat/arm/index.rst index 9c2fcb102..f72992b80 100644 --- a/docs/plat/arm/index.rst +++ b/docs/plat/arm/index.rst @@ -11,6 +11,7 @@ Arm Development Platforms tc0/index arm_fpga/index arm-build-options + morello/index This chapter holds documentation related to Arm's development platforms, including both software models (FVPs) and hardware development boards diff --git a/docs/plat/arm/morello/index.rst b/docs/plat/arm/morello/index.rst new file mode 100644 index 000000000..b18001cae --- /dev/null +++ b/docs/plat/arm/morello/index.rst @@ -0,0 +1,33 @@ +Morello Platform +================ + +Morello is an ARMv8-A platform that implements the capability architecture extension. +The platform port present at `site `_ +provides ARMv8-A architecture enablement. + +Capability architecture specific changes will be added `here `_ + +Further information on Morello Platform is available at `info `_ + +Boot Sequence +------------- + +The execution begins from SCP_BL1 which loads the SCP_BL2 and starts its +execution. SCP_BL2 powers up the AP which starts execution at AP_BL31. The AP +then continues executing and hands off execution to Non-secure world (UEFI). + +Build Procedure (TF-A only) +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Obtain arm `toolchain `_. + Set the CROSS_COMPILE environment variable to point to the toolchain folder. + +- Build TF-A: + + .. code:: shell + + export CROSS_COMPILE=/bin/aarch64-none-elf- + + make PLAT=morello all + +*Copyright (c) 2020, Arm Limited. All rights reserved.* -- cgit v1.2.3 From 6e4da01ffbf42bf97933d72868f38aa378313698 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Fri, 2 Oct 2020 11:54:56 +0100 Subject: spmd: Fix signedness comparison warning With -Wsign-compare, compilers issue a warning in the SPMD code: ==================== services/std_svc/spmd/spmd_pm.c:35:22: error: comparison of integer expressions of different signedness: 'int' and 'unsigned int' [-Werror=sign-compare] 35 | if ((id < 0) || (id >= PLATFORM_CORE_COUNT)) { | ^~ cc1: all warnings being treated as errors ==================== Since we just established that "id" is positive, we can safely cast it to an unsigned type to make the comparison have matching types. Change-Id: I6ef24804c88136d7e3f15de008e4fea854f10ffe Signed-off-by: Andre Przywara --- services/std_svc/spmd/spmd_pm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/std_svc/spmd/spmd_pm.c b/services/std_svc/spmd/spmd_pm.c index 64ddbe5f4..5433e5d25 100644 --- a/services/std_svc/spmd/spmd_pm.c +++ b/services/std_svc/spmd/spmd_pm.c @@ -32,7 +32,7 @@ int spmd_pm_secondary_core_set_ep(unsigned long long mpidr, { int id = plat_core_pos_by_mpidr(mpidr); - if ((id < 0) || (id >= PLATFORM_CORE_COUNT)) { + if ((id < 0) || ((unsigned int)id >= PLATFORM_CORE_COUNT)) { ERROR("%s inconsistent MPIDR (%llx)\n", __func__, mpidr); return -EINVAL; } -- cgit v1.2.3 From 3b456661e9ed6c4de048c78d95d329bb2c57ecfd Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 1 Oct 2020 22:41:48 +0100 Subject: libfdt: Upgrade libfdt source files Update the libfdt source files, the upstream commit is 73e0f143b73d ("libfdt: fdt_strerror(): Fix comparison warning"). This brings us the fixes for the signed/unsigned comparison warnings, so platforms can enable -Wsign-compare now. Change-Id: I303d891c82ffea0acefdde27289339db5ac5a289 Signed-off-by: Andre Przywara --- include/lib/libfdt/libfdt.h | 8 ++++++++ lib/libfdt/fdt.c | 31 +++++++++++++++++++++---------- lib/libfdt/fdt_overlay.c | 3 ++- lib/libfdt/fdt_ro.c | 20 +++++++++++--------- lib/libfdt/fdt_rw.c | 2 +- lib/libfdt/fdt_strerror.c | 4 ++-- lib/libfdt/fdt_sw.c | 29 ++++++++++++++++------------- lib/libfdt/fdt_wip.c | 2 +- 8 files changed, 62 insertions(+), 37 deletions(-) diff --git a/include/lib/libfdt/libfdt.h b/include/lib/libfdt/libfdt.h index 48f375c9c..544d3efff 100644 --- a/include/lib/libfdt/libfdt.h +++ b/include/lib/libfdt/libfdt.h @@ -9,6 +9,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + #define FDT_FIRST_SUPPORTED_VERSION 0x02 #define FDT_LAST_SUPPORTED_VERSION 0x11 @@ -2069,4 +2073,8 @@ int fdt_overlay_apply(void *fdt, void *fdto); const char *fdt_strerror(int errval); +#ifdef __cplusplus +} +#endif + #endif /* LIBFDT_H */ diff --git a/lib/libfdt/fdt.c b/lib/libfdt/fdt.c index c28fcc115..6cf2fa03b 100644 --- a/lib/libfdt/fdt.c +++ b/lib/libfdt/fdt.c @@ -134,16 +134,20 @@ int fdt_check_header(const void *fdt) const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len) { - unsigned absoffset = offset + fdt_off_dt_struct(fdt); + unsigned int uoffset = offset; + unsigned int absoffset = offset + fdt_off_dt_struct(fdt); + + if (offset < 0) + return NULL; if (!can_assume(VALID_INPUT)) - if ((absoffset < offset) + if ((absoffset < uoffset) || ((absoffset + len) < absoffset) || (absoffset + len) > fdt_totalsize(fdt)) return NULL; if (can_assume(LATEST) || fdt_version(fdt) >= 0x11) - if (((offset + len) < offset) + if (((uoffset + len) < uoffset) || ((offset + len) > fdt_size_dt_struct(fdt))) return NULL; @@ -206,10 +210,11 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) int fdt_check_node_offset_(const void *fdt, int offset) { - if (can_assume(VALID_INPUT)) - return offset; - if ((offset < 0) || (offset % FDT_TAGSIZE) - || (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE)) + if (!can_assume(VALID_INPUT) + && ((offset < 0) || (offset % FDT_TAGSIZE))) + return -FDT_ERR_BADOFFSET; + + if (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE) return -FDT_ERR_BADOFFSET; return offset; @@ -217,8 +222,11 @@ int fdt_check_node_offset_(const void *fdt, int offset) int fdt_check_prop_offset_(const void *fdt, int offset) { - if ((offset < 0) || (offset % FDT_TAGSIZE) - || (fdt_next_tag(fdt, offset, &offset) != FDT_PROP)) + if (!can_assume(VALID_INPUT) + && ((offset < 0) || (offset % FDT_TAGSIZE))) + return -FDT_ERR_BADOFFSET; + + if (fdt_next_tag(fdt, offset, &offset) != FDT_PROP) return -FDT_ERR_BADOFFSET; return offset; @@ -306,9 +314,12 @@ const char *fdt_find_string_(const char *strtab, int tabsize, const char *s) int fdt_move(const void *fdt, void *buf, int bufsize) { + if (!can_assume(VALID_INPUT) && bufsize < 0) + return -FDT_ERR_NOSPACE; + FDT_RO_PROBE(fdt); - if (fdt_totalsize(fdt) > bufsize) + if (fdt_totalsize(fdt) > (unsigned int)bufsize) return -FDT_ERR_NOSPACE; memmove(buf, fdt, fdt_totalsize(fdt)); diff --git a/lib/libfdt/fdt_overlay.c b/lib/libfdt/fdt_overlay.c index b310e49a6..d217e79b6 100644 --- a/lib/libfdt/fdt_overlay.c +++ b/lib/libfdt/fdt_overlay.c @@ -241,6 +241,7 @@ static int overlay_update_local_node_references(void *fdto, if (fixup_len % sizeof(uint32_t)) return -FDT_ERR_BADOVERLAY; + fixup_len /= sizeof(uint32_t); tree_val = fdt_getprop(fdto, tree_node, name, &tree_len); if (!tree_val) { @@ -250,7 +251,7 @@ static int overlay_update_local_node_references(void *fdto, return tree_len; } - for (i = 0; i < (fixup_len / sizeof(uint32_t)); i++) { + for (i = 0; i < fixup_len; i++) { fdt32_t adj_val; uint32_t poffset; diff --git a/lib/libfdt/fdt_ro.c b/lib/libfdt/fdt_ro.c index e03570a56..91cc6fefe 100644 --- a/lib/libfdt/fdt_ro.c +++ b/lib/libfdt/fdt_ro.c @@ -53,7 +53,7 @@ const char *fdt_get_string(const void *fdt, int stroffset, int *lenp) err = -FDT_ERR_BADOFFSET; absoffset = stroffset + fdt_off_dt_strings(fdt); - if (absoffset >= totalsize) + if (absoffset >= (unsigned)totalsize) goto fail; len = totalsize - absoffset; @@ -61,17 +61,19 @@ const char *fdt_get_string(const void *fdt, int stroffset, int *lenp) if (stroffset < 0) goto fail; if (can_assume(LATEST) || fdt_version(fdt) >= 17) { - if (stroffset >= fdt_size_dt_strings(fdt)) + if ((unsigned)stroffset >= fdt_size_dt_strings(fdt)) goto fail; if ((fdt_size_dt_strings(fdt) - stroffset) < len) len = fdt_size_dt_strings(fdt) - stroffset; } } else if (fdt_magic(fdt) == FDT_SW_MAGIC) { - if ((stroffset >= 0) - || (stroffset < -fdt_size_dt_strings(fdt))) + unsigned int sw_stroffset = -stroffset; + + if ((stroffset >= 0) || + (sw_stroffset > fdt_size_dt_strings(fdt))) goto fail; - if ((-stroffset) < len) - len = -stroffset; + if (sw_stroffset < len) + len = sw_stroffset; } else { err = -FDT_ERR_INTERNAL; goto fail; @@ -157,8 +159,8 @@ int fdt_generate_phandle(const void *fdt, uint32_t *phandle) static const struct fdt_reserve_entry *fdt_mem_rsv(const void *fdt, int n) { - int offset = n * sizeof(struct fdt_reserve_entry); - int absoffset = fdt_off_mem_rsvmap(fdt) + offset; + unsigned int offset = n * sizeof(struct fdt_reserve_entry); + unsigned int absoffset = fdt_off_mem_rsvmap(fdt) + offset; if (!can_assume(VALID_INPUT)) { if (absoffset < fdt_off_mem_rsvmap(fdt)) @@ -680,7 +682,7 @@ int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle) { int offset; - if ((phandle == 0) || (phandle == -1)) + if ((phandle == 0) || (phandle == ~0U)) return -FDT_ERR_BADPHANDLE; FDT_RO_PROBE(fdt); diff --git a/lib/libfdt/fdt_rw.c b/lib/libfdt/fdt_rw.c index 93e4a2b56..68887b969 100644 --- a/lib/libfdt/fdt_rw.c +++ b/lib/libfdt/fdt_rw.c @@ -59,7 +59,7 @@ static int fdt_splice_(void *fdt, void *splicepoint, int oldlen, int newlen) if ((oldlen < 0) || (soff + oldlen < soff) || (soff + oldlen > dsize)) return -FDT_ERR_BADOFFSET; - if ((p < (char *)fdt) || (dsize + newlen < oldlen)) + if ((p < (char *)fdt) || (dsize + newlen < (unsigned)oldlen)) return -FDT_ERR_BADOFFSET; if (dsize - oldlen + newlen > fdt_totalsize(fdt)) return -FDT_ERR_NOSPACE; diff --git a/lib/libfdt/fdt_strerror.c b/lib/libfdt/fdt_strerror.c index 768db66ea..b4356931b 100644 --- a/lib/libfdt/fdt_strerror.c +++ b/lib/libfdt/fdt_strerror.c @@ -40,7 +40,7 @@ static struct fdt_errtabent fdt_errtable[] = { FDT_ERRTABENT(FDT_ERR_NOPHANDLES), FDT_ERRTABENT(FDT_ERR_BADFLAGS), }; -#define FDT_ERRTABSIZE (sizeof(fdt_errtable) / sizeof(fdt_errtable[0])) +#define FDT_ERRTABSIZE ((int)(sizeof(fdt_errtable) / sizeof(fdt_errtable[0]))) const char *fdt_strerror(int errval) { @@ -48,7 +48,7 @@ const char *fdt_strerror(int errval) return ""; else if (errval == 0) return ""; - else if (errval > -FDT_ERRTABSIZE) { + else if (-errval < FDT_ERRTABSIZE) { const char *s = fdt_errtable[-errval].str; if (s) diff --git a/lib/libfdt/fdt_sw.c b/lib/libfdt/fdt_sw.c index 26759d5df..68b543c4d 100644 --- a/lib/libfdt/fdt_sw.c +++ b/lib/libfdt/fdt_sw.c @@ -32,7 +32,7 @@ static int fdt_sw_probe_(void *fdt) /* 'memrsv' state: Initial state after fdt_create() * * Allowed functions: - * fdt_add_reservmap_entry() + * fdt_add_reservemap_entry() * fdt_finish_reservemap() [moves to 'struct' state] */ static int fdt_sw_probe_memrsv_(void *fdt) @@ -93,8 +93,8 @@ static inline uint32_t sw_flags(void *fdt) static void *fdt_grab_space_(void *fdt, size_t len) { - int offset = fdt_size_dt_struct(fdt); - int spaceleft; + unsigned int offset = fdt_size_dt_struct(fdt); + unsigned int spaceleft; spaceleft = fdt_totalsize(fdt) - fdt_off_dt_struct(fdt) - fdt_size_dt_strings(fdt); @@ -108,8 +108,8 @@ static void *fdt_grab_space_(void *fdt, size_t len) int fdt_create_with_flags(void *buf, int bufsize, uint32_t flags) { - const size_t hdrsize = FDT_ALIGN(sizeof(struct fdt_header), - sizeof(struct fdt_reserve_entry)); + const int hdrsize = FDT_ALIGN(sizeof(struct fdt_header), + sizeof(struct fdt_reserve_entry)); void *fdt = buf; if (bufsize < hdrsize) @@ -152,6 +152,9 @@ int fdt_resize(void *fdt, void *buf, int bufsize) FDT_SW_PROBE(fdt); + if (bufsize < 0) + return -FDT_ERR_NOSPACE; + headsize = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt); tailsize = fdt_size_dt_strings(fdt); @@ -159,7 +162,7 @@ int fdt_resize(void *fdt, void *buf, int bufsize) headsize + tailsize > fdt_totalsize(fdt)) return -FDT_ERR_INTERNAL; - if ((headsize + tailsize) > bufsize) + if ((headsize + tailsize) > (unsigned)bufsize) return -FDT_ERR_NOSPACE; oldtail = (char *)fdt + fdt_totalsize(fdt) - tailsize; @@ -247,18 +250,18 @@ int fdt_end_node(void *fdt) static int fdt_add_string_(void *fdt, const char *s) { char *strtab = (char *)fdt + fdt_totalsize(fdt); - int strtabsize = fdt_size_dt_strings(fdt); - int len = strlen(s) + 1; - int struct_top, offset; + unsigned int strtabsize = fdt_size_dt_strings(fdt); + unsigned int len = strlen(s) + 1; + unsigned int struct_top, offset; - offset = -strtabsize - len; + offset = strtabsize + len; struct_top = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt); - if (fdt_totalsize(fdt) + offset < struct_top) + if (fdt_totalsize(fdt) - offset < struct_top) return 0; /* no more room :( */ - memcpy(strtab + offset, s, len); + memcpy(strtab - offset, s, len); fdt_set_size_dt_strings(fdt, strtabsize + len); - return offset; + return -offset; } /* Must only be used to roll back in case of error */ diff --git a/lib/libfdt/fdt_wip.c b/lib/libfdt/fdt_wip.c index f64139e0b..c2d7566a6 100644 --- a/lib/libfdt/fdt_wip.c +++ b/lib/libfdt/fdt_wip.c @@ -23,7 +23,7 @@ int fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset, if (!propval) return proplen; - if (proplen < (len + idx)) + if ((unsigned)proplen < (len + idx)) return -FDT_ERR_NOSPACE; memcpy((char *)propval + idx, val, len); -- cgit v1.2.3 From 55ff05f384aa8e150f192f618e807bab3e1ea12b Mon Sep 17 00:00:00 2001 From: johpow01 Date: Tue, 29 Sep 2020 17:19:09 -0500 Subject: Workaround for Cortex A76 erratum 1868343 Cortex A76 erratum 1868343 is a Cat B erratum, present in older revisions of the Cortex A76 processor core. The workaround is to set a bit in the CPUACTLR_EL1 system register, which delays instruction fetch after branch misprediction. This workaround will have a small impact on performance. This workaround is the same as workarounds for errata 1262606 and 1275112, so all 3 have been combined into one function call. SDEN can be found here: https://documentation-service.arm.com/static/5f2bed6d60a93e65927bc8e7 Signed-off-by: John Powell Change-Id: I7f2f9965f495540a1f84bb7dcc28aff45d6cee5d --- docs/design/cpu-specific-build-macros.rst | 3 + lib/cpus/aarch64/cortex_a76.S | 92 +++++++++++++++++-------------- lib/cpus/cpu-ops.mk | 8 +++ 3 files changed, 63 insertions(+), 40 deletions(-) diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst index e9ff17e8c..8152c00d5 100644 --- a/docs/design/cpu-specific-build-macros.rst +++ b/docs/design/cpu-specific-build-macros.rst @@ -249,6 +249,9 @@ For Cortex-A76, the following errata build flags are defined : limitation of errata framework this errata is applied to all revisions of Cortex-A76 CPU. +- ``ERRATA_A76_1868343``: This applies errata 1868343 workaround to Cortex-A76 + CPU. This needs to be enabled only for revision <= r4p0 of the CPU. + For Cortex-A77, the following errata build flags are defined : - ``ERRATA_A77_1508412``: This applies errata 1508412 workaround to Cortex-A77 diff --git a/lib/cpus/aarch64/cortex_a76.S b/lib/cpus/aarch64/cortex_a76.S index 0895946e4..98a11832d 100644 --- a/lib/cpus/aarch64/cortex_a76.S +++ b/lib/cpus/aarch64/cortex_a76.S @@ -337,44 +337,6 @@ func check_errata_1262888 b cpu_rev_var_ls endfunc check_errata_1262888 - /* -------------------------------------------------- - * Errata Workaround for Cortex A76 Errata #1275112 - * and Errata #1262606. - * This applies only to revision <= r3p0 of Cortex A76. - * Inputs: - * x0: variant[4:7] and revision[0:3] of current cpu. - * Shall clobber: x0-x17 - * -------------------------------------------------- - */ -func errata_a76_1275112_1262606_wa - /* - * Compare x0 against revision r3p0 - */ - mov x17, x30 - /* - * Since both errata #1275112 and #1262606 have the same check, we can - * invoke any one of them for the check here. - */ - bl check_errata_1275112 - cbz x0, 1f - mrs x1, CORTEX_A76_CPUACTLR_EL1 - orr x1, x1, CORTEX_A76_CPUACTLR_EL1_BIT_13 - msr CORTEX_A76_CPUACTLR_EL1, x1 - isb -1: - ret x17 -endfunc errata_a76_1275112_1262606_wa - -func check_errata_1262606 - mov x1, #0x30 - b cpu_rev_var_ls -endfunc check_errata_1262606 - -func check_errata_1275112 - mov x1, #0x30 - b cpu_rev_var_ls -endfunc check_errata_1275112 - /* --------------------------------------------------- * Errata Workaround for Cortex A76 Errata #1286807. * This applies only to revision <= r3p0 of Cortex A76. @@ -448,6 +410,55 @@ func check_errata_1800710 b cpu_rev_var_ls endfunc check_errata_1800710 + /* -------------------------------------------------- + * Errata Workaround for Cortex A76 Errata #1262606, + * #1275112, and #1868343. #1262606 and #1275112 + * apply to revisions <= r3p0 and #1868343 applies to + * revisions <= r4p0. + * Inputs: + * x0: variant[4:7] and revision[0:3] of current cpu. + * Shall clobber: x0-x17 + * -------------------------------------------------- + */ + +func errata_a76_1262606_1275112_1868343_wa + mov x17, x30 + +/* Check for <= r3p0 cases and branch if check passes. */ +#if ERRATA_A76_1262606 || ERRATA_A76_1275112 + bl check_errata_1262606 + cbnz x0, 1f +#endif + +/* Check for <= r4p0 cases and branch if check fails. */ +#if ERRATA_A76_1868343 + bl check_errata_1868343 + cbz x0, 2f +#endif +1: + mrs x1, CORTEX_A76_CPUACTLR_EL1 + orr x1, x1, #CORTEX_A76_CPUACTLR_EL1_BIT_13 + msr CORTEX_A76_CPUACTLR_EL1, x1 + isb +2: + ret x17 +endfunc errata_a76_1262606_1275112_1868343_wa + +func check_errata_1262606 + mov x1, #0x30 + b cpu_rev_var_ls +endfunc check_errata_1262606 + +func check_errata_1275112 + mov x1, #0x30 + b cpu_rev_var_ls +endfunc check_errata_1275112 + +func check_errata_1868343 + mov x1, #0x40 + b cpu_rev_var_ls +endfunc check_errata_1868343 + func check_errata_cve_2018_3639 #if WORKAROUND_CVE_2018_3639 mov x0, #ERRATA_APPLIES @@ -512,9 +523,9 @@ func cortex_a76_reset_func bl errata_a76_1257314_wa #endif -#if ERRATA_A76_1262606 || ERRATA_A76_1275112 +#if ERRATA_A76_1262606 || ERRATA_A76_1275112 || ERRATA_A76_1868343 mov x0, x18 - bl errata_a76_1275112_1262606_wa + bl errata_a76_1262606_1275112_1868343_wa #endif #if ERRATA_A76_1262888 @@ -615,6 +626,7 @@ func cortex_a76_errata_report report_errata ERRATA_A76_1791580, cortex_a76, 1791580 report_errata ERRATA_A76_1800710, cortex_a76, 1800710 report_errata ERRATA_A76_1165522, cortex_a76, 1165522 + report_errata ERRATA_A76_1868343, cortex_a76, 1868343 report_errata WORKAROUND_CVE_2018_3639, cortex_a76, cve_2018_3639 report_errata ERRATA_DSU_798953, cortex_a76, dsu_798953 report_errata ERRATA_DSU_936184, cortex_a76, dsu_936184 diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk index 5df94cce4..925ed5f08 100644 --- a/lib/cpus/cpu-ops.mk +++ b/lib/cpus/cpu-ops.mk @@ -278,6 +278,10 @@ ERRATA_A76_1800710 ?=0 # to all revisions of Cortex A76 cpu. ERRATA_A76_1165522 ?=0 +# Flag to apply erratum 1868343 workaround during reset. This erratum applies +# only to revision <= r4p0 of the Cortex A76 cpu. +ERRATA_A76_1868343 ?=0 + # Flag to apply erratum 1508412 workaround during reset. This erratum applies # only to revision <= r1p0 of the Cortex A77 cpu. ERRATA_A77_1508412 ?=0 @@ -555,6 +559,10 @@ $(eval $(call add_define,ERRATA_A76_1800710)) $(eval $(call assert_boolean,ERRATA_A76_1165522)) $(eval $(call add_define,ERRATA_A76_1165522)) +# Process ERRATA_A76_1868343 flag +$(eval $(call assert_boolean,ERRATA_A76_1868343)) +$(eval $(call add_define,ERRATA_A76_1868343)) + # Process ERRATA_A77_1508412 flag $(eval $(call assert_boolean,ERRATA_A77_1508412)) $(eval $(call add_define,ERRATA_A77_1508412)) -- cgit v1.2.3 From 6792ba159815a437889d7c758608933f75c0b935 Mon Sep 17 00:00:00 2001 From: Stefan Chulski Date: Mon, 24 Jun 2019 19:13:38 +0300 Subject: plat: marvell: ap806: implement workaround for errata-id FE-4265711 ERRATA ID: FE-4265711 - Incorrect CNTVAL reading CNTVAL reflects the global system counter value in binary format. Due to this erratum, the CNTVAL value presented to the processor may be incorrect for several clock cycles. Workaround: Override the default value of AP Register Device General control 20 [19:16] and AP Register Device General Control 21 [11:8] to the value of 0x3. Change-Id: I1705608d08acd9631ab98d6f7ceada34d6b8336f Signed-off-by: Stefan Chulski Signed-off-by: Marcin Wojtas --- .../armada/a8k/common/aarch64/plat_arch_config.c | 32 ++++++++++++++++++++++ .../armada/a8k/common/include/platform_def.h | 2 ++ 2 files changed, 34 insertions(+) diff --git a/plat/marvell/armada/a8k/common/aarch64/plat_arch_config.c b/plat/marvell/armada/a8k/common/aarch64/plat_arch_config.c index 9facdbc25..d57651466 100644 --- a/plat/marvell/armada/a8k/common/aarch64/plat_arch_config.c +++ b/plat/marvell/armada/a8k/common/aarch64/plat_arch_config.c @@ -15,6 +15,13 @@ #define MVEBU_IO_AFFINITY (0xF00) #define MVEBU_SF_REG (MVEBU_REGS_BASE + 0x40) #define MVEBU_SF_EN BIT(8) +#define MVEBU_DFX_REG(cluster_id) (MVEBU_REGS_BASE + 0x6F82A0 + \ + (cluster_id) * 0x4) +#define MVEBU_DFX_CLK_EN_POS 0x3 +#define MVEBU_DFX_CL0_CLK_OFFS 16 +#define MVEBU_DFX_CL0_CLK_MASK (0xF << MVEBU_DFX_CL0_CLK_OFFS) +#define MVEBU_DFX_CL1_CLK_OFFS 8 +#define MVEBU_DFX_CL1_CLK_MASK (0xF << MVEBU_DFX_CL1_CLK_OFFS) #ifdef MVEBU_SOC_AP807 static void plat_enable_snoop_filter(void) @@ -29,6 +36,29 @@ static void plat_enable_snoop_filter(void) } #endif +#ifndef MVEBU_SOC_AP807 +static void plat_config_dfx_clock(void) +{ + int cluster_id = plat_my_core_pos(); + uint32_t val; + + /* DFX clock needs to be configured once per cluster */ + if ((cluster_id % PLAT_MAX_CPUS_PER_CLUSTER) != 0) { + return; + } + + val = mmio_read_32(MVEBU_DFX_REG(cluster_id / PLAT_MAX_CPUS_PER_CLUSTER)); + if (cluster_id == 0) { + val &= ~MVEBU_DFX_CL0_CLK_MASK; + val |= (MVEBU_DFX_CLK_EN_POS << MVEBU_DFX_CL0_CLK_OFFS); + } else { + val &= ~MVEBU_DFX_CL1_CLK_MASK; + val |= (MVEBU_DFX_CLK_EN_POS << MVEBU_DFX_CL1_CLK_OFFS); + } + mmio_write_32(MVEBU_DFX_REG(cluster_id / PLAT_MAX_CPUS_PER_CLUSTER), val); +} +#endif + static void plat_enable_affinity(void) { int cluster_id; @@ -59,5 +89,7 @@ void marvell_psci_arch_init(int die_index) #ifdef MVEBU_SOC_AP807 plat_enable_snoop_filter(); +#else + plat_config_dfx_clock(); #endif } diff --git a/plat/marvell/armada/a8k/common/include/platform_def.h b/plat/marvell/armada/a8k/common/include/platform_def.h index 944a1517b..7d8505991 100644 --- a/plat/marvell/armada/a8k/common/include/platform_def.h +++ b/plat/marvell/armada/a8k/common/include/platform_def.h @@ -92,6 +92,8 @@ #define PLAT_MARVELL_CORE_COUNT (PLAT_MARVELL_CLUSTER_COUNT * \ PLAT_MARVELL_CLUSTER_CORE_COUNT) +#define PLAT_MAX_CPUS_PER_CLUSTER PLAT_MARVELL_CLUSTER_CORE_COUNT + /* Part of DRAM that is used as Trusted ROM */ #define PLAT_MARVELL_TRUSTED_ROM_BASE PLAT_MARVELL_ATF_LOAD_ADDR /* 4 MB for FIP image */ -- cgit v1.2.3 From a9688f07122058c9510cf1ef20b839ddceec4c01 Mon Sep 17 00:00:00 2001 From: Alex Leibovich Date: Wed, 25 Dec 2019 09:11:38 +0200 Subject: plat: marvell: armada: add ccu window for workaround errata-id 3033912 Added ccu window to allow access to addresses in the range [0xf100_0000, 0xf1ff_ffff]. Change-Id: I63ee68338d674114d01cd627198dc907653493e8 Signed-off-by: Alex Leibovich --- drivers/marvell/ccu.c | 41 +++++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/drivers/marvell/ccu.c b/drivers/marvell/ccu.c index ecf5091b4..b4251f49b 100644 --- a/drivers/marvell/ccu.c +++ b/drivers/marvell/ccu.c @@ -26,11 +26,38 @@ #define ADDRESS_MASK (0xFFFFFFF0) #define CCU_WIN_ALIGNMENT (0x100000) +/* + * Physical address of the highest address of window bits[31:19] = 0x6FF + * Physical address of the lowest address of window bits[18:6] = 0x6E0 + * Unit Id bits [5:2] = 2 + * RGF Window Enable bit[0] = 1 + * 0x37f9b809 - 11011111111 0011011100000 0010 0 1 + */ +#define ERRATA_WA_CCU_WIN4 0x37f9b809U + +/* + * Physical address of the highest address of window bits[31:19] = 0xFFF + * Physical address of the lowest address of window bits[18:6] = 0x800 + * Unit Id bits [5:2] = 2 + * RGF Window Enable bit[0] = 1 + * 0x7ffa0009 - 111111111111 0100000000000 0010 0 1 + */ +#define ERRATA_WA_CCU_WIN5 0x7ffa0009U + +/* + * Physical address of the highest address of window bits[31:19] = 0x1FFF + * Physical address of the lowest address of window bits[18:6] = 0x1000 + * Unit Id bits [5:2] = 2 + * RGF Window Enable bit[0] = 1 + * 0xfffc000d - 1111111111111 1000000000000 0011 0 1 + */ +#define ERRATA_WA_CCU_WIN6 0xfffc000dU + #define IS_DRAM_TARGET(tgt) ((((tgt) == DRAM_0_TID) || \ ((tgt) == DRAM_1_TID) || \ ((tgt) == RAR_TID)) ? 1 : 0) -#define CCU_RGF(win) (MVEBU_CCU_BASE(MVEBU_AP0) + \ +#define CCU_RGF(win) (MVEBU_CCU_BASE(MVEBU_AP0) + \ 0x90 + 4 * (win)) /* For storage of CR, SCR, ALR, AHR abd GCR */ @@ -376,10 +403,12 @@ void errata_wa_init(void) * EERATA ID: RES-3033912 - Internal Address Space Init state causes * a hang upon accesses to [0xf070_0000, 0xf07f_ffff] * Workaround: Boot Firmware (ATF) should configure CCU_RGF_WIN(4) to - * split [0x6e_0000, 0xff_ffff] to values [0x6e_0000, 0x6f_ffff] and - * [0x80_0000, 0xff_ffff] that cause accesses to the - * segment of [0xf070_0000, 0xf07f_ffff] to act as RAZWI. + * split [0x6e_0000, 0x1ff_ffff] to values [0x6e_0000, 0x6f_ffff] and + * [0x80_0000, 0xff_ffff] and [0x100_0000, 0x1ff_ffff],that cause + * accesses to the segment of [0xf070_0000, 0xf1ff_ffff] + * to act as RAZWI. */ - mmio_write_32(CCU_RGF(4), 0x37f9b809); - mmio_write_32(CCU_RGF(5), 0x7ffa0009); + mmio_write_32(CCU_RGF(4), ERRATA_WA_CCU_WIN4); + mmio_write_32(CCU_RGF(5), ERRATA_WA_CCU_WIN5); + mmio_write_32(CCU_RGF(6), ERRATA_WA_CCU_WIN6); } -- cgit v1.2.3 From 11e6ed094d742d66f2b37ea2c44faf903cbca945 Mon Sep 17 00:00:00 2001 From: Konstantin Porotchkin Date: Thu, 22 Aug 2019 14:23:34 +0300 Subject: drivers: marvell: mochi: Update AP incoming masters secure level Do not force non-secure access level for PIDI masters when LLC_SRAM is enabled. The EIP197 is located on CP0 and need to access secure SRAM in AP LLC. This requires EIP197 DMA to have AXPROT[1]=0 and not changed when forwarded to address decoding tables. Change-Id: I8962db94a124350c14220ba6d0364d294ae4664a Signed-off-by: Konstantin Porotchkin --- drivers/marvell/mochi/ap807_setup.c | 43 ++++++++++++++++++++++++++++-------- drivers/marvell/mochi/apn806_setup.c | 41 +++++++++++++++++++++++++++------- 2 files changed, 67 insertions(+), 17 deletions(-) diff --git a/drivers/marvell/mochi/ap807_setup.c b/drivers/marvell/mochi/ap807_setup.c index 7cdfe051e..1069f8cef 100644 --- a/drivers/marvell/mochi/ap807_setup.c +++ b/drivers/marvell/mochi/ap807_setup.c @@ -47,6 +47,14 @@ SEC_MOCHI_IN_ACC_IHB1_EN | \ SEC_MOCHI_IN_ACC_IHB2_EN | \ SEC_MOCHI_IN_ACC_PIDI_EN) +#define MOCHI_IN_ACC_LEVEL_FORCE_NONSEC (0) +#define MOCHI_IN_ACC_LEVEL_FORCE_SEC (1) +#define MOCHI_IN_ACC_LEVEL_LEAVE_ORIG (2) +#define MOCHI_IN_ACC_LEVEL_MASK_ALL (3) +#define SEC_MOCHI_IN_ACC_IHB0_LEVEL(l) ((l) << 1) +#define SEC_MOCHI_IN_ACC_IHB1_LEVEL(l) ((l) << 4) +#define SEC_MOCHI_IN_ACC_PIDI_LEVEL(l) ((l) << 10) + /* SYSRST_OUTn Config definitions */ #define MVEBU_SYSRST_OUT_CONFIG_REG (MVEBU_MISC_SOC_BASE + 0x4) @@ -71,19 +79,36 @@ enum axi_attr { static void ap_sec_masters_access_en(uint32_t enable) { - uint32_t reg; - /* Open/Close incoming access for all masters. * The access is disabled in trusted boot mode * Could only be done in EL3 */ - reg = mmio_read_32(SEC_MOCHI_IN_ACC_REG); - if (enable) - mmio_write_32(SEC_MOCHI_IN_ACC_REG, reg | - SEC_IN_ACCESS_ENA_ALL_MASTERS); - else - mmio_write_32(SEC_MOCHI_IN_ACC_REG, - reg & ~SEC_IN_ACCESS_ENA_ALL_MASTERS); + if (enable != 0) { + mmio_clrsetbits_32(SEC_MOCHI_IN_ACC_REG, 0x0U, /* no clear */ + SEC_IN_ACCESS_ENA_ALL_MASTERS); +#if LLC_SRAM + /* Do not change access security level + * for PIDI masters + */ + mmio_clrsetbits_32(SEC_MOCHI_IN_ACC_REG, + SEC_MOCHI_IN_ACC_PIDI_LEVEL( + MOCHI_IN_ACC_LEVEL_MASK_ALL), + SEC_MOCHI_IN_ACC_PIDI_LEVEL( + MOCHI_IN_ACC_LEVEL_LEAVE_ORIG)); +#endif + } else { + mmio_clrsetbits_32(SEC_MOCHI_IN_ACC_REG, + SEC_IN_ACCESS_ENA_ALL_MASTERS, + 0x0U /* no set */); +#if LLC_SRAM + /* Return PIDI access level to the default */ + mmio_clrsetbits_32(SEC_MOCHI_IN_ACC_REG, + SEC_MOCHI_IN_ACC_PIDI_LEVEL( + MOCHI_IN_ACC_LEVEL_MASK_ALL), + SEC_MOCHI_IN_ACC_PIDI_LEVEL( + MOCHI_IN_ACC_LEVEL_FORCE_NONSEC)); +#endif + } } static void setup_smmu(void) diff --git a/drivers/marvell/mochi/apn806_setup.c b/drivers/marvell/mochi/apn806_setup.c index b8925d9f2..8c3ba9296 100644 --- a/drivers/marvell/mochi/apn806_setup.c +++ b/drivers/marvell/mochi/apn806_setup.c @@ -41,6 +41,14 @@ SEC_MOCHI_IN_ACC_IHB1_EN | \ SEC_MOCHI_IN_ACC_IHB2_EN | \ SEC_MOCHI_IN_ACC_PIDI_EN) +#define MOCHI_IN_ACC_LEVEL_FORCE_NONSEC (0) +#define MOCHI_IN_ACC_LEVEL_FORCE_SEC (1) +#define MOCHI_IN_ACC_LEVEL_LEAVE_ORIG (2) +#define MOCHI_IN_ACC_LEVEL_MASK_ALL (3) +#define SEC_MOCHI_IN_ACC_IHB0_LEVEL(l) ((l) << 1) +#define SEC_MOCHI_IN_ACC_IHB1_LEVEL(l) ((l) << 4) +#define SEC_MOCHI_IN_ACC_PIDI_LEVEL(l) ((l) << 10) + /* SYSRST_OUTn Config definitions */ #define MVEBU_SYSRST_OUT_CONFIG_REG (MVEBU_MISC_SOC_BASE + 0x4) @@ -67,19 +75,36 @@ enum axi_attr { static void apn_sec_masters_access_en(uint32_t enable) { - uint32_t reg; - /* Open/Close incoming access for all masters. * The access is disabled in trusted boot mode * Could only be done in EL3 */ - reg = mmio_read_32(SEC_MOCHI_IN_ACC_REG); - if (enable) - mmio_write_32(SEC_MOCHI_IN_ACC_REG, reg | + if (enable != 0) { + mmio_clrsetbits_32(SEC_MOCHI_IN_ACC_REG, 0x0U, /* no clear */ SEC_IN_ACCESS_ENA_ALL_MASTERS); - else - mmio_write_32(SEC_MOCHI_IN_ACC_REG, reg & - ~SEC_IN_ACCESS_ENA_ALL_MASTERS); +#if LLC_SRAM + /* Do not change access security level + * for PIDI masters + */ + mmio_clrsetbits_32(SEC_MOCHI_IN_ACC_REG, + SEC_MOCHI_IN_ACC_PIDI_LEVEL( + MOCHI_IN_ACC_LEVEL_MASK_ALL), + SEC_MOCHI_IN_ACC_PIDI_LEVEL( + MOCHI_IN_ACC_LEVEL_LEAVE_ORIG)); +#endif + } else { + mmio_clrsetbits_32(SEC_MOCHI_IN_ACC_REG, + SEC_IN_ACCESS_ENA_ALL_MASTERS, + 0x0U /* no set */); +#if LLC_SRAM + /* Return PIDI access level to the default */ + mmio_clrsetbits_32(SEC_MOCHI_IN_ACC_REG, + SEC_MOCHI_IN_ACC_PIDI_LEVEL( + MOCHI_IN_ACC_LEVEL_MASK_ALL), + SEC_MOCHI_IN_ACC_PIDI_LEVEL( + MOCHI_IN_ACC_LEVEL_FORCE_NONSEC)); +#endif + } } static void setup_smmu(void) -- cgit v1.2.3 From 8fa134089229e86847bf17e820011340a36be7b7 Mon Sep 17 00:00:00 2001 From: Marcin Wojtas Date: Mon, 9 Sep 2019 03:38:18 +0200 Subject: marvell: comphy: cp110: implement erratum IPCE_COMPHY-1353 According to erratum IPCE_COMPHY-1353 the TX_IDLE bit should be toggled in addition to the XFI/SFI PHY reset. Change-Id: Idd2c2abfcb2f960caa01e6d69db524c2e4734f50 Signed-off-by: Marcin Wojtas --- drivers/marvell/comphy/comphy-cp110.h | 3 +++ drivers/marvell/comphy/phy-comphy-cp110.c | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/drivers/marvell/comphy/comphy-cp110.h b/drivers/marvell/comphy/comphy-cp110.h index 3678c90fb..27ddcd0e3 100644 --- a/drivers/marvell/comphy/comphy-cp110.h +++ b/drivers/marvell/comphy/comphy-cp110.h @@ -116,6 +116,9 @@ (0x1 << SD_EXTERNAL_CONFIG0_MEDIA_MODE_OFFSET) #define SD_EXTERNAL_CONFIG1_REG 0x4 +#define SD_EXTERNAL_CONFIG1_TX_IDLE_OFFSET 2 +#define SD_EXTERNAL_CONFIG1_TX_IDLE_MASK \ + (0x1 << SD_EXTERNAL_CONFIG1_TX_IDLE_OFFSET) #define SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET 3 #define SD_EXTERNAL_CONFIG1_RESET_IN_MASK \ (0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET) diff --git a/drivers/marvell/comphy/phy-comphy-cp110.c b/drivers/marvell/comphy/phy-comphy-cp110.c index 1d5b6f564..012197ebd 100644 --- a/drivers/marvell/comphy/phy-comphy-cp110.c +++ b/drivers/marvell/comphy/phy-comphy-cp110.c @@ -898,11 +898,21 @@ static int mvebu_cp110_comphy_xfi_power_on(uint64_t comphy_base, data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET; mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK; data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET; + mask |= SD_EXTERNAL_CONFIG1_TX_IDLE_MASK; + data |= 0x1 << SD_EXTERNAL_CONFIG1_TX_IDLE_OFFSET; reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask); /* Wait 1ms - until band gap and ref clock ready */ mdelay(1); + /* + * Erratum IPCE_COMPHY-1353: toggle TX_IDLE bit in + * addition to the PHY reset + */ + mask = SD_EXTERNAL_CONFIG1_TX_IDLE_MASK; + data = 0x0U; + reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask); + /* Start comphy Configuration */ debug("stage: Comphy configuration\n"); /* set reference clock */ -- cgit v1.2.3 From 38f6daca7a1ebdd9336d4618d8da906a14c4f0c3 Mon Sep 17 00:00:00 2001 From: Grzegorz Jaszczyk Date: Tue, 21 Jan 2020 17:02:10 +0100 Subject: marvell: comphy: cp110: add support for SATA comphy polarity invert The cp110 comphy has ability to invert RX and/or TX polarity. Polarity depends on board design. Currently all supported boards doesn't require SATA phy polarity invert, therefore COMPHY_POLARITY_NO_INVERT is set for all boards. Change-Id: Ifd0bc6aaf8a76a0928132b197422f3193cf020d5 Signed-off-by: Grzegorz Jaszczyk --- drivers/marvell/comphy/comphy-cp110.h | 8 ++++++ drivers/marvell/comphy/phy-comphy-cp110.c | 29 +++++++++++++++++++++- drivers/marvell/comphy/phy-comphy-cp110.h | 6 +++++ drivers/marvell/comphy/phy-default-porting-layer.h | 1 + .../armada/a8k/a80x0/board/phy-porting-layer.h | 4 +++ .../otx2/t91/t9130/board/phy-porting-layer.h | 1 + 6 files changed, 48 insertions(+), 1 deletion(-) diff --git a/drivers/marvell/comphy/comphy-cp110.h b/drivers/marvell/comphy/comphy-cp110.h index 27ddcd0e3..9b10619ed 100644 --- a/drivers/marvell/comphy/comphy-cp110.h +++ b/drivers/marvell/comphy/comphy-cp110.h @@ -355,6 +355,14 @@ #define HPIPE_CDR_LOCK_DET_EN_MASK \ (0x1 << HPIPE_CDR_LOCK_DET_EN_OFFSET) +#define HPIPE_SYNC_PATTERN_REG 0x090 +#define HPIPE_SYNC_PATTERN_TXD_INV_OFFSET 10 +#define HPIPE_SYNC_PATTERN_TXD_INV_MASK \ + (0x1 << HPIPE_SYNC_PATTERN_TXD_INV_OFFSET) +#define HPIPE_SYNC_PATTERN_RXD_INV_OFFSET 11 +#define HPIPE_SYNC_PATTERN_RXD_INV_MASK \ + (0x1 << HPIPE_SYNC_PATTERN_RXD_INV_OFFSET) + #define HPIPE_INTERFACE_REG 0x94 #define HPIPE_INTERFACE_GEN_MAX_OFFSET 10 #define HPIPE_INTERFACE_GEN_MAX_MASK \ diff --git a/drivers/marvell/comphy/phy-comphy-cp110.c b/drivers/marvell/comphy/phy-comphy-cp110.c index 012197ebd..e9dcfb861 100644 --- a/drivers/marvell/comphy/phy-comphy-cp110.c +++ b/drivers/marvell/comphy/phy-comphy-cp110.c @@ -323,12 +323,33 @@ int mvebu_cp110_comphy_is_pll_locked(uint64_t comphy_base, uint8_t comphy_index) return ret; } +static void mvebu_cp110_polarity_invert(uintptr_t addr, uint8_t phy_polarity_invert) +{ + uint32_t mask, data; + + /* Set RX / TX polarity */ + data = mask = 0x0U; + if ((phy_polarity_invert & COMPHY_POLARITY_TXD_INVERT) != 0) { + data |= (1 << HPIPE_SYNC_PATTERN_TXD_INV_OFFSET); + mask |= HPIPE_SYNC_PATTERN_TXD_INV_MASK; + debug("%s: inverting TX polarity\n", __func__); + } + + if ((phy_polarity_invert & COMPHY_POLARITY_RXD_INVERT) != 0) { + data |= (1 << HPIPE_SYNC_PATTERN_RXD_INV_OFFSET); + mask |= HPIPE_SYNC_PATTERN_RXD_INV_MASK; + debug("%s: inverting RX polarity\n", __func__); + } + + reg_set(addr, data, mask); +} + static int mvebu_cp110_comphy_sata_power_on(uint64_t comphy_base, uint8_t comphy_index, uint32_t comphy_mode) { uintptr_t hpipe_addr, sd_ip_addr, comphy_addr; uint32_t mask, data; - uint8_t ap_nr, cp_nr; + uint8_t ap_nr, cp_nr, phy_polarity_invert; int ret = 0; debug_enter(); @@ -338,6 +359,7 @@ static int mvebu_cp110_comphy_sata_power_on(uint64_t comphy_base, const struct sata_params *sata_static_values = &sata_static_values_tab[ap_nr][cp_nr][comphy_index]; + phy_polarity_invert = sata_static_values->polarity_invert; /* configure phy selector for SATA */ mvebu_cp110_comphy_set_phy_selector(comphy_base, @@ -629,6 +651,11 @@ static int mvebu_cp110_comphy_sata_power_on(uint64_t comphy_base, reg_set(hpipe_addr + HPIPE_PWR_CTR_REG, 0x0 << HPIPE_PWR_CTR_RST_DFE_OFFSET, HPIPE_PWR_CTR_RST_DFE_MASK); + + if (phy_polarity_invert != 0) + mvebu_cp110_polarity_invert(hpipe_addr + HPIPE_SYNC_PATTERN_REG, + phy_polarity_invert); + /* SW reset for interrupt logic */ reg_set(hpipe_addr + HPIPE_PWR_CTR_REG, 0x1 << HPIPE_PWR_CTR_SFT_RST_OFFSET, diff --git a/drivers/marvell/comphy/phy-comphy-cp110.h b/drivers/marvell/comphy/phy-comphy-cp110.h index 63aef1200..1dc3aa253 100644 --- a/drivers/marvell/comphy/phy-comphy-cp110.h +++ b/drivers/marvell/comphy/phy-comphy-cp110.h @@ -76,6 +76,8 @@ struct sata_params { uint8_t g2_rx_selmupi; uint8_t g3_rx_selmupi; + uint8_t polarity_invert; + _Bool valid; }; @@ -89,3 +91,7 @@ int mvebu_cp110_comphy_xfi_rx_training(uint64_t comphy_base, uint8_t comphy_index); int mvebu_cp110_comphy_digital_reset(uint64_t comphy_base, uint8_t comphy_index, uint32_t comphy_mode, uint32_t command); + +#define COMPHY_POLARITY_NO_INVERT 0 +#define COMPHY_POLARITY_TXD_INVERT 1 +#define COMPHY_POLARITY_RXD_INVERT 2 diff --git a/drivers/marvell/comphy/phy-default-porting-layer.h b/drivers/marvell/comphy/phy-default-porting-layer.h index b3ad7eb14..28bfcf242 100644 --- a/drivers/marvell/comphy/phy-default-porting-layer.h +++ b/drivers/marvell/comphy/phy-default-porting-layer.h @@ -45,6 +45,7 @@ static const struct sata_params .g3_rx_selmupf = 0x2, .g1_rx_selmupi = 0x0, .g2_rx_selmupi = 0x0, .g3_rx_selmupi = 0x2, + .polarity_invert = COMPHY_POLARITY_NO_INVERT, .valid = 0x1 }, }; diff --git a/plat/marvell/armada/a8k/a80x0/board/phy-porting-layer.h b/plat/marvell/armada/a8k/a80x0/board/phy-porting-layer.h index abd85b5d2..f0800298b 100644 --- a/plat/marvell/armada/a8k/a80x0/board/phy-porting-layer.h +++ b/plat/marvell/armada/a8k/a80x0/board/phy-porting-layer.h @@ -92,6 +92,7 @@ static const struct sata_params .g3_rx_selmupf = 0x2, .g1_rx_selmupi = 0x0, .g2_rx_selmupi = 0x0, .g3_rx_selmupi = 0x2, + .polarity_invert = COMPHY_POLARITY_NO_INVERT, .valid = 0x1 }, /* Comphy1 */ { 0 }, /* Comphy2 */ @@ -116,6 +117,7 @@ static const struct sata_params .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 */ @@ -146,6 +148,7 @@ static const struct sata_params .g3_rx_selmupf = 0x2, .g1_rx_selmupi = 0x0, .g2_rx_selmupi = 0x0, .g3_rx_selmupi = 0x2, + .polarity_invert = COMPHY_POLARITY_NO_INVERT, .valid = 0x1 }, /* Comphy1 */ { 0 }, /* Comphy2 */ @@ -170,6 +173,7 @@ static const struct sata_params .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 */ diff --git a/plat/marvell/octeontx/otx2/t91/t9130/board/phy-porting-layer.h b/plat/marvell/octeontx/otx2/t91/t9130/board/phy-porting-layer.h index a8660552e..824465845 100644 --- a/plat/marvell/octeontx/otx2/t91/t9130/board/phy-porting-layer.h +++ b/plat/marvell/octeontx/otx2/t91/t9130/board/phy-porting-layer.h @@ -131,6 +131,7 @@ SATA_PARAMS sata_static_values_tab[AP_NUM][CP_NUM][MAX_LANE_NR] = { .g3_rx_selmupf = 0x2, .g1_rx_selmupi = 0x0, .g2_rx_selmupi = 0x0, .g3_rx_selmupi = 0x2, + .polarity_invert = COMPHY_POLARITY_NO_INVERT, .valid = 0x1 }, }; -- cgit v1.2.3 From ff9cfdc0e2de57bb8bdd7173bb1b924a09501f39 Mon Sep 17 00:00:00 2001 From: Grzegorz Jaszczyk Date: Tue, 21 Jan 2020 17:02:29 +0100 Subject: marvell: comphy: cp110: add support for USB comphy polarity invert The polarity inversion for USB was not tested due to lack of hw design which requires it. Currently all supported boards doesn't require USB phy polarity inversion, therefore COMPHY_POLARITY_NO_INVERT is set for all boards. Enable the option for the ones that need it. Change-Id: Ia5f2ee313a93962e94963e2dd8a759ef6d9da369 Signed-off-by: Grzegorz Jaszczyk --- drivers/marvell/comphy/phy-comphy-cp110.c | 15 +++++++++++++++ drivers/marvell/comphy/phy-comphy-cp110.h | 4 ++++ drivers/marvell/comphy/phy-default-porting-layer.h | 7 +++++++ plat/marvell/armada/a8k/a80x0/board/phy-porting-layer.h | 7 +++++++ .../octeontx/otx2/t91/t9130/board/phy-porting-layer.h | 6 ++++++ 5 files changed, 39 insertions(+) diff --git a/drivers/marvell/comphy/phy-comphy-cp110.c b/drivers/marvell/comphy/phy-comphy-cp110.c index e9dcfb861..d1c26f8d3 100644 --- a/drivers/marvell/comphy/phy-comphy-cp110.c +++ b/drivers/marvell/comphy/phy-comphy-cp110.c @@ -1922,6 +1922,7 @@ static int mvebu_cp110_comphy_usb3_power_on(uint64_t comphy_base, { uintptr_t hpipe_addr, comphy_addr, addr; uint32_t mask, data; + uint8_t ap_nr, cp_nr, phy_polarity_invert; int ret = 0; debug_enter(); @@ -1930,6 +1931,13 @@ static int mvebu_cp110_comphy_usb3_power_on(uint64_t comphy_base, mvebu_cp110_comphy_set_pipe_selector(comphy_base, comphy_index, comphy_mode); + mvebu_cp110_get_ap_and_cp_nr(&ap_nr, &cp_nr, comphy_base); + + const struct usb_params *usb_static_values = + &usb_static_values_tab[ap_nr][cp_nr][comphy_index]; + + phy_polarity_invert = usb_static_values->polarity_invert; + hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base), comphy_index); comphy_addr = COMPHY_ADDR(comphy_base, comphy_index); @@ -2009,6 +2017,13 @@ static int mvebu_cp110_comphy_usb3_power_on(uint64_t comphy_base, 0x1 << HPIPE_TST_MODE_CTRL_MODE_MARGIN_OFFSET, HPIPE_TST_MODE_CTRL_MODE_MARGIN_MASK); + /* The polarity inversion for USB was not tested due to lack of hw + * design which requires it. Support is added for customer needs. + */ + if (phy_polarity_invert) + mvebu_cp110_polarity_invert(hpipe_addr + HPIPE_SYNC_PATTERN_REG, + phy_polarity_invert); + /* Start analog parameters from ETP(HW) */ debug("stage: Analog parameters from ETP(HW)\n"); /* Set Pin DFE_PAT_DIS -> Bit[1]: PIN_DFE_PAT_DIS = 0x0 */ diff --git a/drivers/marvell/comphy/phy-comphy-cp110.h b/drivers/marvell/comphy/phy-comphy-cp110.h index 1dc3aa253..b4a210242 100644 --- a/drivers/marvell/comphy/phy-comphy-cp110.h +++ b/drivers/marvell/comphy/phy-comphy-cp110.h @@ -81,6 +81,10 @@ struct sata_params { _Bool valid; }; +struct usb_params { + uint8_t polarity_invert; +}; + int mvebu_cp110_comphy_is_pll_locked(uint64_t comphy_base, uint8_t comphy_index); int mvebu_cp110_comphy_power_off(uint64_t comphy_base, diff --git a/drivers/marvell/comphy/phy-default-porting-layer.h b/drivers/marvell/comphy/phy-default-porting-layer.h index 28bfcf242..3c63c64b8 100644 --- a/drivers/marvell/comphy/phy-default-porting-layer.h +++ b/drivers/marvell/comphy/phy-default-porting-layer.h @@ -49,4 +49,11 @@ static const struct sata_params .valid = 0x1 }, }; + +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_DEFAULT_PORTING_LAYER_H */ diff --git a/plat/marvell/armada/a8k/a80x0/board/phy-porting-layer.h b/plat/marvell/armada/a8k/a80x0/board/phy-porting-layer.h index f0800298b..afa3be158 100644 --- a/plat/marvell/armada/a8k/a80x0/board/phy-porting-layer.h +++ b/plat/marvell/armada/a8k/a80x0/board/phy-porting-layer.h @@ -182,4 +182,11 @@ static const struct sata_params }, }, }; + +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/octeontx/otx2/t91/t9130/board/phy-porting-layer.h b/plat/marvell/octeontx/otx2/t91/t9130/board/phy-porting-layer.h index 824465845..6b554074c 100644 --- a/plat/marvell/octeontx/otx2/t91/t9130/board/phy-porting-layer.h +++ b/plat/marvell/octeontx/otx2/t91/t9130/board/phy-porting-layer.h @@ -136,4 +136,10 @@ SATA_PARAMS sata_static_values_tab[AP_NUM][CP_NUM][MAX_LANE_NR] = { }, }; +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 */ -- cgit v1.2.3 From 270367fbf7e2d3cb004257a7d1123fc89d58eba6 Mon Sep 17 00:00:00 2001 From: Konstantin Porotchkin Date: Tue, 27 Aug 2019 16:21:10 +0300 Subject: plat: marvell: armada: a3k: allow image load to RAM address 0 Marvell uses RAM address 0x0 for loading BL33 stage images. When ATF is built with DEBUG=1, its IO subsystem fails on assert checking the destination RAM address != 0. This patch adds PLAT_ALLOW_ZERO_ADDR_COPY to A3K platform allowing to bypass the above check in debug mode. Change-Id: I687e35cb2e9dc3166bdaa81b3904c20b784c5c6a Signed-off-by: Konstantin Porotchkin --- plat/marvell/armada/a3k/common/include/platform_def.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/plat/marvell/armada/a3k/common/include/platform_def.h b/plat/marvell/armada/a3k/common/include/platform_def.h index 61c7dfe70..3d839f820 100644 --- a/plat/marvell/armada/a3k/common/include/platform_def.h +++ b/plat/marvell/armada/a3k/common/include/platform_def.h @@ -70,6 +70,14 @@ * PLAT_MARVELL_FIP_BASE = 0x4120000 */ +/* + * Since BL33 is loaded by BL2 (and validated by BL31) to DRAM offset 0, + * it is allowed to load/copy images to 'NULL' pointers + */ +#if defined(IMAGE_BL2) || defined(IMAGE_BL31) +#define PLAT_ALLOW_ZERO_ADDR_COPY +#endif + #define PLAT_MARVELL_ATF_BASE 0x4000000 #define PLAT_MARVELL_ATF_LOAD_ADDR \ (PLAT_MARVELL_ATF_BASE + 0x100000) -- cgit v1.2.3 From fc8dc4999770dc0887b09e650f4ae7e7eb0befc0 Mon Sep 17 00:00:00 2001 From: Konstantin Porotchkin Date: Thu, 24 Oct 2019 10:48:08 +0300 Subject: plat: marvell: armada: a3k: rename the UART images archive Add *.bin extension to UART recovery images archive name. Such naming will cause the UART recovery images to be copied to the Buildroot output folder upon flash image build. Change-Id: I6992df1ab2ded725bed58e5baf245ae92c4cb289 Signed-off-by: Konstantin Porotchkin --- plat/marvell/armada/a3k/common/a3700_common.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk index 996556719..ace74a8b1 100644 --- a/plat/marvell/armada/a3k/common/a3700_common.mk +++ b/plat/marvell/armada/a3k/common/a3700_common.mk @@ -138,7 +138,7 @@ endif @mv -t $(BUILD_PLAT)/$(BUILD_UART) $(TIM_IMAGE) $(DOIMAGE_CFG) $(TIMN_IMAGE) $(TIMNCFG) @find . -name "*_h.*" |xargs cp -ut $(BUILD_PLAT)/$(BUILD_UART) @mv $(subst .bin,_h.bin,$(WTMI_MULTI_IMG)) $(BUILD_PLAT)/$(BUILD_UART)/wtmi_h.bin - @tar czf $(BUILD_PLAT)/$(BUILD_UART).tgz -C $(BUILD_PLAT) ./$(BUILD_UART) + @tar czf $(BUILD_PLAT)/$(BUILD_UART).tgz.bin -C $(BUILD_PLAT) ./$(BUILD_UART) @echo @echo "Building flash image" $(TIMBUILD) $(TIMBLDARGS) -- cgit v1.2.3 From 1d935a1b557b6f85d0d42b1fb90cd261d2e57717 Mon Sep 17 00:00:00 2001 From: Marcin Wojtas Date: Sun, 4 Oct 2020 16:00:07 +0200 Subject: docs: marvell: update mv_ddr branch Now that the BLE image sources (mv_ddr) are updated, reflect the proper branch in the Armada build howto. Change-Id: I959d1343d0dfdd681c7e39bdcaed9b36aaddfca1 Signed-off-by: Marcin Wojtas --- docs/plat/marvell/armada/build.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/plat/marvell/armada/build.rst b/docs/plat/marvell/armada/build.rst index 6b9054c7c..56b627b48 100644 --- a/docs/plat/marvell/armada/build.rst +++ b/docs/plat/marvell/armada/build.rst @@ -259,7 +259,7 @@ Armada37x0 Builds require installation of 3 components > export CROSS_CM3=/opt/arm-cross/bin/arm-linux-gnueabi (2) DDR initialization library sources (mv_ddr) available at the following repository - (use the "mv_ddr-armada-atf-mainline" branch): + (use the "mv_ddr-armada-18.12" branch): https://github.com/MarvellEmbeddedProcessors/mv-ddr-marvell.git @@ -271,6 +271,6 @@ Armada70x0 and Armada80x0 Builds require installation of an additional component ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (1) DDR initialization library sources (mv_ddr) available at the following repository - (use the "mv_ddr-armada-atf-mainline" branch): + (use the "mv_ddr-armada-18.12" branch): https://github.com/MarvellEmbeddedProcessors/mv-ddr-marvell.git -- cgit v1.2.3 From b1f596b68b040cfcdb19d06252b2998e6354a36a Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Mon, 5 Oct 2020 09:54:09 +0200 Subject: bl32: use SORT_BY_ALIGNMENT macro in sp_min.ld.S The macro SORT_BY_ALIGNMENT is used for .text* and .rodata*. This allows reducing the space lost to object alignment. This is an alignment with the following patch: ebd6efae67c6a086bc97d807a638bde324d936dc Some comments are also aligned with other linker scripts. Change-Id: I2ea59edb445af0ed8c08fd883ffbf56852570d0c Signed-off-by: Yann Gautier --- bl32/sp_min/sp_min.ld.S | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/bl32/sp_min/sp_min.ld.S b/bl32/sp_min/sp_min.ld.S index 9e0596f1f..5223915e5 100644 --- a/bl32/sp_min/sp_min.ld.S +++ b/bl32/sp_min/sp_min.ld.S @@ -22,14 +22,14 @@ MEMORY { SECTIONS { . = BL32_BASE; - ASSERT(. == ALIGN(PAGE_SIZE), - "BL32_BASE address is not aligned on a page boundary.") + ASSERT(. == ALIGN(PAGE_SIZE), + "BL32_BASE address is not aligned on a page boundary.") #if SEPARATE_CODE_AND_RODATA .text . : { __TEXT_START__ = .; *entrypoint.o(.text*) - *(.text*) + *(SORT_BY_ALIGNMENT(.text*)) *(.vectors) . = ALIGN(PAGE_SIZE); __TEXT_END__ = .; @@ -46,7 +46,7 @@ SECTIONS .rodata . : { __RODATA_START__ = .; - *(.rodata*) + *(SORT_BY_ALIGNMENT(.rodata*)) RODATA_COMMON @@ -61,8 +61,8 @@ SECTIONS ro . : { __RO_START__ = .; *entrypoint.o(.text*) - *(.text*) - *(.rodata*) + *(SORT_BY_ALIGNMENT(.text*)) + *(SORT_BY_ALIGNMENT(.rodata*)) RODATA_COMMON @@ -76,7 +76,7 @@ SECTIONS /* * Memory page(s) mapped to this section will be marked as * read-only, executable. No RW data from the next section must - * creep in. Ensure the rest of the current memory block is unused. + * creep in. Ensure the rest of the current memory page is unused. */ . = ALIGN(PAGE_SIZE); __RO_END__ = .; @@ -134,10 +134,10 @@ SECTIONS #endif /* - * Define a linker symbol to mark end of the RW memory area for this + * Define a linker symbol to mark the end of the RW memory area for this * image. */ __RW_END__ = .; - __BL32_END__ = .; + __BL32_END__ = .; } -- cgit v1.2.3 From fdd97d7c64edb256812e786a7aa224a3010a7fec Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Mon, 5 Oct 2020 11:39:19 +0200 Subject: bl32: add an assert on BL32_SIZE in sp_min.ld.S This assert is present in all other linker scripts. This checks the size of BL32 doesn't exceed its defined limit. Change-Id: I0005959b5591d3eebd870045adafe437108bc9e1 Signed-off-by: Yann Gautier --- bl32/sp_min/sp_min.ld.S | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bl32/sp_min/sp_min.ld.S b/bl32/sp_min/sp_min.ld.S index 5223915e5..f202c7ada 100644 --- a/bl32/sp_min/sp_min.ld.S +++ b/bl32/sp_min/sp_min.ld.S @@ -140,4 +140,6 @@ SECTIONS __RW_END__ = .; __BL32_END__ = .; + + ASSERT(. <= BL32_LIMIT, "BL32 image has exceeded its limit.") } -- cgit v1.2.3 From 1f19411a14cbe5693ff3df203964481e6ee57a83 Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Mon, 17 Aug 2020 08:52:33 +0200 Subject: docs: code review guidelines Document the code review process in TF-A. Specifically: * Give an overview of code review and best practices. * Give guidelines for the participants in code review. * Outline responsibilities of each type of participant. * Explain the Gerrit labels used in the review process. Change-Id: I519ca4b2859601a7b897706e310f149a0c92e390 Signed-off-by: Sandrine Bailleux Signed-off-by: David Horstmann --- docs/process/code-review-guidelines.rst | 216 ++++++++++++++++++++++++++++++++ docs/process/coding-style.rst | 2 + docs/process/contributing.rst | 2 + docs/process/index.rst | 1 + 4 files changed, 221 insertions(+) create mode 100644 docs/process/code-review-guidelines.rst diff --git a/docs/process/code-review-guidelines.rst b/docs/process/code-review-guidelines.rst new file mode 100644 index 000000000..67a211f75 --- /dev/null +++ b/docs/process/code-review-guidelines.rst @@ -0,0 +1,216 @@ +Code Review Guidelines +====================== + +This document provides TF-A specific details about the project's code review +process. It should be read in conjunction with the `Project Maintenance +Process`_, which it supplements. + + +Why do we do code reviews? +-------------------------- + +The main goal of code reviews is to improve the code quality. By reviewing each +other's code, we can help catch issues that were missed by the author +before they are integrated in the source tree. Different people bring different +perspectives, depending on their past work, experiences and their current use +cases of TF-A in their products. + +Code reviews also play a key role in sharing knowledge within the +community. People with more expertise in one area of the code base can +help those that are less familiar with it. + +Code reviews are meant to benefit everyone through team work. It is not about +unfairly criticizing or belittling the work of any contributor. + + +Good practices +-------------- + +To ensure the code review gives the greatest possible benefit, participants in +the project should: + +- Be considerate of other people and their needs. Participants may be working + to different timescales, and have different priorities. Keep this in + mind - be gracious while waiting for action from others, and timely in your + actions when others are waiting for you. + +- Review other people's patches where possible. The more active reviewers there + are, the more quickly new patches can be reviewed and merged. Contributing to + code review helps everyone in the long run, as it creates a culture of + participation which serves everyone's interests. + + +Guidelines for patch contributors +--------------------------------- + +In addition to the rules outlined in the :ref:`Contributor's Guide`, as a patch +contributor you are expected to: + +- Answer all comments from people who took the time to review your + patches. + +- Be patient and resilient. It is quite common for patches to go through + several rounds of reviews and rework before they get approved, especially + for larger features. + + In the event that a code review takes longer than you would hope for, you + may try the following actions to speed it up: + + - Ping the reviewers on Gerrit or on the mailing list. If it is urgent, + explain why. Please remain courteous and do not abuse this. + + - If one code owner has become unresponsive, ask the other code owners for + help progressing the patch. + + - If there is only one code owner and they have become unresponsive, ask one + of the project maintainers for help. + +- Do the right thing for the project, not the fastest thing to get code merged. + + For example, if some existing piece of code - say a driver - does not quite + meet your exact needs, go the extra mile and extend the code with the missing + functionality you require - as opposed to copying the code into some other + directory to have the freedom to change it in any way. This way, your changes + benefit everyone and will be maintained over time. + + +Guidelines for all reviewers +---------------------------- + +There are no good or bad review comments. If you have any doubt about a patch or +need some clarifications, it's better to ask rather than letting a potential +issue slip. Examples of review comments could be: + +- Questions ("Why do you need to do this?", "What if X happens?") +- Bugs ("I think you need a logical \|\| rather than a bitwise \|.") +- Design issues ("This won't scale well when we introduce feature X.") +- Improvements ("Would it be better if we did Y instead?") + + +Guidelines for code owners +-------------------------- + +Code owners are listed on the :ref:`Project Maintenance` page, +along with the module(s) they look after. + +When reviewing a patch, code owners are expected to check the following: + +- The patch looks good from a technical point of view. For example: + + - The structure of the code is clear. + + - It complies with the relevant standards or technical documentation (where + applicable). + + - It leverages existing interfaces rather than introducing new ones + unnecessarily. + + - It fits well in the design of the module. + + - It adheres to the security model of the project. In particular, it does not + increase the attack surface (e.g. new SMCs) without justification. + +- The patch adheres to the TF-A :ref:`Coding Style`. The CI system should help + catch coding style violations. + +- (Only applicable to generic code) The code is MISRA-compliant (see + :ref:`misra-compliance`). The CI system should help catch violations. + +- Documentation is provided/updated (where applicable). + +- The patch has had an appropriate level of testing. Testing details are + expected to be provided by the patch author. If they are not, do not hesitate + to request this information. + +- All CI automated tests pass. + +If a code owner is happy with a patch, they should give their approval +through the ``Code-Owner-Review+1`` label in Gerrit. If instead, they have +concerns, questions, or any other type of blocking comment, they should set +``Code-Owner-Review-1``. + +Code owners are expected to behave professionally and responsibly. Here are some +guidelines for them: + +- Once you are engaged in a review, make sure you stay involved until the patch + is merged. Rejecting a patch and going away is not very helpful. You are + expected to monitor the patch author's answers to your review comments, + answer back if needed and review new revisions of their patch. + +- Provide constructive feedback. Just saying, "This is wrong, you should do X + instead." is usually not very helpful. The patch author is unlikely to + understand why you are requesting this change and might feel personally + attacked. + +- Be mindful when reviewing a patch. As a code owner, you are viewed as + the expert for the relevant module. By approving a patch, you are partially + responsible for its quality and the effects it has for all TF-A users. Make + sure you fully understand what the implications of a patch might be. + + +Guidelines for maintainers +-------------------------- + +Maintainers are listed on the :ref:`Project Maintenance` page. + +When reviewing a patch, maintainers are expected to check the following: + +- The general structure of the patch looks good. This covers things like: + + - Code organization. + + - Files and directories, names and locations. + + For example, platform code should be added under the ``plat/`` directory. + + - Naming conventions. + + For example, platform identifiers should be properly namespaced to avoid + name clashes with generic code. + + - API design. + +- Interaction of the patch with other modules in the code base. + +- The patch aims at complying with any standard or technical documentation + that applies. + +- New files must have the correct license and copyright headers. See :ref:`this + paragraph` for more information. The CI system + should help catch files with incorrect or no copyright/license headers. + +- There is no third party code or binary blobs with potential IP concerns. + Maintainers should look for copyright or license notices in code, and use + their best judgement. If they are unsure about a patch, they should ask + other maintainers for help. + +- Generally speaking, new driver code should be placed in the generic + layer. There are cases where a driver has to stay into the platform layer but + this should be the exception, rather than the rule. + +- Existing common drivers (in particular for Arm IPs like the GIC driver) should + not be copied into the platform layer to cater for platform quirks. This + type of code duplication hurts the maintainability of the project. The + duplicate driver is less likely to benefit from bug fixes and future + enhancements. In most cases, it is possible to rework a generic driver to + make it more flexible and fit slightly different use cases. That way, these + enhancements benefit everyone. + +- When a platform specific driver really is required, the burden lies with the + patch author to prove the need for it. A detailed justification should be + posted via the commit message or on the mailing list. + +- Before merging a patch, verify that all review comments have been addressed. + If this is not the case, encourage the patch author and the relevant + reviewers to resolve these together. + +If a maintainer is happy with a patch, they should give their approval +through the ``Maintainer-Review+1`` label in Gerrit. If instead, they have +concerns, questions, or any other type of blocking comment, they should set +``Maintainer-Review-1``. + +-------------- + +*Copyright (c) 2020, Arm Limited. All rights reserved.* + +.. _Project Maintenance Process: https://developer.trustedfirmware.org/w/collaboration/project-maintenance-process/ diff --git a/docs/process/coding-style.rst b/docs/process/coding-style.rst index fd1984d30..94fd85e36 100644 --- a/docs/process/coding-style.rst +++ b/docs/process/coding-style.rst @@ -42,6 +42,8 @@ Both GCC and Clang compiler toolchains have support for *GNU99* mode, though Clang does lack support for a small number of GNU extensions. These missing extensions are rarely used, however, and should not pose a problem. +.. _misra-compliance: + MISRA Compliance ---------------- diff --git a/docs/process/contributing.rst b/docs/process/contributing.rst index 0b3b848f4..15c2b4529 100644 --- a/docs/process/contributing.rst +++ b/docs/process/contributing.rst @@ -90,6 +90,8 @@ Making Changes (and nothing else) in the last commit of the series. Otherwise, include the documentation changes within the single commit. +.. _copyright-license-guidance: + - Ensure that each changed file has the correct copyright and license information. Files that entirely consist of contributions to this project should have a copyright notice and BSD-3-Clause SPDX license identifier of diff --git a/docs/process/index.rst b/docs/process/index.rst index 1cb535405..37324b0e9 100644 --- a/docs/process/index.rst +++ b/docs/process/index.rst @@ -11,5 +11,6 @@ Processes & Policies coding-style coding-guidelines contributing + code-review-guidelines faq security-hardening -- cgit v1.2.3 From 5effe0beba9ebb115e0a0c79dccf93bd9272c7e4 Mon Sep 17 00:00:00 2001 From: Jimmy Brisson Date: Wed, 30 Sep 2020 15:34:51 -0500 Subject: Rename Cortex Hercules AE to Cortex 78 AE Change-Id: Ic0ca51a855660509264ff0d084c068e1421ad09a Signed-off-by: Jimmy Brisson --- include/lib/cpus/aarch64/cortex_a78_ae.h | 14 ++++ include/lib/cpus/aarch64/cortex_hercules_ae.h | 14 ---- lib/cpus/aarch64/cortex_a78_ae.S | 100 ++++++++++++++++++++++++++ lib/cpus/aarch64/cortex_hercules_ae.S | 100 -------------------------- plat/arm/board/arm_fpga/platform.mk | 2 +- plat/arm/board/fvp/platform.mk | 2 +- 6 files changed, 116 insertions(+), 116 deletions(-) create mode 100644 include/lib/cpus/aarch64/cortex_a78_ae.h delete mode 100644 include/lib/cpus/aarch64/cortex_hercules_ae.h create mode 100644 lib/cpus/aarch64/cortex_a78_ae.S delete mode 100644 lib/cpus/aarch64/cortex_hercules_ae.S diff --git a/include/lib/cpus/aarch64/cortex_a78_ae.h b/include/lib/cpus/aarch64/cortex_a78_ae.h new file mode 100644 index 000000000..24ae7eeac --- /dev/null +++ b/include/lib/cpus/aarch64/cortex_a78_ae.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2019-2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CORTEX_A78_AE_H +#define CORTEX_A78_AE_H + +#include + +#define CORTEX_A78_AE_MIDR U(0x410FD420) + +#endif /* CORTEX_A78_AE_H */ diff --git a/include/lib/cpus/aarch64/cortex_hercules_ae.h b/include/lib/cpus/aarch64/cortex_hercules_ae.h deleted file mode 100644 index 73c22f732..000000000 --- a/include/lib/cpus/aarch64/cortex_hercules_ae.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2019-2020, ARM Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef CORTEX_HERCULES_AE_H -#define CORTEX_HERCULES_AE_H - -#include - -#define CORTEX_HERCULES_AE_MIDR U(0x410FD420) - -#endif /* CORTEX_HERCULES_AE_H */ diff --git a/lib/cpus/aarch64/cortex_a78_ae.S b/lib/cpus/aarch64/cortex_a78_ae.S new file mode 100644 index 000000000..9aff9ac85 --- /dev/null +++ b/lib/cpus/aarch64/cortex_a78_ae.S @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2019-2020, 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_a78_ae must be compiled with HW_ASSISTED_COHERENCY enabled" +#endif + + /* ------------------------------------------------- + * The CPU Ops reset function for Cortex-A78-AE + * ------------------------------------------------- + */ +#if ENABLE_AMU +func cortex_a78_ae_reset_func + /* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */ + mrs x0, actlr_el3 + bic x0, x0, #CORTEX_A78_ACTLR_TAM_BIT + msr actlr_el3, x0 + + /* Make sure accesses from non-secure EL0/EL1 are not trapped to EL2 */ + mrs x0, actlr_el2 + bic x0, x0, #CORTEX_A78_ACTLR_TAM_BIT + msr actlr_el2, x0 + + /* Enable group0 counters */ + mov x0, #CORTEX_A78_AMU_GROUP0_MASK + msr CPUAMCNTENSET0_EL0, x0 + + /* Enable group1 counters */ + mov x0, #CORTEX_A78_AMU_GROUP1_MASK + msr CPUAMCNTENSET1_EL0, x0 + isb + + ret +endfunc cortex_a78_ae_reset_func +#endif + + /* ------------------------------------------------------- + * HW will do the cache maintenance while powering down + * ------------------------------------------------------- + */ +func cortex_a78_ae_core_pwr_dwn + /* ------------------------------------------------------- + * Enable CPU power down bit in power control register + * ------------------------------------------------------- + */ + mrs x0, CORTEX_A78_CPUPWRCTLR_EL1 + orr x0, x0, #CORTEX_A78_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT + msr CORTEX_A78_CPUPWRCTLR_EL1, x0 + isb + ret +endfunc cortex_a78_ae_core_pwr_dwn + + /* + * Errata printing function for cortex_a78_ae. Must follow AAPCS. + */ +#if REPORT_ERRATA +func cortex_a78_ae_errata_report + ret +endfunc cortex_a78_ae_errata_report +#endif + + /* ------------------------------------------------------- + * This function provides cortex_a78_ae 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_a78_ae_regs, "aS" +cortex_a78_ae_regs: /* The ascii list of register names to be reported */ + .asciz "cpuectlr_el1", "" + +func cortex_a78_ae_cpu_reg_dump + adr x6, cortex_a78_ae_regs + mrs x8, CORTEX_A78_CPUECTLR_EL1 + ret +endfunc cortex_a78_ae_cpu_reg_dump + +#if ENABLE_AMU +#define A78_AE_RESET_FUNC cortex_a78_ae_reset_func +#else +#define A78_AE_RESET_FUNC CPU_NO_RESET_FUNC +#endif + +declare_cpu_ops cortex_a78_ae, CORTEX_A78_AE_MIDR, \ + A78_AE_RESET_FUNC, \ + cortex_a78_ae_core_pwr_dwn diff --git a/lib/cpus/aarch64/cortex_hercules_ae.S b/lib/cpus/aarch64/cortex_hercules_ae.S deleted file mode 100644 index 4452c419a..000000000 --- a/lib/cpus/aarch64/cortex_hercules_ae.S +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2019-2020, 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_hercules_ae must be compiled with HW_ASSISTED_COHERENCY enabled" -#endif - - /* ------------------------------------------------- - * The CPU Ops reset function for Cortex-Hercules-AE - * ------------------------------------------------- - */ -#if ENABLE_AMU -func cortex_hercules_ae_reset_func - /* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */ - mrs x0, actlr_el3 - bic x0, x0, #CORTEX_A78_ACTLR_TAM_BIT - msr actlr_el3, x0 - - /* Make sure accesses from non-secure EL0/EL1 are not trapped to EL2 */ - mrs x0, actlr_el2 - bic x0, x0, #CORTEX_A78_ACTLR_TAM_BIT - msr actlr_el2, x0 - - /* Enable group0 counters */ - mov x0, #CORTEX_A78_AMU_GROUP0_MASK - msr CPUAMCNTENSET0_EL0, x0 - - /* Enable group1 counters */ - mov x0, #CORTEX_A78_AMU_GROUP1_MASK - msr CPUAMCNTENSET1_EL0, x0 - isb - - ret -endfunc cortex_hercules_ae_reset_func -#endif - - /* ------------------------------------------------------- - * HW will do the cache maintenance while powering down - * ------------------------------------------------------- - */ -func cortex_hercules_ae_core_pwr_dwn - /* ------------------------------------------------------- - * Enable CPU power down bit in power control register - * ------------------------------------------------------- - */ - mrs x0, CORTEX_A78_CPUPWRCTLR_EL1 - orr x0, x0, #CORTEX_A78_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT - msr CORTEX_A78_CPUPWRCTLR_EL1, x0 - isb - ret -endfunc cortex_hercules_ae_core_pwr_dwn - - /* - * Errata printing function for cortex_hercules_ae. Must follow AAPCS. - */ -#if REPORT_ERRATA -func cortex_hercules_ae_errata_report - ret -endfunc cortex_hercules_ae_errata_report -#endif - - /* ------------------------------------------------------- - * This function provides cortex_hercules_ae 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_hercules_ae_regs, "aS" -cortex_hercules_ae_regs: /* The ascii list of register names to be reported */ - .asciz "cpuectlr_el1", "" - -func cortex_hercules_ae_cpu_reg_dump - adr x6, cortex_hercules_ae_regs - mrs x8, CORTEX_A78_CPUECTLR_EL1 - ret -endfunc cortex_hercules_ae_cpu_reg_dump - -#if ENABLE_AMU -#define HERCULES_AE_RESET_FUNC cortex_hercules_ae_reset_func -#else -#define HERCULES_AE_RESET_FUNC CPU_NO_RESET_FUNC -#endif - -declare_cpu_ops cortex_hercules_ae, CORTEX_HERCULES_AE_MIDR, \ - HERCULES_AE_RESET_FUNC, \ - cortex_hercules_ae_core_pwr_dwn diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk index ab576b6ea..4b309fd03 100644 --- a/plat/arm/board/arm_fpga/platform.mk +++ b/plat/arm/board/arm_fpga/platform.mk @@ -62,7 +62,7 @@ else lib/cpus/aarch64/neoverse_n1.S \ lib/cpus/aarch64/neoverse_e1.S \ lib/cpus/aarch64/neoverse_zeus.S \ - lib/cpus/aarch64/cortex_hercules_ae.S \ + lib/cpus/aarch64/cortex_a78_ae.S \ lib/cpus/aarch64/cortex_a65.S \ lib/cpus/aarch64/cortex_a65ae.S \ lib/cpus/aarch64/cortex_klein.S \ diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 4565d05ac..f2a2ede80 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -121,7 +121,7 @@ else lib/cpus/aarch64/neoverse_n1.S \ lib/cpus/aarch64/neoverse_e1.S \ lib/cpus/aarch64/neoverse_zeus.S \ - lib/cpus/aarch64/cortex_hercules_ae.S \ + lib/cpus/aarch64/cortex_a78_ae.S \ lib/cpus/aarch64/cortex_klein.S \ lib/cpus/aarch64/cortex_matterhorn.S \ lib/cpus/aarch64/cortex_a65.S \ -- cgit v1.2.3 From 467937b63d90cd65d74c3cb29561d495660612bd Mon Sep 17 00:00:00 2001 From: Jimmy Brisson Date: Wed, 30 Sep 2020 15:28:03 -0500 Subject: Rename Neoverse Zeus to Neoverse V1 Change-Id: Ieb411e2f8092fa82062e619305b680673a8f184f Signed-off-by: Jimmy Brisson --- include/lib/cpus/aarch64/neoverse_v1.h | 23 +++++++++ include/lib/cpus/aarch64/neoverse_zeus.h | 23 --------- lib/cpus/aarch64/neoverse_v1.S | 80 ++++++++++++++++++++++++++++++++ lib/cpus/aarch64/neoverse_zeus.S | 80 -------------------------------- plat/arm/board/arm_fpga/platform.mk | 2 +- plat/arm/board/fvp/platform.mk | 2 +- plat/arm/board/rddaniel/platform.mk | 2 +- plat/arm/board/rddanielxlr/platform.mk | 2 +- 8 files changed, 107 insertions(+), 107 deletions(-) create mode 100644 include/lib/cpus/aarch64/neoverse_v1.h delete mode 100644 include/lib/cpus/aarch64/neoverse_zeus.h create mode 100644 lib/cpus/aarch64/neoverse_v1.S delete mode 100644 lib/cpus/aarch64/neoverse_zeus.S diff --git a/include/lib/cpus/aarch64/neoverse_v1.h b/include/lib/cpus/aarch64/neoverse_v1.h new file mode 100644 index 000000000..650eb4d41 --- /dev/null +++ b/include/lib/cpus/aarch64/neoverse_v1.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2019-2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef NEOVERSE_V1_H +#define NEOVERSE_V1_H + +#define NEOVERSE_V1_MIDR U(0x410FD400) + +/******************************************************************************* + * CPU Extended Control register specific definitions. + ******************************************************************************/ +#define NEOVERSE_V1_CPUECTLR_EL1 S3_0_C15_C1_4 + +/******************************************************************************* + * CPU Power Control register specific definitions + ******************************************************************************/ +#define NEOVERSE_V1_CPUPWRCTLR_EL1 S3_0_C15_C2_7 +#define NEOVERSE_V1_CPUPWRCTLR_EL1_CORE_PWRDN_BIT U(1) + +#endif /* NEOVERSE_V1_H */ diff --git a/include/lib/cpus/aarch64/neoverse_zeus.h b/include/lib/cpus/aarch64/neoverse_zeus.h deleted file mode 100644 index f0947271d..000000000 --- a/include/lib/cpus/aarch64/neoverse_zeus.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2019, ARM Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef NEOVERSE_ZEUS_H -#define NEOVERSE_ZEUS_H - -#define NEOVERSE_ZEUS_MIDR U(0x410FD400) - -/******************************************************************************* - * CPU Extended Control register specific definitions. - ******************************************************************************/ -#define NEOVERSE_ZEUS_CPUECTLR_EL1 S3_0_C15_C1_4 - -/******************************************************************************* - * CPU Power Control register specific definitions - ******************************************************************************/ -#define NEOVERSE_ZEUS_CPUPWRCTLR_EL1 S3_0_C15_C2_7 -#define NEOVERSE_ZEUS_CPUPWRCTLR_EL1_CORE_PWRDN_BIT U(1) - -#endif /* NEOVERSE_ZEUS_H */ diff --git a/lib/cpus/aarch64/neoverse_v1.S b/lib/cpus/aarch64/neoverse_v1.S new file mode 100644 index 000000000..733629425 --- /dev/null +++ b/lib/cpus/aarch64/neoverse_v1.S @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2019-2020, 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 V1 must be compiled with HW_ASSISTED_COHERENCY enabled" +#endif + +/* 64-bit only core */ +#if CTX_INCLUDE_AARCH32_REGS == 1 +#error "Neoverse-V1 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0" +#endif + + /* --------------------------------------------- + * HW will do the cache maintenance while powering down + * --------------------------------------------- + */ +func neoverse_v1_core_pwr_dwn + /* --------------------------------------------- + * Enable CPU power down bit in power control register + * --------------------------------------------- + */ + mrs x0, NEOVERSE_V1_CPUPWRCTLR_EL1 + orr x0, x0, #NEOVERSE_V1_CPUPWRCTLR_EL1_CORE_PWRDN_BIT + msr NEOVERSE_V1_CPUPWRCTLR_EL1, x0 + isb + ret +endfunc neoverse_v1_core_pwr_dwn + + /* + * Errata printing function for Neoverse V1. Must follow AAPCS. + */ +#if REPORT_ERRATA +func neoverse_v1_errata_report + ret +endfunc neoverse_v1_errata_report +#endif + +func neoverse_v1_reset_func + mov x19, x30 + + /* Disable speculative loads */ + msr SSBS, xzr + + isb + ret x19 +endfunc neoverse_v1_reset_func + + /* --------------------------------------------- + * This function provides Neoverse-V1 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_v1_regs, "aS" +neoverse_v1_regs: /* The ascii list of register names to be reported */ + .asciz "cpuectlr_el1", "" + +func neoverse_v1_cpu_reg_dump + adr x6, neoverse_v1_regs + mrs x8, NEOVERSE_V1_CPUECTLR_EL1 + ret +endfunc neoverse_v1_cpu_reg_dump + +declare_cpu_ops neoverse_v1, NEOVERSE_V1_MIDR, \ + neoverse_v1_reset_func, \ + neoverse_v1_core_pwr_dwn diff --git a/lib/cpus/aarch64/neoverse_zeus.S b/lib/cpus/aarch64/neoverse_zeus.S deleted file mode 100644 index 44882b459..000000000 --- a/lib/cpus/aarch64/neoverse_zeus.S +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2019, 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 Zeus must be compiled with HW_ASSISTED_COHERENCY enabled" -#endif - -/* 64-bit only core */ -#if CTX_INCLUDE_AARCH32_REGS == 1 -#error "Neoverse-Zeus supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0" -#endif - - /* --------------------------------------------- - * HW will do the cache maintenance while powering down - * --------------------------------------------- - */ -func neoverse_zeus_core_pwr_dwn - /* --------------------------------------------- - * Enable CPU power down bit in power control register - * --------------------------------------------- - */ - mrs x0, NEOVERSE_ZEUS_CPUPWRCTLR_EL1 - orr x0, x0, #NEOVERSE_ZEUS_CPUPWRCTLR_EL1_CORE_PWRDN_BIT - msr NEOVERSE_ZEUS_CPUPWRCTLR_EL1, x0 - isb - ret -endfunc neoverse_zeus_core_pwr_dwn - - /* - * Errata printing function for Neoverse Zeus. Must follow AAPCS. - */ -#if REPORT_ERRATA -func neoverse_zeus_errata_report - ret -endfunc neoverse_zeus_errata_report -#endif - -func neoverse_zeus_reset_func - mov x19, x30 - - /* Disable speculative loads */ - msr SSBS, xzr - - isb - ret x19 -endfunc neoverse_zeus_reset_func - - /* --------------------------------------------- - * This function provides Neoverse-Zeus 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_zeus_regs, "aS" -neoverse_zeus_regs: /* The ascii list of register names to be reported */ - .asciz "cpuectlr_el1", "" - -func neoverse_zeus_cpu_reg_dump - adr x6, neoverse_zeus_regs - mrs x8, NEOVERSE_ZEUS_CPUECTLR_EL1 - ret -endfunc neoverse_zeus_cpu_reg_dump - -declare_cpu_ops neoverse_zeus, NEOVERSE_ZEUS_MIDR, \ - neoverse_zeus_reset_func, \ - neoverse_zeus_core_pwr_dwn diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk index 4b309fd03..4b751fb20 100644 --- a/plat/arm/board/arm_fpga/platform.mk +++ b/plat/arm/board/arm_fpga/platform.mk @@ -61,7 +61,7 @@ else lib/cpus/aarch64/cortex_a78.S \ lib/cpus/aarch64/neoverse_n1.S \ lib/cpus/aarch64/neoverse_e1.S \ - lib/cpus/aarch64/neoverse_zeus.S \ + lib/cpus/aarch64/neoverse_v1.S \ lib/cpus/aarch64/cortex_a78_ae.S \ lib/cpus/aarch64/cortex_a65.S \ lib/cpus/aarch64/cortex_a65ae.S \ diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index f2a2ede80..4da0d7643 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -120,7 +120,7 @@ else lib/cpus/aarch64/cortex_a78.S \ lib/cpus/aarch64/neoverse_n1.S \ lib/cpus/aarch64/neoverse_e1.S \ - lib/cpus/aarch64/neoverse_zeus.S \ + lib/cpus/aarch64/neoverse_v1.S \ lib/cpus/aarch64/cortex_a78_ae.S \ lib/cpus/aarch64/cortex_klein.S \ lib/cpus/aarch64/cortex_matterhorn.S \ diff --git a/plat/arm/board/rddaniel/platform.mk b/plat/arm/board/rddaniel/platform.mk index 8909b551c..7422d638a 100644 --- a/plat/arm/board/rddaniel/platform.mk +++ b/plat/arm/board/rddaniel/platform.mk @@ -12,7 +12,7 @@ RDDANIEL_BASE = plat/arm/board/rddaniel PLAT_INCLUDES += -I${RDDANIEL_BASE}/include/ -SGI_CPU_SOURCES := lib/cpus/aarch64/neoverse_zeus.S +SGI_CPU_SOURCES := lib/cpus/aarch64/neoverse_v1.S BL1_SOURCES += ${SGI_CPU_SOURCES} \ ${RDDANIEL_BASE}/rddaniel_err.c diff --git a/plat/arm/board/rddanielxlr/platform.mk b/plat/arm/board/rddanielxlr/platform.mk index 61af81aab..8cbad525c 100644 --- a/plat/arm/board/rddanielxlr/platform.mk +++ b/plat/arm/board/rddanielxlr/platform.mk @@ -13,7 +13,7 @@ RDDANIELXLR_BASE = plat/arm/board/rddanielxlr PLAT_INCLUDES += -I${RDDANIELXLR_BASE}/include/ -SGI_CPU_SOURCES := lib/cpus/aarch64/neoverse_zeus.S +SGI_CPU_SOURCES := lib/cpus/aarch64/neoverse_v1.S BL1_SOURCES += ${SGI_CPU_SOURCES} \ ${RDDANIELXLR_BASE}/rddanielxlr_err.c -- cgit v1.2.3 From 3bfcc9d700c93992ea900f5790e9ad4be04a0db8 Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Mon, 5 Oct 2020 10:18:52 +0100 Subject: plat/arm: common: add guard for arm_get_rotpk_info_regs Only define arm_get_rotpk_info_regs if ROTPK is in registers, i.e. (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID). This will allow platform build without definition of TZ_PUB_KEY_HASH_BASE if dedicated registers for ROTPK are not available on the platform. Change-Id: I74ee2d5007f5d876a031a1efca20ebee2dede0c7 Signed-off-by: Usama Arif --- plat/arm/board/common/board_arm_trusted_boot.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plat/arm/board/common/board_arm_trusted_boot.c b/plat/arm/board/common/board_arm_trusted_boot.c index 8239e0d1a..66cc3e949 100644 --- a/plat/arm/board/common/board_arm_trusted_boot.c +++ b/plat/arm/board/common/board_arm_trusted_boot.c @@ -47,8 +47,11 @@ uintptr_t nv_cntr_base_addr[MAX_NV_CTR_IDS] = { extern unsigned char arm_rotpk_header[], arm_rotpk_hash_end[]; +#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID) || ARM_CRYPTOCELL_INTEG static unsigned char rotpk_hash_der[ARM_ROTPK_HEADER_LEN + ARM_ROTPK_HASH_LEN]; +#endif +#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID) /* * Return the ROTPK hash stored in dedicated registers. */ @@ -85,6 +88,7 @@ int arm_get_rotpk_info_regs(void **key_ptr, unsigned int *key_len, *flags = ROTPK_IS_HASH; return 0; } +#endif #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \ (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) -- cgit v1.2.3 From 4276cfe2fa6fba6dc71a2cc3c0c2a5cc194ce542 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Wed, 7 Oct 2020 11:09:42 +0100 Subject: fdt: Fix coverity complaint about 32-bit multiplication Coverity raised an eyebrow over our GICR frame size calculation: ======== CID 362942: Integer handling issues (OVERFLOW_BEFORE_WIDEN) Potentially overflowing expression "nr_cores * gicr_frame_size" with type "unsigned int" (32 bits, unsigned) is evaluated using 32-bit arithmetic, and then used in a context that expects an expression of type "uint64_t" (64 bits, unsigned). ======== Even with a GICv4 (256KB frame size) we need 16384 cores to overflow 32-bit, so it's not a practical issue. But it's also easy to fix, so let's just do that: cast gicr_frame_size to an unsigned 64-bit integer, so that the multiplication is done in the 64-bit realm. Change-Id: Iad10e19b9e58d5fbf9d13205fbcef0aac5ae48af Signed-off-by: Andre Przywara --- common/fdt_fixup.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/common/fdt_fixup.c b/common/fdt_fixup.c index a1604e74f..e88a55008 100644 --- a/common/fdt_fixup.c +++ b/common/fdt_fixup.c @@ -425,7 +425,8 @@ int fdt_adjust_gic_redist(void *dtb, unsigned int nr_cores, redist_size_32 = cpu_to_fdt32(nr_cores * gicr_frame_size); val = &redist_size_32; } else { - redist_size_64 = cpu_to_fdt64(nr_cores * gicr_frame_size); + redist_size_64 = cpu_to_fdt64(nr_cores * + (uint64_t)gicr_frame_size); val = &redist_size_64; } -- cgit v1.2.3 From 35c75377a0642a75a0b8d0b309ae231da15bc470 Mon Sep 17 00:00:00 2001 From: johpow01 Date: Thu, 10 Sep 2020 13:39:26 -0500 Subject: Workaround for Cortex A77 erratum 1925769 Cortex A77 erratum 1925769 is a Cat B erratum, present in older revisions of the Cortex A77 processor core. The workaround is to set bit 8 in the ECTLR_EL1 register, there is a small performance cost (<0.5%) for setting this bit. SDEN can be found here: https://documentation-service.arm.com/static/5f7c35d0d3be967f7be46d33 Signed-off-by: John Powell Change-Id: I9cf0e0b5dc1e3e32e24279d2632c759cc7bd7ce9 --- docs/design/cpu-specific-build-macros.rst | 3 +++ include/lib/cpus/aarch64/cortex_a77.h | 1 + lib/cpus/aarch64/cortex_a77.S | 35 +++++++++++++++++++++++++++++++ lib/cpus/cpu-ops.mk | 8 +++++++ 4 files changed, 47 insertions(+) diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst index 8152c00d5..c976b8b3a 100644 --- a/docs/design/cpu-specific-build-macros.rst +++ b/docs/design/cpu-specific-build-macros.rst @@ -260,6 +260,9 @@ For Cortex-A77, the following errata build flags are defined : - ``ERRATA_A77_1800714``: This applies errata 1800714 workaround to Cortex-A77 CPU. This needs to be enabled only for revision <= r1p1 of the CPU. +- ``ERRATA_A77_1925769``: This applies errata 1925769 workaround to Cortex-A77 + CPU. This needs to be enabled only for revision <= r1p1 of the CPU. + For Cortex-A78, the following errata build flags are defined : - ``ERRATA_A78_1688305``: This applies errata 1688305 workaround to Cortex-A78 diff --git a/include/lib/cpus/aarch64/cortex_a77.h b/include/lib/cpus/aarch64/cortex_a77.h index 41aced8d2..ed84c0f4a 100644 --- a/include/lib/cpus/aarch64/cortex_a77.h +++ b/include/lib/cpus/aarch64/cortex_a77.h @@ -16,6 +16,7 @@ * CPU Extended Control register specific definitions. ******************************************************************************/ #define CORTEX_A77_CPUECTLR_EL1 S3_0_C15_C1_4 +#define CORTEX_A77_CPUECTLR_EL1_BIT_8 (ULL(1) << 8) #define CORTEX_A77_CPUECTLR_EL1_BIT_53 (ULL(1) << 53) /******************************************************************************* diff --git a/lib/cpus/aarch64/cortex_a77.S b/lib/cpus/aarch64/cortex_a77.S index ea219998f..04a610e49 100644 --- a/lib/cpus/aarch64/cortex_a77.S +++ b/lib/cpus/aarch64/cortex_a77.S @@ -114,6 +114,35 @@ func check_errata_1800714 b cpu_rev_var_ls endfunc check_errata_1800714 + /* -------------------------------------------------- + * Errata Workaround for Cortex A77 Errata #1925769. + * This applies to revision <= r1p1 of Cortex A77. + * Inputs: + * x0: variant[4:7] and revision[0:3] of current cpu. + * Shall clobber: x0-x17 + * -------------------------------------------------- + */ +func errata_a77_1925769_wa + /* Compare x0 against revision <= r1p1 */ + mov x17, x30 + bl check_errata_1925769 + cbz x0, 1f + + /* Set bit 8 in ECTLR_EL1 */ + mrs x1, CORTEX_A77_CPUECTLR_EL1 + orr x1, x1, #CORTEX_A77_CPUECTLR_EL1_BIT_8 + msr CORTEX_A77_CPUECTLR_EL1, x1 + isb +1: + ret x17 +endfunc errata_a77_1925769_wa + +func check_errata_1925769 + /* Applies to everything <= r1p1 */ + mov x1, #0x11 + b cpu_rev_var_ls +endfunc check_errata_1925769 + /* ------------------------------------------------- * The CPU Ops reset function for Cortex-A77. * Shall clobber: x0-x19 @@ -134,6 +163,11 @@ func cortex_a77_reset_func bl errata_a77_1800714_wa #endif +#if ERRATA_A77_1925769 + mov x0, x18 + bl errata_a77_1925769_wa +#endif + ret x19 endfunc cortex_a77_reset_func @@ -169,6 +203,7 @@ func cortex_a77_errata_report */ report_errata ERRATA_A77_1508412, cortex_a77, 1508412 report_errata ERRATA_A77_1800714, cortex_a77, 1800714 + report_errata ERRATA_A77_1925769, cortex_a77, 1925769 ldp x8, x30, [sp], #16 ret diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk index 925ed5f08..12105388f 100644 --- a/lib/cpus/cpu-ops.mk +++ b/lib/cpus/cpu-ops.mk @@ -290,6 +290,10 @@ ERRATA_A77_1508412 ?=0 # only to revision <= r1p1 of the Cortex A77 cpu. ERRATA_A77_1800714 ?=0 +# Flag to apply erratum 1925769 workaround during reset. This erratum applies +# only to revision <= r1p1 of the Cortex A77 cpu. +ERRATA_A77_1925769 ?=0 + # Flag to apply erratum 1688305 workaround during reset. This erratum applies # to revisions r0p0 - r1p0 of the A78 cpu. ERRATA_A78_1688305 ?=0 @@ -571,6 +575,10 @@ $(eval $(call add_define,ERRATA_A77_1508412)) $(eval $(call assert_boolean,ERRATA_A77_1800714)) $(eval $(call add_define,ERRATA_A77_1800714)) +# Process ERRATA_A77_1925769 flag +$(eval $(call assert_boolean,ERRATA_A77_1925769)) +$(eval $(call add_define,ERRATA_A77_1925769)) + # Process ERRATA_A78_1688305 flag $(eval $(call assert_boolean,ERRATA_A78_1688305)) $(eval $(call add_define,ERRATA_A78_1688305)) -- cgit v1.2.3 From 44966000ec11e22ae2d580d0291d6e1cd613895d Mon Sep 17 00:00:00 2001 From: Lionel Debieve Date: Mon, 5 Oct 2020 14:24:04 +0200 Subject: drivers: stm32_fmc2_nand: fix incorrect error detection Clear interrupt flag register after each sector read to avoid issue when checking the register status. Without clearing the interrupt, the status read doesn't wait properly the ready bit. Signed-off-by: Lionel Debieve Change-Id: If290e3f165b986f0e736bb1b5e4d3dad4b749d74 --- drivers/st/fmc/stm32_fmc2_nand.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/st/fmc/stm32_fmc2_nand.c b/drivers/st/fmc/stm32_fmc2_nand.c index dbbeee4c5..5eee4f3b9 100644 --- a/drivers/st/fmc/stm32_fmc2_nand.c +++ b/drivers/st/fmc/stm32_fmc2_nand.c @@ -37,6 +37,7 @@ #define FMC2_PATT 0x8CU #define FMC2_HECCR 0x94U #define FMC2_BCHISR 0x254U +#define FMC2_BCHICR 0x258U #define FMC2_BCHDSR0 0x27CU #define FMC2_BCHDSR1 0x280U #define FMC2_BCHDSR2 0x284U @@ -82,6 +83,8 @@ #define FMC2_PATT_DEFAULT 0x0A0A0A0AU /* FMC2_BCHISR register */ #define FMC2_BCHISR_DERF BIT(1) +/* FMC2_BCHICR register */ +#define FMC2_BCHICR_CLEAR_IRQ GENMASK_32(4, 0) /* FMC2_BCHDSR0 register */ #define FMC2_BCHDSR0_DUE BIT(0) #define FMC2_BCHDSR0_DEF BIT(1) @@ -500,6 +503,7 @@ static void stm32_fmc2_hwctl(struct nand_device *nand) if (nand->ecc.max_bit_corr != FMC2_ECC_HAM) { mmio_clrbits_32(fmc2_base() + FMC2_PCR, FMC2_PCR_WEN); + mmio_write_32(fmc2_base() + FMC2_BCHICR, FMC2_BCHICR_CLEAR_IRQ); } stm32_fmc2_set_ecc(true); -- cgit v1.2.3 From 390181a4334c6d6425e2d97988b26e0ed0a93235 Mon Sep 17 00:00:00 2001 From: Jagadeesh Ujja Date: Wed, 7 Oct 2020 13:39:55 +0530 Subject: fdts: enable virtio-rng component for morello fvp platform enable virtio-rng component for morello fvp platform Change-Id: I89b950f067a4d14dfa418de3859c88c8f91cf7c5 Signed-off-by: Jagadeesh Ujja --- fdts/morello-fvp.dts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fdts/morello-fvp.dts b/fdts/morello-fvp.dts index ecbed5ebd..2218b2aaf 100644 --- a/fdts/morello-fvp.dts +++ b/fdts/morello-fvp.dts @@ -80,6 +80,12 @@ interrupts = ; }; + virtio_rng@1c190000 { + compatible = "virtio,mmio","virtio-rng"; + reg = <0x0 0x1c190000 0x0 0x200>; + interrupts = ; + }; + ethernet@1d100000 { compatible = "smsc,lan91c111"; reg = <0x0 0x1d100000 0x0 0x10000>; -- cgit v1.2.3 From 276a9c1bf8b2a784934fd778783bd8eabe1147c4 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Thu, 14 May 2020 16:54:12 +0200 Subject: stm32mp1: use internal MAKE_LD macro to generate stm32 linker files The previous proprietary version was not correctly handling dependencies. Using MAKE_LD from make_helpers files now correctly handles that. The generated linker script is the same as before. Change-Id: Iccfd8dc3fffa7a33e73b184b72e0dfd5d26bc9c9 Signed-off-by: Yann Gautier --- plat/st/stm32mp1/platform.mk | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk index 41eacc8fd..16c4b1cf2 100644 --- a/plat/st/stm32mp1/platform.mk +++ b/plat/st/stm32mp1/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -210,9 +210,7 @@ ${BUILD_PLAT}/stm32mp1-%.o: ${BUILD_PLAT}/fdts/%.dtb plat/st/stm32mp1/stm32mp1.S -DDTB_BIN_PATH=\"$<\" \ -c plat/st/stm32mp1/stm32mp1.S -o $@ -${STM32_TF_LINKERFILE}: plat/st/stm32mp1/stm32mp1.ld.S ${BUILD_PLAT} - @echo " LDS $<" - ${Q}${AS} ${ASFLAGS} ${TF_CFLAGS} -P -E $< -o $@ +$(eval $(call MAKE_LD,${STM32_TF_LINKERFILE},plat/st/stm32mp1/stm32mp1.ld.S,2)) tf-a-%.elf: stm32mp1-%.o ${STM32_TF_LINKERFILE} @echo " LDS $<" -- cgit v1.2.3 From 49e2373cf97d1b4b2f3571d183a540e3db83af8f Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Thu, 23 Jan 2020 18:41:20 +0100 Subject: stm32mp1: use ASFLAGS for binary paths To simplify the rule that creates the concatenated binary, use ASFLAGS instead of adding all paths in the AS command line. This allows a better management if a binary is not present. Change-Id: Ic8b4566e7dedc6f55be355a92e3b214cef138d9b Signed-off-by: Yann Gautier --- plat/st/stm32mp1/platform.mk | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk index 16c4b1cf2..54f832a34 100644 --- a/plat/st/stm32mp1/platform.mk +++ b/plat/st/stm32mp1/platform.mk @@ -179,10 +179,11 @@ STM32IMAGE ?= ${STM32IMAGEPATH}/stm32image${BIN_EXT} all: check_dtc_version ${STM32_TF_STM32} stm32image +ASFLAGS += -DBL2_BIN_PATH=\"${BUILD_PLAT}/bl2.bin\" ifeq ($(AARCH32_SP),sp_min) # BL32 is built only if using SP_MIN BL32_DEP := bl32 -BL32_PATH := -DBL32_BIN_PATH=\"${BUILD_PLAT}/bl32.bin\" +ASFLAGS += -DBL32_BIN_PATH=\"${BUILD_PLAT}/bl32.bin\" endif distclean realclean clean: clean_stm32image @@ -205,8 +206,6 @@ check_dtc_version: ${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} \ - ${BL32_PATH} \ - -DBL2_BIN_PATH=\"${BUILD_PLAT}/bl2.bin\" \ -DDTB_BIN_PATH=\"$<\" \ -c plat/st/stm32mp1/stm32mp1.S -o $@ -- cgit v1.2.3 From 2eaffd51a659accf4ff73b357be891017b54eafa Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Wed, 12 Feb 2020 09:30:49 +0100 Subject: stm32mp1: sort platform.mk First put Makefile variables definition, then definitions for each feature, then C flags, then source files, then compilation rules. Change-Id: I238115ea2fe4ebafccd2135979814c27932c34e2 Signed-off-by: Yann Gautier --- plat/st/stm32mp1/platform.mk | 85 ++++++++++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 38 deletions(-) diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk index 54f832a34..f71b080d7 100644 --- a/plat/st/stm32mp1/platform.mk +++ b/plat/st/stm32mp1/platform.mk @@ -13,8 +13,6 @@ STM32_TF_VERSION ?= 0 # Enable dynamic memory mapping PLAT_XLAT_TABLES_DYNAMIC := 1 -$(eval $(call assert_boolean,PLAT_XLAT_TABLES_DYNAMIC)) -$(eval $(call add_define,PLAT_XLAT_TABLES_DYNAMIC)) ifeq ($(AARCH32_SP),sp_min) # Disable Neon support: sp_min runtime may conflict with non-secure world @@ -26,13 +24,11 @@ WORKAROUND_CVE_2017_5715:= 0 # Number of TF-A copies in the device STM32_TF_A_COPIES := 2 -$(eval $(call add_define,STM32_TF_A_COPIES)) ifeq ($(AARCH32_SP),optee) PLAT_PARTITION_MAX_ENTRIES := $(shell echo $$(($(STM32_TF_A_COPIES) + 4))) else PLAT_PARTITION_MAX_ENTRIES := $(shell echo $$(($(STM32_TF_A_COPIES) + 1))) endif -$(eval $(call add_define,PLAT_PARTITION_MAX_ENTRIES)) # Boot devices STM32MP_EMMC ?= 0 @@ -46,32 +42,60 @@ ifeq ($(filter 1,${STM32MP_EMMC} ${STM32MP_SDMMC} ${STM32MP_RAW_NAND} \ $(error "No boot device driver is enabled") endif +# Device tree +DTB_FILE_NAME ?= stm32mp157c-ev1.dtb +FDT_SOURCES := $(addprefix fdts/, $(patsubst %.dtb,%.dts,$(DTB_FILE_NAME))) +DTC_FLAGS += -Wno-unit_address_vs_reg + +# Macros and rules to build TF binary +STM32_TF_ELF_LDFLAGS := --hash-style=gnu --as-needed +STM32_TF_STM32 := $(addprefix ${BUILD_PLAT}/tf-a-, $(patsubst %.dtb,%.stm32,$(DTB_FILE_NAME))) +STM32_TF_LINKERFILE := ${BUILD_PLAT}/stm32mp1.ld + +ASFLAGS += -DBL2_BIN_PATH=\"${BUILD_PLAT}/bl2.bin\" +ifeq ($(AARCH32_SP),sp_min) +# BL32 is built only if using SP_MIN +BL32_DEP := bl32 +ASFLAGS += -DBL32_BIN_PATH=\"${BUILD_PLAT}/bl32.bin\" +endif + +# Variables for use with stm32image +STM32IMAGEPATH ?= tools/stm32image +STM32IMAGE ?= ${STM32IMAGEPATH}/stm32image${BIN_EXT} + +# Enable flags for C files $(eval $(call assert_booleans,\ - $(sort \ - STM32MP_EMMC \ - STM32MP_SDMMC \ - STM32MP_RAW_NAND \ - STM32MP_SPI_NAND \ - STM32MP_SPI_NOR \ + $(sort \ + STM32MP_EMMC \ + STM32MP_SDMMC \ + STM32MP_RAW_NAND \ + STM32MP_SPI_NAND \ + STM32MP_SPI_NOR \ + PLAT_XLAT_TABLES_DYNAMIC \ +))) + +$(eval $(call assert_numerics,\ + $(sort \ + STM32_TF_A_COPIES \ + PLAT_PARTITION_MAX_ENTRIES \ ))) $(eval $(call add_defines,\ - $(sort \ - STM32MP_EMMC \ - STM32MP_SDMMC \ - STM32MP_RAW_NAND \ - STM32MP_SPI_NAND \ - STM32MP_SPI_NOR \ + $(sort \ + STM32MP_EMMC \ + STM32MP_SDMMC \ + STM32MP_RAW_NAND \ + STM32MP_SPI_NAND \ + STM32MP_SPI_NOR \ + PLAT_XLAT_TABLES_DYNAMIC \ + STM32_TF_A_COPIES \ + PLAT_PARTITION_MAX_ENTRIES \ ))) +# Include paths and source files PLAT_INCLUDES := -Iplat/st/common/include/ PLAT_INCLUDES += -Iplat/st/stm32mp1/include/ -# Device tree -DTB_FILE_NAME ?= stm32mp157c-ev1.dtb -FDT_SOURCES := $(addprefix fdts/, $(patsubst %.dtb,%.dts,$(DTB_FILE_NAME))) -DTC_FLAGS += -Wno-unit_address_vs_reg - include lib/libfdt/libfdt.mk PLAT_BL_COMMON_SOURCES := common/fdt_wrappers.c \ @@ -165,27 +189,12 @@ ifeq ($(AARCH32_SP),optee) BL2_SOURCES += lib/optee/optee_utils.c endif -# Macros and rules to build TF binary -STM32_TF_ELF_LDFLAGS := --hash-style=gnu --as-needed -STM32_TF_STM32 := $(addprefix ${BUILD_PLAT}/tf-a-, $(patsubst %.dtb,%.stm32,$(DTB_FILE_NAME))) -STM32_TF_LINKERFILE := ${BUILD_PLAT}/stm32mp1.ld - -# Variables for use with stm32image -STM32IMAGEPATH ?= tools/stm32image -STM32IMAGE ?= ${STM32IMAGEPATH}/stm32image${BIN_EXT} - -.PHONY: check_dtc_version stm32image clean_stm32image +# Compilation rules +.PHONY: check_dtc_version stm32image clean_stm32image .SUFFIXES: all: check_dtc_version ${STM32_TF_STM32} stm32image -ASFLAGS += -DBL2_BIN_PATH=\"${BUILD_PLAT}/bl2.bin\" -ifeq ($(AARCH32_SP),sp_min) -# BL32 is built only if using SP_MIN -BL32_DEP := bl32 -ASFLAGS += -DBL32_BIN_PATH=\"${BUILD_PLAT}/bl32.bin\" -endif - distclean realclean clean: clean_stm32image stm32image: -- cgit v1.2.3 From 3e0727d6dea00bd4a3f40051bfb633adf56868ef Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Thu, 17 Sep 2020 12:28:12 +0200 Subject: stm32mp1: add macros to define PLAT_PARTITION_MAX_ENTRIES There were fixed values when computing PLAT_PARTITION_MAX_ENTRIES. Use STM32_BL33_PARTS_NUM and STM32_RUNTIME_PARTS_NUM. The first one is for the number of copies of BL33. The second one depends on the use case SP_min or OP-TEE. For OP-TEE, there are 3 partitions. For SP_min, as it is in the same binary as BL2, it is set to 0. It will be set to 1 if BL32 is in a separate binary. Change-Id: Iba4d8ec5fbc713bebfbdcd9f9426c3fded20d3ad Signed-off-by: Yann Gautier --- plat/st/stm32mp1/platform.mk | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk index f71b080d7..159689606 100644 --- a/plat/st/stm32mp1/platform.mk +++ b/plat/st/stm32mp1/platform.mk @@ -24,11 +24,15 @@ WORKAROUND_CVE_2017_5715:= 0 # Number of TF-A copies in the device STM32_TF_A_COPIES := 2 +STM32_BL33_PARTS_NUM := 1 ifeq ($(AARCH32_SP),optee) -PLAT_PARTITION_MAX_ENTRIES := $(shell echo $$(($(STM32_TF_A_COPIES) + 4))) +STM32_RUNTIME_PARTS_NUM := 3 else -PLAT_PARTITION_MAX_ENTRIES := $(shell echo $$(($(STM32_TF_A_COPIES) + 1))) +STM32_RUNTIME_PARTS_NUM := 0 endif +PLAT_PARTITION_MAX_ENTRIES := $(shell echo $$(($(STM32_TF_A_COPIES) + \ + $(STM32_BL33_PARTS_NUM) + \ + $(STM32_RUNTIME_PARTS_NUM)))) # Boot devices STM32MP_EMMC ?= 0 -- cgit v1.2.3 From 128e0b3e2e07e151f6c9c8563707ef9f60825eee Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Fri, 18 Sep 2020 10:21:29 +0200 Subject: stm32mp1: update rules for stm32image tool In heavy parallel builds, it has sometimes been seen issues with the tool not generated before it was needed. Change some rules order and dependency to solve that. Change-Id: I8f4b4f46a2ea0fe496bc66bca47c66d1c81d3c99 Signed-off-by: Yann Gautier --- plat/st/stm32mp1/platform.mk | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk index 159689606..904a51486 100644 --- a/plat/st/stm32mp1/platform.mk +++ b/plat/st/stm32mp1/platform.mk @@ -197,11 +197,13 @@ endif .PHONY: check_dtc_version stm32image clean_stm32image .SUFFIXES: -all: check_dtc_version ${STM32_TF_STM32} stm32image +all: check_dtc_version stm32image ${STM32_TF_STM32} distclean realclean clean: clean_stm32image -stm32image: +stm32image: ${STM32IMAGE} + +${STM32IMAGE}: ${STM32IMAGE_SRC} ${Q}${MAKE} CPPFLAGS="" --no-print-directory -C ${STM32IMAGEPATH} clean_stm32image: @@ -234,10 +236,12 @@ tf-a-%.bin: tf-a-%.elf @echo "Built $@ successfully" @echo -tf-a-%.stm32: tf-a-%.bin stm32image +tf-a-%.stm32: ${STM32IMAGE} tf-a-%.bin @echo - @echo "Generated $@" + @echo "Generate $@" $(eval LOADADDR = $(shell cat $(@:.stm32=.map) | grep RAM | awk '{print $$2}')) $(eval ENTRY = $(shell cat $(@:.stm32=.map) | grep "__BL2_IMAGE_START" | awk '{print $$1}')) - ${STM32IMAGE} -s $< -d $@ -l $(LOADADDR) -e ${ENTRY} -v ${STM32_TF_VERSION} + ${Q}${STM32IMAGE} -s $(word 2,$^) -d $@ \ + -l $(LOADADDR) -e ${ENTRY} \ + -v ${STM32_TF_VERSION} @echo -- cgit v1.2.3 From 38b2304158be5a3006b1d16e5f1ad3a1a43d41a6 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Fri, 18 Sep 2020 10:32:37 +0200 Subject: stm32mp1: cosmetics in platform.mk Remove some useless extra tabs or spaces. Replace some spaces with tabs. Change-Id: I0e8e2a1a1be7a1109ba7f3e3ae35e3fe1b5b4552 Signed-off-by: Yann Gautier --- plat/st/stm32mp1/platform.mk | 50 ++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk index 904a51486..359581925 100644 --- a/plat/st/stm32mp1/platform.mk +++ b/plat/st/stm32mp1/platform.mk @@ -16,7 +16,7 @@ PLAT_XLAT_TABLES_DYNAMIC := 1 ifeq ($(AARCH32_SP),sp_min) # Disable Neon support: sp_min runtime may conflict with non-secure world -TF_CFLAGS += -mfloat-abi=soft +TF_CFLAGS += -mfloat-abi=soft endif # Not needed for Cortex-A7 @@ -218,30 +218,30 @@ check_dtc_version: fi -${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 plat/st/stm32mp1/stm32mp1.S -o $@ +${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 plat/st/stm32mp1/stm32mp1.S -o $@ $(eval $(call MAKE_LD,${STM32_TF_LINKERFILE},plat/st/stm32mp1/stm32mp1.ld.S,2)) -tf-a-%.elf: stm32mp1-%.o ${STM32_TF_LINKERFILE} - @echo " LDS $<" - ${Q}${LD} -o $@ ${STM32_TF_ELF_LDFLAGS} -Map=$(@:.elf=.map) --script ${STM32_TF_LINKERFILE} $< - -tf-a-%.bin: tf-a-%.elf - ${Q}${OC} -O binary $< $@ - @echo - @echo "Built $@ successfully" - @echo - -tf-a-%.stm32: ${STM32IMAGE} tf-a-%.bin - @echo - @echo "Generate $@" - $(eval LOADADDR = $(shell cat $(@:.stm32=.map) | grep RAM | awk '{print $$2}')) - $(eval ENTRY = $(shell cat $(@:.stm32=.map) | grep "__BL2_IMAGE_START" | awk '{print $$1}')) - ${Q}${STM32IMAGE} -s $(word 2,$^) -d $@ \ - -l $(LOADADDR) -e ${ENTRY} \ - -v ${STM32_TF_VERSION} - @echo +tf-a-%.elf: stm32mp1-%.o ${STM32_TF_LINKERFILE} + @echo " LDS $<" + ${Q}${LD} -o $@ ${STM32_TF_ELF_LDFLAGS} -Map=$(@:.elf=.map) --script ${STM32_TF_LINKERFILE} $< + +tf-a-%.bin: tf-a-%.elf + ${Q}${OC} -O binary $< $@ + @echo + @echo "Built $@ successfully" + @echo + +tf-a-%.stm32: ${STM32IMAGE} tf-a-%.bin + @echo + @echo "Generate $@" + $(eval LOADADDR = $(shell cat $(@:.stm32=.map) | grep RAM | awk '{print $$2}')) + $(eval ENTRY = $(shell cat $(@:.stm32=.map) | grep "__BL2_IMAGE_START" | awk '{print $$1}')) + ${Q}${STM32IMAGE} -s $(word 2,$^) -d $@ \ + -l $(LOADADDR) -e ${ENTRY} \ + -v ${STM32_TF_VERSION} + @echo -- cgit v1.2.3 From 3e0a861e3c7b7594e617a9390ab06441abb1293f Mon Sep 17 00:00:00 2001 From: Jagadeesh Ujja Date: Wed, 7 Oct 2020 19:51:46 +0530 Subject: lib/cpus: update MIDR value for rainier cpu This patch updates the MIDR value for rainier cpu. Change-Id: I99a5d96f757239cf65b2688095c4ec66cd991cf9 Signed-off-by: Jagadeesh Ujja --- include/lib/cpus/aarch64/rainier.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/lib/cpus/aarch64/rainier.h b/include/lib/cpus/aarch64/rainier.h index 9ff166956..978661ff6 100644 --- a/include/lib/cpus/aarch64/rainier.h +++ b/include/lib/cpus/aarch64/rainier.h @@ -10,7 +10,7 @@ #include /* RAINIER MIDR for revision 0 */ -#define RAINIER_MIDR U(0x3f0f4100) +#define RAINIER_MIDR U(0x3f0f4120) /* Exception Syndrome register EC code for IC Trap */ #define RAINIER_EC_IC_TRAP U(0x1f) -- cgit v1.2.3 From 831b0e9824e6c7cb07308830c12977acb79156c7 Mon Sep 17 00:00:00 2001 From: Jimmy Brisson Date: Wed, 5 Aug 2020 13:44:05 -0500 Subject: Don't return error information from console_flush And from crash_console_flush. We ignore the error information return by console_flush in _every_ place where we call it, and casting the return type to void does not work around the MISRA violation that this causes. Instead, we collect the error information from the driver (to avoid changing that API), and don't return it to the caller. Change-Id: I1e35afe01764d5c8f0efd04f8949d333ffb688c1 Signed-off-by: Jimmy Brisson --- common/backtrace/backtrace.c | 2 +- docs/getting_started/porting-guide.rst | 5 ++--- drivers/amlogic/console/aarch64/meson_console.S | 11 +++++------ drivers/arm/pl011/aarch32/pl011_console.S | 18 ++++++++---------- drivers/arm/pl011/aarch64/pl011_console.S | 12 +++++------- drivers/cadence/uart/aarch64/cdns_console.S | 11 +++++------ drivers/console/aarch32/skeleton_console.S | 10 ++-------- drivers/console/aarch64/skeleton_console.S | 12 +++--------- drivers/console/multi_console.c | 9 ++------- .../coreboot/cbmem_console/aarch64/cbmem_console.S | 13 +++++-------- drivers/imx/uart/imx_uart.c | 5 ++--- drivers/marvell/uart/a3700_console.S | 9 ++++----- drivers/renesas/rcar/console/rcar_console.S | 7 ++----- drivers/renesas/rcar/scif/scif.S | 7 ++----- drivers/st/uart/aarch32/stm32_console.S | 18 ++++++++---------- drivers/ti/uart/aarch32/16550_console.S | 11 +++++------ drivers/ti/uart/aarch64/16550_console.S | 11 +++++------ include/common/debug.h | 2 +- include/drivers/console.h | 6 +++--- include/plat/common/platform.h | 2 +- lib/libc/assert.c | 8 ++++---- lib/psci/psci_system_off.c | 8 ++++---- plat/amlogic/common/aarch64/aml_helpers.S | 6 +++--- plat/arm/board/fvp/fvp_console.c | 2 +- plat/arm/board/fvp/fvp_err.c | 2 +- plat/arm/common/aarch32/arm_helpers.S | 6 +++--- plat/arm/common/aarch64/arm_helpers.S | 6 +++--- plat/arm/common/arm_console.c | 6 +++--- plat/brcm/board/common/bcm_console.c | 4 ++-- plat/brcm/board/stingray/aarch64/plat_helpers.S | 2 +- plat/common/aarch64/plat_common.c | 2 +- plat/hisilicon/hikey/aarch64/hikey_helpers.S | 6 +++--- plat/hisilicon/hikey960/aarch64/hikey960_helpers.S | 6 +++--- plat/hisilicon/poplar/aarch64/poplar_helpers.S | 6 +++--- plat/imx/common/imx_uart_console.S | 3 +-- plat/imx/common/lpuart_console.S | 3 +-- plat/layerscape/common/aarch64/ls_console.S | 11 +++++------ plat/marvell/armada/common/aarch64/marvell_helpers.S | 5 +++-- plat/marvell/armada/common/marvell_console.c | 6 +++--- plat/mediatek/common/drivers/uart/8250_console.S | 7 +++---- plat/mediatek/mt6795/aarch64/plat_helpers.S | 6 +++--- plat/nvidia/tegra/common/tegra_pm.c | 4 ++-- plat/nvidia/tegra/drivers/spe/shared_console.S | 20 ++++++++++---------- plat/qemu/common/aarch32/plat_helpers.S | 6 +++--- plat/qemu/common/aarch64/plat_helpers.S | 6 +++--- plat/qti/qtiseclib/inc/qtiseclib_cb_interface.h | 2 +- plat/qti/qtiseclib/src/qtiseclib_cb_interface.c | 2 +- plat/renesas/rcar/aarch64/plat_helpers.S | 2 +- plat/rpi/common/aarch64/plat_helpers.S | 4 ++-- plat/socionext/synquacer/sq_helpers.S | 6 +++--- plat/socionext/uniphier/uniphier_console.S | 3 +-- plat/socionext/uniphier/uniphier_console_setup.c | 2 +- plat/st/stm32mp1/stm32mp1_helper.S | 2 +- plat/ti/k3/common/k3_helpers.S | 6 +++--- plat/xilinx/zynqmp/aarch64/zynqmp_helpers.S | 6 +++--- 55 files changed, 160 insertions(+), 203 deletions(-) diff --git a/common/backtrace/backtrace.c b/common/backtrace/backtrace.c index a07c066ce..25e2c707b 100644 --- a/common/backtrace/backtrace.c +++ b/common/backtrace/backtrace.c @@ -261,7 +261,7 @@ void backtrace(const char *cookie) struct frame_record *fr = __builtin_frame_address(0U); /* Printing the backtrace may crash the system, flush before starting */ - (void)console_flush(); + console_flush(); fr = adjust_frame_record(fr); diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst index f3316164b..19e26e4ea 100644 --- a/docs/getting_started/porting-guide.rst +++ b/docs/getting_started/porting-guide.rst @@ -2724,12 +2724,11 @@ Function : plat_crash_console_flush [mandatory] :: Argument : void - Return : int + Return : void This API is used by the crash reporting mechanism to force write of all buffered data on the designated crash console. It should only use general purpose -registers x0 through x5 to do its work. The return value is 0 on successful -completion; otherwise the return value is -1. +registers x0 through x5 to do its work. .. _External Abort handling and RAS Support: diff --git a/drivers/amlogic/console/aarch64/meson_console.S b/drivers/amlogic/console/aarch64/meson_console.S index 39c2545e7..6d0a2d62e 100644 --- a/drivers/amlogic/console/aarch64/meson_console.S +++ b/drivers/amlogic/console/aarch64/meson_console.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -224,11 +224,11 @@ func console_meson_core_getc endfunc console_meson_core_getc /* --------------------------------------------- - * int console_meson_flush(console_t *console) + * void console_meson_flush(console_t *console) * Function to force a write of all buffered * data that hasn't been output. * In : x0 - pointer to console_t structure - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : x0, x1 * --------------------------------------------- */ @@ -242,11 +242,11 @@ func console_meson_flush endfunc console_meson_flush /* --------------------------------------------- - * int console_meson_core_flush(uintptr_t base_addr) + * void console_meson_core_flush(uintptr_t base_addr) * Function to force a write of all buffered * data that hasn't been output. * In : x0 - console base address - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : x0, x1 * --------------------------------------------- */ @@ -258,6 +258,5 @@ func console_meson_core_flush /* Wait until the transmit FIFO is empty */ 1: ldr w1, [x0, #MESON_STATUS_OFFSET] tbz w1, #MESON_STATUS_TX_EMPTY_BIT, 1b - mov w0, #0 ret endfunc console_meson_core_flush diff --git a/drivers/arm/pl011/aarch32/pl011_console.S b/drivers/arm/pl011/aarch32/pl011_console.S index 93045f03d..9caeb0c69 100644 --- a/drivers/arm/pl011/aarch32/pl011_console.S +++ b/drivers/arm/pl011/aarch32/pl011_console.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -222,17 +222,19 @@ func console_pl011_getc endfunc console_pl011_getc /* --------------------------------------------- - * int console_core_flush(uintptr_t base_addr) + * void console_core_flush(uintptr_t base_addr) * Function to force a write of all buffered * data that hasn't been output. * In : r0 - console base address - * Out : return -1 on error else return 0. + * Out : void * Clobber list : r0, r1 * --------------------------------------------- */ func console_pl011_core_flush +#if ENABLE_ASSERTIONS cmp r0, #0 - beq flush_error + ASM_ASSERT(ne) +#endif /* ENABLE_ASSERTIONS */ 1: /* Loop while the transmit FIFO is busy */ @@ -240,19 +242,15 @@ func console_pl011_core_flush tst r1, #PL011_UARTFR_BUSY bne 1b - mov r0, #0 - bx lr -flush_error: - mov r0, #-1 bx lr endfunc console_pl011_core_flush /* --------------------------------------------- - * int console_pl011_flush(console_t *console) + * void console_pl011_flush(console_t *console) * Function to force a write of all buffered * data that hasn't been output. * In : r0 - pointer to console_t structure - * Out : return -1 on error else return 0. + * Out : void * Clobber list: r0, r1 * --------------------------------------------- */ diff --git a/drivers/arm/pl011/aarch64/pl011_console.S b/drivers/arm/pl011/aarch64/pl011_console.S index 3a2a3cdb4..861d2ed22 100644 --- a/drivers/arm/pl011/aarch64/pl011_console.S +++ b/drivers/arm/pl011/aarch64/pl011_console.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -208,11 +208,11 @@ func console_pl011_getc endfunc console_pl011_getc /* --------------------------------------------- - * int console_pl011_core_flush(uintptr_t base_addr) + * void console_pl011_core_flush(uintptr_t base_addr) * Function to force a write of all buffered * data that hasn't been output. * In : x0 - console base address - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : x0, x1 * --------------------------------------------- */ @@ -225,17 +225,15 @@ func console_pl011_core_flush /* Loop until the transmit FIFO is empty */ ldr w1, [x0, #UARTFR] tbnz w1, #PL011_UARTFR_BUSY_BIT, 1b - - mov w0, #0 ret endfunc console_pl011_core_flush /* --------------------------------------------- - * int console_pl011_flush(console_t *console) + * void console_pl011_flush(console_t *console) * Function to force a write of all buffered * data that hasn't been output. * In : x0 - pointer to console_t structure - * Out : return -1 on error else return 0. + * Out : void * Clobber list : x0, x1 * --------------------------------------------- */ diff --git a/drivers/cadence/uart/aarch64/cdns_console.S b/drivers/cadence/uart/aarch64/cdns_console.S index 8e5d6a1aa..d1995e3e6 100644 --- a/drivers/cadence/uart/aarch64/cdns_console.S +++ b/drivers/cadence/uart/aarch64/cdns_console.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -184,11 +184,11 @@ func console_cdns_getc endfunc console_cdns_getc /* --------------------------------------------- - * int console_cdns_core_flush(uintptr_t base_addr) + * void console_cdns_core_flush(uintptr_t base_addr) * Function to force a write of all buffered * data that hasn't been output. * In : x0 - console base address - * Out : return -1 on error else return 0. + * Out : void * Clobber list : x0, x1 * --------------------------------------------- */ @@ -198,16 +198,15 @@ func console_cdns_core_flush ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ /* Placeholder */ - mov w0, #0 ret endfunc console_cdns_core_flush /* --------------------------------------------- - * int console_cdns_flush(console_t *console) + * void console_cdns_flush(console_t *console) * Function to force a write of all buffered * data that hasn't been output. * In : x0 - pointer to console_t structure - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : x0, x1 * --------------------------------------------- */ diff --git a/drivers/console/aarch32/skeleton_console.S b/drivers/console/aarch32/skeleton_console.S index c594f7edf..a9e13ec44 100644 --- a/drivers/console/aarch32/skeleton_console.S +++ b/drivers/console/aarch32/skeleton_console.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -149,7 +149,7 @@ endfunc console_xxx_getc * Function to force a write of all buffered * data that hasn't been output. * In : r0 - pointer to console_xxx_t struct - * Out: r0 - 0 on success, < 0 on error + * Out: void * Clobber list : r0, r1, r2, r3, r4, r5 * --------------------------------------------- */ @@ -166,11 +166,5 @@ func console_xxx_flush * all data has been flushed or there was an unrecoverable error. */ - mov r0, #0 - bx lr - - /* Jump here if an unrecoverable error has been encountered. */ -flush_error: - mov r0, #-1 bx lr endfunc console_xxx_flush diff --git a/drivers/console/aarch64/skeleton_console.S b/drivers/console/aarch64/skeleton_console.S index 9a8586775..7ea2eec9f 100644 --- a/drivers/console/aarch64/skeleton_console.S +++ b/drivers/console/aarch64/skeleton_console.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -145,11 +145,11 @@ getc_error: endfunc console_xxx_getc /* --------------------------------------------- - * int console_xxx_flush(console_xxx_t *console) + * void console_xxx_flush(console_xxx_t *console) * Function to force a write of all buffered * data that hasn't been output. * In : x0 - pointer to console_xxx_t struct - * Out: w0 - 0 on success, < 0 on error + * Out: void * Clobber list : x0, x1, x2, x3, x4, x5 * --------------------------------------------- */ @@ -166,11 +166,5 @@ func console_xxx_flush * all data has been flushed or there was an unrecoverable error. */ - mov w0, #0 - ret - - /* Jump here if an unrecoverable error has been encountered. */ -flush_error: - mov w0, #-1 ret endfunc console_xxx_flush diff --git a/drivers/console/multi_console.c b/drivers/console/multi_console.c index 0665f202f..08b8e9fb1 100644 --- a/drivers/console/multi_console.c +++ b/drivers/console/multi_console.c @@ -119,17 +119,12 @@ int console_getc(void) return err; } -int console_flush(void) +void console_flush(void) { - int err = ERROR_NO_VALID_CONSOLE; console_t *console; for (console = console_list; console != NULL; console = console->next) if ((console->flags & console_state) && (console->flush != NULL)) { - int ret = console->flush(console); - if ((err == ERROR_NO_VALID_CONSOLE) || (ret < err)) - err = ret; + console->flush(console); } - - return err; } diff --git a/drivers/coreboot/cbmem_console/aarch64/cbmem_console.S b/drivers/coreboot/cbmem_console/aarch64/cbmem_console.S index a4a7bf8f3..db07e6c0b 100644 --- a/drivers/coreboot/cbmem_console/aarch64/cbmem_console.S +++ b/drivers/coreboot/cbmem_console/aarch64/cbmem_console.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -82,20 +82,17 @@ putc_write_back: endfunc console_cbmc_putc /* ----------------------------------------------- - * int console_cbmc_flush(console_cbmc_t *console) + * void console_cbmc_flush(console_cbmc_t *console) * Flushes the CBMEM console by flushing the * console buffer from the CPU's data cache. * In: x0 - pointer to console_cbmc_t struct - * Out: x0 - 0 for success - * Clobber list: x0, x1, x2, x3, x5 + * Out: void + * Clobber list: x0, x1, x2, x3 * ----------------------------------------------- */ func console_cbmc_flush - mov x5, x30 ldr x1, [x0, #CONSOLE_T_CBMC_SIZE] ldr x0, [x0, #CONSOLE_T_BASE] add x1, x1, #8 /* add size of console header */ - bl clean_dcache_range /* (clobbers x2 and x3) */ - mov x0, #0 - ret x5 + b clean_dcache_range /* (clobbers x2 and x3) */ endfunc console_cbmc_flush diff --git a/drivers/imx/uart/imx_uart.c b/drivers/imx/uart/imx_uart.c index 2c9652d19..dfe2e92b9 100644 --- a/drivers/imx/uart/imx_uart.c +++ b/drivers/imx/uart/imx_uart.c @@ -171,12 +171,11 @@ int console_imx_uart_core_getc(uintptr_t base_addr) * Function to force a write of all buffered * data that hasn't been output. * In : r0 - console base address - * Out : return -1 on error else return 0. + * Out : void * Clobber list : r0, r1 * --------------------------------------------- */ -int console_imx_uart_core_flush(uintptr_t base_addr) +void console_imx_uart_core_flush(uintptr_t base_addr) { - return 0; } diff --git a/drivers/marvell/uart/a3700_console.S b/drivers/marvell/uart/a3700_console.S index ecd494ca7..d184a2d24 100644 --- a/drivers/marvell/uart/a3700_console.S +++ b/drivers/marvell/uart/a3700_console.S @@ -223,25 +223,24 @@ func console_a3700_getc endfunc console_a3700_getc /* --------------------------------------------- - * int console_a3700_core_flush(uintptr_t base_addr) + * void console_a3700_core_flush(uintptr_t base_addr) * Function to force a write of all buffered * data that hasn't been output. * In : x0 - console base address - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : x0, x1 * --------------------------------------------- */ func console_a3700_core_flush - mov w0, #0 ret endfunc console_a3700_core_flush /* --------------------------------------------- - * int console_a3700_flush(console_t *console) + * void console_a3700_flush(console_t *console) * Function to force a write of all buffered * data that hasn't been output. * In : x0 - pointer to console_t structure - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : x0, x1 * --------------------------------------------- */ diff --git a/drivers/renesas/rcar/console/rcar_console.S b/drivers/renesas/rcar/console/rcar_console.S index 4d006b703..29baa67a4 100644 --- a/drivers/renesas/rcar/console/rcar_console.S +++ b/drivers/renesas/rcar/console/rcar_console.S @@ -82,15 +82,12 @@ func console_rcar_putc endfunc console_rcar_putc /* --------------------------------------------- - * int console_rcar_flush(void) + * void console_rcar_flush(void) * Function to force a write of all buffered - * data that hasn't been output. It returns 0 - * upon successful completion, otherwise it - * returns -1. + * data that hasn't been output. It returns void * Clobber list : x0, x1 * --------------------------------------------- */ func console_rcar_flush - mov w0, #0 ret endfunc console_rcar_flush diff --git a/drivers/renesas/rcar/scif/scif.S b/drivers/renesas/rcar/scif/scif.S index 064aba471..ae26cc402 100644 --- a/drivers/renesas/rcar/scif/scif.S +++ b/drivers/renesas/rcar/scif/scif.S @@ -305,11 +305,9 @@ func console_rcar_putc endfunc console_rcar_putc /* --------------------------------------------- - * int console_rcar_flush(void) + * void console_rcar_flush(void) * Function to force a write of all buffered - * data that hasn't been output. It returns 0 - * upon successful completion, otherwise it - * returns -1. + * data that hasn't been output. It returns void * Clobber list : x0, x1 * --------------------------------------------- */ @@ -327,6 +325,5 @@ func console_rcar_flush and w1, w1, #~(SCSCR_TE_EN + SCSCR_RE_EN) strh w1, [x0, #SCIF_SCSCR] - mov w0, #0 ret endfunc console_rcar_flush diff --git a/drivers/st/uart/aarch32/stm32_console.S b/drivers/st/uart/aarch32/stm32_console.S index 0ed37d1bd..686b18b96 100644 --- a/drivers/st/uart/aarch32/stm32_console.S +++ b/drivers/st/uart/aarch32/stm32_console.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -193,37 +193,35 @@ func console_stm32_core_getc endfunc console_stm32_core_getc /* --------------------------------------------------------------- - * int console_core_flush(uintptr_t base_addr) + * void console_core_flush(uintptr_t base_addr) * * Function to force a write of all buffered data that hasn't been * output. * * In : r0 - console base address - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : r0, r1 * --------------------------------------------------------------- */ func console_stm32_core_flush +#if ENABLE_ASSERTIONS cmp r0, #0 - beq flush_error + ASM_ASSERT(ne) +#endif /* ENABLE_ASSERTIONS */ /* Check Transmit Data Register Empty */ txe_loop_3: ldr r1, [r0, #USART_ISR] tst r1, #USART_ISR_TXE beq txe_loop_3 - mov r0, #0 - bx lr -flush_error: - mov r0, #-1 bx lr endfunc console_stm32_core_flush /* ------------------------------------------------------ - * int console_stm32_flush(console_t *console) + * void console_stm32_flush(console_t *console) * Function to force a write of all buffered * data that hasn't been output. * In : r0 - pointer to console_t structure - * Out : return -1 on error else return 0. + * Out : void. * Clobber list: r0, r1 * ------------------------------------------------------ */ diff --git a/drivers/ti/uart/aarch32/16550_console.S b/drivers/ti/uart/aarch32/16550_console.S index bc0b3ab1c..0429f8702 100644 --- a/drivers/ti/uart/aarch32/16550_console.S +++ b/drivers/ti/uart/aarch32/16550_console.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -232,11 +232,11 @@ func console_16550_getc endfunc console_16550_getc /* --------------------------------------------- - * int console_16550_core_flush(uintptr_t base_addr) + * void console_16550_core_flush(uintptr_t base_addr) * Function to force a write of all buffered * data that hasn't been output. * In : r0 - console base address - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : r0, r1 * --------------------------------------------- */ @@ -252,16 +252,15 @@ func console_16550_core_flush cmp r1, #(UARTLSR_TEMT | UARTLSR_THRE) bne 1b - mov r0, #0 bx lr endfunc console_16550_core_flush /* --------------------------------------------- - * int console_16550_flush(console_t *console) + * void console_16550_flush(console_t *console) * Function to force a write of all buffered * data that hasn't been output. * In : r0 - pointer to console_t structure - * Out : return -1 on error else return 0. + * Out : void * Clobber list : r0, r1 * --------------------------------------------- */ diff --git a/drivers/ti/uart/aarch64/16550_console.S b/drivers/ti/uart/aarch64/16550_console.S index 064022798..cb2151253 100644 --- a/drivers/ti/uart/aarch64/16550_console.S +++ b/drivers/ti/uart/aarch64/16550_console.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -225,11 +225,11 @@ func console_16550_getc endfunc console_16550_getc /* --------------------------------------------- - * int console_16550_core_flush(uintptr_t base_addr) + * void console_16550_core_flush(uintptr_t base_addr) * Function to force a write of all buffered * data that hasn't been output. * In : x0 - console base address - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : x0, x1 * --------------------------------------------- */ @@ -245,16 +245,15 @@ func console_16550_core_flush cmp w1, #(UARTLSR_TEMT | UARTLSR_THRE) b.ne 1b - mov w0, #0 ret endfunc console_16550_core_flush /* --------------------------------------------- - * int console_16550_flush(console_t *console) + * void console_16550_flush(console_t *console) * Function to force a write of all buffered * data that hasn't been output. * In : x0 - pointer to console_t structure - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : x0, x1 * --------------------------------------------- */ diff --git a/include/common/debug.h b/include/common/debug.h index 9aef15b51..ed0e8bf97 100644 --- a/include/common/debug.h +++ b/include/common/debug.h @@ -101,7 +101,7 @@ void __dead2 do_panic(void); #define panic() \ do { \ backtrace(__func__); \ - (void)console_flush(); \ + console_flush(); \ do_panic(); \ } while (false) diff --git a/include/drivers/console.h b/include/drivers/console.h index 761816ac7..99bf96041 100644 --- a/include/drivers/console.h +++ b/include/drivers/console.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -43,7 +43,7 @@ typedef struct console { u_register_t flags; int (*const putc)(int character, struct console *console); int (*const getc)(struct console *console); - int (*const flush)(struct console *console); + void (*const flush)(struct console *console); uintptr_t base; /* Additional private driver data may follow here. */ } console_t; @@ -76,7 +76,7 @@ int console_putc(int c); /* Read a character (blocking) from any console registered for current state. */ int console_getc(void); /* Flush all consoles registered for the current state. */ -int console_flush(void); +void console_flush(void); #endif /* __ASSEMBLER__ */ diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h index 2c1a180c8..ebcc85577 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.h @@ -111,7 +111,7 @@ uintptr_t plat_get_my_stack(void); void plat_report_exception(unsigned int exception_type); int plat_crash_console_init(void); int plat_crash_console_putc(int c); -int plat_crash_console_flush(void); +void plat_crash_console_flush(void); void plat_error_handler(int err) __dead2; void plat_panic_handler(void) __dead2; const char *plat_log_get_prefix(unsigned int log_level); diff --git a/lib/libc/assert.c b/lib/libc/assert.c index 49f59db16..ff987b3be 100644 --- a/lib/libc/assert.c +++ b/lib/libc/assert.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -23,7 +23,7 @@ void __dead2 __assert(const char *file, unsigned int line, { printf("ASSERT: %s:%d:%s\n", file, line, assertion); backtrace("assert"); - (void)console_flush(); + console_flush(); plat_panic_handler(); } #elif PLAT_LOG_LEVEL_ASSERT >= LOG_LEVEL_INFO @@ -31,14 +31,14 @@ void __dead2 __assert(const char *file, unsigned int line) { printf("ASSERT: %s:%d\n", file, line); backtrace("assert"); - (void)console_flush(); + console_flush(); plat_panic_handler(); } #else void __dead2 __assert(void) { backtrace("assert"); - (void)console_flush(); + console_flush(); plat_panic_handler(); } #endif diff --git a/lib/psci/psci_system_off.c b/lib/psci/psci_system_off.c index 141d69ef2..002392cad 100644 --- a/lib/psci/psci_system_off.c +++ b/lib/psci/psci_system_off.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -25,7 +25,7 @@ void __dead2 psci_system_off(void) psci_spd_pm->svc_system_off(); } - (void) console_flush(); + console_flush(); /* Call the platform specific hook */ psci_plat_pm_ops->system_off(); @@ -44,7 +44,7 @@ void __dead2 psci_system_reset(void) psci_spd_pm->svc_system_reset(); } - (void) console_flush(); + console_flush(); /* Call the platform specific hook */ psci_plat_pm_ops->system_reset(); @@ -77,7 +77,7 @@ u_register_t psci_system_reset2(uint32_t reset_type, u_register_t cookie) if ((psci_spd_pm != NULL) && (psci_spd_pm->svc_system_reset != NULL)) { psci_spd_pm->svc_system_reset(); } - (void) console_flush(); + console_flush(); return (u_register_t) psci_plat_pm_ops->system_reset2((int) is_vendor, reset_type, diff --git a/plat/amlogic/common/aarch64/aml_helpers.S b/plat/amlogic/common/aarch64/aml_helpers.S index 39bff0833..159c7d17f 100644 --- a/plat/amlogic/common/aarch64/aml_helpers.S +++ b/plat/amlogic/common/aarch64/aml_helpers.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -78,8 +78,8 @@ func plat_crash_console_putc endfunc plat_crash_console_putc /* --------------------------------------------- - * int plat_crash_console_flush() - * Out : return -1 on error else return 0. + * void plat_crash_console_flush() + * Out : void. * Clobber list : x0, x1 * --------------------------------------------- */ diff --git a/plat/arm/board/fvp/fvp_console.c b/plat/arm/board/fvp/fvp_console.c index 928b47bf1..1a6cd4202 100644 --- a/plat/arm/board/fvp/fvp_console.c +++ b/plat/arm/board/fvp/fvp_console.c @@ -49,6 +49,6 @@ void arm_console_runtime_init(void) void arm_console_runtime_end(void) { - (void)console_flush(); + console_flush(); (void)console_unregister(&fvp_runtime_console); } diff --git a/plat/arm/board/fvp/fvp_err.c b/plat/arm/board/fvp/fvp_err.c index 62ac882b0..c9b20905f 100644 --- a/plat/arm/board/fvp/fvp_err.c +++ b/plat/arm/board/fvp/fvp_err.c @@ -37,7 +37,7 @@ __dead2 void plat_arm_error_handler(int err) break; } - (void)console_flush(); + console_flush(); /* Setup the watchdog to reset the system as soon as possible */ sp805_refresh(ARM_SP805_TWDG_BASE, 1U); diff --git a/plat/arm/common/aarch32/arm_helpers.S b/plat/arm/common/aarch32/arm_helpers.S index badddd3a9..1da2d4cad 100644 --- a/plat/arm/common/aarch32/arm_helpers.S +++ b/plat/arm/common/aarch32/arm_helpers.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -64,10 +64,10 @@ func plat_crash_console_putc endfunc plat_crash_console_putc /* --------------------------------------------- - * int plat_crash_console_flush() + * void plat_crash_console_flush() * Function to force a write of all buffered * data that hasn't been output. - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : r0 * --------------------------------------------- */ diff --git a/plat/arm/common/aarch64/arm_helpers.S b/plat/arm/common/aarch64/arm_helpers.S index 06720589a..b47078173 100644 --- a/plat/arm/common/aarch64/arm_helpers.S +++ b/plat/arm/common/aarch64/arm_helpers.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -66,10 +66,10 @@ func plat_crash_console_putc endfunc plat_crash_console_putc /* --------------------------------------------- - * int plat_crash_console_flush() + * void plat_crash_console_flush() * Function to force a write of all buffered * data that hasn't been output. - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : r0 * --------------------------------------------- */ diff --git a/plat/arm/common/arm_console.c b/plat/arm/common/arm_console.c index c2281c42d..af5f11e46 100644 --- a/plat/arm/common/arm_console.c +++ b/plat/arm/common/arm_console.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -43,7 +43,7 @@ void __init arm_console_boot_init(void) void arm_console_boot_end(void) { - (void)console_flush(); + console_flush(); (void)console_unregister(&arm_boot_console); } @@ -62,5 +62,5 @@ void arm_console_runtime_init(void) void arm_console_runtime_end(void) { - (void)console_flush(); + console_flush(); } diff --git a/plat/brcm/board/common/bcm_console.c b/plat/brcm/board/common/bcm_console.c index d484a6f63..5f2009403 100644 --- a/plat/brcm/board/common/bcm_console.c +++ b/plat/brcm/board/common/bcm_console.c @@ -39,7 +39,7 @@ void bcm_console_boot_init(void) void bcm_console_boot_end(void) { - (void)console_flush(); + console_flush(); (void)console_unregister(&bcm_boot_console); } @@ -59,7 +59,7 @@ void bcm_console_runtime_init(void) void bcm_console_runtime_end(void) { - (void)console_flush(); + console_flush(); (void)console_unregister(&bcm_runtime_console); } diff --git a/plat/brcm/board/stingray/aarch64/plat_helpers.S b/plat/brcm/board/stingray/aarch64/plat_helpers.S index 609553248..9a2039daf 100644 --- a/plat/brcm/board/stingray/aarch64/plat_helpers.S +++ b/plat/brcm/board/stingray/aarch64/plat_helpers.S @@ -182,7 +182,7 @@ func plat_crash_console_putc endfunc plat_crash_console_putc /* --------------------------------------------- - * int plat_crash_console_flush(void) + * void plat_crash_console_flush(void) * Function to flush crash console * Clobber list : x0, x1 * --------------------------------------------- diff --git a/plat/common/aarch64/plat_common.c b/plat/common/aarch64/plat_common.c index b8a4d012e..ba4c366a9 100644 --- a/plat/common/aarch64/plat_common.c +++ b/plat/common/aarch64/plat_common.c @@ -96,7 +96,7 @@ void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie, #if HANDLE_EA_EL3_FIRST /* Skip backtrace for lower EL */ if (level != MODE_EL3) { - (void)console_flush(); + console_flush(); do_panic(); } #endif diff --git a/plat/hisilicon/hikey/aarch64/hikey_helpers.S b/plat/hisilicon/hikey/aarch64/hikey_helpers.S index 1752d3bb9..82a404ad3 100644 --- a/plat/hisilicon/hikey/aarch64/hikey_helpers.S +++ b/plat/hisilicon/hikey/aarch64/hikey_helpers.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -62,10 +62,10 @@ func plat_crash_console_putc endfunc plat_crash_console_putc /* --------------------------------------------- - * int plat_crash_console_flush() + * void plat_crash_console_flush() * Function to force a write of all buffered * data that hasn't been output. - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : x0, x1 * --------------------------------------------- */ diff --git a/plat/hisilicon/hikey960/aarch64/hikey960_helpers.S b/plat/hisilicon/hikey960/aarch64/hikey960_helpers.S index 606f2d0f9..5381369bc 100644 --- a/plat/hisilicon/hikey960/aarch64/hikey960_helpers.S +++ b/plat/hisilicon/hikey960/aarch64/hikey960_helpers.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -66,10 +66,10 @@ func plat_crash_console_putc endfunc plat_crash_console_putc /* --------------------------------------------- - * int plat_crash_console_flush() + * void plat_crash_console_flush() * Function to force a write of all buffered * data that hasn't been output. - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : x0, x1 * --------------------------------------------- */ diff --git a/plat/hisilicon/poplar/aarch64/poplar_helpers.S b/plat/hisilicon/poplar/aarch64/poplar_helpers.S index 928dbefcc..063ee6494 100644 --- a/plat/hisilicon/poplar/aarch64/poplar_helpers.S +++ b/plat/hisilicon/poplar/aarch64/poplar_helpers.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -65,10 +65,10 @@ func plat_crash_console_putc endfunc plat_crash_console_putc /* --------------------------------------------- - * int plat_crash_console_flush() + * void plat_crash_console_flush() * Function to force a write of all buffered * data that hasn't been output. - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : r0 * --------------------------------------------- */ diff --git a/plat/imx/common/imx_uart_console.S b/plat/imx/common/imx_uart_console.S index 0cb4fb870..ceeb3a76c 100644 --- a/plat/imx/common/imx_uart_console.S +++ b/plat/imx/common/imx_uart_console.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -84,6 +84,5 @@ getc_error: endfunc console_imx_uart_getc func console_imx_uart_flush - mov x0, #0 ret endfunc console_imx_uart_flush diff --git a/plat/imx/common/lpuart_console.S b/plat/imx/common/lpuart_console.S index 98b358807..ff01e3551 100644 --- a/plat/imx/common/lpuart_console.S +++ b/plat/imx/common/lpuart_console.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -72,6 +72,5 @@ getc_error: endfunc console_lpuart_getc func console_lpuart_flush - mov x0, #0 ret endfunc console_lpuart_flush diff --git a/plat/layerscape/common/aarch64/ls_console.S b/plat/layerscape/common/aarch64/ls_console.S index c1bd3f731..fb8267bc0 100644 --- a/plat/layerscape/common/aarch64/ls_console.S +++ b/plat/layerscape/common/aarch64/ls_console.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -214,11 +214,11 @@ func console_ls_16550_getc endfunc console_ls_16550_getc /* --------------------------------------------- - * int console_ls_16550_core_flush(uintptr_t base_addr) + * void console_ls_16550_core_flush(uintptr_t base_addr) * Function to force a write of all buffered * data that hasn't been output. * In : x0 - console base address - * Out : return -1 on error else return 0. + * Out : void * Clobber list : x0, x1 * --------------------------------------------- */ @@ -234,16 +234,15 @@ func console_ls_16550_core_flush cmp w1, #(UARTLSR_TEMT | UARTLSR_THRE) b.ne 1b - mov w0, #0 ret endfunc console_ls_16550_core_flush /* --------------------------------------------- - * int console_ls_16550_flush(console_t *console) + * void console_ls_16550_flush(console_t *console) * Function to force a write of all buffered * data that hasn't been output. * In : x0 - pointer to console_t structure - * Out : return -1 on error else return 0. + * Out : void * Clobber list : x0, x1 * --------------------------------------------- */ diff --git a/plat/marvell/armada/common/aarch64/marvell_helpers.S b/plat/marvell/armada/common/aarch64/marvell_helpers.S index 4ddc73db5..b798f17c5 100644 --- a/plat/marvell/armada/common/aarch64/marvell_helpers.S +++ b/plat/marvell/armada/common/aarch64/marvell_helpers.S @@ -1,4 +1,5 @@ /* + * Copyright (c) 2020, ARM Limited. All rights reserved. * Copyright (C) 2018 Marvell International Ltd. * * SPDX-License-Identifier: BSD-3-Clause @@ -90,10 +91,10 @@ func plat_crash_console_putc endfunc plat_crash_console_putc /* --------------------------------------------- - * int plat_crash_console_flush() + * void plat_crash_console_flush() * Function to force a write of all buffered * data that hasn't been output. - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : r0 * --------------------------------------------- */ diff --git a/plat/marvell/armada/common/marvell_console.c b/plat/marvell/armada/common/marvell_console.c index 17166618a..c84b004be 100644 --- a/plat/marvell/armada/common/marvell_console.c +++ b/plat/marvell/armada/common/marvell_console.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -49,7 +49,7 @@ void marvell_console_boot_init(void) void marvell_console_boot_end(void) { - (void)console_flush(); + console_flush(); (void)console_unregister(&marvell_boot_console); } @@ -70,7 +70,7 @@ void marvell_console_runtime_init(void) void marvell_console_runtime_end(void) { - (void)console_flush(); + console_flush(); (void)console_unregister(&marvell_runtime_console); } diff --git a/plat/mediatek/common/drivers/uart/8250_console.S b/plat/mediatek/common/drivers/uart/8250_console.S index 94a6c02ab..7a946f9a3 100644 --- a/plat/mediatek/common/drivers/uart/8250_console.S +++ b/plat/mediatek/common/drivers/uart/8250_console.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -149,16 +149,15 @@ getc_error: endfunc console_core_getc /* --------------------------------------------- - * int console_core_flush(uintptr_t base_addr) + * void console_core_flush(uintptr_t base_addr) * Function to force a write of all buffered * data that hasn't been output. * In : x0 - console base address - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : x0, x1 * --------------------------------------------- */ func console_core_flush /* Placeholder */ - mov w0, #0 ret endfunc console_core_flush diff --git a/plat/mediatek/mt6795/aarch64/plat_helpers.S b/plat/mediatek/mt6795/aarch64/plat_helpers.S index 94f9eaef9..aaddb2bba 100644 --- a/plat/mediatek/mt6795/aarch64/plat_helpers.S +++ b/plat/mediatek/mt6795/aarch64/plat_helpers.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -123,10 +123,10 @@ func plat_crash_console_putc endfunc plat_crash_console_putc /* --------------------------------------------- - * int plat_crash_console_flush(int c) + * void plat_crash_console_flush(int c) * Function to force a write of all buffered * data that hasn't been output. - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : x0, x1 * --------------------------------------------- */ diff --git a/plat/nvidia/tegra/common/tegra_pm.c b/plat/nvidia/tegra/common/tegra_pm.c index 27dd3a290..ec34a850d 100644 --- a/plat/nvidia/tegra/common/tegra_pm.c +++ b/plat/nvidia/tegra/common/tegra_pm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -138,7 +138,7 @@ static __dead2 void tegra_pwr_domain_power_down_wfi(const psci_power_state_t if (target_state->pwr_domain_state[PLAT_MAX_PWR_LVL] == PSTATE_ID_SOC_POWERDN) { INFO("%s: complete. Entering System Suspend...\n", __func__); - (void)console_flush(); + console_flush(); console_switch_state(0); } diff --git a/plat/nvidia/tegra/drivers/spe/shared_console.S b/plat/nvidia/tegra/drivers/spe/shared_console.S index 9196c1cd1..d1b18dd44 100644 --- a/plat/nvidia/tegra/drivers/spe/shared_console.S +++ b/plat/nvidia/tegra/drivers/spe/shared_console.S @@ -1,10 +1,11 @@ /* - * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include +#include #include #define CONSOLE_NUM_BYTES_SHIFT 24 @@ -151,33 +152,32 @@ func console_spe_getc endfunc console_spe_getc /* ------------------------------------------------- - * int console_spe_core_flush(uintptr_t base_addr) + * void console_spe_core_flush(uintptr_t base_addr) * Function to force a write of all buffered * data that hasn't been output. * In : x0 - console base address - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : x0, x1 * ------------------------------------------------- */ func console_spe_core_flush - cbz x0, flush_error +#if ENABLE_ASSERTIONS + cmp x0, #0 + ASM_ASSERT(ne) +#endif /* ENABLE_ASSERTIONS */ /* flush console */ mov w1, #(CONSOLE_RING_DOORBELL | CONSOLE_FLUSH_DATA_TO_PORT) str w1, [x0] - mov w0, #0 - ret -flush_error: - mov w0, #-1 ret endfunc console_spe_core_flush /* --------------------------------------------- - * int console_spe_flush(console_t *console) + * void console_spe_flush(console_t *console) * Function to force a write of all buffered * data that hasn't been output. * In : x0 - pointer to console_t structure - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : x0, x1 * --------------------------------------------- */ diff --git a/plat/qemu/common/aarch32/plat_helpers.S b/plat/qemu/common/aarch32/plat_helpers.S index 15e860b42..5e346d585 100644 --- a/plat/qemu/common/aarch32/plat_helpers.S +++ b/plat/qemu/common/aarch32/plat_helpers.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -125,10 +125,10 @@ func plat_crash_console_putc endfunc plat_crash_console_putc /* --------------------------------------------- - * int plat_crash_console_flush(int c) + * void plat_crash_console_flush(int c) * Function to force a write of all buffered * data that hasn't been output. - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : x0, x1 * --------------------------------------------- */ diff --git a/plat/qemu/common/aarch64/plat_helpers.S b/plat/qemu/common/aarch64/plat_helpers.S index dbcdc2d39..b54617385 100644 --- a/plat/qemu/common/aarch64/plat_helpers.S +++ b/plat/qemu/common/aarch64/plat_helpers.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -121,10 +121,10 @@ func plat_crash_console_putc endfunc plat_crash_console_putc /* --------------------------------------------- - * int plat_crash_console_flush(int c) + * void plat_crash_console_flush(int c) * Function to force a write of all buffered * data that hasn't been output. - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : x0, x1 * --------------------------------------------- */ diff --git a/plat/qti/qtiseclib/inc/qtiseclib_cb_interface.h b/plat/qti/qtiseclib/inc/qtiseclib_cb_interface.h index 2252557a0..deef41c5b 100644 --- a/plat/qti/qtiseclib/inc/qtiseclib_cb_interface.h +++ b/plat/qti/qtiseclib/inc/qtiseclib_cb_interface.h @@ -44,7 +44,7 @@ void qtiseclib_cb_switch_console_to_crash_state(void); void qtiseclib_cb_udelay(uint32_t usec); -int qtiseclib_cb_console_flush(void); +void qtiseclib_cb_console_flush(void); #if QTI_SDI_BUILD int qtiseclib_cb_mmap_remove_dynamic_region(uintptr_t base_va, size_t size); diff --git a/plat/qti/qtiseclib/src/qtiseclib_cb_interface.c b/plat/qti/qtiseclib/src/qtiseclib_cb_interface.c index 331a104b2..bb552c66b 100644 --- a/plat/qti/qtiseclib/src/qtiseclib_cb_interface.c +++ b/plat/qti/qtiseclib/src/qtiseclib_cb_interface.c @@ -121,7 +121,7 @@ void qtiseclib_cb_udelay(uint32_t usec) udelay(usec); } -int qtiseclib_cb_console_flush(void) +void qtiseclib_cb_console_flush(void) { return console_flush(); } diff --git a/plat/renesas/rcar/aarch64/plat_helpers.S b/plat/renesas/rcar/aarch64/plat_helpers.S index 138d98807..ec21f2510 100644 --- a/plat/renesas/rcar/aarch64/plat_helpers.S +++ b/plat/renesas/rcar/aarch64/plat_helpers.S @@ -295,7 +295,7 @@ func plat_crash_console_putc endfunc plat_crash_console_putc /* --------------------------------------------- - * int plat_crash_console_flush() + * void plat_crash_console_flush() * --------------------------------------------- */ func plat_crash_console_flush diff --git a/plat/rpi/common/aarch64/plat_helpers.S b/plat/rpi/common/aarch64/plat_helpers.S index e21233a1d..f045e2113 100644 --- a/plat/rpi/common/aarch64/plat_helpers.S +++ b/plat/rpi/common/aarch64/plat_helpers.S @@ -183,10 +183,10 @@ func plat_crash_console_putc endfunc plat_crash_console_putc /* --------------------------------------------- - * int plat_crash_console_flush() + * void plat_crash_console_flush() * Function to force a write of all buffered * data that hasn't been output. - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : x0, x1 * --------------------------------------------- */ diff --git a/plat/socionext/synquacer/sq_helpers.S b/plat/socionext/synquacer/sq_helpers.S index 558aa15f6..7a2d97b33 100644 --- a/plat/socionext/synquacer/sq_helpers.S +++ b/plat/socionext/synquacer/sq_helpers.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -98,10 +98,10 @@ func plat_crash_console_putc endfunc plat_crash_console_putc /* - * int plat_crash_console_flush(int c) + * void plat_crash_console_flush(int c) * Function to force a write of all buffered * data that hasn't been output. - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : x0, x1 */ func plat_crash_console_flush diff --git a/plat/socionext/uniphier/uniphier_console.S b/plat/socionext/uniphier/uniphier_console.S index f3dde0cc1..48927f414 100644 --- a/plat/socionext/uniphier/uniphier_console.S +++ b/plat/socionext/uniphier/uniphier_console.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -61,6 +61,5 @@ func uniphier_console_flush 0: ldr w1, [x0, #UNIPHIER_UART_LSR] tbz w1, #UNIPHIER_UART_LSR_TEMT_BIT, 0b - mov w0, #0 ret endfunc uniphier_console_flush diff --git a/plat/socionext/uniphier/uniphier_console_setup.c b/plat/socionext/uniphier/uniphier_console_setup.c index e2ae8bf28..9fda26e93 100644 --- a/plat/socionext/uniphier/uniphier_console_setup.c +++ b/plat/socionext/uniphier/uniphier_console_setup.c @@ -20,7 +20,7 @@ /* These callbacks are implemented in assembly to use crash_console_helpers.S */ int uniphier_console_putc(int character, struct console *console); int uniphier_console_getc(struct console *console); -int uniphier_console_flush(struct console *console); +void uniphier_console_flush(struct console *console); static console_t uniphier_console = { .flags = CONSOLE_FLAG_BOOT | diff --git a/plat/st/stm32mp1/stm32mp1_helper.S b/plat/st/stm32mp1/stm32mp1_helper.S index 407eb3979..302136236 100644 --- a/plat/st/stm32mp1/stm32mp1_helper.S +++ b/plat/st/stm32mp1/stm32mp1_helper.S @@ -198,7 +198,7 @@ func plat_crash_console_init endfunc plat_crash_console_init /* --------------------------------------------- - * int plat_crash_console_flush(void) + * void plat_crash_console_flush(void) * * Flush the crash console without a C Runtime stack. * --------------------------------------------- diff --git a/plat/ti/k3/common/k3_helpers.S b/plat/ti/k3/common/k3_helpers.S index 3afca591e..f4f7d18ea 100644 --- a/plat/ti/k3/common/k3_helpers.S +++ b/plat/ti/k3/common/k3_helpers.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -141,10 +141,10 @@ func plat_crash_console_putc endfunc plat_crash_console_putc /* --------------------------------------------- - * int plat_crash_console_flush() + * void plat_crash_console_flush() * Function to force a write of all buffered * data that hasn't been output. - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : x0, x1 * --------------------------------------------- */ diff --git a/plat/xilinx/zynqmp/aarch64/zynqmp_helpers.S b/plat/xilinx/zynqmp/aarch64/zynqmp_helpers.S index beba66405..7eab337e9 100644 --- a/plat/xilinx/zynqmp/aarch64/zynqmp_helpers.S +++ b/plat/xilinx/zynqmp/aarch64/zynqmp_helpers.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -106,10 +106,10 @@ func plat_crash_console_putc endfunc plat_crash_console_putc /* --------------------------------------------- - * int plat_crash_console_flush() + * void plat_crash_console_flush() * Function to force a write of all buffered * data that hasn't been output. - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : r0 * --------------------------------------------- */ -- cgit v1.2.3 From 20d384978b7e79b15ac92f07664db59efa17bf59 Mon Sep 17 00:00:00 2001 From: johpow01 Date: Mon, 28 Sep 2020 16:56:48 -0500 Subject: Fix casting bug in gicv2_main.c In the function gicv2_set_spi_routing, the signed value proc_num is cast to unsigned int before being compared to other unsigned values in two assert calls. The value proc_num can be a negative value, and once the negative value is cast to unsigned it becomes a very large number which will trigger the assert. This patch changes the assert cast so that the unsigned values are cast to signed instead, keeping the same functionality but allowing proc_num to be negative. This bug can be seen when running the SDEI RM_ANY routing mode test in TFTF on the Juno platform. This patch also makes the usage of the proc_num variable in other gicv2 functions more clear. Signed-off-by: John Powell Change-Id: If1b98eebb00bd9b73862e5e995e5e68c168170a6 --- drivers/arm/gic/v2/gicv2_main.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/arm/gic/v2/gicv2_main.c b/drivers/arm/gic/v2/gicv2_main.c index 4b21b920a..939d09718 100644 --- a/drivers/arm/gic/v2/gicv2_main.c +++ b/drivers/arm/gic/v2/gicv2_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -296,8 +296,8 @@ void gicv2_set_pe_target_mask(unsigned int proc_num) assert(driver_data != NULL); assert(driver_data->gicd_base != 0U); assert(driver_data->target_masks != NULL); - assert((unsigned int)proc_num < GICV2_MAX_TARGET_PE); - assert((unsigned int)proc_num < driver_data->target_masks_num); + assert(proc_num < GICV2_MAX_TARGET_PE); + assert(proc_num < driver_data->target_masks_num); /* Return if the target mask is already populated */ if (driver_data->target_masks[proc_num] != 0U) @@ -422,7 +422,8 @@ void gicv2_raise_sgi(int sgi_num, int proc_num) unsigned int sgir_val, target; assert(driver_data != NULL); - assert((unsigned int)proc_num < GICV2_MAX_TARGET_PE); + assert(proc_num >= 0); + assert(proc_num < (int)GICV2_MAX_TARGET_PE); assert(driver_data->gicd_base != 0U); /* @@ -430,7 +431,7 @@ void gicv2_raise_sgi(int sgi_num, int proc_num) * should be valid. */ assert(driver_data->target_masks != NULL); - assert((unsigned int)proc_num < driver_data->target_masks_num); + assert(proc_num < (int)driver_data->target_masks_num); /* Don't raise SGI if the mask hasn't been populated */ target = driver_data->target_masks[proc_num]; @@ -466,8 +467,9 @@ void gicv2_set_spi_routing(unsigned int id, int proc_num) * should be valid. */ assert(driver_data->target_masks != NULL); - assert((unsigned int)proc_num < GICV2_MAX_TARGET_PE); - assert((unsigned int)proc_num < driver_data->target_masks_num); + assert(proc_num < (int)GICV2_MAX_TARGET_PE); + assert(driver_data->target_masks_num < INT_MAX); + assert(proc_num < (int)driver_data->target_masks_num); if (proc_num < 0) { /* Target all PEs */ -- cgit v1.2.3 From 583079ae0680bb7c69e3d81a3b6742947efd699b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Wed, 7 Oct 2020 11:01:00 +0200 Subject: docs: marvell: update ddr3 build instructions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add information about 2GB variant of EspressoBin V5 and use Marvell git branches which contain required fixes for EspressoBin. Signed-off-by: Pali Rohár Change-Id: I1db510f1576f4762259ad7b0c10024b8ab434a59 --- docs/plat/marvell/armada/build.rst | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/plat/marvell/armada/build.rst b/docs/plat/marvell/armada/build.rst index 56b627b48..e21fb3cfb 100644 --- a/docs/plat/marvell/armada/build.rst +++ b/docs/plat/marvell/armada/build.rst @@ -124,11 +124,12 @@ There are several build options: Supported Options: - DDR3 1CS (0): DB-88F3720-DDR3-Modular (512MB); EspressoBIN (512MB) - DDR4 1CS (1): DB-88F3720-DDR4-Modular (512MB) - - DDR3 2CS (2): EspressoBIN V3-V5 (1GB) + - DDR3 2CS (2): EspressoBIN V3-V5 (1GB 2CS) - DDR4 2CS (3): DB-88F3720-DDR4-Modular (4GB) - - DDR3 1CS (4): DB-88F3720-DDR3-Modular (1GB) + - DDR3 1CS (4): DB-88F3720-DDR3-Modular (1GB); EspressoBIN V3-V5 (1GB 1CS) - DDR4 1CS (5): EspressoBin V7 (1GB) - DDR4 2CS (6): EspressoBin V7 (2GB) + - DDR3 2CS (7): EspressoBin V3-V5 (2GB) - CUSTOMER (CUST): Customer board, DDR3 1CS 512MB - CLOCKSPRESET @@ -259,11 +260,12 @@ Armada37x0 Builds require installation of 3 components > export CROSS_CM3=/opt/arm-cross/bin/arm-linux-gnueabi (2) DDR initialization library sources (mv_ddr) available at the following repository - (use the "mv_ddr-armada-18.12" branch): + (use the "mv-ddr-devel" branch): https://github.com/MarvellEmbeddedProcessors/mv-ddr-marvell.git -(3) Armada3700 tools available at the following repository (use the latest release branch): +(3) Armada3700 tools available at the following repository + (use the "A3700_utils-armada-18.12-fixed" branch): https://github.com/MarvellEmbeddedProcessors/A3700-utils-marvell.git @@ -271,6 +273,6 @@ Armada70x0 and Armada80x0 Builds require installation of an additional component ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (1) DDR initialization library sources (mv_ddr) available at the following repository - (use the "mv_ddr-armada-18.12" branch): + (use the "mv-ddr-devel" branch): https://github.com/MarvellEmbeddedProcessors/mv-ddr-marvell.git -- cgit v1.2.3 From ae3cf1ff31024d0ea200d7ec9a7d0412042cbdc5 Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Tue, 6 Oct 2020 15:54:12 +0100 Subject: TF-A: Add HASH_ALG default value to defaults.mk This patch adds default value of 'sha256' for HASH_ALG build flag to 'make_helpers\defaults.mk', according to 'docs\getting_started\build-options.rst'. This fixes Measured Boot driver error when TF-A uses default HASH_ALG value and TPM_HASH_ALG is set to sha384 or sha512. Change-Id: Id0aa34b54807de0adaf88e5f7d7032577c22f365 Signed-off-by: Alexei Fedorov --- make_helpers/defaults.mk | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index 7220a5d76..bc4982d64 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2016-2020, ARM Limited. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -150,6 +150,10 @@ GICV2_G0_FOR_EL3 := 0 # by lower ELs. HANDLE_EA_EL3_FIRST := 0 +# Secure hash algorithm flag, accepts 3 values: sha256, sha384 and sha512. +# The default value is sha256. +HASH_ALG := sha256 + # Whether system coherency is managed in hardware, without explicit software # operations. HW_ASSISTED_COHERENCY := 0 -- cgit v1.2.3 From c959ea78e527a6ba2ac406ed16f2ca05b0f6ee7c Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Wed, 7 Oct 2020 16:04:06 +0100 Subject: Remove deprecated macro from TF-A code Removed '__ASSEMBLY__' deprecated macro from TF-A code Change-Id: I9082a568b695acb5b903f509db11c8672b62d9d0 Signed-off-by: Manish V Badarkhe --- Makefile | 3 +-- include/drivers/marvell/cache_llc.h | 4 ++-- plat/nvidia/tegra/include/drivers/memctrl_v2.h | 8 ++++---- plat/nvidia/tegra/include/t186/tegra_mc_def.h | 4 ++-- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index a9a4d9058..cb47491a4 100644 --- a/Makefile +++ b/Makefile @@ -1067,8 +1067,7 @@ ifneq ($(findstring clang,$(notdir $(CC))),) else CPPFLAGS += -Wno-error=deprecated-declarations -Wno-error=cpp endif -# __ASSEMBLY__ is deprecated in favor of the compiler-builtin __ASSEMBLER__. -ASFLAGS += -D__ASSEMBLY__ + # AARCH32/AARCH64 macros are deprecated in favor of the compiler-builtin __aarch64__. ifeq (${ARCH},aarch32) $(eval $(call add_define,AARCH32)) diff --git a/include/drivers/marvell/cache_llc.h b/include/drivers/marvell/cache_llc.h index d6dd65382..72111b374 100644 --- a/include/drivers/marvell/cache_llc.h +++ b/include/drivers/marvell/cache_llc.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 Marvell International Ltd. + * Copyright (C) 2018-2020 Marvell International Ltd. * * SPDX-License-Identifier: BSD-3-Clause * https://spdx.org/licenses @@ -57,6 +57,6 @@ int llc_sram_enable(int ap_index, int size); void llc_sram_disable(int ap_index); int llc_sram_test(int ap_index, int size, char *msg); #endif /* LLC_SRAM */ -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ #endif /* CACHE_LLC_H */ diff --git a/plat/nvidia/tegra/include/drivers/memctrl_v2.h b/plat/nvidia/tegra/include/drivers/memctrl_v2.h index 1e153063a..9af3027ea 100644 --- a/plat/nvidia/tegra/include/drivers/memctrl_v2.h +++ b/plat/nvidia/tegra/include/drivers/memctrl_v2.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -26,7 +26,7 @@ #define MC_SMMU_BYPASS_CONFIG_SETTINGS (MC_SMMU_BYPASS_CONFIG_WRITE_ACCESS_BIT | \ MC_SMMU_CTRL_TBU_BYPASS_SPL_STREAMID) -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #include @@ -53,9 +53,9 @@ typedef struct mc_regs { .val = 0xFFFFFFFFU, \ } -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #include diff --git a/plat/nvidia/tegra/include/t186/tegra_mc_def.h b/plat/nvidia/tegra/include/t186/tegra_mc_def.h index 398453eb9..fa447725b 100644 --- a/plat/nvidia/tegra/include/t186/tegra_mc_def.h +++ b/plat/nvidia/tegra/include/t186/tegra_mc_def.h @@ -282,7 +282,7 @@ #define MC_CLIENT_HOTRESET_CTRL1_SCE_FLUSH_ENB (1U << 24) #define MC_CLIENT_HOTRESET_STATUS1 0x974U -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ /******************************************************************************* * Structure to hold the transaction override settings to use to override @@ -393,6 +393,6 @@ typedef struct mc_streamid_security_cfg { MC_TXN_OVERRIDE_CONFIG_CGID_##so_dev_axi_id); \ } while (0) -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ #endif /* TEGRA_MC_DEF_H */ -- cgit v1.2.3 From 0e16177ea2c4b0c86ec158bb6d2d0b562dbb4739 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Wed, 7 Oct 2020 18:53:23 +0100 Subject: plat: brcm: Remove 'AARCH32' deprecated macro Removed 'AARCH32' deprecated macro from 'stingray' Broadcom platform code. Change-Id: If8d9e785b7980fefd39df06547fcf71b899fd735 Signed-off-by: Manish V Badarkhe --- plat/brcm/board/stingray/src/brcm_pm_ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/brcm/board/stingray/src/brcm_pm_ops.c b/plat/brcm/board/stingray/src/brcm_pm_ops.c index 090fbca53..03a604c15 100644 --- a/plat/brcm/board/stingray/src/brcm_pm_ops.c +++ b/plat/brcm/board/stingray/src/brcm_pm_ops.c @@ -323,7 +323,7 @@ static int brcm_validate_ns_entrypoint(uintptr_t entrypoint) if ((entrypoint >= BRCM_NS_DRAM1_BASE) && (entrypoint < (BRCM_NS_DRAM1_BASE + BRCM_NS_DRAM1_SIZE))) return PSCI_E_SUCCESS; -#ifndef AARCH32 +#ifdef __aarch64__ if ((entrypoint >= BRCM_DRAM2_BASE) && (entrypoint < (BRCM_DRAM2_BASE + BRCM_DRAM2_SIZE))) return PSCI_E_SUCCESS; -- cgit v1.2.3 From acbe35e0f83be531feec10d8eb9db71eab7b27da Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Wed, 7 Oct 2020 21:15:27 +0100 Subject: Makefile: Remove unused macro Removed unused macro AARCH32 and AARCH64 from makefile Change-Id: I6729e300f18d66dd7c6978d3bbd5a88937839c31 Signed-off-by: Manish V Badarkhe --- Makefile | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Makefile b/Makefile index cb47491a4..c5073e016 100644 --- a/Makefile +++ b/Makefile @@ -1067,13 +1067,6 @@ ifneq ($(findstring clang,$(notdir $(CC))),) else CPPFLAGS += -Wno-error=deprecated-declarations -Wno-error=cpp endif - -# AARCH32/AARCH64 macros are deprecated in favor of the compiler-builtin __aarch64__. -ifeq (${ARCH},aarch32) - $(eval $(call add_define,AARCH32)) -else - $(eval $(call add_define,AARCH64)) -endif endif # !ERROR_DEPRECATED $(eval $(call MAKE_LIB_DIRS)) -- cgit v1.2.3 From 0c3e8acbd6fd18c358967d79ecdb91b5bfcdc4a6 Mon Sep 17 00:00:00 2001 From: Christophe Kerello Date: Thu, 16 Jul 2020 16:57:34 +0200 Subject: drivers: stm32_fmc2_nand: move to new bindings FMC node bindings are modified to add EBI controller node. FMC driver and associated device tree files are modified to support these new bindings. Change-Id: I4bf201e96a1aca20957e0dac3a3b87caadd05bdc Signed-off-by: Christophe Kerello Signed-off-by: Lionel Debieve --- drivers/st/fmc/stm32_fmc2_nand.c | 85 +++++++++++++++++++++++++++++++--------- fdts/stm32mp151.dtsi | 35 ++++++++++++----- fdts/stm32mp157c-ev1.dts | 13 ++++-- 3 files changed, 100 insertions(+), 33 deletions(-) diff --git a/drivers/st/fmc/stm32_fmc2_nand.c b/drivers/st/fmc/stm32_fmc2_nand.c index 5eee4f3b9..857743666 100644 --- a/drivers/st/fmc/stm32_fmc2_nand.c +++ b/drivers/st/fmc/stm32_fmc2_nand.c @@ -26,8 +26,10 @@ #define TIMEOUT_US_1_MS 1000U /* FMC2 Compatibility */ -#define DT_FMC2_COMPAT "st,stm32mp15-fmc2" +#define DT_FMC2_EBI_COMPAT "st,stm32mp1-fmc2-ebi" +#define DT_FMC2_NFC_COMPAT "st,stm32mp1-fmc2-nfc" #define MAX_CS 2U +#define MAX_BANK 5U /* FMC2 Controller Registers */ #define FMC2_BCR1 0x00U @@ -793,23 +795,26 @@ static const struct nand_ctrl_ops ctrl_ops = { int stm32_fmc2_init(void) { - int fmc_node; - int fmc_subnode = 0; + int fmc_ebi_node; + int fmc_nfc_node; + int fmc_flash_node = 0; int nchips = 0; unsigned int i; void *fdt = NULL; const fdt32_t *cuint; struct dt_node_info info; + uintptr_t bank_address[MAX_BANK] = { 0, 0, 0, 0, 0 }; + uint8_t bank_assigned = 0; + uint8_t bank; int ret; if (fdt_get_address(&fdt) == 0) { return -FDT_ERR_NOTFOUND; } - fmc_node = dt_get_node(&info, -1, DT_FMC2_COMPAT); - if (fmc_node == -FDT_ERR_NOTFOUND) { - WARN("No FMC2 node found\n"); - return fmc_node; + fmc_ebi_node = dt_get_node(&info, -1, DT_FMC2_EBI_COMPAT); + if (fmc_ebi_node < 0) { + return fmc_ebi_node; } if (info.status == DT_DISABLED) { @@ -825,27 +830,69 @@ int stm32_fmc2_init(void) stm32_fmc2.clock_id = (unsigned long)info.clock; stm32_fmc2.reset_id = (unsigned int)info.reset; - cuint = fdt_getprop(fdt, fmc_node, "reg", NULL); + cuint = fdt_getprop(fdt, fmc_ebi_node, "ranges", NULL); if (cuint == NULL) { return -FDT_ERR_BADVALUE; } - cuint += 2; - - for (i = 0U; i < MAX_CS; i++) { - stm32_fmc2.cs[i].data_base = fdt32_to_cpu(*cuint); - stm32_fmc2.cs[i].cmd_base = fdt32_to_cpu(*(cuint + 2)); - stm32_fmc2.cs[i].addr_base = fdt32_to_cpu(*(cuint + 4)); - cuint += 6; + for (i = 0U; i < MAX_BANK; i++) { + bank = fdt32_to_cpu(*cuint); + if ((bank >= MAX_BANK) || ((bank_assigned & BIT(bank)) != 0U)) { + return -FDT_ERR_BADVALUE; + } + bank_assigned |= BIT(bank); + bank_address[bank] = fdt32_to_cpu(*(cuint + 2)); + cuint += 4; } /* Pinctrl initialization */ - if (dt_set_pinctrl_config(fmc_node) != 0) { + if (dt_set_pinctrl_config(fmc_ebi_node) != 0) { + return -FDT_ERR_BADVALUE; + } + + /* Parse NFC controller node */ + fmc_nfc_node = fdt_node_offset_by_compatible(fdt, fmc_ebi_node, + DT_FMC2_NFC_COMPAT); + if (fmc_nfc_node < 0) { + return fmc_nfc_node; + } + + if (fdt_get_status(fmc_nfc_node) == DT_DISABLED) { + return -FDT_ERR_NOTFOUND; + } + + cuint = fdt_getprop(fdt, fmc_nfc_node, "reg", NULL); + if (cuint == NULL) { return -FDT_ERR_BADVALUE; } + for (i = 0U; i < MAX_CS; i++) { + bank = fdt32_to_cpu(*cuint); + if (bank >= MAX_BANK) { + return -FDT_ERR_BADVALUE; + } + stm32_fmc2.cs[i].data_base = fdt32_to_cpu(*(cuint + 1)) + + bank_address[bank]; + + bank = fdt32_to_cpu(*(cuint + 3)); + if (bank >= MAX_BANK) { + return -FDT_ERR_BADVALUE; + } + stm32_fmc2.cs[i].cmd_base = fdt32_to_cpu(*(cuint + 4)) + + bank_address[bank]; + + bank = fdt32_to_cpu(*(cuint + 6)); + if (bank >= MAX_BANK) { + return -FDT_ERR_BADVALUE; + } + stm32_fmc2.cs[i].addr_base = fdt32_to_cpu(*(cuint + 7)) + + bank_address[bank]; + + cuint += 9; + } + /* Parse flash nodes */ - fdt_for_each_subnode(fmc_subnode, fdt, fmc_node) { + fdt_for_each_subnode(fmc_flash_node, fdt, fmc_nfc_node) { nchips++; } @@ -854,9 +901,9 @@ int stm32_fmc2_init(void) return -FDT_ERR_BADVALUE; } - fdt_for_each_subnode(fmc_subnode, fdt, fmc_node) { + fdt_for_each_subnode(fmc_flash_node, fdt, fmc_nfc_node) { /* Get chip select */ - cuint = fdt_getprop(fdt, fmc_subnode, "reg", NULL); + cuint = fdt_getprop(fdt, fmc_flash_node, "reg", NULL); if (cuint == NULL) { WARN("Chip select not well defined\n"); return -FDT_ERR_BADVALUE; diff --git a/fdts/stm32mp151.dtsi b/fdts/stm32mp151.dtsi index 2eb4a3943..8f175a649 100644 --- a/fdts/stm32mp151.dtsi +++ b/fdts/stm32mp151.dtsi @@ -264,19 +264,34 @@ status = "disabled"; }; - fmc: nand-controller@58002000 { - compatible = "st,stm32mp15-fmc2"; - reg = <0x58002000 0x1000>, - <0x80000000 0x1000>, - <0x88010000 0x1000>, - <0x88020000 0x1000>, - <0x81000000 0x1000>, - <0x89010000 0x1000>, - <0x89020000 0x1000>; - interrupts = ; + fmc: memory-controller@58002000 { + #address-cells = <2>; + #size-cells = <1>; + compatible = "st,stm32mp1-fmc2-ebi"; + reg = <0x58002000 0x1000>; clocks = <&rcc FMC_K>; resets = <&rcc FMC_R>; status = "disabled"; + + ranges = <0 0 0x60000000 0x04000000>, /* EBI CS 1 */ + <1 0 0x64000000 0x04000000>, /* EBI CS 2 */ + <2 0 0x68000000 0x04000000>, /* EBI CS 3 */ + <3 0 0x6c000000 0x04000000>, /* EBI CS 4 */ + <4 0 0x80000000 0x10000000>; /* NAND */ + + nand-controller@4,0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "st,stm32mp1-fmc2-nfc"; + reg = <4 0x00000000 0x1000>, + <4 0x08010000 0x1000>, + <4 0x08020000 0x1000>, + <4 0x01000000 0x1000>, + <4 0x09010000 0x1000>, + <4 0x09020000 0x1000>; + interrupts = ; + status = "disabled"; + }; }; qspi: spi@58003000 { diff --git a/fdts/stm32mp157c-ev1.dts b/fdts/stm32mp157c-ev1.dts index 50c0b939b..c5d12e3b2 100644 --- a/fdts/stm32mp157c-ev1.dts +++ b/fdts/stm32mp157c-ev1.dts @@ -24,11 +24,16 @@ pinctrl-names = "default"; pinctrl-0 = <&fmc_pins_a>; status = "okay"; - #address-cells = <1>; - #size-cells = <0>; - nand: nand@0 { - reg = <0>; + nand-controller@4,0 { + status = "okay"; + + nand@0 { + reg = <0>; + nand-on-flash-bbt; + #address-cells = <1>; + #size-cells = <1>; + }; }; }; -- cgit v1.2.3 From 495885bce6584f63916d7778ca000e848c939a9d Mon Sep 17 00:00:00 2001 From: Lionel Debieve Date: Tue, 21 Jul 2020 15:22:55 +0200 Subject: drivers: stm32_fmc2_nand: fix boundary check for chip select Chip select is retrieved from device tree and check must be done regarding the MAX_CS defined. Signed-off-by: Lionel Debieve Reviewed-by: Christophe KERELLO Change-Id: I03144b133bd51a845a4794f0f6bbd9402fc04936 --- drivers/st/fmc/stm32_fmc2_nand.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/st/fmc/stm32_fmc2_nand.c b/drivers/st/fmc/stm32_fmc2_nand.c index 857743666..a58a243ad 100644 --- a/drivers/st/fmc/stm32_fmc2_nand.c +++ b/drivers/st/fmc/stm32_fmc2_nand.c @@ -908,7 +908,12 @@ int stm32_fmc2_init(void) WARN("Chip select not well defined\n"); return -FDT_ERR_BADVALUE; } + stm32_fmc2.cs_sel = fdt32_to_cpu(*cuint); + if (stm32_fmc2.cs_sel >= MAX_CS) { + return -FDT_ERR_BADVALUE; + } + VERBOSE("NAND CS %i\n", stm32_fmc2.cs_sel); } -- cgit v1.2.3 From d7b5f40823d449cc79e6440174390997cf11a9d9 Mon Sep 17 00:00:00 2001 From: Jimmy Brisson Date: Tue, 4 Aug 2020 16:18:52 -0500 Subject: Increase type widths to satisfy width requirements Usually, C has no problem up-converting types to larger bit sizes. MISRA rule 10.7 requires that you not do this, or be very explicit about this. This resolves the following required rule: bl1/aarch64/bl1_context_mgmt.c:81:[MISRA C-2012 Rule 10.7 (required)] The width of the composite expression "0U | ((mode & 3U) << 2U) | 1U | 0x3c0U" (32 bits) is less that the right hand operand "18446744073709547519ULL" (64 bits). This also resolves MISRA defects such as: bl2/aarch64/bl2arch_setup.c:18:[MISRA C-2012 Rule 12.2 (required)] In the expression "3U << 20", shifting more than 7 bits, the number of bits in the essential type of the left expression, "3U", is not allowed. Further, MISRA requires that all shifts don't overflow. The definition of PAGE_SIZE was (1U << 12), and 1U is 8 bits. This caused about 50 issues. This fixes the violation by changing the definition to 1UL << 12. Since this uses 32bits, it should not create any issues for aarch32. This patch also contains a fix for a build failure in the sun50i_a64 platform. Specifically, these misra fixes removed a single and instruction, 92407e73 and x19, x19, #0xffffffff from the cm_setup_context function caused a relocation in psci_cpus_on_start to require a linker-generated stub. This increased the size of the .text section and caused an alignment later on to go over a page boundary and round up to the end of RAM before placing the .data section. This sectionn is of non-zero size and therefore causes a link error. The fix included in this reorders the functions during link time without changing their ording with respect to alignment. Change-Id: I76b4b662c3d262296728a8b9aab7a33b02087f16 Signed-off-by: Jimmy Brisson --- bl1/aarch64/bl1_context_mgmt.c | 4 +-- bl31/bl31.ld.S | 2 +- bl32/tsp/aarch64/tsp_entrypoint.S | 2 +- common/bl_common.c | 4 +-- drivers/arm/cci/cci.c | 6 ++-- drivers/arm/tzc/tzc400.c | 6 ++-- drivers/arm/tzc/tzc_common_private.h | 18 ++++++------ include/arch/aarch32/arch.h | 30 ++++++++++---------- include/arch/aarch64/arch.h | 44 +++++++++++++++--------------- include/arch/aarch64/el3_common_macros.S | 2 +- include/export/common/ep_info_exp.h | 10 +++---- include/lib/pmf/pmf.h | 10 +++---- include/lib/pmf/pmf_helpers.h | 16 ++++++----- include/lib/smccc.h | 7 +++-- include/lib/xlat_tables/xlat_tables_defs.h | 6 ++-- lib/aarch64/misc_helpers.S | 6 ++-- lib/el3_runtime/aarch64/context_mgmt.c | 4 +-- lib/psci/psci_common.c | 6 ++-- lib/xlat_tables_v2/xlat_tables_utils.c | 8 +++--- plat/arm/common/arm_common.c | 2 +- 20 files changed, 99 insertions(+), 94 deletions(-) diff --git a/bl1/aarch64/bl1_context_mgmt.c b/bl1/aarch64/bl1_context_mgmt.c index 87e367ce8..2a8d58efd 100644 --- a/bl1/aarch64/bl1_context_mgmt.c +++ b/bl1/aarch64/bl1_context_mgmt.c @@ -78,8 +78,8 @@ void bl1_prepare_next_image(unsigned int image_id) mode = MODE_EL2; } - next_bl_ep->spsr = (uint32_t)SPSR_64(mode, MODE_SP_ELX, - DISABLE_ALL_EXCEPTIONS); + 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); diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S index 502650097..8a1573ab6 100644 --- a/bl31/bl31.ld.S +++ b/bl31/bl31.ld.S @@ -37,7 +37,7 @@ SECTIONS .text . : { __TEXT_START__ = .; *bl31_entrypoint.o(.text*) - *(SORT_BY_ALIGNMENT(.text*)) + *(SORT_BY_ALIGNMENT(SORT(.text*))) *(.vectors) . = ALIGN(PAGE_SIZE); __TEXT_END__ = .; diff --git a/bl32/tsp/aarch64/tsp_entrypoint.S b/bl32/tsp/aarch64/tsp_entrypoint.S index ebc5c2c3d..a007bab30 100644 --- a/bl32/tsp/aarch64/tsp_entrypoint.S +++ b/bl32/tsp/aarch64/tsp_entrypoint.S @@ -60,7 +60,7 @@ func tsp_entrypoint _align=3 */ pie_fixup: ldr x0, =pie_fixup - and x0, x0, #~(PAGE_SIZE - 1) + and x0, x0, #~(PAGE_SIZE_MASK) mov_imm x1, (BL32_LIMIT - BL32_BASE) add x1, x1, x0 bl fixup_gdt_reloc diff --git a/common/bl_common.c b/common/bl_common.c index 2fcb5385d..f17afcb11 100644 --- a/common/bl_common.c +++ b/common/bl_common.c @@ -50,8 +50,8 @@ static int dyn_is_auth_disabled(void) uintptr_t page_align(uintptr_t value, unsigned dir) { /* Round up the limit to the next page boundary */ - if ((value & (PAGE_SIZE - 1U)) != 0U) { - value &= ~(PAGE_SIZE - 1U); + if ((value & PAGE_SIZE_MASK) != 0U) { + value &= ~PAGE_SIZE_MASK; if (dir == UP) value += PAGE_SIZE; } diff --git a/drivers/arm/cci/cci.c b/drivers/arm/cci/cci.c index a139f6cc7..2adfe1718 100644 --- a/drivers/arm/cci/cci.c +++ b/drivers/arm/cci/cci.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -52,11 +52,11 @@ static bool validate_cci_map(const int *map) return false; } - if ((valid_cci_map & (1U << slave_if_id)) != 0U) { + if ((valid_cci_map & (1UL << slave_if_id)) != 0U) { ERROR("Multiple masters are assigned same slave interface ID\n"); return false; } - valid_cci_map |= 1U << slave_if_id; + valid_cci_map |= 1UL << slave_if_id; } if (valid_cci_map == 0U) { diff --git a/drivers/arm/tzc/tzc400.c b/drivers/arm/tzc/tzc400.c index 50d670139..95a5e7f77 100644 --- a/drivers/arm/tzc/tzc400.c +++ b/drivers/arm/tzc/tzc400.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -91,9 +91,9 @@ static void _tzc400_set_gate_keeper(uintptr_t base, open_status = get_gate_keeper_os(base); if (val != 0) - open_status |= (1U << filter); + open_status |= (1UL << filter); else - open_status &= ~(1U << filter); + open_status &= ~(1UL << filter); _tzc400_write_gate_keeper(base, (open_status & GATE_KEEPER_OR_MASK) << GATE_KEEPER_OR_SHIFT); diff --git a/drivers/arm/tzc/tzc_common_private.h b/drivers/arm/tzc/tzc_common_private.h index c800536f3..1d99077ad 100644 --- a/drivers/arm/tzc/tzc_common_private.h +++ b/drivers/arm/tzc/tzc_common_private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -30,13 +30,13 @@ mmio_write_32(base + \ TZC_REGION_OFFSET( \ TZC_##macro_name##_REGION_SIZE, \ - region_no) + \ + (u_register_t)region_no) + \ TZC_##macro_name##_REGION_BASE_LOW_0_OFFSET, \ (uint32_t)region_base); \ mmio_write_32(base + \ TZC_REGION_OFFSET( \ TZC_##macro_name##_REGION_SIZE, \ - region_no) + \ + (u_register_t)region_no) + \ TZC_##macro_name##_REGION_BASE_HIGH_0_OFFSET, \ (uint32_t)(region_base >> 32)); \ } @@ -48,15 +48,15 @@ unsigned long long region_top) \ { \ mmio_write_32(base + \ - TZC_REGION_OFFSET \ - (TZC_##macro_name##_REGION_SIZE, \ - region_no) + \ + TZC_REGION_OFFSET( \ + TZC_##macro_name##_REGION_SIZE, \ + (u_register_t)region_no) + \ TZC_##macro_name##_REGION_TOP_LOW_0_OFFSET, \ (uint32_t)region_top); \ mmio_write_32(base + \ TZC_REGION_OFFSET( \ TZC_##macro_name##_REGION_SIZE, \ - region_no) + \ + (u_register_t)region_no) + \ TZC_##macro_name##_REGION_TOP_HIGH_0_OFFSET, \ (uint32_t)(region_top >> 32)); \ } @@ -70,7 +70,7 @@ mmio_write_32(base + \ TZC_REGION_OFFSET( \ TZC_##macro_name##_REGION_SIZE, \ - region_no) + \ + (u_register_t)region_no) + \ TZC_##macro_name##_REGION_ATTR_0_OFFSET, \ attr); \ } @@ -84,7 +84,7 @@ mmio_write_32(base + \ TZC_REGION_OFFSET( \ TZC_##macro_name##_REGION_SIZE, \ - region_no) + \ + (u_register_t)region_no) + \ TZC_##macro_name##_REGION_ID_ACCESS_0_OFFSET, \ val); \ } diff --git a/include/arch/aarch32/arch.h b/include/arch/aarch32/arch.h index 1032e1373..db8938ff1 100644 --- a/include/arch/aarch32/arch.h +++ b/include/arch/aarch32/arch.h @@ -183,23 +183,23 @@ /* CPACR definitions */ #define CPACR_FPEN(x) ((x) << 20) -#define CPACR_FP_TRAP_PL0 U(0x1) -#define CPACR_FP_TRAP_ALL U(0x2) -#define CPACR_FP_TRAP_NONE U(0x3) +#define CPACR_FP_TRAP_PL0 UL(0x1) +#define CPACR_FP_TRAP_ALL UL(0x2) +#define CPACR_FP_TRAP_NONE UL(0x3) /* SCR definitions */ -#define SCR_TWE_BIT (U(1) << 13) -#define SCR_TWI_BIT (U(1) << 12) -#define SCR_SIF_BIT (U(1) << 9) -#define SCR_HCE_BIT (U(1) << 8) -#define SCR_SCD_BIT (U(1) << 7) -#define SCR_NET_BIT (U(1) << 6) -#define SCR_AW_BIT (U(1) << 5) -#define SCR_FW_BIT (U(1) << 4) -#define SCR_EA_BIT (U(1) << 3) -#define SCR_FIQ_BIT (U(1) << 2) -#define SCR_IRQ_BIT (U(1) << 1) -#define SCR_NS_BIT (U(1) << 0) +#define SCR_TWE_BIT (UL(1) << 13) +#define SCR_TWI_BIT (UL(1) << 12) +#define SCR_SIF_BIT (UL(1) << 9) +#define SCR_HCE_BIT (UL(1) << 8) +#define SCR_SCD_BIT (UL(1) << 7) +#define SCR_NET_BIT (UL(1) << 6) +#define SCR_AW_BIT (UL(1) << 5) +#define SCR_FW_BIT (UL(1) << 4) +#define SCR_EA_BIT (UL(1) << 3) +#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(0x33ff) #define SCR_RESET_VAL U(0x0) diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index ebe1a244a..33e1134dd 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -326,34 +326,34 @@ /* CPACR_El1 definitions */ #define CPACR_EL1_FPEN(x) ((x) << 20) -#define CPACR_EL1_FP_TRAP_EL0 U(0x1) -#define CPACR_EL1_FP_TRAP_ALL U(0x2) -#define CPACR_EL1_FP_TRAP_NONE U(0x3) +#define CPACR_EL1_FP_TRAP_EL0 UL(0x1) +#define CPACR_EL1_FP_TRAP_ALL UL(0x2) +#define CPACR_EL1_FP_TRAP_NONE UL(0x3) /* SCR definitions */ #define SCR_RES1_BITS ((U(1) << 4) | (U(1) << 5)) #define SCR_TWEDEL_SHIFT U(30) #define SCR_TWEDEL_MASK ULL(0xf) #define SCR_TWEDEn_BIT (UL(1) << 29) -#define SCR_ECVEN_BIT (U(1) << 28) -#define SCR_FGTEN_BIT (U(1) << 27) -#define SCR_ATA_BIT (U(1) << 26) -#define SCR_FIEN_BIT (U(1) << 21) -#define SCR_EEL2_BIT (U(1) << 18) -#define SCR_API_BIT (U(1) << 17) -#define SCR_APK_BIT (U(1) << 16) -#define SCR_TERR_BIT (U(1) << 15) -#define SCR_TWE_BIT (U(1) << 13) -#define SCR_TWI_BIT (U(1) << 12) -#define SCR_ST_BIT (U(1) << 11) -#define SCR_RW_BIT (U(1) << 10) -#define SCR_SIF_BIT (U(1) << 9) -#define SCR_HCE_BIT (U(1) << 8) -#define SCR_SMD_BIT (U(1) << 7) -#define SCR_EA_BIT (U(1) << 3) -#define SCR_FIQ_BIT (U(1) << 2) -#define SCR_IRQ_BIT (U(1) << 1) -#define SCR_NS_BIT (U(1) << 0) +#define SCR_ECVEN_BIT (UL(1) << 28) +#define SCR_FGTEN_BIT (UL(1) << 27) +#define SCR_ATA_BIT (UL(1) << 26) +#define SCR_FIEN_BIT (UL(1) << 21) +#define SCR_EEL2_BIT (UL(1) << 18) +#define SCR_API_BIT (UL(1) << 17) +#define SCR_APK_BIT (UL(1) << 16) +#define SCR_TERR_BIT (UL(1) << 15) +#define SCR_TWE_BIT (UL(1) << 13) +#define SCR_TWI_BIT (UL(1) << 12) +#define SCR_ST_BIT (UL(1) << 11) +#define SCR_RW_BIT (UL(1) << 10) +#define SCR_SIF_BIT (UL(1) << 9) +#define SCR_HCE_BIT (UL(1) << 8) +#define SCR_SMD_BIT (UL(1) << 7) +#define SCR_EA_BIT (UL(1) << 3) +#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_RESET_VAL SCR_RES1_BITS diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S index 17a4efaf6..6f4143c5f 100644 --- a/include/arch/aarch64/el3_common_macros.S +++ b/include/arch/aarch64/el3_common_macros.S @@ -305,7 +305,7 @@ */ pie_fixup: ldr x0, =pie_fixup - and x0, x0, #~(PAGE_SIZE - 1) + and x0, x0, #~(PAGE_SIZE_MASK) mov_imm x1, \_pie_fixup_size add x1, x1, x0 bl fixup_gdt_reloc diff --git a/include/export/common/ep_info_exp.h b/include/export/common/ep_info_exp.h index 4c703e6de..9d2969f3f 100644 --- a/include/export/common/ep_info_exp.h +++ b/include/export/common/ep_info_exp.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -25,10 +25,10 @@ #endif /* Security state of the image. */ -#define EP_SECURITY_MASK U(0x1) -#define EP_SECURITY_SHIFT U(0) -#define EP_SECURE U(0x0) -#define EP_NON_SECURE U(0x1) +#define EP_SECURITY_MASK UL(0x1) +#define EP_SECURITY_SHIFT UL(0) +#define EP_SECURE UL(0x0) +#define EP_NON_SECURE UL(0x1) /* Endianness of the image. */ #define EP_EE_MASK U(0x2) diff --git a/include/lib/pmf/pmf.h b/include/lib/pmf/pmf.h index 3fc8e3863..fa990d2e5 100644 --- a/include/lib/pmf/pmf.h +++ b/include/lib/pmf/pmf.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -14,13 +14,13 @@ /* * Constants used for/by PMF services. */ -#define PMF_ARM_TIF_IMPL_ID U(0x41) +#define PMF_ARM_TIF_IMPL_ID UL(0x41) #define PMF_TID_SHIFT 0 -#define PMF_TID_MASK (U(0xFF) << PMF_TID_SHIFT) +#define PMF_TID_MASK (UL(0xFF) << PMF_TID_SHIFT) #define PMF_SVC_ID_SHIFT 10 -#define PMF_SVC_ID_MASK (U(0x3F) << PMF_SVC_ID_SHIFT) +#define PMF_SVC_ID_MASK (UL(0x3F) << PMF_SVC_ID_SHIFT) #define PMF_IMPL_ID_SHIFT 24 -#define PMF_IMPL_ID_MASK (U(0xFF) << PMF_IMPL_ID_SHIFT) +#define PMF_IMPL_ID_MASK (UL(0xFF) << PMF_IMPL_ID_SHIFT) /* * Flags passed to PMF_REGISTER_SERVICE diff --git a/include/lib/pmf/pmf_helpers.h b/include/lib/pmf/pmf_helpers.h index cfb27f7dc..b49c6da09 100644 --- a/include/lib/pmf/pmf_helpers.h +++ b/include/lib/pmf/pmf_helpers.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -174,24 +174,26 @@ typedef struct pmf_svc_desc { unsigned long long ts) \ { \ CASSERT(_flags != 0, select_proper_config); \ - PMF_VALIDATE_TID(_name, tid); \ + PMF_VALIDATE_TID(_name, (uint64_t)tid); \ uintptr_t base_addr = (uintptr_t) pmf_ts_mem_ ## _name; \ if (((_flags) & PMF_STORE_ENABLE) != 0) \ - __pmf_store_timestamp(base_addr, tid, ts); \ + __pmf_store_timestamp(base_addr, \ + (uint64_t)tid, ts); \ if (((_flags) & PMF_DUMP_ENABLE) != 0) \ - __pmf_dump_timestamp(tid, ts); \ + __pmf_dump_timestamp((uint64_t)tid, ts); \ } \ void pmf_capture_timestamp_with_cache_maint_ ## _name( \ unsigned int tid, \ unsigned long long ts) \ { \ CASSERT(_flags != 0, select_proper_config); \ - PMF_VALIDATE_TID(_name, tid); \ + PMF_VALIDATE_TID(_name, (uint64_t)tid); \ uintptr_t base_addr = (uintptr_t) pmf_ts_mem_ ## _name; \ if (((_flags) & PMF_STORE_ENABLE) != 0) \ - __pmf_store_timestamp_with_cache_maint(base_addr, tid, ts);\ + __pmf_store_timestamp_with_cache_maint( \ + base_addr, (uint64_t)tid, ts); \ if (((_flags) & PMF_DUMP_ENABLE) != 0) \ - __pmf_dump_timestamp(tid, ts); \ + __pmf_dump_timestamp((uint64_t)tid, ts); \ } /* diff --git a/include/lib/smccc.h b/include/lib/smccc.h index 366f0560b..470317dd0 100644 --- a/include/lib/smccc.h +++ b/include/lib/smccc.h @@ -78,8 +78,8 @@ #define SMC_64 U(1) #define SMC_32 U(0) -#define SMC_TYPE_FAST ULL(1) -#define SMC_TYPE_YIELD ULL(0) +#define SMC_TYPE_FAST UL(1) +#define SMC_TYPE_YIELD UL(0) #define SMC_OK ULL(0) #define SMC_UNK -1 @@ -112,7 +112,8 @@ /* The macro below is used to identify a valid Fast SMC call */ #define is_valid_fast_smc(_fid) ((!(((_fid) >> 16) & U(0xff))) && \ - (GET_SMC_TYPE(_fid) == SMC_TYPE_FAST)) + (GET_SMC_TYPE(_fid) \ + == (uint32_t)SMC_TYPE_FAST)) /* * Macro to define UUID for services. Apart from defining and initializing a diff --git a/include/lib/xlat_tables/xlat_tables_defs.h b/include/lib/xlat_tables/xlat_tables_defs.h index 76cfc0b34..579d8d89c 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-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -74,8 +74,8 @@ * 64KB. However, only 4KB are supported at the moment. */ #define PAGE_SIZE_SHIFT FOUR_KB_SHIFT -#define PAGE_SIZE (U(1) << PAGE_SIZE_SHIFT) -#define PAGE_SIZE_MASK (PAGE_SIZE - U(1)) +#define PAGE_SIZE (UL(1) << PAGE_SIZE_SHIFT) +#define PAGE_SIZE_MASK (PAGE_SIZE - UL(1)) #define IS_PAGE_ALIGNED(addr) (((addr) & PAGE_SIZE_MASK) == U(0)) #if (ARM_ARCH_MAJOR == 7) && !ARMV7_SUPPORTS_LARGE_PAGE_ADDRESSING diff --git a/lib/aarch64/misc_helpers.S b/lib/aarch64/misc_helpers.S index d298f2b66..052891683 100644 --- a/lib/aarch64/misc_helpers.S +++ b/lib/aarch64/misc_helpers.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -496,7 +496,7 @@ func fixup_gdt_reloc /* Test if the limits are 4K aligned */ #if ENABLE_ASSERTIONS orr x0, x0, x1 - tst x0, #(PAGE_SIZE - 1) + tst x0, #(PAGE_SIZE_MASK) ASM_ASSERT(eq) #endif /* @@ -504,7 +504,7 @@ func fixup_gdt_reloc * Assume that this function is called within a page at the start of * fixup region. */ - and x2, x30, #~(PAGE_SIZE - 1) + and x2, x30, #~(PAGE_SIZE_MASK) sub x0, x2, x6 /* Diff(S) = Current Address - Compiled Address */ adrp x1, __GOT_START__ diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c index e5434eb13..b460731e8 100644 --- a/lib/el3_runtime/aarch64/context_mgmt.c +++ b/lib/el3_runtime/aarch64/context_mgmt.c @@ -710,7 +710,7 @@ void cm_write_scr_el3_bit(uint32_t security_state, assert(ctx != NULL); /* Ensure that the bit position is a valid one */ - assert(((1U << bit_pos) & SCR_VALID_BIT_MASK) != 0U); + assert(((1UL << bit_pos) & SCR_VALID_BIT_MASK) != 0U); /* Ensure that the 'value' is only a bit wide */ assert(value <= 1U); @@ -721,7 +721,7 @@ void cm_write_scr_el3_bit(uint32_t security_state, */ state = get_el3state_ctx(ctx); scr_el3 = read_ctx_reg(state, CTX_SCR_EL3); - scr_el3 &= ~(1U << bit_pos); + scr_el3 &= ~(1UL << bit_pos); scr_el3 |= (u_register_t)value << bit_pos; write_ctx_reg(state, CTX_SCR_EL3, scr_el3); } diff --git a/lib/psci/psci_common.c b/lib/psci/psci_common.c index 6d813774d..9f8a08abb 100644 --- a/lib/psci/psci_common.c +++ b/lib/psci/psci_common.c @@ -663,7 +663,8 @@ static int psci_get_ns_ep_info(entry_point_info_t *ep, mode = ((ns_scr_el3 & SCR_HCE_BIT) != 0U) ? MODE_EL2 : MODE_EL1; - ep->spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); + ep->spsr = SPSR_64((uint64_t)mode, MODE_SP_ELX, + DISABLE_ALL_EXCEPTIONS); } else { mode = ((ns_scr_el3 & SCR_HCE_BIT) != 0U) ? @@ -675,7 +676,8 @@ static int psci_get_ns_ep_info(entry_point_info_t *ep, */ daif = DAIF_ABT_BIT | DAIF_IRQ_BIT | DAIF_FIQ_BIT; - ep->spsr = SPSR_MODE32(mode, entrypoint & 0x1, ee, daif); + ep->spsr = SPSR_MODE32((uint64_t)mode, entrypoint & 0x1, ee, + daif); } return PSCI_E_SUCCESS; diff --git a/lib/xlat_tables_v2/xlat_tables_utils.c b/lib/xlat_tables_v2/xlat_tables_utils.c index 30babc63f..9fae7e917 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-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -472,7 +472,7 @@ int xlat_change_mem_attributes_ctx(const xlat_ctx_t *ctx, uintptr_t base_va, /* * Sanity checks. */ - for (size_t i = 0U; i < pages_count; ++i) { + for (unsigned int i = 0U; i < pages_count; ++i) { const uint64_t *entry; uint64_t desc, attr_index; unsigned int level; @@ -497,8 +497,8 @@ int xlat_change_mem_attributes_ctx(const xlat_ctx_t *ctx, uintptr_t base_va, (level != XLAT_TABLE_LEVEL_MAX)) { WARN("Address 0x%lx is not mapped at the right granularity.\n", base_va); - WARN("Granularity is 0x%llx, should be 0x%x.\n", - (unsigned long long)XLAT_BLOCK_SIZE(level), PAGE_SIZE); + WARN("Granularity is 0x%lx, should be 0x%lx.\n", + XLAT_BLOCK_SIZE(level), PAGE_SIZE); return -EINVAL; } diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c index 296aaf8bf..7d9fd6c72 100644 --- a/plat/arm/common/arm_common.c +++ b/plat/arm/common/arm_common.c @@ -97,7 +97,7 @@ uint32_t arm_get_spsr_for_bl33_entry(void) * the FIP ToC and allowing the platform to have a say as * well. */ - spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); + spsr = SPSR_64((uint64_t)mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); return spsr; } #else -- cgit v1.2.3 From f964f5c363bc0f690520153741f0f22226e871cc Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Wed, 8 Jan 2020 10:05:14 +0100 Subject: stm32mp1: add finished good variant in board identifier Update the board info with the new coding including the finished good variant: Board: MBxxxx Var. Rev.- The OTP 59 coding is: bit [31:16] (hex) => MBxxxx bit [15:12] (dec) => Variant CPN (1....15) bit [11:8] (dec) => Revision board (index with A = 1, Z = 26) bit [7:4] (dec) => Variant FG : finished good (NEW) bit [3:0] (dec) => BOM (01, .... 255) Change-Id: I4fbc0c84596419d1bc30d166311444ece1d9123f Signed-off-by: Patrick Delaunay Signed-off-by: Yann Gautier --- plat/st/stm32mp1/stm32mp1_private.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c index e1df31829..02579d8c6 100644 --- a/plat/st/stm32mp1/stm32mp1_private.c +++ b/plat/st/stm32mp1/stm32mp1_private.c @@ -16,18 +16,22 @@ /* Internal layout of the 32bit OTP word board_id */ #define BOARD_ID_BOARD_NB_MASK GENMASK(31, 16) #define BOARD_ID_BOARD_NB_SHIFT 16 -#define BOARD_ID_VARIANT_MASK GENMASK(15, 12) -#define BOARD_ID_VARIANT_SHIFT 12 +#define BOARD_ID_VARCPN_MASK GENMASK(15, 12) +#define BOARD_ID_VARCPN_SHIFT 12 #define BOARD_ID_REVISION_MASK GENMASK(11, 8) #define BOARD_ID_REVISION_SHIFT 8 +#define BOARD_ID_VARFG_MASK GENMASK(7, 4) +#define BOARD_ID_VARFG_SHIFT 4 #define BOARD_ID_BOM_MASK GENMASK(3, 0) #define BOARD_ID2NB(_id) (((_id) & BOARD_ID_BOARD_NB_MASK) >> \ BOARD_ID_BOARD_NB_SHIFT) -#define BOARD_ID2VAR(_id) (((_id) & BOARD_ID_VARIANT_MASK) >> \ - BOARD_ID_VARIANT_SHIFT) +#define BOARD_ID2VARCPN(_id) (((_id) & BOARD_ID_VARCPN_MASK) >> \ + BOARD_ID_VARCPN_SHIFT) #define BOARD_ID2REV(_id) (((_id) & BOARD_ID_REVISION_MASK) >> \ BOARD_ID_REVISION_SHIFT) +#define BOARD_ID2VARFG(_id) (((_id) & BOARD_ID_VARFG_MASK) >> \ + BOARD_ID_VARFG_SHIFT) #define BOARD_ID2BOM(_id) ((_id) & BOARD_ID_BOM_MASK) #if defined(IMAGE_BL2) @@ -333,9 +337,10 @@ void stm32mp_print_boardinfo(void) rev[0] = BOARD_ID2REV(board_id) - 1 + 'A'; rev[1] = '\0'; - NOTICE("Board: MB%04x Var%d Rev.%s-%02d\n", + NOTICE("Board: MB%04x Var%d.%d Rev.%s-%02d\n", BOARD_ID2NB(board_id), - BOARD_ID2VAR(board_id), + BOARD_ID2VARCPN(board_id), + BOARD_ID2VARFG(board_id), rev, BOARD_ID2BOM(board_id)); } -- cgit v1.2.3 From ade9ce03b867e0df5886b81888ad05a8905c0728 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Tue, 5 May 2020 17:58:40 +0200 Subject: stm32mp1: get peripheral base address from a define Retrieve peripheral base address from a define instead of parsing the device tree. The goal is to improve execution time. Signed-off-by: Pascal Paillet Signed-off-by: Yann Gautier Change-Id: I2588c53ad3d4abcc3d7fe156458434a7940dd72b --- drivers/st/clk/stm32mp1_clk.c | 37 +++++------ drivers/st/clk/stm32mp_clkfunc.c | 58 +---------------- include/drivers/st/stm32mp_clkfunc.h | 4 +- plat/st/common/include/stm32mp_dt.h | 4 -- plat/st/common/stm32mp_common.c | 40 ++---------- plat/st/common/stm32mp_dt.c | 120 ----------------------------------- plat/st/stm32mp1/stm32mp1_def.h | 4 +- plat/st/stm32mp1/stm32mp1_syscfg.c | 32 ++++------ 8 files changed, 38 insertions(+), 261 deletions(-) diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c index f8bc5a217..564bd8798 100644 --- a/drivers/st/clk/stm32mp1_clk.c +++ b/drivers/st/clk/stm32mp1_clk.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2019, STMicroelectronics - All Rights Reserved + * Copyright (C) 2018-2020, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ @@ -1664,28 +1664,26 @@ static void stm32mp1_set_rtcsrc(unsigned int clksrc, bool lse_css) static void stm32mp1_stgen_config(void) { - uintptr_t stgen; uint32_t cntfid0; unsigned long rate; unsigned long long counter; - stgen = fdt_get_stgen_base(); - cntfid0 = mmio_read_32(stgen + CNTFID_OFF); + cntfid0 = mmio_read_32(STGEN_BASE + CNTFID_OFF); rate = get_clock_rate(stm32mp1_clk_get_parent(STGEN_K)); if (cntfid0 == rate) { return; } - mmio_clrbits_32(stgen + CNTCR_OFF, CNTCR_EN); - counter = (unsigned long long)mmio_read_32(stgen + CNTCVL_OFF); - counter |= ((unsigned long long)mmio_read_32(stgen + CNTCVU_OFF)) << 32; + mmio_clrbits_32(STGEN_BASE + CNTCR_OFF, CNTCR_EN); + counter = (unsigned long long)mmio_read_32(STGEN_BASE + CNTCVL_OFF); + counter |= ((unsigned long long)mmio_read_32(STGEN_BASE + CNTCVU_OFF)) << 32; counter = (counter * rate / cntfid0); - mmio_write_32(stgen + CNTCVL_OFF, (uint32_t)counter); - mmio_write_32(stgen + CNTCVU_OFF, (uint32_t)(counter >> 32)); - mmio_write_32(stgen + CNTFID_OFF, rate); - mmio_setbits_32(stgen + CNTCR_OFF, CNTCR_EN); + mmio_write_32(STGEN_BASE + CNTCVL_OFF, (uint32_t)counter); + mmio_write_32(STGEN_BASE + CNTCVU_OFF, (uint32_t)(counter >> 32)); + mmio_write_32(STGEN_BASE + CNTFID_OFF, rate); + mmio_setbits_32(STGEN_BASE + CNTCR_OFF, CNTCR_EN); write_cntfrq((u_register_t)rate); @@ -1695,20 +1693,17 @@ static void stm32mp1_stgen_config(void) void stm32mp1_stgen_increment(unsigned long long offset_in_ms) { - uintptr_t stgen; unsigned long long cnt; - stgen = fdt_get_stgen_base(); + cnt = ((unsigned long long)mmio_read_32(STGEN_BASE + CNTCVU_OFF) << 32) | + mmio_read_32(STGEN_BASE + CNTCVL_OFF); - cnt = ((unsigned long long)mmio_read_32(stgen + CNTCVU_OFF) << 32) | - mmio_read_32(stgen + CNTCVL_OFF); + cnt += (offset_in_ms * mmio_read_32(STGEN_BASE + CNTFID_OFF)) / 1000U; - cnt += (offset_in_ms * mmio_read_32(stgen + CNTFID_OFF)) / 1000U; - - mmio_clrbits_32(stgen + CNTCR_OFF, CNTCR_EN); - mmio_write_32(stgen + CNTCVL_OFF, (uint32_t)cnt); - mmio_write_32(stgen + CNTCVU_OFF, (uint32_t)(cnt >> 32)); - mmio_setbits_32(stgen + CNTCR_OFF, CNTCR_EN); + mmio_clrbits_32(STGEN_BASE + CNTCR_OFF, CNTCR_EN); + mmio_write_32(STGEN_BASE + CNTCVL_OFF, (uint32_t)cnt); + mmio_write_32(STGEN_BASE + CNTCVU_OFF, (uint32_t)(cnt >> 32)); + mmio_setbits_32(STGEN_BASE + CNTCR_OFF, CNTCR_EN); } static void stm32mp1_pkcs_config(uint32_t pkcs) diff --git a/drivers/st/clk/stm32mp_clkfunc.c b/drivers/st/clk/stm32mp_clkfunc.c index e87ab1ba7..8333f6dfb 100644 --- a/drivers/st/clk/stm32mp_clkfunc.c +++ b/drivers/st/clk/stm32mp_clkfunc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved + * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ @@ -14,8 +14,6 @@ #include #include -#define DT_STGEN_COMPAT "st,stm32-stgen" - /* * Get the frequency of an oscillator from its name in device tree. * @param name: oscillator name @@ -168,33 +166,6 @@ int fdt_get_rcc_node(void *fdt) return fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT); } -/* - * Get the RCC base address from the device tree - * @return: RCC address or 0 on error - */ -uint32_t fdt_rcc_read_addr(void) -{ - int node; - void *fdt; - const fdt32_t *cuint; - - if (fdt_get_address(&fdt) == 0) { - return 0; - } - - node = fdt_get_rcc_node(fdt); - if (node < 0) { - return 0; - } - - cuint = fdt_getprop(fdt, node, "reg", NULL); - if (cuint == NULL) { - return 0; - } - - return fdt32_to_cpu(*cuint); -} - /* * Read a series of parameters in rcc-clk section in device tree * @param prop_name: Name of the RCC property to be read @@ -298,33 +269,6 @@ bool fdt_get_rcc_secure_status(void) return !!(fdt_get_status(node) & DT_SECURE); } -/* - * Get the stgen base address. - * @return: address of stgen on success, and NULL value on failure. - */ -uintptr_t fdt_get_stgen_base(void) -{ - int node; - const fdt32_t *cuint; - void *fdt; - - if (fdt_get_address(&fdt) == 0) { - return 0; - } - - node = fdt_node_offset_by_compatible(fdt, -1, DT_STGEN_COMPAT); - if (node < 0) { - return 0; - } - - cuint = fdt_getprop(fdt, node, "reg", NULL); - if (cuint == NULL) { - return 0; - } - - return fdt32_to_cpu(*cuint); -} - /* * Get the clock ID of the given node in device tree. * @param node: node offset diff --git a/include/drivers/st/stm32mp_clkfunc.h b/include/drivers/st/stm32mp_clkfunc.h index 0902f445d..c7e0b6e6f 100644 --- a/include/drivers/st/stm32mp_clkfunc.h +++ b/include/drivers/st/stm32mp_clkfunc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved + * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ @@ -20,14 +20,12 @@ uint32_t fdt_osc_read_uint32_default(enum stm32mp_osc_id osc_id, uint32_t dflt_value); int fdt_get_rcc_node(void *fdt); -uint32_t fdt_rcc_read_addr(void); int fdt_rcc_read_uint32_array(const char *prop_name, uint32_t count, uint32_t *array); int fdt_rcc_subnode_offset(const char *name); const fdt32_t *fdt_rcc_read_prop(const char *prop_name, int *lenp); bool fdt_get_rcc_secure_status(void); -uintptr_t fdt_get_stgen_base(void); int fdt_get_clock_id(int node); #endif /* STM32MP_CLKFUNC_H */ diff --git a/plat/st/common/include/stm32mp_dt.h b/plat/st/common/include/stm32mp_dt.h index 44ad820dc..e3b4e597e 100644 --- a/plat/st/common/include/stm32mp_dt.h +++ b/plat/st/common/include/stm32mp_dt.h @@ -34,11 +34,7 @@ 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); uint32_t dt_get_ddr_size(void); -uintptr_t dt_get_ddrctrl_base(void); -uintptr_t dt_get_ddrphyc_base(void); -uintptr_t dt_get_pwr_base(void); uint32_t dt_get_pwr_vdd_voltage(void); -uintptr_t dt_get_syscfg_base(void); const char *dt_get_board_model(void); int fdt_get_gpio_bank_pin_count(unsigned int bank); diff --git a/plat/st/common/stm32mp_common.c b/plat/st/common/stm32mp_common.c index 48a747c7c..89d807838 100644 --- a/plat/st/common/stm32mp_common.c +++ b/plat/st/common/stm32mp_common.c @@ -39,54 +39,22 @@ uintptr_t stm32mp_get_boot_ctx_address(void) uintptr_t stm32mp_ddrctrl_base(void) { - static uintptr_t ddrctrl_base; - - if (ddrctrl_base == 0) { - ddrctrl_base = dt_get_ddrctrl_base(); - - assert(ddrctrl_base == DDRCTRL_BASE); - } - - return ddrctrl_base; + return DDRCTRL_BASE; } uintptr_t stm32mp_ddrphyc_base(void) { - static uintptr_t ddrphyc_base; - - if (ddrphyc_base == 0) { - ddrphyc_base = dt_get_ddrphyc_base(); - - assert(ddrphyc_base == DDRPHYC_BASE); - } - - return ddrphyc_base; + return DDRPHYC_BASE; } uintptr_t stm32mp_pwr_base(void) { - static uintptr_t pwr_base; - - if (pwr_base == 0) { - pwr_base = dt_get_pwr_base(); - - assert(pwr_base == PWR_BASE); - } - - return pwr_base; + return PWR_BASE; } uintptr_t stm32mp_rcc_base(void) { - static uintptr_t rcc_base; - - if (rcc_base == 0) { - rcc_base = fdt_rcc_read_addr(); - - assert(rcc_base == RCC_BASE); - } - - return rcc_base; + return RCC_BASE; } bool stm32mp_lock_available(void) diff --git a/plat/st/common/stm32mp_dt.c b/plat/st/common/stm32mp_dt.c index 4b8b2db90..391e5f054 100644 --- a/plat/st/common/stm32mp_dt.c +++ b/plat/st/common/stm32mp_dt.c @@ -113,26 +113,6 @@ static int fdt_get_node_parent_address_cells(int node) return fdt_address_cells(fdt, parent); } - -/******************************************************************************* - * This function returns the size cells from the node parent. - * Returns: - * - #size-cells value if success. - * - invalid value if error. - * - a default value if undefined #size-cells property as per libfdt - * implementation. - ******************************************************************************/ -static int fdt_get_node_parent_size_cells(int node) -{ - int parent; - - parent = fdt_parent_offset(fdt, node); - if (parent < 0) { - return -FDT_ERR_NOTFOUND; - } - - return fdt_size_cells(fdt, parent); -} #endif /******************************************************************************* @@ -240,81 +220,6 @@ uint32_t dt_get_ddr_size(void) return fdt_read_uint32_default(fdt, node, "st,mem-size", 0); } -/******************************************************************************* - * This function gets DDRCTRL base address information from the DT. - * Returns value on success, and 0 on failure. - ******************************************************************************/ -uintptr_t dt_get_ddrctrl_base(void) -{ - int node; - uint32_t array[4]; - - node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT); - if (node < 0) { - INFO("%s: Cannot read DDR node in DT\n", __func__); - return 0; - } - - assert((fdt_get_node_parent_address_cells(node) == 1) && - (fdt_get_node_parent_size_cells(node) == 1)); - - if (fdt_read_uint32_array(fdt, node, "reg", 4, array) < 0) { - return 0; - } - - return array[0]; -} - -/******************************************************************************* - * This function gets DDRPHYC base address information from the DT. - * Returns value on success, and 0 on failure. - ******************************************************************************/ -uintptr_t dt_get_ddrphyc_base(void) -{ - int node; - uint32_t array[4]; - - node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT); - if (node < 0) { - INFO("%s: Cannot read DDR node in DT\n", __func__); - return 0; - } - - assert((fdt_get_node_parent_address_cells(node) == 1) && - (fdt_get_node_parent_size_cells(node) == 1)); - - if (fdt_read_uint32_array(fdt, node, "reg", 4, array) < 0) { - return 0; - } - - return array[2]; -} - -/******************************************************************************* - * This function gets PWR base address information from the DT. - * Returns value on success, and 0 on failure. - ******************************************************************************/ -uintptr_t dt_get_pwr_base(void) -{ - int node; - const fdt32_t *cuint; - - node = fdt_node_offset_by_compatible(fdt, -1, DT_PWR_COMPAT); - if (node < 0) { - INFO("%s: Cannot read PWR node in DT\n", __func__); - return 0; - } - - assert(fdt_get_node_parent_address_cells(node) == 1); - - cuint = fdt_getprop(fdt, node, "reg", NULL); - if (cuint == NULL) { - return 0; - } - - return fdt32_to_cpu(*cuint); -} - /******************************************************************************* * This function gets PWR VDD regulator voltage information from the DT. * Returns value in microvolts on success, and 0 on failure. @@ -354,31 +259,6 @@ uint32_t dt_get_pwr_vdd_voltage(void) return fdt32_to_cpu(*cuint); } -/******************************************************************************* - * This function gets SYSCFG base address information from the DT. - * Returns value on success, and 0 on failure. - ******************************************************************************/ -uintptr_t dt_get_syscfg_base(void) -{ - int node; - const fdt32_t *cuint; - - node = fdt_node_offset_by_compatible(fdt, -1, DT_SYSCFG_COMPAT); - if (node < 0) { - INFO("%s: Cannot read SYSCFG node in DT\n", __func__); - return 0; - } - - assert(fdt_get_node_parent_address_cells(node) == 1); - - cuint = fdt_getprop(fdt, node, "reg", NULL); - if (cuint == NULL) { - return 0; - } - - return fdt32_to_cpu(*cuint); -} - /******************************************************************************* * This function retrieves board model from DT * Returns string taken from model node, NULL otherwise diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h index 37b9125d8..ee04a23fd 100644 --- a/plat/st/stm32mp1/stm32mp1_def.h +++ b/plat/st/stm32mp1/stm32mp1_def.h @@ -506,6 +506,7 @@ static inline uint32_t tamp_bkpr(uint32_t idx) /******************************************************************************* * Miscellaneous STM32MP1 peripherals base address ******************************************************************************/ +#define BSEC_BASE U(0x5C005000) #define CRYP1_BASE U(0x54001000) #define DBGMCU_BASE U(0x50081000) #define HASH1_BASE U(0x54002000) @@ -514,6 +515,8 @@ static inline uint32_t tamp_bkpr(uint32_t idx) #define RNG1_BASE U(0x54003000) #define RTC_BASE U(0x5c004000) #define SPI6_BASE U(0x5c001000) +#define STGEN_BASE U(0x5c008000) +#define SYSCFG_BASE U(0x50020000) /******************************************************************************* * Device Tree defines @@ -522,6 +525,5 @@ static inline uint32_t tamp_bkpr(uint32_t idx) #define DT_IWDG_COMPAT "st,stm32mp1-iwdg" #define DT_PWR_COMPAT "st,stm32mp1,pwr-reg" #define DT_RCC_CLK_COMPAT "st,stm32mp1-rcc" -#define DT_SYSCFG_COMPAT "st,stm32mp157-syscfg" #endif /* STM32MP1_DEF_H */ diff --git a/plat/st/stm32mp1/stm32mp1_syscfg.c b/plat/st/stm32mp1/stm32mp1_syscfg.c index 2fd06f38a..109725c8a 100644 --- a/plat/st/stm32mp1/stm32mp1_syscfg.c +++ b/plat/st/stm32mp1/stm32mp1_syscfg.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, STMicroelectronics - All Rights Reserved + * Copyright (c) 2019-2020, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ @@ -63,18 +63,17 @@ void stm32mp1_syscfg_init(void) uint32_t bootr; uint32_t otp = 0; uint32_t vdd_voltage; - uintptr_t syscfg_base = dt_get_syscfg_base(); /* * Interconnect update : select master using the port 1. * LTDC = AXI_M9. */ - mmio_write_32(syscfg_base + SYSCFG_ICNR, SYSCFG_ICNR_AXI_M9); + mmio_write_32(SYSCFG_BASE + SYSCFG_ICNR, SYSCFG_ICNR_AXI_M9); /* Disable Pull-Down for boot pin connected to VDD */ - bootr = mmio_read_32(syscfg_base + SYSCFG_BOOTR) & + bootr = mmio_read_32(SYSCFG_BASE + SYSCFG_BOOTR) & SYSCFG_BOOTR_BOOT_MASK; - mmio_clrsetbits_32(syscfg_base + SYSCFG_BOOTR, SYSCFG_BOOTR_BOOTPD_MASK, + mmio_clrsetbits_32(SYSCFG_BASE + SYSCFG_BOOTR, SYSCFG_BOOTR_BOOTPD_MASK, bootr << SYSCFG_BOOTR_BOOTPD_SHIFT); /* @@ -105,7 +104,7 @@ void stm32mp1_syscfg_init(void) if (vdd_voltage == 0U) { WARN("VDD unknown"); } else if (vdd_voltage < 2700000U) { - mmio_write_32(syscfg_base + SYSCFG_IOCTRLSETR, + mmio_write_32(SYSCFG_BASE + SYSCFG_IOCTRLSETR, SYSCFG_IOCTRLSETR_HSLVEN_TRACE | SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI | SYSCFG_IOCTRLSETR_HSLVEN_ETH | @@ -129,8 +128,6 @@ void stm32mp1_syscfg_init(void) void stm32mp1_syscfg_enable_io_compensation(void) { - uintptr_t syscfg_base = dt_get_syscfg_base(); - /* * Activate automatic I/O compensation. * Warning: need to ensure CSI enabled and ready in clock driver. @@ -138,20 +135,19 @@ void stm32mp1_syscfg_enable_io_compensation(void) */ stm32mp1_clk_enable_non_secure(SYSCFG); - mmio_setbits_32(syscfg_base + SYSCFG_CMPENSETR, + mmio_setbits_32(SYSCFG_BASE + SYSCFG_CMPENSETR, SYSCFG_CMPENSETR_MPU_EN); - while ((mmio_read_32(syscfg_base + SYSCFG_CMPCR) & + while ((mmio_read_32(SYSCFG_BASE + SYSCFG_CMPCR) & SYSCFG_CMPCR_READY) == 0U) { ; } - mmio_clrbits_32(syscfg_base + SYSCFG_CMPCR, SYSCFG_CMPCR_SW_CTRL); + mmio_clrbits_32(SYSCFG_BASE + SYSCFG_CMPCR, SYSCFG_CMPCR_SW_CTRL); } void stm32mp1_syscfg_disable_io_compensation(void) { - uintptr_t syscfg_base = dt_get_syscfg_base(); uint32_t value; /* @@ -160,20 +156,18 @@ void stm32mp1_syscfg_disable_io_compensation(void) * requested for other usages and always OFF in STANDBY. * Disable non-secure SYSCFG clock, we assume non-secure is suspended. */ - value = mmio_read_32(syscfg_base + SYSCFG_CMPCR) >> + value = mmio_read_32(SYSCFG_BASE + SYSCFG_CMPCR) >> SYSCFG_CMPCR_ANSRC_SHIFT; - mmio_clrbits_32(syscfg_base + SYSCFG_CMPCR, + mmio_clrbits_32(SYSCFG_BASE + SYSCFG_CMPCR, SYSCFG_CMPCR_RANSRC | SYSCFG_CMPCR_RAPSRC); - value = mmio_read_32(syscfg_base + SYSCFG_CMPCR) | + value = mmio_read_32(SYSCFG_BASE + SYSCFG_CMPCR) | (value << SYSCFG_CMPCR_RANSRC_SHIFT); - mmio_write_32(syscfg_base + SYSCFG_CMPCR, value); - - mmio_setbits_32(syscfg_base + SYSCFG_CMPCR, SYSCFG_CMPCR_SW_CTRL); + mmio_write_32(SYSCFG_BASE + SYSCFG_CMPCR, value | SYSCFG_CMPCR_SW_CTRL); - mmio_clrbits_32(syscfg_base + SYSCFG_CMPENSETR, + mmio_clrbits_32(SYSCFG_BASE + SYSCFG_CMPENSETR, SYSCFG_CMPENSETR_MPU_EN); stm32mp1_clk_disable_non_secure(SYSCFG); -- cgit v1.2.3 From ffb3f2771340a75c713c992a11501f963ddc310f Mon Sep 17 00:00:00 2001 From: Lionel Debieve Date: Tue, 25 Jun 2019 10:40:37 +0200 Subject: stm32mp1: support of STM32MP15x Rev.Z Add a new revision of STM32MP15x CPU (Rev.Z). Change-Id: I227dd6d9b3fcc43270015cfb21f60aeb0a8ab658 Signed-off-by: Lionel Debieve Signed-off-by: Yann Gautier --- plat/st/stm32mp1/stm32mp1_def.h | 1 + plat/st/stm32mp1/stm32mp1_private.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h index 369ba6921..825df2cae 100644 --- a/plat/st/stm32mp1/stm32mp1_def.h +++ b/plat/st/stm32mp1/stm32mp1_def.h @@ -39,6 +39,7 @@ #define STM32MP151A_PART_NB U(0x0500002F) #define STM32MP1_REV_B U(0x2000) +#define STM32MP1_REV_Z U(0x2001) /******************************************************************************* * PACKAGE ID diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c index fd60db282..499766d3d 100644 --- a/plat/st/stm32mp1/stm32mp1_private.c +++ b/plat/st/stm32mp1/stm32mp1_private.c @@ -261,6 +261,9 @@ void stm32mp_print_cpuinfo(void) case STM32MP1_REV_B: cpu_r = "B"; break; + case STM32MP1_REV_Z: + cpu_r = "Z"; + break; default: cpu_r = "?"; break; -- cgit v1.2.3 From 8ccf4954bf747099e999b111ab0c19cc7186b986 Mon Sep 17 00:00:00 2001 From: Lionel Debieve Date: Fri, 17 May 2019 16:01:18 +0200 Subject: stm32mp1: add support for new SoC profiles Update to support new part numbers. Add new STM32 MPUs Part = STM32MP151F, STM32MP153F, STM32MP157F, STM32MP151D, STM32MP153D, STM32MP157D The STM32MP1 series is available in 3 different lines which are pin-to-pin compatible: - STM32MP157: Dual Cortex-A7 cores, Cortex-M4 core @ 209 MHz, 3D GPU, DSI display interface and CAN FD - STM32MP153: Dual Cortex-A7 cores, Cortex-M4 core @ 209 MHz and CAN FD - STM32MP151: Single Cortex-A7 core, Cortex-M4 core @ 209 MHz Each line comes with a security option (cryptography & secure boot) & a Cortex-A frequency option : - A Basic + Cortex-A7 @ 650 MHz - C Secure Boot + HW Crypto + Cortex-A7 @ 650 MHz - D Basic + Cortex-A7 @ 800 MHz - F Secure Boot + HW Crypto + Cortex-A7 @ 800 MHz Remove useless variable in stm32mp_is_single_core(). Change-Id: Id30c836af986c6340c91efa8a7ae9480a2827089 Signed-off-by: Lionel Debieve Signed-off-by: Yann Gautier --- plat/st/stm32mp1/stm32mp1_def.h | 6 ++++++ plat/st/stm32mp1/stm32mp1_private.c | 28 ++++++++++++++++++++++------ 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h index 825df2cae..37b9125d8 100644 --- a/plat/st/stm32mp1/stm32mp1_def.h +++ b/plat/st/stm32mp1/stm32mp1_def.h @@ -37,6 +37,12 @@ #define STM32MP153A_PART_NB U(0x05000025) #define STM32MP151C_PART_NB U(0x0500002E) #define STM32MP151A_PART_NB U(0x0500002F) +#define STM32MP157F_PART_NB U(0x05000080) +#define STM32MP157D_PART_NB U(0x05000081) +#define STM32MP153F_PART_NB U(0x050000A4) +#define STM32MP153D_PART_NB U(0x050000A5) +#define STM32MP151F_PART_NB U(0x050000AE) +#define STM32MP151D_PART_NB U(0x050000AF) #define STM32MP1_REV_B U(0x2000) #define STM32MP1_REV_Z U(0x2001) diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c index 499766d3d..29c4ad7ce 100644 --- a/plat/st/stm32mp1/stm32mp1_private.c +++ b/plat/st/stm32mp1/stm32mp1_private.c @@ -220,6 +220,24 @@ void stm32mp_print_cpuinfo(void) case STM32MP151A_PART_NB: cpu_s = "151A"; break; + case STM32MP157F_PART_NB: + cpu_s = "157F"; + break; + case STM32MP157D_PART_NB: + cpu_s = "157D"; + break; + case STM32MP153F_PART_NB: + cpu_s = "153F"; + break; + case STM32MP153D_PART_NB: + cpu_s = "153D"; + break; + case STM32MP151F_PART_NB: + cpu_s = "151F"; + break; + case STM32MP151D_PART_NB: + cpu_s = "151D"; + break; default: cpu_s = "????"; break; @@ -323,7 +341,6 @@ void stm32mp_print_boardinfo(void) bool stm32mp_is_single_core(void) { uint32_t part_number; - bool ret = false; if (get_part_number(&part_number) < 0) { ERROR("Invalid part number, assume single core chip"); @@ -333,14 +350,13 @@ bool stm32mp_is_single_core(void) switch (part_number) { case STM32MP151A_PART_NB: case STM32MP151C_PART_NB: - ret = true; - break; + case STM32MP151D_PART_NB: + case STM32MP151F_PART_NB: + return true; default: - break; + return false; } - - return ret; } /* Return true when device is in closed state */ -- cgit v1.2.3 From d75a3409773973510e53742e27f31e82724f1158 Mon Sep 17 00:00:00 2001 From: Nicolas Le Bayon Date: Mon, 23 Sep 2019 11:18:32 +0200 Subject: stm32mp1: add asserts in get_cpu_package() and get_part_number() Change-Id: I2b702698d6be93da5ac86da1cbc98b3838315a5a Signed-off-by: Nicolas Le Bayon Signed-off-by: Yann Gautier --- plat/st/stm32mp1/stm32mp1_private.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c index 29c4ad7ce..e1df31829 100644 --- a/plat/st/stm32mp1/stm32mp1_private.c +++ b/plat/st/stm32mp1/stm32mp1_private.c @@ -154,6 +154,8 @@ static int get_part_number(uint32_t *part_nb) uint32_t part_number; uint32_t dev_id; + assert(part_nb != NULL); + if (stm32mp1_dbgmcu_get_chip_dev_id(&dev_id) < 0) { return -1; } @@ -175,6 +177,8 @@ static int get_cpu_package(uint32_t *cpu_package) { uint32_t package; + assert(cpu_package != NULL); + if (bsec_shadow_read_otp(&package, PACKAGE_OTP) != BSEC_OK) { ERROR("BSEC: PACKAGE_OTP Error\n"); return -1; -- cgit v1.2.3 From 6354401276aaf02a671398c8c69a11b9c7ebd80c Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Tue, 13 Oct 2020 11:27:05 +0200 Subject: docs: update STM32MP1 with versions details After introducing the new STM32MP1 SoC versions in patch [1], the document describing STM32MP1 platform is updated with the information given in the patch commit message. [1]: stm32mp1: add support for new SoC profiles Change-Id: I6d7ce1a3c29678ddac78a6685f5d5daf28c3c3a1 Signed-off-by: Yann Gautier --- docs/plat/stm32mp1.rst | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/docs/plat/stm32mp1.rst b/docs/plat/stm32mp1.rst index 263867c25..f597460db 100644 --- a/docs/plat/stm32mp1.rst +++ b/docs/plat/stm32mp1.rst @@ -8,6 +8,23 @@ The STM32MP1 chip also embeds a Cortex-M4. More information can be found on `STM32MP1 Series`_ page. +STM32MP1 Versions +----------------- +The STM32MP1 series is available in 3 different lines which are pin-to-pin compatible: + +- STM32MP157: Dual Cortex-A7 cores, Cortex-M4 core @ 209 MHz, 3D GPU, DSI display interface and CAN FD +- STM32MP153: Dual Cortex-A7 cores, Cortex-M4 core @ 209 MHz and CAN FD +- STM32MP151: Single Cortex-A7 core, Cortex-M4 core @ 209 MHz + +Each line comes with a security option (cryptography & secure boot) and a Cortex-A frequency option: + +- A Basic + Cortex-A7 @ 650 MHz +- C Secure Boot + HW Crypto + Cortex-A7 @ 650 MHz +- D Basic + Cortex-A7 @ 800 MHz +- F Secure Boot + HW Crypto + Cortex-A7 @ 800 MHz + +The `STM32MP1 part number codification`_ page gives more information about part numbers. + Design ------ The STM32MP1 resets in the ROM code of the Cortex-A7. @@ -129,3 +146,4 @@ OP-TEE artifacts go into separate partitions as follows: .. _STM32MP1 Series: https://www.st.com/en/microcontrollers-microprocessors/stm32mp1-series.html +.. _STM32MP1 part number codification: https://wiki.st.com/stm32mpu/wiki/STM32MP15_microprocessor#Part_number_codification -- cgit v1.2.3 From ab049ec07aad62f3637247e96de8a939ff0958c0 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Tue, 13 Oct 2020 18:03:31 +0200 Subject: stm32mp1: use %u in NOTICE message for board info The board information values, read in an OTP are never negative, %u is then used instead of %d. Change-Id: I3bc22401fb4d54666ddf56411f75b79aca738492 Signed-off-by: Yann Gautier --- plat/st/stm32mp1/stm32mp1_private.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c index 02579d8c6..bc77ee334 100644 --- a/plat/st/stm32mp1/stm32mp1_private.c +++ b/plat/st/stm32mp1/stm32mp1_private.c @@ -337,7 +337,7 @@ void stm32mp_print_boardinfo(void) rev[0] = BOARD_ID2REV(board_id) - 1 + 'A'; rev[1] = '\0'; - NOTICE("Board: MB%04x Var%d.%d Rev.%s-%02d\n", + NOTICE("Board: MB%04x Var%u.%u Rev.%s-%02u\n", BOARD_ID2NB(board_id), BOARD_ID2VARCPN(board_id), BOARD_ID2VARFG(board_id), -- cgit v1.2.3 From b37b52ef8bc05bfd8dcca992d4ba84cd7c5d23bb Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Tue, 13 Oct 2020 18:05:06 +0200 Subject: fdts: add missing hash node in STM32MP157C-ED1 board DT Without this node, the board fails to boot and panics in the function stm32mp_init_auth(). Change-Id: Ia54924410dac2a8c94dd6e45d7e93977fe7d87e2 Signed-off-by: Yann Gautier --- fdts/stm32mp157c-ed1.dts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fdts/stm32mp157c-ed1.dts b/fdts/stm32mp157c-ed1.dts index 615e2cc07..a6b98b7d9 100644 --- a/fdts/stm32mp157c-ed1.dts +++ b/fdts/stm32mp157c-ed1.dts @@ -55,6 +55,10 @@ status="okay"; }; +&hash1 { + status = "okay"; +}; + &i2c4 { pinctrl-names = "default"; pinctrl-0 = <&i2c4_pins_a>; -- cgit v1.2.3 From c5e1b061ced441c85bd286769d963a1fca05c4da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Thu, 15 Oct 2020 13:50:28 +0200 Subject: plat: marvell: armada: a3k: When WTP is empty do not define variables and targets which depends on it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some of targets (e.g. mrvl_flash) depends on WTP build option. Other targets (e.g. fip) can be build also without WTP build option as they do not depend on it. This change put all A3720 variables and targets which depends on WTP into conditional if-endif section, so they are not defined when user has not supplied WTP build option. Target mrvl_flash is defined also when WTP was not specified and in this case it just print error message to help user. Variables which do not depend on WTP are moved to the top of a3700_common.mk file. Signed-off-by: Pali Rohár Change-Id: Idb3892233586a0afca3e0e6564279641d2e4b960 --- plat/marvell/armada/a3k/common/a3700_common.mk | 100 ++++++++++++++----------- 1 file changed, 55 insertions(+), 45 deletions(-) diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk index ace74a8b1..a135d5fd2 100644 --- a/plat/marvell/armada/a3k/common/a3700_common.mk +++ b/plat/marvell/armada/a3k/common/a3700_common.mk @@ -18,6 +18,54 @@ HANDLE_EA_EL3_FIRST := 1 include plat/marvell/marvell.mk #*********** A3700 ************* + +# GICV3 +$(eval $(call add_define,CONFIG_GICV3)) + +# CCI-400 +$(eval $(call add_define,USE_CCI)) + +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk + +MARVELL_GIC_SOURCES := ${GICV3_SOURCES} \ + plat/common/plat_gicv3.c + +PLAT_INCLUDES := -I$(PLAT_FAMILY_BASE)/$(PLAT) \ + -I$(PLAT_COMMON_BASE)/include \ + -I$(PLAT_INCLUDE_BASE)/common \ + -I$(MARVELL_DRV_BASE) \ + -I$/drivers/arm/gic/common/ + +PLAT_BL_COMMON_SOURCES := $(PLAT_COMMON_BASE)/aarch64/a3700_common.c \ + $(MARVELL_COMMON_BASE)/marvell_cci.c \ + $(MARVELL_DRV_BASE)/uart/a3700_console.S + +BL1_SOURCES += $(PLAT_COMMON_BASE)/aarch64/plat_helpers.S \ + lib/cpus/aarch64/cortex_a53.S + +BL31_PORTING_SOURCES := $(PLAT_FAMILY_BASE)/$(PLAT)/board/pm_src.c + +MARVELL_DRV := $(MARVELL_DRV_BASE)/comphy/phy-comphy-3700.c + +BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \ + $(PLAT_COMMON_BASE)/aarch64/plat_helpers.S \ + $(PLAT_COMMON_BASE)/plat_pm.c \ + $(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_ddr_info.c \ + $(MARVELL_COMMON_BASE)/marvell_gicv3.c \ + $(MARVELL_GIC_SOURCES) \ + drivers/arm/cci/cci.c \ + $(BL31_PORTING_SOURCES) \ + $(PLAT_COMMON_BASE)/a3700_sip_svc.c \ + $(MARVELL_DRV) + +ifneq (${WTP},) + DOIMAGEPATH := $(WTP) DOIMAGETOOL := $(DOIMAGEPATH)/wtptp/linux/tbb_linux @@ -72,51 +120,6 @@ TIMBLDUARTARGS := $(MARVELL_SECURE_BOOT) UART $(IMAGESPATH) $(DOIMAGEPATH) $(CL $(DDR_TOPOLOGY) 0 0 $(DOIMAGE_CFG) $(TIMNCFG) $(TIMNSIG) 0 DOIMAGE_FLAGS := -r $(DOIMAGE_CFG) -v -D -# GICV3 -$(eval $(call add_define,CONFIG_GICV3)) - -# CCI-400 -$(eval $(call add_define,USE_CCI)) - -# Include GICv3 driver files -include drivers/arm/gic/v3/gicv3.mk - -MARVELL_GIC_SOURCES := ${GICV3_SOURCES} \ - plat/common/plat_gicv3.c - -PLAT_INCLUDES := -I$(PLAT_FAMILY_BASE)/$(PLAT) \ - -I$(PLAT_COMMON_BASE)/include \ - -I$(PLAT_INCLUDE_BASE)/common \ - -I$(MARVELL_DRV_BASE) \ - -I$/drivers/arm/gic/common/ - -PLAT_BL_COMMON_SOURCES := $(PLAT_COMMON_BASE)/aarch64/a3700_common.c \ - $(MARVELL_COMMON_BASE)/marvell_cci.c \ - $(MARVELL_DRV_BASE)/uart/a3700_console.S - -BL1_SOURCES += $(PLAT_COMMON_BASE)/aarch64/plat_helpers.S \ - lib/cpus/aarch64/cortex_a53.S - -BL31_PORTING_SOURCES := $(PLAT_FAMILY_BASE)/$(PLAT)/board/pm_src.c - -MARVELL_DRV := $(MARVELL_DRV_BASE)/comphy/phy-comphy-3700.c - -BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \ - $(PLAT_COMMON_BASE)/aarch64/plat_helpers.S \ - $(PLAT_COMMON_BASE)/plat_pm.c \ - $(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_ddr_info.c \ - $(MARVELL_COMMON_BASE)/marvell_gicv3.c \ - $(MARVELL_GIC_SOURCES) \ - drivers/arm/cci/cci.c \ - $(BL31_PORTING_SOURCES) \ - $(PLAT_COMMON_BASE)/a3700_sip_svc.c \ - $(MARVELL_DRV) - mrvl_flash: ${BUILD_PLAT}/${FIP_NAME} ${DOIMAGETOOL} $(shell truncate -s %128K ${BUILD_PLAT}/bl1.bin) $(shell cat ${BUILD_PLAT}/bl1.bin ${BUILD_PLAT}/${FIP_NAME} > ${BUILD_PLAT}/${BOOT_IMAGE}) @@ -168,3 +171,10 @@ endif @mv -t $(BUILD_PLAT) $(TIM_IMAGE) $(DOIMAGE_CFG) $(TIMN_IMAGE) $(TIMNCFG) $(WTMI_IMG) $(WTMI_SYSINIT_IMG) $(WTMI_MULTI_IMG) @if [ "$(MARVELL_SECURE_BOOT)" = "1" ]; then mv -t $(BUILD_PLAT) $(WTMI_ENC_IMG) OtpHash.txt; fi @find . -name "*.txt" | grep -E "CSK[[:alnum:]]_KeyHash.txt|Tim_msg.txt|TIMHash.txt" | xargs rm -f + +else # ${WTP} + +mrvl_flash: + $(error "Platform '${PLAT}' for target '$@' requires WTP. Please set WTP to point to the right directory") + +endif # ${WTP} -- cgit v1.2.3 From e0caf8f57ce4c7e16f1b72b19265748647f9744e Mon Sep 17 00:00:00 2001 From: Saurabh Gorecha Date: Thu, 15 Oct 2020 00:05:36 +0530 Subject: Update in coreboot_get_memory_type API to include size as well Change-Id: I3f563cffd58b0591b433c85c0ff6b71e486eb2c8 Signed-off-by: Saurabh Gorecha --- include/lib/coreboot.h | 2 +- lib/coreboot/coreboot_table.c | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/include/lib/coreboot.h b/include/lib/coreboot.h index dda3173a2..0aa65791d 100644 --- a/include/lib/coreboot.h +++ b/include/lib/coreboot.h @@ -39,7 +39,7 @@ typedef enum { CB_MEM_TABLE = 16, } coreboot_memory_t; -coreboot_memory_t coreboot_get_memory_type(uintptr_t address); +coreboot_memory_t coreboot_get_memory_type(uintptr_t start, size_t size); void coreboot_table_setup(void *base); #endif /* COREBOOT_H */ diff --git a/lib/coreboot/coreboot_table.c b/lib/coreboot/coreboot_table.c index c4cd1d752..fb31ef1e0 100644 --- a/lib/coreboot/coreboot_table.c +++ b/lib/coreboot/coreboot_table.c @@ -89,7 +89,7 @@ static void setup_cbmem_console(uintptr_t baseaddr) CONSOLE_FLAG_CRASH); } -coreboot_memory_t coreboot_get_memory_type(uintptr_t address) +coreboot_memory_t coreboot_get_memory_type(uintptr_t start, size_t size) { int i; @@ -98,9 +98,11 @@ coreboot_memory_t coreboot_get_memory_type(uintptr_t address) if (range->type == CB_MEM_NONE) break; /* end of table reached */ - if (address >= range->start && - address - range->start < range->size) + if ((start >= range->start) && + (start - range->start < range->size) && + (size <= range->size - (start - range->start))) { return range->type; + } } return CB_MEM_NONE; -- cgit v1.2.3 From 4b918452bdb3f117c3ab735313e8a1b86e938440 Mon Sep 17 00:00:00 2001 From: Saurabh Gorecha Date: Thu, 15 Oct 2020 00:11:15 +0530 Subject: plat:qti Mandate SMC implementaion and bug fix implementation of SMC call SMCCC_ARCH_SOC_ID adding debugging logs in mem assign call. Checking range of param in mem_assign call is from CB_MEM_RAM or CB_MEM_RESERVED. Change-Id: Iba51bff154df01e02dcb7715582ffaff7beba26e Signed-off-by: Saurabh Gorecha --- plat/qti/common/inc/qti_board_def.h | 8 ++++ plat/qti/common/src/qti_common.c | 46 +++++++++++++++++++++ plat/qti/common/src/qti_syscall.c | 48 ++++++++++++++++------ .../qti/qtiseclib/inc/sc7180/qtiseclib_defs_plat.h | 6 --- plat/qti/sc7180/inc/platform_def.h | 12 ++++++ 5 files changed, 102 insertions(+), 18 deletions(-) diff --git a/plat/qti/common/inc/qti_board_def.h b/plat/qti/common/inc/qti_board_def.h index 4c84661b7..c95e4c0c3 100644 --- a/plat/qti/common/inc/qti_board_def.h +++ b/plat/qti/common/inc/qti_board_def.h @@ -12,6 +12,14 @@ * development platforms */ +/* + * Defines used to retrieve QTI SOC Version + */ +#define JEDEC_QTI_BKID U(0x0) +#define JEDEC_QTI_MFID U(0x70) +#define QTI_SOC_CONTINUATION_SHIFT U(24) +#define QTI_SOC_IDENTIFICATION_SHIFT U(16) + /* Size of cacheable stacks */ #define PLATFORM_STACK_SIZE 0x1000 diff --git a/plat/qti/common/src/qti_common.c b/plat/qti/common/src/qti_common.c index ff0fa3060..9355eb774 100644 --- a/plat/qti/common/src/qti_common.c +++ b/plat/qti/common/src/qti_common.c @@ -11,7 +11,10 @@ #include #include +#include +#include #include +#include #include #include @@ -146,3 +149,46 @@ int qti_mmap_remove_dynamic_region(uintptr_t base_va, size_t size) qti_align_mem_region(base_va, size, &base_va, &size); return mmap_remove_dynamic_region(base_va, size); } + +/* + * This function returns soc version which mainly consist of below fields + * + * soc_version[30:24] = JEP-106 continuation code for the SiP + * soc_version[23:16] = JEP-106 identification code with parity bit for the SiP + * soc_version[0:15] = Implementation defined SoC ID + */ +int32_t plat_get_soc_version(void) +{ + uint32_t soc_version = (QTI_SOC_VERSION & QTI_SOC_VERSION_MASK); + uint32_t jep106az_code = (JEDEC_QTI_BKID << QTI_SOC_CONTINUATION_SHIFT) + | (JEDEC_QTI_MFID << QTI_SOC_IDENTIFICATION_SHIFT); + return (int32_t)(jep106az_code | (soc_version)); +} + +/* + * This function returns soc revision in below format + * + * soc_revision[0:30] = SOC revision of specific SOC + */ +int32_t plat_get_soc_revision(void) +{ + return mmio_read_32(QTI_SOC_REVISION_REG) & QTI_SOC_REVISION_MASK; +} + +/***************************************************************************** + * plat_smccc_feature_available() - This function checks whether SMCCC feature + * is availabile for the platform or not. + * @fid: SMCCC function id + * + * Return SMC_ARCH_CALL_SUCCESS if SMCCC feature is available and + * SMC_ARCH_CALL_NOT_SUPPORTED otherwise. + *****************************************************************************/ +int32_t plat_smccc_feature_available(u_register_t fid) +{ + switch (fid) { + case SMCCC_ARCH_SOC_ID: + return SMC_ARCH_CALL_SUCCESS; + default: + return SMC_ARCH_CALL_NOT_SUPPORTED; + } +} diff --git a/plat/qti/common/src/qti_syscall.c b/plat/qti/common/src/qti_syscall.c index 27c48959f..a7601b657 100644 --- a/plat/qti/common/src/qti_syscall.c +++ b/plat/qti/common/src/qti_syscall.c @@ -27,7 +27,7 @@ */ #define QTI_SIP_SVC_CALL_COUNT_ID U(0x0200ff00) #define QTI_SIP_SVC_UID_ID U(0x0200ff01) -/* 0x8200ff02 is reserved */ +/* 0x8200ff02 is reserved*/ #define QTI_SIP_SVC_VERSION_ID U(0x0200ff03) /* @@ -97,37 +97,52 @@ bool qti_mem_assign_validate_param(memprot_info_t *mem_info, || (src_vm_list_cnt >= QTI_VM_LAST) || (dst_vm_list_cnt == 0) || (dst_vm_list_cnt >= QTI_VM_LAST) || (u_num_mappings == 0) || u_num_mappings > QTI_VM_MAX_LIST_SIZE) { + ERROR("vm count is 0 or more then QTI_VM_LAST or empty list\n"); + ERROR("source_vm_list %p dest_vm_list %p mem_info %p src_vm_list_cnt %u dst_vm_list_cnt %u u_num_mappings %u\n", + source_vm_list, dest_vm_list, mem_info, + (unsigned int)src_vm_list_cnt, + (unsigned int)dst_vm_list_cnt, + (unsigned int)u_num_mappings); return false; } for (i = 0; i < u_num_mappings; i++) { if ((mem_info[i].mem_addr & (SIZE4K - 1)) + || (mem_info[i].mem_size == 0) || (mem_info[i].mem_size & (SIZE4K - 1))) { + ERROR("mem_info passed buffer 0x%x or size 0x%x is not 4k aligned\n", + (unsigned int)mem_info[i].mem_addr, + (unsigned int)mem_info[i].mem_size); return false; } if ((mem_info[i].mem_addr + mem_info[i].mem_size) < mem_info[i].mem_addr) { + ERROR("overflow in mem_addr 0x%x add mem_size 0x%x\n", + (unsigned int)mem_info[i].mem_addr, + (unsigned int)mem_info[i].mem_size); return false; } - if (coreboot_get_memory_type(mem_info[i].mem_addr) != - CB_MEM_RAM) { + coreboot_memory_t mem_type = coreboot_get_memory_type( + mem_info[i].mem_addr, + mem_info[i].mem_size); + if (mem_type != CB_MEM_RAM && mem_type != CB_MEM_RESERVED) { + ERROR("memory region not in CB MEM RAM or RESERVED area: region start 0x%x size 0x%x\n", + (unsigned int)mem_info[i].mem_addr, + (unsigned int)mem_info[i].mem_size); return false; } - - if (coreboot_get_memory_type - (mem_info[i].mem_addr + mem_info[i].mem_size) != - CB_MEM_RAM) { - return false; - } - } for (i = 0; i < src_vm_list_cnt; i++) { if (source_vm_list[i] >= QTI_VM_LAST) { + ERROR("source_vm_list[%d] 0x%x is more then QTI_VM_LAST\n", + i, (unsigned int)source_vm_list[i]); return false; } } for (i = 0; i < dst_vm_list_cnt; i++) { if (dest_vm_list[i].dst_vm >= QTI_VM_LAST) { + ERROR("dest_vm_list[%d] 0x%x is more then QTI_VM_LAST\n", + i, (unsigned int)dest_vm_list[i].dst_vm); return false; } } @@ -150,6 +165,7 @@ static uintptr_t qti_sip_mem_assign(void *handle, uint32_t smc_cc, } /* Validate input arg count & retrieve arg3-6 from NS Buffer. */ if ((x1 != QTI_SIP_SVC_MEM_ASSIGN_PARAM_ID) || (x5 == 0x0)) { + ERROR("invalid mem_assign param id or no mapping info\n"); goto unmap_return; } @@ -160,6 +176,8 @@ static uintptr_t qti_sip_mem_assign(void *handle, uint32_t smc_cc, SMC_32) ? (sizeof(uint32_t) * 4) : (sizeof(uint64_t) * 4); if (qti_mmap_add_dynamic_region(dyn_map_start, dyn_map_size, (MT_NS | MT_RO_DATA)) != 0) { + ERROR("map failed for params NS Buffer %x %x\n", + (unsigned int)dyn_map_start, (unsigned int)dyn_map_size); goto unmap_return; } /* Retrieve indirect args. */ @@ -174,6 +192,8 @@ static uintptr_t qti_sip_mem_assign(void *handle, uint32_t smc_cc, } /* Un-Map NS Buffer. */ if (qti_mmap_remove_dynamic_region(dyn_map_start, dyn_map_size) != 0) { + ERROR("unmap failed for params NS Buffer %x %x\n", + (unsigned int)dyn_map_start, (unsigned int)dyn_map_size); goto unmap_return; } @@ -191,6 +211,8 @@ static uintptr_t qti_sip_mem_assign(void *handle, uint32_t smc_cc, if (qti_mmap_add_dynamic_region(dyn_map_start, dyn_map_size, (MT_NS | MT_RO_DATA)) != 0) { + ERROR("map failed for params NS Buffer2 %x %x\n", + (unsigned int)dyn_map_start, (unsigned int)dyn_map_size); goto unmap_return; } memprot_info_t *mem_info_p = (memprot_info_t *) x2; @@ -205,6 +227,7 @@ static uintptr_t qti_sip_mem_assign(void *handle, uint32_t smc_cc, source_vm_list_p, src_vm_list_cnt, dest_vm_list_p, dst_vm_list_cnt) != true) { + ERROR("Param validation failed\n"); goto unmap_return; } @@ -219,8 +242,7 @@ static uintptr_t qti_sip_mem_assign(void *handle, uint32_t smc_cc, for (int i = 0; i < dst_vm_list_cnt; i++) { dest_vm_list[i].dst_vm = dest_vm_list_p[i].dst_vm; - dest_vm_list[i].dst_vm_perm = - dest_vm_list_p[i].dst_vm_perm; + dest_vm_list[i].dst_vm_perm = dest_vm_list_p[i].dst_vm_perm; dest_vm_list[i].ctx = dest_vm_list_p[i].ctx; dest_vm_list[i].ctx_size = dest_vm_list_p[i].ctx_size; } @@ -233,6 +255,8 @@ static uintptr_t qti_sip_mem_assign(void *handle, uint32_t smc_cc, /* Un-Map NS Buffers. */ if (qti_mmap_remove_dynamic_region(dyn_map_start, dyn_map_size) != 0) { + ERROR("unmap failed for params NS Buffer %x %x\n", + (unsigned int)dyn_map_start, (unsigned int)dyn_map_size); goto unmap_return; } /* Invoke API lib api. */ diff --git a/plat/qti/qtiseclib/inc/sc7180/qtiseclib_defs_plat.h b/plat/qti/qtiseclib/inc/sc7180/qtiseclib_defs_plat.h index c695c190d..3ecee2022 100644 --- a/plat/qti/qtiseclib/inc/sc7180/qtiseclib_defs_plat.h +++ b/plat/qti/qtiseclib/inc/sc7180/qtiseclib_defs_plat.h @@ -13,12 +13,6 @@ #define BL31_BASE 0x80b00000 #define BL31_SIZE 0x00100000 -/*----------------------------------------------------------------------------*/ -/* AOP CMD DB address space for mapping */ -/*----------------------------------------------------------------------------*/ -#define QTI_AOP_CMD_DB_BASE 0x80820000 -#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) diff --git a/plat/qti/sc7180/inc/platform_def.h b/plat/qti/sc7180/inc/platform_def.h index 17e1310b0..b0798a63f 100644 --- a/plat/qti/sc7180/inc/platform_def.h +++ b/plat/qti/sc7180/inc/platform_def.h @@ -178,5 +178,17 @@ /*----------------------------------------------------------------------------*/ #define QTI_PS_HOLD_REG 0x0C264000 /*----------------------------------------------------------------------------*/ +/* AOP CMD DB address space for mapping */ +/*----------------------------------------------------------------------------*/ +#define QTI_AOP_CMD_DB_BASE 0x80820000 +#define QTI_AOP_CMD_DB_SIZE 0x00020000 +/*----------------------------------------------------------------------------*/ +/* SOC hw version register */ +/*----------------------------------------------------------------------------*/ +#define QTI_SOC_VERSION U(0x7180) +#define QTI_SOC_VERSION_MASK U(0xFFFF) +#define QTI_SOC_REVISION_REG 0x1FC8000 +#define QTI_SOC_REVISION_MASK U(0xFFFF) +/*----------------------------------------------------------------------------*/ #endif /* PLATFORM_DEF_H */ -- cgit v1.2.3 From fb28d5254d0e56308674a48b164943172a86a32d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Thu, 8 Oct 2020 15:19:26 +0200 Subject: plat: marvell: armada: Fix dependences for target fip MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For building fip image it is not needed to build target mrvl_flash. This fip image contains only bl2, bl31 and bl33 (u-boot.bin) images and therefore it does not depend on Marvell wtmi and wtp A3700-utils. So remove mrvl_flash dependency for fip target to allow building fip image without need to build mrvl_flash and therefore specify and provide Marvell wmi and wtp A3700-utils. This changes fixes compilation of fip image for A3700 platform by command: make CROSS_COMPILE=aarch64-linux-gnu- BL33=/path/u-boot/u-boot.bin \ DEBUG=0 LOG_LEVEL=0 USE_COHERENT_MEM=0 PLAT=a3700 fip Marvell boot image can be still build by 'mrvl_flash' target. Signed-off-by: Pali Rohár Change-Id: Iba9a9da5be6fd1da23407fc2d490aedcb1a292c9 --- plat/marvell/armada/common/marvell_common.mk | 2 -- 1 file changed, 2 deletions(-) diff --git a/plat/marvell/armada/common/marvell_common.mk b/plat/marvell/armada/common/marvell_common.mk index 2e96e2f84..07864e42f 100644 --- a/plat/marvell/armada/common/marvell_common.mk +++ b/plat/marvell/armada/common/marvell_common.mk @@ -86,5 +86,3 @@ endif ifeq (${MSS_SUPPORT}, 1) include $(MARVELL_PLAT_BASE)/common/mss/mss_common.mk endif - -fip: mrvl_flash -- cgit v1.2.3 From f329442c395e7583327babff1fbbbb2543a8f2c8 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Thu, 8 Oct 2020 02:11:20 +0100 Subject: docs: Update code freeze and release target date for v2.4 Updated code freeze and release information date for v2.4 release. Change-Id: I76d5d04d0ee062a350f6a693eb04c29017d8b2e0 Signed-off-by: Manish V Badarkhe --- 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 f3167fb25..4c424b9e7 100644 --- a/docs/about/release-information.rst +++ b/docs/about/release-information.rst @@ -42,7 +42,7 @@ depending on project requirement and partner feedback. +-----------------+---------------------------+------------------------------+ | v2.3 | 4th week of Apr '20 | 1st week of Apr '20 | +-----------------+---------------------------+------------------------------+ -| v2.4 | 4th week of Oct '20 | 1st week of Oct '20 | +| v2.4 | 2nd week of Nov '20 | 4th week of Oct '20 | +-----------------+---------------------------+------------------------------+ Removal of Deprecated Interfaces -- cgit v1.2.3 From c20bbfa16d30d7840a04f8a3a42a2ca4147da6a9 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Thu, 8 Oct 2020 02:16:25 +0100 Subject: docs: Update Release information for v2.5 Updated tentative code freeze and release target date for v2.5 release. Change-Id: Idcfd9a127e9210846370dfa0685badac5b1c25c7 Signed-off-by: Manish V Badarkhe --- docs/about/release-information.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/about/release-information.rst b/docs/about/release-information.rst index 4c424b9e7..d6f8de85d 100644 --- a/docs/about/release-information.rst +++ b/docs/about/release-information.rst @@ -44,6 +44,8 @@ depending on project requirement and partner feedback. +-----------------+---------------------------+------------------------------+ | v2.4 | 2nd week of Nov '20 | 4th week of Oct '20 | +-----------------+---------------------------+------------------------------+ +| v2.5 | 2nd week of May '21 | 4th week of Apr '21 | ++-----------------+---------------------------+------------------------------+ Removal of Deprecated Interfaces -------------------------------- -- cgit v1.2.3 From 3bd19575e8122c3e32960a2e905f09e446504028 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Thu, 8 Oct 2020 02:21:20 +0100 Subject: docs: Remove deprecated information There are no references to AARCH32, AARCH64 and __ASSEMBLY__ macros in the TF-A code hence removed the deprecated information mentioning about these macros in the document. Change-Id: I472ab985ca2e4173bae23ff7b4465a9b60bc82eb Signed-off-by: Manish V Badarkhe --- docs/about/release-information.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/about/release-information.rst b/docs/about/release-information.rst index d6f8de85d..55c8bdaf4 100644 --- a/docs/about/release-information.rst +++ b/docs/about/release-information.rst @@ -59,9 +59,7 @@ Release version after which it will be removed. | | Date | after | | | | | Release | | +================================+=============+=========+=========================================================+ -| ``AARCH32``/``AARCH64`` macros | Oct '19 | v2.3 | Deprecated in favor of ``__aarch64__`` | -+--------------------------------+-------------+---------+---------------------------------------------------------+ -| ``__ASSEMBLY__`` macro | Oct '19 | v2.3 | Deprecated in favor of ``__ASSEMBLER__`` | +| | | | | +--------------------------------+-------------+---------+---------------------------------------------------------+ -------------- -- cgit v1.2.3 From 0412b7323db50da35beaaa56158993be8f056910 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Mon, 19 Oct 2020 17:10:11 +0200 Subject: plat: marvell: armada: Fix including plat/marvell/marvell.mk file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Include file plat/marvell/marvell.mk for platform A3700 was included two times. Once from file plat/marvell/armada/a3k/common/a3700_common.mk and second time from common file plat/marvell/armada/common/marvell_common.mk. It caused following warning every time was make called: plat/marvell/marvell.mk:51: warning: overriding recipe for target 'mrvl_clean' plat/marvell/marvell.mk:51: warning: ignoring old recipe for target 'mrvl_clean' Change in this commit removes inclusion of plat/marvell/marvell.mk file in common file plat/marvell/armada/common/marvell_common.mk. As a80x0 platform needs this include file, add it also into a80x0 platform specific include file lat/marvell/armada/a8k/common/a8k_common.mk. Also moves inclusion of plat/marvell/marvell.mk file in a3700 platform file plat/marvell/armada/a3k/common/a3700_common.mk at correct place. Global plat/marvell/marvell.mk expects that variables DOIMAGEPATH and DOIMAGETOOL are already defined, but it defines MARVELL_SECURE_BOOT variable which is needed by plat/marvell/armada/a3k/common/a3700_common.mk. Signed-off-by: Pali Rohár Change-Id: I5cbbd7eb8a3376924419f9850516b2a4924be5aa --- plat/marvell/armada/a3k/common/a3700_common.mk | 4 ++-- plat/marvell/armada/a8k/common/a8k_common.mk | 2 ++ plat/marvell/armada/common/marvell_common.mk | 1 - 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk index a135d5fd2..8f65e92b3 100644 --- a/plat/marvell/armada/a3k/common/a3700_common.mk +++ b/plat/marvell/armada/a3k/common/a3700_common.mk @@ -15,8 +15,6 @@ MARVELL_DRV_BASE := drivers/marvell MARVELL_COMMON_BASE := $(MARVELL_PLAT_BASE)/common HANDLE_EA_EL3_FIRST := 1 -include plat/marvell/marvell.mk - #*********** A3700 ************* # GICV3 @@ -69,6 +67,8 @@ ifneq (${WTP},) DOIMAGEPATH := $(WTP) DOIMAGETOOL := $(DOIMAGEPATH)/wtptp/linux/tbb_linux +include plat/marvell/marvell.mk + ifeq ($(MARVELL_SECURE_BOOT),1) DOIMAGE_CFG := $(DOIMAGEPATH)/atf-tim.txt IMAGESPATH := $(DOIMAGEPATH)/tim/trusted diff --git a/plat/marvell/armada/a8k/common/a8k_common.mk b/plat/marvell/armada/a8k/common/a8k_common.mk index 02f1553b0..a807891e5 100644 --- a/plat/marvell/armada/a8k/common/a8k_common.mk +++ b/plat/marvell/armada/a8k/common/a8k_common.mk @@ -33,6 +33,8 @@ $(eval $(call add_define,AP_NUM)) DOIMAGEPATH ?= tools/marvell/doimage DOIMAGETOOL ?= ${DOIMAGEPATH}/doimage +include plat/marvell/marvell.mk + ROM_BIN_EXT ?= $(BUILD_PLAT)/ble.bin DOIMAGE_FLAGS += -b $(ROM_BIN_EXT) $(NAND_DOIMAGE_FLAGS) $(DOIMAGE_SEC_FLAGS) diff --git a/plat/marvell/armada/common/marvell_common.mk b/plat/marvell/armada/common/marvell_common.mk index 2e96e2f84..1cc6dba60 100644 --- a/plat/marvell/armada/common/marvell_common.mk +++ b/plat/marvell/armada/common/marvell_common.mk @@ -7,7 +7,6 @@ MARVELL_PLAT_BASE := plat/marvell/armada MARVELL_PLAT_INCLUDE_BASE := include/plat/marvell/armada include plat/marvell/version.mk -include plat/marvell/marvell.mk VERSION_STRING +=(Marvell-${SUBVERSION}) -- cgit v1.2.3 From 0f777eabd99d4bf40acf0a215112160502917172 Mon Sep 17 00:00:00 2001 From: Arunachalam Ganapathy Date: Tue, 26 May 2020 11:32:35 +0100 Subject: lib: el3_runtime: Fix aarch32 system registers in el2_sysregs_context AArch64-only platforms do not implement AArch32 at EL1 and higher ELs. In such cases the build option CTX_INCLUDE_AARCH32_REGS is set to 0. So don't save/restore aarch32 system registers in el2_sysregs_context save/restore routines if CTX_INCLUDE_AARCH32_REGS is set to 0. Change-Id: I229cdd46136c4b4bc9623b02eb444d904e09ce5a Signed-off-by: Arunachalam Ganapathy --- lib/el3_runtime/aarch64/context.S | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S index 1cb527d99..785e85093 100644 --- a/lib/el3_runtime/aarch64/context.S +++ b/lib/el3_runtime/aarch64/context.S @@ -65,9 +65,13 @@ func el2_sysregs_context_save mrs x9, cptr_el2 stp x17, x9, [x0, #CTX_CNTVOFF_EL2] - mrs x10, dbgvcr32_el2 mrs x11, elr_el2 +#if CTX_INCLUDE_AARCH32_REGS + mrs x10, dbgvcr32_el2 stp x10, x11, [x0, #CTX_DBGVCR32_EL2] +#else + str x11, [x0, #CTX_ELR_EL2] +#endif mrs x14, esr_el2 mrs x15, far_el2 @@ -185,8 +189,10 @@ func el2_sysregs_context_save mrs x9, contextidr_el2 stp x17, x9, [x0, #CTX_CNTHV_TVAL_EL2] +#if CTX_INCLUDE_AARCH32_REGS mrs x10, sder32_el2 str x10, [x0, #CTX_SDER32_EL2] +#endif mrs x11, ttbr1_el2 str x11, [x0, #CTX_TTBR1_EL2] @@ -255,8 +261,12 @@ func el2_sysregs_context_restore msr cntvoff_el2, x17 msr cptr_el2, x9 +#if CTX_INCLUDE_AARCH32_REGS ldp x10, x11, [x0, #CTX_DBGVCR32_EL2] msr dbgvcr32_el2, x10 +#else + ldr x11, [x0, #CTX_ELR_EL2] +#endif msr elr_el2, x11 ldp x14, x15, [x0, #CTX_ESR_EL2] @@ -374,8 +384,10 @@ func el2_sysregs_context_restore msr cnthv_tval_el2, x9 msr contextidr_el2, x10 +#if CTX_INCLUDE_AARCH32_REGS ldr x11, [x0, #CTX_SDER32_EL2] msr sder32_el2, x11 +#endif ldr x12, [x0, #CTX_TTBR1_EL2] msr ttbr1_el2, x12 -- cgit v1.2.3 From 062f8aaf8a415497191f991a744fc7901362ba3c Mon Sep 17 00:00:00 2001 From: Arunachalam Ganapathy Date: Thu, 28 May 2020 11:57:09 +0100 Subject: lib: el3_runtime: Conditionally save/restore EL2 NEVE registers Include EL2 registers related to Nested Virtualization in EL2 context save/restore routines if architecture supports it and platform wants to use these features in Secure world. Change-Id: If006ab83bbc2576488686f5ffdff88b91adced5c Signed-off-by: Arunachalam Ganapathy --- Makefile | 2 ++ docs/getting_started/build-options.rst | 4 ++++ lib/el3_runtime/aarch64/context.S | 4 ++++ make_helpers/defaults.mk | 5 +++++ 4 files changed, 15 insertions(+) diff --git a/Makefile b/Makefile index c5073e016..961423826 100644 --- a/Makefile +++ b/Makefile @@ -865,6 +865,7 @@ $(eval $(call assert_booleans,\ CTX_INCLUDE_PAUTH_REGS \ CTX_INCLUDE_MTE_REGS \ CTX_INCLUDE_EL2_REGS \ + CTX_INCLUDE_NEVE_REGS \ DEBUG \ DYN_DISABLE_AUTH \ EL3_EXCEPTION_HANDLING \ @@ -953,6 +954,7 @@ $(eval $(call add_defines,\ EL3_EXCEPTION_HANDLING \ CTX_INCLUDE_MTE_REGS \ CTX_INCLUDE_EL2_REGS \ + CTX_INCLUDE_NEVE_REGS \ DECRYPTION_SUPPORT_${DECRYPTION_SUPPORT} \ ENABLE_AMU \ ENABLE_ASSERTIONS \ diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 40fc5dbbc..8adf4ad8b 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -161,6 +161,10 @@ Common build options registers to be included when saving and restoring the CPU context. Default is 0. +- ``CTX_INCLUDE_NEVE_REGS``: Boolean option that, when set to 1, will cause the + Armv8.4-NV registers to be saved/restored when entering/exiting an EL2 + execution context. Default value is 0. + - ``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 diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S index 785e85093..c942c10ec 100644 --- a/lib/el3_runtime/aarch64/context.S +++ b/lib/el3_runtime/aarch64/context.S @@ -200,8 +200,10 @@ func el2_sysregs_context_save mrs x12, vdisr_el2 str x12, [x0, #CTX_VDISR_EL2] +#if CTX_INCLUDE_NEVE_REGS mrs x13, vncr_el2 str x13, [x0, #CTX_VNCR_EL2] +#endif mrs x14, vsesr_el2 str x14, [x0, #CTX_VSESR_EL2] @@ -395,8 +397,10 @@ func el2_sysregs_context_restore ldr x13, [x0, #CTX_VDISR_EL2] msr vdisr_el2, x13 +#if CTX_INCLUDE_NEVE_REGS ldr x14, [x0, #CTX_VNCR_EL2] msr vncr_el2, x14 +#endif ldr x15, [x0, #CTX_VSESR_EL2] msr vsesr_el2, x15 diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index bc4982d64..578bd5987 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -62,6 +62,11 @@ CTX_INCLUDE_FPREGS := 0 # world. It is not needed to use it in the Non-secure world. CTX_INCLUDE_PAUTH_REGS := 0 +# Include Nested virtualization control (Armv8.4-NV) registers in cpu context. +# This must be set to 1 if architecture implements Nested Virtualization +# Extension and platform wants to use this feature in the Secure world +CTX_INCLUDE_NEVE_REGS := 0 + # Debug build DEBUG := 0 -- cgit v1.2.3 From 2b036b79950db23e3ce9a1a8d5f2f702a1206f5c Mon Sep 17 00:00:00 2001 From: Arunachalam Ganapathy Date: Fri, 9 Oct 2020 14:51:41 +0100 Subject: lib: el3_runtime: Fix SPE system registers in el2_sysregs_context Include EL2 registers related to SPE in EL2 context save/restore routines if architecture supports it and platform wants to use these features in Secure world. Change-Id: Ie01a2c38fa5f6c907276eddec120fdfb222561a6 Signed-off-by: Arunachalam Ganapathy --- lib/el3_runtime/aarch64/context.S | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S index c942c10ec..773082a85 100644 --- a/lib/el3_runtime/aarch64/context.S +++ b/lib/el3_runtime/aarch64/context.S @@ -94,8 +94,12 @@ func el2_sysregs_context_save stp x13, x14, [x0, #CTX_ICH_VMCR_EL2] mrs x15, mdcr_el2 +#if ENABLE_SPE_FOR_LOWER_ELS mrs x16, PMSCR_EL2 stp x15, x16, [x0, #CTX_MDCR_EL2] +#else + str x15, [x0, #CTX_MDCR_EL2] +#endif mrs x17, sctlr_el2 mrs x9, spsr_el2 @@ -291,9 +295,13 @@ func el2_sysregs_context_restore msr ICH_VMCR_EL2, x13 msr mair_el2, x14 +#if ENABLE_SPE_FOR_LOWER_ELS ldp x15, x16, [x0, #CTX_MDCR_EL2] - msr mdcr_el2, x15 msr PMSCR_EL2, x16 +#else + ldr x15, [x0, #CTX_MDCR_EL2] +#endif + msr mdcr_el2, x15 ldp x17, x9, [x0, #CTX_SCTLR_EL2] msr sctlr_el2, x17 -- cgit v1.2.3 From c398caf509096ca72f77a3e8f21489a4acc9763d Mon Sep 17 00:00:00 2001 From: Arunachalam Ganapathy Date: Thu, 28 May 2020 12:32:10 +0100 Subject: plat: tc0: Disable SPE Statistical Profiling Extension is not supported by Matterhorn core Change-Id: Iec652f1c6d6b6a9bf118ba682276a7c70a6abc0d Signed-off-by: Arunachalam Ganapathy --- plat/arm/board/tc0/platform.mk | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plat/arm/board/tc0/platform.mk b/plat/arm/board/tc0/platform.mk index 05d691ee2..4db081e70 100644 --- a/plat/arm/board/tc0/platform.mk +++ b/plat/arm/board/tc0/platform.mk @@ -98,6 +98,8 @@ override CTX_INCLUDE_AARCH32_REGS := 0 override CTX_INCLUDE_PAUTH_REGS := 1 +override ENABLE_SPE_FOR_LOWER_ELS := 0 + include plat/arm/common/arm_common.mk include plat/arm/css/common/css_common.mk include plat/arm/soc/common/soc_css.mk -- cgit v1.2.3 From d32113c7f3d291b35e0debdccac609c88a0343ae Mon Sep 17 00:00:00 2001 From: Arunachalam Ganapathy Date: Mon, 27 Jul 2020 13:51:30 +0100 Subject: plat: arm: Make BL32_BASE platform dependent when SPD_spmd is enabled To support platforms without Trusted DRAM this patch defines PLAT_ARM_SPMC_BASE and enables platform to use either Trusted DRAM or DRAM region behind TZC. Change-Id: Icaa5c7d33334258ff27e8e0bfd0812c304e68ae4 Signed-off-by: Arunachalam Ganapathy --- include/plat/arm/common/arm_def.h | 6 +++--- plat/arm/board/fvp/include/platform_def.h | 9 +++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index c01864306..00746c6da 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -497,9 +497,9 @@ # elif defined(SPD_spmd) # define TSP_SEC_MEM_BASE (ARM_AP_TZC_DRAM1_BASE + ULL(0x200000)) # define TSP_SEC_MEM_SIZE (ARM_AP_TZC_DRAM1_SIZE - ULL(0x200000)) -# define BL32_BASE PLAT_ARM_TRUSTED_DRAM_BASE -# define BL32_LIMIT (PLAT_ARM_TRUSTED_DRAM_BASE \ - + (UL(1) << 21)) +# define BL32_BASE PLAT_ARM_SPMC_BASE +# define BL32_LIMIT (PLAT_ARM_SPMC_BASE + \ + PLAT_ARM_SPMC_SIZE) # elif ARM_BL31_IN_DRAM # define TSP_SEC_MEM_BASE (ARM_AP_TZC_DRAM1_BASE + \ PLAT_ARM_MAX_BL31_SIZE) diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h index 50f638924..8defcf837 100644 --- a/plat/arm/board/fvp/include/platform_def.h +++ b/plat/arm/board/fvp/include/platform_def.h @@ -43,6 +43,15 @@ #define PLAT_ARM_TRUSTED_DRAM_BASE UL(0x06000000) #define PLAT_ARM_TRUSTED_DRAM_SIZE UL(0x02000000) /* 32 MB */ +/* + * Max size of SPMC is 2MB for fvp. With SPMD enabled this value corresponds to + * max size of BL32 image. + */ +#if defined(SPD_spmd) +#define PLAT_ARM_SPMC_BASE PLAT_ARM_TRUSTED_DRAM_BASE +#define PLAT_ARM_SPMC_SIZE UL(0x200000) /* 2 MB */ +#endif + /* virtual address used by dynamic mem_protect for chunk_base */ #define PLAT_ARM_MEM_PROTEC_VA_FRAME UL(0xc0000000) -- cgit v1.2.3 From a3ecbb3553564d8e560209fdde165c85129b3f70 Mon Sep 17 00:00:00 2001 From: Arunachalam Ganapathy Date: Tue, 22 Sep 2020 12:47:33 +0100 Subject: plat: tc0: Add TZC DRAM1 region for SPMC and trusted OS - Reserve 32MB below ARM_AP_TZC_DRAM1_BASE for TC0_TZC_DRAM1 - Add TC0_NS_DRAM1 base and mapping - Reserve memory region in tc0.dts Change-Id: If2431f7f68e4255e28c86a0e89637dab7c424a13 Signed-off-by: Arunachalam Ganapathy --- fdts/tc0.dts | 2 +- plat/arm/board/tc0/include/platform_def.h | 35 +++++++++++++++++++++++++++++++ plat/arm/board/tc0/tc0_plat.c | 2 +- 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/fdts/tc0.dts b/fdts/tc0.dts index 15c14cabd..763c813cf 100644 --- a/fdts/tc0.dts +++ b/fdts/tc0.dts @@ -106,7 +106,7 @@ memory@80000000 { device_type = "memory"; - reg = <0x0 0x80000000 0x0 0x80000000>; + reg = <0x0 0x80000000 0x0 0x7d000000>; }; psci { diff --git a/plat/arm/board/tc0/include/platform_def.h b/plat/arm/board/tc0/include/platform_def.h index 075c4037b..81b3944e5 100644 --- a/plat/arm/board/tc0/include/platform_def.h +++ b/plat/arm/board/tc0/include/platform_def.h @@ -21,6 +21,41 @@ #define PLAT_ARM_TRUSTED_SRAM_SIZE 0x00080000 /* 512 KB */ +/* + * The top 16MB of ARM_DRAM1 is configured as secure access only using the TZC, + * its base is ARM_AP_TZC_DRAM1_BASE. + * + * Reserve 32MB below ARM_AP_TZC_DRAM1_BASE for: + * - BL32_BASE when SPD_spmd is enabled + * - Region to load Trusted OS + */ +#define TC0_TZC_DRAM1_BASE (ARM_AP_TZC_DRAM1_BASE - \ + TC0_TZC_DRAM1_SIZE) +#define TC0_TZC_DRAM1_SIZE UL(0x02000000) /* 32 MB */ +#define TC0_TZC_DRAM1_END (TC0_TZC_DRAM1_BASE + \ + TC0_TZC_DRAM1_SIZE - 1) + +#define TC0_NS_DRAM1_BASE ARM_DRAM1_BASE +#define TC0_NS_DRAM1_SIZE (ARM_DRAM1_SIZE - \ + ARM_TZC_DRAM1_SIZE - \ + TC0_TZC_DRAM1_SIZE) +#define TC0_NS_DRAM1_END (TC0_NS_DRAM1_BASE + \ + TC0_NS_DRAM1_SIZE - 1) + +/* + * Mappings for TC0 DRAM1 (non-secure) and TC0 TZC DRAM1 (secure) + */ +#define TC0_MAP_NS_DRAM1 MAP_REGION_FLAT( \ + TC0_NS_DRAM1_BASE, \ + TC0_NS_DRAM1_SIZE, \ + MT_MEMORY | MT_RW | MT_NS) + + +#define TC0_MAP_TZC_DRAM1 MAP_REGION_FLAT( \ + TC0_TZC_DRAM1_BASE, \ + TC0_TZC_DRAM1_SIZE, \ + MT_MEMORY | MT_RW | MT_SECURE) + /* * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the * plat_arm_mmap array defined for each BL stage. diff --git a/plat/arm/board/tc0/tc0_plat.c b/plat/arm/board/tc0/tc0_plat.c index 05461928d..304666a01 100644 --- a/plat/arm/board/tc0/tc0_plat.c +++ b/plat/arm/board/tc0/tc0_plat.c @@ -38,7 +38,7 @@ const mmap_region_t plat_arm_mmap[] = { ARM_MAP_SHARED_RAM, TC0_FLASH0_RO, TC0_MAP_DEVICE, - ARM_MAP_NS_DRAM1, + TC0_MAP_NS_DRAM1, #if ARM_BL31_IN_DRAM ARM_MAP_BL31_SEC_DRAM, #endif -- cgit v1.2.3 From b0d127515a8f0694f884e4b1790cf57b0e1d91fe Mon Sep 17 00:00:00 2001 From: Arunachalam Ganapathy Date: Tue, 22 Sep 2020 12:50:45 +0100 Subject: plat: tc0: Enable SPMC execution at S-EL2 This patch enables SPMC execution at S-EL2 by adding below changes - Map TC0_MAP_TZC_DRAM1 for loading SPMC - Add details of cactus test secure partitions - Adds tc0 spmc manifest file with details on secure partitions - Inlcude TOS_FW_CONFIG when SPM is spmd - Increases bl2 image size SPMC at S-EL2 is only enabled when build with SPD=spmd. Change-Id: I4c5f70911903c232ee8ecca57f1e288d6b1cd647 Signed-off-by: Arunachalam Ganapathy --- plat/arm/board/tc0/fdts/tc0_fw_config.dts | 8 ++- plat/arm/board/tc0/fdts/tc0_spmc_manifest.dts | 93 +++++++++++++++++++++++++++ plat/arm/board/tc0/fdts/tc0_tb_fw_config.dts | 20 ++++++ plat/arm/board/tc0/include/platform_def.h | 13 +++- plat/arm/board/tc0/platform.mk | 8 +++ plat/arm/board/tc0/tc0_plat.c | 3 + 6 files changed, 143 insertions(+), 2 deletions(-) create mode 100644 plat/arm/board/tc0/fdts/tc0_spmc_manifest.dts diff --git a/plat/arm/board/tc0/fdts/tc0_fw_config.dts b/plat/arm/board/tc0/fdts/tc0_fw_config.dts index 381ce1fcb..4b6abd4d1 100644 --- a/plat/arm/board/tc0/fdts/tc0_fw_config.dts +++ b/plat/arm/board/tc0/fdts/tc0_fw_config.dts @@ -14,10 +14,16 @@ tb_fw-config { load-address = <0x0 0x4001300>; - max-size = <0x200>; + max-size = <0x400>; id = ; }; + tos_fw-config { + load-address = <0x0 0x04001700>; + max-size = <0x1000>; + id = ; + }; + hw-config { load-address = <0x0 0x83000000>; max-size = <0x01000000>; diff --git a/plat/arm/board/tc0/fdts/tc0_spmc_manifest.dts b/plat/arm/board/tc0/fdts/tc0_spmc_manifest.dts new file mode 100644 index 000000000..b6c543ade --- /dev/null +++ b/plat/arm/board/tc0/fdts/tc0_spmc_manifest.dts @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +/dts-v1/; + +/ { + compatible = "arm,ffa-core-manifest-1.0"; + #address-cells = <2>; + #size-cells = <1>; + + attribute { + spmc_id = <0x8000>; + maj_ver = <0x1>; + min_ver = <0x0>; + exec_state = <0x0>; + load_address = <0x0 0xfd000000>; + entrypoint = <0x0 0xfd000000>; + binary_size = <0x80000>; + }; + + chosen { + linux,initrd-start = <0>; + linux,initrd-end = <0>; + }; + + hypervisor { + compatible = "hafnium,hafnium"; + vm1 { + is_ffa_partition; + debug_name = "cactus-primary"; + load_address = <0xfe000000>; + }; + vm2 { + is_ffa_partition; + debug_name = "cactus-secondary"; + load_address = <0xfe100000>; + vcpu_count = <4>; + mem_size = <1048576>; + }; + vm3 { + is_ffa_partition; + debug_name = "cactus-tertiary"; + load_address = <0xfe200000>; + vcpu_count = <4>; + mem_size = <1048576>; + }; + }; + + cpus { + #address-cells = <0x2>; + #size-cells = <0x0>; + + CPU0:cpu@0 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x0>; + enable-method = "psci"; + }; + + /* + * SPM(Hafnium) requires secondary cpu nodes are declared in + * descending order + */ + CPU3:cpu@300 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x300>; + enable-method = "psci"; + }; + + CPU2:cpu@200 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x200>; + enable-method = "psci"; + }; + + CPU1:cpu@100 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x100>; + enable-method = "psci"; + }; + }; + + /* 32MB of TC0_TZC_DRAM1_BASE */ + memory@fd000000 { + device_type = "memory"; + reg = <0x0 0xfd000000 0x2000000>; + }; +}; diff --git a/plat/arm/board/tc0/fdts/tc0_tb_fw_config.dts b/plat/arm/board/tc0/fdts/tc0_tb_fw_config.dts index 2fd25d9b4..3df94bf92 100644 --- a/plat/arm/board/tc0/fdts/tc0_tb_fw_config.dts +++ b/plat/arm/board/tc0/fdts/tc0_tb_fw_config.dts @@ -24,4 +24,24 @@ mbedtls_heap_addr = <0x0 0x0>; mbedtls_heap_size = <0x0>; }; + + secure-partitions { + compatible = "arm,sp"; + cactus-primary { + uuid = <0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>; + load-address = <0xfe000000>; + owner = "SiP"; + }; + + cactus-secondary { + uuid = <0xd1582309 0xf02347b9 0x827c4464 0xf5578fc8>; + load-address = <0xfe100000>; + owner = "Plat"; + }; + + cactus-tertiary { + uuid = <0x79b55c73 0x1d8c44b9 0x859361e1 0x770ad8d2>; + load-address = <0xfe200000>; + }; + }; }; diff --git a/plat/arm/board/tc0/include/platform_def.h b/plat/arm/board/tc0/include/platform_def.h index 81b3944e5..dbec706fa 100644 --- a/plat/arm/board/tc0/include/platform_def.h +++ b/plat/arm/board/tc0/include/platform_def.h @@ -55,6 +55,14 @@ TC0_TZC_DRAM1_BASE, \ TC0_TZC_DRAM1_SIZE, \ MT_MEMORY | MT_RW | MT_SECURE) +/* + * Max size of SPMC is 2MB for tc0. With SPMD enabled this value corresponds to + * max size of BL32 image. + */ +#if defined(SPD_spmd) +#define PLAT_ARM_SPMC_BASE TC0_TZC_DRAM1_BASE +#define PLAT_ARM_SPMC_SIZE UL(0x200000) /* 2 MB */ +#endif /* * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the @@ -106,7 +114,7 @@ #if TRUSTED_BOARD_BOOT # define PLAT_ARM_MAX_BL2_SIZE 0x1E000 #else -# define PLAT_ARM_MAX_BL2_SIZE 0x11000 +# define PLAT_ARM_MAX_BL2_SIZE 0x14000 #endif /* @@ -241,4 +249,7 @@ #define PLAT_ARM_TZC_NS_DEV_ACCESS \ (TZC_REGION_ACCESS_RDWR(TZC_NSAID_DEFAULT)) +/* virtual address used by dynamic mem_protect for chunk_base */ +#define PLAT_ARM_MEM_PROTEC_VA_FRAME UL(0xc0000000) + #endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/tc0/platform.mk b/plat/arm/board/tc0/platform.mk index 4db081e70..5d2cc38c4 100644 --- a/plat/arm/board/tc0/platform.mk +++ b/plat/arm/board/tc0/platform.mk @@ -85,6 +85,14 @@ $(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG})) # Add the TB_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG})) +ifeq (${SPD},spmd) +FDT_SOURCES += ${TC0_BASE}/fdts/${PLAT}_spmc_manifest.dts +TC0_TOS_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_spmc_manifest.dtb + +# Add the TOS_FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${TC0_TOS_FW_CONFIG},--tos-fw-config,${TC0_TOS_FW_CONFIG})) +endif + #Device tree TC0_HW_CONFIG_DTS := fdts/tc0.dts TC0_HW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}.dtb diff --git a/plat/arm/board/tc0/tc0_plat.c b/plat/arm/board/tc0/tc0_plat.c index 304666a01..e12ad56d8 100644 --- a/plat/arm/board/tc0/tc0_plat.c +++ b/plat/arm/board/tc0/tc0_plat.c @@ -39,6 +39,9 @@ const mmap_region_t plat_arm_mmap[] = { TC0_FLASH0_RO, TC0_MAP_DEVICE, TC0_MAP_NS_DRAM1, +#if defined(SPD_spmd) + TC0_MAP_TZC_DRAM1, +#endif #if ARM_BL31_IN_DRAM ARM_MAP_BL31_SEC_DRAM, #endif -- cgit v1.2.3 From 879b5b8bcaf8c03940e571628838c8476cb69dca Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Wed, 26 Aug 2020 14:04:31 +0100 Subject: plat: tc0: Configure TZC with secure world regions This includes configuration for SPMC and trusted OS. Change-Id: Ie24df200f446b3f5b23f5f764b115c7191e6ada3 Signed-off-by: Usama Arif Signed-off-by: Arunachalam Ganapathy --- plat/arm/board/tc0/include/platform_def.h | 11 +++++++++++ plat/arm/board/tc0/tc0_security.c | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/plat/arm/board/tc0/include/platform_def.h b/plat/arm/board/tc0/include/platform_def.h index dbec706fa..72a035f0a 100644 --- a/plat/arm/board/tc0/include/platform_def.h +++ b/plat/arm/board/tc0/include/platform_def.h @@ -249,6 +249,17 @@ #define PLAT_ARM_TZC_NS_DEV_ACCESS \ (TZC_REGION_ACCESS_RDWR(TZC_NSAID_DEFAULT)) +/* + * The first region below, TC0_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. + */ +#define TC0_TZC_REGIONS_DEF \ + {TC0_TZC_DRAM1_BASE, ARM_SCP_TZC_DRAM1_END, \ + TZC_REGION_S_RDWR, PLAT_ARM_TZC_NS_DEV_ACCESS}, \ + {TC0_NS_DRAM1_BASE, TC0_NS_DRAM1_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) diff --git a/plat/arm/board/tc0/tc0_security.c b/plat/arm/board/tc0/tc0_security.c index 5f1cb1159..f54376203 100644 --- a/plat/arm/board/tc0/tc0_security.c +++ b/plat/arm/board/tc0/tc0_security.c @@ -8,7 +8,7 @@ #include static const arm_tzc_regions_info_t tzc_regions[] = { - ARM_TZC_REGIONS_DEF, + TC0_TZC_REGIONS_DEF, {} }; -- cgit v1.2.3 From bea8019826f97546e18265d3d7b8e54dfa7da250 Mon Sep 17 00:00:00 2001 From: Jimmy Brisson Date: Fri, 24 Jul 2020 14:31:48 -0500 Subject: Free X509_EXTENSIONs Previously, we would leak these extensions as they are not freed by the stack. An except from the `sk_TYPE_free` documentation: sk_TYPE_free() frees up the sk structure. It does not free up any elements of sk. After this call sk is no longer valid. The fix is to drain the stack and free its elements before freeing the stack. sk_TYPE_pop_free does this, so we use that instead. Change-Id: Ie70c302f9dda5af1a7243f163d36e99916ee639c Signed-off-by: Jimmy Brisson --- tools/cert_create/src/main.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/cert_create/src/main.c b/tools/cert_create/src/main.c index 2ba110132..368493a88 100644 --- a/tools/cert_create/src/main.c +++ b/tools/cert_create/src/main.c @@ -539,6 +539,11 @@ int main(int argc, char *argv[]) exit(1); } + for (cert_ext = sk_X509_EXTENSION_pop(sk); cert_ext != NULL; + cert_ext = sk_X509_EXTENSION_pop(sk)) { + X509_EXTENSION_free(cert_ext); + } + sk_X509_EXTENSION_free(sk); } -- cgit v1.2.3 From 1f111f12b5ecc69670653763512e557f59f88ef9 Mon Sep 17 00:00:00 2001 From: Jimmy Brisson Date: Mon, 27 Jul 2020 10:43:40 -0500 Subject: Free keys after use Change-Id: I16ba4420ffeb9aa439e0a09a1b34d2aba2e1eb6e Signed-off-by: Jimmy Brisson --- tools/cert_create/src/main.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tools/cert_create/src/main.c b/tools/cert_create/src/main.c index 368493a88..31978a995 100644 --- a/tools/cert_create/src/main.c +++ b/tools/cert_create/src/main.c @@ -581,6 +581,13 @@ int main(int argc, char *argv[]) } } + /* If we got here, then we must have filled the key array completely. + * We can then safely call free on all of the keys in the array + */ + for (i = 0; i < num_keys; i++) { + EVP_PKEY_free(keys[i].key); + } + #ifndef OPENSSL_NO_ENGINE ENGINE_cleanup(); #endif -- cgit v1.2.3 From 4a34d18f35b76f1df282b1a077ad749d13c1d19d Mon Sep 17 00:00:00 2001 From: Jimmy Brisson Date: Mon, 27 Jul 2020 11:23:20 -0500 Subject: Free arguments copied with strdup Change-Id: I0ad9620145c2a9c4450b9bf20cd1f70c9db6593c Signed-off-by: Jimmy Brisson --- tools/cert_create/src/main.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tools/cert_create/src/main.c b/tools/cert_create/src/main.c index 31978a995..d5abe4917 100644 --- a/tools/cert_create/src/main.c +++ b/tools/cert_create/src/main.c @@ -593,5 +593,32 @@ int main(int argc, char *argv[]) #endif CRYPTO_cleanup_all_ex_data(); + + /* We allocated strings through strdup, so now we have to free them */ + for (i = 0; i < num_keys; i++) { + if (keys[i].fn != NULL) { + void *ptr = keys[i].fn; + + keys[i].fn = NULL; + free(ptr); + } + } + for (i = 0; i < num_extensions; i++) { + if (extensions[i].arg != NULL) { + void *ptr = (void *)extensions[i].arg; + + extensions[i].arg = NULL; + free(ptr); + } + } + for (i = 0; i < num_certs; i++) { + if (certs[i].fn != NULL) { + void *ptr = (void *)certs[i].fn; + + certs[i].fn = NULL; + free(ptr); + } + } + return 0; } -- cgit v1.2.3 From bcad20308fbaad350ad0486d7cb36ae23b44a18b Mon Sep 17 00:00:00 2001 From: Jimmy Brisson Date: Mon, 27 Jul 2020 13:22:42 -0500 Subject: Use preallocated parts of the HASH struct When OpenSSL's macro allocates the HASH struct, it allocates the fields as well. After this allocation, the prior code would assign over the pointers inside the HASH struct, leaking these fields. This patch avoids allocating extra copies of these members. Change-Id: I50a38b0a04b52ec54d6388db0f694feb578d2818 Signed-off-by: Jimmy Brisson --- tools/cert_create/src/ext.c | 37 +++++++++++-------------------------- 1 file changed, 11 insertions(+), 26 deletions(-) diff --git a/tools/cert_create/src/ext.c b/tools/cert_create/src/ext.c index d9a92bb10..65dd3e583 100644 --- a/tools/cert_create/src/ext.c +++ b/tools/cert_create/src/ext.c @@ -158,51 +158,36 @@ X509_EXTENSION *ext_new_hash(int nid, int crit, const EVP_MD *md, unsigned char *buf, size_t len) { X509_EXTENSION *ex; - ASN1_OCTET_STRING *octet; HASH *hash; ASN1_OBJECT *algorithm; - X509_ALGOR *x509_algor; unsigned char *p = NULL; int sz; + /* HASH structure containing algorithm + hash */ + hash = HASH_new(); + if (hash == NULL) { + return NULL; + } + /* OBJECT_IDENTIFIER with hash algorithm */ algorithm = OBJ_nid2obj(EVP_MD_type(md)); if (algorithm == NULL) { + HASH_free(hash); return NULL; } /* Create X509_ALGOR */ - x509_algor = X509_ALGOR_new(); - if (x509_algor == NULL) { - return NULL; - } - x509_algor->algorithm = algorithm; - x509_algor->parameter = ASN1_TYPE_new(); - ASN1_TYPE_set(x509_algor->parameter, V_ASN1_NULL, NULL); + hash->hashAlgorithm->algorithm = algorithm; + hash->hashAlgorithm->parameter = ASN1_TYPE_new(); + ASN1_TYPE_set(hash->hashAlgorithm->parameter, V_ASN1_NULL, NULL); /* OCTET_STRING with the actual hash */ - octet = ASN1_OCTET_STRING_new(); - if (octet == NULL) { - X509_ALGOR_free(x509_algor); - return NULL; - } - ASN1_OCTET_STRING_set(octet, buf, len); - - /* HASH structure containing algorithm + hash */ - hash = HASH_new(); - if (hash == NULL) { - ASN1_OCTET_STRING_free(octet); - X509_ALGOR_free(x509_algor); - return NULL; - } - hash->hashAlgorithm = x509_algor; - hash->dataHash = octet; + ASN1_OCTET_STRING_set(hash->dataHash, buf, len); /* DER encoded HASH */ sz = i2d_HASH(hash, &p); if ((sz <= 0) || (p == NULL)) { HASH_free(hash); - X509_ALGOR_free(x509_algor); return NULL; } -- cgit v1.2.3 From 774ba5a23df64db75476391622142afae0976399 Mon Sep 17 00:00:00 2001 From: Fengquan Chen Date: Mon, 12 Oct 2020 16:33:25 +0800 Subject: mediatek: mt8183: add timer V20 compensation add timer driver. Signed-off-by: Fengquan Chen Change-Id: I60a7273f922233a618a6163b802c0858ed89f75f --- plat/mediatek/mt8183/bl31_plat_setup.c | 3 +++ plat/mediatek/mt8183/drivers/timer/mt_timer.c | 29 +++++++++++++++++++++++++++ plat/mediatek/mt8183/drivers/timer/mt_timer.h | 20 ++++++++++++++++++ plat/mediatek/mt8183/platform.mk | 2 ++ 4 files changed, 54 insertions(+) create mode 100644 plat/mediatek/mt8183/drivers/timer/mt_timer.c create mode 100644 plat/mediatek/mt8183/drivers/timer/mt_timer.h diff --git a/plat/mediatek/mt8183/bl31_plat_setup.c b/plat/mediatek/mt8183/bl31_plat_setup.c index e96b4ad0c..7dac8a49b 100644 --- a/plat/mediatek/mt8183/bl31_plat_setup.c +++ b/plat/mediatek/mt8183/bl31_plat_setup.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -148,6 +149,8 @@ void bl31_platform_setup(void) mt_gic_driver_init(); mt_gic_init(); + mt_systimer_init(); + /* Init mcsi SF */ plat_mtk_cci_init_sf(); diff --git a/plat/mediatek/mt8183/drivers/timer/mt_timer.c b/plat/mediatek/mt8183/drivers/timer/mt_timer.c new file mode 100644 index 000000000..0da4815b1 --- /dev/null +++ b/plat/mediatek/mt8183/drivers/timer/mt_timer.c @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include +#include +#include +#include +#include +#include + +static void enable_systimer_compensation(void) +{ + unsigned int reg; + + reg = mmio_read_32(CNTCR_REG); + reg &= ~COMP_15_EN; + reg |= COMP_20_EN; + mmio_write_32(CNTCR_REG, reg); + + NOTICE("[systimer] CNTCR_REG(0x%x)\n", mmio_read_32(CNTCR_REG)); +} + +void mt_systimer_init(void) +{ + /* systimer is default on, so we only enable systimer compensation */ + enable_systimer_compensation(); +} diff --git a/plat/mediatek/mt8183/drivers/timer/mt_timer.h b/plat/mediatek/mt8183/drivers/timer/mt_timer.h new file mode 100644 index 000000000..0b8edc517 --- /dev/null +++ b/plat/mediatek/mt8183/drivers/timer/mt_timer.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MT_TIMER_H +#define MT_TIMER_H + + +#define SYSTIMER_BASE (0x10017000) +#define CNTCR_REG (SYSTIMER_BASE + 0x0) +#define CNTSR_REG (SYSTIMER_BASE + 0x4) + +#define COMP_15_EN (1 << 10) +#define COMP_20_EN (1 << 11) + +void mt_systimer_init(void); + +#endif /* MT_TIMER_H */ diff --git a/plat/mediatek/mt8183/platform.mk b/plat/mediatek/mt8183/platform.mk index 3ccc928ac..f290a4e6d 100644 --- a/plat/mediatek/mt8183/platform.mk +++ b/plat/mediatek/mt8183/platform.mk @@ -14,6 +14,7 @@ PLAT_INCLUDES := -I${MTK_PLAT}/common/ \ -I${MTK_PLAT_SOC}/drivers/mcdi/ \ -I${MTK_PLAT_SOC}/drivers/spmc/ \ -I${MTK_PLAT_SOC}/drivers/gpio/ \ + -I${MTK_PLAT_SOC}/drivers/timer/ \ -I${MTK_PLAT_SOC}/drivers/pmic/ \ -I${MTK_PLAT_SOC}/drivers/spm/ \ -I${MTK_PLAT_SOC}/drivers/sspm/ \ @@ -58,6 +59,7 @@ BL31_SOURCES += common/desc_image_load.c \ ${MTK_PLAT_SOC}/drivers/spm/spm_suspend.c \ ${MTK_PLAT_SOC}/drivers/gpio/mtgpio.c \ ${MTK_PLAT_SOC}/drivers/uart/uart.c \ + ${MTK_PLAT_SOC}/drivers/timer/mt_timer.c \ ${MTK_PLAT_SOC}/drivers/emi_mpu/emi_mpu.c \ ${MTK_PLAT_SOC}/plat_pm.c \ ${MTK_PLAT_SOC}/plat_topology.c \ -- cgit v1.2.3 From b5e3d54017b3f48033960d392aa98ba053adfd97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Wed, 21 Oct 2020 11:50:40 +0200 Subject: plat: marvell: armada: Building ${DOIMAGETOOL} is only for a8k MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently a3k target is misusing ${DOIMAGETOOL} target for building flash and UART images. It is not used for building image tool. So move ${DOIMAGETOOL} target from common marvell include file into a8k include file and add correct invocation of ${MAKE} into a3k for building flash and UART images. Part of this change is also checks that MV_DDR_PATH for a3k was specified by user as this option is required for building a3k flash and UART images. Signed-off-by: Pali Rohár Change-Id: I5ae9d08b8505460933f17836c9b6435fd6e51bb6 --- plat/marvell/armada/a3k/common/a3700_common.mk | 2 ++ plat/marvell/armada/a8k/common/a8k_common.mk | 38 ++++++++++++++++++++++++-- plat/marvell/marvell.mk | 37 ------------------------- 3 files changed, 38 insertions(+), 39 deletions(-) diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk index 8f65e92b3..2050d59b6 100644 --- a/plat/marvell/armada/a3k/common/a3700_common.mk +++ b/plat/marvell/armada/a3k/common/a3700_common.mk @@ -124,6 +124,8 @@ mrvl_flash: ${BUILD_PLAT}/${FIP_NAME} ${DOIMAGETOOL} $(shell truncate -s %128K ${BUILD_PLAT}/bl1.bin) $(shell cat ${BUILD_PLAT}/bl1.bin ${BUILD_PLAT}/${FIP_NAME} > ${BUILD_PLAT}/${BOOT_IMAGE}) $(shell truncate -s %4 ${BUILD_PLAT}/${BOOT_IMAGE}) + $(if $(value MV_DDR_PATH),,$(error "Platform '${PLAT}' for target '$@' requires MV_DDR_PATH. Please set MV_DDR_PATH to point to the right directory")) + ${Q}${MAKE} --no-print-directory -C ${DOIMAGEPATH} WTMI_IMG=$(WTMI_IMG) MV_DDR_PATH=$(MV_DDR_PATH) $(shell truncate -s %4 $(WTMI_IMG)) @echo @echo "Building uart images" diff --git a/plat/marvell/armada/a8k/common/a8k_common.mk b/plat/marvell/armada/a8k/common/a8k_common.mk index a807891e5..c8273265e 100644 --- a/plat/marvell/armada/a8k/common/a8k_common.mk +++ b/plat/marvell/armada/a8k/common/a8k_common.mk @@ -4,8 +4,6 @@ # SPDX-License-Identifier: BSD-3-Clause # https://spdx.org/licenses -include tools/marvell/doimage/doimage.mk - PLAT_FAMILY := a8k PLAT_INCLUDE_BASE := include/plat/marvell/armada/$(PLAT_FAMILY) PLAT_COMMON_BASE := plat/marvell/armada/a8k/common @@ -34,6 +32,34 @@ DOIMAGEPATH ?= tools/marvell/doimage DOIMAGETOOL ?= ${DOIMAGEPATH}/doimage include plat/marvell/marvell.mk +include tools/marvell/doimage/doimage.mk + +ifeq (${MARVELL_SECURE_BOOT},1) +DOIMAGE_SEC_FLAGS := -c $(DOIMAGE_SEC) +DOIMAGE_LIBS_CHECK = \ + if ! [ -d "/usr/include/mbedtls" ]; then \ + echo "****************************************" >&2; \ + echo "Missing mbedTLS installation! " >&2; \ + echo "Please download it from \"tls.mbed.org\"" >&2; \ + echo "Alternatively on Debian/Ubuntu system install" >&2; \ + echo "\"libmbedtls-dev\" package" >&2; \ + echo "Make sure to use version 2.1.0 or later" >&2; \ + echo "****************************************" >&2; \ + exit 1; \ + else if ! [ -f "/usr/include/libconfig.h" ]; then \ + echo "********************************************************" >&2; \ + echo "Missing Libconfig installation!" >&2; \ + echo "Please download it from \"www.hyperrealm.com/libconfig/\"" >&2; \ + echo "Alternatively on Debian/Ubuntu system install packages" >&2; \ + echo "\"libconfig8\" and \"libconfig8-dev\"" >&2; \ + echo "********************************************************" >&2; \ + exit 1; \ + fi \ + fi +else #MARVELL_SECURE_BOOT +DOIMAGE_LIBS_CHECK = +DOIMAGE_SEC_FLAGS = +endif #MARVELL_SECURE_BOOT ROM_BIN_EXT ?= $(BUILD_PLAT)/ble.bin DOIMAGE_FLAGS += -b $(ROM_BIN_EXT) $(NAND_DOIMAGE_FLAGS) $(DOIMAGE_SEC_FLAGS) @@ -126,6 +152,14 @@ BLE_PATH ?= $(PLAT_COMMON_BASE)/ble include ${BLE_PATH}/ble.mk $(eval $(call MAKE_BL,e)) +mrvl_clean: + @echo " Doimage CLEAN" + ${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${DOIMAGEPATH} clean + +${DOIMAGETOOL}: mrvl_clean + @$(DOIMAGE_LIBS_CHECK) + ${Q}${MAKE} --no-print-directory -C ${DOIMAGEPATH} + mrvl_flash: ${BUILD_PLAT}/${FIP_NAME} ${DOIMAGETOOL} ${BUILD_PLAT}/ble.bin $(shell truncate -s %128K ${BUILD_PLAT}/bl1.bin) $(shell cat ${BUILD_PLAT}/bl1.bin ${BUILD_PLAT}/${FIP_NAME} > ${BUILD_PLAT}/${BOOT_IMAGE}) diff --git a/plat/marvell/marvell.mk b/plat/marvell/marvell.mk index 82457536d..b6a2b9995 100644 --- a/plat/marvell/marvell.mk +++ b/plat/marvell/marvell.mk @@ -19,40 +19,3 @@ $(eval $(call add_define,PALLADIUM)) # Set board to work with DDR 32bit DDR32 := 0 $(eval $(call add_define,DDR32)) - -ifeq (${MARVELL_SECURE_BOOT},1) -DOIMAGE_SEC_FLAGS := -c $(DOIMAGE_SEC) -DOIMAGE_LIBS_CHECK = \ - if ! [ -d "/usr/include/mbedtls" ]; then \ - echo "****************************************" >&2; \ - echo "Missing mbedTLS installation! " >&2; \ - echo "Please download it from \"tls.mbed.org\"" >&2; \ - echo "Alternatively on Debian/Ubuntu system install" >&2; \ - echo "\"libmbedtls-dev\" package" >&2; \ - echo "Make sure to use version 2.1.0 or later" >&2; \ - echo "****************************************" >&2; \ - exit 1; \ - else if ! [ -f "/usr/include/libconfig.h" ]; then \ - echo "********************************************************" >&2; \ - echo "Missing Libconfig installation!" >&2; \ - echo "Please download it from \"www.hyperrealm.com/libconfig/\"" >&2; \ - echo "Alternatively on Debian/Ubuntu system install packages" >&2; \ - echo "\"libconfig8\" and \"libconfig8-dev\"" >&2; \ - echo "********************************************************" >&2; \ - exit 1; \ - fi \ - fi -else #MARVELL_SECURE_BOOT -DOIMAGE_LIBS_CHECK = -DOIMAGE_SEC_FLAGS = -endif #MARVELL_SECURE_BOOT - -mrvl_clean: - @echo " Doimage CLEAN" - ${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${DOIMAGEPATH} clean - -${DOIMAGETOOL}: mrvl_clean - @$(DOIMAGE_LIBS_CHECK) - ${Q}${MAKE} --no-print-directory -C ${DOIMAGEPATH} VERSION=$(SUBVERSION) WTMI_IMG=$(WTMI_IMG) - - -- cgit v1.2.3 From d1ff30d7a71a4e06919b299aae6130c27d11d754 Mon Sep 17 00:00:00 2001 From: Tomas Pilar Date: Tue, 11 Aug 2020 15:06:16 +0100 Subject: plat/qemu_sbsa: Remove cortex_a53 and aem_generic The qemu_sbsa platform uses 42bit address size but the cortex-a53 only supports 40bit addressing, the cpu is incompatible with the platform. The aem_generic is also not used with qemu_sbsa, in fact, the platform currently only properly supports the cortex-a57 cpu. Change-Id: I91c92533116f1c3451d01ca99824e91d3d58df14 Signed-off-by: Tomas Pilar --- plat/qemu/qemu_sbsa/platform.mk | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/plat/qemu/qemu_sbsa/platform.mk b/plat/qemu/qemu_sbsa/platform.mk index 3aa7cbe5a..9be56a392 100644 --- a/plat/qemu/qemu_sbsa/platform.mk +++ b/plat/qemu/qemu_sbsa/platform.mk @@ -47,9 +47,7 @@ BL1_SOURCES += drivers/io/io_semihosting.c \ ${PLAT_QEMU_COMMON_PATH}/${ARCH}/plat_helpers.S \ ${PLAT_QEMU_COMMON_PATH}/qemu_bl1_setup.c -BL1_SOURCES += lib/cpus/aarch64/aem_generic.S \ - lib/cpus/aarch64/cortex_a53.S \ - lib/cpus/aarch64/cortex_a57.S +BL1_SOURCES += lib/cpus/aarch64/cortex_a57.S BL2_SOURCES += drivers/io/io_semihosting.c \ drivers/io/io_storage.c \ @@ -75,9 +73,7 @@ QEMU_GIC_SOURCES := ${GICV3_SOURCES} \ plat/common/plat_gicv3.c \ ${PLAT_QEMU_COMMON_PATH}/qemu_gicv3.c -BL31_SOURCES += lib/cpus/aarch64/aem_generic.S \ - lib/cpus/aarch64/cortex_a53.S \ - lib/cpus/aarch64/cortex_a57.S \ +BL31_SOURCES += lib/cpus/aarch64/cortex_a57.S \ lib/semihosting/semihosting.c \ lib/semihosting/${ARCH}/semihosting_call.S \ plat/common/plat_psci_common.c \ -- cgit v1.2.3 From d0d63afeb440c4ccc8a5685130f1b8de1536eec2 Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Thu, 8 Oct 2020 08:38:58 +0200 Subject: SPMC: adjust device region for first secure partition For the first partition, mark first 2GB as device memory excluding the Trusted DRAM region reserved for the SPMC. Signed-off-by: Olivier Deprez Change-Id: I3ff110b3facf5b6d41ac2519ff6ca5e30a0a502b --- plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts | 20 ++++++++++++++------ .../board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts | 9 +++++++-- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts index 934a01afc..8b9c281e2 100644 --- a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts +++ b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts @@ -5,13 +5,12 @@ */ /dts-v1/; -#define AFF 00 +#define AFF 00 #include "fvp-defs.dtsi" #undef POST -#define POST \ - enable-method = "psci"; \ - }; +#define POST \ + }; / { compatible = "arm,ffa-core-manifest-1.0"; @@ -61,7 +60,11 @@ #size-cells = <0x0>; CPU_0 - /* SPM(Hafnium) requires secondary cpu nodes are declared in descending order */ + + /* + * SPMC (Hafnium) requires secondary core nodes are declared + * in descending order. + */ CPU_7 CPU_6 CPU_5 @@ -71,7 +74,12 @@ CPU_1 }; - memory@60000000 { + device-memory@0 { + device_type = "device-memory"; + reg = <0x0 0x0 0x6000000 0x0 0x8000000 0x78000000>; + }; + + memory@6000000 { device_type = "memory"; reg = <0x0 0x6000000 0x2000000>; /* Trusted DRAM */ }; diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts index f5b31b43c..266adfc2b 100644 --- a/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts +++ b/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts @@ -49,7 +49,7 @@ CPU_0 /* - * SPMC(Hafnium) requires secondary core nodes are declared + * SPMC (Hafnium) requires secondary core nodes are declared * in descending order. */ CPU_7 @@ -61,7 +61,12 @@ CPU_1 }; - memory@60000000 { + device-memory@0 { + device_type = "device-memory"; + reg = <0x0 0x0 0x6000000 0x0 0x8000000 0x78000000>; + }; + + memory@6000000 { device_type = "memory"; reg = <0x0 0x6000000 0x2000000>; /* Trusted DRAM */ }; -- cgit v1.2.3 From f8e6a09c64b59eebb1de712ccb7d3203b0184ad6 Mon Sep 17 00:00:00 2001 From: "Abdul Halim, Muhammad Hadi Asyrafi" Date: Thu, 14 May 2020 15:32:43 +0800 Subject: intel: common: Improve mailbox driver readability Use pre-defined macros for return values and common mailbox arguments Signed-off-by: Abdul Halim, Muhammad Hadi Asyrafi Change-Id: I5d549ee5358aebadf909f79fda55e83ee9844a0e --- plat/intel/soc/common/include/socfpga_mailbox.h | 5 ++- plat/intel/soc/common/soc/socfpga_mailbox.c | 59 +++++++++++++------------ plat/intel/soc/common/socfpga_sip_svc.c | 18 ++++---- 3 files changed, 42 insertions(+), 40 deletions(-) diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h index b250b3e90..f44bc0ecc 100644 --- a/plat/intel/soc/common/include/socfpga_mailbox.h +++ b/plat/intel/soc/common/include/socfpga_mailbox.h @@ -64,6 +64,7 @@ /* Mailbox Definitions */ #define CMD_DIRECT 0 +#define CMD_INDIRECT 1 #define CMD_CASUAL 0 #define CMD_URGENT 1 @@ -123,7 +124,7 @@ #define MBOX_CLIENT_ID_CMD(CLIENT_ID) ((CLIENT_ID) << 28) #define MBOX_JOB_ID_CMD(JOB_ID) (JOB_ID<<24) #define MBOX_CMD_LEN_CMD(CMD_LEN) ((CMD_LEN) << 12) -#define MBOX_INDIRECT (1 << 11) +#define MBOX_INDIRECT(val) ((val) << 11) /* RSU Macros */ #define RSU_VERSION_ACMF BIT(8) @@ -140,7 +141,7 @@ void mailbox_set_qspi_direct(void); int mailbox_send_cmd(int job_id, unsigned int cmd, uint32_t *args, int len, int urgent, uint32_t *response, int resp_len); int mailbox_send_cmd_async(int job_id, unsigned int cmd, uint32_t *args, - int len, int urgent); + int len, int urgent, int indirect); int mailbox_read_response(int job_id, uint32_t *response, int resp_len); void mailbox_reset_cold(void); void mailbox_clear_response(void); diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c index d066f27b5..cbc6bfba3 100644 --- a/plat/intel/soc/common/soc/socfpga_mailbox.c +++ b/plat/intel/soc/common/soc/socfpga_mailbox.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Intel Corporation. All rights reserved. + * Copyright (c) 2020, Intel Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -32,7 +32,7 @@ static int fill_mailbox_circular_buffer(uint32_t header_cmd, uint32_t *args, cmd_free_offset %= MBOX_CMD_BUFFER_SIZE; mmio_write_32(MBOX_OFFSET + MBOX_CIN, cmd_free_offset); - return 0; + return MBOX_RET_OK; } int mailbox_read_response(int job_id, uint32_t *response, int resp_len) @@ -120,12 +120,12 @@ int mailbox_poll_response(int job_id, int urgent, uint32_t *response, MBOX_STATUS_UA_MASK) ^ (urgent & MBOX_STATUS_UA_MASK)) { mmio_write_32(MBOX_OFFSET + MBOX_URG, 0); - return 0; + return MBOX_RET_OK; } mmio_write_32(MBOX_OFFSET + MBOX_URG, 0); INFO("Error: Mailbox did not get UA"); - return -1; + return MBOX_RET_ERROR; } rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN); @@ -168,7 +168,7 @@ int mailbox_poll_response(int job_id, int urgent, uint32_t *response, } int mailbox_send_cmd_async(int job_id, unsigned int cmd, uint32_t *args, - int len, int urgent) + int len, int urgent, int indirect) { if (urgent) mmio_write_32(MBOX_OFFSET + MBOX_URG, 1); @@ -176,12 +176,12 @@ int mailbox_send_cmd_async(int job_id, unsigned int cmd, uint32_t *args, fill_mailbox_circular_buffer(MBOX_CLIENT_ID_CMD(MBOX_ATF_CLIENT_ID) | MBOX_JOB_ID_CMD(job_id) | MBOX_CMD_LEN_CMD(len) | - MBOX_INDIRECT | + MBOX_INDIRECT(indirect) | cmd, args, len); mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1); - return 0; + return MBOX_RET_OK; } int mailbox_send_cmd(int job_id, unsigned int cmd, uint32_t *args, @@ -229,25 +229,21 @@ void mailbox_set_int(int interrupt) void mailbox_set_qspi_open(void) { mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE); - mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_OPEN, 0, 0, 0, NULL, 0); + mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_OPEN, NULL, 0, + CMD_CASUAL, NULL, 0); } void mailbox_set_qspi_direct(void) { - mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_DIRECT, 0, 0, 0, NULL, 0); + mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_DIRECT, NULL, 0, + CMD_CASUAL, NULL, 0); } void mailbox_set_qspi_close(void) { mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE); - mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_CLOSE, 0, 0, 0, NULL, 0); -} - -int mailbox_get_qspi_clock(void) -{ - mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE); - return mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_DIRECT, 0, 0, 0, - NULL, 0); + mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_CLOSE, NULL, 0, + CMD_CASUAL, NULL, 0); } void mailbox_qspi_set_cs(int device_select) @@ -258,19 +254,20 @@ void mailbox_qspi_set_cs(int device_select) cs_setting = (cs_setting << 28); mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE); mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_SET_CS, &cs_setting, - 1, 0, NULL, 0); + 1, CMD_CASUAL, NULL, 0); } void mailbox_reset_cold(void) { mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE); - mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_REBOOT_HPS, 0, 0, 0, NULL, 0); + mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_REBOOT_HPS, NULL, 0, + CMD_CASUAL, NULL, 0); } int mailbox_rsu_get_spt_offset(uint32_t *resp_buf, uint32_t resp_buf_len) { return mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_SUBPARTITION_TABLE, - NULL, 0, 0, (uint32_t *)resp_buf, + NULL, 0, CMD_CASUAL, (uint32_t *)resp_buf, resp_buf_len); } @@ -291,8 +288,9 @@ int mailbox_rsu_status(uint32_t *resp_buf, uint32_t resp_buf_len) info->retry_counter = ~0; - ret = mailbox_send_cmd(MBOX_JOB_ID, MBOX_RSU_STATUS, NULL, 0, 0, - (uint32_t *)resp_buf, resp_buf_len); + ret = mailbox_send_cmd(MBOX_JOB_ID, MBOX_RSU_STATUS, NULL, 0, + CMD_CASUAL, (uint32_t *)resp_buf, + resp_buf_len); if (ret < 0) return ret; @@ -307,13 +305,15 @@ int mailbox_rsu_status(uint32_t *resp_buf, uint32_t resp_buf_len) int mailbox_rsu_update(uint32_t *flash_offset) { return mailbox_send_cmd(MBOX_JOB_ID, MBOX_RSU_UPDATE, - flash_offset, 2, 0, NULL, 0); + flash_offset, 2, + CMD_CASUAL, NULL, 0); } int mailbox_hps_stage_notify(uint32_t execution_stage) { return mailbox_send_cmd(MBOX_JOB_ID, MBOX_HPS_STAGE_NOTIFY, - &execution_stage, 1, 0, NULL, 0); + &execution_stage, 1, CMD_CASUAL, + NULL, 0); } int mailbox_init(void) @@ -325,7 +325,8 @@ int mailbox_init(void) mmio_write_32(MBOX_OFFSET + MBOX_URG, 0); mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0); - status = mailbox_send_cmd(0, MBOX_CMD_RESTART, 0, 0, 1, NULL, 0); + status = mailbox_send_cmd(0, MBOX_CMD_RESTART, NULL, 0, + CMD_URGENT, NULL, 0); if (status) return status; @@ -333,7 +334,7 @@ int mailbox_init(void) mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE | MBOX_INT_FLAG_UAE); - return 0; + return MBOX_RET_OK; } int intel_mailbox_get_config_status(uint32_t cmd) @@ -341,8 +342,8 @@ int intel_mailbox_get_config_status(uint32_t cmd) int status; uint32_t res, response[6]; - status = mailbox_send_cmd(1, cmd, NULL, 0, 0, response, - sizeof(response) / sizeof(response[0])); + status = mailbox_send_cmd(MBOX_JOB_ID, cmd, NULL, 0, CMD_CASUAL, response, + ARRAY_SIZE(response)); if (status < 0) return status; @@ -361,7 +362,7 @@ int intel_mailbox_get_config_status(uint32_t cmd) if ((res & SOFTFUNC_STATUS_CONF_DONE) && (res & SOFTFUNC_STATUS_INIT_DONE)) - return 0; + return MBOX_RET_OK; return MBOX_CFGSTAT_STATE_CONFIG; } diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c index a20baab4c..b879cfc3b 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -74,10 +74,9 @@ static int intel_fpga_sdm_write_buffer(struct fpga_config_info *buffer) args[2] = bytes_per_block; buffer->size_written += args[2]; - mailbox_send_cmd_async( - send_id++ % MBOX_MAX_JOB_ID, - MBOX_RECONFIG_DATA, - args, 3, 0); + mailbox_send_cmd_async(send_id++ % MBOX_MAX_JOB_ID, + MBOX_RECONFIG_DATA, args, 3, + CMD_CASUAL, CMD_INDIRECT); buffer->subblocks_sent++; max_blocks--; @@ -154,7 +153,7 @@ static int intel_fpga_config_completed_write(uint32_t *completed_addr, while (*count < 3) { resp_len = mailbox_read_response(rcv_id % MBOX_MAX_JOB_ID, - resp, sizeof(resp) / sizeof(resp[0])); + resp, ARRAY_SIZE(resp)); if (resp_len < 0) break; @@ -208,10 +207,10 @@ static int intel_fpga_config_start(uint32_t config_type) mailbox_clear_response(); - mailbox_send_cmd(1, MBOX_CMD_CANCEL, 0, 0, 0, NULL, 0); + mailbox_send_cmd(1, MBOX_CMD_CANCEL, NULL, 0, CMD_CASUAL, NULL, 0); - status = mailbox_send_cmd(1, MBOX_RECONFIG, 0, 0, 0, - response, sizeof(response) / sizeof(response[0])); + status = mailbox_send_cmd(1, MBOX_RECONFIG, NULL, 0, CMD_CASUAL, + response, ARRAY_SIZE(response)); if (status < 0) return status; @@ -449,6 +448,7 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, u_register_t x5, x6; int mbox_status, len_in_resp; + switch (smc_fid) { case SIP_SVC_UID: /* Return UID to the caller */ -- cgit v1.2.3 From d191eb247adc53b913b44f4ad9df90c5445f55c8 Mon Sep 17 00:00:00 2001 From: "Abdul Halim, Muhammad Hadi Asyrafi" Date: Mon, 18 May 2020 10:32:15 +0800 Subject: intel: common: Remove urgent from mailbox async Remove urgent argument from asynchrounous mailbox command as any urgent command should always be synchronous Signed-off-by: Abdul Halim, Muhammad Hadi Asyrafi Change-Id: Iaa64335db24df3a562470d0d1c3d6a3a71493319 --- plat/intel/soc/common/include/socfpga_mailbox.h | 2 +- plat/intel/soc/common/soc/socfpga_mailbox.c | 5 +---- plat/intel/soc/common/socfpga_sip_svc.c | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h index f44bc0ecc..710ecf0c5 100644 --- a/plat/intel/soc/common/include/socfpga_mailbox.h +++ b/plat/intel/soc/common/include/socfpga_mailbox.h @@ -141,7 +141,7 @@ void mailbox_set_qspi_direct(void); int mailbox_send_cmd(int job_id, unsigned int cmd, uint32_t *args, int len, int urgent, uint32_t *response, int resp_len); int mailbox_send_cmd_async(int job_id, unsigned int cmd, uint32_t *args, - int len, int urgent, int indirect); + int len, int indirect); int mailbox_read_response(int job_id, uint32_t *response, int resp_len); void mailbox_reset_cold(void); void mailbox_clear_response(void); diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c index cbc6bfba3..39b63c987 100644 --- a/plat/intel/soc/common/soc/socfpga_mailbox.c +++ b/plat/intel/soc/common/soc/socfpga_mailbox.c @@ -168,11 +168,8 @@ int mailbox_poll_response(int job_id, int urgent, uint32_t *response, } int mailbox_send_cmd_async(int job_id, unsigned int cmd, uint32_t *args, - int len, int urgent, int indirect) + int len, int indirect) { - if (urgent) - mmio_write_32(MBOX_OFFSET + MBOX_URG, 1); - fill_mailbox_circular_buffer(MBOX_CLIENT_ID_CMD(MBOX_ATF_CLIENT_ID) | MBOX_JOB_ID_CMD(job_id) | MBOX_CMD_LEN_CMD(len) | diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c index b879cfc3b..8588e933b 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -76,7 +76,7 @@ static int intel_fpga_sdm_write_buffer(struct fpga_config_info *buffer) buffer->size_written += args[2]; mailbox_send_cmd_async(send_id++ % MBOX_MAX_JOB_ID, MBOX_RECONFIG_DATA, args, 3, - CMD_CASUAL, CMD_INDIRECT); + CMD_INDIRECT); buffer->subblocks_sent++; max_blocks--; -- cgit v1.2.3 From 1ae7b6f6b1dcc8669743c81a41423d8eca45949b Mon Sep 17 00:00:00 2001 From: Richard Gong Date: Mon, 13 Apr 2020 09:40:43 -0500 Subject: intel: SIP: increase FPGA_CONFIG_SIZE to 32 MB Increase INTEL_SIP_SMC_FPGA_CONFIG_SIZE from 16 to 32MB. We need higher pre-reserved memory size between Intel service layer and secure monitor software so we can handle JIC file authorization. Signed-off-by: Richard Gong Change-Id: Ibab4e42e4b7b93a4cf741e60ec9439359ba0a64c --- plat/intel/soc/common/include/socfpga_sip_svc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h index 22e54e895..329f511ad 100644 --- a/plat/intel/soc/common/include/socfpga_sip_svc.h +++ b/plat/intel/soc/common/include/socfpga_sip_svc.h @@ -44,7 +44,7 @@ /* FPGA config helpers */ #define INTEL_SIP_SMC_FPGA_CONFIG_ADDR 0x400000 -#define INTEL_SIP_SMC_FPGA_CONFIG_SIZE 16777216 +#define INTEL_SIP_SMC_FPGA_CONFIG_SIZE 0x2000000 /* SMC function IDs for SiP Service queries */ #define SIP_SVC_CALL_COUNT 0x8200ff00 -- cgit v1.2.3 From 7f56f240d336801e923ad8e8620e6e469810b5fe Mon Sep 17 00:00:00 2001 From: Chee Hong Ang Date: Fri, 24 Apr 2020 21:51:00 +0800 Subject: intel: clear 'PLAT_SEC_ENTRY' in early platform setup Ensure 'PLAT_SEC_ENTRY' is cleared during early platform setup. This is to prevent the slave CPU cores jump to the stale entry point after warm reset when using U-Boot SPL as first stage boot loader. Signed-off-by: Chee Hong Ang Change-Id: I3294ce2f74aa691d0cf311fa30f27f9d4fb8800a --- plat/intel/soc/agilex/bl31_plat_setup.c | 6 ++++-- plat/intel/soc/common/include/platform_def.h | 2 ++ plat/intel/soc/stratix10/bl31_plat_setup.c | 6 ++++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/plat/intel/soc/agilex/bl31_plat_setup.c b/plat/intel/soc/agilex/bl31_plat_setup.c index 6f32aff4a..436538b39 100644 --- a/plat/intel/soc/agilex/bl31_plat_setup.c +++ b/plat/intel/soc/agilex/bl31_plat_setup.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. - * Copyright (c) 2019, Intel Corporation. All rights reserved. + * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Intel Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -39,6 +39,8 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, { static console_t console; + mmio_write_64(PLAT_SEC_ENTRY, PLAT_SEC_WARM_ENTRY); + console_16550_register(PLAT_UART0_BASE, PLAT_UART_CLOCK, PLAT_BAUDRATE, &console); /* diff --git a/plat/intel/soc/common/include/platform_def.h b/plat/intel/soc/common/include/platform_def.h index 046d13880..55600ee69 100644 --- a/plat/intel/soc/common/include/platform_def.h +++ b/plat/intel/soc/common/include/platform_def.h @@ -134,6 +134,8 @@ #define PLAT_CPUID_RELEASE (BL_DATA_LIMIT - 16) #define PLAT_SEC_ENTRY (BL_DATA_LIMIT - 8) +#define PLAT_SEC_WARM_ENTRY 0 + /******************************************************************************* * Platform specific page table and MMU setup constants ******************************************************************************/ diff --git a/plat/intel/soc/stratix10/bl31_plat_setup.c b/plat/intel/soc/stratix10/bl31_plat_setup.c index 5813c8f8c..e0c3054ed 100644 --- a/plat/intel/soc/stratix10/bl31_plat_setup.c +++ b/plat/intel/soc/stratix10/bl31_plat_setup.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. - * Copyright (c) 2019, Intel Corporation. All rights reserved. + * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Intel Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -47,6 +47,8 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, { static console_t console; + mmio_write_64(PLAT_SEC_ENTRY, PLAT_SEC_WARM_ENTRY); + console_16550_register(PLAT_UART0_BASE, PLAT_UART_CLOCK, PLAT_BAUDRATE, &console); /* -- cgit v1.2.3 From 941fc5c0d2a6129e8e8791449e6ffa70f21ac378 Mon Sep 17 00:00:00 2001 From: "Abdul Halim, Muhammad Hadi Asyrafi" Date: Wed, 12 Feb 2020 19:57:44 +0800 Subject: intel: common: Improve readability of mailbox read response Rename variables to improve readability of mailbox read response and mailbox poll response flow. Signed-off-by: Abdul Halim, Muhammad Hadi Asyrafi Change-Id: Icd33ff1d2abb28eeead15e4eb9c7f9629f8cb402 --- plat/intel/soc/common/soc/socfpga_mailbox.c | 59 +++++++++++++++-------------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c index 39b63c987..4f02b6948 100644 --- a/plat/intel/soc/common/soc/socfpga_mailbox.c +++ b/plat/intel/soc/common/soc/socfpga_mailbox.c @@ -39,9 +39,10 @@ int mailbox_read_response(int job_id, uint32_t *response, int resp_len) { int rin = 0; int rout = 0; - int response_length = 0; - int resp = 0; + int mbox_resp_len = 0; + int resp_data = 0; int total_resp_len = 0; + uint32_t *resp_buf = response; if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM)) mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0); @@ -50,31 +51,31 @@ int mailbox_read_response(int job_id, uint32_t *response, int resp_len) rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT); if (rout != rin) { - resp = mmio_read_32(MBOX_OFFSET + + resp_data = mmio_read_32(MBOX_OFFSET + MBOX_RESP_BUFFER + ((rout++)*4)); rout %= MBOX_RESP_BUFFER_SIZE; mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout); - if (MBOX_RESP_CLIENT_ID(resp) != MBOX_ATF_CLIENT_ID || - MBOX_RESP_JOB_ID(resp) != job_id) { + if (MBOX_RESP_CLIENT_ID(resp_data) != MBOX_ATF_CLIENT_ID || + MBOX_RESP_JOB_ID(resp_data) != job_id) { return MBOX_WRONG_ID; } - if (MBOX_RESP_ERR(resp) > 0) { - INFO("Error in response: %x\n", resp); - return -resp; + if (MBOX_RESP_ERR(resp_data) > 0) { + INFO("Error in response: %x\n", resp_data); + return -resp_data; } - response_length = MBOX_RESP_LEN(resp); + mbox_resp_len = MBOX_RESP_LEN(resp_data); - while (response_length) { + while (mbox_resp_len > 0) { - response_length--; - resp = mmio_read_32(MBOX_OFFSET + + mbox_resp_len--; + resp_data = mmio_read_32(MBOX_OFFSET + MBOX_RESP_BUFFER + (rout)*4); - if (response && resp_len) { - *(response + total_resp_len) = resp; + if (resp_buf && resp_len) { + *(resp_buf + total_resp_len) = resp_data; resp_len--; total_resp_len++; } @@ -95,9 +96,10 @@ int mailbox_poll_response(int job_id, int urgent, uint32_t *response, int timeout = 0xFFFFFF; int rin = 0; int rout = 0; - int response_length = 0; - int resp = 0; + int mbox_resp_len = 0; + int resp_data = 0; int total_resp_len = 0; + uint32_t *resp_buf = response; while (1) { @@ -132,29 +134,30 @@ int mailbox_poll_response(int job_id, int urgent, uint32_t *response, rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT); while (rout != rin) { - resp = mmio_read_32(MBOX_OFFSET + + resp_data = mmio_read_32(MBOX_OFFSET + MBOX_RESP_BUFFER + ((rout++)*4)); rout %= MBOX_RESP_BUFFER_SIZE; mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout); - if (MBOX_RESP_CLIENT_ID(resp) != MBOX_ATF_CLIENT_ID || - MBOX_RESP_JOB_ID(resp) != job_id) + if (MBOX_RESP_CLIENT_ID(resp_data) != MBOX_ATF_CLIENT_ID + || MBOX_RESP_JOB_ID(resp_data) != job_id) continue; - if (MBOX_RESP_ERR(resp) > 0) { - INFO("Error in response: %x\n", resp); - return -MBOX_RESP_ERR(resp); + if (MBOX_RESP_ERR(resp_data) > 0) { + INFO("Error in response: %x\n", resp_data); + return -MBOX_RESP_ERR(resp_data); } - response_length = MBOX_RESP_LEN(resp); + mbox_resp_len = MBOX_RESP_LEN(resp_data); - while (response_length) { - response_length--; - resp = mmio_read_32(MBOX_OFFSET + + while (mbox_resp_len > 0) { + mbox_resp_len--; + resp_data = mmio_read_32(MBOX_OFFSET + MBOX_RESP_BUFFER + (rout)*4); - if (response && resp_len) { - *(response + total_resp_len) = resp; + if (resp_buf && resp_len) { + *(resp_buf + total_resp_len) + = resp_data; resp_len--; total_resp_len++; } -- cgit v1.2.3 From 516f32219b7417db1497d7a553d0e4465aafcb55 Mon Sep 17 00:00:00 2001 From: "Abdul Halim, Muhammad Hadi Asyrafi" Date: Thu, 14 May 2020 14:53:29 +0800 Subject: intel: common: Clean up mailbox and sip header Sort and rearrange definitions in both mailbox and sip header to increase readability and maintainability. Signed-off-by: Abdul Halim, Muhammad Hadi Asyrafi Change-Id: I5544c2f17efdf3174757c55afd8cc1062fbae856 --- plat/intel/soc/common/include/socfpga_mailbox.h | 130 +++++++++++++----------- plat/intel/soc/common/include/socfpga_sip_svc.h | 14 ++- 2 files changed, 82 insertions(+), 62 deletions(-) diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h index 3c56d15bf..b250b3e90 100644 --- a/plat/intel/soc/common/include/socfpga_mailbox.h +++ b/plat/intel/soc/common/include/socfpga_mailbox.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Intel Corporation. All rights reserved. + * Copyright (c) 2019-2020, Intel Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,35 +9,15 @@ #include + #define MBOX_OFFSET 0xffa30000 #define MBOX_MAX_JOB_ID 0xf #define MBOX_ATF_CLIENT_ID 0x1 #define MBOX_JOB_ID 0x1 -/* Mailbox interrupt flags and masks */ -#define MBOX_INT_FLAG_COE 0x1 -#define MBOX_INT_FLAG_RIE 0x2 -#define MBOX_INT_FLAG_UAE 0x100 -#define MBOX_COE_BIT(INTERRUPT) ((INTERRUPT) & 0x3) -#define MBOX_UAE_BIT(INTERRUPT) (((INTERRUPT) & (1<<8))) - -/* Mailbox response and status */ -#define MBOX_RESP_BUFFER_SIZE 16 -#define MBOX_RESP_ERR(BUFFER) ((BUFFER) & 0x00000fff) -#define MBOX_RESP_LEN(BUFFER) (((BUFFER) & 0x007ff000) >> 12) -#define MBOX_RESP_CLIENT_ID(BUFFER) (((BUFFER) & 0xf0000000) >> 28) -#define MBOX_RESP_JOB_ID(BUFFER) (((BUFFER) & 0x0f000000) >> 24) -#define MBOX_STATUS_UA_MASK (1<<8) -/* Mailbox command and response */ -#define MBOX_CMD_FREE_OFFSET 0x14 -#define MBOX_CMD_BUFFER_SIZE 32 -#define MBOX_CLIENT_ID_CMD(CLIENT_ID) ((CLIENT_ID) << 28) -#define MBOX_JOB_ID_CMD(JOB_ID) (JOB_ID<<24) -#define MBOX_CMD_LEN_CMD(CMD_LEN) ((CMD_LEN) << 12) -#define MBOX_INDIRECT (1 << 11) -#define MBOX_INSUFFICIENT_BUFFER -2 +/* Mailbox Shared Memory Register Map */ #define MBOX_CIN 0x00 #define MBOX_ROUT 0x04 #define MBOX_URG 0x08 @@ -48,60 +28,61 @@ #define MBOX_CMD_BUFFER 0x40 #define MBOX_RESP_BUFFER 0xC0 -#define MBOX_RESP_BUFFER_SIZE 16 -#define MBOX_RESP_OK 0 -#define MBOX_RESP_INVALID_CMD 1 -#define MBOX_RESP_UNKNOWN_BR 2 -#define MBOX_RESP_UNKNOWN 3 -#define MBOX_RESP_NOT_CONFIGURED 256 - /* Mailbox SDM doorbell */ #define MBOX_DOORBELL_TO_SDM 0x400 #define MBOX_DOORBELL_FROM_SDM 0x480 -/* Mailbox QSPI commands */ -#define MBOX_CMD_RESTART 2 -#define MBOX_CMD_QSPI_OPEN 50 -#define MBOX_CMD_QSPI_CLOSE 51 -#define MBOX_CMD_QSPI_DIRECT 59 -#define MBOX_CMD_GET_IDCODE 16 -#define MBOX_CMD_QSPI_SET_CS 52 -/* Mailbox CANCEL command */ -#define MBOX_CMD_CANCEL 0x3 +/* Mailbox commands */ -/* Mailbox REBOOT commands */ -#define MBOX_CMD_REBOOT_HPS 71 +#define MBOX_CMD_NOOP 0x00 +#define MBOX_CMD_SYNC 0x01 +#define MBOX_CMD_RESTART 0x02 +#define MBOX_CMD_CANCEL 0x03 +#define MBOX_CMD_GET_IDCODE 0x10 +#define MBOX_CMD_REBOOT_HPS 0x47 -/* Mailbox RSU commands */ -#define MBOX_GET_SUBPARTITION_TABLE 90 -#define MBOX_RSU_STATUS 91 -#define MBOX_RSU_UPDATE 92 +/* Reconfiguration Commands */ +#define MBOX_CONFIG_STATUS 0x04 +#define MBOX_RECONFIG 0x06 +#define MBOX_RECONFIG_DATA 0x08 +#define MBOX_RECONFIG_STATUS 0x09 -/* Mailbox RSU macros */ -#define RSU_VERSION_ACMF BIT(8) -#define RSU_VERSION_ACMF_MASK 0xff00 +/* QSPI Commands */ +#define MBOX_CMD_QSPI_OPEN 0x32 +#define MBOX_CMD_QSPI_CLOSE 0x33 +#define MBOX_CMD_QSPI_SET_CS 0x34 +#define MBOX_CMD_QSPI_DIRECT 0x3B + +/* RSU Commands */ +#define MBOX_GET_SUBPARTITION_TABLE 0x5A +#define MBOX_RSU_STATUS 0x5B +#define MBOX_RSU_UPDATE 0x5C +#define MBOX_HPS_STAGE_NOTIFY 0x5D + + +/* Mailbox Definitions */ -/* HPS stage notify command */ -#define MBOX_HPS_STAGE_NOTIFY 93 +#define CMD_DIRECT 0 +#define CMD_CASUAL 0 +#define CMD_URGENT 1 + +#define MBOX_RESP_BUFFER_SIZE 16 +#define MBOX_CMD_BUFFER_SIZE 32 /* Execution states for HPS_STAGE_NOTIFY */ #define HPS_EXECUTION_STATE_FSBL 0 #define HPS_EXECUTION_STATE_SSBL 1 #define HPS_EXECUTION_STATE_OS 2 -/* Mailbox reconfiguration commands */ -#define MBOX_CONFIG_STATUS 4 -#define MBOX_RECONFIG 6 -#define MBOX_RECONFIG_DATA 8 -#define MBOX_RECONFIG_STATUS 9 - -/* Generic error handling */ -#define MBOX_TIMEOUT -2047 +/* Status Response */ +#define MBOX_RET_OK 0 +#define MBOX_RET_ERROR -1 #define MBOX_NO_RESPONSE -2 #define MBOX_WRONG_ID -3 +#define MBOX_TIMEOUT -2047 -/* Mailbox status */ +/* Reconfig Status Response */ #define RECONFIG_STATUS_STATE 0 #define RECONFIG_STATUS_PIN_STATUS 2 #define RECONFIG_STATUS_SOFTFUNC_STATUS 3 @@ -121,6 +102,36 @@ #define MBOX_CFGSTAT_STATE_ERROR_BOOT_INFO 0xf0000007 #define MBOX_CFGSTAT_STATE_ERROR_QSPI_ERROR 0xf0000008 + +/* Mailbox Macros */ + +/* Mailbox interrupt flags and masks */ +#define MBOX_INT_FLAG_COE 0x1 +#define MBOX_INT_FLAG_RIE 0x2 +#define MBOX_INT_FLAG_UAE 0x100 +#define MBOX_COE_BIT(INTERRUPT) ((INTERRUPT) & 0x3) +#define MBOX_UAE_BIT(INTERRUPT) (((INTERRUPT) & (1<<8))) + +/* Mailbox response and status */ +#define MBOX_RESP_ERR(BUFFER) ((BUFFER) & 0x00000fff) +#define MBOX_RESP_LEN(BUFFER) (((BUFFER) & 0x007ff000) >> 12) +#define MBOX_RESP_CLIENT_ID(BUFFER) (((BUFFER) & 0xf0000000) >> 28) +#define MBOX_RESP_JOB_ID(BUFFER) (((BUFFER) & 0x0f000000) >> 24) +#define MBOX_STATUS_UA_MASK (1<<8) + +/* Mailbox command and response */ +#define MBOX_CLIENT_ID_CMD(CLIENT_ID) ((CLIENT_ID) << 28) +#define MBOX_JOB_ID_CMD(JOB_ID) (JOB_ID<<24) +#define MBOX_CMD_LEN_CMD(CMD_LEN) ((CMD_LEN) << 12) +#define MBOX_INDIRECT (1 << 11) + +/* RSU Macros */ +#define RSU_VERSION_ACMF BIT(8) +#define RSU_VERSION_ACMF_MASK 0xff00 + + +/* Mailbox Function Definitions */ + void mailbox_set_int(int interrupt_input); int mailbox_init(void); void mailbox_set_qspi_close(void); @@ -131,7 +142,6 @@ int mailbox_send_cmd(int job_id, unsigned int cmd, uint32_t *args, int mailbox_send_cmd_async(int job_id, unsigned int cmd, uint32_t *args, int len, int urgent); int mailbox_read_response(int job_id, uint32_t *response, int resp_len); -int mailbox_get_qspi_clock(void); void mailbox_reset_cold(void); void mailbox_clear_response(void); diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h index 19a52f7b9..22e54e895 100644 --- a/plat/intel/soc/common/include/socfpga_sip_svc.h +++ b/plat/intel/soc/common/include/socfpga_sip_svc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Intel Corporation. All rights reserved. + * Copyright (c) 2019-2020, Intel Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -17,21 +17,31 @@ /* SMC SiP service function identifier */ + +/* FPGA Reconfig */ #define INTEL_SIP_SMC_FPGA_CONFIG_START 0xC2000001 #define INTEL_SIP_SMC_FPGA_CONFIG_WRITE 0x42000002 #define INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE 0xC2000003 #define INTEL_SIP_SMC_FPGA_CONFIG_ISDONE 0xC2000004 #define INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM 0xC2000005 + +/* Secure Register Access */ #define INTEL_SIP_SMC_REG_READ 0xC2000007 #define INTEL_SIP_SMC_REG_WRITE 0xC2000008 #define INTEL_SIP_SMC_REG_UPDATE 0xC2000009 + +/* Remote System Update */ #define INTEL_SIP_SMC_RSU_STATUS 0xC200000B #define INTEL_SIP_SMC_RSU_UPDATE 0xC200000C -#define INTEL_SIP_LEGACY_SMC_ECC_DBE 0xC200000D #define INTEL_SIP_SMC_RSU_NOTIFY 0xC200000E #define INTEL_SIP_SMC_RSU_RETRY_COUNTER 0xC200000F + +/* Send Mailbox Command */ #define INTEL_SIP_SMC_MBOX_SEND_CMD 0xC200001E + +/* SiP Definitions */ + /* FPGA config helpers */ #define INTEL_SIP_SMC_FPGA_CONFIG_ADDR 0x400000 #define INTEL_SIP_SMC_FPGA_CONFIG_SIZE 16777216 -- cgit v1.2.3 From 054af8f233d94670dca1a27992296a5afc6b1f73 Mon Sep 17 00:00:00 2001 From: Po Xu Date: Fri, 18 Sep 2020 09:32:31 +0800 Subject: mediatek: mt8192: add GPIO driver support add GPIO driver Change-Id: I67a9abef078e7a62b34dfbd366b45c03892800cd Signed-off-by: Po Xu --- plat/mediatek/mt8192/bl31_plat_setup.c | 2 + plat/mediatek/mt8192/drivers/gpio/mtgpio.c | 340 ++++++++++++++++++++++++ plat/mediatek/mt8192/drivers/gpio/mtgpio.h | 384 ++++++++++++++++++++++++++++ plat/mediatek/mt8192/include/platform_def.h | 10 + plat/mediatek/mt8192/platform.mk | 8 +- 5 files changed, 742 insertions(+), 2 deletions(-) create mode 100644 plat/mediatek/mt8192/drivers/gpio/mtgpio.c create mode 100644 plat/mediatek/mt8192/drivers/gpio/mtgpio.h diff --git a/plat/mediatek/mt8192/bl31_plat_setup.c b/plat/mediatek/mt8192/bl31_plat_setup.c index f96528196..9a01bef65 100644 --- a/plat/mediatek/mt8192/bl31_plat_setup.c +++ b/plat/mediatek/mt8192/bl31_plat_setup.c @@ -15,6 +15,7 @@ #include /* Platform Includes */ +#include #include #include #include @@ -83,6 +84,7 @@ void bl31_platform_setup(void) /* Initialize the GIC driver, CPU and distributor interfaces */ mt_gic_driver_init(); mt_gic_init(); + plat_mt8192_gpio_init(); } /******************************************************************************* diff --git a/plat/mediatek/mt8192/drivers/gpio/mtgpio.c b/plat/mediatek/mt8192/drivers/gpio/mtgpio.c new file mode 100644 index 000000000..e07b75a47 --- /dev/null +++ b/plat/mediatek/mt8192/drivers/gpio/mtgpio.c @@ -0,0 +1,340 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include + +/****************************************************************************** + *Macro Definition + ******************************************************************************/ +#define GPIO_MODE_BITS 4 +#define MAX_GPIO_MODE_PER_REG 8 +#define MAX_GPIO_REG_BITS 32 +#define DIR_BASE (GPIO_BASE + 0x000) +#define DOUT_BASE (GPIO_BASE + 0x100) +#define DIN_BASE (GPIO_BASE + 0x200) +#define MODE_BASE (GPIO_BASE + 0x300) +#define SET 0x4 +#define CLR 0x8 + +static void mt_set_gpio_dir_chip(uint32_t pin, int dir) +{ + uint32_t pos, bit; + + assert(pin < MAX_GPIO_PIN); + assert(dir < MT_GPIO_DIR_MAX); + + pos = pin / MAX_GPIO_REG_BITS; + bit = pin % MAX_GPIO_REG_BITS; + + if (dir == MT_GPIO_DIR_IN) { + mmio_write_32(DIR_BASE + 0x10U * pos + CLR, 1U << bit); + } else { + mmio_write_32(DIR_BASE + 0x10U * pos + SET, 1U << bit); + } +} + +static int mt_get_gpio_dir_chip(uint32_t pin) +{ + uint32_t pos, bit; + uint32_t reg; + + assert(pin < MAX_GPIO_PIN); + + pos = pin / MAX_GPIO_REG_BITS; + bit = pin % MAX_GPIO_REG_BITS; + + reg = mmio_read_32(DIR_BASE + 0x10U * pos); + return (((reg & (1U << bit)) != 0U) ? MT_GPIO_DIR_OUT : MT_GPIO_DIR_IN); +} + +static void mt_set_gpio_out_chip(uint32_t pin, int output) +{ + uint32_t pos, bit; + + assert(pin < MAX_GPIO_PIN); + assert(output < MT_GPIO_OUT_MAX); + + pos = pin / MAX_GPIO_REG_BITS; + bit = pin % MAX_GPIO_REG_BITS; + + if (output == MT_GPIO_OUT_ZERO) { + mmio_write_32(DOUT_BASE + 0x10U * pos + CLR, 1U << bit); + } else { + mmio_write_32(DOUT_BASE + 0x10U * pos + SET, 1U << bit); + } +} + +static int mt_get_gpio_in_chip(uint32_t pin) +{ + uint32_t pos, bit; + uint32_t reg; + + assert(pin < MAX_GPIO_PIN); + + pos = pin / MAX_GPIO_REG_BITS; + bit = pin % MAX_GPIO_REG_BITS; + + reg = mmio_read_32(DIN_BASE + 0x10U * pos); + return (((reg & (1U << bit)) != 0U) ? 1 : 0); +} + +static uintptr_t mt_gpio_find_reg_addr(uint32_t pin) +{ + uintptr_t reg_addr = 0U; + struct mt_pin_info gpio_info; + + gpio_info = mt8192_pin_infos[pin]; + + switch (gpio_info.base & 0x0f) { + case 0: + reg_addr = IOCFG_RM_BASE; + break; + case 1: + reg_addr = IOCFG_BM_BASE; + break; + case 2: + reg_addr = IOCFG_BL_BASE; + break; + case 3: + reg_addr = IOCFG_BR_BASE; + break; + case 4: + reg_addr = IOCFG_LM_BASE; + break; + case 5: + reg_addr = IOCFG_LB_BASE; + break; + case 6: + reg_addr = IOCFG_RT_BASE; + break; + case 7: + reg_addr = IOCFG_LT_BASE; + break; + case 8: + reg_addr = IOCFG_TL_BASE; + break; + default: + break; + } + + return reg_addr; +} + +static void mt_gpio_set_spec_pull_pupd(uint32_t pin, int enable, + int select) +{ + uintptr_t reg1; + uintptr_t reg2; + struct mt_pin_info gpio_info; + + gpio_info = mt8192_pin_infos[pin]; + uint32_t bit = gpio_info.bit; + + reg1 = mt_gpio_find_reg_addr(pin) + gpio_info.offset; + reg2 = reg1 + (gpio_info.base & 0xf0); + if (enable == MT_GPIO_PULL_ENABLE) { + mmio_write_32(reg2 + SET, (1U << bit)); + if (select == MT_GPIO_PULL_DOWN) { + mmio_write_32(reg1 + SET, (1U << bit)); + } else { + mmio_write_32(reg1 + CLR, (1U << bit)); + } + } else { + mmio_write_32(reg2 + CLR, (1U << bit)); + mmio_write_32((reg2 + 0x010U) + CLR, (1U << bit)); + } +} + +static void mt_gpio_set_pull_pu_pd(uint32_t pin, int enable, + int select) +{ + uintptr_t reg1; + uintptr_t reg2; + struct mt_pin_info gpio_info; + + gpio_info = mt8192_pin_infos[pin]; + uint32_t bit = gpio_info.bit; + + reg1 = mt_gpio_find_reg_addr(pin) + gpio_info.offset; + reg2 = reg1 - (gpio_info.base & 0xf0); + + if (enable == MT_GPIO_PULL_ENABLE) { + if (select == MT_GPIO_PULL_DOWN) { + mmio_write_32(reg1 + CLR, (1U << bit)); + mmio_write_32(reg2 + SET, (1U << bit)); + } else { + mmio_write_32(reg2 + CLR, (1U << bit)); + mmio_write_32(reg1 + SET, (1U << bit)); + } + } else { + mmio_write_32(reg1 + CLR, (1U << bit)); + mmio_write_32(reg2 + CLR, (1U << bit)); + } +} + +static void mt_gpio_set_pull_chip(uint32_t pin, int enable, + int select) +{ + struct mt_pin_info gpio_info; + + gpio_info = mt8192_pin_infos[pin]; + if (gpio_info.flag) { + mt_gpio_set_spec_pull_pupd(pin, enable, select); + } else { + mt_gpio_set_pull_pu_pd(pin, enable, select); + } +} + +static int mt_gpio_get_spec_pull_pupd(uint32_t pin) +{ + uintptr_t reg1; + uintptr_t reg2; + uint32_t r0; + uint32_t r1; + + struct mt_pin_info gpio_info; + + gpio_info = mt8192_pin_infos[pin]; + uint32_t bit = gpio_info.bit; + + reg1 = mt_gpio_find_reg_addr(pin) + gpio_info.offset; + reg2 = reg1 + (gpio_info.base & 0xf0); + + r0 = (mmio_read_32(reg2) >> bit) & 1U; + r1 = (mmio_read_32(reg2 + 0x010) >> bit) & 1U; + if (r0 == 0U && r1 == 0U) { + return MT_GPIO_PULL_NONE; + } else { + if (mmio_read_32(reg1) & (1U << bit)) { + return MT_GPIO_PULL_DOWN; + } else { + return MT_GPIO_PULL_UP; + } + } +} + +static int mt_gpio_get_pull_pu_pd(uint32_t pin) +{ + uintptr_t reg1; + uintptr_t reg2; + uint32_t pu; + uint32_t pd; + + struct mt_pin_info gpio_info; + + gpio_info = mt8192_pin_infos[pin]; + uint32_t bit = gpio_info.bit; + + reg1 = mt_gpio_find_reg_addr(pin) + gpio_info.offset; + reg2 = reg1 - (gpio_info.base & 0xf0); + pu = (mmio_read_32(reg1) >> bit) & 1U; + pd = (mmio_read_32(reg2) >> bit) & 1U; + if (pu == 1U) { + return MT_GPIO_PULL_UP; + } else if (pd == 1U) { + return MT_GPIO_PULL_DOWN; + } else { + return MT_GPIO_PULL_NONE; + } +} + +static int mt_gpio_get_pull_chip(uint32_t pin) +{ + struct mt_pin_info gpio_info; + + gpio_info = mt8192_pin_infos[pin]; + if (gpio_info.flag) { + return mt_gpio_get_spec_pull_pupd(pin); + } else { + return mt_gpio_get_pull_pu_pd(pin); + } +} + +static void mt_set_gpio_pull_select_chip(uint32_t pin, int sel) +{ + assert(pin < MAX_GPIO_PIN); + + if (sel == MT_GPIO_PULL_NONE) { + mt_gpio_set_pull_chip(pin, MT_GPIO_PULL_DISABLE, MT_GPIO_PULL_DOWN); + } else if (sel == MT_GPIO_PULL_UP) { + mt_gpio_set_pull_chip(pin, MT_GPIO_PULL_ENABLE, MT_GPIO_PULL_UP); + } else if (sel == MT_GPIO_PULL_DOWN) { + mt_gpio_set_pull_chip(pin, MT_GPIO_PULL_ENABLE, MT_GPIO_PULL_DOWN); + } +} + +/* get pull-up or pull-down, regardless of resistor value */ +static int mt_get_gpio_pull_select_chip(uint32_t pin) +{ + assert(pin < MAX_GPIO_PIN); + + return mt_gpio_get_pull_chip(pin); +} + +static void mt_set_gpio_dir(int gpio, int direction) +{ + mt_set_gpio_dir_chip((uint32_t)gpio, direction); +} + +static int mt_get_gpio_dir(int gpio) +{ + uint32_t pin; + + pin = (uint32_t)gpio; + return mt_get_gpio_dir_chip(pin); +} + +static void mt_set_gpio_pull(int gpio, int pull) +{ + uint32_t pin; + + pin = (uint32_t)gpio; + mt_set_gpio_pull_select_chip(pin, pull); +} + +static int mt_get_gpio_pull(int gpio) +{ + uint32_t pin; + + pin = (uint32_t)gpio; + return mt_get_gpio_pull_select_chip(pin); +} + +static void mt_set_gpio_out(int gpio, int value) +{ + uint32_t pin; + + pin = (uint32_t)gpio; + mt_set_gpio_out_chip(pin, value); +} + +static int mt_get_gpio_in(int gpio) +{ + uint32_t pin; + + pin = (uint32_t)gpio; + return mt_get_gpio_in_chip(pin); +} + +const gpio_ops_t mtgpio_ops = { + .get_direction = mt_get_gpio_dir, + .set_direction = mt_set_gpio_dir, + .get_value = mt_get_gpio_in, + .set_value = mt_set_gpio_out, + .set_pull = mt_set_gpio_pull, + .get_pull = mt_get_gpio_pull, +}; + +void plat_mt8192_gpio_init(void) +{ + gpio_init(&mtgpio_ops); +} diff --git a/plat/mediatek/mt8192/drivers/gpio/mtgpio.h b/plat/mediatek/mt8192/drivers/gpio/mtgpio.h new file mode 100644 index 000000000..ca0c964f6 --- /dev/null +++ b/plat/mediatek/mt8192/drivers/gpio/mtgpio.h @@ -0,0 +1,384 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MT_GPIO_H +#define MT_GPIO_H + +#include +#include + +#include + +/* Error Code No. */ +#define RSUCCESS 0 +#define ERACCESS 1 +#define ERINVAL 2 +#define ERWRAPPER 3 +#define MAX_GPIO_PIN MT_GPIO_BASE_MAX + +/* Enumeration for GPIO pin */ +typedef enum GPIO_PIN { + GPIO_UNSUPPORTED = -1, + + GPIO0, GPIO1, GPIO2, GPIO3, GPIO4, GPIO5, GPIO6, GPIO7, + GPIO8, GPIO9, GPIO10, GPIO11, GPIO12, GPIO13, GPIO14, GPIO15, + GPIO16, GPIO17, GPIO18, GPIO19, GPIO20, GPIO21, GPIO22, GPIO23, + GPIO24, GPIO25, GPIO26, GPIO27, GPIO28, GPIO29, GPIO30, GPIO31, + GPIO32, GPIO33, GPIO34, GPIO35, GPIO36, GPIO37, GPIO38, GPIO39, + GPIO40, GPIO41, GPIO42, GPIO43, GPIO44, GPIO45, GPIO46, GPIO47, + GPIO48, GPIO49, GPIO50, GPIO51, GPIO52, GPIO53, GPIO54, GPIO55, + GPIO56, GPIO57, GPIO58, GPIO59, GPIO60, GPIO61, GPIO62, GPIO63, + GPIO64, GPIO65, GPIO66, GPIO67, GPIO68, GPIO69, GPIO70, GPIO71, + GPIO72, GPIO73, GPIO74, GPIO75, GPIO76, GPIO77, GPIO78, GPIO79, + GPIO80, GPIO81, GPIO82, GPIO83, GPIO84, GPIO85, GPIO86, GPIO87, + GPIO88, GPIO89, GPIO90, GPIO91, GPIO92, GPIO93, GPIO94, GPIO95, + GPIO96, GPIO97, GPIO98, GPIO99, GPIO100, GPIO101, GPIO102, GPIO103, + GPIO104, GPIO105, GPIO106, GPIO107, GPIO108, GPIO109, GPIO110, GPIO111, + GPIO112, GPIO113, GPIO114, GPIO115, GPIO116, GPIO117, GPIO118, GPIO119, + GPIO120, GPIO121, GPIO122, GPIO123, GPIO124, GPIO125, GPIO126, GPIO127, + GPIO128, GPIO129, GPIO130, GPIO131, GPIO132, GPIO133, GPIO134, GPIO135, + GPIO136, GPIO137, GPIO138, GPIO139, GPIO140, GPIO141, GPIO142, GPIO143, + GPIO144, GPIO145, GPIO146, GPIO147, GPIO148, GPIO149, GPIO150, GPIO151, + GPIO152, GPIO153, GPIO154, GPIO155, GPIO156, GPIO157, GPIO158, GPIO159, + GPIO160, GPIO161, GPIO162, GPIO163, GPIO164, GPIO165, GPIO166, GPIO167, + GPIO168, GPIO169, GPIO170, GPIO171, GPIO172, GPIO173, GPIO174, GPIO175, + GPIO176, GPIO177, GPIO178, GPIO179, GPIO180, GPIO181, GPIO182, GPIO183, + GPIO184, GPIO185, GPIO186, GPIO187, GPIO188, GPIO189, GPIO190, GPIO191, + GPIO192, GPIO193, GPIO194, GPIO195, GPIO196, GPIO197, GPIO198, GPIO199, + GPIO200, GPIO201, GPIO202, GPIO203, GPIO204, GPIO205, GPIO206, GPIO207, + GPIO208, GPIO209, GPIO210, GPIO211, GPIO212, GPIO213, GPIO214, GPIO215, + GPIO216, GPIO217, GPIO218, GPIO219, + MT_GPIO_BASE_MAX +} GPIO_PIN; + +/* GPIO MODE CONTROL VALUE*/ +typedef enum { + GPIO_MODE_UNSUPPORTED = -1, + GPIO_MODE_GPIO = 0, + GPIO_MODE_00 = 0, + GPIO_MODE_01, + GPIO_MODE_02, + GPIO_MODE_03, + GPIO_MODE_04, + GPIO_MODE_05, + GPIO_MODE_06, + GPIO_MODE_07, + + GPIO_MODE_MAX, + GPIO_MODE_DEFAULT = GPIO_MODE_00, +} GPIO_MODE; + +/* GPIO DIRECTION */ +typedef enum { + MT_GPIO_DIR_UNSUPPORTED = -1, + MT_GPIO_DIR_OUT = 0, + MT_GPIO_DIR_IN = 1, + MT_GPIO_DIR_MAX, + MT_GPIO_DIR_DEFAULT = MT_GPIO_DIR_IN, +} GPIO_DIR; + +/* GPIO PULL ENABLE*/ +typedef enum { + MT_GPIO_PULL_EN_UNSUPPORTED = -1, + MT_GPIO_PULL_DISABLE = 0, + MT_GPIO_PULL_ENABLE = 1, + MT_GPIO_PULL_ENABLE_R0 = 2, + MT_GPIO_PULL_ENABLE_R1 = 3, + MT_GPIO_PULL_ENABLE_R0R1 = 4, + + MT_GPIO_PULL_EN_MAX, + MT_GPIO_PULL_EN_DEFAULT = MT_GPIO_PULL_ENABLE, +} GPIO_PULL_EN; + +/* GPIO PULL-UP/PULL-DOWN*/ +typedef enum { + MT_GPIO_PULL_UNSUPPORTED = -1, + MT_GPIO_PULL_NONE = 0, + MT_GPIO_PULL_UP = 1, + MT_GPIO_PULL_DOWN = 2, + MT_GPIO_PULL_MAX, + MT_GPIO_PULL_DEFAULT = MT_GPIO_PULL_DOWN +} GPIO_PULL; + +/* GPIO OUTPUT */ +typedef enum { + MT_GPIO_OUT_UNSUPPORTED = -1, + MT_GPIO_OUT_ZERO = 0, + MT_GPIO_OUT_ONE = 1, + + MT_GPIO_OUT_MAX, + MT_GPIO_OUT_DEFAULT = MT_GPIO_OUT_ZERO, + MT_GPIO_DATA_OUT_DEFAULT = MT_GPIO_OUT_ZERO, /*compatible with DCT*/ +} GPIO_OUT; + +/* GPIO INPUT */ +typedef enum { + MT_GPIO_IN_UNSUPPORTED = -1, + MT_GPIO_IN_ZERO = 0, + MT_GPIO_IN_ONE = 1, + + MT_GPIO_IN_MAX, +} GPIO_IN; + +typedef struct { + uint32_t val; + uint32_t set; + uint32_t rst; + uint32_t _align1; +} VAL_REGS; + +typedef struct { + VAL_REGS dir[7]; + uint8_t rsv00[144]; + VAL_REGS dout[7]; + uint8_t rsv01[144]; + VAL_REGS din[7]; + uint8_t rsv02[144]; + VAL_REGS mode[28]; +} GPIO_REGS; + + +#define PIN(_id, _flag, _bit, _base, _offset) { \ + .id = _id, \ + .flag = _flag, \ + .bit = _bit, \ + .base = _base, \ + .offset = _offset, \ + } + +struct mt_pin_info { + uint8_t id; + uint8_t flag; + uint8_t bit; + uint16_t base; + uint16_t offset; +}; + +static const struct mt_pin_info mt8192_pin_infos[] = { + PIN(0, 0, 9, 0x23, 0xb0), + PIN(1, 0, 10, 0x23, 0xb0), + PIN(2, 0, 11, 0x23, 0xb0), + PIN(3, 0, 12, 0x23, 0xb0), + PIN(4, 0, 13, 0x23, 0xb0), + PIN(5, 0, 14, 0x23, 0xb0), + PIN(6, 0, 15, 0x23, 0xb0), + PIN(7, 0, 16, 0x23, 0xb0), + PIN(8, 0, 17, 0x23, 0xb0), + PIN(9, 0, 18, 0x23, 0xb0), + PIN(10, 1, 0, 0x15, 0x20), + PIN(11, 1, 1, 0x15, 0x20), + PIN(12, 1, 2, 0x15, 0x20), + PIN(13, 1, 3, 0x15, 0x20), + PIN(14, 1, 4, 0x15, 0x20), + PIN(15, 1, 5, 0x15, 0x20), + PIN(16, 0, 2, 0x17, 0x50), + PIN(17, 0, 3, 0x17, 0x50), + PIN(18, 0, 21, 0x36, 0xa0), + PIN(19, 0, 22, 0x36, 0xa0), + PIN(20, 0, 23, 0x36, 0xa0), + PIN(21, 0, 24, 0x36, 0xa0), + PIN(22, 0, 3, 0x21, 0x90), + PIN(23, 0, 4, 0x21, 0x90), + PIN(24, 0, 5, 0x21, 0x90), + PIN(25, 0, 6, 0x21, 0x90), + PIN(26, 0, 5, 0x22, 0x80), + PIN(27, 0, 6, 0x22, 0x80), + PIN(28, 0, 7, 0x22, 0x80), + PIN(29, 0, 8, 0x22, 0x80), + PIN(30, 0, 9, 0x22, 0x80), + PIN(31, 0, 27, 0x22, 0x70), + PIN(32, 0, 24, 0x22, 0x70), + PIN(33, 0, 26, 0x22, 0x70), + PIN(34, 0, 23, 0x22, 0x70), + PIN(35, 0, 25, 0x22, 0x70), + PIN(36, 0, 20, 0x21, 0x90), + PIN(37, 0, 21, 0x21, 0x90), + PIN(38, 0, 22, 0x21, 0x90), + PIN(39, 0, 23, 0x21, 0x90), + PIN(40, 0, 0, 0x17, 0x50), + PIN(41, 0, 1, 0x17, 0x50), + PIN(42, 0, 4, 0x17, 0x50), + PIN(43, 0, 25, 0x36, 0xa0), + PIN(44, 0, 26, 0x36, 0xa0), + PIN(45, 1, 9, 0x20, 0x60), + PIN(46, 1, 11, 0x20, 0x60), + PIN(47, 1, 10, 0x20, 0x60), + PIN(48, 1, 7, 0x20, 0x60), + PIN(49, 1, 8, 0x20, 0x60), + PIN(50, 1, 6, 0x20, 0x60), + PIN(51, 1, 0, 0x20, 0x60), + PIN(52, 1, 1, 0x20, 0x60), + PIN(53, 1, 5, 0x20, 0x60), + PIN(54, 1, 2, 0x20, 0x60), + PIN(55, 1, 4, 0x20, 0x60), + PIN(56, 1, 3, 0x20, 0x60), + PIN(57, 0, 1, 0x22, 0x80), + PIN(58, 0, 2, 0x22, 0x80), + PIN(59, 0, 3, 0x22, 0x80), + PIN(60, 0, 4, 0x22, 0x80), + PIN(61, 0, 28, 0x22, 0x70), + PIN(62, 0, 22, 0x22, 0x70), + PIN(63, 0, 0, 0x22, 0x70), + PIN(64, 0, 1, 0x22, 0x70), + PIN(65, 0, 12, 0x22, 0x70), + PIN(66, 0, 15, 0x22, 0x70), + PIN(67, 0, 16, 0x22, 0x70), + PIN(68, 0, 17, 0x22, 0x70), + PIN(69, 0, 18, 0x22, 0x70), + PIN(70, 0, 19, 0x22, 0x70), + PIN(71, 0, 20, 0x22, 0x70), + PIN(72, 0, 21, 0x22, 0x70), + PIN(73, 0, 2, 0x22, 0x70), + PIN(74, 0, 3, 0x22, 0x70), + PIN(75, 0, 4, 0x22, 0x70), + PIN(76, 0, 5, 0x22, 0x70), + PIN(77, 0, 6, 0x22, 0x70), + PIN(78, 0, 7, 0x22, 0x70), + PIN(79, 0, 8, 0x22, 0x70), + PIN(80, 0, 9, 0x22, 0x70), + PIN(81, 0, 10, 0x22, 0x70), + PIN(82, 0, 11, 0x22, 0x70), + PIN(83, 0, 13, 0x22, 0x70), + PIN(84, 0, 14, 0x22, 0x70), + PIN(85, 0, 31, 0x22, 0x70), + PIN(86, 0, 0, 0x22, 0x80), + PIN(87, 0, 29, 0x22, 0x70), + PIN(88, 0, 30, 0x22, 0x70), + PIN(89, 0, 24, 0x21, 0x90), + PIN(90, 0, 25, 0x21, 0x90), + PIN(91, 0, 0, 0x21, 0x90), + PIN(92, 0, 2, 0x21, 0xa0), + PIN(93, 0, 4, 0x21, 0xa0), + PIN(94, 0, 3, 0x21, 0xa0), + PIN(95, 0, 5, 0x21, 0xa0), + PIN(96, 0, 31, 0x21, 0x90), + PIN(97, 0, 26, 0x21, 0x90), + PIN(98, 0, 0, 0x21, 0xa0), + PIN(99, 0, 27, 0x21, 0x90), + PIN(100, 0, 28, 0x21, 0x90), + PIN(101, 0, 29, 0x21, 0x90), + PIN(102, 0, 30, 0x21, 0x90), + PIN(103, 0, 18, 0x21, 0x90), + PIN(104, 0, 17, 0x21, 0x90), + PIN(105, 0, 19, 0x21, 0x90), + PIN(106, 0, 16, 0x21, 0x90), + PIN(107, 0, 1, 0x21, 0x90), + PIN(108, 0, 2, 0x21, 0x90), + PIN(109, 0, 10, 0x21, 0x90), + PIN(110, 0, 7, 0x21, 0x90), + PIN(111, 0, 9, 0x21, 0x90), + PIN(112, 0, 11, 0x21, 0x90), + PIN(113, 0, 8, 0x21, 0x90), + PIN(114, 0, 14, 0x21, 0x90), + PIN(115, 0, 13, 0x21, 0x90), + PIN(116, 0, 15, 0x21, 0x90), + PIN(117, 0, 12, 0x21, 0x90), + PIN(118, 0, 23, 0x23, 0xb0), + PIN(119, 0, 29, 0x23, 0xb0), + PIN(120, 0, 28, 0x23, 0xb0), + PIN(121, 0, 2, 0x23, 0xc0), + PIN(122, 0, 27, 0x23, 0xb0), + PIN(123, 0, 1, 0x23, 0xc0), + PIN(124, 0, 26, 0x23, 0xb0), + PIN(125, 0, 0, 0x23, 0xc0), + PIN(126, 0, 19, 0x23, 0xb0), + PIN(127, 0, 20, 0x23, 0xb0), + PIN(128, 0, 21, 0x23, 0xb0), + PIN(129, 0, 22, 0x23, 0xb0), + PIN(130, 0, 6, 0x23, 0xb0), + PIN(131, 0, 7, 0x23, 0xb0), + PIN(132, 0, 8, 0x23, 0xb0), + PIN(133, 0, 3, 0x23, 0xb0), + PIN(134, 0, 4, 0x23, 0xb0), + PIN(135, 0, 5, 0x23, 0xb0), + PIN(136, 0, 0, 0x23, 0xb0), + PIN(137, 0, 1, 0x23, 0xb0), + PIN(138, 0, 2, 0x23, 0xb0), + PIN(139, 0, 25, 0x23, 0xb0), + PIN(140, 0, 31, 0x23, 0xb0), + PIN(141, 0, 24, 0x23, 0xb0), + PIN(142, 0, 30, 0x23, 0xb0), + PIN(143, 0, 6, 0x20, 0x70), + PIN(144, 0, 7, 0x20, 0x70), + PIN(145, 0, 8, 0x20, 0x70), + PIN(146, 0, 3, 0x20, 0x70), + PIN(147, 0, 4, 0x20, 0x70), + PIN(148, 0, 5, 0x20, 0x70), + PIN(149, 0, 0, 0x20, 0x70), + PIN(150, 0, 1, 0x20, 0x70), + PIN(151, 0, 2, 0x20, 0x70), + PIN(152, 1, 3, 0x36, 0x90), + PIN(153, 1, 2, 0x36, 0x90), + PIN(154, 1, 0, 0x36, 0x906), + PIN(155, 1, 1, 0x36, 0x90), + PIN(156, 0, 29, 0x36, 0xa0), + PIN(157, 0, 30, 0x36, 0xa0), + PIN(158, 0, 31, 0x36, 0xa0), + PIN(159, 0, 0, 0x36, 0xb0), + PIN(160, 0, 27, 0x36, 0xa04), + PIN(161, 0, 28, 0x36, 0xa0), + PIN(162, 0, 0, 0x36, 0xa0), + PIN(163, 0, 1, 0x36, 0xa0), + PIN(164, 0, 2, 0x36, 0xa0), + PIN(165, 0, 3, 0x36, 0xa0), + PIN(166, 0, 4, 0x36, 0xa0), + PIN(167, 0, 5, 0x36, 0xa0), + PIN(168, 0, 6, 0x36, 0xa0), + PIN(169, 0, 7, 0x36, 0xa0), + PIN(170, 0, 8, 0x36, 0xa0), + PIN(171, 0, 9, 0x36, 0xa0), + PIN(172, 0, 13, 0x36, 0xa0), + PIN(173, 0, 14, 0x36, 0xa0), + PIN(174, 0, 12, 0x36, 0xa0), + PIN(175, 0, 15, 0x36, 0xa0), + PIN(176, 0, 10, 0x36, 0xa0), + PIN(177, 0, 11, 0x36, 0xa0), + PIN(178, 0, 16, 0x36, 0xa0), + PIN(179, 0, 17, 0x36, 0xa0), + PIN(180, 0, 18, 0x36, 0xa0), + PIN(181, 0, 19, 0x36, 0xa0), + PIN(182, 0, 20, 0x36, 0xa0), + PIN(183, 1, 1, 0x18, 0x30), + PIN(184, 1, 2, 0x18, 0x30), + PIN(185, 1, 4, 0x18, 0x30), + PIN(186, 1, 6, 0x18, 0x30), + PIN(187, 1, 8, 0x18, 0x30), + PIN(188, 1, 3, 0x18, 0x30), + PIN(189, 1, 7, 0x18, 0x30), + PIN(190, 1, 9, 0x18, 0x30), + PIN(191, 1, 10, 0x18, 0x30), + PIN(192, 1, 0, 0x18, 0x30), + PIN(193, 1, 5, 0x18, 0x30), + PIN(194, 1, 11, 0x18, 0x30), + PIN(195, 0, 16, 0x14, 0x50), + PIN(196, 0, 6, 0x14, 0x50), + PIN(197, 0, 8, 0x14, 0x50), + PIN(198, 0, 7, 0x14, 0x50), + PIN(199, 0, 3, 0x14, 0x50), + PIN(200, 0, 6, 0x17, 0x50), + PIN(201, 0, 8, 0x17, 0x50), + PIN(202, 0, 15, 0x14, 0x50), + PIN(203, 0, 17, 0x14, 0x50), + PIN(204, 0, 5, 0x17, 0x50), + PIN(205, 0, 7, 0x17, 0x50), + PIN(206, 0, 18, 0x14, 0x50), + PIN(207, 0, 19, 0x14, 0x50), + PIN(208, 0, 20, 0x14, 0x50), + PIN(209, 0, 12, 0x14, 0x50), + PIN(210, 0, 11, 0x14, 0x50), + PIN(211, 0, 13, 0x14, 0x50), + PIN(212, 0, 10, 0x14, 0x50), + PIN(213, 0, 14, 0x14, 0x50), + PIN(214, 0, 0, 0x14, 0x50), + PIN(215, 0, 9, 0x14, 0x50), + PIN(216, 0, 4, 0x14, 0x50), + PIN(217, 0, 5, 0x14, 0x50), + PIN(218, 0, 1, 0x14, 0x50), + PIN(219, 0, 2, 0x14, 0x50), +}; + +void plat_mt8192_gpio_init(void); +#endif /* MT_GPIO_H */ diff --git a/plat/mediatek/mt8192/include/platform_def.h b/plat/mediatek/mt8192/include/platform_def.h index 5ff013ecc..768e7cf82 100644 --- a/plat/mediatek/mt8192/include/platform_def.h +++ b/plat/mediatek/mt8192/include/platform_def.h @@ -24,6 +24,16 @@ #define MTK_DEV_RNG2_BASE 0x0c000000 #define MTK_DEV_RNG2_SIZE 0x600000 +#define GPIO_BASE (IO_PHYS + 0x00005000) +#define IOCFG_RM_BASE (IO_PHYS + 0x01C20000) +#define IOCFG_BM_BASE (IO_PHYS + 0x01D10000) +#define IOCFG_BL_BASE (IO_PHYS + 0x01D30000) +#define IOCFG_BR_BASE (IO_PHYS + 0x01D40000) +#define IOCFG_LM_BASE (IO_PHYS + 0x01E20000) +#define IOCFG_LB_BASE (IO_PHYS + 0x01E70000) +#define IOCFG_RT_BASE (IO_PHYS + 0x01EA0000) +#define IOCFG_LT_BASE (IO_PHYS + 0x01F20000) +#define IOCFG_TL_BASE (IO_PHYS + 0x01F30000) /******************************************************************************* * UART related constants ******************************************************************************/ diff --git a/plat/mediatek/mt8192/platform.mk b/plat/mediatek/mt8192/platform.mk index c972ac61d..0d732d50a 100644 --- a/plat/mediatek/mt8192/platform.mk +++ b/plat/mediatek/mt8192/platform.mk @@ -8,7 +8,9 @@ MTK_PLAT := plat/mediatek MTK_PLAT_SOC := ${MTK_PLAT}/${PLAT} PLAT_INCLUDES := -I${MTK_PLAT}/common/ \ - -I${MTK_PLAT_SOC}/include/ + -I${MTK_PLAT_SOC}/include/ \ + -I${MTK_PLAT_SOC}/drivers/ \ + -I${MTK_PLAT_SOC}/drivers/gpio/ GICV3_SUPPORT_GIC600 := 1 include drivers/arm/gic/v3/gicv3.mk @@ -21,6 +23,7 @@ PLAT_BL_COMMON_SOURCES := ${GICV3_SOURCES} \ BL31_SOURCES += common/desc_image_load.c \ drivers/ti/uart/aarch64/16550_console.S \ + drivers/gpio/gpio.c \ lib/bl_aux_params/bl_aux_params.c \ lib/cpus/aarch64/cortex_a55.S \ lib/cpus/aarch64/cortex_a76.S \ @@ -32,7 +35,8 @@ BL31_SOURCES += common/desc_image_load.c \ ${MTK_PLAT_SOC}/bl31_plat_setup.c \ ${MTK_PLAT_SOC}/plat_pm.c \ ${MTK_PLAT_SOC}/plat_topology.c \ - ${MTK_PLAT_SOC}/plat_mt_gic.c + ${MTK_PLAT_SOC}/plat_mt_gic.c \ + ${MTK_PLAT_SOC}/drivers/gpio/mtgpio.c # Configs for A76 and A55 -- cgit v1.2.3 From aad868b4d955fe827821f40830aa3392b9b24a83 Mon Sep 17 00:00:00 2001 From: "Abdul Halim, Muhammad Hadi Asyrafi" Date: Mon, 18 May 2020 11:16:48 +0800 Subject: intel: common: Change how mailbox handles job id & buffer This patch modifies several basic mailbox driver features to prepare for FCS enablement: - Job id management for asynchronous response - SDM command buffer full Signed-off-by: Abdul Halim, Muhammad Hadi Asyrafi Change-Id: I78168dfb6c521d70d9cba187356b7a3c8e9b62d2 --- plat/intel/soc/common/include/socfpga_mailbox.h | 14 +++--- plat/intel/soc/common/include/socfpga_sip_svc.h | 15 ++++++ plat/intel/soc/common/soc/socfpga_mailbox.c | 39 +++++++++++----- plat/intel/soc/common/socfpga_sip_svc.c | 62 +++++++++---------------- 4 files changed, 71 insertions(+), 59 deletions(-) diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h index 710ecf0c5..75323fdf5 100644 --- a/plat/intel/soc/common/include/socfpga_mailbox.h +++ b/plat/intel/soc/common/include/socfpga_mailbox.h @@ -12,9 +12,10 @@ #define MBOX_OFFSET 0xffa30000 -#define MBOX_MAX_JOB_ID 0xf -#define MBOX_ATF_CLIENT_ID 0x1 -#define MBOX_JOB_ID 0x1 +#define MBOX_ATF_CLIENT_ID 0x1U +#define MBOX_MAX_JOB_ID 0xFU +#define MBOX_MAX_IND_JOB_ID (MBOX_MAX_JOB_ID - 1U) +#define MBOX_JOB_ID MBOX_MAX_JOB_ID /* Mailbox Shared Memory Register Map */ @@ -81,6 +82,7 @@ #define MBOX_RET_ERROR -1 #define MBOX_NO_RESPONSE -2 #define MBOX_WRONG_ID -3 +#define MBOX_BUFFER_FULL -4 #define MBOX_TIMEOUT -2047 /* Reconfig Status Response */ @@ -138,11 +140,11 @@ int mailbox_init(void); void mailbox_set_qspi_close(void); void mailbox_set_qspi_open(void); void mailbox_set_qspi_direct(void); -int mailbox_send_cmd(int job_id, unsigned int cmd, uint32_t *args, +int mailbox_send_cmd(uint32_t job_id, unsigned int cmd, uint32_t *args, int len, int urgent, uint32_t *response, int resp_len); -int mailbox_send_cmd_async(int job_id, unsigned int cmd, uint32_t *args, +int mailbox_send_cmd_async(uint32_t *job_id, unsigned int cmd, uint32_t *args, int len, int indirect); -int mailbox_read_response(int job_id, uint32_t *response, int resp_len); +int mailbox_read_response(uint32_t *job_id, uint32_t *response, int resp_len); void mailbox_reset_cold(void); void mailbox_clear_response(void); diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h index 329f511ad..92adfa3a7 100644 --- a/plat/intel/soc/common/include/socfpga_sip_svc.h +++ b/plat/intel/soc/common/include/socfpga_sip_svc.h @@ -55,4 +55,19 @@ #define SIP_SVC_VERSION_MAJOR 0 #define SIP_SVC_VERSION_MINOR 1 + +/* Structure Definitions */ +struct fpga_config_info { + uint32_t addr; + int size; + int size_written; + uint32_t write_requested; + int subblocks_sent; + int block_number; +}; + +/* Function Definitions */ + +bool is_address_in_ddr_range(uint64_t addr, uint64_t size); + #endif /* SOCFPGA_SIP_SVC_H */ diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c index 4f02b6948..5935777c0 100644 --- a/plat/intel/soc/common/soc/socfpga_mailbox.c +++ b/plat/intel/soc/common/soc/socfpga_mailbox.c @@ -14,10 +14,16 @@ static int fill_mailbox_circular_buffer(uint32_t header_cmd, uint32_t *args, int len) { - uint32_t cmd_free_offset; + uint32_t sdm_read_offset, cmd_free_offset; int i; cmd_free_offset = mmio_read_32(MBOX_OFFSET + MBOX_CIN); + sdm_read_offset = mmio_read_32(MBOX_OFFSET + MBOX_COUT); + + if ((cmd_free_offset < sdm_read_offset) && + (cmd_free_offset + len > sdm_read_offset)) { + return MBOX_BUFFER_FULL; + } mmio_write_32(MBOX_OFFSET + MBOX_CMD_BUFFER + (cmd_free_offset++ * 4), header_cmd); @@ -35,7 +41,7 @@ static int fill_mailbox_circular_buffer(uint32_t header_cmd, uint32_t *args, return MBOX_RET_OK; } -int mailbox_read_response(int job_id, uint32_t *response, int resp_len) +int mailbox_read_response(uint32_t *job_id, uint32_t *response, int resp_len) { int rin = 0; int rout = 0; @@ -57,11 +63,13 @@ int mailbox_read_response(int job_id, uint32_t *response, int resp_len) rout %= MBOX_RESP_BUFFER_SIZE; mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout); - if (MBOX_RESP_CLIENT_ID(resp_data) != MBOX_ATF_CLIENT_ID || - MBOX_RESP_JOB_ID(resp_data) != job_id) { + + if (MBOX_RESP_CLIENT_ID(resp_data) != MBOX_ATF_CLIENT_ID) { return MBOX_WRONG_ID; } + *job_id = MBOX_RESP_JOB_ID(resp_data); + if (MBOX_RESP_ERR(resp_data) > 0) { INFO("Error in response: %x\n", resp_data); return -resp_data; @@ -90,7 +98,7 @@ int mailbox_read_response(int job_id, uint32_t *response, int resp_len) } -int mailbox_poll_response(int job_id, int urgent, uint32_t *response, +int mailbox_poll_response(uint32_t job_id, int urgent, uint32_t *response, int resp_len) { int timeout = 0xFFFFFF; @@ -170,21 +178,28 @@ int mailbox_poll_response(int job_id, int urgent, uint32_t *response, } } -int mailbox_send_cmd_async(int job_id, unsigned int cmd, uint32_t *args, +int mailbox_send_cmd_async(uint32_t *job_id, unsigned int cmd, uint32_t *args, int len, int indirect) { - fill_mailbox_circular_buffer(MBOX_CLIENT_ID_CMD(MBOX_ATF_CLIENT_ID) | - MBOX_JOB_ID_CMD(job_id) | - MBOX_CMD_LEN_CMD(len) | - MBOX_INDIRECT(indirect) | - cmd, args, len); + int status; + + status = fill_mailbox_circular_buffer( + MBOX_CLIENT_ID_CMD(MBOX_ATF_CLIENT_ID) | + MBOX_JOB_ID_CMD(*job_id) | + MBOX_CMD_LEN_CMD(len) | + MBOX_INDIRECT(indirect) | + cmd, args, len); + if (status < 0) { + return status; + } mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1); + *job_id = (*job_id + 1) % MBOX_MAX_IND_JOB_ID; return MBOX_RET_OK; } -int mailbox_send_cmd(int job_id, unsigned int cmd, uint32_t *args, +int mailbox_send_cmd(uint32_t job_id, unsigned int cmd, uint32_t *args, int len, int urgent, uint32_t *response, int resp_len) { int status = 0; diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c index 8588e933b..d5789f247 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -14,30 +14,15 @@ #include "socfpga_reset_manager.h" #include "socfpga_sip_svc.h" -/* Number of SiP Calls implemented */ -#define SIP_NUM_CALLS 0x3 /* Total buffer the driver can hold */ #define FPGA_CONFIG_BUFFER_SIZE 4 -static int current_block; -static int read_block; -static int current_buffer; -static int send_id; -static int rcv_id; -static int max_blocks; -static uint32_t bytes_per_block; -static uint32_t blocks_submitted; -static int is_partial_reconfig; - -struct fpga_config_info { - uint32_t addr; - int size; - int size_written; - uint32_t write_requested; - int subblocks_sent; - int block_number; -}; +static int current_block, current_buffer; +static int read_block, max_blocks, is_partial_reconfig; +static uint32_t send_id, rcv_id; +static uint32_t bytes_per_block, blocks_submitted; + /* SiP Service UUID */ DEFINE_SVC_UUID2(intl_svc_uid, @@ -74,9 +59,8 @@ static int intel_fpga_sdm_write_buffer(struct fpga_config_info *buffer) args[2] = bytes_per_block; buffer->size_written += args[2]; - mailbox_send_cmd_async(send_id++ % MBOX_MAX_JOB_ID, - MBOX_RECONFIG_DATA, args, 3, - CMD_INDIRECT); + mailbox_send_cmd_async(&send_id, MBOX_RECONFIG_DATA, args, + 3, CMD_INDIRECT); buffer->subblocks_sent++; max_blocks--; @@ -142,7 +126,7 @@ static int mark_last_buffer_xfer_completed(uint32_t *buffer_addr_completed) } static int intel_fpga_config_completed_write(uint32_t *completed_addr, - uint32_t *count) + uint32_t *count, uint32_t *job_id) { uint32_t status = INTEL_SIP_SMC_STATUS_OK; *count = 0; @@ -152,14 +136,13 @@ static int intel_fpga_config_completed_write(uint32_t *completed_addr, while (*count < 3) { - resp_len = mailbox_read_response(rcv_id % MBOX_MAX_JOB_ID, + resp_len = mailbox_read_response(job_id, resp, ARRAY_SIZE(resp)); if (resp_len < 0) break; max_blocks++; - rcv_id++; if (mark_last_buffer_xfer_completed( &completed_addr[*count]) == 0) @@ -231,8 +214,6 @@ static int intel_fpga_config_start(uint32_t config_type) current_block = 0; read_block = 0; current_buffer = 0; - send_id = 0; - rcv_id = 0; /* full reconfiguration */ if (!is_partial_reconfig) { @@ -251,7 +232,7 @@ static bool is_fpga_config_buffer_full(void) return true; } -static bool is_address_in_ddr_range(uint64_t addr, uint64_t size) +bool is_address_in_ddr_range(uint64_t addr, uint64_t size) { if (size > (UINT64_MAX - addr)) return false; @@ -440,11 +421,10 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, void *handle, u_register_t flags) { - uint32_t val = 0; + uint32_t retval = 0; uint32_t status = INTEL_SIP_SMC_STATUS_OK; uint32_t completed_addr[3]; uint64_t rsu_respbuf[9]; - uint32_t count = 0; u_register_t x5, x6; int mbox_status, len_in_resp; @@ -474,8 +454,8 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, case INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE: status = intel_fpga_config_completed_write(completed_addr, - &count); - switch (count) { + &retval, &rcv_id); + switch (retval) { case 1: SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK, completed_addr[0], 0, 0); @@ -500,17 +480,17 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, } case INTEL_SIP_SMC_REG_READ: - status = intel_secure_reg_read(x1, &val); - SMC_RET3(handle, status, val, x1); + status = intel_secure_reg_read(x1, &retval); + SMC_RET3(handle, status, retval, x1); case INTEL_SIP_SMC_REG_WRITE: - status = intel_secure_reg_write(x1, (uint32_t)x2, &val); - SMC_RET3(handle, status, val, x1); + status = intel_secure_reg_write(x1, (uint32_t)x2, &retval); + SMC_RET3(handle, status, retval, x1); case INTEL_SIP_SMC_REG_UPDATE: status = intel_secure_reg_update(x1, (uint32_t)x2, - (uint32_t)x3, &val); - SMC_RET3(handle, status, val, x1); + (uint32_t)x3, &retval); + SMC_RET3(handle, status, retval, x1); case INTEL_SIP_SMC_RSU_STATUS: status = intel_rsu_status(rsu_respbuf, @@ -532,11 +512,11 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, case INTEL_SIP_SMC_RSU_RETRY_COUNTER: status = intel_rsu_retry_counter((uint32_t *)rsu_respbuf, - ARRAY_SIZE(rsu_respbuf), &val); + ARRAY_SIZE(rsu_respbuf), &retval); if (status) { SMC_RET1(handle, status); } else { - SMC_RET2(handle, status, val); + SMC_RET2(handle, status, retval); } case INTEL_SIP_SMC_MBOX_SEND_CMD: -- cgit v1.2.3 From 39aebd358e7d430f5803fe47416ac4749684dbb9 Mon Sep 17 00:00:00 2001 From: "Abdul Halim, Muhammad Hadi Asyrafi" Date: Wed, 29 Apr 2020 22:26:40 +0800 Subject: intel: mailbox: Driver now handles larger response This patch factorizes mailbox read response from SDM into a function. Also fix the logic to support reading larger than 16 words response from SDM. Signed-off-by: Abdul Halim, Muhammad Hadi Asyrafi Change-Id: Ie035ecffbbc42e12dd68061c403904c28c3b70e5 --- plat/intel/soc/common/include/socfpga_mailbox.h | 1 + plat/intel/soc/common/soc/socfpga_mailbox.c | 85 ++++++++++++------------- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h index 75323fdf5..59714fdb1 100644 --- a/plat/intel/soc/common/include/socfpga_mailbox.h +++ b/plat/intel/soc/common/include/socfpga_mailbox.h @@ -145,6 +145,7 @@ int mailbox_send_cmd(uint32_t job_id, unsigned int cmd, uint32_t *args, int mailbox_send_cmd_async(uint32_t *job_id, unsigned int cmd, uint32_t *args, int len, int indirect); int mailbox_read_response(uint32_t *job_id, uint32_t *response, int resp_len); +int iterate_resp(int mbox_resp_len, uint32_t *resp_buf, int resp_len); void mailbox_reset_cold(void); void mailbox_clear_response(void); diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c index 5935777c0..3bb2561cb 100644 --- a/plat/intel/soc/common/soc/socfpga_mailbox.c +++ b/plat/intel/soc/common/soc/socfpga_mailbox.c @@ -45,10 +45,7 @@ int mailbox_read_response(uint32_t *job_id, uint32_t *response, int resp_len) { int rin = 0; int rout = 0; - int mbox_resp_len = 0; int resp_data = 0; - int total_resp_len = 0; - uint32_t *resp_buf = response; if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM)) mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0); @@ -74,26 +71,10 @@ int mailbox_read_response(uint32_t *job_id, uint32_t *response, int resp_len) INFO("Error in response: %x\n", resp_data); return -resp_data; } - mbox_resp_len = MBOX_RESP_LEN(resp_data); - while (mbox_resp_len > 0) { - - mbox_resp_len--; - resp_data = mmio_read_32(MBOX_OFFSET + - MBOX_RESP_BUFFER + - (rout)*4); - if (resp_buf && resp_len) { - *(resp_buf + total_resp_len) = resp_data; - resp_len--; - total_resp_len++; - } - rout++; - rout %= MBOX_RESP_BUFFER_SIZE; - mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout); - } - return total_resp_len; + return iterate_resp(MBOX_RESP_LEN(resp_data), + response, resp_len); } - return MBOX_NO_RESPONSE; } @@ -104,10 +85,7 @@ int mailbox_poll_response(uint32_t job_id, int urgent, uint32_t *response, int timeout = 0xFFFFFF; int rin = 0; int rout = 0; - int mbox_resp_len = 0; int resp_data = 0; - int total_resp_len = 0; - uint32_t *resp_buf = response; while (1) { @@ -118,7 +96,7 @@ int mailbox_poll_response(uint32_t job_id, int urgent, uint32_t *response, } if (!timeout) { - INFO("Timed out waiting for SDM"); + INFO("Timed out waiting for SDM\n"); return MBOX_TIMEOUT; } @@ -156,26 +134,47 @@ int mailbox_poll_response(uint32_t job_id, int urgent, uint32_t *response, INFO("Error in response: %x\n", resp_data); return -MBOX_RESP_ERR(resp_data); } - mbox_resp_len = MBOX_RESP_LEN(resp_data); - - while (mbox_resp_len > 0) { - mbox_resp_len--; - resp_data = mmio_read_32(MBOX_OFFSET + - MBOX_RESP_BUFFER + - (rout)*4); - if (resp_buf && resp_len) { - *(resp_buf + total_resp_len) - = resp_data; - resp_len--; - total_resp_len++; - } - rout++; - rout %= MBOX_RESP_BUFFER_SIZE; - mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout); - } - return total_resp_len; + + return iterate_resp(MBOX_RESP_LEN(resp_data), + response, resp_len); + } + } +} + +int iterate_resp(int mbox_resp_len, uint32_t *resp_buf, int resp_len) +{ + uint32_t timeout; + int resp_data = 0, total_resp_len = 0; + int rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN); + int rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT); + + while (mbox_resp_len > 0) { + timeout = 0xFFFFFF; + mbox_resp_len--; + resp_data = mmio_read_32(MBOX_OFFSET + + MBOX_RESP_BUFFER + + (rout)*4); + if (resp_buf && resp_len) { + *(resp_buf + total_resp_len) + = resp_data; + resp_len--; + total_resp_len++; + } + rout++; + rout %= MBOX_RESP_BUFFER_SIZE; + mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout); + + do { + timeout--; + rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN); + } while ((rout == rin) && (mbox_resp_len > 0) && (timeout > 0)); + + if (timeout == 0) { + INFO("Timed out waiting for SDM\n"); + return MBOX_TIMEOUT; } } + return total_resp_len; } int mailbox_send_cmd_async(uint32_t *job_id, unsigned int cmd, uint32_t *args, -- cgit v1.2.3 From 6d9f9f5ea0be1bc9d7daf6ecbe2e58e743dc9f28 Mon Sep 17 00:00:00 2001 From: Chee Hong Ang Date: Mon, 11 May 2020 00:40:18 +0800 Subject: intel: mailbox: Read mailbox response even there is an error Mailbox driver should read the response data if the response length in the response header is non-zero even the response header indicates error (non-zero). Signed-off-by: Chee Hong Ang Change-Id: I928f705f43c0f46ac74b84428b830276cc4c9640 --- plat/intel/soc/common/soc/socfpga_mailbox.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c index 3bb2561cb..4bae66efd 100644 --- a/plat/intel/soc/common/soc/socfpga_mailbox.c +++ b/plat/intel/soc/common/soc/socfpga_mailbox.c @@ -46,6 +46,7 @@ int mailbox_read_response(uint32_t *job_id, uint32_t *response, int resp_len) int rin = 0; int rout = 0; int resp_data = 0; + int ret_resp_len; if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM)) mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0); @@ -67,13 +68,19 @@ int mailbox_read_response(uint32_t *job_id, uint32_t *response, int resp_len) *job_id = MBOX_RESP_JOB_ID(resp_data); + ret_resp_len = MBOX_RESP_LEN(resp_data); + + if (ret_resp_len != 0) { + ret_resp_len = iterate_resp(ret_resp_len, response, + resp_len); + } + if (MBOX_RESP_ERR(resp_data) > 0) { INFO("Error in response: %x\n", resp_data); return -resp_data; } - return iterate_resp(MBOX_RESP_LEN(resp_data), - response, resp_len); + return ret_resp_len; } return MBOX_NO_RESPONSE; } @@ -86,6 +93,7 @@ int mailbox_poll_response(uint32_t job_id, int urgent, uint32_t *response, int rin = 0; int rout = 0; int resp_data = 0; + int ret_resp_len; while (1) { @@ -130,13 +138,20 @@ int mailbox_poll_response(uint32_t job_id, int urgent, uint32_t *response, || MBOX_RESP_JOB_ID(resp_data) != job_id) continue; + ret_resp_len = MBOX_RESP_LEN(resp_data); + + if (ret_resp_len != 0) { + ret_resp_len = iterate_resp(ret_resp_len, + response, + resp_len); + } + if (MBOX_RESP_ERR(resp_data) > 0) { INFO("Error in response: %x\n", resp_data); return -MBOX_RESP_ERR(resp_data); } - return iterate_resp(MBOX_RESP_LEN(resp_data), - response, resp_len); + return ret_resp_len; } } } -- cgit v1.2.3 From d96e7cda8a9f84ca8d0054bc1c86aabcb27db1d1 Mon Sep 17 00:00:00 2001 From: Chee Hong Ang Date: Mon, 11 May 2020 00:55:01 +0800 Subject: intel: mailbox: Ensure time out duration is predictive For each count down of time out counter, wait for number of miliseconds to ensure the time out duration is predictive. Signed-off-by: Chee Hong Ang Change-Id: I0e92dd1ef1da0ef504ec86472cf0d3c88528930b --- plat/intel/soc/agilex/bl31_plat_setup.c | 2 ++ plat/intel/soc/agilex/platform.mk | 4 ++-- plat/intel/soc/common/soc/socfpga_mailbox.c | 29 ++++++++++++++++++----------- plat/intel/soc/stratix10/bl31_plat_setup.c | 2 ++ plat/intel/soc/stratix10/platform.mk | 4 ++-- 5 files changed, 26 insertions(+), 15 deletions(-) diff --git a/plat/intel/soc/agilex/bl31_plat_setup.c b/plat/intel/soc/agilex/bl31_plat_setup.c index 436538b39..168236b64 100644 --- a/plat/intel/soc/agilex/bl31_plat_setup.c +++ b/plat/intel/soc/agilex/bl31_plat_setup.c @@ -101,6 +101,8 @@ static const gicv2_driver_data_t plat_gicv2_gic_data = { ******************************************************************************/ void bl31_platform_setup(void) { + socfpga_delay_timer_init(); + /* Initialize the gic cpu and distributor interfaces */ gicv2_driver_init(&plat_gicv2_gic_data); gicv2_distif_init(); diff --git a/plat/intel/soc/agilex/platform.mk b/plat/intel/soc/agilex/platform.mk index 814d9c663..bf5cc1445 100644 --- a/plat/intel/soc/agilex/platform.mk +++ b/plat/intel/soc/agilex/platform.mk @@ -25,7 +25,8 @@ PLAT_BL_COMMON_SOURCES := \ lib/xlat_tables/aarch64/xlat_tables.c \ lib/xlat_tables/xlat_tables_common.c \ plat/intel/soc/common/aarch64/platform_common.c \ - plat/intel/soc/common/aarch64/plat_helpers.S + plat/intel/soc/common/aarch64/plat_helpers.S \ + plat/intel/soc/common/socfpga_delay_timer.c BL2_SOURCES += \ common/desc_image_load.c \ @@ -44,7 +45,6 @@ BL2_SOURCES += \ plat/intel/soc/agilex/soc/agilex_mmc.c \ plat/intel/soc/agilex/soc/agilex_pinmux.c \ plat/intel/soc/common/bl2_plat_mem_params_desc.c \ - plat/intel/soc/common/socfpga_delay_timer.c \ plat/intel/soc/common/socfpga_image_load.c \ plat/intel/soc/common/socfpga_storage.c \ plat/intel/soc/common/soc/socfpga_emac.c \ diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c index 4bae66efd..984aa9c6e 100644 --- a/plat/intel/soc/common/soc/socfpga_mailbox.c +++ b/plat/intel/soc/common/soc/socfpga_mailbox.c @@ -89,7 +89,7 @@ int mailbox_read_response(uint32_t *job_id, uint32_t *response, int resp_len) int mailbox_poll_response(uint32_t job_id, int urgent, uint32_t *response, int resp_len) { - int timeout = 0xFFFFFF; + uint32_t timeout = 40U; int rin = 0; int rout = 0; int resp_data = 0; @@ -97,13 +97,15 @@ int mailbox_poll_response(uint32_t job_id, int urgent, uint32_t *response, while (1) { - while (timeout > 0 && - !(mmio_read_32(MBOX_OFFSET + - MBOX_DOORBELL_FROM_SDM) & 1)) { - timeout--; - } + do { + if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM) + & 1) { + break; + } + mdelay(25); + } while (--timeout != 0U); - if (!timeout) { + if (timeout == 0U) { INFO("Timed out waiting for SDM\n"); return MBOX_TIMEOUT; } @@ -164,7 +166,7 @@ int iterate_resp(int mbox_resp_len, uint32_t *resp_buf, int resp_len) int rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT); while (mbox_resp_len > 0) { - timeout = 0xFFFFFF; + timeout = 40; mbox_resp_len--; resp_data = mmio_read_32(MBOX_OFFSET + MBOX_RESP_BUFFER + @@ -180,11 +182,16 @@ int iterate_resp(int mbox_resp_len, uint32_t *resp_buf, int resp_len) mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout); do { - timeout--; rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN); - } while ((rout == rin) && (mbox_resp_len > 0) && (timeout > 0)); + if (rout == rin) { + mdelay(25); + } else { + break; + } + timeout--; + } while ((mbox_resp_len > 0) && (timeout != 0U)); - if (timeout == 0) { + if (timeout == 0U) { INFO("Timed out waiting for SDM\n"); return MBOX_TIMEOUT; } diff --git a/plat/intel/soc/stratix10/bl31_plat_setup.c b/plat/intel/soc/stratix10/bl31_plat_setup.c index e0c3054ed..128a8080d 100644 --- a/plat/intel/soc/stratix10/bl31_plat_setup.c +++ b/plat/intel/soc/stratix10/bl31_plat_setup.c @@ -109,6 +109,8 @@ static const gicv2_driver_data_t plat_gicv2_gic_data = { ******************************************************************************/ void bl31_platform_setup(void) { + socfpga_delay_timer_init(); + /* Initialize the gic cpu and distributor interfaces */ gicv2_driver_init(&plat_gicv2_gic_data); gicv2_distif_init(); diff --git a/plat/intel/soc/stratix10/platform.mk b/plat/intel/soc/stratix10/platform.mk index 3bd6af9ce..8bbd01027 100644 --- a/plat/intel/soc/stratix10/platform.mk +++ b/plat/intel/soc/stratix10/platform.mk @@ -25,7 +25,8 @@ PLAT_BL_COMMON_SOURCES := \ lib/xlat_tables/aarch64/xlat_tables.c \ lib/xlat_tables/xlat_tables_common.c \ plat/intel/soc/common/aarch64/platform_common.c \ - plat/intel/soc/common/aarch64/plat_helpers.S + plat/intel/soc/common/aarch64/plat_helpers.S \ + plat/intel/soc/common/socfpga_delay_timer.c BL2_SOURCES += \ common/desc_image_load.c \ @@ -43,7 +44,6 @@ BL2_SOURCES += \ plat/intel/soc/stratix10/soc/s10_memory_controller.c \ plat/intel/soc/stratix10/soc/s10_pinmux.c \ plat/intel/soc/common/bl2_plat_mem_params_desc.c \ - plat/intel/soc/common/socfpga_delay_timer.c \ plat/intel/soc/common/socfpga_image_load.c \ plat/intel/soc/common/socfpga_storage.c \ plat/intel/soc/common/soc/socfpga_emac.c \ -- cgit v1.2.3 From 4978bc28325f5337bac5b2a2df1b772409628cb2 Mon Sep 17 00:00:00 2001 From: "Abdul Halim, Muhammad Hadi Asyrafi" Date: Tue, 2 Jun 2020 01:05:24 +0800 Subject: intel: mailbox: Use retry count in mailbox poll Change the main loop inside mailbox poll function from while(1) to a retry counter named sdm_loop. This is to limit the maximum possible looping of the function and prevent unexpected behaviour. Signed-off-by: Abdul Halim, Muhammad Hadi Asyrafi Change-Id: I63afad958fe5f656f6333b60d5a8b4c0ada3b23d --- plat/intel/soc/common/soc/socfpga_mailbox.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c index 984aa9c6e..ddfe34cd0 100644 --- a/plat/intel/soc/common/soc/socfpga_mailbox.c +++ b/plat/intel/soc/common/soc/socfpga_mailbox.c @@ -90,12 +90,13 @@ int mailbox_poll_response(uint32_t job_id, int urgent, uint32_t *response, int resp_len) { uint32_t timeout = 40U; + uint32_t sdm_loop = 255U; int rin = 0; int rout = 0; int resp_data = 0; int ret_resp_len; - while (1) { + while (sdm_loop != 0U) { do { if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM) @@ -106,8 +107,7 @@ int mailbox_poll_response(uint32_t job_id, int urgent, uint32_t *response, } while (--timeout != 0U); if (timeout == 0U) { - INFO("Timed out waiting for SDM\n"); - return MBOX_TIMEOUT; + break; } mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0); @@ -155,7 +155,12 @@ int mailbox_poll_response(uint32_t job_id, int urgent, uint32_t *response, return ret_resp_len; } + + sdm_loop--; } + + INFO("Timed out waiting for SDM\n"); + return MBOX_TIMEOUT; } int iterate_resp(int mbox_resp_len, uint32_t *resp_buf, int resp_len) -- cgit v1.2.3 From d14e965c036af6b7164164a28d65771559760189 Mon Sep 17 00:00:00 2001 From: "Abdul Halim, Muhammad Hadi Asyrafi" Date: Tue, 2 Jun 2020 01:06:33 +0800 Subject: intel: mailbox: Enable sending large mailbox command Allow mailbox command that is larger than mailbox command FIFO buffer size to be sent to SDM in multiple chunks. Signed-off-by: Abdul Halim, Muhammad Hadi Asyrafi Change-Id: I683d5f1d04c4fdf57d11ecae6232b7ed3fc49e26 --- plat/intel/soc/common/soc/socfpga_mailbox.c | 110 +++++++++++++++++++++++----- 1 file changed, 91 insertions(+), 19 deletions(-) diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c index ddfe34cd0..870ef10d4 100644 --- a/plat/intel/soc/common/soc/socfpga_mailbox.c +++ b/plat/intel/soc/common/soc/socfpga_mailbox.c @@ -11,32 +11,105 @@ #include "socfpga_mailbox.h" #include "socfpga_sip_svc.h" + +static bool is_mailbox_cmdbuf_full(uint32_t cin) +{ + uint32_t cout = mmio_read_32(MBOX_OFFSET + MBOX_COUT); + + return (((cin + 1U) % MBOX_CMD_BUFFER_SIZE) == cout); +} + +static bool is_mailbox_cmdbuf_empty(uint32_t cin) +{ + uint32_t cout = mmio_read_32(MBOX_OFFSET + MBOX_COUT); + + return (((cout + 1U) % MBOX_CMD_BUFFER_SIZE) == cin); +} + +static int wait_for_mailbox_cmdbuf_empty(uint32_t cin) +{ + uint32_t timeout = 200U; + + do { + if (is_mailbox_cmdbuf_empty(cin)) { + break; + } + mdelay(10U); + } while (--timeout != 0U); + + if (timeout == 0U) { + return MBOX_TIMEOUT; + } + + return MBOX_RET_OK; +} + +static int write_mailbox_cmd_buffer(uint32_t *cin, uint32_t cout, + uint32_t data, + bool *is_doorbell_triggered) +{ + uint32_t timeout = 100U; + + do { + if (is_mailbox_cmdbuf_full(*cin)) { + if (!(*is_doorbell_triggered)) { + mmio_write_32(MBOX_OFFSET + + MBOX_DOORBELL_TO_SDM, 1); + *is_doorbell_triggered = true; + } + mdelay(10U); + } else { + mmio_write_32(MBOX_OFFSET + MBOX_CMD_BUFFER + + (*cin * 4), data); + (*cin)++; + *cin %= MBOX_CMD_BUFFER_SIZE; + mmio_write_32(MBOX_OFFSET + MBOX_CIN, *cin); + break; + } + } while (--timeout != 0U); + + if (timeout == 0U) { + return MBOX_TIMEOUT; + } + + if (*is_doorbell_triggered) { + int ret = wait_for_mailbox_cmdbuf_empty(*cin); + return ret; + } + + return MBOX_RET_OK; +} + static int fill_mailbox_circular_buffer(uint32_t header_cmd, uint32_t *args, int len) { uint32_t sdm_read_offset, cmd_free_offset; - int i; + uint32_t i; + int ret; + bool is_doorbell_triggered = false; cmd_free_offset = mmio_read_32(MBOX_OFFSET + MBOX_CIN); sdm_read_offset = mmio_read_32(MBOX_OFFSET + MBOX_COUT); - if ((cmd_free_offset < sdm_read_offset) && - (cmd_free_offset + len > sdm_read_offset)) { - return MBOX_BUFFER_FULL; + ret = write_mailbox_cmd_buffer(&cmd_free_offset, sdm_read_offset, + header_cmd, &is_doorbell_triggered); + if (ret != 0) { + return ret; } - mmio_write_32(MBOX_OFFSET + MBOX_CMD_BUFFER + (cmd_free_offset++ * 4), - header_cmd); - - - for (i = 0; i < len; i++) { - cmd_free_offset %= MBOX_CMD_BUFFER_SIZE; - mmio_write_32(MBOX_OFFSET + MBOX_CMD_BUFFER + - (cmd_free_offset++ * 4), args[i]); + for (i = 0U; i < len; i++) { + is_doorbell_triggered = false; + ret = write_mailbox_cmd_buffer(&cmd_free_offset, + sdm_read_offset, args[i], + &is_doorbell_triggered); + if (ret != 0) { + return ret; + } } - cmd_free_offset %= MBOX_CMD_BUFFER_SIZE; - mmio_write_32(MBOX_OFFSET + MBOX_CIN, cmd_free_offset); + if (!is_doorbell_triggered) { + mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1); + } return MBOX_RET_OK; } @@ -103,7 +176,7 @@ int mailbox_poll_response(uint32_t job_id, int urgent, uint32_t *response, & 1) { break; } - mdelay(25); + mdelay(10U); } while (--timeout != 0U); if (timeout == 0U) { @@ -171,7 +244,7 @@ int iterate_resp(int mbox_resp_len, uint32_t *resp_buf, int resp_len) int rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT); while (mbox_resp_len > 0) { - timeout = 40; + timeout = 100U; mbox_resp_len--; resp_data = mmio_read_32(MBOX_OFFSET + MBOX_RESP_BUFFER + @@ -189,7 +262,7 @@ int iterate_resp(int mbox_resp_len, uint32_t *resp_buf, int resp_len) do { rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN); if (rout == rin) { - mdelay(25); + mdelay(10U); } else { break; } @@ -219,7 +292,6 @@ int mailbox_send_cmd_async(uint32_t *job_id, unsigned int cmd, uint32_t *args, return status; } - mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1); *job_id = (*job_id + 1) % MBOX_MAX_IND_JOB_ID; return MBOX_RET_OK; @@ -234,6 +306,7 @@ int mailbox_send_cmd(uint32_t job_id, unsigned int cmd, uint32_t *args, urgent |= mmio_read_32(MBOX_OFFSET + MBOX_STATUS) & MBOX_STATUS_UA_MASK; mmio_write_32(MBOX_OFFSET + MBOX_URG, cmd); + mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1); } else { @@ -247,7 +320,6 @@ int mailbox_send_cmd(uint32_t job_id, unsigned int cmd, uint32_t *args, if (status) return status; - mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1); status = mailbox_poll_response(job_id, urgent, response, resp_len); return status; -- cgit v1.2.3 From 997560470a18e1f0b84f35b2d51960fee9b5fc61 Mon Sep 17 00:00:00 2001 From: Chee Hong Ang Date: Mon, 11 May 2020 11:23:21 +0800 Subject: intel: mailbox: Mailbox error recovery handling Attempt to restart the mailbox if the mailbox driver not able to write any data into the mailbox command buffer. Signed-off-by: Chee Hong Ang Change-Id: Ia45291c985844dec9da82839cac701347534d32b --- plat/intel/soc/common/include/socfpga_mailbox.h | 1 + plat/intel/soc/common/soc/socfpga_mailbox.c | 22 +++++++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h index 59714fdb1..3a2bf309e 100644 --- a/plat/intel/soc/common/include/socfpga_mailbox.h +++ b/plat/intel/soc/common/include/socfpga_mailbox.h @@ -127,6 +127,7 @@ #define MBOX_JOB_ID_CMD(JOB_ID) (JOB_ID<<24) #define MBOX_CMD_LEN_CMD(CMD_LEN) ((CMD_LEN) << 12) #define MBOX_INDIRECT(val) ((val) << 11) +#define MBOX_CMD_MASK(header) ((header) & 0x7ff) /* RSU Macros */ #define RSU_VERSION_ACMF BIT(8) diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c index 870ef10d4..9ba9b3171 100644 --- a/plat/intel/soc/common/soc/socfpga_mailbox.c +++ b/plat/intel/soc/common/soc/socfpga_mailbox.c @@ -94,7 +94,7 @@ static int fill_mailbox_circular_buffer(uint32_t header_cmd, uint32_t *args, ret = write_mailbox_cmd_buffer(&cmd_free_offset, sdm_read_offset, header_cmd, &is_doorbell_triggered); if (ret != 0) { - return ret; + goto restart_mailbox; } for (i = 0U; i < len; i++) { @@ -103,7 +103,7 @@ static int fill_mailbox_circular_buffer(uint32_t header_cmd, uint32_t *args, sdm_read_offset, args[i], &is_doorbell_triggered); if (ret != 0) { - return ret; + goto restart_mailbox; } } @@ -112,6 +112,22 @@ static int fill_mailbox_circular_buffer(uint32_t header_cmd, uint32_t *args, } return MBOX_RET_OK; + +restart_mailbox: + /* + * Attempt to restart mailbox if the driver not able to write + * into mailbox command buffer + */ + if (MBOX_CMD_MASK(header_cmd) != MBOX_CMD_RESTART) { + INFO("Mailbox timed out: Attempting mailbox reset\n"); + ret = mailbox_init(); + + if (ret == MBOX_TIMEOUT) { + INFO("Error: Mailbox fail to restart\n"); + } + } + + return MBOX_TIMEOUT; } int mailbox_read_response(uint32_t *job_id, uint32_t *response, int resp_len) @@ -150,7 +166,7 @@ int mailbox_read_response(uint32_t *job_id, uint32_t *response, int resp_len) if (MBOX_RESP_ERR(resp_data) > 0) { INFO("Error in response: %x\n", resp_data); - return -resp_data; + return -MBOX_RESP_ERR(resp_data); } return ret_resp_len; -- cgit v1.2.3 From 9e285909ae02ba61ada6620f89c8575b2941e3b3 Mon Sep 17 00:00:00 2001 From: "Abdul Halim, Muhammad Hadi Asyrafi" Date: Tue, 1 Sep 2020 21:05:18 +0800 Subject: intel: mailbox: Fix non-MISRA compliant code This patch is used to fix remaining non compliant code for Intel SocFPGA's mailbox driver. These changes include: - adding integer literal for unsigned constant - fix non-boolean controlling expression - add braces even on conditional single statement bodies Signed-off-by: Abdul Halim, Muhammad Hadi Asyrafi Change-Id: I0f8fd96a3540f35ee102fd2f2369b76fa73e39e1 --- plat/intel/soc/common/soc/socfpga_mailbox.c | 79 +++++++++++++++++------------ 1 file changed, 46 insertions(+), 33 deletions(-) diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c index 9ba9b3171..29f3df28d 100644 --- a/plat/intel/soc/common/soc/socfpga_mailbox.c +++ b/plat/intel/soc/common/soc/socfpga_mailbox.c @@ -54,7 +54,7 @@ static int write_mailbox_cmd_buffer(uint32_t *cin, uint32_t cout, if (is_mailbox_cmdbuf_full(*cin)) { if (!(*is_doorbell_triggered)) { mmio_write_32(MBOX_OFFSET + - MBOX_DOORBELL_TO_SDM, 1); + MBOX_DOORBELL_TO_SDM, 1U); *is_doorbell_triggered = true; } mdelay(10U); @@ -108,7 +108,7 @@ static int fill_mailbox_circular_buffer(uint32_t header_cmd, uint32_t *args, } if (!is_doorbell_triggered) { - mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1); + mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1U); } return MBOX_RET_OK; @@ -137,8 +137,9 @@ int mailbox_read_response(uint32_t *job_id, uint32_t *response, int resp_len) int resp_data = 0; int ret_resp_len; - if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM)) - mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0); + if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM) == 1U) { + mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U); + } rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN); rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT); @@ -189,7 +190,7 @@ int mailbox_poll_response(uint32_t job_id, int urgent, uint32_t *response, do { if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM) - & 1) { + == 1U) { break; } mdelay(10U); @@ -199,18 +200,18 @@ int mailbox_poll_response(uint32_t job_id, int urgent, uint32_t *response, break; } - mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0); + mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U); - if (urgent & 1) { - mdelay(5); + if ((urgent & 1) != 0) { + mdelay(5U); if ((mmio_read_32(MBOX_OFFSET + MBOX_STATUS) & MBOX_STATUS_UA_MASK) ^ (urgent & MBOX_STATUS_UA_MASK)) { - mmio_write_32(MBOX_OFFSET + MBOX_URG, 0); + mmio_write_32(MBOX_OFFSET + MBOX_URG, 0U); return MBOX_RET_OK; } - mmio_write_32(MBOX_OFFSET + MBOX_URG, 0); + mmio_write_32(MBOX_OFFSET + MBOX_URG, 0U); INFO("Error: Mailbox did not get UA"); return MBOX_RET_ERROR; } @@ -226,8 +227,9 @@ int mailbox_poll_response(uint32_t job_id, int urgent, uint32_t *response, mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout); if (MBOX_RESP_CLIENT_ID(resp_data) != MBOX_ATF_CLIENT_ID - || MBOX_RESP_JOB_ID(resp_data) != job_id) + || MBOX_RESP_JOB_ID(resp_data) != job_id) { continue; + } ret_resp_len = MBOX_RESP_LEN(resp_data); @@ -308,7 +310,7 @@ int mailbox_send_cmd_async(uint32_t *job_id, unsigned int cmd, uint32_t *args, return status; } - *job_id = (*job_id + 1) % MBOX_MAX_IND_JOB_ID; + *job_id = (*job_id + 1U) % MBOX_MAX_IND_JOB_ID; return MBOX_RET_OK; } @@ -318,11 +320,11 @@ int mailbox_send_cmd(uint32_t job_id, unsigned int cmd, uint32_t *args, { int status = 0; - if (urgent) { + if (urgent != 0) { urgent |= mmio_read_32(MBOX_OFFSET + MBOX_STATUS) & MBOX_STATUS_UA_MASK; mmio_write_32(MBOX_OFFSET + MBOX_URG, cmd); - mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1); + mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1U); } else { @@ -333,8 +335,9 @@ int mailbox_send_cmd(uint32_t job_id, unsigned int cmd, uint32_t *args, cmd, args, len); } - if (status) + if (status != 0) { return status; + } status = mailbox_poll_response(job_id, urgent, response, resp_len); @@ -375,12 +378,12 @@ void mailbox_set_qspi_close(void) CMD_CASUAL, NULL, 0); } -void mailbox_qspi_set_cs(int device_select) +void mailbox_qspi_set_cs(uint32_t device_select) { - uint32_t cs_setting = device_select; + uint32_t cs_setting; /* QSPI device select settings at 31:28 */ - cs_setting = (cs_setting << 28); + cs_setting = (device_select << 28); mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE); mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_SET_CS, &cs_setting, 1, CMD_CASUAL, NULL, 0); @@ -415,18 +418,21 @@ int mailbox_rsu_status(uint32_t *resp_buf, uint32_t resp_buf_len) int ret; struct rsu_status_info *info = (struct rsu_status_info *)resp_buf; - info->retry_counter = ~0; + info->retry_counter = ~0U; ret = mailbox_send_cmd(MBOX_JOB_ID, MBOX_RSU_STATUS, NULL, 0, CMD_CASUAL, (uint32_t *)resp_buf, resp_buf_len); - if (ret < 0) + if (ret < 0) { return ret; + } - if (info->retry_counter != ~0) - if (!(info->version & RSU_VERSION_ACMF_MASK)) + if (info->retry_counter != ~0U) { + if ((info->version & RSU_VERSION_ACMF_MASK) == 0U) { info->version |= RSU_VERSION_ACMF; + } + } return ret; } @@ -451,14 +457,15 @@ int mailbox_init(void) mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE | MBOX_INT_FLAG_UAE); - mmio_write_32(MBOX_OFFSET + MBOX_URG, 0); - mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0); + mmio_write_32(MBOX_OFFSET + MBOX_URG, 0U); + mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U); - status = mailbox_send_cmd(0, MBOX_CMD_RESTART, NULL, 0, + status = mailbox_send_cmd(0U, MBOX_CMD_RESTART, NULL, 0, CMD_URGENT, NULL, 0); - if (status) + if (status != 0) { return status; + } mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE | MBOX_INT_FLAG_UAE); @@ -474,24 +481,29 @@ int intel_mailbox_get_config_status(uint32_t cmd) status = mailbox_send_cmd(MBOX_JOB_ID, cmd, NULL, 0, CMD_CASUAL, response, ARRAY_SIZE(response)); - if (status < 0) + if (status < 0) { return status; + } res = response[RECONFIG_STATUS_STATE]; - if (res && res != MBOX_CFGSTAT_STATE_CONFIG) + if ((res != 0U) && (res != MBOX_CFGSTAT_STATE_CONFIG)) { return res; + } res = response[RECONFIG_STATUS_PIN_STATUS]; - if (!(res & PIN_STATUS_NSTATUS)) + if ((res & PIN_STATUS_NSTATUS) == 0U) { return MBOX_CFGSTAT_STATE_ERROR_HARDWARE; + } res = response[RECONFIG_STATUS_SOFTFUNC_STATUS]; - if (res & SOFTFUNC_STATUS_SEU_ERROR) + if ((res & SOFTFUNC_STATUS_SEU_ERROR) != 0U) { return MBOX_CFGSTAT_STATE_ERROR_HARDWARE; + } - if ((res & SOFTFUNC_STATUS_CONF_DONE) && - (res & SOFTFUNC_STATUS_INIT_DONE)) + if ((res & SOFTFUNC_STATUS_CONF_DONE) != 0U && + (res & SOFTFUNC_STATUS_INIT_DONE) != 0U) { return MBOX_RET_OK; + } return MBOX_CFGSTAT_STATE_CONFIG; } @@ -500,8 +512,9 @@ int intel_mailbox_is_fpga_not_ready(void) { int ret = intel_mailbox_get_config_status(MBOX_RECONFIG_STATUS); - if (ret && ret != MBOX_CFGSTAT_STATE_CONFIG) + if ((ret != MBOX_RET_OK) && (ret != MBOX_CFGSTAT_STATE_CONFIG)) { ret = intel_mailbox_get_config_status(MBOX_CONFIG_STATUS); + } return ret; } -- cgit v1.2.3 From d57318b7c9584f1613c9223028ef8ea186d6d203 Mon Sep 17 00:00:00 2001 From: "Abdul Halim, Muhammad Hadi Asyrafi" Date: Thu, 15 Oct 2020 15:27:18 +0800 Subject: intel: common: Fix non-MISRA compliant code v2 This patch is used to fix remaining non compliant code for Intel SoCFPGA's mailbox and sip driver. These changes include: - Change non-interface required uint32_t into unsigned int - Change non-negative variable to unsigned int - Remove obsolete variable initialization to 0 Signed-off-by: Abdul Halim, Muhammad Hadi Asyrafi Change-Id: I3a16c7621a5fc75eb614d97d72e44c86e7d53bf5 --- plat/intel/soc/common/include/socfpga_mailbox.h | 19 ++-- plat/intel/soc/common/soc/socfpga_mailbox.c | 128 ++++++++++++------------ plat/intel/soc/common/socfpga_sip_svc.c | 14 +-- 3 files changed, 85 insertions(+), 76 deletions(-) diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h index 3a2bf309e..923c4f154 100644 --- a/plat/intel/soc/common/include/socfpga_mailbox.h +++ b/plat/intel/soc/common/include/socfpga_mailbox.h @@ -136,17 +136,22 @@ /* Mailbox Function Definitions */ -void mailbox_set_int(int interrupt_input); +void mailbox_set_int(uint32_t interrupt_input); int mailbox_init(void); void mailbox_set_qspi_close(void); void mailbox_set_qspi_open(void); void mailbox_set_qspi_direct(void); -int mailbox_send_cmd(uint32_t job_id, unsigned int cmd, uint32_t *args, - int len, int urgent, uint32_t *response, int resp_len); -int mailbox_send_cmd_async(uint32_t *job_id, unsigned int cmd, uint32_t *args, - int len, int indirect); -int mailbox_read_response(uint32_t *job_id, uint32_t *response, int resp_len); -int iterate_resp(int mbox_resp_len, uint32_t *resp_buf, int resp_len); + +int mailbox_send_cmd(uint32_t job_id, uint32_t cmd, uint32_t *args, + unsigned int len, uint32_t urgent, uint32_t *response, + unsigned int resp_len); +int mailbox_send_cmd_async(uint32_t *job_id, uint32_t cmd, uint32_t *args, + unsigned int len, unsigned int indirect); +int mailbox_read_response(uint32_t *job_id, uint32_t *response, + unsigned int resp_len); +unsigned int iterate_resp(uint32_t mbox_resp_len, uint32_t *resp_buf, + unsigned int resp_len); + void mailbox_reset_cold(void); void mailbox_clear_response(void); diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c index 29f3df28d..aec94af94 100644 --- a/plat/intel/soc/common/soc/socfpga_mailbox.c +++ b/plat/intel/soc/common/soc/socfpga_mailbox.c @@ -28,7 +28,7 @@ static bool is_mailbox_cmdbuf_empty(uint32_t cin) static int wait_for_mailbox_cmdbuf_empty(uint32_t cin) { - uint32_t timeout = 200U; + unsigned int timeout = 200U; do { if (is_mailbox_cmdbuf_empty(cin)) { @@ -48,7 +48,7 @@ static int write_mailbox_cmd_buffer(uint32_t *cin, uint32_t cout, uint32_t data, bool *is_doorbell_triggered) { - uint32_t timeout = 100U; + unsigned int timeout = 100U; do { if (is_mailbox_cmdbuf_full(*cin)) { @@ -81,10 +81,10 @@ static int write_mailbox_cmd_buffer(uint32_t *cin, uint32_t cout, } static int fill_mailbox_circular_buffer(uint32_t header_cmd, uint32_t *args, - int len) + unsigned int len) { uint32_t sdm_read_offset, cmd_free_offset; - uint32_t i; + unsigned int i; int ret; bool is_doorbell_triggered = false; @@ -130,12 +130,13 @@ restart_mailbox: return MBOX_TIMEOUT; } -int mailbox_read_response(uint32_t *job_id, uint32_t *response, int resp_len) +int mailbox_read_response(unsigned int *job_id, uint32_t *response, + unsigned int resp_len) { - int rin = 0; - int rout = 0; - int resp_data = 0; - int ret_resp_len; + uint32_t rin; + uint32_t rout; + uint32_t resp_data; + unsigned int ret_resp_len; if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM) == 1U) { mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U); @@ -146,7 +147,7 @@ int mailbox_read_response(uint32_t *job_id, uint32_t *response, int resp_len) if (rout != rin) { resp_data = mmio_read_32(MBOX_OFFSET + - MBOX_RESP_BUFFER + ((rout++)*4)); + MBOX_RESP_BUFFER + ((rout++)*4U)); rout %= MBOX_RESP_BUFFER_SIZE; mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout); @@ -160,12 +161,12 @@ int mailbox_read_response(uint32_t *job_id, uint32_t *response, int resp_len) ret_resp_len = MBOX_RESP_LEN(resp_data); - if (ret_resp_len != 0) { + if (ret_resp_len != 0U) { ret_resp_len = iterate_resp(ret_resp_len, response, resp_len); } - if (MBOX_RESP_ERR(resp_data) > 0) { + if (MBOX_RESP_ERR(resp_data) > 0U) { INFO("Error in response: %x\n", resp_data); return -MBOX_RESP_ERR(resp_data); } @@ -176,15 +177,15 @@ int mailbox_read_response(uint32_t *job_id, uint32_t *response, int resp_len) } -int mailbox_poll_response(uint32_t job_id, int urgent, uint32_t *response, - int resp_len) +int mailbox_poll_response(uint32_t job_id, uint32_t urgent, uint32_t *response, + unsigned int resp_len) { - uint32_t timeout = 40U; - uint32_t sdm_loop = 255U; - int rin = 0; - int rout = 0; - int resp_data = 0; - int ret_resp_len; + unsigned int timeout = 40U; + unsigned int sdm_loop = 255U; + unsigned int ret_resp_len; + uint32_t rin; + uint32_t rout; + uint32_t resp_data; while (sdm_loop != 0U) { @@ -202,7 +203,7 @@ int mailbox_poll_response(uint32_t job_id, int urgent, uint32_t *response, mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U); - if ((urgent & 1) != 0) { + if ((urgent & 1U) != 0U) { mdelay(5U); if ((mmio_read_32(MBOX_OFFSET + MBOX_STATUS) & MBOX_STATUS_UA_MASK) ^ @@ -221,7 +222,7 @@ int mailbox_poll_response(uint32_t job_id, int urgent, uint32_t *response, while (rout != rin) { resp_data = mmio_read_32(MBOX_OFFSET + - MBOX_RESP_BUFFER + ((rout++)*4)); + MBOX_RESP_BUFFER + ((rout++)*4U)); rout %= MBOX_RESP_BUFFER_SIZE; mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout); @@ -233,13 +234,13 @@ int mailbox_poll_response(uint32_t job_id, int urgent, uint32_t *response, ret_resp_len = MBOX_RESP_LEN(resp_data); - if (ret_resp_len != 0) { + if (ret_resp_len != 0U) { ret_resp_len = iterate_resp(ret_resp_len, response, resp_len); } - if (MBOX_RESP_ERR(resp_data) > 0) { + if (MBOX_RESP_ERR(resp_data) > 0U) { INFO("Error in response: %x\n", resp_data); return -MBOX_RESP_ERR(resp_data); } @@ -254,20 +255,22 @@ int mailbox_poll_response(uint32_t job_id, int urgent, uint32_t *response, return MBOX_TIMEOUT; } -int iterate_resp(int mbox_resp_len, uint32_t *resp_buf, int resp_len) +unsigned int iterate_resp(uint32_t mbox_resp_len, uint32_t *resp_buf, + unsigned int resp_len) { - uint32_t timeout; - int resp_data = 0, total_resp_len = 0; - int rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN); - int rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT); + unsigned int timeout, total_resp_len = 0U; + uint32_t resp_data; + uint32_t rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN); + uint32_t rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT); - while (mbox_resp_len > 0) { + while (mbox_resp_len > 0U) { timeout = 100U; mbox_resp_len--; resp_data = mmio_read_32(MBOX_OFFSET + MBOX_RESP_BUFFER + - (rout)*4); - if (resp_buf && resp_len) { + (rout)*4U); + + if ((resp_buf != NULL) && (resp_len != 0U)) { *(resp_buf + total_resp_len) = resp_data; resp_len--; @@ -285,7 +288,7 @@ int iterate_resp(int mbox_resp_len, uint32_t *resp_buf, int resp_len) break; } timeout--; - } while ((mbox_resp_len > 0) && (timeout != 0U)); + } while ((mbox_resp_len > 0U) && (timeout != 0U)); if (timeout == 0U) { INFO("Timed out waiting for SDM\n"); @@ -295,8 +298,8 @@ int iterate_resp(int mbox_resp_len, uint32_t *resp_buf, int resp_len) return total_resp_len; } -int mailbox_send_cmd_async(uint32_t *job_id, unsigned int cmd, uint32_t *args, - int len, int indirect) +int mailbox_send_cmd_async(uint32_t *job_id, uint32_t cmd, uint32_t *args, + unsigned int len, unsigned int indirect) { int status; @@ -315,12 +318,13 @@ int mailbox_send_cmd_async(uint32_t *job_id, unsigned int cmd, uint32_t *args, return MBOX_RET_OK; } -int mailbox_send_cmd(uint32_t job_id, unsigned int cmd, uint32_t *args, - int len, int urgent, uint32_t *response, int resp_len) +int mailbox_send_cmd(uint32_t job_id, uint32_t cmd, uint32_t *args, + unsigned int len, uint32_t urgent, uint32_t *response, + unsigned int resp_len) { int status = 0; - if (urgent != 0) { + if (urgent != 0U) { urgent |= mmio_read_32(MBOX_OFFSET + MBOX_STATUS) & MBOX_STATUS_UA_MASK; mmio_write_32(MBOX_OFFSET + MBOX_URG, cmd); @@ -350,7 +354,7 @@ void mailbox_clear_response(void) mmio_read_32(MBOX_OFFSET + MBOX_RIN)); } -void mailbox_set_int(int interrupt) +void mailbox_set_int(uint32_t interrupt) { mmio_write_32(MBOX_OFFSET+MBOX_INT, MBOX_COE_BIT(interrupt) | @@ -361,21 +365,21 @@ void mailbox_set_int(int interrupt) void mailbox_set_qspi_open(void) { mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE); - mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_OPEN, NULL, 0, - CMD_CASUAL, NULL, 0); + mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_OPEN, NULL, 0U, + CMD_CASUAL, NULL, 0U); } void mailbox_set_qspi_direct(void) { - mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_DIRECT, NULL, 0, - CMD_CASUAL, NULL, 0); + mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_DIRECT, NULL, 0U, + CMD_CASUAL, NULL, 0U); } void mailbox_set_qspi_close(void) { mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE); - mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_CLOSE, NULL, 0, - CMD_CASUAL, NULL, 0); + mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_CLOSE, NULL, 0U, + CMD_CASUAL, NULL, 0U); } void mailbox_qspi_set_cs(uint32_t device_select) @@ -386,20 +390,20 @@ void mailbox_qspi_set_cs(uint32_t device_select) cs_setting = (device_select << 28); mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE); mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_SET_CS, &cs_setting, - 1, CMD_CASUAL, NULL, 0); + 1U, CMD_CASUAL, NULL, 0U); } void mailbox_reset_cold(void) { mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE); - mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_REBOOT_HPS, NULL, 0, - CMD_CASUAL, NULL, 0); + mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_REBOOT_HPS, NULL, 0U, + CMD_CASUAL, NULL, 0U); } -int mailbox_rsu_get_spt_offset(uint32_t *resp_buf, uint32_t resp_buf_len) +int mailbox_rsu_get_spt_offset(uint32_t *resp_buf, unsigned int resp_buf_len) { return mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_SUBPARTITION_TABLE, - NULL, 0, CMD_CASUAL, (uint32_t *)resp_buf, + NULL, 0U, CMD_CASUAL, resp_buf, resp_buf_len); } @@ -413,15 +417,15 @@ struct rsu_status_info { uint32_t retry_counter; }; -int mailbox_rsu_status(uint32_t *resp_buf, uint32_t resp_buf_len) +int mailbox_rsu_status(uint32_t *resp_buf, unsigned int resp_buf_len) { int ret; struct rsu_status_info *info = (struct rsu_status_info *)resp_buf; info->retry_counter = ~0U; - ret = mailbox_send_cmd(MBOX_JOB_ID, MBOX_RSU_STATUS, NULL, 0, - CMD_CASUAL, (uint32_t *)resp_buf, + ret = mailbox_send_cmd(MBOX_JOB_ID, MBOX_RSU_STATUS, NULL, 0U, + CMD_CASUAL, resp_buf, resp_buf_len); if (ret < 0) { @@ -440,28 +444,28 @@ int mailbox_rsu_status(uint32_t *resp_buf, uint32_t resp_buf_len) int mailbox_rsu_update(uint32_t *flash_offset) { return mailbox_send_cmd(MBOX_JOB_ID, MBOX_RSU_UPDATE, - flash_offset, 2, - CMD_CASUAL, NULL, 0); + flash_offset, 2U, + CMD_CASUAL, NULL, 0U); } int mailbox_hps_stage_notify(uint32_t execution_stage) { return mailbox_send_cmd(MBOX_JOB_ID, MBOX_HPS_STAGE_NOTIFY, - &execution_stage, 1, CMD_CASUAL, - NULL, 0); + &execution_stage, 1U, CMD_CASUAL, + NULL, 0U); } int mailbox_init(void) { - int status = 0; + int status; mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE | MBOX_INT_FLAG_UAE); mmio_write_32(MBOX_OFFSET + MBOX_URG, 0U); mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U); - status = mailbox_send_cmd(0U, MBOX_CMD_RESTART, NULL, 0, - CMD_URGENT, NULL, 0); + status = mailbox_send_cmd(0U, MBOX_CMD_RESTART, NULL, 0U, + CMD_URGENT, NULL, 0U); if (status != 0) { return status; @@ -478,8 +482,8 @@ int intel_mailbox_get_config_status(uint32_t cmd) int status; uint32_t res, response[6]; - status = mailbox_send_cmd(MBOX_JOB_ID, cmd, NULL, 0, CMD_CASUAL, response, - ARRAY_SIZE(response)); + status = mailbox_send_cmd(MBOX_JOB_ID, cmd, NULL, 0U, CMD_CASUAL, + response, ARRAY_SIZE(response)); if (status < 0) { return status; diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c index d5789f247..86a44556a 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -60,7 +60,7 @@ static int intel_fpga_sdm_write_buffer(struct fpga_config_info *buffer) buffer->size_written += args[2]; mailbox_send_cmd_async(&send_id, MBOX_RECONFIG_DATA, args, - 3, CMD_INDIRECT); + 3U, CMD_INDIRECT); buffer->subblocks_sent++; max_blocks--; @@ -190,9 +190,9 @@ static int intel_fpga_config_start(uint32_t config_type) mailbox_clear_response(); - mailbox_send_cmd(1, MBOX_CMD_CANCEL, NULL, 0, CMD_CASUAL, NULL, 0); + mailbox_send_cmd(1U, MBOX_CMD_CANCEL, NULL, 0U, CMD_CASUAL, NULL, 0U); - status = mailbox_send_cmd(1, MBOX_RECONFIG, NULL, 0, CMD_CASUAL, + status = mailbox_send_cmd(1U, MBOX_RECONFIG, NULL, 0U, CMD_CASUAL, response, ARRAY_SIZE(response)); if (status < 0) @@ -351,7 +351,7 @@ uint32_t intel_secure_reg_update(uint64_t reg_addr, uint32_t mask, /* Intel Remote System Update (RSU) services */ uint64_t intel_rsu_update_address; -static uint32_t intel_rsu_status(uint64_t *respbuf, uint32_t respbuf_sz) +static uint32_t intel_rsu_status(uint64_t *respbuf, unsigned int respbuf_sz) { if (mailbox_rsu_status((uint32_t *)respbuf, respbuf_sz) < 0) return INTEL_SIP_SMC_RSU_ERROR; @@ -384,9 +384,9 @@ static uint32_t intel_rsu_retry_counter(uint32_t *respbuf, uint32_t respbuf_sz, } /* Mailbox services */ -static uint32_t intel_mbox_send_cmd(uint32_t cmd, uint32_t *args, int len, - int urgent, uint32_t *response, - int resp_len, int *mbox_status, +static uint32_t intel_mbox_send_cmd(uint32_t cmd, uint32_t *args, uint32_t len, + uint32_t urgent, uint32_t *response, + uint32_t resp_len, int *mbox_status, int *len_in_resp) { *len_in_resp = 0; -- cgit v1.2.3 From 2be491b1dc8deae73befd10d137d485c1a41d7f1 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Fri, 16 Oct 2020 18:19:03 +0100 Subject: aarch64/arm: Add compiler barrier to barrier instructions When issuing barrier instructions like DSB or DMB, we must make sure that the compiler does not undermine out efforts to fence off instructions. Currently the compiler is free to move the barrier instruction around, in respect to former or later memory access statements, which is not what we want. Add a compiler barrier to the inline assembly statement in our DEFINE_SYSOP_TYPE_FUNC macro, to make sure memory accesses are not reordered by the compiler. This is in line with Linux' definition: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/include/asm/barrier.h Since those instructions share a definition, apart from DSB and DMB this now also covers some TLBI instructions. Having a compiler barrier there also is useful, although we probably have stronger barriers in place already. Change-Id: If6fe97b13a562643a643efc507cb4aad29daa5b6 Reported-by: Alexandru Elisei Signed-off-by: Andre Przywara --- include/arch/aarch32/arch_helpers.h | 2 +- include/arch/aarch64/arch_helpers.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/arch/aarch32/arch_helpers.h b/include/arch/aarch32/arch_helpers.h index 94cf7ea9d..82efb188a 100644 --- a/include/arch/aarch32/arch_helpers.h +++ b/include/arch/aarch32/arch_helpers.h @@ -166,7 +166,7 @@ static inline void _op(void) \ #define DEFINE_SYSOP_TYPE_FUNC(_op, _type) \ static inline void _op ## _type(void) \ { \ - __asm__ (#_op " " #_type); \ + __asm__ (#_op " " #_type : : : "memory"); \ } /* Define function for system instruction with register parameter */ diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h index 1f2f4a923..5d1bc948c 100644 --- a/include/arch/aarch64/arch_helpers.h +++ b/include/arch/aarch64/arch_helpers.h @@ -80,7 +80,7 @@ static inline void _op(uint64_t v) \ #define DEFINE_SYSOP_TYPE_FUNC(_op, _type) \ static inline void _op ## _type(void) \ { \ - __asm__ (#_op " " #_type); \ + __asm__ (#_op " " #_type : : : "memory"); \ } /* Define function for system instruction with register parameter */ -- cgit v1.2.3 From b6cec337854b80c8ec3a36b0c7a82c531d59acac Mon Sep 17 00:00:00 2001 From: gtk_pangao Date: Thu, 19 Dec 2019 15:58:20 +0800 Subject: mediatek: mt8192: add sys_cirq driver 1.add sys_cirq driver 2.add gic api for cirq Change-Id: Ie6802d6ddcf7dde3412a050736dfdc85f97cb51b Signed-off-by: gtk_pangao --- plat/mediatek/mt8192/include/mt_gic_v3.h | 3 + plat/mediatek/mt8192/include/plat_mt_cirq.h | 82 +++++ plat/mediatek/mt8192/plat_mt_cirq.c | 494 ++++++++++++++++++++++++++++ plat/mediatek/mt8192/plat_mt_gic.c | 19 ++ plat/mediatek/mt8192/platform.mk | 1 + 5 files changed, 599 insertions(+) create mode 100644 plat/mediatek/mt8192/include/plat_mt_cirq.h create mode 100644 plat/mediatek/mt8192/plat_mt_cirq.c diff --git a/plat/mediatek/mt8192/include/mt_gic_v3.h b/plat/mediatek/mt8192/include/mt_gic_v3.h index 34ba8a7e3..c4ab44fa3 100644 --- a/plat/mediatek/mt8192/include/mt_gic_v3.h +++ b/plat/mediatek/mt8192/include/mt_gic_v3.h @@ -21,4 +21,7 @@ void mt_gic_rdistif_restore(void); void mt_gic_rdistif_restore_all(void); void gic_sgi_save_all(void); void gic_sgi_restore_all(void); +uint32_t mt_irq_get_pending(uint32_t irq); +void mt_irq_set_pending(uint32_t irq); + #endif /* MT_GIC_V3_H */ diff --git a/plat/mediatek/mt8192/include/plat_mt_cirq.h b/plat/mediatek/mt8192/include/plat_mt_cirq.h new file mode 100644 index 000000000..581860109 --- /dev/null +++ b/plat/mediatek/mt8192/include/plat_mt_cirq.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLAT_MT_CIRQ_H +#define PLAT_MT_CIRQ_H + +#define SYS_CIRQ_BASE U(0x10204000) +#define CIRQ_IRQ_NUM U(439) +#define CIRQ_SPI_START U(96) +/* + * Define hardware register + */ +#define CIRQ_STA_BASE U(0x000) +#define CIRQ_ACK_BASE U(0x080) +#define CIRQ_MASK_BASE U(0x100) +#define CIRQ_MASK_SET_BASE U(0x180) +#define CIRQ_MASK_CLR_BASE U(0x200) +#define CIRQ_SENS_BASE U(0x280) +#define CIRQ_SENS_SET_BASE U(0x300) +#define CIRQ_SENS_CLR_BASE U(0x380) +#define CIRQ_POL_BASE U(0x400) +#define CIRQ_POL_SET_BASE U(0x480) +#define CIRQ_POL_CLR_BASE U(0x500) +#define CIRQ_CON U(0x600) + +/* + * Register placement + */ +#define CIRQ_CON_EN_BITS U(0) +#define CIRQ_CON_EDGE_ONLY_BITS U(1) +#define CIRQ_CON_FLUSH_BITS U(2) +#define CIRQ_CON_EVENT_BITS U(31) +#define CIRQ_CON_SW_RST_BITS U(20) +#define CIRQ_CON_BITS_MASK U(0x7) + +/* + * Register setting + */ +#define CIRQ_CON_EN U(0x1) +#define CIRQ_CON_EDGE_ONLY U(0x1) +#define CIRQ_SW_RESET U(0x1) +#define CIRQ_CON_FLUSH U(0x1) + +/* + * Define constant + */ +#define CIRQ_CTRL_REG_NUM ((CIRQ_IRQ_NUM + 31U) / 32U) +#define MT_CIRQ_POL_NEG U(0) +#define MT_CIRQ_POL_POS U(1) +#define MT_CIRQ_EDGE_SENSITIVE U(0) +#define MT_CIRQ_LEVEL_SENSITIVE U(1) + +/* + * Define macro + */ +#define IRQ_TO_CIRQ_NUM(irq) ((irq) - (CIRQ_SPI_START)) +#define CIRQ_TO_IRQ_NUM(cirq) ((cirq) + (CIRQ_SPI_START)) + +/* + * Define cirq events + */ +struct cirq_events { + uint32_t spi_start; + uint32_t num_of_events; + uint32_t *wakeup_events; +}; + +/* + * Define function prototypes. + */ +void mt_cirq_enable(void); +void mt_cirq_disable(void); +void mt_cirq_clone_gic(void); +void mt_cirq_flush(void); +void mt_cirq_sw_reset(void); +void set_wakeup_sources(uint32_t *list, uint32_t num_of_events); +void mt_cirq_dump_reg(void); + +#endif /* PLAT_MT_CIRQ_H */ diff --git a/plat/mediatek/mt8192/plat_mt_cirq.c b/plat/mediatek/mt8192/plat_mt_cirq.c new file mode 100644 index 000000000..7fc060799 --- /dev/null +++ b/plat/mediatek/mt8192/plat_mt_cirq.c @@ -0,0 +1,494 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +static struct cirq_events cirq_all_events = { + .spi_start = CIRQ_SPI_START +}; + +static inline void mt_cirq_write32(uint32_t val, uint32_t addr) +{ + mmio_write_32(addr + SYS_CIRQ_BASE, val); +} + +static inline uint32_t mt_cirq_read32(uint32_t addr) +{ + return mmio_read_32(addr + SYS_CIRQ_BASE); +} + +/* + * cirq_clone_flush_check_store: + * set 1 if we need to enable clone/flush value's check + */ +static int32_t cirq_clone_flush_check_val; + +/* + * cirq_pattern_clone_flush_check_show: set 1 if we need to do pattern test. + */ +static int32_t cirq_pattern_clone_flush_check_val; + +/* + * cirq_pattern_clone_flush_check_show: set 1 if we need to do pattern test. + */ +static int32_t cirq_pattern_list; + +/* + * mt_cirq_ack_all: Ack all the interrupt on SYS_CIRQ + */ +void mt_cirq_ack_all(void) +{ + unsigned int i; + + for (i = 0U; i < CIRQ_CTRL_REG_NUM; i++) { + mt_cirq_write32(0xFFFFFFFF, CIRQ_ACK_BASE + (i * 4U)); + } + /* make sure all cirq setting take effect before doing other things */ + dmbsy(); +} + +/* + * mt_cirq_enable: Enable SYS_CIRQ + */ +void mt_cirq_enable(void) +{ + uint32_t st; + + mt_cirq_ack_all(); + + st = mt_cirq_read32(CIRQ_CON); + st |= (CIRQ_CON_EN << CIRQ_CON_EN_BITS) | + (CIRQ_CON_EDGE_ONLY << CIRQ_CON_EDGE_ONLY_BITS); + + mt_cirq_write32((st & CIRQ_CON_BITS_MASK), CIRQ_CON); +} + +/* + * mt_cirq_disable: Disable SYS_CIRQ + */ +void mt_cirq_disable(void) +{ + uint32_t st; + + st = mt_cirq_read32(CIRQ_CON); + st &= ~(CIRQ_CON_EN << CIRQ_CON_EN_BITS); + + mt_cirq_write32((st & CIRQ_CON_BITS_MASK), CIRQ_CON); +} + +/* + * mt_cirq_get_mask: Get the specified SYS_CIRQ mask + * @cirq_num: the SYS_CIRQ number to get + * @return: + * 1: this cirq is masked + * 0: this cirq is umasked + * 2: cirq num is out of range + */ +__attribute__((weak)) unsigned int mt_cirq_get_mask(uint32_t cirq_num) +{ + uint32_t st; + unsigned int val; + + if (cirq_num >= CIRQ_IRQ_NUM) { + ERROR("[CIRQ] %s: invalid cirq %u\n", __func__, cirq_num); + return 2; + } + + st = mt_cirq_read32((cirq_num / 32U) * 4U + CIRQ_MASK_BASE); + val = (st >> (cirq_num % 32U)) & 1U; + return val; +} + +/* + * mt_cirq_mask_all: Mask all interrupts on SYS_CIRQ. + */ +void mt_cirq_mask_all(void) +{ + unsigned int i; + + for (i = 0U; i < CIRQ_CTRL_REG_NUM; i++) { + mt_cirq_write32(0xFFFFFFFF, CIRQ_MASK_SET_BASE + (i * 4U)); + } + /* make sure all cirq setting take effect before doing other things */ + dmbsy(); +} + +/* + * mt_cirq_unmask_all: Unmask all interrupts on SYS_CIRQ. + */ +void mt_cirq_unmask_all(void) +{ + unsigned int i; + + for (i = 0U; i < CIRQ_CTRL_REG_NUM; i++) { + mt_cirq_write32(0xFFFFFFFF, CIRQ_MASK_CLR_BASE + (i * 4U)); + } + /* make sure all cirq setting take effect before doing other things */ + dmbsy(); +} + +/* + * mt_cirq_mask: Mask the specified SYS_CIRQ. + * @cirq_num: the SYS_CIRQ number to mask + * @return: + * 0: mask success + * -1: cirq num is out of range + */ +static int mt_cirq_mask(uint32_t cirq_num) +{ + uint32_t bit = 1U << (cirq_num % 32U); + + if (cirq_num >= CIRQ_IRQ_NUM) { + ERROR("[CIRQ] %s: invalid cirq %u\n", __func__, cirq_num); + return -1; + } + + mt_cirq_write32(bit, (cirq_num / 32U) * 4U + CIRQ_MASK_SET_BASE); + return 0; +} + +/* + * mt_cirq_unmask: Unmask the specified SYS_CIRQ. + * @cirq_num: the SYS_CIRQ number to unmask + * @return: + * 0: umask success + * -1: cirq num is out of range + */ +static int mt_cirq_unmask(uint32_t cirq_num) +{ + uint32_t bit = 1U << (cirq_num % 32U); + + if (cirq_num >= CIRQ_IRQ_NUM) { + ERROR("[CIRQ] %s: invalid cirq %u\n", __func__, cirq_num); + return -1; + } + + mt_cirq_write32(bit, (cirq_num / 32U) * 4U + CIRQ_MASK_CLR_BASE); + return 0; +} + +/* + * mt_cirq_set_sens: Set the sensitivity for the specified SYS_CIRQ number. + * @cirq_num: the SYS_CIRQ number to set + * @sens: sensitivity to set + * @return: + * 0: set sens success + * -1: cirq num is out of range + */ +static int mt_cirq_set_sens(uint32_t cirq_num, uint32_t sens) +{ + uint32_t base; + uint32_t bit = 1U << (cirq_num % 32U); + + if (cirq_num >= CIRQ_IRQ_NUM) { + ERROR("[CIRQ] %s: invalid cirq %u\n", __func__, cirq_num); + return -1; + } + + if (sens == MT_CIRQ_EDGE_SENSITIVE) { + base = (cirq_num / 32U) * 4U + CIRQ_SENS_CLR_BASE; + } else if (sens == MT_CIRQ_LEVEL_SENSITIVE) { + base = (cirq_num / 32U) * 4U + CIRQ_SENS_SET_BASE; + } else { + ERROR("[CIRQ] set_sens invalid sen value %u\n", sens); + return -1; + } + + mt_cirq_write32(bit, base); + return 0; +} + +/* + * mt_cirq_get_sens: Get the specified SYS_CIRQ sensitivity + * @cirq_num: the SYS_CIRQ number to get + * @return: + * 1: this cirq is MT_LEVEL_SENSITIVE + * 0: this cirq is MT_EDGE_SENSITIVE + * 2: cirq num is out of range + */ +__attribute__((weak)) unsigned int mt_cirq_get_sens(uint32_t cirq_num) +{ + uint32_t st; + unsigned int val; + + if (cirq_num >= CIRQ_IRQ_NUM) { + ERROR("[CIRQ] %s: invalid cirq %u\n", __func__, cirq_num); + return 2; + } + + st = mt_cirq_read32((cirq_num / 32U) * 4U + CIRQ_SENS_BASE); + val = (st >> (cirq_num % 32U)) & 1U; + return val; +} + +/* + * mt_cirq_set_pol: Set the polarity for the specified SYS_CIRQ number. + * @cirq_num: the SYS_CIRQ number to set + * @pol: polarity to set + * @return: + * 0: set pol success + * -1: cirq num is out of range + */ +static int mt_cirq_set_pol(uint32_t cirq_num, uint32_t pol) +{ + uint32_t base; + uint32_t bit = 1U << (cirq_num % 32U); + + if (cirq_num >= CIRQ_IRQ_NUM) { + ERROR("[CIRQ] %s: invalid cirq %u\n", __func__, cirq_num); + return -1; + } + + if (pol == MT_CIRQ_POL_NEG) { + base = (cirq_num / 32U) * 4U + CIRQ_POL_CLR_BASE; + } else if (pol == MT_CIRQ_POL_POS) { + base = (cirq_num / 32U) * 4U + CIRQ_POL_SET_BASE; + } else { + ERROR("[CIRQ] set_pol invalid polarity value %u\n", pol); + return -1; + } + + mt_cirq_write32(bit, base); + return 0; +} + +/* + * mt_cirq_get_pol: Get the specified SYS_CIRQ polarity + * @cirq_num: the SYS_CIRQ number to get + * @return: + * 1: this cirq is MT_CIRQ_POL_POS + * 0: this cirq is MT_CIRQ_POL_NEG + * 2: cirq num is out of range + */ +__attribute__((weak)) unsigned int mt_cirq_get_pol(uint32_t cirq_num) +{ + uint32_t st; + unsigned int val; + + if (cirq_num >= CIRQ_IRQ_NUM) { + ERROR("[CIRQ] %s: invalid cirq %u\n", __func__, cirq_num); + return 2; + } + + st = mt_cirq_read32((cirq_num / 32U) * 4U + CIRQ_POL_BASE); + val = (st >> (cirq_num % 32U)) & 1U; + return val; +} + +/* + * mt_cirq_get_pending: Get the specified SYS_CIRQ pending + * @cirq_num: the SYS_CIRQ number to get + * @return: + * 1: this cirq is pending + * 0: this cirq is not pending + * 2: cirq num is out of range + */ +static unsigned int mt_cirq_get_pending(uint32_t cirq_num) +{ + uint32_t st; + unsigned int val; + + if (cirq_num >= CIRQ_IRQ_NUM) { + ERROR("[CIRQ] %s: invalid cirq %u\n", __func__, cirq_num); + return 2; + } + + st = mt_cirq_read32((cirq_num / 32U) * 4U + CIRQ_STA_BASE); + val = (st >> (cirq_num % 32U)) & 1U; + return val; +} + +/* + * mt_cirq_clone_pol: Copy the polarity setting from GIC to SYS_CIRQ + */ +void mt_cirq_clone_pol(void) +{ + uint32_t cirq_num; + + for (cirq_num = 0U; cirq_num < CIRQ_IRQ_NUM; cirq_num++) { + mt_cirq_set_pol(cirq_num, MT_CIRQ_POL_POS); + } +} + +/* + * mt_cirq_clone_sens: Copy the sensitivity setting from GIC to SYS_CIRQ + */ +void mt_cirq_clone_sens(void) +{ + uint32_t cirq_num, irq_num; + uint32_t st, val; + + for (cirq_num = 0U; cirq_num < CIRQ_IRQ_NUM; cirq_num++) { + irq_num = CIRQ_TO_IRQ_NUM(cirq_num); + + if ((cirq_num == 0U) || (irq_num % 16U == 0U)) { + st = mmio_read_32(BASE_GICD_BASE + GICD_ICFGR + + (irq_num / 16U * 4U)); + } + + val = (st >> ((irq_num % 16U) * 2U)) & 0x2U; + + if (val) { + mt_cirq_set_sens(cirq_num, MT_CIRQ_EDGE_SENSITIVE); + } else { + mt_cirq_set_sens(cirq_num, MT_CIRQ_LEVEL_SENSITIVE); + } + } +} + +/* + * mt_cirq_clone_mask: Copy the mask setting from GIC to SYS_CIRQ + */ +void mt_cirq_clone_mask(void) +{ + uint32_t cirq_num, irq_num; + uint32_t st, val; + + for (cirq_num = 0U; cirq_num < CIRQ_IRQ_NUM; cirq_num++) { + irq_num = CIRQ_TO_IRQ_NUM(cirq_num); + + if ((cirq_num == 0U) || (irq_num % 32U == 0U)) { + st = mmio_read_32(BASE_GICD_BASE + + GICD_ISENABLER + (irq_num / 32U * 4U)); + } + + val = (st >> (irq_num % 32)) & 1U; + + if (val) { + mt_cirq_unmask(cirq_num); + } else { + mt_cirq_mask(cirq_num); + } + } +} + +/* + * mt_cirq_clone_gic: Copy the setting from GIC to SYS_CIRQ + */ +void mt_cirq_clone_gic(void) +{ + mt_cirq_clone_sens(); + mt_cirq_clone_mask(); +} + +/* + * mt_cirq_disable: Flush interrupt from SYS_CIRQ to GIC + */ +void mt_cirq_flush(void) +{ + unsigned int i; + unsigned char cirq_p_val = 0U; + unsigned char irq_p_val = 0U; + uint32_t irq_p = 0U; + unsigned char pass = 1U; + uint32_t first_cirq_found = 0U; + uint32_t first_flushed_cirq; + uint32_t first_irq_flushedto; + uint32_t last_fluashed_cirq; + uint32_t last_irq_flushedto; + + if (cirq_pattern_clone_flush_check_val == 1U) { + if (cirq_pattern_list < CIRQ_IRQ_NUM) { + mt_cirq_unmask(cirq_pattern_list); + mt_cirq_set_sens(cirq_pattern_list, + MT_CIRQ_EDGE_SENSITIVE); + mt_cirq_set_pol(cirq_pattern_list, MT_CIRQ_POL_NEG); + mt_cirq_set_pol(cirq_pattern_list, MT_CIRQ_POL_POS); + mt_cirq_set_pol(cirq_pattern_list, MT_CIRQ_POL_NEG); + } else { + ERROR("[CIRQ] no pattern to test,"); + ERROR("input pattern first\n"); + } + ERROR("[CIRQ] cirq_pattern %u, cirq_p %u,", + cirq_pattern_list, + mt_cirq_get_pending(cirq_pattern_list)); + ERROR("cirq_s %u, cirq_con 0x%x\n", + mt_cirq_get_sens(cirq_pattern_list), + mt_cirq_read32(CIRQ_CON)); + } + + mt_cirq_unmask_all(); + + for (i = 0U; i < CIRQ_IRQ_NUM; i++) { + cirq_p_val = mt_cirq_get_pending(i); + if (cirq_p_val) { + mt_irq_set_pending(CIRQ_TO_IRQ_NUM(i)); + } + + if (cirq_clone_flush_check_val == 1U) { + if (cirq_p_val == 0U) { + continue; + } + irq_p = CIRQ_TO_IRQ_NUM(i); + irq_p_val = mt_irq_get_pending(irq_p); + if (cirq_p_val != irq_p_val) { + ERROR("[CIRQ] CIRQ Flush Failed "); + ERROR("%u(cirq %d)!= %u(gic %d)\n", + cirq_p_val, i, irq_p_val, + CIRQ_TO_IRQ_NUM(i)); + pass = 0; + } else { + ERROR("[CIRQ] CIRQ Flush Pass "); + ERROR("%u(cirq %d) = %u(gic %d)\n", + cirq_p_val, i, irq_p_val, + CIRQ_TO_IRQ_NUM(i)); + } + if (!first_cirq_found) { + first_flushed_cirq = i; + first_irq_flushedto = irq_p; + first_cirq_found = 1U; + } + last_fluashed_cirq = i; + last_irq_flushedto = irq_p; + } + } + + if (cirq_clone_flush_check_val == 1U) { + if (first_cirq_found) { + ERROR("[CIRQ] The first flush : CIRQ%u to IRQ%u\n", + first_flushed_cirq, first_irq_flushedto); + ERROR("[CIRQ] The last flush : CIRQ%u to IRQ%u\n", + last_fluashed_cirq, last_irq_flushedto); + } else { + ERROR("[CIRQ] There are no pending "); + ERROR("interrupt in CIRQ\n"); + ERROR("[CIRQ] so no flush operation happened\n"); + } + ERROR("[CIRQ] The Flush Max Range : CIRQ"); + ERROR("%d to IRQ%d ~ CIRQ%d to IRQ%d\n", 0U, + CIRQ_TO_IRQ_NUM(0U), CIRQ_IRQ_NUM - 1U, + CIRQ_TO_IRQ_NUM(CIRQ_IRQ_NUM - 1U)); + ERROR("[CIRQ] Flush Check %s, Confirm:SPI_START_OFFSET:%d\n", + pass == 1 ? "Pass" : "Failed", CIRQ_SPI_START); + } + mt_cirq_mask_all(); + mt_cirq_ack_all(); +} + +void mt_cirq_sw_reset(void) +{ + uint32_t st; + + st = mt_cirq_read32(CIRQ_CON); + st |= (CIRQ_SW_RESET << CIRQ_CON_SW_RST_BITS); + + mt_cirq_write32(st, CIRQ_CON); +} + +void set_wakeup_sources(uint32_t *list, uint32_t num_of_events) +{ + cirq_all_events.num_of_events = num_of_events; + cirq_all_events.wakeup_events = list; +} diff --git a/plat/mediatek/mt8192/plat_mt_gic.c b/plat/mediatek/mt8192/plat_mt_gic.c index 593f5d04e..ae8d697a5 100644 --- a/plat/mediatek/mt8192/plat_mt_gic.c +++ b/plat/mediatek/mt8192/plat_mt_gic.c @@ -175,3 +175,22 @@ void mt_gic_init(void) gicv3_rdistif_init(plat_my_core_pos()); gicv3_cpuif_enable(plat_my_core_pos()); } + +uint32_t mt_irq_get_pending(uint32_t irq) +{ + uint32_t val; + + val = mmio_read_32(BASE_GICD_BASE + GICD_ISPENDR + + irq / 32 * 4); + val = (val >> (irq % 32)) & 1U; + return val; +} + + +void mt_irq_set_pending(uint32_t irq) +{ + uint32_t bit = 1U << (irq % 32); + + mmio_write_32(BASE_GICD_BASE + GICD_ISPENDR + + irq / 32 * 4, bit); +} diff --git a/plat/mediatek/mt8192/platform.mk b/plat/mediatek/mt8192/platform.mk index 0d732d50a..071700ee9 100644 --- a/plat/mediatek/mt8192/platform.mk +++ b/plat/mediatek/mt8192/platform.mk @@ -36,6 +36,7 @@ BL31_SOURCES += common/desc_image_load.c \ ${MTK_PLAT_SOC}/plat_pm.c \ ${MTK_PLAT_SOC}/plat_topology.c \ ${MTK_PLAT_SOC}/plat_mt_gic.c \ + ${MTK_PLAT_SOC}/plat_mt_cirq.c \ ${MTK_PLAT_SOC}/drivers/gpio/mtgpio.c -- cgit v1.2.3 From 0f408247292b6e49a4228dc7bd3941caf1db5dbc Mon Sep 17 00:00:00 2001 From: Nina Wu Date: Thu, 2 Jul 2020 12:10:13 +0800 Subject: mediatek: mt8192: Add reboot function for PSCI Add system_reset function in psci ops Change-Id: If85be70b8ae9d6487e02626356f0ff1e78b76de9 Signed-off-by: Nina Wu --- plat/mediatek/mt8192/plat_pm.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/plat/mediatek/mt8192/plat_pm.c b/plat/mediatek/mt8192/plat_pm.c index 81a170dd7..becf5d311 100644 --- a/plat/mediatek/mt8192/plat_pm.c +++ b/plat/mediatek/mt8192/plat_pm.c @@ -5,16 +5,36 @@ */ /* common headers */ +#include +#include +#include #include /* mediatek platform specific headers */ +#include +/******************************************************************************* + * MTK handlers to shutdown/reboot the system + ******************************************************************************/ +static void __dead2 plat_mtk_system_reset(void) +{ + struct bl_aux_gpio_info *gpio_reset = plat_get_mtk_gpio_reset(); + + INFO("MTK System Reset\n"); + + gpio_set_value(gpio_reset->index, gpio_reset->polarity); + + wfi(); + ERROR("MTK System Reset: operation not handled.\n"); + panic(); +} /******************************************************************************* * MTK_platform handler called when an affinity instance is about to be turned * on. The level and mpidr determine the affinity instance. ******************************************************************************/ static const plat_psci_ops_t plat_plat_pm_ops = { + .system_reset = plat_mtk_system_reset, }; int plat_setup_psci_ops(uintptr_t sec_entrypoint, -- cgit v1.2.3 From 4a128018b63ca9a4517eeefbe0c1c50b691ce433 Mon Sep 17 00:00:00 2001 From: Dehui Sun Date: Fri, 3 Jul 2020 09:19:06 +0800 Subject: mediatek: mt8192: add timer support add timer driver. Signed-off-by: Dehui Sun Change-Id: I07448d85a15bb14577b05e4f302860d609420ba7 --- plat/mediatek/mt8192/drivers/timer/mt_timer.c | 30 +++++++++++++++++++++++++++ plat/mediatek/mt8192/drivers/timer/mt_timer.h | 30 +++++++++++++++++++++++++++ plat/mediatek/mt8192/platform.mk | 6 ++++-- 3 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 plat/mediatek/mt8192/drivers/timer/mt_timer.c create mode 100644 plat/mediatek/mt8192/drivers/timer/mt_timer.h diff --git a/plat/mediatek/mt8192/drivers/timer/mt_timer.c b/plat/mediatek/mt8192/drivers/timer/mt_timer.c new file mode 100644 index 000000000..781f940b6 --- /dev/null +++ b/plat/mediatek/mt8192/drivers/timer/mt_timer.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + + +uint64_t normal_time_base; +uint64_t atf_time_base; + +void sched_clock_init(uint64_t normal_base, uint64_t atf_base) +{ + normal_time_base += normal_base; + atf_time_base = atf_base; +} + +uint64_t sched_clock(void) +{ + uint64_t cval; + uint64_t rel_base; + + rel_base = read_cntpct_el0() - atf_time_base; + cval = ((rel_base * 1000U) / SYS_COUNTER_FREQ_IN_MHZ) + - normal_time_base; + return cval; +} diff --git a/plat/mediatek/mt8192/drivers/timer/mt_timer.h b/plat/mediatek/mt8192/drivers/timer/mt_timer.h new file mode 100644 index 000000000..7aca4a3bf --- /dev/null +++ b/plat/mediatek/mt8192/drivers/timer/mt_timer.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MT_TIMER_H +#define MT_TIMER_H + +#define SYSTIMER_BASE (0x10017000) +#define CNTCR_REG (SYSTIMER_BASE + 0x0) +#define CNTSR_REG (SYSTIMER_BASE + 0x4) +#define CNTSYS_L_REG (SYSTIMER_BASE + 0x8) +#define CNTSYS_H_REG (SYSTIMER_BASE + 0xc) + +#define TIEO_EN (1 << 3) +#define COMP_15_EN (1 << 10) +#define COMP_20_EN (1 << 11) +#define COMP_25_EN (1 << 12) + +#define COMP_FEATURE_MASK (COMP_15_EN | COMP_20_EN | COMP_25_EN | TIEO_EN) +#define COMP_15_MASK (COMP_15_EN) +#define COMP_20_MASK (COMP_20_EN | TIEO_EN) +#define COMP_25_MASK (COMP_20_EN | COMP_25_EN) + + +void sched_clock_init(uint64_t normal_base, uint64_t atf_base); +uint64_t sched_clock(void); + +#endif /* MT_TIMER_H */ diff --git a/plat/mediatek/mt8192/platform.mk b/plat/mediatek/mt8192/platform.mk index 071700ee9..7544b2658 100644 --- a/plat/mediatek/mt8192/platform.mk +++ b/plat/mediatek/mt8192/platform.mk @@ -10,7 +10,8 @@ MTK_PLAT_SOC := ${MTK_PLAT}/${PLAT} PLAT_INCLUDES := -I${MTK_PLAT}/common/ \ -I${MTK_PLAT_SOC}/include/ \ -I${MTK_PLAT_SOC}/drivers/ \ - -I${MTK_PLAT_SOC}/drivers/gpio/ + -I${MTK_PLAT_SOC}/drivers/gpio/ \ + -I${MTK_PLAT_SOC}/drivers/timer/ GICV3_SUPPORT_GIC600 := 1 include drivers/arm/gic/v3/gicv3.mk @@ -37,7 +38,8 @@ BL31_SOURCES += common/desc_image_load.c \ ${MTK_PLAT_SOC}/plat_topology.c \ ${MTK_PLAT_SOC}/plat_mt_gic.c \ ${MTK_PLAT_SOC}/plat_mt_cirq.c \ - ${MTK_PLAT_SOC}/drivers/gpio/mtgpio.c + ${MTK_PLAT_SOC}/drivers/gpio/mtgpio.c \ + ${MTK_PLAT_SOC}/drivers/timer/mt_timer.c # Configs for A76 and A55 -- cgit v1.2.3 From 3ed5606bd1156e61241b57cb2dcceb90f75f6332 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 14 Oct 2020 15:17:49 +0100 Subject: Use constant stack size with RECLAIM_INIT_CODE Currently, when RECLAIM_INIT_CODE is set, the stacks are scaled to ensure that the entirety of the init section can be reclaimed as stack. This causes an issue in lib/psci/aarch64/psci_helpers.S, where the stack size is used for cache operations in psci_do_pwrdown_cache_maintenance(). If the stacks are scaled, then the PSCI code may fail to invalidate some of the stack memory before power down. Resizing stacks is also not good for stability in general, since code that works with a small number of cores may overflow the stack when the number of cores is increased. Change to make every stack be PLATFORM_STACK_SIZE big, and allow the total stack to be smaller than the init section. Any pages of the init section not reclaimed as stack will be set to read-only and execute-never, for security. Change-Id: I10b3884981006431f2fcbec3864c81d4a8c246e8 Signed-off-by: David Horstmann --- include/plat/arm/common/arm_reclaim_init.ld.S | 54 ++++++++------------------- plat/arm/common/arm_bl31_setup.c | 34 +++++++++++++++-- plat/common/aarch64/platform_mp_stack.S | 33 ---------------- 3 files changed, 46 insertions(+), 75 deletions(-) diff --git a/include/plat/arm/common/arm_reclaim_init.ld.S b/include/plat/arm/common/arm_reclaim_init.ld.S index e4d4f1254..717f65e2b 100644 --- a/include/plat/arm/common/arm_reclaim_init.ld.S +++ b/include/plat/arm/common/arm_reclaim_init.ld.S @@ -14,54 +14,30 @@ SECTIONS __INIT_CODE_START__ = .; *(*text.init*); __INIT_CODE_END__ = .; + INIT_CODE_END_ALIGNED = ALIGN(PAGE_SIZE); } >RAM #ifdef BL31_PROGBITS_LIMIT ASSERT(__INIT_CODE_END__ <= BL31_PROGBITS_LIMIT, "BL31 init has exceeded progbits limit.") #endif - - ASSERT(__INIT_CODE_END__ <= __STACKS_END__, - "Init code ends past the end of the stacks") - } -#undef MIN #define ABS ABSOLUTE -#define COUNT PLATFORM_CORE_COUNT -#define ALIGN_MASK ~(CACHE_WRITEBACK_GRANULE - 1) - -#define PRIMARY_STACK \ - __STACKS_START__ = .; \ - *(tzfw_normal_stacks) \ - OFFSET = ABS(SIZEOF(.init) - (. - __STACKS_START__)); \ - /* Offset sign */ \ - SIGN = ABS(OFFSET) & (1 << 63); \ - /* Offset mask */ \ - MASK = ABS(SIGN >> 63) - 1; \ - . += ABS(OFFSET) & ABS(MASK); \ - . = ALIGN(PAGE_SIZE); \ - __STACKS_END__ = .; \ - /* Total stack size */ \ - SIZE = ABS(. - __STACKS_START__); \ - /* Maximum primary CPU stack */ \ - STACK = ABS(__STACKS_START__ + SIZE / COUNT) & ALIGN_MASK; \ - /* Primary CPU stack */ \ - __PRIMARY_STACK__ = MIN(STACK, ABS(__INIT_CODE_START__)); -#if (COUNT > 1) -#define SECONDARY_STACK \ - /* Size of the secondary CPUs' stack */ \ - REST = ABS(__STACKS_END__ - __PRIMARY_STACK__); \ - /* Secondary per-CPU stack size */ \ - __STACK_SIZE__ = ABS(REST / (COUNT - 1)); -#else -#define SECONDARY_STACK -#endif - -#define STACK_SECTION \ - stacks (NOLOAD) : { \ - PRIMARY_STACK \ - SECONDARY_STACK \ +#define STACK_SECTION \ + stacks (NOLOAD) : { \ + __STACKS_START__ = .; \ + *(tzfw_normal_stacks) \ + __STACKS_END__ = .; \ + /* Allow room for the init section where necessary. */ \ + OFFSET = ABS(SIZEOF(.init) - (. - __STACKS_START__)); \ + /* Offset sign */ \ + SIGN = ABS(OFFSET) & (1 << 63); \ + /* Offset mask */ \ + MASK = ABS(SIGN >> 63) - 1; \ + . += ABS(OFFSET) & ABS(MASK); \ + . = ALIGN(PAGE_SIZE); \ } + #endif /* ARM_RECLAIM_INIT_LD_S */ diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c index fc238b1d8..81ef6e7b2 100644 --- a/plat/arm/common/arm_bl31_setup.c +++ b/plat/arm/common/arm_bl31_setup.c @@ -47,9 +47,12 @@ CASSERT(BL31_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl31_base_overflows); #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); +IMPORT_SYM(unsigned long, __STACKS_END__, BL_STACKS_END_UNALIGNED); #define BL_INIT_CODE_END ((BL_CODE_END_UNALIGNED + PAGE_SIZE - 1) & \ ~(PAGE_SIZE - 1)) +#define BL_STACKS_END ((BL_STACKS_END_UNALIGNED + PAGE_SIZE - 1) & \ + ~(PAGE_SIZE - 1)) #define MAP_BL_INIT_CODE MAP_REGION_FLAT( \ BL_INIT_CODE_BASE, \ @@ -291,14 +294,39 @@ void arm_bl31_plat_runtime_setup(void) #if RECLAIM_INIT_CODE /* - * Zero out and make RW memory used to store image boot time code so it can - * be reclaimed during runtime + * Make memory for image boot time code RW to reclaim it as stack for the + * secondary cores, or RO where it cannot be reclaimed: + * + * |-------- INIT SECTION --------| + * ----------------------------------------- + * | CORE 0 | CORE 1 | CORE 2 | EXTRA | + * | STACK | STACK | STACK | SPACE | + * ----------------------------------------- + * <-------------------> <------> + * MAKE RW AND XN MAKE + * FOR STACKS RO AND XN */ void arm_free_init_memory(void) { - int ret = xlat_change_mem_attributes(BL_INIT_CODE_BASE, + int ret = 0; + + if (BL_STACKS_END < BL_INIT_CODE_END) { + /* Reclaim some of the init section as stack if possible. */ + if (BL_INIT_CODE_BASE < BL_STACKS_END) { + ret |= xlat_change_mem_attributes(BL_INIT_CODE_BASE, + BL_STACKS_END - BL_INIT_CODE_BASE, + MT_RW_DATA); + } + /* Make the rest of the init section read-only. */ + ret |= xlat_change_mem_attributes(BL_STACKS_END, + BL_INIT_CODE_END - BL_STACKS_END, + MT_RO_DATA); + } else { + /* The stacks cover the init section, so reclaim it all. */ + ret |= xlat_change_mem_attributes(BL_INIT_CODE_BASE, BL_INIT_CODE_END - BL_INIT_CODE_BASE, MT_RW_DATA); + } if (ret != 0) { ERROR("Could not reclaim initialization code"); diff --git a/plat/common/aarch64/platform_mp_stack.S b/plat/common/aarch64/platform_mp_stack.S index ee0dbb4f6..c34a4cf3b 100644 --- a/plat/common/aarch64/platform_mp_stack.S +++ b/plat/common/aarch64/platform_mp_stack.S @@ -32,42 +32,9 @@ * ----------------------------------------------------- */ func plat_get_my_stack -#if (defined(IMAGE_BL31) && RECLAIM_INIT_CODE) -#if (PLATFORM_CORE_COUNT == 1) - /* Single CPU */ - adrp x0, __PRIMARY_STACK__ - add x0, x0, :lo12:__PRIMARY_STACK__ - ret -#else - mov x10, x30 - bl plat_my_core_pos - cbnz x0, 2f - - /* Primary CPU */ - adrp x0, __PRIMARY_STACK__ - add x0, x0, :lo12:__PRIMARY_STACK__ - ret x10 - - /* Secondary CPU */ -2: sub x0, x0, #(PLATFORM_CORE_COUNT - 1) - adrp x1, __STACKS_END__ - adrp x2, __STACK_SIZE__ - add x1, x1, :lo12:__STACKS_END__ - add x2, x2, :lo12:__STACK_SIZE__ - - madd x0, x0, x2, x1 - bic x0, x0, #(CACHE_WRITEBACK_GRANULE - 1) - ret x10 -#endif - /* Prevent linker from removal of stack section */ - .quad platform_normal_stacks - -#else /* !(IMAGE_BL31 && RECLAIM_INIT_CODE) */ mov x10, x30 get_my_mp_stack platform_normal_stacks, PLATFORM_STACK_SIZE ret x10 - -#endif /* IMAGE_BL31 && RECLAIM_INIT_CODE */ endfunc plat_get_my_stack /* ----------------------------------------------------- -- cgit v1.2.3 From 8cdb1693394a6be59eb1b404243e0bdfb3c1eba4 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Sun, 8 Nov 2020 17:38:57 +0000 Subject: make_helpers: tbbr: Fix FWU certificate generation Provide missed command line parameters such as KEY_ALG, HASH_ALG and KEY_SIZE while generating the FWU certificate. Signed-off-by: Gilad Ben Yossef Signed-off-by: Manish V Badarkhe Change-Id: I017fa3fff844f4262ae2441cbc9fee909d357fb3 --- make_helpers/tbbr/tbbr_tools.mk | 3 +++ 1 file changed, 3 insertions(+) diff --git a/make_helpers/tbbr/tbbr_tools.mk b/make_helpers/tbbr/tbbr_tools.mk index 9c92d3ffb..853ad11be 100644 --- a/make_helpers/tbbr/tbbr_tools.mk +++ b/make_helpers/tbbr/tbbr_tools.mk @@ -54,8 +54,11 @@ $(eval $(call TOOL_ADD_PAYLOAD,${FWU_CERT},--fwu-cert,,FWU_)) # packed in the FIP). Developers can use their own keys by specifying the proper # build option in the command line when building the Trusted Firmware $(if ${KEY_ALG},$(eval $(call CERT_ADD_CMD_OPT,${KEY_ALG},--key-alg))) +$(if ${KEY_ALG},$(eval $(call CERT_ADD_CMD_OPT,${KEY_ALG},--key-alg,FWU_))) $(if ${KEY_SIZE},$(eval $(call CERT_ADD_CMD_OPT,${KEY_SIZE},--key-size))) +$(if ${KEY_SIZE},$(eval $(call CERT_ADD_CMD_OPT,${KEY_SIZE},--key-size,FWU_))) $(if ${HASH_ALG},$(eval $(call CERT_ADD_CMD_OPT,${HASH_ALG},--hash-alg))) +$(if ${HASH_ALG},$(eval $(call CERT_ADD_CMD_OPT,${HASH_ALG},--hash-alg,FWU_))) $(if ${ROT_KEY},$(eval $(call CERT_ADD_CMD_OPT,${ROT_KEY},--rot-key))) $(if ${ROT_KEY},$(eval $(call CERT_ADD_CMD_OPT,${ROT_KEY},--rot-key,FWU_))) $(if ${PROT_KEY},$(eval $(call CERT_ADD_CMD_OPT,${PROT_KEY},--prot-key))) -- cgit v1.2.3 From c23cf053037ecc4521a7e03ba0100f1c78afd580 Mon Sep 17 00:00:00 2001 From: Mirela Simonovic Date: Fri, 24 Aug 2018 17:09:07 +0200 Subject: zynqmp: pm: Filter errors related to clock gate permissions Linux clock framework cannot properly deal with these errors. When the error is related to the lack of permissions to control the clock we filter the error and report the success to linux. Before recent changes in clock framework across the stack, this was done in the PMU-FW as a workaround. Since the PMU-FW now handles clocks and the permissions to control them using general principles rather than workarounds, it can no longer distinguish such exceptions and it has to return no-access error. Signed-off-by: Mirela Simonovic Acked-by: Will Wong Signed-off-by: Michal Simek Change-Id: I1491a80e472f44e322a542b29a20eb1cb3319802 --- plat/xilinx/zynqmp/pm_service/pm_api_sys.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c index b1720d9f6..cd9d597bf 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c +++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c @@ -907,7 +907,13 @@ static enum pm_ret_status pm_clock_gate(unsigned int clock_id, /* Send request to the PMU */ PM_PACK_PAYLOAD2(payload, api_id, clock_id); - return pm_ipi_send_sync(primary_proc, payload, NULL, 0); + status = pm_ipi_send_sync(primary_proc, payload, NULL, 0); + + /* If action fails due to the lack of permissions filter the error */ + if (status == PM_RET_ERROR_ACCESS) + status = PM_RET_SUCCESS; + + return status; } /** -- cgit v1.2.3 From a8b10c6490e5a4656bfa06fae5c0f19fabfe4ab2 Mon Sep 17 00:00:00 2001 From: Davorin Mista Date: Fri, 24 Aug 2018 17:09:06 +0200 Subject: zynqmp: pm: update error codes to match Linux and PMU Firmware All EEMI error codes start with value 2000. Note: Legacy error codes ARGS (=1) and NOTSUPPORTED (=4) returned by current ATF code have been left in place. Signed-off-by: Davorin Mista Acked-by: Will Wong Signed-off-by: Michal Simek Change-Id: I939afa85957cac88025d82a80f9f6dd49be993b6 --- plat/xilinx/zynqmp/pm_service/pm_defs.h | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/plat/xilinx/zynqmp/pm_service/pm_defs.h b/plat/xilinx/zynqmp/pm_service/pm_defs.h index cae36c9d8..4776d424b 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_defs.h +++ b/plat/xilinx/zynqmp/pm_service/pm_defs.h @@ -215,26 +215,29 @@ enum pm_opchar_type { /** * @PM_RET_SUCCESS: success - * @PM_RET_ERROR_ARGS: illegal arguments provided + * @PM_RET_ERROR_ARGS: illegal arguments provided (deprecated) + * @PM_RET_ERROR_NOTSUPPORTED: feature not supported (deprecated) + * @PM_RET_ERROR_INTERNAL: internal error + * @PM_RET_ERROR_CONFLICT: conflict * @PM_RET_ERROR_ACCESS: access rights violation + * @PM_RET_ERROR_INVALID_NODE: invalid node + * @PM_RET_ERROR_DOUBLE_REQ: duplicate request for same node + * @PM_RET_ERROR_ABORT_SUSPEND: suspend procedure has been aborted * @PM_RET_ERROR_TIMEOUT: timeout in communication with PMU - * @PM_RET_ERROR_NOTSUPPORTED: feature not supported - * @PM_RET_ERROR_PROC: node is not a processor node - * @PM_RET_ERROR_API_ID: illegal API ID - * @PM_RET_ERROR_OTHER: other error + * @PM_RET_ERROR_NODE_USED: node is already in use */ enum pm_ret_status { PM_RET_SUCCESS, - PM_RET_ERROR_ARGS, - PM_RET_ERROR_ACCESS, - PM_RET_ERROR_TIMEOUT, - PM_RET_ERROR_NOTSUPPORTED, - PM_RET_ERROR_PROC, - PM_RET_ERROR_API_ID, - PM_RET_ERROR_FAILURE, - PM_RET_ERROR_COMMUNIC, - PM_RET_ERROR_DOUBLEREQ, - PM_RET_ERROR_OTHER, + PM_RET_ERROR_ARGS = 1, + PM_RET_ERROR_NOTSUPPORTED = 4, + PM_RET_ERROR_INTERNAL = 2000, + PM_RET_ERROR_CONFLICT = 2001, + PM_RET_ERROR_ACCESS = 2002, + PM_RET_ERROR_INVALID_NODE = 2003, + PM_RET_ERROR_DOUBLE_REQ = 2004, + PM_RET_ERROR_ABORT_SUSPEND = 2005, + PM_RET_ERROR_TIMEOUT = 2006, + PM_RET_ERROR_NODE_USED = 2007 }; /** -- cgit v1.2.3 From e9930d42c7137043e2d8cafdd6913b9a957e5601 Mon Sep 17 00:00:00 2001 From: Venkatesh Yadav Abbarapu Date: Mon, 13 Jul 2020 21:18:01 -0600 Subject: plat: xilinx: Use fno-jump-tables flag in CPPFLAGS From GCC-9 implementation of switch case was generated through jump tables, because of which we are seeing 1MB increase in rodata section. To reduce the size we are recommending to use fno-jump-tables. Signed-off-by: Venkatesh Yadav Abbarapu Signed-off-by: Michal Simek Change-Id: I069733610809b8299fbf641f0ae35b359a8afd69 --- plat/xilinx/zynqmp/platform.mk | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk index 44f20f69f..194e72dc7 100644 --- a/plat/xilinx/zynqmp/platform.mk +++ b/plat/xilinx/zynqmp/platform.mk @@ -95,6 +95,8 @@ BL31_SOURCES += drivers/arm/cci/cci.c \ plat/xilinx/zynqmp/pm_service/pm_api_clock.c \ plat/xilinx/zynqmp/pm_service/pm_client.c +BL31_CPPFLAGS += -fno-jump-tables + ifneq (${RESET_TO_BL31},1) $(error "Using BL31 as the reset vector is only one option supported on ZynqMP. Please set RESET_TO_BL31 to 1.") endif -- cgit v1.2.3 From 942d0c7c1cb5a90dda2191b9dec5044cd95fdaa2 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 12 Nov 2020 11:19:48 +0100 Subject: Add myself and Venkatesh Yadav Abbarapu as code owners for Xilinx platforms Jolly left the company and Siva (DP) has moved to different possition that's why it is necessary to change code ownership. Signed-off-by: Michal Simek Change-Id: I546d9a0f7a2abd0c7a65be807725bc609160f3b2 --- docs/about/maintainers.rst | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst index ab2d3f9f8..f50093884 100644 --- a/docs/about/maintainers.rst +++ b/docs/about/maintainers.rst @@ -529,8 +529,10 @@ UniPhier platform port Xilinx platform port ^^^^^^^^^^^^^^^^^^^^ -:M: Siva Durga Prasad Paladugu -:G: `sivadur`_ +:M: Michal Simek +:G: `michalsimek`_ +:M: Venkatesh Yadav Abbarapu +:G: `venkatesh`_ :F: docs/plat/xilinx-zynqmp.rst :F: plat/xilinx/ @@ -614,6 +616,7 @@ Build system .. _ldts: https://github.com/ldts .. _marex: https://github.com/marex .. _masahir0y: https://github.com/masahir0y +.. _michalsimek: https://github.com/michalsimek .. _mmind: https://github.com/mmind .. _mtk09422: https://github.com/mtk09422 .. _niej: https://github.com/niej @@ -624,13 +627,13 @@ Build system .. _sandrine-bailleux-arm: https://github.com/sandrine-bailleux-arm .. _sgorecha: https://github.com/sgorecha .. _shawnguo2: https://github.com/shawnguo2 -.. _sivadur: https://github.com/sivadur .. _smaeul: https://github.com/smaeul .. _soby-mathew: https://github.com/soby-mathew .. _thloh85-intel: https://github.com/thloh85-intel .. _thomas-arm: https://github.com/thomas-arm .. _TonyXie06: https://github.com/TonyXie06 .. _vwadekar: https://github.com/vwadekar +.. _venkatesh: https://github.com/vabbarap .. _Yann-lms: https://github.com/Yann-lms .. _manish-pandey-arm: https://github.com/manish-pandey-arm .. _mardyk01: https://github.com/mardyk01 -- cgit v1.2.3 From 5d9101b39c441fb1bad5b6df9fddb0ee116141b2 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 12 Nov 2020 15:19:04 +0000 Subject: Fix typos and misspellings Fix a number of typos and misspellings in TF-A documentation and comments. Signed-off-by: David Horstmann Change-Id: I34c5a28c3af15f28d1ccada4d9866aee6af136ee --- docs/components/psa-ffa-manifest-binding.rst | 4 ++-- docs/getting_started/porting-guide.rst | 2 +- docs/process/coding-style.rst | 2 +- plat/common/aarch64/platform_mp_stack.S | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/components/psa-ffa-manifest-binding.rst b/docs/components/psa-ffa-manifest-binding.rst index 09894ae57..af79074af 100644 --- a/docs/components/psa-ffa-manifest-binding.rst +++ b/docs/components/psa-ffa-manifest-binding.rst @@ -13,7 +13,7 @@ Partition Properties - compatible [mandatory] - value type: - Must be the string "arm,ffa-manifest-X.Y" which specifies the major and - minor versions fo the device tree binding for the FFA manifest represented + minor versions of the device tree binding for the FFA manifest represented by this node. The minor number is incremented if the binding changes in a backwards compatible manner. @@ -240,7 +240,7 @@ Device Regions - exclusive-access - value type: - Presence of this field implies that this endpoint must be granted exclusive - access and ownership of this devices's MMIO region. + access and ownership of this device's MMIO region. -------------- diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst index 19e26e4ea..d063ec7e6 100644 --- a/docs/getting_started/porting-guide.rst +++ b/docs/getting_started/porting-guide.rst @@ -116,7 +116,7 @@ likely to be suitable for all platform ports. by ``plat/common/aarch64/platform_mp_stack.S`` and ``plat/common/aarch64/platform_up_stack.S``. -- **define : CACHE_WRITEBACK_GRANULE** +- **#define : CACHE_WRITEBACK_GRANULE** Defines the size in bits of the largest cache line across all the cache levels in the platform. diff --git a/docs/process/coding-style.rst b/docs/process/coding-style.rst index 94fd85e36..be13b14fa 100644 --- a/docs/process/coding-style.rst +++ b/docs/process/coding-style.rst @@ -101,7 +101,7 @@ Note that there is no space between the name of a function and the following parentheses. Control statements (``if``, ``for``, ``switch``, ``while``, etc) must be -separated from the following open paranthesis by a single space. The previous +separated from the following open parenthesis by a single space. The previous example illustrates this for an ``if`` statement. Line Length diff --git a/plat/common/aarch64/platform_mp_stack.S b/plat/common/aarch64/platform_mp_stack.S index c34a4cf3b..c0668ea78 100644 --- a/plat/common/aarch64/platform_mp_stack.S +++ b/plat/common/aarch64/platform_mp_stack.S @@ -14,7 +14,7 @@ .weak plat_set_my_stack /* --------------------------------------------------------------------- - * When the compatility layer is disabled, the platform APIs + * When the compatibility layer is disabled, the platform APIs * plat_get_my_stack() and plat_set_my_stack() are supported by the * platform and the previous APIs platform_get_stack() and * platform_set_stack() are defined in terms of new APIs making use of -- cgit v1.2.3 From 95ed9a9e0dd32710ed6845a24478bbe1bb9fd91a Mon Sep 17 00:00:00 2001 From: johpow01 Date: Thu, 12 Nov 2020 13:32:00 -0600 Subject: Revert workaround for A76 erratum 1800710 This errata workaround did not work as intended and was revised in subsequent SDEN releases so we are reverting this change. This is the patch being reverted: https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/4684 Signed-off-by: John Powell Change-Id: I560749a5b55e22fbe49d3f428a8b9545d6bdaaf0 --- docs/design/cpu-specific-build-macros.rst | 3 --- include/lib/cpus/aarch64/cortex_a76.h | 1 - lib/cpus/aarch64/cortex_a76.S | 35 ------------------------------- lib/cpus/cpu-ops.mk | 8 ------- 4 files changed, 47 deletions(-) diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst index c976b8b3a..5f3d69948 100644 --- a/docs/design/cpu-specific-build-macros.rst +++ b/docs/design/cpu-specific-build-macros.rst @@ -241,9 +241,6 @@ For Cortex-A76, the following errata build flags are defined : - ``ERRATA_A76_1791580``: This applies errata 1791580 workaround to Cortex-A76 CPU. This needs to be enabled only for revision <= r4p0 of the CPU. -- ``ERRATA_A76_1800710``: This applies errata 1800710 workaround to Cortex-A76 - CPU. This needs to be enabled only for revision <= r4p0 of the CPU. - - ``ERRATA_A76_1165522``: This applies errata 1165522 workaround to all revisions of Cortex-A76 CPU. This errata is fixed in r3p0 but due to limitation of errata framework this errata is applied to all revisions diff --git a/include/lib/cpus/aarch64/cortex_a76.h b/include/lib/cpus/aarch64/cortex_a76.h index b522e8e11..a61825f1b 100644 --- a/include/lib/cpus/aarch64/cortex_a76.h +++ b/include/lib/cpus/aarch64/cortex_a76.h @@ -20,7 +20,6 @@ #define CORTEX_A76_CPUECTLR_EL1_WS_THR_L2 (ULL(3) << 24) #define CORTEX_A76_CPUECTLR_EL1_BIT_51 (ULL(1) << 51) -#define CORTEX_A76_CPUECTLR_EL1_BIT_53 (ULL(1) << 53) /******************************************************************************* * CPU Auxiliary Control register specific definitions. diff --git a/lib/cpus/aarch64/cortex_a76.S b/lib/cpus/aarch64/cortex_a76.S index 98a11832d..2c99cdc92 100644 --- a/lib/cpus/aarch64/cortex_a76.S +++ b/lib/cpus/aarch64/cortex_a76.S @@ -381,35 +381,6 @@ func check_errata_1791580 b cpu_rev_var_ls endfunc check_errata_1791580 - /* -------------------------------------------------- - * Errata Workaround for Cortex A76 Errata #1800710. - * This applies to revision <= r4p0 of Cortex A76. - * Inputs: - * x0: variant[4:7] and revision[0:3] of current cpu. - * Shall clobber: x0-x17 - * -------------------------------------------------- - */ -func errata_a76_1800710_wa - /* Compare x0 against revision <= r4p0 */ - mov x17, x30 - bl check_errata_1800710 - cbz x0, 1f - - /* Disable allocation of splintered pages in the L2 TLB */ - mrs x1, CORTEX_A76_CPUECTLR_EL1 - orr x1, x1, CORTEX_A76_CPUECTLR_EL1_BIT_53 - msr CORTEX_A76_CPUECTLR_EL1, x1 - isb -1: - ret x17 -endfunc errata_a76_1800710_wa - -func check_errata_1800710 - /* Applies to everything <= r4p0 */ - mov x1, #0x40 - b cpu_rev_var_ls -endfunc check_errata_1800710 - /* -------------------------------------------------- * Errata Workaround for Cortex A76 Errata #1262606, * #1275112, and #1868343. #1262606 and #1275112 @@ -538,11 +509,6 @@ func cortex_a76_reset_func bl errata_a76_1791580_wa #endif -#if ERRATA_A76_1800710 - mov x0, x18 - bl errata_a76_1800710_wa -#endif - #if WORKAROUND_CVE_2018_3639 /* If the PE implements SSBS, we don't need the dynamic workaround */ mrs x0, id_aa64pfr1_el1 @@ -624,7 +590,6 @@ func cortex_a76_errata_report report_errata ERRATA_A76_1275112, cortex_a76, 1275112 report_errata ERRATA_A76_1286807, cortex_a76, 1286807 report_errata ERRATA_A76_1791580, cortex_a76, 1791580 - report_errata ERRATA_A76_1800710, cortex_a76, 1800710 report_errata ERRATA_A76_1165522, cortex_a76, 1165522 report_errata ERRATA_A76_1868343, cortex_a76, 1868343 report_errata WORKAROUND_CVE_2018_3639, cortex_a76, cve_2018_3639 diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk index 12105388f..7575051e5 100644 --- a/lib/cpus/cpu-ops.mk +++ b/lib/cpus/cpu-ops.mk @@ -270,10 +270,6 @@ ERRATA_A76_1286807 ?=0 # only to revision <= r4p0 of the Cortex A76 cpu. ERRATA_A76_1791580 ?=0 -# Flag to apply erratum 1800710 workaround during reset. This erratum applies -# only to revision <= r4p0 of the Cortex A76 cpu. -ERRATA_A76_1800710 ?=0 - # Flag to apply erratum 1165522 workaround during reset. This erratum applies # to all revisions of Cortex A76 cpu. ERRATA_A76_1165522 ?=0 @@ -555,10 +551,6 @@ $(eval $(call add_define,ERRATA_A76_1286807)) $(eval $(call assert_boolean,ERRATA_A76_1791580)) $(eval $(call add_define,ERRATA_A76_1791580)) -# Process ERRATA_A76_1800710 flag -$(eval $(call assert_boolean,ERRATA_A76_1800710)) -$(eval $(call add_define,ERRATA_A76_1800710)) - # Process ERRATA_A76_1165522 flag $(eval $(call assert_boolean,ERRATA_A76_1165522)) $(eval $(call add_define,ERRATA_A76_1165522)) -- cgit v1.2.3 From 9bbc03a6e0608a949d66d9da6db12a455b452bfb Mon Sep 17 00:00:00 2001 From: johpow01 Date: Thu, 12 Nov 2020 14:15:41 -0600 Subject: Revert workaround for A77 erratum 1800714 This errata workaround did not work as intended and was revised in subsequent SDEN releases so we are reverting this change. This is the patch being reverted: https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/4686 Signed-off-by: John Powell Change-Id: I8554c75d7217331c7effd781b5f7f49b781bbebe --- docs/design/cpu-specific-build-macros.rst | 3 --- include/lib/cpus/aarch64/cortex_a77.h | 1 - lib/cpus/aarch64/cortex_a77.S | 35 ------------------------------- lib/cpus/cpu-ops.mk | 8 ------- 4 files changed, 47 deletions(-) diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst index 5f3d69948..c0fda78dd 100644 --- a/docs/design/cpu-specific-build-macros.rst +++ b/docs/design/cpu-specific-build-macros.rst @@ -254,9 +254,6 @@ For Cortex-A77, the following errata build flags are defined : - ``ERRATA_A77_1508412``: This applies errata 1508412 workaround to Cortex-A77 CPU. This needs to be enabled only for revision <= r1p0 of the CPU. -- ``ERRATA_A77_1800714``: This applies errata 1800714 workaround to Cortex-A77 - CPU. This needs to be enabled only for revision <= r1p1 of the CPU. - - ``ERRATA_A77_1925769``: This applies errata 1925769 workaround to Cortex-A77 CPU. This needs to be enabled only for revision <= r1p1 of the CPU. diff --git a/include/lib/cpus/aarch64/cortex_a77.h b/include/lib/cpus/aarch64/cortex_a77.h index ed84c0f4a..0a42a5d77 100644 --- a/include/lib/cpus/aarch64/cortex_a77.h +++ b/include/lib/cpus/aarch64/cortex_a77.h @@ -17,7 +17,6 @@ ******************************************************************************/ #define CORTEX_A77_CPUECTLR_EL1 S3_0_C15_C1_4 #define CORTEX_A77_CPUECTLR_EL1_BIT_8 (ULL(1) << 8) -#define CORTEX_A77_CPUECTLR_EL1_BIT_53 (ULL(1) << 53) /******************************************************************************* * CPU Power Control register specific definitions. diff --git a/lib/cpus/aarch64/cortex_a77.S b/lib/cpus/aarch64/cortex_a77.S index 04a610e49..e3a6f5fbf 100644 --- a/lib/cpus/aarch64/cortex_a77.S +++ b/lib/cpus/aarch64/cortex_a77.S @@ -85,35 +85,6 @@ func check_errata_1508412_0 b cpu_rev_var_ls endfunc check_errata_1508412_0 - /* -------------------------------------------------- - * Errata Workaround for Cortex A77 Errata #1800714. - * This applies to revision <= r1p1 of Cortex A77. - * Inputs: - * x0: variant[4:7] and revision[0:3] of current cpu. - * Shall clobber: x0-x17 - * -------------------------------------------------- - */ -func errata_a77_1800714_wa - /* Compare x0 against revision <= r1p1 */ - mov x17, x30 - bl check_errata_1800714 - cbz x0, 1f - - /* Disable allocation of splintered pages in the L2 TLB */ - mrs x1, CORTEX_A77_CPUECTLR_EL1 - orr x1, x1, CORTEX_A77_CPUECTLR_EL1_BIT_53 - msr CORTEX_A77_CPUECTLR_EL1, x1 - isb -1: - ret x17 -endfunc errata_a77_1800714_wa - -func check_errata_1800714 - /* Applies to everything <= r1p1 */ - mov x1, #0x11 - b cpu_rev_var_ls -endfunc check_errata_1800714 - /* -------------------------------------------------- * Errata Workaround for Cortex A77 Errata #1925769. * This applies to revision <= r1p1 of Cortex A77. @@ -158,11 +129,6 @@ func cortex_a77_reset_func bl errata_a77_1508412_wa #endif -#if ERRATA_A77_1800714 - mov x0, x18 - bl errata_a77_1800714_wa -#endif - #if ERRATA_A77_1925769 mov x0, x18 bl errata_a77_1925769_wa @@ -202,7 +168,6 @@ func cortex_a77_errata_report * checking functions of each errata. */ report_errata ERRATA_A77_1508412, cortex_a77, 1508412 - report_errata ERRATA_A77_1800714, cortex_a77, 1800714 report_errata ERRATA_A77_1925769, cortex_a77, 1925769 ldp x8, x30, [sp], #16 diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk index 7575051e5..4126105aa 100644 --- a/lib/cpus/cpu-ops.mk +++ b/lib/cpus/cpu-ops.mk @@ -282,10 +282,6 @@ ERRATA_A76_1868343 ?=0 # only to revision <= r1p0 of the Cortex A77 cpu. ERRATA_A77_1508412 ?=0 -# Flag to apply erratum 1800714 workaround during reset. This erratum applies -# only to revision <= r1p1 of the Cortex A77 cpu. -ERRATA_A77_1800714 ?=0 - # Flag to apply erratum 1925769 workaround during reset. This erratum applies # only to revision <= r1p1 of the Cortex A77 cpu. ERRATA_A77_1925769 ?=0 @@ -563,10 +559,6 @@ $(eval $(call add_define,ERRATA_A76_1868343)) $(eval $(call assert_boolean,ERRATA_A77_1508412)) $(eval $(call add_define,ERRATA_A77_1508412)) -# Process ERRATA_A77_1800714 flag -$(eval $(call assert_boolean,ERRATA_A77_1800714)) -$(eval $(call add_define,ERRATA_A77_1800714)) - # Process ERRATA_A77_1925769 flag $(eval $(call assert_boolean,ERRATA_A77_1925769)) $(eval $(call add_define,ERRATA_A77_1925769)) -- cgit v1.2.3 From caff3c87245cab1c95c4f2958144d8f78f42685e Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Fri, 13 Nov 2020 12:36:49 +0000 Subject: TSP: Fix GCC 11.0.0 compilation error. This patch fixes the following compilation error reported by aarch64-none-elf-gcc 11.0.0: bl32/tsp/tsp_main.c: In function 'tsp_smc_handler': bl32/tsp/tsp_main.c:393:9: error: 'tsp_get_magic' accessing 32 bytes in a region of size 16 [-Werror=stringop-overflow=] 393 | tsp_get_magic(service_args); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ bl32/tsp/tsp_main.c:393:9: note: referencing argument 1 of type 'uint64_t *' {aka 'long long unsigned int *'} In file included from bl32/tsp/tsp_main.c:19: bl32/tsp/tsp_private.h:64:6: note: in a call to function 'tsp_get_magic' 64 | void tsp_get_magic(uint64_t args[4]); | ^~~~~~~~~~~~~ by changing declaration of tsp_get_magic function from void tsp_get_magic(uint64_t args[4]); to uint128_t tsp_get_magic(void); which returns arguments directly in x0 and x1 registers. In bl32\tsp\tsp_main.c the current tsp_smc_handler() implementation calls tsp_get_magic(service_args); , where service_args array is declared as uint64_t service_args[2]; and tsp_get_magic() in bl32\tsp\aarch64\tsp_request.S copies only 2 registers in output buffer: /* Store returned arguments to the array */ stp x0, x1, [x4, #0] Change-Id: Ib34759fc5d7bb803e6c734540d91ea278270b330 Signed-off-by: Alexei Fedorov --- bl32/tsp/aarch64/tsp_request.S | 13 ++----------- bl32/tsp/tsp_main.c | 30 +++++++++++++++++------------- bl32/tsp/tsp_private.h | 4 ++-- 3 files changed, 21 insertions(+), 26 deletions(-) diff --git a/bl32/tsp/aarch64/tsp_request.S b/bl32/tsp/aarch64/tsp_request.S index 5ad16da66..6e238ea4c 100644 --- a/bl32/tsp/aarch64/tsp_request.S +++ b/bl32/tsp/aarch64/tsp_request.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,28 +9,19 @@ .globl tsp_get_magic - /* * This function raises an SMC to retrieve arguments from secure * monitor/dispatcher, saves the returned arguments the array received in x0, * and then returns to the caller */ func tsp_get_magic - /* Save address to stack */ - stp x0, xzr, [sp, #-16]! - /* Load arguments */ ldr w0, _tsp_fid_get_magic /* Raise SMC */ smc #0 - /* Restore address from stack */ - ldp x4, xzr, [sp], #16 - - /* Store returned arguments to the array */ - stp x0, x1, [x4, #0] - + /* Return arguments in x1:x0 */ ret endfunc tsp_get_magic diff --git a/bl32/tsp/tsp_main.c b/bl32/tsp/tsp_main.c index e9478380c..01c9ec58f 100644 --- a/bl32/tsp/tsp_main.c +++ b/bl32/tsp/tsp_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -363,8 +363,10 @@ tsp_args_t *tsp_smc_handler(uint64_t func, uint64_t arg6, uint64_t arg7) { + uint128_t service_args; + uint64_t service_arg0; + uint64_t service_arg1; uint64_t results[2]; - uint64_t service_args[2]; uint32_t linear_id = plat_my_core_pos(); /* Update this cpu's statistics */ @@ -387,10 +389,12 @@ tsp_args_t *tsp_smc_handler(uint64_t func, results[1] = arg2; /* - * Request a service back from dispatcher/secure monitor. This call - * return and thereafter resume execution + * Request a service back from dispatcher/secure monitor. + * This call returns and thereafter resumes execution. */ - tsp_get_magic(service_args); + service_args = tsp_get_magic(); + service_arg0 = (uint64_t)service_args; + service_arg1 = (uint64_t)(service_args >> 64U); #if CTX_INCLUDE_MTE_REGS /* @@ -403,20 +407,20 @@ tsp_args_t *tsp_smc_handler(uint64_t func, /* Determine the function to perform based on the function ID */ switch (TSP_BARE_FID(func)) { case TSP_ADD: - results[0] += service_args[0]; - results[1] += service_args[1]; + results[0] += service_arg0; + results[1] += service_arg1; break; case TSP_SUB: - results[0] -= service_args[0]; - results[1] -= service_args[1]; + results[0] -= service_arg0; + results[1] -= service_arg1; break; case TSP_MUL: - results[0] *= service_args[0]; - results[1] *= service_args[1]; + results[0] *= service_arg0; + results[1] *= service_arg1; break; case TSP_DIV: - results[0] /= service_args[0] ? service_args[0] : 1; - results[1] /= service_args[1] ? service_args[1] : 1; + results[0] /= service_arg0 ? service_arg0 : 1; + results[1] /= service_arg1 ? service_arg1 : 1; break; default: break; diff --git a/bl32/tsp/tsp_private.h b/bl32/tsp/tsp_private.h index cbd527f37..38d9732f5 100644 --- a/bl32/tsp/tsp_private.h +++ b/bl32/tsp/tsp_private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -61,7 +61,7 @@ typedef struct tsp_args { */ CASSERT(TSP_ARGS_SIZE == sizeof(tsp_args_t), assert_sp_args_size_mismatch); -void tsp_get_magic(uint64_t args[4]); +uint128_t tsp_get_magic(void); tsp_args_t *tsp_cpu_resume_main(uint64_t max_off_pwrlvl, uint64_t arg1, -- cgit v1.2.3 From 0bd1a2e94ddad15c6423b619864ed7dc3b63e134 Mon Sep 17 00:00:00 2001 From: Chris Kay Date: Thu, 29 Oct 2020 14:28:59 +0000 Subject: docs: Update changelog for v2.4 release Change-Id: I67c9db2fc6d4b83fec2d001745b9305102d4a2ae Signed-off-by: Chris Kay --- docs/change-log.rst | 556 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 555 insertions(+), 1 deletion(-) diff --git a/docs/change-log.rst b/docs/change-log.rst index 7befba437..3b8f8365c 100644 --- a/docs/change-log.rst +++ b/docs/change-log.rst @@ -4,6 +4,560 @@ 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.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 ----------- @@ -32,7 +586,7 @@ New Features - 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 + - 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. -- cgit v1.2.3 From 5edddf3a0fd8d5d1775552081bcf18b311e5f4d3 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Thu, 8 Oct 2020 02:33:17 +0100 Subject: Makefile: Update the minor version to indicate 2.4 release Updated the minor version to '4' to indicate 2.4 release Change-Id: Ib142fa15baeb43025fae371c7649199b8121c18f Signed-off-by: Manish V Badarkhe --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 961423826..5c9186ece 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ # Trusted Firmware Version # VERSION_MAJOR := 2 -VERSION_MINOR := 3 +VERSION_MINOR := 4 # Default goal is build all images .DEFAULT_GOAL := all -- cgit v1.2.3 From c6a7ab7787ccc2d1c916918a0b8c470321d41448 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Thu, 29 Oct 2020 16:44:45 +0100 Subject: plat: marvell: armada: a3k: Add support for building $(DOIMAGETOOL) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Current binary wtptp/linux/tbb_linux which is specified in $(DOIMAGETOOL) variable points to external pre-compiled Marvell x86_64 ELF linux binary from A3700-utils-marvell WTP repository. It means that currently it is not possible to compile TF-A for A3720 on other host platform then linux x86_64. Part of the A3700-utils-marvell WTP repository is also source code of $(DOIMAGETOOL) TBB_Linux tool. This change adds support for building $(DOIMAGETOOL) also for a3k platform. After running $(MAKE) at appropriate subdirectory of A3700-utils-marvell WTP repository, compiled TBB_linux tool will appear in WTP subdirectory wtptp/src/TBB_Linux/release/. So update also $(DOIMAGETOOL) variable to point to the correct location where TBB_linux was built. To build TBB_linux it is required to compile external Crypto++ library which is available at: https://github.com/weidai11/cryptopp.git User needs to set CRYPTOPP_PATH option to specify path to that library. After this change it is now possible to build whole firmware for A3720 platform without requirement to use pre-compiled/proprietary x86_64 executable binaries from Marvell. Signed-off-by: Pali Rohár Change-Id: I6f26bd4356778a2f8f730a223067a2e550e6c8e0 --- plat/marvell/armada/a3k/common/a3700_common.mk | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk index 2050d59b6..001443c6f 100644 --- a/plat/marvell/armada/a3k/common/a3700_common.mk +++ b/plat/marvell/armada/a3k/common/a3700_common.mk @@ -65,7 +65,7 @@ BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \ ifneq (${WTP},) DOIMAGEPATH := $(WTP) -DOIMAGETOOL := $(DOIMAGEPATH)/wtptp/linux/tbb_linux +DOIMAGETOOL := $(DOIMAGEPATH)/wtptp/src/TBB_Linux/release/TBB_linux include plat/marvell/marvell.mk @@ -120,6 +120,11 @@ TIMBLDUARTARGS := $(MARVELL_SECURE_BOOT) UART $(IMAGESPATH) $(DOIMAGEPATH) $(CL $(DDR_TOPOLOGY) 0 0 $(DOIMAGE_CFG) $(TIMNCFG) $(TIMNSIG) 0 DOIMAGE_FLAGS := -r $(DOIMAGE_CFG) -v -D +$(DOIMAGETOOL): + $(if $(value CRYPTOPP_PATH),,$(error "Platform '${PLAT}' for WTP image tool requires CRYPTOPP_PATH. Please set CRYPTOPP_PATH to point to the right directory")) + $(Q)$(MAKE) --no-print-directory -C $(CRYPTOPP_PATH) -f GNUmakefile + $(Q)$(MAKE) --no-print-directory -C $(DOIMAGEPATH)/wtptp/src/TBB_Linux -f TBB_linux.mak LIBDIR=$(CRYPTOPP_PATH) + mrvl_flash: ${BUILD_PLAT}/${FIP_NAME} ${DOIMAGETOOL} $(shell truncate -s %128K ${BUILD_PLAT}/bl1.bin) $(shell cat ${BUILD_PLAT}/bl1.bin ${BUILD_PLAT}/${FIP_NAME} > ${BUILD_PLAT}/${BOOT_IMAGE}) -- cgit v1.2.3 From 91bc2da73c474ad285666c5461b48e0568db6ddc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Thu, 29 Oct 2020 16:50:19 +0100 Subject: plat: marvell: armada: Add new target mrvl_bootimage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This new target builds boot-image.bin binary as described in documentation. This image does not contain WTMI image and therefore WTP repository is not required for building. Having ability to build just this boot-image.bin binary without full flash-image.bin is useful for A3720 Turris MOX board which does not use Marvell's WTP and a3700_utils. To reduce duplicity between a8k and a3k code, define this new target and also definitions for $(BUILD_PLAT)/$(BOOT_IMAGE) in common include file marvell_common.mk. For this purpose it is needed to include plat/marvell/marvell.mk file from a3700_common.mk unconditionally (and not only when WTP is defined). Now when common file plat/marvell/marvell.mk does not contain definition for building $(DOIMAGETOOL), it is possible to move its inclusion at the top of the a3700_common.mk file. Signed-off-by: Pali Rohár Change-Id: Ic58303b37a1601be9a06ff83b7a279cb7cfc8280 --- plat/marvell/armada/a3k/common/a3700_common.mk | 9 +++------ plat/marvell/armada/a8k/common/a8k_common.mk | 4 +--- plat/marvell/armada/common/marvell_common.mk | 9 +++++++++ 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk index 001443c6f..5e2f8e299 100644 --- a/plat/marvell/armada/a3k/common/a3700_common.mk +++ b/plat/marvell/armada/a3k/common/a3700_common.mk @@ -15,6 +15,8 @@ MARVELL_DRV_BASE := drivers/marvell MARVELL_COMMON_BASE := $(MARVELL_PLAT_BASE)/common HANDLE_EA_EL3_FIRST := 1 +include plat/marvell/marvell.mk + #*********** A3700 ************* # GICV3 @@ -67,8 +69,6 @@ ifneq (${WTP},) DOIMAGEPATH := $(WTP) DOIMAGETOOL := $(DOIMAGEPATH)/wtptp/src/TBB_Linux/release/TBB_linux -include plat/marvell/marvell.mk - ifeq ($(MARVELL_SECURE_BOOT),1) DOIMAGE_CFG := $(DOIMAGEPATH)/atf-tim.txt IMAGESPATH := $(DOIMAGEPATH)/tim/trusted @@ -125,10 +125,7 @@ $(DOIMAGETOOL): $(Q)$(MAKE) --no-print-directory -C $(CRYPTOPP_PATH) -f GNUmakefile $(Q)$(MAKE) --no-print-directory -C $(DOIMAGEPATH)/wtptp/src/TBB_Linux -f TBB_linux.mak LIBDIR=$(CRYPTOPP_PATH) -mrvl_flash: ${BUILD_PLAT}/${FIP_NAME} ${DOIMAGETOOL} - $(shell truncate -s %128K ${BUILD_PLAT}/bl1.bin) - $(shell cat ${BUILD_PLAT}/bl1.bin ${BUILD_PLAT}/${FIP_NAME} > ${BUILD_PLAT}/${BOOT_IMAGE}) - $(shell truncate -s %4 ${BUILD_PLAT}/${BOOT_IMAGE}) +mrvl_flash: ${BUILD_PLAT}/${BOOT_IMAGE} ${DOIMAGETOOL} $(if $(value MV_DDR_PATH),,$(error "Platform '${PLAT}' for target '$@' requires MV_DDR_PATH. Please set MV_DDR_PATH to point to the right directory")) ${Q}${MAKE} --no-print-directory -C ${DOIMAGEPATH} WTMI_IMG=$(WTMI_IMG) MV_DDR_PATH=$(MV_DDR_PATH) $(shell truncate -s %4 $(WTMI_IMG)) diff --git a/plat/marvell/armada/a8k/common/a8k_common.mk b/plat/marvell/armada/a8k/common/a8k_common.mk index c8273265e..58394a46f 100644 --- a/plat/marvell/armada/a8k/common/a8k_common.mk +++ b/plat/marvell/armada/a8k/common/a8k_common.mk @@ -160,8 +160,6 @@ ${DOIMAGETOOL}: mrvl_clean @$(DOIMAGE_LIBS_CHECK) ${Q}${MAKE} --no-print-directory -C ${DOIMAGEPATH} -mrvl_flash: ${BUILD_PLAT}/${FIP_NAME} ${DOIMAGETOOL} ${BUILD_PLAT}/ble.bin - $(shell truncate -s %128K ${BUILD_PLAT}/bl1.bin) - $(shell cat ${BUILD_PLAT}/bl1.bin ${BUILD_PLAT}/${FIP_NAME} > ${BUILD_PLAT}/${BOOT_IMAGE}) +mrvl_flash: ${BUILD_PLAT}/${BOOT_IMAGE} ${DOIMAGETOOL} ${DOIMAGETOOL} ${DOIMAGE_FLAGS} ${BUILD_PLAT}/${BOOT_IMAGE} ${BUILD_PLAT}/${FLASH_IMAGE} diff --git a/plat/marvell/armada/common/marvell_common.mk b/plat/marvell/armada/common/marvell_common.mk index af149fa08..7f8dffa00 100644 --- a/plat/marvell/armada/common/marvell_common.mk +++ b/plat/marvell/armada/common/marvell_common.mk @@ -85,3 +85,12 @@ endif ifeq (${MSS_SUPPORT}, 1) include $(MARVELL_PLAT_BASE)/common/mss/mss_common.mk endif + +$(BUILD_PLAT)/$(BOOT_IMAGE): $(BUILD_PLAT)/bl1.bin $(BUILD_PLAT)/$(FIP_NAME) + @cp $(BUILD_PLAT)/bl1.bin $(BUILD_PLAT)/$(BOOT_IMAGE) || { rm -f $(BUILD_PLAT)/$(BOOT_IMAGE); false; } + @truncate -s %128K $(BUILD_PLAT)/$(BOOT_IMAGE) || { rm -f $(BUILD_PLAT)/$(BOOT_IMAGE); false; } + @cat $(BUILD_PLAT)/$(FIP_NAME) >> $(BUILD_PLAT)/$(BOOT_IMAGE) || { rm -f $(BUILD_PLAT)/$(BOOT_IMAGE); false; } + @truncate -s %4 $(BUILD_PLAT)/$(BOOT_IMAGE) || { rm -f $(BUILD_PLAT)/$(BOOT_IMAGE); false; } + @echo "Built $@ successfully" + +mrvl_bootimage: $(BUILD_PLAT)/$(BOOT_IMAGE) -- cgit v1.2.3 From f20cb7e54e152863a8cba9cc4802fb9381a317ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Thu, 29 Oct 2020 17:44:27 +0100 Subject: docs: marvell: Update build documentation to reflect mrvl_bootimage and mrvl_flash changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also add example how to build TF-A for A3720 Turris MOX board and also fix style/indentation issues and information about default values. Signed-off-by: Pali Rohár Change-Id: I2dc957307b1b627b403a8d960e85f5ac9e15aee5 --- docs/plat/marvell/armada/build.rst | 107 +++++++++++++++++++++++-------------- 1 file changed, 66 insertions(+), 41 deletions(-) diff --git a/docs/plat/marvell/armada/build.rst b/docs/plat/marvell/armada/build.rst index e21fb3cfb..54182cb08 100644 --- a/docs/plat/marvell/armada/build.rst +++ b/docs/plat/marvell/armada/build.rst @@ -61,17 +61,17 @@ There are several build options: Defines the level of logging which will be purged to the default output port. - LOG_LEVEL_NONE 0 - LOG_LEVEL_ERROR 10 - LOG_LEVEL_NOTICE 20 - LOG_LEVEL_WARNING 30 - LOG_LEVEL_INFO 40 - LOG_LEVEL_VERBOSE 50 + - 0 - LOG_LEVEL_NONE + - 10 - LOG_LEVEL_ERROR + - 20 - LOG_LEVEL_NOTICE (default for DEBUG=0) + - 30 - LOG_LEVEL_WARNING + - 40 - LOG_LEVEL_INFO (default for DEBUG=1) + - 50 - LOG_LEVEL_VERBOSE - USE_COHERENT_MEM This flag determines whether to include the coherent memory region in the - BL memory map or not. + BL memory map or not. Enabled by default. - LLC_ENABLE @@ -122,25 +122,25 @@ There are several build options: For Armada37x0 only, the DDR topology map index/name, default is 0. Supported Options: - - DDR3 1CS (0): DB-88F3720-DDR3-Modular (512MB); EspressoBIN (512MB) - - DDR4 1CS (1): DB-88F3720-DDR4-Modular (512MB) - - DDR3 2CS (2): EspressoBIN V3-V5 (1GB 2CS) - - DDR4 2CS (3): DB-88F3720-DDR4-Modular (4GB) - - DDR3 1CS (4): DB-88F3720-DDR3-Modular (1GB); EspressoBIN V3-V5 (1GB 1CS) - - DDR4 1CS (5): EspressoBin V7 (1GB) - - DDR4 2CS (6): EspressoBin V7 (2GB) - - DDR3 2CS (7): EspressoBin V3-V5 (2GB) - - CUSTOMER (CUST): Customer board, DDR3 1CS 512MB + - 0 - DDR3 1CS: DB-88F3720-DDR3-Modular (512MB); EspressoBIN (512MB) + - 1 - DDR4 1CS: DB-88F3720-DDR4-Modular (512MB) + - 2 - DDR3 2CS: EspressoBIN V3-V5 (1GB 2CS) + - 3 - DDR4 2CS: DB-88F3720-DDR4-Modular (4GB) + - 4 - DDR3 1CS: DB-88F3720-DDR3-Modular (1GB); EspressoBIN V3-V5 (1GB 1CS) + - 5 - DDR4 1CS: EspressoBin V7 (1GB) + - 6 - DDR4 2CS: EspressoBin V7 (2GB) + - 7 - DDR3 2CS: EspressoBin V3-V5 (2GB) + - CUST - CUSTOMER: Customer board, DDR3 1CS 512MB - CLOCKSPRESET For Armada37x0 only, the clock tree configuration preset including CPU and DDR frequency, default is CPU_800_DDR_800. - - CPU_600_DDR_600 - CPU at 600 MHz, DDR at 600 MHz - - CPU_800_DDR_800 - CPU at 800 MHz, DDR at 800 MHz - - CPU_1000_DDR_800 - CPU at 1000 MHz, DDR at 800 MHz - - CPU_1200_DDR_750 - CPU at 1200 MHz, DDR at 750 MHz + - CPU_600_DDR_600 - CPU at 600 MHz, DDR at 600 MHz + - CPU_800_DDR_800 - CPU at 800 MHz, DDR at 800 MHz + - CPU_1000_DDR_800 - CPU at 1000 MHz, DDR at 800 MHz + - CPU_1200_DDR_750 - CPU at 1200 MHz, DDR at 750 MHz - BOOTDEV @@ -176,33 +176,48 @@ There are several build options: - WTP - For Armada37x0 only, use this parameter to point to wtptools source code - directory, which can be found as a3700_utils.zip in the release. Usage - example: ``WTP=/path/to/a3700_utils`` + For Armada37x0 only, use this parameter to point to wtptools source code + directory, which can be found as a3700_utils.zip in the release. Usage + example: ``WTP=/path/to/a3700_utils`` - For example, in order to build the image in debug mode with log level up to 'notice' level run +- CRYPTOPP_PATH - .. code:: shell + For Armada37x0 only, use this parameter tp point to Crypto++ source code + directory, which is required for building WTP image tool. - > make DEBUG=1 USE_COHERENT_MEM=0 LOG_LEVEL=20 PLAT= all fip - And if we want to build a Armada37x0 image in debug mode with log level up to 'notice' level, - the image has the preset CPU at 1000 MHz, preset DDR3 at 800 MHz, the DDR topology of DDR4 2CS, - the image boot from SPI NOR flash partition 0, and the image is non trusted in WTP, the command - line is as following +For example, in order to build the image in debug mode with log level up to 'notice' level run - .. code:: shell +.. code:: shell + + > make DEBUG=1 USE_COHERENT_MEM=0 LOG_LEVEL=20 PLAT= mrvl_flash + +And if we want to build a Armada37x0 image in debug mode with log level up to 'notice' level, +the image has the preset CPU at 1000 MHz, preset DDR3 at 800 MHz, the DDR topology of DDR4 2CS, +the image boot from SPI NOR flash partition 0, and the image is non trusted in WTP, the command +line is as following + +.. code:: shell + + > make DEBUG=1 USE_COHERENT_MEM=0 LOG_LEVEL=20 CLOCKSPRESET=CPU_1000_DDR_800 \ + MARVELL_SECURE_BOOT=0 DDR_TOPOLOGY=3 BOOTDEV=SPINOR PARTNUM=0 PLAT=a3700 \ + MV_DDR_PATH=/path/to/mv-ddr-marvell/ WTP=/path/to/A3700-utils-marvell/ \ + CRYPTOPP_PATH=/path/to/cryptopp/ BL33=/path/to/u-boot.bin \ + all fip mrvl_bootimage mrvl_flash - > make DEBUG=1 USE_COHERENT_MEM=0 LOG_LEVEL=20 CLOCKSPRESET=CPU_1000_DDR_800 \ - MARVELL_SECURE_BOOT=0 DDR_TOPOLOGY=3 BOOTDEV=SPINOR PARTNUM=0 PLAT=a3700 all fip +To build just TF-A without WTMI image (useful for A3720 Turris MOX board), run following command: - Supported MARVELL_PLATFORM are: - - a3700 (for both A3720 DB and EspressoBin) - - a70x0 - - a70x0_amc (for AMC board) - - a80x0 - - a80x0_mcbin (for MacchiatoBin) - - t9130 (OcteonTX2 CN913x) +.. code:: shell + + > make USE_COHERENT_MEM=0 PLAT=a3700 BL33=/path/to/u-boot.bin CROSS_COMPILE=aarch64-linux-gnu- mrvl_bootimage + +Supported MARVELL_PLATFORM are: + - a3700 (for both A3720 DB and EspressoBin) + - a70x0 + - a70x0_amc (for AMC board) + - a80x0 + - a80x0_mcbin (for MacchiatoBin) + - t9130 (OcteonTX2 CN913x) Special Build Flags -------------------- @@ -224,7 +239,7 @@ For more information about build options, please refer to the Build output ------------ -Marvell's TF-A compilation generates 7 files: +Marvell's TF-A compilation generates 8 files: - ble.bin - BLe image - bl1.bin - BL1 image @@ -234,6 +249,12 @@ Marvell's TF-A compilation generates 7 files: - boot-image.bin - TF-A image (contains BL1 and FIP images) - flash-image.bin - Image which contains boot-image.bin and SPL image. Should be placed on the boot flash/device. + - uart-images.tgz.bin - GZIPed TAR archive which contains Armada37x0 images + for booting via UART. Could be loaded via Marvell's WtpDownload tool from + A3700-utils-marvell repository. + +Additional make target ``mrvl_bootimage`` produce ``boot-image.bin`` file and target +``mrvl_flash`` produce final ``flash-image.bin`` and ``uart-images.tgz.bin`` files. Tools and external components installation @@ -269,6 +290,10 @@ Armada37x0 Builds require installation of 3 components https://github.com/MarvellEmbeddedProcessors/A3700-utils-marvell.git +(4) Crypto++ library available at the following repository: + + https://github.com/weidai11/cryptopp.git + Armada70x0 and Armada80x0 Builds require installation of an additional component ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- cgit v1.2.3 From d22db1b050d7a5bb3d28751aab342d723bf8536d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Tue, 10 Nov 2020 16:34:48 +0100 Subject: plat: marvell: Update SUBVERSION to match Marvell's forked version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Marvell's TF-A fork has SUBVERSION set to devel-18.12.2. The only differences between Marvell's devel-18.12.0 and devel-18.12.2 versions are documentation updates and cherry-picked patches from TF-A upstream repository. So upstream TF-A has already all changes from Marvell's TF-A devel-18.12.2 fork and therefore update SUBVERSION to reflect this state. Signed-off-by: Pali Rohár Change-Id: I5ce946a5176a5cbf124acd8037392463d586b072 --- plat/marvell/version.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/marvell/version.mk b/plat/marvell/version.mk index e072e12d5..bb2225537 100644 --- a/plat/marvell/version.mk +++ b/plat/marvell/version.mk @@ -1 +1 @@ -SUBVERSION = devel-18.12.0 +SUBVERSION = devel-18.12.2 -- cgit v1.2.3 From 7a0f795ee716c5d26bcfd994288e35e2b193b5df Mon Sep 17 00:00:00 2001 From: Saurabh Gorecha Date: Fri, 20 Nov 2020 01:05:47 +0530 Subject: plat:qti Mandate SMC implementaion renamed smcc api with correct name plat_is_smccc_feature_available Change-Id: I277ece02bffc2caa065256576c1a047dfcde1c92 Signed-off-by: Saurabh Gorecha --- plat/qti/common/src/qti_common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plat/qti/common/src/qti_common.c b/plat/qti/common/src/qti_common.c index 9355eb774..da0eaec44 100644 --- a/plat/qti/common/src/qti_common.c +++ b/plat/qti/common/src/qti_common.c @@ -176,14 +176,14 @@ int32_t plat_get_soc_revision(void) } /***************************************************************************** - * plat_smccc_feature_available() - This function checks whether SMCCC feature + * plat_is_smccc_feature_available() - This function checks whether SMCCC feature * is availabile for the platform or not. * @fid: SMCCC function id * * Return SMC_ARCH_CALL_SUCCESS if SMCCC feature is available and * SMC_ARCH_CALL_NOT_SUPPORTED otherwise. *****************************************************************************/ -int32_t plat_smccc_feature_available(u_register_t fid) +int32_t plat_is_smccc_feature_available(u_register_t fid) { switch (fid) { case SMCCC_ARCH_SOC_ID: -- cgit v1.2.3 From 840fa94aa3a5d3e90a3546ab030304053213d473 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Thu, 19 Nov 2020 19:52:41 +0000 Subject: plat/nvidia: tegra: Rename SMC API Renamed SMC API from "plat_smccc_feature_available" to "plat_is_smccc_feature_available" as per the current implementation. Signed-off-by: Manish V Badarkhe Change-Id: Ib0fa400816fba61039c2029a9e127501a6a36811 --- plat/nvidia/tegra/common/tegra_platform.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plat/nvidia/tegra/common/tegra_platform.c b/plat/nvidia/tegra/common/tegra_platform.c index 7c73e8fe1..d45d9886f 100644 --- a/plat/nvidia/tegra/common/tegra_platform.c +++ b/plat/nvidia/tegra/common/tegra_platform.c @@ -297,14 +297,14 @@ int32_t plat_get_soc_revision(void) } /***************************************************************************** - * plat_smccc_feature_available() - This function checks whether SMCCC feature + * plat_is_smccc_feature_available() - This function checks whether SMCCC feature * is availabile for the platform or not. * @fid: SMCCC function id * * Return SMC_ARCH_CALL_SUCCESS if SMCCC feature is available and * SMC_ARCH_CALL_NOT_SUPPORTED otherwise. *****************************************************************************/ -int32_t plat_smccc_feature_available(u_register_t fid) +int32_t plat_is_smccc_feature_available(u_register_t fid) { switch (fid) { case SMCCC_ARCH_SOC_ID: -- cgit v1.2.3 From 5f14ca993759178cca1b10c614b545e60930c5c6 Mon Sep 17 00:00:00 2001 From: Tanmay Jagdale Date: Fri, 20 Nov 2020 16:36:50 +0530 Subject: plat/qemu_sbsa: Include libraries for Cortex-A72 Include libraries needed to emulate Cortex-A72 on sbsa-ref target of QEMU. Signed-off-by: Tanmay Jagdale Change-Id: I98cf17b1662c70898977a841af07e07b5cfca8ba --- plat/qemu/qemu_sbsa/platform.mk | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plat/qemu/qemu_sbsa/platform.mk b/plat/qemu/qemu_sbsa/platform.mk index 9be56a392..acaa43f9e 100644 --- a/plat/qemu/qemu_sbsa/platform.mk +++ b/plat/qemu/qemu_sbsa/platform.mk @@ -47,7 +47,8 @@ BL1_SOURCES += drivers/io/io_semihosting.c \ ${PLAT_QEMU_COMMON_PATH}/${ARCH}/plat_helpers.S \ ${PLAT_QEMU_COMMON_PATH}/qemu_bl1_setup.c -BL1_SOURCES += lib/cpus/aarch64/cortex_a57.S +BL1_SOURCES += lib/cpus/aarch64/cortex_a57.S \ + lib/cpus/aarch64/cortex_a72.S BL2_SOURCES += drivers/io/io_semihosting.c \ drivers/io/io_storage.c \ @@ -74,6 +75,7 @@ QEMU_GIC_SOURCES := ${GICV3_SOURCES} \ ${PLAT_QEMU_COMMON_PATH}/qemu_gicv3.c BL31_SOURCES += lib/cpus/aarch64/cortex_a57.S \ + lib/cpus/aarch64/cortex_a72.S \ lib/semihosting/semihosting.c \ lib/semihosting/${ARCH}/semihosting_call.S \ plat/common/plat_psci_common.c \ -- cgit v1.2.3 From 5c336e0636ad24692daf5cd7bab8a54906260a7a Mon Sep 17 00:00:00 2001 From: Jessica Clarke Date: Sun, 25 Oct 2020 18:10:24 +0000 Subject: fdts: Remove "virtio-rng" from Morello FVP This is not a standard string that any kernel recognises, nor do any of the FDTs embedded in kernels specify this, nor does QEMU's virt machine. Whilst its presence does no harm, it's not a thing code should consult as a result, and so drop it in order to not cause confusion and risk incorrect code being written to search for it. Signed-off-by: Jessica Clarke Change-Id: Iea3214a23181c54e600cf8f4f12dfc822140c23d --- fdts/morello-fvp.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdts/morello-fvp.dts b/fdts/morello-fvp.dts index 2218b2aaf..00b4c43aa 100644 --- a/fdts/morello-fvp.dts +++ b/fdts/morello-fvp.dts @@ -81,7 +81,7 @@ }; virtio_rng@1c190000 { - compatible = "virtio,mmio","virtio-rng"; + compatible = "virtio,mmio"; reg = <0x0 0x1c190000 0x0 0x200>; interrupts = ; }; -- cgit v1.2.3 From de7091a1f596bf2be54750110f74f1e266ec1693 Mon Sep 17 00:00:00 2001 From: Jessica Clarke Date: Sun, 25 Oct 2020 18:18:47 +0000 Subject: fdts: Add VirtIO network device to Morello FVP Signed-off-by: Jessica Clarke Change-Id: I5ad5290925f637b94168b507b3dcbdd5e1b82e5a --- fdts/morello-fvp.dts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fdts/morello-fvp.dts b/fdts/morello-fvp.dts index 00b4c43aa..699dc2346 100644 --- a/fdts/morello-fvp.dts +++ b/fdts/morello-fvp.dts @@ -80,6 +80,12 @@ interrupts = ; }; + virtio_net@1c180000 { + compatible = "virtio,mmio"; + reg = <0x0 0x1c180000 0x0 0x200>; + interrupts = ; + }; + virtio_rng@1c190000 { compatible = "virtio,mmio"; reg = <0x0 0x1c190000 0x0 0x200>; -- cgit v1.2.3 From a83103c8240b02c38688aaf18fed2222ffa467b7 Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Wed, 25 Nov 2020 14:07:05 +0000 Subject: Aarch64: Add support for FEAT_PANx extensions This patch provides the changes listed below: - Adds new bit fields definitions for SCTLR_EL1/2 registers - Corrects the name of SCTLR_EL1/2.[20] bit field from SCTLR_UWXN_BIT to SCTLR_TSCXT_BIT - Adds FEAT_PANx bit field definitions and their possible values for ID_AA64MMFR1_EL1 register. - Adds setting of SCTLR_EL1.SPAN bit to preserve PSTATE.PAN on taking an exception to EL1 in spm_sp_setup() function (services\std_svc\spm_mm\spm_mm_setup.c) Change-Id: If51f20e7995c649126a7728a4d0867041fdade19 Signed-off-by: Alexei Fedorov --- include/arch/aarch64/arch.h | 59 ++++++++++++++++++++++++++++++++-- services/std_svc/spm_mm/spm_mm_setup.c | 4 ++- 2 files changed, 60 insertions(+), 3 deletions(-) diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index 33e1134dd..29342f71a 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -243,6 +243,13 @@ #define ID_AA64MMFR1_EL1_TWED_SUPPORTED ULL(0x1) #define ID_AA64MMFR1_EL1_TWED_NOT_SUPPORTED ULL(0x0) +#define ID_AA64MMFR1_EL1_PAN_SHIFT U(20) +#define ID_AA64MMFR1_EL1_PAN_MASK ULL(0xf) +#define ID_AA64MMFR1_EL1_PAN_NOT_SUPPORTED ULL(0x0) +#define ID_AA64MMFR1_EL1_PAN_SUPPORTED ULL(0x1) +#define ID_AA64MMFR1_EL1_PAN2_SUPPORTED ULL(0x2) +#define ID_AA64MMFR1_EL1_PAN3_SUPPORTED ULL(0x3) + /* ID_AA64MMFR2_EL1 definitions */ #define ID_AA64MMFR2_EL1 S3_0_C0_C7_2 @@ -286,6 +293,7 @@ #define SCTLR_EL1_RES1 ((UL(1) << 29) | (UL(1) << 28) | (UL(1) << 23) | \ (UL(1) << 22) | (UL(1) << 20) | (UL(1) << 11)) + #define SCTLR_AARCH32_EL1_RES1 \ ((U(1) << 23) | (U(1) << 22) | (U(1) << 11) | \ (U(1) << 4) | (U(1) << 3)) @@ -300,9 +308,12 @@ #define SCTLR_SA_BIT (ULL(1) << 3) #define SCTLR_SA0_BIT (ULL(1) << 4) #define SCTLR_CP15BEN_BIT (ULL(1) << 5) +#define SCTLR_nAA_BIT (ULL(1) << 6) #define SCTLR_ITD_BIT (ULL(1) << 7) #define SCTLR_SED_BIT (ULL(1) << 8) #define SCTLR_UMA_BIT (ULL(1) << 9) +#define SCTLR_EnRCTX_BIT (ULL(1) << 10) +#define SCTLR_EOS_BIT (ULL(1) << 11) #define SCTLR_I_BIT (ULL(1) << 12) #define SCTLR_EnDB_BIT (ULL(1) << 13) #define SCTLR_DZE_BIT (ULL(1) << 14) @@ -310,21 +321,65 @@ #define SCTLR_NTWI_BIT (ULL(1) << 16) #define SCTLR_NTWE_BIT (ULL(1) << 18) #define SCTLR_WXN_BIT (ULL(1) << 19) -#define SCTLR_UWXN_BIT (ULL(1) << 20) +#define SCTLR_TSCXT_BIT (ULL(1) << 20) #define SCTLR_IESB_BIT (ULL(1) << 21) +#define SCTLR_EIS_BIT (ULL(1) << 22) +#define SCTLR_SPAN_BIT (ULL(1) << 23) #define SCTLR_E0E_BIT (ULL(1) << 24) #define SCTLR_EE_BIT (ULL(1) << 25) #define SCTLR_UCI_BIT (ULL(1) << 26) #define SCTLR_EnDA_BIT (ULL(1) << 27) +#define SCTLR_nTLSMD_BIT (ULL(1) << 28) +#define SCTLR_LSMAOE_BIT (ULL(1) << 29) #define SCTLR_EnIB_BIT (ULL(1) << 30) #define SCTLR_EnIA_BIT (ULL(1) << 31) #define SCTLR_BT0_BIT (ULL(1) << 35) #define SCTLR_BT1_BIT (ULL(1) << 36) #define SCTLR_BT_BIT (ULL(1) << 36) +#define SCTLR_ITFSB_BIT (ULL(1) << 37) +#define SCTLR_TCF0_SHIFT U(38) +#define SCTLR_TCF0_MASK ULL(3) + +/* Tag Check Faults in EL0 have no effect on the PE */ +#define SCTLR_TCF0_NO_EFFECT U(0) +/* Tag Check Faults in EL0 cause a synchronous exception */ +#define SCTLR_TCF0_SYNC U(1) +/* Tag Check Faults in EL0 are asynchronously accumulated */ +#define SCTLR_TCF0_ASYNC U(2) +/* + * Tag Check Faults in EL0 cause a synchronous exception on reads, + * and are asynchronously accumulated on writes + */ +#define SCTLR_TCF0_SYNCR_ASYNCW U(3) + +#define SCTLR_TCF_SHIFT U(40) +#define SCTLR_TCF_MASK ULL(3) + +/* Tag Check Faults in EL1 have no effect on the PE */ +#define SCTLR_TCF_NO_EFFECT U(0) +/* Tag Check Faults in EL1 cause a synchronous exception */ +#define SCTLR_TCF_SYNC U(1) +/* Tag Check Faults in EL1 are asynchronously accumulated */ +#define SCTLR_TCF_ASYNC U(2) +/* + * Tag Check Faults in EL1 cause a synchronous exception on reads, + * and are asynchronously accumulated on writes + */ +#define SCTLR_TCF_SYNCR_ASYNCW U(3) + +#define SCTLR_ATA0_BIT (ULL(1) << 42) +#define SCTLR_ATA_BIT (ULL(1) << 43) #define SCTLR_DSSBS_BIT (ULL(1) << 44) +#define SCTLR_TWEDEn_BIT (ULL(1) << 45) +#define SCTLR_TWEDEL_SHIFT U(46) +#define SCTLR_TWEDEL_MASK ULL(0xf) +#define SCTLR_EnASR_BIT (ULL(1) << 54) +#define SCTLR_EnAS0_BIT (ULL(1) << 55) +#define SCTLR_EnALS_BIT (ULL(1) << 56) +#define SCTLR_EPAN_BIT (ULL(1) << 57) #define SCTLR_RESET_VAL SCTLR_EL3_RES1 -/* CPACR_El1 definitions */ +/* CPACR_EL1 definitions */ #define CPACR_EL1_FPEN(x) ((x) << 20) #define CPACR_EL1_FP_TRAP_EL0 UL(0x1) #define CPACR_EL1_FP_TRAP_ALL UL(0x2) diff --git a/services/std_svc/spm_mm/spm_mm_setup.c b/services/std_svc/spm_mm/spm_mm_setup.c index 468e5b3af..32562c311 100644 --- a/services/std_svc/spm_mm/spm_mm_setup.c +++ b/services/std_svc/spm_mm/spm_mm_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -142,6 +142,8 @@ void spm_sp_setup(sp_context_t *sp_ctx) SCTLR_DZE_BIT | /* Enable SP Alignment check for EL0 */ SCTLR_SA0_BIT | + /* Don't change PSTATE.PAN on taking an exception to EL1 */ + SCTLR_SPAN_BIT | /* Allow cacheable data and instr. accesses to normal memory. */ SCTLR_C_BIT | SCTLR_I_BIT | /* Enable MMU. */ -- cgit v1.2.3 From 25bbbd2d632be40a4b9afd75a0dfb7eddd1e3081 Mon Sep 17 00:00:00 2001 From: Javier Almansa Sobrino Date: Fri, 23 Oct 2020 13:22:07 +0100 Subject: Add support for Neoverse-N2 CPUs. Enable basic support for Neoverse-N2 CPUs. Signed-off-by: Javier Almansa Sobrino Change-Id: I498adc2d9fc61ac6e1af8ece131039410872e8ad --- docs/design/cpu-specific-build-macros.rst | 3 +- include/lib/cpus/aarch64/neoverse_n1.h | 8 -- include/lib/cpus/aarch64/neoverse_n2.h | 31 ++++++++ include/lib/cpus/aarch64/neoverse_n_common.h | 18 +++++ lib/cpus/aarch64/neoverse_n1.S | 19 +---- lib/cpus/aarch64/neoverse_n2.S | 109 +++++++++++++++++++++++++++ lib/cpus/aarch64/neoverse_n_common.S | 26 +++++++ lib/cpus/cpu-ops.mk | 8 +- plat/arm/board/arm_fpga/platform.mk | 2 + plat/arm/board/fvp/platform.mk | 2 + plat/arm/board/n1sdp/platform.mk | 2 +- 11 files changed, 198 insertions(+), 30 deletions(-) create mode 100644 include/lib/cpus/aarch64/neoverse_n2.h create mode 100644 include/lib/cpus/aarch64/neoverse_n_common.h create mode 100644 lib/cpus/aarch64/neoverse_n2.S create mode 100644 lib/cpus/aarch64/neoverse_n_common.S diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst index c0fda78dd..e901e0c5e 100644 --- a/docs/design/cpu-specific-build-macros.rst +++ b/docs/design/cpu-specific-build-macros.rst @@ -363,10 +363,11 @@ architecture that can be enabled by the platform as desired. Cortex-A57 based platform must make its own decision on whether to use the optimization. This flag is disabled by default. -- ``NEOVERSE_N1_EXTERNAL_LLC``: This flag indicates that an external last +- ``NEOVERSE_Nx_EXTERNAL_LLC``: This flag indicates that an external last level cache(LLC) is present in the system, and that the DataSource field on the master CHI interface indicates when data is returned from the LLC. This is used to control how the LL_CACHE* PMU events count. + Default value is 0 (Disabled). -------------- diff --git a/include/lib/cpus/aarch64/neoverse_n1.h b/include/lib/cpus/aarch64/neoverse_n1.h index 9998b93f2..b50befa8d 100644 --- a/include/lib/cpus/aarch64/neoverse_n1.h +++ b/include/lib/cpus/aarch64/neoverse_n1.h @@ -64,12 +64,4 @@ #define CPUPOR_EL3 S3_6_C15_C8_2 #define CPUPMR_EL3 S3_6_C15_C8_3 -/****************************************************************************** - * CPU Configuration register definitions. - *****************************************************************************/ -#define CPUCFR_EL1 S3_0_C15_C0_0 - -/* SCU bit of CPU Configuration Register, EL1 */ -#define SCU_SHIFT U(2) - #endif /* NEOVERSE_N1_H */ diff --git a/include/lib/cpus/aarch64/neoverse_n2.h b/include/lib/cpus/aarch64/neoverse_n2.h new file mode 100644 index 000000000..7cbd8c17b --- /dev/null +++ b/include/lib/cpus/aarch64/neoverse_n2.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef NEOVERSE_N2_H +#define NEOVERSE_N2_H + +/* Neoverse N2 ID register for revision r0p0 */ +#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) + +/******************************************************************************* + * 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) + +/******************************************************************************* + * CPU Auxiliary Control register specific definitions. + ******************************************************************************/ +#define NEOVERSE_N2_CPUACTLR2_EL1 S3_0_C15_C1_1 +#define NEOVERSE_N2_CPUACTLR2_EL1_BIT_2 (ULL(1) << 2) + +#endif /* NEOVERSE_N2_H */ diff --git a/include/lib/cpus/aarch64/neoverse_n_common.h b/include/lib/cpus/aarch64/neoverse_n_common.h new file mode 100644 index 000000000..7cb91cd05 --- /dev/null +++ b/include/lib/cpus/aarch64/neoverse_n_common.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef NEOVERSE_N_COMMON_H +#define NEOVERSE_N_COMMON_H + +/****************************************************************************** + * Neoverse Nx CPU Configuration register definitions + *****************************************************************************/ +#define CPUCFR_EL1 S3_0_C15_C0_0 + +/* SCU bit of CPU Configuration Register, EL1 */ +#define SCU_SHIFT U(2) + +#endif /* NEOVERSE_N_COMMON_H */ diff --git a/lib/cpus/aarch64/neoverse_n1.S b/lib/cpus/aarch64/neoverse_n1.S index 03ee47209..96891be1d 100644 --- a/lib/cpus/aarch64/neoverse_n1.S +++ b/lib/cpus/aarch64/neoverse_n1.S @@ -1,15 +1,15 @@ /* - * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include #include -#include #include #include #include +#include /* Hardware handled coherency */ #if HW_ASSISTED_COHERENCY == 0 @@ -22,19 +22,6 @@ #endif .global neoverse_n1_errata_ic_trap_handler - .global is_scu_present_in_dsu - -/* - * Check DSU is configured with SCU and L3 unit - * 1-> SCU present - * 0-> SCU not present - */ -func is_scu_present_in_dsu - mrs x0, CPUCFR_EL1 - ubfx x0, x0, #SCU_SHIFT, #1 - eor x0, x0, #1 - ret -endfunc is_scu_present_in_dsu /* -------------------------------------------------- * Errata Workaround for Neoverse N1 Erratum 1043202. @@ -515,7 +502,7 @@ func neoverse_n1_reset_func msr CPUAMCNTENSET_EL0, x0 #endif -#if NEOVERSE_N1_EXTERNAL_LLC +#if NEOVERSE_Nx_EXTERNAL_LLC /* Some system may have External LLC, core needs to be made aware */ mrs x0, NEOVERSE_N1_CPUECTLR_EL1 orr x0, x0, NEOVERSE_N1_CPUECTLR_EL1_EXTLLC_BIT diff --git a/lib/cpus/aarch64/neoverse_n2.S b/lib/cpus/aarch64/neoverse_n2.S new file mode 100644 index 000000000..8d646cba5 --- /dev/null +++ b/lib/cpus/aarch64/neoverse_n2.S @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +/* Hardware handled coherency */ +#if HW_ASSISTED_COHERENCY == 0 +#error "Neoverse N2 must be compiled with HW_ASSISTED_COHERENCY enabled" +#endif + +/* 64-bit only core */ +#if CTX_INCLUDE_AARCH32_REGS == 1 +#error "Neoverse-N2 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0" +#endif + + /* ------------------------------------------------- + * The CPU Ops reset function for Neoverse N2. + * ------------------------------------------------- + */ +func neoverse_n2_reset_func + /* Check if the PE implements SSBS */ + mrs x0, id_aa64pfr1_el1 + tst x0, #(ID_AA64PFR1_EL1_SSBS_MASK << ID_AA64PFR1_EL1_SSBS_SHIFT) + b.eq 1f + + /* Disable speculative loads */ + msr SSBS, xzr +1: + /* Force all cacheable atomic instructions to be near */ + mrs x0, NEOVERSE_N2_CPUACTLR2_EL1 + orr x0, x0, #NEOVERSE_N2_CPUACTLR2_EL1_BIT_2 + msr NEOVERSE_N2_CPUACTLR2_EL1, x0 + +#if ENABLE_AMU + /* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */ + mrs x0, cptr_el3 + orr x0, x0, #TAM_BIT + msr cptr_el3, x0 + + /* Make sure accesses from EL0/EL1 are not trapped to EL2 */ + mrs x0, cptr_el2 + orr x0, x0, #TAM_BIT + msr cptr_el2, x0 + + /* No need to enable the counters as this would be done at el3 exit */ +#endif + +#if NEOVERSE_Nx_EXTERNAL_LLC + /* Some systems may have External LLC, core needs to be made aware */ + mrs x0, NEOVERSE_N2_CPUECTLR_EL1 + orr x0, x0, NEOVERSE_N2_CPUECTLR_EL1_EXTLLC_BIT + msr NEOVERSE_N2_CPUECTLR_EL1, x0 +#endif + + isb + ret +endfunc neoverse_n2_reset_func + +func neoverse_n2_core_pwr_dwn + /* --------------------------------------------- + * Enable CPU power down bit in power control register + * No need to do cache maintenance here. + * --------------------------------------------- + */ + mrs x0, NEOVERSE_N2_CPUPWRCTLR_EL1 + orr x0, x0, #NEOVERSE_N2_CORE_PWRDN_EN_BIT + msr NEOVERSE_N2_CPUPWRCTLR_EL1, x0 + isb + ret +endfunc neoverse_n2_core_pwr_dwn + +#if REPORT_ERRATA +/* + * Errata printing function for Neoverse N2 cores. Must follow AAPCS. + */ +func neoverse_n2_errata_report + /* No errata reported for Neoverse N2 cores */ + ret +endfunc neoverse_n2_errata_report +#endif + + /* --------------------------------------------- + * This function provides Neoverse N2 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_n2_regs, "aS" +neoverse_n2_regs: /* The ASCII list of register names to be reported */ + .asciz "cpupwrctlr_el1", "" + +func neoverse_n2_cpu_reg_dump + adr x6, neoverse_n2_regs + mrs x8, NEOVERSE_N2_CPUPWRCTLR_EL1 + ret +endfunc neoverse_n2_cpu_reg_dump + +declare_cpu_ops neoverse_n2, NEOVERSE_N2_MIDR, \ + neoverse_n2_reset_func, \ + neoverse_n2_core_pwr_dwn diff --git a/lib/cpus/aarch64/neoverse_n_common.S b/lib/cpus/aarch64/neoverse_n_common.S new file mode 100644 index 000000000..b816342ba --- /dev/null +++ b/lib/cpus/aarch64/neoverse_n_common.S @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + + .global is_scu_present_in_dsu + +/* + * Check if the SCU L3 Unit is present on the DSU + * 1-> SCU present + * 0-> SCU not present + * + * This function is implemented as weak on dsu_helpers.S and must be + * overwritten for Neoverse Nx cores. + */ + +func is_scu_present_in_dsu + mrs x0, CPUCFR_EL1 + ubfx x0, x0, #SCU_SHIFT, #1 + eor x0, x0, #1 + ret +endfunc is_scu_present_in_dsu diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk index 4126105aa..084e6e7bd 100644 --- a/lib/cpus/cpu-ops.mk +++ b/lib/cpus/cpu-ops.mk @@ -25,9 +25,9 @@ WORKAROUND_CVE_2017_5715 ?=1 WORKAROUND_CVE_2018_3639 ?=1 DYNAMIC_WORKAROUND_CVE_2018_3639 ?=0 -# Flag to indicate internal or external Last level cache +# Flags to indicate internal or external Last level cache # By default internal -NEOVERSE_N1_EXTERNAL_LLC ?=0 +NEOVERSE_Nx_EXTERNAL_LLC ?=0 # Process A57_ENABLE_NONCACHEABLE_LOAD_FWD flag $(eval $(call assert_boolean,A57_ENABLE_NONCACHEABLE_LOAD_FWD)) @@ -56,8 +56,8 @@ $(eval $(call add_define,WORKAROUND_CVE_2018_3639)) $(eval $(call assert_boolean,DYNAMIC_WORKAROUND_CVE_2018_3639)) $(eval $(call add_define,DYNAMIC_WORKAROUND_CVE_2018_3639)) -$(eval $(call assert_boolean,NEOVERSE_N1_EXTERNAL_LLC)) -$(eval $(call add_define,NEOVERSE_N1_EXTERNAL_LLC)) +$(eval $(call assert_boolean,NEOVERSE_Nx_EXTERNAL_LLC)) +$(eval $(call add_define,NEOVERSE_Nx_EXTERNAL_LLC)) ifneq (${DYNAMIC_WORKAROUND_CVE_2018_3639},0) ifeq (${WORKAROUND_CVE_2018_3639},0) diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk index 4b751fb20..3ac1c01ab 100644 --- a/plat/arm/board/arm_fpga/platform.mk +++ b/plat/arm/board/arm_fpga/platform.mk @@ -59,7 +59,9 @@ else lib/cpus/aarch64/cortex_a76ae.S \ lib/cpus/aarch64/cortex_a77.S \ lib/cpus/aarch64/cortex_a78.S \ + lib/cpus/aarch64/neoverse_n_common.S \ lib/cpus/aarch64/neoverse_n1.S \ + lib/cpus/aarch64/neoverse_n2.S \ lib/cpus/aarch64/neoverse_e1.S \ lib/cpus/aarch64/neoverse_v1.S \ lib/cpus/aarch64/cortex_a78_ae.S \ diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 4da0d7643..0a6fa56ad 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -118,7 +118,9 @@ else lib/cpus/aarch64/cortex_a76ae.S \ lib/cpus/aarch64/cortex_a77.S \ lib/cpus/aarch64/cortex_a78.S \ + lib/cpus/aarch64/neoverse_n_common.S \ lib/cpus/aarch64/neoverse_n1.S \ + lib/cpus/aarch64/neoverse_n2.S \ lib/cpus/aarch64/neoverse_e1.S \ lib/cpus/aarch64/neoverse_v1.S \ lib/cpus/aarch64/cortex_a78_ae.S \ diff --git a/plat/arm/board/n1sdp/platform.mk b/plat/arm/board/n1sdp/platform.mk index 4b621e3c0..f20397acd 100644 --- a/plat/arm/board/n1sdp/platform.mk +++ b/plat/arm/board/n1sdp/platform.mk @@ -69,7 +69,7 @@ HW_ASSISTED_COHERENCY := 1 USE_COHERENT_MEM := 0 # Enable the flag since N1SDP has a system level cache -NEOVERSE_N1_EXTERNAL_LLC := 1 +NEOVERSE_Nx_EXTERNAL_LLC := 1 include plat/arm/common/arm_common.mk include plat/arm/css/common/css_common.mk include plat/arm/board/common/board_common.mk -- cgit v1.2.3 From 826ba363c46cbd7fce906d542c91e399802e16aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20M=C3=BCllner?= Date: Fri, 20 Nov 2020 22:06:16 +0100 Subject: rockchip: Add support for the stack protector MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It uses the system timer as "entropy" source in the same way as QEMU, layerscape and others. Change-Id: Icda17b78e85255bea96109ca2ee0e091187d62ac Signed-off-by: Christoph Müllner --- plat/rockchip/common/rockchip_stack_protector.c | 24 ++++++++++++++++++++++++ plat/rockchip/px30/platform.mk | 4 ++++ plat/rockchip/rk3328/platform.mk | 4 ++++ plat/rockchip/rk3368/platform.mk | 4 ++++ plat/rockchip/rk3399/platform.mk | 4 ++++ 5 files changed, 40 insertions(+) create mode 100644 plat/rockchip/common/rockchip_stack_protector.c diff --git a/plat/rockchip/common/rockchip_stack_protector.c b/plat/rockchip/common/rockchip_stack_protector.c new file mode 100644 index 000000000..18989779e --- /dev/null +++ b/plat/rockchip/common/rockchip_stack_protector.c @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include + +#define RANDOM_CANARY_VALUE ((u_register_t) 3288484550995823360ULL) + +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 virt platform 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/rockchip/px30/platform.mk b/plat/rockchip/px30/platform.mk index 87cf18704..b1bb80701 100644 --- a/plat/rockchip/px30/platform.mk +++ b/plat/rockchip/px30/platform.mk @@ -36,6 +36,10 @@ PLAT_BL_COMMON_SOURCES := lib/bl_aux_params/bl_aux_params.c \ lib/xlat_tables/aarch64/xlat_tables.c \ plat/common/plat_psci_common.c +ifneq (${ENABLE_STACK_PROTECTOR},0) +PLAT_BL_COMMON_SOURCES += ${RK_PLAT_COMMON}/rockchip_stack_protector.c +endif + BL31_SOURCES += ${RK_GIC_SOURCES} \ common/desc_image_load.c \ drivers/arm/cci/cci.c \ diff --git a/plat/rockchip/rk3328/platform.mk b/plat/rockchip/rk3328/platform.mk index 0219422f9..5a307e491 100644 --- a/plat/rockchip/rk3328/platform.mk +++ b/plat/rockchip/rk3328/platform.mk @@ -35,6 +35,10 @@ PLAT_BL_COMMON_SOURCES := common/desc_image_load.c \ plat/common/aarch64/crash_console_helpers.S \ plat/common/plat_psci_common.c +ifneq (${ENABLE_STACK_PROTECTOR},0) +PLAT_BL_COMMON_SOURCES += ${RK_PLAT_COMMON}/rockchip_stack_protector.c +endif + BL31_SOURCES += ${RK_GIC_SOURCES} \ drivers/arm/cci/cci.c \ drivers/ti/uart/aarch64/16550_console.S \ diff --git a/plat/rockchip/rk3368/platform.mk b/plat/rockchip/rk3368/platform.mk index cb0cb8962..e78729357 100644 --- a/plat/rockchip/rk3368/platform.mk +++ b/plat/rockchip/rk3368/platform.mk @@ -33,6 +33,10 @@ PLAT_BL_COMMON_SOURCES := common/desc_image_load.c \ plat/common/aarch64/crash_console_helpers.S \ plat/common/plat_psci_common.c +ifneq (${ENABLE_STACK_PROTECTOR},0) +PLAT_BL_COMMON_SOURCES += ${RK_PLAT_COMMON}/rockchip_stack_protector.c +endif + BL31_SOURCES += ${RK_GIC_SOURCES} \ drivers/arm/cci/cci.c \ drivers/ti/uart/aarch64/16550_console.S \ diff --git a/plat/rockchip/rk3399/platform.mk b/plat/rockchip/rk3399/platform.mk index a658fb286..aba67c2fe 100644 --- a/plat/rockchip/rk3399/platform.mk +++ b/plat/rockchip/rk3399/platform.mk @@ -38,6 +38,10 @@ PLAT_BL_COMMON_SOURCES := common/desc_image_load.c \ plat/common/aarch64/crash_console_helpers.S \ plat/common/plat_psci_common.c +ifneq (${ENABLE_STACK_PROTECTOR},0) +PLAT_BL_COMMON_SOURCES += ${RK_PLAT_COMMON}/rockchip_stack_protector.c +endif + BL31_SOURCES += ${RK_GIC_SOURCES} \ drivers/arm/cci/cci.c \ drivers/ti/uart/aarch64/16550_console.S \ -- cgit v1.2.3 From 54b590ec0dbef0e26bd618244c4b1fcd1a03b4cb Mon Sep 17 00:00:00 2001 From: Masato Fukumori Date: Tue, 1 Dec 2020 22:17:27 +0900 Subject: qemu/qemu_sbsa: increase SHARED_RAM_SIZE Increase SHARED_RAM_SIZE in sbsa_qemu platform from 4KB to 8KB. sbsa_qemu uses SHARED_RAM for mail box and hold state of each cpus. If qemu is configured with 512 cpus, region size used by qemu is greater than 4KB. Signed-off-by: Masato Fukumori Change-Id: I639e44e89335249d385cdc339350f509e9bd5e36 --- plat/qemu/qemu_sbsa/include/platform_def.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/qemu/qemu_sbsa/include/platform_def.h b/plat/qemu/qemu_sbsa/include/platform_def.h index 76340051a..75851e391 100644 --- a/plat/qemu/qemu_sbsa/include/platform_def.h +++ b/plat/qemu/qemu_sbsa/include/platform_def.h @@ -85,7 +85,7 @@ */ #define SHARED_RAM_BASE SEC_SRAM_BASE -#define SHARED_RAM_SIZE 0x00001000 +#define SHARED_RAM_SIZE 0x00002000 #define PLAT_QEMU_TRUSTED_MAILBOX_BASE SHARED_RAM_BASE #define PLAT_QEMU_TRUSTED_MAILBOX_SIZE (8 + PLAT_QEMU_HOLD_SIZE) -- cgit v1.2.3 From 0563ab08e892b899905193d4e482440eecd2d36a Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Tue, 1 Dec 2020 13:22:25 +0000 Subject: Aarch64: Add support for FEAT_MTE3 This patch provides the following changes: - Adds definition for FEAT_MTE3 value in ID_AA64PFR1_EL1 register - Enables Memory Tagging Extension for FEAT_MTE3. Change-Id: I735988575466fdc083892ec12c1aee89b5faa472 Signed-off-by: Alexei Fedorov --- include/arch/aarch64/arch.h | 14 +++++++++++--- lib/el3_runtime/aarch64/context_mgmt.c | 31 +++++++++++++++++-------------- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index 33e1134dd..2518e5c27 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -266,9 +266,17 @@ #define ID_AA64PFR1_EL1_MTE_SHIFT U(8) #define ID_AA64PFR1_EL1_MTE_MASK ULL(0xf) -#define MTE_UNIMPLEMENTED ULL(0) -#define MTE_IMPLEMENTED_EL0 ULL(1) /* MTE is only implemented at EL0 */ -#define MTE_IMPLEMENTED_ELX ULL(2) /* MTE is implemented at all ELs */ +/* Memory Tagging Extension is not implemented */ +#define MTE_UNIMPLEMENTED U(0) +/* FEAT_MTE: MTE instructions accessible at EL0 are implemented */ +#define MTE_IMPLEMENTED_EL0 U(1) +/* FEAT_MTE2: Full MTE is implemented */ +#define MTE_IMPLEMENTED_ELX U(2) +/* + * FEAT_MTE3: MTE is implemented with support for + * asymmetric Tag Check Fault handling + */ +#define MTE_IMPLEMENTED_ASY U(3) #define ID_AA64PFR1_MPAM_FRAC_SHIFT ULL(16) #define ID_AA64PFR1_MPAM_FRAC_MASK ULL(0xf) diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c index b460731e8..72d463b71 100644 --- a/lib/el3_runtime/aarch64/context_mgmt.c +++ b/lib/el3_runtime/aarch64/context_mgmt.c @@ -144,30 +144,33 @@ void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep) scr_el3 |= SCR_API_BIT | SCR_APK_BIT; #endif /* !CTX_INCLUDE_PAUTH_REGS */ +#if !CTX_INCLUDE_MTE_REGS || ENABLE_ASSERTIONS + /* Get Memory Tagging Extension support level */ + unsigned int mte = get_armv8_5_mte_support(); +#endif /* * Enable MTE support. Support is enabled unilaterally for the normal * world, and only for the secure world when CTX_INCLUDE_MTE_REGS is * set. */ #if CTX_INCLUDE_MTE_REGS - assert(get_armv8_5_mte_support() == MTE_IMPLEMENTED_ELX); + assert((mte == MTE_IMPLEMENTED_ELX) || (mte == MTE_IMPLEMENTED_ASY)); scr_el3 |= SCR_ATA_BIT; #else - unsigned int mte = get_armv8_5_mte_support(); - if (mte == MTE_IMPLEMENTED_EL0) { - /* - * Can enable MTE across both worlds as no MTE registers are - * used - */ - scr_el3 |= SCR_ATA_BIT; - } else if (mte == MTE_IMPLEMENTED_ELX && security_state == NON_SECURE) { - /* - * Can only enable MTE in Non-Secure world without register - * saving - */ + /* + * When MTE is only implemented at EL0, it can be enabled + * across both worlds as no MTE registers are used. + */ + if ((mte == MTE_IMPLEMENTED_EL0) || + /* + * When MTE is implemented at all ELs, it can be only enabled + * in Non-Secure world without register saving. + */ + (((mte == MTE_IMPLEMENTED_ELX) || (mte == MTE_IMPLEMENTED_ASY)) && + (security_state == NON_SECURE))) { scr_el3 |= SCR_ATA_BIT; } -#endif +#endif /* CTX_INCLUDE_MTE_REGS */ #ifdef IMAGE_BL31 /* -- cgit v1.2.3 From 279f77b4926577b3fe529ffeed4033aedfcd4d4a Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Wed, 19 Aug 2020 19:07:26 +0200 Subject: .editorconfig: set max line length to 100 Relax the 80 character line length, as done in checkpatch, since Linux 5.7. Change-Id: I093a2e6a45336339193173f7ff6a461279cf411d Signed-off-by: Yann Gautier --- .editorconfig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.editorconfig b/.editorconfig index f523ca19d..12f786de5 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,5 +1,5 @@ # -# Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved. +# Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -38,10 +38,10 @@ indent_style = tab insert_final_newline = true # [LCS] Chapter 2: Breaking long lines and strings -# "The limit on the length of lines is 80 columns" +# "The limit on the length of lines is 100 columns" # This is a "soft" requirement for Arm-TF, and should not be the sole # reason for changes. -max_line_length = 80 +max_line_length = 100 # [LCS] Chapter 1: Indentation # "Tabs are 8 characters" -- cgit v1.2.3 From 84f2e34fee3dd955b23682e24a0469a5e26cc025 Mon Sep 17 00:00:00 2001 From: Venkatesh Yadav Abbarapu Date: Thu, 3 Dec 2020 20:27:18 -0700 Subject: plat: xilinx: zynqmp: Include GICv2 makefile Update the xilinx platform makefile to include GICv2 makefile instead of adding the individual files. Updating this change as per the latest changes done in the commit #1322dc94f7. Signed-off-by: Venkatesh Yadav Abbarapu Change-Id: I79d8374c47a7f42761d121522b32ac7a5021ede8 --- plat/xilinx/zynqmp/platform.mk | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk index 194e72dc7..1cd168f7d 100644 --- a/plat/xilinx/zynqmp/platform.mk +++ b/plat/xilinx/zynqmp/platform.mk @@ -59,13 +59,14 @@ PLAT_INCLUDES := -Iinclude/plat/arm/common/ \ -Iplat/xilinx/zynqmp/include/ \ -Iplat/xilinx/zynqmp/pm_service/ \ +# Include GICv2 driver files +include drivers/arm/gic/v2/gicv2.mk + PLAT_BL_COMMON_SOURCES := lib/xlat_tables/xlat_tables_common.c \ lib/xlat_tables/aarch64/xlat_tables.c \ drivers/delay_timer/delay_timer.c \ drivers/delay_timer/generic_delay_timer.c \ - drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v2/gicv2_main.c \ - drivers/arm/gic/v2/gicv2_helpers.c \ + ${GICV2_SOURCES} \ drivers/cadence/uart/aarch64/cdns_console.S \ plat/arm/common/arm_cci.c \ plat/arm/common/arm_common.c \ -- cgit v1.2.3 From a7379a2ab16c508db48ba6b3237689a084aa138a Mon Sep 17 00:00:00 2001 From: Tejas Patel Date: Sun, 22 Nov 2020 23:37:55 -0800 Subject: plat: zynqmp: Change macro name of PM_BOOT_HEALTH_STATUS_REG For boot health status PMU Global General Storage Register 4 is used. GGS4 can be used for other purpose along with boot health status. So, change its name from PM_BOOT_HEALTH_STATUS_REG to PMU_GLOBAL_GEN_STORAGE4. Signed-off-by: Tejas Patel Signed-off-by: Rajan Vaja Change-Id: I2f5c4c6a161121e7cdb4b9f0f8711d0dad16c372 --- plat/xilinx/zynqmp/include/zynqmp_def.h | 7 ++++--- plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/plat/xilinx/zynqmp/include/zynqmp_def.h b/plat/xilinx/zynqmp/include/zynqmp_def.h index 5e7254e5c..461439530 100644 --- a/plat/xilinx/zynqmp/include/zynqmp_def.h +++ b/plat/xilinx/zynqmp/include/zynqmp_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -341,8 +341,9 @@ #define PGGS_BASEADDR (0xFFD80050U) #define PGGS_NUM_REGS U(4) -/* Warm restart boot health status register and mask */ -#define PM_BOOT_HEALTH_STATUS_REG (GGS_BASEADDR + U(0x10)) +/* PMU GGS4 register 4 is used for warm restart boot health status */ +#define PMU_GLOBAL_GEN_STORAGE4 (GGS_BASEADDR + 0x10) +/* Warm restart boot health status mask */ #define PM_BOOT_HEALTH_STATUS_MASK U(0x01) /*AFI registers */ diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c index 60e80d907..9da904eb5 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c +++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -575,7 +575,7 @@ static enum pm_ret_status pm_ioctl_ulpi_reset(void) */ static enum pm_ret_status pm_ioctl_set_boot_health_status(unsigned int value) { - return pm_mmio_write(PM_BOOT_HEALTH_STATUS_REG, + return pm_mmio_write(PMU_GLOBAL_GEN_STORAGE4, PM_BOOT_HEALTH_STATUS_MASK, value); } -- cgit v1.2.3 From 490d81d2fa441de8b3b469b5e9c057b2ac68a5d6 Mon Sep 17 00:00:00 2001 From: Venkatesh Yadav Abbarapu Date: Fri, 10 Jan 2020 03:01:35 -0700 Subject: plat: xilinx: zynqmp: Enable log messages for debug Save some space by enabling the log messages like bl33 address only for debug builds. Also check the bl33 and bl32 address and print only if this is not NULL. Signed-off-by: Venkatesh Yadav Abbarapu Signed-off-by: Rajan Vaja Change-Id: I58d846bf69a75e839eb49abcbb9920af13296886 --- plat/xilinx/zynqmp/bl31_zynqmp_setup.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c index b6d8770cc..8272d6221 100644 --- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c +++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c @@ -104,9 +104,12 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, else if (ret != FSBL_HANDOFF_SUCCESS) panic(); } - - NOTICE("BL31: Secure code at 0x%lx\n", bl32_image_ep_info.pc); - NOTICE("BL31: Non secure code at 0x%lx\n", bl33_image_ep_info.pc); + if (bl32_image_ep_info.pc) { + VERBOSE("BL31: Secure code at 0x%lx\n", bl32_image_ep_info.pc); + } + if (bl33_image_ep_info.pc) { + VERBOSE("BL31: Non secure code at 0x%lx\n", bl33_image_ep_info.pc); + } } /* Enable the test setup */ -- cgit v1.2.3 From bdcd1bd0a58bb08cdf245c888329ba4db1eaab26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Mon, 23 Nov 2020 19:14:40 +0100 Subject: plat: marvell: armada: a3k: Do not modify $(WTMI_IMG) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit $(WTMI_IMG) is used only by $(MAKE) subprocess in $(DOIMAGEPATH) directory. So calling truncate on $(WTMI_IMG) after $(MAKE) in $(DOIMAGEPATH) has no effect and can just damage input file for future usage. Therefore remove this truncate call. Signed-off-by: Pali Rohár Change-Id: I9925c54c5d3d10eadc19825c5565ad4598a739a7 --- plat/marvell/armada/a3k/common/a3700_common.mk | 1 - 1 file changed, 1 deletion(-) diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk index 5e2f8e299..9f7dc2c67 100644 --- a/plat/marvell/armada/a3k/common/a3700_common.mk +++ b/plat/marvell/armada/a3k/common/a3700_common.mk @@ -128,7 +128,6 @@ $(DOIMAGETOOL): mrvl_flash: ${BUILD_PLAT}/${BOOT_IMAGE} ${DOIMAGETOOL} $(if $(value MV_DDR_PATH),,$(error "Platform '${PLAT}' for target '$@' requires MV_DDR_PATH. Please set MV_DDR_PATH to point to the right directory")) ${Q}${MAKE} --no-print-directory -C ${DOIMAGEPATH} WTMI_IMG=$(WTMI_IMG) MV_DDR_PATH=$(MV_DDR_PATH) - $(shell truncate -s %4 $(WTMI_IMG)) @echo @echo "Building uart images" $(TIMBUILD) $(TIMBLDUARTARGS) -- cgit v1.2.3 From 13aa89562313a7029f9db76cbc8069bb8deebbd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Mon, 23 Nov 2020 19:19:04 +0100 Subject: plat: marvell: armada: a3k: Do not modify $(WTMI_MULTI_IMG) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rather create a temporary copy in $(BUILD_PLAT) and modify only copy. Signed-off-by: Pali Rohár Change-Id: I256c029106ea6f69faa086fc4e5bee9f68cd257f --- plat/marvell/armada/a3k/common/a3700_common.mk | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk index 9f7dc2c67..294f9dd07 100644 --- a/plat/marvell/armada/a3k/common/a3700_common.mk +++ b/plat/marvell/armada/a3k/common/a3700_common.mk @@ -156,8 +156,9 @@ ifeq ($(MARVELL_SECURE_BOOT),1) @echo -e "\n\t=======================================================\n"; @echo -e "\t Secure boot. Encrypting wtmi and boot-image \n"; @echo -e "\t=======================================================\n"; - @truncate -s %16 $(WTMI_MULTI_IMG) - @openssl enc -aes-256-cbc -e -in $(WTMI_MULTI_IMG) \ + @cp $(WTMI_MULTI_IMG) $(BUILD_PLAT)/wtmi-align.bin + @truncate -s %16 $(BUILD_PLAT)/wtmi-align.bin + @openssl enc -aes-256-cbc -e -in $(BUILD_PLAT)/wtmi-align.bin \ -out $(WTMI_ENC_IMG) \ -K `cat $(IMAGESPATH)/aes-256.txt` -nosalt \ -iv `cat $(IMAGESPATH)/iv.txt` -p -- cgit v1.2.3 From 2f852b89b13ebc1ef2c40c5c5d780e5daab0330e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Mon, 23 Nov 2020 19:22:37 +0100 Subject: plat: marvell: armada: a3k: Do not remove external WTMI image files outside of TF-A repository MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Create copy of WTMI images instead of moving them into TF-A build directory. Signed-off-by: Pali Rohár Change-Id: I2dc24c33b9ce540e4acde51fc1a5c946ae66a5d7 --- plat/marvell/armada/a3k/common/a3700_common.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk index 294f9dd07..c75721f2e 100644 --- a/plat/marvell/armada/a3k/common/a3700_common.mk +++ b/plat/marvell/armada/a3k/common/a3700_common.mk @@ -172,7 +172,8 @@ endif @if [ -e "$(TIMNCFG)" ]; then $(DOIMAGETOOL) -r $(TIMNCFG); fi @if [ "$(MARVELL_SECURE_BOOT)" = "1" ]; then sed -i 's|$(WTMI_MULTI_IMG)|$(WTMI_ENC_IMG)|1;s|$(BOOT_IMAGE)|$(BOOT_ENC_IMAGE)|1;' $(TIMNCFG); fi $(TIM2IMG) $(TIM2IMGARGS) -o $(BUILD_PLAT)/$(FLASH_IMAGE) - @mv -t $(BUILD_PLAT) $(TIM_IMAGE) $(DOIMAGE_CFG) $(TIMN_IMAGE) $(TIMNCFG) $(WTMI_IMG) $(WTMI_SYSINIT_IMG) $(WTMI_MULTI_IMG) + @mv -t $(BUILD_PLAT) $(TIM_IMAGE) $(DOIMAGE_CFG) $(TIMN_IMAGE) $(TIMNCFG) + @cp -t $(BUILD_PLAT) $(WTMI_IMG) $(WTMI_SYSINIT_IMG) $(WTMI_MULTI_IMG) @if [ "$(MARVELL_SECURE_BOOT)" = "1" ]; then mv -t $(BUILD_PLAT) $(WTMI_ENC_IMG) OtpHash.txt; fi @find . -name "*.txt" | grep -E "CSK[[:alnum:]]_KeyHash.txt|Tim_msg.txt|TIMHash.txt" | xargs rm -f -- cgit v1.2.3 From bafc9476b95652164bfdce5fe800c7e76394b127 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Mon, 23 Nov 2020 19:34:43 +0100 Subject: plat: marvell: armada: a3k: Build $(WTMI_ENC_IMG) in $(BUILD_PLAT) directory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pali Rohár Change-Id: Iaecd6c24bf334a959ac2bf395c3ee49c810b01a7 --- plat/marvell/armada/a3k/common/a3700_common.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk index c75721f2e..fccd4868c 100644 --- a/plat/marvell/armada/a3k/common/a3700_common.mk +++ b/plat/marvell/armada/a3k/common/a3700_common.mk @@ -101,7 +101,7 @@ WTMI_SYSINIT_IMG := $(DOIMAGEPATH)/wtmi/sys_init/build/sys_init.bin # and sys-init image (WTMI_SYSINIT_IMG). WTMI_MULTI_IMG := $(DOIMAGEPATH)/wtmi/build/wtmi.bin -WTMI_ENC_IMG := $(DOIMAGEPATH)/wtmi/build/wtmi-enc.bin +WTMI_ENC_IMG := $(BUILD_PLAT)/wtmi-enc.bin BUILD_UART := uart-images SRCPATH := $(dir $(BL33)) @@ -174,7 +174,7 @@ endif $(TIM2IMG) $(TIM2IMGARGS) -o $(BUILD_PLAT)/$(FLASH_IMAGE) @mv -t $(BUILD_PLAT) $(TIM_IMAGE) $(DOIMAGE_CFG) $(TIMN_IMAGE) $(TIMNCFG) @cp -t $(BUILD_PLAT) $(WTMI_IMG) $(WTMI_SYSINIT_IMG) $(WTMI_MULTI_IMG) - @if [ "$(MARVELL_SECURE_BOOT)" = "1" ]; then mv -t $(BUILD_PLAT) $(WTMI_ENC_IMG) OtpHash.txt; fi + @if [ "$(MARVELL_SECURE_BOOT)" = "1" ]; then mv -t $(BUILD_PLAT) OtpHash.txt; fi @find . -name "*.txt" | grep -E "CSK[[:alnum:]]_KeyHash.txt|Tim_msg.txt|TIMHash.txt" | xargs rm -f else # ${WTP} -- cgit v1.2.3 From ed9bae6ad5471c56182f4b16c4b9edcefec52c6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Mon, 23 Nov 2020 19:37:28 +0100 Subject: plat: marvell: armada: a3k: Use make ifeq/endif syntax for $(MARVELL_SECURE_BOOT) code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pali Rohár Change-Id: Id766db4a900a56c795fe5ffdd8a2b80b1aaa2132 --- plat/marvell/armada/a3k/common/a3700_common.mk | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk index fccd4868c..437f5d050 100644 --- a/plat/marvell/armada/a3k/common/a3700_common.mk +++ b/plat/marvell/armada/a3k/common/a3700_common.mk @@ -170,11 +170,15 @@ ifeq ($(MARVELL_SECURE_BOOT),1) endif $(DOIMAGETOOL) $(DOIMAGE_FLAGS) @if [ -e "$(TIMNCFG)" ]; then $(DOIMAGETOOL) -r $(TIMNCFG); fi - @if [ "$(MARVELL_SECURE_BOOT)" = "1" ]; then sed -i 's|$(WTMI_MULTI_IMG)|$(WTMI_ENC_IMG)|1;s|$(BOOT_IMAGE)|$(BOOT_ENC_IMAGE)|1;' $(TIMNCFG); fi +ifeq ($(MARVELL_SECURE_BOOT),1) + @sed -i 's|$(WTMI_MULTI_IMG)|$(WTMI_ENC_IMG)|1;s|$(BOOT_IMAGE)|$(BOOT_ENC_IMAGE)|1;' $(TIMNCFG) +endif $(TIM2IMG) $(TIM2IMGARGS) -o $(BUILD_PLAT)/$(FLASH_IMAGE) @mv -t $(BUILD_PLAT) $(TIM_IMAGE) $(DOIMAGE_CFG) $(TIMN_IMAGE) $(TIMNCFG) @cp -t $(BUILD_PLAT) $(WTMI_IMG) $(WTMI_SYSINIT_IMG) $(WTMI_MULTI_IMG) - @if [ "$(MARVELL_SECURE_BOOT)" = "1" ]; then mv -t $(BUILD_PLAT) OtpHash.txt; fi +ifeq ($(MARVELL_SECURE_BOOT),1) + @mv -t $(BUILD_PLAT) OtpHash.txt +endif @find . -name "*.txt" | grep -E "CSK[[:alnum:]]_KeyHash.txt|Tim_msg.txt|TIMHash.txt" | xargs rm -f else # ${WTP} -- cgit v1.2.3 From e4bbd39c65656d46a112b4b645469cd6747469e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Mon, 23 Nov 2020 19:45:28 +0100 Subject: plat: marvell: armada: Add missing FORCE, .PHONY and clean targets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FORCE target is used as a dependency for other file targets which needs to be always rebuilt. .PHONY target is standard Makefile target which specify non-file targets and therefore needs to be always rebuilt. Targets clean, realclean and distclean are .PHONY targets used to remove built files. Correctly set that mrvl_clean target is prerequisite for these clean targets to ensure that built files are removed. Finally this change with usage of FORCE target allows to remove mrvl_clean hack from the prerequisites of a8k ${DOIMAGETOOL} target which was used just to ensure that ${DOIMAGETOOL} is always rebuilt via make subprocess. Signed-off-by: Pali Rohár Change-Id: I2fa8971244b43f101d846fc433ef7b0b6f139c92 --- plat/marvell/armada/a3k/common/a3700_common.mk | 17 ++++++++++++++++- plat/marvell/armada/a8k/common/a8k_common.mk | 8 +++++++- plat/marvell/armada/common/marvell_common.mk | 1 + 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk index 437f5d050..09edee0d8 100644 --- a/plat/marvell/armada/a3k/common/a3700_common.mk +++ b/plat/marvell/armada/a3k/common/a3700_common.mk @@ -120,11 +120,12 @@ TIMBLDUARTARGS := $(MARVELL_SECURE_BOOT) UART $(IMAGESPATH) $(DOIMAGEPATH) $(CL $(DDR_TOPOLOGY) 0 0 $(DOIMAGE_CFG) $(TIMNCFG) $(TIMNSIG) 0 DOIMAGE_FLAGS := -r $(DOIMAGE_CFG) -v -D -$(DOIMAGETOOL): +$(DOIMAGETOOL): FORCE $(if $(value CRYPTOPP_PATH),,$(error "Platform '${PLAT}' for WTP image tool requires CRYPTOPP_PATH. Please set CRYPTOPP_PATH to point to the right directory")) $(Q)$(MAKE) --no-print-directory -C $(CRYPTOPP_PATH) -f GNUmakefile $(Q)$(MAKE) --no-print-directory -C $(DOIMAGEPATH)/wtptp/src/TBB_Linux -f TBB_linux.mak LIBDIR=$(CRYPTOPP_PATH) +.PHONY: mrvl_flash mrvl_flash: ${BUILD_PLAT}/${BOOT_IMAGE} ${DOIMAGETOOL} $(if $(value MV_DDR_PATH),,$(error "Platform '${PLAT}' for target '$@' requires MV_DDR_PATH. Please set MV_DDR_PATH to point to the right directory")) ${Q}${MAKE} --no-print-directory -C ${DOIMAGEPATH} WTMI_IMG=$(WTMI_IMG) MV_DDR_PATH=$(MV_DDR_PATH) @@ -181,9 +182,23 @@ ifeq ($(MARVELL_SECURE_BOOT),1) endif @find . -name "*.txt" | grep -E "CSK[[:alnum:]]_KeyHash.txt|Tim_msg.txt|TIMHash.txt" | xargs rm -f +clean realclean distclean: mrvl_clean + +.PHONY: mrvl_clean +mrvl_clean: + -$(Q)$(MAKE) --no-print-directory -C $(DOIMAGEPATH) MV_DDR_PATH=$(MV_DDR_PATH) clean + -$(Q)$(MAKE) --no-print-directory -C $(DOIMAGEPATH)/wtptp/src/TBB_Linux -f TBB_linux.mak LIBDIR=$(CRYPTOPP_PATH) clean +ifdef CRYPTOPP_PATH + -$(Q)$(MAKE) --no-print-directory -C $(CRYPTOPP_PATH) -f GNUmakefile clean +endif + else # ${WTP} +.PHONY: mrvl_flash mrvl_flash: $(error "Platform '${PLAT}' for target '$@' requires WTP. Please set WTP to point to the right directory") endif # ${WTP} + +.PHONY: FORCE +FORCE:; diff --git a/plat/marvell/armada/a8k/common/a8k_common.mk b/plat/marvell/armada/a8k/common/a8k_common.mk index 58394a46f..cf1516a28 100644 --- a/plat/marvell/armada/a8k/common/a8k_common.mk +++ b/plat/marvell/armada/a8k/common/a8k_common.mk @@ -152,14 +152,20 @@ BLE_PATH ?= $(PLAT_COMMON_BASE)/ble include ${BLE_PATH}/ble.mk $(eval $(call MAKE_BL,e)) +clean realclean distclean: mrvl_clean + +.PHONY: mrvl_clean mrvl_clean: @echo " Doimage CLEAN" ${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${DOIMAGEPATH} clean -${DOIMAGETOOL}: mrvl_clean +${DOIMAGETOOL}: FORCE @$(DOIMAGE_LIBS_CHECK) ${Q}${MAKE} --no-print-directory -C ${DOIMAGEPATH} +.PHONY: mrvl_flash mrvl_flash: ${BUILD_PLAT}/${BOOT_IMAGE} ${DOIMAGETOOL} ${DOIMAGETOOL} ${DOIMAGE_FLAGS} ${BUILD_PLAT}/${BOOT_IMAGE} ${BUILD_PLAT}/${FLASH_IMAGE} +.PHONY: FORCE +FORCE:; diff --git a/plat/marvell/armada/common/marvell_common.mk b/plat/marvell/armada/common/marvell_common.mk index 7f8dffa00..9d4cca114 100644 --- a/plat/marvell/armada/common/marvell_common.mk +++ b/plat/marvell/armada/common/marvell_common.mk @@ -93,4 +93,5 @@ $(BUILD_PLAT)/$(BOOT_IMAGE): $(BUILD_PLAT)/bl1.bin $(BUILD_PLAT)/$(FIP_NAME) @truncate -s %4 $(BUILD_PLAT)/$(BOOT_IMAGE) || { rm -f $(BUILD_PLAT)/$(BOOT_IMAGE); false; } @echo "Built $@ successfully" +.PHONY: mrvl_bootimage mrvl_bootimage: $(BUILD_PLAT)/$(BOOT_IMAGE) -- cgit v1.2.3 From 23b1be79d7243e7ec5f0e52c8d7dd9f9c1c618b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Thu, 3 Dec 2020 11:59:53 +0100 Subject: plat: marvell: armada: Maximal size of bl1 image in mrvl_bootimage is 128kB MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add check when building mrvl_bootimage that size of bl1 image is not bigger than maximal size. Signed-off-by: Pali Rohár Change-Id: Ib873debd3cfdba9acd4c168ee37edab3032e9f25 --- plat/marvell/armada/common/marvell_common.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/plat/marvell/armada/common/marvell_common.mk b/plat/marvell/armada/common/marvell_common.mk index 9d4cca114..e5ee710a6 100644 --- a/plat/marvell/armada/common/marvell_common.mk +++ b/plat/marvell/armada/common/marvell_common.mk @@ -87,6 +87,7 @@ include $(MARVELL_PLAT_BASE)/common/mss/mss_common.mk endif $(BUILD_PLAT)/$(BOOT_IMAGE): $(BUILD_PLAT)/bl1.bin $(BUILD_PLAT)/$(FIP_NAME) + $(if $(shell find $(BUILD_PLAT)/bl1.bin -type f -size +128k),$(error "Image '$(BUILD_PLAT)/bl1.bin' is bigger than 128kB")) @cp $(BUILD_PLAT)/bl1.bin $(BUILD_PLAT)/$(BOOT_IMAGE) || { rm -f $(BUILD_PLAT)/$(BOOT_IMAGE); false; } @truncate -s %128K $(BUILD_PLAT)/$(BOOT_IMAGE) || { rm -f $(BUILD_PLAT)/$(BOOT_IMAGE); false; } @cat $(BUILD_PLAT)/$(FIP_NAME) >> $(BUILD_PLAT)/$(BOOT_IMAGE) || { rm -f $(BUILD_PLAT)/$(BOOT_IMAGE); false; } -- cgit v1.2.3 From bc1f368743009bf405c23fc907b82e07965233bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Mon, 23 Nov 2020 19:49:23 +0100 Subject: plat: marvell: armada: a3k: Split building $(WTMI_MULTI_IMG) and $(TIMDDRTOOL) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These two targets are build by make subprocesses and are independent. So splitting them into own targets allow make to build them in parallel. $(TIMBUILD) script depends on $(TIMDDRTOOL) so specify it in Makefile. Signed-off-by: Pali Rohár Change-Id: I139fc7fe64d8de275b01a853e15bfb88c4ff840d --- plat/marvell/armada/a3k/common/a3700_common.mk | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk index 09edee0d8..7eddff9a9 100644 --- a/plat/marvell/armada/a3k/common/a3700_common.mk +++ b/plat/marvell/armada/a3k/common/a3700_common.mk @@ -85,6 +85,9 @@ endif #MARVELL_SECURE_BOOT TIMBUILD := $(DOIMAGEPATH)/script/buildtim.sh TIM2IMG := $(DOIMAGEPATH)/script/tim2img.pl +TIMDDRTOOL := $(DOIMAGEPATH)/tim/ddr/ddr_tool + +$(TIMBUILD): $(TIMDDRTOOL) # WTMI_IMG is used to specify the customized RTOS image running over # Service CPU (CM3 processor). By the default, it points to a @@ -125,10 +128,15 @@ $(DOIMAGETOOL): FORCE $(Q)$(MAKE) --no-print-directory -C $(CRYPTOPP_PATH) -f GNUmakefile $(Q)$(MAKE) --no-print-directory -C $(DOIMAGEPATH)/wtptp/src/TBB_Linux -f TBB_linux.mak LIBDIR=$(CRYPTOPP_PATH) +$(WTMI_MULTI_IMG): FORCE + $(Q)$(MAKE) --no-print-directory -C $(DOIMAGEPATH) WTMI_IMG=$(WTMI_IMG) WTMI + +$(TIMDDRTOOL): FORCE + $(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")) + $(Q)$(MAKE) --no-print-directory -C $(DOIMAGEPATH) MV_DDR_PATH=$(MV_DDR_PATH) mv_ddr + .PHONY: mrvl_flash -mrvl_flash: ${BUILD_PLAT}/${BOOT_IMAGE} ${DOIMAGETOOL} - $(if $(value MV_DDR_PATH),,$(error "Platform '${PLAT}' for target '$@' requires MV_DDR_PATH. Please set MV_DDR_PATH to point to the right directory")) - ${Q}${MAKE} --no-print-directory -C ${DOIMAGEPATH} WTMI_IMG=$(WTMI_IMG) MV_DDR_PATH=$(MV_DDR_PATH) +mrvl_flash: ${BUILD_PLAT}/${BOOT_IMAGE} ${WTMI_MULTI_IMG} ${DOIMAGETOOL} ${TIMBUILD} @echo @echo "Building uart images" $(TIMBUILD) $(TIMBLDUARTARGS) -- cgit v1.2.3 From e33370828db397a9bdd5a52315cf4772bdbca1a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Thu, 3 Dec 2020 12:00:47 +0100 Subject: plat: marvell: armada: a3k: Simplify check if WTP variable is defined MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pali Rohár Change-Id: Ieb352f0765882efdcb64ef54e6b2a39768590a06 --- plat/marvell/armada/a3k/common/a3700_common.mk | 6 +++--- 1 file 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 7eddff9a9..e2022fac7 100644 --- a/plat/marvell/armada/a3k/common/a3700_common.mk +++ b/plat/marvell/armada/a3k/common/a3700_common.mk @@ -64,7 +64,7 @@ BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \ $(PLAT_COMMON_BASE)/a3700_sip_svc.c \ $(MARVELL_DRV) -ifneq (${WTP},) +ifdef WTP DOIMAGEPATH := $(WTP) DOIMAGETOOL := $(DOIMAGEPATH)/wtptp/src/TBB_Linux/release/TBB_linux @@ -200,13 +200,13 @@ ifdef CRYPTOPP_PATH -$(Q)$(MAKE) --no-print-directory -C $(CRYPTOPP_PATH) -f GNUmakefile clean endif -else # ${WTP} +else # WTP .PHONY: mrvl_flash mrvl_flash: $(error "Platform '${PLAT}' for target '$@' requires WTP. Please set WTP to point to the right directory") -endif # ${WTP} +endif # WTP .PHONY: FORCE FORCE:; -- cgit v1.2.3 From b05d2792aec4eab096d6be1355f7134614ee92c3 Mon Sep 17 00:00:00 2001 From: Ravi Patel Date: Tue, 30 Jul 2019 04:10:07 -0700 Subject: xilinx: versal: Do not pass ACPU0 always in set_wakeup_source() Existing code passes ACPU0 to LibPM as node_id in set_wakeup_source() call because last suspending core will be ACPU0 in most of the case. Now it may be possible that user may disable the ACPU0 using hot-plug and after that it suspends Linux. So in that case ACPU0 will not be last suspending core. To overcome above scenario, pass the current running processor ID while calling set_wakeup_source(). Signed-off-by: Ravi Patel Signed-off-by: Rajan Vaja Change-Id: If15354c2150b5bb1305b5f93ca4e8c7a81d59f0a --- plat/xilinx/versal/pm_service/pm_client.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/plat/xilinx/versal/pm_service/pm_client.c b/plat/xilinx/versal/pm_service/pm_client.c index 5b47838e9..9ab921ee7 100644 --- a/plat/xilinx/versal/pm_service/pm_client.c +++ b/plat/xilinx/versal/pm_service/pm_client.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Xilinx, Inc. All rights reserved. + * Copyright (c) 2019-2020, Xilinx, Inc. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -113,8 +113,9 @@ static enum pm_device_node_idx irq_to_pm_node_idx(unsigned int irq) /** * pm_client_set_wakeup_sources - Set all devices with enabled interrupts as * wake sources in the LibPM. + * @node_id: Node id of processor */ -static void pm_client_set_wakeup_sources(void) +static void pm_client_set_wakeup_sources(uint32_t node_id) { uint32_t reg_num; uint32_t device_id; @@ -147,7 +148,7 @@ static void pm_client_set_wakeup_sources(void) (!pm_wakeup_nodes_set[node_idx])) { /* Get device ID from node index */ device_id = PERIPH_DEVID(node_idx); - ret = pm_set_wakeup_source(XPM_DEVID_ACPU_0, + ret = pm_set_wakeup_source(node_id, device_id, 1); pm_wakeup_nodes_set[node_idx] = !ret; } @@ -167,7 +168,7 @@ void pm_client_suspend(const struct pm_proc *proc, unsigned int state) bakery_lock_get(&pm_client_secure_lock); if (state == PM_STATE_SUSPEND_TO_RAM) - pm_client_set_wakeup_sources(); + pm_client_set_wakeup_sources(proc->node_id); /* Set powerdown request */ mmio_write_32(FPD_APU_PWRCTL, mmio_read_32(FPD_APU_PWRCTL) | -- cgit v1.2.3 From 4b8ab607ea412e5ee2d59c590789e40428e3d943 Mon Sep 17 00:00:00 2001 From: Venkatesh Yadav Abbarapu Date: Tue, 10 Dec 2019 22:16:36 -0500 Subject: plat: versal: Update API list in feature check Add below API in feature check list which is actually present in firmware: - PM_GET_CHIPID Signed-off-by: Venkatesh Yadav Abbarapu Signed-off-by: Ravi Patel Signed-off-by: Rajan Vaja Change-Id: I98b82da74164f065c8835861f74b0f2855e9bcbf --- plat/xilinx/versal/pm_service/pm_api_sys.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.c b/plat/xilinx/versal/pm_service/pm_api_sys.c index dbe94e624..75cc3d12e 100644 --- a/plat/xilinx/versal/pm_service/pm_api_sys.c +++ b/plat/xilinx/versal/pm_service/pm_api_sys.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Xilinx, Inc. All rights reserved. + * Copyright (c) 2019-2020, Xilinx, Inc. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -798,6 +798,7 @@ enum pm_ret_status pm_feature_check(uint32_t api_id, unsigned int *version) case PM_SET_REQUIREMENT: case PM_RESET_ASSERT: case PM_RESET_GET_STATUS: + case PM_GET_CHIPID: case PM_PINCTRL_REQUEST: case PM_PINCTRL_RELEASE: case PM_PINCTRL_GET_FUNCTION: -- cgit v1.2.3 From d4c7b55050df147dce8c243e6bc8a3e9645c027b Mon Sep 17 00:00:00 2001 From: Ravi Patel Date: Fri, 21 Jun 2019 05:00:49 -0700 Subject: xilinx: versal: Skip store/restore of GIC during CPU idle GIC registers needs to be stored/restored during system suspend/resume only and not during CPU idle. During CPU idle, minimum 1 CPU is in ON state. Signed-off-by: Ravi Patel Signed-off-by: Rajan Vaja Change-Id: I5de2ce3a61bf4260f9385349202b0f592a47aaba --- plat/xilinx/versal/plat_psci.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/plat/xilinx/versal/plat_psci.c b/plat/xilinx/versal/plat_psci.c index 39550858a..fda42dfda 100644 --- a/plat/xilinx/versal/plat_psci.c +++ b/plat/xilinx/versal/plat_psci.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -59,7 +59,9 @@ static void versal_pwr_domain_suspend(const psci_power_state_t *target_state) plat_versal_gic_cpuif_disable(); - plat_versal_gic_save(); + if (target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE) { + plat_versal_gic_save(); + } state = target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE ? PM_STATE_SUSPEND_TO_RAM : PM_STATE_CPU_IDLE; @@ -99,11 +101,9 @@ static void versal_pwr_domain_suspend_finish( /* APU was turned off, so restore GIC context */ if (target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE) { plat_versal_gic_resume(); - plat_versal_gic_cpuif_enable(); - } else { - plat_versal_gic_cpuif_enable(); - plat_versal_gic_pcpu_init(); } + + plat_versal_gic_cpuif_enable(); } void versal_pwr_domain_on_finish(const psci_power_state_t *target_state) -- cgit v1.2.3 From addc4e969bb157d736ccd0d46db85c8e9c835d42 Mon Sep 17 00:00:00 2001 From: Ravi Patel Date: Mon, 23 Nov 2020 04:19:08 -0800 Subject: plat: xilinx: Mask unnecessary bytes of return error code Versal firmware adds extra error codes along with PM error codes while sending response to driver. This makes incorrect error identification at driver side. To fix this, mask the unnecessary error bytes before sending the error code to the driver. Signed-off-by: Ravi Patel Signed-off-by: Rajan Vaja Change-Id: I18c2f3bd2d067e91344852c2f0c1bafea0e6eb23 --- plat/xilinx/common/pm_service/pm_ipi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plat/xilinx/common/pm_service/pm_ipi.c b/plat/xilinx/common/pm_service/pm_ipi.c index c83d25b0d..5dcceaea2 100644 --- a/plat/xilinx/common/pm_service/pm_ipi.c +++ b/plat/xilinx/common/pm_service/pm_ipi.c @@ -18,6 +18,8 @@ #include "pm_ipi.h" +#define ERROR_CODE_MASK 0xFFFFU + DEFINE_BAKERY_LOCK(pm_secure_lock); /** @@ -230,7 +232,7 @@ enum pm_ret_status pm_ipi_send_sync(const struct pm_proc *proc, if (ret != PM_RET_SUCCESS) goto unlock; - ret = pm_ipi_buff_read(proc, value, count); + ret = ERROR_CODE_MASK & (pm_ipi_buff_read(proc, value, count)); unlock: bakery_lock_release(&pm_secure_lock); -- cgit v1.2.3 From abf27efac609123c06d987d0532d2c04e8668591 Mon Sep 17 00:00:00 2001 From: Venkatesh Yadav Abbarapu Date: Mon, 23 Nov 2020 03:29:51 -0800 Subject: plat:xilinx:versal: Use defaults when PDI is without sw partitions In JTAG mode check the ATF handoff structure, if the magic string is not present then use bl32 and bl33 default values. Signed-off-by: Venkatesh Yadav Abbarapu Signed-off-by: Rajan Vaja Change-Id: I1f2c4a2060d8a2e70d3b5fb2473124b685f257fc --- plat/xilinx/versal/bl31_versal_setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/xilinx/versal/bl31_versal_setup.c b/plat/xilinx/versal/bl31_versal_setup.c index 03b7fbbb4..27991d381 100644 --- a/plat/xilinx/versal/bl31_versal_setup.c +++ b/plat/xilinx/versal/bl31_versal_setup.c @@ -97,7 +97,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, enum fsbl_handoff ret = fsbl_atf_handover(&bl32_image_ep_info, &bl33_image_ep_info, atf_handoff_addr); - if (ret == FSBL_HANDOFF_NO_STRUCT) { + if (ret == FSBL_HANDOFF_NO_STRUCT || ret == FSBL_HANDOFF_INVAL_STRUCT) { bl31_set_default_config(); } else if (ret != FSBL_HANDOFF_SUCCESS) { panic(); -- cgit v1.2.3 From 1ba2d84fe2959cc2f8720c38855760af5d77e298 Mon Sep 17 00:00:00 2001 From: Rajan Vaja Date: Mon, 23 Nov 2020 04:13:54 -0800 Subject: xilinx: versal: Updated Response of QueryData API call For the current XilPM calls, The handler of IPI returns information with 16 Bytes data. So during QueryData API call for the ClockName and PinFunctionName, response data(name of clock or function) response[0..3] are used to return name. And status is not being returned for such API. Updated XilPM calls reply in a consistent way and The handler of IPI return information with 32Bytes data. Where response[0] always set to status. For the version-2 of QueryData API, during call for the ClockName and PinFunctionName, response data(name of clock or function) get as response[1...4]. To support both the version of QueryData API, added version based compatibility by the use of feature check. Signed-off-by: Venkatesh Yadav Abbarapu Signed-off-by: Amit Sunil Dhamne Signed-off-by: Rajan Vaja Change-Id: I336128bff7bbe659903b0f8ce20ae6da7e3b51b4 --- plat/xilinx/versal/pm_service/pm_api_sys.c | 26 +++++++++++++++++++++++++- plat/xilinx/versal/pm_service/pm_defs.h | 25 ++++++++++++++++++++++++- plat/xilinx/versal/pm_service/pm_svc_main.c | 9 +++++---- 3 files changed, 54 insertions(+), 6 deletions(-) diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.c b/plat/xilinx/versal/pm_service/pm_api_sys.c index 75cc3d12e..dd9ff6445 100644 --- a/plat/xilinx/versal/pm_service/pm_api_sys.c +++ b/plat/xilinx/versal/pm_service/pm_api_sys.c @@ -14,6 +14,7 @@ #include #include "pm_api_sys.h" #include "pm_client.h" +#include "pm_defs.h" /********************************************************************* * Target module IDs macros @@ -689,12 +690,31 @@ enum pm_ret_status pm_system_shutdown(uint32_t type, uint32_t subtype) enum pm_ret_status pm_query_data(uint32_t qid, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t *data) { + uint32_t ret; + uint32_t version; uint32_t payload[PAYLOAD_ARG_CNT]; + uint32_t fw_api_version; /* Send request to the PMC */ PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, PM_QUERY_DATA, qid, arg1, arg2, arg3); - return pm_ipi_send_sync(primary_proc, payload, data, 4); + + ret = pm_feature_check(PM_QUERY_DATA, &version); + if (PM_RET_SUCCESS == ret){ + fw_api_version = version & 0xFFFF ; + if ((2U == fw_api_version) && + ((XPM_QID_CLOCK_GET_NAME == qid) || + (XPM_QID_PINCTRL_GET_FUNCTION_NAME == qid))) { + ret = pm_ipi_send_sync(primary_proc, payload, data, 8); + ret = data[0]; + data[0] = data[1]; + data[1] = data[2]; + data[2] = data[3]; + } else { + ret = pm_ipi_send_sync(primary_proc, payload, data, 4); + } + } + return ret; } /** * pm_api_ioctl() - PM IOCTL API for device control and configs @@ -806,7 +826,11 @@ enum pm_ret_status pm_feature_check(uint32_t api_id, unsigned int *version) case PM_PINCTRL_CONFIG_PARAM_GET: case PM_PINCTRL_CONFIG_PARAM_SET: case PM_IOCTL: + *version = (PM_API_BASE_VERSION << 16); + break; case PM_QUERY_DATA: + *version = (PM_API_QUERY_DATA_VERSION << 16); + break; case PM_CLOCK_ENABLE: case PM_CLOCK_DISABLE: case PM_CLOCK_GETSTATE: diff --git a/plat/xilinx/versal/pm_service/pm_defs.h b/plat/xilinx/versal/pm_service/pm_defs.h index 966b00bb5..b8c017c3e 100644 --- a/plat/xilinx/versal/pm_service/pm_defs.h +++ b/plat/xilinx/versal/pm_service/pm_defs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Xilinx, Inc. All rights reserved. + * Copyright (c) 2019-2020, Xilinx, Inc. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -39,6 +39,8 @@ /* PM API Versions */ #define PM_API_BASE_VERSION 1U +#define PM_API_QUERY_DATA_VERSION 2U + /* PM API ids */ #define PM_GET_API_VERSION 1U #define PM_GET_DEVICE_STATUS 3U @@ -163,4 +165,25 @@ enum pm_ret_status { PM_RET_ERROR_TIMEOUT = 2006, PM_RET_ERROR_NODE_USED = 2007 }; + +/** + * Qids + */ +enum pm_query_id { + XPM_QID_INVALID, + XPM_QID_CLOCK_GET_NAME, + XPM_QID_CLOCK_GET_TOPOLOGY, + XPM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS, + XPM_QID_CLOCK_GET_MUXSOURCES, + XPM_QID_CLOCK_GET_ATTRIBUTES, + XPM_QID_PINCTRL_GET_NUM_PINS, + XPM_QID_PINCTRL_GET_NUM_FUNCTIONS, + XPM_QID_PINCTRL_GET_NUM_FUNCTION_GROUPS, + XPM_QID_PINCTRL_GET_FUNCTION_NAME, + XPM_QID_PINCTRL_GET_FUNCTION_GROUPS, + XPM_QID_PINCTRL_GET_PIN_GROUPS, + XPM_QID_CLOCK_GET_NUM_CLOCKS, + XPM_QID_CLOCK_GET_MAX_DIVISOR, + XPM_QID_PLD_GET_PARENT, +}; #endif /* PM_DEFS_H */ diff --git a/plat/xilinx/versal/pm_service/pm_svc_main.c b/plat/xilinx/versal/pm_service/pm_svc_main.c index 45b280370..f0e42d651 100644 --- a/plat/xilinx/versal/pm_service/pm_svc_main.c +++ b/plat/xilinx/versal/pm_service/pm_svc_main.c @@ -214,14 +214,15 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, case PM_QUERY_DATA: { - uint32_t data[4] = { 0 }; + uint32_t data[8] = { 0 }; ret = pm_query_data(pm_arg[0], pm_arg[1], pm_arg[2], - pm_arg[3], data); + pm_arg[3], data); + SMC_RET2(handle, (uint64_t)ret | ((uint64_t)data[0] << 32), - (uint64_t)data[1] | ((uint64_t)data[2] << 32)); - } + (uint64_t)data[1] | ((uint64_t)data[2] << 32)); + } case PM_CLOCK_ENABLE: ret = pm_clock_enable(pm_arg[0]); SMC_RET1(handle, (uint64_t)ret); -- cgit v1.2.3 From 2cc1fa9537e793af7c7d659dd53fc62f9e80a4d6 Mon Sep 17 00:00:00 2001 From: Ravi Patel Date: Mon, 12 Aug 2019 03:10:10 -0700 Subject: plat: versal: Add InitFinalize API call Add support to call InitFinalize API in Versal which calls corresponding LibPM API. Signed-off-by: Ravi Patel Signed-off-by: Rajan Vaja Change-Id: I3428b7245b4db1ef6db8a90b7ad20b6e484ed3b2 --- plat/xilinx/versal/pm_service/pm_api_sys.c | 18 +++++++++++++++++- plat/xilinx/versal/pm_service/pm_api_sys.h | 3 ++- plat/xilinx/versal/pm_service/pm_svc_main.c | 3 ++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.c b/plat/xilinx/versal/pm_service/pm_api_sys.c index dd9ff6445..1f7539d96 100644 --- a/plat/xilinx/versal/pm_service/pm_api_sys.c +++ b/plat/xilinx/versal/pm_service/pm_api_sys.c @@ -84,6 +84,22 @@ enum pm_ret_status pm_get_api_version(unsigned int *version) return pm_ipi_send_sync(primary_proc, payload, version, 1); } +/** + * pm_init_finalize() - Call to notify PMC PM firmware that master has power + * management enabled and that it has finished its + * initialization + * + * @return Status returned by the PMU firmware + */ +enum pm_ret_status pm_init_finalize(void) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMU */ + PM_PACK_PAYLOAD1(payload, LIBPM_MODULE_ID, PM_INIT_FINALIZE); + return pm_ipi_send_sync(primary_proc, payload, NULL, 0); +} + /** * pm_self_suspend() - PM call for processor to suspend itself * @nid Node id of the processor or subsystem @@ -800,7 +816,6 @@ enum pm_ret_status pm_feature_check(uint32_t api_id, unsigned int *version) switch (api_id) { case PM_GET_CALLBACK_DATA: case PM_GET_TRUSTZONE_VERSION: - case PM_INIT_FINALIZE: *version = (PM_API_BASE_VERSION << 16); return PM_RET_SUCCESS; case PM_GET_API_VERSION: @@ -843,6 +858,7 @@ enum pm_ret_status pm_feature_check(uint32_t api_id, unsigned int *version) case PM_PLL_SET_MODE: case PM_PLL_GET_MODE: case PM_FEATURE_CHECK: + case PM_INIT_FINALIZE: *version = (PM_API_BASE_VERSION << 16); break; case PM_LOAD_PDI: diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.h b/plat/xilinx/versal/pm_service/pm_api_sys.h index 4de592a2f..dd2aefc47 100644 --- a/plat/xilinx/versal/pm_service/pm_api_sys.h +++ b/plat/xilinx/versal/pm_service/pm_api_sys.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Xilinx, Inc. All rights reserved. + * Copyright (c) 2019-2020, Xilinx, Inc. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -15,6 +15,7 @@ **********************************************************/ enum pm_ret_status pm_get_api_version(unsigned int *version); +enum pm_ret_status pm_init_finalize(void); enum pm_ret_status pm_self_suspend(uint32_t nid, unsigned int latency, unsigned int state, diff --git a/plat/xilinx/versal/pm_service/pm_svc_main.c b/plat/xilinx/versal/pm_service/pm_svc_main.c index f0e42d651..9ad13da5d 100644 --- a/plat/xilinx/versal/pm_service/pm_svc_main.c +++ b/plat/xilinx/versal/pm_service/pm_svc_main.c @@ -159,7 +159,8 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, } case PM_INIT_FINALIZE: - SMC_RET1(handle, (uint64_t)PM_RET_SUCCESS); + ret = pm_init_finalize(); + SMC_RET1(handle, (uint64_t)ret); case PM_GET_CALLBACK_DATA: { -- cgit v1.2.3 From 07d8a5f7dc0aed07382cd7d3a276988b2e02b76d Mon Sep 17 00:00:00 2001 From: Tejas Patel Date: Wed, 25 Nov 2020 01:53:12 -0800 Subject: plat: xilinx: versal: Add support of set max latency for the device Add support of set max latency, to change in the maximum powerup latency requirements for a specific device currently used by Subsystem. Signed-off-by: Tejas Patel Signed-off-by: Rajan Vaja Change-Id: I8749886abb1a7884a42c4d156d89c9cd562a5b1a --- plat/xilinx/versal/pm_service/pm_api_sys.c | 21 +++++++++++++++++++++ plat/xilinx/versal/pm_service/pm_api_sys.h | 1 + plat/xilinx/versal/pm_service/pm_defs.h | 1 + plat/xilinx/versal/pm_service/pm_svc_main.c | 6 ++++++ 4 files changed, 29 insertions(+) diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.c b/plat/xilinx/versal/pm_service/pm_api_sys.c index 1f7539d96..bb14c42e3 100644 --- a/plat/xilinx/versal/pm_service/pm_api_sys.c +++ b/plat/xilinx/versal/pm_service/pm_api_sys.c @@ -859,6 +859,7 @@ enum pm_ret_status pm_feature_check(uint32_t api_id, unsigned int *version) case PM_PLL_GET_MODE: case PM_FEATURE_CHECK: case PM_INIT_FINALIZE: + case PM_SET_MAX_LATENCY: *version = (PM_API_BASE_VERSION << 16); break; case PM_LOAD_PDI: @@ -924,3 +925,23 @@ enum pm_ret_status pm_get_op_characteristic(uint32_t device_id, device_id, type); return pm_ipi_send_sync(primary_proc, payload, result, 1); } + +/** + * pm_set_max_latency() - PM call to change in the maximum wake-up latency + * requirements for a specific device currently + * used by that CPU. + * @device_id Device ID + * @latency Latency value + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_set_max_latency(uint32_t device_id, uint32_t latency) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMC */ + PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, PM_SET_MAX_LATENCY, + device_id, latency); + + return pm_ipi_send_sync(primary_proc, payload, NULL, 0); +} diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.h b/plat/xilinx/versal/pm_service/pm_api_sys.h index dd2aefc47..a280b3eb0 100644 --- a/plat/xilinx/versal/pm_service/pm_api_sys.h +++ b/plat/xilinx/versal/pm_service/pm_api_sys.h @@ -73,4 +73,5 @@ enum pm_ret_status pm_load_pdi(uint32_t src, uint32_t address_low, enum pm_ret_status pm_get_op_characteristic(uint32_t device_id, enum pm_opchar_type type, uint32_t *result); +enum pm_ret_status pm_set_max_latency(uint32_t device_id, uint32_t latency); #endif /* PM_API_SYS_H */ diff --git a/plat/xilinx/versal/pm_service/pm_defs.h b/plat/xilinx/versal/pm_service/pm_defs.h index b8c017c3e..5f59ba7cb 100644 --- a/plat/xilinx/versal/pm_service/pm_defs.h +++ b/plat/xilinx/versal/pm_service/pm_defs.h @@ -55,6 +55,7 @@ #define PM_REQUEST_DEVICE 13U #define PM_RELEASE_DEVICE 14U #define PM_SET_REQUIREMENT 15U +#define PM_SET_MAX_LATENCY 16U #define PM_RESET_ASSERT 17U #define PM_RESET_GET_STATUS 18U #define PM_INIT_FINALIZE 21U diff --git a/plat/xilinx/versal/pm_service/pm_svc_main.c b/plat/xilinx/versal/pm_service/pm_svc_main.c index 9ad13da5d..295d1e5f6 100644 --- a/plat/xilinx/versal/pm_service/pm_svc_main.c +++ b/plat/xilinx/versal/pm_service/pm_svc_main.c @@ -323,6 +323,12 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, SMC_RET1(handle, (uint64_t)ret | ((uint64_t)result << 32)); } + case PM_SET_MAX_LATENCY: + { + ret = pm_set_max_latency(pm_arg[0], pm_arg[1]); + SMC_RET1(handle, (uint64_t)ret); + } + default: WARN("Unimplemented PM Service Call: 0x%x\n", smc_fid); SMC_RET1(handle, SMC_UNK); -- cgit v1.2.3 From b6d7b3e9d616c255ad9ebaea7e029b383a2c9add Mon Sep 17 00:00:00 2001 From: Tejas Patel Date: Tue, 1 Sep 2020 04:43:53 -0700 Subject: plat: xilinx: versal: Add support to get clock rate value Add support to get clock's rate value. Signed-off-by: Tejas Patel Signed-off-by: Rajan Vaja Change-Id: I3ed881053ef323b2ca73e13edd0affda860d381d --- plat/xilinx/versal/pm_service/pm_api_sys.c | 17 +++++++++++++++++ plat/xilinx/versal/pm_service/pm_api_sys.h | 1 + plat/xilinx/versal/pm_service/pm_svc_main.c | 9 +++++++++ 3 files changed, 27 insertions(+) diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.c b/plat/xilinx/versal/pm_service/pm_api_sys.c index bb14c42e3..fd0581efa 100644 --- a/plat/xilinx/versal/pm_service/pm_api_sys.c +++ b/plat/xilinx/versal/pm_service/pm_api_sys.c @@ -571,6 +571,22 @@ enum pm_ret_status pm_clock_get_parent(uint32_t clk_id, uint32_t *parent) return pm_ipi_send_sync(primary_proc, payload, parent, 1); } +/** + * pm_clock_get_rate() - Get the rate value for the clock + * @clk_id Clock ID + * @rate: Buffer to store clock rate value + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_clock_get_rate(uint32_t clk_id, uint32_t *clk_rate) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMC */ + PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, PM_CLOCK_GETRATE, clk_id); + + return pm_ipi_send_sync(primary_proc, payload, clk_rate, 2); +} /** * pm_pll_set_param() - Set PLL parameter @@ -853,6 +869,7 @@ enum pm_ret_status pm_feature_check(uint32_t api_id, unsigned int *version) case PM_CLOCK_GETDIVIDER: case PM_CLOCK_SETPARENT: case PM_CLOCK_GETPARENT: + case PM_CLOCK_GETRATE: case PM_PLL_SET_PARAMETER: case PM_PLL_GET_PARAMETER: case PM_PLL_SET_MODE: diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.h b/plat/xilinx/versal/pm_service/pm_api_sys.h index a280b3eb0..72f00763f 100644 --- a/plat/xilinx/versal/pm_service/pm_api_sys.h +++ b/plat/xilinx/versal/pm_service/pm_api_sys.h @@ -53,6 +53,7 @@ enum pm_ret_status pm_clock_set_divider(uint32_t clk_id, uint32_t divider); enum pm_ret_status pm_clock_get_divider(uint32_t clk_id, uint32_t *divider); enum pm_ret_status pm_clock_set_parent(uint32_t clk_id, uint32_t parent); enum pm_ret_status pm_clock_get_parent(uint32_t clk_id, uint32_t *parent); +enum pm_ret_status pm_clock_get_rate(uint32_t clk_id, uint32_t *clk_rate); enum pm_ret_status pm_pll_set_param(uint32_t clk_id, uint32_t param, uint32_t value); enum pm_ret_status pm_pll_get_param(uint32_t clk_id, uint32_t param, diff --git a/plat/xilinx/versal/pm_service/pm_svc_main.c b/plat/xilinx/versal/pm_service/pm_svc_main.c index 295d1e5f6..f2c248e15 100644 --- a/plat/xilinx/versal/pm_service/pm_svc_main.c +++ b/plat/xilinx/versal/pm_service/pm_svc_main.c @@ -264,6 +264,15 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32); } + case PM_CLOCK_GETRATE: + { + uint32_t rate[2] = { 0 }; + + ret = pm_clock_get_rate(pm_arg[0], rate); + SMC_RET2(handle, (uint64_t)ret | ((uint64_t)rate[0] << 32), + rate[1]); + } + case PM_PLL_SET_PARAMETER: ret = pm_pll_set_param(pm_arg[0], pm_arg[1], pm_arg[2]); SMC_RET1(handle, (uint64_t)ret); -- cgit v1.2.3 From 6af1228677a5fed17dbcfa92eacf83cba4b9a92b Mon Sep 17 00:00:00 2001 From: Tejas Patel Date: Wed, 25 Nov 2020 01:56:57 -0800 Subject: plat: xilinx: versal: Add support of register notifier Add support of register notifier. Signed-off-by: Tejas Patel Signed-off-by: Rajan Vaja Change-Id: I41ef4c63abcc9aee552790b843adb25a5fd0c23e --- plat/xilinx/versal/pm_service/pm_api_sys.c | 23 +++++++++++++++++++++++ plat/xilinx/versal/pm_service/pm_api_sys.h | 2 ++ plat/xilinx/versal/pm_service/pm_defs.h | 1 + plat/xilinx/versal/pm_service/pm_svc_main.c | 6 ++++++ 4 files changed, 32 insertions(+) diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.c b/plat/xilinx/versal/pm_service/pm_api_sys.c index fd0581efa..df6c9af49 100644 --- a/plat/xilinx/versal/pm_service/pm_api_sys.c +++ b/plat/xilinx/versal/pm_service/pm_api_sys.c @@ -877,6 +877,7 @@ enum pm_ret_status pm_feature_check(uint32_t api_id, unsigned int *version) case PM_FEATURE_CHECK: case PM_INIT_FINALIZE: case PM_SET_MAX_LATENCY: + case PM_REGISTER_NOTIFIER: *version = (PM_API_BASE_VERSION << 16); break; case PM_LOAD_PDI: @@ -962,3 +963,25 @@ enum pm_ret_status pm_set_max_latency(uint32_t device_id, uint32_t latency) return pm_ipi_send_sync(primary_proc, payload, NULL, 0); } + +/** + * pm_register_notifier() - PM call to register a subsystem to be notified + * about the device event + * @device_id Device ID for the Node to which the event is related + * @event Event in question + * @wake Wake subsystem upon capturing the event if value 1 + * @enable Enable the registration for value 1, disable for value 0 + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_register_notifier(uint32_t device_id, uint32_t event, + uint32_t wake, uint32_t enable) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMC */ + PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, PM_REGISTER_NOTIFIER, + device_id, event, wake, enable); + + return pm_ipi_send_sync(primary_proc, payload, NULL, 0); +} diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.h b/plat/xilinx/versal/pm_service/pm_api_sys.h index 72f00763f..84867b638 100644 --- a/plat/xilinx/versal/pm_service/pm_api_sys.h +++ b/plat/xilinx/versal/pm_service/pm_api_sys.h @@ -75,4 +75,6 @@ enum pm_ret_status pm_get_op_characteristic(uint32_t device_id, enum pm_opchar_type type, uint32_t *result); enum pm_ret_status pm_set_max_latency(uint32_t device_id, uint32_t latency); +enum pm_ret_status pm_register_notifier(uint32_t device_id, uint32_t event, + uint32_t wake, uint32_t enable); #endif /* PM_API_SYS_H */ diff --git a/plat/xilinx/versal/pm_service/pm_defs.h b/plat/xilinx/versal/pm_service/pm_defs.h index 5f59ba7cb..793f75009 100644 --- a/plat/xilinx/versal/pm_service/pm_defs.h +++ b/plat/xilinx/versal/pm_service/pm_defs.h @@ -45,6 +45,7 @@ #define PM_GET_API_VERSION 1U #define PM_GET_DEVICE_STATUS 3U #define PM_GET_OP_CHARACTERISTIC 4U +#define PM_REGISTER_NOTIFIER 5U #define PM_REQ_SUSPEND 6U #define PM_SELF_SUSPEND 7U #define PM_FORCE_POWERDOWN 8U diff --git a/plat/xilinx/versal/pm_service/pm_svc_main.c b/plat/xilinx/versal/pm_service/pm_svc_main.c index f2c248e15..2ed6d2701 100644 --- a/plat/xilinx/versal/pm_service/pm_svc_main.c +++ b/plat/xilinx/versal/pm_service/pm_svc_main.c @@ -338,6 +338,12 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, SMC_RET1(handle, (uint64_t)ret); } + case PM_REGISTER_NOTIFIER: + { + ret = pm_register_notifier(pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3]); + SMC_RET1(handle, (uint64_t)ret); + } + default: WARN("Unimplemented PM Service Call: 0x%x\n", smc_fid); SMC_RET1(handle, SMC_UNK); -- cgit v1.2.3 From 3d1e536eea5818218f55aa68909eeee0e78a53e0 Mon Sep 17 00:00:00 2001 From: James Liao Date: Tue, 16 Jun 2020 13:28:28 +0800 Subject: mediatek: mt8192: Add SPMC driver Add SPMC driver for CPU power on/off. Change-Id: I526b98d5885855efce019dd09cfd93b8816cbf19 Signed-off-by: James Liao --- plat/mediatek/mt8192/drivers/spmc/mtspmc.c | 177 ++++++++++++++ plat/mediatek/mt8192/drivers/spmc/mtspmc.h | 31 +++ plat/mediatek/mt8192/drivers/spmc/mtspmc_private.h | 184 +++++++++++++++ plat/mediatek/mt8192/include/mcucfg.h | 257 +++++++++++++++++++++ plat/mediatek/mt8192/include/platform_def.h | 1 + plat/mediatek/mt8192/platform.mk | 3 +- 6 files changed, 652 insertions(+), 1 deletion(-) create mode 100644 plat/mediatek/mt8192/drivers/spmc/mtspmc.c create mode 100644 plat/mediatek/mt8192/drivers/spmc/mtspmc.h create mode 100644 plat/mediatek/mt8192/drivers/spmc/mtspmc_private.h create mode 100644 plat/mediatek/mt8192/include/mcucfg.h diff --git a/plat/mediatek/mt8192/drivers/spmc/mtspmc.c b/plat/mediatek/mt8192/drivers/spmc/mtspmc.c new file mode 100644 index 000000000..7ccebd6ab --- /dev/null +++ b/plat/mediatek/mt8192/drivers/spmc/mtspmc.c @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include + +#include +#include +#include + + +void mcucfg_disable_gic_wakeup(uint32_t cluster, uint32_t cpu) +{ + mmio_setbits_32(MCUCFG_CPC_FLOW_CTRL_CFG, GIC_WAKEUP_IGNORE(cpu)); +} + +void mcucfg_enable_gic_wakeup(uint32_t cluster, uint32_t cpu) +{ + mmio_clrbits_32(MCUCFG_CPC_FLOW_CTRL_CFG, GIC_WAKEUP_IGNORE(cpu)); +} + +void mcucfg_set_bootaddr(uint32_t cluster, uint32_t cpu, uintptr_t bootaddr) +{ + assert(cluster == 0U); + + mmio_write_32(per_cpu(cluster, cpu, MCUCFG_BOOTADDR), bootaddr); +} + +uintptr_t mcucfg_get_bootaddr(uint32_t cluster, uint32_t cpu) +{ + assert(cluster == 0U); + + return (uintptr_t)mmio_read_32(per_cpu(cluster, cpu, MCUCFG_BOOTADDR)); +} + +void mcucfg_init_archstate(uint32_t cluster, uint32_t cpu, bool arm64) +{ + uint32_t reg; + + assert(cluster == 0U); + + reg = per_cluster(cluster, MCUCFG_INITARCH); + + if (arm64) { + mmio_setbits_32(reg, MCUCFG_INITARCH_CPU_BIT(cpu)); + } else { + mmio_clrbits_32(reg, MCUCFG_INITARCH_CPU_BIT(cpu)); + } +} + +/** + * Return subsystem's power state. + * + * @mask: mask to SPM_CPU_PWR_STATUS to query the power state + * of one subsystem. + * RETURNS: + * 0 (the subsys was powered off) + * 1 (the subsys was powered on) + */ +bool spm_get_powerstate(uint32_t mask) +{ + return (mmio_read_32(SPM_CPU_PWR_STATUS) & mask) != 0U; +} + +bool spm_get_cluster_powerstate(uint32_t cluster) +{ + assert(cluster == 0U); + + return spm_get_powerstate(MP0_CPUTOP); +} + +bool spm_get_cpu_powerstate(uint32_t cluster, uint32_t cpu) +{ + uint32_t mask = BIT(cpu); + + assert(cluster == 0U); + + return spm_get_powerstate(mask); +} + +int spmc_init(void) +{ + INFO("SPM: enable CPC mode\n"); + + mmio_write_32(SPM_POWERON_CONFIG_EN, PROJECT_CODE | BCLK_CG_EN); + + mmio_setbits_32(per_cpu(0, 1, SPM_CPU_PWR), PWR_RST_B); + mmio_setbits_32(per_cpu(0, 2, SPM_CPU_PWR), PWR_RST_B); + mmio_setbits_32(per_cpu(0, 3, SPM_CPU_PWR), PWR_RST_B); + mmio_setbits_32(per_cpu(0, 4, SPM_CPU_PWR), PWR_RST_B); + mmio_setbits_32(per_cpu(0, 5, SPM_CPU_PWR), PWR_RST_B); + mmio_setbits_32(per_cpu(0, 6, SPM_CPU_PWR), PWR_RST_B); + mmio_setbits_32(per_cpu(0, 7, SPM_CPU_PWR), PWR_RST_B); + + mmio_setbits_32(MCUCFG_CPC_FLOW_CTRL_CFG, GIC_WAKEUP_IGNORE(1)); + mmio_setbits_32(MCUCFG_CPC_FLOW_CTRL_CFG, GIC_WAKEUP_IGNORE(2)); + mmio_setbits_32(MCUCFG_CPC_FLOW_CTRL_CFG, GIC_WAKEUP_IGNORE(3)); + mmio_setbits_32(MCUCFG_CPC_FLOW_CTRL_CFG, GIC_WAKEUP_IGNORE(4)); + mmio_setbits_32(MCUCFG_CPC_FLOW_CTRL_CFG, GIC_WAKEUP_IGNORE(5)); + mmio_setbits_32(MCUCFG_CPC_FLOW_CTRL_CFG, GIC_WAKEUP_IGNORE(6)); + mmio_setbits_32(MCUCFG_CPC_FLOW_CTRL_CFG, GIC_WAKEUP_IGNORE(7)); + + mmio_clrbits_32(SPM_MCUSYS_PWR_CON, RESETPWRON_CONFIG); + mmio_clrbits_32(SPM_MP0_CPUTOP_PWR_CON, RESETPWRON_CONFIG); + mmio_clrbits_32(per_cpu(0, 0, SPM_CPU_PWR), RESETPWRON_CONFIG); + + mmio_setbits_32(MCUCFG_CPC_FLOW_CTRL_CFG, CPC_CTRL_ENABLE); + + return 0; +} + +/** + * Power on a core with specified cluster and core index + * + * @cluster: the cluster ID of the CPU which to be powered on + * @cpu: the CPU ID of the CPU which to be powered on + */ +void spm_poweron_cpu(uint32_t cluster, uint32_t cpu) +{ + /* set to 0 after BIG VPROC bulk on & before B-core power on seq. */ + if (cpu >= 4U) { + mmio_write_32(DREQ20_BIG_VPROC_ISO, 0U); + } + + mmio_setbits_32(MCUCFG_CPC_FLOW_CTRL_CFG, SSPM_ALL_PWR_CTRL_EN); + mmio_setbits_32(per_cpu(cluster, cpu, SPM_CPU_PWR), PWR_ON); + + while (!spm_get_cpu_powerstate(cluster, cpu)) { + } + + mmio_clrbits_32(MCUCFG_CPC_FLOW_CTRL_CFG, SSPM_ALL_PWR_CTRL_EN); + + /* Enable Big CPU Last PC */ + if (cpu >= 4U) { + mmio_clrbits_32(LAST_PC_REG(cpu), BIT(3)); + } +} + +/** + * Power off a core with specified cluster and core index + * + * @cluster: the cluster ID of the CPU which to be powered off + * @cpu: the CPU ID of the CPU which to be powered off + */ +void spm_poweroff_cpu(uint32_t cluster, uint32_t cpu) +{ + /* Set mp0_spmc_pwr_on_cpuX = 0 */ + mmio_clrbits_32(per_cpu(cluster, cpu, SPM_CPU_PWR), PWR_ON); +} + +/** + * Power off a cluster with specified index + * + * @cluster: the cluster index which to be powered off + */ +void spm_poweroff_cluster(uint32_t cluster) +{ + /* No need to power on/off cluster on single cluster platform */ + assert(false); +} + +/** + * Power on a cluster with specified index + * + * @cluster: the cluster index which to be powered on + */ +void spm_poweron_cluster(uint32_t cluster) +{ + /* No need to power on/off cluster on single cluster platform */ + assert(false); +} diff --git a/plat/mediatek/mt8192/drivers/spmc/mtspmc.h b/plat/mediatek/mt8192/drivers/spmc/mtspmc.h new file mode 100644 index 000000000..7ed2e6220 --- /dev/null +++ b/plat/mediatek/mt8192/drivers/spmc/mtspmc.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MTSPMC_H +#define MTSPMC_H + +#include + +int spmc_init(void); + +void spm_poweron_cpu(uint32_t cluster, uint32_t cpu); +void spm_poweroff_cpu(uint32_t cluster, uint32_t cpu); + +void spm_poweroff_cluster(uint32_t cluster); +void spm_poweron_cluster(uint32_t cluster); + +bool spm_get_cpu_powerstate(uint32_t cluster, uint32_t cpu); +bool spm_get_cluster_powerstate(uint32_t cluster); +bool spm_get_powerstate(uint32_t mask); + +void mcucfg_init_archstate(uint32_t cluster, uint32_t cpu, bool arm64); +void mcucfg_set_bootaddr(uint32_t cluster, uint32_t cpu, uintptr_t bootaddr); +uintptr_t mcucfg_get_bootaddr(uint32_t cluster, uint32_t cpu); + +void mcucfg_disable_gic_wakeup(uint32_t cluster, uint32_t cpu); +void mcucfg_enable_gic_wakeup(uint32_t cluster, uint32_t cpu); + +#endif /* MTSPMC_H */ diff --git a/plat/mediatek/mt8192/drivers/spmc/mtspmc_private.h b/plat/mediatek/mt8192/drivers/spmc/mtspmc_private.h new file mode 100644 index 000000000..ad782955d --- /dev/null +++ b/plat/mediatek/mt8192/drivers/spmc/mtspmc_private.h @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MTSPMC_PRIVATE_H +#define MTSPMC_PRIVATE_H + +#include +#include + +unsigned long read_cpuectlr(void); +void write_cpuectlr(unsigned long cpuectlr); + +unsigned long read_cpupwrctlr_el1(void); +void write_cpupwrctlr_el1(unsigned long cpuectlr); + +/* + * per_cpu/cluster helper + */ +struct per_cpu_reg { + unsigned int cluster_addr; + unsigned int cpu_stride; +}; + +#define per_cpu(cluster, cpu, reg) \ + (reg[cluster].cluster_addr + (cpu << reg[cluster].cpu_stride)) + +#define per_cluster(cluster, reg) (reg[cluster].cluster_addr) + +#define SPM_REG(ofs) (uint32_t)(SPM_BASE + (ofs)) +#define MCUCFG_REG(ofs) (uint32_t)(MCUCFG_BASE + (ofs)) +#define INFRACFG_AO_REG(ofs) (uint32_t)(INFRACFG_AO_BASE + (ofs)) + +/* === SPMC related registers */ +#define SPM_POWERON_CONFIG_EN SPM_REG(0x000) +/* bit-fields of SPM_POWERON_CONFIG_EN */ +#define PROJECT_CODE (U(0xb16) << 16) +#define BCLK_CG_EN BIT(0) + +#define SPM_PWR_STATUS SPM_REG(0x16c) +#define SPM_PWR_STATUS_2ND SPM_REG(0x170) +#define SPM_CPU_PWR_STATUS SPM_REG(0x174) + +/* bit-fields of SPM_PWR_STATUS */ +#define MD BIT(0) +#define CONN BIT(1) +#define DDRPHY BIT(2) +#define DISP BIT(3) +#define MFG BIT(4) +#define ISP BIT(5) +#define INFRA BIT(6) +#define VDEC BIT(7) +#define MP0_CPUTOP BIT(8) +#define MP0_CPU0 BIT(9) +#define MP0_CPU1 BIT(10) +#define MP0_CPU2 BIT(11) +#define MP0_CPU3 BIT(12) +#define MCUSYS BIT(14) +#define MP0_CPU4 BIT(15) +#define MP0_CPU5 BIT(16) +#define MP0_CPU6 BIT(17) +#define MP0_CPU7 BIT(18) +#define VEN BIT(21) + +/* === SPMC related registers */ +#define SPM_MCUSYS_PWR_CON MCUCFG_REG(0xd200) +#define SPM_MP0_CPUTOP_PWR_CON MCUCFG_REG(0xd204) +#define SPM_MP0_CPU0_PWR_CON MCUCFG_REG(0xd208) +#define SPM_MP0_CPU1_PWR_CON MCUCFG_REG(0xd20c) +#define SPM_MP0_CPU2_PWR_CON MCUCFG_REG(0xd210) +#define SPM_MP0_CPU3_PWR_CON MCUCFG_REG(0xd214) +#define SPM_MP0_CPU4_PWR_CON MCUCFG_REG(0xd218) +#define SPM_MP0_CPU5_PWR_CON MCUCFG_REG(0xd21c) +#define SPM_MP0_CPU6_PWR_CON MCUCFG_REG(0xd220) +#define SPM_MP0_CPU7_PWR_CON MCUCFG_REG(0xd224) + +/* bit fields of SPM_*_PWR_CON */ +#define PWR_ON_ACK BIT(31) +#define VPROC_EXT_OFF BIT(7) +#define DORMANT_EN BIT(6) +#define RESETPWRON_CONFIG BIT(5) +#define PWR_CLK_DIS BIT(4) +#define PWR_ON BIT(2) +#define PWR_RST_B BIT(0) + +/**** per_cpu registers for SPM_MP0_CPU?_PWR_CON */ +static const struct per_cpu_reg SPM_CPU_PWR[] = { + { .cluster_addr = SPM_MP0_CPU0_PWR_CON, .cpu_stride = 2U } +}; + +/**** per_cluster registers for SPM_MP0_CPUTOP_PWR_CON */ +static const struct per_cpu_reg SPM_CLUSTER_PWR[] = { + { .cluster_addr = SPM_MP0_CPUTOP_PWR_CON, .cpu_stride = 0U } +}; + +/* === MCUCFG related registers */ +/* aa64naa32 */ +#define MCUCFG_MP0_CLUSTER_CFG5 MCUCFG_REG(0xc8e4) +/* reset vectors */ +#define MCUCFG_MP0_CLUSTER_CFG8 MCUCFG_REG(0xc900) +#define MCUCFG_MP0_CLUSTER_CFG10 MCUCFG_REG(0xc908) +#define MCUCFG_MP0_CLUSTER_CFG12 MCUCFG_REG(0xc910) +#define MCUCFG_MP0_CLUSTER_CFG14 MCUCFG_REG(0xc918) +#define MCUCFG_MP0_CLUSTER_CFG16 MCUCFG_REG(0xc920) +#define MCUCFG_MP0_CLUSTER_CFG18 MCUCFG_REG(0xc928) +#define MCUCFG_MP0_CLUSTER_CFG20 MCUCFG_REG(0xc930) +#define MCUCFG_MP0_CLUSTER_CFG22 MCUCFG_REG(0xc938) + +/* MCUSYS DREQ BIG VPROC ISO control */ +#define DREQ20_BIG_VPROC_ISO MCUCFG_REG(0xad8c) + +/**** per_cpu registers for MCUCFG_MP0_CLUSTER_CFG? */ +static const struct per_cpu_reg MCUCFG_BOOTADDR[] = { + { .cluster_addr = MCUCFG_MP0_CLUSTER_CFG8, .cpu_stride = 3U } +}; + +/**** per_cpu registers for MCUCFG_MP0_CLUSTER_CFG5 */ +static const struct per_cpu_reg MCUCFG_INITARCH[] = { + { .cluster_addr = MCUCFG_MP0_CLUSTER_CFG5, .cpu_stride = 0U } +}; + +#define MCUCFG_INITARCH_CPU_BIT(cpu) BIT(16U + cpu) +#define LAST_PC_REG(cpu) (MCUCFG_REG(0x308) + (cpu * 0x800)) + +/* === CPC control */ +#define MCUCFG_CPC_FLOW_CTRL_CFG MCUCFG_REG(0xa814) +#define MCUCFG_CPC_SPMC_PWR_STATUS MCUCFG_REG(0xa840) + +/* bit fields of CPC_FLOW_CTRL_CFG */ +#define CPC_CTRL_ENABLE BIT(16) +#define SSPM_ALL_PWR_CTRL_EN BIT(13) /* for cpu-hotplug */ +#define GIC_WAKEUP_IGNORE(cpu) BIT(21 + cpu) + +/* bit fields of CPC_SPMC_PWR_STATUS */ +#define CORE_SPMC_PWR_ON_ACK GENMASK(15, 0) + +/* === APB Module infracfg_ao */ +#define INFRA_TOPAXI_PROTECTEN INFRACFG_AO_REG(0x0220) +#define INFRA_TOPAXI_PROTECTEN_STA0 INFRACFG_AO_REG(0x0224) +#define INFRA_TOPAXI_PROTECTEN_STA1 INFRACFG_AO_REG(0x0228) +#define INFRA_TOPAXI_PROTECTEN_SET INFRACFG_AO_REG(0x02a0) +#define INFRA_TOPAXI_PROTECTEN_CLR INFRACFG_AO_REG(0x02a4) +#define INFRA_TOPAXI_PROTECTEN_1 INFRACFG_AO_REG(0x0250) +#define INFRA_TOPAXI_PROTECTEN_STA0_1 INFRACFG_AO_REG(0x0254) +#define INFRA_TOPAXI_PROTECTEN_STA1_1 INFRACFG_AO_REG(0x0258) +#define INFRA_TOPAXI_PROTECTEN_1_SET INFRACFG_AO_REG(0x02a8) +#define INFRA_TOPAXI_PROTECTEN_1_CLR INFRACFG_AO_REG(0x02ac) + +/* bit fields of INFRA_TOPAXI_PROTECTEN */ +#define MP0_SPMC_PROT_STEP1_0_MASK BIT(12) +#define MP0_SPMC_PROT_STEP1_1_MASK (BIT(26) | BIT(12)) + +/* === SPARK */ +#define VOLTAGE_04 U(0x40) +#define VOLTAGE_05 U(0x60) + +#define PTP3_CPU0_SPMC_SW_CFG MCUCFG_REG(0x200) +#define CPU0_ILDO_CONTROL5 MCUCFG_REG(0x334) +#define CPU0_ILDO_CONTROL8 MCUCFG_REG(0x340) + +/* bit fields of CPU0_ILDO_CONTROL5 */ +#define ILDO_RET_VOSEL GENMASK(7, 0) + +/* bit fields of PTP3_CPU_SPMC_SW_CFG */ +#define SW_SPARK_EN BIT(0) + +/* bit fields of CPU0_ILDO_CONTROL8 */ +#define ILDO_BYPASS_B BIT(0) + +static const struct per_cpu_reg MCUCFG_SPARK[] = { + { .cluster_addr = PTP3_CPU0_SPMC_SW_CFG, .cpu_stride = 11U } +}; + +static const struct per_cpu_reg ILDO_CONTROL5[] = { + { .cluster_addr = CPU0_ILDO_CONTROL5, .cpu_stride = 11U } +}; + +static const struct per_cpu_reg ILDO_CONTROL8[] = { + { .cluster_addr = CPU0_ILDO_CONTROL8, .cpu_stride = 11U } +}; + +#endif /* MTSPMC_PRIVATE_H */ diff --git a/plat/mediatek/mt8192/include/mcucfg.h b/plat/mediatek/mt8192/include/mcucfg.h new file mode 100644 index 000000000..046cf7314 --- /dev/null +++ b/plat/mediatek/mt8192/include/mcucfg.h @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MCUCFG_H +#define MCUCFG_H + +#ifndef __ASSEMBLER__ +#include +#endif /* __ASSEMBLER__ */ + +#include + +#define MCUCFG_REG(ofs) (uint32_t)(MCUCFG_BASE + (ofs)) + +#define MP2_MISC_CONFIG_BOOT_ADDR_L(cpu) (MCUCFG_REG(0x2290) + ((cpu) * 8)) +#define MP2_MISC_CONFIG_BOOT_ADDR_H(cpu) (MCUCFG_REG(0x2294) + ((cpu) * 8)) + +#define MP2_CPUCFG MCUCFG_REG(0x2208) + +#define MP2_CPU0_STANDBYWFE BIT(4) +#define MP2_CPU1_STANDBYWFE BIT(5) + +#define MP0_CPUTOP_SPMC_CTL MCUCFG_REG(0x788) +#define MP1_CPUTOP_SPMC_CTL MCUCFG_REG(0x78C) +#define MP1_CPUTOP_SPMC_SRAM_CTL MCUCFG_REG(0x790) + +#define sw_spark_en BIT(0) +#define sw_no_wait_for_q_channel BIT(1) +#define sw_fsm_override BIT(2) +#define sw_logic_pre1_pdb BIT(3) +#define sw_logic_pre2_pdb BIT(4) +#define sw_logic_pdb BIT(5) +#define sw_iso BIT(6) +#define sw_sram_sleepb (U(0x3F) << 7) +#define sw_sram_isointb BIT(13) +#define sw_clk_dis BIT(14) +#define sw_ckiso BIT(15) +#define sw_pd (U(0x3F) << 16) +#define sw_hot_plug_reset BIT(22) +#define sw_pwr_on_override_en BIT(23) +#define sw_pwr_on BIT(24) +#define sw_coq_dis BIT(25) +#define logic_pdbo_all_off_ack BIT(26) +#define logic_pdbo_all_on_ack BIT(27) +#define logic_pre2_pdbo_all_on_ack BIT(28) +#define logic_pre1_pdbo_all_on_ack BIT(29) + + +#define CPUSYSx_CPUx_SPMC_CTL(cluster, cpu) \ + (MCUCFG_REG(0x1c30) + cluster * 0x2000 + cpu * 4) + +#define CPUSYS0_CPU0_SPMC_CTL MCUCFG_REG(0x1c30) +#define CPUSYS0_CPU1_SPMC_CTL MCUCFG_REG(0x1c34) +#define CPUSYS0_CPU2_SPMC_CTL MCUCFG_REG(0x1c38) +#define CPUSYS0_CPU3_SPMC_CTL MCUCFG_REG(0x1c3C) + +#define CPUSYS1_CPU0_SPMC_CTL MCUCFG_REG(0x3c30) +#define CPUSYS1_CPU1_SPMC_CTL MCUCFG_REG(0x3c34) +#define CPUSYS1_CPU2_SPMC_CTL MCUCFG_REG(0x3c38) +#define CPUSYS1_CPU3_SPMC_CTL MCUCFG_REG(0x3c3C) + +#define cpu_sw_spark_en BIT(0) +#define cpu_sw_no_wait_for_q_channel BIT(1) +#define cpu_sw_fsm_override BIT(2) +#define cpu_sw_logic_pre1_pdb BIT(3) +#define cpu_sw_logic_pre2_pdb BIT(4) +#define cpu_sw_logic_pdb BIT(5) +#define cpu_sw_iso BIT(6) +#define cpu_sw_sram_sleepb BIT(7) +#define cpu_sw_sram_isointb BIT(8) +#define cpu_sw_clk_dis BIT(9) +#define cpu_sw_ckiso BIT(10) +#define cpu_sw_pd (U(0x1F) << 11) +#define cpu_sw_hot_plug_reset BIT(16) +#define cpu_sw_powr_on_override_en BIT(17) +#define cpu_sw_pwr_on BIT(18) +#define cpu_spark2ldo_allswoff BIT(19) +#define cpu_pdbo_all_on_ack BIT(20) +#define cpu_pre2_pdbo_allon_ack BIT(21) +#define cpu_pre1_pdbo_allon_ack BIT(22) + +/* CPC related registers */ +#define CPC_MCUSYS_CPC_OFF_THRES MCUCFG_REG(0xa714) +#define CPC_MCUSYS_PWR_CTRL MCUCFG_REG(0xa804) +#define CPC_MCUSYS_CPC_FLOW_CTRL_CFG MCUCFG_REG(0xa814) +#define CPC_MCUSYS_LAST_CORE_REQ MCUCFG_REG(0xa818) +#define CPC_MCUSYS_MP_LAST_CORE_RESP MCUCFG_REG(0xa81c) +#define CPC_MCUSYS_LAST_CORE_RESP MCUCFG_REG(0xa824) +#define CPC_MCUSYS_PWR_ON_MASK MCUCFG_REG(0xa828) +#define CPC_MCUSYS_CPU_ON_SW_HINT_SET MCUCFG_REG(0xa8a8) +#define CPC_MCUSYS_CPU_ON_SW_HINT_CLR MCUCFG_REG(0xa8ac) +#define CPC_MCUSYS_CPC_DBG_SETTING MCUCFG_REG(0xab00) +#define CPC_MCUSYS_CPC_KERNEL_TIME_L_BASE MCUCFG_REG(0xab04) +#define CPC_MCUSYS_CPC_KERNEL_TIME_H_BASE MCUCFG_REG(0xab08) +#define CPC_MCUSYS_CPC_SYSTEM_TIME_L_BASE MCUCFG_REG(0xab0c) +#define CPC_MCUSYS_CPC_SYSTEM_TIME_H_BASE MCUCFG_REG(0xab10) +#define CPC_MCUSYS_TRACE_SEL MCUCFG_REG(0xab14) +#define CPC_MCUSYS_TRACE_DATA MCUCFG_REG(0xab20) +#define CPC_MCUSYS_CLUSTER_COUNTER MCUCFG_REG(0xab70) +#define CPC_MCUSYS_CLUSTER_COUNTER_CLR MCUCFG_REG(0xab74) + +#define SPARK2LDO MCUCFG_REG(0x2700) +/* APB Module mcucfg */ +#define MP0_CA7_CACHE_CONFIG MCUCFG_REG(0x000) +#define MP0_AXI_CONFIG MCUCFG_REG(0x02C) +#define MP0_MISC_CONFIG0 MCUCFG_REG(0x030) +#define MP0_MISC_CONFIG1 MCUCFG_REG(0x034) +#define MP0_MISC_CONFIG2 MCUCFG_REG(0x038) +#define MP0_MISC_CONFIG_BOOT_ADDR(cpu) (MP0_MISC_CONFIG2 + ((cpu) * 8)) +#define MP0_MISC_CONFIG3 MCUCFG_REG(0x03C) +#define MP0_MISC_CONFIG9 MCUCFG_REG(0x054) +#define MP0_CA7_MISC_CONFIG MCUCFG_REG(0x064) + +#define MP0_RW_RSVD0 MCUCFG_REG(0x06C) + + +#define MP1_CA7_CACHE_CONFIG MCUCFG_REG(0x200) +#define MP1_AXI_CONFIG MCUCFG_REG(0x22C) +#define MP1_MISC_CONFIG0 MCUCFG_REG(0x230) +#define MP1_MISC_CONFIG1 MCUCFG_REG(0x234) +#define MP1_MISC_CONFIG2 MCUCFG_REG(0x238) +#define MP1_MISC_CONFIG_BOOT_ADDR(cpu) (MP1_MISC_CONFIG2 + ((cpu) * 8)) +#define MP1_MISC_CONFIG3 MCUCFG_REG(0x23C) +#define MP1_MISC_CONFIG9 MCUCFG_REG(0x254) +#define MP1_CA7_MISC_CONFIG MCUCFG_REG(0x264) + +#define CCI_ADB400_DCM_CONFIG MCUCFG_REG(0x740) +#define SYNC_DCM_CONFIG MCUCFG_REG(0x744) + +#define MP0_CLUSTER_CFG0 MCUCFG_REG(0xC8D0) + +#define MP0_SPMC MCUCFG_REG(0x788) +#define MP1_SPMC MCUCFG_REG(0x78C) +#define MP2_AXI_CONFIG MCUCFG_REG(0x220C) +#define MP2_AXI_CONFIG_ACINACTM BIT(0) +#define MP2_AXI_CONFIG_AINACTS BIT(4) + +#define MPx_AXI_CONFIG_ACINACTM BIT(4) +#define MPx_AXI_CONFIG_AINACTS BIT(5) + +#define MPx_CA7_MISC_CONFIG_standbywfil2 BIT(28) + +#define MP0_CPU0_STANDBYWFE BIT(20) +#define MP0_CPU1_STANDBYWFE BIT(21) +#define MP0_CPU2_STANDBYWFE BIT(22) +#define MP0_CPU3_STANDBYWFE BIT(23) + +#define MP1_CPU0_STANDBYWFE BIT(20) +#define MP1_CPU1_STANDBYWFE BIT(21) +#define MP1_CPU2_STANDBYWFE BIT(22) +#define MP1_CPU3_STANDBYWFE BIT(23) + +#define CPUSYS0_SPARKVRETCNTRL MCUCFG_REG(0x1c00) +#define CPUSYS0_SPARKEN MCUCFG_REG(0x1c04) +#define CPUSYS0_AMUXSEL MCUCFG_REG(0x1c08) +#define CPUSYS1_SPARKVRETCNTRL MCUCFG_REG(0x3c00) +#define CPUSYS1_SPARKEN MCUCFG_REG(0x3c04) +#define CPUSYS1_AMUXSEL MCUCFG_REG(0x3c08) + +#define MP2_PWR_RST_CTL MCUCFG_REG(0x2008) +#define MP2_PTP3_CPUTOP_SPMC0 MCUCFG_REG(0x22A0) +#define MP2_PTP3_CPUTOP_SPMC1 MCUCFG_REG(0x22A4) + +#define MP2_COQ MCUCFG_REG(0x22BC) +#define MP2_COQ_SW_DIS BIT(0) + +#define MP2_CA15M_MON_SEL MCUCFG_REG(0x2400) +#define MP2_CA15M_MON_L MCUCFG_REG(0x2404) + +#define CPUSYS2_CPU0_SPMC_CTL MCUCFG_REG(0x2430) +#define CPUSYS2_CPU1_SPMC_CTL MCUCFG_REG(0x2438) +#define CPUSYS2_CPU0_SPMC_STA MCUCFG_REG(0x2434) +#define CPUSYS2_CPU1_SPMC_STA MCUCFG_REG(0x243C) + +#define MP0_CA7L_DBG_PWR_CTRL MCUCFG_REG(0x068) +#define MP1_CA7L_DBG_PWR_CTRL MCUCFG_REG(0x268) +#define BIG_DBG_PWR_CTRL MCUCFG_REG(0x75C) + +#define MP2_SW_RST_B BIT(0) +#define MP2_TOPAON_APB_MASK BIT(1) + +#define B_SW_HOT_PLUG_RESET BIT(30) + +#define B_SW_PD_OFFSET 18U +#define B_SW_PD (U(0x3f) << B_SW_PD_OFFSET) + +#define B_SW_SRAM_SLEEPB_OFFSET 12U +#define B_SW_SRAM_SLEEPB (U(0x3f) << B_SW_SRAM_SLEEPB_OFFSET) + +#define B_SW_SRAM_ISOINTB BIT(9) +#define B_SW_ISO BIT(8) +#define B_SW_LOGIC_PDB BIT(7) +#define B_SW_LOGIC_PRE2_PDB BIT(6) +#define B_SW_LOGIC_PRE1_PDB BIT(5) +#define B_SW_FSM_OVERRIDE BIT(4) +#define B_SW_PWR_ON BIT(3) +#define B_SW_PWR_ON_OVERRIDE_EN BIT(2) + +#define B_FSM_STATE_OUT_OFFSET (6U) +#define B_FSM_STATE_OUT_MASK (U(0x1f) << B_FSM_STATE_OUT_OFFSET) +#define B_SW_LOGIC_PDBO_ALL_OFF_ACK BIT(5) +#define B_SW_LOGIC_PDBO_ALL_ON_ACK BIT(4) +#define B_SW_LOGIC_PRE2_PDBO_ALL_ON_ACK BIT(3) +#define B_SW_LOGIC_PRE1_PDBO_ALL_ON_ACK BIT(2) + +#define B_FSM_OFF (0U << B_FSM_STATE_OUT_OFFSET) +#define B_FSM_ON (1U << B_FSM_STATE_OUT_OFFSET) +#define B_FSM_RET (2U << B_FSM_STATE_OUT_OFFSET) + +#ifndef __ASSEMBLER__ +/* cpu boot mode */ +enum { + MP0_CPUCFG_64BIT_SHIFT = 12U, + MP1_CPUCFG_64BIT_SHIFT = 28U, + MP0_CPUCFG_64BIT = U(0xf) << MP0_CPUCFG_64BIT_SHIFT, + MP1_CPUCFG_64BIT = U(0xf) << MP1_CPUCFG_64BIT_SHIFT +}; + +enum { + MP1_DIS_RGU0_WAIT_PD_CPUS_L1_ACK_SHIFT = 0U, + MP1_DIS_RGU1_WAIT_PD_CPUS_L1_ACK_SHIFT = 4U, + MP1_DIS_RGU2_WAIT_PD_CPUS_L1_ACK_SHIFT = 8U, + MP1_DIS_RGU3_WAIT_PD_CPUS_L1_ACK_SHIFT = 12U, + MP1_DIS_RGU_NOCPU_WAIT_PD_CPUS_L1_ACK_SHIFT = 16U, + + MP1_DIS_RGU0_WAIT_PD_CPUS_L1_ACK = + U(0xf) << MP1_DIS_RGU0_WAIT_PD_CPUS_L1_ACK_SHIFT, + MP1_DIS_RGU1_WAIT_PD_CPUS_L1_ACK = + U(0xf) << MP1_DIS_RGU1_WAIT_PD_CPUS_L1_ACK_SHIFT, + MP1_DIS_RGU2_WAIT_PD_CPUS_L1_ACK = + U(0xf) << MP1_DIS_RGU2_WAIT_PD_CPUS_L1_ACK_SHIFT, + MP1_DIS_RGU3_WAIT_PD_CPUS_L1_ACK = + U(0xf) << MP1_DIS_RGU3_WAIT_PD_CPUS_L1_ACK_SHIFT, + MP1_DIS_RGU_NOCPU_WAIT_PD_CPUS_L1_ACK = + U(0xf) << MP1_DIS_RGU_NOCPU_WAIT_PD_CPUS_L1_ACK_SHIFT +}; + +enum { + MP1_AINACTS_SHIFT = 4U, + MP1_AINACTS = 1U << MP1_AINACTS_SHIFT +}; + +enum { + MP1_SW_CG_GEN_SHIFT = 12U, + MP1_SW_CG_GEN = 1U << MP1_SW_CG_GEN_SHIFT +}; + +enum { + MP1_L2RSTDISABLE_SHIFT = 14U, + MP1_L2RSTDISABLE = 1U << MP1_L2RSTDISABLE_SHIFT +}; +#endif /* __ASSEMBLER__ */ + +#endif /* MCUCFG_H */ diff --git a/plat/mediatek/mt8192/include/platform_def.h b/plat/mediatek/mt8192/include/platform_def.h index 768e7cf82..e6e1f8d0a 100644 --- a/plat/mediatek/mt8192/include/platform_def.h +++ b/plat/mediatek/mt8192/include/platform_def.h @@ -25,6 +25,7 @@ #define MTK_DEV_RNG2_SIZE 0x600000 #define GPIO_BASE (IO_PHYS + 0x00005000) +#define SPM_BASE (IO_PHYS + 0x00006000) #define IOCFG_RM_BASE (IO_PHYS + 0x01C20000) #define IOCFG_BM_BASE (IO_PHYS + 0x01D10000) #define IOCFG_BL_BASE (IO_PHYS + 0x01D30000) diff --git a/plat/mediatek/mt8192/platform.mk b/plat/mediatek/mt8192/platform.mk index 7544b2658..e1da9c17a 100644 --- a/plat/mediatek/mt8192/platform.mk +++ b/plat/mediatek/mt8192/platform.mk @@ -11,6 +11,7 @@ PLAT_INCLUDES := -I${MTK_PLAT}/common/ \ -I${MTK_PLAT_SOC}/include/ \ -I${MTK_PLAT_SOC}/drivers/ \ -I${MTK_PLAT_SOC}/drivers/gpio/ \ + -I${MTK_PLAT_SOC}/drivers/spmc/ \ -I${MTK_PLAT_SOC}/drivers/timer/ GICV3_SUPPORT_GIC600 := 1 @@ -39,9 +40,9 @@ BL31_SOURCES += common/desc_image_load.c \ ${MTK_PLAT_SOC}/plat_mt_gic.c \ ${MTK_PLAT_SOC}/plat_mt_cirq.c \ ${MTK_PLAT_SOC}/drivers/gpio/mtgpio.c \ + ${MTK_PLAT_SOC}/drivers/spmc/mtspmc.c \ ${MTK_PLAT_SOC}/drivers/timer/mt_timer.c - # Configs for A76 and A55 HW_ASSISTED_COHERENCY := 1 USE_COHERENT_MEM := 0 -- cgit v1.2.3 From 271d9497dccc2aea2f67723c6581342ff7b5253e Mon Sep 17 00:00:00 2001 From: James Liao Date: Mon, 15 Jun 2020 16:41:03 +0800 Subject: mediatek: mt8192: Add MCDI drivers Add MCDI related drivers to handle CPU powered on/off in CPU suspend. Change-Id: I5110461e8eef86f8383b45f197ec5cb10dbfeb3e Signed-off-by: James Liao --- plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm.c | 123 ++++++++++ plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm_cpc.c | 269 ++++++++++++++++++++++ plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm_cpc.h | 106 +++++++++ plat/mediatek/mt8192/drivers/mcdi/mt_mcdi.c | 148 ++++++++++++ plat/mediatek/mt8192/drivers/mcdi/mt_mcdi.h | 12 + plat/mediatek/mt8192/include/plat_mtk_lpm.h | 48 ++++ plat/mediatek/mt8192/include/plat_pm.h | 38 +++ plat/mediatek/mt8192/include/platform_def.h | 2 + plat/mediatek/mt8192/platform.mk | 4 + 9 files changed, 750 insertions(+) create mode 100644 plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm.c create mode 100644 plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm_cpc.c create mode 100644 plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm_cpc.h create mode 100644 plat/mediatek/mt8192/drivers/mcdi/mt_mcdi.c create mode 100644 plat/mediatek/mt8192/drivers/mcdi/mt_mcdi.h create mode 100644 plat/mediatek/mt8192/include/plat_mtk_lpm.h create mode 100644 plat/mediatek/mt8192/include/plat_pm.h diff --git a/plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm.c b/plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm.c new file mode 100644 index 000000000..d6d4af742 --- /dev/null +++ b/plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +DEFINE_SYSREG_RW_FUNCS(dbgprcr_el1); + +static int plat_mt_lp_cpu_rc; + +static int pwr_state_prompt(unsigned int cpu, const psci_power_state_t *state) +{ + return 0; +} + +static int pwr_state_reflect(unsigned int cpu, const psci_power_state_t *state) +{ + mtk_cpc_core_on_hint_clr(cpu); + + if (IS_SYSTEM_SUSPEND_STATE(state)) { + mtk_cpc_time_sync(); + } + + return 0; +} + +static int pwr_cpu_pwron(unsigned int cpu, const psci_power_state_t *state) +{ + return 0; +} + +static int pwr_cpu_pwrdwn(unsigned int cpu, const psci_power_state_t *state) +{ + /* clear DBGPRCR.CORENPDRQ to allow CPU power down */ + write_dbgprcr_el1(0ULL); + + return 0; +} + +static int pwr_cluster_pwron(unsigned int cpu, const psci_power_state_t *state) +{ + return 0; +} + +static int pwr_cluster_pwrdwn(unsigned int cpu, const psci_power_state_t *state) +{ + return 0; +} + +static int pwr_mcusys_pwron(unsigned int cpu, const psci_power_state_t *state) +{ + if (!IS_MCUSYS_OFF_STATE(state) || (plat_mt_lp_cpu_rc < 0)) { + return -1; + } + + mtk_cpc_mcusys_off_reflect(); + + return 0; +} + +static int pwr_mcusys_pwron_finished(unsigned int cpu, + const psci_power_state_t *state) +{ + if (!IS_MCUSYS_OFF_STATE(state) || (plat_mt_lp_cpu_rc < 0)) { + return -1; + } + + return 0; +} + +static int pwr_mcusys_pwrdwn(unsigned int cpu, const psci_power_state_t *state) +{ + if (!IS_MCUSYS_OFF_STATE(state)) { + goto mt_pwr_mcusysoff_break; + } + + if (mcdi_try_init() != 0) { /* not ready to process mcusys-off */ + goto mt_pwr_mcusysoff_break; + } + + return 0; + +mt_pwr_mcusysoff_break: + + plat_mt_lp_cpu_rc = -1; + + return -1; +} + +static const struct mt_lpm_tz plat_pm = { + .pwr_prompt = pwr_state_prompt, + .pwr_reflect = pwr_state_reflect, + .pwr_cpu_on = pwr_cpu_pwron, + .pwr_cpu_dwn = pwr_cpu_pwrdwn, + .pwr_cluster_on = pwr_cluster_pwron, + .pwr_cluster_dwn = pwr_cluster_pwrdwn, + .pwr_mcusys_dwn = pwr_mcusys_pwrdwn, + .pwr_mcusys_on = pwr_mcusys_pwron, + .pwr_mcusys_on_finished = pwr_mcusys_pwron_finished +}; + +const struct mt_lpm_tz *mt_plat_cpu_pm_init(void) +{ + mtk_cpc_init(); + + if (mcdi_try_init() == 0) { + INFO("MCDI init done.\n"); + } + + return &plat_pm; +} diff --git a/plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm_cpc.c b/plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm_cpc.c new file mode 100644 index 000000000..f8c51a199 --- /dev/null +++ b/plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm_cpc.c @@ -0,0 +1,269 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include + +#include +#include + +struct mtk_cpc_dev { + int auto_off; + unsigned int auto_thres_tick; +}; + +static struct mtk_cpc_dev cpc; + +static int mtk_cpc_last_core_prot(uint32_t prot_req, + uint32_t resp_reg, uint32_t resp_ofs) +{ + uint32_t sta, retry; + + retry = 0U; + + while (retry++ < RETRY_CNT_MAX) { + + mmio_write_32(CPC_MCUSYS_LAST_CORE_REQ, prot_req); + + udelay(1U); + + sta = (mmio_read_32(resp_reg) >> resp_ofs) & CPC_PROT_RESP_MASK; + + if (sta == PROT_SUCCESS) { + return CPC_SUCCESS; + } else if (sta == PROT_GIVEUP) { + return CPC_ERR_FAIL; + } + } + + return CPC_ERR_TIMEOUT; +} + +int mtk_cpu_pm_mcusys_prot_aquire(void) +{ + return mtk_cpc_last_core_prot( + MCUSYS_PROT_SET, + CPC_MCUSYS_LAST_CORE_RESP, + MCUSYS_RESP_OFS); +} + +void mtk_cpu_pm_mcusys_prot_release(void) +{ + mmio_write_32(CPC_MCUSYS_PWR_ON_MASK, MCUSYS_PROT_CLR); +} + +int mtk_cpu_pm_cluster_prot_aquire(unsigned int cluster) +{ + return mtk_cpc_last_core_prot( + CPUSYS_PROT_SET, + CPC_MCUSYS_MP_LAST_CORE_RESP, + CPUSYS_RESP_OFS); +} + +void mtk_cpu_pm_cluster_prot_release(unsigned int cluster) +{ + mmio_write_32(CPC_MCUSYS_PWR_ON_MASK, CPUSYS_PROT_CLR); +} + +static void mtk_cpc_cluster_cnt_backup(void) +{ + uint32_t backup_cnt; + uint32_t curr_cnt; + uint32_t cnt_mask = GENMASK(14, 0); + uint32_t clr_mask = GENMASK(1, 0); + + /* Single Cluster */ + backup_cnt = mmio_read_32(CPC_CLUSTER_CNT_BACKUP); + curr_cnt = mmio_read_32(CPC_MCUSYS_CLUSTER_COUNTER); + + /* Get off count if dormant count is 0 */ + if ((curr_cnt & cnt_mask) == 0U) { + curr_cnt = (curr_cnt >> 16) & cnt_mask; + } else { + curr_cnt = curr_cnt & cnt_mask; + } + + mmio_write_32(CPC_CLUSTER_CNT_BACKUP, backup_cnt + curr_cnt); + mmio_write_32(CPC_MCUSYS_CLUSTER_COUNTER_CLR, clr_mask); +} + +static inline void mtk_cpc_mcusys_off_en(void) +{ + mmio_write_32(CPC_MCUSYS_PWR_CTRL, 1U); +} + +static inline void mtk_cpc_mcusys_off_dis(void) +{ + mmio_write_32(CPC_MCUSYS_PWR_CTRL, 0U); +} + +void mtk_cpc_mcusys_off_reflect(void) +{ + mtk_cpc_mcusys_off_dis(); + mtk_cpu_pm_mcusys_prot_release(); +} + +int mtk_cpc_mcusys_off_prepare(void) +{ + if (mtk_cpu_pm_mcusys_prot_aquire() != CPC_SUCCESS) { + return CPC_ERR_FAIL; + } + + mtk_cpc_cluster_cnt_backup(); + mtk_cpc_mcusys_off_en(); + + return CPC_SUCCESS; +} + +void mtk_cpc_core_on_hint_set(unsigned int cpu) +{ + mmio_write_32(CPC_MCUSYS_CPU_ON_SW_HINT_SET, BIT(cpu)); +} + +void mtk_cpc_core_on_hint_clr(unsigned int cpu) +{ + mmio_write_32(CPC_MCUSYS_CPU_ON_SW_HINT_CLR, BIT(cpu)); +} + +static void mtk_cpc_dump_timestamp(void) +{ + uint32_t id; + + for (id = 0U; id < CPC_TRACE_ID_NUM; id++) { + mmio_write_32(CPC_MCUSYS_TRACE_SEL, id); + + memcpy((void *)(uintptr_t)CPC_TRACE_SRAM(id), + (const void *)(uintptr_t)CPC_MCUSYS_TRACE_DATA, + CPC_TRACE_SIZE); + } +} + +void mtk_cpc_time_sync(void) +{ + uint64_t kt; + uint32_t systime_l, systime_h; + + kt = sched_clock(); + systime_l = mmio_read_32(CNTSYS_L_REG); + systime_h = mmio_read_32(CNTSYS_H_REG); + + /* sync kernel timer to cpc */ + mmio_write_32(CPC_MCUSYS_CPC_KERNEL_TIME_L_BASE, (uint32_t)kt); + mmio_write_32(CPC_MCUSYS_CPC_KERNEL_TIME_H_BASE, (uint32_t)(kt >> 32)); + /* sync system timer to cpc */ + mmio_write_32(CPC_MCUSYS_CPC_SYSTEM_TIME_L_BASE, systime_l); + mmio_write_32(CPC_MCUSYS_CPC_SYSTEM_TIME_H_BASE, systime_h); +} + +static void mtk_cpc_config(uint32_t cfg, uint32_t data) +{ + uint32_t val; + uint32_t reg = 0U; + + switch (cfg) { + case CPC_SMC_CONFIG_PROF: + reg = CPC_MCUSYS_CPC_DBG_SETTING; + val = mmio_read_32(reg); + val = (data != 0U) ? (val | CPC_PROF_EN) : (val & ~CPC_PROF_EN); + break; + case CPC_SMC_CONFIG_AUTO_OFF: + reg = CPC_MCUSYS_CPC_FLOW_CTRL_CFG; + val = mmio_read_32(reg); + if (data != 0U) { + val |= CPC_AUTO_OFF_EN; + cpc.auto_off = 1; + } else { + val &= ~CPC_AUTO_OFF_EN; + cpc.auto_off = 0; + } + break; + case CPC_SMC_CONFIG_AUTO_OFF_THRES: + reg = CPC_MCUSYS_CPC_OFF_THRES; + cpc.auto_thres_tick = us_to_ticks(data); + val = cpc.auto_thres_tick; + break; + case CPC_SMC_CONFIG_CNT_CLR: + reg = CPC_MCUSYS_CLUSTER_COUNTER_CLR; + val = GENMASK(1, 0); /* clr_mask */ + break; + case CPC_SMC_CONFIG_TIME_SYNC: + mtk_cpc_time_sync(); + break; + default: + break; + } + + if (reg != 0U) { + mmio_write_32(reg, val); + } +} + +static uint32_t mtk_cpc_read_config(uint32_t cfg) +{ + uint32_t res = 0U; + + switch (cfg) { + case CPC_SMC_CONFIG_PROF: + res = (mmio_read_32(CPC_MCUSYS_CPC_DBG_SETTING) & CPC_PROF_EN) ? + 1U : 0U; + break; + case CPC_SMC_CONFIG_AUTO_OFF: + res = cpc.auto_off; + break; + case CPC_SMC_CONFIG_AUTO_OFF_THRES: + res = ticks_to_us(cpc.auto_thres_tick); + break; + case CPC_SMC_CONFIG_CNT_CLR: + break; + default: + break; + } + + return res; +} + +uint64_t mtk_cpc_handler(uint64_t act, uint64_t arg1, uint64_t arg2) +{ + uint64_t res = 0ULL; + + switch (act) { + case CPC_SMC_EVENT_DUMP_TRACE_DATA: + mtk_cpc_dump_timestamp(); + break; + case CPC_SMC_EVENT_GIC_DPG_SET: + /* isolated_status = x2; */ + break; + case CPC_SMC_EVENT_CPC_CONFIG: + mtk_cpc_config((uint32_t)arg1, (uint32_t)arg2); + break; + case CPC_SMC_EVENT_READ_CONFIG: + res = mtk_cpc_read_config((uint32_t)arg1); + break; + default: + break; + } + + return res; +} + +void mtk_cpc_init(void) +{ + mmio_write_32(CPC_MCUSYS_CPC_DBG_SETTING, + mmio_read_32(CPC_MCUSYS_CPC_DBG_SETTING) + | CPC_DBG_EN + | CPC_CALC_EN); + + cpc.auto_off = 1; + cpc.auto_thres_tick = us_to_ticks(8000); + + mmio_write_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG, + mmio_read_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG) + | CPC_OFF_PRE_EN + | (cpc.auto_off ? CPC_AUTO_OFF_EN : 0U)); + + mmio_write_32(CPC_MCUSYS_CPC_OFF_THRES, cpc.auto_thres_tick); +} diff --git a/plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm_cpc.h b/plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm_cpc.h new file mode 100644 index 000000000..19dd6a283 --- /dev/null +++ b/plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm_cpc.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MT_CPU_PM_CPC_H +#define MT_CPU_PM_CPC_H + +#include +#include +#include +#include + +#define NEED_CPUSYS_PROT_WORKAROUND 1 + +/* system sram registers */ +#define CPUIDLE_SRAM_REG(r) (uint32_t)(MTK_MCDI_SRAM_BASE + (r)) + +/* db dump */ +#define CPC_TRACE_SIZE U(0x20) +#define CPC_TRACE_ID_NUM U(10) +#define CPC_TRACE_SRAM(id) (CPUIDLE_SRAM_REG(0x10) + (id) * CPC_TRACE_SIZE) + +/* buckup off count */ +#define CPC_CLUSTER_CNT_BACKUP CPUIDLE_SRAM_REG(0x1F0) +#define CPC_MCUSYS_CNT CPUIDLE_SRAM_REG(0x1F4) + +/* CPC_MCUSYS_CPC_FLOW_CTRL_CFG(0xA814): debug setting */ +#define CPC_PWR_ON_SEQ_DIS BIT(1) +#define CPC_PWR_ON_PRIORITY BIT(2) +#define CPC_AUTO_OFF_EN BIT(5) +#define CPC_DORMANT_WAIT_EN BIT(14) +#define CPC_CTRL_EN BIT(16) +#define CPC_OFF_PRE_EN BIT(29) + +/* CPC_MCUSYS_LAST_CORE_REQ(0xA818) : last core protection */ +#define CPUSYS_PROT_SET BIT(0) +#define MCUSYS_PROT_SET BIT(8) +#define CPUSYS_PROT_CLR BIT(8) +#define MCUSYS_PROT_CLR BIT(9) + +#define CPC_PROT_RESP_MASK U(0x3) +#define CPUSYS_RESP_OFS U(16) +#define MCUSYS_RESP_OFS U(30) + +#define cpusys_resp(r) (((r) >> CPUSYS_RESP_OFS) & CPC_PROT_RESP_MASK) +#define mcusys_resp(r) (((r) >> MCUSYS_RESP_OFS) & CPC_PROT_RESP_MASK) + +#define RETRY_CNT_MAX U(1000) + +#define PROT_RETRY U(0) +#define PROT_SUCCESS U(1) +#define PROT_GIVEUP U(2) + +/* CPC_MCUSYS_CPC_DBG_SETTING(0xAB00): debug setting */ +#define CPC_PROF_EN BIT(0) +#define CPC_DBG_EN BIT(1) +#define CPC_FREEZE BIT(2) +#define CPC_CALC_EN BIT(3) + +enum { + CPC_SUCCESS = 0, + + CPC_ERR_FAIL, + CPC_ERR_TIMEOUT, + + NF_CPC_ERR +}; + +enum { + CPC_SMC_EVENT_DUMP_TRACE_DATA, + CPC_SMC_EVENT_GIC_DPG_SET, + CPC_SMC_EVENT_CPC_CONFIG, + CPC_SMC_EVENT_READ_CONFIG, + + NF_CPC_SMC_EVENT +}; + +enum { + CPC_SMC_CONFIG_PROF, + CPC_SMC_CONFIG_AUTO_OFF, + CPC_SMC_CONFIG_AUTO_OFF_THRES, + CPC_SMC_CONFIG_CNT_CLR, + CPC_SMC_CONFIG_TIME_SYNC, + + NF_CPC_SMC_CONFIG +}; + +#define us_to_ticks(us) ((us) * 13) +#define ticks_to_us(tick) ((tick) / 13) + +int mtk_cpu_pm_cluster_prot_aquire(unsigned int cluster); +void mtk_cpu_pm_cluster_prot_release(unsigned int cluster); + +void mtk_cpc_mcusys_off_reflect(void); +int mtk_cpc_mcusys_off_prepare(void); + +void mtk_cpc_core_on_hint_set(unsigned int cpu); +void mtk_cpc_core_on_hint_clr(unsigned int cpu); +void mtk_cpc_time_sync(void); + +uint64_t mtk_cpc_handler(uint64_t act, uint64_t arg1, uint64_t arg2); +void mtk_cpc_init(void); + +#endif /* MT_CPU_PM_CPC_H */ diff --git a/plat/mediatek/mt8192/drivers/mcdi/mt_mcdi.c b/plat/mediatek/mt8192/drivers/mcdi/mt_mcdi.c new file mode 100644 index 000000000..df741221d --- /dev/null +++ b/plat/mediatek/mt8192/drivers/mcdi/mt_mcdi.c @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include + +/* Read/Write */ +#define APMCU_MCUPM_MBOX_AP_READY U(0) +#define APMCU_MCUPM_MBOX_RESERVED_1 U(1) +#define APMCU_MCUPM_MBOX_RESERVED_2 U(2) +#define APMCU_MCUPM_MBOX_RESERVED_3 U(3) +#define APMCU_MCUPM_MBOX_PWR_CTRL_EN U(4) +#define APMCU_MCUPM_MBOX_L3_CACHE_MODE U(5) +#define APMCU_MCUPM_MBOX_BUCK_MODE U(6) +#define APMCU_MCUPM_MBOX_ARMPLL_MODE U(7) +/* Read only */ +#define APMCU_MCUPM_MBOX_TASK_STA U(8) +#define APMCU_MCUPM_MBOX_RESERVED_9 U(9) +#define APMCU_MCUPM_MBOX_RESERVED_10 U(10) +#define APMCU_MCUPM_MBOX_RESERVED_11 U(11) + +/* CPC mode - Read/Write */ +#define APMCU_MCUPM_MBOX_WAKEUP_CPU U(12) + +/* Mbox Slot: APMCU_MCUPM_MBOX_PWR_CTRL_EN */ +#define MCUPM_MCUSYS_CTRL BIT(0) +#define MCUPM_BUCK_CTRL BIT(1) +#define MCUPM_ARMPLL_CTRL BIT(2) +#define MCUPM_CM_CTRL BIT(3) +#define MCUPM_PWR_CTRL_MASK GENMASK(3, 0) + +/* Mbox Slot: APMCU_MCUPM_MBOX_BUCK_MODE */ +#define MCUPM_BUCK_NORMAL_MODE U(0) /* default */ +#define MCUPM_BUCK_LP_MODE U(1) +#define MCUPM_BUCK_OFF_MODE U(2) +#define NF_MCUPM_BUCK_MODE U(3) + +/* Mbox Slot: APMCU_MCUPM_MBOX_ARMPLL_MODE */ +#define MCUPM_ARMPLL_ON U(0) /* default */ +#define MCUPM_ARMPLL_GATING U(1) +#define MCUPM_ARMPLL_OFF U(2) +#define NF_MCUPM_ARMPLL_MODE U(3) + +/* Mbox Slot: APMCU_MCUPM_MBOX_TASK_STA */ +#define MCUPM_TASK_UNINIT U(0) +#define MCUPM_TASK_INIT U(1) +#define MCUPM_TASK_INIT_FINISH U(2) +#define MCUPM_TASK_WAIT U(3) +#define MCUPM_TASK_RUN U(4) +#define MCUPM_TASK_PAUSE U(5) + +#define SSPM_MBOX_3_BASE U(0x0c55fce0) + +#define MCDI_NOT_INIT 0 +#define MCDI_INIT_1 1 +#define MCDI_INIT_2 2 +#define MCDI_INIT_DONE 3 + +static int mcdi_init_status __section("tzfw_coherent_mem"); + +static inline uint32_t mcdi_mbox_read(uint32_t id) +{ + return mmio_read_32(SSPM_MBOX_3_BASE + (id << 2)); +} + +static inline void mcdi_mbox_write(uint32_t id, uint32_t val) +{ + mmio_write_32(SSPM_MBOX_3_BASE + (id << 2), val); +} + +static void mtk_mcupm_pwr_ctrl_setting(uint32_t dev) +{ + mcdi_mbox_write(APMCU_MCUPM_MBOX_PWR_CTRL_EN, dev); +} + +static void mtk_set_mcupm_pll_mode(uint32_t mode) +{ + if (mode < NF_MCUPM_ARMPLL_MODE) { + mcdi_mbox_write(APMCU_MCUPM_MBOX_ARMPLL_MODE, mode); + } +} + +static void mtk_set_mcupm_buck_mode(uint32_t mode) +{ + if (mode < NF_MCUPM_BUCK_MODE) { + mcdi_mbox_write(APMCU_MCUPM_MBOX_BUCK_MODE, mode); + } +} + +static int mtk_mcupm_is_ready(void) +{ + unsigned int sta = mcdi_mbox_read(APMCU_MCUPM_MBOX_TASK_STA); + + return (sta == MCUPM_TASK_WAIT) || (sta == MCUPM_TASK_INIT_FINISH); +} + +static int mcdi_init_1(void) +{ + unsigned int sta = mcdi_mbox_read(APMCU_MCUPM_MBOX_TASK_STA); + + if (sta != MCUPM_TASK_INIT) { + return -1; + } + + mtk_set_mcupm_pll_mode(MCUPM_ARMPLL_OFF); + mtk_set_mcupm_buck_mode(MCUPM_BUCK_OFF_MODE); + + mtk_mcupm_pwr_ctrl_setting( + MCUPM_MCUSYS_CTRL | + MCUPM_BUCK_CTRL | + MCUPM_ARMPLL_CTRL); + + mcdi_mbox_write(APMCU_MCUPM_MBOX_AP_READY, 1); + + return 0; +} + +static int mcdi_init_2(void) +{ + return mtk_mcupm_is_ready() ? 0 : -1; +} + +int mcdi_try_init(void) +{ + if (mcdi_init_status == MCDI_INIT_DONE) { + return 0; + } + + if (mcdi_init_status == MCDI_NOT_INIT) { + mcdi_init_status = MCDI_INIT_1; + } + + if (mcdi_init_status == MCDI_INIT_1 && mcdi_init_1() == 0) { + mcdi_init_status = MCDI_INIT_2; + } + + if (mcdi_init_status == MCDI_INIT_2 && mcdi_init_2() == 0) { + mcdi_init_status = MCDI_INIT_DONE; + } + + return (mcdi_init_status == MCDI_INIT_DONE) ? 0 : mcdi_init_status; +} diff --git a/plat/mediatek/mt8192/drivers/mcdi/mt_mcdi.h b/plat/mediatek/mt8192/drivers/mcdi/mt_mcdi.h new file mode 100644 index 000000000..f3545aabf --- /dev/null +++ b/plat/mediatek/mt8192/drivers/mcdi/mt_mcdi.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MT_MCDI_H +#define MT_MCDI_H + +int mcdi_try_init(void); + +#endif /* MT_MCDI_H */ diff --git a/plat/mediatek/mt8192/include/plat_mtk_lpm.h b/plat/mediatek/mt8192/include/plat_mtk_lpm.h new file mode 100644 index 000000000..8ba8b93a8 --- /dev/null +++ b/plat/mediatek/mt8192/include/plat_mtk_lpm.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLAT_MTK_LPM_H +#define PLAT_MTK_LPM_H + +#include +#include + +#define MT_IRQ_REMAIN_MAX U(8) +#define MT_IRQ_REMAIN_CAT_LOG BIT(31) + +struct mt_irqremain { + unsigned int count; + unsigned int irqs[MT_IRQ_REMAIN_MAX]; + unsigned int wakeupsrc_cat[MT_IRQ_REMAIN_MAX]; + unsigned int wakeupsrc[MT_IRQ_REMAIN_MAX]; +}; + +#define PLAT_RC_STATUS_READY BIT(0) +#define PLAT_RC_STATUS_FEATURE_EN BIT(1) +#define PLAT_RC_STATUS_UART_NONSLEEP BIT(31) + +struct mt_lpm_tz { + int (*pwr_prompt)(unsigned int cpu, const psci_power_state_t *state); + int (*pwr_reflect)(unsigned int cpu, const psci_power_state_t *state); + + int (*pwr_cpu_on)(unsigned int cpu, const psci_power_state_t *state); + int (*pwr_cpu_dwn)(unsigned int cpu, const psci_power_state_t *state); + + int (*pwr_cluster_on)(unsigned int cpu, + const psci_power_state_t *state); + int (*pwr_cluster_dwn)(unsigned int cpu, + const psci_power_state_t *state); + + int (*pwr_mcusys_on)(unsigned int cpu, const psci_power_state_t *state); + int (*pwr_mcusys_on_finished)(unsigned int cpu, + const psci_power_state_t *state); + int (*pwr_mcusys_dwn)(unsigned int cpu, + const psci_power_state_t *state); +}; + +const struct mt_lpm_tz *mt_plat_cpu_pm_init(void); + +#endif /* PLAT_MTK_LPM_H */ diff --git a/plat/mediatek/mt8192/include/plat_pm.h b/plat/mediatek/mt8192/include/plat_pm.h new file mode 100644 index 000000000..a2881cef6 --- /dev/null +++ b/plat/mediatek/mt8192/include/plat_pm.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLAT_PM_H +#define PLAT_PM_H + +#include + +#define MT_PLAT_PWR_STATE_CPU U(1) +#define MT_PLAT_PWR_STATE_CLUSTER U(2) +#define MT_PLAT_PWR_STATE_MCUSYS U(3) +#define MT_PLAT_PWR_STATE_SUSPEND2IDLE U(8) +#define MT_PLAT_PWR_STATE_SYSTEM_SUSPEND U(9) + +#define MTK_LOCAL_STATE_RUN U(0) +#define MTK_LOCAL_STATE_RET U(1) +#define MTK_LOCAL_STATE_OFF U(2) + +#define MTK_AFFLVL_CPU U(0) +#define MTK_AFFLVL_CLUSTER U(1) +#define MTK_AFFLVL_MCUSYS U(2) +#define MTK_AFFLVL_SYSTEM U(3) + +#define IS_CLUSTER_OFF_STATE(s) \ + is_local_state_off(s->pwr_domain_state[MTK_AFFLVL_CLUSTER]) +#define IS_MCUSYS_OFF_STATE(s) \ + is_local_state_off(s->pwr_domain_state[MTK_AFFLVL_MCUSYS]) +#define IS_SYSTEM_SUSPEND_STATE(s) \ + is_local_state_off(s->pwr_domain_state[MTK_AFFLVL_SYSTEM]) + +#define IS_PLAT_SUSPEND_ID(stateid)\ + ((stateid == MT_PLAT_PWR_STATE_SUSPEND2IDLE) \ + || (stateid == MT_PLAT_PWR_STATE_SYSTEM_SUSPEND)) + +#endif /* PLAT_PM_H */ diff --git a/plat/mediatek/mt8192/include/platform_def.h b/plat/mediatek/mt8192/include/platform_def.h index e6e1f8d0a..8d43dc8a9 100644 --- a/plat/mediatek/mt8192/include/platform_def.h +++ b/plat/mediatek/mt8192/include/platform_def.h @@ -23,6 +23,8 @@ #define MTK_DEV_RNG1_SIZE 0x10000000 #define MTK_DEV_RNG2_BASE 0x0c000000 #define MTK_DEV_RNG2_SIZE 0x600000 +#define MTK_MCDI_SRAM_BASE 0x11B000 +#define MTK_MCDI_SRAM_MAP_SIZE 0x1000 #define GPIO_BASE (IO_PHYS + 0x00005000) #define SPM_BASE (IO_PHYS + 0x00006000) diff --git a/plat/mediatek/mt8192/platform.mk b/plat/mediatek/mt8192/platform.mk index e1da9c17a..93b059e93 100644 --- a/plat/mediatek/mt8192/platform.mk +++ b/plat/mediatek/mt8192/platform.mk @@ -11,6 +11,7 @@ PLAT_INCLUDES := -I${MTK_PLAT}/common/ \ -I${MTK_PLAT_SOC}/include/ \ -I${MTK_PLAT_SOC}/drivers/ \ -I${MTK_PLAT_SOC}/drivers/gpio/ \ + -I${MTK_PLAT_SOC}/drivers/mcdi/ \ -I${MTK_PLAT_SOC}/drivers/spmc/ \ -I${MTK_PLAT_SOC}/drivers/timer/ @@ -40,6 +41,9 @@ BL31_SOURCES += common/desc_image_load.c \ ${MTK_PLAT_SOC}/plat_mt_gic.c \ ${MTK_PLAT_SOC}/plat_mt_cirq.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 \ + ${MTK_PLAT_SOC}/drivers/mcdi/mt_mcdi.c \ ${MTK_PLAT_SOC}/drivers/spmc/mtspmc.c \ ${MTK_PLAT_SOC}/drivers/timer/mt_timer.c -- cgit v1.2.3 From 82c00c2ff5a6e0484f0c78c9677bf7e8dfaa287c Mon Sep 17 00:00:00 2001 From: James Liao Date: Tue, 16 Jun 2020 11:48:36 +0800 Subject: mediatek: mt8192: Add CPU hotplug and MCDI support Implement PSCI platform OPs to support CPU hotplug and MCDI. Change-Id: I31abfc752b69ac40e70bc9e7a55163eb39776c44 Signed-off-by: James Liao --- plat/mediatek/mt8192/include/platform_def.h | 5 +- plat/mediatek/mt8192/plat_pm.c | 356 +++++++++++++++++++++++++++- plat/mediatek/mt8192/plat_topology.c | 2 + 3 files changed, 350 insertions(+), 13 deletions(-) diff --git a/plat/mediatek/mt8192/include/platform_def.h b/plat/mediatek/mt8192/include/platform_def.h index 8d43dc8a9..163ea6188 100644 --- a/plat/mediatek/mt8192/include/platform_def.h +++ b/plat/mediatek/mt8192/include/platform_def.h @@ -70,11 +70,12 @@ ******************************************************************************/ #define PLATFORM_STACK_SIZE 0x800 -#define PLAT_MAX_PWR_LVL U(2) +#define PLAT_MAX_PWR_LVL U(3) #define PLAT_MAX_RET_STATE U(1) -#define PLAT_MAX_OFF_STATE U(2) +#define PLAT_MAX_OFF_STATE U(9) #define PLATFORM_SYSTEM_COUNT U(1) +#define PLATFORM_MCUSYS_COUNT U(1) #define PLATFORM_CLUSTER_COUNT U(1) #define PLATFORM_CLUSTER0_CORE_COUNT U(8) #define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER0_CORE_COUNT) diff --git a/plat/mediatek/mt8192/plat_pm.c b/plat/mediatek/mt8192/plat_pm.c index becf5d311..654a9a9f8 100644 --- a/plat/mediatek/mt8192/plat_pm.c +++ b/plat/mediatek/mt8192/plat_pm.c @@ -5,17 +5,335 @@ */ /* common headers */ +#include + #include #include #include #include -/* mediatek platform specific headers */ +/* platform specific headers */ +#include +#include +#include +#include #include +#include + +/* + * Cluster state request: + * [0] : The CPU requires cluster power down + * [1] : The CPU requires cluster power on + */ +#define coordinate_cluster(onoff) write_clusterpwrdn_el1(onoff) +#define coordinate_cluster_pwron() coordinate_cluster(1) +#define coordinate_cluster_pwroff() coordinate_cluster(0) + +/* platform secure entry point */ +static uintptr_t secure_entrypoint; +/* per-CPU power state */ +static unsigned int plat_power_state[PLATFORM_CORE_COUNT]; + +/* platform CPU power domain - ops */ +static const struct mt_lpm_tz *plat_mt_pm; + +#define plat_mt_pm_invoke(_name, _cpu, _state) ({ \ + int ret = -1; \ + if (plat_mt_pm != NULL && plat_mt_pm->_name != NULL) { \ + ret = plat_mt_pm->_name(_cpu, _state); \ + } \ + ret; }) + +#define plat_mt_pm_invoke_no_check(_name, _cpu, _state) ({ \ + if (plat_mt_pm != NULL && plat_mt_pm->_name != NULL) { \ + (void) plat_mt_pm->_name(_cpu, _state); \ + } \ + }) + +/* + * Common MTK_platform operations to power on/off a + * CPU in response to a CPU_ON, CPU_OFF or CPU_SUSPEND request. + */ + +static void plat_cpu_pwrdwn_common(unsigned int cpu, + const psci_power_state_t *state, unsigned int req_pstate) +{ + assert(cpu == plat_my_core_pos()); + + plat_mt_pm_invoke_no_check(pwr_cpu_dwn, cpu, state); + + if ((psci_get_pstate_pwrlvl(req_pstate) >= MTK_AFFLVL_CLUSTER) || + (req_pstate == 0U)) { /* hotplug off */ + coordinate_cluster_pwroff(); + } + + /* Prevent interrupts from spuriously waking up this CPU */ + mt_gic_rdistif_save(); + gicv3_cpuif_disable(cpu); + gicv3_rdistif_off(cpu); +} + +static void plat_cpu_pwron_common(unsigned int cpu, + const psci_power_state_t *state, unsigned int req_pstate) +{ + assert(cpu == plat_my_core_pos()); + + plat_mt_pm_invoke_no_check(pwr_cpu_on, cpu, state); + + coordinate_cluster_pwron(); + + /* Enable the GIC CPU interface */ + gicv3_rdistif_on(cpu); + gicv3_cpuif_enable(cpu); + mt_gic_rdistif_init(); + + /* + * If mcusys does power down before then restore + * all CPUs' GIC Redistributors + */ + if (IS_MCUSYS_OFF_STATE(state)) { + mt_gic_rdistif_restore_all(); + } else { + mt_gic_rdistif_restore(); + } +} + +/* + * Common MTK_platform operations to power on/off a + * cluster in response to a CPU_ON, CPU_OFF or CPU_SUSPEND request. + */ + +static void plat_cluster_pwrdwn_common(unsigned int cpu, + const psci_power_state_t *state, unsigned int req_pstate) +{ + assert(cpu == plat_my_core_pos()); + + if (plat_mt_pm_invoke(pwr_cluster_dwn, cpu, state) != 0) { + coordinate_cluster_pwron(); + + /* TODO: return on fail. + * Add a 'return' here before adding any code following + * the if-block. + */ + } +} + +static void plat_cluster_pwron_common(unsigned int cpu, + const psci_power_state_t *state, unsigned int req_pstate) +{ + assert(cpu == plat_my_core_pos()); + + if (plat_mt_pm_invoke(pwr_cluster_on, cpu, state) != 0) { + /* TODO: return on fail. + * Add a 'return' here before adding any code following + * the if-block. + */ + } +} + +/* + * Common MTK_platform operations to power on/off a + * mcusys in response to a CPU_ON, CPU_OFF or CPU_SUSPEND request. + */ + +static void plat_mcusys_pwrdwn_common(unsigned int cpu, + const psci_power_state_t *state, unsigned int req_pstate) +{ + assert(cpu == plat_my_core_pos()); + + if (plat_mt_pm_invoke(pwr_mcusys_dwn, cpu, state) != 0) { + return; /* return on fail */ + } + + mt_gic_distif_save(); + gic_sgi_save_all(); +} + +static void plat_mcusys_pwron_common(unsigned int cpu, + const psci_power_state_t *state, unsigned int req_pstate) +{ + assert(cpu == plat_my_core_pos()); + + if (plat_mt_pm_invoke(pwr_mcusys_on, cpu, state) != 0) { + return; /* return on fail */ + } + + mt_gic_init(); + mt_gic_distif_restore(); + gic_sgi_restore_all(); + + plat_mt_pm_invoke_no_check(pwr_mcusys_on_finished, cpu, state); +} + +/* + * plat_psci_ops implementation + */ + +static void plat_cpu_standby(plat_local_state_t cpu_state) +{ + uint64_t scr; + + scr = read_scr_el3(); + write_scr_el3(scr | SCR_IRQ_BIT | SCR_FIQ_BIT); + + isb(); + dsb(); + wfi(); + + write_scr_el3(scr); +} + +static int plat_power_domain_on(u_register_t mpidr) +{ + unsigned int cpu = (unsigned int)plat_core_pos_by_mpidr(mpidr); + unsigned int cluster = 0U; + + if (cpu >= PLATFORM_CORE_COUNT) { + return PSCI_E_INVALID_PARAMS; + } + + if (!spm_get_cluster_powerstate(cluster)) { + spm_poweron_cluster(cluster); + } + + /* init CPU reset arch as AARCH64 */ + mcucfg_init_archstate(cluster, cpu, true); + mcucfg_set_bootaddr(cluster, cpu, secure_entrypoint); + spm_poweron_cpu(cluster, cpu); + + return PSCI_E_SUCCESS; +} + +static void plat_power_domain_on_finish(const psci_power_state_t *state) +{ + unsigned long mpidr = read_mpidr_el1(); + unsigned int cpu = (unsigned int)plat_core_pos_by_mpidr(mpidr); + + assert(cpu < PLATFORM_CORE_COUNT); + + /* Allow IRQs to wakeup this core in IDLE flow */ + mcucfg_enable_gic_wakeup(0U, cpu); + + if (IS_CLUSTER_OFF_STATE(state)) { + plat_cluster_pwron_common(cpu, state, 0U); + } + + plat_cpu_pwron_common(cpu, state, 0U); +} + +static void plat_power_domain_off(const psci_power_state_t *state) +{ + unsigned long mpidr = read_mpidr_el1(); + unsigned int cpu = (unsigned int)plat_core_pos_by_mpidr(mpidr); + + assert(cpu < PLATFORM_CORE_COUNT); + + plat_cpu_pwrdwn_common(cpu, state, 0U); + spm_poweroff_cpu(0U, cpu); + + /* prevent unintended IRQs from waking up the hot-unplugged core */ + mcucfg_disable_gic_wakeup(0U, cpu); + + if (IS_CLUSTER_OFF_STATE(state)) { + plat_cluster_pwrdwn_common(cpu, state, 0U); + } +} + +static void plat_power_domain_suspend(const psci_power_state_t *state) +{ + unsigned int cpu = plat_my_core_pos(); + + assert(cpu < PLATFORM_CORE_COUNT); + + plat_mt_pm_invoke_no_check(pwr_prompt, cpu, state); + + /* Perform the common CPU specific operations */ + plat_cpu_pwrdwn_common(cpu, state, plat_power_state[cpu]); + + if (IS_CLUSTER_OFF_STATE(state)) { + /* Perform the common cluster specific operations */ + plat_cluster_pwrdwn_common(cpu, state, plat_power_state[cpu]); + } + + if (IS_MCUSYS_OFF_STATE(state)) { + /* Perform the common mcusys specific operations */ + plat_mcusys_pwrdwn_common(cpu, state, plat_power_state[cpu]); + } +} + +static void plat_power_domain_suspend_finish(const psci_power_state_t *state) +{ + unsigned int cpu = plat_my_core_pos(); + + assert(cpu < PLATFORM_CORE_COUNT); + + if (IS_MCUSYS_OFF_STATE(state)) { + /* Perform the common mcusys specific operations */ + plat_mcusys_pwron_common(cpu, state, plat_power_state[cpu]); + } + + if (IS_CLUSTER_OFF_STATE(state)) { + /* Perform the common cluster specific operations */ + plat_cluster_pwron_common(cpu, state, plat_power_state[cpu]); + } + + /* Perform the common CPU specific operations */ + plat_cpu_pwron_common(cpu, state, plat_power_state[cpu]); + + plat_mt_pm_invoke_no_check(pwr_reflect, cpu, state); +} + +static int plat_validate_power_state(unsigned int power_state, + psci_power_state_t *req_state) +{ + unsigned int pstate = psci_get_pstate_type(power_state); + unsigned int aff_lvl = psci_get_pstate_pwrlvl(power_state); + unsigned int cpu = plat_my_core_pos(); + + if (aff_lvl > PLAT_MAX_PWR_LVL) { + return PSCI_E_INVALID_PARAMS; + } + + if (pstate == PSTATE_TYPE_STANDBY) { + req_state->pwr_domain_state[0] = PLAT_MAX_RET_STATE; + } else { + unsigned int i; + unsigned int pstate_id = psci_get_pstate_id(power_state); + plat_local_state_t s = MTK_LOCAL_STATE_OFF; + + /* Use pstate_id to be power domain state */ + if (pstate_id > s) { + s = (plat_local_state_t)pstate_id; + } + + for (i = 0U; i <= aff_lvl; i++) { + req_state->pwr_domain_state[i] = s; + } + } + + plat_power_state[cpu] = power_state; + return PSCI_E_SUCCESS; +} + +static void plat_get_sys_suspend_power_state(psci_power_state_t *req_state) +{ + unsigned int lv; + unsigned int cpu = plat_my_core_pos(); + + for (lv = PSCI_CPU_PWR_LVL; lv <= PLAT_MAX_PWR_LVL; lv++) { + req_state->pwr_domain_state[lv] = PLAT_MAX_OFF_STATE; + } + + plat_power_state[cpu] = + psci_make_powerstate( + MT_PLAT_PWR_STATE_SYSTEM_SUSPEND, + PSTATE_TYPE_POWERDOWN, PLAT_MAX_PWR_LVL); + + flush_dcache_range((uintptr_t) + &plat_power_state[cpu], + sizeof(plat_power_state[cpu])); +} -/******************************************************************************* - * MTK handlers to shutdown/reboot the system - ******************************************************************************/ static void __dead2 plat_mtk_system_reset(void) { struct bl_aux_gpio_info *gpio_reset = plat_get_mtk_gpio_reset(); @@ -29,18 +347,34 @@ static void __dead2 plat_mtk_system_reset(void) panic(); } -/******************************************************************************* - * MTK_platform handler called when an affinity instance is about to be turned - * on. The level and mpidr determine the affinity instance. - ******************************************************************************/ -static const plat_psci_ops_t plat_plat_pm_ops = { - .system_reset = plat_mtk_system_reset, +static const plat_psci_ops_t plat_psci_ops = { + .system_reset = plat_mtk_system_reset, + .cpu_standby = plat_cpu_standby, + .pwr_domain_on = plat_power_domain_on, + .pwr_domain_on_finish = plat_power_domain_on_finish, + .pwr_domain_off = plat_power_domain_off, + .pwr_domain_suspend = plat_power_domain_suspend, + .pwr_domain_suspend_finish = plat_power_domain_suspend_finish, + .validate_power_state = plat_validate_power_state, + .get_sys_suspend_power_state = plat_get_sys_suspend_power_state }; int plat_setup_psci_ops(uintptr_t sec_entrypoint, const plat_psci_ops_t **psci_ops) { - *psci_ops = &plat_plat_pm_ops; + *psci_ops = &plat_psci_ops; + secure_entrypoint = sec_entrypoint; + + /* + * init the warm reset config for boot CPU + * reset arch as AARCH64 + * reset addr as function bl31_warm_entrypoint() + */ + mcucfg_init_archstate(0U, 0U, true); + mcucfg_set_bootaddr(0U, 0U, secure_entrypoint); + + spmc_init(); + plat_mt_pm = mt_plat_cpu_pm_init(); return 0; } diff --git a/plat/mediatek/mt8192/plat_topology.c b/plat/mediatek/mt8192/plat_topology.c index aa4975e80..8c1231a6e 100644 --- a/plat/mediatek/mt8192/plat_topology.c +++ b/plat/mediatek/mt8192/plat_topology.c @@ -17,6 +17,8 @@ const unsigned char mtk_power_domain_tree_desc[] = { /* Number of root nodes */ PLATFORM_SYSTEM_COUNT, /* Number of children for the root node */ + PLATFORM_MCUSYS_COUNT, + /* Number of children for the mcusys node */ PLATFORM_CLUSTER_COUNT, /* Number of children for the first cluster node */ PLATFORM_CLUSTER0_CORE_COUNT, -- cgit v1.2.3 From f3fbacaa9ae9e47dee75272f80408c6dec2e0e2c Mon Sep 17 00:00:00 2001 From: Dehui Sun Date: Mon, 6 Jul 2020 18:01:42 +0800 Subject: mediatek: mt8192: enable NS access for systimer Enable NS access for all systimers. Signed-off-by: Dehui Sun Change-Id: I3693997082a1d6f09fef5a79b6cf5a91be46cb8a --- plat/mediatek/mt8192/bl31_plat_setup.c | 3 +++ plat/mediatek/mt8192/drivers/timer/mt_timer.c | 8 ++++++++ plat/mediatek/mt8192/drivers/timer/mt_timer.h | 5 +++++ 3 files changed, 16 insertions(+) diff --git a/plat/mediatek/mt8192/bl31_plat_setup.c b/plat/mediatek/mt8192/bl31_plat_setup.c index 9a01bef65..4d2f5d24c 100644 --- a/plat/mediatek/mt8192/bl31_plat_setup.c +++ b/plat/mediatek/mt8192/bl31_plat_setup.c @@ -17,6 +17,7 @@ /* Platform Includes */ #include #include +#include #include #include @@ -84,7 +85,9 @@ void bl31_platform_setup(void) /* Initialize the GIC driver, CPU and distributor interfaces */ mt_gic_driver_init(); mt_gic_init(); + plat_mt8192_gpio_init(); + mt_systimer_init(); } /******************************************************************************* diff --git a/plat/mediatek/mt8192/drivers/timer/mt_timer.c b/plat/mediatek/mt8192/drivers/timer/mt_timer.c index 781f940b6..08608854a 100644 --- a/plat/mediatek/mt8192/drivers/timer/mt_timer.c +++ b/plat/mediatek/mt8192/drivers/timer/mt_timer.c @@ -5,6 +5,7 @@ */ #include +#include #include #include @@ -28,3 +29,10 @@ uint64_t sched_clock(void) - normal_time_base; return cval; } + +void mt_systimer_init(void) +{ + /* Enable access in NS mode */ + mmio_write_32(CNTWACR_REG, CNT_WRITE_ACCESS_CTL_MASK); + mmio_write_32(CNTRACR_REG, CNT_READ_ACCESS_CTL_MASK); +} diff --git a/plat/mediatek/mt8192/drivers/timer/mt_timer.h b/plat/mediatek/mt8192/drivers/timer/mt_timer.h index 7aca4a3bf..b35317715 100644 --- a/plat/mediatek/mt8192/drivers/timer/mt_timer.h +++ b/plat/mediatek/mt8192/drivers/timer/mt_timer.h @@ -12,6 +12,8 @@ #define CNTSR_REG (SYSTIMER_BASE + 0x4) #define CNTSYS_L_REG (SYSTIMER_BASE + 0x8) #define CNTSYS_H_REG (SYSTIMER_BASE + 0xc) +#define CNTWACR_REG (SYSTIMER_BASE + 0x10) +#define CNTRACR_REG (SYSTIMER_BASE + 0x14) #define TIEO_EN (1 << 3) #define COMP_15_EN (1 << 10) @@ -23,8 +25,11 @@ #define COMP_20_MASK (COMP_20_EN | TIEO_EN) #define COMP_25_MASK (COMP_20_EN | COMP_25_EN) +#define CNT_WRITE_ACCESS_CTL_MASK (0x3FFFFF0U) +#define CNT_READ_ACCESS_CTL_MASK (0x3FFFFFFU) void sched_clock_init(uint64_t normal_base, uint64_t atf_base); uint64_t sched_clock(void); +void mt_systimer_init(void); #endif /* MT_TIMER_H */ -- cgit v1.2.3 From 95cc8894886b92f4749999a25297bc5942a97d7b Mon Sep 17 00:00:00 2001 From: Nina Wu Date: Wed, 5 Aug 2020 13:53:59 +0800 Subject: mediatek: mt8192: Initialize delay_timer Init delay_timer for the use of delay functions Change-Id: I35aefd7515bb9259634c8b6bc37d8c74da96e8f1 Signed-off-by: Nina Wu --- plat/mediatek/mt8192/bl31_plat_setup.c | 2 ++ plat/mediatek/mt8192/platform.mk | 2 ++ 2 files changed, 4 insertions(+) diff --git a/plat/mediatek/mt8192/bl31_plat_setup.c b/plat/mediatek/mt8192/bl31_plat_setup.c index 4d2f5d24c..2a0e131b9 100644 --- a/plat/mediatek/mt8192/bl31_plat_setup.c +++ b/plat/mediatek/mt8192/bl31_plat_setup.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -88,6 +89,7 @@ void bl31_platform_setup(void) plat_mt8192_gpio_init(); mt_systimer_init(); + generic_delay_timer_init(); } /******************************************************************************* diff --git a/plat/mediatek/mt8192/platform.mk b/plat/mediatek/mt8192/platform.mk index 93b059e93..3c54f70dd 100644 --- a/plat/mediatek/mt8192/platform.mk +++ b/plat/mediatek/mt8192/platform.mk @@ -25,6 +25,8 @@ PLAT_BL_COMMON_SOURCES := ${GICV3_SOURCES} \ plat/common/plat_psci_common.c BL31_SOURCES += common/desc_image_load.c \ + drivers/delay_timer/delay_timer.c \ + drivers/delay_timer/generic_delay_timer.c \ drivers/ti/uart/aarch64/16550_console.S \ drivers/gpio/gpio.c \ lib/bl_aux_params/bl_aux_params.c \ -- cgit v1.2.3 From cbd6331beb650d0c76a957f0d74e2df0461344f9 Mon Sep 17 00:00:00 2001 From: Hsin-Hsiung Wang Date: Wed, 12 Aug 2020 16:31:06 +0800 Subject: mediatek: mt8192: add pmic mt6359p driver add pmic mt6359p driver Signed-off-by: Hsin-Hsiung Wang Change-Id: I20f2218f7d2087e8d2bf31258cf92a02e0dab77d --- .../common/drivers/pmic_wrap/pmic_wrap_init_v2.c | 125 +++++++++++++++++++++ plat/mediatek/mt8192/drivers/pmic/pmic.c | 13 +++ plat/mediatek/mt8192/drivers/pmic/pmic.h | 15 +++ plat/mediatek/mt8192/drivers/pmic/pmic_wrap_init.h | 76 +++++++++++++ plat/mediatek/mt8192/include/platform_def.h | 1 + plat/mediatek/mt8192/platform.mk | 3 + 6 files changed, 233 insertions(+) create mode 100644 plat/mediatek/common/drivers/pmic_wrap/pmic_wrap_init_v2.c create mode 100644 plat/mediatek/mt8192/drivers/pmic/pmic.c create mode 100644 plat/mediatek/mt8192/drivers/pmic/pmic.h create mode 100644 plat/mediatek/mt8192/drivers/pmic/pmic_wrap_init.h diff --git a/plat/mediatek/common/drivers/pmic_wrap/pmic_wrap_init_v2.c b/plat/mediatek/common/drivers/pmic_wrap/pmic_wrap_init_v2.c new file mode 100644 index 000000000..fca69130a --- /dev/null +++ b/plat/mediatek/common/drivers/pmic_wrap/pmic_wrap_init_v2.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include "platform_def.h" +#include "pmic_wrap_init.h" + +/* pmic wrap module wait_idle and read polling interval (in microseconds) */ +enum pwrap_polling_interval { + WAIT_IDLE_POLLING_DELAY_US = 1, + READ_POLLING_DELAY_US = 2 +}; + +static uint32_t pwrap_check_idle(void *wacs_register, uint32_t timeout_us) +{ + uint32_t reg_rdata = 0U, retry; + + retry = (timeout_us + WAIT_IDLE_POLLING_DELAY_US) / + WAIT_IDLE_POLLING_DELAY_US; + while (retry != 0) { + udelay(WAIT_IDLE_POLLING_DELAY_US); + reg_rdata = mmio_read_32((uintptr_t)wacs_register); + if (GET_WACS_FSM(reg_rdata) == SWINF_FSM_IDLE) { + break; + } + retry--; + }; + + if (retry == 0) { + /* timeout */ + return E_PWR_WAIT_IDLE_TIMEOUT; + } + + return 0U; +} + +static uint32_t pwrap_check_vldclr(void *wacs_register, uint32_t timeout_us) +{ + uint32_t reg_rdata = 0U, retry; + + retry = (timeout_us + READ_POLLING_DELAY_US) / READ_POLLING_DELAY_US; + while (retry != 0) { + udelay(READ_POLLING_DELAY_US); + reg_rdata = mmio_read_32((uintptr_t)wacs_register); + if (GET_WACS_FSM(reg_rdata) == SWINF_FSM_WFVLDCLR) { + break; + } + retry--; + }; + + if (retry == 0) { + /* timeout */ + return E_PWR_WAIT_IDLE_TIMEOUT; + } + + return 0U; +} + +static int32_t pwrap_wacs2(uint32_t write, uint32_t adr, uint32_t wdata, + uint32_t *rdata, uint32_t init_check) +{ + uint32_t reg_rdata, return_value; + + if (init_check != 0) { + if ((mmio_read_32((uintptr_t)&mtk_pwrap->init_done) & 0x1) == 0) { + ERROR("initialization isn't finished\n"); + return E_PWR_NOT_INIT_DONE; + } + } + + /* Wait for Software Interface FSM state to be IDLE. */ + return_value = pwrap_check_idle(&mtk_pwrap->wacs2_sta, + PWRAP_WAIT_IDLE_US); + if (return_value != 0) { + return return_value; + } + + /* Set the write data */ + if (write == 1) { + /* Set the write data. */ + mmio_write_32((uintptr_t)&mtk_pwrap->wacs2_wdata, wdata); + } + + /* Send the command. */ + mmio_write_32((uintptr_t)&mtk_pwrap->wacs2_cmd, (write << 29) | adr); + + if (write == 0) { + /* + * Wait for Software Interface FSM state to be WFVLDCLR, + * read the data and clear the valid flag. + */ + return_value = pwrap_check_vldclr(&mtk_pwrap->wacs2_sta, + PWRAP_READ_US); + if (return_value != 0) { + return return_value; + } + + if (rdata == NULL) { + return E_PWR_INVALID_ARG; + } + + reg_rdata = mmio_read_32((uintptr_t)&mtk_pwrap->wacs2_rdata); + *rdata = reg_rdata; + mmio_write_32((uintptr_t)&mtk_pwrap->wacs2_vldclr, 0x1); + } + + return return_value; +} + +/* external API for pmic_wrap user */ +int32_t pwrap_read(uint32_t adr, uint32_t *rdata) +{ + return pwrap_wacs2(0, adr, 0, rdata, 1); +} + +int32_t pwrap_write(uint32_t adr, uint32_t wdata) +{ + return pwrap_wacs2(1, adr, wdata, 0, 1); +} diff --git a/plat/mediatek/mt8192/drivers/pmic/pmic.c b/plat/mediatek/mt8192/drivers/pmic/pmic.c new file mode 100644 index 000000000..cca441397 --- /dev/null +++ b/plat/mediatek/mt8192/drivers/pmic/pmic.c @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +void pmic_power_off(void) +{ + pwrap_write(PMIC_PWRHOLD, 0x0); +} diff --git a/plat/mediatek/mt8192/drivers/pmic/pmic.h b/plat/mediatek/mt8192/drivers/pmic/pmic.h new file mode 100644 index 000000000..aac22afa3 --- /dev/null +++ b/plat/mediatek/mt8192/drivers/pmic/pmic.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PMIC_H +#define PMIC_H + +#define PMIC_PWRHOLD 0xa08 + +/* external API */ +void pmic_power_off(void); + +#endif /* PMIC_H */ diff --git a/plat/mediatek/mt8192/drivers/pmic/pmic_wrap_init.h b/plat/mediatek/mt8192/drivers/pmic/pmic_wrap_init.h new file mode 100644 index 000000000..ae892ed5a --- /dev/null +++ b/plat/mediatek/mt8192/drivers/pmic/pmic_wrap_init.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PMIC_WRAP_INIT_H +#define PMIC_WRAP_INIT_H + +#include + +#include "platform_def.h" + +/* external API */ +int32_t pwrap_read(uint32_t adr, uint32_t *rdata); +int32_t pwrap_write(uint32_t adr, uint32_t wdata); + +static struct mt8192_pmic_wrap_regs *const mtk_pwrap = (void *)PMIC_WRAP_BASE; + +/* PMIC_WRAP registers */ +struct mt8192_pmic_wrap_regs { + uint32_t init_done; + uint32_t reserved[799]; + uint32_t wacs2_cmd; + uint32_t wacs2_wdata; + uint32_t reserved1[3]; + uint32_t wacs2_rdata; + uint32_t reserved2[3]; + uint32_t wacs2_vldclr; + uint32_t wacs2_sta; +}; + +#define GET_WACS_FSM(x) ((x >> 1) & 0x7) + +/* macro for SWINF_FSM */ +#define SWINF_FSM_IDLE (0x00) +#define SWINF_FSM_REQ (0x02) +#define SWINF_FSM_WFDLE (0x04) +#define SWINF_FSM_WFVLDCLR (0x06) +#define SWINF_INIT_DONE (0x01) + +/* timeout setting */ +#define PWRAP_READ_US 1000 +#define PWRAP_WAIT_IDLE_US 1000 + +/* error information flag */ +enum pwrap_errno { + E_PWR_INVALID_ARG = 1, + E_PWR_INVALID_RW = 2, + E_PWR_INVALID_ADDR = 3, + E_PWR_INVALID_WDAT = 4, + E_PWR_INVALID_OP_MANUAL = 5, + E_PWR_NOT_IDLE_STATE = 6, + E_PWR_NOT_INIT_DONE = 7, + E_PWR_NOT_INIT_DONE_READ = 8, + E_PWR_WAIT_IDLE_TIMEOUT = 9, + E_PWR_WAIT_IDLE_TIMEOUT_READ = 10, + E_PWR_INIT_SIDLY_FAIL = 11, + E_PWR_RESET_TIMEOUT = 12, + E_PWR_TIMEOUT = 13, + E_PWR_INIT_RESET_SPI = 20, + E_PWR_INIT_SIDLY = 21, + E_PWR_INIT_REG_CLOCK = 22, + E_PWR_INIT_ENABLE_PMIC = 23, + E_PWR_INIT_DIO = 24, + E_PWR_INIT_CIPHER = 25, + E_PWR_INIT_WRITE_TEST = 26, + E_PWR_INIT_ENABLE_CRC = 27, + E_PWR_INIT_ENABLE_DEWRAP = 28, + E_PWR_INIT_ENABLE_EVENT = 29, + E_PWR_READ_TEST_FAIL = 30, + E_PWR_WRITE_TEST_FAIL = 31, + E_PWR_SWITCH_DIO = 32 +}; + +#endif /* PMIC_WRAP_INIT_H */ diff --git a/plat/mediatek/mt8192/include/platform_def.h b/plat/mediatek/mt8192/include/platform_def.h index 163ea6188..a3ab1a0ca 100644 --- a/plat/mediatek/mt8192/include/platform_def.h +++ b/plat/mediatek/mt8192/include/platform_def.h @@ -28,6 +28,7 @@ #define GPIO_BASE (IO_PHYS + 0x00005000) #define SPM_BASE (IO_PHYS + 0x00006000) +#define PMIC_WRAP_BASE (IO_PHYS + 0x00026000) #define IOCFG_RM_BASE (IO_PHYS + 0x01C20000) #define IOCFG_BM_BASE (IO_PHYS + 0x01D10000) #define IOCFG_BL_BASE (IO_PHYS + 0x01D30000) diff --git a/plat/mediatek/mt8192/platform.mk b/plat/mediatek/mt8192/platform.mk index 3c54f70dd..01851effc 100644 --- a/plat/mediatek/mt8192/platform.mk +++ b/plat/mediatek/mt8192/platform.mk @@ -12,6 +12,7 @@ PLAT_INCLUDES := -I${MTK_PLAT}/common/ \ -I${MTK_PLAT_SOC}/drivers/ \ -I${MTK_PLAT_SOC}/drivers/gpio/ \ -I${MTK_PLAT_SOC}/drivers/mcdi/ \ + -I${MTK_PLAT_SOC}/drivers/pmic/ \ -I${MTK_PLAT_SOC}/drivers/spmc/ \ -I${MTK_PLAT_SOC}/drivers/timer/ @@ -33,11 +34,13 @@ BL31_SOURCES += common/desc_image_load.c \ lib/cpus/aarch64/cortex_a55.S \ lib/cpus/aarch64/cortex_a76.S \ plat/common/plat_gicv3.c \ + ${MTK_PLAT}/common/drivers/pmic_wrap/pmic_wrap_init_v2.c \ ${MTK_PLAT}/common/mtk_plat_common.c \ ${MTK_PLAT}/common/params_setup.c \ ${MTK_PLAT_SOC}/aarch64/platform_common.c \ ${MTK_PLAT_SOC}/aarch64/plat_helpers.S \ ${MTK_PLAT_SOC}/bl31_plat_setup.c \ + ${MTK_PLAT_SOC}/drivers/pmic/pmic.c \ ${MTK_PLAT_SOC}/plat_pm.c \ ${MTK_PLAT_SOC}/plat_topology.c \ ${MTK_PLAT_SOC}/plat_mt_gic.c \ -- cgit v1.2.3 From 26f3dbe2d656e0fda9c52669af7d369c277c259e Mon Sep 17 00:00:00 2001 From: Hsin-Hsiung Wang Date: Wed, 12 Aug 2020 16:32:10 +0800 Subject: mediatek: mt8192: add power-off support add power-off support Signed-off-by: Hsin-Hsiung Wang Change-Id: If19e99971515a8ae1ac9ae21046e4382adc18a69 --- plat/mediatek/mt8192/plat_pm.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/plat/mediatek/mt8192/plat_pm.c b/plat/mediatek/mt8192/plat_pm.c index 654a9a9f8..ac6cb8085 100644 --- a/plat/mediatek/mt8192/plat_pm.c +++ b/plat/mediatek/mt8192/plat_pm.c @@ -19,6 +19,7 @@ #include #include #include +#include /* * Cluster state request: @@ -334,6 +335,17 @@ static void plat_get_sys_suspend_power_state(psci_power_state_t *req_state) sizeof(plat_power_state[cpu])); } +static void __dead2 plat_mtk_system_off(void) +{ + INFO("MTK System Off\n"); + + pmic_power_off(); + + wfi(); + ERROR("MTK System Off: operation not handled.\n"); + panic(); +} + static void __dead2 plat_mtk_system_reset(void) { struct bl_aux_gpio_info *gpio_reset = plat_get_mtk_gpio_reset(); @@ -355,6 +367,7 @@ static const plat_psci_ops_t plat_psci_ops = { .pwr_domain_off = plat_power_domain_off, .pwr_domain_suspend = plat_power_domain_suspend, .pwr_domain_suspend_finish = plat_power_domain_suspend_finish, + .system_off = plat_mtk_system_off, .validate_power_state = plat_validate_power_state, .get_sys_suspend_power_state = plat_get_sys_suspend_power_state }; -- cgit v1.2.3 From 49fd68abe46dbbb69027283527cc5c9d8a81b678 Mon Sep 17 00:00:00 2001 From: "G.Pangao" Date: Fri, 6 Nov 2020 09:20:25 +0800 Subject: mediatek: mt8192: modify sys_cirq driver 1.Modify this driver to make it more complete and more standard. 2.And makes this driver available for more IC services. 3.Solve some bugs in the software. Signed-off-by: G.Pangao Change-Id: I284956d47ebbbd550ec93767679181185e442348 --- plat/mediatek/mt8192/include/plat_mt_cirq.h | 124 +++-- plat/mediatek/mt8192/plat_mt_cirq.c | 718 +++++++++++++++------------- 2 files changed, 473 insertions(+), 369 deletions(-) diff --git a/plat/mediatek/mt8192/include/plat_mt_cirq.h b/plat/mediatek/mt8192/include/plat_mt_cirq.h index 581860109..bb8b4577f 100644 --- a/plat/mediatek/mt8192/include/plat_mt_cirq.h +++ b/plat/mediatek/mt8192/include/plat_mt_cirq.h @@ -7,24 +7,53 @@ #ifndef PLAT_MT_CIRQ_H #define PLAT_MT_CIRQ_H -#define SYS_CIRQ_BASE U(0x10204000) -#define CIRQ_IRQ_NUM U(439) -#define CIRQ_SPI_START U(96) +#include + +enum { + IRQ_MASK_HEADER = 0xF1F1F1F1, + IRQ_MASK_FOOTER = 0xF2F2F2F2 +}; + +struct mtk_irq_mask { + uint32_t header; /* for error checking */ + uint32_t mask0; + uint32_t mask1; + uint32_t mask2; + uint32_t mask3; + uint32_t mask4; + uint32_t mask5; + uint32_t mask6; + uint32_t mask7; + uint32_t mask8; + uint32_t mask9; + uint32_t mask10; + uint32_t mask11; + uint32_t mask12; + uint32_t footer; /* for error checking */ +}; + /* * Define hardware register */ -#define CIRQ_STA_BASE U(0x000) -#define CIRQ_ACK_BASE U(0x080) -#define CIRQ_MASK_BASE U(0x100) -#define CIRQ_MASK_SET_BASE U(0x180) -#define CIRQ_MASK_CLR_BASE U(0x200) -#define CIRQ_SENS_BASE U(0x280) -#define CIRQ_SENS_SET_BASE U(0x300) -#define CIRQ_SENS_CLR_BASE U(0x380) -#define CIRQ_POL_BASE U(0x400) -#define CIRQ_POL_SET_BASE U(0x480) -#define CIRQ_POL_CLR_BASE U(0x500) -#define CIRQ_CON U(0x600) + +#define SYS_CIRQ_BASE U(0x10204000) +#define CIRQ_REG_NUM U(14) +#define CIRQ_IRQ_NUM U(439) +#define CIRQ_SPI_START U(64) +#define MD_WDT_IRQ_BIT_ID U(110) + +#define CIRQ_STA_BASE (SYS_CIRQ_BASE + U(0x000)) +#define CIRQ_ACK_BASE (SYS_CIRQ_BASE + U(0x080)) +#define CIRQ_MASK_BASE (SYS_CIRQ_BASE + U(0x100)) +#define CIRQ_MASK_SET_BASE (SYS_CIRQ_BASE + U(0x180)) +#define CIRQ_MASK_CLR_BASE (SYS_CIRQ_BASE + U(0x200)) +#define CIRQ_SENS_BASE (SYS_CIRQ_BASE + U(0x280)) +#define CIRQ_SENS_SET_BASE (SYS_CIRQ_BASE + U(0x300)) +#define CIRQ_SENS_CLR_BASE (SYS_CIRQ_BASE + U(0x380)) +#define CIRQ_POL_BASE (SYS_CIRQ_BASE + U(0x400)) +#define CIRQ_POL_SET_BASE (SYS_CIRQ_BASE + U(0x480)) +#define CIRQ_POL_CLR_BASE (SYS_CIRQ_BASE + U(0x500)) +#define CIRQ_CON (SYS_CIRQ_BASE + U(0x600)) /* * Register placement @@ -32,8 +61,8 @@ #define CIRQ_CON_EN_BITS U(0) #define CIRQ_CON_EDGE_ONLY_BITS U(1) #define CIRQ_CON_FLUSH_BITS U(2) -#define CIRQ_CON_EVENT_BITS U(31) #define CIRQ_CON_SW_RST_BITS U(20) +#define CIRQ_CON_EVENT_BITS U(31) #define CIRQ_CON_BITS_MASK U(0x7) /* @@ -41,42 +70,59 @@ */ #define CIRQ_CON_EN U(0x1) #define CIRQ_CON_EDGE_ONLY U(0x1) -#define CIRQ_SW_RESET U(0x1) #define CIRQ_CON_FLUSH U(0x1) +#define CIRQ_SW_RESET U(0x1) /* * Define constant */ #define CIRQ_CTRL_REG_NUM ((CIRQ_IRQ_NUM + 31U) / 32U) -#define MT_CIRQ_POL_NEG U(0) -#define MT_CIRQ_POL_POS U(1) -#define MT_CIRQ_EDGE_SENSITIVE U(0) -#define MT_CIRQ_LEVEL_SENSITIVE U(1) -/* - * Define macro - */ -#define IRQ_TO_CIRQ_NUM(irq) ((irq) - (CIRQ_SPI_START)) -#define CIRQ_TO_IRQ_NUM(cirq) ((cirq) + (CIRQ_SPI_START)) +#define MT_CIRQ_POL_NEG U(0) +#define MT_CIRQ_POL_POS U(1) + +#define IRQ_TO_CIRQ_NUM(irq) ((irq) - (32U + CIRQ_SPI_START)) +#define CIRQ_TO_IRQ_NUM(cirq) ((cirq) + (32U + CIRQ_SPI_START)) + +/* GIC sensitive */ +#define SENS_EDGE U(0x2) +#define SENS_LEVEL U(0x1) -/* - * Define cirq events - */ -struct cirq_events { - uint32_t spi_start; - uint32_t num_of_events; - uint32_t *wakeup_events; -}; /* * Define function prototypes. */ -void mt_cirq_enable(void); -void mt_cirq_disable(void); +int mt_cirq_test(void); +void mt_cirq_dump_reg(void); +int mt_irq_mask_restore(struct mtk_irq_mask *mask); +int mt_irq_mask_all(struct mtk_irq_mask *mask); void mt_cirq_clone_gic(void); +void mt_cirq_enable(void); void mt_cirq_flush(void); -void mt_cirq_sw_reset(void); +void mt_cirq_disable(void); +void mt_irq_unmask_for_sleep_ex(uint32_t irq); void set_wakeup_sources(uint32_t *list, uint32_t num_of_events); -void mt_cirq_dump_reg(void); +void mt_cirq_sw_reset(void); + +struct cirq_reg { + uint32_t reg_num; + uint32_t used; + uint32_t mask; + uint32_t pol; + uint32_t sen; + uint32_t pending; + uint32_t the_link; +}; + +struct cirq_events { + uint32_t num_reg; + uint32_t spi_start; + uint32_t num_of_events; + uint32_t *wakeup_events; + struct cirq_reg table[CIRQ_REG_NUM]; + uint32_t dist_base; + uint32_t cirq_base; + uint32_t used_reg_head; +}; -#endif /* PLAT_MT_CIRQ_H */ +#endif /* PLAT_MT_CIRQ_H */ diff --git a/plat/mediatek/mt8192/plat_mt_cirq.c b/plat/mediatek/mt8192/plat_mt_cirq.c index 7fc060799..9002b7ee1 100644 --- a/plat/mediatek/mt8192/plat_mt_cirq.c +++ b/plat/mediatek/mt8192/plat_mt_cirq.c @@ -7,137 +7,255 @@ #include #include #include -#include #include #include -#include #include #include static struct cirq_events cirq_all_events = { - .spi_start = CIRQ_SPI_START + .spi_start = CIRQ_SPI_START, }; - -static inline void mt_cirq_write32(uint32_t val, uint32_t addr) -{ - mmio_write_32(addr + SYS_CIRQ_BASE, val); -} - -static inline uint32_t mt_cirq_read32(uint32_t addr) -{ - return mmio_read_32(addr + SYS_CIRQ_BASE); -} - +static uint32_t already_cloned; /* - * cirq_clone_flush_check_store: - * set 1 if we need to enable clone/flush value's check + * mt_irq_mask_restore: restore all interrupts + * @mask: pointer to struct mtk_irq_mask for storing the original mask value. + * Return 0 for success; return negative values for failure. + * (This is ONLY used for the idle current measurement by the factory mode.) */ -static int32_t cirq_clone_flush_check_val; +int mt_irq_mask_restore(struct mtk_irq_mask *mask) +{ + if (mask == NULL) { + return -1; + } + if (mask->header != IRQ_MASK_HEADER) { + return -1; + } + if (mask->footer != IRQ_MASK_FOOTER) { + return -1; + } -/* - * cirq_pattern_clone_flush_check_show: set 1 if we need to do pattern test. - */ -static int32_t cirq_pattern_clone_flush_check_val; + mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x4), + mask->mask1); + mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x8), + mask->mask2); + mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0xc), + mask->mask3); + mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x10), + mask->mask4); + mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x14), + mask->mask5); + mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x18), + mask->mask6); + mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x1c), + mask->mask7); + mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x20), + mask->mask8); + mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x24), + mask->mask9); + mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x28), + mask->mask10); + mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x2c), + mask->mask11); + mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x30), + mask->mask12); + /* make sure dist changes happen */ + dsb(); -/* - * cirq_pattern_clone_flush_check_show: set 1 if we need to do pattern test. - */ -static int32_t cirq_pattern_list; + return 0; +} /* - * mt_cirq_ack_all: Ack all the interrupt on SYS_CIRQ + * mt_irq_mask_all: disable all interrupts + * @mask: pointer to struct mtk_irq_mask for storing the original mask value. + * Return 0 for success; return negative values for failure. + * (This is ONLY used for the idle current measurement by the factory mode.) */ -void mt_cirq_ack_all(void) +int mt_irq_mask_all(struct mtk_irq_mask *mask) { - unsigned int i; - - for (i = 0U; i < CIRQ_CTRL_REG_NUM; i++) { - mt_cirq_write32(0xFFFFFFFF, CIRQ_ACK_BASE + (i * 4U)); + if (mask != NULL) { + /* for SPI */ + mask->mask1 = mmio_read_32((BASE_GICD_BASE + + GICD_ISENABLER + 0x4)); + mask->mask2 = mmio_read_32((BASE_GICD_BASE + + GICD_ISENABLER + 0x8)); + mask->mask3 = mmio_read_32((BASE_GICD_BASE + + GICD_ISENABLER + 0xc)); + mask->mask4 = mmio_read_32((BASE_GICD_BASE + + GICD_ISENABLER + 0x10)); + mask->mask5 = mmio_read_32((BASE_GICD_BASE + + GICD_ISENABLER + 0x14)); + mask->mask6 = mmio_read_32((BASE_GICD_BASE + + GICD_ISENABLER + 0x18)); + mask->mask7 = mmio_read_32((BASE_GICD_BASE + + GICD_ISENABLER + 0x1c)); + mask->mask8 = mmio_read_32((BASE_GICD_BASE + + GICD_ISENABLER + 0x20)); + mask->mask9 = mmio_read_32((BASE_GICD_BASE + + GICD_ISENABLER + 0x24)); + mask->mask10 = mmio_read_32((BASE_GICD_BASE + + GICD_ISENABLER + 0x28)); + mask->mask11 = mmio_read_32((BASE_GICD_BASE + + GICD_ISENABLER + 0x2c)); + mask->mask12 = mmio_read_32((BASE_GICD_BASE + + GICD_ISENABLER + 0x30)); + + /* for SPI */ + mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x4), + 0xFFFFFFFF); + mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x8), + 0xFFFFFFFF); + mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0xC), + 0xFFFFFFFF); + mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x10), + 0xFFFFFFFF); + mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x14), + 0xFFFFFFFF); + mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x18), + 0xFFFFFFFF); + mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x1C), + 0xFFFFFFFF); + mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x20), + 0xFFFFFFFF); + mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x24), + 0xFFFFFFFF); + mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x28), + 0xFFFFFFFF); + mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x2c), + 0xFFFFFFFF); + mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x30), + 0xFFFFFFFF); + /* make sure distributor changes happen */ + dsb(); + + mask->header = IRQ_MASK_HEADER; + mask->footer = IRQ_MASK_FOOTER; + + return 0; + } else { + return -1; } - /* make sure all cirq setting take effect before doing other things */ - dmbsy(); } -/* - * mt_cirq_enable: Enable SYS_CIRQ - */ -void mt_cirq_enable(void) +static uint32_t mt_irq_get_pol(uint32_t irq) { - uint32_t st; +#ifdef CIRQ_WITH_POLARITY + uint32_t reg; + uint32_t base = INT_POL_CTL0; - mt_cirq_ack_all(); + if (irq < 32U) { + return 0; + } - st = mt_cirq_read32(CIRQ_CON); - st |= (CIRQ_CON_EN << CIRQ_CON_EN_BITS) | - (CIRQ_CON_EDGE_ONLY << CIRQ_CON_EDGE_ONLY_BITS); + reg = ((irq - 32U) / 32U); - mt_cirq_write32((st & CIRQ_CON_BITS_MASK), CIRQ_CON); + return mmio_read_32(base + reg * 4U); +#else + return 0; +#endif } -/* - * mt_cirq_disable: Disable SYS_CIRQ - */ -void mt_cirq_disable(void) +unsigned int mt_irq_get_sens(unsigned int irq) { - uint32_t st; + unsigned int config; - st = mt_cirq_read32(CIRQ_CON); - st &= ~(CIRQ_CON_EN << CIRQ_CON_EN_BITS); + /* + * 2'b10 edge + * 2'b01 level + */ + config = mmio_read_32(MT_GIC_BASE + GICD_ICFGR + (irq / 16U) * 4U); + config = (config >> (irq % 16U) * 2U) & 0x3; - mt_cirq_write32((st & CIRQ_CON_BITS_MASK), CIRQ_CON); + return config; } -/* - * mt_cirq_get_mask: Get the specified SYS_CIRQ mask - * @cirq_num: the SYS_CIRQ number to get - * @return: - * 1: this cirq is masked - * 0: this cirq is umasked - * 2: cirq num is out of range - */ -__attribute__((weak)) unsigned int mt_cirq_get_mask(uint32_t cirq_num) +static void collect_all_wakeup_events(void) { - uint32_t st; - unsigned int val; - - if (cirq_num >= CIRQ_IRQ_NUM) { - ERROR("[CIRQ] %s: invalid cirq %u\n", __func__, cirq_num); - return 2; + unsigned int i; + uint32_t gic_irq; + uint32_t cirq; + uint32_t cirq_reg; + uint32_t cirq_offset; + uint32_t mask; + uint32_t pol_mask; + uint32_t irq_offset; + uint32_t irq_mask; + + if ((cirq_all_events.wakeup_events == NULL) || + cirq_all_events.num_of_events == 0U) { + return; } - st = mt_cirq_read32((cirq_num / 32U) * 4U + CIRQ_MASK_BASE); - val = (st >> (cirq_num % 32U)) & 1U; - return val; -} - -/* - * mt_cirq_mask_all: Mask all interrupts on SYS_CIRQ. - */ -void mt_cirq_mask_all(void) -{ - unsigned int i; + for (i = 0U; i < cirq_all_events.num_of_events; i++) { + if (cirq_all_events.wakeup_events[i] > 0U) { + gic_irq = cirq_all_events.wakeup_events[i]; + cirq = gic_irq - cirq_all_events.spi_start - 32U; + cirq_reg = cirq / 32U; + cirq_offset = cirq % 32U; + mask = 0x1 << cirq_offset; + irq_offset = gic_irq % 32U; + irq_mask = 0x1 << irq_offset; + /* + * CIRQ default masks all + */ + cirq_all_events.table[cirq_reg].mask |= mask; + /* + * CIRQ default pol is low + */ + pol_mask = mt_irq_get_pol( + cirq_all_events.wakeup_events[i]) + & irq_mask; + /* + * 0 means rising + */ + if (pol_mask == 0U) { + cirq_all_events.table[cirq_reg].pol |= mask; + } + /* + * CIRQ could monitor edge/level trigger + * cirq register (0: edge, 1: level) + */ + if (mt_irq_get_sens(cirq_all_events.wakeup_events[i]) + == SENS_EDGE) { + cirq_all_events.table[cirq_reg].sen |= mask; + } - for (i = 0U; i < CIRQ_CTRL_REG_NUM; i++) { - mt_cirq_write32(0xFFFFFFFF, CIRQ_MASK_SET_BASE + (i * 4U)); + cirq_all_events.table[cirq_reg].used = 1U; + cirq_all_events.table[cirq_reg].reg_num = cirq_reg; + } } - /* make sure all cirq setting take effect before doing other things */ - dmbsy(); } /* - * mt_cirq_unmask_all: Unmask all interrupts on SYS_CIRQ. + * mt_cirq_set_pol: Set the polarity for the specified SYS_CIRQ number. + * @cirq_num: the SYS_CIRQ number to set + * @pol: polarity to set + * @return: + * 0: set pol success + * -1: cirq num is out of range */ -void mt_cirq_unmask_all(void) +#ifdef CIRQ_WITH_POLARITY +static int mt_cirq_set_pol(uint32_t cirq_num, uint32_t pol) { - unsigned int i; + uint32_t base; + uint32_t bit = 1U << (cirq_num % 32U); - for (i = 0U; i < CIRQ_CTRL_REG_NUM; i++) { - mt_cirq_write32(0xFFFFFFFF, CIRQ_MASK_CLR_BASE + (i * 4U)); + if (cirq_num >= CIRQ_IRQ_NUM) { + return -1; + } + + if (pol == MT_CIRQ_POL_NEG) { + base = (cirq_num / 32U) * 4U + CIRQ_POL_CLR_BASE; + } else if (pol == MT_CIRQ_POL_POS) { + base = (cirq_num / 32U) * 4U + CIRQ_POL_SET_BASE; + } else { + return -1; } - /* make sure all cirq setting take effect before doing other things */ - dmbsy(); + + mmio_write_32(base, bit); + return 0; } +#endif /* * mt_cirq_mask: Mask the specified SYS_CIRQ. @@ -151,11 +269,11 @@ static int mt_cirq_mask(uint32_t cirq_num) uint32_t bit = 1U << (cirq_num % 32U); if (cirq_num >= CIRQ_IRQ_NUM) { - ERROR("[CIRQ] %s: invalid cirq %u\n", __func__, cirq_num); return -1; } - mt_cirq_write32(bit, (cirq_num / 32U) * 4U + CIRQ_MASK_SET_BASE); + mmio_write_32((cirq_num / 32U) * 4U + CIRQ_MASK_SET_BASE, bit); + return 0; } @@ -171,324 +289,264 @@ static int mt_cirq_unmask(uint32_t cirq_num) uint32_t bit = 1U << (cirq_num % 32U); if (cirq_num >= CIRQ_IRQ_NUM) { - ERROR("[CIRQ] %s: invalid cirq %u\n", __func__, cirq_num); return -1; } - mt_cirq_write32(bit, (cirq_num / 32U) * 4U + CIRQ_MASK_CLR_BASE); + mmio_write_32((cirq_num / 32U) * 4U + CIRQ_MASK_CLR_BASE, bit); + return 0; } -/* - * mt_cirq_set_sens: Set the sensitivity for the specified SYS_CIRQ number. - * @cirq_num: the SYS_CIRQ number to set - * @sens: sensitivity to set - * @return: - * 0: set sens success - * -1: cirq num is out of range - */ -static int mt_cirq_set_sens(uint32_t cirq_num, uint32_t sens) +uint32_t mt_irq_get_en(uint32_t irq) { - uint32_t base; - uint32_t bit = 1U << (cirq_num % 32U); + uint32_t addr, st, val; - if (cirq_num >= CIRQ_IRQ_NUM) { - ERROR("[CIRQ] %s: invalid cirq %u\n", __func__, cirq_num); - return -1; - } + addr = BASE_GICD_BASE + GICD_ISENABLER + (irq / 32U) * 4U; + st = mmio_read_32(addr); - if (sens == MT_CIRQ_EDGE_SENSITIVE) { - base = (cirq_num / 32U) * 4U + CIRQ_SENS_CLR_BASE; - } else if (sens == MT_CIRQ_LEVEL_SENSITIVE) { - base = (cirq_num / 32U) * 4U + CIRQ_SENS_SET_BASE; - } else { - ERROR("[CIRQ] set_sens invalid sen value %u\n", sens); - return -1; - } + val = (st >> (irq % 32U)) & 1U; - mt_cirq_write32(bit, base); - return 0; + return val; } -/* - * mt_cirq_get_sens: Get the specified SYS_CIRQ sensitivity - * @cirq_num: the SYS_CIRQ number to get - * @return: - * 1: this cirq is MT_LEVEL_SENSITIVE - * 0: this cirq is MT_EDGE_SENSITIVE - * 2: cirq num is out of range - */ -__attribute__((weak)) unsigned int mt_cirq_get_sens(uint32_t cirq_num) +static void __cirq_fast_clone(void) { - uint32_t st; - unsigned int val; + struct cirq_reg *reg; + unsigned int i; - if (cirq_num >= CIRQ_IRQ_NUM) { - ERROR("[CIRQ] %s: invalid cirq %u\n", __func__, cirq_num); - return 2; - } + for (i = 0U; i < CIRQ_REG_NUM ; ++i) { + uint32_t cirq_bit; - st = mt_cirq_read32((cirq_num / 32U) * 4U + CIRQ_SENS_BASE); - val = (st >> (cirq_num % 32U)) & 1U; - return val; -} + reg = &cirq_all_events.table[i]; -/* - * mt_cirq_set_pol: Set the polarity for the specified SYS_CIRQ number. - * @cirq_num: the SYS_CIRQ number to set - * @pol: polarity to set - * @return: - * 0: set pol success - * -1: cirq num is out of range - */ -static int mt_cirq_set_pol(uint32_t cirq_num, uint32_t pol) -{ - uint32_t base; - uint32_t bit = 1U << (cirq_num % 32U); + if (reg->used == 0U) { + continue; + } - if (cirq_num >= CIRQ_IRQ_NUM) { - ERROR("[CIRQ] %s: invalid cirq %u\n", __func__, cirq_num); - return -1; - } + mmio_write_32(CIRQ_SENS_CLR_BASE + (reg->reg_num * 4U), + reg->sen); - if (pol == MT_CIRQ_POL_NEG) { - base = (cirq_num / 32U) * 4U + CIRQ_POL_CLR_BASE; - } else if (pol == MT_CIRQ_POL_POS) { - base = (cirq_num / 32U) * 4U + CIRQ_POL_SET_BASE; - } else { - ERROR("[CIRQ] set_pol invalid polarity value %u\n", pol); - return -1; - } + for (cirq_bit = 0U; cirq_bit < 32U; ++cirq_bit) { + uint32_t val, cirq_id; + uint32_t gic_id; +#ifdef CIRQ_WITH_POLARITY + uint32_t gic_bit, pol; +#endif + uint32_t en; - mt_cirq_write32(bit, base); - return 0; -} + val = ((1U << cirq_bit) & reg->mask); -/* - * mt_cirq_get_pol: Get the specified SYS_CIRQ polarity - * @cirq_num: the SYS_CIRQ number to get - * @return: - * 1: this cirq is MT_CIRQ_POL_POS - * 0: this cirq is MT_CIRQ_POL_NEG - * 2: cirq num is out of range - */ -__attribute__((weak)) unsigned int mt_cirq_get_pol(uint32_t cirq_num) -{ - uint32_t st; - unsigned int val; + if (val == 0U) { + continue; + } - if (cirq_num >= CIRQ_IRQ_NUM) { - ERROR("[CIRQ] %s: invalid cirq %u\n", __func__, cirq_num); - return 2; + cirq_id = (reg->reg_num << 5U) + cirq_bit; + gic_id = CIRQ_TO_IRQ_NUM(cirq_id); +#ifdef CIRQ_WITH_POLARITY + gic_bit = (0x1U << ((gic_id - 32U) % 32U)); + pol = mt_irq_get_pol(gic_id) & gic_bit; + if (pol != 0U) { + mt_cirq_set_pol(cirq_id, MT_CIRQ_POL_NEG); + } else { + mt_cirq_set_pol(cirq_id, MT_CIRQ_POL_POS); + } +#endif + en = mt_irq_get_en(gic_id); + if (en == 1U) { + mt_cirq_unmask(cirq_id); + } else { + mt_cirq_mask(cirq_id); + } + } } +} - st = mt_cirq_read32((cirq_num / 32U) * 4U + CIRQ_POL_BASE); - val = (st >> (cirq_num % 32U)) & 1U; - return val; +static void cirq_fast_clone(void) +{ + if (already_cloned == 0U) { + collect_all_wakeup_events(); + already_cloned = 1U; + } + __cirq_fast_clone(); } +void set_wakeup_sources(uint32_t *list, uint32_t num_of_events) +{ + cirq_all_events.num_of_events = num_of_events; + cirq_all_events.wakeup_events = list; +} /* - * mt_cirq_get_pending: Get the specified SYS_CIRQ pending - * @cirq_num: the SYS_CIRQ number to get - * @return: - * 1: this cirq is pending - * 0: this cirq is not pending - * 2: cirq num is out of range + * mt_cirq_clone_gic: Copy the setting from GIC to SYS_CIRQ */ -static unsigned int mt_cirq_get_pending(uint32_t cirq_num) +void mt_cirq_clone_gic(void) { - uint32_t st; - unsigned int val; + cirq_fast_clone(); +} - if (cirq_num >= CIRQ_IRQ_NUM) { - ERROR("[CIRQ] %s: invalid cirq %u\n", __func__, cirq_num); - return 2; +uint32_t mt_irq_get_pending_vec(uint32_t start_irq) +{ + uint32_t base = 0U; + uint32_t pending_vec = 0U; + uint32_t reg = start_irq / 32U; + uint32_t LSB_num, MSB_num; + uint32_t LSB_vec, MSB_vec; + + base = BASE_GICD_BASE; + + /* if start_irq is not aligned 32, do some assembling */ + MSB_num = start_irq % 32U; + if (MSB_num != 0U) { + LSB_num = 32U - MSB_num; + LSB_vec = mmio_read_32(base + GICD_ISPENDR + + reg * 4U) >> MSB_num; + MSB_vec = mmio_read_32(base + GICD_ISPENDR + + (reg + 1U) * 4U) << LSB_num; + pending_vec = MSB_vec | LSB_vec; + } else { + pending_vec = mmio_read_32(base + GICD_ISPENDR + reg * 4); } - st = mt_cirq_read32((cirq_num / 32U) * 4U + CIRQ_STA_BASE); - val = (st >> (cirq_num % 32U)) & 1U; - return val; + return pending_vec; +} + +static int mt_cirq_get_mask_vec(unsigned int i) +{ + return mmio_read_32((i * 4U) + CIRQ_MASK_BASE); } /* - * mt_cirq_clone_pol: Copy the polarity setting from GIC to SYS_CIRQ + * mt_cirq_ack_all: Ack all the interrupt on SYS_CIRQ */ -void mt_cirq_clone_pol(void) +void mt_cirq_ack_all(void) { - uint32_t cirq_num; + uint32_t ack_vec, pend_vec, mask_vec; + unsigned int i; - for (cirq_num = 0U; cirq_num < CIRQ_IRQ_NUM; cirq_num++) { - mt_cirq_set_pol(cirq_num, MT_CIRQ_POL_POS); + for (i = 0; i < CIRQ_CTRL_REG_NUM; i++) { + /* + * if a irq is pending & not masked, don't ack it + * , since cirq start irq might not be 32 aligned with gic, + * need an exotic API to get proper vector of pending irq + */ + pend_vec = mt_irq_get_pending_vec(CIRQ_SPI_START + + (i + 1U) * 32U); + mask_vec = mt_cirq_get_mask_vec(i); + /* those should be acked are: "not (pending & not masked)", + */ + ack_vec = (~pend_vec) | mask_vec; + mmio_write_32(CIRQ_ACK_BASE + (i * 4U), ack_vec); } -} + /* + * make sure all cirq setting take effect + * before doing other things + */ + dsb(); +} /* - * mt_cirq_clone_sens: Copy the sensitivity setting from GIC to SYS_CIRQ + * mt_cirq_enable: Enable SYS_CIRQ */ -void mt_cirq_clone_sens(void) +void mt_cirq_enable(void) { - uint32_t cirq_num, irq_num; - uint32_t st, val; - - for (cirq_num = 0U; cirq_num < CIRQ_IRQ_NUM; cirq_num++) { - irq_num = CIRQ_TO_IRQ_NUM(cirq_num); + uint32_t st; - if ((cirq_num == 0U) || (irq_num % 16U == 0U)) { - st = mmio_read_32(BASE_GICD_BASE + GICD_ICFGR + - (irq_num / 16U * 4U)); - } + /* level only */ + mt_cirq_ack_all(); - val = (st >> ((irq_num % 16U) * 2U)) & 0x2U; + st = mmio_read_32(CIRQ_CON); + /* + * CIRQ could monitor edge/level trigger + */ + st |= (CIRQ_CON_EN << CIRQ_CON_EN_BITS); - if (val) { - mt_cirq_set_sens(cirq_num, MT_CIRQ_EDGE_SENSITIVE); - } else { - mt_cirq_set_sens(cirq_num, MT_CIRQ_LEVEL_SENSITIVE); - } - } + mmio_write_32(CIRQ_CON, (st & CIRQ_CON_BITS_MASK)); } /* - * mt_cirq_clone_mask: Copy the mask setting from GIC to SYS_CIRQ + * mt_cirq_disable: Disable SYS_CIRQ */ -void mt_cirq_clone_mask(void) +void mt_cirq_disable(void) { - uint32_t cirq_num, irq_num; - uint32_t st, val; + uint32_t st; - for (cirq_num = 0U; cirq_num < CIRQ_IRQ_NUM; cirq_num++) { - irq_num = CIRQ_TO_IRQ_NUM(cirq_num); + st = mmio_read_32(CIRQ_CON); + st &= ~(CIRQ_CON_EN << CIRQ_CON_EN_BITS); + mmio_write_32(CIRQ_CON, (st & CIRQ_CON_BITS_MASK)); +} - if ((cirq_num == 0U) || (irq_num % 32U == 0U)) { - st = mmio_read_32(BASE_GICD_BASE + - GICD_ISENABLER + (irq_num / 32U * 4U)); - } +void mt_irq_unmask_for_sleep_ex(uint32_t irq) +{ + uint32_t mask; - val = (st >> (irq_num % 32)) & 1U; + mask = 1U << (irq % 32U); - if (val) { - mt_cirq_unmask(cirq_num); - } else { - mt_cirq_mask(cirq_num); - } - } + mmio_write_32(BASE_GICD_BASE + GICD_ISENABLER + + ((irq / 32U) * 4U), mask); } -/* - * mt_cirq_clone_gic: Copy the setting from GIC to SYS_CIRQ - */ -void mt_cirq_clone_gic(void) +void mt_cirq_mask_all(void) { - mt_cirq_clone_sens(); - mt_cirq_clone_mask(); + unsigned int i; + + for (i = 0U; i < CIRQ_CTRL_REG_NUM; i++) { + mmio_write_32(CIRQ_MASK_SET_BASE + (i * 4U), 0xFFFFFFFF); + } + dsb(); } -/* - * mt_cirq_disable: Flush interrupt from SYS_CIRQ to GIC - */ -void mt_cirq_flush(void) +static void cirq_fast_sw_flush(void) { + struct cirq_reg *reg; unsigned int i; - unsigned char cirq_p_val = 0U; - unsigned char irq_p_val = 0U; - uint32_t irq_p = 0U; - unsigned char pass = 1U; - uint32_t first_cirq_found = 0U; - uint32_t first_flushed_cirq; - uint32_t first_irq_flushedto; - uint32_t last_fluashed_cirq; - uint32_t last_irq_flushedto; - - if (cirq_pattern_clone_flush_check_val == 1U) { - if (cirq_pattern_list < CIRQ_IRQ_NUM) { - mt_cirq_unmask(cirq_pattern_list); - mt_cirq_set_sens(cirq_pattern_list, - MT_CIRQ_EDGE_SENSITIVE); - mt_cirq_set_pol(cirq_pattern_list, MT_CIRQ_POL_NEG); - mt_cirq_set_pol(cirq_pattern_list, MT_CIRQ_POL_POS); - mt_cirq_set_pol(cirq_pattern_list, MT_CIRQ_POL_NEG); - } else { - ERROR("[CIRQ] no pattern to test,"); - ERROR("input pattern first\n"); - } - ERROR("[CIRQ] cirq_pattern %u, cirq_p %u,", - cirq_pattern_list, - mt_cirq_get_pending(cirq_pattern_list)); - ERROR("cirq_s %u, cirq_con 0x%x\n", - mt_cirq_get_sens(cirq_pattern_list), - mt_cirq_read32(CIRQ_CON)); - } - mt_cirq_unmask_all(); + for (i = 0U; i < CIRQ_REG_NUM ; ++i) { + uint32_t cirq_bit; - for (i = 0U; i < CIRQ_IRQ_NUM; i++) { - cirq_p_val = mt_cirq_get_pending(i); - if (cirq_p_val) { - mt_irq_set_pending(CIRQ_TO_IRQ_NUM(i)); + reg = &cirq_all_events.table[i]; + + if (reg->used == 0U) { + continue; } - if (cirq_clone_flush_check_val == 1U) { - if (cirq_p_val == 0U) { + reg->pending = mmio_read_32(CIRQ_STA_BASE + + (reg->reg_num << 2U)); + reg->pending &= reg->mask; + + for (cirq_bit = 0U; cirq_bit < 32U; ++cirq_bit) { + uint32_t val, cirq_id; + + val = (1U << cirq_bit) & reg->pending; + if (val == 0U) { continue; - } - irq_p = CIRQ_TO_IRQ_NUM(i); - irq_p_val = mt_irq_get_pending(irq_p); - if (cirq_p_val != irq_p_val) { - ERROR("[CIRQ] CIRQ Flush Failed "); - ERROR("%u(cirq %d)!= %u(gic %d)\n", - cirq_p_val, i, irq_p_val, - CIRQ_TO_IRQ_NUM(i)); - pass = 0; - } else { - ERROR("[CIRQ] CIRQ Flush Pass "); - ERROR("%u(cirq %d) = %u(gic %d)\n", - cirq_p_val, i, irq_p_val, - CIRQ_TO_IRQ_NUM(i)); } - if (!first_cirq_found) { - first_flushed_cirq = i; - first_irq_flushedto = irq_p; - first_cirq_found = 1U; + + cirq_id = (reg->reg_num << 5U) + cirq_bit; + mt_irq_set_pending(CIRQ_TO_IRQ_NUM(cirq_id)); + if (CIRQ_TO_IRQ_NUM(cirq_id) == MD_WDT_IRQ_BIT_ID) { + INFO("Set MD_WDT_IRQ pending in %s\n", + __func__); } - last_fluashed_cirq = i; - last_irq_flushedto = irq_p; } } +} - if (cirq_clone_flush_check_val == 1U) { - if (first_cirq_found) { - ERROR("[CIRQ] The first flush : CIRQ%u to IRQ%u\n", - first_flushed_cirq, first_irq_flushedto); - ERROR("[CIRQ] The last flush : CIRQ%u to IRQ%u\n", - last_fluashed_cirq, last_irq_flushedto); - } else { - ERROR("[CIRQ] There are no pending "); - ERROR("interrupt in CIRQ\n"); - ERROR("[CIRQ] so no flush operation happened\n"); - } - ERROR("[CIRQ] The Flush Max Range : CIRQ"); - ERROR("%d to IRQ%d ~ CIRQ%d to IRQ%d\n", 0U, - CIRQ_TO_IRQ_NUM(0U), CIRQ_IRQ_NUM - 1U, - CIRQ_TO_IRQ_NUM(CIRQ_IRQ_NUM - 1U)); - ERROR("[CIRQ] Flush Check %s, Confirm:SPI_START_OFFSET:%d\n", - pass == 1 ? "Pass" : "Failed", CIRQ_SPI_START); - } +/* + * mt_cirq_disable: Flush interrupt from SYS_CIRQ to GIC + */ +void mt_cirq_flush(void) +{ + cirq_fast_sw_flush(); mt_cirq_mask_all(); mt_cirq_ack_all(); } void mt_cirq_sw_reset(void) { +#ifdef CIRQ_NEED_SW_RESET uint32_t st; - st = mt_cirq_read32(CIRQ_CON); + st = mmio_read_32(CIRQ_CON); st |= (CIRQ_SW_RESET << CIRQ_CON_SW_RST_BITS); - - mt_cirq_write32(st, CIRQ_CON); -} - -void set_wakeup_sources(uint32_t *list, uint32_t num_of_events) -{ - cirq_all_events.num_of_events = num_of_events; - cirq_all_events.wakeup_events = list; + mmio_write_32(CIRQ_CON, st); +#endif } -- cgit v1.2.3 From bb28dc7aeaf4207eeaa8b1aca8b8e10e135a1829 Mon Sep 17 00:00:00 2001 From: Yuchen Huang Date: Sat, 1 Aug 2020 16:23:12 +0800 Subject: mediatek: mt8192: add uart save and restore api When system resume, we want to print log as soon as possible. So we add uart save and restore api, and they will be called when systtem suspend and resume. Change-Id: I83b477fd2b39567c9c6b70534ef186993f7053ae Signed-off-by: Yuchen Huang Signed-off-by: Roger Lu --- plat/mediatek/common/drivers/uart/uart.c | 112 ++++++++++++++++++++++++++++ plat/mediatek/mt8183/drivers/uart/uart.c | 111 --------------------------- plat/mediatek/mt8183/drivers/uart/uart.h | 2 +- plat/mediatek/mt8183/platform.mk | 2 +- plat/mediatek/mt8192/drivers/uart/uart.h | 100 +++++++++++++++++++++++++ plat/mediatek/mt8192/include/platform_def.h | 1 + plat/mediatek/mt8192/platform.mk | 4 +- 7 files changed, 218 insertions(+), 114 deletions(-) create mode 100644 plat/mediatek/common/drivers/uart/uart.c delete mode 100644 plat/mediatek/mt8183/drivers/uart/uart.c create mode 100644 plat/mediatek/mt8192/drivers/uart/uart.h diff --git a/plat/mediatek/common/drivers/uart/uart.c b/plat/mediatek/common/drivers/uart/uart.c new file mode 100644 index 000000000..b940eb339 --- /dev/null +++ b/plat/mediatek/common/drivers/uart/uart.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +static struct mt_uart uart_save_addr[DRV_SUPPORT_UART_PORTS]; + +static const uint32_t uart_base_addr[DRV_SUPPORT_UART_PORTS] = { + UART0_BASE, + UART1_BASE +}; + +void mt_uart_restore(void) +{ + int uart_idx = UART_PORT0; + struct mt_uart *uart; + unsigned long base; + + /* Must NOT print any debug log before UART restore */ + for (uart_idx = UART_PORT0; uart_idx < HW_SUPPORT_UART_PORTS; + uart_idx++) { + + uart = &uart_save_addr[uart_idx]; + base = uart->base; + + mmio_write_32(UART_LCR(base), UART_LCR_MODE_B); + mmio_write_32(UART_EFR(base), uart->registers.efr); + mmio_write_32(UART_LCR(base), uart->registers.lcr); + mmio_write_32(UART_FCR(base), uart->registers.fcr); + + /* baudrate */ + mmio_write_32(UART_HIGHSPEED(base), uart->registers.highspeed); + mmio_write_32(UART_FRACDIV_L(base), uart->registers.fracdiv_l); + mmio_write_32(UART_FRACDIV_M(base), uart->registers.fracdiv_m); + mmio_write_32(UART_LCR(base), + uart->registers.lcr | UART_LCR_DLAB); + mmio_write_32(UART_DLL(base), uart->registers.dll); + mmio_write_32(UART_DLH(base), uart->registers.dlh); + mmio_write_32(UART_LCR(base), uart->registers.lcr); + mmio_write_32(UART_SAMPLE_COUNT(base), + uart->registers.sample_count); + mmio_write_32(UART_SAMPLE_POINT(base), + uart->registers.sample_point); + mmio_write_32(UART_GUARD(base), uart->registers.guard); + + /* flow control */ + mmio_write_32(UART_ESCAPE_EN(base), uart->registers.escape_en); + mmio_write_32(UART_MCR(base), uart->registers.mcr); + mmio_write_32(UART_IER(base), uart->registers.ier); + mmio_write_32(UART_SCR(base), uart->registers.scr); + } +} + +void mt_uart_save(void) +{ + int uart_idx = UART_PORT0; + struct mt_uart *uart; + unsigned long base; + + for (uart_idx = UART_PORT0; uart_idx < HW_SUPPORT_UART_PORTS; + uart_idx++) { + + uart_save_addr[uart_idx].base = uart_base_addr[uart_idx]; + base = uart_base_addr[uart_idx]; + uart = &uart_save_addr[uart_idx]; + uart->registers.lcr = mmio_read_32(UART_LCR(base)); + + mmio_write_32(UART_LCR(base), UART_LCR_MODE_B); + uart->registers.efr = mmio_read_32(UART_EFR(base)); + mmio_write_32(UART_LCR(base), uart->registers.lcr); + uart->registers.fcr = mmio_read_32(UART_FCR_RD(base)); + + /* baudrate */ + uart->registers.highspeed = mmio_read_32(UART_HIGHSPEED(base)); + uart->registers.fracdiv_l = mmio_read_32(UART_FRACDIV_L(base)); + uart->registers.fracdiv_m = mmio_read_32(UART_FRACDIV_M(base)); + mmio_write_32(UART_LCR(base), + uart->registers.lcr | UART_LCR_DLAB); + uart->registers.dll = mmio_read_32(UART_DLL(base)); + uart->registers.dlh = mmio_read_32(UART_DLH(base)); + mmio_write_32(UART_LCR(base), uart->registers.lcr); + uart->registers.sample_count = mmio_read_32( + UART_SAMPLE_COUNT(base)); + uart->registers.sample_point = mmio_read_32( + UART_SAMPLE_POINT(base)); + uart->registers.guard = mmio_read_32(UART_GUARD(base)); + + /* flow control */ + uart->registers.escape_en = mmio_read_32(UART_ESCAPE_EN(base)); + uart->registers.mcr = mmio_read_32(UART_MCR(base)); + uart->registers.ier = mmio_read_32(UART_IER(base)); + uart->registers.scr = mmio_read_32(UART_SCR(base)); + } +} + +void mt_console_uart_cg(int on) +{ + if (on == 1) { + mmio_write_32(UART_CLOCK_GATE_CLR, UART0_CLOCK_GATE_BIT); + } else { + mmio_write_32(UART_CLOCK_GATE_SET, UART0_CLOCK_GATE_BIT); + } +} + +uint32_t mt_console_uart_cg_status(void) +{ + return mmio_read_32(UART_CLOCK_GATE_STA) & UART0_CLOCK_GATE_BIT; +} diff --git a/plat/mediatek/mt8183/drivers/uart/uart.c b/plat/mediatek/mt8183/drivers/uart/uart.c deleted file mode 100644 index 3c6a98036..000000000 --- a/plat/mediatek/mt8183/drivers/uart/uart.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include - -static struct mt_uart uart_save_addr[DRV_SUPPORT_UART_PORTS]; - -static const unsigned int uart_base_addr[DRV_SUPPORT_UART_PORTS] = { - UART0_BASE, - UART1_BASE -}; - -void mt_uart_restore(void) -{ - int uart_idx = UART_PORT0; - struct mt_uart *uart; - unsigned long base; - - /* Must NOT print any debug log before UART restore */ - for (uart_idx = UART_PORT0; uart_idx < HW_SUPPORT_UART_PORTS; - uart_idx++) { - - uart = &uart_save_addr[uart_idx]; - base = uart->base; - - mmio_write_32(UART_LCR(base), UART_LCR_MODE_B); - mmio_write_32(UART_EFR(base), uart->registers.efr); - mmio_write_32(UART_LCR(base), uart->registers.lcr); - mmio_write_32(UART_FCR(base), uart->registers.fcr); - - /* baudrate */ - mmio_write_32(UART_HIGHSPEED(base), uart->registers.highspeed); - mmio_write_32(UART_FRACDIV_L(base), uart->registers.fracdiv_l); - mmio_write_32(UART_FRACDIV_M(base), uart->registers.fracdiv_m); - mmio_write_32(UART_LCR(base), - uart->registers.lcr | UART_LCR_DLAB); - mmio_write_32(UART_DLL(base), uart->registers.dll); - mmio_write_32(UART_DLH(base), uart->registers.dlh); - mmio_write_32(UART_LCR(base), uart->registers.lcr); - mmio_write_32(UART_SAMPLE_COUNT(base), - uart->registers.sample_count); - mmio_write_32(UART_SAMPLE_POINT(base), - uart->registers.sample_point); - mmio_write_32(UART_GUARD(base), uart->registers.guard); - - /* flow control */ - mmio_write_32(UART_ESCAPE_EN(base), uart->registers.escape_en); - mmio_write_32(UART_MCR(base), uart->registers.mcr); - mmio_write_32(UART_IER(base), uart->registers.ier); - mmio_write_32(UART_SCR(base), uart->registers.scr); - } -} - -void mt_uart_save(void) -{ - int uart_idx = UART_PORT0; - struct mt_uart *uart; - unsigned long base; - - for (uart_idx = UART_PORT0; uart_idx < HW_SUPPORT_UART_PORTS; - uart_idx++) { - - uart_save_addr[uart_idx].base = uart_base_addr[uart_idx]; - base = uart_base_addr[uart_idx]; - uart = &uart_save_addr[uart_idx]; - uart->registers.lcr = mmio_read_32(UART_LCR(base)); - - mmio_write_32(UART_LCR(base), UART_LCR_MODE_B); - uart->registers.efr = mmio_read_32(UART_EFR(base)); - mmio_write_32(UART_LCR(base), uart->registers.lcr); - uart->registers.fcr = mmio_read_32(UART_FCR_RD(base)); - - /* baudrate */ - uart->registers.highspeed = mmio_read_32(UART_HIGHSPEED(base)); - uart->registers.fracdiv_l = mmio_read_32(UART_FRACDIV_L(base)); - uart->registers.fracdiv_m = mmio_read_32(UART_FRACDIV_M(base)); - mmio_write_32(UART_LCR(base), - uart->registers.lcr | UART_LCR_DLAB); - uart->registers.dll = mmio_read_32(UART_DLL(base)); - uart->registers.dlh = mmio_read_32(UART_DLH(base)); - mmio_write_32(UART_LCR(base), uart->registers.lcr); - uart->registers.sample_count = mmio_read_32( - UART_SAMPLE_COUNT(base)); - uart->registers.sample_point = mmio_read_32( - UART_SAMPLE_POINT(base)); - uart->registers.guard = mmio_read_32(UART_GUARD(base)); - - /* flow control */ - uart->registers.escape_en = mmio_read_32(UART_ESCAPE_EN(base)); - uart->registers.mcr = mmio_read_32(UART_MCR(base)); - uart->registers.ier = mmio_read_32(UART_IER(base)); - uart->registers.scr = mmio_read_32(UART_SCR(base)); - } -} - -void mt_console_uart_cg(int on) -{ - if (on) - mmio_write_32(UART_CLOCK_GATE_CLR, UART0_CLOCK_GATE_BIT); - else - mmio_write_32(UART_CLOCK_GATE_SET, UART0_CLOCK_GATE_BIT); -} - -int mt_console_uart_cg_status(void) -{ - return mmio_read_32(UART_CLOCK_GATE_STA) & UART0_CLOCK_GATE_BIT; -} diff --git a/plat/mediatek/mt8183/drivers/uart/uart.h b/plat/mediatek/mt8183/drivers/uart/uart.h index be04c3509..062ce3adc 100644 --- a/plat/mediatek/mt8183/drivers/uart/uart.h +++ b/plat/mediatek/mt8183/drivers/uart/uart.h @@ -95,6 +95,6 @@ struct mt_uart { void mt_uart_save(void); void mt_uart_restore(void); void mt_console_uart_cg(int on); -int mt_console_uart_cg_status(void); +uint32_t mt_console_uart_cg_status(void); #endif /* __UART_H__ */ diff --git a/plat/mediatek/mt8183/platform.mk b/plat/mediatek/mt8183/platform.mk index f290a4e6d..07da1afac 100644 --- a/plat/mediatek/mt8183/platform.mk +++ b/plat/mediatek/mt8183/platform.mk @@ -45,6 +45,7 @@ BL31_SOURCES += common/desc_image_load.c \ ${MTK_PLAT}/common/mtk_plat_common.c \ ${MTK_PLAT}/common/drivers/pmic_wrap/pmic_wrap_init.c \ ${MTK_PLAT}/common/drivers/rtc/rtc_common.c \ + ${MTK_PLAT}/common/drivers/uart/uart.c \ ${MTK_PLAT}/common/params_setup.c \ ${MTK_PLAT_SOC}/aarch64/plat_helpers.S \ ${MTK_PLAT_SOC}/aarch64/platform_common.c \ @@ -58,7 +59,6 @@ BL31_SOURCES += common/desc_image_load.c \ ${MTK_PLAT_SOC}/drivers/spm/spm_pmic_wrap.c \ ${MTK_PLAT_SOC}/drivers/spm/spm_suspend.c \ ${MTK_PLAT_SOC}/drivers/gpio/mtgpio.c \ - ${MTK_PLAT_SOC}/drivers/uart/uart.c \ ${MTK_PLAT_SOC}/drivers/timer/mt_timer.c \ ${MTK_PLAT_SOC}/drivers/emi_mpu/emi_mpu.c \ ${MTK_PLAT_SOC}/plat_pm.c \ diff --git a/plat/mediatek/mt8192/drivers/uart/uart.h b/plat/mediatek/mt8192/drivers/uart/uart.h new file mode 100644 index 000000000..ac8b94dd1 --- /dev/null +++ b/plat/mediatek/mt8192/drivers/uart/uart.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef UART_H +#define UART_H + +#include + +/* UART HW information */ +#define HW_SUPPORT_UART_PORTS 2 +#define DRV_SUPPORT_UART_PORTS 2 + +/* console UART clock cg */ +#define UART_CLOCK_GATE_SET (INFRACFG_AO_BASE + 0x80) +#define UART_CLOCK_GATE_CLR (INFRACFG_AO_BASE + 0x84) +#define UART_CLOCK_GATE_STA (INFRACFG_AO_BASE + 0x90) +#define UART0_CLOCK_GATE_BIT (1U<<22) +#define UART1_CLOCK_GATE_BIT (1U<<23) + +/* UART registers */ +#define UART_RBR(_baseaddr) (_baseaddr + 0x0) +#define UART_THR(_baseaddr) (_baseaddr + 0x0) +#define UART_IER(_baseaddr) (_baseaddr + 0x4) +#define UART_IIR(_baseaddr) (_baseaddr + 0x8) +#define UART_FCR(_baseaddr) (_baseaddr + 0x8) +#define UART_LCR(_baseaddr) (_baseaddr + 0xc) +#define UART_MCR(_baseaddr) (_baseaddr + 0x10) +#define UART_LSR(_baseaddr) (_baseaddr + 0x14) +#define UART_MSR(_baseaddr) (_baseaddr + 0x18) +#define UART_SCR(_baseaddr) (_baseaddr + 0x1c) +#define UART_DLL(_baseaddr) (_baseaddr + 0x0) +#define UART_DLH(_baseaddr) (_baseaddr + 0x4) +#define UART_EFR(_baseaddr) (_baseaddr + 0x8) +#define UART_XON1(_baseaddr) (_baseaddr + 0x10) +#define UART_XON2(_baseaddr) (_baseaddr + 0x14) +#define UART_XOFF1(_baseaddr) (_baseaddr + 0x18) +#define UART_XOFF2(_baseaddr) (_baseaddr + 0x1c) +#define UART_AUTOBAUD(_baseaddr) (_baseaddr + 0x20) +#define UART_HIGHSPEED(_baseaddr) (_baseaddr + 0x24) +#define UART_SAMPLE_COUNT(_baseaddr) (_baseaddr + 0x28) +#define UART_SAMPLE_POINT(_baseaddr) (_baseaddr + 0x2c) +#define UART_AUTOBAUD_REG(_baseaddr) (_baseaddr + 0x30) +#define UART_RATE_FIX_REG(_baseaddr) (_baseaddr + 0x34) +#define UART_AUTO_BAUDSAMPLE(_baseaddr) (_baseaddr + 0x38) +#define UART_GUARD(_baseaddr) (_baseaddr + 0x3c) +#define UART_ESCAPE_DAT(_baseaddr) (_baseaddr + 0x40) +#define UART_ESCAPE_EN(_baseaddr) (_baseaddr + 0x44) +#define UART_SLEEP_EN(_baseaddr) (_baseaddr + 0x48) +#define UART_DMA_EN(_baseaddr) (_baseaddr + 0x4c) +#define UART_RXTRI_AD(_baseaddr) (_baseaddr + 0x50) +#define UART_FRACDIV_L(_baseaddr) (_baseaddr + 0x54) +#define UART_FRACDIV_M(_baseaddr) (_baseaddr + 0x58) +#define UART_FCR_RD(_baseaddr) (_baseaddr + 0x5C) +#define UART_USB_RX_SEL(_baseaddr) (_baseaddr + 0xB0) +#define UART_SLEEP_REQ(_baseaddr) (_baseaddr + 0xB4) +#define UART_SLEEP_ACK(_baseaddr) (_baseaddr + 0xB8) +#define UART_SPM_SEL(_baseaddr) (_baseaddr + 0xBC) +#define UART_LCR_DLAB 0x0080 +#define UART_LCR_MODE_B 0x00bf + +enum uart_port_ID { + UART_PORT0 = 0, + UART_PORT1 +}; + +struct mt_uart_register { + uint32_t dll; + uint32_t dlh; + uint32_t ier; + uint32_t lcr; + uint32_t mcr; + uint32_t fcr; + uint32_t lsr; + uint32_t scr; + uint32_t efr; + uint32_t highspeed; + uint32_t sample_count; + uint32_t sample_point; + uint32_t fracdiv_l; + uint32_t fracdiv_m; + uint32_t escape_en; + uint32_t guard; + uint32_t rx_sel; +}; + +struct mt_uart { + unsigned long base; + struct mt_uart_register registers; +}; + +/* external API */ +void mt_uart_save(void); +void mt_uart_restore(void); +void mt_console_uart_cg(int on); +uint32_t mt_console_uart_cg_status(void); + +#endif /* __UART_H__ */ diff --git a/plat/mediatek/mt8192/include/platform_def.h b/plat/mediatek/mt8192/include/platform_def.h index a3ab1a0ca..51cf36136 100644 --- a/plat/mediatek/mt8192/include/platform_def.h +++ b/plat/mediatek/mt8192/include/platform_def.h @@ -26,6 +26,7 @@ #define MTK_MCDI_SRAM_BASE 0x11B000 #define MTK_MCDI_SRAM_MAP_SIZE 0x1000 +#define INFRACFG_AO_BASE (IO_PHYS + 0x00001000) #define GPIO_BASE (IO_PHYS + 0x00005000) #define SPM_BASE (IO_PHYS + 0x00006000) #define PMIC_WRAP_BASE (IO_PHYS + 0x00026000) diff --git a/plat/mediatek/mt8192/platform.mk b/plat/mediatek/mt8192/platform.mk index 01851effc..3e23e05cd 100644 --- a/plat/mediatek/mt8192/platform.mk +++ b/plat/mediatek/mt8192/platform.mk @@ -14,7 +14,8 @@ PLAT_INCLUDES := -I${MTK_PLAT}/common/ \ -I${MTK_PLAT_SOC}/drivers/mcdi/ \ -I${MTK_PLAT_SOC}/drivers/pmic/ \ -I${MTK_PLAT_SOC}/drivers/spmc/ \ - -I${MTK_PLAT_SOC}/drivers/timer/ + -I${MTK_PLAT_SOC}/drivers/timer/ \ + -I${MTK_PLAT_SOC}/drivers/uart/ GICV3_SUPPORT_GIC600 := 1 include drivers/arm/gic/v3/gicv3.mk @@ -35,6 +36,7 @@ BL31_SOURCES += common/desc_image_load.c \ lib/cpus/aarch64/cortex_a76.S \ plat/common/plat_gicv3.c \ ${MTK_PLAT}/common/drivers/pmic_wrap/pmic_wrap_init_v2.c \ + ${MTK_PLAT}/common/drivers/uart/uart.c \ ${MTK_PLAT}/common/mtk_plat_common.c \ ${MTK_PLAT}/common/params_setup.c \ ${MTK_PLAT_SOC}/aarch64/platform_common.c \ -- cgit v1.2.3 From 189f038f55a1a2472b613e160eeb791e11b7c486 Mon Sep 17 00:00:00 2001 From: Nina Wu Date: Wed, 19 Aug 2020 17:20:15 +0800 Subject: mediatek: mt8192: Add SiP service Add the basic SiP service Change-Id: Ib7f2380aab910adf8d33498a79ecd287273907c5 Signed-off-by: Nina Wu --- plat/mediatek/mt8192/include/plat_sip_calls.h | 15 +++++++++++++++ plat/mediatek/mt8192/plat_sip_calls.c | 27 +++++++++++++++++++++++++++ plat/mediatek/mt8192/platform.mk | 2 ++ 3 files changed, 44 insertions(+) create mode 100644 plat/mediatek/mt8192/include/plat_sip_calls.h create mode 100644 plat/mediatek/mt8192/plat_sip_calls.c diff --git a/plat/mediatek/mt8192/include/plat_sip_calls.h b/plat/mediatek/mt8192/include/plat_sip_calls.h new file mode 100644 index 000000000..0e423225c --- /dev/null +++ b/plat/mediatek/mt8192/include/plat_sip_calls.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLAT_SIP_CALLS_H +#define PLAT_SIP_CALLS_H + +/******************************************************************************* + * Plat SiP function constants + ******************************************************************************/ +#define MTK_PLAT_SIP_NUM_CALLS 0 + +#endif /* PLAT_SIP_CALLS_H */ diff --git a/plat/mediatek/mt8192/plat_sip_calls.c b/plat/mediatek/mt8192/plat_sip_calls.c new file mode 100644 index 000000000..f97684f77 --- /dev/null +++ b/plat/mediatek/mt8192/plat_sip_calls.c @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +uintptr_t mediatek_plat_sip_handler(uint32_t smc_fid, + u_register_t x1, + u_register_t x2, + u_register_t x3, + u_register_t x4, + void *cookie, + void *handle, + u_register_t flags) +{ + + switch (smc_fid) { + default: + ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid); + break; + } + + SMC_RET1(handle, SMC_UNK); +} diff --git a/plat/mediatek/mt8192/platform.mk b/plat/mediatek/mt8192/platform.mk index 3e23e05cd..3ada52939 100644 --- a/plat/mediatek/mt8192/platform.mk +++ b/plat/mediatek/mt8192/platform.mk @@ -38,6 +38,7 @@ BL31_SOURCES += common/desc_image_load.c \ ${MTK_PLAT}/common/drivers/pmic_wrap/pmic_wrap_init_v2.c \ ${MTK_PLAT}/common/drivers/uart/uart.c \ ${MTK_PLAT}/common/mtk_plat_common.c \ + ${MTK_PLAT}/common/mtk_sip_svc.c \ ${MTK_PLAT}/common/params_setup.c \ ${MTK_PLAT_SOC}/aarch64/platform_common.c \ ${MTK_PLAT_SOC}/aarch64/plat_helpers.S \ @@ -47,6 +48,7 @@ BL31_SOURCES += common/desc_image_load.c \ ${MTK_PLAT_SOC}/plat_topology.c \ ${MTK_PLAT_SOC}/plat_mt_gic.c \ ${MTK_PLAT_SOC}/plat_mt_cirq.c \ + ${MTK_PLAT_SOC}/plat_sip_calls.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 8709c939d8df7f3c0eea4a790ade76fc97678ec2 Mon Sep 17 00:00:00 2001 From: "elly.chiang" Date: Tue, 25 Aug 2020 22:31:14 +0800 Subject: mediatek: mt8192: add ptp3 driver enable PTP3 for protecting sysPi Signed-off-by: elly.chiang Change-Id: Ic3a13c8314f829dca8547861b98639d1d9444eb2 --- .../mediatek/mt8192/drivers/ptp3/mtk_ptp3_common.h | 48 ++++++++++++ plat/mediatek/mt8192/drivers/ptp3/mtk_ptp3_main.c | 85 ++++++++++++++++++++++ plat/mediatek/mt8192/plat_pm.c | 6 ++ plat/mediatek/mt8192/platform.mk | 2 + 4 files changed, 141 insertions(+) create mode 100644 plat/mediatek/mt8192/drivers/ptp3/mtk_ptp3_common.h create mode 100644 plat/mediatek/mt8192/drivers/ptp3/mtk_ptp3_main.c diff --git a/plat/mediatek/mt8192/drivers/ptp3/mtk_ptp3_common.h b/plat/mediatek/mt8192/drivers/ptp3/mtk_ptp3_common.h new file mode 100644 index 000000000..92c71bcdd --- /dev/null +++ b/plat/mediatek/mt8192/drivers/ptp3/mtk_ptp3_common.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MTK_PTP3_H +#define MTK_PTP3_H + +#include +#include + +/************************************************ + * BIT Operation and REG r/w + ************************************************/ +#define ptp3_read(addr) mmio_read_32((uintptr_t)addr) +#define ptp3_write(addr, val) mmio_write_32((uintptr_t)addr, val) + +/************************************************ + * CPU info + ************************************************/ +#define NR_PTP3_CFG1_CPU U(8) +#define PTP3_CFG1_CPU_START_ID U(0) +#define PTP3_CFG1_MASK 0x00100000 + +#define NR_PTP3_CFG2_CPU U(4) +#define PTP3_CFG2_CPU_START_ID U(4) + +#define NR_PTP3_CFG3_CPU U(4) +#define PTP3_CFG3_CPU_START_ID U(4) + +/************************************************ + * config enum + ************************************************/ +enum PTP3_CFG { + PTP3_CFG_ADDR, + PTP3_CFG_VALUE, + NR_PTP3_CFG, +}; + +/************************************ + * prototype + ************************************/ +/* init trigger for ptp3 feature */ +extern void ptp3_init(unsigned int core); +extern void ptp3_deinit(unsigned int core); + +#endif /* MTK_PTP3_H */ diff --git a/plat/mediatek/mt8192/drivers/ptp3/mtk_ptp3_main.c b/plat/mediatek/mt8192/drivers/ptp3/mtk_ptp3_main.c new file mode 100644 index 000000000..053d21081 --- /dev/null +++ b/plat/mediatek/mt8192/drivers/ptp3/mtk_ptp3_main.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. \ + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "mtk_ptp3_common.h" + +/************************************************ + * Central control: turn on sysPi protection + ************************************************/ +static unsigned int ptp3_cfg1[NR_PTP3_CFG1_CPU][NR_PTP3_CFG] = { + {0x0C530610, 0x110842}, + {0x0C530E10, 0x110842}, + {0x0C531610, 0x110842}, + {0x0C531E10, 0x110842}, + {0x0C532610, 0x110842}, + {0x0C532E10, 0x110842}, + {0x0C533610, 0x110842}, + {0x0C533E10, 0x110842} +}; +static unsigned int ptp3_cfg2[NR_PTP3_CFG2_CPU][NR_PTP3_CFG] = { + {0x0C53B830, 0x68000}, + {0x0C53BA30, 0x68000}, + {0x0C53BC30, 0x68000}, + {0x0C53BE30, 0x68000} +}; +static unsigned int ptp3_cfg3[NR_PTP3_CFG3_CPU][NR_PTP3_CFG] = { + {0x0C532480, 0x7C607C6}, + {0x0C532C80, 0x7C607C6}, + {0x0C533480, 0x7C607C6}, + {0x0C533C80, 0x7C607C6} +}; + +/************************************************ + * API + ************************************************/ +void ptp3_init(unsigned int core) +{ + unsigned int _core; + + if (core >= PTP3_CFG1_CPU_START_ID) { + if (core < NR_PTP3_CFG1_CPU) { + /* update ptp3_cfg1 */ + ptp3_write( + ptp3_cfg1[core][PTP3_CFG_ADDR], + ptp3_cfg1[core][PTP3_CFG_VALUE]); + } + } + + if (core >= PTP3_CFG2_CPU_START_ID) { + _core = core - PTP3_CFG2_CPU_START_ID; + + if (_core < NR_PTP3_CFG2_CPU) { + /* update ptp3_cfg2 */ + ptp3_write( + ptp3_cfg2[_core][PTP3_CFG_ADDR], + ptp3_cfg2[_core][PTP3_CFG_VALUE]); + } + } + + if (core >= PTP3_CFG3_CPU_START_ID) { + _core = core - PTP3_CFG3_CPU_START_ID; + + if (_core < NR_PTP3_CFG3_CPU) { + /* update ptp3_cfg3 */ + ptp3_write( + ptp3_cfg3[_core][PTP3_CFG_ADDR], + ptp3_cfg3[_core][PTP3_CFG_VALUE]); + } + } +} + +void ptp3_deinit(unsigned int core) +{ + if (core >= PTP3_CFG1_CPU_START_ID) { + if (core < NR_PTP3_CFG1_CPU) { + /* update ptp3_cfg1 */ + ptp3_write( + ptp3_cfg1[core][PTP3_CFG_ADDR], + ptp3_cfg1[core][PTP3_CFG_VALUE] & + ~PTP3_CFG1_MASK); + } + } +} diff --git a/plat/mediatek/mt8192/plat_pm.c b/plat/mediatek/mt8192/plat_pm.c index ac6cb8085..3ea27b6c1 100644 --- a/plat/mediatek/mt8192/plat_pm.c +++ b/plat/mediatek/mt8192/plat_pm.c @@ -14,6 +14,7 @@ /* platform specific headers */ #include +#include #include #include #include @@ -72,6 +73,8 @@ static void plat_cpu_pwrdwn_common(unsigned int cpu, mt_gic_rdistif_save(); gicv3_cpuif_disable(cpu); gicv3_rdistif_off(cpu); + /* PTP3 config */ + ptp3_deinit(cpu); } static void plat_cpu_pwron_common(unsigned int cpu, @@ -97,6 +100,9 @@ static void plat_cpu_pwron_common(unsigned int cpu, } else { mt_gic_rdistif_restore(); } + + /* PTP3 config */ + ptp3_init(cpu); } /* diff --git a/plat/mediatek/mt8192/platform.mk b/plat/mediatek/mt8192/platform.mk index 3ada52939..b36a7e867 100644 --- a/plat/mediatek/mt8192/platform.mk +++ b/plat/mediatek/mt8192/platform.mk @@ -13,6 +13,7 @@ PLAT_INCLUDES := -I${MTK_PLAT}/common/ \ -I${MTK_PLAT_SOC}/drivers/gpio/ \ -I${MTK_PLAT_SOC}/drivers/mcdi/ \ -I${MTK_PLAT_SOC}/drivers/pmic/ \ + -I${MTK_PLAT_SOC}/drivers/ptp3/ \ -I${MTK_PLAT_SOC}/drivers/spmc/ \ -I${MTK_PLAT_SOC}/drivers/timer/ \ -I${MTK_PLAT_SOC}/drivers/uart/ @@ -53,6 +54,7 @@ BL31_SOURCES += common/desc_image_load.c \ ${MTK_PLAT_SOC}/drivers/mcdi/mt_cpu_pm.c \ ${MTK_PLAT_SOC}/drivers/mcdi/mt_cpu_pm_cpc.c \ ${MTK_PLAT_SOC}/drivers/mcdi/mt_mcdi.c \ + ${MTK_PLAT_SOC}/drivers/ptp3/mtk_ptp3_main.c \ ${MTK_PLAT_SOC}/drivers/spmc/mtspmc.c \ ${MTK_PLAT_SOC}/drivers/timer/mt_timer.c -- cgit v1.2.3 From 43d7bbcc6c4e2d14dbab0dac9bf94026c504c4f8 Mon Sep 17 00:00:00 2001 From: Nina Wu Date: Tue, 8 Sep 2020 14:36:07 +0800 Subject: mediatek: mt8192: dcm: Add mcusys related dcm drivers 1. Add mcusys related dcm drivers 2. Turn on mcusys-related dcm by default Change-Id: Ibbee37c87cc38e7a6cd7c93c2fc0817aad6dbe95 Signed-off-by: Nina Wu --- plat/mediatek/mt8192/bl31_plat_setup.c | 6 + plat/mediatek/mt8192/drivers/dcm/mtk_dcm.c | 63 +++ plat/mediatek/mt8192/drivers/dcm/mtk_dcm.h | 14 + plat/mediatek/mt8192/drivers/dcm/mtk_dcm_utils.c | 562 +++++++++++++++++++++++ plat/mediatek/mt8192/drivers/dcm/mtk_dcm_utils.h | 68 +++ plat/mediatek/mt8192/platform.mk | 3 + 6 files changed, 716 insertions(+) create mode 100644 plat/mediatek/mt8192/drivers/dcm/mtk_dcm.c create mode 100644 plat/mediatek/mt8192/drivers/dcm/mtk_dcm.h create mode 100644 plat/mediatek/mt8192/drivers/dcm/mtk_dcm_utils.c create mode 100644 plat/mediatek/mt8192/drivers/dcm/mtk_dcm_utils.h diff --git a/plat/mediatek/mt8192/bl31_plat_setup.c b/plat/mediatek/mt8192/bl31_plat_setup.c index 2a0e131b9..32e124f1f 100644 --- a/plat/mediatek/mt8192/bl31_plat_setup.c +++ b/plat/mediatek/mt8192/bl31_plat_setup.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -83,6 +84,11 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, ******************************************************************************/ void bl31_platform_setup(void) { + /* Set dcm on */ + if (!dcm_set_default()) { + ERROR("Failed to set default dcm on!!\n"); + } + /* Initialize the GIC driver, CPU and distributor interfaces */ mt_gic_driver_init(); mt_gic_init(); diff --git a/plat/mediatek/mt8192/drivers/dcm/mtk_dcm.c b/plat/mediatek/mt8192/drivers/dcm/mtk_dcm.c new file mode 100644 index 000000000..dd8bf4eed --- /dev/null +++ b/plat/mediatek/mt8192/drivers/dcm/mtk_dcm.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +static void dcm_armcore(bool mode) +{ + dcm_mp_cpusys_top_bus_pll_div_dcm(mode); + dcm_mp_cpusys_top_cpu_pll_div_0_dcm(mode); + dcm_mp_cpusys_top_cpu_pll_div_1_dcm(mode); +} + +static void dcm_mcusys(bool on) +{ + dcm_mp_cpusys_top_adb_dcm(on); + dcm_mp_cpusys_top_apb_dcm(on); + dcm_mp_cpusys_top_cpubiu_dcm(on); + dcm_mp_cpusys_top_misc_dcm(on); + dcm_mp_cpusys_top_mp0_qdcm(on); + dcm_cpccfg_reg_emi_wfifo(on); + dcm_mp_cpusys_top_last_cor_idle_dcm(on); +} + +static void dcm_stall(bool on) +{ + dcm_mp_cpusys_top_core_stall_dcm(on); + dcm_mp_cpusys_top_fcm_stall_dcm(on); +} + +static bool check_dcm_state(void) +{ + bool ret = true; + + ret &= dcm_mp_cpusys_top_bus_pll_div_dcm_is_on(); + ret &= dcm_mp_cpusys_top_cpu_pll_div_0_dcm_is_on(); + ret &= dcm_mp_cpusys_top_cpu_pll_div_1_dcm_is_on(); + + ret &= dcm_mp_cpusys_top_adb_dcm_is_on(); + ret &= dcm_mp_cpusys_top_apb_dcm_is_on(); + ret &= dcm_mp_cpusys_top_cpubiu_dcm_is_on(); + ret &= dcm_mp_cpusys_top_misc_dcm_is_on(); + ret &= dcm_mp_cpusys_top_mp0_qdcm_is_on(); + ret &= dcm_cpccfg_reg_emi_wfifo_is_on(); + ret &= dcm_mp_cpusys_top_last_cor_idle_dcm_is_on(); + + ret &= dcm_mp_cpusys_top_core_stall_dcm_is_on(); + ret &= dcm_mp_cpusys_top_fcm_stall_dcm_is_on(); + + return ret; +} + +bool dcm_set_default(void) +{ + dcm_armcore(true); + dcm_mcusys(true); + dcm_stall(true); + + return check_dcm_state(); +} diff --git a/plat/mediatek/mt8192/drivers/dcm/mtk_dcm.h b/plat/mediatek/mt8192/drivers/dcm/mtk_dcm.h new file mode 100644 index 000000000..ee98d0e38 --- /dev/null +++ b/plat/mediatek/mt8192/drivers/dcm/mtk_dcm.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MTK_DCM_H +#define MTK_DCM_H + +#include + +bool dcm_set_default(void); + +#endif /* #ifndef MTK_DCM_H */ diff --git a/plat/mediatek/mt8192/drivers/dcm/mtk_dcm_utils.c b/plat/mediatek/mt8192/drivers/dcm/mtk_dcm_utils.c new file mode 100644 index 000000000..15a700c2b --- /dev/null +++ b/plat/mediatek/mt8192/drivers/dcm/mtk_dcm_utils.c @@ -0,0 +1,562 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#define MP_CPUSYS_TOP_ADB_DCM_REG0_MASK (BIT(17)) +#define MP_CPUSYS_TOP_ADB_DCM_REG1_MASK (BIT(15) | \ + BIT(16) | \ + BIT(17) | \ + BIT(18) | \ + BIT(21)) +#define MP_CPUSYS_TOP_ADB_DCM_REG2_MASK (BIT(15) | \ + BIT(16) | \ + BIT(17) | \ + BIT(18)) +#define MP_CPUSYS_TOP_ADB_DCM_REG0_ON (BIT(17)) +#define MP_CPUSYS_TOP_ADB_DCM_REG1_ON (BIT(15) | \ + BIT(16) | \ + BIT(17) | \ + BIT(18) | \ + BIT(21)) +#define MP_CPUSYS_TOP_ADB_DCM_REG2_ON (BIT(15) | \ + BIT(16) | \ + BIT(17) | \ + BIT(18)) +#define MP_CPUSYS_TOP_ADB_DCM_REG0_OFF ((0x0 << 17)) +#define MP_CPUSYS_TOP_ADB_DCM_REG1_OFF ((0x0 << 15) | \ + (0x0 << 16) | \ + (0x0 << 17) | \ + (0x0 << 18) | \ + (0x0 << 21)) +#define MP_CPUSYS_TOP_ADB_DCM_REG2_OFF ((0x0 << 15) | \ + (0x0 << 16) | \ + (0x0 << 17) | \ + (0x0 << 18)) + +bool dcm_mp_cpusys_top_adb_dcm_is_on(void) +{ + bool ret = true; + + ret &= ((mmio_read_32(MP_ADB_DCM_CFG0) & + MP_CPUSYS_TOP_ADB_DCM_REG0_MASK) == + (unsigned int) MP_CPUSYS_TOP_ADB_DCM_REG0_ON); + ret &= ((mmio_read_32(MP_ADB_DCM_CFG4) & + MP_CPUSYS_TOP_ADB_DCM_REG1_MASK) == + (unsigned int) MP_CPUSYS_TOP_ADB_DCM_REG1_ON); + ret &= ((mmio_read_32(MCUSYS_DCM_CFG0) & + MP_CPUSYS_TOP_ADB_DCM_REG2_MASK) == + (unsigned int) MP_CPUSYS_TOP_ADB_DCM_REG2_ON); + + return ret; +} + +void dcm_mp_cpusys_top_adb_dcm(bool on) +{ + if (on) { + /* TINFO = "Turn ON DCM 'mp_cpusys_top_adb_dcm'" */ + mmio_clrsetbits_32(MP_ADB_DCM_CFG0, + MP_CPUSYS_TOP_ADB_DCM_REG0_MASK, + MP_CPUSYS_TOP_ADB_DCM_REG0_ON); + mmio_clrsetbits_32(MP_ADB_DCM_CFG4, + MP_CPUSYS_TOP_ADB_DCM_REG1_MASK, + MP_CPUSYS_TOP_ADB_DCM_REG1_ON); + mmio_clrsetbits_32(MCUSYS_DCM_CFG0, + MP_CPUSYS_TOP_ADB_DCM_REG2_MASK, + MP_CPUSYS_TOP_ADB_DCM_REG2_ON); + } else { + /* TINFO = "Turn OFF DCM 'mp_cpusys_top_adb_dcm'" */ + mmio_clrsetbits_32(MP_ADB_DCM_CFG0, + MP_CPUSYS_TOP_ADB_DCM_REG0_MASK, + MP_CPUSYS_TOP_ADB_DCM_REG0_OFF); + mmio_clrsetbits_32(MP_ADB_DCM_CFG4, + MP_CPUSYS_TOP_ADB_DCM_REG1_MASK, + MP_CPUSYS_TOP_ADB_DCM_REG1_OFF); + mmio_clrsetbits_32(MCUSYS_DCM_CFG0, + MP_CPUSYS_TOP_ADB_DCM_REG2_MASK, + MP_CPUSYS_TOP_ADB_DCM_REG2_OFF); + } +} + +#define MP_CPUSYS_TOP_APB_DCM_REG0_MASK (BIT(5)) +#define MP_CPUSYS_TOP_APB_DCM_REG1_MASK (BIT(8)) +#define MP_CPUSYS_TOP_APB_DCM_REG2_MASK (BIT(16)) +#define MP_CPUSYS_TOP_APB_DCM_REG0_ON (BIT(5)) +#define MP_CPUSYS_TOP_APB_DCM_REG1_ON (BIT(8)) +#define MP_CPUSYS_TOP_APB_DCM_REG2_ON (BIT(16)) +#define MP_CPUSYS_TOP_APB_DCM_REG0_OFF ((0x0 << 5)) +#define MP_CPUSYS_TOP_APB_DCM_REG1_OFF ((0x0 << 8)) +#define MP_CPUSYS_TOP_APB_DCM_REG2_OFF ((0x0 << 16)) + +bool dcm_mp_cpusys_top_apb_dcm_is_on(void) +{ + bool ret = true; + + ret &= ((mmio_read_32(MP_MISC_DCM_CFG0) & + MP_CPUSYS_TOP_APB_DCM_REG0_MASK) == + (unsigned int) MP_CPUSYS_TOP_APB_DCM_REG0_ON); + ret &= ((mmio_read_32(MCUSYS_DCM_CFG0) & + MP_CPUSYS_TOP_APB_DCM_REG1_MASK) == + (unsigned int) MP_CPUSYS_TOP_APB_DCM_REG1_ON); + ret &= ((mmio_read_32(MP0_DCM_CFG0) & + MP_CPUSYS_TOP_APB_DCM_REG2_MASK) == + (unsigned int) MP_CPUSYS_TOP_APB_DCM_REG2_ON); + + return ret; +} + +void dcm_mp_cpusys_top_apb_dcm(bool on) +{ + if (on) { + /* TINFO = "Turn ON DCM 'mp_cpusys_top_apb_dcm'" */ + mmio_clrsetbits_32(MP_MISC_DCM_CFG0, + MP_CPUSYS_TOP_APB_DCM_REG0_MASK, + MP_CPUSYS_TOP_APB_DCM_REG0_ON); + mmio_clrsetbits_32(MCUSYS_DCM_CFG0, + MP_CPUSYS_TOP_APB_DCM_REG1_MASK, + MP_CPUSYS_TOP_APB_DCM_REG1_ON); + mmio_clrsetbits_32(MP0_DCM_CFG0, + MP_CPUSYS_TOP_APB_DCM_REG2_MASK, + MP_CPUSYS_TOP_APB_DCM_REG2_ON); + } else { + /* TINFO = "Turn OFF DCM 'mp_cpusys_top_apb_dcm'" */ + mmio_clrsetbits_32(MP_MISC_DCM_CFG0, + MP_CPUSYS_TOP_APB_DCM_REG0_MASK, + MP_CPUSYS_TOP_APB_DCM_REG0_OFF); + mmio_clrsetbits_32(MCUSYS_DCM_CFG0, + MP_CPUSYS_TOP_APB_DCM_REG1_MASK, + MP_CPUSYS_TOP_APB_DCM_REG1_OFF); + mmio_clrsetbits_32(MP0_DCM_CFG0, + MP_CPUSYS_TOP_APB_DCM_REG2_MASK, + MP_CPUSYS_TOP_APB_DCM_REG2_OFF); + } +} + +#define MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_MASK (BIT(11)) +#define MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_ON (BIT(11)) +#define MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_OFF ((0x0 << 11)) + +bool dcm_mp_cpusys_top_bus_pll_div_dcm_is_on(void) +{ + bool ret = true; + + ret &= ((mmio_read_32(BUS_PLLDIV_CFG) & + MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_MASK) == + (unsigned int) MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_ON); + + return ret; +} + +void dcm_mp_cpusys_top_bus_pll_div_dcm(bool on) +{ + if (on) { + /* TINFO = "Turn ON DCM 'mp_cpusys_top_bus_pll_div_dcm'" */ + mmio_clrsetbits_32(BUS_PLLDIV_CFG, + MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_MASK, + MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_ON); + } else { + /* TINFO = "Turn OFF DCM 'mp_cpusys_top_bus_pll_div_dcm'" */ + mmio_clrsetbits_32(BUS_PLLDIV_CFG, + MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_MASK, + MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_OFF); + } +} + +#define MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_MASK (BIT(0)) +#define MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_ON (BIT(0)) +#define MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_OFF ((0x0 << 0)) + +bool dcm_mp_cpusys_top_core_stall_dcm_is_on(void) +{ + bool ret = true; + + ret &= ((mmio_read_32(MP0_DCM_CFG7) & + MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_MASK) == + (unsigned int) MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_ON); + + return ret; +} + +void dcm_mp_cpusys_top_core_stall_dcm(bool on) +{ + if (on) { + /* TINFO = "Turn ON DCM 'mp_cpusys_top_core_stall_dcm'" */ + mmio_clrsetbits_32(MP0_DCM_CFG7, + MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_MASK, + MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_ON); + } else { + /* TINFO = "Turn OFF DCM 'mp_cpusys_top_core_stall_dcm'" */ + mmio_clrsetbits_32(MP0_DCM_CFG7, + MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_MASK, + MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_OFF); + } +} + +#define MP_CPUSYS_TOP_CPUBIU_DCM_REG0_MASK ((0xffff << 0)) +#define MP_CPUSYS_TOP_CPUBIU_DCM_REG0_ON ((0xffff << 0)) +#define MP_CPUSYS_TOP_CPUBIU_DCM_REG0_OFF ((0x0 << 0)) + +bool dcm_mp_cpusys_top_cpubiu_dcm_is_on(void) +{ + bool ret = true; + + ret &= ((mmio_read_32(MCSI_DCM0) & + MP_CPUSYS_TOP_CPUBIU_DCM_REG0_MASK) == + (unsigned int) MP_CPUSYS_TOP_CPUBIU_DCM_REG0_ON); + + return ret; +} + +void dcm_mp_cpusys_top_cpubiu_dcm(bool on) +{ + if (on) { + /* TINFO = "Turn ON DCM 'mp_cpusys_top_cpubiu_dcm'" */ + mmio_clrsetbits_32(MCSI_DCM0, + MP_CPUSYS_TOP_CPUBIU_DCM_REG0_MASK, + MP_CPUSYS_TOP_CPUBIU_DCM_REG0_ON); + } else { + /* TINFO = "Turn OFF DCM 'mp_cpusys_top_cpubiu_dcm'" */ + mmio_clrsetbits_32(MCSI_DCM0, + MP_CPUSYS_TOP_CPUBIU_DCM_REG0_MASK, + MP_CPUSYS_TOP_CPUBIU_DCM_REG0_OFF); + } +} + +#define MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_MASK (BIT(11)) +#define MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_ON (BIT(11)) +#define MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_OFF ((0x0 << 11)) + +bool dcm_mp_cpusys_top_cpu_pll_div_0_dcm_is_on(void) +{ + bool ret = true; + + ret &= ((mmio_read_32(CPU_PLLDIV_CFG0) & + MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_MASK) == + (unsigned int) MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_ON); + + return ret; +} + +void dcm_mp_cpusys_top_cpu_pll_div_0_dcm(bool on) +{ + if (on) { + /* TINFO = "Turn ON DCM 'mp_cpusys_top_cpu_pll_div_0_dcm'" */ + mmio_clrsetbits_32(CPU_PLLDIV_CFG0, + MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_MASK, + MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_ON); + } else { + /* TINFO = "Turn OFF DCM 'mp_cpusys_top_cpu_pll_div_0_dcm'" */ + mmio_clrsetbits_32(CPU_PLLDIV_CFG0, + MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_MASK, + MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_OFF); + } +} + +#define MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_MASK (BIT(11)) +#define MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_ON (BIT(11)) +#define MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_OFF ((0x0 << 11)) + +bool dcm_mp_cpusys_top_cpu_pll_div_1_dcm_is_on(void) +{ + bool ret = true; + + ret &= ((mmio_read_32(CPU_PLLDIV_CFG1) & + MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_MASK) == + (unsigned int) MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_ON); + + return ret; +} + +void dcm_mp_cpusys_top_cpu_pll_div_1_dcm(bool on) +{ + if (on) { + /* TINFO = "Turn ON DCM 'mp_cpusys_top_cpu_pll_div_1_dcm'" */ + mmio_clrsetbits_32(CPU_PLLDIV_CFG1, + MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_MASK, + MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_ON); + } else { + /* TINFO = "Turn OFF DCM 'mp_cpusys_top_cpu_pll_div_1_dcm'" */ + mmio_clrsetbits_32(CPU_PLLDIV_CFG1, + MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_MASK, + MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_OFF); + } +} + +#define MP_CPUSYS_TOP_CPU_PLL_DIV_2_DCM_REG0_MASK (BIT(11)) +#define MP_CPUSYS_TOP_CPU_PLL_DIV_2_DCM_REG0_ON (BIT(11)) +#define MP_CPUSYS_TOP_CPU_PLL_DIV_2_DCM_REG0_OFF ((0x0 << 11)) + +bool dcm_mp_cpusys_top_cpu_pll_div_2_dcm_is_on(void) +{ + bool ret = true; + + ret &= ((mmio_read_32(CPU_PLLDIV_CFG2) & + MP_CPUSYS_TOP_CPU_PLL_DIV_2_DCM_REG0_MASK) == + (unsigned int) MP_CPUSYS_TOP_CPU_PLL_DIV_2_DCM_REG0_ON); + + return ret; +} + +void dcm_mp_cpusys_top_cpu_pll_div_2_dcm(bool on) +{ + if (on) { + /* TINFO = "Turn ON DCM 'mp_cpusys_top_cpu_pll_div_2_dcm'" */ + mmio_clrsetbits_32(CPU_PLLDIV_CFG2, + MP_CPUSYS_TOP_CPU_PLL_DIV_2_DCM_REG0_MASK, + MP_CPUSYS_TOP_CPU_PLL_DIV_2_DCM_REG0_ON); + } else { + /* TINFO = "Turn OFF DCM 'mp_cpusys_top_cpu_pll_div_2_dcm'" */ + mmio_clrsetbits_32(CPU_PLLDIV_CFG2, + MP_CPUSYS_TOP_CPU_PLL_DIV_2_DCM_REG0_MASK, + MP_CPUSYS_TOP_CPU_PLL_DIV_2_DCM_REG0_OFF); + } +} + +#define MP_CPUSYS_TOP_CPU_PLL_DIV_3_DCM_REG0_MASK (BIT(11)) +#define MP_CPUSYS_TOP_CPU_PLL_DIV_3_DCM_REG0_ON (BIT(11)) +#define MP_CPUSYS_TOP_CPU_PLL_DIV_3_DCM_REG0_OFF ((0x0 << 11)) + +bool dcm_mp_cpusys_top_cpu_pll_div_3_dcm_is_on(void) +{ + bool ret = true; + + ret &= ((mmio_read_32(CPU_PLLDIV_CFG3) & + MP_CPUSYS_TOP_CPU_PLL_DIV_3_DCM_REG0_MASK) == + (unsigned int) MP_CPUSYS_TOP_CPU_PLL_DIV_3_DCM_REG0_ON); + + return ret; +} + +void dcm_mp_cpusys_top_cpu_pll_div_3_dcm(bool on) +{ + if (on) { + /* TINFO = "Turn ON DCM 'mp_cpusys_top_cpu_pll_div_3_dcm'" */ + mmio_clrsetbits_32(CPU_PLLDIV_CFG3, + MP_CPUSYS_TOP_CPU_PLL_DIV_3_DCM_REG0_MASK, + MP_CPUSYS_TOP_CPU_PLL_DIV_3_DCM_REG0_ON); + } else { + /* TINFO = "Turn OFF DCM 'mp_cpusys_top_cpu_pll_div_3_dcm'" */ + mmio_clrsetbits_32(CPU_PLLDIV_CFG3, + MP_CPUSYS_TOP_CPU_PLL_DIV_3_DCM_REG0_MASK, + MP_CPUSYS_TOP_CPU_PLL_DIV_3_DCM_REG0_OFF); + } +} + +#define MP_CPUSYS_TOP_CPU_PLL_DIV_4_DCM_REG0_MASK (BIT(11)) +#define MP_CPUSYS_TOP_CPU_PLL_DIV_4_DCM_REG0_ON (BIT(11)) +#define MP_CPUSYS_TOP_CPU_PLL_DIV_4_DCM_REG0_OFF ((0x0 << 11)) + +bool dcm_mp_cpusys_top_cpu_pll_div_4_dcm_is_on(void) +{ + bool ret = true; + + ret &= ((mmio_read_32(CPU_PLLDIV_CFG4) & + MP_CPUSYS_TOP_CPU_PLL_DIV_4_DCM_REG0_MASK) == + (unsigned int) MP_CPUSYS_TOP_CPU_PLL_DIV_4_DCM_REG0_ON); + + return ret; +} + +void dcm_mp_cpusys_top_cpu_pll_div_4_dcm(bool on) +{ + if (on) { + /* TINFO = "Turn ON DCM 'mp_cpusys_top_cpu_pll_div_4_dcm'" */ + mmio_clrsetbits_32(CPU_PLLDIV_CFG4, + MP_CPUSYS_TOP_CPU_PLL_DIV_4_DCM_REG0_MASK, + MP_CPUSYS_TOP_CPU_PLL_DIV_4_DCM_REG0_ON); + } else { + /* TINFO = "Turn OFF DCM 'mp_cpusys_top_cpu_pll_div_4_dcm'" */ + mmio_clrsetbits_32(CPU_PLLDIV_CFG4, + MP_CPUSYS_TOP_CPU_PLL_DIV_4_DCM_REG0_MASK, + MP_CPUSYS_TOP_CPU_PLL_DIV_4_DCM_REG0_OFF); + } +} + +#define MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_MASK (BIT(4)) +#define MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_ON (BIT(4)) +#define MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_OFF ((0x0 << 4)) + +bool dcm_mp_cpusys_top_fcm_stall_dcm_is_on(void) +{ + bool ret = true; + + ret &= ((mmio_read_32(MP0_DCM_CFG7) & + MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_MASK) == + (unsigned int) MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_ON); + + return ret; +} + +void dcm_mp_cpusys_top_fcm_stall_dcm(bool on) +{ + if (on) { + /* TINFO = "Turn ON DCM 'mp_cpusys_top_fcm_stall_dcm'" */ + mmio_clrsetbits_32(MP0_DCM_CFG7, + MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_MASK, + MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_ON); + } else { + /* TINFO = "Turn OFF DCM 'mp_cpusys_top_fcm_stall_dcm'" */ + mmio_clrsetbits_32(MP0_DCM_CFG7, + MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_MASK, + MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_OFF); + } +} + +#define MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_MASK ((0x1U << 31)) +#define MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_ON ((0x1U << 31)) +#define MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_OFF ((0x0U << 31)) + +bool dcm_mp_cpusys_top_last_cor_idle_dcm_is_on(void) +{ + bool ret = true; + + ret &= ((mmio_read_32(BUS_PLLDIV_CFG) & + MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_MASK) == + (unsigned int) MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_ON); + + return ret; +} + +void dcm_mp_cpusys_top_last_cor_idle_dcm(bool on) +{ + if (on) { + /* TINFO = "Turn ON DCM 'mp_cpusys_top_last_cor_idle_dcm'" */ + mmio_clrsetbits_32(BUS_PLLDIV_CFG, + MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_MASK, + MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_ON); + } else { + /* TINFO = "Turn OFF DCM 'mp_cpusys_top_last_cor_idle_dcm'" */ + mmio_clrsetbits_32(BUS_PLLDIV_CFG, + MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_MASK, + MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_OFF); + } +} + +#define MP_CPUSYS_TOP_MISC_DCM_REG0_MASK (BIT(1) | \ + BIT(4)) +#define MP_CPUSYS_TOP_MISC_DCM_REG0_ON (BIT(1) | \ + BIT(4)) +#define MP_CPUSYS_TOP_MISC_DCM_REG0_OFF ((0x0 << 1) | \ + (0x0 << 4)) + +bool dcm_mp_cpusys_top_misc_dcm_is_on(void) +{ + bool ret = true; + + ret &= ((mmio_read_32(MP_MISC_DCM_CFG0) & + MP_CPUSYS_TOP_MISC_DCM_REG0_MASK) == + (unsigned int) MP_CPUSYS_TOP_MISC_DCM_REG0_ON); + + return ret; +} + +void dcm_mp_cpusys_top_misc_dcm(bool on) +{ + if (on) { + /* TINFO = "Turn ON DCM 'mp_cpusys_top_misc_dcm'" */ + mmio_clrsetbits_32(MP_MISC_DCM_CFG0, + MP_CPUSYS_TOP_MISC_DCM_REG0_MASK, + MP_CPUSYS_TOP_MISC_DCM_REG0_ON); + } else { + /* TINFO = "Turn OFF DCM 'mp_cpusys_top_misc_dcm'" */ + mmio_clrsetbits_32(MP_MISC_DCM_CFG0, + MP_CPUSYS_TOP_MISC_DCM_REG0_MASK, + MP_CPUSYS_TOP_MISC_DCM_REG0_OFF); + } +} + +#define MP_CPUSYS_TOP_MP0_QDCM_REG0_MASK (BIT(3)) +#define MP_CPUSYS_TOP_MP0_QDCM_REG1_MASK (BIT(0) | \ + BIT(1) | \ + BIT(2) | \ + BIT(3)) +#define MP_CPUSYS_TOP_MP0_QDCM_REG0_ON (BIT(3)) +#define MP_CPUSYS_TOP_MP0_QDCM_REG1_ON (BIT(0) | \ + BIT(1) | \ + BIT(2) | \ + BIT(3)) +#define MP_CPUSYS_TOP_MP0_QDCM_REG0_OFF ((0x0 << 3)) +#define MP_CPUSYS_TOP_MP0_QDCM_REG1_OFF ((0x0 << 0) | \ + (0x0 << 1) | \ + (0x0 << 2) | \ + (0x0 << 3)) + +bool dcm_mp_cpusys_top_mp0_qdcm_is_on(void) +{ + bool ret = true; + + ret &= ((mmio_read_32(MP_MISC_DCM_CFG0) & + MP_CPUSYS_TOP_MP0_QDCM_REG0_MASK) == + (unsigned int) MP_CPUSYS_TOP_MP0_QDCM_REG0_ON); + ret &= ((mmio_read_32(MP0_DCM_CFG0) & + MP_CPUSYS_TOP_MP0_QDCM_REG1_MASK) == + (unsigned int) MP_CPUSYS_TOP_MP0_QDCM_REG1_ON); + + return ret; +} + +void dcm_mp_cpusys_top_mp0_qdcm(bool on) +{ + if (on) { + /* TINFO = "Turn ON DCM 'mp_cpusys_top_mp0_qdcm'" */ + mmio_clrsetbits_32(MP_MISC_DCM_CFG0, + MP_CPUSYS_TOP_MP0_QDCM_REG0_MASK, + MP_CPUSYS_TOP_MP0_QDCM_REG0_ON); + mmio_clrsetbits_32(MP0_DCM_CFG0, + MP_CPUSYS_TOP_MP0_QDCM_REG1_MASK, + MP_CPUSYS_TOP_MP0_QDCM_REG1_ON); + } else { + /* TINFO = "Turn OFF DCM 'mp_cpusys_top_mp0_qdcm'" */ + mmio_clrsetbits_32(MP_MISC_DCM_CFG0, + MP_CPUSYS_TOP_MP0_QDCM_REG0_MASK, + MP_CPUSYS_TOP_MP0_QDCM_REG0_OFF); + mmio_clrsetbits_32(MP0_DCM_CFG0, + MP_CPUSYS_TOP_MP0_QDCM_REG1_MASK, + MP_CPUSYS_TOP_MP0_QDCM_REG1_OFF); + } +} + +#define CPCCFG_REG_EMI_WFIFO_REG0_MASK (BIT(0) | \ + BIT(1) | \ + BIT(2) | \ + BIT(3)) +#define CPCCFG_REG_EMI_WFIFO_REG0_ON (BIT(0) | \ + BIT(1) | \ + BIT(2) | \ + BIT(3)) +#define CPCCFG_REG_EMI_WFIFO_REG0_OFF ((0x0 << 0) | \ + (0x0 << 1) | \ + (0x0 << 2) | \ + (0x0 << 3)) + +bool dcm_cpccfg_reg_emi_wfifo_is_on(void) +{ + bool ret = true; + + ret &= ((mmio_read_32(EMI_WFIFO) & + CPCCFG_REG_EMI_WFIFO_REG0_MASK) == + (unsigned int) CPCCFG_REG_EMI_WFIFO_REG0_ON); + + return ret; +} + +void dcm_cpccfg_reg_emi_wfifo(bool on) +{ + if (on) { + /* TINFO = "Turn ON DCM 'cpccfg_reg_emi_wfifo'" */ + mmio_clrsetbits_32(EMI_WFIFO, + CPCCFG_REG_EMI_WFIFO_REG0_MASK, + CPCCFG_REG_EMI_WFIFO_REG0_ON); + } else { + /* TINFO = "Turn OFF DCM 'cpccfg_reg_emi_wfifo'" */ + mmio_clrsetbits_32(EMI_WFIFO, + CPCCFG_REG_EMI_WFIFO_REG0_MASK, + CPCCFG_REG_EMI_WFIFO_REG0_OFF); + } +} + diff --git a/plat/mediatek/mt8192/drivers/dcm/mtk_dcm_utils.h b/plat/mediatek/mt8192/drivers/dcm/mtk_dcm_utils.h new file mode 100644 index 000000000..1cf78345e --- /dev/null +++ b/plat/mediatek/mt8192/drivers/dcm/mtk_dcm_utils.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MTK_DCM_UTILS_H +#define MTK_DCM_UTILS_H + +#include + +#include +#include + +/* Base */ +#define MP_CPUSYS_TOP_BASE (MCUCFG_BASE + 0x8000) +#define CPCCFG_REG_BASE (MCUCFG_BASE + 0xA800) + +/* Register Definition */ +#define CPU_PLLDIV_CFG0 (MP_CPUSYS_TOP_BASE + 0x22a0) +#define CPU_PLLDIV_CFG1 (MP_CPUSYS_TOP_BASE + 0x22a4) +#define CPU_PLLDIV_CFG2 (MP_CPUSYS_TOP_BASE + 0x22a8) +#define CPU_PLLDIV_CFG3 (MP_CPUSYS_TOP_BASE + 0x22ac) +#define CPU_PLLDIV_CFG4 (MP_CPUSYS_TOP_BASE + 0x22b0) +#define BUS_PLLDIV_CFG (MP_CPUSYS_TOP_BASE + 0x22e0) +#define MCSI_DCM0 (MP_CPUSYS_TOP_BASE + 0x2440) +#define MP_ADB_DCM_CFG0 (MP_CPUSYS_TOP_BASE + 0x2500) +#define MP_ADB_DCM_CFG4 (MP_CPUSYS_TOP_BASE + 0x2510) +#define MP_MISC_DCM_CFG0 (MP_CPUSYS_TOP_BASE + 0x2518) +#define MCUSYS_DCM_CFG0 (MP_CPUSYS_TOP_BASE + 0x25c0) +#define EMI_WFIFO (CPCCFG_REG_BASE + 0x100) +#define MP0_DCM_CFG0 (MP_CPUSYS_TOP_BASE + 0x4880) +#define MP0_DCM_CFG7 (MP_CPUSYS_TOP_BASE + 0x489c) + +/* MP_CPUSYS_TOP */ +bool dcm_mp_cpusys_top_adb_dcm_is_on(void); +void dcm_mp_cpusys_top_adb_dcm(bool on); +bool dcm_mp_cpusys_top_apb_dcm_is_on(void); +void dcm_mp_cpusys_top_apb_dcm(bool on); +bool dcm_mp_cpusys_top_bus_pll_div_dcm_is_on(void); +void dcm_mp_cpusys_top_bus_pll_div_dcm(bool on); +bool dcm_mp_cpusys_top_core_stall_dcm_is_on(void); +void dcm_mp_cpusys_top_core_stall_dcm(bool on); +bool dcm_mp_cpusys_top_cpubiu_dcm_is_on(void); +void dcm_mp_cpusys_top_cpubiu_dcm(bool on); +bool dcm_mp_cpusys_top_cpu_pll_div_0_dcm_is_on(void); +void dcm_mp_cpusys_top_cpu_pll_div_0_dcm(bool on); +bool dcm_mp_cpusys_top_cpu_pll_div_1_dcm_is_on(void); +void dcm_mp_cpusys_top_cpu_pll_div_1_dcm(bool on); +bool dcm_mp_cpusys_top_cpu_pll_div_2_dcm_is_on(void); +void dcm_mp_cpusys_top_cpu_pll_div_2_dcm(bool on); +bool dcm_mp_cpusys_top_cpu_pll_div_3_dcm_is_on(void); +void dcm_mp_cpusys_top_cpu_pll_div_3_dcm(bool on); +bool dcm_mp_cpusys_top_cpu_pll_div_4_dcm_is_on(void); +void dcm_mp_cpusys_top_cpu_pll_div_4_dcm(bool on); +bool dcm_mp_cpusys_top_fcm_stall_dcm_is_on(void); +void dcm_mp_cpusys_top_fcm_stall_dcm(bool on); +bool dcm_mp_cpusys_top_last_cor_idle_dcm_is_on(void); +void dcm_mp_cpusys_top_last_cor_idle_dcm(bool on); +bool dcm_mp_cpusys_top_misc_dcm_is_on(void); +void dcm_mp_cpusys_top_misc_dcm(bool on); +bool dcm_mp_cpusys_top_mp0_qdcm_is_on(void); +void dcm_mp_cpusys_top_mp0_qdcm(bool on); +/* CPCCFG_REG */ +bool dcm_cpccfg_reg_emi_wfifo_is_on(void); +void dcm_cpccfg_reg_emi_wfifo(bool on); + +#endif diff --git a/plat/mediatek/mt8192/platform.mk b/plat/mediatek/mt8192/platform.mk index b36a7e867..191895a21 100644 --- a/plat/mediatek/mt8192/platform.mk +++ b/plat/mediatek/mt8192/platform.mk @@ -10,6 +10,7 @@ MTK_PLAT_SOC := ${MTK_PLAT}/${PLAT} PLAT_INCLUDES := -I${MTK_PLAT}/common/ \ -I${MTK_PLAT_SOC}/include/ \ -I${MTK_PLAT_SOC}/drivers/ \ + -I${MTK_PLAT_SOC}/drivers/dcm \ -I${MTK_PLAT_SOC}/drivers/gpio/ \ -I${MTK_PLAT_SOC}/drivers/mcdi/ \ -I${MTK_PLAT_SOC}/drivers/pmic/ \ @@ -50,6 +51,8 @@ BL31_SOURCES += common/desc_image_load.c \ ${MTK_PLAT_SOC}/plat_mt_gic.c \ ${MTK_PLAT_SOC}/plat_mt_cirq.c \ ${MTK_PLAT_SOC}/plat_sip_calls.c \ + ${MTK_PLAT_SOC}/drivers/dcm/mtk_dcm.c \ + ${MTK_PLAT_SOC}/drivers/dcm/mtk_dcm_utils.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 b635d11bcdcabdb76df92ca6a8913cd489b3c6f7 Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Tue, 10 Nov 2020 17:50:43 +0100 Subject: spm: remove device-memory node from SPMC manifests The PVM concept is removed from the SPMC so the device-memory node which is specifying the device memory range for the PVM is no longer applicable. Signed-off-by: Olivier Deprez Change-Id: If0cb956e0197028b24ecb78952c66ec454904516 --- plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts | 5 ----- plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts | 5 ----- 2 files changed, 10 deletions(-) diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts index 8b9c281e2..32549a0e1 100644 --- a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts +++ b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts @@ -74,11 +74,6 @@ CPU_1 }; - device-memory@0 { - device_type = "device-memory"; - reg = <0x0 0x0 0x6000000 0x0 0x8000000 0x78000000>; - }; - memory@6000000 { device_type = "memory"; reg = <0x0 0x6000000 0x2000000>; /* Trusted DRAM */ diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts index 266adfc2b..e59acb3ba 100644 --- a/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts +++ b/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts @@ -61,11 +61,6 @@ CPU_1 }; - device-memory@0 { - device_type = "device-memory"; - reg = <0x0 0x0 0x6000000 0x0 0x8000000 0x78000000>; - }; - memory@6000000 { device_type = "memory"; reg = <0x0 0x6000000 0x2000000>; /* Trusted DRAM */ -- cgit v1.2.3 From 3ac8680cbbfbba199ec20f5fe0f3fcaa98df20ac Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Thu, 12 Nov 2020 18:14:22 +0100 Subject: spm: update OP-TEE SP manifest with device-regions node Specify peripherals accessed by OP-TEE as a Secure Partition running as a VM managed by the SPMC. Signed-off-by: Olivier Deprez Change-Id: Icf9aae038e2b1b0ce4696f78ff964bfff8a1498c --- fdts/optee_sp_manifest.dts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/fdts/optee_sp_manifest.dts b/fdts/optee_sp_manifest.dts index 02a5ef340..928d0d3bf 100644 --- a/fdts/optee_sp_manifest.dts +++ b/fdts/optee_sp_manifest.dts @@ -30,4 +30,20 @@ /* Boot protocol */ gp-register-num = <0x0>; + + device-regions { + compatible = "arm,ffa-manifest-device-regions"; + + uart1 { + base-address = <0x00000000 0x1c0a0000>; + pages-count = <1>; + attributes = <0x3>; /* read-write */ + }; + + gicd { + base-address = <0x00000000 0x2f000000>; + pages-count = <16>; + attributes = <0x3>; /* read-write */ + }; + }; }; -- cgit v1.2.3 From 76d22f06dc3b9f266394ef237188b0193645a6be Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Thu, 3 Dec 2020 15:13:49 +0100 Subject: spm: move OP-TEE SP manifest DTS to FVP platform Signed-off-by: Olivier Deprez Change-Id: I0981c43e2ef8172138f65d95eac7b20f8969394e --- fdts/optee_sp_manifest.dts | 49 --------------------------- plat/arm/board/fvp/fdts/optee_sp_manifest.dts | 49 +++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 49 deletions(-) delete mode 100644 fdts/optee_sp_manifest.dts create mode 100644 plat/arm/board/fvp/fdts/optee_sp_manifest.dts diff --git a/fdts/optee_sp_manifest.dts b/fdts/optee_sp_manifest.dts deleted file mode 100644 index 928d0d3bf..000000000 --- a/fdts/optee_sp_manifest.dts +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2020, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - * - * This file is a Partition Manifest (PM) for a minimal Secure Partition (SP) - * that has additional optional properties defined. - * - */ - -/dts-v1/; - -/ { - compatible = "arm,ffa-manifest-1.0"; - - /* Properties */ - description = "op-tee"; - ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */ - uuid = <0x486178e0 0xe7f811e3 0xbc5e0002 0xa5d5c51b>; - id = <1>; - execution-ctx-count = <8>; - exception-level = <2>; /* S-EL1 */ - execution-state = <0>; /* AARCH64 */ - load-address = <0x6280000>; - entrypoint-offset = <0x1000>; - xlat-granule = <0>; /* 4KiB */ - boot-order = <0>; - messaging-method = <0>; /* Direct messaging only */ - run-time-model = <1>; /* Run to completion */ - - /* Boot protocol */ - gp-register-num = <0x0>; - - device-regions { - compatible = "arm,ffa-manifest-device-regions"; - - uart1 { - base-address = <0x00000000 0x1c0a0000>; - pages-count = <1>; - attributes = <0x3>; /* read-write */ - }; - - gicd { - base-address = <0x00000000 0x2f000000>; - pages-count = <16>; - attributes = <0x3>; /* read-write */ - }; - }; -}; diff --git a/plat/arm/board/fvp/fdts/optee_sp_manifest.dts b/plat/arm/board/fvp/fdts/optee_sp_manifest.dts new file mode 100644 index 000000000..928d0d3bf --- /dev/null +++ b/plat/arm/board/fvp/fdts/optee_sp_manifest.dts @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * This file is a Partition Manifest (PM) for a minimal Secure Partition (SP) + * that has additional optional properties defined. + * + */ + +/dts-v1/; + +/ { + compatible = "arm,ffa-manifest-1.0"; + + /* Properties */ + description = "op-tee"; + ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */ + uuid = <0x486178e0 0xe7f811e3 0xbc5e0002 0xa5d5c51b>; + id = <1>; + execution-ctx-count = <8>; + exception-level = <2>; /* S-EL1 */ + execution-state = <0>; /* AARCH64 */ + load-address = <0x6280000>; + entrypoint-offset = <0x1000>; + xlat-granule = <0>; /* 4KiB */ + boot-order = <0>; + messaging-method = <0>; /* Direct messaging only */ + run-time-model = <1>; /* Run to completion */ + + /* Boot protocol */ + gp-register-num = <0x0>; + + device-regions { + compatible = "arm,ffa-manifest-device-regions"; + + uart1 { + base-address = <0x00000000 0x1c0a0000>; + pages-count = <1>; + attributes = <0x3>; /* read-write */ + }; + + gicd { + base-address = <0x00000000 0x2f000000>; + pages-count = <16>; + attributes = <0x3>; /* read-write */ + }; + }; +}; -- cgit v1.2.3 From 5134fcbb47e83bdfc5427c44ce7f1f4238456c0d Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Tue, 24 Nov 2020 17:32:43 +0100 Subject: spm: remove chosen node from SPMC manifests The chosen node is no longer required as the SPMC implements a specific boot flow which no longer requires this node. Signed-off-by: Olivier Deprez Change-Id: Ib566b602a7f83003a1b2d0ba5f6ebf4d8b7a9156 --- plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts | 5 ----- plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts | 5 ----- 2 files changed, 10 deletions(-) diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts index 32549a0e1..43b146630 100644 --- a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts +++ b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts @@ -27,11 +27,6 @@ binary_size = <0x80000>; }; - chosen { - linux,initrd-start = <0>; - linux,initrd-end = <0>; - }; - hypervisor { compatible = "hafnium,hafnium"; vm1 { diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts index e59acb3ba..117909de9 100644 --- a/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts +++ b/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts @@ -27,11 +27,6 @@ binary_size = <0x80000>; }; - chosen { - linux,initrd-start = <0>; - linux,initrd-end = <0>; - }; - hypervisor { compatible = "hafnium,hafnium"; vm1 { -- cgit v1.2.3 From 89832ac9ef48e3bf065259b3421e3aeccfd5a973 Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Wed, 25 Nov 2020 10:29:41 +0100 Subject: spm: provide number of vCPUs and VM size for first SP The primary VM concept is removed from the SPMC. Update the SPMC manifests with number of Execution Contexts and SP workspace size for the first Secure Partition (as it is done for NWd secondary VMs and other SPs). Signed-off-by: Olivier Deprez Change-Id: I3b9c52666f7dfe74ab1f7d2148ad0070ee44b54e --- plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts | 2 ++ plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts | 2 ++ 2 files changed, 4 insertions(+) diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts index 43b146630..f4805db69 100644 --- a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts +++ b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts @@ -33,6 +33,8 @@ is_ffa_partition; debug_name = "cactus-primary"; load_address = <0x7000000>; + vcpu_count = <8>; + mem_size = <1048576>; }; vm2 { is_ffa_partition; diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts index 117909de9..57d6792e1 100644 --- a/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts +++ b/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts @@ -34,6 +34,8 @@ debug_name = "op-tee"; load_address = <0x6280000>; smc_whitelist = <0xbe000000>; + vcpu_count = <8>; + mem_size = <1048576>; }; }; -- cgit v1.2.3 From f2afaad0718b3a3e2b5f63ea3229933eecc6d7c2 Mon Sep 17 00:00:00 2001 From: Siva Durga Prasad Paladugu Date: Sun, 22 Nov 2020 22:10:12 -0800 Subject: zynqmp: pm_api_clock: Copy only the valid bytes This patches copies only the valid part of string and avoids filling junk at the end. Signed-off-by: Siva Durga Prasad Paladugu Signed-off-by: Rajan Vaja Change-Id: If23772f31f9cf7f5042e8bfc474fbfe77dcd90e7 --- plat/xilinx/zynqmp/pm_service/pm_api_clock.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c index 852f92763..27966635e 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c +++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -2435,7 +2435,8 @@ enum pm_ret_status pm_api_clock_get_num_clocks(unsigned int *nclocks) enum pm_ret_status pm_api_clock_get_name(unsigned int clock_id, char *name) { if (clock_id == CLK_MAX) - memcpy(name, END_OF_CLK, CLK_NAME_LEN); + memcpy(name, END_OF_CLK, sizeof(END_OF_CLK) > CLK_NAME_LEN ? + CLK_NAME_LEN : sizeof(END_OF_CLK)); else if (!pm_clock_valid(clock_id)) memset(name, 0, CLK_NAME_LEN); else if (clock_id < CLK_MAX_OUTPUT_CLK) -- cgit v1.2.3 From c8f62536833eca49723b6360b3744e5110ae0ffe Mon Sep 17 00:00:00 2001 From: Ravi Patel Date: Tue, 18 Sep 2018 02:14:12 -0700 Subject: zynqmp: pm: Update flags in common clk divisor node Current implementation doesn't support change of div1 value if clk has 2 divisor because div1 clk is the parent of the div2 clk and div2 clk does not have SET_RATE_PARENT flag. This causes div1 value to be fixed and only value of div2 will be adjusted according to required clock rate. Example: Consider a case of nand_ref clock which has 2 divisor and 1 mux. The frequency of mux clock is 1500MHz and default value of div1 and div2 is 15 and 1 respectively. So the final clock will be of 100MHz. When driver requests 80MHz for nand_ref clock, clock framework will adjust the div2 value to 1 (setting div2 value 2 results final clock to 50MHz which is more inaccurate compare to 100Mhz) which results final clock to 100MHz. Ideally the value of div1 and div2 should be updated to 19 and 1 respectively so that final clock goes to around 78MHz. This patch fixes above problem by allowing change in div1 value. Signed-off-by: Ravi Patel Signed-off-by: Rajan Vaja Change-Id: Ibb98f6748d28653fdd1e59bf433b6a37ce9c1a58 --- plat/xilinx/zynqmp/pm_service/pm_api_clock.c | 36 +++++++++++++++++++--------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c index 27966635e..f2dfbb17b 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c +++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c @@ -129,12 +129,26 @@ .div = NA_DIV, \ } -#define GENERIC_DIV(id) \ +#define GENERIC_DIV1 \ { \ - .type = TYPE_DIV##id, \ - .offset = PERIPH_DIV##id##_SHIFT, \ - .width = PERIPH_DIV##id##_WIDTH, \ + .type = TYPE_DIV1, \ + .offset = PERIPH_DIV1_SHIFT, \ + .width = PERIPH_DIV1_WIDTH, \ + .clkflags = CLK_SET_RATE_NO_REPARENT | \ + CLK_IS_BASIC, \ + .typeflags = CLK_DIVIDER_ONE_BASED | \ + CLK_DIVIDER_ALLOW_ZERO, \ + .mult = NA_MULT, \ + .div = NA_DIV, \ + } + +#define GENERIC_DIV2 \ + { \ + .type = TYPE_DIV2, \ + .offset = PERIPH_DIV2_SHIFT, \ + .width = PERIPH_DIV2_WIDTH, \ .clkflags = CLK_SET_RATE_NO_REPARENT | \ + CLK_SET_RATE_PARENT | \ CLK_IS_BASIC, \ .typeflags = CLK_DIVIDER_ONE_BASED | \ CLK_DIVIDER_ALLOW_ZERO, \ @@ -340,25 +354,25 @@ static struct pm_clock_node acpu_nodes[] = { static struct pm_clock_node generic_mux_div_nodes[] = { GENERIC_MUX, - GENERIC_DIV(1), + GENERIC_DIV1, }; static struct pm_clock_node generic_mux_div_gate_nodes[] = { GENERIC_MUX, - GENERIC_DIV(1), + GENERIC_DIV1, GENERIC_GATE, }; static struct pm_clock_node generic_mux_div_unused_gate_nodes[] = { GENERIC_MUX, - GENERIC_DIV(1), + GENERIC_DIV1, IGNORE_UNUSED_GATE, }; static struct pm_clock_node generic_mux_div_div_gate_nodes[] = { GENERIC_MUX, - GENERIC_DIV(1), - GENERIC_DIV(2), + GENERIC_DIV1, + GENERIC_DIV2, GENERIC_GATE, }; @@ -410,8 +424,8 @@ static struct pm_clock_node dp_audio_video_ref_nodes[] = { static struct pm_clock_node usb_nodes[] = { GENERIC_MUX, - GENERIC_DIV(1), - GENERIC_DIV(2), + GENERIC_DIV1, + GENERIC_DIV2, { .type = TYPE_GATE, .offset = USB_GATE_SHIFT, -- cgit v1.2.3 From 605767475ec42f4250edbfd10be7e605f7d3aa1d Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 8 Nov 2020 19:13:32 +0100 Subject: rcar_gen3: drivers: console: Treat log as device memory The BL31 log driver is registered before the xlat tables are initialized, at that point the log memory is configured as device memory and can only be accessed with up-to-32bit aligned accesses. Adjust the driver to do just that. The memset() call has to be replaced by a loop of 32bit writes to the log, the memcpy() is trivial to replace with a single 32bit write of the entire TLOG word. In the end, this even simplifies the code. Signed-off-by: Marek Vasut Change-Id: Ie9152e782e67d93e7236069a294df812e2b873bf --- drivers/renesas/rcar/console/rcar_printf.c | 37 ++++++++++++++++++------------ 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/drivers/renesas/rcar/console/rcar_printf.c b/drivers/renesas/rcar/console/rcar_printf.c index e75b9f454..ad074fe05 100644 --- a/drivers/renesas/rcar/console/rcar_printf.c +++ b/drivers/renesas/rcar/console/rcar_printf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -19,11 +19,22 @@ #define INDEX_TIMER_COUNT (4U) +#define RCAR_LOG_HEAD (('T' << 0) | ('L' << 8) | ('O' << 16) | ('G' << 24)) + +/* + * The log is initialized and used before BL31 xlat tables are initialized, + * therefore the log memory is a device memory at that point. Make sure the + * memory is correclty aligned and accessed only with up-to 32bit, aligned, + * writes. + */ +CASSERT((RCAR_BL31_LOG_BASE & 0x7) == 0, assert_bl31_log_base_unaligned); +CASSERT((RCAR_BL31_LOG_MAX & 0x7) == 0, assert_bl31_log_max_unaligned); + extern RCAR_INSTANTIATE_LOCK typedef struct log_head { - uint8_t head[4]; + uint32_t head; uint32_t index; uint32_t size; - uint8_t res[4]; + uint32_t res; } loghead_t; typedef struct log_map { @@ -66,15 +77,12 @@ int32_t rcar_set_log_data(int32_t c) int32_t rcar_log_init(void) { - - static const uint8_t const_header[] = "TLOG"; - logmap_t *t_log; + logmap_t *t_log = (logmap_t *)RCAR_BL31_LOG_BASE; + uint32_t *log_data = (uint32_t *)t_log->log_data; int16_t init_flag = 0; + int i; - t_log = (logmap_t *) RCAR_BL31_LOG_BASE; - if (memcmp - ((const void *)t_log->header.head, (const void *)const_header, - sizeof(t_log->header.head)) != 0) { + if (t_log->header.head != RCAR_LOG_HEAD) { /* * Log header is not "TLOG", then log area initialize */ @@ -87,11 +95,10 @@ int32_t rcar_log_init(void) init_flag = 1; } if (init_flag == 1) { - (void)memset((void *)t_log->log_data, 0, - (size_t) RCAR_BL31_LOG_MAX); - (void)memcpy((void *)t_log->header.head, - (const void *)const_header, - sizeof(t_log->header.head)); + for (i = 0; i < RCAR_BL31_LOG_MAX; i += 4) + *log_data++ = 0; + + t_log->header.head = RCAR_LOG_HEAD; t_log->header.index = 0U; t_log->header.size = 0U; } -- cgit v1.2.3 From db2aeddc79337e499918328a0c5e80ff824042f5 Mon Sep 17 00:00:00 2001 From: Aditya Angadi Date: Wed, 18 Nov 2020 08:27:15 +0530 Subject: plat/arm/sgi: refactor the inclusion of memory mapping Upcoming RD platforms have a different memory map from those of the existing platforms. So make the build of the existing mmap entries to be usable only for existing platforms and let upcoming platforms define a different set of mmap entries. Change-Id: Id1ef0293efe8749c78a99237e78d32573c7233aa Signed-off-by: Aditya Angadi --- plat/arm/board/rddaniel/platform.mk | 2 ++ plat/arm/board/rddanielxlr/platform.mk | 2 ++ plat/arm/board/rde1edge/platform.mk | 2 ++ plat/arm/board/rdn1edge/platform.mk | 2 ++ plat/arm/board/sgi575/platform.mk | 2 ++ plat/arm/css/sgi/sgi-common.mk | 3 +-- 6 files changed, 11 insertions(+), 2 deletions(-) diff --git a/plat/arm/board/rddaniel/platform.mk b/plat/arm/board/rddaniel/platform.mk index 7422d638a..6553ae27e 100644 --- a/plat/arm/board/rddaniel/platform.mk +++ b/plat/arm/board/rddaniel/platform.mk @@ -14,6 +14,8 @@ PLAT_INCLUDES += -I${RDDANIEL_BASE}/include/ SGI_CPU_SOURCES := lib/cpus/aarch64/neoverse_v1.S +PLAT_BL_COMMON_SOURCES += ${CSS_ENT_BASE}/sgi_plat.c + BL1_SOURCES += ${SGI_CPU_SOURCES} \ ${RDDANIEL_BASE}/rddaniel_err.c diff --git a/plat/arm/board/rddanielxlr/platform.mk b/plat/arm/board/rddanielxlr/platform.mk index 8cbad525c..2f41e2e72 100644 --- a/plat/arm/board/rddanielxlr/platform.mk +++ b/plat/arm/board/rddanielxlr/platform.mk @@ -15,6 +15,8 @@ PLAT_INCLUDES += -I${RDDANIELXLR_BASE}/include/ SGI_CPU_SOURCES := lib/cpus/aarch64/neoverse_v1.S +PLAT_BL_COMMON_SOURCES += ${CSS_ENT_BASE}/sgi_plat.c + BL1_SOURCES += ${SGI_CPU_SOURCES} \ ${RDDANIELXLR_BASE}/rddanielxlr_err.c diff --git a/plat/arm/board/rde1edge/platform.mk b/plat/arm/board/rde1edge/platform.mk index a7c043413..53074f495 100644 --- a/plat/arm/board/rde1edge/platform.mk +++ b/plat/arm/board/rde1edge/platform.mk @@ -12,6 +12,8 @@ PLAT_INCLUDES += -I${RDE1EDGE_BASE}/include/ SGI_CPU_SOURCES := lib/cpus/aarch64/neoverse_e1.S +PLAT_BL_COMMON_SOURCES += ${CSS_ENT_BASE}/sgi_plat.c + BL1_SOURCES += ${SGI_CPU_SOURCES} \ ${RDE1EDGE_BASE}/rde1edge_err.c diff --git a/plat/arm/board/rdn1edge/platform.mk b/plat/arm/board/rdn1edge/platform.mk index b3134262e..d65854f8d 100644 --- a/plat/arm/board/rdn1edge/platform.mk +++ b/plat/arm/board/rdn1edge/platform.mk @@ -15,6 +15,8 @@ PLAT_INCLUDES += -I${RDN1EDGE_BASE}/include/ SGI_CPU_SOURCES := lib/cpus/aarch64/neoverse_n1.S +PLAT_BL_COMMON_SOURCES += ${CSS_ENT_BASE}/sgi_plat.c + BL1_SOURCES += ${SGI_CPU_SOURCES} \ ${RDN1EDGE_BASE}/rdn1edge_err.c diff --git a/plat/arm/board/sgi575/platform.mk b/plat/arm/board/sgi575/platform.mk index 56f5733f1..89abcfe8e 100644 --- a/plat/arm/board/sgi575/platform.mk +++ b/plat/arm/board/sgi575/platform.mk @@ -12,6 +12,8 @@ PLAT_INCLUDES += -I${SGI575_BASE}/include/ SGI_CPU_SOURCES := lib/cpus/aarch64/cortex_a75.S +PLAT_BL_COMMON_SOURCES += ${CSS_ENT_BASE}/sgi_plat.c + BL1_SOURCES += ${SGI_CPU_SOURCES} \ ${SGI575_BASE}/sgi575_err.c diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/css/sgi/sgi-common.mk index 6b9e0cda6..615f53dc9 100644 --- a/plat/arm/css/sgi/sgi-common.mk +++ b/plat/arm/css/sgi/sgi-common.mk @@ -32,8 +32,7 @@ ENT_GIC_SOURCES := ${GICV3_SOURCES} \ plat/common/plat_gicv3.c \ plat/arm/common/arm_gicv3.c -PLAT_BL_COMMON_SOURCES += ${CSS_ENT_BASE}/sgi_plat.c \ - ${CSS_ENT_BASE}/aarch64/sgi_helper.S +PLAT_BL_COMMON_SOURCES += ${CSS_ENT_BASE}/aarch64/sgi_helper.S BL1_SOURCES += ${INTERCONNECT_SOURCES} \ drivers/arm/sbsa/sbsa.c -- cgit v1.2.3 From 60f995fd98c9f5e81a0fe5b02999c5472f772c2e Mon Sep 17 00:00:00 2001 From: Aditya Angadi Date: Wed, 18 Nov 2020 08:32:30 +0530 Subject: plat/arm/sgi: refactor header file inclusions Upcoming RD platforms have deviations in various definitions of platform macros from that of the exisiting platforms. In preparation for adding support for those upcoming RD platforms, refactor the header file inclusion to allow newer platforms to use a different set of platform macros. Change-Id: Ic80283ddadafaa7f766f300652cb0d4e507efdb6 Signed-off-by: Aditya Angadi --- plat/arm/board/rddaniel/include/platform_def.h | 2 +- plat/arm/board/rddanielxlr/include/platform_def.h | 2 +- plat/arm/board/rddanielxlr/rddanielxlr_plat.c | 2 +- plat/arm/board/rde1edge/include/platform_def.h | 2 +- plat/arm/board/rdn1edge/include/platform_def.h | 2 +- plat/arm/board/rdn1edge/rdn1edge_plat.c | 2 +- plat/arm/board/sgi575/include/platform_def.h | 2 +- plat/arm/css/sgi/include/sgi_base_platform_def.h | 3 --- plat/arm/css/sgi/include/sgi_soc_platform_def.h | 15 +++++++++++++++ 9 files changed, 22 insertions(+), 10 deletions(-) create mode 100644 plat/arm/css/sgi/include/sgi_soc_platform_def.h diff --git a/plat/arm/board/rddaniel/include/platform_def.h b/plat/arm/board/rddaniel/include/platform_def.h index a118ca38a..5b98b4e8c 100644 --- a/plat/arm/board/rddaniel/include/platform_def.h +++ b/plat/arm/board/rddaniel/include/platform_def.h @@ -9,7 +9,7 @@ #include -#include +#include #define PLAT_ARM_CLUSTER_COUNT U(16) #define CSS_SGI_MAX_CPUS_PER_CLUSTER U(1) diff --git a/plat/arm/board/rddanielxlr/include/platform_def.h b/plat/arm/board/rddanielxlr/include/platform_def.h index b1376b85d..112b2102b 100644 --- a/plat/arm/board/rddanielxlr/include/platform_def.h +++ b/plat/arm/board/rddanielxlr/include/platform_def.h @@ -8,7 +8,7 @@ #define PLATFORM_DEF_H #include -#include +#include #define PLAT_ARM_CLUSTER_COUNT U(4) #define CSS_SGI_MAX_CPUS_PER_CLUSTER U(1) diff --git a/plat/arm/board/rddanielxlr/rddanielxlr_plat.c b/plat/arm/board/rddanielxlr/rddanielxlr_plat.c index 4b5f16a4f..a1a4876c0 100644 --- a/plat/arm/board/rddanielxlr/rddanielxlr_plat.c +++ b/plat/arm/board/rddanielxlr/rddanielxlr_plat.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #if defined(IMAGE_BL31) diff --git a/plat/arm/board/rde1edge/include/platform_def.h b/plat/arm/board/rde1edge/include/platform_def.h index 3fb640972..c39fe2b69 100644 --- a/plat/arm/board/rde1edge/include/platform_def.h +++ b/plat/arm/board/rde1edge/include/platform_def.h @@ -9,7 +9,7 @@ #include -#include +#include #define PLAT_ARM_CLUSTER_COUNT U(2) #define CSS_SGI_MAX_CPUS_PER_CLUSTER U(8) diff --git a/plat/arm/board/rdn1edge/include/platform_def.h b/plat/arm/board/rdn1edge/include/platform_def.h index ab63e23ec..b167c46e0 100644 --- a/plat/arm/board/rdn1edge/include/platform_def.h +++ b/plat/arm/board/rdn1edge/include/platform_def.h @@ -9,7 +9,7 @@ #include -#include +#include #define PLAT_ARM_CLUSTER_COUNT U(2) #define CSS_SGI_MAX_CPUS_PER_CLUSTER U(4) diff --git a/plat/arm/board/rdn1edge/rdn1edge_plat.c b/plat/arm/board/rdn1edge/rdn1edge_plat.c index f62c6f402..1dbbf26da 100644 --- a/plat/arm/board/rdn1edge/rdn1edge_plat.c +++ b/plat/arm/board/rdn1edge/rdn1edge_plat.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #if defined(IMAGE_BL31) diff --git a/plat/arm/board/sgi575/include/platform_def.h b/plat/arm/board/sgi575/include/platform_def.h index 95986cf4a..c929334cd 100644 --- a/plat/arm/board/sgi575/include/platform_def.h +++ b/plat/arm/board/sgi575/include/platform_def.h @@ -9,7 +9,7 @@ #include -#include +#include #define PLAT_ARM_CLUSTER_COUNT U(2) #define CSS_SGI_MAX_CPUS_PER_CLUSTER U(4) 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 159084f95..b805746de 100644 --- a/plat/arm/css/sgi/include/sgi_base_platform_def.h +++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h @@ -9,12 +9,9 @@ #include #include -#include -#include #include #include #include -#include #include #define PLATFORM_CORE_COUNT (CSS_SGI_CHIP_COUNT * \ diff --git a/plat/arm/css/sgi/include/sgi_soc_platform_def.h b/plat/arm/css/sgi/include/sgi_soc_platform_def.h new file mode 100644 index 000000000..d7a839a52 --- /dev/null +++ b/plat/arm/css/sgi/include/sgi_soc_platform_def.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SGI_SOC_PLATFORM_DEF_H +#define SGI_SOC_PLATFORM_DEF_H + +#include +#include +#include +#include + +#endif /* SGI_SOC_PLATFORM_DEF_H */ -- cgit v1.2.3 From 284efb16b4c95d638198863cdf3a310dcd9ec144 Mon Sep 17 00:00:00 2001 From: Aditya Angadi Date: Tue, 17 Nov 2020 21:17:58 +0530 Subject: plat/arm/sgi: platform definitions for upcoming platforms Upcoming RD platforms have changes in the SOC address map from that of the existing platforms. As a prepartory step to add support for the upcoming platforms, create platform definitions for those platforms. Change-Id: Ic5df9fed02c44e65ec260bbb5efc1b8dbd919a56 Signed-off-by: Aditya Angadi --- plat/arm/css/sgi/include/sgi_soc_css_def_v2.h | 194 +++++++++++++++++++++ plat/arm/css/sgi/include/sgi_soc_platform_def_v2.h | 13 ++ 2 files changed, 207 insertions(+) create mode 100644 plat/arm/css/sgi/include/sgi_soc_css_def_v2.h create mode 100644 plat/arm/css/sgi/include/sgi_soc_platform_def_v2.h diff --git a/plat/arm/css/sgi/include/sgi_soc_css_def_v2.h b/plat/arm/css/sgi/include/sgi_soc_css_def_v2.h new file mode 100644 index 000000000..03f107367 --- /dev/null +++ b/plat/arm/css/sgi/include/sgi_soc_css_def_v2.h @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SGI_SOC_CSS_DEF_V2_H +#define SGI_SOC_CSS_DEF_V2_H + +#include +#include + +/* + * Definitions common to all ARM CSS SoCs + */ + +/* Following covers ARM CSS SoC Peripherals */ + +#define SOC_SYSTEM_PERIPH_BASE UL(0x0C000000) +#define SOC_SYSTEM_PERIPH_SIZE UL(0x02000000) + +#define SOC_PLATFORM_PERIPH_BASE UL(0x0E000000) +#define SOC_PLATFORM_PERIPH_SIZE UL(0x02000000) + +#define SOC_CSS_PCIE_CONTROL_BASE UL(0x0ef20000) + +/* PL011 UART related constants */ +#define SOC_CSS_UART1_BASE UL(0x0ef80000) +#define SOC_CSS_UART0_BASE UL(0x0ef70000) + +/* Memory controller */ +#define SOC_MEMCNTRL_BASE UL(0x10000000) +#define SOC_MEMCNTRL_SIZE UL(0x10000000) + +#define SOC_CSS_UART0_CLK_IN_HZ UL(7372800) +#define SOC_CSS_UART1_CLK_IN_HZ UL(7372800) + +/* SoC NIC-400 Global Programmers View (GPV) */ +#define SOC_CSS_NIC400_BASE UL(0x0ED00000) + +#define SOC_CSS_NIC400_USB_EHCI U(0) +#define SOC_CSS_NIC400_TLX_MASTER U(1) +#define SOC_CSS_NIC400_USB_OHCI U(2) +#define SOC_CSS_NIC400_PL354_SMC U(3) +/* + * The apb4_bridge controls access to: + * - the PCIe configuration registers + * - the MMU units for USB, HDLCD and DMA + */ +#define SOC_CSS_NIC400_APB4_BRIDGE U(4) + +/* Non-volatile counters */ +#define SOC_TRUSTED_NVCTR_BASE UL(0x0EE70000) +#define TFW_NVCTR_BASE (SOC_TRUSTED_NVCTR_BASE + 0x0000) +#define TFW_NVCTR_SIZE U(4) +#define NTFW_CTR_BASE (SOC_TRUSTED_NVCTR_BASE + 0x0004) +#define NTFW_CTR_SIZE U(4) + +/* Keys */ +#define SOC_KEYS_BASE UL(0x0EE80000) +#define TZ_PUB_KEY_HASH_BASE (SOC_KEYS_BASE + 0x0000) +#define TZ_PUB_KEY_HASH_SIZE U(32) +#define HU_KEY_BASE (SOC_KEYS_BASE + 0x0020) +#define HU_KEY_SIZE U(16) +#define END_KEY_BASE (SOC_KEYS_BASE + 0x0044) +#define END_KEY_SIZE U(32) + +#define SOC_PLATFORM_PERIPH_MAP_DEVICE MAP_REGION_FLAT( \ + SOC_PLATFORM_PERIPH_BASE, \ + SOC_PLATFORM_PERIPH_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#define SOC_SYSTEM_PERIPH_MAP_DEVICE MAP_REGION_FLAT( \ + SOC_SYSTEM_PERIPH_BASE, \ + SOC_SYSTEM_PERIPH_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#define SOC_MEMCNTRL_MAP_DEVICE MAP_REGION_FLAT( \ + SOC_MEMCNTRL_BASE, \ + SOC_MEMCNTRL_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +/* + * The bootsec_bridge controls access to a bunch of peripherals, e.g. the UARTs. + */ +#define SOC_CSS_NIC400_BOOTSEC_BRIDGE U(5) +#define SOC_CSS_NIC400_BOOTSEC_BRIDGE_UART1 UL(1 << 12) + +/* + * Required platform porting definitions common to all ARM CSS SoCs + */ +/* 2MB used for SCP DDR retraining */ +#define PLAT_ARM_SCP_TZC_DRAM1_SIZE UL(0x00200000) + +/* V2M motherboard system registers & offsets */ +#define V2M_SYSREGS_BASE UL(0x0C010000) +#define V2M_SYS_LED U(0x8) + +/* + * V2M sysled bit definitions. The values written to this + * register are defined in arch.h & runtime_svc.h. Only + * used by the primary cpu to diagnose any cold boot issues. + * + * SYS_LED[0] - Security state (S=0/NS=1) + * SYS_LED[2:1] - Exception Level (EL3-EL0) + * SYS_LED[7:3] - Exception Class (Sync/Async & origin) + * + */ +#define V2M_SYS_LED_SS_SHIFT U(0) +#define V2M_SYS_LED_EL_SHIFT U(1) +#define V2M_SYS_LED_EC_SHIFT U(3) + +#define V2M_SYS_LED_SS_MASK U(0x01) +#define V2M_SYS_LED_EL_MASK U(0x03) +#define V2M_SYS_LED_EC_MASK U(0x1f) + +/* NOR Flash */ +#define V2M_FLASH0_BASE UL(0x08000000) +#define V2M_FLASH0_SIZE UL(0x04000000) +#define V2M_FLASH_BLOCK_SIZE UL(0x00040000) /* 256 KB */ + +/* + * The flash can be mapped either as read-only or read-write. + * + * If it is read-write then it should also be mapped as device memory because + * NOR flash programming involves sending a fixed, ordered sequence of commands. + * + * If it is read-only then it should also be mapped as: + * - Normal memory, because reading from NOR flash is transparent, it is like + * reading from RAM. + * - Non-executable by default. If some parts of the flash need to be executable + * then platform code is responsible for re-mapping the appropriate portion + * of it as executable. + */ +#define V2M_MAP_FLASH0_RW MAP_REGION_FLAT(V2M_FLASH0_BASE,\ + V2M_FLASH0_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#define V2M_MAP_FLASH0_RO MAP_REGION_FLAT(V2M_FLASH0_BASE,\ + V2M_FLASH0_SIZE, \ + MT_RO_DATA | MT_SECURE) + +#define SGI_MAP_FLASH0_RO MAP_REGION_FLAT(V2M_FLASH0_BASE,\ + V2M_FLASH0_SIZE, \ + MT_DEVICE | MT_RO | MT_SECURE) + +/* Platform ID address */ +#define BOARD_CSS_PLAT_ID_REG_ADDR UL(0x0EFE00E0) + +/* Platform ID related accessors */ +#define BOARD_CSS_PLAT_ID_REG_ID_MASK U(0x0F) +#define BOARD_CSS_PLAT_ID_REG_ID_SHIFT U(0x00) +#define BOARD_CSS_PLAT_ID_REG_VERSION_MASK U(0xF00) +#define BOARD_CSS_PLAT_ID_REG_VERSION_SHIFT U(0x08) +#define BOARD_CSS_PLAT_TYPE_RTL U(0x00) +#define BOARD_CSS_PLAT_TYPE_FPGA U(0x01) +#define BOARD_CSS_PLAT_TYPE_EMULATOR U(0x02) +#define BOARD_CSS_PLAT_TYPE_FVP U(0x03) + +#ifndef __ASSEMBLER__ + +#include + +#define BOARD_CSS_GET_PLAT_TYPE(addr) \ + ((mmio_read_32(addr) & BOARD_CSS_PLAT_ID_REG_ID_MASK) \ + >> BOARD_CSS_PLAT_ID_REG_ID_SHIFT) + +#endif /* __ASSEMBLER__ */ + + +#define MAX_IO_DEVICES U(3) +#define MAX_IO_HANDLES U(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) + +/* UART related constants */ +#define PLAT_ARM_BOOT_UART_BASE SOC_CSS_UART0_BASE +#define PLAT_ARM_BOOT_UART_CLK_IN_HZ SOC_CSS_UART0_CLK_IN_HZ + +#define PLAT_ARM_RUN_UART_BASE SOC_CSS_UART1_BASE +#define PLAT_ARM_RUN_UART_CLK_IN_HZ SOC_CSS_UART1_CLK_IN_HZ + +#define PLAT_ARM_SP_MIN_RUN_UART_BASE SOC_CSS_UART1_BASE +#define PLAT_ARM_SP_MIN_RUN_UART_CLK_IN_HZ SOC_CSS_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 + +#endif /* SGI_SOC_CSS_DEF_V2_H */ diff --git a/plat/arm/css/sgi/include/sgi_soc_platform_def_v2.h b/plat/arm/css/sgi/include/sgi_soc_platform_def_v2.h new file mode 100644 index 000000000..cb747c34a --- /dev/null +++ b/plat/arm/css/sgi/include/sgi_soc_platform_def_v2.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SGI_SOC_PLATFORM_DEF_V2_H +#define SGI_SOC_PLATFORM_DEF_V2_H + +#include +#include + +#endif /* SGI_SOC_PLATFORM_DEF_V2_H */ -- cgit v1.2.3 From 1b19ad68479a439623b24b3a7e9cab7251d33cd1 Mon Sep 17 00:00:00 2001 From: Aditya Angadi Date: Thu, 19 Nov 2020 17:18:21 +0530 Subject: plat/arm/sgi: add platform id value for rdn2 platform In preparation for adding the board support for RD-N2 platform, add macros to define the platform id and the corresponding SCMI platform info for the RD-N2 platform. Change-Id: Ie764ae618732b39e316f7ed080421f5d79adab21 Signed-off-by: Aditya Angadi --- plat/arm/css/sgi/include/sgi_variant.h | 3 +++ plat/arm/css/sgi/sgi_bl31_setup.c | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/plat/arm/css/sgi/include/sgi_variant.h b/plat/arm/css/sgi/include/sgi_variant.h index f4c5300d0..eb12f3f35 100644 --- a/plat/arm/css/sgi/include/sgi_variant.h +++ b/plat/arm/css/sgi/include/sgi_variant.h @@ -17,6 +17,9 @@ /* SID Version values for RD-Daniel */ #define RD_DANIEL_SID_VER_PART_NUM 0x078a +/* SID Version values for RD-N2 */ +#define RD_N2_SID_VER_PART_NUM 0x07B7 + /* Structure containing SGI platform variant information */ typedef struct sgi_platform_info { unsigned int platform_id; /* Part Number of the platform */ diff --git a/plat/arm/css/sgi/sgi_bl31_setup.c b/plat/arm/css/sgi/sgi_bl31_setup.c index a4aed004d..d5c7593f6 100644 --- a/plat/arm/css/sgi/sgi_bl31_setup.c +++ b/plat/arm/css/sgi/sgi_bl31_setup.c @@ -74,7 +74,8 @@ static scmi_channel_plat_info_t rd_n1e1_edge_scmi_plat_info[] = { scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id) { if (sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM || - sgi_plat_info.platform_id == RD_DANIEL_SID_VER_PART_NUM) { + sgi_plat_info.platform_id == RD_DANIEL_SID_VER_PART_NUM || + sgi_plat_info.platform_id == RD_N2_SID_VER_PART_NUM) { if (channel_id >= ARRAY_SIZE(rd_n1e1_edge_scmi_plat_info)) panic(); return &rd_n1e1_edge_scmi_plat_info[channel_id]; -- cgit v1.2.3 From 6bb9f7a1abae75f120dff90d9e4132a64ba88811 Mon Sep 17 00:00:00 2001 From: Aditya Angadi Date: Thu, 19 Nov 2020 17:32:41 +0530 Subject: plat/arm/sgi: adapt to changes in memory map Upcoming RD platforms will have an updated memory map for the various pheripherals on the system. So, for the newer platforms, handle the memory mapping and other platform specific functionality separately from the existing platforms. Change-Id: Iab1355a4c8ea1f6db4f79fcdd6eed907903b6a18 Signed-off-by: Aditya Angadi --- plat/arm/css/sgi/sgi_plat_v2.c | 85 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 plat/arm/css/sgi/sgi_plat_v2.c diff --git a/plat/arm/css/sgi/sgi_plat_v2.c b/plat/arm/css/sgi/sgi_plat_v2.c new file mode 100644 index 000000000..a770255fc --- /dev/null +++ b/plat/arm/css/sgi/sgi_plat_v2.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include + +#include +#include +#include + +/* + * Table of regions for different BL stages to map using the MMU. + */ +#if IMAGE_BL1 +const mmap_region_t plat_arm_mmap[] = { + ARM_MAP_SHARED_RAM, + SGI_MAP_FLASH0_RO, + CSS_SGI_MAP_DEVICE, + SOC_PLATFORM_PERIPH_MAP_DEVICE, + SOC_SYSTEM_PERIPH_MAP_DEVICE, + {0} +}; +#endif + +#if IMAGE_BL2 +const mmap_region_t plat_arm_mmap[] = { + ARM_MAP_SHARED_RAM, + SGI_MAP_FLASH0_RO, +#ifdef PLAT_ARM_MEM_PROT_ADDR + ARM_V2M_MAP_MEM_PROTECT, +#endif + CSS_SGI_MAP_DEVICE, + SOC_MEMCNTRL_MAP_DEVICE, + SOC_PLATFORM_PERIPH_MAP_DEVICE, + SOC_SYSTEM_PERIPH_MAP_DEVICE, + ARM_MAP_NS_DRAM1, +#if ARM_BL31_IN_DRAM + ARM_MAP_BL31_SEC_DRAM, +#endif +#if TRUSTED_BOARD_BOOT && !BL2_AT_EL3 + ARM_MAP_BL1_RW, +#endif + {0} +}; +#endif + +#if IMAGE_BL31 +const mmap_region_t plat_arm_mmap[] = { + ARM_MAP_SHARED_RAM, +#ifdef PLAT_ARM_MEM_PROT_ADDR + ARM_V2M_MAP_MEM_PROTECT, +#endif + CSS_SGI_MAP_DEVICE, + SOC_PLATFORM_PERIPH_MAP_DEVICE, + SOC_SYSTEM_PERIPH_MAP_DEVICE, + {0} +}; + +#endif + +ARM_CASSERT_MMAP + +#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 plat_arm_secure_wdt_start(void) +{ + sbsa_wdog_start(SBSA_SECURE_WDOG_BASE, SBSA_SECURE_WDOG_TIMEOUT); +} + +void plat_arm_secure_wdt_stop(void) +{ + sbsa_wdog_stop(SBSA_SECURE_WDOG_BASE); +} -- cgit v1.2.3 From 34e443e21d30e2d3c4f0ac9d41625bdc064eed02 Mon Sep 17 00:00:00 2001 From: Aditya Angadi Date: Thu, 19 Nov 2020 18:05:33 +0530 Subject: board/rdn2: add board support for rdn2 platform Add the initial board support for RD-N2 platform. Change-Id: I8325885bf248dd92191d6fc92a2da91c23118f8c Signed-off-by: Aditya Angadi --- plat/arm/board/rdn2/fdts/rdn2_fw_config.dts | 27 +++++++++++ plat/arm/board/rdn2/fdts/rdn2_nt_fw_config.dts | 22 +++++++++ plat/arm/board/rdn2/fdts/rdn2_tb_fw_config.dts | 28 +++++++++++ plat/arm/board/rdn2/include/platform_def.h | 65 ++++++++++++++++++++++++++ plat/arm/board/rdn2/platform.mk | 59 +++++++++++++++++++++++ plat/arm/board/rdn2/rdn2_err.c | 17 +++++++ plat/arm/board/rdn2/rdn2_plat.c | 31 ++++++++++++ plat/arm/board/rdn2/rdn2_security.c | 25 ++++++++++ plat/arm/board/rdn2/rdn2_topology.c | 62 ++++++++++++++++++++++++ plat/arm/board/rdn2/rdn2_trusted_boot.c | 26 +++++++++++ 10 files changed, 362 insertions(+) create mode 100644 plat/arm/board/rdn2/fdts/rdn2_fw_config.dts create mode 100644 plat/arm/board/rdn2/fdts/rdn2_nt_fw_config.dts create mode 100644 plat/arm/board/rdn2/fdts/rdn2_tb_fw_config.dts create mode 100644 plat/arm/board/rdn2/include/platform_def.h create mode 100644 plat/arm/board/rdn2/platform.mk create mode 100644 plat/arm/board/rdn2/rdn2_err.c create mode 100644 plat/arm/board/rdn2/rdn2_plat.c create mode 100644 plat/arm/board/rdn2/rdn2_security.c create mode 100644 plat/arm/board/rdn2/rdn2_topology.c create mode 100644 plat/arm/board/rdn2/rdn2_trusted_boot.c diff --git a/plat/arm/board/rdn2/fdts/rdn2_fw_config.dts b/plat/arm/board/rdn2/fdts/rdn2_fw_config.dts new file mode 100644 index 000000000..9c9cefe87 --- /dev/null +++ b/plat/arm/board/rdn2/fdts/rdn2_fw_config.dts @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +/dts-v1/; + +/ { + dtb-registry { + compatible = "fconf,dyn_cfg-dtb_registry"; + + tb_fw-config { + load-address = <0x0 0x4001300>; + max-size = <0x200>; + id = ; + }; + + nt_fw-config { + load-address = <0x0 0xFEF00000>; + max-size = <0x0100000>; + id = ; + }; + }; +}; diff --git a/plat/arm/board/rdn2/fdts/rdn2_nt_fw_config.dts b/plat/arm/board/rdn2/fdts/rdn2_nt_fw_config.dts new file mode 100644 index 000000000..bbc36fc14 --- /dev/null +++ b/plat/arm/board/rdn2/fdts/rdn2_nt_fw_config.dts @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; +/ { + /* compatible string */ + compatible = "arm,rd-n2"; + + /* + * Place holder for system-id node with default values. The + * value of platform-id and config-id will be set to the + * correct values during the BL2 stage of boot. + */ + system-id { + platform-id = <0x0>; + config-id = <0x0>; + multi-chip-mode = <0x0>; + }; +}; diff --git a/plat/arm/board/rdn2/fdts/rdn2_tb_fw_config.dts b/plat/arm/board/rdn2/fdts/rdn2_tb_fw_config.dts new file mode 100644 index 000000000..49eda2735 --- /dev/null +++ b/plat/arm/board/rdn2/fdts/rdn2_tb_fw_config.dts @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +/ { + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + + /* + * The following two entries are placeholders for Mbed TLS + * heap information. The default values don't matter since + * they will be overwritten by BL1. + * In case of having shared Mbed TLS heap between BL1 and BL2, + * BL1 will populate these two properties with the respective + * info about the shared heap. This info will be available for + * BL2 in order to locate and re-use the heap. + */ + mbedtls_heap_addr = <0x0 0x0>; + mbedtls_heap_size = <0x0>; + }; +}; diff --git a/plat/arm/board/rdn2/include/platform_def.h b/plat/arm/board/rdn2/include/platform_def.h new file mode 100644 index 000000000..ebfbf66a6 --- /dev/null +++ b/plat/arm/board/rdn2/include/platform_def.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +#include + +#include + +#define PLAT_ARM_CLUSTER_COUNT U(16) +#define CSS_SGI_MAX_CPUS_PER_CLUSTER U(1) +#define CSS_SGI_MAX_PE_PER_CPU U(1) + +#define PLAT_CSS_MHU_BASE UL(0x2A920000) +#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE + +#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL2 +#define PLAT_MAX_PWR_LVL ARM_PWR_LVL1 + +/* TZC Related Constants */ +#define PLAT_ARM_TZC_BASE UL(0x10820000) +#define PLAT_ARM_TZC_FILTERS TZC_400_REGION_ATTR_FILTER_BIT(0) + +#define TZC400_OFFSET UL(0x1000000) +#define TZC400_COUNT U(8) + +#define TZC400_BASE(n) (PLAT_ARM_TZC_BASE + \ + (n * TZC400_OFFSET)) + +#define TZC_NSAID_ALL_AP U(0) +#define TZC_NSAID_PCI U(1) +#define TZC_NSAID_HDLCD0 U(2) +#define TZC_NSAID_CLCD U(7) +#define TZC_NSAID_AP U(9) +#define TZC_NSAID_VIRTIO U(15) + +#define PLAT_ARM_TZC_NS_DEV_ACCESS \ + (TZC_REGION_ACCESS_RDWR(TZC_NSAID_ALL_AP)) | \ + (TZC_REGION_ACCESS_RDWR(TZC_NSAID_HDLCD0)) | \ + (TZC_REGION_ACCESS_RDWR(TZC_NSAID_PCI)) | \ + (TZC_REGION_ACCESS_RDWR(TZC_NSAID_AP)) | \ + (TZC_REGION_ACCESS_RDWR(TZC_NSAID_CLCD)) | \ + (TZC_REGION_ACCESS_RDWR(TZC_NSAID_VIRTIO)) + +/* + * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes + */ +#ifdef __aarch64__ +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 42) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 42) +#else +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) +#endif + +/* GIC related constants */ +#define PLAT_ARM_GICD_BASE UL(0x30000000) +#define PLAT_ARM_GICC_BASE UL(0x2C000000) +#define PLAT_ARM_GICR_BASE UL(0x30140000) + +#endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/rdn2/platform.mk b/plat/arm/board/rdn2/platform.mk new file mode 100644 index 000000000..6be611360 --- /dev/null +++ b/plat/arm/board/rdn2/platform.mk @@ -0,0 +1,59 @@ +# Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# RD-N2 platform uses GIC-Clayton which is based on GICv4.1 +GIC_ENABLE_V4_EXTN := 1 + +include plat/arm/css/sgi/sgi-common.mk + +RDN2_BASE = plat/arm/board/rdn2 + +PLAT_INCLUDES += -I${RDN2_BASE}/include/ + +SGI_CPU_SOURCES := lib/cpus/aarch64/neoverse_n2.S + +PLAT_BL_COMMON_SOURCES += ${CSS_ENT_BASE}/sgi_plat_v2.c + +BL1_SOURCES += ${SGI_CPU_SOURCES} \ + ${RDN2_BASE}/rdn2_err.c + +BL2_SOURCES += ${RDN2_BASE}/rdn2_plat.c \ + ${RDN2_BASE}/rdn2_security.c \ + ${RDN2_BASE}/rdn2_err.c \ + lib/utils/mem_region.c \ + drivers/arm/tzc/tzc400.c \ + plat/arm/common/arm_tzc400.c \ + plat/arm/common/arm_nor_psci_mem_protect.c + +BL31_SOURCES += ${SGI_CPU_SOURCES} \ + ${RDN2_BASE}/rdn2_plat.c \ + ${RDN2_BASE}/rdn2_topology.c \ + drivers/cfi/v2m/v2m_flash.c \ + lib/utils/mem_region.c \ + plat/arm/common/arm_nor_psci_mem_protect.c + +ifeq (${TRUSTED_BOARD_BOOT}, 1) +BL1_SOURCES += ${RDN2_BASE}/rdn2_trusted_boot.c +BL2_SOURCES += ${RDN2_BASE}/rdn2_trusted_boot.c +endif + +# Add the FDT_SOURCES and options for Dynamic Config +FDT_SOURCES += ${RDN2_BASE}/fdts/${PLAT}_fw_config.dts \ + ${RDN2_BASE}/fdts/${PLAT}_tb_fw_config.dts +FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb + +# Add the FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG})) +# Add the TB_FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG})) + +FDT_SOURCES += ${RDN2_BASE}/fdts/${PLAT}_nt_fw_config.dts +NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb + +# Add the NT_FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config)) + +override CTX_INCLUDE_AARCH32_REGS := 0 diff --git a/plat/arm/board/rdn2/rdn2_err.c b/plat/arm/board/rdn2/rdn2_err.c new file mode 100644 index 000000000..802ac21f6 --- /dev/null +++ b/plat/arm/board/rdn2/rdn2_err.c @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +/* + * rdn2 error handler + */ +void __dead2 plat_arm_error_handler(int err) +{ + while (1) { + wfi(); + } +} diff --git a/plat/arm/board/rdn2/rdn2_plat.c b/plat/arm/board/rdn2/rdn2_plat.c new file mode 100644 index 000000000..5bf14e3a1 --- /dev/null +++ b/plat/arm/board/rdn2/rdn2_plat.c @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +unsigned int plat_arm_sgi_get_platform_id(void) +{ + return mmio_read_32(SID_REG_BASE + SID_SYSTEM_ID_OFFSET) + & SID_SYSTEM_ID_PART_NUM_MASK; +} + +unsigned int plat_arm_sgi_get_config_id(void) +{ + return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET); +} + +unsigned int plat_arm_sgi_get_multi_chip_mode(void) +{ + return (mmio_read_32(SID_REG_BASE + SID_NODE_ID_OFFSET) & + SID_MULTI_CHIP_MODE_MASK) >> + SID_MULTI_CHIP_MODE_SHIFT; +} + +void bl31_platform_setup(void) +{ + sgi_bl31_common_platform_setup(); +} diff --git a/plat/arm/board/rdn2/rdn2_security.c b/plat/arm/board/rdn2/rdn2_security.c new file mode 100644 index 000000000..9568b60cd --- /dev/null +++ b/plat/arm/board/rdn2/rdn2_security.c @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + + +static const arm_tzc_regions_info_t tzc_regions[] = { + ARM_TZC_REGIONS_DEF, + {} +}; + +/* Initialize the secure environment */ +void plat_arm_security_setup(void) +{ + + int i; + + for (i = 0; i < TZC400_COUNT; i++) + arm_tzc400_setup(TZC400_BASE(i), tzc_regions); + +} diff --git a/plat/arm/board/rdn2/rdn2_topology.c b/plat/arm/board/rdn2/rdn2_topology.c new file mode 100644 index 000000000..5c2e287cb --- /dev/null +++ b/plat/arm/board/rdn2/rdn2_topology.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +/****************************************************************************** + * The power domain tree descriptor. + ******************************************************************************/ +const unsigned char rd_n2_pd_tree_desc[] = { + PLAT_ARM_CLUSTER_COUNT, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, +}; + +/******************************************************************************* + * This function returns the topology tree information. + ******************************************************************************/ +const unsigned char *plat_get_power_domain_tree_desc(void) +{ + return rd_n2_pd_tree_desc; +} + +/******************************************************************************* + * The array mapping platform core position (implemented by plat_my_core_pos()) + * to the SCMI power domain ID implemented by SCP. + ******************************************************************************/ +const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = { + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x0)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x1)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x2)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x3)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x4)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x5)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x6)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x7)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x8)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x9)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xA)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xB)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xC)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xD)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xE)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xF)), +}; diff --git a/plat/arm/board/rdn2/rdn2_trusted_boot.c b/plat/arm/board/rdn2/rdn2_trusted_boot.c new file mode 100644 index 000000000..4592b8fba --- /dev/null +++ b/plat/arm/board/rdn2/rdn2_trusted_boot.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#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); +} -- cgit v1.2.3 From 7b24e48a46b47b2b37c0b0c4458d4ce515487e36 Mon Sep 17 00:00:00 2001 From: Aditya Angadi Date: Tue, 8 Dec 2020 13:35:27 +0530 Subject: doc: Update list of supported FVP platforms Updated the list of supported FVP platforms with support for RD-N2 FVP. Change-Id: I861bbb6d520c20e718f072e118c66dab61fe1386 Signed-off-by: Aditya Angadi --- docs/plat/arm/fvp/index.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/plat/arm/fvp/index.rst b/docs/plat/arm/fvp/index.rst index 3a13268fa..f643f6b00 100644 --- a/docs/plat/arm/fvp/index.rst +++ b/docs/plat/arm/fvp/index.rst @@ -50,6 +50,7 @@ Arm FVPs without shifted affinities, and that do not support threaded CPU cores - ``FVP_RD_N1_edge`` (Version 11.10 build 36) - ``FVP_RD_N1_edge_dual`` (Version 11.10 build 36) - ``FVP_RD_Daniel`` (Version 11.10 build 36) +- ``FVP_RD_N2`` (Version 11.13 build 10) - ``FVP_TC0`` (Version 0.0 build 6114) - ``Foundation_Platform`` -- cgit v1.2.3 From 745da67b27d75606f6f52c019711c882ee86a137 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Wed, 25 Nov 2020 21:08:40 +0000 Subject: docs: Update the FIP generation process using SP images Updated the documentation for the FIP generation process using SP images. Change-Id: I4df7f379f08f33adba6f5c82904291576972e106 Signed-off-by: Manish V Badarkhe --- .../diagrams/plantuml/fip-secure-partitions.puml | 95 ++++++++++++++++------ 1 file changed, 70 insertions(+), 25 deletions(-) diff --git a/docs/resources/diagrams/plantuml/fip-secure-partitions.puml b/docs/resources/diagrams/plantuml/fip-secure-partitions.puml index 40621dbed..9457e326a 100644 --- a/docs/resources/diagrams/plantuml/fip-secure-partitions.puml +++ b/docs/resources/diagrams/plantuml/fip-secure-partitions.puml @@ -13,6 +13,7 @@ folder SP_vendor_1 { === UUID = xxx load_address = 0xaaa + owner = "Sip" ... ] } @@ -24,9 +25,26 @@ folder SP_vendor_2 { === UUID = yyy load_address = 0xbbb + owner = "Plat" ] } +artifact tb_fw_config.dts [ + tb_fw_config.dts + ---- + secure-partitions + === + spkg_1 UUID + spkg_1 load_address + --- + spkg_2 UUID + spkg_2 load_address + --- + ... + === + ... +] + artifact config.json [ SP_LAYOUT.json === @@ -41,31 +59,22 @@ artifact config.json [ control sp_mk_generator -artifact fconf_node [ - fconf_sp.dts - === - spkg_1 UUID - spkg_1 load_address - --- - spkg_2 UUID - spkg_2 load_address -] - artifact sp_gen [ sp_gen.mk === FDT_SOURCE = ... SPTOOL_ARGS = ... - FIP_ARG = ... + FIP_ARGS = ... + CRT_ARGS = ... ] control dtc control sptool -artifact FW_CONFIG +artifact tb_fw_config.dtb artifact spkg_1 [ - spkg_1.bin + sp1.pkg === header --- @@ -75,27 +84,56 @@ artifact spkg_1 [ ] artifact spkg_2 [ - spkg_2.bin + sp2.pkg + === + header + --- + manifest + --- + binary +] + +artifact signed_tb_fw_config.dtb [ + tb_fw_config.dtb (signed) +] + +artifact signed_spkg_1 [ + sp1.pkg (signed) + === + header + --- + manifest + --- + binary + --- + signature +] + +artifact signed_spkg_2 [ + sp2.pkg (signed) === header --- manifest --- binary + --- + signature ] +control crttool control fiptool artifact fip [ fip.bin === - FW_CONFIG.dtb + tb_fw_config.dtb (signed) --- ... --- - SPKG1 + sp1.pkg (signed & SiP owned) --- - SPKG2 + sp2.pkg (signed & Platform owned) --- ... ] @@ -103,20 +141,27 @@ artifact fip [ config.json .up.> SP_vendor_1 config.json .up.> SP_vendor_2 config.json --> sp_mk_generator -sp_mk_generator --> fconf_node sp_mk_generator --> sp_gen - +sp_gen --> fiptool +sp_gen --> cert_create sp_gen --> sptool + sptool --> spkg_1 sptool --> spkg_2 -fconf_node -down-> dtc -dtc --> FW_CONFIG +spkg_1 --> cert_create +spkg_2 --> cert_create +cert_create --> signed_spkg_1 +cert_create --> signed_spkg_2 -sp_gen --> fiptool -FW_CONFIG --> fiptool -spkg_1 -down-> fiptool -spkg_2 -down-> fiptool +tb_fw_config.dts --> dtc +dtc --> tb_fw_config.dtb +tb_fw_config.dtb --> cert_create +cert_create --> signed_tb_fw_config.dtb + +signed_tb_fw_config.dtb --> fiptool +signed_spkg_1 -down-> fiptool +signed_spkg_2 -down-> fiptool fiptool -down-> fip @enduml -- cgit v1.2.3 From a82b5f70fb64c9ff0590a53f24ce94d6bb6111e4 Mon Sep 17 00:00:00 2001 From: Manish Pandey Date: Thu, 10 Dec 2020 10:48:22 +0000 Subject: xilinx: versal: fix static failure Signed-off-by: Manish Pandey Change-Id: Icef550072296d6aba89a0827dd72d0b86047556f --- plat/xilinx/versal/pm_service/pm_api_sys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.c b/plat/xilinx/versal/pm_service/pm_api_sys.c index df6c9af49..eae881e22 100644 --- a/plat/xilinx/versal/pm_service/pm_api_sys.c +++ b/plat/xilinx/versal/pm_service/pm_api_sys.c @@ -732,7 +732,7 @@ enum pm_ret_status pm_query_data(uint32_t qid, uint32_t arg1, uint32_t arg2, arg2, arg3); ret = pm_feature_check(PM_QUERY_DATA, &version); - if (PM_RET_SUCCESS == ret){ + if (PM_RET_SUCCESS == ret) { fw_api_version = version & 0xFFFF ; if ((2U == fw_api_version) && ((XPM_QID_CLOCK_GET_NAME == qid) || -- cgit v1.2.3 From 2ab0ef8db9561699fef0f77f5a1735e4903f6b3e Mon Sep 17 00:00:00 2001 From: Sai Krishna Potthuri Date: Tue, 20 Oct 2020 07:00:06 -0600 Subject: plat: zynqmp: Check for DLL status before doing reset This patch check for the DLL status before doing the DLL reset. If DLL reset is already issued then skip the reset inside ATF otherwise DLL reset will be issued. By doing this way, all the following cases will be supported. 1. Patched ATF + Patched Linux base. 2. Older ATF + Patched Linux base. 3. Patched ATF + Older Linux base. Signed-off-by: Sai Krishna Potthuri Acked-by: Michal Simek Signed-off-by: Michal Simek Change-Id: I53a0a27521330f1543275cc9cb44cd1dfc569c65 --- plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c index 60e80d907..9b1ffbc7a 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c +++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c @@ -282,17 +282,29 @@ static enum pm_ret_status pm_ioctl_sd_set_tapdelay(enum pm_node_id nid, { unsigned int shift; enum pm_ret_status ret; + unsigned int val, mask; - if (nid == NODE_SD_0) + if (nid == NODE_SD_0) { shift = 0; - else if (nid == NODE_SD_1) + mask = ZYNQMP_SD0_DLL_RST_MASK; + } else if (nid == NODE_SD_1) { shift = ZYNQMP_SD_TAP_OFFSET; - else + mask = ZYNQMP_SD1_DLL_RST_MASK; + } else { return PM_RET_ERROR_ARGS; + } - ret = pm_ioctl_sd_dll_reset(nid, PM_DLL_RESET_ASSERT); - if (ret != PM_RET_SUCCESS) + ret = pm_mmio_read(ZYNQMP_SD_DLL_CTRL, &val); + if (ret != PM_RET_SUCCESS) { return ret; + } + + if ((val & mask) == 0) { + ret = pm_ioctl_sd_dll_reset(nid, PM_DLL_RESET_ASSERT); + if (ret != PM_RET_SUCCESS) { + return ret; + } + } if (type == PM_TAPDELAY_INPUT) { ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY, @@ -326,7 +338,10 @@ static enum pm_ret_status pm_ioctl_sd_set_tapdelay(enum pm_node_id nid, } reset_release: - pm_ioctl_sd_dll_reset(nid, PM_DLL_RESET_RELEASE); + if ((val & mask) == 0) { + (void)pm_ioctl_sd_dll_reset(nid, PM_DLL_RESET_RELEASE); + } + return ret; } -- cgit v1.2.3 From fe1fa205fca4d1dd4a1b1755942956dbca65d573 Mon Sep 17 00:00:00 2001 From: Sai Krishna Potthuri Date: Fri, 30 Oct 2020 00:09:43 -0600 Subject: plat: zynqmp: Disable ITAPDLYENA bit for zero ITAP delay This patch disable the ITAPDLYENA bit for ITAP delay value zero. As per IP design, it is recommended to disable the ITAPDLYENA bit before auto-tuning. Also disable OTAPDLYENA bit always as there is one issue in RTL where SD0_OTAPDLYENA has been wrongly connected to both SD0 and SD1 controllers. Hence it is recommended to disable OTAPDLYENA bit always for both the controllers. Signed-off-by: Sai Krishna Potthuri Acked-by: Srinivas Goud Signed-off-by: Michal Simek Change-Id: Icf035cb63510ac7bec4e9d523a622f145eaf0989 --- plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c index 9b1ffbc7a..9f3acaa19 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c +++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c @@ -312,9 +312,15 @@ static enum pm_ret_status pm_ioctl_sd_set_tapdelay(enum pm_node_id nid, (ZYNQMP_SD_ITAPCHGWIN << shift)); if (ret != PM_RET_SUCCESS) goto reset_release; - ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY, - (ZYNQMP_SD_ITAPDLYENA_MASK << shift), - (ZYNQMP_SD_ITAPDLYENA << shift)); + if (value == 0) + ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY, + (ZYNQMP_SD_ITAPDLYENA_MASK << + shift), 0); + else + ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY, + (ZYNQMP_SD_ITAPDLYENA_MASK << + shift), (ZYNQMP_SD_ITAPDLYENA << + shift)); if (ret != PM_RET_SUCCESS) goto reset_release; ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY, @@ -326,8 +332,7 @@ static enum pm_ret_status pm_ioctl_sd_set_tapdelay(enum pm_node_id nid, (ZYNQMP_SD_ITAPCHGWIN_MASK << shift), 0); } else if (type == PM_TAPDELAY_OUTPUT) { ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY, - (ZYNQMP_SD_OTAPDLYENA_MASK << shift), - (ZYNQMP_SD_OTAPDLYENA << shift)); + (ZYNQMP_SD_OTAPDLYENA_MASK << shift), 0); if (ret != PM_RET_SUCCESS) goto reset_release; ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY, -- cgit v1.2.3 From f18217902a4c84c2cb6695164ffa1db540a0146b Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Mon, 7 Dec 2020 16:38:53 +0000 Subject: TF-A: Add build option for Arm Feature Modifiers This patch adds a new ARM_ARCH_FEATURE build option to add support for compiler's feature modifiers. It has the form '[no]feature+...' and defaults to 'none'. This option translates into compiler option '-march=armvX[.Y]-a+[no]feature+...'. Change-Id: I37742f270a898f5d6968e146cbcc04cbf53ef2ad Signed-off-by: Alexei Fedorov --- Makefile | 43 +++++++++++++++++++++++++--------- docs/getting_started/build-options.rst | 6 +++++ make_helpers/defaults.mk | 3 +++ 3 files changed, 41 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index 5c9186ece..f950eb834 100644 --- a/Makefile +++ b/Makefile @@ -185,13 +185,14 @@ target32-directive = -target arm-none-eabi else target32-directive = -target armv8a-none-eabi -# Set the compiler's target architecture profile based on ARM_ARCH_MINOR option +# Set the compiler's target architecture profile based on +# ARM_ARCH_MAJOR ARM_ARCH_MINOR options ifeq (${ARM_ARCH_MINOR},0) -march32-directive = -march=armv8-a -march64-directive = -march=armv8-a +march32-directive = -march=armv${ARM_ARCH_MAJOR}-a +march64-directive = -march=armv${ARM_ARCH_MAJOR}-a else -march32-directive = -march=armv8.${ARM_ARCH_MINOR}-a -march64-directive = -march=armv8.${ARM_ARCH_MINOR}-a +march32-directive = -march=armv${ARM_ARCH_MAJOR}.${ARM_ARCH_MINOR}-a +march64-directive = -march=armv${ARM_ARCH_MAJOR}.${ARM_ARCH_MINOR}-a endif endif @@ -203,23 +204,43 @@ mem_tag_arch_support = yes endif endif -# Enabled required option for memory stack tagging. Currently, these options are -# enabled only for clang and armclang compiler. +# Get architecture feature modifiers +arch-features = ${ARM_ARCH_FEATURE} + +# Enable required options for memory stack tagging. +# Currently, these options are enabled only for clang and armclang compiler. ifeq (${SUPPORT_STACK_MEMTAG},yes) ifdef mem_tag_arch_support +# Check for armclang and clang compilers ifneq ( ,$(filter $(notdir $(CC)),armclang clang)) -march64-directive = -march=armv${ARM_ARCH_MAJOR}.${ARM_ARCH_MINOR}-a+memtag +# Add "memtag" architecture feature modifier if not specified +ifeq ( ,$(findstring memtag,$(arch-features))) +arch-features := $(arch-features)+memtag +endif # memtag ifeq ($(notdir $(CC)),armclang) TF_CFLAGS += -mmemtag-stack else ifeq ($(notdir $(CC)),clang) TF_CFLAGS += -fsanitize=memtag -endif -endif +endif # armclang +endif # armclang clang else $(error "Error: stack memory tagging is not supported for architecture \ ${ARCH},armv${ARM_ARCH_MAJOR}.${ARM_ARCH_MINOR}-a") +endif # mem_tag_arch_support +endif # SUPPORT_STACK_MEMTAG + +# Set the compiler's architecture feature modifiers +ifneq ($(arch-features), none) +# Strip "none+" from arch-features +arch-features := $(subst none+,,$(arch-features)) +ifeq ($(ARCH), aarch32) +march32-directive := $(march32-directive)+$(arch-features) +else +march64-directive := $(march64-directive)+$(arch-features) endif -endif +# Print features +$(info Arm Architecture Features specified: $(subst +, ,$(arch-features))) +endif # arch-features ifneq ($(findstring armclang,$(notdir $(CC))),) TF_CFLAGS_aarch32 = -target arm-arm-none-eabi $(march32-directive) diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 8adf4ad8b..d4eb6a768 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -26,6 +26,12 @@ Common build options ``aarch64`` or ``aarch32`` as values. By default, it is defined to ``aarch64``. +- ``ARM_ARCH_FEATURE``: Optional Arm Architecture build option which specifies + one or more feature modifiers. This option has the form ``[no]feature+...`` + and defaults to ``none``. It translates into compiler option + ``-march=armvX[.Y]-a+[no]feature+...``. See compiler's documentation for the + list of supported feature modifiers. + - ``ARM_ARCH_MAJOR``: The major version of Arm Architecture to target when compiling TF-A. Its value must be numeric, and defaults to 8 . See also, *Armv8 Architecture Extensions* and *Armv7 Architecture Extensions* in diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index 578bd5987..9e5fe8557 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -19,6 +19,9 @@ AARCH32_SP := none # The Target build architecture. Supported values are: aarch64, aarch32. ARCH := aarch64 +# ARM Architecture feature modifiers: none by default +ARM_ARCH_FEATURE := none + # ARM Architecture major and minor versions: 8.0 by default. ARM_ARCH_MAJOR := 8 ARM_ARCH_MINOR := 0 -- cgit v1.2.3 From 0063dd1708e67e5d36168caaf2a0df383bbe1455 Mon Sep 17 00:00:00 2001 From: Javier Almansa Sobrino Date: Mon, 23 Nov 2020 18:38:15 +0000 Subject: Add support for FEAT_MTPMU for Armv8.6 If FEAT_PMUv3 is implemented and PMEVTYPER(_EL0).MT bit is implemented as well, it is possible to control whether PMU counters take into account events happening on other threads. If FEAT_MTPMU is implemented, EL3 (or EL2) can override the MT bit leaving it to effective state of 0 regardless of any write to it. This patch introduces the DISABLE_MTPMU flag, which allows to diable multithread event count from EL3 (or EL2). The flag is disabled by default so the behavior is consistent with those architectures that do not implement FEAT_MTPMU. Signed-off-by: Javier Almansa Sobrino Change-Id: Iee3a8470ae8ba13316af1bd40c8d4aa86e0cb85e --- Makefile | 2 + bl1/bl1.mk | 6 +- bl2/bl2.mk | 6 +- bl31/bl31.mk | 5 +- bl32/sp_min/sp_min.mk | 6 +- docs/getting_started/build-options.rst | 5 ++ include/arch/aarch32/arch.h | 11 ++++ include/arch/aarch32/el3_common_macros.S | 4 ++ include/arch/aarch64/arch.h | 7 +++ include/arch/aarch64/el3_common_macros.S | 4 ++ lib/extensions/mtpmu/aarch32/mtpmu.S | 105 +++++++++++++++++++++++++++++++ lib/extensions/mtpmu/aarch64/mtpmu.S | 96 ++++++++++++++++++++++++++++ make_helpers/defaults.mk | 4 ++ 13 files changed, 257 insertions(+), 4 deletions(-) create mode 100644 lib/extensions/mtpmu/aarch32/mtpmu.S create mode 100644 lib/extensions/mtpmu/aarch64/mtpmu.S diff --git a/Makefile b/Makefile index 5c9186ece..4b13d4d4e 100644 --- a/Makefile +++ b/Makefile @@ -867,6 +867,7 @@ $(eval $(call assert_booleans,\ CTX_INCLUDE_EL2_REGS \ CTX_INCLUDE_NEVE_REGS \ DEBUG \ + DISABLE_MTPMU \ DYN_DISABLE_AUTH \ EL3_EXCEPTION_HANDLING \ ENABLE_AMU \ @@ -956,6 +957,7 @@ $(eval $(call add_defines,\ CTX_INCLUDE_EL2_REGS \ CTX_INCLUDE_NEVE_REGS \ DECRYPTION_SUPPORT_${DECRYPTION_SUPPORT} \ + DISABLE_MTPMU \ ENABLE_AMU \ ENABLE_ASSERTIONS \ ENABLE_BTI \ diff --git a/bl1/bl1.mk b/bl1/bl1.mk index b83999075..d11b4ab0e 100644 --- a/bl1/bl1.mk +++ b/bl1/bl1.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -16,6 +16,10 @@ BL1_SOURCES += bl1/bl1_main.c \ plat/common/${ARCH}/platform_up_stack.S \ ${MBEDTLS_SOURCES} +ifeq (${DISABLE_MTPMU},1) +BL1_SOURCES += lib/extensions/mtpmu/${ARCH}/mtpmu.S +endif + ifeq (${ARCH},aarch64) BL1_SOURCES += lib/cpus/aarch64/dsu_helpers.S \ lib/el3_runtime/aarch64/context.S diff --git a/bl2/bl2.mk b/bl2/bl2.mk index 6dc0f1825..735e7e04f 100644 --- a/bl2/bl2.mk +++ b/bl2/bl2.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -25,6 +25,10 @@ BL2_SOURCES += bl2/${ARCH}/bl2_el3_entrypoint.S \ lib/cpus/${ARCH}/cpu_helpers.S \ lib/cpus/errata_report.c +ifeq (${DISABLE_MTPMU},1) +BL2_SOURCES += lib/extensions/mtpmu/${ARCH}/mtpmu.S +endif + ifeq (${ARCH},aarch64) BL2_SOURCES += lib/cpus/aarch64/dsu_helpers.S endif diff --git a/bl31/bl31.mk b/bl31/bl31.mk index cd6549bff..e299fe139 100644 --- a/bl31/bl31.mk +++ b/bl31/bl31.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -40,6 +40,9 @@ BL31_SOURCES += bl31/bl31_main.c \ ${SPMD_SOURCES} \ ${SPM_SOURCES} +ifeq (${DISABLE_MTPMU},1) +BL31_SOURCES += lib/extensions/mtpmu/aarch64/mtpmu.S +endif ifeq (${ENABLE_PMF}, 1) BL31_SOURCES += lib/pmf/pmf_main.c diff --git a/bl32/sp_min/sp_min.mk b/bl32/sp_min/sp_min.mk index 6233299d7..afd7ae196 100644 --- a/bl32/sp_min/sp_min.mk +++ b/bl32/sp_min/sp_min.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -19,6 +19,10 @@ BL32_SOURCES += bl32/sp_min/sp_min_main.c \ services/std_svc/std_svc_setup.c \ ${PSCI_LIB_SOURCES} +ifeq (${DISABLE_MTPMU},1) +BL32_SOURCES += lib/extensions/mtpmu/aarch32/mtpmu.S +endif + ifeq (${ENABLE_PMF}, 1) BL32_SOURCES += lib/pmf/pmf_main.c endif diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 8adf4ad8b..1d243cfbf 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -185,6 +185,11 @@ Common build options of the binary image. If set to 1, then only the ELF image is built. 0 is the default. +- ``DISABLE_MTPMU``: Boolean option to disable FEAT_MTPMU if implemented + (Armv8.6 onwards). Its default value is 0 to keep consistency with platforms + that do not implement FEAT_MTPMU. For more information on FEAT_MTPMU, + check the latest Arm ARM. + - ``DYN_DISABLE_AUTH``: Provides the capability to dynamically disable Trusted Board Boot authentication at runtime. This option is meant to be enabled only for development platforms. ``TRUSTED_BOARD_BOOT`` flag must be set if this diff --git a/include/arch/aarch32/arch.h b/include/arch/aarch32/arch.h index db8938ff1..c30073b8c 100644 --- a/include/arch/aarch32/arch.h +++ b/include/arch/aarch32/arch.h @@ -102,6 +102,11 @@ /* CSSELR definitions */ #define LEVEL_SHIFT U(1) +/* ID_DFR1_EL1 definitions */ +#define ID_DFR1_MTPMU_SHIFT U(0) +#define ID_DFR1_MTPMU_MASK U(0xf) +#define ID_DFR1_MTPMU_SUPPORTED U(1) + /* ID_MMFR4 definitions */ #define ID_MMFR4_CNP_SHIFT U(12) #define ID_MMFR4_CNP_LENGTH U(4) @@ -126,6 +131,9 @@ #define ID_PFR1_GENTIMER_MASK U(0xf) #define ID_PFR1_GIC_SHIFT U(28) #define ID_PFR1_GIC_MASK U(0xf) +#define ID_PFR1_SEC_SHIFT U(4) +#define ID_PFR1_SEC_MASK U(0xf) +#define ID_PFR1_ELx_ENABLED U(1) /* SCTLR definitions */ #define SCTLR_RES1_DEF ((U(1) << 23) | (U(1) << 22) | (U(1) << 4) | \ @@ -164,6 +172,7 @@ #define SDCR_SCCD_BIT (U(1) << 23) #define SDCR_SPME_BIT (U(1) << 17) #define SDCR_RESET_VAL U(0x0) +#define SDCR_MTPME_BIT (U(1) << 28) /* HSCTLR definitions */ #define HSCTLR_RES1 ((U(1) << 29) | (U(1) << 28) | (U(1) << 23) | \ @@ -244,6 +253,7 @@ #define VTTBR_BADDR_SHIFT U(0) /* HDCR definitions */ +#define HDCR_MTPME_BIT (U(1) << 28) #define HDCR_HLP_BIT (U(1) << 26) #define HDCR_HPME_BIT (U(1) << 7) #define HDCR_RESET_VAL U(0x0) @@ -503,6 +513,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_DFR1 p15, 0, c0, c3, 5 #define ID_PFR0 p15, 0, c0, c1, 0 #define ID_PFR1 p15, 0, c0, c1, 1 #define MAIR0 p15, 0, c10, c2, 0 diff --git a/include/arch/aarch32/el3_common_macros.S b/include/arch/aarch32/el3_common_macros.S index 4fd746d5a..580dd95b7 100644 --- a/include/arch/aarch32/el3_common_macros.S +++ b/include/arch/aarch32/el3_common_macros.S @@ -242,6 +242,10 @@ cps #MODE32_mon isb +#if DISABLE_MTPMU + bl mtpmu_disable +#endif + .if \_warm_boot_mailbox /* ------------------------------------------------------------- * This code will be executed for both warm and cold resets. diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index 6dcdacf98..09e598a2d 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -188,6 +188,11 @@ #define ID_AA64DFR0_PMS_SHIFT U(32) #define ID_AA64DFR0_PMS_MASK ULL(0xf) +/* ID_AA64DFR0_EL1.MTPMU definitions (for ARMv8.6+) */ +#define ID_AA64DFR0_MTPMU_SHIFT U(48) +#define ID_AA64DFR0_MTPMU_MASK ULL(0xf) +#define ID_AA64DFR0_MTPMU_SUPPORTED ULL(1) + /* ID_AA64ISAR1_EL1 definitions */ #define ID_AA64ISAR1_EL1 S3_0_C0_C6_1 #define ID_AA64ISAR1_GPI_SHIFT U(28) @@ -421,6 +426,7 @@ #define SCR_RESET_VAL SCR_RES1_BITS /* MDCR_EL3 definitions */ +#define MDCR_MTPME_BIT (ULL(1) << 28) #define MDCR_SCCD_BIT (ULL(1) << 23) #define MDCR_SPME_BIT (ULL(1) << 17) #define MDCR_SDD_BIT (ULL(1) << 16) @@ -436,6 +442,7 @@ #define MDCR_EL3_RESET_VAL ULL(0x0) /* MDCR_EL2 definitions */ +#define MDCR_EL2_MTPME (U(1) << 28) #define MDCR_EL2_HLP (U(1) << 26) #define MDCR_EL2_HCCD (U(1) << 23) #define MDCR_EL2_TTRF (U(1) << 19) diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S index 6f4143c5f..f75998351 100644 --- a/include/arch/aarch64/el3_common_macros.S +++ b/include/arch/aarch64/el3_common_macros.S @@ -277,6 +277,10 @@ 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. diff --git a/lib/extensions/mtpmu/aarch32/mtpmu.S b/lib/extensions/mtpmu/aarch32/mtpmu.S new file mode 100644 index 000000000..834cee3ea --- /dev/null +++ b/lib/extensions/mtpmu/aarch32/mtpmu.S @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + + .global mtpmu_disable + +/* ------------------------------------------------------------- + * The functions in this file are called at entrypoint, before + * the CPU has decided whether this is a cold or a warm boot. + * Therefore there are no stack yet to rely on for a C function + * call. + * ------------------------------------------------------------- + */ + +/* + * bool mtpmu_supported(void) + * + * Return a boolean indicating whether FEAT_MTPMU is supported or not. + * + * Trash registers: r0. + */ +func mtpmu_supported + ldcopr r0, ID_DFR1 + and r0, r0, #(ID_DFR1_MTPMU_MASK >> ID_DFR1_MTPMU_SHIFT) + cmp r0, #ID_DFR1_MTPMU_SUPPORTED + mov r0, #0 + addeq r0, r0, #1 + bx lr +endfunc mtpmu_supported + +/* + * bool el_implemented(unsigned int el) + * + * Return a boolean indicating if the specified EL (2 or 3) is implemented. + * + * Trash registers: r0 + */ +func el_implemented + cmp r0, #3 + ldcopr r0, ID_PFR1 + lsreq r0, r0, #ID_PFR1_SEC_SHIFT + lsrne r0, r0, #ID_PFR1_VIRTEXT_SHIFT + /* + * ID_PFR1_VIRTEXT_MASK is the same as ID_PFR1_SEC_MASK + * so use any one of them + */ + and r0, r0, #ID_PFR1_VIRTEXT_MASK + cmp r0, #ID_PFR1_ELx_ENABLED + mov r0, #0 + addeq r0, r0, #1 + bx lr +endfunc el_implemented + +/* + * void mtpmu_disable(void) + * + * Disable mtpmu feature if supported. + * + * Trash register: r0, r1, r2 + */ +func mtpmu_disable + mov r2, lr + bl mtpmu_supported + cmp r0, #0 + bxeq r2 /* FEAT_MTPMU not supported */ + + /* FEAT_MTMPU Supported */ + mov r0, #3 + bl el_implemented + cmp r0, #0 + beq 1f + + /* EL3 implemented */ + ldcopr r0, SDCR + ldr r1, =SDCR_MTPME_BIT + bic r0, r0, r1 + stcopr r0, SDCR + + /* + * If EL3 is implemented, HDCR.MTPME is implemented as Res0 and + * FEAT_MTPMU is controlled only from EL3, so no need to perform + * any operations for EL2. + */ + isb + bx r2 +1: + /* EL3 not implemented */ + mov r0, #2 + bl el_implemented + cmp r0, #0 + bxeq r2 /* No EL2 or EL3 implemented */ + + /* EL2 implemented */ + ldcopr r0, HDCR + ldr r1, =HDCR_MTPME_BIT + orr r0, r0, r1 + stcopr r0, HDCR + isb + bx r2 +endfunc mtpmu_disable diff --git a/lib/extensions/mtpmu/aarch64/mtpmu.S b/lib/extensions/mtpmu/aarch64/mtpmu.S new file mode 100644 index 000000000..0a1d57b9d --- /dev/null +++ b/lib/extensions/mtpmu/aarch64/mtpmu.S @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + + .global mtpmu_disable + +/* ------------------------------------------------------------- + * The functions in this file are called at entrypoint, before + * the CPU has decided whether this is a cold or a warm boot. + * Therefore there are no stack yet to rely on for a C function + * call. + * ------------------------------------------------------------- + */ + +/* + * bool mtpmu_supported(void) + * + * Return a boolean indicating whether FEAT_MTPMU is supported or not. + * + * Trash registers: x0, x1 + */ +func mtpmu_supported + mrs x0, id_aa64dfr0_el1 + mov_imm x1, ID_AA64DFR0_MTPMU_MASK + and x0, x1, x0, LSR #ID_AA64DFR0_MTPMU_SHIFT + cmp x0, ID_AA64DFR0_MTPMU_SUPPORTED + cset x0, eq + ret +endfunc mtpmu_supported + +/* + * bool el_implemented(unsigned int el_shift) + * + * Return a boolean indicating if the specified EL is implemented. + * The EL is represented as the bitmask shift on id_aa64pfr0_el1 register. + * + * Trash registers: x0, x1 + */ +func el_implemented + mrs x1, id_aa64pfr0_el1 + lsr x1, x1, x0 + cmp x1, #ID_AA64PFR0_ELX_MASK + cset x0, eq + ret +endfunc el_implemented + +/* + * void mtpmu_disable(void) + * + * Disable mtpmu feature if supported. + * + * Trash register: x0, x1, x30 + */ +func mtpmu_disable + mov x10, x30 + bl mtpmu_supported + cbz x0, exit_disable + + /* FEAT_MTMPU Supported */ + mov_imm x0, ID_AA64PFR0_EL3_SHIFT + bl el_implemented + cbz x0, 1f + + /* EL3 implemented */ + mrs x0, mdcr_el3 + mov_imm x1, MDCR_MTPME_BIT + bic x0, x0, x1 + msr mdcr_el3, x0 + + /* + * If EL3 is implemented, MDCR_EL2.MTPME is implemented as Res0 and + * FEAT_MTPMU is controlled only from EL3, so no need to perform + * any operations for EL2. + */ + isb +exit_disable: + ret x10 +1: + /* EL3 not implemented */ + mov_imm x0, ID_AA64PFR0_EL2_SHIFT + bl el_implemented + cbz x0, exit_disable + + /* EL2 implemented */ + mrs x0, mdcr_el2 + mov_imm x1, MDCR_EL2_MTPME + bic x0, x0, x1 + msr mdcr_el2, x0 + isb + ret x10 +endfunc mtpmu_disable diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index 578bd5987..f69a73ea6 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -79,6 +79,10 @@ DEFAULT_PLAT := fvp # Disable the generation of the binary image (ELF only). DISABLE_BIN_GENERATION := 0 +# Disable MTPMU if FEAT_MTPMU is supported. Default is 0 to keep backwards +# compatibility. +DISABLE_MTPMU := 0 + # Enable capability to disable authentication dynamically. Only meant for # development platforms. DYN_DISABLE_AUTH := 0 -- cgit v1.2.3 From 978a824091303748007de308e11af12c2601bc05 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sun, 13 Dec 2020 21:44:54 -0600 Subject: allwinner: Add R_PRCM security setup for H6 H6 has a reorganized R_PRCM compared to A64/H5, with the security switch at a different offset. Until now, we did not notice, because the switch has no effect unless the secure mode e-fuse is blown. Since we are adding more platform-specific CCU registers, move them to their own header, and out of the memory map (where they do not belong). Signed-off-by: Samuel Holland Change-Id: Ie77476db0515080954eaa2e32bf6c3de657cda86 --- plat/allwinner/common/sunxi_security.c | 4 ++-- plat/allwinner/sun50i_a64/include/sunxi_ccu.h | 14 ++++++++++++++ plat/allwinner/sun50i_a64/include/sunxi_mmap.h | 1 - plat/allwinner/sun50i_h6/include/sunxi_ccu.h | 14 ++++++++++++++ plat/allwinner/sun50i_h6/include/sunxi_mmap.h | 1 - 5 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 plat/allwinner/sun50i_a64/include/sunxi_ccu.h create mode 100644 plat/allwinner/sun50i_h6/include/sunxi_ccu.h diff --git a/plat/allwinner/common/sunxi_security.c b/plat/allwinner/common/sunxi_security.c index 92c83b06e..fab3ba81a 100644 --- a/plat/allwinner/common/sunxi_security.c +++ b/plat/allwinner/common/sunxi_security.c @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -16,7 +17,6 @@ #define SPC_DECPORT_CLR_REG(p) (SUNXI_SPC_BASE + ((p) * 0x0c) + 0xc) #endif -#define R_PRCM_SEC_SWITCH_REG 0x1d0 #define DMA_SEC_REG 0x20 /* @@ -40,7 +40,7 @@ void sunxi_security_setup(void) mmio_write_32(SUNXI_CCU_SEC_SWITCH_REG, 0x7); /* Set R_PRCM bus clocks to non-secure */ - mmio_write_32(SUNXI_R_PRCM_BASE + R_PRCM_SEC_SWITCH_REG, 0x1); + mmio_write_32(SUNXI_R_PRCM_SEC_SWITCH_REG, 0x1); /* Set all DMA channels (16 max.) to non-secure */ mmio_write_32(SUNXI_DMA_BASE + DMA_SEC_REG, 0xffff); diff --git a/plat/allwinner/sun50i_a64/include/sunxi_ccu.h b/plat/allwinner/sun50i_a64/include/sunxi_ccu.h new file mode 100644 index 000000000..2a2488621 --- /dev/null +++ b/plat/allwinner/sun50i_a64/include/sunxi_ccu.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SUNXI_CCU_H +#define SUNXI_CCU_H + +#define SUNXI_CCU_SEC_SWITCH_REG (SUNXI_CCU_BASE + 0x02f0) + +#define SUNXI_R_PRCM_SEC_SWITCH_REG (SUNXI_R_PRCM_BASE + 0x01d0) + +#endif /* SUNXI_CCU_H */ diff --git a/plat/allwinner/sun50i_a64/include/sunxi_mmap.h b/plat/allwinner/sun50i_a64/include/sunxi_mmap.h index 9d2542fce..6c847d39b 100644 --- a/plat/allwinner/sun50i_a64/include/sunxi_mmap.h +++ b/plat/allwinner/sun50i_a64/include/sunxi_mmap.h @@ -36,7 +36,6 @@ #define SUNXI_MSGBOX_BASE 0x01c17000 #define SUNXI_SPINLOCK_BASE 0x01c18000 #define SUNXI_CCU_BASE 0x01c20000 -#define SUNXI_CCU_SEC_SWITCH_REG (SUNXI_CCU_BASE + 0x2f0) #define SUNXI_PIO_BASE 0x01c20800 #define SUNXI_TIMER_BASE 0x01c20c00 #define SUNXI_WDOG_BASE 0x01c20ca0 diff --git a/plat/allwinner/sun50i_h6/include/sunxi_ccu.h b/plat/allwinner/sun50i_h6/include/sunxi_ccu.h new file mode 100644 index 000000000..85fbb9080 --- /dev/null +++ b/plat/allwinner/sun50i_h6/include/sunxi_ccu.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SUNXI_CCU_H +#define SUNXI_CCU_H + +#define SUNXI_CCU_SEC_SWITCH_REG (SUNXI_CCU_BASE + 0x0f00) + +#define SUNXI_R_PRCM_SEC_SWITCH_REG (SUNXI_R_PRCM_BASE + 0x0290) + +#endif /* SUNXI_CCU_H */ diff --git a/plat/allwinner/sun50i_h6/include/sunxi_mmap.h b/plat/allwinner/sun50i_h6/include/sunxi_mmap.h index 702db770f..39a505a81 100644 --- a/plat/allwinner/sun50i_h6/include/sunxi_mmap.h +++ b/plat/allwinner/sun50i_h6/include/sunxi_mmap.h @@ -30,7 +30,6 @@ #define SUNXI_DMA_BASE 0x03002000 #define SUNXI_MSGBOX_BASE 0x03003000 #define SUNXI_CCU_BASE 0x03001000 -#define SUNXI_CCU_SEC_SWITCH_REG (SUNXI_CCU_BASE + 0xf00) #define SUNXI_PIO_BASE 0x0300b000 #define SUNXI_TIMER_BASE 0x03009000 #define SUNXI_WDOG_BASE 0x030090a0 -- cgit v1.2.3 From 49d98cd549c3e2cb5fa4316e1ed365af4d95d9ba Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sun, 13 Dec 2020 21:56:15 -0600 Subject: allwinner: Add SPC security setup for H6 The H6 has a "secure port controller" similar to the A64/H5, but with more ports and a different register layout. Split the platform-specific parts out into a header, and add the missing MMIO base address. Signed-off-by: Samuel Holland Change-Id: I3703868bc595459ecf9568b9d1605cb1be014bf5 --- plat/allwinner/common/sunxi_security.c | 15 ++++----------- plat/allwinner/sun50i_a64/include/sunxi_spc.h | 16 ++++++++++++++++ plat/allwinner/sun50i_h6/include/sunxi_mmap.h | 1 + plat/allwinner/sun50i_h6/include/sunxi_spc.h | 16 ++++++++++++++++ 4 files changed, 37 insertions(+), 11 deletions(-) create mode 100644 plat/allwinner/sun50i_a64/include/sunxi_spc.h create mode 100644 plat/allwinner/sun50i_h6/include/sunxi_spc.h diff --git a/plat/allwinner/common/sunxi_security.c b/plat/allwinner/common/sunxi_security.c index fab3ba81a..98b91c39f 100644 --- a/plat/allwinner/common/sunxi_security.c +++ b/plat/allwinner/common/sunxi_security.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -10,12 +10,7 @@ #include #include #include - -#ifdef SUNXI_SPC_BASE -#define SPC_DECPORT_STA_REG(p) (SUNXI_SPC_BASE + ((p) * 0x0c) + 0x4) -#define SPC_DECPORT_SET_REG(p) (SUNXI_SPC_BASE + ((p) * 0x0c) + 0x8) -#define SPC_DECPORT_CLR_REG(p) (SUNXI_SPC_BASE + ((p) * 0x0c) + 0xc) -#endif +#include #define DMA_SEC_REG 0x20 @@ -27,14 +22,12 @@ */ void sunxi_security_setup(void) { -#ifdef SUNXI_SPC_BASE int i; INFO("Configuring SPC Controller\n"); /* SPC setup: set all devices to non-secure */ - for (i = 0; i < 6; i++) - mmio_write_32(SPC_DECPORT_SET_REG(i), 0xff); -#endif + for (i = 0; i < SUNXI_SPC_NUM_PORTS; i++) + mmio_write_32(SUNXI_SPC_DECPORT_SET_REG(i), 0xffffffff); /* set MBUS clocks, bus clocks (AXI/AHB/APB) and PLLs to non-secure */ mmio_write_32(SUNXI_CCU_SEC_SWITCH_REG, 0x7); diff --git a/plat/allwinner/sun50i_a64/include/sunxi_spc.h b/plat/allwinner/sun50i_a64/include/sunxi_spc.h new file mode 100644 index 000000000..5ba7e18fe --- /dev/null +++ b/plat/allwinner/sun50i_a64/include/sunxi_spc.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SUNXI_SPC_H +#define SUNXI_SPC_H + +#define SUNXI_SPC_NUM_PORTS 6 + +#define SUNXI_SPC_DECPORT_STA_REG(p) (SUNXI_SPC_BASE + 0x0004 + 0x0c * (p)) +#define SUNXI_SPC_DECPORT_SET_REG(p) (SUNXI_SPC_BASE + 0x0008 + 0x0c * (p)) +#define SUNXI_SPC_DECPORT_CLR_REG(p) (SUNXI_SPC_BASE + 0x000c + 0x0c * (p)) + +#endif /* SUNXI_SPC_H */ diff --git a/plat/allwinner/sun50i_h6/include/sunxi_mmap.h b/plat/allwinner/sun50i_h6/include/sunxi_mmap.h index 39a505a81..514621f00 100644 --- a/plat/allwinner/sun50i_h6/include/sunxi_mmap.h +++ b/plat/allwinner/sun50i_h6/include/sunxi_mmap.h @@ -31,6 +31,7 @@ #define SUNXI_MSGBOX_BASE 0x03003000 #define SUNXI_CCU_BASE 0x03001000 #define SUNXI_PIO_BASE 0x0300b000 +#define SUNXI_SPC_BASE 0x03008000 #define SUNXI_TIMER_BASE 0x03009000 #define SUNXI_WDOG_BASE 0x030090a0 #define SUNXI_THS_BASE 0x05070400 diff --git a/plat/allwinner/sun50i_h6/include/sunxi_spc.h b/plat/allwinner/sun50i_h6/include/sunxi_spc.h new file mode 100644 index 000000000..0f5965bee --- /dev/null +++ b/plat/allwinner/sun50i_h6/include/sunxi_spc.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SUNXI_SPC_H +#define SUNXI_SPC_H + +#define SUNXI_SPC_NUM_PORTS 14 + +#define SUNXI_SPC_DECPORT_STA_REG(p) (SUNXI_SPC_BASE + 0x0000 + 0x10 * (p)) +#define SUNXI_SPC_DECPORT_SET_REG(p) (SUNXI_SPC_BASE + 0x0004 + 0x10 * (p)) +#define SUNXI_SPC_DECPORT_CLR_REG(p) (SUNXI_SPC_BASE + 0x0008 + 0x10 * (p)) + +#endif /* SUNXI_SPC_H */ -- cgit v1.2.3 From 3d36d8e600c734ee474dc53e4fc4a0009aaa4a2b Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sun, 13 Dec 2020 20:05:11 -0600 Subject: allwinner: Fix non-default PRELOADED_BL33_BASE While the Allwinner platform code nominally supported a custom PRELOADED_BL33_BASE, some references to the BL33 load address used another constant: PLAT_SUNXI_NS_IMAGE_OFFSET. To allow the DTB search code to work if a U-Boot BL33 is loaded to a custom address, consistently use PRELOADED_BL33_BASE. And to avoid this confusion in the future, remove the other constant. Signed-off-by: Samuel Holland Change-Id: Ie6b97ae1fdec95d784676aef39200bef161471b0 --- plat/allwinner/common/allwinner-common.mk | 3 +++ plat/allwinner/common/include/platform_def.h | 3 --- plat/allwinner/common/sunxi_bl31_setup.c | 4 ++-- plat/allwinner/common/sunxi_common.c | 11 +---------- 4 files changed, 6 insertions(+), 15 deletions(-) diff --git a/plat/allwinner/common/allwinner-common.mk b/plat/allwinner/common/allwinner-common.mk index 997aaa6f7..4d8b2514a 100644 --- a/plat/allwinner/common/allwinner-common.mk +++ b/plat/allwinner/common/allwinner-common.mk @@ -49,6 +49,9 @@ ERRATA_A53_835769 := 1 ERRATA_A53_843419 := 1 ERRATA_A53_855873 := 1 +# The traditional U-Boot load address is 160MB into DRAM. +PRELOADED_BL33_BASE ?= 0x4a000000 + # The reset vector can be changed for each CPU. PROGRAMMABLE_RESET_ADDRESS := 1 diff --git a/plat/allwinner/common/include/platform_def.h b/plat/allwinner/common/include/platform_def.h index 975cc48d5..93720fff2 100644 --- a/plat/allwinner/common/include/platform_def.h +++ b/plat/allwinner/common/include/platform_def.h @@ -25,9 +25,6 @@ #define BL31_NOBITS_BASE (SUNXI_SRAM_A1_BASE + 0x1000) #define BL31_NOBITS_LIMIT (SUNXI_SRAM_A1_BASE + SUNXI_SRAM_A1_SIZE) -/* The traditional U-Boot load address is 160MB into DRAM, so at 0x4a000000 */ -#define PLAT_SUNXI_NS_IMAGE_OFFSET (SUNXI_DRAM_BASE + (160U << 20)) - /* How much memory to reserve as secure for BL32, if configured */ #define SUNXI_DRAM_SEC_SIZE (32U << 20) diff --git a/plat/allwinner/common/sunxi_bl31_setup.c b/plat/allwinner/common/sunxi_bl31_setup.c index e836a345b..9c8eaa409 100644 --- a/plat/allwinner/common/sunxi_bl31_setup.c +++ b/plat/allwinner/common/sunxi_bl31_setup.c @@ -57,7 +57,7 @@ static void *sunxi_find_dtb(void) for (i = 0; i < 2048 / sizeof(uint64_t); i++) { uint32_t *dtb_base; - if (u_boot_base[i] != PLAT_SUNXI_NS_IMAGE_OFFSET) + if (u_boot_base[i] != PRELOADED_BL33_BASE) continue; /* Does the suspected U-Boot size look anyhow reasonable? */ @@ -96,7 +96,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, * Tell BL31 where the non-trusted software image * is located and the entry state information */ - bl33_image_ep_info.pc = plat_get_ns_image_entrypoint(); + bl33_image_ep_info.pc = PRELOADED_BL33_BASE; bl33_image_ep_info.spsr = SPSR_64(MODE_EL2, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); diff --git a/plat/allwinner/common/sunxi_common.c b/plat/allwinner/common/sunxi_common.c index 0ca18adc3..39dc6f933 100644 --- a/plat/allwinner/common/sunxi_common.c +++ b/plat/allwinner/common/sunxi_common.c @@ -27,7 +27,7 @@ static const mmap_region_t sunxi_mmap[PLATFORM_MMAP_REGIONS + 1] = { MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER), MAP_REGION(SUNXI_DRAM_BASE, SUNXI_DRAM_VIRT_BASE, SUNXI_DRAM_SEC_SIZE, MT_RW_DATA | MT_SECURE), - MAP_REGION(PLAT_SUNXI_NS_IMAGE_OFFSET, + MAP_REGION(PRELOADED_BL33_BASE, SUNXI_DRAM_VIRT_BASE + SUNXI_DRAM_SEC_SIZE, SUNXI_DRAM_MAP_SIZE, MT_RO_DATA | MT_NS), @@ -39,15 +39,6 @@ unsigned int plat_get_syscnt_freq2(void) return SUNXI_OSC24M_CLK_IN_HZ; } -uintptr_t plat_get_ns_image_entrypoint(void) -{ -#ifdef PRELOADED_BL33_BASE - return PRELOADED_BL33_BASE; -#else - return PLAT_SUNXI_NS_IMAGE_OFFSET; -#endif -} - void sunxi_configure_mmu_el3(int flags) { mmap_add_region(BL_CODE_BASE, BL_CODE_BASE, -- cgit v1.2.3 From 74665119f04de0cd7c735fa741aff607a4a9fde8 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sun, 13 Dec 2020 22:22:17 -0600 Subject: allwinner: Enable workaround for Cortex-A53 erratum 1530924 BL31 reports the following warning during boot: WARNING: BL31: cortex_a53: CPU workaround for 1530924 was missing! Resolve this by enabling the workaround on the affected platforms. Change-Id: Ia1d5075370be5ae67b7bece96ec0069d9692b14c Signed-off-by: Samuel Holland --- plat/allwinner/common/allwinner-common.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/plat/allwinner/common/allwinner-common.mk b/plat/allwinner/common/allwinner-common.mk index 997aaa6f7..88ffc31f7 100644 --- a/plat/allwinner/common/allwinner-common.mk +++ b/plat/allwinner/common/allwinner-common.mk @@ -48,6 +48,7 @@ ENABLE_SVE_FOR_NS := 0 ERRATA_A53_835769 := 1 ERRATA_A53_843419 := 1 ERRATA_A53_855873 := 1 +ERRATA_A53_1530924 := 1 # The reset vector can be changed for each CPU. PROGRAMMABLE_RESET_ADDRESS := 1 -- cgit v1.2.3 From d6fdb52b9c9db0454fa49dbbb969ea4164de29c0 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sun, 13 Dec 2020 22:53:02 -0600 Subject: allwinner: Always use a 3MHz RSB bus clock None of the other drivers (Linux, U-Boot, Crust) need to lower the bus clock frequency to switch the PMIC to RSB mode. That logic is not needed here, either. The hardware takes care of running this transaction at the correct bus frequency. Signed-off-by: Samuel Holland Change-Id: Idcfe933df4da75d5fd5a4f3e362da40ac26bdad1 --- plat/allwinner/sun50i_a64/sunxi_power.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/plat/allwinner/sun50i_a64/sunxi_power.c b/plat/allwinner/sun50i_a64/sunxi_power.c index 5b7d76ae9..8aa610cc3 100644 --- a/plat/allwinner/sun50i_a64/sunxi_power.c +++ b/plat/allwinner/sun50i_a64/sunxi_power.c @@ -92,8 +92,8 @@ static int rsb_init(void) if (ret) return ret; - /* Start with 400 KHz to issue the I2C->RSB switch command. */ - ret = rsb_set_bus_speed(SUNXI_OSC24M_CLK_IN_HZ, 400000); + /* Switch to the recommended 3 MHz bus clock. */ + ret = rsb_set_bus_speed(SUNXI_OSC24M_CLK_IN_HZ, 3000000); if (ret) return ret; @@ -105,11 +105,6 @@ static int rsb_init(void) if (ret) return ret; - /* Now in RSB mode, switch to the recommended 3 MHz. */ - ret = rsb_set_bus_speed(SUNXI_OSC24M_CLK_IN_HZ, 3000000); - if (ret) - return ret; - /* Associate the 8-bit runtime address with the 12-bit bus address. */ ret = rsb_assign_runtime_address(AXP803_HW_ADDR, AXP803_RT_ADDR); -- cgit v1.2.3 From 4470298333d0e453d5ac2f9beb73b6a3787edcce Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sun, 13 Dec 2020 22:43:15 -0600 Subject: allwinner: Return the PMIC to I2C mode after use This gives the rich OS the flexibility to choose between I2C and RSB communication. Since a runtime address can only be assigned once after entering RSB mode, it also lets the rich OS choose any runtime address. Signed-off-by: Samuel Holland Change-Id: Id49c124c5e925985fc31c0ba38c7fb6c941aafa8 --- include/drivers/allwinner/axp.h | 4 ++++ plat/allwinner/sun50i_a64/sunxi_power.c | 12 +++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/include/drivers/allwinner/axp.h b/include/drivers/allwinner/axp.h index 9c0035f96..222820b12 100644 --- a/include/drivers/allwinner/axp.h +++ b/include/drivers/allwinner/axp.h @@ -9,6 +9,10 @@ #include +#define AXP20X_MODE_REG 0x3e +#define AXP20X_MODE_I2C 0x00 +#define AXP20X_MODE_RSB 0x7c + #define NA 0xff enum { diff --git a/plat/allwinner/sun50i_a64/sunxi_power.c b/plat/allwinner/sun50i_a64/sunxi_power.c index 8aa610cc3..80a69c340 100644 --- a/plat/allwinner/sun50i_a64/sunxi_power.c +++ b/plat/allwinner/sun50i_a64/sunxi_power.c @@ -97,11 +97,8 @@ static int rsb_init(void) if (ret) return ret; - /* - * Initiate an I2C transaction to write 0x7c into register 0x3e, - * switching the PMIC to RSB mode. - */ - ret = rsb_set_device_mode(0x7c3e00); + /* Initiate an I2C transaction to switch the PMIC to RSB mode. */ + ret = rsb_set_device_mode(AXP20X_MODE_RSB << 16 | AXP20X_MODE_REG << 8); if (ret) return ret; @@ -151,6 +148,11 @@ int sunxi_pmic_setup(uint16_t socid, const void *fdt) pmic = AXP803_RSB; axp_setup_regulators(fdt); + /* Switch the PMIC back to I2C mode. */ + ret = axp_write(AXP20X_MODE_REG, AXP20X_MODE_I2C); + if (ret) + return ret; + break; default: return -ENODEV; -- cgit v1.2.3 From 7060e0d891b9f9cccf46867de142e1808c61fd6d Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sun, 13 Dec 2020 22:34:10 -0600 Subject: allwinner: Use RSB for the PMIC connection on H6 RSB is faster and more efficient, and it has a simpler driver. As long as the PMIC is returned to I2C mode after use, the rich OS can later use either bus. Change-Id: I0c5f32e88a090c8c5cccb81bd24596b301ab9da7 Signed-off-by: Samuel Holland --- plat/allwinner/common/sunxi_common.c | 8 ++- plat/allwinner/sun50i_h6/include/sunxi_mmap.h | 1 + plat/allwinner/sun50i_h6/platform.mk | 2 +- plat/allwinner/sun50i_h6/sunxi_power.c | 74 +++++++++++++-------------- 4 files changed, 40 insertions(+), 45 deletions(-) diff --git a/plat/allwinner/common/sunxi_common.c b/plat/allwinner/common/sunxi_common.c index 0ca18adc3..841fea81d 100644 --- a/plat/allwinner/common/sunxi_common.c +++ b/plat/allwinner/common/sunxi_common.c @@ -125,11 +125,9 @@ int sunxi_init_platform_r_twi(uint16_t socid, bool use_rsb) device_bit = BIT(6); break; case SUNXI_SOC_H6: - if (use_rsb) - return -ENODEV; - pin_func = 0x33; + pin_func = use_rsb ? 0x22 : 0x33; device_bit = BIT(16); - reset_offset = 0x19c; + reset_offset = use_rsb ? 0x1bc : 0x19c; break; case SUNXI_SOC_A64: pin_func = use_rsb ? 0x22 : 0x33; @@ -157,7 +155,7 @@ int sunxi_init_platform_r_twi(uint16_t socid, bool use_rsb) if (socid != SUNXI_SOC_H6) mmio_setbits_32(SUNXI_R_PRCM_BASE + 0x28, device_bit); else - mmio_setbits_32(SUNXI_R_PRCM_BASE + 0x19c, device_bit | BIT(0)); + mmio_setbits_32(SUNXI_R_PRCM_BASE + reset_offset, BIT(0)); /* assert, then de-assert reset of I2C/RSB controller */ mmio_clrbits_32(SUNXI_R_PRCM_BASE + reset_offset, device_bit); diff --git a/plat/allwinner/sun50i_h6/include/sunxi_mmap.h b/plat/allwinner/sun50i_h6/include/sunxi_mmap.h index 702db770f..1b716061b 100644 --- a/plat/allwinner/sun50i_h6/include/sunxi_mmap.h +++ b/plat/allwinner/sun50i_h6/include/sunxi_mmap.h @@ -55,6 +55,7 @@ #define SUNXI_R_TWD_BASE 0x07020800 #define SUNXI_R_CPUCFG_BASE 0x07000400 #define SUNXI_R_I2C_BASE 0x07081400 +#define SUNXI_R_RSB_BASE 0x07083000 #define SUNXI_R_UART_BASE 0x07080000 #define SUNXI_R_PIO_BASE 0x07022000 diff --git a/plat/allwinner/sun50i_h6/platform.mk b/plat/allwinner/sun50i_h6/platform.mk index 4ecc57cf0..1c98919b1 100644 --- a/plat/allwinner/sun50i_h6/platform.mk +++ b/plat/allwinner/sun50i_h6/platform.mk @@ -8,4 +8,4 @@ include plat/allwinner/common/allwinner-common.mk BL31_SOURCES += drivers/allwinner/axp/axp805.c \ - drivers/mentor/i2c/mi2cv.c + drivers/allwinner/sunxi_rsb.c diff --git a/plat/allwinner/sun50i_h6/sunxi_power.c b/plat/allwinner/sun50i_h6/sunxi_power.c index 443015bac..a7865a5d4 100644 --- a/plat/allwinner/sun50i_h6/sunxi_power.c +++ b/plat/allwinner/sun50i_h6/sunxi_power.c @@ -6,20 +6,17 @@ */ #include -#include -#include #include #include -#include -#include -#include +#include #include #include #include -#define AXP805_ADDR 0x36 +#define AXP805_HW_ADDR 0x745 +#define AXP805_RT_ADDR 0x3a static enum pmic_type { UNKNOWN, @@ -28,67 +25,67 @@ static enum pmic_type { int axp_read(uint8_t reg) { - uint8_t val; - int ret; - - ret = i2c_write(AXP805_ADDR, 0, 0, ®, 1); - if (ret == 0) - ret = i2c_read(AXP805_ADDR, 0, 0, &val, 1); - if (ret) { - ERROR("PMIC: Cannot read AXP805 register %02x\n", reg); - return ret; - } - - return val; + return rsb_read(AXP805_RT_ADDR, reg); } int axp_write(uint8_t reg, uint8_t val) { - int ret; - - ret = i2c_write(AXP805_ADDR, reg, 1, &val, 1); - if (ret) - ERROR("PMIC: Cannot write AXP805 register %02x\n", reg); - - return ret; + return rsb_write(AXP805_RT_ADDR, reg, val); } -static int axp805_probe(void) +static int rsb_init(void) { int ret; - /* Switch the AXP805 to master/single-PMIC mode. */ - ret = axp_write(0xff, 0x0); + ret = rsb_init_controller(); if (ret) return ret; - ret = axp_check_id(); + /* Switch to the recommended 3 MHz bus clock. */ + ret = rsb_set_bus_speed(SUNXI_OSC24M_CLK_IN_HZ, 3000000); if (ret) return ret; - return 0; + /* Initiate an I2C transaction to switch the PMIC to RSB mode. */ + ret = rsb_set_device_mode(AXP20X_MODE_RSB << 16 | AXP20X_MODE_REG << 8); + if (ret) + return ret; + + /* Associate the 8-bit runtime address with the 12-bit bus address. */ + ret = rsb_assign_runtime_address(AXP805_HW_ADDR, AXP805_RT_ADDR); + if (ret) + return ret; + + return axp_check_id(); } int sunxi_pmic_setup(uint16_t socid, const void *fdt) { int ret; - INFO("PMIC: Probing AXP805 on I2C\n"); + INFO("PMIC: Probing AXP805 on RSB\n"); - ret = sunxi_init_platform_r_twi(SUNXI_SOC_H6, false); + ret = sunxi_init_platform_r_twi(socid, true); if (ret) return ret; - /* initialise mi2cv driver */ - i2c_init((void *)SUNXI_R_I2C_BASE); + ret = rsb_init(); + if (ret) + return ret; - ret = axp805_probe(); + /* Switch the AXP805 to master/single-PMIC mode. */ + ret = axp_write(0xff, 0x0); if (ret) return ret; pmic = AXP805; axp_setup_regulators(fdt); + /* Switch the PMIC back to I2C mode. */ + ret = axp_write(AXP20X_MODE_REG, AXP20X_MODE_I2C); + if (ret) + return ret; + return 0; } @@ -96,10 +93,9 @@ void sunxi_power_down(void) { switch (pmic) { case AXP805: - /* Re-initialise after rich OS might have used it. */ - sunxi_init_platform_r_twi(SUNXI_SOC_H6, false); - /* initialise mi2cv driver */ - i2c_init((void *)SUNXI_R_I2C_BASE); + /* (Re-)init RSB in case the rich OS has disabled it. */ + sunxi_init_platform_r_twi(SUNXI_SOC_H6, true); + rsb_init(); axp_power_off(); break; default: -- cgit v1.2.3 From f66827c0a1c9b94ecc2b402dfaa2e80e0df29c8d Mon Sep 17 00:00:00 2001 From: Arunachalam Ganapathy Date: Tue, 17 Nov 2020 14:56:39 +0000 Subject: plat: arm: Increase SP max size Increase SP max size for latest OP-TEE build with debug and stats enabled. Signed-off-by: Arunachalam Ganapathy Change-Id: I4593884e0deb39ada10009f6876d815136f8ee65 --- include/plat/arm/common/fconf_arm_sp_getter.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/plat/arm/common/fconf_arm_sp_getter.h b/include/plat/arm/common/fconf_arm_sp_getter.h index c6315bee2..aa628dfd3 100644 --- a/include/plat/arm/common/fconf_arm_sp_getter.h +++ b/include/plat/arm/common/fconf_arm_sp_getter.h @@ -13,7 +13,7 @@ /* arm_sp getter */ #define arm__sp_getter(prop) arm_sp.prop -#define ARM_SP_MAX_SIZE U(0x80000) +#define ARM_SP_MAX_SIZE U(0xb0000) #define ARM_SP_OWNER_NAME_LEN U(8) struct arm_sp_t { -- cgit v1.2.3 From 86069c0cba291eeecc3fe422523745b87553f971 Mon Sep 17 00:00:00 2001 From: Arunachalam Ganapathy Date: Tue, 17 Nov 2020 14:48:59 +0000 Subject: plat: tc0: enable opteed support Enable SPD=opteed support for tc0 platform. Signed-off-by: Arunachalam Ganapathy Change-Id: Ieb038d645c68fbe6b5a211c7279569e21b476fc3 --- plat/arm/board/tc0/tc0_plat.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plat/arm/board/tc0/tc0_plat.c b/plat/arm/board/tc0/tc0_plat.c index e12ad56d8..b5698c098 100644 --- a/plat/arm/board/tc0/tc0_plat.c +++ b/plat/arm/board/tc0/tc0_plat.c @@ -50,6 +50,10 @@ const mmap_region_t plat_arm_mmap[] = { #endif #if TRUSTED_BOARD_BOOT && !BL2_AT_EL3 ARM_MAP_BL1_RW, +#endif +#ifdef SPD_opteed + ARM_MAP_OPTEE_CORE_MEM, + ARM_OPTEE_PAGEABLE_LOAD_MEM, #endif {0} }; -- cgit v1.2.3 From be3a3bc715619b5ea15b3f338cd80d00d92cb836 Mon Sep 17 00:00:00 2001 From: Arunachalam Ganapathy Date: Tue, 8 Dec 2020 16:35:18 +0000 Subject: docs: arm: Add OPTEE_SP_FW_CONFIG This adds documentation for device tree build flag OPTEE_SP_FW_CONFIG. Signed-off-by: Arunachalam Ganapathy Change-Id: Ie45f075cf04182701007f87aa0c8912cd567157a --- docs/plat/arm/arm-build-options.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/plat/arm/arm-build-options.rst b/docs/plat/arm/arm-build-options.rst index 2e50068f6..a1d231357 100644 --- a/docs/plat/arm/arm-build-options.rst +++ b/docs/plat/arm/arm-build-options.rst @@ -94,6 +94,10 @@ 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. +- ``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. + For a better understanding of these options, the Arm development platform memory map is explained in the :ref:`Firmware Design`. -- cgit v1.2.3 From 39460d0570dbe8f6ba7b2d9666e48172bfcb73b0 Mon Sep 17 00:00:00 2001 From: Arunachalam Ganapathy Date: Tue, 17 Nov 2020 15:05:01 +0000 Subject: plat: tc0: OP-TEE as S-EL1 SP with SPMC at S-EL2 This patch adds support to enable OP-TEE as S-EL1 SP with SPMC at S-EL2 - create SPMC manifest file with OP-TEE as SP - add support for ARM_SPMC_MANIFEST_DTS build option - add optee entry with ffa as method in tc0.dts Signed-off-by: Arunachalam Ganapathy Change-Id: Ia9b5c22c6f605d3886914bbac8ac45e8365671cb --- fdts/tc0.dts | 13 ++++ .../board/tc0/fdts/tc0_spmc_optee_sp_manifest.dts | 78 ++++++++++++++++++++++ plat/arm/board/tc0/fdts/tc0_tb_fw_config.dts | 7 ++ plat/arm/board/tc0/include/platform_def.h | 2 +- plat/arm/board/tc0/platform.mk | 8 ++- 5 files changed, 105 insertions(+), 3 deletions(-) create mode 100644 plat/arm/board/tc0/fdts/tc0_spmc_optee_sp_manifest.dts diff --git a/fdts/tc0.dts b/fdts/tc0.dts index 763c813cf..2a1c1cd3d 100644 --- a/fdts/tc0.dts +++ b/fdts/tc0.dts @@ -370,4 +370,17 @@ }; }; }; + + ffa { + compatible = "arm,ffa"; + conduit = "smc"; + mem_share_buffer = "tx"; + }; + + firmware { + optee { + compatible = "linaro,optee-tz"; + method = "ffa"; + }; + }; }; diff --git a/plat/arm/board/tc0/fdts/tc0_spmc_optee_sp_manifest.dts b/plat/arm/board/tc0/fdts/tc0_spmc_optee_sp_manifest.dts new file mode 100644 index 000000000..a58b9113e --- /dev/null +++ b/plat/arm/board/tc0/fdts/tc0_spmc_optee_sp_manifest.dts @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +/dts-v1/; + +#define AFF 00 + +#include "fvp-defs.dtsi" +#undef POST +#define POST \ + }; + +/ { + compatible = "arm,ffa-core-manifest-1.0"; + #address-cells = <2>; + #size-cells = <1>; + + attribute { + spmc_id = <0x8000>; + maj_ver = <0x1>; + min_ver = <0x0>; + exec_state = <0x0>; + load_address = <0x0 0xfd000000>; + entrypoint = <0x0 0xfd000000>; + binary_size = <0x80000>; + }; + + /* + * temporary: This entry is added based on v2.4 hafnium and will be + * removed when rebased to upstream master. + */ + chosen { + linux,initrd-start = <0>; + linux,initrd-end = <0>; + }; + + hypervisor { + compatible = "hafnium,hafnium"; + vm1 { + is_ffa_partition; + debug_name = "op-tee"; + load_address = <0xfd280000>; + }; + }; + + cpus { + #address-cells = <0x2>; + #size-cells = <0x0>; + + CPU_0 + + /* + * SPMC (Hafnium) requires secondary core nodes are declared + * in descending order. + */ + CPU_3 + CPU_2 + CPU_1 + }; + + /* + * temporary: This device-memory region is added based on v2.4 hafnium + * and will be removed when rebased to upstream master. As first + * Secure Partition no longer maps device memory. + */ + device-memory@21000000 { + device_type = "device-memory"; + reg = <0x0 0x21000000 0x5f000000>; + }; + + /* 32MB of TC0_TZC_DRAM1_BASE */ + memory@fd000000 { + device_type = "memory"; + reg = <0x0 0xfd000000 0x2000000>; + }; +}; diff --git a/plat/arm/board/tc0/fdts/tc0_tb_fw_config.dts b/plat/arm/board/tc0/fdts/tc0_tb_fw_config.dts index 3df94bf92..de5f95d5e 100644 --- a/plat/arm/board/tc0/fdts/tc0_tb_fw_config.dts +++ b/plat/arm/board/tc0/fdts/tc0_tb_fw_config.dts @@ -27,6 +27,12 @@ secure-partitions { compatible = "arm,sp"; +#if OPTEE_SP_FW_CONFIG + op-tee { + uuid = <0x486178e0 0xe7f811e3 0xbc5e0002 0xa5d5c51b>; + load-address = <0xfd280000>; + }; +#else cactus-primary { uuid = <0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>; load-address = <0xfe000000>; @@ -43,5 +49,6 @@ uuid = <0x79b55c73 0x1d8c44b9 0x859361e1 0x770ad8d2>; load-address = <0xfe200000>; }; +#endif }; }; diff --git a/plat/arm/board/tc0/include/platform_def.h b/plat/arm/board/tc0/include/platform_def.h index 72a035f0a..2ff2699b3 100644 --- a/plat/arm/board/tc0/include/platform_def.h +++ b/plat/arm/board/tc0/include/platform_def.h @@ -112,7 +112,7 @@ * little space for growth. */ #if TRUSTED_BOARD_BOOT -# define PLAT_ARM_MAX_BL2_SIZE 0x1E000 +# define PLAT_ARM_MAX_BL2_SIZE 0x20000 #else # define PLAT_ARM_MAX_BL2_SIZE 0x14000 #endif diff --git a/plat/arm/board/tc0/platform.mk b/plat/arm/board/tc0/platform.mk index 5d2cc38c4..6cc5f4618 100644 --- a/plat/arm/board/tc0/platform.mk +++ b/plat/arm/board/tc0/platform.mk @@ -86,8 +86,12 @@ $(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG})) $(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG})) ifeq (${SPD},spmd) -FDT_SOURCES += ${TC0_BASE}/fdts/${PLAT}_spmc_manifest.dts -TC0_TOS_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_spmc_manifest.dtb +ifeq ($(ARM_SPMC_MANIFEST_DTS),) +ARM_SPMC_MANIFEST_DTS := ${TC0_BASE}/fdts/${PLAT}_spmc_manifest.dts +endif + +FDT_SOURCES += ${ARM_SPMC_MANIFEST_DTS} +TC0_TOS_FW_CONFIG := ${BUILD_PLAT}/fdts/$(notdir $(basename ${ARM_SPMC_MANIFEST_DTS})).dtb # Add the TOS_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${TC0_TOS_FW_CONFIG},--tos-fw-config,${TC0_TOS_FW_CONFIG})) -- cgit v1.2.3 From b153ce0391012e9228b807815a65fa0dc514cf77 Mon Sep 17 00:00:00 2001 From: Arunachalam Ganapathy Date: Mon, 14 Dec 2020 12:31:32 +0000 Subject: fdts: tc0: Add reserved-memory node for OP-TEE Add reserved-memory region for OP-TEE and mark as no-map. This memory region is used by OP-TEE as non-secure shared RAM. Signed-off-by: Arunachalam Ganapathy Change-Id: I5a22999a8c5550024d0f47e848d35924017df245 --- fdts/tc0.dts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/fdts/tc0.dts b/fdts/tc0.dts index 2a1c1cd3d..543847405 100644 --- a/fdts/tc0.dts +++ b/fdts/tc0.dts @@ -109,6 +109,17 @@ reg = <0x0 0x80000000 0x0 0x7d000000>; }; + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + optee@0xfce00000 { + reg = <0x00000000 0xfce00000 0 0x00200000>; + no-map; + }; + }; + psci { compatible = "arm,psci-1.0", "arm,psci-0.2", "arm,psci"; method = "smc"; -- cgit v1.2.3 From 4b310108b3e33e4d0c38125e7b0db313ab65e0b1 Mon Sep 17 00:00:00 2001 From: Rajan Vaja Date: Mon, 23 Nov 2020 21:33:39 -0800 Subject: zynqmp: pm: Update return type in query functions In pm_query_data() function return type is stored in response so there is no use of return type. Update return type of function pm_query_data() from enum pm_ret_status to void. Similarly update return type of pm_api_clock_get_name() and pm_api_pinctrl_get_function_name() functions. Signed-off-by: Rajan Vaja Change-Id: Id811926f0b4ebcc472480bb94f3b88109eb036cd --- plat/xilinx/zynqmp/pm_service/pm_api_clock.c | 4 +- plat/xilinx/zynqmp/pm_service/pm_api_clock.h | 4 +- plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c | 7 +-- plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h | 5 +- plat/xilinx/zynqmp/pm_service/pm_api_sys.c | 71 +++++++++----------------- plat/xilinx/zynqmp/pm_service/pm_api_sys.h | 7 +-- plat/xilinx/zynqmp/pm_service/pm_svc_main.c | 4 +- 7 files changed, 33 insertions(+), 69 deletions(-) diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c index f2dfbb17b..0cc517ec9 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c +++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c @@ -2446,7 +2446,7 @@ enum pm_ret_status pm_api_clock_get_num_clocks(unsigned int *nclocks) * * @return Returns success. In case of error, name data is 0. */ -enum pm_ret_status pm_api_clock_get_name(unsigned int clock_id, char *name) +void pm_api_clock_get_name(unsigned int clock_id, char *name) { if (clock_id == CLK_MAX) memcpy(name, END_OF_CLK, sizeof(END_OF_CLK) > CLK_NAME_LEN ? @@ -2458,8 +2458,6 @@ enum pm_ret_status pm_api_clock_get_name(unsigned int clock_id, char *name) else memcpy(name, ext_clocks[clock_id - CLK_MAX_OUTPUT_CLK].name, CLK_NAME_LEN); - - return PM_RET_SUCCESS; } /** diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.h b/plat/xilinx/zynqmp/pm_service/pm_api_clock.h index 301ed24b6..5efd63ff5 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.h +++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -294,7 +294,7 @@ struct pm_pll *pm_clock_get_pll(enum clock_id clock_id); struct pm_pll *pm_clock_get_pll_by_related_clk(enum clock_id clock_id); uint8_t pm_clock_has_div(unsigned int clock_id, enum pm_clock_div_id div_id); -enum pm_ret_status pm_api_clock_get_name(unsigned int clock_id, char *name); +void pm_api_clock_get_name(unsigned int clock_id, char *name); enum pm_ret_status pm_api_clock_get_num_clocks(unsigned int *nclocks); enum pm_ret_status pm_api_clock_get_topology(unsigned int clock_id, unsigned int index, diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c index 4b8dfb614..05bbe722d 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c +++ b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c @@ -2604,18 +2604,13 @@ enum pm_ret_status pm_api_pinctrl_get_num_func_groups(unsigned int fid, * * This function is used by master to get name of function specified * by given function ID. - * - * @return Returns success. In case of error, name data is 0. */ -enum pm_ret_status pm_api_pinctrl_get_function_name(unsigned int fid, - char *name) +void pm_api_pinctrl_get_function_name(unsigned int fid, char *name) { if (fid >= MAX_FUNCTION) memcpy(name, END_OF_FUNCTION, FUNCTION_NAME_LEN); else memcpy(name, pinctrl_functions[fid].name, FUNCTION_NAME_LEN); - - return PM_RET_SUCCESS; } /** diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h index 9923c00ba..414a27334 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h +++ b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -719,8 +719,7 @@ enum pm_ret_status pm_api_pinctrl_set_config(unsigned int pin, enum pm_ret_status pm_api_pinctrl_get_config(unsigned int pin, unsigned int param, unsigned int *value); -enum pm_ret_status pm_api_pinctrl_get_function_name(unsigned int fid, - char *name); +void pm_api_pinctrl_get_function_name(unsigned int fid, char *name); enum pm_ret_status pm_api_pinctrl_get_function_groups(unsigned int fid, unsigned int index, uint16_t *groups); diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c index cd9d597bf..c37a3b3d3 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c +++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c @@ -793,12 +793,10 @@ static enum pm_ret_status pm_clock_get_num_clocks(uint32_t *nclocks) * * This function is used by master to get nmae of clock specified * by given clock ID. - * - * @return Returns status, either success or error+reason */ -static enum pm_ret_status pm_clock_get_name(unsigned int clock_id, char *name) +static void pm_clock_get_name(unsigned int clock_id, char *name) { - return pm_api_clock_get_name(clock_id, name); + pm_api_clock_get_name(clock_id, name); } /** @@ -1235,13 +1233,10 @@ static enum pm_ret_status pm_pinctrl_get_num_function_groups(unsigned int fid, * * This function is used by master to get name of function specified * by given function Id - * - * Return: Returns status, either success or error+reason. */ -static enum pm_ret_status pm_pinctrl_get_function_name(unsigned int fid, - char *name) +static void pm_pinctrl_get_function_name(unsigned int fid, char *name) { - return pm_api_pinctrl_get_function_name(fid, name); + pm_api_pinctrl_get_function_name(fid, name); } /** @@ -1301,78 +1296,58 @@ static enum pm_ret_status pm_pinctrl_get_pin_groups(unsigned int pin_id, * @data Returned output data * * This function returns requested data. - * - * @return Returns status, either success or error+reason */ -enum pm_ret_status pm_query_data(enum pm_query_id qid, - unsigned int arg1, - unsigned int arg2, - unsigned int arg3, - unsigned int *data) +void pm_query_data(enum pm_query_id qid, unsigned int arg1, unsigned int arg2, + unsigned int arg3, unsigned int *data) { - enum pm_ret_status ret; - switch (qid) { case PM_QID_CLOCK_GET_NAME: - ret = pm_clock_get_name(arg1, (char *)data); + pm_clock_get_name(arg1, (char *)data); break; case PM_QID_CLOCK_GET_TOPOLOGY: - ret = pm_clock_get_topology(arg1, arg2, &data[1]); - data[0] = (unsigned int)ret; + data[0] = pm_clock_get_topology(arg1, arg2, &data[1]); break; case PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS: - ret = pm_clock_get_fixedfactor_params(arg1, &data[1], &data[2]); - data[0] = (unsigned int)ret; + data[0] = pm_clock_get_fixedfactor_params(arg1, &data[1], + &data[2]); break; case PM_QID_CLOCK_GET_PARENTS: - ret = pm_clock_get_parents(arg1, arg2, &data[1]); - data[0] = (unsigned int)ret; + data[0] = pm_clock_get_parents(arg1, arg2, &data[1]); break; case PM_QID_CLOCK_GET_ATTRIBUTES: - ret = pm_clock_get_attributes(arg1, &data[1]); - data[0] = (unsigned int)ret; + data[0] = pm_clock_get_attributes(arg1, &data[1]); break; case PM_QID_PINCTRL_GET_NUM_PINS: - ret = pm_pinctrl_get_num_pins(&data[1]); - data[0] = (unsigned int)ret; + data[0] = pm_pinctrl_get_num_pins(&data[1]); break; case PM_QID_PINCTRL_GET_NUM_FUNCTIONS: - ret = pm_pinctrl_get_num_functions(&data[1]); - data[0] = (unsigned int)ret; + data[0] = pm_pinctrl_get_num_functions(&data[1]); break; case PM_QID_PINCTRL_GET_NUM_FUNCTION_GROUPS: - ret = pm_pinctrl_get_num_function_groups(arg1, &data[1]); - data[0] = (unsigned int)ret; + data[0] = pm_pinctrl_get_num_function_groups(arg1, &data[1]); break; case PM_QID_PINCTRL_GET_FUNCTION_NAME: - ret = pm_pinctrl_get_function_name(arg1, (char *)data); + pm_pinctrl_get_function_name(arg1, (char *)data); break; case PM_QID_PINCTRL_GET_FUNCTION_GROUPS: - ret = pm_pinctrl_get_function_groups(arg1, arg2, - (uint16_t *)&data[1]); - data[0] = (unsigned int)ret; + data[0] = pm_pinctrl_get_function_groups(arg1, arg2, + (uint16_t *)&data[1]); break; case PM_QID_PINCTRL_GET_PIN_GROUPS: - ret = pm_pinctrl_get_pin_groups(arg1, arg2, - (uint16_t *)&data[1]); - data[0] = (unsigned int)ret; + data[0] = pm_pinctrl_get_pin_groups(arg1, arg2, + (uint16_t *)&data[1]); break; case PM_QID_CLOCK_GET_NUM_CLOCKS: - ret = pm_clock_get_num_clocks(&data[1]); - data[0] = (unsigned int)ret; + data[0] = pm_clock_get_num_clocks(&data[1]); break; case PM_QID_CLOCK_GET_MAX_DIVISOR: - ret = pm_clock_get_max_divisor(arg1, arg2, &data[1]); - data[0] = (unsigned int)ret; + data[0] = pm_clock_get_max_divisor(arg1, arg2, &data[1]); break; default: - ret = PM_RET_ERROR_ARGS; + data[0] = PM_RET_ERROR_ARGS; WARN("Unimplemented query service call: 0x%x\n", qid); - break; } - - return ret; } enum pm_ret_status pm_sha_hash(uint32_t address_high, diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h index ff66d3f02..930e4702f 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h +++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h @@ -151,11 +151,8 @@ enum pm_ret_status pm_clock_setparent(unsigned int clock_id, unsigned int parent_id); enum pm_ret_status pm_clock_getparent(unsigned int clock_id, unsigned int *parent_id); -enum pm_ret_status pm_query_data(enum pm_query_id qid, - unsigned int arg1, - unsigned int arg2, - unsigned int arg3, - unsigned int *data); +void pm_query_data(enum pm_query_id qid, unsigned int arg1, unsigned int arg2, + unsigned int arg3, unsigned int *data); enum pm_ret_status pm_sha_hash(uint32_t address_high, uint32_t address_low, uint32_t size, diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c index 3f4f0691e..14321ec77 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c +++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c @@ -474,8 +474,8 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, { uint32_t data[4] = { 0 }; - ret = pm_query_data(pm_arg[0], pm_arg[1], pm_arg[2], - pm_arg[3], data); + pm_query_data(pm_arg[0], pm_arg[1], pm_arg[2], + pm_arg[3], data); SMC_RET2(handle, (uint64_t)data[0] | ((uint64_t)data[1] << 32), (uint64_t)data[2] | ((uint64_t)data[3] << 32)); } -- cgit v1.2.3 From 43a029cb97630c69a897de10c582b98cb15a3204 Mon Sep 17 00:00:00 2001 From: Mirela Simonovic Date: Thu, 13 Sep 2018 12:49:45 +0200 Subject: zynqmp: pm: Implement pinctrl request/release EEMI API The calls are just passed through to the PMU-FW. Before issuing other pinctrl functions the pin should be successfully requested. Signed-off-by: Mirela Simonovic Signed-off-by: Rajan Vaja Change-Id: Ibce280edebedf779b3962009c274d0b3d928e0e4 --- plat/xilinx/zynqmp/pm_service/pm_api_sys.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c index c37a3b3d3..d6e0369df 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c +++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c @@ -655,7 +655,11 @@ void pm_get_callbackdata(uint32_t *data, size_t count) */ enum pm_ret_status pm_pinctrl_request(unsigned int pin) { - return PM_RET_SUCCESS; + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMU */ + PM_PACK_PAYLOAD2(payload, PM_PINCTRL_REQUEST, pin); + return pm_ipi_send_sync(primary_proc, payload, NULL, 0); } /** @@ -668,7 +672,11 @@ enum pm_ret_status pm_pinctrl_request(unsigned int pin) */ enum pm_ret_status pm_pinctrl_release(unsigned int pin) { - return PM_RET_SUCCESS; + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMU */ + PM_PACK_PAYLOAD2(payload, PM_PINCTRL_RELEASE, pin); + return pm_ipi_send_sync(primary_proc, payload, NULL, 0); } /** -- cgit v1.2.3 From 10a346d9ce3889715dce21f8a1873a94912df41c Mon Sep 17 00:00:00 2001 From: Mirela Simonovic Date: Thu, 13 Sep 2018 12:49:46 +0200 Subject: zynqmp: pm: Reimplement pinctrl set/get function EEMI API Functions are reimplemented to issue system-level pinctrl EEMI calls to the PMU-FW rather than using MMIO read/write. Macros and functions that appear to be unused after the change is made are removed. Signed-off-by: Mirela Simonovic Signed-off-by: Rajan Vaja Change-Id: I21b8fda855aa69090b85d6aaf411e19560201cb5 --- plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c | 106 ------------------------- plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h | 4 - plat/xilinx/zynqmp/pm_service/pm_api_sys.c | 23 +++--- 3 files changed, 13 insertions(+), 120 deletions(-) diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c index 05bbe722d..a9ab6e153 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c +++ b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c @@ -19,9 +19,7 @@ #include "pm_common.h" #include "pm_ipi.h" -#define PINCTRL_FUNCTION_MASK U(0xFE) #define PINCTRL_VOLTAGE_STATUS_MASK U(0x01) -#define NFUNCS_PER_PIN U(13) #define PINCTRL_NUM_MIOS U(78) #define MAX_PIN_PER_REG U(26) #define PINCTRL_BANK_ADDR_STEP U(28) @@ -46,12 +44,6 @@ #define PINCTRL_REGVAL_TO_PIN_CONFIG(_pin, _val) \ (((_val) >> PINCTRL_PIN_OFFSET(_pin)) & 0x1) -static uint8_t pm_pinctrl_mux[NFUNCS_PER_PIN] = { - 0x02, 0x04, 0x08, 0x10, 0x18, - 0x00, 0x20, 0x40, 0x60, 0x80, - 0xA0, 0xC0, 0xE0 -}; - struct pinctrl_function { char name[FUNCTION_NAME_LEN]; uint16_t (*groups)[]; @@ -2709,104 +2701,6 @@ enum pm_ret_status pm_api_pinctrl_get_pin_groups(unsigned int pin, return PM_RET_SUCCESS; } -/** - * pm_api_pinctrl_get_function() - Read function id set for the given pin - * @pin Pin number - * @nid Node ID of function currently set for given pin - * - * This function provides the function currently set for the given pin. - * - * @return Returns status, either success or error+reason - */ -enum pm_ret_status pm_api_pinctrl_get_function(unsigned int pin, - unsigned int *id) -{ - unsigned int i = 0, j = 0; - enum pm_ret_status ret = PM_RET_SUCCESS; - unsigned int ctrlreg, val, gid; - uint16_t *grps; - - ctrlreg = IOU_SLCR_BASEADDR + 4U * pin; - ret = pm_mmio_read(ctrlreg, &val); - if (ret != PM_RET_SUCCESS) - return ret; - - val &= PINCTRL_FUNCTION_MASK; - - for (i = 0; i < NFUNCS_PER_PIN; i++) - if (val == pm_pinctrl_mux[i]) - break; - - if (i == NFUNCS_PER_PIN) - return PM_RET_ERROR_NOTSUPPORTED; - - gid = *(*zynqmp_pin_groups[pin].groups + i); - - for (i = 0; i < MAX_FUNCTION; i++) { - grps = *pinctrl_functions[i].groups; - if (grps == NULL) - continue; - if (val != pinctrl_functions[i].regval) - continue; - - for (j = 0; grps[j] != (uint16_t)END_OF_GROUPS; j++) { - if (gid == grps[j]) { - *id = i; - goto done; - } - } - } - if (i == MAX_FUNCTION) - ret = PM_RET_ERROR_ARGS; -done: - return ret; -} - -/** - * pm_api_pinctrl_set_function() - Set function id set for the given pin - * @pin Pin number - * @nid Node ID of function to set for given pin - * - * This function provides the function currently set for the given pin. - * - * @return Returns status, either success or error+reason - */ -enum pm_ret_status pm_api_pinctrl_set_function(unsigned int pin, - unsigned int fid) -{ - int i, j; - unsigned int ctrlreg, val; - uint16_t *pgrps, *fgrps; - - ctrlreg = IOU_SLCR_BASEADDR + 4U * pin; - val = pinctrl_functions[fid].regval; - - for (i = 0; i < NFUNCS_PER_PIN; i++) - if (val == pm_pinctrl_mux[i]) - break; - - if (i == NFUNCS_PER_PIN) - return PM_RET_ERROR_NOTSUPPORTED; - - pgrps = *zynqmp_pin_groups[pin].groups; - if (!pgrps) - return PM_RET_ERROR_NOTSUPPORTED; - - fgrps = *pinctrl_functions[fid].groups; - if (!fgrps) - return PM_RET_ERROR_NOTSUPPORTED; - - for (i = 0; fgrps[i] != (uint16_t)END_OF_GROUPS; i++) - for (j = 0; pgrps[j] != (uint16_t)END_OF_GROUPS; j++) - if (fgrps[i] == pgrps[j]) - goto match; - - return PM_RET_ERROR_NOTSUPPORTED; - -match: - return pm_mmio_write(ctrlreg, PINCTRL_FUNCTION_MASK, val); -} - /** * pm_api_pinctrl_set_config() - Set configuration parameter for given pin * @pin: Pin for which configuration is to be set diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h index 414a27334..7ce61b049 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h +++ b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h @@ -709,10 +709,6 @@ enum { #define PINCTRL_DRIVE_STRENGTH_8MA 2U #define PINCTRL_DRIVE_STRENGTH_12MA 3U -enum pm_ret_status pm_api_pinctrl_set_function(unsigned int pin, - unsigned int fid); -enum pm_ret_status pm_api_pinctrl_get_function(unsigned int pin, - unsigned int *id); enum pm_ret_status pm_api_pinctrl_set_config(unsigned int pin, unsigned int param, unsigned int value); diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c index d6e0369df..1c5d1acc3 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c +++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c @@ -682,31 +682,34 @@ enum pm_ret_status pm_pinctrl_release(unsigned int pin) /** * pm_pinctrl_get_function() - Read function id set for the given pin * @pin Pin number - * @nid Node ID of function currently set for given pin + * @fid ID of function currently set for given pin * * This function provides the function currently set for the given pin. * * @return Returns status, either success or error+reason */ -enum pm_ret_status pm_pinctrl_get_function(unsigned int pin, - enum pm_node_id *nid) +enum pm_ret_status pm_pinctrl_get_function(unsigned int pin, unsigned int *fid) { - return pm_api_pinctrl_get_function(pin, nid); + uint32_t payload[PAYLOAD_ARG_CNT]; + + PM_PACK_PAYLOAD2(payload, PM_PINCTRL_GET_FUNCTION, pin); + return pm_ipi_send_sync(primary_proc, payload, fid, 1); } /** * pm_pinctrl_set_function() - Set function id set for the given pin * @pin Pin number - * @nid Node ID of function to set for given pin - * - * This function provides the function currently set for the given pin. + * @fid ID of function to set for given pin * * @return Returns status, either success or error+reason */ -enum pm_ret_status pm_pinctrl_set_function(unsigned int pin, - enum pm_node_id nid) +enum pm_ret_status pm_pinctrl_set_function(unsigned int pin, unsigned int fid) { - return pm_api_pinctrl_set_function(pin, (unsigned int)nid); + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMU */ + PM_PACK_PAYLOAD3(payload, PM_PINCTRL_SET_FUNCTION, pin, fid); + return pm_ipi_send_sync(primary_proc, payload, NULL, 0); } /** -- cgit v1.2.3 From 95c3ebcb845dac8e1e9b517efb5ecd50289833ac Mon Sep 17 00:00:00 2001 From: Mirela Simonovic Date: Sun, 22 Nov 2020 23:31:14 -0800 Subject: zynqmp: pm: Reimplement pinctrl get/set config parameter EEMI API calls Functions are reimplemented to issue system-level pinctrl EEMI calls to the PMU-FW rather than using MMIO read/write. Macros and functions that appear to be unused after the change is made are removed. Signed-off-by: Mirela Simonovic Signed-off-by: Rajan Vaja Change-Id: I51f2285a79f202cb2ca9f031044002e16dd1e92f --- plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c | 254 ------------------------- plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h | 6 - plat/xilinx/zynqmp/pm_service/pm_api_sys.c | 16 +- 3 files changed, 11 insertions(+), 265 deletions(-) diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c index a9ab6e153..9a6b497f3 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c +++ b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c @@ -19,31 +19,6 @@ #include "pm_common.h" #include "pm_ipi.h" -#define PINCTRL_VOLTAGE_STATUS_MASK U(0x01) -#define PINCTRL_NUM_MIOS U(78) -#define MAX_PIN_PER_REG U(26) -#define PINCTRL_BANK_ADDR_STEP U(28) - -#define PINCTRL_DRVSTRN0_REG_OFFSET U(0) -#define PINCTRL_DRVSTRN1_REG_OFFSET U(4) -#define PINCTRL_SCHCMOS_REG_OFFSET U(8) -#define PINCTRL_PULLCTRL_REG_OFFSET U(12) -#define PINCTRL_PULLSTAT_REG_OFFSET U(16) -#define PINCTRL_SLEWCTRL_REG_OFFSET U(20) -#define PINCTRL_VOLTAGE_STAT_REG_OFFSET U(24) - -#define IOU_SLCR_BANK1_CTRL5 U(0XFF180164) - -#define PINCTRL_CFG_ADDR_OFFSET(addr, reg, miopin) \ - ((addr) + 4 * PINCTRL_NUM_MIOS + PINCTRL_BANK_ADDR_STEP * \ - ((miopin) / MAX_PIN_PER_REG) + (reg)) - -#define PINCTRL_PIN_OFFSET(_miopin) \ - ((_miopin) - (MAX_PIN_PER_REG * ((_miopin) / MAX_PIN_PER_REG))) - -#define PINCTRL_REGVAL_TO_PIN_CONFIG(_pin, _val) \ - (((_val) >> PINCTRL_PIN_OFFSET(_pin)) & 0x1) - struct pinctrl_function { char name[FUNCTION_NAME_LEN]; uint16_t (*groups)[]; @@ -2700,232 +2675,3 @@ enum pm_ret_status pm_api_pinctrl_get_pin_groups(unsigned int pin, return PM_RET_SUCCESS; } - -/** - * pm_api_pinctrl_set_config() - Set configuration parameter for given pin - * @pin: Pin for which configuration is to be set - * @param: Configuration parameter to be set - * @value: Value to be set for configuration parameter - * - * This function sets value of requested configuration parameter for given pin. - * - * @return Returns status, either success or error+reason - */ -enum pm_ret_status pm_api_pinctrl_set_config(unsigned int pin, - unsigned int param, - unsigned int value) -{ - enum pm_ret_status ret; - unsigned int ctrlreg, mask, val, offset; - - if (param >= PINCTRL_CONFIG_MAX) - return PM_RET_ERROR_NOTSUPPORTED; - - if (pin >= PINCTRL_NUM_MIOS) - return PM_RET_ERROR_ARGS; - - mask = 1 << PINCTRL_PIN_OFFSET(pin); - - switch (param) { - case PINCTRL_CONFIG_SLEW_RATE: - if (value != PINCTRL_SLEW_RATE_FAST && - value != PINCTRL_SLEW_RATE_SLOW) - return PM_RET_ERROR_ARGS; - - ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR, - PINCTRL_SLEWCTRL_REG_OFFSET, - pin); - val = value << PINCTRL_PIN_OFFSET(pin); - ret = pm_mmio_write(ctrlreg, mask, val); - break; - case PINCTRL_CONFIG_BIAS_STATUS: - if (value != PINCTRL_BIAS_ENABLE && - value != PINCTRL_BIAS_DISABLE) - return PM_RET_ERROR_ARGS; - - ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR, - PINCTRL_PULLSTAT_REG_OFFSET, - pin); - - offset = PINCTRL_PIN_OFFSET(pin); - if (ctrlreg == IOU_SLCR_BANK1_CTRL5) - offset = (offset < 12U) ? - (offset + 14U) : (offset - 12U); - - val = value << offset; - mask = 1 << offset; - ret = pm_mmio_write(ctrlreg, mask, val); - break; - case PINCTRL_CONFIG_PULL_CTRL: - - if (value != PINCTRL_BIAS_PULL_DOWN && - value != PINCTRL_BIAS_PULL_UP) - return PM_RET_ERROR_ARGS; - - ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR, - PINCTRL_PULLSTAT_REG_OFFSET, - pin); - - offset = PINCTRL_PIN_OFFSET(pin); - if (ctrlreg == IOU_SLCR_BANK1_CTRL5) - offset = (offset < 12U) ? - (offset + 14U) : (offset - 12U); - - val = PINCTRL_BIAS_ENABLE << offset; - ret = pm_mmio_write(ctrlreg, 1 << offset, val); - if (ret != PM_RET_SUCCESS) - return ret; - - ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR, - PINCTRL_PULLCTRL_REG_OFFSET, - pin); - val = value << PINCTRL_PIN_OFFSET(pin); - ret = pm_mmio_write(ctrlreg, mask, val); - break; - case PINCTRL_CONFIG_SCHMITT_CMOS: - if (value != PINCTRL_INPUT_TYPE_CMOS && - value != PINCTRL_INPUT_TYPE_SCHMITT) - return PM_RET_ERROR_ARGS; - - ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR, - PINCTRL_SCHCMOS_REG_OFFSET, - pin); - - val = value << PINCTRL_PIN_OFFSET(pin); - ret = pm_mmio_write(ctrlreg, mask, val); - break; - case PINCTRL_CONFIG_DRIVE_STRENGTH: - if (value > PINCTRL_DRIVE_STRENGTH_12MA) - return PM_RET_ERROR_ARGS; - - ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR, - PINCTRL_DRVSTRN0_REG_OFFSET, - pin); - val = (value >> 1) << PINCTRL_PIN_OFFSET(pin); - ret = pm_mmio_write(ctrlreg, mask, val); - if (ret) - return ret; - - ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR, - PINCTRL_DRVSTRN1_REG_OFFSET, - pin); - val = (value & 0x01U) << PINCTRL_PIN_OFFSET(pin); - ret = pm_mmio_write(ctrlreg, mask, val); - break; - default: - ERROR("Invalid parameter %u\n", param); - ret = PM_RET_ERROR_NOTSUPPORTED; - break; - } - - return ret; -} - -/** - * pm_api_pinctrl_get_config() - Get configuration parameter value for given pin - * @pin: Pin for which configuration is to be read - * @param: Configuration parameter to be read - * @value: buffer to store value of configuration parameter - * - * This function reads value of requested configuration parameter for given pin. - * - * @return Returns status, either success or error+reason - */ -enum pm_ret_status pm_api_pinctrl_get_config(unsigned int pin, - unsigned int param, - unsigned int *value) -{ - enum pm_ret_status ret; - unsigned int ctrlreg, val; - - if (param >= PINCTRL_CONFIG_MAX) - return PM_RET_ERROR_NOTSUPPORTED; - - if (pin >= PINCTRL_NUM_MIOS) - return PM_RET_ERROR_ARGS; - - switch (param) { - case PINCTRL_CONFIG_SLEW_RATE: - ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR, - PINCTRL_SLEWCTRL_REG_OFFSET, - pin); - - ret = pm_mmio_read(ctrlreg, &val); - if (ret != PM_RET_SUCCESS) - return ret; - - *value = PINCTRL_REGVAL_TO_PIN_CONFIG(pin, val); - break; - case PINCTRL_CONFIG_BIAS_STATUS: - ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR, - PINCTRL_PULLSTAT_REG_OFFSET, - pin); - - ret = pm_mmio_read(ctrlreg, &val); - if (ret) - return ret; - - if (ctrlreg == IOU_SLCR_BANK1_CTRL5) - val = ((val & 0x3FFF) << 12) | ((val >> 14) & 0xFFF); - - *value = PINCTRL_REGVAL_TO_PIN_CONFIG(pin, val); - break; - case PINCTRL_CONFIG_PULL_CTRL: - - ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR, - PINCTRL_PULLCTRL_REG_OFFSET, - pin); - - ret = pm_mmio_read(ctrlreg, &val); - if (ret) - return ret; - - *value = PINCTRL_REGVAL_TO_PIN_CONFIG(pin, val); - break; - case PINCTRL_CONFIG_SCHMITT_CMOS: - ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR, - PINCTRL_SCHCMOS_REG_OFFSET, - pin); - - ret = pm_mmio_read(ctrlreg, &val); - if (ret) - return ret; - - *value = PINCTRL_REGVAL_TO_PIN_CONFIG(pin, val); - break; - case PINCTRL_CONFIG_DRIVE_STRENGTH: - ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR, - PINCTRL_DRVSTRN0_REG_OFFSET, - pin); - ret = pm_mmio_read(ctrlreg, &val); - if (ret) - return ret; - - *value = PINCTRL_REGVAL_TO_PIN_CONFIG(pin, val) << 1; - - ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR, - PINCTRL_DRVSTRN1_REG_OFFSET, - pin); - ret = pm_mmio_read(ctrlreg, &val); - if (ret) - return ret; - - *value |= PINCTRL_REGVAL_TO_PIN_CONFIG(pin, val); - break; - case PINCTRL_CONFIG_VOLTAGE_STATUS: - ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR, - PINCTRL_VOLTAGE_STAT_REG_OFFSET, - pin); - - ret = pm_mmio_read(ctrlreg, &val); - if (ret) - return ret; - - *value = val & PINCTRL_VOLTAGE_STATUS_MASK; - break; - default: - return PM_RET_ERROR_NOTSUPPORTED; - } - - return PM_RET_SUCCESS; -} diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h index 7ce61b049..2b8fca3cd 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h +++ b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h @@ -709,12 +709,6 @@ enum { #define PINCTRL_DRIVE_STRENGTH_8MA 2U #define PINCTRL_DRIVE_STRENGTH_12MA 3U -enum pm_ret_status pm_api_pinctrl_set_config(unsigned int pin, - unsigned int param, - unsigned int value); -enum pm_ret_status pm_api_pinctrl_get_config(unsigned int pin, - unsigned int param, - unsigned int *value); void pm_api_pinctrl_get_function_name(unsigned int fid, char *name); enum pm_ret_status pm_api_pinctrl_get_function_groups(unsigned int fid, unsigned int index, diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c index 1c5d1acc3..1ec06f9d0 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c +++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c @@ -726,24 +726,30 @@ enum pm_ret_status pm_pinctrl_get_config(unsigned int pin, unsigned int param, unsigned int *value) { - return pm_api_pinctrl_get_config(pin, param, value); + uint32_t payload[PAYLOAD_ARG_CNT]; + + PM_PACK_PAYLOAD3(payload, PM_PINCTRL_CONFIG_PARAM_GET, pin, param); + return pm_ipi_send_sync(primary_proc, payload, value, 1); } /** - * pm_pinctrl_set_config() - Read value of requested config param for given pin + * pm_pinctrl_set_config() - Set value of requested config param for given pin * @pin Pin number * @param Parameter to set * @value Parameter value to set * - * This function provides the configuration parameter value for the given pin. - * * @return Returns status, either success or error+reason */ enum pm_ret_status pm_pinctrl_set_config(unsigned int pin, unsigned int param, unsigned int value) { - return pm_api_pinctrl_set_config(pin, param, value); + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMU */ + PM_PACK_PAYLOAD4(payload, PM_PINCTRL_CONFIG_PARAM_SET, pin, param, + value); + return pm_ipi_send_sync(primary_proc, payload, NULL, 0); } /** -- cgit v1.2.3 From fb86e5373ceb3a82485eb3ee2545d15d96a1ce02 Mon Sep 17 00:00:00 2001 From: Vijayenthiran Subramaniam Date: Tue, 15 Dec 2020 20:07:43 +0530 Subject: plat/arm/rdn2: update gic redistributor base address RD-N2 platform has been updated to use six GIC ITS blocks. This results in change in base address of the GIC Redistributor to accomodate two new GIC ITS blocks. Update the base address of GICR to reflect the same. Signed-off-by: Vijayenthiran Subramaniam Change-Id: I740a547328fb9a9f25d7a09c08e61bdbc8bf781c --- plat/arm/board/rdn2/include/platform_def.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/arm/board/rdn2/include/platform_def.h b/plat/arm/board/rdn2/include/platform_def.h index ebfbf66a6..5561f8c6e 100644 --- a/plat/arm/board/rdn2/include/platform_def.h +++ b/plat/arm/board/rdn2/include/platform_def.h @@ -60,6 +60,6 @@ /* GIC related constants */ #define PLAT_ARM_GICD_BASE UL(0x30000000) #define PLAT_ARM_GICC_BASE UL(0x2C000000) -#define PLAT_ARM_GICR_BASE UL(0x30140000) +#define PLAT_ARM_GICR_BASE UL(0x301C0000) #endif /* PLATFORM_DEF_H */ -- cgit v1.2.3 From 42f2fa823fe5ecd2eba0e7141c05859153a49581 Mon Sep 17 00:00:00 2001 From: Xi Chen Date: Mon, 2 Nov 2020 10:45:34 +0800 Subject: mediatek: mt8192: Add MPU support 1 Add Domain1(PCIe device) protect address: 0x80000000~0x83FF0000. 2 Add Domain2(SSPM/SPM/DPM/MCUPM) protect address: 0x40000000~0x1FFFF0000. Signed-off-by: Xi Chen Change-Id: I4aaed37150076ae5943484c4adadac999a3d1762 --- plat/mediatek/mt8192/bl31_plat_setup.c | 4 + plat/mediatek/mt8192/drivers/emi_mpu/emi_mpu.c | 122 +++++++++++++++++++++++++ plat/mediatek/mt8192/drivers/emi_mpu/emi_mpu.h | 102 +++++++++++++++++++++ plat/mediatek/mt8192/include/platform_def.h | 2 + plat/mediatek/mt8192/platform.mk | 2 + 5 files changed, 232 insertions(+) create mode 100644 plat/mediatek/mt8192/drivers/emi_mpu/emi_mpu.c create mode 100644 plat/mediatek/mt8192/drivers/emi_mpu/emi_mpu.h diff --git a/plat/mediatek/mt8192/bl31_plat_setup.c b/plat/mediatek/mt8192/bl31_plat_setup.c index 32e124f1f..9de4a2e62 100644 --- a/plat/mediatek/mt8192/bl31_plat_setup.c +++ b/plat/mediatek/mt8192/bl31_plat_setup.c @@ -16,6 +16,7 @@ #include /* Platform Includes */ +#include #include #include #include @@ -89,6 +90,9 @@ void bl31_platform_setup(void) ERROR("Failed to set default dcm on!!\n"); } + /* MPU Init */ + emi_mpu_init(); + /* Initialize the GIC driver, CPU and distributor interfaces */ mt_gic_driver_init(); mt_gic_init(); diff --git a/plat/mediatek/mt8192/drivers/emi_mpu/emi_mpu.c b/plat/mediatek/mt8192/drivers/emi_mpu/emi_mpu.c new file mode 100644 index 000000000..d5d7e2e29 --- /dev/null +++ b/plat/mediatek/mt8192/drivers/emi_mpu/emi_mpu.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +/* + * emi_mpu_set_region_protection: protect a region. + * @start: start address of the region + * @end: end address of the region + * @access_permission: EMI MPU access permission + * Return 0 for success, otherwise negative status code. + */ +static int _emi_mpu_set_protection( + unsigned long start, unsigned long end, + unsigned int apc) +{ + unsigned int dgroup; + unsigned int region; + + region = (start >> 24) & 0xFF; + start &= 0x00FFFFFF; + dgroup = (end >> 24) & 0xFF; + end &= 0x00FFFFFF; + + if ((region >= EMI_MPU_REGION_NUM) || (dgroup > EMI_MPU_DGROUP_NUM)) { + WARN("Region:%u or dgroup:%u is wrong!\n", region, dgroup); + return -1; + } + + apc &= 0x80FFFFFF; + + if ((start >= DRAM_OFFSET) && (end >= start)) { + start -= DRAM_OFFSET; + end -= DRAM_OFFSET; + } else { + WARN("start:0x%lx or end:0x%lx address is wrong!\n", + start, end); + return -2; + } + + 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); + + return 0; +} + +void dump_emi_mpu_regions(void) +{ + unsigned long apc[EMI_MPU_DGROUP_NUM], sa, ea; + + int region, i; + + /* Only dump 8 regions(max: EMI_MPU_REGION_NUM --> 32) */ + for (region = 0; region < 8; ++region) { + for (i = 0; i < EMI_MPU_DGROUP_NUM; ++i) + apc[i] = mmio_read_32(EMI_MPU_APC(region, i)); + sa = mmio_read_32(EMI_MPU_SA(region)); + ea = mmio_read_32(EMI_MPU_EA(region)); + + WARN("region %d:\n", region); + WARN("\tsa:0x%lx, ea:0x%lx, apc0: 0x%lx apc1: 0x%lx\n", + sa, ea, apc[0], apc[1]); + } +} + +int emi_mpu_set_protection(struct emi_region_info_t *region_info) +{ + unsigned long start, end; + int i; + + if (region_info->region >= EMI_MPU_REGION_NUM) + return -1; + + start = (unsigned long)(region_info->start >> EMI_MPU_ALIGN_BITS) | + (region_info->region << 24); + + for (i = EMI_MPU_DGROUP_NUM - 1; i >= 0; i--) { + end = (unsigned long)(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) +{ + /* Set permission */ + struct emi_region_info_t region_info; + + /* PCE-e protect address(TODO) */ + region_info.start = 0x80000000ULL; + region_info.end = 0x83FF0000ULL; + region_info.region = 1; + SET_ACCESS_PERMISSION(region_info.apc, 1, + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, + FORBIDDEN, FORBIDDEN, NO_PROT, + NO_PROT /*FORBIDDEN*/); + emi_mpu_set_protection(®ion_info); + + /* Forbidden All */ + region_info.start = 0x40000000ULL; /* dram base addr */ + region_info.end = 0x1FFFF0000ULL; + region_info.region = 2; + SET_ACCESS_PERMISSION(region_info.apc, 1, + NO_PROT, NO_PROT, NO_PROT, NO_PROT, + NO_PROT, NO_PROT, NO_PROT, NO_PROT, + NO_PROT, NO_PROT, NO_PROT, NO_PROT, + NO_PROT, FORBIDDEN, NO_PROT, NO_PROT); + emi_mpu_set_protection(®ion_info); + + dump_emi_mpu_regions(); +} + diff --git a/plat/mediatek/mt8192/drivers/emi_mpu/emi_mpu.h b/plat/mediatek/mt8192/drivers/emi_mpu/emi_mpu.h new file mode 100644 index 000000000..0b1543197 --- /dev/null +++ b/plat/mediatek/mt8192/drivers/emi_mpu/emi_mpu.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef EMI_MPU_H +#define EMI_MPU_H + +#include + +#define EMI_MPUP (EMI_BASE + 0x01D8) +#define EMI_MPUQ (EMI_BASE + 0x01E0) +#define EMI_MPUR (EMI_BASE + 0x01E8) +#define EMI_MPUS (EMI_BASE + 0x01F0) +#define EMI_MPUT (EMI_BASE + 0x01F8) +#define EMI_MPUY (EMI_BASE + 0x0220) +#define EMI_MPU_CTRL (EMI_MPU_BASE + 0x0000) +#define EMI_MPUD0_ST (EMI_BASE + 0x0160) +#define EMI_MPUD1_ST (EMI_BASE + 0x0164) +#define EMI_MPUD2_ST (EMI_BASE + 0x0168) +#define EMI_MPUD3_ST (EMI_BASE + 0x016C) +#define EMI_MPUD0_ST2 (EMI_BASE + 0x0200) +#define EMI_MPUD1_ST2 (EMI_BASE + 0x0204) +#define EMI_MPUD2_ST2 (EMI_BASE + 0x0208) +#define EMI_MPUD3_ST2 (EMI_BASE + 0x020C) + +#define EMI_PHY_OFFSET (0x40000000UL) + +#define NO_PROT (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 SECURE_OS_MPU_REGION_ID (0) +#define ATF_MPU_REGION_ID (1) + +#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_DOMAIN_NUM 16 +#define EMI_MPU_REGION_NUM 32 +#define EMI_MPU_ALIGN_BITS 16 +#define DRAM_OFFSET (0x40000000 >> EMI_MPU_ALIGN_BITS) + +#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[0] = 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 long apc[EMI_MPU_DGROUP_NUM]; +}; + +void emi_mpu_init(void); +int emi_mpu_set_protection(struct emi_region_info_t *region_info); +void dump_emi_mpu_regions(void); + +#endif /* __EMI_MPU_H */ diff --git a/plat/mediatek/mt8192/include/platform_def.h b/plat/mediatek/mt8192/include/platform_def.h index 51cf36136..3e4441424 100644 --- a/plat/mediatek/mt8192/include/platform_def.h +++ b/plat/mediatek/mt8192/include/platform_def.h @@ -30,6 +30,8 @@ #define GPIO_BASE (IO_PHYS + 0x00005000) #define SPM_BASE (IO_PHYS + 0x00006000) #define PMIC_WRAP_BASE (IO_PHYS + 0x00026000) +#define EMI_BASE (IO_PHYS + 0x00219000) +#define EMI_MPU_BASE (IO_PHYS + 0x00226000) #define IOCFG_RM_BASE (IO_PHYS + 0x01C20000) #define IOCFG_BM_BASE (IO_PHYS + 0x01D10000) #define IOCFG_BL_BASE (IO_PHYS + 0x01D30000) diff --git a/plat/mediatek/mt8192/platform.mk b/plat/mediatek/mt8192/platform.mk index 191895a21..c21914e0c 100644 --- a/plat/mediatek/mt8192/platform.mk +++ b/plat/mediatek/mt8192/platform.mk @@ -11,6 +11,7 @@ PLAT_INCLUDES := -I${MTK_PLAT}/common/ \ -I${MTK_PLAT_SOC}/include/ \ -I${MTK_PLAT_SOC}/drivers/ \ -I${MTK_PLAT_SOC}/drivers/dcm \ + -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/ \ @@ -53,6 +54,7 @@ BL31_SOURCES += common/desc_image_load.c \ ${MTK_PLAT_SOC}/plat_sip_calls.c \ ${MTK_PLAT_SOC}/drivers/dcm/mtk_dcm.c \ ${MTK_PLAT_SOC}/drivers/dcm/mtk_dcm_utils.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 04589e2b1e5eca4efbf032907879221c34e35c84 Mon Sep 17 00:00:00 2001 From: Yidi Lin Date: Thu, 10 Dec 2020 19:56:50 +0800 Subject: mediatek: mt8192: Fix non-MISRA compliant code CID 364144: Integer handling issues (NO_EFFECT) The unsigned value is always greater-than-or-equal-to-zero. Remove such check. Change-Id: Ia395eb32f55a7098d2581ce7f548b7e1112beaa0 Signed-off-by: Yidi Lin --- plat/mediatek/mt8192/drivers/ptp3/mtk_ptp3_main.c | 29 +++++++++++------------ 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/plat/mediatek/mt8192/drivers/ptp3/mtk_ptp3_main.c b/plat/mediatek/mt8192/drivers/ptp3/mtk_ptp3_main.c index 053d21081..f1d849386 100644 --- a/plat/mediatek/mt8192/drivers/ptp3/mtk_ptp3_main.c +++ b/plat/mediatek/mt8192/drivers/ptp3/mtk_ptp3_main.c @@ -39,15 +39,15 @@ void ptp3_init(unsigned int core) { unsigned int _core; - if (core >= PTP3_CFG1_CPU_START_ID) { - if (core < NR_PTP3_CFG1_CPU) { - /* update ptp3_cfg1 */ - ptp3_write( - ptp3_cfg1[core][PTP3_CFG_ADDR], - ptp3_cfg1[core][PTP3_CFG_VALUE]); - } + /* Apply ptp3_cfg1 for core 0 to 7 */ + if (core < NR_PTP3_CFG1_CPU) { + /* update ptp3_cfg1 */ + ptp3_write( + ptp3_cfg1[core][PTP3_CFG_ADDR], + ptp3_cfg1[core][PTP3_CFG_VALUE]); } + /* Apply ptp3_cfg2 for core 4 to 7 */ if (core >= PTP3_CFG2_CPU_START_ID) { _core = core - PTP3_CFG2_CPU_START_ID; @@ -59,6 +59,7 @@ void ptp3_init(unsigned int core) } } + /* Apply ptp3_cfg3 for core 4 to 7 */ if (core >= PTP3_CFG3_CPU_START_ID) { _core = core - PTP3_CFG3_CPU_START_ID; @@ -73,13 +74,11 @@ void ptp3_init(unsigned int core) void ptp3_deinit(unsigned int core) { - if (core >= PTP3_CFG1_CPU_START_ID) { - if (core < NR_PTP3_CFG1_CPU) { - /* update ptp3_cfg1 */ - ptp3_write( - ptp3_cfg1[core][PTP3_CFG_ADDR], - ptp3_cfg1[core][PTP3_CFG_VALUE] & - ~PTP3_CFG1_MASK); - } + if (core < NR_PTP3_CFG1_CPU) { + /* update ptp3_cfg1 */ + ptp3_write( + ptp3_cfg1[core][PTP3_CFG_ADDR], + ptp3_cfg1[core][PTP3_CFG_VALUE] & + ~PTP3_CFG1_MASK); } } -- cgit v1.2.3 From 44ad5d67cf6006fc53e0248d78a0419a41f0de8d Mon Sep 17 00:00:00 2001 From: Yidi Lin Date: Tue, 15 Dec 2020 15:45:23 +0800 Subject: mediatek: mt8192: Fix non-MISRA compliant code CID 364146: Control flow issues (DEADCODE) Since the value of PSTATE_PWR_LVL_MASK and the value the of PLAT_MAX_PWR_LVL are equal on mt8192, the following equation never hold. if (aff_lvl > PLAT_MAX_PWR_LVL) { return PSCI_E_INVALID_PARAMS; } Remove the deadcode to comply with MISRA standard. Signed-off-by: Yidi Lin Change-Id: I71d0aa826eded8c3b5af961e733167ae40699398 --- plat/mediatek/mt8192/plat_pm.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/plat/mediatek/mt8192/plat_pm.c b/plat/mediatek/mt8192/plat_pm.c index 3ea27b6c1..1fcafeb44 100644 --- a/plat/mediatek/mt8192/plat_pm.c +++ b/plat/mediatek/mt8192/plat_pm.c @@ -297,10 +297,6 @@ static int plat_validate_power_state(unsigned int power_state, unsigned int aff_lvl = psci_get_pstate_pwrlvl(power_state); unsigned int cpu = plat_my_core_pos(); - if (aff_lvl > PLAT_MAX_PWR_LVL) { - return PSCI_E_INVALID_PARAMS; - } - if (pstate == PSTATE_TYPE_STANDBY) { req_state->pwr_domain_state[0] = PLAT_MAX_RET_STATE; } else { -- cgit v1.2.3 From b686d33095b9bbe0d5288d227e4cd91bb4eedeb9 Mon Sep 17 00:00:00 2001 From: Yuchen Huang Date: Wed, 14 Oct 2020 20:14:37 +0800 Subject: mediatek: mt8192: add rtc power off sequence add mt6359p rtc power off sequence and enable k_eosc mode Signed-off-by: Yuchen Huang Change-Id: I65450c63c44ccb5082541dbbe28b8aa0a95ecc56 --- plat/mediatek/mt8192/drivers/rtc/rtc.c | 148 +++++++++++++++++++++++++ plat/mediatek/mt8192/drivers/rtc/rtc.h | 197 +++++++++++++++++++++++++++++++++ plat/mediatek/mt8192/plat_pm.c | 2 + plat/mediatek/mt8192/platform.mk | 3 + 4 files changed, 350 insertions(+) create mode 100644 plat/mediatek/mt8192/drivers/rtc/rtc.c create mode 100644 plat/mediatek/mt8192/drivers/rtc/rtc.h diff --git a/plat/mediatek/mt8192/drivers/rtc/rtc.c b/plat/mediatek/mt8192/drivers/rtc/rtc.c new file mode 100644 index 000000000..124bc8fbe --- /dev/null +++ b/plat/mediatek/mt8192/drivers/rtc/rtc.c @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + + +static void RTC_Config_Interface(uint32_t addr, uint16_t data, + uint16_t mask, uint16_t shift) +{ + uint16_t pmic_reg; + + pmic_reg = RTC_Read(addr); + + pmic_reg &= ~(mask << shift); + pmic_reg |= (data << shift); + + RTC_Write(addr, pmic_reg); +} + +static int32_t rtc_disable_2sec_reboot(void) +{ + uint16_t reboot; + + reboot = (RTC_Read(RTC_AL_SEC) & ~RTC_BBPU_2SEC_EN) & + ~RTC_BBPU_AUTO_PDN_SEL; + RTC_Write(RTC_AL_SEC, reboot); + + return RTC_Write_Trigger(); +} + +static int32_t rtc_enable_k_eosc(void) +{ + uint16_t alm_dow, alm_sec; + int16_t ret; + + /* Turning on eosc cali mode clock */ + RTC_Config_Interface(PMIC_RG_SCK_TOP_CKPDN_CON0_CLR, 1, + PMIC_RG_RTC_EOSC32_CK_PDN_MASK, + PMIC_RG_RTC_EOSC32_CK_PDN_SHIFT); + + alm_sec = RTC_Read(RTC_AL_SEC) & (~RTC_LPD_OPT_MASK); + RTC_Write(RTC_AL_SEC, alm_sec); + ret = RTC_Write_Trigger(); + if (ret == 0) { + return 0; + } + + RTC_Write(RTC_CON, RTC_LPD_EN); + ret = RTC_Write_Trigger(); + if (ret == 0) { + return 0; + } + + RTC_Write(RTC_CON, RTC_LPD_RST); + ret = RTC_Write_Trigger(); + if (ret == 0) { + return 0; + } + + RTC_Write(RTC_CON, RTC_LPD_EN); + ret = RTC_Write_Trigger(); + if (ret == 0) { + return 0; + } + + RTC_Write(RTC_POWERKEY1, RTC_POWERKEY1_KEY); + RTC_Write(RTC_POWERKEY2, RTC_POWERKEY2_KEY); + ret = RTC_Write_Trigger(); + if (ret == 0) { + return 0; + } + + /* set RTC EOSC calibration period = 8sec */ + alm_dow = (RTC_Read(RTC_AL_DOW) & (~RTC_RG_EOSC_CALI_TD_MASK)) | + RTC_RG_EOSC_CALI_TD_8SEC; + RTC_Write(RTC_AL_DOW, alm_dow); + ret = RTC_Write_Trigger(); + if (ret == 0) { + return 0; + } + + RTC_Write(RTC_BBPU, + RTC_Read(RTC_BBPU) | RTC_BBPU_KEY | RTC_BBPU_RELOAD); + ret = RTC_Write_Trigger(); + if (ret == 0) { + return 0; + } + + /* Enable K EOSC mode :use solution1 of eosc cali to fix mt6359p 32K*/ + RTC_Write(RTC_AL_YEA, (((RTC_Read(RTC_AL_YEA) | RTC_K_EOSC_RSV_0) + & (~RTC_K_EOSC_RSV_1)) | (RTC_K_EOSC_RSV_2))); + ret = RTC_Write_Trigger(); + if (ret == 0) { + return 0; + } + + INFO("[RTC] RTC_enable_k_eosc\n"); + + return 1; +} + +void rtc_power_off_sequence(void) +{ + uint16_t bbpu; + int16_t ret; + + ret = rtc_disable_2sec_reboot(); + if (ret == 0) { + return; + } + + ret = rtc_enable_k_eosc(); + if (ret == 0) { + return; + } + + bbpu = RTC_BBPU_KEY | RTC_BBPU_PWREN; + + if (Writeif_unlock() != 0) { + RTC_Write(RTC_BBPU, + bbpu | RTC_BBPU_RESET_ALARM | RTC_BBPU_RESET_SPAR); + RTC_Write(RTC_AL_MASK, RTC_AL_MASK_DOW); + ret = RTC_Write_Trigger(); + if (ret == 0) { + return; + } + mdelay(1); + + bbpu = RTC_Read(RTC_BBPU); + + if (((bbpu & RTC_BBPU_RESET_ALARM) > 0) || + ((bbpu & RTC_BBPU_RESET_SPAR) > 0)) { + INFO("[RTC] timeout\n"); + } + + bbpu = RTC_Read(RTC_BBPU) | RTC_BBPU_KEY | RTC_BBPU_RELOAD; + RTC_Write(RTC_BBPU, bbpu); + ret = RTC_Write_Trigger(); + if (ret == 0) { + return; + } + } +} diff --git a/plat/mediatek/mt8192/drivers/rtc/rtc.h b/plat/mediatek/mt8192/drivers/rtc/rtc.h new file mode 100644 index 000000000..419bfe42c --- /dev/null +++ b/plat/mediatek/mt8192/drivers/rtc/rtc.h @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef RTC_H +#define RTC_H + +/* RTC registers */ +enum { + RTC_BBPU = 0x0588, + RTC_IRQ_STA = 0x058A, + RTC_IRQ_EN = 0x058C, + RTC_CII_EN = 0x058E +}; + +enum { + RTC_AL_SEC = 0x05A0, + RTC_AL_MIN = 0x05A2, + RTC_AL_HOU = 0x05A4, + RTC_AL_DOM = 0x05A6, + RTC_AL_DOW = 0x05A8, + RTC_AL_MTH = 0x05AA, + RTC_AL_YEA = 0x05AC, + RTC_AL_MASK = 0x0590 +}; + +enum { + RTC_OSC32CON = 0x05AE, + RTC_CON = 0x05C4, + RTC_WRTGR = 0x05C2 +}; + +enum { + RTC_POWERKEY1 = 0x05B0, + RTC_POWERKEY2 = 0x05B2 +}; + +enum { + RTC_POWERKEY1_KEY = 0xA357, + RTC_POWERKEY2_KEY = 0x67D2 +}; + +enum { + RTC_PDN1 = 0x05B4, + RTC_PDN2 = 0x05B6, + RTC_SPAR0 = 0x05B8, + RTC_SPAR1 = 0x05BA, + RTC_PROT = 0x05BC, + RTC_DIFF = 0x05BE, + RTC_CALI = 0x05C0 +}; + +enum { + RTC_OSC32CON_UNLOCK1 = 0x1A57, + RTC_OSC32CON_UNLOCK2 = 0x2B68 +}; + +enum { + RTC_LPD_EN = 0x0406, + RTC_LPD_RST = 0x040E +}; + +enum { + RTC_LPD_OPT_XOSC_AND_EOSC_LPD = 0U << 13, + RTC_LPD_OPT_EOSC_LPD = 1U << 13, + RTC_LPD_OPT_XOSC_LPD = 2U << 13, + RTC_LPD_OPT_F32K_CK_ALIVE = 3U << 13, +}; + +#define RTC_LPD_OPT_MASK (3U << 13) + +enum { + RTC_PROT_UNLOCK1 = 0x586A, + RTC_PROT_UNLOCK2 = 0x9136 +}; + +enum { + RTC_BBPU_PWREN = 1U << 0, + RTC_BBPU_SPAR_SW = 1U << 1, + RTC_BBPU_RESET_SPAR = 1U << 2, + RTC_BBPU_RESET_ALARM = 1U << 3, + RTC_BBPU_CLRPKY = 1U << 4, + RTC_BBPU_RELOAD = 1U << 5, + RTC_BBPU_CBUSY = 1U << 6 +}; + +enum { + RTC_AL_MASK_SEC = 1U << 0, + RTC_AL_MASK_MIN = 1U << 1, + RTC_AL_MASK_HOU = 1U << 2, + RTC_AL_MASK_DOM = 1U << 3, + RTC_AL_MASK_DOW = 1U << 4, + RTC_AL_MASK_MTH = 1U << 5, + RTC_AL_MASK_YEA = 1U << 6 +}; + +enum { + RTC_BBPU_AUTO_PDN_SEL = 1U << 6, + RTC_BBPU_2SEC_CK_SEL = 1U << 7, + RTC_BBPU_2SEC_EN = 1U << 8, + RTC_BBPU_2SEC_MODE = 0x3 << 9, + RTC_BBPU_2SEC_STAT_CLEAR = 1U << 11, + RTC_BBPU_2SEC_STAT_STA = 1U << 12 +}; + +enum { + RTC_BBPU_KEY = 0x43 << 8 +}; + +enum { + RTC_EMBCK_SRC_SEL = 1 << 8, + RTC_EMBCK_SEL_MODE = 3 << 6, + RTC_XOSC32_ENB = 1 << 5, + RTC_REG_XOSC32_ENB = 1 << 15 +}; + +enum { + RTC_K_EOSC_RSV_0 = 1 << 8, + RTC_K_EOSC_RSV_1 = 1 << 9, + RTC_K_EOSC_RSV_2 = 1 << 10 +}; + +enum { + RTC_RG_EOSC_CALI_TD_1SEC = 3 << 5, + RTC_RG_EOSC_CALI_TD_2SEC = 4 << 5, + RTC_RG_EOSC_CALI_TD_4SEC = 5 << 5, + RTC_RG_EOSC_CALI_TD_8SEC = 6 << 5, + RTC_RG_EOSC_CALI_TD_16SEC = 7 << 5, + RTC_RG_EOSC_CALI_TD_MASK = 7 << 5 +}; + +/* PMIC TOP Register Definition */ +enum { + PMIC_RG_TOP_CON = 0x0020, + PMIC_RG_TOP_CKPDN_CON1 = 0x0112, + PMIC_RG_TOP_CKPDN_CON1_SET = 0x0114, + PMIC_RG_TOP_CKPDN_CON1_CLR = 0x0116, + PMIC_RG_TOP_CKSEL_CON0 = 0x0118, + PMIC_RG_TOP_CKSEL_CON0_SET = 0x011A, + PMIC_RG_TOP_CKSEL_CON0_CLR = 0x011C +}; + +/* PMIC SCK Register Definition */ +enum { + PMIC_RG_SCK_TOP_CKPDN_CON0 = 0x0514, + PMIC_RG_SCK_TOP_CKPDN_CON0_SET = 0x0516, + PMIC_RG_SCK_TOP_CKPDN_CON0_CLR = 0x0518, + PMIC_RG_EOSC_CALI_CON0 = 0x53A +}; + +enum { + PMIC_EOSC_CALI_START_ADDR = 0x53A +}; + +enum { + PMIC_EOSC_CALI_START_MASK = 0x1, + PMIC_EOSC_CALI_START_SHIFT = 0 +}; + +/* PMIC DCXO Register Definition */ +enum { + PMIC_RG_DCXO_CW00 = 0x0788, + PMIC_RG_DCXO_CW02 = 0x0790, + PMIC_RG_DCXO_CW08 = 0x079C, + PMIC_RG_DCXO_CW09 = 0x079E, + PMIC_RG_DCXO_CW09_CLR = 0x07A2, + PMIC_RG_DCXO_CW10 = 0x07A4, + PMIC_RG_DCXO_CW12 = 0x07A8, + PMIC_RG_DCXO_CW13 = 0x07AA, + PMIC_RG_DCXO_CW15 = 0x07AE, + PMIC_RG_DCXO_CW19 = 0x07B6, +}; + +enum { + PMIC_RG_SRCLKEN_IN0_HW_MODE_MASK = 0x1, + PMIC_RG_SRCLKEN_IN0_HW_MODE_SHIFT = 1, + PMIC_RG_SRCLKEN_IN1_HW_MODE_MASK = 0x1, + PMIC_RG_SRCLKEN_IN1_HW_MODE_SHIFT = 3, + PMIC_RG_RTC_EOSC32_CK_PDN_MASK = 0x1, + PMIC_RG_RTC_EOSC32_CK_PDN_SHIFT = 2, + PMIC_RG_EOSC_CALI_TD_MASK = 0x7, + PMIC_RG_EOSC_CALI_TD_SHIFT = 5, + PMIC_RG_XO_EN32K_MAN_MASK = 0x1, + PMIC_RG_XO_EN32K_MAN_SHIFT = 0 +}; + +/* external API */ +uint16_t RTC_Read(uint32_t addr); +void RTC_Write(uint32_t addr, uint16_t data); +int32_t rtc_busy_wait(void); +int32_t RTC_Write_Trigger(void); +int32_t Writeif_unlock(void); +void rtc_power_off_sequence(void); + +#endif /* RTC_H */ diff --git a/plat/mediatek/mt8192/plat_pm.c b/plat/mediatek/mt8192/plat_pm.c index 1fcafeb44..6a74c02dd 100644 --- a/plat/mediatek/mt8192/plat_pm.c +++ b/plat/mediatek/mt8192/plat_pm.c @@ -21,6 +21,7 @@ #include #include #include +#include /* * Cluster state request: @@ -341,6 +342,7 @@ static void __dead2 plat_mtk_system_off(void) { INFO("MTK System Off\n"); + rtc_power_off_sequence(); pmic_power_off(); wfi(); diff --git a/plat/mediatek/mt8192/platform.mk b/plat/mediatek/mt8192/platform.mk index c21914e0c..a5e7ee26a 100644 --- a/plat/mediatek/mt8192/platform.mk +++ b/plat/mediatek/mt8192/platform.mk @@ -16,6 +16,7 @@ PLAT_INCLUDES := -I${MTK_PLAT}/common/ \ -I${MTK_PLAT_SOC}/drivers/mcdi/ \ -I${MTK_PLAT_SOC}/drivers/pmic/ \ -I${MTK_PLAT_SOC}/drivers/ptp3/ \ + -I${MTK_PLAT_SOC}/drivers/rtc/ \ -I${MTK_PLAT_SOC}/drivers/spmc/ \ -I${MTK_PLAT_SOC}/drivers/timer/ \ -I${MTK_PLAT_SOC}/drivers/uart/ @@ -39,6 +40,7 @@ BL31_SOURCES += common/desc_image_load.c \ lib/cpus/aarch64/cortex_a76.S \ plat/common/plat_gicv3.c \ ${MTK_PLAT}/common/drivers/pmic_wrap/pmic_wrap_init_v2.c \ + ${MTK_PLAT}/common/drivers/rtc/rtc_common.c \ ${MTK_PLAT}/common/drivers/uart/uart.c \ ${MTK_PLAT}/common/mtk_plat_common.c \ ${MTK_PLAT}/common/mtk_sip_svc.c \ @@ -47,6 +49,7 @@ BL31_SOURCES += common/desc_image_load.c \ ${MTK_PLAT_SOC}/aarch64/plat_helpers.S \ ${MTK_PLAT_SOC}/bl31_plat_setup.c \ ${MTK_PLAT_SOC}/drivers/pmic/pmic.c \ + ${MTK_PLAT_SOC}/drivers/rtc/rtc.c \ ${MTK_PLAT_SOC}/plat_pm.c \ ${MTK_PLAT_SOC}/plat_topology.c \ ${MTK_PLAT_SOC}/plat_mt_gic.c \ -- cgit v1.2.3 From 3f0d83695cdad443a11fff9679019735021c445d Mon Sep 17 00:00:00 2001 From: johpow01 Date: Tue, 15 Dec 2020 19:02:18 -0600 Subject: Workaround for Cortex A76 erratum 1946160 Cortex A76 erratum 1946160 is a Cat B erratum, present in some revisions of the A76 processor core. The workaround is to insert a DMB ST before acquire atomic instructions without release semantics. This issue is present in revisions r0p0 - r4p1 but this workaround only applies to revisions r3p0 - r4p1, there is no workaround for older versions. SDEN can be found here: https://documentation-service.arm.com/static/5fbb77d7d77dd807b9a80cc1 Signed-off-by: John Powell Change-Id: Ief33779ee76a89ce2649812ae5214b86a139e327 --- docs/design/cpu-specific-build-macros.rst | 3 ++ lib/cpus/aarch64/cortex_a76.S | 61 +++++++++++++++++++++++++++++++ lib/cpus/cpu-ops.mk | 8 ++++ 3 files changed, 72 insertions(+) diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst index e901e0c5e..d859cc581 100644 --- a/docs/design/cpu-specific-build-macros.rst +++ b/docs/design/cpu-specific-build-macros.rst @@ -249,6 +249,9 @@ For Cortex-A76, the following errata build flags are defined : - ``ERRATA_A76_1868343``: This applies errata 1868343 workaround to Cortex-A76 CPU. This needs to be enabled only for revision <= r4p0 of the CPU. +- ``ERRATA_A76_1946160``: This applies errata 1946160 workaround to Cortex-A76 + CPU. This needs to be enabled only for revisions r3p0 - r4p1 of the CPU. + For Cortex-A77, the following errata build flags are defined : - ``ERRATA_A77_1508412``: This applies errata 1508412 workaround to Cortex-A77 diff --git a/lib/cpus/aarch64/cortex_a76.S b/lib/cpus/aarch64/cortex_a76.S index 2c99cdc92..4f7f4bb9a 100644 --- a/lib/cpus/aarch64/cortex_a76.S +++ b/lib/cpus/aarch64/cortex_a76.S @@ -430,6 +430,61 @@ func check_errata_1868343 b cpu_rev_var_ls endfunc check_errata_1868343 +/* -------------------------------------------------- + * Errata Workaround for A76 Erratum 1946160. + * This applies to revisions r3p0 - r4p1 of A76. + * It also exists in r0p0 - r2p0 but there is no fix + * in those revisions. + * Inputs: + * x0: variant[4:7] and revision[0:3] of current cpu. + * Shall clobber: x0-x17 + * -------------------------------------------------- + */ +func errata_a76_1946160_wa + /* Compare x0 against revisions r3p0 - r4p1 */ + mov x17, x30 + bl check_errata_1946160 + cbz x0, 1f + + mov x0, #3 + msr S3_6_C15_C8_0, x0 + ldr x0, =0x10E3900002 + msr S3_6_C15_C8_2, x0 + ldr x0, =0x10FFF00083 + msr S3_6_C15_C8_3, x0 + ldr x0, =0x2001003FF + msr S3_6_C15_C8_1, x0 + + mov x0, #4 + msr S3_6_C15_C8_0, x0 + ldr x0, =0x10E3800082 + msr S3_6_C15_C8_2, x0 + ldr x0, =0x10FFF00083 + msr S3_6_C15_C8_3, x0 + ldr x0, =0x2001003FF + msr S3_6_C15_C8_1, x0 + + mov x0, #5 + msr S3_6_C15_C8_0, x0 + ldr x0, =0x10E3800200 + msr S3_6_C15_C8_2, x0 + ldr x0, =0x10FFF003E0 + msr S3_6_C15_C8_3, x0 + ldr x0, =0x2001003FF + msr S3_6_C15_C8_1, x0 + + isb +1: + ret x17 +endfunc errata_a76_1946160_wa + +func check_errata_1946160 + /* Applies to revisions r3p0 - r4p1. */ + mov x1, #0x30 + mov x2, #0x41 + b cpu_rev_var_range +endfunc check_errata_1946160 + func check_errata_cve_2018_3639 #if WORKAROUND_CVE_2018_3639 mov x0, #ERRATA_APPLIES @@ -509,6 +564,11 @@ func cortex_a76_reset_func bl errata_a76_1791580_wa #endif +#if ERRATA_A76_1946160 + mov x0, x18 + bl errata_a76_1946160_wa +#endif + #if WORKAROUND_CVE_2018_3639 /* If the PE implements SSBS, we don't need the dynamic workaround */ mrs x0, id_aa64pfr1_el1 @@ -592,6 +652,7 @@ func cortex_a76_errata_report report_errata ERRATA_A76_1791580, cortex_a76, 1791580 report_errata ERRATA_A76_1165522, cortex_a76, 1165522 report_errata ERRATA_A76_1868343, cortex_a76, 1868343 + report_errata ERRATA_A76_1946160, cortex_a76, 1946160 report_errata WORKAROUND_CVE_2018_3639, cortex_a76, cve_2018_3639 report_errata ERRATA_DSU_798953, cortex_a76, dsu_798953 report_errata ERRATA_DSU_936184, cortex_a76, dsu_936184 diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk index 084e6e7bd..da0157f4c 100644 --- a/lib/cpus/cpu-ops.mk +++ b/lib/cpus/cpu-ops.mk @@ -278,6 +278,10 @@ ERRATA_A76_1165522 ?=0 # only to revision <= r4p0 of the Cortex A76 cpu. ERRATA_A76_1868343 ?=0 +# Flag to apply erratum 1946160 workaround during reset. This erratum applies +# only to revisions r3p0 - r4p1 of the Cortex A76 cpu. +ERRATA_A76_1946160 ?=0 + # Flag to apply erratum 1508412 workaround during reset. This erratum applies # only to revision <= r1p0 of the Cortex A77 cpu. ERRATA_A77_1508412 ?=0 @@ -555,6 +559,10 @@ $(eval $(call add_define,ERRATA_A76_1165522)) $(eval $(call assert_boolean,ERRATA_A76_1868343)) $(eval $(call add_define,ERRATA_A76_1868343)) +# Process ERRATA_A76_1946160 flag +$(eval $(call assert_boolean,ERRATA_A76_1946160)) +$(eval $(call add_define,ERRATA_A76_1946160)) + # Process ERRATA_A77_1508412 flag $(eval $(call assert_boolean,ERRATA_A77_1508412)) $(eval $(call add_define,ERRATA_A77_1508412)) -- cgit v1.2.3 From a492527b1f4a9ed0c90bb9794b4ffb64ea75039f Mon Sep 17 00:00:00 2001 From: Biju Das Date: Sun, 13 Dec 2020 19:41:27 +0000 Subject: drivers: renesas: rcar: eMMC driver code clean up Fix checkpatch warnings and MISRA defects. There are no functional changes. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: I349a8eaa7bd6182746ba5104ee9fe48a709c24fd --- drivers/renesas/rcar/emmc/emmc_cmd.c | 37 +- drivers/renesas/rcar/emmc/emmc_config.h | 38 +- drivers/renesas/rcar/emmc/emmc_hal.h | 609 +++++++++++++++++-------- drivers/renesas/rcar/emmc/emmc_init.c | 35 +- drivers/renesas/rcar/emmc/emmc_interrupt.c | 8 +- drivers/renesas/rcar/emmc/emmc_mount.c | 85 ++-- drivers/renesas/rcar/emmc/emmc_read.c | 15 +- drivers/renesas/rcar/emmc/emmc_registers.h | 284 ++++++------ drivers/renesas/rcar/emmc/emmc_std.h | 705 +++++++++++++++-------------- drivers/renesas/rcar/emmc/emmc_utility.c | 12 +- 10 files changed, 999 insertions(+), 829 deletions(-) diff --git a/drivers/renesas/rcar/emmc/emmc_cmd.c b/drivers/renesas/rcar/emmc/emmc_cmd.c index a2e25e339..d255bffc9 100644 --- a/drivers/renesas/rcar/emmc/emmc_cmd.c +++ b/drivers/renesas/rcar/emmc/emmc_cmd.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,10 +7,10 @@ #include #include "emmc_config.h" +#include "emmc_def.h" #include "emmc_hal.h" -#include "emmc_std.h" #include "emmc_registers.h" -#include "emmc_def.h" +#include "emmc_std.h" #include "micro_delay.h" static void emmc_little_to_big(uint8_t *p, uint32_t value) @@ -22,6 +22,7 @@ static void emmc_little_to_big(uint8_t *p, uint32_t value) p[1] = (uint8_t) (value >> 16); p[2] = (uint8_t) (value >> 8); p[3] = (uint8_t) value; + } static void emmc_softreset(void) @@ -64,7 +65,6 @@ reset: SETR_32(SD_INFO2, SD_INFO2_CLEAR); SETR_32(SD_INFO1_MASK, 0x00000000U); /* all interrupt disable */ SETR_32(SD_INFO2_MASK, SD_INFO2_CLEAR); /* all interrupt disable */ - } static void emmc_read_response(uint32_t *response) @@ -96,8 +96,7 @@ static EMMC_ERROR_CODE emmc_response_check(uint32_t *response, { HAL_MEMCARD_RESPONSE_TYPE response_type = - (HAL_MEMCARD_RESPONSE_TYPE) (mmc_drv_obj.cmd_info. - cmd & HAL_MEMCARD_RESPONSE_TYPE_MASK); + ((HAL_MEMCARD_RESPONSE_TYPE)mmc_drv_obj.cmd_info.cmd & HAL_MEMCARD_RESPONSE_TYPE_MASK); if (response == NULL) return EMMC_ERR_PARAM; @@ -117,7 +116,7 @@ static EMMC_ERROR_CODE emmc_response_check(uint32_t *response, } return EMMC_ERR_CARD_STATUS_BIT; } - return EMMC_SUCCESS;; + return EMMC_SUCCESS; } if (response_type == HAL_MEMCARD_RESPONSE_R4) { @@ -223,11 +222,11 @@ EMMC_ERROR_CODE emmc_exec_cmd(uint32_t error_mask, uint32_t *response) state = ESTATE_BEGIN; response_type = - (HAL_MEMCARD_RESPONSE_TYPE) (mmc_drv_obj.cmd_info. - cmd & HAL_MEMCARD_RESPONSE_TYPE_MASK); + ((HAL_MEMCARD_RESPONSE_TYPE)mmc_drv_obj.cmd_info.cmd & + HAL_MEMCARD_RESPONSE_TYPE_MASK); cmd_type = - (HAL_MEMCARD_COMMAND_TYPE) (mmc_drv_obj.cmd_info. - cmd & HAL_MEMCARD_COMMAND_TYPE_MASK); + ((HAL_MEMCARD_COMMAND_TYPE) mmc_drv_obj.cmd_info.cmd & + HAL_MEMCARD_COMMAND_TYPE_MASK); /* state machine */ while ((mmc_drv_obj.force_terminate != TRUE) && (state != ESTATE_END)) { @@ -427,8 +426,9 @@ EMMC_ERROR_CODE emmc_exec_cmd(uint32_t error_mask, uint32_t *response) case ESTATE_ACCESS_END: /* clear flag */ - if (HAL_MEMCARD_DMA == mmc_drv_obj.transfer_mode) { - SETR_32(CC_EXT_MODE, CC_EXT_MODE_CLEAR); /* W (CC_EXT_MODE, H'0000_1010) SD_BUF DMA transfer disabled */ + if (mmc_drv_obj.transfer_mode == HAL_MEMCARD_DMA) { + /* W (CC_EXT_MODE, H'0000_1010) SD_BUF DMA transfer disabled */ + SETR_32(CC_EXT_MODE, CC_EXT_MODE_CLEAR); SETR_32(SD_STOP, 0x00000000U); mmc_drv_obj.during_dma_transfer = FALSE; } @@ -448,8 +448,9 @@ EMMC_ERROR_CODE emmc_exec_cmd(uint32_t error_mask, uint32_t *response) case ESTATE_TRANSFER_ERROR: /* The error occurred in the Data transfer. */ - if (HAL_MEMCARD_DMA == mmc_drv_obj.transfer_mode) { - SETR_32(CC_EXT_MODE, CC_EXT_MODE_CLEAR); /* W (CC_EXT_MODE, H'0000_1010) SD_BUF DMA transfer disabled */ + if (mmc_drv_obj.transfer_mode == HAL_MEMCARD_DMA) { + /* W (CC_EXT_MODE, H'0000_1010) SD_BUF DMA transfer disabled */ + SETR_32(CC_EXT_MODE, CC_EXT_MODE_CLEAR); SETR_32(SD_STOP, 0x00000000U); mmc_drv_obj.during_dma_transfer = FALSE; } @@ -468,8 +469,8 @@ EMMC_ERROR_CODE emmc_exec_cmd(uint32_t error_mask, uint32_t *response) default: state = ESTATE_END; break; - } /* switch (state) */ - } /* while ( (mmc_drv_obj.force_terminate != TRUE) && (state != ESTATE_END) ) */ + } /* switch (state) */ + } /* while ( (mmc_drv_obj.force_terminate != TRUE) && (state != ESTATE_END) ) */ /* force terminate */ if (mmc_drv_obj.force_terminate == TRUE) { @@ -481,7 +482,7 @@ EMMC_ERROR_CODE emmc_exec_cmd(uint32_t error_mask, uint32_t *response) ERROR("BL2: emmc exec_cmd:EMMC_ERR_FORCE_TERMINATE\n"); emmc_softreset(); - return EMMC_ERR_FORCE_TERMINATE; /* error information has already been written. */ + return EMMC_ERR_FORCE_TERMINATE; /* error information has already been written. */ } /* success */ diff --git a/drivers/renesas/rcar/emmc/emmc_config.h b/drivers/renesas/rcar/emmc/emmc_config.h index 686ccb99c..16b6b8aa9 100644 --- a/drivers/renesas/rcar/emmc/emmc_config.h +++ b/drivers/renesas/rcar/emmc/emmc_config.h @@ -1,40 +1,20 @@ /* - * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ -/** - * @file emmc_config.h - * @brief Configuration file - * - */ - #ifndef EMMC_CONFIG_H #define EMMC_CONFIG_H -/* ************************ HEADER (INCLUDE) SECTION *********************** */ - -/* ***************** MACROS, CONSTANTS, COMPILATION FLAGS ****************** */ - -/** @brief MMC driver config - */ -#define EMMC_RCA 1UL /* RCA */ -#define EMMC_RW_DATA_TIMEOUT 0x40UL /* 314ms (freq = 400KHz, timeout Counter = 0x04(SDCLK * 2^17) */ -#define EMMC_RETRY_COUNT 0 /* how many times to try after fail. Don't change. */ -#define EMMC_CMD_MAX 60UL /* Don't change. */ - -/** @brief etc - */ -#define LOADIMAGE_FLAGS_DMA_ENABLE 0x00000001UL - -/* ********************** STRUCTURES, TYPE DEFINITIONS ********************* */ - -/* ********************** DECLARATION OF EXTERNAL DATA ********************* */ - -/* ************************** FUNCTION PROTOTYPES ************************** */ +/* RCA */ +#define EMMC_RCA 1UL +/* 314ms (freq = 400KHz, timeout Counter = 0x04(SDCLK * 2^17) */ +#define EMMC_RW_DATA_TIMEOUT 0x40UL +/* how many times to try after fail. Don't change. */ +#define EMMC_RETRY_COUNT 0 +#define EMMC_CMD_MAX 60UL /* Don't change. */ -/* ********************************* CODE ********************************** */ +#define LOADIMAGE_FLAGS_DMA_ENABLE 0x00000001UL #endif /* EMMC_CONFIG_H */ -/* ******************************** END ************************************ */ diff --git a/drivers/renesas/rcar/emmc/emmc_hal.h b/drivers/renesas/rcar/emmc/emmc_hal.h index f0b7e9d77..0a8551719 100644 --- a/drivers/renesas/rcar/emmc/emmc_hal.h +++ b/drivers/renesas/rcar/emmc/emmc_hal.h @@ -1,100 +1,81 @@ /* - * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ -/** - * @file emmc_hal.h - * @brief emmc boot driver is expecting this header file - * - */ - #ifndef EMMC_HAL_H #define EMMC_HAL_H -/* ************************ HEADER (INCLUDE) SECTION *********************** */ -#include -/* ***************** MACROS, CONSTANTS, COMPILATION FLAGS ****************** */ - -/** @brief memory card error/status types - */ -#define HAL_MEMCARD_OUT_OF_RANGE 0x80000000L -#define HAL_MEMCARD_ADDRESS_ERROR 0x40000000L -#define HAL_MEMCARD_BLOCK_LEN_ERROR 0x20000000L -#define HAL_MEMCARD_ERASE_SEQ_ERROR 0x10000000L -#define HAL_MEMCARD_ERASE_PARAM 0x08000000L -#define HAL_MEMCARD_WP_VIOLATION 0x04000000L -#define HAL_MEMCARD_CARD_IS_LOCKED 0x02000000L -#define HAL_MEMCARD_LOCK_UNLOCK_FAILED 0x01000000L -#define HAL_MEMCARD_COM_CRC_ERROR 0x00800000L -#define HAL_MEMCARD_ILEGAL_COMMAND 0x00400000L -#define HAL_MEMCARD_CARD_ECC_FAILED 0x00200000L -#define HAL_MEMCARD_CC_ERROR 0x00100000L -#define HAL_MEMCARD_ERROR 0x00080000L -#define HAL_MEMCARD_UNDERRUN 0x00040000L -#define HAL_MEMCARD_OVERRUN 0x00020000L -#define HAL_MEMCARD_CIDCSD_OVERWRITE 0x00010000L -#define HAL_MEMCARD_WP_ERASE_SKIP 0x00008000L -#define HAL_MEMCARD_CARD_ECC_DISABLED 0x00004000L -#define HAL_MEMCARD_ERASE_RESET 0x00002000L -#define HAL_MEMCARD_CARD_STATE 0x00001E00L -#define HAL_MEMCARD_CARD_READY_FOR_DATA 0x00000100L -#define HAL_MEMCARD_APP_CMD 0x00000020L -#define HAL_MEMCARD_SWITCH_ERROR 0x00000080L -#define HAL_MEMCARD_AKE_SEQ_ERROR 0x00000008L -#define HAL_MEMCARD_NO_ERRORS 0x00000000L - -/** @brief Memory card response types - */ -#define HAL_MEMCARD_COMMAND_INDEX_MASK 0x0003f - -/* ********************** STRUCTURES, TYPE DEFINITIONS ********************* */ -/** @brief Type of the return value. - */ +/* memory card error/status types */ +#define HAL_MEMCARD_OUT_OF_RANGE 0x80000000L +#define HAL_MEMCARD_ADDRESS_ERROR 0x40000000L +#define HAL_MEMCARD_BLOCK_LEN_ERROR 0x20000000L +#define HAL_MEMCARD_ERASE_SEQ_ERROR 0x10000000L +#define HAL_MEMCARD_ERASE_PARAM 0x08000000L +#define HAL_MEMCARD_WP_VIOLATION 0x04000000L +#define HAL_MEMCARD_CARD_IS_LOCKED 0x02000000L +#define HAL_MEMCARD_LOCK_UNLOCK_FAILED 0x01000000L +#define HAL_MEMCARD_COM_CRC_ERROR 0x00800000L +#define HAL_MEMCARD_ILEGAL_COMMAND 0x00400000L +#define HAL_MEMCARD_CARD_ECC_FAILED 0x00200000L +#define HAL_MEMCARD_CC_ERROR 0x00100000L +#define HAL_MEMCARD_ERROR 0x00080000L +#define HAL_MEMCARD_UNDERRUN 0x00040000L +#define HAL_MEMCARD_OVERRUN 0x00020000L +#define HAL_MEMCARD_CIDCSD_OVERWRITE 0x00010000L +#define HAL_MEMCARD_WP_ERASE_SKIP 0x00008000L +#define HAL_MEMCARD_CARD_ECC_DISABLED 0x00004000L +#define HAL_MEMCARD_ERASE_RESET 0x00002000L +#define HAL_MEMCARD_CARD_STATE 0x00001E00L +#define HAL_MEMCARD_CARD_READY_FOR_DATA 0x00000100L +#define HAL_MEMCARD_APP_CMD 0x00000020L +#define HAL_MEMCARD_SWITCH_ERROR 0x00000080L +#define HAL_MEMCARD_AKE_SEQ_ERROR 0x00000008L +#define HAL_MEMCARD_NO_ERRORS 0x00000000L + +/* Memory card response types */ +#define HAL_MEMCARD_COMMAND_INDEX_MASK 0x0003f + +/* Type of the return value. */ typedef enum { HAL_MEMCARD_FAIL = 0U, HAL_MEMCARD_OK = 1U, - HAL_MEMCARD_DMA_ALLOC_FAIL = 2U, /**< DMA channel allocation failed */ - HAL_MEMCARD_DMA_TRANSFER_FAIL = 3U, /**< DMA transfer failed */ - HAL_MEMCARD_CARD_STATUS_ERROR = 4U, /**< A non-masked error bit was set in the card status */ - HAL_MEMCARD_CMD_TIMEOUT = 5U, /**< Command timeout occurred */ - HAL_MEMCARD_DATA_TIMEOUT = 6U, /**< Data timeout occurred */ - HAL_MEMCARD_CMD_CRC_ERROR = 7U, /**< Command CRC error occurred */ - HAL_MEMCARD_DATA_CRC_ERROR = 8U /**< Data CRC error occurred */ + HAL_MEMCARD_DMA_ALLOC_FAIL = 2U, /* DMA channel allocation failed */ + HAL_MEMCARD_DMA_TRANSFER_FAIL = 3U, /* DMA transfer failed */ + HAL_MEMCARD_CARD_STATUS_ERROR = 4U, /* card status non-masked error */ + HAL_MEMCARD_CMD_TIMEOUT = 5U, /* Command timeout occurred */ + HAL_MEMCARD_DATA_TIMEOUT = 6U, /* Data timeout occurred */ + HAL_MEMCARD_CMD_CRC_ERROR = 7U, /* Command CRC error occurred */ + HAL_MEMCARD_DATA_CRC_ERROR = 8U /* Data CRC error occurred */ } HAL_MEMCARD_RETURN; -/** @brief memory access operation - */ +/* memory access operation */ typedef enum { - HAL_MEMCARD_READ = 0U, /**< read */ - HAL_MEMCARD_WRITE = 1U /**< write */ + HAL_MEMCARD_READ = 0U, /* read */ + HAL_MEMCARD_WRITE = 1U /* write */ } HAL_MEMCARD_OPERATION; -/** @brief Type of data width on memorycard bus - */ +/* Type of data width on memorycard bus */ typedef enum { HAL_MEMCARD_DATA_WIDTH_1_BIT = 0U, HAL_MEMCARD_DATA_WIDTH_4_BIT = 1U, HAL_MEMCARD_DATA_WIDTH_8_BIT = 2U -} HAL_MEMCARD_DATA_WIDTH; /**< data (bus) width types */ +} HAL_MEMCARD_DATA_WIDTH; /* data (bus) width types */ -/** @brief Presence of the memory card - */ +/* Presence of the memory card */ typedef enum { HAL_MEMCARD_CARD_IS_IN = 0U, HAL_MEMCARD_CARD_IS_OUT = 1U } HAL_MEMCARD_PRESENCE_STATUS; /* presence status of the memory card */ -/** @brief mode of data transfer - */ +/* mode of data transfer */ typedef enum { HAL_MEMCARD_DMA = 0U, HAL_MEMCARD_NOT_DMA = 1U } HAL_MEMCARD_DATA_TRANSFER_MODE; -/** @brief Memory card response types. - */ +/* Memory card response types. */ typedef enum hal_memcard_response_type { HAL_MEMCARD_RESPONSE_NONE = 0x00000U, HAL_MEMCARD_RESPONSE_R1 = 0x00100U, @@ -108,8 +89,7 @@ typedef enum hal_memcard_response_type { HAL_MEMCARD_RESPONSE_TYPE_MASK = 0x00f00U } HAL_MEMCARD_RESPONSE_TYPE; -/** @brief Memory card command types. - */ +/* Memory card command types. */ typedef enum hal_memcard_command_type { HAL_MEMCARD_COMMAND_TYPE_BC = 0x00000U, HAL_MEMCARD_COMMAND_TYPE_BCR = 0x01000U, @@ -119,8 +99,7 @@ typedef enum hal_memcard_command_type { HAL_MEMCARD_COMMAND_TYPE_MASK = 0x07000U } HAL_MEMCARD_COMMAND_TYPE; -/** @brief Type of memory card - */ +/* Type of memory card */ typedef enum hal_memcard_command_card_type { HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON = 0x00000U, HAL_MEMCARD_COMMAND_CARD_TYPE_MMC = 0x08000U, @@ -128,191 +107,429 @@ typedef enum hal_memcard_command_card_type { HAL_MEMCARD_COMMAND_CARD_TYPE_MASK = 0x18000U } HAL_MEMCARD_COMMAND_CARD_TYPE; -/** @brief Memory card application command. - */ +/* Memory card application command. */ typedef enum hal_memcard_command_app_norm { HAL_MEMCARD_COMMAND_NORMAL = 0x00000U, HAL_MEMCARD_COMMAND_APP = 0x20000U, HAL_MEMCARD_COMMAND_APP_NORM_MASK = 0x20000U } HAL_MEMCARD_COMMAND_APP_NORM; -/** @brief Memory card command codes. - */ +/* Memory card command codes. */ typedef enum { /* class 0 and class 1 */ - CMD0_GO_IDLE_STATE = 0 | HAL_MEMCARD_RESPONSE_NONE | HAL_MEMCARD_COMMAND_TYPE_BC | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD0 */ - CMD1_SEND_OP_COND = 1 | HAL_MEMCARD_RESPONSE_R3 | HAL_MEMCARD_COMMAND_TYPE_BCR | HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | HAL_MEMCARD_COMMAND_NORMAL, /* CMD1 */ - CMD2_ALL_SEND_CID_MMC = 2 | HAL_MEMCARD_RESPONSE_R2 | HAL_MEMCARD_COMMAND_TYPE_BCR | HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | HAL_MEMCARD_COMMAND_NORMAL, /* CMD2 */ + /* CMD0 */ + CMD0_GO_IDLE_STATE = + 0U | (uint32_t)HAL_MEMCARD_RESPONSE_NONE | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_BC | + (uint32_t) HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD1 */ + CMD1_SEND_OP_COND = + 1U | (uint32_t)HAL_MEMCARD_RESPONSE_R3 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_BCR | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD2 */ + CMD2_ALL_SEND_CID_MMC = + 2U | (uint32_t)HAL_MEMCARD_RESPONSE_R2 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_BCR | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, CMD2_ALL_SEND_CID_SD = - 2 | HAL_MEMCARD_RESPONSE_R2 | HAL_MEMCARD_COMMAND_TYPE_BCR | - HAL_MEMCARD_COMMAND_CARD_TYPE_SD | HAL_MEMCARD_COMMAND_NORMAL, - CMD3_SET_RELATIVE_ADDR = 3 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | HAL_MEMCARD_COMMAND_NORMAL, /* CMD3 */ + 2U | (uint32_t)HAL_MEMCARD_RESPONSE_R2 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_BCR | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD3 */ + CMD3_SET_RELATIVE_ADDR = + 3U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, CMD3_SEND_RELATIVE_ADDR = - 3 | HAL_MEMCARD_RESPONSE_R6 | HAL_MEMCARD_COMMAND_TYPE_AC | - HAL_MEMCARD_COMMAND_CARD_TYPE_SD | HAL_MEMCARD_COMMAND_NORMAL, - CMD4_SET_DSR = 4 | HAL_MEMCARD_RESPONSE_NONE | HAL_MEMCARD_COMMAND_TYPE_BC | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD4 */ - CMD5_SLEEP_AWAKE = 5 | HAL_MEMCARD_RESPONSE_R1b | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | HAL_MEMCARD_COMMAND_NORMAL, /* CMD5 */ - CMD6_SWITCH = 6 | HAL_MEMCARD_RESPONSE_R1b | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | HAL_MEMCARD_COMMAND_NORMAL, /* CMD6 */ + 3U | (uint32_t)HAL_MEMCARD_RESPONSE_R6 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD4 */ + CMD4_SET_DSR = + 4U | (uint32_t)HAL_MEMCARD_RESPONSE_NONE | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_BC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD5 */ + CMD5_SLEEP_AWAKE = + 5U | (uint32_t)HAL_MEMCARD_RESPONSE_R1b | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD6 */ + CMD6_SWITCH = + 6U | (uint32_t)HAL_MEMCARD_RESPONSE_R1b | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, CMD6_SWITCH_FUNC = - 6 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_AC | - HAL_MEMCARD_COMMAND_CARD_TYPE_SD | HAL_MEMCARD_COMMAND_NORMAL, + 6U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, ACMD6_SET_BUS_WIDTH = - 6 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_AC | - HAL_MEMCARD_COMMAND_CARD_TYPE_SD | HAL_MEMCARD_COMMAND_APP, - CMD7_SELECT_CARD = 7 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD7 */ - CMD7_SELECT_CARD_PROG = 7 | HAL_MEMCARD_RESPONSE_R1b | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD7(from Disconnected State to Programming State) */ + 6U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | + (uint32_t)HAL_MEMCARD_COMMAND_APP, + /* CMD7 */ + CMD7_SELECT_CARD = + 7U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD7(from Disconnected State to Programming State) */ + CMD7_SELECT_CARD_PROG = + 7U | (uint32_t)HAL_MEMCARD_RESPONSE_R1b | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, CMD7_DESELECT_CARD = - 7 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_AC | - HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, - CMD8_SEND_EXT_CSD = 8 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | HAL_MEMCARD_COMMAND_NORMAL, /* CMD8 */ + 7U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD8 */ + CMD8_SEND_EXT_CSD = + 8U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, CMD8_SEND_IF_COND = - 8 | HAL_MEMCARD_RESPONSE_R7 | HAL_MEMCARD_COMMAND_TYPE_BCR | - HAL_MEMCARD_COMMAND_CARD_TYPE_SD | HAL_MEMCARD_COMMAND_NORMAL, - CMD9_SEND_CSD = 9 | HAL_MEMCARD_RESPONSE_R2 | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD9 */ - CMD10_SEND_CID = 10 | HAL_MEMCARD_RESPONSE_R2 | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD10 */ - CMD11_READ_DAT_UNTIL_STOP = 11 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | HAL_MEMCARD_COMMAND_CARD_TYPE_SD | HAL_MEMCARD_COMMAND_NORMAL, /* CMD11 */ - CMD12_STOP_TRANSMISSION = 12 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD12 */ - CMD12_STOP_TRANSMISSION_WRITE = 12 | HAL_MEMCARD_RESPONSE_R1b | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD12(R1b : write case) */ - CMD13_SEND_STATUS = 13 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD13 */ + 8U | (uint32_t)HAL_MEMCARD_RESPONSE_R7 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_BCR | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD9 */ + CMD9_SEND_CSD = + 9U | (uint32_t)HAL_MEMCARD_RESPONSE_R2 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD10 */ + CMD10_SEND_CID = + 10U | (uint32_t)HAL_MEMCARD_RESPONSE_R2 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD11 */ + CMD11_READ_DAT_UNTIL_STOP = + 11U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD12 */ + CMD12_STOP_TRANSMISSION = + 12U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD12(R1b : write case) */ + CMD12_STOP_TRANSMISSION_WRITE = + 12U | (uint32_t)HAL_MEMCARD_RESPONSE_R1b | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD13 */ + CMD13_SEND_STATUS = + 13U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, ACMD13_SD_STATUS = - 13 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | - HAL_MEMCARD_COMMAND_CARD_TYPE_SD | HAL_MEMCARD_COMMAND_APP, - CMD14_BUSTEST_R = 14 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | HAL_MEMCARD_COMMAND_NORMAL, /* CMD14 */ - CMD15_GO_INACTIVE_STATE = 15 | HAL_MEMCARD_RESPONSE_NONE | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD15 */ + 13U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | + (uint32_t)HAL_MEMCARD_COMMAND_APP, + /* CMD14 */ + CMD14_BUSTEST_R = + 14U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD15 */ + CMD15_GO_INACTIVE_STATE = + 15U | (uint32_t)HAL_MEMCARD_RESPONSE_NONE | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, /* class 2 */ - CMD16_SET_BLOCKLEN = 16 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD16 */ - CMD17_READ_SINGLE_BLOCK = 17 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD17 */ - CMD18_READ_MULTIPLE_BLOCK = 18 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD18 */ - CMD19_BUS_TEST_W = 19 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | HAL_MEMCARD_COMMAND_NORMAL, /* CMD19 */ + /* CMD16 */ + CMD16_SET_BLOCKLEN = + 16U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD17 */ + CMD17_READ_SINGLE_BLOCK = + 17U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD18 */ + CMD18_READ_MULTIPLE_BLOCK = + 18U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD19 */ + CMD19_BUS_TEST_W = + 19U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, /* class 3 */ - CMD20_WRITE_DAT_UNTIL_STOP = 20 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | HAL_MEMCARD_COMMAND_NORMAL, /* CMD20 */ - CMD21 = 21, /* CMD21 */ - CMD22 = 22, /* CMD22 */ + /* CMD20 */ + CMD20_WRITE_DAT_UNTIL_STOP = + 20U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD21 */ + CMD21 = 21U, + /* CMD22 */ + CMD22 = 22U, ACMD22_SEND_NUM_WR_BLOCKS = - 22 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_AC | - HAL_MEMCARD_COMMAND_CARD_TYPE_SD | HAL_MEMCARD_COMMAND_APP, + 22U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | + (uint32_t)HAL_MEMCARD_COMMAND_APP, /* class 4 */ - CMD23_SET_BLOCK_COUNT = 23 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | HAL_MEMCARD_COMMAND_NORMAL, /* CMD23 */ + /* CMD23 */ + CMD23_SET_BLOCK_COUNT = + 23U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, ACMD23_SET_WR_BLK_ERASE_COUNT = - 23 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_AC | - HAL_MEMCARD_COMMAND_CARD_TYPE_SD | HAL_MEMCARD_COMMAND_APP, - CMD24_WRITE_BLOCK = 24 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD24 */ - CMD25_WRITE_MULTIPLE_BLOCK = 25 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD25 */ - CMD26_PROGRAM_CID = 26 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | HAL_MEMCARD_COMMAND_NORMAL, /* CMD26 */ - CMD27_PROGRAM_CSD = 27 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD27 */ + 23U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | + (uint32_t)HAL_MEMCARD_COMMAND_APP, + /* CMD24 */ + CMD24_WRITE_BLOCK = + 24U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD25 */ + CMD25_WRITE_MULTIPLE_BLOCK = + 25U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD26 */ + CMD26_PROGRAM_CID = + 26U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD27 */ + CMD27_PROGRAM_CSD = + 27U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, /* class 6 */ - CMD28_SET_WRITE_PROT = 28 | HAL_MEMCARD_RESPONSE_R1b | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD28 */ - CMD29_CLR_WRITE_PROT = 29 | HAL_MEMCARD_RESPONSE_R1b | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD29 */ - CMD30_SEND_WRITE_PROT = 30 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD30 */ - CMD30_SEND_WRITE_PROT_TYPE = 31 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD31 */ + /* CMD28 */ + CMD28_SET_WRITE_PROT = + 28U | (uint32_t)HAL_MEMCARD_RESPONSE_R1b | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD29 */ + CMD29_CLR_WRITE_PROT = + 29U | (uint32_t)HAL_MEMCARD_RESPONSE_R1b | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD30 */ + CMD30_SEND_WRITE_PROT = + 30U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD31 */ + CMD30_SEND_WRITE_PROT_TYPE = + 31U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, /* class 5 */ - CMD32_ERASE_WR_BLK_START = 32 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_SD | HAL_MEMCARD_COMMAND_NORMAL, /* CMD32 */ - CMD33_ERASE_WR_BLK_END = 33 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_SD | HAL_MEMCARD_COMMAND_NORMAL, /* CMD33 */ - CMD34 = 34, /* CMD34 */ - CMD35_ERASE_GROUP_START = 35 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | HAL_MEMCARD_COMMAND_NORMAL, /* CMD35 */ - CMD36_ERASE_GROUP_END = 36 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | HAL_MEMCARD_COMMAND_NORMAL, /* CMD36 */ - CMD37 = 37, /* CMD37 */ - CMD38_ERASE = 38 | HAL_MEMCARD_RESPONSE_R1b | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD38 */ + /* CMD32 */ + CMD32_ERASE_WR_BLK_START = + 32U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD33 */ + CMD33_ERASE_WR_BLK_END = + 33U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD34 */ + CMD34 = 34U, + /* CMD35 */ + CMD35_ERASE_GROUP_START = + 35U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD36 */ + CMD36_ERASE_GROUP_END = + 36U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD37 */ + CMD37 = 37U, + /* CMD38 */ + CMD38_ERASE = + 38U | (uint32_t)HAL_MEMCARD_RESPONSE_R1b | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, /* class 9 */ - CMD39_FASTIO = 39 | HAL_MEMCARD_RESPONSE_R4 | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | HAL_MEMCARD_COMMAND_NORMAL, /* CMD39 */ - CMD40_GO_IRQSTATE = 40 | HAL_MEMCARD_RESPONSE_R5 | HAL_MEMCARD_COMMAND_TYPE_BCR | HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | HAL_MEMCARD_COMMAND_NORMAL, /* CMD40 */ - CMD41 = 41, /* CMD41 */ + /* CMD39 */ + CMD39_FASTIO = + 39U | (uint32_t)HAL_MEMCARD_RESPONSE_R4 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD40 */ + CMD40_GO_IRQSTATE = + 40U | (uint32_t)HAL_MEMCARD_RESPONSE_R5 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_BCR | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD41 */ + CMD41 = 41, ACMD41_SD_SEND_OP_COND = - 41 | HAL_MEMCARD_RESPONSE_R3 | HAL_MEMCARD_COMMAND_TYPE_BCR | - HAL_MEMCARD_COMMAND_CARD_TYPE_SD | HAL_MEMCARD_COMMAND_APP, + 41U | (uint32_t)HAL_MEMCARD_RESPONSE_R3 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_BCR | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | + (uint32_t)HAL_MEMCARD_COMMAND_APP, /* class 7 */ - CMD42_LOCK_UNLOCK = 42 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD42 */ + /* CMD42 */ + CMD42_LOCK_UNLOCK = + 42U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, ACMD42_SET_CLR_CARD_DETECT = - 42 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_AC | - HAL_MEMCARD_COMMAND_CARD_TYPE_SD | HAL_MEMCARD_COMMAND_APP, - CMD43 = 43, /* CMD43 */ - CMD44 = 44, /* CMD44 */ - CMD45 = 45, /* CMD45 */ - CMD46 = 46, /* CMD46 */ - CMD47 = 47, /* CMD47 */ - CMD48 = 48, /* CMD48 */ - CMD49 = 49, /* CMD49 */ - CMD50 = 50, /* CMD50 */ - CMD51 = 51, /* CMD51 */ + 42U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | + (uint32_t)HAL_MEMCARD_COMMAND_APP, + CMD43 = 43U, /* CMD43 */ + CMD44 = 44U, /* CMD44 */ + CMD45 = 45U, /* CMD45 */ + CMD46 = 46U, /* CMD46 */ + CMD47 = 47U, /* CMD47 */ + CMD48 = 48U, /* CMD48 */ + CMD49 = 49U, /* CMD49 */ + CMD50 = 50U, /* CMD50 */ + CMD51 = 51U, /* CMD51 */ ACMD51_SEND_SCR = - 51 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | - HAL_MEMCARD_COMMAND_CARD_TYPE_SD | HAL_MEMCARD_COMMAND_APP, - CMD52 = 52, /* CMD52 */ - CMD53 = 53, /* CMD53 */ - CMD54 = 54, /* CMD54 */ + 51U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | + (uint32_t)HAL_MEMCARD_COMMAND_APP, + CMD52 = 52U, /* CMD52 */ + CMD53 = 53U, /* CMD53 */ + CMD54 = 54U, /* CMD54 */ /* class 8 */ - CMD55_APP_CMD = 55 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD55 */ - CMD56_GEN_CMD = 56 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD56 */ - CMD57 = 57, /* CMD57 */ - CMD58 = 58, /* CMD58 */ - CMD59 = 59, /* CMD59 */ - CMD60 = 60, /* CMD60 */ - CMD61 = 61, /* CMD61 */ - CMD62 = 62, /* CMD62 */ - CMD63 = 63 /* CMD63 */ + /* CMD55 */ + CMD55_APP_CMD = + 55U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD56 */ + CMD56_GEN_CMD = + 56U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + CMD57 = 57U, /* CMD57 */ + CMD58 = 58U, /* CMD58 */ + CMD59 = 59U, /* CMD59 */ + CMD60 = 60U, /* CMD60 */ + CMD61 = 61U, /* CMD61 */ + CMD62 = 62U, /* CMD62 */ + CMD63 = 63U /* CMD63 */ } HAL_MEMCARD_COMMAND; -/** @brief Configuration structure from HAL layer. +/* + * Configuration structure from HAL layer. * * If some field is not available it should be filled with 0xFF. - * The API version is 32-bit unsigned integer telling the version of the API. The integer is divided to four sections which each can be treated as a 8-bit unsigned number: - * Bits 31-24 make the most significant part of the version number. This number starts from 1 i.e. the second version of the API will be 0x02xxxxxx. This number changes only, if the API itself changes so much that it is not compatible anymore with older releases. - * Bits 23-16 API minor version number. For example API version 2.1 would be 0x0201xxxx. - * Bits 15-8 are the number of the year when release is done. The 0 is year 2000, 1 is year 2001 and so on - * Bits 7- are the week number when release is done. First full week of the year is 1 + * The API version is 32-bit unsigned integer telling the version of the API. + * The integer is divided to four sections which each can be treated as a 8-bit + * unsigned number: + * Bits 31-24 make the most significant part of the version number. This number + * starts from 1 i.e. the second version of the API will be 0x02xxxxxx. This + * number changes only, if the API itself changes so much that it is not + * compatible anymore with older releases. + * Bits 23-16 API minor version number. For example API version 2.1 would be + * 0x0201xxxx. + * Bits 15-8 are the number of the year when release is done. The 0 is year + * 2000, 1 is year 2001 and so on + * Bits 7- are the week number when release is done. First full week of the + * year is 1 * - * @note Example: let's assume that release 2.1 is done on week 10 year 2008 the version will get the value 0x0201080A + * Example: let's assume that release 2.1 is done on week 10 year 2008 + * the version will get the value 0x0201080A */ typedef struct { - /** - * Version of the chipset API implementation - * - * bits [31:24] API specification major version number.
- * bits [23:16] API specification minor version number.
- * bits [15:8] API implemention year. (2000 = 0, 2001 = 1, ...)
- * bits [7:0] API implemention week.
- * Example: API specification version 4.0, implementation w46 2008 => 0x0400082E - */ + /* + * Version of the chipset API implementation + * + * bits [31:24] API specification major version number.
+ * bits [23:16] API specification minor version number.
+ * bits [15:8] API implementation year. (2000 = 0, 2001 = 1, ...) + * bits [7:0] API implementation week. + * Example: API spec version 4.0, implementation w46 2008 => 0x0400082E + */ uint32_t api_version; - /** maximum block count which can be transferred at once */ + /* maximum block count which can be transferred at once */ uint32_t max_block_count; - /** maximum clock frequence in Hz supported by HW */ + /* maximum clock frequence in Hz supported by HW */ uint32_t max_clock_freq; - /** maximum data bus width supported by HW */ + /* maximum data bus width supported by HW */ uint16_t max_data_width; - /** Is high-speed mode supported by HW (yes=1, no=0) */ + /* Is high-speed mode supported by HW (yes=1, no=0) */ uint8_t hs_mode_supported; - /** Is memory card removable (yes=1, no=0) */ + /* Is memory card removable (yes=1, no=0) */ uint8_t card_removable; } HAL_MEMCARD_HW_CONF; -/** @brief Configuration structure to HAL layer. - */ +/* Configuration structure to HAL layer. */ typedef struct { - /** how many times to try after fail, for instance sending command */ + /* how many times to try after fail, for instance sending command */ uint32_t retries_after_fail; } HAL_MEMCARD_INIT_CONF; -/* ********************** DECLARATION OF EXTERNAL DATA ********************* */ - -/* ************************** FUNCTION PROTOTYPES ************************** */ - -/* ********************************* CODE ********************************** */ - #endif /* EMMC_HAL_H */ - -/* ******************************** END ************************************ */ diff --git a/drivers/renesas/rcar/emmc/emmc_init.c b/drivers/renesas/rcar/emmc/emmc_init.c index b27e16586..354aa3c82 100644 --- a/drivers/renesas/rcar/emmc/emmc_init.c +++ b/drivers/renesas/rcar/emmc/emmc_init.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -32,12 +32,12 @@ EMMC_ERROR_CODE rcar_emmc_memcard_power(uint8_t mode) return EMMC_SUCCESS; } -static __inline void emmc_set_retry_count(uint32_t retry) +static inline void emmc_set_retry_count(uint32_t retry) { mmc_drv_obj.retries_after_fail = retry; } -static __inline void emmc_set_data_timeout(uint32_t data_timeout) +static inline void emmc_set_data_timeout(uint32_t data_timeout) { mmc_drv_obj.data_timeout = data_timeout; } @@ -73,7 +73,8 @@ static EMMC_ERROR_CODE emmc_dev_finalize(void) EMMC_ERROR_CODE result; uint32_t dataL; - /* MMC power off + /* + * MMC power off * the power supply of eMMC device is always turning on. * RST_n : Hi --> Low level. */ @@ -115,27 +116,25 @@ static EMMC_ERROR_CODE emmc_dev_init(void) SETR_32(HOST_MODE, 0x00000000U); /* SD_BUF access width = 64-bit */ SETR_32(SD_OPTION, 0x0000C0EEU); /* Bus width = 1bit, timeout=MAX */ - SETR_32(SD_CLK_CTRL, 0x00000000U); /* Automatic Control=Disable, Clock Output=Disable */ + SETR_32(SD_CLK_CTRL, 0x00000000U); /* Disable Automatic Control & Clock Output */ return EMMC_SUCCESS; } static EMMC_ERROR_CODE emmc_reset_controller(void) { - EMMC_ERROR_CODE retult; + EMMC_ERROR_CODE result; /* initialize mmc driver */ emmc_drv_init(); /* initialize H/W */ - retult = emmc_dev_init(); - if (EMMC_SUCCESS != retult) { - return retult; + result = emmc_dev_init(); + if (result == EMMC_SUCCESS) { + mmc_drv_obj.initialize = TRUE; } - mmc_drv_obj.initialize = TRUE; - - return retult; + return result; } @@ -152,14 +151,12 @@ EMMC_ERROR_CODE emmc_terminate(void) EMMC_ERROR_CODE rcar_emmc_init(void) { - EMMC_ERROR_CODE retult; + EMMC_ERROR_CODE result; - retult = emmc_reset_controller(); - if (EMMC_SUCCESS != retult) { - return retult; + result = emmc_reset_controller(); + if (result == EMMC_SUCCESS) { + emmc_driver_config(); } - emmc_driver_config(); - - return EMMC_SUCCESS; + return result; } diff --git a/drivers/renesas/rcar/emmc/emmc_interrupt.c b/drivers/renesas/rcar/emmc/emmc_interrupt.c index 2557280cf..092fdfb72 100644 --- a/drivers/renesas/rcar/emmc/emmc_interrupt.c +++ b/drivers/renesas/rcar/emmc/emmc_interrupt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights * reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -118,7 +118,7 @@ uint32_t emmc_interrupt(void) SETR_32(DM_CM_INFO2, 0x00000000U); /* interrupt clear */ SETR_32(SD_INFO2, (GETR_32(SD_INFO2) & ~SD_INFO2_BWE)); - /* DM_CM_INFO2: DMA-ch0 error occured */ + /* DM_CM_INFO2: DMA-ch0 error occurred */ if ((BIT16 & mmc_drv_obj.dm_event2) != 0) { mmc_drv_obj.dma_error_flag = TRUE; } else { @@ -128,13 +128,13 @@ uint32_t emmc_interrupt(void) /* wait next interrupt */ mmc_drv_obj.state_machine_blocking = FALSE; } - /* DM_CM_INFO1: DMA-ch1 transfer complete or error occured */ + /* DM_CM_INFO1: DMA-ch1 transfer complete or error occurred */ else if ((end_bit & mmc_drv_obj.dm_event1) != 0U) { SETR_32(DM_CM_INFO1, 0x00000000U); SETR_32(DM_CM_INFO2, 0x00000000U); /* interrupt clear */ SETR_32(SD_INFO2, (GETR_32(SD_INFO2) & ~SD_INFO2_BRE)); - /* DM_CM_INFO2: DMA-ch1 error occured */ + /* DM_CM_INFO2: DMA-ch1 error occurred */ if ((BIT17 & mmc_drv_obj.dm_event2) != 0) { mmc_drv_obj.dma_error_flag = TRUE; } else { diff --git a/drivers/renesas/rcar/emmc/emmc_mount.c b/drivers/renesas/rcar/emmc/emmc_mount.c index df8203ea8..e04afd4cf 100644 --- a/drivers/renesas/rcar/emmc/emmc_mount.c +++ b/drivers/renesas/rcar/emmc/emmc_mount.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -8,10 +8,10 @@ #include #include "emmc_config.h" +#include "emmc_def.h" #include "emmc_hal.h" -#include "emmc_std.h" #include "emmc_registers.h" -#include "emmc_def.h" +#include "emmc_std.h" #include "micro_delay.h" #include "rcar_def.h" @@ -53,7 +53,7 @@ static EMMC_ERROR_CODE emmc_card_init(void) int32_t retry; uint32_t freq = MMC_400KHZ; /* 390KHz */ EMMC_ERROR_CODE result; - uint32_t resultCalc; + uint32_t result_calc; /* state check */ if ((mmc_drv_obj.initialize != TRUE) @@ -161,9 +161,12 @@ static EMMC_ERROR_CODE emmc_card_init(void) mmc_drv_obj.selected = TRUE; - /* card speed check */ - resultCalc = emmc_calc_tran_speed(&freq); /* Card spec is calculated from TRAN_SPEED(CSD). */ - if (resultCalc == 0) { + /* + * card speed check + * Card spec is calculated from TRAN_SPEED(CSD) + */ + result_calc = emmc_calc_tran_speed(&freq); + if (result_calc == 0) { emmc_write_error_info(EMMC_FUNCNO_CARD_INIT, EMMC_ERR_ILLEGAL_CARD); return EMMC_ERR_ILLEGAL_CARD; @@ -201,7 +204,8 @@ static EMMC_ERROR_CODE emmc_card_init(void) HAL_MEMCARD_NOT_DMA); result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); if (result != EMMC_SUCCESS) { - /* CMD12 is not send. + /* + * CMD12 is not send. * If BUS initialization is failed, user must be execute Bus initialization again. * Bus initialization is start CMD0(soft reset command). */ @@ -217,7 +221,7 @@ static EMMC_ERROR_CODE emmc_card_init(void) static EMMC_ERROR_CODE emmc_high_speed(void) { - uint32_t freq; /**< High speed mode clock frequency */ + uint32_t freq; /* High speed mode clock frequency */ EMMC_ERROR_CODE result; uint8_t cardType; @@ -236,8 +240,8 @@ static EMMC_ERROR_CODE emmc_high_speed(void) else freq = MMC_20MHZ; - /* Hi-Speed-mode selction */ - if ((MMC_52MHZ == freq) || (MMC_26MHZ == freq)) { + /* Hi-Speed-mode selection */ + if ((freq == MMC_52MHZ) || (freq == MMC_26MHZ)) { /* CMD6 */ emmc_make_nontrans_cmd(CMD6_SWITCH, EMMC_SWITCH_HS_TIMING); result = @@ -322,7 +326,8 @@ static EMMC_ERROR_CODE emmc_bus_width(uint32_t width) return EMMC_ERR_STATE; } - mmc_drv_obj.bus_width = (HAL_MEMCARD_DATA_WIDTH) (width >> 2); /* 2 = 8bit, 1 = 4bit, 0 =1bit */ + /* 2 = 8bit, 1 = 4bit, 0 =1bit */ + mmc_drv_obj.bus_width = (HAL_MEMCARD_DATA_WIDTH) (width >> 2); /* CMD6 */ emmc_make_nontrans_cmd(CMD6_SWITCH, @@ -371,7 +376,6 @@ static EMMC_ERROR_CODE emmc_bus_width(uint32_t width) return EMMC_SUCCESS; EXIT: - emmc_write_error_info(EMMC_FUNCNO_BUS_WIDTH, result); ERROR("BL2: emmc bus_width error end\n"); return result; @@ -489,82 +493,83 @@ static void emmc_get_partition_access(void) static uint32_t emmc_calc_tran_speed(uint32_t *freq) { - const uint32_t unit[8] = { 10000, 100000, 1000000, 10000000, - 0, 0, 0, 0 }; /**< frequency unit (1/10) */ - const uint32_t mult[16] = { 0, 10, 12, 13, 15, 20, 26, 30, 35, 40, 45, - 52, 55, 60, 70, 80 }; - - uint32_t maxFreq; - uint32_t result; + const uint32_t unit[8] = { 10000U, 100000U, 1000000U, 10000000U, + 0U, 0U, 0U, 0U }; /* frequency unit (1/10) */ + const uint32_t mult[16] = { 0U, 10U, 12U, 13U, 15U, 20U, 26U, 30U, 35U, + 40U, 45U, 52U, 55U, 60U, 70U, 80U }; uint32_t tran_speed = EMMC_CSD_TRAN_SPEED(); + uint32_t max_freq; + uint32_t result; - /* tran_speed = 0x32 + /* + * tran_speed = 0x32 * unit[tran_speed&0x7] = uint[0x2] = 1000000 * mult[(tran_speed&0x78)>>3] = mult[0x30>>3] = mult[6] = 26 * 1000000 * 26 = 26000000 (26MHz) */ result = 1; - maxFreq = + max_freq = unit[tran_speed & EMMC_TRANSPEED_FREQ_UNIT_MASK] * mult[(tran_speed & EMMC_TRANSPEED_MULT_MASK) >> EMMC_TRANSPEED_MULT_SHIFT]; - if (maxFreq == 0) { + if (max_freq == 0) { result = 0; - } else if (MMC_FREQ_52MHZ <= maxFreq) + } else if (max_freq >= MMC_FREQ_52MHZ) { *freq = MMC_52MHZ; - else if (MMC_FREQ_26MHZ <= maxFreq) + } else if (max_freq >= MMC_FREQ_26MHZ) { *freq = MMC_26MHZ; - else if (MMC_FREQ_20MHZ <= maxFreq) + } else if (max_freq >= MMC_FREQ_20MHZ) { *freq = MMC_20MHZ; - else + } else { *freq = MMC_400KHZ; + } return result; } static uint32_t emmc_set_timeout_register_value(uint32_t freq) { - uint32_t timeoutCnt; /* SD_OPTION - Timeout Counter */ + uint32_t timeout_cnt; /* SD_OPTION - Timeout Counter */ switch (freq) { case 1U: - timeoutCnt = 0xE0U; + timeout_cnt = 0xE0U; break; /* SDCLK * 2^27 */ case 2U: - timeoutCnt = 0xE0U; + timeout_cnt = 0xE0U; break; /* SDCLK * 2^27 */ case 4U: - timeoutCnt = 0xD0U; + timeout_cnt = 0xD0U; break; /* SDCLK * 2^26 */ case 8U: - timeoutCnt = 0xC0U; + timeout_cnt = 0xC0U; break; /* SDCLK * 2^25 */ case 16U: - timeoutCnt = 0xB0U; + timeout_cnt = 0xB0U; break; /* SDCLK * 2^24 */ case 32U: - timeoutCnt = 0xA0U; + timeout_cnt = 0xA0U; break; /* SDCLK * 2^23 */ case 64U: - timeoutCnt = 0x90U; + timeout_cnt = 0x90U; break; /* SDCLK * 2^22 */ case 128U: - timeoutCnt = 0x80U; + timeout_cnt = 0x80U; break; /* SDCLK * 2^21 */ case 256U: - timeoutCnt = 0x70U; + timeout_cnt = 0x70U; break; /* SDCLK * 2^20 */ case 512U: - timeoutCnt = 0x70U; + timeout_cnt = 0x70U; break; /* SDCLK * 2^20 */ default: - timeoutCnt = 0xE0U; + timeout_cnt = 0xE0U; break; /* SDCLK * 2^27 */ } - return timeoutCnt; + return timeout_cnt; } EMMC_ERROR_CODE emmc_set_ext_csd(uint32_t arg) diff --git a/drivers/renesas/rcar/emmc/emmc_read.c b/drivers/renesas/rcar/emmc/emmc_read.c index 390d0caac..96e73ca56 100644 --- a/drivers/renesas/rcar/emmc/emmc_read.c +++ b/drivers/renesas/rcar/emmc/emmc_read.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,15 +7,15 @@ #include #include "emmc_config.h" +#include "emmc_def.h" #include "emmc_hal.h" -#include "emmc_std.h" #include "emmc_registers.h" -#include "emmc_def.h" +#include "emmc_std.h" -#define MIN_EMMC(a, b) (((a) < (b)) ? (a) : (b)) -#define EMMC_RW_SECTOR_COUNT_MAX 0x0000ffffU +#define MIN_EMMC(a, b) (((a) < (b)) ? (a) : (b)) +#define EMMC_RW_SECTOR_COUNT_MAX 0x0000ffffU -static EMMC_ERROR_CODE emmc_multiple_block_read (uint32_t *buff_address_virtual, +static EMMC_ERROR_CODE emmc_multiple_block_read(uint32_t *buff_address_virtual, uint32_t sector_number, uint32_t count, HAL_MEMCARD_DATA_TRANSFER_MODE transfer_mode) { @@ -39,7 +39,8 @@ static EMMC_ERROR_CODE emmc_multiple_block_read (uint32_t *buff_address_virtual, } SETR_32(SD_SECCNT, count); SETR_32(SD_STOP, 0x00000100); - SETR_32(CC_EXT_MODE, (CC_EXT_MODE_CLEAR | CC_EXT_MODE_DMASDRW_ENABLE)); /* SD_BUF Read/Write DMA Transfer enable */ + /* SD_BUF Read/Write DMA Transfer enable */ + SETR_32(CC_EXT_MODE, (CC_EXT_MODE_CLEAR | CC_EXT_MODE_DMASDRW_ENABLE)); /* CMD18 */ emmc_make_trans_cmd(CMD18_READ_MULTIPLE_BLOCK, sector_number, diff --git a/drivers/renesas/rcar/emmc/emmc_registers.h b/drivers/renesas/rcar/emmc/emmc_registers.h index 55ff33d8c..ae689ca24 100644 --- a/drivers/renesas/rcar/emmc/emmc_registers.h +++ b/drivers/renesas/rcar/emmc/emmc_registers.h @@ -1,22 +1,12 @@ /* - * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ -/** - * @file emmc_registers.h - * @brief emmc boot driver is expecting this header file. HS-MMC module header file. - * - */ - #ifndef EMMC_REGISTERS_H #define EMMC_REGISTERS_H -/* ************************ HEADER (INCLUDE) SECTION *********************** */ - -/* ***************** MACROS, CONSTANTS, COMPILATION FLAGS ****************** */ - /* MMC channel select */ #define MMC_CH0 (0U) /* SDHI2/MMC0 */ #define MMC_CH1 (1U) /* SDHI3/MMC1 */ @@ -27,73 +17,71 @@ #define USE_MMC_CH (MMC_CH0) /* R-Car H3/M3/M3N */ #endif /* RCAR_LSI == RCAR_E3 */ -#define BIT0 (0x00000001U) -#define BIT1 (0x00000002U) -#define BIT2 (0x00000004U) -#define BIT3 (0x00000008U) -#define BIT4 (0x00000010U) -#define BIT5 (0x00000020U) -#define BIT6 (0x00000040U) -#define BIT7 (0x00000080U) -#define BIT8 (0x00000100U) -#define BIT9 (0x00000200U) -#define BIT10 (0x00000400U) -#define BIT11 (0x00000800U) -#define BIT12 (0x00001000U) -#define BIT13 (0x00002000U) -#define BIT14 (0x00004000U) -#define BIT15 (0x00008000U) -#define BIT16 (0x00010000U) -#define BIT17 (0x00020000U) -#define BIT18 (0x00040000U) -#define BIT19 (0x00080000U) -#define BIT20 (0x00100000U) -#define BIT21 (0x00200000U) -#define BIT22 (0x00400000U) -#define BIT23 (0x00800000U) -#define BIT24 (0x01000000U) -#define BIT25 (0x02000000U) -#define BIT26 (0x04000000U) -#define BIT27 (0x08000000U) -#define BIT28 (0x10000000U) -#define BIT29 (0x20000000U) -#define BIT30 (0x40000000U) -#define BIT31 (0x80000000U) - -/** @brief Clock Pulse Generator (CPG) registers - */ -#define CPG_BASE (0xE6150000U) - -#define CPG_MSTPSR3 (CPG_BASE+0x0048U) /* Module stop status register 3 */ - -#define CPG_SMSTPCR3 (CPG_BASE+0x013CU) /* System module stop control register 3 */ - -#define CPG_SD2CKCR (CPG_BASE+0x0268U) /* SDHI2 clock frequency control register */ -#define CPG_SD3CKCR (CPG_BASE+0x026CU) /* SDHI3 clock frequency control register */ - -#define CPG_CPGWPR (CPG_BASE+0x0900U) /* CPG Write Protect Register */ +#define BIT0 (0x00000001U) +#define BIT1 (0x00000002U) +#define BIT2 (0x00000004U) +#define BIT3 (0x00000008U) +#define BIT4 (0x00000010U) +#define BIT5 (0x00000020U) +#define BIT6 (0x00000040U) +#define BIT7 (0x00000080U) +#define BIT8 (0x00000100U) +#define BIT9 (0x00000200U) +#define BIT10 (0x00000400U) +#define BIT11 (0x00000800U) +#define BIT12 (0x00001000U) +#define BIT13 (0x00002000U) +#define BIT14 (0x00004000U) +#define BIT15 (0x00008000U) +#define BIT16 (0x00010000U) +#define BIT17 (0x00020000U) +#define BIT18 (0x00040000U) +#define BIT19 (0x00080000U) +#define BIT20 (0x00100000U) +#define BIT21 (0x00200000U) +#define BIT22 (0x00400000U) +#define BIT23 (0x00800000U) +#define BIT24 (0x01000000U) +#define BIT25 (0x02000000U) +#define BIT26 (0x04000000U) +#define BIT27 (0x08000000U) +#define BIT28 (0x10000000U) +#define BIT29 (0x20000000U) +#define BIT30 (0x40000000U) +#define BIT31 (0x80000000U) + +/* Clock Pulse Generator (CPG) registers */ +#define CPG_BASE (0xE6150000U) +/* Module stop status register 3 */ +#define CPG_MSTPSR3 (CPG_BASE + 0x0048U) +/* System module stop control register 3 */ +#define CPG_SMSTPCR3 (CPG_BASE + 0x013CU) +/* SDHI2 clock frequency control register */ +#define CPG_SD2CKCR (CPG_BASE + 0x0268U) +/* SDHI3 clock frequency control register */ +#define CPG_SD3CKCR (CPG_BASE + 0x026CU) +/* CPG Write Protect Register */ +#define CPG_CPGWPR (CPG_BASE + 0x0900U) #if USE_MMC_CH == MMC_CH0 -#define CPG_SDxCKCR (CPG_SD2CKCR) /* SDHI2/MMC0 */ +#define CPG_SDxCKCR (CPG_SD2CKCR) /* SDHI2/MMC0 */ #else /* USE_MMC_CH == MMC_CH0 */ -#define CPG_SDxCKCR (CPG_SD3CKCR) /* SDHI3/MMC1 */ +#define CPG_SDxCKCR (CPG_SD3CKCR) /* SDHI3/MMC1 */ #endif /* USE_MMC_CH == MMC_CH0 */ -/** Boot Status register - */ +/* Boot Status register */ #define MFISBTSTSR (0xE6260604U) #define MFISBTSTSR_BOOT_PARTITION (0x00000010U) -/** brief eMMC registers - */ -#define MMC0_SD_BASE (0xEE140000U) +/* eMMC registers */ +#define MMC0_SD_BASE (0xEE140000U) #define MMC1_SD_BASE (0xEE160000U) #if USE_MMC_CH == MMC_CH0 -#define MMC_SD_BASE (MMC0_SD_BASE) +#define MMC_SD_BASE (MMC0_SD_BASE) #else /* USE_MMC_CH == MMC_CH0 */ -#define MMC_SD_BASE (MMC1_SD_BASE) +#define MMC_SD_BASE (MMC1_SD_BASE) #endif /* USE_MMC_CH == MMC_CH0 */ #define SD_CMD (MMC_SD_BASE + 0x0000U) @@ -136,125 +124,105 @@ #define DM_CM_INFO2_MASK (MMC_SD_BASE + 0x0858U) #define DM_DTRAN_ADDR (MMC_SD_BASE + 0x0880U) -/** @brief SD_INFO1 Registers - */ -#define SD_INFO1_HPIRES 0x00010000UL /* Response Reception Completion */ -#define SD_INFO1_INFO10 0x00000400UL /* Indicates the SDDAT3 state */ -#define SD_INFO1_INFO9 0x00000200UL /* SDDAT3 Card Insertion */ -#define SD_INFO1_INFO8 0x00000100UL /* SDDAT3 Card Removal */ -#define SD_INFO1_INFO7 0x00000080UL /* Write Protect */ -#define SD_INFO1_INFO5 0x00000020UL /* Indicates the ISDCD state */ -#define SD_INFO1_INFO4 0x00000010UL /* ISDCD Card Insertion */ -#define SD_INFO1_INFO3 0x00000008UL /* ISDCD Card Removal */ -#define SD_INFO1_INFO2 0x00000004UL /* Access end */ -#define SD_INFO1_INFO0 0x00000001UL /* Response end */ - -/** @brief SD_INFO2 Registers - */ -#define SD_INFO2_ILA 0x00008000UL /* Illegal Access Error */ -#define SD_INFO2_CBSY 0x00004000UL /* Command Type Register Busy */ -#define SD_INFO2_SCLKDIVEN 0x00002000UL -#define SD_INFO2_BWE 0x00000200UL /* SD_BUF Write Enable */ -#define SD_INFO2_BRE 0x00000100UL /* SD_BUF Read Enable */ -#define SD_INFO2_DAT0 0x00000080UL /* SDDAT0 */ -#define SD_INFO2_ERR6 0x00000040UL /* Response Timeout */ -#define SD_INFO2_ERR5 0x00000020UL /* SD_BUF Illegal Read Access */ -#define SD_INFO2_ERR4 0x00000010UL /* SD_BUF Illegal Write Access */ -#define SD_INFO2_ERR3 0x00000008UL /* Data Timeout */ -#define SD_INFO2_ERR2 0x00000004UL /* END Error */ -#define SD_INFO2_ERR1 0x00000002UL /* CRC Error */ -#define SD_INFO2_ERR0 0x00000001UL /* CMD Error */ -#define SD_INFO2_ALL_ERR 0x0000807FUL -#define SD_INFO2_CLEAR 0x00000800UL /* BIT11 The write value should always be 1. HWM_0003 */ - -/** @brief SOFT_RST - */ -#define SOFT_RST_SDRST 0x00000001UL - -/** @brief SD_CLK_CTRL - */ +/* SD_INFO1 Registers */ +#define SD_INFO1_HPIRES 0x00010000UL /* Response Reception Completion */ +#define SD_INFO1_INFO10 0x00000400UL /* Indicates the SDDAT3 state */ +#define SD_INFO1_INFO9 0x00000200UL /* SDDAT3 Card Insertion */ +#define SD_INFO1_INFO8 0x00000100UL /* SDDAT3 Card Removal */ +#define SD_INFO1_INFO7 0x00000080UL /* Write Protect */ +#define SD_INFO1_INFO5 0x00000020UL /* Indicates the ISDCD state */ +#define SD_INFO1_INFO4 0x00000010UL /* ISDCD Card Insertion */ +#define SD_INFO1_INFO3 0x00000008UL /* ISDCD Card Removal */ +#define SD_INFO1_INFO2 0x00000004UL /* Access end */ +#define SD_INFO1_INFO0 0x00000001UL /* Response end */ + +/* SD_INFO2 Registers */ +#define SD_INFO2_ILA 0x00008000UL /* Illegal Access Error */ +#define SD_INFO2_CBSY 0x00004000UL /* Command Type Register Busy */ +#define SD_INFO2_SCLKDIVEN 0x00002000UL +#define SD_INFO2_BWE 0x00000200UL /* SD_BUF Write Enable */ +#define SD_INFO2_BRE 0x00000100UL /* SD_BUF Read Enable */ +#define SD_INFO2_DAT0 0x00000080UL /* SDDAT0 */ +#define SD_INFO2_ERR6 0x00000040UL /* Response Timeout */ +#define SD_INFO2_ERR5 0x00000020UL /* SD_BUF Illegal Read Access */ +#define SD_INFO2_ERR4 0x00000010UL /* SD_BUF Illegal Write Access */ +#define SD_INFO2_ERR3 0x00000008UL /* Data Timeout */ +#define SD_INFO2_ERR2 0x00000004UL /* END Error */ +#define SD_INFO2_ERR1 0x00000002UL /* CRC Error */ +#define SD_INFO2_ERR0 0x00000001UL /* CMD Error */ +#define SD_INFO2_ALL_ERR 0x0000807FUL +#define SD_INFO2_CLEAR 0x00000800UL /* BIT11 write value should always be 1. HWM_0003 */ + +/* SOFT_RST */ +#define SOFT_RST_SDRST 0x00000001UL + +/* SD_CLK_CTRL */ #define SD_CLK_CTRL_SDCLKOFFEN 0x00000200UL -#define SD_CLK_CTRL_SCLKEN 0x00000100UL -#define SD_CLK_CTRL_CLKDIV_MASK 0x000000FFUL -#define SD_CLOCK_ENABLE 0x00000100UL -#define SD_CLOCK_DISABLE 0x00000000UL -#define SD_CLK_WRITE_MASK 0x000003FFUL -#define SD_CLK_CLKDIV_CLEAR_MASK 0xFFFFFF0FUL - -/** @brief SD_OPTION - */ +#define SD_CLK_CTRL_SCLKEN 0x00000100UL +#define SD_CLK_CTRL_CLKDIV_MASK 0x000000FFUL +#define SD_CLOCK_ENABLE 0x00000100UL +#define SD_CLOCK_DISABLE 0x00000000UL +#define SD_CLK_WRITE_MASK 0x000003FFUL +#define SD_CLK_CLKDIV_CLEAR_MASK 0xFFFFFF0FUL + +/* SD_OPTION */ #define SD_OPTION_TIMEOUT_CNT_MASK 0x000000F0UL -/** @brief MMC Clock Frequency +/* + * MMC Clock Frequency * 200MHz * 1/x = output clock */ -#define MMC_CLK_OFF 0UL /* Clock output is disabled */ -#define MMC_400KHZ 512UL /* 200MHz * 1/512 = 390 KHz */ -#define MMC_20MHZ 16UL /* 200MHz * 1/16 = 12.5 MHz Normal speed mode */ -#define MMC_26MHZ 8UL /* 200MHz * 1/8 = 25 MHz High speed mode 26Mhz */ -#define MMC_52MHZ 4UL /* 200MHz * 1/4 = 50 MHz High speed mode 52Mhz */ -#define MMC_100MHZ 2UL /* 200MHz * 1/2 = 100 MHz */ -#define MMC_200MHZ 1UL /* 200MHz * 1/1 = 200 MHz */ +#define MMC_CLK_OFF 0UL /* Clock output is disabled */ +#define MMC_400KHZ 512UL /* 200MHz * 1/512 = 390 KHz */ +#define MMC_20MHZ 16UL /* 200MHz * 1/16 = 12.5 MHz Normal speed mode */ +#define MMC_26MHZ 8UL /* 200MHz * 1/8 = 25 MHz HS mode 26Mhz */ +#define MMC_52MHZ 4UL /* 200MHz * 1/4 = 50 MHz HS mode 52Mhz */ +#define MMC_100MHZ 2UL /* 200MHz * 1/2 = 100 MHz */ +#define MMC_200MHZ 1UL /* 200MHz * 1/1 = 200 MHz */ #define MMC_FREQ_52MHZ 52000000UL #define MMC_FREQ_26MHZ 26000000UL #define MMC_FREQ_20MHZ 20000000UL -/** @brief MMC Clock DIV - */ -#define MMC_SD_CLK_START 0x00000100UL /* CLOCK On */ -#define MMC_SD_CLK_STOP (~0x00000100UL) /* CLOCK stop */ -#define MMC_SD_CLK_DIV1 0x000000FFUL /* 1/1 */ -#define MMC_SD_CLK_DIV2 0x00000000UL /* 1/2 */ -#define MMC_SD_CLK_DIV4 0x00000001UL /* 1/4 */ -#define MMC_SD_CLK_DIV8 0x00000002UL /* 1/8 */ -#define MMC_SD_CLK_DIV16 0x00000004UL /* 1/16 */ -#define MMC_SD_CLK_DIV32 0x00000008UL /* 1/32 */ -#define MMC_SD_CLK_DIV64 0x00000010UL /* 1/64 */ -#define MMC_SD_CLK_DIV128 0x00000020UL /* 1/128 */ -#define MMC_SD_CLK_DIV256 0x00000040UL /* 1/256 */ -#define MMC_SD_CLK_DIV512 0x00000080UL /* 1/512 */ - -/** @brief DM_CM_DTRAN_MODE - */ -#define DM_CM_DTRAN_MODE_CH0 0x00000000UL /* CH0(downstream) */ -#define DM_CM_DTRAN_MODE_CH1 0x00010000UL /* CH1(upstream) */ +/* MMC Clock DIV */ +#define MMC_SD_CLK_START 0x00000100UL /* CLOCK On */ +#define MMC_SD_CLK_STOP (~0x00000100UL) /* CLOCK stop */ +#define MMC_SD_CLK_DIV1 0x000000FFUL /* 1/1 */ +#define MMC_SD_CLK_DIV2 0x00000000UL /* 1/2 */ +#define MMC_SD_CLK_DIV4 0x00000001UL /* 1/4 */ +#define MMC_SD_CLK_DIV8 0x00000002UL /* 1/8 */ +#define MMC_SD_CLK_DIV16 0x00000004UL /* 1/16 */ +#define MMC_SD_CLK_DIV32 0x00000008UL /* 1/32 */ +#define MMC_SD_CLK_DIV64 0x00000010UL /* 1/64 */ +#define MMC_SD_CLK_DIV128 0x00000020UL /* 1/128 */ +#define MMC_SD_CLK_DIV256 0x00000040UL /* 1/256 */ +#define MMC_SD_CLK_DIV512 0x00000080UL /* 1/512 */ + +/* DM_CM_DTRAN_MODE */ +#define DM_CM_DTRAN_MODE_CH0 0x00000000UL /* CH0(downstream) */ +#define DM_CM_DTRAN_MODE_CH1 0x00010000UL /* CH1(upstream) */ #define DM_CM_DTRAN_MODE_BIT_WIDTH 0x00000030UL -/** @brief CC_EXT_MODE - */ +/* CC_EXT_MODE */ #define CC_EXT_MODE_DMASDRW_ENABLE 0x00000002UL /* SD_BUF Read/Write DMA Transfer */ -#define CC_EXT_MODE_CLEAR 0x00001010UL /* BIT 12 & 4 always 1. */ +#define CC_EXT_MODE_CLEAR 0x00001010UL /* BIT 12 & 4 always 1. */ -/** @brief DM_CM_INFO_MASK - */ +/* DM_CM_INFO_MASK */ #define DM_CM_INFO_MASK_CLEAR 0xFFFCFFFEUL #define DM_CM_INFO_CH0_ENABLE 0x00010001UL #define DM_CM_INFO_CH1_ENABLE 0x00020001UL -/** @brief DM_DTRAN_ADDR - */ +/* DM_DTRAN_ADDR */ #define DM_DTRAN_ADDR_WRITE_MASK 0xFFFFFFF8UL -/** @brief DM_CM_DTRAN_CTRL - */ +/* DM_CM_DTRAN_CTRL */ #define DM_CM_DTRAN_CTRL_START 0x00000001UL -/** @brief SYSC Registers - */ +/* SYSC Registers */ #if USE_MMC_CH == MMC_CH0 #define CPG_MSTP_MMC (BIT12) /* SDHI2/MMC0 */ #else /* USE_MMC_CH == MMC_CH0 */ #define CPG_MSTP_MMC (BIT11) /* SDHI3/MMC1 */ #endif /* USE_MMC_CH == MMC_CH0 */ -/* ********************** STRUCTURES, TYPE DEFINITIONS ********************* */ - -/* ********************** DECLARATION OF EXTERNAL DATA ********************* */ - -/* ************************** FUNCTION PROTOTYPES ************************** */ - -/* ********************************* CODE ********************************** */ - #endif /* EMMC_REGISTERS_H */ -/* ******************************** END ************************************ */ diff --git a/drivers/renesas/rcar/emmc/emmc_std.h b/drivers/renesas/rcar/emmc/emmc_std.h index 99cb6b992..087c6e91d 100644 --- a/drivers/renesas/rcar/emmc/emmc_std.h +++ b/drivers/renesas/rcar/emmc/emmc_std.h @@ -1,23 +1,14 @@ /* - * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ -/** - * @file emmc_std.h - * @brief eMMC boot is expecting this header file - * - */ - #ifndef EMMC_STD_H #define EMMC_STD_H #include "emmc_hal.h" -/* ************************ HEADER (INCLUDE) SECTION *********************** */ - -/* ***************** MACROS, CONSTANTS, COMPILATION FLAGS ****************** */ #ifndef FALSE #define FALSE 0U #endif @@ -25,29 +16,24 @@ #define TRUE 1U #endif -/** @brief 64bit registers - **/ -#define SETR_64(r, v) (*(volatile uint64_t *)(r) = (v)) -#define GETR_64(r) (*(volatile uint64_t *)(r)) +/* 64bit registers */ +#define SETR_64(r, v) (*(volatile uint64_t *)(r) = (v)) +#define GETR_64(r) (*(volatile uint64_t *)(r)) -/** @brief 32bit registers - **/ -#define SETR_32(r, v) (*(volatile uint32_t *)(r) = (v)) -#define GETR_32(r) (*(volatile uint32_t *)(r)) +/* 32bit registers */ +#define SETR_32(r, v) (*(volatile uint32_t *)(r) = (v)) +#define GETR_32(r) (*(volatile uint32_t *)(r)) -/** @brief 16bit registers - */ -#define SETR_16(r, v) (*(volatile uint16_t *)(r) = (v)) -#define GETR_16(r) (*(volatile uint16_t *)(r)) +/* 16bit registers */ +#define SETR_16(r, v) (*(volatile uint16_t *)(r) = (v)) +#define GETR_16(r) (*(volatile uint16_t *)(r)) -/** @brief 8bit registers - */ -#define SETR_8(r, v) (*(volatile uint8_t *)(r) = (v)) -#define GETR_8(r) (*(volatile uint8_t *)(r)) +/* 8bit registers */ +#define SETR_8(r, v) (*(volatile uint8_t *)(r) = (v)) +#define GETR_8(r) (*(volatile uint8_t *)(r)) -/** @brief CSD register Macros - */ -#define EMMC_GET_CID(x, y) (emmc_bit_field(mmc_drv_obj.cid_data, (x), (y))) +/* CSD register Macros */ +#define EMMC_GET_CID(x, y) (emmc_bit_field(mmc_drv_obj.cid_data, (x), (y))) #define EMMC_CID_MID() (EMMC_GET_CID(127, 120)) #define EMMC_CID_CBX() (EMMC_GET_CID(113, 112)) @@ -59,267 +45,269 @@ #define EMMC_CID_MDT() (EMMC_GET_CID(15, 8)) #define EMMC_CID_CRC() (EMMC_GET_CID(7, 1)) -/** @brief CSD register Macros - */ -#define EMMC_GET_CSD(x, y) (emmc_bit_field(mmc_drv_obj.csd_data, (x), (y))) - -#define EMMC_CSD_CSD_STRUCTURE() (EMMC_GET_CSD(127, 126)) -#define EMMC_CSD_SPEC_VARS() (EMMC_GET_CSD(125, 122)) -#define EMMC_CSD_TAAC() (EMMC_GET_CSD(119, 112)) -#define EMMC_CSD_NSAC() (EMMC_GET_CSD(111, 104)) -#define EMMC_CSD_TRAN_SPEED() (EMMC_GET_CSD(103, 96)) -#define EMMC_CSD_CCC() (EMMC_GET_CSD(95, 84)) -#define EMMC_CSD_READ_BL_LEN() (EMMC_GET_CSD(83, 80)) -#define EMMC_CSD_READ_BL_PARTIAL() (EMMC_GET_CSD(79, 79)) -#define EMMC_CSD_WRITE_BLK_MISALIGN() (EMMC_GET_CSD(78, 78)) -#define EMMC_CSD_READ_BLK_MISALIGN() (EMMC_GET_CSD(77, 77)) -#define EMMC_CSD_DSR_IMP() (EMMC_GET_CSD(76, 76)) -#define EMMC_CSD_C_SIZE() (EMMC_GET_CSD(73, 62)) -#define EMMC_CSD_VDD_R_CURR_MIN() (EMMC_GET_CSD(61, 59)) -#define EMMC_CSD_VDD_R_CURR_MAX() (EMMC_GET_CSD(58, 56)) -#define EMMC_CSD_VDD_W_CURR_MIN() (EMMC_GET_CSD(55, 53)) -#define EMMC_CSD_VDD_W_CURR_MAX() (EMMC_GET_CSD(52, 50)) -#define EMMC_CSD_C_SIZE_MULT() (EMMC_GET_CSD(49, 47)) -#define EMMC_CSD_ERASE_GRP_SIZE() (EMMC_GET_CSD(46, 42)) -#define EMMC_CSD_ERASE_GRP_MULT() (EMMC_GET_CSD(41, 37)) -#define EMMC_CSD_WP_GRP_SIZE() (EMMC_GET_CSD(36, 32)) -#define EMMC_CSD_WP_GRP_ENABLE() (EMMC_GET_CSD(31, 31)) -#define EMMC_CSD_DEFALT_ECC() (EMMC_GET_CSD(30, 29)) -#define EMMC_CSD_R2W_FACTOR() (EMMC_GET_CSD(28, 26)) -#define EMMC_CSD_WRITE_BL_LEN() (EMMC_GET_CSD(25, 22)) -#define EMMC_CSD_WRITE_BL_PARTIAL() (EMMC_GET_CSD(21, 21)) -#define EMMC_CSD_CONTENT_PROT_APP() (EMMC_GET_CSD(16, 16)) -#define EMMC_CSD_FILE_FORMAT_GRP() (EMMC_GET_CSD(15, 15)) -#define EMMC_CSD_COPY() (EMMC_GET_CSD(14, 14)) -#define EMMC_CSD_PERM_WRITE_PROTECT() (EMMC_GET_CSD(13, 13)) -#define EMMC_CSD_TMP_WRITE_PROTECT() (EMMC_GET_CSD(12, 12)) -#define EMMC_CSD_FILE_FORMAT() (EMMC_GET_CSD(11, 10)) -#define EMMC_CSD_ECC() (EMMC_GET_CSD(9, 8)) -#define EMMC_CSD_CRC() (EMMC_GET_CSD(7, 1)) - -/** @brief for sector access - */ -#define EMMC_4B_BOUNDARY_CHECK_MASK 0x00000003 -#define EMMC_SECTOR_SIZE_SHIFT 9U /* 512 = 2^9 */ -#define EMMC_SECTOR_SIZE 512 -#define EMMC_BLOCK_LENGTH 512 -#define EMMC_BLOCK_LENGTH_DW 128 -#define EMMC_BUF_SIZE_SHIFT 3U /* 8byte = 2^3 */ - -/** @brief eMMC specification clock - */ -#define EMMC_CLOCK_SPEC_400K 400000UL /**< initialize clock 400KHz */ -#define EMMC_CLOCK_SPEC_20M 20000000UL /**< normal speed 20MHz */ -#define EMMC_CLOCK_SPEC_26M 26000000UL /**< high speed 26MHz */ -#define EMMC_CLOCK_SPEC_52M 52000000UL /**< high speed 52MHz */ -#define EMMC_CLOCK_SPEC_100M 100000000UL /**< high speed 100MHz */ - -/** @brief EMMC driver error code. (extended HAL_MEMCARD_RETURN) - */ +/* CSD register Macros */ +#define EMMC_GET_CSD(x, y) (emmc_bit_field(mmc_drv_obj.csd_data, (x), (y))) + +#define EMMC_CSD_CSD_STRUCTURE() (EMMC_GET_CSD(127, 126)) +#define EMMC_CSD_SPEC_VARS() (EMMC_GET_CSD(125, 122)) +#define EMMC_CSD_TAAC() (EMMC_GET_CSD(119, 112)) +#define EMMC_CSD_NSAC() (EMMC_GET_CSD(111, 104)) +#define EMMC_CSD_TRAN_SPEED() (EMMC_GET_CSD(103, 96)) +#define EMMC_CSD_CCC() (EMMC_GET_CSD(95, 84)) +#define EMMC_CSD_READ_BL_LEN() (EMMC_GET_CSD(83, 80)) +#define EMMC_CSD_READ_BL_PARTIAL() (EMMC_GET_CSD(79, 79)) +#define EMMC_CSD_WRITE_BLK_MISALIGN() (EMMC_GET_CSD(78, 78)) +#define EMMC_CSD_READ_BLK_MISALIGN() (EMMC_GET_CSD(77, 77)) +#define EMMC_CSD_DSR_IMP() (EMMC_GET_CSD(76, 76)) +#define EMMC_CSD_C_SIZE() (EMMC_GET_CSD(73, 62)) +#define EMMC_CSD_VDD_R_CURR_MIN() (EMMC_GET_CSD(61, 59)) +#define EMMC_CSD_VDD_R_CURR_MAX() (EMMC_GET_CSD(58, 56)) +#define EMMC_CSD_VDD_W_CURR_MIN() (EMMC_GET_CSD(55, 53)) +#define EMMC_CSD_VDD_W_CURR_MAX() (EMMC_GET_CSD(52, 50)) +#define EMMC_CSD_C_SIZE_MULT() (EMMC_GET_CSD(49, 47)) +#define EMMC_CSD_ERASE_GRP_SIZE() (EMMC_GET_CSD(46, 42)) +#define EMMC_CSD_ERASE_GRP_MULT() (EMMC_GET_CSD(41, 37)) +#define EMMC_CSD_WP_GRP_SIZE() (EMMC_GET_CSD(36, 32)) +#define EMMC_CSD_WP_GRP_ENABLE() (EMMC_GET_CSD(31, 31)) +#define EMMC_CSD_DEFALT_ECC() (EMMC_GET_CSD(30, 29)) +#define EMMC_CSD_R2W_FACTOR() (EMMC_GET_CSD(28, 26)) +#define EMMC_CSD_WRITE_BL_LEN() (EMMC_GET_CSD(25, 22)) +#define EMMC_CSD_WRITE_BL_PARTIAL() (EMMC_GET_CSD(21, 21)) +#define EMMC_CSD_CONTENT_PROT_APP() (EMMC_GET_CSD(16, 16)) +#define EMMC_CSD_FILE_FORMAT_GRP() (EMMC_GET_CSD(15, 15)) +#define EMMC_CSD_COPY() (EMMC_GET_CSD(14, 14)) +#define EMMC_CSD_PERM_WRITE_PROTECT() (EMMC_GET_CSD(13, 13)) +#define EMMC_CSD_TMP_WRITE_PROTECT() (EMMC_GET_CSD(12, 12)) +#define EMMC_CSD_FILE_FORMAT() (EMMC_GET_CSD(11, 10)) +#define EMMC_CSD_ECC() (EMMC_GET_CSD(9, 8)) +#define EMMC_CSD_CRC() (EMMC_GET_CSD(7, 1)) + +/* sector access */ +#define EMMC_4B_BOUNDARY_CHECK_MASK 0x00000003 +#define EMMC_SECTOR_SIZE_SHIFT 9U /* 512 = 2^9 */ +#define EMMC_SECTOR_SIZE 512 +#define EMMC_BLOCK_LENGTH 512 +#define EMMC_BLOCK_LENGTH_DW 128 +#define EMMC_BUF_SIZE_SHIFT 3U /* 8byte = 2^3 */ + +/* eMMC specification clock */ +#define EMMC_CLOCK_SPEC_400K 400000UL /* initialize clock 400KHz */ +#define EMMC_CLOCK_SPEC_20M 20000000UL /* normal speed 20MHz */ +#define EMMC_CLOCK_SPEC_26M 26000000UL /* high speed 26MHz */ +#define EMMC_CLOCK_SPEC_52M 52000000UL /* high speed 52MHz */ +#define EMMC_CLOCK_SPEC_100M 100000000UL /* high speed 100MHz */ + +/* EMMC driver error code. (extended HAL_MEMCARD_RETURN) */ typedef enum { - EMMC_ERR = 0, /**< unknown error */ - EMMC_SUCCESS, /**< OK */ - EMMC_ERR_FROM_DMAC, /**< DMAC allocation error */ - EMMC_ERR_FROM_DMAC_TRANSFER, /**< DMAC transfer error */ - EMMC_ERR_CARD_STATUS_BIT, /**< card status error. Non-masked error bit was set in the card status */ - EMMC_ERR_CMD_TIMEOUT, /**< command timeout error */ - EMMC_ERR_DATA_TIMEOUT, /**< data timeout error */ - EMMC_ERR_CMD_CRC, /**< command CRC error */ - EMMC_ERR_DATA_CRC, /**< data CRC error */ - EMMC_ERR_PARAM, /**< parameter error */ - EMMC_ERR_RESPONSE, /**< response error */ - EMMC_ERR_RESPONSE_BUSY, /**< response busy error */ - EMMC_ERR_TRANSFER, /**< data transfer error */ - EMMC_ERR_READ_SECTOR, /**< read sector error */ - EMMC_ERR_WRITE_SECTOR, /**< write sector error */ - EMMC_ERR_STATE, /**< state error */ - EMMC_ERR_TIMEOUT, /**< timeout error */ - EMMC_ERR_ILLEGAL_CARD, /**< illegal card */ - EMMC_ERR_CARD_BUSY, /**< Busy state */ - EMMC_ERR_CARD_STATE, /**< card state error */ - EMMC_ERR_SET_TRACE, /**< trace information error */ - EMMC_ERR_FROM_TIMER, /**< Timer error */ - EMMC_ERR_FORCE_TERMINATE, /**< Force terminate */ - EMMC_ERR_CARD_POWER, /**< card power fail */ - EMMC_ERR_ERASE_SECTOR, /**< erase sector error */ - EMMC_ERR_INFO2 /**< exec cmd error info2 */ + EMMC_ERR = 0, /* unknown error */ + EMMC_SUCCESS, /* OK */ + EMMC_ERR_FROM_DMAC, /* DMAC allocation error */ + EMMC_ERR_FROM_DMAC_TRANSFER, /* DMAC transfer error */ + EMMC_ERR_CARD_STATUS_BIT, /* card status error */ + EMMC_ERR_CMD_TIMEOUT, /* command timeout error */ + EMMC_ERR_DATA_TIMEOUT, /* data timeout error */ + EMMC_ERR_CMD_CRC, /* command CRC error */ + EMMC_ERR_DATA_CRC, /* data CRC error */ + EMMC_ERR_PARAM, /* parameter error */ + EMMC_ERR_RESPONSE, /* response error */ + EMMC_ERR_RESPONSE_BUSY, /* response busy error */ + EMMC_ERR_TRANSFER, /* data transfer error */ + EMMC_ERR_READ_SECTOR, /* read sector error */ + EMMC_ERR_WRITE_SECTOR, /* write sector error */ + EMMC_ERR_STATE, /* state error */ + EMMC_ERR_TIMEOUT, /* timeout error */ + EMMC_ERR_ILLEGAL_CARD, /* illegal card */ + EMMC_ERR_CARD_BUSY, /* Busy state */ + EMMC_ERR_CARD_STATE, /* card state error */ + EMMC_ERR_SET_TRACE, /* trace information error */ + EMMC_ERR_FROM_TIMER, /* Timer error */ + EMMC_ERR_FORCE_TERMINATE, /* Force terminate */ + EMMC_ERR_CARD_POWER, /* card power fail */ + EMMC_ERR_ERASE_SECTOR, /* erase sector error */ + EMMC_ERR_INFO2 /* exec cmd error info2 */ } EMMC_ERROR_CODE; -/** @brief Function number */ -#define EMMC_FUNCNO_NONE 0U -#define EMMC_FUNCNO_DRIVER_INIT 1U -#define EMMC_FUNCNO_CARD_POWER_ON 2U -#define EMMC_FUNCNO_MOUNT 3U -#define EMMC_FUNCNO_CARD_INIT 4U -#define EMMC_FUNCNO_HIGH_SPEED 5U -#define EMMC_FUNCNO_BUS_WIDTH 6U -#define EMMC_FUNCNO_MULTI_BOOT_SELECT_PARTITION 7U -#define EMMC_FUNCNO_MULTI_BOOT_READ_SECTOR 8U -#define EMMC_FUNCNO_TRANS_DATA_READ_SECTOR 9U -#define EMMC_FUNCNO_UBOOT_IMAGE_SELECT_PARTITION 10U -#define EMMC_FUNCNO_UBOOT_IMAGE_READ_SECTOR 11U -#define EMMC_FUNCNO_SET_CLOCK 12U -#define EMMC_FUNCNO_EXEC_CMD 13U -#define EMMC_FUNCNO_READ_SECTOR 14U -#define EMMC_FUNCNO_WRITE_SECTOR 15U -#define EMMC_FUNCNO_ERASE_SECTOR 16U -#define EMMC_FUNCNO_GET_PERTITION_ACCESS 17U -/** @brief Response +/* Function number */ +#define EMMC_FUNCNO_NONE 0U +#define EMMC_FUNCNO_DRIVER_INIT 1U +#define EMMC_FUNCNO_CARD_POWER_ON 2U +#define EMMC_FUNCNO_MOUNT 3U +#define EMMC_FUNCNO_CARD_INIT 4U +#define EMMC_FUNCNO_HIGH_SPEED 5U +#define EMMC_FUNCNO_BUS_WIDTH 6U +#define EMMC_FUNCNO_MULTI_BOOT_SELECT_PARTITION 7U +#define EMMC_FUNCNO_MULTI_BOOT_READ_SECTOR 8U +#define EMMC_FUNCNO_TRANS_DATA_READ_SECTOR 9U +#define EMMC_FUNCNO_UBOOT_IMAGE_SELECT_PARTITION 10U +#define EMMC_FUNCNO_UBOOT_IMAGE_READ_SECTOR 11U +#define EMMC_FUNCNO_SET_CLOCK 12U +#define EMMC_FUNCNO_EXEC_CMD 13U +#define EMMC_FUNCNO_READ_SECTOR 14U +#define EMMC_FUNCNO_WRITE_SECTOR 15U +#define EMMC_FUNCNO_ERASE_SECTOR 16U +#define EMMC_FUNCNO_GET_PERTITION_ACCESS 17U +/* + * Response + * R1 + * Type 'E' bit and bit14(must be 0). ignore bit22 */ -/** R1 */ -#define EMMC_R1_ERROR_MASK 0xFDBFE080U /* Type 'E' bit and bit14(must be 0). ignore bit22 */ -#define EMMC_R1_ERROR_MASK_WITHOUT_CRC (0xFD3FE080U) /* Ignore bit23 (Not check CRC error) */ -#define EMMC_R1_STATE_MASK 0x00001E00U /* [12:9] */ -#define EMMC_R1_READY 0x00000100U /* bit8 */ -#define EMMC_R1_STATE_SHIFT 9 - -/** R4 */ -#define EMMC_R4_RCA_MASK 0xFFFF0000UL -#define EMMC_R4_STATUS 0x00008000UL - -/** CSD */ -#define EMMC_TRANSPEED_FREQ_UNIT_MASK 0x07 /* bit[2:0] */ -#define EMMC_TRANSPEED_FREQ_UNIT_SHIFT 0 -#define EMMC_TRANSPEED_MULT_MASK 0x78 /* bit[6:3] */ -#define EMMC_TRANSPEED_MULT_SHIFT 3 - -/** OCR */ -#define EMMC_HOST_OCR_VALUE 0x40FF8080 -#define EMMC_OCR_STATUS_BIT 0x80000000L /* Card power up status bit */ -#define EMMC_OCR_ACCESS_MODE_MASK 0x60000000L /* bit[30:29] */ -#define EMMC_OCR_ACCESS_MODE_SECT 0x40000000L -#define EMMC_OCR_ACCESS_MODE_BYTE 0x00000000L - -/** EXT_CSD */ -#define EMMC_EXT_CSD_S_CMD_SET 504 -#define EMMC_EXT_CSD_INI_TIMEOUT_AP 241 -#define EMMC_EXT_CSD_PWR_CL_DDR_52_360 239 -#define EMMC_EXT_CSD_PWR_CL_DDR_52_195 238 -#define EMMC_EXT_CSD_MIN_PERF_DDR_W_8_52 235 -#define EMMC_EXT_CSD_MIN_PERF_DDR_R_8_52 234 -#define EMMC_EXT_CSD_TRIM_MULT 232 -#define EMMC_EXT_CSD_SEC_FEATURE_SUPPORT 231 -#define EMMC_EXT_CSD_SEC_ERASE_MULT 229 -#define EMMC_EXT_CSD_BOOT_INFO 228 -#define EMMC_EXT_CSD_BOOT_SIZE_MULTI 226 -#define EMMC_EXT_CSD_ACC_SIZE 225 -#define EMMC_EXT_CSD_HC_ERASE_GRP_SIZE 224 -#define EMMC_EXT_CSD_ERASE_TIMEOUT_MULT 223 -#define EMMC_EXT_CSD_PEL_WR_SEC_C 222 -#define EMMC_EXT_CSD_HC_WP_GRP_SIZE 221 -#define EMMC_EXT_CSD_S_C_VCC 220 -#define EMMC_EXT_CSD_S_C_VCCQ 219 -#define EMMC_EXT_CSD_S_A_TIMEOUT 217 -#define EMMC_EXT_CSD_SEC_COUNT 215 -#define EMMC_EXT_CSD_MIN_PERF_W_8_52 210 -#define EMMC_EXT_CSD_MIN_PERF_R_8_52 209 -#define EMMC_EXT_CSD_MIN_PERF_W_8_26_4_52 208 -#define EMMC_EXT_CSD_MIN_PERF_R_8_26_4_52 207 -#define EMMC_EXT_CSD_MIN_PERF_W_4_26 206 -#define EMMC_EXT_CSD_MIN_PERF_R_4_26 205 -#define EMMC_EXT_CSD_PWR_CL_26_360 203 -#define EMMC_EXT_CSD_PWR_CL_52_360 202 -#define EMMC_EXT_CSD_PWR_CL_26_195 201 -#define EMMC_EXT_CSD_PWR_CL_52_195 200 -#define EMMC_EXT_CSD_CARD_TYPE 196 -#define EMMC_EXT_CSD_CSD_STRUCTURE 194 -#define EMMC_EXT_CSD_EXT_CSD_REV 192 -#define EMMC_EXT_CSD_CMD_SET 191 -#define EMMC_EXT_CSD_CMD_SET_REV 189 -#define EMMC_EXT_CSD_POWER_CLASS 187 -#define EMMC_EXT_CSD_HS_TIMING 185 -#define EMMC_EXT_CSD_BUS_WIDTH 183 -#define EMMC_EXT_CSD_ERASED_MEM_CONT 181 -#define EMMC_EXT_CSD_PARTITION_CONFIG 179 -#define EMMC_EXT_CSD_BOOT_CONFIG_PROT 178 -#define EMMC_EXT_CSD_BOOT_BUS_WIDTH 177 -#define EMMC_EXT_CSD_ERASE_GROUP_DEF 175 -#define EMMC_EXT_CSD_BOOT_WP 173 -#define EMMC_EXT_CSD_USER_WP 171 -#define EMMC_EXT_CSD_FW_CONFIG 169 -#define EMMC_EXT_CSD_RPMB_SIZE_MULT 168 -#define EMMC_EXT_CSD_RST_n_FUNCTION 162 -#define EMMC_EXT_CSD_PARTITIONING_SUPPORT 160 -#define EMMC_EXT_CSD_MAX_ENH_SIZE_MULT 159 -#define EMMC_EXT_CSD_PARTITIONS_ATTRIBUTE 156 -#define EMMC_EXT_CSD_PARTITION_SETTING_COMPLETED 155 -#define EMMC_EXT_CSD_GP_SIZE_MULT 154 -#define EMMC_EXT_CSD_ENH_SIZE_MULT 142 -#define EMMC_EXT_CSD_ENH_START_ADDR 139 -#define EMMC_EXT_CSD_SEC_BAD_BLK_MGMNT 134 - -#define EMMC_EXT_CSD_CARD_TYPE_26MHZ 0x01 -#define EMMC_EXT_CSD_CARD_TYPE_52MHZ 0x02 -#define EMMC_EXT_CSD_CARD_TYPE_DDR_52MHZ_12V 0x04 -#define EMMC_EXT_CSD_CARD_TYPE_DDR_52MHZ_18V 0x08 -#define EMMC_EXT_CSD_CARD_TYPE_52MHZ_MASK 0x0e - -/** SWITCH (CMD6) argument */ -#define EXTCSD_ACCESS_BYTE (BIT25|BIT24) -#define EXTCSD_SET_BITS BIT24 - -#define HS_TIMING_ADD (185<<16) /* H'b9 */ -#define HS_TIMING_1 (1<<8) -#define HS_TIMING_HS200 (2<<8) -#define HS_TIMING_HS400 (3<<8) - -#define BUS_WIDTH_ADD (183<<16) /* H'b7 */ -#define BUS_WIDTH_1 (0<<8) -#define BUS_WIDTH_4 (1<<8) -#define BUS_WIDTH_8 (2<<8) -#define BUS_WIDTH_4DDR (5<<8) -#define BUS_WIDTH_8DDR (6<<8) - -#define EMMC_SWITCH_HS_TIMING (EXTCSD_ACCESS_BYTE|HS_TIMING_ADD|HS_TIMING_1) /**< H'03b90100 */ -#define EMMC_SWITCH_HS_TIMING_OFF (EXTCSD_ACCESS_BYTE|HS_TIMING_ADD) /**< H'03b90000 */ - -#define EMMC_SWITCH_BUS_WIDTH_1 (EXTCSD_ACCESS_BYTE|BUS_WIDTH_ADD|BUS_WIDTH_1) /**< H'03b70000 */ -#define EMMC_SWITCH_BUS_WIDTH_4 (EXTCSD_ACCESS_BYTE|BUS_WIDTH_ADD|BUS_WIDTH_4) /**< H'03b70100 */ -#define EMMC_SWITCH_BUS_WIDTH_8 (EXTCSD_ACCESS_BYTE|BUS_WIDTH_ADD|BUS_WIDTH_8) /**< H'03b70200 */ -#define EMMC_SWITCH_BUS_WIDTH_4DDR (EXTCSD_ACCESS_BYTE|BUS_WIDTH_ADD|BUS_WIDTH_4DDR) /**< H'03b70500 */ -#define EMMC_SWITCH_BUS_WIDTH_8DDR (EXTCSD_ACCESS_BYTE|BUS_WIDTH_ADD|BUS_WIDTH_8DDR) /**< H'03b70600 */ -#define EMMC_SWITCH_PARTITION_CONFIG 0x03B30000UL /**< Partition config = 0x00 */ - -#define TIMING_HIGH_SPEED 1UL +#define EMMC_R1_ERROR_MASK 0xFDBFE080U +/* Ignore bit23 (Not check CRC error) */ +#define EMMC_R1_ERROR_MASK_WITHOUT_CRC (0xFD3FE080U) +#define EMMC_R1_STATE_MASK 0x00001E00U /* [12:9] */ +#define EMMC_R1_READY 0x00000100U /* bit8 */ +#define EMMC_R1_STATE_SHIFT 9 + +/* R4 */ +#define EMMC_R4_RCA_MASK 0xFFFF0000UL +#define EMMC_R4_STATUS 0x00008000UL + +/* CSD */ +#define EMMC_TRANSPEED_FREQ_UNIT_MASK 0x07 /* bit[2:0] */ +#define EMMC_TRANSPEED_FREQ_UNIT_SHIFT 0 +#define EMMC_TRANSPEED_MULT_MASK 0x78 /* bit[6:3] */ +#define EMMC_TRANSPEED_MULT_SHIFT 3 + +/* OCR */ +#define EMMC_HOST_OCR_VALUE 0x40FF8080 +#define EMMC_OCR_STATUS_BIT 0x80000000L /* Card power up status bit */ +#define EMMC_OCR_ACCESS_MODE_MASK 0x60000000L /* bit[30:29] */ +#define EMMC_OCR_ACCESS_MODE_SECT 0x40000000L +#define EMMC_OCR_ACCESS_MODE_BYTE 0x00000000L + +/* EXT_CSD */ +#define EMMC_EXT_CSD_S_CMD_SET 504 +#define EMMC_EXT_CSD_INI_TIMEOUT_AP 241 +#define EMMC_EXT_CSD_PWR_CL_DDR_52_360 239 +#define EMMC_EXT_CSD_PWR_CL_DDR_52_195 238 +#define EMMC_EXT_CSD_MIN_PERF_DDR_W_8_52 235 +#define EMMC_EXT_CSD_MIN_PERF_DDR_R_8_52 234 +#define EMMC_EXT_CSD_TRIM_MULT 232 +#define EMMC_EXT_CSD_SEC_FEATURE_SUPPORT 231 +#define EMMC_EXT_CSD_SEC_ERASE_MULT 229 +#define EMMC_EXT_CSD_BOOT_INFO 228 +#define EMMC_EXT_CSD_BOOT_SIZE_MULTI 226 +#define EMMC_EXT_CSD_ACC_SIZE 225 +#define EMMC_EXT_CSD_HC_ERASE_GRP_SIZE 224 +#define EMMC_EXT_CSD_ERASE_TIMEOUT_MULT 223 +#define EMMC_EXT_CSD_PEL_WR_SEC_C 222 +#define EMMC_EXT_CSD_HC_WP_GRP_SIZE 221 +#define EMMC_EXT_CSD_S_C_VCC 220 +#define EMMC_EXT_CSD_S_C_VCCQ 219 +#define EMMC_EXT_CSD_S_A_TIMEOUT 217 +#define EMMC_EXT_CSD_SEC_COUNT 215 +#define EMMC_EXT_CSD_MIN_PERF_W_8_52 210 +#define EMMC_EXT_CSD_MIN_PERF_R_8_52 209 +#define EMMC_EXT_CSD_MIN_PERF_W_8_26_4_52 208 +#define EMMC_EXT_CSD_MIN_PERF_R_8_26_4_52 207 +#define EMMC_EXT_CSD_MIN_PERF_W_4_26 206 +#define EMMC_EXT_CSD_MIN_PERF_R_4_26 205 +#define EMMC_EXT_CSD_PWR_CL_26_360 203 +#define EMMC_EXT_CSD_PWR_CL_52_360 202 +#define EMMC_EXT_CSD_PWR_CL_26_195 201 +#define EMMC_EXT_CSD_PWR_CL_52_195 200 +#define EMMC_EXT_CSD_CARD_TYPE 196 +#define EMMC_EXT_CSD_CSD_STRUCTURE 194 +#define EMMC_EXT_CSD_EXT_CSD_REV 192 +#define EMMC_EXT_CSD_CMD_SET 191 +#define EMMC_EXT_CSD_CMD_SET_REV 189 +#define EMMC_EXT_CSD_POWER_CLASS 187 +#define EMMC_EXT_CSD_HS_TIMING 185 +#define EMMC_EXT_CSD_BUS_WIDTH 183 +#define EMMC_EXT_CSD_ERASED_MEM_CONT 181 +#define EMMC_EXT_CSD_PARTITION_CONFIG 179 +#define EMMC_EXT_CSD_BOOT_CONFIG_PROT 178 +#define EMMC_EXT_CSD_BOOT_BUS_WIDTH 177 +#define EMMC_EXT_CSD_ERASE_GROUP_DEF 175 +#define EMMC_EXT_CSD_BOOT_WP 173 +#define EMMC_EXT_CSD_USER_WP 171 +#define EMMC_EXT_CSD_FW_CONFIG 169 +#define EMMC_EXT_CSD_RPMB_SIZE_MULT 168 +#define EMMC_EXT_CSD_RST_n_FUNCTION 162 +#define EMMC_EXT_CSD_PARTITIONING_SUPPORT 160 +#define EMMC_EXT_CSD_MAX_ENH_SIZE_MULT 159 +#define EMMC_EXT_CSD_PARTITIONS_ATTRIBUTE 156 +#define EMMC_EXT_CSD_PARTITION_SETTING_COMPLETED 155 +#define EMMC_EXT_CSD_GP_SIZE_MULT 154 +#define EMMC_EXT_CSD_ENH_SIZE_MULT 142 +#define EMMC_EXT_CSD_ENH_START_ADDR 139 +#define EMMC_EXT_CSD_SEC_BAD_BLK_MGMNT 134 + +#define EMMC_EXT_CSD_CARD_TYPE_26MHZ 0x01 +#define EMMC_EXT_CSD_CARD_TYPE_52MHZ 0x02 +#define EMMC_EXT_CSD_CARD_TYPE_DDR_52MHZ_12V 0x04 +#define EMMC_EXT_CSD_CARD_TYPE_DDR_52MHZ_18V 0x08 +#define EMMC_EXT_CSD_CARD_TYPE_52MHZ_MASK 0x0e + +/* SWITCH (CMD6) argument */ +#define EXTCSD_ACCESS_BYTE (BIT25 | BIT24) +#define EXTCSD_SET_BITS BIT24 + +#define HS_TIMING_ADD (185 << 16) /* H'b9 */ +#define HS_TIMING_1 (1 << 8) +#define HS_TIMING_HS200 (2 << 8) +#define HS_TIMING_HS400 (3 << 8) + +#define BUS_WIDTH_ADD (183 << 16) /* H'b7 */ +#define BUS_WIDTH_1 (0 << 8) +#define BUS_WIDTH_4 (1 << 8) +#define BUS_WIDTH_8 (2 << 8) +#define BUS_WIDTH_4DDR (5 << 8) +#define BUS_WIDTH_8DDR (6 << 8) + +#define EMMC_SWITCH_HS_TIMING (EXTCSD_ACCESS_BYTE | HS_TIMING_ADD |\ + HS_TIMING_1) /* H'03b90100 */ +#define EMMC_SWITCH_HS_TIMING_OFF (EXTCSD_ACCESS_BYTE |\ + HS_TIMING_ADD) /* H'03b90000 */ + +#define EMMC_SWITCH_BUS_WIDTH_1 (EXTCSD_ACCESS_BYTE | BUS_WIDTH_ADD |\ + BUS_WIDTH_1) /* H'03b70000 */ +#define EMMC_SWITCH_BUS_WIDTH_4 (EXTCSD_ACCESS_BYTE | BUS_WIDTH_ADD |\ + BUS_WIDTH_4) /* H'03b70100 */ +#define EMMC_SWITCH_BUS_WIDTH_8 (EXTCSD_ACCESS_BYTE | BUS_WIDTH_ADD |\ + BUS_WIDTH_8) /* H'03b70200 */ +#define EMMC_SWITCH_BUS_WIDTH_4DDR (EXTCSD_ACCESS_BYTE | BUS_WIDTH_ADD |\ + BUS_WIDTH_4DDR) /* H'03b70500 */ +#define EMMC_SWITCH_BUS_WIDTH_8DDR (EXTCSD_ACCESS_BYTE | BUS_WIDTH_ADD |\ + BUS_WIDTH_8DDR) /* H'03b70600 */ +/* Partition config = 0x00 */ +#define EMMC_SWITCH_PARTITION_CONFIG 0x03B30000UL + +#define TIMING_HIGH_SPEED 1UL #define EMMC_BOOT_PARTITION_EN_MASK 0x38U #define EMMC_BOOT_PARTITION_EN_SHIFT 3U -/** Bus width */ -#define EMMC_BUSWIDTH_1BIT CE_CMD_SET_DATW_1BIT -#define EMMC_BUSWIDTH_4BIT CE_CMD_SET_DATW_4BIT -#define EMMC_BUSWIDTH_8BIT CE_CMD_SET_DATW_8BIT +/* Bus width */ +#define EMMC_BUSWIDTH_1BIT CE_CMD_SET_DATW_1BIT +#define EMMC_BUSWIDTH_4BIT CE_CMD_SET_DATW_4BIT +#define EMMC_BUSWIDTH_8BIT CE_CMD_SET_DATW_8BIT -/** for st_mmc_base */ -#define EMMC_MAX_RESPONSE_LENGTH 17 -#define EMMC_MAX_CID_LENGTH 16 -#define EMMC_MAX_CSD_LENGTH 16 -#define EMMC_MAX_EXT_CSD_LENGTH 512U -#define EMMC_RES_REG_ALIGNED 4U -#define EMMC_BUF_REG_ALIGNED 8U +/* for st_mmc_base */ +#define EMMC_MAX_RESPONSE_LENGTH 17 +#define EMMC_MAX_CID_LENGTH 16 +#define EMMC_MAX_CSD_LENGTH 16 +#define EMMC_MAX_EXT_CSD_LENGTH 512U +#define EMMC_RES_REG_ALIGNED 4U +#define EMMC_BUF_REG_ALIGNED 8U -/** @brief for TAAC mask - */ -#define TAAC_TIME_UNIT_MASK (0x07) -#define TAAC_MULTIPLIER_FACTOR_MASK (0x0F) +/* TAAC mask */ +#define TAAC_TIME_UNIT_MASK (0x07) +#define TAAC_MULTIPLIER_FACTOR_MASK (0x0F) -/* ********************** STRUCTURES, TYPE DEFINITIONS ********************* */ - -/** @brief Partition id - */ +/* Partition id */ typedef enum { - PARTITION_ID_USER = 0x0, /**< User Area */ - PARTITION_ID_BOOT_1 = 0x1, /**< boot partition 1 */ - PARTITION_ID_BOOT_2 = 0x2, /**< boot partition 2 */ - PARTITION_ID_RPMB = 0x3, /**< Replay Protected Memory Block */ - PARTITION_ID_GP_1 = 0x4, /**< General Purpose partition 1 */ - PARTITION_ID_GP_2 = 0x5, /**< General Purpose partition 2 */ - PARTITION_ID_GP_3 = 0x6, /**< General Purpose partition 3 */ - PARTITION_ID_GP_4 = 0x7, /**< General Purpose partition 4 */ - PARTITION_ID_MASK = 0x7 /**< [2:0] */ + PARTITION_ID_USER = 0x0, /* User Area */ + PARTITION_ID_BOOT_1 = 0x1, /* boot partition 1 */ + PARTITION_ID_BOOT_2 = 0x2, /* boot partition 2 */ + PARTITION_ID_RPMB = 0x3, /* Replay Protected Memory Block */ + PARTITION_ID_GP_1 = 0x4, /* General Purpose partition 1 */ + PARTITION_ID_GP_2 = 0x5, /* General Purpose partition 2 */ + PARTITION_ID_GP_3 = 0x6, /* General Purpose partition 3 */ + PARTITION_ID_GP_4 = 0x7, /* General Purpose partition 4 */ + PARTITION_ID_MASK = 0x7 /* [2:0] */ } EMMC_PARTITION_ID; -/** @brief card state in R1 response [12:9] - */ +/* card state in R1 response [12:9] */ typedef enum { EMMC_R1_STATE_IDLE = 0, EMMC_R1_STATE_READY, @@ -349,126 +337,139 @@ typedef enum { ESTATE_END } EMMC_INT_STATE; -/** @brief eMMC boot driver error information - */ +/* eMMC boot driver error information */ typedef struct { - uint16_t num; /**< error no */ - uint16_t code; /**< error code */ - volatile uint32_t info1; /**< SD_INFO1 register value. (hardware dependence) */ - volatile uint32_t info2; /**< SD_INFO2 register value. (hardware dependence) */ - volatile uint32_t status1;/**< SD_ERR_STS1 register value. (hardware dependence) */ - volatile uint32_t status2;/**< SD_ERR_STS2 register value. (hardware dependence) */ - volatile uint32_t dm_info1;/**< DM_CM_INFO1 register value. (hardware dependence) */ - volatile uint32_t dm_info2;/**< DM_CM_INFO2 register value. (hardware dependence) */ + uint16_t num; /* error no */ + uint16_t code; /* error code */ + + volatile uint32_t info1; /* SD_INFO1. (hw dependent) */ + volatile uint32_t info2; /* SD_INFO2. (hw dependent) */ + volatile uint32_t status1; /* SD_ERR_STS1. (hw dependent) */ + volatile uint32_t status2; /* SD_ERR_STS2. (hw dependent) */ + volatile uint32_t dm_info1; /* DM_CM_INFO1. (hw dependent) */ + volatile uint32_t dm_info2; /* DM_CM_INFO2. (hw dependent) */ } st_error_info; -/** @brief Command information - */ +/* Command information */ typedef struct { - HAL_MEMCARD_COMMAND cmd; /**< Command information */ - uint32_t arg; /**< argument */ - HAL_MEMCARD_OPERATION dir; /**< direction */ - uint32_t hw; /**< H/W dependence. SD_CMD register value. */ + HAL_MEMCARD_COMMAND cmd; /* Command information */ + uint32_t arg; /* argument */ + HAL_MEMCARD_OPERATION dir; /* direction */ + uint32_t hw; /* SD_CMD register value. */ } st_command_info; -/** @brief MMC driver base - */ +/* MMC driver base */ typedef struct { - st_error_info error_info; /**< error information */ - st_command_info cmd_info; /**< command information */ + st_error_info error_info; /* error information */ + st_command_info cmd_info; /* command information */ /* for data transfer */ - uint32_t *buff_address_virtual; /**< Dest or Src buff */ - uint32_t *buff_address_physical; /**< Dest or Src buff */ - HAL_MEMCARD_DATA_WIDTH bus_width; - /**< bus width */ - uint32_t trans_size; /**< transfer size for this command */ - uint32_t remain_size; /**< remain size for this command */ - uint32_t response_length; /**< response length for this command */ - uint32_t sector_size; /**< sector_size */ + uint32_t *buff_address_virtual; /* Dest or Src buff */ + uint32_t *buff_address_physical; /* Dest or Src buff */ + HAL_MEMCARD_DATA_WIDTH bus_width; /* bus width */ + + uint32_t trans_size; /* transfer size for this command */ + uint32_t remain_size; /* remain size for this command */ + uint32_t response_length; /* response length for this command */ + uint32_t sector_size; /* sector_size */ /* clock */ - uint32_t base_clock; /**< MMC host controller clock */ - uint32_t max_freq; /**< Max frequency (Card Spec)[Hz]. It changes dynamically by CSD and EXT_CSD. */ - uint32_t request_freq; /**< request freq [Hz] (400K, 26MHz, 52MHz, etc) */ - uint32_t current_freq; /**< current MMC clock[Hz] (the closest frequency supported by HW) */ + uint32_t base_clock; /* MMC host controller clock */ + /* + * Max freq (Card Spec)[Hz]. It changes dynamically by CSD and + * EXT_CSD. + */ + uint32_t max_freq; + /* request freq [Hz] (400K, 26MHz, 52MHz, etc) */ + uint32_t request_freq; + /* current MMC clock[Hz] (the closest frequency supported by HW) */ + uint32_t current_freq; /* state flag */ + /* presence status of the memory card */ HAL_MEMCARD_PRESENCE_STATUS card_present; - /**< presence status of the memory card */ - uint32_t card_power_enable; /**< True : Power ON */ - uint32_t clock_enable; /**< True : Clock ON */ - uint32_t initialize; /**< True : initialize complete. */ - uint32_t access_mode; /**< True : sector access, FALSE : byte access */ - uint32_t mount; /**< True : mount complete. */ - uint32_t selected; /**< True : selected card. */ + + uint32_t card_power_enable; + uint32_t clock_enable; + /* True : initialize complete. */ + uint32_t initialize; + /* True : sector access, FALSE : byte access */ + uint32_t access_mode; + /* True : mount complete. */ + uint32_t mount; + /* True : selected card. */ + uint32_t selected; + /* 0: DMA, 1:PIO */ HAL_MEMCARD_DATA_TRANSFER_MODE transfer_mode; - /**< 0: DMA, 1:PIO */ - uint32_t image_num; /**< loaded ISSW image No. ISSW have copy image. */ - EMMC_R1_STATE current_state; /**< card state */ - volatile uint32_t during_cmd_processing; /**< True : during command processing */ - volatile uint32_t during_transfer; /**< True : during transfer */ - volatile uint32_t during_dma_transfer; /**< True : during transfer (DMA)*/ - volatile uint32_t dma_error_flag; /**< True : occurred DMAC error */ - volatile uint32_t force_terminate; /**< force terminate flag */ - volatile uint32_t state_machine_blocking; /**< state machine blocking flag : True or False */ + + /* loaded ISSW image No. ISSW have copy image. */ + uint32_t image_num; + /* card state */ + EMMC_R1_STATE current_state; + /* True : during command processing */ + volatile uint32_t during_cmd_processing; + /* True : during transfer */ + volatile uint32_t during_transfer; + /* True : during transfer (DMA) */ + volatile uint32_t during_dma_transfer; + /* True : occurred DMAC error */ + volatile uint32_t dma_error_flag; + /* force terminate flag */ + volatile uint32_t force_terminate; + /* state machine blocking flag : True or False */ + volatile uint32_t state_machine_blocking; + /* True : get partition access processing */ volatile uint32_t get_partition_access_flag; - /**< True : get partition access processing */ - EMMC_PARTITION_ID boot_partition_en; /**< Boot partition */ - EMMC_PARTITION_ID partition_access; /**< Current access partition */ + EMMC_PARTITION_ID boot_partition_en; /* Boot partition */ + EMMC_PARTITION_ID partition_access; /* Current access partition */ /* timeout */ - uint32_t hs_timing; /**< high speed */ + uint32_t hs_timing; - /* timeout */ - uint32_t data_timeout; /**< read and write data timeout.*/ + /* read and write data timeout */ + uint32_t data_timeout; /* retry */ - uint32_t retries_after_fail; /**< how many times to try after fail, for instance sending command */ + uint32_t retries_after_fail; /* interrupt */ - volatile uint32_t int_event1; /**< interrupt SD_INFO1 Event */ - volatile uint32_t int_event2; /**< interrupt SD_INFO2 Event */ - volatile uint32_t dm_event1; /**< interrupt DM_CM_INFO1 Event */ - volatile uint32_t dm_event2; /**< interrupt DM_CM_INFO2 Event */ + volatile uint32_t int_event1; /* interrupt SD_INFO1 Event */ + volatile uint32_t int_event2; /* interrupt SD_INFO2 Event */ + volatile uint32_t dm_event1; /* interrupt DM_CM_INFO1 Event */ + volatile uint32_t dm_event2; /* interrupt DM_CM_INFO2 Event */ /* response */ - uint32_t *response; /**< pointer to buffer for executing command. */ - uint32_t r1_card_status; /**< R1 response data */ - uint32_t r3_ocr; /**< R3 response data */ - uint32_t r4_resp; /**< R4 response data */ - uint32_t r5_resp; /**< R5 response data */ + uint32_t *response; /* buffer ptr for executing command. */ + uint32_t r1_card_status; /* R1 response data */ + uint32_t r3_ocr; /* R3 response data */ + uint32_t r4_resp; /* R4 response data */ + uint32_t r5_resp; /* R5 response data */ + /* True : clock mode is low. (MMC clock = Max26MHz) */ uint32_t low_clock_mode_enable; - /**< True : clock mode is low. (MMC clock = Max26MHz) */ + uint32_t reserved2; uint32_t reserved3; uint32_t reserved4; /* CSD registers (4byte align) */ - uint8_t csd_data[EMMC_MAX_CSD_LENGTH] /**< CSD */ + uint8_t csd_data[EMMC_MAX_CSD_LENGTH] /* CSD */ __attribute__ ((aligned(EMMC_RES_REG_ALIGNED))); /* CID registers (4byte align) */ - uint8_t cid_data[EMMC_MAX_CID_LENGTH] /**< CID */ + uint8_t cid_data[EMMC_MAX_CID_LENGTH] /* CID */ __attribute__ ((aligned(EMMC_RES_REG_ALIGNED))); /* EXT CSD registers (8byte align) */ - uint8_t ext_csd_data[EMMC_MAX_EXT_CSD_LENGTH] /**< EXT_CSD */ + uint8_t ext_csd_data[EMMC_MAX_EXT_CSD_LENGTH] /* EXT_CSD */ __attribute__ ((aligned(EMMC_BUF_REG_ALIGNED))); /* Response registers (4byte align) */ - uint8_t response_data[EMMC_MAX_RESPONSE_LENGTH] /**< other response */ + uint8_t response_data[EMMC_MAX_RESPONSE_LENGTH] /* other response */ __attribute__ ((aligned(EMMC_RES_REG_ALIGNED))); } st_mmc_base; typedef int (*func) (void); -/* ********************** DECLARATION OF EXTERNAL DATA ********************* */ - -/* ************************** FUNCTION PROTOTYPES ************************** */ uint32_t emmc_get_csd_time(void); #define MMC_DEBUG -/* ********************************* CODE ********************************** */ - -/* ******************************** END ************************************ */ #endif /* EMMC_STD_H */ diff --git a/drivers/renesas/rcar/emmc/emmc_utility.c b/drivers/renesas/rcar/emmc/emmc_utility.c index 39d9ede5a..2e88abc75 100644 --- a/drivers/renesas/rcar/emmc/emmc_utility.c +++ b/drivers/renesas/rcar/emmc/emmc_utility.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,10 +7,10 @@ #include #include "emmc_config.h" +#include "emmc_def.h" #include "emmc_hal.h" -#include "emmc_std.h" #include "emmc_registers.h" -#include "emmc_def.h" +#include "emmc_std.h" static const uint32_t cmd_reg_hw[EMMC_CMD_MAX + 1] = { 0x00000000, /* CMD0 */ @@ -97,8 +97,8 @@ uint32_t emmc_bit_field(uint8_t *data, uint32_t top, uint32_t bottom) value = (uint32_t) ((data[index_top] << 24) | (data[index_top + 1] << 16) | - (data[index_top + 2] << 8) | data[index_top + - 3]); + (data[index_top + 2] << 8) | + data[index_top + 3]); } value = ((value >> (bottom & 0x07)) & ((1 << (top - bottom + 1)) - 1)); @@ -150,7 +150,7 @@ void emmc_make_nontrans_cmd(HAL_MEMCARD_COMMAND cmd, uint32_t arg) mmc_drv_obj.response = &mmc_drv_obj.r1_card_status; break; case HAL_MEMCARD_RESPONSE_R1b: - mmc_drv_obj.cmd_info.hw |= BIT10; /* bit10 = R1 busy bit */ + mmc_drv_obj.cmd_info.hw |= BIT10; /* bit10 = R1 busy bit */ mmc_drv_obj.response = &mmc_drv_obj.r1_card_status; break; case HAL_MEMCARD_RESPONSE_R2: -- cgit v1.2.3 From a86865ac42ac6f518da14474c94f38869c032488 Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Wed, 2 Dec 2020 16:24:32 +0000 Subject: PSCI: fix limit of 256 CPUs caused by cast to unsigned char In psci_setup.c psci_init_pwr_domain_node() takes an unsigned char as node_idx which limits it to initialising only the first 256 CPUs. As the calling function does not check for a limit of 256 I think this is a bug so change the unsigned char to uint16_t and change the cast from the calling site in populate_power_domain_tree(). Also update the non_cpu_pwr_domain_node structure lock_index to uint16_t and update the function signature for psci_lock_init() appropriately. Finally add a define PSCI_MAX_CPUS_INDEX to psci_private.h and add a CASSERT to psci_setup.c to make sure PLATFORM_CORE_COUNT cannot exceed the index value. Signed-off-by: Graeme Gregory Change-Id: I9e26842277db7483fd698b46bbac62aa86e71b45 --- lib/psci/psci_private.h | 9 +++++++-- lib/psci/psci_setup.c | 14 ++++++++++++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/lib/psci/psci_private.h b/lib/psci/psci_private.h index e2dcfa8b1..72bd6bd11 100644 --- a/lib/psci/psci_private.h +++ b/lib/psci/psci_private.h @@ -42,6 +42,11 @@ define_psci_cap(PSCI_SYSTEM_RESET2_AARCH64) | \ define_psci_cap(PSCI_MEM_CHK_RANGE_AARCH64)) +/* Internally PSCI uses a uint16_t for various cpu indexes so + * define a limit to number of CPUs that can be initialised. + */ +#define PSCI_MAX_CPUS_INDEX 0xFFFFU + /* * Helper functions to get/set the fields of PSCI per-cpu data. */ @@ -134,7 +139,7 @@ typedef struct non_cpu_pwr_domain_node { unsigned char level; /* For indexing the psci_lock array*/ - unsigned char lock_index; + uint16_t lock_index; } non_cpu_pd_node_t; typedef struct cpu_pwr_domain_node { @@ -239,7 +244,7 @@ static inline void psci_lock_release(non_cpu_pd_node_t *non_cpu_pd_node) #endif /* HW_ASSISTED_COHERENCY */ static inline void psci_lock_init(non_cpu_pd_node_t *non_cpu_pd_node, - unsigned char idx) + uint16_t idx) { non_cpu_pd_node[idx].lock_index = idx; } diff --git a/lib/psci/psci_setup.c b/lib/psci/psci_setup.c index d1ec99808..9c37d63f2 100644 --- a/lib/psci/psci_setup.c +++ b/lib/psci/psci_setup.c @@ -17,6 +17,12 @@ #include "psci_private.h" +/* + * Check that PLATFORM_CORE_COUNT fits into the number of cores + * that can be represented by PSCI_MAX_CPUS_INDEX. + */ +CASSERT(PLATFORM_CORE_COUNT <= (PSCI_MAX_CPUS_INDEX + 1U), assert_psci_cores_overflow); + /******************************************************************************* * Per cpu non-secure contexts used to program the architectural state prior * return to the normal world. @@ -34,11 +40,13 @@ unsigned int psci_caps; * Function which initializes the 'psci_non_cpu_pd_nodes' or the * 'psci_cpu_pd_nodes' corresponding to the power level. ******************************************************************************/ -static void __init psci_init_pwr_domain_node(unsigned char node_idx, +static void __init psci_init_pwr_domain_node(uint16_t node_idx, unsigned int parent_idx, unsigned char level) { if (level > PSCI_CPU_PWR_LVL) { + assert(node_idx < PSCI_NUM_NON_CPU_PWR_DOMAINS); + psci_non_cpu_pd_nodes[node_idx].level = level; psci_lock_init(psci_non_cpu_pd_nodes, node_idx); psci_non_cpu_pd_nodes[node_idx].parent_node = parent_idx; @@ -47,6 +55,8 @@ static void __init psci_init_pwr_domain_node(unsigned char node_idx, } else { psci_cpu_data_t *svc_cpu_data; + assert(node_idx < PLATFORM_CORE_COUNT); + psci_cpu_pd_nodes[node_idx].parent_node = parent_idx; /* Initialize with an invalid mpidr */ @@ -144,7 +154,7 @@ static unsigned int __init populate_power_domain_tree(const unsigned char for (j = node_index; j < (node_index + num_children); j++) - psci_init_pwr_domain_node((unsigned char)j, + psci_init_pwr_domain_node((uint16_t)j, parent_node_index - 1U, (unsigned char)level); -- cgit v1.2.3 From 74ac817a6100422d404e544334bebf5dea51ed9e Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Thu, 10 Dec 2020 14:41:10 -0600 Subject: maintainers: Update maintainers for TI port Andrew is no longer with TI unfortunately, so stepping up to provide maintainer for supported TI platforms. Signed-off-by: Nishanth Menon Change-Id: Ia1be294631421913bcbc3d346947195cb442d437 --- docs/about/maintainers.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst index f50093884..91a5621b9 100644 --- a/docs/about/maintainers.rst +++ b/docs/about/maintainers.rst @@ -516,8 +516,8 @@ Synquacer platform port Texas Instruments platform port ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -:M: Andrew F. Davis -:G: `glneo`_ +:M: Nishanth Menon +:G: `nmenon`_ :F: docs/plat/ti-k3.rst :F: plat/ti/ @@ -651,5 +651,6 @@ Build system .. _john-powell-arm: https://github.com/john-powell-arm .. _raghuncstate: https://github.com/raghuncstate .. _CJKay: https://github.com/cjkay +.. _nmenon: https://github.com/nmenon .. _Project Maintenance Process: https://developer.trustedfirmware.org/w/collaboration/project-maintenance-process/ -- cgit v1.2.3 From c3e23332b45577671ceb3a08b46de8f2cd4de82a Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Thu, 10 Dec 2020 16:49:42 -0600 Subject: ti: k3: common: Enable A53 erratum 1530924 The CatB erratum ARM_ERRATA_A53_1530924 applies to all TI A53 platforms as well. See the following for further information: https://developer.arm.com/documentation/epm048406/2100 Signed-off-by: Nishanth Menon Change-Id: Ic095424ce510139e060b38cfb84509d2cc573cad --- plat/ti/k3/common/plat_common.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/plat/ti/k3/common/plat_common.mk b/plat/ti/k3/common/plat_common.mk index c00262bcf..662c71dfa 100644 --- a/plat/ti/k3/common/plat_common.mk +++ b/plat/ti/k3/common/plat_common.mk @@ -21,6 +21,7 @@ ERRATA_A53_835769 := 1 ERRATA_A53_836870 := 1 ERRATA_A53_843419 := 1 ERRATA_A53_855873 := 1 +ERRATA_A53_1530924 := 1 # A72 Erratum for SoC ERRATA_A72_859971 := 1 -- cgit v1.2.3 From 60fba7c8e8152013a06162cd11c1257b38d049bf Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Thu, 10 Dec 2020 16:57:35 -0600 Subject: ti: k3: common: Enable A72 erratum 1319367 The CatB erratum ARM_ERRATA_A72_1319367 applies to all TI A72 platforms as well. See the following for further information: https://developer.arm.com/documentation/epm012079/11/ Signed-off-by: Nishanth Menon Change-Id: I80c6262b9cdadcb12f6dfd5a21272989ba257719 --- plat/ti/k3/common/plat_common.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/plat/ti/k3/common/plat_common.mk b/plat/ti/k3/common/plat_common.mk index 662c71dfa..05c004993 100644 --- a/plat/ti/k3/common/plat_common.mk +++ b/plat/ti/k3/common/plat_common.mk @@ -25,6 +25,7 @@ ERRATA_A53_1530924 := 1 # A72 Erratum for SoC ERRATA_A72_859971 := 1 +ERRATA_A72_1319367 := 1 CRASH_REPORTING := 1 HANDLE_EA_EL3_FIRST := 1 -- cgit v1.2.3 From 6a22d9ea3c7fa28d053d3ba264b49b7396a86f9e Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Thu, 10 Dec 2020 20:51:51 -0600 Subject: ti: k3: common: Make plat_get_syscnt_freq2 check CNT_FID0 GTC reg ARM's generic timer[1] picks up it's graycode from GTC. However, the frequency of the GTC is supposed to be programmed in CNTFID0[2] register. In K3, architecture, GTC provides a central time to many parts of the SoC including graycode to the generic timer in the ARMv8 subsystem. However, due to the central nature and the need to enable the counter early in the boot process, the R5 based bootloader enables GTC and programs it's frequency based on central needs of the system. This may not be a constant 200MHz based on the system. The bootloader is supposed to program the FID0 register with the correct frequency it has sourced for GTC from the central system controller, and TF-A is supposed to use that as the frequency for it's local timer. A mismatch in programmed frequency and what we program for generic timer will, as we can imagine, all kind of weird mayhem. So, check the CNTFID0 register, if it is 0, warn and use the default frequency to continue the boot process. While at it, we can also check CNTCR register to provide some basic diagnostics to make sure that we don't have OS folks scratch their heads. Even though this is used during cpu online operations, the cost of this additional check is minimal enough for us not to use #ifdeffery with DEBUG flags. [1] https://developer.arm.com/documentation/100095/0002/generic-timer/generic-timer-register-summary/aarch64-generic-timer-register-summary [2] https://developer.arm.com/docs/ddi0595/h/external-system-registers/cntfid0 [3] https://developer.arm.com/docs/ddi0595/h/external-system-registers/cntcr Signed-off-by: Nishanth Menon Change-Id: Ib03e06788580f3540dcb1a11677d0d6d398b2c9f --- plat/ti/k3/common/k3_bl31_setup.c | 34 ++++++++++++++++++++++++++++++++++ plat/ti/k3/include/platform_def.h | 9 +++++++++ 2 files changed, 43 insertions(+) diff --git a/plat/ti/k3/common/k3_bl31_setup.c b/plat/ti/k3/common/k3_bl31_setup.c index 8bd736292..ac4e60e4d 100644 --- a/plat/ti/k3/common/k3_bl31_setup.c +++ b/plat/ti/k3/common/k3_bl31_setup.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -23,6 +24,7 @@ const mmap_region_t plat_k3_mmap[] = { MAP_REGION_FLAT(K3_USART_BASE, K3_USART_SIZE, MT_DEVICE | MT_RW | MT_SECURE), MAP_REGION_FLAT(K3_GIC_BASE, K3_GIC_SIZE, MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(K3_GTC_BASE, K3_GTC_SIZE, MT_DEVICE | MT_RW | MT_SECURE), MAP_REGION_FLAT(SEC_PROXY_RT_BASE, SEC_PROXY_RT_SIZE, MT_DEVICE | MT_RW | MT_SECURE), MAP_REGION_FLAT(SEC_PROXY_SCFG_BASE, SEC_PROXY_SCFG_SIZE, MT_DEVICE | MT_RW | MT_SECURE), MAP_REGION_FLAT(SEC_PROXY_DATA_BASE, SEC_PROXY_DATA_SIZE, MT_DEVICE | MT_RW | MT_SECURE), @@ -127,6 +129,38 @@ void platform_mem_init(void) unsigned int plat_get_syscnt_freq2(void) { + uint32_t gtc_freq; + uint32_t gtc_ctrl; + + /* Lets try and provide basic diagnostics - cost is low */ + gtc_ctrl = mmio_read_32(K3_GTC_BASE + K3_GTC_CNTCR_OFFSET); + /* Did the bootloader fail to enable timer and OS guys are confused? */ + if ((gtc_ctrl & K3_GTC_CNTCR_EN_MASK) == 0U) { + ERROR("GTC is disabled! Timekeeping broken. Fix Bootloader\n"); + } + /* + * If debug will not pause time, we will have issues like + * drivers timing out while debugging, in cases of OS like Linux, + * RCU stall errors, which can be hard to differentiate vs real issues. + */ + if ((gtc_ctrl & K3_GTC_CNTCR_HDBG_MASK) == 0U) { + WARN("GTC: Debug access doesn't stop time. Fix Bootloader\n"); + } + + gtc_freq = mmio_read_32(K3_GTC_BASE + K3_GTC_CNTFID0_OFFSET); + /* Many older bootloaders may have missed programming FID0 register */ + if (gtc_freq != 0U) { + return gtc_freq; + } + + /* + * We could have just warned about this, but this can have serious + * hard to debug side effects if we are NOT sure what the actual + * frequency is. Lets make sure people don't miss this. + */ + ERROR("GTC_CNTFID0 is 0! Assuming %d Hz. Fix Bootloader\n", + SYS_COUNTER_FREQ_IN_TICKS); + return SYS_COUNTER_FREQ_IN_TICKS; } diff --git a/plat/ti/k3/include/platform_def.h b/plat/ti/k3/include/platform_def.h index 98db626e2..a56dd3d74 100644 --- a/plat/ti/k3/include/platform_def.h +++ b/plat/ti/k3/include/platform_def.h @@ -150,6 +150,15 @@ INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, grp, \ GIC_INTR_CFG_EDGE) + +#define K3_GTC_BASE 0x00A90000 +/* We just need 20 byte offset, but simpler to just remap the 64K page in */ +#define K3_GTC_SIZE 0x10000 +#define K3_GTC_CNTCR_OFFSET 0x00 +#define K3_GTC_CNTCR_EN_MASK 0x01 +#define K3_GTC_CNTCR_HDBG_MASK 0x02 +#define K3_GTC_CNTFID0_OFFSET 0x20 + #define K3_GIC_BASE 0x01800000 #define K3_GIC_SIZE 0x200000 -- cgit v1.2.3 From f577388a3292c60d6b4483c7cda267375de77f52 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Thu, 10 Dec 2020 17:37:04 -0600 Subject: ti: k3: common: sec_proxy: Fill non-message data fields with 0x0 Sec proxy data buffer is 60 bytes with the last of the registers indicating transmission completion. This however poses a bit of a challenge. The backing memory for sec_proxy is regular memory, and all sec proxy does is to trigger a burst of all 60 bytes of data over to the target thread backing ring accelerator. It doesn't do a memory scrub when it moves data out in the burst. When we transmit multiple messages, remnants of previous message is also transmitted which results in some random data being set in TISCI fields of messages that have been expanded forward. The entire concept of backward compatibility hinges on the fact that the unused message fields remain 0x0 allowing for 0x0 value to be specially considered when backward compatibility of message extension is done. So, instead of just writing the completion register, we continue to fill the message buffer up with 0x0 (note: for partial message involving completion, we already do this). This allows us to scale and introduce ABI changes back into TF-A only as needed. Signed-off-by: Nishanth Menon Change-Id: Ie22cb2a319f4aa80aef23ffc7e059207e5d4c640 --- plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c b/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c index ee1eecf78..cbe5fdab9 100644 --- a/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c +++ b/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c @@ -261,9 +261,14 @@ int k3_sec_proxy_send(enum k3_sec_proxy_chan_id id, const struct k3_sec_proxy_ms /* * 'data_reg' indicates next register to write. If we did not already * write on tx complete reg(last reg), we must do so for transmit + * In addition, we also need to make sure all intermediate data + * registers(if any required), are reset to 0 for TISCI backward + * compatibility to be maintained. */ - if (data_reg <= spm.desc.data_end_offset) - mmio_write_32(spt->data + spm.desc.data_end_offset, 0); + while (data_reg <= spm.desc.data_end_offset) { + mmio_write_32(spt->data + data_reg, 0); + data_reg += sizeof(uint32_t); + } VERBOSE("Message successfully sent on thread %s\n", spt->name); -- cgit v1.2.3 From 22b7a2298602cd05964d6c9739fe43c6a855467a Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Sat, 24 Oct 2020 01:28:54 +0000 Subject: ti: k3: drivers: ti_sci: Update ti_sci_msg_req_reboot to include domain The ti_sci_msg_req_reboot message payload has been extended to include a domain field, and this should be zero to reset the entire SoC with System Firmwares newer than v2020.04. Add the domain field to the ti_sci_msg_req_reboot message structure for completeness. Set it up to zero to fix the reboot issues with newer firmwares. This takes care of the specific ABI that changed and has an impact on ATF function. Signed-off-by: Suman Anna Signed-off-by: Dave Gerlach Signed-off-by: Nishanth Menon Change-Id: I4f8064b9d6555687822dc2b2b8ec97609286fa0b --- plat/ti/k3/common/drivers/ti_sci/ti_sci.c | 1 + plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h | 3 +++ 2 files changed, 4 insertions(+) diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c index e390efee6..2c3313c43 100644 --- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c +++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c @@ -1163,6 +1163,7 @@ int ti_sci_core_reboot(void) ERROR("Message alloc failed (%d)\n", ret); return ret; } + req.domain = TI_SCI_DOMAIN_FULL_SOC_RESET; ret = ti_sci_do_xfer(&xfer); if (ret) { diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h b/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h index 2d23f9a9c..310bf459d 100644 --- a/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h +++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h @@ -95,12 +95,15 @@ struct ti_sci_msg_resp_version { /** * struct ti_sci_msg_req_reboot - Reboot the SoC * @hdr: Generic Header + * @domain: Domain to be reset, 0 for full SoC reboot * * Request type is TI_SCI_MSG_SYS_RESET, responded with a generic * ACK/NACK message. */ struct ti_sci_msg_req_reboot { struct ti_sci_msg_hdr hdr; +#define TI_SCI_DOMAIN_FULL_SOC_RESET 0x0 + uint8_t domain; } __packed; /** -- cgit v1.2.3 From ff7b75e213e4fe575d5f58f30fe3a1a63fe8ce0b Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Thu, 10 Dec 2020 22:17:58 -0600 Subject: ti: k3: Move USE_COHERENT_MEM only for the generic board commit 65f7b81728d0 ("ti: k3: common: Use coherent memory for shared data") introduced WARMBOOT_ENABLE_DCACHE_EARLY and USE_COHERENT_MEM to handle multiple clusters across L3 cache systems. This is represented by "generic" board in k3 platform. On "lite" platforms, however, system level coherency is lacking since we don't have a global monitor or an L3 cache controller. Though, at a cluster level, ARM CPU level coherency is very much possible since the max number of clusters permitted in lite platform configuration is "1". However, we need to be able to disable USE_COHERENT_MEM for the lite configuration due to the lack of system level coherency. See docs/getting_started/build-options.rst for further information. Signed-off-by: Nishanth Menon Change-Id: I4a0ec150b3f9ea12369254aef834a6cbe82d6be6 --- plat/ti/k3/board/generic/board.mk | 3 +++ plat/ti/k3/common/plat_common.mk | 3 +-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/plat/ti/k3/board/generic/board.mk b/plat/ti/k3/board/generic/board.mk index a34221454..c5bd1ec3c 100644 --- a/plat/ti/k3/board/generic/board.mk +++ b/plat/ti/k3/board/generic/board.mk @@ -13,5 +13,8 @@ $(eval $(call add_define,PRELOADED_BL33_BASE)) K3_HW_CONFIG_BASE ?= 0x82000000 $(eval $(call add_define,K3_HW_CONFIG_BASE)) +# System coherency is managed in hardware +USE_COHERENT_MEM := 1 + PLAT_INCLUDES += \ -Iplat/ti/k3/board/generic/include \ diff --git a/plat/ti/k3/common/plat_common.mk b/plat/ti/k3/common/plat_common.mk index 05c004993..ab7366b7e 100644 --- a/plat/ti/k3/common/plat_common.mk +++ b/plat/ti/k3/common/plat_common.mk @@ -11,9 +11,8 @@ COLD_BOOT_SINGLE_CPU := 1 # We can choose where a core starts executing PROGRAMMABLE_RESET_ADDRESS:= 1 -# System coherency is managed in hardware +# ARM coherency is managed in hardware WARMBOOT_ENABLE_DCACHE_EARLY := 1 -USE_COHERENT_MEM := 1 # A53 erratum for SoC. (enable them all) ERRATA_A53_826319 := 1 -- cgit v1.2.3 From 7f323eb2df2d449cc3a425aab78583bcabaa5984 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Thu, 10 Dec 2020 18:39:41 -0600 Subject: ti: k3: common: sec_proxy: Introduce sec_proxy_lite definition There are two communication scheme that have been enabled to communicate with Secure Proxy in TI. a) A full fledged prioritized communication scheme, which involves upto 5 threads from the perspective of the host software b) A much simpler "lite" version which is just a two thread scheme involving just a transmit and receive thread scheme. The (a) system is specifically useful when the SoC is massive involving multiple processor systems and where the potential for priority inversion is clearly a system usecase killer. However, this comes with the baggage of significant die area for larger number of instances of secure proxy, ring accelerator and backing memories for queued messages. Example SoCs using this scheme would be: AM654[1], J721E[2], J7200[3] etc. The (b) scheme(aka the lite scheme) is introduced on smaller SoCs where memory and area concerns are paramount. The tradeoff of priority loss is acceptable given the reduced number of processors communicating with the central system controller. This brings about a very significant area and memory usage savings while the loss of communication priority has no demonstrable impact. Example SoC using this scheme would be: AM642[4] While we can detect using JTAG ID and conceptually handle things dynamically, adding such a scheme involves a lot of unused data (cost of ATF memory footprint), pointer lookups (performance cost) and still due to follow on patches, does'nt negate the need for a different build configuration. However, (a) and (b) family of SoCs share the same scheme and addresses etc, this helps minimize our churn quite a bit Instead of introducing a complex data structure lookup scheme, lets keep things simple by first introducing the pieces necessary for an alternate communication scheme, then introduce a second platform representing the "lite" family of K3 processors. NOTE: This is only possible since ATF uses just two (secure) threads for actual communication with the central system controller. This is sufficient for the function that ATF uses. The (a) scheme and the (b) scheme also varies w.r.t the base addresses used, even though the memory window assigned for them have remained consistent. We introduce the delta as part of this change as well. This is expected to remain consistent as a standard in TI SoCs. References: [1] See AM65x Technical Reference Manual (SPRUID7, April 2018) for further details: https://www.ti.com/lit/pdf/spruid7 [2] See J721E Technical Reference Manual (SPRUIL1, May 2019) for further details: https://www.ti.com/lit/pdf/spruil1 [3] See J7200 Technical Reference Manual (SPRUIU1, June 2020) for further details: https://www.ti.com/lit/pdf/spruiu1 [4] See AM64X Technical Reference Manual (SPRUIM2, Nov 2020) for further details: https://www.ti.com/lit/pdf/spruim2 Signed-off-by: Nishanth Menon Change-Id: I697711ee0e6601965015ddf950fdfdec8e759bfc --- plat/ti/k3/board/generic/board.mk | 4 ++++ plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c | 5 +++++ plat/ti/k3/common/drivers/sec_proxy/sec_proxy.h | 15 +++++++++++++++ plat/ti/k3/include/platform_def.h | 9 +++++++++ 4 files changed, 33 insertions(+) diff --git a/plat/ti/k3/board/generic/board.mk b/plat/ti/k3/board/generic/board.mk index c5bd1ec3c..ef74cd64c 100644 --- a/plat/ti/k3/board/generic/board.mk +++ b/plat/ti/k3/board/generic/board.mk @@ -13,6 +13,10 @@ $(eval $(call add_define,PRELOADED_BL33_BASE)) K3_HW_CONFIG_BASE ?= 0x82000000 $(eval $(call add_define,K3_HW_CONFIG_BASE)) +# Define sec_proxy usage as the full prioritized communication scheme +K3_SEC_PROXY_LITE := 0 +$(eval $(call add_define,K3_SEC_PROXY_LITE)) + # System coherency is managed in hardware USE_COHERENT_MEM := 1 diff --git a/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c b/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c index cbe5fdab9..a0bfdee36 100644 --- a/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c +++ b/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c @@ -97,11 +97,16 @@ static struct k3_sec_proxy_mbox spm = { .data_end_offset = 0x3C, }, .threads = { +#if !K3_SEC_PROXY_LITE SP_THREAD(SP_NOTIFY), SP_THREAD(SP_RESPONSE), SP_THREAD(SP_HIGH_PRIORITY), SP_THREAD(SP_LOW_PRIORITY), SP_THREAD(SP_NOTIFY_RESP), +#else + SP_THREAD(SP_RESPONSE), + SP_THREAD(SP_HIGH_PRIORITY), +#endif /* K3_SEC_PROXY_LITE */ }, }; diff --git a/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.h b/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.h index 6c4f5dfff..f4b0b4bac 100644 --- a/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.h +++ b/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.h @@ -16,13 +16,28 @@ * enum k3_sec_proxy_chan_id - Secure Proxy thread IDs * * These the available IDs used in k3_sec_proxy_{send,recv}() + * There are two schemes we use: + * * if K3_SEC_PROXY_LITE = 1, we just have two threads to talk + * * if K3_SEC_PROXY_LITE = 0, we have the full fledged + * communication scheme available. */ enum k3_sec_proxy_chan_id { +#if !K3_SEC_PROXY_LITE SP_NOTIFY = 0, SP_RESPONSE, SP_HIGH_PRIORITY, SP_LOW_PRIORITY, SP_NOTIFY_RESP, +#else + SP_RESPONSE = 8, + /* + * Note: TISCI documentation indicates "low priority", but in reality + * with a single thread, there is no low or high priority.. This usage + * is more appropriate for TF-A since we can reduce the churn as a + * result. + */ + SP_HIGH_PRIORITY, +#endif /* K3_SEC_PROXY_LITE */ }; /** diff --git a/plat/ti/k3/include/platform_def.h b/plat/ti/k3/include/platform_def.h index a56dd3d74..f12fb0b21 100644 --- a/plat/ti/k3/include/platform_def.h +++ b/plat/ti/k3/include/platform_def.h @@ -162,12 +162,21 @@ #define K3_GIC_BASE 0x01800000 #define K3_GIC_SIZE 0x200000 +#if !K3_SEC_PROXY_LITE #define SEC_PROXY_DATA_BASE 0x32C00000 #define SEC_PROXY_DATA_SIZE 0x80000 #define SEC_PROXY_SCFG_BASE 0x32800000 #define SEC_PROXY_SCFG_SIZE 0x80000 #define SEC_PROXY_RT_BASE 0x32400000 #define SEC_PROXY_RT_SIZE 0x80000 +#else +#define SEC_PROXY_DATA_BASE 0x4D000000 +#define SEC_PROXY_DATA_SIZE 0x80000 +#define SEC_PROXY_SCFG_BASE 0x4A400000 +#define SEC_PROXY_SCFG_SIZE 0x80000 +#define SEC_PROXY_RT_BASE 0x4A600000 +#define SEC_PROXY_RT_SIZE 0x80000 +#endif /* K3_SEC_PROXY_LITE */ #define SEC_PROXY_TIMEOUT_US 1000000 #define SEC_PROXY_MAX_MESSAGE_SIZE 56 -- cgit v1.2.3 From 84af89563e1b17def844d3672bc601ae51f0257f Mon Sep 17 00:00:00 2001 From: "Andrew F. Davis" Date: Wed, 9 Dec 2020 17:52:50 -0600 Subject: ti: k3: Introduce lite device board support Add device support for the 'lite' K3 devices. These will use modified device addresses and allow for fewer cores to save memory. Note: This family of devices are characterized by a single cluster of ARMv8 processor upto a max of 4 processors and lack of a level 3 cache. The first generation of this family is introduced with AM642. See AM64X Technical Reference Manual (SPRUIM2, Nov 2020) for further details: https://www.ti.com/lit/pdf/spruim2 Signed-off-by: Andrew F. Davis Signed-off-by: Nishanth Menon Change-Id: I8cd2c1c9a9434646d0c72fca3162dd5bc9bd692a --- plat/ti/k3/board/lite/board.mk | 24 ++++++++++++++++++++++ plat/ti/k3/board/lite/include/board_def.h | 34 +++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 plat/ti/k3/board/lite/board.mk create mode 100644 plat/ti/k3/board/lite/include/board_def.h diff --git a/plat/ti/k3/board/lite/board.mk b/plat/ti/k3/board/lite/board.mk new file mode 100644 index 000000000..76246be47 --- /dev/null +++ b/plat/ti/k3/board/lite/board.mk @@ -0,0 +1,24 @@ +# +# Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +BL32_BASE ?= 0x9e800000 +$(eval $(call add_define,BL32_BASE)) + +PRELOADED_BL33_BASE ?= 0x80080000 +$(eval $(call add_define,PRELOADED_BL33_BASE)) + +K3_HW_CONFIG_BASE ?= 0x82000000 +$(eval $(call add_define,K3_HW_CONFIG_BASE)) + +# Define sec_proxy usage as the lite version +K3_SEC_PROXY_LITE := 1 +$(eval $(call add_define,K3_SEC_PROXY_LITE)) + +# We dont have system level coherency capability +USE_COHERENT_MEM := 0 + +PLAT_INCLUDES += \ + -Iplat/ti/k3/board/lite/include \ diff --git a/plat/ti/k3/board/lite/include/board_def.h b/plat/ti/k3/board/lite/include/board_def.h new file mode 100644 index 000000000..7c7ea62c1 --- /dev/null +++ b/plat/ti/k3/board/lite/include/board_def.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef BOARD_DEF_H +#define BOARD_DEF_H + +#include + +/* The ports must be in order and contiguous */ +#define K3_CLUSTER0_CORE_COUNT U(4) +#define K3_CLUSTER1_CORE_COUNT U(0) +#define K3_CLUSTER2_CORE_COUNT U(0) +#define K3_CLUSTER3_CORE_COUNT U(0) + +/* + * This RAM will be used for the bootloader including code, bss, and stacks. + * It may need to be increased if BL31 grows in size. + * Current computation assumes data structures necessary for GIC and ARM for + * a single cluster of 4 processor. + */ +#define SEC_SRAM_BASE 0x70000000 /* Base of SRAM */ +#define SEC_SRAM_SIZE 0x0001a000 /* 104k */ + +#define PLAT_MAX_OFF_STATE U(2) +#define PLAT_MAX_RET_STATE U(1) + +#define PLAT_PROC_START_ID 32 +#define PLAT_PROC_DEVICE_START_ID 135 +#define PLAT_CLUSTER_DEVICE_START_ID 134 + +#endif /* BOARD_DEF_H */ -- cgit v1.2.3 From e63e4140e0970e3161b117b8884f7b5a030c68c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Wed, 23 Dec 2020 19:23:26 +0100 Subject: marvell: uart: a3720: Implement console_a3700_core_flush MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implementation is simple, just wait for the TX FIFO to be empty. Without this patch TF-A on A3720 truncate the last line: NOTICE: BL31: Built : 16:1 With this patch TF-A on A3720 print correctly also the last line: NOTICE: BL31: Built : 19:03:31, Dec 23 2020 Signed-off-by: Pali Rohár Change-Id: I2f2ea42beab66ba132afdb400ca7898c5419db09 --- drivers/marvell/uart/a3700_console.S | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/marvell/uart/a3700_console.S b/drivers/marvell/uart/a3700_console.S index d184a2d24..dc374eed1 100644 --- a/drivers/marvell/uart/a3700_console.S +++ b/drivers/marvell/uart/a3700_console.S @@ -232,6 +232,11 @@ endfunc console_a3700_getc * --------------------------------------------- */ func console_a3700_core_flush + /* Wait for the TX FIFO to be empty */ +1: ldr w1, [x0, #UART_STATUS_REG] + and w1, w1, #UARTLSR_TXFIFOEMPTY + cmp w1, #UARTLSR_TXFIFOEMPTY + b.ne 1b ret endfunc console_a3700_core_flush -- cgit v1.2.3 From 47f2445ad651e9e37c69daccfc9fba298525ca3f Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Tue, 29 Dec 2020 13:52:11 +0000 Subject: Plat AXG: Fix PLAT_MAX_PWR_LVL value This patch fixes AXG platform build error: plat/amlogic/axg/axg_pm.c: In function 'axg_pwr_domain_off': plat/amlogic/axg/axg_pm.c:124:43: error: array subscript 2 is above array bounds of 'const plat_local_state_t[2]' {aka 'const unsigned char[2]'} by changing PLAT_MAX_PWR_LVL from MPIDR_AFFLVL1 to MPIDR_AFFLVL2 in plat\amlogic\axg\include\platform_def.h. Change-Id: I9a701e8f26231e62f844920aec5830664f3fb324 Signed-off-by: Alexei Fedorov --- plat/amlogic/axg/include/platform_def.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plat/amlogic/axg/include/platform_def.h b/plat/amlogic/axg/include/platform_def.h index a47cf7348..c97687e36 100644 --- a/plat/amlogic/axg/include/platform_def.h +++ b/plat/amlogic/axg/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -24,7 +24,7 @@ #define AML_PRIMARY_CPU U(0) -#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL1 +#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL2 #define PLAT_NUM_PWR_DOMAINS (PLATFORM_CLUSTER_COUNT + \ PLATFORM_CORE_COUNT) -- cgit v1.2.3 From d716f045f280596f6b8aa3b4cc12615af821d1e3 Mon Sep 17 00:00:00 2001 From: Kalyani Akula Date: Sun, 22 Nov 2020 22:42:10 -0800 Subject: zynqmp : pm : Adds new zynqmp-pm api SMC call for register access This patch adds new zynqmp-pm api to provide read/write access to CSU or PMU global registers. Signed-off-by: Kalyani Akula Signed-off-by: Rajan Vaja Change-Id: I4fd52eb732fc3e6a8bccd96cad7dc090b2161042 --- plat/xilinx/zynqmp/include/zynqmp_def.h | 6 ++++ plat/xilinx/zynqmp/pm_service/pm_api_sys.c | 45 +++++++++++++++++++++++++++++ plat/xilinx/zynqmp/pm_service/pm_api_sys.h | 10 +++++++ plat/xilinx/zynqmp/pm_service/pm_defs.h | 4 ++- plat/xilinx/zynqmp/pm_service/pm_svc_main.c | 9 ++++++ 5 files changed, 73 insertions(+), 1 deletion(-) diff --git a/plat/xilinx/zynqmp/include/zynqmp_def.h b/plat/xilinx/zynqmp/include/zynqmp_def.h index 461439530..b492210b0 100644 --- a/plat/xilinx/zynqmp/include/zynqmp_def.h +++ b/plat/xilinx/zynqmp/include/zynqmp_def.h @@ -350,4 +350,10 @@ #define AFIFM6_WRCTRL U(13) #define FABRIC_WIDTH U(3) +/* CSUDMA Module Base Address*/ +#define CSUDMA_BASE 0xFFC80000 + +/* RSA-CORE Module Base Address*/ +#define RSA_CORE_BASE 0xFFCE0000 + #endif /* ZYNQMP_DEF_H */ diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c index 1ec06f9d0..9a1f1b486 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c +++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c @@ -1546,3 +1546,48 @@ enum pm_ret_status pm_pll_get_mode(enum pm_node_id nid, enum pm_pll_mode *mode) PM_PACK_PAYLOAD2(payload, PM_PLL_GET_MODE, nid); return pm_ipi_send_sync(primary_proc, payload, mode, 1); } + +/** + * pm_register_access() - PM API for register read/write access data + * + * @register_access_id Register_access_id which says register read/write + * + * @address Address of the register to be accessed + * + * @mask Mask value to be used while writing value + * + * @value Value to be written to register + * + * @out Returned output data + * + * This function returns requested data. + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_register_access(unsigned int register_access_id, + unsigned int address, + unsigned int mask, + unsigned int value, + unsigned int *out) +{ + enum pm_ret_status ret; + + if (((ZYNQMP_CSU_BASEADDR & address) != ZYNQMP_CSU_BASEADDR) && + ((CSUDMA_BASE & address) != CSUDMA_BASE) && + ((RSA_CORE_BASE & address) != RSA_CORE_BASE) && + ((PMU_GLOBAL_BASE & address) != PMU_GLOBAL_BASE)) + return PM_RET_ERROR_ACCESS; + + switch (register_access_id) { + case CONFIG_REG_WRITE: + ret = pm_mmio_write(address, mask, value); + break; + case CONFIG_REG_READ: + ret = pm_mmio_read(address, out); + break; + default: + ret = PM_RET_ERROR_ARGS; + WARN("Unimplemented register_access call\n\r"); + } + return ret; +} diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h index 930e4702f..60fc303fe 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h +++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h @@ -28,6 +28,11 @@ enum pm_query_id { PM_QID_CLOCK_GET_MAX_DIVISOR, }; +enum pm_register_access_id { + CONFIG_REG_WRITE, + CONFIG_REG_READ, +}; + /********************************************************** * System-level API function declarations **********************************************************/ @@ -175,6 +180,11 @@ enum pm_ret_status pm_fpga_read(uint32_t reg_numframes, enum pm_ret_status pm_aes_engine(uint32_t address_high, uint32_t address_low, uint32_t *value); +enum pm_ret_status pm_register_access(unsigned int register_access_id, + unsigned int address, + unsigned int mask, + unsigned int value, + unsigned int *out); enum pm_ret_status pm_pll_set_parameter(enum pm_node_id nid, enum pm_pll_param param_id, diff --git a/plat/xilinx/zynqmp/pm_service/pm_defs.h b/plat/xilinx/zynqmp/pm_service/pm_defs.h index 4776d424b..8b28807b7 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_defs.h +++ b/plat/xilinx/zynqmp/pm_service/pm_defs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -97,6 +97,8 @@ enum pm_api_id { PM_PLL_GET_PARAMETER, PM_PLL_SET_MODE, PM_PLL_GET_MODE, + /* PM Register Access API */ + PM_REGISTER_ACCESS, PM_API_MAX }; diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c index 14321ec77..bf608dbd3 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c +++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c @@ -606,6 +606,15 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, SMC_RET1(handle, (uint64_t)ret | ((uint64_t)mode << 32)); } + case PM_REGISTER_ACCESS: + { + uint32_t value; + + ret = pm_register_access(pm_arg[0], pm_arg[1], pm_arg[2], + pm_arg[3], &value); + SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32); + } + default: WARN("Unimplemented PM Service Call: 0x%x\n", smc_fid); SMC_RET1(handle, SMC_UNK); -- cgit v1.2.3 From 1f91019457b7c2e0f7e9445935985f3d376ad844 Mon Sep 17 00:00:00 2001 From: VNSL Durga Date: Mon, 23 Nov 2020 04:46:04 -0800 Subject: zynqmp:pm: Adds new zynqmp-pm api SMC call for efuse This patch adds new api to access zynqmp efuse memory Signed-off-by: VNSL Durga Signed-off-by: Rajan Vaja Change-Id: I0971ab6549552a6f96412431388d19b822db00ab --- plat/xilinx/zynqmp/pm_service/pm_api_sys.c | 26 ++++++++++++++++++++++++++ plat/xilinx/zynqmp/pm_service/pm_api_sys.h | 2 ++ plat/xilinx/zynqmp/pm_service/pm_defs.h | 1 + plat/xilinx/zynqmp/pm_service/pm_svc_main.c | 8 ++++++++ 4 files changed, 37 insertions(+) diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c index 9a1f1b486..342714935 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c +++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c @@ -1591,3 +1591,29 @@ enum pm_ret_status pm_register_access(unsigned int register_access_id, } return ret; } + +/** + * pm_efuse_access() - To program or read efuse bits. + * + * This function provides access to the xilskey library to program/read + * efuse bits. + * + * address_low: lower 32-bit Linear memory space address + * address_high: higher 32-bit Linear memory space address + * + * value: Returned output value + * + * @return Returns status, either success or error+reason + * + */ +enum pm_ret_status pm_efuse_access(uint32_t address_high, + uint32_t address_low, + uint32_t *value) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMU */ + PM_PACK_PAYLOAD3(payload, PM_EFUSE_ACCESS, address_high, address_low); + + return pm_ipi_send_sync(primary_proc, payload, value, 1); +} diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h index 60fc303fe..b3ebb2752 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h +++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h @@ -196,5 +196,7 @@ enum pm_ret_status pm_pll_get_parameter(enum pm_node_id nid, enum pm_ret_status pm_pll_set_mode(enum pm_node_id nid, enum pm_pll_mode mode); enum pm_ret_status pm_pll_get_mode(enum pm_node_id nid, enum pm_pll_mode *mode); +enum pm_ret_status pm_efuse_access(uint32_t address_high, + uint32_t address_low, uint32_t *value); #endif /* PM_API_SYS_H */ diff --git a/plat/xilinx/zynqmp/pm_service/pm_defs.h b/plat/xilinx/zynqmp/pm_service/pm_defs.h index 8b28807b7..da8789301 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_defs.h +++ b/plat/xilinx/zynqmp/pm_service/pm_defs.h @@ -99,6 +99,7 @@ enum pm_api_id { PM_PLL_GET_MODE, /* PM Register Access API */ PM_REGISTER_ACCESS, + PM_EFUSE_ACCESS, PM_API_MAX }; diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c index bf608dbd3..5b3e73724 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c +++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c @@ -615,6 +615,14 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32); } + case PM_EFUSE_ACCESS: + { + uint32_t value; + + ret = pm_efuse_access(pm_arg[0], pm_arg[1], &value); + SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32); + } + default: WARN("Unimplemented PM Service Call: 0x%x\n", smc_fid); SMC_RET1(handle, SMC_UNK); -- cgit v1.2.3 From 504925f99da0d9c63646b1eb3c1ad9a861c20968 Mon Sep 17 00:00:00 2001 From: Venkatesh Yadav Abbarapu Date: Mon, 23 Nov 2020 04:26:54 -0800 Subject: xilinx: zynqmp: Add support for Error Management Adding the EM specific smc handler for the EM-related requests. Signed-off-by: Venkatesh Yadav Abbarapu Signed-off-by: Rajan Vaja Change-Id: I98122d49604a01a2f6bd1e509a5896ee68069dd0 --- plat/xilinx/zynqmp/pm_service/pm_api_sys.c | 31 +++++++++++++++++ plat/xilinx/zynqmp/pm_service/pm_api_sys.h | 3 ++ plat/xilinx/zynqmp/pm_service/pm_defs.h | 10 ++++++ plat/xilinx/zynqmp/pm_service/pm_svc_main.c | 53 +++++++++++++++++++++++++++++ plat/xilinx/zynqmp/pm_service/pm_svc_main.h | 5 ++- plat/xilinx/zynqmp/sip_svc_setup.c | 11 ++++-- 6 files changed, 110 insertions(+), 3 deletions(-) diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c index 342714935..9a53408fd 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c +++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c @@ -65,6 +65,10 @@ unsigned int pm_get_shutdown_scope(void) PM_PACK_PAYLOAD5(pl, arg0, arg1, arg2, arg3, arg4); \ } +#define EM_PACK_PAYLOAD1(pl, arg0) { \ + pl[0] = (uint16_t)(0xE) << 16 | (uint16_t)arg0; \ +} + /** * pm_self_suspend() - PM call for processor to suspend itself * @nid Node id of the processor or subsystem @@ -1617,3 +1621,30 @@ enum pm_ret_status pm_efuse_access(uint32_t address_high, return pm_ipi_send_sync(primary_proc, payload, value, 1); } + +enum pm_ret_status em_set_action(unsigned int *value) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMU */ + EM_PACK_PAYLOAD1(payload, EM_SET_ACTION); + return pm_ipi_send_sync(primary_proc, payload, value, 1); +} + +enum pm_ret_status em_remove_action(unsigned int *value) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMU */ + EM_PACK_PAYLOAD1(payload, EM_REMOVE_ACTION); + return pm_ipi_send_sync(primary_proc, payload, value, 1); +} + +enum pm_ret_status em_send_errors(unsigned int *value) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMU */ + EM_PACK_PAYLOAD1(payload, EM_SEND_ERRORS); + return pm_ipi_send_sync(primary_proc, payload, value, 1); +} diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h index b3ebb2752..b0c26529d 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h +++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h @@ -198,5 +198,8 @@ enum pm_ret_status pm_pll_set_mode(enum pm_node_id nid, enum pm_pll_mode mode); enum pm_ret_status pm_pll_get_mode(enum pm_node_id nid, enum pm_pll_mode *mode); enum pm_ret_status pm_efuse_access(uint32_t address_high, uint32_t address_low, uint32_t *value); +enum pm_ret_status em_set_action(unsigned int *value); +enum pm_ret_status em_remove_action(unsigned int *value); +enum pm_ret_status em_send_errors(unsigned int *value); #endif /* PM_API_SYS_H */ diff --git a/plat/xilinx/zynqmp/pm_service/pm_defs.h b/plat/xilinx/zynqmp/pm_service/pm_defs.h index da8789301..ee31c9267 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_defs.h +++ b/plat/xilinx/zynqmp/pm_service/pm_defs.h @@ -33,6 +33,7 @@ #define PM_STATE_CPU_IDLE 0x0U #define PM_STATE_SUSPEND_TO_RAM 0xFU +#define EM_FUNID_NUM_MASK 0xF0000U /********************************************************************* * Enum definitions ********************************************************************/ @@ -323,4 +324,13 @@ enum pm_clock_div_id { PM_CLOCK_DIV1_ID, }; +/** + * EM API IDs + */ +enum em_api_id { + EM_SET_ACTION = 1, + EM_REMOVE_ACTION, + EM_SEND_ERRORS, +}; + #endif /* PM_DEFS_H */ diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c index 5b3e73724..a4bc1ac08 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c +++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c @@ -628,3 +628,56 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, SMC_RET1(handle, SMC_UNK); } } + +/** + * em_smc_handler() - SMC handler for EM-API calls coming from EL1/EL2. + * @smc_fid - Function Identifier + * @x1 - x4 - Arguments + * @cookie - Unused + * @handler - Pointer to caller's context structure + * + * @return - Unused + * + * Determines that smc_fid is valid and supported EM SMC Function ID from the + * list of em_api_ids, otherwise completes the request with + * the unknown SMC Function ID + * + * The SMC calls for EM service are forwarded from SIP Service SMC handler + * function with rt_svc_handle signature + */ +uint64_t em_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, + uint64_t x4, void *cookie, void *handle, uint64_t flags) +{ + enum pm_ret_status ret; + + switch (smc_fid & FUNCID_NUM_MASK) { + /* EM API Functions */ + case EM_SET_ACTION: + { + uint32_t value; + + ret = em_set_action(&value); + SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32); + } + + case EM_REMOVE_ACTION: + { + uint32_t value; + + ret = em_remove_action(&value); + SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32); + } + + case EM_SEND_ERRORS: + { + uint32_t value; + + ret = em_send_errors(&value); + SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32); + } + + default: + WARN("Unimplemented EM Service Call: 0x%x\n", smc_fid); + SMC_RET1(handle, SMC_UNK); + } +} diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.h b/plat/xilinx/zynqmp/pm_service/pm_svc_main.h index 0968f64cb..abadd4065 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.h +++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -14,4 +14,7 @@ uint64_t pm_smc_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 em_smc_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 /* PM_SVC_MAIN_H */ diff --git a/plat/xilinx/zynqmp/sip_svc_setup.c b/plat/xilinx/zynqmp/sip_svc_setup.c index 9b182749c..4c29da231 100644 --- a/plat/xilinx/zynqmp/sip_svc_setup.c +++ b/plat/xilinx/zynqmp/sip_svc_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -25,6 +25,9 @@ #define PM_FID_MASK 0xf000u #define PM_FID_VALUE 0u #define IPI_FID_VALUE 0x1000u +#define EM_FID_MASK 0xf0000u +#define EM_FID_VALUE 0xE0000u +#define is_em_fid(_fid) (((_fid) & EM_FID_MASK) == EM_FID_VALUE) #define is_pm_fid(_fid) (((_fid) & PM_FID_MASK) == PM_FID_VALUE) #define is_ipi_fid(_fid) (((_fid) & PM_FID_MASK) == IPI_FID_VALUE) @@ -61,8 +64,12 @@ uintptr_t sip_svc_smc_handler(uint32_t smc_fid, void *handle, u_register_t flags) { + /* Let EM SMC handler deal with EM-related requests */ + if (is_em_fid(smc_fid)) { + return em_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, + flags); + } else if (is_pm_fid(smc_fid)) { /* Let PM SMC handler deal with PM-related requests */ - if (is_pm_fid(smc_fid)) { return pm_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags); } -- cgit v1.2.3 From d9243f264b91b45d82376081afc3c2b45c0e540f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= Date: Tue, 5 Jan 2021 14:01:05 +0100 Subject: plat: marvell: armada: a3k: support doing system reset via CM3 secure coprocessor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce a new build option CM3_SYSTEM_RESET for A3700 platform, which, when enabled, adds code to the PSCI reset handler to try to do system reset by the WTMI firmware running on the Cortex-M3 secure coprocessor. (This function is exposed via the mailbox interface.) The reason is that the Turris MOX board has a HW bug which causes reset to hang unpredictably. This issue can be solved by putting the board in a specific state before reset. Signed-off-by: Marek Behún Change-Id: I3f60b9f244f334adcd33d6db6a361fbc8b8d209f --- docs/plat/marvell/armada/build.rst | 17 +++++- plat/marvell/armada/a3k/common/a3700_common.mk | 6 ++- plat/marvell/armada/a3k/common/cm3_system_reset.c | 62 ++++++++++++++++++++++ .../armada/a3k/common/include/a3700_plat_def.h | 8 ++- plat/marvell/armada/a3k/common/include/a3700_pm.h | 4 +- plat/marvell/armada/a3k/common/plat_pm.c | 10 +++- 6 files changed, 102 insertions(+), 5 deletions(-) create mode 100644 plat/marvell/armada/a3k/common/cm3_system_reset.c diff --git a/docs/plat/marvell/armada/build.rst b/docs/plat/marvell/armada/build.rst index 54182cb08..2c2bd680c 100644 --- a/docs/plat/marvell/armada/build.rst +++ b/docs/plat/marvell/armada/build.rst @@ -86,6 +86,20 @@ There are several build options: There is no reason to enable this feature if OP-TEE OS built with CFG_WITH_PAGER=n. Only set LLC_SRAM=1 if OP-TEE OS is built with CFG_WITH_PAGER=y. +- CM3_SYSTEM_RESET + + For Armada37x0 only, when ``CM3_SYSTEM_RESET=1``, the Cortex-M3 secure coprocessor will + be used for system reset. + TF-A will send command 0x0009 with a magic value via the rWTM mailbox interface to the + Cortex-M3 secure coprocessor. + The firmware running in the coprocessor must either implement this functionality or + ignore the 0x0009 command (which is true for the firmware from A3700-utils-marvell + repository). If this option is enabled but the firmware does not support this command, + an error message will be printed prior trying to reboot via the usual way. + + This option is needed on Turris MOX as a workaround to a HW bug which causes reset to + sometime hang the board. + - MARVELL_SECURE_BOOT Build trusted(=1)/non trusted(=0) image, default is non trusted. @@ -209,7 +223,8 @@ To build just TF-A without WTMI image (useful for A3720 Turris MOX board), run f .. code:: shell - > make USE_COHERENT_MEM=0 PLAT=a3700 BL33=/path/to/u-boot.bin CROSS_COMPILE=aarch64-linux-gnu- mrvl_bootimage + > make USE_COHERENT_MEM=0 PLAT=a3700 CM3_SYSTEM_RESET=1 BL33=/path/to/u-boot.bin \ + CROSS_COMPILE=aarch64-linux-gnu- mrvl_bootimage Supported MARVELL_PLATFORM are: - a3700 (for both A3720 DB and EspressoBin) diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk index e2022fac7..712b16202 100644 --- a/plat/marvell/armada/a3k/common/a3700_common.mk +++ b/plat/marvell/armada/a3k/common/a3700_common.mk @@ -1,5 +1,5 @@ # -# Copyright (C) 2018 Marvell International Ltd. +# Copyright (C) 2018-2020 Marvell International Ltd. # # SPDX-License-Identifier: BSD-3-Clause # https://spdx.org/licenses @@ -64,6 +64,10 @@ BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \ $(PLAT_COMMON_BASE)/a3700_sip_svc.c \ $(MARVELL_DRV) +ifeq ($(CM3_SYSTEM_RESET),1) +BL31_SOURCES += $(PLAT_COMMON_BASE)/cm3_system_reset.c +endif + ifdef WTP DOIMAGEPATH := $(WTP) diff --git a/plat/marvell/armada/a3k/common/cm3_system_reset.c b/plat/marvell/armada/a3k/common/cm3_system_reset.c new file mode 100644 index 000000000..548ff5168 --- /dev/null +++ b/plat/marvell/armada/a3k/common/cm3_system_reset.c @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2020 Marek Behun, CZ.NIC + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include +#include +#include + +#include + +/* Cortex-M3 Secure Processor Mailbox Registers */ +#define MVEBU_RWTM_PARAM0_REG (MVEBU_RWTM_REG_BASE) +#define MVEBU_RWTM_CMD_REG (MVEBU_RWTM_REG_BASE + 0x40) +#define MVEBU_RWTM_HOST_INT_RESET_REG (MVEBU_RWTM_REG_BASE + 0xC8) +#define MVEBU_RWTM_HOST_INT_MASK_REG (MVEBU_RWTM_REG_BASE + 0xCC) +#define MVEBU_RWTM_HOST_INT_SP_COMPLETE BIT(0) + +#define MVEBU_RWTM_REBOOT_CMD 0x0009 +#define MVEBU_RWTM_REBOOT_MAGIC 0xDEADBEEF + +static inline bool rwtm_completed(void) +{ + return (mmio_read_32(MVEBU_RWTM_HOST_INT_RESET_REG) & + MVEBU_RWTM_HOST_INT_SP_COMPLETE) != 0; +} + +static bool rwtm_wait(int ms) +{ + while (ms && !rwtm_completed()) { + mdelay(1); + --ms; + } + + return rwtm_completed(); +} + +void cm3_system_reset(void) +{ + int tries = 5; + + for (; tries > 0; --tries) { + mmio_clrbits_32(MVEBU_RWTM_HOST_INT_RESET_REG, + MVEBU_RWTM_HOST_INT_SP_COMPLETE); + + mmio_write_32(MVEBU_RWTM_PARAM0_REG, MVEBU_RWTM_REBOOT_MAGIC); + mmio_write_32(MVEBU_RWTM_CMD_REG, MVEBU_RWTM_REBOOT_CMD); + + if (rwtm_wait(10)) { + break; + } + + mdelay(100); + } + + /* If we reach here, the command is not implemented. */ + ERROR("System reset command not implemented in WTMI firmware!\n"); +} diff --git a/plat/marvell/armada/a3k/common/include/a3700_plat_def.h b/plat/marvell/armada/a3k/common/include/a3700_plat_def.h index c7f40adc3..d23f5beea 100644 --- a/plat/marvell/armada/a3k/common/include/a3700_plat_def.h +++ b/plat/marvell/armada/a3k/common/include/a3700_plat_def.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 Marvell International Ltd. + * Copyright (C) 2018-2020 Marvell International Ltd. * * SPDX-License-Identifier: BSD-3-Clause * https://spdx.org/licenses @@ -119,4 +119,10 @@ */ #define MVEBU_COMPHY_REG_BASE (MVEBU_REGS_BASE + 0x18300) +/***************************************************************************** + * Cortex-M3 Secure Processor Mailbox constants + ***************************************************************************** + */ +#define MVEBU_RWTM_REG_BASE (MVEBU_REGS_BASE + 0xB0000) + #endif /* A3700_PLAT_DEF_H */ diff --git a/plat/marvell/armada/a3k/common/include/a3700_pm.h b/plat/marvell/armada/a3k/common/include/a3700_pm.h index cc6cf436a..44dbb9f7d 100644 --- a/plat/marvell/armada/a3k/common/include/a3700_pm.h +++ b/plat/marvell/armada/a3k/common/include/a3700_pm.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Marvell International Ltd. + * Copyright (C) 2016-2020 Marvell International Ltd. * * SPDX-License-Identifier: BSD-3-Clause * https://spdx.org/licenses @@ -48,4 +48,6 @@ struct pm_wake_up_src_config { struct pm_wake_up_src_config *mv_wake_up_src_config_get(void); +void cm3_system_reset(void); + #endif /* A3700_PM_H */ diff --git a/plat/marvell/armada/a3k/common/plat_pm.c b/plat/marvell/armada/a3k/common/plat_pm.c index f8ce6fe29..2bae37e3f 100644 --- a/plat/marvell/armada/a3k/common/plat_pm.c +++ b/plat/marvell/armada/a3k/common/plat_pm.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 Marvell International Ltd. + * Copyright (C) 2018-2020 Marvell International Ltd. * * SPDX-License-Identifier: BSD-3-Clause * https://spdx.org/licenses @@ -763,6 +763,11 @@ static void __dead2 a3700_system_off(void) panic(); } +#pragma weak cm3_system_reset +void cm3_system_reset(void) +{ +} + /***************************************************************************** * A3700 handlers to reset the system ***************************************************************************** @@ -780,6 +785,9 @@ static void __dead2 a3700_system_reset(void) 2 * sizeof(uint64_t)); #endif + /* Use Cortex-M3 secure coprocessor for system reset */ + cm3_system_reset(); + /* Trigger the warm reset */ mmio_write_32(MVEBU_WARM_RESET_REG, MVEBU_WARM_RESET_MAGIC); -- cgit v1.2.3 From db9736e3d86d7098f9785a9db834746a8b2ed335 Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Fri, 25 Dec 2020 10:52:56 +0000 Subject: AArch64: Fix assertions in processing dynamic relocations This patch provides the following changes in fixup_gdt_reloc() function: - Fixes assertions in processing dynamic relocations, when relocation entries not matching R_AARCH64_RELATIVE type are found. Linker might generate entries of relocation type R_AARCH64_NONE (code 0), which should be ignored to make the code boot. Similar issue was fixed in OP-TEE (see optee_os/ldelf/ta_elf_rel.c commit 7a4dc765c133125428136a496a7644c6fec9b3c2) - Fixes bug when "b.ge" (signed greater than or equal) condition codes were used instead of "b.hs" (greater than or equal) for comparison of absolute addresses. - Adds optimisation which skips fixing Global Object Table (GOT) entries when offset value is 0. Change-Id: I35e34e055b7476843903859be947b883a1feb1b5 Signed-off-by: Alexei Fedorov --- lib/aarch64/misc_helpers.S | 48 ++++++++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/lib/aarch64/misc_helpers.S b/lib/aarch64/misc_helpers.S index 052891683..b6f6c9d88 100644 --- a/lib/aarch64/misc_helpers.S +++ b/lib/aarch64/misc_helpers.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 */ @@ -486,15 +486,20 @@ endfunc enable_vfp * arguments (which is usually the limits of the relocable BL image). * x0 - the start of the fixup region * x1 - the limit of the fixup region - * These addresses have to be page (4KB aligned). + * These addresses have to be 4KB page aligned. * --------------------------------------------------------------------------- */ + +/* Relocation codes */ +#define R_AARCH64_NONE 0 +#define R_AARCH64_RELATIVE 1027 + func fixup_gdt_reloc mov x6, x0 mov x7, x1 - /* Test if the limits are 4K aligned */ #if ENABLE_ASSERTIONS + /* Test if the limits are 4KB aligned */ orr x0, x0, x1 tst x0, #(PAGE_SIZE_MASK) ASM_ASSERT(eq) @@ -505,7 +510,8 @@ func fixup_gdt_reloc * fixup region. */ and x2, x30, #~(PAGE_SIZE_MASK) - sub x0, x2, x6 /* Diff(S) = Current Address - Compiled Address */ + subs x0, x2, x6 /* Diff(S) = Current Address - Compiled Address */ + b.eq 3f /* Diff(S) = 0. No relocation needed */ adrp x1, __GOT_START__ add x1, x1, :lo12:__GOT_START__ @@ -518,31 +524,32 @@ func fixup_gdt_reloc * The new_addr is the address currently the binary is executing from * and old_addr is the address at compile time. */ -1: - ldr x3, [x1] +1: ldr x3, [x1] + /* Skip adding offset if address is < lower limit */ cmp x3, x6 b.lo 2f + /* Skip adding offset if address is >= upper limit */ cmp x3, x7 - b.ge 2f + b.hs 2f add x3, x3, x0 str x3, [x1] -2: - add x1, x1, #8 + +2: add x1, x1, #8 cmp x1, x2 b.lo 1b /* Starting dynamic relocations. Use adrp/adr to get RELA_START and END */ - adrp x1, __RELA_START__ +3: adrp x1, __RELA_START__ add x1, x1, :lo12:__RELA_START__ adrp x2, __RELA_END__ add x2, x2, :lo12:__RELA_END__ + /* * According to ELF-64 specification, the RELA data structure is as * follows: - * typedef struct - * { + * typedef struct { * Elf64_Addr r_offset; * Elf64_Xword r_info; * Elf64_Sxword r_addend; @@ -550,16 +557,19 @@ func fixup_gdt_reloc * * r_offset is address of reference * r_info is symbol index and type of relocation (in this case - * 0x403 which corresponds to R_AARCH64_RELATIVE). + * code 1027 which corresponds to R_AARCH64_RELATIVE). * r_addend is constant part of expression. * * Size of Elf64_Rela structure is 24 bytes. */ -1: - /* Assert that the relocation type is R_AARCH64_RELATIVE */ + + /* Skip R_AARCH64_NONE entry with code 0 */ +1: ldr x3, [x1, #8] + cbz x3, 2f + #if ENABLE_ASSERTIONS - ldr x3, [x1, #8] - cmp x3, #0x403 + /* Assert that the relocation type is R_AARCH64_RELATIVE */ + cmp x3, #R_AARCH64_RELATIVE ASM_ASSERT(eq) #endif ldr x3, [x1] /* r_offset */ @@ -569,9 +579,10 @@ func fixup_gdt_reloc /* Skip adding offset if r_addend is < lower limit */ cmp x4, x6 b.lo 2f + /* Skip adding offset if r_addend entry is >= upper limit */ cmp x4, x7 - b.ge 2f + b.hs 2f add x4, x0, x4 /* Diff(S) + r_addend */ str x4, [x3] @@ -579,6 +590,5 @@ func fixup_gdt_reloc 2: add x1, x1, #24 cmp x1, x2 b.lo 1b - ret endfunc fixup_gdt_reloc -- cgit v1.2.3 From a98122064dcc3704a54c44323ba2eda8de7358dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Tue, 24 Nov 2020 15:38:08 +0100 Subject: Makefile: Do not mark file targets as .PHONY target MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Only non-file targets should be set a .PHONY. Otherwise if file target is set as .PHONY then targets which depends on those file .PHONY targets would be always rebuilt even when their prerequisites are not changed. File target which needs to be always rebuilt can be specified in Make system via having a prerequisite on some .PHONY target, instead of marking whole target as .PHONY. In Makefile projects it is common to create empty .PHONY target named FORCE for this purpose. This patch changes all file targets which are set as .PHONY to depends on new .PHONY target FORCE, to ensure that these file targets are always rebuilt (as before). Basically they are those targets which calls external make subprocess. After FORCE target is specified in main Makefile, remove it from other Makefile files to prevent duplicate definitions. Signed-off-by: Pali Rohár Change-Id: Iee3b4e0de93879b95eb29a1745a041538412e69e --- Makefile | 18 ++++++++---------- plat/arm/board/common/board_common.mk | 1 - plat/marvell/armada/a3k/common/a3700_common.mk | 3 --- plat/marvell/armada/a8k/common/a8k_common.mk | 3 --- plat/marvell/armada/a8k/common/ble/ble.mk | 2 -- 5 files changed, 8 insertions(+), 19 deletions(-) diff --git a/Makefile b/Makefile index 2d5a5bb2e..b0399f15b 100644 --- a/Makefile +++ b/Makefile @@ -1245,8 +1245,7 @@ checkpatch: locate-checkpatch certtool: ${CRTTOOL} -.PHONY: ${CRTTOOL} -${CRTTOOL}: +${CRTTOOL}: FORCE ${Q}${MAKE} PLAT=${PLAT} USE_TBBR_DEFS=${USE_TBBR_DEFS} COT=${COT} OPENSSL_DIR=${OPENSSL_DIR} CRTTOOL=${CRTTOOL} --no-print-directory -C ${CRTTOOLPATH} @${ECHO_BLANK_LINE} @echo "Built $@ successfully" @@ -1288,8 +1287,7 @@ fiptool: ${FIPTOOL} fip: ${BUILD_PLAT}/${FIP_NAME} fwu_fip: ${BUILD_PLAT}/${FWU_FIP_NAME} -.PHONY: ${FIPTOOL} -${FIPTOOL}: +${FIPTOOL}: FORCE @${ECHO_BLANK_LINE} @echo "Building $@" ifdef UNIX_MK @@ -1302,12 +1300,10 @@ endif @${ECHO_BLANK_LINE} sptool: ${SPTOOL} -.PHONY: ${SPTOOL} -${SPTOOL}: +${SPTOOL}: FORCE ${Q}${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" SPTOOL=${SPTOOL} --no-print-directory -C ${SPTOOLPATH} -.PHONY: libraries -romlib.bin: libraries +romlib.bin: libraries FORCE ${Q}${MAKE} PLAT_DIR=${PLAT_DIR} BUILD_PLAT=${BUILD_PLAT} ENABLE_BTI=${ENABLE_BTI} ARM_ARCH_MINOR=${ARM_ARCH_MINOR} INCLUDES='${INCLUDES}' DEFINES='${DEFINES}' --no-print-directory -C ${ROMLIBPATH} all # Call print_memory_map tool @@ -1320,8 +1316,7 @@ doc: enctool: ${ENCTOOL} -.PHONY: ${ENCTOOL} -${ENCTOOL}: +${ENCTOOL}: FORCE ${Q}${MAKE} PLAT=${PLAT} BUILD_INFO=0 OPENSSL_DIR=${OPENSSL_DIR} ENCTOOL=${ENCTOOL} --no-print-directory -C ${ENCTOOLPATH} @${ECHO_BLANK_LINE} @echo "Built $@ successfully" @@ -1375,3 +1370,6 @@ help: @echo "" @echo "example: build all targets for the FVP platform:" @echo " CROSS_COMPILE=aarch64-none-elf- make PLAT=fvp all" + +.PHONY: FORCE +FORCE:; diff --git a/plat/arm/board/common/board_common.mk b/plat/arm/board/common/board_common.mk index 1885a600a..6db0c0031 100644 --- a/plat/arm/board/common/board_common.mk +++ b/plat/arm/board/common/board_common.mk @@ -41,7 +41,6 @@ $(eval $(call add_define,ARM_ROTPK_LOCATION_ID)) # Force generation of the new hash if ROT_KEY is specified ifdef ROT_KEY HASH_PREREQUISITES = $(ROT_KEY) FORCE -FORCE: else HASH_PREREQUISITES = $(ROT_KEY) endif diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk index 712b16202..2bb0f193d 100644 --- a/plat/marvell/armada/a3k/common/a3700_common.mk +++ b/plat/marvell/armada/a3k/common/a3700_common.mk @@ -211,6 +211,3 @@ mrvl_flash: $(error "Platform '${PLAT}' for target '$@' requires WTP. Please set WTP to point to the right directory") endif # WTP - -.PHONY: FORCE -FORCE:; diff --git a/plat/marvell/armada/a8k/common/a8k_common.mk b/plat/marvell/armada/a8k/common/a8k_common.mk index cf1516a28..b7c7d848d 100644 --- a/plat/marvell/armada/a8k/common/a8k_common.mk +++ b/plat/marvell/armada/a8k/common/a8k_common.mk @@ -166,6 +166,3 @@ ${DOIMAGETOOL}: FORCE .PHONY: mrvl_flash mrvl_flash: ${BUILD_PLAT}/${BOOT_IMAGE} ${DOIMAGETOOL} ${DOIMAGETOOL} ${DOIMAGE_FLAGS} ${BUILD_PLAT}/${BOOT_IMAGE} ${BUILD_PLAT}/${FLASH_IMAGE} - -.PHONY: FORCE -FORCE:; diff --git a/plat/marvell/armada/a8k/common/ble/ble.mk b/plat/marvell/armada/a8k/common/ble/ble.mk index 60fbf5f1d..78c62a010 100644 --- a/plat/marvell/armada/a8k/common/ble/ble.mk +++ b/plat/marvell/armada/a8k/common/ble/ble.mk @@ -26,7 +26,5 @@ PLAT_INCLUDES += -I$(MV_DDR_PATH) \ BLE_LINKERFILE := $(BLE_PATH)/ble.ld.S -FORCE: - $(MV_DDR_LIB): FORCE @+make -C $(MV_DDR_PATH) --no-print-directory PLAT_INCLUDES="$(PLAT_INCLUDES)" PLATFORM=$(PLAT) ARCH=AARCH64 OBJ_DIR=$(BUILD_PLAT)/ble -- cgit v1.2.3 From 4727fd1320940c2d89c75c13645864c46a24d96d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Tue, 24 Nov 2020 16:53:04 +0100 Subject: Makefile: Fix ${FIP_NAME} to be rebuilt only when needed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently ${FIP_DEPS} as prerequisite for ${BUILD_PLAT}/${FIP_NAME} contains .PHONY targets check_$(1) and therefore ${BUILD_PLAT}/${FIP_NAME} is always rebuilt even when other file target prerequisites are not changed. These changes fix above issue and ${BUILD_PLAT}/${FIP_NAME} target is rebuilt only when its prerequisites are changed. There are 3 changes: Content of check_$(1) target is moved into check_$(1)_cmd variable so it can be easily reused. .PHONY check_$(1) targets are not put into ${FIP_DEPS} and ${FWU_FIP_DEPS} dependencies anymore and required checks which are in ${CHECK_FIP_CMD} and ${CHECK_FWU_FIP_CMD} variables are executed as part of targets ${BUILD_PLAT}/${FIP_NAME} and ${BUILD_PLAT}/${FWU_FIP_NAME} itself. To ensure that ${BUILD_PLAT}/${FIP_NAME} and ${BUILD_PLAT}/${FWU_FIP_NAME} are rebuilt even when additional dependency file image added by TOOL_ADD_IMG is changed, this file image (if exists) is added as file dependency to ${FIP_DEPS} and ${FWU_FIP_DEPS}. If it does not exist then FORCE target is added to ensure that FIP/FWU_FIP is rebuilt. Command ${CHECK_FIP_CMD}/${CHECK_FWU_FIP_CMD} will then thrown an error message if the file is required but not present. So this change ensures that if BL33 image is updated then final FIP image is updated too. And if BL33 image is not specified or does not exist and is required to be present then check_$(1)_cmd call from ${CHECK_FIP_CMD} would ensure that error message is thrown during build. Signed-off-by: Pali Rohár Change-Id: I635cf82e2b667ff57e2af83500d4aca71d235e3e --- Makefile | 2 ++ make_helpers/build_macros.mk | 15 +++++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index b0399f15b..ceb5a118c 100644 --- a/Makefile +++ b/Makefile @@ -1261,6 +1261,7 @@ certificates: ${CRT_DEPS} ${CRTTOOL} endif ${BUILD_PLAT}/${FIP_NAME}: ${FIP_DEPS} ${FIPTOOL} + $(eval ${CHECK_FIP_CMD}) ${Q}${FIPTOOL} create ${FIP_ARGS} $@ ${Q}${FIPTOOL} info $@ @${ECHO_BLANK_LINE} @@ -1277,6 +1278,7 @@ fwu_certificates: ${FWU_CRT_DEPS} ${CRTTOOL} endif ${BUILD_PLAT}/${FWU_FIP_NAME}: ${FWU_FIP_DEPS} ${FIPTOOL} + $(eval ${CHECK_FWU_FIP_CMD}) ${Q}${FIPTOOL} create ${FWU_FIP_ARGS} $@ ${Q}${FIPTOOL} info $@ @${ECHO_BLANK_LINE} diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk index 613fca23f..86550288c 100644 --- a/make_helpers/build_macros.mk +++ b/make_helpers/build_macros.mk @@ -214,21 +214,28 @@ define TOOL_ADD_IMG # This is the uppercase form of the first parameter $(eval _V := $(call uppercase,$(1))) + # $(check_$(1)_cmd) variable is executed in the check_$(1) target and also + # is put into the ${CHECK_$(3)FIP_CMD} variable which is executed by the + # target ${BUILD_PLAT}/${$(3)FIP_NAME}. + $(eval check_$(1)_cmd := \ + $(if $(value $(_V)),,$$$$(error "Platform '${PLAT}' requires $(_V). Please set $(_V) to point to the right file")) \ + $(if $(wildcard $(value $(_V))),,$$$$(error '$(_V)=$(value $(_V))' was specified, but '$(value $(_V))' does not exist)) \ + ) + $(3)CRT_DEPS += check_$(1) - $(3)FIP_DEPS += check_$(1) + CHECK_$(3)FIP_CMD += $$(check_$(1)_cmd) ifeq ($(4),1) $(eval ENC_BIN := ${BUILD_PLAT}/$(1)_enc.bin) $(call ENCRYPT_FW,$(value $(_V)),$(ENC_BIN)) $(call TOOL_ADD_IMG_PAYLOAD,$(1),$(value $(_V)),$(2),$(ENC_BIN),$(3), \ $(ENC_BIN)) else - $(call TOOL_ADD_IMG_PAYLOAD,$(1),$(value $(_V)),$(2),,$(3)) + $(call TOOL_ADD_IMG_PAYLOAD,$(1),$(value $(_V)),$(2),$(if $(wildcard $(value $(_V))),$(value $(_V)),FORCE),$(3)) endif .PHONY: check_$(1) check_$(1): - $$(if $(value $(_V)),,$$(error "Platform '${PLAT}' requires $(_V). Please set $(_V) to point to the right file")) - $$(if $(wildcard $(value $(_V))),,$$(error '$(_V)=$(value $(_V))' was specified, but '$(value $(_V))' does not exist)) + $(check_$(1)_cmd) endef ################################################################################ -- cgit v1.2.3 From e43258fa0055b3d9b22be63dbe7ea9dd9ffc794f Mon Sep 17 00:00:00 2001 From: Venkatesh Yadav Abbarapu Date: Sun, 10 Jan 2021 20:40:16 -0700 Subject: plat: xilinx: Fix non-MISRA compliant code This patch fixes the non compliant code like missing braces for conditional single statement bodies. Signed-off-by: Venkatesh Yadav Abbarapu Change-Id: I95b410ae5950f85dc913c4448fcd0a97e0fd490c --- plat/xilinx/versal/bl31_versal_setup.c | 6 ++++-- plat/xilinx/versal/plat_versal.c | 6 ++++-- plat/xilinx/zynqmp/bl31_zynqmp_setup.c | 20 +++++++++++++------- plat/xilinx/zynqmp/plat_zynqmp.c | 6 ++++-- 4 files changed, 25 insertions(+), 13 deletions(-) diff --git a/plat/xilinx/versal/bl31_versal_setup.c b/plat/xilinx/versal/bl31_versal_setup.c index 27991d381..5e870ff5f 100644 --- a/plat/xilinx/versal/bl31_versal_setup.c +++ b/plat/xilinx/versal/bl31_versal_setup.c @@ -34,8 +34,9 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) { assert(sec_state_is_valid(type)); - if (type == NON_SECURE) + if (type == NON_SECURE) { return &bl33_image_ep_info; + } return &bl32_image_ep_info; } @@ -68,8 +69,9 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, VERSAL_UART_CLOCK, VERSAL_UART_BAUDRATE, &versal_runtime_console); - if (rc == 0) + if (rc == 0) { panic(); + } console_set_scope(&versal_runtime_console, CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME); diff --git a/plat/xilinx/versal/plat_versal.c b/plat/xilinx/versal/plat_versal.c index a080a76a9..107eae66b 100644 --- a/plat/xilinx/versal/plat_versal.c +++ b/plat/xilinx/versal/plat_versal.c @@ -9,11 +9,13 @@ int plat_core_pos_by_mpidr(u_register_t mpidr) { - if (mpidr & MPIDR_CLUSTER_MASK) + if (mpidr & MPIDR_CLUSTER_MASK) { return -1; + } - if ((mpidr & MPIDR_CPU_MASK) >= PLATFORM_CORE_COUNT) + if ((mpidr & MPIDR_CPU_MASK) >= PLATFORM_CORE_COUNT) { return -1; + } return versal_calc_core_pos(mpidr); } diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c index 8272d6221..d4cd7f65b 100644 --- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c +++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c @@ -32,8 +32,9 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) { assert(sec_state_is_valid(type)); - if (type == NON_SECURE) + if (type == NON_SECURE) { return &bl33_image_ep_info; + } return &bl32_image_ep_info; } @@ -99,10 +100,11 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, enum fsbl_handoff ret = fsbl_atf_handover(&bl32_image_ep_info, &bl33_image_ep_info, atf_handoff_addr); - if (ret == FSBL_HANDOFF_NO_STRUCT) + if (ret == FSBL_HANDOFF_NO_STRUCT) { bl31_set_default_config(); - else if (ret != FSBL_HANDOFF_SUCCESS) + } else if (ret != FSBL_HANDOFF_SUCCESS) { panic(); + } } if (bl32_image_ep_info.pc) { VERBOSE("BL31: Secure code at 0x%lx\n", bl32_image_ep_info.pc); @@ -137,12 +139,14 @@ static interrupt_type_handler_t type_el3_interrupt_table[MAX_INTR_EL3]; int request_intr_type_el3(uint32_t id, interrupt_type_handler_t handler) { /* Validate 'handler' and 'id' parameters */ - if (!handler || id >= MAX_INTR_EL3) + if (!handler || id >= MAX_INTR_EL3) { return -EINVAL; + } /* Check if a handler has already been registered */ - if (type_el3_interrupt_table[id]) + if (type_el3_interrupt_table[id]) { return -EALREADY; + } type_el3_interrupt_table[id] = handler; @@ -157,8 +161,9 @@ static uint64_t rdo_el3_interrupt_handler(uint32_t id, uint32_t flags, intr_id = plat_ic_get_pending_interrupt_id(); handler = type_el3_interrupt_table[intr_id]; - if (handler != NULL) + if (handler != NULL) { handler(intr_id, flags, handle, cookie); + } return 0; } @@ -181,8 +186,9 @@ void bl31_plat_runtime_setup(void) set_interrupt_rm_flag(flags, NON_SECURE); rc = register_interrupt_type_handler(INTR_TYPE_EL3, rdo_el3_interrupt_handler, flags); - if (rc) + if (rc) { panic(); + } #endif } diff --git a/plat/xilinx/zynqmp/plat_zynqmp.c b/plat/xilinx/zynqmp/plat_zynqmp.c index 906ce1b7f..58a52a3bf 100644 --- a/plat/xilinx/zynqmp/plat_zynqmp.c +++ b/plat/xilinx/zynqmp/plat_zynqmp.c @@ -9,11 +9,13 @@ int plat_core_pos_by_mpidr(u_register_t mpidr) { - if (mpidr & MPIDR_CLUSTER_MASK) + if (mpidr & MPIDR_CLUSTER_MASK) { return -1; + } - if ((mpidr & MPIDR_CPU_MASK) >= PLATFORM_CORE_COUNT) + if ((mpidr & MPIDR_CPU_MASK) >= PLATFORM_CORE_COUNT) { return -1; + } return zynqmp_calc_core_pos(mpidr); } -- cgit v1.2.3 From edf771a11f7331a3c5e640dcd35fb930f9a08170 Mon Sep 17 00:00:00 2001 From: Aditya Angadi Date: Tue, 15 Dec 2020 17:10:50 +0530 Subject: plat/arm: rename rddaniel to rdv1 Reference Design platform RD-Daniel has been renamed to RD-V1. Correspondingly, remove all uses of 'rddaniel' and replace it with 'rdv1' where appropriate. Signed-off-by: Aditya Angadi Change-Id: I1702bab39c501f8c0a09df131cb2394d54c83bcf --- .../arm/board/rddaniel/fdts/rddaniel_fw_config.dts | 27 --------- .../board/rddaniel/fdts/rddaniel_nt_fw_config.dts | 22 -------- .../board/rddaniel/fdts/rddaniel_tb_fw_config.dts | 28 ---------- plat/arm/board/rddaniel/include/platform_def.h | 65 ---------------------- plat/arm/board/rddaniel/platform.mk | 59 -------------------- plat/arm/board/rddaniel/rddaniel_err.c | 17 ------ plat/arm/board/rddaniel/rddaniel_plat.c | 30 ---------- plat/arm/board/rddaniel/rddaniel_security.c | 22 -------- plat/arm/board/rddaniel/rddaniel_topology.c | 62 --------------------- plat/arm/board/rddaniel/rddaniel_trusted_boot.c | 26 --------- plat/arm/board/rdv1/fdts/rdv1_fw_config.dts | 27 +++++++++ plat/arm/board/rdv1/fdts/rdv1_nt_fw_config.dts | 22 ++++++++ plat/arm/board/rdv1/fdts/rdv1_tb_fw_config.dts | 28 ++++++++++ plat/arm/board/rdv1/include/platform_def.h | 65 ++++++++++++++++++++++ plat/arm/board/rdv1/platform.mk | 59 ++++++++++++++++++++ plat/arm/board/rdv1/rdv1_err.c | 17 ++++++ plat/arm/board/rdv1/rdv1_plat.c | 30 ++++++++++ plat/arm/board/rdv1/rdv1_security.c | 22 ++++++++ plat/arm/board/rdv1/rdv1_topology.c | 62 +++++++++++++++++++++ plat/arm/board/rdv1/rdv1_trusted_boot.c | 26 +++++++++ plat/arm/css/sgi/include/sgi_variant.h | 4 +- plat/arm/css/sgi/sgi_bl31_setup.c | 6 +- 22 files changed, 363 insertions(+), 363 deletions(-) delete mode 100644 plat/arm/board/rddaniel/fdts/rddaniel_fw_config.dts delete mode 100644 plat/arm/board/rddaniel/fdts/rddaniel_nt_fw_config.dts delete mode 100644 plat/arm/board/rddaniel/fdts/rddaniel_tb_fw_config.dts delete mode 100644 plat/arm/board/rddaniel/include/platform_def.h delete mode 100644 plat/arm/board/rddaniel/platform.mk delete mode 100644 plat/arm/board/rddaniel/rddaniel_err.c delete mode 100644 plat/arm/board/rddaniel/rddaniel_plat.c delete mode 100644 plat/arm/board/rddaniel/rddaniel_security.c delete mode 100644 plat/arm/board/rddaniel/rddaniel_topology.c delete mode 100644 plat/arm/board/rddaniel/rddaniel_trusted_boot.c create mode 100644 plat/arm/board/rdv1/fdts/rdv1_fw_config.dts create mode 100644 plat/arm/board/rdv1/fdts/rdv1_nt_fw_config.dts create mode 100644 plat/arm/board/rdv1/fdts/rdv1_tb_fw_config.dts create mode 100644 plat/arm/board/rdv1/include/platform_def.h create mode 100644 plat/arm/board/rdv1/platform.mk create mode 100644 plat/arm/board/rdv1/rdv1_err.c create mode 100644 plat/arm/board/rdv1/rdv1_plat.c create mode 100644 plat/arm/board/rdv1/rdv1_security.c create mode 100644 plat/arm/board/rdv1/rdv1_topology.c create mode 100644 plat/arm/board/rdv1/rdv1_trusted_boot.c diff --git a/plat/arm/board/rddaniel/fdts/rddaniel_fw_config.dts b/plat/arm/board/rddaniel/fdts/rddaniel_fw_config.dts deleted file mode 100644 index 9c9cefe87..000000000 --- a/plat/arm/board/rddaniel/fdts/rddaniel_fw_config.dts +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -/dts-v1/; - -/ { - dtb-registry { - compatible = "fconf,dyn_cfg-dtb_registry"; - - tb_fw-config { - load-address = <0x0 0x4001300>; - max-size = <0x200>; - id = ; - }; - - nt_fw-config { - load-address = <0x0 0xFEF00000>; - max-size = <0x0100000>; - id = ; - }; - }; -}; diff --git a/plat/arm/board/rddaniel/fdts/rddaniel_nt_fw_config.dts b/plat/arm/board/rddaniel/fdts/rddaniel_nt_fw_config.dts deleted file mode 100644 index 4d4580d68..000000000 --- a/plat/arm/board/rddaniel/fdts/rddaniel_nt_fw_config.dts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/dts-v1/; -/ { - /* compatible string */ - compatible = "arm,rd-daniel"; - - /* - * Place holder for system-id node with default values. The - * value of platform-id and config-id will be set to the - * correct values during the BL2 stage of boot. - */ - system-id { - platform-id = <0x0>; - config-id = <0x0>; - multi-chip-mode = <0x0>; - }; -}; diff --git a/plat/arm/board/rddaniel/fdts/rddaniel_tb_fw_config.dts b/plat/arm/board/rddaniel/fdts/rddaniel_tb_fw_config.dts deleted file mode 100644 index 49eda2735..000000000 --- a/plat/arm/board/rddaniel/fdts/rddaniel_tb_fw_config.dts +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/dts-v1/; - -/ { - tb_fw-config { - compatible = "arm,tb_fw"; - - /* Disable authentication for development */ - disable_auth = <0x0>; - - /* - * The following two entries are placeholders for Mbed TLS - * heap information. The default values don't matter since - * they will be overwritten by BL1. - * In case of having shared Mbed TLS heap between BL1 and BL2, - * BL1 will populate these two properties with the respective - * info about the shared heap. This info will be available for - * BL2 in order to locate and re-use the heap. - */ - mbedtls_heap_addr = <0x0 0x0>; - mbedtls_heap_size = <0x0>; - }; -}; diff --git a/plat/arm/board/rddaniel/include/platform_def.h b/plat/arm/board/rddaniel/include/platform_def.h deleted file mode 100644 index 5b98b4e8c..000000000 --- a/plat/arm/board/rddaniel/include/platform_def.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef PLATFORM_DEF_H -#define PLATFORM_DEF_H - -#include - -#include - -#define PLAT_ARM_CLUSTER_COUNT U(16) -#define CSS_SGI_MAX_CPUS_PER_CLUSTER U(1) -#define CSS_SGI_MAX_PE_PER_CPU U(1) - -#define PLAT_CSS_MHU_BASE UL(0x45400000) -#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE - -#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL2 -#define PLAT_MAX_PWR_LVL ARM_PWR_LVL1 - -/* TZC Related Constants */ -#define PLAT_ARM_TZC_BASE UL(0x21830000) -#define PLAT_ARM_TZC_FILTERS TZC_400_REGION_ATTR_FILTER_BIT(0) - -#define TZC400_OFFSET UL(0x1000000) -#define TZC400_COUNT 4 - -#define TZC400_BASE(n) (PLAT_ARM_TZC_BASE + \ - (n * TZC400_OFFSET)) - -#define TZC_NSAID_ALL_AP U(0) -#define TZC_NSAID_PCI U(1) -#define TZC_NSAID_HDLCD0 U(2) -#define TZC_NSAID_CLCD U(7) -#define TZC_NSAID_AP U(9) -#define TZC_NSAID_VIRTIO U(15) - -#define PLAT_ARM_TZC_NS_DEV_ACCESS \ - (TZC_REGION_ACCESS_RDWR(TZC_NSAID_ALL_AP)) | \ - (TZC_REGION_ACCESS_RDWR(TZC_NSAID_HDLCD0)) | \ - (TZC_REGION_ACCESS_RDWR(TZC_NSAID_PCI)) | \ - (TZC_REGION_ACCESS_RDWR(TZC_NSAID_AP)) | \ - (TZC_REGION_ACCESS_RDWR(TZC_NSAID_CLCD)) | \ - (TZC_REGION_ACCESS_RDWR(TZC_NSAID_VIRTIO)) - -/* - * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes - */ -#ifdef __aarch64__ -#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 42) -#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 42) -#else -#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) -#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) -#endif - -/* GIC related constants */ -#define PLAT_ARM_GICD_BASE UL(0x30000000) -#define PLAT_ARM_GICC_BASE UL(0x2C000000) -#define PLAT_ARM_GICR_BASE UL(0x30140000) - -#endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/rddaniel/platform.mk b/plat/arm/board/rddaniel/platform.mk deleted file mode 100644 index 6553ae27e..000000000 --- a/plat/arm/board/rddaniel/platform.mk +++ /dev/null @@ -1,59 +0,0 @@ -# Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. -# -# SPDX-License-Identifier: BSD-3-Clause -# - -# RD-Daniel platform uses GIC-Clayton which is based on GICv4.1 -GIC_ENABLE_V4_EXTN := 1 - -include plat/arm/css/sgi/sgi-common.mk - -RDDANIEL_BASE = plat/arm/board/rddaniel - -PLAT_INCLUDES += -I${RDDANIEL_BASE}/include/ - -SGI_CPU_SOURCES := lib/cpus/aarch64/neoverse_v1.S - -PLAT_BL_COMMON_SOURCES += ${CSS_ENT_BASE}/sgi_plat.c - -BL1_SOURCES += ${SGI_CPU_SOURCES} \ - ${RDDANIEL_BASE}/rddaniel_err.c - -BL2_SOURCES += ${RDDANIEL_BASE}/rddaniel_plat.c \ - ${RDDANIEL_BASE}/rddaniel_security.c \ - ${RDDANIEL_BASE}/rddaniel_err.c \ - lib/utils/mem_region.c \ - drivers/arm/tzc/tzc400.c \ - plat/arm/common/arm_tzc400.c \ - plat/arm/common/arm_nor_psci_mem_protect.c - -BL31_SOURCES += ${SGI_CPU_SOURCES} \ - ${RDDANIEL_BASE}/rddaniel_plat.c \ - ${RDDANIEL_BASE}/rddaniel_topology.c \ - drivers/cfi/v2m/v2m_flash.c \ - lib/utils/mem_region.c \ - plat/arm/common/arm_nor_psci_mem_protect.c - -ifeq (${TRUSTED_BOARD_BOOT}, 1) -BL1_SOURCES += ${RDDANIEL_BASE}/rddaniel_trusted_boot.c -BL2_SOURCES += ${RDDANIEL_BASE}/rddaniel_trusted_boot.c -endif - -# Add the FDT_SOURCES and options for Dynamic Config -FDT_SOURCES += ${RDDANIEL_BASE}/fdts/${PLAT}_fw_config.dts \ - ${RDDANIEL_BASE}/fdts/${PLAT}_tb_fw_config.dts -FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb -TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb - -# Add the FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG})) -# Add the TB_FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG})) - -FDT_SOURCES += ${RDDANIEL_BASE}/fdts/${PLAT}_nt_fw_config.dts -NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb - -# Add the NT_FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config,${NT_FW_CONFIG})) - -override CTX_INCLUDE_AARCH32_REGS := 0 diff --git a/plat/arm/board/rddaniel/rddaniel_err.c b/plat/arm/board/rddaniel/rddaniel_err.c deleted file mode 100644 index 5e1094219..000000000 --- a/plat/arm/board/rddaniel/rddaniel_err.c +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -/* - * rddaniel error handler - */ -void __dead2 plat_arm_error_handler(int err) -{ - while (1) { - wfi(); - } -} diff --git a/plat/arm/board/rddaniel/rddaniel_plat.c b/plat/arm/board/rddaniel/rddaniel_plat.c deleted file mode 100644 index ab5251e51..000000000 --- a/plat/arm/board/rddaniel/rddaniel_plat.c +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include - -unsigned int plat_arm_sgi_get_platform_id(void) -{ - return mmio_read_32(SID_REG_BASE + SID_SYSTEM_ID_OFFSET) - & SID_SYSTEM_ID_PART_NUM_MASK; -} - -unsigned int plat_arm_sgi_get_config_id(void) -{ - return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET); -} - -unsigned int plat_arm_sgi_get_multi_chip_mode(void) -{ - return (mmio_read_32(SID_REG_BASE + SID_NODE_ID_OFFSET) & - SID_MULTI_CHIP_MODE_MASK) >> SID_MULTI_CHIP_MODE_SHIFT; -} - -void bl31_platform_setup(void) -{ - sgi_bl31_common_platform_setup(); -} diff --git a/plat/arm/board/rddaniel/rddaniel_security.c b/plat/arm/board/rddaniel/rddaniel_security.c deleted file mode 100644 index 1247db860..000000000 --- a/plat/arm/board/rddaniel/rddaniel_security.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include - -static const arm_tzc_regions_info_t tzc_regions[] = { - ARM_TZC_REGIONS_DEF, - {} -}; - -/* Initialize the secure environment */ -void plat_arm_security_setup(void) -{ - int i; - - for (i = 0; i < TZC400_COUNT; i++) - arm_tzc400_setup(TZC400_BASE(i), tzc_regions); -} diff --git a/plat/arm/board/rddaniel/rddaniel_topology.c b/plat/arm/board/rddaniel/rddaniel_topology.c deleted file mode 100644 index 55f5e04da..000000000 --- a/plat/arm/board/rddaniel/rddaniel_topology.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include - -/****************************************************************************** - * The power domain tree descriptor. - ******************************************************************************/ -const unsigned char rd_daniel_pd_tree_desc[] = { - PLAT_ARM_CLUSTER_COUNT, - CSS_SGI_MAX_CPUS_PER_CLUSTER, - CSS_SGI_MAX_CPUS_PER_CLUSTER, - CSS_SGI_MAX_CPUS_PER_CLUSTER, - CSS_SGI_MAX_CPUS_PER_CLUSTER, - CSS_SGI_MAX_CPUS_PER_CLUSTER, - CSS_SGI_MAX_CPUS_PER_CLUSTER, - CSS_SGI_MAX_CPUS_PER_CLUSTER, - CSS_SGI_MAX_CPUS_PER_CLUSTER, - CSS_SGI_MAX_CPUS_PER_CLUSTER, - CSS_SGI_MAX_CPUS_PER_CLUSTER, - CSS_SGI_MAX_CPUS_PER_CLUSTER, - CSS_SGI_MAX_CPUS_PER_CLUSTER, - CSS_SGI_MAX_CPUS_PER_CLUSTER, - CSS_SGI_MAX_CPUS_PER_CLUSTER, - CSS_SGI_MAX_CPUS_PER_CLUSTER, - CSS_SGI_MAX_CPUS_PER_CLUSTER -}; - -/******************************************************************************* - * This function returns the topology tree information. - ******************************************************************************/ -const unsigned char *plat_get_power_domain_tree_desc(void) -{ - return rd_daniel_pd_tree_desc; -} - -/******************************************************************************* - * The array mapping platform core position (implemented by plat_my_core_pos()) - * to the SCMI power domain ID implemented by SCP. - ******************************************************************************/ -const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = { - (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x0)), - (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x1)), - (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x2)), - (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x3)), - (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x4)), - (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x5)), - (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x6)), - (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x7)), - (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x8)), - (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x9)), - (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xA)), - (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xB)), - (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xC)), - (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xD)), - (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xE)), - (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xF)) -}; diff --git a/plat/arm/board/rddaniel/rddaniel_trusted_boot.c b/plat/arm/board/rddaniel/rddaniel_trusted_boot.c deleted file mode 100644 index 4592b8fba..000000000 --- a/plat/arm/board/rddaniel/rddaniel_trusted_boot.c +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2020, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#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); -} diff --git a/plat/arm/board/rdv1/fdts/rdv1_fw_config.dts b/plat/arm/board/rdv1/fdts/rdv1_fw_config.dts new file mode 100644 index 000000000..9c9cefe87 --- /dev/null +++ b/plat/arm/board/rdv1/fdts/rdv1_fw_config.dts @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +/dts-v1/; + +/ { + dtb-registry { + compatible = "fconf,dyn_cfg-dtb_registry"; + + tb_fw-config { + load-address = <0x0 0x4001300>; + max-size = <0x200>; + id = ; + }; + + nt_fw-config { + load-address = <0x0 0xFEF00000>; + max-size = <0x0100000>; + id = ; + }; + }; +}; diff --git a/plat/arm/board/rdv1/fdts/rdv1_nt_fw_config.dts b/plat/arm/board/rdv1/fdts/rdv1_nt_fw_config.dts new file mode 100644 index 000000000..62ba2c3f2 --- /dev/null +++ b/plat/arm/board/rdv1/fdts/rdv1_nt_fw_config.dts @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; +/ { + /* compatible string */ + compatible = "arm,rd-v1"; + + /* + * Place holder for system-id node with default values. The + * value of platform-id and config-id will be set to the + * correct values during the BL2 stage of boot. + */ + system-id { + platform-id = <0x0>; + config-id = <0x0>; + multi-chip-mode = <0x0>; + }; +}; diff --git a/plat/arm/board/rdv1/fdts/rdv1_tb_fw_config.dts b/plat/arm/board/rdv1/fdts/rdv1_tb_fw_config.dts new file mode 100644 index 000000000..49eda2735 --- /dev/null +++ b/plat/arm/board/rdv1/fdts/rdv1_tb_fw_config.dts @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +/ { + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + + /* + * The following two entries are placeholders for Mbed TLS + * heap information. The default values don't matter since + * they will be overwritten by BL1. + * In case of having shared Mbed TLS heap between BL1 and BL2, + * BL1 will populate these two properties with the respective + * info about the shared heap. This info will be available for + * BL2 in order to locate and re-use the heap. + */ + mbedtls_heap_addr = <0x0 0x0>; + mbedtls_heap_size = <0x0>; + }; +}; diff --git a/plat/arm/board/rdv1/include/platform_def.h b/plat/arm/board/rdv1/include/platform_def.h new file mode 100644 index 000000000..5b98b4e8c --- /dev/null +++ b/plat/arm/board/rdv1/include/platform_def.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +#include + +#include + +#define PLAT_ARM_CLUSTER_COUNT U(16) +#define CSS_SGI_MAX_CPUS_PER_CLUSTER U(1) +#define CSS_SGI_MAX_PE_PER_CPU U(1) + +#define PLAT_CSS_MHU_BASE UL(0x45400000) +#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE + +#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL2 +#define PLAT_MAX_PWR_LVL ARM_PWR_LVL1 + +/* TZC Related Constants */ +#define PLAT_ARM_TZC_BASE UL(0x21830000) +#define PLAT_ARM_TZC_FILTERS TZC_400_REGION_ATTR_FILTER_BIT(0) + +#define TZC400_OFFSET UL(0x1000000) +#define TZC400_COUNT 4 + +#define TZC400_BASE(n) (PLAT_ARM_TZC_BASE + \ + (n * TZC400_OFFSET)) + +#define TZC_NSAID_ALL_AP U(0) +#define TZC_NSAID_PCI U(1) +#define TZC_NSAID_HDLCD0 U(2) +#define TZC_NSAID_CLCD U(7) +#define TZC_NSAID_AP U(9) +#define TZC_NSAID_VIRTIO U(15) + +#define PLAT_ARM_TZC_NS_DEV_ACCESS \ + (TZC_REGION_ACCESS_RDWR(TZC_NSAID_ALL_AP)) | \ + (TZC_REGION_ACCESS_RDWR(TZC_NSAID_HDLCD0)) | \ + (TZC_REGION_ACCESS_RDWR(TZC_NSAID_PCI)) | \ + (TZC_REGION_ACCESS_RDWR(TZC_NSAID_AP)) | \ + (TZC_REGION_ACCESS_RDWR(TZC_NSAID_CLCD)) | \ + (TZC_REGION_ACCESS_RDWR(TZC_NSAID_VIRTIO)) + +/* + * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes + */ +#ifdef __aarch64__ +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 42) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 42) +#else +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) +#endif + +/* GIC related constants */ +#define PLAT_ARM_GICD_BASE UL(0x30000000) +#define PLAT_ARM_GICC_BASE UL(0x2C000000) +#define PLAT_ARM_GICR_BASE UL(0x30140000) + +#endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/rdv1/platform.mk b/plat/arm/board/rdv1/platform.mk new file mode 100644 index 000000000..5033b1874 --- /dev/null +++ b/plat/arm/board/rdv1/platform.mk @@ -0,0 +1,59 @@ +# Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# RD-V1 platform uses GIC-Clayton which is based on GICv4.1 +GIC_ENABLE_V4_EXTN := 1 + +include plat/arm/css/sgi/sgi-common.mk + +RDV1_BASE = plat/arm/board/rdv1 + +PLAT_INCLUDES += -I${RDV1_BASE}/include/ + +SGI_CPU_SOURCES := lib/cpus/aarch64/neoverse_v1.S + +PLAT_BL_COMMON_SOURCES += ${CSS_ENT_BASE}/sgi_plat.c + +BL1_SOURCES += ${SGI_CPU_SOURCES} \ + ${RDV1_BASE}/rdv1_err.c + +BL2_SOURCES += ${RDV1_BASE}/rdv1_plat.c \ + ${RDV1_BASE}/rdv1_security.c \ + ${RDV1_BASE}/rdv1_err.c \ + lib/utils/mem_region.c \ + drivers/arm/tzc/tzc400.c \ + plat/arm/common/arm_tzc400.c \ + plat/arm/common/arm_nor_psci_mem_protect.c + +BL31_SOURCES += ${SGI_CPU_SOURCES} \ + ${RDV1_BASE}/rdv1_plat.c \ + ${RDV1_BASE}/rdv1_topology.c \ + drivers/cfi/v2m/v2m_flash.c \ + lib/utils/mem_region.c \ + plat/arm/common/arm_nor_psci_mem_protect.c + +ifeq (${TRUSTED_BOARD_BOOT}, 1) +BL1_SOURCES += ${RDV1_BASE}/rdv1_trusted_boot.c +BL2_SOURCES += ${RDV1_BASE}/rdv1_trusted_boot.c +endif + +# Add the FDT_SOURCES and options for Dynamic Config +FDT_SOURCES += ${RDV1_BASE}/fdts/${PLAT}_fw_config.dts \ + ${RDV1_BASE}/fdts/${PLAT}_tb_fw_config.dts +FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb + +# Add the FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG})) +# Add the TB_FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG})) + +FDT_SOURCES += ${RDV1_BASE}/fdts/${PLAT}_nt_fw_config.dts +NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb + +# Add the NT_FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config,${NT_FW_CONFIG})) + +override CTX_INCLUDE_AARCH32_REGS := 0 diff --git a/plat/arm/board/rdv1/rdv1_err.c b/plat/arm/board/rdv1/rdv1_err.c new file mode 100644 index 000000000..68f9a3ef6 --- /dev/null +++ b/plat/arm/board/rdv1/rdv1_err.c @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +/* + * rdv1 error handler + */ +void __dead2 plat_arm_error_handler(int err) +{ + while (1) { + wfi(); + } +} diff --git a/plat/arm/board/rdv1/rdv1_plat.c b/plat/arm/board/rdv1/rdv1_plat.c new file mode 100644 index 000000000..ab5251e51 --- /dev/null +++ b/plat/arm/board/rdv1/rdv1_plat.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +unsigned int plat_arm_sgi_get_platform_id(void) +{ + return mmio_read_32(SID_REG_BASE + SID_SYSTEM_ID_OFFSET) + & SID_SYSTEM_ID_PART_NUM_MASK; +} + +unsigned int plat_arm_sgi_get_config_id(void) +{ + return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET); +} + +unsigned int plat_arm_sgi_get_multi_chip_mode(void) +{ + return (mmio_read_32(SID_REG_BASE + SID_NODE_ID_OFFSET) & + SID_MULTI_CHIP_MODE_MASK) >> SID_MULTI_CHIP_MODE_SHIFT; +} + +void bl31_platform_setup(void) +{ + sgi_bl31_common_platform_setup(); +} diff --git a/plat/arm/board/rdv1/rdv1_security.c b/plat/arm/board/rdv1/rdv1_security.c new file mode 100644 index 000000000..1247db860 --- /dev/null +++ b/plat/arm/board/rdv1/rdv1_security.c @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +static const arm_tzc_regions_info_t tzc_regions[] = { + ARM_TZC_REGIONS_DEF, + {} +}; + +/* Initialize the secure environment */ +void plat_arm_security_setup(void) +{ + int i; + + for (i = 0; i < TZC400_COUNT; i++) + arm_tzc400_setup(TZC400_BASE(i), tzc_regions); +} diff --git a/plat/arm/board/rdv1/rdv1_topology.c b/plat/arm/board/rdv1/rdv1_topology.c new file mode 100644 index 000000000..ab64fd8d0 --- /dev/null +++ b/plat/arm/board/rdv1/rdv1_topology.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +/****************************************************************************** + * The power domain tree descriptor. + ******************************************************************************/ +const unsigned char rd_v1_pd_tree_desc[] = { + PLAT_ARM_CLUSTER_COUNT, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER +}; + +/******************************************************************************* + * This function returns the topology tree information. + ******************************************************************************/ +const unsigned char *plat_get_power_domain_tree_desc(void) +{ + return rd_v1_pd_tree_desc; +} + +/******************************************************************************* + * The array mapping platform core position (implemented by plat_my_core_pos()) + * to the SCMI power domain ID implemented by SCP. + ******************************************************************************/ +const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = { + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x0)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x1)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x2)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x3)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x4)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x5)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x6)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x7)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x8)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x9)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xA)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xB)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xC)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xD)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xE)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xF)) +}; diff --git a/plat/arm/board/rdv1/rdv1_trusted_boot.c b/plat/arm/board/rdv1/rdv1_trusted_boot.c new file mode 100644 index 000000000..4592b8fba --- /dev/null +++ b/plat/arm/board/rdv1/rdv1_trusted_boot.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#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); +} diff --git a/plat/arm/css/sgi/include/sgi_variant.h b/plat/arm/css/sgi/include/sgi_variant.h index eb12f3f35..ecf6d93d6 100644 --- a/plat/arm/css/sgi/include/sgi_variant.h +++ b/plat/arm/css/sgi/include/sgi_variant.h @@ -14,8 +14,8 @@ #define RD_N1E1_EDGE_SID_VER_PART_NUM 0x0786 #define RD_E1_EDGE_CONFIG_ID 0x2 -/* SID Version values for RD-Daniel */ -#define RD_DANIEL_SID_VER_PART_NUM 0x078a +/* SID Version values for RD-V1 */ +#define RD_V1_SID_VER_PART_NUM 0x078a /* SID Version values for RD-N2 */ #define RD_N2_SID_VER_PART_NUM 0x07B7 diff --git a/plat/arm/css/sgi/sgi_bl31_setup.c b/plat/arm/css/sgi/sgi_bl31_setup.c index d5c7593f6..89e2cab08 100644 --- a/plat/arm/css/sgi/sgi_bl31_setup.c +++ b/plat/arm/css/sgi/sgi_bl31_setup.c @@ -74,7 +74,7 @@ static scmi_channel_plat_info_t rd_n1e1_edge_scmi_plat_info[] = { scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id) { if (sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM || - sgi_plat_info.platform_id == RD_DANIEL_SID_VER_PART_NUM || + sgi_plat_info.platform_id == RD_V1_SID_VER_PART_NUM || sgi_plat_info.platform_id == RD_N2_SID_VER_PART_NUM) { if (channel_id >= ARRAY_SIZE(rd_n1e1_edge_scmi_plat_info)) panic(); @@ -108,12 +108,12 @@ void sgi_bl31_common_platform_setup(void) const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops) { /* - * For RD-E1-Edge and RD-Daniel platforms, only CPU power ON/OFF + * For RD-E1-Edge and RD-V1 platforms, only CPU power ON/OFF * PSCI platform callbacks are supported. */ if (((sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM) && (sgi_plat_info.config_id == RD_E1_EDGE_CONFIG_ID)) || - (sgi_plat_info.platform_id == RD_DANIEL_SID_VER_PART_NUM)) { + (sgi_plat_info.platform_id == RD_V1_SID_VER_PART_NUM)) { ops->cpu_standby = NULL; ops->system_off = NULL; ops->system_reset = NULL; -- cgit v1.2.3 From 90aecf1e0adec8bb88bf6737408af8a30e21c741 Mon Sep 17 00:00:00 2001 From: Aditya Angadi Date: Tue, 15 Dec 2020 17:28:08 +0530 Subject: plat/arm: rename rddanielxlr to rdv1mc Reference Design platform RD-Daniel-ConfigXLR has been renamed to RD-V1-MC. Correspondingly, remove all uses of 'rddanielxlr' and replace it with 'rdv1mc' where appropriate. Signed-off-by: Aditya Angadi Change-Id: I5d91c69738397b19ced43949b4080c74678e604c --- .../rddanielxlr/fdts/rddanielxlr_fw_config.dts | 27 ----- .../rddanielxlr/fdts/rddanielxlr_nt_fw_config.dts | 22 ---- .../rddanielxlr/fdts/rddanielxlr_tb_fw_config.dts | 28 ----- plat/arm/board/rddanielxlr/include/platform_def.h | 37 ------ plat/arm/board/rddanielxlr/platform.mk | 68 ----------- plat/arm/board/rddanielxlr/rddanielxlr_err.c | 17 --- plat/arm/board/rddanielxlr/rddanielxlr_plat.c | 131 --------------------- plat/arm/board/rddanielxlr/rddanielxlr_security.c | 10 -- plat/arm/board/rddanielxlr/rddanielxlr_topology.c | 78 ------------ .../board/rddanielxlr/rddanielxlr_trusted_boot.c | 26 ---- plat/arm/board/rdv1mc/fdts/rdv1mc_fw_config.dts | 27 +++++ plat/arm/board/rdv1mc/fdts/rdv1mc_nt_fw_config.dts | 22 ++++ plat/arm/board/rdv1mc/fdts/rdv1mc_tb_fw_config.dts | 28 +++++ plat/arm/board/rdv1mc/include/platform_def.h | 37 ++++++ plat/arm/board/rdv1mc/platform.mk | 68 +++++++++++ plat/arm/board/rdv1mc/rdv1mc_err.c | 17 +++ plat/arm/board/rdv1mc/rdv1mc_plat.c | 131 +++++++++++++++++++++ plat/arm/board/rdv1mc/rdv1mc_security.c | 10 ++ plat/arm/board/rdv1mc/rdv1mc_topology.c | 78 ++++++++++++ plat/arm/board/rdv1mc/rdv1mc_trusted_boot.c | 26 ++++ 20 files changed, 444 insertions(+), 444 deletions(-) delete mode 100644 plat/arm/board/rddanielxlr/fdts/rddanielxlr_fw_config.dts delete mode 100644 plat/arm/board/rddanielxlr/fdts/rddanielxlr_nt_fw_config.dts delete mode 100644 plat/arm/board/rddanielxlr/fdts/rddanielxlr_tb_fw_config.dts delete mode 100644 plat/arm/board/rddanielxlr/include/platform_def.h delete mode 100644 plat/arm/board/rddanielxlr/platform.mk delete mode 100644 plat/arm/board/rddanielxlr/rddanielxlr_err.c delete mode 100644 plat/arm/board/rddanielxlr/rddanielxlr_plat.c delete mode 100644 plat/arm/board/rddanielxlr/rddanielxlr_security.c delete mode 100644 plat/arm/board/rddanielxlr/rddanielxlr_topology.c delete mode 100644 plat/arm/board/rddanielxlr/rddanielxlr_trusted_boot.c create mode 100644 plat/arm/board/rdv1mc/fdts/rdv1mc_fw_config.dts create mode 100644 plat/arm/board/rdv1mc/fdts/rdv1mc_nt_fw_config.dts create mode 100644 plat/arm/board/rdv1mc/fdts/rdv1mc_tb_fw_config.dts create mode 100644 plat/arm/board/rdv1mc/include/platform_def.h create mode 100644 plat/arm/board/rdv1mc/platform.mk create mode 100644 plat/arm/board/rdv1mc/rdv1mc_err.c create mode 100644 plat/arm/board/rdv1mc/rdv1mc_plat.c create mode 100644 plat/arm/board/rdv1mc/rdv1mc_security.c create mode 100644 plat/arm/board/rdv1mc/rdv1mc_topology.c create mode 100644 plat/arm/board/rdv1mc/rdv1mc_trusted_boot.c diff --git a/plat/arm/board/rddanielxlr/fdts/rddanielxlr_fw_config.dts b/plat/arm/board/rddanielxlr/fdts/rddanielxlr_fw_config.dts deleted file mode 100644 index 9c9cefe87..000000000 --- a/plat/arm/board/rddanielxlr/fdts/rddanielxlr_fw_config.dts +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -/dts-v1/; - -/ { - dtb-registry { - compatible = "fconf,dyn_cfg-dtb_registry"; - - tb_fw-config { - load-address = <0x0 0x4001300>; - max-size = <0x200>; - id = ; - }; - - nt_fw-config { - load-address = <0x0 0xFEF00000>; - max-size = <0x0100000>; - id = ; - }; - }; -}; diff --git a/plat/arm/board/rddanielxlr/fdts/rddanielxlr_nt_fw_config.dts b/plat/arm/board/rddanielxlr/fdts/rddanielxlr_nt_fw_config.dts deleted file mode 100644 index 42d07a450..000000000 --- a/plat/arm/board/rddanielxlr/fdts/rddanielxlr_nt_fw_config.dts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/dts-v1/; -/ { - /* compatible string */ - compatible = "arm,rd-daniel-xlr"; - - /* - * Place holder for system-id node with default values. The - * value of platform-id and config-id will be set to the - * correct values during the BL2 stage of boot. - */ - system-id { - platform-id = <0x0>; - config-id = <0x0>; - multi-chip-mode = <0x0>; - }; -}; diff --git a/plat/arm/board/rddanielxlr/fdts/rddanielxlr_tb_fw_config.dts b/plat/arm/board/rddanielxlr/fdts/rddanielxlr_tb_fw_config.dts deleted file mode 100644 index 49eda2735..000000000 --- a/plat/arm/board/rddanielxlr/fdts/rddanielxlr_tb_fw_config.dts +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/dts-v1/; - -/ { - tb_fw-config { - compatible = "arm,tb_fw"; - - /* Disable authentication for development */ - disable_auth = <0x0>; - - /* - * The following two entries are placeholders for Mbed TLS - * heap information. The default values don't matter since - * they will be overwritten by BL1. - * In case of having shared Mbed TLS heap between BL1 and BL2, - * BL1 will populate these two properties with the respective - * info about the shared heap. This info will be available for - * BL2 in order to locate and re-use the heap. - */ - mbedtls_heap_addr = <0x0 0x0>; - mbedtls_heap_size = <0x0>; - }; -}; diff --git a/plat/arm/board/rddanielxlr/include/platform_def.h b/plat/arm/board/rddanielxlr/include/platform_def.h deleted file mode 100644 index 112b2102b..000000000 --- a/plat/arm/board/rddanielxlr/include/platform_def.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef PLATFORM_DEF_H -#define PLATFORM_DEF_H - -#include -#include - -#define PLAT_ARM_CLUSTER_COUNT U(4) -#define CSS_SGI_MAX_CPUS_PER_CLUSTER U(1) -#define CSS_SGI_MAX_PE_PER_CPU U(1) - -#define PLAT_CSS_MHU_BASE UL(0x45400000) -#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE - -#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL2 -#define PLAT_MAX_PWR_LVL ARM_PWR_LVL1 - -/* Virtual address used by dynamic mem_protect for chunk_base */ -#define PLAT_ARM_MEM_PROTEC_VA_FRAME UL(0xC0000000) - -/* Physical and virtual address space limits for MMU in AARCH64 mode */ -#define PLAT_PHY_ADDR_SPACE_SIZE CSS_SGI_REMOTE_CHIP_MEM_OFFSET( \ - CSS_SGI_CHIP_COUNT) -#define PLAT_VIRT_ADDR_SPACE_SIZE CSS_SGI_REMOTE_CHIP_MEM_OFFSET( \ - CSS_SGI_CHIP_COUNT) - -/* GIC related constants */ -#define PLAT_ARM_GICD_BASE UL(0x30000000) -#define PLAT_ARM_GICC_BASE UL(0x2C000000) -#define PLAT_ARM_GICR_BASE UL(0x30140000) - -#endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/rddanielxlr/platform.mk b/plat/arm/board/rddanielxlr/platform.mk deleted file mode 100644 index 2f41e2e72..000000000 --- a/plat/arm/board/rddanielxlr/platform.mk +++ /dev/null @@ -1,68 +0,0 @@ -# Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. -# -# SPDX-License-Identifier: BSD-3-Clause -# - -# Enable GICv4 extension with multichip driver -GIC_ENABLE_V4_EXTN := 1 -GICV3_IMPL_GIC600_MULTICHIP := 1 - -include plat/arm/css/sgi/sgi-common.mk - -RDDANIELXLR_BASE = plat/arm/board/rddanielxlr - -PLAT_INCLUDES += -I${RDDANIELXLR_BASE}/include/ - -SGI_CPU_SOURCES := lib/cpus/aarch64/neoverse_v1.S - -PLAT_BL_COMMON_SOURCES += ${CSS_ENT_BASE}/sgi_plat.c - -BL1_SOURCES += ${SGI_CPU_SOURCES} \ - ${RDDANIELXLR_BASE}/rddanielxlr_err.c - -BL2_SOURCES += ${RDDANIELXLR_BASE}/rddanielxlr_plat.c \ - ${RDDANIELXLR_BASE}/rddanielxlr_security.c \ - ${RDDANIELXLR_BASE}/rddanielxlr_err.c \ - lib/utils/mem_region.c \ - plat/arm/common/arm_nor_psci_mem_protect.c - -BL31_SOURCES += ${SGI_CPU_SOURCES} \ - ${RDDANIELXLR_BASE}/rddanielxlr_plat.c \ - ${RDDANIELXLR_BASE}/rddanielxlr_topology.c \ - drivers/cfi/v2m/v2m_flash.c \ - drivers/arm/gic/v3/gic600_multichip.c \ - lib/utils/mem_region.c \ - plat/arm/common/arm_nor_psci_mem_protect.c - -ifeq (${TRUSTED_BOARD_BOOT}, 1) -BL1_SOURCES += ${RDDANIELXLR_BASE}/rddanielxlr_trusted_boot.c -BL2_SOURCES += ${RDDANIELXLR_BASE}/rddanielxlr_trusted_boot.c -endif - -# Enable dynamic addition of MMAP regions in BL31 -BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC - -# Add the FDT_SOURCES and options for Dynamic Config -FDT_SOURCES += ${RDDANIELXLR_BASE}/fdts/${PLAT}_fw_config.dts \ - ${RDDANIELXLR_BASE}/fdts/${PLAT}_tb_fw_config.dts -FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb -TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb - -# Add the FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG})) -# Add the TB_FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG})) - -$(eval $(call CREATE_SEQ,SEQ,4)) -ifneq ($(CSS_SGI_CHIP_COUNT),$(filter $(CSS_SGI_CHIP_COUNT),$(SEQ))) - $(error "Chip count for RD-Daniel Config-XLR should be either $(SEQ) \ - currently it is set to ${CSS_SGI_CHIP_COUNT}.") -endif - -FDT_SOURCES += ${RDDANIELXLR_BASE}/fdts/${PLAT}_nt_fw_config.dts -NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb - -# Add the NT_FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config,${NT_FW_CONFIG})) - -override CTX_INCLUDE_AARCH32_REGS := 0 diff --git a/plat/arm/board/rddanielxlr/rddanielxlr_err.c b/plat/arm/board/rddanielxlr/rddanielxlr_err.c deleted file mode 100644 index bff57cdae..000000000 --- a/plat/arm/board/rddanielxlr/rddanielxlr_err.c +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -/* - * rddanielxlr error handler - */ -void __dead2 plat_arm_error_handler(int err) -{ - while (true) { - wfi(); - } -} diff --git a/plat/arm/board/rddanielxlr/rddanielxlr_plat.c b/plat/arm/board/rddanielxlr/rddanielxlr_plat.c deleted file mode 100644 index a1a4876c0..000000000 --- a/plat/arm/board/rddanielxlr/rddanielxlr_plat.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include -#include -#include -#include - -#if defined(IMAGE_BL31) -static const mmap_region_t rddanielxlr_dynamic_mmap[] = { - ARM_MAP_SHARED_RAM_REMOTE_CHIP(1), - CSS_SGI_MAP_DEVICE_REMOTE_CHIP(1), - SOC_CSS_MAP_DEVICE_REMOTE_CHIP(1), -#if (CSS_SGI_CHIP_COUNT > 2) - ARM_MAP_SHARED_RAM_REMOTE_CHIP(2), - CSS_SGI_MAP_DEVICE_REMOTE_CHIP(2), - SOC_CSS_MAP_DEVICE_REMOTE_CHIP(2), -#endif -#if (CSS_SGI_CHIP_COUNT > 3) - ARM_MAP_SHARED_RAM_REMOTE_CHIP(3), - CSS_SGI_MAP_DEVICE_REMOTE_CHIP(3), - SOC_CSS_MAP_DEVICE_REMOTE_CHIP(3) -#endif -}; - -static struct gic600_multichip_data rddanielxlr_multichip_data __init = { - .rt_owner_base = PLAT_ARM_GICD_BASE, - .rt_owner = 0, - .chip_count = CSS_SGI_CHIP_COUNT, - .chip_addrs = { - PLAT_ARM_GICD_BASE >> 16, - (PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1)) >> 16, -#if (CSS_SGI_CHIP_COUNT > 2) - (PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(2)) >> 16, -#endif -#if (CSS_SGI_CHIP_COUNT > 3) - (PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(3)) >> 16, -#endif - }, - .spi_ids = { - {32, 255}, - {0, 0}, -#if (CSS_SGI_CHIP_COUNT > 2) - {0, 0}, -#endif -#if (CSS_SGI_CHIP_COUNT > 3) - {0, 0}, -#endif - } -}; - -static uintptr_t rddanielxlr_multichip_gicr_frames[] = { - /* Chip 0's GICR Base */ - PLAT_ARM_GICR_BASE, - /* Chip 1's GICR BASE */ - PLAT_ARM_GICR_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1), -#if (CSS_SGI_CHIP_COUNT > 2) - /* Chip 2's GICR BASE */ - PLAT_ARM_GICR_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(2), -#endif -#if (CSS_SGI_CHIP_COUNT > 3) - /* Chip 3's GICR BASE */ - PLAT_ARM_GICR_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(3), -#endif - UL(0) /* Zero Termination */ -}; -#endif /* IMAGE_BL31 */ - -unsigned int plat_arm_sgi_get_platform_id(void) -{ - return mmio_read_32(SID_REG_BASE + SID_SYSTEM_ID_OFFSET) - & SID_SYSTEM_ID_PART_NUM_MASK; -} - -unsigned int plat_arm_sgi_get_config_id(void) -{ - return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET); -} - -unsigned int plat_arm_sgi_get_multi_chip_mode(void) -{ - return (mmio_read_32(SID_REG_BASE + SID_NODE_ID_OFFSET) & - SID_MULTI_CHIP_MODE_MASK) >> SID_MULTI_CHIP_MODE_SHIFT; -} - -/* - * bl31_platform_setup_function is guarded by IMAGE_BL31 macro because - * PLAT_XLAT_TABLES_DYNAMIC macro is set to build only for BL31 and not - * for other stages. - */ -#if defined(IMAGE_BL31) -void bl31_platform_setup(void) -{ - int ret; - unsigned int i; - - if ((plat_arm_sgi_get_multi_chip_mode() == 0) && - (CSS_SGI_CHIP_COUNT > 1)) { - ERROR("Chip Count is set to %u but multi-chip mode is not " - "enabled\n", CSS_SGI_CHIP_COUNT); - panic(); - } else if ((plat_arm_sgi_get_multi_chip_mode() == 1) && - (CSS_SGI_CHIP_COUNT > 1)) { - INFO("Enabling support for multi-chip in RD-Daniel Cfg-XLR\n"); - - for (i = 0; i < ARRAY_SIZE(rddanielxlr_dynamic_mmap); i++) { - ret = mmap_add_dynamic_region( - rddanielxlr_dynamic_mmap[i].base_pa, - rddanielxlr_dynamic_mmap[i].base_va, - rddanielxlr_dynamic_mmap[i].size, - rddanielxlr_dynamic_mmap[i].attr); - if (ret != 0) { - ERROR("Failed to add dynamic mmap entry " - "(ret=%d)\n", ret); - panic(); - } - } - - plat_arm_override_gicr_frames( - rddanielxlr_multichip_gicr_frames); - gic600_multichip_init(&rddanielxlr_multichip_data); - } - - sgi_bl31_common_platform_setup(); -} -#endif /* IMAGE_BL31 */ diff --git a/plat/arm/board/rddanielxlr/rddanielxlr_security.c b/plat/arm/board/rddanielxlr/rddanielxlr_security.c deleted file mode 100644 index 541f800a8..000000000 --- a/plat/arm/board/rddanielxlr/rddanielxlr_security.c +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* Initialize the secure environment */ -void plat_arm_security_setup(void) -{ -} diff --git a/plat/arm/board/rddanielxlr/rddanielxlr_topology.c b/plat/arm/board/rddanielxlr/rddanielxlr_topology.c deleted file mode 100644 index 610e667ce..000000000 --- a/plat/arm/board/rddanielxlr/rddanielxlr_topology.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include -#include - -/****************************************************************************** - * The power domain tree descriptor. - ******************************************************************************/ -const unsigned char rd_daniel_xlr_pd_tree_desc_multi_chip[] = { - ((PLAT_ARM_CLUSTER_COUNT) * (CSS_SGI_CHIP_COUNT)), - CSS_SGI_MAX_CPUS_PER_CLUSTER, - CSS_SGI_MAX_CPUS_PER_CLUSTER, - CSS_SGI_MAX_CPUS_PER_CLUSTER, - CSS_SGI_MAX_CPUS_PER_CLUSTER, -#if (CSS_SGI_CHIP_COUNT > 1) - CSS_SGI_MAX_CPUS_PER_CLUSTER, - CSS_SGI_MAX_CPUS_PER_CLUSTER, - CSS_SGI_MAX_CPUS_PER_CLUSTER, - CSS_SGI_MAX_CPUS_PER_CLUSTER, -#endif -#if (CSS_SGI_CHIP_COUNT > 2) - CSS_SGI_MAX_CPUS_PER_CLUSTER, - CSS_SGI_MAX_CPUS_PER_CLUSTER, - CSS_SGI_MAX_CPUS_PER_CLUSTER, - CSS_SGI_MAX_CPUS_PER_CLUSTER, -#endif -#if (CSS_SGI_CHIP_COUNT > 3) - CSS_SGI_MAX_CPUS_PER_CLUSTER, - CSS_SGI_MAX_CPUS_PER_CLUSTER, - CSS_SGI_MAX_CPUS_PER_CLUSTER, - CSS_SGI_MAX_CPUS_PER_CLUSTER -#endif -}; - -/******************************************************************************* - * This function returns the topology tree information. - ******************************************************************************/ -const unsigned char *plat_get_power_domain_tree_desc(void) -{ - if (plat_arm_sgi_get_multi_chip_mode() == 1) - return rd_daniel_xlr_pd_tree_desc_multi_chip; - panic(); -} - -/******************************************************************************* - * The array mapping platform core position (implemented by plat_my_core_pos()) - * to the SCMI power domain ID implemented by SCP. - ******************************************************************************/ -const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = { - (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x0)), - (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x1)), - (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x2)), - (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x3)), -#if (CSS_SGI_CHIP_COUNT > 1) - (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x0)), - (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x1)), - (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x2)), - (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x3)), -#endif -#if (CSS_SGI_CHIP_COUNT > 2) - (SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x0)), - (SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x1)), - (SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x2)), - (SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x3)), -#endif -#if (CSS_SGI_CHIP_COUNT > 3) - (SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x0)), - (SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x1)), - (SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x2)), - (SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x3)) -#endif -}; diff --git a/plat/arm/board/rddanielxlr/rddanielxlr_trusted_boot.c b/plat/arm/board/rddanielxlr/rddanielxlr_trusted_boot.c deleted file mode 100644 index 4592b8fba..000000000 --- a/plat/arm/board/rddanielxlr/rddanielxlr_trusted_boot.c +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2020, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#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); -} diff --git a/plat/arm/board/rdv1mc/fdts/rdv1mc_fw_config.dts b/plat/arm/board/rdv1mc/fdts/rdv1mc_fw_config.dts new file mode 100644 index 000000000..9c9cefe87 --- /dev/null +++ b/plat/arm/board/rdv1mc/fdts/rdv1mc_fw_config.dts @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +/dts-v1/; + +/ { + dtb-registry { + compatible = "fconf,dyn_cfg-dtb_registry"; + + tb_fw-config { + load-address = <0x0 0x4001300>; + max-size = <0x200>; + id = ; + }; + + nt_fw-config { + load-address = <0x0 0xFEF00000>; + max-size = <0x0100000>; + id = ; + }; + }; +}; diff --git a/plat/arm/board/rdv1mc/fdts/rdv1mc_nt_fw_config.dts b/plat/arm/board/rdv1mc/fdts/rdv1mc_nt_fw_config.dts new file mode 100644 index 000000000..71c7db3cb --- /dev/null +++ b/plat/arm/board/rdv1mc/fdts/rdv1mc_nt_fw_config.dts @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; +/ { + /* compatible string */ + compatible = "arm,rd-v1-mc"; + + /* + * Place holder for system-id node with default values. The + * value of platform-id and config-id will be set to the + * correct values during the BL2 stage of boot. + */ + system-id { + platform-id = <0x0>; + config-id = <0x0>; + multi-chip-mode = <0x0>; + }; +}; diff --git a/plat/arm/board/rdv1mc/fdts/rdv1mc_tb_fw_config.dts b/plat/arm/board/rdv1mc/fdts/rdv1mc_tb_fw_config.dts new file mode 100644 index 000000000..49eda2735 --- /dev/null +++ b/plat/arm/board/rdv1mc/fdts/rdv1mc_tb_fw_config.dts @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +/ { + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + + /* + * The following two entries are placeholders for Mbed TLS + * heap information. The default values don't matter since + * they will be overwritten by BL1. + * In case of having shared Mbed TLS heap between BL1 and BL2, + * BL1 will populate these two properties with the respective + * info about the shared heap. This info will be available for + * BL2 in order to locate and re-use the heap. + */ + mbedtls_heap_addr = <0x0 0x0>; + mbedtls_heap_size = <0x0>; + }; +}; diff --git a/plat/arm/board/rdv1mc/include/platform_def.h b/plat/arm/board/rdv1mc/include/platform_def.h new file mode 100644 index 000000000..112b2102b --- /dev/null +++ b/plat/arm/board/rdv1mc/include/platform_def.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +#include +#include + +#define PLAT_ARM_CLUSTER_COUNT U(4) +#define CSS_SGI_MAX_CPUS_PER_CLUSTER U(1) +#define CSS_SGI_MAX_PE_PER_CPU U(1) + +#define PLAT_CSS_MHU_BASE UL(0x45400000) +#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE + +#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL2 +#define PLAT_MAX_PWR_LVL ARM_PWR_LVL1 + +/* Virtual address used by dynamic mem_protect for chunk_base */ +#define PLAT_ARM_MEM_PROTEC_VA_FRAME UL(0xC0000000) + +/* Physical and virtual address space limits for MMU in AARCH64 mode */ +#define PLAT_PHY_ADDR_SPACE_SIZE CSS_SGI_REMOTE_CHIP_MEM_OFFSET( \ + CSS_SGI_CHIP_COUNT) +#define PLAT_VIRT_ADDR_SPACE_SIZE CSS_SGI_REMOTE_CHIP_MEM_OFFSET( \ + CSS_SGI_CHIP_COUNT) + +/* GIC related constants */ +#define PLAT_ARM_GICD_BASE UL(0x30000000) +#define PLAT_ARM_GICC_BASE UL(0x2C000000) +#define PLAT_ARM_GICR_BASE UL(0x30140000) + +#endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/rdv1mc/platform.mk b/plat/arm/board/rdv1mc/platform.mk new file mode 100644 index 000000000..50728416a --- /dev/null +++ b/plat/arm/board/rdv1mc/platform.mk @@ -0,0 +1,68 @@ +# Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# Enable GICv4 extension with multichip driver +GIC_ENABLE_V4_EXTN := 1 +GICV3_IMPL_GIC600_MULTICHIP := 1 + +include plat/arm/css/sgi/sgi-common.mk + +RDV1MC_BASE = plat/arm/board/rdv1mc + +PLAT_INCLUDES += -I${RDV1MC_BASE}/include/ + +SGI_CPU_SOURCES := lib/cpus/aarch64/neoverse_v1.S + +PLAT_BL_COMMON_SOURCES += ${CSS_ENT_BASE}/sgi_plat.c + +BL1_SOURCES += ${SGI_CPU_SOURCES} \ + ${RDV1MC_BASE}/rdv1mc_err.c + +BL2_SOURCES += ${RDV1MC_BASE}/rdv1mc_plat.c \ + ${RDV1MC_BASE}/rdv1mc_security.c \ + ${RDV1MC_BASE}/rdv1mc_err.c \ + lib/utils/mem_region.c \ + plat/arm/common/arm_nor_psci_mem_protect.c + +BL31_SOURCES += ${SGI_CPU_SOURCES} \ + ${RDV1MC_BASE}/rdv1mc_plat.c \ + ${RDV1MC_BASE}/rdv1mc_topology.c \ + drivers/cfi/v2m/v2m_flash.c \ + drivers/arm/gic/v3/gic600_multichip.c \ + lib/utils/mem_region.c \ + plat/arm/common/arm_nor_psci_mem_protect.c + +ifeq (${TRUSTED_BOARD_BOOT}, 1) +BL1_SOURCES += ${RDV1MC_BASE}/rdv1mc_trusted_boot.c +BL2_SOURCES += ${RDV1MC_BASE}/rdv1mc_trusted_boot.c +endif + +# Enable dynamic addition of MMAP regions in BL31 +BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC + +# Add the FDT_SOURCES and options for Dynamic Config +FDT_SOURCES += ${RDV1MC_BASE}/fdts/${PLAT}_fw_config.dts \ + ${RDV1MC_BASE}/fdts/${PLAT}_tb_fw_config.dts +FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb + +# Add the FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG})) +# Add the TB_FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG})) + +$(eval $(call CREATE_SEQ,SEQ,4)) +ifneq ($(CSS_SGI_CHIP_COUNT),$(filter $(CSS_SGI_CHIP_COUNT),$(SEQ))) + $(error "Chip count for RD-V1-MC should be either $(SEQ) \ + currently it is set to ${CSS_SGI_CHIP_COUNT}.") +endif + +FDT_SOURCES += ${RDV1MC_BASE}/fdts/${PLAT}_nt_fw_config.dts +NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb + +# Add the NT_FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config,${NT_FW_CONFIG})) + +override CTX_INCLUDE_AARCH32_REGS := 0 diff --git a/plat/arm/board/rdv1mc/rdv1mc_err.c b/plat/arm/board/rdv1mc/rdv1mc_err.c new file mode 100644 index 000000000..755a5034e --- /dev/null +++ b/plat/arm/board/rdv1mc/rdv1mc_err.c @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +/* + * rdv1mc error handler + */ +void __dead2 plat_arm_error_handler(int err) +{ + while (true) { + wfi(); + } +} diff --git a/plat/arm/board/rdv1mc/rdv1mc_plat.c b/plat/arm/board/rdv1mc/rdv1mc_plat.c new file mode 100644 index 000000000..d85940066 --- /dev/null +++ b/plat/arm/board/rdv1mc/rdv1mc_plat.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include + +#if defined(IMAGE_BL31) +static const mmap_region_t rdv1mc_dynamic_mmap[] = { + ARM_MAP_SHARED_RAM_REMOTE_CHIP(1), + CSS_SGI_MAP_DEVICE_REMOTE_CHIP(1), + SOC_CSS_MAP_DEVICE_REMOTE_CHIP(1), +#if (CSS_SGI_CHIP_COUNT > 2) + ARM_MAP_SHARED_RAM_REMOTE_CHIP(2), + CSS_SGI_MAP_DEVICE_REMOTE_CHIP(2), + SOC_CSS_MAP_DEVICE_REMOTE_CHIP(2), +#endif +#if (CSS_SGI_CHIP_COUNT > 3) + ARM_MAP_SHARED_RAM_REMOTE_CHIP(3), + CSS_SGI_MAP_DEVICE_REMOTE_CHIP(3), + SOC_CSS_MAP_DEVICE_REMOTE_CHIP(3) +#endif +}; + +static struct gic600_multichip_data rdv1mc_multichip_data __init = { + .rt_owner_base = PLAT_ARM_GICD_BASE, + .rt_owner = 0, + .chip_count = CSS_SGI_CHIP_COUNT, + .chip_addrs = { + PLAT_ARM_GICD_BASE >> 16, + (PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1)) >> 16, +#if (CSS_SGI_CHIP_COUNT > 2) + (PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(2)) >> 16, +#endif +#if (CSS_SGI_CHIP_COUNT > 3) + (PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(3)) >> 16, +#endif + }, + .spi_ids = { + {32, 255}, + {0, 0}, +#if (CSS_SGI_CHIP_COUNT > 2) + {0, 0}, +#endif +#if (CSS_SGI_CHIP_COUNT > 3) + {0, 0}, +#endif + } +}; + +static uintptr_t rdv1mc_multichip_gicr_frames[] = { + /* Chip 0's GICR Base */ + PLAT_ARM_GICR_BASE, + /* Chip 1's GICR BASE */ + PLAT_ARM_GICR_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1), +#if (CSS_SGI_CHIP_COUNT > 2) + /* Chip 2's GICR BASE */ + PLAT_ARM_GICR_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(2), +#endif +#if (CSS_SGI_CHIP_COUNT > 3) + /* Chip 3's GICR BASE */ + PLAT_ARM_GICR_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(3), +#endif + UL(0) /* Zero Termination */ +}; +#endif /* IMAGE_BL31 */ + +unsigned int plat_arm_sgi_get_platform_id(void) +{ + return mmio_read_32(SID_REG_BASE + SID_SYSTEM_ID_OFFSET) + & SID_SYSTEM_ID_PART_NUM_MASK; +} + +unsigned int plat_arm_sgi_get_config_id(void) +{ + return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET); +} + +unsigned int plat_arm_sgi_get_multi_chip_mode(void) +{ + return (mmio_read_32(SID_REG_BASE + SID_NODE_ID_OFFSET) & + SID_MULTI_CHIP_MODE_MASK) >> SID_MULTI_CHIP_MODE_SHIFT; +} + +/* + * bl31_platform_setup_function is guarded by IMAGE_BL31 macro because + * PLAT_XLAT_TABLES_DYNAMIC macro is set to build only for BL31 and not + * for other stages. + */ +#if defined(IMAGE_BL31) +void bl31_platform_setup(void) +{ + int ret; + unsigned int i; + + if ((plat_arm_sgi_get_multi_chip_mode() == 0) && + (CSS_SGI_CHIP_COUNT > 1)) { + ERROR("Chip Count is set to %u but multi-chip mode is not " + "enabled\n", CSS_SGI_CHIP_COUNT); + panic(); + } else if ((plat_arm_sgi_get_multi_chip_mode() == 1) && + (CSS_SGI_CHIP_COUNT > 1)) { + INFO("Enabling support for multi-chip in RD-V1-MC\n"); + + for (i = 0; i < ARRAY_SIZE(rdv1mc_dynamic_mmap); i++) { + ret = mmap_add_dynamic_region( + rdv1mc_dynamic_mmap[i].base_pa, + rdv1mc_dynamic_mmap[i].base_va, + rdv1mc_dynamic_mmap[i].size, + rdv1mc_dynamic_mmap[i].attr); + if (ret != 0) { + ERROR("Failed to add dynamic mmap entry " + "(ret=%d)\n", ret); + panic(); + } + } + + plat_arm_override_gicr_frames( + rdv1mc_multichip_gicr_frames); + gic600_multichip_init(&rdv1mc_multichip_data); + } + + sgi_bl31_common_platform_setup(); +} +#endif /* IMAGE_BL31 */ diff --git a/plat/arm/board/rdv1mc/rdv1mc_security.c b/plat/arm/board/rdv1mc/rdv1mc_security.c new file mode 100644 index 000000000..541f800a8 --- /dev/null +++ b/plat/arm/board/rdv1mc/rdv1mc_security.c @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* Initialize the secure environment */ +void plat_arm_security_setup(void) +{ +} diff --git a/plat/arm/board/rdv1mc/rdv1mc_topology.c b/plat/arm/board/rdv1mc/rdv1mc_topology.c new file mode 100644 index 000000000..4486e5cfa --- /dev/null +++ b/plat/arm/board/rdv1mc/rdv1mc_topology.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +/****************************************************************************** + * The power domain tree descriptor. + ******************************************************************************/ +const unsigned char rd_v1_mc_pd_tree_desc_multi_chip[] = { + ((PLAT_ARM_CLUSTER_COUNT) * (CSS_SGI_CHIP_COUNT)), + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, +#if (CSS_SGI_CHIP_COUNT > 1) + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, +#endif +#if (CSS_SGI_CHIP_COUNT > 2) + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, +#endif +#if (CSS_SGI_CHIP_COUNT > 3) + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER +#endif +}; + +/******************************************************************************* + * This function returns the topology tree information. + ******************************************************************************/ +const unsigned char *plat_get_power_domain_tree_desc(void) +{ + if (plat_arm_sgi_get_multi_chip_mode() == 1) + return rd_v1_mc_pd_tree_desc_multi_chip; + panic(); +} + +/******************************************************************************* + * The array mapping platform core position (implemented by plat_my_core_pos()) + * to the SCMI power domain ID implemented by SCP. + ******************************************************************************/ +const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = { + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x0)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x1)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x2)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x3)), +#if (CSS_SGI_CHIP_COUNT > 1) + (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x0)), + (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x1)), + (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x2)), + (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x3)), +#endif +#if (CSS_SGI_CHIP_COUNT > 2) + (SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x0)), + (SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x1)), + (SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x2)), + (SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x3)), +#endif +#if (CSS_SGI_CHIP_COUNT > 3) + (SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x0)), + (SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x1)), + (SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x2)), + (SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x3)) +#endif +}; diff --git a/plat/arm/board/rdv1mc/rdv1mc_trusted_boot.c b/plat/arm/board/rdv1mc/rdv1mc_trusted_boot.c new file mode 100644 index 000000000..4592b8fba --- /dev/null +++ b/plat/arm/board/rdv1mc/rdv1mc_trusted_boot.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#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); +} -- cgit v1.2.3 From c58633854b379713ce97091b1513252b4e420605 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Sun, 13 Dec 2020 20:05:24 +0000 Subject: drivers: renesas: rcar: iic_dvfs: Fix coding style Sort the header includes alphabetically, fix typos and drop unneeded TAB and replace it with space Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: I62e2658b0309c0985dd32ff023b8b16bd7f2be8e --- drivers/renesas/rcar/iic_dvfs/iic_dvfs.c | 259 +++++++++++++++++-------------- drivers/renesas/rcar/iic_dvfs/iic_dvfs.h | 14 +- 2 files changed, 152 insertions(+), 121 deletions(-) diff --git a/drivers/renesas/rcar/iic_dvfs/iic_dvfs.c b/drivers/renesas/rcar/iic_dvfs/iic_dvfs.c index 28b56c10e..e1c9a5bd4 100644 --- a/drivers/renesas/rcar/iic_dvfs/iic_dvfs.c +++ b/drivers/renesas/rcar/iic_dvfs/iic_dvfs.c @@ -1,5 +1,5 @@ /* - * 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 */ @@ -7,59 +7,59 @@ #include #include -#include "rcar_def.h" #include "cpg_registers.h" #include "iic_dvfs.h" +#include "rcar_def.h" #include "rcar_private.h" #define DVFS_RETRY_MAX (2U) -#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_0 (0x07) -#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_1 (0x09) -#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_2 (0x0B) -#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_3 (0x0E) -#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_E (0x15) - -#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_0 (0x01) -#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_1 (0x02) -#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_2 (0x03) -#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_3 (0x05) -#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_E (0x07) - -#define CPG_BIT_SMSTPCR9_DVFS (0x04000000) - -#define IIC_DVFS_REG_BASE (0xE60B0000) -#define IIC_DVFS_REG_ICDR (IIC_DVFS_REG_BASE + 0x0000) -#define IIC_DVFS_REG_ICCR (IIC_DVFS_REG_BASE + 0x0004) -#define IIC_DVFS_REG_ICSR (IIC_DVFS_REG_BASE + 0x0008) -#define IIC_DVFS_REG_ICIC (IIC_DVFS_REG_BASE + 0x000C) -#define IIC_DVFS_REG_ICCL (IIC_DVFS_REG_BASE + 0x0010) -#define IIC_DVFS_REG_ICCH (IIC_DVFS_REG_BASE + 0x0014) - -#define IIC_DVFS_BIT_ICSR_BUSY (0x10) -#define IIC_DVFS_BIT_ICSR_AL (0x08) -#define IIC_DVFS_BIT_ICSR_TACK (0x04) -#define IIC_DVFS_BIT_ICSR_WAIT (0x02) -#define IIC_DVFS_BIT_ICSR_DTE (0x01) - -#define IIC_DVFS_BIT_ICCR_ENABLE (0x80) -#define IIC_DVFS_SET_ICCR_START (0x94) -#define IIC_DVFS_SET_ICCR_STOP (0x90) -#define IIC_DVFS_SET_ICCR_RETRANSMISSION (0x94) -#define IIC_DVFS_SET_ICCR_CHANGE (0x81) -#define IIC_DVFS_SET_ICCR_STOP_READ (0xC0) - -#define IIC_DVFS_BIT_ICIC_TACKE (0x04) -#define IIC_DVFS_BIT_ICIC_WAITE (0x02) -#define IIC_DVFS_BIT_ICIC_DTEE (0x01) - -#define DVFS_READ_MODE (0x01) -#define DVFS_WRITE_MODE (0x00) - -#define IIC_DVFS_SET_DUMMY (0x52) +#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_0 (0x07U) +#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_1 (0x09U) +#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_2 (0x0BU) +#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_3 (0x0EU) +#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_E (0x15U) + +#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_0 (0x01U) +#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_1 (0x02U) +#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_2 (0x03U) +#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_3 (0x05U) +#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_E (0x07U) + +#define CPG_BIT_SMSTPCR9_DVFS (0x04000000U) + +#define IIC_DVFS_REG_BASE (0xE60B0000U) +#define IIC_DVFS_REG_ICDR (IIC_DVFS_REG_BASE + 0x0000U) +#define IIC_DVFS_REG_ICCR (IIC_DVFS_REG_BASE + 0x0004U) +#define IIC_DVFS_REG_ICSR (IIC_DVFS_REG_BASE + 0x0008U) +#define IIC_DVFS_REG_ICIC (IIC_DVFS_REG_BASE + 0x000CU) +#define IIC_DVFS_REG_ICCL (IIC_DVFS_REG_BASE + 0x0010U) +#define IIC_DVFS_REG_ICCH (IIC_DVFS_REG_BASE + 0x0014U) + +#define IIC_DVFS_BIT_ICSR_BUSY (0x10U) +#define IIC_DVFS_BIT_ICSR_AL (0x08U) +#define IIC_DVFS_BIT_ICSR_TACK (0x04U) +#define IIC_DVFS_BIT_ICSR_WAIT (0x02U) +#define IIC_DVFS_BIT_ICSR_DTE (0x01U) + +#define IIC_DVFS_BIT_ICCR_ENABLE (0x80U) +#define IIC_DVFS_SET_ICCR_START (0x94U) +#define IIC_DVFS_SET_ICCR_STOP (0x90U) +#define IIC_DVFS_SET_ICCR_RETRANSMISSION (0x94U) +#define IIC_DVFS_SET_ICCR_CHANGE (0x81U) +#define IIC_DVFS_SET_ICCR_STOP_READ (0xC0U) + +#define IIC_DVFS_BIT_ICIC_TACKE (0x04U) +#define IIC_DVFS_BIT_ICIC_WAITE (0x02U) +#define IIC_DVFS_BIT_ICIC_DTEE (0x01U) + +#define DVFS_READ_MODE (0x01U) +#define DVFS_WRITE_MODE (0x00U) + +#define IIC_DVFS_SET_DUMMY (0x52U) #define IIC_DVFS_SET_BUSY_LOOP (500000000U) -typedef enum { +enum dvfs_state_t { DVFS_START = 0, DVFS_STOP, DVFS_RETRANSMIT, @@ -69,9 +69,9 @@ typedef enum { DVFS_SET_SLAVE, DVFS_WRITE_ADDR, DVFS_WRITE_DATA, - DVFS_CHANGE_SEND_TO_RECIEVE, + DVFS_CHANGE_SEND_TO_RECEIVE, DVFS_DONE, -} DVFS_STATE_T; +}; #define DVFS_PROCESS (1) #define DVFS_COMPLETE (0) @@ -79,26 +79,26 @@ typedef enum { #if IMAGE_BL31 #define IIC_DVFS_FUNC(__name, ...) \ -static int32_t __attribute__ ((section (".system_ram"))) \ +static int32_t __attribute__ ((section(".system_ram"))) \ dvfs_ ##__name(__VA_ARGS__) #define RCAR_DVFS_API(__name, ...) \ -int32_t __attribute__ ((section (".system_ram"))) \ +int32_t __attribute__ ((section(".system_ram"))) \ rcar_iic_dvfs_ ##__name(__VA_ARGS__) #else -#define IIC_DVFS_FUNC(__name, ...) \ +#define IIC_DVFS_FUNC(__name, ...) \ static int32_t dvfs_ ##__name(__VA_ARGS__) #define RCAR_DVFS_API(__name, ...) \ int32_t rcar_iic_dvfs_ ##__name(__VA_ARGS__) #endif -IIC_DVFS_FUNC(check_error, DVFS_STATE_T *state, uint32_t *err, uint8_t mode) +IIC_DVFS_FUNC(check_error, enum dvfs_state_t *state, uint32_t *err, uint8_t mode) { - uint8_t icsr_al = 0, icsr_tack = 0; + uint8_t icsr_al = 0U, icsr_tack = 0U; uint8_t reg, stop; - uint32_t i = 0; + uint32_t i = 0U; stop = mode == DVFS_READ_MODE ? IIC_DVFS_SET_ICCR_STOP_READ : IIC_DVFS_SET_ICCR_STOP; @@ -107,43 +107,48 @@ IIC_DVFS_FUNC(check_error, DVFS_STATE_T *state, uint32_t *err, uint8_t mode) icsr_al = (reg & IIC_DVFS_BIT_ICSR_AL) == IIC_DVFS_BIT_ICSR_AL; icsr_tack = (reg & IIC_DVFS_BIT_ICSR_TACK) == IIC_DVFS_BIT_ICSR_TACK; - if (icsr_al == 0 && icsr_tack == 0) + if (icsr_al == 0U && icsr_tack == 0U) { return DVFS_PROCESS; + } if (icsr_al) { reg = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_AL; mmio_write_8(IIC_DVFS_REG_ICSR, reg); - if (*state == DVFS_SET_SLAVE) + if (*state == DVFS_SET_SLAVE) { mmio_write_8(IIC_DVFS_REG_ICDR, IIC_DVFS_SET_DUMMY); + } do { reg = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT; - } while (reg == 0); + } while (reg == 0U); mmio_write_8(IIC_DVFS_REG_ICCR, stop); reg = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT; mmio_write_8(IIC_DVFS_REG_ICSR, reg); - i = 0; + i = 0U; do { reg = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_BUSY; - if (reg == 0) + if (reg == 0U) { break; + } - if (i++ > IIC_DVFS_SET_BUSY_LOOP) + if (i++ > IIC_DVFS_SET_BUSY_LOOP) { panic(); + } - } while (1); + } while (true); mmio_write_8(IIC_DVFS_REG_ICCR, 0x00U); (*err)++; - if (*err > DVFS_RETRY_MAX) + if (*err > DVFS_RETRY_MAX) { return DVFS_ERROR; + } *state = DVFS_START; @@ -161,24 +166,26 @@ IIC_DVFS_FUNC(check_error, DVFS_STATE_T *state, uint32_t *err, uint8_t mode) reg = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_TACK; mmio_write_8(IIC_DVFS_REG_ICSR, reg); - i = 0; - while ((mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_BUSY) != 0) { - if (i++ > IIC_DVFS_SET_BUSY_LOOP) + i = 0U; + while ((mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_BUSY) != 0U) { + if (i++ > IIC_DVFS_SET_BUSY_LOOP) { panic(); + } } - mmio_write_8(IIC_DVFS_REG_ICCR, 0); + mmio_write_8(IIC_DVFS_REG_ICCR, 0U); (*err)++; - if (*err > DVFS_RETRY_MAX) + if (*err > DVFS_RETRY_MAX) { return DVFS_ERROR; + } *state = DVFS_START; return DVFS_PROCESS; } -IIC_DVFS_FUNC(start, DVFS_STATE_T * state) +IIC_DVFS_FUNC(start, enum dvfs_state_t *state) { uint8_t iccl = IIC_DVFS_SET_ICCL_EXTAL_TYPE_E; uint8_t icch = IIC_DVFS_SET_ICCH_EXTAL_TYPE_E; @@ -190,8 +197,9 @@ IIC_DVFS_FUNC(start, DVFS_STATE_T * state) mmio_write_8(IIC_DVFS_REG_ICCR, mode); lsi_product = mmio_read_32(RCAR_PRR) & PRR_PRODUCT_MASK; - if (lsi_product == PRR_PRODUCT_E3) + if (lsi_product == PRR_PRODUCT_E3) { goto start; + } reg = mmio_read_32(RCAR_MODEMR) & CHECK_MD13_MD14; switch (reg) { @@ -228,19 +236,21 @@ start: return result; } -IIC_DVFS_FUNC(set_slave, DVFS_STATE_T * state, uint32_t *err, uint8_t slave) +IIC_DVFS_FUNC(set_slave, enum dvfs_state_t *state, uint32_t *err, uint8_t slave) { uint8_t mode; int32_t result; uint8_t address; result = dvfs_check_error(state, err, DVFS_WRITE_MODE); - if (result == DVFS_ERROR) + if (result == DVFS_ERROR) { return result; + } mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_DTE; - if (mode != IIC_DVFS_BIT_ICSR_DTE) + if (mode != IIC_DVFS_BIT_ICSR_DTE) { return result; + } mode = mmio_read_8(IIC_DVFS_REG_ICIC) & ~IIC_DVFS_BIT_ICIC_DTEE; mmio_write_8(IIC_DVFS_REG_ICIC, mode); @@ -253,18 +263,20 @@ IIC_DVFS_FUNC(set_slave, DVFS_STATE_T * state, uint32_t *err, uint8_t slave) return result; } -IIC_DVFS_FUNC(write_addr, DVFS_STATE_T *state, uint32_t *err, uint8_t reg_addr) +IIC_DVFS_FUNC(write_addr, enum dvfs_state_t *state, uint32_t *err, uint8_t reg_addr) { uint8_t mode; int32_t result; result = dvfs_check_error(state, err, DVFS_WRITE_MODE); - if (result == DVFS_ERROR) + if (result == DVFS_ERROR) { return result; + } mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT; - if (mode != IIC_DVFS_BIT_ICSR_WAIT) + if (mode != IIC_DVFS_BIT_ICSR_WAIT) { return result; + } mmio_write_8(IIC_DVFS_REG_ICDR, reg_addr); @@ -276,18 +288,21 @@ IIC_DVFS_FUNC(write_addr, DVFS_STATE_T *state, uint32_t *err, uint8_t reg_addr) return result; } -IIC_DVFS_FUNC(write_data, DVFS_STATE_T *state, uint32_t *err, uint8_t reg_data) +IIC_DVFS_FUNC(write_data, enum dvfs_state_t *state, uint32_t *err, + uint8_t reg_data) { int32_t result; uint8_t mode; result = dvfs_check_error(state, err, DVFS_WRITE_MODE); - if (result == DVFS_ERROR) + if (result == DVFS_ERROR) { return result; + } mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT; - if (mode != IIC_DVFS_BIT_ICSR_WAIT) + if (mode != IIC_DVFS_BIT_ICSR_WAIT) { return result; + } mmio_write_8(IIC_DVFS_REG_ICDR, reg_data); @@ -299,18 +314,20 @@ IIC_DVFS_FUNC(write_data, DVFS_STATE_T *state, uint32_t *err, uint8_t reg_data) return result; } -IIC_DVFS_FUNC(stop, DVFS_STATE_T *state, uint32_t *err) +IIC_DVFS_FUNC(stop, enum dvfs_state_t *state, uint32_t *err) { int32_t result; uint8_t mode; result = dvfs_check_error(state, err, DVFS_WRITE_MODE); - if (result == DVFS_ERROR) + if (result == DVFS_ERROR) { return result; + } mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT; - if (mode != IIC_DVFS_BIT_ICSR_WAIT) + if (mode != IIC_DVFS_BIT_ICSR_WAIT) { return result; + } mmio_write_8(IIC_DVFS_REG_ICCR, IIC_DVFS_SET_ICCR_STOP); @@ -326,32 +343,35 @@ IIC_DVFS_FUNC(done, void) { uint32_t i; - for (i = 0; i < IIC_DVFS_SET_BUSY_LOOP; i++) { - if (mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_BUSY) + for (i = 0U; i < IIC_DVFS_SET_BUSY_LOOP; i++) { + if ((mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_BUSY) != 0U) { continue; + } goto done; } panic(); done: - mmio_write_8(IIC_DVFS_REG_ICCR, 0); + mmio_write_8(IIC_DVFS_REG_ICCR, 0U); return DVFS_COMPLETE; } -IIC_DVFS_FUNC(write_reg_addr_read, DVFS_STATE_T *state, uint32_t *err, - uint8_t reg_addr) +IIC_DVFS_FUNC(write_reg_addr_read, enum dvfs_state_t *state, uint32_t *err, + uint8_t reg_addr) { int32_t result; uint8_t mode; result = dvfs_check_error(state, err, DVFS_WRITE_MODE); - if (result == DVFS_ERROR) + if (result == DVFS_ERROR) { return result; + } mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT; - if (mode != IIC_DVFS_BIT_ICSR_WAIT) + if (mode != IIC_DVFS_BIT_ICSR_WAIT) { return result; + } mmio_write_8(IIC_DVFS_REG_ICDR, reg_addr); @@ -363,18 +383,20 @@ IIC_DVFS_FUNC(write_reg_addr_read, DVFS_STATE_T *state, uint32_t *err, return result; } -IIC_DVFS_FUNC(retransmit, DVFS_STATE_T *state, uint32_t *err) +IIC_DVFS_FUNC(retransmit, enum dvfs_state_t *state, uint32_t *err) { int32_t result; uint8_t mode; result = dvfs_check_error(state, err, DVFS_WRITE_MODE); - if (result == DVFS_ERROR) + if (result == DVFS_ERROR) { return result; + } mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT; - if (mode != IIC_DVFS_BIT_ICSR_WAIT) + if (mode != IIC_DVFS_BIT_ICSR_WAIT) { return result; + } mmio_write_8(IIC_DVFS_REG_ICCR, IIC_DVFS_SET_ICCR_RETRANSMISSION); @@ -389,20 +411,22 @@ IIC_DVFS_FUNC(retransmit, DVFS_STATE_T *state, uint32_t *err) return result; } -IIC_DVFS_FUNC(set_slave_read, DVFS_STATE_T *state, uint32_t *err, - uint8_t slave) +IIC_DVFS_FUNC(set_slave_read, enum dvfs_state_t *state, uint32_t *err, + uint8_t slave) { uint8_t address; int32_t result; uint8_t mode; result = dvfs_check_error(state, err, DVFS_WRITE_MODE); - if (result == DVFS_ERROR) + if (result == DVFS_ERROR) { return result; + } mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_DTE; - if (mode != IIC_DVFS_BIT_ICSR_DTE) + if (mode != IIC_DVFS_BIT_ICSR_DTE) { return result; + } mode = mmio_read_8(IIC_DVFS_REG_ICIC) & ~IIC_DVFS_BIT_ICIC_DTEE; mmio_write_8(IIC_DVFS_REG_ICIC, mode); @@ -410,23 +434,25 @@ IIC_DVFS_FUNC(set_slave_read, DVFS_STATE_T *state, uint32_t *err, address = ((uint8_t) (slave << 1) + DVFS_READ_MODE); mmio_write_8(IIC_DVFS_REG_ICDR, address); - *state = DVFS_CHANGE_SEND_TO_RECIEVE; + *state = DVFS_CHANGE_SEND_TO_RECEIVE; return result; } -IIC_DVFS_FUNC(change_send_to_recieve, DVFS_STATE_T *state, uint32_t *err) +IIC_DVFS_FUNC(change_send_to_receive, enum dvfs_state_t *state, uint32_t *err) { int32_t result; uint8_t mode; result = dvfs_check_error(state, err, DVFS_WRITE_MODE); - if (result == DVFS_ERROR) + if (result == DVFS_ERROR) { return result; + } mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT; - if (mode != IIC_DVFS_BIT_ICSR_WAIT) + if (mode != IIC_DVFS_BIT_ICSR_WAIT) { return result; + } mmio_write_8(IIC_DVFS_REG_ICCR, IIC_DVFS_SET_ICCR_CHANGE); @@ -438,18 +464,20 @@ IIC_DVFS_FUNC(change_send_to_recieve, DVFS_STATE_T *state, uint32_t *err) return result; } -IIC_DVFS_FUNC(stop_read, DVFS_STATE_T *state, uint32_t *err) +IIC_DVFS_FUNC(stop_read, enum dvfs_state_t *state, uint32_t *err) { int32_t result; uint8_t mode; result = dvfs_check_error(state, err, DVFS_READ_MODE); - if (result == DVFS_ERROR) + if (result == DVFS_ERROR) { return result; + } mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT; - if (mode != IIC_DVFS_BIT_ICSR_WAIT) + if (mode != IIC_DVFS_BIT_ICSR_WAIT) { return result; + } mmio_write_8(IIC_DVFS_REG_ICCR, IIC_DVFS_SET_ICCR_STOP_READ); @@ -464,13 +492,14 @@ IIC_DVFS_FUNC(stop_read, DVFS_STATE_T *state, uint32_t *err) return result; } -IIC_DVFS_FUNC(read, DVFS_STATE_T *state, uint8_t *reg_data) +IIC_DVFS_FUNC(read, enum dvfs_state_t *state, uint8_t *reg_data) { uint8_t mode; mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_DTE; - if (mode != IIC_DVFS_BIT_ICSR_DTE) + if (mode != IIC_DVFS_BIT_ICSR_DTE) { return DVFS_PROCESS; + } mode = mmio_read_8(IIC_DVFS_REG_ICIC) & ~IIC_DVFS_BIT_ICIC_DTEE; mmio_write_8(IIC_DVFS_REG_ICIC, mode); @@ -483,12 +512,12 @@ IIC_DVFS_FUNC(read, DVFS_STATE_T *state, uint8_t *reg_data) RCAR_DVFS_API(send, uint8_t slave, uint8_t reg_addr, uint8_t reg_data) { - DVFS_STATE_T state = DVFS_START; + enum dvfs_state_t state = DVFS_START; int32_t result = DVFS_PROCESS; - uint32_t err = 0; + uint32_t err = 0U; mstpcr_write(SCMSTPCR9, CPG_MSTPSR9, CPG_BIT_SMSTPCR9_DVFS); - mmio_write_8(IIC_DVFS_REG_ICCR, 0); + mmio_write_8(IIC_DVFS_REG_ICCR, 0U); again: switch (state) { case DVFS_START: @@ -514,20 +543,21 @@ again: break; } - if (result == DVFS_PROCESS) + if (result == DVFS_PROCESS) { goto again; + } return result; } RCAR_DVFS_API(receive, uint8_t slave, uint8_t reg, uint8_t *data) { - DVFS_STATE_T state = DVFS_START; + enum dvfs_state_t state = DVFS_START; int32_t result = DVFS_PROCESS; - uint32_t err = 0; + uint32_t err = 0U; mstpcr_write(SCMSTPCR9, CPG_MSTPSR9, CPG_BIT_SMSTPCR9_DVFS); - mmio_write_8(IIC_DVFS_REG_ICCR, 0); + mmio_write_8(IIC_DVFS_REG_ICCR, 0U); again: switch (state) { case DVFS_START: @@ -545,8 +575,8 @@ again: case DVFS_SET_SLAVE_READ: result = dvfs_set_slave_read(&state, &err, slave); break; - case DVFS_CHANGE_SEND_TO_RECIEVE: - result = dvfs_change_send_to_recieve(&state, &err); + case DVFS_CHANGE_SEND_TO_RECEIVE: + result = dvfs_change_send_to_receive(&state, &err); break; case DVFS_STOP_READ: result = dvfs_stop_read(&state, &err); @@ -562,8 +592,9 @@ again: break; } - if (result == DVFS_PROCESS) + if (result == DVFS_PROCESS) { goto again; + } return result; } diff --git a/drivers/renesas/rcar/iic_dvfs/iic_dvfs.h b/drivers/renesas/rcar/iic_dvfs/iic_dvfs.h index 2dec58f64..244c06cfd 100644 --- a/drivers/renesas/rcar/iic_dvfs/iic_dvfs.h +++ b/drivers/renesas/rcar/iic_dvfs/iic_dvfs.h @@ -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 */ @@ -8,14 +8,14 @@ #define IIC_DVFS_H /* PMIC slave */ -#define PMIC (0x30) -#define BKUP_MODE_CNT (0x20) -#define DVFS_SET_VID (0x54) -#define REG_KEEP10 (0x79) +#define PMIC (0x30U) +#define BKUP_MODE_CNT (0x20U) +#define DVFS_SET_VID (0x54U) +#define REG_KEEP10 (0x79U) /* EEPROM slave */ -#define EEPROM (0x50) -#define BOARD_ID (0x70) +#define EEPROM (0x50U) +#define BOARD_ID (0x70U) int32_t rcar_iic_dvfs_receive(uint8_t slave, uint8_t reg, uint8_t *data); int32_t rcar_iic_dvfs_send(uint8_t slave, uint8_t regr, uint8_t data); -- cgit v1.2.3 From 2f943087b31df1724ceaaab551769f60a8ff4065 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Sun, 13 Dec 2020 20:10:32 +0000 Subject: drivers: renesas: rcar: scif: Fix coding style Replace TAB with space after #define macros and update comments as per TF-A coding style. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: Iff46838a41f991f7dd9dc6fb043e9e482ea0b11d --- drivers/renesas/rcar/scif/scif.S | 176 +++++++++++++++++++-------------------- 1 file changed, 88 insertions(+), 88 deletions(-) diff --git a/drivers/renesas/rcar/scif/scif.S b/drivers/renesas/rcar/scif/scif.S index ae26cc402..beb8dd838 100644 --- a/drivers/renesas/rcar/scif/scif.S +++ b/drivers/renesas/rcar/scif/scif.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,43 +9,43 @@ #include #include -#define SCIF_INTERNAL_CLK 0 -#define SCIF_EXTARNAL_CLK 1 -#define SCIF_CLK SCIF_INTERNAL_CLK +#define SCIF_INTERNAL_CLK 0 +#define SCIF_EXTARNAL_CLK 1 +#define SCIF_CLK SCIF_INTERNAL_CLK /* product register */ -#define PRR (0xFFF00044) -#define PRR_PRODUCT_MASK (0x00007F00) -#define PRR_CUT_MASK (0x000000FF) -#define PRR_PRODUCT_H3_VER_10 (0x00004F00) -#define PRR_PRODUCT_E3 (0x00005700) -#define PRR_PRODUCT_D3 (0x00005800) +#define PRR (0xFFF00044) +#define PRR_PRODUCT_MASK (0x00007F00) +#define PRR_CUT_MASK (0x000000FF) +#define PRR_PRODUCT_H3_VER_10 (0x00004F00) +#define PRR_PRODUCT_E3 (0x00005700) +#define PRR_PRODUCT_D3 (0x00005800) /* module stop */ -#define CPG_BASE (0xE6150000) -#define CPG_SMSTPCR2 (0x0138) -#define CPG_SMSTPCR3 (0x013C) +#define CPG_BASE (0xE6150000) +#define CPG_SMSTPCR2 (0x0138) +#define CPG_SMSTPCR3 (0x013C) #define CPG_MSTPSR2 (0x0040) -#define CPG_MSTPSR3 (0x0048) -#define MSTP207 (1 << 7) -#define MSTP310 (1 << 10) -#define CPG_CPGWPR (0x0900) +#define CPG_MSTPSR3 (0x0048) +#define MSTP207 (1 << 7) +#define MSTP310 (1 << 10) +#define CPG_CPGWPR (0x0900) /* scif */ -#define SCIF0_BASE (0xE6E60000) -#define SCIF2_BASE (0xE6E88000) -#define SCIF_SCSMR (0x00) -#define SCIF_SCBRR (0x04) -#define SCIF_SCSCR (0x08) -#define SCIF_SCFTDR (0x0C) -#define SCIF_SCFSR (0x10) -#define SCIF_SCFRDR (0x14) -#define SCIF_SCFCR (0x18) -#define SCIF_SCFDR (0x1C) -#define SCIF_SCSPTR (0x20) -#define SCIF_SCLSR (0x24) -#define SCIF_DL (0x30) -#define SCIF_CKS (0x34) +#define SCIF0_BASE (0xE6E60000) +#define SCIF2_BASE (0xE6E88000) +#define SCIF_SCSMR (0x00) +#define SCIF_SCBRR (0x04) +#define SCIF_SCSCR (0x08) +#define SCIF_SCFTDR (0x0C) +#define SCIF_SCFSR (0x10) +#define SCIF_SCFRDR (0x14) +#define SCIF_SCFCR (0x18) +#define SCIF_SCFDR (0x1C) +#define SCIF_SCSPTR (0x20) +#define SCIF_SCLSR (0x24) +#define SCIF_DL (0x30) +#define SCIF_CKS (0x34) #if RCAR_LSI == RCAR_V3M #define SCIF_BASE SCIF0_BASE @@ -60,70 +60,71 @@ #endif /* mode pin */ -#define RST_MODEMR (0xE6160060) -#define MODEMR_MD12 (0x00001000) +#define RST_MODEMR (0xE6160060) +#define MODEMR_MD12 (0x00001000) -#define SCSMR_CA_MASK (1 << 7) -#define SCSMR_CA_ASYNC (0x0000) -#define SCSMR_CHR_MASK (1 << 6) -#define SCSMR_CHR_8 (0x0000) -#define SCSMR_PE_MASK (1 << 5) -#define SCSMR_PE_DIS (0x0000) -#define SCSMR_STOP_MASK (1 << 3) -#define SCSMR_STOP_1 (0x0000) -#define SCSMR_CKS_MASK (3 << 0) -#define SCSMR_CKS_DIV1 (0x0000) -#define SCSMR_INIT_DATA (SCSMR_CA_ASYNC + \ +#define SCSMR_CA_MASK (1 << 7) +#define SCSMR_CA_ASYNC (0x0000) +#define SCSMR_CHR_MASK (1 << 6) +#define SCSMR_CHR_8 (0x0000) +#define SCSMR_PE_MASK (1 << 5) +#define SCSMR_PE_DIS (0x0000) +#define SCSMR_STOP_MASK (1 << 3) +#define SCSMR_STOP_1 (0x0000) +#define SCSMR_CKS_MASK (3 << 0) +#define SCSMR_CKS_DIV1 (0x0000) +#define SCSMR_INIT_DATA (SCSMR_CA_ASYNC + \ SCSMR_CHR_8 + \ SCSMR_PE_DIS + \ SCSMR_STOP_1 + \ SCSMR_CKS_DIV1) -#define SCBRR_115200BPS (17) -#define SCBRR_115200BPSON (16) -#define SCBRR_115200BPS_E3_SSCG (15) -#define SCBRR_230400BPS (8) +#define SCBRR_115200BPS (17) +#define SCBRR_115200BPSON (16) +#define SCBRR_115200BPS_E3_SSCG (15) +#define SCBRR_230400BPS (8) -#define SCSCR_TE_MASK (1 << 5) -#define SCSCR_TE_DIS (0x0000) -#define SCSCR_TE_EN (0x0020) -#define SCSCR_RE_MASK (1 << 4) -#define SCSCR_RE_DIS (0x0000) -#define SCSCR_RE_EN (0x0010) -#define SCSCR_CKE_MASK (3 << 0) -#define SCSCR_CKE_INT (0x0000) -#define SCSCR_CKE_BRG (0x0002) +#define SCSCR_TE_MASK (1 << 5) +#define SCSCR_TE_DIS (0x0000) +#define SCSCR_TE_EN (0x0020) +#define SCSCR_RE_MASK (1 << 4) +#define SCSCR_RE_DIS (0x0000) +#define SCSCR_RE_EN (0x0010) +#define SCSCR_CKE_MASK (3 << 0) +#define SCSCR_CKE_INT (0x0000) +#define SCSCR_CKE_BRG (0x0002) #if SCIF_CLK == SCIF_EXTARNAL_CLK -#define SCSCR_CKE_INT_CLK (SCSCR_CKE_BRG) +#define SCSCR_CKE_INT_CLK (SCSCR_CKE_BRG) #else -#define SCFSR_TEND_MASK (1 << 6) -#define SCFSR_TEND_TRANS_END (0x0040) -#define SCSCR_CKE_INT_CLK (SCSCR_CKE_INT) +#define SCFSR_TEND_MASK (1 << 6) +#define SCFSR_TEND_TRANS_END (0x0040) +#define SCSCR_CKE_INT_CLK (SCSCR_CKE_INT) #endif -#define SCFSR_INIT_DATA (0x0000) -#define SCFCR_TTRG_MASK (3 << 4) -#define SCFCR_TTRG_8 (0x0000) -#define SCFCR_TTRG_0 (0x0030) -#define SCFCR_TFRST_MASK (1 << 2) -#define SCFCR_TFRST_DIS (0x0000) -#define SCFCR_TFRST_EN (0x0004) -#define SCFCR_RFRS_MASK (1 << 1) -#define SCFCR_RFRS_DIS (0x0000) -#define SCFCR_RFRS_EN (0x0002) -#define SCFCR_INIT_DATA (SCFCR_TTRG_8) -#define SCFDR_T_MASK (0x1f << 8) -#define DL_INIT_DATA (8) -#define CKS_CKS_DIV_MASK (1 << 15) -#define CKS_CKS_DIV_CLK (0x0000) -#define CKS_XIN_MASK (1 << 14) -#define CKS_XIN_SCIF_CLK (0x0000) -#define CKS_INIT_DATA (CKS_CKS_DIV_CLK + CKS_XIN_SCIF_CLK) +#define SCFSR_INIT_DATA (0x0000) +#define SCFCR_TTRG_MASK (3 << 4) +#define SCFCR_TTRG_8 (0x0000) +#define SCFCR_TTRG_0 (0x0030) +#define SCFCR_TFRST_MASK (1 << 2) +#define SCFCR_TFRST_DIS (0x0000) +#define SCFCR_TFRST_EN (0x0004) +#define SCFCR_RFRS_MASK (1 << 1) +#define SCFCR_RFRS_DIS (0x0000) +#define SCFCR_RFRS_EN (0x0002) +#define SCFCR_INIT_DATA (SCFCR_TTRG_8) +#define SCFDR_T_MASK (0x1f << 8) +#define DL_INIT_DATA (8) +#define CKS_CKS_DIV_MASK (1 << 15) +#define CKS_CKS_DIV_CLK (0x0000) +#define CKS_XIN_MASK (1 << 14) +#define CKS_XIN_SCIF_CLK (0x0000) +#define CKS_INIT_DATA (CKS_CKS_DIV_CLK + CKS_XIN_SCIF_CLK) .globl console_rcar_register .globl console_rcar_init .globl console_rcar_putc .globl console_rcar_flush - /* ----------------------------------------------- + /* + * ----------------------------------------------- * int console_rcar_register( * uintptr_t base, uint32_t clk, uint32_t baud, * console_t *console) @@ -154,7 +155,7 @@ register_fail: ret x7 endfunc console_rcar_register - /* ----------------------------------------------- + /* * int console_rcar_init(unsigned long base_addr, * unsigned int uart_clk, unsigned int baud_rate) * Function to initialize the console without a @@ -166,7 +167,6 @@ endfunc console_rcar_register * w2 - Baud rate * Out: return 1 on success * Clobber list : x1, x2 - * ----------------------------------------------- */ func console_rcar_init ldr x0, =CPG_BASE @@ -188,8 +188,10 @@ func console_rcar_init ldrh w1, [x0, #SCIF_SCFCR] orr w1, w1, #(SCFCR_TFRST_EN + SCFCR_RFRS_EN) strh w1, [x0, #SCIF_SCFCR] - /* Read flags of ER, DR, BRK, and RDF in SCFSR and those of TO and ORER - in SCLSR, then clear them to 0 */ + /* + * Read flags of ER, DR, BRK, and RDF in SCFSR and those of TO and ORER + * in SCLSR, then clear them to 0 + */ mov w1, #SCFSR_INIT_DATA strh w1, [x0, #SCIF_SCFSR] mov w1, #0 @@ -265,7 +267,7 @@ func console_rcar_init ret endfunc console_rcar_init - /* -------------------------------------------------------- + /* * int console_rcar_putc(int c, unsigned int base_addr) * Function to output a character over the console. It * returns the character printed on success or -1 on error. @@ -273,7 +275,6 @@ endfunc console_rcar_init * x1 - pointer to console_t structure * Out : return -1 on error else return character. * Clobber list : x2 - * -------------------------------------------------------- */ func console_rcar_putc ldr x1, =SCIF_BASE @@ -304,12 +305,11 @@ func console_rcar_putc ret endfunc console_rcar_putc - /* --------------------------------------------- + /* * void console_rcar_flush(void) * Function to force a write of all buffered * data that hasn't been output. It returns void * Clobber list : x0, x1 - * --------------------------------------------- */ func console_rcar_flush ldr x0, =SCIF_BASE -- cgit v1.2.3 From 5ee92a748caf826f7527fe9066e89109b4a97ba5 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Sun, 13 Dec 2020 19:49:36 +0000 Subject: drivers: renesas: rcar: auth: Use space instead of TAB Use space instead of TAB after #define's. Also updated header files as per TF-A coding style. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: I4eac94f0bc79f24b8ac7165ec48f1e1de95d7205 --- drivers/renesas/rcar/auth/auth_mod.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/drivers/renesas/rcar/auth/auth_mod.c b/drivers/renesas/rcar/auth/auth_mod.c index ece3462f4..4aa86e2a4 100644 --- a/drivers/renesas/rcar/auth/auth_mod.c +++ b/drivers/renesas/rcar/auth/auth_mod.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights * reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -7,29 +7,28 @@ #include -#include - #include #include #include #include +#include #include "rom_api.h" typedef int32_t(*secure_boot_api_f) (uint32_t a, uint32_t b, void *c); extern int32_t rcar_get_certificate(const int32_t name, uint32_t *cert_addr); -#define RCAR_IMAGE_ID_MAX (10) -#define RCAR_CERT_MAGIC_NUM (0xE291F358U) +#define RCAR_IMAGE_ID_MAX (10) +#define RCAR_CERT_MAGIC_NUM (0xE291F358U) #define RCAR_BOOT_KEY_CERT (0xE6300C00U) #define RCAR_BOOT_KEY_CERT_NEW (0xE6300F00U) -#define RST_BASE (0xE6160000U) -#define RST_MODEMR (RST_BASE + 0x0060U) -#define MFISOFTMDR (0xE6260600U) -#define MODEMR_MD5_MASK (0x00000020U) -#define MODEMR_MD5_SHIFT (5U) -#define SOFTMD_BOOTMODE_MASK (0x00000001U) -#define SOFTMD_NORMALBOOT (0x1U) +#define RST_BASE (0xE6160000U) +#define RST_MODEMR (RST_BASE + 0x0060U) +#define MFISOFTMDR (0xE6260600U) +#define MODEMR_MD5_MASK (0x00000020U) +#define MODEMR_MD5_SHIFT (5U) +#define SOFTMD_BOOTMODE_MASK (0x00000001U) +#define SOFTMD_NORMALBOOT (0x1U) static secure_boot_api_f secure_boot_api; @@ -125,9 +124,9 @@ verify_image: #if RCAR_BL2_DCACHE == 1 /* enable */ write_sctlr_el3(read_sctlr_el3() | SCTLR_C_BIT); -#endif +#endif /* RCAR_BL2_DCACHE */ -#endif +#endif /* IMAGE_BL2 */ return ret; } -- cgit v1.2.3 From 041c581e2ad05b83fb4dc6a75ce0fbdb3c6953c4 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Sun, 13 Dec 2020 20:13:42 +0000 Subject: drivers: renesas: rcar: watchdog: Fix typo Fix the typo "occured" -> "occurred" Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: Ic66ceab364f7dc926dc6a6db641ca173601cd031 --- drivers/renesas/rcar/watchdog/swdt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/renesas/rcar/watchdog/swdt.c b/drivers/renesas/rcar/watchdog/swdt.c index 111e65174..05987ab70 100644 --- a/drivers/renesas/rcar/watchdog/swdt.c +++ b/drivers/renesas/rcar/watchdog/swdt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -162,6 +162,6 @@ void rcar_swdt_exec(uint64_t p) gicv2_end_of_interrupt(ARM_IRQ_SEC_WDT); rcar_swdt_release(); ERROR("\n"); - ERROR("System WDT overflow, occured address is %p\n", (void *)p); + ERROR("System WDT overflow, occurred address is %p\n", (void *)p); panic(); } -- cgit v1.2.3 From 41b1a30098686e7144a5a595d5939b017bfcddd2 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Sun, 13 Dec 2020 19:53:15 +0000 Subject: drivers: renesas: rcar: avs: Fix checkpatch warnings Fix checkpatch warnings. There are no functional changes. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: Ic7406aa88e121914270a8d192f170c9c4244578a --- drivers/renesas/rcar/avs/avs_driver.c | 74 +++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 34 deletions(-) diff --git a/drivers/renesas/rcar/avs/avs_driver.c b/drivers/renesas/rcar/avs/avs_driver.c index 647869ede..2c939cd59 100644 --- a/drivers/renesas/rcar/avs/avs_driver.c +++ b/drivers/renesas/rcar/avs/avs_driver.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -8,8 +8,8 @@ #include #include -#include "cpg_registers.h" #include "avs_driver.h" +#include "cpg_registers.h" #include "rcar_def.h" #include "rcar_private.h" @@ -22,12 +22,12 @@ #endif /* PMIC_ROHM_BD9571 */ /* Base address of Adaptive Voltage Scaling module registers*/ -#define AVS_BASE (0xE60A0000U) +#define AVS_BASE (0xE60A0000U) /* Adaptive Dynamic Voltage ADJust Parameter2 registers */ -#define ADVADJP2 (AVS_BASE + 0x013CU) +#define ADVADJP2 (AVS_BASE + 0x013CU) /* Mask VOLCOND bit in ADVADJP2 registers */ -#define ADVADJP2_VOLCOND_MASK (0x000001FFU) /* VOLCOND[8:0] */ +#define ADVADJP2_VOLCOND_MASK (0x000001FFU) /* VOLCOND[8:0] */ #if PMIC_ROHM_BD9571 /* I2C for DVFS bit in CPG registers for module standby and software reset*/ @@ -38,19 +38,19 @@ #if PMIC_ROHM_BD9571 /* Base address of IICDVFS registers*/ -#define IIC_DVFS_BASE (0xE60B0000U) +#define IIC_DVFS_BASE (0xE60B0000U) /* IIC bus data register */ -#define IIC_ICDR (IIC_DVFS_BASE + 0x0000U) +#define IIC_ICDR (IIC_DVFS_BASE + 0x0000U) /* IIC bus control register */ -#define IIC_ICCR (IIC_DVFS_BASE + 0x0004U) +#define IIC_ICCR (IIC_DVFS_BASE + 0x0004U) /* IIC bus status register */ -#define IIC_ICSR (IIC_DVFS_BASE + 0x0008U) +#define IIC_ICSR (IIC_DVFS_BASE + 0x0008U) /* IIC interrupt control register */ -#define IIC_ICIC (IIC_DVFS_BASE + 0x000CU) +#define IIC_ICIC (IIC_DVFS_BASE + 0x000CU) /* IIC clock control register low */ -#define IIC_ICCL (IIC_DVFS_BASE + 0x0010U) +#define IIC_ICCL (IIC_DVFS_BASE + 0x0010U) /* IIC clock control register high */ -#define IIC_ICCH (IIC_DVFS_BASE + 0x0014U) +#define IIC_ICCH (IIC_DVFS_BASE + 0x0014U) /* Bit in ICSR register */ #define ICSR_BUSY (0x10U) @@ -76,20 +76,23 @@ #define ICCR_STOP_RECV (0xC0U) /* Low-level period of SCL */ -#define ICCL_FREQ_8p33M (0x07U) /* for CP Phy 8.3333MHz */ -#define ICCL_FREQ_10M (0x09U) /* for CP Phy 10MHz */ -#define ICCL_FREQ_12p5M (0x0BU) /* for CP Phy 12.5MHz */ -#define ICCL_FREQ_16p66M (0x0EU) /* for CP Phy 16.6666MHz */ +#define ICCL_FREQ_8p33M (0x07U) /* for CP Phy 8.3333MHz */ +#define ICCL_FREQ_10M (0x09U) /* for CP Phy 10MHz */ +#define ICCL_FREQ_12p5M (0x0BU) /* for CP Phy 12.5MHz */ +#define ICCL_FREQ_16p66M (0x0EU) /* for CP Phy 16.6666MHz */ /* High-level period of SCL */ -#define ICCH_FREQ_8p33M (0x01U) /* for CP Phy 8.3333MHz */ -#define ICCH_FREQ_10M (0x02U) /* for CP Phy 10MHz */ -#define ICCH_FREQ_12p5M (0x03U) /* for CP Phy 12.5MHz */ -#define ICCH_FREQ_16p66M (0x05U) /* for CP Phy 16.6666MHz */ +#define ICCH_FREQ_8p33M (0x01U) /* for CP Phy 8.3333MHz */ +#define ICCH_FREQ_10M (0x02U) /* for CP Phy 10MHz */ +#define ICCH_FREQ_12p5M (0x03U) /* for CP Phy 12.5MHz */ +#define ICCH_FREQ_16p66M (0x05U) /* for CP Phy 16.6666MHz */ /* PMIC */ -#define PMIC_W_SLAVE_ADDRESS (0x60U) /* ROHM BD9571 slave address + (W) */ -#define PMIC_R_SLAVE_ADDRESS (0x61U) /* ROHM BD9571 slave address + (R) */ -#define PMIC_DVFS_SETVID (0x54U) /* ROHM BD9571 DVFS SetVID register */ +/* ROHM BD9571 slave address + (W) */ +#define PMIC_W_SLAVE_ADDRESS (0x60U) +/* ROHM BD9571 slave address + (R) */ +#define PMIC_R_SLAVE_ADDRESS (0x61U) +/* ROHM BD9571 DVFS SetVID register */ +#define PMIC_DVFS_SETVID (0x54U) #endif /* PMIC_ROHM_BD9571 */ /* Individual information */ @@ -102,7 +105,7 @@ typedef struct { } initial_voltage_t; static const initial_voltage_t init_vol_tbl[] = { - /* AVS code, RHOM BD9571 DVFS SetVID register */ + /* AVS code, ROHM BD9571 DVFS SetVID register */ {0x00U, 0x53U}, /* AVS0, 0.83V */ {0x01U, 0x52U}, /* AVS1, 0.82V */ {0x02U, 0x51U}, /* AVS2, 0.81V */ @@ -188,7 +191,7 @@ void rcar_avs_init(void) /* Disable I2C module and All internal registers initialized. */ mmio_write_8(IIC_ICCR, 0x00U); while ((mmio_read_8(IIC_ICCR) & ICCR_ENABLE) != 0U) { - /* Disable I2C module and All internal registers initialized. */ + /* Disable I2C module and all internal registers initialized. */ mmio_write_8(IIC_ICCR, 0x00U); } @@ -283,8 +286,8 @@ void rcar_avs_setting(void) /* Dose efuse_avs exceed the number of */ /* the tables? */ if (efuse_avs >= EFUSE_AVS_NUM) { - ERROR("AVS number of eFuse is out " - "of a range. number=%u\n", + ERROR("%s%s=%u\n", "AVS number of ", + "eFuse is out of range. number", efuse_avs); /* Infinite loop */ panic(); @@ -417,7 +420,8 @@ void rcar_avs_end(void) { uint8_t addr = PMIC_DVFS_SETVID; uint8_t value = avs_read_pmic_reg(addr); - NOTICE("Read PMIC register. address=0x%x value=0x%x \n", + + NOTICE("Read PMIC register. address=0x%x value=0x%x\n", addr, value); } #endif @@ -446,8 +450,8 @@ static avs_error_t avs_check_error(void) avs_error_t ret; if ((mmio_read_8(IIC_ICSR) & ICSR_AL) == ICSR_AL) { - NOTICE("Loss of arbitration is detected. " - "AVS status=%d Retry=%u\n", avs_status, avs_retry); + NOTICE("%s AVS status=%d Retry=%u\n", + "Loss of arbitration is detected.", avs_status, avs_retry); /* Check of retry number of times */ if (avs_retry >= AVS_RETRY_NUM) { ERROR("AVS setting failed in retry. max=%u\n", @@ -458,8 +462,8 @@ static avs_error_t avs_check_error(void) /* Set the error detected to error status. */ ret = avs_error_al; } else if ((mmio_read_8(IIC_ICSR) & ICSR_TACK) == ICSR_TACK) { - NOTICE("Non-acknowledge is detected. " - "AVS status=%d Retry=%u\n", avs_status, avs_retry); + NOTICE("%s AVS status=%d Retry=%u\n", + "Non-acknowledge is detected.", avs_status, avs_retry); /* Check of retry number of times */ if (avs_retry >= AVS_RETRY_NUM) { ERROR("AVS setting failed in retry. max=%u\n", @@ -526,8 +530,10 @@ static uint8_t avs_read_pmic_reg(uint8_t addr) /* Set frequency of 400kHz */ avs_set_iic_clock(); - /* Set ICIC.WAITE=1, ICIC.DTEE=1 to enable data transmission */ - /* interrupt and wait interrupt. */ + /* + * Set ICIC.WAITE=1, ICIC.DTEE=1 to enable data transmission + * interrupt and wait interrupt. + */ mmio_write_8(IIC_ICIC, mmio_read_8(IIC_ICIC) | ICIC_WAITE | ICIC_DTEE); /* Write H'94 in ICCR to issue start condition */ -- cgit v1.2.3 From 95e1166e8d176f2530cfcc22a1f7b47a6e6ade21 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Sun, 13 Dec 2020 20:17:01 +0000 Subject: drivers: renesas: rcar: common: Code cleanup This patch fixes the below checkpatch warnings Line 13: WARNING: please, no spaces at the start of a line Line 15: WARNING: please, no spaces at the start of a line Line 18: WARNING: Missing a blank line after declarations Line 24: WARNING: please, no spaces at the start of a line Line 26: WARNING: please, no spaces at the start of a line Line 29: WARNING: Missing a blank line after declarations Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: I41d146e86889640d11e88c0717039353ddceff0d --- drivers/renesas/rcar/common.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/renesas/rcar/common.c b/drivers/renesas/rcar/common.c index 42bdce579..9b7c1eb16 100644 --- a/drivers/renesas/rcar/common.c +++ b/drivers/renesas/rcar/common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2018-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -8,24 +8,27 @@ #include "rcar_private.h" -void #if IMAGE_BL31 - __attribute__ ((section(".system_ram"))) +void __attribute__ ((section(".system_ram"))) cpg_write(uintptr_t regadr, uint32_t regval) +#else +void cpg_write(uintptr_t regadr, uint32_t regval) #endif - cpg_write(uintptr_t regadr, uint32_t regval) { - uint32_t value = (regval); + uint32_t value = regval; + mmio_write_32((uintptr_t) RCAR_CPGWPR, ~value); mmio_write_32(regadr, value); } -void #if IMAGE_BL31 - __attribute__ ((section(".system_ram"))) +void __attribute__ ((section(".system_ram"))) mstpcr_write(uint32_t mstpcr, uint32_t mstpsr, + uint32_t target_bit) +#else +void mstpcr_write(uint32_t mstpcr, uint32_t mstpsr, uint32_t target_bit) #endif - mstpcr_write(uint32_t mstpcr, uint32_t mstpsr, uint32_t target_bit) { uint32_t reg; + reg = mmio_read_32(mstpcr); reg &= ~target_bit; cpg_write(mstpcr, reg); -- cgit v1.2.3 From ee0dbc41045c12164d90c3ca79b7c40fa5da9175 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Sun, 13 Dec 2020 19:59:26 +0000 Subject: drivers: renesas: rcar: delay: Fix checkpatch warnings Fix checkpatch warnings. There are no functional changes. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: Iec7dd019bd38e84eccd8cc17189745fdef1911bb --- drivers/renesas/rcar/delay/micro_delay.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/renesas/rcar/delay/micro_delay.c b/drivers/renesas/rcar/delay/micro_delay.c index aced5891a..a5e2a6928 100644 --- a/drivers/renesas/rcar/delay/micro_delay.c +++ b/drivers/renesas/rcar/delay/micro_delay.c @@ -1,18 +1,19 @@ /* - * Copyright (c) 2018, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2018-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include #include + #include "micro_delay.h" #define RCAR_CONV_MICROSEC 1000000U void #if IMAGE_BL31 - __attribute__ ((section (".system_ram"))) + __attribute__ ((section(".system_ram"))) #endif rcar_micro_delay(uint64_t micro_sec) { -- cgit v1.2.3 From cb413426f2d2742e68b1325c026dbd3c4f1f559b Mon Sep 17 00:00:00 2001 From: Biju Das Date: Sun, 13 Dec 2020 20:24:19 +0000 Subject: drivers: renesas: rcar: pwrc: Code cleanup This patches fixes checkpatch warnings, replace TAB with space after #define macros and arrange header as per TF-A coding style. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: Iba009587e0b499b3ae58876be390602ae14175b2 --- drivers/renesas/rcar/pwrc/pwrc.c | 261 ++++++++++++++++++++------------------- drivers/renesas/rcar/pwrc/pwrc.h | 10 +- 2 files changed, 138 insertions(+), 133 deletions(-) diff --git a/drivers/renesas/rcar/pwrc/pwrc.c b/drivers/renesas/rcar/pwrc/pwrc.c index 2ce6b6139..c0f015f04 100644 --- a/drivers/renesas/rcar/pwrc/pwrc.c +++ b/drivers/renesas/rcar/pwrc/pwrc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -16,10 +16,10 @@ #include #include "iic_dvfs.h" -#include "rcar_def.h" -#include "rcar_private.h" #include "micro_delay.h" #include "pwrc.h" +#include "rcar_def.h" +#include "rcar_private.h" /* * Someday there will be a generic power controller api. At the moment each @@ -27,105 +27,105 @@ */ RCAR_INSTANTIATE_LOCK -#define WUP_IRQ_SHIFT (0U) -#define WUP_FIQ_SHIFT (8U) -#define WUP_CSD_SHIFT (16U) -#define BIT_SOFTRESET (1U<<15) -#define BIT_CA53_SCU (1U<<21) -#define BIT_CA57_SCU (1U<<12) -#define REQ_RESUME (1U<<1) -#define REQ_OFF (1U<<0) -#define STATUS_PWRUP (1U<<4) -#define STATUS_PWRDOWN (1U<<0) -#define STATE_CA57_CPU (27U) -#define STATE_CA53_CPU (22U) -#define MODE_L2_DOWN (0x00000002U) -#define CPU_PWR_OFF (0x00000003U) -#define RCAR_PSTR_MASK (0x00000003U) -#define ST_ALL_STANDBY (0x00003333U) +#define WUP_IRQ_SHIFT (0U) +#define WUP_FIQ_SHIFT (8U) +#define WUP_CSD_SHIFT (16U) +#define BIT_SOFTRESET (1U << 15) +#define BIT_CA53_SCU (1U << 21) +#define BIT_CA57_SCU (1U << 12) +#define REQ_RESUME (1U << 1) +#define REQ_OFF (1U << 0) +#define STATUS_PWRUP (1U << 4) +#define STATUS_PWRDOWN (1U << 0) +#define STATE_CA57_CPU (27U) +#define STATE_CA53_CPU (22U) +#define MODE_L2_DOWN (0x00000002U) +#define CPU_PWR_OFF (0x00000003U) +#define RCAR_PSTR_MASK (0x00000003U) +#define ST_ALL_STANDBY (0x00003333U) /* Suspend to ram */ -#define DBSC4_REG_BASE (0xE6790000U) -#define DBSC4_REG_DBSYSCNT0 (DBSC4_REG_BASE + 0x0100U) -#define DBSC4_REG_DBACEN (DBSC4_REG_BASE + 0x0200U) -#define DBSC4_REG_DBCMD (DBSC4_REG_BASE + 0x0208U) -#define DBSC4_REG_DBRFEN (DBSC4_REG_BASE + 0x0204U) -#define DBSC4_REG_DBWAIT (DBSC4_REG_BASE + 0x0210U) -#define DBSC4_REG_DBCALCNF (DBSC4_REG_BASE + 0x0424U) -#define DBSC4_REG_DBDFIPMSTRCNF (DBSC4_REG_BASE + 0x0520U) -#define DBSC4_REG_DBPDLK0 (DBSC4_REG_BASE + 0x0620U) -#define DBSC4_REG_DBPDRGA0 (DBSC4_REG_BASE + 0x0624U) -#define DBSC4_REG_DBPDRGD0 (DBSC4_REG_BASE + 0x0628U) -#define DBSC4_REG_DBCAM0CTRL0 (DBSC4_REG_BASE + 0x0940U) -#define DBSC4_REG_DBCAM0STAT0 (DBSC4_REG_BASE + 0x0980U) -#define DBSC4_REG_DBCAM1STAT0 (DBSC4_REG_BASE + 0x0990U) -#define DBSC4_REG_DBCAM2STAT0 (DBSC4_REG_BASE + 0x09A0U) -#define DBSC4_REG_DBCAM3STAT0 (DBSC4_REG_BASE + 0x09B0U) -#define DBSC4_BIT_DBACEN_ACCEN ((uint32_t)(1U << 0)) -#define DBSC4_BIT_DBRFEN_ARFEN ((uint32_t)(1U << 0)) -#define DBSC4_BIT_DBCAMxSTAT0 (0x00000001U) -#define DBSC4_BIT_DBDFIPMSTRCNF_PMSTREN (0x00000001U) -#define DBSC4_SET_DBCMD_OPC_PRE (0x04000000U) -#define DBSC4_SET_DBCMD_OPC_SR (0x0A000000U) -#define DBSC4_SET_DBCMD_OPC_PD (0x08000000U) -#define DBSC4_SET_DBCMD_OPC_MRW (0x0E000000U) -#define DBSC4_SET_DBCMD_CH_ALL (0x00800000U) -#define DBSC4_SET_DBCMD_RANK_ALL (0x00040000U) -#define DBSC4_SET_DBCMD_ARG_ALL (0x00000010U) -#define DBSC4_SET_DBCMD_ARG_ENTER (0x00000000U) -#define DBSC4_SET_DBCMD_ARG_MRW_ODTC (0x00000B00U) -#define DBSC4_SET_DBSYSCNT0_WRITE_ENABLE (0x00001234U) -#define DBSC4_SET_DBSYSCNT0_WRITE_DISABLE (0x00000000U) -#define DBSC4_SET_DBPDLK0_PHY_ACCESS (0x0000A55AU) -#define DBSC4_SET_DBPDRGA0_ACIOCR0 (0x0000001AU) -#define DBSC4_SET_DBPDRGD0_ACIOCR0 (0x33C03C11U) -#define DBSC4_SET_DBPDRGA0_DXCCR (0x00000020U) -#define DBSC4_SET_DBPDRGD0_DXCCR (0x00181006U) -#define DBSC4_SET_DBPDRGA0_PGCR1 (0x00000003U) -#define DBSC4_SET_DBPDRGD0_PGCR1 (0x0380C600U) -#define DBSC4_SET_DBPDRGA0_ACIOCR1 (0x0000001BU) -#define DBSC4_SET_DBPDRGD0_ACIOCR1 (0xAAAAAAAAU) -#define DBSC4_SET_DBPDRGA0_ACIOCR3 (0x0000001DU) -#define DBSC4_SET_DBPDRGD0_ACIOCR3 (0xAAAAAAAAU) -#define DBSC4_SET_DBPDRGA0_ACIOCR5 (0x0000001FU) -#define DBSC4_SET_DBPDRGD0_ACIOCR5 (0x000000AAU) -#define DBSC4_SET_DBPDRGA0_DX0GCR2 (0x000000A2U) -#define DBSC4_SET_DBPDRGD0_DX0GCR2 (0xAAAA0000U) -#define DBSC4_SET_DBPDRGA0_DX1GCR2 (0x000000C2U) -#define DBSC4_SET_DBPDRGD0_DX1GCR2 (0xAAAA0000U) -#define DBSC4_SET_DBPDRGA0_DX2GCR2 (0x000000E2U) -#define DBSC4_SET_DBPDRGD0_DX2GCR2 (0xAAAA0000U) -#define DBSC4_SET_DBPDRGA0_DX3GCR2 (0x00000102U) -#define DBSC4_SET_DBPDRGD0_DX3GCR2 (0xAAAA0000U) -#define DBSC4_SET_DBPDRGA0_ZQCR (0x00000090U) -#define DBSC4_SET_DBPDRGD0_ZQCR_MD19_0 (0x04058904U) -#define DBSC4_SET_DBPDRGD0_ZQCR_MD19_1 (0x04058A04U) -#define DBSC4_SET_DBPDRGA0_DX0GCR0 (0x000000A0U) -#define DBSC4_SET_DBPDRGD0_DX0GCR0 (0x7C0002E5U) -#define DBSC4_SET_DBPDRGA0_DX1GCR0 (0x000000C0U) -#define DBSC4_SET_DBPDRGD0_DX1GCR0 (0x7C0002E5U) -#define DBSC4_SET_DBPDRGA0_DX2GCR0 (0x000000E0U) -#define DBSC4_SET_DBPDRGD0_DX2GCR0 (0x7C0002E5U) -#define DBSC4_SET_DBPDRGA0_DX3GCR0 (0x00000100U) -#define DBSC4_SET_DBPDRGD0_DX3GCR0 (0x7C0002E5U) -#define DBSC4_SET_DBPDRGA0_DX0GCR1 (0x000000A1U) -#define DBSC4_SET_DBPDRGD0_DX0GCR1 (0x55550000U) -#define DBSC4_SET_DBPDRGA0_DX1GCR1 (0x000000C1U) -#define DBSC4_SET_DBPDRGD0_DX1GCR1 (0x55550000U) -#define DBSC4_SET_DBPDRGA0_DX2GCR1 (0x000000E1U) -#define DBSC4_SET_DBPDRGD0_DX2GCR1 (0x55550000U) -#define DBSC4_SET_DBPDRGA0_DX3GCR1 (0x00000101U) -#define DBSC4_SET_DBPDRGD0_DX3GCR1 (0x55550000U) -#define DBSC4_SET_DBPDRGA0_DX0GCR3 (0x000000A3U) -#define DBSC4_SET_DBPDRGD0_DX0GCR3 (0x00008484U) -#define DBSC4_SET_DBPDRGA0_DX1GCR3 (0x000000C3U) -#define DBSC4_SET_DBPDRGD0_DX1GCR3 (0x00008484U) -#define DBSC4_SET_DBPDRGA0_DX2GCR3 (0x000000E3U) -#define DBSC4_SET_DBPDRGD0_DX2GCR3 (0x00008484U) -#define DBSC4_SET_DBPDRGA0_DX3GCR3 (0x00000103U) -#define DBSC4_SET_DBPDRGD0_DX3GCR3 (0x00008484U) -#define RST_BASE (0xE6160000U) -#define RST_MODEMR (RST_BASE + 0x0060U) -#define RST_MODEMR_BIT0 (0x00000001U) +#define DBSC4_REG_BASE (0xE6790000U) +#define DBSC4_REG_DBSYSCNT0 (DBSC4_REG_BASE + 0x0100U) +#define DBSC4_REG_DBACEN (DBSC4_REG_BASE + 0x0200U) +#define DBSC4_REG_DBCMD (DBSC4_REG_BASE + 0x0208U) +#define DBSC4_REG_DBRFEN (DBSC4_REG_BASE + 0x0204U) +#define DBSC4_REG_DBWAIT (DBSC4_REG_BASE + 0x0210U) +#define DBSC4_REG_DBCALCNF (DBSC4_REG_BASE + 0x0424U) +#define DBSC4_REG_DBDFIPMSTRCNF (DBSC4_REG_BASE + 0x0520U) +#define DBSC4_REG_DBPDLK0 (DBSC4_REG_BASE + 0x0620U) +#define DBSC4_REG_DBPDRGA0 (DBSC4_REG_BASE + 0x0624U) +#define DBSC4_REG_DBPDRGD0 (DBSC4_REG_BASE + 0x0628U) +#define DBSC4_REG_DBCAM0CTRL0 (DBSC4_REG_BASE + 0x0940U) +#define DBSC4_REG_DBCAM0STAT0 (DBSC4_REG_BASE + 0x0980U) +#define DBSC4_REG_DBCAM1STAT0 (DBSC4_REG_BASE + 0x0990U) +#define DBSC4_REG_DBCAM2STAT0 (DBSC4_REG_BASE + 0x09A0U) +#define DBSC4_REG_DBCAM3STAT0 (DBSC4_REG_BASE + 0x09B0U) +#define DBSC4_BIT_DBACEN_ACCEN ((uint32_t)(1U << 0)) +#define DBSC4_BIT_DBRFEN_ARFEN ((uint32_t)(1U << 0)) +#define DBSC4_BIT_DBCAMxSTAT0 (0x00000001U) +#define DBSC4_BIT_DBDFIPMSTRCNF_PMSTREN (0x00000001U) +#define DBSC4_SET_DBCMD_OPC_PRE (0x04000000U) +#define DBSC4_SET_DBCMD_OPC_SR (0x0A000000U) +#define DBSC4_SET_DBCMD_OPC_PD (0x08000000U) +#define DBSC4_SET_DBCMD_OPC_MRW (0x0E000000U) +#define DBSC4_SET_DBCMD_CH_ALL (0x00800000U) +#define DBSC4_SET_DBCMD_RANK_ALL (0x00040000U) +#define DBSC4_SET_DBCMD_ARG_ALL (0x00000010U) +#define DBSC4_SET_DBCMD_ARG_ENTER (0x00000000U) +#define DBSC4_SET_DBCMD_ARG_MRW_ODTC (0x00000B00U) +#define DBSC4_SET_DBSYSCNT0_WRITE_ENABLE (0x00001234U) +#define DBSC4_SET_DBSYSCNT0_WRITE_DISABLE (0x00000000U) +#define DBSC4_SET_DBPDLK0_PHY_ACCESS (0x0000A55AU) +#define DBSC4_SET_DBPDRGA0_ACIOCR0 (0x0000001AU) +#define DBSC4_SET_DBPDRGD0_ACIOCR0 (0x33C03C11U) +#define DBSC4_SET_DBPDRGA0_DXCCR (0x00000020U) +#define DBSC4_SET_DBPDRGD0_DXCCR (0x00181006U) +#define DBSC4_SET_DBPDRGA0_PGCR1 (0x00000003U) +#define DBSC4_SET_DBPDRGD0_PGCR1 (0x0380C600U) +#define DBSC4_SET_DBPDRGA0_ACIOCR1 (0x0000001BU) +#define DBSC4_SET_DBPDRGD0_ACIOCR1 (0xAAAAAAAAU) +#define DBSC4_SET_DBPDRGA0_ACIOCR3 (0x0000001DU) +#define DBSC4_SET_DBPDRGD0_ACIOCR3 (0xAAAAAAAAU) +#define DBSC4_SET_DBPDRGA0_ACIOCR5 (0x0000001FU) +#define DBSC4_SET_DBPDRGD0_ACIOCR5 (0x000000AAU) +#define DBSC4_SET_DBPDRGA0_DX0GCR2 (0x000000A2U) +#define DBSC4_SET_DBPDRGD0_DX0GCR2 (0xAAAA0000U) +#define DBSC4_SET_DBPDRGA0_DX1GCR2 (0x000000C2U) +#define DBSC4_SET_DBPDRGD0_DX1GCR2 (0xAAAA0000U) +#define DBSC4_SET_DBPDRGA0_DX2GCR2 (0x000000E2U) +#define DBSC4_SET_DBPDRGD0_DX2GCR2 (0xAAAA0000U) +#define DBSC4_SET_DBPDRGA0_DX3GCR2 (0x00000102U) +#define DBSC4_SET_DBPDRGD0_DX3GCR2 (0xAAAA0000U) +#define DBSC4_SET_DBPDRGA0_ZQCR (0x00000090U) +#define DBSC4_SET_DBPDRGD0_ZQCR_MD19_0 (0x04058904U) +#define DBSC4_SET_DBPDRGD0_ZQCR_MD19_1 (0x04058A04U) +#define DBSC4_SET_DBPDRGA0_DX0GCR0 (0x000000A0U) +#define DBSC4_SET_DBPDRGD0_DX0GCR0 (0x7C0002E5U) +#define DBSC4_SET_DBPDRGA0_DX1GCR0 (0x000000C0U) +#define DBSC4_SET_DBPDRGD0_DX1GCR0 (0x7C0002E5U) +#define DBSC4_SET_DBPDRGA0_DX2GCR0 (0x000000E0U) +#define DBSC4_SET_DBPDRGD0_DX2GCR0 (0x7C0002E5U) +#define DBSC4_SET_DBPDRGA0_DX3GCR0 (0x00000100U) +#define DBSC4_SET_DBPDRGD0_DX3GCR0 (0x7C0002E5U) +#define DBSC4_SET_DBPDRGA0_DX0GCR1 (0x000000A1U) +#define DBSC4_SET_DBPDRGD0_DX0GCR1 (0x55550000U) +#define DBSC4_SET_DBPDRGA0_DX1GCR1 (0x000000C1U) +#define DBSC4_SET_DBPDRGD0_DX1GCR1 (0x55550000U) +#define DBSC4_SET_DBPDRGA0_DX2GCR1 (0x000000E1U) +#define DBSC4_SET_DBPDRGD0_DX2GCR1 (0x55550000U) +#define DBSC4_SET_DBPDRGA0_DX3GCR1 (0x00000101U) +#define DBSC4_SET_DBPDRGD0_DX3GCR1 (0x55550000U) +#define DBSC4_SET_DBPDRGA0_DX0GCR3 (0x000000A3U) +#define DBSC4_SET_DBPDRGD0_DX0GCR3 (0x00008484U) +#define DBSC4_SET_DBPDRGA0_DX1GCR3 (0x000000C3U) +#define DBSC4_SET_DBPDRGD0_DX1GCR3 (0x00008484U) +#define DBSC4_SET_DBPDRGA0_DX2GCR3 (0x000000E3U) +#define DBSC4_SET_DBPDRGD0_DX2GCR3 (0x00008484U) +#define DBSC4_SET_DBPDRGA0_DX3GCR3 (0x00000103U) +#define DBSC4_SET_DBPDRGD0_DX3GCR3 (0x00008484U) +#define RST_BASE (0xE6160000U) +#define RST_MODEMR (RST_BASE + 0x0060U) +#define RST_MODEMR_BIT0 (0x00000001U) #define RCAR_CNTCR_OFF (0x00U) #define RCAR_CNTCVL_OFF (0x08U) @@ -136,17 +136,17 @@ RCAR_INSTANTIATE_LOCK #define RCAR_CNTCR_FCREQ(x) ((uint32_t)(x) << 8U) #if PMIC_ROHM_BD9571 -#define BIT_BKUP_CTRL_OUT ((uint8_t)(1U << 4)) -#define PMIC_BKUP_MODE_CNT (0x20U) -#define PMIC_QLLM_CNT (0x27U) -#define PMIC_RETRY_MAX (100U) -#endif -#define SCTLR_EL3_M_BIT ((uint32_t)1U << 0) -#define RCAR_CA53CPU_NUM_MAX (4U) -#define RCAR_CA57CPU_NUM_MAX (4U) -#define IS_A53A57(c) ((c) == RCAR_CLUSTER_A53A57) -#define IS_CA57(c) ((c) == RCAR_CLUSTER_CA57) -#define IS_CA53(c) ((c) == RCAR_CLUSTER_CA53) +#define BIT_BKUP_CTRL_OUT ((uint8_t)(1U << 4)) +#define PMIC_BKUP_MODE_CNT (0x20U) +#define PMIC_QLLM_CNT (0x27U) +#define PMIC_RETRY_MAX (100U) +#endif /* PMIC_ROHM_BD9571 */ +#define SCTLR_EL3_M_BIT ((uint32_t)1U << 0) +#define RCAR_CA53CPU_NUM_MAX (4U) +#define RCAR_CA57CPU_NUM_MAX (4U) +#define IS_A53A57(c) ((c) == RCAR_CLUSTER_A53A57) +#define IS_CA57(c) ((c) == RCAR_CLUSTER_CA57) +#define IS_CA53(c) ((c) == RCAR_CLUSTER_CA53) #ifndef __ASSEMBLER__ IMPORT_SYM(unsigned long, __system_ram_start__, SYSTEM_RAM_START); @@ -320,11 +320,13 @@ void rcar_pwrc_clusteroff(uint64_t mpidr) c = rcar_pwrc_get_mpidr_cluster(mpidr); dst = IS_CA53(c) ? RCAR_CA53CPUCMCR : RCAR_CA57CPUCMCR; - if (PRR_PRODUCT_M3 == product && cut < PRR_PRODUCT_30) + if (product == PRR_PRODUCT_M3 && cut < PRR_PRODUCT_30) { goto done; + } - if (PRR_PRODUCT_H3 == product && cut <= PRR_PRODUCT_20) + if (product == PRR_PRODUCT_H3 && cut <= PRR_PRODUCT_20) { goto done; + } /* all of the CPUs in the cluster is in the CoreStandby mode */ mmio_write_32(dst, MODE_L2_DOWN); @@ -343,7 +345,7 @@ static void rcar_pwrc_save_timer_state(void) rcar_pwrc_saved_cntfid = mmio_read_32((uintptr_t)(RCAR_CNTC_BASE + RCAR_CNTFID_OFF)); } -#endif +#endif /* RCAR_SYSTEM_SUSPEND */ void rcar_pwrc_restore_timer_state(void) { @@ -372,10 +374,10 @@ void rcar_pwrc_system_reset(void) } #endif /* PMIC_ROHM_BD9571 */ -#define RST_CA53_CPU0_BARH (0xE6160080U) -#define RST_CA53_CPU0_BARL (0xE6160084U) -#define RST_CA57_CPU0_BARH (0xE61600C0U) -#define RST_CA57_CPU0_BARL (0xE61600C4U) +#define RST_CA53_CPU0_BARH (0xE6160080U) +#define RST_CA53_CPU0_BARL (0xE6160084U) +#define RST_CA57_CPU0_BARH (0xE61600C0U) +#define RST_CA57_CPU0_BARL (0xE61600C4U) void rcar_pwrc_setup(void) { @@ -427,11 +429,13 @@ static void __attribute__ ((section(".system_ram"))) product = reg & PRR_PRODUCT_MASK; cut = reg & PRR_CUT_MASK; - if (product == PRR_PRODUCT_M3 && cut < PRR_PRODUCT_30) + if (product == PRR_PRODUCT_M3 && cut < PRR_PRODUCT_30) { goto self_refresh; + } - if (product == PRR_PRODUCT_H3 && cut < PRR_PRODUCT_20) + if (product == PRR_PRODUCT_H3 && cut < PRR_PRODUCT_20) { goto self_refresh; + } mmio_write_32(DBSC4_REG_DBSYSCNT0, DBSC4_SET_DBSYSCNT0_WRITE_ENABLE); @@ -509,7 +513,7 @@ self_refresh: } static void __attribute__ ((section(".system_ram"))) - rcar_pwrc_set_self_refresh_e3(void) +rcar_pwrc_set_self_refresh_e3(void) { uint32_t ddr_md; uint32_t reg; @@ -533,8 +537,10 @@ static void __attribute__ ((section(".system_ram"))) while (mmio_read_32(DBSC4_REG_DBWAIT)) ; - /* Set the auto-refresh enable register */ - /* Set the ARFEN bit to 0 in the DBRFEN */ + /* + * Set the auto-refresh enable register + * Set the ARFEN bit to 0 in the DBRFEN + */ mmio_write_32(DBSC4_REG_DBRFEN, 0); mmio_write_32(DBSC4_REG_DBPDLK0, DBSC4_SET_DBPDLK0_PHY_ACCESS); @@ -638,7 +644,7 @@ static void __attribute__ ((section(".system_ram"))) } void __attribute__ ((section(".system_ram"))) __attribute__ ((noinline)) - rcar_pwrc_go_suspend_to_ram(void) +rcar_pwrc_go_suspend_to_ram(void) { #if PMIC_ROHM_BD9571 int32_t rc = -1, qllm = -1; @@ -713,7 +719,7 @@ void rcar_pwrc_suspend_to_ram(void) error = rcar_iic_dvfs_send(PMIC, REG_KEEP10, 0); if (error) { - ERROR("Failed send KEEP10 init ret=%d \n", error); + ERROR("Failed send KEEP10 init ret=%d\n", error); return; } #endif @@ -835,7 +841,6 @@ int32_t rcar_pwrc_cpu_on_check(uint64_t mpidr) uint64_t my_cpu; int32_t rtn; uint32_t my_cluster_type; - const uint32_t cluster_type[PLATFORM_CLUSTER_COUNT] = { RCAR_CLUSTER_CA53, RCAR_CLUSTER_CA57 @@ -861,6 +866,6 @@ int32_t rcar_pwrc_cpu_on_check(uint64_t mpidr) } } } - return (rtn); + return rtn; } diff --git a/drivers/renesas/rcar/pwrc/pwrc.h b/drivers/renesas/rcar/pwrc/pwrc.h index 2b8178397..f73099b0b 100644 --- a/drivers/renesas/rcar/pwrc/pwrc.h +++ b/drivers/renesas/rcar/pwrc/pwrc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -31,12 +31,12 @@ #define WKUP_PPONR 0x2 #define WKUP_GICREQ 0x3 -#define RCAR_INVALID (0xffffffffU) +#define RCAR_INVALID (0xffffffffU) #define PSYSR_INVALID 0xffffffff -#define RCAR_CLUSTER_A53A57 (0U) -#define RCAR_CLUSTER_CA53 (1U) -#define RCAR_CLUSTER_CA57 (2U) +#define RCAR_CLUSTER_A53A57 (0U) +#define RCAR_CLUSTER_CA53 (1U) +#define RCAR_CLUSTER_CA57 (2U) #ifndef __ASSEMBLER__ void rcar_pwrc_disable_interrupt_wakeup(uint64_t mpidr); -- cgit v1.2.3 From 240c9cbf15e7c1bbd0d787103fcbfc54df18b80c Mon Sep 17 00:00:00 2001 From: Biju Das Date: Sun, 13 Dec 2020 20:02:24 +0000 Subject: drivers: renesas: rcar: dma: Fix coding style Sort the headers alphabetically and replace TAB with a space after #define. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: I07c358294b7c02cbfa360112bbbde0eb5f2b50f5 --- drivers/renesas/rcar/dma/dma_driver.c | 50 +++++++++++++++++------------------ 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/drivers/renesas/rcar/dma/dma_driver.c b/drivers/renesas/rcar/dma/dma_driver.c index e0be46e6f..44ee98592 100644 --- a/drivers/renesas/rcar/dma/dma_driver.c +++ b/drivers/renesas/rcar/dma/dma_driver.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,15 +11,15 @@ #include #include -#include "rcar_def.h" #include "cpg_registers.h" +#include "rcar_def.h" #include "rcar_private.h" /* DMA CHANNEL setting (0/16/32) */ #if RCAR_LSI == RCAR_V3M -#define DMA_CH 16 +#define DMA_CH 16 #else -#define DMA_CH 0 +#define DMA_CH 0 #endif #if (DMA_CH == 0) @@ -39,7 +39,7 @@ /* DMA operation */ #define DMA_DMAOR (DMA_BASE + 0x0060U) /* DMA secure control */ -#define DMA_DMASEC (DMA_BASE + 0x0030U) +#define DMA_DMASEC (DMA_BASE + 0x0030U) /* DMA channel clear */ #define DMA_DMACHCLR (DMA_BASE + 0x0080U) /* DMA source address */ @@ -53,21 +53,21 @@ /* DMA fixed destination address */ #define DMA_DMAFIXDAR (DMA_BASE + 0x8014U) -#define DMA_USE_CHANNEL (0x00000001U) -#define DMAOR_INITIAL (0x0301U) -#define DMACHCLR_CH_ALL (0x0000FFFFU) -#define DMAFIXDAR_32BIT_SHIFT (32U) -#define DMAFIXDAR_DAR_MASK (0x000000FFU) -#define DMADAR_BOUNDARY_ADDR (0x100000000ULL) -#define DMATCR_CNT_SHIFT (6U) -#define DMATCR_MAX (0x00FFFFFFU) -#define DMACHCR_TRN_MODE (0x00105409U) -#define DMACHCR_DE_BIT (0x00000001U) -#define DMACHCR_TE_BIT (0x00000002U) -#define DMACHCR_CHE_BIT (0x80000000U) - -#define DMA_SIZE_UNIT FLASH_TRANS_SIZE_UNIT -#define DMA_FRACTION_MASK (0xFFU) +#define DMA_USE_CHANNEL (0x00000001U) +#define DMAOR_INITIAL (0x0301U) +#define DMACHCLR_CH_ALL (0x0000FFFFU) +#define DMAFIXDAR_32BIT_SHIFT (32U) +#define DMAFIXDAR_DAR_MASK (0x000000FFU) +#define DMADAR_BOUNDARY_ADDR (0x100000000ULL) +#define DMATCR_CNT_SHIFT (6U) +#define DMATCR_MAX (0x00FFFFFFU) +#define DMACHCR_TRN_MODE (0x00105409U) +#define DMACHCR_DE_BIT (0x00000001U) +#define DMACHCR_TE_BIT (0x00000002U) +#define DMACHCR_CHE_BIT (0x80000000U) + +#define DMA_SIZE_UNIT FLASH_TRANS_SIZE_UNIT +#define DMA_FRACTION_MASK (0xFFU) #define DMA_DST_LIMIT (0x10000000000ULL) /* transfer length limit */ @@ -129,16 +129,16 @@ void rcar_dma_exec(uintptr_t dst, uint32_t src, uint32_t len) } if (src & DMA_FRACTION_MASK) { - ERROR("BL2: DMA - source address invalid (0x%x), " - "length (0x%x)\n", src, dma_len); + ERROR("BL2: DMA - src address invalid (0x%x), len=(0x%x)\n", + src, dma_len); panic(); } if ((dst & UINT32_MAX) + dma_len > DMADAR_BOUNDARY_ADDR || - (dst + dma_len > DMA_DST_LIMIT) || + (dst + dma_len > DMA_DST_LIMIT) || (dst & DMA_FRACTION_MASK)) { - ERROR("BL2: DMA - destination address invalid (0x%lx), " - "length (0x%x)\n", dst, dma_len); + ERROR("BL2: DMA - dest address invalid (0x%lx), len=(0x%x)\n", + dst, dma_len); panic(); } -- cgit v1.2.3 From eb52759a1826d640d601e3b0b2d5ca756e745f1b Mon Sep 17 00:00:00 2001 From: Biju Das Date: Sun, 13 Dec 2020 20:28:45 +0000 Subject: drivers: renesas: rcar: io: Code cleanup This patch fixes checkpatch warnings and arrange header as per TF-A coding style. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: I46cd4d9b2851202324fe714e776cf3ad2ee1d923 --- drivers/renesas/rcar/io/io_emmcdrv.c | 38 +++++++----- drivers/renesas/rcar/io/io_memdrv.c | 19 +++--- drivers/renesas/rcar/io/io_rcar.c | 109 ++++++++++++++++++++--------------- 3 files changed, 95 insertions(+), 71 deletions(-) diff --git a/drivers/renesas/rcar/io/io_emmcdrv.c b/drivers/renesas/rcar/io/io_emmcdrv.c index 84240d260..c2b5f7c08 100644 --- a/drivers/renesas/rcar/io/io_emmcdrv.c +++ b/drivers/renesas/rcar/io/io_emmcdrv.c @@ -1,5 +1,5 @@ /* - * 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 */ @@ -10,13 +10,13 @@ #include #include -#include "io_common.h" -#include "io_emmcdrv.h" -#include "io_private.h" #include "emmc_config.h" +#include "emmc_def.h" #include "emmc_hal.h" #include "emmc_std.h" -#include "emmc_def.h" +#include "io_common.h" +#include "io_emmcdrv.h" +#include "io_private.h" static int32_t emmcdrv_dev_open(const uintptr_t spec __attribute__ ((unused)), io_dev_info_t **dev_info); @@ -41,8 +41,9 @@ static io_type_t device_type_emmcdrv(void) static int32_t emmcdrv_block_seek(io_entity_t *entity, int32_t mode, signed long long offset) { - if (mode != IO_SEEK_SET) + if (mode != IO_SEEK_SET) { return IO_FAIL; + } ((file_state_t *) entity->info)->file_pos = offset; @@ -64,12 +65,14 @@ static int32_t emmcdrv_block_read(io_entity_t *entity, uintptr_t buffer, current_file.partition, current_file.file_pos, sector_add, length, sector_num); - if ((buffer + length - 1U) <= (uintptr_t)UINT32_MAX) + if ((buffer + length - 1U) <= (uintptr_t)UINT32_MAX) { emmc_dma = LOADIMAGE_FLAGS_DMA_ENABLE; + } if (emmc_read_sector((uint32_t *) buffer, sector_add, sector_num, - emmc_dma) != EMMC_SUCCESS) + emmc_dma) != EMMC_SUCCESS) { result = IO_FAIL; + } *length_read = length; fp->file_pos += (signed long long)length; @@ -92,8 +95,8 @@ static int32_t emmcdrv_block_open(io_dev_info_t *dev_info, if (emmcdrv_bootpartition == PARTITION_ID_USER) { emmcdrv_bootpartition = mmc_drv_obj.boot_partition_en; - if ((PARTITION_ID_BOOT_1 == emmcdrv_bootpartition) || - (PARTITION_ID_BOOT_2 == emmcdrv_bootpartition)) { + if ((emmcdrv_bootpartition == PARTITION_ID_BOOT_1) || + (emmcdrv_bootpartition == PARTITION_ID_BOOT_2)) { current_file.partition = emmcdrv_bootpartition; NOTICE("BL2: eMMC boot from partition %d\n", @@ -103,16 +106,18 @@ static int32_t emmcdrv_block_open(io_dev_info_t *dev_info, return IO_FAIL; } - if ((PARTITION_ID_USER == block_spec->partition) || - (PARTITION_ID_BOOT_1 == block_spec->partition) || - (PARTITION_ID_BOOT_2 == block_spec->partition)) + if ((block_spec->partition == PARTITION_ID_USER) || + (block_spec->partition == PARTITION_ID_BOOT_1) || + (block_spec->partition == PARTITION_ID_BOOT_2)) { current_file.partition = block_spec->partition; - else + } else { current_file.partition = emmcdrv_bootpartition; + } done: - if (emmc_select_partition(current_file.partition) != EMMC_SUCCESS) + if (emmc_select_partition(current_file.partition) != EMMC_SUCCESS) { return IO_FAIL; + } entity->info = (uintptr_t) ¤t_file; @@ -166,8 +171,9 @@ int32_t rcar_register_io_dev_emmcdrv(const io_dev_connector_t **dev_con) int32_t rc; rc = io_register_device(&emmcdrv_dev_info); - if (rc == IO_SUCCESS) + if (rc == IO_SUCCESS) { *dev_con = &emmcdrv_dev_connector; + } return rc; } diff --git a/drivers/renesas/rcar/io/io_memdrv.c b/drivers/renesas/rcar/io/io_memdrv.c index 7e8c1d3a6..1f31c0fb9 100644 --- a/drivers/renesas/rcar/io/io_memdrv.c +++ b/drivers/renesas/rcar/io/io_memdrv.c @@ -1,5 +1,5 @@ /* - * 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 */ @@ -11,8 +11,8 @@ #include #include "io_common.h" -#include "io_private.h" #include "io_memdrv.h" +#include "io_private.h" #include "rcar_def.h" extern void rcar_dma_exec(uintptr_t dst, uint32_t src, uint32_t len); @@ -21,7 +21,8 @@ static int32_t memdrv_dev_open(const uintptr_t dev __attribute__ ((unused)), io_dev_info_t **dev_info); static int32_t memdrv_dev_close(io_dev_info_t *dev_info); -/* As we need to be able to keep state for seek, only one file can be open +/* + * As we need to be able to keep state for seek, only one file can be open * at a time. Make this a structure and point to the entity->info. When we * can malloc memory we can change this to support more open files. */ @@ -43,12 +44,14 @@ static int32_t memdrv_block_open(io_dev_info_t *dev_info, const uintptr_t spec, { const io_drv_spec_t *block_spec = (io_drv_spec_t *) spec; - /* Since we need to track open state for seek() we only allow one open + /* + * Since we need to track open state for seek() we only allow one open * spec at a time. When we have dynamic memory we can malloc and set * entity->info. */ - if (current_file.in_use != 0U) + if (current_file.in_use != 0U) { return IO_RESOURCES_EXHAUSTED; + } /* File cursor offset for seek and incremental reads etc. */ current_file.base = block_spec->offset; @@ -63,8 +66,9 @@ static int32_t memdrv_block_open(io_dev_info_t *dev_info, const uintptr_t spec, static int32_t memdrv_block_seek(io_entity_t *entity, int32_t mode, signed long long offset) { - if (mode != IO_SEEK_SET) + if (mode != IO_SEEK_SET) { return IO_FAIL; + } ((file_state_t *) entity->info)->file_pos = offset; @@ -142,8 +146,9 @@ int32_t rcar_register_io_dev_memdrv(const io_dev_connector_t **dev_con) int32_t result; result = io_register_device(&memdrv_dev_info); - if (result == IO_SUCCESS) + if (result == IO_SUCCESS) { *dev_con = &memdrv_dev_connector; + } return result; } diff --git a/drivers/renesas/rcar/io/io_rcar.c b/drivers/renesas/rcar/io/io_rcar.c index b82c51078..c3e8319de 100644 --- a/drivers/renesas/rcar/io/io_rcar.c +++ b/drivers/renesas/rcar/io/io_rcar.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -8,8 +8,6 @@ #include #include -#include - #include #include #include @@ -24,6 +22,7 @@ #include "io_rcar.h" #include "io_common.h" #include "io_private.h" +#include extern int32_t plat_get_drv_source(uint32_t id, uintptr_t *dev, uintptr_t *image_spec); @@ -39,7 +38,8 @@ typedef struct { } plat_rcar_name_offset_t; typedef struct { - /* Put position above the struct to allow {0} on static init. + /* + * Put position above the struct to allow {0} on static init. * It is a workaround for a known bug in GCC * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53119 */ @@ -59,7 +59,7 @@ typedef struct { #define RCAR_ATTR_SET_ISNOLOAD(a) (((a) & 0x1) << 16U) #define RCAR_ATTR_SET_CERTOFF(a) (((a) & 0xF) << 8U) #define RCAR_ATTR_SET_ALL(a, b, c) ((uint32_t)(RCAR_ATTR_SET_CALCADDR(a) |\ - RCAR_ATTR_SET_ISNOLOAD(b) | \ + RCAR_ATTR_SET_ISNOLOAD(b) |\ RCAR_ATTR_SET_CERTOFF(c))) #define RCAR_ATTR_GET_CALCADDR(a) ((a) & 0xFU) @@ -136,9 +136,11 @@ int32_t rcar_get_certificate(const int32_t name, uint32_t *cert) { #if TRUSTED_BOARD_BOOT int32_t i; + for (i = 0; i < ARRAY_SIZE(cert_offset); i++) { - if (name != cert_offset[i].name) + if (name != cert_offset[i].name) { continue; + } *cert = RCAR_CERT_SIZE; *cert *= RCAR_ATTR_GET_CERTOFF(cert_offset[i].attr); @@ -157,12 +159,14 @@ static int32_t file_to_offset(const int32_t name, uintptr_t *offset, int32_t i; for (i = 0; i < ARRAY_SIZE(name_offset); i++) { - if (name != name_offset[i].name) + if (name != name_offset[i].name) { continue; + } addr = RCAR_ATTR_GET_CALCADDR(name_offset[i].attr); - if (rcar_image_number + 2 < addr) + if (rcar_image_number + 2U < addr) { continue; + } *offset = rcar_image_header[addr]; *cert = RCAR_CERT_SIZE; @@ -175,8 +179,9 @@ static int32_t file_to_offset(const int32_t name, uintptr_t *offset, #if TRUSTED_BOARD_BOOT for (i = 0; i < ARRAY_SIZE(cert_offset); i++) { - if (name != cert_offset[i].name) + if (name != cert_offset[i].name) { continue; + } *no_load = RCAR_ATTR_GET_ISNOLOAD(cert_offset[i].attr); *partition = 0U; @@ -282,8 +287,9 @@ static int32_t check_load_area(uintptr_t dst, uintptr_t len) result = IO_FAIL; } done: - if (result == IO_FAIL) + if (result == IO_FAIL) { ERROR("BL2: Out of range : dst=0x%lx len=0x%lx\n", dst, len); + } return result; } @@ -307,14 +313,15 @@ static int32_t load_bl33x(void) BL338_IMAGE_ID }; - if (loaded != IO_NOT_SUPPORTED) + if (loaded != IO_NOT_SUPPORTED) { return loaded; + } for (i = 1; i < rcar_image_number; i++) { rc = file_to_offset(img[i], &offset, &cert, &noload, &partition); if (rc != IO_SUCCESS) { - WARN("load_bl33x: failed to get offset\n"); + WARN("%s: failed to get offset\n", __func__); loaded = IO_FAIL; return loaded; } @@ -324,34 +331,34 @@ static int32_t load_bl33x(void) rc = io_open(rcar_handle, rcar_spec, &handle); if (rc != IO_SUCCESS) { - WARN("Failed to open FIP (%i)\n", rc); + WARN("%s: Failed to open FIP (%i)\n", __func__, rc); loaded = IO_FAIL; return loaded; } rc = io_seek(handle, IO_SEEK_SET, offset); if (rc != IO_SUCCESS) { - WARN("load_bl33x: failed to seek\n"); + WARN("%s: failed to seek\n", __func__); loaded = IO_FAIL; return loaded; } rc = check_load_area(dst, len); if (rc != IO_SUCCESS) { - WARN("load_bl33x: check load area\n"); + WARN("%s: check load area\n", __func__); loaded = IO_FAIL; return loaded; } rc = io_read(handle, dst, len, &cnt); if (rc != IO_SUCCESS) { - WARN("load_bl33x: failed to read\n"); + WARN("%s: failed to read\n", __func__); loaded = IO_FAIL; return loaded; } #if TRUSTED_BOARD_BOOT rc = auth_mod_verify_img(img[i], (void *)dst, len); - if (rc) { + if (rc != 0) { memset((void *)dst, 0x00, len); loaded = IO_FAIL; return loaded; @@ -367,8 +374,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) = { - 0}; + uint64_t header[64] __aligned(FLASH_TRANS_SIZE_UNIT) = {0UL}; uintptr_t handle; ssize_t offset; uint32_t i; @@ -382,8 +388,9 @@ static int32_t rcar_dev_init(io_dev_info_t *dev_info, const uintptr_t name) return IO_FAIL; } - if (RCAR_CERT_LOAD == rcar_cert_load) + if (rcar_cert_load == RCAR_CERT_LOAD) { return IO_SUCCESS; + } rc = io_open(rcar_handle, rcar_spec, &handle); if (rc != IO_SUCCESS) { @@ -391,16 +398,18 @@ static int32_t rcar_dev_init(io_dev_info_t *dev_info, const uintptr_t name) return IO_FAIL; } - /* get start address list */ - /* [0] address num */ - /* [1] BL33-1 image address */ - /* [2] BL33-2 image address */ - /* [3] BL33-3 image address */ - /* [4] BL33-4 image address */ - /* [5] BL33-5 image address */ - /* [6] BL33-6 image address */ - /* [7] BL33-7 image address */ - /* [8] BL33-8 image address */ + /* + * get start address list + * [0] address num + * [1] BL33-1 image address + * [2] BL33-2 image address + * [3] BL33-3 image address + * [4] BL33-4 image address + * [5] BL33-5 image address + * [6] BL33-6 image address + * [7] BL33-7 image address + * [8] BL33-8 image address + */ offset = name == EMMC_DEV_ID ? RCAR_EMMC_CERT_HEADER : RCAR_FLASH_CERT_HEADER; rc = io_seek(handle, IO_SEEK_SET, offset); @@ -447,8 +456,9 @@ static int32_t rcar_dev_init(io_dev_info_t *dev_info, const uintptr_t name) rcar_cert_load = RCAR_CERT_LOAD; error: - if (rc != IO_SUCCESS) + if (rc != IO_SUCCESS) { rc = IO_FAIL; + } io_close(handle); @@ -464,13 +474,15 @@ static int32_t rcar_file_open(io_dev_info_t *info, const uintptr_t file_spec, uint32_t noload, cert, len; int32_t rc; - /* Only one file open at a time. We need to track state (ie, file - * cursor position). Since the header lives at * offset zero, this entry + /* + * Only one file open at a time. We need to track state (ie, file + * cursor position). Since the header lives at offset zero, this entry * should never be zero in an active file. * Once the system supports dynamic memory allocation we will allow more - * than one open file at a time. */ + * than one open file at a time. + */ if (current_file.offset != 0U) { - WARN("rcar_file_open : Only one open file at a time.\n"); + WARN("%s: Only one open file at a time.\n", __func__); return IO_RESOURCES_EXHAUSTED; } @@ -480,7 +492,7 @@ static int32_t rcar_file_open(io_dev_info_t *info, const uintptr_t file_spec, return IO_FAIL; } - if (noload) { + if (noload != 0U) { current_file.offset = 1; current_file.dst = 0; current_file.size = 1; @@ -494,12 +506,10 @@ static int32_t rcar_file_open(io_dev_info_t *info, const uintptr_t file_spec, rcar_read_certificate((uint64_t) cert, &len, &dst); - /*----------------* - * Baylibre: HACK * - *----------------*/ - if (BL31_IMAGE_ID == spec->offset && len < RCAR_TRUSTED_SRAM_SIZE) { - WARN("r-car ignoring the BL31 size from certificate," - "using RCAR_TRUSTED_SRAM_SIZE instead\n"); + /* Baylibre: HACK */ + if (spec->offset == BL31_IMAGE_ID && len < RCAR_TRUSTED_SRAM_SIZE) { + WARN("%s,%s\n", "r-car ignoring the BL31 size from certificate", + "using RCAR_TRUSTED_SRAM_SIZE instead"); len = RCAR_TRUSTED_SRAM_SIZE; } @@ -536,7 +546,7 @@ static int32_t rcar_file_read(io_entity_t *entity, uintptr_t buffer, #else static uint32_t load_bl33x_counter; #endif - if (current_file.no_load) { + if (current_file.no_load != 0U) { *cnt = length; return IO_SUCCESS; } @@ -551,14 +561,14 @@ static int32_t rcar_file_read(io_entity_t *entity, uintptr_t buffer, rc = io_seek(handle, IO_SEEK_SET, offset); if (rc != IO_SUCCESS) { - WARN("rcar_file_read: failed to seek\n"); + WARN("%s: failed to seek\n", __func__); goto error; } if (load_bl33x_counter == RCAR_COUNT_LOAD_BL33) { rc = check_load_area(buffer, length); if (rc != IO_SUCCESS) { - WARN("rcar_file_read: load area err\n"); + WARN("%s: load area err\n", __func__); goto error; } } @@ -573,8 +583,9 @@ static int32_t rcar_file_read(io_entity_t *entity, uintptr_t buffer, io_close(handle); load_bl33x_counter += 1; - if (load_bl33x_counter == RCAR_COUNT_LOAD_BL33X) + if (load_bl33x_counter == RCAR_COUNT_LOAD_BL33X) { return load_bl33x(); + } return IO_SUCCESS; error: @@ -584,8 +595,9 @@ error: static int32_t rcar_file_close(io_entity_t *entity) { - if (current_file.offset) + if (current_file.offset != 0U) { memset(¤t_file, 0, sizeof(current_file)); + } entity->info = 0U; @@ -634,8 +646,9 @@ int32_t rcar_register_io_dev(const io_dev_connector_t **dev_con) int32_t result; result = io_register_device(&rcar_dev_info); - if (result == IO_SUCCESS) + if (result == IO_SUCCESS) { *dev_con = &rcar_dev_connector; + } return result; } -- cgit v1.2.3 From 0b3d4273fa9a18de64ce457834724fe6471237d8 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 6 Oct 2017 10:24:17 +0200 Subject: cadence: Change logic in uart driver Write char if fifo is empty. If this is done like this all chars are printed. Because origin code just put that chars to fifo and in case of reset messages were missing. Before this change chars are put to fifo and only check before adding if fifo is full. The patch is changing this logic that it is adding char only when fifo is empty to make sure that in case of reset (by another SW for example) all chars are printed. Maybe one char can be missed but for IP itself it is much easier to send just one char compare to full fifo. Signed-off-by: Michal Simek Change-Id: Ic24c2c1252bce24be2aed68ee29477ca4a549e5f --- drivers/cadence/uart/aarch64/cdns_console.S | 8 ++++---- include/drivers/cadence/cdns_uart.h | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/cadence/uart/aarch64/cdns_console.S b/drivers/cadence/uart/aarch64/cdns_console.S index d1995e3e6..4c1a80efc 100644 --- a/drivers/cadence/uart/aarch64/cdns_console.S +++ b/drivers/cadence/uart/aarch64/cdns_console.S @@ -105,15 +105,15 @@ func console_cdns_core_putc cmp w0, #0xA b.ne 2f 1: - /* Check if the transmit FIFO is full */ + /* Check if the transmit FIFO is empty */ ldr w2, [x1, #R_UART_SR] - tbnz w2, #UART_SR_INTR_TFUL_BIT, 1b + tbz w2, #UART_SR_INTR_TEMPTY_BIT, 1b mov w2, #0xD str w2, [x1, #R_UART_TX] 2: - /* Check if the transmit FIFO is full */ + /* Check if the transmit FIFO is empty */ ldr w2, [x1, #R_UART_SR] - tbnz w2, #UART_SR_INTR_TFUL_BIT, 2b + tbz w2, #UART_SR_INTR_TEMPTY_BIT, 2b str w0, [x1, #R_UART_TX] ret endfunc console_cdns_core_putc diff --git a/include/drivers/cadence/cdns_uart.h b/include/drivers/cadence/cdns_uart.h index 46ba4663e..30ca910b9 100644 --- a/include/drivers/cadence/cdns_uart.h +++ b/include/drivers/cadence/cdns_uart.h @@ -21,6 +21,7 @@ #define R_UART_SR 0x2C #define UART_SR_INTR_REMPTY_BIT 1 #define UART_SR_INTR_TFUL_BIT 4 +#define UART_SR_INTR_TEMPTY_BIT 3 #define R_UART_TX 0x30 #define R_UART_RX 0x30 -- cgit v1.2.3 From b04921f73a19c7adfb408b89e5c7547304156555 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= Date: Thu, 7 Jan 2021 21:52:44 +0100 Subject: plat: marvell: armada: a3k: improve 4GB DRAM usage from 3.375 GB to 3.75 GB MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current configuration of CPU windows on Armada 37x0 with 4 GB DRAM can only utilize 3.375 GB of memory. This is because there are only 5 configuration windows, configured as such (in hexadecimal, also showing ranges not configurable by CPU windows): 0 - 80000000 | 2 GB | DDR | CPU window 0 80000000 - C0000000 | 1 GB | DDR | CPU window 1 C0000000 - D0000000 | 256 MB | DDR | CPU window 2 D0000000 - D2000000 | 32 MB | | Internal regs empty space | | | D8000000 - D8010000 | 64 KB | | CCI regs empty space | | | E0000000 - E8000000 | 128 MB | DDR | CPU window 3 E8000000 - F0000000 | 128 MB | PCIe | CPU window 4 empty space | | | FFF00000 - end | 64 KB | | Boot ROM This can be improved by taking into account that: - CCI window can be moved (the base address is only hardcoded in TF-A; U-Boot and Linux will not break with changing of this address) - PCIe window can be moved (upstream U-Boot can change device-tree ranges of PCIe if PCIe window is moved) Change the layout after the Internal regs as such: D2000000 - F2000000 | 512 MB | DDR | CPU window 3 F2000000 - FA000000 | 128 MB | PCIe | CPU window 4 empty space | | | FE000000 - FE010000 | 64 KB | | CCI regs empty space | | | FFF00000 - end | 64 KB | | Boot ROM (Note that CCI regs base address is moved from D8000000 to FE000000 in all cases, not only for the configuration with 4 GB of DRAM. This is because TF-A is built with this address as a constant, so we cannot change this address at runtime only on some boards.) This yields 3.75 GB of usable RAM. Moreover U-Boot can theoretically reconfigure the PCIe window to DDR if it discovers that no PCIe card is connected. This can add another 128 MB of DRAM (resulting only in 128 MB of DRAM not being used). Signed-off-by: Marek Behún Change-Id: I4ca1999f852f90055fac8b2c4f7e80275a13ad7e --- plat/marvell/armada/a3k/common/a3700_common.mk | 5 +- plat/marvell/armada/a3k/common/dram_win.c | 56 +++++++++++----------- .../armada/a3k/common/include/a3700_plat_def.h | 12 +++-- .../armada/a3k/common/include/platform_def.h | 6 ++- plat/marvell/armada/a3k/common/plat_cci.c | 35 ++++++++++++++ 5 files changed, 80 insertions(+), 34 deletions(-) create mode 100644 plat/marvell/armada/a3k/common/plat_cci.c diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk index 712b16202..74cf78ac5 100644 --- a/plat/marvell/armada/a3k/common/a3700_common.mk +++ b/plat/marvell/armada/a3k/common/a3700_common.mk @@ -1,5 +1,5 @@ # -# Copyright (C) 2018-2020 Marvell International Ltd. +# Copyright (C) 2018-2021 Marvell International Ltd. # # SPDX-License-Identifier: BSD-3-Clause # https://spdx.org/licenses @@ -38,7 +38,6 @@ PLAT_INCLUDES := -I$(PLAT_FAMILY_BASE)/$(PLAT) \ -I$/drivers/arm/gic/common/ PLAT_BL_COMMON_SOURCES := $(PLAT_COMMON_BASE)/aarch64/a3700_common.c \ - $(MARVELL_COMMON_BASE)/marvell_cci.c \ $(MARVELL_DRV_BASE)/uart/a3700_console.S BL1_SOURCES += $(PLAT_COMMON_BASE)/aarch64/plat_helpers.S \ @@ -50,12 +49,14 @@ MARVELL_DRV := $(MARVELL_DRV_BASE)/comphy/phy-comphy-3700.c BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \ $(PLAT_COMMON_BASE)/aarch64/plat_helpers.S \ + $(PLAT_COMMON_BASE)/plat_cci.c \ $(PLAT_COMMON_BASE)/plat_pm.c \ $(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 \ $(MARVELL_COMMON_BASE)/marvell_gicv3.c \ $(MARVELL_GIC_SOURCES) \ diff --git a/plat/marvell/armada/a3k/common/dram_win.c b/plat/marvell/armada/a3k/common/dram_win.c index 694f6d480..e89f29504 100644 --- a/plat/marvell/armada/a3k/common/dram_win.c +++ b/plat/marvell/armada/a3k/common/dram_win.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 Marvell International Ltd. + * Copyright (C) 2018-2021 Marvell International Ltd. * * SPDX-License-Identifier: BSD-3-Clause * https://spdx.org/licenses @@ -92,33 +92,35 @@ struct cpu_win_configuration mv_cpu_wins[CPU_WIN_CONFIG_MAX][MV_CPU_WIN_NUM] = { }, /* - * If total dram size is more than 2GB, now there is only one case - 4GB - * dram; we will use below cpu windows configurations: - * - Internal Regs, CCI-400, Boot Rom and PCIe windows are kept as - * default; - * - Use 4 CPU decode windows for DRAM, which cover 3.375GB DRAM; - * DDR window 0 is configured in tim header with 2GB size, no need to - * configure it again here; + * If total DRAM size is more than 2GB, now there is only one case: + * 4GB of DRAM; to better utilize address space (for maximization of + * DRAM usage), we will use the configuration of CPU windows below: + * - Internal Regs and Boot ROM windows are kept as default; + * - CCI-400 is moved from its default address to another address + * (this is actually done even if DRAM size is not more than 2 GB, + * because the firmware is compiled with that address as a + * constant); + * - PCIe window is moved to another address; + * - Use 4 CPU decode windows for DRAM, which cover 3.75GB DRAM; + * DDR window 0 is configured in tim header with 2G B size, no need + * to configure it again here; * - * 0xFFFFFFFF ---> |-----------------------| - * | Boot ROM | 64KB + * 0xFFFFFFFF ---> +-----------------------+ + * | Boot ROM | 64 KB * 0xFFF00000 ---> +-----------------------+ * : : - * 0xF0000000 ---> |-----------------------| - * | PCIE | 128 MB - * 0xE8000000 ---> |-----------------------| - * | DDR window 3 | 128 MB - * 0xE0000000 ---> +-----------------------+ - * : : - * 0xD8010000 ---> |-----------------------| - * | CCI Regs | 64 KB - * 0xD8000000 ---> +-----------------------+ - * : : + * 0xFE010000 ---> +-----------------------+ + * | CCI Regs | 64 KB + * 0xFE000000 ---> +-----------------------+ * : : + * 0xFA000000 ---> +-----------------------+ + * | PCIE | 128 MB + * 0xF2000000 ---> +-----------------------+ + * | DDR window 3 | 512 MB * 0xD2000000 ---> +-----------------------+ - * | Internal Regs | 32MB + * | Internal Regs | 32 MB * 0xD0000000 ---> |-----------------------| - * | DDR window 2 | 256 MB + * | DDR window 2 | 256 MB * 0xC0000000 ---> |-----------------------| * | | * | DDR window 1 | 1 GB @@ -155,14 +157,14 @@ struct cpu_win_configuration mv_cpu_wins[CPU_WIN_CONFIG_MAX][MV_CPU_WIN_NUM] = { 0xc0000000}, {CPU_WIN_ENABLED, CPU_WIN_TARGET_DRAM, - 0xe0000000, - 0x08000000, - 0xe0000000}, + 0xd2000000, + 0x20000000, + 0xd2000000}, {CPU_WIN_ENABLED, CPU_WIN_TARGET_PCIE, - 0xe8000000, + 0xf2000000, 0x08000000, - 0xe8000000}, + 0xf2000000}, }, }; diff --git a/plat/marvell/armada/a3k/common/include/a3700_plat_def.h b/plat/marvell/armada/a3k/common/include/a3700_plat_def.h index d23f5beea..83d95616b 100644 --- a/plat/marvell/armada/a3k/common/include/a3700_plat_def.h +++ b/plat/marvell/armada/a3k/common/include/a3700_plat_def.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2020 Marvell International Ltd. + * Copyright (C) 2018-2021 Marvell International Ltd. * * SPDX-License-Identifier: BSD-3-Clause * https://spdx.org/licenses @@ -41,8 +41,14 @@ #define MVEBU_GICR_BASE 0x1D40000 #define MVEBU_GICC_BASE 0x1D80000 -/* CCI-400 */ -#define MVEBU_CCI_BASE 0x8000000 +/* + * CCI-400 base address + * This address is absolute, not relative to MVEBU_REGS_BASE. + * This is not the default CCI base address (that would be 0xD8000000). + * Rather we remap CCI to this address to better utilize the address space. + * (The remapping is done in plat/marvell/armada/a3k/common/plat_cci.c) + */ +#define MVEBU_CCI_BASE 0xFE000000 /***************************************************************************** * North and south bridge register base diff --git a/plat/marvell/armada/a3k/common/include/platform_def.h b/plat/marvell/armada/a3k/common/include/platform_def.h index 3d839f820..057ee2eb9 100644 --- a/plat/marvell/armada/a3k/common/include/platform_def.h +++ b/plat/marvell/armada/a3k/common/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2019 Marvell International Ltd. + * Copyright (C) 2016-2021 Marvell International Ltd. * * SPDX-License-Identifier: BSD-3-Clause * https://spdx.org/licenses @@ -148,7 +148,7 @@ #define PLAT_MARVELL_SHARED_RAM_CACHED 1 /* CCI related constants */ -#define PLAT_MARVELL_CCI_BASE (MVEBU_REGS_BASE + MVEBU_CCI_BASE) +#define PLAT_MARVELL_CCI_BASE MVEBU_CCI_BASE #define PLAT_MARVELL_CCI_CLUSTER0_SL_IFACE_IX 3 #define PLAT_MARVELL_CCI_CLUSTER1_SL_IFACE_IX 4 @@ -227,6 +227,8 @@ #define CPU_DEC_RLR_REMAP_LOW_MASK \ (0xffff << CPU_DEC_BR_BASE_OFFS) +#define CPU_DEC_CCI_BASE_REG (MVEBU_CPU_DEC_WIN_REG_BASE + 0xe0) + /* Securities */ #define IRQ_SEC_OS_TICK_INT MARVELL_IRQ_SEC_PHY_TIMER diff --git a/plat/marvell/armada/a3k/common/plat_cci.c b/plat/marvell/armada/a3k/common/plat_cci.c new file mode 100644 index 000000000..56f091fef --- /dev/null +++ b/plat/marvell/armada/a3k/common/plat_cci.c @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2021 Marek Behun + * + * Based on plat/marvell/armada/common/marvell_cci.c + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include + +#include + +static const int cci_map[] = { + PLAT_MARVELL_CCI_CLUSTER0_SL_IFACE_IX, + PLAT_MARVELL_CCI_CLUSTER1_SL_IFACE_IX +}; + +/* + * This redefines the weak definition in + * plat/marvell/armada/common/marvell_cci.c + */ +void plat_marvell_interconnect_init(void) +{ + /* + * To better utilize the address space, we remap CCI base address from + * the default (0xD8000000) to MVEBU_CCI_BASE. + * This has to be done here, rather than in cpu_wins_init(), because + * cpu_wins_init() is called later. + */ + mmio_write_32(CPU_DEC_CCI_BASE_REG, MVEBU_CCI_BASE >> 20); + + cci_init(PLAT_MARVELL_CCI_BASE, cci_map, ARRAY_SIZE(cci_map)); +} -- cgit v1.2.3 From 19fe3c72956be2d68dcc6edd7b0779a9a86da87d Mon Sep 17 00:00:00 2001 From: Rajan Vaja Date: Fri, 5 Oct 2018 04:42:57 -0700 Subject: zynqmp: pm: Update PM version and support PM version check ATF is not checking PM version. Add version check in such a way that it is compatible with current and newer version of PM. Signed-off-by: Rajan Vaja Change-Id: Ia095d118121e6f75e8d320e87d5e2018068fa079 --- plat/xilinx/zynqmp/pm_service/pm_defs.h | 2 +- plat/xilinx/zynqmp/pm_service/pm_svc_main.c | 38 +++++++++++++++++------------ plat/xilinx/zynqmp/sip_svc_setup.c | 4 +-- 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/plat/xilinx/zynqmp/pm_service/pm_defs.h b/plat/xilinx/zynqmp/pm_service/pm_defs.h index ee31c9267..3324431dd 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_defs.h +++ b/plat/xilinx/zynqmp/pm_service/pm_defs.h @@ -18,7 +18,7 @@ * (PM_VERSION_MAJOR << 16) | PM_VERSION_MINOR */ #define PM_VERSION_MAJOR 1 -#define PM_VERSION_MINOR 0 +#define PM_VERSION_MINOR 1 #define PM_VERSION ((PM_VERSION_MAJOR << 16) | PM_VERSION_MINOR) diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c index a4bc1ac08..49824c70d 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c +++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c @@ -29,8 +29,8 @@ #define PM_SET_SUSPEND_MODE 0xa02 #define PM_GET_TRUSTZONE_VERSION 0xa03 -/* !0 - UP, 0 - DOWN */ -static int32_t pm_up = 0; +/* pm_up = !0 - UP, pm_up = 0 - DOWN */ +static int32_t pm_up, ipi_irq_flag; #if ZYNQMP_WDT_RESTART static spinlock_t inc_lock; @@ -210,6 +210,15 @@ int pm_setup(void) status = pm_ipi_init(primary_proc); + ret = pm_get_api_version(&pm_ctx.api_version); + if (pm_ctx.api_version < PM_VERSION) { + ERROR("BL31: Platform Management API version error. Expected: " + "v%d.%d - Found: v%d.%d\n", PM_VERSION_MAJOR, + PM_VERSION_MINOR, pm_ctx.api_version >> 16, + pm_ctx.api_version & 0xFFFF); + return -EINVAL; + } + #if ZYNQMP_WDT_RESTART status = pm_wdt_restart_setup(); if (status) @@ -321,22 +330,21 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, case PM_GET_API_VERSION: /* Check is PM API version already verified */ - if (pm_ctx.api_version == PM_VERSION) { + if (pm_ctx.api_version >= PM_VERSION) { + if (!ipi_irq_flag) { + /* + * Enable IPI IRQ + * assume the rich OS is OK to handle callback IRQs now. + * Even if we were wrong, it would not enable the IRQ in + * the GIC. + */ + pm_ipi_irq_enable(primary_proc); + ipi_irq_flag = 1; + } SMC_RET1(handle, (uint64_t)PM_RET_SUCCESS | - ((uint64_t)PM_VERSION << 32)); + ((uint64_t)pm_ctx.api_version << 32)); } - ret = pm_get_api_version(&pm_ctx.api_version); - /* - * Enable IPI IRQ - * assume the rich OS is OK to handle callback IRQs now. - * Even if we were wrong, it would not enable the IRQ in - * the GIC. - */ - pm_ipi_irq_enable(primary_proc); - SMC_RET1(handle, (uint64_t)ret | - ((uint64_t)pm_ctx.api_version << 32)); - case PM_SET_CONFIGURATION: ret = pm_set_configuration(pm_arg[0]); SMC_RET1(handle, (uint64_t)ret); diff --git a/plat/xilinx/zynqmp/sip_svc_setup.c b/plat/xilinx/zynqmp/sip_svc_setup.c index 4c29da231..114da33d6 100644 --- a/plat/xilinx/zynqmp/sip_svc_setup.c +++ b/plat/xilinx/zynqmp/sip_svc_setup.c @@ -44,9 +44,7 @@ DEFINE_SVC_UUID2(zynqmp_sip_uuid, static int32_t sip_svc_setup(void) { /* PM implementation as SiP Service */ - pm_setup(); - - return 0; + return pm_setup(); } /** -- cgit v1.2.3 From 0a67923b99e1b1108ac0543e28ba9b9f4ccef1cc Mon Sep 17 00:00:00 2001 From: Will Wong Date: Sun, 22 Nov 2020 23:45:21 -0800 Subject: zynqmp: pm: Add support for PS and system reset on WDT restart Add ability to support PS and System reset after idling the APU, by reading the restart scope from the PMU. Signed-off-by: Will Wong Signed-off-by: Rajan Vaja Change-Id: I23c01725d8ebb71ad34be02ab204411b93620702 --- plat/xilinx/zynqmp/include/zynqmp_def.h | 3 +++ plat/xilinx/zynqmp/pm_service/pm_svc_main.c | 7 +++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/plat/xilinx/zynqmp/include/zynqmp_def.h b/plat/xilinx/zynqmp/include/zynqmp_def.h index b492210b0..f47463000 100644 --- a/plat/xilinx/zynqmp/include/zynqmp_def.h +++ b/plat/xilinx/zynqmp/include/zynqmp_def.h @@ -345,6 +345,9 @@ #define PMU_GLOBAL_GEN_STORAGE4 (GGS_BASEADDR + 0x10) /* Warm restart boot health status mask */ #define PM_BOOT_HEALTH_STATUS_MASK U(0x01) +/* WDT restart scope shift and mask */ +#define RESTART_SCOPE_SHIFT (3) +#define RESTART_SCOPE_MASK (0x3U << RESTART_SCOPE_SHIFT) /*AFI registers */ #define AFIFM6_WRCTRL U(13) diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c index 49824c70d..a49bda8d2 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c +++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c @@ -142,6 +142,8 @@ static uint64_t __unused __dead2 zynqmp_sgi7_irq(uint32_t id, uint32_t flags, void *handle, void *cookie) { int i; + uint32_t value; + /* enter wfi and stay there */ INFO("Entering wfi\n"); @@ -156,8 +158,9 @@ static uint64_t __unused __dead2 zynqmp_sgi7_irq(uint32_t id, uint32_t flags, spin_unlock(&inc_lock); if (active_cores == 0) { - pm_system_shutdown(PMF_SHUTDOWN_TYPE_RESET, - PMF_SHUTDOWN_SUBTYPE_SUBSYSTEM); + pm_mmio_read(PMU_GLOBAL_GEN_STORAGE4, &value); + value = (value & RESTART_SCOPE_MASK) >> RESTART_SCOPE_SHIFT; + pm_system_shutdown(PMF_SHUTDOWN_TYPE_RESET, value); } /* enter wfi and stay there */ -- cgit v1.2.3 From e26c59d2c968eb0122bf1c333d5ceba534d5fe45 Mon Sep 17 00:00:00 2001 From: johpow01 Date: Tue, 6 Oct 2020 17:55:25 -0500 Subject: Workaround for Cortex A78 erratum 1941498 Cortex A78 erratum 1941498 is a Cat B erratum that applies to revisions r0p0, r1p0, and r1p1. The workaround is to set bit 8 in the ECTLR_EL1 register, there is a small performance cost (<0.5%) for setting this bit. SDEN can be found here: https://documentation-service.arm.com/static/5fb66157ca04df4095c1cc2e Signed-off-by: John Powell Change-Id: I959cee8e3d46c1b84ff5e4409ce5945e459cc6a9 --- docs/design/cpu-specific-build-macros.rst | 3 +++ include/lib/cpus/aarch64/cortex_a78.h | 19 ++++++++-------- lib/cpus/aarch64/cortex_a78.S | 38 +++++++++++++++++++++++++++++-- lib/cpus/cpu-ops.mk | 10 +++++++- 4 files changed, 58 insertions(+), 12 deletions(-) diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst index d859cc581..09aa3017f 100644 --- a/docs/design/cpu-specific-build-macros.rst +++ b/docs/design/cpu-specific-build-macros.rst @@ -265,6 +265,9 @@ For Cortex-A78, the following errata build flags are defined : - ``ERRATA_A78_1688305``: This applies errata 1688305 workaround to Cortex-A78 CPU. This needs to be enabled only for revision r0p0 - r1p0 of the CPU. +- ``ERRATA_A78_1941498``: This applies errata 1941498 workaround to Cortex-A78 + CPU. This needs to be enabled for revisions r0p0, r1p0, and r1p1 of the CPU. + For Neoverse N1, the following errata build flags are defined : - ``ERRATA_N1_1073348``: This applies errata 1073348 workaround to Neoverse-N1 diff --git a/include/lib/cpus/aarch64/cortex_a78.h b/include/lib/cpus/aarch64/cortex_a78.h index 0d4712b6a..caa512046 100644 --- a/include/lib/cpus/aarch64/cortex_a78.h +++ b/include/lib/cpus/aarch64/cortex_a78.h @@ -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 */ @@ -15,17 +15,18 @@ * CPU Extended Control register specific definitions. ******************************************************************************/ #define CORTEX_A78_CPUECTLR_EL1 S3_0_C15_C1_4 +#define CORTEX_A78_CPUECTLR_EL1_BIT_8 (ULL(1) << 8) /******************************************************************************* * CPU Power Control register specific definitions ******************************************************************************/ -#define CORTEX_A78_CPUPWRCTLR_EL1 S3_0_C15_C2_7 +#define CORTEX_A78_CPUPWRCTLR_EL1 S3_0_C15_C2_7 #define CORTEX_A78_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT U(1) /******************************************************************************* * CPU Auxiliary Control register specific definitions. ******************************************************************************/ -#define CORTEX_A78_ACTLR_TAM_BIT (ULL(1) << 30) +#define CORTEX_A78_ACTLR_TAM_BIT (ULL(1) << 30) #define CORTEX_A78_ACTLR2_EL1 S3_0_C15_C1_1 #define CORTEX_A78_ACTLR2_EL1_BIT_1 (ULL(1) << 1) @@ -33,12 +34,12 @@ /******************************************************************************* * CPU Activity Monitor Unit register specific definitions. ******************************************************************************/ -#define CPUAMCNTENCLR0_EL0 S3_3_C15_C2_4 -#define CPUAMCNTENSET0_EL0 S3_3_C15_C2_5 -#define CPUAMCNTENCLR1_EL0 S3_3_C15_C3_0 -#define CPUAMCNTENSET1_EL0 S3_3_C15_C3_1 +#define CPUAMCNTENCLR0_EL0 S3_3_C15_C2_4 +#define CPUAMCNTENSET0_EL0 S3_3_C15_C2_5 +#define CPUAMCNTENCLR1_EL0 S3_3_C15_C3_0 +#define CPUAMCNTENSET1_EL0 S3_3_C15_C3_1 -#define CORTEX_A78_AMU_GROUP0_MASK U(0xF) -#define CORTEX_A78_AMU_GROUP1_MASK U(0x7) +#define CORTEX_A78_AMU_GROUP0_MASK U(0xF) +#define CORTEX_A78_AMU_GROUP1_MASK U(0x7) #endif /* CORTEX_A78_H */ diff --git a/lib/cpus/aarch64/cortex_a78.S b/lib/cpus/aarch64/cortex_a78.S index 9914f12e8..ef760ed8a 100644 --- a/lib/cpus/aarch64/cortex_a78.S +++ b/lib/cpus/aarch64/cortex_a78.S @@ -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 */ @@ -31,7 +31,7 @@ func errata_a78_1688305_wa bl check_errata_1688305 cbz x0, 1f mrs x1, CORTEX_A78_ACTLR2_EL1 - orr x1, x1, CORTEX_A78_ACTLR2_EL1_BIT_1 + orr x1, x1, #CORTEX_A78_ACTLR2_EL1_BIT_1 msr CORTEX_A78_ACTLR2_EL1, x1 isb 1: @@ -44,6 +44,34 @@ func check_errata_1688305 b cpu_rev_var_ls endfunc check_errata_1688305 + /* -------------------------------------------------- + * Errata Workaround for Cortex A78 Errata #1941498. + * This applies to revisions r0p0, r1p0, and r1p1. + * x0: variant[4:7] and revision[0:3] of current cpu. + * Shall clobber: x0-x17 + * -------------------------------------------------- + */ +func errata_a78_1941498_wa + /* Compare x0 against revision <= r1p1 */ + mov x17, x30 + bl check_errata_1941498 + cbz x0, 1f + + /* Set bit 8 in ECTLR_EL1 */ + mrs x1, CORTEX_A78_CPUECTLR_EL1 + orr x1, x1, #CORTEX_A78_CPUECTLR_EL1_BIT_8 + msr CORTEX_A78_CPUECTLR_EL1, x1 + isb +1: + ret x17 +endfunc errata_a78_1941498_wa + +func check_errata_1941498 + /* Check for revision <= r1p1, might need to be updated later. */ + mov x1, #0x11 + b cpu_rev_var_ls +endfunc check_errata_1941498 + /* ------------------------------------------------- * The CPU Ops reset function for Cortex-A78 * ------------------------------------------------- @@ -58,6 +86,11 @@ func cortex_a78_reset_func bl errata_a78_1688305_wa #endif +#if ERRATA_A78_1941498 + mov x0, x18 + bl errata_a78_1941498_wa +#endif + #if ENABLE_AMU /* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */ mrs x0, actlr_el3 @@ -113,6 +146,7 @@ func cortex_a78_errata_report * checking functions of each errata. */ report_errata ERRATA_A78_1688305, cortex_a78, 1688305 + report_errata ERRATA_A78_1941498, cortex_a78, 1941498 ldp x8, x30, [sp], #16 ret diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk index da0157f4c..b7dec0b77 100644 --- a/lib/cpus/cpu-ops.mk +++ b/lib/cpus/cpu-ops.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved. # Copyright (c) 2020, NVIDIA Corporation. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause @@ -294,6 +294,10 @@ ERRATA_A77_1925769 ?=0 # to revisions r0p0 - r1p0 of the A78 cpu. ERRATA_A78_1688305 ?=0 +# Flag to apply erratum 1941498 workaround during reset. This erratum applies +# to revisions r0p0, r1p0, and r1p1 of the A78 cpu. +ERRATA_A78_1941498 ?=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 @@ -575,6 +579,10 @@ $(eval $(call add_define,ERRATA_A77_1925769)) $(eval $(call assert_boolean,ERRATA_A78_1688305)) $(eval $(call add_define,ERRATA_A78_1688305)) +# Process ERRATA_A78_1941498 flag +$(eval $(call assert_boolean,ERRATA_A78_1941498)) +$(eval $(call add_define,ERRATA_A78_1941498)) + # Process ERRATA_N1_1043202 flag $(eval $(call assert_boolean,ERRATA_N1_1043202)) $(eval $(call add_define,ERRATA_N1_1043202)) -- cgit v1.2.3 From 74c87a4bcd06ba255a424c707d441b1a75e8e61c Mon Sep 17 00:00:00 2001 From: Masahisa Kojima Date: Wed, 23 Sep 2020 16:52:59 +0900 Subject: qemu/qemu_sbsa: enable secure variable storage This implements support for UEFI secure variable storage using standalone MM framework on qemu_sbsa platform. Non-secure shared memory between UEFI and standalone MM is allocated at the top of DRAM. DRAM size of qemu_sbsa varies depends on the QEMU parameter, so the non-secure shared memory is allocated by trusted firmware and passed the base address and size to UEFI through device tree "/reserved-memory" node. Change-Id: I367191f408eb9850b7ec7761ee346b014c539767 Signed-off-by: Masahisa Kojima --- plat/qemu/common/qemu_common.c | 1 + plat/qemu/common/qemu_spm.c | 65 ++++++++++++++++++++++++++++-- plat/qemu/qemu_sbsa/include/platform_def.h | 18 ++++++++- plat/qemu/qemu_sbsa/platform.mk | 2 + 4 files changed, 81 insertions(+), 5 deletions(-) diff --git a/plat/qemu/common/qemu_common.c b/plat/qemu/common/qemu_common.c index 7f8e4c494..7d2730d69 100644 --- a/plat/qemu/common/qemu_common.c +++ b/plat/qemu/common/qemu_common.c @@ -94,6 +94,7 @@ static const mmap_region_t plat_qemu_mmap[] = { MAP_DEVICE1, #endif #if SPM_MM + MAP_NS_DRAM0, QEMU_SPM_BUF_EL3_MMAP, #else MAP_BL32_MEM, diff --git a/plat/qemu/common/qemu_spm.c b/plat/qemu/common/qemu_spm.c index e9ab1a5c3..93dd2b37d 100644 --- a/plat/qemu/common/qemu_spm.c +++ b/plat/qemu/common/qemu_spm.c @@ -3,7 +3,12 @@ * Copyright (c) 2020, Linaro Limited and Contributors. All rights reserved. */ +#include + #include +#include +#include +#include #include #include @@ -14,12 +19,13 @@ DEVICE1_SIZE, \ MT_DEVICE | MT_RW | MT_SECURE | MT_USER) -const mmap_region_t plat_qemu_secure_partition_mmap[] = { - MAP_DEVICE1_EL0, /* for the UART */ +mmap_region_t plat_qemu_secure_partition_mmap[] = { + QEMU_SP_IMAGE_NS_BUF_MMAP, /* must be placed at first entry */ + MAP_DEVICE1_EL0, /* for the UART */ QEMU_SP_IMAGE_MMAP, QEMU_SPM_BUF_EL0_MMAP, - QEMU_SP_IMAGE_NS_BUF_MMAP, QEMU_SP_IMAGE_RW_MMAP, + MAP_SECURE_VARSTORE, {0} }; @@ -38,7 +44,7 @@ static spm_mm_mp_info_t sp_mp_info[] = { [7] = {0x80000007, 0} }; -const spm_mm_boot_info_t plat_qemu_secure_partition_boot_info = { +spm_mm_boot_info_t plat_qemu_secure_partition_boot_info = { .h.type = PARAM_SP_IMAGE_BOOT_INFO, .h.version = VERSION_1, .h.size = sizeof(spm_mm_boot_info_t), @@ -65,12 +71,63 @@ ehf_pri_desc_t qemu_exceptions[] = { EHF_PRI_DESC(QEMU_PRI_BITS, PLAT_SP_PRI) }; +int dt_add_ns_buf_node(uintptr_t *base) +{ + uintptr_t addr; + size_t size; + uintptr_t ns_buf_addr; + int node; + int err; + void *fdt = (void *)ARM_PRELOADED_DTB_BASE; + + err = fdt_open_into(fdt, fdt, PLAT_QEMU_DT_MAX_SIZE); + if (err < 0) { + ERROR("Invalid Device Tree at %p: error %d\n", fdt, err); + return err; + } + + /* + * reserved-memory for standaloneMM non-secure buffer + * is allocated at the top of the first system memory region. + */ + node = fdt_path_offset(fdt, "/memory"); + + err = fdt_get_reg_props_by_index(fdt, node, 0, &addr, &size); + if (err < 0) { + ERROR("Failed to get the memory node information\n"); + return err; + } + INFO("System RAM @ 0x%lx - 0x%lx\n", addr, addr + size - 1); + + ns_buf_addr = addr + (size - PLAT_QEMU_SP_IMAGE_NS_BUF_SIZE); + INFO("reserved-memory for spm-mm @ 0x%lx - 0x%llx\n", ns_buf_addr, + ns_buf_addr + PLAT_QEMU_SP_IMAGE_NS_BUF_SIZE - 1); + + err = fdt_add_reserved_memory(fdt, "ns-buf-spm-mm", ns_buf_addr, + PLAT_QEMU_SP_IMAGE_NS_BUF_SIZE); + if (err < 0) { + ERROR("Failed to add the reserved-memory node\n"); + return err; + } + + *base = ns_buf_addr; + return 0; +} + /* Plug in QEMU exceptions to Exception Handling Framework. */ EHF_REGISTER_PRIORITIES(qemu_exceptions, ARRAY_SIZE(qemu_exceptions), QEMU_PRI_BITS); const mmap_region_t *plat_get_secure_partition_mmap(void *cookie) { + uintptr_t ns_buf_base; + + dt_add_ns_buf_node(&ns_buf_base); + + plat_qemu_secure_partition_mmap[0].base_pa = ns_buf_base; + plat_qemu_secure_partition_mmap[0].base_va = ns_buf_base; + plat_qemu_secure_partition_boot_info.sp_ns_comm_buf_base = ns_buf_base; + return plat_qemu_secure_partition_mmap; } diff --git a/plat/qemu/qemu_sbsa/include/platform_def.h b/plat/qemu/qemu_sbsa/include/platform_def.h index 75851e391..db394c038 100644 --- a/plat/qemu/qemu_sbsa/include/platform_def.h +++ b/plat/qemu/qemu_sbsa/include/platform_def.h @@ -300,10 +300,13 @@ /* * Shared memory between Normal world and S-EL0 for * passing data during service requests. It will be marked as RW and NS. + * This buffer is allocated at the top of NS_DRAM, the base address is + * overridden in SPM initialization. */ #define PLAT_QEMU_SP_IMAGE_NS_BUF_BASE (PLAT_QEMU_DT_BASE + \ PLAT_QEMU_DT_MAX_SIZE) -#define PLAT_QEMU_SP_IMAGE_NS_BUF_SIZE ULL(0x10000) +#define PLAT_QEMU_SP_IMAGE_NS_BUF_SIZE ULL(0x200000) + #define QEMU_SP_IMAGE_NS_BUF_MMAP MAP_REGION2( \ PLAT_QEMU_SP_IMAGE_NS_BUF_BASE, \ PLAT_QEMU_SP_IMAGE_NS_BUF_BASE, \ @@ -334,6 +337,19 @@ MT_USER, \ PAGE_SIZE) +/* + * Secure variable storage is located at Secure Flash. + */ +#if SPM_MM +#define QEMU_SECURE_VARSTORE_BASE 0x01000000 +#define QEMU_SECURE_VARSTORE_SIZE 0x00100000 +#define MAP_SECURE_VARSTORE MAP_REGION_FLAT( \ + QEMU_SECURE_VARSTORE_BASE, \ + QEMU_SECURE_VARSTORE_SIZE, \ + MT_MEMORY | MT_RW | \ + MT_SECURE | MT_USER) +#endif + /* Total number of memory regions with distinct properties */ #define PLAT_QEMU_SP_IMAGE_NUM_MEM_REGIONS 6 diff --git a/plat/qemu/qemu_sbsa/platform.mk b/plat/qemu/qemu_sbsa/platform.mk index acaa43f9e..98d1347d1 100644 --- a/plat/qemu/qemu_sbsa/platform.mk +++ b/plat/qemu/qemu_sbsa/platform.mk @@ -83,6 +83,8 @@ BL31_SOURCES += lib/cpus/aarch64/cortex_a57.S \ ${PLAT_QEMU_COMMON_PATH}/topology.c \ ${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} ifeq (${SPM_MM},1) BL31_SOURCES += ${PLAT_QEMU_COMMON_PATH}/qemu_spm.c -- cgit v1.2.3 From ca7145009db22011036819333146452ad7be891f Mon Sep 17 00:00:00 2001 From: Biju Das Date: Sun, 13 Dec 2020 20:36:30 +0000 Subject: plat: renesas: rcar: Fix coding style Sort the header includes alphabetically and fix checkpatch warnings. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: I08fd0d12ee1d8d61391e8afc33f8c67fcf70c4e5 --- plat/renesas/rcar/bl2_cpg_init.c | 14 +++++++------- plat/renesas/rcar/plat_storage.c | 24 +++++++++--------------- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/plat/renesas/rcar/bl2_cpg_init.c b/plat/renesas/rcar/bl2_cpg_init.c index c3ca9ea16..175434469 100644 --- a/plat/renesas/rcar/bl2_cpg_init.c +++ b/plat/renesas/rcar/bl2_cpg_init.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,8 +7,8 @@ #include #include -#include "rcar_def.h" #include "cpg_registers.h" +#include "rcar_def.h" #include "rcar_private.h" static void bl2_secure_cpg_init(void); @@ -77,7 +77,7 @@ static void bl2_secure_cpg_init(void) stop_cr5 = 0xBFFFFFFFU; #endif - /** Secure Module Stop Control Registers */ + /* Secure Module Stop Control Registers */ cpg_write(SCMSTPCR0, 0xFFFFFFFFU); cpg_write(SCMSTPCR1, 0xFFFFFFFFU); cpg_write(SCMSTPCR2, stop_cr2); @@ -91,7 +91,7 @@ static void bl2_secure_cpg_init(void) cpg_write(SCMSTPCR10, 0xFFFFFFFFU); cpg_write(SCMSTPCR11, 0xFFFFFFFFU); - /** Secure Software Reset Access Enable Control Registers */ + /* Secure Software Reset Access Enable Control Registers */ cpg_write(SCSRSTECR0, 0x00000000U); cpg_write(SCSRSTECR1, 0x00000000U); cpg_write(SCSRSTECR2, reset_cr2); @@ -152,7 +152,7 @@ static void bl2_system_cpg_init_h3(void) #if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_M3) static void bl2_realtime_cpg_init_m3(void) { - /** Realtime Module Stop Control Registers */ + /* Realtime Module Stop Control Registers */ cpg_write(RMSTPCR0, 0x00200000U); cpg_write(RMSTPCR1, 0xFFFFFFFFU); cpg_write(RMSTPCR2, 0x040E0FDCU); @@ -169,7 +169,7 @@ static void bl2_realtime_cpg_init_m3(void) static void bl2_system_cpg_init_m3(void) { - /** System Module Stop Control Registers */ + /* System Module Stop Control Registers */ cpg_write(SMSTPCR0, 0x00200000U); cpg_write(SMSTPCR1, 0xFFFFFFFFU); cpg_write(SMSTPCR2, 0x040E2FDCU); @@ -188,7 +188,7 @@ static void bl2_system_cpg_init_m3(void) #if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_M3N) static void bl2_realtime_cpg_init_m3n(void) { - /** Realtime Module Stop Control Registers */ + /* Realtime Module Stop Control Registers */ cpg_write(RMSTPCR0, 0x00210000U); cpg_write(RMSTPCR1, 0xFFFFFFFFU); cpg_write(RMSTPCR2, 0x040E0FDCU); diff --git a/plat/renesas/rcar/plat_storage.c b/plat/renesas/rcar/plat_storage.c index 05e3d9f0d..652456103 100644 --- a/plat/renesas/rcar/plat_storage.c +++ b/plat/renesas/rcar/plat_storage.c @@ -1,23 +1,22 @@ /* - * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include -#include - #include #include #include #include #include "io_common.h" -#include "io_rcar.h" #include "io_memdrv.h" #include "io_emmcdrv.h" #include "io_private.h" +#include "io_rcar.h" +#include static uintptr_t emmcdrv_dev_handle; static uintptr_t memdrv_dev_handle; @@ -167,7 +166,7 @@ static int32_t open_rcar(const uintptr_t spec); struct plat_io_policy { uintptr_t *dev_handle; uintptr_t image_spec; - int32_t(*check) (const uintptr_t spec); + int32_t (*check)(const uintptr_t spec); }; static const struct plat_io_policy policies[] = { @@ -305,7 +304,7 @@ static const struct plat_io_policy policies[] = { (uintptr_t) &bl338_cert_file_spec, &open_rcar}, { #else - { + { #endif 0, 0, 0} }; @@ -322,16 +321,11 @@ static io_drv_spec_t io_drv_spec_emmcdrv = { 0, }; -static struct plat_io_policy drv_policies[] - __attribute__ ((section(".data"))) = { +static struct plat_io_policy drv_policies[] __attribute__ ((section(".data"))) = { /* FLASH_DEV_ID */ - { - &memdrv_dev_handle, - (uintptr_t) &io_drv_spec_memdrv, &open_memmap,}, - /* EMMC_DEV_ID */ - { - &emmcdrv_dev_handle, - (uintptr_t) &io_drv_spec_emmcdrv, &open_emmcdrv,} + { &memdrv_dev_handle, (uintptr_t) &io_drv_spec_memdrv, &open_memmap, }, + /* EMMC_DEV_ID */ + { &emmcdrv_dev_handle, (uintptr_t) &io_drv_spec_emmcdrv, &open_emmcdrv, } }; static int32_t open_rcar(const uintptr_t spec) -- cgit v1.2.3 From b28c29d0084e1380333881d718ebeb0ef65b10a5 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Wed, 16 Dec 2020 09:53:19 +0000 Subject: drivers: renesas: eMMC: Move to common Move eMMC driver code to common directory, so that the same code can be re-used by both R-Car Gen3 and RZ/G2 platforms. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: I7f3055709337327d1a1c9f563c14ad1626adb355 --- drivers/renesas/common/emmc/emmc_cmd.c | 493 +++++++++++++++++++ drivers/renesas/common/emmc/emmc_config.h | 20 + drivers/renesas/common/emmc/emmc_def.h | 78 +++ drivers/renesas/common/emmc/emmc_hal.h | 535 +++++++++++++++++++++ drivers/renesas/common/emmc/emmc_init.c | 162 +++++++ drivers/renesas/common/emmc/emmc_interrupt.c | 217 +++++++++ drivers/renesas/common/emmc/emmc_mount.c | 686 +++++++++++++++++++++++++++ drivers/renesas/common/emmc/emmc_read.c | 130 +++++ drivers/renesas/common/emmc/emmc_registers.h | 228 +++++++++ drivers/renesas/common/emmc/emmc_std.h | 475 +++++++++++++++++++ drivers/renesas/common/emmc/emmc_utility.c | 226 +++++++++ drivers/renesas/rcar/emmc/emmc_cmd.c | 493 ------------------- drivers/renesas/rcar/emmc/emmc_config.h | 20 - drivers/renesas/rcar/emmc/emmc_def.h | 78 --- drivers/renesas/rcar/emmc/emmc_hal.h | 535 --------------------- drivers/renesas/rcar/emmc/emmc_init.c | 162 ------- drivers/renesas/rcar/emmc/emmc_interrupt.c | 217 --------- drivers/renesas/rcar/emmc/emmc_mount.c | 686 --------------------------- drivers/renesas/rcar/emmc/emmc_read.c | 130 ----- drivers/renesas/rcar/emmc/emmc_registers.h | 228 --------- drivers/renesas/rcar/emmc/emmc_std.h | 475 ------------------- drivers/renesas/rcar/emmc/emmc_utility.c | 226 --------- plat/renesas/common/common.mk | 6 + plat/renesas/rcar/platform.mk | 8 +- 24 files changed, 3257 insertions(+), 3257 deletions(-) create mode 100644 drivers/renesas/common/emmc/emmc_cmd.c create mode 100644 drivers/renesas/common/emmc/emmc_config.h create mode 100644 drivers/renesas/common/emmc/emmc_def.h create mode 100644 drivers/renesas/common/emmc/emmc_hal.h create mode 100644 drivers/renesas/common/emmc/emmc_init.c create mode 100644 drivers/renesas/common/emmc/emmc_interrupt.c create mode 100644 drivers/renesas/common/emmc/emmc_mount.c create mode 100644 drivers/renesas/common/emmc/emmc_read.c create mode 100644 drivers/renesas/common/emmc/emmc_registers.h create mode 100644 drivers/renesas/common/emmc/emmc_std.h create mode 100644 drivers/renesas/common/emmc/emmc_utility.c delete mode 100644 drivers/renesas/rcar/emmc/emmc_cmd.c delete mode 100644 drivers/renesas/rcar/emmc/emmc_config.h delete mode 100644 drivers/renesas/rcar/emmc/emmc_def.h delete mode 100644 drivers/renesas/rcar/emmc/emmc_hal.h delete mode 100644 drivers/renesas/rcar/emmc/emmc_init.c delete mode 100644 drivers/renesas/rcar/emmc/emmc_interrupt.c delete mode 100644 drivers/renesas/rcar/emmc/emmc_mount.c delete mode 100644 drivers/renesas/rcar/emmc/emmc_read.c delete mode 100644 drivers/renesas/rcar/emmc/emmc_registers.h delete mode 100644 drivers/renesas/rcar/emmc/emmc_std.h delete mode 100644 drivers/renesas/rcar/emmc/emmc_utility.c diff --git a/drivers/renesas/common/emmc/emmc_cmd.c b/drivers/renesas/common/emmc/emmc_cmd.c new file mode 100644 index 000000000..d255bffc9 --- /dev/null +++ b/drivers/renesas/common/emmc/emmc_cmd.c @@ -0,0 +1,493 @@ +/* + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include "emmc_config.h" +#include "emmc_def.h" +#include "emmc_hal.h" +#include "emmc_registers.h" +#include "emmc_std.h" +#include "micro_delay.h" + +static void emmc_little_to_big(uint8_t *p, uint32_t value) +{ + if (p == NULL) + return; + + p[0] = (uint8_t) (value >> 24); + p[1] = (uint8_t) (value >> 16); + p[2] = (uint8_t) (value >> 8); + p[3] = (uint8_t) value; + +} + +static void emmc_softreset(void) +{ + int32_t loop = 10000; + int32_t retry = 1000; + + /* flag clear */ + mmc_drv_obj.during_cmd_processing = FALSE; + mmc_drv_obj.during_transfer = FALSE; + mmc_drv_obj.during_dma_transfer = FALSE; + mmc_drv_obj.state_machine_blocking = FALSE; + mmc_drv_obj.force_terminate = FALSE; + mmc_drv_obj.dma_error_flag = FALSE; + + /* during operation ? */ + if ((GETR_32(SD_INFO2) & SD_INFO2_CBSY) == 0) + goto reset; + + /* wait CMDSEQ = 0 */ + while (loop > 0) { + if ((GETR_32(SD_INFO2) & SD_INFO2_CBSY) == 0) + break; /* ready */ + + loop--; + if ((loop == 0) && (retry > 0)) { + rcar_micro_delay(1000U); /* wait 1ms */ + loop = 10000; + retry--; + } + } + +reset: + /* reset */ + SETR_32(SOFT_RST, (GETR_32(SOFT_RST) & (~SOFT_RST_SDRST))); + SETR_32(SOFT_RST, (GETR_32(SOFT_RST) | SOFT_RST_SDRST)); + + /* initialize */ + SETR_32(SD_INFO1, 0x00000000U); + SETR_32(SD_INFO2, SD_INFO2_CLEAR); + SETR_32(SD_INFO1_MASK, 0x00000000U); /* all interrupt disable */ + SETR_32(SD_INFO2_MASK, SD_INFO2_CLEAR); /* all interrupt disable */ +} + +static void emmc_read_response(uint32_t *response) +{ + uint8_t *p; + + if (response == NULL) + return; + + /* read response */ + if (mmc_drv_obj.response_length != EMMC_MAX_RESPONSE_LENGTH) { + *response = GETR_32(SD_RSP10); /* [39:8] */ + return; + } + + /* CSD or CID */ + p = (uint8_t *) (response); + emmc_little_to_big(p, ((GETR_32(SD_RSP76) << 8) + | (GETR_32(SD_RSP54) >> 24))); /* [127:96] */ + emmc_little_to_big(p + 4, ((GETR_32(SD_RSP54) << 8) + | (GETR_32(SD_RSP32) >> 24))); /* [95:64] */ + emmc_little_to_big(p + 8, ((GETR_32(SD_RSP32) << 8) + | (GETR_32(SD_RSP10) >> 24))); /* [63:32] */ + emmc_little_to_big(p + 12, (GETR_32(SD_RSP10) << 8)); +} + +static EMMC_ERROR_CODE emmc_response_check(uint32_t *response, + uint32_t error_mask) +{ + + HAL_MEMCARD_RESPONSE_TYPE response_type = + ((HAL_MEMCARD_RESPONSE_TYPE)mmc_drv_obj.cmd_info.cmd & HAL_MEMCARD_RESPONSE_TYPE_MASK); + + if (response == NULL) + return EMMC_ERR_PARAM; + + if (response_type == HAL_MEMCARD_RESPONSE_NONE) + return EMMC_SUCCESS; + + + if (response_type <= HAL_MEMCARD_RESPONSE_R1b) { + /* R1 or R1b */ + mmc_drv_obj.current_state = + (EMMC_R1_STATE) ((*response & EMMC_R1_STATE_MASK) >> + EMMC_R1_STATE_SHIFT); + if ((*response & error_mask) != 0) { + if ((0x80 & *response) != 0) { + ERROR("BL2: emmc SWITCH_ERROR\n"); + } + return EMMC_ERR_CARD_STATUS_BIT; + } + return EMMC_SUCCESS; + } + + if (response_type == HAL_MEMCARD_RESPONSE_R4) { + if ((*response & EMMC_R4_STATUS) != 0) + return EMMC_ERR_CARD_STATUS_BIT; + } + + return EMMC_SUCCESS; +} + +static void emmc_WaitCmd2Cmd_8Cycle(void) +{ + uint32_t dataL, wait = 0; + + dataL = GETR_32(SD_CLK_CTRL); + dataL &= 0x000000FF; + + switch (dataL) { + case 0xFF: + case 0x00: + case 0x01: + case 0x02: + case 0x04: + case 0x08: + case 0x10: + case 0x20: + wait = 10U; + break; + case 0x40: + wait = 20U; + break; + case 0x80: + wait = 30U; + break; + } + + rcar_micro_delay(wait); +} + +static void cmdErrSdInfo2Log(void) +{ + ERROR("BL2: emmc ERR SD_INFO2 = 0x%x\n", mmc_drv_obj.error_info.info2); +} + +static void emmc_data_transfer_dma(void) +{ + mmc_drv_obj.during_dma_transfer = TRUE; + mmc_drv_obj.dma_error_flag = FALSE; + + SETR_32(SD_INFO1_MASK, 0x00000000U); + SETR_32(SD_INFO2_MASK, (SD_INFO2_ALL_ERR | SD_INFO2_CLEAR)); + + /* DMAC setting */ + if (mmc_drv_obj.cmd_info.dir == HAL_MEMCARD_WRITE) { + /* transfer complete interrupt enable */ + SETR_32(DM_CM_INFO1_MASK, + (DM_CM_INFO_MASK_CLEAR | DM_CM_INFO_CH0_ENABLE)); + SETR_32(DM_CM_INFO2_MASK, + (DM_CM_INFO_MASK_CLEAR | DM_CM_INFO_CH0_ENABLE)); + /* BUFF --> FIFO */ + SETR_32(DM_CM_DTRAN_MODE, (DM_CM_DTRAN_MODE_CH0 | + DM_CM_DTRAN_MODE_BIT_WIDTH)); + } else { + /* transfer complete interrupt enable */ + SETR_32(DM_CM_INFO1_MASK, + (DM_CM_INFO_MASK_CLEAR | DM_CM_INFO_CH1_ENABLE)); + SETR_32(DM_CM_INFO2_MASK, + (DM_CM_INFO_MASK_CLEAR | DM_CM_INFO_CH1_ENABLE)); + /* FIFO --> BUFF */ + SETR_32(DM_CM_DTRAN_MODE, (DM_CM_DTRAN_MODE_CH1 + | DM_CM_DTRAN_MODE_BIT_WIDTH)); + } + SETR_32(DM_DTRAN_ADDR, (((uintptr_t) mmc_drv_obj.buff_address_virtual & + DM_DTRAN_ADDR_WRITE_MASK))); + + SETR_32(DM_CM_DTRAN_CTRL, DM_CM_DTRAN_CTRL_START); +} + +EMMC_ERROR_CODE emmc_exec_cmd(uint32_t error_mask, uint32_t *response) +{ + EMMC_ERROR_CODE rtn_code = EMMC_SUCCESS; + HAL_MEMCARD_RESPONSE_TYPE response_type; + HAL_MEMCARD_COMMAND_TYPE cmd_type; + EMMC_INT_STATE state; + uint32_t err_not_care_flag = FALSE; + + /* parameter check */ + if (response == NULL) { + emmc_write_error_info(EMMC_FUNCNO_EXEC_CMD, EMMC_ERR_PARAM); + return EMMC_ERR_PARAM; + } + + /* state check */ + if (mmc_drv_obj.clock_enable != TRUE) { + emmc_write_error_info(EMMC_FUNCNO_EXEC_CMD, EMMC_ERR_STATE); + return EMMC_ERR_STATE; + } + + if (mmc_drv_obj.state_machine_blocking == TRUE) { + emmc_write_error_info(EMMC_FUNCNO_EXEC_CMD, EMMC_ERR); + return EMMC_ERR; + } + + state = ESTATE_BEGIN; + response_type = + ((HAL_MEMCARD_RESPONSE_TYPE)mmc_drv_obj.cmd_info.cmd & + HAL_MEMCARD_RESPONSE_TYPE_MASK); + cmd_type = + ((HAL_MEMCARD_COMMAND_TYPE) mmc_drv_obj.cmd_info.cmd & + HAL_MEMCARD_COMMAND_TYPE_MASK); + + /* state machine */ + while ((mmc_drv_obj.force_terminate != TRUE) && (state != ESTATE_END)) { + /* The interrupt factor flag is observed. */ + emmc_interrupt(); + + /* wait interrupt */ + if (mmc_drv_obj.state_machine_blocking == TRUE) + continue; + + switch (state) { + case ESTATE_BEGIN: + /* Busy check */ + if ((mmc_drv_obj.error_info.info2 & SD_INFO2_CBSY) != 0) { + emmc_write_error_info(EMMC_FUNCNO_EXEC_CMD, + EMMC_ERR_CARD_BUSY); + return EMMC_ERR_CARD_BUSY; + } + + /* clear register */ + SETR_32(SD_INFO1, 0x00000000U); + SETR_32(SD_INFO2, SD_INFO2_CLEAR); + SETR_32(SD_INFO1_MASK, SD_INFO1_INFO0); + SETR_32(SD_INFO2_MASK, + (SD_INFO2_ALL_ERR | SD_INFO2_CLEAR)); + + state = ESTATE_ISSUE_CMD; + /* through */ + + case ESTATE_ISSUE_CMD: + /* ARG */ + SETR_32(SD_ARG, mmc_drv_obj.cmd_info.arg); + /* issue cmd */ + SETR_32(SD_CMD, mmc_drv_obj.cmd_info.hw); + /* Set driver flag */ + mmc_drv_obj.during_cmd_processing = TRUE; + mmc_drv_obj.state_machine_blocking = TRUE; + + if (response_type == HAL_MEMCARD_RESPONSE_NONE) { + state = ESTATE_NON_RESP_CMD; + } else { + state = ESTATE_RCV_RESP; + } + + break; + + case ESTATE_NON_RESP_CMD: + /* interrupt disable */ + SETR_32(SD_INFO1_MASK, 0x00000000U); + SETR_32(SD_INFO2_MASK, SD_INFO2_CLEAR); + + /* check interrupt */ + if ((mmc_drv_obj.int_event2 & SD_INFO2_ALL_ERR) != 0) { + /* error interrupt */ + cmdErrSdInfo2Log(); + rtn_code = EMMC_ERR_INFO2; + state = ESTATE_ERROR; + } else if ((mmc_drv_obj.int_event1 & SD_INFO1_INFO0) == + 0) { + /* not receive expected interrupt */ + rtn_code = EMMC_ERR_RESPONSE; + state = ESTATE_ERROR; + } else { + emmc_WaitCmd2Cmd_8Cycle(); + state = ESTATE_END; + } + break; + + case ESTATE_RCV_RESP: + /* interrupt disable */ + SETR_32(SD_INFO1_MASK, 0x00000000U); + SETR_32(SD_INFO2_MASK, SD_INFO2_CLEAR); + + /* check interrupt */ + if ((mmc_drv_obj.int_event2 & SD_INFO2_ALL_ERR) != 0) { + if ((mmc_drv_obj.get_partition_access_flag == + TRUE) + && ((mmc_drv_obj.int_event2 & SD_INFO2_ERR6) + != 0U)) { + err_not_care_flag = TRUE; + rtn_code = EMMC_ERR_CMD_TIMEOUT; + } else { + /* error interrupt */ + cmdErrSdInfo2Log(); + rtn_code = EMMC_ERR_INFO2; + } + state = ESTATE_ERROR; + break; + } else if ((mmc_drv_obj.int_event1 & SD_INFO1_INFO0) == + 0) { + /* not receive expected interrupt */ + rtn_code = EMMC_ERR_RESPONSE; + state = ESTATE_ERROR; + break; + } + + /* read response */ + emmc_read_response(response); + + /* check response */ + rtn_code = emmc_response_check(response, error_mask); + if (rtn_code != EMMC_SUCCESS) { + state = ESTATE_ERROR; + break; + } + + if (response_type == HAL_MEMCARD_RESPONSE_R1b) { + /* R1b */ + SETR_32(SD_INFO2_MASK, + (SD_INFO2_ALL_ERR | SD_INFO2_CLEAR)); + state = ESTATE_RCV_RESPONSE_BUSY; + } else { + state = ESTATE_CHECK_RESPONSE_COMPLETE; + } + break; + + case ESTATE_RCV_RESPONSE_BUSY: + /* check interrupt */ + if ((mmc_drv_obj.int_event2 & SD_INFO2_ALL_ERR) != 0) { + /* error interrupt */ + cmdErrSdInfo2Log(); + rtn_code = EMMC_ERR_INFO2; + state = ESTATE_ERROR; + break; + } + /* DAT0 not Busy */ + if ((SD_INFO2_DAT0 & mmc_drv_obj.error_info.info2) != 0) { + state = ESTATE_CHECK_RESPONSE_COMPLETE; + break; + } + break; + + case ESTATE_CHECK_RESPONSE_COMPLETE: + if (cmd_type >= HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE) { + state = ESTATE_DATA_TRANSFER; + } else { + emmc_WaitCmd2Cmd_8Cycle(); + state = ESTATE_END; + } + break; + + case ESTATE_DATA_TRANSFER: + /* ADTC command */ + mmc_drv_obj.during_transfer = TRUE; + mmc_drv_obj.state_machine_blocking = TRUE; + + if (mmc_drv_obj.transfer_mode == HAL_MEMCARD_DMA) { + /* DMA */ + emmc_data_transfer_dma(); + } else { + /* PIO */ + /* interrupt enable (FIFO read/write enable) */ + if (mmc_drv_obj.cmd_info.dir == + HAL_MEMCARD_WRITE) { + SETR_32(SD_INFO2_MASK, + (SD_INFO2_BWE | SD_INFO2_ALL_ERR + | SD_INFO2_CLEAR)); + } else { + SETR_32(SD_INFO2_MASK, + (SD_INFO2_BRE | SD_INFO2_ALL_ERR + | SD_INFO2_CLEAR)); + } + } + state = ESTATE_DATA_TRANSFER_COMPLETE; + break; + + case ESTATE_DATA_TRANSFER_COMPLETE: + /* check interrupt */ + if ((mmc_drv_obj.int_event2 & SD_INFO2_ALL_ERR) != 0) { + /* error interrupt */ + cmdErrSdInfo2Log(); + rtn_code = EMMC_ERR_INFO2; + state = ESTATE_TRANSFER_ERROR; + break; + } + + /* DMAC error ? */ + if (mmc_drv_obj.dma_error_flag == TRUE) { + /* Error occurred in DMAC driver. */ + rtn_code = EMMC_ERR_FROM_DMAC_TRANSFER; + state = ESTATE_TRANSFER_ERROR; + } else if (mmc_drv_obj.during_dma_transfer == TRUE) { + /* DMAC not finished. unknown error */ + rtn_code = EMMC_ERR; + state = ESTATE_TRANSFER_ERROR; + } else { + SETR_32(SD_INFO1_MASK, SD_INFO1_INFO2); + SETR_32(SD_INFO2_MASK, + (SD_INFO2_ALL_ERR | SD_INFO2_CLEAR)); + + mmc_drv_obj.state_machine_blocking = TRUE; + + state = ESTATE_ACCESS_END; + } + break; + + case ESTATE_ACCESS_END: + + /* clear flag */ + if (mmc_drv_obj.transfer_mode == HAL_MEMCARD_DMA) { + /* W (CC_EXT_MODE, H'0000_1010) SD_BUF DMA transfer disabled */ + SETR_32(CC_EXT_MODE, CC_EXT_MODE_CLEAR); + SETR_32(SD_STOP, 0x00000000U); + mmc_drv_obj.during_dma_transfer = FALSE; + } + + SETR_32(SD_INFO1_MASK, 0x00000000U); + SETR_32(SD_INFO2_MASK, SD_INFO2_CLEAR); + SETR_32(SD_INFO1, 0x00000000U); + SETR_32(SD_INFO2, SD_INFO2_CLEAR); + + if ((mmc_drv_obj.int_event1 & SD_INFO1_INFO2) != 0) { + emmc_WaitCmd2Cmd_8Cycle(); + state = ESTATE_END; + } else { + state = ESTATE_ERROR; + } + break; + + case ESTATE_TRANSFER_ERROR: + /* The error occurred in the Data transfer. */ + if (mmc_drv_obj.transfer_mode == HAL_MEMCARD_DMA) { + /* W (CC_EXT_MODE, H'0000_1010) SD_BUF DMA transfer disabled */ + SETR_32(CC_EXT_MODE, CC_EXT_MODE_CLEAR); + SETR_32(SD_STOP, 0x00000000U); + mmc_drv_obj.during_dma_transfer = FALSE; + } + /* through */ + + case ESTATE_ERROR: + if (err_not_care_flag == TRUE) { + mmc_drv_obj.during_cmd_processing = FALSE; + } else { + emmc_softreset(); + emmc_write_error_info(EMMC_FUNCNO_EXEC_CMD, + rtn_code); + } + return rtn_code; + + default: + state = ESTATE_END; + break; + } /* switch (state) */ + } /* while ( (mmc_drv_obj.force_terminate != TRUE) && (state != ESTATE_END) ) */ + + /* force terminate */ + if (mmc_drv_obj.force_terminate == TRUE) { + /* timeout timer is expired. Or, PIO data transfer error. */ + /* Timeout occurred in the DMA transfer. */ + if (mmc_drv_obj.during_dma_transfer == TRUE) { + mmc_drv_obj.during_dma_transfer = FALSE; + } + ERROR("BL2: emmc exec_cmd:EMMC_ERR_FORCE_TERMINATE\n"); + emmc_softreset(); + + return EMMC_ERR_FORCE_TERMINATE; /* error information has already been written. */ + } + + /* success */ + mmc_drv_obj.during_cmd_processing = FALSE; + mmc_drv_obj.during_transfer = FALSE; + + return EMMC_SUCCESS; +} diff --git a/drivers/renesas/common/emmc/emmc_config.h b/drivers/renesas/common/emmc/emmc_config.h new file mode 100644 index 000000000..16b6b8aa9 --- /dev/null +++ b/drivers/renesas/common/emmc/emmc_config.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef EMMC_CONFIG_H +#define EMMC_CONFIG_H + +/* RCA */ +#define EMMC_RCA 1UL +/* 314ms (freq = 400KHz, timeout Counter = 0x04(SDCLK * 2^17) */ +#define EMMC_RW_DATA_TIMEOUT 0x40UL +/* how many times to try after fail. Don't change. */ +#define EMMC_RETRY_COUNT 0 +#define EMMC_CMD_MAX 60UL /* Don't change. */ + +#define LOADIMAGE_FLAGS_DMA_ENABLE 0x00000001UL + +#endif /* EMMC_CONFIG_H */ diff --git a/drivers/renesas/common/emmc/emmc_def.h b/drivers/renesas/common/emmc/emmc_def.h new file mode 100644 index 000000000..178c795b9 --- /dev/null +++ b/drivers/renesas/common/emmc/emmc_def.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file emmc_def.h + * @brief eMMC boot is expecting this header file + * + */ + +#ifndef EMMC_DEF_H +#define EMMC_DEF_H + +#include "emmc_std.h" + +/* ************************ HEADER (INCLUDE) SECTION *********************** */ + +/* ***************** MACROS, CONSTANTS, COMPILATION FLAGS ****************** */ +#define EMMC_POWER_ON (1U) + +/* ********************** STRUCTURES, TYPE DEFINITIONS ********************* */ + +/* ********************** DECLARATION OF EXTERNAL DATA ********************* */ +extern st_mmc_base mmc_drv_obj; + +/* ************************** FUNCTION PROTOTYPES ************************** */ + +/** @brief for assembler program + */ +uint32_t _rom_emmc_finalize(void); + +/** @brief eMMC driver API + */ +EMMC_ERROR_CODE rcar_emmc_init(void); +EMMC_ERROR_CODE emmc_terminate(void); +EMMC_ERROR_CODE rcar_emmc_memcard_power(uint8_t mode); +EMMC_ERROR_CODE rcar_emmc_mount(void); +EMMC_ERROR_CODE emmc_set_request_mmc_clock(uint32_t *freq); +EMMC_ERROR_CODE emmc_send_idle_cmd(uint32_t arg); +EMMC_ERROR_CODE emmc_select_partition(EMMC_PARTITION_ID id); +EMMC_ERROR_CODE emmc_read_sector(uint32_t *buff_address_virtual, + uint32_t sector_number, uint32_t count, + uint32_t feature_flags); +EMMC_ERROR_CODE emmc_write_sector(uint32_t *buff_address_virtual, + uint32_t sector_number, uint32_t count, + uint32_t feature_flags); +EMMC_ERROR_CODE emmc_erase_sector(uint32_t *start_address, + uint32_t *end_address); +uint32_t emmc_bit_field(uint8_t *data, uint32_t top, uint32_t bottom); + +/** @brief interrupt service + */ +uint32_t emmc_interrupt(void); + +/** @brief DMA + */ + +/** @brief send command API + */ +EMMC_ERROR_CODE emmc_exec_cmd(uint32_t error_mask, uint32_t *response); +void emmc_make_nontrans_cmd(HAL_MEMCARD_COMMAND cmd, uint32_t arg); +void emmc_make_trans_cmd(HAL_MEMCARD_COMMAND cmd, uint32_t arg, + uint32_t *buff_address_virtual, uint32_t len, + HAL_MEMCARD_OPERATION dir, + HAL_MEMCARD_DATA_TRANSFER_MODE transfer_mode); +EMMC_ERROR_CODE emmc_set_ext_csd(uint32_t arg); + +/** @brief for error information + */ +void emmc_write_error_info(uint16_t func_no, EMMC_ERROR_CODE error_code); +void emmc_write_error_info_func_no(uint16_t func_no); + +/* ********************************* CODE ********************************** */ + +#endif /* EMMC_DEF_H */ +/* ******************************** END ************************************ */ diff --git a/drivers/renesas/common/emmc/emmc_hal.h b/drivers/renesas/common/emmc/emmc_hal.h new file mode 100644 index 000000000..0a8551719 --- /dev/null +++ b/drivers/renesas/common/emmc/emmc_hal.h @@ -0,0 +1,535 @@ +/* + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef EMMC_HAL_H +#define EMMC_HAL_H + +/* memory card error/status types */ +#define HAL_MEMCARD_OUT_OF_RANGE 0x80000000L +#define HAL_MEMCARD_ADDRESS_ERROR 0x40000000L +#define HAL_MEMCARD_BLOCK_LEN_ERROR 0x20000000L +#define HAL_MEMCARD_ERASE_SEQ_ERROR 0x10000000L +#define HAL_MEMCARD_ERASE_PARAM 0x08000000L +#define HAL_MEMCARD_WP_VIOLATION 0x04000000L +#define HAL_MEMCARD_CARD_IS_LOCKED 0x02000000L +#define HAL_MEMCARD_LOCK_UNLOCK_FAILED 0x01000000L +#define HAL_MEMCARD_COM_CRC_ERROR 0x00800000L +#define HAL_MEMCARD_ILEGAL_COMMAND 0x00400000L +#define HAL_MEMCARD_CARD_ECC_FAILED 0x00200000L +#define HAL_MEMCARD_CC_ERROR 0x00100000L +#define HAL_MEMCARD_ERROR 0x00080000L +#define HAL_MEMCARD_UNDERRUN 0x00040000L +#define HAL_MEMCARD_OVERRUN 0x00020000L +#define HAL_MEMCARD_CIDCSD_OVERWRITE 0x00010000L +#define HAL_MEMCARD_WP_ERASE_SKIP 0x00008000L +#define HAL_MEMCARD_CARD_ECC_DISABLED 0x00004000L +#define HAL_MEMCARD_ERASE_RESET 0x00002000L +#define HAL_MEMCARD_CARD_STATE 0x00001E00L +#define HAL_MEMCARD_CARD_READY_FOR_DATA 0x00000100L +#define HAL_MEMCARD_APP_CMD 0x00000020L +#define HAL_MEMCARD_SWITCH_ERROR 0x00000080L +#define HAL_MEMCARD_AKE_SEQ_ERROR 0x00000008L +#define HAL_MEMCARD_NO_ERRORS 0x00000000L + +/* Memory card response types */ +#define HAL_MEMCARD_COMMAND_INDEX_MASK 0x0003f + +/* Type of the return value. */ +typedef enum { + HAL_MEMCARD_FAIL = 0U, + HAL_MEMCARD_OK = 1U, + HAL_MEMCARD_DMA_ALLOC_FAIL = 2U, /* DMA channel allocation failed */ + HAL_MEMCARD_DMA_TRANSFER_FAIL = 3U, /* DMA transfer failed */ + HAL_MEMCARD_CARD_STATUS_ERROR = 4U, /* card status non-masked error */ + HAL_MEMCARD_CMD_TIMEOUT = 5U, /* Command timeout occurred */ + HAL_MEMCARD_DATA_TIMEOUT = 6U, /* Data timeout occurred */ + HAL_MEMCARD_CMD_CRC_ERROR = 7U, /* Command CRC error occurred */ + HAL_MEMCARD_DATA_CRC_ERROR = 8U /* Data CRC error occurred */ +} HAL_MEMCARD_RETURN; + +/* memory access operation */ +typedef enum { + HAL_MEMCARD_READ = 0U, /* read */ + HAL_MEMCARD_WRITE = 1U /* write */ +} HAL_MEMCARD_OPERATION; + +/* Type of data width on memorycard bus */ +typedef enum { + HAL_MEMCARD_DATA_WIDTH_1_BIT = 0U, + HAL_MEMCARD_DATA_WIDTH_4_BIT = 1U, + HAL_MEMCARD_DATA_WIDTH_8_BIT = 2U +} HAL_MEMCARD_DATA_WIDTH; /* data (bus) width types */ + +/* Presence of the memory card */ +typedef enum { + HAL_MEMCARD_CARD_IS_IN = 0U, + HAL_MEMCARD_CARD_IS_OUT = 1U +} HAL_MEMCARD_PRESENCE_STATUS; /* presence status of the memory card */ + +/* mode of data transfer */ +typedef enum { + HAL_MEMCARD_DMA = 0U, + HAL_MEMCARD_NOT_DMA = 1U +} HAL_MEMCARD_DATA_TRANSFER_MODE; + +/* Memory card response types. */ +typedef enum hal_memcard_response_type { + HAL_MEMCARD_RESPONSE_NONE = 0x00000U, + HAL_MEMCARD_RESPONSE_R1 = 0x00100U, + HAL_MEMCARD_RESPONSE_R1b = 0x00200U, + HAL_MEMCARD_RESPONSE_R2 = 0x00300U, + HAL_MEMCARD_RESPONSE_R3 = 0x00400U, + HAL_MEMCARD_RESPONSE_R4 = 0x00500U, + HAL_MEMCARD_RESPONSE_R5 = 0x00600U, + HAL_MEMCARD_RESPONSE_R6 = 0x00700U, + HAL_MEMCARD_RESPONSE_R7 = 0x00800U, + HAL_MEMCARD_RESPONSE_TYPE_MASK = 0x00f00U +} HAL_MEMCARD_RESPONSE_TYPE; + +/* Memory card command types. */ +typedef enum hal_memcard_command_type { + HAL_MEMCARD_COMMAND_TYPE_BC = 0x00000U, + HAL_MEMCARD_COMMAND_TYPE_BCR = 0x01000U, + HAL_MEMCARD_COMMAND_TYPE_AC = 0x02000U, + HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE = 0x03000U, + HAL_MEMCARD_COMMAND_TYPE_ADTC_READ = 0x04000U, + HAL_MEMCARD_COMMAND_TYPE_MASK = 0x07000U +} HAL_MEMCARD_COMMAND_TYPE; + +/* Type of memory card */ +typedef enum hal_memcard_command_card_type { + HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON = 0x00000U, + HAL_MEMCARD_COMMAND_CARD_TYPE_MMC = 0x08000U, + HAL_MEMCARD_COMMAND_CARD_TYPE_SD = 0x10000U, + HAL_MEMCARD_COMMAND_CARD_TYPE_MASK = 0x18000U +} HAL_MEMCARD_COMMAND_CARD_TYPE; + +/* Memory card application command. */ +typedef enum hal_memcard_command_app_norm { + HAL_MEMCARD_COMMAND_NORMAL = 0x00000U, + HAL_MEMCARD_COMMAND_APP = 0x20000U, + HAL_MEMCARD_COMMAND_APP_NORM_MASK = 0x20000U +} HAL_MEMCARD_COMMAND_APP_NORM; + +/* Memory card command codes. */ +typedef enum { +/* class 0 and class 1 */ + /* CMD0 */ + CMD0_GO_IDLE_STATE = + 0U | (uint32_t)HAL_MEMCARD_RESPONSE_NONE | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_BC | + (uint32_t) HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD1 */ + CMD1_SEND_OP_COND = + 1U | (uint32_t)HAL_MEMCARD_RESPONSE_R3 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_BCR | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD2 */ + CMD2_ALL_SEND_CID_MMC = + 2U | (uint32_t)HAL_MEMCARD_RESPONSE_R2 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_BCR | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + CMD2_ALL_SEND_CID_SD = + 2U | (uint32_t)HAL_MEMCARD_RESPONSE_R2 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_BCR | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD3 */ + CMD3_SET_RELATIVE_ADDR = + 3U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + CMD3_SEND_RELATIVE_ADDR = + 3U | (uint32_t)HAL_MEMCARD_RESPONSE_R6 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD4 */ + CMD4_SET_DSR = + 4U | (uint32_t)HAL_MEMCARD_RESPONSE_NONE | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_BC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD5 */ + CMD5_SLEEP_AWAKE = + 5U | (uint32_t)HAL_MEMCARD_RESPONSE_R1b | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD6 */ + CMD6_SWITCH = + 6U | (uint32_t)HAL_MEMCARD_RESPONSE_R1b | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + CMD6_SWITCH_FUNC = + 6U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + ACMD6_SET_BUS_WIDTH = + 6U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | + (uint32_t)HAL_MEMCARD_COMMAND_APP, + /* CMD7 */ + CMD7_SELECT_CARD = + 7U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD7(from Disconnected State to Programming State) */ + CMD7_SELECT_CARD_PROG = + 7U | (uint32_t)HAL_MEMCARD_RESPONSE_R1b | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + CMD7_DESELECT_CARD = + 7U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD8 */ + CMD8_SEND_EXT_CSD = + 8U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + CMD8_SEND_IF_COND = + 8U | (uint32_t)HAL_MEMCARD_RESPONSE_R7 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_BCR | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD9 */ + CMD9_SEND_CSD = + 9U | (uint32_t)HAL_MEMCARD_RESPONSE_R2 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD10 */ + CMD10_SEND_CID = + 10U | (uint32_t)HAL_MEMCARD_RESPONSE_R2 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD11 */ + CMD11_READ_DAT_UNTIL_STOP = + 11U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD12 */ + CMD12_STOP_TRANSMISSION = + 12U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD12(R1b : write case) */ + CMD12_STOP_TRANSMISSION_WRITE = + 12U | (uint32_t)HAL_MEMCARD_RESPONSE_R1b | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD13 */ + CMD13_SEND_STATUS = + 13U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + ACMD13_SD_STATUS = + 13U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | + (uint32_t)HAL_MEMCARD_COMMAND_APP, + /* CMD14 */ + CMD14_BUSTEST_R = + 14U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD15 */ + CMD15_GO_INACTIVE_STATE = + 15U | (uint32_t)HAL_MEMCARD_RESPONSE_NONE | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + +/* class 2 */ + /* CMD16 */ + CMD16_SET_BLOCKLEN = + 16U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD17 */ + CMD17_READ_SINGLE_BLOCK = + 17U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD18 */ + CMD18_READ_MULTIPLE_BLOCK = + 18U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD19 */ + CMD19_BUS_TEST_W = + 19U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + +/* class 3 */ + /* CMD20 */ + CMD20_WRITE_DAT_UNTIL_STOP = + 20U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD21 */ + CMD21 = 21U, + /* CMD22 */ + CMD22 = 22U, + ACMD22_SEND_NUM_WR_BLOCKS = + 22U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | + (uint32_t)HAL_MEMCARD_COMMAND_APP, + +/* class 4 */ + /* CMD23 */ + CMD23_SET_BLOCK_COUNT = + 23U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + ACMD23_SET_WR_BLK_ERASE_COUNT = + 23U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | + (uint32_t)HAL_MEMCARD_COMMAND_APP, + /* CMD24 */ + CMD24_WRITE_BLOCK = + 24U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD25 */ + CMD25_WRITE_MULTIPLE_BLOCK = + 25U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD26 */ + CMD26_PROGRAM_CID = + 26U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD27 */ + CMD27_PROGRAM_CSD = + 27U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + +/* class 6 */ + /* CMD28 */ + CMD28_SET_WRITE_PROT = + 28U | (uint32_t)HAL_MEMCARD_RESPONSE_R1b | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD29 */ + CMD29_CLR_WRITE_PROT = + 29U | (uint32_t)HAL_MEMCARD_RESPONSE_R1b | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD30 */ + CMD30_SEND_WRITE_PROT = + 30U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD31 */ + CMD30_SEND_WRITE_PROT_TYPE = + 31U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + +/* class 5 */ + /* CMD32 */ + CMD32_ERASE_WR_BLK_START = + 32U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD33 */ + CMD33_ERASE_WR_BLK_END = + 33U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD34 */ + CMD34 = 34U, + /* CMD35 */ + CMD35_ERASE_GROUP_START = + 35U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD36 */ + CMD36_ERASE_GROUP_END = + 36U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD37 */ + CMD37 = 37U, + /* CMD38 */ + CMD38_ERASE = + 38U | (uint32_t)HAL_MEMCARD_RESPONSE_R1b | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + +/* class 9 */ + /* CMD39 */ + CMD39_FASTIO = + 39U | (uint32_t)HAL_MEMCARD_RESPONSE_R4 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD40 */ + CMD40_GO_IRQSTATE = + 40U | (uint32_t)HAL_MEMCARD_RESPONSE_R5 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_BCR | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD41 */ + CMD41 = 41, + ACMD41_SD_SEND_OP_COND = + 41U | (uint32_t)HAL_MEMCARD_RESPONSE_R3 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_BCR | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | + (uint32_t)HAL_MEMCARD_COMMAND_APP, + +/* class 7 */ + /* CMD42 */ + CMD42_LOCK_UNLOCK = + 42U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + ACMD42_SET_CLR_CARD_DETECT = + 42U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | + (uint32_t)HAL_MEMCARD_COMMAND_APP, + CMD43 = 43U, /* CMD43 */ + CMD44 = 44U, /* CMD44 */ + CMD45 = 45U, /* CMD45 */ + CMD46 = 46U, /* CMD46 */ + CMD47 = 47U, /* CMD47 */ + CMD48 = 48U, /* CMD48 */ + CMD49 = 49U, /* CMD49 */ + CMD50 = 50U, /* CMD50 */ + CMD51 = 51U, /* CMD51 */ + ACMD51_SEND_SCR = + 51U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | + (uint32_t)HAL_MEMCARD_COMMAND_APP, + CMD52 = 52U, /* CMD52 */ + CMD53 = 53U, /* CMD53 */ + CMD54 = 54U, /* CMD54 */ + +/* class 8 */ + /* CMD55 */ + CMD55_APP_CMD = + 55U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + /* CMD56 */ + CMD56_GEN_CMD = + 56U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | + (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | + (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | + (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, + CMD57 = 57U, /* CMD57 */ + CMD58 = 58U, /* CMD58 */ + CMD59 = 59U, /* CMD59 */ + CMD60 = 60U, /* CMD60 */ + CMD61 = 61U, /* CMD61 */ + CMD62 = 62U, /* CMD62 */ + CMD63 = 63U /* CMD63 */ +} HAL_MEMCARD_COMMAND; + +/* + * Configuration structure from HAL layer. + * + * If some field is not available it should be filled with 0xFF. + * The API version is 32-bit unsigned integer telling the version of the API. + * The integer is divided to four sections which each can be treated as a 8-bit + * unsigned number: + * Bits 31-24 make the most significant part of the version number. This number + * starts from 1 i.e. the second version of the API will be 0x02xxxxxx. This + * number changes only, if the API itself changes so much that it is not + * compatible anymore with older releases. + * Bits 23-16 API minor version number. For example API version 2.1 would be + * 0x0201xxxx. + * Bits 15-8 are the number of the year when release is done. The 0 is year + * 2000, 1 is year 2001 and so on + * Bits 7- are the week number when release is done. First full week of the + * year is 1 + * + * Example: let's assume that release 2.1 is done on week 10 year 2008 + * the version will get the value 0x0201080A + */ +typedef struct { + /* + * Version of the chipset API implementation + * + * bits [31:24] API specification major version number.
+ * bits [23:16] API specification minor version number.
+ * bits [15:8] API implementation year. (2000 = 0, 2001 = 1, ...) + * bits [7:0] API implementation week. + * Example: API spec version 4.0, implementation w46 2008 => 0x0400082E + */ + uint32_t api_version; + + /* maximum block count which can be transferred at once */ + uint32_t max_block_count; + + /* maximum clock frequence in Hz supported by HW */ + uint32_t max_clock_freq; + + /* maximum data bus width supported by HW */ + uint16_t max_data_width; + + /* Is high-speed mode supported by HW (yes=1, no=0) */ + uint8_t hs_mode_supported; + + /* Is memory card removable (yes=1, no=0) */ + uint8_t card_removable; + +} HAL_MEMCARD_HW_CONF; + +/* Configuration structure to HAL layer. */ +typedef struct { + /* how many times to try after fail, for instance sending command */ + uint32_t retries_after_fail; +} HAL_MEMCARD_INIT_CONF; + +#endif /* EMMC_HAL_H */ diff --git a/drivers/renesas/common/emmc/emmc_init.c b/drivers/renesas/common/emmc/emmc_init.c new file mode 100644 index 000000000..354aa3c82 --- /dev/null +++ b/drivers/renesas/common/emmc/emmc_init.c @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include + +#include "emmc_config.h" +#include "emmc_hal.h" +#include "emmc_std.h" +#include "emmc_registers.h" +#include "emmc_def.h" +#include "rcar_private.h" + +st_mmc_base mmc_drv_obj; + +EMMC_ERROR_CODE rcar_emmc_memcard_power(uint8_t mode) +{ + + if (mode == TRUE) { + /* power on (Vcc&Vccq is always power on) */ + mmc_drv_obj.card_power_enable = TRUE; + } else { + /* power off (Vcc&Vccq is always power on) */ + mmc_drv_obj.card_power_enable = FALSE; + mmc_drv_obj.mount = FALSE; + mmc_drv_obj.selected = FALSE; + } + + return EMMC_SUCCESS; +} +static inline void emmc_set_retry_count(uint32_t retry) +{ + mmc_drv_obj.retries_after_fail = retry; +} + +static inline void emmc_set_data_timeout(uint32_t data_timeout) +{ + mmc_drv_obj.data_timeout = data_timeout; +} + +static void emmc_memset(uint8_t *buff, uint8_t data, uint32_t cnt) +{ + if (buff == NULL) { + return; + } + + while (cnt > 0) { + *buff++ = data; + cnt--; + } +} + +static void emmc_driver_config(void) +{ + emmc_set_retry_count(EMMC_RETRY_COUNT); + emmc_set_data_timeout(EMMC_RW_DATA_TIMEOUT); +} + +static void emmc_drv_init(void) +{ + emmc_memset((uint8_t *) (&mmc_drv_obj), 0, sizeof(st_mmc_base)); + mmc_drv_obj.card_present = HAL_MEMCARD_CARD_IS_IN; + mmc_drv_obj.data_timeout = EMMC_RW_DATA_TIMEOUT; + mmc_drv_obj.bus_width = HAL_MEMCARD_DATA_WIDTH_1_BIT; +} + +static EMMC_ERROR_CODE emmc_dev_finalize(void) +{ + EMMC_ERROR_CODE result; + uint32_t dataL; + + /* + * MMC power off + * the power supply of eMMC device is always turning on. + * RST_n : Hi --> Low level. + */ + result = rcar_emmc_memcard_power(FALSE); + + /* host controller reset */ + SETR_32(SD_INFO1, 0x00000000U); /* all interrupt clear */ + SETR_32(SD_INFO2, SD_INFO2_CLEAR); /* all interrupt clear */ + SETR_32(SD_INFO1_MASK, 0x00000000U); /* all interrupt disable */ + SETR_32(SD_INFO2_MASK, SD_INFO2_CLEAR); /* all interrupt disable */ + SETR_32(SD_CLK_CTRL, 0x00000000U); /* MMC clock stop */ + + dataL = mmio_read_32(CPG_SMSTPCR3); + if ((dataL & CPG_MSTP_MMC) == 0U) { + dataL |= (CPG_MSTP_MMC); + mmio_write_32(CPG_CPGWPR, (~dataL)); + mmio_write_32(CPG_SMSTPCR3, dataL); + } + + return result; +} + +static EMMC_ERROR_CODE emmc_dev_init(void) +{ + /* Enable clock supply to eMMC. */ + mstpcr_write(CPG_SMSTPCR3, CPG_MSTPSR3, CPG_MSTP_MMC); + + /* Set SD clock */ + mmio_write_32(CPG_CPGWPR, ~((uint32_t) (BIT9 | BIT0))); /* SD phy 200MHz */ + + /* Stop SDnH clock & SDn=200MHz */ + mmio_write_32(CPG_SDxCKCR, (BIT9 | BIT0)); + + /* MMCIF initialize */ + SETR_32(SD_INFO1, 0x00000000U); /* all interrupt clear */ + SETR_32(SD_INFO2, SD_INFO2_CLEAR); /* all interrupt clear */ + SETR_32(SD_INFO1_MASK, 0x00000000U); /* all interrupt disable */ + SETR_32(SD_INFO2_MASK, SD_INFO2_CLEAR); /* all interrupt disable */ + + SETR_32(HOST_MODE, 0x00000000U); /* SD_BUF access width = 64-bit */ + SETR_32(SD_OPTION, 0x0000C0EEU); /* Bus width = 1bit, timeout=MAX */ + SETR_32(SD_CLK_CTRL, 0x00000000U); /* Disable Automatic Control & Clock Output */ + + return EMMC_SUCCESS; +} + +static EMMC_ERROR_CODE emmc_reset_controller(void) +{ + EMMC_ERROR_CODE result; + + /* initialize mmc driver */ + emmc_drv_init(); + + /* initialize H/W */ + result = emmc_dev_init(); + if (result == EMMC_SUCCESS) { + mmc_drv_obj.initialize = TRUE; + } + + return result; + +} + +EMMC_ERROR_CODE emmc_terminate(void) +{ + EMMC_ERROR_CODE result; + + result = emmc_dev_finalize(); + + emmc_memset((uint8_t *) (&mmc_drv_obj), 0, sizeof(st_mmc_base)); + + return result; +} + +EMMC_ERROR_CODE rcar_emmc_init(void) +{ + EMMC_ERROR_CODE result; + + result = emmc_reset_controller(); + if (result == EMMC_SUCCESS) { + emmc_driver_config(); + } + + return result; +} diff --git a/drivers/renesas/common/emmc/emmc_interrupt.c b/drivers/renesas/common/emmc/emmc_interrupt.c new file mode 100644 index 000000000..092fdfb72 --- /dev/null +++ b/drivers/renesas/common/emmc/emmc_interrupt.c @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights + * reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include + +#include "emmc_config.h" +#include "emmc_def.h" +#include "emmc_hal.h" +#include "emmc_registers.h" +#include "emmc_std.h" +#include "rcar_def.h" + +static EMMC_ERROR_CODE emmc_trans_sector(uint32_t *buff_address_virtual); + +uint32_t emmc_interrupt(void) +{ + EMMC_ERROR_CODE result; + uint32_t prr_data; + uint32_t cut_ver; + uint32_t end_bit; + + prr_data = mmio_read_32((uintptr_t) RCAR_PRR); + cut_ver = prr_data & PRR_CUT_MASK; + if ((prr_data & PRR_PRODUCT_MASK) == PRR_PRODUCT_H3) { + if (cut_ver == PRR_PRODUCT_10) { + end_bit = BIT17; + } else if (cut_ver == PRR_PRODUCT_11) { + end_bit = BIT17; + } else { + end_bit = BIT20; + } + } else if ((prr_data & PRR_PRODUCT_MASK) == PRR_PRODUCT_M3) { + if (cut_ver == PRR_PRODUCT_10) { + end_bit = BIT17; + } else { + end_bit = BIT20; + } + } else { + end_bit = BIT20; + } + + /* SD_INFO */ + mmc_drv_obj.error_info.info1 = GETR_32(SD_INFO1); + mmc_drv_obj.error_info.info2 = GETR_32(SD_INFO2); + + /* SD_INFO EVENT */ + mmc_drv_obj.int_event1 = + mmc_drv_obj.error_info.info1 & GETR_32(SD_INFO1_MASK); + mmc_drv_obj.int_event2 = + mmc_drv_obj.error_info.info2 & GETR_32(SD_INFO2_MASK); + + /* ERR_STS */ + mmc_drv_obj.error_info.status1 = GETR_32(SD_ERR_STS1); + mmc_drv_obj.error_info.status2 = GETR_32(SD_ERR_STS2); + + /* DM_CM_INFO */ + mmc_drv_obj.error_info.dm_info1 = GETR_32(DM_CM_INFO1); + mmc_drv_obj.error_info.dm_info2 = GETR_32(DM_CM_INFO2); + + /* DM_CM_INFO EVENT */ + mmc_drv_obj.dm_event1 = + mmc_drv_obj.error_info.dm_info1 & GETR_32(DM_CM_INFO1_MASK); + mmc_drv_obj.dm_event2 = + mmc_drv_obj.error_info.dm_info2 & GETR_32(DM_CM_INFO2_MASK); + + /* ERR SD_INFO2 */ + if ((SD_INFO2_ALL_ERR & mmc_drv_obj.int_event2) != 0) { + SETR_32(SD_INFO1_MASK, 0x00000000U); /* interrupt disable */ + SETR_32(SD_INFO2_MASK, SD_INFO2_CLEAR); /* interrupt disable */ + SETR_32(SD_INFO1, 0x00000000U); /* interrupt clear */ + SETR_32(SD_INFO2, SD_INFO2_CLEAR); /* interrupt clear */ + mmc_drv_obj.state_machine_blocking = FALSE; + } + + /* PIO Transfer */ + /* BWE/BRE */ + else if (((SD_INFO2_BWE | SD_INFO2_BRE) & mmc_drv_obj.int_event2)) { + /* BWE */ + if (SD_INFO2_BWE & mmc_drv_obj.int_event2) { + SETR_32(SD_INFO2, (GETR_32(SD_INFO2) & ~SD_INFO2_BWE)); + } + /* BRE */ + else { + SETR_32(SD_INFO2, (GETR_32(SD_INFO2) & ~SD_INFO2_BRE)); + } + + result = emmc_trans_sector(mmc_drv_obj.buff_address_virtual); + mmc_drv_obj.buff_address_virtual += EMMC_BLOCK_LENGTH; + mmc_drv_obj.remain_size -= EMMC_BLOCK_LENGTH; + + if (result != EMMC_SUCCESS) { + /* data transfer error */ + emmc_write_error_info(EMMC_FUNCNO_NONE, result); + + /* Panic */ + SETR_32(SD_INFO1_MASK, 0x00000000U); + SETR_32(SD_INFO2_MASK, SD_INFO2_CLEAR); + SETR_32(SD_INFO1, 0x00000000U); + /* interrupt clear */ + SETR_32(SD_INFO2, SD_INFO2_CLEAR); + mmc_drv_obj.force_terminate = TRUE; + } else { + mmc_drv_obj.during_transfer = FALSE; + } + mmc_drv_obj.state_machine_blocking = FALSE; + } + + /* DMA_TRANSFER */ + /* DM_CM_INFO1: DMA-ch0 transfer complete or error occurred */ + else if ((BIT16 & mmc_drv_obj.dm_event1) != 0) { + SETR_32(DM_CM_INFO1, 0x00000000U); + SETR_32(DM_CM_INFO2, 0x00000000U); + /* interrupt clear */ + SETR_32(SD_INFO2, (GETR_32(SD_INFO2) & ~SD_INFO2_BWE)); + /* DM_CM_INFO2: DMA-ch0 error occurred */ + if ((BIT16 & mmc_drv_obj.dm_event2) != 0) { + mmc_drv_obj.dma_error_flag = TRUE; + } else { + mmc_drv_obj.during_dma_transfer = FALSE; + mmc_drv_obj.during_transfer = FALSE; + } + /* wait next interrupt */ + mmc_drv_obj.state_machine_blocking = FALSE; + } + /* DM_CM_INFO1: DMA-ch1 transfer complete or error occurred */ + else if ((end_bit & mmc_drv_obj.dm_event1) != 0U) { + SETR_32(DM_CM_INFO1, 0x00000000U); + SETR_32(DM_CM_INFO2, 0x00000000U); + /* interrupt clear */ + SETR_32(SD_INFO2, (GETR_32(SD_INFO2) & ~SD_INFO2_BRE)); + /* DM_CM_INFO2: DMA-ch1 error occurred */ + if ((BIT17 & mmc_drv_obj.dm_event2) != 0) { + mmc_drv_obj.dma_error_flag = TRUE; + } else { + mmc_drv_obj.during_dma_transfer = FALSE; + mmc_drv_obj.during_transfer = FALSE; + } + /* wait next interrupt */ + mmc_drv_obj.state_machine_blocking = FALSE; + } + + /* Response end */ + else if ((SD_INFO1_INFO0 & mmc_drv_obj.int_event1) != 0) { + /* interrupt clear */ + SETR_32(SD_INFO1, (GETR_32(SD_INFO1) & ~SD_INFO1_INFO0)); + mmc_drv_obj.state_machine_blocking = FALSE; + } + /* Access end */ + else if ((SD_INFO1_INFO2 & mmc_drv_obj.int_event1) != 0) { + /* interrupt clear */ + SETR_32(SD_INFO1, (GETR_32(SD_INFO1) & ~SD_INFO1_INFO2)); + mmc_drv_obj.state_machine_blocking = FALSE; + } else { + /* nothing to do. */ + } + + return (uint32_t) 0; +} + +static EMMC_ERROR_CODE emmc_trans_sector(uint32_t *buff_address_virtual) +{ + uint32_t length, i; + uint64_t *bufPtrLL; + + if (buff_address_virtual == NULL) { + return EMMC_ERR_PARAM; + } + + if ((mmc_drv_obj.during_transfer != TRUE) + || (mmc_drv_obj.remain_size == 0)) { + return EMMC_ERR_STATE; + } + + bufPtrLL = (uint64_t *) buff_address_virtual; + length = mmc_drv_obj.remain_size; + + /* data transefer */ + for (i = 0; i < (length >> 3); i++) { + /* Write */ + if (mmc_drv_obj.cmd_info.dir == HAL_MEMCARD_WRITE) { + SETR_64(SD_BUF0, *bufPtrLL); /* buffer --> FIFO */ + } + /* Read */ + else { + /* Checks when the read data reaches SD_SIZE. */ + /* The BRE bit is cleared at emmc_interrupt function. */ + if (((i % + (uint32_t) (EMMC_BLOCK_LENGTH >> + EMMC_BUF_SIZE_SHIFT)) == 0U) + && (i != 0U)) { + /* BRE check */ + while (((GETR_32(SD_INFO2)) & SD_INFO2_BRE) == + 0U) { + /* ERROR check */ + if (((GETR_32(SD_INFO2)) & + SD_INFO2_ALL_ERR) != 0U) { + return EMMC_ERR_TRANSFER; + } + } + /* BRE clear */ + SETR_32(SD_INFO2, + (uint32_t) (GETR_32(SD_INFO2) & + ~SD_INFO2_BRE)); + } + *bufPtrLL = GETR_64(SD_BUF0); /* FIFO --> buffer */ + } + bufPtrLL++; + } + + return EMMC_SUCCESS; +} diff --git a/drivers/renesas/common/emmc/emmc_mount.c b/drivers/renesas/common/emmc/emmc_mount.c new file mode 100644 index 000000000..e04afd4cf --- /dev/null +++ b/drivers/renesas/common/emmc/emmc_mount.c @@ -0,0 +1,686 @@ +/* + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include "emmc_config.h" +#include "emmc_def.h" +#include "emmc_hal.h" +#include "emmc_registers.h" +#include "emmc_std.h" +#include "micro_delay.h" +#include "rcar_def.h" + +static EMMC_ERROR_CODE emmc_clock_ctrl(uint8_t mode); +static EMMC_ERROR_CODE emmc_card_init(void); +static EMMC_ERROR_CODE emmc_high_speed(void); +static EMMC_ERROR_CODE emmc_bus_width(uint32_t width); +static uint32_t emmc_set_timeout_register_value(uint32_t freq); +static void set_sd_clk(uint32_t clkDiv); +static uint32_t emmc_calc_tran_speed(uint32_t *freq); +static void emmc_get_partition_access(void); +static void emmc_set_bootpartition(void); + +static void emmc_set_bootpartition(void) +{ + uint32_t reg; + + reg = mmio_read_32(RCAR_PRR) & (PRR_PRODUCT_MASK | PRR_CUT_MASK); + if (reg == PRR_PRODUCT_M3_CUT10) { + mmc_drv_obj.boot_partition_en = + (EMMC_PARTITION_ID) ((mmc_drv_obj.ext_csd_data[179] & + EMMC_BOOT_PARTITION_EN_MASK) >> + EMMC_BOOT_PARTITION_EN_SHIFT); + } else if ((reg == PRR_PRODUCT_H3_CUT20) + || (reg == PRR_PRODUCT_M3_CUT11)) { + mmc_drv_obj.boot_partition_en = mmc_drv_obj.partition_access; + } else { + if ((mmio_read_32(MFISBTSTSR) & MFISBTSTSR_BOOT_PARTITION) != + 0U) { + mmc_drv_obj.boot_partition_en = PARTITION_ID_BOOT_2; + } else { + mmc_drv_obj.boot_partition_en = PARTITION_ID_BOOT_1; + } + } +} + +static EMMC_ERROR_CODE emmc_card_init(void) +{ + int32_t retry; + uint32_t freq = MMC_400KHZ; /* 390KHz */ + EMMC_ERROR_CODE result; + uint32_t result_calc; + + /* state check */ + if ((mmc_drv_obj.initialize != TRUE) + || (mmc_drv_obj.card_power_enable != TRUE) + || ((GETR_32(SD_INFO2) & SD_INFO2_CBSY) != 0) + ) { + emmc_write_error_info(EMMC_FUNCNO_CARD_INIT, EMMC_ERR_STATE); + return EMMC_ERR_STATE; + } + + /* clock on (force change) */ + mmc_drv_obj.current_freq = 0; + mmc_drv_obj.max_freq = MMC_20MHZ; + result = emmc_set_request_mmc_clock(&freq); + if (result != EMMC_SUCCESS) { + emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT); + return EMMC_ERR; + } + + rcar_micro_delay(1000U); /* wait 1ms */ + + /* Get current access partition */ + emmc_get_partition_access(); + + /* CMD0, arg=0x00000000 */ + result = emmc_send_idle_cmd(0x00000000); + if (result != EMMC_SUCCESS) { + emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT); + return result; + } + + rcar_micro_delay(200U); /* wait 74clock 390kHz(189.74us) */ + + /* CMD1 */ + emmc_make_nontrans_cmd(CMD1_SEND_OP_COND, EMMC_HOST_OCR_VALUE); + for (retry = 300; retry > 0; retry--) { + result = + emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); + if (result != EMMC_SUCCESS) { + emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT); + return result; + } + + if ((mmc_drv_obj.r3_ocr & EMMC_OCR_STATUS_BIT) != 0) { + break; /* card is ready. exit loop */ + } + rcar_micro_delay(1000U); /* wait 1ms */ + } + + if (retry == 0) { + emmc_write_error_info(EMMC_FUNCNO_CARD_INIT, EMMC_ERR_TIMEOUT); + return EMMC_ERR_TIMEOUT; + } + + switch (mmc_drv_obj.r3_ocr & EMMC_OCR_ACCESS_MODE_MASK) { + case EMMC_OCR_ACCESS_MODE_SECT: + mmc_drv_obj.access_mode = TRUE; /* sector mode */ + break; + default: + /* unknown value */ + emmc_write_error_info(EMMC_FUNCNO_CARD_INIT, EMMC_ERR); + return EMMC_ERR; + } + + /* CMD2 */ + emmc_make_nontrans_cmd(CMD2_ALL_SEND_CID_MMC, 0x00000000); + mmc_drv_obj.response = (uint32_t *) (&mmc_drv_obj.cid_data[0]); /* use CID special buffer */ + result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); + if (result != EMMC_SUCCESS) { + emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT); + return result; + } + + /* CMD3 */ + emmc_make_nontrans_cmd(CMD3_SET_RELATIVE_ADDR, EMMC_RCA << 16); + result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); + if (result != EMMC_SUCCESS) { + emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT); + return result; + } + + /* CMD9 (CSD) */ + emmc_make_nontrans_cmd(CMD9_SEND_CSD, EMMC_RCA << 16); + mmc_drv_obj.response = (uint32_t *) (&mmc_drv_obj.csd_data[0]); /* use CSD special buffer */ + result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); + if (result != EMMC_SUCCESS) { + emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT); + return result; + } + + /* card version check */ + if (EMMC_CSD_SPEC_VARS() < 4) { + emmc_write_error_info(EMMC_FUNCNO_CARD_INIT, + EMMC_ERR_ILLEGAL_CARD); + return EMMC_ERR_ILLEGAL_CARD; + } + + /* CMD7 (select card) */ + emmc_make_nontrans_cmd(CMD7_SELECT_CARD, EMMC_RCA << 16); + result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); + if (result != EMMC_SUCCESS) { + emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT); + return result; + } + + mmc_drv_obj.selected = TRUE; + + /* + * card speed check + * Card spec is calculated from TRAN_SPEED(CSD) + */ + result_calc = emmc_calc_tran_speed(&freq); + if (result_calc == 0) { + emmc_write_error_info(EMMC_FUNCNO_CARD_INIT, + EMMC_ERR_ILLEGAL_CARD); + return EMMC_ERR_ILLEGAL_CARD; + } + mmc_drv_obj.max_freq = freq; /* max frequency (card spec) */ + + result = emmc_set_request_mmc_clock(&freq); + if (result != EMMC_SUCCESS) { + emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT); + return EMMC_ERR; + } + + /* set read/write timeout */ + mmc_drv_obj.data_timeout = emmc_set_timeout_register_value(freq); + SETR_32(SD_OPTION, + ((GETR_32(SD_OPTION) & ~(SD_OPTION_TIMEOUT_CNT_MASK)) | + mmc_drv_obj.data_timeout)); + + /* SET_BLOCKLEN(512byte) */ + /* CMD16 */ + emmc_make_nontrans_cmd(CMD16_SET_BLOCKLEN, EMMC_BLOCK_LENGTH); + result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); + if (result != EMMC_SUCCESS) { + emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT); + return result; + } + + /* Transfer Data Length */ + SETR_32(SD_SIZE, EMMC_BLOCK_LENGTH); + + /* CMD8 (EXT_CSD) */ + emmc_make_trans_cmd(CMD8_SEND_EXT_CSD, 0x00000000, + (uint32_t *) (&mmc_drv_obj.ext_csd_data[0]), + EMMC_MAX_EXT_CSD_LENGTH, HAL_MEMCARD_READ, + HAL_MEMCARD_NOT_DMA); + result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); + if (result != EMMC_SUCCESS) { + /* + * CMD12 is not send. + * If BUS initialization is failed, user must be execute Bus initialization again. + * Bus initialization is start CMD0(soft reset command). + */ + emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT); + return result; + } + + /* Set boot partition */ + emmc_set_bootpartition(); + + return EMMC_SUCCESS; +} + +static EMMC_ERROR_CODE emmc_high_speed(void) +{ + uint32_t freq; /* High speed mode clock frequency */ + EMMC_ERROR_CODE result; + uint8_t cardType; + + /* state check */ + if (mmc_drv_obj.selected != TRUE) { + emmc_write_error_info(EMMC_FUNCNO_HIGH_SPEED, EMMC_ERR_STATE); + return EMMC_ERR_STATE; + } + + /* max frequency */ + cardType = (uint8_t) mmc_drv_obj.ext_csd_data[EMMC_EXT_CSD_CARD_TYPE]; + if ((cardType & EMMC_EXT_CSD_CARD_TYPE_52MHZ) != 0) + freq = MMC_52MHZ; + else if ((cardType & EMMC_EXT_CSD_CARD_TYPE_26MHZ) != 0) + freq = MMC_26MHZ; + else + freq = MMC_20MHZ; + + /* Hi-Speed-mode selection */ + if ((freq == MMC_52MHZ) || (freq == MMC_26MHZ)) { + /* CMD6 */ + emmc_make_nontrans_cmd(CMD6_SWITCH, EMMC_SWITCH_HS_TIMING); + result = + emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); + if (result != EMMC_SUCCESS) { + emmc_write_error_info_func_no(EMMC_FUNCNO_HIGH_SPEED); + return result; + } + + mmc_drv_obj.hs_timing = TIMING_HIGH_SPEED; /* High-Speed */ + } + + /* set mmc clock */ + mmc_drv_obj.max_freq = freq; + result = emmc_set_request_mmc_clock(&freq); + if (result != EMMC_SUCCESS) { + emmc_write_error_info_func_no(EMMC_FUNCNO_HIGH_SPEED); + return EMMC_ERR; + } + + /* set read/write timeout */ + mmc_drv_obj.data_timeout = emmc_set_timeout_register_value(freq); + SETR_32(SD_OPTION, + ((GETR_32(SD_OPTION) & ~(SD_OPTION_TIMEOUT_CNT_MASK)) | + mmc_drv_obj.data_timeout)); + + /* CMD13 */ + emmc_make_nontrans_cmd(CMD13_SEND_STATUS, EMMC_RCA << 16); + result = + emmc_exec_cmd(EMMC_R1_ERROR_MASK_WITHOUT_CRC, mmc_drv_obj.response); + if (result != EMMC_SUCCESS) { + emmc_write_error_info_func_no(EMMC_FUNCNO_HIGH_SPEED); + return result; + } + + return EMMC_SUCCESS; +} + +static EMMC_ERROR_CODE emmc_clock_ctrl(uint8_t mode) +{ + uint32_t value; + + /* busy check */ + if ((GETR_32(SD_INFO2) & SD_INFO2_CBSY) != 0) { + emmc_write_error_info(EMMC_FUNCNO_SET_CLOCK, + EMMC_ERR_CARD_BUSY); + return EMMC_ERR; + } + + if (mode == TRUE) { + /* clock ON */ + value = + ((GETR_32(SD_CLK_CTRL) | MMC_SD_CLK_START) & + SD_CLK_WRITE_MASK); + SETR_32(SD_CLK_CTRL, value); /* on */ + mmc_drv_obj.clock_enable = TRUE; + } else { + /* clock OFF */ + value = + ((GETR_32(SD_CLK_CTRL) & MMC_SD_CLK_STOP) & + SD_CLK_WRITE_MASK); + SETR_32(SD_CLK_CTRL, value); /* off */ + mmc_drv_obj.clock_enable = FALSE; + } + + return EMMC_SUCCESS; +} + +static EMMC_ERROR_CODE emmc_bus_width(uint32_t width) +{ + EMMC_ERROR_CODE result = EMMC_ERR; + + /* parameter check */ + if ((width != 8) && (width != 4) && (width != 1)) { + emmc_write_error_info(EMMC_FUNCNO_BUS_WIDTH, EMMC_ERR_PARAM); + return EMMC_ERR_PARAM; + } + + /* state check */ + if (mmc_drv_obj.selected != TRUE) { + emmc_write_error_info(EMMC_FUNCNO_BUS_WIDTH, EMMC_ERR_STATE); + return EMMC_ERR_STATE; + } + + /* 2 = 8bit, 1 = 4bit, 0 =1bit */ + mmc_drv_obj.bus_width = (HAL_MEMCARD_DATA_WIDTH) (width >> 2); + + /* CMD6 */ + emmc_make_nontrans_cmd(CMD6_SWITCH, + (EMMC_SWITCH_BUS_WIDTH_1 | + (mmc_drv_obj.bus_width << 8))); + result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); + if (result != EMMC_SUCCESS) { + /* occurred error */ + mmc_drv_obj.bus_width = HAL_MEMCARD_DATA_WIDTH_1_BIT; + goto EXIT; + } + + switch (mmc_drv_obj.bus_width) { + case HAL_MEMCARD_DATA_WIDTH_1_BIT: + SETR_32(SD_OPTION, + ((GETR_32(SD_OPTION) & ~(BIT15 | BIT13)) | BIT15)); + break; + case HAL_MEMCARD_DATA_WIDTH_4_BIT: + SETR_32(SD_OPTION, (GETR_32(SD_OPTION) & ~(BIT15 | BIT13))); + break; + case HAL_MEMCARD_DATA_WIDTH_8_BIT: + SETR_32(SD_OPTION, + ((GETR_32(SD_OPTION) & ~(BIT15 | BIT13)) | BIT13)); + break; + default: + goto EXIT; + } + + /* CMD13 */ + emmc_make_nontrans_cmd(CMD13_SEND_STATUS, EMMC_RCA << 16); + result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); + if (result != EMMC_SUCCESS) { + goto EXIT; + } + + /* CMD8 (EXT_CSD) */ + emmc_make_trans_cmd(CMD8_SEND_EXT_CSD, 0x00000000, + (uint32_t *) (&mmc_drv_obj.ext_csd_data[0]), + EMMC_MAX_EXT_CSD_LENGTH, HAL_MEMCARD_READ, + HAL_MEMCARD_NOT_DMA); + result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); + if (result != EMMC_SUCCESS) { + goto EXIT; + } + + return EMMC_SUCCESS; + +EXIT: + emmc_write_error_info(EMMC_FUNCNO_BUS_WIDTH, result); + ERROR("BL2: emmc bus_width error end\n"); + return result; +} + +EMMC_ERROR_CODE emmc_select_partition(EMMC_PARTITION_ID id) +{ + EMMC_ERROR_CODE result; + uint32_t arg; + uint32_t partition_config; + + /* state check */ + if (mmc_drv_obj.mount != TRUE) { + emmc_write_error_info(EMMC_FUNCNO_NONE, EMMC_ERR_STATE); + return EMMC_ERR_STATE; + } + + /* id = PARTITION_ACCESS(Bit[2:0]) */ + if ((id & ~PARTITION_ID_MASK) != 0) { + emmc_write_error_info(EMMC_FUNCNO_NONE, EMMC_ERR_PARAM); + return EMMC_ERR_PARAM; + } + + /* EXT_CSD[179] value */ + partition_config = + (uint32_t) mmc_drv_obj.ext_csd_data[EMMC_EXT_CSD_PARTITION_CONFIG]; + if ((partition_config & PARTITION_ID_MASK) == id) { + result = EMMC_SUCCESS; + } else { + + partition_config = + (uint32_t) ((partition_config & ~PARTITION_ID_MASK) | id); + arg = EMMC_SWITCH_PARTITION_CONFIG | (partition_config << 8); + + result = emmc_set_ext_csd(arg); + } + + return result; +} + +static void set_sd_clk(uint32_t clkDiv) +{ + uint32_t dataL; + + dataL = (GETR_32(SD_CLK_CTRL) & (~SD_CLK_CTRL_CLKDIV_MASK)); + + switch (clkDiv) { + case 1: + dataL |= 0x000000FFU; + break; /* 1/1 */ + case 2: + dataL |= 0x00000000U; + break; /* 1/2 */ + case 4: + dataL |= 0x00000001U; + break; /* 1/4 */ + case 8: + dataL |= 0x00000002U; + break; /* 1/8 */ + case 16: + dataL |= 0x00000004U; + break; /* 1/16 */ + case 32: + dataL |= 0x00000008U; + break; /* 1/32 */ + case 64: + dataL |= 0x00000010U; + break; /* 1/64 */ + case 128: + dataL |= 0x00000020U; + break; /* 1/128 */ + case 256: + dataL |= 0x00000040U; + break; /* 1/256 */ + case 512: + dataL |= 0x00000080U; + break; /* 1/512 */ + } + + SETR_32(SD_CLK_CTRL, dataL); + mmc_drv_obj.current_freq = (uint32_t) clkDiv; +} + +static void emmc_get_partition_access(void) +{ + uint32_t reg; + EMMC_ERROR_CODE result; + + reg = mmio_read_32(RCAR_PRR) & (PRR_PRODUCT_MASK | PRR_CUT_MASK); + if ((reg == PRR_PRODUCT_H3_CUT20) || (reg == PRR_PRODUCT_M3_CUT11)) { + SETR_32(SD_OPTION, 0x000060EEU); /* 8 bits width */ + /* CMD8 (EXT_CSD) */ + emmc_make_trans_cmd(CMD8_SEND_EXT_CSD, 0x00000000U, + (uint32_t *) (&mmc_drv_obj.ext_csd_data[0]), + EMMC_MAX_EXT_CSD_LENGTH, + HAL_MEMCARD_READ, HAL_MEMCARD_NOT_DMA); + mmc_drv_obj.get_partition_access_flag = TRUE; + result = + emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); + mmc_drv_obj.get_partition_access_flag = FALSE; + if (result == EMMC_SUCCESS) { + mmc_drv_obj.partition_access = + (EMMC_PARTITION_ID) (mmc_drv_obj.ext_csd_data[179] + & PARTITION_ID_MASK); + } else if (result == EMMC_ERR_CMD_TIMEOUT) { + mmc_drv_obj.partition_access = PARTITION_ID_BOOT_1; + } else { + emmc_write_error_info(EMMC_FUNCNO_GET_PERTITION_ACCESS, + result); + panic(); + } + SETR_32(SD_OPTION, 0x0000C0EEU); /* Initialize */ + } +} + +static uint32_t emmc_calc_tran_speed(uint32_t *freq) +{ + const uint32_t unit[8] = { 10000U, 100000U, 1000000U, 10000000U, + 0U, 0U, 0U, 0U }; /* frequency unit (1/10) */ + const uint32_t mult[16] = { 0U, 10U, 12U, 13U, 15U, 20U, 26U, 30U, 35U, + 40U, 45U, 52U, 55U, 60U, 70U, 80U }; + uint32_t tran_speed = EMMC_CSD_TRAN_SPEED(); + uint32_t max_freq; + uint32_t result; + + /* + * tran_speed = 0x32 + * unit[tran_speed&0x7] = uint[0x2] = 1000000 + * mult[(tran_speed&0x78)>>3] = mult[0x30>>3] = mult[6] = 26 + * 1000000 * 26 = 26000000 (26MHz) + */ + + result = 1; + max_freq = + unit[tran_speed & EMMC_TRANSPEED_FREQ_UNIT_MASK] * + mult[(tran_speed & EMMC_TRANSPEED_MULT_MASK) >> + EMMC_TRANSPEED_MULT_SHIFT]; + + if (max_freq == 0) { + result = 0; + } else if (max_freq >= MMC_FREQ_52MHZ) { + *freq = MMC_52MHZ; + } else if (max_freq >= MMC_FREQ_26MHZ) { + *freq = MMC_26MHZ; + } else if (max_freq >= MMC_FREQ_20MHZ) { + *freq = MMC_20MHZ; + } else { + *freq = MMC_400KHZ; + } + + return result; +} + +static uint32_t emmc_set_timeout_register_value(uint32_t freq) +{ + uint32_t timeout_cnt; /* SD_OPTION - Timeout Counter */ + + switch (freq) { + case 1U: + timeout_cnt = 0xE0U; + break; /* SDCLK * 2^27 */ + case 2U: + timeout_cnt = 0xE0U; + break; /* SDCLK * 2^27 */ + case 4U: + timeout_cnt = 0xD0U; + break; /* SDCLK * 2^26 */ + case 8U: + timeout_cnt = 0xC0U; + break; /* SDCLK * 2^25 */ + case 16U: + timeout_cnt = 0xB0U; + break; /* SDCLK * 2^24 */ + case 32U: + timeout_cnt = 0xA0U; + break; /* SDCLK * 2^23 */ + case 64U: + timeout_cnt = 0x90U; + break; /* SDCLK * 2^22 */ + case 128U: + timeout_cnt = 0x80U; + break; /* SDCLK * 2^21 */ + case 256U: + timeout_cnt = 0x70U; + break; /* SDCLK * 2^20 */ + case 512U: + timeout_cnt = 0x70U; + break; /* SDCLK * 2^20 */ + default: + timeout_cnt = 0xE0U; + break; /* SDCLK * 2^27 */ + } + + return timeout_cnt; +} + +EMMC_ERROR_CODE emmc_set_ext_csd(uint32_t arg) +{ + EMMC_ERROR_CODE result; + + /* CMD6 */ + emmc_make_nontrans_cmd(CMD6_SWITCH, arg); + result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); + if (result != EMMC_SUCCESS) { + return result; + } + + /* CMD13 */ + emmc_make_nontrans_cmd(CMD13_SEND_STATUS, EMMC_RCA << 16); + result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); + if (result != EMMC_SUCCESS) { + return result; + } + + /* CMD8 (EXT_CSD) */ + emmc_make_trans_cmd(CMD8_SEND_EXT_CSD, 0x00000000, + (uint32_t *) (&mmc_drv_obj.ext_csd_data[0]), + EMMC_MAX_EXT_CSD_LENGTH, HAL_MEMCARD_READ, + HAL_MEMCARD_NOT_DMA); + result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); + if (result != EMMC_SUCCESS) { + return result; + } + return EMMC_SUCCESS; +} + +EMMC_ERROR_CODE emmc_set_request_mmc_clock(uint32_t *freq) +{ + /* parameter check */ + if (freq == NULL) { + emmc_write_error_info(EMMC_FUNCNO_SET_CLOCK, EMMC_ERR_PARAM); + return EMMC_ERR_PARAM; + } + + /* state check */ + if ((mmc_drv_obj.initialize != TRUE) + || (mmc_drv_obj.card_power_enable != TRUE)) { + emmc_write_error_info(EMMC_FUNCNO_SET_CLOCK, EMMC_ERR_STATE); + return EMMC_ERR_STATE; + } + + /* clock is already running in the desired frequency. */ + if ((mmc_drv_obj.clock_enable == TRUE) + && (mmc_drv_obj.current_freq == *freq)) { + return EMMC_SUCCESS; + } + + /* busy check */ + if ((GETR_32(SD_INFO2) & SD_INFO2_CBSY) != 0) { + emmc_write_error_info(EMMC_FUNCNO_SET_CLOCK, + EMMC_ERR_CARD_BUSY); + return EMMC_ERR; + } + + set_sd_clk(*freq); + mmc_drv_obj.clock_enable = FALSE; + + return emmc_clock_ctrl(TRUE); /* clock on */ +} + +EMMC_ERROR_CODE rcar_emmc_mount(void) +{ + EMMC_ERROR_CODE result; + + /* state check */ + if ((mmc_drv_obj.initialize != TRUE) + || (mmc_drv_obj.card_power_enable != TRUE) + || ((GETR_32(SD_INFO2) & SD_INFO2_CBSY) != 0) + ) { + emmc_write_error_info(EMMC_FUNCNO_MOUNT, EMMC_ERR_STATE); + return EMMC_ERR_STATE; + } + + /* initialize card (IDLE state --> Transfer state) */ + result = emmc_card_init(); + if (result != EMMC_SUCCESS) { + emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT); + if (emmc_clock_ctrl(FALSE) != EMMC_SUCCESS) { + /* nothing to do. */ + } + return result; + } + + /* Switching high speed mode */ + result = emmc_high_speed(); + if (result != EMMC_SUCCESS) { + emmc_write_error_info_func_no(EMMC_FUNCNO_HIGH_SPEED); + if (emmc_clock_ctrl(FALSE) != EMMC_SUCCESS) { + /* nothing to do. */ + } + return result; + } + + /* Changing the data bus width */ + result = emmc_bus_width(8); + if (result != EMMC_SUCCESS) { + emmc_write_error_info_func_no(EMMC_FUNCNO_BUS_WIDTH); + if (emmc_clock_ctrl(FALSE) != EMMC_SUCCESS) { + /* nothing to do. */ + } + return result; + } + + /* mount complete */ + mmc_drv_obj.mount = TRUE; + + return EMMC_SUCCESS; +} diff --git a/drivers/renesas/common/emmc/emmc_read.c b/drivers/renesas/common/emmc/emmc_read.c new file mode 100644 index 000000000..96e73ca56 --- /dev/null +++ b/drivers/renesas/common/emmc/emmc_read.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include "emmc_config.h" +#include "emmc_def.h" +#include "emmc_hal.h" +#include "emmc_registers.h" +#include "emmc_std.h" + +#define MIN_EMMC(a, b) (((a) < (b)) ? (a) : (b)) +#define EMMC_RW_SECTOR_COUNT_MAX 0x0000ffffU + +static EMMC_ERROR_CODE emmc_multiple_block_read(uint32_t *buff_address_virtual, + uint32_t sector_number, uint32_t count, + HAL_MEMCARD_DATA_TRANSFER_MODE transfer_mode) +{ + EMMC_ERROR_CODE result; + + /* parameter check */ + if ((count > EMMC_RW_SECTOR_COUNT_MAX) + || (count == 0) + || ((transfer_mode != HAL_MEMCARD_DMA) + && (transfer_mode != HAL_MEMCARD_NOT_DMA)) + ) { + emmc_write_error_info(EMMC_FUNCNO_READ_SECTOR, EMMC_ERR_PARAM); + return EMMC_ERR_PARAM; + } + + /* CMD23 */ + emmc_make_nontrans_cmd(CMD23_SET_BLOCK_COUNT, count); + result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); + if (result != EMMC_SUCCESS) { + return result; + } + SETR_32(SD_SECCNT, count); + SETR_32(SD_STOP, 0x00000100); + /* SD_BUF Read/Write DMA Transfer enable */ + SETR_32(CC_EXT_MODE, (CC_EXT_MODE_CLEAR | CC_EXT_MODE_DMASDRW_ENABLE)); + + /* CMD18 */ + emmc_make_trans_cmd(CMD18_READ_MULTIPLE_BLOCK, sector_number, + buff_address_virtual, + count << EMMC_SECTOR_SIZE_SHIFT, HAL_MEMCARD_READ, + transfer_mode); + result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); + if (result != EMMC_SUCCESS) { + return result; /* CMD18 error code */ + } + + /* CMD13 */ + emmc_make_nontrans_cmd(CMD13_SEND_STATUS, EMMC_RCA << 16); + result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); + if (result != EMMC_SUCCESS) { + return result; + } +#if RCAR_BL2_DCACHE == 1 + if (transfer_mode == HAL_MEMCARD_NOT_DMA) { + flush_dcache_range((uint64_t) buff_address_virtual, + ((size_t) count << EMMC_SECTOR_SIZE_SHIFT)); + } +#endif /* RCAR_BL2_DCACHE == 1 */ + + /* ready status check */ + if ((mmc_drv_obj.r1_card_status & EMMC_R1_READY) == 0) { + emmc_write_error_info(EMMC_FUNCNO_READ_SECTOR, + EMMC_ERR_CARD_BUSY); + return EMMC_ERR_CARD_BUSY; + } + + /* state check */ + if (mmc_drv_obj.current_state != EMMC_R1_STATE_TRAN) { + emmc_write_error_info(EMMC_FUNCNO_READ_SECTOR, + EMMC_ERR_CARD_STATE); + return EMMC_ERR_CARD_STATE; + } + + return EMMC_SUCCESS; +} + +EMMC_ERROR_CODE emmc_read_sector(uint32_t *buff_address_virtual, + uint32_t sector_number, + uint32_t count, uint32_t feature_flags) +{ + uint32_t trans_count; + uint32_t remain; + EMMC_ERROR_CODE result; + HAL_MEMCARD_DATA_TRANSFER_MODE transfer_mode; + + /* parameter check */ + if (count == 0) { + emmc_write_error_info(EMMC_FUNCNO_READ_SECTOR, EMMC_ERR_PARAM); + return EMMC_ERR_PARAM; + } + + /* state check */ + if (mmc_drv_obj.mount != TRUE) { + emmc_write_error_info(EMMC_FUNCNO_READ_SECTOR, EMMC_ERR_STATE); + return EMMC_ERR_STATE; + } + + /* DMA? */ + if ((feature_flags & LOADIMAGE_FLAGS_DMA_ENABLE) != 0) { + transfer_mode = HAL_MEMCARD_DMA; + } else { + transfer_mode = HAL_MEMCARD_NOT_DMA; + } + + remain = count; + while (remain != 0) { + trans_count = MIN_EMMC(remain, EMMC_RW_SECTOR_COUNT_MAX); + result = + emmc_multiple_block_read(buff_address_virtual, + sector_number, trans_count, + transfer_mode); + if (result != EMMC_SUCCESS) { + return result; + } + + buff_address_virtual += (EMMC_BLOCK_LENGTH_DW * trans_count); + sector_number += trans_count; + remain -= trans_count; + } + + return EMMC_SUCCESS; +} diff --git a/drivers/renesas/common/emmc/emmc_registers.h b/drivers/renesas/common/emmc/emmc_registers.h new file mode 100644 index 000000000..ae689ca24 --- /dev/null +++ b/drivers/renesas/common/emmc/emmc_registers.h @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef EMMC_REGISTERS_H +#define EMMC_REGISTERS_H + +/* MMC channel select */ +#define MMC_CH0 (0U) /* SDHI2/MMC0 */ +#define MMC_CH1 (1U) /* SDHI3/MMC1 */ + +#if RCAR_LSI == RCAR_E3 +#define USE_MMC_CH (MMC_CH1) /* R-Car E3 */ +#else /* RCAR_LSI == RCAR_E3 */ +#define USE_MMC_CH (MMC_CH0) /* R-Car H3/M3/M3N */ +#endif /* RCAR_LSI == RCAR_E3 */ + +#define BIT0 (0x00000001U) +#define BIT1 (0x00000002U) +#define BIT2 (0x00000004U) +#define BIT3 (0x00000008U) +#define BIT4 (0x00000010U) +#define BIT5 (0x00000020U) +#define BIT6 (0x00000040U) +#define BIT7 (0x00000080U) +#define BIT8 (0x00000100U) +#define BIT9 (0x00000200U) +#define BIT10 (0x00000400U) +#define BIT11 (0x00000800U) +#define BIT12 (0x00001000U) +#define BIT13 (0x00002000U) +#define BIT14 (0x00004000U) +#define BIT15 (0x00008000U) +#define BIT16 (0x00010000U) +#define BIT17 (0x00020000U) +#define BIT18 (0x00040000U) +#define BIT19 (0x00080000U) +#define BIT20 (0x00100000U) +#define BIT21 (0x00200000U) +#define BIT22 (0x00400000U) +#define BIT23 (0x00800000U) +#define BIT24 (0x01000000U) +#define BIT25 (0x02000000U) +#define BIT26 (0x04000000U) +#define BIT27 (0x08000000U) +#define BIT28 (0x10000000U) +#define BIT29 (0x20000000U) +#define BIT30 (0x40000000U) +#define BIT31 (0x80000000U) + +/* Clock Pulse Generator (CPG) registers */ +#define CPG_BASE (0xE6150000U) +/* Module stop status register 3 */ +#define CPG_MSTPSR3 (CPG_BASE + 0x0048U) +/* System module stop control register 3 */ +#define CPG_SMSTPCR3 (CPG_BASE + 0x013CU) +/* SDHI2 clock frequency control register */ +#define CPG_SD2CKCR (CPG_BASE + 0x0268U) +/* SDHI3 clock frequency control register */ +#define CPG_SD3CKCR (CPG_BASE + 0x026CU) +/* CPG Write Protect Register */ +#define CPG_CPGWPR (CPG_BASE + 0x0900U) + +#if USE_MMC_CH == MMC_CH0 +#define CPG_SDxCKCR (CPG_SD2CKCR) /* SDHI2/MMC0 */ +#else /* USE_MMC_CH == MMC_CH0 */ +#define CPG_SDxCKCR (CPG_SD3CKCR) /* SDHI3/MMC1 */ +#endif /* USE_MMC_CH == MMC_CH0 */ + +/* Boot Status register */ +#define MFISBTSTSR (0xE6260604U) + +#define MFISBTSTSR_BOOT_PARTITION (0x00000010U) + +/* eMMC registers */ +#define MMC0_SD_BASE (0xEE140000U) +#define MMC1_SD_BASE (0xEE160000U) + +#if USE_MMC_CH == MMC_CH0 +#define MMC_SD_BASE (MMC0_SD_BASE) +#else /* USE_MMC_CH == MMC_CH0 */ +#define MMC_SD_BASE (MMC1_SD_BASE) +#endif /* USE_MMC_CH == MMC_CH0 */ + +#define SD_CMD (MMC_SD_BASE + 0x0000U) +#define SD_PORTSEL (MMC_SD_BASE + 0x0008U) +#define SD_ARG (MMC_SD_BASE + 0x0010U) +#define SD_ARG1 (MMC_SD_BASE + 0x0018U) +#define SD_STOP (MMC_SD_BASE + 0x0020U) +#define SD_SECCNT (MMC_SD_BASE + 0x0028U) +#define SD_RSP10 (MMC_SD_BASE + 0x0030U) +#define SD_RSP1 (MMC_SD_BASE + 0x0038U) +#define SD_RSP32 (MMC_SD_BASE + 0x0040U) +#define SD_RSP3 (MMC_SD_BASE + 0x0048U) +#define SD_RSP54 (MMC_SD_BASE + 0x0050U) +#define SD_RSP5 (MMC_SD_BASE + 0x0058U) +#define SD_RSP76 (MMC_SD_BASE + 0x0060U) +#define SD_RSP7 (MMC_SD_BASE + 0x0068U) +#define SD_INFO1 (MMC_SD_BASE + 0x0070U) +#define SD_INFO2 (MMC_SD_BASE + 0x0078U) +#define SD_INFO1_MASK (MMC_SD_BASE + 0x0080U) +#define SD_INFO2_MASK (MMC_SD_BASE + 0x0088U) +#define SD_CLK_CTRL (MMC_SD_BASE + 0x0090U) +#define SD_SIZE (MMC_SD_BASE + 0x0098U) +#define SD_OPTION (MMC_SD_BASE + 0x00A0U) +#define SD_ERR_STS1 (MMC_SD_BASE + 0x00B0U) +#define SD_ERR_STS2 (MMC_SD_BASE + 0x00B8U) +#define SD_BUF0 (MMC_SD_BASE + 0x00C0U) +#define SDIO_MODE (MMC_SD_BASE + 0x00D0U) +#define SDIO_INFO1 (MMC_SD_BASE + 0x00D8U) +#define SDIO_INFO1_MASK (MMC_SD_BASE + 0x00E0U) +#define CC_EXT_MODE (MMC_SD_BASE + 0x0360U) +#define SOFT_RST (MMC_SD_BASE + 0x0380U) +#define VERSION (MMC_SD_BASE + 0x0388U) +#define HOST_MODE (MMC_SD_BASE + 0x0390U) +#define DM_CM_DTRAN_MODE (MMC_SD_BASE + 0x0820U) +#define DM_CM_DTRAN_CTRL (MMC_SD_BASE + 0x0828U) +#define DM_CM_RST (MMC_SD_BASE + 0x0830U) +#define DM_CM_INFO1 (MMC_SD_BASE + 0x0840U) +#define DM_CM_INFO1_MASK (MMC_SD_BASE + 0x0848U) +#define DM_CM_INFO2 (MMC_SD_BASE + 0x0850U) +#define DM_CM_INFO2_MASK (MMC_SD_BASE + 0x0858U) +#define DM_DTRAN_ADDR (MMC_SD_BASE + 0x0880U) + +/* SD_INFO1 Registers */ +#define SD_INFO1_HPIRES 0x00010000UL /* Response Reception Completion */ +#define SD_INFO1_INFO10 0x00000400UL /* Indicates the SDDAT3 state */ +#define SD_INFO1_INFO9 0x00000200UL /* SDDAT3 Card Insertion */ +#define SD_INFO1_INFO8 0x00000100UL /* SDDAT3 Card Removal */ +#define SD_INFO1_INFO7 0x00000080UL /* Write Protect */ +#define SD_INFO1_INFO5 0x00000020UL /* Indicates the ISDCD state */ +#define SD_INFO1_INFO4 0x00000010UL /* ISDCD Card Insertion */ +#define SD_INFO1_INFO3 0x00000008UL /* ISDCD Card Removal */ +#define SD_INFO1_INFO2 0x00000004UL /* Access end */ +#define SD_INFO1_INFO0 0x00000001UL /* Response end */ + +/* SD_INFO2 Registers */ +#define SD_INFO2_ILA 0x00008000UL /* Illegal Access Error */ +#define SD_INFO2_CBSY 0x00004000UL /* Command Type Register Busy */ +#define SD_INFO2_SCLKDIVEN 0x00002000UL +#define SD_INFO2_BWE 0x00000200UL /* SD_BUF Write Enable */ +#define SD_INFO2_BRE 0x00000100UL /* SD_BUF Read Enable */ +#define SD_INFO2_DAT0 0x00000080UL /* SDDAT0 */ +#define SD_INFO2_ERR6 0x00000040UL /* Response Timeout */ +#define SD_INFO2_ERR5 0x00000020UL /* SD_BUF Illegal Read Access */ +#define SD_INFO2_ERR4 0x00000010UL /* SD_BUF Illegal Write Access */ +#define SD_INFO2_ERR3 0x00000008UL /* Data Timeout */ +#define SD_INFO2_ERR2 0x00000004UL /* END Error */ +#define SD_INFO2_ERR1 0x00000002UL /* CRC Error */ +#define SD_INFO2_ERR0 0x00000001UL /* CMD Error */ +#define SD_INFO2_ALL_ERR 0x0000807FUL +#define SD_INFO2_CLEAR 0x00000800UL /* BIT11 write value should always be 1. HWM_0003 */ + +/* SOFT_RST */ +#define SOFT_RST_SDRST 0x00000001UL + +/* SD_CLK_CTRL */ +#define SD_CLK_CTRL_SDCLKOFFEN 0x00000200UL +#define SD_CLK_CTRL_SCLKEN 0x00000100UL +#define SD_CLK_CTRL_CLKDIV_MASK 0x000000FFUL +#define SD_CLOCK_ENABLE 0x00000100UL +#define SD_CLOCK_DISABLE 0x00000000UL +#define SD_CLK_WRITE_MASK 0x000003FFUL +#define SD_CLK_CLKDIV_CLEAR_MASK 0xFFFFFF0FUL + +/* SD_OPTION */ +#define SD_OPTION_TIMEOUT_CNT_MASK 0x000000F0UL + +/* + * MMC Clock Frequency + * 200MHz * 1/x = output clock + */ +#define MMC_CLK_OFF 0UL /* Clock output is disabled */ +#define MMC_400KHZ 512UL /* 200MHz * 1/512 = 390 KHz */ +#define MMC_20MHZ 16UL /* 200MHz * 1/16 = 12.5 MHz Normal speed mode */ +#define MMC_26MHZ 8UL /* 200MHz * 1/8 = 25 MHz HS mode 26Mhz */ +#define MMC_52MHZ 4UL /* 200MHz * 1/4 = 50 MHz HS mode 52Mhz */ +#define MMC_100MHZ 2UL /* 200MHz * 1/2 = 100 MHz */ +#define MMC_200MHZ 1UL /* 200MHz * 1/1 = 200 MHz */ + +#define MMC_FREQ_52MHZ 52000000UL +#define MMC_FREQ_26MHZ 26000000UL +#define MMC_FREQ_20MHZ 20000000UL + +/* MMC Clock DIV */ +#define MMC_SD_CLK_START 0x00000100UL /* CLOCK On */ +#define MMC_SD_CLK_STOP (~0x00000100UL) /* CLOCK stop */ +#define MMC_SD_CLK_DIV1 0x000000FFUL /* 1/1 */ +#define MMC_SD_CLK_DIV2 0x00000000UL /* 1/2 */ +#define MMC_SD_CLK_DIV4 0x00000001UL /* 1/4 */ +#define MMC_SD_CLK_DIV8 0x00000002UL /* 1/8 */ +#define MMC_SD_CLK_DIV16 0x00000004UL /* 1/16 */ +#define MMC_SD_CLK_DIV32 0x00000008UL /* 1/32 */ +#define MMC_SD_CLK_DIV64 0x00000010UL /* 1/64 */ +#define MMC_SD_CLK_DIV128 0x00000020UL /* 1/128 */ +#define MMC_SD_CLK_DIV256 0x00000040UL /* 1/256 */ +#define MMC_SD_CLK_DIV512 0x00000080UL /* 1/512 */ + +/* DM_CM_DTRAN_MODE */ +#define DM_CM_DTRAN_MODE_CH0 0x00000000UL /* CH0(downstream) */ +#define DM_CM_DTRAN_MODE_CH1 0x00010000UL /* CH1(upstream) */ +#define DM_CM_DTRAN_MODE_BIT_WIDTH 0x00000030UL + +/* CC_EXT_MODE */ +#define CC_EXT_MODE_DMASDRW_ENABLE 0x00000002UL /* SD_BUF Read/Write DMA Transfer */ +#define CC_EXT_MODE_CLEAR 0x00001010UL /* BIT 12 & 4 always 1. */ + +/* DM_CM_INFO_MASK */ +#define DM_CM_INFO_MASK_CLEAR 0xFFFCFFFEUL +#define DM_CM_INFO_CH0_ENABLE 0x00010001UL +#define DM_CM_INFO_CH1_ENABLE 0x00020001UL + +/* DM_DTRAN_ADDR */ +#define DM_DTRAN_ADDR_WRITE_MASK 0xFFFFFFF8UL + +/* DM_CM_DTRAN_CTRL */ +#define DM_CM_DTRAN_CTRL_START 0x00000001UL + +/* SYSC Registers */ +#if USE_MMC_CH == MMC_CH0 +#define CPG_MSTP_MMC (BIT12) /* SDHI2/MMC0 */ +#else /* USE_MMC_CH == MMC_CH0 */ +#define CPG_MSTP_MMC (BIT11) /* SDHI3/MMC1 */ +#endif /* USE_MMC_CH == MMC_CH0 */ + +#endif /* EMMC_REGISTERS_H */ diff --git a/drivers/renesas/common/emmc/emmc_std.h b/drivers/renesas/common/emmc/emmc_std.h new file mode 100644 index 000000000..087c6e91d --- /dev/null +++ b/drivers/renesas/common/emmc/emmc_std.h @@ -0,0 +1,475 @@ +/* + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef EMMC_STD_H +#define EMMC_STD_H + +#include "emmc_hal.h" + +#ifndef FALSE +#define FALSE 0U +#endif +#ifndef TRUE +#define TRUE 1U +#endif + +/* 64bit registers */ +#define SETR_64(r, v) (*(volatile uint64_t *)(r) = (v)) +#define GETR_64(r) (*(volatile uint64_t *)(r)) + +/* 32bit registers */ +#define SETR_32(r, v) (*(volatile uint32_t *)(r) = (v)) +#define GETR_32(r) (*(volatile uint32_t *)(r)) + +/* 16bit registers */ +#define SETR_16(r, v) (*(volatile uint16_t *)(r) = (v)) +#define GETR_16(r) (*(volatile uint16_t *)(r)) + +/* 8bit registers */ +#define SETR_8(r, v) (*(volatile uint8_t *)(r) = (v)) +#define GETR_8(r) (*(volatile uint8_t *)(r)) + +/* CSD register Macros */ +#define EMMC_GET_CID(x, y) (emmc_bit_field(mmc_drv_obj.cid_data, (x), (y))) + +#define EMMC_CID_MID() (EMMC_GET_CID(127, 120)) +#define EMMC_CID_CBX() (EMMC_GET_CID(113, 112)) +#define EMMC_CID_OID() (EMMC_GET_CID(111, 104)) +#define EMMC_CID_PNM1() (EMMC_GET_CID(103, 88)) +#define EMMC_CID_PNM2() (EMMC_GET_CID(87, 56)) +#define EMMC_CID_PRV() (EMMC_GET_CID(55, 48)) +#define EMMC_CID_PSN() (EMMC_GET_CID(47, 16)) +#define EMMC_CID_MDT() (EMMC_GET_CID(15, 8)) +#define EMMC_CID_CRC() (EMMC_GET_CID(7, 1)) + +/* CSD register Macros */ +#define EMMC_GET_CSD(x, y) (emmc_bit_field(mmc_drv_obj.csd_data, (x), (y))) + +#define EMMC_CSD_CSD_STRUCTURE() (EMMC_GET_CSD(127, 126)) +#define EMMC_CSD_SPEC_VARS() (EMMC_GET_CSD(125, 122)) +#define EMMC_CSD_TAAC() (EMMC_GET_CSD(119, 112)) +#define EMMC_CSD_NSAC() (EMMC_GET_CSD(111, 104)) +#define EMMC_CSD_TRAN_SPEED() (EMMC_GET_CSD(103, 96)) +#define EMMC_CSD_CCC() (EMMC_GET_CSD(95, 84)) +#define EMMC_CSD_READ_BL_LEN() (EMMC_GET_CSD(83, 80)) +#define EMMC_CSD_READ_BL_PARTIAL() (EMMC_GET_CSD(79, 79)) +#define EMMC_CSD_WRITE_BLK_MISALIGN() (EMMC_GET_CSD(78, 78)) +#define EMMC_CSD_READ_BLK_MISALIGN() (EMMC_GET_CSD(77, 77)) +#define EMMC_CSD_DSR_IMP() (EMMC_GET_CSD(76, 76)) +#define EMMC_CSD_C_SIZE() (EMMC_GET_CSD(73, 62)) +#define EMMC_CSD_VDD_R_CURR_MIN() (EMMC_GET_CSD(61, 59)) +#define EMMC_CSD_VDD_R_CURR_MAX() (EMMC_GET_CSD(58, 56)) +#define EMMC_CSD_VDD_W_CURR_MIN() (EMMC_GET_CSD(55, 53)) +#define EMMC_CSD_VDD_W_CURR_MAX() (EMMC_GET_CSD(52, 50)) +#define EMMC_CSD_C_SIZE_MULT() (EMMC_GET_CSD(49, 47)) +#define EMMC_CSD_ERASE_GRP_SIZE() (EMMC_GET_CSD(46, 42)) +#define EMMC_CSD_ERASE_GRP_MULT() (EMMC_GET_CSD(41, 37)) +#define EMMC_CSD_WP_GRP_SIZE() (EMMC_GET_CSD(36, 32)) +#define EMMC_CSD_WP_GRP_ENABLE() (EMMC_GET_CSD(31, 31)) +#define EMMC_CSD_DEFALT_ECC() (EMMC_GET_CSD(30, 29)) +#define EMMC_CSD_R2W_FACTOR() (EMMC_GET_CSD(28, 26)) +#define EMMC_CSD_WRITE_BL_LEN() (EMMC_GET_CSD(25, 22)) +#define EMMC_CSD_WRITE_BL_PARTIAL() (EMMC_GET_CSD(21, 21)) +#define EMMC_CSD_CONTENT_PROT_APP() (EMMC_GET_CSD(16, 16)) +#define EMMC_CSD_FILE_FORMAT_GRP() (EMMC_GET_CSD(15, 15)) +#define EMMC_CSD_COPY() (EMMC_GET_CSD(14, 14)) +#define EMMC_CSD_PERM_WRITE_PROTECT() (EMMC_GET_CSD(13, 13)) +#define EMMC_CSD_TMP_WRITE_PROTECT() (EMMC_GET_CSD(12, 12)) +#define EMMC_CSD_FILE_FORMAT() (EMMC_GET_CSD(11, 10)) +#define EMMC_CSD_ECC() (EMMC_GET_CSD(9, 8)) +#define EMMC_CSD_CRC() (EMMC_GET_CSD(7, 1)) + +/* sector access */ +#define EMMC_4B_BOUNDARY_CHECK_MASK 0x00000003 +#define EMMC_SECTOR_SIZE_SHIFT 9U /* 512 = 2^9 */ +#define EMMC_SECTOR_SIZE 512 +#define EMMC_BLOCK_LENGTH 512 +#define EMMC_BLOCK_LENGTH_DW 128 +#define EMMC_BUF_SIZE_SHIFT 3U /* 8byte = 2^3 */ + +/* eMMC specification clock */ +#define EMMC_CLOCK_SPEC_400K 400000UL /* initialize clock 400KHz */ +#define EMMC_CLOCK_SPEC_20M 20000000UL /* normal speed 20MHz */ +#define EMMC_CLOCK_SPEC_26M 26000000UL /* high speed 26MHz */ +#define EMMC_CLOCK_SPEC_52M 52000000UL /* high speed 52MHz */ +#define EMMC_CLOCK_SPEC_100M 100000000UL /* high speed 100MHz */ + +/* EMMC driver error code. (extended HAL_MEMCARD_RETURN) */ +typedef enum { + EMMC_ERR = 0, /* unknown error */ + EMMC_SUCCESS, /* OK */ + EMMC_ERR_FROM_DMAC, /* DMAC allocation error */ + EMMC_ERR_FROM_DMAC_TRANSFER, /* DMAC transfer error */ + EMMC_ERR_CARD_STATUS_BIT, /* card status error */ + EMMC_ERR_CMD_TIMEOUT, /* command timeout error */ + EMMC_ERR_DATA_TIMEOUT, /* data timeout error */ + EMMC_ERR_CMD_CRC, /* command CRC error */ + EMMC_ERR_DATA_CRC, /* data CRC error */ + EMMC_ERR_PARAM, /* parameter error */ + EMMC_ERR_RESPONSE, /* response error */ + EMMC_ERR_RESPONSE_BUSY, /* response busy error */ + EMMC_ERR_TRANSFER, /* data transfer error */ + EMMC_ERR_READ_SECTOR, /* read sector error */ + EMMC_ERR_WRITE_SECTOR, /* write sector error */ + EMMC_ERR_STATE, /* state error */ + EMMC_ERR_TIMEOUT, /* timeout error */ + EMMC_ERR_ILLEGAL_CARD, /* illegal card */ + EMMC_ERR_CARD_BUSY, /* Busy state */ + EMMC_ERR_CARD_STATE, /* card state error */ + EMMC_ERR_SET_TRACE, /* trace information error */ + EMMC_ERR_FROM_TIMER, /* Timer error */ + EMMC_ERR_FORCE_TERMINATE, /* Force terminate */ + EMMC_ERR_CARD_POWER, /* card power fail */ + EMMC_ERR_ERASE_SECTOR, /* erase sector error */ + EMMC_ERR_INFO2 /* exec cmd error info2 */ +} EMMC_ERROR_CODE; + +/* Function number */ +#define EMMC_FUNCNO_NONE 0U +#define EMMC_FUNCNO_DRIVER_INIT 1U +#define EMMC_FUNCNO_CARD_POWER_ON 2U +#define EMMC_FUNCNO_MOUNT 3U +#define EMMC_FUNCNO_CARD_INIT 4U +#define EMMC_FUNCNO_HIGH_SPEED 5U +#define EMMC_FUNCNO_BUS_WIDTH 6U +#define EMMC_FUNCNO_MULTI_BOOT_SELECT_PARTITION 7U +#define EMMC_FUNCNO_MULTI_BOOT_READ_SECTOR 8U +#define EMMC_FUNCNO_TRANS_DATA_READ_SECTOR 9U +#define EMMC_FUNCNO_UBOOT_IMAGE_SELECT_PARTITION 10U +#define EMMC_FUNCNO_UBOOT_IMAGE_READ_SECTOR 11U +#define EMMC_FUNCNO_SET_CLOCK 12U +#define EMMC_FUNCNO_EXEC_CMD 13U +#define EMMC_FUNCNO_READ_SECTOR 14U +#define EMMC_FUNCNO_WRITE_SECTOR 15U +#define EMMC_FUNCNO_ERASE_SECTOR 16U +#define EMMC_FUNCNO_GET_PERTITION_ACCESS 17U +/* + * Response + * R1 + * Type 'E' bit and bit14(must be 0). ignore bit22 + */ +#define EMMC_R1_ERROR_MASK 0xFDBFE080U +/* Ignore bit23 (Not check CRC error) */ +#define EMMC_R1_ERROR_MASK_WITHOUT_CRC (0xFD3FE080U) +#define EMMC_R1_STATE_MASK 0x00001E00U /* [12:9] */ +#define EMMC_R1_READY 0x00000100U /* bit8 */ +#define EMMC_R1_STATE_SHIFT 9 + +/* R4 */ +#define EMMC_R4_RCA_MASK 0xFFFF0000UL +#define EMMC_R4_STATUS 0x00008000UL + +/* CSD */ +#define EMMC_TRANSPEED_FREQ_UNIT_MASK 0x07 /* bit[2:0] */ +#define EMMC_TRANSPEED_FREQ_UNIT_SHIFT 0 +#define EMMC_TRANSPEED_MULT_MASK 0x78 /* bit[6:3] */ +#define EMMC_TRANSPEED_MULT_SHIFT 3 + +/* OCR */ +#define EMMC_HOST_OCR_VALUE 0x40FF8080 +#define EMMC_OCR_STATUS_BIT 0x80000000L /* Card power up status bit */ +#define EMMC_OCR_ACCESS_MODE_MASK 0x60000000L /* bit[30:29] */ +#define EMMC_OCR_ACCESS_MODE_SECT 0x40000000L +#define EMMC_OCR_ACCESS_MODE_BYTE 0x00000000L + +/* EXT_CSD */ +#define EMMC_EXT_CSD_S_CMD_SET 504 +#define EMMC_EXT_CSD_INI_TIMEOUT_AP 241 +#define EMMC_EXT_CSD_PWR_CL_DDR_52_360 239 +#define EMMC_EXT_CSD_PWR_CL_DDR_52_195 238 +#define EMMC_EXT_CSD_MIN_PERF_DDR_W_8_52 235 +#define EMMC_EXT_CSD_MIN_PERF_DDR_R_8_52 234 +#define EMMC_EXT_CSD_TRIM_MULT 232 +#define EMMC_EXT_CSD_SEC_FEATURE_SUPPORT 231 +#define EMMC_EXT_CSD_SEC_ERASE_MULT 229 +#define EMMC_EXT_CSD_BOOT_INFO 228 +#define EMMC_EXT_CSD_BOOT_SIZE_MULTI 226 +#define EMMC_EXT_CSD_ACC_SIZE 225 +#define EMMC_EXT_CSD_HC_ERASE_GRP_SIZE 224 +#define EMMC_EXT_CSD_ERASE_TIMEOUT_MULT 223 +#define EMMC_EXT_CSD_PEL_WR_SEC_C 222 +#define EMMC_EXT_CSD_HC_WP_GRP_SIZE 221 +#define EMMC_EXT_CSD_S_C_VCC 220 +#define EMMC_EXT_CSD_S_C_VCCQ 219 +#define EMMC_EXT_CSD_S_A_TIMEOUT 217 +#define EMMC_EXT_CSD_SEC_COUNT 215 +#define EMMC_EXT_CSD_MIN_PERF_W_8_52 210 +#define EMMC_EXT_CSD_MIN_PERF_R_8_52 209 +#define EMMC_EXT_CSD_MIN_PERF_W_8_26_4_52 208 +#define EMMC_EXT_CSD_MIN_PERF_R_8_26_4_52 207 +#define EMMC_EXT_CSD_MIN_PERF_W_4_26 206 +#define EMMC_EXT_CSD_MIN_PERF_R_4_26 205 +#define EMMC_EXT_CSD_PWR_CL_26_360 203 +#define EMMC_EXT_CSD_PWR_CL_52_360 202 +#define EMMC_EXT_CSD_PWR_CL_26_195 201 +#define EMMC_EXT_CSD_PWR_CL_52_195 200 +#define EMMC_EXT_CSD_CARD_TYPE 196 +#define EMMC_EXT_CSD_CSD_STRUCTURE 194 +#define EMMC_EXT_CSD_EXT_CSD_REV 192 +#define EMMC_EXT_CSD_CMD_SET 191 +#define EMMC_EXT_CSD_CMD_SET_REV 189 +#define EMMC_EXT_CSD_POWER_CLASS 187 +#define EMMC_EXT_CSD_HS_TIMING 185 +#define EMMC_EXT_CSD_BUS_WIDTH 183 +#define EMMC_EXT_CSD_ERASED_MEM_CONT 181 +#define EMMC_EXT_CSD_PARTITION_CONFIG 179 +#define EMMC_EXT_CSD_BOOT_CONFIG_PROT 178 +#define EMMC_EXT_CSD_BOOT_BUS_WIDTH 177 +#define EMMC_EXT_CSD_ERASE_GROUP_DEF 175 +#define EMMC_EXT_CSD_BOOT_WP 173 +#define EMMC_EXT_CSD_USER_WP 171 +#define EMMC_EXT_CSD_FW_CONFIG 169 +#define EMMC_EXT_CSD_RPMB_SIZE_MULT 168 +#define EMMC_EXT_CSD_RST_n_FUNCTION 162 +#define EMMC_EXT_CSD_PARTITIONING_SUPPORT 160 +#define EMMC_EXT_CSD_MAX_ENH_SIZE_MULT 159 +#define EMMC_EXT_CSD_PARTITIONS_ATTRIBUTE 156 +#define EMMC_EXT_CSD_PARTITION_SETTING_COMPLETED 155 +#define EMMC_EXT_CSD_GP_SIZE_MULT 154 +#define EMMC_EXT_CSD_ENH_SIZE_MULT 142 +#define EMMC_EXT_CSD_ENH_START_ADDR 139 +#define EMMC_EXT_CSD_SEC_BAD_BLK_MGMNT 134 + +#define EMMC_EXT_CSD_CARD_TYPE_26MHZ 0x01 +#define EMMC_EXT_CSD_CARD_TYPE_52MHZ 0x02 +#define EMMC_EXT_CSD_CARD_TYPE_DDR_52MHZ_12V 0x04 +#define EMMC_EXT_CSD_CARD_TYPE_DDR_52MHZ_18V 0x08 +#define EMMC_EXT_CSD_CARD_TYPE_52MHZ_MASK 0x0e + +/* SWITCH (CMD6) argument */ +#define EXTCSD_ACCESS_BYTE (BIT25 | BIT24) +#define EXTCSD_SET_BITS BIT24 + +#define HS_TIMING_ADD (185 << 16) /* H'b9 */ +#define HS_TIMING_1 (1 << 8) +#define HS_TIMING_HS200 (2 << 8) +#define HS_TIMING_HS400 (3 << 8) + +#define BUS_WIDTH_ADD (183 << 16) /* H'b7 */ +#define BUS_WIDTH_1 (0 << 8) +#define BUS_WIDTH_4 (1 << 8) +#define BUS_WIDTH_8 (2 << 8) +#define BUS_WIDTH_4DDR (5 << 8) +#define BUS_WIDTH_8DDR (6 << 8) + +#define EMMC_SWITCH_HS_TIMING (EXTCSD_ACCESS_BYTE | HS_TIMING_ADD |\ + HS_TIMING_1) /* H'03b90100 */ +#define EMMC_SWITCH_HS_TIMING_OFF (EXTCSD_ACCESS_BYTE |\ + HS_TIMING_ADD) /* H'03b90000 */ + +#define EMMC_SWITCH_BUS_WIDTH_1 (EXTCSD_ACCESS_BYTE | BUS_WIDTH_ADD |\ + BUS_WIDTH_1) /* H'03b70000 */ +#define EMMC_SWITCH_BUS_WIDTH_4 (EXTCSD_ACCESS_BYTE | BUS_WIDTH_ADD |\ + BUS_WIDTH_4) /* H'03b70100 */ +#define EMMC_SWITCH_BUS_WIDTH_8 (EXTCSD_ACCESS_BYTE | BUS_WIDTH_ADD |\ + BUS_WIDTH_8) /* H'03b70200 */ +#define EMMC_SWITCH_BUS_WIDTH_4DDR (EXTCSD_ACCESS_BYTE | BUS_WIDTH_ADD |\ + BUS_WIDTH_4DDR) /* H'03b70500 */ +#define EMMC_SWITCH_BUS_WIDTH_8DDR (EXTCSD_ACCESS_BYTE | BUS_WIDTH_ADD |\ + BUS_WIDTH_8DDR) /* H'03b70600 */ +/* Partition config = 0x00 */ +#define EMMC_SWITCH_PARTITION_CONFIG 0x03B30000UL + +#define TIMING_HIGH_SPEED 1UL +#define EMMC_BOOT_PARTITION_EN_MASK 0x38U +#define EMMC_BOOT_PARTITION_EN_SHIFT 3U + +/* Bus width */ +#define EMMC_BUSWIDTH_1BIT CE_CMD_SET_DATW_1BIT +#define EMMC_BUSWIDTH_4BIT CE_CMD_SET_DATW_4BIT +#define EMMC_BUSWIDTH_8BIT CE_CMD_SET_DATW_8BIT + +/* for st_mmc_base */ +#define EMMC_MAX_RESPONSE_LENGTH 17 +#define EMMC_MAX_CID_LENGTH 16 +#define EMMC_MAX_CSD_LENGTH 16 +#define EMMC_MAX_EXT_CSD_LENGTH 512U +#define EMMC_RES_REG_ALIGNED 4U +#define EMMC_BUF_REG_ALIGNED 8U + +/* TAAC mask */ +#define TAAC_TIME_UNIT_MASK (0x07) +#define TAAC_MULTIPLIER_FACTOR_MASK (0x0F) + +/* Partition id */ +typedef enum { + PARTITION_ID_USER = 0x0, /* User Area */ + PARTITION_ID_BOOT_1 = 0x1, /* boot partition 1 */ + PARTITION_ID_BOOT_2 = 0x2, /* boot partition 2 */ + PARTITION_ID_RPMB = 0x3, /* Replay Protected Memory Block */ + PARTITION_ID_GP_1 = 0x4, /* General Purpose partition 1 */ + PARTITION_ID_GP_2 = 0x5, /* General Purpose partition 2 */ + PARTITION_ID_GP_3 = 0x6, /* General Purpose partition 3 */ + PARTITION_ID_GP_4 = 0x7, /* General Purpose partition 4 */ + PARTITION_ID_MASK = 0x7 /* [2:0] */ +} EMMC_PARTITION_ID; + +/* card state in R1 response [12:9] */ +typedef enum { + EMMC_R1_STATE_IDLE = 0, + EMMC_R1_STATE_READY, + EMMC_R1_STATE_IDENT, + EMMC_R1_STATE_STBY, + EMMC_R1_STATE_TRAN, + EMMC_R1_STATE_DATA, + EMMC_R1_STATE_RCV, + EMMC_R1_STATE_PRG, + EMMC_R1_STATE_DIS, + EMMC_R1_STATE_BTST, + EMMC_R1_STATE_SLEP +} EMMC_R1_STATE; + +typedef enum { + ESTATE_BEGIN = 0, + ESTATE_ISSUE_CMD, + ESTATE_NON_RESP_CMD, + ESTATE_RCV_RESP, + ESTATE_RCV_RESPONSE_BUSY, + ESTATE_CHECK_RESPONSE_COMPLETE, + ESTATE_DATA_TRANSFER, + ESTATE_DATA_TRANSFER_COMPLETE, + ESTATE_ACCESS_END, + ESTATE_TRANSFER_ERROR, + ESTATE_ERROR, + ESTATE_END +} EMMC_INT_STATE; + +/* eMMC boot driver error information */ +typedef struct { + uint16_t num; /* error no */ + uint16_t code; /* error code */ + + volatile uint32_t info1; /* SD_INFO1. (hw dependent) */ + volatile uint32_t info2; /* SD_INFO2. (hw dependent) */ + volatile uint32_t status1; /* SD_ERR_STS1. (hw dependent) */ + volatile uint32_t status2; /* SD_ERR_STS2. (hw dependent) */ + volatile uint32_t dm_info1; /* DM_CM_INFO1. (hw dependent) */ + volatile uint32_t dm_info2; /* DM_CM_INFO2. (hw dependent) */ +} st_error_info; + +/* Command information */ +typedef struct { + HAL_MEMCARD_COMMAND cmd; /* Command information */ + uint32_t arg; /* argument */ + HAL_MEMCARD_OPERATION dir; /* direction */ + uint32_t hw; /* SD_CMD register value. */ +} st_command_info; + +/* MMC driver base */ +typedef struct { + st_error_info error_info; /* error information */ + st_command_info cmd_info; /* command information */ + + /* for data transfer */ + uint32_t *buff_address_virtual; /* Dest or Src buff */ + uint32_t *buff_address_physical; /* Dest or Src buff */ + HAL_MEMCARD_DATA_WIDTH bus_width; /* bus width */ + + uint32_t trans_size; /* transfer size for this command */ + uint32_t remain_size; /* remain size for this command */ + uint32_t response_length; /* response length for this command */ + uint32_t sector_size; /* sector_size */ + + /* clock */ + uint32_t base_clock; /* MMC host controller clock */ + /* + * Max freq (Card Spec)[Hz]. It changes dynamically by CSD and + * EXT_CSD. + */ + uint32_t max_freq; + /* request freq [Hz] (400K, 26MHz, 52MHz, etc) */ + uint32_t request_freq; + /* current MMC clock[Hz] (the closest frequency supported by HW) */ + uint32_t current_freq; + + /* state flag */ + /* presence status of the memory card */ + HAL_MEMCARD_PRESENCE_STATUS card_present; + + uint32_t card_power_enable; + uint32_t clock_enable; + /* True : initialize complete. */ + uint32_t initialize; + /* True : sector access, FALSE : byte access */ + uint32_t access_mode; + /* True : mount complete. */ + uint32_t mount; + /* True : selected card. */ + uint32_t selected; + /* 0: DMA, 1:PIO */ + HAL_MEMCARD_DATA_TRANSFER_MODE transfer_mode; + + /* loaded ISSW image No. ISSW have copy image. */ + uint32_t image_num; + /* card state */ + EMMC_R1_STATE current_state; + /* True : during command processing */ + volatile uint32_t during_cmd_processing; + /* True : during transfer */ + volatile uint32_t during_transfer; + /* True : during transfer (DMA) */ + volatile uint32_t during_dma_transfer; + /* True : occurred DMAC error */ + volatile uint32_t dma_error_flag; + /* force terminate flag */ + volatile uint32_t force_terminate; + /* state machine blocking flag : True or False */ + volatile uint32_t state_machine_blocking; + /* True : get partition access processing */ + volatile uint32_t get_partition_access_flag; + + EMMC_PARTITION_ID boot_partition_en; /* Boot partition */ + EMMC_PARTITION_ID partition_access; /* Current access partition */ + + /* timeout */ + uint32_t hs_timing; + + /* read and write data timeout */ + uint32_t data_timeout; + + /* retry */ + uint32_t retries_after_fail; + + /* interrupt */ + volatile uint32_t int_event1; /* interrupt SD_INFO1 Event */ + volatile uint32_t int_event2; /* interrupt SD_INFO2 Event */ + volatile uint32_t dm_event1; /* interrupt DM_CM_INFO1 Event */ + volatile uint32_t dm_event2; /* interrupt DM_CM_INFO2 Event */ + + /* response */ + uint32_t *response; /* buffer ptr for executing command. */ + uint32_t r1_card_status; /* R1 response data */ + uint32_t r3_ocr; /* R3 response data */ + uint32_t r4_resp; /* R4 response data */ + uint32_t r5_resp; /* R5 response data */ + + /* True : clock mode is low. (MMC clock = Max26MHz) */ + uint32_t low_clock_mode_enable; + + uint32_t reserved2; + uint32_t reserved3; + uint32_t reserved4; + + /* CSD registers (4byte align) */ + uint8_t csd_data[EMMC_MAX_CSD_LENGTH] /* CSD */ + __attribute__ ((aligned(EMMC_RES_REG_ALIGNED))); + /* CID registers (4byte align) */ + uint8_t cid_data[EMMC_MAX_CID_LENGTH] /* CID */ + __attribute__ ((aligned(EMMC_RES_REG_ALIGNED))); + /* EXT CSD registers (8byte align) */ + uint8_t ext_csd_data[EMMC_MAX_EXT_CSD_LENGTH] /* EXT_CSD */ + __attribute__ ((aligned(EMMC_BUF_REG_ALIGNED))); + /* Response registers (4byte align) */ + uint8_t response_data[EMMC_MAX_RESPONSE_LENGTH] /* other response */ + __attribute__ ((aligned(EMMC_RES_REG_ALIGNED))); +} st_mmc_base; + +typedef int (*func) (void); + +uint32_t emmc_get_csd_time(void); + +#define MMC_DEBUG +#endif /* EMMC_STD_H */ diff --git a/drivers/renesas/common/emmc/emmc_utility.c b/drivers/renesas/common/emmc/emmc_utility.c new file mode 100644 index 000000000..2e88abc75 --- /dev/null +++ b/drivers/renesas/common/emmc/emmc_utility.c @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include "emmc_config.h" +#include "emmc_def.h" +#include "emmc_hal.h" +#include "emmc_registers.h" +#include "emmc_std.h" + +static const uint32_t cmd_reg_hw[EMMC_CMD_MAX + 1] = { + 0x00000000, /* CMD0 */ + 0x00000701, /* CMD1 */ + 0x00000002, /* CMD2 */ + 0x00000003, /* CMD3 */ + 0x00000004, /* CMD4 */ + 0x00000505, /* CMD5 */ + 0x00000406, /* CMD6 */ + 0x00000007, /* CMD7 */ + 0x00001C08, /* CMD8 */ + 0x00000009, /* CMD9 */ + 0x0000000A, /* CMD10 */ + 0x00000000, /* reserved */ + 0x0000000C, /* CMD12 */ + 0x0000000D, /* CMD13 */ + 0x00001C0E, /* CMD14 */ + 0x0000000F, /* CMD15 */ + 0x00000010, /* CMD16 */ + 0x00000011, /* CMD17 */ + 0x00007C12, /* CMD18 */ + 0x00000C13, /* CMD19 */ + 0x00000000, + 0x00001C15, /* CMD21 */ + 0x00000000, + 0x00000017, /* CMD23 */ + 0x00000018, /* CMD24 */ + 0x00006C19, /* CMD25 */ + 0x00000C1A, /* CMD26 */ + 0x0000001B, /* CMD27 */ + 0x0000001C, /* CMD28 */ + 0x0000001D, /* CMD29 */ + 0x0000001E, /* CMD30 */ + 0x00001C1F, /* CMD31 */ + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000423, /* CMD35 */ + 0x00000424, /* CMD36 */ + 0x00000000, + 0x00000026, /* CMD38 */ + 0x00000427, /* CMD39 */ + 0x00000428, /* CMD40(send cmd) */ + 0x00000000, + 0x0000002A, /* CMD42 */ + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000C31, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00007C35, + 0x00006C36, + 0x00000037, /* CMD55 */ + 0x00000038, /* CMD56(Read) */ + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000 +}; + +uint32_t emmc_bit_field(uint8_t *data, uint32_t top, uint32_t bottom) +{ + uint32_t value; + + uint32_t index_top = (uint32_t) (15 - (top >> 3)); + uint32_t index_bottom = (uint32_t) (15 - (bottom >> 3)); + + if (index_top == index_bottom) { + value = data[index_top]; + } else if ((index_top + 1) == index_bottom) { + value = + (uint32_t) ((data[index_top] << 8) | data[index_bottom]); + } else if ((index_top + 2) == index_bottom) { + value = + (uint32_t) ((data[index_top] << 16) | + (data[index_top + 1] << 8) | data[index_top + + 2]); + } else { + value = + (uint32_t) ((data[index_top] << 24) | + (data[index_top + 1] << 16) | + (data[index_top + 2] << 8) | + data[index_top + 3]); + } + + value = ((value >> (bottom & 0x07)) & ((1 << (top - bottom + 1)) - 1)); + + return value; +} + +void emmc_write_error_info(uint16_t func_no, EMMC_ERROR_CODE error_code) +{ + + mmc_drv_obj.error_info.num = func_no; + mmc_drv_obj.error_info.code = (uint16_t) error_code; + + ERROR("BL2: emmc err:func_no=0x%x code=0x%x\n", func_no, error_code); +} + +void emmc_write_error_info_func_no(uint16_t func_no) +{ + + mmc_drv_obj.error_info.num = func_no; + + ERROR("BL2: emmc err:func_no=0x%x\n", func_no); +} + +void emmc_make_nontrans_cmd(HAL_MEMCARD_COMMAND cmd, uint32_t arg) +{ + /* command information */ + mmc_drv_obj.cmd_info.cmd = cmd; + mmc_drv_obj.cmd_info.arg = arg; + mmc_drv_obj.cmd_info.dir = HAL_MEMCARD_READ; + mmc_drv_obj.cmd_info.hw = + cmd_reg_hw[cmd & HAL_MEMCARD_COMMAND_INDEX_MASK]; + + /* clear data transfer information */ + mmc_drv_obj.trans_size = 0; + mmc_drv_obj.remain_size = 0; + mmc_drv_obj.buff_address_virtual = NULL; + mmc_drv_obj.buff_address_physical = NULL; + + /* response information */ + mmc_drv_obj.response_length = 6; + + switch (mmc_drv_obj.cmd_info.cmd & HAL_MEMCARD_RESPONSE_TYPE_MASK) { + case HAL_MEMCARD_RESPONSE_NONE: + mmc_drv_obj.response = (uint32_t *) mmc_drv_obj.response_data; + mmc_drv_obj.response_length = 0; + break; + case HAL_MEMCARD_RESPONSE_R1: + mmc_drv_obj.response = &mmc_drv_obj.r1_card_status; + break; + case HAL_MEMCARD_RESPONSE_R1b: + mmc_drv_obj.cmd_info.hw |= BIT10; /* bit10 = R1 busy bit */ + mmc_drv_obj.response = &mmc_drv_obj.r1_card_status; + break; + case HAL_MEMCARD_RESPONSE_R2: + mmc_drv_obj.response = (uint32_t *) mmc_drv_obj.response_data; + mmc_drv_obj.response_length = 17; + break; + case HAL_MEMCARD_RESPONSE_R3: + mmc_drv_obj.response = &mmc_drv_obj.r3_ocr; + break; + case HAL_MEMCARD_RESPONSE_R4: + mmc_drv_obj.response = &mmc_drv_obj.r4_resp; + break; + case HAL_MEMCARD_RESPONSE_R5: + mmc_drv_obj.response = &mmc_drv_obj.r5_resp; + break; + default: + mmc_drv_obj.response = (uint32_t *) mmc_drv_obj.response_data; + break; + } +} + +void emmc_make_trans_cmd(HAL_MEMCARD_COMMAND cmd, uint32_t arg, + uint32_t *buff_address_virtual, + uint32_t len, + HAL_MEMCARD_OPERATION dir, + HAL_MEMCARD_DATA_TRANSFER_MODE transfer_mode) +{ + emmc_make_nontrans_cmd(cmd, arg); /* update common information */ + + /* for data transfer command */ + mmc_drv_obj.cmd_info.dir = dir; + mmc_drv_obj.buff_address_virtual = buff_address_virtual; + mmc_drv_obj.buff_address_physical = buff_address_virtual; + mmc_drv_obj.trans_size = len; + mmc_drv_obj.remain_size = len; + mmc_drv_obj.transfer_mode = transfer_mode; +} + +EMMC_ERROR_CODE emmc_send_idle_cmd(uint32_t arg) +{ + EMMC_ERROR_CODE result; + uint32_t freq; + + /* initialize state */ + mmc_drv_obj.mount = FALSE; + mmc_drv_obj.selected = FALSE; + mmc_drv_obj.during_transfer = FALSE; + mmc_drv_obj.during_cmd_processing = FALSE; + mmc_drv_obj.during_dma_transfer = FALSE; + mmc_drv_obj.dma_error_flag = FALSE; + mmc_drv_obj.force_terminate = FALSE; + mmc_drv_obj.state_machine_blocking = FALSE; + + mmc_drv_obj.bus_width = HAL_MEMCARD_DATA_WIDTH_1_BIT; + mmc_drv_obj.max_freq = MMC_20MHZ; /* 20MHz */ + mmc_drv_obj.current_state = EMMC_R1_STATE_IDLE; + + /* CMD0 (MMC clock is current frequency. if Data transfer mode, 20MHz or higher.) */ + emmc_make_nontrans_cmd(CMD0_GO_IDLE_STATE, arg); /* CMD0 */ + result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); + if (result != EMMC_SUCCESS) { + return result; + } + + /* change MMC clock(400KHz) */ + freq = MMC_400KHZ; + result = emmc_set_request_mmc_clock(&freq); + if (result != EMMC_SUCCESS) { + return result; + } + + return EMMC_SUCCESS; +} diff --git a/drivers/renesas/rcar/emmc/emmc_cmd.c b/drivers/renesas/rcar/emmc/emmc_cmd.c deleted file mode 100644 index d255bffc9..000000000 --- a/drivers/renesas/rcar/emmc/emmc_cmd.c +++ /dev/null @@ -1,493 +0,0 @@ -/* - * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include "emmc_config.h" -#include "emmc_def.h" -#include "emmc_hal.h" -#include "emmc_registers.h" -#include "emmc_std.h" -#include "micro_delay.h" - -static void emmc_little_to_big(uint8_t *p, uint32_t value) -{ - if (p == NULL) - return; - - p[0] = (uint8_t) (value >> 24); - p[1] = (uint8_t) (value >> 16); - p[2] = (uint8_t) (value >> 8); - p[3] = (uint8_t) value; - -} - -static void emmc_softreset(void) -{ - int32_t loop = 10000; - int32_t retry = 1000; - - /* flag clear */ - mmc_drv_obj.during_cmd_processing = FALSE; - mmc_drv_obj.during_transfer = FALSE; - mmc_drv_obj.during_dma_transfer = FALSE; - mmc_drv_obj.state_machine_blocking = FALSE; - mmc_drv_obj.force_terminate = FALSE; - mmc_drv_obj.dma_error_flag = FALSE; - - /* during operation ? */ - if ((GETR_32(SD_INFO2) & SD_INFO2_CBSY) == 0) - goto reset; - - /* wait CMDSEQ = 0 */ - while (loop > 0) { - if ((GETR_32(SD_INFO2) & SD_INFO2_CBSY) == 0) - break; /* ready */ - - loop--; - if ((loop == 0) && (retry > 0)) { - rcar_micro_delay(1000U); /* wait 1ms */ - loop = 10000; - retry--; - } - } - -reset: - /* reset */ - SETR_32(SOFT_RST, (GETR_32(SOFT_RST) & (~SOFT_RST_SDRST))); - SETR_32(SOFT_RST, (GETR_32(SOFT_RST) | SOFT_RST_SDRST)); - - /* initialize */ - SETR_32(SD_INFO1, 0x00000000U); - SETR_32(SD_INFO2, SD_INFO2_CLEAR); - SETR_32(SD_INFO1_MASK, 0x00000000U); /* all interrupt disable */ - SETR_32(SD_INFO2_MASK, SD_INFO2_CLEAR); /* all interrupt disable */ -} - -static void emmc_read_response(uint32_t *response) -{ - uint8_t *p; - - if (response == NULL) - return; - - /* read response */ - if (mmc_drv_obj.response_length != EMMC_MAX_RESPONSE_LENGTH) { - *response = GETR_32(SD_RSP10); /* [39:8] */ - return; - } - - /* CSD or CID */ - p = (uint8_t *) (response); - emmc_little_to_big(p, ((GETR_32(SD_RSP76) << 8) - | (GETR_32(SD_RSP54) >> 24))); /* [127:96] */ - emmc_little_to_big(p + 4, ((GETR_32(SD_RSP54) << 8) - | (GETR_32(SD_RSP32) >> 24))); /* [95:64] */ - emmc_little_to_big(p + 8, ((GETR_32(SD_RSP32) << 8) - | (GETR_32(SD_RSP10) >> 24))); /* [63:32] */ - emmc_little_to_big(p + 12, (GETR_32(SD_RSP10) << 8)); -} - -static EMMC_ERROR_CODE emmc_response_check(uint32_t *response, - uint32_t error_mask) -{ - - HAL_MEMCARD_RESPONSE_TYPE response_type = - ((HAL_MEMCARD_RESPONSE_TYPE)mmc_drv_obj.cmd_info.cmd & HAL_MEMCARD_RESPONSE_TYPE_MASK); - - if (response == NULL) - return EMMC_ERR_PARAM; - - if (response_type == HAL_MEMCARD_RESPONSE_NONE) - return EMMC_SUCCESS; - - - if (response_type <= HAL_MEMCARD_RESPONSE_R1b) { - /* R1 or R1b */ - mmc_drv_obj.current_state = - (EMMC_R1_STATE) ((*response & EMMC_R1_STATE_MASK) >> - EMMC_R1_STATE_SHIFT); - if ((*response & error_mask) != 0) { - if ((0x80 & *response) != 0) { - ERROR("BL2: emmc SWITCH_ERROR\n"); - } - return EMMC_ERR_CARD_STATUS_BIT; - } - return EMMC_SUCCESS; - } - - if (response_type == HAL_MEMCARD_RESPONSE_R4) { - if ((*response & EMMC_R4_STATUS) != 0) - return EMMC_ERR_CARD_STATUS_BIT; - } - - return EMMC_SUCCESS; -} - -static void emmc_WaitCmd2Cmd_8Cycle(void) -{ - uint32_t dataL, wait = 0; - - dataL = GETR_32(SD_CLK_CTRL); - dataL &= 0x000000FF; - - switch (dataL) { - case 0xFF: - case 0x00: - case 0x01: - case 0x02: - case 0x04: - case 0x08: - case 0x10: - case 0x20: - wait = 10U; - break; - case 0x40: - wait = 20U; - break; - case 0x80: - wait = 30U; - break; - } - - rcar_micro_delay(wait); -} - -static void cmdErrSdInfo2Log(void) -{ - ERROR("BL2: emmc ERR SD_INFO2 = 0x%x\n", mmc_drv_obj.error_info.info2); -} - -static void emmc_data_transfer_dma(void) -{ - mmc_drv_obj.during_dma_transfer = TRUE; - mmc_drv_obj.dma_error_flag = FALSE; - - SETR_32(SD_INFO1_MASK, 0x00000000U); - SETR_32(SD_INFO2_MASK, (SD_INFO2_ALL_ERR | SD_INFO2_CLEAR)); - - /* DMAC setting */ - if (mmc_drv_obj.cmd_info.dir == HAL_MEMCARD_WRITE) { - /* transfer complete interrupt enable */ - SETR_32(DM_CM_INFO1_MASK, - (DM_CM_INFO_MASK_CLEAR | DM_CM_INFO_CH0_ENABLE)); - SETR_32(DM_CM_INFO2_MASK, - (DM_CM_INFO_MASK_CLEAR | DM_CM_INFO_CH0_ENABLE)); - /* BUFF --> FIFO */ - SETR_32(DM_CM_DTRAN_MODE, (DM_CM_DTRAN_MODE_CH0 | - DM_CM_DTRAN_MODE_BIT_WIDTH)); - } else { - /* transfer complete interrupt enable */ - SETR_32(DM_CM_INFO1_MASK, - (DM_CM_INFO_MASK_CLEAR | DM_CM_INFO_CH1_ENABLE)); - SETR_32(DM_CM_INFO2_MASK, - (DM_CM_INFO_MASK_CLEAR | DM_CM_INFO_CH1_ENABLE)); - /* FIFO --> BUFF */ - SETR_32(DM_CM_DTRAN_MODE, (DM_CM_DTRAN_MODE_CH1 - | DM_CM_DTRAN_MODE_BIT_WIDTH)); - } - SETR_32(DM_DTRAN_ADDR, (((uintptr_t) mmc_drv_obj.buff_address_virtual & - DM_DTRAN_ADDR_WRITE_MASK))); - - SETR_32(DM_CM_DTRAN_CTRL, DM_CM_DTRAN_CTRL_START); -} - -EMMC_ERROR_CODE emmc_exec_cmd(uint32_t error_mask, uint32_t *response) -{ - EMMC_ERROR_CODE rtn_code = EMMC_SUCCESS; - HAL_MEMCARD_RESPONSE_TYPE response_type; - HAL_MEMCARD_COMMAND_TYPE cmd_type; - EMMC_INT_STATE state; - uint32_t err_not_care_flag = FALSE; - - /* parameter check */ - if (response == NULL) { - emmc_write_error_info(EMMC_FUNCNO_EXEC_CMD, EMMC_ERR_PARAM); - return EMMC_ERR_PARAM; - } - - /* state check */ - if (mmc_drv_obj.clock_enable != TRUE) { - emmc_write_error_info(EMMC_FUNCNO_EXEC_CMD, EMMC_ERR_STATE); - return EMMC_ERR_STATE; - } - - if (mmc_drv_obj.state_machine_blocking == TRUE) { - emmc_write_error_info(EMMC_FUNCNO_EXEC_CMD, EMMC_ERR); - return EMMC_ERR; - } - - state = ESTATE_BEGIN; - response_type = - ((HAL_MEMCARD_RESPONSE_TYPE)mmc_drv_obj.cmd_info.cmd & - HAL_MEMCARD_RESPONSE_TYPE_MASK); - cmd_type = - ((HAL_MEMCARD_COMMAND_TYPE) mmc_drv_obj.cmd_info.cmd & - HAL_MEMCARD_COMMAND_TYPE_MASK); - - /* state machine */ - while ((mmc_drv_obj.force_terminate != TRUE) && (state != ESTATE_END)) { - /* The interrupt factor flag is observed. */ - emmc_interrupt(); - - /* wait interrupt */ - if (mmc_drv_obj.state_machine_blocking == TRUE) - continue; - - switch (state) { - case ESTATE_BEGIN: - /* Busy check */ - if ((mmc_drv_obj.error_info.info2 & SD_INFO2_CBSY) != 0) { - emmc_write_error_info(EMMC_FUNCNO_EXEC_CMD, - EMMC_ERR_CARD_BUSY); - return EMMC_ERR_CARD_BUSY; - } - - /* clear register */ - SETR_32(SD_INFO1, 0x00000000U); - SETR_32(SD_INFO2, SD_INFO2_CLEAR); - SETR_32(SD_INFO1_MASK, SD_INFO1_INFO0); - SETR_32(SD_INFO2_MASK, - (SD_INFO2_ALL_ERR | SD_INFO2_CLEAR)); - - state = ESTATE_ISSUE_CMD; - /* through */ - - case ESTATE_ISSUE_CMD: - /* ARG */ - SETR_32(SD_ARG, mmc_drv_obj.cmd_info.arg); - /* issue cmd */ - SETR_32(SD_CMD, mmc_drv_obj.cmd_info.hw); - /* Set driver flag */ - mmc_drv_obj.during_cmd_processing = TRUE; - mmc_drv_obj.state_machine_blocking = TRUE; - - if (response_type == HAL_MEMCARD_RESPONSE_NONE) { - state = ESTATE_NON_RESP_CMD; - } else { - state = ESTATE_RCV_RESP; - } - - break; - - case ESTATE_NON_RESP_CMD: - /* interrupt disable */ - SETR_32(SD_INFO1_MASK, 0x00000000U); - SETR_32(SD_INFO2_MASK, SD_INFO2_CLEAR); - - /* check interrupt */ - if ((mmc_drv_obj.int_event2 & SD_INFO2_ALL_ERR) != 0) { - /* error interrupt */ - cmdErrSdInfo2Log(); - rtn_code = EMMC_ERR_INFO2; - state = ESTATE_ERROR; - } else if ((mmc_drv_obj.int_event1 & SD_INFO1_INFO0) == - 0) { - /* not receive expected interrupt */ - rtn_code = EMMC_ERR_RESPONSE; - state = ESTATE_ERROR; - } else { - emmc_WaitCmd2Cmd_8Cycle(); - state = ESTATE_END; - } - break; - - case ESTATE_RCV_RESP: - /* interrupt disable */ - SETR_32(SD_INFO1_MASK, 0x00000000U); - SETR_32(SD_INFO2_MASK, SD_INFO2_CLEAR); - - /* check interrupt */ - if ((mmc_drv_obj.int_event2 & SD_INFO2_ALL_ERR) != 0) { - if ((mmc_drv_obj.get_partition_access_flag == - TRUE) - && ((mmc_drv_obj.int_event2 & SD_INFO2_ERR6) - != 0U)) { - err_not_care_flag = TRUE; - rtn_code = EMMC_ERR_CMD_TIMEOUT; - } else { - /* error interrupt */ - cmdErrSdInfo2Log(); - rtn_code = EMMC_ERR_INFO2; - } - state = ESTATE_ERROR; - break; - } else if ((mmc_drv_obj.int_event1 & SD_INFO1_INFO0) == - 0) { - /* not receive expected interrupt */ - rtn_code = EMMC_ERR_RESPONSE; - state = ESTATE_ERROR; - break; - } - - /* read response */ - emmc_read_response(response); - - /* check response */ - rtn_code = emmc_response_check(response, error_mask); - if (rtn_code != EMMC_SUCCESS) { - state = ESTATE_ERROR; - break; - } - - if (response_type == HAL_MEMCARD_RESPONSE_R1b) { - /* R1b */ - SETR_32(SD_INFO2_MASK, - (SD_INFO2_ALL_ERR | SD_INFO2_CLEAR)); - state = ESTATE_RCV_RESPONSE_BUSY; - } else { - state = ESTATE_CHECK_RESPONSE_COMPLETE; - } - break; - - case ESTATE_RCV_RESPONSE_BUSY: - /* check interrupt */ - if ((mmc_drv_obj.int_event2 & SD_INFO2_ALL_ERR) != 0) { - /* error interrupt */ - cmdErrSdInfo2Log(); - rtn_code = EMMC_ERR_INFO2; - state = ESTATE_ERROR; - break; - } - /* DAT0 not Busy */ - if ((SD_INFO2_DAT0 & mmc_drv_obj.error_info.info2) != 0) { - state = ESTATE_CHECK_RESPONSE_COMPLETE; - break; - } - break; - - case ESTATE_CHECK_RESPONSE_COMPLETE: - if (cmd_type >= HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE) { - state = ESTATE_DATA_TRANSFER; - } else { - emmc_WaitCmd2Cmd_8Cycle(); - state = ESTATE_END; - } - break; - - case ESTATE_DATA_TRANSFER: - /* ADTC command */ - mmc_drv_obj.during_transfer = TRUE; - mmc_drv_obj.state_machine_blocking = TRUE; - - if (mmc_drv_obj.transfer_mode == HAL_MEMCARD_DMA) { - /* DMA */ - emmc_data_transfer_dma(); - } else { - /* PIO */ - /* interrupt enable (FIFO read/write enable) */ - if (mmc_drv_obj.cmd_info.dir == - HAL_MEMCARD_WRITE) { - SETR_32(SD_INFO2_MASK, - (SD_INFO2_BWE | SD_INFO2_ALL_ERR - | SD_INFO2_CLEAR)); - } else { - SETR_32(SD_INFO2_MASK, - (SD_INFO2_BRE | SD_INFO2_ALL_ERR - | SD_INFO2_CLEAR)); - } - } - state = ESTATE_DATA_TRANSFER_COMPLETE; - break; - - case ESTATE_DATA_TRANSFER_COMPLETE: - /* check interrupt */ - if ((mmc_drv_obj.int_event2 & SD_INFO2_ALL_ERR) != 0) { - /* error interrupt */ - cmdErrSdInfo2Log(); - rtn_code = EMMC_ERR_INFO2; - state = ESTATE_TRANSFER_ERROR; - break; - } - - /* DMAC error ? */ - if (mmc_drv_obj.dma_error_flag == TRUE) { - /* Error occurred in DMAC driver. */ - rtn_code = EMMC_ERR_FROM_DMAC_TRANSFER; - state = ESTATE_TRANSFER_ERROR; - } else if (mmc_drv_obj.during_dma_transfer == TRUE) { - /* DMAC not finished. unknown error */ - rtn_code = EMMC_ERR; - state = ESTATE_TRANSFER_ERROR; - } else { - SETR_32(SD_INFO1_MASK, SD_INFO1_INFO2); - SETR_32(SD_INFO2_MASK, - (SD_INFO2_ALL_ERR | SD_INFO2_CLEAR)); - - mmc_drv_obj.state_machine_blocking = TRUE; - - state = ESTATE_ACCESS_END; - } - break; - - case ESTATE_ACCESS_END: - - /* clear flag */ - if (mmc_drv_obj.transfer_mode == HAL_MEMCARD_DMA) { - /* W (CC_EXT_MODE, H'0000_1010) SD_BUF DMA transfer disabled */ - SETR_32(CC_EXT_MODE, CC_EXT_MODE_CLEAR); - SETR_32(SD_STOP, 0x00000000U); - mmc_drv_obj.during_dma_transfer = FALSE; - } - - SETR_32(SD_INFO1_MASK, 0x00000000U); - SETR_32(SD_INFO2_MASK, SD_INFO2_CLEAR); - SETR_32(SD_INFO1, 0x00000000U); - SETR_32(SD_INFO2, SD_INFO2_CLEAR); - - if ((mmc_drv_obj.int_event1 & SD_INFO1_INFO2) != 0) { - emmc_WaitCmd2Cmd_8Cycle(); - state = ESTATE_END; - } else { - state = ESTATE_ERROR; - } - break; - - case ESTATE_TRANSFER_ERROR: - /* The error occurred in the Data transfer. */ - if (mmc_drv_obj.transfer_mode == HAL_MEMCARD_DMA) { - /* W (CC_EXT_MODE, H'0000_1010) SD_BUF DMA transfer disabled */ - SETR_32(CC_EXT_MODE, CC_EXT_MODE_CLEAR); - SETR_32(SD_STOP, 0x00000000U); - mmc_drv_obj.during_dma_transfer = FALSE; - } - /* through */ - - case ESTATE_ERROR: - if (err_not_care_flag == TRUE) { - mmc_drv_obj.during_cmd_processing = FALSE; - } else { - emmc_softreset(); - emmc_write_error_info(EMMC_FUNCNO_EXEC_CMD, - rtn_code); - } - return rtn_code; - - default: - state = ESTATE_END; - break; - } /* switch (state) */ - } /* while ( (mmc_drv_obj.force_terminate != TRUE) && (state != ESTATE_END) ) */ - - /* force terminate */ - if (mmc_drv_obj.force_terminate == TRUE) { - /* timeout timer is expired. Or, PIO data transfer error. */ - /* Timeout occurred in the DMA transfer. */ - if (mmc_drv_obj.during_dma_transfer == TRUE) { - mmc_drv_obj.during_dma_transfer = FALSE; - } - ERROR("BL2: emmc exec_cmd:EMMC_ERR_FORCE_TERMINATE\n"); - emmc_softreset(); - - return EMMC_ERR_FORCE_TERMINATE; /* error information has already been written. */ - } - - /* success */ - mmc_drv_obj.during_cmd_processing = FALSE; - mmc_drv_obj.during_transfer = FALSE; - - return EMMC_SUCCESS; -} diff --git a/drivers/renesas/rcar/emmc/emmc_config.h b/drivers/renesas/rcar/emmc/emmc_config.h deleted file mode 100644 index 16b6b8aa9..000000000 --- a/drivers/renesas/rcar/emmc/emmc_config.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef EMMC_CONFIG_H -#define EMMC_CONFIG_H - -/* RCA */ -#define EMMC_RCA 1UL -/* 314ms (freq = 400KHz, timeout Counter = 0x04(SDCLK * 2^17) */ -#define EMMC_RW_DATA_TIMEOUT 0x40UL -/* how many times to try after fail. Don't change. */ -#define EMMC_RETRY_COUNT 0 -#define EMMC_CMD_MAX 60UL /* Don't change. */ - -#define LOADIMAGE_FLAGS_DMA_ENABLE 0x00000001UL - -#endif /* EMMC_CONFIG_H */ diff --git a/drivers/renesas/rcar/emmc/emmc_def.h b/drivers/renesas/rcar/emmc/emmc_def.h deleted file mode 100644 index 178c795b9..000000000 --- a/drivers/renesas/rcar/emmc/emmc_def.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/** - * @file emmc_def.h - * @brief eMMC boot is expecting this header file - * - */ - -#ifndef EMMC_DEF_H -#define EMMC_DEF_H - -#include "emmc_std.h" - -/* ************************ HEADER (INCLUDE) SECTION *********************** */ - -/* ***************** MACROS, CONSTANTS, COMPILATION FLAGS ****************** */ -#define EMMC_POWER_ON (1U) - -/* ********************** STRUCTURES, TYPE DEFINITIONS ********************* */ - -/* ********************** DECLARATION OF EXTERNAL DATA ********************* */ -extern st_mmc_base mmc_drv_obj; - -/* ************************** FUNCTION PROTOTYPES ************************** */ - -/** @brief for assembler program - */ -uint32_t _rom_emmc_finalize(void); - -/** @brief eMMC driver API - */ -EMMC_ERROR_CODE rcar_emmc_init(void); -EMMC_ERROR_CODE emmc_terminate(void); -EMMC_ERROR_CODE rcar_emmc_memcard_power(uint8_t mode); -EMMC_ERROR_CODE rcar_emmc_mount(void); -EMMC_ERROR_CODE emmc_set_request_mmc_clock(uint32_t *freq); -EMMC_ERROR_CODE emmc_send_idle_cmd(uint32_t arg); -EMMC_ERROR_CODE emmc_select_partition(EMMC_PARTITION_ID id); -EMMC_ERROR_CODE emmc_read_sector(uint32_t *buff_address_virtual, - uint32_t sector_number, uint32_t count, - uint32_t feature_flags); -EMMC_ERROR_CODE emmc_write_sector(uint32_t *buff_address_virtual, - uint32_t sector_number, uint32_t count, - uint32_t feature_flags); -EMMC_ERROR_CODE emmc_erase_sector(uint32_t *start_address, - uint32_t *end_address); -uint32_t emmc_bit_field(uint8_t *data, uint32_t top, uint32_t bottom); - -/** @brief interrupt service - */ -uint32_t emmc_interrupt(void); - -/** @brief DMA - */ - -/** @brief send command API - */ -EMMC_ERROR_CODE emmc_exec_cmd(uint32_t error_mask, uint32_t *response); -void emmc_make_nontrans_cmd(HAL_MEMCARD_COMMAND cmd, uint32_t arg); -void emmc_make_trans_cmd(HAL_MEMCARD_COMMAND cmd, uint32_t arg, - uint32_t *buff_address_virtual, uint32_t len, - HAL_MEMCARD_OPERATION dir, - HAL_MEMCARD_DATA_TRANSFER_MODE transfer_mode); -EMMC_ERROR_CODE emmc_set_ext_csd(uint32_t arg); - -/** @brief for error information - */ -void emmc_write_error_info(uint16_t func_no, EMMC_ERROR_CODE error_code); -void emmc_write_error_info_func_no(uint16_t func_no); - -/* ********************************* CODE ********************************** */ - -#endif /* EMMC_DEF_H */ -/* ******************************** END ************************************ */ diff --git a/drivers/renesas/rcar/emmc/emmc_hal.h b/drivers/renesas/rcar/emmc/emmc_hal.h deleted file mode 100644 index 0a8551719..000000000 --- a/drivers/renesas/rcar/emmc/emmc_hal.h +++ /dev/null @@ -1,535 +0,0 @@ -/* - * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef EMMC_HAL_H -#define EMMC_HAL_H - -/* memory card error/status types */ -#define HAL_MEMCARD_OUT_OF_RANGE 0x80000000L -#define HAL_MEMCARD_ADDRESS_ERROR 0x40000000L -#define HAL_MEMCARD_BLOCK_LEN_ERROR 0x20000000L -#define HAL_MEMCARD_ERASE_SEQ_ERROR 0x10000000L -#define HAL_MEMCARD_ERASE_PARAM 0x08000000L -#define HAL_MEMCARD_WP_VIOLATION 0x04000000L -#define HAL_MEMCARD_CARD_IS_LOCKED 0x02000000L -#define HAL_MEMCARD_LOCK_UNLOCK_FAILED 0x01000000L -#define HAL_MEMCARD_COM_CRC_ERROR 0x00800000L -#define HAL_MEMCARD_ILEGAL_COMMAND 0x00400000L -#define HAL_MEMCARD_CARD_ECC_FAILED 0x00200000L -#define HAL_MEMCARD_CC_ERROR 0x00100000L -#define HAL_MEMCARD_ERROR 0x00080000L -#define HAL_MEMCARD_UNDERRUN 0x00040000L -#define HAL_MEMCARD_OVERRUN 0x00020000L -#define HAL_MEMCARD_CIDCSD_OVERWRITE 0x00010000L -#define HAL_MEMCARD_WP_ERASE_SKIP 0x00008000L -#define HAL_MEMCARD_CARD_ECC_DISABLED 0x00004000L -#define HAL_MEMCARD_ERASE_RESET 0x00002000L -#define HAL_MEMCARD_CARD_STATE 0x00001E00L -#define HAL_MEMCARD_CARD_READY_FOR_DATA 0x00000100L -#define HAL_MEMCARD_APP_CMD 0x00000020L -#define HAL_MEMCARD_SWITCH_ERROR 0x00000080L -#define HAL_MEMCARD_AKE_SEQ_ERROR 0x00000008L -#define HAL_MEMCARD_NO_ERRORS 0x00000000L - -/* Memory card response types */ -#define HAL_MEMCARD_COMMAND_INDEX_MASK 0x0003f - -/* Type of the return value. */ -typedef enum { - HAL_MEMCARD_FAIL = 0U, - HAL_MEMCARD_OK = 1U, - HAL_MEMCARD_DMA_ALLOC_FAIL = 2U, /* DMA channel allocation failed */ - HAL_MEMCARD_DMA_TRANSFER_FAIL = 3U, /* DMA transfer failed */ - HAL_MEMCARD_CARD_STATUS_ERROR = 4U, /* card status non-masked error */ - HAL_MEMCARD_CMD_TIMEOUT = 5U, /* Command timeout occurred */ - HAL_MEMCARD_DATA_TIMEOUT = 6U, /* Data timeout occurred */ - HAL_MEMCARD_CMD_CRC_ERROR = 7U, /* Command CRC error occurred */ - HAL_MEMCARD_DATA_CRC_ERROR = 8U /* Data CRC error occurred */ -} HAL_MEMCARD_RETURN; - -/* memory access operation */ -typedef enum { - HAL_MEMCARD_READ = 0U, /* read */ - HAL_MEMCARD_WRITE = 1U /* write */ -} HAL_MEMCARD_OPERATION; - -/* Type of data width on memorycard bus */ -typedef enum { - HAL_MEMCARD_DATA_WIDTH_1_BIT = 0U, - HAL_MEMCARD_DATA_WIDTH_4_BIT = 1U, - HAL_MEMCARD_DATA_WIDTH_8_BIT = 2U -} HAL_MEMCARD_DATA_WIDTH; /* data (bus) width types */ - -/* Presence of the memory card */ -typedef enum { - HAL_MEMCARD_CARD_IS_IN = 0U, - HAL_MEMCARD_CARD_IS_OUT = 1U -} HAL_MEMCARD_PRESENCE_STATUS; /* presence status of the memory card */ - -/* mode of data transfer */ -typedef enum { - HAL_MEMCARD_DMA = 0U, - HAL_MEMCARD_NOT_DMA = 1U -} HAL_MEMCARD_DATA_TRANSFER_MODE; - -/* Memory card response types. */ -typedef enum hal_memcard_response_type { - HAL_MEMCARD_RESPONSE_NONE = 0x00000U, - HAL_MEMCARD_RESPONSE_R1 = 0x00100U, - HAL_MEMCARD_RESPONSE_R1b = 0x00200U, - HAL_MEMCARD_RESPONSE_R2 = 0x00300U, - HAL_MEMCARD_RESPONSE_R3 = 0x00400U, - HAL_MEMCARD_RESPONSE_R4 = 0x00500U, - HAL_MEMCARD_RESPONSE_R5 = 0x00600U, - HAL_MEMCARD_RESPONSE_R6 = 0x00700U, - HAL_MEMCARD_RESPONSE_R7 = 0x00800U, - HAL_MEMCARD_RESPONSE_TYPE_MASK = 0x00f00U -} HAL_MEMCARD_RESPONSE_TYPE; - -/* Memory card command types. */ -typedef enum hal_memcard_command_type { - HAL_MEMCARD_COMMAND_TYPE_BC = 0x00000U, - HAL_MEMCARD_COMMAND_TYPE_BCR = 0x01000U, - HAL_MEMCARD_COMMAND_TYPE_AC = 0x02000U, - HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE = 0x03000U, - HAL_MEMCARD_COMMAND_TYPE_ADTC_READ = 0x04000U, - HAL_MEMCARD_COMMAND_TYPE_MASK = 0x07000U -} HAL_MEMCARD_COMMAND_TYPE; - -/* Type of memory card */ -typedef enum hal_memcard_command_card_type { - HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON = 0x00000U, - HAL_MEMCARD_COMMAND_CARD_TYPE_MMC = 0x08000U, - HAL_MEMCARD_COMMAND_CARD_TYPE_SD = 0x10000U, - HAL_MEMCARD_COMMAND_CARD_TYPE_MASK = 0x18000U -} HAL_MEMCARD_COMMAND_CARD_TYPE; - -/* Memory card application command. */ -typedef enum hal_memcard_command_app_norm { - HAL_MEMCARD_COMMAND_NORMAL = 0x00000U, - HAL_MEMCARD_COMMAND_APP = 0x20000U, - HAL_MEMCARD_COMMAND_APP_NORM_MASK = 0x20000U -} HAL_MEMCARD_COMMAND_APP_NORM; - -/* Memory card command codes. */ -typedef enum { -/* class 0 and class 1 */ - /* CMD0 */ - CMD0_GO_IDLE_STATE = - 0U | (uint32_t)HAL_MEMCARD_RESPONSE_NONE | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_BC | - (uint32_t) HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - /* CMD1 */ - CMD1_SEND_OP_COND = - 1U | (uint32_t)HAL_MEMCARD_RESPONSE_R3 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_BCR | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - /* CMD2 */ - CMD2_ALL_SEND_CID_MMC = - 2U | (uint32_t)HAL_MEMCARD_RESPONSE_R2 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_BCR | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - CMD2_ALL_SEND_CID_SD = - 2U | (uint32_t)HAL_MEMCARD_RESPONSE_R2 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_BCR | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - /* CMD3 */ - CMD3_SET_RELATIVE_ADDR = - 3U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - CMD3_SEND_RELATIVE_ADDR = - 3U | (uint32_t)HAL_MEMCARD_RESPONSE_R6 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - /* CMD4 */ - CMD4_SET_DSR = - 4U | (uint32_t)HAL_MEMCARD_RESPONSE_NONE | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_BC | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - /* CMD5 */ - CMD5_SLEEP_AWAKE = - 5U | (uint32_t)HAL_MEMCARD_RESPONSE_R1b | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - /* CMD6 */ - CMD6_SWITCH = - 6U | (uint32_t)HAL_MEMCARD_RESPONSE_R1b | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - CMD6_SWITCH_FUNC = - 6U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - ACMD6_SET_BUS_WIDTH = - 6U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | - (uint32_t)HAL_MEMCARD_COMMAND_APP, - /* CMD7 */ - CMD7_SELECT_CARD = - 7U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - /* CMD7(from Disconnected State to Programming State) */ - CMD7_SELECT_CARD_PROG = - 7U | (uint32_t)HAL_MEMCARD_RESPONSE_R1b | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - CMD7_DESELECT_CARD = - 7U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - /* CMD8 */ - CMD8_SEND_EXT_CSD = - 8U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - CMD8_SEND_IF_COND = - 8U | (uint32_t)HAL_MEMCARD_RESPONSE_R7 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_BCR | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - /* CMD9 */ - CMD9_SEND_CSD = - 9U | (uint32_t)HAL_MEMCARD_RESPONSE_R2 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - /* CMD10 */ - CMD10_SEND_CID = - 10U | (uint32_t)HAL_MEMCARD_RESPONSE_R2 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - /* CMD11 */ - CMD11_READ_DAT_UNTIL_STOP = - 11U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - /* CMD12 */ - CMD12_STOP_TRANSMISSION = - 12U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - /* CMD12(R1b : write case) */ - CMD12_STOP_TRANSMISSION_WRITE = - 12U | (uint32_t)HAL_MEMCARD_RESPONSE_R1b | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - /* CMD13 */ - CMD13_SEND_STATUS = - 13U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - ACMD13_SD_STATUS = - 13U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | - (uint32_t)HAL_MEMCARD_COMMAND_APP, - /* CMD14 */ - CMD14_BUSTEST_R = - 14U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - /* CMD15 */ - CMD15_GO_INACTIVE_STATE = - 15U | (uint32_t)HAL_MEMCARD_RESPONSE_NONE | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - -/* class 2 */ - /* CMD16 */ - CMD16_SET_BLOCKLEN = - 16U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - /* CMD17 */ - CMD17_READ_SINGLE_BLOCK = - 17U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - /* CMD18 */ - CMD18_READ_MULTIPLE_BLOCK = - 18U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - /* CMD19 */ - CMD19_BUS_TEST_W = - 19U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - -/* class 3 */ - /* CMD20 */ - CMD20_WRITE_DAT_UNTIL_STOP = - 20U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - /* CMD21 */ - CMD21 = 21U, - /* CMD22 */ - CMD22 = 22U, - ACMD22_SEND_NUM_WR_BLOCKS = - 22U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | - (uint32_t)HAL_MEMCARD_COMMAND_APP, - -/* class 4 */ - /* CMD23 */ - CMD23_SET_BLOCK_COUNT = - 23U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - ACMD23_SET_WR_BLK_ERASE_COUNT = - 23U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | - (uint32_t)HAL_MEMCARD_COMMAND_APP, - /* CMD24 */ - CMD24_WRITE_BLOCK = - 24U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - /* CMD25 */ - CMD25_WRITE_MULTIPLE_BLOCK = - 25U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - /* CMD26 */ - CMD26_PROGRAM_CID = - 26U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - /* CMD27 */ - CMD27_PROGRAM_CSD = - 27U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - -/* class 6 */ - /* CMD28 */ - CMD28_SET_WRITE_PROT = - 28U | (uint32_t)HAL_MEMCARD_RESPONSE_R1b | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - /* CMD29 */ - CMD29_CLR_WRITE_PROT = - 29U | (uint32_t)HAL_MEMCARD_RESPONSE_R1b | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - /* CMD30 */ - CMD30_SEND_WRITE_PROT = - 30U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - /* CMD31 */ - CMD30_SEND_WRITE_PROT_TYPE = - 31U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - -/* class 5 */ - /* CMD32 */ - CMD32_ERASE_WR_BLK_START = - 32U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - /* CMD33 */ - CMD33_ERASE_WR_BLK_END = - 33U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - /* CMD34 */ - CMD34 = 34U, - /* CMD35 */ - CMD35_ERASE_GROUP_START = - 35U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - /* CMD36 */ - CMD36_ERASE_GROUP_END = - 36U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - /* CMD37 */ - CMD37 = 37U, - /* CMD38 */ - CMD38_ERASE = - 38U | (uint32_t)HAL_MEMCARD_RESPONSE_R1b | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - -/* class 9 */ - /* CMD39 */ - CMD39_FASTIO = - 39U | (uint32_t)HAL_MEMCARD_RESPONSE_R4 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - /* CMD40 */ - CMD40_GO_IRQSTATE = - 40U | (uint32_t)HAL_MEMCARD_RESPONSE_R5 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_BCR | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - /* CMD41 */ - CMD41 = 41, - ACMD41_SD_SEND_OP_COND = - 41U | (uint32_t)HAL_MEMCARD_RESPONSE_R3 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_BCR | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | - (uint32_t)HAL_MEMCARD_COMMAND_APP, - -/* class 7 */ - /* CMD42 */ - CMD42_LOCK_UNLOCK = - 42U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - ACMD42_SET_CLR_CARD_DETECT = - 42U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | - (uint32_t)HAL_MEMCARD_COMMAND_APP, - CMD43 = 43U, /* CMD43 */ - CMD44 = 44U, /* CMD44 */ - CMD45 = 45U, /* CMD45 */ - CMD46 = 46U, /* CMD46 */ - CMD47 = 47U, /* CMD47 */ - CMD48 = 48U, /* CMD48 */ - CMD49 = 49U, /* CMD49 */ - CMD50 = 50U, /* CMD50 */ - CMD51 = 51U, /* CMD51 */ - ACMD51_SEND_SCR = - 51U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD | - (uint32_t)HAL_MEMCARD_COMMAND_APP, - CMD52 = 52U, /* CMD52 */ - CMD53 = 53U, /* CMD53 */ - CMD54 = 54U, /* CMD54 */ - -/* class 8 */ - /* CMD55 */ - CMD55_APP_CMD = - 55U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - /* CMD56 */ - CMD56_GEN_CMD = - 56U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 | - (uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | - (uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | - (uint32_t)HAL_MEMCARD_COMMAND_NORMAL, - CMD57 = 57U, /* CMD57 */ - CMD58 = 58U, /* CMD58 */ - CMD59 = 59U, /* CMD59 */ - CMD60 = 60U, /* CMD60 */ - CMD61 = 61U, /* CMD61 */ - CMD62 = 62U, /* CMD62 */ - CMD63 = 63U /* CMD63 */ -} HAL_MEMCARD_COMMAND; - -/* - * Configuration structure from HAL layer. - * - * If some field is not available it should be filled with 0xFF. - * The API version is 32-bit unsigned integer telling the version of the API. - * The integer is divided to four sections which each can be treated as a 8-bit - * unsigned number: - * Bits 31-24 make the most significant part of the version number. This number - * starts from 1 i.e. the second version of the API will be 0x02xxxxxx. This - * number changes only, if the API itself changes so much that it is not - * compatible anymore with older releases. - * Bits 23-16 API minor version number. For example API version 2.1 would be - * 0x0201xxxx. - * Bits 15-8 are the number of the year when release is done. The 0 is year - * 2000, 1 is year 2001 and so on - * Bits 7- are the week number when release is done. First full week of the - * year is 1 - * - * Example: let's assume that release 2.1 is done on week 10 year 2008 - * the version will get the value 0x0201080A - */ -typedef struct { - /* - * Version of the chipset API implementation - * - * bits [31:24] API specification major version number.
- * bits [23:16] API specification minor version number.
- * bits [15:8] API implementation year. (2000 = 0, 2001 = 1, ...) - * bits [7:0] API implementation week. - * Example: API spec version 4.0, implementation w46 2008 => 0x0400082E - */ - uint32_t api_version; - - /* maximum block count which can be transferred at once */ - uint32_t max_block_count; - - /* maximum clock frequence in Hz supported by HW */ - uint32_t max_clock_freq; - - /* maximum data bus width supported by HW */ - uint16_t max_data_width; - - /* Is high-speed mode supported by HW (yes=1, no=0) */ - uint8_t hs_mode_supported; - - /* Is memory card removable (yes=1, no=0) */ - uint8_t card_removable; - -} HAL_MEMCARD_HW_CONF; - -/* Configuration structure to HAL layer. */ -typedef struct { - /* how many times to try after fail, for instance sending command */ - uint32_t retries_after_fail; -} HAL_MEMCARD_INIT_CONF; - -#endif /* EMMC_HAL_H */ diff --git a/drivers/renesas/rcar/emmc/emmc_init.c b/drivers/renesas/rcar/emmc/emmc_init.c deleted file mode 100644 index 354aa3c82..000000000 --- a/drivers/renesas/rcar/emmc/emmc_init.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include - -#include "emmc_config.h" -#include "emmc_hal.h" -#include "emmc_std.h" -#include "emmc_registers.h" -#include "emmc_def.h" -#include "rcar_private.h" - -st_mmc_base mmc_drv_obj; - -EMMC_ERROR_CODE rcar_emmc_memcard_power(uint8_t mode) -{ - - if (mode == TRUE) { - /* power on (Vcc&Vccq is always power on) */ - mmc_drv_obj.card_power_enable = TRUE; - } else { - /* power off (Vcc&Vccq is always power on) */ - mmc_drv_obj.card_power_enable = FALSE; - mmc_drv_obj.mount = FALSE; - mmc_drv_obj.selected = FALSE; - } - - return EMMC_SUCCESS; -} -static inline void emmc_set_retry_count(uint32_t retry) -{ - mmc_drv_obj.retries_after_fail = retry; -} - -static inline void emmc_set_data_timeout(uint32_t data_timeout) -{ - mmc_drv_obj.data_timeout = data_timeout; -} - -static void emmc_memset(uint8_t *buff, uint8_t data, uint32_t cnt) -{ - if (buff == NULL) { - return; - } - - while (cnt > 0) { - *buff++ = data; - cnt--; - } -} - -static void emmc_driver_config(void) -{ - emmc_set_retry_count(EMMC_RETRY_COUNT); - emmc_set_data_timeout(EMMC_RW_DATA_TIMEOUT); -} - -static void emmc_drv_init(void) -{ - emmc_memset((uint8_t *) (&mmc_drv_obj), 0, sizeof(st_mmc_base)); - mmc_drv_obj.card_present = HAL_MEMCARD_CARD_IS_IN; - mmc_drv_obj.data_timeout = EMMC_RW_DATA_TIMEOUT; - mmc_drv_obj.bus_width = HAL_MEMCARD_DATA_WIDTH_1_BIT; -} - -static EMMC_ERROR_CODE emmc_dev_finalize(void) -{ - EMMC_ERROR_CODE result; - uint32_t dataL; - - /* - * MMC power off - * the power supply of eMMC device is always turning on. - * RST_n : Hi --> Low level. - */ - result = rcar_emmc_memcard_power(FALSE); - - /* host controller reset */ - SETR_32(SD_INFO1, 0x00000000U); /* all interrupt clear */ - SETR_32(SD_INFO2, SD_INFO2_CLEAR); /* all interrupt clear */ - SETR_32(SD_INFO1_MASK, 0x00000000U); /* all interrupt disable */ - SETR_32(SD_INFO2_MASK, SD_INFO2_CLEAR); /* all interrupt disable */ - SETR_32(SD_CLK_CTRL, 0x00000000U); /* MMC clock stop */ - - dataL = mmio_read_32(CPG_SMSTPCR3); - if ((dataL & CPG_MSTP_MMC) == 0U) { - dataL |= (CPG_MSTP_MMC); - mmio_write_32(CPG_CPGWPR, (~dataL)); - mmio_write_32(CPG_SMSTPCR3, dataL); - } - - return result; -} - -static EMMC_ERROR_CODE emmc_dev_init(void) -{ - /* Enable clock supply to eMMC. */ - mstpcr_write(CPG_SMSTPCR3, CPG_MSTPSR3, CPG_MSTP_MMC); - - /* Set SD clock */ - mmio_write_32(CPG_CPGWPR, ~((uint32_t) (BIT9 | BIT0))); /* SD phy 200MHz */ - - /* Stop SDnH clock & SDn=200MHz */ - mmio_write_32(CPG_SDxCKCR, (BIT9 | BIT0)); - - /* MMCIF initialize */ - SETR_32(SD_INFO1, 0x00000000U); /* all interrupt clear */ - SETR_32(SD_INFO2, SD_INFO2_CLEAR); /* all interrupt clear */ - SETR_32(SD_INFO1_MASK, 0x00000000U); /* all interrupt disable */ - SETR_32(SD_INFO2_MASK, SD_INFO2_CLEAR); /* all interrupt disable */ - - SETR_32(HOST_MODE, 0x00000000U); /* SD_BUF access width = 64-bit */ - SETR_32(SD_OPTION, 0x0000C0EEU); /* Bus width = 1bit, timeout=MAX */ - SETR_32(SD_CLK_CTRL, 0x00000000U); /* Disable Automatic Control & Clock Output */ - - return EMMC_SUCCESS; -} - -static EMMC_ERROR_CODE emmc_reset_controller(void) -{ - EMMC_ERROR_CODE result; - - /* initialize mmc driver */ - emmc_drv_init(); - - /* initialize H/W */ - result = emmc_dev_init(); - if (result == EMMC_SUCCESS) { - mmc_drv_obj.initialize = TRUE; - } - - return result; - -} - -EMMC_ERROR_CODE emmc_terminate(void) -{ - EMMC_ERROR_CODE result; - - result = emmc_dev_finalize(); - - emmc_memset((uint8_t *) (&mmc_drv_obj), 0, sizeof(st_mmc_base)); - - return result; -} - -EMMC_ERROR_CODE rcar_emmc_init(void) -{ - EMMC_ERROR_CODE result; - - result = emmc_reset_controller(); - if (result == EMMC_SUCCESS) { - emmc_driver_config(); - } - - return result; -} diff --git a/drivers/renesas/rcar/emmc/emmc_interrupt.c b/drivers/renesas/rcar/emmc/emmc_interrupt.c deleted file mode 100644 index 092fdfb72..000000000 --- a/drivers/renesas/rcar/emmc/emmc_interrupt.c +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights - * reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include - -#include "emmc_config.h" -#include "emmc_def.h" -#include "emmc_hal.h" -#include "emmc_registers.h" -#include "emmc_std.h" -#include "rcar_def.h" - -static EMMC_ERROR_CODE emmc_trans_sector(uint32_t *buff_address_virtual); - -uint32_t emmc_interrupt(void) -{ - EMMC_ERROR_CODE result; - uint32_t prr_data; - uint32_t cut_ver; - uint32_t end_bit; - - prr_data = mmio_read_32((uintptr_t) RCAR_PRR); - cut_ver = prr_data & PRR_CUT_MASK; - if ((prr_data & PRR_PRODUCT_MASK) == PRR_PRODUCT_H3) { - if (cut_ver == PRR_PRODUCT_10) { - end_bit = BIT17; - } else if (cut_ver == PRR_PRODUCT_11) { - end_bit = BIT17; - } else { - end_bit = BIT20; - } - } else if ((prr_data & PRR_PRODUCT_MASK) == PRR_PRODUCT_M3) { - if (cut_ver == PRR_PRODUCT_10) { - end_bit = BIT17; - } else { - end_bit = BIT20; - } - } else { - end_bit = BIT20; - } - - /* SD_INFO */ - mmc_drv_obj.error_info.info1 = GETR_32(SD_INFO1); - mmc_drv_obj.error_info.info2 = GETR_32(SD_INFO2); - - /* SD_INFO EVENT */ - mmc_drv_obj.int_event1 = - mmc_drv_obj.error_info.info1 & GETR_32(SD_INFO1_MASK); - mmc_drv_obj.int_event2 = - mmc_drv_obj.error_info.info2 & GETR_32(SD_INFO2_MASK); - - /* ERR_STS */ - mmc_drv_obj.error_info.status1 = GETR_32(SD_ERR_STS1); - mmc_drv_obj.error_info.status2 = GETR_32(SD_ERR_STS2); - - /* DM_CM_INFO */ - mmc_drv_obj.error_info.dm_info1 = GETR_32(DM_CM_INFO1); - mmc_drv_obj.error_info.dm_info2 = GETR_32(DM_CM_INFO2); - - /* DM_CM_INFO EVENT */ - mmc_drv_obj.dm_event1 = - mmc_drv_obj.error_info.dm_info1 & GETR_32(DM_CM_INFO1_MASK); - mmc_drv_obj.dm_event2 = - mmc_drv_obj.error_info.dm_info2 & GETR_32(DM_CM_INFO2_MASK); - - /* ERR SD_INFO2 */ - if ((SD_INFO2_ALL_ERR & mmc_drv_obj.int_event2) != 0) { - SETR_32(SD_INFO1_MASK, 0x00000000U); /* interrupt disable */ - SETR_32(SD_INFO2_MASK, SD_INFO2_CLEAR); /* interrupt disable */ - SETR_32(SD_INFO1, 0x00000000U); /* interrupt clear */ - SETR_32(SD_INFO2, SD_INFO2_CLEAR); /* interrupt clear */ - mmc_drv_obj.state_machine_blocking = FALSE; - } - - /* PIO Transfer */ - /* BWE/BRE */ - else if (((SD_INFO2_BWE | SD_INFO2_BRE) & mmc_drv_obj.int_event2)) { - /* BWE */ - if (SD_INFO2_BWE & mmc_drv_obj.int_event2) { - SETR_32(SD_INFO2, (GETR_32(SD_INFO2) & ~SD_INFO2_BWE)); - } - /* BRE */ - else { - SETR_32(SD_INFO2, (GETR_32(SD_INFO2) & ~SD_INFO2_BRE)); - } - - result = emmc_trans_sector(mmc_drv_obj.buff_address_virtual); - mmc_drv_obj.buff_address_virtual += EMMC_BLOCK_LENGTH; - mmc_drv_obj.remain_size -= EMMC_BLOCK_LENGTH; - - if (result != EMMC_SUCCESS) { - /* data transfer error */ - emmc_write_error_info(EMMC_FUNCNO_NONE, result); - - /* Panic */ - SETR_32(SD_INFO1_MASK, 0x00000000U); - SETR_32(SD_INFO2_MASK, SD_INFO2_CLEAR); - SETR_32(SD_INFO1, 0x00000000U); - /* interrupt clear */ - SETR_32(SD_INFO2, SD_INFO2_CLEAR); - mmc_drv_obj.force_terminate = TRUE; - } else { - mmc_drv_obj.during_transfer = FALSE; - } - mmc_drv_obj.state_machine_blocking = FALSE; - } - - /* DMA_TRANSFER */ - /* DM_CM_INFO1: DMA-ch0 transfer complete or error occurred */ - else if ((BIT16 & mmc_drv_obj.dm_event1) != 0) { - SETR_32(DM_CM_INFO1, 0x00000000U); - SETR_32(DM_CM_INFO2, 0x00000000U); - /* interrupt clear */ - SETR_32(SD_INFO2, (GETR_32(SD_INFO2) & ~SD_INFO2_BWE)); - /* DM_CM_INFO2: DMA-ch0 error occurred */ - if ((BIT16 & mmc_drv_obj.dm_event2) != 0) { - mmc_drv_obj.dma_error_flag = TRUE; - } else { - mmc_drv_obj.during_dma_transfer = FALSE; - mmc_drv_obj.during_transfer = FALSE; - } - /* wait next interrupt */ - mmc_drv_obj.state_machine_blocking = FALSE; - } - /* DM_CM_INFO1: DMA-ch1 transfer complete or error occurred */ - else if ((end_bit & mmc_drv_obj.dm_event1) != 0U) { - SETR_32(DM_CM_INFO1, 0x00000000U); - SETR_32(DM_CM_INFO2, 0x00000000U); - /* interrupt clear */ - SETR_32(SD_INFO2, (GETR_32(SD_INFO2) & ~SD_INFO2_BRE)); - /* DM_CM_INFO2: DMA-ch1 error occurred */ - if ((BIT17 & mmc_drv_obj.dm_event2) != 0) { - mmc_drv_obj.dma_error_flag = TRUE; - } else { - mmc_drv_obj.during_dma_transfer = FALSE; - mmc_drv_obj.during_transfer = FALSE; - } - /* wait next interrupt */ - mmc_drv_obj.state_machine_blocking = FALSE; - } - - /* Response end */ - else if ((SD_INFO1_INFO0 & mmc_drv_obj.int_event1) != 0) { - /* interrupt clear */ - SETR_32(SD_INFO1, (GETR_32(SD_INFO1) & ~SD_INFO1_INFO0)); - mmc_drv_obj.state_machine_blocking = FALSE; - } - /* Access end */ - else if ((SD_INFO1_INFO2 & mmc_drv_obj.int_event1) != 0) { - /* interrupt clear */ - SETR_32(SD_INFO1, (GETR_32(SD_INFO1) & ~SD_INFO1_INFO2)); - mmc_drv_obj.state_machine_blocking = FALSE; - } else { - /* nothing to do. */ - } - - return (uint32_t) 0; -} - -static EMMC_ERROR_CODE emmc_trans_sector(uint32_t *buff_address_virtual) -{ - uint32_t length, i; - uint64_t *bufPtrLL; - - if (buff_address_virtual == NULL) { - return EMMC_ERR_PARAM; - } - - if ((mmc_drv_obj.during_transfer != TRUE) - || (mmc_drv_obj.remain_size == 0)) { - return EMMC_ERR_STATE; - } - - bufPtrLL = (uint64_t *) buff_address_virtual; - length = mmc_drv_obj.remain_size; - - /* data transefer */ - for (i = 0; i < (length >> 3); i++) { - /* Write */ - if (mmc_drv_obj.cmd_info.dir == HAL_MEMCARD_WRITE) { - SETR_64(SD_BUF0, *bufPtrLL); /* buffer --> FIFO */ - } - /* Read */ - else { - /* Checks when the read data reaches SD_SIZE. */ - /* The BRE bit is cleared at emmc_interrupt function. */ - if (((i % - (uint32_t) (EMMC_BLOCK_LENGTH >> - EMMC_BUF_SIZE_SHIFT)) == 0U) - && (i != 0U)) { - /* BRE check */ - while (((GETR_32(SD_INFO2)) & SD_INFO2_BRE) == - 0U) { - /* ERROR check */ - if (((GETR_32(SD_INFO2)) & - SD_INFO2_ALL_ERR) != 0U) { - return EMMC_ERR_TRANSFER; - } - } - /* BRE clear */ - SETR_32(SD_INFO2, - (uint32_t) (GETR_32(SD_INFO2) & - ~SD_INFO2_BRE)); - } - *bufPtrLL = GETR_64(SD_BUF0); /* FIFO --> buffer */ - } - bufPtrLL++; - } - - return EMMC_SUCCESS; -} diff --git a/drivers/renesas/rcar/emmc/emmc_mount.c b/drivers/renesas/rcar/emmc/emmc_mount.c deleted file mode 100644 index e04afd4cf..000000000 --- a/drivers/renesas/rcar/emmc/emmc_mount.c +++ /dev/null @@ -1,686 +0,0 @@ -/* - * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include - -#include "emmc_config.h" -#include "emmc_def.h" -#include "emmc_hal.h" -#include "emmc_registers.h" -#include "emmc_std.h" -#include "micro_delay.h" -#include "rcar_def.h" - -static EMMC_ERROR_CODE emmc_clock_ctrl(uint8_t mode); -static EMMC_ERROR_CODE emmc_card_init(void); -static EMMC_ERROR_CODE emmc_high_speed(void); -static EMMC_ERROR_CODE emmc_bus_width(uint32_t width); -static uint32_t emmc_set_timeout_register_value(uint32_t freq); -static void set_sd_clk(uint32_t clkDiv); -static uint32_t emmc_calc_tran_speed(uint32_t *freq); -static void emmc_get_partition_access(void); -static void emmc_set_bootpartition(void); - -static void emmc_set_bootpartition(void) -{ - uint32_t reg; - - reg = mmio_read_32(RCAR_PRR) & (PRR_PRODUCT_MASK | PRR_CUT_MASK); - if (reg == PRR_PRODUCT_M3_CUT10) { - mmc_drv_obj.boot_partition_en = - (EMMC_PARTITION_ID) ((mmc_drv_obj.ext_csd_data[179] & - EMMC_BOOT_PARTITION_EN_MASK) >> - EMMC_BOOT_PARTITION_EN_SHIFT); - } else if ((reg == PRR_PRODUCT_H3_CUT20) - || (reg == PRR_PRODUCT_M3_CUT11)) { - mmc_drv_obj.boot_partition_en = mmc_drv_obj.partition_access; - } else { - if ((mmio_read_32(MFISBTSTSR) & MFISBTSTSR_BOOT_PARTITION) != - 0U) { - mmc_drv_obj.boot_partition_en = PARTITION_ID_BOOT_2; - } else { - mmc_drv_obj.boot_partition_en = PARTITION_ID_BOOT_1; - } - } -} - -static EMMC_ERROR_CODE emmc_card_init(void) -{ - int32_t retry; - uint32_t freq = MMC_400KHZ; /* 390KHz */ - EMMC_ERROR_CODE result; - uint32_t result_calc; - - /* state check */ - if ((mmc_drv_obj.initialize != TRUE) - || (mmc_drv_obj.card_power_enable != TRUE) - || ((GETR_32(SD_INFO2) & SD_INFO2_CBSY) != 0) - ) { - emmc_write_error_info(EMMC_FUNCNO_CARD_INIT, EMMC_ERR_STATE); - return EMMC_ERR_STATE; - } - - /* clock on (force change) */ - mmc_drv_obj.current_freq = 0; - mmc_drv_obj.max_freq = MMC_20MHZ; - result = emmc_set_request_mmc_clock(&freq); - if (result != EMMC_SUCCESS) { - emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT); - return EMMC_ERR; - } - - rcar_micro_delay(1000U); /* wait 1ms */ - - /* Get current access partition */ - emmc_get_partition_access(); - - /* CMD0, arg=0x00000000 */ - result = emmc_send_idle_cmd(0x00000000); - if (result != EMMC_SUCCESS) { - emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT); - return result; - } - - rcar_micro_delay(200U); /* wait 74clock 390kHz(189.74us) */ - - /* CMD1 */ - emmc_make_nontrans_cmd(CMD1_SEND_OP_COND, EMMC_HOST_OCR_VALUE); - for (retry = 300; retry > 0; retry--) { - result = - emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); - if (result != EMMC_SUCCESS) { - emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT); - return result; - } - - if ((mmc_drv_obj.r3_ocr & EMMC_OCR_STATUS_BIT) != 0) { - break; /* card is ready. exit loop */ - } - rcar_micro_delay(1000U); /* wait 1ms */ - } - - if (retry == 0) { - emmc_write_error_info(EMMC_FUNCNO_CARD_INIT, EMMC_ERR_TIMEOUT); - return EMMC_ERR_TIMEOUT; - } - - switch (mmc_drv_obj.r3_ocr & EMMC_OCR_ACCESS_MODE_MASK) { - case EMMC_OCR_ACCESS_MODE_SECT: - mmc_drv_obj.access_mode = TRUE; /* sector mode */ - break; - default: - /* unknown value */ - emmc_write_error_info(EMMC_FUNCNO_CARD_INIT, EMMC_ERR); - return EMMC_ERR; - } - - /* CMD2 */ - emmc_make_nontrans_cmd(CMD2_ALL_SEND_CID_MMC, 0x00000000); - mmc_drv_obj.response = (uint32_t *) (&mmc_drv_obj.cid_data[0]); /* use CID special buffer */ - result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); - if (result != EMMC_SUCCESS) { - emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT); - return result; - } - - /* CMD3 */ - emmc_make_nontrans_cmd(CMD3_SET_RELATIVE_ADDR, EMMC_RCA << 16); - result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); - if (result != EMMC_SUCCESS) { - emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT); - return result; - } - - /* CMD9 (CSD) */ - emmc_make_nontrans_cmd(CMD9_SEND_CSD, EMMC_RCA << 16); - mmc_drv_obj.response = (uint32_t *) (&mmc_drv_obj.csd_data[0]); /* use CSD special buffer */ - result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); - if (result != EMMC_SUCCESS) { - emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT); - return result; - } - - /* card version check */ - if (EMMC_CSD_SPEC_VARS() < 4) { - emmc_write_error_info(EMMC_FUNCNO_CARD_INIT, - EMMC_ERR_ILLEGAL_CARD); - return EMMC_ERR_ILLEGAL_CARD; - } - - /* CMD7 (select card) */ - emmc_make_nontrans_cmd(CMD7_SELECT_CARD, EMMC_RCA << 16); - result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); - if (result != EMMC_SUCCESS) { - emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT); - return result; - } - - mmc_drv_obj.selected = TRUE; - - /* - * card speed check - * Card spec is calculated from TRAN_SPEED(CSD) - */ - result_calc = emmc_calc_tran_speed(&freq); - if (result_calc == 0) { - emmc_write_error_info(EMMC_FUNCNO_CARD_INIT, - EMMC_ERR_ILLEGAL_CARD); - return EMMC_ERR_ILLEGAL_CARD; - } - mmc_drv_obj.max_freq = freq; /* max frequency (card spec) */ - - result = emmc_set_request_mmc_clock(&freq); - if (result != EMMC_SUCCESS) { - emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT); - return EMMC_ERR; - } - - /* set read/write timeout */ - mmc_drv_obj.data_timeout = emmc_set_timeout_register_value(freq); - SETR_32(SD_OPTION, - ((GETR_32(SD_OPTION) & ~(SD_OPTION_TIMEOUT_CNT_MASK)) | - mmc_drv_obj.data_timeout)); - - /* SET_BLOCKLEN(512byte) */ - /* CMD16 */ - emmc_make_nontrans_cmd(CMD16_SET_BLOCKLEN, EMMC_BLOCK_LENGTH); - result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); - if (result != EMMC_SUCCESS) { - emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT); - return result; - } - - /* Transfer Data Length */ - SETR_32(SD_SIZE, EMMC_BLOCK_LENGTH); - - /* CMD8 (EXT_CSD) */ - emmc_make_trans_cmd(CMD8_SEND_EXT_CSD, 0x00000000, - (uint32_t *) (&mmc_drv_obj.ext_csd_data[0]), - EMMC_MAX_EXT_CSD_LENGTH, HAL_MEMCARD_READ, - HAL_MEMCARD_NOT_DMA); - result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); - if (result != EMMC_SUCCESS) { - /* - * CMD12 is not send. - * If BUS initialization is failed, user must be execute Bus initialization again. - * Bus initialization is start CMD0(soft reset command). - */ - emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT); - return result; - } - - /* Set boot partition */ - emmc_set_bootpartition(); - - return EMMC_SUCCESS; -} - -static EMMC_ERROR_CODE emmc_high_speed(void) -{ - uint32_t freq; /* High speed mode clock frequency */ - EMMC_ERROR_CODE result; - uint8_t cardType; - - /* state check */ - if (mmc_drv_obj.selected != TRUE) { - emmc_write_error_info(EMMC_FUNCNO_HIGH_SPEED, EMMC_ERR_STATE); - return EMMC_ERR_STATE; - } - - /* max frequency */ - cardType = (uint8_t) mmc_drv_obj.ext_csd_data[EMMC_EXT_CSD_CARD_TYPE]; - if ((cardType & EMMC_EXT_CSD_CARD_TYPE_52MHZ) != 0) - freq = MMC_52MHZ; - else if ((cardType & EMMC_EXT_CSD_CARD_TYPE_26MHZ) != 0) - freq = MMC_26MHZ; - else - freq = MMC_20MHZ; - - /* Hi-Speed-mode selection */ - if ((freq == MMC_52MHZ) || (freq == MMC_26MHZ)) { - /* CMD6 */ - emmc_make_nontrans_cmd(CMD6_SWITCH, EMMC_SWITCH_HS_TIMING); - result = - emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); - if (result != EMMC_SUCCESS) { - emmc_write_error_info_func_no(EMMC_FUNCNO_HIGH_SPEED); - return result; - } - - mmc_drv_obj.hs_timing = TIMING_HIGH_SPEED; /* High-Speed */ - } - - /* set mmc clock */ - mmc_drv_obj.max_freq = freq; - result = emmc_set_request_mmc_clock(&freq); - if (result != EMMC_SUCCESS) { - emmc_write_error_info_func_no(EMMC_FUNCNO_HIGH_SPEED); - return EMMC_ERR; - } - - /* set read/write timeout */ - mmc_drv_obj.data_timeout = emmc_set_timeout_register_value(freq); - SETR_32(SD_OPTION, - ((GETR_32(SD_OPTION) & ~(SD_OPTION_TIMEOUT_CNT_MASK)) | - mmc_drv_obj.data_timeout)); - - /* CMD13 */ - emmc_make_nontrans_cmd(CMD13_SEND_STATUS, EMMC_RCA << 16); - result = - emmc_exec_cmd(EMMC_R1_ERROR_MASK_WITHOUT_CRC, mmc_drv_obj.response); - if (result != EMMC_SUCCESS) { - emmc_write_error_info_func_no(EMMC_FUNCNO_HIGH_SPEED); - return result; - } - - return EMMC_SUCCESS; -} - -static EMMC_ERROR_CODE emmc_clock_ctrl(uint8_t mode) -{ - uint32_t value; - - /* busy check */ - if ((GETR_32(SD_INFO2) & SD_INFO2_CBSY) != 0) { - emmc_write_error_info(EMMC_FUNCNO_SET_CLOCK, - EMMC_ERR_CARD_BUSY); - return EMMC_ERR; - } - - if (mode == TRUE) { - /* clock ON */ - value = - ((GETR_32(SD_CLK_CTRL) | MMC_SD_CLK_START) & - SD_CLK_WRITE_MASK); - SETR_32(SD_CLK_CTRL, value); /* on */ - mmc_drv_obj.clock_enable = TRUE; - } else { - /* clock OFF */ - value = - ((GETR_32(SD_CLK_CTRL) & MMC_SD_CLK_STOP) & - SD_CLK_WRITE_MASK); - SETR_32(SD_CLK_CTRL, value); /* off */ - mmc_drv_obj.clock_enable = FALSE; - } - - return EMMC_SUCCESS; -} - -static EMMC_ERROR_CODE emmc_bus_width(uint32_t width) -{ - EMMC_ERROR_CODE result = EMMC_ERR; - - /* parameter check */ - if ((width != 8) && (width != 4) && (width != 1)) { - emmc_write_error_info(EMMC_FUNCNO_BUS_WIDTH, EMMC_ERR_PARAM); - return EMMC_ERR_PARAM; - } - - /* state check */ - if (mmc_drv_obj.selected != TRUE) { - emmc_write_error_info(EMMC_FUNCNO_BUS_WIDTH, EMMC_ERR_STATE); - return EMMC_ERR_STATE; - } - - /* 2 = 8bit, 1 = 4bit, 0 =1bit */ - mmc_drv_obj.bus_width = (HAL_MEMCARD_DATA_WIDTH) (width >> 2); - - /* CMD6 */ - emmc_make_nontrans_cmd(CMD6_SWITCH, - (EMMC_SWITCH_BUS_WIDTH_1 | - (mmc_drv_obj.bus_width << 8))); - result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); - if (result != EMMC_SUCCESS) { - /* occurred error */ - mmc_drv_obj.bus_width = HAL_MEMCARD_DATA_WIDTH_1_BIT; - goto EXIT; - } - - switch (mmc_drv_obj.bus_width) { - case HAL_MEMCARD_DATA_WIDTH_1_BIT: - SETR_32(SD_OPTION, - ((GETR_32(SD_OPTION) & ~(BIT15 | BIT13)) | BIT15)); - break; - case HAL_MEMCARD_DATA_WIDTH_4_BIT: - SETR_32(SD_OPTION, (GETR_32(SD_OPTION) & ~(BIT15 | BIT13))); - break; - case HAL_MEMCARD_DATA_WIDTH_8_BIT: - SETR_32(SD_OPTION, - ((GETR_32(SD_OPTION) & ~(BIT15 | BIT13)) | BIT13)); - break; - default: - goto EXIT; - } - - /* CMD13 */ - emmc_make_nontrans_cmd(CMD13_SEND_STATUS, EMMC_RCA << 16); - result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); - if (result != EMMC_SUCCESS) { - goto EXIT; - } - - /* CMD8 (EXT_CSD) */ - emmc_make_trans_cmd(CMD8_SEND_EXT_CSD, 0x00000000, - (uint32_t *) (&mmc_drv_obj.ext_csd_data[0]), - EMMC_MAX_EXT_CSD_LENGTH, HAL_MEMCARD_READ, - HAL_MEMCARD_NOT_DMA); - result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); - if (result != EMMC_SUCCESS) { - goto EXIT; - } - - return EMMC_SUCCESS; - -EXIT: - emmc_write_error_info(EMMC_FUNCNO_BUS_WIDTH, result); - ERROR("BL2: emmc bus_width error end\n"); - return result; -} - -EMMC_ERROR_CODE emmc_select_partition(EMMC_PARTITION_ID id) -{ - EMMC_ERROR_CODE result; - uint32_t arg; - uint32_t partition_config; - - /* state check */ - if (mmc_drv_obj.mount != TRUE) { - emmc_write_error_info(EMMC_FUNCNO_NONE, EMMC_ERR_STATE); - return EMMC_ERR_STATE; - } - - /* id = PARTITION_ACCESS(Bit[2:0]) */ - if ((id & ~PARTITION_ID_MASK) != 0) { - emmc_write_error_info(EMMC_FUNCNO_NONE, EMMC_ERR_PARAM); - return EMMC_ERR_PARAM; - } - - /* EXT_CSD[179] value */ - partition_config = - (uint32_t) mmc_drv_obj.ext_csd_data[EMMC_EXT_CSD_PARTITION_CONFIG]; - if ((partition_config & PARTITION_ID_MASK) == id) { - result = EMMC_SUCCESS; - } else { - - partition_config = - (uint32_t) ((partition_config & ~PARTITION_ID_MASK) | id); - arg = EMMC_SWITCH_PARTITION_CONFIG | (partition_config << 8); - - result = emmc_set_ext_csd(arg); - } - - return result; -} - -static void set_sd_clk(uint32_t clkDiv) -{ - uint32_t dataL; - - dataL = (GETR_32(SD_CLK_CTRL) & (~SD_CLK_CTRL_CLKDIV_MASK)); - - switch (clkDiv) { - case 1: - dataL |= 0x000000FFU; - break; /* 1/1 */ - case 2: - dataL |= 0x00000000U; - break; /* 1/2 */ - case 4: - dataL |= 0x00000001U; - break; /* 1/4 */ - case 8: - dataL |= 0x00000002U; - break; /* 1/8 */ - case 16: - dataL |= 0x00000004U; - break; /* 1/16 */ - case 32: - dataL |= 0x00000008U; - break; /* 1/32 */ - case 64: - dataL |= 0x00000010U; - break; /* 1/64 */ - case 128: - dataL |= 0x00000020U; - break; /* 1/128 */ - case 256: - dataL |= 0x00000040U; - break; /* 1/256 */ - case 512: - dataL |= 0x00000080U; - break; /* 1/512 */ - } - - SETR_32(SD_CLK_CTRL, dataL); - mmc_drv_obj.current_freq = (uint32_t) clkDiv; -} - -static void emmc_get_partition_access(void) -{ - uint32_t reg; - EMMC_ERROR_CODE result; - - reg = mmio_read_32(RCAR_PRR) & (PRR_PRODUCT_MASK | PRR_CUT_MASK); - if ((reg == PRR_PRODUCT_H3_CUT20) || (reg == PRR_PRODUCT_M3_CUT11)) { - SETR_32(SD_OPTION, 0x000060EEU); /* 8 bits width */ - /* CMD8 (EXT_CSD) */ - emmc_make_trans_cmd(CMD8_SEND_EXT_CSD, 0x00000000U, - (uint32_t *) (&mmc_drv_obj.ext_csd_data[0]), - EMMC_MAX_EXT_CSD_LENGTH, - HAL_MEMCARD_READ, HAL_MEMCARD_NOT_DMA); - mmc_drv_obj.get_partition_access_flag = TRUE; - result = - emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); - mmc_drv_obj.get_partition_access_flag = FALSE; - if (result == EMMC_SUCCESS) { - mmc_drv_obj.partition_access = - (EMMC_PARTITION_ID) (mmc_drv_obj.ext_csd_data[179] - & PARTITION_ID_MASK); - } else if (result == EMMC_ERR_CMD_TIMEOUT) { - mmc_drv_obj.partition_access = PARTITION_ID_BOOT_1; - } else { - emmc_write_error_info(EMMC_FUNCNO_GET_PERTITION_ACCESS, - result); - panic(); - } - SETR_32(SD_OPTION, 0x0000C0EEU); /* Initialize */ - } -} - -static uint32_t emmc_calc_tran_speed(uint32_t *freq) -{ - const uint32_t unit[8] = { 10000U, 100000U, 1000000U, 10000000U, - 0U, 0U, 0U, 0U }; /* frequency unit (1/10) */ - const uint32_t mult[16] = { 0U, 10U, 12U, 13U, 15U, 20U, 26U, 30U, 35U, - 40U, 45U, 52U, 55U, 60U, 70U, 80U }; - uint32_t tran_speed = EMMC_CSD_TRAN_SPEED(); - uint32_t max_freq; - uint32_t result; - - /* - * tran_speed = 0x32 - * unit[tran_speed&0x7] = uint[0x2] = 1000000 - * mult[(tran_speed&0x78)>>3] = mult[0x30>>3] = mult[6] = 26 - * 1000000 * 26 = 26000000 (26MHz) - */ - - result = 1; - max_freq = - unit[tran_speed & EMMC_TRANSPEED_FREQ_UNIT_MASK] * - mult[(tran_speed & EMMC_TRANSPEED_MULT_MASK) >> - EMMC_TRANSPEED_MULT_SHIFT]; - - if (max_freq == 0) { - result = 0; - } else if (max_freq >= MMC_FREQ_52MHZ) { - *freq = MMC_52MHZ; - } else if (max_freq >= MMC_FREQ_26MHZ) { - *freq = MMC_26MHZ; - } else if (max_freq >= MMC_FREQ_20MHZ) { - *freq = MMC_20MHZ; - } else { - *freq = MMC_400KHZ; - } - - return result; -} - -static uint32_t emmc_set_timeout_register_value(uint32_t freq) -{ - uint32_t timeout_cnt; /* SD_OPTION - Timeout Counter */ - - switch (freq) { - case 1U: - timeout_cnt = 0xE0U; - break; /* SDCLK * 2^27 */ - case 2U: - timeout_cnt = 0xE0U; - break; /* SDCLK * 2^27 */ - case 4U: - timeout_cnt = 0xD0U; - break; /* SDCLK * 2^26 */ - case 8U: - timeout_cnt = 0xC0U; - break; /* SDCLK * 2^25 */ - case 16U: - timeout_cnt = 0xB0U; - break; /* SDCLK * 2^24 */ - case 32U: - timeout_cnt = 0xA0U; - break; /* SDCLK * 2^23 */ - case 64U: - timeout_cnt = 0x90U; - break; /* SDCLK * 2^22 */ - case 128U: - timeout_cnt = 0x80U; - break; /* SDCLK * 2^21 */ - case 256U: - timeout_cnt = 0x70U; - break; /* SDCLK * 2^20 */ - case 512U: - timeout_cnt = 0x70U; - break; /* SDCLK * 2^20 */ - default: - timeout_cnt = 0xE0U; - break; /* SDCLK * 2^27 */ - } - - return timeout_cnt; -} - -EMMC_ERROR_CODE emmc_set_ext_csd(uint32_t arg) -{ - EMMC_ERROR_CODE result; - - /* CMD6 */ - emmc_make_nontrans_cmd(CMD6_SWITCH, arg); - result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); - if (result != EMMC_SUCCESS) { - return result; - } - - /* CMD13 */ - emmc_make_nontrans_cmd(CMD13_SEND_STATUS, EMMC_RCA << 16); - result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); - if (result != EMMC_SUCCESS) { - return result; - } - - /* CMD8 (EXT_CSD) */ - emmc_make_trans_cmd(CMD8_SEND_EXT_CSD, 0x00000000, - (uint32_t *) (&mmc_drv_obj.ext_csd_data[0]), - EMMC_MAX_EXT_CSD_LENGTH, HAL_MEMCARD_READ, - HAL_MEMCARD_NOT_DMA); - result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); - if (result != EMMC_SUCCESS) { - return result; - } - return EMMC_SUCCESS; -} - -EMMC_ERROR_CODE emmc_set_request_mmc_clock(uint32_t *freq) -{ - /* parameter check */ - if (freq == NULL) { - emmc_write_error_info(EMMC_FUNCNO_SET_CLOCK, EMMC_ERR_PARAM); - return EMMC_ERR_PARAM; - } - - /* state check */ - if ((mmc_drv_obj.initialize != TRUE) - || (mmc_drv_obj.card_power_enable != TRUE)) { - emmc_write_error_info(EMMC_FUNCNO_SET_CLOCK, EMMC_ERR_STATE); - return EMMC_ERR_STATE; - } - - /* clock is already running in the desired frequency. */ - if ((mmc_drv_obj.clock_enable == TRUE) - && (mmc_drv_obj.current_freq == *freq)) { - return EMMC_SUCCESS; - } - - /* busy check */ - if ((GETR_32(SD_INFO2) & SD_INFO2_CBSY) != 0) { - emmc_write_error_info(EMMC_FUNCNO_SET_CLOCK, - EMMC_ERR_CARD_BUSY); - return EMMC_ERR; - } - - set_sd_clk(*freq); - mmc_drv_obj.clock_enable = FALSE; - - return emmc_clock_ctrl(TRUE); /* clock on */ -} - -EMMC_ERROR_CODE rcar_emmc_mount(void) -{ - EMMC_ERROR_CODE result; - - /* state check */ - if ((mmc_drv_obj.initialize != TRUE) - || (mmc_drv_obj.card_power_enable != TRUE) - || ((GETR_32(SD_INFO2) & SD_INFO2_CBSY) != 0) - ) { - emmc_write_error_info(EMMC_FUNCNO_MOUNT, EMMC_ERR_STATE); - return EMMC_ERR_STATE; - } - - /* initialize card (IDLE state --> Transfer state) */ - result = emmc_card_init(); - if (result != EMMC_SUCCESS) { - emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT); - if (emmc_clock_ctrl(FALSE) != EMMC_SUCCESS) { - /* nothing to do. */ - } - return result; - } - - /* Switching high speed mode */ - result = emmc_high_speed(); - if (result != EMMC_SUCCESS) { - emmc_write_error_info_func_no(EMMC_FUNCNO_HIGH_SPEED); - if (emmc_clock_ctrl(FALSE) != EMMC_SUCCESS) { - /* nothing to do. */ - } - return result; - } - - /* Changing the data bus width */ - result = emmc_bus_width(8); - if (result != EMMC_SUCCESS) { - emmc_write_error_info_func_no(EMMC_FUNCNO_BUS_WIDTH); - if (emmc_clock_ctrl(FALSE) != EMMC_SUCCESS) { - /* nothing to do. */ - } - return result; - } - - /* mount complete */ - mmc_drv_obj.mount = TRUE; - - return EMMC_SUCCESS; -} diff --git a/drivers/renesas/rcar/emmc/emmc_read.c b/drivers/renesas/rcar/emmc/emmc_read.c deleted file mode 100644 index 96e73ca56..000000000 --- a/drivers/renesas/rcar/emmc/emmc_read.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include "emmc_config.h" -#include "emmc_def.h" -#include "emmc_hal.h" -#include "emmc_registers.h" -#include "emmc_std.h" - -#define MIN_EMMC(a, b) (((a) < (b)) ? (a) : (b)) -#define EMMC_RW_SECTOR_COUNT_MAX 0x0000ffffU - -static EMMC_ERROR_CODE emmc_multiple_block_read(uint32_t *buff_address_virtual, - uint32_t sector_number, uint32_t count, - HAL_MEMCARD_DATA_TRANSFER_MODE transfer_mode) -{ - EMMC_ERROR_CODE result; - - /* parameter check */ - if ((count > EMMC_RW_SECTOR_COUNT_MAX) - || (count == 0) - || ((transfer_mode != HAL_MEMCARD_DMA) - && (transfer_mode != HAL_MEMCARD_NOT_DMA)) - ) { - emmc_write_error_info(EMMC_FUNCNO_READ_SECTOR, EMMC_ERR_PARAM); - return EMMC_ERR_PARAM; - } - - /* CMD23 */ - emmc_make_nontrans_cmd(CMD23_SET_BLOCK_COUNT, count); - result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); - if (result != EMMC_SUCCESS) { - return result; - } - SETR_32(SD_SECCNT, count); - SETR_32(SD_STOP, 0x00000100); - /* SD_BUF Read/Write DMA Transfer enable */ - SETR_32(CC_EXT_MODE, (CC_EXT_MODE_CLEAR | CC_EXT_MODE_DMASDRW_ENABLE)); - - /* CMD18 */ - emmc_make_trans_cmd(CMD18_READ_MULTIPLE_BLOCK, sector_number, - buff_address_virtual, - count << EMMC_SECTOR_SIZE_SHIFT, HAL_MEMCARD_READ, - transfer_mode); - result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); - if (result != EMMC_SUCCESS) { - return result; /* CMD18 error code */ - } - - /* CMD13 */ - emmc_make_nontrans_cmd(CMD13_SEND_STATUS, EMMC_RCA << 16); - result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); - if (result != EMMC_SUCCESS) { - return result; - } -#if RCAR_BL2_DCACHE == 1 - if (transfer_mode == HAL_MEMCARD_NOT_DMA) { - flush_dcache_range((uint64_t) buff_address_virtual, - ((size_t) count << EMMC_SECTOR_SIZE_SHIFT)); - } -#endif /* RCAR_BL2_DCACHE == 1 */ - - /* ready status check */ - if ((mmc_drv_obj.r1_card_status & EMMC_R1_READY) == 0) { - emmc_write_error_info(EMMC_FUNCNO_READ_SECTOR, - EMMC_ERR_CARD_BUSY); - return EMMC_ERR_CARD_BUSY; - } - - /* state check */ - if (mmc_drv_obj.current_state != EMMC_R1_STATE_TRAN) { - emmc_write_error_info(EMMC_FUNCNO_READ_SECTOR, - EMMC_ERR_CARD_STATE); - return EMMC_ERR_CARD_STATE; - } - - return EMMC_SUCCESS; -} - -EMMC_ERROR_CODE emmc_read_sector(uint32_t *buff_address_virtual, - uint32_t sector_number, - uint32_t count, uint32_t feature_flags) -{ - uint32_t trans_count; - uint32_t remain; - EMMC_ERROR_CODE result; - HAL_MEMCARD_DATA_TRANSFER_MODE transfer_mode; - - /* parameter check */ - if (count == 0) { - emmc_write_error_info(EMMC_FUNCNO_READ_SECTOR, EMMC_ERR_PARAM); - return EMMC_ERR_PARAM; - } - - /* state check */ - if (mmc_drv_obj.mount != TRUE) { - emmc_write_error_info(EMMC_FUNCNO_READ_SECTOR, EMMC_ERR_STATE); - return EMMC_ERR_STATE; - } - - /* DMA? */ - if ((feature_flags & LOADIMAGE_FLAGS_DMA_ENABLE) != 0) { - transfer_mode = HAL_MEMCARD_DMA; - } else { - transfer_mode = HAL_MEMCARD_NOT_DMA; - } - - remain = count; - while (remain != 0) { - trans_count = MIN_EMMC(remain, EMMC_RW_SECTOR_COUNT_MAX); - result = - emmc_multiple_block_read(buff_address_virtual, - sector_number, trans_count, - transfer_mode); - if (result != EMMC_SUCCESS) { - return result; - } - - buff_address_virtual += (EMMC_BLOCK_LENGTH_DW * trans_count); - sector_number += trans_count; - remain -= trans_count; - } - - return EMMC_SUCCESS; -} diff --git a/drivers/renesas/rcar/emmc/emmc_registers.h b/drivers/renesas/rcar/emmc/emmc_registers.h deleted file mode 100644 index ae689ca24..000000000 --- a/drivers/renesas/rcar/emmc/emmc_registers.h +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef EMMC_REGISTERS_H -#define EMMC_REGISTERS_H - -/* MMC channel select */ -#define MMC_CH0 (0U) /* SDHI2/MMC0 */ -#define MMC_CH1 (1U) /* SDHI3/MMC1 */ - -#if RCAR_LSI == RCAR_E3 -#define USE_MMC_CH (MMC_CH1) /* R-Car E3 */ -#else /* RCAR_LSI == RCAR_E3 */ -#define USE_MMC_CH (MMC_CH0) /* R-Car H3/M3/M3N */ -#endif /* RCAR_LSI == RCAR_E3 */ - -#define BIT0 (0x00000001U) -#define BIT1 (0x00000002U) -#define BIT2 (0x00000004U) -#define BIT3 (0x00000008U) -#define BIT4 (0x00000010U) -#define BIT5 (0x00000020U) -#define BIT6 (0x00000040U) -#define BIT7 (0x00000080U) -#define BIT8 (0x00000100U) -#define BIT9 (0x00000200U) -#define BIT10 (0x00000400U) -#define BIT11 (0x00000800U) -#define BIT12 (0x00001000U) -#define BIT13 (0x00002000U) -#define BIT14 (0x00004000U) -#define BIT15 (0x00008000U) -#define BIT16 (0x00010000U) -#define BIT17 (0x00020000U) -#define BIT18 (0x00040000U) -#define BIT19 (0x00080000U) -#define BIT20 (0x00100000U) -#define BIT21 (0x00200000U) -#define BIT22 (0x00400000U) -#define BIT23 (0x00800000U) -#define BIT24 (0x01000000U) -#define BIT25 (0x02000000U) -#define BIT26 (0x04000000U) -#define BIT27 (0x08000000U) -#define BIT28 (0x10000000U) -#define BIT29 (0x20000000U) -#define BIT30 (0x40000000U) -#define BIT31 (0x80000000U) - -/* Clock Pulse Generator (CPG) registers */ -#define CPG_BASE (0xE6150000U) -/* Module stop status register 3 */ -#define CPG_MSTPSR3 (CPG_BASE + 0x0048U) -/* System module stop control register 3 */ -#define CPG_SMSTPCR3 (CPG_BASE + 0x013CU) -/* SDHI2 clock frequency control register */ -#define CPG_SD2CKCR (CPG_BASE + 0x0268U) -/* SDHI3 clock frequency control register */ -#define CPG_SD3CKCR (CPG_BASE + 0x026CU) -/* CPG Write Protect Register */ -#define CPG_CPGWPR (CPG_BASE + 0x0900U) - -#if USE_MMC_CH == MMC_CH0 -#define CPG_SDxCKCR (CPG_SD2CKCR) /* SDHI2/MMC0 */ -#else /* USE_MMC_CH == MMC_CH0 */ -#define CPG_SDxCKCR (CPG_SD3CKCR) /* SDHI3/MMC1 */ -#endif /* USE_MMC_CH == MMC_CH0 */ - -/* Boot Status register */ -#define MFISBTSTSR (0xE6260604U) - -#define MFISBTSTSR_BOOT_PARTITION (0x00000010U) - -/* eMMC registers */ -#define MMC0_SD_BASE (0xEE140000U) -#define MMC1_SD_BASE (0xEE160000U) - -#if USE_MMC_CH == MMC_CH0 -#define MMC_SD_BASE (MMC0_SD_BASE) -#else /* USE_MMC_CH == MMC_CH0 */ -#define MMC_SD_BASE (MMC1_SD_BASE) -#endif /* USE_MMC_CH == MMC_CH0 */ - -#define SD_CMD (MMC_SD_BASE + 0x0000U) -#define SD_PORTSEL (MMC_SD_BASE + 0x0008U) -#define SD_ARG (MMC_SD_BASE + 0x0010U) -#define SD_ARG1 (MMC_SD_BASE + 0x0018U) -#define SD_STOP (MMC_SD_BASE + 0x0020U) -#define SD_SECCNT (MMC_SD_BASE + 0x0028U) -#define SD_RSP10 (MMC_SD_BASE + 0x0030U) -#define SD_RSP1 (MMC_SD_BASE + 0x0038U) -#define SD_RSP32 (MMC_SD_BASE + 0x0040U) -#define SD_RSP3 (MMC_SD_BASE + 0x0048U) -#define SD_RSP54 (MMC_SD_BASE + 0x0050U) -#define SD_RSP5 (MMC_SD_BASE + 0x0058U) -#define SD_RSP76 (MMC_SD_BASE + 0x0060U) -#define SD_RSP7 (MMC_SD_BASE + 0x0068U) -#define SD_INFO1 (MMC_SD_BASE + 0x0070U) -#define SD_INFO2 (MMC_SD_BASE + 0x0078U) -#define SD_INFO1_MASK (MMC_SD_BASE + 0x0080U) -#define SD_INFO2_MASK (MMC_SD_BASE + 0x0088U) -#define SD_CLK_CTRL (MMC_SD_BASE + 0x0090U) -#define SD_SIZE (MMC_SD_BASE + 0x0098U) -#define SD_OPTION (MMC_SD_BASE + 0x00A0U) -#define SD_ERR_STS1 (MMC_SD_BASE + 0x00B0U) -#define SD_ERR_STS2 (MMC_SD_BASE + 0x00B8U) -#define SD_BUF0 (MMC_SD_BASE + 0x00C0U) -#define SDIO_MODE (MMC_SD_BASE + 0x00D0U) -#define SDIO_INFO1 (MMC_SD_BASE + 0x00D8U) -#define SDIO_INFO1_MASK (MMC_SD_BASE + 0x00E0U) -#define CC_EXT_MODE (MMC_SD_BASE + 0x0360U) -#define SOFT_RST (MMC_SD_BASE + 0x0380U) -#define VERSION (MMC_SD_BASE + 0x0388U) -#define HOST_MODE (MMC_SD_BASE + 0x0390U) -#define DM_CM_DTRAN_MODE (MMC_SD_BASE + 0x0820U) -#define DM_CM_DTRAN_CTRL (MMC_SD_BASE + 0x0828U) -#define DM_CM_RST (MMC_SD_BASE + 0x0830U) -#define DM_CM_INFO1 (MMC_SD_BASE + 0x0840U) -#define DM_CM_INFO1_MASK (MMC_SD_BASE + 0x0848U) -#define DM_CM_INFO2 (MMC_SD_BASE + 0x0850U) -#define DM_CM_INFO2_MASK (MMC_SD_BASE + 0x0858U) -#define DM_DTRAN_ADDR (MMC_SD_BASE + 0x0880U) - -/* SD_INFO1 Registers */ -#define SD_INFO1_HPIRES 0x00010000UL /* Response Reception Completion */ -#define SD_INFO1_INFO10 0x00000400UL /* Indicates the SDDAT3 state */ -#define SD_INFO1_INFO9 0x00000200UL /* SDDAT3 Card Insertion */ -#define SD_INFO1_INFO8 0x00000100UL /* SDDAT3 Card Removal */ -#define SD_INFO1_INFO7 0x00000080UL /* Write Protect */ -#define SD_INFO1_INFO5 0x00000020UL /* Indicates the ISDCD state */ -#define SD_INFO1_INFO4 0x00000010UL /* ISDCD Card Insertion */ -#define SD_INFO1_INFO3 0x00000008UL /* ISDCD Card Removal */ -#define SD_INFO1_INFO2 0x00000004UL /* Access end */ -#define SD_INFO1_INFO0 0x00000001UL /* Response end */ - -/* SD_INFO2 Registers */ -#define SD_INFO2_ILA 0x00008000UL /* Illegal Access Error */ -#define SD_INFO2_CBSY 0x00004000UL /* Command Type Register Busy */ -#define SD_INFO2_SCLKDIVEN 0x00002000UL -#define SD_INFO2_BWE 0x00000200UL /* SD_BUF Write Enable */ -#define SD_INFO2_BRE 0x00000100UL /* SD_BUF Read Enable */ -#define SD_INFO2_DAT0 0x00000080UL /* SDDAT0 */ -#define SD_INFO2_ERR6 0x00000040UL /* Response Timeout */ -#define SD_INFO2_ERR5 0x00000020UL /* SD_BUF Illegal Read Access */ -#define SD_INFO2_ERR4 0x00000010UL /* SD_BUF Illegal Write Access */ -#define SD_INFO2_ERR3 0x00000008UL /* Data Timeout */ -#define SD_INFO2_ERR2 0x00000004UL /* END Error */ -#define SD_INFO2_ERR1 0x00000002UL /* CRC Error */ -#define SD_INFO2_ERR0 0x00000001UL /* CMD Error */ -#define SD_INFO2_ALL_ERR 0x0000807FUL -#define SD_INFO2_CLEAR 0x00000800UL /* BIT11 write value should always be 1. HWM_0003 */ - -/* SOFT_RST */ -#define SOFT_RST_SDRST 0x00000001UL - -/* SD_CLK_CTRL */ -#define SD_CLK_CTRL_SDCLKOFFEN 0x00000200UL -#define SD_CLK_CTRL_SCLKEN 0x00000100UL -#define SD_CLK_CTRL_CLKDIV_MASK 0x000000FFUL -#define SD_CLOCK_ENABLE 0x00000100UL -#define SD_CLOCK_DISABLE 0x00000000UL -#define SD_CLK_WRITE_MASK 0x000003FFUL -#define SD_CLK_CLKDIV_CLEAR_MASK 0xFFFFFF0FUL - -/* SD_OPTION */ -#define SD_OPTION_TIMEOUT_CNT_MASK 0x000000F0UL - -/* - * MMC Clock Frequency - * 200MHz * 1/x = output clock - */ -#define MMC_CLK_OFF 0UL /* Clock output is disabled */ -#define MMC_400KHZ 512UL /* 200MHz * 1/512 = 390 KHz */ -#define MMC_20MHZ 16UL /* 200MHz * 1/16 = 12.5 MHz Normal speed mode */ -#define MMC_26MHZ 8UL /* 200MHz * 1/8 = 25 MHz HS mode 26Mhz */ -#define MMC_52MHZ 4UL /* 200MHz * 1/4 = 50 MHz HS mode 52Mhz */ -#define MMC_100MHZ 2UL /* 200MHz * 1/2 = 100 MHz */ -#define MMC_200MHZ 1UL /* 200MHz * 1/1 = 200 MHz */ - -#define MMC_FREQ_52MHZ 52000000UL -#define MMC_FREQ_26MHZ 26000000UL -#define MMC_FREQ_20MHZ 20000000UL - -/* MMC Clock DIV */ -#define MMC_SD_CLK_START 0x00000100UL /* CLOCK On */ -#define MMC_SD_CLK_STOP (~0x00000100UL) /* CLOCK stop */ -#define MMC_SD_CLK_DIV1 0x000000FFUL /* 1/1 */ -#define MMC_SD_CLK_DIV2 0x00000000UL /* 1/2 */ -#define MMC_SD_CLK_DIV4 0x00000001UL /* 1/4 */ -#define MMC_SD_CLK_DIV8 0x00000002UL /* 1/8 */ -#define MMC_SD_CLK_DIV16 0x00000004UL /* 1/16 */ -#define MMC_SD_CLK_DIV32 0x00000008UL /* 1/32 */ -#define MMC_SD_CLK_DIV64 0x00000010UL /* 1/64 */ -#define MMC_SD_CLK_DIV128 0x00000020UL /* 1/128 */ -#define MMC_SD_CLK_DIV256 0x00000040UL /* 1/256 */ -#define MMC_SD_CLK_DIV512 0x00000080UL /* 1/512 */ - -/* DM_CM_DTRAN_MODE */ -#define DM_CM_DTRAN_MODE_CH0 0x00000000UL /* CH0(downstream) */ -#define DM_CM_DTRAN_MODE_CH1 0x00010000UL /* CH1(upstream) */ -#define DM_CM_DTRAN_MODE_BIT_WIDTH 0x00000030UL - -/* CC_EXT_MODE */ -#define CC_EXT_MODE_DMASDRW_ENABLE 0x00000002UL /* SD_BUF Read/Write DMA Transfer */ -#define CC_EXT_MODE_CLEAR 0x00001010UL /* BIT 12 & 4 always 1. */ - -/* DM_CM_INFO_MASK */ -#define DM_CM_INFO_MASK_CLEAR 0xFFFCFFFEUL -#define DM_CM_INFO_CH0_ENABLE 0x00010001UL -#define DM_CM_INFO_CH1_ENABLE 0x00020001UL - -/* DM_DTRAN_ADDR */ -#define DM_DTRAN_ADDR_WRITE_MASK 0xFFFFFFF8UL - -/* DM_CM_DTRAN_CTRL */ -#define DM_CM_DTRAN_CTRL_START 0x00000001UL - -/* SYSC Registers */ -#if USE_MMC_CH == MMC_CH0 -#define CPG_MSTP_MMC (BIT12) /* SDHI2/MMC0 */ -#else /* USE_MMC_CH == MMC_CH0 */ -#define CPG_MSTP_MMC (BIT11) /* SDHI3/MMC1 */ -#endif /* USE_MMC_CH == MMC_CH0 */ - -#endif /* EMMC_REGISTERS_H */ diff --git a/drivers/renesas/rcar/emmc/emmc_std.h b/drivers/renesas/rcar/emmc/emmc_std.h deleted file mode 100644 index 087c6e91d..000000000 --- a/drivers/renesas/rcar/emmc/emmc_std.h +++ /dev/null @@ -1,475 +0,0 @@ -/* - * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef EMMC_STD_H -#define EMMC_STD_H - -#include "emmc_hal.h" - -#ifndef FALSE -#define FALSE 0U -#endif -#ifndef TRUE -#define TRUE 1U -#endif - -/* 64bit registers */ -#define SETR_64(r, v) (*(volatile uint64_t *)(r) = (v)) -#define GETR_64(r) (*(volatile uint64_t *)(r)) - -/* 32bit registers */ -#define SETR_32(r, v) (*(volatile uint32_t *)(r) = (v)) -#define GETR_32(r) (*(volatile uint32_t *)(r)) - -/* 16bit registers */ -#define SETR_16(r, v) (*(volatile uint16_t *)(r) = (v)) -#define GETR_16(r) (*(volatile uint16_t *)(r)) - -/* 8bit registers */ -#define SETR_8(r, v) (*(volatile uint8_t *)(r) = (v)) -#define GETR_8(r) (*(volatile uint8_t *)(r)) - -/* CSD register Macros */ -#define EMMC_GET_CID(x, y) (emmc_bit_field(mmc_drv_obj.cid_data, (x), (y))) - -#define EMMC_CID_MID() (EMMC_GET_CID(127, 120)) -#define EMMC_CID_CBX() (EMMC_GET_CID(113, 112)) -#define EMMC_CID_OID() (EMMC_GET_CID(111, 104)) -#define EMMC_CID_PNM1() (EMMC_GET_CID(103, 88)) -#define EMMC_CID_PNM2() (EMMC_GET_CID(87, 56)) -#define EMMC_CID_PRV() (EMMC_GET_CID(55, 48)) -#define EMMC_CID_PSN() (EMMC_GET_CID(47, 16)) -#define EMMC_CID_MDT() (EMMC_GET_CID(15, 8)) -#define EMMC_CID_CRC() (EMMC_GET_CID(7, 1)) - -/* CSD register Macros */ -#define EMMC_GET_CSD(x, y) (emmc_bit_field(mmc_drv_obj.csd_data, (x), (y))) - -#define EMMC_CSD_CSD_STRUCTURE() (EMMC_GET_CSD(127, 126)) -#define EMMC_CSD_SPEC_VARS() (EMMC_GET_CSD(125, 122)) -#define EMMC_CSD_TAAC() (EMMC_GET_CSD(119, 112)) -#define EMMC_CSD_NSAC() (EMMC_GET_CSD(111, 104)) -#define EMMC_CSD_TRAN_SPEED() (EMMC_GET_CSD(103, 96)) -#define EMMC_CSD_CCC() (EMMC_GET_CSD(95, 84)) -#define EMMC_CSD_READ_BL_LEN() (EMMC_GET_CSD(83, 80)) -#define EMMC_CSD_READ_BL_PARTIAL() (EMMC_GET_CSD(79, 79)) -#define EMMC_CSD_WRITE_BLK_MISALIGN() (EMMC_GET_CSD(78, 78)) -#define EMMC_CSD_READ_BLK_MISALIGN() (EMMC_GET_CSD(77, 77)) -#define EMMC_CSD_DSR_IMP() (EMMC_GET_CSD(76, 76)) -#define EMMC_CSD_C_SIZE() (EMMC_GET_CSD(73, 62)) -#define EMMC_CSD_VDD_R_CURR_MIN() (EMMC_GET_CSD(61, 59)) -#define EMMC_CSD_VDD_R_CURR_MAX() (EMMC_GET_CSD(58, 56)) -#define EMMC_CSD_VDD_W_CURR_MIN() (EMMC_GET_CSD(55, 53)) -#define EMMC_CSD_VDD_W_CURR_MAX() (EMMC_GET_CSD(52, 50)) -#define EMMC_CSD_C_SIZE_MULT() (EMMC_GET_CSD(49, 47)) -#define EMMC_CSD_ERASE_GRP_SIZE() (EMMC_GET_CSD(46, 42)) -#define EMMC_CSD_ERASE_GRP_MULT() (EMMC_GET_CSD(41, 37)) -#define EMMC_CSD_WP_GRP_SIZE() (EMMC_GET_CSD(36, 32)) -#define EMMC_CSD_WP_GRP_ENABLE() (EMMC_GET_CSD(31, 31)) -#define EMMC_CSD_DEFALT_ECC() (EMMC_GET_CSD(30, 29)) -#define EMMC_CSD_R2W_FACTOR() (EMMC_GET_CSD(28, 26)) -#define EMMC_CSD_WRITE_BL_LEN() (EMMC_GET_CSD(25, 22)) -#define EMMC_CSD_WRITE_BL_PARTIAL() (EMMC_GET_CSD(21, 21)) -#define EMMC_CSD_CONTENT_PROT_APP() (EMMC_GET_CSD(16, 16)) -#define EMMC_CSD_FILE_FORMAT_GRP() (EMMC_GET_CSD(15, 15)) -#define EMMC_CSD_COPY() (EMMC_GET_CSD(14, 14)) -#define EMMC_CSD_PERM_WRITE_PROTECT() (EMMC_GET_CSD(13, 13)) -#define EMMC_CSD_TMP_WRITE_PROTECT() (EMMC_GET_CSD(12, 12)) -#define EMMC_CSD_FILE_FORMAT() (EMMC_GET_CSD(11, 10)) -#define EMMC_CSD_ECC() (EMMC_GET_CSD(9, 8)) -#define EMMC_CSD_CRC() (EMMC_GET_CSD(7, 1)) - -/* sector access */ -#define EMMC_4B_BOUNDARY_CHECK_MASK 0x00000003 -#define EMMC_SECTOR_SIZE_SHIFT 9U /* 512 = 2^9 */ -#define EMMC_SECTOR_SIZE 512 -#define EMMC_BLOCK_LENGTH 512 -#define EMMC_BLOCK_LENGTH_DW 128 -#define EMMC_BUF_SIZE_SHIFT 3U /* 8byte = 2^3 */ - -/* eMMC specification clock */ -#define EMMC_CLOCK_SPEC_400K 400000UL /* initialize clock 400KHz */ -#define EMMC_CLOCK_SPEC_20M 20000000UL /* normal speed 20MHz */ -#define EMMC_CLOCK_SPEC_26M 26000000UL /* high speed 26MHz */ -#define EMMC_CLOCK_SPEC_52M 52000000UL /* high speed 52MHz */ -#define EMMC_CLOCK_SPEC_100M 100000000UL /* high speed 100MHz */ - -/* EMMC driver error code. (extended HAL_MEMCARD_RETURN) */ -typedef enum { - EMMC_ERR = 0, /* unknown error */ - EMMC_SUCCESS, /* OK */ - EMMC_ERR_FROM_DMAC, /* DMAC allocation error */ - EMMC_ERR_FROM_DMAC_TRANSFER, /* DMAC transfer error */ - EMMC_ERR_CARD_STATUS_BIT, /* card status error */ - EMMC_ERR_CMD_TIMEOUT, /* command timeout error */ - EMMC_ERR_DATA_TIMEOUT, /* data timeout error */ - EMMC_ERR_CMD_CRC, /* command CRC error */ - EMMC_ERR_DATA_CRC, /* data CRC error */ - EMMC_ERR_PARAM, /* parameter error */ - EMMC_ERR_RESPONSE, /* response error */ - EMMC_ERR_RESPONSE_BUSY, /* response busy error */ - EMMC_ERR_TRANSFER, /* data transfer error */ - EMMC_ERR_READ_SECTOR, /* read sector error */ - EMMC_ERR_WRITE_SECTOR, /* write sector error */ - EMMC_ERR_STATE, /* state error */ - EMMC_ERR_TIMEOUT, /* timeout error */ - EMMC_ERR_ILLEGAL_CARD, /* illegal card */ - EMMC_ERR_CARD_BUSY, /* Busy state */ - EMMC_ERR_CARD_STATE, /* card state error */ - EMMC_ERR_SET_TRACE, /* trace information error */ - EMMC_ERR_FROM_TIMER, /* Timer error */ - EMMC_ERR_FORCE_TERMINATE, /* Force terminate */ - EMMC_ERR_CARD_POWER, /* card power fail */ - EMMC_ERR_ERASE_SECTOR, /* erase sector error */ - EMMC_ERR_INFO2 /* exec cmd error info2 */ -} EMMC_ERROR_CODE; - -/* Function number */ -#define EMMC_FUNCNO_NONE 0U -#define EMMC_FUNCNO_DRIVER_INIT 1U -#define EMMC_FUNCNO_CARD_POWER_ON 2U -#define EMMC_FUNCNO_MOUNT 3U -#define EMMC_FUNCNO_CARD_INIT 4U -#define EMMC_FUNCNO_HIGH_SPEED 5U -#define EMMC_FUNCNO_BUS_WIDTH 6U -#define EMMC_FUNCNO_MULTI_BOOT_SELECT_PARTITION 7U -#define EMMC_FUNCNO_MULTI_BOOT_READ_SECTOR 8U -#define EMMC_FUNCNO_TRANS_DATA_READ_SECTOR 9U -#define EMMC_FUNCNO_UBOOT_IMAGE_SELECT_PARTITION 10U -#define EMMC_FUNCNO_UBOOT_IMAGE_READ_SECTOR 11U -#define EMMC_FUNCNO_SET_CLOCK 12U -#define EMMC_FUNCNO_EXEC_CMD 13U -#define EMMC_FUNCNO_READ_SECTOR 14U -#define EMMC_FUNCNO_WRITE_SECTOR 15U -#define EMMC_FUNCNO_ERASE_SECTOR 16U -#define EMMC_FUNCNO_GET_PERTITION_ACCESS 17U -/* - * Response - * R1 - * Type 'E' bit and bit14(must be 0). ignore bit22 - */ -#define EMMC_R1_ERROR_MASK 0xFDBFE080U -/* Ignore bit23 (Not check CRC error) */ -#define EMMC_R1_ERROR_MASK_WITHOUT_CRC (0xFD3FE080U) -#define EMMC_R1_STATE_MASK 0x00001E00U /* [12:9] */ -#define EMMC_R1_READY 0x00000100U /* bit8 */ -#define EMMC_R1_STATE_SHIFT 9 - -/* R4 */ -#define EMMC_R4_RCA_MASK 0xFFFF0000UL -#define EMMC_R4_STATUS 0x00008000UL - -/* CSD */ -#define EMMC_TRANSPEED_FREQ_UNIT_MASK 0x07 /* bit[2:0] */ -#define EMMC_TRANSPEED_FREQ_UNIT_SHIFT 0 -#define EMMC_TRANSPEED_MULT_MASK 0x78 /* bit[6:3] */ -#define EMMC_TRANSPEED_MULT_SHIFT 3 - -/* OCR */ -#define EMMC_HOST_OCR_VALUE 0x40FF8080 -#define EMMC_OCR_STATUS_BIT 0x80000000L /* Card power up status bit */ -#define EMMC_OCR_ACCESS_MODE_MASK 0x60000000L /* bit[30:29] */ -#define EMMC_OCR_ACCESS_MODE_SECT 0x40000000L -#define EMMC_OCR_ACCESS_MODE_BYTE 0x00000000L - -/* EXT_CSD */ -#define EMMC_EXT_CSD_S_CMD_SET 504 -#define EMMC_EXT_CSD_INI_TIMEOUT_AP 241 -#define EMMC_EXT_CSD_PWR_CL_DDR_52_360 239 -#define EMMC_EXT_CSD_PWR_CL_DDR_52_195 238 -#define EMMC_EXT_CSD_MIN_PERF_DDR_W_8_52 235 -#define EMMC_EXT_CSD_MIN_PERF_DDR_R_8_52 234 -#define EMMC_EXT_CSD_TRIM_MULT 232 -#define EMMC_EXT_CSD_SEC_FEATURE_SUPPORT 231 -#define EMMC_EXT_CSD_SEC_ERASE_MULT 229 -#define EMMC_EXT_CSD_BOOT_INFO 228 -#define EMMC_EXT_CSD_BOOT_SIZE_MULTI 226 -#define EMMC_EXT_CSD_ACC_SIZE 225 -#define EMMC_EXT_CSD_HC_ERASE_GRP_SIZE 224 -#define EMMC_EXT_CSD_ERASE_TIMEOUT_MULT 223 -#define EMMC_EXT_CSD_PEL_WR_SEC_C 222 -#define EMMC_EXT_CSD_HC_WP_GRP_SIZE 221 -#define EMMC_EXT_CSD_S_C_VCC 220 -#define EMMC_EXT_CSD_S_C_VCCQ 219 -#define EMMC_EXT_CSD_S_A_TIMEOUT 217 -#define EMMC_EXT_CSD_SEC_COUNT 215 -#define EMMC_EXT_CSD_MIN_PERF_W_8_52 210 -#define EMMC_EXT_CSD_MIN_PERF_R_8_52 209 -#define EMMC_EXT_CSD_MIN_PERF_W_8_26_4_52 208 -#define EMMC_EXT_CSD_MIN_PERF_R_8_26_4_52 207 -#define EMMC_EXT_CSD_MIN_PERF_W_4_26 206 -#define EMMC_EXT_CSD_MIN_PERF_R_4_26 205 -#define EMMC_EXT_CSD_PWR_CL_26_360 203 -#define EMMC_EXT_CSD_PWR_CL_52_360 202 -#define EMMC_EXT_CSD_PWR_CL_26_195 201 -#define EMMC_EXT_CSD_PWR_CL_52_195 200 -#define EMMC_EXT_CSD_CARD_TYPE 196 -#define EMMC_EXT_CSD_CSD_STRUCTURE 194 -#define EMMC_EXT_CSD_EXT_CSD_REV 192 -#define EMMC_EXT_CSD_CMD_SET 191 -#define EMMC_EXT_CSD_CMD_SET_REV 189 -#define EMMC_EXT_CSD_POWER_CLASS 187 -#define EMMC_EXT_CSD_HS_TIMING 185 -#define EMMC_EXT_CSD_BUS_WIDTH 183 -#define EMMC_EXT_CSD_ERASED_MEM_CONT 181 -#define EMMC_EXT_CSD_PARTITION_CONFIG 179 -#define EMMC_EXT_CSD_BOOT_CONFIG_PROT 178 -#define EMMC_EXT_CSD_BOOT_BUS_WIDTH 177 -#define EMMC_EXT_CSD_ERASE_GROUP_DEF 175 -#define EMMC_EXT_CSD_BOOT_WP 173 -#define EMMC_EXT_CSD_USER_WP 171 -#define EMMC_EXT_CSD_FW_CONFIG 169 -#define EMMC_EXT_CSD_RPMB_SIZE_MULT 168 -#define EMMC_EXT_CSD_RST_n_FUNCTION 162 -#define EMMC_EXT_CSD_PARTITIONING_SUPPORT 160 -#define EMMC_EXT_CSD_MAX_ENH_SIZE_MULT 159 -#define EMMC_EXT_CSD_PARTITIONS_ATTRIBUTE 156 -#define EMMC_EXT_CSD_PARTITION_SETTING_COMPLETED 155 -#define EMMC_EXT_CSD_GP_SIZE_MULT 154 -#define EMMC_EXT_CSD_ENH_SIZE_MULT 142 -#define EMMC_EXT_CSD_ENH_START_ADDR 139 -#define EMMC_EXT_CSD_SEC_BAD_BLK_MGMNT 134 - -#define EMMC_EXT_CSD_CARD_TYPE_26MHZ 0x01 -#define EMMC_EXT_CSD_CARD_TYPE_52MHZ 0x02 -#define EMMC_EXT_CSD_CARD_TYPE_DDR_52MHZ_12V 0x04 -#define EMMC_EXT_CSD_CARD_TYPE_DDR_52MHZ_18V 0x08 -#define EMMC_EXT_CSD_CARD_TYPE_52MHZ_MASK 0x0e - -/* SWITCH (CMD6) argument */ -#define EXTCSD_ACCESS_BYTE (BIT25 | BIT24) -#define EXTCSD_SET_BITS BIT24 - -#define HS_TIMING_ADD (185 << 16) /* H'b9 */ -#define HS_TIMING_1 (1 << 8) -#define HS_TIMING_HS200 (2 << 8) -#define HS_TIMING_HS400 (3 << 8) - -#define BUS_WIDTH_ADD (183 << 16) /* H'b7 */ -#define BUS_WIDTH_1 (0 << 8) -#define BUS_WIDTH_4 (1 << 8) -#define BUS_WIDTH_8 (2 << 8) -#define BUS_WIDTH_4DDR (5 << 8) -#define BUS_WIDTH_8DDR (6 << 8) - -#define EMMC_SWITCH_HS_TIMING (EXTCSD_ACCESS_BYTE | HS_TIMING_ADD |\ - HS_TIMING_1) /* H'03b90100 */ -#define EMMC_SWITCH_HS_TIMING_OFF (EXTCSD_ACCESS_BYTE |\ - HS_TIMING_ADD) /* H'03b90000 */ - -#define EMMC_SWITCH_BUS_WIDTH_1 (EXTCSD_ACCESS_BYTE | BUS_WIDTH_ADD |\ - BUS_WIDTH_1) /* H'03b70000 */ -#define EMMC_SWITCH_BUS_WIDTH_4 (EXTCSD_ACCESS_BYTE | BUS_WIDTH_ADD |\ - BUS_WIDTH_4) /* H'03b70100 */ -#define EMMC_SWITCH_BUS_WIDTH_8 (EXTCSD_ACCESS_BYTE | BUS_WIDTH_ADD |\ - BUS_WIDTH_8) /* H'03b70200 */ -#define EMMC_SWITCH_BUS_WIDTH_4DDR (EXTCSD_ACCESS_BYTE | BUS_WIDTH_ADD |\ - BUS_WIDTH_4DDR) /* H'03b70500 */ -#define EMMC_SWITCH_BUS_WIDTH_8DDR (EXTCSD_ACCESS_BYTE | BUS_WIDTH_ADD |\ - BUS_WIDTH_8DDR) /* H'03b70600 */ -/* Partition config = 0x00 */ -#define EMMC_SWITCH_PARTITION_CONFIG 0x03B30000UL - -#define TIMING_HIGH_SPEED 1UL -#define EMMC_BOOT_PARTITION_EN_MASK 0x38U -#define EMMC_BOOT_PARTITION_EN_SHIFT 3U - -/* Bus width */ -#define EMMC_BUSWIDTH_1BIT CE_CMD_SET_DATW_1BIT -#define EMMC_BUSWIDTH_4BIT CE_CMD_SET_DATW_4BIT -#define EMMC_BUSWIDTH_8BIT CE_CMD_SET_DATW_8BIT - -/* for st_mmc_base */ -#define EMMC_MAX_RESPONSE_LENGTH 17 -#define EMMC_MAX_CID_LENGTH 16 -#define EMMC_MAX_CSD_LENGTH 16 -#define EMMC_MAX_EXT_CSD_LENGTH 512U -#define EMMC_RES_REG_ALIGNED 4U -#define EMMC_BUF_REG_ALIGNED 8U - -/* TAAC mask */ -#define TAAC_TIME_UNIT_MASK (0x07) -#define TAAC_MULTIPLIER_FACTOR_MASK (0x0F) - -/* Partition id */ -typedef enum { - PARTITION_ID_USER = 0x0, /* User Area */ - PARTITION_ID_BOOT_1 = 0x1, /* boot partition 1 */ - PARTITION_ID_BOOT_2 = 0x2, /* boot partition 2 */ - PARTITION_ID_RPMB = 0x3, /* Replay Protected Memory Block */ - PARTITION_ID_GP_1 = 0x4, /* General Purpose partition 1 */ - PARTITION_ID_GP_2 = 0x5, /* General Purpose partition 2 */ - PARTITION_ID_GP_3 = 0x6, /* General Purpose partition 3 */ - PARTITION_ID_GP_4 = 0x7, /* General Purpose partition 4 */ - PARTITION_ID_MASK = 0x7 /* [2:0] */ -} EMMC_PARTITION_ID; - -/* card state in R1 response [12:9] */ -typedef enum { - EMMC_R1_STATE_IDLE = 0, - EMMC_R1_STATE_READY, - EMMC_R1_STATE_IDENT, - EMMC_R1_STATE_STBY, - EMMC_R1_STATE_TRAN, - EMMC_R1_STATE_DATA, - EMMC_R1_STATE_RCV, - EMMC_R1_STATE_PRG, - EMMC_R1_STATE_DIS, - EMMC_R1_STATE_BTST, - EMMC_R1_STATE_SLEP -} EMMC_R1_STATE; - -typedef enum { - ESTATE_BEGIN = 0, - ESTATE_ISSUE_CMD, - ESTATE_NON_RESP_CMD, - ESTATE_RCV_RESP, - ESTATE_RCV_RESPONSE_BUSY, - ESTATE_CHECK_RESPONSE_COMPLETE, - ESTATE_DATA_TRANSFER, - ESTATE_DATA_TRANSFER_COMPLETE, - ESTATE_ACCESS_END, - ESTATE_TRANSFER_ERROR, - ESTATE_ERROR, - ESTATE_END -} EMMC_INT_STATE; - -/* eMMC boot driver error information */ -typedef struct { - uint16_t num; /* error no */ - uint16_t code; /* error code */ - - volatile uint32_t info1; /* SD_INFO1. (hw dependent) */ - volatile uint32_t info2; /* SD_INFO2. (hw dependent) */ - volatile uint32_t status1; /* SD_ERR_STS1. (hw dependent) */ - volatile uint32_t status2; /* SD_ERR_STS2. (hw dependent) */ - volatile uint32_t dm_info1; /* DM_CM_INFO1. (hw dependent) */ - volatile uint32_t dm_info2; /* DM_CM_INFO2. (hw dependent) */ -} st_error_info; - -/* Command information */ -typedef struct { - HAL_MEMCARD_COMMAND cmd; /* Command information */ - uint32_t arg; /* argument */ - HAL_MEMCARD_OPERATION dir; /* direction */ - uint32_t hw; /* SD_CMD register value. */ -} st_command_info; - -/* MMC driver base */ -typedef struct { - st_error_info error_info; /* error information */ - st_command_info cmd_info; /* command information */ - - /* for data transfer */ - uint32_t *buff_address_virtual; /* Dest or Src buff */ - uint32_t *buff_address_physical; /* Dest or Src buff */ - HAL_MEMCARD_DATA_WIDTH bus_width; /* bus width */ - - uint32_t trans_size; /* transfer size for this command */ - uint32_t remain_size; /* remain size for this command */ - uint32_t response_length; /* response length for this command */ - uint32_t sector_size; /* sector_size */ - - /* clock */ - uint32_t base_clock; /* MMC host controller clock */ - /* - * Max freq (Card Spec)[Hz]. It changes dynamically by CSD and - * EXT_CSD. - */ - uint32_t max_freq; - /* request freq [Hz] (400K, 26MHz, 52MHz, etc) */ - uint32_t request_freq; - /* current MMC clock[Hz] (the closest frequency supported by HW) */ - uint32_t current_freq; - - /* state flag */ - /* presence status of the memory card */ - HAL_MEMCARD_PRESENCE_STATUS card_present; - - uint32_t card_power_enable; - uint32_t clock_enable; - /* True : initialize complete. */ - uint32_t initialize; - /* True : sector access, FALSE : byte access */ - uint32_t access_mode; - /* True : mount complete. */ - uint32_t mount; - /* True : selected card. */ - uint32_t selected; - /* 0: DMA, 1:PIO */ - HAL_MEMCARD_DATA_TRANSFER_MODE transfer_mode; - - /* loaded ISSW image No. ISSW have copy image. */ - uint32_t image_num; - /* card state */ - EMMC_R1_STATE current_state; - /* True : during command processing */ - volatile uint32_t during_cmd_processing; - /* True : during transfer */ - volatile uint32_t during_transfer; - /* True : during transfer (DMA) */ - volatile uint32_t during_dma_transfer; - /* True : occurred DMAC error */ - volatile uint32_t dma_error_flag; - /* force terminate flag */ - volatile uint32_t force_terminate; - /* state machine blocking flag : True or False */ - volatile uint32_t state_machine_blocking; - /* True : get partition access processing */ - volatile uint32_t get_partition_access_flag; - - EMMC_PARTITION_ID boot_partition_en; /* Boot partition */ - EMMC_PARTITION_ID partition_access; /* Current access partition */ - - /* timeout */ - uint32_t hs_timing; - - /* read and write data timeout */ - uint32_t data_timeout; - - /* retry */ - uint32_t retries_after_fail; - - /* interrupt */ - volatile uint32_t int_event1; /* interrupt SD_INFO1 Event */ - volatile uint32_t int_event2; /* interrupt SD_INFO2 Event */ - volatile uint32_t dm_event1; /* interrupt DM_CM_INFO1 Event */ - volatile uint32_t dm_event2; /* interrupt DM_CM_INFO2 Event */ - - /* response */ - uint32_t *response; /* buffer ptr for executing command. */ - uint32_t r1_card_status; /* R1 response data */ - uint32_t r3_ocr; /* R3 response data */ - uint32_t r4_resp; /* R4 response data */ - uint32_t r5_resp; /* R5 response data */ - - /* True : clock mode is low. (MMC clock = Max26MHz) */ - uint32_t low_clock_mode_enable; - - uint32_t reserved2; - uint32_t reserved3; - uint32_t reserved4; - - /* CSD registers (4byte align) */ - uint8_t csd_data[EMMC_MAX_CSD_LENGTH] /* CSD */ - __attribute__ ((aligned(EMMC_RES_REG_ALIGNED))); - /* CID registers (4byte align) */ - uint8_t cid_data[EMMC_MAX_CID_LENGTH] /* CID */ - __attribute__ ((aligned(EMMC_RES_REG_ALIGNED))); - /* EXT CSD registers (8byte align) */ - uint8_t ext_csd_data[EMMC_MAX_EXT_CSD_LENGTH] /* EXT_CSD */ - __attribute__ ((aligned(EMMC_BUF_REG_ALIGNED))); - /* Response registers (4byte align) */ - uint8_t response_data[EMMC_MAX_RESPONSE_LENGTH] /* other response */ - __attribute__ ((aligned(EMMC_RES_REG_ALIGNED))); -} st_mmc_base; - -typedef int (*func) (void); - -uint32_t emmc_get_csd_time(void); - -#define MMC_DEBUG -#endif /* EMMC_STD_H */ diff --git a/drivers/renesas/rcar/emmc/emmc_utility.c b/drivers/renesas/rcar/emmc/emmc_utility.c deleted file mode 100644 index 2e88abc75..000000000 --- a/drivers/renesas/rcar/emmc/emmc_utility.c +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include "emmc_config.h" -#include "emmc_def.h" -#include "emmc_hal.h" -#include "emmc_registers.h" -#include "emmc_std.h" - -static const uint32_t cmd_reg_hw[EMMC_CMD_MAX + 1] = { - 0x00000000, /* CMD0 */ - 0x00000701, /* CMD1 */ - 0x00000002, /* CMD2 */ - 0x00000003, /* CMD3 */ - 0x00000004, /* CMD4 */ - 0x00000505, /* CMD5 */ - 0x00000406, /* CMD6 */ - 0x00000007, /* CMD7 */ - 0x00001C08, /* CMD8 */ - 0x00000009, /* CMD9 */ - 0x0000000A, /* CMD10 */ - 0x00000000, /* reserved */ - 0x0000000C, /* CMD12 */ - 0x0000000D, /* CMD13 */ - 0x00001C0E, /* CMD14 */ - 0x0000000F, /* CMD15 */ - 0x00000010, /* CMD16 */ - 0x00000011, /* CMD17 */ - 0x00007C12, /* CMD18 */ - 0x00000C13, /* CMD19 */ - 0x00000000, - 0x00001C15, /* CMD21 */ - 0x00000000, - 0x00000017, /* CMD23 */ - 0x00000018, /* CMD24 */ - 0x00006C19, /* CMD25 */ - 0x00000C1A, /* CMD26 */ - 0x0000001B, /* CMD27 */ - 0x0000001C, /* CMD28 */ - 0x0000001D, /* CMD29 */ - 0x0000001E, /* CMD30 */ - 0x00001C1F, /* CMD31 */ - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000423, /* CMD35 */ - 0x00000424, /* CMD36 */ - 0x00000000, - 0x00000026, /* CMD38 */ - 0x00000427, /* CMD39 */ - 0x00000428, /* CMD40(send cmd) */ - 0x00000000, - 0x0000002A, /* CMD42 */ - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000C31, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00007C35, - 0x00006C36, - 0x00000037, /* CMD55 */ - 0x00000038, /* CMD56(Read) */ - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000 -}; - -uint32_t emmc_bit_field(uint8_t *data, uint32_t top, uint32_t bottom) -{ - uint32_t value; - - uint32_t index_top = (uint32_t) (15 - (top >> 3)); - uint32_t index_bottom = (uint32_t) (15 - (bottom >> 3)); - - if (index_top == index_bottom) { - value = data[index_top]; - } else if ((index_top + 1) == index_bottom) { - value = - (uint32_t) ((data[index_top] << 8) | data[index_bottom]); - } else if ((index_top + 2) == index_bottom) { - value = - (uint32_t) ((data[index_top] << 16) | - (data[index_top + 1] << 8) | data[index_top + - 2]); - } else { - value = - (uint32_t) ((data[index_top] << 24) | - (data[index_top + 1] << 16) | - (data[index_top + 2] << 8) | - data[index_top + 3]); - } - - value = ((value >> (bottom & 0x07)) & ((1 << (top - bottom + 1)) - 1)); - - return value; -} - -void emmc_write_error_info(uint16_t func_no, EMMC_ERROR_CODE error_code) -{ - - mmc_drv_obj.error_info.num = func_no; - mmc_drv_obj.error_info.code = (uint16_t) error_code; - - ERROR("BL2: emmc err:func_no=0x%x code=0x%x\n", func_no, error_code); -} - -void emmc_write_error_info_func_no(uint16_t func_no) -{ - - mmc_drv_obj.error_info.num = func_no; - - ERROR("BL2: emmc err:func_no=0x%x\n", func_no); -} - -void emmc_make_nontrans_cmd(HAL_MEMCARD_COMMAND cmd, uint32_t arg) -{ - /* command information */ - mmc_drv_obj.cmd_info.cmd = cmd; - mmc_drv_obj.cmd_info.arg = arg; - mmc_drv_obj.cmd_info.dir = HAL_MEMCARD_READ; - mmc_drv_obj.cmd_info.hw = - cmd_reg_hw[cmd & HAL_MEMCARD_COMMAND_INDEX_MASK]; - - /* clear data transfer information */ - mmc_drv_obj.trans_size = 0; - mmc_drv_obj.remain_size = 0; - mmc_drv_obj.buff_address_virtual = NULL; - mmc_drv_obj.buff_address_physical = NULL; - - /* response information */ - mmc_drv_obj.response_length = 6; - - switch (mmc_drv_obj.cmd_info.cmd & HAL_MEMCARD_RESPONSE_TYPE_MASK) { - case HAL_MEMCARD_RESPONSE_NONE: - mmc_drv_obj.response = (uint32_t *) mmc_drv_obj.response_data; - mmc_drv_obj.response_length = 0; - break; - case HAL_MEMCARD_RESPONSE_R1: - mmc_drv_obj.response = &mmc_drv_obj.r1_card_status; - break; - case HAL_MEMCARD_RESPONSE_R1b: - mmc_drv_obj.cmd_info.hw |= BIT10; /* bit10 = R1 busy bit */ - mmc_drv_obj.response = &mmc_drv_obj.r1_card_status; - break; - case HAL_MEMCARD_RESPONSE_R2: - mmc_drv_obj.response = (uint32_t *) mmc_drv_obj.response_data; - mmc_drv_obj.response_length = 17; - break; - case HAL_MEMCARD_RESPONSE_R3: - mmc_drv_obj.response = &mmc_drv_obj.r3_ocr; - break; - case HAL_MEMCARD_RESPONSE_R4: - mmc_drv_obj.response = &mmc_drv_obj.r4_resp; - break; - case HAL_MEMCARD_RESPONSE_R5: - mmc_drv_obj.response = &mmc_drv_obj.r5_resp; - break; - default: - mmc_drv_obj.response = (uint32_t *) mmc_drv_obj.response_data; - break; - } -} - -void emmc_make_trans_cmd(HAL_MEMCARD_COMMAND cmd, uint32_t arg, - uint32_t *buff_address_virtual, - uint32_t len, - HAL_MEMCARD_OPERATION dir, - HAL_MEMCARD_DATA_TRANSFER_MODE transfer_mode) -{ - emmc_make_nontrans_cmd(cmd, arg); /* update common information */ - - /* for data transfer command */ - mmc_drv_obj.cmd_info.dir = dir; - mmc_drv_obj.buff_address_virtual = buff_address_virtual; - mmc_drv_obj.buff_address_physical = buff_address_virtual; - mmc_drv_obj.trans_size = len; - mmc_drv_obj.remain_size = len; - mmc_drv_obj.transfer_mode = transfer_mode; -} - -EMMC_ERROR_CODE emmc_send_idle_cmd(uint32_t arg) -{ - EMMC_ERROR_CODE result; - uint32_t freq; - - /* initialize state */ - mmc_drv_obj.mount = FALSE; - mmc_drv_obj.selected = FALSE; - mmc_drv_obj.during_transfer = FALSE; - mmc_drv_obj.during_cmd_processing = FALSE; - mmc_drv_obj.during_dma_transfer = FALSE; - mmc_drv_obj.dma_error_flag = FALSE; - mmc_drv_obj.force_terminate = FALSE; - mmc_drv_obj.state_machine_blocking = FALSE; - - mmc_drv_obj.bus_width = HAL_MEMCARD_DATA_WIDTH_1_BIT; - mmc_drv_obj.max_freq = MMC_20MHZ; /* 20MHz */ - mmc_drv_obj.current_state = EMMC_R1_STATE_IDLE; - - /* CMD0 (MMC clock is current frequency. if Data transfer mode, 20MHz or higher.) */ - emmc_make_nontrans_cmd(CMD0_GO_IDLE_STATE, arg); /* CMD0 */ - result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); - if (result != EMMC_SUCCESS) { - return result; - } - - /* change MMC clock(400KHz) */ - freq = MMC_400KHZ; - result = emmc_set_request_mmc_clock(&freq); - if (result != EMMC_SUCCESS) { - return result; - } - - return EMMC_SUCCESS; -} diff --git a/plat/renesas/common/common.mk b/plat/renesas/common/common.mk index ab9cded70..9b1466349 100644 --- a/plat/renesas/common/common.mk +++ b/plat/renesas/common/common.mk @@ -79,6 +79,12 @@ BL2_SOURCES += ${RCAR_GIC_SOURCES} \ ${LIBFDT_SRCS} \ common/desc_image_load.c \ drivers/renesas/common/common.c \ + drivers/renesas/common/emmc/emmc_interrupt.c \ + drivers/renesas/common/emmc/emmc_utility.c \ + drivers/renesas/common/emmc/emmc_mount.c \ + drivers/renesas/common/emmc/emmc_init.c \ + drivers/renesas/common/emmc/emmc_read.c \ + drivers/renesas/common/emmc/emmc_cmd.c \ drivers/io/io_storage.c BL31_SOURCES += ${RCAR_GIC_SOURCES} \ diff --git a/plat/renesas/rcar/platform.mk b/plat/renesas/rcar/platform.mk index 8613f5ea2..02be49a2e 100644 --- a/plat/renesas/rcar/platform.mk +++ b/plat/renesas/rcar/platform.mk @@ -307,7 +307,7 @@ PLAT_INCLUDES += -Idrivers/renesas/rcar/ddr \ -Idrivers/renesas/rcar/delay \ -Idrivers/renesas/rcar/rom \ -Idrivers/renesas/rcar/scif \ - -Idrivers/renesas/rcar/emmc \ + -Idrivers/renesas/common/emmc \ -Idrivers/renesas/rcar/pwrc \ -Idrivers/renesas/rcar/io @@ -330,12 +330,6 @@ BL2_SOURCES += plat/renesas/rcar/aarch64/platform_common.c \ drivers/renesas/rcar/dma/dma_driver.c \ drivers/renesas/rcar/avs/avs_driver.c \ drivers/renesas/rcar/delay/micro_delay.c \ - drivers/renesas/rcar/emmc/emmc_interrupt.c \ - drivers/renesas/rcar/emmc/emmc_utility.c \ - drivers/renesas/rcar/emmc/emmc_mount.c \ - drivers/renesas/rcar/emmc/emmc_init.c \ - drivers/renesas/rcar/emmc/emmc_read.c \ - drivers/renesas/rcar/emmc/emmc_cmd.c \ drivers/renesas/rcar/watchdog/swdt.c \ drivers/renesas/rcar/rom/rom_api.c \ drivers/renesas/rcar/board/board.c -- cgit v1.2.3 From 788ec26b53502424f22106f98af33c47c9fa41da Mon Sep 17 00:00:00 2001 From: Biju Das Date: Sun, 13 Dec 2020 20:38:44 +0000 Subject: plat: renesas:rcar: Code cleanup Sort the header includes alphabetically, fix typos and drop unneeded TAB and replace it with space Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: Ieff84434877f58ec26c8351611059ad4e11a4e28 --- plat/renesas/rcar/plat_pm.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/plat/renesas/rcar/plat_pm.c b/plat/renesas/rcar/plat_pm.c index 6fc47b95c..7ec78cce3 100644 --- a/plat/renesas/rcar/plat_pm.c +++ b/plat/renesas/rcar/plat_pm.c @@ -6,8 +6,6 @@ #include -#include - #include #include #include @@ -19,17 +17,18 @@ #include #include "iic_dvfs.h" +#include "platform_def.h" #include "pwrc.h" #include "rcar_def.h" #include "rcar_private.h" #include "ulcb_cpld.h" -#define DVFS_SET_VID_0V (0x00) -#define P_ALL_OFF (0x80) -#define KEEPON_DDR1C (0x08) -#define KEEPON_DDR0C (0x04) -#define KEEPON_DDR1 (0x02) -#define KEEPON_DDR0 (0x01) +#define DVFS_SET_VID_0V (0x00) +#define P_ALL_OFF (0x80) +#define KEEPON_DDR1C (0x08) +#define KEEPON_DDR0C (0x04) +#define KEEPON_DDR1 (0x02) +#define KEEPON_DDR0 (0x01) #define SYSTEM_PWR_STATE(s) ((s)->pwr_domain_state[PLAT_MAX_PWR_LVL]) #define CLUSTER_PWR_STATE(s) ((s)->pwr_domain_state[MPIDR_AFFLVL1]) @@ -200,20 +199,20 @@ static void __dead2 rcar_system_reset(void) error = rcar_iic_dvfs_send(PMIC, REG_KEEP10, KEEP10_MAGIC); if (error) { - ERROR("Failed send KEEP10 magic ret=%d \n", error); + ERROR("Failed send KEEP10 magic ret=%d\n", error); goto done; } error = rcar_iic_dvfs_receive(PMIC, BKUP_MODE_CNT, &mode); if (error) { - ERROR("Failed recieve BKUP_Mode_Cnt ret=%d \n", error); + ERROR("Failed receive BKUP_Mode_Cnt ret=%d\n", error); goto done; } mode |= KEEPON_DDR1C | KEEPON_DDR0C | KEEPON_DDR1 | KEEPON_DDR0; error = rcar_iic_dvfs_send(PMIC, BKUP_MODE_CNT, mode); if (error) { - ERROR("Failed send KEEPON_DDRx ret=%d \n", error); + ERROR("Failed send KEEPON_DDRx ret=%d\n", error); goto done; } @@ -292,7 +291,7 @@ static const plat_psci_ops_t rcar_plat_psci_ops = { .system_reset = rcar_system_reset, .validate_power_state = rcar_validate_power_state, #if RCAR_SYSTEM_SUSPEND - .get_sys_suspend_power_state = rcar_get_sys_suspend_power_state, + .get_sys_suspend_power_state = rcar_get_sys_suspend_power_state, #endif }; -- cgit v1.2.3 From 2ddb55752b9da7ebf6c725d2e1e2bb04c82c76b9 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Wed, 16 Dec 2020 10:05:41 +0000 Subject: drivers: renesas: io: Move to common Move io driver code to common directory, so that the same code can be re-used by both R-Car Gen3 and RZ/G2 platforms. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: Ic661e415c91a1fbfd5eee3bba86466037e51574b --- drivers/renesas/common/io/io_common.h | 16 + drivers/renesas/common/io/io_emmcdrv.c | 179 +++++++++ drivers/renesas/common/io/io_emmcdrv.h | 13 + drivers/renesas/common/io/io_memdrv.c | 154 ++++++++ drivers/renesas/common/io/io_memdrv.h | 13 + drivers/renesas/common/io/io_private.h | 20 + drivers/renesas/common/io/io_rcar.c | 654 +++++++++++++++++++++++++++++++++ drivers/renesas/common/io/io_rcar.h | 14 + drivers/renesas/rcar/io/io_common.h | 16 - drivers/renesas/rcar/io/io_emmcdrv.c | 179 --------- drivers/renesas/rcar/io/io_emmcdrv.h | 13 - drivers/renesas/rcar/io/io_memdrv.c | 154 -------- drivers/renesas/rcar/io/io_memdrv.h | 13 - drivers/renesas/rcar/io/io_private.h | 20 - drivers/renesas/rcar/io/io_rcar.c | 654 --------------------------------- drivers/renesas/rcar/io/io_rcar.h | 14 - plat/renesas/common/common.mk | 3 + plat/renesas/rcar/platform.mk | 5 +- 18 files changed, 1067 insertions(+), 1067 deletions(-) create mode 100644 drivers/renesas/common/io/io_common.h create mode 100644 drivers/renesas/common/io/io_emmcdrv.c create mode 100644 drivers/renesas/common/io/io_emmcdrv.h create mode 100644 drivers/renesas/common/io/io_memdrv.c create mode 100644 drivers/renesas/common/io/io_memdrv.h create mode 100644 drivers/renesas/common/io/io_private.h create mode 100644 drivers/renesas/common/io/io_rcar.c create mode 100644 drivers/renesas/common/io/io_rcar.h delete mode 100644 drivers/renesas/rcar/io/io_common.h delete mode 100644 drivers/renesas/rcar/io/io_emmcdrv.c delete mode 100644 drivers/renesas/rcar/io/io_emmcdrv.h delete mode 100644 drivers/renesas/rcar/io/io_memdrv.c delete mode 100644 drivers/renesas/rcar/io/io_memdrv.h delete mode 100644 drivers/renesas/rcar/io/io_private.h delete mode 100644 drivers/renesas/rcar/io/io_rcar.c delete mode 100644 drivers/renesas/rcar/io/io_rcar.h diff --git a/drivers/renesas/common/io/io_common.h b/drivers/renesas/common/io/io_common.h new file mode 100644 index 000000000..6eb77777a --- /dev/null +++ b/drivers/renesas/common/io/io_common.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef IO_COMMON_H +#define IO_COMMON_H + +typedef struct io_drv_spec { + size_t offset; + size_t length; + uint32_t partition; +} io_drv_spec_t; + +#endif /* IO_COMMON_H */ diff --git a/drivers/renesas/common/io/io_emmcdrv.c b/drivers/renesas/common/io/io_emmcdrv.c new file mode 100644 index 000000000..c2b5f7c08 --- /dev/null +++ b/drivers/renesas/common/io/io_emmcdrv.c @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include + +#include "emmc_config.h" +#include "emmc_def.h" +#include "emmc_hal.h" +#include "emmc_std.h" +#include "io_common.h" +#include "io_emmcdrv.h" +#include "io_private.h" + +static int32_t emmcdrv_dev_open(const uintptr_t spec __attribute__ ((unused)), + io_dev_info_t **dev_info); +static int32_t emmcdrv_dev_close(io_dev_info_t *dev_info); + +typedef struct { + uint32_t in_use; + uintptr_t base; + signed long long file_pos; + EMMC_PARTITION_ID partition; +} file_state_t; + +static file_state_t current_file = { 0 }; + +static EMMC_PARTITION_ID emmcdrv_bootpartition = PARTITION_ID_USER; + +static io_type_t device_type_emmcdrv(void) +{ + return IO_TYPE_MEMMAP; +} + +static int32_t emmcdrv_block_seek(io_entity_t *entity, int32_t mode, + signed long long offset) +{ + if (mode != IO_SEEK_SET) { + return IO_FAIL; + } + + ((file_state_t *) entity->info)->file_pos = offset; + + return IO_SUCCESS; +} + +static int32_t emmcdrv_block_read(io_entity_t *entity, uintptr_t buffer, + size_t length, size_t *length_read) +{ + file_state_t *fp = (file_state_t *) entity->info; + uint32_t sector_add, sector_num, emmc_dma = 0; + int32_t result = IO_SUCCESS; + + sector_add = current_file.file_pos >> EMMC_SECTOR_SIZE_SHIFT; + sector_num = (length + EMMC_SECTOR_SIZE - 1U) >> EMMC_SECTOR_SIZE_SHIFT; + + NOTICE("BL2: Load dst=0x%lx src=(p:%d)0x%llx(%d) len=0x%lx(%d)\n", + buffer, + current_file.partition, current_file.file_pos, + sector_add, length, sector_num); + + if ((buffer + length - 1U) <= (uintptr_t)UINT32_MAX) { + emmc_dma = LOADIMAGE_FLAGS_DMA_ENABLE; + } + + if (emmc_read_sector((uint32_t *) buffer, sector_add, sector_num, + emmc_dma) != EMMC_SUCCESS) { + result = IO_FAIL; + } + + *length_read = length; + fp->file_pos += (signed long long)length; + + return result; +} + +static int32_t emmcdrv_block_open(io_dev_info_t *dev_info, + const uintptr_t spec, io_entity_t *entity) +{ + const io_drv_spec_t *block_spec = (io_drv_spec_t *) spec; + + if (current_file.in_use != 0U) { + WARN("mmc_block: Only one open spec at a time\n"); + return IO_RESOURCES_EXHAUSTED; + } + + current_file.file_pos = 0; + current_file.in_use = 1; + + if (emmcdrv_bootpartition == PARTITION_ID_USER) { + emmcdrv_bootpartition = mmc_drv_obj.boot_partition_en; + if ((emmcdrv_bootpartition == PARTITION_ID_BOOT_1) || + (emmcdrv_bootpartition == PARTITION_ID_BOOT_2)) { + current_file.partition = emmcdrv_bootpartition; + + NOTICE("BL2: eMMC boot from partition %d\n", + emmcdrv_bootpartition); + goto done; + } + return IO_FAIL; + } + + if ((block_spec->partition == PARTITION_ID_USER) || + (block_spec->partition == PARTITION_ID_BOOT_1) || + (block_spec->partition == PARTITION_ID_BOOT_2)) { + current_file.partition = block_spec->partition; + } else { + current_file.partition = emmcdrv_bootpartition; + } + +done: + if (emmc_select_partition(current_file.partition) != EMMC_SUCCESS) { + return IO_FAIL; + } + + entity->info = (uintptr_t) ¤t_file; + + return IO_SUCCESS; +} + +static int32_t emmcdrv_block_close(io_entity_t *entity) +{ + memset((void *)¤t_file, 0, sizeof(current_file)); + entity->info = 0U; + + return IO_SUCCESS; +} + +static const io_dev_funcs_t emmcdrv_dev_funcs = { + .type = &device_type_emmcdrv, + .open = &emmcdrv_block_open, + .seek = &emmcdrv_block_seek, + .size = NULL, + .read = &emmcdrv_block_read, + .write = NULL, + .close = &emmcdrv_block_close, + .dev_init = NULL, + .dev_close = &emmcdrv_dev_close +}; + +static const io_dev_info_t emmcdrv_dev_info = { + .funcs = &emmcdrv_dev_funcs, + .info = (uintptr_t) 0 +}; + +static const io_dev_connector_t emmcdrv_dev_connector = { + &emmcdrv_dev_open, +}; + +static int32_t emmcdrv_dev_open(const uintptr_t spec __attribute__ ((unused)), + io_dev_info_t **dev_info) +{ + *dev_info = (io_dev_info_t *) &emmcdrv_dev_info; + + return IO_SUCCESS; +} + +static int32_t emmcdrv_dev_close(io_dev_info_t *dev_info) +{ + return IO_SUCCESS; +} + +int32_t rcar_register_io_dev_emmcdrv(const io_dev_connector_t **dev_con) +{ + int32_t rc; + + rc = io_register_device(&emmcdrv_dev_info); + if (rc == IO_SUCCESS) { + *dev_con = &emmcdrv_dev_connector; + } + + return rc; +} diff --git a/drivers/renesas/common/io/io_emmcdrv.h b/drivers/renesas/common/io/io_emmcdrv.h new file mode 100644 index 000000000..95070f24b --- /dev/null +++ b/drivers/renesas/common/io/io_emmcdrv.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef IO_EMMCDRV_H +#define IO_EMMCDRV_H + +struct io_dev_connector; +int32_t rcar_register_io_dev_emmcdrv(const io_dev_connector_t **connector); + +#endif /* IO_EMMCDRV_H */ diff --git a/drivers/renesas/common/io/io_memdrv.c b/drivers/renesas/common/io/io_memdrv.c new file mode 100644 index 000000000..1f31c0fb9 --- /dev/null +++ b/drivers/renesas/common/io/io_memdrv.c @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include + +#include "io_common.h" +#include "io_memdrv.h" +#include "io_private.h" +#include "rcar_def.h" + +extern void rcar_dma_exec(uintptr_t dst, uint32_t src, uint32_t len); + +static int32_t memdrv_dev_open(const uintptr_t dev __attribute__ ((unused)), + io_dev_info_t **dev_info); +static int32_t memdrv_dev_close(io_dev_info_t *dev_info); + +/* + * As we need to be able to keep state for seek, only one file can be open + * at a time. Make this a structure and point to the entity->info. When we + * can malloc memory we can change this to support more open files. + */ +typedef struct { + uint32_t in_use; + uintptr_t base; + signed long long file_pos; +} file_state_t; + +static file_state_t current_file = { 0 }; + +static io_type_t device_type_memdrv(void) +{ + return IO_TYPE_MEMMAP; +} + +static int32_t memdrv_block_open(io_dev_info_t *dev_info, const uintptr_t spec, + io_entity_t *entity) +{ + const io_drv_spec_t *block_spec = (io_drv_spec_t *) spec; + + /* + * Since we need to track open state for seek() we only allow one open + * spec at a time. When we have dynamic memory we can malloc and set + * entity->info. + */ + if (current_file.in_use != 0U) { + return IO_RESOURCES_EXHAUSTED; + } + + /* File cursor offset for seek and incremental reads etc. */ + current_file.base = block_spec->offset; + current_file.file_pos = 0; + current_file.in_use = 1; + + entity->info = (uintptr_t) ¤t_file; + + return IO_SUCCESS; +} + +static int32_t memdrv_block_seek(io_entity_t *entity, int32_t mode, + signed long long offset) +{ + if (mode != IO_SEEK_SET) { + return IO_FAIL; + } + + ((file_state_t *) entity->info)->file_pos = offset; + + return IO_SUCCESS; +} + +static int32_t memdrv_block_read(io_entity_t *entity, uintptr_t buffer, + size_t length, size_t *cnt) +{ + file_state_t *fp; + + fp = (file_state_t *) entity->info; + + NOTICE("BL2: dst=0x%lx src=0x%llx len=%ld(0x%lx)\n", + buffer, (unsigned long long)fp->base + + (unsigned long long)fp->file_pos, length, length); + + if (FLASH_MEMORY_SIZE < (fp->file_pos + (signed long long)length)) { + ERROR("BL2: check load image (source address)\n"); + return IO_FAIL; + } + + rcar_dma_exec(buffer, fp->base + (uintptr_t)fp->file_pos, length); + fp->file_pos += (signed long long)length; + *cnt = length; + + return IO_SUCCESS; +} + +static int32_t memdrv_block_close(io_entity_t *entity) +{ + entity->info = 0U; + + memset((void *)¤t_file, 0, sizeof(current_file)); + + return IO_SUCCESS; +} + +static const io_dev_funcs_t memdrv_dev_funcs = { + .type = &device_type_memdrv, + .open = &memdrv_block_open, + .seek = &memdrv_block_seek, + .size = NULL, + .read = &memdrv_block_read, + .write = NULL, + .close = &memdrv_block_close, + .dev_init = NULL, + .dev_close = &memdrv_dev_close, +}; + +static const io_dev_info_t memdrv_dev_info = { + .funcs = &memdrv_dev_funcs, + .info = 0, +}; + +static const io_dev_connector_t memdrv_dev_connector = { + .dev_open = &memdrv_dev_open +}; + +static int32_t memdrv_dev_open(const uintptr_t dev __attribute__ ((unused)), + io_dev_info_t **dev_info) +{ + *dev_info = (io_dev_info_t *) &memdrv_dev_info; + + return IO_SUCCESS; +} + +static int32_t memdrv_dev_close(io_dev_info_t *dev_info) +{ + return IO_SUCCESS; +} + +int32_t rcar_register_io_dev_memdrv(const io_dev_connector_t **dev_con) +{ + int32_t result; + + result = io_register_device(&memdrv_dev_info); + if (result == IO_SUCCESS) { + *dev_con = &memdrv_dev_connector; + } + + return result; +} diff --git a/drivers/renesas/common/io/io_memdrv.h b/drivers/renesas/common/io/io_memdrv.h new file mode 100644 index 000000000..90e68123e --- /dev/null +++ b/drivers/renesas/common/io/io_memdrv.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef IO_MEMDRV_H +#define IO_MEMDRV_H + +struct io_dev_connector; +int32_t rcar_register_io_dev_memdrv(const io_dev_connector_t **connector); + +#endif /* IO_MEMDRV_H */ diff --git a/drivers/renesas/common/io/io_private.h b/drivers/renesas/common/io/io_private.h new file mode 100644 index 000000000..207523a73 --- /dev/null +++ b/drivers/renesas/common/io/io_private.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef IO_PRIVATE_H +#define IO_PRIVATE_H + +/* + * Return codes reported by 'io_*' APIs + * The value of fail should not overlap with define of the errno. + * The errno is in "include/lib/stdlib/sys/errno.h". + */ +#define IO_SUCCESS (0) +#define IO_FAIL (-0x81) +#define IO_NOT_SUPPORTED (-0x82) +#define IO_RESOURCES_EXHAUSTED (-0x83) + +#endif /* IO_PRIVATE_H */ diff --git a/drivers/renesas/common/io/io_rcar.c b/drivers/renesas/common/io/io_rcar.c new file mode 100644 index 000000000..c3e8319de --- /dev/null +++ b/drivers/renesas/common/io/io_rcar.c @@ -0,0 +1,654 @@ +/* + * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "io_rcar.h" +#include "io_common.h" +#include "io_private.h" +#include + +extern int32_t plat_get_drv_source(uint32_t id, uintptr_t *dev, + uintptr_t *image_spec); + +static int32_t rcar_dev_open(const uintptr_t dev_spec __attribute__ ((unused)), + io_dev_info_t **dev_info); +static int32_t rcar_dev_close(io_dev_info_t *dev_info); + +typedef struct { + const int32_t name; + const uint32_t offset; + const uint32_t attr; +} plat_rcar_name_offset_t; + +typedef struct { + /* + * Put position above the struct to allow {0} on static init. + * It is a workaround for a known bug in GCC + * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53119 + */ + uint32_t position; + uint32_t no_load; + uintptr_t offset; + uint32_t size; + uintptr_t dst; + uintptr_t partition; /* for eMMC */ + /* RCAR_EMMC_PARTITION_BOOT_0 */ + /* RCAR_EMMC_PARTITION_BOOT_1 */ + /* RCAR_EMMC_PARTITION_USER */ +} file_state_t; + +#define RCAR_GET_FLASH_ADR(a, b) ((uint32_t)((0x40000U * (a)) + (b))) +#define RCAR_ATTR_SET_CALCADDR(a) ((a) & 0xF) +#define RCAR_ATTR_SET_ISNOLOAD(a) (((a) & 0x1) << 16U) +#define RCAR_ATTR_SET_CERTOFF(a) (((a) & 0xF) << 8U) +#define RCAR_ATTR_SET_ALL(a, b, c) ((uint32_t)(RCAR_ATTR_SET_CALCADDR(a) |\ + RCAR_ATTR_SET_ISNOLOAD(b) |\ + RCAR_ATTR_SET_CERTOFF(c))) + +#define RCAR_ATTR_GET_CALCADDR(a) ((a) & 0xFU) +#define RCAR_ATTR_GET_ISNOLOAD(a) (((a) >> 16) & 0x1U) +#define RCAR_ATTR_GET_CERTOFF(a) ((uint32_t)(((a) >> 8) & 0xFU)) + +#define RCAR_MAX_BL3X_IMAGE (8U) +#define RCAR_SECTOR6_CERT_OFFSET (0x400U) +#define RCAR_SDRAM_certESS (0x43F00000U) +#define RCAR_CERT_SIZE (0x800U) +#define RCAR_CERT_INFO_SIZE_OFFSET (0x264U) +#define RCAR_CERT_INFO_DST_OFFSET (0x154U) +#define RCAR_CERT_INFO_SIZE_OFFSET1 (0x364U) +#define RCAR_CERT_INFO_DST_OFFSET1 (0x1D4U) +#define RCAR_CERT_INFO_SIZE_OFFSET2 (0x464U) +#define RCAR_CERT_INFO_DST_OFFSET2 (0x254U) +#define RCAR_CERT_LOAD (1U) + +#define RCAR_FLASH_CERT_HEADER RCAR_GET_FLASH_ADR(6U, 0U) +#define RCAR_EMMC_CERT_HEADER (0x00030000U) + +#define RCAR_COUNT_LOAD_BL33 (2U) +#define RCAR_COUNT_LOAD_BL33X (3U) + +static const plat_rcar_name_offset_t name_offset[] = { + {BL31_IMAGE_ID, 0U, RCAR_ATTR_SET_ALL(0, 0, 0)}, + + /* BL3-2 is optional in the platform */ + {BL32_IMAGE_ID, 0U, RCAR_ATTR_SET_ALL(1, 0, 1)}, + {BL33_IMAGE_ID, 0U, RCAR_ATTR_SET_ALL(2, 0, 2)}, + {BL332_IMAGE_ID, 0U, RCAR_ATTR_SET_ALL(3, 0, 3)}, + {BL333_IMAGE_ID, 0U, RCAR_ATTR_SET_ALL(4, 0, 4)}, + {BL334_IMAGE_ID, 0U, RCAR_ATTR_SET_ALL(5, 0, 5)}, + {BL335_IMAGE_ID, 0U, RCAR_ATTR_SET_ALL(6, 0, 6)}, + {BL336_IMAGE_ID, 0U, RCAR_ATTR_SET_ALL(7, 0, 7)}, + {BL337_IMAGE_ID, 0U, RCAR_ATTR_SET_ALL(8, 0, 8)}, + {BL338_IMAGE_ID, 0U, RCAR_ATTR_SET_ALL(9, 0, 9)}, +}; + +#if TRUSTED_BOARD_BOOT +static const plat_rcar_name_offset_t cert_offset[] = { + /* Certificates */ + {TRUSTED_KEY_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 0)}, + {SOC_FW_KEY_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 0)}, + {TRUSTED_OS_FW_KEY_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 0)}, + {NON_TRUSTED_FW_KEY_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 0)}, + {SOC_FW_CONTENT_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 0)}, + {TRUSTED_OS_FW_CONTENT_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 1)}, + {NON_TRUSTED_FW_CONTENT_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 2)}, + {BL332_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 3)}, + {BL333_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 4)}, + {BL334_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 5)}, + {BL335_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 6)}, + {BL336_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 7)}, + {BL337_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 8)}, + {BL338_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 9)}, +}; +#endif /* TRUSTED_BOARD_BOOT */ + +static file_state_t current_file = { 0 }; + +static uintptr_t rcar_handle, rcar_spec; +static uint64_t rcar_image_header[RCAR_MAX_BL3X_IMAGE + 2U] = { 0U }; +static uint64_t rcar_image_header_prttn[RCAR_MAX_BL3X_IMAGE + 2U] = { 0U }; +static uint64_t rcar_image_number = { 0U }; +static uint32_t rcar_cert_load = { 0U }; + +static io_type_t device_type_rcar(void) +{ + return IO_TYPE_FIRMWARE_IMAGE_PACKAGE; +} + +int32_t rcar_get_certificate(const int32_t name, uint32_t *cert) +{ +#if TRUSTED_BOARD_BOOT + int32_t i; + + for (i = 0; i < ARRAY_SIZE(cert_offset); i++) { + if (name != cert_offset[i].name) { + continue; + } + + *cert = RCAR_CERT_SIZE; + *cert *= RCAR_ATTR_GET_CERTOFF(cert_offset[i].attr); + *cert += RCAR_SDRAM_certESS; + return 0; + } +#endif + return -EINVAL; +} + +static int32_t file_to_offset(const int32_t name, uintptr_t *offset, + uint32_t *cert, uint32_t *no_load, + uintptr_t *partition) +{ + uint32_t addr; + int32_t i; + + for (i = 0; i < ARRAY_SIZE(name_offset); i++) { + if (name != name_offset[i].name) { + continue; + } + + addr = RCAR_ATTR_GET_CALCADDR(name_offset[i].attr); + if (rcar_image_number + 2U < addr) { + continue; + } + + *offset = rcar_image_header[addr]; + *cert = RCAR_CERT_SIZE; + *cert *= RCAR_ATTR_GET_CERTOFF(name_offset[i].attr); + *cert += RCAR_SDRAM_certESS; + *no_load = RCAR_ATTR_GET_ISNOLOAD(name_offset[i].attr); + *partition = rcar_image_header_prttn[addr]; + return IO_SUCCESS; + } + +#if TRUSTED_BOARD_BOOT + for (i = 0; i < ARRAY_SIZE(cert_offset); i++) { + if (name != cert_offset[i].name) { + continue; + } + + *no_load = RCAR_ATTR_GET_ISNOLOAD(cert_offset[i].attr); + *partition = 0U; + *offset = 0U; + *cert = 0U; + return IO_SUCCESS; + } +#endif + return -EINVAL; +} + +#define RCAR_BOOT_KEY_CERT_NEW (0xE6300F00U) +#define RCAR_CERT_MAGIC_NUM (0xE291F358U) + +void rcar_read_certificate(uint64_t cert, uint32_t *len, uintptr_t *dst) +{ + uint32_t seed, val, info_1, info_2; + uintptr_t size, dsth, dstl; + + cert &= 0xFFFFFFFFU; + + seed = mmio_read_32(RCAR_BOOT_KEY_CERT_NEW); + val = mmio_read_32(RCAR_BOOT_KEY_CERT_NEW + 0xC); + info_1 = (val >> 18) & 0x3U; + val = mmio_read_32(cert + 0xC); + info_2 = (val >> 21) & 0x3; + + if (seed == RCAR_CERT_MAGIC_NUM) { + if (info_1 != 1) { + ERROR("BL2: Cert is invalid.\n"); + *dst = 0; + *len = 0; + return; + } + + if (info_2 > 2) { + ERROR("BL2: Cert is invalid.\n"); + *dst = 0; + *len = 0; + return; + } + + switch (info_2) { + case 2: + size = cert + RCAR_CERT_INFO_SIZE_OFFSET2; + dstl = cert + RCAR_CERT_INFO_DST_OFFSET2; + break; + case 1: + size = cert + RCAR_CERT_INFO_SIZE_OFFSET1; + dstl = cert + RCAR_CERT_INFO_DST_OFFSET1; + break; + case 0: + size = cert + RCAR_CERT_INFO_SIZE_OFFSET; + dstl = cert + RCAR_CERT_INFO_DST_OFFSET; + break; + } + + *len = mmio_read_32(size) * 4U; + dsth = dstl + 4U; + *dst = ((uintptr_t) mmio_read_32(dsth) << 32) + + ((uintptr_t) mmio_read_32(dstl)); + return; + } + + size = cert + RCAR_CERT_INFO_SIZE_OFFSET; + *len = mmio_read_32(size) * 4U; + dstl = cert + RCAR_CERT_INFO_DST_OFFSET; + dsth = dstl + 4U; + *dst = ((uintptr_t) mmio_read_32(dsth) << 32) + + ((uintptr_t) mmio_read_32(dstl)); +} + +static int32_t check_load_area(uintptr_t dst, uintptr_t len) +{ + uint32_t legacy = dst + len <= UINT32_MAX - 1 ? 1 : 0; + uintptr_t dram_start, dram_end; + uintptr_t prot_start, prot_end; + int32_t result = IO_SUCCESS; + + dram_start = legacy ? DRAM1_BASE : DRAM_40BIT_BASE; + + dram_end = legacy ? DRAM1_BASE + DRAM1_SIZE : + DRAM_40BIT_BASE + DRAM_40BIT_SIZE; + + prot_start = legacy ? DRAM_PROTECTED_BASE : DRAM_40BIT_PROTECTED_BASE; + + prot_end = prot_start + DRAM_PROTECTED_SIZE; + + if (dst < dram_start || dst > dram_end - len) { + ERROR("BL2: dst address is on the protected area.\n"); + result = IO_FAIL; + goto done; + } + + /* load image is within SDRAM protected area */ + if (dst >= prot_start && dst < prot_end) { + ERROR("BL2: dst address is on the protected area.\n"); + result = IO_FAIL; + } + + if (dst < prot_start && dst > prot_start - len) { + ERROR("BL2: loaded data is on the protected area.\n"); + result = IO_FAIL; + } +done: + if (result == IO_FAIL) { + ERROR("BL2: Out of range : dst=0x%lx len=0x%lx\n", dst, len); + } + + return result; +} + +static int32_t load_bl33x(void) +{ + static int32_t loaded = IO_NOT_SUPPORTED; + uintptr_t dst, partition, handle; + uint32_t noload, cert, len, i; + uintptr_t offset; + int32_t rc; + size_t cnt; + const int32_t img[] = { + BL33_IMAGE_ID, + BL332_IMAGE_ID, + BL333_IMAGE_ID, + BL334_IMAGE_ID, + BL335_IMAGE_ID, + BL336_IMAGE_ID, + BL337_IMAGE_ID, + BL338_IMAGE_ID + }; + + if (loaded != IO_NOT_SUPPORTED) { + return loaded; + } + + for (i = 1; i < rcar_image_number; i++) { + rc = file_to_offset(img[i], &offset, &cert, &noload, + &partition); + if (rc != IO_SUCCESS) { + WARN("%s: failed to get offset\n", __func__); + loaded = IO_FAIL; + return loaded; + } + + rcar_read_certificate((uint64_t) cert, &len, &dst); + ((io_drv_spec_t *) rcar_spec)->partition = partition; + + rc = io_open(rcar_handle, rcar_spec, &handle); + if (rc != IO_SUCCESS) { + WARN("%s: Failed to open FIP (%i)\n", __func__, rc); + loaded = IO_FAIL; + return loaded; + } + + rc = io_seek(handle, IO_SEEK_SET, offset); + if (rc != IO_SUCCESS) { + WARN("%s: failed to seek\n", __func__); + loaded = IO_FAIL; + return loaded; + } + + rc = check_load_area(dst, len); + if (rc != IO_SUCCESS) { + WARN("%s: check load area\n", __func__); + loaded = IO_FAIL; + return loaded; + } + + rc = io_read(handle, dst, len, &cnt); + if (rc != IO_SUCCESS) { + WARN("%s: failed to read\n", __func__); + loaded = IO_FAIL; + return loaded; + } +#if TRUSTED_BOARD_BOOT + rc = auth_mod_verify_img(img[i], (void *)dst, len); + if (rc != 0) { + memset((void *)dst, 0x00, len); + loaded = IO_FAIL; + return loaded; + } +#endif + io_close(handle); + } + + loaded = IO_SUCCESS; + + return loaded; +} + +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}; + uintptr_t handle; + ssize_t offset; + uint32_t i; + int32_t rc; + size_t cnt; + + /* Obtain a reference to the image by querying the platform layer */ + rc = plat_get_drv_source(name, &rcar_handle, &rcar_spec); + if (rc != IO_SUCCESS) { + WARN("Failed to obtain reference to img %ld (%i)\n", name, rc); + return IO_FAIL; + } + + if (rcar_cert_load == RCAR_CERT_LOAD) { + return IO_SUCCESS; + } + + rc = io_open(rcar_handle, rcar_spec, &handle); + if (rc != IO_SUCCESS) { + WARN("Failed to access img %ld (%i)\n", name, rc); + return IO_FAIL; + } + + /* + * get start address list + * [0] address num + * [1] BL33-1 image address + * [2] BL33-2 image address + * [3] BL33-3 image address + * [4] BL33-4 image address + * [5] BL33-5 image address + * [6] BL33-6 image address + * [7] BL33-7 image address + * [8] BL33-8 image address + */ + offset = name == EMMC_DEV_ID ? RCAR_EMMC_CERT_HEADER : + RCAR_FLASH_CERT_HEADER; + rc = io_seek(handle, IO_SEEK_SET, offset); + if (rc != IO_SUCCESS) { + 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; + } + + rcar_image_number = header[0]; + for (i = 0; i < rcar_image_number + 2; i++) { + rcar_image_header[i] = header[i * 2 + 1]; + rcar_image_header_prttn[i] = header[i * 2 + 2]; + } + + if (rcar_image_number == 0 || rcar_image_number > RCAR_MAX_BL3X_IMAGE) { + WARN("Firmware Image Package header check failed.\n"); + goto error; + } + + rc = io_seek(handle, IO_SEEK_SET, offset + RCAR_SECTOR6_CERT_OFFSET); + if (rc != IO_SUCCESS) { + 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) { + WARN("cert file read error.\n"); + goto error; + } + + rcar_cert_load = RCAR_CERT_LOAD; +error: + + if (rc != IO_SUCCESS) { + rc = IO_FAIL; + } + + io_close(handle); + + return rc; + +} + +static int32_t rcar_file_open(io_dev_info_t *info, const uintptr_t file_spec, + io_entity_t *entity) +{ + const io_drv_spec_t *spec = (io_drv_spec_t *) file_spec; + uintptr_t partition, offset, dst; + uint32_t noload, cert, len; + int32_t rc; + + /* + * Only one file open at a time. We need to track state (ie, file + * cursor position). Since the header lives at offset zero, this entry + * should never be zero in an active file. + * Once the system supports dynamic memory allocation we will allow more + * than one open file at a time. + */ + if (current_file.offset != 0U) { + WARN("%s: Only one open file at a time.\n", __func__); + return IO_RESOURCES_EXHAUSTED; + } + + rc = file_to_offset(spec->offset, &offset, &cert, &noload, &partition); + if (rc != IO_SUCCESS) { + WARN("Failed to open file name %ld (%i)\n", spec->offset, rc); + return IO_FAIL; + } + + if (noload != 0U) { + current_file.offset = 1; + current_file.dst = 0; + current_file.size = 1; + current_file.position = 0; + current_file.no_load = noload; + current_file.partition = 0; + entity->info = (uintptr_t) ¤t_file; + + return IO_SUCCESS; + } + + rcar_read_certificate((uint64_t) cert, &len, &dst); + + /* Baylibre: HACK */ + if (spec->offset == BL31_IMAGE_ID && len < RCAR_TRUSTED_SRAM_SIZE) { + WARN("%s,%s\n", "r-car ignoring the BL31 size from certificate", + "using RCAR_TRUSTED_SRAM_SIZE instead"); + len = RCAR_TRUSTED_SRAM_SIZE; + } + + current_file.partition = partition; + current_file.no_load = noload; + current_file.offset = offset; + current_file.position = 0; + current_file.size = len; + current_file.dst = dst; + entity->info = (uintptr_t) ¤t_file; + + return IO_SUCCESS; +} + +static int32_t rcar_file_len(io_entity_t *entity, size_t *length) +{ + *length = ((file_state_t *) entity->info)->size; + + NOTICE("%s: len: 0x%08lx\n", __func__, *length); + + return IO_SUCCESS; +} + +static int32_t rcar_file_read(io_entity_t *entity, uintptr_t buffer, + size_t length, size_t *cnt) +{ + file_state_t *fp = (file_state_t *) entity->info; + ssize_t offset = fp->offset + fp->position; + uintptr_t handle; + int32_t rc; + +#ifdef SPD_NONE + static uint32_t load_bl33x_counter = 1; +#else + static uint32_t load_bl33x_counter; +#endif + if (current_file.no_load != 0U) { + *cnt = length; + return IO_SUCCESS; + } + + ((io_drv_spec_t *) rcar_spec)->partition = fp->partition; + + rc = io_open(rcar_handle, rcar_spec, &handle); + if (rc != IO_SUCCESS) { + WARN("Failed to open FIP (%i)\n", rc); + return IO_FAIL; + } + + rc = io_seek(handle, IO_SEEK_SET, offset); + if (rc != IO_SUCCESS) { + WARN("%s: failed to seek\n", __func__); + goto error; + } + + if (load_bl33x_counter == RCAR_COUNT_LOAD_BL33) { + rc = check_load_area(buffer, length); + if (rc != IO_SUCCESS) { + WARN("%s: load area err\n", __func__); + goto error; + } + } + + rc = io_read(handle, buffer, length, cnt); + if (rc != IO_SUCCESS) { + WARN("Failed to read payload (%i)\n", rc); + goto error; + } + + fp->position += *cnt; + io_close(handle); + + load_bl33x_counter += 1; + if (load_bl33x_counter == RCAR_COUNT_LOAD_BL33X) { + return load_bl33x(); + } + + return IO_SUCCESS; +error: + io_close(handle); + return IO_FAIL; +} + +static int32_t rcar_file_close(io_entity_t *entity) +{ + if (current_file.offset != 0U) { + memset(¤t_file, 0, sizeof(current_file)); + } + + entity->info = 0U; + + return IO_SUCCESS; +} + +static const io_dev_funcs_t rcar_dev_funcs = { + .type = &device_type_rcar, + .open = &rcar_file_open, + .seek = NULL, + .size = &rcar_file_len, + .read = &rcar_file_read, + .write = NULL, + .close = &rcar_file_close, + .dev_init = &rcar_dev_init, + .dev_close = &rcar_dev_close, +}; + +static const io_dev_info_t rcar_dev_info = { + .funcs = &rcar_dev_funcs, + .info = (uintptr_t) 0 +}; + +static const io_dev_connector_t rcar_dev_connector = { + .dev_open = &rcar_dev_open +}; + +static int32_t rcar_dev_open(const uintptr_t dev_spec __attribute__ ((unused)), + io_dev_info_t **dev_info) +{ + *dev_info = (io_dev_info_t *) &rcar_dev_info; + + return IO_SUCCESS; +} + +static int32_t rcar_dev_close(io_dev_info_t *dev_info) +{ + rcar_handle = 0; + rcar_spec = 0; + + return IO_SUCCESS; +} + +int32_t rcar_register_io_dev(const io_dev_connector_t **dev_con) +{ + int32_t result; + + result = io_register_device(&rcar_dev_info); + if (result == IO_SUCCESS) { + *dev_con = &rcar_dev_connector; + } + + return result; +} diff --git a/drivers/renesas/common/io/io_rcar.h b/drivers/renesas/common/io/io_rcar.h new file mode 100644 index 000000000..c26a61767 --- /dev/null +++ b/drivers/renesas/common/io/io_rcar.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef IO_RCAR_H +#define IO_RCAR_H + +int32_t rcar_register_io_dev(const io_dev_connector_t **dev_con); +int32_t rcar_get_certificate(const int32_t name, uint32_t *cert); +void rcar_read_certificate(uint64_t cert, uint32_t *size, uintptr_t *dest); + +#endif /* IO_RCAR_H */ diff --git a/drivers/renesas/rcar/io/io_common.h b/drivers/renesas/rcar/io/io_common.h deleted file mode 100644 index 6eb77777a..000000000 --- a/drivers/renesas/rcar/io/io_common.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef IO_COMMON_H -#define IO_COMMON_H - -typedef struct io_drv_spec { - size_t offset; - size_t length; - uint32_t partition; -} io_drv_spec_t; - -#endif /* IO_COMMON_H */ diff --git a/drivers/renesas/rcar/io/io_emmcdrv.c b/drivers/renesas/rcar/io/io_emmcdrv.c deleted file mode 100644 index c2b5f7c08..000000000 --- a/drivers/renesas/rcar/io/io_emmcdrv.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include -#include -#include - -#include "emmc_config.h" -#include "emmc_def.h" -#include "emmc_hal.h" -#include "emmc_std.h" -#include "io_common.h" -#include "io_emmcdrv.h" -#include "io_private.h" - -static int32_t emmcdrv_dev_open(const uintptr_t spec __attribute__ ((unused)), - io_dev_info_t **dev_info); -static int32_t emmcdrv_dev_close(io_dev_info_t *dev_info); - -typedef struct { - uint32_t in_use; - uintptr_t base; - signed long long file_pos; - EMMC_PARTITION_ID partition; -} file_state_t; - -static file_state_t current_file = { 0 }; - -static EMMC_PARTITION_ID emmcdrv_bootpartition = PARTITION_ID_USER; - -static io_type_t device_type_emmcdrv(void) -{ - return IO_TYPE_MEMMAP; -} - -static int32_t emmcdrv_block_seek(io_entity_t *entity, int32_t mode, - signed long long offset) -{ - if (mode != IO_SEEK_SET) { - return IO_FAIL; - } - - ((file_state_t *) entity->info)->file_pos = offset; - - return IO_SUCCESS; -} - -static int32_t emmcdrv_block_read(io_entity_t *entity, uintptr_t buffer, - size_t length, size_t *length_read) -{ - file_state_t *fp = (file_state_t *) entity->info; - uint32_t sector_add, sector_num, emmc_dma = 0; - int32_t result = IO_SUCCESS; - - sector_add = current_file.file_pos >> EMMC_SECTOR_SIZE_SHIFT; - sector_num = (length + EMMC_SECTOR_SIZE - 1U) >> EMMC_SECTOR_SIZE_SHIFT; - - NOTICE("BL2: Load dst=0x%lx src=(p:%d)0x%llx(%d) len=0x%lx(%d)\n", - buffer, - current_file.partition, current_file.file_pos, - sector_add, length, sector_num); - - if ((buffer + length - 1U) <= (uintptr_t)UINT32_MAX) { - emmc_dma = LOADIMAGE_FLAGS_DMA_ENABLE; - } - - if (emmc_read_sector((uint32_t *) buffer, sector_add, sector_num, - emmc_dma) != EMMC_SUCCESS) { - result = IO_FAIL; - } - - *length_read = length; - fp->file_pos += (signed long long)length; - - return result; -} - -static int32_t emmcdrv_block_open(io_dev_info_t *dev_info, - const uintptr_t spec, io_entity_t *entity) -{ - const io_drv_spec_t *block_spec = (io_drv_spec_t *) spec; - - if (current_file.in_use != 0U) { - WARN("mmc_block: Only one open spec at a time\n"); - return IO_RESOURCES_EXHAUSTED; - } - - current_file.file_pos = 0; - current_file.in_use = 1; - - if (emmcdrv_bootpartition == PARTITION_ID_USER) { - emmcdrv_bootpartition = mmc_drv_obj.boot_partition_en; - if ((emmcdrv_bootpartition == PARTITION_ID_BOOT_1) || - (emmcdrv_bootpartition == PARTITION_ID_BOOT_2)) { - current_file.partition = emmcdrv_bootpartition; - - NOTICE("BL2: eMMC boot from partition %d\n", - emmcdrv_bootpartition); - goto done; - } - return IO_FAIL; - } - - if ((block_spec->partition == PARTITION_ID_USER) || - (block_spec->partition == PARTITION_ID_BOOT_1) || - (block_spec->partition == PARTITION_ID_BOOT_2)) { - current_file.partition = block_spec->partition; - } else { - current_file.partition = emmcdrv_bootpartition; - } - -done: - if (emmc_select_partition(current_file.partition) != EMMC_SUCCESS) { - return IO_FAIL; - } - - entity->info = (uintptr_t) ¤t_file; - - return IO_SUCCESS; -} - -static int32_t emmcdrv_block_close(io_entity_t *entity) -{ - memset((void *)¤t_file, 0, sizeof(current_file)); - entity->info = 0U; - - return IO_SUCCESS; -} - -static const io_dev_funcs_t emmcdrv_dev_funcs = { - .type = &device_type_emmcdrv, - .open = &emmcdrv_block_open, - .seek = &emmcdrv_block_seek, - .size = NULL, - .read = &emmcdrv_block_read, - .write = NULL, - .close = &emmcdrv_block_close, - .dev_init = NULL, - .dev_close = &emmcdrv_dev_close -}; - -static const io_dev_info_t emmcdrv_dev_info = { - .funcs = &emmcdrv_dev_funcs, - .info = (uintptr_t) 0 -}; - -static const io_dev_connector_t emmcdrv_dev_connector = { - &emmcdrv_dev_open, -}; - -static int32_t emmcdrv_dev_open(const uintptr_t spec __attribute__ ((unused)), - io_dev_info_t **dev_info) -{ - *dev_info = (io_dev_info_t *) &emmcdrv_dev_info; - - return IO_SUCCESS; -} - -static int32_t emmcdrv_dev_close(io_dev_info_t *dev_info) -{ - return IO_SUCCESS; -} - -int32_t rcar_register_io_dev_emmcdrv(const io_dev_connector_t **dev_con) -{ - int32_t rc; - - rc = io_register_device(&emmcdrv_dev_info); - if (rc == IO_SUCCESS) { - *dev_con = &emmcdrv_dev_connector; - } - - return rc; -} diff --git a/drivers/renesas/rcar/io/io_emmcdrv.h b/drivers/renesas/rcar/io/io_emmcdrv.h deleted file mode 100644 index 95070f24b..000000000 --- a/drivers/renesas/rcar/io/io_emmcdrv.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef IO_EMMCDRV_H -#define IO_EMMCDRV_H - -struct io_dev_connector; -int32_t rcar_register_io_dev_emmcdrv(const io_dev_connector_t **connector); - -#endif /* IO_EMMCDRV_H */ diff --git a/drivers/renesas/rcar/io/io_memdrv.c b/drivers/renesas/rcar/io/io_memdrv.c deleted file mode 100644 index 1f31c0fb9..000000000 --- a/drivers/renesas/rcar/io/io_memdrv.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include -#include -#include - -#include "io_common.h" -#include "io_memdrv.h" -#include "io_private.h" -#include "rcar_def.h" - -extern void rcar_dma_exec(uintptr_t dst, uint32_t src, uint32_t len); - -static int32_t memdrv_dev_open(const uintptr_t dev __attribute__ ((unused)), - io_dev_info_t **dev_info); -static int32_t memdrv_dev_close(io_dev_info_t *dev_info); - -/* - * As we need to be able to keep state for seek, only one file can be open - * at a time. Make this a structure and point to the entity->info. When we - * can malloc memory we can change this to support more open files. - */ -typedef struct { - uint32_t in_use; - uintptr_t base; - signed long long file_pos; -} file_state_t; - -static file_state_t current_file = { 0 }; - -static io_type_t device_type_memdrv(void) -{ - return IO_TYPE_MEMMAP; -} - -static int32_t memdrv_block_open(io_dev_info_t *dev_info, const uintptr_t spec, - io_entity_t *entity) -{ - const io_drv_spec_t *block_spec = (io_drv_spec_t *) spec; - - /* - * Since we need to track open state for seek() we only allow one open - * spec at a time. When we have dynamic memory we can malloc and set - * entity->info. - */ - if (current_file.in_use != 0U) { - return IO_RESOURCES_EXHAUSTED; - } - - /* File cursor offset for seek and incremental reads etc. */ - current_file.base = block_spec->offset; - current_file.file_pos = 0; - current_file.in_use = 1; - - entity->info = (uintptr_t) ¤t_file; - - return IO_SUCCESS; -} - -static int32_t memdrv_block_seek(io_entity_t *entity, int32_t mode, - signed long long offset) -{ - if (mode != IO_SEEK_SET) { - return IO_FAIL; - } - - ((file_state_t *) entity->info)->file_pos = offset; - - return IO_SUCCESS; -} - -static int32_t memdrv_block_read(io_entity_t *entity, uintptr_t buffer, - size_t length, size_t *cnt) -{ - file_state_t *fp; - - fp = (file_state_t *) entity->info; - - NOTICE("BL2: dst=0x%lx src=0x%llx len=%ld(0x%lx)\n", - buffer, (unsigned long long)fp->base + - (unsigned long long)fp->file_pos, length, length); - - if (FLASH_MEMORY_SIZE < (fp->file_pos + (signed long long)length)) { - ERROR("BL2: check load image (source address)\n"); - return IO_FAIL; - } - - rcar_dma_exec(buffer, fp->base + (uintptr_t)fp->file_pos, length); - fp->file_pos += (signed long long)length; - *cnt = length; - - return IO_SUCCESS; -} - -static int32_t memdrv_block_close(io_entity_t *entity) -{ - entity->info = 0U; - - memset((void *)¤t_file, 0, sizeof(current_file)); - - return IO_SUCCESS; -} - -static const io_dev_funcs_t memdrv_dev_funcs = { - .type = &device_type_memdrv, - .open = &memdrv_block_open, - .seek = &memdrv_block_seek, - .size = NULL, - .read = &memdrv_block_read, - .write = NULL, - .close = &memdrv_block_close, - .dev_init = NULL, - .dev_close = &memdrv_dev_close, -}; - -static const io_dev_info_t memdrv_dev_info = { - .funcs = &memdrv_dev_funcs, - .info = 0, -}; - -static const io_dev_connector_t memdrv_dev_connector = { - .dev_open = &memdrv_dev_open -}; - -static int32_t memdrv_dev_open(const uintptr_t dev __attribute__ ((unused)), - io_dev_info_t **dev_info) -{ - *dev_info = (io_dev_info_t *) &memdrv_dev_info; - - return IO_SUCCESS; -} - -static int32_t memdrv_dev_close(io_dev_info_t *dev_info) -{ - return IO_SUCCESS; -} - -int32_t rcar_register_io_dev_memdrv(const io_dev_connector_t **dev_con) -{ - int32_t result; - - result = io_register_device(&memdrv_dev_info); - if (result == IO_SUCCESS) { - *dev_con = &memdrv_dev_connector; - } - - return result; -} diff --git a/drivers/renesas/rcar/io/io_memdrv.h b/drivers/renesas/rcar/io/io_memdrv.h deleted file mode 100644 index 90e68123e..000000000 --- a/drivers/renesas/rcar/io/io_memdrv.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef IO_MEMDRV_H -#define IO_MEMDRV_H - -struct io_dev_connector; -int32_t rcar_register_io_dev_memdrv(const io_dev_connector_t **connector); - -#endif /* IO_MEMDRV_H */ diff --git a/drivers/renesas/rcar/io/io_private.h b/drivers/renesas/rcar/io/io_private.h deleted file mode 100644 index 207523a73..000000000 --- a/drivers/renesas/rcar/io/io_private.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef IO_PRIVATE_H -#define IO_PRIVATE_H - -/* - * Return codes reported by 'io_*' APIs - * The value of fail should not overlap with define of the errno. - * The errno is in "include/lib/stdlib/sys/errno.h". - */ -#define IO_SUCCESS (0) -#define IO_FAIL (-0x81) -#define IO_NOT_SUPPORTED (-0x82) -#define IO_RESOURCES_EXHAUSTED (-0x83) - -#endif /* IO_PRIVATE_H */ diff --git a/drivers/renesas/rcar/io/io_rcar.c b/drivers/renesas/rcar/io/io_rcar.c deleted file mode 100644 index c3e8319de..000000000 --- a/drivers/renesas/rcar/io/io_rcar.c +++ /dev/null @@ -1,654 +0,0 @@ -/* - * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "io_rcar.h" -#include "io_common.h" -#include "io_private.h" -#include - -extern int32_t plat_get_drv_source(uint32_t id, uintptr_t *dev, - uintptr_t *image_spec); - -static int32_t rcar_dev_open(const uintptr_t dev_spec __attribute__ ((unused)), - io_dev_info_t **dev_info); -static int32_t rcar_dev_close(io_dev_info_t *dev_info); - -typedef struct { - const int32_t name; - const uint32_t offset; - const uint32_t attr; -} plat_rcar_name_offset_t; - -typedef struct { - /* - * Put position above the struct to allow {0} on static init. - * It is a workaround for a known bug in GCC - * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53119 - */ - uint32_t position; - uint32_t no_load; - uintptr_t offset; - uint32_t size; - uintptr_t dst; - uintptr_t partition; /* for eMMC */ - /* RCAR_EMMC_PARTITION_BOOT_0 */ - /* RCAR_EMMC_PARTITION_BOOT_1 */ - /* RCAR_EMMC_PARTITION_USER */ -} file_state_t; - -#define RCAR_GET_FLASH_ADR(a, b) ((uint32_t)((0x40000U * (a)) + (b))) -#define RCAR_ATTR_SET_CALCADDR(a) ((a) & 0xF) -#define RCAR_ATTR_SET_ISNOLOAD(a) (((a) & 0x1) << 16U) -#define RCAR_ATTR_SET_CERTOFF(a) (((a) & 0xF) << 8U) -#define RCAR_ATTR_SET_ALL(a, b, c) ((uint32_t)(RCAR_ATTR_SET_CALCADDR(a) |\ - RCAR_ATTR_SET_ISNOLOAD(b) |\ - RCAR_ATTR_SET_CERTOFF(c))) - -#define RCAR_ATTR_GET_CALCADDR(a) ((a) & 0xFU) -#define RCAR_ATTR_GET_ISNOLOAD(a) (((a) >> 16) & 0x1U) -#define RCAR_ATTR_GET_CERTOFF(a) ((uint32_t)(((a) >> 8) & 0xFU)) - -#define RCAR_MAX_BL3X_IMAGE (8U) -#define RCAR_SECTOR6_CERT_OFFSET (0x400U) -#define RCAR_SDRAM_certESS (0x43F00000U) -#define RCAR_CERT_SIZE (0x800U) -#define RCAR_CERT_INFO_SIZE_OFFSET (0x264U) -#define RCAR_CERT_INFO_DST_OFFSET (0x154U) -#define RCAR_CERT_INFO_SIZE_OFFSET1 (0x364U) -#define RCAR_CERT_INFO_DST_OFFSET1 (0x1D4U) -#define RCAR_CERT_INFO_SIZE_OFFSET2 (0x464U) -#define RCAR_CERT_INFO_DST_OFFSET2 (0x254U) -#define RCAR_CERT_LOAD (1U) - -#define RCAR_FLASH_CERT_HEADER RCAR_GET_FLASH_ADR(6U, 0U) -#define RCAR_EMMC_CERT_HEADER (0x00030000U) - -#define RCAR_COUNT_LOAD_BL33 (2U) -#define RCAR_COUNT_LOAD_BL33X (3U) - -static const plat_rcar_name_offset_t name_offset[] = { - {BL31_IMAGE_ID, 0U, RCAR_ATTR_SET_ALL(0, 0, 0)}, - - /* BL3-2 is optional in the platform */ - {BL32_IMAGE_ID, 0U, RCAR_ATTR_SET_ALL(1, 0, 1)}, - {BL33_IMAGE_ID, 0U, RCAR_ATTR_SET_ALL(2, 0, 2)}, - {BL332_IMAGE_ID, 0U, RCAR_ATTR_SET_ALL(3, 0, 3)}, - {BL333_IMAGE_ID, 0U, RCAR_ATTR_SET_ALL(4, 0, 4)}, - {BL334_IMAGE_ID, 0U, RCAR_ATTR_SET_ALL(5, 0, 5)}, - {BL335_IMAGE_ID, 0U, RCAR_ATTR_SET_ALL(6, 0, 6)}, - {BL336_IMAGE_ID, 0U, RCAR_ATTR_SET_ALL(7, 0, 7)}, - {BL337_IMAGE_ID, 0U, RCAR_ATTR_SET_ALL(8, 0, 8)}, - {BL338_IMAGE_ID, 0U, RCAR_ATTR_SET_ALL(9, 0, 9)}, -}; - -#if TRUSTED_BOARD_BOOT -static const plat_rcar_name_offset_t cert_offset[] = { - /* Certificates */ - {TRUSTED_KEY_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 0)}, - {SOC_FW_KEY_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 0)}, - {TRUSTED_OS_FW_KEY_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 0)}, - {NON_TRUSTED_FW_KEY_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 0)}, - {SOC_FW_CONTENT_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 0)}, - {TRUSTED_OS_FW_CONTENT_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 1)}, - {NON_TRUSTED_FW_CONTENT_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 2)}, - {BL332_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 3)}, - {BL333_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 4)}, - {BL334_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 5)}, - {BL335_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 6)}, - {BL336_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 7)}, - {BL337_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 8)}, - {BL338_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 9)}, -}; -#endif /* TRUSTED_BOARD_BOOT */ - -static file_state_t current_file = { 0 }; - -static uintptr_t rcar_handle, rcar_spec; -static uint64_t rcar_image_header[RCAR_MAX_BL3X_IMAGE + 2U] = { 0U }; -static uint64_t rcar_image_header_prttn[RCAR_MAX_BL3X_IMAGE + 2U] = { 0U }; -static uint64_t rcar_image_number = { 0U }; -static uint32_t rcar_cert_load = { 0U }; - -static io_type_t device_type_rcar(void) -{ - return IO_TYPE_FIRMWARE_IMAGE_PACKAGE; -} - -int32_t rcar_get_certificate(const int32_t name, uint32_t *cert) -{ -#if TRUSTED_BOARD_BOOT - int32_t i; - - for (i = 0; i < ARRAY_SIZE(cert_offset); i++) { - if (name != cert_offset[i].name) { - continue; - } - - *cert = RCAR_CERT_SIZE; - *cert *= RCAR_ATTR_GET_CERTOFF(cert_offset[i].attr); - *cert += RCAR_SDRAM_certESS; - return 0; - } -#endif - return -EINVAL; -} - -static int32_t file_to_offset(const int32_t name, uintptr_t *offset, - uint32_t *cert, uint32_t *no_load, - uintptr_t *partition) -{ - uint32_t addr; - int32_t i; - - for (i = 0; i < ARRAY_SIZE(name_offset); i++) { - if (name != name_offset[i].name) { - continue; - } - - addr = RCAR_ATTR_GET_CALCADDR(name_offset[i].attr); - if (rcar_image_number + 2U < addr) { - continue; - } - - *offset = rcar_image_header[addr]; - *cert = RCAR_CERT_SIZE; - *cert *= RCAR_ATTR_GET_CERTOFF(name_offset[i].attr); - *cert += RCAR_SDRAM_certESS; - *no_load = RCAR_ATTR_GET_ISNOLOAD(name_offset[i].attr); - *partition = rcar_image_header_prttn[addr]; - return IO_SUCCESS; - } - -#if TRUSTED_BOARD_BOOT - for (i = 0; i < ARRAY_SIZE(cert_offset); i++) { - if (name != cert_offset[i].name) { - continue; - } - - *no_load = RCAR_ATTR_GET_ISNOLOAD(cert_offset[i].attr); - *partition = 0U; - *offset = 0U; - *cert = 0U; - return IO_SUCCESS; - } -#endif - return -EINVAL; -} - -#define RCAR_BOOT_KEY_CERT_NEW (0xE6300F00U) -#define RCAR_CERT_MAGIC_NUM (0xE291F358U) - -void rcar_read_certificate(uint64_t cert, uint32_t *len, uintptr_t *dst) -{ - uint32_t seed, val, info_1, info_2; - uintptr_t size, dsth, dstl; - - cert &= 0xFFFFFFFFU; - - seed = mmio_read_32(RCAR_BOOT_KEY_CERT_NEW); - val = mmio_read_32(RCAR_BOOT_KEY_CERT_NEW + 0xC); - info_1 = (val >> 18) & 0x3U; - val = mmio_read_32(cert + 0xC); - info_2 = (val >> 21) & 0x3; - - if (seed == RCAR_CERT_MAGIC_NUM) { - if (info_1 != 1) { - ERROR("BL2: Cert is invalid.\n"); - *dst = 0; - *len = 0; - return; - } - - if (info_2 > 2) { - ERROR("BL2: Cert is invalid.\n"); - *dst = 0; - *len = 0; - return; - } - - switch (info_2) { - case 2: - size = cert + RCAR_CERT_INFO_SIZE_OFFSET2; - dstl = cert + RCAR_CERT_INFO_DST_OFFSET2; - break; - case 1: - size = cert + RCAR_CERT_INFO_SIZE_OFFSET1; - dstl = cert + RCAR_CERT_INFO_DST_OFFSET1; - break; - case 0: - size = cert + RCAR_CERT_INFO_SIZE_OFFSET; - dstl = cert + RCAR_CERT_INFO_DST_OFFSET; - break; - } - - *len = mmio_read_32(size) * 4U; - dsth = dstl + 4U; - *dst = ((uintptr_t) mmio_read_32(dsth) << 32) + - ((uintptr_t) mmio_read_32(dstl)); - return; - } - - size = cert + RCAR_CERT_INFO_SIZE_OFFSET; - *len = mmio_read_32(size) * 4U; - dstl = cert + RCAR_CERT_INFO_DST_OFFSET; - dsth = dstl + 4U; - *dst = ((uintptr_t) mmio_read_32(dsth) << 32) + - ((uintptr_t) mmio_read_32(dstl)); -} - -static int32_t check_load_area(uintptr_t dst, uintptr_t len) -{ - uint32_t legacy = dst + len <= UINT32_MAX - 1 ? 1 : 0; - uintptr_t dram_start, dram_end; - uintptr_t prot_start, prot_end; - int32_t result = IO_SUCCESS; - - dram_start = legacy ? DRAM1_BASE : DRAM_40BIT_BASE; - - dram_end = legacy ? DRAM1_BASE + DRAM1_SIZE : - DRAM_40BIT_BASE + DRAM_40BIT_SIZE; - - prot_start = legacy ? DRAM_PROTECTED_BASE : DRAM_40BIT_PROTECTED_BASE; - - prot_end = prot_start + DRAM_PROTECTED_SIZE; - - if (dst < dram_start || dst > dram_end - len) { - ERROR("BL2: dst address is on the protected area.\n"); - result = IO_FAIL; - goto done; - } - - /* load image is within SDRAM protected area */ - if (dst >= prot_start && dst < prot_end) { - ERROR("BL2: dst address is on the protected area.\n"); - result = IO_FAIL; - } - - if (dst < prot_start && dst > prot_start - len) { - ERROR("BL2: loaded data is on the protected area.\n"); - result = IO_FAIL; - } -done: - if (result == IO_FAIL) { - ERROR("BL2: Out of range : dst=0x%lx len=0x%lx\n", dst, len); - } - - return result; -} - -static int32_t load_bl33x(void) -{ - static int32_t loaded = IO_NOT_SUPPORTED; - uintptr_t dst, partition, handle; - uint32_t noload, cert, len, i; - uintptr_t offset; - int32_t rc; - size_t cnt; - const int32_t img[] = { - BL33_IMAGE_ID, - BL332_IMAGE_ID, - BL333_IMAGE_ID, - BL334_IMAGE_ID, - BL335_IMAGE_ID, - BL336_IMAGE_ID, - BL337_IMAGE_ID, - BL338_IMAGE_ID - }; - - if (loaded != IO_NOT_SUPPORTED) { - return loaded; - } - - for (i = 1; i < rcar_image_number; i++) { - rc = file_to_offset(img[i], &offset, &cert, &noload, - &partition); - if (rc != IO_SUCCESS) { - WARN("%s: failed to get offset\n", __func__); - loaded = IO_FAIL; - return loaded; - } - - rcar_read_certificate((uint64_t) cert, &len, &dst); - ((io_drv_spec_t *) rcar_spec)->partition = partition; - - rc = io_open(rcar_handle, rcar_spec, &handle); - if (rc != IO_SUCCESS) { - WARN("%s: Failed to open FIP (%i)\n", __func__, rc); - loaded = IO_FAIL; - return loaded; - } - - rc = io_seek(handle, IO_SEEK_SET, offset); - if (rc != IO_SUCCESS) { - WARN("%s: failed to seek\n", __func__); - loaded = IO_FAIL; - return loaded; - } - - rc = check_load_area(dst, len); - if (rc != IO_SUCCESS) { - WARN("%s: check load area\n", __func__); - loaded = IO_FAIL; - return loaded; - } - - rc = io_read(handle, dst, len, &cnt); - if (rc != IO_SUCCESS) { - WARN("%s: failed to read\n", __func__); - loaded = IO_FAIL; - return loaded; - } -#if TRUSTED_BOARD_BOOT - rc = auth_mod_verify_img(img[i], (void *)dst, len); - if (rc != 0) { - memset((void *)dst, 0x00, len); - loaded = IO_FAIL; - return loaded; - } -#endif - io_close(handle); - } - - loaded = IO_SUCCESS; - - return loaded; -} - -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}; - uintptr_t handle; - ssize_t offset; - uint32_t i; - int32_t rc; - size_t cnt; - - /* Obtain a reference to the image by querying the platform layer */ - rc = plat_get_drv_source(name, &rcar_handle, &rcar_spec); - if (rc != IO_SUCCESS) { - WARN("Failed to obtain reference to img %ld (%i)\n", name, rc); - return IO_FAIL; - } - - if (rcar_cert_load == RCAR_CERT_LOAD) { - return IO_SUCCESS; - } - - rc = io_open(rcar_handle, rcar_spec, &handle); - if (rc != IO_SUCCESS) { - WARN("Failed to access img %ld (%i)\n", name, rc); - return IO_FAIL; - } - - /* - * get start address list - * [0] address num - * [1] BL33-1 image address - * [2] BL33-2 image address - * [3] BL33-3 image address - * [4] BL33-4 image address - * [5] BL33-5 image address - * [6] BL33-6 image address - * [7] BL33-7 image address - * [8] BL33-8 image address - */ - offset = name == EMMC_DEV_ID ? RCAR_EMMC_CERT_HEADER : - RCAR_FLASH_CERT_HEADER; - rc = io_seek(handle, IO_SEEK_SET, offset); - if (rc != IO_SUCCESS) { - 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; - } - - rcar_image_number = header[0]; - for (i = 0; i < rcar_image_number + 2; i++) { - rcar_image_header[i] = header[i * 2 + 1]; - rcar_image_header_prttn[i] = header[i * 2 + 2]; - } - - if (rcar_image_number == 0 || rcar_image_number > RCAR_MAX_BL3X_IMAGE) { - WARN("Firmware Image Package header check failed.\n"); - goto error; - } - - rc = io_seek(handle, IO_SEEK_SET, offset + RCAR_SECTOR6_CERT_OFFSET); - if (rc != IO_SUCCESS) { - 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) { - WARN("cert file read error.\n"); - goto error; - } - - rcar_cert_load = RCAR_CERT_LOAD; -error: - - if (rc != IO_SUCCESS) { - rc = IO_FAIL; - } - - io_close(handle); - - return rc; - -} - -static int32_t rcar_file_open(io_dev_info_t *info, const uintptr_t file_spec, - io_entity_t *entity) -{ - const io_drv_spec_t *spec = (io_drv_spec_t *) file_spec; - uintptr_t partition, offset, dst; - uint32_t noload, cert, len; - int32_t rc; - - /* - * Only one file open at a time. We need to track state (ie, file - * cursor position). Since the header lives at offset zero, this entry - * should never be zero in an active file. - * Once the system supports dynamic memory allocation we will allow more - * than one open file at a time. - */ - if (current_file.offset != 0U) { - WARN("%s: Only one open file at a time.\n", __func__); - return IO_RESOURCES_EXHAUSTED; - } - - rc = file_to_offset(spec->offset, &offset, &cert, &noload, &partition); - if (rc != IO_SUCCESS) { - WARN("Failed to open file name %ld (%i)\n", spec->offset, rc); - return IO_FAIL; - } - - if (noload != 0U) { - current_file.offset = 1; - current_file.dst = 0; - current_file.size = 1; - current_file.position = 0; - current_file.no_load = noload; - current_file.partition = 0; - entity->info = (uintptr_t) ¤t_file; - - return IO_SUCCESS; - } - - rcar_read_certificate((uint64_t) cert, &len, &dst); - - /* Baylibre: HACK */ - if (spec->offset == BL31_IMAGE_ID && len < RCAR_TRUSTED_SRAM_SIZE) { - WARN("%s,%s\n", "r-car ignoring the BL31 size from certificate", - "using RCAR_TRUSTED_SRAM_SIZE instead"); - len = RCAR_TRUSTED_SRAM_SIZE; - } - - current_file.partition = partition; - current_file.no_load = noload; - current_file.offset = offset; - current_file.position = 0; - current_file.size = len; - current_file.dst = dst; - entity->info = (uintptr_t) ¤t_file; - - return IO_SUCCESS; -} - -static int32_t rcar_file_len(io_entity_t *entity, size_t *length) -{ - *length = ((file_state_t *) entity->info)->size; - - NOTICE("%s: len: 0x%08lx\n", __func__, *length); - - return IO_SUCCESS; -} - -static int32_t rcar_file_read(io_entity_t *entity, uintptr_t buffer, - size_t length, size_t *cnt) -{ - file_state_t *fp = (file_state_t *) entity->info; - ssize_t offset = fp->offset + fp->position; - uintptr_t handle; - int32_t rc; - -#ifdef SPD_NONE - static uint32_t load_bl33x_counter = 1; -#else - static uint32_t load_bl33x_counter; -#endif - if (current_file.no_load != 0U) { - *cnt = length; - return IO_SUCCESS; - } - - ((io_drv_spec_t *) rcar_spec)->partition = fp->partition; - - rc = io_open(rcar_handle, rcar_spec, &handle); - if (rc != IO_SUCCESS) { - WARN("Failed to open FIP (%i)\n", rc); - return IO_FAIL; - } - - rc = io_seek(handle, IO_SEEK_SET, offset); - if (rc != IO_SUCCESS) { - WARN("%s: failed to seek\n", __func__); - goto error; - } - - if (load_bl33x_counter == RCAR_COUNT_LOAD_BL33) { - rc = check_load_area(buffer, length); - if (rc != IO_SUCCESS) { - WARN("%s: load area err\n", __func__); - goto error; - } - } - - rc = io_read(handle, buffer, length, cnt); - if (rc != IO_SUCCESS) { - WARN("Failed to read payload (%i)\n", rc); - goto error; - } - - fp->position += *cnt; - io_close(handle); - - load_bl33x_counter += 1; - if (load_bl33x_counter == RCAR_COUNT_LOAD_BL33X) { - return load_bl33x(); - } - - return IO_SUCCESS; -error: - io_close(handle); - return IO_FAIL; -} - -static int32_t rcar_file_close(io_entity_t *entity) -{ - if (current_file.offset != 0U) { - memset(¤t_file, 0, sizeof(current_file)); - } - - entity->info = 0U; - - return IO_SUCCESS; -} - -static const io_dev_funcs_t rcar_dev_funcs = { - .type = &device_type_rcar, - .open = &rcar_file_open, - .seek = NULL, - .size = &rcar_file_len, - .read = &rcar_file_read, - .write = NULL, - .close = &rcar_file_close, - .dev_init = &rcar_dev_init, - .dev_close = &rcar_dev_close, -}; - -static const io_dev_info_t rcar_dev_info = { - .funcs = &rcar_dev_funcs, - .info = (uintptr_t) 0 -}; - -static const io_dev_connector_t rcar_dev_connector = { - .dev_open = &rcar_dev_open -}; - -static int32_t rcar_dev_open(const uintptr_t dev_spec __attribute__ ((unused)), - io_dev_info_t **dev_info) -{ - *dev_info = (io_dev_info_t *) &rcar_dev_info; - - return IO_SUCCESS; -} - -static int32_t rcar_dev_close(io_dev_info_t *dev_info) -{ - rcar_handle = 0; - rcar_spec = 0; - - return IO_SUCCESS; -} - -int32_t rcar_register_io_dev(const io_dev_connector_t **dev_con) -{ - int32_t result; - - result = io_register_device(&rcar_dev_info); - if (result == IO_SUCCESS) { - *dev_con = &rcar_dev_connector; - } - - return result; -} diff --git a/drivers/renesas/rcar/io/io_rcar.h b/drivers/renesas/rcar/io/io_rcar.h deleted file mode 100644 index c26a61767..000000000 --- a/drivers/renesas/rcar/io/io_rcar.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef IO_RCAR_H -#define IO_RCAR_H - -int32_t rcar_register_io_dev(const io_dev_connector_t **dev_con); -int32_t rcar_get_certificate(const int32_t name, uint32_t *cert); -void rcar_read_certificate(uint64_t cert, uint32_t *size, uintptr_t *dest); - -#endif /* IO_RCAR_H */ diff --git a/plat/renesas/common/common.mk b/plat/renesas/common/common.mk index 9b1466349..82f4d7d7e 100644 --- a/plat/renesas/common/common.mk +++ b/plat/renesas/common/common.mk @@ -79,6 +79,9 @@ BL2_SOURCES += ${RCAR_GIC_SOURCES} \ ${LIBFDT_SRCS} \ common/desc_image_load.c \ drivers/renesas/common/common.c \ + drivers/renesas/common/io/io_emmcdrv.c \ + drivers/renesas/common/io/io_memdrv.c \ + drivers/renesas/common/io/io_rcar.c \ drivers/renesas/common/emmc/emmc_interrupt.c \ drivers/renesas/common/emmc/emmc_utility.c \ drivers/renesas/common/emmc/emmc_mount.c \ diff --git a/plat/renesas/rcar/platform.mk b/plat/renesas/rcar/platform.mk index 02be49a2e..1f0c8abc4 100644 --- a/plat/renesas/rcar/platform.mk +++ b/plat/renesas/rcar/platform.mk @@ -309,7 +309,7 @@ PLAT_INCLUDES += -Idrivers/renesas/rcar/ddr \ -Idrivers/renesas/rcar/scif \ -Idrivers/renesas/common/emmc \ -Idrivers/renesas/rcar/pwrc \ - -Idrivers/renesas/rcar/io + -Idrivers/renesas/common/io BL2_SOURCES += plat/renesas/rcar/aarch64/platform_common.c \ plat/renesas/rcar/aarch64/plat_helpers.S \ @@ -322,9 +322,6 @@ BL2_SOURCES += plat/renesas/rcar/aarch64/platform_common.c \ plat/renesas/rcar/bl2_cpg_init.c \ drivers/renesas/rcar/console/rcar_printf.c \ drivers/renesas/rcar/scif/scif.S \ - drivers/renesas/rcar/io/io_emmcdrv.c \ - drivers/renesas/rcar/io/io_memdrv.c \ - drivers/renesas/rcar/io/io_rcar.c \ drivers/renesas/rcar/auth/auth_mod.c \ drivers/renesas/rcar/rpc/rpc_driver.c \ drivers/renesas/rcar/dma/dma_driver.c \ -- cgit v1.2.3 From 384345874d1a334692ba0dbc4b3eb24c46c83ae4 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Sun, 13 Dec 2020 20:40:44 +0000 Subject: plat: renesas: rcar: Fix checkpatch warnings Fix checkpatch warnings. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: I46801b563c887dc0a66e224ab4971e6503641529 --- plat/renesas/rcar/bl31_plat_setup.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/plat/renesas/rcar/bl31_plat_setup.c b/plat/renesas/rcar/bl31_plat_setup.c index 7bc0d8e27..93798acfb 100644 --- a/plat/renesas/rcar/bl31_plat_setup.c +++ b/plat/renesas/rcar/bl31_plat_setup.c @@ -28,7 +28,7 @@ static const uint64_t BL31_RO_LIMIT = BL_CODE_END; #if USE_COHERENT_MEM static const uint64_t BL31_COHERENT_RAM_BASE = BL_COHERENT_RAM_BASE; static const uint64_t BL31_COHERENT_RAM_LIMIT = BL_COHERENT_RAM_END; -#endif +#endif /* USE_COHERENT_MEM */ extern void plat_rcar_gic_driver_init(void); extern void plat_rcar_gic_init(void); @@ -84,11 +84,11 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, NOTICE("BL3-1 : Rev.%s\n", version_of_renesas); #if RCAR_LSI != RCAR_D3 - if (RCAR_CLUSTER_A53A57 == rcar_pwrc_get_cluster()) { + if (rcar_pwrc_get_cluster() == RCAR_CLUSTER_A53A57) { plat_cci_init(); plat_cci_enable(); } -#endif +#endif /* RCAR_LSI != RCAR_D3 */ } void bl31_plat_arch_setup(void) @@ -98,7 +98,7 @@ void bl31_plat_arch_setup(void) BL31_RO_BASE, BL31_RO_LIMIT #if USE_COHERENT_MEM , BL31_COHERENT_RAM_BASE, BL31_COHERENT_RAM_LIMIT -#endif +#endif /* USE_COHERENT_MEM */ ); rcar_pwrc_code_copy_to_system_ram(); } @@ -113,17 +113,20 @@ void bl31_platform_setup(void) rcar_pwrc_setup(); #if 0 - /* TODO: there is a broad number of rcar-gen3 SoC configurations; to - support all of them, Renesas use the pwrc driver to discover what - cores are on/off before announcing the topology. - This code hasnt been ported yet - */ + /* + * TODO: there is a broad number of rcar-gen3 SoC configurations; to + * support all of them, Renesas use the pwrc driver to discover what + * cores are on/off before announcing the topology. + * This code hasnt been ported yet + */ rcar_setup_topology(); #endif - /* mask should match the kernel's MPIDR_HWID_BITMASK so the core can be - identified during cpuhotplug (check the kernel's psci migrate set of - functions */ + /* + * mask should match the kernel's MPIDR_HWID_BITMASK so the core can be + * identified during cpuhotplug (check the kernel's psci migrate set of + * functions + */ rcar_boot_mpidr = read_mpidr_el1() & 0x0000ffffU; } -- cgit v1.2.3 From c40739a68f557c2267749999f876af6e5f5ff66f Mon Sep 17 00:00:00 2001 From: Biju Das Date: Wed, 16 Dec 2020 10:27:45 +0000 Subject: drivers: renesas: pwrc: Move to common Move pwrc driver code to common directory, so that the same code can be re-used by both R-Car Gen3 and RZ/G2 platforms. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: I75d91a44d872fe2296b15c700efacd5721385363 --- drivers/renesas/common/pwrc/call_sram.S | 48 ++ drivers/renesas/common/pwrc/pwrc.c | 871 ++++++++++++++++++++++++++++++++ drivers/renesas/common/pwrc/pwrc.h | 75 +++ drivers/renesas/rcar/pwrc/call_sram.S | 48 -- drivers/renesas/rcar/pwrc/pwrc.c | 871 -------------------------------- drivers/renesas/rcar/pwrc/pwrc.h | 75 --- plat/renesas/common/common.mk | 2 + plat/renesas/rcar/platform.mk | 6 +- 8 files changed, 998 insertions(+), 998 deletions(-) create mode 100644 drivers/renesas/common/pwrc/call_sram.S create mode 100644 drivers/renesas/common/pwrc/pwrc.c create mode 100644 drivers/renesas/common/pwrc/pwrc.h delete mode 100644 drivers/renesas/rcar/pwrc/call_sram.S delete mode 100644 drivers/renesas/rcar/pwrc/pwrc.c delete mode 100644 drivers/renesas/rcar/pwrc/pwrc.h diff --git a/drivers/renesas/common/pwrc/call_sram.S b/drivers/renesas/common/pwrc/call_sram.S new file mode 100644 index 000000000..aa8644cb9 --- /dev/null +++ b/drivers/renesas/common/pwrc/call_sram.S @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +.global rcar_pwrc_switch_stack + +/* + * x0 : jump address, + * x1 : stack address, + * x2 : arg, + * x3 : stack address (temporary) + */ +func rcar_pwrc_switch_stack + + /* lr to stack */ + stp x29, x30, [sp,#-16] + + /* change stack pointer */ + mov x3, sp + mov sp, x1 + + /* save stack pointer */ + sub sp, sp, #16 + stp x0, x3, [sp] + + /* data synchronization barrier */ + dsb sy + + /* jump to code */ + mov x1, x0 + mov x0, x2 + blr x1 + + /* load stack pointer */ + ldp x0, x2, [sp,#0] + + /* change stack pointer */ + mov sp, x2 + + /* return */ + ldp x29, x30, [sp,#-16] + ret +endfunc rcar_pwrc_switch_stack diff --git a/drivers/renesas/common/pwrc/pwrc.c b/drivers/renesas/common/pwrc/pwrc.c new file mode 100644 index 000000000..c0f015f04 --- /dev/null +++ b/drivers/renesas/common/pwrc/pwrc.c @@ -0,0 +1,871 @@ +/* + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "iic_dvfs.h" +#include "micro_delay.h" +#include "pwrc.h" +#include "rcar_def.h" +#include "rcar_private.h" + +/* + * Someday there will be a generic power controller api. At the moment each + * platform has its own pwrc so just exporting functions should be acceptable. + */ +RCAR_INSTANTIATE_LOCK + +#define WUP_IRQ_SHIFT (0U) +#define WUP_FIQ_SHIFT (8U) +#define WUP_CSD_SHIFT (16U) +#define BIT_SOFTRESET (1U << 15) +#define BIT_CA53_SCU (1U << 21) +#define BIT_CA57_SCU (1U << 12) +#define REQ_RESUME (1U << 1) +#define REQ_OFF (1U << 0) +#define STATUS_PWRUP (1U << 4) +#define STATUS_PWRDOWN (1U << 0) +#define STATE_CA57_CPU (27U) +#define STATE_CA53_CPU (22U) +#define MODE_L2_DOWN (0x00000002U) +#define CPU_PWR_OFF (0x00000003U) +#define RCAR_PSTR_MASK (0x00000003U) +#define ST_ALL_STANDBY (0x00003333U) +/* Suspend to ram */ +#define DBSC4_REG_BASE (0xE6790000U) +#define DBSC4_REG_DBSYSCNT0 (DBSC4_REG_BASE + 0x0100U) +#define DBSC4_REG_DBACEN (DBSC4_REG_BASE + 0x0200U) +#define DBSC4_REG_DBCMD (DBSC4_REG_BASE + 0x0208U) +#define DBSC4_REG_DBRFEN (DBSC4_REG_BASE + 0x0204U) +#define DBSC4_REG_DBWAIT (DBSC4_REG_BASE + 0x0210U) +#define DBSC4_REG_DBCALCNF (DBSC4_REG_BASE + 0x0424U) +#define DBSC4_REG_DBDFIPMSTRCNF (DBSC4_REG_BASE + 0x0520U) +#define DBSC4_REG_DBPDLK0 (DBSC4_REG_BASE + 0x0620U) +#define DBSC4_REG_DBPDRGA0 (DBSC4_REG_BASE + 0x0624U) +#define DBSC4_REG_DBPDRGD0 (DBSC4_REG_BASE + 0x0628U) +#define DBSC4_REG_DBCAM0CTRL0 (DBSC4_REG_BASE + 0x0940U) +#define DBSC4_REG_DBCAM0STAT0 (DBSC4_REG_BASE + 0x0980U) +#define DBSC4_REG_DBCAM1STAT0 (DBSC4_REG_BASE + 0x0990U) +#define DBSC4_REG_DBCAM2STAT0 (DBSC4_REG_BASE + 0x09A0U) +#define DBSC4_REG_DBCAM3STAT0 (DBSC4_REG_BASE + 0x09B0U) +#define DBSC4_BIT_DBACEN_ACCEN ((uint32_t)(1U << 0)) +#define DBSC4_BIT_DBRFEN_ARFEN ((uint32_t)(1U << 0)) +#define DBSC4_BIT_DBCAMxSTAT0 (0x00000001U) +#define DBSC4_BIT_DBDFIPMSTRCNF_PMSTREN (0x00000001U) +#define DBSC4_SET_DBCMD_OPC_PRE (0x04000000U) +#define DBSC4_SET_DBCMD_OPC_SR (0x0A000000U) +#define DBSC4_SET_DBCMD_OPC_PD (0x08000000U) +#define DBSC4_SET_DBCMD_OPC_MRW (0x0E000000U) +#define DBSC4_SET_DBCMD_CH_ALL (0x00800000U) +#define DBSC4_SET_DBCMD_RANK_ALL (0x00040000U) +#define DBSC4_SET_DBCMD_ARG_ALL (0x00000010U) +#define DBSC4_SET_DBCMD_ARG_ENTER (0x00000000U) +#define DBSC4_SET_DBCMD_ARG_MRW_ODTC (0x00000B00U) +#define DBSC4_SET_DBSYSCNT0_WRITE_ENABLE (0x00001234U) +#define DBSC4_SET_DBSYSCNT0_WRITE_DISABLE (0x00000000U) +#define DBSC4_SET_DBPDLK0_PHY_ACCESS (0x0000A55AU) +#define DBSC4_SET_DBPDRGA0_ACIOCR0 (0x0000001AU) +#define DBSC4_SET_DBPDRGD0_ACIOCR0 (0x33C03C11U) +#define DBSC4_SET_DBPDRGA0_DXCCR (0x00000020U) +#define DBSC4_SET_DBPDRGD0_DXCCR (0x00181006U) +#define DBSC4_SET_DBPDRGA0_PGCR1 (0x00000003U) +#define DBSC4_SET_DBPDRGD0_PGCR1 (0x0380C600U) +#define DBSC4_SET_DBPDRGA0_ACIOCR1 (0x0000001BU) +#define DBSC4_SET_DBPDRGD0_ACIOCR1 (0xAAAAAAAAU) +#define DBSC4_SET_DBPDRGA0_ACIOCR3 (0x0000001DU) +#define DBSC4_SET_DBPDRGD0_ACIOCR3 (0xAAAAAAAAU) +#define DBSC4_SET_DBPDRGA0_ACIOCR5 (0x0000001FU) +#define DBSC4_SET_DBPDRGD0_ACIOCR5 (0x000000AAU) +#define DBSC4_SET_DBPDRGA0_DX0GCR2 (0x000000A2U) +#define DBSC4_SET_DBPDRGD0_DX0GCR2 (0xAAAA0000U) +#define DBSC4_SET_DBPDRGA0_DX1GCR2 (0x000000C2U) +#define DBSC4_SET_DBPDRGD0_DX1GCR2 (0xAAAA0000U) +#define DBSC4_SET_DBPDRGA0_DX2GCR2 (0x000000E2U) +#define DBSC4_SET_DBPDRGD0_DX2GCR2 (0xAAAA0000U) +#define DBSC4_SET_DBPDRGA0_DX3GCR2 (0x00000102U) +#define DBSC4_SET_DBPDRGD0_DX3GCR2 (0xAAAA0000U) +#define DBSC4_SET_DBPDRGA0_ZQCR (0x00000090U) +#define DBSC4_SET_DBPDRGD0_ZQCR_MD19_0 (0x04058904U) +#define DBSC4_SET_DBPDRGD0_ZQCR_MD19_1 (0x04058A04U) +#define DBSC4_SET_DBPDRGA0_DX0GCR0 (0x000000A0U) +#define DBSC4_SET_DBPDRGD0_DX0GCR0 (0x7C0002E5U) +#define DBSC4_SET_DBPDRGA0_DX1GCR0 (0x000000C0U) +#define DBSC4_SET_DBPDRGD0_DX1GCR0 (0x7C0002E5U) +#define DBSC4_SET_DBPDRGA0_DX2GCR0 (0x000000E0U) +#define DBSC4_SET_DBPDRGD0_DX2GCR0 (0x7C0002E5U) +#define DBSC4_SET_DBPDRGA0_DX3GCR0 (0x00000100U) +#define DBSC4_SET_DBPDRGD0_DX3GCR0 (0x7C0002E5U) +#define DBSC4_SET_DBPDRGA0_DX0GCR1 (0x000000A1U) +#define DBSC4_SET_DBPDRGD0_DX0GCR1 (0x55550000U) +#define DBSC4_SET_DBPDRGA0_DX1GCR1 (0x000000C1U) +#define DBSC4_SET_DBPDRGD0_DX1GCR1 (0x55550000U) +#define DBSC4_SET_DBPDRGA0_DX2GCR1 (0x000000E1U) +#define DBSC4_SET_DBPDRGD0_DX2GCR1 (0x55550000U) +#define DBSC4_SET_DBPDRGA0_DX3GCR1 (0x00000101U) +#define DBSC4_SET_DBPDRGD0_DX3GCR1 (0x55550000U) +#define DBSC4_SET_DBPDRGA0_DX0GCR3 (0x000000A3U) +#define DBSC4_SET_DBPDRGD0_DX0GCR3 (0x00008484U) +#define DBSC4_SET_DBPDRGA0_DX1GCR3 (0x000000C3U) +#define DBSC4_SET_DBPDRGD0_DX1GCR3 (0x00008484U) +#define DBSC4_SET_DBPDRGA0_DX2GCR3 (0x000000E3U) +#define DBSC4_SET_DBPDRGD0_DX2GCR3 (0x00008484U) +#define DBSC4_SET_DBPDRGA0_DX3GCR3 (0x00000103U) +#define DBSC4_SET_DBPDRGD0_DX3GCR3 (0x00008484U) +#define RST_BASE (0xE6160000U) +#define RST_MODEMR (RST_BASE + 0x0060U) +#define RST_MODEMR_BIT0 (0x00000001U) + +#define RCAR_CNTCR_OFF (0x00U) +#define RCAR_CNTCVL_OFF (0x08U) +#define RCAR_CNTCVU_OFF (0x0CU) +#define RCAR_CNTFID_OFF (0x20U) + +#define RCAR_CNTCR_EN ((uint32_t)1U << 0U) +#define RCAR_CNTCR_FCREQ(x) ((uint32_t)(x) << 8U) + +#if PMIC_ROHM_BD9571 +#define BIT_BKUP_CTRL_OUT ((uint8_t)(1U << 4)) +#define PMIC_BKUP_MODE_CNT (0x20U) +#define PMIC_QLLM_CNT (0x27U) +#define PMIC_RETRY_MAX (100U) +#endif /* PMIC_ROHM_BD9571 */ +#define SCTLR_EL3_M_BIT ((uint32_t)1U << 0) +#define RCAR_CA53CPU_NUM_MAX (4U) +#define RCAR_CA57CPU_NUM_MAX (4U) +#define IS_A53A57(c) ((c) == RCAR_CLUSTER_A53A57) +#define IS_CA57(c) ((c) == RCAR_CLUSTER_CA57) +#define IS_CA53(c) ((c) == RCAR_CLUSTER_CA53) + +#ifndef __ASSEMBLER__ +IMPORT_SYM(unsigned long, __system_ram_start__, SYSTEM_RAM_START); +IMPORT_SYM(unsigned long, __system_ram_end__, SYSTEM_RAM_END); +IMPORT_SYM(unsigned long, __SRAM_COPY_START__, SRAM_COPY_START); +#endif + +uint32_t rcar_pwrc_status(uint64_t mpidr) +{ + uint32_t ret = 0; + uint64_t cm, cpu; + uint32_t reg; + uint32_t c; + + rcar_lock_get(); + + c = rcar_pwrc_get_cluster(); + cm = mpidr & MPIDR_CLUSTER_MASK; + + if (!IS_A53A57(c) && cm != 0) { + ret = RCAR_INVALID; + goto done; + } + + reg = mmio_read_32(RCAR_PRR); + cpu = mpidr & MPIDR_CPU_MASK; + + if (IS_CA53(c)) + if (reg & (1 << (STATE_CA53_CPU + cpu))) + ret = RCAR_INVALID; + if (IS_CA57(c)) + if (reg & (1 << (STATE_CA57_CPU + cpu))) + ret = RCAR_INVALID; +done: + rcar_lock_release(); + + return ret; +} + +static void scu_power_up(uint64_t mpidr) +{ + uintptr_t reg_pwrsr, reg_cpumcr, reg_pwron, reg_pwrer; + uint32_t c, sysc_reg_bit; + + c = rcar_pwrc_get_mpidr_cluster(mpidr); + reg_cpumcr = IS_CA57(c) ? RCAR_CA57CPUCMCR : RCAR_CA53CPUCMCR; + sysc_reg_bit = IS_CA57(c) ? BIT_CA57_SCU : BIT_CA53_SCU; + reg_pwron = IS_CA57(c) ? RCAR_PWRONCR5 : RCAR_PWRONCR3; + reg_pwrer = IS_CA57(c) ? RCAR_PWRER5 : RCAR_PWRER3; + reg_pwrsr = IS_CA57(c) ? RCAR_PWRSR5 : RCAR_PWRSR3; + + if ((mmio_read_32(reg_pwrsr) & STATUS_PWRDOWN) == 0) + return; + + if (mmio_read_32(reg_cpumcr) != 0) + mmio_write_32(reg_cpumcr, 0); + + mmio_setbits_32(RCAR_SYSCIER, sysc_reg_bit); + mmio_setbits_32(RCAR_SYSCIMR, sysc_reg_bit); + + do { + while ((mmio_read_32(RCAR_SYSCSR) & REQ_RESUME) == 0) + ; + mmio_write_32(reg_pwron, 1); + } while (mmio_read_32(reg_pwrer) & 1); + + while ((mmio_read_32(RCAR_SYSCISR) & sysc_reg_bit) == 0) + ; + mmio_write_32(RCAR_SYSCISR, sysc_reg_bit); + while ((mmio_read_32(reg_pwrsr) & STATUS_PWRUP) == 0) + ; +} + +void rcar_pwrc_cpuon(uint64_t mpidr) +{ + uint32_t res_data, on_data; + uintptr_t res_reg, on_reg; + uint32_t limit, c; + uint64_t cpu; + + rcar_lock_get(); + + c = rcar_pwrc_get_mpidr_cluster(mpidr); + res_reg = IS_CA53(c) ? RCAR_CA53RESCNT : RCAR_CA57RESCNT; + on_reg = IS_CA53(c) ? RCAR_CA53WUPCR : RCAR_CA57WUPCR; + limit = IS_CA53(c) ? 0x5A5A0000 : 0xA5A50000; + + res_data = mmio_read_32(res_reg) | limit; + scu_power_up(mpidr); + cpu = mpidr & MPIDR_CPU_MASK; + on_data = 1 << cpu; + mmio_write_32(RCAR_CPGWPR, ~on_data); + mmio_write_32(on_reg, on_data); + mmio_write_32(res_reg, res_data & (~(1 << (3 - cpu)))); + + rcar_lock_release(); +} + +void rcar_pwrc_cpuoff(uint64_t mpidr) +{ + uint32_t c; + uintptr_t reg; + uint64_t cpu; + + rcar_lock_get(); + + cpu = mpidr & MPIDR_CPU_MASK; + c = rcar_pwrc_get_mpidr_cluster(mpidr); + reg = IS_CA53(c) ? RCAR_CA53CPU0CR : RCAR_CA57CPU0CR; + + if (read_mpidr_el1() != mpidr) + panic(); + + mmio_write_32(RCAR_CPGWPR, ~CPU_PWR_OFF); + mmio_write_32(reg + cpu * 0x0010, CPU_PWR_OFF); + + rcar_lock_release(); +} + +void rcar_pwrc_enable_interrupt_wakeup(uint64_t mpidr) +{ + uint32_t c, shift_irq, shift_fiq; + uintptr_t reg; + uint64_t cpu; + + rcar_lock_get(); + + cpu = mpidr & MPIDR_CPU_MASK; + c = rcar_pwrc_get_mpidr_cluster(mpidr); + reg = IS_CA53(c) ? RCAR_WUPMSKCA53 : RCAR_WUPMSKCA57; + + shift_irq = WUP_IRQ_SHIFT + cpu; + shift_fiq = WUP_FIQ_SHIFT + cpu; + + mmio_write_32(reg, ~((uint32_t) 1 << shift_irq) & + ~((uint32_t) 1 << shift_fiq)); + rcar_lock_release(); +} + +void rcar_pwrc_disable_interrupt_wakeup(uint64_t mpidr) +{ + uint32_t c, shift_irq, shift_fiq; + uintptr_t reg; + uint64_t cpu; + + rcar_lock_get(); + + cpu = mpidr & MPIDR_CPU_MASK; + c = rcar_pwrc_get_mpidr_cluster(mpidr); + reg = IS_CA53(c) ? RCAR_WUPMSKCA53 : RCAR_WUPMSKCA57; + + shift_irq = WUP_IRQ_SHIFT + cpu; + shift_fiq = WUP_FIQ_SHIFT + cpu; + + mmio_write_32(reg, ((uint32_t) 1 << shift_irq) | + ((uint32_t) 1 << shift_fiq)); + rcar_lock_release(); +} + +void rcar_pwrc_clusteroff(uint64_t mpidr) +{ + uint32_t c, product, cut, reg; + uintptr_t dst; + + rcar_lock_get(); + + reg = mmio_read_32(RCAR_PRR); + product = reg & PRR_PRODUCT_MASK; + cut = reg & PRR_CUT_MASK; + + c = rcar_pwrc_get_mpidr_cluster(mpidr); + dst = IS_CA53(c) ? RCAR_CA53CPUCMCR : RCAR_CA57CPUCMCR; + + if (product == PRR_PRODUCT_M3 && cut < PRR_PRODUCT_30) { + goto done; + } + + if (product == PRR_PRODUCT_H3 && cut <= PRR_PRODUCT_20) { + goto done; + } + + /* all of the CPUs in the cluster is in the CoreStandby mode */ + mmio_write_32(dst, MODE_L2_DOWN); +done: + rcar_lock_release(); +} + +static uint64_t rcar_pwrc_saved_cntpct_el0; +static uint32_t rcar_pwrc_saved_cntfid; + +#if RCAR_SYSTEM_SUSPEND +static void rcar_pwrc_save_timer_state(void) +{ + rcar_pwrc_saved_cntpct_el0 = read_cntpct_el0(); + + rcar_pwrc_saved_cntfid = + mmio_read_32((uintptr_t)(RCAR_CNTC_BASE + RCAR_CNTFID_OFF)); +} +#endif /* RCAR_SYSTEM_SUSPEND */ + +void rcar_pwrc_restore_timer_state(void) +{ + /* Stop timer before restoring counter value */ + mmio_write_32((uintptr_t)(RCAR_CNTC_BASE + RCAR_CNTCR_OFF), 0U); + + mmio_write_32((uintptr_t)(RCAR_CNTC_BASE + RCAR_CNTCVL_OFF), + (uint32_t)(rcar_pwrc_saved_cntpct_el0 & 0xFFFFFFFFU)); + mmio_write_32((uintptr_t)(RCAR_CNTC_BASE + RCAR_CNTCVU_OFF), + (uint32_t)(rcar_pwrc_saved_cntpct_el0 >> 32U)); + + mmio_write_32((uintptr_t)(RCAR_CNTC_BASE + RCAR_CNTFID_OFF), + rcar_pwrc_saved_cntfid); + + /* Start generic timer back */ + write_cntfrq_el0((u_register_t)plat_get_syscnt_freq2()); + + mmio_write_32((uintptr_t)(RCAR_CNTC_BASE + RCAR_CNTCR_OFF), + (RCAR_CNTCR_FCREQ(0U) | RCAR_CNTCR_EN)); +} + +#if !PMIC_ROHM_BD9571 +void rcar_pwrc_system_reset(void) +{ + mmio_write_32(RCAR_SRESCR, 0x5AA50000U | BIT_SOFTRESET); +} +#endif /* PMIC_ROHM_BD9571 */ + +#define RST_CA53_CPU0_BARH (0xE6160080U) +#define RST_CA53_CPU0_BARL (0xE6160084U) +#define RST_CA57_CPU0_BARH (0xE61600C0U) +#define RST_CA57_CPU0_BARL (0xE61600C4U) + +void rcar_pwrc_setup(void) +{ + uintptr_t rst_barh; + uintptr_t rst_barl; + uint32_t i, j; + uint64_t reset = (uint64_t) (&plat_secondary_reset) & 0xFFFFFFFF; + + const uint32_t cluster[PLATFORM_CLUSTER_COUNT] = { + RCAR_CLUSTER_CA53, + RCAR_CLUSTER_CA57 + }; + const uintptr_t reg_barh[PLATFORM_CLUSTER_COUNT] = { + RST_CA53_CPU0_BARH, + RST_CA57_CPU0_BARH + }; + const uintptr_t reg_barl[PLATFORM_CLUSTER_COUNT] = { + RST_CA53_CPU0_BARL, + RST_CA57_CPU0_BARL + }; + + for (i = 0; i < PLATFORM_CLUSTER_COUNT; i++) { + rst_barh = reg_barh[i]; + rst_barl = reg_barl[i]; + for (j = 0; j < rcar_pwrc_get_cpu_num(cluster[i]); j++) { + mmio_write_32(rst_barh, 0); + mmio_write_32(rst_barl, (uint32_t) reset); + rst_barh += 0x10; + rst_barl += 0x10; + } + } + + rcar_lock_init(); +} + +#if RCAR_SYSTEM_SUSPEND +#define DBCAM_FLUSH(__bit) \ +do { \ + ; \ +} while (!(mmio_read_32(DBSC4_REG_DBCAM##__bit##STAT0) & DBSC4_BIT_DBCAMxSTAT0)) + + +static void __attribute__ ((section(".system_ram"))) + rcar_pwrc_set_self_refresh(void) +{ + uint32_t reg = mmio_read_32(RCAR_PRR); + uint32_t cut, product; + + product = reg & PRR_PRODUCT_MASK; + cut = reg & PRR_CUT_MASK; + + if (product == PRR_PRODUCT_M3 && cut < PRR_PRODUCT_30) { + goto self_refresh; + } + + if (product == PRR_PRODUCT_H3 && cut < PRR_PRODUCT_20) { + goto self_refresh; + } + + mmio_write_32(DBSC4_REG_DBSYSCNT0, DBSC4_SET_DBSYSCNT0_WRITE_ENABLE); + +self_refresh: + + /* DFI_PHYMSTR_ACK setting */ + mmio_write_32(DBSC4_REG_DBDFIPMSTRCNF, + mmio_read_32(DBSC4_REG_DBDFIPMSTRCNF) & + (~DBSC4_BIT_DBDFIPMSTRCNF_PMSTREN)); + + /* Set the Self-Refresh mode */ + mmio_write_32(DBSC4_REG_DBACEN, 0); + + if (product == PRR_PRODUCT_H3 && cut < PRR_PRODUCT_20) + rcar_micro_delay(100); + else if (product == PRR_PRODUCT_H3) { + mmio_write_32(DBSC4_REG_DBCAM0CTRL0, 1); + DBCAM_FLUSH(0); + DBCAM_FLUSH(1); + DBCAM_FLUSH(2); + DBCAM_FLUSH(3); + mmio_write_32(DBSC4_REG_DBCAM0CTRL0, 0); + } else if (product == PRR_PRODUCT_M3) { + mmio_write_32(DBSC4_REG_DBCAM0CTRL0, 1); + DBCAM_FLUSH(0); + DBCAM_FLUSH(1); + mmio_write_32(DBSC4_REG_DBCAM0CTRL0, 0); + } else { + mmio_write_32(DBSC4_REG_DBCAM0CTRL0, 1); + DBCAM_FLUSH(0); + mmio_write_32(DBSC4_REG_DBCAM0CTRL0, 0); + } + + /* Set the SDRAM calibration configuration register */ + mmio_write_32(DBSC4_REG_DBCALCNF, 0); + + reg = DBSC4_SET_DBCMD_OPC_PRE | DBSC4_SET_DBCMD_CH_ALL | + DBSC4_SET_DBCMD_RANK_ALL | DBSC4_SET_DBCMD_ARG_ALL; + mmio_write_32(DBSC4_REG_DBCMD, reg); + while (mmio_read_32(DBSC4_REG_DBWAIT)) + ; + + /* Self-Refresh entry command */ + reg = DBSC4_SET_DBCMD_OPC_SR | DBSC4_SET_DBCMD_CH_ALL | + DBSC4_SET_DBCMD_RANK_ALL | DBSC4_SET_DBCMD_ARG_ENTER; + mmio_write_32(DBSC4_REG_DBCMD, reg); + while (mmio_read_32(DBSC4_REG_DBWAIT)) + ; + + /* Mode Register Write command. (ODT disabled) */ + reg = DBSC4_SET_DBCMD_OPC_MRW | DBSC4_SET_DBCMD_CH_ALL | + DBSC4_SET_DBCMD_RANK_ALL | DBSC4_SET_DBCMD_ARG_MRW_ODTC; + mmio_write_32(DBSC4_REG_DBCMD, reg); + while (mmio_read_32(DBSC4_REG_DBWAIT)) + ; + + /* Power Down entry command */ + reg = DBSC4_SET_DBCMD_OPC_PD | DBSC4_SET_DBCMD_CH_ALL | + DBSC4_SET_DBCMD_RANK_ALL | DBSC4_SET_DBCMD_ARG_ENTER; + mmio_write_32(DBSC4_REG_DBCMD, reg); + while (mmio_read_32(DBSC4_REG_DBWAIT)) + ; + + /* Set the auto-refresh enable register */ + mmio_write_32(DBSC4_REG_DBRFEN, 0U); + rcar_micro_delay(1U); + + if (product == PRR_PRODUCT_M3 && cut < PRR_PRODUCT_30) + return; + + if (product == PRR_PRODUCT_H3 && cut < PRR_PRODUCT_20) + return; + + mmio_write_32(DBSC4_REG_DBSYSCNT0, DBSC4_SET_DBSYSCNT0_WRITE_DISABLE); +} + +static void __attribute__ ((section(".system_ram"))) +rcar_pwrc_set_self_refresh_e3(void) +{ + uint32_t ddr_md; + uint32_t reg; + + ddr_md = (mmio_read_32(RST_MODEMR) >> 19) & RST_MODEMR_BIT0; + + /* Write enable */ + mmio_write_32(DBSC4_REG_DBSYSCNT0, DBSC4_SET_DBSYSCNT0_WRITE_ENABLE); + mmio_write_32(DBSC4_REG_DBACEN, 0); + DBCAM_FLUSH(0); + + reg = DBSC4_SET_DBCMD_OPC_PRE | DBSC4_SET_DBCMD_CH_ALL | + DBSC4_SET_DBCMD_RANK_ALL | DBSC4_SET_DBCMD_ARG_ALL; + mmio_write_32(DBSC4_REG_DBCMD, reg); + while (mmio_read_32(DBSC4_REG_DBWAIT)) + ; + + reg = DBSC4_SET_DBCMD_OPC_SR | DBSC4_SET_DBCMD_CH_ALL | + DBSC4_SET_DBCMD_RANK_ALL | DBSC4_SET_DBCMD_ARG_ENTER; + mmio_write_32(DBSC4_REG_DBCMD, reg); + while (mmio_read_32(DBSC4_REG_DBWAIT)) + ; + + /* + * Set the auto-refresh enable register + * Set the ARFEN bit to 0 in the DBRFEN + */ + mmio_write_32(DBSC4_REG_DBRFEN, 0); + + mmio_write_32(DBSC4_REG_DBPDLK0, DBSC4_SET_DBPDLK0_PHY_ACCESS); + + mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_ACIOCR0); + mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_ACIOCR0); + + /* DDR_DXCCR */ + mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DXCCR); + mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DXCCR); + + /* DDR_PGCR1 */ + mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_PGCR1); + mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_PGCR1); + + /* DDR_ACIOCR1 */ + mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_ACIOCR1); + mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_ACIOCR1); + + /* DDR_ACIOCR3 */ + mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_ACIOCR3); + mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_ACIOCR3); + + /* DDR_ACIOCR5 */ + mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_ACIOCR5); + mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_ACIOCR5); + + /* DDR_DX0GCR2 */ + mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX0GCR2); + mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX0GCR2); + + /* DDR_DX1GCR2 */ + mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX1GCR2); + mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX1GCR2); + + /* DDR_DX2GCR2 */ + mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX2GCR2); + mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX2GCR2); + + /* DDR_DX3GCR2 */ + mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX3GCR2); + mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX3GCR2); + + /* DDR_ZQCR */ + mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_ZQCR); + + mmio_write_32(DBSC4_REG_DBPDRGD0, ddr_md == 0 ? + DBSC4_SET_DBPDRGD0_ZQCR_MD19_0 : + DBSC4_SET_DBPDRGD0_ZQCR_MD19_1); + + /* DDR_DX0GCR0 */ + mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX0GCR0); + mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX0GCR0); + + /* DDR_DX1GCR0 */ + mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX1GCR0); + mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX1GCR0); + + /* DDR_DX2GCR0 */ + mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX2GCR0); + mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX2GCR0); + + /* DDR_DX3GCR0 */ + mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX3GCR0); + mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX3GCR0); + + /* DDR_DX0GCR1 */ + mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX0GCR1); + mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX0GCR1); + + /* DDR_DX1GCR1 */ + mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX1GCR1); + mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX1GCR1); + + /* DDR_DX2GCR1 */ + mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX2GCR1); + mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX2GCR1); + + /* DDR_DX3GCR1 */ + mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX3GCR1); + mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX3GCR1); + + /* DDR_DX0GCR3 */ + mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX0GCR3); + mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX0GCR3); + + /* DDR_DX1GCR3 */ + mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX1GCR3); + mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX1GCR3); + + /* DDR_DX2GCR3 */ + mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX2GCR3); + mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX2GCR3); + + /* DDR_DX3GCR3 */ + mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX3GCR3); + mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX3GCR3); + + /* Write disable */ + mmio_write_32(DBSC4_REG_DBSYSCNT0, DBSC4_SET_DBSYSCNT0_WRITE_DISABLE); +} + +void __attribute__ ((section(".system_ram"))) __attribute__ ((noinline)) +rcar_pwrc_go_suspend_to_ram(void) +{ +#if PMIC_ROHM_BD9571 + int32_t rc = -1, qllm = -1; + uint8_t mode; + uint32_t i; +#endif + uint32_t reg, product; + + reg = mmio_read_32(RCAR_PRR); + product = reg & PRR_PRODUCT_MASK; + + if (product != PRR_PRODUCT_E3) + rcar_pwrc_set_self_refresh(); + else + rcar_pwrc_set_self_refresh_e3(); + +#if PMIC_ROHM_BD9571 + /* Set QLLM Cnt Disable */ + for (i = 0; (i < PMIC_RETRY_MAX) && (qllm != 0); i++) + qllm = rcar_iic_dvfs_send(PMIC, PMIC_QLLM_CNT, 0); + + /* Set trigger of power down to PMIV */ + for (i = 0; (i < PMIC_RETRY_MAX) && (rc != 0) && (qllm == 0); i++) { + rc = rcar_iic_dvfs_receive(PMIC, PMIC_BKUP_MODE_CNT, &mode); + if (rc == 0) { + mode |= BIT_BKUP_CTRL_OUT; + rc = rcar_iic_dvfs_send(PMIC, PMIC_BKUP_MODE_CNT, mode); + } + } +#endif + wfi(); + + while (1) + ; +} + +void rcar_pwrc_set_suspend_to_ram(void) +{ + uintptr_t jump = (uintptr_t) &rcar_pwrc_go_suspend_to_ram; + uintptr_t stack = (uintptr_t) (DEVICE_SRAM_STACK_BASE + + DEVICE_SRAM_STACK_SIZE); + uint32_t sctlr; + + rcar_pwrc_save_timer_state(); + + /* disable MMU */ + sctlr = (uint32_t) read_sctlr_el3(); + sctlr &= (uint32_t) ~SCTLR_EL3_M_BIT; + write_sctlr_el3((uint64_t) sctlr); + + rcar_pwrc_switch_stack(jump, stack, NULL); +} + +void rcar_pwrc_init_suspend_to_ram(void) +{ +#if PMIC_ROHM_BD9571 + uint8_t mode; + + if (rcar_iic_dvfs_receive(PMIC, PMIC_BKUP_MODE_CNT, &mode)) + panic(); + + mode &= (uint8_t) (~BIT_BKUP_CTRL_OUT); + if (rcar_iic_dvfs_send(PMIC, PMIC_BKUP_MODE_CNT, mode)) + panic(); +#endif +} + +void rcar_pwrc_suspend_to_ram(void) +{ +#if RCAR_SYSTEM_RESET_KEEPON_DDR + int32_t error; + + error = rcar_iic_dvfs_send(PMIC, REG_KEEP10, 0); + if (error) { + ERROR("Failed send KEEP10 init ret=%d\n", error); + return; + } +#endif + rcar_pwrc_set_suspend_to_ram(); +} +#endif + +void rcar_pwrc_code_copy_to_system_ram(void) +{ + int ret __attribute__ ((unused)); /* in assert */ + uint32_t attr; + struct device_sram_t { + uintptr_t base; + size_t len; + } sram = { + .base = (uintptr_t) DEVICE_SRAM_BASE, + .len = DEVICE_SRAM_SIZE, + }; + struct ddr_code_t { + void *base; + size_t len; + } code = { + .base = (void *) SRAM_COPY_START, + .len = SYSTEM_RAM_END - SYSTEM_RAM_START, + }; + + attr = MT_MEMORY | MT_RW | MT_SECURE | MT_EXECUTE_NEVER; + ret = xlat_change_mem_attributes(sram.base, sram.len, attr); + assert(ret == 0); + + memcpy((void *)sram.base, code.base, code.len); + flush_dcache_range((uint64_t) sram.base, code.len); + + /* 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) +{ + uint32_t reg; + + reg = mmio_read_32(RCAR_PRR); + + if (reg & (1U << (STATE_CA53_CPU + RCAR_CA53CPU_NUM_MAX))) + return RCAR_CLUSTER_CA57; + + if (reg & (1U << (STATE_CA57_CPU + RCAR_CA57CPU_NUM_MAX))) + return RCAR_CLUSTER_CA53; + + return RCAR_CLUSTER_A53A57; +} + +uint32_t rcar_pwrc_get_mpidr_cluster(uint64_t mpidr) +{ + uint32_t c = rcar_pwrc_get_cluster(); + + if (IS_A53A57(c)) { + if (mpidr & MPIDR_CLUSTER_MASK) + return RCAR_CLUSTER_CA53; + + return RCAR_CLUSTER_CA57; + } + + return c; +} + +#if RCAR_LSI == RCAR_D3 +uint32_t rcar_pwrc_get_cpu_num(uint32_t c) +{ + return 1; +} +#else +uint32_t rcar_pwrc_get_cpu_num(uint32_t c) +{ + uint32_t reg = mmio_read_32(RCAR_PRR); + uint32_t count = 0, i; + + if (IS_A53A57(c) || IS_CA53(c)) { + if (reg & (1 << (STATE_CA53_CPU + RCAR_CA53CPU_NUM_MAX))) + goto count_ca57; + + for (i = 0; i < RCAR_CA53CPU_NUM_MAX; i++) { + if (reg & (1 << (STATE_CA53_CPU + i))) + continue; + count++; + } + } + +count_ca57: + if (IS_A53A57(c) || IS_CA57(c)) { + if (reg & (1U << (STATE_CA57_CPU + RCAR_CA57CPU_NUM_MAX))) + goto done; + + for (i = 0; i < RCAR_CA57CPU_NUM_MAX; i++) { + if (reg & (1 << (STATE_CA57_CPU + i))) + continue; + count++; + } + } + +done: + return count; +} +#endif + +int32_t rcar_pwrc_cpu_on_check(uint64_t mpidr) +{ + uint64_t i; + uint64_t j; + uint64_t cpu_count; + uintptr_t reg_PSTR; + uint32_t status; + uint64_t my_cpu; + int32_t rtn; + uint32_t my_cluster_type; + const uint32_t cluster_type[PLATFORM_CLUSTER_COUNT] = { + RCAR_CLUSTER_CA53, + RCAR_CLUSTER_CA57 + }; + const uintptr_t registerPSTR[PLATFORM_CLUSTER_COUNT] = { + RCAR_CA53PSTR, + RCAR_CA57PSTR + }; + + my_cluster_type = rcar_pwrc_get_cluster(); + + rtn = 0; + my_cpu = mpidr & ((uint64_t)(MPIDR_CPU_MASK)); + for (i = 0U; i < ((uint64_t)(PLATFORM_CLUSTER_COUNT)); i++) { + cpu_count = rcar_pwrc_get_cpu_num(cluster_type[i]); + reg_PSTR = registerPSTR[i]; + for (j = 0U; j < cpu_count; j++) { + if ((my_cluster_type != cluster_type[i]) || (my_cpu != j)) { + status = mmio_read_32(reg_PSTR) >> (j * 4U); + if ((status & 0x00000003U) == 0U) { + rtn--; + } + } + } + } + + return rtn; +} diff --git a/drivers/renesas/common/pwrc/pwrc.h b/drivers/renesas/common/pwrc/pwrc.h new file mode 100644 index 000000000..f73099b0b --- /dev/null +++ b/drivers/renesas/common/pwrc/pwrc.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PWRC_H +#define PWRC_H + +#define PPOFFR_OFF 0x0 +#define PPONR_OFF 0x4 +#define PCOFFR_OFF 0x8 +#define PWKUPR_OFF 0xc +#define PSYSR_OFF 0x10 + +#define PWKUPR_WEN (1ull << 31) + +#define PSYSR_AFF_L2 (1U << 31) +#define PSYSR_AFF_L1 (1 << 30) +#define PSYSR_AFF_L0 (1 << 29) +#define PSYSR_WEN (1 << 28) +#define PSYSR_PC (1 << 27) +#define PSYSR_PP (1 << 26) + +#define PSYSR_WK_SHIFT (24) +#define PSYSR_WK_MASK (0x3) +#define PSYSR_WK(x) (((x) >> PSYSR_WK_SHIFT) & PSYSR_WK_MASK) + +#define WKUP_COLD 0x0 +#define WKUP_RESET 0x1 +#define WKUP_PPONR 0x2 +#define WKUP_GICREQ 0x3 + +#define RCAR_INVALID (0xffffffffU) +#define PSYSR_INVALID 0xffffffff + +#define RCAR_CLUSTER_A53A57 (0U) +#define RCAR_CLUSTER_CA53 (1U) +#define RCAR_CLUSTER_CA57 (2U) + +#ifndef __ASSEMBLER__ +void rcar_pwrc_disable_interrupt_wakeup(uint64_t mpidr); +void rcar_pwrc_enable_interrupt_wakeup(uint64_t mpidr); +void rcar_pwrc_clusteroff(uint64_t mpidr); +void rcar_pwrc_cpuoff(uint64_t mpidr); +void rcar_pwrc_cpuon(uint64_t mpidr); +int32_t rcar_pwrc_cpu_on_check(uint64_t mpidr); +void rcar_pwrc_setup(void); + +uint32_t rcar_pwrc_get_cpu_wkr(uint64_t mpidr); +uint32_t rcar_pwrc_status(uint64_t mpidr); +uint32_t rcar_pwrc_get_cluster(void); +uint32_t rcar_pwrc_get_mpidr_cluster(uint64_t mpidr); +uint32_t rcar_pwrc_get_cpu_num(uint32_t cluster_type); +void rcar_pwrc_restore_timer_state(void); +void plat_secondary_reset(void); + +void rcar_pwrc_code_copy_to_system_ram(void); + +#if !PMIC_ROHM_BD9571 +void rcar_pwrc_system_reset(void); +#endif + +#if RCAR_SYSTEM_SUSPEND +void rcar_pwrc_go_suspend_to_ram(void); +void rcar_pwrc_set_suspend_to_ram(void); +void rcar_pwrc_init_suspend_to_ram(void); +void rcar_pwrc_suspend_to_ram(void); +#endif + +extern uint32_t rcar_pwrc_switch_stack(uintptr_t jump, uintptr_t stack, + void *arg); +#endif + +#endif /* PWRC_H */ diff --git a/drivers/renesas/rcar/pwrc/call_sram.S b/drivers/renesas/rcar/pwrc/call_sram.S deleted file mode 100644 index aa8644cb9..000000000 --- a/drivers/renesas/rcar/pwrc/call_sram.S +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include - -.global rcar_pwrc_switch_stack - -/* - * x0 : jump address, - * x1 : stack address, - * x2 : arg, - * x3 : stack address (temporary) - */ -func rcar_pwrc_switch_stack - - /* lr to stack */ - stp x29, x30, [sp,#-16] - - /* change stack pointer */ - mov x3, sp - mov sp, x1 - - /* save stack pointer */ - sub sp, sp, #16 - stp x0, x3, [sp] - - /* data synchronization barrier */ - dsb sy - - /* jump to code */ - mov x1, x0 - mov x0, x2 - blr x1 - - /* load stack pointer */ - ldp x0, x2, [sp,#0] - - /* change stack pointer */ - mov sp, x2 - - /* return */ - ldp x29, x30, [sp,#-16] - ret -endfunc rcar_pwrc_switch_stack diff --git a/drivers/renesas/rcar/pwrc/pwrc.c b/drivers/renesas/rcar/pwrc/pwrc.c deleted file mode 100644 index c0f015f04..000000000 --- a/drivers/renesas/rcar/pwrc/pwrc.c +++ /dev/null @@ -1,871 +0,0 @@ -/* - * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "iic_dvfs.h" -#include "micro_delay.h" -#include "pwrc.h" -#include "rcar_def.h" -#include "rcar_private.h" - -/* - * Someday there will be a generic power controller api. At the moment each - * platform has its own pwrc so just exporting functions should be acceptable. - */ -RCAR_INSTANTIATE_LOCK - -#define WUP_IRQ_SHIFT (0U) -#define WUP_FIQ_SHIFT (8U) -#define WUP_CSD_SHIFT (16U) -#define BIT_SOFTRESET (1U << 15) -#define BIT_CA53_SCU (1U << 21) -#define BIT_CA57_SCU (1U << 12) -#define REQ_RESUME (1U << 1) -#define REQ_OFF (1U << 0) -#define STATUS_PWRUP (1U << 4) -#define STATUS_PWRDOWN (1U << 0) -#define STATE_CA57_CPU (27U) -#define STATE_CA53_CPU (22U) -#define MODE_L2_DOWN (0x00000002U) -#define CPU_PWR_OFF (0x00000003U) -#define RCAR_PSTR_MASK (0x00000003U) -#define ST_ALL_STANDBY (0x00003333U) -/* Suspend to ram */ -#define DBSC4_REG_BASE (0xE6790000U) -#define DBSC4_REG_DBSYSCNT0 (DBSC4_REG_BASE + 0x0100U) -#define DBSC4_REG_DBACEN (DBSC4_REG_BASE + 0x0200U) -#define DBSC4_REG_DBCMD (DBSC4_REG_BASE + 0x0208U) -#define DBSC4_REG_DBRFEN (DBSC4_REG_BASE + 0x0204U) -#define DBSC4_REG_DBWAIT (DBSC4_REG_BASE + 0x0210U) -#define DBSC4_REG_DBCALCNF (DBSC4_REG_BASE + 0x0424U) -#define DBSC4_REG_DBDFIPMSTRCNF (DBSC4_REG_BASE + 0x0520U) -#define DBSC4_REG_DBPDLK0 (DBSC4_REG_BASE + 0x0620U) -#define DBSC4_REG_DBPDRGA0 (DBSC4_REG_BASE + 0x0624U) -#define DBSC4_REG_DBPDRGD0 (DBSC4_REG_BASE + 0x0628U) -#define DBSC4_REG_DBCAM0CTRL0 (DBSC4_REG_BASE + 0x0940U) -#define DBSC4_REG_DBCAM0STAT0 (DBSC4_REG_BASE + 0x0980U) -#define DBSC4_REG_DBCAM1STAT0 (DBSC4_REG_BASE + 0x0990U) -#define DBSC4_REG_DBCAM2STAT0 (DBSC4_REG_BASE + 0x09A0U) -#define DBSC4_REG_DBCAM3STAT0 (DBSC4_REG_BASE + 0x09B0U) -#define DBSC4_BIT_DBACEN_ACCEN ((uint32_t)(1U << 0)) -#define DBSC4_BIT_DBRFEN_ARFEN ((uint32_t)(1U << 0)) -#define DBSC4_BIT_DBCAMxSTAT0 (0x00000001U) -#define DBSC4_BIT_DBDFIPMSTRCNF_PMSTREN (0x00000001U) -#define DBSC4_SET_DBCMD_OPC_PRE (0x04000000U) -#define DBSC4_SET_DBCMD_OPC_SR (0x0A000000U) -#define DBSC4_SET_DBCMD_OPC_PD (0x08000000U) -#define DBSC4_SET_DBCMD_OPC_MRW (0x0E000000U) -#define DBSC4_SET_DBCMD_CH_ALL (0x00800000U) -#define DBSC4_SET_DBCMD_RANK_ALL (0x00040000U) -#define DBSC4_SET_DBCMD_ARG_ALL (0x00000010U) -#define DBSC4_SET_DBCMD_ARG_ENTER (0x00000000U) -#define DBSC4_SET_DBCMD_ARG_MRW_ODTC (0x00000B00U) -#define DBSC4_SET_DBSYSCNT0_WRITE_ENABLE (0x00001234U) -#define DBSC4_SET_DBSYSCNT0_WRITE_DISABLE (0x00000000U) -#define DBSC4_SET_DBPDLK0_PHY_ACCESS (0x0000A55AU) -#define DBSC4_SET_DBPDRGA0_ACIOCR0 (0x0000001AU) -#define DBSC4_SET_DBPDRGD0_ACIOCR0 (0x33C03C11U) -#define DBSC4_SET_DBPDRGA0_DXCCR (0x00000020U) -#define DBSC4_SET_DBPDRGD0_DXCCR (0x00181006U) -#define DBSC4_SET_DBPDRGA0_PGCR1 (0x00000003U) -#define DBSC4_SET_DBPDRGD0_PGCR1 (0x0380C600U) -#define DBSC4_SET_DBPDRGA0_ACIOCR1 (0x0000001BU) -#define DBSC4_SET_DBPDRGD0_ACIOCR1 (0xAAAAAAAAU) -#define DBSC4_SET_DBPDRGA0_ACIOCR3 (0x0000001DU) -#define DBSC4_SET_DBPDRGD0_ACIOCR3 (0xAAAAAAAAU) -#define DBSC4_SET_DBPDRGA0_ACIOCR5 (0x0000001FU) -#define DBSC4_SET_DBPDRGD0_ACIOCR5 (0x000000AAU) -#define DBSC4_SET_DBPDRGA0_DX0GCR2 (0x000000A2U) -#define DBSC4_SET_DBPDRGD0_DX0GCR2 (0xAAAA0000U) -#define DBSC4_SET_DBPDRGA0_DX1GCR2 (0x000000C2U) -#define DBSC4_SET_DBPDRGD0_DX1GCR2 (0xAAAA0000U) -#define DBSC4_SET_DBPDRGA0_DX2GCR2 (0x000000E2U) -#define DBSC4_SET_DBPDRGD0_DX2GCR2 (0xAAAA0000U) -#define DBSC4_SET_DBPDRGA0_DX3GCR2 (0x00000102U) -#define DBSC4_SET_DBPDRGD0_DX3GCR2 (0xAAAA0000U) -#define DBSC4_SET_DBPDRGA0_ZQCR (0x00000090U) -#define DBSC4_SET_DBPDRGD0_ZQCR_MD19_0 (0x04058904U) -#define DBSC4_SET_DBPDRGD0_ZQCR_MD19_1 (0x04058A04U) -#define DBSC4_SET_DBPDRGA0_DX0GCR0 (0x000000A0U) -#define DBSC4_SET_DBPDRGD0_DX0GCR0 (0x7C0002E5U) -#define DBSC4_SET_DBPDRGA0_DX1GCR0 (0x000000C0U) -#define DBSC4_SET_DBPDRGD0_DX1GCR0 (0x7C0002E5U) -#define DBSC4_SET_DBPDRGA0_DX2GCR0 (0x000000E0U) -#define DBSC4_SET_DBPDRGD0_DX2GCR0 (0x7C0002E5U) -#define DBSC4_SET_DBPDRGA0_DX3GCR0 (0x00000100U) -#define DBSC4_SET_DBPDRGD0_DX3GCR0 (0x7C0002E5U) -#define DBSC4_SET_DBPDRGA0_DX0GCR1 (0x000000A1U) -#define DBSC4_SET_DBPDRGD0_DX0GCR1 (0x55550000U) -#define DBSC4_SET_DBPDRGA0_DX1GCR1 (0x000000C1U) -#define DBSC4_SET_DBPDRGD0_DX1GCR1 (0x55550000U) -#define DBSC4_SET_DBPDRGA0_DX2GCR1 (0x000000E1U) -#define DBSC4_SET_DBPDRGD0_DX2GCR1 (0x55550000U) -#define DBSC4_SET_DBPDRGA0_DX3GCR1 (0x00000101U) -#define DBSC4_SET_DBPDRGD0_DX3GCR1 (0x55550000U) -#define DBSC4_SET_DBPDRGA0_DX0GCR3 (0x000000A3U) -#define DBSC4_SET_DBPDRGD0_DX0GCR3 (0x00008484U) -#define DBSC4_SET_DBPDRGA0_DX1GCR3 (0x000000C3U) -#define DBSC4_SET_DBPDRGD0_DX1GCR3 (0x00008484U) -#define DBSC4_SET_DBPDRGA0_DX2GCR3 (0x000000E3U) -#define DBSC4_SET_DBPDRGD0_DX2GCR3 (0x00008484U) -#define DBSC4_SET_DBPDRGA0_DX3GCR3 (0x00000103U) -#define DBSC4_SET_DBPDRGD0_DX3GCR3 (0x00008484U) -#define RST_BASE (0xE6160000U) -#define RST_MODEMR (RST_BASE + 0x0060U) -#define RST_MODEMR_BIT0 (0x00000001U) - -#define RCAR_CNTCR_OFF (0x00U) -#define RCAR_CNTCVL_OFF (0x08U) -#define RCAR_CNTCVU_OFF (0x0CU) -#define RCAR_CNTFID_OFF (0x20U) - -#define RCAR_CNTCR_EN ((uint32_t)1U << 0U) -#define RCAR_CNTCR_FCREQ(x) ((uint32_t)(x) << 8U) - -#if PMIC_ROHM_BD9571 -#define BIT_BKUP_CTRL_OUT ((uint8_t)(1U << 4)) -#define PMIC_BKUP_MODE_CNT (0x20U) -#define PMIC_QLLM_CNT (0x27U) -#define PMIC_RETRY_MAX (100U) -#endif /* PMIC_ROHM_BD9571 */ -#define SCTLR_EL3_M_BIT ((uint32_t)1U << 0) -#define RCAR_CA53CPU_NUM_MAX (4U) -#define RCAR_CA57CPU_NUM_MAX (4U) -#define IS_A53A57(c) ((c) == RCAR_CLUSTER_A53A57) -#define IS_CA57(c) ((c) == RCAR_CLUSTER_CA57) -#define IS_CA53(c) ((c) == RCAR_CLUSTER_CA53) - -#ifndef __ASSEMBLER__ -IMPORT_SYM(unsigned long, __system_ram_start__, SYSTEM_RAM_START); -IMPORT_SYM(unsigned long, __system_ram_end__, SYSTEM_RAM_END); -IMPORT_SYM(unsigned long, __SRAM_COPY_START__, SRAM_COPY_START); -#endif - -uint32_t rcar_pwrc_status(uint64_t mpidr) -{ - uint32_t ret = 0; - uint64_t cm, cpu; - uint32_t reg; - uint32_t c; - - rcar_lock_get(); - - c = rcar_pwrc_get_cluster(); - cm = mpidr & MPIDR_CLUSTER_MASK; - - if (!IS_A53A57(c) && cm != 0) { - ret = RCAR_INVALID; - goto done; - } - - reg = mmio_read_32(RCAR_PRR); - cpu = mpidr & MPIDR_CPU_MASK; - - if (IS_CA53(c)) - if (reg & (1 << (STATE_CA53_CPU + cpu))) - ret = RCAR_INVALID; - if (IS_CA57(c)) - if (reg & (1 << (STATE_CA57_CPU + cpu))) - ret = RCAR_INVALID; -done: - rcar_lock_release(); - - return ret; -} - -static void scu_power_up(uint64_t mpidr) -{ - uintptr_t reg_pwrsr, reg_cpumcr, reg_pwron, reg_pwrer; - uint32_t c, sysc_reg_bit; - - c = rcar_pwrc_get_mpidr_cluster(mpidr); - reg_cpumcr = IS_CA57(c) ? RCAR_CA57CPUCMCR : RCAR_CA53CPUCMCR; - sysc_reg_bit = IS_CA57(c) ? BIT_CA57_SCU : BIT_CA53_SCU; - reg_pwron = IS_CA57(c) ? RCAR_PWRONCR5 : RCAR_PWRONCR3; - reg_pwrer = IS_CA57(c) ? RCAR_PWRER5 : RCAR_PWRER3; - reg_pwrsr = IS_CA57(c) ? RCAR_PWRSR5 : RCAR_PWRSR3; - - if ((mmio_read_32(reg_pwrsr) & STATUS_PWRDOWN) == 0) - return; - - if (mmio_read_32(reg_cpumcr) != 0) - mmio_write_32(reg_cpumcr, 0); - - mmio_setbits_32(RCAR_SYSCIER, sysc_reg_bit); - mmio_setbits_32(RCAR_SYSCIMR, sysc_reg_bit); - - do { - while ((mmio_read_32(RCAR_SYSCSR) & REQ_RESUME) == 0) - ; - mmio_write_32(reg_pwron, 1); - } while (mmio_read_32(reg_pwrer) & 1); - - while ((mmio_read_32(RCAR_SYSCISR) & sysc_reg_bit) == 0) - ; - mmio_write_32(RCAR_SYSCISR, sysc_reg_bit); - while ((mmio_read_32(reg_pwrsr) & STATUS_PWRUP) == 0) - ; -} - -void rcar_pwrc_cpuon(uint64_t mpidr) -{ - uint32_t res_data, on_data; - uintptr_t res_reg, on_reg; - uint32_t limit, c; - uint64_t cpu; - - rcar_lock_get(); - - c = rcar_pwrc_get_mpidr_cluster(mpidr); - res_reg = IS_CA53(c) ? RCAR_CA53RESCNT : RCAR_CA57RESCNT; - on_reg = IS_CA53(c) ? RCAR_CA53WUPCR : RCAR_CA57WUPCR; - limit = IS_CA53(c) ? 0x5A5A0000 : 0xA5A50000; - - res_data = mmio_read_32(res_reg) | limit; - scu_power_up(mpidr); - cpu = mpidr & MPIDR_CPU_MASK; - on_data = 1 << cpu; - mmio_write_32(RCAR_CPGWPR, ~on_data); - mmio_write_32(on_reg, on_data); - mmio_write_32(res_reg, res_data & (~(1 << (3 - cpu)))); - - rcar_lock_release(); -} - -void rcar_pwrc_cpuoff(uint64_t mpidr) -{ - uint32_t c; - uintptr_t reg; - uint64_t cpu; - - rcar_lock_get(); - - cpu = mpidr & MPIDR_CPU_MASK; - c = rcar_pwrc_get_mpidr_cluster(mpidr); - reg = IS_CA53(c) ? RCAR_CA53CPU0CR : RCAR_CA57CPU0CR; - - if (read_mpidr_el1() != mpidr) - panic(); - - mmio_write_32(RCAR_CPGWPR, ~CPU_PWR_OFF); - mmio_write_32(reg + cpu * 0x0010, CPU_PWR_OFF); - - rcar_lock_release(); -} - -void rcar_pwrc_enable_interrupt_wakeup(uint64_t mpidr) -{ - uint32_t c, shift_irq, shift_fiq; - uintptr_t reg; - uint64_t cpu; - - rcar_lock_get(); - - cpu = mpidr & MPIDR_CPU_MASK; - c = rcar_pwrc_get_mpidr_cluster(mpidr); - reg = IS_CA53(c) ? RCAR_WUPMSKCA53 : RCAR_WUPMSKCA57; - - shift_irq = WUP_IRQ_SHIFT + cpu; - shift_fiq = WUP_FIQ_SHIFT + cpu; - - mmio_write_32(reg, ~((uint32_t) 1 << shift_irq) & - ~((uint32_t) 1 << shift_fiq)); - rcar_lock_release(); -} - -void rcar_pwrc_disable_interrupt_wakeup(uint64_t mpidr) -{ - uint32_t c, shift_irq, shift_fiq; - uintptr_t reg; - uint64_t cpu; - - rcar_lock_get(); - - cpu = mpidr & MPIDR_CPU_MASK; - c = rcar_pwrc_get_mpidr_cluster(mpidr); - reg = IS_CA53(c) ? RCAR_WUPMSKCA53 : RCAR_WUPMSKCA57; - - shift_irq = WUP_IRQ_SHIFT + cpu; - shift_fiq = WUP_FIQ_SHIFT + cpu; - - mmio_write_32(reg, ((uint32_t) 1 << shift_irq) | - ((uint32_t) 1 << shift_fiq)); - rcar_lock_release(); -} - -void rcar_pwrc_clusteroff(uint64_t mpidr) -{ - uint32_t c, product, cut, reg; - uintptr_t dst; - - rcar_lock_get(); - - reg = mmio_read_32(RCAR_PRR); - product = reg & PRR_PRODUCT_MASK; - cut = reg & PRR_CUT_MASK; - - c = rcar_pwrc_get_mpidr_cluster(mpidr); - dst = IS_CA53(c) ? RCAR_CA53CPUCMCR : RCAR_CA57CPUCMCR; - - if (product == PRR_PRODUCT_M3 && cut < PRR_PRODUCT_30) { - goto done; - } - - if (product == PRR_PRODUCT_H3 && cut <= PRR_PRODUCT_20) { - goto done; - } - - /* all of the CPUs in the cluster is in the CoreStandby mode */ - mmio_write_32(dst, MODE_L2_DOWN); -done: - rcar_lock_release(); -} - -static uint64_t rcar_pwrc_saved_cntpct_el0; -static uint32_t rcar_pwrc_saved_cntfid; - -#if RCAR_SYSTEM_SUSPEND -static void rcar_pwrc_save_timer_state(void) -{ - rcar_pwrc_saved_cntpct_el0 = read_cntpct_el0(); - - rcar_pwrc_saved_cntfid = - mmio_read_32((uintptr_t)(RCAR_CNTC_BASE + RCAR_CNTFID_OFF)); -} -#endif /* RCAR_SYSTEM_SUSPEND */ - -void rcar_pwrc_restore_timer_state(void) -{ - /* Stop timer before restoring counter value */ - mmio_write_32((uintptr_t)(RCAR_CNTC_BASE + RCAR_CNTCR_OFF), 0U); - - mmio_write_32((uintptr_t)(RCAR_CNTC_BASE + RCAR_CNTCVL_OFF), - (uint32_t)(rcar_pwrc_saved_cntpct_el0 & 0xFFFFFFFFU)); - mmio_write_32((uintptr_t)(RCAR_CNTC_BASE + RCAR_CNTCVU_OFF), - (uint32_t)(rcar_pwrc_saved_cntpct_el0 >> 32U)); - - mmio_write_32((uintptr_t)(RCAR_CNTC_BASE + RCAR_CNTFID_OFF), - rcar_pwrc_saved_cntfid); - - /* Start generic timer back */ - write_cntfrq_el0((u_register_t)plat_get_syscnt_freq2()); - - mmio_write_32((uintptr_t)(RCAR_CNTC_BASE + RCAR_CNTCR_OFF), - (RCAR_CNTCR_FCREQ(0U) | RCAR_CNTCR_EN)); -} - -#if !PMIC_ROHM_BD9571 -void rcar_pwrc_system_reset(void) -{ - mmio_write_32(RCAR_SRESCR, 0x5AA50000U | BIT_SOFTRESET); -} -#endif /* PMIC_ROHM_BD9571 */ - -#define RST_CA53_CPU0_BARH (0xE6160080U) -#define RST_CA53_CPU0_BARL (0xE6160084U) -#define RST_CA57_CPU0_BARH (0xE61600C0U) -#define RST_CA57_CPU0_BARL (0xE61600C4U) - -void rcar_pwrc_setup(void) -{ - uintptr_t rst_barh; - uintptr_t rst_barl; - uint32_t i, j; - uint64_t reset = (uint64_t) (&plat_secondary_reset) & 0xFFFFFFFF; - - const uint32_t cluster[PLATFORM_CLUSTER_COUNT] = { - RCAR_CLUSTER_CA53, - RCAR_CLUSTER_CA57 - }; - const uintptr_t reg_barh[PLATFORM_CLUSTER_COUNT] = { - RST_CA53_CPU0_BARH, - RST_CA57_CPU0_BARH - }; - const uintptr_t reg_barl[PLATFORM_CLUSTER_COUNT] = { - RST_CA53_CPU0_BARL, - RST_CA57_CPU0_BARL - }; - - for (i = 0; i < PLATFORM_CLUSTER_COUNT; i++) { - rst_barh = reg_barh[i]; - rst_barl = reg_barl[i]; - for (j = 0; j < rcar_pwrc_get_cpu_num(cluster[i]); j++) { - mmio_write_32(rst_barh, 0); - mmio_write_32(rst_barl, (uint32_t) reset); - rst_barh += 0x10; - rst_barl += 0x10; - } - } - - rcar_lock_init(); -} - -#if RCAR_SYSTEM_SUSPEND -#define DBCAM_FLUSH(__bit) \ -do { \ - ; \ -} while (!(mmio_read_32(DBSC4_REG_DBCAM##__bit##STAT0) & DBSC4_BIT_DBCAMxSTAT0)) - - -static void __attribute__ ((section(".system_ram"))) - rcar_pwrc_set_self_refresh(void) -{ - uint32_t reg = mmio_read_32(RCAR_PRR); - uint32_t cut, product; - - product = reg & PRR_PRODUCT_MASK; - cut = reg & PRR_CUT_MASK; - - if (product == PRR_PRODUCT_M3 && cut < PRR_PRODUCT_30) { - goto self_refresh; - } - - if (product == PRR_PRODUCT_H3 && cut < PRR_PRODUCT_20) { - goto self_refresh; - } - - mmio_write_32(DBSC4_REG_DBSYSCNT0, DBSC4_SET_DBSYSCNT0_WRITE_ENABLE); - -self_refresh: - - /* DFI_PHYMSTR_ACK setting */ - mmio_write_32(DBSC4_REG_DBDFIPMSTRCNF, - mmio_read_32(DBSC4_REG_DBDFIPMSTRCNF) & - (~DBSC4_BIT_DBDFIPMSTRCNF_PMSTREN)); - - /* Set the Self-Refresh mode */ - mmio_write_32(DBSC4_REG_DBACEN, 0); - - if (product == PRR_PRODUCT_H3 && cut < PRR_PRODUCT_20) - rcar_micro_delay(100); - else if (product == PRR_PRODUCT_H3) { - mmio_write_32(DBSC4_REG_DBCAM0CTRL0, 1); - DBCAM_FLUSH(0); - DBCAM_FLUSH(1); - DBCAM_FLUSH(2); - DBCAM_FLUSH(3); - mmio_write_32(DBSC4_REG_DBCAM0CTRL0, 0); - } else if (product == PRR_PRODUCT_M3) { - mmio_write_32(DBSC4_REG_DBCAM0CTRL0, 1); - DBCAM_FLUSH(0); - DBCAM_FLUSH(1); - mmio_write_32(DBSC4_REG_DBCAM0CTRL0, 0); - } else { - mmio_write_32(DBSC4_REG_DBCAM0CTRL0, 1); - DBCAM_FLUSH(0); - mmio_write_32(DBSC4_REG_DBCAM0CTRL0, 0); - } - - /* Set the SDRAM calibration configuration register */ - mmio_write_32(DBSC4_REG_DBCALCNF, 0); - - reg = DBSC4_SET_DBCMD_OPC_PRE | DBSC4_SET_DBCMD_CH_ALL | - DBSC4_SET_DBCMD_RANK_ALL | DBSC4_SET_DBCMD_ARG_ALL; - mmio_write_32(DBSC4_REG_DBCMD, reg); - while (mmio_read_32(DBSC4_REG_DBWAIT)) - ; - - /* Self-Refresh entry command */ - reg = DBSC4_SET_DBCMD_OPC_SR | DBSC4_SET_DBCMD_CH_ALL | - DBSC4_SET_DBCMD_RANK_ALL | DBSC4_SET_DBCMD_ARG_ENTER; - mmio_write_32(DBSC4_REG_DBCMD, reg); - while (mmio_read_32(DBSC4_REG_DBWAIT)) - ; - - /* Mode Register Write command. (ODT disabled) */ - reg = DBSC4_SET_DBCMD_OPC_MRW | DBSC4_SET_DBCMD_CH_ALL | - DBSC4_SET_DBCMD_RANK_ALL | DBSC4_SET_DBCMD_ARG_MRW_ODTC; - mmio_write_32(DBSC4_REG_DBCMD, reg); - while (mmio_read_32(DBSC4_REG_DBWAIT)) - ; - - /* Power Down entry command */ - reg = DBSC4_SET_DBCMD_OPC_PD | DBSC4_SET_DBCMD_CH_ALL | - DBSC4_SET_DBCMD_RANK_ALL | DBSC4_SET_DBCMD_ARG_ENTER; - mmio_write_32(DBSC4_REG_DBCMD, reg); - while (mmio_read_32(DBSC4_REG_DBWAIT)) - ; - - /* Set the auto-refresh enable register */ - mmio_write_32(DBSC4_REG_DBRFEN, 0U); - rcar_micro_delay(1U); - - if (product == PRR_PRODUCT_M3 && cut < PRR_PRODUCT_30) - return; - - if (product == PRR_PRODUCT_H3 && cut < PRR_PRODUCT_20) - return; - - mmio_write_32(DBSC4_REG_DBSYSCNT0, DBSC4_SET_DBSYSCNT0_WRITE_DISABLE); -} - -static void __attribute__ ((section(".system_ram"))) -rcar_pwrc_set_self_refresh_e3(void) -{ - uint32_t ddr_md; - uint32_t reg; - - ddr_md = (mmio_read_32(RST_MODEMR) >> 19) & RST_MODEMR_BIT0; - - /* Write enable */ - mmio_write_32(DBSC4_REG_DBSYSCNT0, DBSC4_SET_DBSYSCNT0_WRITE_ENABLE); - mmio_write_32(DBSC4_REG_DBACEN, 0); - DBCAM_FLUSH(0); - - reg = DBSC4_SET_DBCMD_OPC_PRE | DBSC4_SET_DBCMD_CH_ALL | - DBSC4_SET_DBCMD_RANK_ALL | DBSC4_SET_DBCMD_ARG_ALL; - mmio_write_32(DBSC4_REG_DBCMD, reg); - while (mmio_read_32(DBSC4_REG_DBWAIT)) - ; - - reg = DBSC4_SET_DBCMD_OPC_SR | DBSC4_SET_DBCMD_CH_ALL | - DBSC4_SET_DBCMD_RANK_ALL | DBSC4_SET_DBCMD_ARG_ENTER; - mmio_write_32(DBSC4_REG_DBCMD, reg); - while (mmio_read_32(DBSC4_REG_DBWAIT)) - ; - - /* - * Set the auto-refresh enable register - * Set the ARFEN bit to 0 in the DBRFEN - */ - mmio_write_32(DBSC4_REG_DBRFEN, 0); - - mmio_write_32(DBSC4_REG_DBPDLK0, DBSC4_SET_DBPDLK0_PHY_ACCESS); - - mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_ACIOCR0); - mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_ACIOCR0); - - /* DDR_DXCCR */ - mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DXCCR); - mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DXCCR); - - /* DDR_PGCR1 */ - mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_PGCR1); - mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_PGCR1); - - /* DDR_ACIOCR1 */ - mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_ACIOCR1); - mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_ACIOCR1); - - /* DDR_ACIOCR3 */ - mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_ACIOCR3); - mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_ACIOCR3); - - /* DDR_ACIOCR5 */ - mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_ACIOCR5); - mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_ACIOCR5); - - /* DDR_DX0GCR2 */ - mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX0GCR2); - mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX0GCR2); - - /* DDR_DX1GCR2 */ - mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX1GCR2); - mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX1GCR2); - - /* DDR_DX2GCR2 */ - mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX2GCR2); - mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX2GCR2); - - /* DDR_DX3GCR2 */ - mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX3GCR2); - mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX3GCR2); - - /* DDR_ZQCR */ - mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_ZQCR); - - mmio_write_32(DBSC4_REG_DBPDRGD0, ddr_md == 0 ? - DBSC4_SET_DBPDRGD0_ZQCR_MD19_0 : - DBSC4_SET_DBPDRGD0_ZQCR_MD19_1); - - /* DDR_DX0GCR0 */ - mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX0GCR0); - mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX0GCR0); - - /* DDR_DX1GCR0 */ - mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX1GCR0); - mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX1GCR0); - - /* DDR_DX2GCR0 */ - mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX2GCR0); - mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX2GCR0); - - /* DDR_DX3GCR0 */ - mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX3GCR0); - mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX3GCR0); - - /* DDR_DX0GCR1 */ - mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX0GCR1); - mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX0GCR1); - - /* DDR_DX1GCR1 */ - mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX1GCR1); - mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX1GCR1); - - /* DDR_DX2GCR1 */ - mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX2GCR1); - mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX2GCR1); - - /* DDR_DX3GCR1 */ - mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX3GCR1); - mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX3GCR1); - - /* DDR_DX0GCR3 */ - mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX0GCR3); - mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX0GCR3); - - /* DDR_DX1GCR3 */ - mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX1GCR3); - mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX1GCR3); - - /* DDR_DX2GCR3 */ - mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX2GCR3); - mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX2GCR3); - - /* DDR_DX3GCR3 */ - mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX3GCR3); - mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX3GCR3); - - /* Write disable */ - mmio_write_32(DBSC4_REG_DBSYSCNT0, DBSC4_SET_DBSYSCNT0_WRITE_DISABLE); -} - -void __attribute__ ((section(".system_ram"))) __attribute__ ((noinline)) -rcar_pwrc_go_suspend_to_ram(void) -{ -#if PMIC_ROHM_BD9571 - int32_t rc = -1, qllm = -1; - uint8_t mode; - uint32_t i; -#endif - uint32_t reg, product; - - reg = mmio_read_32(RCAR_PRR); - product = reg & PRR_PRODUCT_MASK; - - if (product != PRR_PRODUCT_E3) - rcar_pwrc_set_self_refresh(); - else - rcar_pwrc_set_self_refresh_e3(); - -#if PMIC_ROHM_BD9571 - /* Set QLLM Cnt Disable */ - for (i = 0; (i < PMIC_RETRY_MAX) && (qllm != 0); i++) - qllm = rcar_iic_dvfs_send(PMIC, PMIC_QLLM_CNT, 0); - - /* Set trigger of power down to PMIV */ - for (i = 0; (i < PMIC_RETRY_MAX) && (rc != 0) && (qllm == 0); i++) { - rc = rcar_iic_dvfs_receive(PMIC, PMIC_BKUP_MODE_CNT, &mode); - if (rc == 0) { - mode |= BIT_BKUP_CTRL_OUT; - rc = rcar_iic_dvfs_send(PMIC, PMIC_BKUP_MODE_CNT, mode); - } - } -#endif - wfi(); - - while (1) - ; -} - -void rcar_pwrc_set_suspend_to_ram(void) -{ - uintptr_t jump = (uintptr_t) &rcar_pwrc_go_suspend_to_ram; - uintptr_t stack = (uintptr_t) (DEVICE_SRAM_STACK_BASE + - DEVICE_SRAM_STACK_SIZE); - uint32_t sctlr; - - rcar_pwrc_save_timer_state(); - - /* disable MMU */ - sctlr = (uint32_t) read_sctlr_el3(); - sctlr &= (uint32_t) ~SCTLR_EL3_M_BIT; - write_sctlr_el3((uint64_t) sctlr); - - rcar_pwrc_switch_stack(jump, stack, NULL); -} - -void rcar_pwrc_init_suspend_to_ram(void) -{ -#if PMIC_ROHM_BD9571 - uint8_t mode; - - if (rcar_iic_dvfs_receive(PMIC, PMIC_BKUP_MODE_CNT, &mode)) - panic(); - - mode &= (uint8_t) (~BIT_BKUP_CTRL_OUT); - if (rcar_iic_dvfs_send(PMIC, PMIC_BKUP_MODE_CNT, mode)) - panic(); -#endif -} - -void rcar_pwrc_suspend_to_ram(void) -{ -#if RCAR_SYSTEM_RESET_KEEPON_DDR - int32_t error; - - error = rcar_iic_dvfs_send(PMIC, REG_KEEP10, 0); - if (error) { - ERROR("Failed send KEEP10 init ret=%d\n", error); - return; - } -#endif - rcar_pwrc_set_suspend_to_ram(); -} -#endif - -void rcar_pwrc_code_copy_to_system_ram(void) -{ - int ret __attribute__ ((unused)); /* in assert */ - uint32_t attr; - struct device_sram_t { - uintptr_t base; - size_t len; - } sram = { - .base = (uintptr_t) DEVICE_SRAM_BASE, - .len = DEVICE_SRAM_SIZE, - }; - struct ddr_code_t { - void *base; - size_t len; - } code = { - .base = (void *) SRAM_COPY_START, - .len = SYSTEM_RAM_END - SYSTEM_RAM_START, - }; - - attr = MT_MEMORY | MT_RW | MT_SECURE | MT_EXECUTE_NEVER; - ret = xlat_change_mem_attributes(sram.base, sram.len, attr); - assert(ret == 0); - - memcpy((void *)sram.base, code.base, code.len); - flush_dcache_range((uint64_t) sram.base, code.len); - - /* 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) -{ - uint32_t reg; - - reg = mmio_read_32(RCAR_PRR); - - if (reg & (1U << (STATE_CA53_CPU + RCAR_CA53CPU_NUM_MAX))) - return RCAR_CLUSTER_CA57; - - if (reg & (1U << (STATE_CA57_CPU + RCAR_CA57CPU_NUM_MAX))) - return RCAR_CLUSTER_CA53; - - return RCAR_CLUSTER_A53A57; -} - -uint32_t rcar_pwrc_get_mpidr_cluster(uint64_t mpidr) -{ - uint32_t c = rcar_pwrc_get_cluster(); - - if (IS_A53A57(c)) { - if (mpidr & MPIDR_CLUSTER_MASK) - return RCAR_CLUSTER_CA53; - - return RCAR_CLUSTER_CA57; - } - - return c; -} - -#if RCAR_LSI == RCAR_D3 -uint32_t rcar_pwrc_get_cpu_num(uint32_t c) -{ - return 1; -} -#else -uint32_t rcar_pwrc_get_cpu_num(uint32_t c) -{ - uint32_t reg = mmio_read_32(RCAR_PRR); - uint32_t count = 0, i; - - if (IS_A53A57(c) || IS_CA53(c)) { - if (reg & (1 << (STATE_CA53_CPU + RCAR_CA53CPU_NUM_MAX))) - goto count_ca57; - - for (i = 0; i < RCAR_CA53CPU_NUM_MAX; i++) { - if (reg & (1 << (STATE_CA53_CPU + i))) - continue; - count++; - } - } - -count_ca57: - if (IS_A53A57(c) || IS_CA57(c)) { - if (reg & (1U << (STATE_CA57_CPU + RCAR_CA57CPU_NUM_MAX))) - goto done; - - for (i = 0; i < RCAR_CA57CPU_NUM_MAX; i++) { - if (reg & (1 << (STATE_CA57_CPU + i))) - continue; - count++; - } - } - -done: - return count; -} -#endif - -int32_t rcar_pwrc_cpu_on_check(uint64_t mpidr) -{ - uint64_t i; - uint64_t j; - uint64_t cpu_count; - uintptr_t reg_PSTR; - uint32_t status; - uint64_t my_cpu; - int32_t rtn; - uint32_t my_cluster_type; - const uint32_t cluster_type[PLATFORM_CLUSTER_COUNT] = { - RCAR_CLUSTER_CA53, - RCAR_CLUSTER_CA57 - }; - const uintptr_t registerPSTR[PLATFORM_CLUSTER_COUNT] = { - RCAR_CA53PSTR, - RCAR_CA57PSTR - }; - - my_cluster_type = rcar_pwrc_get_cluster(); - - rtn = 0; - my_cpu = mpidr & ((uint64_t)(MPIDR_CPU_MASK)); - for (i = 0U; i < ((uint64_t)(PLATFORM_CLUSTER_COUNT)); i++) { - cpu_count = rcar_pwrc_get_cpu_num(cluster_type[i]); - reg_PSTR = registerPSTR[i]; - for (j = 0U; j < cpu_count; j++) { - if ((my_cluster_type != cluster_type[i]) || (my_cpu != j)) { - status = mmio_read_32(reg_PSTR) >> (j * 4U); - if ((status & 0x00000003U) == 0U) { - rtn--; - } - } - } - } - - return rtn; -} diff --git a/drivers/renesas/rcar/pwrc/pwrc.h b/drivers/renesas/rcar/pwrc/pwrc.h deleted file mode 100644 index f73099b0b..000000000 --- a/drivers/renesas/rcar/pwrc/pwrc.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef PWRC_H -#define PWRC_H - -#define PPOFFR_OFF 0x0 -#define PPONR_OFF 0x4 -#define PCOFFR_OFF 0x8 -#define PWKUPR_OFF 0xc -#define PSYSR_OFF 0x10 - -#define PWKUPR_WEN (1ull << 31) - -#define PSYSR_AFF_L2 (1U << 31) -#define PSYSR_AFF_L1 (1 << 30) -#define PSYSR_AFF_L0 (1 << 29) -#define PSYSR_WEN (1 << 28) -#define PSYSR_PC (1 << 27) -#define PSYSR_PP (1 << 26) - -#define PSYSR_WK_SHIFT (24) -#define PSYSR_WK_MASK (0x3) -#define PSYSR_WK(x) (((x) >> PSYSR_WK_SHIFT) & PSYSR_WK_MASK) - -#define WKUP_COLD 0x0 -#define WKUP_RESET 0x1 -#define WKUP_PPONR 0x2 -#define WKUP_GICREQ 0x3 - -#define RCAR_INVALID (0xffffffffU) -#define PSYSR_INVALID 0xffffffff - -#define RCAR_CLUSTER_A53A57 (0U) -#define RCAR_CLUSTER_CA53 (1U) -#define RCAR_CLUSTER_CA57 (2U) - -#ifndef __ASSEMBLER__ -void rcar_pwrc_disable_interrupt_wakeup(uint64_t mpidr); -void rcar_pwrc_enable_interrupt_wakeup(uint64_t mpidr); -void rcar_pwrc_clusteroff(uint64_t mpidr); -void rcar_pwrc_cpuoff(uint64_t mpidr); -void rcar_pwrc_cpuon(uint64_t mpidr); -int32_t rcar_pwrc_cpu_on_check(uint64_t mpidr); -void rcar_pwrc_setup(void); - -uint32_t rcar_pwrc_get_cpu_wkr(uint64_t mpidr); -uint32_t rcar_pwrc_status(uint64_t mpidr); -uint32_t rcar_pwrc_get_cluster(void); -uint32_t rcar_pwrc_get_mpidr_cluster(uint64_t mpidr); -uint32_t rcar_pwrc_get_cpu_num(uint32_t cluster_type); -void rcar_pwrc_restore_timer_state(void); -void plat_secondary_reset(void); - -void rcar_pwrc_code_copy_to_system_ram(void); - -#if !PMIC_ROHM_BD9571 -void rcar_pwrc_system_reset(void); -#endif - -#if RCAR_SYSTEM_SUSPEND -void rcar_pwrc_go_suspend_to_ram(void); -void rcar_pwrc_set_suspend_to_ram(void); -void rcar_pwrc_init_suspend_to_ram(void); -void rcar_pwrc_suspend_to_ram(void); -#endif - -extern uint32_t rcar_pwrc_switch_stack(uintptr_t jump, uintptr_t stack, - void *arg); -#endif - -#endif /* PWRC_H */ diff --git a/plat/renesas/common/common.mk b/plat/renesas/common/common.mk index 82f4d7d7e..6e8786d66 100644 --- a/plat/renesas/common/common.mk +++ b/plat/renesas/common/common.mk @@ -94,6 +94,8 @@ BL31_SOURCES += ${RCAR_GIC_SOURCES} \ lib/cpus/aarch64/cortex_a53.S \ lib/cpus/aarch64/cortex_a57.S \ plat/common/plat_psci_common.c \ + drivers/renesas/common/pwrc/call_sram.S \ + drivers/renesas/common/pwrc/pwrc.c \ drivers/renesas/common/common.c \ drivers/arm/cci/cci.c diff --git a/plat/renesas/rcar/platform.mk b/plat/renesas/rcar/platform.mk index 1f0c8abc4..6685a8115 100644 --- a/plat/renesas/rcar/platform.mk +++ b/plat/renesas/rcar/platform.mk @@ -308,7 +308,7 @@ PLAT_INCLUDES += -Idrivers/renesas/rcar/ddr \ -Idrivers/renesas/rcar/rom \ -Idrivers/renesas/rcar/scif \ -Idrivers/renesas/common/emmc \ - -Idrivers/renesas/rcar/pwrc \ + -Idrivers/renesas/common/pwrc \ -Idrivers/renesas/common/io BL2_SOURCES += plat/renesas/rcar/aarch64/platform_common.c \ @@ -338,9 +338,7 @@ BL31_SOURCES += plat/renesas/rcar/plat_topology.c \ plat/renesas/rcar/plat_pm.c \ drivers/renesas/rcar/console/rcar_console.S \ drivers/renesas/rcar/console/rcar_printf.c \ - drivers/renesas/rcar/delay/micro_delay.c \ - drivers/renesas/rcar/pwrc/call_sram.S \ - drivers/renesas/rcar/pwrc/pwrc.c + drivers/renesas/rcar/delay/micro_delay.c ifeq (${RCAR_GEN3_ULCB},1) BL31_SOURCES += drivers/renesas/rcar/cpld/ulcb_cpld.c -- cgit v1.2.3 From 157c4fcafdead3852071cb2a97fa6ec79ce4b881 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Sun, 13 Dec 2020 20:44:28 +0000 Subject: plat: renesas:rcar: Fix checkpatch warnings Fix checkpatch warnings. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: If9318a5113fbd6ae8b5c4bfb409da9e393673258 --- plat/renesas/rcar/bl2_secure_setting.c | 602 +++++++++++++++++---------------- 1 file changed, 306 insertions(+), 296 deletions(-) diff --git a/plat/renesas/rcar/bl2_secure_setting.c b/plat/renesas/rcar/bl2_secure_setting.c index 7473df5a2..095d1f62a 100644 --- a/plat/renesas/rcar/bl2_secure_setting.c +++ b/plat/renesas/rcar/bl2_secure_setting.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -18,230 +18,244 @@ static const struct { uint32_t reg; uint32_t val; } lifec[] = { - /** LIFEC0 (SECURITY) settings */ - /* Security attribute setting for master ports */ - /* Bit 0: ARM realtime core (Cortex-R7) master port */ - /* 0: Non-Secure */ - { - SEC_SRC, 0x0000001EU}, - /** Security attribute setting for slave ports 0 to 15 */ - /* {SEC_SEL0, 0xFFFFFFFFU}, */ - /* {SEC_SEL1, 0xFFFFFFFFU}, */ - /* {SEC_SEL2, 0xFFFFFFFFU}, */ - /* Bit19: AXI-Bus (Main Memory domain AXI) slave ports */ - /* 0: registers accessed from secure resource only */ - /* Bit 9: DBSC4 register access slave ports. */ - /* 0: registers accessed from secure resource only. */ + /* + * LIFEC0 (SECURITY) settings + * Security attribute setting for master ports + * Bit 0: ARM realtime core (Cortex-R7) master port + * 0: Non-Secure + */ + { SEC_SRC, 0x0000001EU }, + /* + * Security attribute setting for slave ports 0 to 15 + * {SEC_SEL0, 0xFFFFFFFFU}, + * {SEC_SEL1, 0xFFFFFFFFU}, + * {SEC_SEL2, 0xFFFFFFFFU}, + * Bit19: AXI-Bus (Main Memory domain AXI) slave ports + * 0: registers accessed from secure resource only + * Bit 9: DBSC4 register access slave ports. + * 0: registers accessed from secure resource only. + */ #if (LIFEC_DBSC_PROTECT_ENABLE == 1) - { - SEC_SEL3, 0xFFF7FDFFU}, -#else - { - SEC_SEL3, 0xFFFFFFFFU}, -#endif - /* {SEC_SEL4, 0xFFFFFFFFU}, */ - /* Bit 6: Boot ROM slave ports. */ - /* 0: registers accessed from secure resource only */ - { - SEC_SEL5, 0xFFFFFFBFU}, - /* Bit13: SCEG PKA (secure APB) slave ports */ - /* 0: registers accessed from secure resource only */ - /* 1: Reserved[R-Car E3] */ - /* Bit12: SCEG PKA (public APB) slave ports */ - /* 0: registers accessed from secure resource only */ - /* 1: Reserved[R-Car E3] */ - /* Bit10: SCEG Secure Core slave ports */ - /* 0: registers accessed from secure resource only */ + { SEC_SEL3, 0xFFF7FDFFU }, +#else /* LIFEC_DBSC_PROTECT_ENABLE == 1 */ + { SEC_SEL3, 0xFFFFFFFFU }, +#endif /* LIFEC_DBSC_PROTECT_ENABLE == 1 */ + /* + * {SEC_SEL4, 0xFFFFFFFFU}, + * Bit 6: Boot ROM slave ports. + * 0: registers accessed from secure resource only + */ + { SEC_SEL5, 0xFFFFFFBFU }, + /* + * Bit13: SCEG PKA (secure APB) slave ports + * 0: registers accessed from secure resource only + * 1: Reserved[R-Car E3] + * Bit12: SCEG PKA (public APB) slave ports + * 0: registers accessed from secure resource only + * 1: Reserved[R-Car E3] + * Bit10: SCEG Secure Core slave ports + * 0: registers accessed from secure resource only + */ #if (RCAR_LSI == RCAR_E3) || (RCAR_LSI == RCAR_D3) - { - SEC_SEL6, 0xFFFFFBFFU}, -#else - { - SEC_SEL6, 0xFFFFCBFFU}, -#endif - /* {SEC_SEL7, 0xFFFFFFFFU}, */ - /* {SEC_SEL8, 0xFFFFFFFFU}, */ - /* {SEC_SEL9, 0xFFFFFFFFU}, */ - /* {SEC_SEL10, 0xFFFFFFFFU}, */ - /* {SEC_SEL11, 0xFFFFFFFFU}, */ - /* {SEC_SEL12, 0xFFFFFFFFU}, */ - /* Bit22: RPC slave ports. */ - /* 0: registers accessed from secure resource only. */ + { SEC_SEL6, 0xFFFFFBFFU }, +#else /* (RCAR_LSI == RCAR_E3) || (RCAR_LSI == RCAR_D3) */ + { SEC_SEL6, 0xFFFFCBFFU }, +#endif /* (RCAR_LSI == RCAR_E3) || (RCAR_LSI == RCAR_D3) */ + /* + * {SEC_SEL7, 0xFFFFFFFFU}, + * {SEC_SEL8, 0xFFFFFFFFU}, + * {SEC_SEL9, 0xFFFFFFFFU}, + * {SEC_SEL10, 0xFFFFFFFFU}, + * {SEC_SEL11, 0xFFFFFFFFU}, + * {SEC_SEL12, 0xFFFFFFFFU}, + * Bit22: RPC slave ports. + * 0: registers accessed from secure resource only. + */ #if (RCAR_RPC_HYPERFLASH_LOCKED == 1) - {SEC_SEL13, 0xFFBFFFFFU}, -#endif - /* Bit27: System Timer (SCMT) slave ports */ - /* 0: registers accessed from secure resource only */ - /* Bit26: System Watchdog Timer (SWDT) slave ports */ - /* 0: registers accessed from secure resource only */ - { - SEC_SEL14, 0xF3FFFFFFU}, - /* Bit13: RST slave ports. */ - /* 0: registers accessed from secure resource only */ - /* Bit 7: Life Cycle 0 slave ports */ - /* 0: registers accessed from secure resource only */ - { - SEC_SEL15, 0xFFFFFF3FU}, - /** Security group 0 attribute setting for master ports 0 */ - /** Security group 1 attribute setting for master ports 0 */ - /* {SEC_GRP0CR0, 0x00000000U}, */ - /* {SEC_GRP1CR0, 0x00000000U}, */ - /** Security group 0 attribute setting for master ports 1 */ - /** Security group 1 attribute setting for master ports 1 */ - /* {SEC_GRP0CR1, 0x00000000U}, */ - /* {SEC_GRP1CR1, 0x00000000U}, */ - /** Security group 0 attribute setting for master ports 2 */ - /** Security group 1 attribute setting for master ports 2 */ - /* Bit17: SCEG Secure Core master ports. */ - /* SecurityGroup3 */ - { - SEC_GRP0CR2, 0x00020000U}, { - SEC_GRP1CR2, 0x00020000U}, - /** Security group 0 attribute setting for master ports 3 */ - /** Security group 1 attribute setting for master ports 3 */ - /* {SEC_GRP0CR3, 0x00000000U}, */ - /* {SEC_GRP1CR3, 0x00000000U}, */ - /** Security group 0 attribute setting for slave ports 0 */ - /** Security group 1 attribute setting for slave ports 0 */ - /* {SEC_GRP0COND0, 0x00000000U}, */ - /* {SEC_GRP1COND0, 0x00000000U}, */ - /** Security group 0 attribute setting for slave ports 1 */ - /** Security group 1 attribute setting for slave ports 1 */ - /* {SEC_GRP0COND1, 0x00000000U}, */ - /* {SEC_GRP1COND1, 0x00000000U}, */ - /** Security group 0 attribute setting for slave ports 2 */ - /** Security group 1 attribute setting for slave ports 2 */ - /* {SEC_GRP0COND2, 0x00000000U}, */ - /* {SEC_GRP1COND2, 0x00000000U}, */ - /** Security group 0 attribute setting for slave ports 3 */ - /** Security group 1 attribute setting for slave ports 3 */ - /* Bit19: AXI-Bus (Main Memory domain AXI) slave ports. */ - /* SecurityGroup3 */ - /* Bit 9: DBSC4 register access slave ports. */ - /* SecurityGroup3 */ + { SEC_SEL13, 0xFFBFFFFFU }, +#endif /* (RCAR_RPC_HYPERFLASH_LOCKED == 1) */ + /* + * Bit27: System Timer (SCMT) slave ports + * 0: registers accessed from secure resource only + * Bit26: System Watchdog Timer (SWDT) slave ports + * 0: registers accessed from secure resource only + */ + { SEC_SEL14, 0xF3FFFFFFU }, + /* + * Bit13: RST slave ports. + * 0: registers accessed from secure resource only + * Bit 7: Life Cycle 0 slave ports + * 0: registers accessed from secure resource only + */ + { SEC_SEL15, 0xFFFFFF3FU }, + /* + * Security group 0 attribute setting for master ports 0 + * Security group 1 attribute setting for master ports 0 + * {SEC_GRP0CR0, 0x00000000U}, + * {SEC_GRP1CR0, 0x00000000U}, + * Security group 0 attribute setting for master ports 1 + * Security group 1 attribute setting for master ports 1 + * {SEC_GRP0CR1, 0x00000000U}, + * {SEC_GRP1CR1, 0x00000000U}, + * Security group 0 attribute setting for master ports 2 + * Security group 1 attribute setting for master ports 2 + * Bit17: SCEG Secure Core master ports. + * SecurityGroup3 + */ + { SEC_GRP0CR2, 0x00020000U }, + { SEC_GRP1CR2, 0x00020000U }, + /* + * Security group 0 attribute setting for master ports 3 + * Security group 1 attribute setting for master ports 3 + * {SEC_GRP0CR3, 0x00000000U}, + * {SEC_GRP1CR3, 0x00000000U}, + * Security group 0 attribute setting for slave ports 0 + * Security group 1 attribute setting for slave ports 0 + * {SEC_GRP0COND0, 0x00000000U}, + * {SEC_GRP1COND0, 0x00000000U}, + * Security group 0 attribute setting for slave ports 1 + * Security group 1 attribute setting for slave ports 1 + * {SEC_GRP0COND1, 0x00000000U}, + * {SEC_GRP1COND1, 0x00000000U}, + * Security group 0 attribute setting for slave ports 2 + * Security group 1 attribute setting for slave ports 2 + * {SEC_GRP0COND2, 0x00000000U}, + * {SEC_GRP1COND2, 0x00000000U}, + * Security group 0 attribute setting for slave ports 3 + * Security group 1 attribute setting for slave ports 3 + * Bit19: AXI-Bus (Main Memory domain AXI) slave ports. + * SecurityGroup3 + * Bit 9: DBSC4 register access slave ports. + * SecurityGroup3 + */ #if (LIFEC_DBSC_PROTECT_ENABLE == 1) - { - SEC_GRP0COND3, 0x00080200U}, { - SEC_GRP1COND3, 0x00080200U}, -#else - { - SEC_GRP0COND3, 0x00000000U}, { - SEC_GRP1COND3, 0x00000000U}, -#endif - /** Security group 0 attribute setting for slave ports 4 */ - /** Security group 1 attribute setting for slave ports 4 */ - /* {SEC_GRP0COND4, 0x00000000U}, */ - /* {SEC_GRP1COND4, 0x00000000U}, */ - /** Security group 0 attribute setting for slave ports 5 */ - /** Security group 1 attribute setting for slave ports 5 */ - /* Bit 6: Boot ROM slave ports */ - /* SecurityGroup3 */ - { - SEC_GRP0COND5, 0x00000040U}, { - SEC_GRP1COND5, 0x00000040U}, - /** Security group 0 attribute setting for slave ports 6 */ - /** Security group 1 attribute setting for slave ports 6 */ - /* Bit13: SCEG PKA (secure APB) slave ports */ - /* SecurityGroup3 */ - /* Reserved[R-Car E3] */ - /* Bit12: SCEG PKA (public APB) slave ports */ - /* SecurityGroup3 */ - /* Reserved[R-Car E3] */ - /* Bit10: SCEG Secure Core slave ports */ - /* SecurityGroup3 */ + { SEC_GRP0COND3, 0x00080200U }, + { SEC_GRP1COND3, 0x00080200U }, +#else /* (LIFEC_DBSC_PROTECT_ENABLE == 1) */ + { SEC_GRP0COND3, 0x00000000U }, + { SEC_GRP1COND3, 0x00000000U }, +#endif /* (LIFEC_DBSC_PROTECT_ENABLE == 1) */ + /* + * Security group 0 attribute setting for slave ports 4 + * Security group 1 attribute setting for slave ports 4 + * {SEC_GRP0COND4, 0x00000000U}, + * {SEC_GRP1COND4, 0x00000000U}, + * Security group 0 attribute setting for slave ports 5 + * Security group 1 attribute setting for slave ports 5 + * Bit 6: Boot ROM slave ports + * SecurityGroup3 + */ + { SEC_GRP0COND5, 0x00000040U }, + { SEC_GRP1COND5, 0x00000040U }, + /* + * Security group 0 attribute setting for slave ports 6 + * Security group 1 attribute setting for slave ports 6 + * Bit13: SCEG PKA (secure APB) slave ports + * SecurityGroup3 + * Reserved[R-Car E3] + * Bit12: SCEG PKA (public APB) slave ports + * SecurityGroup3 + * Reserved[R-Car E3] + * Bit10: SCEG Secure Core slave ports + * SecurityGroup3 + */ #if RCAR_LSI == RCAR_E3 - { - SEC_GRP0COND6, 0x00000400U}, { - SEC_GRP1COND6, 0x00000400U}, -#else - { - SEC_GRP0COND6, 0x00003400U}, { - SEC_GRP1COND6, 0x00003400U}, -#endif - /** Security group 0 attribute setting for slave ports 7 */ - /** Security group 1 attribute setting for slave ports 7 */ - /* {SEC_GRP0COND7, 0x00000000U}, */ - /* {SEC_GRP1COND7, 0x00000000U}, */ - /** Security group 0 attribute setting for slave ports 8 */ - /** Security group 1 attribute setting for slave ports 8 */ - /* {SEC_GRP0COND8, 0x00000000U}, */ - /* {SEC_GRP1COND8, 0x00000000U}, */ - /** Security group 0 attribute setting for slave ports 9 */ - /** Security group 1 attribute setting for slave ports 9 */ - /* {SEC_GRP0COND9, 0x00000000U}, */ - /* {SEC_GRP1COND9, 0x00000000U}, */ - /** Security group 0 attribute setting for slave ports 10 */ - /** Security group 1 attribute setting for slave ports 10 */ - /* {SEC_GRP0COND10, 0x00000000U}, */ - /* {SEC_GRP1COND10, 0x00000000U}, */ - /** Security group 0 attribute setting for slave ports 11 */ - /** Security group 1 attribute setting for slave ports 11 */ - /* {SEC_GRP0COND11, 0x00000000U}, */ - /* {SEC_GRP1COND11, 0x00000000U}, */ - /** Security group 0 attribute setting for slave ports 12 */ - /** Security group 1 attribute setting for slave ports 12 */ - /* {SEC_GRP0COND12, 0x00000000U}, */ - /* {SEC_GRP1COND12, 0x00000000U}, */ - /** Security group 0 attribute setting for slave ports 13 */ - /** Security group 1 attribute setting for slave ports 13 */ - /* Bit22: RPC slave ports. */ - /* SecurityGroup3 */ + { SEC_GRP0COND6, 0x00000400U }, + { SEC_GRP1COND6, 0x00000400U }, +#else /* RCAR_LSI == RCAR_E3 */ + { SEC_GRP0COND6, 0x00003400U }, + { SEC_GRP1COND6, 0x00003400U }, +#endif /* RCAR_LSI == RCAR_E3 */ + /* + * Security group 0 attribute setting for slave ports 7 + * Security group 1 attribute setting for slave ports 7 + * {SEC_GRP0COND7, 0x00000000U}, + * {SEC_GRP1COND7, 0x00000000U}, + * Security group 0 attribute setting for slave ports 8 + * Security group 1 attribute setting for slave ports 8 + * {SEC_GRP0COND8, 0x00000000U}, + * {SEC_GRP1COND8, 0x00000000U}, + * Security group 0 attribute setting for slave ports 9 + * Security group 1 attribute setting for slave ports 9 + * {SEC_GRP0COND9, 0x00000000U}, + * {SEC_GRP1COND9, 0x00000000U}, + * Security group 0 attribute setting for slave ports 10 + * Security group 1 attribute setting for slave ports 10 + * {SEC_GRP0COND10, 0x00000000U}, + * {SEC_GRP1COND10, 0x00000000U}, + * Security group 0 attribute setting for slave ports 11 + * Security group 1 attribute setting for slave ports 11 + * {SEC_GRP0COND11, 0x00000000U}, + * {SEC_GRP1COND11, 0x00000000U}, + * Security group 0 attribute setting for slave ports 12 + * Security group 1 attribute setting for slave ports 12 + * {SEC_GRP0COND12, 0x00000000U}, + * {SEC_GRP1COND12, 0x00000000U}, + * Security group 0 attribute setting for slave ports 13 + * Security group 1 attribute setting for slave ports 13 + * Bit22: RPC slave ports. + * SecurityGroup3 + */ #if (RCAR_RPC_HYPERFLASH_LOCKED == 1) - {SEC_GRP0COND13, 0x00400000U}, - {SEC_GRP1COND13, 0x00400000U}, -#endif - /** Security group 0 attribute setting for slave ports 14 */ - /** Security group 1 attribute setting for slave ports 14 */ - /* Bit26: System Timer (SCMT) slave ports */ - /* SecurityGroup3 */ - /* Bit27: System Watchdog Timer (SWDT) slave ports */ - /* SecurityGroup3 */ - { - SEC_GRP0COND14, 0x0C000000U}, { - SEC_GRP1COND14, 0x0C000000U}, - /** Security group 0 attribute setting for slave ports 15 */ - /** Security group 1 attribute setting for slave ports 15 */ - /* Bit13: RST slave ports */ - /* SecurityGroup3 */ - /* Bit 7: Life Cycle 0 slave ports */ - /* SecurityGroup3 */ - /* Bit 6: TDBG slave ports */ - /* SecurityGroup3 */ - { - SEC_GRP0COND15, 0x000000C0U}, { - SEC_GRP1COND15, 0x000000C0U}, - /** Security write protection attribute setting slave ports 0 */ - /* {SEC_READONLY0, 0x00000000U}, */ - /** Security write protection attribute setting slave ports 1 */ - /* {SEC_READONLY1, 0x00000000U}, */ - /** Security write protection attribute setting slave ports 2 */ - /* {SEC_READONLY2, 0x00000000U}, */ - /** Security write protection attribute setting slave ports 3 */ - /* {SEC_READONLY3, 0x00000000U}, */ - /** Security write protection attribute setting slave ports 4 */ - /* {SEC_READONLY4, 0x00000000U}, */ - /** Security write protection attribute setting slave ports 5 */ - /* {SEC_READONLY5, 0x00000000U}, */ - /** Security write protection attribute setting slave ports 6 */ - /* {SEC_READONLY6, 0x00000000U}, */ - /** Security write protection attribute setting slave ports 7 */ - /* {SEC_READONLY7, 0x00000000U}, */ - /** Security write protection attribute setting slave ports 8 */ - /* {SEC_READONLY8, 0x00000000U}, */ - /** Security write protection attribute setting slave ports 9 */ - /* {SEC_READONLY9, 0x00000000U}, */ - /** Security write protection attribute setting slave ports 10 */ - /* {SEC_READONLY10, 0x00000000U}, */ - /** Security write protection attribute setting slave ports 11 */ - /* {SEC_READONLY11, 0x00000000U}, */ - /** Security write protection attribute setting slave ports 12 */ - /* {SEC_READONLY12, 0x00000000U}, */ - /** Security write protection attribute setting slave ports 13 */ - /* {SEC_READONLY13, 0x00000000U}, */ - /** Security write protection attribute setting slave ports 14 */ - /* {SEC_READONLY14, 0x00000000U}, */ - /** Security write protection attribute setting slave ports 15 */ - /* {SEC_READONLY15, 0x00000000U} */ + { SEC_GRP0COND13, 0x00400000U }, + { SEC_GRP1COND13, 0x00400000U }, +#endif /* (RCAR_RPC_HYPERFLASH_LOCKED == 1) */ + /* + * Security group 0 attribute setting for slave ports 14 + * Security group 1 attribute setting for slave ports 14 + * Bit26: System Timer (SCMT) slave ports + * SecurityGroup3 + * Bit27: System Watchdog Timer (SWDT) slave ports + * SecurityGroup3 + */ + { SEC_GRP0COND14, 0x0C000000U }, + { SEC_GRP1COND14, 0x0C000000U }, + /* + * Security group 0 attribute setting for slave ports 15 + * Security group 1 attribute setting for slave ports 15 + * Bit13: RST slave ports + * SecurityGroup3 + * Bit 7: Life Cycle 0 slave ports + * SecurityGroup3 + * Bit 6: TDBG slave ports + * SecurityGroup3 + */ + { SEC_GRP0COND15, 0x000000C0U }, + { SEC_GRP1COND15, 0x000000C0U }, + /* + * Security write protection attribute setting slave ports 0 + * {SEC_READONLY0, 0x00000000U}, + * Security write protection attribute setting slave ports 1 + * {SEC_READONLY1, 0x00000000U}, + * Security write protection attribute setting slave ports 2 + * {SEC_READONLY2, 0x00000000U}, + * Security write protection attribute setting slave ports 3 + * {SEC_READONLY3, 0x00000000U}, + * Security write protection attribute setting slave ports 4 + * {SEC_READONLY4, 0x00000000U}, + * Security write protection attribute setting slave ports 5 + * {SEC_READONLY5, 0x00000000U}, + * Security write protection attribute setting slave ports 6 + * {SEC_READONLY6, 0x00000000U}, + * Security write protection attribute setting slave ports 7 + * {SEC_READONLY7, 0x00000000U}, + * Security write protection attribute setting slave ports 8 + * {SEC_READONLY8, 0x00000000U}, + * Security write protection attribute setting slave ports 9 + * {SEC_READONLY9, 0x00000000U}, + * Security write protection attribute setting slave ports 10 + * {SEC_READONLY10, 0x00000000U}, + * Security write protection attribute setting slave ports 11 + * {SEC_READONLY11, 0x00000000U}, + * Security write protection attribute setting slave ports 12 + * {SEC_READONLY12, 0x00000000U}, + * Security write protection attribute setting slave ports 13 + * {SEC_READONLY13, 0x00000000U}, + * Security write protection attribute setting slave ports 14 + * {SEC_READONLY14, 0x00000000U}, + * Security write protection attribute setting slave ports 15 + * {SEC_READONLY15, 0x00000000U} + */ }; /* AXI settings */ @@ -249,78 +263,78 @@ static const struct { uint32_t reg; uint32_t val; } axi[] = { - /* DRAM protection */ - /* AXI dram protected area division */ - { - AXI_DPTDIVCR0, 0x0E0403F0U}, { - AXI_DPTDIVCR1, 0x0E0407E0U}, { - AXI_DPTDIVCR2, 0x0E080000U}, { - AXI_DPTDIVCR3, 0x0E080000U}, { - AXI_DPTDIVCR4, 0x0E080000U}, { - AXI_DPTDIVCR5, 0x0E080000U}, { - AXI_DPTDIVCR6, 0x0E080000U}, { - AXI_DPTDIVCR7, 0x0E080000U}, { - AXI_DPTDIVCR8, 0x0E080000U}, { - AXI_DPTDIVCR9, 0x0E080000U}, { - AXI_DPTDIVCR10, 0x0E080000U}, { - AXI_DPTDIVCR11, 0x0E080000U}, { - AXI_DPTDIVCR12, 0x0E080000U}, { - AXI_DPTDIVCR13, 0x0E080000U}, { - AXI_DPTDIVCR14, 0x0E080000U}, - /* AXI dram protected area setting */ - { - AXI_DPTCR0, 0x0E000000U}, { - AXI_DPTCR1, 0x0E000E0EU}, { - AXI_DPTCR2, 0x0E000000U}, { - AXI_DPTCR3, 0x0E000000U}, { - AXI_DPTCR4, 0x0E000000U}, { - AXI_DPTCR5, 0x0E000000U}, { - AXI_DPTCR6, 0x0E000000U}, { - AXI_DPTCR7, 0x0E000000U}, { - AXI_DPTCR8, 0x0E000000U}, { - AXI_DPTCR9, 0x0E000000U}, { - AXI_DPTCR10, 0x0E000000U}, { - AXI_DPTCR11, 0x0E000000U}, { - AXI_DPTCR12, 0x0E000000U}, { - AXI_DPTCR13, 0x0E000000U}, { - AXI_DPTCR14, 0x0E000000U}, { - AXI_DPTCR15, 0x0E000000U}, - /* SRAM ptotection */ - /* AXI sram protected area division */ - { - AXI_SPTDIVCR0, 0x0E0E6304U}, { - AXI_SPTDIVCR1, 0x0E0E6360U}, { - AXI_SPTDIVCR2, 0x0E0E6360U}, { - AXI_SPTDIVCR3, 0x0E0E6360U}, { - AXI_SPTDIVCR4, 0x0E0E6360U}, { - AXI_SPTDIVCR5, 0x0E0E6360U}, { - AXI_SPTDIVCR6, 0x0E0E6360U}, { - AXI_SPTDIVCR7, 0x0E0E6360U}, { - AXI_SPTDIVCR8, 0x0E0E6360U}, { - AXI_SPTDIVCR9, 0x0E0E6360U}, { - AXI_SPTDIVCR10, 0x0E0E6360U}, { - AXI_SPTDIVCR11, 0x0E0E6360U}, { - AXI_SPTDIVCR12, 0x0E0E6360U}, { - AXI_SPTDIVCR13, 0x0E0E6360U}, { - AXI_SPTDIVCR14, 0x0E0E6360U}, - /* AXI sram protected area setting */ - { - AXI_SPTCR0, 0x0E000E0EU}, { - AXI_SPTCR1, 0x0E000000U}, { - AXI_SPTCR2, 0x0E000000U}, { - AXI_SPTCR3, 0x0E000000U}, { - AXI_SPTCR4, 0x0E000000U}, { - AXI_SPTCR5, 0x0E000000U}, { - AXI_SPTCR6, 0x0E000000U}, { - AXI_SPTCR7, 0x0E000000U}, { - AXI_SPTCR8, 0x0E000000U}, { - AXI_SPTCR9, 0x0E000000U}, { - AXI_SPTCR10, 0x0E000000U}, { - AXI_SPTCR11, 0x0E000000U}, { - AXI_SPTCR12, 0x0E000000U}, { - AXI_SPTCR13, 0x0E000000U}, { - AXI_SPTCR14, 0x0E000000U}, { - AXI_SPTCR15, 0x0E000000U} + /* + * DRAM protection + * AXI dram protected area division + */ + {AXI_DPTDIVCR0, 0x0E0403F0U}, + {AXI_DPTDIVCR1, 0x0E0407E0U}, + {AXI_DPTDIVCR2, 0x0E080000U}, + {AXI_DPTDIVCR3, 0x0E080000U}, + {AXI_DPTDIVCR4, 0x0E080000U}, + {AXI_DPTDIVCR5, 0x0E080000U}, + {AXI_DPTDIVCR6, 0x0E080000U}, + {AXI_DPTDIVCR7, 0x0E080000U}, + {AXI_DPTDIVCR8, 0x0E080000U}, + {AXI_DPTDIVCR9, 0x0E080000U}, + {AXI_DPTDIVCR10, 0x0E080000U}, + {AXI_DPTDIVCR11, 0x0E080000U}, + {AXI_DPTDIVCR12, 0x0E080000U}, + {AXI_DPTDIVCR13, 0x0E080000U}, + {AXI_DPTDIVCR14, 0x0E080000U}, + /* AXI dram protected area setting */ + {AXI_DPTCR0, 0x0E000000U}, + {AXI_DPTCR1, 0x0E000E0EU}, + {AXI_DPTCR2, 0x0E000000U}, + {AXI_DPTCR3, 0x0E000000U}, + {AXI_DPTCR4, 0x0E000000U}, + {AXI_DPTCR5, 0x0E000000U}, + {AXI_DPTCR6, 0x0E000000U}, + {AXI_DPTCR7, 0x0E000000U}, + {AXI_DPTCR8, 0x0E000000U}, + {AXI_DPTCR9, 0x0E000000U}, + {AXI_DPTCR10, 0x0E000000U}, + {AXI_DPTCR11, 0x0E000000U}, + {AXI_DPTCR12, 0x0E000000U}, + {AXI_DPTCR13, 0x0E000000U}, + {AXI_DPTCR14, 0x0E000000U}, + {AXI_DPTCR15, 0x0E000000U}, + /* + * SRAM ptotection + * AXI sram protected area division + */ + {AXI_SPTDIVCR0, 0x0E0E6304U}, + {AXI_SPTDIVCR1, 0x0E0E6360U}, + {AXI_SPTDIVCR2, 0x0E0E6360U}, + {AXI_SPTDIVCR3, 0x0E0E6360U}, + {AXI_SPTDIVCR4, 0x0E0E6360U}, + {AXI_SPTDIVCR5, 0x0E0E6360U}, + {AXI_SPTDIVCR6, 0x0E0E6360U}, + {AXI_SPTDIVCR7, 0x0E0E6360U}, + {AXI_SPTDIVCR8, 0x0E0E6360U}, + {AXI_SPTDIVCR9, 0x0E0E6360U}, + {AXI_SPTDIVCR10, 0x0E0E6360U}, + {AXI_SPTDIVCR11, 0x0E0E6360U}, + {AXI_SPTDIVCR12, 0x0E0E6360U}, + {AXI_SPTDIVCR13, 0x0E0E6360U}, + {AXI_SPTDIVCR14, 0x0E0E6360U}, + /* AXI sram protected area setting */ + {AXI_SPTCR0, 0x0E000E0EU}, + {AXI_SPTCR1, 0x0E000000U}, + {AXI_SPTCR2, 0x0E000000U}, + {AXI_SPTCR3, 0x0E000000U}, + {AXI_SPTCR4, 0x0E000000U}, + {AXI_SPTCR5, 0x0E000000U}, + {AXI_SPTCR6, 0x0E000000U}, + {AXI_SPTCR7, 0x0E000000U}, + {AXI_SPTCR8, 0x0E000000U}, + {AXI_SPTCR9, 0x0E000000U}, + {AXI_SPTCR10, 0x0E000000U}, + {AXI_SPTCR11, 0x0E000000U}, + {AXI_SPTCR12, 0x0E000000U}, + {AXI_SPTCR13, 0x0E000000U}, + {AXI_SPTCR14, 0x0E000000U}, + {AXI_SPTCR15, 0x0E000000U} }; static void lifec_security_setting(void) @@ -342,11 +356,7 @@ static void axi_security_setting(void) void bl2_secure_setting(void) { - const uint32_t delay = 10; - lifec_security_setting(); axi_security_setting(); - rcar_micro_delay(delay); - - return; + rcar_micro_delay(10U); } -- cgit v1.2.3 From 865e34741b02b3a9ddf9f652f2649407f33debb0 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Wed, 16 Dec 2020 10:36:17 +0000 Subject: drivers: renesas: console: Move to common Move console/scif driver code to common directory, so that the same code can be re-used by both R-Car Gen3 and RZ/G2 platforms. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: I0b15e4f4ffaaa99e77bcee32b1dad648eeadcd9b --- drivers/renesas/common/console/rcar_console.S | 93 ++++++++ drivers/renesas/common/console/rcar_printf.c | 108 +++++++++ drivers/renesas/common/console/rcar_printf.h | 15 ++ drivers/renesas/common/scif/scif.S | 329 ++++++++++++++++++++++++++ drivers/renesas/rcar/console/rcar_console.S | 93 -------- drivers/renesas/rcar/console/rcar_printf.c | 108 --------- drivers/renesas/rcar/console/rcar_printf.h | 15 -- drivers/renesas/rcar/scif/scif.S | 329 -------------------------- plat/renesas/common/common.mk | 4 + plat/renesas/rcar/platform.mk | 6 +- 10 files changed, 550 insertions(+), 550 deletions(-) create mode 100644 drivers/renesas/common/console/rcar_console.S create mode 100644 drivers/renesas/common/console/rcar_printf.c create mode 100644 drivers/renesas/common/console/rcar_printf.h create mode 100644 drivers/renesas/common/scif/scif.S delete mode 100644 drivers/renesas/rcar/console/rcar_console.S delete mode 100644 drivers/renesas/rcar/console/rcar_printf.c delete mode 100644 drivers/renesas/rcar/console/rcar_printf.h delete mode 100644 drivers/renesas/rcar/scif/scif.S diff --git a/drivers/renesas/common/console/rcar_console.S b/drivers/renesas/common/console/rcar_console.S new file mode 100644 index 000000000..29baa67a4 --- /dev/null +++ b/drivers/renesas/common/console/rcar_console.S @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2018-2019, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + + .globl console_rcar_register + .globl console_rcar_init + .globl console_rcar_putc + .globl console_rcar_flush + + .extern rcar_log_init + .extern rcar_set_log_data + + /* ----------------------------------------------- + * int console_rcar_register( + * uintptr_t base, uint32_t clk, uint32_t baud, + * console_t *console) + * Function to initialize and register a new rcar + * console. Storage passed in for the console struct + * *must* be persistent (i.e. not from the stack). + * In: x0 - UART register base address + * w1 - UART clock in Hz + * w2 - Baud rate + * x3 - pointer to empty console_t struct + * Out: return 1 on success, 0 on error + * Clobber list : x0, x1, x2, x6, x7, x14 + * ----------------------------------------------- + */ +func console_rcar_register + mov x7, x30 + mov x6, x3 + cbz x6, register_fail + str x0, [x6, #CONSOLE_T_BASE] + + bl rcar_log_init + cbz x0, register_fail + + mov x0, x6 + mov x30, x7 + finish_console_register rcar, putc=1, getc=0, flush=1 + +register_fail: + ret x7 +endfunc console_rcar_register + + /* --------------------------------------------- + * int console_rcar_init(unsigned long base_addr, + * unsigned int uart_clk, unsigned int baud_rate) + * Function to initialize the console without a + * C Runtime to print debug information. This + * function will be accessed by crash reporting. + * In: x0 - console base address + * w1 - Uart clock in Hz + * w2 - Baud rate + * Out: return 1 on success + * Clobber list : x1, x2 + * --------------------------------------------- + */ +func console_rcar_init + mov w0, #0 + ret +endfunc console_rcar_init + + /* -------------------------------------------------------- + * int console_rcar_putc(int c, console_t *console) + * Function to output a character over the console. It + * returns the character printed on success or -1 on error. + * In : w0 - character to be printed + * x1 - pointer to console_t structure + * Out : return -1 on error else return character. + * Clobber list : x2 + * -------------------------------------------------------- + */ +func console_rcar_putc + b rcar_set_log_data +endfunc console_rcar_putc + + /* --------------------------------------------- + * void console_rcar_flush(void) + * Function to force a write of all buffered + * data that hasn't been output. It returns void + * Clobber list : x0, x1 + * --------------------------------------------- + */ +func console_rcar_flush + ret +endfunc console_rcar_flush diff --git a/drivers/renesas/common/console/rcar_printf.c b/drivers/renesas/common/console/rcar_printf.c new file mode 100644 index 000000000..ad074fe05 --- /dev/null +++ b/drivers/renesas/common/console/rcar_printf.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include + +#include +#include +#include + +#include "rcar_def.h" +#include "rcar_private.h" +#include "rcar_printf.h" + +#define INDEX_TIMER_COUNT (4U) + +#define RCAR_LOG_HEAD (('T' << 0) | ('L' << 8) | ('O' << 16) | ('G' << 24)) + +/* + * The log is initialized and used before BL31 xlat tables are initialized, + * therefore the log memory is a device memory at that point. Make sure the + * memory is correclty aligned and accessed only with up-to 32bit, aligned, + * writes. + */ +CASSERT((RCAR_BL31_LOG_BASE & 0x7) == 0, assert_bl31_log_base_unaligned); +CASSERT((RCAR_BL31_LOG_MAX & 0x7) == 0, assert_bl31_log_max_unaligned); + +extern RCAR_INSTANTIATE_LOCK typedef struct log_head { + uint32_t head; + uint32_t index; + uint32_t size; + uint32_t res; +} loghead_t; + +typedef struct log_map { + loghead_t header; + uint8_t log_data[RCAR_BL31_LOG_MAX]; + uint8_t res_data[RCAR_LOG_RES_SIZE]; +} logmap_t; + +int32_t rcar_set_log_data(int32_t c) +{ + logmap_t *t_log; + + t_log = (logmap_t *) RCAR_BL31_LOG_BASE; + + rcar_lock_get(); + + /* + * If index is broken, then index and size initialize + */ + if (t_log->header.index >= (uint32_t) RCAR_BL31_LOG_MAX) { + t_log->header.index = 0U; + t_log->header.size = 0U; + } + /* + * data store to log area then index and size renewal + */ + t_log->log_data[t_log->header.index] = (uint8_t) c; + t_log->header.index++; + if (t_log->header.size < t_log->header.index) { + t_log->header.size = t_log->header.index; + } + if (t_log->header.index >= (uint32_t) RCAR_BL31_LOG_MAX) { + t_log->header.index = 0U; + } + + rcar_lock_release(); + + return 1; +} + +int32_t rcar_log_init(void) +{ + logmap_t *t_log = (logmap_t *)RCAR_BL31_LOG_BASE; + uint32_t *log_data = (uint32_t *)t_log->log_data; + int16_t init_flag = 0; + int i; + + if (t_log->header.head != RCAR_LOG_HEAD) { + /* + * Log header is not "TLOG", then log area initialize + */ + init_flag = 1; + } + if (t_log->header.index >= (uint32_t) RCAR_BL31_LOG_MAX) { + /* + * index is broken, then log area initialize + */ + init_flag = 1; + } + if (init_flag == 1) { + for (i = 0; i < RCAR_BL31_LOG_MAX; i += 4) + *log_data++ = 0; + + t_log->header.head = RCAR_LOG_HEAD; + t_log->header.index = 0U; + t_log->header.size = 0U; + } + rcar_lock_init(); + + return 1; +} diff --git a/drivers/renesas/common/console/rcar_printf.h b/drivers/renesas/common/console/rcar_printf.h new file mode 100644 index 000000000..5da70e636 --- /dev/null +++ b/drivers/renesas/common/console/rcar_printf.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef RCAR_PRINTF_H +#define RCAR_PRINTF_H + +#include + +int32_t rcar_set_log_data(int32_t c); +int32_t rcar_log_init(void); + +#endif /* RCAR_PRINTF_H */ diff --git a/drivers/renesas/common/scif/scif.S b/drivers/renesas/common/scif/scif.S new file mode 100644 index 000000000..beb8dd838 --- /dev/null +++ b/drivers/renesas/common/scif/scif.S @@ -0,0 +1,329 @@ +/* + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +#define SCIF_INTERNAL_CLK 0 +#define SCIF_EXTARNAL_CLK 1 +#define SCIF_CLK SCIF_INTERNAL_CLK + +/* product register */ +#define PRR (0xFFF00044) +#define PRR_PRODUCT_MASK (0x00007F00) +#define PRR_CUT_MASK (0x000000FF) +#define PRR_PRODUCT_H3_VER_10 (0x00004F00) +#define PRR_PRODUCT_E3 (0x00005700) +#define PRR_PRODUCT_D3 (0x00005800) + +/* module stop */ +#define CPG_BASE (0xE6150000) +#define CPG_SMSTPCR2 (0x0138) +#define CPG_SMSTPCR3 (0x013C) +#define CPG_MSTPSR2 (0x0040) +#define CPG_MSTPSR3 (0x0048) +#define MSTP207 (1 << 7) +#define MSTP310 (1 << 10) +#define CPG_CPGWPR (0x0900) + +/* scif */ +#define SCIF0_BASE (0xE6E60000) +#define SCIF2_BASE (0xE6E88000) +#define SCIF_SCSMR (0x00) +#define SCIF_SCBRR (0x04) +#define SCIF_SCSCR (0x08) +#define SCIF_SCFTDR (0x0C) +#define SCIF_SCFSR (0x10) +#define SCIF_SCFRDR (0x14) +#define SCIF_SCFCR (0x18) +#define SCIF_SCFDR (0x1C) +#define SCIF_SCSPTR (0x20) +#define SCIF_SCLSR (0x24) +#define SCIF_DL (0x30) +#define SCIF_CKS (0x34) + +#if RCAR_LSI == RCAR_V3M +#define SCIF_BASE SCIF0_BASE +#define CPG_SMSTPCR CPG_SMSTPCR2 +#define CPG_MSTPSR CPG_MSTPSR2 +#define MSTP MSTP207 +#else +#define SCIF_BASE SCIF2_BASE +#define CPG_SMSTPCR CPG_SMSTPCR3 +#define CPG_MSTPSR CPG_MSTPSR3 +#define MSTP MSTP310 +#endif + +/* mode pin */ +#define RST_MODEMR (0xE6160060) +#define MODEMR_MD12 (0x00001000) + +#define SCSMR_CA_MASK (1 << 7) +#define SCSMR_CA_ASYNC (0x0000) +#define SCSMR_CHR_MASK (1 << 6) +#define SCSMR_CHR_8 (0x0000) +#define SCSMR_PE_MASK (1 << 5) +#define SCSMR_PE_DIS (0x0000) +#define SCSMR_STOP_MASK (1 << 3) +#define SCSMR_STOP_1 (0x0000) +#define SCSMR_CKS_MASK (3 << 0) +#define SCSMR_CKS_DIV1 (0x0000) +#define SCSMR_INIT_DATA (SCSMR_CA_ASYNC + \ + SCSMR_CHR_8 + \ + SCSMR_PE_DIS + \ + SCSMR_STOP_1 + \ + SCSMR_CKS_DIV1) +#define SCBRR_115200BPS (17) +#define SCBRR_115200BPSON (16) +#define SCBRR_115200BPS_E3_SSCG (15) +#define SCBRR_230400BPS (8) + +#define SCSCR_TE_MASK (1 << 5) +#define SCSCR_TE_DIS (0x0000) +#define SCSCR_TE_EN (0x0020) +#define SCSCR_RE_MASK (1 << 4) +#define SCSCR_RE_DIS (0x0000) +#define SCSCR_RE_EN (0x0010) +#define SCSCR_CKE_MASK (3 << 0) +#define SCSCR_CKE_INT (0x0000) +#define SCSCR_CKE_BRG (0x0002) +#if SCIF_CLK == SCIF_EXTARNAL_CLK +#define SCSCR_CKE_INT_CLK (SCSCR_CKE_BRG) +#else +#define SCFSR_TEND_MASK (1 << 6) +#define SCFSR_TEND_TRANS_END (0x0040) +#define SCSCR_CKE_INT_CLK (SCSCR_CKE_INT) +#endif +#define SCFSR_INIT_DATA (0x0000) +#define SCFCR_TTRG_MASK (3 << 4) +#define SCFCR_TTRG_8 (0x0000) +#define SCFCR_TTRG_0 (0x0030) +#define SCFCR_TFRST_MASK (1 << 2) +#define SCFCR_TFRST_DIS (0x0000) +#define SCFCR_TFRST_EN (0x0004) +#define SCFCR_RFRS_MASK (1 << 1) +#define SCFCR_RFRS_DIS (0x0000) +#define SCFCR_RFRS_EN (0x0002) +#define SCFCR_INIT_DATA (SCFCR_TTRG_8) +#define SCFDR_T_MASK (0x1f << 8) +#define DL_INIT_DATA (8) +#define CKS_CKS_DIV_MASK (1 << 15) +#define CKS_CKS_DIV_CLK (0x0000) +#define CKS_XIN_MASK (1 << 14) +#define CKS_XIN_SCIF_CLK (0x0000) +#define CKS_INIT_DATA (CKS_CKS_DIV_CLK + CKS_XIN_SCIF_CLK) + + .globl console_rcar_register + .globl console_rcar_init + .globl console_rcar_putc + .globl console_rcar_flush + + /* + * ----------------------------------------------- + * int console_rcar_register( + * uintptr_t base, uint32_t clk, uint32_t baud, + * console_t *console) + * Function to initialize and register a new rcar + * console. Storage passed in for the console struct + * *must* be persistent (i.e. not from the stack). + * In: x0 - UART register base address + * w1 - UART clock in Hz + * w2 - Baud rate + * x3 - pointer to empty console_t struct + * Out: return 1 on success, 0 on error + * Clobber list : x0, x1, x2, x6, x7, x14 + * ----------------------------------------------- + */ +func console_rcar_register + mov x7, x30 + mov x6, x3 + cbz x6, register_fail + str x0, [x6, #CONSOLE_T_BASE] + + bl console_rcar_init + + mov x0, x6 + mov x30, x7 + finish_console_register rcar, putc=1, getc=0, flush=1 + +register_fail: + ret x7 +endfunc console_rcar_register + + /* + * int console_rcar_init(unsigned long base_addr, + * unsigned int uart_clk, unsigned int baud_rate) + * Function to initialize the console without a + * C Runtime to print debug information. This + * function will be accessed by console_rcar_register + * and crash reporting. + * In: x0 - console base address + * w1 - Uart clock in Hz + * w2 - Baud rate + * Out: return 1 on success + * Clobber list : x1, x2 + */ +func console_rcar_init + ldr x0, =CPG_BASE + ldr w1, [x0, #CPG_SMSTPCR] + and w1, w1, #~MSTP + mvn w2, w1 + str w2, [x0, #CPG_CPGWPR] + str w1, [x0, #CPG_SMSTPCR] +5: + ldr w1, [x0, #CPG_MSTPSR] + and w1, w1, #MSTP + cbnz w1, 5b + + ldr x0, =SCIF_BASE + /* Clear bits TE and RE in SCSCR to 0 */ + mov w1, #(SCSCR_TE_DIS + SCSCR_RE_DIS) + strh w1, [x0, #SCIF_SCSCR] + /* Set bits TFRST and RFRST in SCFCR to 1 */ + ldrh w1, [x0, #SCIF_SCFCR] + orr w1, w1, #(SCFCR_TFRST_EN + SCFCR_RFRS_EN) + strh w1, [x0, #SCIF_SCFCR] + /* + * Read flags of ER, DR, BRK, and RDF in SCFSR and those of TO and ORER + * in SCLSR, then clear them to 0 + */ + mov w1, #SCFSR_INIT_DATA + strh w1, [x0, #SCIF_SCFSR] + mov w1, #0 + strh w1, [x0, #SCIF_SCLSR] + /* Set bits CKE[1:0] in SCSCR */ + ldrh w1, [x0, #SCIF_SCSCR] + and w1, w1, #~SCSCR_CKE_MASK + mov w2, #SCSCR_CKE_INT_CLK + orr w1, w1, w2 + strh w1, [x0, #SCIF_SCSCR] + /* Set data transfer format in SCSMR */ + mov w1, #SCSMR_INIT_DATA + strh w1, [x0, #SCIF_SCSMR] + /* Set value in SCBRR */ +#if SCIF_CLK == SCIF_INTERNAL_CLK + ldr x1, =PRR + ldr w1, [x1] + and w1, w1, #(PRR_PRODUCT_MASK | PRR_CUT_MASK) + mov w2, #PRR_PRODUCT_H3_VER_10 + cmp w1, w2 + beq 3f + and w1, w1, #PRR_PRODUCT_MASK + mov w2, #PRR_PRODUCT_D3 + cmp w1, w2 + beq 4f + and w1, w1, #PRR_PRODUCT_MASK + mov w2, #PRR_PRODUCT_E3 + cmp w1, w2 + bne 5f + + ldr x1, =RST_MODEMR + ldr w1, [x1] + and w1, w1, #MODEMR_MD12 + mov w2, #MODEMR_MD12 + cmp w1, w2 + bne 5f + + mov w1, #SCBRR_115200BPS_E3_SSCG + b 2f +5: + mov w1, #SCBRR_115200BPS + b 2f +4: + mov w1, #SCBRR_115200BPSON + b 2f +3: + mov w1, #SCBRR_230400BPS +2: + strb w1, [x0, SCIF_SCBRR] +#else + mov w1, #DL_INIT_DATA + strh w1, [x0, #SCIF_DL] + mov w1, #CKS_INIT_DATA + strh w1, [x0, #SCIF_CKS] +#endif + /* 1-bit interval elapsed */ + mov w1, #100 +1: + subs w1, w1, #1 + cbnz w1, 1b + /* + * Set bits RTRG[1:0], TTRG[1:0], and MCE in SCFCR + * Clear bits FRST and RFRST to 0 + */ + mov w1, #SCFCR_INIT_DATA + strh w1, [x0, #SCIF_SCFCR] + /* Set bits TE and RE in SCSCR to 1 */ + ldrh w1, [x0, #SCIF_SCSCR] + orr w1, w1, #(SCSCR_TE_EN + SCSCR_RE_EN) + strh w1, [x0, #SCIF_SCSCR] + mov x0, #1 + + ret +endfunc console_rcar_init + + /* + * int console_rcar_putc(int c, unsigned int base_addr) + * Function to output a character over the console. It + * returns the character printed on success or -1 on error. + * In : w0 - character to be printed + * x1 - pointer to console_t structure + * Out : return -1 on error else return character. + * Clobber list : x2 + */ +func console_rcar_putc + ldr x1, =SCIF_BASE + cmp w0, #0xA + /* Prepend '\r' to '\n' */ + bne 2f +1: + /* Check if the transmit FIFO is full */ + ldrh w2, [x1, #SCIF_SCFDR] + ubfx w2, w2, #8, #5 + cmp w2, #16 + bcs 1b + mov w2, #0x0D + strb w2, [x1, #SCIF_SCFTDR] +2: + /* Check if the transmit FIFO is full */ + ldrh w2, [x1, #SCIF_SCFDR] + ubfx w2, w2, #8, #5 + cmp w2, #16 + bcs 2b + strb w0, [x1, #SCIF_SCFTDR] + + /* Clear TEND flag */ + ldrh w2, [x1, #SCIF_SCFSR] + and w2, w2, #~SCFSR_TEND_MASK + strh w2, [x1, #SCIF_SCFSR] + + ret +endfunc console_rcar_putc + + /* + * void console_rcar_flush(void) + * Function to force a write of all buffered + * data that hasn't been output. It returns void + * Clobber list : x0, x1 + */ +func console_rcar_flush + ldr x0, =SCIF_BASE +1: + /* Check TEND flag */ + ldrh w1, [x0, #SCIF_SCFSR] + and w1, w1, #SCFSR_TEND_MASK + cmp w1, #SCFSR_TEND_TRANS_END + bne 1b + + ldr x0, =SCIF_BASE + ldrh w1, [x0, #SCIF_SCSCR] + and w1, w1, #~(SCSCR_TE_EN + SCSCR_RE_EN) + strh w1, [x0, #SCIF_SCSCR] + + ret +endfunc console_rcar_flush diff --git a/drivers/renesas/rcar/console/rcar_console.S b/drivers/renesas/rcar/console/rcar_console.S deleted file mode 100644 index 29baa67a4..000000000 --- a/drivers/renesas/rcar/console/rcar_console.S +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2018-2019, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include -#include - - .globl console_rcar_register - .globl console_rcar_init - .globl console_rcar_putc - .globl console_rcar_flush - - .extern rcar_log_init - .extern rcar_set_log_data - - /* ----------------------------------------------- - * int console_rcar_register( - * uintptr_t base, uint32_t clk, uint32_t baud, - * console_t *console) - * Function to initialize and register a new rcar - * console. Storage passed in for the console struct - * *must* be persistent (i.e. not from the stack). - * In: x0 - UART register base address - * w1 - UART clock in Hz - * w2 - Baud rate - * x3 - pointer to empty console_t struct - * Out: return 1 on success, 0 on error - * Clobber list : x0, x1, x2, x6, x7, x14 - * ----------------------------------------------- - */ -func console_rcar_register - mov x7, x30 - mov x6, x3 - cbz x6, register_fail - str x0, [x6, #CONSOLE_T_BASE] - - bl rcar_log_init - cbz x0, register_fail - - mov x0, x6 - mov x30, x7 - finish_console_register rcar, putc=1, getc=0, flush=1 - -register_fail: - ret x7 -endfunc console_rcar_register - - /* --------------------------------------------- - * int console_rcar_init(unsigned long base_addr, - * unsigned int uart_clk, unsigned int baud_rate) - * Function to initialize the console without a - * C Runtime to print debug information. This - * function will be accessed by crash reporting. - * In: x0 - console base address - * w1 - Uart clock in Hz - * w2 - Baud rate - * Out: return 1 on success - * Clobber list : x1, x2 - * --------------------------------------------- - */ -func console_rcar_init - mov w0, #0 - ret -endfunc console_rcar_init - - /* -------------------------------------------------------- - * int console_rcar_putc(int c, console_t *console) - * Function to output a character over the console. It - * returns the character printed on success or -1 on error. - * In : w0 - character to be printed - * x1 - pointer to console_t structure - * Out : return -1 on error else return character. - * Clobber list : x2 - * -------------------------------------------------------- - */ -func console_rcar_putc - b rcar_set_log_data -endfunc console_rcar_putc - - /* --------------------------------------------- - * void console_rcar_flush(void) - * Function to force a write of all buffered - * data that hasn't been output. It returns void - * Clobber list : x0, x1 - * --------------------------------------------- - */ -func console_rcar_flush - ret -endfunc console_rcar_flush diff --git a/drivers/renesas/rcar/console/rcar_printf.c b/drivers/renesas/rcar/console/rcar_printf.c deleted file mode 100644 index ad074fe05..000000000 --- a/drivers/renesas/rcar/console/rcar_printf.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include - -#include - -#include -#include -#include - -#include "rcar_def.h" -#include "rcar_private.h" -#include "rcar_printf.h" - -#define INDEX_TIMER_COUNT (4U) - -#define RCAR_LOG_HEAD (('T' << 0) | ('L' << 8) | ('O' << 16) | ('G' << 24)) - -/* - * The log is initialized and used before BL31 xlat tables are initialized, - * therefore the log memory is a device memory at that point. Make sure the - * memory is correclty aligned and accessed only with up-to 32bit, aligned, - * writes. - */ -CASSERT((RCAR_BL31_LOG_BASE & 0x7) == 0, assert_bl31_log_base_unaligned); -CASSERT((RCAR_BL31_LOG_MAX & 0x7) == 0, assert_bl31_log_max_unaligned); - -extern RCAR_INSTANTIATE_LOCK typedef struct log_head { - uint32_t head; - uint32_t index; - uint32_t size; - uint32_t res; -} loghead_t; - -typedef struct log_map { - loghead_t header; - uint8_t log_data[RCAR_BL31_LOG_MAX]; - uint8_t res_data[RCAR_LOG_RES_SIZE]; -} logmap_t; - -int32_t rcar_set_log_data(int32_t c) -{ - logmap_t *t_log; - - t_log = (logmap_t *) RCAR_BL31_LOG_BASE; - - rcar_lock_get(); - - /* - * If index is broken, then index and size initialize - */ - if (t_log->header.index >= (uint32_t) RCAR_BL31_LOG_MAX) { - t_log->header.index = 0U; - t_log->header.size = 0U; - } - /* - * data store to log area then index and size renewal - */ - t_log->log_data[t_log->header.index] = (uint8_t) c; - t_log->header.index++; - if (t_log->header.size < t_log->header.index) { - t_log->header.size = t_log->header.index; - } - if (t_log->header.index >= (uint32_t) RCAR_BL31_LOG_MAX) { - t_log->header.index = 0U; - } - - rcar_lock_release(); - - return 1; -} - -int32_t rcar_log_init(void) -{ - logmap_t *t_log = (logmap_t *)RCAR_BL31_LOG_BASE; - uint32_t *log_data = (uint32_t *)t_log->log_data; - int16_t init_flag = 0; - int i; - - if (t_log->header.head != RCAR_LOG_HEAD) { - /* - * Log header is not "TLOG", then log area initialize - */ - init_flag = 1; - } - if (t_log->header.index >= (uint32_t) RCAR_BL31_LOG_MAX) { - /* - * index is broken, then log area initialize - */ - init_flag = 1; - } - if (init_flag == 1) { - for (i = 0; i < RCAR_BL31_LOG_MAX; i += 4) - *log_data++ = 0; - - t_log->header.head = RCAR_LOG_HEAD; - t_log->header.index = 0U; - t_log->header.size = 0U; - } - rcar_lock_init(); - - return 1; -} diff --git a/drivers/renesas/rcar/console/rcar_printf.h b/drivers/renesas/rcar/console/rcar_printf.h deleted file mode 100644 index 5da70e636..000000000 --- a/drivers/renesas/rcar/console/rcar_printf.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef RCAR_PRINTF_H -#define RCAR_PRINTF_H - -#include - -int32_t rcar_set_log_data(int32_t c); -int32_t rcar_log_init(void); - -#endif /* RCAR_PRINTF_H */ diff --git a/drivers/renesas/rcar/scif/scif.S b/drivers/renesas/rcar/scif/scif.S deleted file mode 100644 index beb8dd838..000000000 --- a/drivers/renesas/rcar/scif/scif.S +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include -#include - -#define SCIF_INTERNAL_CLK 0 -#define SCIF_EXTARNAL_CLK 1 -#define SCIF_CLK SCIF_INTERNAL_CLK - -/* product register */ -#define PRR (0xFFF00044) -#define PRR_PRODUCT_MASK (0x00007F00) -#define PRR_CUT_MASK (0x000000FF) -#define PRR_PRODUCT_H3_VER_10 (0x00004F00) -#define PRR_PRODUCT_E3 (0x00005700) -#define PRR_PRODUCT_D3 (0x00005800) - -/* module stop */ -#define CPG_BASE (0xE6150000) -#define CPG_SMSTPCR2 (0x0138) -#define CPG_SMSTPCR3 (0x013C) -#define CPG_MSTPSR2 (0x0040) -#define CPG_MSTPSR3 (0x0048) -#define MSTP207 (1 << 7) -#define MSTP310 (1 << 10) -#define CPG_CPGWPR (0x0900) - -/* scif */ -#define SCIF0_BASE (0xE6E60000) -#define SCIF2_BASE (0xE6E88000) -#define SCIF_SCSMR (0x00) -#define SCIF_SCBRR (0x04) -#define SCIF_SCSCR (0x08) -#define SCIF_SCFTDR (0x0C) -#define SCIF_SCFSR (0x10) -#define SCIF_SCFRDR (0x14) -#define SCIF_SCFCR (0x18) -#define SCIF_SCFDR (0x1C) -#define SCIF_SCSPTR (0x20) -#define SCIF_SCLSR (0x24) -#define SCIF_DL (0x30) -#define SCIF_CKS (0x34) - -#if RCAR_LSI == RCAR_V3M -#define SCIF_BASE SCIF0_BASE -#define CPG_SMSTPCR CPG_SMSTPCR2 -#define CPG_MSTPSR CPG_MSTPSR2 -#define MSTP MSTP207 -#else -#define SCIF_BASE SCIF2_BASE -#define CPG_SMSTPCR CPG_SMSTPCR3 -#define CPG_MSTPSR CPG_MSTPSR3 -#define MSTP MSTP310 -#endif - -/* mode pin */ -#define RST_MODEMR (0xE6160060) -#define MODEMR_MD12 (0x00001000) - -#define SCSMR_CA_MASK (1 << 7) -#define SCSMR_CA_ASYNC (0x0000) -#define SCSMR_CHR_MASK (1 << 6) -#define SCSMR_CHR_8 (0x0000) -#define SCSMR_PE_MASK (1 << 5) -#define SCSMR_PE_DIS (0x0000) -#define SCSMR_STOP_MASK (1 << 3) -#define SCSMR_STOP_1 (0x0000) -#define SCSMR_CKS_MASK (3 << 0) -#define SCSMR_CKS_DIV1 (0x0000) -#define SCSMR_INIT_DATA (SCSMR_CA_ASYNC + \ - SCSMR_CHR_8 + \ - SCSMR_PE_DIS + \ - SCSMR_STOP_1 + \ - SCSMR_CKS_DIV1) -#define SCBRR_115200BPS (17) -#define SCBRR_115200BPSON (16) -#define SCBRR_115200BPS_E3_SSCG (15) -#define SCBRR_230400BPS (8) - -#define SCSCR_TE_MASK (1 << 5) -#define SCSCR_TE_DIS (0x0000) -#define SCSCR_TE_EN (0x0020) -#define SCSCR_RE_MASK (1 << 4) -#define SCSCR_RE_DIS (0x0000) -#define SCSCR_RE_EN (0x0010) -#define SCSCR_CKE_MASK (3 << 0) -#define SCSCR_CKE_INT (0x0000) -#define SCSCR_CKE_BRG (0x0002) -#if SCIF_CLK == SCIF_EXTARNAL_CLK -#define SCSCR_CKE_INT_CLK (SCSCR_CKE_BRG) -#else -#define SCFSR_TEND_MASK (1 << 6) -#define SCFSR_TEND_TRANS_END (0x0040) -#define SCSCR_CKE_INT_CLK (SCSCR_CKE_INT) -#endif -#define SCFSR_INIT_DATA (0x0000) -#define SCFCR_TTRG_MASK (3 << 4) -#define SCFCR_TTRG_8 (0x0000) -#define SCFCR_TTRG_0 (0x0030) -#define SCFCR_TFRST_MASK (1 << 2) -#define SCFCR_TFRST_DIS (0x0000) -#define SCFCR_TFRST_EN (0x0004) -#define SCFCR_RFRS_MASK (1 << 1) -#define SCFCR_RFRS_DIS (0x0000) -#define SCFCR_RFRS_EN (0x0002) -#define SCFCR_INIT_DATA (SCFCR_TTRG_8) -#define SCFDR_T_MASK (0x1f << 8) -#define DL_INIT_DATA (8) -#define CKS_CKS_DIV_MASK (1 << 15) -#define CKS_CKS_DIV_CLK (0x0000) -#define CKS_XIN_MASK (1 << 14) -#define CKS_XIN_SCIF_CLK (0x0000) -#define CKS_INIT_DATA (CKS_CKS_DIV_CLK + CKS_XIN_SCIF_CLK) - - .globl console_rcar_register - .globl console_rcar_init - .globl console_rcar_putc - .globl console_rcar_flush - - /* - * ----------------------------------------------- - * int console_rcar_register( - * uintptr_t base, uint32_t clk, uint32_t baud, - * console_t *console) - * Function to initialize and register a new rcar - * console. Storage passed in for the console struct - * *must* be persistent (i.e. not from the stack). - * In: x0 - UART register base address - * w1 - UART clock in Hz - * w2 - Baud rate - * x3 - pointer to empty console_t struct - * Out: return 1 on success, 0 on error - * Clobber list : x0, x1, x2, x6, x7, x14 - * ----------------------------------------------- - */ -func console_rcar_register - mov x7, x30 - mov x6, x3 - cbz x6, register_fail - str x0, [x6, #CONSOLE_T_BASE] - - bl console_rcar_init - - mov x0, x6 - mov x30, x7 - finish_console_register rcar, putc=1, getc=0, flush=1 - -register_fail: - ret x7 -endfunc console_rcar_register - - /* - * int console_rcar_init(unsigned long base_addr, - * unsigned int uart_clk, unsigned int baud_rate) - * Function to initialize the console without a - * C Runtime to print debug information. This - * function will be accessed by console_rcar_register - * and crash reporting. - * In: x0 - console base address - * w1 - Uart clock in Hz - * w2 - Baud rate - * Out: return 1 on success - * Clobber list : x1, x2 - */ -func console_rcar_init - ldr x0, =CPG_BASE - ldr w1, [x0, #CPG_SMSTPCR] - and w1, w1, #~MSTP - mvn w2, w1 - str w2, [x0, #CPG_CPGWPR] - str w1, [x0, #CPG_SMSTPCR] -5: - ldr w1, [x0, #CPG_MSTPSR] - and w1, w1, #MSTP - cbnz w1, 5b - - ldr x0, =SCIF_BASE - /* Clear bits TE and RE in SCSCR to 0 */ - mov w1, #(SCSCR_TE_DIS + SCSCR_RE_DIS) - strh w1, [x0, #SCIF_SCSCR] - /* Set bits TFRST and RFRST in SCFCR to 1 */ - ldrh w1, [x0, #SCIF_SCFCR] - orr w1, w1, #(SCFCR_TFRST_EN + SCFCR_RFRS_EN) - strh w1, [x0, #SCIF_SCFCR] - /* - * Read flags of ER, DR, BRK, and RDF in SCFSR and those of TO and ORER - * in SCLSR, then clear them to 0 - */ - mov w1, #SCFSR_INIT_DATA - strh w1, [x0, #SCIF_SCFSR] - mov w1, #0 - strh w1, [x0, #SCIF_SCLSR] - /* Set bits CKE[1:0] in SCSCR */ - ldrh w1, [x0, #SCIF_SCSCR] - and w1, w1, #~SCSCR_CKE_MASK - mov w2, #SCSCR_CKE_INT_CLK - orr w1, w1, w2 - strh w1, [x0, #SCIF_SCSCR] - /* Set data transfer format in SCSMR */ - mov w1, #SCSMR_INIT_DATA - strh w1, [x0, #SCIF_SCSMR] - /* Set value in SCBRR */ -#if SCIF_CLK == SCIF_INTERNAL_CLK - ldr x1, =PRR - ldr w1, [x1] - and w1, w1, #(PRR_PRODUCT_MASK | PRR_CUT_MASK) - mov w2, #PRR_PRODUCT_H3_VER_10 - cmp w1, w2 - beq 3f - and w1, w1, #PRR_PRODUCT_MASK - mov w2, #PRR_PRODUCT_D3 - cmp w1, w2 - beq 4f - and w1, w1, #PRR_PRODUCT_MASK - mov w2, #PRR_PRODUCT_E3 - cmp w1, w2 - bne 5f - - ldr x1, =RST_MODEMR - ldr w1, [x1] - and w1, w1, #MODEMR_MD12 - mov w2, #MODEMR_MD12 - cmp w1, w2 - bne 5f - - mov w1, #SCBRR_115200BPS_E3_SSCG - b 2f -5: - mov w1, #SCBRR_115200BPS - b 2f -4: - mov w1, #SCBRR_115200BPSON - b 2f -3: - mov w1, #SCBRR_230400BPS -2: - strb w1, [x0, SCIF_SCBRR] -#else - mov w1, #DL_INIT_DATA - strh w1, [x0, #SCIF_DL] - mov w1, #CKS_INIT_DATA - strh w1, [x0, #SCIF_CKS] -#endif - /* 1-bit interval elapsed */ - mov w1, #100 -1: - subs w1, w1, #1 - cbnz w1, 1b - /* - * Set bits RTRG[1:0], TTRG[1:0], and MCE in SCFCR - * Clear bits FRST and RFRST to 0 - */ - mov w1, #SCFCR_INIT_DATA - strh w1, [x0, #SCIF_SCFCR] - /* Set bits TE and RE in SCSCR to 1 */ - ldrh w1, [x0, #SCIF_SCSCR] - orr w1, w1, #(SCSCR_TE_EN + SCSCR_RE_EN) - strh w1, [x0, #SCIF_SCSCR] - mov x0, #1 - - ret -endfunc console_rcar_init - - /* - * int console_rcar_putc(int c, unsigned int base_addr) - * Function to output a character over the console. It - * returns the character printed on success or -1 on error. - * In : w0 - character to be printed - * x1 - pointer to console_t structure - * Out : return -1 on error else return character. - * Clobber list : x2 - */ -func console_rcar_putc - ldr x1, =SCIF_BASE - cmp w0, #0xA - /* Prepend '\r' to '\n' */ - bne 2f -1: - /* Check if the transmit FIFO is full */ - ldrh w2, [x1, #SCIF_SCFDR] - ubfx w2, w2, #8, #5 - cmp w2, #16 - bcs 1b - mov w2, #0x0D - strb w2, [x1, #SCIF_SCFTDR] -2: - /* Check if the transmit FIFO is full */ - ldrh w2, [x1, #SCIF_SCFDR] - ubfx w2, w2, #8, #5 - cmp w2, #16 - bcs 2b - strb w0, [x1, #SCIF_SCFTDR] - - /* Clear TEND flag */ - ldrh w2, [x1, #SCIF_SCFSR] - and w2, w2, #~SCFSR_TEND_MASK - strh w2, [x1, #SCIF_SCFSR] - - ret -endfunc console_rcar_putc - - /* - * void console_rcar_flush(void) - * Function to force a write of all buffered - * data that hasn't been output. It returns void - * Clobber list : x0, x1 - */ -func console_rcar_flush - ldr x0, =SCIF_BASE -1: - /* Check TEND flag */ - ldrh w1, [x0, #SCIF_SCFSR] - and w1, w1, #SCFSR_TEND_MASK - cmp w1, #SCFSR_TEND_TRANS_END - bne 1b - - ldr x0, =SCIF_BASE - ldrh w1, [x0, #SCIF_SCSCR] - and w1, w1, #~(SCSCR_TE_EN + SCSCR_RE_EN) - strh w1, [x0, #SCIF_SCSCR] - - ret -endfunc console_rcar_flush diff --git a/plat/renesas/common/common.mk b/plat/renesas/common/common.mk index 6e8786d66..cdcbc2144 100644 --- a/plat/renesas/common/common.mk +++ b/plat/renesas/common/common.mk @@ -78,6 +78,8 @@ BL2_SOURCES += ${RCAR_GIC_SOURCES} \ lib/cpus/aarch64/cortex_a57.S \ ${LIBFDT_SRCS} \ common/desc_image_load.c \ + drivers/renesas/common/console/rcar_printf.c \ + drivers/renesas/common/scif/scif.S \ drivers/renesas/common/common.c \ drivers/renesas/common/io/io_emmcdrv.c \ drivers/renesas/common/io/io_memdrv.c \ @@ -94,6 +96,8 @@ BL31_SOURCES += ${RCAR_GIC_SOURCES} \ lib/cpus/aarch64/cortex_a53.S \ lib/cpus/aarch64/cortex_a57.S \ plat/common/plat_psci_common.c \ + drivers/renesas/common/console/rcar_console.S \ + drivers/renesas/common/console/rcar_printf.c \ drivers/renesas/common/pwrc/call_sram.S \ drivers/renesas/common/pwrc/pwrc.c \ drivers/renesas/common/common.c \ diff --git a/plat/renesas/rcar/platform.mk b/plat/renesas/rcar/platform.mk index 6685a8115..05f9c2d26 100644 --- a/plat/renesas/rcar/platform.mk +++ b/plat/renesas/rcar/platform.mk @@ -306,7 +306,7 @@ PLAT_INCLUDES += -Idrivers/renesas/rcar/ddr \ -Idrivers/renesas/rcar/avs \ -Idrivers/renesas/rcar/delay \ -Idrivers/renesas/rcar/rom \ - -Idrivers/renesas/rcar/scif \ + -Idrivers/renesas/common/scif \ -Idrivers/renesas/common/emmc \ -Idrivers/renesas/common/pwrc \ -Idrivers/renesas/common/io @@ -320,8 +320,6 @@ BL2_SOURCES += plat/renesas/rcar/aarch64/platform_common.c \ plat/renesas/rcar/bl2_plat_mem_params_desc.c \ plat/renesas/rcar/plat_image_load.c \ plat/renesas/rcar/bl2_cpg_init.c \ - drivers/renesas/rcar/console/rcar_printf.c \ - drivers/renesas/rcar/scif/scif.S \ drivers/renesas/rcar/auth/auth_mod.c \ drivers/renesas/rcar/rpc/rpc_driver.c \ drivers/renesas/rcar/dma/dma_driver.c \ @@ -336,8 +334,6 @@ BL31_SOURCES += plat/renesas/rcar/plat_topology.c \ plat/renesas/rcar/aarch64/platform_common.c \ plat/renesas/rcar/bl31_plat_setup.c \ plat/renesas/rcar/plat_pm.c \ - drivers/renesas/rcar/console/rcar_console.S \ - drivers/renesas/rcar/console/rcar_printf.c \ drivers/renesas/rcar/delay/micro_delay.c ifeq (${RCAR_GEN3_ULCB},1) -- cgit v1.2.3 From f020963999b8ffed8f2760d9f358acebbb14ab2f Mon Sep 17 00:00:00 2001 From: Biju Das Date: Sun, 13 Dec 2020 20:49:27 +0000 Subject: plat: renesas: rcar: include: Code cleanup This patch fixes checkpatch warnings and replaces TAB with space after #define macros. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: I11f65d494997cbf612376fb120c27ef0166cdd3a --- plat/renesas/rcar/include/platform_def.h | 42 ++-- plat/renesas/rcar/include/rcar_def.h | 208 ++++++++-------- plat/renesas/rcar/include/rcar_private.h | 19 +- .../rcar/include/registers/lifec_registers.h | 262 ++++++++++----------- 4 files changed, 270 insertions(+), 261 deletions(-) diff --git a/plat/renesas/rcar/include/platform_def.h b/plat/renesas/rcar/include/platform_def.h index b7f0ca113..73787140b 100644 --- a/plat/renesas/rcar/include/platform_def.h +++ b/plat/renesas/rcar/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -29,20 +29,20 @@ /* Size of cacheable stacks */ #if IMAGE_BL1 #if TRUSTED_BOARD_BOOT -#define PLATFORM_STACK_SIZE U(0x1000) +#define PLATFORM_STACK_SIZE U(0x1000) #else -#define PLATFORM_STACK_SIZE U(0x440) +#define PLATFORM_STACK_SIZE U(0x440) #endif #elif IMAGE_BL2 #if TRUSTED_BOARD_BOOT -#define PLATFORM_STACK_SIZE U(0x1000) +#define PLATFORM_STACK_SIZE U(0x1000) #else -#define PLATFORM_STACK_SIZE U(0x400) +#define PLATFORM_STACK_SIZE U(0x400) #endif #elif IMAGE_BL31 -#define PLATFORM_STACK_SIZE U(0x400) +#define PLATFORM_STACK_SIZE U(0x400) #elif IMAGE_BL32 -#define PLATFORM_STACK_SIZE U(0x440) +#define PLATFORM_STACK_SIZE U(0x440) #endif #define BL332_IMAGE_ID (NS_BL2U_IMAGE_ID + 1) @@ -97,11 +97,13 @@ #define MAX_IO_DEVICES U(3) #define MAX_IO_HANDLES U(4) -/******************************************************************************* +/* + ****************************************************************************** * BL2 specific defines. - ******************************************************************************/ -/* Put BL2 just below BL3-1. BL2_BASE is calculated using the current BL2 debug - * size plus a little space for growth. */ + ****************************************************************************** + * Put BL2 just below BL3-1. BL2_BASE is calculated using the current BL2 debug + * size plus a little space for growth. + */ #define RCAR_SYSRAM_BASE U(0xE6300000) #if (RCAR_LSI == RCAR_E3) || (RCAR_LSI == RCAR_D3) #define BL2_LIMIT U(0xE6320000) @@ -121,17 +123,19 @@ #endif #define RCAR_SYSRAM_SIZE (BL2_BASE - RCAR_SYSRAM_BASE) -/******************************************************************************* +/* + ****************************************************************************** * BL31 specific defines. - ******************************************************************************/ -/* Put BL3-1 at the top of the Trusted SRAM. BL31_BASE is calculated using the - * current BL3-1 debug size plus a little space for growth. */ + ****************************************************************************** + * Put BL3-1 at the top of the Trusted SRAM. BL31_BASE is calculated using the + * current BL3-1 debug size plus a little space for growth. + */ #define BL31_BASE (RCAR_TRUSTED_SRAM_BASE) #define BL31_LIMIT (RCAR_TRUSTED_SRAM_BASE + \ RCAR_TRUSTED_SRAM_SIZE) -#define RCAR_BL31_LOG_BASE (0x44040000) -#define RCAR_BL31_SDRAM_BTM (RCAR_BL31_LOG_BASE + 0x14000) -#define RCAR_BL31_LOG_SIZE (RCAR_BL31_SDRAM_BTM - RCAR_BL31_LOG_BASE) +#define RCAR_BL31_LOG_BASE (0x44040000) +#define RCAR_BL31_SDRAM_BTM (RCAR_BL31_LOG_BASE + 0x14000) +#define RCAR_BL31_LOG_SIZE (RCAR_BL31_SDRAM_BTM - RCAR_BL31_LOG_BASE) #define BL31_SRAM_BASE (DEVICE_SRAM_BASE) #define BL31_SRAM_LIMIT (DEVICE_SRAM_BASE + DEVICE_SRAM_SIZE) @@ -176,7 +180,7 @@ * Declarations and constants to access the mailboxes safely. Each mailbox is * 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. Such alignment ensures that two maiboxes do not sit on the same cache + * caches. Such alignment ensures that two mailboxes do not sit on the same cache * line at any cache level. They could belong to different cpus/clusters & * get written while being protected by different locks causing corruption of * a valid mailbox address. diff --git a/plat/renesas/rcar/include/rcar_def.h b/plat/renesas/rcar/include/rcar_def.h index 0ffbfe979..6c5b29561 100644 --- a/plat/renesas/rcar/include/rcar_def.h +++ b/plat/renesas/rcar/include/rcar_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -33,13 +33,13 @@ #define DRAM1_SIZE U(0x80000000) #define DRAM1_NS_BASE (DRAM1_BASE + U(0x10000000)) #define DRAM1_NS_SIZE (DRAM1_SIZE - DRAM1_NS_BASE) -#define DRAM_40BIT_BASE ULL(0x0400000000) -#define DRAM_40BIT_SIZE ULL(0x0400000000) -#define DRAM_PROTECTED_BASE ULL(0x43F00000) -#define DRAM_40BIT_PROTECTED_BASE ULL(0x0403F00000) -#define DRAM_PROTECTED_SIZE ULL(0x03F00000) -#define RCAR_BL31_CRASH_BASE U(0x4403F000) -#define RCAR_BL31_CRASH_SIZE U(0x00001000) +#define DRAM_40BIT_BASE ULL(0x0400000000) +#define DRAM_40BIT_SIZE ULL(0x0400000000) +#define DRAM_PROTECTED_BASE ULL(0x43F00000) +#define DRAM_40BIT_PROTECTED_BASE ULL(0x0403F00000) +#define DRAM_PROTECTED_SIZE ULL(0x03F00000) +#define RCAR_BL31_CRASH_BASE U(0x4403F000) +#define RCAR_BL31_CRASH_SIZE U(0x00001000) /* Entrypoint mailboxes */ #define MBOX_BASE RCAR_SHARED_MEM_BASE #define MBOX_SIZE 0x200 @@ -47,15 +47,19 @@ #define PARAMS_BASE (MBOX_BASE + MBOX_SIZE) #define BOOT_KIND_BASE (RCAR_SHARED_MEM_BASE + \ RCAR_SHARED_MEM_SIZE - 0x100) -/* The number of regions like RO(code), coherent and data required by - * different BL stages which need to be mapped in the MMU */ +/* + * The number of regions like RO(code), coherent and data required by + * different BL stages which need to be mapped in the MMU + */ #if USE_COHERENT_MEM #define RCAR_BL_REGIONS (3) #else #define RCAR_BL_REGIONS (2) #endif -/* The RCAR_MAX_MMAP_REGIONS depend on the number of entries in rcar_mmap[] - * defined for each BL stage in rcar_common.c. */ +/* + * The RCAR_MAX_MMAP_REGIONS depends on the number of entries in rcar_mmap[] + * defined for each BL stage in rcar_common.c. + */ #if IMAGE_BL2 #define RCAR_MMAP_ENTRIES (9) #endif @@ -73,24 +77,24 @@ /* BL33 */ #define NS_IMAGE_OFFSET (DRAM1_BASE + U(0x09000000)) /* BL31 */ -#define RCAR_DEVICE_BASE DEVICE_RCAR_BASE -#define RCAR_DEVICE_SIZE (0x1A000000) -#define RCAR_LOG_RES_SIZE (512/8) -#define RCAR_LOG_HEADER_SIZE (16) -#define RCAR_LOG_OTHER_SIZE (RCAR_LOG_HEADER_SIZE + \ +#define RCAR_DEVICE_BASE DEVICE_RCAR_BASE +#define RCAR_DEVICE_SIZE (0x1A000000) +#define RCAR_LOG_RES_SIZE (64) +#define RCAR_LOG_HEADER_SIZE (16) +#define RCAR_LOG_OTHER_SIZE (RCAR_LOG_HEADER_SIZE + \ RCAR_LOG_RES_SIZE) -#define RCAR_BL31_LOG_MAX (RCAR_BL31_LOG_SIZE - \ +#define RCAR_BL31_LOG_MAX (RCAR_BL31_LOG_SIZE - \ RCAR_LOG_OTHER_SIZE) -#define RCAR_CRASH_STACK RCAR_BL31_CRASH_BASE -#define AARCH64_SPACE_BASE ULL(0x00000000000) -#define AARCH64_SPACE_SIZE ULL(0x10000000000) +#define RCAR_CRASH_STACK RCAR_BL31_CRASH_BASE +#define AARCH64_SPACE_BASE ULL(0x00000000000) +#define AARCH64_SPACE_SIZE ULL(0x10000000000) /* CCI related constants */ #define CCI500_BASE U(0xF1200000) #define CCI500_CLUSTER0_SL_IFACE_IX (2) #define CCI500_CLUSTER1_SL_IFACE_IX (3) #define CCI500_CLUSTER0_SL_IFACE_IX_FOR_M3 (1) #define CCI500_CLUSTER1_SL_IFACE_IX_FOR_M3 (2) -#define RCAR_CCI_BASE CCI500_BASE +#define RCAR_CCI_BASE CCI500_BASE /* GIC */ #define RCAR_GICD_BASE U(0xF1010000) #define RCAR_GICR_BASE U(0xF1010000) @@ -106,47 +110,47 @@ #define ARM_IRQ_SEC_SGI_5 U(13) #define ARM_IRQ_SEC_SGI_6 U(14) #define ARM_IRQ_SEC_SGI_7 U(15) -#define ARM_IRQ_SEC_RPC U(70) -#define ARM_IRQ_SEC_TIMER U(166) -#define ARM_IRQ_SEC_TIMER_UP U(171) -#define ARM_IRQ_SEC_WDT U(173) -#define ARM_IRQ_SEC_CRYPT U(102) -#define ARM_IRQ_SEC_CRYPT_SecPKA U(97) -#define ARM_IRQ_SEC_CRYPT_PubPKA U(98) +#define ARM_IRQ_SEC_RPC U(70) +#define ARM_IRQ_SEC_TIMER U(166) +#define ARM_IRQ_SEC_TIMER_UP U(171) +#define ARM_IRQ_SEC_WDT U(173) +#define ARM_IRQ_SEC_CRYPT U(102) +#define ARM_IRQ_SEC_CRYPT_SecPKA U(97) +#define ARM_IRQ_SEC_CRYPT_PubPKA U(98) /* Timer control */ -#define RCAR_CNTC_BASE U(0xE6080000) +#define RCAR_CNTC_BASE U(0xE6080000) /* Reset */ -#define RCAR_CPGWPR U(0xE6150900) /* CPG write protect */ -#define RCAR_MODEMR U(0xE6160060) /* Mode pin */ -#define RCAR_CA57RESCNT U(0xE6160040) /* Reset control A57 */ -#define RCAR_CA53RESCNT U(0xE6160044) /* Reset control A53 */ -#define RCAR_SRESCR U(0xE6160110) /* Soft Power On Reset */ -#define RCAR_CA53WUPCR U(0xE6151010) /* Wake-up control A53 */ -#define RCAR_CA57WUPCR U(0xE6152010) /* Wake-up control A57 */ -#define RCAR_CA53PSTR U(0xE6151040) /* Power status A53 */ -#define RCAR_CA57PSTR U(0xE6152040) /* Power status A57 */ -#define RCAR_CA53CPU0CR U(0xE6151100) /* CPU control A53 */ -#define RCAR_CA57CPU0CR U(0xE6152100) /* CPU control A57 */ -#define RCAR_CA53CPUCMCR U(0xE6151184) /* Common power A53 */ -#define RCAR_CA57CPUCMCR U(0xE6152184) /* Common power A57 */ -#define RCAR_WUPMSKCA57 U(0xE6180014) /* Wake-up mask A57 */ -#define RCAR_WUPMSKCA53 U(0xE6180018) /* Wake-up mask A53 */ +#define RCAR_CPGWPR U(0xE6150900) /* CPG write protect */ +#define RCAR_MODEMR U(0xE6160060) /* Mode pin */ +#define RCAR_CA57RESCNT U(0xE6160040) /* Reset control A57 */ +#define RCAR_CA53RESCNT U(0xE6160044) /* Reset control A53 */ +#define RCAR_SRESCR U(0xE6160110) /* Soft Power On Reset */ +#define RCAR_CA53WUPCR U(0xE6151010) /* Wake-up control A53 */ +#define RCAR_CA57WUPCR U(0xE6152010) /* Wake-up control A57 */ +#define RCAR_CA53PSTR U(0xE6151040) /* Power status A53 */ +#define RCAR_CA57PSTR U(0xE6152040) /* Power status A57 */ +#define RCAR_CA53CPU0CR U(0xE6151100) /* CPU control A53 */ +#define RCAR_CA57CPU0CR U(0xE6152100) /* CPU control A57 */ +#define RCAR_CA53CPUCMCR U(0xE6151184) /* Common power A53 */ +#define RCAR_CA57CPUCMCR U(0xE6152184) /* Common power A57 */ +#define RCAR_WUPMSKCA57 U(0xE6180014) /* Wake-up mask A57 */ +#define RCAR_WUPMSKCA53 U(0xE6180018) /* Wake-up mask A53 */ /* SYSC */ -#define RCAR_PWRSR3 U(0xE6180140) /* Power stat A53-SCU */ -#define RCAR_PWRSR5 U(0xE61801C0) /* Power stat A57-SCU */ -#define RCAR_SYSCIER U(0xE618000C) /* Interrupt enable */ -#define RCAR_SYSCIMR U(0xE6180010) /* Interrupt mask */ -#define RCAR_SYSCSR U(0xE6180000) /* SYSC status */ -#define RCAR_PWRONCR3 U(0xE618014C) /* Power resume A53-SCU */ -#define RCAR_PWRONCR5 U(0xE61801CC) /* Power resume A57-SCU */ -#define RCAR_PWROFFCR3 U(0xE6180144) /* Power shutof A53-SCU */ -#define RCAR_PWROFFCR5 U(0xE61801C4) /* Power shutof A57-SCU */ -#define RCAR_PWRER3 U(0xE6180154) /* shutoff/resume error */ -#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_PWRSR3 U(0xE6180140) /* Power stat A53-SCU */ +#define RCAR_PWRSR5 U(0xE61801C0) /* Power stat A57-SCU */ +#define RCAR_SYSCIER U(0xE618000C) /* Interrupt enable */ +#define RCAR_SYSCIMR U(0xE6180010) /* Interrupt mask */ +#define RCAR_SYSCSR U(0xE6180000) /* SYSC status */ +#define RCAR_PWRONCR3 U(0xE618014C) /* Power resume A53-SCU */ +#define RCAR_PWRONCR5 U(0xE61801CC) /* Power resume A57-SCU */ +#define RCAR_PWROFFCR3 U(0xE6180144) /* Power shutoff A53-SCU */ +#define RCAR_PWROFFCR5 U(0xE61801C4) /* Power shutoff A57-SCU */ +#define RCAR_PWRER3 U(0xE6180154) /* shutoff/resume error */ +#define RCAR_PWRER5 U(0xE61801D4) /* shutoff/resume error */ +#define RCAR_SYSCISR U(0xE6180004) /* Interrupt status */ +#define RCAR_SYSCISCR U(0xE6180008) /* Interrupt stat clear */ /* Product register */ -#define RCAR_PRR U(0xFFF00044) +#define RCAR_PRR U(0xFFF00044) #define RCAR_M3_CUT_VER11 U(0x00000010) /* M3 Ver.1.1/Ver.1.2 */ #define RCAR_MAJOR_MASK U(0x000000F0) #define RCAR_MINOR_MASK U(0x0000000F) @@ -198,39 +202,39 @@ /* Memory mapped Generic timer interfaces */ #define ARM_SYS_CNTCTL_BASE RCAR_CNTC_BASE /* MODEMR PLL masks and bitfield values */ -#define CHECK_MD13_MD14 U(0x6000) -#define MD14_MD13_TYPE_0 U(0x0000) /* MD14=0 MD13=0 */ -#define MD14_MD13_TYPE_1 U(0x2000) /* MD14=0 MD13=1 */ -#define MD14_MD13_TYPE_2 U(0x4000) /* MD14=1 MD13=0 */ -#define MD14_MD13_TYPE_3 U(0x6000) /* MD14=1 MD13=1 */ +#define CHECK_MD13_MD14 U(0x6000) +#define MD14_MD13_TYPE_0 U(0x0000) /* MD14=0 MD13=0 */ +#define MD14_MD13_TYPE_1 U(0x2000) /* MD14=0 MD13=1 */ +#define MD14_MD13_TYPE_2 U(0x4000) /* MD14=1 MD13=0 */ +#define MD14_MD13_TYPE_3 U(0x6000) /* MD14=1 MD13=1 */ /* Frequency of EXTAL(Hz) */ -#define EXTAL_MD14_MD13_TYPE_0 U(8333300) /* MD14=0 MD13=0 */ -#define EXTAL_MD14_MD13_TYPE_1 U(10000000) /* MD14=0 MD13=1 */ -#define EXTAL_MD14_MD13_TYPE_2 U(12500000) /* MD14=1 MD13=0 */ -#define EXTAL_MD14_MD13_TYPE_3 U(16666600) /* MD14=1 MD13=1 */ -#define EXTAL_SALVATOR_XS U(8320000) /* Salvator-XS */ +#define EXTAL_MD14_MD13_TYPE_0 U(8333300) /* MD14=0 MD13=0 */ +#define EXTAL_MD14_MD13_TYPE_1 U(10000000) /* MD14=0 MD13=1 */ +#define EXTAL_MD14_MD13_TYPE_2 U(12500000) /* MD14=1 MD13=0 */ +#define EXTAL_MD14_MD13_TYPE_3 U(16666600) /* MD14=1 MD13=1 */ +#define EXTAL_SALVATOR_XS U(8320000) /* Salvator-XS */ #define EXTAL_EBISU U(24000000) /* Ebisu */ #define EXTAL_DRAAK U(24000000) /* Draak */ -/* CPG write protect registers */ -#define CPGWPR_PASSWORD (0x5A5AFFFFU) -#define CPGWPCR_PASSWORD (0xA5A50000U) +/* CPG write protect registers */ +#define CPGWPR_PASSWORD (0x5A5AFFFFU) +#define CPGWPCR_PASSWORD (0xA5A50000U) /* CA5x Debug Resource control registers */ -#define CPG_CA57DBGRCR (CPG_BASE + 0x2180U) -#define CPG_CA53DBGRCR (CPG_BASE + 0x1180U) -#define DBGCPUPREN ((uint32_t)1U << 19U) -#define CPG_PLL0CR (CPG_BASE + 0x00D8U) -#define CPG_PLL2CR (CPG_BASE + 0x002CU) -#define CPG_PLL4CR (CPG_BASE + 0x01F4U) +#define CPG_CA57DBGRCR (CPG_BASE + 0x2180U) +#define CPG_CA53DBGRCR (CPG_BASE + 0x1180U) +#define DBGCPUPREN ((uint32_t)1U << 19U) +#define CPG_PLL0CR (CPG_BASE + 0x00D8U) +#define CPG_PLL2CR (CPG_BASE + 0x002CU) +#define CPG_PLL4CR (CPG_BASE + 0x01F4U) #define CPG_CPGWPCR (CPG_BASE + 0x0904U) /* RST Registers */ -#define RST_BASE (0xE6160000U) -#define RST_WDTRSTCR (RST_BASE + 0x0054U) +#define RST_BASE (0xE6160000U) +#define RST_WDTRSTCR (RST_BASE + 0x0054U) #define RST_MODEMR (RST_BASE + 0x0060U) -#define WDTRSTCR_PASSWORD (0xA55A0000U) -#define WDTRSTCR_RWDT_RSTMSK ((uint32_t)1U << 0U) +#define WDTRSTCR_PASSWORD (0xA55A0000U) +#define WDTRSTCR_RWDT_RSTMSK ((uint32_t)1U << 0U) /* MFIS Registers */ -#define MFISWPCNTR_PASSWORD (0xACCE0000U) -#define MFISWPCNTR (0xE6260900U) +#define MFISWPCNTR_PASSWORD (0xACCE0000U) +#define MFISWPCNTR (0xE6260900U) /* IPMMU registers */ #define IPMMU_MM_BASE (0xE67B0000U) #define IPMMUMM_IMSCTLR (IPMMU_MM_BASE + 0x0500U) @@ -263,8 +267,8 @@ #define IPMMU_DS1_BASE (0xE7740000U) #define IPMMUDS1_IMSCTLR (IPMMU_DS1_BASE + 0x0500U) /* ARMREG registers */ -#define P_ARMREG_SEC_CTRL (0xE62711F0U) -#define P_ARMREG_SEC_CTRL_PROT (0x00000001U) +#define P_ARMREG_SEC_CTRL (0xE62711F0U) +#define P_ARMREG_SEC_CTRL_PROT (0x00000001U) /* MIDR */ #define MIDR_CA57 (0x0D07U << MIDR_PN_SHIFT) #define MIDR_CA53 (0x0D03U << MIDR_PN_SHIFT) @@ -279,28 +283,28 @@ #define RCAR_COLD_BOOT (0x00U) #define RCAR_WARM_BOOT (0x01U) #if PMIC_ROHM_BD9571 && RCAR_SYSTEM_RESET_KEEPON_DDR -#define KEEP10_MAGIC (0x55U) +#define KEEP10_MAGIC (0x55U) #endif /* lossy registers */ -#define LOSSY_PARAMS_BASE (0x47FD7000U) -#define AXI_DCMPAREACRA0 (0xE6784100U) -#define AXI_DCMPAREACRB0 (0xE6784104U) +#define LOSSY_PARAMS_BASE (0x47FD7000U) +#define AXI_DCMPAREACRA0 (0xE6784100U) +#define AXI_DCMPAREACRB0 (0xE6784104U) #define LOSSY_ENABLE (0x80000000U) #define LOSSY_DISABLE (0x00000000U) #define LOSSY_FMT_YUVPLANAR (0x00000000U) #define LOSSY_FMT_YUV422INTLV (0x20000000U) #define LOSSY_FMT_ARGB8888 (0x40000000U) -#define LOSSY_ST_ADDR0 (0x54000000U) -#define LOSSY_END_ADDR0 (0x57000000U) -#define LOSSY_FMT0 LOSSY_FMT_YUVPLANAR -#define LOSSY_ENA_DIS0 LOSSY_ENABLE -#define LOSSY_ST_ADDR1 0x0U -#define LOSSY_END_ADDR1 0x0U -#define LOSSY_FMT1 LOSSY_FMT_ARGB8888 -#define LOSSY_ENA_DIS1 LOSSY_DISABLE -#define LOSSY_ST_ADDR2 0x0U -#define LOSSY_END_ADDR2 0x0U -#define LOSSY_FMT2 LOSSY_FMT_YUV422INTLV -#define LOSSY_ENA_DIS2 LOSSY_DISABLE +#define LOSSY_ST_ADDR0 (0x54000000U) +#define LOSSY_END_ADDR0 (0x57000000U) +#define LOSSY_FMT0 LOSSY_FMT_YUVPLANAR +#define LOSSY_ENA_DIS0 LOSSY_ENABLE +#define LOSSY_ST_ADDR1 0x0U +#define LOSSY_END_ADDR1 0x0U +#define LOSSY_FMT1 LOSSY_FMT_ARGB8888 +#define LOSSY_ENA_DIS1 LOSSY_DISABLE +#define LOSSY_ST_ADDR2 0x0U +#define LOSSY_END_ADDR2 0x0U +#define LOSSY_FMT2 LOSSY_FMT_YUV422INTLV +#define LOSSY_ENA_DIS2 LOSSY_DISABLE #endif /* RCAR_DEF_H */ diff --git a/plat/renesas/rcar/include/rcar_private.h b/plat/renesas/rcar/include/rcar_private.h index a76c0238b..36f4ca540 100644 --- a/plat/renesas/rcar/include/rcar_private.h +++ b/plat/renesas/rcar/include/rcar_private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,12 +7,12 @@ #ifndef RCAR_PRIVATE_H #define RCAR_PRIVATE_H -#include - #include #include #include +#include + typedef volatile struct mailbox { unsigned long value __aligned(CACHE_WRITEBACK_GRANULE); } mailbox_t; @@ -62,17 +62,18 @@ typedef struct rcar_cpu_data { */ #define rcar_lock_init(_lock_arg) -#define rcar_lock_get(_lock_arg) \ - bakery_lock_get(_lock_arg, \ +#define rcar_lock_get(_lock_arg) \ + bakery_lock_get(_lock_arg, \ CPU_DATA_PLAT_PCPU_OFFSET + RCAR_CPU_DATA_LOCK_OFFSET) #define rcar_lock_release(_lock_arg) \ - bakery_lock_release(_lock_arg, \ + bakery_lock_release(_lock_arg, \ CPU_DATA_PLAT_PCPU_OFFSET + RCAR_CPU_DATA_LOCK_OFFSET) -/* Ensure that the size of the RCAR specific per-cpu data structure and the size +/* + * Ensure that the size of the RCAR specific per-cpu data structure and the size * of the memory allocated in generic per-cpu data for the platform are the same */ -CASSERT(PLAT_PCPU_DATA_SIZE == sizeof(rcar_cpu_data_t), +CASSERT(sizeof(rcar_cpu_data_t) == PLAT_PCPU_DATA_SIZE, rcar_pcpu_data_size_mismatch); #endif /* @@ -84,7 +85,7 @@ void rcar_configure_mmu_el3(unsigned long total_base, #if USE_COHERENT_MEM , unsigned long coh_start, unsigned long coh_limit #endif - ); + ); void rcar_setup_topology(void); void rcar_cci_disable(void); diff --git a/plat/renesas/rcar/include/registers/lifec_registers.h b/plat/renesas/rcar/include/registers/lifec_registers.h index de78760ae..5f49e52c0 100644 --- a/plat/renesas/rcar/include/registers/lifec_registers.h +++ b/plat/renesas/rcar/include/registers/lifec_registers.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,138 +7,138 @@ #ifndef LIFEC_REGISTERS_H #define LIFEC_REGISTERS_H -#define LIFEC_SEC_BASE (0xE6110000U) +#define LIFEC_SEC_BASE (0xE6110000U) -#define SEC_SRC (LIFEC_SEC_BASE + 0x0008U) -#define SEC_SEL0 (LIFEC_SEC_BASE + 0x0030U) -#define SEC_SEL1 (LIFEC_SEC_BASE + 0x0034U) -#define SEC_SEL2 (LIFEC_SEC_BASE + 0x0038U) -#define SEC_SEL3 (LIFEC_SEC_BASE + 0x003CU) -#define SEC_SEL4 (LIFEC_SEC_BASE + 0x0058U) -#define SEC_SEL5 (LIFEC_SEC_BASE + 0x005CU) +#define SEC_SRC (LIFEC_SEC_BASE + 0x0008U) +#define SEC_SEL0 (LIFEC_SEC_BASE + 0x0030U) +#define SEC_SEL1 (LIFEC_SEC_BASE + 0x0034U) +#define SEC_SEL2 (LIFEC_SEC_BASE + 0x0038U) +#define SEC_SEL3 (LIFEC_SEC_BASE + 0x003CU) +#define SEC_SEL4 (LIFEC_SEC_BASE + 0x0058U) +#define SEC_SEL5 (LIFEC_SEC_BASE + 0x005CU) #define SEC_SEL6 (LIFEC_SEC_BASE + 0x0060U) -#define SEC_SEL7 (LIFEC_SEC_BASE + 0x0064U) -#define SEC_SEL8 (LIFEC_SEC_BASE + 0x0068U) -#define SEC_SEL9 (LIFEC_SEC_BASE + 0x006CU) -#define SEC_SEL10 (LIFEC_SEC_BASE + 0x0070U) -#define SEC_SEL11 (LIFEC_SEC_BASE + 0x0074U) -#define SEC_SEL12 (LIFEC_SEC_BASE + 0x0078U) -#define SEC_SEL13 (LIFEC_SEC_BASE + 0x007CU) -#define SEC_SEL14 (LIFEC_SEC_BASE + 0x0080U) -#define SEC_SEL15 (LIFEC_SEC_BASE + 0x0084U) -#define SEC_GRP0CR0 (LIFEC_SEC_BASE + 0x0138U) -#define SEC_GRP1CR0 (LIFEC_SEC_BASE + 0x013CU) -#define SEC_GRP0CR1 (LIFEC_SEC_BASE + 0x0140U) -#define SEC_GRP1CR1 (LIFEC_SEC_BASE + 0x0144U) -#define SEC_GRP0CR2 (LIFEC_SEC_BASE + 0x0148U) -#define SEC_GRP1CR2 (LIFEC_SEC_BASE + 0x014CU) -#define SEC_GRP0CR3 (LIFEC_SEC_BASE + 0x0150U) -#define SEC_GRP1CR3 (LIFEC_SEC_BASE + 0x0154U) -#define SEC_GRP0COND0 (LIFEC_SEC_BASE + 0x0158U) -#define SEC_GRP1COND0 (LIFEC_SEC_BASE + 0x015CU) -#define SEC_GRP0COND1 (LIFEC_SEC_BASE + 0x0160U) -#define SEC_GRP1COND1 (LIFEC_SEC_BASE + 0x0164U) -#define SEC_GRP0COND2 (LIFEC_SEC_BASE + 0x0168U) -#define SEC_GRP1COND2 (LIFEC_SEC_BASE + 0x016CU) -#define SEC_GRP0COND3 (LIFEC_SEC_BASE + 0x0170U) -#define SEC_GRP1COND3 (LIFEC_SEC_BASE + 0x0174U) -#define SEC_GRP0COND4 (LIFEC_SEC_BASE + 0x0178U) -#define SEC_GRP1COND4 (LIFEC_SEC_BASE + 0x017CU) -#define SEC_GRP0COND5 (LIFEC_SEC_BASE + 0x0180U) -#define SEC_GRP1COND5 (LIFEC_SEC_BASE + 0x0184U) -#define SEC_GRP0COND6 (LIFEC_SEC_BASE + 0x0188U) -#define SEC_GRP1COND6 (LIFEC_SEC_BASE + 0x018CU) -#define SEC_GRP0COND7 (LIFEC_SEC_BASE + 0x0190U) -#define SEC_GRP1COND7 (LIFEC_SEC_BASE + 0x0194U) -#define SEC_GRP0COND8 (LIFEC_SEC_BASE + 0x0198U) -#define SEC_GRP1COND8 (LIFEC_SEC_BASE + 0x019CU) -#define SEC_GRP0COND9 (LIFEC_SEC_BASE + 0x01A0U) -#define SEC_GRP1COND9 (LIFEC_SEC_BASE + 0x01A4U) -#define SEC_GRP0COND10 (LIFEC_SEC_BASE + 0x01A8U) -#define SEC_GRP1COND10 (LIFEC_SEC_BASE + 0x01ACU) -#define SEC_GRP0COND11 (LIFEC_SEC_BASE + 0x01B0U) -#define SEC_GRP1COND11 (LIFEC_SEC_BASE + 0x01B4U) -#define SEC_GRP0COND12 (LIFEC_SEC_BASE + 0x01B8U) -#define SEC_GRP1COND12 (LIFEC_SEC_BASE + 0x01BCU) -#define SEC_GRP0COND13 (LIFEC_SEC_BASE + 0x01C0U) -#define SEC_GRP1COND13 (LIFEC_SEC_BASE + 0x01C4U) -#define SEC_GRP0COND14 (LIFEC_SEC_BASE + 0x01C8U) -#define SEC_GRP1COND14 (LIFEC_SEC_BASE + 0x01CCU) -#define SEC_GRP0COND15 (LIFEC_SEC_BASE + 0x01D0U) -#define SEC_GRP1COND15 (LIFEC_SEC_BASE + 0x01D4U) -#define SEC_READONLY0 (LIFEC_SEC_BASE + 0x01D8U) -#define SEC_READONLY1 (LIFEC_SEC_BASE + 0x01DCU) -#define SEC_READONLY2 (LIFEC_SEC_BASE + 0x01E0U) -#define SEC_READONLY3 (LIFEC_SEC_BASE + 0x01E4U) -#define SEC_READONLY4 (LIFEC_SEC_BASE + 0x01E8U) -#define SEC_READONLY5 (LIFEC_SEC_BASE + 0x01ECU) -#define SEC_READONLY6 (LIFEC_SEC_BASE + 0x01F0U) -#define SEC_READONLY7 (LIFEC_SEC_BASE + 0x01F4U) -#define SEC_READONLY8 (LIFEC_SEC_BASE + 0x01F8U) -#define SEC_READONLY9 (LIFEC_SEC_BASE + 0x01FCU) -#define SEC_READONLY10 (LIFEC_SEC_BASE + 0x0200U) -#define SEC_READONLY11 (LIFEC_SEC_BASE + 0x0204U) -#define SEC_READONLY12 (LIFEC_SEC_BASE + 0x0208U) -#define SEC_READONLY13 (LIFEC_SEC_BASE + 0x020CU) -#define SEC_READONLY14 (LIFEC_SEC_BASE + 0x0210U) -#define SEC_READONLY15 (LIFEC_SEC_BASE + 0x0214U) +#define SEC_SEL7 (LIFEC_SEC_BASE + 0x0064U) +#define SEC_SEL8 (LIFEC_SEC_BASE + 0x0068U) +#define SEC_SEL9 (LIFEC_SEC_BASE + 0x006CU) +#define SEC_SEL10 (LIFEC_SEC_BASE + 0x0070U) +#define SEC_SEL11 (LIFEC_SEC_BASE + 0x0074U) +#define SEC_SEL12 (LIFEC_SEC_BASE + 0x0078U) +#define SEC_SEL13 (LIFEC_SEC_BASE + 0x007CU) +#define SEC_SEL14 (LIFEC_SEC_BASE + 0x0080U) +#define SEC_SEL15 (LIFEC_SEC_BASE + 0x0084U) +#define SEC_GRP0CR0 (LIFEC_SEC_BASE + 0x0138U) +#define SEC_GRP1CR0 (LIFEC_SEC_BASE + 0x013CU) +#define SEC_GRP0CR1 (LIFEC_SEC_BASE + 0x0140U) +#define SEC_GRP1CR1 (LIFEC_SEC_BASE + 0x0144U) +#define SEC_GRP0CR2 (LIFEC_SEC_BASE + 0x0148U) +#define SEC_GRP1CR2 (LIFEC_SEC_BASE + 0x014CU) +#define SEC_GRP0CR3 (LIFEC_SEC_BASE + 0x0150U) +#define SEC_GRP1CR3 (LIFEC_SEC_BASE + 0x0154U) +#define SEC_GRP0COND0 (LIFEC_SEC_BASE + 0x0158U) +#define SEC_GRP1COND0 (LIFEC_SEC_BASE + 0x015CU) +#define SEC_GRP0COND1 (LIFEC_SEC_BASE + 0x0160U) +#define SEC_GRP1COND1 (LIFEC_SEC_BASE + 0x0164U) +#define SEC_GRP0COND2 (LIFEC_SEC_BASE + 0x0168U) +#define SEC_GRP1COND2 (LIFEC_SEC_BASE + 0x016CU) +#define SEC_GRP0COND3 (LIFEC_SEC_BASE + 0x0170U) +#define SEC_GRP1COND3 (LIFEC_SEC_BASE + 0x0174U) +#define SEC_GRP0COND4 (LIFEC_SEC_BASE + 0x0178U) +#define SEC_GRP1COND4 (LIFEC_SEC_BASE + 0x017CU) +#define SEC_GRP0COND5 (LIFEC_SEC_BASE + 0x0180U) +#define SEC_GRP1COND5 (LIFEC_SEC_BASE + 0x0184U) +#define SEC_GRP0COND6 (LIFEC_SEC_BASE + 0x0188U) +#define SEC_GRP1COND6 (LIFEC_SEC_BASE + 0x018CU) +#define SEC_GRP0COND7 (LIFEC_SEC_BASE + 0x0190U) +#define SEC_GRP1COND7 (LIFEC_SEC_BASE + 0x0194U) +#define SEC_GRP0COND8 (LIFEC_SEC_BASE + 0x0198U) +#define SEC_GRP1COND8 (LIFEC_SEC_BASE + 0x019CU) +#define SEC_GRP0COND9 (LIFEC_SEC_BASE + 0x01A0U) +#define SEC_GRP1COND9 (LIFEC_SEC_BASE + 0x01A4U) +#define SEC_GRP0COND10 (LIFEC_SEC_BASE + 0x01A8U) +#define SEC_GRP1COND10 (LIFEC_SEC_BASE + 0x01ACU) +#define SEC_GRP0COND11 (LIFEC_SEC_BASE + 0x01B0U) +#define SEC_GRP1COND11 (LIFEC_SEC_BASE + 0x01B4U) +#define SEC_GRP0COND12 (LIFEC_SEC_BASE + 0x01B8U) +#define SEC_GRP1COND12 (LIFEC_SEC_BASE + 0x01BCU) +#define SEC_GRP0COND13 (LIFEC_SEC_BASE + 0x01C0U) +#define SEC_GRP1COND13 (LIFEC_SEC_BASE + 0x01C4U) +#define SEC_GRP0COND14 (LIFEC_SEC_BASE + 0x01C8U) +#define SEC_GRP1COND14 (LIFEC_SEC_BASE + 0x01CCU) +#define SEC_GRP0COND15 (LIFEC_SEC_BASE + 0x01D0U) +#define SEC_GRP1COND15 (LIFEC_SEC_BASE + 0x01D4U) +#define SEC_READONLY0 (LIFEC_SEC_BASE + 0x01D8U) +#define SEC_READONLY1 (LIFEC_SEC_BASE + 0x01DCU) +#define SEC_READONLY2 (LIFEC_SEC_BASE + 0x01E0U) +#define SEC_READONLY3 (LIFEC_SEC_BASE + 0x01E4U) +#define SEC_READONLY4 (LIFEC_SEC_BASE + 0x01E8U) +#define SEC_READONLY5 (LIFEC_SEC_BASE + 0x01ECU) +#define SEC_READONLY6 (LIFEC_SEC_BASE + 0x01F0U) +#define SEC_READONLY7 (LIFEC_SEC_BASE + 0x01F4U) +#define SEC_READONLY8 (LIFEC_SEC_BASE + 0x01F8U) +#define SEC_READONLY9 (LIFEC_SEC_BASE + 0x01FCU) +#define SEC_READONLY10 (LIFEC_SEC_BASE + 0x0200U) +#define SEC_READONLY11 (LIFEC_SEC_BASE + 0x0204U) +#define SEC_READONLY12 (LIFEC_SEC_BASE + 0x0208U) +#define SEC_READONLY13 (LIFEC_SEC_BASE + 0x020CU) +#define SEC_READONLY14 (LIFEC_SEC_BASE + 0x0210U) +#define SEC_READONLY15 (LIFEC_SEC_BASE + 0x0214U) -#define LIFEC_SAFE_BASE (0xE6120000U) -#define SAFE_GRP0CR0 (LIFEC_SAFE_BASE + 0x0138U) -#define SAFE_GRP1CR0 (LIFEC_SAFE_BASE + 0x013CU) -#define SAFE_GRP0CR1 (LIFEC_SAFE_BASE + 0x0140U) -#define SAFE_GRP1CR1 (LIFEC_SAFE_BASE + 0x0144U) -#define SAFE_GRP0CR2 (LIFEC_SAFE_BASE + 0x0148U) -#define SAFE_GRP1CR2 (LIFEC_SAFE_BASE + 0x014CU) -#define SAFE_GRP0CR3 (LIFEC_SAFE_BASE + 0x0150U) -#define SAFE_GRP1CR3 (LIFEC_SAFE_BASE + 0x0154U) -#define SAFE_GRP0COND0 (LIFEC_SAFE_BASE + 0x0158U) -#define SAFE_GRP1COND0 (LIFEC_SAFE_BASE + 0x015CU) -#define SAFE_GRP0COND1 (LIFEC_SAFE_BASE + 0x0160U) -#define SAFE_GRP1COND1 (LIFEC_SAFE_BASE + 0x0164U) -#define SAFE_GRP0COND2 (LIFEC_SAFE_BASE + 0x0168U) -#define SAFE_GRP1COND2 (LIFEC_SAFE_BASE + 0x016CU) -#define SAFE_GRP0COND3 (LIFEC_SAFE_BASE + 0x0170U) -#define SAFE_GRP1COND3 (LIFEC_SAFE_BASE + 0x0174U) -#define SAFE_GRP0COND4 (LIFEC_SAFE_BASE + 0x0178U) -#define SAFE_GRP1COND4 (LIFEC_SAFE_BASE + 0x017CU) -#define SAFE_GRP0COND5 (LIFEC_SAFE_BASE + 0x0180U) -#define SAFE_GRP1COND5 (LIFEC_SAFE_BASE + 0x0184U) -#define SAFE_GRP0COND6 (LIFEC_SAFE_BASE + 0x0188U) -#define SAFE_GRP1COND6 (LIFEC_SAFE_BASE + 0x018CU) -#define SAFE_GRP0COND7 (LIFEC_SAFE_BASE + 0x0190U) -#define SAFE_GRP1COND7 (LIFEC_SAFE_BASE + 0x0194U) -#define SAFE_GRP0COND8 (LIFEC_SAFE_BASE + 0x0198U) -#define SAFE_GRP1COND8 (LIFEC_SAFE_BASE + 0x019CU) -#define SAFE_GRP0COND9 (LIFEC_SAFE_BASE + 0x01A0U) -#define SAFE_GRP1COND9 (LIFEC_SAFE_BASE + 0x01A4U) -#define SAFE_GRP0COND10 (LIFEC_SAFE_BASE + 0x01A8U) -#define SAFE_GRP1COND10 (LIFEC_SAFE_BASE + 0x01ACU) -#define SAFE_GRP0COND11 (LIFEC_SAFE_BASE + 0x01B0U) -#define SAFE_GRP1COND11 (LIFEC_SAFE_BASE + 0x01B4U) -#define SAFE_GRP0COND12 (LIFEC_SAFE_BASE + 0x01B8U) -#define SAFE_GRP1COND12 (LIFEC_SAFE_BASE + 0x01BCU) -#define SAFE_GRP0COND13 (LIFEC_SAFE_BASE + 0x01C0U) -#define SAFE_GRP1COND13 (LIFEC_SAFE_BASE + 0x01C4U) -#define SAFE_GRP0COND14 (LIFEC_SAFE_BASE + 0x01C8U) -#define SAFE_GRP1COND14 (LIFEC_SAFE_BASE + 0x01CCU) -#define SAFE_GRP0COND15 (LIFEC_SAFE_BASE + 0x01D0U) -#define SAFE_GRP1COND15 (LIFEC_SAFE_BASE + 0x01D4U) -#define SAFE_READONLY0 (LIFEC_SAFE_BASE + 0x01D8U) -#define SAFE_READONLY1 (LIFEC_SAFE_BASE + 0x01DCU) -#define SAFE_READONLY2 (LIFEC_SAFE_BASE + 0x01E0U) -#define SAFE_READONLY3 (LIFEC_SAFE_BASE + 0x01E4U) -#define SAFE_READONLY4 (LIFEC_SAFE_BASE + 0x01E8U) -#define SAFE_READONLY5 (LIFEC_SAFE_BASE + 0x01ECU) -#define SAFE_READONLY6 (LIFEC_SAFE_BASE + 0x01F0U) -#define SAFE_READONLY7 (LIFEC_SAFE_BASE + 0x01F4U) -#define SAFE_READONLY8 (LIFEC_SAFE_BASE + 0x01F8U) -#define SAFE_READONLY9 (LIFEC_SAFE_BASE + 0x01FCU) -#define SAFE_READONLY10 (LIFEC_SAFE_BASE + 0x0200U) -#define SAFE_READONLY11 (LIFEC_SAFE_BASE + 0x0204U) -#define SAFE_READONLY12 (LIFEC_SAFE_BASE + 0x0208U) -#define SAFE_READONLY13 (LIFEC_SAFE_BASE + 0x020CU) -#define SAFE_READONLY14 (LIFEC_SAFE_BASE + 0x0210U) -#define SAFE_READONLY15 (LIFEC_SAFE_BASE + 0x0214U) +#define LIFEC_SAFE_BASE (0xE6120000U) +#define SAFE_GRP0CR0 (LIFEC_SAFE_BASE + 0x0138U) +#define SAFE_GRP1CR0 (LIFEC_SAFE_BASE + 0x013CU) +#define SAFE_GRP0CR1 (LIFEC_SAFE_BASE + 0x0140U) +#define SAFE_GRP1CR1 (LIFEC_SAFE_BASE + 0x0144U) +#define SAFE_GRP0CR2 (LIFEC_SAFE_BASE + 0x0148U) +#define SAFE_GRP1CR2 (LIFEC_SAFE_BASE + 0x014CU) +#define SAFE_GRP0CR3 (LIFEC_SAFE_BASE + 0x0150U) +#define SAFE_GRP1CR3 (LIFEC_SAFE_BASE + 0x0154U) +#define SAFE_GRP0COND0 (LIFEC_SAFE_BASE + 0x0158U) +#define SAFE_GRP1COND0 (LIFEC_SAFE_BASE + 0x015CU) +#define SAFE_GRP0COND1 (LIFEC_SAFE_BASE + 0x0160U) +#define SAFE_GRP1COND1 (LIFEC_SAFE_BASE + 0x0164U) +#define SAFE_GRP0COND2 (LIFEC_SAFE_BASE + 0x0168U) +#define SAFE_GRP1COND2 (LIFEC_SAFE_BASE + 0x016CU) +#define SAFE_GRP0COND3 (LIFEC_SAFE_BASE + 0x0170U) +#define SAFE_GRP1COND3 (LIFEC_SAFE_BASE + 0x0174U) +#define SAFE_GRP0COND4 (LIFEC_SAFE_BASE + 0x0178U) +#define SAFE_GRP1COND4 (LIFEC_SAFE_BASE + 0x017CU) +#define SAFE_GRP0COND5 (LIFEC_SAFE_BASE + 0x0180U) +#define SAFE_GRP1COND5 (LIFEC_SAFE_BASE + 0x0184U) +#define SAFE_GRP0COND6 (LIFEC_SAFE_BASE + 0x0188U) +#define SAFE_GRP1COND6 (LIFEC_SAFE_BASE + 0x018CU) +#define SAFE_GRP0COND7 (LIFEC_SAFE_BASE + 0x0190U) +#define SAFE_GRP1COND7 (LIFEC_SAFE_BASE + 0x0194U) +#define SAFE_GRP0COND8 (LIFEC_SAFE_BASE + 0x0198U) +#define SAFE_GRP1COND8 (LIFEC_SAFE_BASE + 0x019CU) +#define SAFE_GRP0COND9 (LIFEC_SAFE_BASE + 0x01A0U) +#define SAFE_GRP1COND9 (LIFEC_SAFE_BASE + 0x01A4U) +#define SAFE_GRP0COND10 (LIFEC_SAFE_BASE + 0x01A8U) +#define SAFE_GRP1COND10 (LIFEC_SAFE_BASE + 0x01ACU) +#define SAFE_GRP0COND11 (LIFEC_SAFE_BASE + 0x01B0U) +#define SAFE_GRP1COND11 (LIFEC_SAFE_BASE + 0x01B4U) +#define SAFE_GRP0COND12 (LIFEC_SAFE_BASE + 0x01B8U) +#define SAFE_GRP1COND12 (LIFEC_SAFE_BASE + 0x01BCU) +#define SAFE_GRP0COND13 (LIFEC_SAFE_BASE + 0x01C0U) +#define SAFE_GRP1COND13 (LIFEC_SAFE_BASE + 0x01C4U) +#define SAFE_GRP0COND14 (LIFEC_SAFE_BASE + 0x01C8U) +#define SAFE_GRP1COND14 (LIFEC_SAFE_BASE + 0x01CCU) +#define SAFE_GRP0COND15 (LIFEC_SAFE_BASE + 0x01D0U) +#define SAFE_GRP1COND15 (LIFEC_SAFE_BASE + 0x01D4U) +#define SAFE_READONLY0 (LIFEC_SAFE_BASE + 0x01D8U) +#define SAFE_READONLY1 (LIFEC_SAFE_BASE + 0x01DCU) +#define SAFE_READONLY2 (LIFEC_SAFE_BASE + 0x01E0U) +#define SAFE_READONLY3 (LIFEC_SAFE_BASE + 0x01E4U) +#define SAFE_READONLY4 (LIFEC_SAFE_BASE + 0x01E8U) +#define SAFE_READONLY5 (LIFEC_SAFE_BASE + 0x01ECU) +#define SAFE_READONLY6 (LIFEC_SAFE_BASE + 0x01F0U) +#define SAFE_READONLY7 (LIFEC_SAFE_BASE + 0x01F4U) +#define SAFE_READONLY8 (LIFEC_SAFE_BASE + 0x01F8U) +#define SAFE_READONLY9 (LIFEC_SAFE_BASE + 0x01FCU) +#define SAFE_READONLY10 (LIFEC_SAFE_BASE + 0x0200U) +#define SAFE_READONLY11 (LIFEC_SAFE_BASE + 0x0204U) +#define SAFE_READONLY12 (LIFEC_SAFE_BASE + 0x0208U) +#define SAFE_READONLY13 (LIFEC_SAFE_BASE + 0x020CU) +#define SAFE_READONLY14 (LIFEC_SAFE_BASE + 0x0210U) +#define SAFE_READONLY15 (LIFEC_SAFE_BASE + 0x0214U) #endif /* LIFEC_REGISTERS_H */ -- cgit v1.2.3 From cdcf1f1492dd05b8f9038e1bbdd091e93c153a3c Mon Sep 17 00:00:00 2001 From: Biju Das Date: Wed, 16 Dec 2020 10:46:36 +0000 Subject: drivers: renesas: delay: Move to common Move delay driver code to common directory, so that the same code can be re-used by both R-Car Gen3 and RZ/G2 platforms. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: I5e806bd0e0a0a4b436048513b7089db90ff9805f --- drivers/renesas/common/delay/micro_delay.c | 31 ++++++++++++++++++++++++++++++ drivers/renesas/common/delay/micro_delay.h | 15 +++++++++++++++ drivers/renesas/rcar/delay/micro_delay.c | 31 ------------------------------ drivers/renesas/rcar/delay/micro_delay.h | 15 --------------- plat/renesas/common/common.mk | 2 ++ plat/renesas/rcar/platform.mk | 6 ++---- 6 files changed, 50 insertions(+), 50 deletions(-) create mode 100644 drivers/renesas/common/delay/micro_delay.c create mode 100644 drivers/renesas/common/delay/micro_delay.h delete mode 100644 drivers/renesas/rcar/delay/micro_delay.c delete mode 100644 drivers/renesas/rcar/delay/micro_delay.h diff --git a/drivers/renesas/common/delay/micro_delay.c b/drivers/renesas/common/delay/micro_delay.c new file mode 100644 index 000000000..a5e2a6928 --- /dev/null +++ b/drivers/renesas/common/delay/micro_delay.c @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2018-2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include "micro_delay.h" + +#define RCAR_CONV_MICROSEC 1000000U + +void +#if IMAGE_BL31 + __attribute__ ((section(".system_ram"))) +#endif + rcar_micro_delay(uint64_t micro_sec) +{ + uint64_t freq; + uint64_t base_count; + uint64_t get_count; + uint64_t wait_time = 0U; + + freq = read_cntfrq_el0(); + base_count = read_cntpct_el0(); + while (micro_sec > wait_time) { + get_count = read_cntpct_el0(); + wait_time = ((get_count - base_count) * RCAR_CONV_MICROSEC) / freq; + } +} diff --git a/drivers/renesas/common/delay/micro_delay.h b/drivers/renesas/common/delay/micro_delay.h new file mode 100644 index 000000000..37b71f80a --- /dev/null +++ b/drivers/renesas/common/delay/micro_delay.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MICRO_DELAY_H +#define MICRO_DELAY_H + +#ifndef __ASSEMBLER__ +#include +void rcar_micro_delay(uint64_t micro_sec); +#endif + +#endif /* MICRO_DELAY_H */ diff --git a/drivers/renesas/rcar/delay/micro_delay.c b/drivers/renesas/rcar/delay/micro_delay.c deleted file mode 100644 index a5e2a6928..000000000 --- a/drivers/renesas/rcar/delay/micro_delay.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2018-2020, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include - -#include "micro_delay.h" - -#define RCAR_CONV_MICROSEC 1000000U - -void -#if IMAGE_BL31 - __attribute__ ((section(".system_ram"))) -#endif - rcar_micro_delay(uint64_t micro_sec) -{ - uint64_t freq; - uint64_t base_count; - uint64_t get_count; - uint64_t wait_time = 0U; - - freq = read_cntfrq_el0(); - base_count = read_cntpct_el0(); - while (micro_sec > wait_time) { - get_count = read_cntpct_el0(); - wait_time = ((get_count - base_count) * RCAR_CONV_MICROSEC) / freq; - } -} diff --git a/drivers/renesas/rcar/delay/micro_delay.h b/drivers/renesas/rcar/delay/micro_delay.h deleted file mode 100644 index 37b71f80a..000000000 --- a/drivers/renesas/rcar/delay/micro_delay.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef MICRO_DELAY_H -#define MICRO_DELAY_H - -#ifndef __ASSEMBLER__ -#include -void rcar_micro_delay(uint64_t micro_sec); -#endif - -#endif /* MICRO_DELAY_H */ diff --git a/plat/renesas/common/common.mk b/plat/renesas/common/common.mk index cdcbc2144..dda7c89f2 100644 --- a/plat/renesas/common/common.mk +++ b/plat/renesas/common/common.mk @@ -84,6 +84,7 @@ BL2_SOURCES += ${RCAR_GIC_SOURCES} \ drivers/renesas/common/io/io_emmcdrv.c \ drivers/renesas/common/io/io_memdrv.c \ drivers/renesas/common/io/io_rcar.c \ + drivers/renesas/common/delay/micro_delay.c \ drivers/renesas/common/emmc/emmc_interrupt.c \ drivers/renesas/common/emmc/emmc_utility.c \ drivers/renesas/common/emmc/emmc_mount.c \ @@ -98,6 +99,7 @@ BL31_SOURCES += ${RCAR_GIC_SOURCES} \ plat/common/plat_psci_common.c \ drivers/renesas/common/console/rcar_console.S \ drivers/renesas/common/console/rcar_printf.c \ + drivers/renesas/common/delay/micro_delay.c \ drivers/renesas/common/pwrc/call_sram.S \ drivers/renesas/common/pwrc/pwrc.c \ drivers/renesas/common/common.c \ diff --git a/plat/renesas/rcar/platform.mk b/plat/renesas/rcar/platform.mk index 05f9c2d26..ca6fe6b73 100644 --- a/plat/renesas/rcar/platform.mk +++ b/plat/renesas/rcar/platform.mk @@ -304,7 +304,7 @@ PLAT_INCLUDES += -Idrivers/renesas/rcar/ddr \ -Idrivers/renesas/rcar/cpld/ \ -Idrivers/renesas/common/iic_dvfs \ -Idrivers/renesas/rcar/avs \ - -Idrivers/renesas/rcar/delay \ + -Idrivers/renesas/common/delay \ -Idrivers/renesas/rcar/rom \ -Idrivers/renesas/common/scif \ -Idrivers/renesas/common/emmc \ @@ -324,7 +324,6 @@ BL2_SOURCES += plat/renesas/rcar/aarch64/platform_common.c \ drivers/renesas/rcar/rpc/rpc_driver.c \ drivers/renesas/rcar/dma/dma_driver.c \ drivers/renesas/rcar/avs/avs_driver.c \ - drivers/renesas/rcar/delay/micro_delay.c \ drivers/renesas/rcar/watchdog/swdt.c \ drivers/renesas/rcar/rom/rom_api.c \ drivers/renesas/rcar/board/board.c @@ -333,8 +332,7 @@ BL31_SOURCES += plat/renesas/rcar/plat_topology.c \ plat/renesas/rcar/aarch64/plat_helpers.S \ plat/renesas/rcar/aarch64/platform_common.c \ plat/renesas/rcar/bl31_plat_setup.c \ - plat/renesas/rcar/plat_pm.c \ - drivers/renesas/rcar/delay/micro_delay.c + plat/renesas/rcar/plat_pm.c ifeq (${RCAR_GEN3_ULCB},1) BL31_SOURCES += drivers/renesas/rcar/cpld/ulcb_cpld.c -- cgit v1.2.3 From 011a4c2f049a422e91ac26d5c146f3a1c7d2d16d Mon Sep 17 00:00:00 2001 From: Biju Das Date: Wed, 16 Dec 2020 08:57:59 +0000 Subject: plat: renesas: Move headers and assembly files to common folder Create a common directory and move the header and assembly files so that the common code can be used by both Renesas R-Car Gen3 and RZ/G2 platforms. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: Ia9a563a1c3c9f8c6f0d3cb82622deb2e155d7f6c --- drivers/renesas/common/common.c | 37 +++ drivers/renesas/rcar/common.c | 37 --- plat/renesas/common/common.mk | 86 ++++++ plat/renesas/common/include/plat.ld.S | 36 +++ plat/renesas/common/include/plat_macros.S | 88 ++++++ plat/renesas/common/include/platform_def.h | 199 +++++++++++++ plat/renesas/common/include/rcar_def.h | 310 +++++++++++++++++++++ plat/renesas/common/include/rcar_private.h | 108 +++++++ plat/renesas/common/include/rcar_version.h | 17 ++ .../common/include/registers/axi_registers.h | 246 ++++++++++++++++ .../common/include/registers/cpg_registers.h | 136 +++++++++ .../common/include/registers/lifec_registers.h | 144 ++++++++++ plat/renesas/rcar/include/plat.ld.S | 36 --- plat/renesas/rcar/include/plat_macros.S | 88 ------ plat/renesas/rcar/include/platform_def.h | 199 ------------- plat/renesas/rcar/include/rcar_def.h | 310 --------------------- plat/renesas/rcar/include/rcar_private.h | 108 ------- plat/renesas/rcar/include/rcar_version.h | 17 -- .../renesas/rcar/include/registers/axi_registers.h | 246 ---------------- .../renesas/rcar/include/registers/cpg_registers.h | 136 --------- .../rcar/include/registers/lifec_registers.h | 144 ---------- plat/renesas/rcar/platform.mk | 94 +------ 22 files changed, 1416 insertions(+), 1406 deletions(-) create mode 100644 drivers/renesas/common/common.c delete mode 100644 drivers/renesas/rcar/common.c create mode 100644 plat/renesas/common/common.mk create mode 100644 plat/renesas/common/include/plat.ld.S create mode 100644 plat/renesas/common/include/plat_macros.S create mode 100644 plat/renesas/common/include/platform_def.h create mode 100644 plat/renesas/common/include/rcar_def.h create mode 100644 plat/renesas/common/include/rcar_private.h create mode 100644 plat/renesas/common/include/rcar_version.h create mode 100644 plat/renesas/common/include/registers/axi_registers.h create mode 100644 plat/renesas/common/include/registers/cpg_registers.h create mode 100644 plat/renesas/common/include/registers/lifec_registers.h delete mode 100644 plat/renesas/rcar/include/plat.ld.S delete mode 100644 plat/renesas/rcar/include/plat_macros.S delete mode 100644 plat/renesas/rcar/include/platform_def.h delete mode 100644 plat/renesas/rcar/include/rcar_def.h delete mode 100644 plat/renesas/rcar/include/rcar_private.h delete mode 100644 plat/renesas/rcar/include/rcar_version.h delete mode 100644 plat/renesas/rcar/include/registers/axi_registers.h delete mode 100644 plat/renesas/rcar/include/registers/cpg_registers.h delete mode 100644 plat/renesas/rcar/include/registers/lifec_registers.h diff --git a/drivers/renesas/common/common.c b/drivers/renesas/common/common.c new file mode 100644 index 000000000..9b7c1eb16 --- /dev/null +++ b/drivers/renesas/common/common.c @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2018-2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include "rcar_private.h" + +#if IMAGE_BL31 +void __attribute__ ((section(".system_ram"))) cpg_write(uintptr_t regadr, uint32_t regval) +#else +void cpg_write(uintptr_t regadr, uint32_t regval) +#endif +{ + uint32_t value = regval; + + mmio_write_32((uintptr_t) RCAR_CPGWPR, ~value); + mmio_write_32(regadr, value); +} + +#if IMAGE_BL31 +void __attribute__ ((section(".system_ram"))) mstpcr_write(uint32_t mstpcr, uint32_t mstpsr, + uint32_t target_bit) +#else +void mstpcr_write(uint32_t mstpcr, uint32_t mstpsr, uint32_t target_bit) +#endif +{ + uint32_t reg; + + reg = mmio_read_32(mstpcr); + reg &= ~target_bit; + cpg_write(mstpcr, reg); + while ((mmio_read_32(mstpsr) & target_bit) != 0U) { + } +} diff --git a/drivers/renesas/rcar/common.c b/drivers/renesas/rcar/common.c deleted file mode 100644 index 9b7c1eb16..000000000 --- a/drivers/renesas/rcar/common.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2018-2020, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include "rcar_private.h" - -#if IMAGE_BL31 -void __attribute__ ((section(".system_ram"))) cpg_write(uintptr_t regadr, uint32_t regval) -#else -void cpg_write(uintptr_t regadr, uint32_t regval) -#endif -{ - uint32_t value = regval; - - mmio_write_32((uintptr_t) RCAR_CPGWPR, ~value); - mmio_write_32(regadr, value); -} - -#if IMAGE_BL31 -void __attribute__ ((section(".system_ram"))) mstpcr_write(uint32_t mstpcr, uint32_t mstpsr, - uint32_t target_bit) -#else -void mstpcr_write(uint32_t mstpcr, uint32_t mstpsr, uint32_t target_bit) -#endif -{ - uint32_t reg; - - reg = mmio_read_32(mstpcr); - reg &= ~target_bit; - cpg_write(mstpcr, reg); - while ((mmio_read_32(mstpsr) & target_bit) != 0U) { - } -} diff --git a/plat/renesas/common/common.mk b/plat/renesas/common/common.mk new file mode 100644 index 000000000..f2e1112a6 --- /dev/null +++ b/plat/renesas/common/common.mk @@ -0,0 +1,86 @@ +# +# Copyright (c) 2018-2020, Renesas Electronics Corporation. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +PROGRAMMABLE_RESET_ADDRESS := 0 +COLD_BOOT_SINGLE_CPU := 1 +ARM_CCI_PRODUCT_ID := 500 +TRUSTED_BOARD_BOOT := 1 +RESET_TO_BL31 := 1 +GENERATE_COT := 1 +BL2_AT_EL3 := 1 +ENABLE_SVE_FOR_NS := 0 +MULTI_CONSOLE_API := 1 + +CRASH_REPORTING := 1 +HANDLE_EA_EL3_FIRST := 1 + +$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT)) + +ifeq (${SPD},none) + SPD_NONE:=1 + $(eval $(call add_define,SPD_NONE)) +endif + +# LSI setting common define +RCAR_H3:=0 +RCAR_M3:=1 +RCAR_M3N:=2 +RCAR_E3:=3 +RCAR_H3N:=4 +RCAR_D3:=5 +RCAR_V3M:=6 +RCAR_AUTO:=99 +$(eval $(call add_define,RCAR_H3)) +$(eval $(call add_define,RCAR_M3)) +$(eval $(call add_define,RCAR_M3N)) +$(eval $(call add_define,RCAR_E3)) +$(eval $(call add_define,RCAR_H3N)) +$(eval $(call add_define,RCAR_D3)) +$(eval $(call add_define,RCAR_V3M)) +$(eval $(call add_define,RCAR_AUTO)) +RCAR_CUT_10:=0 +RCAR_CUT_11:=1 +RCAR_CUT_13:=3 +RCAR_CUT_20:=10 +RCAR_CUT_30:=20 +$(eval $(call add_define,RCAR_CUT_10)) +$(eval $(call add_define,RCAR_CUT_11)) +$(eval $(call add_define,RCAR_CUT_13)) +$(eval $(call add_define,RCAR_CUT_20)) +$(eval $(call add_define,RCAR_CUT_30)) + +# Enable workarounds for selected Cortex-A53 erratas. +ERRATA_A53_835769 := 1 +ERRATA_A53_843419 := 1 +ERRATA_A53_855873 := 1 + +# Enable workarounds for selected Cortex-A57 erratas. +ERRATA_A57_859972 := 1 +ERRATA_A57_813419 := 1 + +PLAT_INCLUDES := -Iplat/renesas/common/include/registers \ + -Iplat/renesas/common/include \ + -Iplat/renesas/common + +RCAR_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ + drivers/arm/gic/v2/gicv2_main.c \ + drivers/arm/gic/v2/gicv2_helpers.c \ + plat/common/plat_gicv2.c + +BL2_SOURCES += ${RCAR_GIC_SOURCES} \ + lib/cpus/aarch64/cortex_a53.S \ + lib/cpus/aarch64/cortex_a57.S \ + ${LIBFDT_SRCS} \ + common/desc_image_load.c \ + drivers/renesas/common/common.c \ + drivers/io/io_storage.c + +BL31_SOURCES += ${RCAR_GIC_SOURCES} \ + lib/cpus/aarch64/cortex_a53.S \ + lib/cpus/aarch64/cortex_a57.S \ + plat/common/plat_psci_common.c \ + drivers/renesas/common/common.c \ + drivers/arm/cci/cci.c diff --git a/plat/renesas/common/include/plat.ld.S b/plat/renesas/common/include/plat.ld.S new file mode 100644 index 000000000..7aef324c4 --- /dev/null +++ b/plat/renesas/common/include/plat.ld.S @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef RCAR_PLAT_LD_S +#define RCAR_PLAT_LD_S + +#include +#include + +MEMORY { + SRAM (rwx): ORIGIN = BL31_SRAM_BASE, LENGTH = DEVICE_SRAM_SIZE + PRAM (r): ORIGIN = BL31_LIMIT - DEVICE_SRAM_SIZE, LENGTH = DEVICE_SRAM_SIZE +} + +SECTIONS +{ + /* SRAM_COPY is in PRAM */ + . = BL31_LIMIT - DEVICE_SRAM_SIZE; + __SRAM_COPY_START__ = .; + + .system_ram : { + /* system ram start is in SRAM */ + __system_ram_start__ = .; + *(.system_ram*) + *iic_dvfs.o(.rodata) + __system_ram_end__ = .; + } >SRAM AT>PRAM + + ASSERT(__BL31_END__ <= BL31_LIMIT - DEVICE_SRAM_SIZE, + "BL31 image too large - writing on top of SRAM!") + +} + +#endif /* RCAR_PLAT_LD_S */ diff --git a/plat/renesas/common/include/plat_macros.S b/plat/renesas/common/include/plat_macros.S new file mode 100644 index 000000000..927cd39e8 --- /dev/null +++ b/plat/renesas/common/include/plat_macros.S @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include "rcar_def.h" + +.section .rodata.gic_reg_name, "aS" +gicc_regs: + .asciz "gicc_hppir", "gicc_ahppir", "gicc_ctlr", "" +gicd_pend_reg: + .asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n Offset:\t\t\tvalue\n" +newline: + .asciz "\n" +spacer: + .asciz ":\t\t0x" + + /* --------------------------------------------- + * The below macro prints out relevant GIC + * registers whenever an unhandled exception is + * taken in BL3-1. + * Clobbers: x0 - x10, x16, x17, sp + * --------------------------------------------- + */ + .macro plat_print_gic_regs + mov_imm x17, RCAR_GICC_BASE + mov_imm x16, RCAR_GICD_BASE +print_gicc_regs: + /* gicc base address is now in x17 */ + adr x6, gicc_regs /* Load the gicc reg list to x6 */ + /* Load the gicc regs to gp regs used by str_in_crash_buf_print */ + ldr w8, [x17, #GICC_HPPIR] + ldr w9, [x17, #GICC_AHPPIR] + ldr w10, [x17, #GICC_CTLR] + /* Store to the crash buf and print to console */ + bl str_in_crash_buf_print + + /* Print the GICD_ISPENDR regs */ + add x7, x16, #GICD_ISPENDR + adr x4, gicd_pend_reg + bl asm_print_str +gicd_ispendr_loop: + sub x4, x7, x16 + cmp x4, #0x280 + b.eq exit_print_gic_regs + bl asm_print_hex + adr x4, spacer + bl asm_print_str + ldr x4, [x7], #8 + bl asm_print_hex + adr x4, newline + bl asm_print_str + b gicd_ispendr_loop +exit_print_gic_regs: + .endm + +.section .rodata.cci_reg_name, "aS" +cci_iface_regs: + .asciz "cci_snoop_ctrl_cluster0", "cci_snoop_ctrl_cluster1" , "" + + /* ------------------------------------------------ + * The below macro prints out relevant interconnect + * registers whenever an unhandled exception is + * taken in BL3-1. + * Clobbers: x0 - x9, sp + * ------------------------------------------------ + */ + .macro plat_print_interconnect_regs + adr x6, cci_iface_regs + /* Store in x7 the base address of the first interface */ + mov_imm x7, (CCI500_BASE + SLAVE_IFACE3_OFFSET) + ldr w8, [x7, #SNOOP_CTRL_REG] + /* Store in x7 the base address of the second interface */ + mov_imm x7, (CCI500_BASE + SLAVE_IFACE4_OFFSET) + ldr w9, [x7, #SNOOP_CTRL_REG] + /* Store to the crash buf and print to console */ + bl str_in_crash_buf_print + .endm + + .macro plat_crash_print_regs + plat_print_gic_regs + plat_print_interconnect_regs + .endm diff --git a/plat/renesas/common/include/platform_def.h b/plat/renesas/common/include/platform_def.h new file mode 100644 index 000000000..73787140b --- /dev/null +++ b/plat/renesas/common/include/platform_def.h @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +#ifndef __ASSEMBLER__ +#include +#endif + +#include + +#include "rcar_def.h" + +/******************************************************************************* + * Platform binary types for linking + ******************************************************************************/ +#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64" +#define PLATFORM_LINKER_ARCH aarch64 + +/******************************************************************************* + * Generic platform constants + ******************************************************************************/ + #define FIRMWARE_WELCOME_STR "Booting Rcar-gen3 Trusted Firmware\n" + +/* Size of cacheable stacks */ +#if IMAGE_BL1 +#if TRUSTED_BOARD_BOOT +#define PLATFORM_STACK_SIZE U(0x1000) +#else +#define PLATFORM_STACK_SIZE U(0x440) +#endif +#elif IMAGE_BL2 +#if TRUSTED_BOARD_BOOT +#define PLATFORM_STACK_SIZE U(0x1000) +#else +#define PLATFORM_STACK_SIZE U(0x400) +#endif +#elif IMAGE_BL31 +#define PLATFORM_STACK_SIZE U(0x400) +#elif IMAGE_BL32 +#define PLATFORM_STACK_SIZE U(0x440) +#endif + +#define BL332_IMAGE_ID (NS_BL2U_IMAGE_ID + 1) +#define BL333_IMAGE_ID (NS_BL2U_IMAGE_ID + 2) +#define BL334_IMAGE_ID (NS_BL2U_IMAGE_ID + 3) +#define BL335_IMAGE_ID (NS_BL2U_IMAGE_ID + 4) +#define BL336_IMAGE_ID (NS_BL2U_IMAGE_ID + 5) +#define BL337_IMAGE_ID (NS_BL2U_IMAGE_ID + 6) +#define BL338_IMAGE_ID (NS_BL2U_IMAGE_ID + 7) + +#define BL332_KEY_CERT_ID (NS_BL2U_IMAGE_ID + 8) +#define BL333_KEY_CERT_ID (NS_BL2U_IMAGE_ID + 9) +#define BL334_KEY_CERT_ID (NS_BL2U_IMAGE_ID + 10) +#define BL335_KEY_CERT_ID (NS_BL2U_IMAGE_ID + 11) +#define BL336_KEY_CERT_ID (NS_BL2U_IMAGE_ID + 12) +#define BL337_KEY_CERT_ID (NS_BL2U_IMAGE_ID + 13) +#define BL338_KEY_CERT_ID (NS_BL2U_IMAGE_ID + 14) + +#define BL332_CERT_ID (NS_BL2U_IMAGE_ID + 15) +#define BL333_CERT_ID (NS_BL2U_IMAGE_ID + 16) +#define BL334_CERT_ID (NS_BL2U_IMAGE_ID + 17) +#define BL335_CERT_ID (NS_BL2U_IMAGE_ID + 18) +#define BL336_CERT_ID (NS_BL2U_IMAGE_ID + 19) +#define BL337_CERT_ID (NS_BL2U_IMAGE_ID + 20) +#define BL338_CERT_ID (NS_BL2U_IMAGE_ID + 21) + +/* io drivers id */ +#define FLASH_DEV_ID U(0) +#define EMMC_DEV_ID U(1) + +/* + * R-Car H3 Cortex-A57 + * L1:I/48KB(16KBx3way) D/32KB(16KBx2way) L2:2MB(128KBx16way) + * Cortex-A53 + * L1:I/32KB(16KBx2way) D/32KB(8KBx4way) L2:512KB(32KBx16way) + */ +#define PLATFORM_CACHE_LINE_SIZE 64 +#define PLATFORM_CLUSTER_COUNT U(2) +#define PLATFORM_CLUSTER0_CORE_COUNT U(4) +#define PLATFORM_CLUSTER1_CORE_COUNT U(4) +#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER1_CORE_COUNT + \ + PLATFORM_CLUSTER0_CORE_COUNT) +#define PLATFORM_MAX_CPUS_PER_CLUSTER U(4) + +#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL2 +#define PLAT_NUM_PWR_DOMAINS (PLATFORM_CORE_COUNT + \ + PLATFORM_CLUSTER_COUNT + 1) + +#define PLAT_MAX_RET_STATE U(1) +#define PLAT_MAX_OFF_STATE U(2) + +#define MAX_IO_DEVICES U(3) +#define MAX_IO_HANDLES U(4) + +/* + ****************************************************************************** + * BL2 specific defines. + ****************************************************************************** + * Put BL2 just below BL3-1. BL2_BASE is calculated using the current BL2 debug + * size plus a little space for growth. + */ +#define RCAR_SYSRAM_BASE U(0xE6300000) +#if (RCAR_LSI == RCAR_E3) || (RCAR_LSI == RCAR_D3) +#define BL2_LIMIT U(0xE6320000) +#else +#define BL2_LIMIT U(0xE6360000) +#endif + +#if (RCAR_LSI == RCAR_E3) || (RCAR_LSI == RCAR_D3) +#define BL2_BASE U(0xE6304000) +#define BL2_IMAGE_LIMIT U(0xE6318000) +#elif (RCAR_LSI == RCAR_V3M) +#define BL2_BASE U(0xE6344000) +#define BL2_IMAGE_LIMIT U(0xE636E800) +#else +#define BL2_BASE U(0xE6304000) +#define BL2_IMAGE_LIMIT U(0xE632E800) +#endif +#define RCAR_SYSRAM_SIZE (BL2_BASE - RCAR_SYSRAM_BASE) + +/* + ****************************************************************************** + * BL31 specific defines. + ****************************************************************************** + * Put BL3-1 at the top of the Trusted SRAM. BL31_BASE is calculated using the + * current BL3-1 debug size plus a little space for growth. + */ +#define BL31_BASE (RCAR_TRUSTED_SRAM_BASE) +#define BL31_LIMIT (RCAR_TRUSTED_SRAM_BASE + \ + RCAR_TRUSTED_SRAM_SIZE) +#define RCAR_BL31_LOG_BASE (0x44040000) +#define RCAR_BL31_SDRAM_BTM (RCAR_BL31_LOG_BASE + 0x14000) +#define RCAR_BL31_LOG_SIZE (RCAR_BL31_SDRAM_BTM - RCAR_BL31_LOG_BASE) +#define BL31_SRAM_BASE (DEVICE_SRAM_BASE) +#define BL31_SRAM_LIMIT (DEVICE_SRAM_BASE + DEVICE_SRAM_SIZE) + +/******************************************************************************* + * BL32 specific defines. + ******************************************************************************/ +#ifndef SPD_NONE +#define BL32_BASE U(0x44100000) +#define BL32_LIMIT (BL32_BASE + U(0x100000)) +#endif + +/******************************************************************************* + * BL33 + ******************************************************************************/ +#define BL33_BASE DRAM1_NS_BASE + + +/******************************************************************************* + * Platform specific page table and MMU setup constants + ******************************************************************************/ +#if IMAGE_BL1 +#define MAX_XLAT_TABLES U(2) +#elif IMAGE_BL2 +#define MAX_XLAT_TABLES U(5) +#elif IMAGE_BL31 +#define MAX_XLAT_TABLES U(4) +#elif IMAGE_BL32 +#define MAX_XLAT_TABLES U(3) +#endif + +#if IMAGE_BL2 +#define PLAT_PHY_ADDR_SPACE_SIZE (ULL(1) << 40) +#define PLAT_VIRT_ADDR_SPACE_SIZE (ULL(1) << 40) +#else +#define PLAT_PHY_ADDR_SPACE_SIZE (ULL(1) << 32) +#define PLAT_VIRT_ADDR_SPACE_SIZE (ULL(1) << 32) +#endif + +#define MAX_MMAP_REGIONS (RCAR_MMAP_ENTRIES + RCAR_BL_REGIONS) + +/******************************************************************************* + * Declarations and constants to access the mailboxes safely. Each mailbox is + * 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. Such alignment ensures that two mailboxes do not sit on the same cache + * line at any cache level. They could belong to different cpus/clusters & + * get written while being protected by different locks causing corruption of + * a valid mailbox address. + ******************************************************************************/ +#define CACHE_WRITEBACK_SHIFT (6) +#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT) + +/******************************************************************************* + * Size of the per-cpu data in bytes that should be reserved in the generic + * per-cpu data structure for the RCAR port. + ******************************************************************************/ +#if !USE_COHERENT_MEM +#define PLAT_PCPU_DATA_SIZE (2) +#endif + +#endif /* PLATFORM_DEF_H */ diff --git a/plat/renesas/common/include/rcar_def.h b/plat/renesas/common/include/rcar_def.h new file mode 100644 index 000000000..6c5b29561 --- /dev/null +++ b/plat/renesas/common/include/rcar_def.h @@ -0,0 +1,310 @@ +/* + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef RCAR_DEF_H +#define RCAR_DEF_H + +#include +#include + +#define RCAR_PRIMARY_CPU 0x0 +#define RCAR_TRUSTED_SRAM_BASE 0x44000000 +#define RCAR_TRUSTED_SRAM_SIZE 0x0003E000 +#define RCAR_SHARED_MEM_BASE (RCAR_TRUSTED_SRAM_BASE + \ + RCAR_TRUSTED_SRAM_SIZE) +#define RCAR_SHARED_MEM_SIZE U(0x00001000) +#define FLASH0_BASE U(0x08000000) +#define FLASH0_SIZE U(0x04000000) +#define FLASH_MEMORY_SIZE U(0x04000000) /* hyper flash */ +#define FLASH_TRANS_SIZE_UNIT U(0x00000100) +#define DEVICE_RCAR_BASE U(0xE6000000) +#define DEVICE_RCAR_SIZE U(0x00300000) +#define DEVICE_RCAR_BASE2 U(0xE6360000) +#define DEVICE_RCAR_SIZE2 U(0x19CA0000) +#define DEVICE_SRAM_BASE U(0xE6300000) +#define DEVICE_SRAM_SIZE U(0x00002000) +#define DEVICE_SRAM_STACK_BASE (DEVICE_SRAM_BASE + DEVICE_SRAM_SIZE) +#define DEVICE_SRAM_STACK_SIZE U(0x00001000) +#define DRAM_LIMIT ULL(0x0000010000000000) +#define DRAM1_BASE U(0x40000000) +#define DRAM1_SIZE U(0x80000000) +#define DRAM1_NS_BASE (DRAM1_BASE + U(0x10000000)) +#define DRAM1_NS_SIZE (DRAM1_SIZE - DRAM1_NS_BASE) +#define DRAM_40BIT_BASE ULL(0x0400000000) +#define DRAM_40BIT_SIZE ULL(0x0400000000) +#define DRAM_PROTECTED_BASE ULL(0x43F00000) +#define DRAM_40BIT_PROTECTED_BASE ULL(0x0403F00000) +#define DRAM_PROTECTED_SIZE ULL(0x03F00000) +#define RCAR_BL31_CRASH_BASE U(0x4403F000) +#define RCAR_BL31_CRASH_SIZE U(0x00001000) +/* Entrypoint mailboxes */ +#define MBOX_BASE RCAR_SHARED_MEM_BASE +#define MBOX_SIZE 0x200 +/* Base address where parameters to BL31 are stored */ +#define PARAMS_BASE (MBOX_BASE + MBOX_SIZE) +#define BOOT_KIND_BASE (RCAR_SHARED_MEM_BASE + \ + RCAR_SHARED_MEM_SIZE - 0x100) +/* + * The number of regions like RO(code), coherent and data required by + * different BL stages which need to be mapped in the MMU + */ +#if USE_COHERENT_MEM +#define RCAR_BL_REGIONS (3) +#else +#define RCAR_BL_REGIONS (2) +#endif +/* + * The RCAR_MAX_MMAP_REGIONS depends on the number of entries in rcar_mmap[] + * defined for each BL stage in rcar_common.c. + */ +#if IMAGE_BL2 +#define RCAR_MMAP_ENTRIES (9) +#endif +#if IMAGE_BL31 +#define RCAR_MMAP_ENTRIES (9) +#endif +#if IMAGE_BL2 +#define REG1_BASE U(0xE6400000) +#define REG1_SIZE U(0x04C00000) +#define ROM0_BASE U(0xEB100000) +#define ROM0_SIZE U(0x00028000) +#define REG2_BASE U(0xEC000000) +#define REG2_SIZE U(0x14000000) +#endif +/* BL33 */ +#define NS_IMAGE_OFFSET (DRAM1_BASE + U(0x09000000)) +/* BL31 */ +#define RCAR_DEVICE_BASE DEVICE_RCAR_BASE +#define RCAR_DEVICE_SIZE (0x1A000000) +#define RCAR_LOG_RES_SIZE (64) +#define RCAR_LOG_HEADER_SIZE (16) +#define RCAR_LOG_OTHER_SIZE (RCAR_LOG_HEADER_SIZE + \ + RCAR_LOG_RES_SIZE) +#define RCAR_BL31_LOG_MAX (RCAR_BL31_LOG_SIZE - \ + RCAR_LOG_OTHER_SIZE) +#define RCAR_CRASH_STACK RCAR_BL31_CRASH_BASE +#define AARCH64_SPACE_BASE ULL(0x00000000000) +#define AARCH64_SPACE_SIZE ULL(0x10000000000) +/* CCI related constants */ +#define CCI500_BASE U(0xF1200000) +#define CCI500_CLUSTER0_SL_IFACE_IX (2) +#define CCI500_CLUSTER1_SL_IFACE_IX (3) +#define CCI500_CLUSTER0_SL_IFACE_IX_FOR_M3 (1) +#define CCI500_CLUSTER1_SL_IFACE_IX_FOR_M3 (2) +#define RCAR_CCI_BASE CCI500_BASE +/* GIC */ +#define RCAR_GICD_BASE U(0xF1010000) +#define RCAR_GICR_BASE U(0xF1010000) +#define RCAR_GICC_BASE U(0xF1020000) +#define RCAR_GICH_BASE U(0xF1040000) +#define RCAR_GICV_BASE U(0xF1060000) +#define ARM_IRQ_SEC_PHY_TIMER U(29) +#define ARM_IRQ_SEC_SGI_0 U(8) +#define ARM_IRQ_SEC_SGI_1 U(9) +#define ARM_IRQ_SEC_SGI_2 U(10) +#define ARM_IRQ_SEC_SGI_3 U(11) +#define ARM_IRQ_SEC_SGI_4 U(12) +#define ARM_IRQ_SEC_SGI_5 U(13) +#define ARM_IRQ_SEC_SGI_6 U(14) +#define ARM_IRQ_SEC_SGI_7 U(15) +#define ARM_IRQ_SEC_RPC U(70) +#define ARM_IRQ_SEC_TIMER U(166) +#define ARM_IRQ_SEC_TIMER_UP U(171) +#define ARM_IRQ_SEC_WDT U(173) +#define ARM_IRQ_SEC_CRYPT U(102) +#define ARM_IRQ_SEC_CRYPT_SecPKA U(97) +#define ARM_IRQ_SEC_CRYPT_PubPKA U(98) +/* Timer control */ +#define RCAR_CNTC_BASE U(0xE6080000) +/* Reset */ +#define RCAR_CPGWPR U(0xE6150900) /* CPG write protect */ +#define RCAR_MODEMR U(0xE6160060) /* Mode pin */ +#define RCAR_CA57RESCNT U(0xE6160040) /* Reset control A57 */ +#define RCAR_CA53RESCNT U(0xE6160044) /* Reset control A53 */ +#define RCAR_SRESCR U(0xE6160110) /* Soft Power On Reset */ +#define RCAR_CA53WUPCR U(0xE6151010) /* Wake-up control A53 */ +#define RCAR_CA57WUPCR U(0xE6152010) /* Wake-up control A57 */ +#define RCAR_CA53PSTR U(0xE6151040) /* Power status A53 */ +#define RCAR_CA57PSTR U(0xE6152040) /* Power status A57 */ +#define RCAR_CA53CPU0CR U(0xE6151100) /* CPU control A53 */ +#define RCAR_CA57CPU0CR U(0xE6152100) /* CPU control A57 */ +#define RCAR_CA53CPUCMCR U(0xE6151184) /* Common power A53 */ +#define RCAR_CA57CPUCMCR U(0xE6152184) /* Common power A57 */ +#define RCAR_WUPMSKCA57 U(0xE6180014) /* Wake-up mask A57 */ +#define RCAR_WUPMSKCA53 U(0xE6180018) /* Wake-up mask A53 */ +/* SYSC */ +#define RCAR_PWRSR3 U(0xE6180140) /* Power stat A53-SCU */ +#define RCAR_PWRSR5 U(0xE61801C0) /* Power stat A57-SCU */ +#define RCAR_SYSCIER U(0xE618000C) /* Interrupt enable */ +#define RCAR_SYSCIMR U(0xE6180010) /* Interrupt mask */ +#define RCAR_SYSCSR U(0xE6180000) /* SYSC status */ +#define RCAR_PWRONCR3 U(0xE618014C) /* Power resume A53-SCU */ +#define RCAR_PWRONCR5 U(0xE61801CC) /* Power resume A57-SCU */ +#define RCAR_PWROFFCR3 U(0xE6180144) /* Power shutoff A53-SCU */ +#define RCAR_PWROFFCR5 U(0xE61801C4) /* Power shutoff A57-SCU */ +#define RCAR_PWRER3 U(0xE6180154) /* shutoff/resume error */ +#define RCAR_PWRER5 U(0xE61801D4) /* shutoff/resume error */ +#define RCAR_SYSCISR U(0xE6180004) /* Interrupt status */ +#define RCAR_SYSCISCR U(0xE6180008) /* Interrupt stat clear */ +/* Product register */ +#define RCAR_PRR U(0xFFF00044) +#define RCAR_M3_CUT_VER11 U(0x00000010) /* M3 Ver.1.1/Ver.1.2 */ +#define RCAR_MAJOR_MASK U(0x000000F0) +#define RCAR_MINOR_MASK U(0x0000000F) +#define PRR_PRODUCT_SHIFT U(8) +#define RCAR_MAJOR_SHIFT U(4) +#define RCAR_MINOR_SHIFT U(0) +#define RCAR_MAJOR_OFFSET U(1) +#define RCAR_M3_MINOR_OFFSET U(2) +#define PRR_PRODUCT_H3_CUT10 (PRR_PRODUCT_H3 | U(0x00)) /* 1.0 */ +#define PRR_PRODUCT_H3_CUT11 (PRR_PRODUCT_H3 | U(0x01)) /* 1.1 */ +#define PRR_PRODUCT_H3_CUT20 (PRR_PRODUCT_H3 | U(0x10)) /* 2.0 */ +#define PRR_PRODUCT_M3_CUT10 (PRR_PRODUCT_M3 | U(0x00)) /* 1.0 */ +#define PRR_PRODUCT_M3_CUT11 (PRR_PRODUCT_M3 | U(0x10)) +#define PRR 0xFFF00044U +#define PRR_PRODUCT_MASK 0x00007F00U +#define PRR_CUT_MASK 0x000000FFU +#define PRR_PRODUCT_H3 0x00004F00U /* R-Car H3 */ +#define PRR_PRODUCT_M3 0x00005200U /* R-Car M3-W */ +#define PRR_PRODUCT_V3M 0x00005400U /* R-Car V3M */ +#define PRR_PRODUCT_M3N 0x00005500U /* R-Car M3-N */ +#define PRR_PRODUCT_V3H 0x00005600U /* R-Car V3H */ +#define PRR_PRODUCT_E3 0x00005700U /* R-Car E3 */ +#define PRR_PRODUCT_D3 0x00005800U /* R-Car D3 */ +#define PRR_PRODUCT_10 0x00U /* Ver.1.0 */ +#define PRR_PRODUCT_11 0x01U /* Ver.1.1 */ +#define PRR_PRODUCT_20 0x10U /* Ver.2.0 */ +#define PRR_PRODUCT_21 0x11U /* Ver.2.1 */ +#define PRR_PRODUCT_30 0x20U /* Ver.3.0 */ +#define RCAR_CPU_MASK_CA57 U(0x80000000) +#define RCAR_CPU_MASK_CA53 U(0x04000000) +#define RCAR_CPU_HAVE_CA57 U(0x00000000) +#define RCAR_CPU_HAVE_CA53 U(0x00000000) +#define RCAR_SSCG_MASK U(0x1000) /* MD12 */ +#define RCAR_SSCG_ENABLE U(0x1000) +/* MD pin information */ +#define MODEMR_BOOT_CPU_MASK U(0x000000C0) +#define MODEMR_BOOT_CPU_CR7 U(0x000000C0) +#define MODEMR_BOOT_CPU_CA57 U(0x00000000) +#define MODEMR_BOOT_CPU_CA53 U(0x00000040) +#define MODEMR_BOOT_DEV_MASK U(0x0000001E) +#define MODEMR_BOOT_DEV_HYPERFLASH160 U(0x00000004) +#define MODEMR_BOOT_DEV_HYPERFLASH80 U(0x00000006) +#define MODEMR_BOOT_DEV_QSPI_FLASH40 U(0x00000008) +#define MODEMR_BOOT_DEV_QSPI_FLASH80 U(0x0000000C) +#define MODEMR_BOOT_DEV_EMMC_25X1 U(0x0000000A) +#define MODEMR_BOOT_DEV_EMMC_50X8 U(0x0000001A) +#define MODEMR_BOOT_PLL_MASK U(0x00006000) +#define MODEMR_BOOT_PLL_SHIFT U(13) +/* Memory mapped Generic timer interfaces */ +#define ARM_SYS_CNTCTL_BASE RCAR_CNTC_BASE +/* MODEMR PLL masks and bitfield values */ +#define CHECK_MD13_MD14 U(0x6000) +#define MD14_MD13_TYPE_0 U(0x0000) /* MD14=0 MD13=0 */ +#define MD14_MD13_TYPE_1 U(0x2000) /* MD14=0 MD13=1 */ +#define MD14_MD13_TYPE_2 U(0x4000) /* MD14=1 MD13=0 */ +#define MD14_MD13_TYPE_3 U(0x6000) /* MD14=1 MD13=1 */ +/* Frequency of EXTAL(Hz) */ +#define EXTAL_MD14_MD13_TYPE_0 U(8333300) /* MD14=0 MD13=0 */ +#define EXTAL_MD14_MD13_TYPE_1 U(10000000) /* MD14=0 MD13=1 */ +#define EXTAL_MD14_MD13_TYPE_2 U(12500000) /* MD14=1 MD13=0 */ +#define EXTAL_MD14_MD13_TYPE_3 U(16666600) /* MD14=1 MD13=1 */ +#define EXTAL_SALVATOR_XS U(8320000) /* Salvator-XS */ +#define EXTAL_EBISU U(24000000) /* Ebisu */ +#define EXTAL_DRAAK U(24000000) /* Draak */ +/* CPG write protect registers */ +#define CPGWPR_PASSWORD (0x5A5AFFFFU) +#define CPGWPCR_PASSWORD (0xA5A50000U) +/* CA5x Debug Resource control registers */ +#define CPG_CA57DBGRCR (CPG_BASE + 0x2180U) +#define CPG_CA53DBGRCR (CPG_BASE + 0x1180U) +#define DBGCPUPREN ((uint32_t)1U << 19U) +#define CPG_PLL0CR (CPG_BASE + 0x00D8U) +#define CPG_PLL2CR (CPG_BASE + 0x002CU) +#define CPG_PLL4CR (CPG_BASE + 0x01F4U) +#define CPG_CPGWPCR (CPG_BASE + 0x0904U) +/* RST Registers */ +#define RST_BASE (0xE6160000U) +#define RST_WDTRSTCR (RST_BASE + 0x0054U) +#define RST_MODEMR (RST_BASE + 0x0060U) +#define WDTRSTCR_PASSWORD (0xA55A0000U) +#define WDTRSTCR_RWDT_RSTMSK ((uint32_t)1U << 0U) +/* MFIS Registers */ +#define MFISWPCNTR_PASSWORD (0xACCE0000U) +#define MFISWPCNTR (0xE6260900U) +/* IPMMU registers */ +#define IPMMU_MM_BASE (0xE67B0000U) +#define IPMMUMM_IMSCTLR (IPMMU_MM_BASE + 0x0500U) +#define IPMMUMM_IMAUXCTLR (IPMMU_MM_BASE + 0x0504U) +#define IPMMUMM_IMSCTLR_ENABLE (0xC0000000U) +#define IPMMUMM_IMAUXCTLR_NMERGE40_BIT (0x01000000U) +#define IMSCTLR_DISCACHE (0xE0000000U) +#define IPMMU_VP0_BASE (0xFE990000U) +#define IPMMUVP0_IMSCTLR (IPMMU_VP0_BASE + 0x0500U) +#define IPMMU_VI0_BASE (0xFEBD0000U) +#define IPMMUVI0_IMSCTLR (IPMMU_VI0_BASE + 0x0500U) +#define IPMMU_VI1_BASE (0xFEBE0000U) +#define IPMMUVI1_IMSCTLR (IPMMU_VI1_BASE + 0x0500U) +#define IPMMU_PV0_BASE (0xFD800000U) +#define IPMMUPV0_IMSCTLR (IPMMU_PV0_BASE + 0x0500U) +#define IPMMU_PV1_BASE (0xFD950000U) +#define IPMMUPV1_IMSCTLR (IPMMU_PV1_BASE + 0x0500U) +#define IPMMU_PV2_BASE (0xFD960000U) +#define IPMMUPV2_IMSCTLR (IPMMU_PV2_BASE + 0x0500U) +#define IPMMU_PV3_BASE (0xFD970000U) +#define IPMMUPV3_IMSCTLR (IPMMU_PV3_BASE + 0x0500U) +#define IPMMU_HC_BASE (0xE6570000U) +#define IPMMUHC_IMSCTLR (IPMMU_HC_BASE + 0x0500U) +#define IPMMU_RT_BASE (0xFFC80000U) +#define IPMMURT_IMSCTLR (IPMMU_RT_BASE + 0x0500U) +#define IPMMU_MP_BASE (0xEC670000U) +#define IPMMUMP_IMSCTLR (IPMMU_MP_BASE + 0x0500U) +#define IPMMU_DS0_BASE (0xE6740000U) +#define IPMMUDS0_IMSCTLR (IPMMU_DS0_BASE + 0x0500U) +#define IPMMU_DS1_BASE (0xE7740000U) +#define IPMMUDS1_IMSCTLR (IPMMU_DS1_BASE + 0x0500U) +/* ARMREG registers */ +#define P_ARMREG_SEC_CTRL (0xE62711F0U) +#define P_ARMREG_SEC_CTRL_PROT (0x00000001U) +/* MIDR */ +#define MIDR_CA57 (0x0D07U << MIDR_PN_SHIFT) +#define MIDR_CA53 (0x0D03U << MIDR_PN_SHIFT) +/* for SuspendToRAM */ +#define GPIO_BASE (0xE6050000U) +#define GPIO_INDT1 (GPIO_BASE + 0x100CU) +#define GPIO_INDT3 (GPIO_BASE + 0x300CU) +#define GPIO_INDT6 (GPIO_BASE + 0x540CU) +#define GPIO_OUTDT1 (GPIO_BASE + 0x1008U) +#define GPIO_OUTDT3 (GPIO_BASE + 0x3008U) +#define GPIO_OUTDT6 (GPIO_BASE + 0x5408U) +#define RCAR_COLD_BOOT (0x00U) +#define RCAR_WARM_BOOT (0x01U) +#if PMIC_ROHM_BD9571 && RCAR_SYSTEM_RESET_KEEPON_DDR +#define KEEP10_MAGIC (0x55U) +#endif +/* lossy registers */ +#define LOSSY_PARAMS_BASE (0x47FD7000U) +#define AXI_DCMPAREACRA0 (0xE6784100U) +#define AXI_DCMPAREACRB0 (0xE6784104U) +#define LOSSY_ENABLE (0x80000000U) +#define LOSSY_DISABLE (0x00000000U) +#define LOSSY_FMT_YUVPLANAR (0x00000000U) +#define LOSSY_FMT_YUV422INTLV (0x20000000U) +#define LOSSY_FMT_ARGB8888 (0x40000000U) +#define LOSSY_ST_ADDR0 (0x54000000U) +#define LOSSY_END_ADDR0 (0x57000000U) +#define LOSSY_FMT0 LOSSY_FMT_YUVPLANAR +#define LOSSY_ENA_DIS0 LOSSY_ENABLE +#define LOSSY_ST_ADDR1 0x0U +#define LOSSY_END_ADDR1 0x0U +#define LOSSY_FMT1 LOSSY_FMT_ARGB8888 +#define LOSSY_ENA_DIS1 LOSSY_DISABLE +#define LOSSY_ST_ADDR2 0x0U +#define LOSSY_END_ADDR2 0x0U +#define LOSSY_FMT2 LOSSY_FMT_YUV422INTLV +#define LOSSY_ENA_DIS2 LOSSY_DISABLE + +#endif /* RCAR_DEF_H */ diff --git a/plat/renesas/common/include/rcar_private.h b/plat/renesas/common/include/rcar_private.h new file mode 100644 index 000000000..36f4ca540 --- /dev/null +++ b/plat/renesas/common/include/rcar_private.h @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef RCAR_PRIVATE_H +#define RCAR_PRIVATE_H + +#include +#include +#include + +#include + +typedef volatile struct mailbox { + unsigned long value __aligned(CACHE_WRITEBACK_GRANULE); +} mailbox_t; + +/* + * This structure represents the superset of information that is passed to + * BL31 e.g. while passing control to it from BL2 which is bl31_params + * and bl31_plat_params and its elements + */ +typedef struct bl2_to_bl31_params_mem { + image_info_t bl32_image_info; + image_info_t bl33_image_info; + entry_point_info_t bl33_ep_info; + entry_point_info_t bl32_ep_info; +} bl2_to_bl31_params_mem_t; + +#if USE_COHERENT_MEM +#define RCAR_INSTANTIATE_LOCK DEFINE_BAKERY_LOCK(rcar_lock); +#define rcar_lock_init() bakery_lock_init(&rcar_lock) +#define rcar_lock_get() bakery_lock_get(&rcar_lock) +#define rcar_lock_release() bakery_lock_release(&rcar_lock) +#else +/* + * Constants to specify how many bakery locks this platform implements. These + * are used if the platform chooses not to use coherent memory for bakery lock + * data structures. + */ +#define RCAR_MAX_BAKERIES 2 +#define RCAR_PWRC_BAKERY_ID 0 + +/* + * Definition of structure which holds platform specific per-cpu data. Currently + * it holds only the bakery lock information for each cpu. Constants to + * specify how many bakeries this platform implements and bakery ids are + * specified in rcar_def.h + */ +typedef struct rcar_cpu_data { + bakery_info_t pcpu_bakery_info[RCAR_MAX_BAKERIES]; +} rcar_cpu_data_t; + +#define RCAR_CPU_DATA_LOCK_OFFSET \ + __builtin_offsetof(rcar_cpu_data_t, pcpu_bakery_info) +/* + * Helper macros for bakery lock api when using the above rcar_cpu_data_t for + * bakery lock data structures. It assumes that the bakery_info is at the + * beginning of the platform specific per-cpu data. + */ +#define rcar_lock_init(_lock_arg) + +#define rcar_lock_get(_lock_arg) \ + bakery_lock_get(_lock_arg, \ + CPU_DATA_PLAT_PCPU_OFFSET + RCAR_CPU_DATA_LOCK_OFFSET) + +#define rcar_lock_release(_lock_arg) \ + bakery_lock_release(_lock_arg, \ + CPU_DATA_PLAT_PCPU_OFFSET + RCAR_CPU_DATA_LOCK_OFFSET) +/* + * Ensure that the size of the RCAR specific per-cpu data structure and the size + * of the memory allocated in generic per-cpu data for the platform are the same + */ +CASSERT(sizeof(rcar_cpu_data_t) == PLAT_PCPU_DATA_SIZE, + rcar_pcpu_data_size_mismatch); +#endif +/* + * Function and variable prototypes + */ +void rcar_configure_mmu_el3(unsigned long total_base, + unsigned long total_size, + unsigned long ro_start, unsigned long ro_limit +#if USE_COHERENT_MEM + , unsigned long coh_start, unsigned long coh_limit +#endif + ); + +void rcar_setup_topology(void); +void rcar_cci_disable(void); +void rcar_cci_enable(void); +void rcar_cci_init(void); + +void plat_invalidate_icache(void); +void plat_cci_disable(void); +void plat_cci_enable(void); +void plat_cci_init(void); + +void mstpcr_write(uint32_t mstpcr, uint32_t mstpsr, uint32_t target_bit); +void cpg_write(uintptr_t regadr, uint32_t regval); + +void rcar_console_boot_init(void); +void rcar_console_boot_end(void); +void rcar_console_runtime_init(void); +void rcar_console_runtime_end(void); + +#endif /* RCAR_PRIVATE_H */ diff --git a/plat/renesas/common/include/rcar_version.h b/plat/renesas/common/include/rcar_version.h new file mode 100644 index 000000000..67cbd71ab --- /dev/null +++ b/plat/renesas/common/include/rcar_version.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef RCAR_VERSION_H +#define RCAR_VERSION_H + +#include + +#define VERSION_OF_RENESAS "2.0.6" +#define VERSION_OF_RENESAS_MAXLEN 128 + +extern const uint8_t version_of_renesas[VERSION_OF_RENESAS_MAXLEN]; + +#endif /* RCAR_VERSION_H */ diff --git a/plat/renesas/common/include/registers/axi_registers.h b/plat/renesas/common/include/registers/axi_registers.h new file mode 100644 index 000000000..36cd58bd9 --- /dev/null +++ b/plat/renesas/common/include/registers/axi_registers.h @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef AXI_REGISTERS_H +#define AXI_REGISTERS_H + +/* AXI registers */ + +/* AXI base address */ +#define AXI_BASE (0xE6780000U) + +/* address split */ + +/* AXI address split control 0 */ +#define AXI_ADSPLCR0 (AXI_BASE + 0x4008U) +/* AXI address split control 1 */ +#define AXI_ADSPLCR1 (AXI_BASE + 0x400CU) +/* AXI address split control 2 */ +#define AXI_ADSPLCR2 (AXI_BASE + 0x4010U) +/* AXI address split control 3 */ +#define AXI_ADSPLCR3 (AXI_BASE + 0x4014U) + +/* functional safety */ + +/* AXI functional safety control */ +#define AXI_FUSACR (AXI_BASE + 0x4020U) + +/* decompression */ + +/* AXI decompression area configuration A0 */ +#define AXI_DCMPAREACRA0 (AXI_BASE + 0x4100U) +/* AXI decompression area configuration B0 */ +#define AXI_DCMPAREACRB0 (AXI_BASE + 0x4104U) +/* AXI decompression area configuration A1 */ +#define AXI_DCMPAREACRA1 (AXI_BASE + 0x4108U) +/* AXI decompression area configuration B1 */ +#define AXI_DCMPAREACRB1 (AXI_BASE + 0x410CU) +/* AXI decompression area configuration A2 */ +#define AXI_DCMPAREACRA2 (AXI_BASE + 0x4110U) +/* AXI decompression area configuration B2 */ +#define AXI_DCMPAREACRB2 (AXI_BASE + 0x4114U) +/* AXI decompression area configuration A3 */ +#define AXI_DCMPAREACRA3 (AXI_BASE + 0x4118U) +/* AXI decompression area configuration B3 */ +#define AXI_DCMPAREACRB3 (AXI_BASE + 0x411CU) +/* AXI decompression area configuration A4 */ +#define AXI_DCMPAREACRA4 (AXI_BASE + 0x4120U) +/* AXI decompression area configuration B4 */ +#define AXI_DCMPAREACRB4 (AXI_BASE + 0x4124U) +/* AXI decompression area configuration A5 */ +#define AXI_DCMPAREACRA5 (AXI_BASE + 0x4128U) +/* AXI decompression area configuration B5 */ +#define AXI_DCMPAREACRB5 (AXI_BASE + 0x412CU) +/* AXI decompression area configuration A6 */ +#define AXI_DCMPAREACRA6 (AXI_BASE + 0x4130U) +/* AXI decompression area configuration B6 */ +#define AXI_DCMPAREACRB6 (AXI_BASE + 0x4134U) +/* AXI decompression area configuration A7 */ +#define AXI_DCMPAREACRA7 (AXI_BASE + 0x4138U) +/* AXI decompression area configuration B7 */ +#define AXI_DCMPAREACRB7 (AXI_BASE + 0x413CU) +/* AXI decompression area configuration A8 */ +#define AXI_DCMPAREACRA8 (AXI_BASE + 0x4140U) +/* AXI decompression area configuration B8 */ +#define AXI_DCMPAREACRB8 (AXI_BASE + 0x4144U) +/* AXI decompression area configuration A9 */ +#define AXI_DCMPAREACRA9 (AXI_BASE + 0x4148U) +/* AXI decompression area configuration B9 */ +#define AXI_DCMPAREACRB9 (AXI_BASE + 0x414CU) +/* AXI decompression area configuration A10 */ +#define AXI_DCMPAREACRA10 (AXI_BASE + 0x4150U) +/* AXI decompression area configuration B10 */ +#define AXI_DCMPAREACRB10 (AXI_BASE + 0x4154U) +/* AXI decompression area configuration A11 */ +#define AXI_DCMPAREACRA11 (AXI_BASE + 0x4158U) +/* AXI decompression area configuration B11 */ +#define AXI_DCMPAREACRB11 (AXI_BASE + 0x415CU) +/* AXI decompression area configuration A12 */ +#define AXI_DCMPAREACRA12 (AXI_BASE + 0x4160U) +/* AXI decompression area configuration B12 */ +#define AXI_DCMPAREACRB12 (AXI_BASE + 0x4164U) +/* AXI decompression area configuration A13 */ +#define AXI_DCMPAREACRA13 (AXI_BASE + 0x4168U) +/* AXI decompression area configuration B13 */ +#define AXI_DCMPAREACRB13 (AXI_BASE + 0x416CU) +/* AXI decompression area configuration A14 */ +#define AXI_DCMPAREACRA14 (AXI_BASE + 0x4170U) +/* AXI decompression area configuration B14 */ +#define AXI_DCMPAREACRB14 (AXI_BASE + 0x4174U) +/* AXI decompression area configuration A15 */ +#define AXI_DCMPAREACRA15 (AXI_BASE + 0x4178U) +/* AXI decompression area configuration B15 */ +#define AXI_DCMPAREACRB15 (AXI_BASE + 0x417CU) +/* AXI decompression shadow area configuration */ +#define AXI_DCMPSHDWCR (AXI_BASE + 0x4280U) + +/* SDRAM protection */ + +/* AXI dram protected area division 0 */ +#define AXI_DPTDIVCR0 (AXI_BASE + 0x4400U) +/* AXI dram protected area division 1 */ +#define AXI_DPTDIVCR1 (AXI_BASE + 0x4404U) +/* AXI dram protected area division 2 */ +#define AXI_DPTDIVCR2 (AXI_BASE + 0x4408U) +/* AXI dram protected area division 3 */ +#define AXI_DPTDIVCR3 (AXI_BASE + 0x440CU) +/* AXI dram protected area division 4 */ +#define AXI_DPTDIVCR4 (AXI_BASE + 0x4410U) +/* AXI dram protected area division 5 */ +#define AXI_DPTDIVCR5 (AXI_BASE + 0x4414U) +/* AXI dram protected area division 6 */ +#define AXI_DPTDIVCR6 (AXI_BASE + 0x4418U) +/* AXI dram protected area division 7 */ +#define AXI_DPTDIVCR7 (AXI_BASE + 0x441CU) +/* AXI dram protected area division 8 */ +#define AXI_DPTDIVCR8 (AXI_BASE + 0x4420U) +/* AXI dram protected area division 9 */ +#define AXI_DPTDIVCR9 (AXI_BASE + 0x4424U) +/* AXI dram protected area division 10 */ +#define AXI_DPTDIVCR10 (AXI_BASE + 0x4428U) +/* AXI dram protected area division 11 */ +#define AXI_DPTDIVCR11 (AXI_BASE + 0x442CU) +/* AXI dram protected area division 12 */ +#define AXI_DPTDIVCR12 (AXI_BASE + 0x4430U) +/* AXI dram protected area division 13 */ +#define AXI_DPTDIVCR13 (AXI_BASE + 0x4434U) +/* AXI dram protected area division 14 */ +#define AXI_DPTDIVCR14 (AXI_BASE + 0x4438U) + +/* AXI dram protected area setting 0 */ +#define AXI_DPTCR0 (AXI_BASE + 0x4440U) +/* AXI dram protected area setting 1 */ +#define AXI_DPTCR1 (AXI_BASE + 0x4444U) +/* AXI dram protected area setting 2 */ +#define AXI_DPTCR2 (AXI_BASE + 0x4448U) +/* AXI dram protected area setting 3 */ +#define AXI_DPTCR3 (AXI_BASE + 0x444CU) +/* AXI dram protected area setting 4 */ +#define AXI_DPTCR4 (AXI_BASE + 0x4450U) +/* AXI dram protected area setting 5 */ +#define AXI_DPTCR5 (AXI_BASE + 0x4454U) +/* AXI dram protected area setting 6 */ +#define AXI_DPTCR6 (AXI_BASE + 0x4458U) +/* AXI dram protected area setting 7 */ +#define AXI_DPTCR7 (AXI_BASE + 0x445CU) +/* AXI dram protected area setting 8 */ +#define AXI_DPTCR8 (AXI_BASE + 0x4460U) +/* AXI dram protected area setting 9 */ +#define AXI_DPTCR9 (AXI_BASE + 0x4464U) +/* AXI dram protected area setting 10 */ +#define AXI_DPTCR10 (AXI_BASE + 0x4468U) +/* AXI dram protected area setting 11 */ +#define AXI_DPTCR11 (AXI_BASE + 0x446CU) +/* AXI dram protected area setting 12 */ +#define AXI_DPTCR12 (AXI_BASE + 0x4470U) +/* AXI dram protected area setting 13 */ +#define AXI_DPTCR13 (AXI_BASE + 0x4474U) +/* AXI dram protected area setting 14 */ +#define AXI_DPTCR14 (AXI_BASE + 0x4478U) +/* AXI dram protected area setting 15 */ +#define AXI_DPTCR15 (AXI_BASE + 0x447CU) + +/* SRAM protection */ + +/* AXI sram protected area division 0 */ +#define AXI_SPTDIVCR0 (AXI_BASE + 0x4500U) +/* AXI sram protected area division 1 */ +#define AXI_SPTDIVCR1 (AXI_BASE + 0x4504U) +/* AXI sram protected area division 2 */ +#define AXI_SPTDIVCR2 (AXI_BASE + 0x4508U) +/* AXI sram protected area division 3 */ +#define AXI_SPTDIVCR3 (AXI_BASE + 0x450CU) +/* AXI sram protected area division 4 */ +#define AXI_SPTDIVCR4 (AXI_BASE + 0x4510U) +/* AXI sram protected area division 5 */ +#define AXI_SPTDIVCR5 (AXI_BASE + 0x4514U) +/* AXI sram protected area division 6 */ +#define AXI_SPTDIVCR6 (AXI_BASE + 0x4518U) +/* AXI sram protected area division 7 */ +#define AXI_SPTDIVCR7 (AXI_BASE + 0x451CU) +/* AXI sram protected area division 8 */ +#define AXI_SPTDIVCR8 (AXI_BASE + 0x4520U) +/* AXI sram protected area division 9 */ +#define AXI_SPTDIVCR9 (AXI_BASE + 0x4524U) +/* AXI sram protected area division 10 */ +#define AXI_SPTDIVCR10 (AXI_BASE + 0x4528U) +/* AXI sram protected area division 11 */ +#define AXI_SPTDIVCR11 (AXI_BASE + 0x452CU) +/* AXI sram protected area division 12 */ +#define AXI_SPTDIVCR12 (AXI_BASE + 0x4530U) +/* AXI sram protected area division 13 */ +#define AXI_SPTDIVCR13 (AXI_BASE + 0x4534U) +/* AXI sram protected area division 14 */ +#define AXI_SPTDIVCR14 (AXI_BASE + 0x4538U) + +/* AXI sram protected area setting 0 */ +#define AXI_SPTCR0 (AXI_BASE + 0x4540U) +/* AXI sram protected area setting 1 */ +#define AXI_SPTCR1 (AXI_BASE + 0x4544U) +/* AXI sram protected area setting 2 */ +#define AXI_SPTCR2 (AXI_BASE + 0x4548U) +/* AXI sram protected area setting 3 */ +#define AXI_SPTCR3 (AXI_BASE + 0x454CU) +/* AXI sram protected area setting 4 */ +#define AXI_SPTCR4 (AXI_BASE + 0x4550U) +/* AXI sram protected area setting 5 */ +#define AXI_SPTCR5 (AXI_BASE + 0x4554U) +/* AXI sram protected area setting 6 */ +#define AXI_SPTCR6 (AXI_BASE + 0x4558U) +/* AXI sram protected area setting 7 */ +#define AXI_SPTCR7 (AXI_BASE + 0x455CU) +/* AXI sram protected area setting 8 */ +#define AXI_SPTCR8 (AXI_BASE + 0x4560U) +/* AXI sram protected area setting 9 */ +#define AXI_SPTCR9 (AXI_BASE + 0x4564U) +/* AXI sram protected area setting 10 */ +#define AXI_SPTCR10 (AXI_BASE + 0x4568U) +/* AXI sram protected area setting 11 */ +#define AXI_SPTCR11 (AXI_BASE + 0x456CU) +/* AXI sram protected area setting 12 */ +#define AXI_SPTCR12 (AXI_BASE + 0x4570U) +/* AXI sram protected area setting 13 */ +#define AXI_SPTCR13 (AXI_BASE + 0x4574U) +/* AXI sram protected area setting 14 */ +#define AXI_SPTCR14 (AXI_BASE + 0x4578U) +/* AXI sram protected area setting 15 */ +#define AXI_SPTCR15 (AXI_BASE + 0x457CU) + +/* EDC base address */ +#define EDC_BASE (0xFF840000U) + +/* EDC edc enable */ +#define EDC_EDCEN (EDC_BASE + 0x0010U) +/* EDC edc status 0 */ +#define EDC_EDCST0 (EDC_BASE + 0x0020U) +/* EDC edc status 1 */ +#define EDC_EDCST1 (EDC_BASE + 0x0024U) +/* EDC edc interrupt enable 0 */ +#define EDC_EDCINTEN0 (EDC_BASE + 0x0040U) +/* EDC edc interrupt enable 1 */ +#define EDC_EDCINTEN1 (EDC_BASE + 0x0044U) + +#endif /* AXI_REGISTERS_H */ diff --git a/plat/renesas/common/include/registers/cpg_registers.h b/plat/renesas/common/include/registers/cpg_registers.h new file mode 100644 index 000000000..0d698d9c1 --- /dev/null +++ b/plat/renesas/common/include/registers/cpg_registers.h @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CPG_REGISTERS_H +#define CPG_REGISTERS_H + +/* CPG base address */ +#define CPG_BASE (0xE6150000U) + +/* CPG system module stop control 2 */ +#define CPG_SMSTPCR2 (CPG_BASE + 0x0138U) +/* CPG software reset 2 */ +#define CPG_SRCR2 (CPG_BASE + 0x00B0U) +/* CPG module stop status 2 */ +#define CPG_MSTPSR2 (CPG_BASE + 0x0040U) +/* CPG write protect */ +#define CPG_CPGWPR (CPG_BASE + 0x0900U) +/* CPG write protect control */ +#define CPG_CPGWPCR (CPG_BASE + 0x0904U) +/* CPG system module stop control 9 */ +#define CPG_SMSTPCR9 (CPG_BASE + 0x0994U) +/* CPG module stop status 9 */ +#define CPG_MSTPSR9 (CPG_BASE + 0x09A4U) + +/* CPG (SECURITY) registers */ + +/* Secure Module Stop Control Register 0 */ +#define SCMSTPCR0 (CPG_BASE + 0x0B20U) +/* Secure Module Stop Control Register 1 */ +#define SCMSTPCR1 (CPG_BASE + 0x0B24U) +/* Secure Module Stop Control Register 2 */ +#define SCMSTPCR2 (CPG_BASE + 0x0B28U) +/* Secure Module Stop Control Register 3 */ +#define SCMSTPCR3 (CPG_BASE + 0x0B2CU) +/* Secure Module Stop Control Register 4 */ +#define SCMSTPCR4 (CPG_BASE + 0x0B30U) +/* Secure Module Stop Control Register 5 */ +#define SCMSTPCR5 (CPG_BASE + 0x0B34U) +/* Secure Module Stop Control Register 6 */ +#define SCMSTPCR6 (CPG_BASE + 0x0B38U) +/* Secure Module Stop Control Register 7 */ +#define SCMSTPCR7 (CPG_BASE + 0x0B3CU) +/* Secure Module Stop Control Register 8 */ +#define SCMSTPCR8 (CPG_BASE + 0x0B40U) +/* Secure Module Stop Control Register 9 */ +#define SCMSTPCR9 (CPG_BASE + 0x0B44U) +/* Secure Module Stop Control Register 10 */ +#define SCMSTPCR10 (CPG_BASE + 0x0B48U) +/* Secure Module Stop Control Register 11 */ +#define SCMSTPCR11 (CPG_BASE + 0x0B4CU) + +/* CPG (SECURITY) registers */ + +/* Secure Software Reset Access Enable Control Register 0 */ +#define SCSRSTECR0 (CPG_BASE + 0x0B80U) +/* Secure Software Reset Access Enable Control Register 1 */ +#define SCSRSTECR1 (CPG_BASE + 0x0B84U) +/* Secure Software Reset Access Enable Control Register 2 */ +#define SCSRSTECR2 (CPG_BASE + 0x0B88U) +/* Secure Software Reset Access Enable Control Register 3 */ +#define SCSRSTECR3 (CPG_BASE + 0x0B8CU) +/* Secure Software Reset Access Enable Control Register 4 */ +#define SCSRSTECR4 (CPG_BASE + 0x0B90U) +/* Secure Software Reset Access Enable Control Register 5 */ +#define SCSRSTECR5 (CPG_BASE + 0x0B94U) +/* Secure Software Reset Access Enable Control Register 6 */ +#define SCSRSTECR6 (CPG_BASE + 0x0B98U) +/* Secure Software Reset Access Enable Control Register 7 */ +#define SCSRSTECR7 (CPG_BASE + 0x0B9CU) +/* Secure Software Reset Access Enable Control Register 8 */ +#define SCSRSTECR8 (CPG_BASE + 0x0BA0U) +/* Secure Software Reset Access Enable Control Register 9 */ +#define SCSRSTECR9 (CPG_BASE + 0x0BA4U) +/* Secure Software Reset Access Enable Control Register 10 */ +#define SCSRSTECR10 (CPG_BASE + 0x0BA8U) +/* Secure Software Reset Access Enable Control Register 11 */ +#define SCSRSTECR11 (CPG_BASE + 0x0BACU) + +/* CPG (REALTIME) registers */ + +/* Realtime Module Stop Control Register 0 */ +#define RMSTPCR0 (CPG_BASE + 0x0110U) +/* Realtime Module Stop Control Register 1 */ +#define RMSTPCR1 (CPG_BASE + 0x0114U) +/* Realtime Module Stop Control Register 2 */ +#define RMSTPCR2 (CPG_BASE + 0x0118U) +/* Realtime Module Stop Control Register 3 */ +#define RMSTPCR3 (CPG_BASE + 0x011CU) +/* Realtime Module Stop Control Register 4 */ +#define RMSTPCR4 (CPG_BASE + 0x0120U) +/* Realtime Module Stop Control Register 5 */ +#define RMSTPCR5 (CPG_BASE + 0x0124U) +/* Realtime Module Stop Control Register 6 */ +#define RMSTPCR6 (CPG_BASE + 0x0128U) +/* Realtime Module Stop Control Register 7 */ +#define RMSTPCR7 (CPG_BASE + 0x012CU) +/* Realtime Module Stop Control Register 8 */ +#define RMSTPCR8 (CPG_BASE + 0x0980U) +/* Realtime Module Stop Control Register 9 */ +#define RMSTPCR9 (CPG_BASE + 0x0984U) +/* Realtime Module Stop Control Register 10 */ +#define RMSTPCR10 (CPG_BASE + 0x0988U) +/* Realtime Module Stop Control Register 11 */ +#define RMSTPCR11 (CPG_BASE + 0x098CU) + +/* CPG (SYSTEM) registers */ + +/* System Module Stop Control Register 0 */ +#define SMSTPCR0 (CPG_BASE + 0x0130U) +/* System Module Stop Control Register 1 */ +#define SMSTPCR1 (CPG_BASE + 0x0134U) +/* System Module Stop Control Register 2 */ +#define SMSTPCR2 (CPG_BASE + 0x0138U) +/* System Module Stop Control Register 3 */ +#define SMSTPCR3 (CPG_BASE + 0x013CU) +/* System Module Stop Control Register 4 */ +#define SMSTPCR4 (CPG_BASE + 0x0140U) +/* System Module Stop Control Register 5 */ +#define SMSTPCR5 (CPG_BASE + 0x0144U) +/* System Module Stop Control Register 6 */ +#define SMSTPCR6 (CPG_BASE + 0x0148U) +/* System Module Stop Control Register 7 */ +#define SMSTPCR7 (CPG_BASE + 0x014CU) +/* System Module Stop Control Register 8 */ +#define SMSTPCR8 (CPG_BASE + 0x0990U) +/* System Module Stop Control Register 9 */ +#define SMSTPCR9 (CPG_BASE + 0x0994U) +/* System Module Stop Control Register 10 */ +#define SMSTPCR10 (CPG_BASE + 0x0998U) +/* System Module Stop Control Register 11 */ +#define SMSTPCR11 (CPG_BASE + 0x099CU) + +#endif /* CPG_REGISTERS_H */ diff --git a/plat/renesas/common/include/registers/lifec_registers.h b/plat/renesas/common/include/registers/lifec_registers.h new file mode 100644 index 000000000..5f49e52c0 --- /dev/null +++ b/plat/renesas/common/include/registers/lifec_registers.h @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef LIFEC_REGISTERS_H +#define LIFEC_REGISTERS_H + +#define LIFEC_SEC_BASE (0xE6110000U) + +#define SEC_SRC (LIFEC_SEC_BASE + 0x0008U) +#define SEC_SEL0 (LIFEC_SEC_BASE + 0x0030U) +#define SEC_SEL1 (LIFEC_SEC_BASE + 0x0034U) +#define SEC_SEL2 (LIFEC_SEC_BASE + 0x0038U) +#define SEC_SEL3 (LIFEC_SEC_BASE + 0x003CU) +#define SEC_SEL4 (LIFEC_SEC_BASE + 0x0058U) +#define SEC_SEL5 (LIFEC_SEC_BASE + 0x005CU) +#define SEC_SEL6 (LIFEC_SEC_BASE + 0x0060U) +#define SEC_SEL7 (LIFEC_SEC_BASE + 0x0064U) +#define SEC_SEL8 (LIFEC_SEC_BASE + 0x0068U) +#define SEC_SEL9 (LIFEC_SEC_BASE + 0x006CU) +#define SEC_SEL10 (LIFEC_SEC_BASE + 0x0070U) +#define SEC_SEL11 (LIFEC_SEC_BASE + 0x0074U) +#define SEC_SEL12 (LIFEC_SEC_BASE + 0x0078U) +#define SEC_SEL13 (LIFEC_SEC_BASE + 0x007CU) +#define SEC_SEL14 (LIFEC_SEC_BASE + 0x0080U) +#define SEC_SEL15 (LIFEC_SEC_BASE + 0x0084U) +#define SEC_GRP0CR0 (LIFEC_SEC_BASE + 0x0138U) +#define SEC_GRP1CR0 (LIFEC_SEC_BASE + 0x013CU) +#define SEC_GRP0CR1 (LIFEC_SEC_BASE + 0x0140U) +#define SEC_GRP1CR1 (LIFEC_SEC_BASE + 0x0144U) +#define SEC_GRP0CR2 (LIFEC_SEC_BASE + 0x0148U) +#define SEC_GRP1CR2 (LIFEC_SEC_BASE + 0x014CU) +#define SEC_GRP0CR3 (LIFEC_SEC_BASE + 0x0150U) +#define SEC_GRP1CR3 (LIFEC_SEC_BASE + 0x0154U) +#define SEC_GRP0COND0 (LIFEC_SEC_BASE + 0x0158U) +#define SEC_GRP1COND0 (LIFEC_SEC_BASE + 0x015CU) +#define SEC_GRP0COND1 (LIFEC_SEC_BASE + 0x0160U) +#define SEC_GRP1COND1 (LIFEC_SEC_BASE + 0x0164U) +#define SEC_GRP0COND2 (LIFEC_SEC_BASE + 0x0168U) +#define SEC_GRP1COND2 (LIFEC_SEC_BASE + 0x016CU) +#define SEC_GRP0COND3 (LIFEC_SEC_BASE + 0x0170U) +#define SEC_GRP1COND3 (LIFEC_SEC_BASE + 0x0174U) +#define SEC_GRP0COND4 (LIFEC_SEC_BASE + 0x0178U) +#define SEC_GRP1COND4 (LIFEC_SEC_BASE + 0x017CU) +#define SEC_GRP0COND5 (LIFEC_SEC_BASE + 0x0180U) +#define SEC_GRP1COND5 (LIFEC_SEC_BASE + 0x0184U) +#define SEC_GRP0COND6 (LIFEC_SEC_BASE + 0x0188U) +#define SEC_GRP1COND6 (LIFEC_SEC_BASE + 0x018CU) +#define SEC_GRP0COND7 (LIFEC_SEC_BASE + 0x0190U) +#define SEC_GRP1COND7 (LIFEC_SEC_BASE + 0x0194U) +#define SEC_GRP0COND8 (LIFEC_SEC_BASE + 0x0198U) +#define SEC_GRP1COND8 (LIFEC_SEC_BASE + 0x019CU) +#define SEC_GRP0COND9 (LIFEC_SEC_BASE + 0x01A0U) +#define SEC_GRP1COND9 (LIFEC_SEC_BASE + 0x01A4U) +#define SEC_GRP0COND10 (LIFEC_SEC_BASE + 0x01A8U) +#define SEC_GRP1COND10 (LIFEC_SEC_BASE + 0x01ACU) +#define SEC_GRP0COND11 (LIFEC_SEC_BASE + 0x01B0U) +#define SEC_GRP1COND11 (LIFEC_SEC_BASE + 0x01B4U) +#define SEC_GRP0COND12 (LIFEC_SEC_BASE + 0x01B8U) +#define SEC_GRP1COND12 (LIFEC_SEC_BASE + 0x01BCU) +#define SEC_GRP0COND13 (LIFEC_SEC_BASE + 0x01C0U) +#define SEC_GRP1COND13 (LIFEC_SEC_BASE + 0x01C4U) +#define SEC_GRP0COND14 (LIFEC_SEC_BASE + 0x01C8U) +#define SEC_GRP1COND14 (LIFEC_SEC_BASE + 0x01CCU) +#define SEC_GRP0COND15 (LIFEC_SEC_BASE + 0x01D0U) +#define SEC_GRP1COND15 (LIFEC_SEC_BASE + 0x01D4U) +#define SEC_READONLY0 (LIFEC_SEC_BASE + 0x01D8U) +#define SEC_READONLY1 (LIFEC_SEC_BASE + 0x01DCU) +#define SEC_READONLY2 (LIFEC_SEC_BASE + 0x01E0U) +#define SEC_READONLY3 (LIFEC_SEC_BASE + 0x01E4U) +#define SEC_READONLY4 (LIFEC_SEC_BASE + 0x01E8U) +#define SEC_READONLY5 (LIFEC_SEC_BASE + 0x01ECU) +#define SEC_READONLY6 (LIFEC_SEC_BASE + 0x01F0U) +#define SEC_READONLY7 (LIFEC_SEC_BASE + 0x01F4U) +#define SEC_READONLY8 (LIFEC_SEC_BASE + 0x01F8U) +#define SEC_READONLY9 (LIFEC_SEC_BASE + 0x01FCU) +#define SEC_READONLY10 (LIFEC_SEC_BASE + 0x0200U) +#define SEC_READONLY11 (LIFEC_SEC_BASE + 0x0204U) +#define SEC_READONLY12 (LIFEC_SEC_BASE + 0x0208U) +#define SEC_READONLY13 (LIFEC_SEC_BASE + 0x020CU) +#define SEC_READONLY14 (LIFEC_SEC_BASE + 0x0210U) +#define SEC_READONLY15 (LIFEC_SEC_BASE + 0x0214U) + +#define LIFEC_SAFE_BASE (0xE6120000U) +#define SAFE_GRP0CR0 (LIFEC_SAFE_BASE + 0x0138U) +#define SAFE_GRP1CR0 (LIFEC_SAFE_BASE + 0x013CU) +#define SAFE_GRP0CR1 (LIFEC_SAFE_BASE + 0x0140U) +#define SAFE_GRP1CR1 (LIFEC_SAFE_BASE + 0x0144U) +#define SAFE_GRP0CR2 (LIFEC_SAFE_BASE + 0x0148U) +#define SAFE_GRP1CR2 (LIFEC_SAFE_BASE + 0x014CU) +#define SAFE_GRP0CR3 (LIFEC_SAFE_BASE + 0x0150U) +#define SAFE_GRP1CR3 (LIFEC_SAFE_BASE + 0x0154U) +#define SAFE_GRP0COND0 (LIFEC_SAFE_BASE + 0x0158U) +#define SAFE_GRP1COND0 (LIFEC_SAFE_BASE + 0x015CU) +#define SAFE_GRP0COND1 (LIFEC_SAFE_BASE + 0x0160U) +#define SAFE_GRP1COND1 (LIFEC_SAFE_BASE + 0x0164U) +#define SAFE_GRP0COND2 (LIFEC_SAFE_BASE + 0x0168U) +#define SAFE_GRP1COND2 (LIFEC_SAFE_BASE + 0x016CU) +#define SAFE_GRP0COND3 (LIFEC_SAFE_BASE + 0x0170U) +#define SAFE_GRP1COND3 (LIFEC_SAFE_BASE + 0x0174U) +#define SAFE_GRP0COND4 (LIFEC_SAFE_BASE + 0x0178U) +#define SAFE_GRP1COND4 (LIFEC_SAFE_BASE + 0x017CU) +#define SAFE_GRP0COND5 (LIFEC_SAFE_BASE + 0x0180U) +#define SAFE_GRP1COND5 (LIFEC_SAFE_BASE + 0x0184U) +#define SAFE_GRP0COND6 (LIFEC_SAFE_BASE + 0x0188U) +#define SAFE_GRP1COND6 (LIFEC_SAFE_BASE + 0x018CU) +#define SAFE_GRP0COND7 (LIFEC_SAFE_BASE + 0x0190U) +#define SAFE_GRP1COND7 (LIFEC_SAFE_BASE + 0x0194U) +#define SAFE_GRP0COND8 (LIFEC_SAFE_BASE + 0x0198U) +#define SAFE_GRP1COND8 (LIFEC_SAFE_BASE + 0x019CU) +#define SAFE_GRP0COND9 (LIFEC_SAFE_BASE + 0x01A0U) +#define SAFE_GRP1COND9 (LIFEC_SAFE_BASE + 0x01A4U) +#define SAFE_GRP0COND10 (LIFEC_SAFE_BASE + 0x01A8U) +#define SAFE_GRP1COND10 (LIFEC_SAFE_BASE + 0x01ACU) +#define SAFE_GRP0COND11 (LIFEC_SAFE_BASE + 0x01B0U) +#define SAFE_GRP1COND11 (LIFEC_SAFE_BASE + 0x01B4U) +#define SAFE_GRP0COND12 (LIFEC_SAFE_BASE + 0x01B8U) +#define SAFE_GRP1COND12 (LIFEC_SAFE_BASE + 0x01BCU) +#define SAFE_GRP0COND13 (LIFEC_SAFE_BASE + 0x01C0U) +#define SAFE_GRP1COND13 (LIFEC_SAFE_BASE + 0x01C4U) +#define SAFE_GRP0COND14 (LIFEC_SAFE_BASE + 0x01C8U) +#define SAFE_GRP1COND14 (LIFEC_SAFE_BASE + 0x01CCU) +#define SAFE_GRP0COND15 (LIFEC_SAFE_BASE + 0x01D0U) +#define SAFE_GRP1COND15 (LIFEC_SAFE_BASE + 0x01D4U) +#define SAFE_READONLY0 (LIFEC_SAFE_BASE + 0x01D8U) +#define SAFE_READONLY1 (LIFEC_SAFE_BASE + 0x01DCU) +#define SAFE_READONLY2 (LIFEC_SAFE_BASE + 0x01E0U) +#define SAFE_READONLY3 (LIFEC_SAFE_BASE + 0x01E4U) +#define SAFE_READONLY4 (LIFEC_SAFE_BASE + 0x01E8U) +#define SAFE_READONLY5 (LIFEC_SAFE_BASE + 0x01ECU) +#define SAFE_READONLY6 (LIFEC_SAFE_BASE + 0x01F0U) +#define SAFE_READONLY7 (LIFEC_SAFE_BASE + 0x01F4U) +#define SAFE_READONLY8 (LIFEC_SAFE_BASE + 0x01F8U) +#define SAFE_READONLY9 (LIFEC_SAFE_BASE + 0x01FCU) +#define SAFE_READONLY10 (LIFEC_SAFE_BASE + 0x0200U) +#define SAFE_READONLY11 (LIFEC_SAFE_BASE + 0x0204U) +#define SAFE_READONLY12 (LIFEC_SAFE_BASE + 0x0208U) +#define SAFE_READONLY13 (LIFEC_SAFE_BASE + 0x020CU) +#define SAFE_READONLY14 (LIFEC_SAFE_BASE + 0x0210U) +#define SAFE_READONLY15 (LIFEC_SAFE_BASE + 0x0214U) + +#endif /* LIFEC_REGISTERS_H */ diff --git a/plat/renesas/rcar/include/plat.ld.S b/plat/renesas/rcar/include/plat.ld.S deleted file mode 100644 index 7aef324c4..000000000 --- a/plat/renesas/rcar/include/plat.ld.S +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ -#ifndef RCAR_PLAT_LD_S -#define RCAR_PLAT_LD_S - -#include -#include - -MEMORY { - SRAM (rwx): ORIGIN = BL31_SRAM_BASE, LENGTH = DEVICE_SRAM_SIZE - PRAM (r): ORIGIN = BL31_LIMIT - DEVICE_SRAM_SIZE, LENGTH = DEVICE_SRAM_SIZE -} - -SECTIONS -{ - /* SRAM_COPY is in PRAM */ - . = BL31_LIMIT - DEVICE_SRAM_SIZE; - __SRAM_COPY_START__ = .; - - .system_ram : { - /* system ram start is in SRAM */ - __system_ram_start__ = .; - *(.system_ram*) - *iic_dvfs.o(.rodata) - __system_ram_end__ = .; - } >SRAM AT>PRAM - - ASSERT(__BL31_END__ <= BL31_LIMIT - DEVICE_SRAM_SIZE, - "BL31 image too large - writing on top of SRAM!") - -} - -#endif /* RCAR_PLAT_LD_S */ diff --git a/plat/renesas/rcar/include/plat_macros.S b/plat/renesas/rcar/include/plat_macros.S deleted file mode 100644 index 927cd39e8..000000000 --- a/plat/renesas/rcar/include/plat_macros.S +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include - -#include "rcar_def.h" - -.section .rodata.gic_reg_name, "aS" -gicc_regs: - .asciz "gicc_hppir", "gicc_ahppir", "gicc_ctlr", "" -gicd_pend_reg: - .asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n Offset:\t\t\tvalue\n" -newline: - .asciz "\n" -spacer: - .asciz ":\t\t0x" - - /* --------------------------------------------- - * The below macro prints out relevant GIC - * registers whenever an unhandled exception is - * taken in BL3-1. - * Clobbers: x0 - x10, x16, x17, sp - * --------------------------------------------- - */ - .macro plat_print_gic_regs - mov_imm x17, RCAR_GICC_BASE - mov_imm x16, RCAR_GICD_BASE -print_gicc_regs: - /* gicc base address is now in x17 */ - adr x6, gicc_regs /* Load the gicc reg list to x6 */ - /* Load the gicc regs to gp regs used by str_in_crash_buf_print */ - ldr w8, [x17, #GICC_HPPIR] - ldr w9, [x17, #GICC_AHPPIR] - ldr w10, [x17, #GICC_CTLR] - /* Store to the crash buf and print to console */ - bl str_in_crash_buf_print - - /* Print the GICD_ISPENDR regs */ - add x7, x16, #GICD_ISPENDR - adr x4, gicd_pend_reg - bl asm_print_str -gicd_ispendr_loop: - sub x4, x7, x16 - cmp x4, #0x280 - b.eq exit_print_gic_regs - bl asm_print_hex - adr x4, spacer - bl asm_print_str - ldr x4, [x7], #8 - bl asm_print_hex - adr x4, newline - bl asm_print_str - b gicd_ispendr_loop -exit_print_gic_regs: - .endm - -.section .rodata.cci_reg_name, "aS" -cci_iface_regs: - .asciz "cci_snoop_ctrl_cluster0", "cci_snoop_ctrl_cluster1" , "" - - /* ------------------------------------------------ - * The below macro prints out relevant interconnect - * registers whenever an unhandled exception is - * taken in BL3-1. - * Clobbers: x0 - x9, sp - * ------------------------------------------------ - */ - .macro plat_print_interconnect_regs - adr x6, cci_iface_regs - /* Store in x7 the base address of the first interface */ - mov_imm x7, (CCI500_BASE + SLAVE_IFACE3_OFFSET) - ldr w8, [x7, #SNOOP_CTRL_REG] - /* Store in x7 the base address of the second interface */ - mov_imm x7, (CCI500_BASE + SLAVE_IFACE4_OFFSET) - ldr w9, [x7, #SNOOP_CTRL_REG] - /* Store to the crash buf and print to console */ - bl str_in_crash_buf_print - .endm - - .macro plat_crash_print_regs - plat_print_gic_regs - plat_print_interconnect_regs - .endm diff --git a/plat/renesas/rcar/include/platform_def.h b/plat/renesas/rcar/include/platform_def.h deleted file mode 100644 index 73787140b..000000000 --- a/plat/renesas/rcar/include/platform_def.h +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef PLATFORM_DEF_H -#define PLATFORM_DEF_H - -#ifndef __ASSEMBLER__ -#include -#endif - -#include - -#include "rcar_def.h" - -/******************************************************************************* - * Platform binary types for linking - ******************************************************************************/ -#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64" -#define PLATFORM_LINKER_ARCH aarch64 - -/******************************************************************************* - * Generic platform constants - ******************************************************************************/ - #define FIRMWARE_WELCOME_STR "Booting Rcar-gen3 Trusted Firmware\n" - -/* Size of cacheable stacks */ -#if IMAGE_BL1 -#if TRUSTED_BOARD_BOOT -#define PLATFORM_STACK_SIZE U(0x1000) -#else -#define PLATFORM_STACK_SIZE U(0x440) -#endif -#elif IMAGE_BL2 -#if TRUSTED_BOARD_BOOT -#define PLATFORM_STACK_SIZE U(0x1000) -#else -#define PLATFORM_STACK_SIZE U(0x400) -#endif -#elif IMAGE_BL31 -#define PLATFORM_STACK_SIZE U(0x400) -#elif IMAGE_BL32 -#define PLATFORM_STACK_SIZE U(0x440) -#endif - -#define BL332_IMAGE_ID (NS_BL2U_IMAGE_ID + 1) -#define BL333_IMAGE_ID (NS_BL2U_IMAGE_ID + 2) -#define BL334_IMAGE_ID (NS_BL2U_IMAGE_ID + 3) -#define BL335_IMAGE_ID (NS_BL2U_IMAGE_ID + 4) -#define BL336_IMAGE_ID (NS_BL2U_IMAGE_ID + 5) -#define BL337_IMAGE_ID (NS_BL2U_IMAGE_ID + 6) -#define BL338_IMAGE_ID (NS_BL2U_IMAGE_ID + 7) - -#define BL332_KEY_CERT_ID (NS_BL2U_IMAGE_ID + 8) -#define BL333_KEY_CERT_ID (NS_BL2U_IMAGE_ID + 9) -#define BL334_KEY_CERT_ID (NS_BL2U_IMAGE_ID + 10) -#define BL335_KEY_CERT_ID (NS_BL2U_IMAGE_ID + 11) -#define BL336_KEY_CERT_ID (NS_BL2U_IMAGE_ID + 12) -#define BL337_KEY_CERT_ID (NS_BL2U_IMAGE_ID + 13) -#define BL338_KEY_CERT_ID (NS_BL2U_IMAGE_ID + 14) - -#define BL332_CERT_ID (NS_BL2U_IMAGE_ID + 15) -#define BL333_CERT_ID (NS_BL2U_IMAGE_ID + 16) -#define BL334_CERT_ID (NS_BL2U_IMAGE_ID + 17) -#define BL335_CERT_ID (NS_BL2U_IMAGE_ID + 18) -#define BL336_CERT_ID (NS_BL2U_IMAGE_ID + 19) -#define BL337_CERT_ID (NS_BL2U_IMAGE_ID + 20) -#define BL338_CERT_ID (NS_BL2U_IMAGE_ID + 21) - -/* io drivers id */ -#define FLASH_DEV_ID U(0) -#define EMMC_DEV_ID U(1) - -/* - * R-Car H3 Cortex-A57 - * L1:I/48KB(16KBx3way) D/32KB(16KBx2way) L2:2MB(128KBx16way) - * Cortex-A53 - * L1:I/32KB(16KBx2way) D/32KB(8KBx4way) L2:512KB(32KBx16way) - */ -#define PLATFORM_CACHE_LINE_SIZE 64 -#define PLATFORM_CLUSTER_COUNT U(2) -#define PLATFORM_CLUSTER0_CORE_COUNT U(4) -#define PLATFORM_CLUSTER1_CORE_COUNT U(4) -#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER1_CORE_COUNT + \ - PLATFORM_CLUSTER0_CORE_COUNT) -#define PLATFORM_MAX_CPUS_PER_CLUSTER U(4) - -#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL2 -#define PLAT_NUM_PWR_DOMAINS (PLATFORM_CORE_COUNT + \ - PLATFORM_CLUSTER_COUNT + 1) - -#define PLAT_MAX_RET_STATE U(1) -#define PLAT_MAX_OFF_STATE U(2) - -#define MAX_IO_DEVICES U(3) -#define MAX_IO_HANDLES U(4) - -/* - ****************************************************************************** - * BL2 specific defines. - ****************************************************************************** - * Put BL2 just below BL3-1. BL2_BASE is calculated using the current BL2 debug - * size plus a little space for growth. - */ -#define RCAR_SYSRAM_BASE U(0xE6300000) -#if (RCAR_LSI == RCAR_E3) || (RCAR_LSI == RCAR_D3) -#define BL2_LIMIT U(0xE6320000) -#else -#define BL2_LIMIT U(0xE6360000) -#endif - -#if (RCAR_LSI == RCAR_E3) || (RCAR_LSI == RCAR_D3) -#define BL2_BASE U(0xE6304000) -#define BL2_IMAGE_LIMIT U(0xE6318000) -#elif (RCAR_LSI == RCAR_V3M) -#define BL2_BASE U(0xE6344000) -#define BL2_IMAGE_LIMIT U(0xE636E800) -#else -#define BL2_BASE U(0xE6304000) -#define BL2_IMAGE_LIMIT U(0xE632E800) -#endif -#define RCAR_SYSRAM_SIZE (BL2_BASE - RCAR_SYSRAM_BASE) - -/* - ****************************************************************************** - * BL31 specific defines. - ****************************************************************************** - * Put BL3-1 at the top of the Trusted SRAM. BL31_BASE is calculated using the - * current BL3-1 debug size plus a little space for growth. - */ -#define BL31_BASE (RCAR_TRUSTED_SRAM_BASE) -#define BL31_LIMIT (RCAR_TRUSTED_SRAM_BASE + \ - RCAR_TRUSTED_SRAM_SIZE) -#define RCAR_BL31_LOG_BASE (0x44040000) -#define RCAR_BL31_SDRAM_BTM (RCAR_BL31_LOG_BASE + 0x14000) -#define RCAR_BL31_LOG_SIZE (RCAR_BL31_SDRAM_BTM - RCAR_BL31_LOG_BASE) -#define BL31_SRAM_BASE (DEVICE_SRAM_BASE) -#define BL31_SRAM_LIMIT (DEVICE_SRAM_BASE + DEVICE_SRAM_SIZE) - -/******************************************************************************* - * BL32 specific defines. - ******************************************************************************/ -#ifndef SPD_NONE -#define BL32_BASE U(0x44100000) -#define BL32_LIMIT (BL32_BASE + U(0x100000)) -#endif - -/******************************************************************************* - * BL33 - ******************************************************************************/ -#define BL33_BASE DRAM1_NS_BASE - - -/******************************************************************************* - * Platform specific page table and MMU setup constants - ******************************************************************************/ -#if IMAGE_BL1 -#define MAX_XLAT_TABLES U(2) -#elif IMAGE_BL2 -#define MAX_XLAT_TABLES U(5) -#elif IMAGE_BL31 -#define MAX_XLAT_TABLES U(4) -#elif IMAGE_BL32 -#define MAX_XLAT_TABLES U(3) -#endif - -#if IMAGE_BL2 -#define PLAT_PHY_ADDR_SPACE_SIZE (ULL(1) << 40) -#define PLAT_VIRT_ADDR_SPACE_SIZE (ULL(1) << 40) -#else -#define PLAT_PHY_ADDR_SPACE_SIZE (ULL(1) << 32) -#define PLAT_VIRT_ADDR_SPACE_SIZE (ULL(1) << 32) -#endif - -#define MAX_MMAP_REGIONS (RCAR_MMAP_ENTRIES + RCAR_BL_REGIONS) - -/******************************************************************************* - * Declarations and constants to access the mailboxes safely. Each mailbox is - * 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. Such alignment ensures that two mailboxes do not sit on the same cache - * line at any cache level. They could belong to different cpus/clusters & - * get written while being protected by different locks causing corruption of - * a valid mailbox address. - ******************************************************************************/ -#define CACHE_WRITEBACK_SHIFT (6) -#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT) - -/******************************************************************************* - * Size of the per-cpu data in bytes that should be reserved in the generic - * per-cpu data structure for the RCAR port. - ******************************************************************************/ -#if !USE_COHERENT_MEM -#define PLAT_PCPU_DATA_SIZE (2) -#endif - -#endif /* PLATFORM_DEF_H */ diff --git a/plat/renesas/rcar/include/rcar_def.h b/plat/renesas/rcar/include/rcar_def.h deleted file mode 100644 index 6c5b29561..000000000 --- a/plat/renesas/rcar/include/rcar_def.h +++ /dev/null @@ -1,310 +0,0 @@ -/* - * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef RCAR_DEF_H -#define RCAR_DEF_H - -#include -#include - -#define RCAR_PRIMARY_CPU 0x0 -#define RCAR_TRUSTED_SRAM_BASE 0x44000000 -#define RCAR_TRUSTED_SRAM_SIZE 0x0003E000 -#define RCAR_SHARED_MEM_BASE (RCAR_TRUSTED_SRAM_BASE + \ - RCAR_TRUSTED_SRAM_SIZE) -#define RCAR_SHARED_MEM_SIZE U(0x00001000) -#define FLASH0_BASE U(0x08000000) -#define FLASH0_SIZE U(0x04000000) -#define FLASH_MEMORY_SIZE U(0x04000000) /* hyper flash */ -#define FLASH_TRANS_SIZE_UNIT U(0x00000100) -#define DEVICE_RCAR_BASE U(0xE6000000) -#define DEVICE_RCAR_SIZE U(0x00300000) -#define DEVICE_RCAR_BASE2 U(0xE6360000) -#define DEVICE_RCAR_SIZE2 U(0x19CA0000) -#define DEVICE_SRAM_BASE U(0xE6300000) -#define DEVICE_SRAM_SIZE U(0x00002000) -#define DEVICE_SRAM_STACK_BASE (DEVICE_SRAM_BASE + DEVICE_SRAM_SIZE) -#define DEVICE_SRAM_STACK_SIZE U(0x00001000) -#define DRAM_LIMIT ULL(0x0000010000000000) -#define DRAM1_BASE U(0x40000000) -#define DRAM1_SIZE U(0x80000000) -#define DRAM1_NS_BASE (DRAM1_BASE + U(0x10000000)) -#define DRAM1_NS_SIZE (DRAM1_SIZE - DRAM1_NS_BASE) -#define DRAM_40BIT_BASE ULL(0x0400000000) -#define DRAM_40BIT_SIZE ULL(0x0400000000) -#define DRAM_PROTECTED_BASE ULL(0x43F00000) -#define DRAM_40BIT_PROTECTED_BASE ULL(0x0403F00000) -#define DRAM_PROTECTED_SIZE ULL(0x03F00000) -#define RCAR_BL31_CRASH_BASE U(0x4403F000) -#define RCAR_BL31_CRASH_SIZE U(0x00001000) -/* Entrypoint mailboxes */ -#define MBOX_BASE RCAR_SHARED_MEM_BASE -#define MBOX_SIZE 0x200 -/* Base address where parameters to BL31 are stored */ -#define PARAMS_BASE (MBOX_BASE + MBOX_SIZE) -#define BOOT_KIND_BASE (RCAR_SHARED_MEM_BASE + \ - RCAR_SHARED_MEM_SIZE - 0x100) -/* - * The number of regions like RO(code), coherent and data required by - * different BL stages which need to be mapped in the MMU - */ -#if USE_COHERENT_MEM -#define RCAR_BL_REGIONS (3) -#else -#define RCAR_BL_REGIONS (2) -#endif -/* - * The RCAR_MAX_MMAP_REGIONS depends on the number of entries in rcar_mmap[] - * defined for each BL stage in rcar_common.c. - */ -#if IMAGE_BL2 -#define RCAR_MMAP_ENTRIES (9) -#endif -#if IMAGE_BL31 -#define RCAR_MMAP_ENTRIES (9) -#endif -#if IMAGE_BL2 -#define REG1_BASE U(0xE6400000) -#define REG1_SIZE U(0x04C00000) -#define ROM0_BASE U(0xEB100000) -#define ROM0_SIZE U(0x00028000) -#define REG2_BASE U(0xEC000000) -#define REG2_SIZE U(0x14000000) -#endif -/* BL33 */ -#define NS_IMAGE_OFFSET (DRAM1_BASE + U(0x09000000)) -/* BL31 */ -#define RCAR_DEVICE_BASE DEVICE_RCAR_BASE -#define RCAR_DEVICE_SIZE (0x1A000000) -#define RCAR_LOG_RES_SIZE (64) -#define RCAR_LOG_HEADER_SIZE (16) -#define RCAR_LOG_OTHER_SIZE (RCAR_LOG_HEADER_SIZE + \ - RCAR_LOG_RES_SIZE) -#define RCAR_BL31_LOG_MAX (RCAR_BL31_LOG_SIZE - \ - RCAR_LOG_OTHER_SIZE) -#define RCAR_CRASH_STACK RCAR_BL31_CRASH_BASE -#define AARCH64_SPACE_BASE ULL(0x00000000000) -#define AARCH64_SPACE_SIZE ULL(0x10000000000) -/* CCI related constants */ -#define CCI500_BASE U(0xF1200000) -#define CCI500_CLUSTER0_SL_IFACE_IX (2) -#define CCI500_CLUSTER1_SL_IFACE_IX (3) -#define CCI500_CLUSTER0_SL_IFACE_IX_FOR_M3 (1) -#define CCI500_CLUSTER1_SL_IFACE_IX_FOR_M3 (2) -#define RCAR_CCI_BASE CCI500_BASE -/* GIC */ -#define RCAR_GICD_BASE U(0xF1010000) -#define RCAR_GICR_BASE U(0xF1010000) -#define RCAR_GICC_BASE U(0xF1020000) -#define RCAR_GICH_BASE U(0xF1040000) -#define RCAR_GICV_BASE U(0xF1060000) -#define ARM_IRQ_SEC_PHY_TIMER U(29) -#define ARM_IRQ_SEC_SGI_0 U(8) -#define ARM_IRQ_SEC_SGI_1 U(9) -#define ARM_IRQ_SEC_SGI_2 U(10) -#define ARM_IRQ_SEC_SGI_3 U(11) -#define ARM_IRQ_SEC_SGI_4 U(12) -#define ARM_IRQ_SEC_SGI_5 U(13) -#define ARM_IRQ_SEC_SGI_6 U(14) -#define ARM_IRQ_SEC_SGI_7 U(15) -#define ARM_IRQ_SEC_RPC U(70) -#define ARM_IRQ_SEC_TIMER U(166) -#define ARM_IRQ_SEC_TIMER_UP U(171) -#define ARM_IRQ_SEC_WDT U(173) -#define ARM_IRQ_SEC_CRYPT U(102) -#define ARM_IRQ_SEC_CRYPT_SecPKA U(97) -#define ARM_IRQ_SEC_CRYPT_PubPKA U(98) -/* Timer control */ -#define RCAR_CNTC_BASE U(0xE6080000) -/* Reset */ -#define RCAR_CPGWPR U(0xE6150900) /* CPG write protect */ -#define RCAR_MODEMR U(0xE6160060) /* Mode pin */ -#define RCAR_CA57RESCNT U(0xE6160040) /* Reset control A57 */ -#define RCAR_CA53RESCNT U(0xE6160044) /* Reset control A53 */ -#define RCAR_SRESCR U(0xE6160110) /* Soft Power On Reset */ -#define RCAR_CA53WUPCR U(0xE6151010) /* Wake-up control A53 */ -#define RCAR_CA57WUPCR U(0xE6152010) /* Wake-up control A57 */ -#define RCAR_CA53PSTR U(0xE6151040) /* Power status A53 */ -#define RCAR_CA57PSTR U(0xE6152040) /* Power status A57 */ -#define RCAR_CA53CPU0CR U(0xE6151100) /* CPU control A53 */ -#define RCAR_CA57CPU0CR U(0xE6152100) /* CPU control A57 */ -#define RCAR_CA53CPUCMCR U(0xE6151184) /* Common power A53 */ -#define RCAR_CA57CPUCMCR U(0xE6152184) /* Common power A57 */ -#define RCAR_WUPMSKCA57 U(0xE6180014) /* Wake-up mask A57 */ -#define RCAR_WUPMSKCA53 U(0xE6180018) /* Wake-up mask A53 */ -/* SYSC */ -#define RCAR_PWRSR3 U(0xE6180140) /* Power stat A53-SCU */ -#define RCAR_PWRSR5 U(0xE61801C0) /* Power stat A57-SCU */ -#define RCAR_SYSCIER U(0xE618000C) /* Interrupt enable */ -#define RCAR_SYSCIMR U(0xE6180010) /* Interrupt mask */ -#define RCAR_SYSCSR U(0xE6180000) /* SYSC status */ -#define RCAR_PWRONCR3 U(0xE618014C) /* Power resume A53-SCU */ -#define RCAR_PWRONCR5 U(0xE61801CC) /* Power resume A57-SCU */ -#define RCAR_PWROFFCR3 U(0xE6180144) /* Power shutoff A53-SCU */ -#define RCAR_PWROFFCR5 U(0xE61801C4) /* Power shutoff A57-SCU */ -#define RCAR_PWRER3 U(0xE6180154) /* shutoff/resume error */ -#define RCAR_PWRER5 U(0xE61801D4) /* shutoff/resume error */ -#define RCAR_SYSCISR U(0xE6180004) /* Interrupt status */ -#define RCAR_SYSCISCR U(0xE6180008) /* Interrupt stat clear */ -/* Product register */ -#define RCAR_PRR U(0xFFF00044) -#define RCAR_M3_CUT_VER11 U(0x00000010) /* M3 Ver.1.1/Ver.1.2 */ -#define RCAR_MAJOR_MASK U(0x000000F0) -#define RCAR_MINOR_MASK U(0x0000000F) -#define PRR_PRODUCT_SHIFT U(8) -#define RCAR_MAJOR_SHIFT U(4) -#define RCAR_MINOR_SHIFT U(0) -#define RCAR_MAJOR_OFFSET U(1) -#define RCAR_M3_MINOR_OFFSET U(2) -#define PRR_PRODUCT_H3_CUT10 (PRR_PRODUCT_H3 | U(0x00)) /* 1.0 */ -#define PRR_PRODUCT_H3_CUT11 (PRR_PRODUCT_H3 | U(0x01)) /* 1.1 */ -#define PRR_PRODUCT_H3_CUT20 (PRR_PRODUCT_H3 | U(0x10)) /* 2.0 */ -#define PRR_PRODUCT_M3_CUT10 (PRR_PRODUCT_M3 | U(0x00)) /* 1.0 */ -#define PRR_PRODUCT_M3_CUT11 (PRR_PRODUCT_M3 | U(0x10)) -#define PRR 0xFFF00044U -#define PRR_PRODUCT_MASK 0x00007F00U -#define PRR_CUT_MASK 0x000000FFU -#define PRR_PRODUCT_H3 0x00004F00U /* R-Car H3 */ -#define PRR_PRODUCT_M3 0x00005200U /* R-Car M3-W */ -#define PRR_PRODUCT_V3M 0x00005400U /* R-Car V3M */ -#define PRR_PRODUCT_M3N 0x00005500U /* R-Car M3-N */ -#define PRR_PRODUCT_V3H 0x00005600U /* R-Car V3H */ -#define PRR_PRODUCT_E3 0x00005700U /* R-Car E3 */ -#define PRR_PRODUCT_D3 0x00005800U /* R-Car D3 */ -#define PRR_PRODUCT_10 0x00U /* Ver.1.0 */ -#define PRR_PRODUCT_11 0x01U /* Ver.1.1 */ -#define PRR_PRODUCT_20 0x10U /* Ver.2.0 */ -#define PRR_PRODUCT_21 0x11U /* Ver.2.1 */ -#define PRR_PRODUCT_30 0x20U /* Ver.3.0 */ -#define RCAR_CPU_MASK_CA57 U(0x80000000) -#define RCAR_CPU_MASK_CA53 U(0x04000000) -#define RCAR_CPU_HAVE_CA57 U(0x00000000) -#define RCAR_CPU_HAVE_CA53 U(0x00000000) -#define RCAR_SSCG_MASK U(0x1000) /* MD12 */ -#define RCAR_SSCG_ENABLE U(0x1000) -/* MD pin information */ -#define MODEMR_BOOT_CPU_MASK U(0x000000C0) -#define MODEMR_BOOT_CPU_CR7 U(0x000000C0) -#define MODEMR_BOOT_CPU_CA57 U(0x00000000) -#define MODEMR_BOOT_CPU_CA53 U(0x00000040) -#define MODEMR_BOOT_DEV_MASK U(0x0000001E) -#define MODEMR_BOOT_DEV_HYPERFLASH160 U(0x00000004) -#define MODEMR_BOOT_DEV_HYPERFLASH80 U(0x00000006) -#define MODEMR_BOOT_DEV_QSPI_FLASH40 U(0x00000008) -#define MODEMR_BOOT_DEV_QSPI_FLASH80 U(0x0000000C) -#define MODEMR_BOOT_DEV_EMMC_25X1 U(0x0000000A) -#define MODEMR_BOOT_DEV_EMMC_50X8 U(0x0000001A) -#define MODEMR_BOOT_PLL_MASK U(0x00006000) -#define MODEMR_BOOT_PLL_SHIFT U(13) -/* Memory mapped Generic timer interfaces */ -#define ARM_SYS_CNTCTL_BASE RCAR_CNTC_BASE -/* MODEMR PLL masks and bitfield values */ -#define CHECK_MD13_MD14 U(0x6000) -#define MD14_MD13_TYPE_0 U(0x0000) /* MD14=0 MD13=0 */ -#define MD14_MD13_TYPE_1 U(0x2000) /* MD14=0 MD13=1 */ -#define MD14_MD13_TYPE_2 U(0x4000) /* MD14=1 MD13=0 */ -#define MD14_MD13_TYPE_3 U(0x6000) /* MD14=1 MD13=1 */ -/* Frequency of EXTAL(Hz) */ -#define EXTAL_MD14_MD13_TYPE_0 U(8333300) /* MD14=0 MD13=0 */ -#define EXTAL_MD14_MD13_TYPE_1 U(10000000) /* MD14=0 MD13=1 */ -#define EXTAL_MD14_MD13_TYPE_2 U(12500000) /* MD14=1 MD13=0 */ -#define EXTAL_MD14_MD13_TYPE_3 U(16666600) /* MD14=1 MD13=1 */ -#define EXTAL_SALVATOR_XS U(8320000) /* Salvator-XS */ -#define EXTAL_EBISU U(24000000) /* Ebisu */ -#define EXTAL_DRAAK U(24000000) /* Draak */ -/* CPG write protect registers */ -#define CPGWPR_PASSWORD (0x5A5AFFFFU) -#define CPGWPCR_PASSWORD (0xA5A50000U) -/* CA5x Debug Resource control registers */ -#define CPG_CA57DBGRCR (CPG_BASE + 0x2180U) -#define CPG_CA53DBGRCR (CPG_BASE + 0x1180U) -#define DBGCPUPREN ((uint32_t)1U << 19U) -#define CPG_PLL0CR (CPG_BASE + 0x00D8U) -#define CPG_PLL2CR (CPG_BASE + 0x002CU) -#define CPG_PLL4CR (CPG_BASE + 0x01F4U) -#define CPG_CPGWPCR (CPG_BASE + 0x0904U) -/* RST Registers */ -#define RST_BASE (0xE6160000U) -#define RST_WDTRSTCR (RST_BASE + 0x0054U) -#define RST_MODEMR (RST_BASE + 0x0060U) -#define WDTRSTCR_PASSWORD (0xA55A0000U) -#define WDTRSTCR_RWDT_RSTMSK ((uint32_t)1U << 0U) -/* MFIS Registers */ -#define MFISWPCNTR_PASSWORD (0xACCE0000U) -#define MFISWPCNTR (0xE6260900U) -/* IPMMU registers */ -#define IPMMU_MM_BASE (0xE67B0000U) -#define IPMMUMM_IMSCTLR (IPMMU_MM_BASE + 0x0500U) -#define IPMMUMM_IMAUXCTLR (IPMMU_MM_BASE + 0x0504U) -#define IPMMUMM_IMSCTLR_ENABLE (0xC0000000U) -#define IPMMUMM_IMAUXCTLR_NMERGE40_BIT (0x01000000U) -#define IMSCTLR_DISCACHE (0xE0000000U) -#define IPMMU_VP0_BASE (0xFE990000U) -#define IPMMUVP0_IMSCTLR (IPMMU_VP0_BASE + 0x0500U) -#define IPMMU_VI0_BASE (0xFEBD0000U) -#define IPMMUVI0_IMSCTLR (IPMMU_VI0_BASE + 0x0500U) -#define IPMMU_VI1_BASE (0xFEBE0000U) -#define IPMMUVI1_IMSCTLR (IPMMU_VI1_BASE + 0x0500U) -#define IPMMU_PV0_BASE (0xFD800000U) -#define IPMMUPV0_IMSCTLR (IPMMU_PV0_BASE + 0x0500U) -#define IPMMU_PV1_BASE (0xFD950000U) -#define IPMMUPV1_IMSCTLR (IPMMU_PV1_BASE + 0x0500U) -#define IPMMU_PV2_BASE (0xFD960000U) -#define IPMMUPV2_IMSCTLR (IPMMU_PV2_BASE + 0x0500U) -#define IPMMU_PV3_BASE (0xFD970000U) -#define IPMMUPV3_IMSCTLR (IPMMU_PV3_BASE + 0x0500U) -#define IPMMU_HC_BASE (0xE6570000U) -#define IPMMUHC_IMSCTLR (IPMMU_HC_BASE + 0x0500U) -#define IPMMU_RT_BASE (0xFFC80000U) -#define IPMMURT_IMSCTLR (IPMMU_RT_BASE + 0x0500U) -#define IPMMU_MP_BASE (0xEC670000U) -#define IPMMUMP_IMSCTLR (IPMMU_MP_BASE + 0x0500U) -#define IPMMU_DS0_BASE (0xE6740000U) -#define IPMMUDS0_IMSCTLR (IPMMU_DS0_BASE + 0x0500U) -#define IPMMU_DS1_BASE (0xE7740000U) -#define IPMMUDS1_IMSCTLR (IPMMU_DS1_BASE + 0x0500U) -/* ARMREG registers */ -#define P_ARMREG_SEC_CTRL (0xE62711F0U) -#define P_ARMREG_SEC_CTRL_PROT (0x00000001U) -/* MIDR */ -#define MIDR_CA57 (0x0D07U << MIDR_PN_SHIFT) -#define MIDR_CA53 (0x0D03U << MIDR_PN_SHIFT) -/* for SuspendToRAM */ -#define GPIO_BASE (0xE6050000U) -#define GPIO_INDT1 (GPIO_BASE + 0x100CU) -#define GPIO_INDT3 (GPIO_BASE + 0x300CU) -#define GPIO_INDT6 (GPIO_BASE + 0x540CU) -#define GPIO_OUTDT1 (GPIO_BASE + 0x1008U) -#define GPIO_OUTDT3 (GPIO_BASE + 0x3008U) -#define GPIO_OUTDT6 (GPIO_BASE + 0x5408U) -#define RCAR_COLD_BOOT (0x00U) -#define RCAR_WARM_BOOT (0x01U) -#if PMIC_ROHM_BD9571 && RCAR_SYSTEM_RESET_KEEPON_DDR -#define KEEP10_MAGIC (0x55U) -#endif -/* lossy registers */ -#define LOSSY_PARAMS_BASE (0x47FD7000U) -#define AXI_DCMPAREACRA0 (0xE6784100U) -#define AXI_DCMPAREACRB0 (0xE6784104U) -#define LOSSY_ENABLE (0x80000000U) -#define LOSSY_DISABLE (0x00000000U) -#define LOSSY_FMT_YUVPLANAR (0x00000000U) -#define LOSSY_FMT_YUV422INTLV (0x20000000U) -#define LOSSY_FMT_ARGB8888 (0x40000000U) -#define LOSSY_ST_ADDR0 (0x54000000U) -#define LOSSY_END_ADDR0 (0x57000000U) -#define LOSSY_FMT0 LOSSY_FMT_YUVPLANAR -#define LOSSY_ENA_DIS0 LOSSY_ENABLE -#define LOSSY_ST_ADDR1 0x0U -#define LOSSY_END_ADDR1 0x0U -#define LOSSY_FMT1 LOSSY_FMT_ARGB8888 -#define LOSSY_ENA_DIS1 LOSSY_DISABLE -#define LOSSY_ST_ADDR2 0x0U -#define LOSSY_END_ADDR2 0x0U -#define LOSSY_FMT2 LOSSY_FMT_YUV422INTLV -#define LOSSY_ENA_DIS2 LOSSY_DISABLE - -#endif /* RCAR_DEF_H */ diff --git a/plat/renesas/rcar/include/rcar_private.h b/plat/renesas/rcar/include/rcar_private.h deleted file mode 100644 index 36f4ca540..000000000 --- a/plat/renesas/rcar/include/rcar_private.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef RCAR_PRIVATE_H -#define RCAR_PRIVATE_H - -#include -#include -#include - -#include - -typedef volatile struct mailbox { - unsigned long value __aligned(CACHE_WRITEBACK_GRANULE); -} mailbox_t; - -/* - * This structure represents the superset of information that is passed to - * BL31 e.g. while passing control to it from BL2 which is bl31_params - * and bl31_plat_params and its elements - */ -typedef struct bl2_to_bl31_params_mem { - image_info_t bl32_image_info; - image_info_t bl33_image_info; - entry_point_info_t bl33_ep_info; - entry_point_info_t bl32_ep_info; -} bl2_to_bl31_params_mem_t; - -#if USE_COHERENT_MEM -#define RCAR_INSTANTIATE_LOCK DEFINE_BAKERY_LOCK(rcar_lock); -#define rcar_lock_init() bakery_lock_init(&rcar_lock) -#define rcar_lock_get() bakery_lock_get(&rcar_lock) -#define rcar_lock_release() bakery_lock_release(&rcar_lock) -#else -/* - * Constants to specify how many bakery locks this platform implements. These - * are used if the platform chooses not to use coherent memory for bakery lock - * data structures. - */ -#define RCAR_MAX_BAKERIES 2 -#define RCAR_PWRC_BAKERY_ID 0 - -/* - * Definition of structure which holds platform specific per-cpu data. Currently - * it holds only the bakery lock information for each cpu. Constants to - * specify how many bakeries this platform implements and bakery ids are - * specified in rcar_def.h - */ -typedef struct rcar_cpu_data { - bakery_info_t pcpu_bakery_info[RCAR_MAX_BAKERIES]; -} rcar_cpu_data_t; - -#define RCAR_CPU_DATA_LOCK_OFFSET \ - __builtin_offsetof(rcar_cpu_data_t, pcpu_bakery_info) -/* - * Helper macros for bakery lock api when using the above rcar_cpu_data_t for - * bakery lock data structures. It assumes that the bakery_info is at the - * beginning of the platform specific per-cpu data. - */ -#define rcar_lock_init(_lock_arg) - -#define rcar_lock_get(_lock_arg) \ - bakery_lock_get(_lock_arg, \ - CPU_DATA_PLAT_PCPU_OFFSET + RCAR_CPU_DATA_LOCK_OFFSET) - -#define rcar_lock_release(_lock_arg) \ - bakery_lock_release(_lock_arg, \ - CPU_DATA_PLAT_PCPU_OFFSET + RCAR_CPU_DATA_LOCK_OFFSET) -/* - * Ensure that the size of the RCAR specific per-cpu data structure and the size - * of the memory allocated in generic per-cpu data for the platform are the same - */ -CASSERT(sizeof(rcar_cpu_data_t) == PLAT_PCPU_DATA_SIZE, - rcar_pcpu_data_size_mismatch); -#endif -/* - * Function and variable prototypes - */ -void rcar_configure_mmu_el3(unsigned long total_base, - unsigned long total_size, - unsigned long ro_start, unsigned long ro_limit -#if USE_COHERENT_MEM - , unsigned long coh_start, unsigned long coh_limit -#endif - ); - -void rcar_setup_topology(void); -void rcar_cci_disable(void); -void rcar_cci_enable(void); -void rcar_cci_init(void); - -void plat_invalidate_icache(void); -void plat_cci_disable(void); -void plat_cci_enable(void); -void plat_cci_init(void); - -void mstpcr_write(uint32_t mstpcr, uint32_t mstpsr, uint32_t target_bit); -void cpg_write(uintptr_t regadr, uint32_t regval); - -void rcar_console_boot_init(void); -void rcar_console_boot_end(void); -void rcar_console_runtime_init(void); -void rcar_console_runtime_end(void); - -#endif /* RCAR_PRIVATE_H */ diff --git a/plat/renesas/rcar/include/rcar_version.h b/plat/renesas/rcar/include/rcar_version.h deleted file mode 100644 index 67cbd71ab..000000000 --- a/plat/renesas/rcar/include/rcar_version.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef RCAR_VERSION_H -#define RCAR_VERSION_H - -#include - -#define VERSION_OF_RENESAS "2.0.6" -#define VERSION_OF_RENESAS_MAXLEN 128 - -extern const uint8_t version_of_renesas[VERSION_OF_RENESAS_MAXLEN]; - -#endif /* RCAR_VERSION_H */ diff --git a/plat/renesas/rcar/include/registers/axi_registers.h b/plat/renesas/rcar/include/registers/axi_registers.h deleted file mode 100644 index 36cd58bd9..000000000 --- a/plat/renesas/rcar/include/registers/axi_registers.h +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef AXI_REGISTERS_H -#define AXI_REGISTERS_H - -/* AXI registers */ - -/* AXI base address */ -#define AXI_BASE (0xE6780000U) - -/* address split */ - -/* AXI address split control 0 */ -#define AXI_ADSPLCR0 (AXI_BASE + 0x4008U) -/* AXI address split control 1 */ -#define AXI_ADSPLCR1 (AXI_BASE + 0x400CU) -/* AXI address split control 2 */ -#define AXI_ADSPLCR2 (AXI_BASE + 0x4010U) -/* AXI address split control 3 */ -#define AXI_ADSPLCR3 (AXI_BASE + 0x4014U) - -/* functional safety */ - -/* AXI functional safety control */ -#define AXI_FUSACR (AXI_BASE + 0x4020U) - -/* decompression */ - -/* AXI decompression area configuration A0 */ -#define AXI_DCMPAREACRA0 (AXI_BASE + 0x4100U) -/* AXI decompression area configuration B0 */ -#define AXI_DCMPAREACRB0 (AXI_BASE + 0x4104U) -/* AXI decompression area configuration A1 */ -#define AXI_DCMPAREACRA1 (AXI_BASE + 0x4108U) -/* AXI decompression area configuration B1 */ -#define AXI_DCMPAREACRB1 (AXI_BASE + 0x410CU) -/* AXI decompression area configuration A2 */ -#define AXI_DCMPAREACRA2 (AXI_BASE + 0x4110U) -/* AXI decompression area configuration B2 */ -#define AXI_DCMPAREACRB2 (AXI_BASE + 0x4114U) -/* AXI decompression area configuration A3 */ -#define AXI_DCMPAREACRA3 (AXI_BASE + 0x4118U) -/* AXI decompression area configuration B3 */ -#define AXI_DCMPAREACRB3 (AXI_BASE + 0x411CU) -/* AXI decompression area configuration A4 */ -#define AXI_DCMPAREACRA4 (AXI_BASE + 0x4120U) -/* AXI decompression area configuration B4 */ -#define AXI_DCMPAREACRB4 (AXI_BASE + 0x4124U) -/* AXI decompression area configuration A5 */ -#define AXI_DCMPAREACRA5 (AXI_BASE + 0x4128U) -/* AXI decompression area configuration B5 */ -#define AXI_DCMPAREACRB5 (AXI_BASE + 0x412CU) -/* AXI decompression area configuration A6 */ -#define AXI_DCMPAREACRA6 (AXI_BASE + 0x4130U) -/* AXI decompression area configuration B6 */ -#define AXI_DCMPAREACRB6 (AXI_BASE + 0x4134U) -/* AXI decompression area configuration A7 */ -#define AXI_DCMPAREACRA7 (AXI_BASE + 0x4138U) -/* AXI decompression area configuration B7 */ -#define AXI_DCMPAREACRB7 (AXI_BASE + 0x413CU) -/* AXI decompression area configuration A8 */ -#define AXI_DCMPAREACRA8 (AXI_BASE + 0x4140U) -/* AXI decompression area configuration B8 */ -#define AXI_DCMPAREACRB8 (AXI_BASE + 0x4144U) -/* AXI decompression area configuration A9 */ -#define AXI_DCMPAREACRA9 (AXI_BASE + 0x4148U) -/* AXI decompression area configuration B9 */ -#define AXI_DCMPAREACRB9 (AXI_BASE + 0x414CU) -/* AXI decompression area configuration A10 */ -#define AXI_DCMPAREACRA10 (AXI_BASE + 0x4150U) -/* AXI decompression area configuration B10 */ -#define AXI_DCMPAREACRB10 (AXI_BASE + 0x4154U) -/* AXI decompression area configuration A11 */ -#define AXI_DCMPAREACRA11 (AXI_BASE + 0x4158U) -/* AXI decompression area configuration B11 */ -#define AXI_DCMPAREACRB11 (AXI_BASE + 0x415CU) -/* AXI decompression area configuration A12 */ -#define AXI_DCMPAREACRA12 (AXI_BASE + 0x4160U) -/* AXI decompression area configuration B12 */ -#define AXI_DCMPAREACRB12 (AXI_BASE + 0x4164U) -/* AXI decompression area configuration A13 */ -#define AXI_DCMPAREACRA13 (AXI_BASE + 0x4168U) -/* AXI decompression area configuration B13 */ -#define AXI_DCMPAREACRB13 (AXI_BASE + 0x416CU) -/* AXI decompression area configuration A14 */ -#define AXI_DCMPAREACRA14 (AXI_BASE + 0x4170U) -/* AXI decompression area configuration B14 */ -#define AXI_DCMPAREACRB14 (AXI_BASE + 0x4174U) -/* AXI decompression area configuration A15 */ -#define AXI_DCMPAREACRA15 (AXI_BASE + 0x4178U) -/* AXI decompression area configuration B15 */ -#define AXI_DCMPAREACRB15 (AXI_BASE + 0x417CU) -/* AXI decompression shadow area configuration */ -#define AXI_DCMPSHDWCR (AXI_BASE + 0x4280U) - -/* SDRAM protection */ - -/* AXI dram protected area division 0 */ -#define AXI_DPTDIVCR0 (AXI_BASE + 0x4400U) -/* AXI dram protected area division 1 */ -#define AXI_DPTDIVCR1 (AXI_BASE + 0x4404U) -/* AXI dram protected area division 2 */ -#define AXI_DPTDIVCR2 (AXI_BASE + 0x4408U) -/* AXI dram protected area division 3 */ -#define AXI_DPTDIVCR3 (AXI_BASE + 0x440CU) -/* AXI dram protected area division 4 */ -#define AXI_DPTDIVCR4 (AXI_BASE + 0x4410U) -/* AXI dram protected area division 5 */ -#define AXI_DPTDIVCR5 (AXI_BASE + 0x4414U) -/* AXI dram protected area division 6 */ -#define AXI_DPTDIVCR6 (AXI_BASE + 0x4418U) -/* AXI dram protected area division 7 */ -#define AXI_DPTDIVCR7 (AXI_BASE + 0x441CU) -/* AXI dram protected area division 8 */ -#define AXI_DPTDIVCR8 (AXI_BASE + 0x4420U) -/* AXI dram protected area division 9 */ -#define AXI_DPTDIVCR9 (AXI_BASE + 0x4424U) -/* AXI dram protected area division 10 */ -#define AXI_DPTDIVCR10 (AXI_BASE + 0x4428U) -/* AXI dram protected area division 11 */ -#define AXI_DPTDIVCR11 (AXI_BASE + 0x442CU) -/* AXI dram protected area division 12 */ -#define AXI_DPTDIVCR12 (AXI_BASE + 0x4430U) -/* AXI dram protected area division 13 */ -#define AXI_DPTDIVCR13 (AXI_BASE + 0x4434U) -/* AXI dram protected area division 14 */ -#define AXI_DPTDIVCR14 (AXI_BASE + 0x4438U) - -/* AXI dram protected area setting 0 */ -#define AXI_DPTCR0 (AXI_BASE + 0x4440U) -/* AXI dram protected area setting 1 */ -#define AXI_DPTCR1 (AXI_BASE + 0x4444U) -/* AXI dram protected area setting 2 */ -#define AXI_DPTCR2 (AXI_BASE + 0x4448U) -/* AXI dram protected area setting 3 */ -#define AXI_DPTCR3 (AXI_BASE + 0x444CU) -/* AXI dram protected area setting 4 */ -#define AXI_DPTCR4 (AXI_BASE + 0x4450U) -/* AXI dram protected area setting 5 */ -#define AXI_DPTCR5 (AXI_BASE + 0x4454U) -/* AXI dram protected area setting 6 */ -#define AXI_DPTCR6 (AXI_BASE + 0x4458U) -/* AXI dram protected area setting 7 */ -#define AXI_DPTCR7 (AXI_BASE + 0x445CU) -/* AXI dram protected area setting 8 */ -#define AXI_DPTCR8 (AXI_BASE + 0x4460U) -/* AXI dram protected area setting 9 */ -#define AXI_DPTCR9 (AXI_BASE + 0x4464U) -/* AXI dram protected area setting 10 */ -#define AXI_DPTCR10 (AXI_BASE + 0x4468U) -/* AXI dram protected area setting 11 */ -#define AXI_DPTCR11 (AXI_BASE + 0x446CU) -/* AXI dram protected area setting 12 */ -#define AXI_DPTCR12 (AXI_BASE + 0x4470U) -/* AXI dram protected area setting 13 */ -#define AXI_DPTCR13 (AXI_BASE + 0x4474U) -/* AXI dram protected area setting 14 */ -#define AXI_DPTCR14 (AXI_BASE + 0x4478U) -/* AXI dram protected area setting 15 */ -#define AXI_DPTCR15 (AXI_BASE + 0x447CU) - -/* SRAM protection */ - -/* AXI sram protected area division 0 */ -#define AXI_SPTDIVCR0 (AXI_BASE + 0x4500U) -/* AXI sram protected area division 1 */ -#define AXI_SPTDIVCR1 (AXI_BASE + 0x4504U) -/* AXI sram protected area division 2 */ -#define AXI_SPTDIVCR2 (AXI_BASE + 0x4508U) -/* AXI sram protected area division 3 */ -#define AXI_SPTDIVCR3 (AXI_BASE + 0x450CU) -/* AXI sram protected area division 4 */ -#define AXI_SPTDIVCR4 (AXI_BASE + 0x4510U) -/* AXI sram protected area division 5 */ -#define AXI_SPTDIVCR5 (AXI_BASE + 0x4514U) -/* AXI sram protected area division 6 */ -#define AXI_SPTDIVCR6 (AXI_BASE + 0x4518U) -/* AXI sram protected area division 7 */ -#define AXI_SPTDIVCR7 (AXI_BASE + 0x451CU) -/* AXI sram protected area division 8 */ -#define AXI_SPTDIVCR8 (AXI_BASE + 0x4520U) -/* AXI sram protected area division 9 */ -#define AXI_SPTDIVCR9 (AXI_BASE + 0x4524U) -/* AXI sram protected area division 10 */ -#define AXI_SPTDIVCR10 (AXI_BASE + 0x4528U) -/* AXI sram protected area division 11 */ -#define AXI_SPTDIVCR11 (AXI_BASE + 0x452CU) -/* AXI sram protected area division 12 */ -#define AXI_SPTDIVCR12 (AXI_BASE + 0x4530U) -/* AXI sram protected area division 13 */ -#define AXI_SPTDIVCR13 (AXI_BASE + 0x4534U) -/* AXI sram protected area division 14 */ -#define AXI_SPTDIVCR14 (AXI_BASE + 0x4538U) - -/* AXI sram protected area setting 0 */ -#define AXI_SPTCR0 (AXI_BASE + 0x4540U) -/* AXI sram protected area setting 1 */ -#define AXI_SPTCR1 (AXI_BASE + 0x4544U) -/* AXI sram protected area setting 2 */ -#define AXI_SPTCR2 (AXI_BASE + 0x4548U) -/* AXI sram protected area setting 3 */ -#define AXI_SPTCR3 (AXI_BASE + 0x454CU) -/* AXI sram protected area setting 4 */ -#define AXI_SPTCR4 (AXI_BASE + 0x4550U) -/* AXI sram protected area setting 5 */ -#define AXI_SPTCR5 (AXI_BASE + 0x4554U) -/* AXI sram protected area setting 6 */ -#define AXI_SPTCR6 (AXI_BASE + 0x4558U) -/* AXI sram protected area setting 7 */ -#define AXI_SPTCR7 (AXI_BASE + 0x455CU) -/* AXI sram protected area setting 8 */ -#define AXI_SPTCR8 (AXI_BASE + 0x4560U) -/* AXI sram protected area setting 9 */ -#define AXI_SPTCR9 (AXI_BASE + 0x4564U) -/* AXI sram protected area setting 10 */ -#define AXI_SPTCR10 (AXI_BASE + 0x4568U) -/* AXI sram protected area setting 11 */ -#define AXI_SPTCR11 (AXI_BASE + 0x456CU) -/* AXI sram protected area setting 12 */ -#define AXI_SPTCR12 (AXI_BASE + 0x4570U) -/* AXI sram protected area setting 13 */ -#define AXI_SPTCR13 (AXI_BASE + 0x4574U) -/* AXI sram protected area setting 14 */ -#define AXI_SPTCR14 (AXI_BASE + 0x4578U) -/* AXI sram protected area setting 15 */ -#define AXI_SPTCR15 (AXI_BASE + 0x457CU) - -/* EDC base address */ -#define EDC_BASE (0xFF840000U) - -/* EDC edc enable */ -#define EDC_EDCEN (EDC_BASE + 0x0010U) -/* EDC edc status 0 */ -#define EDC_EDCST0 (EDC_BASE + 0x0020U) -/* EDC edc status 1 */ -#define EDC_EDCST1 (EDC_BASE + 0x0024U) -/* EDC edc interrupt enable 0 */ -#define EDC_EDCINTEN0 (EDC_BASE + 0x0040U) -/* EDC edc interrupt enable 1 */ -#define EDC_EDCINTEN1 (EDC_BASE + 0x0044U) - -#endif /* AXI_REGISTERS_H */ diff --git a/plat/renesas/rcar/include/registers/cpg_registers.h b/plat/renesas/rcar/include/registers/cpg_registers.h deleted file mode 100644 index 0d698d9c1..000000000 --- a/plat/renesas/rcar/include/registers/cpg_registers.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef CPG_REGISTERS_H -#define CPG_REGISTERS_H - -/* CPG base address */ -#define CPG_BASE (0xE6150000U) - -/* CPG system module stop control 2 */ -#define CPG_SMSTPCR2 (CPG_BASE + 0x0138U) -/* CPG software reset 2 */ -#define CPG_SRCR2 (CPG_BASE + 0x00B0U) -/* CPG module stop status 2 */ -#define CPG_MSTPSR2 (CPG_BASE + 0x0040U) -/* CPG write protect */ -#define CPG_CPGWPR (CPG_BASE + 0x0900U) -/* CPG write protect control */ -#define CPG_CPGWPCR (CPG_BASE + 0x0904U) -/* CPG system module stop control 9 */ -#define CPG_SMSTPCR9 (CPG_BASE + 0x0994U) -/* CPG module stop status 9 */ -#define CPG_MSTPSR9 (CPG_BASE + 0x09A4U) - -/* CPG (SECURITY) registers */ - -/* Secure Module Stop Control Register 0 */ -#define SCMSTPCR0 (CPG_BASE + 0x0B20U) -/* Secure Module Stop Control Register 1 */ -#define SCMSTPCR1 (CPG_BASE + 0x0B24U) -/* Secure Module Stop Control Register 2 */ -#define SCMSTPCR2 (CPG_BASE + 0x0B28U) -/* Secure Module Stop Control Register 3 */ -#define SCMSTPCR3 (CPG_BASE + 0x0B2CU) -/* Secure Module Stop Control Register 4 */ -#define SCMSTPCR4 (CPG_BASE + 0x0B30U) -/* Secure Module Stop Control Register 5 */ -#define SCMSTPCR5 (CPG_BASE + 0x0B34U) -/* Secure Module Stop Control Register 6 */ -#define SCMSTPCR6 (CPG_BASE + 0x0B38U) -/* Secure Module Stop Control Register 7 */ -#define SCMSTPCR7 (CPG_BASE + 0x0B3CU) -/* Secure Module Stop Control Register 8 */ -#define SCMSTPCR8 (CPG_BASE + 0x0B40U) -/* Secure Module Stop Control Register 9 */ -#define SCMSTPCR9 (CPG_BASE + 0x0B44U) -/* Secure Module Stop Control Register 10 */ -#define SCMSTPCR10 (CPG_BASE + 0x0B48U) -/* Secure Module Stop Control Register 11 */ -#define SCMSTPCR11 (CPG_BASE + 0x0B4CU) - -/* CPG (SECURITY) registers */ - -/* Secure Software Reset Access Enable Control Register 0 */ -#define SCSRSTECR0 (CPG_BASE + 0x0B80U) -/* Secure Software Reset Access Enable Control Register 1 */ -#define SCSRSTECR1 (CPG_BASE + 0x0B84U) -/* Secure Software Reset Access Enable Control Register 2 */ -#define SCSRSTECR2 (CPG_BASE + 0x0B88U) -/* Secure Software Reset Access Enable Control Register 3 */ -#define SCSRSTECR3 (CPG_BASE + 0x0B8CU) -/* Secure Software Reset Access Enable Control Register 4 */ -#define SCSRSTECR4 (CPG_BASE + 0x0B90U) -/* Secure Software Reset Access Enable Control Register 5 */ -#define SCSRSTECR5 (CPG_BASE + 0x0B94U) -/* Secure Software Reset Access Enable Control Register 6 */ -#define SCSRSTECR6 (CPG_BASE + 0x0B98U) -/* Secure Software Reset Access Enable Control Register 7 */ -#define SCSRSTECR7 (CPG_BASE + 0x0B9CU) -/* Secure Software Reset Access Enable Control Register 8 */ -#define SCSRSTECR8 (CPG_BASE + 0x0BA0U) -/* Secure Software Reset Access Enable Control Register 9 */ -#define SCSRSTECR9 (CPG_BASE + 0x0BA4U) -/* Secure Software Reset Access Enable Control Register 10 */ -#define SCSRSTECR10 (CPG_BASE + 0x0BA8U) -/* Secure Software Reset Access Enable Control Register 11 */ -#define SCSRSTECR11 (CPG_BASE + 0x0BACU) - -/* CPG (REALTIME) registers */ - -/* Realtime Module Stop Control Register 0 */ -#define RMSTPCR0 (CPG_BASE + 0x0110U) -/* Realtime Module Stop Control Register 1 */ -#define RMSTPCR1 (CPG_BASE + 0x0114U) -/* Realtime Module Stop Control Register 2 */ -#define RMSTPCR2 (CPG_BASE + 0x0118U) -/* Realtime Module Stop Control Register 3 */ -#define RMSTPCR3 (CPG_BASE + 0x011CU) -/* Realtime Module Stop Control Register 4 */ -#define RMSTPCR4 (CPG_BASE + 0x0120U) -/* Realtime Module Stop Control Register 5 */ -#define RMSTPCR5 (CPG_BASE + 0x0124U) -/* Realtime Module Stop Control Register 6 */ -#define RMSTPCR6 (CPG_BASE + 0x0128U) -/* Realtime Module Stop Control Register 7 */ -#define RMSTPCR7 (CPG_BASE + 0x012CU) -/* Realtime Module Stop Control Register 8 */ -#define RMSTPCR8 (CPG_BASE + 0x0980U) -/* Realtime Module Stop Control Register 9 */ -#define RMSTPCR9 (CPG_BASE + 0x0984U) -/* Realtime Module Stop Control Register 10 */ -#define RMSTPCR10 (CPG_BASE + 0x0988U) -/* Realtime Module Stop Control Register 11 */ -#define RMSTPCR11 (CPG_BASE + 0x098CU) - -/* CPG (SYSTEM) registers */ - -/* System Module Stop Control Register 0 */ -#define SMSTPCR0 (CPG_BASE + 0x0130U) -/* System Module Stop Control Register 1 */ -#define SMSTPCR1 (CPG_BASE + 0x0134U) -/* System Module Stop Control Register 2 */ -#define SMSTPCR2 (CPG_BASE + 0x0138U) -/* System Module Stop Control Register 3 */ -#define SMSTPCR3 (CPG_BASE + 0x013CU) -/* System Module Stop Control Register 4 */ -#define SMSTPCR4 (CPG_BASE + 0x0140U) -/* System Module Stop Control Register 5 */ -#define SMSTPCR5 (CPG_BASE + 0x0144U) -/* System Module Stop Control Register 6 */ -#define SMSTPCR6 (CPG_BASE + 0x0148U) -/* System Module Stop Control Register 7 */ -#define SMSTPCR7 (CPG_BASE + 0x014CU) -/* System Module Stop Control Register 8 */ -#define SMSTPCR8 (CPG_BASE + 0x0990U) -/* System Module Stop Control Register 9 */ -#define SMSTPCR9 (CPG_BASE + 0x0994U) -/* System Module Stop Control Register 10 */ -#define SMSTPCR10 (CPG_BASE + 0x0998U) -/* System Module Stop Control Register 11 */ -#define SMSTPCR11 (CPG_BASE + 0x099CU) - -#endif /* CPG_REGISTERS_H */ diff --git a/plat/renesas/rcar/include/registers/lifec_registers.h b/plat/renesas/rcar/include/registers/lifec_registers.h deleted file mode 100644 index 5f49e52c0..000000000 --- a/plat/renesas/rcar/include/registers/lifec_registers.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef LIFEC_REGISTERS_H -#define LIFEC_REGISTERS_H - -#define LIFEC_SEC_BASE (0xE6110000U) - -#define SEC_SRC (LIFEC_SEC_BASE + 0x0008U) -#define SEC_SEL0 (LIFEC_SEC_BASE + 0x0030U) -#define SEC_SEL1 (LIFEC_SEC_BASE + 0x0034U) -#define SEC_SEL2 (LIFEC_SEC_BASE + 0x0038U) -#define SEC_SEL3 (LIFEC_SEC_BASE + 0x003CU) -#define SEC_SEL4 (LIFEC_SEC_BASE + 0x0058U) -#define SEC_SEL5 (LIFEC_SEC_BASE + 0x005CU) -#define SEC_SEL6 (LIFEC_SEC_BASE + 0x0060U) -#define SEC_SEL7 (LIFEC_SEC_BASE + 0x0064U) -#define SEC_SEL8 (LIFEC_SEC_BASE + 0x0068U) -#define SEC_SEL9 (LIFEC_SEC_BASE + 0x006CU) -#define SEC_SEL10 (LIFEC_SEC_BASE + 0x0070U) -#define SEC_SEL11 (LIFEC_SEC_BASE + 0x0074U) -#define SEC_SEL12 (LIFEC_SEC_BASE + 0x0078U) -#define SEC_SEL13 (LIFEC_SEC_BASE + 0x007CU) -#define SEC_SEL14 (LIFEC_SEC_BASE + 0x0080U) -#define SEC_SEL15 (LIFEC_SEC_BASE + 0x0084U) -#define SEC_GRP0CR0 (LIFEC_SEC_BASE + 0x0138U) -#define SEC_GRP1CR0 (LIFEC_SEC_BASE + 0x013CU) -#define SEC_GRP0CR1 (LIFEC_SEC_BASE + 0x0140U) -#define SEC_GRP1CR1 (LIFEC_SEC_BASE + 0x0144U) -#define SEC_GRP0CR2 (LIFEC_SEC_BASE + 0x0148U) -#define SEC_GRP1CR2 (LIFEC_SEC_BASE + 0x014CU) -#define SEC_GRP0CR3 (LIFEC_SEC_BASE + 0x0150U) -#define SEC_GRP1CR3 (LIFEC_SEC_BASE + 0x0154U) -#define SEC_GRP0COND0 (LIFEC_SEC_BASE + 0x0158U) -#define SEC_GRP1COND0 (LIFEC_SEC_BASE + 0x015CU) -#define SEC_GRP0COND1 (LIFEC_SEC_BASE + 0x0160U) -#define SEC_GRP1COND1 (LIFEC_SEC_BASE + 0x0164U) -#define SEC_GRP0COND2 (LIFEC_SEC_BASE + 0x0168U) -#define SEC_GRP1COND2 (LIFEC_SEC_BASE + 0x016CU) -#define SEC_GRP0COND3 (LIFEC_SEC_BASE + 0x0170U) -#define SEC_GRP1COND3 (LIFEC_SEC_BASE + 0x0174U) -#define SEC_GRP0COND4 (LIFEC_SEC_BASE + 0x0178U) -#define SEC_GRP1COND4 (LIFEC_SEC_BASE + 0x017CU) -#define SEC_GRP0COND5 (LIFEC_SEC_BASE + 0x0180U) -#define SEC_GRP1COND5 (LIFEC_SEC_BASE + 0x0184U) -#define SEC_GRP0COND6 (LIFEC_SEC_BASE + 0x0188U) -#define SEC_GRP1COND6 (LIFEC_SEC_BASE + 0x018CU) -#define SEC_GRP0COND7 (LIFEC_SEC_BASE + 0x0190U) -#define SEC_GRP1COND7 (LIFEC_SEC_BASE + 0x0194U) -#define SEC_GRP0COND8 (LIFEC_SEC_BASE + 0x0198U) -#define SEC_GRP1COND8 (LIFEC_SEC_BASE + 0x019CU) -#define SEC_GRP0COND9 (LIFEC_SEC_BASE + 0x01A0U) -#define SEC_GRP1COND9 (LIFEC_SEC_BASE + 0x01A4U) -#define SEC_GRP0COND10 (LIFEC_SEC_BASE + 0x01A8U) -#define SEC_GRP1COND10 (LIFEC_SEC_BASE + 0x01ACU) -#define SEC_GRP0COND11 (LIFEC_SEC_BASE + 0x01B0U) -#define SEC_GRP1COND11 (LIFEC_SEC_BASE + 0x01B4U) -#define SEC_GRP0COND12 (LIFEC_SEC_BASE + 0x01B8U) -#define SEC_GRP1COND12 (LIFEC_SEC_BASE + 0x01BCU) -#define SEC_GRP0COND13 (LIFEC_SEC_BASE + 0x01C0U) -#define SEC_GRP1COND13 (LIFEC_SEC_BASE + 0x01C4U) -#define SEC_GRP0COND14 (LIFEC_SEC_BASE + 0x01C8U) -#define SEC_GRP1COND14 (LIFEC_SEC_BASE + 0x01CCU) -#define SEC_GRP0COND15 (LIFEC_SEC_BASE + 0x01D0U) -#define SEC_GRP1COND15 (LIFEC_SEC_BASE + 0x01D4U) -#define SEC_READONLY0 (LIFEC_SEC_BASE + 0x01D8U) -#define SEC_READONLY1 (LIFEC_SEC_BASE + 0x01DCU) -#define SEC_READONLY2 (LIFEC_SEC_BASE + 0x01E0U) -#define SEC_READONLY3 (LIFEC_SEC_BASE + 0x01E4U) -#define SEC_READONLY4 (LIFEC_SEC_BASE + 0x01E8U) -#define SEC_READONLY5 (LIFEC_SEC_BASE + 0x01ECU) -#define SEC_READONLY6 (LIFEC_SEC_BASE + 0x01F0U) -#define SEC_READONLY7 (LIFEC_SEC_BASE + 0x01F4U) -#define SEC_READONLY8 (LIFEC_SEC_BASE + 0x01F8U) -#define SEC_READONLY9 (LIFEC_SEC_BASE + 0x01FCU) -#define SEC_READONLY10 (LIFEC_SEC_BASE + 0x0200U) -#define SEC_READONLY11 (LIFEC_SEC_BASE + 0x0204U) -#define SEC_READONLY12 (LIFEC_SEC_BASE + 0x0208U) -#define SEC_READONLY13 (LIFEC_SEC_BASE + 0x020CU) -#define SEC_READONLY14 (LIFEC_SEC_BASE + 0x0210U) -#define SEC_READONLY15 (LIFEC_SEC_BASE + 0x0214U) - -#define LIFEC_SAFE_BASE (0xE6120000U) -#define SAFE_GRP0CR0 (LIFEC_SAFE_BASE + 0x0138U) -#define SAFE_GRP1CR0 (LIFEC_SAFE_BASE + 0x013CU) -#define SAFE_GRP0CR1 (LIFEC_SAFE_BASE + 0x0140U) -#define SAFE_GRP1CR1 (LIFEC_SAFE_BASE + 0x0144U) -#define SAFE_GRP0CR2 (LIFEC_SAFE_BASE + 0x0148U) -#define SAFE_GRP1CR2 (LIFEC_SAFE_BASE + 0x014CU) -#define SAFE_GRP0CR3 (LIFEC_SAFE_BASE + 0x0150U) -#define SAFE_GRP1CR3 (LIFEC_SAFE_BASE + 0x0154U) -#define SAFE_GRP0COND0 (LIFEC_SAFE_BASE + 0x0158U) -#define SAFE_GRP1COND0 (LIFEC_SAFE_BASE + 0x015CU) -#define SAFE_GRP0COND1 (LIFEC_SAFE_BASE + 0x0160U) -#define SAFE_GRP1COND1 (LIFEC_SAFE_BASE + 0x0164U) -#define SAFE_GRP0COND2 (LIFEC_SAFE_BASE + 0x0168U) -#define SAFE_GRP1COND2 (LIFEC_SAFE_BASE + 0x016CU) -#define SAFE_GRP0COND3 (LIFEC_SAFE_BASE + 0x0170U) -#define SAFE_GRP1COND3 (LIFEC_SAFE_BASE + 0x0174U) -#define SAFE_GRP0COND4 (LIFEC_SAFE_BASE + 0x0178U) -#define SAFE_GRP1COND4 (LIFEC_SAFE_BASE + 0x017CU) -#define SAFE_GRP0COND5 (LIFEC_SAFE_BASE + 0x0180U) -#define SAFE_GRP1COND5 (LIFEC_SAFE_BASE + 0x0184U) -#define SAFE_GRP0COND6 (LIFEC_SAFE_BASE + 0x0188U) -#define SAFE_GRP1COND6 (LIFEC_SAFE_BASE + 0x018CU) -#define SAFE_GRP0COND7 (LIFEC_SAFE_BASE + 0x0190U) -#define SAFE_GRP1COND7 (LIFEC_SAFE_BASE + 0x0194U) -#define SAFE_GRP0COND8 (LIFEC_SAFE_BASE + 0x0198U) -#define SAFE_GRP1COND8 (LIFEC_SAFE_BASE + 0x019CU) -#define SAFE_GRP0COND9 (LIFEC_SAFE_BASE + 0x01A0U) -#define SAFE_GRP1COND9 (LIFEC_SAFE_BASE + 0x01A4U) -#define SAFE_GRP0COND10 (LIFEC_SAFE_BASE + 0x01A8U) -#define SAFE_GRP1COND10 (LIFEC_SAFE_BASE + 0x01ACU) -#define SAFE_GRP0COND11 (LIFEC_SAFE_BASE + 0x01B0U) -#define SAFE_GRP1COND11 (LIFEC_SAFE_BASE + 0x01B4U) -#define SAFE_GRP0COND12 (LIFEC_SAFE_BASE + 0x01B8U) -#define SAFE_GRP1COND12 (LIFEC_SAFE_BASE + 0x01BCU) -#define SAFE_GRP0COND13 (LIFEC_SAFE_BASE + 0x01C0U) -#define SAFE_GRP1COND13 (LIFEC_SAFE_BASE + 0x01C4U) -#define SAFE_GRP0COND14 (LIFEC_SAFE_BASE + 0x01C8U) -#define SAFE_GRP1COND14 (LIFEC_SAFE_BASE + 0x01CCU) -#define SAFE_GRP0COND15 (LIFEC_SAFE_BASE + 0x01D0U) -#define SAFE_GRP1COND15 (LIFEC_SAFE_BASE + 0x01D4U) -#define SAFE_READONLY0 (LIFEC_SAFE_BASE + 0x01D8U) -#define SAFE_READONLY1 (LIFEC_SAFE_BASE + 0x01DCU) -#define SAFE_READONLY2 (LIFEC_SAFE_BASE + 0x01E0U) -#define SAFE_READONLY3 (LIFEC_SAFE_BASE + 0x01E4U) -#define SAFE_READONLY4 (LIFEC_SAFE_BASE + 0x01E8U) -#define SAFE_READONLY5 (LIFEC_SAFE_BASE + 0x01ECU) -#define SAFE_READONLY6 (LIFEC_SAFE_BASE + 0x01F0U) -#define SAFE_READONLY7 (LIFEC_SAFE_BASE + 0x01F4U) -#define SAFE_READONLY8 (LIFEC_SAFE_BASE + 0x01F8U) -#define SAFE_READONLY9 (LIFEC_SAFE_BASE + 0x01FCU) -#define SAFE_READONLY10 (LIFEC_SAFE_BASE + 0x0200U) -#define SAFE_READONLY11 (LIFEC_SAFE_BASE + 0x0204U) -#define SAFE_READONLY12 (LIFEC_SAFE_BASE + 0x0208U) -#define SAFE_READONLY13 (LIFEC_SAFE_BASE + 0x020CU) -#define SAFE_READONLY14 (LIFEC_SAFE_BASE + 0x0210U) -#define SAFE_READONLY15 (LIFEC_SAFE_BASE + 0x0214U) - -#endif /* LIFEC_REGISTERS_H */ diff --git a/plat/renesas/rcar/platform.mk b/plat/renesas/rcar/platform.mk index 4c41dd341..bdc29fe35 100644 --- a/plat/renesas/rcar/platform.mk +++ b/plat/renesas/rcar/platform.mk @@ -1,56 +1,10 @@ # -# Copyright (c) 2018-2019, Renesas Electronics Corporation. All rights reserved. +# Copyright (c) 2018-2020, Renesas Electronics Corporation. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # -PROGRAMMABLE_RESET_ADDRESS := 0 -COLD_BOOT_SINGLE_CPU := 1 -ARM_CCI_PRODUCT_ID := 500 -TRUSTED_BOARD_BOOT := 1 -RESET_TO_BL31 := 1 -GENERATE_COT := 1 -BL2_AT_EL3 := 1 -ENABLE_SVE_FOR_NS := 0 -MULTI_CONSOLE_API := 1 - -CRASH_REPORTING := 1 -HANDLE_EA_EL3_FIRST := 1 - -$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT)) - -ifeq (${SPD},none) - SPD_NONE:=1 - $(eval $(call add_define,SPD_NONE)) -endif - -# LSI setting common define -RCAR_H3:=0 -RCAR_M3:=1 -RCAR_M3N:=2 -RCAR_E3:=3 -RCAR_H3N:=4 -RCAR_D3:=5 -RCAR_V3M:=6 -RCAR_AUTO:=99 -$(eval $(call add_define,RCAR_H3)) -$(eval $(call add_define,RCAR_M3)) -$(eval $(call add_define,RCAR_M3N)) -$(eval $(call add_define,RCAR_E3)) -$(eval $(call add_define,RCAR_H3N)) -$(eval $(call add_define,RCAR_D3)) -$(eval $(call add_define,RCAR_V3M)) -$(eval $(call add_define,RCAR_AUTO)) -RCAR_CUT_10:=0 -RCAR_CUT_11:=1 -RCAR_CUT_13:=3 -RCAR_CUT_20:=10 -RCAR_CUT_30:=20 -$(eval $(call add_define,RCAR_CUT_10)) -$(eval $(call add_define,RCAR_CUT_11)) -$(eval $(call add_define,RCAR_CUT_13)) -$(eval $(call add_define,RCAR_CUT_20)) -$(eval $(call add_define,RCAR_CUT_30)) +include plat/renesas/common/common.mk ifndef LSI $(error "Error: Unknown LSI. Please use LSI= to specify the LSI") @@ -339,21 +293,12 @@ ifeq (${RCAR_SYSTEM_RESET_KEEPON_DDR},1) endif endif -# Enable workarounds for selected Cortex-A53 erratas. -ERRATA_A53_835769 := 1 -ERRATA_A53_843419 := 1 -ERRATA_A53_855873 := 1 - -# Enable workarounds for selected Cortex-A57 erratas. -ERRATA_A57_859972 := 1 -ERRATA_A57_813419 := 1 - include drivers/renesas/rcar/ddr/ddr.mk include drivers/renesas/rcar/qos/qos.mk include drivers/renesas/rcar/pfc/pfc.mk include lib/libfdt/libfdt.mk -PLAT_INCLUDES := -Idrivers/renesas/rcar/ddr \ +PLAT_INCLUDES += -Idrivers/renesas/rcar/ddr \ -Idrivers/renesas/rcar/qos \ -Idrivers/renesas/rcar/iic_dvfs \ -Idrivers/renesas/rcar/board \ @@ -364,25 +309,12 @@ PLAT_INCLUDES := -Idrivers/renesas/rcar/ddr \ -Idrivers/renesas/rcar/scif \ -Idrivers/renesas/rcar/emmc \ -Idrivers/renesas/rcar/pwrc \ - -Idrivers/renesas/rcar/io \ - -Iplat/renesas/rcar/include/registers \ - -Iplat/renesas/rcar/include \ - -Iplat/renesas/rcar + -Idrivers/renesas/rcar/io PLAT_BL_COMMON_SOURCES := drivers/renesas/rcar/iic_dvfs/iic_dvfs.c \ plat/renesas/rcar/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 \ - plat/common/plat_gicv2.c - -BL2_SOURCES += ${RCAR_GIC_SOURCES} \ - lib/cpus/aarch64/cortex_a53.S \ - lib/cpus/aarch64/cortex_a57.S \ - ${LIBFDT_SRCS} \ - common/desc_image_load.c \ - plat/renesas/rcar/aarch64/platform_common.c \ +BL2_SOURCES += plat/renesas/rcar/aarch64/platform_common.c \ plat/renesas/rcar/aarch64/plat_helpers.S \ plat/renesas/rcar/bl2_interrupt_error.c \ plat/renesas/rcar/bl2_secure_setting.c \ @@ -393,7 +325,6 @@ BL2_SOURCES += ${RCAR_GIC_SOURCES} \ plat/renesas/rcar/bl2_cpg_init.c \ drivers/renesas/rcar/console/rcar_printf.c \ drivers/renesas/rcar/scif/scif.S \ - drivers/renesas/rcar/common.c \ drivers/renesas/rcar/io/io_emmcdrv.c \ drivers/renesas/rcar/io/io_memdrv.c \ drivers/renesas/rcar/io/io_rcar.c \ @@ -410,14 +341,9 @@ BL2_SOURCES += ${RCAR_GIC_SOURCES} \ drivers/renesas/rcar/emmc/emmc_cmd.c \ drivers/renesas/rcar/watchdog/swdt.c \ drivers/renesas/rcar/rom/rom_api.c \ - drivers/renesas/rcar/board/board.c \ - drivers/io/io_storage.c - -BL31_SOURCES += ${RCAR_GIC_SOURCES} \ - lib/cpus/aarch64/cortex_a53.S \ - lib/cpus/aarch64/cortex_a57.S \ - plat/common/plat_psci_common.c \ - plat/renesas/rcar/plat_topology.c \ + drivers/renesas/rcar/board/board.c + +BL31_SOURCES += plat/renesas/rcar/plat_topology.c \ plat/renesas/rcar/aarch64/plat_helpers.S \ plat/renesas/rcar/aarch64/platform_common.c \ plat/renesas/rcar/bl31_plat_setup.c \ @@ -426,9 +352,7 @@ BL31_SOURCES += ${RCAR_GIC_SOURCES} \ drivers/renesas/rcar/console/rcar_printf.c \ drivers/renesas/rcar/delay/micro_delay.c \ drivers/renesas/rcar/pwrc/call_sram.S \ - drivers/renesas/rcar/pwrc/pwrc.c \ - drivers/renesas/rcar/common.c \ - drivers/arm/cci/cci.c + drivers/renesas/rcar/pwrc/pwrc.c ifeq (${RCAR_GEN3_ULCB},1) BL31_SOURCES += drivers/renesas/rcar/cpld/ulcb_cpld.c -- cgit v1.2.3 From e17997dfd6e615c99a2176d9bcaf7a73c6f618cd Mon Sep 17 00:00:00 2001 From: Biju Das Date: Wed, 16 Dec 2020 10:56:03 +0000 Subject: drivers: renesas: rom: Move to common Move rom driver code to common directory, so that the same code can be re-used by both R-Car Gen3 and RZ/G2 platforms. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: I399dfb5eff186db76d26fa9c54bea88bee66789c --- drivers/renesas/common/rom/rom_api.c | 106 +++++++++++++++++++++++++++++++++++ drivers/renesas/common/rom/rom_api.h | 31 ++++++++++ drivers/renesas/rcar/rom/rom_api.c | 106 ----------------------------------- drivers/renesas/rcar/rom/rom_api.h | 31 ---------- plat/renesas/common/common.mk | 1 + plat/renesas/rcar/platform.mk | 3 +- 6 files changed, 139 insertions(+), 139 deletions(-) create mode 100644 drivers/renesas/common/rom/rom_api.c create mode 100644 drivers/renesas/common/rom/rom_api.h delete mode 100644 drivers/renesas/rcar/rom/rom_api.c delete mode 100644 drivers/renesas/rcar/rom/rom_api.h diff --git a/drivers/renesas/common/rom/rom_api.c b/drivers/renesas/common/rom/rom_api.c new file mode 100644 index 000000000..fda28150e --- /dev/null +++ b/drivers/renesas/common/rom/rom_api.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include + +#include "rcar_def.h" +#include "rom_api.h" + +typedef uint32_t(*rom_secure_boot_api_f) (uint32_t *key, uint32_t *cert, + rom_read_flash_f pFuncReadFlash); + +typedef uint32_t(*rom_get_lcs_api_f) (uint32_t *lcs); + +#define OLD_API_TABLE1 (0U) /* H3 Ver.1.0/Ver.1.1 */ +#define OLD_API_TABLE2 (1U) /* H3 Ver.2.0 */ +#define OLD_API_TABLE3 (2U) /* M3 Ver.1.0 */ +#define NEW_API_TABLE (3U) /* H3 Ver.3.0, M3 Ver.1.1 or later, M3N, E3, D3, V3M WS2.0 */ +#define NEW_API_TABLE2 (4U) /* V3M WS1.0 */ +#define API_TABLE_MAX (5U) /* table max */ + /* Later than H3 Ver.2.0 */ + +static uint32_t get_table_index(void) +{ + uint32_t product; + uint32_t cut_ver; + uint32_t index; + + product = mmio_read_32(RCAR_PRR) & PRR_PRODUCT_MASK; + cut_ver = mmio_read_32(RCAR_PRR) & PRR_CUT_MASK; + + switch (product) { + case PRR_PRODUCT_H3: + if (cut_ver == PRR_PRODUCT_10) + index = OLD_API_TABLE1; + else if (cut_ver == PRR_PRODUCT_11) + index = OLD_API_TABLE1; + else if (cut_ver == PRR_PRODUCT_20) + index = OLD_API_TABLE2; + else + /* Later than H3 Ver.2.0 */ + index = NEW_API_TABLE; + break; + case PRR_PRODUCT_M3: + if (cut_ver == PRR_PRODUCT_10) + index = OLD_API_TABLE3; + else + /* M3 Ver.1.1 or later */ + index = NEW_API_TABLE; + break; + case PRR_PRODUCT_V3M: + if (cut_ver == PRR_PRODUCT_10) + /* V3M WS1.0 */ + index = NEW_API_TABLE2; + else + /* V3M WS2.0 or later */ + index = NEW_API_TABLE; + break; + default: + index = NEW_API_TABLE; + break; + } + + return index; +} + +uint32_t rcar_rom_secure_boot_api(uint32_t *key, uint32_t *cert, + rom_read_flash_f read_flash) +{ + static const uintptr_t rom_api_table[API_TABLE_MAX] = { + 0xEB10DD64U, /* H3 Ver.1.0/Ver.1.1 */ + 0xEB116ED4U, /* H3 Ver.2.0 */ + 0xEB1102FCU, /* M3 Ver.1.0 */ + 0xEB100180U, /* H3 Ver.3.0, M3 Ver.1.1 or later, M3N, E3, D3, V3M WS2.0 */ + 0xEB110128U, /* V3M WS1.0 */ + }; + rom_secure_boot_api_f secure_boot; + uint32_t index; + + index = get_table_index(); + secure_boot = (rom_secure_boot_api_f) rom_api_table[index]; + + return secure_boot(key, cert, read_flash); +} + +uint32_t rcar_rom_get_lcs(uint32_t *lcs) +{ + static const uintptr_t rom_get_lcs_table[API_TABLE_MAX] = { + 0xEB10DFE0U, /* H3 Ver.1.0/Ver.1.1 */ + 0xEB117150U, /* H3 Ver.2.0 */ + 0xEB110578U, /* M3 Ver.1.0 */ + 0xEB10018CU, /* H3 Ver.3.0, M3 Ver.1.1 or later, M3N, E3, D3, V3M WS2.0 */ + 0xEB1103A4U, /* V3M WS1.0 */ + }; + rom_get_lcs_api_f get_lcs; + uint32_t index; + + index = get_table_index(); + get_lcs = (rom_get_lcs_api_f) rom_get_lcs_table[index]; + + return get_lcs(lcs); +} diff --git a/drivers/renesas/common/rom/rom_api.h b/drivers/renesas/common/rom/rom_api.h new file mode 100644 index 000000000..1d5b03d7f --- /dev/null +++ b/drivers/renesas/common/rom/rom_api.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef ROM_API_H +#define ROM_API_H + +#include + +#define SBROM_OK (0x00000000U) +#define SBROM_ILLEGAL_INPUT_PARAM_ERR (0x0B000001U) +#define SBROM_ILLEGAL_OEM_HASH_VALUE_ERR (0x0B000008U) +#define SBROM_ILLEGAL_LCS_FOR_OPERATION_ERR (0x0B000010U) +#define SBROM_HASH_NOT_PROGRAMMED_ERR (0x0B000100U) +#define SBROM_PUB_KEY_HASH_VALIDATION_FAILURE (0xF1000006U) +#define SBROM_RSA_SIG_VERIFICATION_FAILED (0xF1000007U) + +#define LCS_CM (0x0U) +#define LCS_DM (0x1U) +#define LCS_SD (0x3U) +#define LCS_SE (0x5U) +#define LCS_FA (0x7U) + +typedef uint32_t(*rom_read_flash_f) (uint64_t src, uint8_t *dst, uint32_t len); +uint32_t rcar_rom_secure_boot_api(uint32_t *key, uint32_t *cert, + rom_read_flash_f f); +uint32_t rcar_rom_get_lcs(uint32_t *lcs); + +#endif /* ROM_API_H */ diff --git a/drivers/renesas/rcar/rom/rom_api.c b/drivers/renesas/rcar/rom/rom_api.c deleted file mode 100644 index fda28150e..000000000 --- a/drivers/renesas/rcar/rom/rom_api.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include - -#include "rcar_def.h" -#include "rom_api.h" - -typedef uint32_t(*rom_secure_boot_api_f) (uint32_t *key, uint32_t *cert, - rom_read_flash_f pFuncReadFlash); - -typedef uint32_t(*rom_get_lcs_api_f) (uint32_t *lcs); - -#define OLD_API_TABLE1 (0U) /* H3 Ver.1.0/Ver.1.1 */ -#define OLD_API_TABLE2 (1U) /* H3 Ver.2.0 */ -#define OLD_API_TABLE3 (2U) /* M3 Ver.1.0 */ -#define NEW_API_TABLE (3U) /* H3 Ver.3.0, M3 Ver.1.1 or later, M3N, E3, D3, V3M WS2.0 */ -#define NEW_API_TABLE2 (4U) /* V3M WS1.0 */ -#define API_TABLE_MAX (5U) /* table max */ - /* Later than H3 Ver.2.0 */ - -static uint32_t get_table_index(void) -{ - uint32_t product; - uint32_t cut_ver; - uint32_t index; - - product = mmio_read_32(RCAR_PRR) & PRR_PRODUCT_MASK; - cut_ver = mmio_read_32(RCAR_PRR) & PRR_CUT_MASK; - - switch (product) { - case PRR_PRODUCT_H3: - if (cut_ver == PRR_PRODUCT_10) - index = OLD_API_TABLE1; - else if (cut_ver == PRR_PRODUCT_11) - index = OLD_API_TABLE1; - else if (cut_ver == PRR_PRODUCT_20) - index = OLD_API_TABLE2; - else - /* Later than H3 Ver.2.0 */ - index = NEW_API_TABLE; - break; - case PRR_PRODUCT_M3: - if (cut_ver == PRR_PRODUCT_10) - index = OLD_API_TABLE3; - else - /* M3 Ver.1.1 or later */ - index = NEW_API_TABLE; - break; - case PRR_PRODUCT_V3M: - if (cut_ver == PRR_PRODUCT_10) - /* V3M WS1.0 */ - index = NEW_API_TABLE2; - else - /* V3M WS2.0 or later */ - index = NEW_API_TABLE; - break; - default: - index = NEW_API_TABLE; - break; - } - - return index; -} - -uint32_t rcar_rom_secure_boot_api(uint32_t *key, uint32_t *cert, - rom_read_flash_f read_flash) -{ - static const uintptr_t rom_api_table[API_TABLE_MAX] = { - 0xEB10DD64U, /* H3 Ver.1.0/Ver.1.1 */ - 0xEB116ED4U, /* H3 Ver.2.0 */ - 0xEB1102FCU, /* M3 Ver.1.0 */ - 0xEB100180U, /* H3 Ver.3.0, M3 Ver.1.1 or later, M3N, E3, D3, V3M WS2.0 */ - 0xEB110128U, /* V3M WS1.0 */ - }; - rom_secure_boot_api_f secure_boot; - uint32_t index; - - index = get_table_index(); - secure_boot = (rom_secure_boot_api_f) rom_api_table[index]; - - return secure_boot(key, cert, read_flash); -} - -uint32_t rcar_rom_get_lcs(uint32_t *lcs) -{ - static const uintptr_t rom_get_lcs_table[API_TABLE_MAX] = { - 0xEB10DFE0U, /* H3 Ver.1.0/Ver.1.1 */ - 0xEB117150U, /* H3 Ver.2.0 */ - 0xEB110578U, /* M3 Ver.1.0 */ - 0xEB10018CU, /* H3 Ver.3.0, M3 Ver.1.1 or later, M3N, E3, D3, V3M WS2.0 */ - 0xEB1103A4U, /* V3M WS1.0 */ - }; - rom_get_lcs_api_f get_lcs; - uint32_t index; - - index = get_table_index(); - get_lcs = (rom_get_lcs_api_f) rom_get_lcs_table[index]; - - return get_lcs(lcs); -} diff --git a/drivers/renesas/rcar/rom/rom_api.h b/drivers/renesas/rcar/rom/rom_api.h deleted file mode 100644 index 1d5b03d7f..000000000 --- a/drivers/renesas/rcar/rom/rom_api.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef ROM_API_H -#define ROM_API_H - -#include - -#define SBROM_OK (0x00000000U) -#define SBROM_ILLEGAL_INPUT_PARAM_ERR (0x0B000001U) -#define SBROM_ILLEGAL_OEM_HASH_VALUE_ERR (0x0B000008U) -#define SBROM_ILLEGAL_LCS_FOR_OPERATION_ERR (0x0B000010U) -#define SBROM_HASH_NOT_PROGRAMMED_ERR (0x0B000100U) -#define SBROM_PUB_KEY_HASH_VALIDATION_FAILURE (0xF1000006U) -#define SBROM_RSA_SIG_VERIFICATION_FAILED (0xF1000007U) - -#define LCS_CM (0x0U) -#define LCS_DM (0x1U) -#define LCS_SD (0x3U) -#define LCS_SE (0x5U) -#define LCS_FA (0x7U) - -typedef uint32_t(*rom_read_flash_f) (uint64_t src, uint8_t *dst, uint32_t len); -uint32_t rcar_rom_secure_boot_api(uint32_t *key, uint32_t *cert, - rom_read_flash_f f); -uint32_t rcar_rom_get_lcs(uint32_t *lcs); - -#endif /* ROM_API_H */ diff --git a/plat/renesas/common/common.mk b/plat/renesas/common/common.mk index dda7c89f2..09ff1d513 100644 --- a/plat/renesas/common/common.mk +++ b/plat/renesas/common/common.mk @@ -91,6 +91,7 @@ BL2_SOURCES += ${RCAR_GIC_SOURCES} \ drivers/renesas/common/emmc/emmc_init.c \ drivers/renesas/common/emmc/emmc_read.c \ drivers/renesas/common/emmc/emmc_cmd.c \ + drivers/renesas/common/rom/rom_api.c \ drivers/io/io_storage.c BL31_SOURCES += ${RCAR_GIC_SOURCES} \ diff --git a/plat/renesas/rcar/platform.mk b/plat/renesas/rcar/platform.mk index ca6fe6b73..4cd2f93b5 100644 --- a/plat/renesas/rcar/platform.mk +++ b/plat/renesas/rcar/platform.mk @@ -305,7 +305,7 @@ PLAT_INCLUDES += -Idrivers/renesas/rcar/ddr \ -Idrivers/renesas/common/iic_dvfs \ -Idrivers/renesas/rcar/avs \ -Idrivers/renesas/common/delay \ - -Idrivers/renesas/rcar/rom \ + -Idrivers/renesas/common/rom \ -Idrivers/renesas/common/scif \ -Idrivers/renesas/common/emmc \ -Idrivers/renesas/common/pwrc \ @@ -325,7 +325,6 @@ BL2_SOURCES += plat/renesas/rcar/aarch64/platform_common.c \ drivers/renesas/rcar/dma/dma_driver.c \ drivers/renesas/rcar/avs/avs_driver.c \ drivers/renesas/rcar/watchdog/swdt.c \ - drivers/renesas/rcar/rom/rom_api.c \ drivers/renesas/rcar/board/board.c BL31_SOURCES += plat/renesas/rcar/plat_topology.c \ -- cgit v1.2.3 From be92e5a22f83fe5e580b4c60148ec9b150b82c23 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Wed, 16 Dec 2020 09:43:41 +0000 Subject: drivers: renesas: Move plat common sources Move plat common sources to common directory, so that same code can be re-used by both R-Car Gen3 and RZ/G2 platforms. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: Id2b1822c97cc50e3febaffc2e5f42b4d53809a17 --- drivers/renesas/common/iic_dvfs/iic_dvfs.c | 600 +++++++++++++++++++++++++++++ drivers/renesas/common/iic_dvfs/iic_dvfs.h | 23 ++ drivers/renesas/rcar/iic_dvfs/iic_dvfs.c | 600 ----------------------------- drivers/renesas/rcar/iic_dvfs/iic_dvfs.h | 23 -- plat/renesas/common/common.mk | 7 + plat/renesas/common/rcar_common.c | 104 +++++ plat/renesas/rcar/platform.mk | 9 +- plat/renesas/rcar/rcar_common.c | 104 ----- 8 files changed, 735 insertions(+), 735 deletions(-) create mode 100644 drivers/renesas/common/iic_dvfs/iic_dvfs.c create mode 100644 drivers/renesas/common/iic_dvfs/iic_dvfs.h delete mode 100644 drivers/renesas/rcar/iic_dvfs/iic_dvfs.c delete mode 100644 drivers/renesas/rcar/iic_dvfs/iic_dvfs.h create mode 100644 plat/renesas/common/rcar_common.c delete mode 100644 plat/renesas/rcar/rcar_common.c diff --git a/drivers/renesas/common/iic_dvfs/iic_dvfs.c b/drivers/renesas/common/iic_dvfs/iic_dvfs.c new file mode 100644 index 000000000..e1c9a5bd4 --- /dev/null +++ b/drivers/renesas/common/iic_dvfs/iic_dvfs.c @@ -0,0 +1,600 @@ +/* + * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include "cpg_registers.h" +#include "iic_dvfs.h" +#include "rcar_def.h" +#include "rcar_private.h" + +#define DVFS_RETRY_MAX (2U) + +#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_0 (0x07U) +#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_1 (0x09U) +#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_2 (0x0BU) +#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_3 (0x0EU) +#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_E (0x15U) + +#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_0 (0x01U) +#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_1 (0x02U) +#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_2 (0x03U) +#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_3 (0x05U) +#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_E (0x07U) + +#define CPG_BIT_SMSTPCR9_DVFS (0x04000000U) + +#define IIC_DVFS_REG_BASE (0xE60B0000U) +#define IIC_DVFS_REG_ICDR (IIC_DVFS_REG_BASE + 0x0000U) +#define IIC_DVFS_REG_ICCR (IIC_DVFS_REG_BASE + 0x0004U) +#define IIC_DVFS_REG_ICSR (IIC_DVFS_REG_BASE + 0x0008U) +#define IIC_DVFS_REG_ICIC (IIC_DVFS_REG_BASE + 0x000CU) +#define IIC_DVFS_REG_ICCL (IIC_DVFS_REG_BASE + 0x0010U) +#define IIC_DVFS_REG_ICCH (IIC_DVFS_REG_BASE + 0x0014U) + +#define IIC_DVFS_BIT_ICSR_BUSY (0x10U) +#define IIC_DVFS_BIT_ICSR_AL (0x08U) +#define IIC_DVFS_BIT_ICSR_TACK (0x04U) +#define IIC_DVFS_BIT_ICSR_WAIT (0x02U) +#define IIC_DVFS_BIT_ICSR_DTE (0x01U) + +#define IIC_DVFS_BIT_ICCR_ENABLE (0x80U) +#define IIC_DVFS_SET_ICCR_START (0x94U) +#define IIC_DVFS_SET_ICCR_STOP (0x90U) +#define IIC_DVFS_SET_ICCR_RETRANSMISSION (0x94U) +#define IIC_DVFS_SET_ICCR_CHANGE (0x81U) +#define IIC_DVFS_SET_ICCR_STOP_READ (0xC0U) + +#define IIC_DVFS_BIT_ICIC_TACKE (0x04U) +#define IIC_DVFS_BIT_ICIC_WAITE (0x02U) +#define IIC_DVFS_BIT_ICIC_DTEE (0x01U) + +#define DVFS_READ_MODE (0x01U) +#define DVFS_WRITE_MODE (0x00U) + +#define IIC_DVFS_SET_DUMMY (0x52U) +#define IIC_DVFS_SET_BUSY_LOOP (500000000U) + +enum dvfs_state_t { + DVFS_START = 0, + DVFS_STOP, + DVFS_RETRANSMIT, + DVFS_READ, + DVFS_STOP_READ, + DVFS_SET_SLAVE_READ, + DVFS_SET_SLAVE, + DVFS_WRITE_ADDR, + DVFS_WRITE_DATA, + DVFS_CHANGE_SEND_TO_RECEIVE, + DVFS_DONE, +}; + +#define DVFS_PROCESS (1) +#define DVFS_COMPLETE (0) +#define DVFS_ERROR (-1) + +#if IMAGE_BL31 +#define IIC_DVFS_FUNC(__name, ...) \ +static int32_t __attribute__ ((section(".system_ram"))) \ +dvfs_ ##__name(__VA_ARGS__) + +#define RCAR_DVFS_API(__name, ...) \ +int32_t __attribute__ ((section(".system_ram"))) \ +rcar_iic_dvfs_ ##__name(__VA_ARGS__) + +#else +#define IIC_DVFS_FUNC(__name, ...) \ +static int32_t dvfs_ ##__name(__VA_ARGS__) + +#define RCAR_DVFS_API(__name, ...) \ +int32_t rcar_iic_dvfs_ ##__name(__VA_ARGS__) +#endif + +IIC_DVFS_FUNC(check_error, enum dvfs_state_t *state, uint32_t *err, uint8_t mode) +{ + uint8_t icsr_al = 0U, icsr_tack = 0U; + uint8_t reg, stop; + uint32_t i = 0U; + + stop = mode == DVFS_READ_MODE ? IIC_DVFS_SET_ICCR_STOP_READ : + IIC_DVFS_SET_ICCR_STOP; + + reg = mmio_read_8(IIC_DVFS_REG_ICSR); + icsr_al = (reg & IIC_DVFS_BIT_ICSR_AL) == IIC_DVFS_BIT_ICSR_AL; + icsr_tack = (reg & IIC_DVFS_BIT_ICSR_TACK) == IIC_DVFS_BIT_ICSR_TACK; + + if (icsr_al == 0U && icsr_tack == 0U) { + return DVFS_PROCESS; + } + + if (icsr_al) { + reg = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_AL; + mmio_write_8(IIC_DVFS_REG_ICSR, reg); + + if (*state == DVFS_SET_SLAVE) { + mmio_write_8(IIC_DVFS_REG_ICDR, IIC_DVFS_SET_DUMMY); + } + + do { + reg = mmio_read_8(IIC_DVFS_REG_ICSR) & + IIC_DVFS_BIT_ICSR_WAIT; + } while (reg == 0U); + + mmio_write_8(IIC_DVFS_REG_ICCR, stop); + + reg = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT; + mmio_write_8(IIC_DVFS_REG_ICSR, reg); + + i = 0U; + do { + reg = mmio_read_8(IIC_DVFS_REG_ICSR) & + IIC_DVFS_BIT_ICSR_BUSY; + if (reg == 0U) { + break; + } + + if (i++ > IIC_DVFS_SET_BUSY_LOOP) { + panic(); + } + + } while (true); + + mmio_write_8(IIC_DVFS_REG_ICCR, 0x00U); + + (*err)++; + if (*err > DVFS_RETRY_MAX) { + return DVFS_ERROR; + } + + *state = DVFS_START; + + return DVFS_PROCESS; + + } + + /* icsr_tack */ + mmio_write_8(IIC_DVFS_REG_ICCR, stop); + + reg = mmio_read_8(IIC_DVFS_REG_ICIC); + reg &= ~(IIC_DVFS_BIT_ICIC_WAITE | IIC_DVFS_BIT_ICIC_DTEE); + mmio_write_8(IIC_DVFS_REG_ICIC, reg); + + reg = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_TACK; + mmio_write_8(IIC_DVFS_REG_ICSR, reg); + + i = 0U; + while ((mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_BUSY) != 0U) { + if (i++ > IIC_DVFS_SET_BUSY_LOOP) { + panic(); + } + } + + mmio_write_8(IIC_DVFS_REG_ICCR, 0U); + (*err)++; + + if (*err > DVFS_RETRY_MAX) { + return DVFS_ERROR; + } + + *state = DVFS_START; + + return DVFS_PROCESS; +} + +IIC_DVFS_FUNC(start, enum dvfs_state_t *state) +{ + uint8_t iccl = IIC_DVFS_SET_ICCL_EXTAL_TYPE_E; + uint8_t icch = IIC_DVFS_SET_ICCH_EXTAL_TYPE_E; + int32_t result = DVFS_PROCESS; + uint32_t reg, lsi_product; + uint8_t mode; + + mode = mmio_read_8(IIC_DVFS_REG_ICCR) | IIC_DVFS_BIT_ICCR_ENABLE; + mmio_write_8(IIC_DVFS_REG_ICCR, mode); + + lsi_product = mmio_read_32(RCAR_PRR) & PRR_PRODUCT_MASK; + if (lsi_product == PRR_PRODUCT_E3) { + goto start; + } + + reg = mmio_read_32(RCAR_MODEMR) & CHECK_MD13_MD14; + switch (reg) { + case MD14_MD13_TYPE_0: + iccl = IIC_DVFS_SET_ICCL_EXTAL_TYPE_0; + icch = IIC_DVFS_SET_ICCH_EXTAL_TYPE_0; + break; + case MD14_MD13_TYPE_1: + iccl = IIC_DVFS_SET_ICCL_EXTAL_TYPE_1; + icch = IIC_DVFS_SET_ICCH_EXTAL_TYPE_1; + break; + case MD14_MD13_TYPE_2: + iccl = IIC_DVFS_SET_ICCL_EXTAL_TYPE_2; + icch = IIC_DVFS_SET_ICCH_EXTAL_TYPE_2; + break; + default: + iccl = IIC_DVFS_SET_ICCL_EXTAL_TYPE_3; + icch = IIC_DVFS_SET_ICCH_EXTAL_TYPE_3; + break; + } +start: + mmio_write_8(IIC_DVFS_REG_ICCL, iccl); + mmio_write_8(IIC_DVFS_REG_ICCH, icch); + + mode = mmio_read_8(IIC_DVFS_REG_ICIC) + | IIC_DVFS_BIT_ICIC_TACKE + | IIC_DVFS_BIT_ICIC_WAITE | IIC_DVFS_BIT_ICIC_DTEE; + + mmio_write_8(IIC_DVFS_REG_ICIC, mode); + mmio_write_8(IIC_DVFS_REG_ICCR, IIC_DVFS_SET_ICCR_START); + + *state = DVFS_SET_SLAVE; + + return result; +} + +IIC_DVFS_FUNC(set_slave, enum dvfs_state_t *state, uint32_t *err, uint8_t slave) +{ + uint8_t mode; + int32_t result; + uint8_t address; + + result = dvfs_check_error(state, err, DVFS_WRITE_MODE); + if (result == DVFS_ERROR) { + return result; + } + + mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_DTE; + if (mode != IIC_DVFS_BIT_ICSR_DTE) { + return result; + } + + mode = mmio_read_8(IIC_DVFS_REG_ICIC) & ~IIC_DVFS_BIT_ICIC_DTEE; + mmio_write_8(IIC_DVFS_REG_ICIC, mode); + + address = slave << 1; + mmio_write_8(IIC_DVFS_REG_ICDR, address); + + *state = DVFS_WRITE_ADDR; + + return result; +} + +IIC_DVFS_FUNC(write_addr, enum dvfs_state_t *state, uint32_t *err, uint8_t reg_addr) +{ + uint8_t mode; + int32_t result; + + result = dvfs_check_error(state, err, DVFS_WRITE_MODE); + if (result == DVFS_ERROR) { + return result; + } + + mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT; + if (mode != IIC_DVFS_BIT_ICSR_WAIT) { + return result; + } + + mmio_write_8(IIC_DVFS_REG_ICDR, reg_addr); + + mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT; + mmio_write_8(IIC_DVFS_REG_ICSR, mode); + + *state = DVFS_WRITE_DATA; + + return result; +} + +IIC_DVFS_FUNC(write_data, enum dvfs_state_t *state, uint32_t *err, + uint8_t reg_data) +{ + int32_t result; + uint8_t mode; + + result = dvfs_check_error(state, err, DVFS_WRITE_MODE); + if (result == DVFS_ERROR) { + return result; + } + + mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT; + if (mode != IIC_DVFS_BIT_ICSR_WAIT) { + return result; + } + + mmio_write_8(IIC_DVFS_REG_ICDR, reg_data); + + mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT; + mmio_write_8(IIC_DVFS_REG_ICSR, mode); + + *state = DVFS_STOP; + + return result; +} + +IIC_DVFS_FUNC(stop, enum dvfs_state_t *state, uint32_t *err) +{ + int32_t result; + uint8_t mode; + + result = dvfs_check_error(state, err, DVFS_WRITE_MODE); + if (result == DVFS_ERROR) { + return result; + } + + mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT; + if (mode != IIC_DVFS_BIT_ICSR_WAIT) { + return result; + } + + mmio_write_8(IIC_DVFS_REG_ICCR, IIC_DVFS_SET_ICCR_STOP); + + mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT; + mmio_write_8(IIC_DVFS_REG_ICSR, mode); + + *state = DVFS_DONE; + + return result; +} + +IIC_DVFS_FUNC(done, void) +{ + uint32_t i; + + for (i = 0U; i < IIC_DVFS_SET_BUSY_LOOP; i++) { + if ((mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_BUSY) != 0U) { + continue; + } + goto done; + } + + panic(); +done: + mmio_write_8(IIC_DVFS_REG_ICCR, 0U); + + return DVFS_COMPLETE; +} + +IIC_DVFS_FUNC(write_reg_addr_read, enum dvfs_state_t *state, uint32_t *err, + uint8_t reg_addr) +{ + int32_t result; + uint8_t mode; + + result = dvfs_check_error(state, err, DVFS_WRITE_MODE); + if (result == DVFS_ERROR) { + return result; + } + + mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT; + if (mode != IIC_DVFS_BIT_ICSR_WAIT) { + return result; + } + + mmio_write_8(IIC_DVFS_REG_ICDR, reg_addr); + + mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT; + mmio_write_8(IIC_DVFS_REG_ICSR, mode); + + *state = DVFS_RETRANSMIT; + + return result; +} + +IIC_DVFS_FUNC(retransmit, enum dvfs_state_t *state, uint32_t *err) +{ + int32_t result; + uint8_t mode; + + result = dvfs_check_error(state, err, DVFS_WRITE_MODE); + if (result == DVFS_ERROR) { + return result; + } + + mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT; + if (mode != IIC_DVFS_BIT_ICSR_WAIT) { + return result; + } + + mmio_write_8(IIC_DVFS_REG_ICCR, IIC_DVFS_SET_ICCR_RETRANSMISSION); + + mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT; + mmio_write_8(IIC_DVFS_REG_ICSR, mode); + + mode = mmio_read_8(IIC_DVFS_REG_ICIC) | IIC_DVFS_BIT_ICIC_DTEE; + mmio_write_8(IIC_DVFS_REG_ICIC, mode); + + *state = DVFS_SET_SLAVE_READ; + + return result; +} + +IIC_DVFS_FUNC(set_slave_read, enum dvfs_state_t *state, uint32_t *err, + uint8_t slave) +{ + uint8_t address; + int32_t result; + uint8_t mode; + + result = dvfs_check_error(state, err, DVFS_WRITE_MODE); + if (result == DVFS_ERROR) { + return result; + } + + mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_DTE; + if (mode != IIC_DVFS_BIT_ICSR_DTE) { + return result; + } + + mode = mmio_read_8(IIC_DVFS_REG_ICIC) & ~IIC_DVFS_BIT_ICIC_DTEE; + mmio_write_8(IIC_DVFS_REG_ICIC, mode); + + address = ((uint8_t) (slave << 1) + DVFS_READ_MODE); + mmio_write_8(IIC_DVFS_REG_ICDR, address); + + *state = DVFS_CHANGE_SEND_TO_RECEIVE; + + return result; +} + +IIC_DVFS_FUNC(change_send_to_receive, enum dvfs_state_t *state, uint32_t *err) +{ + int32_t result; + uint8_t mode; + + result = dvfs_check_error(state, err, DVFS_WRITE_MODE); + if (result == DVFS_ERROR) { + return result; + } + + mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT; + if (mode != IIC_DVFS_BIT_ICSR_WAIT) { + return result; + } + + mmio_write_8(IIC_DVFS_REG_ICCR, IIC_DVFS_SET_ICCR_CHANGE); + + mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT; + mmio_write_8(IIC_DVFS_REG_ICSR, mode); + + *state = DVFS_STOP_READ; + + return result; +} + +IIC_DVFS_FUNC(stop_read, enum dvfs_state_t *state, uint32_t *err) +{ + int32_t result; + uint8_t mode; + + result = dvfs_check_error(state, err, DVFS_READ_MODE); + if (result == DVFS_ERROR) { + return result; + } + + mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT; + if (mode != IIC_DVFS_BIT_ICSR_WAIT) { + return result; + } + + mmio_write_8(IIC_DVFS_REG_ICCR, IIC_DVFS_SET_ICCR_STOP_READ); + + mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT; + mmio_write_8(IIC_DVFS_REG_ICSR, mode); + + mode = mmio_read_8(IIC_DVFS_REG_ICIC) | IIC_DVFS_BIT_ICIC_DTEE; + mmio_write_8(IIC_DVFS_REG_ICIC, mode); + + *state = DVFS_READ; + + return result; +} + +IIC_DVFS_FUNC(read, enum dvfs_state_t *state, uint8_t *reg_data) +{ + uint8_t mode; + + mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_DTE; + if (mode != IIC_DVFS_BIT_ICSR_DTE) { + return DVFS_PROCESS; + } + + mode = mmio_read_8(IIC_DVFS_REG_ICIC) & ~IIC_DVFS_BIT_ICIC_DTEE; + mmio_write_8(IIC_DVFS_REG_ICIC, mode); + + *reg_data = mmio_read_8(IIC_DVFS_REG_ICDR); + *state = DVFS_DONE; + + return DVFS_PROCESS; +} + +RCAR_DVFS_API(send, uint8_t slave, uint8_t reg_addr, uint8_t reg_data) +{ + enum dvfs_state_t state = DVFS_START; + int32_t result = DVFS_PROCESS; + uint32_t err = 0U; + + mstpcr_write(SCMSTPCR9, CPG_MSTPSR9, CPG_BIT_SMSTPCR9_DVFS); + mmio_write_8(IIC_DVFS_REG_ICCR, 0U); +again: + switch (state) { + case DVFS_START: + result = dvfs_start(&state); + break; + case DVFS_SET_SLAVE: + result = dvfs_set_slave(&state, &err, slave); + break; + case DVFS_WRITE_ADDR: + result = dvfs_write_addr(&state, &err, reg_addr); + break; + case DVFS_WRITE_DATA: + result = dvfs_write_data(&state, &err, reg_data); + break; + case DVFS_STOP: + result = dvfs_stop(&state, &err); + break; + case DVFS_DONE: + result = dvfs_done(); + break; + default: + panic(); + break; + } + + if (result == DVFS_PROCESS) { + goto again; + } + + return result; +} + +RCAR_DVFS_API(receive, uint8_t slave, uint8_t reg, uint8_t *data) +{ + enum dvfs_state_t state = DVFS_START; + int32_t result = DVFS_PROCESS; + uint32_t err = 0U; + + mstpcr_write(SCMSTPCR9, CPG_MSTPSR9, CPG_BIT_SMSTPCR9_DVFS); + mmio_write_8(IIC_DVFS_REG_ICCR, 0U); +again: + switch (state) { + case DVFS_START: + result = dvfs_start(&state); + break; + case DVFS_SET_SLAVE: + result = dvfs_set_slave(&state, &err, slave); + break; + case DVFS_WRITE_ADDR: + result = dvfs_write_reg_addr_read(&state, &err, reg); + break; + case DVFS_RETRANSMIT: + result = dvfs_retransmit(&state, &err); + break; + case DVFS_SET_SLAVE_READ: + result = dvfs_set_slave_read(&state, &err, slave); + break; + case DVFS_CHANGE_SEND_TO_RECEIVE: + result = dvfs_change_send_to_receive(&state, &err); + break; + case DVFS_STOP_READ: + result = dvfs_stop_read(&state, &err); + break; + case DVFS_READ: + result = dvfs_read(&state, data); + break; + case DVFS_DONE: + result = dvfs_done(); + break; + default: + panic(); + break; + } + + if (result == DVFS_PROCESS) { + goto again; + } + + return result; +} diff --git a/drivers/renesas/common/iic_dvfs/iic_dvfs.h b/drivers/renesas/common/iic_dvfs/iic_dvfs.h new file mode 100644 index 000000000..244c06cfd --- /dev/null +++ b/drivers/renesas/common/iic_dvfs/iic_dvfs.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef IIC_DVFS_H +#define IIC_DVFS_H + +/* PMIC slave */ +#define PMIC (0x30U) +#define BKUP_MODE_CNT (0x20U) +#define DVFS_SET_VID (0x54U) +#define REG_KEEP10 (0x79U) + +/* EEPROM slave */ +#define EEPROM (0x50U) +#define BOARD_ID (0x70U) + +int32_t rcar_iic_dvfs_receive(uint8_t slave, uint8_t reg, uint8_t *data); +int32_t rcar_iic_dvfs_send(uint8_t slave, uint8_t regr, uint8_t data); + +#endif /* IIC_DVFS_H */ diff --git a/drivers/renesas/rcar/iic_dvfs/iic_dvfs.c b/drivers/renesas/rcar/iic_dvfs/iic_dvfs.c deleted file mode 100644 index e1c9a5bd4..000000000 --- a/drivers/renesas/rcar/iic_dvfs/iic_dvfs.c +++ /dev/null @@ -1,600 +0,0 @@ -/* - * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include - -#include "cpg_registers.h" -#include "iic_dvfs.h" -#include "rcar_def.h" -#include "rcar_private.h" - -#define DVFS_RETRY_MAX (2U) - -#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_0 (0x07U) -#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_1 (0x09U) -#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_2 (0x0BU) -#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_3 (0x0EU) -#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_E (0x15U) - -#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_0 (0x01U) -#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_1 (0x02U) -#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_2 (0x03U) -#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_3 (0x05U) -#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_E (0x07U) - -#define CPG_BIT_SMSTPCR9_DVFS (0x04000000U) - -#define IIC_DVFS_REG_BASE (0xE60B0000U) -#define IIC_DVFS_REG_ICDR (IIC_DVFS_REG_BASE + 0x0000U) -#define IIC_DVFS_REG_ICCR (IIC_DVFS_REG_BASE + 0x0004U) -#define IIC_DVFS_REG_ICSR (IIC_DVFS_REG_BASE + 0x0008U) -#define IIC_DVFS_REG_ICIC (IIC_DVFS_REG_BASE + 0x000CU) -#define IIC_DVFS_REG_ICCL (IIC_DVFS_REG_BASE + 0x0010U) -#define IIC_DVFS_REG_ICCH (IIC_DVFS_REG_BASE + 0x0014U) - -#define IIC_DVFS_BIT_ICSR_BUSY (0x10U) -#define IIC_DVFS_BIT_ICSR_AL (0x08U) -#define IIC_DVFS_BIT_ICSR_TACK (0x04U) -#define IIC_DVFS_BIT_ICSR_WAIT (0x02U) -#define IIC_DVFS_BIT_ICSR_DTE (0x01U) - -#define IIC_DVFS_BIT_ICCR_ENABLE (0x80U) -#define IIC_DVFS_SET_ICCR_START (0x94U) -#define IIC_DVFS_SET_ICCR_STOP (0x90U) -#define IIC_DVFS_SET_ICCR_RETRANSMISSION (0x94U) -#define IIC_DVFS_SET_ICCR_CHANGE (0x81U) -#define IIC_DVFS_SET_ICCR_STOP_READ (0xC0U) - -#define IIC_DVFS_BIT_ICIC_TACKE (0x04U) -#define IIC_DVFS_BIT_ICIC_WAITE (0x02U) -#define IIC_DVFS_BIT_ICIC_DTEE (0x01U) - -#define DVFS_READ_MODE (0x01U) -#define DVFS_WRITE_MODE (0x00U) - -#define IIC_DVFS_SET_DUMMY (0x52U) -#define IIC_DVFS_SET_BUSY_LOOP (500000000U) - -enum dvfs_state_t { - DVFS_START = 0, - DVFS_STOP, - DVFS_RETRANSMIT, - DVFS_READ, - DVFS_STOP_READ, - DVFS_SET_SLAVE_READ, - DVFS_SET_SLAVE, - DVFS_WRITE_ADDR, - DVFS_WRITE_DATA, - DVFS_CHANGE_SEND_TO_RECEIVE, - DVFS_DONE, -}; - -#define DVFS_PROCESS (1) -#define DVFS_COMPLETE (0) -#define DVFS_ERROR (-1) - -#if IMAGE_BL31 -#define IIC_DVFS_FUNC(__name, ...) \ -static int32_t __attribute__ ((section(".system_ram"))) \ -dvfs_ ##__name(__VA_ARGS__) - -#define RCAR_DVFS_API(__name, ...) \ -int32_t __attribute__ ((section(".system_ram"))) \ -rcar_iic_dvfs_ ##__name(__VA_ARGS__) - -#else -#define IIC_DVFS_FUNC(__name, ...) \ -static int32_t dvfs_ ##__name(__VA_ARGS__) - -#define RCAR_DVFS_API(__name, ...) \ -int32_t rcar_iic_dvfs_ ##__name(__VA_ARGS__) -#endif - -IIC_DVFS_FUNC(check_error, enum dvfs_state_t *state, uint32_t *err, uint8_t mode) -{ - uint8_t icsr_al = 0U, icsr_tack = 0U; - uint8_t reg, stop; - uint32_t i = 0U; - - stop = mode == DVFS_READ_MODE ? IIC_DVFS_SET_ICCR_STOP_READ : - IIC_DVFS_SET_ICCR_STOP; - - reg = mmio_read_8(IIC_DVFS_REG_ICSR); - icsr_al = (reg & IIC_DVFS_BIT_ICSR_AL) == IIC_DVFS_BIT_ICSR_AL; - icsr_tack = (reg & IIC_DVFS_BIT_ICSR_TACK) == IIC_DVFS_BIT_ICSR_TACK; - - if (icsr_al == 0U && icsr_tack == 0U) { - return DVFS_PROCESS; - } - - if (icsr_al) { - reg = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_AL; - mmio_write_8(IIC_DVFS_REG_ICSR, reg); - - if (*state == DVFS_SET_SLAVE) { - mmio_write_8(IIC_DVFS_REG_ICDR, IIC_DVFS_SET_DUMMY); - } - - do { - reg = mmio_read_8(IIC_DVFS_REG_ICSR) & - IIC_DVFS_BIT_ICSR_WAIT; - } while (reg == 0U); - - mmio_write_8(IIC_DVFS_REG_ICCR, stop); - - reg = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT; - mmio_write_8(IIC_DVFS_REG_ICSR, reg); - - i = 0U; - do { - reg = mmio_read_8(IIC_DVFS_REG_ICSR) & - IIC_DVFS_BIT_ICSR_BUSY; - if (reg == 0U) { - break; - } - - if (i++ > IIC_DVFS_SET_BUSY_LOOP) { - panic(); - } - - } while (true); - - mmio_write_8(IIC_DVFS_REG_ICCR, 0x00U); - - (*err)++; - if (*err > DVFS_RETRY_MAX) { - return DVFS_ERROR; - } - - *state = DVFS_START; - - return DVFS_PROCESS; - - } - - /* icsr_tack */ - mmio_write_8(IIC_DVFS_REG_ICCR, stop); - - reg = mmio_read_8(IIC_DVFS_REG_ICIC); - reg &= ~(IIC_DVFS_BIT_ICIC_WAITE | IIC_DVFS_BIT_ICIC_DTEE); - mmio_write_8(IIC_DVFS_REG_ICIC, reg); - - reg = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_TACK; - mmio_write_8(IIC_DVFS_REG_ICSR, reg); - - i = 0U; - while ((mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_BUSY) != 0U) { - if (i++ > IIC_DVFS_SET_BUSY_LOOP) { - panic(); - } - } - - mmio_write_8(IIC_DVFS_REG_ICCR, 0U); - (*err)++; - - if (*err > DVFS_RETRY_MAX) { - return DVFS_ERROR; - } - - *state = DVFS_START; - - return DVFS_PROCESS; -} - -IIC_DVFS_FUNC(start, enum dvfs_state_t *state) -{ - uint8_t iccl = IIC_DVFS_SET_ICCL_EXTAL_TYPE_E; - uint8_t icch = IIC_DVFS_SET_ICCH_EXTAL_TYPE_E; - int32_t result = DVFS_PROCESS; - uint32_t reg, lsi_product; - uint8_t mode; - - mode = mmio_read_8(IIC_DVFS_REG_ICCR) | IIC_DVFS_BIT_ICCR_ENABLE; - mmio_write_8(IIC_DVFS_REG_ICCR, mode); - - lsi_product = mmio_read_32(RCAR_PRR) & PRR_PRODUCT_MASK; - if (lsi_product == PRR_PRODUCT_E3) { - goto start; - } - - reg = mmio_read_32(RCAR_MODEMR) & CHECK_MD13_MD14; - switch (reg) { - case MD14_MD13_TYPE_0: - iccl = IIC_DVFS_SET_ICCL_EXTAL_TYPE_0; - icch = IIC_DVFS_SET_ICCH_EXTAL_TYPE_0; - break; - case MD14_MD13_TYPE_1: - iccl = IIC_DVFS_SET_ICCL_EXTAL_TYPE_1; - icch = IIC_DVFS_SET_ICCH_EXTAL_TYPE_1; - break; - case MD14_MD13_TYPE_2: - iccl = IIC_DVFS_SET_ICCL_EXTAL_TYPE_2; - icch = IIC_DVFS_SET_ICCH_EXTAL_TYPE_2; - break; - default: - iccl = IIC_DVFS_SET_ICCL_EXTAL_TYPE_3; - icch = IIC_DVFS_SET_ICCH_EXTAL_TYPE_3; - break; - } -start: - mmio_write_8(IIC_DVFS_REG_ICCL, iccl); - mmio_write_8(IIC_DVFS_REG_ICCH, icch); - - mode = mmio_read_8(IIC_DVFS_REG_ICIC) - | IIC_DVFS_BIT_ICIC_TACKE - | IIC_DVFS_BIT_ICIC_WAITE | IIC_DVFS_BIT_ICIC_DTEE; - - mmio_write_8(IIC_DVFS_REG_ICIC, mode); - mmio_write_8(IIC_DVFS_REG_ICCR, IIC_DVFS_SET_ICCR_START); - - *state = DVFS_SET_SLAVE; - - return result; -} - -IIC_DVFS_FUNC(set_slave, enum dvfs_state_t *state, uint32_t *err, uint8_t slave) -{ - uint8_t mode; - int32_t result; - uint8_t address; - - result = dvfs_check_error(state, err, DVFS_WRITE_MODE); - if (result == DVFS_ERROR) { - return result; - } - - mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_DTE; - if (mode != IIC_DVFS_BIT_ICSR_DTE) { - return result; - } - - mode = mmio_read_8(IIC_DVFS_REG_ICIC) & ~IIC_DVFS_BIT_ICIC_DTEE; - mmio_write_8(IIC_DVFS_REG_ICIC, mode); - - address = slave << 1; - mmio_write_8(IIC_DVFS_REG_ICDR, address); - - *state = DVFS_WRITE_ADDR; - - return result; -} - -IIC_DVFS_FUNC(write_addr, enum dvfs_state_t *state, uint32_t *err, uint8_t reg_addr) -{ - uint8_t mode; - int32_t result; - - result = dvfs_check_error(state, err, DVFS_WRITE_MODE); - if (result == DVFS_ERROR) { - return result; - } - - mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT; - if (mode != IIC_DVFS_BIT_ICSR_WAIT) { - return result; - } - - mmio_write_8(IIC_DVFS_REG_ICDR, reg_addr); - - mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT; - mmio_write_8(IIC_DVFS_REG_ICSR, mode); - - *state = DVFS_WRITE_DATA; - - return result; -} - -IIC_DVFS_FUNC(write_data, enum dvfs_state_t *state, uint32_t *err, - uint8_t reg_data) -{ - int32_t result; - uint8_t mode; - - result = dvfs_check_error(state, err, DVFS_WRITE_MODE); - if (result == DVFS_ERROR) { - return result; - } - - mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT; - if (mode != IIC_DVFS_BIT_ICSR_WAIT) { - return result; - } - - mmio_write_8(IIC_DVFS_REG_ICDR, reg_data); - - mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT; - mmio_write_8(IIC_DVFS_REG_ICSR, mode); - - *state = DVFS_STOP; - - return result; -} - -IIC_DVFS_FUNC(stop, enum dvfs_state_t *state, uint32_t *err) -{ - int32_t result; - uint8_t mode; - - result = dvfs_check_error(state, err, DVFS_WRITE_MODE); - if (result == DVFS_ERROR) { - return result; - } - - mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT; - if (mode != IIC_DVFS_BIT_ICSR_WAIT) { - return result; - } - - mmio_write_8(IIC_DVFS_REG_ICCR, IIC_DVFS_SET_ICCR_STOP); - - mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT; - mmio_write_8(IIC_DVFS_REG_ICSR, mode); - - *state = DVFS_DONE; - - return result; -} - -IIC_DVFS_FUNC(done, void) -{ - uint32_t i; - - for (i = 0U; i < IIC_DVFS_SET_BUSY_LOOP; i++) { - if ((mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_BUSY) != 0U) { - continue; - } - goto done; - } - - panic(); -done: - mmio_write_8(IIC_DVFS_REG_ICCR, 0U); - - return DVFS_COMPLETE; -} - -IIC_DVFS_FUNC(write_reg_addr_read, enum dvfs_state_t *state, uint32_t *err, - uint8_t reg_addr) -{ - int32_t result; - uint8_t mode; - - result = dvfs_check_error(state, err, DVFS_WRITE_MODE); - if (result == DVFS_ERROR) { - return result; - } - - mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT; - if (mode != IIC_DVFS_BIT_ICSR_WAIT) { - return result; - } - - mmio_write_8(IIC_DVFS_REG_ICDR, reg_addr); - - mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT; - mmio_write_8(IIC_DVFS_REG_ICSR, mode); - - *state = DVFS_RETRANSMIT; - - return result; -} - -IIC_DVFS_FUNC(retransmit, enum dvfs_state_t *state, uint32_t *err) -{ - int32_t result; - uint8_t mode; - - result = dvfs_check_error(state, err, DVFS_WRITE_MODE); - if (result == DVFS_ERROR) { - return result; - } - - mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT; - if (mode != IIC_DVFS_BIT_ICSR_WAIT) { - return result; - } - - mmio_write_8(IIC_DVFS_REG_ICCR, IIC_DVFS_SET_ICCR_RETRANSMISSION); - - mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT; - mmio_write_8(IIC_DVFS_REG_ICSR, mode); - - mode = mmio_read_8(IIC_DVFS_REG_ICIC) | IIC_DVFS_BIT_ICIC_DTEE; - mmio_write_8(IIC_DVFS_REG_ICIC, mode); - - *state = DVFS_SET_SLAVE_READ; - - return result; -} - -IIC_DVFS_FUNC(set_slave_read, enum dvfs_state_t *state, uint32_t *err, - uint8_t slave) -{ - uint8_t address; - int32_t result; - uint8_t mode; - - result = dvfs_check_error(state, err, DVFS_WRITE_MODE); - if (result == DVFS_ERROR) { - return result; - } - - mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_DTE; - if (mode != IIC_DVFS_BIT_ICSR_DTE) { - return result; - } - - mode = mmio_read_8(IIC_DVFS_REG_ICIC) & ~IIC_DVFS_BIT_ICIC_DTEE; - mmio_write_8(IIC_DVFS_REG_ICIC, mode); - - address = ((uint8_t) (slave << 1) + DVFS_READ_MODE); - mmio_write_8(IIC_DVFS_REG_ICDR, address); - - *state = DVFS_CHANGE_SEND_TO_RECEIVE; - - return result; -} - -IIC_DVFS_FUNC(change_send_to_receive, enum dvfs_state_t *state, uint32_t *err) -{ - int32_t result; - uint8_t mode; - - result = dvfs_check_error(state, err, DVFS_WRITE_MODE); - if (result == DVFS_ERROR) { - return result; - } - - mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT; - if (mode != IIC_DVFS_BIT_ICSR_WAIT) { - return result; - } - - mmio_write_8(IIC_DVFS_REG_ICCR, IIC_DVFS_SET_ICCR_CHANGE); - - mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT; - mmio_write_8(IIC_DVFS_REG_ICSR, mode); - - *state = DVFS_STOP_READ; - - return result; -} - -IIC_DVFS_FUNC(stop_read, enum dvfs_state_t *state, uint32_t *err) -{ - int32_t result; - uint8_t mode; - - result = dvfs_check_error(state, err, DVFS_READ_MODE); - if (result == DVFS_ERROR) { - return result; - } - - mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT; - if (mode != IIC_DVFS_BIT_ICSR_WAIT) { - return result; - } - - mmio_write_8(IIC_DVFS_REG_ICCR, IIC_DVFS_SET_ICCR_STOP_READ); - - mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT; - mmio_write_8(IIC_DVFS_REG_ICSR, mode); - - mode = mmio_read_8(IIC_DVFS_REG_ICIC) | IIC_DVFS_BIT_ICIC_DTEE; - mmio_write_8(IIC_DVFS_REG_ICIC, mode); - - *state = DVFS_READ; - - return result; -} - -IIC_DVFS_FUNC(read, enum dvfs_state_t *state, uint8_t *reg_data) -{ - uint8_t mode; - - mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_DTE; - if (mode != IIC_DVFS_BIT_ICSR_DTE) { - return DVFS_PROCESS; - } - - mode = mmio_read_8(IIC_DVFS_REG_ICIC) & ~IIC_DVFS_BIT_ICIC_DTEE; - mmio_write_8(IIC_DVFS_REG_ICIC, mode); - - *reg_data = mmio_read_8(IIC_DVFS_REG_ICDR); - *state = DVFS_DONE; - - return DVFS_PROCESS; -} - -RCAR_DVFS_API(send, uint8_t slave, uint8_t reg_addr, uint8_t reg_data) -{ - enum dvfs_state_t state = DVFS_START; - int32_t result = DVFS_PROCESS; - uint32_t err = 0U; - - mstpcr_write(SCMSTPCR9, CPG_MSTPSR9, CPG_BIT_SMSTPCR9_DVFS); - mmio_write_8(IIC_DVFS_REG_ICCR, 0U); -again: - switch (state) { - case DVFS_START: - result = dvfs_start(&state); - break; - case DVFS_SET_SLAVE: - result = dvfs_set_slave(&state, &err, slave); - break; - case DVFS_WRITE_ADDR: - result = dvfs_write_addr(&state, &err, reg_addr); - break; - case DVFS_WRITE_DATA: - result = dvfs_write_data(&state, &err, reg_data); - break; - case DVFS_STOP: - result = dvfs_stop(&state, &err); - break; - case DVFS_DONE: - result = dvfs_done(); - break; - default: - panic(); - break; - } - - if (result == DVFS_PROCESS) { - goto again; - } - - return result; -} - -RCAR_DVFS_API(receive, uint8_t slave, uint8_t reg, uint8_t *data) -{ - enum dvfs_state_t state = DVFS_START; - int32_t result = DVFS_PROCESS; - uint32_t err = 0U; - - mstpcr_write(SCMSTPCR9, CPG_MSTPSR9, CPG_BIT_SMSTPCR9_DVFS); - mmio_write_8(IIC_DVFS_REG_ICCR, 0U); -again: - switch (state) { - case DVFS_START: - result = dvfs_start(&state); - break; - case DVFS_SET_SLAVE: - result = dvfs_set_slave(&state, &err, slave); - break; - case DVFS_WRITE_ADDR: - result = dvfs_write_reg_addr_read(&state, &err, reg); - break; - case DVFS_RETRANSMIT: - result = dvfs_retransmit(&state, &err); - break; - case DVFS_SET_SLAVE_READ: - result = dvfs_set_slave_read(&state, &err, slave); - break; - case DVFS_CHANGE_SEND_TO_RECEIVE: - result = dvfs_change_send_to_receive(&state, &err); - break; - case DVFS_STOP_READ: - result = dvfs_stop_read(&state, &err); - break; - case DVFS_READ: - result = dvfs_read(&state, data); - break; - case DVFS_DONE: - result = dvfs_done(); - break; - default: - panic(); - break; - } - - if (result == DVFS_PROCESS) { - goto again; - } - - return result; -} diff --git a/drivers/renesas/rcar/iic_dvfs/iic_dvfs.h b/drivers/renesas/rcar/iic_dvfs/iic_dvfs.h deleted file mode 100644 index 244c06cfd..000000000 --- a/drivers/renesas/rcar/iic_dvfs/iic_dvfs.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef IIC_DVFS_H -#define IIC_DVFS_H - -/* PMIC slave */ -#define PMIC (0x30U) -#define BKUP_MODE_CNT (0x20U) -#define DVFS_SET_VID (0x54U) -#define REG_KEEP10 (0x79U) - -/* EEPROM slave */ -#define EEPROM (0x50U) -#define BOARD_ID (0x70U) - -int32_t rcar_iic_dvfs_receive(uint8_t slave, uint8_t reg, uint8_t *data); -int32_t rcar_iic_dvfs_send(uint8_t slave, uint8_t regr, uint8_t data); - -#endif /* IIC_DVFS_H */ diff --git a/plat/renesas/common/common.mk b/plat/renesas/common/common.mk index f2e1112a6..ab9cded70 100644 --- a/plat/renesas/common/common.mk +++ b/plat/renesas/common/common.mk @@ -65,6 +65,9 @@ PLAT_INCLUDES := -Iplat/renesas/common/include/registers \ -Iplat/renesas/common/include \ -Iplat/renesas/common +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 \ @@ -84,3 +87,7 @@ BL31_SOURCES += ${RCAR_GIC_SOURCES} \ plat/common/plat_psci_common.c \ drivers/renesas/common/common.c \ drivers/arm/cci/cci.c + +include lib/xlat_tables_v2/xlat_tables.mk +include drivers/auth/mbedtls/mbedtls_crypto.mk +PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS} diff --git a/plat/renesas/common/rcar_common.c b/plat/renesas/common/rcar_common.c new file mode 100644 index 000000000..dec7229b3 --- /dev/null +++ b/plat/renesas/common/rcar_common.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2019, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include + +#include + +#define CPG_BASE 0xE6150000 +#define CPG_MSTPSR3 0x0048 +#define MSTP318 (1 << 18) +#define MSTP319 (1 << 19) +#define PMSR 0x5c +#define PMSR_L1FAEG (1U << 31) +#define PMSR_PMEL1RX (1 << 23) +#define PMCTLR 0x60 +#define PMSR_L1IATN (1U << 31) + +static int rcar_pcie_fixup(unsigned int controller) +{ + uint32_t rcar_pcie_base[] = { 0xfe011000, 0xee811000 }; + uint32_t addr = rcar_pcie_base[controller]; + uint32_t cpg, pmsr; + int ret = 0; + + /* Test if PCIECx is enabled */ + cpg = mmio_read_32(CPG_BASE + CPG_MSTPSR3); + if (cpg & (MSTP318 << !controller)) + return ret; + + pmsr = mmio_read_32(addr + PMSR); + + if ((pmsr & PMSR_PMEL1RX) && ((pmsr & 0x70000) != 0x30000)) { + /* Fix applicable */ + mmio_write_32(addr + PMCTLR, PMSR_L1IATN); + while (!(mmio_read_32(addr + PMSR) & PMSR_L1FAEG)) + ; + mmio_write_32(addr + PMSR, PMSR_L1FAEG | PMSR_PMEL1RX); + ret = 1; + } + + return ret; +} + +/* RAS functions common to AArch64 ARM platforms */ +void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie, + void *handle, uint64_t flags) +{ + unsigned int fixed = 0; + + fixed |= rcar_pcie_fixup(0); + fixed |= rcar_pcie_fixup(1); + + if (fixed) + return; + + ERROR("Unhandled External Abort received on 0x%lx at EL3!\n", + read_mpidr_el1()); + ERROR(" exception reason=%u syndrome=0x%llx\n", ea_reason, syndrome); + + panic(); +} + +#include + +static console_t rcar_boot_console; +static console_t rcar_runtime_console; + +void rcar_console_boot_init(void) +{ + int ret; + + ret = console_rcar_register(0, 0, 0, &rcar_boot_console); + if (!ret) + panic(); + + console_set_scope(&rcar_boot_console, CONSOLE_FLAG_BOOT); +} + +void rcar_console_boot_end(void) +{ +} + +void rcar_console_runtime_init(void) +{ + int ret; + + ret = console_rcar_register(1, 0, 0, &rcar_runtime_console); + if (!ret) + panic(); + + console_set_scope(&rcar_boot_console, CONSOLE_FLAG_RUNTIME); +} + +void rcar_console_runtime_end(void) +{ +} diff --git a/plat/renesas/rcar/platform.mk b/plat/renesas/rcar/platform.mk index bdc29fe35..8613f5ea2 100644 --- a/plat/renesas/rcar/platform.mk +++ b/plat/renesas/rcar/platform.mk @@ -300,9 +300,9 @@ include lib/libfdt/libfdt.mk PLAT_INCLUDES += -Idrivers/renesas/rcar/ddr \ -Idrivers/renesas/rcar/qos \ - -Idrivers/renesas/rcar/iic_dvfs \ -Idrivers/renesas/rcar/board \ -Idrivers/renesas/rcar/cpld/ \ + -Idrivers/renesas/common/iic_dvfs \ -Idrivers/renesas/rcar/avs \ -Idrivers/renesas/rcar/delay \ -Idrivers/renesas/rcar/rom \ @@ -311,9 +311,6 @@ PLAT_INCLUDES += -Idrivers/renesas/rcar/ddr \ -Idrivers/renesas/rcar/pwrc \ -Idrivers/renesas/rcar/io -PLAT_BL_COMMON_SOURCES := drivers/renesas/rcar/iic_dvfs/iic_dvfs.c \ - plat/renesas/rcar/rcar_common.c - BL2_SOURCES += plat/renesas/rcar/aarch64/platform_common.c \ plat/renesas/rcar/aarch64/plat_helpers.S \ plat/renesas/rcar/bl2_interrupt_error.c \ @@ -358,10 +355,6 @@ ifeq (${RCAR_GEN3_ULCB},1) BL31_SOURCES += drivers/renesas/rcar/cpld/ulcb_cpld.c endif -include lib/xlat_tables_v2/xlat_tables.mk -include drivers/auth/mbedtls/mbedtls_crypto.mk -PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS} - # build the layout images for the bootrom and the necessary srecords rcar: rcar_layout_tool rcar_srecord distclean realclean clean: clean_layout_tool clean_srecord diff --git a/plat/renesas/rcar/rcar_common.c b/plat/renesas/rcar/rcar_common.c deleted file mode 100644 index dec7229b3..000000000 --- a/plat/renesas/rcar/rcar_common.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2019, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include -#include -#include -#include - -#include - -#define CPG_BASE 0xE6150000 -#define CPG_MSTPSR3 0x0048 -#define MSTP318 (1 << 18) -#define MSTP319 (1 << 19) -#define PMSR 0x5c -#define PMSR_L1FAEG (1U << 31) -#define PMSR_PMEL1RX (1 << 23) -#define PMCTLR 0x60 -#define PMSR_L1IATN (1U << 31) - -static int rcar_pcie_fixup(unsigned int controller) -{ - uint32_t rcar_pcie_base[] = { 0xfe011000, 0xee811000 }; - uint32_t addr = rcar_pcie_base[controller]; - uint32_t cpg, pmsr; - int ret = 0; - - /* Test if PCIECx is enabled */ - cpg = mmio_read_32(CPG_BASE + CPG_MSTPSR3); - if (cpg & (MSTP318 << !controller)) - return ret; - - pmsr = mmio_read_32(addr + PMSR); - - if ((pmsr & PMSR_PMEL1RX) && ((pmsr & 0x70000) != 0x30000)) { - /* Fix applicable */ - mmio_write_32(addr + PMCTLR, PMSR_L1IATN); - while (!(mmio_read_32(addr + PMSR) & PMSR_L1FAEG)) - ; - mmio_write_32(addr + PMSR, PMSR_L1FAEG | PMSR_PMEL1RX); - ret = 1; - } - - return ret; -} - -/* RAS functions common to AArch64 ARM platforms */ -void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie, - void *handle, uint64_t flags) -{ - unsigned int fixed = 0; - - fixed |= rcar_pcie_fixup(0); - fixed |= rcar_pcie_fixup(1); - - if (fixed) - return; - - ERROR("Unhandled External Abort received on 0x%lx at EL3!\n", - read_mpidr_el1()); - ERROR(" exception reason=%u syndrome=0x%llx\n", ea_reason, syndrome); - - panic(); -} - -#include - -static console_t rcar_boot_console; -static console_t rcar_runtime_console; - -void rcar_console_boot_init(void) -{ - int ret; - - ret = console_rcar_register(0, 0, 0, &rcar_boot_console); - if (!ret) - panic(); - - console_set_scope(&rcar_boot_console, CONSOLE_FLAG_BOOT); -} - -void rcar_console_boot_end(void) -{ -} - -void rcar_console_runtime_init(void) -{ - int ret; - - ret = console_rcar_register(1, 0, 0, &rcar_runtime_console); - if (!ret) - panic(); - - console_set_scope(&rcar_boot_console, CONSOLE_FLAG_RUNTIME); -} - -void rcar_console_runtime_end(void) -{ -} -- cgit v1.2.3 From d58da31400cf1f3148f6c98e97effd151f6a66f3 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Wed, 16 Dec 2020 11:00:21 +0000 Subject: drivers: renesas: watchdog: Move to common Move watch driver code to common directory, so that the same code can be re-used by both R-Car Gen3 and RZ/G2 platforms. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: I235f2cde325a0feeadbfc4b7ee02e8b1186f7ea1 --- drivers/renesas/common/watchdog/swdt.c | 167 +++++++++++++++++++++++++++++++++ drivers/renesas/rcar/watchdog/swdt.c | 167 --------------------------------- plat/renesas/common/common.mk | 1 + plat/renesas/rcar/platform.mk | 1 - 4 files changed, 168 insertions(+), 168 deletions(-) create mode 100644 drivers/renesas/common/watchdog/swdt.c delete mode 100644 drivers/renesas/rcar/watchdog/swdt.c diff --git a/drivers/renesas/common/watchdog/swdt.c b/drivers/renesas/common/watchdog/swdt.c new file mode 100644 index 000000000..05987ab70 --- /dev/null +++ b/drivers/renesas/common/watchdog/swdt.c @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +#include "rcar_def.h" + +extern void gicd_set_icenabler(uintptr_t base, unsigned int id); + +#define RST_BASE (0xE6160000U) +#define RST_WDTRSTCR (RST_BASE + 0x0054U) +#define SWDT_BASE (0xE6030000U) +#define SWDT_WTCNT (SWDT_BASE + 0x0000U) +#define SWDT_WTCSRA (SWDT_BASE + 0x0004U) +#define SWDT_WTCSRB (SWDT_BASE + 0x0008U) +#define SWDT_GICD_BASE (0xF1010000U) +#define SWDT_GICC_BASE (0xF1020000U) +#define SWDT_GICD_CTLR (SWDT_GICD_BASE + 0x0000U) +#define SWDT_GICD_IGROUPR (SWDT_GICD_BASE + 0x0080U) +#define SWDT_GICD_ISPRIORITYR (SWDT_GICD_BASE + 0x0400U) +#define SWDT_GICC_CTLR (SWDT_GICC_BASE + 0x0000U) +#define SWDT_GICC_PMR (SWDT_GICC_BASE + 0x0004U) +#define SWDT_GICD_ITARGETSR (SWDT_GICD_BASE + 0x0800U) +#define IGROUPR_NUM (16U) +#define ISPRIORITY_NUM (128U) +#define ITARGET_MASK (0x03U) + +#define WDTRSTCR_UPPER_BYTE (0xA55A0000U) +#define WTCSRA_UPPER_BYTE (0xA5A5A500U) +#define WTCSRB_UPPER_BYTE (0xA5A5A500U) +#define WTCNT_UPPER_BYTE (0x5A5A0000U) +#define WTCNT_RESET_VALUE (0xF488U) +#define WTCSRA_BIT_CKS (0x0007U) +#define WTCSRB_BIT_CKS (0x003FU) +#define SWDT_RSTMSK (1U << 1U) +#define WTCSRA_WOVFE (1U << 3U) +#define WTCSRA_WRFLG (1U << 5U) +#define SWDT_ENABLE (1U << 7U) + +#define WDTRSTCR_MASK_ALL (0x0000FFFFU) +#define WTCSRA_MASK_ALL (0x000000FFU) +#define WTCNT_INIT_DATA (WTCNT_UPPER_BYTE + WTCNT_RESET_VALUE) +#define WTCSRA_INIT_DATA (WTCSRA_UPPER_BYTE + 0x0FU) +#define WTCSRB_INIT_DATA (WTCSRB_UPPER_BYTE + 0x21U) + +#if RCAR_LSI == RCAR_D3 +#define WTCNT_COUNT_8p13k (0x10000U - 40760U) +#else +#define WTCNT_COUNT_8p13k (0x10000U - 40687U) +#endif +#define WTCNT_COUNT_8p13k_H3VER10 (0x10000U - 20343U) +#define WTCNT_COUNT_8p22k (0x10000U - 41115U) +#define WTCNT_COUNT_7p81k (0x10000U - 39062U) +#define WTCSRA_CKS_DIV16 (0x00000002U) + +static void swdt_disable(void) +{ + uint32_t rmsk; + + rmsk = mmio_read_32(RST_WDTRSTCR) & WDTRSTCR_MASK_ALL; + rmsk |= SWDT_RSTMSK; + mmio_write_32(RST_WDTRSTCR, WDTRSTCR_UPPER_BYTE | rmsk); + + mmio_write_32(SWDT_WTCNT, WTCNT_INIT_DATA); + mmio_write_32(SWDT_WTCSRA, WTCSRA_INIT_DATA); + mmio_write_32(SWDT_WTCSRB, WTCSRB_INIT_DATA); + + /* Set the interrupt clear enable register */ + gicd_set_icenabler(RCAR_GICD_BASE, ARM_IRQ_SEC_WDT); +} + +void rcar_swdt_init(void) +{ + uint32_t rmsk, sr; +#if (RCAR_LSI != RCAR_E3) + uint32_t reg, val, product_cut, chk_data; + + reg = mmio_read_32(RCAR_PRR); + product_cut = reg & (PRR_PRODUCT_MASK | PRR_CUT_MASK); + + reg = mmio_read_32(RCAR_MODEMR); + chk_data = reg & CHECK_MD13_MD14; +#endif + /* stop watchdog */ + if (mmio_read_32(SWDT_WTCSRA) & SWDT_ENABLE) + mmio_write_32(SWDT_WTCSRA, WTCSRA_UPPER_BYTE); + + mmio_write_32(SWDT_WTCSRA, WTCSRA_UPPER_BYTE | + WTCSRA_WOVFE | WTCSRA_CKS_DIV16); + +#if (RCAR_LSI == RCAR_E3) + mmio_write_32(SWDT_WTCNT, WTCNT_UPPER_BYTE | WTCNT_COUNT_7p81k); +#else + val = WTCNT_UPPER_BYTE; + + switch (chk_data) { + case MD14_MD13_TYPE_0: + case MD14_MD13_TYPE_2: + val |= WTCNT_COUNT_8p13k; + break; + case MD14_MD13_TYPE_1: + val |= WTCNT_COUNT_8p22k; + break; + case MD14_MD13_TYPE_3: + val |= product_cut == (PRR_PRODUCT_H3 | PRR_PRODUCT_10) ? + WTCNT_COUNT_8p13k_H3VER10 : WTCNT_COUNT_8p13k; + break; + default: + ERROR("MODEMR ERROR value = %x\n", chk_data); + panic(); + break; + } + + mmio_write_32(SWDT_WTCNT, val); +#endif + rmsk = mmio_read_32(RST_WDTRSTCR) & WDTRSTCR_MASK_ALL; + rmsk |= SWDT_RSTMSK | WDTRSTCR_UPPER_BYTE; + mmio_write_32(RST_WDTRSTCR, rmsk); + + while ((mmio_read_8(SWDT_WTCSRA) & WTCSRA_WRFLG) != 0U) + ; + + /* Start the System WatchDog Timer */ + sr = mmio_read_32(SWDT_WTCSRA) & WTCSRA_MASK_ALL; + mmio_write_32(SWDT_WTCSRA, (WTCSRA_UPPER_BYTE | sr | SWDT_ENABLE)); +} + +void rcar_swdt_release(void) +{ + uintptr_t itarget = SWDT_GICD_ITARGETSR + + (ARM_IRQ_SEC_WDT & ~ITARGET_MASK); + uint32_t i; + + /* Disable FIQ interrupt */ + write_daifset(DAIF_FIQ_BIT); + /* FIQ interrupts are not taken to EL3 */ + write_scr_el3(read_scr_el3() & ~SCR_FIQ_BIT); + + swdt_disable(); + gicv2_cpuif_disable(); + + for (i = 0; i < IGROUPR_NUM; i++) + mmio_write_32(SWDT_GICD_IGROUPR + i * 4, 0U); + + for (i = 0; i < ISPRIORITY_NUM; i++) + mmio_write_32(SWDT_GICD_ISPRIORITYR + i * 4, 0U); + + mmio_write_32(itarget, 0U); + mmio_write_32(SWDT_GICD_CTLR, 0U); + mmio_write_32(SWDT_GICC_CTLR, 0U); + mmio_write_32(SWDT_GICC_PMR, 0U); +} + +void rcar_swdt_exec(uint64_t p) +{ + gicv2_end_of_interrupt(ARM_IRQ_SEC_WDT); + rcar_swdt_release(); + ERROR("\n"); + ERROR("System WDT overflow, occurred address is %p\n", (void *)p); + panic(); +} diff --git a/drivers/renesas/rcar/watchdog/swdt.c b/drivers/renesas/rcar/watchdog/swdt.c deleted file mode 100644 index 05987ab70..000000000 --- a/drivers/renesas/rcar/watchdog/swdt.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include -#include - -#include "rcar_def.h" - -extern void gicd_set_icenabler(uintptr_t base, unsigned int id); - -#define RST_BASE (0xE6160000U) -#define RST_WDTRSTCR (RST_BASE + 0x0054U) -#define SWDT_BASE (0xE6030000U) -#define SWDT_WTCNT (SWDT_BASE + 0x0000U) -#define SWDT_WTCSRA (SWDT_BASE + 0x0004U) -#define SWDT_WTCSRB (SWDT_BASE + 0x0008U) -#define SWDT_GICD_BASE (0xF1010000U) -#define SWDT_GICC_BASE (0xF1020000U) -#define SWDT_GICD_CTLR (SWDT_GICD_BASE + 0x0000U) -#define SWDT_GICD_IGROUPR (SWDT_GICD_BASE + 0x0080U) -#define SWDT_GICD_ISPRIORITYR (SWDT_GICD_BASE + 0x0400U) -#define SWDT_GICC_CTLR (SWDT_GICC_BASE + 0x0000U) -#define SWDT_GICC_PMR (SWDT_GICC_BASE + 0x0004U) -#define SWDT_GICD_ITARGETSR (SWDT_GICD_BASE + 0x0800U) -#define IGROUPR_NUM (16U) -#define ISPRIORITY_NUM (128U) -#define ITARGET_MASK (0x03U) - -#define WDTRSTCR_UPPER_BYTE (0xA55A0000U) -#define WTCSRA_UPPER_BYTE (0xA5A5A500U) -#define WTCSRB_UPPER_BYTE (0xA5A5A500U) -#define WTCNT_UPPER_BYTE (0x5A5A0000U) -#define WTCNT_RESET_VALUE (0xF488U) -#define WTCSRA_BIT_CKS (0x0007U) -#define WTCSRB_BIT_CKS (0x003FU) -#define SWDT_RSTMSK (1U << 1U) -#define WTCSRA_WOVFE (1U << 3U) -#define WTCSRA_WRFLG (1U << 5U) -#define SWDT_ENABLE (1U << 7U) - -#define WDTRSTCR_MASK_ALL (0x0000FFFFU) -#define WTCSRA_MASK_ALL (0x000000FFU) -#define WTCNT_INIT_DATA (WTCNT_UPPER_BYTE + WTCNT_RESET_VALUE) -#define WTCSRA_INIT_DATA (WTCSRA_UPPER_BYTE + 0x0FU) -#define WTCSRB_INIT_DATA (WTCSRB_UPPER_BYTE + 0x21U) - -#if RCAR_LSI == RCAR_D3 -#define WTCNT_COUNT_8p13k (0x10000U - 40760U) -#else -#define WTCNT_COUNT_8p13k (0x10000U - 40687U) -#endif -#define WTCNT_COUNT_8p13k_H3VER10 (0x10000U - 20343U) -#define WTCNT_COUNT_8p22k (0x10000U - 41115U) -#define WTCNT_COUNT_7p81k (0x10000U - 39062U) -#define WTCSRA_CKS_DIV16 (0x00000002U) - -static void swdt_disable(void) -{ - uint32_t rmsk; - - rmsk = mmio_read_32(RST_WDTRSTCR) & WDTRSTCR_MASK_ALL; - rmsk |= SWDT_RSTMSK; - mmio_write_32(RST_WDTRSTCR, WDTRSTCR_UPPER_BYTE | rmsk); - - mmio_write_32(SWDT_WTCNT, WTCNT_INIT_DATA); - mmio_write_32(SWDT_WTCSRA, WTCSRA_INIT_DATA); - mmio_write_32(SWDT_WTCSRB, WTCSRB_INIT_DATA); - - /* Set the interrupt clear enable register */ - gicd_set_icenabler(RCAR_GICD_BASE, ARM_IRQ_SEC_WDT); -} - -void rcar_swdt_init(void) -{ - uint32_t rmsk, sr; -#if (RCAR_LSI != RCAR_E3) - uint32_t reg, val, product_cut, chk_data; - - reg = mmio_read_32(RCAR_PRR); - product_cut = reg & (PRR_PRODUCT_MASK | PRR_CUT_MASK); - - reg = mmio_read_32(RCAR_MODEMR); - chk_data = reg & CHECK_MD13_MD14; -#endif - /* stop watchdog */ - if (mmio_read_32(SWDT_WTCSRA) & SWDT_ENABLE) - mmio_write_32(SWDT_WTCSRA, WTCSRA_UPPER_BYTE); - - mmio_write_32(SWDT_WTCSRA, WTCSRA_UPPER_BYTE | - WTCSRA_WOVFE | WTCSRA_CKS_DIV16); - -#if (RCAR_LSI == RCAR_E3) - mmio_write_32(SWDT_WTCNT, WTCNT_UPPER_BYTE | WTCNT_COUNT_7p81k); -#else - val = WTCNT_UPPER_BYTE; - - switch (chk_data) { - case MD14_MD13_TYPE_0: - case MD14_MD13_TYPE_2: - val |= WTCNT_COUNT_8p13k; - break; - case MD14_MD13_TYPE_1: - val |= WTCNT_COUNT_8p22k; - break; - case MD14_MD13_TYPE_3: - val |= product_cut == (PRR_PRODUCT_H3 | PRR_PRODUCT_10) ? - WTCNT_COUNT_8p13k_H3VER10 : WTCNT_COUNT_8p13k; - break; - default: - ERROR("MODEMR ERROR value = %x\n", chk_data); - panic(); - break; - } - - mmio_write_32(SWDT_WTCNT, val); -#endif - rmsk = mmio_read_32(RST_WDTRSTCR) & WDTRSTCR_MASK_ALL; - rmsk |= SWDT_RSTMSK | WDTRSTCR_UPPER_BYTE; - mmio_write_32(RST_WDTRSTCR, rmsk); - - while ((mmio_read_8(SWDT_WTCSRA) & WTCSRA_WRFLG) != 0U) - ; - - /* Start the System WatchDog Timer */ - sr = mmio_read_32(SWDT_WTCSRA) & WTCSRA_MASK_ALL; - mmio_write_32(SWDT_WTCSRA, (WTCSRA_UPPER_BYTE | sr | SWDT_ENABLE)); -} - -void rcar_swdt_release(void) -{ - uintptr_t itarget = SWDT_GICD_ITARGETSR + - (ARM_IRQ_SEC_WDT & ~ITARGET_MASK); - uint32_t i; - - /* Disable FIQ interrupt */ - write_daifset(DAIF_FIQ_BIT); - /* FIQ interrupts are not taken to EL3 */ - write_scr_el3(read_scr_el3() & ~SCR_FIQ_BIT); - - swdt_disable(); - gicv2_cpuif_disable(); - - for (i = 0; i < IGROUPR_NUM; i++) - mmio_write_32(SWDT_GICD_IGROUPR + i * 4, 0U); - - for (i = 0; i < ISPRIORITY_NUM; i++) - mmio_write_32(SWDT_GICD_ISPRIORITYR + i * 4, 0U); - - mmio_write_32(itarget, 0U); - mmio_write_32(SWDT_GICD_CTLR, 0U); - mmio_write_32(SWDT_GICC_CTLR, 0U); - mmio_write_32(SWDT_GICC_PMR, 0U); -} - -void rcar_swdt_exec(uint64_t p) -{ - gicv2_end_of_interrupt(ARM_IRQ_SEC_WDT); - rcar_swdt_release(); - ERROR("\n"); - ERROR("System WDT overflow, occurred address is %p\n", (void *)p); - panic(); -} diff --git a/plat/renesas/common/common.mk b/plat/renesas/common/common.mk index 09ff1d513..adee49bf7 100644 --- a/plat/renesas/common/common.mk +++ b/plat/renesas/common/common.mk @@ -91,6 +91,7 @@ BL2_SOURCES += ${RCAR_GIC_SOURCES} \ drivers/renesas/common/emmc/emmc_init.c \ drivers/renesas/common/emmc/emmc_read.c \ drivers/renesas/common/emmc/emmc_cmd.c \ + drivers/renesas/common/watchdog/swdt.c \ drivers/renesas/common/rom/rom_api.c \ drivers/io/io_storage.c diff --git a/plat/renesas/rcar/platform.mk b/plat/renesas/rcar/platform.mk index 4cd2f93b5..bb7af4044 100644 --- a/plat/renesas/rcar/platform.mk +++ b/plat/renesas/rcar/platform.mk @@ -324,7 +324,6 @@ BL2_SOURCES += plat/renesas/rcar/aarch64/platform_common.c \ drivers/renesas/rcar/rpc/rpc_driver.c \ drivers/renesas/rcar/dma/dma_driver.c \ drivers/renesas/rcar/avs/avs_driver.c \ - drivers/renesas/rcar/watchdog/swdt.c \ drivers/renesas/rcar/board/board.c BL31_SOURCES += plat/renesas/rcar/plat_topology.c \ -- cgit v1.2.3 From 6f97490e2fd97a4e8fca82f4fb57cb1f52fa4958 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Wed, 16 Dec 2020 11:02:59 +0000 Subject: drivers: renesas: dma: Move to common Move dma driver code to common directory, so that the same code can be re-used by both R-Car Gen3 and RZ/G2 platforms. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: Idce2e2f4e098cfc17219f963373d20ebf74e5b7c --- drivers/renesas/common/dma/dma_driver.c | 153 ++++++++++++++++++++++++++++++++ drivers/renesas/rcar/dma/dma_driver.c | 153 -------------------------------- plat/renesas/common/common.mk | 1 + plat/renesas/rcar/platform.mk | 1 - 4 files changed, 154 insertions(+), 154 deletions(-) create mode 100644 drivers/renesas/common/dma/dma_driver.c delete mode 100644 drivers/renesas/rcar/dma/dma_driver.c diff --git a/drivers/renesas/common/dma/dma_driver.c b/drivers/renesas/common/dma/dma_driver.c new file mode 100644 index 000000000..44ee98592 --- /dev/null +++ b/drivers/renesas/common/dma/dma_driver.c @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include +#include + +#include "cpg_registers.h" +#include "rcar_def.h" +#include "rcar_private.h" + +/* DMA CHANNEL setting (0/16/32) */ +#if RCAR_LSI == RCAR_V3M +#define DMA_CH 16 +#else +#define DMA_CH 0 +#endif + +#if (DMA_CH == 0) +#define SYS_DMAC_BIT ((uint32_t)1U << 19U) +#define DMA_BASE (0xE6700000U) +#elif (DMA_CH == 16) +#define SYS_DMAC_BIT ((uint32_t)1U << 18U) +#define DMA_BASE (0xE7300000U) +#elif (DMA_CH == 32) +#define SYS_DMAC_BIT ((uint32_t)1U << 17U) +#define DMA_BASE (0xE7320000U) +#else +#define SYS_DMAC_BIT ((uint32_t)1U << 19U) +#define DMA_BASE (0xE6700000U) +#endif + +/* DMA operation */ +#define DMA_DMAOR (DMA_BASE + 0x0060U) +/* DMA secure control */ +#define DMA_DMASEC (DMA_BASE + 0x0030U) +/* DMA channel clear */ +#define DMA_DMACHCLR (DMA_BASE + 0x0080U) +/* DMA source address */ +#define DMA_DMASAR (DMA_BASE + 0x8000U) +/* DMA destination address */ +#define DMA_DMADAR (DMA_BASE + 0x8004U) +/* DMA transfer count */ +#define DMA_DMATCR (DMA_BASE + 0x8008U) +/* DMA channel control */ +#define DMA_DMACHCR (DMA_BASE + 0x800CU) +/* DMA fixed destination address */ +#define DMA_DMAFIXDAR (DMA_BASE + 0x8014U) + +#define DMA_USE_CHANNEL (0x00000001U) +#define DMAOR_INITIAL (0x0301U) +#define DMACHCLR_CH_ALL (0x0000FFFFU) +#define DMAFIXDAR_32BIT_SHIFT (32U) +#define DMAFIXDAR_DAR_MASK (0x000000FFU) +#define DMADAR_BOUNDARY_ADDR (0x100000000ULL) +#define DMATCR_CNT_SHIFT (6U) +#define DMATCR_MAX (0x00FFFFFFU) +#define DMACHCR_TRN_MODE (0x00105409U) +#define DMACHCR_DE_BIT (0x00000001U) +#define DMACHCR_TE_BIT (0x00000002U) +#define DMACHCR_CHE_BIT (0x80000000U) + +#define DMA_SIZE_UNIT FLASH_TRANS_SIZE_UNIT +#define DMA_FRACTION_MASK (0xFFU) +#define DMA_DST_LIMIT (0x10000000000ULL) + +/* transfer length limit */ +#define DMA_LENGTH_LIMIT ((DMATCR_MAX * (1U << DMATCR_CNT_SHIFT)) \ + & ~DMA_FRACTION_MASK) + +static void dma_enable(void) +{ + mstpcr_write(CPG_SMSTPCR2, CPG_MSTPSR2, SYS_DMAC_BIT); +} + +static void dma_setup(void) +{ + mmio_write_16(DMA_DMAOR, 0); + mmio_write_32(DMA_DMACHCLR, DMACHCLR_CH_ALL); +} + +static void dma_start(uintptr_t dst, uint32_t src, uint32_t len) +{ + mmio_write_16(DMA_DMAOR, DMAOR_INITIAL); + mmio_write_32(DMA_DMAFIXDAR, (dst >> DMAFIXDAR_32BIT_SHIFT) & + DMAFIXDAR_DAR_MASK); + mmio_write_32(DMA_DMADAR, dst & UINT32_MAX); + mmio_write_32(DMA_DMASAR, src); + mmio_write_32(DMA_DMATCR, len >> DMATCR_CNT_SHIFT); + mmio_write_32(DMA_DMASEC, DMA_USE_CHANNEL); + mmio_write_32(DMA_DMACHCR, DMACHCR_TRN_MODE); +} + +static void dma_end(void) +{ + while ((mmio_read_32(DMA_DMACHCR) & DMACHCR_TE_BIT) == 0) { + if ((mmio_read_32(DMA_DMACHCR) & DMACHCR_CHE_BIT) != 0U) { + ERROR("BL2: DMA - Channel Address Error\n"); + panic(); + break; + } + } + /* DMA transfer Disable */ + mmio_clrbits_32(DMA_DMACHCR, DMACHCR_DE_BIT); + while ((mmio_read_32(DMA_DMACHCR) & DMACHCR_DE_BIT) != 0) + ; + + mmio_write_32(DMA_DMASEC, 0); + mmio_write_16(DMA_DMAOR, 0); + mmio_write_32(DMA_DMACHCLR, DMA_USE_CHANNEL); +} + +void rcar_dma_exec(uintptr_t dst, uint32_t src, uint32_t len) +{ + uint32_t dma_len = len; + + if (len & DMA_FRACTION_MASK) + dma_len = (len + DMA_SIZE_UNIT) & ~DMA_FRACTION_MASK; + + if (!dma_len || dma_len > DMA_LENGTH_LIMIT) { + ERROR("BL2: DMA - size invalid, length (0x%x)\n", dma_len); + panic(); + } + + if (src & DMA_FRACTION_MASK) { + ERROR("BL2: DMA - src address invalid (0x%x), len=(0x%x)\n", + src, dma_len); + panic(); + } + + if ((dst & UINT32_MAX) + dma_len > DMADAR_BOUNDARY_ADDR || + (dst + dma_len > DMA_DST_LIMIT) || + (dst & DMA_FRACTION_MASK)) { + ERROR("BL2: DMA - dest address invalid (0x%lx), len=(0x%x)\n", + dst, dma_len); + panic(); + } + + dma_start(dst, src, dma_len); + dma_end(); +} + +void rcar_dma_init(void) +{ + dma_enable(); + dma_setup(); +} diff --git a/drivers/renesas/rcar/dma/dma_driver.c b/drivers/renesas/rcar/dma/dma_driver.c deleted file mode 100644 index 44ee98592..000000000 --- a/drivers/renesas/rcar/dma/dma_driver.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include - -#include -#include -#include - -#include "cpg_registers.h" -#include "rcar_def.h" -#include "rcar_private.h" - -/* DMA CHANNEL setting (0/16/32) */ -#if RCAR_LSI == RCAR_V3M -#define DMA_CH 16 -#else -#define DMA_CH 0 -#endif - -#if (DMA_CH == 0) -#define SYS_DMAC_BIT ((uint32_t)1U << 19U) -#define DMA_BASE (0xE6700000U) -#elif (DMA_CH == 16) -#define SYS_DMAC_BIT ((uint32_t)1U << 18U) -#define DMA_BASE (0xE7300000U) -#elif (DMA_CH == 32) -#define SYS_DMAC_BIT ((uint32_t)1U << 17U) -#define DMA_BASE (0xE7320000U) -#else -#define SYS_DMAC_BIT ((uint32_t)1U << 19U) -#define DMA_BASE (0xE6700000U) -#endif - -/* DMA operation */ -#define DMA_DMAOR (DMA_BASE + 0x0060U) -/* DMA secure control */ -#define DMA_DMASEC (DMA_BASE + 0x0030U) -/* DMA channel clear */ -#define DMA_DMACHCLR (DMA_BASE + 0x0080U) -/* DMA source address */ -#define DMA_DMASAR (DMA_BASE + 0x8000U) -/* DMA destination address */ -#define DMA_DMADAR (DMA_BASE + 0x8004U) -/* DMA transfer count */ -#define DMA_DMATCR (DMA_BASE + 0x8008U) -/* DMA channel control */ -#define DMA_DMACHCR (DMA_BASE + 0x800CU) -/* DMA fixed destination address */ -#define DMA_DMAFIXDAR (DMA_BASE + 0x8014U) - -#define DMA_USE_CHANNEL (0x00000001U) -#define DMAOR_INITIAL (0x0301U) -#define DMACHCLR_CH_ALL (0x0000FFFFU) -#define DMAFIXDAR_32BIT_SHIFT (32U) -#define DMAFIXDAR_DAR_MASK (0x000000FFU) -#define DMADAR_BOUNDARY_ADDR (0x100000000ULL) -#define DMATCR_CNT_SHIFT (6U) -#define DMATCR_MAX (0x00FFFFFFU) -#define DMACHCR_TRN_MODE (0x00105409U) -#define DMACHCR_DE_BIT (0x00000001U) -#define DMACHCR_TE_BIT (0x00000002U) -#define DMACHCR_CHE_BIT (0x80000000U) - -#define DMA_SIZE_UNIT FLASH_TRANS_SIZE_UNIT -#define DMA_FRACTION_MASK (0xFFU) -#define DMA_DST_LIMIT (0x10000000000ULL) - -/* transfer length limit */ -#define DMA_LENGTH_LIMIT ((DMATCR_MAX * (1U << DMATCR_CNT_SHIFT)) \ - & ~DMA_FRACTION_MASK) - -static void dma_enable(void) -{ - mstpcr_write(CPG_SMSTPCR2, CPG_MSTPSR2, SYS_DMAC_BIT); -} - -static void dma_setup(void) -{ - mmio_write_16(DMA_DMAOR, 0); - mmio_write_32(DMA_DMACHCLR, DMACHCLR_CH_ALL); -} - -static void dma_start(uintptr_t dst, uint32_t src, uint32_t len) -{ - mmio_write_16(DMA_DMAOR, DMAOR_INITIAL); - mmio_write_32(DMA_DMAFIXDAR, (dst >> DMAFIXDAR_32BIT_SHIFT) & - DMAFIXDAR_DAR_MASK); - mmio_write_32(DMA_DMADAR, dst & UINT32_MAX); - mmio_write_32(DMA_DMASAR, src); - mmio_write_32(DMA_DMATCR, len >> DMATCR_CNT_SHIFT); - mmio_write_32(DMA_DMASEC, DMA_USE_CHANNEL); - mmio_write_32(DMA_DMACHCR, DMACHCR_TRN_MODE); -} - -static void dma_end(void) -{ - while ((mmio_read_32(DMA_DMACHCR) & DMACHCR_TE_BIT) == 0) { - if ((mmio_read_32(DMA_DMACHCR) & DMACHCR_CHE_BIT) != 0U) { - ERROR("BL2: DMA - Channel Address Error\n"); - panic(); - break; - } - } - /* DMA transfer Disable */ - mmio_clrbits_32(DMA_DMACHCR, DMACHCR_DE_BIT); - while ((mmio_read_32(DMA_DMACHCR) & DMACHCR_DE_BIT) != 0) - ; - - mmio_write_32(DMA_DMASEC, 0); - mmio_write_16(DMA_DMAOR, 0); - mmio_write_32(DMA_DMACHCLR, DMA_USE_CHANNEL); -} - -void rcar_dma_exec(uintptr_t dst, uint32_t src, uint32_t len) -{ - uint32_t dma_len = len; - - if (len & DMA_FRACTION_MASK) - dma_len = (len + DMA_SIZE_UNIT) & ~DMA_FRACTION_MASK; - - if (!dma_len || dma_len > DMA_LENGTH_LIMIT) { - ERROR("BL2: DMA - size invalid, length (0x%x)\n", dma_len); - panic(); - } - - if (src & DMA_FRACTION_MASK) { - ERROR("BL2: DMA - src address invalid (0x%x), len=(0x%x)\n", - src, dma_len); - panic(); - } - - if ((dst & UINT32_MAX) + dma_len > DMADAR_BOUNDARY_ADDR || - (dst + dma_len > DMA_DST_LIMIT) || - (dst & DMA_FRACTION_MASK)) { - ERROR("BL2: DMA - dest address invalid (0x%lx), len=(0x%x)\n", - dst, dma_len); - panic(); - } - - dma_start(dst, src, dma_len); - dma_end(); -} - -void rcar_dma_init(void) -{ - dma_enable(); - dma_setup(); -} diff --git a/plat/renesas/common/common.mk b/plat/renesas/common/common.mk index adee49bf7..ec10b6f25 100644 --- a/plat/renesas/common/common.mk +++ b/plat/renesas/common/common.mk @@ -84,6 +84,7 @@ BL2_SOURCES += ${RCAR_GIC_SOURCES} \ drivers/renesas/common/io/io_emmcdrv.c \ drivers/renesas/common/io/io_memdrv.c \ drivers/renesas/common/io/io_rcar.c \ + drivers/renesas/common/dma/dma_driver.c \ drivers/renesas/common/delay/micro_delay.c \ drivers/renesas/common/emmc/emmc_interrupt.c \ drivers/renesas/common/emmc/emmc_utility.c \ diff --git a/plat/renesas/rcar/platform.mk b/plat/renesas/rcar/platform.mk index bb7af4044..a54255f0a 100644 --- a/plat/renesas/rcar/platform.mk +++ b/plat/renesas/rcar/platform.mk @@ -322,7 +322,6 @@ BL2_SOURCES += plat/renesas/rcar/aarch64/platform_common.c \ plat/renesas/rcar/bl2_cpg_init.c \ drivers/renesas/rcar/auth/auth_mod.c \ drivers/renesas/rcar/rpc/rpc_driver.c \ - drivers/renesas/rcar/dma/dma_driver.c \ drivers/renesas/rcar/avs/avs_driver.c \ drivers/renesas/rcar/board/board.c -- cgit v1.2.3 From 9a0c8b7c579032817d0159a9c4474d18a3fd9ed9 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Wed, 16 Dec 2020 11:11:09 +0000 Subject: drivers: renesas: auth: Move to common Move authentication driver code to common directory, so that the same code can be re-used by both R-Car Gen3 and RZ/G2 platforms. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: I02592dfc714998bf89b9feaa78f685ae36be6f59 --- drivers/renesas/common/auth/auth_mod.c | 172 +++++++++++++++++++++++++++++++++ drivers/renesas/rcar/auth/auth_mod.c | 172 --------------------------------- plat/renesas/common/common.mk | 1 + plat/renesas/rcar/platform.mk | 1 - 4 files changed, 173 insertions(+), 173 deletions(-) create mode 100644 drivers/renesas/common/auth/auth_mod.c delete mode 100644 drivers/renesas/rcar/auth/auth_mod.c diff --git a/drivers/renesas/common/auth/auth_mod.c b/drivers/renesas/common/auth/auth_mod.c new file mode 100644 index 000000000..4aa86e2a4 --- /dev/null +++ b/drivers/renesas/common/auth/auth_mod.c @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights + * reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include + +#include +#include "rom_api.h" + +typedef int32_t(*secure_boot_api_f) (uint32_t a, uint32_t b, void *c); +extern int32_t rcar_get_certificate(const int32_t name, uint32_t *cert_addr); + +#define RCAR_IMAGE_ID_MAX (10) +#define RCAR_CERT_MAGIC_NUM (0xE291F358U) +#define RCAR_BOOT_KEY_CERT (0xE6300C00U) +#define RCAR_BOOT_KEY_CERT_NEW (0xE6300F00U) +#define RST_BASE (0xE6160000U) +#define RST_MODEMR (RST_BASE + 0x0060U) +#define MFISOFTMDR (0xE6260600U) +#define MODEMR_MD5_MASK (0x00000020U) +#define MODEMR_MD5_SHIFT (5U) +#define SOFTMD_BOOTMODE_MASK (0x00000001U) +#define SOFTMD_NORMALBOOT (0x1U) + +static secure_boot_api_f secure_boot_api; + +int auth_mod_get_parent_id(unsigned int img_id, unsigned int *parent_id) +{ + return 1; +} + +int auth_mod_verify_img(unsigned int img_id, void *ptr, unsigned int len) +{ + int32_t ret = 0, index = 0; + uint32_t cert_addr = 0U; + static const struct img_to_cert_t { + uint32_t id; + int32_t cert; + const char *name; + } image[RCAR_IMAGE_ID_MAX] = { + { BL31_IMAGE_ID, SOC_FW_CONTENT_CERT_ID, "BL31" }, + { BL32_IMAGE_ID, TRUSTED_OS_FW_CONTENT_CERT_ID, "BL32" }, + { BL33_IMAGE_ID, NON_TRUSTED_FW_CONTENT_CERT_ID, "BL33" }, + { BL332_IMAGE_ID, BL332_CERT_ID, "BL332" }, + { BL333_IMAGE_ID, BL333_CERT_ID, "BL333" }, + { BL334_IMAGE_ID, BL334_CERT_ID, "BL334" }, + { BL335_IMAGE_ID, BL335_CERT_ID, "BL335" }, + { BL336_IMAGE_ID, BL336_CERT_ID, "BL336" }, + { BL337_IMAGE_ID, BL337_CERT_ID, "BL337" }, + { BL338_IMAGE_ID, BL338_CERT_ID, "BL338" }, + }; + +#if IMAGE_BL2 + switch (img_id) { + case TRUSTED_KEY_CERT_ID: + case SOC_FW_KEY_CERT_ID: + case TRUSTED_OS_FW_KEY_CERT_ID: + case NON_TRUSTED_FW_KEY_CERT_ID: + case BL332_KEY_CERT_ID: + case BL333_KEY_CERT_ID: + case BL334_KEY_CERT_ID: + case BL335_KEY_CERT_ID: + case BL336_KEY_CERT_ID: + case BL337_KEY_CERT_ID: + case BL338_KEY_CERT_ID: + case SOC_FW_CONTENT_CERT_ID: + case TRUSTED_OS_FW_CONTENT_CERT_ID: + case NON_TRUSTED_FW_CONTENT_CERT_ID: + case BL332_CERT_ID: + case BL333_CERT_ID: + case BL334_CERT_ID: + case BL335_CERT_ID: + case BL336_CERT_ID: + case BL337_CERT_ID: + case BL338_CERT_ID: + return ret; + case BL31_IMAGE_ID: + case BL32_IMAGE_ID: + case BL33_IMAGE_ID: + case BL332_IMAGE_ID: + case BL333_IMAGE_ID: + case BL334_IMAGE_ID: + case BL335_IMAGE_ID: + case BL336_IMAGE_ID: + case BL337_IMAGE_ID: + case BL338_IMAGE_ID: + goto verify_image; + default: + return -1; + } + +verify_image: + for (index = 0; index < RCAR_IMAGE_ID_MAX; index++) { + if (img_id != image[index].id) + continue; + + ret = rcar_get_certificate(image[index].cert, &cert_addr); + break; + } + + if (ret || (index == RCAR_IMAGE_ID_MAX)) { + ERROR("Verification Failed for image id = %d\n", img_id); + return ret; + } +#if RCAR_BL2_DCACHE == 1 + /* clean and disable */ + write_sctlr_el3(read_sctlr_el3() & ~SCTLR_C_BIT); + dcsw_op_all(DCCISW); +#endif + ret = (mmio_read_32(RCAR_BOOT_KEY_CERT_NEW) == RCAR_CERT_MAGIC_NUM) ? + secure_boot_api(RCAR_BOOT_KEY_CERT_NEW, cert_addr, NULL) : + secure_boot_api(RCAR_BOOT_KEY_CERT, cert_addr, NULL); + if (ret) + ERROR("Verification Failed 0x%x, %s\n", ret, image[index].name); + +#if RCAR_BL2_DCACHE == 1 + /* enable */ + write_sctlr_el3(read_sctlr_el3() | SCTLR_C_BIT); +#endif /* RCAR_BL2_DCACHE */ + +#endif /* IMAGE_BL2 */ + return ret; +} + +static int32_t normal_boot_verify(uint32_t a, uint32_t b, void *c) +{ + return 0; +} + +void auth_mod_init(void) +{ +#if RCAR_SECURE_BOOT + uint32_t soft_md = mmio_read_32(MFISOFTMDR) & SOFTMD_BOOTMODE_MASK; + uint32_t md = mmio_read_32(RST_MODEMR) & MODEMR_MD5_MASK; + uint32_t lcs, ret; + + secure_boot_api = (secure_boot_api_f) &rcar_rom_secure_boot_api; + + ret = rcar_rom_get_lcs(&lcs); + if (ret) { + ERROR("BL2: Failed to get the LCS. (%d)\n", ret); + panic(); + } + + switch (lcs) { + case LCS_SE: + if (soft_md == SOFTMD_NORMALBOOT) + secure_boot_api = &normal_boot_verify; + break; + case LCS_SD: + secure_boot_api = &normal_boot_verify; + break; + default: + if (md >> MODEMR_MD5_SHIFT) + secure_boot_api = &normal_boot_verify; + } + + NOTICE("BL2: %s boot\n", + secure_boot_api == &normal_boot_verify ? "Normal" : "Secure"); +#else + NOTICE("BL2: Normal boot\n"); + secure_boot_api = &normal_boot_verify; +#endif +} diff --git a/drivers/renesas/rcar/auth/auth_mod.c b/drivers/renesas/rcar/auth/auth_mod.c deleted file mode 100644 index 4aa86e2a4..000000000 --- a/drivers/renesas/rcar/auth/auth_mod.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights - * reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include -#include -#include -#include - -#include -#include "rom_api.h" - -typedef int32_t(*secure_boot_api_f) (uint32_t a, uint32_t b, void *c); -extern int32_t rcar_get_certificate(const int32_t name, uint32_t *cert_addr); - -#define RCAR_IMAGE_ID_MAX (10) -#define RCAR_CERT_MAGIC_NUM (0xE291F358U) -#define RCAR_BOOT_KEY_CERT (0xE6300C00U) -#define RCAR_BOOT_KEY_CERT_NEW (0xE6300F00U) -#define RST_BASE (0xE6160000U) -#define RST_MODEMR (RST_BASE + 0x0060U) -#define MFISOFTMDR (0xE6260600U) -#define MODEMR_MD5_MASK (0x00000020U) -#define MODEMR_MD5_SHIFT (5U) -#define SOFTMD_BOOTMODE_MASK (0x00000001U) -#define SOFTMD_NORMALBOOT (0x1U) - -static secure_boot_api_f secure_boot_api; - -int auth_mod_get_parent_id(unsigned int img_id, unsigned int *parent_id) -{ - return 1; -} - -int auth_mod_verify_img(unsigned int img_id, void *ptr, unsigned int len) -{ - int32_t ret = 0, index = 0; - uint32_t cert_addr = 0U; - static const struct img_to_cert_t { - uint32_t id; - int32_t cert; - const char *name; - } image[RCAR_IMAGE_ID_MAX] = { - { BL31_IMAGE_ID, SOC_FW_CONTENT_CERT_ID, "BL31" }, - { BL32_IMAGE_ID, TRUSTED_OS_FW_CONTENT_CERT_ID, "BL32" }, - { BL33_IMAGE_ID, NON_TRUSTED_FW_CONTENT_CERT_ID, "BL33" }, - { BL332_IMAGE_ID, BL332_CERT_ID, "BL332" }, - { BL333_IMAGE_ID, BL333_CERT_ID, "BL333" }, - { BL334_IMAGE_ID, BL334_CERT_ID, "BL334" }, - { BL335_IMAGE_ID, BL335_CERT_ID, "BL335" }, - { BL336_IMAGE_ID, BL336_CERT_ID, "BL336" }, - { BL337_IMAGE_ID, BL337_CERT_ID, "BL337" }, - { BL338_IMAGE_ID, BL338_CERT_ID, "BL338" }, - }; - -#if IMAGE_BL2 - switch (img_id) { - case TRUSTED_KEY_CERT_ID: - case SOC_FW_KEY_CERT_ID: - case TRUSTED_OS_FW_KEY_CERT_ID: - case NON_TRUSTED_FW_KEY_CERT_ID: - case BL332_KEY_CERT_ID: - case BL333_KEY_CERT_ID: - case BL334_KEY_CERT_ID: - case BL335_KEY_CERT_ID: - case BL336_KEY_CERT_ID: - case BL337_KEY_CERT_ID: - case BL338_KEY_CERT_ID: - case SOC_FW_CONTENT_CERT_ID: - case TRUSTED_OS_FW_CONTENT_CERT_ID: - case NON_TRUSTED_FW_CONTENT_CERT_ID: - case BL332_CERT_ID: - case BL333_CERT_ID: - case BL334_CERT_ID: - case BL335_CERT_ID: - case BL336_CERT_ID: - case BL337_CERT_ID: - case BL338_CERT_ID: - return ret; - case BL31_IMAGE_ID: - case BL32_IMAGE_ID: - case BL33_IMAGE_ID: - case BL332_IMAGE_ID: - case BL333_IMAGE_ID: - case BL334_IMAGE_ID: - case BL335_IMAGE_ID: - case BL336_IMAGE_ID: - case BL337_IMAGE_ID: - case BL338_IMAGE_ID: - goto verify_image; - default: - return -1; - } - -verify_image: - for (index = 0; index < RCAR_IMAGE_ID_MAX; index++) { - if (img_id != image[index].id) - continue; - - ret = rcar_get_certificate(image[index].cert, &cert_addr); - break; - } - - if (ret || (index == RCAR_IMAGE_ID_MAX)) { - ERROR("Verification Failed for image id = %d\n", img_id); - return ret; - } -#if RCAR_BL2_DCACHE == 1 - /* clean and disable */ - write_sctlr_el3(read_sctlr_el3() & ~SCTLR_C_BIT); - dcsw_op_all(DCCISW); -#endif - ret = (mmio_read_32(RCAR_BOOT_KEY_CERT_NEW) == RCAR_CERT_MAGIC_NUM) ? - secure_boot_api(RCAR_BOOT_KEY_CERT_NEW, cert_addr, NULL) : - secure_boot_api(RCAR_BOOT_KEY_CERT, cert_addr, NULL); - if (ret) - ERROR("Verification Failed 0x%x, %s\n", ret, image[index].name); - -#if RCAR_BL2_DCACHE == 1 - /* enable */ - write_sctlr_el3(read_sctlr_el3() | SCTLR_C_BIT); -#endif /* RCAR_BL2_DCACHE */ - -#endif /* IMAGE_BL2 */ - return ret; -} - -static int32_t normal_boot_verify(uint32_t a, uint32_t b, void *c) -{ - return 0; -} - -void auth_mod_init(void) -{ -#if RCAR_SECURE_BOOT - uint32_t soft_md = mmio_read_32(MFISOFTMDR) & SOFTMD_BOOTMODE_MASK; - uint32_t md = mmio_read_32(RST_MODEMR) & MODEMR_MD5_MASK; - uint32_t lcs, ret; - - secure_boot_api = (secure_boot_api_f) &rcar_rom_secure_boot_api; - - ret = rcar_rom_get_lcs(&lcs); - if (ret) { - ERROR("BL2: Failed to get the LCS. (%d)\n", ret); - panic(); - } - - switch (lcs) { - case LCS_SE: - if (soft_md == SOFTMD_NORMALBOOT) - secure_boot_api = &normal_boot_verify; - break; - case LCS_SD: - secure_boot_api = &normal_boot_verify; - break; - default: - if (md >> MODEMR_MD5_SHIFT) - secure_boot_api = &normal_boot_verify; - } - - NOTICE("BL2: %s boot\n", - secure_boot_api == &normal_boot_verify ? "Normal" : "Secure"); -#else - NOTICE("BL2: Normal boot\n"); - secure_boot_api = &normal_boot_verify; -#endif -} diff --git a/plat/renesas/common/common.mk b/plat/renesas/common/common.mk index ec10b6f25..61e86fe3b 100644 --- a/plat/renesas/common/common.mk +++ b/plat/renesas/common/common.mk @@ -84,6 +84,7 @@ BL2_SOURCES += ${RCAR_GIC_SOURCES} \ drivers/renesas/common/io/io_emmcdrv.c \ drivers/renesas/common/io/io_memdrv.c \ drivers/renesas/common/io/io_rcar.c \ + drivers/renesas/common/auth/auth_mod.c \ drivers/renesas/common/dma/dma_driver.c \ drivers/renesas/common/delay/micro_delay.c \ drivers/renesas/common/emmc/emmc_interrupt.c \ diff --git a/plat/renesas/rcar/platform.mk b/plat/renesas/rcar/platform.mk index a54255f0a..fc83cc5da 100644 --- a/plat/renesas/rcar/platform.mk +++ b/plat/renesas/rcar/platform.mk @@ -320,7 +320,6 @@ BL2_SOURCES += plat/renesas/rcar/aarch64/platform_common.c \ plat/renesas/rcar/bl2_plat_mem_params_desc.c \ plat/renesas/rcar/plat_image_load.c \ plat/renesas/rcar/bl2_cpg_init.c \ - drivers/renesas/rcar/auth/auth_mod.c \ drivers/renesas/rcar/rpc/rpc_driver.c \ drivers/renesas/rcar/avs/avs_driver.c \ drivers/renesas/rcar/board/board.c -- cgit v1.2.3 From b50b6c8149bf33b2001a228aed68fd1dd468b7ba Mon Sep 17 00:00:00 2001 From: Biju Das Date: Wed, 16 Dec 2020 11:13:06 +0000 Subject: drivers: renesas: avs: Move to common Move avs driver code to common directory, so that the same code can be re-used by both R-Car Gen3 and RZ/G2 platforms. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: I85d9fa8b6abf158ce2521f1696478f7c5339fc42 --- drivers/renesas/common/avs/avs_driver.c | 630 ++++++++++++++++++++++++++++++++ drivers/renesas/common/avs/avs_driver.h | 20 + drivers/renesas/rcar/avs/avs_driver.c | 630 -------------------------------- drivers/renesas/rcar/avs/avs_driver.h | 20 - plat/renesas/common/common.mk | 1 + plat/renesas/rcar/platform.mk | 3 +- 6 files changed, 652 insertions(+), 652 deletions(-) create mode 100644 drivers/renesas/common/avs/avs_driver.c create mode 100644 drivers/renesas/common/avs/avs_driver.h delete mode 100644 drivers/renesas/rcar/avs/avs_driver.c delete mode 100644 drivers/renesas/rcar/avs/avs_driver.h diff --git a/drivers/renesas/common/avs/avs_driver.c b/drivers/renesas/common/avs/avs_driver.c new file mode 100644 index 000000000..2c939cd59 --- /dev/null +++ b/drivers/renesas/common/avs/avs_driver.c @@ -0,0 +1,630 @@ +/* + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include "avs_driver.h" +#include "cpg_registers.h" +#include "rcar_def.h" +#include "rcar_private.h" + +#if (AVS_SETTING_ENABLE == 1) +#if PMIC_ROHM_BD9571 +/* Read PMIC register for debug. 1:enable / 0:disable */ +#define AVS_READ_PMIC_REG_ENABLE 0 +/* The re-try number of times of the AVS setting. */ +#define AVS_RETRY_NUM (1U) +#endif /* PMIC_ROHM_BD9571 */ + +/* Base address of Adaptive Voltage Scaling module registers*/ +#define AVS_BASE (0xE60A0000U) +/* Adaptive Dynamic Voltage ADJust Parameter2 registers */ +#define ADVADJP2 (AVS_BASE + 0x013CU) + +/* Mask VOLCOND bit in ADVADJP2 registers */ +#define ADVADJP2_VOLCOND_MASK (0x000001FFU) /* VOLCOND[8:0] */ + +#if PMIC_ROHM_BD9571 +/* I2C for DVFS bit in CPG registers for module standby and software reset*/ +#define CPG_SYS_DVFS_BIT (0x04000000U) +#endif /* PMIC_ROHM_BD9571 */ +/* ADVFS Module bit in CPG registers for module standby and software reset*/ +#define CPG_SYS_ADVFS_BIT (0x02000000U) + +#if PMIC_ROHM_BD9571 +/* Base address of IICDVFS registers*/ +#define IIC_DVFS_BASE (0xE60B0000U) +/* IIC bus data register */ +#define IIC_ICDR (IIC_DVFS_BASE + 0x0000U) +/* IIC bus control register */ +#define IIC_ICCR (IIC_DVFS_BASE + 0x0004U) +/* IIC bus status register */ +#define IIC_ICSR (IIC_DVFS_BASE + 0x0008U) +/* IIC interrupt control register */ +#define IIC_ICIC (IIC_DVFS_BASE + 0x000CU) +/* IIC clock control register low */ +#define IIC_ICCL (IIC_DVFS_BASE + 0x0010U) +/* IIC clock control register high */ +#define IIC_ICCH (IIC_DVFS_BASE + 0x0014U) + +/* Bit in ICSR register */ +#define ICSR_BUSY (0x10U) +#define ICSR_AL (0x08U) +#define ICSR_TACK (0x04U) +#define ICSR_WAIT (0x02U) +#define ICSR_DTE (0x01U) + +/* Bit in ICIC register */ +#define ICIC_TACKE (0x04U) +#define ICIC_WAITE (0x02U) +#define ICIC_DTEE (0x01U) + +/* I2C bus interface enable */ +#define ICCR_ENABLE (0x80U) +/* Start condition */ +#define ICCR_START (0x94U) +/* Stop condition */ +#define ICCR_STOP (0x90U) +/* Restart condition with change to receive mode change */ +#define ICCR_START_RECV (0x81U) +/* Stop condition for receive mode */ +#define ICCR_STOP_RECV (0xC0U) + +/* Low-level period of SCL */ +#define ICCL_FREQ_8p33M (0x07U) /* for CP Phy 8.3333MHz */ +#define ICCL_FREQ_10M (0x09U) /* for CP Phy 10MHz */ +#define ICCL_FREQ_12p5M (0x0BU) /* for CP Phy 12.5MHz */ +#define ICCL_FREQ_16p66M (0x0EU) /* for CP Phy 16.6666MHz */ +/* High-level period of SCL */ +#define ICCH_FREQ_8p33M (0x01U) /* for CP Phy 8.3333MHz */ +#define ICCH_FREQ_10M (0x02U) /* for CP Phy 10MHz */ +#define ICCH_FREQ_12p5M (0x03U) /* for CP Phy 12.5MHz */ +#define ICCH_FREQ_16p66M (0x05U) /* for CP Phy 16.6666MHz */ + +/* PMIC */ +/* ROHM BD9571 slave address + (W) */ +#define PMIC_W_SLAVE_ADDRESS (0x60U) +/* ROHM BD9571 slave address + (R) */ +#define PMIC_R_SLAVE_ADDRESS (0x61U) +/* ROHM BD9571 DVFS SetVID register */ +#define PMIC_DVFS_SETVID (0x54U) +#endif /* PMIC_ROHM_BD9571 */ + +/* Individual information */ +#define EFUSE_AVS0 (0U) +#define EFUSE_AVS_NUM ARRAY_SIZE(init_vol_tbl) + +typedef struct { + uint32_t avs; /* AVS code */ + uint8_t vol; /* Voltage */ +} initial_voltage_t; + +static const initial_voltage_t init_vol_tbl[] = { + /* AVS code, ROHM BD9571 DVFS SetVID register */ + {0x00U, 0x53U}, /* AVS0, 0.83V */ + {0x01U, 0x52U}, /* AVS1, 0.82V */ + {0x02U, 0x51U}, /* AVS2, 0.81V */ + {0x04U, 0x50U}, /* AVS3, 0.80V */ + {0x08U, 0x4FU}, /* AVS4, 0.79V */ + {0x10U, 0x4EU}, /* AVS5, 0.78V */ + {0x20U, 0x4DU}, /* AVS6, 0.77V */ + {0x40U, 0x4CU} /* AVS7, 0.76V */ +}; + +#if PMIC_ROHM_BD9571 +/* Kind of AVS settings status */ +typedef enum { + avs_status_none = 0, + avs_status_init, + avs_status_start_condition, + avs_status_set_slave_addr, + avs_status_write_reg_addr, + avs_status_write_reg_data, + avs_status_stop_condition, + avs_status_end, + avs_status_complete, + avs_status_al_start, + avs_status_al_transfer, + avs_status_nack, + avs_status_error_stop, + ave_status_error_end +} avs_status_t; + +/* Kind of AVS error */ +typedef enum { + avs_error_none = 0, + avs_error_al, + avs_error_nack +} avs_error_t; + +static avs_status_t avs_status; +static uint32_t avs_retry; +#endif /* PMIC_ROHM_BD9571 */ +static uint32_t efuse_avs = EFUSE_AVS0; + +#if PMIC_ROHM_BD9571 +/* prototype */ +static avs_error_t avs_check_error(void); +static void avs_set_iic_clock(void); +#if AVS_READ_PMIC_REG_ENABLE == 1 +static uint8_t avs_read_pmic_reg(uint8_t addr); +static void avs_poll(uint8_t bit_pos, uint8_t val); +#endif +#endif /* PMIC_ROHM_BD9571 */ +#endif /* (AVS_SETTING_ENABLE==1) */ + +/* + * Initialize to enable the AVS setting. + */ +void rcar_avs_init(void) +{ +#if (AVS_SETTING_ENABLE == 1) + uint32_t val; + +#if PMIC_ROHM_BD9571 + /* Initialize AVS status */ + avs_status = avs_status_init; +#endif /* PMIC_ROHM_BD9571 */ + + /* Enable clock supply to ADVFS. */ + mstpcr_write(CPG_SMSTPCR9, CPG_MSTPSR9, CPG_SYS_ADVFS_BIT); + + /* Read AVS code (Initial values are derived from eFuse) */ + val = mmio_read_32(ADVADJP2) & ADVADJP2_VOLCOND_MASK; + + for (efuse_avs = 0U; efuse_avs < EFUSE_AVS_NUM; efuse_avs++) { + if (val == init_vol_tbl[efuse_avs].avs) + break; + } + + if (efuse_avs >= EFUSE_AVS_NUM) + efuse_avs = EFUSE_AVS0; /* Not applicable */ +#if PMIC_ROHM_BD9571 + /* Enable clock supply to DVFS. */ + mstpcr_write(CPG_SMSTPCR9, CPG_MSTPSR9, CPG_SYS_DVFS_BIT); + + /* Disable I2C module and All internal registers initialized. */ + mmio_write_8(IIC_ICCR, 0x00U); + while ((mmio_read_8(IIC_ICCR) & ICCR_ENABLE) != 0U) { + /* Disable I2C module and all internal registers initialized. */ + mmio_write_8(IIC_ICCR, 0x00U); + } + + /* Set next status */ + avs_status = avs_status_start_condition; + +#endif /* PMIC_ROHM_BD9571 */ +#endif /* (AVS_SETTING_ENABLE==1) */ +} + +/* + * Set the value of register corresponding to the voltage + * by transfer of I2C to PIMC. + */ +void rcar_avs_setting(void) +{ +#if (AVS_SETTING_ENABLE == 1) +#if PMIC_ROHM_BD9571 + avs_error_t err; + + switch (avs_status) { + case avs_status_start_condition: + /* Set ICCR.ICE=1 to activate the I2C module. */ + mmio_write_8(IIC_ICCR, mmio_read_8(IIC_ICCR) | ICCR_ENABLE); + /* Set frequency of 400kHz */ + avs_set_iic_clock(); + /* Set ICIC.TACKE=1, ICIC.WAITE=1, ICIC.DTEE=1 to */ + /* enable interrupt control. */ + mmio_write_8(IIC_ICIC, mmio_read_8(IIC_ICIC) + | ICIC_TACKE | ICIC_WAITE | ICIC_DTEE); + /* Write H'94 in ICCR to issue start condition */ + mmio_write_8(IIC_ICCR, ICCR_START); + /* Set next status */ + avs_status = avs_status_set_slave_addr; + break; + case avs_status_set_slave_addr: + /* Check error. */ + err = avs_check_error(); + if (err == avs_error_al) { + /* Recovery sequence of just after start. */ + avs_status = avs_status_al_start; + } else if (err == avs_error_nack) { + /* Recovery sequence of detected NACK */ + avs_status = avs_status_nack; + } else { + /* Was data transmission enabled ? */ + if ((mmio_read_8(IIC_ICSR) & ICSR_DTE) == ICSR_DTE) { + /* Clear ICIC.DTEE to disable a DTE interrupt */ + mmio_write_8(IIC_ICIC, mmio_read_8(IIC_ICIC) + & (uint8_t) (~ICIC_DTEE)); + /* Send PMIC slave address + (W) */ + mmio_write_8(IIC_ICDR, PMIC_W_SLAVE_ADDRESS); + /* Set next status */ + avs_status = avs_status_write_reg_addr; + } + } + break; + case avs_status_write_reg_addr: + /* Check error. */ + err = avs_check_error(); + if (err == avs_error_al) { + /* Recovery sequence of during data transfer. */ + avs_status = avs_status_al_transfer; + } else if (err == avs_error_nack) { + /* Recovery sequence of detected NACK */ + avs_status = avs_status_nack; + } else { + /* If wait state after data transmission. */ + if ((mmio_read_8(IIC_ICSR) & ICSR_WAIT) == ICSR_WAIT) { + /* Write PMIC DVFS_SetVID address */ + mmio_write_8(IIC_ICDR, PMIC_DVFS_SETVID); + /* Clear ICSR.WAIT to exit from wait state. */ + mmio_write_8(IIC_ICSR, mmio_read_8(IIC_ICSR) + & (uint8_t) (~ICSR_WAIT)); + /* Set next status */ + avs_status = avs_status_write_reg_data; + } + } + break; + case avs_status_write_reg_data: + /* Check error. */ + err = avs_check_error(); + if (err == avs_error_al) { + /* Recovery sequence of during data transfer. */ + avs_status = avs_status_al_transfer; + } else if (err == avs_error_nack) { + /* Recovery sequence of detected NACK */ + avs_status = avs_status_nack; + } else { + /* If wait state after data transmission. */ + if ((mmio_read_8(IIC_ICSR) & ICSR_WAIT) == ICSR_WAIT) { + /* Dose efuse_avs exceed the number of */ + /* the tables? */ + if (efuse_avs >= EFUSE_AVS_NUM) { + ERROR("%s%s=%u\n", "AVS number of ", + "eFuse is out of range. number", + efuse_avs); + /* Infinite loop */ + panic(); + } + /* Write PMIC DVFS_SetVID value */ + mmio_write_8(IIC_ICDR, + init_vol_tbl[efuse_avs].vol); + /* Clear ICSR.WAIT to exit from wait state. */ + mmio_write_8(IIC_ICSR, mmio_read_8(IIC_ICSR) + & (uint8_t) (~ICSR_WAIT)); + /* Set next status */ + avs_status = avs_status_stop_condition; + } + } + break; + case avs_status_stop_condition: + err = avs_check_error(); + if (err == avs_error_al) { + /* Recovery sequence of during data transfer. */ + avs_status = avs_status_al_transfer; + } else if (err == avs_error_nack) { + /* Recovery sequence of detected NACK */ + avs_status = avs_status_nack; + } else { + /* If wait state after data transmission. */ + if ((mmio_read_8(IIC_ICSR) & ICSR_WAIT) == ICSR_WAIT) { + /* Write H'90 in ICCR to issue stop condition */ + mmio_write_8(IIC_ICCR, ICCR_STOP); + /* Clear ICSR.WAIT to exit from wait state. */ + mmio_write_8(IIC_ICSR, mmio_read_8(IIC_ICSR) + & (uint8_t) (~ICSR_WAIT)); + /* Set next status */ + avs_status = avs_status_end; + } + } + break; + case avs_status_end: + /* Is this module not busy?. */ + if ((mmio_read_8(IIC_ICSR) & ICSR_BUSY) == 0U) { + /* Set ICCR=H'00 to disable the I2C module. */ + mmio_write_8(IIC_ICCR, 0x00U); + /* Set next status */ + avs_status = avs_status_complete; + } + break; + case avs_status_al_start: + /* Clear ICSR.AL bit */ + mmio_write_8(IIC_ICSR, (mmio_read_8(IIC_ICSR) + & (uint8_t) (~ICSR_AL))); + /* Transmit a clock pulse */ + mmio_write_8(IIC_ICDR, init_vol_tbl[EFUSE_AVS0].vol); + /* Set next status */ + avs_status = avs_status_error_stop; + break; + case avs_status_al_transfer: + /* Clear ICSR.AL bit */ + mmio_write_8(IIC_ICSR, (mmio_read_8(IIC_ICSR) + & (uint8_t) (~ICSR_AL))); + /* Set next status */ + avs_status = avs_status_error_stop; + break; + case avs_status_nack: + /* Write H'90 in ICCR to issue stop condition */ + mmio_write_8(IIC_ICCR, ICCR_STOP); + /* Disable a WAIT and DTEE interrupt. */ + mmio_write_8(IIC_ICIC, mmio_read_8(IIC_ICIC) + & (uint8_t) (~(ICIC_WAITE | ICIC_DTEE))); + /* Clear ICSR.TACK bit */ + mmio_write_8(IIC_ICSR, mmio_read_8(IIC_ICSR) + & (uint8_t) (~ICSR_TACK)); + /* Set next status */ + avs_status = ave_status_error_end; + break; + case avs_status_error_stop: + /* If wait state after data transmission. */ + if ((mmio_read_8(IIC_ICSR) & ICSR_WAIT) == ICSR_WAIT) { + /* Write H'90 in ICCR to issue stop condition */ + mmio_write_8(IIC_ICCR, ICCR_STOP); + /* Clear ICSR.WAIT to exit from wait state. */ + mmio_write_8(IIC_ICSR, mmio_read_8(IIC_ICSR) + & (uint8_t) (~ICSR_WAIT)); + /* Set next status */ + avs_status = ave_status_error_end; + } + break; + case ave_status_error_end: + /* Is this module not busy?. */ + if ((mmio_read_8(IIC_ICSR) & ICSR_BUSY) == 0U) { + /* Set ICCR=H'00 to disable the I2C module. */ + mmio_write_8(IIC_ICCR, 0x00U); + /* Increment the re-try number of times. */ + avs_retry++; + /* Set start a re-try to status. */ + avs_status = avs_status_start_condition; + } + break; + case avs_status_complete: + /* After "avs_status" became the "avs_status_complete", */ + /* "avs_setting()" function may be called. */ + break; + default: + /* This case is not possible. */ + ERROR("AVS setting is in invalid status. status=%u\n", + avs_status); + /* Infinite loop */ + panic(); + break; + } +#endif /* PMIC_ROHM_BD9571 */ +#endif /* (AVS_SETTING_ENABLE==1) */ +} + +/* + * Finish the AVS setting. + */ +void rcar_avs_end(void) +{ +#if (AVS_SETTING_ENABLE == 1) + uint32_t mstp; + +#if PMIC_ROHM_BD9571 + /* While status is not completion, be repeated. */ + while (avs_status != avs_status_complete) + rcar_avs_setting(); + + NOTICE("AVS setting succeeded. DVFS_SetVID=0x%x\n", + init_vol_tbl[efuse_avs].vol); + +#if AVS_READ_PMIC_REG_ENABLE == 1 + { + uint8_t addr = PMIC_DVFS_SETVID; + uint8_t value = avs_read_pmic_reg(addr); + + NOTICE("Read PMIC register. address=0x%x value=0x%x\n", + addr, value); + } +#endif + + /* Bit of the module which wants to disable clock supply. */ + mstp = CPG_SYS_DVFS_BIT; + /* Disables the supply of clock signal to a module. */ + cpg_write(CPG_SMSTPCR9, mmio_read_32(CPG_SMSTPCR9) | mstp); +#endif /* PMIC_ROHM_BD9571 */ + + /* Bit of the module which wants to disable clock supply. */ + mstp = CPG_SYS_ADVFS_BIT; + /* Disables the supply of clock signal to a module. */ + cpg_write(CPG_SMSTPCR9, mmio_read_32(CPG_SMSTPCR9) | mstp); + +#endif /* (AVS_SETTING_ENABLE==1) */ +} + +#if (AVS_SETTING_ENABLE == 1) +#if PMIC_ROHM_BD9571 +/* + * Check error and judge re-try. + */ +static avs_error_t avs_check_error(void) +{ + avs_error_t ret; + + if ((mmio_read_8(IIC_ICSR) & ICSR_AL) == ICSR_AL) { + NOTICE("%s AVS status=%d Retry=%u\n", + "Loss of arbitration is detected.", avs_status, avs_retry); + /* Check of retry number of times */ + if (avs_retry >= AVS_RETRY_NUM) { + ERROR("AVS setting failed in retry. max=%u\n", + AVS_RETRY_NUM); + /* Infinite loop */ + panic(); + } + /* Set the error detected to error status. */ + ret = avs_error_al; + } else if ((mmio_read_8(IIC_ICSR) & ICSR_TACK) == ICSR_TACK) { + NOTICE("%s AVS status=%d Retry=%u\n", + "Non-acknowledge is detected.", avs_status, avs_retry); + /* Check of retry number of times */ + if (avs_retry >= AVS_RETRY_NUM) { + ERROR("AVS setting failed in retry. max=%u\n", + AVS_RETRY_NUM); + /* Infinite loop */ + panic(); + } + /* Set the error detected to error status. */ + ret = avs_error_nack; + } else { + /* Not error. */ + ret = avs_error_none; + } + return ret; +} + +/* + * Set I2C for DVFS clock. + */ +static void avs_set_iic_clock(void) +{ + uint32_t md_pin; + + /* Read Mode pin register. */ + md_pin = mmio_read_32(RCAR_MODEMR) & CHECK_MD13_MD14; + /* Set the module clock (CP phy) for the IIC-DVFS. */ + /* CP phy is EXTAL / 2. */ + switch (md_pin) { + case MD14_MD13_TYPE_0: /* EXTAL = 16.6666MHz */ + mmio_write_8(IIC_ICCL, ICCL_FREQ_8p33M); + mmio_write_8(IIC_ICCH, ICCH_FREQ_8p33M); + break; + case MD14_MD13_TYPE_1: /* EXTAL = 20MHz */ + mmio_write_8(IIC_ICCL, ICCL_FREQ_10M); + mmio_write_8(IIC_ICCH, ICCH_FREQ_10M); + break; + case MD14_MD13_TYPE_2: /* EXTAL = 25MHz (H3/M3) */ + mmio_write_8(IIC_ICCL, ICCL_FREQ_12p5M); + mmio_write_8(IIC_ICCH, ICCH_FREQ_12p5M); + break; + case MD14_MD13_TYPE_3: /* EXTAL = 33.3333MHz */ + mmio_write_8(IIC_ICCL, ICCL_FREQ_16p66M); + mmio_write_8(IIC_ICCH, ICCH_FREQ_16p66M); + break; + default: /* This case is not possible. */ + /* CP Phy frequency is to be set for the 16.66MHz */ + mmio_write_8(IIC_ICCL, ICCL_FREQ_16p66M); + mmio_write_8(IIC_ICCH, ICCH_FREQ_16p66M); + break; + } +} + +#if AVS_READ_PMIC_REG_ENABLE == 1 +/* + * Read the value of the register of PMIC. + */ +static uint8_t avs_read_pmic_reg(uint8_t addr) +{ + uint8_t reg; + + /* Set ICCR.ICE=1 to activate the I2C module. */ + mmio_write_8(IIC_ICCR, mmio_read_8(IIC_ICCR) | ICCR_ENABLE); + + /* Set frequency of 400kHz */ + avs_set_iic_clock(); + + /* + * Set ICIC.WAITE=1, ICIC.DTEE=1 to enable data transmission + * interrupt and wait interrupt. + */ + mmio_write_8(IIC_ICIC, mmio_read_8(IIC_ICIC) | ICIC_WAITE | ICIC_DTEE); + + /* Write H'94 in ICCR to issue start condition */ + mmio_write_8(IIC_ICCR, ICCR_START); + + /* Wait for a until ICSR.DTE becomes 1. */ + avs_poll(ICSR_DTE, 1U); + + /* Clear ICIC.DTEE to disable a DTE interrupt. */ + mmio_write_8(IIC_ICIC, mmio_read_8(IIC_ICIC) & (uint8_t) (~ICIC_DTEE)); + /* Send slave address of PMIC */ + mmio_write_8(IIC_ICDR, PMIC_W_SLAVE_ADDRESS); + + /* Wait for a until ICSR.WAIT becomes 1. */ + avs_poll(ICSR_WAIT, 1U); + + /* write PMIC address */ + mmio_write_8(IIC_ICDR, addr); + /* Clear ICSR.WAIT to exit from WAIT status. */ + mmio_write_8(IIC_ICSR, mmio_read_8(IIC_ICSR) & (uint8_t) (~ICSR_WAIT)); + + /* Wait for a until ICSR.WAIT becomes 1. */ + avs_poll(ICSR_WAIT, 1U); + + /* Write H'94 in ICCR to issue restart condition */ + mmio_write_8(IIC_ICCR, ICCR_START); + /* Clear ICSR.WAIT to exit from WAIT status. */ + mmio_write_8(IIC_ICSR, mmio_read_8(IIC_ICSR) & (uint8_t) (~ICSR_WAIT)); + /* Set ICIC.DTEE=1 to enable data transmission interrupt. */ + mmio_write_8(IIC_ICIC, mmio_read_8(IIC_ICIC) | ICIC_DTEE); + + /* Wait for a until ICSR.DTE becomes 1. */ + avs_poll(ICSR_DTE, 1U); + + /* Clear ICIC.DTEE to disable a DTE interrupt. */ + mmio_write_8(IIC_ICIC, mmio_read_8(IIC_ICIC) & (uint8_t) (~ICIC_DTEE)); + /* Send slave address of PMIC */ + mmio_write_8(IIC_ICDR, PMIC_R_SLAVE_ADDRESS); + + /* Wait for a until ICSR.WAIT becomes 1. */ + avs_poll(ICSR_WAIT, 1U); + + /* Write H'81 to ICCR to issue the repeated START condition */ + /* for changing the transmission mode to the receive mode. */ + mmio_write_8(IIC_ICCR, ICCR_START_RECV); + /* Clear ICSR.WAIT to exit from WAIT status. */ + mmio_write_8(IIC_ICSR, mmio_read_8(IIC_ICSR) & (uint8_t) (~ICSR_WAIT)); + + /* Wait for a until ICSR.WAIT becomes 1. */ + avs_poll(ICSR_WAIT, 1U); + + /* Set ICCR to H'C0 for the STOP condition */ + mmio_write_8(IIC_ICCR, ICCR_STOP_RECV); + /* Clear ICSR.WAIT to exit from WAIT status. */ + mmio_write_8(IIC_ICSR, mmio_read_8(IIC_ICSR) & (uint8_t) (~ICSR_WAIT)); + /* Set ICIC.DTEE=1 to enable data transmission interrupt. */ + mmio_write_8(IIC_ICIC, mmio_read_8(IIC_ICIC) | ICIC_DTEE); + + /* Wait for a until ICSR.DTE becomes 1. */ + avs_poll(ICSR_DTE, 1U); + + /* Receive DVFS SetVID register */ + /* Clear ICIC.DTEE to disable a DTE interrupt. */ + mmio_write_8(IIC_ICIC, mmio_read_8(IIC_ICIC) & (uint8_t) (~ICIC_DTEE)); + /* Receive DVFS SetVID register */ + reg = mmio_read_8(IIC_ICDR); + + /* Wait until ICSR.BUSY is cleared. */ + avs_poll(ICSR_BUSY, 0U); + + /* Set ICCR=H'00 to disable the I2C module. */ + mmio_write_8(IIC_ICCR, 0x00U); + + return reg; +} + +/* + * Wait processing by the polling. + */ +static void avs_poll(uint8_t bit_pos, uint8_t val) +{ + uint8_t bit_val = 0U; + + if (val != 0U) + bit_val = bit_pos; + + while (1) { + if ((mmio_read_8(IIC_ICSR) & bit_pos) == bit_val) + break; + } +} +#endif /* AVS_READ_PMIC_REG_ENABLE */ +#endif /* PMIC_ROHM_BD9571 */ +#endif /* (AVS_SETTING_ENABLE==1) */ diff --git a/drivers/renesas/common/avs/avs_driver.h b/drivers/renesas/common/avs/avs_driver.h new file mode 100644 index 000000000..aa773b604 --- /dev/null +++ b/drivers/renesas/common/avs/avs_driver.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights + * reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef AVS_DRIVER_H +#define AVS_DRIVER_H + +/* AVS Setting. 1:enable / 0:disable */ +#ifndef AVS_SETTING_ENABLE +#define AVS_SETTING_ENABLE 1 +#endif /* AVS_SETTING_ENABLE */ + +void rcar_avs_init(void); +void rcar_avs_setting(void); +void rcar_avs_end(void); + +#endif /* AVS_DRIVER_H */ diff --git a/drivers/renesas/rcar/avs/avs_driver.c b/drivers/renesas/rcar/avs/avs_driver.c deleted file mode 100644 index 2c939cd59..000000000 --- a/drivers/renesas/rcar/avs/avs_driver.c +++ /dev/null @@ -1,630 +0,0 @@ -/* - * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include - -#include "avs_driver.h" -#include "cpg_registers.h" -#include "rcar_def.h" -#include "rcar_private.h" - -#if (AVS_SETTING_ENABLE == 1) -#if PMIC_ROHM_BD9571 -/* Read PMIC register for debug. 1:enable / 0:disable */ -#define AVS_READ_PMIC_REG_ENABLE 0 -/* The re-try number of times of the AVS setting. */ -#define AVS_RETRY_NUM (1U) -#endif /* PMIC_ROHM_BD9571 */ - -/* Base address of Adaptive Voltage Scaling module registers*/ -#define AVS_BASE (0xE60A0000U) -/* Adaptive Dynamic Voltage ADJust Parameter2 registers */ -#define ADVADJP2 (AVS_BASE + 0x013CU) - -/* Mask VOLCOND bit in ADVADJP2 registers */ -#define ADVADJP2_VOLCOND_MASK (0x000001FFU) /* VOLCOND[8:0] */ - -#if PMIC_ROHM_BD9571 -/* I2C for DVFS bit in CPG registers for module standby and software reset*/ -#define CPG_SYS_DVFS_BIT (0x04000000U) -#endif /* PMIC_ROHM_BD9571 */ -/* ADVFS Module bit in CPG registers for module standby and software reset*/ -#define CPG_SYS_ADVFS_BIT (0x02000000U) - -#if PMIC_ROHM_BD9571 -/* Base address of IICDVFS registers*/ -#define IIC_DVFS_BASE (0xE60B0000U) -/* IIC bus data register */ -#define IIC_ICDR (IIC_DVFS_BASE + 0x0000U) -/* IIC bus control register */ -#define IIC_ICCR (IIC_DVFS_BASE + 0x0004U) -/* IIC bus status register */ -#define IIC_ICSR (IIC_DVFS_BASE + 0x0008U) -/* IIC interrupt control register */ -#define IIC_ICIC (IIC_DVFS_BASE + 0x000CU) -/* IIC clock control register low */ -#define IIC_ICCL (IIC_DVFS_BASE + 0x0010U) -/* IIC clock control register high */ -#define IIC_ICCH (IIC_DVFS_BASE + 0x0014U) - -/* Bit in ICSR register */ -#define ICSR_BUSY (0x10U) -#define ICSR_AL (0x08U) -#define ICSR_TACK (0x04U) -#define ICSR_WAIT (0x02U) -#define ICSR_DTE (0x01U) - -/* Bit in ICIC register */ -#define ICIC_TACKE (0x04U) -#define ICIC_WAITE (0x02U) -#define ICIC_DTEE (0x01U) - -/* I2C bus interface enable */ -#define ICCR_ENABLE (0x80U) -/* Start condition */ -#define ICCR_START (0x94U) -/* Stop condition */ -#define ICCR_STOP (0x90U) -/* Restart condition with change to receive mode change */ -#define ICCR_START_RECV (0x81U) -/* Stop condition for receive mode */ -#define ICCR_STOP_RECV (0xC0U) - -/* Low-level period of SCL */ -#define ICCL_FREQ_8p33M (0x07U) /* for CP Phy 8.3333MHz */ -#define ICCL_FREQ_10M (0x09U) /* for CP Phy 10MHz */ -#define ICCL_FREQ_12p5M (0x0BU) /* for CP Phy 12.5MHz */ -#define ICCL_FREQ_16p66M (0x0EU) /* for CP Phy 16.6666MHz */ -/* High-level period of SCL */ -#define ICCH_FREQ_8p33M (0x01U) /* for CP Phy 8.3333MHz */ -#define ICCH_FREQ_10M (0x02U) /* for CP Phy 10MHz */ -#define ICCH_FREQ_12p5M (0x03U) /* for CP Phy 12.5MHz */ -#define ICCH_FREQ_16p66M (0x05U) /* for CP Phy 16.6666MHz */ - -/* PMIC */ -/* ROHM BD9571 slave address + (W) */ -#define PMIC_W_SLAVE_ADDRESS (0x60U) -/* ROHM BD9571 slave address + (R) */ -#define PMIC_R_SLAVE_ADDRESS (0x61U) -/* ROHM BD9571 DVFS SetVID register */ -#define PMIC_DVFS_SETVID (0x54U) -#endif /* PMIC_ROHM_BD9571 */ - -/* Individual information */ -#define EFUSE_AVS0 (0U) -#define EFUSE_AVS_NUM ARRAY_SIZE(init_vol_tbl) - -typedef struct { - uint32_t avs; /* AVS code */ - uint8_t vol; /* Voltage */ -} initial_voltage_t; - -static const initial_voltage_t init_vol_tbl[] = { - /* AVS code, ROHM BD9571 DVFS SetVID register */ - {0x00U, 0x53U}, /* AVS0, 0.83V */ - {0x01U, 0x52U}, /* AVS1, 0.82V */ - {0x02U, 0x51U}, /* AVS2, 0.81V */ - {0x04U, 0x50U}, /* AVS3, 0.80V */ - {0x08U, 0x4FU}, /* AVS4, 0.79V */ - {0x10U, 0x4EU}, /* AVS5, 0.78V */ - {0x20U, 0x4DU}, /* AVS6, 0.77V */ - {0x40U, 0x4CU} /* AVS7, 0.76V */ -}; - -#if PMIC_ROHM_BD9571 -/* Kind of AVS settings status */ -typedef enum { - avs_status_none = 0, - avs_status_init, - avs_status_start_condition, - avs_status_set_slave_addr, - avs_status_write_reg_addr, - avs_status_write_reg_data, - avs_status_stop_condition, - avs_status_end, - avs_status_complete, - avs_status_al_start, - avs_status_al_transfer, - avs_status_nack, - avs_status_error_stop, - ave_status_error_end -} avs_status_t; - -/* Kind of AVS error */ -typedef enum { - avs_error_none = 0, - avs_error_al, - avs_error_nack -} avs_error_t; - -static avs_status_t avs_status; -static uint32_t avs_retry; -#endif /* PMIC_ROHM_BD9571 */ -static uint32_t efuse_avs = EFUSE_AVS0; - -#if PMIC_ROHM_BD9571 -/* prototype */ -static avs_error_t avs_check_error(void); -static void avs_set_iic_clock(void); -#if AVS_READ_PMIC_REG_ENABLE == 1 -static uint8_t avs_read_pmic_reg(uint8_t addr); -static void avs_poll(uint8_t bit_pos, uint8_t val); -#endif -#endif /* PMIC_ROHM_BD9571 */ -#endif /* (AVS_SETTING_ENABLE==1) */ - -/* - * Initialize to enable the AVS setting. - */ -void rcar_avs_init(void) -{ -#if (AVS_SETTING_ENABLE == 1) - uint32_t val; - -#if PMIC_ROHM_BD9571 - /* Initialize AVS status */ - avs_status = avs_status_init; -#endif /* PMIC_ROHM_BD9571 */ - - /* Enable clock supply to ADVFS. */ - mstpcr_write(CPG_SMSTPCR9, CPG_MSTPSR9, CPG_SYS_ADVFS_BIT); - - /* Read AVS code (Initial values are derived from eFuse) */ - val = mmio_read_32(ADVADJP2) & ADVADJP2_VOLCOND_MASK; - - for (efuse_avs = 0U; efuse_avs < EFUSE_AVS_NUM; efuse_avs++) { - if (val == init_vol_tbl[efuse_avs].avs) - break; - } - - if (efuse_avs >= EFUSE_AVS_NUM) - efuse_avs = EFUSE_AVS0; /* Not applicable */ -#if PMIC_ROHM_BD9571 - /* Enable clock supply to DVFS. */ - mstpcr_write(CPG_SMSTPCR9, CPG_MSTPSR9, CPG_SYS_DVFS_BIT); - - /* Disable I2C module and All internal registers initialized. */ - mmio_write_8(IIC_ICCR, 0x00U); - while ((mmio_read_8(IIC_ICCR) & ICCR_ENABLE) != 0U) { - /* Disable I2C module and all internal registers initialized. */ - mmio_write_8(IIC_ICCR, 0x00U); - } - - /* Set next status */ - avs_status = avs_status_start_condition; - -#endif /* PMIC_ROHM_BD9571 */ -#endif /* (AVS_SETTING_ENABLE==1) */ -} - -/* - * Set the value of register corresponding to the voltage - * by transfer of I2C to PIMC. - */ -void rcar_avs_setting(void) -{ -#if (AVS_SETTING_ENABLE == 1) -#if PMIC_ROHM_BD9571 - avs_error_t err; - - switch (avs_status) { - case avs_status_start_condition: - /* Set ICCR.ICE=1 to activate the I2C module. */ - mmio_write_8(IIC_ICCR, mmio_read_8(IIC_ICCR) | ICCR_ENABLE); - /* Set frequency of 400kHz */ - avs_set_iic_clock(); - /* Set ICIC.TACKE=1, ICIC.WAITE=1, ICIC.DTEE=1 to */ - /* enable interrupt control. */ - mmio_write_8(IIC_ICIC, mmio_read_8(IIC_ICIC) - | ICIC_TACKE | ICIC_WAITE | ICIC_DTEE); - /* Write H'94 in ICCR to issue start condition */ - mmio_write_8(IIC_ICCR, ICCR_START); - /* Set next status */ - avs_status = avs_status_set_slave_addr; - break; - case avs_status_set_slave_addr: - /* Check error. */ - err = avs_check_error(); - if (err == avs_error_al) { - /* Recovery sequence of just after start. */ - avs_status = avs_status_al_start; - } else if (err == avs_error_nack) { - /* Recovery sequence of detected NACK */ - avs_status = avs_status_nack; - } else { - /* Was data transmission enabled ? */ - if ((mmio_read_8(IIC_ICSR) & ICSR_DTE) == ICSR_DTE) { - /* Clear ICIC.DTEE to disable a DTE interrupt */ - mmio_write_8(IIC_ICIC, mmio_read_8(IIC_ICIC) - & (uint8_t) (~ICIC_DTEE)); - /* Send PMIC slave address + (W) */ - mmio_write_8(IIC_ICDR, PMIC_W_SLAVE_ADDRESS); - /* Set next status */ - avs_status = avs_status_write_reg_addr; - } - } - break; - case avs_status_write_reg_addr: - /* Check error. */ - err = avs_check_error(); - if (err == avs_error_al) { - /* Recovery sequence of during data transfer. */ - avs_status = avs_status_al_transfer; - } else if (err == avs_error_nack) { - /* Recovery sequence of detected NACK */ - avs_status = avs_status_nack; - } else { - /* If wait state after data transmission. */ - if ((mmio_read_8(IIC_ICSR) & ICSR_WAIT) == ICSR_WAIT) { - /* Write PMIC DVFS_SetVID address */ - mmio_write_8(IIC_ICDR, PMIC_DVFS_SETVID); - /* Clear ICSR.WAIT to exit from wait state. */ - mmio_write_8(IIC_ICSR, mmio_read_8(IIC_ICSR) - & (uint8_t) (~ICSR_WAIT)); - /* Set next status */ - avs_status = avs_status_write_reg_data; - } - } - break; - case avs_status_write_reg_data: - /* Check error. */ - err = avs_check_error(); - if (err == avs_error_al) { - /* Recovery sequence of during data transfer. */ - avs_status = avs_status_al_transfer; - } else if (err == avs_error_nack) { - /* Recovery sequence of detected NACK */ - avs_status = avs_status_nack; - } else { - /* If wait state after data transmission. */ - if ((mmio_read_8(IIC_ICSR) & ICSR_WAIT) == ICSR_WAIT) { - /* Dose efuse_avs exceed the number of */ - /* the tables? */ - if (efuse_avs >= EFUSE_AVS_NUM) { - ERROR("%s%s=%u\n", "AVS number of ", - "eFuse is out of range. number", - efuse_avs); - /* Infinite loop */ - panic(); - } - /* Write PMIC DVFS_SetVID value */ - mmio_write_8(IIC_ICDR, - init_vol_tbl[efuse_avs].vol); - /* Clear ICSR.WAIT to exit from wait state. */ - mmio_write_8(IIC_ICSR, mmio_read_8(IIC_ICSR) - & (uint8_t) (~ICSR_WAIT)); - /* Set next status */ - avs_status = avs_status_stop_condition; - } - } - break; - case avs_status_stop_condition: - err = avs_check_error(); - if (err == avs_error_al) { - /* Recovery sequence of during data transfer. */ - avs_status = avs_status_al_transfer; - } else if (err == avs_error_nack) { - /* Recovery sequence of detected NACK */ - avs_status = avs_status_nack; - } else { - /* If wait state after data transmission. */ - if ((mmio_read_8(IIC_ICSR) & ICSR_WAIT) == ICSR_WAIT) { - /* Write H'90 in ICCR to issue stop condition */ - mmio_write_8(IIC_ICCR, ICCR_STOP); - /* Clear ICSR.WAIT to exit from wait state. */ - mmio_write_8(IIC_ICSR, mmio_read_8(IIC_ICSR) - & (uint8_t) (~ICSR_WAIT)); - /* Set next status */ - avs_status = avs_status_end; - } - } - break; - case avs_status_end: - /* Is this module not busy?. */ - if ((mmio_read_8(IIC_ICSR) & ICSR_BUSY) == 0U) { - /* Set ICCR=H'00 to disable the I2C module. */ - mmio_write_8(IIC_ICCR, 0x00U); - /* Set next status */ - avs_status = avs_status_complete; - } - break; - case avs_status_al_start: - /* Clear ICSR.AL bit */ - mmio_write_8(IIC_ICSR, (mmio_read_8(IIC_ICSR) - & (uint8_t) (~ICSR_AL))); - /* Transmit a clock pulse */ - mmio_write_8(IIC_ICDR, init_vol_tbl[EFUSE_AVS0].vol); - /* Set next status */ - avs_status = avs_status_error_stop; - break; - case avs_status_al_transfer: - /* Clear ICSR.AL bit */ - mmio_write_8(IIC_ICSR, (mmio_read_8(IIC_ICSR) - & (uint8_t) (~ICSR_AL))); - /* Set next status */ - avs_status = avs_status_error_stop; - break; - case avs_status_nack: - /* Write H'90 in ICCR to issue stop condition */ - mmio_write_8(IIC_ICCR, ICCR_STOP); - /* Disable a WAIT and DTEE interrupt. */ - mmio_write_8(IIC_ICIC, mmio_read_8(IIC_ICIC) - & (uint8_t) (~(ICIC_WAITE | ICIC_DTEE))); - /* Clear ICSR.TACK bit */ - mmio_write_8(IIC_ICSR, mmio_read_8(IIC_ICSR) - & (uint8_t) (~ICSR_TACK)); - /* Set next status */ - avs_status = ave_status_error_end; - break; - case avs_status_error_stop: - /* If wait state after data transmission. */ - if ((mmio_read_8(IIC_ICSR) & ICSR_WAIT) == ICSR_WAIT) { - /* Write H'90 in ICCR to issue stop condition */ - mmio_write_8(IIC_ICCR, ICCR_STOP); - /* Clear ICSR.WAIT to exit from wait state. */ - mmio_write_8(IIC_ICSR, mmio_read_8(IIC_ICSR) - & (uint8_t) (~ICSR_WAIT)); - /* Set next status */ - avs_status = ave_status_error_end; - } - break; - case ave_status_error_end: - /* Is this module not busy?. */ - if ((mmio_read_8(IIC_ICSR) & ICSR_BUSY) == 0U) { - /* Set ICCR=H'00 to disable the I2C module. */ - mmio_write_8(IIC_ICCR, 0x00U); - /* Increment the re-try number of times. */ - avs_retry++; - /* Set start a re-try to status. */ - avs_status = avs_status_start_condition; - } - break; - case avs_status_complete: - /* After "avs_status" became the "avs_status_complete", */ - /* "avs_setting()" function may be called. */ - break; - default: - /* This case is not possible. */ - ERROR("AVS setting is in invalid status. status=%u\n", - avs_status); - /* Infinite loop */ - panic(); - break; - } -#endif /* PMIC_ROHM_BD9571 */ -#endif /* (AVS_SETTING_ENABLE==1) */ -} - -/* - * Finish the AVS setting. - */ -void rcar_avs_end(void) -{ -#if (AVS_SETTING_ENABLE == 1) - uint32_t mstp; - -#if PMIC_ROHM_BD9571 - /* While status is not completion, be repeated. */ - while (avs_status != avs_status_complete) - rcar_avs_setting(); - - NOTICE("AVS setting succeeded. DVFS_SetVID=0x%x\n", - init_vol_tbl[efuse_avs].vol); - -#if AVS_READ_PMIC_REG_ENABLE == 1 - { - uint8_t addr = PMIC_DVFS_SETVID; - uint8_t value = avs_read_pmic_reg(addr); - - NOTICE("Read PMIC register. address=0x%x value=0x%x\n", - addr, value); - } -#endif - - /* Bit of the module which wants to disable clock supply. */ - mstp = CPG_SYS_DVFS_BIT; - /* Disables the supply of clock signal to a module. */ - cpg_write(CPG_SMSTPCR9, mmio_read_32(CPG_SMSTPCR9) | mstp); -#endif /* PMIC_ROHM_BD9571 */ - - /* Bit of the module which wants to disable clock supply. */ - mstp = CPG_SYS_ADVFS_BIT; - /* Disables the supply of clock signal to a module. */ - cpg_write(CPG_SMSTPCR9, mmio_read_32(CPG_SMSTPCR9) | mstp); - -#endif /* (AVS_SETTING_ENABLE==1) */ -} - -#if (AVS_SETTING_ENABLE == 1) -#if PMIC_ROHM_BD9571 -/* - * Check error and judge re-try. - */ -static avs_error_t avs_check_error(void) -{ - avs_error_t ret; - - if ((mmio_read_8(IIC_ICSR) & ICSR_AL) == ICSR_AL) { - NOTICE("%s AVS status=%d Retry=%u\n", - "Loss of arbitration is detected.", avs_status, avs_retry); - /* Check of retry number of times */ - if (avs_retry >= AVS_RETRY_NUM) { - ERROR("AVS setting failed in retry. max=%u\n", - AVS_RETRY_NUM); - /* Infinite loop */ - panic(); - } - /* Set the error detected to error status. */ - ret = avs_error_al; - } else if ((mmio_read_8(IIC_ICSR) & ICSR_TACK) == ICSR_TACK) { - NOTICE("%s AVS status=%d Retry=%u\n", - "Non-acknowledge is detected.", avs_status, avs_retry); - /* Check of retry number of times */ - if (avs_retry >= AVS_RETRY_NUM) { - ERROR("AVS setting failed in retry. max=%u\n", - AVS_RETRY_NUM); - /* Infinite loop */ - panic(); - } - /* Set the error detected to error status. */ - ret = avs_error_nack; - } else { - /* Not error. */ - ret = avs_error_none; - } - return ret; -} - -/* - * Set I2C for DVFS clock. - */ -static void avs_set_iic_clock(void) -{ - uint32_t md_pin; - - /* Read Mode pin register. */ - md_pin = mmio_read_32(RCAR_MODEMR) & CHECK_MD13_MD14; - /* Set the module clock (CP phy) for the IIC-DVFS. */ - /* CP phy is EXTAL / 2. */ - switch (md_pin) { - case MD14_MD13_TYPE_0: /* EXTAL = 16.6666MHz */ - mmio_write_8(IIC_ICCL, ICCL_FREQ_8p33M); - mmio_write_8(IIC_ICCH, ICCH_FREQ_8p33M); - break; - case MD14_MD13_TYPE_1: /* EXTAL = 20MHz */ - mmio_write_8(IIC_ICCL, ICCL_FREQ_10M); - mmio_write_8(IIC_ICCH, ICCH_FREQ_10M); - break; - case MD14_MD13_TYPE_2: /* EXTAL = 25MHz (H3/M3) */ - mmio_write_8(IIC_ICCL, ICCL_FREQ_12p5M); - mmio_write_8(IIC_ICCH, ICCH_FREQ_12p5M); - break; - case MD14_MD13_TYPE_3: /* EXTAL = 33.3333MHz */ - mmio_write_8(IIC_ICCL, ICCL_FREQ_16p66M); - mmio_write_8(IIC_ICCH, ICCH_FREQ_16p66M); - break; - default: /* This case is not possible. */ - /* CP Phy frequency is to be set for the 16.66MHz */ - mmio_write_8(IIC_ICCL, ICCL_FREQ_16p66M); - mmio_write_8(IIC_ICCH, ICCH_FREQ_16p66M); - break; - } -} - -#if AVS_READ_PMIC_REG_ENABLE == 1 -/* - * Read the value of the register of PMIC. - */ -static uint8_t avs_read_pmic_reg(uint8_t addr) -{ - uint8_t reg; - - /* Set ICCR.ICE=1 to activate the I2C module. */ - mmio_write_8(IIC_ICCR, mmio_read_8(IIC_ICCR) | ICCR_ENABLE); - - /* Set frequency of 400kHz */ - avs_set_iic_clock(); - - /* - * Set ICIC.WAITE=1, ICIC.DTEE=1 to enable data transmission - * interrupt and wait interrupt. - */ - mmio_write_8(IIC_ICIC, mmio_read_8(IIC_ICIC) | ICIC_WAITE | ICIC_DTEE); - - /* Write H'94 in ICCR to issue start condition */ - mmio_write_8(IIC_ICCR, ICCR_START); - - /* Wait for a until ICSR.DTE becomes 1. */ - avs_poll(ICSR_DTE, 1U); - - /* Clear ICIC.DTEE to disable a DTE interrupt. */ - mmio_write_8(IIC_ICIC, mmio_read_8(IIC_ICIC) & (uint8_t) (~ICIC_DTEE)); - /* Send slave address of PMIC */ - mmio_write_8(IIC_ICDR, PMIC_W_SLAVE_ADDRESS); - - /* Wait for a until ICSR.WAIT becomes 1. */ - avs_poll(ICSR_WAIT, 1U); - - /* write PMIC address */ - mmio_write_8(IIC_ICDR, addr); - /* Clear ICSR.WAIT to exit from WAIT status. */ - mmio_write_8(IIC_ICSR, mmio_read_8(IIC_ICSR) & (uint8_t) (~ICSR_WAIT)); - - /* Wait for a until ICSR.WAIT becomes 1. */ - avs_poll(ICSR_WAIT, 1U); - - /* Write H'94 in ICCR to issue restart condition */ - mmio_write_8(IIC_ICCR, ICCR_START); - /* Clear ICSR.WAIT to exit from WAIT status. */ - mmio_write_8(IIC_ICSR, mmio_read_8(IIC_ICSR) & (uint8_t) (~ICSR_WAIT)); - /* Set ICIC.DTEE=1 to enable data transmission interrupt. */ - mmio_write_8(IIC_ICIC, mmio_read_8(IIC_ICIC) | ICIC_DTEE); - - /* Wait for a until ICSR.DTE becomes 1. */ - avs_poll(ICSR_DTE, 1U); - - /* Clear ICIC.DTEE to disable a DTE interrupt. */ - mmio_write_8(IIC_ICIC, mmio_read_8(IIC_ICIC) & (uint8_t) (~ICIC_DTEE)); - /* Send slave address of PMIC */ - mmio_write_8(IIC_ICDR, PMIC_R_SLAVE_ADDRESS); - - /* Wait for a until ICSR.WAIT becomes 1. */ - avs_poll(ICSR_WAIT, 1U); - - /* Write H'81 to ICCR to issue the repeated START condition */ - /* for changing the transmission mode to the receive mode. */ - mmio_write_8(IIC_ICCR, ICCR_START_RECV); - /* Clear ICSR.WAIT to exit from WAIT status. */ - mmio_write_8(IIC_ICSR, mmio_read_8(IIC_ICSR) & (uint8_t) (~ICSR_WAIT)); - - /* Wait for a until ICSR.WAIT becomes 1. */ - avs_poll(ICSR_WAIT, 1U); - - /* Set ICCR to H'C0 for the STOP condition */ - mmio_write_8(IIC_ICCR, ICCR_STOP_RECV); - /* Clear ICSR.WAIT to exit from WAIT status. */ - mmio_write_8(IIC_ICSR, mmio_read_8(IIC_ICSR) & (uint8_t) (~ICSR_WAIT)); - /* Set ICIC.DTEE=1 to enable data transmission interrupt. */ - mmio_write_8(IIC_ICIC, mmio_read_8(IIC_ICIC) | ICIC_DTEE); - - /* Wait for a until ICSR.DTE becomes 1. */ - avs_poll(ICSR_DTE, 1U); - - /* Receive DVFS SetVID register */ - /* Clear ICIC.DTEE to disable a DTE interrupt. */ - mmio_write_8(IIC_ICIC, mmio_read_8(IIC_ICIC) & (uint8_t) (~ICIC_DTEE)); - /* Receive DVFS SetVID register */ - reg = mmio_read_8(IIC_ICDR); - - /* Wait until ICSR.BUSY is cleared. */ - avs_poll(ICSR_BUSY, 0U); - - /* Set ICCR=H'00 to disable the I2C module. */ - mmio_write_8(IIC_ICCR, 0x00U); - - return reg; -} - -/* - * Wait processing by the polling. - */ -static void avs_poll(uint8_t bit_pos, uint8_t val) -{ - uint8_t bit_val = 0U; - - if (val != 0U) - bit_val = bit_pos; - - while (1) { - if ((mmio_read_8(IIC_ICSR) & bit_pos) == bit_val) - break; - } -} -#endif /* AVS_READ_PMIC_REG_ENABLE */ -#endif /* PMIC_ROHM_BD9571 */ -#endif /* (AVS_SETTING_ENABLE==1) */ diff --git a/drivers/renesas/rcar/avs/avs_driver.h b/drivers/renesas/rcar/avs/avs_driver.h deleted file mode 100644 index aa773b604..000000000 --- a/drivers/renesas/rcar/avs/avs_driver.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights - * reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef AVS_DRIVER_H -#define AVS_DRIVER_H - -/* AVS Setting. 1:enable / 0:disable */ -#ifndef AVS_SETTING_ENABLE -#define AVS_SETTING_ENABLE 1 -#endif /* AVS_SETTING_ENABLE */ - -void rcar_avs_init(void); -void rcar_avs_setting(void); -void rcar_avs_end(void); - -#endif /* AVS_DRIVER_H */ diff --git a/plat/renesas/common/common.mk b/plat/renesas/common/common.mk index 61e86fe3b..46035714e 100644 --- a/plat/renesas/common/common.mk +++ b/plat/renesas/common/common.mk @@ -86,6 +86,7 @@ BL2_SOURCES += ${RCAR_GIC_SOURCES} \ drivers/renesas/common/io/io_rcar.c \ drivers/renesas/common/auth/auth_mod.c \ drivers/renesas/common/dma/dma_driver.c \ + drivers/renesas/common/avs/avs_driver.c \ drivers/renesas/common/delay/micro_delay.c \ drivers/renesas/common/emmc/emmc_interrupt.c \ drivers/renesas/common/emmc/emmc_utility.c \ diff --git a/plat/renesas/rcar/platform.mk b/plat/renesas/rcar/platform.mk index fc83cc5da..35dd0ef13 100644 --- a/plat/renesas/rcar/platform.mk +++ b/plat/renesas/rcar/platform.mk @@ -303,7 +303,7 @@ PLAT_INCLUDES += -Idrivers/renesas/rcar/ddr \ -Idrivers/renesas/rcar/board \ -Idrivers/renesas/rcar/cpld/ \ -Idrivers/renesas/common/iic_dvfs \ - -Idrivers/renesas/rcar/avs \ + -Idrivers/renesas/common/avs \ -Idrivers/renesas/common/delay \ -Idrivers/renesas/common/rom \ -Idrivers/renesas/common/scif \ @@ -321,7 +321,6 @@ BL2_SOURCES += plat/renesas/rcar/aarch64/platform_common.c \ plat/renesas/rcar/plat_image_load.c \ plat/renesas/rcar/bl2_cpg_init.c \ drivers/renesas/rcar/rpc/rpc_driver.c \ - drivers/renesas/rcar/avs/avs_driver.c \ drivers/renesas/rcar/board/board.c BL31_SOURCES += plat/renesas/rcar/plat_topology.c \ -- cgit v1.2.3 From f1be079225fa57bc348baf8163847d8b6b5c5a9d Mon Sep 17 00:00:00 2001 From: Biju Das Date: Wed, 16 Dec 2020 11:15:33 +0000 Subject: drivers: renesas: rpc: Move to common Move rpc driver code to common directory, so that the same code can be re-used by both R-Car Gen3 and RZ/G2 platforms. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: I04805d720d95b8edcc14e652f897fadc7f432197 --- drivers/renesas/common/rpc/rpc_driver.c | 57 ++++++++++++++++++++++++++++++ drivers/renesas/common/rpc/rpc_registers.h | 25 +++++++++++++ drivers/renesas/rcar/rpc/rpc_driver.c | 57 ------------------------------ drivers/renesas/rcar/rpc/rpc_registers.h | 25 ------------- plat/renesas/common/common.mk | 1 + plat/renesas/rcar/platform.mk | 1 - 6 files changed, 83 insertions(+), 83 deletions(-) create mode 100644 drivers/renesas/common/rpc/rpc_driver.c create mode 100644 drivers/renesas/common/rpc/rpc_registers.h delete mode 100644 drivers/renesas/rcar/rpc/rpc_driver.c delete mode 100644 drivers/renesas/rcar/rpc/rpc_registers.h diff --git a/drivers/renesas/common/rpc/rpc_driver.c b/drivers/renesas/common/rpc/rpc_driver.c new file mode 100644 index 000000000..63de5b851 --- /dev/null +++ b/drivers/renesas/common/rpc/rpc_driver.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include + +#include "cpg_registers.h" +#include "rcar_def.h" +#include "rcar_private.h" +#include "rpc_registers.h" + +#define MSTPSR9_RPC_BIT (0x00020000U) +#define RPC_CMNCR_MD_BIT (0x80000000U) +#define RPC_PHYCNT_CAL BIT(31) +#define RPC_PHYCNT_STRTIM_M3V1 (0x6 << 15UL) +#define RPC_PHYCNT_STRTIM (0x7 << 15UL) + +static void rpc_enable(void) +{ + /* Enable clock supply to RPC. */ + mstpcr_write(CPG_SMSTPCR9, CPG_MSTPSR9, MSTPSR9_RPC_BIT); +} + +static void rpc_setup(void) +{ + uint32_t product, cut, reg, phy_strtim; + + if (mmio_read_32(RPC_CMNCR) & RPC_CMNCR_MD_BIT) + mmio_clrbits_32(RPC_CMNCR, RPC_CMNCR_MD_BIT); + + product = mmio_read_32(RCAR_PRR) & PRR_PRODUCT_MASK; + cut = mmio_read_32(RCAR_PRR) & PRR_CUT_MASK; + + if ((product == PRR_PRODUCT_M3) && (cut < PRR_PRODUCT_30)) + phy_strtim = RPC_PHYCNT_STRTIM_M3V1; + else + phy_strtim = RPC_PHYCNT_STRTIM; + + reg = mmio_read_32(RPC_PHYCNT); + reg &= ~RPC_PHYCNT_STRTIM; + reg |= phy_strtim; + mmio_write_32(RPC_PHYCNT, reg); + reg |= RPC_PHYCNT_CAL; + mmio_write_32(RPC_PHYCNT, reg); +} + +void rcar_rpc_init(void) +{ + rpc_enable(); + rpc_setup(); +} diff --git a/drivers/renesas/common/rpc/rpc_registers.h b/drivers/renesas/common/rpc/rpc_registers.h new file mode 100644 index 000000000..79aea8599 --- /dev/null +++ b/drivers/renesas/common/rpc/rpc_registers.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef RPC_REGISTERS_H +#define RPC_REGISTERS_H + +#define RPC_BASE (0xEE200000U) +#define RPC_CMNCR (RPC_BASE + 0x0000U) +#define RPC_SSLDR (RPC_BASE + 0x0004U) +#define RPC_DRCR (RPC_BASE + 0x000CU) +#define RPC_DRCMR (RPC_BASE + 0x0010U) +#define RPC_DRENR (RPC_BASE + 0x001CU) +#define RPC_SMCR (RPC_BASE + 0x0020U) +#define RPC_SMCMR (RPC_BASE + 0x0024U) +#define RPC_SMENR (RPC_BASE + 0x0030U) +#define RPC_CMNSR (RPC_BASE + 0x0048U) +#define RPC_DRDMCR (RPC_BASE + 0x0058U) +#define RPC_DRDRENR (RPC_BASE + 0x005CU) +#define RPC_PHYCNT (RPC_BASE + 0x007CU) +#define RPC_PHYINT (RPC_BASE + 0x0088U) + +#endif /* RPC_REGISTERS_H */ diff --git a/drivers/renesas/rcar/rpc/rpc_driver.c b/drivers/renesas/rcar/rpc/rpc_driver.c deleted file mode 100644 index 63de5b851..000000000 --- a/drivers/renesas/rcar/rpc/rpc_driver.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include - -#include -#include - -#include "cpg_registers.h" -#include "rcar_def.h" -#include "rcar_private.h" -#include "rpc_registers.h" - -#define MSTPSR9_RPC_BIT (0x00020000U) -#define RPC_CMNCR_MD_BIT (0x80000000U) -#define RPC_PHYCNT_CAL BIT(31) -#define RPC_PHYCNT_STRTIM_M3V1 (0x6 << 15UL) -#define RPC_PHYCNT_STRTIM (0x7 << 15UL) - -static void rpc_enable(void) -{ - /* Enable clock supply to RPC. */ - mstpcr_write(CPG_SMSTPCR9, CPG_MSTPSR9, MSTPSR9_RPC_BIT); -} - -static void rpc_setup(void) -{ - uint32_t product, cut, reg, phy_strtim; - - if (mmio_read_32(RPC_CMNCR) & RPC_CMNCR_MD_BIT) - mmio_clrbits_32(RPC_CMNCR, RPC_CMNCR_MD_BIT); - - product = mmio_read_32(RCAR_PRR) & PRR_PRODUCT_MASK; - cut = mmio_read_32(RCAR_PRR) & PRR_CUT_MASK; - - if ((product == PRR_PRODUCT_M3) && (cut < PRR_PRODUCT_30)) - phy_strtim = RPC_PHYCNT_STRTIM_M3V1; - else - phy_strtim = RPC_PHYCNT_STRTIM; - - reg = mmio_read_32(RPC_PHYCNT); - reg &= ~RPC_PHYCNT_STRTIM; - reg |= phy_strtim; - mmio_write_32(RPC_PHYCNT, reg); - reg |= RPC_PHYCNT_CAL; - mmio_write_32(RPC_PHYCNT, reg); -} - -void rcar_rpc_init(void) -{ - rpc_enable(); - rpc_setup(); -} diff --git a/drivers/renesas/rcar/rpc/rpc_registers.h b/drivers/renesas/rcar/rpc/rpc_registers.h deleted file mode 100644 index 79aea8599..000000000 --- a/drivers/renesas/rcar/rpc/rpc_registers.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef RPC_REGISTERS_H -#define RPC_REGISTERS_H - -#define RPC_BASE (0xEE200000U) -#define RPC_CMNCR (RPC_BASE + 0x0000U) -#define RPC_SSLDR (RPC_BASE + 0x0004U) -#define RPC_DRCR (RPC_BASE + 0x000CU) -#define RPC_DRCMR (RPC_BASE + 0x0010U) -#define RPC_DRENR (RPC_BASE + 0x001CU) -#define RPC_SMCR (RPC_BASE + 0x0020U) -#define RPC_SMCMR (RPC_BASE + 0x0024U) -#define RPC_SMENR (RPC_BASE + 0x0030U) -#define RPC_CMNSR (RPC_BASE + 0x0048U) -#define RPC_DRDMCR (RPC_BASE + 0x0058U) -#define RPC_DRDRENR (RPC_BASE + 0x005CU) -#define RPC_PHYCNT (RPC_BASE + 0x007CU) -#define RPC_PHYINT (RPC_BASE + 0x0088U) - -#endif /* RPC_REGISTERS_H */ diff --git a/plat/renesas/common/common.mk b/plat/renesas/common/common.mk index 46035714e..b342bdc08 100644 --- a/plat/renesas/common/common.mk +++ b/plat/renesas/common/common.mk @@ -85,6 +85,7 @@ BL2_SOURCES += ${RCAR_GIC_SOURCES} \ drivers/renesas/common/io/io_memdrv.c \ drivers/renesas/common/io/io_rcar.c \ drivers/renesas/common/auth/auth_mod.c \ + drivers/renesas/common/rpc/rpc_driver.c \ drivers/renesas/common/dma/dma_driver.c \ drivers/renesas/common/avs/avs_driver.c \ drivers/renesas/common/delay/micro_delay.c \ diff --git a/plat/renesas/rcar/platform.mk b/plat/renesas/rcar/platform.mk index 35dd0ef13..542b36e22 100644 --- a/plat/renesas/rcar/platform.mk +++ b/plat/renesas/rcar/platform.mk @@ -320,7 +320,6 @@ BL2_SOURCES += plat/renesas/rcar/aarch64/platform_common.c \ plat/renesas/rcar/bl2_plat_mem_params_desc.c \ plat/renesas/rcar/plat_image_load.c \ plat/renesas/rcar/bl2_cpg_init.c \ - drivers/renesas/rcar/rpc/rpc_driver.c \ drivers/renesas/rcar/board/board.c BL31_SOURCES += plat/renesas/rcar/plat_topology.c \ -- cgit v1.2.3 From 662d3cc8075828d6d56ef646b8fccca667828b11 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Wed, 16 Dec 2020 11:53:59 +0000 Subject: drivers: renesas: Move ddr/qos/qos header files Move DDR/QoS/PFC header files, so that the same code can be re-used by both R-Car Gen3 and RZ/G2 platforms. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: I2cc0ceda8d05b6b8d95a69afdc233dc0d098e850 --- drivers/renesas/common/ddr_regs.h | 257 ++++++++++++++++++++++++++++++++++++ drivers/renesas/common/pfc_regs.h | 230 ++++++++++++++++++++++++++++++++ drivers/renesas/common/qos_reg.h | 133 +++++++++++++++++++ drivers/renesas/rcar/ddr/ddr_regs.h | 257 ------------------------------------ drivers/renesas/rcar/pfc/pfc_regs.h | 230 -------------------------------- drivers/renesas/rcar/qos/qos_reg.h | 133 ------------------- plat/renesas/rcar/platform.mk | 1 + 7 files changed, 621 insertions(+), 620 deletions(-) create mode 100644 drivers/renesas/common/ddr_regs.h create mode 100644 drivers/renesas/common/pfc_regs.h create mode 100644 drivers/renesas/common/qos_reg.h delete mode 100644 drivers/renesas/rcar/ddr/ddr_regs.h delete mode 100644 drivers/renesas/rcar/pfc/pfc_regs.h delete mode 100644 drivers/renesas/rcar/qos/qos_reg.h diff --git a/drivers/renesas/common/ddr_regs.h b/drivers/renesas/common/ddr_regs.h new file mode 100644 index 000000000..ba26c69c8 --- /dev/null +++ b/drivers/renesas/common/ddr_regs.h @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2015-2019, Renesas Electronics Corporation + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef BOOT_INIT_DRAM_REGDEF_H_ +#define BOOT_INIT_DRAM_REGDEF_H_ + +/* DBSC registers */ +#define DBSC_DBSYSCONF0 0xE6790000U +#define DBSC_DBSYSCONF1 0xE6790004U +#define DBSC_DBPHYCONF0 0xE6790010U +#define DBSC_DBKIND 0xE6790020U +#define DBSC_DBMEMCONF(ch, cs) (0xE6790030U + 0x10U * (ch) + 0x04U * (cs)) +#define DBSC_DBMEMCONF_0_0 0xE6790030U +#define DBSC_DBMEMCONF_0_1 0xE6790034U +#define DBSC_DBMEMCONF_0_2 0xE6790038U +#define DBSC_DBMEMCONF_0_3 0xE679003CU +#define DBSC_DBMEMCONF_1_2 0xE6790048U +#define DBSC_DBMEMCONF_1_3 0xE679004CU +#define DBSC_DBMEMCONF_1_0 0xE6790040U +#define DBSC_DBMEMCONF_1_1 0xE6790044U +#define DBSC_DBMEMCONF_2_0 0xE6790050U +#define DBSC_DBMEMCONF_2_1 0xE6790054U +#define DBSC_DBMEMCONF_2_2 0xE6790058U +#define DBSC_DBMEMCONF_2_3 0xE679005CU +#define DBSC_DBMEMCONF_3_0 0xE6790060U +#define DBSC_DBMEMCONF_3_1 0xE6790064U +#define DBSC_DBMEMCONF_3_2 0xE6790068U +#define DBSC_DBMEMCONF_3_3 0xE679006CU +#define DBSC_DBSYSCNT0 0xE6790100U +#define DBSC_DBSVCR1 0xE6790104U +#define DBSC_DBSTATE0 0xE6790108U +#define DBSC_DBSTATE1 0xE679010CU +#define DBSC_DBINTEN 0xE6790180U +#define DBSC_DBINTSTAT0 0xE6790184U +#define DBSC_DBACEN 0xE6790200U +#define DBSC_DBRFEN 0xE6790204U +#define DBSC_DBCMD 0xE6790208U +#define DBSC_DBWAIT 0xE6790210U +#define DBSC_DBSYSCTRL0 0xE6790280U +#define DBSC_DBTR(x) (0xE6790300U + 0x04U * (x)) +#define DBSC_DBTR0 0xE6790300U +#define DBSC_DBTR1 0xE6790304U +#define DBSC_DBTR2 0xE6790308U +#define DBSC_DBTR3 0xE679030CU +#define DBSC_DBTR4 0xE6790310U +#define DBSC_DBTR5 0xE6790314U +#define DBSC_DBTR6 0xE6790318U +#define DBSC_DBTR7 0xE679031CU +#define DBSC_DBTR8 0xE6790320U +#define DBSC_DBTR9 0xE6790324U +#define DBSC_DBTR10 0xE6790328U +#define DBSC_DBTR11 0xE679032CU +#define DBSC_DBTR12 0xE6790330U +#define DBSC_DBTR13 0xE6790334U +#define DBSC_DBTR14 0xE6790338U +#define DBSC_DBTR15 0xE679033CU +#define DBSC_DBTR16 0xE6790340U +#define DBSC_DBTR17 0xE6790344U +#define DBSC_DBTR18 0xE6790348U +#define DBSC_DBTR19 0xE679034CU +#define DBSC_DBTR20 0xE6790350U +#define DBSC_DBTR21 0xE6790354U +#define DBSC_DBTR22 0xE6790358U +#define DBSC_DBTR23 0xE679035CU +#define DBSC_DBTR24 0xE6790360U +#define DBSC_DBTR25 0xE6790364U +#define DBSC_DBTR26 0xE6790368U +#define DBSC_DBBL 0xE6790400U +#define DBSC_DBRFCNF1 0xE6790414U +#define DBSC_DBRFCNF2 0xE6790418U +#define DBSC_DBTSPCNF 0xE6790420U +#define DBSC_DBCALCNF 0xE6790424U +#define DBSC_DBRNK(x) (0xE6790430U + 0x04U * (x)) +#define DBSC_DBRNK2 0xE6790438U +#define DBSC_DBRNK3 0xE679043CU +#define DBSC_DBRNK4 0xE6790440U +#define DBSC_DBRNK5 0xE6790444U +#define DBSC_DBPDNCNF 0xE6790450U +#define DBSC_DBODT(x) (0xE6790460U + 0x04U * (x)) +#define DBSC_DBODT0 0xE6790460U +#define DBSC_DBODT1 0xE6790464U +#define DBSC_DBODT2 0xE6790468U +#define DBSC_DBODT3 0xE679046CU +#define DBSC_DBODT4 0xE6790470U +#define DBSC_DBODT5 0xE6790474U +#define DBSC_DBODT6 0xE6790478U +#define DBSC_DBODT7 0xE679047CU +#define DBSC_DBADJ0 0xE6790500U +#define DBSC_DBDBICNT 0xE6790518U +#define DBSC_DBDFIPMSTRCNF 0xE6790520U +#define DBSC_DBDFICUPDCNF 0xE679052CU +#define DBSC_DBDFISTAT(ch) (0xE6790600U + 0x40U * (ch)) +#define DBSC_DBDFISTAT_0 0xE6790600U +#define DBSC_DBDFISTAT_1 0xE6790640U +#define DBSC_DBDFISTAT_2 0xE6790680U +#define DBSC_DBDFISTAT_3 0xE67906C0U +#define DBSC_DBDFICNT(ch) (0xE6790604U + 0x40U * (ch)) +#define DBSC_DBDFICNT_0 0xE6790604U +#define DBSC_DBDFICNT_1 0xE6790644U +#define DBSC_DBDFICNT_2 0xE6790684U +#define DBSC_DBDFICNT_3 0xE67906C4U +#define DBSC_DBPDCNT0(ch) (0xE6790610U + 0x40U * (ch)) +#define DBSC_DBPDCNT0_0 0xE6790610U +#define DBSC_DBPDCNT0_1 0xE6790650U +#define DBSC_DBPDCNT0_2 0xE6790690U +#define DBSC_DBPDCNT0_3 0xE67906D0U +#define DBSC_DBPDCNT1(ch) (0xE6790614U + 0x40U * (ch)) +#define DBSC_DBPDCNT1_0 0xE6790614U +#define DBSC_DBPDCNT1_1 0xE6790654U +#define DBSC_DBPDCNT1_2 0xE6790694U +#define DBSC_DBPDCNT1_3 0xE67906D4U +#define DBSC_DBPDCNT2(ch) (0xE6790618U + 0x40U * (ch)) +#define DBSC_DBPDCNT2_0 0xE6790618U +#define DBSC_DBPDCNT2_1 0xE6790658U +#define DBSC_DBPDCNT2_2 0xE6790698U +#define DBSC_DBPDCNT2_3 0xE67906D8U +#define DBSC_DBPDCNT3(ch) (0xE679061CU + 0x40U * (ch)) +#define DBSC_DBPDCNT3_0 0xE679061CU +#define DBSC_DBPDCNT3_1 0xE679065CU +#define DBSC_DBPDCNT3_2 0xE679069CU +#define DBSC_DBPDCNT3_3 0xE67906DCU +#define DBSC_DBPDLK(ch) (0xE6790620U + 0x40U * (ch)) +#define DBSC_DBPDLK_0 0xE6790620U +#define DBSC_DBPDLK_1 0xE6790660U +#define DBSC_DBPDLK_2 0xE67906a0U +#define DBSC_DBPDLK_3 0xE67906e0U +#define DBSC_DBPDRGA(ch) (0xE6790624U + 0x40U * (ch)) +#define DBSC_DBPDRGD(ch) (0xE6790628U + 0x40U * (ch)) +#define DBSC_DBPDRGA_0 0xE6790624U +#define DBSC_DBPDRGD_0 0xE6790628U +#define DBSC_DBPDRGA_1 0xE6790664U +#define DBSC_DBPDRGD_1 0xE6790668U +#define DBSC_DBPDRGA_2 0xE67906A4U +#define DBSC_DBPDRGD_2 0xE67906A8U +#define DBSC_DBPDRGA_3 0xE67906E4U +#define DBSC_DBPDRGD_3 0xE67906E8U +#define DBSC_DBPDSTAT(ch) (0xE6790630U + 0x40U * (ch)) +#define DBSC_DBPDSTAT_0 0xE6790630U +#define DBSC_DBPDSTAT_1 0xE6790670U +#define DBSC_DBPDSTAT_2 0xE67906B0U +#define DBSC_DBPDSTAT_3 0xE67906F0U +#define DBSC_DBBUS0CNF0 0xE6790800U +#define DBSC_DBBUS0CNF1 0xE6790804U +#define DBSC_DBCAM0CNF1 0xE6790904U +#define DBSC_DBCAM0CNF2 0xE6790908U +#define DBSC_DBCAM0CNF3 0xE679090CU +#define DBSC_DBBSWAP 0xE67909F0U +#define DBSC_DBBCAMDIS 0xE67909FCU +#define DBSC_DBSCHCNT0 0xE6791000U +#define DBSC_DBSCHCNT1 0xE6791004U +#define DBSC_DBSCHSZ0 0xE6791010U +#define DBSC_DBSCHRW0 0xE6791020U +#define DBSC_DBSCHRW1 0xE6791024U +#define DBSC_DBSCHQOS_0(x) (0xE6791030U + 0x10U * (x)) +#define DBSC_DBSCHQOS_1(x) (0xE6791034U + 0x10U * (x)) +#define DBSC_DBSCHQOS_2(x) (0xE6791038U + 0x10U * (x)) +#define DBSC_DBSCHQOS_3(x) (0xE679103CU + 0x10U * (x)) +#define DBSC_DBSCHQOS00 0xE6791030U +#define DBSC_DBSCHQOS01 0xE6791034U +#define DBSC_DBSCHQOS02 0xE6791038U +#define DBSC_DBSCHQOS03 0xE679103CU +#define DBSC_DBSCHQOS10 0xE6791040U +#define DBSC_DBSCHQOS11 0xE6791044U +#define DBSC_DBSCHQOS12 0xE6791048U +#define DBSC_DBSCHQOS13 0xE679104CU +#define DBSC_DBSCHQOS20 0xE6791050U +#define DBSC_DBSCHQOS21 0xE6791054U +#define DBSC_DBSCHQOS22 0xE6791058U +#define DBSC_DBSCHQOS23 0xE679105CU +#define DBSC_DBSCHQOS30 0xE6791060U +#define DBSC_DBSCHQOS31 0xE6791064U +#define DBSC_DBSCHQOS32 0xE6791068U +#define DBSC_DBSCHQOS33 0xE679106CU +#define DBSC_DBSCHQOS40 0xE6791070U +#define DBSC_DBSCHQOS41 0xE6791074U +#define DBSC_DBSCHQOS42 0xE6791078U +#define DBSC_DBSCHQOS43 0xE679107CU +#define DBSC_DBSCHQOS50 0xE6791080U +#define DBSC_DBSCHQOS51 0xE6791084U +#define DBSC_DBSCHQOS52 0xE6791088U +#define DBSC_DBSCHQOS53 0xE679108CU +#define DBSC_DBSCHQOS60 0xE6791090U +#define DBSC_DBSCHQOS61 0xE6791094U +#define DBSC_DBSCHQOS62 0xE6791098U +#define DBSC_DBSCHQOS63 0xE679109CU +#define DBSC_DBSCHQOS70 0xE67910A0U +#define DBSC_DBSCHQOS71 0xE67910A4U +#define DBSC_DBSCHQOS72 0xE67910A8U +#define DBSC_DBSCHQOS73 0xE67910ACU +#define DBSC_DBSCHQOS80 0xE67910B0U +#define DBSC_DBSCHQOS81 0xE67910B4U +#define DBSC_DBSCHQOS82 0xE67910B8U +#define DBSC_DBSCHQOS83 0xE67910BCU +#define DBSC_DBSCHQOS90 0xE67910C0U +#define DBSC_DBSCHQOS91 0xE67910C4U +#define DBSC_DBSCHQOS92 0xE67910C8U +#define DBSC_DBSCHQOS93 0xE67910CCU +#define DBSC_DBSCHQOS100 0xE67910D0U +#define DBSC_DBSCHQOS101 0xE67910D4U +#define DBSC_DBSCHQOS102 0xE67910D8U +#define DBSC_DBSCHQOS103 0xE67910DCU +#define DBSC_DBSCHQOS110 0xE67910E0U +#define DBSC_DBSCHQOS111 0xE67910E4U +#define DBSC_DBSCHQOS112 0xE67910E8U +#define DBSC_DBSCHQOS113 0xE67910ECU +#define DBSC_DBSCHQOS120 0xE67910F0U +#define DBSC_DBSCHQOS121 0xE67910F4U +#define DBSC_DBSCHQOS122 0xE67910F8U +#define DBSC_DBSCHQOS123 0xE67910FCU +#define DBSC_DBSCHQOS130 0xE6791100U +#define DBSC_DBSCHQOS131 0xE6791104U +#define DBSC_DBSCHQOS132 0xE6791108U +#define DBSC_DBSCHQOS133 0xE679110CU +#define DBSC_DBSCHQOS140 0xE6791110U +#define DBSC_DBSCHQOS141 0xE6791114U +#define DBSC_DBSCHQOS142 0xE6791118U +#define DBSC_DBSCHQOS143 0xE679111CU +#define DBSC_DBSCHQOS150 0xE6791120U +#define DBSC_DBSCHQOS151 0xE6791124U +#define DBSC_DBSCHQOS152 0xE6791128U +#define DBSC_DBSCHQOS153 0xE679112CU +#define DBSC_DBSCTR0 0xE6791700U +#define DBSC_DBSCTR1 0xE6791708U +#define DBSC_DBSCHRW2 0xE679170CU +#define DBSC_SCFCTST01(x) (0xE6791700U + 0x08U * (x)) +#define DBSC_SCFCTST0 0xE6791700U +#define DBSC_SCFCTST1 0xE6791708U +#define DBSC_SCFCTST2 0xE679170CU +#define DBSC_DBMRRDR(chab) (0xE6791800U + 0x04U * (chab)) +#define DBSC_DBMRRDR_0 0xE6791800U +#define DBSC_DBMRRDR_1 0xE6791804U +#define DBSC_DBMRRDR_2 0xE6791808U +#define DBSC_DBMRRDR_3 0xE679180CU +#define DBSC_DBMRRDR_4 0xE6791810U +#define DBSC_DBMRRDR_5 0xE6791814U +#define DBSC_DBMRRDR_6 0xE6791818U +#define DBSC_DBMRRDR_7 0xE679181CU +#define DBSC_DBMEMSWAPCONF0 0xE6792000U + +/* CPG registers */ +#define CPG_BASE 0xE6150000U +#define CPG_FRQCRB (CPG_BASE + 0x0004U) +#define CPG_PLLECR (CPG_BASE + 0x00D0U) +#define CPG_MSTPSR5 (CPG_BASE + 0x003CU) +#define CPG_SRCR4 (CPG_BASE + 0x00BCU) +#define CPG_PLL3CR (CPG_BASE + 0x00DCU) +#define CPG_ZB3CKCR (CPG_BASE + 0x0380U) +#define CPG_FRQCRD (CPG_BASE + 0x00E4U) +#define CPG_SMSTPCR5 (CPG_BASE + 0x0144U) +#define CPG_CPGWPR (CPG_BASE + 0x0900U) +#define CPG_SRSTCLR4 (CPG_BASE + 0x0950U) + +#endif /* BOOT_INIT_DRAM_REGDEF_H_*/ diff --git a/drivers/renesas/common/pfc_regs.h b/drivers/renesas/common/pfc_regs.h new file mode 100644 index 000000000..418773366 --- /dev/null +++ b/drivers/renesas/common/pfc_regs.h @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef PFC_REGS_H +#define PFC_REGS_H + +/* GPIO base address */ +#define GPIO_BASE (0xE6050000U) + +/* GPIO registers */ +#define GPIO_IOINTSEL0 (GPIO_BASE + 0x0000U) +#define GPIO_INOUTSEL0 (GPIO_BASE + 0x0004U) +#define GPIO_OUTDT0 (GPIO_BASE + 0x0008U) +#define GPIO_INDT0 (GPIO_BASE + 0x000CU) +#define GPIO_INTDT0 (GPIO_BASE + 0x0010U) +#define GPIO_INTCLR0 (GPIO_BASE + 0x0014U) +#define GPIO_INTMSK0 (GPIO_BASE + 0x0018U) +#define GPIO_MSKCLR0 (GPIO_BASE + 0x001CU) +#define GPIO_POSNEG0 (GPIO_BASE + 0x0020U) +#define GPIO_EDGLEVEL0 (GPIO_BASE + 0x0024U) +#define GPIO_FILONOFF0 (GPIO_BASE + 0x0028U) +#define GPIO_INTMSKS0 (GPIO_BASE + 0x0038U) +#define GPIO_MSKCLRS0 (GPIO_BASE + 0x003CU) +#define GPIO_OUTDTSEL0 (GPIO_BASE + 0x0040U) +#define GPIO_OUTDTH0 (GPIO_BASE + 0x0044U) +#define GPIO_OUTDTL0 (GPIO_BASE + 0x0048U) +#define GPIO_BOTHEDGE0 (GPIO_BASE + 0x004CU) +#define GPIO_IOINTSEL1 (GPIO_BASE + 0x1000U) +#define GPIO_INOUTSEL1 (GPIO_BASE + 0x1004U) +#define GPIO_OUTDT1 (GPIO_BASE + 0x1008U) +#define GPIO_INDT1 (GPIO_BASE + 0x100CU) +#define GPIO_INTDT1 (GPIO_BASE + 0x1010U) +#define GPIO_INTCLR1 (GPIO_BASE + 0x1014U) +#define GPIO_INTMSK1 (GPIO_BASE + 0x1018U) +#define GPIO_MSKCLR1 (GPIO_BASE + 0x101CU) +#define GPIO_POSNEG1 (GPIO_BASE + 0x1020U) +#define GPIO_EDGLEVEL1 (GPIO_BASE + 0x1024U) +#define GPIO_FILONOFF1 (GPIO_BASE + 0x1028U) +#define GPIO_INTMSKS1 (GPIO_BASE + 0x1038U) +#define GPIO_MSKCLRS1 (GPIO_BASE + 0x103CU) +#define GPIO_OUTDTSEL1 (GPIO_BASE + 0x1040U) +#define GPIO_OUTDTH1 (GPIO_BASE + 0x1044U) +#define GPIO_OUTDTL1 (GPIO_BASE + 0x1048U) +#define GPIO_BOTHEDGE1 (GPIO_BASE + 0x104CU) +#define GPIO_IOINTSEL2 (GPIO_BASE + 0x2000U) +#define GPIO_INOUTSEL2 (GPIO_BASE + 0x2004U) +#define GPIO_OUTDT2 (GPIO_BASE + 0x2008U) +#define GPIO_INDT2 (GPIO_BASE + 0x200CU) +#define GPIO_INTDT2 (GPIO_BASE + 0x2010U) +#define GPIO_INTCLR2 (GPIO_BASE + 0x2014U) +#define GPIO_INTMSK2 (GPIO_BASE + 0x2018U) +#define GPIO_MSKCLR2 (GPIO_BASE + 0x201CU) +#define GPIO_POSNEG2 (GPIO_BASE + 0x2020U) +#define GPIO_EDGLEVEL2 (GPIO_BASE + 0x2024U) +#define GPIO_FILONOFF2 (GPIO_BASE + 0x2028U) +#define GPIO_INTMSKS2 (GPIO_BASE + 0x2038U) +#define GPIO_MSKCLRS2 (GPIO_BASE + 0x203CU) +#define GPIO_OUTDTSEL2 (GPIO_BASE + 0x2040U) +#define GPIO_OUTDTH2 (GPIO_BASE + 0x2044U) +#define GPIO_OUTDTL2 (GPIO_BASE + 0x2048U) +#define GPIO_BOTHEDGE2 (GPIO_BASE + 0x204CU) +#define GPIO_IOINTSEL3 (GPIO_BASE + 0x3000U) +#define GPIO_INOUTSEL3 (GPIO_BASE + 0x3004U) +#define GPIO_OUTDT3 (GPIO_BASE + 0x3008U) +#define GPIO_INDT3 (GPIO_BASE + 0x300CU) +#define GPIO_INTDT3 (GPIO_BASE + 0x3010U) +#define GPIO_INTCLR3 (GPIO_BASE + 0x3014U) +#define GPIO_INTMSK3 (GPIO_BASE + 0x3018U) +#define GPIO_MSKCLR3 (GPIO_BASE + 0x301CU) +#define GPIO_POSNEG3 (GPIO_BASE + 0x3020U) +#define GPIO_EDGLEVEL3 (GPIO_BASE + 0x3024U) +#define GPIO_FILONOFF3 (GPIO_BASE + 0x3028U) +#define GPIO_INTMSKS3 (GPIO_BASE + 0x3038U) +#define GPIO_MSKCLRS3 (GPIO_BASE + 0x303CU) +#define GPIO_OUTDTSEL3 (GPIO_BASE + 0x3040U) +#define GPIO_OUTDTH3 (GPIO_BASE + 0x3044U) +#define GPIO_OUTDTL3 (GPIO_BASE + 0x3048U) +#define GPIO_BOTHEDGE3 (GPIO_BASE + 0x304CU) +#define GPIO_IOINTSEL4 (GPIO_BASE + 0x4000U) +#define GPIO_INOUTSEL4 (GPIO_BASE + 0x4004U) +#define GPIO_OUTDT4 (GPIO_BASE + 0x4008U) +#define GPIO_INDT4 (GPIO_BASE + 0x400CU) +#define GPIO_INTDT4 (GPIO_BASE + 0x4010U) +#define GPIO_INTCLR4 (GPIO_BASE + 0x4014U) +#define GPIO_INTMSK4 (GPIO_BASE + 0x4018U) +#define GPIO_MSKCLR4 (GPIO_BASE + 0x401CU) +#define GPIO_POSNEG4 (GPIO_BASE + 0x4020U) +#define GPIO_EDGLEVEL4 (GPIO_BASE + 0x4024U) +#define GPIO_FILONOFF4 (GPIO_BASE + 0x4028U) +#define GPIO_INTMSKS4 (GPIO_BASE + 0x4038U) +#define GPIO_MSKCLRS4 (GPIO_BASE + 0x403CU) +#define GPIO_OUTDTSEL4 (GPIO_BASE + 0x4040U) +#define GPIO_OUTDTH4 (GPIO_BASE + 0x4044U) +#define GPIO_OUTDTL4 (GPIO_BASE + 0x4048U) +#define GPIO_BOTHEDGE4 (GPIO_BASE + 0x404CU) +#define GPIO_IOINTSEL5 (GPIO_BASE + 0x5000U) +#define GPIO_INOUTSEL5 (GPIO_BASE + 0x5004U) +#define GPIO_OUTDT5 (GPIO_BASE + 0x5008U) +#define GPIO_INDT5 (GPIO_BASE + 0x500CU) +#define GPIO_INTDT5 (GPIO_BASE + 0x5010U) +#define GPIO_INTCLR5 (GPIO_BASE + 0x5014U) +#define GPIO_INTMSK5 (GPIO_BASE + 0x5018U) +#define GPIO_MSKCLR5 (GPIO_BASE + 0x501CU) +#define GPIO_POSNEG5 (GPIO_BASE + 0x5020U) +#define GPIO_EDGLEVEL5 (GPIO_BASE + 0x5024U) +#define GPIO_FILONOFF5 (GPIO_BASE + 0x5028U) +#define GPIO_INTMSKS5 (GPIO_BASE + 0x5038U) +#define GPIO_MSKCLRS5 (GPIO_BASE + 0x503CU) +#define GPIO_OUTDTSEL5 (GPIO_BASE + 0x5040U) +#define GPIO_OUTDTH5 (GPIO_BASE + 0x5044U) +#define GPIO_OUTDTL5 (GPIO_BASE + 0x5048U) +#define GPIO_BOTHEDGE5 (GPIO_BASE + 0x504CU) +#define GPIO_IOINTSEL6 (GPIO_BASE + 0x5400U) +#define GPIO_INOUTSEL6 (GPIO_BASE + 0x5404U) +#define GPIO_OUTDT6 (GPIO_BASE + 0x5408U) +#define GPIO_INTDT6 (GPIO_BASE + 0x5410U) +#define GPIO_INTCLR6 (GPIO_BASE + 0x5414U) +#define GPIO_INTMSK6 (GPIO_BASE + 0x5418U) +#define GPIO_MSKCLR6 (GPIO_BASE + 0x541CU) +#define GPIO_POSNEG6 (GPIO_BASE + 0x5420U) +#define GPIO_EDGLEVEL6 (GPIO_BASE + 0x5424U) +#define GPIO_FILONOFF6 (GPIO_BASE + 0x5428U) +#define GPIO_INTMSKS6 (GPIO_BASE + 0x5438U) +#define GPIO_MSKCLRS6 (GPIO_BASE + 0x543CU) +#define GPIO_OUTDTSEL6 (GPIO_BASE + 0x5440U) +#define GPIO_OUTDTH6 (GPIO_BASE + 0x5444U) +#define GPIO_OUTDTL6 (GPIO_BASE + 0x5448U) +#define GPIO_BOTHEDGE6 (GPIO_BASE + 0x544CU) +#define GPIO_IOINTSEL7 (GPIO_BASE + 0x5800U) +#define GPIO_INOUTSEL7 (GPIO_BASE + 0x5804U) +#define GPIO_OUTDT7 (GPIO_BASE + 0x5808U) +#define GPIO_INDT7 (GPIO_BASE + 0x580CU) +#define GPIO_INTDT7 (GPIO_BASE + 0x5810U) +#define GPIO_INTCLR7 (GPIO_BASE + 0x5814U) +#define GPIO_INTMSK7 (GPIO_BASE + 0x5818U) +#define GPIO_MSKCLR7 (GPIO_BASE + 0x581CU) +#define GPIO_POSNEG7 (GPIO_BASE + 0x5820U) +#define GPIO_EDGLEVEL7 (GPIO_BASE + 0x5824U) +#define GPIO_FILONOFF7 (GPIO_BASE + 0x5828U) +#define GPIO_INTMSKS7 (GPIO_BASE + 0x5838U) +#define GPIO_MSKCLRS7 (GPIO_BASE + 0x583CU) +#define GPIO_OUTDTSEL7 (GPIO_BASE + 0x5840U) +#define GPIO_OUTDTH7 (GPIO_BASE + 0x5844U) +#define GPIO_OUTDTL7 (GPIO_BASE + 0x5848U) +#define GPIO_BOTHEDGE7 (GPIO_BASE + 0x584CU) + +/* Pin functon base address */ +#define PFC_BASE (0xE6060000U) + +/* Pin functon registers */ +#define PFC_PMMR (PFC_BASE + 0x0000U) +#define PFC_GPSR0 (PFC_BASE + 0x0100U) +#define PFC_GPSR1 (PFC_BASE + 0x0104U) +#define PFC_GPSR2 (PFC_BASE + 0x0108U) +#define PFC_GPSR3 (PFC_BASE + 0x010CU) +#define PFC_GPSR4 (PFC_BASE + 0x0110U) +#define PFC_GPSR5 (PFC_BASE + 0x0114U) +#define PFC_GPSR6 (PFC_BASE + 0x0118U) +#define PFC_GPSR7 (PFC_BASE + 0x011CU) +#define PFC_IPSR0 (PFC_BASE + 0x0200U) +#define PFC_IPSR1 (PFC_BASE + 0x0204U) +#define PFC_IPSR2 (PFC_BASE + 0x0208U) +#define PFC_IPSR3 (PFC_BASE + 0x020CU) +#define PFC_IPSR4 (PFC_BASE + 0x0210U) +#define PFC_IPSR5 (PFC_BASE + 0x0214U) +#define PFC_IPSR6 (PFC_BASE + 0x0218U) +#define PFC_IPSR7 (PFC_BASE + 0x021CU) +#define PFC_IPSR8 (PFC_BASE + 0x0220U) +#define PFC_IPSR9 (PFC_BASE + 0x0224U) +#define PFC_IPSR10 (PFC_BASE + 0x0228U) +#define PFC_IPSR11 (PFC_BASE + 0x022CU) +#define PFC_IPSR12 (PFC_BASE + 0x0230U) +#define PFC_IPSR13 (PFC_BASE + 0x0234U) +#define PFC_IPSR14 (PFC_BASE + 0x0238U) +#define PFC_IPSR15 (PFC_BASE + 0x023CU) +#define PFC_IPSR16 (PFC_BASE + 0x0240U) +#define PFC_IPSR17 (PFC_BASE + 0x0244U) +#define PFC_IPSR18 (PFC_BASE + 0x0248U) +#define PFC_DRVCTRL0 (PFC_BASE + 0x0300U) +#define PFC_DRVCTRL1 (PFC_BASE + 0x0304U) +#define PFC_DRVCTRL2 (PFC_BASE + 0x0308U) +#define PFC_DRVCTRL3 (PFC_BASE + 0x030CU) +#define PFC_DRVCTRL4 (PFC_BASE + 0x0310U) +#define PFC_DRVCTRL5 (PFC_BASE + 0x0314U) +#define PFC_DRVCTRL6 (PFC_BASE + 0x0318U) +#define PFC_DRVCTRL7 (PFC_BASE + 0x031CU) +#define PFC_DRVCTRL8 (PFC_BASE + 0x0320U) +#define PFC_DRVCTRL9 (PFC_BASE + 0x0324U) +#define PFC_DRVCTRL10 (PFC_BASE + 0x0328U) +#define PFC_DRVCTRL11 (PFC_BASE + 0x032CU) +#define PFC_DRVCTRL12 (PFC_BASE + 0x0330U) +#define PFC_DRVCTRL13 (PFC_BASE + 0x0334U) +#define PFC_DRVCTRL14 (PFC_BASE + 0x0338U) +#define PFC_DRVCTRL15 (PFC_BASE + 0x033CU) +#define PFC_DRVCTRL16 (PFC_BASE + 0x0340U) +#define PFC_DRVCTRL17 (PFC_BASE + 0x0344U) +#define PFC_DRVCTRL18 (PFC_BASE + 0x0348U) +#define PFC_DRVCTRL19 (PFC_BASE + 0x034CU) +#define PFC_DRVCTRL20 (PFC_BASE + 0x0350U) +#define PFC_DRVCTRL21 (PFC_BASE + 0x0354U) +#define PFC_DRVCTRL22 (PFC_BASE + 0x0358U) +#define PFC_DRVCTRL23 (PFC_BASE + 0x035CU) +#define PFC_DRVCTRL24 (PFC_BASE + 0x0360U) +#define PFC_POCCTRL0 (PFC_BASE + 0x0380U) +#define PFC_IOCTRL31 (PFC_BASE + 0x0384U) +#define PFC_POCCTRL2 (PFC_BASE + 0x0388U) +#define PFC_TDSELCTRL0 (PFC_BASE + 0x03C0U) +#define PFC_IOCTRL (PFC_BASE + 0x03E0U) +#define PFC_TSREG (PFC_BASE + 0x03E4U) +#define PFC_PUEN0 (PFC_BASE + 0x0400U) +#define PFC_PUEN1 (PFC_BASE + 0x0404U) +#define PFC_PUEN2 (PFC_BASE + 0x0408U) +#define PFC_PUEN3 (PFC_BASE + 0x040CU) +#define PFC_PUEN4 (PFC_BASE + 0x0410U) +#define PFC_PUEN5 (PFC_BASE + 0x0414U) +#define PFC_PUEN6 (PFC_BASE + 0x0418U) +#define PFC_PUD0 (PFC_BASE + 0x0440U) +#define PFC_PUD1 (PFC_BASE + 0x0444U) +#define PFC_PUD2 (PFC_BASE + 0x0448U) +#define PFC_PUD3 (PFC_BASE + 0x044CU) +#define PFC_PUD4 (PFC_BASE + 0x0450U) +#define PFC_PUD5 (PFC_BASE + 0x0454U) +#define PFC_PUD6 (PFC_BASE + 0x0458U) +#define PFC_MOD_SEL0 (PFC_BASE + 0x0500U) +#define PFC_MOD_SEL1 (PFC_BASE + 0x0504U) +#define PFC_MOD_SEL2 (PFC_BASE + 0x0508U) + +#endif /* PFC_REGS_H */ diff --git a/drivers/renesas/common/qos_reg.h b/drivers/renesas/common/qos_reg.h new file mode 100644 index 000000000..f2012fa45 --- /dev/null +++ b/drivers/renesas/common/qos_reg.h @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2017-2019, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QOS_REG_H +#define QOS_REG_H + +#define RCAR_QOS_NONE 3U +#define RCAR_QOS_TYPE_DEFAULT 0U + +#define RCAR_DRAM_SPLIT_LINEAR 0U +#define RCAR_DRAM_SPLIT_4CH 1U +#define RCAR_DRAM_SPLIT_2CH 2U +#define RCAR_DRAM_SPLIT_AUTO 3U +#define RST_BASE (0xE6160000U) +#define RST_MODEMR (RST_BASE + 0x0060U) + +#define DBSC_BASE 0xE6790000U +#define DBSC_DBSYSCNT0 (DBSC_BASE + 0x0100U) +#define DBSC_AXARB (DBSC_BASE + 0x0800U) +#define DBSC_DBCAM0CNF1 (DBSC_BASE + 0x0904U) +#define DBSC_DBCAM0CNF2 (DBSC_BASE + 0x0908U) +#define DBSC_DBCAM0CNF3 (DBSC_BASE + 0x090CU) +#define DBSC_DBSCHCNT0 (DBSC_BASE + 0x1000U) +#define DBSC_DBSCHCNT1 (DBSC_BASE + 0x1004U) +#define DBSC_DBSCHSZ0 (DBSC_BASE + 0x1010U) +#define DBSC_DBSCHRW0 (DBSC_BASE + 0x1020U) +#define DBSC_DBSCHRW1 (DBSC_BASE + 0x1024U) +#define DBSC_DBSCHQOS00 (DBSC_BASE + 0x1030U) +#define DBSC_DBSCHQOS01 (DBSC_BASE + 0x1034U) +#define DBSC_DBSCHQOS02 (DBSC_BASE + 0x1038U) +#define DBSC_DBSCHQOS03 (DBSC_BASE + 0x103CU) +#define DBSC_DBSCHQOS40 (DBSC_BASE + 0x1070U) +#define DBSC_DBSCHQOS41 (DBSC_BASE + 0x1074U) +#define DBSC_DBSCHQOS42 (DBSC_BASE + 0x1078U) +#define DBSC_DBSCHQOS43 (DBSC_BASE + 0x107CU) +#define DBSC_DBSCHQOS90 (DBSC_BASE + 0x10C0U) +#define DBSC_DBSCHQOS91 (DBSC_BASE + 0x10C4U) +#define DBSC_DBSCHQOS92 (DBSC_BASE + 0x10C8U) +#define DBSC_DBSCHQOS93 (DBSC_BASE + 0x10CCU) +#define DBSC_DBSCHQOS120 (DBSC_BASE + 0x10F0U) +#define DBSC_DBSCHQOS121 (DBSC_BASE + 0x10F4U) +#define DBSC_DBSCHQOS122 (DBSC_BASE + 0x10F8U) +#define DBSC_DBSCHQOS123 (DBSC_BASE + 0x10FCU) +#define DBSC_DBSCHQOS130 (DBSC_BASE + 0x1100U) +#define DBSC_DBSCHQOS131 (DBSC_BASE + 0x1104U) +#define DBSC_DBSCHQOS132 (DBSC_BASE + 0x1108U) +#define DBSC_DBSCHQOS133 (DBSC_BASE + 0x110CU) +#define DBSC_DBSCHQOS140 (DBSC_BASE + 0x1110U) +#define DBSC_DBSCHQOS141 (DBSC_BASE + 0x1114U) +#define DBSC_DBSCHQOS142 (DBSC_BASE + 0x1118U) +#define DBSC_DBSCHQOS143 (DBSC_BASE + 0x111CU) +#define DBSC_DBSCHQOS150 (DBSC_BASE + 0x1120U) +#define DBSC_DBSCHQOS151 (DBSC_BASE + 0x1124U) +#define DBSC_DBSCHQOS152 (DBSC_BASE + 0x1128U) +#define DBSC_DBSCHQOS153 (DBSC_BASE + 0x112CU) +#define DBSC_SCFCTST0 (DBSC_BASE + 0x1700U) +#define DBSC_SCFCTST1 (DBSC_BASE + 0x1708U) +#define DBSC_SCFCTST2 (DBSC_BASE + 0x170CU) + +#define AXI_BASE 0xE6784000U +#define AXI_ADSPLCR0 (AXI_BASE + 0x0008U) +#define AXI_ADSPLCR1 (AXI_BASE + 0x000CU) +#define AXI_ADSPLCR2 (AXI_BASE + 0x0010U) +#define AXI_ADSPLCR3 (AXI_BASE + 0x0014U) +#define AXI_MMCR (AXI_BASE + 0x0300U) +#define ADSPLCR0_ADRMODE_DEFAULT ((uint32_t)0U << 31U) +#define ADSPLCR0_ADRMODE_GEN2 ((uint32_t)1U << 31U) +#define ADSPLCR0_SPLITSEL(x) ((uint32_t)(x) << 16U) +#define ADSPLCR0_AREA(x) ((uint32_t)(x) << 8U) +#define ADSPLCR0_SWP 0x0CU + +#define AXI_TR3CR 0xE67D100CU +#define AXI_TR4CR 0xE67D1014U + +#define QOS_BASE0 0xE67E0000U +#define QOSBW_FIX_QOS_BANK0 (QOS_BASE0 + 0x0000U) +#define QOSBW_FIX_QOS_BANK1 (QOS_BASE0 + 0x1000U) +#define QOSBW_BE_QOS_BANK0 (QOS_BASE0 + 0x2000U) +#define QOSBW_BE_QOS_BANK1 (QOS_BASE0 + 0x3000U) +#define QOSCTRL_SL_INIT (QOS_BASE0 + 0x8000U) +#define QOSCTRL_REF_ARS (QOS_BASE0 + 0x8004U) +#define QOSCTRL_STATQC (QOS_BASE0 + 0x8008U) + +#define QOS_BASE1 0xE67F0000U +#define QOSCTRL_RAS (QOS_BASE1 + 0x0000U) +#define QOSCTRL_FIXTH (QOS_BASE1 + 0x0004U) +#define QOSCTRL_RAEN (QOS_BASE1 + 0x0018U) +#define QOSCTRL_REGGD (QOS_BASE1 + 0x0020U) +#define QOSCTRL_DANN (QOS_BASE1 + 0x0030U) +#define QOSCTRL_DANT (QOS_BASE1 + 0x0038U) +#define QOSCTRL_EC (QOS_BASE1 + 0x003CU) +#define QOSCTRL_EMS (QOS_BASE1 + 0x0040U) +#define QOSCTRL_FSS (QOS_BASE1 + 0x0048U) +#define QOSCTRL_INSFC (QOS_BASE1 + 0x0050U) +#define QOSCTRL_BERR (QOS_BASE1 + 0x0054U) +#define QOSCTRL_EARLYR (QOS_BASE1 + 0x0060U) +#define QOSCTRL_RACNT0 (QOS_BASE1 + 0x0080U) +#define QOSCTRL_STATGEN0 (QOS_BASE1 + 0x0088U) + +#define GPU_ACT_GRD 0xFD820808U +#define GPU_ACT0 0xFD820800U +#define GPU_ACT1 0xFD821800U +#define GPU_ACT2 0xFD822800U +#define GPU_ACT3 0xFD823800U +#define GPU_ACT4 0xFD824800U +#define GPU_ACT5 0xFD825800U +#define GPU_ACT6 0xFD826800U +#define GPU_ACT7 0xFD827800U + +#define RT_ACT0 0xFFC50800U +#define RT_ACT1 0xFFC51800U + +#define CPU_ACT0 0xF1300800U +#define CPU_ACT1 0xF1340800U +#define CPU_ACT2 0xF1380800U +#define CPU_ACT3 0xF13C0800U + +#define RCAR_REWT_TRAINING_DISABLE 0U +#define RCAR_REWT_TRAINING_ENABLE 1U + +#define QOSWT_FIX_WTQOS_BANK0 (QOSBW_FIX_QOS_BANK0 + 0x0800U) +#define QOSWT_FIX_WTQOS_BANK1 (QOSBW_FIX_QOS_BANK1 + 0x0800U) +#define QOSWT_BE_WTQOS_BANK0 (QOSBW_BE_QOS_BANK0 + 0x0800U) +#define QOSWT_BE_WTQOS_BANK1 (QOSBW_BE_QOS_BANK1 + 0x0800U) +#define QOSWT_WTEN (QOS_BASE0 + 0x8030U) +#define QOSWT_WTREF (QOS_BASE0 + 0x8034U) +#define QOSWT_WTSET0 (QOS_BASE0 + 0x8038U) +#define QOSWT_WTSET1 (QOS_BASE0 + 0x803CU) + +#endif /* QOS_REG_H */ diff --git a/drivers/renesas/rcar/ddr/ddr_regs.h b/drivers/renesas/rcar/ddr/ddr_regs.h deleted file mode 100644 index ba26c69c8..000000000 --- a/drivers/renesas/rcar/ddr/ddr_regs.h +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright (c) 2015-2019, Renesas Electronics Corporation - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef BOOT_INIT_DRAM_REGDEF_H_ -#define BOOT_INIT_DRAM_REGDEF_H_ - -/* DBSC registers */ -#define DBSC_DBSYSCONF0 0xE6790000U -#define DBSC_DBSYSCONF1 0xE6790004U -#define DBSC_DBPHYCONF0 0xE6790010U -#define DBSC_DBKIND 0xE6790020U -#define DBSC_DBMEMCONF(ch, cs) (0xE6790030U + 0x10U * (ch) + 0x04U * (cs)) -#define DBSC_DBMEMCONF_0_0 0xE6790030U -#define DBSC_DBMEMCONF_0_1 0xE6790034U -#define DBSC_DBMEMCONF_0_2 0xE6790038U -#define DBSC_DBMEMCONF_0_3 0xE679003CU -#define DBSC_DBMEMCONF_1_2 0xE6790048U -#define DBSC_DBMEMCONF_1_3 0xE679004CU -#define DBSC_DBMEMCONF_1_0 0xE6790040U -#define DBSC_DBMEMCONF_1_1 0xE6790044U -#define DBSC_DBMEMCONF_2_0 0xE6790050U -#define DBSC_DBMEMCONF_2_1 0xE6790054U -#define DBSC_DBMEMCONF_2_2 0xE6790058U -#define DBSC_DBMEMCONF_2_3 0xE679005CU -#define DBSC_DBMEMCONF_3_0 0xE6790060U -#define DBSC_DBMEMCONF_3_1 0xE6790064U -#define DBSC_DBMEMCONF_3_2 0xE6790068U -#define DBSC_DBMEMCONF_3_3 0xE679006CU -#define DBSC_DBSYSCNT0 0xE6790100U -#define DBSC_DBSVCR1 0xE6790104U -#define DBSC_DBSTATE0 0xE6790108U -#define DBSC_DBSTATE1 0xE679010CU -#define DBSC_DBINTEN 0xE6790180U -#define DBSC_DBINTSTAT0 0xE6790184U -#define DBSC_DBACEN 0xE6790200U -#define DBSC_DBRFEN 0xE6790204U -#define DBSC_DBCMD 0xE6790208U -#define DBSC_DBWAIT 0xE6790210U -#define DBSC_DBSYSCTRL0 0xE6790280U -#define DBSC_DBTR(x) (0xE6790300U + 0x04U * (x)) -#define DBSC_DBTR0 0xE6790300U -#define DBSC_DBTR1 0xE6790304U -#define DBSC_DBTR2 0xE6790308U -#define DBSC_DBTR3 0xE679030CU -#define DBSC_DBTR4 0xE6790310U -#define DBSC_DBTR5 0xE6790314U -#define DBSC_DBTR6 0xE6790318U -#define DBSC_DBTR7 0xE679031CU -#define DBSC_DBTR8 0xE6790320U -#define DBSC_DBTR9 0xE6790324U -#define DBSC_DBTR10 0xE6790328U -#define DBSC_DBTR11 0xE679032CU -#define DBSC_DBTR12 0xE6790330U -#define DBSC_DBTR13 0xE6790334U -#define DBSC_DBTR14 0xE6790338U -#define DBSC_DBTR15 0xE679033CU -#define DBSC_DBTR16 0xE6790340U -#define DBSC_DBTR17 0xE6790344U -#define DBSC_DBTR18 0xE6790348U -#define DBSC_DBTR19 0xE679034CU -#define DBSC_DBTR20 0xE6790350U -#define DBSC_DBTR21 0xE6790354U -#define DBSC_DBTR22 0xE6790358U -#define DBSC_DBTR23 0xE679035CU -#define DBSC_DBTR24 0xE6790360U -#define DBSC_DBTR25 0xE6790364U -#define DBSC_DBTR26 0xE6790368U -#define DBSC_DBBL 0xE6790400U -#define DBSC_DBRFCNF1 0xE6790414U -#define DBSC_DBRFCNF2 0xE6790418U -#define DBSC_DBTSPCNF 0xE6790420U -#define DBSC_DBCALCNF 0xE6790424U -#define DBSC_DBRNK(x) (0xE6790430U + 0x04U * (x)) -#define DBSC_DBRNK2 0xE6790438U -#define DBSC_DBRNK3 0xE679043CU -#define DBSC_DBRNK4 0xE6790440U -#define DBSC_DBRNK5 0xE6790444U -#define DBSC_DBPDNCNF 0xE6790450U -#define DBSC_DBODT(x) (0xE6790460U + 0x04U * (x)) -#define DBSC_DBODT0 0xE6790460U -#define DBSC_DBODT1 0xE6790464U -#define DBSC_DBODT2 0xE6790468U -#define DBSC_DBODT3 0xE679046CU -#define DBSC_DBODT4 0xE6790470U -#define DBSC_DBODT5 0xE6790474U -#define DBSC_DBODT6 0xE6790478U -#define DBSC_DBODT7 0xE679047CU -#define DBSC_DBADJ0 0xE6790500U -#define DBSC_DBDBICNT 0xE6790518U -#define DBSC_DBDFIPMSTRCNF 0xE6790520U -#define DBSC_DBDFICUPDCNF 0xE679052CU -#define DBSC_DBDFISTAT(ch) (0xE6790600U + 0x40U * (ch)) -#define DBSC_DBDFISTAT_0 0xE6790600U -#define DBSC_DBDFISTAT_1 0xE6790640U -#define DBSC_DBDFISTAT_2 0xE6790680U -#define DBSC_DBDFISTAT_3 0xE67906C0U -#define DBSC_DBDFICNT(ch) (0xE6790604U + 0x40U * (ch)) -#define DBSC_DBDFICNT_0 0xE6790604U -#define DBSC_DBDFICNT_1 0xE6790644U -#define DBSC_DBDFICNT_2 0xE6790684U -#define DBSC_DBDFICNT_3 0xE67906C4U -#define DBSC_DBPDCNT0(ch) (0xE6790610U + 0x40U * (ch)) -#define DBSC_DBPDCNT0_0 0xE6790610U -#define DBSC_DBPDCNT0_1 0xE6790650U -#define DBSC_DBPDCNT0_2 0xE6790690U -#define DBSC_DBPDCNT0_3 0xE67906D0U -#define DBSC_DBPDCNT1(ch) (0xE6790614U + 0x40U * (ch)) -#define DBSC_DBPDCNT1_0 0xE6790614U -#define DBSC_DBPDCNT1_1 0xE6790654U -#define DBSC_DBPDCNT1_2 0xE6790694U -#define DBSC_DBPDCNT1_3 0xE67906D4U -#define DBSC_DBPDCNT2(ch) (0xE6790618U + 0x40U * (ch)) -#define DBSC_DBPDCNT2_0 0xE6790618U -#define DBSC_DBPDCNT2_1 0xE6790658U -#define DBSC_DBPDCNT2_2 0xE6790698U -#define DBSC_DBPDCNT2_3 0xE67906D8U -#define DBSC_DBPDCNT3(ch) (0xE679061CU + 0x40U * (ch)) -#define DBSC_DBPDCNT3_0 0xE679061CU -#define DBSC_DBPDCNT3_1 0xE679065CU -#define DBSC_DBPDCNT3_2 0xE679069CU -#define DBSC_DBPDCNT3_3 0xE67906DCU -#define DBSC_DBPDLK(ch) (0xE6790620U + 0x40U * (ch)) -#define DBSC_DBPDLK_0 0xE6790620U -#define DBSC_DBPDLK_1 0xE6790660U -#define DBSC_DBPDLK_2 0xE67906a0U -#define DBSC_DBPDLK_3 0xE67906e0U -#define DBSC_DBPDRGA(ch) (0xE6790624U + 0x40U * (ch)) -#define DBSC_DBPDRGD(ch) (0xE6790628U + 0x40U * (ch)) -#define DBSC_DBPDRGA_0 0xE6790624U -#define DBSC_DBPDRGD_0 0xE6790628U -#define DBSC_DBPDRGA_1 0xE6790664U -#define DBSC_DBPDRGD_1 0xE6790668U -#define DBSC_DBPDRGA_2 0xE67906A4U -#define DBSC_DBPDRGD_2 0xE67906A8U -#define DBSC_DBPDRGA_3 0xE67906E4U -#define DBSC_DBPDRGD_3 0xE67906E8U -#define DBSC_DBPDSTAT(ch) (0xE6790630U + 0x40U * (ch)) -#define DBSC_DBPDSTAT_0 0xE6790630U -#define DBSC_DBPDSTAT_1 0xE6790670U -#define DBSC_DBPDSTAT_2 0xE67906B0U -#define DBSC_DBPDSTAT_3 0xE67906F0U -#define DBSC_DBBUS0CNF0 0xE6790800U -#define DBSC_DBBUS0CNF1 0xE6790804U -#define DBSC_DBCAM0CNF1 0xE6790904U -#define DBSC_DBCAM0CNF2 0xE6790908U -#define DBSC_DBCAM0CNF3 0xE679090CU -#define DBSC_DBBSWAP 0xE67909F0U -#define DBSC_DBBCAMDIS 0xE67909FCU -#define DBSC_DBSCHCNT0 0xE6791000U -#define DBSC_DBSCHCNT1 0xE6791004U -#define DBSC_DBSCHSZ0 0xE6791010U -#define DBSC_DBSCHRW0 0xE6791020U -#define DBSC_DBSCHRW1 0xE6791024U -#define DBSC_DBSCHQOS_0(x) (0xE6791030U + 0x10U * (x)) -#define DBSC_DBSCHQOS_1(x) (0xE6791034U + 0x10U * (x)) -#define DBSC_DBSCHQOS_2(x) (0xE6791038U + 0x10U * (x)) -#define DBSC_DBSCHQOS_3(x) (0xE679103CU + 0x10U * (x)) -#define DBSC_DBSCHQOS00 0xE6791030U -#define DBSC_DBSCHQOS01 0xE6791034U -#define DBSC_DBSCHQOS02 0xE6791038U -#define DBSC_DBSCHQOS03 0xE679103CU -#define DBSC_DBSCHQOS10 0xE6791040U -#define DBSC_DBSCHQOS11 0xE6791044U -#define DBSC_DBSCHQOS12 0xE6791048U -#define DBSC_DBSCHQOS13 0xE679104CU -#define DBSC_DBSCHQOS20 0xE6791050U -#define DBSC_DBSCHQOS21 0xE6791054U -#define DBSC_DBSCHQOS22 0xE6791058U -#define DBSC_DBSCHQOS23 0xE679105CU -#define DBSC_DBSCHQOS30 0xE6791060U -#define DBSC_DBSCHQOS31 0xE6791064U -#define DBSC_DBSCHQOS32 0xE6791068U -#define DBSC_DBSCHQOS33 0xE679106CU -#define DBSC_DBSCHQOS40 0xE6791070U -#define DBSC_DBSCHQOS41 0xE6791074U -#define DBSC_DBSCHQOS42 0xE6791078U -#define DBSC_DBSCHQOS43 0xE679107CU -#define DBSC_DBSCHQOS50 0xE6791080U -#define DBSC_DBSCHQOS51 0xE6791084U -#define DBSC_DBSCHQOS52 0xE6791088U -#define DBSC_DBSCHQOS53 0xE679108CU -#define DBSC_DBSCHQOS60 0xE6791090U -#define DBSC_DBSCHQOS61 0xE6791094U -#define DBSC_DBSCHQOS62 0xE6791098U -#define DBSC_DBSCHQOS63 0xE679109CU -#define DBSC_DBSCHQOS70 0xE67910A0U -#define DBSC_DBSCHQOS71 0xE67910A4U -#define DBSC_DBSCHQOS72 0xE67910A8U -#define DBSC_DBSCHQOS73 0xE67910ACU -#define DBSC_DBSCHQOS80 0xE67910B0U -#define DBSC_DBSCHQOS81 0xE67910B4U -#define DBSC_DBSCHQOS82 0xE67910B8U -#define DBSC_DBSCHQOS83 0xE67910BCU -#define DBSC_DBSCHQOS90 0xE67910C0U -#define DBSC_DBSCHQOS91 0xE67910C4U -#define DBSC_DBSCHQOS92 0xE67910C8U -#define DBSC_DBSCHQOS93 0xE67910CCU -#define DBSC_DBSCHQOS100 0xE67910D0U -#define DBSC_DBSCHQOS101 0xE67910D4U -#define DBSC_DBSCHQOS102 0xE67910D8U -#define DBSC_DBSCHQOS103 0xE67910DCU -#define DBSC_DBSCHQOS110 0xE67910E0U -#define DBSC_DBSCHQOS111 0xE67910E4U -#define DBSC_DBSCHQOS112 0xE67910E8U -#define DBSC_DBSCHQOS113 0xE67910ECU -#define DBSC_DBSCHQOS120 0xE67910F0U -#define DBSC_DBSCHQOS121 0xE67910F4U -#define DBSC_DBSCHQOS122 0xE67910F8U -#define DBSC_DBSCHQOS123 0xE67910FCU -#define DBSC_DBSCHQOS130 0xE6791100U -#define DBSC_DBSCHQOS131 0xE6791104U -#define DBSC_DBSCHQOS132 0xE6791108U -#define DBSC_DBSCHQOS133 0xE679110CU -#define DBSC_DBSCHQOS140 0xE6791110U -#define DBSC_DBSCHQOS141 0xE6791114U -#define DBSC_DBSCHQOS142 0xE6791118U -#define DBSC_DBSCHQOS143 0xE679111CU -#define DBSC_DBSCHQOS150 0xE6791120U -#define DBSC_DBSCHQOS151 0xE6791124U -#define DBSC_DBSCHQOS152 0xE6791128U -#define DBSC_DBSCHQOS153 0xE679112CU -#define DBSC_DBSCTR0 0xE6791700U -#define DBSC_DBSCTR1 0xE6791708U -#define DBSC_DBSCHRW2 0xE679170CU -#define DBSC_SCFCTST01(x) (0xE6791700U + 0x08U * (x)) -#define DBSC_SCFCTST0 0xE6791700U -#define DBSC_SCFCTST1 0xE6791708U -#define DBSC_SCFCTST2 0xE679170CU -#define DBSC_DBMRRDR(chab) (0xE6791800U + 0x04U * (chab)) -#define DBSC_DBMRRDR_0 0xE6791800U -#define DBSC_DBMRRDR_1 0xE6791804U -#define DBSC_DBMRRDR_2 0xE6791808U -#define DBSC_DBMRRDR_3 0xE679180CU -#define DBSC_DBMRRDR_4 0xE6791810U -#define DBSC_DBMRRDR_5 0xE6791814U -#define DBSC_DBMRRDR_6 0xE6791818U -#define DBSC_DBMRRDR_7 0xE679181CU -#define DBSC_DBMEMSWAPCONF0 0xE6792000U - -/* CPG registers */ -#define CPG_BASE 0xE6150000U -#define CPG_FRQCRB (CPG_BASE + 0x0004U) -#define CPG_PLLECR (CPG_BASE + 0x00D0U) -#define CPG_MSTPSR5 (CPG_BASE + 0x003CU) -#define CPG_SRCR4 (CPG_BASE + 0x00BCU) -#define CPG_PLL3CR (CPG_BASE + 0x00DCU) -#define CPG_ZB3CKCR (CPG_BASE + 0x0380U) -#define CPG_FRQCRD (CPG_BASE + 0x00E4U) -#define CPG_SMSTPCR5 (CPG_BASE + 0x0144U) -#define CPG_CPGWPR (CPG_BASE + 0x0900U) -#define CPG_SRSTCLR4 (CPG_BASE + 0x0950U) - -#endif /* BOOT_INIT_DRAM_REGDEF_H_*/ diff --git a/drivers/renesas/rcar/pfc/pfc_regs.h b/drivers/renesas/rcar/pfc/pfc_regs.h deleted file mode 100644 index 418773366..000000000 --- a/drivers/renesas/rcar/pfc/pfc_regs.h +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ -#ifndef PFC_REGS_H -#define PFC_REGS_H - -/* GPIO base address */ -#define GPIO_BASE (0xE6050000U) - -/* GPIO registers */ -#define GPIO_IOINTSEL0 (GPIO_BASE + 0x0000U) -#define GPIO_INOUTSEL0 (GPIO_BASE + 0x0004U) -#define GPIO_OUTDT0 (GPIO_BASE + 0x0008U) -#define GPIO_INDT0 (GPIO_BASE + 0x000CU) -#define GPIO_INTDT0 (GPIO_BASE + 0x0010U) -#define GPIO_INTCLR0 (GPIO_BASE + 0x0014U) -#define GPIO_INTMSK0 (GPIO_BASE + 0x0018U) -#define GPIO_MSKCLR0 (GPIO_BASE + 0x001CU) -#define GPIO_POSNEG0 (GPIO_BASE + 0x0020U) -#define GPIO_EDGLEVEL0 (GPIO_BASE + 0x0024U) -#define GPIO_FILONOFF0 (GPIO_BASE + 0x0028U) -#define GPIO_INTMSKS0 (GPIO_BASE + 0x0038U) -#define GPIO_MSKCLRS0 (GPIO_BASE + 0x003CU) -#define GPIO_OUTDTSEL0 (GPIO_BASE + 0x0040U) -#define GPIO_OUTDTH0 (GPIO_BASE + 0x0044U) -#define GPIO_OUTDTL0 (GPIO_BASE + 0x0048U) -#define GPIO_BOTHEDGE0 (GPIO_BASE + 0x004CU) -#define GPIO_IOINTSEL1 (GPIO_BASE + 0x1000U) -#define GPIO_INOUTSEL1 (GPIO_BASE + 0x1004U) -#define GPIO_OUTDT1 (GPIO_BASE + 0x1008U) -#define GPIO_INDT1 (GPIO_BASE + 0x100CU) -#define GPIO_INTDT1 (GPIO_BASE + 0x1010U) -#define GPIO_INTCLR1 (GPIO_BASE + 0x1014U) -#define GPIO_INTMSK1 (GPIO_BASE + 0x1018U) -#define GPIO_MSKCLR1 (GPIO_BASE + 0x101CU) -#define GPIO_POSNEG1 (GPIO_BASE + 0x1020U) -#define GPIO_EDGLEVEL1 (GPIO_BASE + 0x1024U) -#define GPIO_FILONOFF1 (GPIO_BASE + 0x1028U) -#define GPIO_INTMSKS1 (GPIO_BASE + 0x1038U) -#define GPIO_MSKCLRS1 (GPIO_BASE + 0x103CU) -#define GPIO_OUTDTSEL1 (GPIO_BASE + 0x1040U) -#define GPIO_OUTDTH1 (GPIO_BASE + 0x1044U) -#define GPIO_OUTDTL1 (GPIO_BASE + 0x1048U) -#define GPIO_BOTHEDGE1 (GPIO_BASE + 0x104CU) -#define GPIO_IOINTSEL2 (GPIO_BASE + 0x2000U) -#define GPIO_INOUTSEL2 (GPIO_BASE + 0x2004U) -#define GPIO_OUTDT2 (GPIO_BASE + 0x2008U) -#define GPIO_INDT2 (GPIO_BASE + 0x200CU) -#define GPIO_INTDT2 (GPIO_BASE + 0x2010U) -#define GPIO_INTCLR2 (GPIO_BASE + 0x2014U) -#define GPIO_INTMSK2 (GPIO_BASE + 0x2018U) -#define GPIO_MSKCLR2 (GPIO_BASE + 0x201CU) -#define GPIO_POSNEG2 (GPIO_BASE + 0x2020U) -#define GPIO_EDGLEVEL2 (GPIO_BASE + 0x2024U) -#define GPIO_FILONOFF2 (GPIO_BASE + 0x2028U) -#define GPIO_INTMSKS2 (GPIO_BASE + 0x2038U) -#define GPIO_MSKCLRS2 (GPIO_BASE + 0x203CU) -#define GPIO_OUTDTSEL2 (GPIO_BASE + 0x2040U) -#define GPIO_OUTDTH2 (GPIO_BASE + 0x2044U) -#define GPIO_OUTDTL2 (GPIO_BASE + 0x2048U) -#define GPIO_BOTHEDGE2 (GPIO_BASE + 0x204CU) -#define GPIO_IOINTSEL3 (GPIO_BASE + 0x3000U) -#define GPIO_INOUTSEL3 (GPIO_BASE + 0x3004U) -#define GPIO_OUTDT3 (GPIO_BASE + 0x3008U) -#define GPIO_INDT3 (GPIO_BASE + 0x300CU) -#define GPIO_INTDT3 (GPIO_BASE + 0x3010U) -#define GPIO_INTCLR3 (GPIO_BASE + 0x3014U) -#define GPIO_INTMSK3 (GPIO_BASE + 0x3018U) -#define GPIO_MSKCLR3 (GPIO_BASE + 0x301CU) -#define GPIO_POSNEG3 (GPIO_BASE + 0x3020U) -#define GPIO_EDGLEVEL3 (GPIO_BASE + 0x3024U) -#define GPIO_FILONOFF3 (GPIO_BASE + 0x3028U) -#define GPIO_INTMSKS3 (GPIO_BASE + 0x3038U) -#define GPIO_MSKCLRS3 (GPIO_BASE + 0x303CU) -#define GPIO_OUTDTSEL3 (GPIO_BASE + 0x3040U) -#define GPIO_OUTDTH3 (GPIO_BASE + 0x3044U) -#define GPIO_OUTDTL3 (GPIO_BASE + 0x3048U) -#define GPIO_BOTHEDGE3 (GPIO_BASE + 0x304CU) -#define GPIO_IOINTSEL4 (GPIO_BASE + 0x4000U) -#define GPIO_INOUTSEL4 (GPIO_BASE + 0x4004U) -#define GPIO_OUTDT4 (GPIO_BASE + 0x4008U) -#define GPIO_INDT4 (GPIO_BASE + 0x400CU) -#define GPIO_INTDT4 (GPIO_BASE + 0x4010U) -#define GPIO_INTCLR4 (GPIO_BASE + 0x4014U) -#define GPIO_INTMSK4 (GPIO_BASE + 0x4018U) -#define GPIO_MSKCLR4 (GPIO_BASE + 0x401CU) -#define GPIO_POSNEG4 (GPIO_BASE + 0x4020U) -#define GPIO_EDGLEVEL4 (GPIO_BASE + 0x4024U) -#define GPIO_FILONOFF4 (GPIO_BASE + 0x4028U) -#define GPIO_INTMSKS4 (GPIO_BASE + 0x4038U) -#define GPIO_MSKCLRS4 (GPIO_BASE + 0x403CU) -#define GPIO_OUTDTSEL4 (GPIO_BASE + 0x4040U) -#define GPIO_OUTDTH4 (GPIO_BASE + 0x4044U) -#define GPIO_OUTDTL4 (GPIO_BASE + 0x4048U) -#define GPIO_BOTHEDGE4 (GPIO_BASE + 0x404CU) -#define GPIO_IOINTSEL5 (GPIO_BASE + 0x5000U) -#define GPIO_INOUTSEL5 (GPIO_BASE + 0x5004U) -#define GPIO_OUTDT5 (GPIO_BASE + 0x5008U) -#define GPIO_INDT5 (GPIO_BASE + 0x500CU) -#define GPIO_INTDT5 (GPIO_BASE + 0x5010U) -#define GPIO_INTCLR5 (GPIO_BASE + 0x5014U) -#define GPIO_INTMSK5 (GPIO_BASE + 0x5018U) -#define GPIO_MSKCLR5 (GPIO_BASE + 0x501CU) -#define GPIO_POSNEG5 (GPIO_BASE + 0x5020U) -#define GPIO_EDGLEVEL5 (GPIO_BASE + 0x5024U) -#define GPIO_FILONOFF5 (GPIO_BASE + 0x5028U) -#define GPIO_INTMSKS5 (GPIO_BASE + 0x5038U) -#define GPIO_MSKCLRS5 (GPIO_BASE + 0x503CU) -#define GPIO_OUTDTSEL5 (GPIO_BASE + 0x5040U) -#define GPIO_OUTDTH5 (GPIO_BASE + 0x5044U) -#define GPIO_OUTDTL5 (GPIO_BASE + 0x5048U) -#define GPIO_BOTHEDGE5 (GPIO_BASE + 0x504CU) -#define GPIO_IOINTSEL6 (GPIO_BASE + 0x5400U) -#define GPIO_INOUTSEL6 (GPIO_BASE + 0x5404U) -#define GPIO_OUTDT6 (GPIO_BASE + 0x5408U) -#define GPIO_INTDT6 (GPIO_BASE + 0x5410U) -#define GPIO_INTCLR6 (GPIO_BASE + 0x5414U) -#define GPIO_INTMSK6 (GPIO_BASE + 0x5418U) -#define GPIO_MSKCLR6 (GPIO_BASE + 0x541CU) -#define GPIO_POSNEG6 (GPIO_BASE + 0x5420U) -#define GPIO_EDGLEVEL6 (GPIO_BASE + 0x5424U) -#define GPIO_FILONOFF6 (GPIO_BASE + 0x5428U) -#define GPIO_INTMSKS6 (GPIO_BASE + 0x5438U) -#define GPIO_MSKCLRS6 (GPIO_BASE + 0x543CU) -#define GPIO_OUTDTSEL6 (GPIO_BASE + 0x5440U) -#define GPIO_OUTDTH6 (GPIO_BASE + 0x5444U) -#define GPIO_OUTDTL6 (GPIO_BASE + 0x5448U) -#define GPIO_BOTHEDGE6 (GPIO_BASE + 0x544CU) -#define GPIO_IOINTSEL7 (GPIO_BASE + 0x5800U) -#define GPIO_INOUTSEL7 (GPIO_BASE + 0x5804U) -#define GPIO_OUTDT7 (GPIO_BASE + 0x5808U) -#define GPIO_INDT7 (GPIO_BASE + 0x580CU) -#define GPIO_INTDT7 (GPIO_BASE + 0x5810U) -#define GPIO_INTCLR7 (GPIO_BASE + 0x5814U) -#define GPIO_INTMSK7 (GPIO_BASE + 0x5818U) -#define GPIO_MSKCLR7 (GPIO_BASE + 0x581CU) -#define GPIO_POSNEG7 (GPIO_BASE + 0x5820U) -#define GPIO_EDGLEVEL7 (GPIO_BASE + 0x5824U) -#define GPIO_FILONOFF7 (GPIO_BASE + 0x5828U) -#define GPIO_INTMSKS7 (GPIO_BASE + 0x5838U) -#define GPIO_MSKCLRS7 (GPIO_BASE + 0x583CU) -#define GPIO_OUTDTSEL7 (GPIO_BASE + 0x5840U) -#define GPIO_OUTDTH7 (GPIO_BASE + 0x5844U) -#define GPIO_OUTDTL7 (GPIO_BASE + 0x5848U) -#define GPIO_BOTHEDGE7 (GPIO_BASE + 0x584CU) - -/* Pin functon base address */ -#define PFC_BASE (0xE6060000U) - -/* Pin functon registers */ -#define PFC_PMMR (PFC_BASE + 0x0000U) -#define PFC_GPSR0 (PFC_BASE + 0x0100U) -#define PFC_GPSR1 (PFC_BASE + 0x0104U) -#define PFC_GPSR2 (PFC_BASE + 0x0108U) -#define PFC_GPSR3 (PFC_BASE + 0x010CU) -#define PFC_GPSR4 (PFC_BASE + 0x0110U) -#define PFC_GPSR5 (PFC_BASE + 0x0114U) -#define PFC_GPSR6 (PFC_BASE + 0x0118U) -#define PFC_GPSR7 (PFC_BASE + 0x011CU) -#define PFC_IPSR0 (PFC_BASE + 0x0200U) -#define PFC_IPSR1 (PFC_BASE + 0x0204U) -#define PFC_IPSR2 (PFC_BASE + 0x0208U) -#define PFC_IPSR3 (PFC_BASE + 0x020CU) -#define PFC_IPSR4 (PFC_BASE + 0x0210U) -#define PFC_IPSR5 (PFC_BASE + 0x0214U) -#define PFC_IPSR6 (PFC_BASE + 0x0218U) -#define PFC_IPSR7 (PFC_BASE + 0x021CU) -#define PFC_IPSR8 (PFC_BASE + 0x0220U) -#define PFC_IPSR9 (PFC_BASE + 0x0224U) -#define PFC_IPSR10 (PFC_BASE + 0x0228U) -#define PFC_IPSR11 (PFC_BASE + 0x022CU) -#define PFC_IPSR12 (PFC_BASE + 0x0230U) -#define PFC_IPSR13 (PFC_BASE + 0x0234U) -#define PFC_IPSR14 (PFC_BASE + 0x0238U) -#define PFC_IPSR15 (PFC_BASE + 0x023CU) -#define PFC_IPSR16 (PFC_BASE + 0x0240U) -#define PFC_IPSR17 (PFC_BASE + 0x0244U) -#define PFC_IPSR18 (PFC_BASE + 0x0248U) -#define PFC_DRVCTRL0 (PFC_BASE + 0x0300U) -#define PFC_DRVCTRL1 (PFC_BASE + 0x0304U) -#define PFC_DRVCTRL2 (PFC_BASE + 0x0308U) -#define PFC_DRVCTRL3 (PFC_BASE + 0x030CU) -#define PFC_DRVCTRL4 (PFC_BASE + 0x0310U) -#define PFC_DRVCTRL5 (PFC_BASE + 0x0314U) -#define PFC_DRVCTRL6 (PFC_BASE + 0x0318U) -#define PFC_DRVCTRL7 (PFC_BASE + 0x031CU) -#define PFC_DRVCTRL8 (PFC_BASE + 0x0320U) -#define PFC_DRVCTRL9 (PFC_BASE + 0x0324U) -#define PFC_DRVCTRL10 (PFC_BASE + 0x0328U) -#define PFC_DRVCTRL11 (PFC_BASE + 0x032CU) -#define PFC_DRVCTRL12 (PFC_BASE + 0x0330U) -#define PFC_DRVCTRL13 (PFC_BASE + 0x0334U) -#define PFC_DRVCTRL14 (PFC_BASE + 0x0338U) -#define PFC_DRVCTRL15 (PFC_BASE + 0x033CU) -#define PFC_DRVCTRL16 (PFC_BASE + 0x0340U) -#define PFC_DRVCTRL17 (PFC_BASE + 0x0344U) -#define PFC_DRVCTRL18 (PFC_BASE + 0x0348U) -#define PFC_DRVCTRL19 (PFC_BASE + 0x034CU) -#define PFC_DRVCTRL20 (PFC_BASE + 0x0350U) -#define PFC_DRVCTRL21 (PFC_BASE + 0x0354U) -#define PFC_DRVCTRL22 (PFC_BASE + 0x0358U) -#define PFC_DRVCTRL23 (PFC_BASE + 0x035CU) -#define PFC_DRVCTRL24 (PFC_BASE + 0x0360U) -#define PFC_POCCTRL0 (PFC_BASE + 0x0380U) -#define PFC_IOCTRL31 (PFC_BASE + 0x0384U) -#define PFC_POCCTRL2 (PFC_BASE + 0x0388U) -#define PFC_TDSELCTRL0 (PFC_BASE + 0x03C0U) -#define PFC_IOCTRL (PFC_BASE + 0x03E0U) -#define PFC_TSREG (PFC_BASE + 0x03E4U) -#define PFC_PUEN0 (PFC_BASE + 0x0400U) -#define PFC_PUEN1 (PFC_BASE + 0x0404U) -#define PFC_PUEN2 (PFC_BASE + 0x0408U) -#define PFC_PUEN3 (PFC_BASE + 0x040CU) -#define PFC_PUEN4 (PFC_BASE + 0x0410U) -#define PFC_PUEN5 (PFC_BASE + 0x0414U) -#define PFC_PUEN6 (PFC_BASE + 0x0418U) -#define PFC_PUD0 (PFC_BASE + 0x0440U) -#define PFC_PUD1 (PFC_BASE + 0x0444U) -#define PFC_PUD2 (PFC_BASE + 0x0448U) -#define PFC_PUD3 (PFC_BASE + 0x044CU) -#define PFC_PUD4 (PFC_BASE + 0x0450U) -#define PFC_PUD5 (PFC_BASE + 0x0454U) -#define PFC_PUD6 (PFC_BASE + 0x0458U) -#define PFC_MOD_SEL0 (PFC_BASE + 0x0500U) -#define PFC_MOD_SEL1 (PFC_BASE + 0x0504U) -#define PFC_MOD_SEL2 (PFC_BASE + 0x0508U) - -#endif /* PFC_REGS_H */ diff --git a/drivers/renesas/rcar/qos/qos_reg.h b/drivers/renesas/rcar/qos/qos_reg.h deleted file mode 100644 index f2012fa45..000000000 --- a/drivers/renesas/rcar/qos/qos_reg.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (c) 2017-2019, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef QOS_REG_H -#define QOS_REG_H - -#define RCAR_QOS_NONE 3U -#define RCAR_QOS_TYPE_DEFAULT 0U - -#define RCAR_DRAM_SPLIT_LINEAR 0U -#define RCAR_DRAM_SPLIT_4CH 1U -#define RCAR_DRAM_SPLIT_2CH 2U -#define RCAR_DRAM_SPLIT_AUTO 3U -#define RST_BASE (0xE6160000U) -#define RST_MODEMR (RST_BASE + 0x0060U) - -#define DBSC_BASE 0xE6790000U -#define DBSC_DBSYSCNT0 (DBSC_BASE + 0x0100U) -#define DBSC_AXARB (DBSC_BASE + 0x0800U) -#define DBSC_DBCAM0CNF1 (DBSC_BASE + 0x0904U) -#define DBSC_DBCAM0CNF2 (DBSC_BASE + 0x0908U) -#define DBSC_DBCAM0CNF3 (DBSC_BASE + 0x090CU) -#define DBSC_DBSCHCNT0 (DBSC_BASE + 0x1000U) -#define DBSC_DBSCHCNT1 (DBSC_BASE + 0x1004U) -#define DBSC_DBSCHSZ0 (DBSC_BASE + 0x1010U) -#define DBSC_DBSCHRW0 (DBSC_BASE + 0x1020U) -#define DBSC_DBSCHRW1 (DBSC_BASE + 0x1024U) -#define DBSC_DBSCHQOS00 (DBSC_BASE + 0x1030U) -#define DBSC_DBSCHQOS01 (DBSC_BASE + 0x1034U) -#define DBSC_DBSCHQOS02 (DBSC_BASE + 0x1038U) -#define DBSC_DBSCHQOS03 (DBSC_BASE + 0x103CU) -#define DBSC_DBSCHQOS40 (DBSC_BASE + 0x1070U) -#define DBSC_DBSCHQOS41 (DBSC_BASE + 0x1074U) -#define DBSC_DBSCHQOS42 (DBSC_BASE + 0x1078U) -#define DBSC_DBSCHQOS43 (DBSC_BASE + 0x107CU) -#define DBSC_DBSCHQOS90 (DBSC_BASE + 0x10C0U) -#define DBSC_DBSCHQOS91 (DBSC_BASE + 0x10C4U) -#define DBSC_DBSCHQOS92 (DBSC_BASE + 0x10C8U) -#define DBSC_DBSCHQOS93 (DBSC_BASE + 0x10CCU) -#define DBSC_DBSCHQOS120 (DBSC_BASE + 0x10F0U) -#define DBSC_DBSCHQOS121 (DBSC_BASE + 0x10F4U) -#define DBSC_DBSCHQOS122 (DBSC_BASE + 0x10F8U) -#define DBSC_DBSCHQOS123 (DBSC_BASE + 0x10FCU) -#define DBSC_DBSCHQOS130 (DBSC_BASE + 0x1100U) -#define DBSC_DBSCHQOS131 (DBSC_BASE + 0x1104U) -#define DBSC_DBSCHQOS132 (DBSC_BASE + 0x1108U) -#define DBSC_DBSCHQOS133 (DBSC_BASE + 0x110CU) -#define DBSC_DBSCHQOS140 (DBSC_BASE + 0x1110U) -#define DBSC_DBSCHQOS141 (DBSC_BASE + 0x1114U) -#define DBSC_DBSCHQOS142 (DBSC_BASE + 0x1118U) -#define DBSC_DBSCHQOS143 (DBSC_BASE + 0x111CU) -#define DBSC_DBSCHQOS150 (DBSC_BASE + 0x1120U) -#define DBSC_DBSCHQOS151 (DBSC_BASE + 0x1124U) -#define DBSC_DBSCHQOS152 (DBSC_BASE + 0x1128U) -#define DBSC_DBSCHQOS153 (DBSC_BASE + 0x112CU) -#define DBSC_SCFCTST0 (DBSC_BASE + 0x1700U) -#define DBSC_SCFCTST1 (DBSC_BASE + 0x1708U) -#define DBSC_SCFCTST2 (DBSC_BASE + 0x170CU) - -#define AXI_BASE 0xE6784000U -#define AXI_ADSPLCR0 (AXI_BASE + 0x0008U) -#define AXI_ADSPLCR1 (AXI_BASE + 0x000CU) -#define AXI_ADSPLCR2 (AXI_BASE + 0x0010U) -#define AXI_ADSPLCR3 (AXI_BASE + 0x0014U) -#define AXI_MMCR (AXI_BASE + 0x0300U) -#define ADSPLCR0_ADRMODE_DEFAULT ((uint32_t)0U << 31U) -#define ADSPLCR0_ADRMODE_GEN2 ((uint32_t)1U << 31U) -#define ADSPLCR0_SPLITSEL(x) ((uint32_t)(x) << 16U) -#define ADSPLCR0_AREA(x) ((uint32_t)(x) << 8U) -#define ADSPLCR0_SWP 0x0CU - -#define AXI_TR3CR 0xE67D100CU -#define AXI_TR4CR 0xE67D1014U - -#define QOS_BASE0 0xE67E0000U -#define QOSBW_FIX_QOS_BANK0 (QOS_BASE0 + 0x0000U) -#define QOSBW_FIX_QOS_BANK1 (QOS_BASE0 + 0x1000U) -#define QOSBW_BE_QOS_BANK0 (QOS_BASE0 + 0x2000U) -#define QOSBW_BE_QOS_BANK1 (QOS_BASE0 + 0x3000U) -#define QOSCTRL_SL_INIT (QOS_BASE0 + 0x8000U) -#define QOSCTRL_REF_ARS (QOS_BASE0 + 0x8004U) -#define QOSCTRL_STATQC (QOS_BASE0 + 0x8008U) - -#define QOS_BASE1 0xE67F0000U -#define QOSCTRL_RAS (QOS_BASE1 + 0x0000U) -#define QOSCTRL_FIXTH (QOS_BASE1 + 0x0004U) -#define QOSCTRL_RAEN (QOS_BASE1 + 0x0018U) -#define QOSCTRL_REGGD (QOS_BASE1 + 0x0020U) -#define QOSCTRL_DANN (QOS_BASE1 + 0x0030U) -#define QOSCTRL_DANT (QOS_BASE1 + 0x0038U) -#define QOSCTRL_EC (QOS_BASE1 + 0x003CU) -#define QOSCTRL_EMS (QOS_BASE1 + 0x0040U) -#define QOSCTRL_FSS (QOS_BASE1 + 0x0048U) -#define QOSCTRL_INSFC (QOS_BASE1 + 0x0050U) -#define QOSCTRL_BERR (QOS_BASE1 + 0x0054U) -#define QOSCTRL_EARLYR (QOS_BASE1 + 0x0060U) -#define QOSCTRL_RACNT0 (QOS_BASE1 + 0x0080U) -#define QOSCTRL_STATGEN0 (QOS_BASE1 + 0x0088U) - -#define GPU_ACT_GRD 0xFD820808U -#define GPU_ACT0 0xFD820800U -#define GPU_ACT1 0xFD821800U -#define GPU_ACT2 0xFD822800U -#define GPU_ACT3 0xFD823800U -#define GPU_ACT4 0xFD824800U -#define GPU_ACT5 0xFD825800U -#define GPU_ACT6 0xFD826800U -#define GPU_ACT7 0xFD827800U - -#define RT_ACT0 0xFFC50800U -#define RT_ACT1 0xFFC51800U - -#define CPU_ACT0 0xF1300800U -#define CPU_ACT1 0xF1340800U -#define CPU_ACT2 0xF1380800U -#define CPU_ACT3 0xF13C0800U - -#define RCAR_REWT_TRAINING_DISABLE 0U -#define RCAR_REWT_TRAINING_ENABLE 1U - -#define QOSWT_FIX_WTQOS_BANK0 (QOSBW_FIX_QOS_BANK0 + 0x0800U) -#define QOSWT_FIX_WTQOS_BANK1 (QOSBW_FIX_QOS_BANK1 + 0x0800U) -#define QOSWT_BE_WTQOS_BANK0 (QOSBW_BE_QOS_BANK0 + 0x0800U) -#define QOSWT_BE_WTQOS_BANK1 (QOSBW_BE_QOS_BANK1 + 0x0800U) -#define QOSWT_WTEN (QOS_BASE0 + 0x8030U) -#define QOSWT_WTREF (QOS_BASE0 + 0x8034U) -#define QOSWT_WTSET0 (QOS_BASE0 + 0x8038U) -#define QOSWT_WTSET1 (QOS_BASE0 + 0x803CU) - -#endif /* QOS_REG_H */ diff --git a/plat/renesas/rcar/platform.mk b/plat/renesas/rcar/platform.mk index 542b36e22..a861c7c7c 100644 --- a/plat/renesas/rcar/platform.mk +++ b/plat/renesas/rcar/platform.mk @@ -302,6 +302,7 @@ PLAT_INCLUDES += -Idrivers/renesas/rcar/ddr \ -Idrivers/renesas/rcar/qos \ -Idrivers/renesas/rcar/board \ -Idrivers/renesas/rcar/cpld/ \ + -Idrivers/renesas/common \ -Idrivers/renesas/common/iic_dvfs \ -Idrivers/renesas/common/avs \ -Idrivers/renesas/common/delay \ -- cgit v1.2.3 From fd9b3c5ae9b211670ba9cdbe6520892b6e39df59 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Wed, 16 Dec 2020 11:21:33 +0000 Subject: plat: renesas: aarch64: Move to common Move plat aarch64 code to common directory, so that the same code can be re-used by both R-Car Gen3 and RZ/G2 platforms. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: I66265e5e68bfcf5c3534965fb3549a145c782b47 --- plat/renesas/common/aarch64/plat_helpers.S | 392 ++++++++++++++++++++++++++ plat/renesas/common/aarch64/platform_common.c | 271 ++++++++++++++++++ plat/renesas/common/common.mk | 4 + plat/renesas/rcar/aarch64/plat_helpers.S | 392 -------------------------- plat/renesas/rcar/aarch64/platform_common.c | 271 ------------------ plat/renesas/rcar/platform.mk | 6 +- 6 files changed, 668 insertions(+), 668 deletions(-) create mode 100644 plat/renesas/common/aarch64/plat_helpers.S create mode 100644 plat/renesas/common/aarch64/platform_common.c delete mode 100644 plat/renesas/rcar/aarch64/plat_helpers.S delete mode 100644 plat/renesas/rcar/aarch64/platform_common.c diff --git a/plat/renesas/common/aarch64/plat_helpers.S b/plat/renesas/common/aarch64/plat_helpers.S new file mode 100644 index 000000000..ec21f2510 --- /dev/null +++ b/plat/renesas/common/aarch64/plat_helpers.S @@ -0,0 +1,392 @@ +/* + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include + +#include "rcar_def.h" + + .globl plat_get_my_entrypoint + .extern plat_set_my_stack + .globl platform_mem_init + + .globl plat_crash_console_init + .globl plat_crash_console_putc + .globl plat_crash_console_flush + .globl plat_invalidate_icache + .globl plat_report_exception + .globl plat_secondary_reset + .globl plat_reset_handler + .globl plat_my_core_pos + .extern rcar_log_init + + .extern console_rcar_init + .extern console_rcar_putc + .extern console_rcar_flush + +#if IMAGE_BL2 + #define INT_ID_MASK (0x3ff) + .extern bl2_interrupt_error_type + .extern bl2_interrupt_error_id + .globl bl2_enter_bl31 + .extern gicv2_acknowledge_interrupt + .extern rcar_swdt_exec +#endif + + /* ----------------------------------------------------- + * void platform_get_core_pos (mpidr) + * ----------------------------------------------------- + */ +func platform_get_core_pos + and x1, x0, #MPIDR_CPU_MASK + and x0, x0, #MPIDR_CLUSTER_MASK + add x0, x1, x0, LSR #6 + ret +endfunc platform_get_core_pos + + /* ----------------------------------------------------- + * void platform_my_core_pos + * ----------------------------------------------------- + */ +func plat_my_core_pos + mrs x0, mpidr_el1 + b platform_get_core_pos +endfunc plat_my_core_pos + + /* ----------------------------------------------------- + * void platform_get_my_entrypoint (unsigned int mpid); + * + * Main job of this routine is to distinguish between + * a cold and warm boot. + * On a cold boot the secondaries first wait for the + * platform to be initialized after which they are + * hotplugged in. The primary proceeds to perform the + * platform initialization. + * On a warm boot, each cpu jumps to the address in its + * mailbox. + * + * TODO: Not a good idea to save lr in a temp reg + * ----------------------------------------------------- + */ +func plat_get_my_entrypoint + mrs x0, mpidr_el1 + mov x9, x30 /* lr */ + +#if defined(IMAGE_BL2) + /* always cold boot on bl2 */ + mov x0, #0 + ret x9 +#else + ldr x1, =BOOT_KIND_BASE + ldr x21, [x1] + + /* Check the reset info */ + and x1, x21, #0x000c + cmp x1, #0x0008 + beq el3_panic + cmp x1, #0x000c + beq el3_panic + + /* Check the boot kind */ + and x1, x21, #0x0003 + cmp x1, #0x0002 + beq el3_panic + cmp x1, #0x0003 + beq el3_panic + + /* warm boot or cold boot */ + and x1, x21, #1 + cmp x1, #0 + bne warm_reset + + /* Cold boot */ + mov x0, #0 + b exit + +warm_reset: + /* -------------------------------------------------------------------- + * A per-cpu mailbox is maintained in the trusted SDRAM. Its flushed out + * of the caches after every update using normal memory so its safe to + * read it here with SO attributes + * --------------------------------------------------------------------- + */ + ldr x10, =MBOX_BASE + bl platform_get_core_pos + lsl x0, x0, #CACHE_WRITEBACK_SHIFT + ldr x0, [x10, x0] + cbz x0, _panic +exit: + ret x9 +_panic: + b do_panic +#endif + +endfunc plat_get_my_entrypoint + + /* --------------------------------------------- + * plat_secondary_reset + * + * --------------------------------------------- + */ +func plat_secondary_reset + mrs x0, sctlr_el3 + bic x0, x0, #SCTLR_EE_BIT + msr sctlr_el3, x0 + isb + + mrs x0, cptr_el3 + bic w0, w0, #TCPAC_BIT + bic w0, w0, #TTA_BIT + bic w0, w0, #TFP_BIT + msr cptr_el3, x0 + + mov_imm x0, PARAMS_BASE + mov_imm x2, BL31_BASE + ldr x3, =BOOT_KIND_BASE + mov x1, #0x1 + str x1, [x3] + br x2 /* jump to BL31 */ + nop + nop + nop +endfunc plat_secondary_reset + + /* --------------------------------------------- + * plat_enter_bl31 + * + * --------------------------------------------- + */ +func bl2_enter_bl31 + 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. + */ +#if RCAR_BL2_DCACHE == 1 + /* Disable mmu and data cache */ + bl disable_mmu_el3 + /* Data cache clean and invalidate */ + mov x0, #DCCISW + bl dcsw_op_all + /* TLB invalidate all, EL3 */ + tlbi alle3 +#endif /* RCAR_BL2_DCACHE == 1 */ + bl disable_mmu_icache_el3 + /* Invalidate instruction cache */ + ic iallu + dsb sy + isb + ldp x0, x1, [x20, #ENTRY_POINT_INFO_PC_OFFSET] + msr elr_el3, x0 + msr spsr_el3, x1 + exception_return +endfunc bl2_enter_bl31 + + /* ----------------------------------------------------- + * void platform_mem_init (void); + * + * Zero out the mailbox registers in the shared memory + * and set the rcar_boot_kind_flag. + * The mmu is turned off right now and only the primary can + * ever execute this code. Secondaries will read the + * mailboxes using SO accesses. + * ----------------------------------------------------- + */ +func platform_mem_init +#if !IMAGE_BL2 + ldr x0, =MBOX_BASE + mov w1, #PLATFORM_CORE_COUNT +loop: + str xzr, [x0], #CACHE_WRITEBACK_GRANULE + subs w1, w1, #1 + b.gt loop +#endif + ret +endfunc platform_mem_init + + /* --------------------------------------------- + * void plat_report_exception(unsigned int type) + * Function to report an unhandled exception + * with platform-specific means. + * --------------------------------------------- + */ +func plat_report_exception + /* Switch to SP_EL0 */ + msr spsel, #0 +#if IMAGE_BL2 + mov w1, #FIQ_SP_EL0 + cmp w0, w1 + beq rep_exec_fiq_elx + b rep_exec_panic_type +rep_exec_fiq_elx: + bl gicv2_acknowledge_interrupt + mov x2, #INT_ID_MASK + and x0, x0, x2 + mov x1, #ARM_IRQ_SEC_WDT + cmp x0, x1 + bne rep_exec_panic_id + mrs x0, ELR_EL3 + b rcar_swdt_exec +rep_exec_panic_type: + /* x0 is interrupt TYPE */ + b bl2_interrupt_error_type +rep_exec_panic_id: + /* x0 is interrupt ID */ + b bl2_interrupt_error_id +rep_exec_end: +#endif + ret +endfunc plat_report_exception + + /* --------------------------------------------- + * int plat_crash_console_init(void) + * Function to initialize log area + * --------------------------------------------- + */ +func plat_crash_console_init +#if IMAGE_BL2 + mov x0, #0 +#else + mov x1, sp + mov_imm x2, RCAR_CRASH_STACK + mov sp, x2 + str x1, [sp, #-16]! + str x30, [sp, #-16]! + bl console_rcar_init + ldr x30, [sp], #16 + ldr x1, [sp], #16 + mov sp, x1 +#endif + ret +endfunc plat_crash_console_init + + /* --------------------------------------------- + * int plat_crash_console_putc(int c) + * Function to store a character to log area + * --------------------------------------------- + */ +func plat_crash_console_putc + mov x1, sp + mov_imm x2, RCAR_CRASH_STACK + mov sp, x2 + str x1, [sp, #-16]! + str x30, [sp, #-16]! + str x3, [sp, #-16]! + str x4, [sp, #-16]! + str x5, [sp, #-16]! + bl console_rcar_putc + ldr x5, [sp], #16 + ldr x4, [sp], #16 + ldr x3, [sp], #16 + ldr x30, [sp], #16 + ldr x1, [sp], #16 + mov sp, x1 + ret +endfunc plat_crash_console_putc + + /* --------------------------------------------- + * void plat_crash_console_flush() + * --------------------------------------------- + */ +func plat_crash_console_flush + b console_rcar_flush +endfunc plat_crash_console_flush + + /* -------------------------------------------------------------------- + * void plat_reset_handler(void); + * + * Before adding code in this function, refer to the guidelines in + * docs/firmware-design.md to determine whether the code should reside + * within the FIRST_RESET_HANDLER_CALL block or not. + * + * For R-Car H3: + * - Set the L2 Tag RAM latency to 2 (i.e. 3 cycles) for Cortex-A57 + * - Set the L2 Data setup latency to 1 (i.e. 1 cycles) for Cortex-A57 + * - Set the L2 Data RAM latency to 3 (i.e. 4 cycles) for Cortex-A57 + * For R-Car M3/M3N: + * - Set the L2 Tag RAM latency to 2 (i.e. 3 cycles) for Cortex-A57 + * - Set the L2 Data setup latency to 0 (i.e. 0 cycles) for Cortex-A57 + * - Set the L2 Data RAM latency to 3 (i.e. 4 cycles) for Cortex-A57 + * + * -------------------------------------------------------------------- + */ +func plat_reset_handler + /* + * On R-Car H3 : x2 := 0 + * On R-Car M3/M3N: x2 := 1 + */ + /* read PRR */ + ldr x0, =0xFFF00044 + ldr w0, [x0] + ubfx w0, w0, 8, 8 + /* H3? */ + cmp w0, #0x4F + b.eq RCARH3 + /* set R-Car M3/M3N */ + mov x2, #1 + b CHK_A5x +RCARH3: + /* set R-Car H3 */ + mov x2, #0 + /* -------------------------------------------------------------------- + * Determine whether this code is executed on a Cortex-A53 or on a + * Cortex-A57 core. + * -------------------------------------------------------------------- + */ +CHK_A5x: + mrs x0, midr_el1 + ubfx x1, x0, MIDR_PN_SHIFT, #12 + cmp w1, #((CORTEX_A57_MIDR >> MIDR_PN_SHIFT) & MIDR_PN_MASK) + b.eq A57 + ret +A57: + /* Get data from CORTEX_A57_L2CTLR_EL1 */ + mrs x0, CORTEX_A57_L2CTLR_EL1 + /* + * On R-Car H3/M3/M3N + * + * L2 Tag RAM latency is bit8-6 of CORTEX_A57_L2CTLR_EL1 + * L2 Data RAM setup is bit5 of CORTEX_A57_L2CTLR_EL1 + * L2 Data RAM latency is bit2-0 of CORTEX_A57_L2CTLR_EL1 + */ + /* clear bit of L2 RAM */ + /* ~(0x1e7) -> x1 */ + mov x1, #0x1e7 + neg x1, x1 + /* clear bit of L2 RAM -> x0 */ + and x0, x0, x1 + /* L2 Tag RAM latency (3 cycles) */ + orr x0, x0, #0x2 << 6 + /* If M3/M3N then L2 RAM setup is 0 */ + cbnz x2, M3_L2 + /* L2 Data RAM setup (1 cycle) */ + orr x0, x0, #0x1 << 5 +M3_L2: + /* L2 Data RAM latency (4 cycles) */ + orr x0, x0, #0x3 + /* Store data to L2CTLR_EL1 */ + msr CORTEX_A57_L2CTLR_EL1, x0 +apply_l2_ram_latencies: + ret +endfunc plat_reset_handler + + /* --------------------------------------------- + * void plat_invalidate_icache(void) + * Instruction Cache Invalidate All to PoU + * --------------------------------------------- + */ +func plat_invalidate_icache + ic iallu + + ret +endfunc plat_invalidate_icache diff --git a/plat/renesas/common/aarch64/platform_common.c b/plat/renesas/common/aarch64/platform_common.c new file mode 100644 index 000000000..b0a88cb6b --- /dev/null +++ b/plat/renesas/common/aarch64/platform_common.c @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rcar_def.h" +#include "rcar_private.h" +#include "rcar_version.h" + +#if (IMAGE_BL2) +extern void rcar_read_certificate(uint64_t cert, uint32_t *len, uintptr_t *p); +extern int32_t rcar_get_certificate(const int32_t name, uint32_t *cert); +#endif + +const uint8_t version_of_renesas[VERSION_OF_RENESAS_MAXLEN] + __attribute__ ((__section__("ro"))) = VERSION_OF_RENESAS; + +#define MAP_SHARED_RAM MAP_REGION_FLAT(RCAR_SHARED_MEM_BASE, \ + RCAR_SHARED_MEM_SIZE, \ + MT_MEMORY | MT_RW | MT_SECURE) + +#define MAP_FLASH0 MAP_REGION_FLAT(FLASH0_BASE, \ + FLASH0_SIZE, \ + MT_MEMORY | MT_RO | MT_SECURE) + +#define MAP_DRAM1_NS MAP_REGION_FLAT(DRAM1_NS_BASE, \ + DRAM1_NS_SIZE, \ + MT_MEMORY | MT_RW | MT_NS) + +#define MAP_DEVICE_RCAR MAP_REGION_FLAT(DEVICE_RCAR_BASE, \ + DEVICE_RCAR_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#define MAP_DEVICE_RCAR2 MAP_REGION_FLAT(DEVICE_RCAR_BASE2, \ + DEVICE_RCAR_SIZE2, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#define MAP_SRAM MAP_REGION_FLAT(DEVICE_SRAM_BASE, \ + DEVICE_SRAM_SIZE, \ + MT_MEMORY | MT_RO | MT_SECURE) + +#define MAP_SRAM_STACK MAP_REGION_FLAT(DEVICE_SRAM_STACK_BASE, \ + DEVICE_SRAM_STACK_SIZE, \ + MT_MEMORY | MT_RW | MT_SECURE) + +#define MAP_ATFW_CRASH MAP_REGION_FLAT(RCAR_BL31_CRASH_BASE, \ + RCAR_BL31_CRASH_SIZE, \ + MT_MEMORY | MT_RW | MT_SECURE) + +#define MAP_ATFW_LOG MAP_REGION_FLAT(RCAR_BL31_LOG_BASE, \ + RCAR_BL31_LOG_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) +#if IMAGE_BL2 +#define MAP_DRAM0 MAP_REGION_FLAT(DRAM1_BASE, \ + DRAM1_SIZE, \ + MT_MEMORY | MT_RW | MT_SECURE) + +#define MAP_REG0 MAP_REGION_FLAT(DEVICE_RCAR_BASE, \ + DEVICE_RCAR_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#define MAP_RAM0 MAP_REGION_FLAT(RCAR_SYSRAM_BASE, \ + RCAR_SYSRAM_SIZE, \ + MT_MEMORY | MT_RW | MT_SECURE) + +#define MAP_REG1 MAP_REGION_FLAT(REG1_BASE, \ + REG1_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#define MAP_ROM MAP_REGION_FLAT(ROM0_BASE, \ + ROM0_SIZE, \ + MT_MEMORY | MT_RO | MT_SECURE) + +#define MAP_REG2 MAP_REGION_FLAT(REG2_BASE, \ + REG2_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#define MAP_DRAM1 MAP_REGION_FLAT(DRAM_40BIT_BASE, \ + DRAM_40BIT_SIZE, \ + MT_MEMORY | MT_RW | MT_SECURE) +#endif + +#ifdef BL32_BASE +#define MAP_BL32_MEM MAP_REGION_FLAT(BL32_BASE, \ + BL32_LIMIT - BL32_BASE, \ + MT_MEMORY | MT_RW | MT_SECURE) +#endif + +#if IMAGE_BL2 +static const mmap_region_t rcar_mmap[] = { + MAP_FLASH0, /* 0x08000000 - 0x0BFFFFFF RPC area */ + MAP_DRAM0, /* 0x40000000 - 0xBFFFFFFF DRAM area(Legacy) */ + MAP_REG0, /* 0xE6000000 - 0xE62FFFFF SoC register area */ + MAP_RAM0, /* 0xE6300000 - 0xE6303FFF System RAM area */ + MAP_REG1, /* 0xE6400000 - 0xEAFFFFFF SoC register area */ + MAP_ROM, /* 0xEB100000 - 0xEB127FFF boot ROM area */ + MAP_REG2, /* 0xEC000000 - 0xFFFFFFFF SoC register area */ + MAP_DRAM1, /* 0x0400000000 - 0x07FFFFFFFF DRAM area(4GB over) */ + {0} +}; +#endif + +#if IMAGE_BL31 +static const mmap_region_t rcar_mmap[] = { + MAP_SHARED_RAM, + MAP_ATFW_CRASH, + MAP_ATFW_LOG, + MAP_DEVICE_RCAR, + MAP_DEVICE_RCAR2, + MAP_SRAM, + MAP_SRAM_STACK, + {0} +}; +#endif + +#if IMAGE_BL32 +static const mmap_region_t rcar_mmap[] = { + MAP_DEVICE0, + MAP_DEVICE1, + {0} +}; +#endif + +CASSERT(ARRAY_SIZE(rcar_mmap) + RCAR_BL_REGIONS + <= MAX_MMAP_REGIONS, assert_max_mmap_regions); + +/* + * Macro generating the code for the function setting up the pagetables as per + * the platform memory map & initialize the mmu, for the given exception level + */ +#if USE_COHERENT_MEM +void rcar_configure_mmu_el3(unsigned long total_base, + unsigned long total_size, + unsigned long ro_start, + unsigned long ro_limit, + unsigned long coh_start, + unsigned long coh_limit) +{ + mmap_add_region(total_base, total_base, total_size, + MT_MEMORY | MT_RW | MT_SECURE); + mmap_add_region(ro_start, ro_start, ro_limit - ro_start, + MT_MEMORY | MT_RO | MT_SECURE); + mmap_add_region(coh_start, coh_start, coh_limit - coh_start, + MT_DEVICE | MT_RW | MT_SECURE); + mmap_add(rcar_mmap); + + init_xlat_tables(); + enable_mmu_el3(0); +} +#else +void rcar_configure_mmu_el3(unsigned long total_base, + unsigned long total_size, + unsigned long ro_start, + unsigned long ro_limit) +{ + mmap_add_region(total_base, total_base, total_size, + MT_MEMORY | MT_RW | MT_SECURE); + mmap_add_region(ro_start, ro_start, ro_limit - ro_start, + MT_MEMORY | MT_RO | MT_SECURE); + mmap_add(rcar_mmap); + + init_xlat_tables(); + enable_mmu_el3(0); +} +#endif + +uintptr_t plat_get_ns_image_entrypoint(void) +{ +#if (IMAGE_BL2) + uint32_t cert, len; + uintptr_t dst; + int32_t ret; + + ret = rcar_get_certificate(NON_TRUSTED_FW_CONTENT_CERT_ID, &cert); + if (ret) { + ERROR("%s : cert file load error", __func__); + return NS_IMAGE_OFFSET; + } + + rcar_read_certificate((uint64_t) cert, &len, &dst); + + return dst; +#else + return NS_IMAGE_OFFSET; +#endif +} + +unsigned int plat_get_syscnt_freq2(void) +{ + unsigned int freq; + + freq = mmio_read_32(ARM_SYS_CNTCTL_BASE + CNTFID_OFF); + if (freq == 0) + panic(); + + return freq; +} + +void plat_rcar_gic_init(void) +{ + gicv2_distif_init(); + gicv2_pcpu_distif_init(); + gicv2_cpuif_enable(); +} + +static const interrupt_prop_t interrupt_props[] = { +#if IMAGE_BL2 + INTR_PROP_DESC(ARM_IRQ_SEC_WDT, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), +#else + INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE), + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE), + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE), + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE), + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE), + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE), + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE), + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE), + INTR_PROP_DESC(ARM_IRQ_SEC_RPC, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(ARM_IRQ_SEC_TIMER, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(ARM_IRQ_SEC_TIMER_UP, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(ARM_IRQ_SEC_WDT, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(ARM_IRQ_SEC_CRYPT, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(ARM_IRQ_SEC_CRYPT_SecPKA, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(ARM_IRQ_SEC_CRYPT_PubPKA, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), +#endif +}; + +static const gicv2_driver_data_t plat_gicv2_driver_data = { + .interrupt_props = interrupt_props, + .interrupt_props_num = (uint32_t) ARRAY_SIZE(interrupt_props), + .gicd_base = RCAR_GICD_BASE, + .gicc_base = RCAR_GICC_BASE, +}; + +void plat_rcar_gic_driver_init(void) +{ + gicv2_driver_init(&plat_gicv2_driver_data); +} diff --git a/plat/renesas/common/common.mk b/plat/renesas/common/common.mk index b342bdc08..cb0bb07b2 100644 --- a/plat/renesas/common/common.mk +++ b/plat/renesas/common/common.mk @@ -78,6 +78,8 @@ BL2_SOURCES += ${RCAR_GIC_SOURCES} \ lib/cpus/aarch64/cortex_a57.S \ ${LIBFDT_SRCS} \ common/desc_image_load.c \ + plat/renesas/common/aarch64/platform_common.c \ + plat/renesas/common/aarch64/plat_helpers.S \ drivers/renesas/common/console/rcar_printf.c \ drivers/renesas/common/scif/scif.S \ drivers/renesas/common/common.c \ @@ -103,6 +105,8 @@ BL31_SOURCES += ${RCAR_GIC_SOURCES} \ lib/cpus/aarch64/cortex_a53.S \ lib/cpus/aarch64/cortex_a57.S \ plat/common/plat_psci_common.c \ + plat/renesas/common/aarch64/plat_helpers.S \ + plat/renesas/common/aarch64/platform_common.c \ drivers/renesas/common/console/rcar_console.S \ drivers/renesas/common/console/rcar_printf.c \ drivers/renesas/common/delay/micro_delay.c \ diff --git a/plat/renesas/rcar/aarch64/plat_helpers.S b/plat/renesas/rcar/aarch64/plat_helpers.S deleted file mode 100644 index ec21f2510..000000000 --- a/plat/renesas/rcar/aarch64/plat_helpers.S +++ /dev/null @@ -1,392 +0,0 @@ -/* - * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. - * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include -#include -#include -#include - -#include "rcar_def.h" - - .globl plat_get_my_entrypoint - .extern plat_set_my_stack - .globl platform_mem_init - - .globl plat_crash_console_init - .globl plat_crash_console_putc - .globl plat_crash_console_flush - .globl plat_invalidate_icache - .globl plat_report_exception - .globl plat_secondary_reset - .globl plat_reset_handler - .globl plat_my_core_pos - .extern rcar_log_init - - .extern console_rcar_init - .extern console_rcar_putc - .extern console_rcar_flush - -#if IMAGE_BL2 - #define INT_ID_MASK (0x3ff) - .extern bl2_interrupt_error_type - .extern bl2_interrupt_error_id - .globl bl2_enter_bl31 - .extern gicv2_acknowledge_interrupt - .extern rcar_swdt_exec -#endif - - /* ----------------------------------------------------- - * void platform_get_core_pos (mpidr) - * ----------------------------------------------------- - */ -func platform_get_core_pos - and x1, x0, #MPIDR_CPU_MASK - and x0, x0, #MPIDR_CLUSTER_MASK - add x0, x1, x0, LSR #6 - ret -endfunc platform_get_core_pos - - /* ----------------------------------------------------- - * void platform_my_core_pos - * ----------------------------------------------------- - */ -func plat_my_core_pos - mrs x0, mpidr_el1 - b platform_get_core_pos -endfunc plat_my_core_pos - - /* ----------------------------------------------------- - * void platform_get_my_entrypoint (unsigned int mpid); - * - * Main job of this routine is to distinguish between - * a cold and warm boot. - * On a cold boot the secondaries first wait for the - * platform to be initialized after which they are - * hotplugged in. The primary proceeds to perform the - * platform initialization. - * On a warm boot, each cpu jumps to the address in its - * mailbox. - * - * TODO: Not a good idea to save lr in a temp reg - * ----------------------------------------------------- - */ -func plat_get_my_entrypoint - mrs x0, mpidr_el1 - mov x9, x30 /* lr */ - -#if defined(IMAGE_BL2) - /* always cold boot on bl2 */ - mov x0, #0 - ret x9 -#else - ldr x1, =BOOT_KIND_BASE - ldr x21, [x1] - - /* Check the reset info */ - and x1, x21, #0x000c - cmp x1, #0x0008 - beq el3_panic - cmp x1, #0x000c - beq el3_panic - - /* Check the boot kind */ - and x1, x21, #0x0003 - cmp x1, #0x0002 - beq el3_panic - cmp x1, #0x0003 - beq el3_panic - - /* warm boot or cold boot */ - and x1, x21, #1 - cmp x1, #0 - bne warm_reset - - /* Cold boot */ - mov x0, #0 - b exit - -warm_reset: - /* -------------------------------------------------------------------- - * A per-cpu mailbox is maintained in the trusted SDRAM. Its flushed out - * of the caches after every update using normal memory so its safe to - * read it here with SO attributes - * --------------------------------------------------------------------- - */ - ldr x10, =MBOX_BASE - bl platform_get_core_pos - lsl x0, x0, #CACHE_WRITEBACK_SHIFT - ldr x0, [x10, x0] - cbz x0, _panic -exit: - ret x9 -_panic: - b do_panic -#endif - -endfunc plat_get_my_entrypoint - - /* --------------------------------------------- - * plat_secondary_reset - * - * --------------------------------------------- - */ -func plat_secondary_reset - mrs x0, sctlr_el3 - bic x0, x0, #SCTLR_EE_BIT - msr sctlr_el3, x0 - isb - - mrs x0, cptr_el3 - bic w0, w0, #TCPAC_BIT - bic w0, w0, #TTA_BIT - bic w0, w0, #TFP_BIT - msr cptr_el3, x0 - - mov_imm x0, PARAMS_BASE - mov_imm x2, BL31_BASE - ldr x3, =BOOT_KIND_BASE - mov x1, #0x1 - str x1, [x3] - br x2 /* jump to BL31 */ - nop - nop - nop -endfunc plat_secondary_reset - - /* --------------------------------------------- - * plat_enter_bl31 - * - * --------------------------------------------- - */ -func bl2_enter_bl31 - 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. - */ -#if RCAR_BL2_DCACHE == 1 - /* Disable mmu and data cache */ - bl disable_mmu_el3 - /* Data cache clean and invalidate */ - mov x0, #DCCISW - bl dcsw_op_all - /* TLB invalidate all, EL3 */ - tlbi alle3 -#endif /* RCAR_BL2_DCACHE == 1 */ - bl disable_mmu_icache_el3 - /* Invalidate instruction cache */ - ic iallu - dsb sy - isb - ldp x0, x1, [x20, #ENTRY_POINT_INFO_PC_OFFSET] - msr elr_el3, x0 - msr spsr_el3, x1 - exception_return -endfunc bl2_enter_bl31 - - /* ----------------------------------------------------- - * void platform_mem_init (void); - * - * Zero out the mailbox registers in the shared memory - * and set the rcar_boot_kind_flag. - * The mmu is turned off right now and only the primary can - * ever execute this code. Secondaries will read the - * mailboxes using SO accesses. - * ----------------------------------------------------- - */ -func platform_mem_init -#if !IMAGE_BL2 - ldr x0, =MBOX_BASE - mov w1, #PLATFORM_CORE_COUNT -loop: - str xzr, [x0], #CACHE_WRITEBACK_GRANULE - subs w1, w1, #1 - b.gt loop -#endif - ret -endfunc platform_mem_init - - /* --------------------------------------------- - * void plat_report_exception(unsigned int type) - * Function to report an unhandled exception - * with platform-specific means. - * --------------------------------------------- - */ -func plat_report_exception - /* Switch to SP_EL0 */ - msr spsel, #0 -#if IMAGE_BL2 - mov w1, #FIQ_SP_EL0 - cmp w0, w1 - beq rep_exec_fiq_elx - b rep_exec_panic_type -rep_exec_fiq_elx: - bl gicv2_acknowledge_interrupt - mov x2, #INT_ID_MASK - and x0, x0, x2 - mov x1, #ARM_IRQ_SEC_WDT - cmp x0, x1 - bne rep_exec_panic_id - mrs x0, ELR_EL3 - b rcar_swdt_exec -rep_exec_panic_type: - /* x0 is interrupt TYPE */ - b bl2_interrupt_error_type -rep_exec_panic_id: - /* x0 is interrupt ID */ - b bl2_interrupt_error_id -rep_exec_end: -#endif - ret -endfunc plat_report_exception - - /* --------------------------------------------- - * int plat_crash_console_init(void) - * Function to initialize log area - * --------------------------------------------- - */ -func plat_crash_console_init -#if IMAGE_BL2 - mov x0, #0 -#else - mov x1, sp - mov_imm x2, RCAR_CRASH_STACK - mov sp, x2 - str x1, [sp, #-16]! - str x30, [sp, #-16]! - bl console_rcar_init - ldr x30, [sp], #16 - ldr x1, [sp], #16 - mov sp, x1 -#endif - ret -endfunc plat_crash_console_init - - /* --------------------------------------------- - * int plat_crash_console_putc(int c) - * Function to store a character to log area - * --------------------------------------------- - */ -func plat_crash_console_putc - mov x1, sp - mov_imm x2, RCAR_CRASH_STACK - mov sp, x2 - str x1, [sp, #-16]! - str x30, [sp, #-16]! - str x3, [sp, #-16]! - str x4, [sp, #-16]! - str x5, [sp, #-16]! - bl console_rcar_putc - ldr x5, [sp], #16 - ldr x4, [sp], #16 - ldr x3, [sp], #16 - ldr x30, [sp], #16 - ldr x1, [sp], #16 - mov sp, x1 - ret -endfunc plat_crash_console_putc - - /* --------------------------------------------- - * void plat_crash_console_flush() - * --------------------------------------------- - */ -func plat_crash_console_flush - b console_rcar_flush -endfunc plat_crash_console_flush - - /* -------------------------------------------------------------------- - * void plat_reset_handler(void); - * - * Before adding code in this function, refer to the guidelines in - * docs/firmware-design.md to determine whether the code should reside - * within the FIRST_RESET_HANDLER_CALL block or not. - * - * For R-Car H3: - * - Set the L2 Tag RAM latency to 2 (i.e. 3 cycles) for Cortex-A57 - * - Set the L2 Data setup latency to 1 (i.e. 1 cycles) for Cortex-A57 - * - Set the L2 Data RAM latency to 3 (i.e. 4 cycles) for Cortex-A57 - * For R-Car M3/M3N: - * - Set the L2 Tag RAM latency to 2 (i.e. 3 cycles) for Cortex-A57 - * - Set the L2 Data setup latency to 0 (i.e. 0 cycles) for Cortex-A57 - * - Set the L2 Data RAM latency to 3 (i.e. 4 cycles) for Cortex-A57 - * - * -------------------------------------------------------------------- - */ -func plat_reset_handler - /* - * On R-Car H3 : x2 := 0 - * On R-Car M3/M3N: x2 := 1 - */ - /* read PRR */ - ldr x0, =0xFFF00044 - ldr w0, [x0] - ubfx w0, w0, 8, 8 - /* H3? */ - cmp w0, #0x4F - b.eq RCARH3 - /* set R-Car M3/M3N */ - mov x2, #1 - b CHK_A5x -RCARH3: - /* set R-Car H3 */ - mov x2, #0 - /* -------------------------------------------------------------------- - * Determine whether this code is executed on a Cortex-A53 or on a - * Cortex-A57 core. - * -------------------------------------------------------------------- - */ -CHK_A5x: - mrs x0, midr_el1 - ubfx x1, x0, MIDR_PN_SHIFT, #12 - cmp w1, #((CORTEX_A57_MIDR >> MIDR_PN_SHIFT) & MIDR_PN_MASK) - b.eq A57 - ret -A57: - /* Get data from CORTEX_A57_L2CTLR_EL1 */ - mrs x0, CORTEX_A57_L2CTLR_EL1 - /* - * On R-Car H3/M3/M3N - * - * L2 Tag RAM latency is bit8-6 of CORTEX_A57_L2CTLR_EL1 - * L2 Data RAM setup is bit5 of CORTEX_A57_L2CTLR_EL1 - * L2 Data RAM latency is bit2-0 of CORTEX_A57_L2CTLR_EL1 - */ - /* clear bit of L2 RAM */ - /* ~(0x1e7) -> x1 */ - mov x1, #0x1e7 - neg x1, x1 - /* clear bit of L2 RAM -> x0 */ - and x0, x0, x1 - /* L2 Tag RAM latency (3 cycles) */ - orr x0, x0, #0x2 << 6 - /* If M3/M3N then L2 RAM setup is 0 */ - cbnz x2, M3_L2 - /* L2 Data RAM setup (1 cycle) */ - orr x0, x0, #0x1 << 5 -M3_L2: - /* L2 Data RAM latency (4 cycles) */ - orr x0, x0, #0x3 - /* Store data to L2CTLR_EL1 */ - msr CORTEX_A57_L2CTLR_EL1, x0 -apply_l2_ram_latencies: - ret -endfunc plat_reset_handler - - /* --------------------------------------------- - * void plat_invalidate_icache(void) - * Instruction Cache Invalidate All to PoU - * --------------------------------------------- - */ -func plat_invalidate_icache - ic iallu - - ret -endfunc plat_invalidate_icache diff --git a/plat/renesas/rcar/aarch64/platform_common.c b/plat/renesas/rcar/aarch64/platform_common.c deleted file mode 100644 index b0a88cb6b..000000000 --- a/plat/renesas/rcar/aarch64/platform_common.c +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. - * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "rcar_def.h" -#include "rcar_private.h" -#include "rcar_version.h" - -#if (IMAGE_BL2) -extern void rcar_read_certificate(uint64_t cert, uint32_t *len, uintptr_t *p); -extern int32_t rcar_get_certificate(const int32_t name, uint32_t *cert); -#endif - -const uint8_t version_of_renesas[VERSION_OF_RENESAS_MAXLEN] - __attribute__ ((__section__("ro"))) = VERSION_OF_RENESAS; - -#define MAP_SHARED_RAM MAP_REGION_FLAT(RCAR_SHARED_MEM_BASE, \ - RCAR_SHARED_MEM_SIZE, \ - MT_MEMORY | MT_RW | MT_SECURE) - -#define MAP_FLASH0 MAP_REGION_FLAT(FLASH0_BASE, \ - FLASH0_SIZE, \ - MT_MEMORY | MT_RO | MT_SECURE) - -#define MAP_DRAM1_NS MAP_REGION_FLAT(DRAM1_NS_BASE, \ - DRAM1_NS_SIZE, \ - MT_MEMORY | MT_RW | MT_NS) - -#define MAP_DEVICE_RCAR MAP_REGION_FLAT(DEVICE_RCAR_BASE, \ - DEVICE_RCAR_SIZE, \ - MT_DEVICE | MT_RW | MT_SECURE) - -#define MAP_DEVICE_RCAR2 MAP_REGION_FLAT(DEVICE_RCAR_BASE2, \ - DEVICE_RCAR_SIZE2, \ - MT_DEVICE | MT_RW | MT_SECURE) - -#define MAP_SRAM MAP_REGION_FLAT(DEVICE_SRAM_BASE, \ - DEVICE_SRAM_SIZE, \ - MT_MEMORY | MT_RO | MT_SECURE) - -#define MAP_SRAM_STACK MAP_REGION_FLAT(DEVICE_SRAM_STACK_BASE, \ - DEVICE_SRAM_STACK_SIZE, \ - MT_MEMORY | MT_RW | MT_SECURE) - -#define MAP_ATFW_CRASH MAP_REGION_FLAT(RCAR_BL31_CRASH_BASE, \ - RCAR_BL31_CRASH_SIZE, \ - MT_MEMORY | MT_RW | MT_SECURE) - -#define MAP_ATFW_LOG MAP_REGION_FLAT(RCAR_BL31_LOG_BASE, \ - RCAR_BL31_LOG_SIZE, \ - MT_DEVICE | MT_RW | MT_SECURE) -#if IMAGE_BL2 -#define MAP_DRAM0 MAP_REGION_FLAT(DRAM1_BASE, \ - DRAM1_SIZE, \ - MT_MEMORY | MT_RW | MT_SECURE) - -#define MAP_REG0 MAP_REGION_FLAT(DEVICE_RCAR_BASE, \ - DEVICE_RCAR_SIZE, \ - MT_DEVICE | MT_RW | MT_SECURE) - -#define MAP_RAM0 MAP_REGION_FLAT(RCAR_SYSRAM_BASE, \ - RCAR_SYSRAM_SIZE, \ - MT_MEMORY | MT_RW | MT_SECURE) - -#define MAP_REG1 MAP_REGION_FLAT(REG1_BASE, \ - REG1_SIZE, \ - MT_DEVICE | MT_RW | MT_SECURE) - -#define MAP_ROM MAP_REGION_FLAT(ROM0_BASE, \ - ROM0_SIZE, \ - MT_MEMORY | MT_RO | MT_SECURE) - -#define MAP_REG2 MAP_REGION_FLAT(REG2_BASE, \ - REG2_SIZE, \ - MT_DEVICE | MT_RW | MT_SECURE) - -#define MAP_DRAM1 MAP_REGION_FLAT(DRAM_40BIT_BASE, \ - DRAM_40BIT_SIZE, \ - MT_MEMORY | MT_RW | MT_SECURE) -#endif - -#ifdef BL32_BASE -#define MAP_BL32_MEM MAP_REGION_FLAT(BL32_BASE, \ - BL32_LIMIT - BL32_BASE, \ - MT_MEMORY | MT_RW | MT_SECURE) -#endif - -#if IMAGE_BL2 -static const mmap_region_t rcar_mmap[] = { - MAP_FLASH0, /* 0x08000000 - 0x0BFFFFFF RPC area */ - MAP_DRAM0, /* 0x40000000 - 0xBFFFFFFF DRAM area(Legacy) */ - MAP_REG0, /* 0xE6000000 - 0xE62FFFFF SoC register area */ - MAP_RAM0, /* 0xE6300000 - 0xE6303FFF System RAM area */ - MAP_REG1, /* 0xE6400000 - 0xEAFFFFFF SoC register area */ - MAP_ROM, /* 0xEB100000 - 0xEB127FFF boot ROM area */ - MAP_REG2, /* 0xEC000000 - 0xFFFFFFFF SoC register area */ - MAP_DRAM1, /* 0x0400000000 - 0x07FFFFFFFF DRAM area(4GB over) */ - {0} -}; -#endif - -#if IMAGE_BL31 -static const mmap_region_t rcar_mmap[] = { - MAP_SHARED_RAM, - MAP_ATFW_CRASH, - MAP_ATFW_LOG, - MAP_DEVICE_RCAR, - MAP_DEVICE_RCAR2, - MAP_SRAM, - MAP_SRAM_STACK, - {0} -}; -#endif - -#if IMAGE_BL32 -static const mmap_region_t rcar_mmap[] = { - MAP_DEVICE0, - MAP_DEVICE1, - {0} -}; -#endif - -CASSERT(ARRAY_SIZE(rcar_mmap) + RCAR_BL_REGIONS - <= MAX_MMAP_REGIONS, assert_max_mmap_regions); - -/* - * Macro generating the code for the function setting up the pagetables as per - * the platform memory map & initialize the mmu, for the given exception level - */ -#if USE_COHERENT_MEM -void rcar_configure_mmu_el3(unsigned long total_base, - unsigned long total_size, - unsigned long ro_start, - unsigned long ro_limit, - unsigned long coh_start, - unsigned long coh_limit) -{ - mmap_add_region(total_base, total_base, total_size, - MT_MEMORY | MT_RW | MT_SECURE); - mmap_add_region(ro_start, ro_start, ro_limit - ro_start, - MT_MEMORY | MT_RO | MT_SECURE); - mmap_add_region(coh_start, coh_start, coh_limit - coh_start, - MT_DEVICE | MT_RW | MT_SECURE); - mmap_add(rcar_mmap); - - init_xlat_tables(); - enable_mmu_el3(0); -} -#else -void rcar_configure_mmu_el3(unsigned long total_base, - unsigned long total_size, - unsigned long ro_start, - unsigned long ro_limit) -{ - mmap_add_region(total_base, total_base, total_size, - MT_MEMORY | MT_RW | MT_SECURE); - mmap_add_region(ro_start, ro_start, ro_limit - ro_start, - MT_MEMORY | MT_RO | MT_SECURE); - mmap_add(rcar_mmap); - - init_xlat_tables(); - enable_mmu_el3(0); -} -#endif - -uintptr_t plat_get_ns_image_entrypoint(void) -{ -#if (IMAGE_BL2) - uint32_t cert, len; - uintptr_t dst; - int32_t ret; - - ret = rcar_get_certificate(NON_TRUSTED_FW_CONTENT_CERT_ID, &cert); - if (ret) { - ERROR("%s : cert file load error", __func__); - return NS_IMAGE_OFFSET; - } - - rcar_read_certificate((uint64_t) cert, &len, &dst); - - return dst; -#else - return NS_IMAGE_OFFSET; -#endif -} - -unsigned int plat_get_syscnt_freq2(void) -{ - unsigned int freq; - - freq = mmio_read_32(ARM_SYS_CNTCTL_BASE + CNTFID_OFF); - if (freq == 0) - panic(); - - return freq; -} - -void plat_rcar_gic_init(void) -{ - gicv2_distif_init(); - gicv2_pcpu_distif_init(); - gicv2_cpuif_enable(); -} - -static const interrupt_prop_t interrupt_props[] = { -#if IMAGE_BL2 - INTR_PROP_DESC(ARM_IRQ_SEC_WDT, GIC_HIGHEST_SEC_PRIORITY, - GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), -#else - INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, - GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), - INTR_PROP_DESC(ARM_IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, - GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE), - INTR_PROP_DESC(ARM_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, - GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE), - INTR_PROP_DESC(ARM_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, - GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE), - INTR_PROP_DESC(ARM_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, - GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE), - INTR_PROP_DESC(ARM_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, - GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE), - INTR_PROP_DESC(ARM_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, - GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE), - INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, - GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE), - INTR_PROP_DESC(ARM_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, - GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE), - INTR_PROP_DESC(ARM_IRQ_SEC_RPC, GIC_HIGHEST_SEC_PRIORITY, - GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), - INTR_PROP_DESC(ARM_IRQ_SEC_TIMER, GIC_HIGHEST_SEC_PRIORITY, - GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), - INTR_PROP_DESC(ARM_IRQ_SEC_TIMER_UP, GIC_HIGHEST_SEC_PRIORITY, - GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), - INTR_PROP_DESC(ARM_IRQ_SEC_WDT, GIC_HIGHEST_SEC_PRIORITY, - GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), - INTR_PROP_DESC(ARM_IRQ_SEC_CRYPT, GIC_HIGHEST_SEC_PRIORITY, - GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), - INTR_PROP_DESC(ARM_IRQ_SEC_CRYPT_SecPKA, GIC_HIGHEST_SEC_PRIORITY, - GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), - INTR_PROP_DESC(ARM_IRQ_SEC_CRYPT_PubPKA, GIC_HIGHEST_SEC_PRIORITY, - GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), -#endif -}; - -static const gicv2_driver_data_t plat_gicv2_driver_data = { - .interrupt_props = interrupt_props, - .interrupt_props_num = (uint32_t) ARRAY_SIZE(interrupt_props), - .gicd_base = RCAR_GICD_BASE, - .gicc_base = RCAR_GICC_BASE, -}; - -void plat_rcar_gic_driver_init(void) -{ - gicv2_driver_init(&plat_gicv2_driver_data); -} diff --git a/plat/renesas/rcar/platform.mk b/plat/renesas/rcar/platform.mk index a861c7c7c..ee393f2f4 100644 --- a/plat/renesas/rcar/platform.mk +++ b/plat/renesas/rcar/platform.mk @@ -312,9 +312,7 @@ PLAT_INCLUDES += -Idrivers/renesas/rcar/ddr \ -Idrivers/renesas/common/pwrc \ -Idrivers/renesas/common/io -BL2_SOURCES += plat/renesas/rcar/aarch64/platform_common.c \ - plat/renesas/rcar/aarch64/plat_helpers.S \ - plat/renesas/rcar/bl2_interrupt_error.c \ +BL2_SOURCES += plat/renesas/rcar/bl2_interrupt_error.c \ plat/renesas/rcar/bl2_secure_setting.c \ plat/renesas/rcar/bl2_plat_setup.c \ plat/renesas/rcar/plat_storage.c \ @@ -324,8 +322,6 @@ BL2_SOURCES += plat/renesas/rcar/aarch64/platform_common.c \ drivers/renesas/rcar/board/board.c BL31_SOURCES += plat/renesas/rcar/plat_topology.c \ - plat/renesas/rcar/aarch64/plat_helpers.S \ - plat/renesas/rcar/aarch64/platform_common.c \ plat/renesas/rcar/bl31_plat_setup.c \ plat/renesas/rcar/plat_pm.c -- cgit v1.2.3 From 499c2713f05c602e6f22467c18be30cf9697c42d Mon Sep 17 00:00:00 2001 From: Biju Das Date: Wed, 16 Dec 2020 11:28:07 +0000 Subject: plat: renesas: Move to common Move rcar plat code to common directory, so that the same code can be re-used by both R-Car Gen3 and RZ/G2 platforms. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: I1001bea1a8a9232a03ddbf6931ca3c764ba1e181 --- plat/renesas/common/bl2_cpg_init.c | 424 +++++++++++++++++++++++++ plat/renesas/common/bl2_interrupt_error.c | 109 +++++++ plat/renesas/common/bl2_plat_mem_params_desc.c | 88 +++++ plat/renesas/common/bl2_secure_setting.c | 362 +++++++++++++++++++++ plat/renesas/common/bl31_plat_setup.c | 132 ++++++++ plat/renesas/common/common.mk | 9 + plat/renesas/common/plat_image_load.c | 38 +++ plat/renesas/common/plat_pm.c | 308 ++++++++++++++++++ plat/renesas/common/plat_storage.c | 417 ++++++++++++++++++++++++ plat/renesas/common/plat_topology.c | 47 +++ plat/renesas/rcar/bl2_cpg_init.c | 424 ------------------------- plat/renesas/rcar/bl2_interrupt_error.c | 109 ------- plat/renesas/rcar/bl2_plat_mem_params_desc.c | 88 ----- plat/renesas/rcar/bl2_secure_setting.c | 362 --------------------- plat/renesas/rcar/bl31_plat_setup.c | 132 -------- plat/renesas/rcar/plat_image_load.c | 38 --- plat/renesas/rcar/plat_pm.c | 308 ------------------ plat/renesas/rcar/plat_storage.c | 417 ------------------------ plat/renesas/rcar/plat_topology.c | 47 --- plat/renesas/rcar/platform.mk | 12 +- 20 files changed, 1935 insertions(+), 1936 deletions(-) create mode 100644 plat/renesas/common/bl2_cpg_init.c create mode 100644 plat/renesas/common/bl2_interrupt_error.c create mode 100644 plat/renesas/common/bl2_plat_mem_params_desc.c create mode 100644 plat/renesas/common/bl2_secure_setting.c create mode 100644 plat/renesas/common/bl31_plat_setup.c create mode 100644 plat/renesas/common/plat_image_load.c create mode 100644 plat/renesas/common/plat_pm.c create mode 100644 plat/renesas/common/plat_storage.c create mode 100644 plat/renesas/common/plat_topology.c delete mode 100644 plat/renesas/rcar/bl2_cpg_init.c delete mode 100644 plat/renesas/rcar/bl2_interrupt_error.c delete mode 100644 plat/renesas/rcar/bl2_plat_mem_params_desc.c delete mode 100644 plat/renesas/rcar/bl2_secure_setting.c delete mode 100644 plat/renesas/rcar/bl31_plat_setup.c delete mode 100644 plat/renesas/rcar/plat_image_load.c delete mode 100644 plat/renesas/rcar/plat_pm.c delete mode 100644 plat/renesas/rcar/plat_storage.c delete mode 100644 plat/renesas/rcar/plat_topology.c diff --git a/plat/renesas/common/bl2_cpg_init.c b/plat/renesas/common/bl2_cpg_init.c new file mode 100644 index 000000000..175434469 --- /dev/null +++ b/plat/renesas/common/bl2_cpg_init.c @@ -0,0 +1,424 @@ +/* + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include "cpg_registers.h" +#include "rcar_def.h" +#include "rcar_private.h" + +static void bl2_secure_cpg_init(void); + +#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_H3) || (RCAR_LSI == RCAR_H3N) +static void bl2_realtime_cpg_init_h3(void); +static void bl2_system_cpg_init_h3(void); +#endif + +#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_M3) +static void bl2_realtime_cpg_init_m3(void); +static void bl2_system_cpg_init_m3(void); +#endif + +#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_M3N) +static void bl2_realtime_cpg_init_m3n(void); +static void bl2_system_cpg_init_m3n(void); +#endif + +#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_V3M) +static void bl2_realtime_cpg_init_v3m(void); +static void bl2_system_cpg_init_v3m(void); +#endif + +#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_E3) +static void bl2_realtime_cpg_init_e3(void); +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 + +typedef struct { + uintptr_t adr; + uint32_t val; +} reg_setting_t; + +static void bl2_secure_cpg_init(void) +{ + uint32_t stop_cr2, reset_cr2; + uint32_t stop_cr4, reset_cr4; + uint32_t stop_cr5, reset_cr5; + +#if (RCAR_LSI == RCAR_D3) + reset_cr2 = 0x00000000U; + stop_cr2 = 0xFFFFFFFFU; +#elif (RCAR_LSI == RCAR_E3) + reset_cr2 = 0x10000000U; + stop_cr2 = 0xEFFFFFFFU; +#else + reset_cr2 = 0x14000000U; + stop_cr2 = 0xEBFFFFFFU; +#endif + +#if (RCAR_LSI == RCAR_D3) + reset_cr4 = 0x00000000U; + stop_cr4 = 0xFFFFFFFFU; + reset_cr5 = 0x00000000U; + stop_cr5 = 0xFFFFFFFFU; +#else + reset_cr4 = 0x80000003U; + stop_cr4 = 0x7FFFFFFFU; + reset_cr5 = 0x40000000U; + stop_cr5 = 0xBFFFFFFFU; +#endif + + /* Secure Module Stop Control Registers */ + cpg_write(SCMSTPCR0, 0xFFFFFFFFU); + cpg_write(SCMSTPCR1, 0xFFFFFFFFU); + cpg_write(SCMSTPCR2, stop_cr2); + cpg_write(SCMSTPCR3, 0xFFFFFFFFU); + cpg_write(SCMSTPCR4, stop_cr4); + cpg_write(SCMSTPCR5, stop_cr5); + cpg_write(SCMSTPCR6, 0xFFFFFFFFU); + cpg_write(SCMSTPCR7, 0xFFFFFFFFU); + cpg_write(SCMSTPCR8, 0xFFFFFFFFU); + cpg_write(SCMSTPCR9, 0xFFFDFFFFU); + cpg_write(SCMSTPCR10, 0xFFFFFFFFU); + cpg_write(SCMSTPCR11, 0xFFFFFFFFU); + + /* Secure Software Reset Access Enable Control Registers */ + cpg_write(SCSRSTECR0, 0x00000000U); + cpg_write(SCSRSTECR1, 0x00000000U); + cpg_write(SCSRSTECR2, reset_cr2); + cpg_write(SCSRSTECR3, 0x00000000U); + cpg_write(SCSRSTECR4, reset_cr4); + cpg_write(SCSRSTECR5, reset_cr5); + cpg_write(SCSRSTECR6, 0x00000000U); + cpg_write(SCSRSTECR7, 0x00000000U); + cpg_write(SCSRSTECR8, 0x00000000U); + cpg_write(SCSRSTECR9, 0x00020000U); + cpg_write(SCSRSTECR10, 0x00000000U); + cpg_write(SCSRSTECR11, 0x00000000U); +} + +#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_H3) || (RCAR_LSI == RCAR_H3N) +static void bl2_realtime_cpg_init_h3(void) +{ + uint32_t cut = mmio_read_32(RCAR_PRR) & PRR_CUT_MASK; + uint32_t cr0, cr8; + + cr0 = (cut == PRR_PRODUCT_10 || cut == PRR_PRODUCT_11) ? + 0x00200000U : 0x00210000U; + cr8 = (cut == PRR_PRODUCT_10 || cut == PRR_PRODUCT_11) ? + 0x01F1FFF4U : 0x01F1FFF7U; + + cpg_write(RMSTPCR0, cr0); + cpg_write(RMSTPCR1, 0xFFFFFFFFU); + cpg_write(RMSTPCR2, 0x040E0FDCU); + cpg_write(RMSTPCR3, 0xFFFFFFDFU); + cpg_write(RMSTPCR4, 0x80000004U); + cpg_write(RMSTPCR5, 0xC3FFFFFFU); + cpg_write(RMSTPCR6, 0xFFFFFFFFU); + cpg_write(RMSTPCR7, 0xFFFFFFFFU); + cpg_write(RMSTPCR8, cr8); + cpg_write(RMSTPCR9, 0xFFFFFFFEU); + cpg_write(RMSTPCR10, 0xFFFEFFE0U); + cpg_write(RMSTPCR11, 0x000000B7U); +} + +static void bl2_system_cpg_init_h3(void) +{ + /** System Module Stop Control Registers */ + cpg_write(SMSTPCR0, 0x00210000U); + cpg_write(SMSTPCR1, 0xFFFFFFFFU); + cpg_write(SMSTPCR2, 0x040E2FDCU); + cpg_write(SMSTPCR3, 0xFFFFFBDFU); + cpg_write(SMSTPCR4, 0x80000004U); + cpg_write(SMSTPCR5, 0xC3FFFFFFU); + cpg_write(SMSTPCR6, 0xFFFFFFFFU); + cpg_write(SMSTPCR7, 0xFFFFFFFFU); + cpg_write(SMSTPCR8, 0x01F1FFF5U); + cpg_write(SMSTPCR9, 0xFFFFFFFFU); + cpg_write(SMSTPCR10, 0xFFFEFFE0U); + cpg_write(SMSTPCR11, 0x000000B7U); +} +#endif + +#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_M3) +static void bl2_realtime_cpg_init_m3(void) +{ + /* Realtime Module Stop Control Registers */ + cpg_write(RMSTPCR0, 0x00200000U); + cpg_write(RMSTPCR1, 0xFFFFFFFFU); + cpg_write(RMSTPCR2, 0x040E0FDCU); + cpg_write(RMSTPCR3, 0xFFFFFFDFU); + cpg_write(RMSTPCR4, 0x80000004U); + cpg_write(RMSTPCR5, 0xC3FFFFFFU); + cpg_write(RMSTPCR6, 0xFFFFFFFFU); + cpg_write(RMSTPCR7, 0xFFFFFFFFU); + cpg_write(RMSTPCR8, 0x01F1FFF7U); + cpg_write(RMSTPCR9, 0xFFFFFFFEU); + cpg_write(RMSTPCR10, 0xFFFEFFE0U); + cpg_write(RMSTPCR11, 0x000000B7U); +} + +static void bl2_system_cpg_init_m3(void) +{ + /* System Module Stop Control Registers */ + cpg_write(SMSTPCR0, 0x00200000U); + cpg_write(SMSTPCR1, 0xFFFFFFFFU); + cpg_write(SMSTPCR2, 0x040E2FDCU); + cpg_write(SMSTPCR3, 0xFFFFFBDFU); + cpg_write(SMSTPCR4, 0x80000004U); + cpg_write(SMSTPCR5, 0xC3FFFFFFU); + cpg_write(SMSTPCR6, 0xFFFFFFFFU); + cpg_write(SMSTPCR7, 0xFFFFFFFFU); + cpg_write(SMSTPCR8, 0x01F1FFF7U); + cpg_write(SMSTPCR9, 0xFFFFFFFFU); + cpg_write(SMSTPCR10, 0xFFFEFFE0U); + cpg_write(SMSTPCR11, 0x000000B7U); +} +#endif + +#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_M3N) +static void bl2_realtime_cpg_init_m3n(void) +{ + /* Realtime Module Stop Control Registers */ + cpg_write(RMSTPCR0, 0x00210000U); + cpg_write(RMSTPCR1, 0xFFFFFFFFU); + cpg_write(RMSTPCR2, 0x040E0FDCU); + cpg_write(RMSTPCR3, 0xFFFFFFDFU); + cpg_write(RMSTPCR4, 0x80000004U); + cpg_write(RMSTPCR5, 0xC3FFFFFFU); + cpg_write(RMSTPCR6, 0xFFFFFFFFU); + cpg_write(RMSTPCR7, 0xFFFFFFFFU); + cpg_write(RMSTPCR8, 0x00F1FFF7U); + cpg_write(RMSTPCR9, 0xFFFFFFFFU); + cpg_write(RMSTPCR10, 0xFFFFFFE0U); + cpg_write(RMSTPCR11, 0x000000B7U); +} + +static void bl2_system_cpg_init_m3n(void) +{ + /* System Module Stop Control Registers */ + cpg_write(SMSTPCR0, 0x00210000U); + cpg_write(SMSTPCR1, 0xFFFFFFFFU); + cpg_write(SMSTPCR2, 0x040E2FDCU); + cpg_write(SMSTPCR3, 0xFFFFFBDFU); + cpg_write(SMSTPCR4, 0x80000004U); + cpg_write(SMSTPCR5, 0xC3FFFFFFU); + cpg_write(SMSTPCR6, 0xFFFFFFFFU); + cpg_write(SMSTPCR7, 0xFFFFFFFFU); + cpg_write(SMSTPCR8, 0x00F1FFF7U); + cpg_write(SMSTPCR9, 0xFFFFFFFFU); + cpg_write(SMSTPCR10, 0xFFFFFFE0U); + cpg_write(SMSTPCR11, 0x000000B7U); +} +#endif + +#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_V3M) +static void bl2_realtime_cpg_init_v3m(void) +{ + /* Realtime Module Stop Control Registers */ + cpg_write(RMSTPCR0, 0x00230000U); + cpg_write(RMSTPCR1, 0xFFFFFFFFU); + cpg_write(RMSTPCR2, 0x14062FD8U); + cpg_write(RMSTPCR3, 0xFFFFFFDFU); + cpg_write(RMSTPCR4, 0x80000184U); + cpg_write(RMSTPCR5, 0x83FFFFFFU); + cpg_write(RMSTPCR6, 0xFFFFFFFFU); + cpg_write(RMSTPCR7, 0xFFFFFFFFU); + cpg_write(RMSTPCR8, 0x7FF3FFF4U); + cpg_write(RMSTPCR9, 0xFFFFFFFEU); +} + +static void bl2_system_cpg_init_v3m(void) +{ + /* System Module Stop Control Registers */ + cpg_write(SMSTPCR0, 0x00210000U); + cpg_write(SMSTPCR1, 0xFFFFFFFFU); + cpg_write(SMSTPCR2, 0x340E2FDCU); + cpg_write(SMSTPCR3, 0xFFFFFBDFU); + cpg_write(SMSTPCR4, 0x80000004U); + cpg_write(SMSTPCR5, 0xC3FFFFFFU); + cpg_write(SMSTPCR6, 0xFFFFFFFFU); + cpg_write(SMSTPCR7, 0xFFFFFFFFU); + cpg_write(SMSTPCR8, 0x01F1FFF5U); + cpg_write(SMSTPCR9, 0xFFFFFFFEU); +} +#endif + +#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_E3) +static void bl2_realtime_cpg_init_e3(void) +{ + /* Realtime Module Stop Control Registers */ + cpg_write(RMSTPCR0, 0x00210000U); + cpg_write(RMSTPCR1, 0xFFFFFFFFU); + cpg_write(RMSTPCR2, 0x000E0FDCU); + cpg_write(RMSTPCR3, 0xFFFFFFDFU); + cpg_write(RMSTPCR4, 0x80000004U); + cpg_write(RMSTPCR5, 0xC3FFFFFFU); + cpg_write(RMSTPCR6, 0xFFFFFFFFU); + cpg_write(RMSTPCR7, 0xFFFFFFFFU); + cpg_write(RMSTPCR8, 0x00F1FFF7U); + cpg_write(RMSTPCR9, 0xFFFFFFDFU); + cpg_write(RMSTPCR10, 0xFFFFFFE8U); + cpg_write(RMSTPCR11, 0x000000B7U); +} + +static void bl2_system_cpg_init_e3(void) +{ + /* System Module Stop Control Registers */ + cpg_write(SMSTPCR0, 0x00210000U); + cpg_write(SMSTPCR1, 0xFFFFFFFFU); + cpg_write(SMSTPCR2, 0x000E2FDCU); + cpg_write(SMSTPCR3, 0xFFFFFBDFU); + cpg_write(SMSTPCR4, 0x80000004U); + cpg_write(SMSTPCR5, 0xC3FFFFFFU); + cpg_write(SMSTPCR6, 0xFFFFFFFFU); + cpg_write(SMSTPCR7, 0xFFFFFFFFU); + cpg_write(SMSTPCR8, 0x00F1FFF7U); + cpg_write(SMSTPCR9, 0xFFFFFFDFU); + cpg_write(SMSTPCR10, 0xFFFFFFE8U); + cpg_write(SMSTPCR11, 0x000000B7U); +} +#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 */ + cpg_write(SMSTPCR0, 0x00010000U); + cpg_write(SMSTPCR1, 0xFFFFFFFFU); + cpg_write(SMSTPCR2, 0x00060FDCU); + cpg_write(SMSTPCR3, 0xFFFFFBDFU); + cpg_write(SMSTPCR4, 0x00000084U); + cpg_write(SMSTPCR5, 0x83FFFFFFU); + cpg_write(SMSTPCR6, 0xFFFFFFFFU); + cpg_write(SMSTPCR7, 0xFFFFFFFFU); + cpg_write(SMSTPCR8, 0x00F1FFF7U); + cpg_write(SMSTPCR9, 0xF3F5E016U); + cpg_write(SMSTPCR10, 0xFFFEFFE0U); + cpg_write(SMSTPCR11, 0x000000B7U); +} +#endif + +void bl2_cpg_init(void) +{ + uint32_t boot_cpu = mmio_read_32(RCAR_MODEMR) & MODEMR_BOOT_CPU_MASK; +#if RCAR_LSI == RCAR_AUTO + uint32_t product = mmio_read_32(RCAR_PRR) & PRR_PRODUCT_MASK; +#endif + bl2_secure_cpg_init(); + + if (boot_cpu == MODEMR_BOOT_CPU_CA57 || + boot_cpu == MODEMR_BOOT_CPU_CA53) { +#if RCAR_LSI == RCAR_AUTO + + switch (product) { + case PRR_PRODUCT_H3: + bl2_realtime_cpg_init_h3(); + break; + case PRR_PRODUCT_M3: + bl2_realtime_cpg_init_m3(); + break; + case PRR_PRODUCT_M3N: + bl2_realtime_cpg_init_m3n(); + break; + case PRR_PRODUCT_V3M: + bl2_realtime_cpg_init_v3m(); + break; + case PRR_PRODUCT_E3: + bl2_realtime_cpg_init_e3(); + break; + case PRR_PRODUCT_D3: + bl2_realtime_cpg_init_d3(); + break; + default: + panic(); + break; + } +#elif (RCAR_LSI == RCAR_H3) || (RCAR_LSI == RCAR_H3N) + bl2_realtime_cpg_init_h3(); +#elif RCAR_LSI == RCAR_M3 + bl2_realtime_cpg_init_m3(); +#elif RCAR_LSI == RCAR_M3N + bl2_realtime_cpg_init_m3n(); +#elif RCAR_LSI == RCAR_V3M + bl2_realtime_cpg_init_v3m(); +#elif RCAR_LSI == RCAR_E3 + bl2_realtime_cpg_init_e3(); +#elif RCAR_LSI == RCAR_D3 + bl2_realtime_cpg_init_d3(); +#else +#error "Don't have CPG initialize routine(unknown)." +#endif + } +} + +void bl2_system_cpg_init(void) +{ +#if RCAR_LSI == RCAR_AUTO + uint32_t product = mmio_read_32(RCAR_PRR) & PRR_PRODUCT_MASK; + + switch (product) { + case PRR_PRODUCT_H3: + bl2_system_cpg_init_h3(); + break; + case PRR_PRODUCT_M3: + bl2_system_cpg_init_m3(); + break; + case PRR_PRODUCT_M3N: + bl2_system_cpg_init_m3n(); + break; + case PRR_PRODUCT_V3M: + bl2_system_cpg_init_v3m(); + break; + case PRR_PRODUCT_E3: + bl2_system_cpg_init_e3(); + break; + case PRR_PRODUCT_D3: + bl2_system_cpg_init_d3(); + break; + default: + panic(); + break; + } +#elif (RCAR_LSI == RCAR_H3) || (RCAR_LSI == RCAR_H3N) + bl2_system_cpg_init_h3(); +#elif RCAR_LSI == RCAR_M3 + bl2_system_cpg_init_m3(); +#elif RCAR_LSI == RCAR_M3N + bl2_system_cpg_init_m3n(); +#elif RCAR_LSI == RCAR_V3M + bl2_system_cpg_init_v3m(); +#elif RCAR_LSI == RCAR_E3 + bl2_system_cpg_init_e3(); +#elif RCAR_LSI == RCAR_D3 + bl2_system_cpg_init_d3(); +#else +#error "Don't have CPG initialize routine(unknown)." +#endif +} diff --git a/plat/renesas/common/bl2_interrupt_error.c b/plat/renesas/common/bl2_interrupt_error.c new file mode 100644 index 000000000..d9a4b8e62 --- /dev/null +++ b/plat/renesas/common/bl2_interrupt_error.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include + +#include "rcar_def.h" + +#define SWDT_ERROR_ID (1024U) +#define SWDT_ERROR_TYPE (16U) +#define SWDT_CHAR_MAX (13U) + +extern void rcar_swdt_release(void); + +void bl2_interrupt_error_id(uint32_t int_id) +{ + ERROR("\n"); + if (int_id >= SWDT_ERROR_ID) { + ERROR("Unhandled exception occurred.\n"); + ERROR(" Exception type = FIQ_SP_EL0\n"); + panic(); + } + + /* Clear the interrupt request */ + gicv2_end_of_interrupt((uint32_t) int_id); + rcar_swdt_release(); + ERROR("Unhandled exception occurred.\n"); + ERROR(" Exception type = FIQ_SP_EL0\n"); + ERROR(" SPSR_EL3 = 0x%x\n", (uint32_t) read_spsr_el3()); + ERROR(" ELR_EL3 = 0x%x\n", (uint32_t) read_elr_el3()); + ERROR(" ESR_EL3 = 0x%x\n", (uint32_t) read_esr_el3()); + ERROR(" FAR_EL3 = 0x%x\n", (uint32_t) read_far_el3()); + ERROR("\n"); + panic(); +} + +void bl2_interrupt_error_type(uint32_t ex_type) +{ + const uint8_t interrupt_ex[SWDT_ERROR_TYPE][SWDT_CHAR_MAX] = { + "SYNC SP EL0", + "IRQ SP EL0", + "FIQ SP EL0", + "SERR SP EL0", + "SYNC SP ELx", + "IRQ SP ELx", + "FIQ SP ELx", + "SERR SP ELx", + "SYNC AARCH64", + "IRQ AARCH64", + "FIQ AARCH64", + "SERR AARCH64", + "SYNC AARCH32", + "IRQ AARCH32", + "FIQ AARCH32", + "SERR AARCH32" + }; + char msg[128]; + + /* Clear the interrupt request */ + if (ex_type >= SWDT_ERROR_TYPE) { + ERROR("\n"); + ERROR("Unhandled exception occurred.\n"); + ERROR(" Exception type = Unknown (%d)\n", ex_type); + goto loop; + } + + rcar_swdt_release(); + ERROR("\n"); + ERROR("Unhandled exception occurred.\n"); + snprintf(msg, sizeof(msg), " Exception type = %s\n", + &interrupt_ex[ex_type][0]); + ERROR("%s", msg); + switch (ex_type) { + case SYNC_EXCEPTION_SP_EL0: + ERROR(" SPSR_EL3 = 0x%x\n", (uint32_t) read_spsr_el3()); + ERROR(" ELR_EL3 = 0x%x\n", (uint32_t) read_elr_el3()); + ERROR(" ESR_EL3 = 0x%x\n", (uint32_t) read_esr_el3()); + ERROR(" FAR_EL3 = 0x%x\n", (uint32_t) read_far_el3()); + break; + case IRQ_SP_EL0: + ERROR(" SPSR_EL3 = 0x%x\n", (uint32_t) read_spsr_el3()); + ERROR(" ELR_EL3 = 0x%x\n", (uint32_t) read_elr_el3()); + ERROR(" IAR_EL3 = 0x%x\n", gicv2_acknowledge_interrupt()); + break; + case FIQ_SP_EL0: + ERROR(" SPSR_EL3 = 0x%x\n", (uint32_t) read_spsr_el3()); + ERROR(" ELR_EL3 = 0x%x\n", (uint32_t) read_elr_el3()); + ERROR(" IAR_EL3 = 0x%x\n", gicv2_acknowledge_interrupt()); + break; + case SERROR_SP_EL0: + ERROR(" SPSR_EL3 = 0x%x\n", (uint32_t) read_spsr_el3()); + ERROR(" ELR_EL3 = 0x%x\n", (uint32_t) read_elr_el3()); + ERROR(" ESR_EL3 = 0x%x\n", (uint32_t) read_esr_el3()); + ERROR(" FAR_EL3 = 0x%x\n", (uint32_t) read_far_el3()); + break; + default: + break; + } +loop: + ERROR("\n"); + panic(); +} diff --git a/plat/renesas/common/bl2_plat_mem_params_desc.c b/plat/renesas/common/bl2_plat_mem_params_desc.c new file mode 100644 index 000000000..bf2706d53 --- /dev/null +++ b/plat/renesas/common/bl2_plat_mem_params_desc.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include + +#if (RCAR_BL33_EXECUTION_EL != 0) && (RCAR_BL33_EXECUTION_EL != 1) +#error +#endif + +#if (RCAR_BL33_EXECUTION_EL == 0) +#define BL33_MODE MODE_EL1 +#else +#define BL33_MODE MODE_EL2 +#endif + +extern uint64_t fdt_blob[PAGE_SIZE_4KB / sizeof(uint64_t)]; + +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.spsr = SPSR_64(MODE_EL3, + MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS), + .ep_info.pc = BL31_BASE, + + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2, + image_info_t, IMAGE_ATTRIB_PLAT_SETUP), + .image_info.image_max_size = BL31_LIMIT - BL31_BASE, + .image_info.image_base = BL31_BASE, + +# ifdef BL32_BASE + .next_handoff_image_id = BL32_IMAGE_ID, +# else + .next_handoff_image_id = BL33_IMAGE_ID, +# endif + }, +# ifdef BL32_BASE + { + .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, + .ep_info.spsr = 0, + .ep_info.args.arg3 = (uintptr_t)fdt_blob, + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2, + image_info_t, 0), + .image_info.image_max_size = BL32_LIMIT - BL32_BASE, + .image_info.image_base = BL32_BASE, + + .next_handoff_image_id = BL33_IMAGE_ID, + }, +#endif + { + .image_id = BL33_IMAGE_ID, + + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, VERSION_2, + entry_point_info_t, NON_SECURE | EXECUTABLE), + .ep_info.spsr = SPSR_64(BL33_MODE, MODE_SP_ELX, + DISABLE_ALL_EXCEPTIONS), + .ep_info.pc = BL33_BASE, +#ifdef RCAR_BL33_ARG0 + .ep_info.args.arg0 = RCAR_BL33_ARG0, +#endif + .ep_info.args.arg1 = (uintptr_t)fdt_blob, + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2, + image_info_t, 0), + .image_info.image_max_size = + (uint32_t) (DRAM_LIMIT - BL33_BASE), + .image_info.image_base = BL33_BASE, + + .next_handoff_image_id = INVALID_IMAGE_ID, + } +}; + +REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs) diff --git a/plat/renesas/common/bl2_secure_setting.c b/plat/renesas/common/bl2_secure_setting.c new file mode 100644 index 000000000..095d1f62a --- /dev/null +++ b/plat/renesas/common/bl2_secure_setting.c @@ -0,0 +1,362 @@ +/* + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include "axi_registers.h" +#include "lifec_registers.h" +#include "micro_delay.h" + +static void lifec_security_setting(void); +static void axi_security_setting(void); + +static const struct { + uint32_t reg; + uint32_t val; +} lifec[] = { + /* + * LIFEC0 (SECURITY) settings + * Security attribute setting for master ports + * Bit 0: ARM realtime core (Cortex-R7) master port + * 0: Non-Secure + */ + { SEC_SRC, 0x0000001EU }, + /* + * Security attribute setting for slave ports 0 to 15 + * {SEC_SEL0, 0xFFFFFFFFU}, + * {SEC_SEL1, 0xFFFFFFFFU}, + * {SEC_SEL2, 0xFFFFFFFFU}, + * Bit19: AXI-Bus (Main Memory domain AXI) slave ports + * 0: registers accessed from secure resource only + * Bit 9: DBSC4 register access slave ports. + * 0: registers accessed from secure resource only. + */ +#if (LIFEC_DBSC_PROTECT_ENABLE == 1) + { SEC_SEL3, 0xFFF7FDFFU }, +#else /* LIFEC_DBSC_PROTECT_ENABLE == 1 */ + { SEC_SEL3, 0xFFFFFFFFU }, +#endif /* LIFEC_DBSC_PROTECT_ENABLE == 1 */ + /* + * {SEC_SEL4, 0xFFFFFFFFU}, + * Bit 6: Boot ROM slave ports. + * 0: registers accessed from secure resource only + */ + { SEC_SEL5, 0xFFFFFFBFU }, + /* + * Bit13: SCEG PKA (secure APB) slave ports + * 0: registers accessed from secure resource only + * 1: Reserved[R-Car E3] + * Bit12: SCEG PKA (public APB) slave ports + * 0: registers accessed from secure resource only + * 1: Reserved[R-Car E3] + * Bit10: SCEG Secure Core slave ports + * 0: registers accessed from secure resource only + */ +#if (RCAR_LSI == RCAR_E3) || (RCAR_LSI == RCAR_D3) + { SEC_SEL6, 0xFFFFFBFFU }, +#else /* (RCAR_LSI == RCAR_E3) || (RCAR_LSI == RCAR_D3) */ + { SEC_SEL6, 0xFFFFCBFFU }, +#endif /* (RCAR_LSI == RCAR_E3) || (RCAR_LSI == RCAR_D3) */ + /* + * {SEC_SEL7, 0xFFFFFFFFU}, + * {SEC_SEL8, 0xFFFFFFFFU}, + * {SEC_SEL9, 0xFFFFFFFFU}, + * {SEC_SEL10, 0xFFFFFFFFU}, + * {SEC_SEL11, 0xFFFFFFFFU}, + * {SEC_SEL12, 0xFFFFFFFFU}, + * Bit22: RPC slave ports. + * 0: registers accessed from secure resource only. + */ +#if (RCAR_RPC_HYPERFLASH_LOCKED == 1) + { SEC_SEL13, 0xFFBFFFFFU }, +#endif /* (RCAR_RPC_HYPERFLASH_LOCKED == 1) */ + /* + * Bit27: System Timer (SCMT) slave ports + * 0: registers accessed from secure resource only + * Bit26: System Watchdog Timer (SWDT) slave ports + * 0: registers accessed from secure resource only + */ + { SEC_SEL14, 0xF3FFFFFFU }, + /* + * Bit13: RST slave ports. + * 0: registers accessed from secure resource only + * Bit 7: Life Cycle 0 slave ports + * 0: registers accessed from secure resource only + */ + { SEC_SEL15, 0xFFFFFF3FU }, + /* + * Security group 0 attribute setting for master ports 0 + * Security group 1 attribute setting for master ports 0 + * {SEC_GRP0CR0, 0x00000000U}, + * {SEC_GRP1CR0, 0x00000000U}, + * Security group 0 attribute setting for master ports 1 + * Security group 1 attribute setting for master ports 1 + * {SEC_GRP0CR1, 0x00000000U}, + * {SEC_GRP1CR1, 0x00000000U}, + * Security group 0 attribute setting for master ports 2 + * Security group 1 attribute setting for master ports 2 + * Bit17: SCEG Secure Core master ports. + * SecurityGroup3 + */ + { SEC_GRP0CR2, 0x00020000U }, + { SEC_GRP1CR2, 0x00020000U }, + /* + * Security group 0 attribute setting for master ports 3 + * Security group 1 attribute setting for master ports 3 + * {SEC_GRP0CR3, 0x00000000U}, + * {SEC_GRP1CR3, 0x00000000U}, + * Security group 0 attribute setting for slave ports 0 + * Security group 1 attribute setting for slave ports 0 + * {SEC_GRP0COND0, 0x00000000U}, + * {SEC_GRP1COND0, 0x00000000U}, + * Security group 0 attribute setting for slave ports 1 + * Security group 1 attribute setting for slave ports 1 + * {SEC_GRP0COND1, 0x00000000U}, + * {SEC_GRP1COND1, 0x00000000U}, + * Security group 0 attribute setting for slave ports 2 + * Security group 1 attribute setting for slave ports 2 + * {SEC_GRP0COND2, 0x00000000U}, + * {SEC_GRP1COND2, 0x00000000U}, + * Security group 0 attribute setting for slave ports 3 + * Security group 1 attribute setting for slave ports 3 + * Bit19: AXI-Bus (Main Memory domain AXI) slave ports. + * SecurityGroup3 + * Bit 9: DBSC4 register access slave ports. + * SecurityGroup3 + */ +#if (LIFEC_DBSC_PROTECT_ENABLE == 1) + { SEC_GRP0COND3, 0x00080200U }, + { SEC_GRP1COND3, 0x00080200U }, +#else /* (LIFEC_DBSC_PROTECT_ENABLE == 1) */ + { SEC_GRP0COND3, 0x00000000U }, + { SEC_GRP1COND3, 0x00000000U }, +#endif /* (LIFEC_DBSC_PROTECT_ENABLE == 1) */ + /* + * Security group 0 attribute setting for slave ports 4 + * Security group 1 attribute setting for slave ports 4 + * {SEC_GRP0COND4, 0x00000000U}, + * {SEC_GRP1COND4, 0x00000000U}, + * Security group 0 attribute setting for slave ports 5 + * Security group 1 attribute setting for slave ports 5 + * Bit 6: Boot ROM slave ports + * SecurityGroup3 + */ + { SEC_GRP0COND5, 0x00000040U }, + { SEC_GRP1COND5, 0x00000040U }, + /* + * Security group 0 attribute setting for slave ports 6 + * Security group 1 attribute setting for slave ports 6 + * Bit13: SCEG PKA (secure APB) slave ports + * SecurityGroup3 + * Reserved[R-Car E3] + * Bit12: SCEG PKA (public APB) slave ports + * SecurityGroup3 + * Reserved[R-Car E3] + * Bit10: SCEG Secure Core slave ports + * SecurityGroup3 + */ +#if RCAR_LSI == RCAR_E3 + { SEC_GRP0COND6, 0x00000400U }, + { SEC_GRP1COND6, 0x00000400U }, +#else /* RCAR_LSI == RCAR_E3 */ + { SEC_GRP0COND6, 0x00003400U }, + { SEC_GRP1COND6, 0x00003400U }, +#endif /* RCAR_LSI == RCAR_E3 */ + /* + * Security group 0 attribute setting for slave ports 7 + * Security group 1 attribute setting for slave ports 7 + * {SEC_GRP0COND7, 0x00000000U}, + * {SEC_GRP1COND7, 0x00000000U}, + * Security group 0 attribute setting for slave ports 8 + * Security group 1 attribute setting for slave ports 8 + * {SEC_GRP0COND8, 0x00000000U}, + * {SEC_GRP1COND8, 0x00000000U}, + * Security group 0 attribute setting for slave ports 9 + * Security group 1 attribute setting for slave ports 9 + * {SEC_GRP0COND9, 0x00000000U}, + * {SEC_GRP1COND9, 0x00000000U}, + * Security group 0 attribute setting for slave ports 10 + * Security group 1 attribute setting for slave ports 10 + * {SEC_GRP0COND10, 0x00000000U}, + * {SEC_GRP1COND10, 0x00000000U}, + * Security group 0 attribute setting for slave ports 11 + * Security group 1 attribute setting for slave ports 11 + * {SEC_GRP0COND11, 0x00000000U}, + * {SEC_GRP1COND11, 0x00000000U}, + * Security group 0 attribute setting for slave ports 12 + * Security group 1 attribute setting for slave ports 12 + * {SEC_GRP0COND12, 0x00000000U}, + * {SEC_GRP1COND12, 0x00000000U}, + * Security group 0 attribute setting for slave ports 13 + * Security group 1 attribute setting for slave ports 13 + * Bit22: RPC slave ports. + * SecurityGroup3 + */ +#if (RCAR_RPC_HYPERFLASH_LOCKED == 1) + { SEC_GRP0COND13, 0x00400000U }, + { SEC_GRP1COND13, 0x00400000U }, +#endif /* (RCAR_RPC_HYPERFLASH_LOCKED == 1) */ + /* + * Security group 0 attribute setting for slave ports 14 + * Security group 1 attribute setting for slave ports 14 + * Bit26: System Timer (SCMT) slave ports + * SecurityGroup3 + * Bit27: System Watchdog Timer (SWDT) slave ports + * SecurityGroup3 + */ + { SEC_GRP0COND14, 0x0C000000U }, + { SEC_GRP1COND14, 0x0C000000U }, + /* + * Security group 0 attribute setting for slave ports 15 + * Security group 1 attribute setting for slave ports 15 + * Bit13: RST slave ports + * SecurityGroup3 + * Bit 7: Life Cycle 0 slave ports + * SecurityGroup3 + * Bit 6: TDBG slave ports + * SecurityGroup3 + */ + { SEC_GRP0COND15, 0x000000C0U }, + { SEC_GRP1COND15, 0x000000C0U }, + /* + * Security write protection attribute setting slave ports 0 + * {SEC_READONLY0, 0x00000000U}, + * Security write protection attribute setting slave ports 1 + * {SEC_READONLY1, 0x00000000U}, + * Security write protection attribute setting slave ports 2 + * {SEC_READONLY2, 0x00000000U}, + * Security write protection attribute setting slave ports 3 + * {SEC_READONLY3, 0x00000000U}, + * Security write protection attribute setting slave ports 4 + * {SEC_READONLY4, 0x00000000U}, + * Security write protection attribute setting slave ports 5 + * {SEC_READONLY5, 0x00000000U}, + * Security write protection attribute setting slave ports 6 + * {SEC_READONLY6, 0x00000000U}, + * Security write protection attribute setting slave ports 7 + * {SEC_READONLY7, 0x00000000U}, + * Security write protection attribute setting slave ports 8 + * {SEC_READONLY8, 0x00000000U}, + * Security write protection attribute setting slave ports 9 + * {SEC_READONLY9, 0x00000000U}, + * Security write protection attribute setting slave ports 10 + * {SEC_READONLY10, 0x00000000U}, + * Security write protection attribute setting slave ports 11 + * {SEC_READONLY11, 0x00000000U}, + * Security write protection attribute setting slave ports 12 + * {SEC_READONLY12, 0x00000000U}, + * Security write protection attribute setting slave ports 13 + * {SEC_READONLY13, 0x00000000U}, + * Security write protection attribute setting slave ports 14 + * {SEC_READONLY14, 0x00000000U}, + * Security write protection attribute setting slave ports 15 + * {SEC_READONLY15, 0x00000000U} + */ +}; + +/* AXI settings */ +static const struct { + uint32_t reg; + uint32_t val; +} axi[] = { + /* + * DRAM protection + * AXI dram protected area division + */ + {AXI_DPTDIVCR0, 0x0E0403F0U}, + {AXI_DPTDIVCR1, 0x0E0407E0U}, + {AXI_DPTDIVCR2, 0x0E080000U}, + {AXI_DPTDIVCR3, 0x0E080000U}, + {AXI_DPTDIVCR4, 0x0E080000U}, + {AXI_DPTDIVCR5, 0x0E080000U}, + {AXI_DPTDIVCR6, 0x0E080000U}, + {AXI_DPTDIVCR7, 0x0E080000U}, + {AXI_DPTDIVCR8, 0x0E080000U}, + {AXI_DPTDIVCR9, 0x0E080000U}, + {AXI_DPTDIVCR10, 0x0E080000U}, + {AXI_DPTDIVCR11, 0x0E080000U}, + {AXI_DPTDIVCR12, 0x0E080000U}, + {AXI_DPTDIVCR13, 0x0E080000U}, + {AXI_DPTDIVCR14, 0x0E080000U}, + /* AXI dram protected area setting */ + {AXI_DPTCR0, 0x0E000000U}, + {AXI_DPTCR1, 0x0E000E0EU}, + {AXI_DPTCR2, 0x0E000000U}, + {AXI_DPTCR3, 0x0E000000U}, + {AXI_DPTCR4, 0x0E000000U}, + {AXI_DPTCR5, 0x0E000000U}, + {AXI_DPTCR6, 0x0E000000U}, + {AXI_DPTCR7, 0x0E000000U}, + {AXI_DPTCR8, 0x0E000000U}, + {AXI_DPTCR9, 0x0E000000U}, + {AXI_DPTCR10, 0x0E000000U}, + {AXI_DPTCR11, 0x0E000000U}, + {AXI_DPTCR12, 0x0E000000U}, + {AXI_DPTCR13, 0x0E000000U}, + {AXI_DPTCR14, 0x0E000000U}, + {AXI_DPTCR15, 0x0E000000U}, + /* + * SRAM ptotection + * AXI sram protected area division + */ + {AXI_SPTDIVCR0, 0x0E0E6304U}, + {AXI_SPTDIVCR1, 0x0E0E6360U}, + {AXI_SPTDIVCR2, 0x0E0E6360U}, + {AXI_SPTDIVCR3, 0x0E0E6360U}, + {AXI_SPTDIVCR4, 0x0E0E6360U}, + {AXI_SPTDIVCR5, 0x0E0E6360U}, + {AXI_SPTDIVCR6, 0x0E0E6360U}, + {AXI_SPTDIVCR7, 0x0E0E6360U}, + {AXI_SPTDIVCR8, 0x0E0E6360U}, + {AXI_SPTDIVCR9, 0x0E0E6360U}, + {AXI_SPTDIVCR10, 0x0E0E6360U}, + {AXI_SPTDIVCR11, 0x0E0E6360U}, + {AXI_SPTDIVCR12, 0x0E0E6360U}, + {AXI_SPTDIVCR13, 0x0E0E6360U}, + {AXI_SPTDIVCR14, 0x0E0E6360U}, + /* AXI sram protected area setting */ + {AXI_SPTCR0, 0x0E000E0EU}, + {AXI_SPTCR1, 0x0E000000U}, + {AXI_SPTCR2, 0x0E000000U}, + {AXI_SPTCR3, 0x0E000000U}, + {AXI_SPTCR4, 0x0E000000U}, + {AXI_SPTCR5, 0x0E000000U}, + {AXI_SPTCR6, 0x0E000000U}, + {AXI_SPTCR7, 0x0E000000U}, + {AXI_SPTCR8, 0x0E000000U}, + {AXI_SPTCR9, 0x0E000000U}, + {AXI_SPTCR10, 0x0E000000U}, + {AXI_SPTCR11, 0x0E000000U}, + {AXI_SPTCR12, 0x0E000000U}, + {AXI_SPTCR13, 0x0E000000U}, + {AXI_SPTCR14, 0x0E000000U}, + {AXI_SPTCR15, 0x0E000000U} +}; + +static void lifec_security_setting(void) +{ + uint32_t i; + + for (i = 0; i < ARRAY_SIZE(lifec); i++) + mmio_write_32(lifec[i].reg, lifec[i].val); +} + +/* SRAM/DRAM protection setting */ +static void axi_security_setting(void) +{ + uint32_t i; + + for (i = 0; i < ARRAY_SIZE(axi); i++) + mmio_write_32(axi[i].reg, axi[i].val); +} + +void bl2_secure_setting(void) +{ + lifec_security_setting(); + axi_security_setting(); + rcar_micro_delay(10U); +} diff --git a/plat/renesas/common/bl31_plat_setup.c b/plat/renesas/common/bl31_plat_setup.c new file mode 100644 index 000000000..93798acfb --- /dev/null +++ b/plat/renesas/common/bl31_plat_setup.c @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pwrc.h" +#include "rcar_def.h" +#include "rcar_private.h" +#include "rcar_version.h" + +static const uint64_t BL31_RO_BASE = BL_CODE_BASE; +static const uint64_t BL31_RO_LIMIT = BL_CODE_END; + +#if USE_COHERENT_MEM +static const uint64_t BL31_COHERENT_RAM_BASE = BL_COHERENT_RAM_BASE; +static const uint64_t BL31_COHERENT_RAM_LIMIT = BL_COHERENT_RAM_END; +#endif /* USE_COHERENT_MEM */ + +extern void plat_rcar_gic_driver_init(void); +extern void plat_rcar_gic_init(void); + +u_register_t rcar_boot_mpidr; + +static int cci_map[] = { + CCI500_CLUSTER0_SL_IFACE_IX_FOR_M3, + CCI500_CLUSTER1_SL_IFACE_IX_FOR_M3 +}; + +void plat_cci_init(void) +{ + uint32_t prd; + + prd = mmio_read_32(RCAR_PRR) & (PRR_PRODUCT_MASK | PRR_CUT_MASK); + + if (PRR_PRODUCT_H3_CUT10 == prd || PRR_PRODUCT_H3_CUT11 == prd) { + cci_map[0U] = CCI500_CLUSTER0_SL_IFACE_IX; + cci_map[1U] = CCI500_CLUSTER1_SL_IFACE_IX; + } + + cci_init(RCAR_CCI_BASE, cci_map, ARRAY_SIZE(cci_map)); +} + +void plat_cci_enable(void) +{ + cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr())); +} + +void plat_cci_disable(void) +{ + cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr())); +} + +struct entry_point_info *bl31_plat_get_next_image_ep_info(uint32_t type) +{ + bl2_to_bl31_params_mem_t *from_bl2 = (bl2_to_bl31_params_mem_t *) + PARAMS_BASE; + entry_point_info_t *next_image_info; + + next_image_info = (type == NON_SECURE) ? + &from_bl2->bl33_ep_info : &from_bl2->bl32_ep_info; + + return next_image_info->pc ? next_image_info : NULL; +} + +void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, + u_register_t arg2, u_register_t arg3) +{ + rcar_console_runtime_init(); + + NOTICE("BL3-1 : Rev.%s\n", version_of_renesas); + +#if RCAR_LSI != RCAR_D3 + if (rcar_pwrc_get_cluster() == RCAR_CLUSTER_A53A57) { + plat_cci_init(); + plat_cci_enable(); + } +#endif /* RCAR_LSI != RCAR_D3 */ +} + +void bl31_plat_arch_setup(void) +{ + rcar_configure_mmu_el3(BL31_BASE, + BL31_LIMIT - BL31_BASE, + BL31_RO_BASE, BL31_RO_LIMIT +#if USE_COHERENT_MEM + , BL31_COHERENT_RAM_BASE, BL31_COHERENT_RAM_LIMIT +#endif /* USE_COHERENT_MEM */ + ); + rcar_pwrc_code_copy_to_system_ram(); +} + +void bl31_platform_setup(void) +{ + plat_rcar_gic_driver_init(); + plat_rcar_gic_init(); + + /* enable the system level generic timer */ + mmio_write_32(RCAR_CNTC_BASE + CNTCR_OFF, CNTCR_FCREQ(U(0)) | CNTCR_EN); + + rcar_pwrc_setup(); +#if 0 + /* + * TODO: there is a broad number of rcar-gen3 SoC configurations; to + * support all of them, Renesas use the pwrc driver to discover what + * cores are on/off before announcing the topology. + * This code hasnt been ported yet + */ + + rcar_setup_topology(); +#endif + + /* + * mask should match the kernel's MPIDR_HWID_BITMASK so the core can be + * identified during cpuhotplug (check the kernel's psci migrate set of + * functions + */ + rcar_boot_mpidr = read_mpidr_el1() & 0x0000ffffU; +} diff --git a/plat/renesas/common/common.mk b/plat/renesas/common/common.mk index cb0bb07b2..cadb3d764 100644 --- a/plat/renesas/common/common.mk +++ b/plat/renesas/common/common.mk @@ -80,6 +80,12 @@ BL2_SOURCES += ${RCAR_GIC_SOURCES} \ common/desc_image_load.c \ plat/renesas/common/aarch64/platform_common.c \ plat/renesas/common/aarch64/plat_helpers.S \ + plat/renesas/common/bl2_interrupt_error.c \ + plat/renesas/common/bl2_secure_setting.c \ + plat/renesas/common/plat_storage.c \ + plat/renesas/common/bl2_plat_mem_params_desc.c \ + plat/renesas/common/plat_image_load.c \ + plat/renesas/common/bl2_cpg_init.c \ drivers/renesas/common/console/rcar_printf.c \ drivers/renesas/common/scif/scif.S \ drivers/renesas/common/common.c \ @@ -105,8 +111,11 @@ BL31_SOURCES += ${RCAR_GIC_SOURCES} \ lib/cpus/aarch64/cortex_a53.S \ lib/cpus/aarch64/cortex_a57.S \ plat/common/plat_psci_common.c \ + plat/renesas/common/plat_topology.c \ plat/renesas/common/aarch64/plat_helpers.S \ plat/renesas/common/aarch64/platform_common.c \ + plat/renesas/common/bl31_plat_setup.c \ + plat/renesas/common/plat_pm.c \ drivers/renesas/common/console/rcar_console.S \ drivers/renesas/common/console/rcar_printf.c \ drivers/renesas/common/delay/micro_delay.c \ diff --git a/plat/renesas/common/plat_image_load.c b/plat/renesas/common/plat_image_load.c new file mode 100644 index 000000000..9d814a6e5 --- /dev/null +++ b/plat/renesas/common/plat_image_load.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +extern void bl2_plat_flush_bl31_params(void); + +/******************************************************************************* + * This function flushes the data structures so that they are visible + * in memory for the next BL image. + ******************************************************************************/ +void plat_flush_next_bl_params(void) +{ +#if IMAGE_BL2 + bl2_plat_flush_bl31_params(); +#endif +} + +/******************************************************************************* + * This function returns the list of loadable images. + ******************************************************************************/ +bl_load_info_t *plat_get_bl_image_load_info(void) +{ + return get_bl_load_info_from_mem_params_desc(); +} + +/******************************************************************************* + * This function returns the list of executable images. + ******************************************************************************/ +bl_params_t *plat_get_next_bl_params(void) +{ + return get_next_bl_params_from_mem_params_desc(); +} diff --git a/plat/renesas/common/plat_pm.c b/plat/renesas/common/plat_pm.c new file mode 100644 index 000000000..7ec78cce3 --- /dev/null +++ b/plat/renesas/common/plat_pm.c @@ -0,0 +1,308 @@ +/* + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "iic_dvfs.h" +#include "platform_def.h" +#include "pwrc.h" +#include "rcar_def.h" +#include "rcar_private.h" +#include "ulcb_cpld.h" + +#define DVFS_SET_VID_0V (0x00) +#define P_ALL_OFF (0x80) +#define KEEPON_DDR1C (0x08) +#define KEEPON_DDR0C (0x04) +#define KEEPON_DDR1 (0x02) +#define KEEPON_DDR0 (0x01) + +#define SYSTEM_PWR_STATE(s) ((s)->pwr_domain_state[PLAT_MAX_PWR_LVL]) +#define CLUSTER_PWR_STATE(s) ((s)->pwr_domain_state[MPIDR_AFFLVL1]) +#define CORE_PWR_STATE(s) ((s)->pwr_domain_state[MPIDR_AFFLVL0]) + +extern void rcar_pwrc_restore_generic_timer(uint64_t *stack); +extern void plat_rcar_gic_driver_init(void); +extern void plat_rcar_gic_init(void); +extern u_register_t rcar_boot_mpidr; + +static uintptr_t rcar_sec_entrypoint; + +static void rcar_program_mailbox(uint64_t mpidr, uint64_t address) +{ + mailbox_t *rcar_mboxes = (mailbox_t *) MBOX_BASE; + uint64_t linear_id = plat_core_pos_by_mpidr(mpidr); + unsigned long range; + + rcar_mboxes[linear_id].value = address; + range = (unsigned long)&rcar_mboxes[linear_id]; + + flush_dcache_range(range, sizeof(range)); +} + +static void rcar_cpu_standby(plat_local_state_t cpu_state) +{ + u_register_t scr_el3 = read_scr_el3(); + + write_scr_el3(scr_el3 | SCR_IRQ_BIT); + dsb(); + wfi(); + write_scr_el3(scr_el3); +} + +static int rcar_pwr_domain_on(u_register_t mpidr) +{ + rcar_program_mailbox(mpidr, rcar_sec_entrypoint); + rcar_pwrc_cpuon(mpidr); + + return PSCI_E_SUCCESS; +} + +static void rcar_pwr_domain_on_finish(const psci_power_state_t *target_state) +{ + uint32_t cluster_type = rcar_pwrc_get_cluster(); + unsigned long mpidr = read_mpidr_el1(); + + if (CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) + if (cluster_type == RCAR_CLUSTER_A53A57) + plat_cci_enable(); + + rcar_pwrc_disable_interrupt_wakeup(mpidr); + rcar_program_mailbox(mpidr, 0); + + gicv2_cpuif_enable(); + gicv2_pcpu_distif_init(); +} + +static void rcar_pwr_domain_off(const psci_power_state_t *target_state) +{ +#if RCAR_LSI != RCAR_D3 + uint32_t cluster_type = rcar_pwrc_get_cluster(); +#endif + unsigned long mpidr = read_mpidr_el1(); + + gicv2_cpuif_disable(); + rcar_pwrc_cpuoff(mpidr); + +#if RCAR_LSI != RCAR_D3 + if (CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) { + if (cluster_type == RCAR_CLUSTER_A53A57) + plat_cci_disable(); + + rcar_pwrc_clusteroff(mpidr); + } +#endif +} + +static void rcar_pwr_domain_suspend(const psci_power_state_t *target_state) +{ + uint32_t cluster_type = rcar_pwrc_get_cluster(); + unsigned long mpidr = read_mpidr_el1(); + + if (CORE_PWR_STATE(target_state) != PLAT_MAX_OFF_STATE) + return; + + rcar_program_mailbox(mpidr, rcar_sec_entrypoint); + rcar_pwrc_enable_interrupt_wakeup(mpidr); + gicv2_cpuif_disable(); + rcar_pwrc_cpuoff(mpidr); + + if (CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) { + if (cluster_type == RCAR_CLUSTER_A53A57) + plat_cci_disable(); + + 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 + *target_state) +{ + uint32_t cluster_type = rcar_pwrc_get_cluster(); + + if (SYSTEM_PWR_STATE(target_state) != PLAT_MAX_OFF_STATE) + goto finish; + + plat_rcar_gic_driver_init(); + plat_rcar_gic_init(); + + if (cluster_type == RCAR_CLUSTER_A53A57) + plat_cci_init(); + + rcar_pwrc_restore_timer_state(); + rcar_pwrc_setup(); + rcar_pwrc_code_copy_to_system_ram(); + +#if RCAR_SYSTEM_SUSPEND + rcar_pwrc_init_suspend_to_ram(); +#endif +finish: + rcar_pwr_domain_on_finish(target_state); +} + +static void __dead2 rcar_system_off(void) +{ +#if PMIC_ROHM_BD9571 +#if PMIC_LEVEL_MODE + if (rcar_iic_dvfs_send(PMIC, DVFS_SET_VID, DVFS_SET_VID_0V)) + ERROR("BL3-1:Failed the SYSTEM-OFF.\n"); +#else + if (rcar_iic_dvfs_send(PMIC, BKUP_MODE_CNT, P_ALL_OFF)) + ERROR("BL3-1:Failed the SYSTEM-RESET.\n"); +#endif +#else + uint64_t cpu = read_mpidr_el1() & 0x0000ffff; + int32_t rtn_on; + + rtn_on = rcar_pwrc_cpu_on_check(cpu); + + if (cpu == rcar_boot_mpidr) + panic(); + + if (rtn_on) + panic(); + + rcar_pwrc_cpuoff(cpu); + rcar_pwrc_clusteroff(cpu); + +#endif /* PMIC_ROHM_BD9571 */ + wfi(); + ERROR("RCAR System Off: operation not handled.\n"); + panic(); +} + +static void __dead2 rcar_system_reset(void) +{ +#if PMIC_ROHM_BD9571 +#if PMIC_LEVEL_MODE +#if RCAR_SYSTEM_RESET_KEEPON_DDR + uint8_t mode; + int32_t error; + + error = rcar_iic_dvfs_send(PMIC, REG_KEEP10, KEEP10_MAGIC); + if (error) { + ERROR("Failed send KEEP10 magic ret=%d\n", error); + goto done; + } + + error = rcar_iic_dvfs_receive(PMIC, BKUP_MODE_CNT, &mode); + if (error) { + ERROR("Failed receive BKUP_Mode_Cnt ret=%d\n", error); + goto done; + } + + mode |= KEEPON_DDR1C | KEEPON_DDR0C | KEEPON_DDR1 | KEEPON_DDR0; + error = rcar_iic_dvfs_send(PMIC, BKUP_MODE_CNT, mode); + if (error) { + ERROR("Failed send KEEPON_DDRx ret=%d\n", error); + goto done; + } + + rcar_pwrc_set_suspend_to_ram(); +done: +#else + if (rcar_iic_dvfs_send(PMIC, BKUP_MODE_CNT, P_ALL_OFF)) + ERROR("BL3-1:Failed the SYSTEM-RESET.\n"); +#endif +#else +#if (RCAR_GEN3_ULCB == 1) + rcar_cpld_reset_cpu(); +#endif +#endif +#else + rcar_pwrc_system_reset(); +#endif + wfi(); + + ERROR("RCAR System Reset: operation not handled.\n"); + panic(); +} + +static int rcar_validate_power_state(unsigned int power_state, + psci_power_state_t *req_state) +{ + unsigned int pwr_lvl = psci_get_pstate_pwrlvl(power_state); + unsigned int pstate = psci_get_pstate_type(power_state); + uint32_t i; + + if (pstate == PSTATE_TYPE_STANDBY) { + if (pwr_lvl != MPIDR_AFFLVL0) + return PSCI_E_INVALID_PARAMS; + + req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_RET_STATE; + } else { + for (i = MPIDR_AFFLVL0; i <= pwr_lvl; i++) + req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE; + } + + if (psci_get_pstate_id(power_state)) + return PSCI_E_INVALID_PARAMS; + + return PSCI_E_SUCCESS; +} + +#if RCAR_SYSTEM_SUSPEND +static void rcar_get_sys_suspend_power_state(psci_power_state_t *req_state) +{ + unsigned long mpidr = read_mpidr_el1() & 0x0000ffffU; + int i; + + if (mpidr != rcar_boot_mpidr) + goto deny; + + for (i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++) + req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE; + + return; +deny: + /* deny system suspend entry */ + req_state->pwr_domain_state[PLAT_MAX_PWR_LVL] = PSCI_LOCAL_STATE_RUN; + for (i = MPIDR_AFFLVL0; i < PLAT_MAX_PWR_LVL; i++) + req_state->pwr_domain_state[i] = PLAT_MAX_RET_STATE; +} +#endif + +static const plat_psci_ops_t rcar_plat_psci_ops = { + .cpu_standby = rcar_cpu_standby, + .pwr_domain_on = rcar_pwr_domain_on, + .pwr_domain_off = rcar_pwr_domain_off, + .pwr_domain_suspend = rcar_pwr_domain_suspend, + .pwr_domain_on_finish = rcar_pwr_domain_on_finish, + .pwr_domain_suspend_finish = rcar_pwr_domain_suspend_finish, + .system_off = rcar_system_off, + .system_reset = rcar_system_reset, + .validate_power_state = rcar_validate_power_state, +#if RCAR_SYSTEM_SUSPEND + .get_sys_suspend_power_state = rcar_get_sys_suspend_power_state, +#endif +}; + +int plat_setup_psci_ops(uintptr_t sec_entrypoint, const plat_psci_ops_t **psci_ops) +{ + *psci_ops = &rcar_plat_psci_ops; + rcar_sec_entrypoint = sec_entrypoint; + +#if RCAR_SYSTEM_SUSPEND + rcar_pwrc_init_suspend_to_ram(); +#endif + return 0; +} + diff --git a/plat/renesas/common/plat_storage.c b/plat/renesas/common/plat_storage.c new file mode 100644 index 000000000..652456103 --- /dev/null +++ b/plat/renesas/common/plat_storage.c @@ -0,0 +1,417 @@ +/* + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include + +#include "io_common.h" +#include "io_memdrv.h" +#include "io_emmcdrv.h" +#include "io_private.h" +#include "io_rcar.h" +#include + +static uintptr_t emmcdrv_dev_handle; +static uintptr_t memdrv_dev_handle; +static uintptr_t rcar_dev_handle; + +static uintptr_t boot_io_drv_id; + +static const io_block_spec_t rcar_block_spec = { + .offset = FLASH0_BASE, + .length = FLASH0_SIZE +}; + +static const io_block_spec_t bl2_file_spec = { + .offset = BL2_IMAGE_ID, +}; + +static const io_block_spec_t bl31_file_spec = { + .offset = BL31_IMAGE_ID, +}; + +static const io_block_spec_t bl32_file_spec = { + .offset = BL32_IMAGE_ID, +}; + +static const io_block_spec_t bl33_file_spec = { + .offset = BL33_IMAGE_ID, +}; + +static const io_block_spec_t bl332_file_spec = { + .offset = BL332_IMAGE_ID, +}; + +static const io_block_spec_t bl333_file_spec = { + .offset = BL333_IMAGE_ID, +}; + +static const io_block_spec_t bl334_file_spec = { + .offset = BL334_IMAGE_ID, +}; + +static const io_block_spec_t bl335_file_spec = { + .offset = BL335_IMAGE_ID, +}; + +static const io_block_spec_t bl336_file_spec = { + .offset = BL336_IMAGE_ID, +}; + +static const io_block_spec_t bl337_file_spec = { + .offset = BL337_IMAGE_ID, +}; + +static const io_block_spec_t bl338_file_spec = { + .offset = BL338_IMAGE_ID, +}; + +#if TRUSTED_BOARD_BOOT +static const io_block_spec_t trusted_key_cert_file_spec = { + .offset = TRUSTED_KEY_CERT_ID, +}; + +static const io_block_spec_t bl31_key_cert_file_spec = { + .offset = SOC_FW_KEY_CERT_ID, +}; + +static const io_block_spec_t bl32_key_cert_file_spec = { + .offset = TRUSTED_OS_FW_KEY_CERT_ID, +}; + +static const io_block_spec_t bl33_key_cert_file_spec = { + .offset = NON_TRUSTED_FW_KEY_CERT_ID, +}; + +static const io_block_spec_t bl332_key_cert_file_spec = { + .offset = BL332_KEY_CERT_ID, +}; + +static const io_block_spec_t bl333_key_cert_file_spec = { + .offset = BL333_KEY_CERT_ID, +}; + +static const io_block_spec_t bl334_key_cert_file_spec = { + .offset = BL334_KEY_CERT_ID, +}; + +static const io_block_spec_t bl335_key_cert_file_spec = { + .offset = BL335_KEY_CERT_ID, +}; + +static const io_block_spec_t bl336_key_cert_file_spec = { + .offset = BL336_KEY_CERT_ID, +}; + +static const io_block_spec_t bl337_key_cert_file_spec = { + .offset = BL337_KEY_CERT_ID, +}; + +static const io_block_spec_t bl338_key_cert_file_spec = { + .offset = BL338_KEY_CERT_ID, +}; + +static const io_block_spec_t bl31_cert_file_spec = { + .offset = SOC_FW_CONTENT_CERT_ID, +}; + +static const io_block_spec_t bl32_cert_file_spec = { + .offset = TRUSTED_OS_FW_CONTENT_CERT_ID, +}; + +static const io_block_spec_t bl33_cert_file_spec = { + .offset = NON_TRUSTED_FW_CONTENT_CERT_ID, +}; + +static const io_block_spec_t bl332_cert_file_spec = { + .offset = BL332_CERT_ID, +}; + +static const io_block_spec_t bl333_cert_file_spec = { + .offset = BL333_CERT_ID, +}; + +static const io_block_spec_t bl334_cert_file_spec = { + .offset = BL334_CERT_ID, +}; + +static const io_block_spec_t bl335_cert_file_spec = { + .offset = BL335_CERT_ID, +}; + +static const io_block_spec_t bl336_cert_file_spec = { + .offset = BL336_CERT_ID, +}; + +static const io_block_spec_t bl337_cert_file_spec = { + .offset = BL337_CERT_ID, +}; + +static const io_block_spec_t bl338_cert_file_spec = { + .offset = BL338_CERT_ID, +}; +#endif + +static int32_t open_emmcdrv(const uintptr_t spec); +static int32_t open_memmap(const uintptr_t spec); +static int32_t open_rcar(const uintptr_t spec); + +struct plat_io_policy { + uintptr_t *dev_handle; + uintptr_t image_spec; + int32_t (*check)(const uintptr_t spec); +}; + +static const struct plat_io_policy policies[] = { + [FIP_IMAGE_ID] = { + &memdrv_dev_handle, + (uintptr_t) &rcar_block_spec, + &open_memmap}, + [BL2_IMAGE_ID] = { + &rcar_dev_handle, + (uintptr_t) &bl2_file_spec, + &open_rcar}, + [BL31_IMAGE_ID] = { + &rcar_dev_handle, + (uintptr_t) &bl31_file_spec, + &open_rcar}, + [BL32_IMAGE_ID] = { + &rcar_dev_handle, + (uintptr_t) &bl32_file_spec, + &open_rcar}, + [BL33_IMAGE_ID] = { + &rcar_dev_handle, + (uintptr_t) &bl33_file_spec, + &open_rcar}, + [BL332_IMAGE_ID] = { + &rcar_dev_handle, + (uintptr_t) &bl332_file_spec, + &open_rcar}, + [BL333_IMAGE_ID] = { + &rcar_dev_handle, + (uintptr_t) &bl333_file_spec, + &open_rcar}, + [BL334_IMAGE_ID] = { + &rcar_dev_handle, + (uintptr_t) &bl334_file_spec, + &open_rcar}, + [BL335_IMAGE_ID] = { + &rcar_dev_handle, + (uintptr_t) &bl335_file_spec, + &open_rcar}, + [BL336_IMAGE_ID] = { + &rcar_dev_handle, + (uintptr_t) &bl336_file_spec, + &open_rcar}, + [BL337_IMAGE_ID] = { + &rcar_dev_handle, + (uintptr_t) &bl337_file_spec, + &open_rcar}, + [BL338_IMAGE_ID] = { + &rcar_dev_handle, + (uintptr_t) &bl338_file_spec, + &open_rcar}, +#if TRUSTED_BOARD_BOOT + [TRUSTED_KEY_CERT_ID] = { + &rcar_dev_handle, + (uintptr_t) &trusted_key_cert_file_spec, + &open_rcar}, + [SOC_FW_KEY_CERT_ID] = { + &rcar_dev_handle, + (uintptr_t) &bl31_key_cert_file_spec, + &open_rcar}, + [TRUSTED_OS_FW_KEY_CERT_ID] = { + &rcar_dev_handle, + (uintptr_t) &bl32_key_cert_file_spec, + &open_rcar}, + [NON_TRUSTED_FW_KEY_CERT_ID] = { + &rcar_dev_handle, + (uintptr_t) &bl33_key_cert_file_spec, + &open_rcar}, + [BL332_KEY_CERT_ID] = { + &rcar_dev_handle, + (uintptr_t) &bl332_key_cert_file_spec, + &open_rcar}, + [BL333_KEY_CERT_ID] = { + &rcar_dev_handle, + (uintptr_t) &bl333_key_cert_file_spec, + &open_rcar}, + [BL334_KEY_CERT_ID] = { + &rcar_dev_handle, + (uintptr_t) &bl334_key_cert_file_spec, + &open_rcar}, + [BL335_KEY_CERT_ID] = { + &rcar_dev_handle, + (uintptr_t) &bl335_key_cert_file_spec, + &open_rcar}, + [BL336_KEY_CERT_ID] = { + &rcar_dev_handle, + (uintptr_t) &bl336_key_cert_file_spec, + &open_rcar}, + [BL337_KEY_CERT_ID] = { + &rcar_dev_handle, + (uintptr_t) &bl337_key_cert_file_spec, + &open_rcar}, + [BL338_KEY_CERT_ID] = { + &rcar_dev_handle, + (uintptr_t) &bl338_key_cert_file_spec, + &open_rcar}, + [SOC_FW_CONTENT_CERT_ID] = { + &rcar_dev_handle, + (uintptr_t) &bl31_cert_file_spec, + &open_rcar}, + [TRUSTED_OS_FW_CONTENT_CERT_ID] = { + &rcar_dev_handle, + (uintptr_t) &bl32_cert_file_spec, + &open_rcar}, + [NON_TRUSTED_FW_CONTENT_CERT_ID] = { + &rcar_dev_handle, + (uintptr_t) &bl33_cert_file_spec, + &open_rcar}, + [BL332_CERT_ID] = { + &rcar_dev_handle, + (uintptr_t) &bl332_cert_file_spec, + &open_rcar}, + [BL333_CERT_ID] = { + &rcar_dev_handle, + (uintptr_t) &bl333_cert_file_spec, + &open_rcar}, + [BL334_CERT_ID] = { + &rcar_dev_handle, + (uintptr_t) &bl334_cert_file_spec, + &open_rcar}, + [BL335_CERT_ID] = { + &rcar_dev_handle, + (uintptr_t) &bl335_cert_file_spec, + &open_rcar}, + [BL336_CERT_ID] = { + &rcar_dev_handle, + (uintptr_t) &bl336_cert_file_spec, + &open_rcar}, + [BL337_CERT_ID] = { + &rcar_dev_handle, + (uintptr_t) &bl337_cert_file_spec, + &open_rcar}, + [BL338_CERT_ID] = { + &rcar_dev_handle, + (uintptr_t) &bl338_cert_file_spec, + &open_rcar}, { +#else + { +#endif + 0, 0, 0} +}; + +static io_drv_spec_t io_drv_spec_memdrv = { + FLASH0_BASE, + FLASH0_SIZE, + 0, +}; + +static io_drv_spec_t io_drv_spec_emmcdrv = { + 0, + 0, + 0, +}; + +static struct plat_io_policy drv_policies[] __attribute__ ((section(".data"))) = { + /* FLASH_DEV_ID */ + { &memdrv_dev_handle, (uintptr_t) &io_drv_spec_memdrv, &open_memmap, }, + /* EMMC_DEV_ID */ + { &emmcdrv_dev_handle, (uintptr_t) &io_drv_spec_emmcdrv, &open_emmcdrv, } +}; + +static int32_t open_rcar(const uintptr_t spec) +{ + return io_dev_init(rcar_dev_handle, boot_io_drv_id); +} + +static int32_t open_memmap(const uintptr_t spec) +{ + uintptr_t handle; + int32_t result; + + result = io_dev_init(memdrv_dev_handle, 0); + if (result != IO_SUCCESS) + return result; + + result = io_open(memdrv_dev_handle, spec, &handle); + if (result == IO_SUCCESS) + io_close(handle); + + return result; +} + +static int32_t open_emmcdrv(const uintptr_t spec) +{ + return io_dev_init(emmcdrv_dev_handle, 0); +} + +void rcar_io_setup(void) +{ + const io_dev_connector_t *memmap; + const io_dev_connector_t *rcar; + + boot_io_drv_id = FLASH_DEV_ID; + + rcar_register_io_dev(&rcar); + rcar_register_io_dev_memdrv(&memmap); + io_dev_open(rcar, 0, &rcar_dev_handle); + io_dev_open(memmap, 0, &memdrv_dev_handle); +} + +void rcar_io_emmc_setup(void) +{ + const io_dev_connector_t *rcar; + const io_dev_connector_t *emmc; + + boot_io_drv_id = EMMC_DEV_ID; + + rcar_register_io_dev(&rcar); + rcar_register_io_dev_emmcdrv(&emmc); + io_dev_open(rcar, 0, &rcar_dev_handle); + io_dev_open(emmc, 0, &emmcdrv_dev_handle); +} + +int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, + uintptr_t *image_spec) +{ + const struct plat_io_policy *policy; + int result; + + policy = &policies[image_id]; + + result = policy->check(policy->image_spec); + if (result != IO_SUCCESS) + return result; + + *image_spec = policy->image_spec; + *dev_handle = *(policy->dev_handle); + + return IO_SUCCESS; +} + +int32_t plat_get_drv_source(uint32_t io_drv_id, uintptr_t *dev_handle, + uintptr_t *image_spec) +{ + const struct plat_io_policy *policy; + int32_t result; + + policy = &drv_policies[io_drv_id]; + + result = policy->check(policy->image_spec); + if (result != IO_SUCCESS) + return result; + + *image_spec = policy->image_spec; + *dev_handle = *(policy->dev_handle); + + return IO_SUCCESS; +} diff --git a/plat/renesas/common/plat_topology.c b/plat/renesas/common/plat_topology.c new file mode 100644 index 000000000..0d5880d7a --- /dev/null +++ b/plat/renesas/common/plat_topology.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2018, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include + +static const unsigned char rcar_power_domain_tree_desc[] = { + 1, + PLATFORM_CLUSTER_COUNT, + PLATFORM_CLUSTER0_CORE_COUNT, + PLATFORM_CLUSTER1_CORE_COUNT +}; + +const unsigned char *plat_get_power_domain_tree_desc(void) +{ + return rcar_power_domain_tree_desc; +} + +int plat_core_pos_by_mpidr(u_register_t mpidr) +{ + unsigned int cluster_id, cpu_id; + + mpidr &= MPIDR_AFFINITY_MASK; + + if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) + return -1; + + cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK; + cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK; + + if (cluster_id >= PLATFORM_CLUSTER_COUNT) + return -1; + + if (cluster_id == 0 && cpu_id >= PLATFORM_CLUSTER0_CORE_COUNT) + return -1; + + if (cluster_id == 1 && cpu_id >= PLATFORM_CLUSTER1_CORE_COUNT) + return -1; + + return (cpu_id + cluster_id * PLATFORM_CLUSTER0_CORE_COUNT); +} + diff --git a/plat/renesas/rcar/bl2_cpg_init.c b/plat/renesas/rcar/bl2_cpg_init.c deleted file mode 100644 index 175434469..000000000 --- a/plat/renesas/rcar/bl2_cpg_init.c +++ /dev/null @@ -1,424 +0,0 @@ -/* - * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include - -#include "cpg_registers.h" -#include "rcar_def.h" -#include "rcar_private.h" - -static void bl2_secure_cpg_init(void); - -#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_H3) || (RCAR_LSI == RCAR_H3N) -static void bl2_realtime_cpg_init_h3(void); -static void bl2_system_cpg_init_h3(void); -#endif - -#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_M3) -static void bl2_realtime_cpg_init_m3(void); -static void bl2_system_cpg_init_m3(void); -#endif - -#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_M3N) -static void bl2_realtime_cpg_init_m3n(void); -static void bl2_system_cpg_init_m3n(void); -#endif - -#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_V3M) -static void bl2_realtime_cpg_init_v3m(void); -static void bl2_system_cpg_init_v3m(void); -#endif - -#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_E3) -static void bl2_realtime_cpg_init_e3(void); -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 - -typedef struct { - uintptr_t adr; - uint32_t val; -} reg_setting_t; - -static void bl2_secure_cpg_init(void) -{ - uint32_t stop_cr2, reset_cr2; - uint32_t stop_cr4, reset_cr4; - uint32_t stop_cr5, reset_cr5; - -#if (RCAR_LSI == RCAR_D3) - reset_cr2 = 0x00000000U; - stop_cr2 = 0xFFFFFFFFU; -#elif (RCAR_LSI == RCAR_E3) - reset_cr2 = 0x10000000U; - stop_cr2 = 0xEFFFFFFFU; -#else - reset_cr2 = 0x14000000U; - stop_cr2 = 0xEBFFFFFFU; -#endif - -#if (RCAR_LSI == RCAR_D3) - reset_cr4 = 0x00000000U; - stop_cr4 = 0xFFFFFFFFU; - reset_cr5 = 0x00000000U; - stop_cr5 = 0xFFFFFFFFU; -#else - reset_cr4 = 0x80000003U; - stop_cr4 = 0x7FFFFFFFU; - reset_cr5 = 0x40000000U; - stop_cr5 = 0xBFFFFFFFU; -#endif - - /* Secure Module Stop Control Registers */ - cpg_write(SCMSTPCR0, 0xFFFFFFFFU); - cpg_write(SCMSTPCR1, 0xFFFFFFFFU); - cpg_write(SCMSTPCR2, stop_cr2); - cpg_write(SCMSTPCR3, 0xFFFFFFFFU); - cpg_write(SCMSTPCR4, stop_cr4); - cpg_write(SCMSTPCR5, stop_cr5); - cpg_write(SCMSTPCR6, 0xFFFFFFFFU); - cpg_write(SCMSTPCR7, 0xFFFFFFFFU); - cpg_write(SCMSTPCR8, 0xFFFFFFFFU); - cpg_write(SCMSTPCR9, 0xFFFDFFFFU); - cpg_write(SCMSTPCR10, 0xFFFFFFFFU); - cpg_write(SCMSTPCR11, 0xFFFFFFFFU); - - /* Secure Software Reset Access Enable Control Registers */ - cpg_write(SCSRSTECR0, 0x00000000U); - cpg_write(SCSRSTECR1, 0x00000000U); - cpg_write(SCSRSTECR2, reset_cr2); - cpg_write(SCSRSTECR3, 0x00000000U); - cpg_write(SCSRSTECR4, reset_cr4); - cpg_write(SCSRSTECR5, reset_cr5); - cpg_write(SCSRSTECR6, 0x00000000U); - cpg_write(SCSRSTECR7, 0x00000000U); - cpg_write(SCSRSTECR8, 0x00000000U); - cpg_write(SCSRSTECR9, 0x00020000U); - cpg_write(SCSRSTECR10, 0x00000000U); - cpg_write(SCSRSTECR11, 0x00000000U); -} - -#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_H3) || (RCAR_LSI == RCAR_H3N) -static void bl2_realtime_cpg_init_h3(void) -{ - uint32_t cut = mmio_read_32(RCAR_PRR) & PRR_CUT_MASK; - uint32_t cr0, cr8; - - cr0 = (cut == PRR_PRODUCT_10 || cut == PRR_PRODUCT_11) ? - 0x00200000U : 0x00210000U; - cr8 = (cut == PRR_PRODUCT_10 || cut == PRR_PRODUCT_11) ? - 0x01F1FFF4U : 0x01F1FFF7U; - - cpg_write(RMSTPCR0, cr0); - cpg_write(RMSTPCR1, 0xFFFFFFFFU); - cpg_write(RMSTPCR2, 0x040E0FDCU); - cpg_write(RMSTPCR3, 0xFFFFFFDFU); - cpg_write(RMSTPCR4, 0x80000004U); - cpg_write(RMSTPCR5, 0xC3FFFFFFU); - cpg_write(RMSTPCR6, 0xFFFFFFFFU); - cpg_write(RMSTPCR7, 0xFFFFFFFFU); - cpg_write(RMSTPCR8, cr8); - cpg_write(RMSTPCR9, 0xFFFFFFFEU); - cpg_write(RMSTPCR10, 0xFFFEFFE0U); - cpg_write(RMSTPCR11, 0x000000B7U); -} - -static void bl2_system_cpg_init_h3(void) -{ - /** System Module Stop Control Registers */ - cpg_write(SMSTPCR0, 0x00210000U); - cpg_write(SMSTPCR1, 0xFFFFFFFFU); - cpg_write(SMSTPCR2, 0x040E2FDCU); - cpg_write(SMSTPCR3, 0xFFFFFBDFU); - cpg_write(SMSTPCR4, 0x80000004U); - cpg_write(SMSTPCR5, 0xC3FFFFFFU); - cpg_write(SMSTPCR6, 0xFFFFFFFFU); - cpg_write(SMSTPCR7, 0xFFFFFFFFU); - cpg_write(SMSTPCR8, 0x01F1FFF5U); - cpg_write(SMSTPCR9, 0xFFFFFFFFU); - cpg_write(SMSTPCR10, 0xFFFEFFE0U); - cpg_write(SMSTPCR11, 0x000000B7U); -} -#endif - -#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_M3) -static void bl2_realtime_cpg_init_m3(void) -{ - /* Realtime Module Stop Control Registers */ - cpg_write(RMSTPCR0, 0x00200000U); - cpg_write(RMSTPCR1, 0xFFFFFFFFU); - cpg_write(RMSTPCR2, 0x040E0FDCU); - cpg_write(RMSTPCR3, 0xFFFFFFDFU); - cpg_write(RMSTPCR4, 0x80000004U); - cpg_write(RMSTPCR5, 0xC3FFFFFFU); - cpg_write(RMSTPCR6, 0xFFFFFFFFU); - cpg_write(RMSTPCR7, 0xFFFFFFFFU); - cpg_write(RMSTPCR8, 0x01F1FFF7U); - cpg_write(RMSTPCR9, 0xFFFFFFFEU); - cpg_write(RMSTPCR10, 0xFFFEFFE0U); - cpg_write(RMSTPCR11, 0x000000B7U); -} - -static void bl2_system_cpg_init_m3(void) -{ - /* System Module Stop Control Registers */ - cpg_write(SMSTPCR0, 0x00200000U); - cpg_write(SMSTPCR1, 0xFFFFFFFFU); - cpg_write(SMSTPCR2, 0x040E2FDCU); - cpg_write(SMSTPCR3, 0xFFFFFBDFU); - cpg_write(SMSTPCR4, 0x80000004U); - cpg_write(SMSTPCR5, 0xC3FFFFFFU); - cpg_write(SMSTPCR6, 0xFFFFFFFFU); - cpg_write(SMSTPCR7, 0xFFFFFFFFU); - cpg_write(SMSTPCR8, 0x01F1FFF7U); - cpg_write(SMSTPCR9, 0xFFFFFFFFU); - cpg_write(SMSTPCR10, 0xFFFEFFE0U); - cpg_write(SMSTPCR11, 0x000000B7U); -} -#endif - -#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_M3N) -static void bl2_realtime_cpg_init_m3n(void) -{ - /* Realtime Module Stop Control Registers */ - cpg_write(RMSTPCR0, 0x00210000U); - cpg_write(RMSTPCR1, 0xFFFFFFFFU); - cpg_write(RMSTPCR2, 0x040E0FDCU); - cpg_write(RMSTPCR3, 0xFFFFFFDFU); - cpg_write(RMSTPCR4, 0x80000004U); - cpg_write(RMSTPCR5, 0xC3FFFFFFU); - cpg_write(RMSTPCR6, 0xFFFFFFFFU); - cpg_write(RMSTPCR7, 0xFFFFFFFFU); - cpg_write(RMSTPCR8, 0x00F1FFF7U); - cpg_write(RMSTPCR9, 0xFFFFFFFFU); - cpg_write(RMSTPCR10, 0xFFFFFFE0U); - cpg_write(RMSTPCR11, 0x000000B7U); -} - -static void bl2_system_cpg_init_m3n(void) -{ - /* System Module Stop Control Registers */ - cpg_write(SMSTPCR0, 0x00210000U); - cpg_write(SMSTPCR1, 0xFFFFFFFFU); - cpg_write(SMSTPCR2, 0x040E2FDCU); - cpg_write(SMSTPCR3, 0xFFFFFBDFU); - cpg_write(SMSTPCR4, 0x80000004U); - cpg_write(SMSTPCR5, 0xC3FFFFFFU); - cpg_write(SMSTPCR6, 0xFFFFFFFFU); - cpg_write(SMSTPCR7, 0xFFFFFFFFU); - cpg_write(SMSTPCR8, 0x00F1FFF7U); - cpg_write(SMSTPCR9, 0xFFFFFFFFU); - cpg_write(SMSTPCR10, 0xFFFFFFE0U); - cpg_write(SMSTPCR11, 0x000000B7U); -} -#endif - -#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_V3M) -static void bl2_realtime_cpg_init_v3m(void) -{ - /* Realtime Module Stop Control Registers */ - cpg_write(RMSTPCR0, 0x00230000U); - cpg_write(RMSTPCR1, 0xFFFFFFFFU); - cpg_write(RMSTPCR2, 0x14062FD8U); - cpg_write(RMSTPCR3, 0xFFFFFFDFU); - cpg_write(RMSTPCR4, 0x80000184U); - cpg_write(RMSTPCR5, 0x83FFFFFFU); - cpg_write(RMSTPCR6, 0xFFFFFFFFU); - cpg_write(RMSTPCR7, 0xFFFFFFFFU); - cpg_write(RMSTPCR8, 0x7FF3FFF4U); - cpg_write(RMSTPCR9, 0xFFFFFFFEU); -} - -static void bl2_system_cpg_init_v3m(void) -{ - /* System Module Stop Control Registers */ - cpg_write(SMSTPCR0, 0x00210000U); - cpg_write(SMSTPCR1, 0xFFFFFFFFU); - cpg_write(SMSTPCR2, 0x340E2FDCU); - cpg_write(SMSTPCR3, 0xFFFFFBDFU); - cpg_write(SMSTPCR4, 0x80000004U); - cpg_write(SMSTPCR5, 0xC3FFFFFFU); - cpg_write(SMSTPCR6, 0xFFFFFFFFU); - cpg_write(SMSTPCR7, 0xFFFFFFFFU); - cpg_write(SMSTPCR8, 0x01F1FFF5U); - cpg_write(SMSTPCR9, 0xFFFFFFFEU); -} -#endif - -#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_E3) -static void bl2_realtime_cpg_init_e3(void) -{ - /* Realtime Module Stop Control Registers */ - cpg_write(RMSTPCR0, 0x00210000U); - cpg_write(RMSTPCR1, 0xFFFFFFFFU); - cpg_write(RMSTPCR2, 0x000E0FDCU); - cpg_write(RMSTPCR3, 0xFFFFFFDFU); - cpg_write(RMSTPCR4, 0x80000004U); - cpg_write(RMSTPCR5, 0xC3FFFFFFU); - cpg_write(RMSTPCR6, 0xFFFFFFFFU); - cpg_write(RMSTPCR7, 0xFFFFFFFFU); - cpg_write(RMSTPCR8, 0x00F1FFF7U); - cpg_write(RMSTPCR9, 0xFFFFFFDFU); - cpg_write(RMSTPCR10, 0xFFFFFFE8U); - cpg_write(RMSTPCR11, 0x000000B7U); -} - -static void bl2_system_cpg_init_e3(void) -{ - /* System Module Stop Control Registers */ - cpg_write(SMSTPCR0, 0x00210000U); - cpg_write(SMSTPCR1, 0xFFFFFFFFU); - cpg_write(SMSTPCR2, 0x000E2FDCU); - cpg_write(SMSTPCR3, 0xFFFFFBDFU); - cpg_write(SMSTPCR4, 0x80000004U); - cpg_write(SMSTPCR5, 0xC3FFFFFFU); - cpg_write(SMSTPCR6, 0xFFFFFFFFU); - cpg_write(SMSTPCR7, 0xFFFFFFFFU); - cpg_write(SMSTPCR8, 0x00F1FFF7U); - cpg_write(SMSTPCR9, 0xFFFFFFDFU); - cpg_write(SMSTPCR10, 0xFFFFFFE8U); - cpg_write(SMSTPCR11, 0x000000B7U); -} -#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 */ - cpg_write(SMSTPCR0, 0x00010000U); - cpg_write(SMSTPCR1, 0xFFFFFFFFU); - cpg_write(SMSTPCR2, 0x00060FDCU); - cpg_write(SMSTPCR3, 0xFFFFFBDFU); - cpg_write(SMSTPCR4, 0x00000084U); - cpg_write(SMSTPCR5, 0x83FFFFFFU); - cpg_write(SMSTPCR6, 0xFFFFFFFFU); - cpg_write(SMSTPCR7, 0xFFFFFFFFU); - cpg_write(SMSTPCR8, 0x00F1FFF7U); - cpg_write(SMSTPCR9, 0xF3F5E016U); - cpg_write(SMSTPCR10, 0xFFFEFFE0U); - cpg_write(SMSTPCR11, 0x000000B7U); -} -#endif - -void bl2_cpg_init(void) -{ - uint32_t boot_cpu = mmio_read_32(RCAR_MODEMR) & MODEMR_BOOT_CPU_MASK; -#if RCAR_LSI == RCAR_AUTO - uint32_t product = mmio_read_32(RCAR_PRR) & PRR_PRODUCT_MASK; -#endif - bl2_secure_cpg_init(); - - if (boot_cpu == MODEMR_BOOT_CPU_CA57 || - boot_cpu == MODEMR_BOOT_CPU_CA53) { -#if RCAR_LSI == RCAR_AUTO - - switch (product) { - case PRR_PRODUCT_H3: - bl2_realtime_cpg_init_h3(); - break; - case PRR_PRODUCT_M3: - bl2_realtime_cpg_init_m3(); - break; - case PRR_PRODUCT_M3N: - bl2_realtime_cpg_init_m3n(); - break; - case PRR_PRODUCT_V3M: - bl2_realtime_cpg_init_v3m(); - break; - case PRR_PRODUCT_E3: - bl2_realtime_cpg_init_e3(); - break; - case PRR_PRODUCT_D3: - bl2_realtime_cpg_init_d3(); - break; - default: - panic(); - break; - } -#elif (RCAR_LSI == RCAR_H3) || (RCAR_LSI == RCAR_H3N) - bl2_realtime_cpg_init_h3(); -#elif RCAR_LSI == RCAR_M3 - bl2_realtime_cpg_init_m3(); -#elif RCAR_LSI == RCAR_M3N - bl2_realtime_cpg_init_m3n(); -#elif RCAR_LSI == RCAR_V3M - bl2_realtime_cpg_init_v3m(); -#elif RCAR_LSI == RCAR_E3 - bl2_realtime_cpg_init_e3(); -#elif RCAR_LSI == RCAR_D3 - bl2_realtime_cpg_init_d3(); -#else -#error "Don't have CPG initialize routine(unknown)." -#endif - } -} - -void bl2_system_cpg_init(void) -{ -#if RCAR_LSI == RCAR_AUTO - uint32_t product = mmio_read_32(RCAR_PRR) & PRR_PRODUCT_MASK; - - switch (product) { - case PRR_PRODUCT_H3: - bl2_system_cpg_init_h3(); - break; - case PRR_PRODUCT_M3: - bl2_system_cpg_init_m3(); - break; - case PRR_PRODUCT_M3N: - bl2_system_cpg_init_m3n(); - break; - case PRR_PRODUCT_V3M: - bl2_system_cpg_init_v3m(); - break; - case PRR_PRODUCT_E3: - bl2_system_cpg_init_e3(); - break; - case PRR_PRODUCT_D3: - bl2_system_cpg_init_d3(); - break; - default: - panic(); - break; - } -#elif (RCAR_LSI == RCAR_H3) || (RCAR_LSI == RCAR_H3N) - bl2_system_cpg_init_h3(); -#elif RCAR_LSI == RCAR_M3 - bl2_system_cpg_init_m3(); -#elif RCAR_LSI == RCAR_M3N - bl2_system_cpg_init_m3n(); -#elif RCAR_LSI == RCAR_V3M - bl2_system_cpg_init_v3m(); -#elif RCAR_LSI == RCAR_E3 - bl2_system_cpg_init_e3(); -#elif RCAR_LSI == RCAR_D3 - bl2_system_cpg_init_d3(); -#else -#error "Don't have CPG initialize routine(unknown)." -#endif -} diff --git a/plat/renesas/rcar/bl2_interrupt_error.c b/plat/renesas/rcar/bl2_interrupt_error.c deleted file mode 100644 index d9a4b8e62..000000000 --- a/plat/renesas/rcar/bl2_interrupt_error.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include -#include -#include -#include - -#include "rcar_def.h" - -#define SWDT_ERROR_ID (1024U) -#define SWDT_ERROR_TYPE (16U) -#define SWDT_CHAR_MAX (13U) - -extern void rcar_swdt_release(void); - -void bl2_interrupt_error_id(uint32_t int_id) -{ - ERROR("\n"); - if (int_id >= SWDT_ERROR_ID) { - ERROR("Unhandled exception occurred.\n"); - ERROR(" Exception type = FIQ_SP_EL0\n"); - panic(); - } - - /* Clear the interrupt request */ - gicv2_end_of_interrupt((uint32_t) int_id); - rcar_swdt_release(); - ERROR("Unhandled exception occurred.\n"); - ERROR(" Exception type = FIQ_SP_EL0\n"); - ERROR(" SPSR_EL3 = 0x%x\n", (uint32_t) read_spsr_el3()); - ERROR(" ELR_EL3 = 0x%x\n", (uint32_t) read_elr_el3()); - ERROR(" ESR_EL3 = 0x%x\n", (uint32_t) read_esr_el3()); - ERROR(" FAR_EL3 = 0x%x\n", (uint32_t) read_far_el3()); - ERROR("\n"); - panic(); -} - -void bl2_interrupt_error_type(uint32_t ex_type) -{ - const uint8_t interrupt_ex[SWDT_ERROR_TYPE][SWDT_CHAR_MAX] = { - "SYNC SP EL0", - "IRQ SP EL0", - "FIQ SP EL0", - "SERR SP EL0", - "SYNC SP ELx", - "IRQ SP ELx", - "FIQ SP ELx", - "SERR SP ELx", - "SYNC AARCH64", - "IRQ AARCH64", - "FIQ AARCH64", - "SERR AARCH64", - "SYNC AARCH32", - "IRQ AARCH32", - "FIQ AARCH32", - "SERR AARCH32" - }; - char msg[128]; - - /* Clear the interrupt request */ - if (ex_type >= SWDT_ERROR_TYPE) { - ERROR("\n"); - ERROR("Unhandled exception occurred.\n"); - ERROR(" Exception type = Unknown (%d)\n", ex_type); - goto loop; - } - - rcar_swdt_release(); - ERROR("\n"); - ERROR("Unhandled exception occurred.\n"); - snprintf(msg, sizeof(msg), " Exception type = %s\n", - &interrupt_ex[ex_type][0]); - ERROR("%s", msg); - switch (ex_type) { - case SYNC_EXCEPTION_SP_EL0: - ERROR(" SPSR_EL3 = 0x%x\n", (uint32_t) read_spsr_el3()); - ERROR(" ELR_EL3 = 0x%x\n", (uint32_t) read_elr_el3()); - ERROR(" ESR_EL3 = 0x%x\n", (uint32_t) read_esr_el3()); - ERROR(" FAR_EL3 = 0x%x\n", (uint32_t) read_far_el3()); - break; - case IRQ_SP_EL0: - ERROR(" SPSR_EL3 = 0x%x\n", (uint32_t) read_spsr_el3()); - ERROR(" ELR_EL3 = 0x%x\n", (uint32_t) read_elr_el3()); - ERROR(" IAR_EL3 = 0x%x\n", gicv2_acknowledge_interrupt()); - break; - case FIQ_SP_EL0: - ERROR(" SPSR_EL3 = 0x%x\n", (uint32_t) read_spsr_el3()); - ERROR(" ELR_EL3 = 0x%x\n", (uint32_t) read_elr_el3()); - ERROR(" IAR_EL3 = 0x%x\n", gicv2_acknowledge_interrupt()); - break; - case SERROR_SP_EL0: - ERROR(" SPSR_EL3 = 0x%x\n", (uint32_t) read_spsr_el3()); - ERROR(" ELR_EL3 = 0x%x\n", (uint32_t) read_elr_el3()); - ERROR(" ESR_EL3 = 0x%x\n", (uint32_t) read_esr_el3()); - ERROR(" FAR_EL3 = 0x%x\n", (uint32_t) read_far_el3()); - break; - default: - break; - } -loop: - ERROR("\n"); - panic(); -} diff --git a/plat/renesas/rcar/bl2_plat_mem_params_desc.c b/plat/renesas/rcar/bl2_plat_mem_params_desc.c deleted file mode 100644 index bf2706d53..000000000 --- a/plat/renesas/rcar/bl2_plat_mem_params_desc.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include -#include -#include -#include - -#if (RCAR_BL33_EXECUTION_EL != 0) && (RCAR_BL33_EXECUTION_EL != 1) -#error -#endif - -#if (RCAR_BL33_EXECUTION_EL == 0) -#define BL33_MODE MODE_EL1 -#else -#define BL33_MODE MODE_EL2 -#endif - -extern uint64_t fdt_blob[PAGE_SIZE_4KB / sizeof(uint64_t)]; - -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.spsr = SPSR_64(MODE_EL3, - MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS), - .ep_info.pc = BL31_BASE, - - - SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2, - image_info_t, IMAGE_ATTRIB_PLAT_SETUP), - .image_info.image_max_size = BL31_LIMIT - BL31_BASE, - .image_info.image_base = BL31_BASE, - -# ifdef BL32_BASE - .next_handoff_image_id = BL32_IMAGE_ID, -# else - .next_handoff_image_id = BL33_IMAGE_ID, -# endif - }, -# ifdef BL32_BASE - { - .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, - .ep_info.spsr = 0, - .ep_info.args.arg3 = (uintptr_t)fdt_blob, - - SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2, - image_info_t, 0), - .image_info.image_max_size = BL32_LIMIT - BL32_BASE, - .image_info.image_base = BL32_BASE, - - .next_handoff_image_id = BL33_IMAGE_ID, - }, -#endif - { - .image_id = BL33_IMAGE_ID, - - SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, VERSION_2, - entry_point_info_t, NON_SECURE | EXECUTABLE), - .ep_info.spsr = SPSR_64(BL33_MODE, MODE_SP_ELX, - DISABLE_ALL_EXCEPTIONS), - .ep_info.pc = BL33_BASE, -#ifdef RCAR_BL33_ARG0 - .ep_info.args.arg0 = RCAR_BL33_ARG0, -#endif - .ep_info.args.arg1 = (uintptr_t)fdt_blob, - SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2, - image_info_t, 0), - .image_info.image_max_size = - (uint32_t) (DRAM_LIMIT - BL33_BASE), - .image_info.image_base = BL33_BASE, - - .next_handoff_image_id = INVALID_IMAGE_ID, - } -}; - -REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs) diff --git a/plat/renesas/rcar/bl2_secure_setting.c b/plat/renesas/rcar/bl2_secure_setting.c deleted file mode 100644 index 095d1f62a..000000000 --- a/plat/renesas/rcar/bl2_secure_setting.c +++ /dev/null @@ -1,362 +0,0 @@ -/* - * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include - -#include "axi_registers.h" -#include "lifec_registers.h" -#include "micro_delay.h" - -static void lifec_security_setting(void); -static void axi_security_setting(void); - -static const struct { - uint32_t reg; - uint32_t val; -} lifec[] = { - /* - * LIFEC0 (SECURITY) settings - * Security attribute setting for master ports - * Bit 0: ARM realtime core (Cortex-R7) master port - * 0: Non-Secure - */ - { SEC_SRC, 0x0000001EU }, - /* - * Security attribute setting for slave ports 0 to 15 - * {SEC_SEL0, 0xFFFFFFFFU}, - * {SEC_SEL1, 0xFFFFFFFFU}, - * {SEC_SEL2, 0xFFFFFFFFU}, - * Bit19: AXI-Bus (Main Memory domain AXI) slave ports - * 0: registers accessed from secure resource only - * Bit 9: DBSC4 register access slave ports. - * 0: registers accessed from secure resource only. - */ -#if (LIFEC_DBSC_PROTECT_ENABLE == 1) - { SEC_SEL3, 0xFFF7FDFFU }, -#else /* LIFEC_DBSC_PROTECT_ENABLE == 1 */ - { SEC_SEL3, 0xFFFFFFFFU }, -#endif /* LIFEC_DBSC_PROTECT_ENABLE == 1 */ - /* - * {SEC_SEL4, 0xFFFFFFFFU}, - * Bit 6: Boot ROM slave ports. - * 0: registers accessed from secure resource only - */ - { SEC_SEL5, 0xFFFFFFBFU }, - /* - * Bit13: SCEG PKA (secure APB) slave ports - * 0: registers accessed from secure resource only - * 1: Reserved[R-Car E3] - * Bit12: SCEG PKA (public APB) slave ports - * 0: registers accessed from secure resource only - * 1: Reserved[R-Car E3] - * Bit10: SCEG Secure Core slave ports - * 0: registers accessed from secure resource only - */ -#if (RCAR_LSI == RCAR_E3) || (RCAR_LSI == RCAR_D3) - { SEC_SEL6, 0xFFFFFBFFU }, -#else /* (RCAR_LSI == RCAR_E3) || (RCAR_LSI == RCAR_D3) */ - { SEC_SEL6, 0xFFFFCBFFU }, -#endif /* (RCAR_LSI == RCAR_E3) || (RCAR_LSI == RCAR_D3) */ - /* - * {SEC_SEL7, 0xFFFFFFFFU}, - * {SEC_SEL8, 0xFFFFFFFFU}, - * {SEC_SEL9, 0xFFFFFFFFU}, - * {SEC_SEL10, 0xFFFFFFFFU}, - * {SEC_SEL11, 0xFFFFFFFFU}, - * {SEC_SEL12, 0xFFFFFFFFU}, - * Bit22: RPC slave ports. - * 0: registers accessed from secure resource only. - */ -#if (RCAR_RPC_HYPERFLASH_LOCKED == 1) - { SEC_SEL13, 0xFFBFFFFFU }, -#endif /* (RCAR_RPC_HYPERFLASH_LOCKED == 1) */ - /* - * Bit27: System Timer (SCMT) slave ports - * 0: registers accessed from secure resource only - * Bit26: System Watchdog Timer (SWDT) slave ports - * 0: registers accessed from secure resource only - */ - { SEC_SEL14, 0xF3FFFFFFU }, - /* - * Bit13: RST slave ports. - * 0: registers accessed from secure resource only - * Bit 7: Life Cycle 0 slave ports - * 0: registers accessed from secure resource only - */ - { SEC_SEL15, 0xFFFFFF3FU }, - /* - * Security group 0 attribute setting for master ports 0 - * Security group 1 attribute setting for master ports 0 - * {SEC_GRP0CR0, 0x00000000U}, - * {SEC_GRP1CR0, 0x00000000U}, - * Security group 0 attribute setting for master ports 1 - * Security group 1 attribute setting for master ports 1 - * {SEC_GRP0CR1, 0x00000000U}, - * {SEC_GRP1CR1, 0x00000000U}, - * Security group 0 attribute setting for master ports 2 - * Security group 1 attribute setting for master ports 2 - * Bit17: SCEG Secure Core master ports. - * SecurityGroup3 - */ - { SEC_GRP0CR2, 0x00020000U }, - { SEC_GRP1CR2, 0x00020000U }, - /* - * Security group 0 attribute setting for master ports 3 - * Security group 1 attribute setting for master ports 3 - * {SEC_GRP0CR3, 0x00000000U}, - * {SEC_GRP1CR3, 0x00000000U}, - * Security group 0 attribute setting for slave ports 0 - * Security group 1 attribute setting for slave ports 0 - * {SEC_GRP0COND0, 0x00000000U}, - * {SEC_GRP1COND0, 0x00000000U}, - * Security group 0 attribute setting for slave ports 1 - * Security group 1 attribute setting for slave ports 1 - * {SEC_GRP0COND1, 0x00000000U}, - * {SEC_GRP1COND1, 0x00000000U}, - * Security group 0 attribute setting for slave ports 2 - * Security group 1 attribute setting for slave ports 2 - * {SEC_GRP0COND2, 0x00000000U}, - * {SEC_GRP1COND2, 0x00000000U}, - * Security group 0 attribute setting for slave ports 3 - * Security group 1 attribute setting for slave ports 3 - * Bit19: AXI-Bus (Main Memory domain AXI) slave ports. - * SecurityGroup3 - * Bit 9: DBSC4 register access slave ports. - * SecurityGroup3 - */ -#if (LIFEC_DBSC_PROTECT_ENABLE == 1) - { SEC_GRP0COND3, 0x00080200U }, - { SEC_GRP1COND3, 0x00080200U }, -#else /* (LIFEC_DBSC_PROTECT_ENABLE == 1) */ - { SEC_GRP0COND3, 0x00000000U }, - { SEC_GRP1COND3, 0x00000000U }, -#endif /* (LIFEC_DBSC_PROTECT_ENABLE == 1) */ - /* - * Security group 0 attribute setting for slave ports 4 - * Security group 1 attribute setting for slave ports 4 - * {SEC_GRP0COND4, 0x00000000U}, - * {SEC_GRP1COND4, 0x00000000U}, - * Security group 0 attribute setting for slave ports 5 - * Security group 1 attribute setting for slave ports 5 - * Bit 6: Boot ROM slave ports - * SecurityGroup3 - */ - { SEC_GRP0COND5, 0x00000040U }, - { SEC_GRP1COND5, 0x00000040U }, - /* - * Security group 0 attribute setting for slave ports 6 - * Security group 1 attribute setting for slave ports 6 - * Bit13: SCEG PKA (secure APB) slave ports - * SecurityGroup3 - * Reserved[R-Car E3] - * Bit12: SCEG PKA (public APB) slave ports - * SecurityGroup3 - * Reserved[R-Car E3] - * Bit10: SCEG Secure Core slave ports - * SecurityGroup3 - */ -#if RCAR_LSI == RCAR_E3 - { SEC_GRP0COND6, 0x00000400U }, - { SEC_GRP1COND6, 0x00000400U }, -#else /* RCAR_LSI == RCAR_E3 */ - { SEC_GRP0COND6, 0x00003400U }, - { SEC_GRP1COND6, 0x00003400U }, -#endif /* RCAR_LSI == RCAR_E3 */ - /* - * Security group 0 attribute setting for slave ports 7 - * Security group 1 attribute setting for slave ports 7 - * {SEC_GRP0COND7, 0x00000000U}, - * {SEC_GRP1COND7, 0x00000000U}, - * Security group 0 attribute setting for slave ports 8 - * Security group 1 attribute setting for slave ports 8 - * {SEC_GRP0COND8, 0x00000000U}, - * {SEC_GRP1COND8, 0x00000000U}, - * Security group 0 attribute setting for slave ports 9 - * Security group 1 attribute setting for slave ports 9 - * {SEC_GRP0COND9, 0x00000000U}, - * {SEC_GRP1COND9, 0x00000000U}, - * Security group 0 attribute setting for slave ports 10 - * Security group 1 attribute setting for slave ports 10 - * {SEC_GRP0COND10, 0x00000000U}, - * {SEC_GRP1COND10, 0x00000000U}, - * Security group 0 attribute setting for slave ports 11 - * Security group 1 attribute setting for slave ports 11 - * {SEC_GRP0COND11, 0x00000000U}, - * {SEC_GRP1COND11, 0x00000000U}, - * Security group 0 attribute setting for slave ports 12 - * Security group 1 attribute setting for slave ports 12 - * {SEC_GRP0COND12, 0x00000000U}, - * {SEC_GRP1COND12, 0x00000000U}, - * Security group 0 attribute setting for slave ports 13 - * Security group 1 attribute setting for slave ports 13 - * Bit22: RPC slave ports. - * SecurityGroup3 - */ -#if (RCAR_RPC_HYPERFLASH_LOCKED == 1) - { SEC_GRP0COND13, 0x00400000U }, - { SEC_GRP1COND13, 0x00400000U }, -#endif /* (RCAR_RPC_HYPERFLASH_LOCKED == 1) */ - /* - * Security group 0 attribute setting for slave ports 14 - * Security group 1 attribute setting for slave ports 14 - * Bit26: System Timer (SCMT) slave ports - * SecurityGroup3 - * Bit27: System Watchdog Timer (SWDT) slave ports - * SecurityGroup3 - */ - { SEC_GRP0COND14, 0x0C000000U }, - { SEC_GRP1COND14, 0x0C000000U }, - /* - * Security group 0 attribute setting for slave ports 15 - * Security group 1 attribute setting for slave ports 15 - * Bit13: RST slave ports - * SecurityGroup3 - * Bit 7: Life Cycle 0 slave ports - * SecurityGroup3 - * Bit 6: TDBG slave ports - * SecurityGroup3 - */ - { SEC_GRP0COND15, 0x000000C0U }, - { SEC_GRP1COND15, 0x000000C0U }, - /* - * Security write protection attribute setting slave ports 0 - * {SEC_READONLY0, 0x00000000U}, - * Security write protection attribute setting slave ports 1 - * {SEC_READONLY1, 0x00000000U}, - * Security write protection attribute setting slave ports 2 - * {SEC_READONLY2, 0x00000000U}, - * Security write protection attribute setting slave ports 3 - * {SEC_READONLY3, 0x00000000U}, - * Security write protection attribute setting slave ports 4 - * {SEC_READONLY4, 0x00000000U}, - * Security write protection attribute setting slave ports 5 - * {SEC_READONLY5, 0x00000000U}, - * Security write protection attribute setting slave ports 6 - * {SEC_READONLY6, 0x00000000U}, - * Security write protection attribute setting slave ports 7 - * {SEC_READONLY7, 0x00000000U}, - * Security write protection attribute setting slave ports 8 - * {SEC_READONLY8, 0x00000000U}, - * Security write protection attribute setting slave ports 9 - * {SEC_READONLY9, 0x00000000U}, - * Security write protection attribute setting slave ports 10 - * {SEC_READONLY10, 0x00000000U}, - * Security write protection attribute setting slave ports 11 - * {SEC_READONLY11, 0x00000000U}, - * Security write protection attribute setting slave ports 12 - * {SEC_READONLY12, 0x00000000U}, - * Security write protection attribute setting slave ports 13 - * {SEC_READONLY13, 0x00000000U}, - * Security write protection attribute setting slave ports 14 - * {SEC_READONLY14, 0x00000000U}, - * Security write protection attribute setting slave ports 15 - * {SEC_READONLY15, 0x00000000U} - */ -}; - -/* AXI settings */ -static const struct { - uint32_t reg; - uint32_t val; -} axi[] = { - /* - * DRAM protection - * AXI dram protected area division - */ - {AXI_DPTDIVCR0, 0x0E0403F0U}, - {AXI_DPTDIVCR1, 0x0E0407E0U}, - {AXI_DPTDIVCR2, 0x0E080000U}, - {AXI_DPTDIVCR3, 0x0E080000U}, - {AXI_DPTDIVCR4, 0x0E080000U}, - {AXI_DPTDIVCR5, 0x0E080000U}, - {AXI_DPTDIVCR6, 0x0E080000U}, - {AXI_DPTDIVCR7, 0x0E080000U}, - {AXI_DPTDIVCR8, 0x0E080000U}, - {AXI_DPTDIVCR9, 0x0E080000U}, - {AXI_DPTDIVCR10, 0x0E080000U}, - {AXI_DPTDIVCR11, 0x0E080000U}, - {AXI_DPTDIVCR12, 0x0E080000U}, - {AXI_DPTDIVCR13, 0x0E080000U}, - {AXI_DPTDIVCR14, 0x0E080000U}, - /* AXI dram protected area setting */ - {AXI_DPTCR0, 0x0E000000U}, - {AXI_DPTCR1, 0x0E000E0EU}, - {AXI_DPTCR2, 0x0E000000U}, - {AXI_DPTCR3, 0x0E000000U}, - {AXI_DPTCR4, 0x0E000000U}, - {AXI_DPTCR5, 0x0E000000U}, - {AXI_DPTCR6, 0x0E000000U}, - {AXI_DPTCR7, 0x0E000000U}, - {AXI_DPTCR8, 0x0E000000U}, - {AXI_DPTCR9, 0x0E000000U}, - {AXI_DPTCR10, 0x0E000000U}, - {AXI_DPTCR11, 0x0E000000U}, - {AXI_DPTCR12, 0x0E000000U}, - {AXI_DPTCR13, 0x0E000000U}, - {AXI_DPTCR14, 0x0E000000U}, - {AXI_DPTCR15, 0x0E000000U}, - /* - * SRAM ptotection - * AXI sram protected area division - */ - {AXI_SPTDIVCR0, 0x0E0E6304U}, - {AXI_SPTDIVCR1, 0x0E0E6360U}, - {AXI_SPTDIVCR2, 0x0E0E6360U}, - {AXI_SPTDIVCR3, 0x0E0E6360U}, - {AXI_SPTDIVCR4, 0x0E0E6360U}, - {AXI_SPTDIVCR5, 0x0E0E6360U}, - {AXI_SPTDIVCR6, 0x0E0E6360U}, - {AXI_SPTDIVCR7, 0x0E0E6360U}, - {AXI_SPTDIVCR8, 0x0E0E6360U}, - {AXI_SPTDIVCR9, 0x0E0E6360U}, - {AXI_SPTDIVCR10, 0x0E0E6360U}, - {AXI_SPTDIVCR11, 0x0E0E6360U}, - {AXI_SPTDIVCR12, 0x0E0E6360U}, - {AXI_SPTDIVCR13, 0x0E0E6360U}, - {AXI_SPTDIVCR14, 0x0E0E6360U}, - /* AXI sram protected area setting */ - {AXI_SPTCR0, 0x0E000E0EU}, - {AXI_SPTCR1, 0x0E000000U}, - {AXI_SPTCR2, 0x0E000000U}, - {AXI_SPTCR3, 0x0E000000U}, - {AXI_SPTCR4, 0x0E000000U}, - {AXI_SPTCR5, 0x0E000000U}, - {AXI_SPTCR6, 0x0E000000U}, - {AXI_SPTCR7, 0x0E000000U}, - {AXI_SPTCR8, 0x0E000000U}, - {AXI_SPTCR9, 0x0E000000U}, - {AXI_SPTCR10, 0x0E000000U}, - {AXI_SPTCR11, 0x0E000000U}, - {AXI_SPTCR12, 0x0E000000U}, - {AXI_SPTCR13, 0x0E000000U}, - {AXI_SPTCR14, 0x0E000000U}, - {AXI_SPTCR15, 0x0E000000U} -}; - -static void lifec_security_setting(void) -{ - uint32_t i; - - for (i = 0; i < ARRAY_SIZE(lifec); i++) - mmio_write_32(lifec[i].reg, lifec[i].val); -} - -/* SRAM/DRAM protection setting */ -static void axi_security_setting(void) -{ - uint32_t i; - - for (i = 0; i < ARRAY_SIZE(axi); i++) - mmio_write_32(axi[i].reg, axi[i].val); -} - -void bl2_secure_setting(void) -{ - lifec_security_setting(); - axi_security_setting(); - rcar_micro_delay(10U); -} diff --git a/plat/renesas/rcar/bl31_plat_setup.c b/plat/renesas/rcar/bl31_plat_setup.c deleted file mode 100644 index 93798acfb..000000000 --- a/plat/renesas/rcar/bl31_plat_setup.c +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. - * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pwrc.h" -#include "rcar_def.h" -#include "rcar_private.h" -#include "rcar_version.h" - -static const uint64_t BL31_RO_BASE = BL_CODE_BASE; -static const uint64_t BL31_RO_LIMIT = BL_CODE_END; - -#if USE_COHERENT_MEM -static const uint64_t BL31_COHERENT_RAM_BASE = BL_COHERENT_RAM_BASE; -static const uint64_t BL31_COHERENT_RAM_LIMIT = BL_COHERENT_RAM_END; -#endif /* USE_COHERENT_MEM */ - -extern void plat_rcar_gic_driver_init(void); -extern void plat_rcar_gic_init(void); - -u_register_t rcar_boot_mpidr; - -static int cci_map[] = { - CCI500_CLUSTER0_SL_IFACE_IX_FOR_M3, - CCI500_CLUSTER1_SL_IFACE_IX_FOR_M3 -}; - -void plat_cci_init(void) -{ - uint32_t prd; - - prd = mmio_read_32(RCAR_PRR) & (PRR_PRODUCT_MASK | PRR_CUT_MASK); - - if (PRR_PRODUCT_H3_CUT10 == prd || PRR_PRODUCT_H3_CUT11 == prd) { - cci_map[0U] = CCI500_CLUSTER0_SL_IFACE_IX; - cci_map[1U] = CCI500_CLUSTER1_SL_IFACE_IX; - } - - cci_init(RCAR_CCI_BASE, cci_map, ARRAY_SIZE(cci_map)); -} - -void plat_cci_enable(void) -{ - cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr())); -} - -void plat_cci_disable(void) -{ - cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr())); -} - -struct entry_point_info *bl31_plat_get_next_image_ep_info(uint32_t type) -{ - bl2_to_bl31_params_mem_t *from_bl2 = (bl2_to_bl31_params_mem_t *) - PARAMS_BASE; - entry_point_info_t *next_image_info; - - next_image_info = (type == NON_SECURE) ? - &from_bl2->bl33_ep_info : &from_bl2->bl32_ep_info; - - return next_image_info->pc ? next_image_info : NULL; -} - -void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, - u_register_t arg2, u_register_t arg3) -{ - rcar_console_runtime_init(); - - NOTICE("BL3-1 : Rev.%s\n", version_of_renesas); - -#if RCAR_LSI != RCAR_D3 - if (rcar_pwrc_get_cluster() == RCAR_CLUSTER_A53A57) { - plat_cci_init(); - plat_cci_enable(); - } -#endif /* RCAR_LSI != RCAR_D3 */ -} - -void bl31_plat_arch_setup(void) -{ - rcar_configure_mmu_el3(BL31_BASE, - BL31_LIMIT - BL31_BASE, - BL31_RO_BASE, BL31_RO_LIMIT -#if USE_COHERENT_MEM - , BL31_COHERENT_RAM_BASE, BL31_COHERENT_RAM_LIMIT -#endif /* USE_COHERENT_MEM */ - ); - rcar_pwrc_code_copy_to_system_ram(); -} - -void bl31_platform_setup(void) -{ - plat_rcar_gic_driver_init(); - plat_rcar_gic_init(); - - /* enable the system level generic timer */ - mmio_write_32(RCAR_CNTC_BASE + CNTCR_OFF, CNTCR_FCREQ(U(0)) | CNTCR_EN); - - rcar_pwrc_setup(); -#if 0 - /* - * TODO: there is a broad number of rcar-gen3 SoC configurations; to - * support all of them, Renesas use the pwrc driver to discover what - * cores are on/off before announcing the topology. - * This code hasnt been ported yet - */ - - rcar_setup_topology(); -#endif - - /* - * mask should match the kernel's MPIDR_HWID_BITMASK so the core can be - * identified during cpuhotplug (check the kernel's psci migrate set of - * functions - */ - rcar_boot_mpidr = read_mpidr_el1() & 0x0000ffffU; -} diff --git a/plat/renesas/rcar/plat_image_load.c b/plat/renesas/rcar/plat_image_load.c deleted file mode 100644 index 9d814a6e5..000000000 --- a/plat/renesas/rcar/plat_image_load.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include - -extern void bl2_plat_flush_bl31_params(void); - -/******************************************************************************* - * This function flushes the data structures so that they are visible - * in memory for the next BL image. - ******************************************************************************/ -void plat_flush_next_bl_params(void) -{ -#if IMAGE_BL2 - bl2_plat_flush_bl31_params(); -#endif -} - -/******************************************************************************* - * This function returns the list of loadable images. - ******************************************************************************/ -bl_load_info_t *plat_get_bl_image_load_info(void) -{ - return get_bl_load_info_from_mem_params_desc(); -} - -/******************************************************************************* - * This function returns the list of executable images. - ******************************************************************************/ -bl_params_t *plat_get_next_bl_params(void) -{ - return get_next_bl_params_from_mem_params_desc(); -} diff --git a/plat/renesas/rcar/plat_pm.c b/plat/renesas/rcar/plat_pm.c deleted file mode 100644 index 7ec78cce3..000000000 --- a/plat/renesas/rcar/plat_pm.c +++ /dev/null @@ -1,308 +0,0 @@ -/* - * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "iic_dvfs.h" -#include "platform_def.h" -#include "pwrc.h" -#include "rcar_def.h" -#include "rcar_private.h" -#include "ulcb_cpld.h" - -#define DVFS_SET_VID_0V (0x00) -#define P_ALL_OFF (0x80) -#define KEEPON_DDR1C (0x08) -#define KEEPON_DDR0C (0x04) -#define KEEPON_DDR1 (0x02) -#define KEEPON_DDR0 (0x01) - -#define SYSTEM_PWR_STATE(s) ((s)->pwr_domain_state[PLAT_MAX_PWR_LVL]) -#define CLUSTER_PWR_STATE(s) ((s)->pwr_domain_state[MPIDR_AFFLVL1]) -#define CORE_PWR_STATE(s) ((s)->pwr_domain_state[MPIDR_AFFLVL0]) - -extern void rcar_pwrc_restore_generic_timer(uint64_t *stack); -extern void plat_rcar_gic_driver_init(void); -extern void plat_rcar_gic_init(void); -extern u_register_t rcar_boot_mpidr; - -static uintptr_t rcar_sec_entrypoint; - -static void rcar_program_mailbox(uint64_t mpidr, uint64_t address) -{ - mailbox_t *rcar_mboxes = (mailbox_t *) MBOX_BASE; - uint64_t linear_id = plat_core_pos_by_mpidr(mpidr); - unsigned long range; - - rcar_mboxes[linear_id].value = address; - range = (unsigned long)&rcar_mboxes[linear_id]; - - flush_dcache_range(range, sizeof(range)); -} - -static void rcar_cpu_standby(plat_local_state_t cpu_state) -{ - u_register_t scr_el3 = read_scr_el3(); - - write_scr_el3(scr_el3 | SCR_IRQ_BIT); - dsb(); - wfi(); - write_scr_el3(scr_el3); -} - -static int rcar_pwr_domain_on(u_register_t mpidr) -{ - rcar_program_mailbox(mpidr, rcar_sec_entrypoint); - rcar_pwrc_cpuon(mpidr); - - return PSCI_E_SUCCESS; -} - -static void rcar_pwr_domain_on_finish(const psci_power_state_t *target_state) -{ - uint32_t cluster_type = rcar_pwrc_get_cluster(); - unsigned long mpidr = read_mpidr_el1(); - - if (CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) - if (cluster_type == RCAR_CLUSTER_A53A57) - plat_cci_enable(); - - rcar_pwrc_disable_interrupt_wakeup(mpidr); - rcar_program_mailbox(mpidr, 0); - - gicv2_cpuif_enable(); - gicv2_pcpu_distif_init(); -} - -static void rcar_pwr_domain_off(const psci_power_state_t *target_state) -{ -#if RCAR_LSI != RCAR_D3 - uint32_t cluster_type = rcar_pwrc_get_cluster(); -#endif - unsigned long mpidr = read_mpidr_el1(); - - gicv2_cpuif_disable(); - rcar_pwrc_cpuoff(mpidr); - -#if RCAR_LSI != RCAR_D3 - if (CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) { - if (cluster_type == RCAR_CLUSTER_A53A57) - plat_cci_disable(); - - rcar_pwrc_clusteroff(mpidr); - } -#endif -} - -static void rcar_pwr_domain_suspend(const psci_power_state_t *target_state) -{ - uint32_t cluster_type = rcar_pwrc_get_cluster(); - unsigned long mpidr = read_mpidr_el1(); - - if (CORE_PWR_STATE(target_state) != PLAT_MAX_OFF_STATE) - return; - - rcar_program_mailbox(mpidr, rcar_sec_entrypoint); - rcar_pwrc_enable_interrupt_wakeup(mpidr); - gicv2_cpuif_disable(); - rcar_pwrc_cpuoff(mpidr); - - if (CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) { - if (cluster_type == RCAR_CLUSTER_A53A57) - plat_cci_disable(); - - 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 - *target_state) -{ - uint32_t cluster_type = rcar_pwrc_get_cluster(); - - if (SYSTEM_PWR_STATE(target_state) != PLAT_MAX_OFF_STATE) - goto finish; - - plat_rcar_gic_driver_init(); - plat_rcar_gic_init(); - - if (cluster_type == RCAR_CLUSTER_A53A57) - plat_cci_init(); - - rcar_pwrc_restore_timer_state(); - rcar_pwrc_setup(); - rcar_pwrc_code_copy_to_system_ram(); - -#if RCAR_SYSTEM_SUSPEND - rcar_pwrc_init_suspend_to_ram(); -#endif -finish: - rcar_pwr_domain_on_finish(target_state); -} - -static void __dead2 rcar_system_off(void) -{ -#if PMIC_ROHM_BD9571 -#if PMIC_LEVEL_MODE - if (rcar_iic_dvfs_send(PMIC, DVFS_SET_VID, DVFS_SET_VID_0V)) - ERROR("BL3-1:Failed the SYSTEM-OFF.\n"); -#else - if (rcar_iic_dvfs_send(PMIC, BKUP_MODE_CNT, P_ALL_OFF)) - ERROR("BL3-1:Failed the SYSTEM-RESET.\n"); -#endif -#else - uint64_t cpu = read_mpidr_el1() & 0x0000ffff; - int32_t rtn_on; - - rtn_on = rcar_pwrc_cpu_on_check(cpu); - - if (cpu == rcar_boot_mpidr) - panic(); - - if (rtn_on) - panic(); - - rcar_pwrc_cpuoff(cpu); - rcar_pwrc_clusteroff(cpu); - -#endif /* PMIC_ROHM_BD9571 */ - wfi(); - ERROR("RCAR System Off: operation not handled.\n"); - panic(); -} - -static void __dead2 rcar_system_reset(void) -{ -#if PMIC_ROHM_BD9571 -#if PMIC_LEVEL_MODE -#if RCAR_SYSTEM_RESET_KEEPON_DDR - uint8_t mode; - int32_t error; - - error = rcar_iic_dvfs_send(PMIC, REG_KEEP10, KEEP10_MAGIC); - if (error) { - ERROR("Failed send KEEP10 magic ret=%d\n", error); - goto done; - } - - error = rcar_iic_dvfs_receive(PMIC, BKUP_MODE_CNT, &mode); - if (error) { - ERROR("Failed receive BKUP_Mode_Cnt ret=%d\n", error); - goto done; - } - - mode |= KEEPON_DDR1C | KEEPON_DDR0C | KEEPON_DDR1 | KEEPON_DDR0; - error = rcar_iic_dvfs_send(PMIC, BKUP_MODE_CNT, mode); - if (error) { - ERROR("Failed send KEEPON_DDRx ret=%d\n", error); - goto done; - } - - rcar_pwrc_set_suspend_to_ram(); -done: -#else - if (rcar_iic_dvfs_send(PMIC, BKUP_MODE_CNT, P_ALL_OFF)) - ERROR("BL3-1:Failed the SYSTEM-RESET.\n"); -#endif -#else -#if (RCAR_GEN3_ULCB == 1) - rcar_cpld_reset_cpu(); -#endif -#endif -#else - rcar_pwrc_system_reset(); -#endif - wfi(); - - ERROR("RCAR System Reset: operation not handled.\n"); - panic(); -} - -static int rcar_validate_power_state(unsigned int power_state, - psci_power_state_t *req_state) -{ - unsigned int pwr_lvl = psci_get_pstate_pwrlvl(power_state); - unsigned int pstate = psci_get_pstate_type(power_state); - uint32_t i; - - if (pstate == PSTATE_TYPE_STANDBY) { - if (pwr_lvl != MPIDR_AFFLVL0) - return PSCI_E_INVALID_PARAMS; - - req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_RET_STATE; - } else { - for (i = MPIDR_AFFLVL0; i <= pwr_lvl; i++) - req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE; - } - - if (psci_get_pstate_id(power_state)) - return PSCI_E_INVALID_PARAMS; - - return PSCI_E_SUCCESS; -} - -#if RCAR_SYSTEM_SUSPEND -static void rcar_get_sys_suspend_power_state(psci_power_state_t *req_state) -{ - unsigned long mpidr = read_mpidr_el1() & 0x0000ffffU; - int i; - - if (mpidr != rcar_boot_mpidr) - goto deny; - - for (i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++) - req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE; - - return; -deny: - /* deny system suspend entry */ - req_state->pwr_domain_state[PLAT_MAX_PWR_LVL] = PSCI_LOCAL_STATE_RUN; - for (i = MPIDR_AFFLVL0; i < PLAT_MAX_PWR_LVL; i++) - req_state->pwr_domain_state[i] = PLAT_MAX_RET_STATE; -} -#endif - -static const plat_psci_ops_t rcar_plat_psci_ops = { - .cpu_standby = rcar_cpu_standby, - .pwr_domain_on = rcar_pwr_domain_on, - .pwr_domain_off = rcar_pwr_domain_off, - .pwr_domain_suspend = rcar_pwr_domain_suspend, - .pwr_domain_on_finish = rcar_pwr_domain_on_finish, - .pwr_domain_suspend_finish = rcar_pwr_domain_suspend_finish, - .system_off = rcar_system_off, - .system_reset = rcar_system_reset, - .validate_power_state = rcar_validate_power_state, -#if RCAR_SYSTEM_SUSPEND - .get_sys_suspend_power_state = rcar_get_sys_suspend_power_state, -#endif -}; - -int plat_setup_psci_ops(uintptr_t sec_entrypoint, const plat_psci_ops_t **psci_ops) -{ - *psci_ops = &rcar_plat_psci_ops; - rcar_sec_entrypoint = sec_entrypoint; - -#if RCAR_SYSTEM_SUSPEND - rcar_pwrc_init_suspend_to_ram(); -#endif - return 0; -} - diff --git a/plat/renesas/rcar/plat_storage.c b/plat/renesas/rcar/plat_storage.c deleted file mode 100644 index 652456103..000000000 --- a/plat/renesas/rcar/plat_storage.c +++ /dev/null @@ -1,417 +0,0 @@ -/* - * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include -#include -#include -#include - -#include "io_common.h" -#include "io_memdrv.h" -#include "io_emmcdrv.h" -#include "io_private.h" -#include "io_rcar.h" -#include - -static uintptr_t emmcdrv_dev_handle; -static uintptr_t memdrv_dev_handle; -static uintptr_t rcar_dev_handle; - -static uintptr_t boot_io_drv_id; - -static const io_block_spec_t rcar_block_spec = { - .offset = FLASH0_BASE, - .length = FLASH0_SIZE -}; - -static const io_block_spec_t bl2_file_spec = { - .offset = BL2_IMAGE_ID, -}; - -static const io_block_spec_t bl31_file_spec = { - .offset = BL31_IMAGE_ID, -}; - -static const io_block_spec_t bl32_file_spec = { - .offset = BL32_IMAGE_ID, -}; - -static const io_block_spec_t bl33_file_spec = { - .offset = BL33_IMAGE_ID, -}; - -static const io_block_spec_t bl332_file_spec = { - .offset = BL332_IMAGE_ID, -}; - -static const io_block_spec_t bl333_file_spec = { - .offset = BL333_IMAGE_ID, -}; - -static const io_block_spec_t bl334_file_spec = { - .offset = BL334_IMAGE_ID, -}; - -static const io_block_spec_t bl335_file_spec = { - .offset = BL335_IMAGE_ID, -}; - -static const io_block_spec_t bl336_file_spec = { - .offset = BL336_IMAGE_ID, -}; - -static const io_block_spec_t bl337_file_spec = { - .offset = BL337_IMAGE_ID, -}; - -static const io_block_spec_t bl338_file_spec = { - .offset = BL338_IMAGE_ID, -}; - -#if TRUSTED_BOARD_BOOT -static const io_block_spec_t trusted_key_cert_file_spec = { - .offset = TRUSTED_KEY_CERT_ID, -}; - -static const io_block_spec_t bl31_key_cert_file_spec = { - .offset = SOC_FW_KEY_CERT_ID, -}; - -static const io_block_spec_t bl32_key_cert_file_spec = { - .offset = TRUSTED_OS_FW_KEY_CERT_ID, -}; - -static const io_block_spec_t bl33_key_cert_file_spec = { - .offset = NON_TRUSTED_FW_KEY_CERT_ID, -}; - -static const io_block_spec_t bl332_key_cert_file_spec = { - .offset = BL332_KEY_CERT_ID, -}; - -static const io_block_spec_t bl333_key_cert_file_spec = { - .offset = BL333_KEY_CERT_ID, -}; - -static const io_block_spec_t bl334_key_cert_file_spec = { - .offset = BL334_KEY_CERT_ID, -}; - -static const io_block_spec_t bl335_key_cert_file_spec = { - .offset = BL335_KEY_CERT_ID, -}; - -static const io_block_spec_t bl336_key_cert_file_spec = { - .offset = BL336_KEY_CERT_ID, -}; - -static const io_block_spec_t bl337_key_cert_file_spec = { - .offset = BL337_KEY_CERT_ID, -}; - -static const io_block_spec_t bl338_key_cert_file_spec = { - .offset = BL338_KEY_CERT_ID, -}; - -static const io_block_spec_t bl31_cert_file_spec = { - .offset = SOC_FW_CONTENT_CERT_ID, -}; - -static const io_block_spec_t bl32_cert_file_spec = { - .offset = TRUSTED_OS_FW_CONTENT_CERT_ID, -}; - -static const io_block_spec_t bl33_cert_file_spec = { - .offset = NON_TRUSTED_FW_CONTENT_CERT_ID, -}; - -static const io_block_spec_t bl332_cert_file_spec = { - .offset = BL332_CERT_ID, -}; - -static const io_block_spec_t bl333_cert_file_spec = { - .offset = BL333_CERT_ID, -}; - -static const io_block_spec_t bl334_cert_file_spec = { - .offset = BL334_CERT_ID, -}; - -static const io_block_spec_t bl335_cert_file_spec = { - .offset = BL335_CERT_ID, -}; - -static const io_block_spec_t bl336_cert_file_spec = { - .offset = BL336_CERT_ID, -}; - -static const io_block_spec_t bl337_cert_file_spec = { - .offset = BL337_CERT_ID, -}; - -static const io_block_spec_t bl338_cert_file_spec = { - .offset = BL338_CERT_ID, -}; -#endif - -static int32_t open_emmcdrv(const uintptr_t spec); -static int32_t open_memmap(const uintptr_t spec); -static int32_t open_rcar(const uintptr_t spec); - -struct plat_io_policy { - uintptr_t *dev_handle; - uintptr_t image_spec; - int32_t (*check)(const uintptr_t spec); -}; - -static const struct plat_io_policy policies[] = { - [FIP_IMAGE_ID] = { - &memdrv_dev_handle, - (uintptr_t) &rcar_block_spec, - &open_memmap}, - [BL2_IMAGE_ID] = { - &rcar_dev_handle, - (uintptr_t) &bl2_file_spec, - &open_rcar}, - [BL31_IMAGE_ID] = { - &rcar_dev_handle, - (uintptr_t) &bl31_file_spec, - &open_rcar}, - [BL32_IMAGE_ID] = { - &rcar_dev_handle, - (uintptr_t) &bl32_file_spec, - &open_rcar}, - [BL33_IMAGE_ID] = { - &rcar_dev_handle, - (uintptr_t) &bl33_file_spec, - &open_rcar}, - [BL332_IMAGE_ID] = { - &rcar_dev_handle, - (uintptr_t) &bl332_file_spec, - &open_rcar}, - [BL333_IMAGE_ID] = { - &rcar_dev_handle, - (uintptr_t) &bl333_file_spec, - &open_rcar}, - [BL334_IMAGE_ID] = { - &rcar_dev_handle, - (uintptr_t) &bl334_file_spec, - &open_rcar}, - [BL335_IMAGE_ID] = { - &rcar_dev_handle, - (uintptr_t) &bl335_file_spec, - &open_rcar}, - [BL336_IMAGE_ID] = { - &rcar_dev_handle, - (uintptr_t) &bl336_file_spec, - &open_rcar}, - [BL337_IMAGE_ID] = { - &rcar_dev_handle, - (uintptr_t) &bl337_file_spec, - &open_rcar}, - [BL338_IMAGE_ID] = { - &rcar_dev_handle, - (uintptr_t) &bl338_file_spec, - &open_rcar}, -#if TRUSTED_BOARD_BOOT - [TRUSTED_KEY_CERT_ID] = { - &rcar_dev_handle, - (uintptr_t) &trusted_key_cert_file_spec, - &open_rcar}, - [SOC_FW_KEY_CERT_ID] = { - &rcar_dev_handle, - (uintptr_t) &bl31_key_cert_file_spec, - &open_rcar}, - [TRUSTED_OS_FW_KEY_CERT_ID] = { - &rcar_dev_handle, - (uintptr_t) &bl32_key_cert_file_spec, - &open_rcar}, - [NON_TRUSTED_FW_KEY_CERT_ID] = { - &rcar_dev_handle, - (uintptr_t) &bl33_key_cert_file_spec, - &open_rcar}, - [BL332_KEY_CERT_ID] = { - &rcar_dev_handle, - (uintptr_t) &bl332_key_cert_file_spec, - &open_rcar}, - [BL333_KEY_CERT_ID] = { - &rcar_dev_handle, - (uintptr_t) &bl333_key_cert_file_spec, - &open_rcar}, - [BL334_KEY_CERT_ID] = { - &rcar_dev_handle, - (uintptr_t) &bl334_key_cert_file_spec, - &open_rcar}, - [BL335_KEY_CERT_ID] = { - &rcar_dev_handle, - (uintptr_t) &bl335_key_cert_file_spec, - &open_rcar}, - [BL336_KEY_CERT_ID] = { - &rcar_dev_handle, - (uintptr_t) &bl336_key_cert_file_spec, - &open_rcar}, - [BL337_KEY_CERT_ID] = { - &rcar_dev_handle, - (uintptr_t) &bl337_key_cert_file_spec, - &open_rcar}, - [BL338_KEY_CERT_ID] = { - &rcar_dev_handle, - (uintptr_t) &bl338_key_cert_file_spec, - &open_rcar}, - [SOC_FW_CONTENT_CERT_ID] = { - &rcar_dev_handle, - (uintptr_t) &bl31_cert_file_spec, - &open_rcar}, - [TRUSTED_OS_FW_CONTENT_CERT_ID] = { - &rcar_dev_handle, - (uintptr_t) &bl32_cert_file_spec, - &open_rcar}, - [NON_TRUSTED_FW_CONTENT_CERT_ID] = { - &rcar_dev_handle, - (uintptr_t) &bl33_cert_file_spec, - &open_rcar}, - [BL332_CERT_ID] = { - &rcar_dev_handle, - (uintptr_t) &bl332_cert_file_spec, - &open_rcar}, - [BL333_CERT_ID] = { - &rcar_dev_handle, - (uintptr_t) &bl333_cert_file_spec, - &open_rcar}, - [BL334_CERT_ID] = { - &rcar_dev_handle, - (uintptr_t) &bl334_cert_file_spec, - &open_rcar}, - [BL335_CERT_ID] = { - &rcar_dev_handle, - (uintptr_t) &bl335_cert_file_spec, - &open_rcar}, - [BL336_CERT_ID] = { - &rcar_dev_handle, - (uintptr_t) &bl336_cert_file_spec, - &open_rcar}, - [BL337_CERT_ID] = { - &rcar_dev_handle, - (uintptr_t) &bl337_cert_file_spec, - &open_rcar}, - [BL338_CERT_ID] = { - &rcar_dev_handle, - (uintptr_t) &bl338_cert_file_spec, - &open_rcar}, { -#else - { -#endif - 0, 0, 0} -}; - -static io_drv_spec_t io_drv_spec_memdrv = { - FLASH0_BASE, - FLASH0_SIZE, - 0, -}; - -static io_drv_spec_t io_drv_spec_emmcdrv = { - 0, - 0, - 0, -}; - -static struct plat_io_policy drv_policies[] __attribute__ ((section(".data"))) = { - /* FLASH_DEV_ID */ - { &memdrv_dev_handle, (uintptr_t) &io_drv_spec_memdrv, &open_memmap, }, - /* EMMC_DEV_ID */ - { &emmcdrv_dev_handle, (uintptr_t) &io_drv_spec_emmcdrv, &open_emmcdrv, } -}; - -static int32_t open_rcar(const uintptr_t spec) -{ - return io_dev_init(rcar_dev_handle, boot_io_drv_id); -} - -static int32_t open_memmap(const uintptr_t spec) -{ - uintptr_t handle; - int32_t result; - - result = io_dev_init(memdrv_dev_handle, 0); - if (result != IO_SUCCESS) - return result; - - result = io_open(memdrv_dev_handle, spec, &handle); - if (result == IO_SUCCESS) - io_close(handle); - - return result; -} - -static int32_t open_emmcdrv(const uintptr_t spec) -{ - return io_dev_init(emmcdrv_dev_handle, 0); -} - -void rcar_io_setup(void) -{ - const io_dev_connector_t *memmap; - const io_dev_connector_t *rcar; - - boot_io_drv_id = FLASH_DEV_ID; - - rcar_register_io_dev(&rcar); - rcar_register_io_dev_memdrv(&memmap); - io_dev_open(rcar, 0, &rcar_dev_handle); - io_dev_open(memmap, 0, &memdrv_dev_handle); -} - -void rcar_io_emmc_setup(void) -{ - const io_dev_connector_t *rcar; - const io_dev_connector_t *emmc; - - boot_io_drv_id = EMMC_DEV_ID; - - rcar_register_io_dev(&rcar); - rcar_register_io_dev_emmcdrv(&emmc); - io_dev_open(rcar, 0, &rcar_dev_handle); - io_dev_open(emmc, 0, &emmcdrv_dev_handle); -} - -int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, - uintptr_t *image_spec) -{ - const struct plat_io_policy *policy; - int result; - - policy = &policies[image_id]; - - result = policy->check(policy->image_spec); - if (result != IO_SUCCESS) - return result; - - *image_spec = policy->image_spec; - *dev_handle = *(policy->dev_handle); - - return IO_SUCCESS; -} - -int32_t plat_get_drv_source(uint32_t io_drv_id, uintptr_t *dev_handle, - uintptr_t *image_spec) -{ - const struct plat_io_policy *policy; - int32_t result; - - policy = &drv_policies[io_drv_id]; - - result = policy->check(policy->image_spec); - if (result != IO_SUCCESS) - return result; - - *image_spec = policy->image_spec; - *dev_handle = *(policy->dev_handle); - - return IO_SUCCESS; -} diff --git a/plat/renesas/rcar/plat_topology.c b/plat/renesas/rcar/plat_topology.c deleted file mode 100644 index 0d5880d7a..000000000 --- a/plat/renesas/rcar/plat_topology.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2018, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include -#include - -static const unsigned char rcar_power_domain_tree_desc[] = { - 1, - PLATFORM_CLUSTER_COUNT, - PLATFORM_CLUSTER0_CORE_COUNT, - PLATFORM_CLUSTER1_CORE_COUNT -}; - -const unsigned char *plat_get_power_domain_tree_desc(void) -{ - return rcar_power_domain_tree_desc; -} - -int plat_core_pos_by_mpidr(u_register_t mpidr) -{ - unsigned int cluster_id, cpu_id; - - mpidr &= MPIDR_AFFINITY_MASK; - - if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) - return -1; - - cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK; - cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK; - - if (cluster_id >= PLATFORM_CLUSTER_COUNT) - return -1; - - if (cluster_id == 0 && cpu_id >= PLATFORM_CLUSTER0_CORE_COUNT) - return -1; - - if (cluster_id == 1 && cpu_id >= PLATFORM_CLUSTER1_CORE_COUNT) - return -1; - - return (cpu_id + cluster_id * PLATFORM_CLUSTER0_CORE_COUNT); -} - diff --git a/plat/renesas/rcar/platform.mk b/plat/renesas/rcar/platform.mk index ee393f2f4..5e4978c0a 100644 --- a/plat/renesas/rcar/platform.mk +++ b/plat/renesas/rcar/platform.mk @@ -312,19 +312,9 @@ PLAT_INCLUDES += -Idrivers/renesas/rcar/ddr \ -Idrivers/renesas/common/pwrc \ -Idrivers/renesas/common/io -BL2_SOURCES += plat/renesas/rcar/bl2_interrupt_error.c \ - plat/renesas/rcar/bl2_secure_setting.c \ - plat/renesas/rcar/bl2_plat_setup.c \ - plat/renesas/rcar/plat_storage.c \ - plat/renesas/rcar/bl2_plat_mem_params_desc.c \ - plat/renesas/rcar/plat_image_load.c \ - plat/renesas/rcar/bl2_cpg_init.c \ +BL2_SOURCES += plat/renesas/rcar/bl2_plat_setup.c \ drivers/renesas/rcar/board/board.c -BL31_SOURCES += plat/renesas/rcar/plat_topology.c \ - plat/renesas/rcar/bl31_plat_setup.c \ - plat/renesas/rcar/plat_pm.c - ifeq (${RCAR_GEN3_ULCB},1) BL31_SOURCES += drivers/renesas/rcar/cpld/ulcb_cpld.c endif -- cgit v1.2.3 From ed4fde3125563bb74d32c8a6284b255b764cc56b Mon Sep 17 00:00:00 2001 From: Biju Das Date: Mon, 9 Nov 2020 09:36:46 +0000 Subject: renesas: rzg: Add support for DRAM initialization Add support for initializing DRAM on RZ/G2M SoC. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: I99f1a6971a061a44687af498d55306a93e4fc8f7 --- drivers/renesas/rzg/ddr/boot_init_dram.h | 18 + drivers/renesas/rzg/ddr/ddr.mk | 7 + drivers/renesas/rzg/ddr/ddr_b/boot_init_dram.c | 3700 ++++++++++++ .../renesas/rzg/ddr/ddr_b/boot_init_dram_config.c | 277 + .../renesas/rzg/ddr/ddr_b/boot_init_dram_regdef.h | 99 + drivers/renesas/rzg/ddr/ddr_b/ddr_b.mk | 7 + drivers/renesas/rzg/ddr/ddr_b/ddr_regdef.h | 5891 ++++++++++++++++++++ drivers/renesas/rzg/ddr/ddr_b/init_dram_tbl_g2m.h | 472 ++ drivers/renesas/rzg/ddr/dram_sub_func.h | 14 + 9 files changed, 10485 insertions(+) create mode 100644 drivers/renesas/rzg/ddr/boot_init_dram.h create mode 100644 drivers/renesas/rzg/ddr/ddr.mk create mode 100644 drivers/renesas/rzg/ddr/ddr_b/boot_init_dram.c create mode 100644 drivers/renesas/rzg/ddr/ddr_b/boot_init_dram_config.c create mode 100644 drivers/renesas/rzg/ddr/ddr_b/boot_init_dram_regdef.h create mode 100644 drivers/renesas/rzg/ddr/ddr_b/ddr_b.mk create mode 100644 drivers/renesas/rzg/ddr/ddr_b/ddr_regdef.h create mode 100644 drivers/renesas/rzg/ddr/ddr_b/init_dram_tbl_g2m.h create mode 100644 drivers/renesas/rzg/ddr/dram_sub_func.h diff --git a/drivers/renesas/rzg/ddr/boot_init_dram.h b/drivers/renesas/rzg/ddr/boot_init_dram.h new file mode 100644 index 000000000..294582fa7 --- /dev/null +++ b/drivers/renesas/rzg/ddr/boot_init_dram.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef BOOT_INIT_DRAM_H +#define BOOT_INIT_DRAM_H + +extern int32_t rzg_dram_init(void); + +#define INITDRAM_OK 0 +#define INITDRAM_NG 0xffffffff +#define INITDRAM_ERR_I 0xffffffff +#define INITDRAM_ERR_O 0xfffffffe +#define INITDRAM_ERR_T 0xfffffff0 + +#endif /* BOOT_INIT_DRAM_H */ diff --git a/drivers/renesas/rzg/ddr/ddr.mk b/drivers/renesas/rzg/ddr/ddr.mk new file mode 100644 index 000000000..7558216e3 --- /dev/null +++ b/drivers/renesas/rzg/ddr/ddr.mk @@ -0,0 +1,7 @@ +# +# Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +include drivers/renesas/rzg/ddr/ddr_b/ddr_b.mk diff --git a/drivers/renesas/rzg/ddr/ddr_b/boot_init_dram.c b/drivers/renesas/rzg/ddr/ddr_b/boot_init_dram.c new file mode 100644 index 000000000..45259e3c5 --- /dev/null +++ b/drivers/renesas/rzg/ddr/ddr_b/boot_init_dram.c @@ -0,0 +1,3700 @@ +/* + * Copyright (c) 2021, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include + +#include "boot_init_dram.h" +#include "boot_init_dram_regdef.h" +#include "ddr_regdef.h" +#include "dram_sub_func.h" +#include "init_dram_tbl_g2m.h" +#include "micro_delay.h" +#include "rcar_def.h" + +/* load board configuration */ +#include "boot_init_dram_config.c" + +#define DDR_BACKUPMODE +#define FATAL_MSG(x) NOTICE(x) + +/* variables */ +#ifdef RCAR_DDR_FIXED_LSI_TYPE +#ifndef RCAR_AUTO +#define RCAR_AUTO 99U +#define RZ_G2M 100U + +#define RCAR_CUT_10 0U +#define RCAR_CUT_11 1U +#define RCAR_CUT_20 10U +#define RCAR_CUT_30 20U +#endif /* RCAR_AUTO */ +#ifndef RCAR_LSI +#define RCAR_LSI RCAR_AUTO +#endif + +#if (RCAR_LSI == RCAR_AUTO) +static uint32_t prr_product; +static uint32_t prr_cut; +#else /* RCAR_LSI == RCAR_AUTO */ +#if (RCAR_LSI == RZ_G2M) +static const uint32_t prr_product = PRR_PRODUCT_M3; +#endif /* RCAR_LSI == RZ_G2M */ + +#ifndef RCAR_LSI_CUT +static uint32_t prr_cut; +#else /* RCAR_LSI_CUT */ +#if (RCAR_LSI_CUT == RCAR_CUT_10) +static const uint32_t prr_cut = PRR_PRODUCT_10; +#elif(RCAR_LSI_CUT == RCAR_CUT_11) +static const uint32_t prr_cut = PRR_PRODUCT_11; +#elif(RCAR_LSI_CUT == RCAR_CUT_20) +static const uint32_t prr_cut = PRR_PRODUCT_20; +#elif(RCAR_LSI_CUT == RCAR_CUT_30) +static const uint32_t prr_cut = PRR_PRODUCT_30; +#endif /* RCAR_LSI_CUT == RCAR_CUT_10 */ +#endif /* RCAR_LSI_CUT */ +#endif /* RCAR_LSI == RCAR_AUTO */ +#else /* RCAR_DDR_FIXED_LSI_TYPE */ +static uint32_t prr_product; +static uint32_t prr_cut; +#endif /* RCAR_DDR_FIXED_LSI_TYPE */ + +static const uint32_t *p_ddr_regdef_tbl; +static uint32_t brd_clk; +static uint32_t brd_clkdiv; +static uint32_t brd_clkdiva; +static uint32_t ddr_mbps; +static uint32_t ddr_mbpsdiv; +static uint32_t ddr_tccd; +static uint32_t ddr_phycaslice; +static const struct _boardcnf *board_cnf; +static uint32_t ddr_phyvalid; +static uint32_t ddr_density[DRAM_CH_CNT][CS_CNT]; +static uint32_t ch_have_this_cs[CS_CNT] __aligned(64); +static uint32_t rdqdm_dly[DRAM_CH_CNT][CSAB_CNT][SLICE_CNT * 2U][9U]; +static uint32_t max_density; +static uint32_t ddr0800_mul; +static uint32_t ddr_mul; +static uint32_t DDR_PHY_SLICE_REGSET_OFS; +static uint32_t DDR_PHY_ADR_V_REGSET_OFS; +static uint32_t DDR_PHY_ADR_I_REGSET_OFS; +static uint32_t DDR_PHY_ADR_G_REGSET_OFS; +static uint32_t DDR_PI_REGSET_OFS; +static uint32_t DDR_PHY_SLICE_REGSET_SIZE; +static uint32_t DDR_PHY_ADR_V_REGSET_SIZE; +static uint32_t DDR_PHY_ADR_I_REGSET_SIZE; +static uint32_t DDR_PHY_ADR_G_REGSET_SIZE; +static uint32_t DDR_PI_REGSET_SIZE; +static uint32_t DDR_PHY_SLICE_REGSET_NUM; +static uint32_t DDR_PHY_ADR_V_REGSET_NUM; +static uint32_t DDR_PHY_ADR_I_REGSET_NUM; +static uint32_t DDR_PHY_ADR_G_REGSET_NUM; +static uint32_t DDR_PI_REGSET_NUM; +static uint32_t DDR_PHY_ADR_I_NUM; +#define DDR_PHY_REGSET_MAX 128 +#define DDR_PI_REGSET_MAX 320 +static uint32_t _cnf_DDR_PHY_SLICE_REGSET[DDR_PHY_REGSET_MAX]; +static uint32_t _cnf_DDR_PHY_ADR_V_REGSET[DDR_PHY_REGSET_MAX]; +static uint32_t _cnf_DDR_PHY_ADR_I_REGSET[DDR_PHY_REGSET_MAX]; +static uint32_t _cnf_DDR_PHY_ADR_G_REGSET[DDR_PHY_REGSET_MAX]; +static uint32_t _cnf_DDR_PI_REGSET[DDR_PI_REGSET_MAX]; +static uint32_t pll3_mode; +static uint32_t loop_max; +#ifdef DDR_BACKUPMODE +uint32_t ddr_backup = DRAM_BOOT_STATUS_COLD; +/* #define DDR_BACKUPMODE_HALF */ /* for Half channel(ch0,1 only) */ +#endif + +#ifdef DDR_QOS_INIT_SETTING /* only for non qos_init */ +#define OPERATING_FREQ (400U) /* Mhz */ +#define BASE_SUB_SLOT_NUM (0x6U) +#define SUB_SLOT_CYCLE (0x7EU) /* 126 */ +#define QOSWT_WTSET0_CYCLE \ + ((SUB_SLOT_CYCLE * BASE_SUB_SLOT_NUM * 1000U) / \ + OPERATING_FREQ) /* unit:ns */ + +uint32_t get_refperiod(void) +{ + return QOSWT_WTSET0_CYCLE; +} +#else /* DDR_QOS_INIT_SETTING */ +extern uint32_t get_refperiod(void); +#endif /* DDR_QOS_INIT_SETTING */ + +#define _reg_PHY_RX_CAL_X_NUM 11U +static const uint32_t _reg_PHY_RX_CAL_X[_reg_PHY_RX_CAL_X_NUM] = { + _reg_PHY_RX_CAL_DQ0, + _reg_PHY_RX_CAL_DQ1, + _reg_PHY_RX_CAL_DQ2, + _reg_PHY_RX_CAL_DQ3, + _reg_PHY_RX_CAL_DQ4, + _reg_PHY_RX_CAL_DQ5, + _reg_PHY_RX_CAL_DQ6, + _reg_PHY_RX_CAL_DQ7, + _reg_PHY_RX_CAL_DM, + _reg_PHY_RX_CAL_DQS, + _reg_PHY_RX_CAL_FDBK +}; + +#define _reg_PHY_CLK_WRX_SLAVE_DELAY_NUM 10U +static const uint32_t _reg_PHY_CLK_WRX_SLAVE_DELAY + [_reg_PHY_CLK_WRX_SLAVE_DELAY_NUM] = { + _reg_PHY_CLK_WRDQ0_SLAVE_DELAY, + _reg_PHY_CLK_WRDQ1_SLAVE_DELAY, + _reg_PHY_CLK_WRDQ2_SLAVE_DELAY, + _reg_PHY_CLK_WRDQ3_SLAVE_DELAY, + _reg_PHY_CLK_WRDQ4_SLAVE_DELAY, + _reg_PHY_CLK_WRDQ5_SLAVE_DELAY, + _reg_PHY_CLK_WRDQ6_SLAVE_DELAY, + _reg_PHY_CLK_WRDQ7_SLAVE_DELAY, + _reg_PHY_CLK_WRDM_SLAVE_DELAY, + _reg_PHY_CLK_WRDQS_SLAVE_DELAY +}; + +#define _reg_PHY_RDDQS_X_FALL_SLAVE_DELAY_NUM 9U +static const uint32_t _reg_PHY_RDDQS_X_FALL_SLAVE_DELAY + [_reg_PHY_RDDQS_X_FALL_SLAVE_DELAY_NUM] = { + _reg_PHY_RDDQS_DQ0_FALL_SLAVE_DELAY, + _reg_PHY_RDDQS_DQ1_FALL_SLAVE_DELAY, + _reg_PHY_RDDQS_DQ2_FALL_SLAVE_DELAY, + _reg_PHY_RDDQS_DQ3_FALL_SLAVE_DELAY, + _reg_PHY_RDDQS_DQ4_FALL_SLAVE_DELAY, + _reg_PHY_RDDQS_DQ5_FALL_SLAVE_DELAY, + _reg_PHY_RDDQS_DQ6_FALL_SLAVE_DELAY, + _reg_PHY_RDDQS_DQ7_FALL_SLAVE_DELAY, + _reg_PHY_RDDQS_DM_FALL_SLAVE_DELAY +}; + +#define _reg_PHY_RDDQS_X_RISE_SLAVE_DELAY_NUM 9U +static const uint32_t _reg_PHY_RDDQS_X_RISE_SLAVE_DELAY + [_reg_PHY_RDDQS_X_RISE_SLAVE_DELAY_NUM] = { + _reg_PHY_RDDQS_DQ0_RISE_SLAVE_DELAY, + _reg_PHY_RDDQS_DQ1_RISE_SLAVE_DELAY, + _reg_PHY_RDDQS_DQ2_RISE_SLAVE_DELAY, + _reg_PHY_RDDQS_DQ3_RISE_SLAVE_DELAY, + _reg_PHY_RDDQS_DQ4_RISE_SLAVE_DELAY, + _reg_PHY_RDDQS_DQ5_RISE_SLAVE_DELAY, + _reg_PHY_RDDQS_DQ6_RISE_SLAVE_DELAY, + _reg_PHY_RDDQS_DQ7_RISE_SLAVE_DELAY, + _reg_PHY_RDDQS_DM_RISE_SLAVE_DELAY +}; + +#define _reg_PHY_PAD_TERM_X_NUM 8U +static const uint32_t _reg_PHY_PAD_TERM_X[_reg_PHY_PAD_TERM_X_NUM] = { + _reg_PHY_PAD_FDBK_TERM, + _reg_PHY_PAD_DATA_TERM, + _reg_PHY_PAD_DQS_TERM, + _reg_PHY_PAD_ADDR_TERM, + _reg_PHY_PAD_CLK_TERM, + _reg_PHY_PAD_CKE_TERM, + _reg_PHY_PAD_RST_TERM, + _reg_PHY_PAD_CS_TERM +}; + +#define _reg_PHY_CLK_CACS_SLAVE_DELAY_X_NUM 10U +static const uint32_t _reg_PHY_CLK_CACS_SLAVE_DELAY_X + [_reg_PHY_CLK_CACS_SLAVE_DELAY_X_NUM] = { + _reg_PHY_ADR0_CLK_WR_SLAVE_DELAY, + _reg_PHY_ADR1_CLK_WR_SLAVE_DELAY, + _reg_PHY_ADR2_CLK_WR_SLAVE_DELAY, + _reg_PHY_ADR3_CLK_WR_SLAVE_DELAY, + _reg_PHY_ADR4_CLK_WR_SLAVE_DELAY, + _reg_PHY_ADR5_CLK_WR_SLAVE_DELAY, + + _reg_PHY_GRP_SLAVE_DELAY_0, + _reg_PHY_GRP_SLAVE_DELAY_1, + _reg_PHY_GRP_SLAVE_DELAY_2, + _reg_PHY_GRP_SLAVE_DELAY_3 +}; + +/* Prototypes */ +static inline uint32_t vch_nxt(uint32_t pos); +static void cpg_write_32(uint32_t a, uint32_t v); +static void pll3_control(uint32_t high); +static inline void dsb_sev(void); +static void wait_dbcmd(void); +static void send_dbcmd(uint32_t cmd); +static uint32_t reg_ddrphy_read(uint32_t phyno, uint32_t regadd); +static void reg_ddrphy_write(uint32_t phyno, uint32_t regadd, uint32_t regdata); +static void reg_ddrphy_write_a(uint32_t regadd, uint32_t regdata); +static inline uint32_t ddr_regdef(uint32_t _regdef); +static inline uint32_t ddr_regdef_adr(uint32_t _regdef); +static inline uint32_t ddr_regdef_lsb(uint32_t _regdef); +static void ddr_setval_s(uint32_t ch, uint32_t slice, uint32_t _regdef, + uint32_t val); +static uint32_t ddr_getval_s(uint32_t ch, uint32_t slice, uint32_t _regdef); +static void ddr_setval(uint32_t ch, uint32_t regdef, uint32_t val); +static void ddr_setval_ach_s(uint32_t slice, uint32_t regdef, uint32_t val); +static void ddr_setval_ach(uint32_t regdef, uint32_t val); +static void ddr_setval_ach_as(uint32_t regdef, uint32_t val); +static uint32_t ddr_getval(uint32_t ch, uint32_t regdef); +static uint32_t ddr_getval_ach(uint32_t regdef, uint32_t *p); +static uint32_t ddr_getval_ach_as(uint32_t regdef, uint32_t *p); +static void _tblcopy(uint32_t *to, const uint32_t *from, uint32_t size); +static void ddrtbl_setval(uint32_t *tbl, uint32_t _regdef, uint32_t val); +static uint32_t ddrtbl_getval(uint32_t *tbl, uint32_t _regdef); +static uint32_t ddrphy_regif_chk(void); +static inline void ddrphy_regif_idle(void); +static uint16_t _f_scale(uint32_t _ddr_mbps, uint32_t _ddr_mbpsdiv, uint32_t ps, + uint16_t cyc); +static void _f_scale_js2(uint32_t _ddr_mbps, uint32_t _ddr_mbpsdiv, + uint16_t *_js2); +static int16_t _f_scale_adj(int16_t ps); +static void ddrtbl_load(void); +static void ddr_config_sub(void); +static void ddr_config(void); +static void dbsc_regset(void); +static void dbsc_regset_post(void); +static uint32_t dfi_init_start(void); +static void change_lpddr4_en(uint32_t mode); +static uint32_t set_term_code(void); +static void ddr_register_set(void); +static inline uint32_t wait_freqchgreq(uint32_t assert); +static inline void set_freqchgack(uint32_t assert); +static inline void set_dfifrequency(uint32_t freq); +static uint32_t pll3_freq(uint32_t on); +static void update_dly(void); +static uint32_t pi_training_go(void); +static uint32_t init_ddr(void); +static uint32_t swlvl1(uint32_t ddr_csn, uint32_t reg_cs, uint32_t reg_kick); +static uint32_t wdqdm_man1(void); +static uint32_t wdqdm_man(void); +static uint32_t rdqdm_man1(void); +static uint32_t rdqdm_man(void); + +static int32_t _find_change(uint64_t val, uint32_t dir); +static uint32_t _rx_offset_cal_updn(uint32_t code); +static uint32_t rx_offset_cal(void); +static uint32_t rx_offset_cal_hw(void); +static void adjust_wpath_latency(void); + +struct ddrt_data { + int32_t init_temp; /* Initial Temperature (do) */ + uint32_t init_cal[4U]; /* Initial io-code (4 is for G2H) */ + uint32_t tcomp_cal[4U]; /* Temp. compensated io-code (4 is for G2H) */ +}; + +static struct ddrt_data tcal; + +static void pvtcode_update(void); +static void pvtcode_update2(void); +static void ddr_padcal_tcompensate_getinit(uint32_t override); + +#ifndef DDR_FAST_INIT +static uint32_t rdqdm_le[DRAM_CH_CNT][CS_CNT][SLICE_CNT * 2U][9U]; +static uint32_t rdqdm_te[DRAM_CH_CNT][CS_CNT][SLICE_CNT * 2U][9U]; +static uint32_t rdqdm_nw[DRAM_CH_CNT][CS_CNT][SLICE_CNT * 2U][9U]; +static uint32_t rdqdm_win[DRAM_CH_CNT][CS_CNT][SLICE_CNT]; +static uint32_t rdqdm_st[DRAM_CH_CNT][CS_CNT][SLICE_CNT * 2U]; +static void rdqdm_clr1(uint32_t ch, uint32_t ddr_csn); +static uint32_t rdqdm_ana1(uint32_t ch, uint32_t ddr_csn); + +static uint32_t wdqdm_le[DRAM_CH_CNT][CS_CNT][SLICE_CNT][9U]; +static uint32_t wdqdm_te[DRAM_CH_CNT][CS_CNT][SLICE_CNT][9U]; +static uint32_t wdqdm_dly[DRAM_CH_CNT][CS_CNT][SLICE_CNT][9U]; +static uint32_t wdqdm_st[DRAM_CH_CNT][CS_CNT][SLICE_CNT]; +static uint32_t wdqdm_win[DRAM_CH_CNT][CS_CNT][SLICE_CNT]; +static void wdqdm_clr1(uint32_t ch, uint32_t ddr_csn); +static uint32_t wdqdm_ana1(uint32_t ch, uint32_t ddr_csn); +#endif/* DDR_FAST_INIT */ + +/* macro for channel selection loop */ +static inline uint32_t vch_nxt(uint32_t pos) +{ + uint32_t posn; + + for (posn = pos; posn < DRAM_CH_CNT; posn++) { + if ((ddr_phyvalid & (1U << posn)) != 0U) { + break; + } + } + return posn; +} + +#define foreach_vch(ch) \ +for (ch = vch_nxt(0U); ch < DRAM_CH_CNT; ch = vch_nxt(ch + 1U)) + +#define foreach_ech(ch) \ +for (ch = 0U; ch < DRAM_CH_CNT; ch++) + +/* Printing functions */ +#define MSG_LF(...) + +/* clock settings, reset control */ +static void cpg_write_32(uint32_t a, uint32_t v) +{ + mmio_write_32(CPG_CPGWPR, ~v); + mmio_write_32(a, v); +} + +static void wait_for_pll3_status_bit_turned_on(void) +{ + uint32_t data_l; + + do { + data_l = mmio_read_32(CPG_PLLECR); + } while ((data_l & CPG_PLLECR_PLL3ST_BIT) == 0); + dsb_sev(); +} + +static void pll3_control(uint32_t high) +{ + uint32_t data_l, data_div, data_mul, tmp_div; + + if (high != 0U) { + tmp_div = 3999U * brd_clkdiv * (brd_clkdiva + 1U) / + (brd_clk * ddr_mul) / 2U; + data_mul = ((ddr_mul * tmp_div) - 1U) << 24U; + pll3_mode = 1U; + loop_max = 2U; + } else { + tmp_div = 3999U * brd_clkdiv * (brd_clkdiva + 1U) / + (brd_clk * ddr0800_mul) / 2U; + data_mul = ((ddr0800_mul * tmp_div) - 1U) << 24U; + pll3_mode = 0U; + loop_max = 8U; + } + + switch (tmp_div) { + case 1: + data_div = 0U; + break; + case 2: + case 3: + case 4: + data_div = tmp_div; + break; + default: + data_div = 6U; + data_mul = (data_mul * tmp_div) / 3U; + break; + } + data_mul = data_mul | (brd_clkdiva << 7); + + /* PLL3 disable */ + data_l = mmio_read_32(CPG_PLLECR) & ~CPG_PLLECR_PLL3E_BIT; + cpg_write_32(CPG_PLLECR, data_l); + dsb_sev(); + + if (prr_product == PRR_PRODUCT_M3) { + /* PLL3 DIV resetting(Lowest value:3) */ + data_l = 0x00030003U | (0xFF80FF80U & mmio_read_32(CPG_FRQCRD)); + cpg_write_32(CPG_FRQCRD, data_l); + dsb_sev(); + + /* zb3 clk stop */ + data_l = CPG_ZB3CKCR_ZB3ST_BIT | mmio_read_32(CPG_ZB3CKCR); + cpg_write_32(CPG_ZB3CKCR, data_l); + dsb_sev(); + + /* PLL3 enable */ + data_l = CPG_PLLECR_PLL3E_BIT | mmio_read_32(CPG_PLLECR); + cpg_write_32(CPG_PLLECR, data_l); + dsb_sev(); + + wait_for_pll3_status_bit_turned_on(); + + /* PLL3 DIV resetting (Highest value:0) */ + data_l = (0xFF80FF80U & mmio_read_32(CPG_FRQCRD)); + cpg_write_32(CPG_FRQCRD, data_l); + dsb_sev(); + + /* DIV SET KICK */ + data_l = CPG_FRQCRB_KICK_BIT | mmio_read_32(CPG_FRQCRB); + cpg_write_32(CPG_FRQCRB, data_l); + dsb_sev(); + + /* PLL3 multiplier set */ + cpg_write_32(CPG_PLL3CR, data_mul); + dsb_sev(); + + wait_for_pll3_status_bit_turned_on(); + + /* PLL3 DIV resetting(Target value) */ + data_l = (data_div << 16U) | data_div | + (mmio_read_32(CPG_FRQCRD) & 0xFF80FF80U); + cpg_write_32(CPG_FRQCRD, data_l); + dsb_sev(); + + /* DIV SET KICK */ + data_l = CPG_FRQCRB_KICK_BIT | mmio_read_32(CPG_FRQCRB); + cpg_write_32(CPG_FRQCRB, data_l); + dsb_sev(); + + wait_for_pll3_status_bit_turned_on(); + + /* zb3 clk start */ + data_l = (~CPG_ZB3CKCR_ZB3ST_BIT) & mmio_read_32(CPG_ZB3CKCR); + cpg_write_32(CPG_ZB3CKCR, data_l); + dsb_sev(); + } +} + +/* barrier */ +static inline void dsb_sev(void) +{ + __asm__ __volatile__("dsb sy"); +} + +/* DDR memory register access */ +static void wait_dbcmd(void) +{ + uint32_t data_l; + /* dummy read */ + data_l = mmio_read_32(DBSC_DBCMD); + dsb_sev(); + while (true) { + /* wait DBCMD 1=busy, 0=ready */ + data_l = mmio_read_32(DBSC_DBWAIT); + dsb_sev(); + if ((data_l & 0x00000001U) == 0x00U) { + break; + } + } +} + +static void send_dbcmd(uint32_t cmd) +{ + /* dummy read */ + wait_dbcmd(); + mmio_write_32(DBSC_DBCMD, cmd); + dsb_sev(); +} + +static void dbwait_loop(uint32_t wait_loop) +{ + uint32_t i; + + for (i = 0U; i < wait_loop; i++) { + wait_dbcmd(); + } +} + +/* DDRPHY register access (raw) */ +static uint32_t reg_ddrphy_read(uint32_t phyno, uint32_t regadd) +{ + uint32_t val; + uint32_t loop; + + val = 0U; + mmio_write_32(DBSC_DBPDRGA(phyno), regadd); + dsb_sev(); + + while (mmio_read_32(DBSC_DBPDRGA(phyno)) != regadd) { + dsb_sev(); + } + dsb_sev(); + + for (loop = 0U; loop < loop_max; loop++) { + val = mmio_read_32(DBSC_DBPDRGD(phyno)); + dsb_sev(); + } + + return val; +} + +static void reg_ddrphy_write(uint32_t phyno, uint32_t regadd, uint32_t regdata) +{ + uint32_t loop; + + mmio_write_32(DBSC_DBPDRGA(phyno), regadd); + dsb_sev(); + for (loop = 0U; loop < loop_max; loop++) { + mmio_read_32(DBSC_DBPDRGA(phyno)); + dsb_sev(); + } + mmio_write_32(DBSC_DBPDRGD(phyno), regdata); + dsb_sev(); + + for (loop = 0U; loop < loop_max; loop++) { + mmio_read_32(DBSC_DBPDRGD(phyno)); + dsb_sev(); + } +} + +static void reg_ddrphy_write_a(uint32_t regadd, uint32_t regdata) +{ + uint32_t ch; + uint32_t loop; + + foreach_vch(ch) { + mmio_write_32(DBSC_DBPDRGA(ch), regadd); + dsb_sev(); + } + + foreach_vch(ch) { + mmio_write_32(DBSC_DBPDRGD(ch), regdata); + dsb_sev(); + } + + for (loop = 0U; loop < loop_max; loop++) { + mmio_read_32(DBSC_DBPDRGD(0)); + dsb_sev(); + } +} + +static inline void ddrphy_regif_idle(void) +{ + reg_ddrphy_read(0U, ddr_regdef_adr(_reg_PI_INT_STATUS)); + dsb_sev(); +} + +/* DDRPHY register access (field modify) */ +static inline uint32_t ddr_regdef(uint32_t _regdef) +{ + return p_ddr_regdef_tbl[_regdef]; +} + +static inline uint32_t ddr_regdef_adr(uint32_t _regdef) +{ + return DDR_REGDEF_ADR(p_ddr_regdef_tbl[_regdef]); +} + +static inline uint32_t ddr_regdef_lsb(uint32_t _regdef) +{ + return DDR_REGDEF_LSB(p_ddr_regdef_tbl[_regdef]); +} + +static void ddr_setval_s(uint32_t ch, uint32_t slice, uint32_t _regdef, + uint32_t val) +{ + uint32_t adr; + uint32_t lsb; + uint32_t len; + uint32_t msk; + uint32_t tmp; + uint32_t regdef; + + regdef = ddr_regdef(_regdef); + adr = DDR_REGDEF_ADR(regdef) + 0x80U * slice; + len = DDR_REGDEF_LEN(regdef); + lsb = DDR_REGDEF_LSB(regdef); + if (len == 0x20U) { + msk = 0xffffffffU; + } else { + msk = ((1U << len) - 1U) << lsb; + } + + tmp = reg_ddrphy_read(ch, adr); + tmp = (tmp & (~msk)) | ((val << lsb) & msk); + reg_ddrphy_write(ch, adr, tmp); +} + +static uint32_t ddr_getval_s(uint32_t ch, uint32_t slice, uint32_t _regdef) +{ + uint32_t adr; + uint32_t lsb; + uint32_t len; + uint32_t msk; + uint32_t tmp; + uint32_t regdef; + + regdef = ddr_regdef(_regdef); + adr = DDR_REGDEF_ADR(regdef) + 0x80U * slice; + len = DDR_REGDEF_LEN(regdef); + lsb = DDR_REGDEF_LSB(regdef); + if (len == 0x20U) { + msk = 0xffffffffU; + } else { + msk = ((1U << len) - 1U); + } + + tmp = reg_ddrphy_read(ch, adr); + tmp = (tmp >> lsb) & msk; + + return tmp; +} + +static void ddr_setval(uint32_t ch, uint32_t regdef, uint32_t val) +{ + ddr_setval_s(ch, 0U, regdef, val); +} + +static void ddr_setval_ach_s(uint32_t slice, uint32_t regdef, uint32_t val) +{ + uint32_t ch; + + foreach_vch(ch) { + ddr_setval_s(ch, slice, regdef, val); + } +} + +static void ddr_setval_ach(uint32_t regdef, uint32_t val) +{ + ddr_setval_ach_s(0U, regdef, val); +} + +static void ddr_setval_ach_as(uint32_t regdef, uint32_t val) +{ + uint32_t slice; + + for (slice = 0U; slice < SLICE_CNT; slice++) { + ddr_setval_ach_s(slice, regdef, val); + } +} + +static uint32_t ddr_getval(uint32_t ch, uint32_t regdef) +{ + return ddr_getval_s(ch, 0U, regdef); +} + +static uint32_t ddr_getval_ach(uint32_t regdef, uint32_t *p) +{ + uint32_t ch; + + foreach_vch(ch) { + p[ch] = ddr_getval_s(ch, 0U, regdef); + } + return p[0U]; +} + +static uint32_t ddr_getval_ach_as(uint32_t regdef, uint32_t *p) +{ + uint32_t ch, slice; + uint32_t *pp; + + pp = p; + foreach_vch(ch) { + for (slice = 0U; slice < SLICE_CNT; slice++) { + *pp++ = ddr_getval_s(ch, slice, regdef); + } + } + return p[0U]; +} + +/* handling functions for setting ddrphy value table */ +static void _tblcopy(uint32_t *to, const uint32_t *from, uint32_t size) +{ + uint32_t i; + + for (i = 0U; i < size; i++) { + to[i] = from[i]; + } +} + +static void ddrtbl_setval(uint32_t *tbl, uint32_t _regdef, uint32_t val) +{ + uint32_t adr; + uint32_t lsb; + uint32_t len; + uint32_t msk; + uint32_t tmp; + uint32_t adrmsk; + uint32_t regdef; + + regdef = ddr_regdef(_regdef); + adr = DDR_REGDEF_ADR(regdef); + len = DDR_REGDEF_LEN(regdef); + lsb = DDR_REGDEF_LSB(regdef); + if (len == 0x20U) { + msk = 0xffffffffU; + } else { + msk = ((1U << len) - 1U) << lsb; + } + + if (adr < 0x400U) { + adrmsk = 0xffU; + } else { + adrmsk = 0x7fU; + } + + tmp = tbl[adr & adrmsk]; + tmp = (tmp & (~msk)) | ((val << lsb) & msk); + tbl[adr & adrmsk] = tmp; +} + +static uint32_t ddrtbl_getval(uint32_t *tbl, uint32_t _regdef) +{ + uint32_t adr; + uint32_t lsb; + uint32_t len; + uint32_t msk; + uint32_t tmp; + uint32_t adrmsk; + uint32_t regdef; + + regdef = ddr_regdef(_regdef); + adr = DDR_REGDEF_ADR(regdef); + len = DDR_REGDEF_LEN(regdef); + lsb = DDR_REGDEF_LSB(regdef); + if (len == 0x20U) { + msk = 0xffffffffU; + } else { + msk = ((1U << len) - 1U); + } + + if (adr < 0x400U) { + adrmsk = 0xffU; + } else { + adrmsk = 0x7fU; + } + + tmp = tbl[adr & adrmsk]; + tmp = (tmp >> lsb) & msk; + + return tmp; +} + +/* DDRPHY register access handling */ +static uint32_t ddrphy_regif_chk(void) +{ + uint32_t tmp_ach[DRAM_CH_CNT]; + uint32_t ch; + uint32_t err; + uint32_t PI_VERSION_CODE; + + if (prr_product == PRR_PRODUCT_M3) { + PI_VERSION_CODE = 0x2041U; /* G2M */ + } + + ddr_getval_ach(_reg_PI_VERSION, (uint32_t *)tmp_ach); + err = 0U; + foreach_vch(ch) { + if (tmp_ach[ch] != PI_VERSION_CODE) { + err = 1U; + } + } + return err; +} + +/* functions and parameters for timing setting */ +struct _jedec_spec1 { + uint16_t fx3; + uint8_t rlwodbi; + uint8_t rlwdbi; + uint8_t WL; + uint8_t nwr; + uint8_t nrtp; + uint8_t odtlon; + uint8_t MR1; + uint8_t MR2; +}; + +#define JS1_USABLEC_SPEC_LO 2U +#define JS1_USABLEC_SPEC_HI 5U +#define JS1_FREQ_TBL_NUM 8 +#define JS1_MR1(f) (0x04U | ((f) << 4U)) +#define JS1_MR2(f) (0x00U | ((f) << 3U) | (f)) +static const struct _jedec_spec1 js1[JS1_FREQ_TBL_NUM] = { + /* 533.333Mbps */ + { 800U, 6U, 6U, 4U, 6U, 8U, 0U, JS1_MR1(0U), JS1_MR2(0U) | 0x40U }, + /* 1066.666Mbps */ + { 1600U, 10U, 12U, 8U, 10U, 8U, 0U, JS1_MR1(1U), JS1_MR2(1U) | 0x40U }, + /* 1600.000Mbps */ + { 2400U, 14U, 16U, 12U, 16U, 8U, 6U, JS1_MR1(2U), JS1_MR2(2U) | 0x40U }, + /* 2133.333Mbps */ + { 3200U, 20U, 22U, 10U, 20U, 8U, 4U, JS1_MR1(3U), JS1_MR2(3U) }, + /* 2666.666Mbps */ + { 4000U, 24U, 28U, 12U, 24U, 10U, 4U, JS1_MR1(4U), JS1_MR2(4U) }, + /* 3200.000Mbps */ + { 4800U, 28U, 32U, 14U, 30U, 12U, 6U, JS1_MR1(5U), JS1_MR2(5U) }, + /* 3733.333Mbps */ + { 5600U, 32U, 36U, 16U, 34U, 14U, 6U, JS1_MR1(6U), JS1_MR2(6U) }, + /* 4266.666Mbps */ + { 6400U, 36U, 40U, 18U, 40U, 16U, 8U, JS1_MR1(7U), JS1_MR2(7U) } +}; + +struct _jedec_spec2 { + uint16_t ps; + uint16_t cyc; +}; + +#define js2_tsr 0 +#define js2_txp 1 +#define js2_trtp 2 +#define js2_trcd 3 +#define js2_trppb 4 +#define js2_trpab 5 +#define js2_tras 6 +#define js2_twr 7 +#define js2_twtr 8 +#define js2_trrd 9 +#define js2_tppd 10 +#define js2_tfaw 11 +#define js2_tdqsck 12 +#define js2_tckehcmd 13 +#define js2_tckelcmd 14 +#define js2_tckelpd 15 +#define js2_tmrr 16 +#define js2_tmrw 17 +#define js2_tmrd 18 +#define js2_tzqcalns 19 +#define js2_tzqlat 20 +#define js2_tiedly 21 +#define js2_tODTon_min 22 +#define JS2_TBLCNT 23 + +#define js2_trcpb (JS2_TBLCNT) +#define js2_trcab (JS2_TBLCNT + 1) +#define js2_trfcab (JS2_TBLCNT + 2) +#define JS2_CNT (JS2_TBLCNT + 3) + +#ifndef JS2_DERATE +#define JS2_DERATE 0 +#endif +static const struct _jedec_spec2 jedec_spec2[2][JS2_TBLCNT] = { + { +/* tSR */ { 15000, 3 }, +/* tXP */ { 7500, 3 }, +/* tRTP */ { 7500, 8 }, +/* tRCD */ { 18000, 4 }, +/* tRPpb */ { 18000, 3 }, +/* tRPab */ { 21000, 3 }, +/* tRAS */ { 42000, 3 }, +/* tWR */ { 18000, 4 }, +/* tWTR */ { 10000, 8 }, +/* tRRD */ { 10000, 4 }, +/* tPPD */ { 0, 0 }, +/* tFAW */ { 40000, 0 }, +/* tDQSCK */ { 3500, 0 }, +/* tCKEHCMD */ { 7500, 3 }, +/* tCKELCMD */ { 7500, 3 }, +/* tCKELPD */ { 7500, 3 }, +/* tMRR */ { 0, 8 }, +/* tMRW */ { 10000, 10 }, +/* tMRD */ { 14000, 10 }, +/* tZQCALns */ { 1000 * 10, 0 }, +/* tZQLAT */ { 30000, 10 }, +/* tIEdly */ { 12500, 0 }, +/* tODTon_min */{ 1500, 0 } + }, { +/* tSR */ { 15000, 3 }, +/* tXP */ { 7500, 3 }, +/* tRTP */ { 7500, 8 }, +/* tRCD */ { 19875, 4 }, +/* tRPpb */ { 19875, 3 }, +/* tRPab */ { 22875, 3 }, +/* tRAS */ { 43875, 3 }, +/* tWR */ { 18000, 4 }, +/* tWTR */ { 10000, 8 }, +/* tRRD */ { 11875, 4 }, +/* tPPD */ { 0, 0 }, +/* tFAW */ { 40000, 0 }, +/* tDQSCK */ { 3600, 0 }, +/* tCKEHCMD */ { 7500, 3 }, +/* tCKELCMD */ { 7500, 3 }, +/* tCKELPD */ { 7500, 3 }, +/* tMRR */ { 0, 8 }, +/* tMRW */ { 10000, 10 }, +/* tMRD */ { 14000, 10 }, +/* tZQCALns */ { 1000 * 10, 0 }, +/* tZQLAT */ { 30000, 10 }, +/* tIEdly */ { 12500, 0 }, +/* tODTon_min */{ 1500, 0 } + } +}; + +static const uint16_t jedec_spec2_trfc_ab[7] = { + /* 4Gb, 6Gb, 8Gb, 12Gb, 16Gb, 24Gb(non), 32Gb(non) */ + 130U, 180U, 180U, 280U, 280U, 560U, 560U +}; + +static uint32_t js1_ind; +static uint16_t js2[JS2_CNT]; +static uint8_t RL; +static uint8_t WL; + +static uint16_t _f_scale(uint32_t _ddr_mbps, uint32_t _ddr_mbpsdiv, uint32_t ps, + uint16_t cyc) +{ + uint16_t ret = cyc; + uint32_t tmp; + uint32_t div; + + tmp = (((uint32_t)(ps) + 9U) / 10U) * _ddr_mbps; + div = tmp / (200000U * _ddr_mbpsdiv); + if (tmp != (div * 200000U * _ddr_mbpsdiv)) { + div = div + 1U; + } + + if (div > cyc) { + ret = (uint16_t)div; + } + + return ret; +} + +static void _f_scale_js2(uint32_t _ddr_mbps, uint32_t _ddr_mbpsdiv, + uint16_t *_js2) +{ + int i; + + for (i = 0; i < JS2_TBLCNT; i++) { + _js2[i] = _f_scale(_ddr_mbps, _ddr_mbpsdiv, + jedec_spec2[JS2_DERATE][i].ps, + jedec_spec2[JS2_DERATE][i].cyc); + } + + _js2[js2_trcpb] = _js2[js2_tras] + _js2[js2_trppb]; + _js2[js2_trcab] = _js2[js2_tras] + _js2[js2_trpab]; +} + +/* scaler for DELAY value */ +static int16_t _f_scale_adj(int16_t ps) +{ + int32_t tmp; + /* + * tmp = (int32_t)512 * ps * ddr_mbps /2 / ddr_mbpsdiv / 1000 / 1000; + * = ps * ddr_mbps /2 / ddr_mbpsdiv *512 / 8 / 8 / 125 / 125 + * = ps * ddr_mbps / ddr_mbpsdiv *4 / 125 / 125 + */ + tmp = (int32_t)4 * (int32_t)ps * (int32_t)ddr_mbps / + (int32_t)ddr_mbpsdiv; + tmp = (int32_t)tmp / (int32_t)15625; + + return (int16_t)tmp; +} + +static const uint32_t reg_pi_mr1_data_fx_csx[2U][CSAB_CNT] = { + { + _reg_PI_MR1_DATA_F0_0, + _reg_PI_MR1_DATA_F0_1, + _reg_PI_MR1_DATA_F0_2, + _reg_PI_MR1_DATA_F0_3}, + { + _reg_PI_MR1_DATA_F1_0, + _reg_PI_MR1_DATA_F1_1, + _reg_PI_MR1_DATA_F1_2, + _reg_PI_MR1_DATA_F1_3} +}; + +static const uint32_t reg_pi_mr2_data_fx_csx[2U][CSAB_CNT] = { + { + _reg_PI_MR2_DATA_F0_0, + _reg_PI_MR2_DATA_F0_1, + _reg_PI_MR2_DATA_F0_2, + _reg_PI_MR2_DATA_F0_3}, + { + _reg_PI_MR2_DATA_F1_0, + _reg_PI_MR2_DATA_F1_1, + _reg_PI_MR2_DATA_F1_2, + _reg_PI_MR2_DATA_F1_3} +}; + +static const uint32_t reg_pi_mr3_data_fx_csx[2U][CSAB_CNT] = { + { + _reg_PI_MR3_DATA_F0_0, + _reg_PI_MR3_DATA_F0_1, + _reg_PI_MR3_DATA_F0_2, + _reg_PI_MR3_DATA_F0_3}, + { + _reg_PI_MR3_DATA_F1_0, + _reg_PI_MR3_DATA_F1_1, + _reg_PI_MR3_DATA_F1_2, + _reg_PI_MR3_DATA_F1_3} +}; + +static const uint32_t reg_pi_mr11_data_fx_csx[2U][CSAB_CNT] = { + { + _reg_PI_MR11_DATA_F0_0, + _reg_PI_MR11_DATA_F0_1, + _reg_PI_MR11_DATA_F0_2, + _reg_PI_MR11_DATA_F0_3}, + { + _reg_PI_MR11_DATA_F1_0, + _reg_PI_MR11_DATA_F1_1, + _reg_PI_MR11_DATA_F1_2, + _reg_PI_MR11_DATA_F1_3} +}; + +static const uint32_t reg_pi_mr12_data_fx_csx[2U][CSAB_CNT] = { + { + _reg_PI_MR12_DATA_F0_0, + _reg_PI_MR12_DATA_F0_1, + _reg_PI_MR12_DATA_F0_2, + _reg_PI_MR12_DATA_F0_3}, + { + _reg_PI_MR12_DATA_F1_0, + _reg_PI_MR12_DATA_F1_1, + _reg_PI_MR12_DATA_F1_2, + _reg_PI_MR12_DATA_F1_3} +}; + +static const uint32_t reg_pi_mr14_data_fx_csx[2U][CSAB_CNT] = { + { + _reg_PI_MR14_DATA_F0_0, + _reg_PI_MR14_DATA_F0_1, + _reg_PI_MR14_DATA_F0_2, + _reg_PI_MR14_DATA_F0_3}, + { + _reg_PI_MR14_DATA_F1_0, + _reg_PI_MR14_DATA_F1_1, + _reg_PI_MR14_DATA_F1_2, + _reg_PI_MR14_DATA_F1_3} +}; + +/* + * regif pll w/a ( REGIF G2M WA ) + */ +static void regif_pll_wa(void) +{ + uint32_t ch; + uint32_t reg_ofs; + + /* PLL setting for PHY : G2M */ + reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_PLL_WAIT), + (0x5064U << + ddr_regdef_lsb(_reg_PHY_PLL_WAIT))); + + reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_PLL_CTRL), + (ddrtbl_getval(_cnf_DDR_PHY_ADR_G_REGSET, + _reg_PHY_PLL_CTRL_TOP) << 16) | + ddrtbl_getval(_cnf_DDR_PHY_ADR_G_REGSET, + _reg_PHY_PLL_CTRL)); + reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_PLL_CTRL_CA), + ddrtbl_getval(_cnf_DDR_PHY_ADR_G_REGSET, + _reg_PHY_PLL_CTRL_CA)); + + reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_LP4_BOOT_PLL_CTRL), + (ddrtbl_getval(_cnf_DDR_PHY_ADR_G_REGSET, + _reg_PHY_LP4_BOOT_PLL_CTRL_CA) << 16) | + ddrtbl_getval(_cnf_DDR_PHY_ADR_G_REGSET, + _reg_PHY_LP4_BOOT_PLL_CTRL)); + reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_LP4_BOOT_TOP_PLL_CTRL), + ddrtbl_getval(_cnf_DDR_PHY_ADR_G_REGSET, + _reg_PHY_LP4_BOOT_TOP_PLL_CTRL)); + + reg_ofs = ddr_regdef_adr(_reg_PHY_LPDDR3_CS) - DDR_PHY_ADR_G_REGSET_OFS; + reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_LPDDR3_CS), + _cnf_DDR_PHY_ADR_G_REGSET[reg_ofs]); + + /* protect register interface */ + ddrphy_regif_idle(); + pll3_control(0U); + + reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_DLL_RST_EN), + (0x01U << ddr_regdef_lsb(_reg_PHY_DLL_RST_EN))); + ddrphy_regif_idle(); + + /* + * init start + * dbdficnt0: + * dfi_dram_clk_disable=1 + * dfi_frequency = 0 + * freq_ratio = 01 (2:1) + * init_start =0 + */ + foreach_vch(ch) { + mmio_write_32(DBSC_DBDFICNT(ch), 0x00000F10U); + } + dsb_sev(); + + /* + * dbdficnt0: + * dfi_dram_clk_disable=1 + * dfi_frequency = 0 + * freq_ratio = 01 (2:1) + * init_start =1 + */ + foreach_vch(ch) { + mmio_write_32(DBSC_DBDFICNT(ch), 0x00000F11U); + } + dsb_sev(); + + foreach_ech(ch) { + if ((board_cnf->phyvalid & BIT(ch)) != 0U) { + while ((mmio_read_32(DBSC_PLL_LOCK(ch)) & 0x1fU) != 0x1fU) { + } + } + } + dsb_sev(); +} + +/* load table data into DDR registers */ +static void ddrtbl_load(void) +{ + uint32_t i; + uint32_t slice; + uint32_t csab; + uint32_t adr; + uint32_t data_l; + uint32_t tmp[3]; + uint16_t dataS; + + /* + * TIMING REGISTERS + * search jedec_spec1 index + */ + for (i = JS1_USABLEC_SPEC_LO; i < (uint32_t)JS1_FREQ_TBL_NUM - 1U; i++) { + if ((js1[i].fx3 * 2U * ddr_mbpsdiv >= ddr_mbps * 3U) != 0U) { + break; + } + } + if (i > JS1_USABLEC_SPEC_HI) { + js1_ind = JS1_USABLEC_SPEC_HI; + } else { + js1_ind = i; + } + + if (board_cnf->dbi_en != 0U) { + RL = js1[js1_ind].rlwdbi; + } else { + RL = js1[js1_ind].rlwodbi; + } + + WL = js1[js1_ind].WL; + + /* calculate jedec_spec2 */ + _f_scale_js2(ddr_mbps, ddr_mbpsdiv, js2); + + /* PREPARE TBL */ + if (prr_product == PRR_PRODUCT_M3) { + /* G2M */ + _tblcopy(_cnf_DDR_PHY_SLICE_REGSET, + DDR_PHY_SLICE_REGSET_G2M, DDR_PHY_SLICE_REGSET_NUM_G2M); + _tblcopy(_cnf_DDR_PHY_ADR_V_REGSET, + DDR_PHY_ADR_V_REGSET_G2M, DDR_PHY_ADR_V_REGSET_NUM_G2M); + _tblcopy(_cnf_DDR_PHY_ADR_I_REGSET, + DDR_PHY_ADR_I_REGSET_G2M, DDR_PHY_ADR_I_REGSET_NUM_G2M); + _tblcopy(_cnf_DDR_PHY_ADR_G_REGSET, + DDR_PHY_ADR_G_REGSET_G2M, DDR_PHY_ADR_G_REGSET_NUM_G2M); + _tblcopy(_cnf_DDR_PI_REGSET, + DDR_PI_REGSET_G2M, DDR_PI_REGSET_NUM_G2M); + + DDR_PHY_SLICE_REGSET_OFS = DDR_PHY_SLICE_REGSET_OFS_G2M; + DDR_PHY_ADR_V_REGSET_OFS = DDR_PHY_ADR_V_REGSET_OFS_G2M; + DDR_PHY_ADR_I_REGSET_OFS = DDR_PHY_ADR_I_REGSET_OFS_G2M; + DDR_PHY_ADR_G_REGSET_OFS = DDR_PHY_ADR_G_REGSET_OFS_G2M; + DDR_PI_REGSET_OFS = DDR_PI_REGSET_OFS_G2M; + DDR_PHY_SLICE_REGSET_SIZE = DDR_PHY_SLICE_REGSET_SIZE_G2M; + DDR_PHY_ADR_V_REGSET_SIZE = DDR_PHY_ADR_V_REGSET_SIZE_G2M; + DDR_PHY_ADR_I_REGSET_SIZE = DDR_PHY_ADR_I_REGSET_SIZE_G2M; + DDR_PHY_ADR_G_REGSET_SIZE = DDR_PHY_ADR_G_REGSET_SIZE_G2M; + DDR_PI_REGSET_SIZE = DDR_PI_REGSET_SIZE_G2M; + DDR_PHY_SLICE_REGSET_NUM = DDR_PHY_SLICE_REGSET_NUM_G2M; + DDR_PHY_ADR_V_REGSET_NUM = DDR_PHY_ADR_V_REGSET_NUM_G2M; + DDR_PHY_ADR_I_REGSET_NUM = DDR_PHY_ADR_I_REGSET_NUM_G2M; + DDR_PHY_ADR_G_REGSET_NUM = DDR_PHY_ADR_G_REGSET_NUM_G2M; + DDR_PI_REGSET_NUM = DDR_PI_REGSET_NUM_G2M; + + DDR_PHY_ADR_I_NUM = 2U; + } + + /* on fly gate adjust */ + if ((prr_product == PRR_PRODUCT_M3) && (prr_cut == PRR_PRODUCT_10)) { + ddrtbl_setval(_cnf_DDR_PHY_SLICE_REGSET, + _reg_ON_FLY_GATE_ADJUST_EN, 0x00); + } + + /* Adjust PI parameters */ +#ifdef _def_LPDDR4_ODT + for (i = 0U; i < 2U; i++) { + for (csab = 0U; csab < CSAB_CNT; csab++) { + ddrtbl_setval(_cnf_DDR_PI_REGSET, + reg_pi_mr11_data_fx_csx[i][csab], + _def_LPDDR4_ODT); + } + } +#endif /* _def_LPDDR4_ODT */ + +#ifdef _def_LPDDR4_VREFCA + for (i = 0U; i < 2U; i++) { + for (csab = 0U; csab < CSAB_CNT; csab++) { + ddrtbl_setval(_cnf_DDR_PI_REGSET, + reg_pi_mr12_data_fx_csx[i][csab], + _def_LPDDR4_VREFCA); + } + } +#endif /* _def_LPDDR4_VREFCA */ + + if ((js2[js2_tiedly]) >= 0x0eU) { + dataS = 0x0eU; + } else { + dataS = js2[js2_tiedly]; + } + + ddrtbl_setval(_cnf_DDR_PHY_SLICE_REGSET, _reg_PHY_RDDATA_EN_DLY, dataS); + ddrtbl_setval(_cnf_DDR_PHY_SLICE_REGSET, _reg_PHY_RDDATA_EN_TSEL_DLY, + (dataS - 2U)); + ddrtbl_setval(_cnf_DDR_PI_REGSET, _reg_PI_RDLAT_ADJ_F1, RL - dataS); + + if (ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET, _reg_PHY_WRITE_PATH_LAT_ADD) != 0U) { + data_l = WL - 1U; + } else { + data_l = WL; + } + ddrtbl_setval(_cnf_DDR_PI_REGSET, _reg_PI_WRLAT_ADJ_F1, data_l - 2U); + ddrtbl_setval(_cnf_DDR_PI_REGSET, _reg_PI_WRLAT_F1, data_l); + + if (board_cnf->dbi_en != 0U) { + ddrtbl_setval(_cnf_DDR_PHY_SLICE_REGSET, _reg_PHY_DBI_MODE, + 0x01U); + ddrtbl_setval(_cnf_DDR_PHY_SLICE_REGSET, + _reg_PHY_WDQLVL_DATADM_MASK, 0x000U); + } else { + ddrtbl_setval(_cnf_DDR_PHY_SLICE_REGSET, _reg_PHY_DBI_MODE, + 0x00U); + ddrtbl_setval(_cnf_DDR_PHY_SLICE_REGSET, + _reg_PHY_WDQLVL_DATADM_MASK, 0x100U); + } + + tmp[0] = js1[js1_ind].MR1; + tmp[1] = js1[js1_ind].MR2; + data_l = ddrtbl_getval(_cnf_DDR_PI_REGSET, _reg_PI_MR3_DATA_F1_0); + if (board_cnf->dbi_en != 0U) { + tmp[2] = data_l | 0xc0U; + } else { + tmp[2] = data_l & (~0xc0U); + } + + for (i = 0U; i < 2U; i++) { + for (csab = 0U; csab < CSAB_CNT; csab++) { + ddrtbl_setval(_cnf_DDR_PI_REGSET, + reg_pi_mr1_data_fx_csx[i][csab], tmp[0]); + ddrtbl_setval(_cnf_DDR_PI_REGSET, + reg_pi_mr2_data_fx_csx[i][csab], tmp[1]); + ddrtbl_setval(_cnf_DDR_PI_REGSET, + reg_pi_mr3_data_fx_csx[i][csab], tmp[2]); + } + } + + /* DDRPHY INT START */ + regif_pll_wa(); + dbwait_loop(5U); + + /* FREQ_SEL_MULTICAST & PER_CS_TRAINING_MULTICAST SET (for safety) */ + reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_FREQ_SEL_MULTICAST_EN), + BIT(ddr_regdef_lsb(_reg_PHY_FREQ_SEL_MULTICAST_EN))); + ddr_setval_ach_as(_reg_PHY_PER_CS_TRAINING_MULTICAST_EN, 0x01U); + + /* SET DATA SLICE TABLE */ + for (slice = 0U; slice < SLICE_CNT; slice++) { + adr = + DDR_PHY_SLICE_REGSET_OFS + + DDR_PHY_SLICE_REGSET_SIZE * slice; + for (i = 0U; i < DDR_PHY_SLICE_REGSET_NUM; i++) { + reg_ddrphy_write_a(adr + i, + _cnf_DDR_PHY_SLICE_REGSET[i]); + } + } + + /* SET ADR SLICE TABLE */ + adr = DDR_PHY_ADR_V_REGSET_OFS; + for (i = 0U; i < DDR_PHY_ADR_V_REGSET_NUM; i++) { + reg_ddrphy_write_a(adr + i, _cnf_DDR_PHY_ADR_V_REGSET[i]); + } + + if ((prr_product == PRR_PRODUCT_M3) && + ((0x00ffffffU & (uint32_t)((board_cnf->ch[0].ca_swap) >> 40U)) + != 0x00U)) { + adr = DDR_PHY_ADR_I_REGSET_OFS + DDR_PHY_ADR_I_REGSET_SIZE; + for (i = 0U; i < DDR_PHY_ADR_V_REGSET_NUM; i++) { + reg_ddrphy_write_a(adr + i, + _cnf_DDR_PHY_ADR_V_REGSET[i]); + } + ddrtbl_setval(_cnf_DDR_PHY_ADR_G_REGSET, + _reg_PHY_ADR_DISABLE, 0x02); + DDR_PHY_ADR_I_NUM -= 1U; + ddr_phycaslice = 1U; + +#ifndef _def_LPDDR4_ODT + for (i = 0U; i < 2U; i++) { + for (csab = 0U; csab < CSAB_CNT; csab++) { + ddrtbl_setval(_cnf_DDR_PI_REGSET, + reg_pi_mr11_data_fx_csx[i][csab], + 0x66); + } + } +#endif/* _def_LPDDR4_ODT */ + } else { + ddr_phycaslice = 0U; + } + + if (DDR_PHY_ADR_I_NUM > 0U) { + for (slice = 0U; slice < DDR_PHY_ADR_I_NUM; slice++) { + adr = + DDR_PHY_ADR_I_REGSET_OFS + + DDR_PHY_ADR_I_REGSET_SIZE * slice; + for (i = 0U; i < DDR_PHY_ADR_I_REGSET_NUM; i++) { + reg_ddrphy_write_a(adr + i, + _cnf_DDR_PHY_ADR_I_REGSET + [i]); + } + } + } + + /* SET ADRCTRL SLICE TABLE */ + adr = DDR_PHY_ADR_G_REGSET_OFS; + for (i = 0U; i < DDR_PHY_ADR_G_REGSET_NUM; i++) { + reg_ddrphy_write_a(adr + i, _cnf_DDR_PHY_ADR_G_REGSET[i]); + } + + /* SET PI REGISTERS */ + adr = DDR_PI_REGSET_OFS; + for (i = 0U; i < DDR_PI_REGSET_NUM; i++) { + reg_ddrphy_write_a(adr + i, _cnf_DDR_PI_REGSET[i]); + } +} + +/* CONFIGURE DDR REGISTERS */ +static void ddr_config_sub(void) +{ + const uint32_t _par_CALVL_DEVICE_MAP = 1U; + uint8_t high_byte[SLICE_CNT]; + uint32_t ch, slice; + uint32_t data_l; + uint32_t tmp; + uint32_t i; + + foreach_vch(ch) { + /* BOARD SETTINGS (DQ,DM,VREF_DRIVING) */ + for (slice = 0U; slice < SLICE_CNT; slice++) { + high_byte[slice] = + (board_cnf->ch[ch].dqs_swap >> (4U * slice)) % 2U; + ddr_setval_s(ch, slice, _reg_PHY_DQ_DM_SWIZZLE0, + board_cnf->ch[ch].dq_swap[slice]); + ddr_setval_s(ch, slice, _reg_PHY_DQ_DM_SWIZZLE1, + board_cnf->ch[ch].dm_swap[slice]); + if (high_byte[slice] != 0U) { + /* HIGHER 16 BYTE */ + ddr_setval_s(ch, slice, + _reg_PHY_CALVL_VREF_DRIVING_SLICE, + 0x00); + } else { + /* LOWER 16 BYTE */ + ddr_setval_s(ch, slice, + _reg_PHY_CALVL_VREF_DRIVING_SLICE, + 0x01); + } + } + + /* BOARD SETTINGS (CA,ADDR_SEL) */ + data_l = (0x00ffffffU & (uint32_t)(board_cnf->ch[ch].ca_swap)) | + 0x00888888U; + + /* --- ADR_CALVL_SWIZZLE --- */ + if (prr_product == PRR_PRODUCT_M3) { + ddr_setval(ch, _reg_PHY_ADR_CALVL_SWIZZLE0_0, data_l); + ddr_setval(ch, _reg_PHY_ADR_CALVL_SWIZZLE1_0, + 0x00000000); + ddr_setval(ch, _reg_PHY_ADR_CALVL_SWIZZLE0_1, data_l); + ddr_setval(ch, _reg_PHY_ADR_CALVL_SWIZZLE1_1, + 0x00000000); + ddr_setval(ch, _reg_PHY_ADR_CALVL_DEVICE_MAP, + _par_CALVL_DEVICE_MAP); + } else { + ddr_setval(ch, _reg_PHY_ADR_CALVL_SWIZZLE0, data_l); + ddr_setval(ch, _reg_PHY_ADR_CALVL_SWIZZLE1, 0x00000000); + ddr_setval(ch, _reg_PHY_CALVL_DEVICE_MAP, + _par_CALVL_DEVICE_MAP); + } + + /* --- ADR_ADDR_SEL --- */ + data_l = 0U; + tmp = board_cnf->ch[ch].ca_swap; + for (i = 0U; i < 6U; i++) { + data_l |= ((tmp & 0x0fU) << (i * 5U)); + tmp = tmp >> 4; + } + ddr_setval(ch, _reg_PHY_ADR_ADDR_SEL, data_l); + if (ddr_phycaslice == 1U) { + /* ----------- adr slice2 swap ----------- */ + tmp = (uint32_t)((board_cnf->ch[ch].ca_swap) >> 40); + data_l = (tmp & 0x00ffffffU) | 0x00888888U; + + /* --- ADR_CALVL_SWIZZLE --- */ + if (prr_product == PRR_PRODUCT_M3) { + ddr_setval_s(ch, 2, + _reg_PHY_ADR_CALVL_SWIZZLE0_0, + data_l); + ddr_setval_s(ch, 2, + _reg_PHY_ADR_CALVL_SWIZZLE1_0, + 0x00000000); + ddr_setval_s(ch, 2, + _reg_PHY_ADR_CALVL_SWIZZLE0_1, + data_l); + ddr_setval_s(ch, 2, + _reg_PHY_ADR_CALVL_SWIZZLE1_1, + 0x00000000); + ddr_setval_s(ch, 2, + _reg_PHY_ADR_CALVL_DEVICE_MAP, + _par_CALVL_DEVICE_MAP); + } else { + ddr_setval_s(ch, 2, + _reg_PHY_ADR_CALVL_SWIZZLE0, + data_l); + ddr_setval_s(ch, 2, + _reg_PHY_ADR_CALVL_SWIZZLE1, + 0x00000000); + ddr_setval_s(ch, 2, + _reg_PHY_CALVL_DEVICE_MAP, + _par_CALVL_DEVICE_MAP); + } + + /* --- ADR_ADDR_SEL --- */ + data_l = 0U; + for (i = 0U; i < 6U; i++) { + data_l |= ((tmp & 0x0fU) << (i * 5U)); + tmp = tmp >> 4U; + } + + ddr_setval_s(ch, 2, _reg_PHY_ADR_ADDR_SEL, data_l); + } + + /* BOARD SETTINGS (BYTE_ORDER_SEL) */ + if (prr_product == PRR_PRODUCT_M3) { + /* --- DATA_BYTE_SWAP --- */ + data_l = 0U; + tmp = board_cnf->ch[ch].dqs_swap; + for (i = 0U; i < 4U; i++) { + data_l |= ((tmp & 0x03U) << (i * 2U)); + tmp = tmp >> 4U; + } + } else { + /* --- DATA_BYTE_SWAP --- */ + data_l = board_cnf->ch[ch].dqs_swap; + ddr_setval(ch, _reg_PI_DATA_BYTE_SWAP_EN, 0x01); + ddr_setval(ch, _reg_PI_DATA_BYTE_SWAP_SLICE0, + (data_l) & 0x0fU); + ddr_setval(ch, _reg_PI_DATA_BYTE_SWAP_SLICE1, + (data_l >> 4U * 1U) & 0x0fU); + ddr_setval(ch, _reg_PI_DATA_BYTE_SWAP_SLICE2, + (data_l >> 4U * 2U) & 0x0fU); + ddr_setval(ch, _reg_PI_DATA_BYTE_SWAP_SLICE3, + (data_l >> 4U * 3U) & 0x0fU); + + ddr_setval(ch, _reg_PHY_DATA_BYTE_ORDER_SEL_HIGH, 0x00U); + } + ddr_setval(ch, _reg_PHY_DATA_BYTE_ORDER_SEL, data_l); + } +} + +static void ddr_config(void) +{ + uint32_t num_cacs_dly = _reg_PHY_CLK_CACS_SLAVE_DELAY_X_NUM; + uint32_t reg_ofs, dly; + uint32_t ch, slice; + uint32_t data_l; + uint32_t tmp; + uint32_t i; + int8_t _adj; + int16_t adj; + uint32_t dq; + union { + uint32_t ui32[4]; + uint8_t ui8[16]; + } patt; + uint16_t patm; + + /* configure ddrphy registers */ + ddr_config_sub(); + + /* WDQ_USER_PATT */ + foreach_vch(ch) { + for (slice = 0U; slice < SLICE_CNT; slice++) { + patm = 0U; + for (i = 0U; i < 16U; i++) { + tmp = board_cnf->ch[ch].wdqlvl_patt[i]; + patt.ui8[i] = tmp & 0xffU; + if ((tmp & 0x100U) != 0U) { + patm |= (1U << (uint16_t)i); + } + } + ddr_setval_s(ch, slice, _reg_PHY_USER_PATT0, + patt.ui32[0]); + ddr_setval_s(ch, slice, _reg_PHY_USER_PATT1, + patt.ui32[1]); + ddr_setval_s(ch, slice, _reg_PHY_USER_PATT2, + patt.ui32[2]); + ddr_setval_s(ch, slice, _reg_PHY_USER_PATT3, + patt.ui32[3]); + ddr_setval_s(ch, slice, _reg_PHY_USER_PATT4, patm); + } + } + + /* CACS DLY */ + data_l = board_cnf->cacs_dly + (uint32_t)_f_scale_adj(board_cnf->cacs_dly_adj); + reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_FREQ_SEL_MULTICAST_EN), 0x00U); + foreach_vch(ch) { + for (i = 0U; i < num_cacs_dly - 4U; i++) { + adj = _f_scale_adj(board_cnf->ch[ch].cacs_adj[i]); + dly = _reg_PHY_CLK_CACS_SLAVE_DELAY_X[i]; + ddrtbl_setval(_cnf_DDR_PHY_ADR_V_REGSET, dly, + data_l + (uint32_t)adj); + reg_ofs = ddr_regdef_adr(dly) - DDR_PHY_ADR_V_REGSET_OFS; + reg_ddrphy_write(ch, ddr_regdef_adr(dly), + _cnf_DDR_PHY_ADR_V_REGSET[reg_ofs]); + } + + for (i = num_cacs_dly - 4U; i < num_cacs_dly; i++) { + adj = _f_scale_adj(board_cnf->ch[ch].cacs_adj[i]); + dly = _reg_PHY_CLK_CACS_SLAVE_DELAY_X[i]; + ddrtbl_setval(_cnf_DDR_PHY_ADR_G_REGSET, dly, + data_l + (uint32_t)adj); + reg_ofs = ddr_regdef_adr(dly) - DDR_PHY_ADR_G_REGSET_OFS; + reg_ddrphy_write(ch, ddr_regdef_adr(dly), + _cnf_DDR_PHY_ADR_G_REGSET[reg_ofs]); + } + + if (ddr_phycaslice == 1U) { + for (i = 0U; i < 6U; i++) { + adj = _f_scale_adj(board_cnf->ch[ch].cacs_adj[i + num_cacs_dly]); + dly = _reg_PHY_CLK_CACS_SLAVE_DELAY_X[i]; + ddrtbl_setval(_cnf_DDR_PHY_ADR_V_REGSET, dly, + data_l + (uint32_t)adj); + reg_ofs = ddr_regdef_adr(dly) - DDR_PHY_ADR_V_REGSET_OFS; + reg_ddrphy_write(ch, ddr_regdef_adr(dly) + 0x0100U, + _cnf_DDR_PHY_ADR_V_REGSET[reg_ofs]); + } + } + } + + reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_FREQ_SEL_MULTICAST_EN), + BIT(ddr_regdef_lsb(_reg_PHY_FREQ_SEL_MULTICAST_EN))); + + /* WDQDM DLY */ + data_l = board_cnf->dqdm_dly_w; + foreach_vch(ch) { + for (slice = 0U; slice < SLICE_CNT; slice++) { + for (i = 0U; i <= 8U; i++) { + dq = slice * 8U + (uint32_t)i; + if (i == 8U) { + _adj = board_cnf->ch[ch].dm_adj_w[slice]; + } else { + _adj = board_cnf->ch[ch].dq_adj_w[dq]; + } + adj = _f_scale_adj(_adj); + ddr_setval_s(ch, slice, + _reg_PHY_CLK_WRX_SLAVE_DELAY[i], + data_l + (uint32_t)adj); + } + } + } + + /* RDQDM DLY */ + data_l = board_cnf->dqdm_dly_r; + foreach_vch(ch) { + for (slice = 0U; slice < SLICE_CNT; slice++) { + for (i = 0U; i <= 8U; i++) { + dq = slice * 8U + (uint32_t)i; + if (i == 8U) { + _adj = board_cnf->ch[ch].dm_adj_r[slice]; + } else { + _adj = board_cnf->ch[ch].dq_adj_r[dq]; + } + adj = _f_scale_adj(_adj); + dly = _reg_PHY_RDDQS_X_FALL_SLAVE_DELAY[i]; + ddr_setval_s(ch, slice, dly, data_l + (uint32_t)adj); + dly = _reg_PHY_RDDQS_X_RISE_SLAVE_DELAY[i]; + ddr_setval_s(ch, slice, dly, data_l + (uint32_t)adj); + } + } + } +} + +/* DBSC register setting functions */ +static void dbsc_regset_pre(void) +{ + uint32_t ch, csab; + uint32_t data_l; + + /* PRIMARY SETTINGS */ + /* LPDDR4, BL=16, DFI interface */ + mmio_write_32(DBSC_DBKIND, 0x0000000aU); + mmio_write_32(DBSC_DBBL, 0x00000002U); + mmio_write_32(DBSC_DBPHYCONF0, 0x00000001U); + + /* FREQRATIO=2 */ + mmio_write_32(DBSC_DBSYSCONF1, 0x00000002U); + + /* + * DRAM SIZE REGISTER: + * set all ranks as density=0(4Gb) for PHY initialization + */ + foreach_vch(ch) { + for (csab = 0U; csab < 4U; csab++) { + mmio_write_32(DBSC_DBMEMCONF(ch, csab), + DBMEMCONF_REGD(0U)); + } + } + + if (prr_product == PRR_PRODUCT_M3) { + data_l = 0xe4e4e4e4U; + foreach_ech(ch) { + if ((ddr_phyvalid & (1U << ch)) != 0U) { + data_l = (data_l & (~(0x000000FFU << (ch * 8U)))) + | (((board_cnf->ch[ch].dqs_swap & 0x0003U) + | ((board_cnf->ch[ch].dqs_swap & 0x0030U) >> 2U) + | ((board_cnf->ch[ch].dqs_swap & 0x0300U) >> 4U) + | ((board_cnf->ch[ch].dqs_swap & 0x3000U) >> 6U)) + << (ch * 8U)); + } + } + mmio_write_32(DBSC_DBBSWAP, data_l); + } +} + +static void dbsc_regset(void) +{ + int32_t i; + uint32_t ch; + uint32_t data_l; + uint32_t data_l2; + uint32_t wdql; + uint32_t dqenltncy; + uint32_t dql; + uint32_t dqienltncy; + uint32_t wrcslat; + uint32_t wrcsgap; + uint32_t rdcslat; + uint32_t rdcsgap; + uint32_t scfctst0_act_act; + uint32_t scfctst0_rda_act; + uint32_t scfctst0_wra_act; + uint32_t scfctst0_pre_act; + uint32_t scfctst1_rd_wr; + uint32_t scfctst1_wr_rd; + uint32_t scfctst1_act_rd_wr; + uint32_t scfctst1_asyncofs; + uint32_t dbschhrw1_sctrfcab; + + /* RFC */ + js2[js2_trfcab] = + _f_scale(ddr_mbps, ddr_mbpsdiv, + jedec_spec2_trfc_ab[max_density] * 1000U, 0U); + /* DBTR0.CL : RL */ + mmio_write_32(DBSC_DBTR(0), RL); + + /* DBTR1.CWL : WL */ + mmio_write_32(DBSC_DBTR(1), WL); + + /* DBTR2.AL : 0 */ + mmio_write_32(DBSC_DBTR(2), 0U); + + /* DBTR3.TRCD: tRCD */ + mmio_write_32(DBSC_DBTR(3), js2[js2_trcd]); + + /* DBTR4.TRPA,TRP: tRPab,tRPpb */ + mmio_write_32(DBSC_DBTR(4), (js2[js2_trpab] << 16) | js2[js2_trppb]); + + /* DBTR5.TRC : use tRCpb */ + mmio_write_32(DBSC_DBTR(5), js2[js2_trcpb]); + + /* DBTR6.TRAS : tRAS */ + mmio_write_32(DBSC_DBTR(6), js2[js2_tras]); + + /* DBTR7.TRRD : tRRD */ + mmio_write_32(DBSC_DBTR(7), (js2[js2_trrd] << 16) | js2[js2_trrd]); + + /* DBTR8.TFAW : tFAW */ + mmio_write_32(DBSC_DBTR(8), js2[js2_tfaw]); + + /* DBTR9.TRDPR : tRTP */ + mmio_write_32(DBSC_DBTR(9), js2[js2_trtp]); + + /* DBTR10.TWR : nWR */ + mmio_write_32(DBSC_DBTR(10), js1[js1_ind].nwr); + + /* + * DBTR11.TRDWR : RL + BL / 2 + Rounddown(tRPST) + PHY_ODTLoff - + * odtlon + tDQSCK - tODTon,min + + * PCB delay (out+in) + tPHY_ODToff + */ + mmio_write_32(DBSC_DBTR(11), + RL + (16U / 2U) + 1U + 2U - js1[js1_ind].odtlon + + js2[js2_tdqsck] - js2[js2_tODTon_min] + + _f_scale(ddr_mbps, ddr_mbpsdiv, 1300, 0)); + + /* DBTR12.TWRRD : WL + 1 + BL/2 + tWTR */ + data_l = WL + 1U + (16U / 2U) + js2[js2_twtr]; + mmio_write_32(DBSC_DBTR(12), (data_l << 16) | data_l); + + /* DBTR13.TRFCAB : tRFCab */ + mmio_write_32(DBSC_DBTR(13), js2[js2_trfcab]); + + /* DBTR14.TCKEHDLL,tCKEH : tCKEHCMD,tCKEHCMD */ + mmio_write_32(DBSC_DBTR(14), + (js2[js2_tckehcmd] << 16) | (js2[js2_tckehcmd])); + + /* DBTR15.TCKESR,TCKEL : tSR,tCKELPD */ + mmio_write_32(DBSC_DBTR(15), (js2[js2_tsr] << 16) | (js2[js2_tckelpd])); + + /* DBTR16 */ + /* WDQL : tphy_wrlat + tphy_wrdata */ + wdql = ddrtbl_getval(_cnf_DDR_PI_REGSET, _reg_PI_WRLAT_F1); + /* DQENLTNCY : tphy_wrlat = WL-2 : PHY_WRITE_PATH_LAT_ADD == 0 + * tphy_wrlat = WL-3 : PHY_WRITE_PATH_LAT_ADD != 0 + */ + dqenltncy = ddrtbl_getval(_cnf_DDR_PI_REGSET, _reg_PI_WRLAT_ADJ_F1); + /* DQL : tphy_rdlat + trdata_en */ + /* it is not important for dbsc */ + dql = RL + 16U; + /* DQIENLTNCY : trdata_en */ + dqienltncy = ddrtbl_getval(_cnf_DDR_PI_REGSET, _reg_PI_RDLAT_ADJ_F1) - 1U; + mmio_write_32(DBSC_DBTR(16), + (dqienltncy << 24) | (dql << 16) | (dqenltncy << 8) | wdql); + + /* DBTR24 */ + /* WRCSLAT = WRLAT -5 */ + wrcslat = wdql - 5U; + /* WRCSGAP = 5 */ + wrcsgap = 5U; + /* RDCSLAT = RDLAT_ADJ +2 */ + rdcslat = dqienltncy; + if (prr_product != PRR_PRODUCT_M3) { + rdcslat += 2U; + } + /* RDCSGAP = 6 */ + rdcsgap = 6U; + if (prr_product == PRR_PRODUCT_M3) { + rdcsgap = 4U; + } + mmio_write_32(DBSC_DBTR(24), + (rdcsgap << 24) | (rdcslat << 16) | (wrcsgap << 8) | wrcslat); + + /* DBTR17.TMODRD,TMOD,TRDMR: tMRR,tMRD,(0) */ + mmio_write_32(DBSC_DBTR(17), + (js2[js2_tmrr] << 24) | (js2[js2_tmrd] << 16)); + + /* DBTR18.RODTL, RODTA, WODTL, WODTA : do not use in LPDDR4 */ + mmio_write_32(DBSC_DBTR(18), 0); + + /* DBTR19.TZQCL, TZQCS : do not use in LPDDR4 */ + mmio_write_32(DBSC_DBTR(19), 0); + + /* DBTR20.TXSDLL, TXS : tRFCab+tCKEHCMD */ + data_l = js2[js2_trfcab] + js2[js2_tckehcmd]; + mmio_write_32(DBSC_DBTR(20), (data_l << 16) | data_l); + + /* DBTR21.TCCD */ + /* DBTR23.TCCD */ + if (ddr_tccd == 8U) { + data_l = 8U; + mmio_write_32(DBSC_DBTR(21), (data_l << 16) | data_l); + mmio_write_32(DBSC_DBTR(23), 0x00000002); + } else if (ddr_tccd <= 11U) { + data_l = 11U; + mmio_write_32(DBSC_DBTR(21), (data_l << 16) | data_l); + mmio_write_32(DBSC_DBTR(23), 0x00000000); + } else { + data_l = ddr_tccd; + mmio_write_32(DBSC_DBTR(21), (data_l << 16) | data_l); + mmio_write_32(DBSC_DBTR(23), 0x00000000); + } + + /* DBTR22.ZQLAT : */ + data_l = js2[js2_tzqcalns] * 100U; /* 1000 * 1000 ps */ + data_l = (data_l << 16U) | (js2[js2_tzqlat] + 24U + 20U); + mmio_write_32(DBSC_DBTR(22), data_l); + + /* DBTR25 : do not use in LPDDR4 */ + mmio_write_32(DBSC_DBTR(25), 0U); + + /* + * DBRNK : + * DBSC_DBRNK2 rkrr + * DBSC_DBRNK3 rkrw + * DBSC_DBRNK4 rkwr + * DBSC_DBRNK5 rkww + */ +#define _par_DBRNK_VAL (0x7007U) + + for (i = 0; i < 4; i++) { + data_l = (_par_DBRNK_VAL >> ((uint32_t)i * 4U)) & 0x0fU; + data_l2 = 0U; + foreach_vch(ch) { + data_l2 = data_l2 | (data_l << (4U * ch)); + } + mmio_write_32(DBSC_DBRNK(2 + i), data_l2); + } + mmio_write_32(DBSC_DBADJ0, 0x00000000U); + + /* timing registers for scheduler */ + /* SCFCTST0 */ + /* SCFCTST0 ACT-ACT */ + scfctst0_act_act = js2[js2_trcpb] * 800UL * ddr_mbpsdiv / ddr_mbps; + /* SCFCTST0 RDA-ACT */ + scfctst0_rda_act = ((16U / 2U) + js2[js2_trtp] - 8U + + js2[js2_trppb]) * 800UL * ddr_mbpsdiv / ddr_mbps; + /* SCFCTST0 WRA-ACT */ + scfctst0_wra_act = (WL + 1U + (16U / 2U) + + js1[js1_ind].nwr) * 800UL * ddr_mbpsdiv / ddr_mbps; + /* SCFCTST0 PRE-ACT */ + scfctst0_pre_act = js2[js2_trppb]; + mmio_write_32(DBSC_SCFCTST0, + (scfctst0_act_act << 24) | (scfctst0_rda_act << 16) | + (scfctst0_wra_act << 8) | scfctst0_pre_act); + + /* SCFCTST1 */ + /* SCFCTST1 RD-WR */ + scfctst1_rd_wr = (mmio_read_32(DBSC_DBTR(11)) & 0xffU) * 800UL * ddr_mbpsdiv / + ddr_mbps; + /* SCFCTST1 WR-RD */ + scfctst1_wr_rd = (mmio_read_32(DBSC_DBTR(12)) & 0xff) * 800UL * ddr_mbpsdiv / + ddr_mbps; + /* SCFCTST1 ACT-RD/WR */ + scfctst1_act_rd_wr = js2[js2_trcd] * 800UL * ddr_mbpsdiv / ddr_mbps; + /* SCFCTST1 ASYNCOFS */ + scfctst1_asyncofs = 12U; + mmio_write_32(DBSC_SCFCTST1, + (scfctst1_rd_wr << 24) | (scfctst1_wr_rd << 16) | + (scfctst1_act_rd_wr << 8) | scfctst1_asyncofs); + + /* DBSCHRW1 */ + /* DBSCHRW1 SCTRFCAB */ + dbschhrw1_sctrfcab = js2[js2_trfcab] * 800UL * ddr_mbpsdiv / ddr_mbps; + data_l = (((mmio_read_32(DBSC_DBTR(16)) & 0x00FF0000U) >> 16) + + (mmio_read_32(DBSC_DBTR(22)) & 0x0000FFFFU) + + (0x28U * 2U)) * 400U * 2U * ddr_mbpsdiv / ddr_mbps + 7U; + if (dbschhrw1_sctrfcab < data_l) { + dbschhrw1_sctrfcab = data_l; + } + + if ((prr_product == PRR_PRODUCT_M3) && (prr_cut < PRR_PRODUCT_30)) { + mmio_write_32(DBSC_DBSCHRW1, dbschhrw1_sctrfcab + + ((mmio_read_32(DBSC_DBTR(22)) & 0x0000FFFFU) * + 400U * 2U * ddr_mbpsdiv + (ddr_mbps - 1U)) / ddr_mbps - 3U); + } else { + mmio_write_32(DBSC_DBSCHRW1, dbschhrw1_sctrfcab + + ((mmio_read_32(DBSC_DBTR(22)) & 0x0000FFFFU) * + 400U * 2U * ddr_mbpsdiv + (ddr_mbps - 1U)) / ddr_mbps); + } + + /* QOS and CAM */ +#ifdef DDR_QOS_INIT_SETTING /* only for non qos_init */ + /* wbkwait(0004), wbkmdhi(4,2),wbkmdlo(1,8) */ + mmio_write_32(DBSC_DBCAM0CNF1, 0x00043218U); + /* 0(fillunit),8(dirtymax),4(dirtymin) */ + mmio_write_32(DBSC_DBCAM0CNF2, 0x000000F4U); + /* stop_tolerance */ + mmio_write_32(DBSC_DBSCHRW0, 0x22421111U); + /* rd-wr/wr-rd toggle priority */ + mmio_write_32(DBSC_SCFCTST2, 0x012F1123U); + mmio_write_32(DBSC_DBSCHSZ0, 0x00000001U); + mmio_write_32(DBSC_DBSCHCNT0, 0x000F0037U); + + /* QoS Settings */ + mmio_write_32(DBSC_DBSCHQOS00, 0x00000F00U); + mmio_write_32(DBSC_DBSCHQOS01, 0x00000B00U); + mmio_write_32(DBSC_DBSCHQOS02, 0x00000000U); + mmio_write_32(DBSC_DBSCHQOS03, 0x00000000U); + mmio_write_32(DBSC_DBSCHQOS40, 0x00000300U); + mmio_write_32(DBSC_DBSCHQOS41, 0x000002F0U); + mmio_write_32(DBSC_DBSCHQOS42, 0x00000200U); + mmio_write_32(DBSC_DBSCHQOS43, 0x00000100U); + mmio_write_32(DBSC_DBSCHQOS90, 0x00000100U); + mmio_write_32(DBSC_DBSCHQOS91, 0x000000F0U); + mmio_write_32(DBSC_DBSCHQOS92, 0x000000A0U); + mmio_write_32(DBSC_DBSCHQOS93, 0x00000040U); + mmio_write_32(DBSC_DBSCHQOS120, 0x00000040U); + mmio_write_32(DBSC_DBSCHQOS121, 0x00000030U); + mmio_write_32(DBSC_DBSCHQOS122, 0x00000020U); + mmio_write_32(DBSC_DBSCHQOS123, 0x00000010U); + mmio_write_32(DBSC_DBSCHQOS130, 0x00000100U); + mmio_write_32(DBSC_DBSCHQOS131, 0x000000F0U); + mmio_write_32(DBSC_DBSCHQOS132, 0x000000A0U); + mmio_write_32(DBSC_DBSCHQOS133, 0x00000040U); + mmio_write_32(DBSC_DBSCHQOS140, 0x000000C0U); + mmio_write_32(DBSC_DBSCHQOS141, 0x000000B0U); + mmio_write_32(DBSC_DBSCHQOS142, 0x00000080U); + mmio_write_32(DBSC_DBSCHQOS143, 0x00000040U); + mmio_write_32(DBSC_DBSCHQOS150, 0x00000040U); + mmio_write_32(DBSC_DBSCHQOS151, 0x00000030U); + mmio_write_32(DBSC_DBSCHQOS152, 0x00000020U); + mmio_write_32(DBSC_DBSCHQOS153, 0x00000010U); + + mmio_write_32(QOSCTRL_RAEN, 0x00000001U); +#endif /* DDR_QOS_INIT_SETTING */ + + /* resrdis */ + mmio_write_32(DBSC_DBBCAMDIS, 0x00000001U); +} + +static void dbsc_regset_post(void) +{ + uint32_t slice, rdlat_max, rdlat_min; + uint32_t ch, cs; + uint32_t data_l; + uint32_t srx; + + rdlat_max = 0U; + rdlat_min = 0xffffU; + foreach_vch(ch) { + for (cs = 0U; cs < CS_CNT; cs++) { + if ((ch_have_this_cs[cs] & (1U << ch)) != 0U) { + for (slice = 0U; slice < SLICE_CNT; slice++) { + ddr_setval_s(ch, slice, + _reg_PHY_PER_CS_TRAINING_INDEX, + cs); + data_l = ddr_getval_s(ch, slice, + _reg_PHY_RDDQS_LATENCY_ADJUST); + if (data_l > rdlat_max) { + rdlat_max = data_l; + } + if (data_l < rdlat_min) { + rdlat_min = data_l; + } + } + } + } + } + + mmio_write_32(DBSC_DBTR(24), + ((rdlat_max + 2U) << 24) + + ((rdlat_max + 2U) << 16) + + mmio_read_32(DBSC_DBTR(24))); + + /* set ddr density information */ + foreach_ech(ch) { + for (cs = 0U; cs < CS_CNT; cs++) { + if (ddr_density[ch][cs] == 0xffU) { + mmio_write_32(DBSC_DBMEMCONF(ch, cs), 0x00U); + } else { + mmio_write_32(DBSC_DBMEMCONF(ch, cs), + DBMEMCONF_REGD(ddr_density[ch] + [cs])); + } + } + mmio_write_32(DBSC_DBMEMCONF(ch, 2), 0x00000000U); + mmio_write_32(DBSC_DBMEMCONF(ch, 3), 0x00000000U); + } + + mmio_write_32(DBSC_DBBUS0CNF1, 0x00000010U); + + /* set DBI */ + if (board_cnf->dbi_en != 0U) { + mmio_write_32(DBSC_DBDBICNT, 0x00000003U); + } + + /* set REFCYCLE */ + data_l = (get_refperiod()) * ddr_mbps / 2000U / ddr_mbpsdiv; + mmio_write_32(DBSC_DBRFCNF1, 0x00080000U | (data_l & 0x0000ffffU)); + mmio_write_32(DBSC_DBRFCNF2, 0x00010000U | DBSC_REFINTS); + +#if RCAR_REWT_TRAINING != 0 + /* Periodic-WriteDQ Training seeting */ + if ((prr_product == PRR_PRODUCT_M3) && + (prr_cut == PRR_PRODUCT_10)) { + /* G2M Ver.1.0 not support */ + } else { + /* G2M Ver.1.1 or later */ + mmio_write_32(DBSC_DBDFIPMSTRCNF, 0x00000000U); + + ddr_setval_ach_as(_reg_PHY_WDQLVL_PATT, 0x04U); + ddr_setval_ach_as(_reg_PHY_WDQLVL_QTR_DLY_STEP, 0x0FU); + ddr_setval_ach_as(_reg_PHY_WDQLVL_DLY_STEP, 0x50U); + ddr_setval_ach_as(_reg_PHY_WDQLVL_DQDM_SLV_DLY_START, 0x0300U); + + ddr_setval_ach(_reg_PI_WDQLVL_CS_MAP, + ddrtbl_getval(_cnf_DDR_PI_REGSET, + _reg_PI_WDQLVL_CS_MAP)); + ddr_setval_ach(_reg_PI_LONG_COUNT_MASK, 0x1fU); + ddr_setval_ach(_reg_PI_WDQLVL_VREF_EN, 0x00U); + ddr_setval_ach(_reg_PI_WDQLVL_ROTATE, 0x01U); + ddr_setval_ach(_reg_PI_TREF_F0, 0x0000U); + ddr_setval_ach(_reg_PI_TREF_F1, 0x0000U); + ddr_setval_ach(_reg_PI_TREF_F2, 0x0000U); + + if (prr_product == PRR_PRODUCT_M3) { + ddr_setval_ach(_reg_PI_WDQLVL_EN, 0x02U); + } else { + ddr_setval_ach(_reg_PI_WDQLVL_EN_F1, 0x02U); + } + ddr_setval_ach(_reg_PI_WDQLVL_PERIODIC, 0x01U); + + /* DFI_PHYMSTR_ACK , WTmode setting */ + /* DFI_PHYMSTR_ACK: WTmode =b'01 */ + mmio_write_32(DBSC_DBDFIPMSTRCNF, 0x00000011U); + } +#endif /* RCAR_REWT_TRAINING */ + /* periodic dram zqcal enable */ + mmio_write_32(DBSC_DBCALCNF, 0x01000010U); + + /* periodic phy ctrl update enable */ + if ((prr_product == PRR_PRODUCT_M3) && + (prr_cut < PRR_PRODUCT_30)) { + /* non : G2M Ver.1.x not support */ + } else { + mmio_write_32(DBSC_DBDFICUPDCNF, 0x28240001U); + } + +#ifdef DDR_BACKUPMODE + /* SRX */ + srx = 0x0A840001U; /* for All channels */ + if (ddr_backup == DRAM_BOOT_STATUS_WARM) { +#ifdef DDR_BACKUPMODE_HALF /* for Half channel(ch0, 1 only) */ + NOTICE("BL2: [DEBUG_MESS] DDR_BACKUPMODE_HALF\n"); + srx = 0x0A040001U; +#endif /* DDR_BACKUPMODE_HALF */ + send_dbcmd(srx); + } +#endif /* DDR_BACKUPMODE */ + + /* set Auto Refresh */ + mmio_write_32(DBSC_DBRFEN, 0x00000001U); + +#if RCAR_REWT_TRAINING != 0 + /* Periodic WriteDQ Traning */ + if ((prr_product == PRR_PRODUCT_M3) && + (prr_cut == PRR_PRODUCT_10)) { + /* non : G2M Ver.1.0 not support */ + } else { + /* G2M Ver.1.1 or later */ + ddr_setval_ach(_reg_PI_WDQLVL_INTERVAL, 0x0100U); + } +#endif /* RCAR_REWT_TRAINING */ + + /* dram access enable */ + mmio_write_32(DBSC_DBACEN, 0x00000001U); + + MSG_LF(__func__ "(done)"); +} + +/* DFI_INIT_START */ +static uint32_t dfi_init_start(void) +{ + uint32_t ch; + uint32_t phytrainingok; + uint32_t retry; + uint32_t data_l; + uint32_t ret = 0U; + const uint32_t RETRY_MAX = 0x10000U; + + ddr_setval_ach_as(_reg_PHY_DLL_RST_EN, 0x02U); + dsb_sev(); + ddrphy_regif_idle(); + + /* dll_rst negate */ + foreach_vch(ch) { + mmio_write_32(DBSC_DBPDCNT3(ch), 0x0000CF01U); + } + dsb_sev(); + + /* wait init_complete */ + phytrainingok = 0U; + retry = 0U; + while (retry++ < RETRY_MAX) { + foreach_vch(ch) { + data_l = mmio_read_32(DBSC_DBDFISTAT(ch)); + if (data_l & 0x00000001U) { + phytrainingok |= (1U << ch); + } + } + dsb_sev(); + if (phytrainingok == ddr_phyvalid) { + break; + } + if (retry % 256U == 0U) { + ddr_setval_ach_as(_reg_SC_PHY_RX_CAL_START, 0x01U); + } + } + + /* all ch ok? */ + if ((phytrainingok & ddr_phyvalid) != ddr_phyvalid) { + ret = 0xffU; + goto done; + } + + /* + * dbdficnt0: + * dfi_dram_clk_disable=0 + * dfi_frequency = 0 + * freq_ratio = 01 (2:1) + * init_start =0 + */ + foreach_vch(ch) { + mmio_write_32(DBSC_DBDFICNT(ch), 0x00000010U); + } + dsb_sev(); +done: + return ret; +} + +/* drivability setting : CMOS MODE ON/OFF */ +static void change_lpddr4_en(uint32_t mode) +{ + uint32_t ch; + uint32_t i; + uint32_t data_l; + const uint32_t _reg_PHY_PAD_DRIVE_X[3] = { + _reg_PHY_PAD_ADDR_DRIVE, + _reg_PHY_PAD_CLK_DRIVE, + _reg_PHY_PAD_CS_DRIVE + }; + + foreach_vch(ch) { + for (i = 0U; i < 3U; i++) { + data_l = ddr_getval(ch, _reg_PHY_PAD_DRIVE_X[i]); + if (mode != 0U) { + data_l |= (1U << 14); + } else { + data_l &= ~(1U << 14); + } + ddr_setval(ch, _reg_PHY_PAD_DRIVE_X[i], data_l); + } + } +} + +/* drivability setting */ +static uint32_t set_term_code(void) +{ + uint32_t i; + uint32_t ch, index; + uint32_t data_l; + uint32_t chip_id[2]; + uint32_t term_code; + uint32_t override; + + term_code = ddrtbl_getval(_cnf_DDR_PHY_ADR_G_REGSET, + _reg_PHY_PAD_DATA_TERM); + override = 0U; + for (i = 0U; i < 2U; i++) { + chip_id[i] = mmio_read_32(LIFEC_CHIPID(i)); + } + + index = 0U; + while (true) { + if (termcode_by_sample[index][0] == 0xffffffff) { + break; + } + if ((termcode_by_sample[index][0] == chip_id[0]) && + (termcode_by_sample[index][1] == chip_id[1])) { + term_code = termcode_by_sample[index][2]; + override = 1; + break; + } + index++; + } + + if (override != 0U) { + for (index = 0U; index < _reg_PHY_PAD_TERM_X_NUM; index++) { + data_l = + ddrtbl_getval(_cnf_DDR_PHY_ADR_G_REGSET, + _reg_PHY_PAD_TERM_X[index]); + data_l = (data_l & 0xfffe0000U) | term_code; + ddr_setval_ach(_reg_PHY_PAD_TERM_X[index], data_l); + } + } else if ((prr_product == PRR_PRODUCT_M3) && + (prr_cut == PRR_PRODUCT_10)) { + /* non */ + } else { + ddr_setval_ach(_reg_PHY_PAD_TERM_X[0], + (ddrtbl_getval(_cnf_DDR_PHY_ADR_G_REGSET, + _reg_PHY_PAD_TERM_X[0]) & 0xFFFE0000U)); + ddr_setval_ach(_reg_PHY_CAL_CLEAR_0, 0x01U); + ddr_setval_ach(_reg_PHY_CAL_START_0, 0x01U); + foreach_vch(ch) { + do { + data_l = + ddr_getval(ch, _reg_PHY_CAL_RESULT2_OBS_0); + } while (!(data_l & 0x00800000U)); + } + + /* G2M Ver.1.1 or later */ + foreach_vch(ch) { + for (index = 0U; index < _reg_PHY_PAD_TERM_X_NUM; + index++) { + data_l = ddr_getval(ch, _reg_PHY_PAD_TERM_X[index]); + ddr_setval(ch, _reg_PHY_PAD_TERM_X[index], + (data_l & 0xFFFE0FFFU) | 0x00015000U); + } + } + } + + ddr_padcal_tcompensate_getinit(override); + + return 0U; +} + +/* DDR mode register setting */ +static void ddr_register_set(void) +{ + int32_t fspwp; + uint32_t tmp; + + for (fspwp = 1; fspwp >= 0; fspwp--) { + /*MR13, fspwp */ + send_dbcmd(0x0e840d08U | ((2U - fspwp) << 6)); + + tmp = ddrtbl_getval(_cnf_DDR_PI_REGSET, + reg_pi_mr1_data_fx_csx[fspwp][0]); + send_dbcmd(0x0e840100U | tmp); + + tmp = ddrtbl_getval(_cnf_DDR_PI_REGSET, + reg_pi_mr2_data_fx_csx[fspwp][0]); + send_dbcmd(0x0e840200U | tmp); + + tmp = ddrtbl_getval(_cnf_DDR_PI_REGSET, + reg_pi_mr3_data_fx_csx[fspwp][0]); + send_dbcmd(0x0e840300U | tmp); + + tmp = ddrtbl_getval(_cnf_DDR_PI_REGSET, + reg_pi_mr11_data_fx_csx[fspwp][0]); + send_dbcmd(0x0e840b00U | tmp); + + tmp = ddrtbl_getval(_cnf_DDR_PI_REGSET, + reg_pi_mr12_data_fx_csx[fspwp][0]); + send_dbcmd(0x0e840c00U | tmp); + + tmp = ddrtbl_getval(_cnf_DDR_PI_REGSET, + reg_pi_mr14_data_fx_csx[fspwp][0]); + send_dbcmd(0x0e840e00U | tmp); + /* MR22 */ + send_dbcmd(0x0e841616U); + + /* ZQCAL start */ + send_dbcmd(0x0d84004FU); + + /* ZQLAT */ + send_dbcmd(0x0d840051U); + } + + /* MR13, fspwp */ + send_dbcmd(0x0e840d08U); +} + +/* Training handshake functions */ +static inline uint32_t wait_freqchgreq(uint32_t assert) +{ + uint32_t data_l; + uint32_t count; + uint32_t ch; + + count = 100000U; + + if (assert != 0U) { + do { + data_l = 1U; + foreach_vch(ch) { + data_l &= mmio_read_32(DBSC_DBPDSTAT(ch)); + } + count = count - 1U; + } while (((data_l & 0x01U) != 0x01U) && (count != 0U)); + } else { + do { + data_l = 0U; + foreach_vch(ch) { + data_l |= mmio_read_32(DBSC_DBPDSTAT(ch)); + } + count = count - 1U; + } while (((data_l & 0x01U) != 0x00U) && (count != 0U)); + } + + return (count == 0U); +} + +static inline void set_freqchgack(uint32_t assert) +{ + uint32_t ch; + uint32_t data_l; + + if (assert != 0U) { + data_l = 0x0CF20000U; + } else { + data_l = 0x00000000U; + } + + foreach_vch(ch) { + mmio_write_32(DBSC_DBPDCNT2(ch), data_l); + } +} + +static inline void set_dfifrequency(uint32_t freq) +{ + uint32_t ch; + + foreach_vch(ch) { + mmio_clrsetbits_32(DBSC_DBDFICNT(ch), 0x1fU << 24, freq << 24); + } + dsb_sev(); +} + +static uint32_t pll3_freq(uint32_t on) +{ + uint32_t timeout; + + timeout = wait_freqchgreq(1U); + + if (timeout != 0U) { + return 1U; + } + + pll3_control(on); + set_dfifrequency(on); + + set_freqchgack(1U); + timeout = wait_freqchgreq(0U); + set_freqchgack(0U); + + if (timeout != 0U) { + FATAL_MSG("BL2: Time out[2]\n"); + return 1U; + } + + return 0U; +} + +/* update dly */ +static void update_dly(void) +{ + ddr_setval_ach(_reg_SC_PHY_MANUAL_UPDATE, 0x01U); + ddr_setval_ach(_reg_PHY_ADRCTL_MANUAL_UPDATE, 0x01U); +} + +/* training by pi */ +static uint32_t pi_training_go(void) +{ + uint32_t flag; + uint32_t data_l; + uint32_t retry; + const uint32_t RETRY_MAX = 4096U * 16U; + uint32_t ch; + uint32_t mst_ch; + uint32_t cur_frq; + uint32_t complete; + uint32_t frqchg_req; + + /* pi_start */ + ddr_setval_ach(_reg_PI_START, 0x01U); + foreach_vch(ch) { + ddr_getval(ch, _reg_PI_INT_STATUS); + } + + /* set dfi_phymstr_ack = 1 */ + mmio_write_32(DBSC_DBDFIPMSTRCNF, 0x00000001U); + dsb_sev(); + + /* wait pi_int_status[0] */ + mst_ch = 0U; + flag = 0U; + complete = 0U; + cur_frq = 0U; + for (retry = 0U; retry < RETRY_MAX; retry++) { + frqchg_req = mmio_read_32(DBSC_DBPDSTAT(mst_ch)) & 0x01; + + if (frqchg_req != 0U) { + if (cur_frq != 0U) { + /* Low frequency */ + flag = pll3_freq(0U); + cur_frq = 0U; + } else { + /* High frequency */ + flag = pll3_freq(1U); + cur_frq = 1U; + } + if (flag != 0U) { + break; + } + } else { + if (cur_frq != 0U) { + foreach_vch(ch) { + if ((complete & (1U << ch)) != 0U) { + continue; + } + data_l = ddr_getval(ch, _reg_PI_INT_STATUS); + if ((data_l & 0x01U) != 0U) { + complete |= (1U << ch); + } + } + if (complete == ddr_phyvalid) { + break; + } + } + } + } + foreach_vch(ch) { + /* dummy read */ + data_l = ddr_getval_s(ch, 0U, _reg_PHY_CAL_RESULT2_OBS_0); + data_l = ddr_getval(ch, _reg_PI_INT_STATUS); + ddr_setval(ch, _reg_PI_INT_ACK, data_l); + } + if (ddrphy_regif_chk() != 0U) { + complete = 0xfdU; + } + return complete; +} + +/* Initialize DDR */ +static uint32_t init_ddr(void) +{ + uint32_t i; + uint32_t data_l; + uint32_t phytrainingok; + uint32_t ch, slice; + uint32_t index; + uint32_t err; + int16_t adj; + + MSG_LF(__func__ ":0\n"); + + /* unlock phy */ + /* Unlock DDRPHY register(AGAIN) */ + foreach_vch(ch) { + mmio_write_32(DBSC_DBPDLK(ch), 0x0000A55AU); + } + dsb_sev(); + + reg_ddrphy_write_a(0x00001010U, 0x00000001U); + /* DBSC register pre-setting */ + dbsc_regset_pre(); + + /* load ddrphy registers */ + ddrtbl_load(); + + /* configure ddrphy registers */ + ddr_config(); + + /* dfi_reset assert */ + foreach_vch(ch) { + mmio_write_32(DBSC_DBPDCNT0(ch), 0x01U); + } + dsb_sev(); + + /* dbsc register set */ + dbsc_regset(); + MSG_LF(__func__ ":1\n"); + + /* dfi_reset negate */ + foreach_vch(ch) { + mmio_write_32(DBSC_DBPDCNT0(ch), 0x00U); + } + dsb_sev(); + + /* dfi_init_start (start ddrphy) */ + err = dfi_init_start(); + if (err != 0U) { + return INITDRAM_ERR_I; + } + MSG_LF(__func__ ":2\n"); + + /* ddr backupmode end */ +#ifdef DDR_BACKUPMODE + if (ddr_backup != 0U) { + NOTICE("BL2: [WARM_BOOT]\n"); + } else { + NOTICE("BL2: [COLD_BOOT]\n"); + } +#endif + MSG_LF(__func__ ":3\n"); + + /* override term code after dfi_init_complete */ + err = set_term_code(); + if (err != 0U) { + return INITDRAM_ERR_I; + } + MSG_LF(__func__ ":4\n"); + + /* rx offset calibration */ + if (prr_cut > PRR_PRODUCT_11) { + err = rx_offset_cal_hw(); + } else { + err = rx_offset_cal(); + } + if (err != 0U) { + return INITDRAM_ERR_O; + } + MSG_LF(__func__ ":5\n"); + + /* Dummy PDE */ + send_dbcmd(0x08840000U); + + /* PDX */ + send_dbcmd(0x08840001U); + + /* check register i/f is alive */ + err = ddrphy_regif_chk(); + if (err != 0U) { + return INITDRAM_ERR_O; + } + MSG_LF(__func__ ":6\n"); + + /* phy initialize end */ + + /* setup DDR mode registers */ + /* CMOS MODE */ + change_lpddr4_en(0); + + /* MRS */ + ddr_register_set(); + + /* Thermal sensor setting */ + /* THCTR Bit6: PONM=0 , Bit0: THSST=1 */ + data_l = (mmio_read_32(THS1_THCTR) & 0xFFFFFFBFU) | 0x00000001U; + mmio_write_32(THS1_THCTR, data_l); + + /* LPDDR4 MODE */ + change_lpddr4_en(1); + + MSG_LF(__func__ ":7\n"); + + /* mask CS_MAP if RANKx is not found */ + foreach_vch(ch) { + data_l = ddr_getval(ch, _reg_PI_CS_MAP); + if ((ch_have_this_cs[1] & (1U << ch)) == 0U) { + data_l = data_l & 0x05U; + } + ddr_setval(ch, _reg_PI_CS_MAP, data_l); + } + + /* exec pi_training */ + reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_FREQ_SEL_MULTICAST_EN), + BIT(ddr_regdef_lsb(_reg_PHY_FREQ_SEL_MULTICAST_EN))); + ddr_setval_ach_as(_reg_PHY_PER_CS_TRAINING_MULTICAST_EN, 0x00U); + + foreach_vch(ch) { + for (slice = 0U; slice < SLICE_CNT; slice++) { + ddr_setval_s(ch, slice, + _reg_PHY_PER_CS_TRAINING_EN, + ((ch_have_this_cs[1]) >> ch) & 0x01U); + } + } + + phytrainingok = pi_training_go(); + + if (ddr_phyvalid != (phytrainingok & ddr_phyvalid)) { + return INITDRAM_ERR_T | phytrainingok; + } + + MSG_LF(__func__ ":8\n"); + + /* CACS DLY ADJUST */ + data_l = board_cnf->cacs_dly + (uint32_t)_f_scale_adj(board_cnf->cacs_dly_adj); + foreach_vch(ch) { + for (i = 0U; i < _reg_PHY_CLK_CACS_SLAVE_DELAY_X_NUM; i++) { + adj = _f_scale_adj(board_cnf->ch[ch].cacs_adj[i]); + ddr_setval(ch, _reg_PHY_CLK_CACS_SLAVE_DELAY_X[i], + data_l + (uint32_t)adj); + } + + if (ddr_phycaslice == 1U) { + for (i = 0U; i < 6U; i++) { + index = i + _reg_PHY_CLK_CACS_SLAVE_DELAY_X_NUM; + adj = _f_scale_adj(board_cnf->ch[ch].cacs_adj[index]); + ddr_setval_s(ch, 2U, + _reg_PHY_CLK_CACS_SLAVE_DELAY_X[i], + data_l + (uint32_t)adj); + } + } + } + + update_dly(); + MSG_LF(__func__ ":9\n"); + + /* Adjust write path latency */ + if (ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET, _reg_PHY_WRITE_PATH_LAT_ADD) != 0U) { + adjust_wpath_latency(); + } + + /* RDQLVL Training */ + if (ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET, _reg_PHY_IE_MODE) == 0U) { + ddr_setval_ach_as(_reg_PHY_IE_MODE, 0x01U); + } + + err = rdqdm_man(); + + if (ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET, _reg_PHY_IE_MODE) == 0U) { + ddr_setval_ach_as(_reg_PHY_IE_MODE, 0x00U); + } + + if (err != 0U) { + return INITDRAM_ERR_T; + } + update_dly(); + MSG_LF(__func__ ":10\n"); + + /* WDQLVL Training */ + err = wdqdm_man(); + if (err != 0U) { + return INITDRAM_ERR_T; + } + update_dly(); + MSG_LF(__func__ ":11\n"); + + dbsc_regset_post(); + MSG_LF(__func__ ":12\n"); + + return phytrainingok; +} + +/* SW LEVELING COMMON */ +static uint32_t swlvl1(uint32_t ddr_csn, uint32_t reg_cs, uint32_t reg_kick) +{ + const uint32_t RETRY_MAX = 0x1000U; + uint32_t ch, data_l; + uint32_t waiting; + uint32_t retry; + uint32_t err = 0U; + + /* set EXIT -> OP_DONE is cleared */ + ddr_setval_ach(_reg_PI_SWLVL_EXIT, 0x01); + + /* kick */ + foreach_vch(ch) { + if ((ch_have_this_cs[ddr_csn % 2U] & (1U << ch)) != 0U) { + ddr_setval(ch, reg_cs, ddr_csn); + ddr_setval(ch, reg_kick, 0x01U); + } + } + foreach_vch(ch) { + /*PREPARE ADDR REGISTER (for SWLVL_OP_DONE) */ + ddr_getval(ch, _reg_PI_SWLVL_OP_DONE); + } + waiting = ch_have_this_cs[ddr_csn % 2U]; + dsb_sev(); + retry = RETRY_MAX; + do { + foreach_vch(ch) { + if ((waiting & (1U << ch)) == 0U) { + continue; + } + data_l = ddr_getval(ch, _reg_PI_SWLVL_OP_DONE); + if ((data_l & 0x01U) != 0U) { + waiting &= ~(1U << ch); + } + } + retry--; + } while ((waiting != 0U) && (retry > 0U)); + if (retry == 0U) { + err = 1U; + } + + dsb_sev(); + /* set EXIT -> OP_DONE is cleared */ + ddr_setval_ach(_reg_PI_SWLVL_EXIT, 0x01U); + dsb_sev(); + + return err; +} + +/* WDQ TRAINING */ +#ifndef DDR_FAST_INIT +static void wdqdm_clr1(uint32_t ch, uint32_t ddr_csn) +{ + uint32_t cs, slice; + uint32_t data_l; + int32_t i, k; + + /* clr of training results buffer */ + cs = ddr_csn % 2U; + data_l = board_cnf->dqdm_dly_w; + for (slice = 0U; slice < SLICE_CNT; slice++) { + k = (board_cnf->ch[ch].dqs_swap >> (4 * slice)) & 0x0f; + if (((k >= 2) && (ddr_csn < 2)) || ((k < 2) && (ddr_csn >= 2))) { + continue; + } + + for (i = 0; i <= 8; i++) { + if ((ch_have_this_cs[CS_CNT - 1 - cs] & (1U << ch)) != 0U) { + wdqdm_dly[ch][cs][slice][i] = + wdqdm_dly[ch][CS_CNT - 1 - cs][slice][i]; + } else { + wdqdm_dly[ch][cs][slice][i] = data_l; + } + wdqdm_le[ch][cs][slice][i] = 0U; + wdqdm_te[ch][cs][slice][i] = 0U; + } + wdqdm_st[ch][cs][slice] = 0U; + wdqdm_win[ch][cs][slice] = 0U; + } +} + +static uint32_t wdqdm_ana1(uint32_t ch, uint32_t ddr_csn) +{ + const uint32_t _par_WDQLVL_RETRY_THRES = 0x7c0U; + uint32_t cs, slice; + uint32_t data_l; + int32_t min_win; + int32_t i, k; + uint32_t err; + int32_t win; + int8_t _adj; + int16_t adj; + uint32_t dq; + + /* analysis of training results */ + err = 0U; + for (slice = 0U; slice < SLICE_CNT; slice += 1U) { + k = (board_cnf->ch[ch].dqs_swap >> (4 * slice)) & 0x0f; + if (((k >= 2) && (ddr_csn < 2)) || ((k < 2) && (ddr_csn >= 2))) { + continue; + } + + cs = ddr_csn % 2U; + ddr_setval_s(ch, slice, _reg_PHY_PER_CS_TRAINING_INDEX, cs); + for (i = 0; i < 9; i++) { + dq = slice * 8U + i; + if (i == 8) { + _adj = board_cnf->ch[ch].dm_adj_w[slice]; + } else { + _adj = board_cnf->ch[ch].dq_adj_w[dq]; + } + adj = _f_scale_adj(_adj); + + data_l = + ddr_getval_s(ch, slice, + _reg_PHY_CLK_WRX_SLAVE_DELAY[i]) + adj; + ddr_setval_s(ch, slice, _reg_PHY_CLK_WRX_SLAVE_DELAY[i], + data_l); + wdqdm_dly[ch][cs][slice][i] = data_l; + } + ddr_setval_s(ch, slice, _reg_PHY_PER_CS_TRAINING_EN, 0x00); + data_l = ddr_getval_s(ch, slice, _reg_PHY_WDQLVL_STATUS_OBS); + wdqdm_st[ch][cs][slice] = data_l; + min_win = INT_LEAST32_MAX; + for (i = 0; i <= 8; i++) { + ddr_setval_s(ch, slice, _reg_PHY_WDQLVL_DQDM_OBS_SELECT, + i); + + data_l = + ddr_getval_s(ch, slice, + _reg_PHY_WDQLVL_DQDM_TE_DLY_OBS); + wdqdm_te[ch][cs][slice][i] = data_l; + data_l = + ddr_getval_s(ch, slice, + _reg_PHY_WDQLVL_DQDM_LE_DLY_OBS); + wdqdm_le[ch][cs][slice][i] = data_l; + win = (int32_t)wdqdm_te[ch][cs][slice][i] - + wdqdm_le[ch][cs][slice][i]; + if (min_win > win) { + min_win = win; + } + if (data_l >= _par_WDQLVL_RETRY_THRES) { + err = 2; + } + } + wdqdm_win[ch][cs][slice] = min_win; + ddr_setval_s(ch, slice, _reg_PHY_PER_CS_TRAINING_EN, + ((ch_have_this_cs[1]) >> ch) & 0x01); + } + return err; +} +#endif/* DDR_FAST_INIT */ + +static void wdqdm_cp(uint32_t ddr_csn, uint32_t restore) +{ + uint32_t tgt_cs, src_cs; + uint32_t ch, slice; + uint32_t tmp_r; + uint32_t i; + + /* copy of training results */ + foreach_vch(ch) { + for (tgt_cs = 0U; tgt_cs < CS_CNT; tgt_cs++) { + for (slice = 0U; slice < SLICE_CNT; slice++) { + ddr_setval_s(ch, slice, + _reg_PHY_PER_CS_TRAINING_INDEX, + tgt_cs); + src_cs = ddr_csn % 2U; + if ((ch_have_this_cs[1] & (1U << ch)) == 0U) { + src_cs = 0U; + } + for (i = 0U; i <= 4U; i += 4U) { + if (restore != 0U) { + tmp_r = rdqdm_dly[ch][tgt_cs][slice][i]; + } else { + tmp_r = rdqdm_dly[ch][src_cs][slice][i]; + } + + ddr_setval_s(ch, slice, + _reg_PHY_RDDQS_X_RISE_SLAVE_DELAY[i], + tmp_r); + } + } + } + } +} + +static uint32_t wdqdm_man1(void) +{ + uint32_t mr14_csab0_bak[DRAM_CH_CNT]; + uint32_t ch, cs, ddr_csn; + uint32_t data_l; + uint32_t err = 0U; +#ifndef DDR_FAST_INIT + uint32_t err_flg = 0U; +#endif/* DDR_FAST_INIT */ + + /* CLEAR PREV RESULT */ + for (cs = 0U; cs < CS_CNT; cs++) { + ddr_setval_ach_as(_reg_PHY_PER_CS_TRAINING_INDEX, cs); + ddr_setval_ach_as(_reg_PHY_WDQLVL_CLR_PREV_RESULTS, 0x01U); + } + ddrphy_regif_idle(); + + for (ddr_csn = 0U; ddr_csn < CSAB_CNT; ddr_csn++) { + if (((prr_product == PRR_PRODUCT_M3) && + (prr_cut == PRR_PRODUCT_10))) { + wdqdm_cp(ddr_csn, 0U); + } + + foreach_vch(ch) { + data_l = ddr_getval(ch, reg_pi_mr14_data_fx_csx[1][ddr_csn]); + ddr_setval(ch, reg_pi_mr14_data_fx_csx[1][0], data_l); + } + + /* KICK WDQLVL */ + err = swlvl1(ddr_csn, _reg_PI_WDQLVL_CS, _reg_PI_WDQLVL_REQ); + if (err != 0U) { + goto err_exit; + } + + if (ddr_csn == 0U) { + foreach_vch(ch) { + mr14_csab0_bak[ch] = ddr_getval(ch, + reg_pi_mr14_data_fx_csx[1][0]); + } + } else { + foreach_vch(ch) { + ddr_setval(ch, reg_pi_mr14_data_fx_csx[1][0], + mr14_csab0_bak[ch]); + } + } +#ifndef DDR_FAST_INIT + foreach_vch(ch) { + if ((ch_have_this_cs[ddr_csn % 2U] & (1U << ch)) == 0U) { + wdqdm_clr1(ch, ddr_csn); + continue; + } + err = wdqdm_ana1(ch, ddr_csn); + if (err != 0U) { + err_flg |= (1U << (ddr_csn * 4U + ch)); + } + ddrphy_regif_idle(); + } +#endif/* DDR_FAST_INIT */ + } +err_exit: +#ifndef DDR_FAST_INIT + err |= err_flg; +#endif/* DDR_FAST_INIT */ + + return err; +} + +static uint32_t wdqdm_man(void) +{ + uint32_t datal, ch, ddr_csn, mr14_bkup[4][4]; + const uint32_t retry_max = 0x10U; + uint32_t err, retry_cnt; + + datal = RL + js2[js2_tdqsck] + (16U / 2U) + 1U - WL + 2U + 2U + 19U; + if ((mmio_read_32(DBSC_DBTR(11)) & 0xFF) > datal) { + datal = mmio_read_32(DBSC_DBTR(11)) & 0xFF; + } + ddr_setval_ach(_reg_PI_TDFI_WDQLVL_RW, datal); + + ddr_setval_ach(_reg_PI_TDFI_WDQLVL_WR, + (mmio_read_32(DBSC_DBTR(12)) & 0xFF) + 10); + + ddr_setval_ach(_reg_PI_TRFC_F0, mmio_read_32(DBSC_DBTR(13)) & 0x1FF); + ddr_setval_ach(_reg_PI_TRFC_F1, mmio_read_32(DBSC_DBTR(13)) & 0x1FF); + + retry_cnt = 0U; + err = 0U; + do { + ddr_setval_ach(_reg_PI_WDQLVL_VREF_EN, 0x01); + ddr_setval_ach(_reg_PI_WDQLVL_VREF_NORMAL_STEPSIZE, 0x01); + ddr_setval_ach(_reg_PI_WDQLVL_VREF_DELTA, 0x0C); + dsb_sev(); + err = wdqdm_man1(); + foreach_vch(ch) { + for (ddr_csn = 0U; ddr_csn < CSAB_CNT; ddr_csn++) { + mr14_bkup[ch][ddr_csn] = + ddr_getval(ch, reg_pi_mr14_data_fx_csx + [1][ddr_csn]); + dsb_sev(); + } + } + + ddr_setval_ach(_reg_PI_WDQLVL_VREF_DELTA, 0x04); + + pvtcode_update(); + err = wdqdm_man1(); + foreach_vch(ch) { + for (ddr_csn = 0U; ddr_csn < CSAB_CNT; ddr_csn++) { + mr14_bkup[ch][ddr_csn] = + (mr14_bkup[ch][ddr_csn] + + ddr_getval(ch, reg_pi_mr14_data_fx_csx + [1][ddr_csn])) / 2U; + ddr_setval(ch, + reg_pi_mr14_data_fx_csx[1] + [ddr_csn], + mr14_bkup[ch][ddr_csn]); + } + } + + ddr_setval_ach(_reg_PI_WDQLVL_VREF_NORMAL_STEPSIZE, 0x0U); + ddr_setval_ach(_reg_PI_WDQLVL_VREF_DELTA, 0x0U); + ddr_setval_ach(_reg_PI_WDQLVL_VREF_INITIAL_START_POINT, 0x0U); + ddr_setval_ach(_reg_PI_WDQLVL_VREF_INITIAL_STOP_POINT, 0x0U); + ddr_setval_ach(_reg_PI_WDQLVL_VREF_INITIAL_STEPSIZE, 0x0U); + + pvtcode_update2(); + err = wdqdm_man1(); + ddr_setval_ach(_reg_PI_WDQLVL_VREF_EN, 0x0U); + + } while ((err != 0U) && (++retry_cnt < retry_max)); + + if (prr_product == PRR_PRODUCT_M3 && prr_cut <= PRR_PRODUCT_10) { + wdqdm_cp(0U, 1U); + } + + return (retry_cnt >= retry_max); +} + +/* RDQ TRAINING */ +#ifndef DDR_FAST_INIT +static void rdqdm_clr1(uint32_t ch, uint32_t ddr_csn) +{ + uint32_t cs, slice; + uint32_t data_l; + int32_t i, k; + + /* clr of training results buffer */ + cs = ddr_csn % 2U; + data_l = board_cnf->dqdm_dly_r; + for (slice = 0U; slice < SLICE_CNT; slice++) { + k = (board_cnf->ch[ch].dqs_swap >> (4 * slice)) & 0x0f; + if (((k >= 2) && (ddr_csn < 2)) || ((k < 2) && (ddr_csn >= 2))) { + continue; + } + + for (i = 0; i <= 8; i++) { + if ((ch_have_this_cs[CS_CNT - 1 - cs] & (1U << ch)) != 0U) { + rdqdm_dly[ch][cs][slice][i] = + rdqdm_dly[ch][CS_CNT - 1 - cs][slice][i]; + rdqdm_dly[ch][cs][slice + SLICE_CNT][i] = + rdqdm_dly[ch][CS_CNT - 1 - cs][slice + SLICE_CNT][i]; + } else { + rdqdm_dly[ch][cs][slice][i] = data_l; + rdqdm_dly[ch][cs][slice + SLICE_CNT][i] = data_l; + } + rdqdm_le[ch][cs][slice][i] = 0U; + rdqdm_le[ch][cs][slice + SLICE_CNT][i] = 0U; + rdqdm_te[ch][cs][slice][i] = 0U; + rdqdm_te[ch][cs][slice + SLICE_CNT][i] = 0U; + rdqdm_nw[ch][cs][slice][i] = 0U; + rdqdm_nw[ch][cs][slice + SLICE_CNT][i] = 0U; + } + rdqdm_st[ch][cs][slice] = 0U; + rdqdm_win[ch][cs][slice] = 0U; + } +} + +static uint32_t rdqdm_ana1(uint32_t ch, uint32_t ddr_csn) +{ + uint32_t rdq_status_obs_select; + uint32_t cs, slice; + uint32_t data_l; + uint32_t err; + uint32_t dq; + int32_t min_win; + int8_t _adj; + int16_t adj; + int32_t min_win; + int32_t win; + int32_t i, k; + + /* analysis of training results */ + err = 0U; + for (slice = 0U; slice < SLICE_CNT; slice++) { + k = (board_cnf->ch[ch].dqs_swap >> (4 * slice)) & 0x0f; + if (((k >= 2) && (ddr_csn < 2)) || ((k < 2) && (ddr_csn >= 2))) { + continue; + } + + cs = ddr_csn % 2U; + ddr_setval_s(ch, slice, _reg_PHY_PER_CS_TRAINING_INDEX, cs); + ddrphy_regif_idle(); + + ddr_getval_s(ch, slice, _reg_PHY_PER_CS_TRAINING_INDEX); + ddrphy_regif_idle(); + + for (i = 0; i <= 8; i++) { + dq = slice * 8 + i; + if (i == 8) { + _adj = board_cnf->ch[ch].dm_adj_r[slice]; + } else { + _adj = board_cnf->ch[ch].dq_adj_r[dq]; + } + + adj = _f_scale_adj(_adj); + + data_l = ddr_getval_s(ch, slice, + _reg_PHY_RDDQS_X_RISE_SLAVE_DELAY[i]) + adj; + ddr_setval_s(ch, slice, + _reg_PHY_RDDQS_X_RISE_SLAVE_DELAY[i], + data_l); + rdqdm_dly[ch][cs][slice][i] = data_l; + + data_l = ddr_getval_s(ch, slice, + _reg_PHY_RDDQS_X_FALL_SLAVE_DELAY[i]) + adj; + ddr_setval_s(ch, slice, + _reg_PHY_RDDQS_X_FALL_SLAVE_DELAY[i], + data_l); + rdqdm_dly[ch][cs][slice + SLICE_CNT][i] = data_l; + } + min_win = INT_LEAST32_MAX; + for (i = 0; i <= 8; i++) { + data_l = + ddr_getval_s(ch, slice, _reg_PHY_RDLVL_STATUS_OBS); + rdqdm_st[ch][cs][slice] = data_l; + rdqdm_st[ch][cs][slice + SLICE_CNT] = data_l; + /* k : rise/fall */ + for (k = 0; k < 2; k++) { + if (i == 8) { + rdq_status_obs_select = 16 + 8 * k; + } else { + rdq_status_obs_select = i + k * 8; + } + ddr_setval_s(ch, slice, + _reg_PHY_RDLVL_RDDQS_DQ_OBS_SELECT, + rdq_status_obs_select); + + data_l = + ddr_getval_s(ch, slice, + _reg_PHY_RDLVL_RDDQS_DQ_LE_DLY_OBS); + rdqdm_le[ch][cs][slice + SLICE_CNT * k][i] = data_l; + + data_l = + ddr_getval_s(ch, slice, + _reg_PHY_RDLVL_RDDQS_DQ_TE_DLY_OBS); + rdqdm_te[ch][cs][slice + SLICE_CNT * k][i] = data_l; + + data_l = + ddr_getval_s(ch, slice, + _reg_PHY_RDLVL_RDDQS_DQ_NUM_WINDOWS_OBS); + rdqdm_nw[ch][cs][slice + SLICE_CNT * k][i] = data_l; + + win = + (int32_t)rdqdm_te[ch][cs][slice + + SLICE_CNT * + k][i] - + rdqdm_le[ch][cs][slice + SLICE_CNT * k][i]; + if (i != 8) { + if (min_win > win) { + min_win = win; + } + } + } + } + rdqdm_win[ch][cs][slice] = min_win; + if (min_win <= 0) { + err = 2; + } + } + return err; +} +#else /* DDR_FAST_INIT */ +static void rdqdm_man1_set(uint32_t ddr_csn, uint32_t ch, uint32_t slice) +{ + uint32_t i, adj, data_l; + + for (i = 0U; i <= 8U; i++) { + if (i == 8U) { + adj = _f_scale_adj(board_cnf->ch[ch].dm_adj_r[slice]); + } else { + adj = _f_scale_adj(board_cnf->ch[ch].dq_adj_r[slice * 8U + i]); + } + ddr_setval_s(ch, slice, _reg_PHY_PER_CS_TRAINING_INDEX, ddr_csn); + data_l = ddr_getval_s(ch, slice, _reg_PHY_RDDQS_X_RISE_SLAVE_DELAY[i]) + adj; + ddr_setval_s(ch, slice, _reg_PHY_RDDQS_X_RISE_SLAVE_DELAY[i], data_l); + rdqdm_dly[ch][ddr_csn][slice][i] = data_l; + rdqdm_dly[ch][ddr_csn | 1U][slice][i] = data_l; + + data_l = ddr_getval_s(ch, slice, _reg_PHY_RDDQS_X_FALL_SLAVE_DELAY[i]) + adj; + ddr_setval_s(ch, slice, _reg_PHY_RDDQS_X_FALL_SLAVE_DELAY[i], data_l); + rdqdm_dly[ch][ddr_csn][slice + SLICE_CNT][i] = data_l; + rdqdm_dly[ch][ddr_csn | 1U][slice + SLICE_CNT][i] = data_l; + } +} +#endif /* DDR_FAST_INIT */ + +static uint32_t rdqdm_man1(void) +{ + uint32_t ch; + uint32_t ddr_csn; + uint32_t val; +#ifdef DDR_FAST_INIT + uint32_t slice; +#endif/* DDR_FAST_INIT */ + uint32_t err; + + /* manual execution of training */ + err = 0U; + + for (ddr_csn = 0U; ddr_csn < CSAB_CNT; ddr_csn++) { + /* KICK RDQLVL */ + err = swlvl1(ddr_csn, _reg_PI_RDLVL_CS, _reg_PI_RDLVL_REQ); + if (err != 0U) { + goto err_exit; + } +#ifndef DDR_FAST_INIT + foreach_vch(ch) { + if ((ch_have_this_cs[ddr_csn % 2] & (1U << ch)) == 0U) { + rdqdm_clr1(ch, ddr_csn); + ddrphy_regif_idle(); + continue; + } + err = rdqdm_ana1(ch, ddr_csn); + ddrphy_regif_idle(); + if (err != 0U) { + goto err_exit; + } + } +#else/* DDR_FAST_INIT */ + foreach_vch(ch) { + if ((ch_have_this_cs[ddr_csn] & (1U << ch)) != 0U) { + for (slice = 0U; slice < SLICE_CNT; slice++) { + val = ddr_getval_s(ch, slice, _reg_PHY_RDLVL_STATUS_OBS); + if (val != 0x0D00FFFFU) { + err = (1U << ch) | (0x10U << slice); + goto err_exit; + } + } + } + if ((prr_product == PRR_PRODUCT_M3) && + (prr_cut <= PRR_PRODUCT_10)) { + for (slice = 0U; slice < SLICE_CNT; slice++) { + rdqdm_man1_set(ddr_csn, ch, slice); + } + } + } + ddrphy_regif_idle(); + +#endif/* DDR_FAST_INIT */ + } + +err_exit: + return err; +} + +static uint32_t rdqdm_man(void) +{ + uint32_t err, retry_cnt; + const uint32_t retry_max = 0x01U; + + ddr_setval_ach_as(_reg_PHY_DQ_TSEL_ENABLE, + 0x00000004U | ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET, + _reg_PHY_DQ_TSEL_ENABLE)); + ddr_setval_ach_as(_reg_PHY_DQS_TSEL_ENABLE, + 0x00000004U | ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET, + _reg_PHY_DQS_TSEL_ENABLE)); + ddr_setval_ach_as(_reg_PHY_DQ_TSEL_SELECT, + 0xFF0FFFFFU & ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET, + _reg_PHY_DQ_TSEL_SELECT)); + ddr_setval_ach_as(_reg_PHY_DQS_TSEL_SELECT, + 0xFF0FFFFFU & ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET, + _reg_PHY_DQS_TSEL_SELECT)); + + retry_cnt = 0U; + do { + err = rdqdm_man1(); + ddrphy_regif_idle(); + } while ((err != 0U) && (++retry_cnt < retry_max)); + ddr_setval_ach_as(_reg_PHY_DQ_TSEL_ENABLE, + ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET, + _reg_PHY_DQ_TSEL_ENABLE)); + ddr_setval_ach_as(_reg_PHY_DQS_TSEL_ENABLE, + ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET, + _reg_PHY_DQS_TSEL_ENABLE)); + ddr_setval_ach_as(_reg_PHY_DQ_TSEL_SELECT, + ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET, + _reg_PHY_DQ_TSEL_SELECT)); + ddr_setval_ach_as(_reg_PHY_DQS_TSEL_SELECT, + ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET, + _reg_PHY_DQS_TSEL_SELECT)); + + return (retry_cnt >= retry_max); +} + +/* rx offset calibration */ +static int32_t _find_change(uint64_t val, uint32_t dir) +{ + int32_t i; + uint32_t startval; + uint32_t curval; + const int32_t VAL_END = 0x3fU; + + if (dir == 0U) { + startval = (val & 0x01U); + for (i = 1; i <= VAL_END; i++) { + curval = (val >> i) & 0x01U; + if (curval != startval) { + return i; + } + } + return VAL_END; + } + + startval = (val >> dir) & 0x01U; + for (i = (int32_t)dir - 1; i >= 0; i--) { + curval = (val >> i) & 0x01U; + if (curval != startval) { + return i; + } + } + + return 0; +} + +static uint32_t _rx_offset_cal_updn(uint32_t code) +{ + const uint32_t CODE_MAX = 0x40U; + uint32_t tmp; + + if (code == 0U) { + tmp = (1U << 6) | (CODE_MAX - 1U); + } else { + tmp = (code << 6) | (CODE_MAX - code); + } + + return tmp; +} + +static uint32_t rx_offset_cal(void) +{ + uint32_t index; + uint32_t code; + const uint32_t CODE_MAX = 0x40U; + const uint32_t CODE_STEP = 2U; + uint32_t ch, slice; + uint32_t tmp; + uint32_t tmp_ach_as[DRAM_CH_CNT][SLICE_CNT]; + uint64_t val[DRAM_CH_CNT][SLICE_CNT][_reg_PHY_RX_CAL_X_NUM]; + uint64_t tmpval; + int32_t lsb, msb; + + ddr_setval_ach_as(_reg_PHY_RX_CAL_OVERRIDE, 0x01); + foreach_vch(ch) { + for (slice = 0U; slice < SLICE_CNT; slice++) { + for (index = 0U; index < _reg_PHY_RX_CAL_X_NUM; index++) { + val[ch][slice][index] = 0U; + } + } + } + + for (code = 0U; code < CODE_MAX / CODE_STEP; code++) { + tmp = _rx_offset_cal_updn(code * CODE_STEP); + for (index = 0U; index < _reg_PHY_RX_CAL_X_NUM; index++) { + ddr_setval_ach_as(_reg_PHY_RX_CAL_X[index], tmp); + } + dsb_sev(); + ddr_getval_ach_as(_reg_PHY_RX_CAL_OBS, (uint32_t *)tmp_ach_as); + + foreach_vch(ch) { + for (slice = 0U; slice < SLICE_CNT; slice++) { + tmp = tmp_ach_as[ch][slice]; + for (index = 0U; index < _reg_PHY_RX_CAL_X_NUM; + index++) { + if ((tmp & (1U << index)) != 0U) { + val[ch][slice][index] |= + (1ULL << code); + } else { + val[ch][slice][index] &= + ~(1ULL << code); + } + } + } + } + } + foreach_vch(ch) { + for (slice = 0U; slice < SLICE_CNT; slice++) { + for (index = 0U; index < _reg_PHY_RX_CAL_X_NUM; + index++) { + tmpval = val[ch][slice][index]; + lsb = _find_change(tmpval, 0U); + msb = _find_change(tmpval, + (CODE_MAX / CODE_STEP) - 1U); + tmp = (lsb + msb) >> 1U; + + tmp = _rx_offset_cal_updn(tmp * CODE_STEP); + ddr_setval_s(ch, slice, + _reg_PHY_RX_CAL_X[index], tmp); + } + } + } + ddr_setval_ach_as(_reg_PHY_RX_CAL_OVERRIDE, 0x00); + + return 0U; +} + +static uint32_t rx_offset_cal_hw(void) +{ + uint32_t ch, slice; + uint32_t retry; + uint32_t complete; + uint32_t tmp; + uint32_t tmp_ach_as[DRAM_CH_CNT][SLICE_CNT]; + + ddr_setval_ach_as(_reg_PHY_RX_CAL_X[9], 0x00); + ddr_setval_ach_as(_reg_PHY_RX_CAL_OVERRIDE, 0x00); + ddr_setval_ach_as(_reg_PHY_RX_CAL_SAMPLE_WAIT, 0x0f); + + retry = 0U; + while (retry < 4096U) { + if ((retry & 0xffU) == 0U) { + ddr_setval_ach_as(_reg_SC_PHY_RX_CAL_START, 0x01); + } + foreach_vch(ch) { + for (slice = 0U; slice < SLICE_CNT; slice++) { + tmp_ach_as[ch][slice] = + ddr_getval_s(ch, slice, + _reg_PHY_RX_CAL_X[9]); + } + } + + complete = 1U; + foreach_vch(ch) { + for (slice = 0U; slice < SLICE_CNT; slice++) { + tmp = tmp_ach_as[ch][slice]; + tmp = (tmp & 0x3fU) + ((tmp >> 6) & 0x3fU); + if (tmp != 0x40U) { + complete = 0U; + } + } + } + if (complete != 0U) { + break; + } + + retry++; + } + + return (complete == 0U); +} + +/* adjust wpath latency */ +static void adjust_wpath_latency(void) +{ + uint32_t ch, cs, slice; + uint32_t dly; + uint32_t wpath_add; + const uint32_t _par_EARLY_THRESHOLD_VAL = 0x180U; + + foreach_vch(ch) { + for (slice = 0U; slice < SLICE_CNT; slice += 1U) { + for (cs = 0U; cs < CS_CNT; cs++) { + ddr_setval_s(ch, slice, + _reg_PHY_PER_CS_TRAINING_INDEX, + cs); + ddr_getval_s(ch, slice, + _reg_PHY_PER_CS_TRAINING_INDEX); + dly = + ddr_getval_s(ch, slice, + _reg_PHY_CLK_WRDQS_SLAVE_DELAY); + if (dly <= _par_EARLY_THRESHOLD_VAL) { + continue; + } + + wpath_add = + ddr_getval_s(ch, slice, + _reg_PHY_WRITE_PATH_LAT_ADD); + ddr_setval_s(ch, slice, + _reg_PHY_WRITE_PATH_LAT_ADD, + wpath_add - 1U); + } + } + } +} + +/* DDR Initialize entry */ +int32_t rzg_dram_init(void) +{ + uint32_t ch, cs; + uint32_t data_l; + uint32_t bus_mbps, bus_mbpsdiv; + uint32_t tmp_tccd; + uint32_t failcount; + uint32_t cnf_boardtype; + int32_t ret = INITDRAM_NG; + + /* Thermal sensor setting */ + data_l = mmio_read_32(CPG_MSTPSR5); + if ((data_l & BIT(22)) != 0U) { /* case THS/TSC Standby */ + data_l &= ~BIT(22); + cpg_write_32(CPG_SMSTPCR5, data_l); + while ((mmio_read_32(CPG_MSTPSR5) & BIT(22)) != 0U) { + /* wait bit=0 */ + } + } + + /* THCTR Bit6: PONM=0 , Bit0: THSST=0 */ + data_l = mmio_read_32(THS1_THCTR) & 0xFFFFFFBE; + mmio_write_32(THS1_THCTR, data_l); + + /* Judge product and cut */ +#ifdef RCAR_DDR_FIXED_LSI_TYPE +#if (RCAR_LSI == RCAR_AUTO) + prr_product = mmio_read_32(PRR) & PRR_PRODUCT_MASK; + prr_cut = mmio_read_32(PRR) & PRR_CUT_MASK; +#else /* RCAR_LSI */ +#ifndef RCAR_LSI_CUT + prr_cut = mmio_read_32(PRR) & PRR_CUT_MASK; +#endif /* RCAR_LSI_CUT */ +#endif /* RCAR_LSI */ +#else /* RCAR_DDR_FIXED_LSI_TYPE */ + prr_product = mmio_read_32(PRR) & PRR_PRODUCT_MASK; + prr_cut = mmio_read_32(PRR) & PRR_CUT_MASK; +#endif /* RCAR_DDR_FIXED_LSI_TYPE */ + + if (prr_product == PRR_PRODUCT_M3) { + p_ddr_regdef_tbl = + (const uint32_t *)&DDR_REGDEF_TBL[1][0]; + } else { + FATAL_MSG("BL2: DDR:Unknown Product\n"); + goto done; + } + + if ((prr_product == PRR_PRODUCT_M3) && (prr_cut < PRR_PRODUCT_30)) { + /* non : G2M Ver.1.x not support */ + } else { + mmio_write_32(DBSC_DBSYSCNT0, 0x00001234U); + } + + /* Judge board type */ + cnf_boardtype = boardcnf_get_brd_type(prr_product); + if (cnf_boardtype >= (uint32_t)BOARDNUM) { + FATAL_MSG("BL2: DDR:Unknown Board\n"); + goto done; + } + board_cnf = (const struct _boardcnf *)&boardcnfs[cnf_boardtype]; + +/* RCAR_DRAM_SPLIT_2CH (2U) */ +#if RCAR_DRAM_SPLIT == 2 + ddr_phyvalid = board_cnf->phyvalid; +#else /* RCAR_DRAM_SPLIT_2CH */ + ddr_phyvalid = board_cnf->phyvalid; +#endif /* RCAR_DRAM_SPLIT_2CH */ + + max_density = 0U; + + for (cs = 0U; cs < CS_CNT; cs++) { + ch_have_this_cs[cs] = 0U; + } + + foreach_ech(ch) { + for (cs = 0U; cs < CS_CNT; cs++) { + ddr_density[ch][cs] = 0xffU; + } + } + + foreach_vch(ch) { + for (cs = 0U; cs < CS_CNT; cs++) { + data_l = board_cnf->ch[ch].ddr_density[cs]; + ddr_density[ch][cs] = data_l; + + if (data_l == 0xffU) { + continue; + } + if (data_l > max_density) { + max_density = data_l; + } + ch_have_this_cs[cs] |= (1U << ch); + } + } + + /* Judge board clock frequency (in MHz) */ + boardcnf_get_brd_clk(cnf_boardtype, &brd_clk, &brd_clkdiv); + if ((brd_clk / brd_clkdiv) > 25U) { + brd_clkdiva = 1U; + } else { + brd_clkdiva = 0U; + } + + /* Judge ddr operating frequency clock(in Mbps) */ + boardcnf_get_ddr_mbps(cnf_boardtype, &ddr_mbps, &ddr_mbpsdiv); + + ddr0800_mul = CLK_DIV(800U, 2U, brd_clk, brd_clkdiv * (brd_clkdiva + 1U)); + + ddr_mul = CLK_DIV(ddr_mbps, ddr_mbpsdiv * 2U, brd_clk, + brd_clkdiv * (brd_clkdiva + 1U)); + + /* Adjust tccd */ + data_l = (0x00006000 & mmio_read_32(RST_MODEMR)) >> 13; + bus_mbps = 0U; + bus_mbpsdiv = 0U; + switch (data_l) { + case 0: + bus_mbps = brd_clk * 0x60U * 2U; + bus_mbpsdiv = brd_clkdiv * 1U; + break; + case 1: + bus_mbps = brd_clk * 0x50U * 2U; + bus_mbpsdiv = brd_clkdiv * 1U; + break; + case 2: + bus_mbps = brd_clk * 0x40U * 2U; + bus_mbpsdiv = brd_clkdiv * 1U; + break; + case 3: + bus_mbps = brd_clk * 0x60U * 2U; + bus_mbpsdiv = brd_clkdiv * 2U; + break; + default: + bus_mbps = brd_clk * 0x60U * 2U; + bus_mbpsdiv = brd_clkdiv * 2U; + WARN("BL2: DDR using default values for adjusting tccd"); + break; + } + tmp_tccd = CLK_DIV(ddr_mbps * 8U, ddr_mbpsdiv, bus_mbps, bus_mbpsdiv); + if (8U * ddr_mbps * bus_mbpsdiv != tmp_tccd * bus_mbps * ddr_mbpsdiv) { + tmp_tccd = tmp_tccd + 1U; + } + + if (tmp_tccd < 8U) { + ddr_tccd = 8U; + } else { + ddr_tccd = tmp_tccd; + } + + NOTICE("BL2: DDR%d(%s)\n", ddr_mbps / ddr_mbpsdiv, RCAR_DDR_VERSION); + + MSG_LF("Start\n"); + + /* PLL Setting */ + pll3_control(1U); + + /* initialize DDR */ + data_l = init_ddr(); + if (data_l == ddr_phyvalid) { + failcount = 0U; + } else { + failcount = 1U; + } + + foreach_vch(ch) { + mmio_write_32(DBSC_DBPDLK(ch), 0x00000000U); + } + if ((prr_product == PRR_PRODUCT_M3) && (prr_cut < PRR_PRODUCT_30)) { + /* non : G2M Ver.1.x not support */ + } else { + mmio_write_32(DBSC_DBSYSCNT0, 0x00000000); + } + + if (failcount == 0U) { + ret = INITDRAM_OK; + } + +done: + return ret; +} + +static void pvtcode_update(void) +{ + uint32_t ch; + uint32_t data_l; + uint32_t pvtp[4], pvtn[4], pvtp_init, pvtn_init; + int32_t pvtp_tmp, pvtn_tmp; + + foreach_vch(ch) { + pvtn_init = (tcal.tcomp_cal[ch] & 0xFC0U) >> 6; + pvtp_init = (tcal.tcomp_cal[ch] & 0x03FU) >> 0; + + if (8912U * pvtp_init > 44230U) { + pvtp_tmp = (5000U + 8912U * pvtp_init - 44230U) / 10000U; + } else { + pvtp_tmp = + -((-(5000 + 8912 * pvtp_init - 44230)) / 10000); + } + pvtn_tmp = (5000U + 5776U * (uint32_t)pvtn_init + 30280U) / 10000U; + + pvtn[ch] = (uint32_t)pvtn_tmp + pvtn_init; + pvtp[ch] = (uint32_t)pvtp_tmp + pvtp_init; + + if (pvtn[ch] > 63U) { + pvtn[ch] = 63U; + pvtp[ch] = + (pvtp_tmp) * (63 - 6 * pvtn_tmp - + pvtn_init) / (pvtn_tmp) + + 6 * pvtp_tmp + pvtp_init; + } + + data_l = pvtp[ch] | (pvtn[ch] << 6) | 0x00015000U; + reg_ddrphy_write(ch, ddr_regdef_adr(_reg_PHY_PAD_FDBK_TERM), + data_l | 0x00020000U); + reg_ddrphy_write(ch, ddr_regdef_adr(_reg_PHY_PAD_DATA_TERM), + data_l); + reg_ddrphy_write(ch, ddr_regdef_adr(_reg_PHY_PAD_DQS_TERM), + data_l); + reg_ddrphy_write(ch, ddr_regdef_adr(_reg_PHY_PAD_ADDR_TERM), + data_l); + reg_ddrphy_write(ch, ddr_regdef_adr(_reg_PHY_PAD_CS_TERM), + data_l); + } +} + +static void pvtcode_update2(void) +{ + uint32_t ch; + + foreach_vch(ch) { + reg_ddrphy_write(ch, ddr_regdef_adr(_reg_PHY_PAD_FDBK_TERM), + tcal.init_cal[ch] | 0x00020000U); + reg_ddrphy_write(ch, ddr_regdef_adr(_reg_PHY_PAD_DATA_TERM), + tcal.init_cal[ch]); + reg_ddrphy_write(ch, ddr_regdef_adr(_reg_PHY_PAD_DQS_TERM), + tcal.init_cal[ch]); + reg_ddrphy_write(ch, ddr_regdef_adr(_reg_PHY_PAD_ADDR_TERM), + tcal.init_cal[ch]); + reg_ddrphy_write(ch, ddr_regdef_adr(_reg_PHY_PAD_CS_TERM), + tcal.init_cal[ch]); + } +} + +static void ddr_padcal_tcompensate_getinit(uint32_t override) +{ + uint32_t ch; + uint32_t data_l; + uint32_t pvtp, pvtn; + + tcal.init_temp = 0; + for (ch = 0U; ch < 4U; ch++) { + tcal.init_cal[ch] = 0U; + tcal.tcomp_cal[ch] = 0U; + } + + foreach_vch(ch) { + tcal.init_cal[ch] = ddr_getval(ch, _reg_PHY_PAD_TERM_X[1]); + tcal.tcomp_cal[ch] = ddr_getval(ch, _reg_PHY_PAD_TERM_X[1]); + } + + if (override == 0U) { + data_l = mmio_read_32(THS1_TEMP); + if (data_l < 2800U) { + tcal.init_temp = + (143 * (int32_t)data_l - 359000) / 1000; + } else { + tcal.init_temp = + (121 * (int32_t)data_l - 296300) / 1000; + } + + foreach_vch(ch) { + pvtp = (tcal.init_cal[ch] >> 0) & 0x000003FU; + pvtn = (tcal.init_cal[ch] >> 6) & 0x000003FU; + if ((int32_t)pvtp > + ((tcal.init_temp * 29 - 3625) / 1000)) { + pvtp = (int32_t)pvtp + + ((3625 - tcal.init_temp * 29) / 1000); + } else { + pvtp = 0U; + } + + if ((int32_t)pvtn > + ((tcal.init_temp * 54 - 6750) / 1000)) { + pvtn = (int32_t)pvtn + + ((6750 - tcal.init_temp * 54) / 1000); + } else { + pvtn = 0U; + } + + tcal.init_cal[ch] = 0x00015000U | (pvtn << 6) | pvtp; + } + tcal.init_temp = 125; + } +} + +#ifndef DDR_QOS_INIT_SETTING +/* For QoS init */ +uint8_t rzg_get_boardcnf_phyvalid(void) +{ + return ddr_phyvalid; +} +#endif /* DDR_QOS_INIT_SETTING */ diff --git a/drivers/renesas/rzg/ddr/ddr_b/boot_init_dram_config.c b/drivers/renesas/rzg/ddr/ddr_b/boot_init_dram_config.c new file mode 100644 index 000000000..345ef24c3 --- /dev/null +++ b/drivers/renesas/rzg/ddr/ddr_b/boot_init_dram_config.c @@ -0,0 +1,277 @@ +/* + * Copyright (c) 2021, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#define BOARDNUM 2 +#define BOARD_JUDGE_AUTO + +#ifdef BOARD_JUDGE_AUTO +static uint32_t _board_judge(uint32_t prr_product); + +static uint32_t boardcnf_get_brd_type(uint32_t prr_product) +{ + return _board_judge(prr_product); +} +#else /* BOARD_JUDGE_AUTO */ +static uint32_t boardcnf_get_brd_type(void) +{ + return 1U; +} +#endif /* BOARD_JUDGE_AUTO */ + +#define DDR_FAST_INIT + +struct _boardcnf_ch { + uint8_t ddr_density[CS_CNT]; + uint64_t ca_swap; + uint16_t dqs_swap; + uint32_t dq_swap[SLICE_CNT]; + uint8_t dm_swap[SLICE_CNT]; + uint16_t wdqlvl_patt[16]; + int8_t cacs_adj[16]; + int8_t dm_adj_w[SLICE_CNT]; + int8_t dq_adj_w[SLICE_CNT * 8U]; + int8_t dm_adj_r[SLICE_CNT]; + int8_t dq_adj_r[SLICE_CNT * 8U]; +}; + +struct _boardcnf { + uint8_t phyvalid; + uint8_t dbi_en; + uint16_t cacs_dly; + int16_t cacs_dly_adj; + uint16_t dqdm_dly_w; + uint16_t dqdm_dly_r; + struct _boardcnf_ch ch[DRAM_CH_CNT]; +}; + +#define WDQLVL_PAT {\ + 0x00AA,\ + 0x0055,\ + 0x00AA,\ + 0x0155,\ + 0x01CC,\ + 0x0133,\ + 0x00CC,\ + 0x0033,\ + 0x00F0,\ + 0x010F,\ + 0x01F0,\ + 0x010F,\ + 0x00F0,\ + 0x00F0,\ + 0x000F,\ + 0x010F} + +static const struct _boardcnf boardcnfs[BOARDNUM] = { + { +/* boardcnf[0] HopeRun HiHope RZ/G2M 16Gbit/1rank/2ch board with G2M SoC */ + .phyvalid = 0x03, + .dbi_en = 0x01, + .cacs_dly = 0x02c0, + .cacs_dly_adj = 0, + .dqdm_dly_w = 0x0300, + .dqdm_dly_r = 0x00a0, + .ch = { + { + {0x04, 0xff}, + 0x00345201U, + 0x3201, + {0x01672543U, 0x45361207U, 0x45632107U, 0x60715234U}, + {0x08, 0x08, 0x08, 0x08}, + WDQLVL_PAT, + {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0} + }, + + { + {0x04, 0xff}, + 0x00302154U, + 0x2310, + {0x01672543U, 0x45361207U, 0x45632107U, 0x60715234U}, + {0x08, 0x08, 0x08, 0x08}, + WDQLVL_PAT, + {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0} + } + } + }, +/* boardcnf[1] HopeRun HiHope RZ/G2M 8Gbit/2rank/2ch board with G2M SoC */ + { + 0x03, + 0x01, + 0x02c0, + 0, + 0x0300, + 0x00a0, + { + { + {0x02, 0x02}, + 0x00345201U, + 0x3201, + {0x01672543U, 0x45361207U, 0x45632107U, 0x60715234U}, + {0x08, 0x08, 0x08, 0x08}, + WDQLVL_PAT, + {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0} + }, + { + {0x02, 0x02}, + 0x00302154U, + 0x2310, + {0x01672543U, 0x45361207U, 0x45632107U, 0x60715234U}, + {0x08, 0x08, 0x08, 0x08}, + WDQLVL_PAT, + {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0} + } + } + } +}; + +void boardcnf_get_brd_clk(uint32_t brd, uint32_t *clk, uint32_t *div) +{ + uint32_t md; + + md = (mmio_read_32(RST_MODEMR) >> 13) & 0x3U; + switch (md) { + case 0x0U: + *clk = 50U; + *div = 3U; + break; + case 0x1U: + *clk = 60U; + *div = 3U; + break; + case 0x2U: + *clk = 75U; + *div = 3U; + break; + case 0x3U: + *clk = 100U; + *div = 3U; + break; + default: + break; + } + (void)brd; +} + +void boardcnf_get_ddr_mbps(uint32_t brd, uint32_t *mbps, uint32_t *div) +{ + uint32_t md; + + md = (mmio_read_32(RST_MODEMR) >> 17U) & 0x5U; + md = (md | (md >> 1U)) & 0x3U; + switch (md) { + case 0x0U: + *mbps = 3200U; + *div = 1U; + break; + case 0x1U: + *mbps = 2800U; + *div = 1U; + break; + case 0x2U: + *mbps = 2400U; + *div = 1U; + break; + case 0x3U: + *mbps = 1600U; + *div = 1U; + break; + default: + break; + } + (void)brd; +} + +#define _def_REFPERIOD 1890 + +#define M3_SAMPLE_TT_A84 0xB866CC10U, 0x3B250421U +#define M3_SAMPLE_TT_A85 0xB866CC10U, 0x3AA50421U +#define M3_SAMPLE_TT_A86 0xB866CC10U, 0x3AA48421U +#define M3_SAMPLE_FF_B45 0xB866CC10U, 0x3AB00C21U +#define M3_SAMPLE_FF_B49 0xB866CC10U, 0x39B10C21U +#define M3_SAMPLE_FF_B56 0xB866CC10U, 0x3AAF8C21U +#define M3_SAMPLE_SS_E24 0xB866CC10U, 0x3BA39421U +#define M3_SAMPLE_SS_E28 0xB866CC10U, 0x3C231421U +#define M3_SAMPLE_SS_E32 0xB866CC10U, 0x3C241421U + +static const uint32_t termcode_by_sample[20][3] = { + { M3_SAMPLE_TT_A84, 0x000158D5U }, + { M3_SAMPLE_TT_A85, 0x00015955U }, + { M3_SAMPLE_TT_A86, 0x00015955U }, + { M3_SAMPLE_FF_B45, 0x00015690U }, + { M3_SAMPLE_FF_B49, 0x00015753U }, + { M3_SAMPLE_FF_B56, 0x00015793U }, + { M3_SAMPLE_SS_E24, 0x00015996U }, + { M3_SAMPLE_SS_E28, 0x000159D7U }, + { M3_SAMPLE_SS_E32, 0x00015997U }, + { 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0001554FU} +}; + +#ifdef BOARD_JUDGE_AUTO +/* Board detect function */ +#define GPIO_INDT5 0xE605500CU +#define LPDDR4_2RANK (0x01U << 25U) + +static uint32_t _board_judge(uint32_t prr_product) +{ + uint32_t boardInfo; + uint32_t boardid = 1U; + + if (prr_product == PRR_PRODUCT_M3) { + if ((mmio_read_32(PRR) & PRR_CUT_MASK) != RCAR_M3_CUT_VER11) { + boardInfo = mmio_read_32(GPIO_INDT5); + if ((boardInfo & LPDDR4_2RANK) == 0U) { + boardid = 0U; + } + } + } + + return boardid; +} +#endif /* BOARD_JUDGE_AUTO */ diff --git a/drivers/renesas/rzg/ddr/ddr_b/boot_init_dram_regdef.h b/drivers/renesas/rzg/ddr/ddr_b/boot_init_dram_regdef.h new file mode 100644 index 000000000..9f1c9368b --- /dev/null +++ b/drivers/renesas/rzg/ddr/ddr_b/boot_init_dram_regdef.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef RZG_BOOT_INIT_DRAM_REGDEF_H +#define RZG_BOOT_INIT_DRAM_REGDEF_H + +#define RCAR_DDR_VERSION "rev.0.40" +#define DRAM_CH_CNT 0x04U +#define SLICE_CNT 0x04U +#define CS_CNT 0x02U + +/* order : CS0A, CS0B, CS1A, CS1B */ +#define CSAB_CNT (CS_CNT * 2U) + +/* order : CH0A, CH0B, CH1A, CH1B, CH2A, CH2B, CH3A, CH3B */ +#define CHAB_CNT (DRAM_CH_CNT * 2) + +/* pll setting */ +#define CLK_DIV(a, diva, b, divb) (((a) * (divb)) / ((b) * (diva))) +#define CLK_MUL(a, diva, b, divb) (((a) * (b)) / ((diva) * (divb))) + +/* for ddr density setting */ +#define DBMEMCONF_REG(d3, row, bank, col, dw) \ + (((d3) << 30U) | ((row) << 24U) | ((bank) << 16U) | ((col) << 8U) | (dw)) + +#define DBMEMCONF_REGD(density) \ + (DBMEMCONF_REG((density) % 2U, ((density) + 1U) / \ + 2U + (29U - 3U - 10U - 2U), 3U, 10U, 2U)) + +#define DBMEMCONF_VAL(ch, cs) (DBMEMCONF_REGD(DBMEMCONF_DENS(ch, cs))) + +/* refresh mode */ +#define DBSC_REFINTS (0x0U) + +/* system registers */ +#define CPG_FRQCRB (CPG_BASE + 0x0004U) + +#define CPG_PLLECR (CPG_BASE + 0x00D0U) +#define CPG_MSTPSR5 (CPG_BASE + 0x003CU) +#define CPG_SRCR4 (CPG_BASE + 0x00BCU) +#define CPG_PLL3CR (CPG_BASE + 0x00DCU) +#define CPG_ZB3CKCR (CPG_BASE + 0x0380U) +#define CPG_FRQCRD (CPG_BASE + 0x00E4U) +#define CPG_SMSTPCR5 (CPG_BASE + 0x0144U) +#define CPG_CPGWPR (CPG_BASE + 0x0900U) +#define CPG_SRSTCLR4 (CPG_BASE + 0x0950U) + +#define CPG_FRQCRB_KICK_BIT BIT(31) +#define CPG_PLLECR_PLL3E_BIT BIT(3) +#define CPG_PLLECR_PLL3ST_BIT BIT(11) +#define CPG_ZB3CKCR_ZB3ST_BIT BIT(11) + +#define RST_BASE (0xE6160000U) +#define RST_MODEMR (RST_BASE + 0x0060U) + +#define LIFEC_CHIPID(x) (0xE6110040U + 0x04U * (x)) + +/* DBSC registers */ +#include "ddr_regs.h" + +#define DBSC_DBMONCONF4 0xE6793010U + +#define DBSC_PLL_LOCK(ch) (0xE6794054U + 0x100U * (ch)) +#define DBSC_PLL_LOCK_0 0xE6794054U +#define DBSC_PLL_LOCK_1 0xE6794154U +#define DBSC_PLL_LOCK_2 0xE6794254U +#define DBSC_PLL_LOCK_3 0xE6794354U + +/* STAT registers */ +#define MSTAT_SL_INIT 0xE67E8000U +#define MSTAT_REF_ARS 0xE67E8004U +#define MSTATQ_STATQC 0xE67E8008U +#define MSTATQ_WTENABLE 0xE67E8030U +#define MSTATQ_WTREFRESH 0xE67E8034U +#define MSTATQ_WTSETTING0 0xE67E8038U +#define MSTATQ_WTSETTING1 0xE67E803CU + +#define QOS_BASE1 (0xE67F0000U) +#define QOSCTRL_RAS (QOS_BASE1 + 0x0000U) +#define QOSCTRL_FIXTH (QOS_BASE1 + 0x0004U) +#define QOSCTRL_RAEN (QOS_BASE1 + 0x0018U) +#define QOSCTRL_REGGD (QOS_BASE1 + 0x0020U) +#define QOSCTRL_DANN (QOS_BASE1 + 0x0030U) +#define QOSCTRL_DANT (QOS_BASE1 + 0x0038U) +#define QOSCTRL_EC (QOS_BASE1 + 0x003CU) +#define QOSCTRL_EMS (QOS_BASE1 + 0x0040U) +#define QOSCTRL_INSFC (QOS_BASE1 + 0x0050U) +#define QOSCTRL_BERR (QOS_BASE1 + 0x0054U) +#define QOSCTRL_RACNT0 (QOS_BASE1 + 0x0080U) +#define QOSCTRL_STATGEN0 (QOS_BASE1 + 0x0088U) + +/* other module */ +#define THS1_THCTR 0xE6198020U +#define THS1_TEMP 0xE6198028U + +#endif /* RZG_BOOT_INIT_DRAM_REGDEF_H */ diff --git a/drivers/renesas/rzg/ddr/ddr_b/ddr_b.mk b/drivers/renesas/rzg/ddr/ddr_b/ddr_b.mk new file mode 100644 index 000000000..c137f2624 --- /dev/null +++ b/drivers/renesas/rzg/ddr/ddr_b/ddr_b.mk @@ -0,0 +1,7 @@ +# +# Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +BL2_SOURCES += drivers/renesas/rzg/ddr/ddr_b/boot_init_dram.c diff --git a/drivers/renesas/rzg/ddr/ddr_b/ddr_regdef.h b/drivers/renesas/rzg/ddr/ddr_b/ddr_regdef.h new file mode 100644 index 000000000..1da455f91 --- /dev/null +++ b/drivers/renesas/rzg/ddr/ddr_b/ddr_regdef.h @@ -0,0 +1,5891 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef RZG_DDR_REGDEF_H +#define RZG_DDR_REGDEF_H + +#define _reg_PHY_DQ_DM_SWIZZLE0 0x00000000U +#define _reg_PHY_DQ_DM_SWIZZLE1 0x00000001U +#define _reg_PHY_CLK_WR_BYPASS_SLAVE_DELAY 0x00000002U +#define _reg_PHY_RDDQS_GATE_BYPASS_SLAVE_DELAY 0x00000003U +#define _reg_PHY_BYPASS_TWO_CYC_PREAMBLE 0x00000004U +#define _reg_PHY_CLK_BYPASS_OVERRIDE 0x00000005U +#define _reg_PHY_SW_WRDQ0_SHIFT 0x00000006U +#define _reg_PHY_SW_WRDQ1_SHIFT 0x00000007U +#define _reg_PHY_SW_WRDQ2_SHIFT 0x00000008U +#define _reg_PHY_SW_WRDQ3_SHIFT 0x00000009U +#define _reg_PHY_SW_WRDQ4_SHIFT 0x0000000aU +#define _reg_PHY_SW_WRDQ5_SHIFT 0x0000000bU +#define _reg_PHY_SW_WRDQ6_SHIFT 0x0000000cU +#define _reg_PHY_SW_WRDQ7_SHIFT 0x0000000dU +#define _reg_PHY_SW_WRDM_SHIFT 0x0000000eU +#define _reg_PHY_SW_WRDQS_SHIFT 0x0000000fU +#define _reg_PHY_DQ_TSEL_ENABLE 0x00000010U +#define _reg_PHY_DQ_TSEL_SELECT 0x00000011U +#define _reg_PHY_DQS_TSEL_ENABLE 0x00000012U +#define _reg_PHY_DQS_TSEL_SELECT 0x00000013U +#define _reg_PHY_TWO_CYC_PREAMBLE 0x00000014U +#define _reg_PHY_DBI_MODE 0x00000015U +#define _reg_PHY_PER_RANK_CS_MAP 0x00000016U +#define _reg_PHY_PER_CS_TRAINING_MULTICAST_EN 0x00000017U +#define _reg_PHY_PER_CS_TRAINING_INDEX 0x00000018U +#define _reg_PHY_LP4_BOOT_RDDATA_EN_IE_DLY 0x00000019U +#define _reg_PHY_LP4_BOOT_RDDATA_EN_DLY 0x0000001aU +#define _reg_PHY_LP4_BOOT_RDDATA_EN_TSEL_DLY 0x0000001bU +#define _reg_PHY_LP4_BOOT_RPTR_UPDATE 0x0000001cU +#define _reg_PHY_LP4_BOOT_RDDQS_GATE_SLAVE_DELAY 0x0000001dU +#define _reg_PHY_LP4_BOOT_RDDQS_LATENCY_ADJUST 0x0000001eU +#define _reg_PHY_LP4_BOOT_WRPATH_GATE_DISABLE 0x0000001fU +#define _reg_PHY_LP4_BOOT_RDDATA_EN_OE_DLY 0x00000020U +#define _reg_PHY_LPBK_CONTROL 0x00000021U +#define _reg_PHY_LPBK_DFX_TIMEOUT_EN 0x00000022U +#define _reg_PHY_AUTO_TIMING_MARGIN_CONTROL 0x00000023U +#define _reg_PHY_AUTO_TIMING_MARGIN_OBS 0x00000024U +#define _reg_PHY_SLICE_PWR_RDC_DISABLE 0x00000025U +#define _reg_PHY_PRBS_PATTERN_START 0x00000026U +#define _reg_PHY_PRBS_PATTERN_MASK 0x00000027U +#define _reg_PHY_RDDQS_DQ_BYPASS_SLAVE_DELAY 0x00000028U +#define _reg_PHY_GATE_ERROR_DELAY_SELECT 0x00000029U +#define _reg_SC_PHY_SNAP_OBS_REGS 0x0000002aU +#define _reg_PHY_LPDDR 0x0000002bU +#define _reg_PHY_LPDDR_TYPE 0x0000002cU +#define _reg_PHY_GATE_SMPL1_SLAVE_DELAY 0x0000002dU +#define _reg_PHY_GATE_SMPL2_SLAVE_DELAY 0x0000002eU +#define _reg_ON_FLY_GATE_ADJUST_EN 0x0000002fU +#define _reg_PHY_GATE_TRACKING_OBS 0x00000030U +#define _reg_PHY_DFI40_POLARITY 0x00000031U +#define _reg_PHY_LP4_PST_AMBLE 0x00000032U +#define _reg_PHY_RDLVL_PATT8 0x00000033U +#define _reg_PHY_RDLVL_PATT9 0x00000034U +#define _reg_PHY_RDLVL_PATT10 0x00000035U +#define _reg_PHY_RDLVL_PATT11 0x00000036U +#define _reg_PHY_LP4_RDLVL_PATT8 0x00000037U +#define _reg_PHY_LP4_RDLVL_PATT9 0x00000038U +#define _reg_PHY_LP4_RDLVL_PATT10 0x00000039U +#define _reg_PHY_LP4_RDLVL_PATT11 0x0000003aU +#define _reg_PHY_SLAVE_LOOP_CNT_UPDATE 0x0000003bU +#define _reg_PHY_SW_FIFO_PTR_RST_DISABLE 0x0000003cU +#define _reg_PHY_MASTER_DLY_LOCK_OBS_SELECT 0x0000003dU +#define _reg_PHY_RDDQ_ENC_OBS_SELECT 0x0000003eU +#define _reg_PHY_RDDQS_DQ_ENC_OBS_SELECT 0x0000003fU +#define _reg_PHY_WR_ENC_OBS_SELECT 0x00000040U +#define _reg_PHY_WR_SHIFT_OBS_SELECT 0x00000041U +#define _reg_PHY_FIFO_PTR_OBS_SELECT 0x00000042U +#define _reg_PHY_LVL_DEBUG_MODE 0x00000043U +#define _reg_SC_PHY_LVL_DEBUG_CONT 0x00000044U +#define _reg_PHY_WRLVL_CAPTURE_CNT 0x00000045U +#define _reg_PHY_WRLVL_UPDT_WAIT_CNT 0x00000046U +#define _reg_PHY_WRLVL_DQ_MASK 0x00000047U +#define _reg_PHY_GTLVL_CAPTURE_CNT 0x00000048U +#define _reg_PHY_GTLVL_UPDT_WAIT_CNT 0x00000049U +#define _reg_PHY_RDLVL_CAPTURE_CNT 0x0000004aU +#define _reg_PHY_RDLVL_UPDT_WAIT_CNT 0x0000004bU +#define _reg_PHY_RDLVL_OP_MODE 0x0000004cU +#define _reg_PHY_RDLVL_RDDQS_DQ_OBS_SELECT 0x0000004dU +#define _reg_PHY_RDLVL_DATA_MASK 0x0000004eU +#define _reg_PHY_RDLVL_DATA_SWIZZLE 0x0000004fU +#define _reg_PHY_WDQLVL_BURST_CNT 0x00000050U +#define _reg_PHY_WDQLVL_PATT 0x00000051U +#define _reg_PHY_WDQLVL_DQDM_SLV_DLY_JUMP_OFFSET 0x00000052U +#define _reg_PHY_WDQLVL_UPDT_WAIT_CNT 0x00000053U +#define _reg_PHY_WDQLVL_DQDM_OBS_SELECT 0x00000054U +#define _reg_PHY_WDQLVL_QTR_DLY_STEP 0x00000055U +#define _reg_SC_PHY_WDQLVL_CLR_PREV_RESULTS 0x00000056U +#define _reg_PHY_WDQLVL_CLR_PREV_RESULTS 0x00000057U +#define _reg_PHY_WDQLVL_DATADM_MASK 0x00000058U +#define _reg_PHY_USER_PATT0 0x00000059U +#define _reg_PHY_USER_PATT1 0x0000005aU +#define _reg_PHY_USER_PATT2 0x0000005bU +#define _reg_PHY_USER_PATT3 0x0000005cU +#define _reg_PHY_USER_PATT4 0x0000005dU +#define _reg_PHY_DQ_SWIZZLING 0x0000005eU +#define _reg_PHY_CALVL_VREF_DRIVING_SLICE 0x0000005fU +#define _reg_SC_PHY_MANUAL_CLEAR 0x00000060U +#define _reg_PHY_FIFO_PTR_OBS 0x00000061U +#define _reg_PHY_LPBK_RESULT_OBS 0x00000062U +#define _reg_PHY_LPBK_ERROR_COUNT_OBS 0x00000063U +#define _reg_PHY_MASTER_DLY_LOCK_OBS 0x00000064U +#define _reg_PHY_RDDQ_SLV_DLY_ENC_OBS 0x00000065U +#define _reg_PHY_RDDQS_BASE_SLV_DLY_ENC_OBS 0x00000066U +#define _reg_PHY_RDDQS_DQ_RISE_ADDER_SLV_DLY_ENC_OBS 0x00000067U +#define _reg_PHY_RDDQS_DQ_FALL_ADDER_SLV_DLY_ENC_OBS 0x00000068U +#define _reg_PHY_RDDQS_GATE_SLV_DLY_ENC_OBS 0x00000069U +#define _reg_PHY_WRDQS_BASE_SLV_DLY_ENC_OBS 0x0000006aU +#define _reg_PHY_WRDQ_BASE_SLV_DLY_ENC_OBS 0x0000006bU +#define _reg_PHY_WR_ADDER_SLV_DLY_ENC_OBS 0x0000006cU +#define _reg_PHY_WR_SHIFT_OBS 0x0000006dU +#define _reg_PHY_WRLVL_HARD0_DELAY_OBS 0x0000006eU +#define _reg_PHY_WRLVL_HARD1_DELAY_OBS 0x0000006fU +#define _reg_PHY_WRLVL_STATUS_OBS 0x00000070U +#define _reg_PHY_GATE_SMPL1_SLV_DLY_ENC_OBS 0x00000071U +#define _reg_PHY_GATE_SMPL2_SLV_DLY_ENC_OBS 0x00000072U +#define _reg_PHY_WRLVL_ERROR_OBS 0x00000073U +#define _reg_PHY_GTLVL_HARD0_DELAY_OBS 0x00000074U +#define _reg_PHY_GTLVL_HARD1_DELAY_OBS 0x00000075U +#define _reg_PHY_GTLVL_STATUS_OBS 0x00000076U +#define _reg_PHY_RDLVL_RDDQS_DQ_LE_DLY_OBS 0x00000077U +#define _reg_PHY_RDLVL_RDDQS_DQ_TE_DLY_OBS 0x00000078U +#define _reg_PHY_RDLVL_RDDQS_DQ_NUM_WINDOWS_OBS 0x00000079U +#define _reg_PHY_RDLVL_STATUS_OBS 0x0000007aU +#define _reg_PHY_WDQLVL_DQDM_LE_DLY_OBS 0x0000007bU +#define _reg_PHY_WDQLVL_DQDM_TE_DLY_OBS 0x0000007cU +#define _reg_PHY_WDQLVL_STATUS_OBS 0x0000007dU +#define _reg_PHY_DDL_MODE 0x0000007eU +#define _reg_PHY_DDL_TEST_OBS 0x0000007fU +#define _reg_PHY_DDL_TEST_MSTR_DLY_OBS 0x00000080U +#define _reg_PHY_DDL_TRACK_UPD_THRESHOLD 0x00000081U +#define _reg_PHY_LP4_WDQS_OE_EXTEND 0x00000082U +#define _reg_SC_PHY_RX_CAL_START 0x00000083U +#define _reg_PHY_RX_CAL_OVERRIDE 0x00000084U +#define _reg_PHY_RX_CAL_SAMPLE_WAIT 0x00000085U +#define _reg_PHY_RX_CAL_DQ0 0x00000086U +#define _reg_PHY_RX_CAL_DQ1 0x00000087U +#define _reg_PHY_RX_CAL_DQ2 0x00000088U +#define _reg_PHY_RX_CAL_DQ3 0x00000089U +#define _reg_PHY_RX_CAL_DQ4 0x0000008aU +#define _reg_PHY_RX_CAL_DQ5 0x0000008bU +#define _reg_PHY_RX_CAL_DQ6 0x0000008cU +#define _reg_PHY_RX_CAL_DQ7 0x0000008dU +#define _reg_PHY_RX_CAL_DM 0x0000008eU +#define _reg_PHY_RX_CAL_DQS 0x0000008fU +#define _reg_PHY_RX_CAL_FDBK 0x00000090U +#define _reg_PHY_RX_CAL_OBS 0x00000091U +#define _reg_PHY_RX_CAL_LOCK_OBS 0x00000092U +#define _reg_PHY_RX_CAL_DISABLE 0x00000093U +#define _reg_PHY_CLK_WRDQ0_SLAVE_DELAY 0x00000094U +#define _reg_PHY_CLK_WRDQ1_SLAVE_DELAY 0x00000095U +#define _reg_PHY_CLK_WRDQ2_SLAVE_DELAY 0x00000096U +#define _reg_PHY_CLK_WRDQ3_SLAVE_DELAY 0x00000097U +#define _reg_PHY_CLK_WRDQ4_SLAVE_DELAY 0x00000098U +#define _reg_PHY_CLK_WRDQ5_SLAVE_DELAY 0x00000099U +#define _reg_PHY_CLK_WRDQ6_SLAVE_DELAY 0x0000009aU +#define _reg_PHY_CLK_WRDQ7_SLAVE_DELAY 0x0000009bU +#define _reg_PHY_CLK_WRDM_SLAVE_DELAY 0x0000009cU +#define _reg_PHY_CLK_WRDQS_SLAVE_DELAY 0x0000009dU +#define _reg_PHY_WRLVL_THRESHOLD_ADJUST 0x0000009eU +#define _reg_PHY_RDDQ0_SLAVE_DELAY 0x0000009fU +#define _reg_PHY_RDDQ1_SLAVE_DELAY 0x000000a0U +#define _reg_PHY_RDDQ2_SLAVE_DELAY 0x000000a1U +#define _reg_PHY_RDDQ3_SLAVE_DELAY 0x000000a2U +#define _reg_PHY_RDDQ4_SLAVE_DELAY 0x000000a3U +#define _reg_PHY_RDDQ5_SLAVE_DELAY 0x000000a4U +#define _reg_PHY_RDDQ6_SLAVE_DELAY 0x000000a5U +#define _reg_PHY_RDDQ7_SLAVE_DELAY 0x000000a6U +#define _reg_PHY_RDDM_SLAVE_DELAY 0x000000a7U +#define _reg_PHY_RDDQS_DQ0_RISE_SLAVE_DELAY 0x000000a8U +#define _reg_PHY_RDDQS_DQ0_FALL_SLAVE_DELAY 0x000000a9U +#define _reg_PHY_RDDQS_DQ1_RISE_SLAVE_DELAY 0x000000aaU +#define _reg_PHY_RDDQS_DQ1_FALL_SLAVE_DELAY 0x000000abU +#define _reg_PHY_RDDQS_DQ2_RISE_SLAVE_DELAY 0x000000acU +#define _reg_PHY_RDDQS_DQ2_FALL_SLAVE_DELAY 0x000000adU +#define _reg_PHY_RDDQS_DQ3_RISE_SLAVE_DELAY 0x000000aeU +#define _reg_PHY_RDDQS_DQ3_FALL_SLAVE_DELAY 0x000000afU +#define _reg_PHY_RDDQS_DQ4_RISE_SLAVE_DELAY 0x000000b0U +#define _reg_PHY_RDDQS_DQ4_FALL_SLAVE_DELAY 0x000000b1U +#define _reg_PHY_RDDQS_DQ5_RISE_SLAVE_DELAY 0x000000b2U +#define _reg_PHY_RDDQS_DQ5_FALL_SLAVE_DELAY 0x000000b3U +#define _reg_PHY_RDDQS_DQ6_RISE_SLAVE_DELAY 0x000000b4U +#define _reg_PHY_RDDQS_DQ6_FALL_SLAVE_DELAY 0x000000b5U +#define _reg_PHY_RDDQS_DQ7_RISE_SLAVE_DELAY 0x000000b6U +#define _reg_PHY_RDDQS_DQ7_FALL_SLAVE_DELAY 0x000000b7U +#define _reg_PHY_RDDQS_DM_RISE_SLAVE_DELAY 0x000000b8U +#define _reg_PHY_RDDQS_DM_FALL_SLAVE_DELAY 0x000000b9U +#define _reg_PHY_RDDQS_GATE_SLAVE_DELAY 0x000000baU +#define _reg_PHY_RDDQS_LATENCY_ADJUST 0x000000bbU +#define _reg_PHY_WRITE_PATH_LAT_ADD 0x000000bcU +#define _reg_PHY_WRLVL_DELAY_EARLY_THRESHOLD 0x000000bdU +#define _reg_PHY_WRLVL_DELAY_PERIOD_THRESHOLD 0x000000beU +#define _reg_PHY_WRLVL_EARLY_FORCE_ZERO 0x000000bfU +#define _reg_PHY_GTLVL_RDDQS_SLV_DLY_START 0x000000c0U +#define _reg_PHY_GTLVL_LAT_ADJ_START 0x000000c1U +#define _reg_PHY_WDQLVL_DQDM_SLV_DLY_START 0x000000c2U +#define _reg_PHY_RDLVL_RDDQS_DQ_SLV_DLY_START 0x000000c3U +#define _reg_PHY_FDBK_PWR_CTRL 0x000000c4U +#define _reg_PHY_DQ_OE_TIMING 0x000000c5U +#define _reg_PHY_DQ_TSEL_RD_TIMING 0x000000c6U +#define _reg_PHY_DQ_TSEL_WR_TIMING 0x000000c7U +#define _reg_PHY_DQS_OE_TIMING 0x000000c8U +#define _reg_PHY_DQS_TSEL_RD_TIMING 0x000000c9U +#define _reg_PHY_DQS_OE_RD_TIMING 0x000000caU +#define _reg_PHY_DQS_TSEL_WR_TIMING 0x000000cbU +#define _reg_PHY_PER_CS_TRAINING_EN 0x000000ccU +#define _reg_PHY_DQ_IE_TIMING 0x000000cdU +#define _reg_PHY_DQS_IE_TIMING 0x000000ceU +#define _reg_PHY_RDDATA_EN_IE_DLY 0x000000cfU +#define _reg_PHY_IE_MODE 0x000000d0U +#define _reg_PHY_RDDATA_EN_DLY 0x000000d1U +#define _reg_PHY_RDDATA_EN_TSEL_DLY 0x000000d2U +#define _reg_PHY_RDDATA_EN_OE_DLY 0x000000d3U +#define _reg_PHY_SW_MASTER_MODE 0x000000d4U +#define _reg_PHY_MASTER_DELAY_START 0x000000d5U +#define _reg_PHY_MASTER_DELAY_STEP 0x000000d6U +#define _reg_PHY_MASTER_DELAY_WAIT 0x000000d7U +#define _reg_PHY_MASTER_DELAY_HALF_MEASURE 0x000000d8U +#define _reg_PHY_RPTR_UPDATE 0x000000d9U +#define _reg_PHY_WRLVL_DLY_STEP 0x000000daU +#define _reg_PHY_WRLVL_RESP_WAIT_CNT 0x000000dbU +#define _reg_PHY_GTLVL_DLY_STEP 0x000000dcU +#define _reg_PHY_GTLVL_RESP_WAIT_CNT 0x000000ddU +#define _reg_PHY_GTLVL_BACK_STEP 0x000000deU +#define _reg_PHY_GTLVL_FINAL_STEP 0x000000dfU +#define _reg_PHY_WDQLVL_DLY_STEP 0x000000e0U +#define _reg_PHY_TOGGLE_PRE_SUPPORT 0x000000e1U +#define _reg_PHY_RDLVL_DLY_STEP 0x000000e2U +#define _reg_PHY_WRPATH_GATE_DISABLE 0x000000e3U +#define _reg_PHY_WRPATH_GATE_TIMING 0x000000e4U +#define _reg_PHY_ADR0_SW_WRADDR_SHIFT 0x000000e5U +#define _reg_PHY_ADR1_SW_WRADDR_SHIFT 0x000000e6U +#define _reg_PHY_ADR2_SW_WRADDR_SHIFT 0x000000e7U +#define _reg_PHY_ADR3_SW_WRADDR_SHIFT 0x000000e8U +#define _reg_PHY_ADR4_SW_WRADDR_SHIFT 0x000000e9U +#define _reg_PHY_ADR5_SW_WRADDR_SHIFT 0x000000eaU +#define _reg_PHY_ADR_CLK_WR_BYPASS_SLAVE_DELAY 0x000000ebU +#define _reg_PHY_ADR_CLK_BYPASS_OVERRIDE 0x000000ecU +#define _reg_SC_PHY_ADR_MANUAL_CLEAR 0x000000edU +#define _reg_PHY_ADR_LPBK_RESULT_OBS 0x000000eeU +#define _reg_PHY_ADR_LPBK_ERROR_COUNT_OBS 0x000000efU +#define _reg_PHY_ADR_MASTER_DLY_LOCK_OBS_SELECT 0x000000f0U +#define _reg_PHY_ADR_MASTER_DLY_LOCK_OBS 0x000000f1U +#define _reg_PHY_ADR_BASE_SLV_DLY_ENC_OBS 0x000000f2U +#define _reg_PHY_ADR_ADDER_SLV_DLY_ENC_OBS 0x000000f3U +#define _reg_PHY_ADR_SLAVE_LOOP_CNT_UPDATE 0x000000f4U +#define _reg_PHY_ADR_SLV_DLY_ENC_OBS_SELECT 0x000000f5U +#define _reg_SC_PHY_ADR_SNAP_OBS_REGS 0x000000f6U +#define _reg_PHY_ADR_TSEL_ENABLE 0x000000f7U +#define _reg_PHY_ADR_LPBK_CONTROL 0x000000f8U +#define _reg_PHY_ADR_PRBS_PATTERN_START 0x000000f9U +#define _reg_PHY_ADR_PRBS_PATTERN_MASK 0x000000faU +#define _reg_PHY_ADR_PWR_RDC_DISABLE 0x000000fbU +#define _reg_PHY_ADR_TYPE 0x000000fcU +#define _reg_PHY_ADR_WRADDR_SHIFT_OBS 0x000000fdU +#define _reg_PHY_ADR_IE_MODE 0x000000feU +#define _reg_PHY_ADR_DDL_MODE 0x000000ffU +#define _reg_PHY_ADR_DDL_TEST_OBS 0x00000100U +#define _reg_PHY_ADR_DDL_TEST_MSTR_DLY_OBS 0x00000101U +#define _reg_PHY_ADR_CALVL_START 0x00000102U +#define _reg_PHY_ADR_CALVL_COARSE_DLY 0x00000103U +#define _reg_PHY_ADR_CALVL_QTR 0x00000104U +#define _reg_PHY_ADR_CALVL_SWIZZLE0 0x00000105U +#define _reg_PHY_ADR_CALVL_SWIZZLE1 0x00000106U +#define _reg_PHY_ADR_CALVL_SWIZZLE0_0 0x00000107U +#define _reg_PHY_ADR_CALVL_SWIZZLE1_0 0x00000108U +#define _reg_PHY_ADR_CALVL_SWIZZLE0_1 0x00000109U +#define _reg_PHY_ADR_CALVL_SWIZZLE1_1 0x0000010aU +#define _reg_PHY_ADR_CALVL_DEVICE_MAP 0x0000010bU +#define _reg_PHY_ADR_CALVL_RANK_CTRL 0x0000010cU +#define _reg_PHY_ADR_CALVL_NUM_PATTERNS 0x0000010dU +#define _reg_PHY_ADR_CALVL_CAPTURE_CNT 0x0000010eU +#define _reg_PHY_ADR_CALVL_RESP_WAIT_CNT 0x0000010fU +#define _reg_PHY_ADR_CALVL_DEBUG_MODE 0x00000110U +#define _reg_SC_PHY_ADR_CALVL_DEBUG_CONT 0x00000111U +#define _reg_SC_PHY_ADR_CALVL_ERROR_CLR 0x00000112U +#define _reg_PHY_ADR_CALVL_OBS_SELECT 0x00000113U +#define _reg_PHY_ADR_CALVL_OBS0 0x00000114U +#define _reg_PHY_ADR_CALVL_OBS1 0x00000115U +#define _reg_PHY_ADR_CALVL_RESULT 0x00000116U +#define _reg_PHY_ADR_CALVL_FG_0 0x00000117U +#define _reg_PHY_ADR_CALVL_BG_0 0x00000118U +#define _reg_PHY_ADR_CALVL_FG_1 0x00000119U +#define _reg_PHY_ADR_CALVL_BG_1 0x0000011aU +#define _reg_PHY_ADR_CALVL_FG_2 0x0000011bU +#define _reg_PHY_ADR_CALVL_BG_2 0x0000011cU +#define _reg_PHY_ADR_CALVL_FG_3 0x0000011dU +#define _reg_PHY_ADR_CALVL_BG_3 0x0000011eU +#define _reg_PHY_ADR_ADDR_SEL 0x0000011fU +#define _reg_PHY_ADR_LP4_BOOT_SLV_DELAY 0x00000120U +#define _reg_PHY_ADR_BIT_MASK 0x00000121U +#define _reg_PHY_ADR_SEG_MASK 0x00000122U +#define _reg_PHY_ADR_CALVL_TRAIN_MASK 0x00000123U +#define _reg_PHY_ADR_CSLVL_TRAIN_MASK 0x00000124U +#define _reg_PHY_ADR_SW_TXIO_CTRL 0x00000125U +#define _reg_PHY_ADR_TSEL_SELECT 0x00000126U +#define _reg_PHY_ADR0_CLK_WR_SLAVE_DELAY 0x00000127U +#define _reg_PHY_ADR1_CLK_WR_SLAVE_DELAY 0x00000128U +#define _reg_PHY_ADR2_CLK_WR_SLAVE_DELAY 0x00000129U +#define _reg_PHY_ADR3_CLK_WR_SLAVE_DELAY 0x0000012aU +#define _reg_PHY_ADR4_CLK_WR_SLAVE_DELAY 0x0000012bU +#define _reg_PHY_ADR5_CLK_WR_SLAVE_DELAY 0x0000012cU +#define _reg_PHY_ADR_SW_MASTER_MODE 0x0000012dU +#define _reg_PHY_ADR_MASTER_DELAY_START 0x0000012eU +#define _reg_PHY_ADR_MASTER_DELAY_STEP 0x0000012fU +#define _reg_PHY_ADR_MASTER_DELAY_WAIT 0x00000130U +#define _reg_PHY_ADR_MASTER_DELAY_HALF_MEASURE 0x00000131U +#define _reg_PHY_ADR_CALVL_DLY_STEP 0x00000132U +#define _reg_PHY_FREQ_SEL 0x00000133U +#define _reg_PHY_FREQ_SEL_FROM_REGIF 0x00000134U +#define _reg_PHY_FREQ_SEL_MULTICAST_EN 0x00000135U +#define _reg_PHY_FREQ_SEL_INDEX 0x00000136U +#define _reg_PHY_SW_GRP_SHIFT_0 0x00000137U +#define _reg_PHY_SW_GRP_SHIFT_1 0x00000138U +#define _reg_PHY_SW_GRP_SHIFT_2 0x00000139U +#define _reg_PHY_SW_GRP_SHIFT_3 0x0000013aU +#define _reg_PHY_GRP_BYPASS_SLAVE_DELAY 0x0000013bU +#define _reg_PHY_SW_GRP_BYPASS_SHIFT 0x0000013cU +#define _reg_PHY_GRP_BYPASS_OVERRIDE 0x0000013dU +#define _reg_SC_PHY_MANUAL_UPDATE 0x0000013eU +#define _reg_SC_PHY_MANUAL_UPDATE_PHYUPD_ENABLE 0x0000013fU +#define _reg_PHY_LP4_BOOT_DISABLE 0x00000140U +#define _reg_PHY_CSLVL_ENABLE 0x00000141U +#define _reg_PHY_CSLVL_CS_MAP 0x00000142U +#define _reg_PHY_CSLVL_START 0x00000143U +#define _reg_PHY_CSLVL_QTR 0x00000144U +#define _reg_PHY_CSLVL_COARSE_CHK 0x00000145U +#define _reg_PHY_CSLVL_CAPTURE_CNT 0x00000146U +#define _reg_PHY_CSLVL_COARSE_DLY 0x00000147U +#define _reg_PHY_CSLVL_COARSE_CAPTURE_CNT 0x00000148U +#define _reg_PHY_CSLVL_DEBUG_MODE 0x00000149U +#define _reg_SC_PHY_CSLVL_DEBUG_CONT 0x0000014aU +#define _reg_SC_PHY_CSLVL_ERROR_CLR 0x0000014bU +#define _reg_PHY_CSLVL_OBS0 0x0000014cU +#define _reg_PHY_CSLVL_OBS1 0x0000014dU +#define _reg_PHY_CALVL_CS_MAP 0x0000014eU +#define _reg_PHY_GRP_SLV_DLY_ENC_OBS_SELECT 0x0000014fU +#define _reg_PHY_GRP_SHIFT_OBS_SELECT 0x00000150U +#define _reg_PHY_GRP_SLV_DLY_ENC_OBS 0x00000151U +#define _reg_PHY_GRP_SHIFT_OBS 0x00000152U +#define _reg_PHY_ADRCTL_SLAVE_LOOP_CNT_UPDATE 0x00000153U +#define _reg_PHY_ADRCTL_SNAP_OBS_REGS 0x00000154U +#define _reg_PHY_DFI_PHYUPD_TYPE 0x00000155U +#define _reg_PHY_ADRCTL_LPDDR 0x00000156U +#define _reg_PHY_LP4_ACTIVE 0x00000157U +#define _reg_PHY_LPDDR3_CS 0x00000158U +#define _reg_PHY_CALVL_RESULT_MASK 0x00000159U +#define _reg_SC_PHY_UPDATE_CLK_CAL_VALUES 0x0000015aU +#define _reg_PHY_SW_TXIO_CTRL_0 0x0000015bU +#define _reg_PHY_SW_TXIO_CTRL_1 0x0000015cU +#define _reg_PHY_SW_TXIO_CTRL_2 0x0000015dU +#define _reg_PHY_SW_TXIO_CTRL_3 0x0000015eU +#define _reg_PHY_MEMCLK_SW_TXIO_CTRL 0x0000015fU +#define _reg_PHY_CA_SW_TXPWR_CTRL 0x00000160U +#define _reg_PHY_MEMCLK_SW_TXPWR_CTRL 0x00000161U +#define _reg_PHY_USER_DEF_REG_AC_0 0x00000162U +#define _reg_PHY_USER_DEF_REG_AC_1 0x00000163U +#define _reg_PHY_USER_DEF_REG_AC_2 0x00000164U +#define _reg_PHY_USER_DEF_REG_AC_3 0x00000165U +#define _reg_PHY_UPDATE_CLK_CAL_VALUES 0x00000166U +#define _reg_PHY_CONTINUOUS_CLK_CAL_UPDATE 0x00000167U +#define _reg_PHY_PLL_CTRL 0x00000168U +#define _reg_PHY_PLL_CTRL_TOP 0x00000169U +#define _reg_PHY_PLL_CTRL_CA 0x0000016aU +#define _reg_PHY_PLL_BYPASS 0x0000016bU +#define _reg_PHY_LOW_FREQ_SEL 0x0000016cU +#define _reg_PHY_PAD_VREF_CTRL_DQ_0 0x0000016dU +#define _reg_PHY_PAD_VREF_CTRL_DQ_1 0x0000016eU +#define _reg_PHY_PAD_VREF_CTRL_DQ_2 0x0000016fU +#define _reg_PHY_PAD_VREF_CTRL_DQ_3 0x00000170U +#define _reg_PHY_PAD_VREF_CTRL_AC 0x00000171U +#define _reg_PHY_CSLVL_DLY_STEP 0x00000172U +#define _reg_PHY_SET_DFI_INPUT_0 0x00000173U +#define _reg_PHY_SET_DFI_INPUT_1 0x00000174U +#define _reg_PHY_SET_DFI_INPUT_2 0x00000175U +#define _reg_PHY_SET_DFI_INPUT_3 0x00000176U +#define _reg_PHY_GRP_SLAVE_DELAY_0 0x00000177U +#define _reg_PHY_GRP_SLAVE_DELAY_1 0x00000178U +#define _reg_PHY_GRP_SLAVE_DELAY_2 0x00000179U +#define _reg_PHY_GRP_SLAVE_DELAY_3 0x0000017aU +#define _reg_PHY_CS_ACS_ALLOCATION_0 0x0000017bU +#define _reg_PHY_CS_ACS_ALLOCATION_1 0x0000017cU +#define _reg_PHY_CS_ACS_ALLOCATION_2 0x0000017dU +#define _reg_PHY_CS_ACS_ALLOCATION_3 0x0000017eU +#define _reg_PHY_LP4_BOOT_PLL_CTRL 0x0000017fU +#define _reg_PHY_LP4_BOOT_PLL_CTRL_CA 0x00000180U +#define _reg_PHY_LP4_BOOT_TOP_PLL_CTRL 0x00000181U +#define _reg_PHY_PLL_CTRL_OVERRIDE 0x00000182U +#define _reg_PHY_PLL_WAIT 0x00000183U +#define _reg_PHY_PLL_WAIT_TOP 0x00000184U +#define _reg_PHY_PLL_OBS_0 0x00000185U +#define _reg_PHY_PLL_OBS_1 0x00000186U +#define _reg_PHY_PLL_OBS_2 0x00000187U +#define _reg_PHY_PLL_OBS_3 0x00000188U +#define _reg_PHY_PLL_OBS_4 0x00000189U +#define _reg_PHY_PLL_TESTOUT_SEL 0x0000018aU +#define _reg_PHY_TCKSRE_WAIT 0x0000018bU +#define _reg_PHY_LP4_BOOT_LOW_FREQ_SEL 0x0000018cU +#define _reg_PHY_LP_WAKEUP 0x0000018dU +#define _reg_PHY_LS_IDLE_EN 0x0000018eU +#define _reg_PHY_LP_CTRLUPD_CNTR_CFG 0x0000018fU +#define _reg_PHY_TDFI_PHY_WRDELAY 0x00000190U +#define _reg_PHY_PAD_FDBK_DRIVE 0x00000191U +#define _reg_PHY_PAD_DATA_DRIVE 0x00000192U +#define _reg_PHY_PAD_DQS_DRIVE 0x00000193U +#define _reg_PHY_PAD_ADDR_DRIVE 0x00000194U +#define _reg_PHY_PAD_CLK_DRIVE 0x00000195U +#define _reg_PHY_PAD_FDBK_TERM 0x00000196U +#define _reg_PHY_PAD_DATA_TERM 0x00000197U +#define _reg_PHY_PAD_DQS_TERM 0x00000198U +#define _reg_PHY_PAD_ADDR_TERM 0x00000199U +#define _reg_PHY_PAD_CLK_TERM 0x0000019aU +#define _reg_PHY_PAD_CKE_DRIVE 0x0000019bU +#define _reg_PHY_PAD_CKE_TERM 0x0000019cU +#define _reg_PHY_PAD_RST_DRIVE 0x0000019dU +#define _reg_PHY_PAD_RST_TERM 0x0000019eU +#define _reg_PHY_PAD_CS_DRIVE 0x0000019fU +#define _reg_PHY_PAD_CS_TERM 0x000001a0U +#define _reg_PHY_PAD_ODT_DRIVE 0x000001a1U +#define _reg_PHY_PAD_ODT_TERM 0x000001a2U +#define _reg_PHY_ADRCTL_RX_CAL 0x000001a3U +#define _reg_PHY_ADRCTL_LP3_RX_CAL 0x000001a4U +#define _reg_PHY_TST_CLK_PAD_CTRL 0x000001a5U +#define _reg_PHY_TST_CLK_PAD_CTRL2 0x000001a6U +#define _reg_PHY_CAL_MODE_0 0x000001a7U +#define _reg_PHY_CAL_CLEAR_0 0x000001a8U +#define _reg_PHY_CAL_START_0 0x000001a9U +#define _reg_PHY_CAL_INTERVAL_COUNT_0 0x000001aaU +#define _reg_PHY_CAL_SAMPLE_WAIT_0 0x000001abU +#define _reg_PHY_LP4_BOOT_CAL_CLK_SELECT_0 0x000001acU +#define _reg_PHY_CAL_CLK_SELECT_0 0x000001adU +#define _reg_PHY_CAL_RESULT_OBS_0 0x000001aeU +#define _reg_PHY_CAL_RESULT2_OBS_0 0x000001afU +#define _reg_PHY_CAL_CPTR_CNT_0 0x000001b0U +#define _reg_PHY_CAL_SETTLING_PRD_0 0x000001b1U +#define _reg_PHY_CAL_PU_FINE_ADJ_0 0x000001b2U +#define _reg_PHY_CAL_PD_FINE_ADJ_0 0x000001b3U +#define _reg_PHY_CAL_RCV_FINE_ADJ_0 0x000001b4U +#define _reg_PHY_CAL_DBG_CFG_0 0x000001b5U +#define _reg_SC_PHY_PAD_DBG_CONT_0 0x000001b6U +#define _reg_PHY_CAL_RESULT3_OBS_0 0x000001b7U +#define _reg_PHY_ADRCTL_PVT_MAP_0 0x000001b8U +#define _reg_PHY_CAL_SLOPE_ADJ_0 0x000001b9U +#define _reg_PHY_CAL_SLOPE_ADJ_PASS2_0 0x000001baU +#define _reg_PHY_CAL_TWO_PASS_CFG_0 0x000001bbU +#define _reg_PHY_CAL_SW_CAL_CFG_0 0x000001bcU +#define _reg_PHY_CAL_RANGE_MIN_0 0x000001bdU +#define _reg_PHY_CAL_RANGE_MAX_0 0x000001beU +#define _reg_PHY_PAD_ATB_CTRL 0x000001bfU +#define _reg_PHY_ADRCTL_MANUAL_UPDATE 0x000001c0U +#define _reg_PHY_AC_LPBK_ERR_CLEAR 0x000001c1U +#define _reg_PHY_AC_LPBK_OBS_SELECT 0x000001c2U +#define _reg_PHY_AC_LPBK_ENABLE 0x000001c3U +#define _reg_PHY_AC_LPBK_CONTROL 0x000001c4U +#define _reg_PHY_AC_PRBS_PATTERN_START 0x000001c5U +#define _reg_PHY_AC_PRBS_PATTERN_MASK 0x000001c6U +#define _reg_PHY_AC_LPBK_RESULT_OBS 0x000001c7U +#define _reg_PHY_AC_CLK_LPBK_OBS_SELECT 0x000001c8U +#define _reg_PHY_AC_CLK_LPBK_ENABLE 0x000001c9U +#define _reg_PHY_AC_CLK_LPBK_CONTROL 0x000001caU +#define _reg_PHY_AC_CLK_LPBK_RESULT_OBS 0x000001cbU +#define _reg_PHY_AC_PWR_RDC_DISABLE 0x000001ccU +#define _reg_PHY_DATA_BYTE_ORDER_SEL 0x000001cdU +#define _reg_PHY_DATA_BYTE_ORDER_SEL_HIGH 0x000001ceU +#define _reg_PHY_LPDDR4_CONNECT 0x000001cfU +#define _reg_PHY_CALVL_DEVICE_MAP 0x000001d0U +#define _reg_PHY_ADR_DISABLE 0x000001d1U +#define _reg_PHY_ADRCTL_MSTR_DLY_ENC_SEL 0x000001d2U +#define _reg_PHY_CS_DLY_UPT_PER_AC_SLICE 0x000001d3U +#define _reg_PHY_DDL_AC_ENABLE 0x000001d4U +#define _reg_PHY_DDL_AC_MODE 0x000001d5U +#define _reg_PHY_PAD_BACKGROUND_CAL 0x000001d6U +#define _reg_PHY_INIT_UPDATE_CONFIG 0x000001d7U +#define _reg_PHY_DDL_TRACK_UPD_THRESHOLD_AC 0x000001d8U +#define _reg_PHY_DLL_RST_EN 0x000001d9U +#define _reg_PHY_AC_INIT_COMPLETE_OBS 0x000001daU +#define _reg_PHY_DS_INIT_COMPLETE_OBS 0x000001dbU +#define _reg_PHY_UPDATE_MASK 0x000001dcU +#define _reg_PHY_PLL_SWITCH_CNT 0x000001ddU +#define _reg_PI_START 0x000001deU +#define _reg_PI_DRAM_CLASS 0x000001dfU +#define _reg_PI_VERSION 0x000001e0U +#define _reg_PI_NORMAL_LVL_SEQ 0x000001e1U +#define _reg_PI_INIT_LVL_EN 0x000001e2U +#define _reg_PI_NOTCARE_PHYUPD 0x000001e3U +#define _reg_PI_ONBUS_MBIST 0x000001e4U +#define _reg_PI_TCMD_GAP 0x000001e5U +#define _reg_PI_MASTER_ACK_DURATION_MIN 0x000001e6U +#define _reg_PI_DFI_VERSION 0x000001e7U +#define _reg_PI_TDFI_PHYMSTR_TYPE0 0x000001e8U +#define _reg_PI_TDFI_PHYMSTR_TYPE1 0x000001e9U +#define _reg_PI_TDFI_PHYMSTR_TYPE2 0x000001eaU +#define _reg_PI_TDFI_PHYMSTR_TYPE3 0x000001ebU +#define _reg_PI_DFI_PHYMSTR_TYPE 0x000001ecU +#define _reg_PI_DFI_PHYMSTR_CS_STATE_R 0x000001edU +#define _reg_PI_DFI_PHYMSTR_STATE_SEL_R 0x000001eeU +#define _reg_PI_TDFI_PHYMSTR_MAX_F0 0x000001efU +#define _reg_PI_TDFI_PHYMSTR_RESP_F0 0x000001f0U +#define _reg_PI_TDFI_PHYMSTR_MAX_F1 0x000001f1U +#define _reg_PI_TDFI_PHYMSTR_RESP_F1 0x000001f2U +#define _reg_PI_TDFI_PHYMSTR_MAX_F2 0x000001f3U +#define _reg_PI_TDFI_PHYMSTR_RESP_F2 0x000001f4U +#define _reg_PI_TDFI_PHYUPD_RESP_F0 0x000001f5U +#define _reg_PI_TDFI_PHYUPD_TYPE0_F0 0x000001f6U +#define _reg_PI_TDFI_PHYUPD_TYPE1_F0 0x000001f7U +#define _reg_PI_TDFI_PHYUPD_TYPE2_F0 0x000001f8U +#define _reg_PI_TDFI_PHYUPD_TYPE3_F0 0x000001f9U +#define _reg_PI_TDFI_PHYUPD_RESP_F1 0x000001faU +#define _reg_PI_TDFI_PHYUPD_TYPE0_F1 0x000001fbU +#define _reg_PI_TDFI_PHYUPD_TYPE1_F1 0x000001fcU +#define _reg_PI_TDFI_PHYUPD_TYPE2_F1 0x000001fdU +#define _reg_PI_TDFI_PHYUPD_TYPE3_F1 0x000001feU +#define _reg_PI_TDFI_PHYUPD_RESP_F2 0x000001ffU +#define _reg_PI_TDFI_PHYUPD_TYPE0_F2 0x00000200U +#define _reg_PI_TDFI_PHYUPD_TYPE1_F2 0x00000201U +#define _reg_PI_TDFI_PHYUPD_TYPE2_F2 0x00000202U +#define _reg_PI_TDFI_PHYUPD_TYPE3_F2 0x00000203U +#define _reg_PI_CONTROL_ERROR_STATUS 0x00000204U +#define _reg_PI_EXIT_AFTER_INIT_CALVL 0x00000205U +#define _reg_PI_FREQ_MAP 0x00000206U +#define _reg_PI_INIT_WORK_FREQ 0x00000207U +#define _reg_PI_INIT_DFS_CALVL_ONLY 0x00000208U +#define _reg_PI_POWER_ON_SEQ_BYPASS_ARRAY 0x00000209U +#define _reg_PI_POWER_ON_SEQ_END_ARRAY 0x0000020aU +#define _reg_PI_SEQ1_PAT 0x0000020bU +#define _reg_PI_SEQ1_PAT_MASK 0x0000020cU +#define _reg_PI_SEQ2_PAT 0x0000020dU +#define _reg_PI_SEQ2_PAT_MASK 0x0000020eU +#define _reg_PI_SEQ3_PAT 0x0000020fU +#define _reg_PI_SEQ3_PAT_MASK 0x00000210U +#define _reg_PI_SEQ4_PAT 0x00000211U +#define _reg_PI_SEQ4_PAT_MASK 0x00000212U +#define _reg_PI_SEQ5_PAT 0x00000213U +#define _reg_PI_SEQ5_PAT_MASK 0x00000214U +#define _reg_PI_SEQ6_PAT 0x00000215U +#define _reg_PI_SEQ6_PAT_MASK 0x00000216U +#define _reg_PI_SEQ7_PAT 0x00000217U +#define _reg_PI_SEQ7_PAT_MASK 0x00000218U +#define _reg_PI_SEQ8_PAT 0x00000219U +#define _reg_PI_SEQ8_PAT_MASK 0x0000021aU +#define _reg_PI_WDT_DISABLE 0x0000021bU +#define _reg_PI_SW_RST_N 0x0000021cU +#define _reg_RESERVED_R0 0x0000021dU +#define _reg_PI_CS_MAP 0x0000021eU +#define _reg_PI_TDELAY_RDWR_2_BUS_IDLE_F0 0x0000021fU +#define _reg_PI_TDELAY_RDWR_2_BUS_IDLE_F1 0x00000220U +#define _reg_PI_TDELAY_RDWR_2_BUS_IDLE_F2 0x00000221U +#define _reg_PI_TMRR 0x00000222U +#define _reg_PI_WRLAT_F0 0x00000223U +#define _reg_PI_ADDITIVE_LAT_F0 0x00000224U +#define _reg_PI_CASLAT_LIN_F0 0x00000225U +#define _reg_PI_WRLAT_F1 0x00000226U +#define _reg_PI_ADDITIVE_LAT_F1 0x00000227U +#define _reg_PI_CASLAT_LIN_F1 0x00000228U +#define _reg_PI_WRLAT_F2 0x00000229U +#define _reg_PI_ADDITIVE_LAT_F2 0x0000022aU +#define _reg_PI_CASLAT_LIN_F2 0x0000022bU +#define _reg_PI_PREAMBLE_SUPPORT 0x0000022cU +#define _reg_PI_AREFRESH 0x0000022dU +#define _reg_PI_MCAREF_FORWARD_ONLY 0x0000022eU +#define _reg_PI_TRFC_F0 0x0000022fU +#define _reg_PI_TREF_F0 0x00000230U +#define _reg_PI_TRFC_F1 0x00000231U +#define _reg_PI_TREF_F1 0x00000232U +#define _reg_PI_TRFC_F2 0x00000233U +#define _reg_PI_TREF_F2 0x00000234U +#define _reg_RESERVED_H3VER2 0x00000235U +#define _reg_PI_TREF_INTERVAL 0x00000236U +#define _reg_PI_FREQ_CHANGE_REG_COPY 0x00000237U +#define _reg_PI_FREQ_SEL_FROM_REGIF 0x00000238U +#define _reg_PI_SWLVL_LOAD 0x00000239U +#define _reg_PI_SWLVL_OP_DONE 0x0000023aU +#define _reg_PI_SW_WRLVL_RESP_0 0x0000023bU +#define _reg_PI_SW_WRLVL_RESP_1 0x0000023cU +#define _reg_PI_SW_WRLVL_RESP_2 0x0000023dU +#define _reg_PI_SW_WRLVL_RESP_3 0x0000023eU +#define _reg_PI_SW_RDLVL_RESP_0 0x0000023fU +#define _reg_PI_SW_RDLVL_RESP_1 0x00000240U +#define _reg_PI_SW_RDLVL_RESP_2 0x00000241U +#define _reg_PI_SW_RDLVL_RESP_3 0x00000242U +#define _reg_PI_SW_CALVL_RESP_0 0x00000243U +#define _reg_PI_SW_LEVELING_MODE 0x00000244U +#define _reg_PI_SWLVL_START 0x00000245U +#define _reg_PI_SWLVL_EXIT 0x00000246U +#define _reg_PI_SWLVL_WR_SLICE_0 0x00000247U +#define _reg_PI_SWLVL_RD_SLICE_0 0x00000248U +#define _reg_PI_SWLVL_VREF_UPDATE_SLICE_0 0x00000249U +#define _reg_PI_SW_WDQLVL_RESP_0 0x0000024aU +#define _reg_PI_SWLVL_WR_SLICE_1 0x0000024bU +#define _reg_PI_SWLVL_RD_SLICE_1 0x0000024cU +#define _reg_PI_SWLVL_VREF_UPDATE_SLICE_1 0x0000024dU +#define _reg_PI_SW_WDQLVL_RESP_1 0x0000024eU +#define _reg_PI_SWLVL_WR_SLICE_2 0x0000024fU +#define _reg_PI_SWLVL_RD_SLICE_2 0x00000250U +#define _reg_PI_SWLVL_VREF_UPDATE_SLICE_2 0x00000251U +#define _reg_PI_SW_WDQLVL_RESP_2 0x00000252U +#define _reg_PI_SWLVL_WR_SLICE_3 0x00000253U +#define _reg_PI_SWLVL_RD_SLICE_3 0x00000254U +#define _reg_PI_SWLVL_VREF_UPDATE_SLICE_3 0x00000255U +#define _reg_PI_SW_WDQLVL_RESP_3 0x00000256U +#define _reg_PI_SW_WDQLVL_VREF 0x00000257U +#define _reg_PI_SWLVL_SM2_START 0x00000258U +#define _reg_PI_SWLVL_SM2_WR 0x00000259U +#define _reg_PI_SWLVL_SM2_RD 0x0000025aU +#define _reg_PI_SEQUENTIAL_LVL_REQ 0x0000025bU +#define _reg_PI_DFS_PERIOD_EN 0x0000025cU +#define _reg_PI_SRE_PERIOD_EN 0x0000025dU +#define _reg_PI_DFI40_POLARITY 0x0000025eU +#define _reg_PI_16BIT_DRAM_CONNECT 0x0000025fU +#define _reg_PI_TDFI_CTRL_DELAY_F0 0x00000260U +#define _reg_PI_TDFI_CTRL_DELAY_F1 0x00000261U +#define _reg_PI_TDFI_CTRL_DELAY_F2 0x00000262U +#define _reg_PI_WRLVL_REQ 0x00000263U +#define _reg_PI_WRLVL_CS 0x00000264U +#define _reg_PI_WLDQSEN 0x00000265U +#define _reg_PI_WLMRD 0x00000266U +#define _reg_PI_WRLVL_EN_F0 0x00000267U +#define _reg_PI_WRLVL_EN_F1 0x00000268U +#define _reg_PI_WRLVL_EN_F2 0x00000269U +#define _reg_PI_WRLVL_EN 0x0000026aU +#define _reg_PI_WRLVL_INTERVAL 0x0000026bU +#define _reg_PI_WRLVL_PERIODIC 0x0000026cU +#define _reg_PI_WRLVL_ON_SREF_EXIT 0x0000026dU +#define _reg_PI_WRLVL_DISABLE_DFS 0x0000026eU +#define _reg_PI_WRLVL_RESP_MASK 0x0000026fU +#define _reg_PI_WRLVL_ROTATE 0x00000270U +#define _reg_PI_WRLVL_CS_MAP 0x00000271U +#define _reg_PI_WRLVL_ERROR_STATUS 0x00000272U +#define _reg_PI_TDFI_WRLVL_EN 0x00000273U +#define _reg_PI_TDFI_WRLVL_WW_F0 0x00000274U +#define _reg_PI_TDFI_WRLVL_WW_F1 0x00000275U +#define _reg_PI_TDFI_WRLVL_WW_F2 0x00000276U +#define _reg_PI_TDFI_WRLVL_WW 0x00000277U +#define _reg_PI_TDFI_WRLVL_RESP 0x00000278U +#define _reg_PI_TDFI_WRLVL_MAX 0x00000279U +#define _reg_PI_WRLVL_STROBE_NUM 0x0000027aU +#define _reg_PI_WRLVL_MRR_DQ_RETURN_HIZ 0x0000027bU +#define _reg_PI_WRLVL_EN_DEASSERT_2_MRR 0x0000027cU +#define _reg_PI_TODTL_2CMD_F0 0x0000027dU +#define _reg_PI_ODT_EN_F0 0x0000027eU +#define _reg_PI_TODTL_2CMD_F1 0x0000027fU +#define _reg_PI_ODT_EN_F1 0x00000280U +#define _reg_PI_TODTL_2CMD_F2 0x00000281U +#define _reg_PI_ODT_EN_F2 0x00000282U +#define _reg_PI_TODTH_WR 0x00000283U +#define _reg_PI_TODTH_RD 0x00000284U +#define _reg_PI_ODT_RD_MAP_CS0 0x00000285U +#define _reg_PI_ODT_WR_MAP_CS0 0x00000286U +#define _reg_PI_ODT_RD_MAP_CS1 0x00000287U +#define _reg_PI_ODT_WR_MAP_CS1 0x00000288U +#define _reg_PI_ODT_RD_MAP_CS2 0x00000289U +#define _reg_PI_ODT_WR_MAP_CS2 0x0000028aU +#define _reg_PI_ODT_RD_MAP_CS3 0x0000028bU +#define _reg_PI_ODT_WR_MAP_CS3 0x0000028cU +#define _reg_PI_EN_ODT_ASSERT_EXCEPT_RD 0x0000028dU +#define _reg_PI_ODTLON_F0 0x0000028eU +#define _reg_PI_TODTON_MIN_F0 0x0000028fU +#define _reg_PI_ODTLON_F1 0x00000290U +#define _reg_PI_TODTON_MIN_F1 0x00000291U +#define _reg_PI_ODTLON_F2 0x00000292U +#define _reg_PI_TODTON_MIN_F2 0x00000293U +#define _reg_PI_WR_TO_ODTH_F0 0x00000294U +#define _reg_PI_WR_TO_ODTH_F1 0x00000295U +#define _reg_PI_WR_TO_ODTH_F2 0x00000296U +#define _reg_PI_RD_TO_ODTH_F0 0x00000297U +#define _reg_PI_RD_TO_ODTH_F1 0x00000298U +#define _reg_PI_RD_TO_ODTH_F2 0x00000299U +#define _reg_PI_ADDRESS_MIRRORING 0x0000029aU +#define _reg_PI_RDLVL_REQ 0x0000029bU +#define _reg_PI_RDLVL_GATE_REQ 0x0000029cU +#define _reg_PI_RDLVL_CS 0x0000029dU +#define _reg_PI_RDLVL_PAT_0 0x0000029eU +#define _reg_PI_RDLVL_PAT_1 0x0000029fU +#define _reg_PI_RDLVL_PAT_2 0x000002a0U +#define _reg_PI_RDLVL_PAT_3 0x000002a1U +#define _reg_PI_RDLVL_PAT_4 0x000002a2U +#define _reg_PI_RDLVL_PAT_5 0x000002a3U +#define _reg_PI_RDLVL_PAT_6 0x000002a4U +#define _reg_PI_RDLVL_PAT_7 0x000002a5U +#define _reg_PI_RDLVL_SEQ_EN 0x000002a6U +#define _reg_PI_RDLVL_GATE_SEQ_EN 0x000002a7U +#define _reg_PI_RDLVL_PERIODIC 0x000002a8U +#define _reg_PI_RDLVL_ON_SREF_EXIT 0x000002a9U +#define _reg_PI_RDLVL_DISABLE_DFS 0x000002aaU +#define _reg_PI_RDLVL_GATE_PERIODIC 0x000002abU +#define _reg_PI_RDLVL_GATE_ON_SREF_EXIT 0x000002acU +#define _reg_PI_RDLVL_GATE_DISABLE_DFS 0x000002adU +#define _reg_RESERVED_R1 0x000002aeU +#define _reg_PI_RDLVL_ROTATE 0x000002afU +#define _reg_PI_RDLVL_GATE_ROTATE 0x000002b0U +#define _reg_PI_RDLVL_CS_MAP 0x000002b1U +#define _reg_PI_RDLVL_GATE_CS_MAP 0x000002b2U +#define _reg_PI_TDFI_RDLVL_RR 0x000002b3U +#define _reg_PI_TDFI_RDLVL_RESP 0x000002b4U +#define _reg_PI_RDLVL_RESP_MASK 0x000002b5U +#define _reg_PI_TDFI_RDLVL_EN 0x000002b6U +#define _reg_PI_RDLVL_EN_F0 0x000002b7U +#define _reg_PI_RDLVL_GATE_EN_F0 0x000002b8U +#define _reg_PI_RDLVL_EN_F1 0x000002b9U +#define _reg_PI_RDLVL_GATE_EN_F1 0x000002baU +#define _reg_PI_RDLVL_EN_F2 0x000002bbU +#define _reg_PI_RDLVL_GATE_EN_F2 0x000002bcU +#define _reg_PI_RDLVL_EN 0x000002bdU +#define _reg_PI_RDLVL_GATE_EN 0x000002beU +#define _reg_PI_TDFI_RDLVL_MAX 0x000002bfU +#define _reg_PI_RDLVL_ERROR_STATUS 0x000002c0U +#define _reg_PI_RDLVL_INTERVAL 0x000002c1U +#define _reg_PI_RDLVL_GATE_INTERVAL 0x000002c2U +#define _reg_PI_RDLVL_PATTERN_START 0x000002c3U +#define _reg_PI_RDLVL_PATTERN_NUM 0x000002c4U +#define _reg_PI_RDLVL_STROBE_NUM 0x000002c5U +#define _reg_PI_RDLVL_GATE_STROBE_NUM 0x000002c6U +#define _reg_PI_LPDDR4_RDLVL_PATTERN_8 0x000002c7U +#define _reg_PI_LPDDR4_RDLVL_PATTERN_9 0x000002c8U +#define _reg_PI_LPDDR4_RDLVL_PATTERN_10 0x000002c9U +#define _reg_PI_LPDDR4_RDLVL_PATTERN_11 0x000002caU +#define _reg_PI_RD_PREAMBLE_TRAINING_EN 0x000002cbU +#define _reg_PI_REG_DIMM_ENABLE 0x000002ccU +#define _reg_PI_RDLAT_ADJ_F0 0x000002cdU +#define _reg_PI_RDLAT_ADJ_F1 0x000002ceU +#define _reg_PI_RDLAT_ADJ_F2 0x000002cfU +#define _reg_PI_TDFI_RDDATA_EN 0x000002d0U +#define _reg_PI_WRLAT_ADJ_F0 0x000002d1U +#define _reg_PI_WRLAT_ADJ_F1 0x000002d2U +#define _reg_PI_WRLAT_ADJ_F2 0x000002d3U +#define _reg_PI_TDFI_PHY_WRLAT 0x000002d4U +#define _reg_PI_TDFI_WRCSLAT_F0 0x000002d5U +#define _reg_PI_TDFI_WRCSLAT_F1 0x000002d6U +#define _reg_PI_TDFI_WRCSLAT_F2 0x000002d7U +#define _reg_PI_TDFI_RDCSLAT_F0 0x000002d8U +#define _reg_PI_TDFI_RDCSLAT_F1 0x000002d9U +#define _reg_PI_TDFI_RDCSLAT_F2 0x000002daU +#define _reg_PI_TDFI_PHY_WRDATA_F0 0x000002dbU +#define _reg_PI_TDFI_PHY_WRDATA_F1 0x000002dcU +#define _reg_PI_TDFI_PHY_WRDATA_F2 0x000002ddU +#define _reg_PI_TDFI_PHY_WRDATA 0x000002deU +#define _reg_PI_CALVL_REQ 0x000002dfU +#define _reg_PI_CALVL_CS 0x000002e0U +#define _reg_RESERVED_R2 0x000002e1U +#define _reg_RESERVED_R3 0x000002e2U +#define _reg_PI_CALVL_SEQ_EN 0x000002e3U +#define _reg_PI_CALVL_PERIODIC 0x000002e4U +#define _reg_PI_CALVL_ON_SREF_EXIT 0x000002e5U +#define _reg_PI_CALVL_DISABLE_DFS 0x000002e6U +#define _reg_PI_CALVL_ROTATE 0x000002e7U +#define _reg_PI_CALVL_CS_MAP 0x000002e8U +#define _reg_PI_TDFI_CALVL_EN 0x000002e9U +#define _reg_PI_TDFI_CALVL_CC_F0 0x000002eaU +#define _reg_PI_TDFI_CALVL_CAPTURE_F0 0x000002ebU +#define _reg_PI_TDFI_CALVL_CC_F1 0x000002ecU +#define _reg_PI_TDFI_CALVL_CAPTURE_F1 0x000002edU +#define _reg_PI_TDFI_CALVL_CC_F2 0x000002eeU +#define _reg_PI_TDFI_CALVL_CAPTURE_F2 0x000002efU +#define _reg_PI_TDFI_CALVL_RESP 0x000002f0U +#define _reg_PI_TDFI_CALVL_MAX 0x000002f1U +#define _reg_PI_CALVL_RESP_MASK 0x000002f2U +#define _reg_PI_CALVL_EN_F0 0x000002f3U +#define _reg_PI_CALVL_EN_F1 0x000002f4U +#define _reg_PI_CALVL_EN_F2 0x000002f5U +#define _reg_PI_CALVL_EN 0x000002f6U +#define _reg_PI_CALVL_ERROR_STATUS 0x000002f7U +#define _reg_PI_CALVL_INTERVAL 0x000002f8U +#define _reg_PI_TCACKEL 0x000002f9U +#define _reg_PI_TCAMRD 0x000002faU +#define _reg_PI_TCACKEH 0x000002fbU +#define _reg_PI_TMRZ_F0 0x000002fcU +#define _reg_PI_TCAENT_F0 0x000002fdU +#define _reg_PI_TMRZ_F1 0x000002feU +#define _reg_PI_TCAENT_F1 0x000002ffU +#define _reg_PI_TMRZ_F2 0x00000300U +#define _reg_PI_TCAENT_F2 0x00000301U +#define _reg_PI_TCAEXT 0x00000302U +#define _reg_PI_CA_TRAIN_VREF_EN 0x00000303U +#define _reg_PI_TDFI_CACSCA_F0 0x00000304U +#define _reg_PI_TDFI_CASEL_F0 0x00000305U +#define _reg_PI_TVREF_SHORT_F0 0x00000306U +#define _reg_PI_TVREF_LONG_F0 0x00000307U +#define _reg_PI_TDFI_CACSCA_F1 0x00000308U +#define _reg_PI_TDFI_CASEL_F1 0x00000309U +#define _reg_PI_TVREF_SHORT_F1 0x0000030aU +#define _reg_PI_TVREF_LONG_F1 0x0000030bU +#define _reg_PI_TDFI_CACSCA_F2 0x0000030cU +#define _reg_PI_TDFI_CASEL_F2 0x0000030dU +#define _reg_PI_TVREF_SHORT_F2 0x0000030eU +#define _reg_PI_TVREF_LONG_F2 0x0000030fU +#define _reg_PI_CALVL_VREF_INITIAL_START_POINT_F0 0x00000310U +#define _reg_PI_CALVL_VREF_INITIAL_STOP_POINT_F0 0x00000311U +#define _reg_PI_CALVL_VREF_INITIAL_START_POINT_F1 0x00000312U +#define _reg_PI_CALVL_VREF_INITIAL_STOP_POINT_F1 0x00000313U +#define _reg_PI_CALVL_VREF_INITIAL_START_POINT_F2 0x00000314U +#define _reg_PI_CALVL_VREF_INITIAL_STOP_POINT_F2 0x00000315U +#define _reg_PI_CALVL_VREF_INITIAL_START_POINT 0x00000316U +#define _reg_PI_CALVL_VREF_INITIAL_STOP_POINT 0x00000317U +#define _reg_PI_CALVL_VREF_INITIAL_STEPSIZE 0x00000318U +#define _reg_PI_CALVL_VREF_NORMAL_STEPSIZE 0x00000319U +#define _reg_PI_CALVL_VREF_DELTA_F0 0x0000031aU +#define _reg_PI_CALVL_VREF_DELTA_F1 0x0000031bU +#define _reg_PI_CALVL_VREF_DELTA_F2 0x0000031cU +#define _reg_PI_CALVL_VREF_DELTA 0x0000031dU +#define _reg_PI_TDFI_INIT_START_MIN 0x0000031eU +#define _reg_PI_TDFI_INIT_COMPLETE_MIN 0x0000031fU +#define _reg_PI_TDFI_CALVL_STROBE_F0 0x00000320U +#define _reg_PI_TXP_F0 0x00000321U +#define _reg_PI_TMRWCKEL_F0 0x00000322U +#define _reg_PI_TCKELCK_F0 0x00000323U +#define _reg_PI_TDFI_CALVL_STROBE_F1 0x00000324U +#define _reg_PI_TXP_F1 0x00000325U +#define _reg_PI_TMRWCKEL_F1 0x00000326U +#define _reg_PI_TCKELCK_F1 0x00000327U +#define _reg_PI_TDFI_CALVL_STROBE_F2 0x00000328U +#define _reg_PI_TXP_F2 0x00000329U +#define _reg_PI_TMRWCKEL_F2 0x0000032aU +#define _reg_PI_TCKELCK_F2 0x0000032bU +#define _reg_PI_TCKCKEH 0x0000032cU +#define _reg_PI_CALVL_STROBE_NUM 0x0000032dU +#define _reg_PI_SW_CA_TRAIN_VREF 0x0000032eU +#define _reg_PI_TDFI_INIT_START_F0 0x0000032fU +#define _reg_PI_TDFI_INIT_COMPLETE_F0 0x00000330U +#define _reg_PI_TDFI_INIT_START_F1 0x00000331U +#define _reg_PI_TDFI_INIT_COMPLETE_F1 0x00000332U +#define _reg_PI_TDFI_INIT_START_F2 0x00000333U +#define _reg_PI_TDFI_INIT_COMPLETE_F2 0x00000334U +#define _reg_PI_CLKDISABLE_2_INIT_START 0x00000335U +#define _reg_PI_INIT_STARTORCOMPLETE_2_CLKDISABLE 0x00000336U +#define _reg_PI_DRAM_CLK_DISABLE_DEASSERT_SEL 0x00000337U +#define _reg_PI_REFRESH_BETWEEN_SEGMENT_DISABLE 0x00000338U +#define _reg_PI_TCKEHDQS_F0 0x00000339U +#define _reg_PI_TCKEHDQS_F1 0x0000033aU +#define _reg_PI_TCKEHDQS_F2 0x0000033bU +#define _reg_PI_MC_DFS_PI_SET_VREF_ENABLE 0x0000033cU +#define _reg_PI_WDQLVL_VREF_EN 0x0000033dU +#define _reg_PI_WDQLVL_BST_NUM 0x0000033eU +#define _reg_PI_TDFI_WDQLVL_WR_F0 0x0000033fU +#define _reg_PI_TDFI_WDQLVL_WR_F1 0x00000340U +#define _reg_PI_TDFI_WDQLVL_WR_F2 0x00000341U +#define _reg_PI_TDFI_WDQLVL_WR 0x00000342U +#define _reg_PI_TDFI_WDQLVL_RW 0x00000343U +#define _reg_PI_WDQLVL_RESP_MASK 0x00000344U +#define _reg_PI_WDQLVL_ROTATE 0x00000345U +#define _reg_PI_WDQLVL_CS_MAP 0x00000346U +#define _reg_PI_WDQLVL_VREF_INITIAL_START_POINT_F0 0x00000347U +#define _reg_PI_WDQLVL_VREF_INITIAL_STOP_POINT_F0 0x00000348U +#define _reg_PI_WDQLVL_VREF_INITIAL_START_POINT_F1 0x00000349U +#define _reg_PI_WDQLVL_VREF_INITIAL_STOP_POINT_F1 0x0000034aU +#define _reg_PI_WDQLVL_VREF_INITIAL_START_POINT_F2 0x0000034bU +#define _reg_PI_WDQLVL_VREF_INITIAL_STOP_POINT_F2 0x0000034cU +#define _reg_PI_WDQLVL_VREF_INITIAL_START_POINT 0x0000034dU +#define _reg_PI_WDQLVL_VREF_INITIAL_STOP_POINT 0x0000034eU +#define _reg_PI_WDQLVL_VREF_INITIAL_STEPSIZE 0x0000034fU +#define _reg_PI_WDQLVL_VREF_NORMAL_STEPSIZE 0x00000350U +#define _reg_PI_WDQLVL_VREF_DELTA_F0 0x00000351U +#define _reg_PI_WDQLVL_VREF_DELTA_F1 0x00000352U +#define _reg_PI_WDQLVL_VREF_DELTA_F2 0x00000353U +#define _reg_PI_WDQLVL_VREF_DELTA 0x00000354U +#define _reg_PI_WDQLVL_PERIODIC 0x00000355U +#define _reg_PI_WDQLVL_REQ 0x00000356U +#define _reg_PI_WDQLVL_CS 0x00000357U +#define _reg_PI_TDFI_WDQLVL_EN 0x00000358U +#define _reg_PI_TDFI_WDQLVL_RESP 0x00000359U +#define _reg_PI_TDFI_WDQLVL_MAX 0x0000035aU +#define _reg_PI_WDQLVL_INTERVAL 0x0000035bU +#define _reg_PI_WDQLVL_EN_F0 0x0000035cU +#define _reg_PI_WDQLVL_EN_F1 0x0000035dU +#define _reg_PI_WDQLVL_EN_F2 0x0000035eU +#define _reg_PI_WDQLVL_EN 0x0000035fU +#define _reg_PI_WDQLVL_ON_SREF_EXIT 0x00000360U +#define _reg_PI_WDQLVL_DISABLE_DFS 0x00000361U +#define _reg_PI_WDQLVL_ERROR_STATUS 0x00000362U +#define _reg_PI_MR1_DATA_F0_0 0x00000363U +#define _reg_PI_MR2_DATA_F0_0 0x00000364U +#define _reg_PI_MR3_DATA_F0_0 0x00000365U +#define _reg_PI_MR11_DATA_F0_0 0x00000366U +#define _reg_PI_MR12_DATA_F0_0 0x00000367U +#define _reg_PI_MR14_DATA_F0_0 0x00000368U +#define _reg_PI_MR22_DATA_F0_0 0x00000369U +#define _reg_PI_MR1_DATA_F1_0 0x0000036aU +#define _reg_PI_MR2_DATA_F1_0 0x0000036bU +#define _reg_PI_MR3_DATA_F1_0 0x0000036cU +#define _reg_PI_MR11_DATA_F1_0 0x0000036dU +#define _reg_PI_MR12_DATA_F1_0 0x0000036eU +#define _reg_PI_MR14_DATA_F1_0 0x0000036fU +#define _reg_PI_MR22_DATA_F1_0 0x00000370U +#define _reg_PI_MR1_DATA_F2_0 0x00000371U +#define _reg_PI_MR2_DATA_F2_0 0x00000372U +#define _reg_PI_MR3_DATA_F2_0 0x00000373U +#define _reg_PI_MR11_DATA_F2_0 0x00000374U +#define _reg_PI_MR12_DATA_F2_0 0x00000375U +#define _reg_PI_MR14_DATA_F2_0 0x00000376U +#define _reg_PI_MR22_DATA_F2_0 0x00000377U +#define _reg_PI_MR13_DATA_0 0x00000378U +#define _reg_PI_MR1_DATA_F0_1 0x00000379U +#define _reg_PI_MR2_DATA_F0_1 0x0000037aU +#define _reg_PI_MR3_DATA_F0_1 0x0000037bU +#define _reg_PI_MR11_DATA_F0_1 0x0000037cU +#define _reg_PI_MR12_DATA_F0_1 0x0000037dU +#define _reg_PI_MR14_DATA_F0_1 0x0000037eU +#define _reg_PI_MR22_DATA_F0_1 0x0000037fU +#define _reg_PI_MR1_DATA_F1_1 0x00000380U +#define _reg_PI_MR2_DATA_F1_1 0x00000381U +#define _reg_PI_MR3_DATA_F1_1 0x00000382U +#define _reg_PI_MR11_DATA_F1_1 0x00000383U +#define _reg_PI_MR12_DATA_F1_1 0x00000384U +#define _reg_PI_MR14_DATA_F1_1 0x00000385U +#define _reg_PI_MR22_DATA_F1_1 0x00000386U +#define _reg_PI_MR1_DATA_F2_1 0x00000387U +#define _reg_PI_MR2_DATA_F2_1 0x00000388U +#define _reg_PI_MR3_DATA_F2_1 0x00000389U +#define _reg_PI_MR11_DATA_F2_1 0x0000038aU +#define _reg_PI_MR12_DATA_F2_1 0x0000038bU +#define _reg_PI_MR14_DATA_F2_1 0x0000038cU +#define _reg_PI_MR22_DATA_F2_1 0x0000038dU +#define _reg_PI_MR13_DATA_1 0x0000038eU +#define _reg_PI_MR1_DATA_F0_2 0x0000038fU +#define _reg_PI_MR2_DATA_F0_2 0x00000390U +#define _reg_PI_MR3_DATA_F0_2 0x00000391U +#define _reg_PI_MR11_DATA_F0_2 0x00000392U +#define _reg_PI_MR12_DATA_F0_2 0x00000393U +#define _reg_PI_MR14_DATA_F0_2 0x00000394U +#define _reg_PI_MR22_DATA_F0_2 0x00000395U +#define _reg_PI_MR1_DATA_F1_2 0x00000396U +#define _reg_PI_MR2_DATA_F1_2 0x00000397U +#define _reg_PI_MR3_DATA_F1_2 0x00000398U +#define _reg_PI_MR11_DATA_F1_2 0x00000399U +#define _reg_PI_MR12_DATA_F1_2 0x0000039aU +#define _reg_PI_MR14_DATA_F1_2 0x0000039bU +#define _reg_PI_MR22_DATA_F1_2 0x0000039cU +#define _reg_PI_MR1_DATA_F2_2 0x0000039dU +#define _reg_PI_MR2_DATA_F2_2 0x0000039eU +#define _reg_PI_MR3_DATA_F2_2 0x0000039fU +#define _reg_PI_MR11_DATA_F2_2 0x000003a0U +#define _reg_PI_MR12_DATA_F2_2 0x000003a1U +#define _reg_PI_MR14_DATA_F2_2 0x000003a2U +#define _reg_PI_MR22_DATA_F2_2 0x000003a3U +#define _reg_PI_MR13_DATA_2 0x000003a4U +#define _reg_PI_MR1_DATA_F0_3 0x000003a5U +#define _reg_PI_MR2_DATA_F0_3 0x000003a6U +#define _reg_PI_MR3_DATA_F0_3 0x000003a7U +#define _reg_PI_MR11_DATA_F0_3 0x000003a8U +#define _reg_PI_MR12_DATA_F0_3 0x000003a9U +#define _reg_PI_MR14_DATA_F0_3 0x000003aaU +#define _reg_PI_MR22_DATA_F0_3 0x000003abU +#define _reg_PI_MR1_DATA_F1_3 0x000003acU +#define _reg_PI_MR2_DATA_F1_3 0x000003adU +#define _reg_PI_MR3_DATA_F1_3 0x000003aeU +#define _reg_PI_MR11_DATA_F1_3 0x000003afU +#define _reg_PI_MR12_DATA_F1_3 0x000003b0U +#define _reg_PI_MR14_DATA_F1_3 0x000003b1U +#define _reg_PI_MR22_DATA_F1_3 0x000003b2U +#define _reg_PI_MR1_DATA_F2_3 0x000003b3U +#define _reg_PI_MR2_DATA_F2_3 0x000003b4U +#define _reg_PI_MR3_DATA_F2_3 0x000003b5U +#define _reg_PI_MR11_DATA_F2_3 0x000003b6U +#define _reg_PI_MR12_DATA_F2_3 0x000003b7U +#define _reg_PI_MR14_DATA_F2_3 0x000003b8U +#define _reg_PI_MR22_DATA_F2_3 0x000003b9U +#define _reg_PI_MR13_DATA_3 0x000003baU +#define _reg_PI_BANK_DIFF 0x000003bbU +#define _reg_PI_ROW_DIFF 0x000003bcU +#define _reg_PI_TFC_F0 0x000003bdU +#define _reg_PI_TFC_F1 0x000003beU +#define _reg_PI_TFC_F2 0x000003bfU +#define _reg_PI_TCCD 0x000003c0U +#define _reg_PI_TRTP_F0 0x000003c1U +#define _reg_PI_TRP_F0 0x000003c2U +#define _reg_PI_TRCD_F0 0x000003c3U +#define _reg_PI_TWTR_F0 0x000003c4U +#define _reg_PI_TWR_F0 0x000003c5U +#define _reg_PI_TRAS_MAX_F0 0x000003c6U +#define _reg_PI_TRAS_MIN_F0 0x000003c7U +#define _reg_PI_TDQSCK_MAX_F0 0x000003c8U +#define _reg_PI_TCCDMW_F0 0x000003c9U +#define _reg_PI_TSR_F0 0x000003caU +#define _reg_PI_TMRD_F0 0x000003cbU +#define _reg_PI_TMRW_F0 0x000003ccU +#define _reg_PI_TMOD_F0 0x000003cdU +#define _reg_PI_TRTP_F1 0x000003ceU +#define _reg_PI_TRP_F1 0x000003cfU +#define _reg_PI_TRCD_F1 0x000003d0U +#define _reg_PI_TWTR_F1 0x000003d1U +#define _reg_PI_TWR_F1 0x000003d2U +#define _reg_PI_TRAS_MAX_F1 0x000003d3U +#define _reg_PI_TRAS_MIN_F1 0x000003d4U +#define _reg_PI_TDQSCK_MAX_F1 0x000003d5U +#define _reg_PI_TCCDMW_F1 0x000003d6U +#define _reg_PI_TSR_F1 0x000003d7U +#define _reg_PI_TMRD_F1 0x000003d8U +#define _reg_PI_TMRW_F1 0x000003d9U +#define _reg_PI_TMOD_F1 0x000003daU +#define _reg_PI_TRTP_F2 0x000003dbU +#define _reg_PI_TRP_F2 0x000003dcU +#define _reg_PI_TRCD_F2 0x000003ddU +#define _reg_PI_TWTR_F2 0x000003deU +#define _reg_PI_TWR_F2 0x000003dfU +#define _reg_PI_TRAS_MAX_F2 0x000003e0U +#define _reg_PI_TRAS_MIN_F2 0x000003e1U +#define _reg_PI_TDQSCK_MAX_F2 0x000003e2U +#define _reg_PI_TCCDMW_F2 0x000003e3U +#define _reg_PI_TSR_F2 0x000003e4U +#define _reg_PI_TMRD_F2 0x000003e5U +#define _reg_PI_TMRW_F2 0x000003e6U +#define _reg_PI_TMOD_F2 0x000003e7U +#define _reg_RESERVED_R4 0x000003e8U +#define _reg_RESERVED_R5 0x000003e9U +#define _reg_RESERVED_R6 0x000003eaU +#define _reg_RESERVED_R7 0x000003ebU +#define _reg_RESERVED_R8 0x000003ecU +#define _reg_RESERVED_R9 0x000003edU +#define _reg_RESERVED_R10 0x000003eeU +#define _reg_RESERVED_R11 0x000003efU +#define _reg_RESERVED_R12 0x000003f0U +#define _reg_RESERVED_R13 0x000003f1U +#define _reg_RESERVED_R14 0x000003f2U +#define _reg_RESERVED_R15 0x000003f3U +#define _reg_RESERVED_R16 0x000003f4U +#define _reg_RESERVED_R17 0x000003f5U +#define _reg_RESERVED_R18 0x000003f6U +#define _reg_RESERVED_R19 0x000003f7U +#define _reg_RESERVED_R20 0x000003f8U +#define _reg_RESERVED_R21 0x000003f9U +#define _reg_RESERVED_R22 0x000003faU +#define _reg_RESERVED_R23 0x000003fbU +#define _reg_PI_INT_STATUS 0x000003fcU +#define _reg_PI_INT_ACK 0x000003fdU +#define _reg_PI_INT_MASK 0x000003feU +#define _reg_PI_BIST_EXP_DATA_P0 0x000003ffU +#define _reg_PI_BIST_EXP_DATA_P1 0x00000400U +#define _reg_PI_BIST_EXP_DATA_P2 0x00000401U +#define _reg_PI_BIST_EXP_DATA_P3 0x00000402U +#define _reg_PI_BIST_FAIL_DATA_P0 0x00000403U +#define _reg_PI_BIST_FAIL_DATA_P1 0x00000404U +#define _reg_PI_BIST_FAIL_DATA_P2 0x00000405U +#define _reg_PI_BIST_FAIL_DATA_P3 0x00000406U +#define _reg_PI_BIST_FAIL_ADDR_P0 0x00000407U +#define _reg_PI_BIST_FAIL_ADDR_P1 0x00000408U +#define _reg_PI_BSTLEN 0x00000409U +#define _reg_PI_LONG_COUNT_MASK 0x0000040aU +#define _reg_PI_CMD_SWAP_EN 0x0000040bU +#define _reg_PI_CKE_MUX_0 0x0000040cU +#define _reg_PI_CKE_MUX_1 0x0000040dU +#define _reg_PI_CKE_MUX_2 0x0000040eU +#define _reg_PI_CKE_MUX_3 0x0000040fU +#define _reg_PI_CS_MUX_0 0x00000410U +#define _reg_PI_CS_MUX_1 0x00000411U +#define _reg_PI_CS_MUX_2 0x00000412U +#define _reg_PI_CS_MUX_3 0x00000413U +#define _reg_PI_RAS_N_MUX 0x00000414U +#define _reg_PI_CAS_N_MUX 0x00000415U +#define _reg_PI_WE_N_MUX 0x00000416U +#define _reg_PI_BANK_MUX_0 0x00000417U +#define _reg_PI_BANK_MUX_1 0x00000418U +#define _reg_PI_BANK_MUX_2 0x00000419U +#define _reg_PI_ODT_MUX_0 0x0000041aU +#define _reg_PI_ODT_MUX_1 0x0000041bU +#define _reg_PI_ODT_MUX_2 0x0000041cU +#define _reg_PI_ODT_MUX_3 0x0000041dU +#define _reg_PI_RESET_N_MUX_0 0x0000041eU +#define _reg_PI_RESET_N_MUX_1 0x0000041fU +#define _reg_PI_RESET_N_MUX_2 0x00000420U +#define _reg_PI_RESET_N_MUX_3 0x00000421U +#define _reg_PI_DATA_BYTE_SWAP_EN 0x00000422U +#define _reg_PI_DATA_BYTE_SWAP_SLICE0 0x00000423U +#define _reg_PI_DATA_BYTE_SWAP_SLICE1 0x00000424U +#define _reg_PI_DATA_BYTE_SWAP_SLICE2 0x00000425U +#define _reg_PI_DATA_BYTE_SWAP_SLICE3 0x00000426U +#define _reg_PI_CTRLUPD_REQ_PER_AREF_EN 0x00000427U +#define _reg_PI_TDFI_CTRLUPD_MIN 0x00000428U +#define _reg_PI_TDFI_CTRLUPD_MAX_F0 0x00000429U +#define _reg_PI_TDFI_CTRLUPD_INTERVAL_F0 0x0000042aU +#define _reg_PI_TDFI_CTRLUPD_MAX_F1 0x0000042bU +#define _reg_PI_TDFI_CTRLUPD_INTERVAL_F1 0x0000042cU +#define _reg_PI_TDFI_CTRLUPD_MAX_F2 0x0000042dU +#define _reg_PI_TDFI_CTRLUPD_INTERVAL_F2 0x0000042eU +#define _reg_PI_UPDATE_ERROR_STATUS 0x0000042fU +#define _reg_PI_BIST_GO 0x00000430U +#define _reg_PI_BIST_RESULT 0x00000431U +#define _reg_PI_ADDR_SPACE 0x00000432U +#define _reg_PI_BIST_DATA_CHECK 0x00000433U +#define _reg_PI_BIST_ADDR_CHECK 0x00000434U +#define _reg_PI_BIST_START_ADDRESS_P0 0x00000435U +#define _reg_PI_BIST_START_ADDRESS_P1 0x00000436U +#define _reg_PI_BIST_DATA_MASK_P0 0x00000437U +#define _reg_PI_BIST_DATA_MASK_P1 0x00000438U +#define _reg_PI_BIST_ERR_COUNT 0x00000439U +#define _reg_PI_BIST_ERR_STOP 0x0000043aU +#define _reg_PI_BIST_ADDR_MASK_0_P0 0x0000043bU +#define _reg_PI_BIST_ADDR_MASK_0_P1 0x0000043cU +#define _reg_PI_BIST_ADDR_MASK_1_P0 0x0000043dU +#define _reg_PI_BIST_ADDR_MASK_1_P1 0x0000043eU +#define _reg_PI_BIST_ADDR_MASK_2_P0 0x0000043fU +#define _reg_PI_BIST_ADDR_MASK_2_P1 0x00000440U +#define _reg_PI_BIST_ADDR_MASK_3_P0 0x00000441U +#define _reg_PI_BIST_ADDR_MASK_3_P1 0x00000442U +#define _reg_PI_BIST_ADDR_MASK_4_P0 0x00000443U +#define _reg_PI_BIST_ADDR_MASK_4_P1 0x00000444U +#define _reg_PI_BIST_ADDR_MASK_5_P0 0x00000445U +#define _reg_PI_BIST_ADDR_MASK_5_P1 0x00000446U +#define _reg_PI_BIST_ADDR_MASK_6_P0 0x00000447U +#define _reg_PI_BIST_ADDR_MASK_6_P1 0x00000448U +#define _reg_PI_BIST_ADDR_MASK_7_P0 0x00000449U +#define _reg_PI_BIST_ADDR_MASK_7_P1 0x0000044aU +#define _reg_PI_BIST_ADDR_MASK_8_P0 0x0000044bU +#define _reg_PI_BIST_ADDR_MASK_8_P1 0x0000044cU +#define _reg_PI_BIST_ADDR_MASK_9_P0 0x0000044dU +#define _reg_PI_BIST_ADDR_MASK_9_P1 0x0000044eU +#define _reg_PI_BIST_MODE 0x0000044fU +#define _reg_PI_BIST_ADDR_MODE 0x00000450U +#define _reg_PI_BIST_PAT_MODE 0x00000451U +#define _reg_PI_BIST_USER_PAT_P0 0x00000452U +#define _reg_PI_BIST_USER_PAT_P1 0x00000453U +#define _reg_PI_BIST_USER_PAT_P2 0x00000454U +#define _reg_PI_BIST_USER_PAT_P3 0x00000455U +#define _reg_PI_BIST_PAT_NUM 0x00000456U +#define _reg_PI_BIST_STAGE_0 0x00000457U +#define _reg_PI_BIST_STAGE_1 0x00000458U +#define _reg_PI_BIST_STAGE_2 0x00000459U +#define _reg_PI_BIST_STAGE_3 0x0000045aU +#define _reg_PI_BIST_STAGE_4 0x0000045bU +#define _reg_PI_BIST_STAGE_5 0x0000045cU +#define _reg_PI_BIST_STAGE_6 0x0000045dU +#define _reg_PI_BIST_STAGE_7 0x0000045eU +#define _reg_PI_COL_DIFF 0x0000045fU +#define _reg_PI_SELF_REFRESH_EN 0x00000460U +#define _reg_PI_TXSR_F0 0x00000461U +#define _reg_PI_TXSR_F1 0x00000462U +#define _reg_PI_TXSR_F2 0x00000463U +#define _reg_PI_MONITOR_SRC_SEL_0 0x00000464U +#define _reg_PI_MONITOR_CAP_SEL_0 0x00000465U +#define _reg_PI_MONITOR_0 0x00000466U +#define _reg_PI_MONITOR_SRC_SEL_1 0x00000467U +#define _reg_PI_MONITOR_CAP_SEL_1 0x00000468U +#define _reg_PI_MONITOR_1 0x00000469U +#define _reg_PI_MONITOR_SRC_SEL_2 0x0000046aU +#define _reg_PI_MONITOR_CAP_SEL_2 0x0000046bU +#define _reg_PI_MONITOR_2 0x0000046cU +#define _reg_PI_MONITOR_SRC_SEL_3 0x0000046dU +#define _reg_PI_MONITOR_CAP_SEL_3 0x0000046eU +#define _reg_PI_MONITOR_3 0x0000046fU +#define _reg_PI_MONITOR_SRC_SEL_4 0x00000470U +#define _reg_PI_MONITOR_CAP_SEL_4 0x00000471U +#define _reg_PI_MONITOR_4 0x00000472U +#define _reg_PI_MONITOR_SRC_SEL_5 0x00000473U +#define _reg_PI_MONITOR_CAP_SEL_5 0x00000474U +#define _reg_PI_MONITOR_5 0x00000475U +#define _reg_PI_MONITOR_SRC_SEL_6 0x00000476U +#define _reg_PI_MONITOR_CAP_SEL_6 0x00000477U +#define _reg_PI_MONITOR_6 0x00000478U +#define _reg_PI_MONITOR_SRC_SEL_7 0x00000479U +#define _reg_PI_MONITOR_CAP_SEL_7 0x0000047aU +#define _reg_PI_MONITOR_7 0x0000047bU +#define _reg_PI_MONITOR_STROBE 0x0000047cU +#define _reg_PI_DLL_LOCK 0x0000047dU +#define _reg_PI_FREQ_NUMBER_STATUS 0x0000047eU +#define _reg_RESERVED_R24 0x0000047fU +#define _reg_PI_PHYMSTR_TYPE 0x00000480U +#define _reg_PI_POWER_REDUC_EN 0x00000481U +#define _reg_RESERVED_R25 0x00000482U +#define _reg_RESERVED_R26 0x00000483U +#define _reg_RESERVED_R27 0x00000484U +#define _reg_RESERVED_R28 0x00000485U +#define _reg_RESERVED_R29 0x00000486U +#define _reg_RESERVED_R30 0x00000487U +#define _reg_RESERVED_R31 0x00000488U +#define _reg_RESERVED_R32 0x00000489U +#define _reg_RESERVED_R33 0x0000048aU +#define _reg_RESERVED_R34 0x0000048bU +#define _reg_RESERVED_R35 0x0000048cU +#define _reg_RESERVED_R36 0x0000048dU +#define _reg_RESERVED_R37 0x0000048eU +#define _reg_RESERVED_R38 0x0000048fU +#define _reg_RESERVED_R39 0x00000490U +#define _reg_PI_WRLVL_MAX_STROBE_PEND 0x00000491U +#define _reg_PI_TSDO_F0 0x00000492U +#define _reg_PI_TSDO_F1 0x00000493U +#define _reg_PI_TSDO_F2 0x00000494U + +#define DDR_REGDEF_ADR(regdef) ((regdef) & 0xffffU) +#define DDR_REGDEF_LEN(regdef) (((regdef) >> 16) & 0xffU) +#define DDR_REGDEF_LSB(regdef) (((regdef) >> 24) & 0xffU) + +static const uint32_t DDR_REGDEF_TBL[4][1173] = { + { +/*0000*/ 0xffffffffU, +/*0001*/ 0xffffffffU, +/*0002*/ 0x000b0400U, +/*0003*/ 0xffffffffU, +/*0004*/ 0xffffffffU, +/*0005*/ 0x10010400U, +/*0006*/ 0x18050400U, +/*0007*/ 0x00050401U, +/*0008*/ 0x08050401U, +/*0009*/ 0x10050401U, +/*000a*/ 0x18050401U, +/*000b*/ 0x00050402U, +/*000c*/ 0x08050402U, +/*000d*/ 0x10050402U, +/*000e*/ 0x18050402U, +/*000f*/ 0x00040403U, +/*0010*/ 0x08030403U, +/*0011*/ 0x00180404U, +/*0012*/ 0x18030404U, +/*0013*/ 0x00180405U, +/*0014*/ 0x18020405U, +/*0015*/ 0x00010406U, +/*0016*/ 0x08020406U, +/*0017*/ 0x10010406U, +/*0018*/ 0x18010406U, +/*0019*/ 0x00020407U, +/*001a*/ 0x08040407U, +/*001b*/ 0x10040407U, +/*001c*/ 0x18040407U, +/*001d*/ 0x000a0408U, +/*001e*/ 0x10040408U, +/*001f*/ 0xffffffffU, +/*0020*/ 0xffffffffU, +/*0021*/ 0x18070408U, +/*0022*/ 0xffffffffU, +/*0023*/ 0xffffffffU, +/*0024*/ 0xffffffffU, +/*0025*/ 0xffffffffU, +/*0026*/ 0xffffffffU, +/*0027*/ 0xffffffffU, +/*0028*/ 0x000a0409U, +/*0029*/ 0x10040409U, +/*002a*/ 0x18010409U, +/*002b*/ 0x0001040aU, +/*002c*/ 0x0802040aU, +/*002d*/ 0x1009040aU, +/*002e*/ 0x0009040bU, +/*002f*/ 0x1002040bU, +/*0030*/ 0x0020040cU, +/*0031*/ 0xffffffffU, +/*0032*/ 0x0001040dU, +/*0033*/ 0xffffffffU, +/*0034*/ 0xffffffffU, +/*0035*/ 0xffffffffU, +/*0036*/ 0xffffffffU, +/*0037*/ 0x0020040eU, +/*0038*/ 0x0020040fU, +/*0039*/ 0x00200410U, +/*003a*/ 0x00200411U, +/*003b*/ 0x00030412U, +/*003c*/ 0x08010412U, +/*003d*/ 0x10030412U, +/*003e*/ 0x18030412U, +/*003f*/ 0x00040413U, +/*0040*/ 0x08040413U, +/*0041*/ 0x10040413U, +/*0042*/ 0x18040413U, +/*0043*/ 0x00010414U, +/*0044*/ 0x08010414U, +/*0045*/ 0x10060414U, +/*0046*/ 0x18040414U, +/*0047*/ 0xffffffffU, +/*0048*/ 0x00060415U, +/*0049*/ 0x08040415U, +/*004a*/ 0x10060415U, +/*004b*/ 0x18040415U, +/*004c*/ 0x00020416U, +/*004d*/ 0x08050416U, +/*004e*/ 0x10080416U, +/*004f*/ 0x00200417U, +/*0050*/ 0x00060418U, +/*0051*/ 0x08030418U, +/*0052*/ 0x100b0418U, +/*0053*/ 0x00040419U, +/*0054*/ 0x08040419U, +/*0055*/ 0x10040419U, +/*0056*/ 0xffffffffU, +/*0057*/ 0x18010419U, +/*0058*/ 0x0009041aU, +/*0059*/ 0x0020041bU, +/*005a*/ 0x0020041cU, +/*005b*/ 0x0020041dU, +/*005c*/ 0x0020041eU, +/*005d*/ 0x0010041fU, +/*005e*/ 0x00200420U, +/*005f*/ 0x00010421U, +/*0060*/ 0x08060421U, +/*0061*/ 0x10080421U, +/*0062*/ 0x00200422U, +/*0063*/ 0xffffffffU, +/*0064*/ 0x000a0423U, +/*0065*/ 0x10060423U, +/*0066*/ 0x18070423U, +/*0067*/ 0x00080424U, +/*0068*/ 0x08080424U, +/*0069*/ 0x100a0424U, +/*006a*/ 0x00070425U, +/*006b*/ 0x08080425U, +/*006c*/ 0x10080425U, +/*006d*/ 0x18030425U, +/*006e*/ 0x000a0426U, +/*006f*/ 0x100a0426U, +/*0070*/ 0x00110427U, +/*0071*/ 0x00090428U, +/*0072*/ 0x10090428U, +/*0073*/ 0x00100429U, +/*0074*/ 0x100e0429U, +/*0075*/ 0x000e042aU, +/*0076*/ 0x100c042aU, +/*0077*/ 0x000a042bU, +/*0078*/ 0x100a042bU, +/*0079*/ 0x0002042cU, +/*007a*/ 0x0020042dU, +/*007b*/ 0x000b042eU, +/*007c*/ 0x100b042eU, +/*007d*/ 0x0020042fU, +/*007e*/ 0x00120430U, +/*007f*/ 0x00200431U, +/*0080*/ 0x00200432U, +/*0081*/ 0xffffffffU, +/*0082*/ 0xffffffffU, +/*0083*/ 0x00010433U, +/*0084*/ 0x08010433U, +/*0085*/ 0x10080433U, +/*0086*/ 0x000c0434U, +/*0087*/ 0x100c0434U, +/*0088*/ 0x000c0435U, +/*0089*/ 0x100c0435U, +/*008a*/ 0x000c0436U, +/*008b*/ 0x100c0436U, +/*008c*/ 0x000c0437U, +/*008d*/ 0x100c0437U, +/*008e*/ 0x000c0438U, +/*008f*/ 0x100c0438U, +/*0090*/ 0x000c0439U, +/*0091*/ 0x100b0439U, +/*0092*/ 0xffffffffU, +/*0093*/ 0xffffffffU, +/*0094*/ 0x000b043aU, +/*0095*/ 0x100b043aU, +/*0096*/ 0x000b043bU, +/*0097*/ 0x100b043bU, +/*0098*/ 0x000b043cU, +/*0099*/ 0x100b043cU, +/*009a*/ 0x000b043dU, +/*009b*/ 0x100b043dU, +/*009c*/ 0x000b043eU, +/*009d*/ 0x100a043eU, +/*009e*/ 0xffffffffU, +/*009f*/ 0x000a043fU, +/*00a0*/ 0x100a043fU, +/*00a1*/ 0x000a0440U, +/*00a2*/ 0x100a0440U, +/*00a3*/ 0x000a0441U, +/*00a4*/ 0x100a0441U, +/*00a5*/ 0x000a0442U, +/*00a6*/ 0x100a0442U, +/*00a7*/ 0xffffffffU, +/*00a8*/ 0x000a0443U, +/*00a9*/ 0x100a0443U, +/*00aa*/ 0x000a0444U, +/*00ab*/ 0x100a0444U, +/*00ac*/ 0x000a0445U, +/*00ad*/ 0x100a0445U, +/*00ae*/ 0x000a0446U, +/*00af*/ 0x100a0446U, +/*00b0*/ 0x000a0447U, +/*00b1*/ 0x100a0447U, +/*00b2*/ 0x000a0448U, +/*00b3*/ 0x100a0448U, +/*00b4*/ 0x000a0449U, +/*00b5*/ 0x100a0449U, +/*00b6*/ 0x000a044aU, +/*00b7*/ 0x100a044aU, +/*00b8*/ 0x000a044bU, +/*00b9*/ 0x100a044bU, +/*00ba*/ 0x000a044cU, +/*00bb*/ 0x1004044cU, +/*00bc*/ 0x1803044cU, +/*00bd*/ 0x000a044dU, +/*00be*/ 0x100a044dU, +/*00bf*/ 0x0001044eU, +/*00c0*/ 0x080a044eU, +/*00c1*/ 0x1804044eU, +/*00c2*/ 0x000b044fU, +/*00c3*/ 0x100a044fU, +/*00c4*/ 0xffffffffU, +/*00c5*/ 0x00080450U, +/*00c6*/ 0x08080450U, +/*00c7*/ 0x10080450U, +/*00c8*/ 0x18080450U, +/*00c9*/ 0x00080451U, +/*00ca*/ 0xffffffffU, +/*00cb*/ 0x08080451U, +/*00cc*/ 0x10010451U, +/*00cd*/ 0x18080451U, +/*00ce*/ 0x00080452U, +/*00cf*/ 0x08020452U, +/*00d0*/ 0x10020452U, +/*00d1*/ 0x18040452U, +/*00d2*/ 0x00040453U, +/*00d3*/ 0xffffffffU, +/*00d4*/ 0x08040453U, +/*00d5*/ 0x100a0453U, +/*00d6*/ 0x00060454U, +/*00d7*/ 0x08080454U, +/*00d8*/ 0xffffffffU, +/*00d9*/ 0x10040454U, +/*00da*/ 0x18040454U, +/*00db*/ 0x00050455U, +/*00dc*/ 0x08040455U, +/*00dd*/ 0x10050455U, +/*00de*/ 0x000a0456U, +/*00df*/ 0x100a0456U, +/*00e0*/ 0x00080457U, +/*00e1*/ 0xffffffffU, +/*00e2*/ 0x08040457U, +/*00e3*/ 0xffffffffU, +/*00e4*/ 0xffffffffU, +/*00e5*/ 0x00050600U, +/*00e6*/ 0x08050600U, +/*00e7*/ 0x10050600U, +/*00e8*/ 0x18050600U, +/*00e9*/ 0x00050601U, +/*00ea*/ 0x08050601U, +/*00eb*/ 0x100b0601U, +/*00ec*/ 0x00010602U, +/*00ed*/ 0x08030602U, +/*00ee*/ 0x00200603U, +/*00ef*/ 0xffffffffU, +/*00f0*/ 0x00030604U, +/*00f1*/ 0x080a0604U, +/*00f2*/ 0xffffffffU, +/*00f3*/ 0xffffffffU, +/*00f4*/ 0x18030604U, +/*00f5*/ 0x00030605U, +/*00f6*/ 0x08010605U, +/*00f7*/ 0x10010605U, +/*00f8*/ 0x18060605U, +/*00f9*/ 0xffffffffU, +/*00fa*/ 0xffffffffU, +/*00fb*/ 0xffffffffU, +/*00fc*/ 0x00020606U, +/*00fd*/ 0x08030606U, +/*00fe*/ 0x10010606U, +/*00ff*/ 0x000f0607U, +/*0100*/ 0x00200608U, +/*0101*/ 0x00200609U, +/*0102*/ 0x000b060aU, +/*0103*/ 0x100b060aU, +/*0104*/ 0x000b060bU, +/*0105*/ 0xffffffffU, +/*0106*/ 0xffffffffU, +/*0107*/ 0x0018060cU, +/*0108*/ 0x0018060dU, +/*0109*/ 0x0018060eU, +/*010a*/ 0x0018060fU, +/*010b*/ 0x1804060fU, +/*010c*/ 0x00050610U, +/*010d*/ 0x08020610U, +/*010e*/ 0x10040610U, +/*010f*/ 0x18040610U, +/*0110*/ 0x00010611U, +/*0111*/ 0x08010611U, +/*0112*/ 0x10010611U, +/*0113*/ 0x18030611U, +/*0114*/ 0x00200612U, +/*0115*/ 0x00200613U, +/*0116*/ 0x00010614U, +/*0117*/ 0x08140614U, +/*0118*/ 0x00140615U, +/*0119*/ 0x00140616U, +/*011a*/ 0x00140617U, +/*011b*/ 0x00140618U, +/*011c*/ 0x00140619U, +/*011d*/ 0x0014061aU, +/*011e*/ 0x0014061bU, +/*011f*/ 0x0018061cU, +/*0120*/ 0x000a061dU, +/*0121*/ 0x1006061dU, +/*0122*/ 0x1806061dU, +/*0123*/ 0x0006061eU, +/*0124*/ 0xffffffffU, +/*0125*/ 0xffffffffU, +/*0126*/ 0x0008061fU, +/*0127*/ 0x080b061fU, +/*0128*/ 0x000b0620U, +/*0129*/ 0x100b0620U, +/*012a*/ 0x000b0621U, +/*012b*/ 0x100b0621U, +/*012c*/ 0x000b0622U, +/*012d*/ 0x10040622U, +/*012e*/ 0x000a0623U, +/*012f*/ 0x10060623U, +/*0130*/ 0x18080623U, +/*0131*/ 0xffffffffU, +/*0132*/ 0x00040624U, +/*0133*/ 0xffffffffU, +/*0134*/ 0xffffffffU, +/*0135*/ 0x00010700U, +/*0136*/ 0x08020700U, +/*0137*/ 0x10050700U, +/*0138*/ 0x18050700U, +/*0139*/ 0x00050701U, +/*013a*/ 0x08050701U, +/*013b*/ 0x100b0701U, +/*013c*/ 0x00050702U, +/*013d*/ 0x08010702U, +/*013e*/ 0x10010702U, +/*013f*/ 0xffffffffU, +/*0140*/ 0x18010702U, +/*0141*/ 0x00010703U, +/*0142*/ 0x08040703U, +/*0143*/ 0x100b0703U, +/*0144*/ 0x000b0704U, +/*0145*/ 0xffffffffU, +/*0146*/ 0x10040704U, +/*0147*/ 0x000b0705U, +/*0148*/ 0x10040705U, +/*0149*/ 0x18010705U, +/*014a*/ 0x00010706U, +/*014b*/ 0x08010706U, +/*014c*/ 0x00200707U, +/*014d*/ 0x00200708U, +/*014e*/ 0x00080709U, +/*014f*/ 0x080a0709U, +/*0150*/ 0x18050709U, +/*0151*/ 0x000a070aU, +/*0152*/ 0x1003070aU, +/*0153*/ 0x1803070aU, +/*0154*/ 0x0001070bU, +/*0155*/ 0x0802070bU, +/*0156*/ 0x1001070bU, +/*0157*/ 0x1801070bU, +/*0158*/ 0x0001070cU, +/*0159*/ 0x0802070cU, +/*015a*/ 0xffffffffU, +/*015b*/ 0xffffffffU, +/*015c*/ 0xffffffffU, +/*015d*/ 0xffffffffU, +/*015e*/ 0xffffffffU, +/*015f*/ 0xffffffffU, +/*0160*/ 0xffffffffU, +/*0161*/ 0xffffffffU, +/*0162*/ 0xffffffffU, +/*0163*/ 0xffffffffU, +/*0164*/ 0xffffffffU, +/*0165*/ 0xffffffffU, +/*0166*/ 0x1001070cU, +/*0167*/ 0x1801070cU, +/*0168*/ 0x000d070dU, +/*0169*/ 0xffffffffU, +/*016a*/ 0xffffffffU, +/*016b*/ 0x0005070eU, +/*016c*/ 0x0001070fU, +/*016d*/ 0x080e070fU, +/*016e*/ 0x000e0710U, +/*016f*/ 0x100e0710U, +/*0170*/ 0x000e0711U, +/*0171*/ 0x100e0711U, +/*0172*/ 0x00040712U, +/*0173*/ 0xffffffffU, +/*0174*/ 0xffffffffU, +/*0175*/ 0xffffffffU, +/*0176*/ 0xffffffffU, +/*0177*/ 0x080b0712U, +/*0178*/ 0x000b0713U, +/*0179*/ 0x100b0713U, +/*017a*/ 0x000b0714U, +/*017b*/ 0xffffffffU, +/*017c*/ 0xffffffffU, +/*017d*/ 0xffffffffU, +/*017e*/ 0xffffffffU, +/*017f*/ 0x000d0715U, +/*0180*/ 0xffffffffU, +/*0181*/ 0xffffffffU, +/*0182*/ 0x10100715U, +/*0183*/ 0x00080716U, +/*0184*/ 0xffffffffU, +/*0185*/ 0x08100716U, +/*0186*/ 0x00100717U, +/*0187*/ 0x10100717U, +/*0188*/ 0x00100718U, +/*0189*/ 0x10100718U, +/*018a*/ 0x00030719U, +/*018b*/ 0x08040719U, +/*018c*/ 0x10010719U, +/*018d*/ 0x18040719U, +/*018e*/ 0xffffffffU, +/*018f*/ 0xffffffffU, +/*0190*/ 0x0001071aU, +/*0191*/ 0x0812071aU, +/*0192*/ 0x000a071bU, +/*0193*/ 0x100c071bU, +/*0194*/ 0x0012071cU, +/*0195*/ 0x0014071dU, +/*0196*/ 0x0012071eU, +/*0197*/ 0x0011071fU, +/*0198*/ 0x00110720U, +/*0199*/ 0x00120721U, +/*019a*/ 0x00120722U, +/*019b*/ 0x00120723U, +/*019c*/ 0x00120724U, +/*019d*/ 0x00120725U, +/*019e*/ 0x00120726U, +/*019f*/ 0x00120727U, +/*01a0*/ 0x00120728U, +/*01a1*/ 0xffffffffU, +/*01a2*/ 0xffffffffU, +/*01a3*/ 0x00190729U, +/*01a4*/ 0x0019072aU, +/*01a5*/ 0x0020072bU, +/*01a6*/ 0x0017072cU, +/*01a7*/ 0x1808072cU, +/*01a8*/ 0x0001072dU, +/*01a9*/ 0x0801072dU, +/*01aa*/ 0x0020072eU, +/*01ab*/ 0x0008072fU, +/*01ac*/ 0xffffffffU, +/*01ad*/ 0x0803072fU, +/*01ae*/ 0x00180730U, +/*01af*/ 0x00180731U, +/*01b0*/ 0xffffffffU, +/*01b1*/ 0xffffffffU, +/*01b2*/ 0xffffffffU, +/*01b3*/ 0xffffffffU, +/*01b4*/ 0xffffffffU, +/*01b5*/ 0xffffffffU, +/*01b6*/ 0xffffffffU, +/*01b7*/ 0xffffffffU, +/*01b8*/ 0xffffffffU, +/*01b9*/ 0xffffffffU, +/*01ba*/ 0xffffffffU, +/*01bb*/ 0xffffffffU, +/*01bc*/ 0xffffffffU, +/*01bd*/ 0xffffffffU, +/*01be*/ 0xffffffffU, +/*01bf*/ 0x00100732U, +/*01c0*/ 0x10010732U, +/*01c1*/ 0x18010732U, +/*01c2*/ 0x00050733U, +/*01c3*/ 0x00200734U, +/*01c4*/ 0x00090735U, +/*01c5*/ 0xffffffffU, +/*01c6*/ 0xffffffffU, +/*01c7*/ 0x00200736U, +/*01c8*/ 0x00040737U, +/*01c9*/ 0x08100737U, +/*01ca*/ 0x18060737U, +/*01cb*/ 0x00100738U, +/*01cc*/ 0xffffffffU, +/*01cd*/ 0xffffffffU, +/*01ce*/ 0xffffffffU, +/*01cf*/ 0xffffffffU, +/*01d0*/ 0xffffffffU, +/*01d1*/ 0xffffffffU, +/*01d2*/ 0xffffffffU, +/*01d3*/ 0xffffffffU, +/*01d4*/ 0x00200739U, +/*01d5*/ 0x000b073aU, +/*01d6*/ 0xffffffffU, +/*01d7*/ 0xffffffffU, +/*01d8*/ 0xffffffffU, +/*01d9*/ 0xffffffffU, +/*01da*/ 0xffffffffU, +/*01db*/ 0xffffffffU, +/*01dc*/ 0xffffffffU, +/*01dd*/ 0xffffffffU, +/*01de*/ 0x00010200U, +/*01df*/ 0x08040200U, +/*01e0*/ 0x10100200U, +/*01e1*/ 0x00010201U, +/*01e2*/ 0x08010201U, +/*01e3*/ 0xffffffffU, +/*01e4*/ 0xffffffffU, +/*01e5*/ 0x10100201U, +/*01e6*/ 0xffffffffU, +/*01e7*/ 0xffffffffU, +/*01e8*/ 0xffffffffU, +/*01e9*/ 0xffffffffU, +/*01ea*/ 0xffffffffU, +/*01eb*/ 0xffffffffU, +/*01ec*/ 0xffffffffU, +/*01ed*/ 0xffffffffU, +/*01ee*/ 0xffffffffU, +/*01ef*/ 0x00200202U, +/*01f0*/ 0x00100203U, +/*01f1*/ 0x00200204U, +/*01f2*/ 0x00100205U, +/*01f3*/ 0x00200206U, +/*01f4*/ 0x00100207U, +/*01f5*/ 0x10100207U, +/*01f6*/ 0x00200208U, +/*01f7*/ 0x00200209U, +/*01f8*/ 0x0020020aU, +/*01f9*/ 0x0020020bU, +/*01fa*/ 0x0010020cU, +/*01fb*/ 0x0020020dU, +/*01fc*/ 0x0020020eU, +/*01fd*/ 0x0020020fU, +/*01fe*/ 0x00200210U, +/*01ff*/ 0x00100211U, +/*0200*/ 0x00200212U, +/*0201*/ 0x00200213U, +/*0202*/ 0x00200214U, +/*0203*/ 0x00200215U, +/*0204*/ 0x00090216U, +/*0205*/ 0x10010216U, +/*0206*/ 0x00200217U, +/*0207*/ 0x00050218U, +/*0208*/ 0x08010218U, +/*0209*/ 0x10080218U, +/*020a*/ 0x18080218U, +/*020b*/ 0x001c0219U, +/*020c*/ 0x001c021aU, +/*020d*/ 0x001c021bU, +/*020e*/ 0x001c021cU, +/*020f*/ 0x001c021dU, +/*0210*/ 0x001c021eU, +/*0211*/ 0x001c021fU, +/*0212*/ 0x001c0220U, +/*0213*/ 0x001c0221U, +/*0214*/ 0x001c0222U, +/*0215*/ 0x001c0223U, +/*0216*/ 0x001c0224U, +/*0217*/ 0x001c0225U, +/*0218*/ 0x001c0226U, +/*0219*/ 0x001c0227U, +/*021a*/ 0x001c0228U, +/*021b*/ 0x00010229U, +/*021c*/ 0x08010229U, +/*021d*/ 0x10010229U, +/*021e*/ 0x18040229U, +/*021f*/ 0x0008022aU, +/*0220*/ 0x0808022aU, +/*0221*/ 0x1008022aU, +/*0222*/ 0x1804022aU, +/*0223*/ 0x0006022bU, +/*0224*/ 0xffffffffU, +/*0225*/ 0x0807022bU, +/*0226*/ 0x1006022bU, +/*0227*/ 0xffffffffU, +/*0228*/ 0x1807022bU, +/*0229*/ 0x0006022cU, +/*022a*/ 0xffffffffU, +/*022b*/ 0x0807022cU, +/*022c*/ 0x1002022cU, +/*022d*/ 0x1801022cU, +/*022e*/ 0xffffffffU, +/*022f*/ 0x000a022dU, +/*0230*/ 0x1010022dU, +/*0231*/ 0x000a022eU, +/*0232*/ 0x1010022eU, +/*0233*/ 0x000a022fU, +/*0234*/ 0x1010022fU, +/*0235*/ 0xffffffffU, +/*0236*/ 0x00100230U, +/*0237*/ 0xffffffffU, +/*0238*/ 0xffffffffU, +/*0239*/ 0x10010230U, +/*023a*/ 0x18010230U, +/*023b*/ 0x00010231U, +/*023c*/ 0x08010231U, +/*023d*/ 0x10010231U, +/*023e*/ 0x18010231U, +/*023f*/ 0x00020232U, +/*0240*/ 0x08020232U, +/*0241*/ 0x10020232U, +/*0242*/ 0x18020232U, +/*0243*/ 0x00020233U, +/*0244*/ 0x08030233U, +/*0245*/ 0x10010233U, +/*0246*/ 0x18010233U, +/*0247*/ 0x00010234U, +/*0248*/ 0x08010234U, +/*0249*/ 0xffffffffU, +/*024a*/ 0x10020234U, +/*024b*/ 0x18010234U, +/*024c*/ 0x00010235U, +/*024d*/ 0xffffffffU, +/*024e*/ 0x08020235U, +/*024f*/ 0x10010235U, +/*0250*/ 0x18010235U, +/*0251*/ 0xffffffffU, +/*0252*/ 0x00020236U, +/*0253*/ 0x08010236U, +/*0254*/ 0x10010236U, +/*0255*/ 0xffffffffU, +/*0256*/ 0x18020236U, +/*0257*/ 0x00070237U, +/*0258*/ 0x08010237U, +/*0259*/ 0x10010237U, +/*025a*/ 0x18010237U, +/*025b*/ 0x00010238U, +/*025c*/ 0x08010238U, +/*025d*/ 0x10010238U, +/*025e*/ 0xffffffffU, +/*025f*/ 0x18010238U, +/*0260*/ 0x00040239U, +/*0261*/ 0x08040239U, +/*0262*/ 0x10040239U, +/*0263*/ 0x18010239U, +/*0264*/ 0x0002023aU, +/*0265*/ 0x0806023aU, +/*0266*/ 0x1006023aU, +/*0267*/ 0xffffffffU, +/*0268*/ 0xffffffffU, +/*0269*/ 0xffffffffU, +/*026a*/ 0x1802023aU, +/*026b*/ 0x0010023bU, +/*026c*/ 0x1001023bU, +/*026d*/ 0x1801023bU, +/*026e*/ 0xffffffffU, +/*026f*/ 0x0004023cU, +/*0270*/ 0x0801023cU, +/*0271*/ 0x1004023cU, +/*0272*/ 0x1802023cU, +/*0273*/ 0x0008023dU, +/*0274*/ 0xffffffffU, +/*0275*/ 0xffffffffU, +/*0276*/ 0xffffffffU, +/*0277*/ 0x080a023dU, +/*0278*/ 0x0020023eU, +/*0279*/ 0x0020023fU, +/*027a*/ 0x00050240U, +/*027b*/ 0x08010240U, +/*027c*/ 0x10050240U, +/*027d*/ 0x18080240U, +/*027e*/ 0x00010241U, +/*027f*/ 0x08080241U, +/*0280*/ 0x10010241U, +/*0281*/ 0x18080241U, +/*0282*/ 0x00010242U, +/*0283*/ 0x08040242U, +/*0284*/ 0x10040242U, +/*0285*/ 0x18040242U, +/*0286*/ 0x00040243U, +/*0287*/ 0x08040243U, +/*0288*/ 0x10040243U, +/*0289*/ 0x18040243U, +/*028a*/ 0x00040244U, +/*028b*/ 0x08040244U, +/*028c*/ 0x10040244U, +/*028d*/ 0x18010244U, +/*028e*/ 0x00040245U, +/*028f*/ 0x08040245U, +/*0290*/ 0x10040245U, +/*0291*/ 0x18040245U, +/*0292*/ 0x00040246U, +/*0293*/ 0x08040246U, +/*0294*/ 0x10060246U, +/*0295*/ 0x18060246U, +/*0296*/ 0x00060247U, +/*0297*/ 0x08060247U, +/*0298*/ 0x10060247U, +/*0299*/ 0x18060247U, +/*029a*/ 0xffffffffU, +/*029b*/ 0x00010248U, +/*029c*/ 0x08010248U, +/*029d*/ 0x10020248U, +/*029e*/ 0xffffffffU, +/*029f*/ 0xffffffffU, +/*02a0*/ 0xffffffffU, +/*02a1*/ 0xffffffffU, +/*02a2*/ 0xffffffffU, +/*02a3*/ 0xffffffffU, +/*02a4*/ 0xffffffffU, +/*02a5*/ 0xffffffffU, +/*02a6*/ 0x18040248U, +/*02a7*/ 0x00040249U, +/*02a8*/ 0x08010249U, +/*02a9*/ 0x10010249U, +/*02aa*/ 0xffffffffU, +/*02ab*/ 0x18010249U, +/*02ac*/ 0x0001024aU, +/*02ad*/ 0xffffffffU, +/*02ae*/ 0x0801024aU, +/*02af*/ 0x1001024aU, +/*02b0*/ 0x1801024aU, +/*02b1*/ 0x0004024bU, +/*02b2*/ 0x0804024bU, +/*02b3*/ 0x100a024bU, +/*02b4*/ 0x0020024cU, +/*02b5*/ 0x0004024dU, +/*02b6*/ 0x0808024dU, +/*02b7*/ 0xffffffffU, +/*02b8*/ 0xffffffffU, +/*02b9*/ 0xffffffffU, +/*02ba*/ 0xffffffffU, +/*02bb*/ 0xffffffffU, +/*02bc*/ 0xffffffffU, +/*02bd*/ 0x1002024dU, +/*02be*/ 0x1802024dU, +/*02bf*/ 0x0020024eU, +/*02c0*/ 0x0002024fU, +/*02c1*/ 0x0810024fU, +/*02c2*/ 0x00100250U, +/*02c3*/ 0x10040250U, +/*02c4*/ 0x18040250U, +/*02c5*/ 0x00050251U, +/*02c6*/ 0x08050251U, +/*02c7*/ 0xffffffffU, +/*02c8*/ 0xffffffffU, +/*02c9*/ 0xffffffffU, +/*02ca*/ 0xffffffffU, +/*02cb*/ 0x10010251U, +/*02cc*/ 0x18010251U, +/*02cd*/ 0x00070252U, +/*02ce*/ 0x08070252U, +/*02cf*/ 0x10070252U, +/*02d0*/ 0x18070252U, +/*02d1*/ 0x00070253U, +/*02d2*/ 0x08070253U, +/*02d3*/ 0x10070253U, +/*02d4*/ 0x18070253U, +/*02d5*/ 0x00070254U, +/*02d6*/ 0x08070254U, +/*02d7*/ 0x10070254U, +/*02d8*/ 0xffffffffU, +/*02d9*/ 0xffffffffU, +/*02da*/ 0xffffffffU, +/*02db*/ 0xffffffffU, +/*02dc*/ 0xffffffffU, +/*02dd*/ 0xffffffffU, +/*02de*/ 0x18030254U, +/*02df*/ 0x00010255U, +/*02e0*/ 0x08020255U, +/*02e1*/ 0x10010255U, +/*02e2*/ 0x18040255U, +/*02e3*/ 0x00020256U, +/*02e4*/ 0x08010256U, +/*02e5*/ 0x10010256U, +/*02e6*/ 0xffffffffU, +/*02e7*/ 0x18010256U, +/*02e8*/ 0x00040257U, +/*02e9*/ 0x08080257U, +/*02ea*/ 0x100a0257U, +/*02eb*/ 0x000a0258U, +/*02ec*/ 0x100a0258U, +/*02ed*/ 0x000a0259U, +/*02ee*/ 0x100a0259U, +/*02ef*/ 0x000a025aU, +/*02f0*/ 0x0020025bU, +/*02f1*/ 0x0020025cU, +/*02f2*/ 0x0001025dU, +/*02f3*/ 0xffffffffU, +/*02f4*/ 0xffffffffU, +/*02f5*/ 0xffffffffU, +/*02f6*/ 0x0802025dU, +/*02f7*/ 0x1002025dU, +/*02f8*/ 0x0010025eU, +/*02f9*/ 0x1005025eU, +/*02fa*/ 0x1806025eU, +/*02fb*/ 0x0005025fU, +/*02fc*/ 0x0805025fU, +/*02fd*/ 0x100e025fU, +/*02fe*/ 0x00050260U, +/*02ff*/ 0x080e0260U, +/*0300*/ 0x18050260U, +/*0301*/ 0x000e0261U, +/*0302*/ 0x10050261U, +/*0303*/ 0x18010261U, +/*0304*/ 0x00050262U, +/*0305*/ 0x08050262U, +/*0306*/ 0x100a0262U, +/*0307*/ 0x000a0263U, +/*0308*/ 0x10050263U, +/*0309*/ 0x18050263U, +/*030a*/ 0x000a0264U, +/*030b*/ 0x100a0264U, +/*030c*/ 0x00050265U, +/*030d*/ 0x08050265U, +/*030e*/ 0x100a0265U, +/*030f*/ 0x000a0266U, +/*0310*/ 0xffffffffU, +/*0311*/ 0xffffffffU, +/*0312*/ 0xffffffffU, +/*0313*/ 0xffffffffU, +/*0314*/ 0xffffffffU, +/*0315*/ 0xffffffffU, +/*0316*/ 0x10070266U, +/*0317*/ 0x18070266U, +/*0318*/ 0x00040267U, +/*0319*/ 0x08040267U, +/*031a*/ 0xffffffffU, +/*031b*/ 0xffffffffU, +/*031c*/ 0xffffffffU, +/*031d*/ 0x10040267U, +/*031e*/ 0x18080267U, +/*031f*/ 0x00080268U, +/*0320*/ 0x08040268U, +/*0321*/ 0xffffffffU, +/*0322*/ 0xffffffffU, +/*0323*/ 0xffffffffU, +/*0324*/ 0x10040268U, +/*0325*/ 0xffffffffU, +/*0326*/ 0xffffffffU, +/*0327*/ 0xffffffffU, +/*0328*/ 0x18040268U, +/*0329*/ 0xffffffffU, +/*032a*/ 0xffffffffU, +/*032b*/ 0xffffffffU, +/*032c*/ 0x00040269U, +/*032d*/ 0x08050269U, +/*032e*/ 0x10070269U, +/*032f*/ 0x18080269U, +/*0330*/ 0x0010026aU, +/*0331*/ 0x1008026aU, +/*0332*/ 0x0010026bU, +/*0333*/ 0x1008026bU, +/*0334*/ 0x0010026cU, +/*0335*/ 0x1008026cU, +/*0336*/ 0x1808026cU, +/*0337*/ 0x0001026dU, +/*0338*/ 0x0801026dU, +/*0339*/ 0x1006026dU, +/*033a*/ 0x1806026dU, +/*033b*/ 0x0006026eU, +/*033c*/ 0xffffffffU, +/*033d*/ 0x0801026eU, +/*033e*/ 0x1003026eU, +/*033f*/ 0xffffffffU, +/*0340*/ 0xffffffffU, +/*0341*/ 0xffffffffU, +/*0342*/ 0x000a026fU, +/*0343*/ 0x100a026fU, +/*0344*/ 0x00040270U, +/*0345*/ 0x08010270U, +/*0346*/ 0x10040270U, +/*0347*/ 0xffffffffU, +/*0348*/ 0xffffffffU, +/*0349*/ 0xffffffffU, +/*034a*/ 0xffffffffU, +/*034b*/ 0xffffffffU, +/*034c*/ 0xffffffffU, +/*034d*/ 0x18070270U, +/*034e*/ 0x00070271U, +/*034f*/ 0x08050271U, +/*0350*/ 0x10050271U, +/*0351*/ 0xffffffffU, +/*0352*/ 0xffffffffU, +/*0353*/ 0xffffffffU, +/*0354*/ 0x18040271U, +/*0355*/ 0x00010272U, +/*0356*/ 0x08010272U, +/*0357*/ 0x10020272U, +/*0358*/ 0x18080272U, +/*0359*/ 0x00200273U, +/*035a*/ 0x00200274U, +/*035b*/ 0x00100275U, +/*035c*/ 0xffffffffU, +/*035d*/ 0xffffffffU, +/*035e*/ 0xffffffffU, +/*035f*/ 0x10020275U, +/*0360*/ 0x18010275U, +/*0361*/ 0xffffffffU, +/*0362*/ 0x00020276U, +/*0363*/ 0x08080276U, +/*0364*/ 0x10080276U, +/*0365*/ 0x18080276U, +/*0366*/ 0x00080277U, +/*0367*/ 0x08080277U, +/*0368*/ 0x10080277U, +/*0369*/ 0xffffffffU, +/*036a*/ 0x18080277U, +/*036b*/ 0x00080278U, +/*036c*/ 0x08080278U, +/*036d*/ 0x10080278U, +/*036e*/ 0x18080278U, +/*036f*/ 0x00080279U, +/*0370*/ 0xffffffffU, +/*0371*/ 0x08080279U, +/*0372*/ 0x10080279U, +/*0373*/ 0x18080279U, +/*0374*/ 0x0008027aU, +/*0375*/ 0x0808027aU, +/*0376*/ 0x1008027aU, +/*0377*/ 0xffffffffU, +/*0378*/ 0x1808027aU, +/*0379*/ 0x0008027bU, +/*037a*/ 0x0808027bU, +/*037b*/ 0x1008027bU, +/*037c*/ 0x1808027bU, +/*037d*/ 0x0008027cU, +/*037e*/ 0x0808027cU, +/*037f*/ 0xffffffffU, +/*0380*/ 0x1008027cU, +/*0381*/ 0x1808027cU, +/*0382*/ 0x0008027dU, +/*0383*/ 0x0808027dU, +/*0384*/ 0x1008027dU, +/*0385*/ 0x1808027dU, +/*0386*/ 0xffffffffU, +/*0387*/ 0x0008027eU, +/*0388*/ 0x0808027eU, +/*0389*/ 0x1008027eU, +/*038a*/ 0x1808027eU, +/*038b*/ 0x0008027fU, +/*038c*/ 0x0808027fU, +/*038d*/ 0xffffffffU, +/*038e*/ 0x1008027fU, +/*038f*/ 0x1808027fU, +/*0390*/ 0x00080280U, +/*0391*/ 0x08080280U, +/*0392*/ 0x10080280U, +/*0393*/ 0x18080280U, +/*0394*/ 0x00080281U, +/*0395*/ 0xffffffffU, +/*0396*/ 0x08080281U, +/*0397*/ 0x10080281U, +/*0398*/ 0x18080281U, +/*0399*/ 0x00080282U, +/*039a*/ 0x08080282U, +/*039b*/ 0x10080282U, +/*039c*/ 0xffffffffU, +/*039d*/ 0x18080282U, +/*039e*/ 0x00080283U, +/*039f*/ 0x08080283U, +/*03a0*/ 0x10080283U, +/*03a1*/ 0x18080283U, +/*03a2*/ 0x00080284U, +/*03a3*/ 0xffffffffU, +/*03a4*/ 0x08080284U, +/*03a5*/ 0x10080284U, +/*03a6*/ 0x18080284U, +/*03a7*/ 0x00080285U, +/*03a8*/ 0x08080285U, +/*03a9*/ 0x10080285U, +/*03aa*/ 0x18080285U, +/*03ab*/ 0xffffffffU, +/*03ac*/ 0x00080286U, +/*03ad*/ 0x08080286U, +/*03ae*/ 0x10080286U, +/*03af*/ 0x18080286U, +/*03b0*/ 0x00080287U, +/*03b1*/ 0x08080287U, +/*03b2*/ 0xffffffffU, +/*03b3*/ 0x10080287U, +/*03b4*/ 0x18080287U, +/*03b5*/ 0x00080288U, +/*03b6*/ 0x08080288U, +/*03b7*/ 0x10080288U, +/*03b8*/ 0x18080288U, +/*03b9*/ 0xffffffffU, +/*03ba*/ 0x00080289U, +/*03bb*/ 0x08020289U, +/*03bc*/ 0x10030289U, +/*03bd*/ 0x000a028aU, +/*03be*/ 0x100a028aU, +/*03bf*/ 0x000a028bU, +/*03c0*/ 0x1005028bU, +/*03c1*/ 0x1804028bU, +/*03c2*/ 0x0008028cU, +/*03c3*/ 0x0808028cU, +/*03c4*/ 0x1006028cU, +/*03c5*/ 0x1806028cU, +/*03c6*/ 0x0011028dU, +/*03c7*/ 0x1808028dU, +/*03c8*/ 0x0004028eU, +/*03c9*/ 0x0806028eU, +/*03ca*/ 0xffffffffU, +/*03cb*/ 0x1006028eU, +/*03cc*/ 0x1808028eU, +/*03cd*/ 0xffffffffU, +/*03ce*/ 0x0004028fU, +/*03cf*/ 0x0808028fU, +/*03d0*/ 0x1008028fU, +/*03d1*/ 0x1806028fU, +/*03d2*/ 0x00060290U, +/*03d3*/ 0x08110290U, +/*03d4*/ 0x00080291U, +/*03d5*/ 0x08040291U, +/*03d6*/ 0x10060291U, +/*03d7*/ 0xffffffffU, +/*03d8*/ 0x18060291U, +/*03d9*/ 0x00080292U, +/*03da*/ 0xffffffffU, +/*03db*/ 0x08040292U, +/*03dc*/ 0x10080292U, +/*03dd*/ 0x18080292U, +/*03de*/ 0x00060293U, +/*03df*/ 0x08060293U, +/*03e0*/ 0x00110294U, +/*03e1*/ 0x18080294U, +/*03e2*/ 0x00040295U, +/*03e3*/ 0x08060295U, +/*03e4*/ 0xffffffffU, +/*03e5*/ 0x10060295U, +/*03e6*/ 0x18080295U, +/*03e7*/ 0xffffffffU, +/*03e8*/ 0x00040296U, +/*03e9*/ 0x08040296U, +/*03ea*/ 0x10040296U, +/*03eb*/ 0x18040296U, +/*03ec*/ 0x00040297U, +/*03ed*/ 0x08040297U, +/*03ee*/ 0x10040297U, +/*03ef*/ 0x18040297U, +/*03f0*/ 0x00040298U, +/*03f1*/ 0x08040298U, +/*03f2*/ 0x10040298U, +/*03f3*/ 0x18040298U, +/*03f4*/ 0x00040299U, +/*03f5*/ 0x08040299U, +/*03f6*/ 0x10040299U, +/*03f7*/ 0x18040299U, +/*03f8*/ 0x0004029aU, +/*03f9*/ 0x0804029aU, +/*03fa*/ 0x1004029aU, +/*03fb*/ 0x1804029aU, +/*03fc*/ 0x0011029bU, +/*03fd*/ 0x0010029cU, +/*03fe*/ 0x0011029dU, +/*03ff*/ 0x0020029eU, +/*0400*/ 0x0020029fU, +/*0401*/ 0x002002a0U, +/*0402*/ 0x002002a1U, +/*0403*/ 0x002002a2U, +/*0404*/ 0x002002a3U, +/*0405*/ 0x002002a4U, +/*0406*/ 0x002002a5U, +/*0407*/ 0x002002a6U, +/*0408*/ 0x000202a7U, +/*0409*/ 0x080502a7U, +/*040a*/ 0x100502a7U, +/*040b*/ 0xffffffffU, +/*040c*/ 0xffffffffU, +/*040d*/ 0xffffffffU, +/*040e*/ 0xffffffffU, +/*040f*/ 0xffffffffU, +/*0410*/ 0xffffffffU, +/*0411*/ 0xffffffffU, +/*0412*/ 0xffffffffU, +/*0413*/ 0xffffffffU, +/*0414*/ 0xffffffffU, +/*0415*/ 0xffffffffU, +/*0416*/ 0xffffffffU, +/*0417*/ 0xffffffffU, +/*0418*/ 0xffffffffU, +/*0419*/ 0xffffffffU, +/*041a*/ 0xffffffffU, +/*041b*/ 0xffffffffU, +/*041c*/ 0xffffffffU, +/*041d*/ 0xffffffffU, +/*041e*/ 0xffffffffU, +/*041f*/ 0xffffffffU, +/*0420*/ 0xffffffffU, +/*0421*/ 0xffffffffU, +/*0422*/ 0xffffffffU, +/*0423*/ 0xffffffffU, +/*0424*/ 0xffffffffU, +/*0425*/ 0xffffffffU, +/*0426*/ 0xffffffffU, +/*0427*/ 0x180102a7U, +/*0428*/ 0x000402a8U, +/*0429*/ 0x081002a8U, +/*042a*/ 0x002002a9U, +/*042b*/ 0x001002aaU, +/*042c*/ 0x002002abU, +/*042d*/ 0x001002acU, +/*042e*/ 0x002002adU, +/*042f*/ 0x000702aeU, +/*0430*/ 0x080102aeU, +/*0431*/ 0x100202aeU, +/*0432*/ 0x180602aeU, +/*0433*/ 0x000102afU, +/*0434*/ 0x080102afU, +/*0435*/ 0x002002b0U, +/*0436*/ 0x000202b1U, +/*0437*/ 0x002002b2U, +/*0438*/ 0x002002b3U, +/*0439*/ 0xffffffffU, +/*043a*/ 0xffffffffU, +/*043b*/ 0xffffffffU, +/*043c*/ 0xffffffffU, +/*043d*/ 0xffffffffU, +/*043e*/ 0xffffffffU, +/*043f*/ 0xffffffffU, +/*0440*/ 0xffffffffU, +/*0441*/ 0xffffffffU, +/*0442*/ 0xffffffffU, +/*0443*/ 0xffffffffU, +/*0444*/ 0xffffffffU, +/*0445*/ 0xffffffffU, +/*0446*/ 0xffffffffU, +/*0447*/ 0xffffffffU, +/*0448*/ 0xffffffffU, +/*0449*/ 0xffffffffU, +/*044a*/ 0xffffffffU, +/*044b*/ 0xffffffffU, +/*044c*/ 0xffffffffU, +/*044d*/ 0xffffffffU, +/*044e*/ 0xffffffffU, +/*044f*/ 0xffffffffU, +/*0450*/ 0xffffffffU, +/*0451*/ 0xffffffffU, +/*0452*/ 0xffffffffU, +/*0453*/ 0xffffffffU, +/*0454*/ 0xffffffffU, +/*0455*/ 0xffffffffU, +/*0456*/ 0xffffffffU, +/*0457*/ 0xffffffffU, +/*0458*/ 0xffffffffU, +/*0459*/ 0xffffffffU, +/*045a*/ 0xffffffffU, +/*045b*/ 0xffffffffU, +/*045c*/ 0xffffffffU, +/*045d*/ 0xffffffffU, +/*045e*/ 0xffffffffU, +/*045f*/ 0x000402b4U, +/*0460*/ 0xffffffffU, +/*0461*/ 0xffffffffU, +/*0462*/ 0xffffffffU, +/*0463*/ 0xffffffffU, +/*0464*/ 0xffffffffU, +/*0465*/ 0xffffffffU, +/*0466*/ 0xffffffffU, +/*0467*/ 0xffffffffU, +/*0468*/ 0xffffffffU, +/*0469*/ 0xffffffffU, +/*046a*/ 0xffffffffU, +/*046b*/ 0xffffffffU, +/*046c*/ 0xffffffffU, +/*046d*/ 0xffffffffU, +/*046e*/ 0xffffffffU, +/*046f*/ 0xffffffffU, +/*0470*/ 0xffffffffU, +/*0471*/ 0xffffffffU, +/*0472*/ 0xffffffffU, +/*0473*/ 0xffffffffU, +/*0474*/ 0xffffffffU, +/*0475*/ 0xffffffffU, +/*0476*/ 0xffffffffU, +/*0477*/ 0xffffffffU, +/*0478*/ 0xffffffffU, +/*0479*/ 0xffffffffU, +/*047a*/ 0xffffffffU, +/*047b*/ 0xffffffffU, +/*047c*/ 0xffffffffU, +/*047d*/ 0xffffffffU, +/*047e*/ 0xffffffffU, +/*047f*/ 0xffffffffU, +/*0480*/ 0xffffffffU, +/*0481*/ 0xffffffffU, +/*0482*/ 0xffffffffU, +/*0483*/ 0xffffffffU, +/*0484*/ 0xffffffffU, +/*0485*/ 0xffffffffU, +/*0486*/ 0xffffffffU, +/*0487*/ 0xffffffffU, +/*0488*/ 0xffffffffU, +/*0489*/ 0xffffffffU, +/*048a*/ 0xffffffffU, +/*048b*/ 0xffffffffU, +/*048c*/ 0xffffffffU, +/*048d*/ 0xffffffffU, +/*048e*/ 0xffffffffU, +/*048f*/ 0xffffffffU, +/*0490*/ 0xffffffffU, +/*0491*/ 0xffffffffU, +/*0492*/ 0xffffffffU, +/*0493*/ 0xffffffffU, +/*0494*/ 0xffffffffU, + }, + { +/*0000*/ 0x00200800U, +/*0001*/ 0x00040801U, +/*0002*/ 0x080b0801U, +/*0003*/ 0xffffffffU, +/*0004*/ 0xffffffffU, +/*0005*/ 0x18010801U, +/*0006*/ 0x00050802U, +/*0007*/ 0x08050802U, +/*0008*/ 0x10050802U, +/*0009*/ 0x18050802U, +/*000a*/ 0x00050803U, +/*000b*/ 0x08050803U, +/*000c*/ 0x10050803U, +/*000d*/ 0x18050803U, +/*000e*/ 0x00050804U, +/*000f*/ 0x08040804U, +/*0010*/ 0x10030804U, +/*0011*/ 0x00180805U, +/*0012*/ 0x18030805U, +/*0013*/ 0x00180806U, +/*0014*/ 0x18020806U, +/*0015*/ 0x00010807U, +/*0016*/ 0x08020807U, +/*0017*/ 0x10010807U, +/*0018*/ 0x18010807U, +/*0019*/ 0x00020808U, +/*001a*/ 0x08040808U, +/*001b*/ 0x10040808U, +/*001c*/ 0x18040808U, +/*001d*/ 0x000a0809U, +/*001e*/ 0x10040809U, +/*001f*/ 0xffffffffU, +/*0020*/ 0xffffffffU, +/*0021*/ 0x18070809U, +/*0022*/ 0xffffffffU, +/*0023*/ 0xffffffffU, +/*0024*/ 0xffffffffU, +/*0025*/ 0xffffffffU, +/*0026*/ 0xffffffffU, +/*0027*/ 0xffffffffU, +/*0028*/ 0x000a080aU, +/*0029*/ 0x1005080aU, +/*002a*/ 0x1801080aU, +/*002b*/ 0x0001080bU, +/*002c*/ 0x0802080bU, +/*002d*/ 0x1009080bU, +/*002e*/ 0x0009080cU, +/*002f*/ 0x1002080cU, +/*0030*/ 0x0020080dU, +/*0031*/ 0xffffffffU, +/*0032*/ 0x0001080eU, +/*0033*/ 0xffffffffU, +/*0034*/ 0xffffffffU, +/*0035*/ 0xffffffffU, +/*0036*/ 0xffffffffU, +/*0037*/ 0x0020080fU, +/*0038*/ 0x00200810U, +/*0039*/ 0x00200811U, +/*003a*/ 0x00200812U, +/*003b*/ 0x00030813U, +/*003c*/ 0x08010813U, +/*003d*/ 0x10030813U, +/*003e*/ 0x18030813U, +/*003f*/ 0x00040814U, +/*0040*/ 0x08040814U, +/*0041*/ 0x10040814U, +/*0042*/ 0x18040814U, +/*0043*/ 0x00010815U, +/*0044*/ 0x08010815U, +/*0045*/ 0x10060815U, +/*0046*/ 0x18040815U, +/*0047*/ 0xffffffffU, +/*0048*/ 0x00060816U, +/*0049*/ 0x08040816U, +/*004a*/ 0x10060816U, +/*004b*/ 0x18040816U, +/*004c*/ 0x00020817U, +/*004d*/ 0x08050817U, +/*004e*/ 0x10080817U, +/*004f*/ 0x00200818U, +/*0050*/ 0x00060819U, +/*0051*/ 0x08030819U, +/*0052*/ 0x100b0819U, +/*0053*/ 0x0004081aU, +/*0054*/ 0x0804081aU, +/*0055*/ 0x1004081aU, +/*0056*/ 0xffffffffU, +/*0057*/ 0x1801081aU, +/*0058*/ 0x0009081bU, +/*0059*/ 0x0020081cU, +/*005a*/ 0x0020081dU, +/*005b*/ 0x0020081eU, +/*005c*/ 0x0020081fU, +/*005d*/ 0x00100820U, +/*005e*/ 0xffffffffU, +/*005f*/ 0x10010820U, +/*0060*/ 0x18060820U, +/*0061*/ 0x00080821U, +/*0062*/ 0x00200822U, +/*0063*/ 0xffffffffU, +/*0064*/ 0x000a0823U, +/*0065*/ 0x10060823U, +/*0066*/ 0x18070823U, +/*0067*/ 0x00080824U, +/*0068*/ 0x08080824U, +/*0069*/ 0x100a0824U, +/*006a*/ 0x00070825U, +/*006b*/ 0x08080825U, +/*006c*/ 0x10080825U, +/*006d*/ 0x18030825U, +/*006e*/ 0x000a0826U, +/*006f*/ 0x100a0826U, +/*0070*/ 0x00110827U, +/*0071*/ 0x00090828U, +/*0072*/ 0x10090828U, +/*0073*/ 0x00100829U, +/*0074*/ 0x100e0829U, +/*0075*/ 0x000e082aU, +/*0076*/ 0x100c082aU, +/*0077*/ 0x000a082bU, +/*0078*/ 0x100a082bU, +/*0079*/ 0x0002082cU, +/*007a*/ 0x0020082dU, +/*007b*/ 0x000b082eU, +/*007c*/ 0x100b082eU, +/*007d*/ 0x0020082fU, +/*007e*/ 0x00120830U, +/*007f*/ 0x00200831U, +/*0080*/ 0x00200832U, +/*0081*/ 0xffffffffU, +/*0082*/ 0xffffffffU, +/*0083*/ 0x00010833U, +/*0084*/ 0x08010833U, +/*0085*/ 0x10080833U, +/*0086*/ 0x000c0834U, +/*0087*/ 0x100c0834U, +/*0088*/ 0x000c0835U, +/*0089*/ 0x100c0835U, +/*008a*/ 0x000c0836U, +/*008b*/ 0x100c0836U, +/*008c*/ 0x000c0837U, +/*008d*/ 0x100c0837U, +/*008e*/ 0x000c0838U, +/*008f*/ 0x100c0838U, +/*0090*/ 0x000c0839U, +/*0091*/ 0x100b0839U, +/*0092*/ 0xffffffffU, +/*0093*/ 0xffffffffU, +/*0094*/ 0x000b083aU, +/*0095*/ 0x100b083aU, +/*0096*/ 0x000b083bU, +/*0097*/ 0x100b083bU, +/*0098*/ 0x000b083cU, +/*0099*/ 0x100b083cU, +/*009a*/ 0x000b083dU, +/*009b*/ 0x100b083dU, +/*009c*/ 0x000b083eU, +/*009d*/ 0x100a083eU, +/*009e*/ 0xffffffffU, +/*009f*/ 0x000a083fU, +/*00a0*/ 0x100a083fU, +/*00a1*/ 0x000a0840U, +/*00a2*/ 0x100a0840U, +/*00a3*/ 0x000a0841U, +/*00a4*/ 0x100a0841U, +/*00a5*/ 0x000a0842U, +/*00a6*/ 0x100a0842U, +/*00a7*/ 0x000a0843U, +/*00a8*/ 0x100a0843U, +/*00a9*/ 0x000a0844U, +/*00aa*/ 0x100a0844U, +/*00ab*/ 0x000a0845U, +/*00ac*/ 0x100a0845U, +/*00ad*/ 0x000a0846U, +/*00ae*/ 0x100a0846U, +/*00af*/ 0x000a0847U, +/*00b0*/ 0x100a0847U, +/*00b1*/ 0x000a0848U, +/*00b2*/ 0x100a0848U, +/*00b3*/ 0x000a0849U, +/*00b4*/ 0x100a0849U, +/*00b5*/ 0x000a084aU, +/*00b6*/ 0x100a084aU, +/*00b7*/ 0x000a084bU, +/*00b8*/ 0x100a084bU, +/*00b9*/ 0x000a084cU, +/*00ba*/ 0x100a084cU, +/*00bb*/ 0x0004084dU, +/*00bc*/ 0x0803084dU, +/*00bd*/ 0x100a084dU, +/*00be*/ 0x000a084eU, +/*00bf*/ 0x1001084eU, +/*00c0*/ 0x000a084fU, +/*00c1*/ 0x1004084fU, +/*00c2*/ 0x000b0850U, +/*00c3*/ 0x100a0850U, +/*00c4*/ 0xffffffffU, +/*00c5*/ 0x00080851U, +/*00c6*/ 0x08080851U, +/*00c7*/ 0x10080851U, +/*00c8*/ 0x18080851U, +/*00c9*/ 0x00080852U, +/*00ca*/ 0xffffffffU, +/*00cb*/ 0x08080852U, +/*00cc*/ 0x10010852U, +/*00cd*/ 0x18080852U, +/*00ce*/ 0x00080853U, +/*00cf*/ 0x08020853U, +/*00d0*/ 0x10020853U, +/*00d1*/ 0x18040853U, +/*00d2*/ 0x00040854U, +/*00d3*/ 0xffffffffU, +/*00d4*/ 0x08040854U, +/*00d5*/ 0x100a0854U, +/*00d6*/ 0x00060855U, +/*00d7*/ 0x08080855U, +/*00d8*/ 0xffffffffU, +/*00d9*/ 0x10040855U, +/*00da*/ 0x18040855U, +/*00db*/ 0x00050856U, +/*00dc*/ 0x08040856U, +/*00dd*/ 0x10050856U, +/*00de*/ 0x000a0857U, +/*00df*/ 0x100a0857U, +/*00e0*/ 0x00080858U, +/*00e1*/ 0xffffffffU, +/*00e2*/ 0x08040858U, +/*00e3*/ 0xffffffffU, +/*00e4*/ 0xffffffffU, +/*00e5*/ 0x00050a00U, +/*00e6*/ 0x08050a00U, +/*00e7*/ 0x10050a00U, +/*00e8*/ 0x18050a00U, +/*00e9*/ 0x00050a01U, +/*00ea*/ 0x08050a01U, +/*00eb*/ 0x100b0a01U, +/*00ec*/ 0x00010a02U, +/*00ed*/ 0x08030a02U, +/*00ee*/ 0x00200a03U, +/*00ef*/ 0xffffffffU, +/*00f0*/ 0x00030a04U, +/*00f1*/ 0x080a0a04U, +/*00f2*/ 0xffffffffU, +/*00f3*/ 0xffffffffU, +/*00f4*/ 0x18030a04U, +/*00f5*/ 0x00030a05U, +/*00f6*/ 0x08010a05U, +/*00f7*/ 0x10010a05U, +/*00f8*/ 0x18060a05U, +/*00f9*/ 0xffffffffU, +/*00fa*/ 0xffffffffU, +/*00fb*/ 0xffffffffU, +/*00fc*/ 0x00020a06U, +/*00fd*/ 0x08030a06U, +/*00fe*/ 0x10010a06U, +/*00ff*/ 0x000f0a07U, +/*0100*/ 0x00200a08U, +/*0101*/ 0x00200a09U, +/*0102*/ 0x000b0a0aU, +/*0103*/ 0x100b0a0aU, +/*0104*/ 0x000b0a0bU, +/*0105*/ 0xffffffffU, +/*0106*/ 0xffffffffU, +/*0107*/ 0x00180a0cU, +/*0108*/ 0x00180a0dU, +/*0109*/ 0x00180a0eU, +/*010a*/ 0x00180a0fU, +/*010b*/ 0x18040a0fU, +/*010c*/ 0x00020a10U, +/*010d*/ 0x08020a10U, +/*010e*/ 0x10040a10U, +/*010f*/ 0x18040a10U, +/*0110*/ 0x00010a11U, +/*0111*/ 0x08010a11U, +/*0112*/ 0x10010a11U, +/*0113*/ 0x18030a11U, +/*0114*/ 0x00200a12U, +/*0115*/ 0x00200a13U, +/*0116*/ 0xffffffffU, +/*0117*/ 0x00140a14U, +/*0118*/ 0x00140a15U, +/*0119*/ 0x00140a16U, +/*011a*/ 0x00140a17U, +/*011b*/ 0x00140a18U, +/*011c*/ 0x00140a19U, +/*011d*/ 0x00140a1aU, +/*011e*/ 0x00140a1bU, +/*011f*/ 0x001e0a1cU, +/*0120*/ 0x000a0a1dU, +/*0121*/ 0x10060a1dU, +/*0122*/ 0x18060a1dU, +/*0123*/ 0x00060a1eU, +/*0124*/ 0xffffffffU, +/*0125*/ 0x08060a1eU, +/*0126*/ 0x00080a1fU, +/*0127*/ 0x080b0a1fU, +/*0128*/ 0x000b0a20U, +/*0129*/ 0x100b0a20U, +/*012a*/ 0x000b0a21U, +/*012b*/ 0x100b0a21U, +/*012c*/ 0x000b0a22U, +/*012d*/ 0x10040a22U, +/*012e*/ 0x000a0a23U, +/*012f*/ 0x10060a23U, +/*0130*/ 0x18080a23U, +/*0131*/ 0xffffffffU, +/*0132*/ 0x00040a24U, +/*0133*/ 0xffffffffU, +/*0134*/ 0xffffffffU, +/*0135*/ 0x00010b80U, +/*0136*/ 0x08020b80U, +/*0137*/ 0x10050b80U, +/*0138*/ 0x18050b80U, +/*0139*/ 0x00050b81U, +/*013a*/ 0x08050b81U, +/*013b*/ 0x100b0b81U, +/*013c*/ 0x00050b82U, +/*013d*/ 0x08010b82U, +/*013e*/ 0x10010b82U, +/*013f*/ 0xffffffffU, +/*0140*/ 0x18010b82U, +/*0141*/ 0x00010b83U, +/*0142*/ 0x08040b83U, +/*0143*/ 0x100b0b83U, +/*0144*/ 0x000b0b84U, +/*0145*/ 0xffffffffU, +/*0146*/ 0x10040b84U, +/*0147*/ 0x000b0b85U, +/*0148*/ 0x10040b85U, +/*0149*/ 0x18010b85U, +/*014a*/ 0x00010b86U, +/*014b*/ 0x08010b86U, +/*014c*/ 0x00200b87U, +/*014d*/ 0x00200b88U, +/*014e*/ 0x00080b89U, +/*014f*/ 0x080a0b89U, +/*0150*/ 0x18050b89U, +/*0151*/ 0x000a0b8aU, +/*0152*/ 0x10030b8aU, +/*0153*/ 0x18030b8aU, +/*0154*/ 0x00010b8bU, +/*0155*/ 0x08020b8bU, +/*0156*/ 0x10010b8bU, +/*0157*/ 0x18010b8bU, +/*0158*/ 0x00010b8cU, +/*0159*/ 0x08030b8cU, +/*015a*/ 0xffffffffU, +/*015b*/ 0x10040b8cU, +/*015c*/ 0x18040b8cU, +/*015d*/ 0x00040b8dU, +/*015e*/ 0x08040b8dU, +/*015f*/ 0xffffffffU, +/*0160*/ 0xffffffffU, +/*0161*/ 0xffffffffU, +/*0162*/ 0xffffffffU, +/*0163*/ 0xffffffffU, +/*0164*/ 0xffffffffU, +/*0165*/ 0xffffffffU, +/*0166*/ 0xffffffffU, +/*0167*/ 0xffffffffU, +/*0168*/ 0x000d0b8eU, +/*0169*/ 0x100d0b8eU, +/*016a*/ 0x000d0b8fU, +/*016b*/ 0x00050b90U, +/*016c*/ 0x00010b91U, +/*016d*/ 0x080e0b91U, +/*016e*/ 0x000e0b92U, +/*016f*/ 0x100e0b92U, +/*0170*/ 0x000e0b93U, +/*0171*/ 0x100e0b93U, +/*0172*/ 0x00040b94U, +/*0173*/ 0x08040b94U, +/*0174*/ 0x10040b94U, +/*0175*/ 0x18040b94U, +/*0176*/ 0x00040b95U, +/*0177*/ 0x080b0b95U, +/*0178*/ 0x000b0b96U, +/*0179*/ 0x100b0b96U, +/*017a*/ 0x000b0b97U, +/*017b*/ 0xffffffffU, +/*017c*/ 0xffffffffU, +/*017d*/ 0xffffffffU, +/*017e*/ 0xffffffffU, +/*017f*/ 0x000d0b98U, +/*0180*/ 0x100d0b98U, +/*0181*/ 0x000d0b99U, +/*0182*/ 0x10100b99U, +/*0183*/ 0x10080b8dU, +/*0184*/ 0x18080b8dU, +/*0185*/ 0x00100b9aU, +/*0186*/ 0x10100b9aU, +/*0187*/ 0x00100b9bU, +/*0188*/ 0x10100b9bU, +/*0189*/ 0x00100b9cU, +/*018a*/ 0x10030b9cU, +/*018b*/ 0x18040b9cU, +/*018c*/ 0x00010b9dU, +/*018d*/ 0x08040b9dU, +/*018e*/ 0xffffffffU, +/*018f*/ 0xffffffffU, +/*0190*/ 0x10010b9dU, +/*0191*/ 0x00140b9eU, +/*0192*/ 0x000a0b9fU, +/*0193*/ 0x100c0b9fU, +/*0194*/ 0x00120ba0U, +/*0195*/ 0x00140ba1U, +/*0196*/ 0x00120ba2U, +/*0197*/ 0x00110ba3U, +/*0198*/ 0x00110ba4U, +/*0199*/ 0x00120ba5U, +/*019a*/ 0x00120ba6U, +/*019b*/ 0x00120ba7U, +/*019c*/ 0x00120ba8U, +/*019d*/ 0x00120ba9U, +/*019e*/ 0x00120baaU, +/*019f*/ 0x00120babU, +/*01a0*/ 0x00120bacU, +/*01a1*/ 0xffffffffU, +/*01a2*/ 0xffffffffU, +/*01a3*/ 0x00190badU, +/*01a4*/ 0x00190baeU, +/*01a5*/ 0x00200bafU, +/*01a6*/ 0x00170bb0U, +/*01a7*/ 0x18080bb0U, +/*01a8*/ 0x00010bb1U, +/*01a9*/ 0x08010bb1U, +/*01aa*/ 0x00200bb2U, +/*01ab*/ 0x00080bb3U, +/*01ac*/ 0xffffffffU, +/*01ad*/ 0x08030bb3U, +/*01ae*/ 0x00180bb4U, +/*01af*/ 0x00180bb5U, +/*01b0*/ 0xffffffffU, +/*01b1*/ 0xffffffffU, +/*01b2*/ 0xffffffffU, +/*01b3*/ 0xffffffffU, +/*01b4*/ 0xffffffffU, +/*01b5*/ 0xffffffffU, +/*01b6*/ 0xffffffffU, +/*01b7*/ 0xffffffffU, +/*01b8*/ 0xffffffffU, +/*01b9*/ 0xffffffffU, +/*01ba*/ 0xffffffffU, +/*01bb*/ 0xffffffffU, +/*01bc*/ 0xffffffffU, +/*01bd*/ 0xffffffffU, +/*01be*/ 0xffffffffU, +/*01bf*/ 0x00100bb6U, +/*01c0*/ 0x10010bb6U, +/*01c1*/ 0x18010bb6U, +/*01c2*/ 0x00050bb7U, +/*01c3*/ 0x00200bb8U, +/*01c4*/ 0x00090bb9U, +/*01c5*/ 0xffffffffU, +/*01c6*/ 0xffffffffU, +/*01c7*/ 0x00200bbaU, +/*01c8*/ 0x00040bbbU, +/*01c9*/ 0x08100bbbU, +/*01ca*/ 0x18060bbbU, +/*01cb*/ 0x00100bbcU, +/*01cc*/ 0xffffffffU, +/*01cd*/ 0x10080bbcU, +/*01ce*/ 0xffffffffU, +/*01cf*/ 0xffffffffU, +/*01d0*/ 0xffffffffU, +/*01d1*/ 0x18030bbcU, +/*01d2*/ 0x00020bbdU, +/*01d3*/ 0xffffffffU, +/*01d4*/ 0x00200bbeU, +/*01d5*/ 0x000b0bbfU, +/*01d6*/ 0xffffffffU, +/*01d7*/ 0xffffffffU, +/*01d8*/ 0xffffffffU, +/*01d9*/ 0x10020bbfU, +/*01da*/ 0xffffffffU, +/*01db*/ 0xffffffffU, +/*01dc*/ 0xffffffffU, +/*01dd*/ 0xffffffffU, +/*01de*/ 0x00010200U, +/*01df*/ 0x08040200U, +/*01e0*/ 0x10100200U, +/*01e1*/ 0x00010201U, +/*01e2*/ 0x08010201U, +/*01e3*/ 0xffffffffU, +/*01e4*/ 0xffffffffU, +/*01e5*/ 0x10100201U, +/*01e6*/ 0xffffffffU, +/*01e7*/ 0xffffffffU, +/*01e8*/ 0xffffffffU, +/*01e9*/ 0xffffffffU, +/*01ea*/ 0xffffffffU, +/*01eb*/ 0xffffffffU, +/*01ec*/ 0xffffffffU, +/*01ed*/ 0xffffffffU, +/*01ee*/ 0xffffffffU, +/*01ef*/ 0x00200202U, +/*01f0*/ 0x00100203U, +/*01f1*/ 0x00200204U, +/*01f2*/ 0x00100205U, +/*01f3*/ 0x00200206U, +/*01f4*/ 0x00100207U, +/*01f5*/ 0x10100207U, +/*01f6*/ 0x00200208U, +/*01f7*/ 0x00200209U, +/*01f8*/ 0x0020020aU, +/*01f9*/ 0x0020020bU, +/*01fa*/ 0x0010020cU, +/*01fb*/ 0x0020020dU, +/*01fc*/ 0x0020020eU, +/*01fd*/ 0x0020020fU, +/*01fe*/ 0x00200210U, +/*01ff*/ 0x00100211U, +/*0200*/ 0x00200212U, +/*0201*/ 0x00200213U, +/*0202*/ 0x00200214U, +/*0203*/ 0x00200215U, +/*0204*/ 0x00090216U, +/*0205*/ 0x10010216U, +/*0206*/ 0x00200217U, +/*0207*/ 0x00050218U, +/*0208*/ 0x08010218U, +/*0209*/ 0x10080218U, +/*020a*/ 0x18080218U, +/*020b*/ 0x001e0219U, +/*020c*/ 0x001e021aU, +/*020d*/ 0x001e021bU, +/*020e*/ 0x001e021cU, +/*020f*/ 0x001e021dU, +/*0210*/ 0x001e021eU, +/*0211*/ 0x001e021fU, +/*0212*/ 0x001e0220U, +/*0213*/ 0x001e0221U, +/*0214*/ 0x001e0222U, +/*0215*/ 0x001e0223U, +/*0216*/ 0x001e0224U, +/*0217*/ 0x001e0225U, +/*0218*/ 0x001e0226U, +/*0219*/ 0x001e0227U, +/*021a*/ 0x001e0228U, +/*021b*/ 0x00010229U, +/*021c*/ 0x08010229U, +/*021d*/ 0x10010229U, +/*021e*/ 0x18040229U, +/*021f*/ 0x0008022aU, +/*0220*/ 0x0808022aU, +/*0221*/ 0x1008022aU, +/*0222*/ 0x1804022aU, +/*0223*/ 0x0005022bU, +/*0224*/ 0x0806022bU, +/*0225*/ 0x1007022bU, +/*0226*/ 0x1805022bU, +/*0227*/ 0x0006022cU, +/*0228*/ 0x0807022cU, +/*0229*/ 0x1005022cU, +/*022a*/ 0x1806022cU, +/*022b*/ 0x0007022dU, +/*022c*/ 0x0802022dU, +/*022d*/ 0x1001022dU, +/*022e*/ 0xffffffffU, +/*022f*/ 0x000a022eU, +/*0230*/ 0x1010022eU, +/*0231*/ 0x000a022fU, +/*0232*/ 0x1010022fU, +/*0233*/ 0x000a0230U, +/*0234*/ 0x10100230U, +/*0235*/ 0xffffffffU, +/*0236*/ 0x00100231U, +/*0237*/ 0xffffffffU, +/*0238*/ 0xffffffffU, +/*0239*/ 0x10010231U, +/*023a*/ 0x18010231U, +/*023b*/ 0x00010232U, +/*023c*/ 0x08010232U, +/*023d*/ 0x10010232U, +/*023e*/ 0x18010232U, +/*023f*/ 0x00020233U, +/*0240*/ 0x08020233U, +/*0241*/ 0x10020233U, +/*0242*/ 0x18020233U, +/*0243*/ 0x00020234U, +/*0244*/ 0x08030234U, +/*0245*/ 0x10010234U, +/*0246*/ 0x18010234U, +/*0247*/ 0x00010235U, +/*0248*/ 0x08010235U, +/*0249*/ 0xffffffffU, +/*024a*/ 0x10020235U, +/*024b*/ 0x18010235U, +/*024c*/ 0x00010236U, +/*024d*/ 0xffffffffU, +/*024e*/ 0x08020236U, +/*024f*/ 0x10010236U, +/*0250*/ 0x18010236U, +/*0251*/ 0xffffffffU, +/*0252*/ 0x00020237U, +/*0253*/ 0x08010237U, +/*0254*/ 0x10010237U, +/*0255*/ 0xffffffffU, +/*0256*/ 0x18020237U, +/*0257*/ 0x00070238U, +/*0258*/ 0x08010238U, +/*0259*/ 0x10010238U, +/*025a*/ 0x18010238U, +/*025b*/ 0x00010239U, +/*025c*/ 0x08010239U, +/*025d*/ 0x10010239U, +/*025e*/ 0xffffffffU, +/*025f*/ 0x18010239U, +/*0260*/ 0x0004023aU, +/*0261*/ 0x0804023aU, +/*0262*/ 0x1004023aU, +/*0263*/ 0x1801023aU, +/*0264*/ 0x0002023bU, +/*0265*/ 0x0806023bU, +/*0266*/ 0x1006023bU, +/*0267*/ 0xffffffffU, +/*0268*/ 0xffffffffU, +/*0269*/ 0xffffffffU, +/*026a*/ 0x1802023bU, +/*026b*/ 0x0010023cU, +/*026c*/ 0x1001023cU, +/*026d*/ 0x1801023cU, +/*026e*/ 0xffffffffU, +/*026f*/ 0x0004023dU, +/*0270*/ 0x0801023dU, +/*0271*/ 0x1004023dU, +/*0272*/ 0x1802023dU, +/*0273*/ 0x0008023eU, +/*0274*/ 0xffffffffU, +/*0275*/ 0xffffffffU, +/*0276*/ 0xffffffffU, +/*0277*/ 0x080a023eU, +/*0278*/ 0x0020023fU, +/*0279*/ 0x00200240U, +/*027a*/ 0x00050241U, +/*027b*/ 0x08010241U, +/*027c*/ 0x10050241U, +/*027d*/ 0x18080241U, +/*027e*/ 0x00010242U, +/*027f*/ 0x08080242U, +/*0280*/ 0x10010242U, +/*0281*/ 0x18080242U, +/*0282*/ 0x00010243U, +/*0283*/ 0x08040243U, +/*0284*/ 0x10040243U, +/*0285*/ 0x18040243U, +/*0286*/ 0x00040244U, +/*0287*/ 0x08040244U, +/*0288*/ 0x10040244U, +/*0289*/ 0x18040244U, +/*028a*/ 0x00040245U, +/*028b*/ 0x08040245U, +/*028c*/ 0x10040245U, +/*028d*/ 0x18010245U, +/*028e*/ 0x00040246U, +/*028f*/ 0x08040246U, +/*0290*/ 0x10040246U, +/*0291*/ 0x18040246U, +/*0292*/ 0x00040247U, +/*0293*/ 0x08040247U, +/*0294*/ 0x10060247U, +/*0295*/ 0x18060247U, +/*0296*/ 0x00060248U, +/*0297*/ 0x08060248U, +/*0298*/ 0x10060248U, +/*0299*/ 0x18060248U, +/*029a*/ 0x00040249U, +/*029b*/ 0x08010249U, +/*029c*/ 0x10010249U, +/*029d*/ 0x18020249U, +/*029e*/ 0xffffffffU, +/*029f*/ 0xffffffffU, +/*02a0*/ 0xffffffffU, +/*02a1*/ 0xffffffffU, +/*02a2*/ 0xffffffffU, +/*02a3*/ 0xffffffffU, +/*02a4*/ 0xffffffffU, +/*02a5*/ 0xffffffffU, +/*02a6*/ 0x0004024aU, +/*02a7*/ 0x0804024aU, +/*02a8*/ 0x1001024aU, +/*02a9*/ 0x1801024aU, +/*02aa*/ 0xffffffffU, +/*02ab*/ 0x0001024bU, +/*02ac*/ 0x0801024bU, +/*02ad*/ 0xffffffffU, +/*02ae*/ 0x1001024bU, +/*02af*/ 0x1801024bU, +/*02b0*/ 0x0001024cU, +/*02b1*/ 0x0804024cU, +/*02b2*/ 0x1004024cU, +/*02b3*/ 0x000a024dU, +/*02b4*/ 0x0020024eU, +/*02b5*/ 0x0004024fU, +/*02b6*/ 0x0808024fU, +/*02b7*/ 0xffffffffU, +/*02b8*/ 0xffffffffU, +/*02b9*/ 0xffffffffU, +/*02ba*/ 0xffffffffU, +/*02bb*/ 0xffffffffU, +/*02bc*/ 0xffffffffU, +/*02bd*/ 0x1002024fU, +/*02be*/ 0x1802024fU, +/*02bf*/ 0x00200250U, +/*02c0*/ 0x00020251U, +/*02c1*/ 0x08100251U, +/*02c2*/ 0x00100252U, +/*02c3*/ 0x10040252U, +/*02c4*/ 0x18040252U, +/*02c5*/ 0x00050253U, +/*02c6*/ 0x08050253U, +/*02c7*/ 0xffffffffU, +/*02c8*/ 0xffffffffU, +/*02c9*/ 0xffffffffU, +/*02ca*/ 0xffffffffU, +/*02cb*/ 0x10010253U, +/*02cc*/ 0x18010253U, +/*02cd*/ 0x00080254U, +/*02ce*/ 0x08080254U, +/*02cf*/ 0x10080254U, +/*02d0*/ 0x18080254U, +/*02d1*/ 0x00080255U, +/*02d2*/ 0x08080255U, +/*02d3*/ 0x10080255U, +/*02d4*/ 0x18080255U, +/*02d5*/ 0x00080256U, +/*02d6*/ 0x08080256U, +/*02d7*/ 0x10080256U, +/*02d8*/ 0xffffffffU, +/*02d9*/ 0xffffffffU, +/*02da*/ 0xffffffffU, +/*02db*/ 0xffffffffU, +/*02dc*/ 0xffffffffU, +/*02dd*/ 0xffffffffU, +/*02de*/ 0x18030256U, +/*02df*/ 0x00010257U, +/*02e0*/ 0x08020257U, +/*02e1*/ 0x10010257U, +/*02e2*/ 0x18040257U, +/*02e3*/ 0x00020258U, +/*02e4*/ 0x08010258U, +/*02e5*/ 0x10010258U, +/*02e6*/ 0xffffffffU, +/*02e7*/ 0x18010258U, +/*02e8*/ 0x00040259U, +/*02e9*/ 0x08080259U, +/*02ea*/ 0x100a0259U, +/*02eb*/ 0x000a025aU, +/*02ec*/ 0x100a025aU, +/*02ed*/ 0x000a025bU, +/*02ee*/ 0x100a025bU, +/*02ef*/ 0x000a025cU, +/*02f0*/ 0x0020025dU, +/*02f1*/ 0x0020025eU, +/*02f2*/ 0x0001025fU, +/*02f3*/ 0xffffffffU, +/*02f4*/ 0xffffffffU, +/*02f5*/ 0xffffffffU, +/*02f6*/ 0x0802025fU, +/*02f7*/ 0x1002025fU, +/*02f8*/ 0x00100260U, +/*02f9*/ 0x10050260U, +/*02fa*/ 0x18060260U, +/*02fb*/ 0x00050261U, +/*02fc*/ 0x08050261U, +/*02fd*/ 0x100e0261U, +/*02fe*/ 0x00050262U, +/*02ff*/ 0x080e0262U, +/*0300*/ 0x18050262U, +/*0301*/ 0x000e0263U, +/*0302*/ 0x10050263U, +/*0303*/ 0x18010263U, +/*0304*/ 0x00050264U, +/*0305*/ 0x08050264U, +/*0306*/ 0x100a0264U, +/*0307*/ 0x000a0265U, +/*0308*/ 0x10050265U, +/*0309*/ 0x18050265U, +/*030a*/ 0x000a0266U, +/*030b*/ 0x100a0266U, +/*030c*/ 0x00050267U, +/*030d*/ 0x08050267U, +/*030e*/ 0x100a0267U, +/*030f*/ 0x000a0268U, +/*0310*/ 0xffffffffU, +/*0311*/ 0xffffffffU, +/*0312*/ 0xffffffffU, +/*0313*/ 0xffffffffU, +/*0314*/ 0xffffffffU, +/*0315*/ 0xffffffffU, +/*0316*/ 0x10070268U, +/*0317*/ 0x18070268U, +/*0318*/ 0x00040269U, +/*0319*/ 0x08040269U, +/*031a*/ 0xffffffffU, +/*031b*/ 0xffffffffU, +/*031c*/ 0xffffffffU, +/*031d*/ 0x10040269U, +/*031e*/ 0x18080269U, +/*031f*/ 0x0008026aU, +/*0320*/ 0x0804026aU, +/*0321*/ 0xffffffffU, +/*0322*/ 0xffffffffU, +/*0323*/ 0xffffffffU, +/*0324*/ 0x1004026aU, +/*0325*/ 0xffffffffU, +/*0326*/ 0xffffffffU, +/*0327*/ 0xffffffffU, +/*0328*/ 0x1804026aU, +/*0329*/ 0xffffffffU, +/*032a*/ 0xffffffffU, +/*032b*/ 0xffffffffU, +/*032c*/ 0x0004026bU, +/*032d*/ 0x0805026bU, +/*032e*/ 0x1007026bU, +/*032f*/ 0x1808026bU, +/*0330*/ 0x0010026cU, +/*0331*/ 0x1008026cU, +/*0332*/ 0x0010026dU, +/*0333*/ 0x1008026dU, +/*0334*/ 0x0010026eU, +/*0335*/ 0x1008026eU, +/*0336*/ 0x1808026eU, +/*0337*/ 0x0001026fU, +/*0338*/ 0x0801026fU, +/*0339*/ 0x1006026fU, +/*033a*/ 0x1806026fU, +/*033b*/ 0x00060270U, +/*033c*/ 0xffffffffU, +/*033d*/ 0x08010270U, +/*033e*/ 0x10030270U, +/*033f*/ 0xffffffffU, +/*0340*/ 0xffffffffU, +/*0341*/ 0xffffffffU, +/*0342*/ 0x000a0271U, +/*0343*/ 0x100a0271U, +/*0344*/ 0x00040272U, +/*0345*/ 0x08010272U, +/*0346*/ 0x10040272U, +/*0347*/ 0xffffffffU, +/*0348*/ 0xffffffffU, +/*0349*/ 0xffffffffU, +/*034a*/ 0xffffffffU, +/*034b*/ 0xffffffffU, +/*034c*/ 0xffffffffU, +/*034d*/ 0x18070272U, +/*034e*/ 0x00070273U, +/*034f*/ 0x08050273U, +/*0350*/ 0x10050273U, +/*0351*/ 0xffffffffU, +/*0352*/ 0xffffffffU, +/*0353*/ 0xffffffffU, +/*0354*/ 0x18040273U, +/*0355*/ 0x00010274U, +/*0356*/ 0x08010274U, +/*0357*/ 0x10020274U, +/*0358*/ 0x18080274U, +/*0359*/ 0x00200275U, +/*035a*/ 0x00200276U, +/*035b*/ 0x00100277U, +/*035c*/ 0xffffffffU, +/*035d*/ 0xffffffffU, +/*035e*/ 0xffffffffU, +/*035f*/ 0x10020277U, +/*0360*/ 0x18010277U, +/*0361*/ 0xffffffffU, +/*0362*/ 0x00020278U, +/*0363*/ 0x08100278U, +/*0364*/ 0x00100279U, +/*0365*/ 0x10100279U, +/*0366*/ 0x0008027aU, +/*0367*/ 0x0808027aU, +/*0368*/ 0x1008027aU, +/*0369*/ 0xffffffffU, +/*036a*/ 0x0010027bU, +/*036b*/ 0x1010027bU, +/*036c*/ 0x0010027cU, +/*036d*/ 0x1008027cU, +/*036e*/ 0x1808027cU, +/*036f*/ 0x0008027dU, +/*0370*/ 0xffffffffU, +/*0371*/ 0x0810027dU, +/*0372*/ 0x0010027eU, +/*0373*/ 0x1010027eU, +/*0374*/ 0x0008027fU, +/*0375*/ 0x0808027fU, +/*0376*/ 0x1008027fU, +/*0377*/ 0xffffffffU, +/*0378*/ 0x1808027fU, +/*0379*/ 0x00100280U, +/*037a*/ 0x10100280U, +/*037b*/ 0x00100281U, +/*037c*/ 0x10080281U, +/*037d*/ 0x18080281U, +/*037e*/ 0x00080282U, +/*037f*/ 0xffffffffU, +/*0380*/ 0x08100282U, +/*0381*/ 0x00100283U, +/*0382*/ 0x10100283U, +/*0383*/ 0x00080284U, +/*0384*/ 0x08080284U, +/*0385*/ 0x10080284U, +/*0386*/ 0xffffffffU, +/*0387*/ 0x00100285U, +/*0388*/ 0x10100285U, +/*0389*/ 0x00100286U, +/*038a*/ 0x10080286U, +/*038b*/ 0x18080286U, +/*038c*/ 0x00080287U, +/*038d*/ 0xffffffffU, +/*038e*/ 0x08080287U, +/*038f*/ 0x10100287U, +/*0390*/ 0x00100288U, +/*0391*/ 0x10100288U, +/*0392*/ 0x00080289U, +/*0393*/ 0x08080289U, +/*0394*/ 0x10080289U, +/*0395*/ 0xffffffffU, +/*0396*/ 0x0010028aU, +/*0397*/ 0x1010028aU, +/*0398*/ 0x0010028bU, +/*0399*/ 0x1008028bU, +/*039a*/ 0x1808028bU, +/*039b*/ 0x0008028cU, +/*039c*/ 0xffffffffU, +/*039d*/ 0x0810028cU, +/*039e*/ 0x0010028dU, +/*039f*/ 0x1010028dU, +/*03a0*/ 0x0008028eU, +/*03a1*/ 0x0808028eU, +/*03a2*/ 0x1008028eU, +/*03a3*/ 0xffffffffU, +/*03a4*/ 0x1808028eU, +/*03a5*/ 0x0010028fU, +/*03a6*/ 0x1010028fU, +/*03a7*/ 0x00100290U, +/*03a8*/ 0x10080290U, +/*03a9*/ 0x18080290U, +/*03aa*/ 0x00080291U, +/*03ab*/ 0xffffffffU, +/*03ac*/ 0x08100291U, +/*03ad*/ 0x00100292U, +/*03ae*/ 0x10100292U, +/*03af*/ 0x00080293U, +/*03b0*/ 0x08080293U, +/*03b1*/ 0x10080293U, +/*03b2*/ 0xffffffffU, +/*03b3*/ 0x00100294U, +/*03b4*/ 0x10100294U, +/*03b5*/ 0x00100295U, +/*03b6*/ 0x10080295U, +/*03b7*/ 0x18080295U, +/*03b8*/ 0x00080296U, +/*03b9*/ 0xffffffffU, +/*03ba*/ 0x08080296U, +/*03bb*/ 0x10020296U, +/*03bc*/ 0x18030296U, +/*03bd*/ 0x000a0297U, +/*03be*/ 0x100a0297U, +/*03bf*/ 0x000a0298U, +/*03c0*/ 0x10050298U, +/*03c1*/ 0x18040298U, +/*03c2*/ 0x00080299U, +/*03c3*/ 0x08080299U, +/*03c4*/ 0x10060299U, +/*03c5*/ 0x18060299U, +/*03c6*/ 0x0011029aU, +/*03c7*/ 0x1808029aU, +/*03c8*/ 0x0004029bU, +/*03c9*/ 0x0806029bU, +/*03ca*/ 0xffffffffU, +/*03cb*/ 0x1006029bU, +/*03cc*/ 0x1808029bU, +/*03cd*/ 0x0008029cU, +/*03ce*/ 0x0804029cU, +/*03cf*/ 0x1008029cU, +/*03d0*/ 0x1808029cU, +/*03d1*/ 0x0006029dU, +/*03d2*/ 0x0806029dU, +/*03d3*/ 0x0011029eU, +/*03d4*/ 0x1808029eU, +/*03d5*/ 0x0004029fU, +/*03d6*/ 0x0806029fU, +/*03d7*/ 0xffffffffU, +/*03d8*/ 0x1006029fU, +/*03d9*/ 0x1808029fU, +/*03da*/ 0x000802a0U, +/*03db*/ 0x080402a0U, +/*03dc*/ 0x100802a0U, +/*03dd*/ 0x180802a0U, +/*03de*/ 0x000602a1U, +/*03df*/ 0x080602a1U, +/*03e0*/ 0x001102a2U, +/*03e1*/ 0x180802a2U, +/*03e2*/ 0x000402a3U, +/*03e3*/ 0x080602a3U, +/*03e4*/ 0xffffffffU, +/*03e5*/ 0x100602a3U, +/*03e6*/ 0x180802a3U, +/*03e7*/ 0x000802a4U, +/*03e8*/ 0x080402a4U, +/*03e9*/ 0x100402a4U, +/*03ea*/ 0x180402a4U, +/*03eb*/ 0x000402a5U, +/*03ec*/ 0x080402a5U, +/*03ed*/ 0x100402a5U, +/*03ee*/ 0x180402a5U, +/*03ef*/ 0x000402a6U, +/*03f0*/ 0x080402a6U, +/*03f1*/ 0x100402a6U, +/*03f2*/ 0x180402a6U, +/*03f3*/ 0x000402a7U, +/*03f4*/ 0x080402a7U, +/*03f5*/ 0x100402a7U, +/*03f6*/ 0x180402a7U, +/*03f7*/ 0x000402a8U, +/*03f8*/ 0x080402a8U, +/*03f9*/ 0x100402a8U, +/*03fa*/ 0x180402a8U, +/*03fb*/ 0x000402a9U, +/*03fc*/ 0x081202a9U, +/*03fd*/ 0x001102aaU, +/*03fe*/ 0x001202abU, +/*03ff*/ 0x002002acU, +/*0400*/ 0x002002adU, +/*0401*/ 0x002002aeU, +/*0402*/ 0x002002afU, +/*0403*/ 0x002002b0U, +/*0404*/ 0x002002b1U, +/*0405*/ 0x002002b2U, +/*0406*/ 0x002002b3U, +/*0407*/ 0x002002b4U, +/*0408*/ 0x000302b5U, +/*0409*/ 0x080502b5U, +/*040a*/ 0x100502b5U, +/*040b*/ 0x180102b5U, +/*040c*/ 0x000502b6U, +/*040d*/ 0x080502b6U, +/*040e*/ 0x100502b6U, +/*040f*/ 0x180502b6U, +/*0410*/ 0x000502b7U, +/*0411*/ 0x080502b7U, +/*0412*/ 0x100502b7U, +/*0413*/ 0x180502b7U, +/*0414*/ 0x000502b8U, +/*0415*/ 0x080502b8U, +/*0416*/ 0x100502b8U, +/*0417*/ 0x180502b8U, +/*0418*/ 0x000502b9U, +/*0419*/ 0x080502b9U, +/*041a*/ 0x100502b9U, +/*041b*/ 0x180502b9U, +/*041c*/ 0x000502baU, +/*041d*/ 0x080502baU, +/*041e*/ 0x100502baU, +/*041f*/ 0x180502baU, +/*0420*/ 0x000502bbU, +/*0421*/ 0x080502bbU, +/*0422*/ 0x100102bbU, +/*0423*/ 0x180202bbU, +/*0424*/ 0x000202bcU, +/*0425*/ 0x080202bcU, +/*0426*/ 0x100202bcU, +/*0427*/ 0x180102bcU, +/*0428*/ 0x000402bdU, +/*0429*/ 0x081002bdU, +/*042a*/ 0x002002beU, +/*042b*/ 0x001002bfU, +/*042c*/ 0x002002c0U, +/*042d*/ 0x001002c1U, +/*042e*/ 0x002002c2U, +/*042f*/ 0x000702c3U, +/*0430*/ 0x080102c3U, +/*0431*/ 0x100202c3U, +/*0432*/ 0x180602c3U, +/*0433*/ 0x000102c4U, +/*0434*/ 0x080102c4U, +/*0435*/ 0x002002c5U, +/*0436*/ 0x000302c6U, +/*0437*/ 0x002002c7U, +/*0438*/ 0x002002c8U, +/*0439*/ 0xffffffffU, +/*043a*/ 0xffffffffU, +/*043b*/ 0xffffffffU, +/*043c*/ 0xffffffffU, +/*043d*/ 0xffffffffU, +/*043e*/ 0xffffffffU, +/*043f*/ 0xffffffffU, +/*0440*/ 0xffffffffU, +/*0441*/ 0xffffffffU, +/*0442*/ 0xffffffffU, +/*0443*/ 0xffffffffU, +/*0444*/ 0xffffffffU, +/*0445*/ 0xffffffffU, +/*0446*/ 0xffffffffU, +/*0447*/ 0xffffffffU, +/*0448*/ 0xffffffffU, +/*0449*/ 0xffffffffU, +/*044a*/ 0xffffffffU, +/*044b*/ 0xffffffffU, +/*044c*/ 0xffffffffU, +/*044d*/ 0xffffffffU, +/*044e*/ 0xffffffffU, +/*044f*/ 0xffffffffU, +/*0450*/ 0xffffffffU, +/*0451*/ 0xffffffffU, +/*0452*/ 0xffffffffU, +/*0453*/ 0xffffffffU, +/*0454*/ 0xffffffffU, +/*0455*/ 0xffffffffU, +/*0456*/ 0xffffffffU, +/*0457*/ 0xffffffffU, +/*0458*/ 0xffffffffU, +/*0459*/ 0xffffffffU, +/*045a*/ 0xffffffffU, +/*045b*/ 0xffffffffU, +/*045c*/ 0xffffffffU, +/*045d*/ 0xffffffffU, +/*045e*/ 0xffffffffU, +/*045f*/ 0x000402c9U, +/*0460*/ 0xffffffffU, +/*0461*/ 0xffffffffU, +/*0462*/ 0xffffffffU, +/*0463*/ 0xffffffffU, +/*0464*/ 0xffffffffU, +/*0465*/ 0xffffffffU, +/*0466*/ 0xffffffffU, +/*0467*/ 0xffffffffU, +/*0468*/ 0xffffffffU, +/*0469*/ 0xffffffffU, +/*046a*/ 0xffffffffU, +/*046b*/ 0xffffffffU, +/*046c*/ 0xffffffffU, +/*046d*/ 0xffffffffU, +/*046e*/ 0xffffffffU, +/*046f*/ 0xffffffffU, +/*0470*/ 0xffffffffU, +/*0471*/ 0xffffffffU, +/*0472*/ 0xffffffffU, +/*0473*/ 0xffffffffU, +/*0474*/ 0xffffffffU, +/*0475*/ 0xffffffffU, +/*0476*/ 0xffffffffU, +/*0477*/ 0xffffffffU, +/*0478*/ 0xffffffffU, +/*0479*/ 0xffffffffU, +/*047a*/ 0xffffffffU, +/*047b*/ 0xffffffffU, +/*047c*/ 0xffffffffU, +/*047d*/ 0xffffffffU, +/*047e*/ 0xffffffffU, +/*047f*/ 0xffffffffU, +/*0480*/ 0xffffffffU, +/*0481*/ 0xffffffffU, +/*0482*/ 0xffffffffU, +/*0483*/ 0xffffffffU, +/*0484*/ 0xffffffffU, +/*0485*/ 0xffffffffU, +/*0486*/ 0xffffffffU, +/*0487*/ 0xffffffffU, +/*0488*/ 0xffffffffU, +/*0489*/ 0xffffffffU, +/*048a*/ 0xffffffffU, +/*048b*/ 0xffffffffU, +/*048c*/ 0xffffffffU, +/*048d*/ 0xffffffffU, +/*048e*/ 0xffffffffU, +/*048f*/ 0xffffffffU, +/*0490*/ 0xffffffffU, +/*0491*/ 0xffffffffU, +/*0492*/ 0xffffffffU, +/*0493*/ 0xffffffffU, +/*0494*/ 0xffffffffU, + }, + { +/*0000*/ 0x00200400U, +/*0001*/ 0x00040401U, +/*0002*/ 0x080b0401U, +/*0003*/ 0x000a0402U, +/*0004*/ 0x10020402U, +/*0005*/ 0x18010402U, +/*0006*/ 0x00050403U, +/*0007*/ 0x08050403U, +/*0008*/ 0x10050403U, +/*0009*/ 0x18050403U, +/*000a*/ 0x00050404U, +/*000b*/ 0x08050404U, +/*000c*/ 0x10050404U, +/*000d*/ 0x18050404U, +/*000e*/ 0x00050405U, +/*000f*/ 0x08040405U, +/*0010*/ 0x10030405U, +/*0011*/ 0x00180406U, +/*0012*/ 0x18030406U, +/*0013*/ 0x00180407U, +/*0014*/ 0x18020407U, +/*0015*/ 0x00010408U, +/*0016*/ 0x08020408U, +/*0017*/ 0x10010408U, +/*0018*/ 0x18010408U, +/*0019*/ 0x00020409U, +/*001a*/ 0x08040409U, +/*001b*/ 0x10040409U, +/*001c*/ 0x18040409U, +/*001d*/ 0xffffffffU, +/*001e*/ 0x0004040aU, +/*001f*/ 0xffffffffU, +/*0020*/ 0xffffffffU, +/*0021*/ 0x0809040aU, +/*0022*/ 0x1801040aU, +/*0023*/ 0x0020040bU, +/*0024*/ 0x001c040cU, +/*0025*/ 0x0001040dU, +/*0026*/ 0x0807040dU, +/*0027*/ 0x1009040dU, +/*0028*/ 0x000a040eU, +/*0029*/ 0x1005040eU, +/*002a*/ 0x1801040eU, +/*002b*/ 0x1001040fU, +/*002c*/ 0x1802040fU, +/*002d*/ 0x0009040fU, +/*002e*/ 0x00090410U, +/*002f*/ 0x10020410U, +/*0030*/ 0x00200411U, +/*0031*/ 0x00010412U, +/*0032*/ 0x08020412U, +/*0033*/ 0xffffffffU, +/*0034*/ 0xffffffffU, +/*0035*/ 0xffffffffU, +/*0036*/ 0xffffffffU, +/*0037*/ 0x00200413U, +/*0038*/ 0x00200414U, +/*0039*/ 0x00200415U, +/*003a*/ 0x00200416U, +/*003b*/ 0x00030417U, +/*003c*/ 0x08010417U, +/*003d*/ 0x10040417U, +/*003e*/ 0x18030417U, +/*003f*/ 0x00040418U, +/*0040*/ 0x08040418U, +/*0041*/ 0x10040418U, +/*0042*/ 0x18040418U, +/*0043*/ 0x00010419U, +/*0044*/ 0x08010419U, +/*0045*/ 0x10060419U, +/*0046*/ 0x18040419U, +/*0047*/ 0xffffffffU, +/*0048*/ 0x0006041aU, +/*0049*/ 0x0804041aU, +/*004a*/ 0x1006041aU, +/*004b*/ 0x1804041aU, +/*004c*/ 0x0002041bU, +/*004d*/ 0x0805041bU, +/*004e*/ 0x1008041bU, +/*004f*/ 0xffffffffU, +/*0050*/ 0x1806041bU, +/*0051*/ 0x0003041cU, +/*0052*/ 0x080b041cU, +/*0053*/ 0x1804041cU, +/*0054*/ 0x0004041dU, +/*0055*/ 0x0804041dU, +/*0056*/ 0x1001041dU, +/*0057*/ 0xffffffffU, +/*0058*/ 0x0009041eU, +/*0059*/ 0x0020041fU, +/*005a*/ 0x00200420U, +/*005b*/ 0x00200421U, +/*005c*/ 0x00200422U, +/*005d*/ 0x00100423U, +/*005e*/ 0xffffffffU, +/*005f*/ 0x10010423U, +/*0060*/ 0x18060423U, +/*0061*/ 0x00080424U, +/*0062*/ 0x00200425U, +/*0063*/ 0x00100426U, +/*0064*/ 0x100a0426U, +/*0065*/ 0x00060427U, +/*0066*/ 0x08070427U, +/*0067*/ 0x10080427U, +/*0068*/ 0x18080427U, +/*0069*/ 0x000a0428U, +/*006a*/ 0x10070428U, +/*006b*/ 0x18080428U, +/*006c*/ 0x00080429U, +/*006d*/ 0x08030429U, +/*006e*/ 0x100a0429U, +/*006f*/ 0x000a042aU, +/*0070*/ 0x0011042bU, +/*0071*/ 0x0009042cU, +/*0072*/ 0x1009042cU, +/*0073*/ 0x0010042dU, +/*0074*/ 0x100e042dU, +/*0075*/ 0x000e042eU, +/*0076*/ 0x0012042fU, +/*0077*/ 0x000a0430U, +/*0078*/ 0x100a0430U, +/*0079*/ 0x00020431U, +/*007a*/ 0x00200432U, +/*007b*/ 0x000b0433U, +/*007c*/ 0x100b0433U, +/*007d*/ 0x00200434U, +/*007e*/ 0x00120435U, +/*007f*/ 0x00200436U, +/*0080*/ 0x00200437U, +/*0081*/ 0x00080438U, +/*0082*/ 0x08010438U, +/*0083*/ 0x10010438U, +/*0084*/ 0x18010438U, +/*0085*/ 0x00080439U, +/*0086*/ 0x080c0439U, +/*0087*/ 0x000c043aU, +/*0088*/ 0x100c043aU, +/*0089*/ 0x000c043bU, +/*008a*/ 0x100c043bU, +/*008b*/ 0x000c043cU, +/*008c*/ 0x100c043cU, +/*008d*/ 0x000c043dU, +/*008e*/ 0x100c043dU, +/*008f*/ 0x000c043eU, +/*0090*/ 0x100c043eU, +/*0091*/ 0x000b043fU, +/*0092*/ 0x1009043fU, +/*0093*/ 0x00010440U, +/*0094*/ 0x000b0441U, +/*0095*/ 0x100b0441U, +/*0096*/ 0x000b0442U, +/*0097*/ 0x100b0442U, +/*0098*/ 0x000b0443U, +/*0099*/ 0x100b0443U, +/*009a*/ 0x000b0444U, +/*009b*/ 0x100b0444U, +/*009c*/ 0x000b0445U, +/*009d*/ 0x100a0445U, +/*009e*/ 0x00020446U, +/*009f*/ 0x080a0446U, +/*00a0*/ 0x000a0447U, +/*00a1*/ 0x100a0447U, +/*00a2*/ 0x000a0448U, +/*00a3*/ 0x100a0448U, +/*00a4*/ 0x000a0449U, +/*00a5*/ 0x100a0449U, +/*00a6*/ 0x000a044aU, +/*00a7*/ 0x100a044aU, +/*00a8*/ 0x000a044bU, +/*00a9*/ 0x100a044bU, +/*00aa*/ 0x000a044cU, +/*00ab*/ 0x100a044cU, +/*00ac*/ 0x000a044dU, +/*00ad*/ 0x100a044dU, +/*00ae*/ 0x000a044eU, +/*00af*/ 0x100a044eU, +/*00b0*/ 0x000a044fU, +/*00b1*/ 0x100a044fU, +/*00b2*/ 0x000a0450U, +/*00b3*/ 0x100a0450U, +/*00b4*/ 0x000a0451U, +/*00b5*/ 0x100a0451U, +/*00b6*/ 0x000a0452U, +/*00b7*/ 0x100a0452U, +/*00b8*/ 0x000a0453U, +/*00b9*/ 0x100a0453U, +/*00ba*/ 0x000a0454U, +/*00bb*/ 0x10040454U, +/*00bc*/ 0x18030454U, +/*00bd*/ 0x000a0455U, +/*00be*/ 0x100a0455U, +/*00bf*/ 0x00010456U, +/*00c0*/ 0x080a0456U, +/*00c1*/ 0x18040456U, +/*00c2*/ 0x000b0457U, +/*00c3*/ 0x100a0457U, +/*00c4*/ 0x00030458U, +/*00c5*/ 0x00080459U, +/*00c6*/ 0x08080459U, +/*00c7*/ 0x10080459U, +/*00c8*/ 0x18080459U, +/*00c9*/ 0x0008045aU, +/*00ca*/ 0xffffffffU, +/*00cb*/ 0x0808045aU, +/*00cc*/ 0x1001045aU, +/*00cd*/ 0x1808045aU, +/*00ce*/ 0x0008045bU, +/*00cf*/ 0x0802045bU, +/*00d0*/ 0x1002045bU, +/*00d1*/ 0x1805045bU, +/*00d2*/ 0x0005045cU, +/*00d3*/ 0xffffffffU, +/*00d4*/ 0x0804045cU, +/*00d5*/ 0x100a045cU, +/*00d6*/ 0x0006045dU, +/*00d7*/ 0x0808045dU, +/*00d8*/ 0x1008045dU, +/*00d9*/ 0x1804045dU, +/*00da*/ 0x0004045eU, +/*00db*/ 0x0805045eU, +/*00dc*/ 0x1004045eU, +/*00dd*/ 0x1805045eU, +/*00de*/ 0x000a045fU, +/*00df*/ 0x100a045fU, +/*00e0*/ 0x00080460U, +/*00e1*/ 0xffffffffU, +/*00e2*/ 0x08040460U, +/*00e3*/ 0xffffffffU, +/*00e4*/ 0xffffffffU, +/*00e5*/ 0x00050600U, +/*00e6*/ 0x08050600U, +/*00e7*/ 0x10050600U, +/*00e8*/ 0x18050600U, +/*00e9*/ 0x00050601U, +/*00ea*/ 0x08050601U, +/*00eb*/ 0x100b0601U, +/*00ec*/ 0x00010602U, +/*00ed*/ 0x08030602U, +/*00ee*/ 0x00200603U, +/*00ef*/ 0x00100604U, +/*00f0*/ 0x10040604U, +/*00f1*/ 0x000a0605U, +/*00f2*/ 0x10090605U, +/*00f3*/ 0x00080606U, +/*00f4*/ 0x08030606U, +/*00f5*/ 0x10030606U, +/*00f6*/ 0x18010606U, +/*00f7*/ 0x00010607U, +/*00f8*/ 0x08070607U, +/*00f9*/ 0x10070607U, +/*00fa*/ 0x18050607U, +/*00fb*/ 0x00010608U, +/*00fc*/ 0x08020608U, +/*00fd*/ 0x10030608U, +/*00fe*/ 0x18010608U, +/*00ff*/ 0x000f0609U, +/*0100*/ 0x0020060aU, +/*0101*/ 0x0020060bU, +/*0102*/ 0x000b060cU, +/*0103*/ 0x100b060cU, +/*0104*/ 0x000b060dU, +/*0105*/ 0x0018060eU, +/*0106*/ 0x0018060fU, +/*0107*/ 0xffffffffU, +/*0108*/ 0xffffffffU, +/*0109*/ 0xffffffffU, +/*010a*/ 0xffffffffU, +/*010b*/ 0xffffffffU, +/*010c*/ 0x1802060fU, +/*010d*/ 0x00020610U, +/*010e*/ 0x08040610U, +/*010f*/ 0x10040610U, +/*0110*/ 0x18010610U, +/*0111*/ 0x00010611U, +/*0112*/ 0x08010611U, +/*0113*/ 0x10030611U, +/*0114*/ 0x00200612U, +/*0115*/ 0x00200613U, +/*0116*/ 0xffffffffU, +/*0117*/ 0x00140614U, +/*0118*/ 0x00140615U, +/*0119*/ 0x00140616U, +/*011a*/ 0x00140617U, +/*011b*/ 0x00140618U, +/*011c*/ 0x00140619U, +/*011d*/ 0x0014061aU, +/*011e*/ 0x0014061bU, +/*011f*/ 0x0018061cU, +/*0120*/ 0x000a061dU, +/*0121*/ 0x1006061dU, +/*0122*/ 0x1806061dU, +/*0123*/ 0x0006061eU, +/*0124*/ 0xffffffffU, +/*0125*/ 0x0806061eU, +/*0126*/ 0x0008061fU, +/*0127*/ 0x080b061fU, +/*0128*/ 0x000b0620U, +/*0129*/ 0x100b0620U, +/*012a*/ 0x000b0621U, +/*012b*/ 0x100b0621U, +/*012c*/ 0x000b0622U, +/*012d*/ 0x10040622U, +/*012e*/ 0x000a0623U, +/*012f*/ 0x10060623U, +/*0130*/ 0x18080623U, +/*0131*/ 0x00080624U, +/*0132*/ 0x08040624U, +/*0133*/ 0x00020680U, +/*0134*/ 0x00010681U, +/*0135*/ 0x08010681U, +/*0136*/ 0x10020681U, +/*0137*/ 0x18050681U, +/*0138*/ 0x00050682U, +/*0139*/ 0x08050682U, +/*013a*/ 0x10050682U, +/*013b*/ 0x000b0683U, +/*013c*/ 0x10050683U, +/*013d*/ 0x18010683U, +/*013e*/ 0x00010684U, +/*013f*/ 0xffffffffU, +/*0140*/ 0x08010684U, +/*0141*/ 0x10010684U, +/*0142*/ 0x18040684U, +/*0143*/ 0x000b0685U, +/*0144*/ 0x100b0685U, +/*0145*/ 0x000b0686U, +/*0146*/ 0x10040686U, +/*0147*/ 0x000b0687U, +/*0148*/ 0x10040687U, +/*0149*/ 0x18010687U, +/*014a*/ 0x00010688U, +/*014b*/ 0x08010688U, +/*014c*/ 0x00200689U, +/*014d*/ 0x0020068aU, +/*014e*/ 0x0008068bU, +/*014f*/ 0x080a068bU, +/*0150*/ 0x1805068bU, +/*0151*/ 0x000a068cU, +/*0152*/ 0x1003068cU, +/*0153*/ 0x1803068cU, +/*0154*/ 0x0001068dU, +/*0155*/ 0x0802068dU, +/*0156*/ 0x1001068dU, +/*0157*/ 0x1801068dU, +/*0158*/ 0x0001068eU, +/*0159*/ 0x0802068eU, +/*015a*/ 0x1001068eU, +/*015b*/ 0x0004068fU, +/*015c*/ 0x0804068fU, +/*015d*/ 0x1004068fU, +/*015e*/ 0x1804068fU, +/*015f*/ 0x00010690U, +/*0160*/ 0x08010690U, +/*0161*/ 0x10010690U, +/*0162*/ 0x00200691U, +/*0163*/ 0x00200692U, +/*0164*/ 0x00200693U, +/*0165*/ 0x00200694U, +/*0166*/ 0xffffffffU, +/*0167*/ 0x1801068eU, +/*0168*/ 0x000d0696U, +/*0169*/ 0x100d0696U, +/*016a*/ 0x000d0697U, +/*016b*/ 0x00050698U, +/*016c*/ 0x00010699U, +/*016d*/ 0x080e0699U, +/*016e*/ 0x000e069aU, +/*016f*/ 0x100e069aU, +/*0170*/ 0x000e069bU, +/*0171*/ 0x100e069bU, +/*0172*/ 0x0004069cU, +/*0173*/ 0x0804069cU, +/*0174*/ 0x1004069cU, +/*0175*/ 0x1804069cU, +/*0176*/ 0x0004069dU, +/*0177*/ 0x080b069dU, +/*0178*/ 0x000b069eU, +/*0179*/ 0x100b069eU, +/*017a*/ 0x000b069fU, +/*017b*/ 0xffffffffU, +/*017c*/ 0xffffffffU, +/*017d*/ 0xffffffffU, +/*017e*/ 0xffffffffU, +/*017f*/ 0x000d06a0U, +/*0180*/ 0x100d06a0U, +/*0181*/ 0x000d06a1U, +/*0182*/ 0x101006a1U, +/*0183*/ 0x00080695U, +/*0184*/ 0x08080695U, +/*0185*/ 0x001006a2U, +/*0186*/ 0x101006a2U, +/*0187*/ 0x001006a3U, +/*0188*/ 0x101006a3U, +/*0189*/ 0x001006a4U, +/*018a*/ 0x100306a4U, +/*018b*/ 0x180406a4U, +/*018c*/ 0x000106a5U, +/*018d*/ 0x080806a5U, +/*018e*/ 0x100106a5U, +/*018f*/ 0x180506a5U, +/*0190*/ 0x000106a6U, +/*0191*/ 0x081406a6U, +/*0192*/ 0x000a06a7U, +/*0193*/ 0x100c06a7U, +/*0194*/ 0x001206a8U, +/*0195*/ 0x001406a9U, +/*0196*/ 0x001206aaU, +/*0197*/ 0x001106abU, +/*0198*/ 0x001106acU, +/*0199*/ 0x001206adU, +/*019a*/ 0x001206aeU, +/*019b*/ 0x001206afU, +/*019c*/ 0x001206b0U, +/*019d*/ 0x001206b1U, +/*019e*/ 0x001206b2U, +/*019f*/ 0x001206b3U, +/*01a0*/ 0x001206b4U, +/*01a1*/ 0x001206b5U, +/*01a2*/ 0x001206b6U, +/*01a3*/ 0x000e06b7U, +/*01a4*/ 0x100d06b7U, +/*01a5*/ 0x002006b8U, +/*01a6*/ 0x001706b9U, +/*01a7*/ 0x000906baU, +/*01a8*/ 0x100106baU, +/*01a9*/ 0x180106baU, +/*01aa*/ 0x002006bbU, +/*01ab*/ 0x000806bcU, +/*01ac*/ 0x080306bcU, +/*01ad*/ 0x100306bcU, +/*01ae*/ 0x001806bdU, +/*01af*/ 0x001806beU, +/*01b0*/ 0x180706beU, +/*01b1*/ 0x000506bfU, +/*01b2*/ 0x080806bfU, +/*01b3*/ 0x100806bfU, +/*01b4*/ 0x180806bfU, +/*01b5*/ 0x000106c0U, +/*01b6*/ 0x080106c0U, +/*01b7*/ 0x002006c1U, +/*01b8*/ 0xffffffffU, +/*01b9*/ 0xffffffffU, +/*01ba*/ 0xffffffffU, +/*01bb*/ 0xffffffffU, +/*01bc*/ 0xffffffffU, +/*01bd*/ 0xffffffffU, +/*01be*/ 0xffffffffU, +/*01bf*/ 0x001006c2U, +/*01c0*/ 0x100106c2U, +/*01c1*/ 0x180106c2U, +/*01c2*/ 0x000206c3U, +/*01c3*/ 0x080406c3U, +/*01c4*/ 0x100906c3U, +/*01c5*/ 0x000706c4U, +/*01c6*/ 0x080406c4U, +/*01c7*/ 0x002006c5U, +/*01c8*/ 0x000106c6U, +/*01c9*/ 0x080206c6U, +/*01ca*/ 0x100606c6U, +/*01cb*/ 0x001006c7U, +/*01cc*/ 0x100106c7U, +/*01cd*/ 0x002006c8U, +/*01ce*/ 0x000806c9U, +/*01cf*/ 0x080106c9U, +/*01d0*/ 0x100506c9U, +/*01d1*/ 0xffffffffU, +/*01d2*/ 0x180206c9U, +/*01d3*/ 0x000106caU, +/*01d4*/ 0x002006cbU, +/*01d5*/ 0x000b06ccU, +/*01d6*/ 0x100106ccU, +/*01d7*/ 0x180306ccU, +/*01d8*/ 0x000806cdU, +/*01d9*/ 0x080206cdU, +/*01da*/ 0x100c06cdU, +/*01db*/ 0x000406ceU, +/*01dc*/ 0x080106ceU, +/*01dd*/ 0xffffffffU, +/*01de*/ 0x00010200U, +/*01df*/ 0x08040200U, +/*01e0*/ 0x10100200U, +/*01e1*/ 0x00010201U, +/*01e2*/ 0x08010201U, +/*01e3*/ 0x10010201U, +/*01e4*/ 0xffffffffU, +/*01e5*/ 0x00100202U, +/*01e6*/ 0x10080202U, +/*01e7*/ 0xffffffffU, +/*01e8*/ 0xffffffffU, +/*01e9*/ 0xffffffffU, +/*01ea*/ 0xffffffffU, +/*01eb*/ 0xffffffffU, +/*01ec*/ 0xffffffffU, +/*01ed*/ 0xffffffffU, +/*01ee*/ 0xffffffffU, +/*01ef*/ 0x00200203U, +/*01f0*/ 0x00100204U, +/*01f1*/ 0x00200205U, +/*01f2*/ 0x00100206U, +/*01f3*/ 0x00200207U, +/*01f4*/ 0x00100208U, +/*01f5*/ 0x00140209U, +/*01f6*/ 0x0020020aU, +/*01f7*/ 0x0020020bU, +/*01f8*/ 0x0020020cU, +/*01f9*/ 0x0020020dU, +/*01fa*/ 0x0014020eU, +/*01fb*/ 0x0020020fU, +/*01fc*/ 0x00200210U, +/*01fd*/ 0x00200211U, +/*01fe*/ 0x00200212U, +/*01ff*/ 0x00140213U, +/*0200*/ 0x00200214U, +/*0201*/ 0x00200215U, +/*0202*/ 0x00200216U, +/*0203*/ 0x00200217U, +/*0204*/ 0x00090218U, +/*0205*/ 0x10010218U, +/*0206*/ 0x00200219U, +/*0207*/ 0x0005021aU, +/*0208*/ 0x0801021aU, +/*0209*/ 0x1008021aU, +/*020a*/ 0x1808021aU, +/*020b*/ 0x001c021bU, +/*020c*/ 0x001c021cU, +/*020d*/ 0x001c021dU, +/*020e*/ 0x001c021eU, +/*020f*/ 0x001c021fU, +/*0210*/ 0x001c0220U, +/*0211*/ 0x001c0221U, +/*0212*/ 0x001c0222U, +/*0213*/ 0x001c0223U, +/*0214*/ 0x001c0224U, +/*0215*/ 0x001c0225U, +/*0216*/ 0x001c0226U, +/*0217*/ 0x001c0227U, +/*0218*/ 0x001c0228U, +/*0219*/ 0x001c0229U, +/*021a*/ 0x001c022aU, +/*021b*/ 0x0001022bU, +/*021c*/ 0x0801022bU, +/*021d*/ 0x1001022bU, +/*021e*/ 0x1804022bU, +/*021f*/ 0x0008022cU, +/*0220*/ 0x0808022cU, +/*0221*/ 0x1008022cU, +/*0222*/ 0x1804022cU, +/*0223*/ 0x0007022dU, +/*0224*/ 0xffffffffU, +/*0225*/ 0x0807022dU, +/*0226*/ 0x1007022dU, +/*0227*/ 0xffffffffU, +/*0228*/ 0x1807022dU, +/*0229*/ 0x0007022eU, +/*022a*/ 0xffffffffU, +/*022b*/ 0x0807022eU, +/*022c*/ 0x1002022eU, +/*022d*/ 0x1801022eU, +/*022e*/ 0x0001022fU, +/*022f*/ 0x080a022fU, +/*0230*/ 0x00140230U, +/*0231*/ 0x000a0231U, +/*0232*/ 0x00140232U, +/*0233*/ 0x000a0233U, +/*0234*/ 0x00140234U, +/*0235*/ 0x18010234U, +/*0236*/ 0x00100235U, +/*0237*/ 0x10050235U, +/*0238*/ 0x18010235U, +/*0239*/ 0x00010236U, +/*023a*/ 0x08010236U, +/*023b*/ 0x10010236U, +/*023c*/ 0x18010236U, +/*023d*/ 0x00010237U, +/*023e*/ 0x08010237U, +/*023f*/ 0x10020237U, +/*0240*/ 0x18020237U, +/*0241*/ 0x00020238U, +/*0242*/ 0x08020238U, +/*0243*/ 0x10020238U, +/*0244*/ 0x18030238U, +/*0245*/ 0x00010239U, +/*0246*/ 0x08010239U, +/*0247*/ 0x10010239U, +/*0248*/ 0x18010239U, +/*0249*/ 0xffffffffU, +/*024a*/ 0x0002023aU, +/*024b*/ 0x0801023aU, +/*024c*/ 0x1001023aU, +/*024d*/ 0xffffffffU, +/*024e*/ 0x1802023aU, +/*024f*/ 0x0001023bU, +/*0250*/ 0x0801023bU, +/*0251*/ 0xffffffffU, +/*0252*/ 0x1002023bU, +/*0253*/ 0x1801023bU, +/*0254*/ 0x0001023cU, +/*0255*/ 0xffffffffU, +/*0256*/ 0x0802023cU, +/*0257*/ 0x1007023cU, +/*0258*/ 0x1801023cU, +/*0259*/ 0x0001023dU, +/*025a*/ 0x0801023dU, +/*025b*/ 0x1001023dU, +/*025c*/ 0x1801023dU, +/*025d*/ 0x0001023eU, +/*025e*/ 0x0801023eU, +/*025f*/ 0x1001023eU, +/*0260*/ 0x1804023eU, +/*0261*/ 0x0004023fU, +/*0262*/ 0x0804023fU, +/*0263*/ 0x1001023fU, +/*0264*/ 0x1802023fU, +/*0265*/ 0x00060240U, +/*0266*/ 0x08060240U, +/*0267*/ 0x10020240U, +/*0268*/ 0x18020240U, +/*0269*/ 0x00020241U, +/*026a*/ 0xffffffffU, +/*026b*/ 0x08100241U, +/*026c*/ 0x18010241U, +/*026d*/ 0x00010242U, +/*026e*/ 0x08010242U, +/*026f*/ 0x10040242U, +/*0270*/ 0x18010242U, +/*0271*/ 0x00040243U, +/*0272*/ 0x08020243U, +/*0273*/ 0x10080243U, +/*0274*/ 0xffffffffU, +/*0275*/ 0xffffffffU, +/*0276*/ 0xffffffffU, +/*0277*/ 0x000a0244U, +/*0278*/ 0x00200245U, +/*0279*/ 0x00200246U, +/*027a*/ 0x00050247U, +/*027b*/ 0x08010247U, +/*027c*/ 0x10050247U, +/*027d*/ 0x18080247U, +/*027e*/ 0x00010248U, +/*027f*/ 0x08080248U, +/*0280*/ 0x10010248U, +/*0281*/ 0x18080248U, +/*0282*/ 0x00010249U, +/*0283*/ 0x08040249U, +/*0284*/ 0x10040249U, +/*0285*/ 0x18040249U, +/*0286*/ 0x0004024aU, +/*0287*/ 0x0804024aU, +/*0288*/ 0x1004024aU, +/*0289*/ 0x1804024aU, +/*028a*/ 0x0004024bU, +/*028b*/ 0x0804024bU, +/*028c*/ 0x1004024bU, +/*028d*/ 0x1801024bU, +/*028e*/ 0x0004024cU, +/*028f*/ 0x0804024cU, +/*0290*/ 0x1004024cU, +/*0291*/ 0x1804024cU, +/*0292*/ 0x0004024dU, +/*0293*/ 0x0804024dU, +/*0294*/ 0x1006024dU, +/*0295*/ 0x1806024dU, +/*0296*/ 0x0006024eU, +/*0297*/ 0x0806024eU, +/*0298*/ 0x1006024eU, +/*0299*/ 0x1806024eU, +/*029a*/ 0xffffffffU, +/*029b*/ 0x0001024fU, +/*029c*/ 0x0801024fU, +/*029d*/ 0x1002024fU, +/*029e*/ 0xffffffffU, +/*029f*/ 0xffffffffU, +/*02a0*/ 0xffffffffU, +/*02a1*/ 0xffffffffU, +/*02a2*/ 0xffffffffU, +/*02a3*/ 0xffffffffU, +/*02a4*/ 0xffffffffU, +/*02a5*/ 0xffffffffU, +/*02a6*/ 0x1804024fU, +/*02a7*/ 0x00040250U, +/*02a8*/ 0x08010250U, +/*02a9*/ 0x10010250U, +/*02aa*/ 0x18010250U, +/*02ab*/ 0x00010251U, +/*02ac*/ 0x08010251U, +/*02ad*/ 0x10010251U, +/*02ae*/ 0x18010251U, +/*02af*/ 0x00010252U, +/*02b0*/ 0x08010252U, +/*02b1*/ 0x10040252U, +/*02b2*/ 0x18040252U, +/*02b3*/ 0x000a0253U, +/*02b4*/ 0x00200254U, +/*02b5*/ 0x00040255U, +/*02b6*/ 0x08080255U, +/*02b7*/ 0x10020255U, +/*02b8*/ 0x18020255U, +/*02b9*/ 0x00020256U, +/*02ba*/ 0x08020256U, +/*02bb*/ 0x10020256U, +/*02bc*/ 0x18020256U, +/*02bd*/ 0xffffffffU, +/*02be*/ 0xffffffffU, +/*02bf*/ 0x00200257U, +/*02c0*/ 0x00020258U, +/*02c1*/ 0x08100258U, +/*02c2*/ 0x00100259U, +/*02c3*/ 0x10040259U, +/*02c4*/ 0x18040259U, +/*02c5*/ 0x0005025aU, +/*02c6*/ 0x0805025aU, +/*02c7*/ 0x0020025bU, +/*02c8*/ 0x0020025cU, +/*02c9*/ 0x0020025dU, +/*02ca*/ 0x0020025eU, +/*02cb*/ 0x0001025fU, +/*02cc*/ 0x0801025fU, +/*02cd*/ 0x1007025fU, +/*02ce*/ 0x1807025fU, +/*02cf*/ 0x00070260U, +/*02d0*/ 0x08070260U, +/*02d1*/ 0x10070260U, +/*02d2*/ 0x18070260U, +/*02d3*/ 0x00070261U, +/*02d4*/ 0x08070261U, +/*02d5*/ 0x10070261U, +/*02d6*/ 0x18070261U, +/*02d7*/ 0x00070262U, +/*02d8*/ 0x08070262U, +/*02d9*/ 0x10070262U, +/*02da*/ 0x18070262U, +/*02db*/ 0x00030263U, +/*02dc*/ 0x08030263U, +/*02dd*/ 0x10030263U, +/*02de*/ 0xffffffffU, +/*02df*/ 0x18010263U, +/*02e0*/ 0x00020264U, +/*02e1*/ 0x08010264U, +/*02e2*/ 0x10040264U, +/*02e3*/ 0x18020264U, +/*02e4*/ 0x00010265U, +/*02e5*/ 0x08010265U, +/*02e6*/ 0x10010265U, +/*02e7*/ 0x18010265U, +/*02e8*/ 0x00040266U, +/*02e9*/ 0x08080266U, +/*02ea*/ 0x100a0266U, +/*02eb*/ 0x000a0267U, +/*02ec*/ 0x100a0267U, +/*02ed*/ 0x000a0268U, +/*02ee*/ 0x100a0268U, +/*02ef*/ 0x000a0269U, +/*02f0*/ 0x0020026aU, +/*02f1*/ 0x0020026bU, +/*02f2*/ 0x0001026cU, +/*02f3*/ 0x0802026cU, +/*02f4*/ 0x1002026cU, +/*02f5*/ 0x1802026cU, +/*02f6*/ 0xffffffffU, +/*02f7*/ 0x0002026dU, +/*02f8*/ 0x0810026dU, +/*02f9*/ 0x1805026dU, +/*02fa*/ 0x0006026eU, +/*02fb*/ 0x0805026eU, +/*02fc*/ 0x1005026eU, +/*02fd*/ 0x000e026fU, +/*02fe*/ 0x1005026fU, +/*02ff*/ 0x000e0270U, +/*0300*/ 0x10050270U, +/*0301*/ 0x000e0271U, +/*0302*/ 0x10050271U, +/*0303*/ 0x18010271U, +/*0304*/ 0x00050272U, +/*0305*/ 0x08050272U, +/*0306*/ 0x100a0272U, +/*0307*/ 0x000a0273U, +/*0308*/ 0x10050273U, +/*0309*/ 0x18050273U, +/*030a*/ 0x000a0274U, +/*030b*/ 0x100a0274U, +/*030c*/ 0x00050275U, +/*030d*/ 0x08050275U, +/*030e*/ 0x100a0275U, +/*030f*/ 0x000a0276U, +/*0310*/ 0xffffffffU, +/*0311*/ 0xffffffffU, +/*0312*/ 0xffffffffU, +/*0313*/ 0xffffffffU, +/*0314*/ 0xffffffffU, +/*0315*/ 0xffffffffU, +/*0316*/ 0x10070276U, +/*0317*/ 0x18070276U, +/*0318*/ 0x00040277U, +/*0319*/ 0x08040277U, +/*031a*/ 0xffffffffU, +/*031b*/ 0xffffffffU, +/*031c*/ 0xffffffffU, +/*031d*/ 0x10040277U, +/*031e*/ 0x18080277U, +/*031f*/ 0x00080278U, +/*0320*/ 0x08040278U, +/*0321*/ 0xffffffffU, +/*0322*/ 0xffffffffU, +/*0323*/ 0xffffffffU, +/*0324*/ 0x10040278U, +/*0325*/ 0xffffffffU, +/*0326*/ 0xffffffffU, +/*0327*/ 0xffffffffU, +/*0328*/ 0x18040278U, +/*0329*/ 0xffffffffU, +/*032a*/ 0xffffffffU, +/*032b*/ 0xffffffffU, +/*032c*/ 0x00040279U, +/*032d*/ 0x08050279U, +/*032e*/ 0x10070279U, +/*032f*/ 0x18080279U, +/*0330*/ 0x0010027aU, +/*0331*/ 0x1008027aU, +/*0332*/ 0x0010027bU, +/*0333*/ 0x1008027bU, +/*0334*/ 0x0010027cU, +/*0335*/ 0x1008027cU, +/*0336*/ 0x1808027cU, +/*0337*/ 0x0001027dU, +/*0338*/ 0x0801027dU, +/*0339*/ 0x1006027dU, +/*033a*/ 0x1806027dU, +/*033b*/ 0x0006027eU, +/*033c*/ 0x0801027eU, +/*033d*/ 0x1001027eU, +/*033e*/ 0x1803027eU, +/*033f*/ 0x000a027fU, +/*0340*/ 0x100a027fU, +/*0341*/ 0x000a0280U, +/*0342*/ 0xffffffffU, +/*0343*/ 0x100a0280U, +/*0344*/ 0x00040281U, +/*0345*/ 0x08010281U, +/*0346*/ 0x10040281U, +/*0347*/ 0xffffffffU, +/*0348*/ 0xffffffffU, +/*0349*/ 0xffffffffU, +/*034a*/ 0xffffffffU, +/*034b*/ 0xffffffffU, +/*034c*/ 0xffffffffU, +/*034d*/ 0x18070281U, +/*034e*/ 0x00070282U, +/*034f*/ 0x08050282U, +/*0350*/ 0x10050282U, +/*0351*/ 0xffffffffU, +/*0352*/ 0xffffffffU, +/*0353*/ 0xffffffffU, +/*0354*/ 0x18040282U, +/*0355*/ 0x00010283U, +/*0356*/ 0x08010283U, +/*0357*/ 0x10020283U, +/*0358*/ 0x18080283U, +/*0359*/ 0x00200284U, +/*035a*/ 0x00200285U, +/*035b*/ 0x00100286U, +/*035c*/ 0x10020286U, +/*035d*/ 0x18020286U, +/*035e*/ 0x00020287U, +/*035f*/ 0xffffffffU, +/*0360*/ 0x08010287U, +/*0361*/ 0x10010287U, +/*0362*/ 0x18020287U, +/*0363*/ 0x00080288U, +/*0364*/ 0x08080288U, +/*0365*/ 0x10080288U, +/*0366*/ 0x18080288U, +/*0367*/ 0x00080289U, +/*0368*/ 0x08080289U, +/*0369*/ 0xffffffffU, +/*036a*/ 0x10080289U, +/*036b*/ 0x18080289U, +/*036c*/ 0x0008028aU, +/*036d*/ 0x0808028aU, +/*036e*/ 0x1008028aU, +/*036f*/ 0x1808028aU, +/*0370*/ 0xffffffffU, +/*0371*/ 0x0008028bU, +/*0372*/ 0x0808028bU, +/*0373*/ 0x1008028bU, +/*0374*/ 0x1808028bU, +/*0375*/ 0x0008028cU, +/*0376*/ 0x0808028cU, +/*0377*/ 0xffffffffU, +/*0378*/ 0x1008028cU, +/*0379*/ 0x1808028cU, +/*037a*/ 0x0008028dU, +/*037b*/ 0x0808028dU, +/*037c*/ 0x1008028dU, +/*037d*/ 0x1808028dU, +/*037e*/ 0x0008028eU, +/*037f*/ 0xffffffffU, +/*0380*/ 0x0808028eU, +/*0381*/ 0x1008028eU, +/*0382*/ 0x1808028eU, +/*0383*/ 0x0008028fU, +/*0384*/ 0x0808028fU, +/*0385*/ 0x1008028fU, +/*0386*/ 0xffffffffU, +/*0387*/ 0x1808028fU, +/*0388*/ 0x00080290U, +/*0389*/ 0x08080290U, +/*038a*/ 0x10080290U, +/*038b*/ 0x18080290U, +/*038c*/ 0x00080291U, +/*038d*/ 0xffffffffU, +/*038e*/ 0x08080291U, +/*038f*/ 0x10080291U, +/*0390*/ 0x18080291U, +/*0391*/ 0x00080292U, +/*0392*/ 0x08080292U, +/*0393*/ 0x10080292U, +/*0394*/ 0x18080292U, +/*0395*/ 0xffffffffU, +/*0396*/ 0x00080293U, +/*0397*/ 0x08080293U, +/*0398*/ 0x10080293U, +/*0399*/ 0x18080293U, +/*039a*/ 0x00080294U, +/*039b*/ 0x08080294U, +/*039c*/ 0xffffffffU, +/*039d*/ 0x10080294U, +/*039e*/ 0x18080294U, +/*039f*/ 0x00080295U, +/*03a0*/ 0x08080295U, +/*03a1*/ 0x10080295U, +/*03a2*/ 0x18080295U, +/*03a3*/ 0xffffffffU, +/*03a4*/ 0x00080296U, +/*03a5*/ 0x08080296U, +/*03a6*/ 0x10080296U, +/*03a7*/ 0x18080296U, +/*03a8*/ 0x00080297U, +/*03a9*/ 0x08080297U, +/*03aa*/ 0x10080297U, +/*03ab*/ 0xffffffffU, +/*03ac*/ 0x18080297U, +/*03ad*/ 0x00080298U, +/*03ae*/ 0x08080298U, +/*03af*/ 0x10080298U, +/*03b0*/ 0x18080298U, +/*03b1*/ 0x00080299U, +/*03b2*/ 0xffffffffU, +/*03b3*/ 0x08080299U, +/*03b4*/ 0x10080299U, +/*03b5*/ 0x18080299U, +/*03b6*/ 0x0008029aU, +/*03b7*/ 0x0808029aU, +/*03b8*/ 0x1008029aU, +/*03b9*/ 0xffffffffU, +/*03ba*/ 0x1808029aU, +/*03bb*/ 0x0002029bU, +/*03bc*/ 0x0803029bU, +/*03bd*/ 0x100a029bU, +/*03be*/ 0x000a029cU, +/*03bf*/ 0x100a029cU, +/*03c0*/ 0x0005029dU, +/*03c1*/ 0x0808029dU, +/*03c2*/ 0x1008029dU, +/*03c3*/ 0x1808029dU, +/*03c4*/ 0x0006029eU, +/*03c5*/ 0x0806029eU, +/*03c6*/ 0x0011029fU, +/*03c7*/ 0x1808029fU, +/*03c8*/ 0x000402a0U, +/*03c9*/ 0x080602a0U, +/*03ca*/ 0xffffffffU, +/*03cb*/ 0x100602a0U, +/*03cc*/ 0x180802a0U, +/*03cd*/ 0xffffffffU, +/*03ce*/ 0x000802a1U, +/*03cf*/ 0x080802a1U, +/*03d0*/ 0x100802a1U, +/*03d1*/ 0x180602a1U, +/*03d2*/ 0x000602a2U, +/*03d3*/ 0x081102a2U, +/*03d4*/ 0x000802a3U, +/*03d5*/ 0x080402a3U, +/*03d6*/ 0x100602a3U, +/*03d7*/ 0xffffffffU, +/*03d8*/ 0x180602a3U, +/*03d9*/ 0x000802a4U, +/*03da*/ 0xffffffffU, +/*03db*/ 0x080802a4U, +/*03dc*/ 0x100802a4U, +/*03dd*/ 0x180802a4U, +/*03de*/ 0x000602a5U, +/*03df*/ 0x080602a5U, +/*03e0*/ 0x001102a6U, +/*03e1*/ 0x180802a6U, +/*03e2*/ 0x000402a7U, +/*03e3*/ 0x080602a7U, +/*03e4*/ 0xffffffffU, +/*03e5*/ 0x100602a7U, +/*03e6*/ 0x180802a7U, +/*03e7*/ 0xffffffffU, +/*03e8*/ 0x000402a8U, +/*03e9*/ 0x080402a8U, +/*03ea*/ 0x100402a8U, +/*03eb*/ 0x180402a8U, +/*03ec*/ 0x000402a9U, +/*03ed*/ 0x080402a9U, +/*03ee*/ 0x100402a9U, +/*03ef*/ 0x180402a9U, +/*03f0*/ 0x000402aaU, +/*03f1*/ 0x080402aaU, +/*03f2*/ 0x100402aaU, +/*03f3*/ 0x180402aaU, +/*03f4*/ 0x000402abU, +/*03f5*/ 0x080402abU, +/*03f6*/ 0x100402abU, +/*03f7*/ 0x180402abU, +/*03f8*/ 0x000402acU, +/*03f9*/ 0x080402acU, +/*03fa*/ 0x100402acU, +/*03fb*/ 0x180402acU, +/*03fc*/ 0x001202adU, +/*03fd*/ 0x001102aeU, +/*03fe*/ 0x001202afU, +/*03ff*/ 0x002002b0U, +/*0400*/ 0x002002b1U, +/*0401*/ 0x002002b2U, +/*0402*/ 0x002002b3U, +/*0403*/ 0x002002b4U, +/*0404*/ 0x002002b5U, +/*0405*/ 0x002002b6U, +/*0406*/ 0x002002b7U, +/*0407*/ 0x002002b8U, +/*0408*/ 0x000202b9U, +/*0409*/ 0x080502b9U, +/*040a*/ 0x100502b9U, +/*040b*/ 0x180102b9U, +/*040c*/ 0x000402baU, +/*040d*/ 0x080402baU, +/*040e*/ 0x100402baU, +/*040f*/ 0x180402baU, +/*0410*/ 0x000402bbU, +/*0411*/ 0x080402bbU, +/*0412*/ 0x100402bbU, +/*0413*/ 0x180402bbU, +/*0414*/ 0xffffffffU, +/*0415*/ 0xffffffffU, +/*0416*/ 0xffffffffU, +/*0417*/ 0xffffffffU, +/*0418*/ 0xffffffffU, +/*0419*/ 0xffffffffU, +/*041a*/ 0x000402bcU, +/*041b*/ 0x080402bcU, +/*041c*/ 0x100402bcU, +/*041d*/ 0x180402bcU, +/*041e*/ 0x000402bdU, +/*041f*/ 0x080402bdU, +/*0420*/ 0x100402bdU, +/*0421*/ 0x180402bdU, +/*0422*/ 0x000102beU, +/*0423*/ 0x080202beU, +/*0424*/ 0x100202beU, +/*0425*/ 0x180202beU, +/*0426*/ 0x000202bfU, +/*0427*/ 0x080102bfU, +/*0428*/ 0x100402bfU, +/*0429*/ 0x001002c0U, +/*042a*/ 0x002002c1U, +/*042b*/ 0x001002c2U, +/*042c*/ 0x002002c3U, +/*042d*/ 0x001002c4U, +/*042e*/ 0x002002c5U, +/*042f*/ 0x000702c6U, +/*0430*/ 0x080102c6U, +/*0431*/ 0x100202c6U, +/*0432*/ 0x180602c6U, +/*0433*/ 0x000102c7U, +/*0434*/ 0x080102c7U, +/*0435*/ 0x002002c8U, +/*0436*/ 0x000202c9U, +/*0437*/ 0x002002caU, +/*0438*/ 0x002002cbU, +/*0439*/ 0x000c02ccU, +/*043a*/ 0x100c02ccU, +/*043b*/ 0x002002cdU, +/*043c*/ 0x000302ceU, +/*043d*/ 0x002002cfU, +/*043e*/ 0x000302d0U, +/*043f*/ 0x002002d1U, +/*0440*/ 0x000302d2U, +/*0441*/ 0x002002d3U, +/*0442*/ 0x000302d4U, +/*0443*/ 0x002002d5U, +/*0444*/ 0x000302d6U, +/*0445*/ 0x002002d7U, +/*0446*/ 0x000302d8U, +/*0447*/ 0x002002d9U, +/*0448*/ 0x000302daU, +/*0449*/ 0x002002dbU, +/*044a*/ 0x000302dcU, +/*044b*/ 0x002002ddU, +/*044c*/ 0x000302deU, +/*044d*/ 0x002002dfU, +/*044e*/ 0x000302e0U, +/*044f*/ 0x080302e0U, +/*0450*/ 0x100202e0U, +/*0451*/ 0x180202e0U, +/*0452*/ 0x002002e1U, +/*0453*/ 0x002002e2U, +/*0454*/ 0x002002e3U, +/*0455*/ 0x002002e4U, +/*0456*/ 0x000402e5U, +/*0457*/ 0x001e02e6U, +/*0458*/ 0x001e02e7U, +/*0459*/ 0x001e02e8U, +/*045a*/ 0x001e02e9U, +/*045b*/ 0x001e02eaU, +/*045c*/ 0x001e02ebU, +/*045d*/ 0x001e02ecU, +/*045e*/ 0x001e02edU, +/*045f*/ 0x000402eeU, +/*0460*/ 0xffffffffU, +/*0461*/ 0xffffffffU, +/*0462*/ 0xffffffffU, +/*0463*/ 0xffffffffU, +/*0464*/ 0x080402eeU, +/*0465*/ 0x100102eeU, +/*0466*/ 0x180802eeU, +/*0467*/ 0x000402efU, +/*0468*/ 0x080102efU, +/*0469*/ 0x100802efU, +/*046a*/ 0x180402efU, +/*046b*/ 0x000102f0U, +/*046c*/ 0x080802f0U, +/*046d*/ 0x100402f0U, +/*046e*/ 0x180102f0U, +/*046f*/ 0x000802f1U, +/*0470*/ 0x080402f1U, +/*0471*/ 0x100102f1U, +/*0472*/ 0x180802f1U, +/*0473*/ 0x000402f2U, +/*0474*/ 0x080102f2U, +/*0475*/ 0x100802f2U, +/*0476*/ 0x180402f2U, +/*0477*/ 0x000102f3U, +/*0478*/ 0x080802f3U, +/*0479*/ 0x100402f3U, +/*047a*/ 0x180102f3U, +/*047b*/ 0x000802f4U, +/*047c*/ 0x080802f4U, +/*047d*/ 0x100102f4U, +/*047e*/ 0x180502f4U, +/*047f*/ 0xffffffffU, +/*0480*/ 0xffffffffU, +/*0481*/ 0xffffffffU, +/*0482*/ 0xffffffffU, +/*0483*/ 0xffffffffU, +/*0484*/ 0xffffffffU, +/*0485*/ 0xffffffffU, +/*0486*/ 0xffffffffU, +/*0487*/ 0xffffffffU, +/*0488*/ 0xffffffffU, +/*0489*/ 0xffffffffU, +/*048a*/ 0xffffffffU, +/*048b*/ 0xffffffffU, +/*048c*/ 0xffffffffU, +/*048d*/ 0xffffffffU, +/*048e*/ 0xffffffffU, +/*048f*/ 0xffffffffU, +/*0490*/ 0xffffffffU, +/*0491*/ 0xffffffffU, +/*0492*/ 0xffffffffU, +/*0493*/ 0xffffffffU, +/*0494*/ 0xffffffffU, + }, + { +/*0000*/ 0x00200800U, +/*0001*/ 0x00040801U, +/*0002*/ 0x080b0801U, +/*0003*/ 0x000a0802U, +/*0004*/ 0x10020802U, +/*0005*/ 0x18010802U, +/*0006*/ 0x00060803U, +/*0007*/ 0x08060803U, +/*0008*/ 0x10060803U, +/*0009*/ 0x18060803U, +/*000a*/ 0x00060804U, +/*000b*/ 0x08060804U, +/*000c*/ 0x10050804U, +/*000d*/ 0x18060804U, +/*000e*/ 0x00060805U, +/*000f*/ 0x08040805U, +/*0010*/ 0x10030805U, +/*0011*/ 0x00180806U, +/*0012*/ 0x18030806U, +/*0013*/ 0x00180807U, +/*0014*/ 0x18020807U, +/*0015*/ 0x0801085eU, +/*0016*/ 0x00020808U, +/*0017*/ 0x08010808U, +/*0018*/ 0x10010808U, +/*0019*/ 0x18020808U, +/*001a*/ 0x00050809U, +/*001b*/ 0x08050809U, +/*001c*/ 0x10040809U, +/*001d*/ 0xffffffffU, +/*001e*/ 0x18040809U, +/*001f*/ 0x0002080aU, +/*0020*/ 0x0805080aU, +/*0021*/ 0x1009080aU, +/*0022*/ 0x0001080bU, +/*0023*/ 0x0020080cU, +/*0024*/ 0x001c080dU, +/*0025*/ 0x0001080eU, +/*0026*/ 0x0807080eU, +/*0027*/ 0x1009080eU, +/*0028*/ 0x000a080fU, +/*0029*/ 0x1005080fU, +/*002a*/ 0x1801080fU, +/*002b*/ 0x10010810U, +/*002c*/ 0x18020810U, +/*002d*/ 0x00090810U, +/*002e*/ 0x00090811U, +/*002f*/ 0x10020811U, +/*0030*/ 0x00200812U, +/*0031*/ 0x00010813U, +/*0032*/ 0x08020813U, +/*0033*/ 0x00200814U, +/*0034*/ 0x00200815U, +/*0035*/ 0x00200816U, +/*0036*/ 0x00200817U, +/*0037*/ 0xffffffffU, +/*0038*/ 0xffffffffU, +/*0039*/ 0xffffffffU, +/*003a*/ 0xffffffffU, +/*003b*/ 0x00030818U, +/*003c*/ 0x08010818U, +/*003d*/ 0x10040818U, +/*003e*/ 0x18030818U, +/*003f*/ 0x00040819U, +/*0040*/ 0x08040819U, +/*0041*/ 0x10040819U, +/*0042*/ 0x18040819U, +/*0043*/ 0x0001081aU, +/*0044*/ 0x0801081aU, +/*0045*/ 0x1006081aU, +/*0046*/ 0x1804081aU, +/*0047*/ 0x0008081bU, +/*0048*/ 0x0806081bU, +/*0049*/ 0x1004081bU, +/*004a*/ 0x1806081bU, +/*004b*/ 0x0004081cU, +/*004c*/ 0x0802081cU, +/*004d*/ 0x1005081cU, +/*004e*/ 0x1808081cU, +/*004f*/ 0xffffffffU, +/*0050*/ 0x0006081dU, +/*0051*/ 0x0803081dU, +/*0052*/ 0x100b081dU, +/*0053*/ 0x0004081eU, +/*0054*/ 0x0804081eU, +/*0055*/ 0x1004081eU, +/*0056*/ 0x1801081eU, +/*0057*/ 0xffffffffU, +/*0058*/ 0x0009081fU, +/*0059*/ 0x00200820U, +/*005a*/ 0x00200821U, +/*005b*/ 0x00200822U, +/*005c*/ 0x00200823U, +/*005d*/ 0x00100824U, +/*005e*/ 0xffffffffU, +/*005f*/ 0x10010824U, +/*0060*/ 0x18060824U, +/*0061*/ 0x00080825U, +/*0062*/ 0x00200826U, +/*0063*/ 0x00100827U, +/*0064*/ 0x100b0827U, +/*0065*/ 0x00070828U, +/*0066*/ 0x08070828U, +/*0067*/ 0x10090828U, +/*0068*/ 0x00090829U, +/*0069*/ 0x100b0829U, +/*006a*/ 0x0007082aU, +/*006b*/ 0x0808082aU, +/*006c*/ 0x1009082aU, +/*006d*/ 0x0003082bU, +/*006e*/ 0x080a082bU, +/*006f*/ 0x000a082cU, +/*0070*/ 0x0011082dU, +/*0071*/ 0x000a082eU, +/*0072*/ 0x100a082eU, +/*0073*/ 0x0010082fU, +/*0074*/ 0x100e082fU, +/*0075*/ 0x000e0830U, +/*0076*/ 0x00120831U, +/*0077*/ 0x000a0832U, +/*0078*/ 0x100a0832U, +/*0079*/ 0x00020833U, +/*007a*/ 0x00200834U, +/*007b*/ 0x000b0835U, +/*007c*/ 0x100b0835U, +/*007d*/ 0x00200836U, +/*007e*/ 0x00130837U, +/*007f*/ 0x00200838U, +/*0080*/ 0x00200839U, +/*0081*/ 0x0008083aU, +/*0082*/ 0x0801083aU, +/*0083*/ 0x1001083aU, +/*0084*/ 0x1801083aU, +/*0085*/ 0x0008083bU, +/*0086*/ 0x080c083bU, +/*0087*/ 0x000c083cU, +/*0088*/ 0x100c083cU, +/*0089*/ 0x000c083dU, +/*008a*/ 0x100c083dU, +/*008b*/ 0x000c083eU, +/*008c*/ 0x100c083eU, +/*008d*/ 0x000c083fU, +/*008e*/ 0x100c083fU, +/*008f*/ 0x000c0840U, +/*0090*/ 0x100c0840U, +/*0091*/ 0x000b0841U, +/*0092*/ 0x10090841U, +/*0093*/ 0x00010842U, +/*0094*/ 0x000b0843U, +/*0095*/ 0x100b0843U, +/*0096*/ 0x000b0844U, +/*0097*/ 0x100b0844U, +/*0098*/ 0x000b0845U, +/*0099*/ 0x100b0845U, +/*009a*/ 0x000b0846U, +/*009b*/ 0x100b0846U, +/*009c*/ 0x000b0847U, +/*009d*/ 0x100a0847U, +/*009e*/ 0x00020848U, +/*009f*/ 0x080a0848U, +/*00a0*/ 0x000a0849U, +/*00a1*/ 0x100a0849U, +/*00a2*/ 0x000a084aU, +/*00a3*/ 0x100a084aU, +/*00a4*/ 0x000a084bU, +/*00a5*/ 0x100a084bU, +/*00a6*/ 0x000a084cU, +/*00a7*/ 0x100a084cU, +/*00a8*/ 0x000a084dU, +/*00a9*/ 0x100a084dU, +/*00aa*/ 0x000a084eU, +/*00ab*/ 0x100a084eU, +/*00ac*/ 0x000a084fU, +/*00ad*/ 0x100a084fU, +/*00ae*/ 0x000a0850U, +/*00af*/ 0x100a0850U, +/*00b0*/ 0x000a0851U, +/*00b1*/ 0x100a0851U, +/*00b2*/ 0x000a0852U, +/*00b3*/ 0x100a0852U, +/*00b4*/ 0x000a0853U, +/*00b5*/ 0x100a0853U, +/*00b6*/ 0x000a0854U, +/*00b7*/ 0x100a0854U, +/*00b8*/ 0x000a0855U, +/*00b9*/ 0x100a0855U, +/*00ba*/ 0x000a0856U, +/*00bb*/ 0x10040856U, +/*00bc*/ 0x18030856U, +/*00bd*/ 0x000a0857U, +/*00be*/ 0x100a0857U, +/*00bf*/ 0x00010858U, +/*00c0*/ 0x080a0858U, +/*00c1*/ 0x18040858U, +/*00c2*/ 0x000b0859U, +/*00c3*/ 0x100a0859U, +/*00c4*/ 0x0003085aU, +/*00c5*/ 0x0008085bU, +/*00c6*/ 0x0808085bU, +/*00c7*/ 0x1008085bU, +/*00c8*/ 0x1808085bU, +/*00c9*/ 0x0008085cU, +/*00ca*/ 0x0808085cU, +/*00cb*/ 0x1008085cU, +/*00cc*/ 0x1801085cU, +/*00cd*/ 0x0008085dU, +/*00ce*/ 0x0808085dU, +/*00cf*/ 0x1002085dU, +/*00d0*/ 0x1802085dU, +/*00d1*/ 0x0005085eU, +/*00d2*/ 0x1005085eU, +/*00d3*/ 0x1805085eU, +/*00d4*/ 0x0004085fU, +/*00d5*/ 0x080b085fU, +/*00d6*/ 0x1806085fU, +/*00d7*/ 0x00080860U, +/*00d8*/ 0x08080860U, +/*00d9*/ 0x10040860U, +/*00da*/ 0x18040860U, +/*00db*/ 0x00060861U, +/*00dc*/ 0x08040861U, +/*00dd*/ 0x10050861U, +/*00de*/ 0x000a0862U, +/*00df*/ 0x100a0862U, +/*00e0*/ 0x00080863U, +/*00e1*/ 0x08010863U, +/*00e2*/ 0x10040863U, +/*00e3*/ 0x00020864U, +/*00e4*/ 0x08030864U, +/*00e5*/ 0x00050a00U, +/*00e6*/ 0x08050a00U, +/*00e7*/ 0x10050a00U, +/*00e8*/ 0x18050a00U, +/*00e9*/ 0x00050a01U, +/*00ea*/ 0x08050a01U, +/*00eb*/ 0x100b0a01U, +/*00ec*/ 0x00010a02U, +/*00ed*/ 0x08030a02U, +/*00ee*/ 0x00200a03U, +/*00ef*/ 0x00100a04U, +/*00f0*/ 0x10040a04U, +/*00f1*/ 0x000b0a05U, +/*00f2*/ 0x10070a05U, +/*00f3*/ 0x00090a06U, +/*00f4*/ 0x10030a06U, +/*00f5*/ 0x18030a06U, +/*00f6*/ 0x00010a07U, +/*00f7*/ 0x08010a07U, +/*00f8*/ 0x10070a07U, +/*00f9*/ 0x18070a07U, +/*00fa*/ 0x00050a08U, +/*00fb*/ 0x08010a08U, +/*00fc*/ 0x10020a08U, +/*00fd*/ 0x18030a08U, +/*00fe*/ 0x00010a09U, +/*00ff*/ 0x080f0a09U, +/*0100*/ 0x00200a0aU, +/*0101*/ 0x00200a0bU, +/*0102*/ 0x000b0a0cU, +/*0103*/ 0x100b0a0cU, +/*0104*/ 0x000b0a0dU, +/*0105*/ 0x00180a0eU, +/*0106*/ 0x00180a0fU, +/*0107*/ 0xffffffffU, +/*0108*/ 0xffffffffU, +/*0109*/ 0xffffffffU, +/*010a*/ 0xffffffffU, +/*010b*/ 0xffffffffU, +/*010c*/ 0x18020a0fU, +/*010d*/ 0x00020a10U, +/*010e*/ 0x08040a10U, +/*010f*/ 0x10040a10U, +/*0110*/ 0x18010a10U, +/*0111*/ 0x00010a11U, +/*0112*/ 0x08010a11U, +/*0113*/ 0x10030a11U, +/*0114*/ 0x00200a12U, +/*0115*/ 0x00200a13U, +/*0116*/ 0xffffffffU, +/*0117*/ 0x00140a14U, +/*0118*/ 0x00140a15U, +/*0119*/ 0x00140a16U, +/*011a*/ 0x00140a17U, +/*011b*/ 0x00140a18U, +/*011c*/ 0x00140a19U, +/*011d*/ 0x00140a1aU, +/*011e*/ 0x00140a1bU, +/*011f*/ 0x001e0a1cU, +/*0120*/ 0x000a0a1dU, +/*0121*/ 0x10060a1dU, +/*0122*/ 0x18060a1dU, +/*0123*/ 0x00060a1eU, +/*0124*/ 0x08060a1eU, +/*0125*/ 0x10060a1eU, +/*0126*/ 0x00080a1fU, +/*0127*/ 0x080b0a1fU, +/*0128*/ 0x000b0a20U, +/*0129*/ 0x100b0a20U, +/*012a*/ 0x000b0a21U, +/*012b*/ 0x100b0a21U, +/*012c*/ 0x000b0a22U, +/*012d*/ 0x10040a22U, +/*012e*/ 0x000b0a23U, +/*012f*/ 0x10060a23U, +/*0130*/ 0x18080a23U, +/*0131*/ 0x00080a24U, +/*0132*/ 0x08040a24U, +/*0133*/ 0x00020b80U, +/*0134*/ 0x00010b81U, +/*0135*/ 0x08010b81U, +/*0136*/ 0x10020b81U, +/*0137*/ 0x18050b81U, +/*0138*/ 0x00050b82U, +/*0139*/ 0x08050b82U, +/*013a*/ 0x10050b82U, +/*013b*/ 0x000b0b83U, +/*013c*/ 0x10050b83U, +/*013d*/ 0x18010b83U, +/*013e*/ 0x00010b84U, +/*013f*/ 0x08010b84U, +/*0140*/ 0x10010b84U, +/*0141*/ 0x18010b84U, +/*0142*/ 0x00040b85U, +/*0143*/ 0x080b0b85U, +/*0144*/ 0x000b0b86U, +/*0145*/ 0x100b0b86U, +/*0146*/ 0x00040b87U, +/*0147*/ 0x080b0b87U, +/*0148*/ 0x18040b87U, +/*0149*/ 0x00010b88U, +/*014a*/ 0x08010b88U, +/*014b*/ 0x10010b88U, +/*014c*/ 0x00200b89U, +/*014d*/ 0x00200b8aU, +/*014e*/ 0x00080b8bU, +/*014f*/ 0x080a0b8bU, +/*0150*/ 0x18050b8bU, +/*0151*/ 0x000b0b8cU, +/*0152*/ 0x10030b8cU, +/*0153*/ 0x18030b8cU, +/*0154*/ 0x00010b8dU, +/*0155*/ 0x08020b8dU, +/*0156*/ 0x10010b8dU, +/*0157*/ 0x18010b8dU, +/*0158*/ 0x00010b8eU, +/*0159*/ 0xffffffffU, +/*015a*/ 0x08010b8eU, +/*015b*/ 0x18040b8eU, +/*015c*/ 0x00040b8fU, +/*015d*/ 0x08040b8fU, +/*015e*/ 0x10040b8fU, +/*015f*/ 0x18010b8fU, +/*0160*/ 0x00010b90U, +/*0161*/ 0x08010b90U, +/*0162*/ 0x00200b91U, +/*0163*/ 0x00200b92U, +/*0164*/ 0x00200b93U, +/*0165*/ 0x00200b94U, +/*0166*/ 0xffffffffU, +/*0167*/ 0x10010b8eU, +/*0168*/ 0x000d0b96U, +/*0169*/ 0x100d0b96U, +/*016a*/ 0x000d0b97U, +/*016b*/ 0x00050b98U, +/*016c*/ 0x00010b99U, +/*016d*/ 0x080e0b99U, +/*016e*/ 0x000e0b9aU, +/*016f*/ 0x100e0b9aU, +/*0170*/ 0x000e0b9bU, +/*0171*/ 0x100e0b9bU, +/*0172*/ 0x00040b9cU, +/*0173*/ 0x08040b9cU, +/*0174*/ 0x10040b9cU, +/*0175*/ 0x18040b9cU, +/*0176*/ 0x00040b9dU, +/*0177*/ 0x080b0b9dU, +/*0178*/ 0x000b0b9eU, +/*0179*/ 0x100b0b9eU, +/*017a*/ 0x000b0b9fU, +/*017b*/ 0x00040ba0U, +/*017c*/ 0x08040ba0U, +/*017d*/ 0x10040ba0U, +/*017e*/ 0x18040ba0U, +/*017f*/ 0x000d0ba1U, +/*0180*/ 0x100d0ba1U, +/*0181*/ 0x000d0ba2U, +/*0182*/ 0x10100ba2U, +/*0183*/ 0x00080b95U, +/*0184*/ 0x08080b95U, +/*0185*/ 0x00100ba3U, +/*0186*/ 0x10100ba3U, +/*0187*/ 0x00100ba4U, +/*0188*/ 0x10100ba4U, +/*0189*/ 0x00100ba5U, +/*018a*/ 0x10030ba5U, +/*018b*/ 0x18040ba5U, +/*018c*/ 0x00010ba6U, +/*018d*/ 0x08080ba6U, +/*018e*/ 0x10010ba6U, +/*018f*/ 0x000a0ba7U, +/*0190*/ 0x10010ba7U, +/*0191*/ 0x00140ba8U, +/*0192*/ 0x000b0ba9U, +/*0193*/ 0x100c0ba9U, +/*0194*/ 0x00120baaU, +/*0195*/ 0x00140babU, +/*0196*/ 0x00120bacU, +/*0197*/ 0x00110badU, +/*0198*/ 0x00110baeU, +/*0199*/ 0x00120bafU, +/*019a*/ 0x00120bb0U, +/*019b*/ 0x00120bb1U, +/*019c*/ 0x00120bb2U, +/*019d*/ 0x00120bb3U, +/*019e*/ 0x00120bb4U, +/*019f*/ 0x00120bb5U, +/*01a0*/ 0x00120bb6U, +/*01a1*/ 0x00120bb7U, +/*01a2*/ 0x00120bb8U, +/*01a3*/ 0x000e0bb9U, +/*01a4*/ 0x100d0bb9U, +/*01a5*/ 0x00200bbaU, +/*01a6*/ 0x00170bbbU, +/*01a7*/ 0x000d0bbcU, +/*01a8*/ 0x10010bbcU, +/*01a9*/ 0x18010bbcU, +/*01aa*/ 0x00200bbdU, +/*01ab*/ 0x00080bbeU, +/*01ac*/ 0x08030bbeU, +/*01ad*/ 0x10030bbeU, +/*01ae*/ 0x00180bbfU, +/*01af*/ 0x00180bc0U, +/*01b0*/ 0x18070bc0U, +/*01b1*/ 0x00070bc1U, +/*01b2*/ 0x08080bc1U, +/*01b3*/ 0x10080bc1U, +/*01b4*/ 0x18080bc1U, +/*01b5*/ 0x00010bc2U, +/*01b6*/ 0x08010bc2U, +/*01b7*/ 0x00200bc3U, +/*01b8*/ 0x00070bc4U, +/*01b9*/ 0x08140bc4U, +/*01ba*/ 0x00140bc5U, +/*01bb*/ 0x00190bc6U, +/*01bc*/ 0x00170bc7U, +/*01bd*/ 0x00110bc8U, +/*01be*/ 0x00110bc9U, +/*01bf*/ 0x00100bcaU, +/*01c0*/ 0x10010bcaU, +/*01c1*/ 0x18010bcaU, +/*01c2*/ 0x00020bcbU, +/*01c3*/ 0x08040bcbU, +/*01c4*/ 0x10090bcbU, +/*01c5*/ 0x00070bccU, +/*01c6*/ 0x08040bccU, +/*01c7*/ 0x00200bcdU, +/*01c8*/ 0x00010bceU, +/*01c9*/ 0x08020bceU, +/*01ca*/ 0x10060bceU, +/*01cb*/ 0x00100bcfU, +/*01cc*/ 0x10010bcfU, +/*01cd*/ 0x00200bd0U, +/*01ce*/ 0x00080bd1U, +/*01cf*/ 0x08010bd1U, +/*01d0*/ 0x10050bd1U, +/*01d1*/ 0x18030bd1U, +/*01d2*/ 0x00020bd2U, +/*01d3*/ 0xffffffffU, +/*01d4*/ 0x00200bd3U, +/*01d5*/ 0x000b0bd4U, +/*01d6*/ 0xffffffffU, +/*01d7*/ 0x10030bd4U, +/*01d8*/ 0x18080bd4U, +/*01d9*/ 0x00020bd5U, +/*01da*/ 0x080c0bd5U, +/*01db*/ 0x18040bd5U, +/*01dc*/ 0x00010bd6U, +/*01dd*/ 0x08050bd6U, +/*01de*/ 0x00010200U, +/*01df*/ 0x08040200U, +/*01e0*/ 0x10100200U, +/*01e1*/ 0x00010201U, +/*01e2*/ 0x08010201U, +/*01e3*/ 0x10010201U, +/*01e4*/ 0x18010201U, +/*01e5*/ 0x00100202U, +/*01e6*/ 0x10080202U, +/*01e7*/ 0x18010202U, +/*01e8*/ 0x00200203U, +/*01e9*/ 0x00200204U, +/*01ea*/ 0x00200205U, +/*01eb*/ 0x00200206U, +/*01ec*/ 0x00020207U, +/*01ed*/ 0x08010207U, +/*01ee*/ 0x10010207U, +/*01ef*/ 0x00200208U, +/*01f0*/ 0x00140209U, +/*01f1*/ 0x0020020aU, +/*01f2*/ 0x0014020bU, +/*01f3*/ 0x0020020cU, +/*01f4*/ 0x0014020dU, +/*01f5*/ 0x0014020eU, +/*01f6*/ 0x0020020fU, +/*01f7*/ 0x00200210U, +/*01f8*/ 0x00200211U, +/*01f9*/ 0x00200212U, +/*01fa*/ 0x00140213U, +/*01fb*/ 0x00200214U, +/*01fc*/ 0x00200215U, +/*01fd*/ 0x00200216U, +/*01fe*/ 0x00200217U, +/*01ff*/ 0x00140218U, +/*0200*/ 0x00200219U, +/*0201*/ 0x0020021aU, +/*0202*/ 0x0020021bU, +/*0203*/ 0x0020021cU, +/*0204*/ 0x0009021dU, +/*0205*/ 0x1001021dU, +/*0206*/ 0x0020021eU, +/*0207*/ 0x0005021fU, +/*0208*/ 0x0801021fU, +/*0209*/ 0x1008021fU, +/*020a*/ 0x1808021fU, +/*020b*/ 0x001e0220U, +/*020c*/ 0x001e0221U, +/*020d*/ 0x001e0222U, +/*020e*/ 0x001e0223U, +/*020f*/ 0x001e0224U, +/*0210*/ 0x001e0225U, +/*0211*/ 0x001e0226U, +/*0212*/ 0x001e0227U, +/*0213*/ 0x001e0228U, +/*0214*/ 0x001e0229U, +/*0215*/ 0x001e022aU, +/*0216*/ 0x001e022bU, +/*0217*/ 0x001e022cU, +/*0218*/ 0x001e022dU, +/*0219*/ 0x001e022eU, +/*021a*/ 0x001e022fU, +/*021b*/ 0x00010230U, +/*021c*/ 0x08010230U, +/*021d*/ 0x10010230U, +/*021e*/ 0x18040230U, +/*021f*/ 0x00080231U, +/*0220*/ 0x08080231U, +/*0221*/ 0x10080231U, +/*0222*/ 0x18040231U, +/*0223*/ 0x00070232U, +/*0224*/ 0x08060232U, +/*0225*/ 0x10070232U, +/*0226*/ 0x18070232U, +/*0227*/ 0x00060233U, +/*0228*/ 0x08070233U, +/*0229*/ 0x10070233U, +/*022a*/ 0x18060233U, +/*022b*/ 0x00070234U, +/*022c*/ 0x08020234U, +/*022d*/ 0x10010234U, +/*022e*/ 0x18010234U, +/*022f*/ 0x000a0235U, +/*0230*/ 0x00140236U, +/*0231*/ 0x000a0237U, +/*0232*/ 0x00140238U, +/*0233*/ 0x000a0239U, +/*0234*/ 0x0014023aU, +/*0235*/ 0xffffffffU, +/*0236*/ 0xffffffffU, +/*0237*/ 0x0005023bU, +/*0238*/ 0x0001023cU, +/*0239*/ 0x1001023cU, +/*023a*/ 0x1801023cU, +/*023b*/ 0x0001023dU, +/*023c*/ 0x0801023dU, +/*023d*/ 0x1001023dU, +/*023e*/ 0x1801023dU, +/*023f*/ 0x0002023eU, +/*0240*/ 0x0802023eU, +/*0241*/ 0x1002023eU, +/*0242*/ 0x1802023eU, +/*0243*/ 0x0002023fU, +/*0244*/ 0x0803023fU, +/*0245*/ 0x1001023fU, +/*0246*/ 0x1801023fU, +/*0247*/ 0x00010240U, +/*0248*/ 0x08010240U, +/*0249*/ 0x10010240U, +/*024a*/ 0x18020240U, +/*024b*/ 0x00010241U, +/*024c*/ 0x08010241U, +/*024d*/ 0x10010241U, +/*024e*/ 0x18020241U, +/*024f*/ 0x00010242U, +/*0250*/ 0x08010242U, +/*0251*/ 0x10010242U, +/*0252*/ 0x18020242U, +/*0253*/ 0x00010243U, +/*0254*/ 0x08010243U, +/*0255*/ 0x10010243U, +/*0256*/ 0x18020243U, +/*0257*/ 0xffffffffU, +/*0258*/ 0x00010244U, +/*0259*/ 0x08010244U, +/*025a*/ 0x10010244U, +/*025b*/ 0x18010244U, +/*025c*/ 0x00010245U, +/*025d*/ 0x08010245U, +/*025e*/ 0x10010245U, +/*025f*/ 0x18010245U, +/*0260*/ 0x00040246U, +/*0261*/ 0x08040246U, +/*0262*/ 0x10040246U, +/*0263*/ 0x18010246U, +/*0264*/ 0x00020247U, +/*0265*/ 0x08060247U, +/*0266*/ 0x10060247U, +/*0267*/ 0x18020247U, +/*0268*/ 0x00020248U, +/*0269*/ 0x08020248U, +/*026a*/ 0xffffffffU, +/*026b*/ 0x10100248U, +/*026c*/ 0x00010249U, +/*026d*/ 0x08010249U, +/*026e*/ 0x10010249U, +/*026f*/ 0x18040249U, +/*0270*/ 0x0001024aU, +/*0271*/ 0x0804024aU, +/*0272*/ 0x1003024aU, +/*0273*/ 0x1808024aU, +/*0274*/ 0x000a024bU, +/*0275*/ 0x100a024bU, +/*0276*/ 0x000a024cU, +/*0277*/ 0xffffffffU, +/*0278*/ 0x0020024dU, +/*0279*/ 0x0020024eU, +/*027a*/ 0x0005024fU, +/*027b*/ 0x1801023aU, +/*027c*/ 0x0805023cU, +/*027d*/ 0x0808024fU, +/*027e*/ 0x1001024fU, +/*027f*/ 0x1808024fU, +/*0280*/ 0x00010250U, +/*0281*/ 0x08080250U, +/*0282*/ 0x10010250U, +/*0283*/ 0x18040250U, +/*0284*/ 0x00040251U, +/*0285*/ 0x08040251U, +/*0286*/ 0x10040251U, +/*0287*/ 0x18040251U, +/*0288*/ 0x00040252U, +/*0289*/ 0x08040252U, +/*028a*/ 0x10040252U, +/*028b*/ 0x18040252U, +/*028c*/ 0x00040253U, +/*028d*/ 0x08010253U, +/*028e*/ 0x10040253U, +/*028f*/ 0x18040253U, +/*0290*/ 0x00040254U, +/*0291*/ 0x08040254U, +/*0292*/ 0x10040254U, +/*0293*/ 0x18040254U, +/*0294*/ 0x00060255U, +/*0295*/ 0x08060255U, +/*0296*/ 0x10060255U, +/*0297*/ 0x18060255U, +/*0298*/ 0x00060256U, +/*0299*/ 0x08060256U, +/*029a*/ 0x10040256U, +/*029b*/ 0x18010256U, +/*029c*/ 0x00010257U, +/*029d*/ 0x08020257U, +/*029e*/ 0x00200258U, +/*029f*/ 0x00200259U, +/*02a0*/ 0x0020025aU, +/*02a1*/ 0x0020025bU, +/*02a2*/ 0x0020025cU, +/*02a3*/ 0x0020025dU, +/*02a4*/ 0x0020025eU, +/*02a5*/ 0x0020025fU, +/*02a6*/ 0x00040260U, +/*02a7*/ 0x08040260U, +/*02a8*/ 0x10010260U, +/*02a9*/ 0x18010260U, +/*02aa*/ 0x00010261U, +/*02ab*/ 0x08010261U, +/*02ac*/ 0x10010261U, +/*02ad*/ 0x18010261U, +/*02ae*/ 0x00010262U, +/*02af*/ 0x08010262U, +/*02b0*/ 0x10010262U, +/*02b1*/ 0x18040262U, +/*02b2*/ 0x00040263U, +/*02b3*/ 0x080a0263U, +/*02b4*/ 0x00200264U, +/*02b5*/ 0x00040265U, +/*02b6*/ 0x08080265U, +/*02b7*/ 0x10020265U, +/*02b8*/ 0x18020265U, +/*02b9*/ 0x00020266U, +/*02ba*/ 0x08020266U, +/*02bb*/ 0x10020266U, +/*02bc*/ 0x18020266U, +/*02bd*/ 0xffffffffU, +/*02be*/ 0xffffffffU, +/*02bf*/ 0x00200267U, +/*02c0*/ 0x00030268U, +/*02c1*/ 0x08100268U, +/*02c2*/ 0x00100269U, +/*02c3*/ 0x10040269U, +/*02c4*/ 0x18040269U, +/*02c5*/ 0x0005026aU, +/*02c6*/ 0x0805026aU, +/*02c7*/ 0xffffffffU, +/*02c8*/ 0xffffffffU, +/*02c9*/ 0xffffffffU, +/*02ca*/ 0xffffffffU, +/*02cb*/ 0x1001026aU, +/*02cc*/ 0x1801026aU, +/*02cd*/ 0x0008026bU, +/*02ce*/ 0x0808026bU, +/*02cf*/ 0x1008026bU, +/*02d0*/ 0x1808026bU, +/*02d1*/ 0x0008026cU, +/*02d2*/ 0x0808026cU, +/*02d3*/ 0x1008026cU, +/*02d4*/ 0x1808026cU, +/*02d5*/ 0x0008026dU, +/*02d6*/ 0x0808026dU, +/*02d7*/ 0x1008026dU, +/*02d8*/ 0x1808026dU, +/*02d9*/ 0x0008026eU, +/*02da*/ 0x0808026eU, +/*02db*/ 0x1003026eU, +/*02dc*/ 0x1803026eU, +/*02dd*/ 0x0003026fU, +/*02de*/ 0xffffffffU, +/*02df*/ 0x0801026fU, +/*02e0*/ 0x1002026fU, +/*02e1*/ 0x1801026fU, +/*02e2*/ 0x00040270U, +/*02e3*/ 0x08020270U, +/*02e4*/ 0x10010270U, +/*02e5*/ 0x18010270U, +/*02e6*/ 0x00010271U, +/*02e7*/ 0x08010271U, +/*02e8*/ 0x10040271U, +/*02e9*/ 0x18080271U, +/*02ea*/ 0x000a0272U, +/*02eb*/ 0x100a0272U, +/*02ec*/ 0x000a0273U, +/*02ed*/ 0x100a0273U, +/*02ee*/ 0x000a0274U, +/*02ef*/ 0x100a0274U, +/*02f0*/ 0x00200275U, +/*02f1*/ 0x00200276U, +/*02f2*/ 0x00010277U, +/*02f3*/ 0x08020277U, +/*02f4*/ 0x10020277U, +/*02f5*/ 0x18020277U, +/*02f6*/ 0xffffffffU, +/*02f7*/ 0x00020278U, +/*02f8*/ 0x08100278U, +/*02f9*/ 0x18050278U, +/*02fa*/ 0x00060279U, +/*02fb*/ 0x08050279U, +/*02fc*/ 0x10050279U, +/*02fd*/ 0x000e027aU, +/*02fe*/ 0x1005027aU, +/*02ff*/ 0x000e027bU, +/*0300*/ 0x1005027bU, +/*0301*/ 0x000e027cU, +/*0302*/ 0x1005027cU, +/*0303*/ 0x1801027cU, +/*0304*/ 0x0005027dU, +/*0305*/ 0x0805027dU, +/*0306*/ 0x100a027dU, +/*0307*/ 0x000a027eU, +/*0308*/ 0x1005027eU, +/*0309*/ 0x1805027eU, +/*030a*/ 0x000a027fU, +/*030b*/ 0x100a027fU, +/*030c*/ 0x00050280U, +/*030d*/ 0x08050280U, +/*030e*/ 0x100a0280U, +/*030f*/ 0x000a0281U, +/*0310*/ 0x10070281U, +/*0311*/ 0x18070281U, +/*0312*/ 0x00070282U, +/*0313*/ 0x08070282U, +/*0314*/ 0x10070282U, +/*0315*/ 0x18070282U, +/*0316*/ 0xffffffffU, +/*0317*/ 0xffffffffU, +/*0318*/ 0x00040283U, +/*0319*/ 0x08040283U, +/*031a*/ 0x10040283U, +/*031b*/ 0x18040283U, +/*031c*/ 0x00040284U, +/*031d*/ 0xffffffffU, +/*031e*/ 0x08080284U, +/*031f*/ 0x10080284U, +/*0320*/ 0x18040284U, +/*0321*/ 0x00050285U, +/*0322*/ 0x08080285U, +/*0323*/ 0x10050285U, +/*0324*/ 0x18040285U, +/*0325*/ 0x00050286U, +/*0326*/ 0x08080286U, +/*0327*/ 0x10050286U, +/*0328*/ 0x18040286U, +/*0329*/ 0x00050287U, +/*032a*/ 0x08080287U, +/*032b*/ 0x10050287U, +/*032c*/ 0x18040287U, +/*032d*/ 0x00050288U, +/*032e*/ 0x08070288U, +/*032f*/ 0x10080288U, +/*0330*/ 0x00100289U, +/*0331*/ 0x10080289U, +/*0332*/ 0x0010028aU, +/*0333*/ 0x1008028aU, +/*0334*/ 0x0010028bU, +/*0335*/ 0x1008028bU, +/*0336*/ 0x1808028bU, +/*0337*/ 0x0001028cU, +/*0338*/ 0x0801028cU, +/*0339*/ 0x1006028cU, +/*033a*/ 0x1806028cU, +/*033b*/ 0x0006028dU, +/*033c*/ 0x0801028dU, +/*033d*/ 0x1001028dU, +/*033e*/ 0x1803028dU, +/*033f*/ 0x000a028eU, +/*0340*/ 0x100a028eU, +/*0341*/ 0x000a028fU, +/*0342*/ 0xffffffffU, +/*0343*/ 0x100a028fU, +/*0344*/ 0x00040290U, +/*0345*/ 0x08010290U, +/*0346*/ 0x10040290U, +/*0347*/ 0x18070290U, +/*0348*/ 0x00070291U, +/*0349*/ 0x08070291U, +/*034a*/ 0x10070291U, +/*034b*/ 0x18070291U, +/*034c*/ 0x00070292U, +/*034d*/ 0xffffffffU, +/*034e*/ 0xffffffffU, +/*034f*/ 0x08050292U, +/*0350*/ 0x10050292U, +/*0351*/ 0x18040292U, +/*0352*/ 0x00040293U, +/*0353*/ 0x08040293U, +/*0354*/ 0xffffffffU, +/*0355*/ 0x10010293U, +/*0356*/ 0x18010293U, +/*0357*/ 0x00020294U, +/*0358*/ 0x08080294U, +/*0359*/ 0x00200295U, +/*035a*/ 0x00200296U, +/*035b*/ 0x00100297U, +/*035c*/ 0x10020297U, +/*035d*/ 0x18020297U, +/*035e*/ 0x00020298U, +/*035f*/ 0xffffffffU, +/*0360*/ 0x08010298U, +/*0361*/ 0x10010298U, +/*0362*/ 0x18020298U, +/*0363*/ 0x00100299U, +/*0364*/ 0x10100299U, +/*0365*/ 0x0010029aU, +/*0366*/ 0x1008029aU, +/*0367*/ 0x1808029aU, +/*0368*/ 0x0008029bU, +/*0369*/ 0x0808029bU, +/*036a*/ 0x1010029bU, +/*036b*/ 0x0010029cU, +/*036c*/ 0x1010029cU, +/*036d*/ 0x0008029dU, +/*036e*/ 0x0808029dU, +/*036f*/ 0x1008029dU, +/*0370*/ 0x1808029dU, +/*0371*/ 0x0010029eU, +/*0372*/ 0x1010029eU, +/*0373*/ 0x0010029fU, +/*0374*/ 0x1008029fU, +/*0375*/ 0x1808029fU, +/*0376*/ 0x000802a0U, +/*0377*/ 0x080802a0U, +/*0378*/ 0x100802a0U, +/*0379*/ 0x001002a1U, +/*037a*/ 0x101002a1U, +/*037b*/ 0x001002a2U, +/*037c*/ 0x100802a2U, +/*037d*/ 0x180802a2U, +/*037e*/ 0x000802a3U, +/*037f*/ 0x080802a3U, +/*0380*/ 0x101002a3U, +/*0381*/ 0x001002a4U, +/*0382*/ 0x101002a4U, +/*0383*/ 0x000802a5U, +/*0384*/ 0x080802a5U, +/*0385*/ 0x100802a5U, +/*0386*/ 0x180802a5U, +/*0387*/ 0x001002a6U, +/*0388*/ 0x101002a6U, +/*0389*/ 0x001002a7U, +/*038a*/ 0x100802a7U, +/*038b*/ 0x180802a7U, +/*038c*/ 0x000802a8U, +/*038d*/ 0x080802a8U, +/*038e*/ 0x100802a8U, +/*038f*/ 0x001002a9U, +/*0390*/ 0x101002a9U, +/*0391*/ 0x001002aaU, +/*0392*/ 0x100802aaU, +/*0393*/ 0x180802aaU, +/*0394*/ 0x000802abU, +/*0395*/ 0x080802abU, +/*0396*/ 0x101002abU, +/*0397*/ 0x001002acU, +/*0398*/ 0x101002acU, +/*0399*/ 0x000802adU, +/*039a*/ 0x080802adU, +/*039b*/ 0x100802adU, +/*039c*/ 0x180802adU, +/*039d*/ 0x001002aeU, +/*039e*/ 0x101002aeU, +/*039f*/ 0x001002afU, +/*03a0*/ 0x100802afU, +/*03a1*/ 0x180802afU, +/*03a2*/ 0x000802b0U, +/*03a3*/ 0x080802b0U, +/*03a4*/ 0x100802b0U, +/*03a5*/ 0x001002b1U, +/*03a6*/ 0x101002b1U, +/*03a7*/ 0x001002b2U, +/*03a8*/ 0x100802b2U, +/*03a9*/ 0x180802b2U, +/*03aa*/ 0x000802b3U, +/*03ab*/ 0x080802b3U, +/*03ac*/ 0x101002b3U, +/*03ad*/ 0x001002b4U, +/*03ae*/ 0x101002b4U, +/*03af*/ 0x000802b5U, +/*03b0*/ 0x080802b5U, +/*03b1*/ 0x100802b5U, +/*03b2*/ 0x180802b5U, +/*03b3*/ 0x001002b6U, +/*03b4*/ 0x101002b6U, +/*03b5*/ 0x001002b7U, +/*03b6*/ 0x100802b7U, +/*03b7*/ 0x180802b7U, +/*03b8*/ 0x000802b8U, +/*03b9*/ 0x080802b8U, +/*03ba*/ 0x100802b8U, +/*03bb*/ 0x180202b8U, +/*03bc*/ 0x000302b9U, +/*03bd*/ 0x080a02b9U, +/*03be*/ 0x000a02baU, +/*03bf*/ 0x100a02baU, +/*03c0*/ 0x000502bbU, +/*03c1*/ 0x080802bbU, +/*03c2*/ 0x100802bbU, +/*03c3*/ 0x180802bbU, +/*03c4*/ 0x000602bcU, +/*03c5*/ 0x080602bcU, +/*03c6*/ 0x001102bdU, +/*03c7*/ 0x180802bdU, +/*03c8*/ 0x000402beU, +/*03c9*/ 0x080602beU, +/*03ca*/ 0x100802beU, +/*03cb*/ 0x180802beU, +/*03cc*/ 0x000802bfU, +/*03cd*/ 0x080802bfU, +/*03ce*/ 0x100802bfU, +/*03cf*/ 0x180802bfU, +/*03d0*/ 0x000802c0U, +/*03d1*/ 0x080602c0U, +/*03d2*/ 0x100602c0U, +/*03d3*/ 0x001102c1U, +/*03d4*/ 0x180802c1U, +/*03d5*/ 0x000402c2U, +/*03d6*/ 0x080602c2U, +/*03d7*/ 0x100802c2U, +/*03d8*/ 0x180802c2U, +/*03d9*/ 0x000802c3U, +/*03da*/ 0x080802c3U, +/*03db*/ 0x100802c3U, +/*03dc*/ 0x180802c3U, +/*03dd*/ 0x000802c4U, +/*03de*/ 0x080602c4U, +/*03df*/ 0x100602c4U, +/*03e0*/ 0x001102c5U, +/*03e1*/ 0x180802c5U, +/*03e2*/ 0x000402c6U, +/*03e3*/ 0x080602c6U, +/*03e4*/ 0x100802c6U, +/*03e5*/ 0x180802c6U, +/*03e6*/ 0x000802c7U, +/*03e7*/ 0x080802c7U, +/*03e8*/ 0x100402c7U, +/*03e9*/ 0x180402c7U, +/*03ea*/ 0x000402c8U, +/*03eb*/ 0x080402c8U, +/*03ec*/ 0x100402c8U, +/*03ed*/ 0x180402c8U, +/*03ee*/ 0x000402c9U, +/*03ef*/ 0x080402c9U, +/*03f0*/ 0x100402c9U, +/*03f1*/ 0x180402c9U, +/*03f2*/ 0x000402caU, +/*03f3*/ 0x080402caU, +/*03f4*/ 0x100402caU, +/*03f5*/ 0x180402caU, +/*03f6*/ 0x000402cbU, +/*03f7*/ 0x080402cbU, +/*03f8*/ 0x100402cbU, +/*03f9*/ 0x180402cbU, +/*03fa*/ 0x000402ccU, +/*03fb*/ 0x080402ccU, +/*03fc*/ 0x001702cdU, +/*03fd*/ 0x001602ceU, +/*03fe*/ 0x001702cfU, +/*03ff*/ 0x002002d0U, +/*0400*/ 0x002002d1U, +/*0401*/ 0x002002d2U, +/*0402*/ 0x002002d3U, +/*0403*/ 0x002002d4U, +/*0404*/ 0x002002d5U, +/*0405*/ 0x002002d6U, +/*0406*/ 0x002002d7U, +/*0407*/ 0x002002d8U, +/*0408*/ 0x000202d9U, +/*0409*/ 0x080502d9U, +/*040a*/ 0x100502d9U, +/*040b*/ 0x180102d9U, +/*040c*/ 0x000502daU, +/*040d*/ 0x080502daU, +/*040e*/ 0x100502daU, +/*040f*/ 0x180502daU, +/*0410*/ 0x000502dbU, +/*0411*/ 0x080502dbU, +/*0412*/ 0x100502dbU, +/*0413*/ 0x180502dbU, +/*0414*/ 0x000502dcU, +/*0415*/ 0x080502dcU, +/*0416*/ 0x100502dcU, +/*0417*/ 0x180502dcU, +/*0418*/ 0x000502ddU, +/*0419*/ 0x080502ddU, +/*041a*/ 0x100502ddU, +/*041b*/ 0x180502ddU, +/*041c*/ 0x000502deU, +/*041d*/ 0x080502deU, +/*041e*/ 0x100502deU, +/*041f*/ 0x180502deU, +/*0420*/ 0x000502dfU, +/*0421*/ 0x080502dfU, +/*0422*/ 0x100102dfU, +/*0423*/ 0x180202dfU, +/*0424*/ 0x000202e0U, +/*0425*/ 0x080202e0U, +/*0426*/ 0x100202e0U, +/*0427*/ 0x180102e0U, +/*0428*/ 0x000802e1U, +/*0429*/ 0x081502e1U, +/*042a*/ 0x002002e2U, +/*042b*/ 0x001502e3U, +/*042c*/ 0x002002e4U, +/*042d*/ 0x001502e5U, +/*042e*/ 0x002002e6U, +/*042f*/ 0x000702e7U, +/*0430*/ 0x080102e7U, +/*0431*/ 0x100202e7U, +/*0432*/ 0x180602e7U, +/*0433*/ 0x000102e8U, +/*0434*/ 0x080102e8U, +/*0435*/ 0x002002e9U, +/*0436*/ 0x000202eaU, +/*0437*/ 0x002002ebU, +/*0438*/ 0x002002ecU, +/*0439*/ 0x000c02edU, +/*043a*/ 0x100c02edU, +/*043b*/ 0x002002eeU, +/*043c*/ 0x000302efU, +/*043d*/ 0x002002f0U, +/*043e*/ 0x000302f1U, +/*043f*/ 0x002002f2U, +/*0440*/ 0x000302f3U, +/*0441*/ 0x002002f4U, +/*0442*/ 0x000302f5U, +/*0443*/ 0x002002f6U, +/*0444*/ 0x000302f7U, +/*0445*/ 0x002002f8U, +/*0446*/ 0x000302f9U, +/*0447*/ 0x002002faU, +/*0448*/ 0x000302fbU, +/*0449*/ 0x002002fcU, +/*044a*/ 0x000302fdU, +/*044b*/ 0x002002feU, +/*044c*/ 0x000302ffU, +/*044d*/ 0x00200300U, +/*044e*/ 0x00030301U, +/*044f*/ 0x08030301U, +/*0450*/ 0x10020301U, +/*0451*/ 0x18020301U, +/*0452*/ 0x00200302U, +/*0453*/ 0x00200303U, +/*0454*/ 0x00200304U, +/*0455*/ 0x00200305U, +/*0456*/ 0x00040306U, +/*0457*/ 0x001e0307U, +/*0458*/ 0x001e0308U, +/*0459*/ 0x001e0309U, +/*045a*/ 0x001e030aU, +/*045b*/ 0x001e030bU, +/*045c*/ 0x001e030cU, +/*045d*/ 0x001e030dU, +/*045e*/ 0x001e030eU, +/*045f*/ 0x0004030fU, +/*0460*/ 0x0801030fU, +/*0461*/ 0x1010030fU, +/*0462*/ 0x00100310U, +/*0463*/ 0x10100310U, +/*0464*/ 0x00040311U, +/*0465*/ 0x08010311U, +/*0466*/ 0x10080311U, +/*0467*/ 0x18040311U, +/*0468*/ 0x00010312U, +/*0469*/ 0x08080312U, +/*046a*/ 0x10040312U, +/*046b*/ 0x18010312U, +/*046c*/ 0x00080313U, +/*046d*/ 0x08040313U, +/*046e*/ 0x10010313U, +/*046f*/ 0x18080313U, +/*0470*/ 0x00040314U, +/*0471*/ 0x08010314U, +/*0472*/ 0x10080314U, +/*0473*/ 0x18040314U, +/*0474*/ 0x00010315U, +/*0475*/ 0x08080315U, +/*0476*/ 0x10040315U, +/*0477*/ 0x18010315U, +/*0478*/ 0x00080316U, +/*0479*/ 0x08040316U, +/*047a*/ 0x10010316U, +/*047b*/ 0x18080316U, +/*047c*/ 0x00080317U, +/*047d*/ 0x00010318U, +/*047e*/ 0x08050318U, +/*047f*/ 0x10010318U, +/*0480*/ 0x18020318U, +/*0481*/ 0x00010319U, +/*0482*/ 0x08010319U, +/*0483*/ 0x10010319U, +/*0484*/ 0x18010319U, +/*0485*/ 0x0001031aU, +/*0486*/ 0x0801031aU, +/*0487*/ 0x1001031aU, +/*0488*/ 0x1801031aU, +/*0489*/ 0x0001031bU, +/*048a*/ 0x0801031bU, +/*048b*/ 0x1001031bU, +/*048c*/ 0x1801031bU, +/*048d*/ 0x0001031cU, +/*048e*/ 0x0801031cU, +/*048f*/ 0x1001031cU, +/*0490*/ 0x1801031cU, +/*0491*/ 0x0008031dU, +/*0492*/ 0x0808031dU, +/*0493*/ 0x1008031dU, +/*0494*/ 0x1808031dU, + } +}; + +#endif /* RZG_DDR_REGDEF_H */ diff --git a/drivers/renesas/rzg/ddr/ddr_b/init_dram_tbl_g2m.h b/drivers/renesas/rzg/ddr/ddr_b/init_dram_tbl_g2m.h new file mode 100644 index 000000000..e10162a66 --- /dev/null +++ b/drivers/renesas/rzg/ddr/ddr_b/init_dram_tbl_g2m.h @@ -0,0 +1,472 @@ +/* + * Copyright (c) 2020U, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef RZG_INIT_DRAM_TABLE_G2M_H +#define RZG_INIT_DRAM_TABLE_G2M_H + +#define DDR_PHY_SLICE_REGSET_OFS_G2M 0x0800U +#define DDR_PHY_ADR_V_REGSET_OFS_G2M 0x0a00U +#define DDR_PHY_ADR_I_REGSET_OFS_G2M 0x0a80U +#define DDR_PHY_ADR_G_REGSET_OFS_G2M 0x0b80U +#define DDR_PI_REGSET_OFS_G2M 0x0200U + +#define DDR_PHY_SLICE_REGSET_SIZE_G2M 0x80U +#define DDR_PHY_ADR_V_REGSET_SIZE_G2M 0x80U +#define DDR_PHY_ADR_I_REGSET_SIZE_G2M 0x80U +#define DDR_PHY_ADR_G_REGSET_SIZE_G2M 0x80U +#define DDR_PI_REGSET_SIZE_G2M 0x100U + +#define DDR_PHY_SLICE_REGSET_NUM_G2M 89 +#define DDR_PHY_ADR_V_REGSET_NUM_G2M 37 +#define DDR_PHY_ADR_I_REGSET_NUM_G2M 37 +#define DDR_PHY_ADR_G_REGSET_NUM_G2M 64 +#define DDR_PI_REGSET_NUM_G2M 202 + +static const uint32_t DDR_PHY_SLICE_REGSET_G2M[DDR_PHY_SLICE_REGSET_NUM_G2M] = { + /*0800*/ 0x76543210U, + /*0801*/ 0x0004f008U, + /*0802*/ 0x00000000U, + /*0803*/ 0x00000000U, + /*0804*/ 0x00010000U, + /*0805*/ 0x036e6e0eU, + /*0806*/ 0x026e6e0eU, + /*0807*/ 0x00010300U, + /*0808*/ 0x04000100U, + /*0809*/ 0x00000300U, + /*080a*/ 0x001700c0U, + /*080b*/ 0x00b00201U, + /*080c*/ 0x00030020U, + /*080d*/ 0x00000000U, + /*080e*/ 0x00000000U, + /*080f*/ 0x00000000U, + /*0810*/ 0x00000000U, + /*0811*/ 0x00000000U, + /*0812*/ 0x00000000U, + /*0813*/ 0x00000000U, + /*0814*/ 0x09000000U, + /*0815*/ 0x04080000U, + /*0816*/ 0x04080400U, + /*0817*/ 0x00000000U, + /*0818*/ 0x32103210U, + /*0819*/ 0x00800708U, + /*081a*/ 0x000f000cU, + /*081b*/ 0x00000100U, + /*081c*/ 0x55aa55aaU, + /*081d*/ 0x33cc33ccU, + /*081e*/ 0x0ff00ff0U, + /*081f*/ 0x0f0ff0f0U, + /*0820*/ 0x00018e38U, + /*0821*/ 0x00000000U, + /*0822*/ 0x00000000U, + /*0823*/ 0x00000000U, + /*0824*/ 0x00000000U, + /*0825*/ 0x00000000U, + /*0826*/ 0x00000000U, + /*0827*/ 0x00000000U, + /*0828*/ 0x00000000U, + /*0829*/ 0x00000000U, + /*082a*/ 0x00000000U, + /*082b*/ 0x00000000U, + /*082c*/ 0x00000000U, + /*082d*/ 0x00000000U, + /*082e*/ 0x00000000U, + /*082f*/ 0x00000000U, + /*0830*/ 0x00000000U, + /*0831*/ 0x00000000U, + /*0832*/ 0x00000000U, + /*0833*/ 0x00200000U, + /*0834*/ 0x08200820U, + /*0835*/ 0x08200820U, + /*0836*/ 0x08200820U, + /*0837*/ 0x08200820U, + /*0838*/ 0x08200820U, + /*0839*/ 0x00000820U, + /*083a*/ 0x03000300U, + /*083b*/ 0x03000300U, + /*083c*/ 0x03000300U, + /*083d*/ 0x03000300U, + /*083e*/ 0x00000300U, + /*083f*/ 0x00000000U, + /*0840*/ 0x00000000U, + /*0841*/ 0x00000000U, + /*0842*/ 0x00000000U, + /*0843*/ 0x00a00000U, + /*0844*/ 0x00a000a0U, + /*0845*/ 0x00a000a0U, + /*0846*/ 0x00a000a0U, + /*0847*/ 0x00a000a0U, + /*0848*/ 0x00a000a0U, + /*0849*/ 0x00a000a0U, + /*084a*/ 0x00a000a0U, + /*084b*/ 0x00a000a0U, + /*084c*/ 0x010900a0U, + /*084d*/ 0x02000104U, + /*084e*/ 0x00000000U, + /*084f*/ 0x00010000U, + /*0850*/ 0x00000200U, + /*0851*/ 0x4041a151U, + /*0852*/ 0xc00141a0U, + /*0853*/ 0x0e0100c0U, + /*0854*/ 0x0010000cU, + /*0855*/ 0x0c064208U, + /*0856*/ 0x000f0c18U, + /*0857*/ 0x00e00140U, + /*0858*/ 0x00000c20U +}; + +static const uint32_t DDR_PHY_ADR_V_REGSET_G2M[DDR_PHY_ADR_V_REGSET_NUM_G2M] = { + /*0a00*/ 0x00000000U, + /*0a01*/ 0x00000000U, + /*0a02*/ 0x00000000U, + /*0a03*/ 0x00000000U, + /*0a04*/ 0x00000000U, + /*0a05*/ 0x00000000U, + /*0a06*/ 0x00000002U, + /*0a07*/ 0x00000000U, + /*0a08*/ 0x00000000U, + /*0a09*/ 0x00000000U, + /*0a0a*/ 0x00400320U, + /*0a0b*/ 0x00000040U, + /*0a0c*/ 0x00dcba98U, + /*0a0d*/ 0x00000000U, + /*0a0e*/ 0x00dcba98U, + /*0a0f*/ 0x01000000U, + /*0a10*/ 0x00020003U, + /*0a11*/ 0x00000000U, + /*0a12*/ 0x00000000U, + /*0a13*/ 0x00000000U, + /*0a14*/ 0x0000002aU, + /*0a15*/ 0x00000015U, + /*0a16*/ 0x00000015U, + /*0a17*/ 0x0000002aU, + /*0a18*/ 0x00000033U, + /*0a19*/ 0x0000000cU, + /*0a1a*/ 0x0000000cU, + /*0a1b*/ 0x00000033U, + /*0a1c*/ 0x0a418820U, + /*0a1d*/ 0x003f0000U, + /*0a1e*/ 0x0000003fU, + /*0a1f*/ 0x0002c06eU, + /*0a20*/ 0x02c002c0U, + /*0a21*/ 0x02c002c0U, + /*0a22*/ 0x000002c0U, + /*0a23*/ 0x42080010U, + /*0a24*/ 0x00000003U +}; + +static const uint32_t DDR_PHY_ADR_I_REGSET_G2M[DDR_PHY_ADR_I_REGSET_NUM_G2M] = { + /*0a80*/ 0x04040404U, + /*0a81*/ 0x00000404U, + /*0a82*/ 0x00000000U, + /*0a83*/ 0x00000000U, + /*0a84*/ 0x00000000U, + /*0a85*/ 0x00000000U, + /*0a86*/ 0x00000002U, + /*0a87*/ 0x00000000U, + /*0a88*/ 0x00000000U, + /*0a89*/ 0x00000000U, + /*0a8a*/ 0x00400320U, + /*0a8b*/ 0x00000040U, + /*0a8c*/ 0x00000000U, + /*0a8d*/ 0x00000000U, + /*0a8e*/ 0x00000000U, + /*0a8f*/ 0x01000000U, + /*0a90*/ 0x00020003U, + /*0a91*/ 0x00000000U, + /*0a92*/ 0x00000000U, + /*0a93*/ 0x00000000U, + /*0a94*/ 0x0000002aU, + /*0a95*/ 0x00000015U, + /*0a96*/ 0x00000015U, + /*0a97*/ 0x0000002aU, + /*0a98*/ 0x00000033U, + /*0a99*/ 0x0000000cU, + /*0a9a*/ 0x0000000cU, + /*0a9b*/ 0x00000033U, + /*0a9c*/ 0x00000000U, + /*0a9d*/ 0x00000000U, + /*0a9e*/ 0x00000000U, + /*0a9f*/ 0x0002c06eU, + /*0aa0*/ 0x02c002c0U, + /*0aa1*/ 0x02c002c0U, + /*0aa2*/ 0x000002c0U, + /*0aa3*/ 0x42080010U, + /*0aa4*/ 0x00000003U +}; + +static const uint32_t DDR_PHY_ADR_G_REGSET_G2M[DDR_PHY_ADR_G_REGSET_NUM_G2M] = { + /*0b80*/ 0x00000001U, + /*0b81*/ 0x00000000U, + /*0b82*/ 0x00000005U, + /*0b83*/ 0x04000f00U, + /*0b84*/ 0x00020080U, + /*0b85*/ 0x00020055U, + /*0b86*/ 0x00000000U, + /*0b87*/ 0x00000000U, + /*0b88*/ 0x00000000U, + /*0b89*/ 0x00000050U, + /*0b8a*/ 0x00000000U, + /*0b8b*/ 0x01010100U, + /*0b8c*/ 0x00000600U, + /*0b8d*/ 0x50640000U, + /*0b8e*/ 0x01421142U, + /*0b8f*/ 0x00000142U, + /*0b90*/ 0x00000000U, + /*0b91*/ 0x000f1600U, + /*0b92*/ 0x0f160f16U, + /*0b93*/ 0x0f160f16U, + /*0b94*/ 0x00000003U, + /*0b95*/ 0x0002c000U, + /*0b96*/ 0x02c002c0U, + /*0b97*/ 0x000002c0U, + /*0b98*/ 0x03421342U, + /*0b99*/ 0x00000342U, + /*0b9a*/ 0x00000000U, + /*0b9b*/ 0x00000000U, + /*0b9c*/ 0x05020000U, + /*0b9d*/ 0x00000000U, + /*0b9e*/ 0x00027f6eU, + /*0b9f*/ 0x047f027fU, + /*0ba0*/ 0x00027f6eU, + /*0ba1*/ 0x00047f6eU, + /*0ba2*/ 0x0003554fU, + /*0ba3*/ 0x0001554fU, + /*0ba4*/ 0x0001554fU, + /*0ba5*/ 0x0001554fU, + /*0ba6*/ 0x0001554fU, + /*0ba7*/ 0x00003feeU, + /*0ba8*/ 0x0001554fU, + /*0ba9*/ 0x00003feeU, + /*0baa*/ 0x0001554fU, + /*0bab*/ 0x00027f6eU, + /*0bac*/ 0x0001554fU, + /*0bad*/ 0x00000000U, + /*0bae*/ 0x00000000U, + /*0baf*/ 0x00000000U, + /*0bb0*/ 0x65000000U, + /*0bb1*/ 0x00000000U, + /*0bb2*/ 0x00000000U, + /*0bb3*/ 0x00000201U, + /*0bb4*/ 0x00000000U, + /*0bb5*/ 0x00000000U, + /*0bb6*/ 0x00000000U, + /*0bb7*/ 0x00000000U, + /*0bb8*/ 0x00000000U, + /*0bb9*/ 0x00000000U, + /*0bba*/ 0x00000000U, + /*0bbb*/ 0x00000000U, + /*0bbc*/ 0x06e40000U, + /*0bbd*/ 0x00000000U, + /*0bbe*/ 0x00000000U, + /*0bbf*/ 0x00010000U +}; + +static const uint32_t DDR_PI_REGSET_G2M[DDR_PI_REGSET_NUM_G2M] = { + /*0200*/ 0x00000b00U, + /*0201*/ 0x00000100U, + /*0202*/ 0x00000000U, + /*0203*/ 0x0000ffffU, + /*0204*/ 0x00000000U, + /*0205*/ 0x0000ffffU, + /*0206*/ 0x00000000U, + /*0207*/ 0x304cffffU, + /*0208*/ 0x00000200U, + /*0209*/ 0x00000200U, + /*020a*/ 0x00000200U, + /*020b*/ 0x00000200U, + /*020c*/ 0x0000304cU, + /*020d*/ 0x00000200U, + /*020e*/ 0x00000200U, + /*020f*/ 0x00000200U, + /*0210*/ 0x00000200U, + /*0211*/ 0x0000304cU, + /*0212*/ 0x00000200U, + /*0213*/ 0x00000200U, + /*0214*/ 0x00000200U, + /*0215*/ 0x00000200U, + /*0216*/ 0x00010000U, + /*0217*/ 0x00000003U, + /*0218*/ 0x01000001U, + /*0219*/ 0x00000000U, + /*021a*/ 0x00000000U, + /*021b*/ 0x00000000U, + /*021c*/ 0x00000000U, + /*021d*/ 0x00000000U, + /*021e*/ 0x00000000U, + /*021f*/ 0x00000000U, + /*0220*/ 0x00000000U, + /*0221*/ 0x00000000U, + /*0222*/ 0x00000000U, + /*0223*/ 0x00000000U, + /*0224*/ 0x00000000U, + /*0225*/ 0x00000000U, + /*0226*/ 0x00000000U, + /*0227*/ 0x00000000U, + /*0228*/ 0x00000000U, + /*0229*/ 0x0f000101U, + /*022a*/ 0x08492d25U, + /*022b*/ 0x0e0c0004U, + /*022c*/ 0x000e5000U, + /*022d*/ 0x00000250U, + /*022e*/ 0x00460003U, + /*022f*/ 0x182600cfU, + /*0230*/ 0x182600cfU, + /*0231*/ 0x00000005U, + /*0232*/ 0x00000000U, + /*0233*/ 0x00000000U, + /*0234*/ 0x00000000U, + /*0235*/ 0x00000000U, + /*0236*/ 0x00000000U, + /*0237*/ 0x00000000U, + /*0238*/ 0x00000000U, + /*0239*/ 0x01000000U, + /*023a*/ 0x00040404U, + /*023b*/ 0x01280a00U, + /*023c*/ 0x00000000U, + /*023d*/ 0x000f0000U, + /*023e*/ 0x00001803U, + /*023f*/ 0x00000000U, + /*0240*/ 0x00000000U, + /*0241*/ 0x00060002U, + /*0242*/ 0x00010001U, + /*0243*/ 0x01000101U, + /*0244*/ 0x04020201U, + /*0245*/ 0x00080804U, + /*0246*/ 0x00000000U, + /*0247*/ 0x08030000U, + /*0248*/ 0x15150408U, + /*0249*/ 0x00000000U, + /*024a*/ 0x00000000U, + /*024b*/ 0x00000000U, + /*024c*/ 0x000f0f00U, + /*024d*/ 0x0000001eU, + /*024e*/ 0x00000000U, + /*024f*/ 0x01000300U, + /*0250*/ 0x00000000U, + /*0251*/ 0x00000000U, + /*0252*/ 0x01000000U, + /*0253*/ 0x00010101U, + /*0254*/ 0x000e0e0eU, + /*0255*/ 0x000c0c0cU, + /*0256*/ 0x02060601U, + /*0257*/ 0x00000000U, + /*0258*/ 0x00000003U, + /*0259*/ 0x00181703U, + /*025a*/ 0x00280006U, + /*025b*/ 0x00280016U, + /*025c*/ 0x00000016U, + /*025d*/ 0x00000000U, + /*025e*/ 0x00000000U, + /*025f*/ 0x00000000U, + /*0260*/ 0x140a0000U, + /*0261*/ 0x0005010aU, + /*0262*/ 0x03018d03U, + /*0263*/ 0x000a018dU, + /*0264*/ 0x00060100U, + /*0265*/ 0x01000006U, + /*0266*/ 0x018e018eU, + /*0267*/ 0x018e0100U, + /*0268*/ 0x1111018eU, + /*0269*/ 0x10010204U, + /*026a*/ 0x09090650U, + /*026b*/ 0x20110202U, + /*026c*/ 0x00201000U, + /*026d*/ 0x00201000U, + /*026e*/ 0x04041000U, + /*026f*/ 0x18020100U, + /*0270*/ 0x00010118U, + /*0271*/ 0x004b004aU, + /*0272*/ 0x050f0000U, + /*0273*/ 0x0c01021eU, + /*0274*/ 0x34000000U, + /*0275*/ 0x00000000U, + /*0276*/ 0x00000000U, + /*0277*/ 0x00000000U, + /*0278*/ 0x0000d400U, + /*0279*/ 0x0031002eU, + /*027a*/ 0x00111136U, + /*027b*/ 0x002e00d4U, + /*027c*/ 0x11360031U, + /*027d*/ 0x0000d411U, + /*027e*/ 0x0031002eU, + /*027f*/ 0x00111136U, + /*0280*/ 0x002e00d4U, + /*0281*/ 0x11360031U, + /*0282*/ 0x0000d411U, + /*0283*/ 0x0031002eU, + /*0284*/ 0x00111136U, + /*0285*/ 0x002e00d4U, + /*0286*/ 0x11360031U, + /*0287*/ 0x00d40011U, + /*0288*/ 0x0031002eU, + /*0289*/ 0x00111136U, + /*028a*/ 0x002e00d4U, + /*028b*/ 0x11360031U, + /*028c*/ 0x0000d411U, + /*028d*/ 0x0031002eU, + /*028e*/ 0x00111136U, + /*028f*/ 0x002e00d4U, + /*0290*/ 0x11360031U, + /*0291*/ 0x0000d411U, + /*0292*/ 0x0031002eU, + /*0293*/ 0x00111136U, + /*0294*/ 0x002e00d4U, + /*0295*/ 0x11360031U, + /*0296*/ 0x02000011U, + /*0297*/ 0x018d018dU, + /*0298*/ 0x0c08018dU, + /*0299*/ 0x1f121d22U, + /*029a*/ 0x4301b344U, + /*029b*/ 0x10172006U, + /*029c*/ 0x1d220c10U, + /*029d*/ 0x00001f12U, + /*029e*/ 0x4301b344U, + /*029f*/ 0x10172006U, + /*02a0*/ 0x1d220c10U, + /*02a1*/ 0x00001f12U, + /*02a2*/ 0x4301b344U, + /*02a3*/ 0x10172006U, + /*02a4*/ 0x02000210U, + /*02a5*/ 0x02000200U, + /*02a6*/ 0x02000200U, + /*02a7*/ 0x02000200U, + /*02a8*/ 0x02000200U, + /*02a9*/ 0x00000000U, + /*02aa*/ 0x00000000U, + /*02ab*/ 0x00000000U, + /*02ac*/ 0x00000000U, + /*02ad*/ 0x00000000U, + /*02ae*/ 0x00000000U, + /*02af*/ 0x00000000U, + /*02b0*/ 0x00000000U, + /*02b1*/ 0x00000000U, + /*02b2*/ 0x00000000U, + /*02b3*/ 0x00000000U, + /*02b4*/ 0x00000000U, + /*02b5*/ 0x00000400U, + /*02b6*/ 0x15141312U, + /*02b7*/ 0x11100f0eU, + /*02b8*/ 0x080b0c0dU, + /*02b9*/ 0x05040a09U, + /*02ba*/ 0x01000706U, + /*02bb*/ 0x00000302U, + /*02bc*/ 0x01030201U, + /*02bd*/ 0x00304c00U, + /*02be*/ 0x0001e2f8U, + /*02bf*/ 0x0000304cU, + /*02c0*/ 0x0001e2f8U, + /*02c1*/ 0x0000304cU, + /*02c2*/ 0x0001e2f8U, + /*02c3*/ 0x08000000U, + /*02c4*/ 0x00000100U, + /*02c5*/ 0x00000000U, + /*02c6*/ 0x00000000U, + /*02c7*/ 0x00000000U, + /*02c8*/ 0x00000000U, + /*02c9*/ 0x00000002U +}; + +#endif /* RZG_INIT_DRAM_TABLE_G2M_H */ diff --git a/drivers/renesas/rzg/ddr/dram_sub_func.h b/drivers/renesas/rzg/ddr/dram_sub_func.h new file mode 100644 index 000000000..7affb6156 --- /dev/null +++ b/drivers/renesas/rzg/ddr/dram_sub_func.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef DRAM_SUB_FUNC_H +#define DRAM_SUB_FUNC_H + +#define DRAM_UPDATE_STATUS_ERR -1 +#define DRAM_BOOT_STATUS_COLD 0 +#define DRAM_BOOT_STATUS_WARM 1 + +#endif /* DRAM_SUB_FUNC_H */ -- cgit v1.2.3 From 27bbfca97587bc2073967dd1eea1076c6da41275 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Wed, 16 Dec 2020 11:37:27 +0000 Subject: plat: renesas: common: Include ulcb_cpld.h conditionally Include header ulcb_cpld.h in plat_pm.c only if RCAR_GEN3_ULCB is enabled. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: Ie89223097c608265c50e32778e8df28feed82480 --- plat/renesas/common/plat_pm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plat/renesas/common/plat_pm.c b/plat/renesas/common/plat_pm.c index 7ec78cce3..6a9ad450d 100644 --- a/plat/renesas/common/plat_pm.c +++ b/plat/renesas/common/plat_pm.c @@ -21,7 +21,9 @@ #include "pwrc.h" #include "rcar_def.h" #include "rcar_private.h" +#if RCAR_GEN3_ULCB #include "ulcb_cpld.h" +#endif /* RCAR_GEN3_ULCB */ #define DVFS_SET_VID_0V (0x00) #define P_ALL_OFF (0x80) -- cgit v1.2.3 From 69a9165954b1edf295606e22ec7ae29b86b6274b Mon Sep 17 00:00:00 2001 From: Ross Burton Date: Wed, 13 Jan 2021 12:47:25 +0000 Subject: tools: don't clean when building Don't depend on clean when building, as the user is capable of cleaning if required and this introduces a race where "all" depends on both the compile and the clean in parallel. It's quite possible for some of the compile to happen in parallel with the clean, which results in the link failing as objects just built are missing. Change-Id: I710711eea7483cafa13251c5d94ec693148bd001 Signed-off-by: Ross Burton --- tools/cert_create/Makefile | 2 +- tools/encrypt_fw/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/cert_create/Makefile b/tools/cert_create/Makefile index 0ec08b054..c3c8bcf5e 100644 --- a/tools/cert_create/Makefile +++ b/tools/cert_create/Makefile @@ -59,7 +59,7 @@ HOSTCC ?= gcc .PHONY: all clean realclean -all: clean ${BINARY} +all: ${BINARY} ${BINARY}: ${OBJECTS} Makefile @echo " HOSTLD $@" diff --git a/tools/encrypt_fw/Makefile b/tools/encrypt_fw/Makefile index 6eb6fae7a..96dff2324 100644 --- a/tools/encrypt_fw/Makefile +++ b/tools/encrypt_fw/Makefile @@ -46,7 +46,7 @@ HOSTCC ?= gcc .PHONY: all clean realclean -all: clean ${BINARY} +all: ${BINARY} ${BINARY}: ${OBJECTS} Makefile @echo " HOSTLD $@" -- cgit v1.2.3 From 06ea86fee8bfd1de1a0620e1c627a22af020f40f Mon Sep 17 00:00:00 2001 From: Aditya Angadi Date: Wed, 13 Jan 2021 21:54:01 +0530 Subject: docs: update fvp version to be used for rdv1 platform Move RD-V1 platform to use version of FVP_RD_Daniel from 11.10 build 36 to 11.13 build 10 Signed-off-by: Aditya Angadi Change-Id: I9622c03d342bb780234dec8ffe4ab11d8069acab --- docs/plat/arm/fvp/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/plat/arm/fvp/index.rst b/docs/plat/arm/fvp/index.rst index f643f6b00..ea72962e8 100644 --- a/docs/plat/arm/fvp/index.rst +++ b/docs/plat/arm/fvp/index.rst @@ -49,7 +49,7 @@ Arm FVPs without shifted affinities, and that do not support threaded CPU cores - ``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.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 6114) - ``Foundation_Platform`` -- cgit v1.2.3 From f4db9216f5291f0678d12c53839e49077bfceaec Mon Sep 17 00:00:00 2001 From: Biju Das Date: Mon, 9 Nov 2020 09:38:51 +0000 Subject: renesas: rzg: Add QoS support for RZ/G2M Add QoS support for RZ/G2M SoC. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: If541278fd629761cc83398bba71e63f09d9dbee6 --- drivers/renesas/rzg/qos/G2M/qos_init_g2m_v10.c | 148 +++++++++++++ drivers/renesas/rzg/qos/G2M/qos_init_g2m_v10.h | 12 ++ .../renesas/rzg/qos/G2M/qos_init_g2m_v10_mstat.h | 232 +++++++++++++++++++++ drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11.c | 218 +++++++++++++++++++ drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11.h | 12 ++ .../rzg/qos/G2M/qos_init_g2m_v11_mstat195.h | 230 ++++++++++++++++++++ .../rzg/qos/G2M/qos_init_g2m_v11_mstat390.h | 230 ++++++++++++++++++++ .../rzg/qos/G2M/qos_init_g2m_v11_qoswt195.h | 230 ++++++++++++++++++++ .../rzg/qos/G2M/qos_init_g2m_v11_qoswt390.h | 230 ++++++++++++++++++++ drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30.c | 210 +++++++++++++++++++ drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30.h | 12 ++ .../rzg/qos/G2M/qos_init_g2m_v30_mstat195.h | 230 ++++++++++++++++++++ .../rzg/qos/G2M/qos_init_g2m_v30_mstat390.h | 230 ++++++++++++++++++++ .../rzg/qos/G2M/qos_init_g2m_v30_qoswt195.h | 230 ++++++++++++++++++++ .../rzg/qos/G2M/qos_init_g2m_v30_qoswt390.h | 230 ++++++++++++++++++++ drivers/renesas/rzg/qos/qos.mk | 34 +++ drivers/renesas/rzg/qos/qos_common.h | 67 ++++++ drivers/renesas/rzg/qos/qos_init.c | 175 ++++++++++++++++ drivers/renesas/rzg/qos/qos_init.h | 13 ++ 19 files changed, 2973 insertions(+) create mode 100644 drivers/renesas/rzg/qos/G2M/qos_init_g2m_v10.c create mode 100644 drivers/renesas/rzg/qos/G2M/qos_init_g2m_v10.h create mode 100644 drivers/renesas/rzg/qos/G2M/qos_init_g2m_v10_mstat.h create mode 100644 drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11.c create mode 100644 drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11.h create mode 100644 drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11_mstat195.h create mode 100644 drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11_mstat390.h create mode 100644 drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11_qoswt195.h create mode 100644 drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11_qoswt390.h create mode 100644 drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30.c create mode 100644 drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30.h create mode 100644 drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30_mstat195.h create mode 100644 drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30_mstat390.h create mode 100644 drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30_qoswt195.h create mode 100644 drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30_qoswt390.h create mode 100644 drivers/renesas/rzg/qos/qos.mk create mode 100644 drivers/renesas/rzg/qos/qos_common.h create mode 100644 drivers/renesas/rzg/qos/qos_init.c create mode 100644 drivers/renesas/rzg/qos/qos_init.h diff --git a/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v10.c b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v10.c new file mode 100644 index 000000000..ceaad25f5 --- /dev/null +++ b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v10.c @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2021, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include + +#include "../qos_common.h" +#include "qos_init_g2m_v10.h" +#include "qos_init_g2m_v10_mstat.h" +#include "qos_reg.h" + +#define RCAR_QOS_VERSION "rev.0.19" + +static const struct rcar_gen3_dbsc_qos_settings g2m_v10_qos[] = { + /* BUFCAM settings */ + /* DBSC_DBCAM0CNF0 not set */ + { DBSC_DBCAM0CNF1, 0x00043218U }, + { DBSC_DBCAM0CNF2, 0x000000F4U }, + { DBSC_DBCAM0CNF3, 0x00000000U }, + { DBSC_DBSCHCNT0, 0x080F0037U }, + /* DBSC_DBSCHCNT1 not set */ + { DBSC_DBSCHSZ0, 0x00000001U }, + { DBSC_DBSCHRW0, 0x22421111U }, + + /* DDR3 */ + { DBSC_SCFCTST2, 0x012F1123U }, + + /* QoS Settings */ + { DBSC_DBSCHQOS00, 0x00000F00U }, + { DBSC_DBSCHQOS01, 0x00000B00U }, + { DBSC_DBSCHQOS02, 0x00000000U }, + { DBSC_DBSCHQOS03, 0x00000000U }, + { DBSC_DBSCHQOS40, 0x00000300U }, + { DBSC_DBSCHQOS41, 0x000002F0U }, + { DBSC_DBSCHQOS42, 0x00000200U }, + { DBSC_DBSCHQOS43, 0x00000100U }, + { DBSC_DBSCHQOS90, 0x00000300U }, + { DBSC_DBSCHQOS91, 0x000002F0U }, + { DBSC_DBSCHQOS92, 0x00000200U }, + { DBSC_DBSCHQOS93, 0x00000100U }, + { DBSC_DBSCHQOS130, 0x00000100U }, + { DBSC_DBSCHQOS131, 0x000000F0U }, + { DBSC_DBSCHQOS132, 0x000000A0U }, + { DBSC_DBSCHQOS133, 0x00000040U }, + { DBSC_DBSCHQOS140, 0x000000C0U }, + { DBSC_DBSCHQOS141, 0x000000B0U }, + { DBSC_DBSCHQOS142, 0x00000080U }, + { DBSC_DBSCHQOS143, 0x00000040U }, + { DBSC_DBSCHQOS150, 0x00000040U }, + { DBSC_DBSCHQOS151, 0x00000030U }, + { DBSC_DBSCHQOS152, 0x00000020U }, + { DBSC_DBSCHQOS153, 0x00000010U }, +}; + +void qos_init_g2m_v10(void) +{ + rzg_qos_dbsc_setting(g2m_v10_qos, ARRAY_SIZE(g2m_v10_qos), false); + + /* DRAM split address mapping */ +#if RCAR_DRAM_SPLIT == RCAR_DRAM_SPLIT_4CH +#if RCAR_LSI == RZ_G2M +#error "Don't set DRAM Split 4ch(G2M)" +#else /* RCAR_LSI == RZ_G2M */ + ERROR("DRAM Split 4ch not supported.(G2M)"); + panic(); +#endif /* RCAR_LSI == RZ_G2M */ +#elif (RCAR_DRAM_SPLIT == RCAR_DRAM_SPLIT_2CH) || \ + (RCAR_DRAM_SPLIT == RCAR_DRAM_SPLIT_AUTO) + NOTICE("BL2: DRAM Split is 2ch\n"); + mmio_write_32(AXI_ADSPLCR0, 0x00000000U); + mmio_write_32(AXI_ADSPLCR1, ADSPLCR0_ADRMODE_DEFAULT | + ADSPLCR0_SPLITSEL(0xFFU) | ADSPLCR0_AREA(0x1CU) | + ADSPLCR0_SWP); + mmio_write_32(AXI_ADSPLCR2, 0x089A0000U); + mmio_write_32(AXI_ADSPLCR3, 0x00000000U); +#else /* RCAR_DRAM_SPLIT == RCAR_DRAM_SPLIT_4CH */ + NOTICE("BL2: DRAM Split is OFF\n"); +#endif /* RCAR_DRAM_SPLIT == RCAR_DRAM_SPLIT_4CH */ + +#if !(RCAR_QOS_TYPE == RCAR_QOS_NONE) +#if RCAR_QOS_TYPE == RCAR_QOS_TYPE_DEFAULT + NOTICE("BL2: QoS is default setting(%s)\n", RCAR_QOS_VERSION); +#endif + + /* Resource Alloc setting */ + mmio_write_32(QOSCTRL_RAS, 0x00000028U); + mmio_write_32(QOSCTRL_FIXTH, 0x000F0005U); + mmio_write_32(QOSCTRL_REGGD, 0x00000000U); + mmio_write_64(QOSCTRL_DANN, 0x0101010102020201UL); + mmio_write_32(QOSCTRL_DANT, 0x00100804U); + mmio_write_32(QOSCTRL_EC, 0x00000000U); + mmio_write_64(QOSCTRL_EMS, 0x0000000000000000UL); + mmio_write_32(QOSCTRL_FSS, 0x000003e8U); + mmio_write_32(QOSCTRL_INSFC, 0xC7840001U); + mmio_write_32(QOSCTRL_BERR, 0x00000000U); + mmio_write_32(QOSCTRL_RACNT0, 0x00000000U); + + /* QOSBW setting */ + mmio_write_32(QOSCTRL_SL_INIT, SL_INIT_REFFSSLOT | SL_INIT_SLOTSSLOT | + SL_INIT_SSLOTCLK); + mmio_write_32(QOSCTRL_REF_ARS, 0x00330000U); + + /* QOSBW SRAM setting */ + uint32_t i; + + for (i = 0U; i < ARRAY_SIZE(mstat_fix); i++) { + mmio_write_64(QOSBW_FIX_QOS_BANK0 + i * 8U, mstat_fix[i]); + mmio_write_64(QOSBW_FIX_QOS_BANK1 + i * 8U, mstat_fix[i]); + } + for (i = 0U; i < ARRAY_SIZE(mstat_be); i++) { + mmio_write_64(QOSBW_BE_QOS_BANK0 + i * 8U, mstat_be[i]); + mmio_write_64(QOSBW_BE_QOS_BANK1 + i * 8U, mstat_be[i]); + } + + /* 3DG bus Leaf setting */ + mmio_write_32(0xFD820808U, 0x00001234U); + mmio_write_32(0xFD820800U, 0x00000006U); + mmio_write_32(0xFD821800U, 0x00000006U); + mmio_write_32(0xFD822800U, 0x00000006U); + mmio_write_32(0xFD823800U, 0x00000006U); + mmio_write_32(0xFD824800U, 0x00000006U); + mmio_write_32(0xFD825800U, 0x00000006U); + mmio_write_32(0xFD826800U, 0x00000006U); + mmio_write_32(0xFD827800U, 0x00000006U); + + /* RT bus Leaf setting */ + mmio_write_32(0xFFC50800U, 0x00000000U); + mmio_write_32(0xFFC51800U, 0x00000000U); + + /* Resource Alloc start */ + mmio_write_32(QOSCTRL_RAEN, 0x00000001U); + + /* QOSBW start */ + mmio_write_32(QOSCTRL_STATQC, 0x00000001U); +#else /* !(RCAR_QOS_TYPE == RCAR_QOS_NONE) */ + NOTICE("BL2: QoS is None\n"); + + /* Resource Alloc setting */ + mmio_write_32(QOSCTRL_EC, 0x00000000U); + /* Resource Alloc start */ + mmio_write_32(QOSCTRL_RAEN, 0x00000001U); +#endif /* !(RCAR_QOS_TYPE == RCAR_QOS_NONE) */ +} diff --git a/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v10.h b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v10.h new file mode 100644 index 000000000..627974ab2 --- /dev/null +++ b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v10.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QOS_INIT_G2M_V10_H +#define QOS_INIT_G2M_V10_H + +void qos_init_g2m_v10(void); + +#endif /* QOS_INIT_G2M_V10_H */ diff --git a/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v10_mstat.h b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v10_mstat.h new file mode 100644 index 000000000..c37915c49 --- /dev/null +++ b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v10_mstat.h @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QOS_INIT_G2M_V10_MSTAT_H +#define QOS_INIT_G2M_V10_MSTAT_H + +#if RCAR_QOS_TYPE == RCAR_QOS_TYPE_DEFAULT +static const uint64_t mstat_fix[] = { + /* 0x0000, */ 0x0000000000000000UL, + /* 0x0008, */ 0x0000000000000000UL, + /* 0x0010, */ 0x0000000000000000UL, + /* 0x0018, */ 0x0000000000000000UL, + /* 0x0020, */ 0x0000000000000000UL, + /* 0x0028, */ 0x0000000000000000UL, + /* 0x0030, */ 0x001004030000FFFFUL, + /* 0x0038, */ 0x001004030000FFFFUL, + /* 0x0040, */ 0x001414090000FFFFUL, + /* 0x0048, */ 0x0000000000000000UL, + /* 0x0050, */ 0x001410010000FFFFUL, + /* 0x0058, */ 0x00140C090000FFFFUL, + /* 0x0060, */ 0x00140C090000FFFFUL, + /* 0x0068, */ 0x0000000000000000UL, + /* 0x0070, */ 0x001410010000FFFFUL, + /* 0x0078, */ 0x001004020000FFFFUL, + /* 0x0080, */ 0x0000000000000000UL, + /* 0x0088, */ 0x001414090000FFFFUL, + /* 0x0090, */ 0x001408060000FFFFUL, + /* 0x0098, */ 0x0000000000000000UL, + /* 0x00A0, */ 0x000C08020000FFFFUL, + /* 0x00A8, */ 0x000C04010000FFFFUL, + /* 0x00B0, */ 0x000C04010000FFFFUL, + /* 0x00B8, */ 0x0000000000000000UL, + /* 0x00C0, */ 0x000C08020000FFFFUL, + /* 0x00C8, */ 0x000C04010000FFFFUL, + /* 0x00D0, */ 0x000C04010000FFFFUL, + /* 0x00D8, */ 0x000C04030000FFFFUL, + /* 0x00E0, */ 0x000C100F0000FFFFUL, + /* 0x00E8, */ 0x0000000000000000UL, + /* 0x00F0, */ 0x001010080000FFFFUL, + /* 0x00F8, */ 0x0000000000000000UL, + /* 0x0100, */ 0x0000000000000000UL, + /* 0x0108, */ 0x0000000000000000UL, + /* 0x0110, */ 0x001010080000FFFFUL, + /* 0x0118, */ 0x0000000000000000UL, + /* 0x0120, */ 0x0000000000000000UL, + /* 0x0128, */ 0x0000000000000000UL, + /* 0x0130, */ 0x0000000000000000UL, + /* 0x0138, */ 0x00100C0A0000FFFFUL, + /* 0x0140, */ 0x0000000000000000UL, + /* 0x0148, */ 0x0000000000000000UL, + /* 0x0150, */ 0x00100C0A0000FFFFUL, + /* 0x0158, */ 0x0000000000000000UL, + /* 0x0160, */ 0x00100C0A0000FFFFUL, + /* 0x0168, */ 0x0000000000000000UL, + /* 0x0170, */ 0x0000000000000000UL, + /* 0x0178, */ 0x001008050000FFFFUL, + /* 0x0180, */ 0x0000000000000000UL, + /* 0x0188, */ 0x0000000000000000UL, + /* 0x0190, */ 0x001028280000FFFFUL, + /* 0x0198, */ 0x0000000000000000UL, + /* 0x01A0, */ 0x00100C0A0000FFFFUL, + /* 0x01A8, */ 0x0000000000000000UL, + /* 0x01B0, */ 0x0000000000000000UL, + /* 0x01B8, */ 0x0000000000000000UL, + /* 0x01C0, */ 0x0000000000000000UL, + /* 0x01C8, */ 0x0000000000000000UL, + /* 0x01D0, */ 0x0000000000000000UL, + /* 0x01D8, */ 0x0000000000000000UL, + /* 0x01E0, */ 0x0000000000000000UL, + /* 0x01E8, */ 0x0000000000000000UL, + /* 0x01F0, */ 0x0000000000000000UL, + /* 0x01F8, */ 0x0000000000000000UL, + /* 0x0200, */ 0x0000000000000000UL, + /* 0x0208, */ 0x0000000000000000UL, + /* 0x0210, */ 0x0000000000000000UL, + /* 0x0218, */ 0x0000000000000000UL, + /* 0x0220, */ 0x0000000000000000UL, + /* 0x0228, */ 0x0000000000000000UL, + /* 0x0230, */ 0x0000000000000000UL, + /* 0x0238, */ 0x0000000000000000UL, + /* 0x0240, */ 0x0000000000000000UL, + /* 0x0248, */ 0x0000000000000000UL, + /* 0x0250, */ 0x0000000000000000UL, + /* 0x0258, */ 0x0000000000000000UL, + /* 0x0260, */ 0x0000000000000000UL, + /* 0x0268, */ 0x001408010000FFFFUL, + /* 0x0270, */ 0x001404010000FFFFUL, + /* 0x0278, */ 0x0000000000000000UL, + /* 0x0280, */ 0x0000000000000000UL, + /* 0x0288, */ 0x0000000000000000UL, + /* 0x0290, */ 0x001408010000FFFFUL, + /* 0x0298, */ 0x001404010000FFFFUL, + /* 0x02A0, */ 0x000C04010000FFFFUL, + /* 0x02A8, */ 0x000C04010000FFFFUL, + /* 0x02B0, */ 0x001404010000FFFFUL, + /* 0x02B8, */ 0x0000000000000000UL, + /* 0x02C0, */ 0x0000000000000000UL, + /* 0x02C8, */ 0x0000000000000000UL, + /* 0x02D0, */ 0x000C04010000FFFFUL, + /* 0x02D8, */ 0x000C04010000FFFFUL, + /* 0x02E0, */ 0x001404010000FFFFUL, + /* 0x02E8, */ 0x0000000000000000UL, + /* 0x02F0, */ 0x0000000000000000UL, + /* 0x02F8, */ 0x0000000000000000UL, + /* 0x0300, */ 0x0000000000000000UL, + /* 0x0308, */ 0x0000000000000000UL, + /* 0x0310, */ 0x0000000000000000UL, + /* 0x0318, */ 0x0000000000000000UL, + /* 0x0320, */ 0x0000000000000000UL, + /* 0x0328, */ 0x0000000000000000UL, + /* 0x0330, */ 0x0000000000000000UL, + /* 0x0338, */ 0x0000000000000000UL, + /* 0x0340, */ 0x0000000000000000UL, + /* 0x0348, */ 0x0000000000000000UL, + /* 0x0350, */ 0x0000000000000000UL, +}; + +static const uint64_t mstat_be[] = { + /* 0x0000, */ 0x001200100C89C401UL, + /* 0x0008, */ 0x001200100C89C401UL, + /* 0x0010, */ 0x001200100C89C401UL, + /* 0x0018, */ 0x001200100C89C401UL, + /* 0x0020, */ 0x0000000000000000UL, + /* 0x0028, */ 0x001100100C803401UL, + /* 0x0030, */ 0x0000000000000000UL, + /* 0x0038, */ 0x0000000000000000UL, + /* 0x0040, */ 0x0000000000000000UL, + /* 0x0048, */ 0x0000000000000000UL, + /* 0x0050, */ 0x0000000000000000UL, + /* 0x0058, */ 0x0000000000000000UL, + /* 0x0060, */ 0x0000000000000000UL, + /* 0x0068, */ 0x0000000000000000UL, + /* 0x0070, */ 0x0000000000000000UL, + /* 0x0078, */ 0x0000000000000000UL, + /* 0x0080, */ 0x0000000000000000UL, + /* 0x0088, */ 0x0000000000000000UL, + /* 0x0090, */ 0x0000000000000000UL, + /* 0x0098, */ 0x0000000000000000UL, + /* 0x00A0, */ 0x0000000000000000UL, + /* 0x00A8, */ 0x0000000000000000UL, + /* 0x00B0, */ 0x0000000000000000UL, + /* 0x00B8, */ 0x0000000000000000UL, + /* 0x00C0, */ 0x0000000000000000UL, + /* 0x00C8, */ 0x0000000000000000UL, + /* 0x00D0, */ 0x0000000000000000UL, + /* 0x00D8, */ 0x0000000000000000UL, + /* 0x00E0, */ 0x0000000000000000UL, + /* 0x00E8, */ 0x0000000000000000UL, + /* 0x00F0, */ 0x0000000000000000UL, + /* 0x00F8, */ 0x0000000000000000UL, + /* 0x0100, */ 0x0000000000000000UL, + /* 0x0108, */ 0x0000000000000000UL, + /* 0x0110, */ 0x0000000000000000UL, + /* 0x0118, */ 0x0000000000000000UL, + /* 0x0120, */ 0x0000000000000000UL, + /* 0x0128, */ 0x0000000000000000UL, + /* 0x0130, */ 0x0000000000000000UL, + /* 0x0138, */ 0x0000000000000000UL, + /* 0x0140, */ 0x0000000000000000UL, + /* 0x0148, */ 0x0000000000000000UL, + /* 0x0150, */ 0x0000000000000000UL, + /* 0x0158, */ 0x0000000000000000UL, + /* 0x0160, */ 0x0000000000000000UL, + /* 0x0168, */ 0x0000000000000000UL, + /* 0x0170, */ 0x0000000000000000UL, + /* 0x0178, */ 0x0000000000000000UL, + /* 0x0180, */ 0x0000000000000000UL, + /* 0x0188, */ 0x0000000000000000UL, + /* 0x0190, */ 0x0000000000000000UL, + /* 0x0198, */ 0x0000000000000000UL, + /* 0x01A0, */ 0x0000000000000000UL, + /* 0x01A8, */ 0x0000000000000000UL, + /* 0x01B0, */ 0x0000000000000000UL, + /* 0x01B8, */ 0x0000000000000000UL, + /* 0x01C0, */ 0x001100500C8FFC01UL, + /* 0x01C8, */ 0x001100500C8FFC01UL, + /* 0x01D0, */ 0x001100500C8FFC01UL, + /* 0x01D8, */ 0x001100500C8FFC01UL, + /* 0x01E0, */ 0x0000000000000000UL, + /* 0x01E8, */ 0x001200100C803401UL, + /* 0x01F0, */ 0x001100100C80FC01UL, + /* 0x01F8, */ 0x0000000000000000UL, + /* 0x0200, */ 0x0000000000000000UL, + /* 0x0208, */ 0x001200100C80FC01UL, + /* 0x0210, */ 0x001100100C80FC01UL, + /* 0x0218, */ 0x001100100C825801UL, + /* 0x0220, */ 0x001100100C825801UL, + /* 0x0228, */ 0x0000000000000000UL, + /* 0x0230, */ 0x001100100C825801UL, + /* 0x0238, */ 0x001100100C825801UL, + /* 0x0240, */ 0x001200100C8BB801UL, + /* 0x0248, */ 0x001100100C8EA401UL, + /* 0x0250, */ 0x001200100C8BB801UL, + /* 0x0258, */ 0x001100100C8EA401UL, + /* 0x0260, */ 0x001100100C84E401UL, + /* 0x0268, */ 0x0000000000000000UL, + /* 0x0270, */ 0x0000000000000000UL, + /* 0x0278, */ 0x001100100C81F401UL, + /* 0x0280, */ 0x0000000000000000UL, + /* 0x0288, */ 0x0000000000000000UL, + /* 0x0290, */ 0x0000000000000000UL, + /* 0x0298, */ 0x0000000000000000UL, + /* 0x02A0, */ 0x0000000000000000UL, + /* 0x02A8, */ 0x0000000000000000UL, + /* 0x02B0, */ 0x0000000000000000UL, + /* 0x02B8, */ 0x001100100C803401UL, + /* 0x02C0, */ 0x0000000000000000UL, + /* 0x02C8, */ 0x0000000000000000UL, + /* 0x02D0, */ 0x0000000000000000UL, + /* 0x02D8, */ 0x0000000000000000UL, + /* 0x02E0, */ 0x0000000000000000UL, + /* 0x02E8, */ 0x001100100C803401UL, + /* 0x02F0, */ 0x001100300C8FFC01UL, + /* 0x02F8, */ 0x001100500C8FFC01UL, + /* 0x0300, */ 0x0000000000000000UL, + /* 0x0308, */ 0x001100300C8FFC01UL, + /* 0x0310, */ 0x001100500C8FFC01UL, + /* 0x0318, */ 0x001200100C803401UL, + /* 0x0320, */ 0x0000000000000000UL, + /* 0x0328, */ 0x0000000000000000UL, + /* 0x0330, */ 0x0000000000000000UL, + /* 0x0338, */ 0x0000000000000000UL, + /* 0x0340, */ 0x0000000000000000UL, + /* 0x0348, */ 0x0000000000000000UL, + /* 0x0350, */ 0x0000000000000000UL, +}; +#endif /* RCAR_QOS_TYPE == RCAR_QOS_TYPE_DEFAULT */ + +#endif /* QOS_INIT_G2M_V10_MSTAT_H */ diff --git a/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11.c b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11.c new file mode 100644 index 000000000..db61858ff --- /dev/null +++ b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11.c @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2021, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include + +#include "../qos_common.h" +#include "qos_init_g2m_v11.h" +#if RCAR_QOS_TYPE == RCAR_QOS_TYPE_DEFAULT +#if RCAR_REF_INT == RCAR_REF_DEFAULT +#include "qos_init_g2m_v11_mstat195.h" +#else /* RCAR_REF_INT == RCAR_REF_DEFAULT */ +#include "qos_init_g2m_v11_mstat390.h" +#endif /* RCAR_REF_INT == RCAR_REF_DEFAULT */ +#if RCAR_REWT_TRAINING != RCAR_REWT_TRAINING_DISABLE +#if RCAR_REF_INT == RCAR_REF_DEFAULT +#include "qos_init_g2m_v11_qoswt195.h" +#else /* RCAR_REF_INT == RCAR_REF_DEFAULT */ +#include "qos_init_g2m_v11_qoswt390.h" +#endif /* RCAR_REF_INT == RCAR_REF_DEFAULT */ +#endif /* RCAR_REWT_TRAINING != RCAR_REWT_TRAINING_DISABLE */ +#endif /* RCAR_QOS_TYPE == RCAR_QOS_TYPE_DEFAULT */ +#include "qos_reg.h" + +#define RCAR_QOS_VERSION "rev.0.19" + +#define QOSWT_TIME_BANK0 20000000U /* unit:ns */ + +#define QOSWT_WTEN_ENABLE 0x1U + +#define QOSCTRL_REF_ARS_ARBSTOPCYCLE_G2M_11 (SL_INIT_SSLOTCLK_G2M_11 - 0x5U) + +#define OSWT_WTREF_SLOT0_EN_REQ1_SLOT 3U +#define OSWT_WTREF_SLOT0_EN_REQ2_SLOT 9U +#define QOSWT_WTREF_SLOT0_EN \ + ((0x1U << OSWT_WTREF_SLOT0_EN_REQ1_SLOT) | \ + (0x1U << OSWT_WTREF_SLOT0_EN_REQ2_SLOT)) +#define QOSWT_WTREF_SLOT1_EN \ + ((0x1U << OSWT_WTREF_SLOT0_EN_REQ1_SLOT) | \ + (0x1U << OSWT_WTREF_SLOT0_EN_REQ2_SLOT)) + +#define QOSWT_WTSET0_REQ_SSLOT0 5U +#define WT_BASE_SUB_SLOT_NUM0 12U +#define QOSWT_WTSET0_PERIOD0_G2M_11 \ + ((QOSWT_TIME_BANK0 / QOSWT_WTSET0_CYCLE_G2M_11) - 1U) +#define QOSWT_WTSET0_SSLOT0 (QOSWT_WTSET0_REQ_SSLOT0 - 1U) +#define QOSWT_WTSET0_SLOTSLOT0 (WT_BASE_SUB_SLOT_NUM0 - 1U) + +#define QOSWT_WTSET1_PERIOD1_G2M_11 \ + ((QOSWT_TIME_BANK0 / QOSWT_WTSET0_CYCLE_G2M_11) - 1U) +#define QOSWT_WTSET1_SSLOT1 (QOSWT_WTSET0_REQ_SSLOT0 - 1U) +#define QOSWT_WTSET1_SLOTSLOT1 (WT_BASE_SUB_SLOT_NUM0 - 1U) + +static const struct rcar_gen3_dbsc_qos_settings g2m_v11_qos[] = { + /* BUFCAM settings */ + { DBSC_DBCAM0CNF1, 0x00043218U }, + { DBSC_DBCAM0CNF2, 0x000000F4U }, + { DBSC_DBCAM0CNF3, 0x00000000U }, + { DBSC_DBSCHCNT0, 0x000F0037U }, + { DBSC_DBSCHSZ0, 0x00000001U }, + { DBSC_DBSCHRW0, 0x22421111U }, + + /* DDR3 */ + { DBSC_SCFCTST2, 0x012F1123U }, + + /* QoS settings */ + { DBSC_DBSCHQOS00, 0x00000F00U }, + { DBSC_DBSCHQOS01, 0x00000B00U }, + { DBSC_DBSCHQOS02, 0x00000000U }, + { DBSC_DBSCHQOS03, 0x00000000U }, + { DBSC_DBSCHQOS40, 0x00000300U }, + { DBSC_DBSCHQOS41, 0x000002F0U }, + { DBSC_DBSCHQOS42, 0x00000200U }, + { DBSC_DBSCHQOS43, 0x00000100U }, + { DBSC_DBSCHQOS90, 0x00000100U }, + { DBSC_DBSCHQOS91, 0x000000F0U }, + { DBSC_DBSCHQOS92, 0x000000A0U }, + { DBSC_DBSCHQOS93, 0x00000040U }, + { DBSC_DBSCHQOS120, 0x00000040U }, + { DBSC_DBSCHQOS121, 0x00000030U }, + { DBSC_DBSCHQOS122, 0x00000020U }, + { DBSC_DBSCHQOS123, 0x00000010U }, + { DBSC_DBSCHQOS130, 0x00000100U }, + { DBSC_DBSCHQOS131, 0x000000F0U }, + { DBSC_DBSCHQOS132, 0x000000A0U }, + { DBSC_DBSCHQOS133, 0x00000040U }, + { DBSC_DBSCHQOS140, 0x000000C0U }, + { DBSC_DBSCHQOS141, 0x000000B0U }, + { DBSC_DBSCHQOS142, 0x00000080U }, + { DBSC_DBSCHQOS143, 0x00000040U }, + { DBSC_DBSCHQOS150, 0x00000040U }, + { DBSC_DBSCHQOS151, 0x00000030U }, + { DBSC_DBSCHQOS152, 0x00000020U }, + { DBSC_DBSCHQOS153, 0x00000010U }, +}; + +void qos_init_g2m_v11(void) +{ + uint32_t i; + + rzg_qos_dbsc_setting(g2m_v11_qos, ARRAY_SIZE(g2m_v11_qos), false); + + /* DRAM Split Address mapping */ +#if RCAR_DRAM_SPLIT == RCAR_DRAM_SPLIT_4CH +#if RCAR_LSI == RZ_G2M +#error "Don't set DRAM Split 4ch(G2M)" +#else /* RCAR_LSI == RZ_G2M */ + ERROR("DRAM Split 4ch not supported.(G2M)"); + panic(); +#endif /* RCAR_LSI == RZ_G2M */ +#elif (RCAR_DRAM_SPLIT == RCAR_DRAM_SPLIT_2CH) || \ + (RCAR_DRAM_SPLIT == RCAR_DRAM_SPLIT_AUTO) + NOTICE("BL2: DRAM Split is 2ch\n"); + mmio_write_32(AXI_ADSPLCR0, 0x00000000U); + mmio_write_32(AXI_ADSPLCR1, ADSPLCR0_ADRMODE_DEFAULT | + ADSPLCR0_SPLITSEL(0xFFU) | ADSPLCR0_AREA(0x1CU) | + ADSPLCR0_SWP); + mmio_write_32(AXI_ADSPLCR2, 0x00001004U); + mmio_write_32(AXI_ADSPLCR3, 0x00000000U); +#else /* RCAR_DRAM_SPLIT == RCAR_DRAM_SPLIT_4CH */ + NOTICE("BL2: DRAM Split is OFF\n"); +#endif /* RCAR_DRAM_SPLIT == RCAR_DRAM_SPLIT_4CH */ + +#if !(RCAR_QOS_TYPE == RCAR_QOS_NONE) +#if RCAR_QOS_TYPE == RCAR_QOS_TYPE_DEFAULT + NOTICE("BL2: QoS is default setting(%s)\n", RCAR_QOS_VERSION); +#endif /* RCAR_QOS_TYPE == RCAR_QOS_TYPE_DEFAULT */ + +#if RCAR_REF_INT == RCAR_REF_DEFAULT + NOTICE("BL2: DRAM refresh interval 1.95 usec\n"); +#else /* RCAR_REF_INT == RCAR_REF_DEFAULT */ + NOTICE("BL2: DRAM refresh interval 3.9 usec\n"); +#endif /* RCAR_REF_INT == RCAR_REF_DEFAULT */ + +#if RCAR_REWT_TRAINING != RCAR_REWT_TRAINING_DISABLE + NOTICE("BL2: Periodic Write DQ Training\n"); +#endif /* RCAR_REWT_TRAINING != RCAR_REWT_TRAINING_DISABLE */ + + mmio_write_32(QOSCTRL_RAS, 0x00000044U); + mmio_write_64(QOSCTRL_DANN, 0x0404020002020201UL); + mmio_write_32(QOSCTRL_DANT, 0x0020100AU); + mmio_write_32(QOSCTRL_INSFC, 0x06330001U); + mmio_write_32(QOSCTRL_RACNT0, 0x02010003U); /* GPU Boost Mode ON */ + + mmio_write_32(QOSCTRL_SL_INIT, + SL_INIT_REFFSSLOT | SL_INIT_SLOTSSLOT | + SL_INIT_SSLOTCLK_G2M_11); +#if RCAR_REWT_TRAINING != RCAR_REWT_TRAINING_DISABLE + mmio_write_32(QOSCTRL_REF_ARS, + QOSCTRL_REF_ARS_ARBSTOPCYCLE_G2M_11 << 16); +#else /* RCAR_REWT_TRAINING != RCAR_REWT_TRAINING_DISABLE */ + mmio_write_32(QOSCTRL_REF_ARS, 0x00330000U); +#endif /* RCAR_REWT_TRAINING != RCAR_REWT_TRAINING_DISABLE */ + + for (i = 0U; i < ARRAY_SIZE(mstat_fix); i++) { + mmio_write_64(QOSBW_FIX_QOS_BANK0 + i * 8U, mstat_fix[i]); + mmio_write_64(QOSBW_FIX_QOS_BANK1 + i * 8U, mstat_fix[i]); + } + for (i = 0U; i < ARRAY_SIZE(mstat_be); i++) { + mmio_write_64(QOSBW_BE_QOS_BANK0 + i * 8U, mstat_be[i]); + mmio_write_64(QOSBW_BE_QOS_BANK1 + i * 8U, mstat_be[i]); + } +#if RCAR_REWT_TRAINING != RCAR_REWT_TRAINING_DISABLE + for (i = 0U; i < ARRAY_SIZE(qoswt_fix); i++) { + mmio_write_64(QOSWT_FIX_WTQOS_BANK0 + i * 8U, qoswt_fix[i]); + mmio_write_64(QOSWT_FIX_WTQOS_BANK1 + i * 8U, qoswt_fix[i]); + } + for (i = 0U; i < ARRAY_SIZE(qoswt_be); i++) { + mmio_write_64(QOSWT_BE_WTQOS_BANK0 + i * 8U, qoswt_be[i]); + mmio_write_64(QOSWT_BE_WTQOS_BANK1 + i * 8U, qoswt_be[i]); + } +#endif /* RCAR_REWT_TRAINING != RCAR_REWT_TRAINING_DISABLE */ + + /* 3DG bus Leaf setting */ + mmio_write_32(GPU_ACT_GRD, 0x00001234U); + mmio_write_32(GPU_ACT0, 0x00000000U); + mmio_write_32(GPU_ACT1, 0x00000000U); + mmio_write_32(GPU_ACT2, 0x00000000U); + mmio_write_32(GPU_ACT3, 0x00000000U); + + /* RT bus Leaf setting */ + mmio_write_32(RT_ACT0, 0x00000000U); + mmio_write_32(RT_ACT1, 0x00000000U); + + /* CCI bus Leaf setting */ + mmio_write_32(CPU_ACT0, 0x00000003U); + mmio_write_32(CPU_ACT1, 0x00000003U); + mmio_write_32(CPU_ACT2, 0x00000003U); + mmio_write_32(CPU_ACT3, 0x00000003U); + + mmio_write_32(QOSCTRL_RAEN, 0x00000001U); + +#if RCAR_REWT_TRAINING != RCAR_REWT_TRAINING_DISABLE + /* re-write training setting */ + mmio_write_32(QOSWT_WTREF, + (QOSWT_WTREF_SLOT1_EN << 16) | QOSWT_WTREF_SLOT0_EN); + mmio_write_32(QOSWT_WTSET0, + (QOSWT_WTSET0_PERIOD0_G2M_11 << 16) | + (QOSWT_WTSET0_SSLOT0 << 8) | QOSWT_WTSET0_SLOTSLOT0); + mmio_write_32(QOSWT_WTSET1, + (QOSWT_WTSET1_PERIOD1_G2M_11 << 16) | + (QOSWT_WTSET1_SSLOT1 << 8) | QOSWT_WTSET1_SLOTSLOT1); + + mmio_write_32(QOSWT_WTEN, QOSWT_WTEN_ENABLE); +#endif /* RCAR_REWT_TRAINING != RCAR_REWT_TRAINING_DISABLE */ + + mmio_write_32(QOSCTRL_STATQC, 0x00000001U); +#else /* !(RCAR_QOS_TYPE == RCAR_QOS_NONE) */ + NOTICE("BL2: QoS is None\n"); + + mmio_write_32(QOSCTRL_RAEN, 0x00000001U); +#endif /* !(RCAR_QOS_TYPE == RCAR_QOS_NONE) */ +} diff --git a/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11.h b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11.h new file mode 100644 index 000000000..d0424930b --- /dev/null +++ b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QOS_INIT_G2M_V11_H +#define QOS_INIT_G2M_V11_H + +void qos_init_g2m_v11(void); + +#endif /* QOS_INIT_G2M_V11_H */ diff --git a/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11_mstat195.h b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11_mstat195.h new file mode 100644 index 000000000..950abd6fb --- /dev/null +++ b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11_mstat195.h @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QOS_INIT_G2M_V11_MSTAT195_H +#define QOS_INIT_G2M_V11_MSTAT195_H + +static uint64_t mstat_fix[] = { + /* 0x0000, */ 0x0000000000000000UL, + /* 0x0008, */ 0x0000000000000000UL, + /* 0x0010, */ 0x0000000000000000UL, + /* 0x0018, */ 0x0000000000000000UL, + /* 0x0020, */ 0x0000000000000000UL, + /* 0x0028, */ 0x0000000000000000UL, + /* 0x0030, */ 0x001004040000FFFFUL, + /* 0x0038, */ 0x001004040000FFFFUL, + /* 0x0040, */ 0x001414090000FFFFUL, + /* 0x0048, */ 0x0000000000000000UL, + /* 0x0050, */ 0x001404010000FFFFUL, + /* 0x0058, */ 0x00140C0A0000FFFFUL, + /* 0x0060, */ 0x00140C0A0000FFFFUL, + /* 0x0068, */ 0x0000000000000000UL, + /* 0x0070, */ 0x001404010000FFFFUL, + /* 0x0078, */ 0x001004030000FFFFUL, + /* 0x0080, */ 0x0000000000000000UL, + /* 0x0088, */ 0x001414090000FFFFUL, + /* 0x0090, */ 0x001408070000FFFFUL, + /* 0x0098, */ 0x0000000000000000UL, + /* 0x00a0, */ 0x000C04020000FFFFUL, + /* 0x00a8, */ 0x000C04010000FFFFUL, + /* 0x00b0, */ 0x000C04010000FFFFUL, + /* 0x00b8, */ 0x0000000000000000UL, + /* 0x00c0, */ 0x000C04020000FFFFUL, + /* 0x00c8, */ 0x000C04010000FFFFUL, + /* 0x00d0, */ 0x000C04010000FFFFUL, + /* 0x00d8, */ 0x000C08050000FFFFUL, + /* 0x00e0, */ 0x000C14120000FFFFUL, + /* 0x00e8, */ 0x0000000000000000UL, + /* 0x00f0, */ 0x0000000000000000UL, + /* 0x00f8, */ 0x0000000000000000UL, + /* 0x0100, */ 0x0000000000000000UL, + /* 0x0108, */ 0x0000000000000000UL, + /* 0x0110, */ 0x0000000000000000UL, + /* 0x0118, */ 0x0000000000000000UL, + /* 0x0120, */ 0x0000000000000000UL, + /* 0x0128, */ 0x0000000000000000UL, + /* 0x0130, */ 0x0000000000000000UL, + /* 0x0138, */ 0x00100C0B0000FFFFUL, + /* 0x0140, */ 0x0000000000000000UL, + /* 0x0148, */ 0x0000000000000000UL, + /* 0x0150, */ 0x0010100D0000FFFFUL, + /* 0x0158, */ 0x0000000000000000UL, + /* 0x0160, */ 0x00100C0B0000FFFFUL, + /* 0x0168, */ 0x0000000000000000UL, + /* 0x0170, */ 0x0000000000000000UL, + /* 0x0178, */ 0x001008060000FFFFUL, + /* 0x0180, */ 0x0000000000000000UL, + /* 0x0188, */ 0x0000000000000000UL, + /* 0x0190, */ 0x00102C2C0000FFFFUL, + /* 0x0198, */ 0x0000000000000000UL, + /* 0x01a0, */ 0x00100C0B0000FFFFUL, + /* 0x01a8, */ 0x0000000000000000UL, + /* 0x01b0, */ 0x0000000000000000UL, + /* 0x01b8, */ 0x0000000000000000UL, + /* 0x01c0, */ 0x000C04010000FFFFUL, + /* 0x01c8, */ 0x000C04010000FFFFUL, + /* 0x01d0, */ 0x000C04010000FFFFUL, + /* 0x01d8, */ 0x000C04010000FFFFUL, + /* 0x01e0, */ 0x0000000000000000UL, + /* 0x01e8, */ 0x0000000000000000UL, + /* 0x01f0, */ 0x0000000000000000UL, + /* 0x01f8, */ 0x0000000000000000UL, + /* 0x0200, */ 0x0000000000000000UL, + /* 0x0208, */ 0x0000000000000000UL, + /* 0x0210, */ 0x0000000000000000UL, + /* 0x0218, */ 0x0000000000000000UL, + /* 0x0220, */ 0x0000000000000000UL, + /* 0x0228, */ 0x0000000000000000UL, + /* 0x0230, */ 0x0000000000000000UL, + /* 0x0238, */ 0x0000000000000000UL, + /* 0x0240, */ 0x0000000000000000UL, + /* 0x0248, */ 0x0000000000000000UL, + /* 0x0250, */ 0x0000000000000000UL, + /* 0x0258, */ 0x0000000000000000UL, + /* 0x0260, */ 0x0000000000000000UL, + /* 0x0268, */ 0x001408010000FFFFUL, + /* 0x0270, */ 0x001404010000FFFFUL, + /* 0x0278, */ 0x0000000000000000UL, + /* 0x0280, */ 0x0000000000000000UL, + /* 0x0288, */ 0x0000000000000000UL, + /* 0x0290, */ 0x001408010000FFFFUL, + /* 0x0298, */ 0x001404010000FFFFUL, + /* 0x02a0, */ 0x000C04010000FFFFUL, + /* 0x02a8, */ 0x000C04010000FFFFUL, + /* 0x02b0, */ 0x0000000000000000UL, + /* 0x02b8, */ 0x0000000000000000UL, + /* 0x02c0, */ 0x0000000000000000UL, + /* 0x02c8, */ 0x0000000000000000UL, + /* 0x02d0, */ 0x000C04010000FFFFUL, + /* 0x02d8, */ 0x000C04010000FFFFUL, + /* 0x02e0, */ 0x0000000000000000UL, + /* 0x02e8, */ 0x0000000000000000UL, + /* 0x02f0, */ 0x0000000000000000UL, + /* 0x02f8, */ 0x0000000000000000UL, + /* 0x0300, */ 0x0000000000000000UL, + /* 0x0308, */ 0x0000000000000000UL, + /* 0x0310, */ 0x0000000000000000UL, + /* 0x0318, */ 0x0000000000000000UL, + /* 0x0320, */ 0x0000000000000000UL, + /* 0x0328, */ 0x0000000000000000UL, + /* 0x0330, */ 0x0000000000000000UL, + /* 0x0338, */ 0x0000000000000000UL, + /* 0x0340, */ 0x0000000000000000UL, + /* 0x0348, */ 0x0000000000000000UL, + /* 0x0350, */ 0x0000000000000000UL, +}; + +static uint64_t mstat_be[] = { + /* 0x0000, */ 0x0000000000000000UL, + /* 0x0008, */ 0x0000000000000000UL, + /* 0x0010, */ 0x0000000000000000UL, + /* 0x0018, */ 0x0000000000000000UL, + /* 0x0020, */ 0x0000000000000000UL, + /* 0x0028, */ 0x001200100BD03401UL, + /* 0x0030, */ 0x0000000000000000UL, + /* 0x0038, */ 0x0000000000000000UL, + /* 0x0040, */ 0x0000000000000000UL, + /* 0x0048, */ 0x0000000000000000UL, + /* 0x0050, */ 0x0000000000000000UL, + /* 0x0058, */ 0x0000000000000000UL, + /* 0x0060, */ 0x0000000000000000UL, + /* 0x0068, */ 0x0000000000000000UL, + /* 0x0070, */ 0x0000000000000000UL, + /* 0x0078, */ 0x0000000000000000UL, + /* 0x0080, */ 0x0000000000000000UL, + /* 0x0088, */ 0x0000000000000000UL, + /* 0x0090, */ 0x0000000000000000UL, + /* 0x0098, */ 0x0000000000000000UL, + /* 0x00a0, */ 0x0000000000000000UL, + /* 0x00a8, */ 0x0000000000000000UL, + /* 0x00b0, */ 0x0000000000000000UL, + /* 0x00b8, */ 0x0000000000000000UL, + /* 0x00c0, */ 0x0000000000000000UL, + /* 0x00c8, */ 0x0000000000000000UL, + /* 0x00d0, */ 0x0000000000000000UL, + /* 0x00d8, */ 0x0000000000000000UL, + /* 0x00e0, */ 0x0000000000000000UL, + /* 0x00e8, */ 0x0000000000000000UL, + /* 0x00f0, */ 0x0000000000000000UL, + /* 0x00f8, */ 0x0000000000000000UL, + /* 0x0100, */ 0x0000000000000000UL, + /* 0x0108, */ 0x0000000000000000UL, + /* 0x0110, */ 0x0000000000000000UL, + /* 0x0118, */ 0x0000000000000000UL, + /* 0x0120, */ 0x0000000000000000UL, + /* 0x0128, */ 0x0000000000000000UL, + /* 0x0130, */ 0x0000000000000000UL, + /* 0x0138, */ 0x0000000000000000UL, + /* 0x0140, */ 0x0000000000000000UL, + /* 0x0148, */ 0x0000000000000000UL, + /* 0x0150, */ 0x0000000000000000UL, + /* 0x0158, */ 0x0000000000000000UL, + /* 0x0160, */ 0x0000000000000000UL, + /* 0x0168, */ 0x0000000000000000UL, + /* 0x0170, */ 0x0000000000000000UL, + /* 0x0178, */ 0x0000000000000000UL, + /* 0x0180, */ 0x0000000000000000UL, + /* 0x0188, */ 0x0000000000000000UL, + /* 0x0190, */ 0x0000000000000000UL, + /* 0x0198, */ 0x0000000000000000UL, + /* 0x01a0, */ 0x0000000000000000UL, + /* 0x01a8, */ 0x0000000000000000UL, + /* 0x01b0, */ 0x0000000000000000UL, + /* 0x01b8, */ 0x0000000000000000UL, + /* 0x01c0, */ 0x002100600BDFFC01UL, + /* 0x01c8, */ 0x002100600BDFFC01UL, + /* 0x01d0, */ 0x002100600BDFFC01UL, + /* 0x01d8, */ 0x002100600BDFFC01UL, + /* 0x01e0, */ 0x0000000000000000UL, + /* 0x01e8, */ 0x0000000000000000UL, + /* 0x01f0, */ 0x0000000000000000UL, + /* 0x01f8, */ 0x0000000000000000UL, + /* 0x0200, */ 0x0000000000000000UL, + /* 0x0208, */ 0x0000000000000000UL, + /* 0x0210, */ 0x0000000000000000UL, + /* 0x0218, */ 0x001100200BDFFC01UL, + /* 0x0220, */ 0x001100200BDFFC01UL, + /* 0x0228, */ 0x0000000000000000UL, + /* 0x0230, */ 0x001100200BDFFC01UL, + /* 0x0238, */ 0x001100200BDFFC01UL, + /* 0x0240, */ 0x001200200BDFFC01UL, + /* 0x0248, */ 0x001100200BDFFC01UL, + /* 0x0250, */ 0x001200200BDFFC01UL, + /* 0x0258, */ 0x001100200BDFFC01UL, + /* 0x0260, */ 0x0000000000000000UL, + /* 0x0268, */ 0x0000000000000000UL, + /* 0x0270, */ 0x0000000000000000UL, + /* 0x0278, */ 0x0000000000000000UL, + /* 0x0280, */ 0x0000000000000000UL, + /* 0x0288, */ 0x0000000000000000UL, + /* 0x0290, */ 0x0000000000000000UL, + /* 0x0298, */ 0x0000000000000000UL, + /* 0x02a0, */ 0x0000000000000000UL, + /* 0x02a8, */ 0x0000000000000000UL, + /* 0x02b0, */ 0x0000000000000000UL, + /* 0x02b8, */ 0x0000000000000000UL, + /* 0x02c0, */ 0x0000000000000000UL, + /* 0x02c8, */ 0x0000000000000000UL, + /* 0x02d0, */ 0x0000000000000000UL, + /* 0x02d8, */ 0x0000000000000000UL, + /* 0x02e0, */ 0x0000000000000000UL, + /* 0x02e8, */ 0x0000000000000000UL, + /* 0x02f0, */ 0x001100400BDFFC01UL, + /* 0x02f8, */ 0x001100600BDFFC01UL, + /* 0x0300, */ 0x0000000000000000UL, + /* 0x0308, */ 0x001100400BDFFC01UL, + /* 0x0310, */ 0x001100600BDFFC01UL, + /* 0x0318, */ 0x001200100BD03401UL, + /* 0x0320, */ 0x0000000000000000UL, + /* 0x0328, */ 0x0000000000000000UL, + /* 0x0330, */ 0x0000000000000000UL, + /* 0x0338, */ 0x0000000000000000UL, + /* 0x0340, */ 0x0000000000000000UL, + /* 0x0348, */ 0x0000000000000000UL, + /* 0x0350, */ 0x0000000000000000UL, +}; + +#endif /* QOS_INIT_G2M_V11_MSTAT195_H */ diff --git a/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11_mstat390.h b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11_mstat390.h new file mode 100644 index 000000000..5c6fd2492 --- /dev/null +++ b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11_mstat390.h @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QOS_INIT_G2M_V11_MSTAT390_H +#define QOS_INIT_G2M_V11_MSTAT390_H + +static uint64_t mstat_fix[] = { + /* 0x0000, */ 0x0000000000000000UL, + /* 0x0008, */ 0x0000000000000000UL, + /* 0x0010, */ 0x0000000000000000UL, + /* 0x0018, */ 0x0000000000000000UL, + /* 0x0020, */ 0x0000000000000000UL, + /* 0x0028, */ 0x0000000000000000UL, + /* 0x0030, */ 0x001008070000FFFFUL, + /* 0x0038, */ 0x001008070000FFFFUL, + /* 0x0040, */ 0x001424120000FFFFUL, + /* 0x0048, */ 0x0000000000000000UL, + /* 0x0050, */ 0x001404010000FFFFUL, + /* 0x0058, */ 0x001414130000FFFFUL, + /* 0x0060, */ 0x001414130000FFFFUL, + /* 0x0068, */ 0x0000000000000000UL, + /* 0x0070, */ 0x001404010000FFFFUL, + /* 0x0078, */ 0x001008050000FFFFUL, + /* 0x0080, */ 0x0000000000000000UL, + /* 0x0088, */ 0x001424120000FFFFUL, + /* 0x0090, */ 0x0014100D0000FFFFUL, + /* 0x0098, */ 0x0000000000000000UL, + /* 0x00a0, */ 0x000C08040000FFFFUL, + /* 0x00a8, */ 0x000C04020000FFFFUL, + /* 0x00b0, */ 0x000C04020000FFFFUL, + /* 0x00b8, */ 0x0000000000000000UL, + /* 0x00c0, */ 0x000C08040000FFFFUL, + /* 0x00c8, */ 0x000C04020000FFFFUL, + /* 0x00d0, */ 0x000C04020000FFFFUL, + /* 0x00d8, */ 0x000C0C0A0000FFFFUL, + /* 0x00e0, */ 0x000C24230000FFFFUL, + /* 0x00e8, */ 0x0000000000000000UL, + /* 0x00f0, */ 0x001044110000FFFFUL, + /* 0x00f8, */ 0x0000000000000000UL, + /* 0x0100, */ 0x0000000000000000UL, + /* 0x0108, */ 0x0000000000000000UL, + /* 0x0110, */ 0x001014110000FFFFUL, + /* 0x0118, */ 0x0000000000000000UL, + /* 0x0120, */ 0x0000000000000000UL, + /* 0x0128, */ 0x0000000000000000UL, + /* 0x0130, */ 0x0000000000000000UL, + /* 0x0138, */ 0x001018150000FFFFUL, + /* 0x0140, */ 0x0000000000000000UL, + /* 0x0148, */ 0x0000000000000000UL, + /* 0x0150, */ 0x00101C190000FFFFUL, + /* 0x0158, */ 0x0000000000000000UL, + /* 0x0160, */ 0x001018150000FFFFUL, + /* 0x0168, */ 0x0000000000000000UL, + /* 0x0170, */ 0x0000000000000000UL, + /* 0x0178, */ 0x00100C0B0000FFFFUL, + /* 0x0180, */ 0x0000000000000000UL, + /* 0x0188, */ 0x0000000000000000UL, + /* 0x0190, */ 0x001058570000FFFFUL, + /* 0x0198, */ 0x0000000000000000UL, + /* 0x01a0, */ 0x001018150000FFFFUL, + /* 0x01a8, */ 0x0000000000000000UL, + /* 0x01b0, */ 0x0000000000000000UL, + /* 0x01b8, */ 0x0000000000000000UL, + /* 0x01c0, */ 0x000C04010000FFFFUL, + /* 0x01c8, */ 0x000C04010000FFFFUL, + /* 0x01d0, */ 0x000C04010000FFFFUL, + /* 0x01d8, */ 0x000C04010000FFFFUL, + /* 0x01e0, */ 0x0000000000000000UL, + /* 0x01e8, */ 0x000C04010000FFFFUL, + /* 0x01f0, */ 0x000C04010000FFFFUL, + /* 0x01f8, */ 0x0000000000000000UL, + /* 0x0200, */ 0x0000000000000000UL, + /* 0x0208, */ 0x000C04010000FFFFUL, + /* 0x0210, */ 0x000C04010000FFFFUL, + /* 0x0218, */ 0x0000000000000000UL, + /* 0x0220, */ 0x0000000000000000UL, + /* 0x0228, */ 0x0000000000000000UL, + /* 0x0230, */ 0x0000000000000000UL, + /* 0x0238, */ 0x0000000000000000UL, + /* 0x0240, */ 0x0000000000000000UL, + /* 0x0248, */ 0x0000000000000000UL, + /* 0x0250, */ 0x0000000000000000UL, + /* 0x0258, */ 0x0000000000000000UL, + /* 0x0260, */ 0x000C0C030000FFFFUL, + /* 0x0268, */ 0x001410010000FFFFUL, + /* 0x0270, */ 0x001404010000FFFFUL, + /* 0x0278, */ 0x000C08020000FFFFUL, + /* 0x0280, */ 0x0000000000000000UL, + /* 0x0288, */ 0x0000000000000000UL, + /* 0x0290, */ 0x001410010000FFFFUL, + /* 0x0298, */ 0x001404010000FFFFUL, + /* 0x02a0, */ 0x000C04010000FFFFUL, + /* 0x02a8, */ 0x000C04010000FFFFUL, + /* 0x02b0, */ 0x00140C010000FFFFUL, + /* 0x02b8, */ 0x000C04010000FFFFUL, + /* 0x02c0, */ 0x0000000000000000UL, + /* 0x02c8, */ 0x0000000000000000UL, + /* 0x02d0, */ 0x000C04010000FFFFUL, + /* 0x02d8, */ 0x000C04010000FFFFUL, + /* 0x02e0, */ 0x00140C010000FFFFUL, + /* 0x02e8, */ 0x000C04010000FFFFUL, + /* 0x02f0, */ 0x0000000000000000UL, + /* 0x02f8, */ 0x0000000000000000UL, + /* 0x0300, */ 0x0000000000000000UL, + /* 0x0308, */ 0x0000000000000000UL, + /* 0x0310, */ 0x0000000000000000UL, + /* 0x0318, */ 0x0000000000000000UL, + /* 0x0320, */ 0x0000000000000000UL, + /* 0x0328, */ 0x0000000000000000UL, + /* 0x0330, */ 0x0000000000000000UL, + /* 0x0338, */ 0x0000000000000000UL, + /* 0x0340, */ 0x0000000000000000UL, + /* 0x0348, */ 0x0000000000000000UL, + /* 0x0350, */ 0x0000000000000000UL, +}; + +static uint64_t mstat_be[] = { + /* 0x0000, */ 0x0012003005EFFC01UL, + /* 0x0008, */ 0x0012003005EFFC01UL, + /* 0x0010, */ 0x0012003005EFFC01UL, + /* 0x0018, */ 0x0012003005EFFC01UL, + /* 0x0020, */ 0x0000000000000000UL, + /* 0x0028, */ 0x0012001005E03401UL, + /* 0x0030, */ 0x0000000000000000UL, + /* 0x0038, */ 0x0000000000000000UL, + /* 0x0040, */ 0x0000000000000000UL, + /* 0x0048, */ 0x0000000000000000UL, + /* 0x0050, */ 0x0000000000000000UL, + /* 0x0058, */ 0x0000000000000000UL, + /* 0x0060, */ 0x0000000000000000UL, + /* 0x0068, */ 0x0000000000000000UL, + /* 0x0070, */ 0x0000000000000000UL, + /* 0x0078, */ 0x0000000000000000UL, + /* 0x0080, */ 0x0000000000000000UL, + /* 0x0088, */ 0x0000000000000000UL, + /* 0x0090, */ 0x0000000000000000UL, + /* 0x0098, */ 0x0000000000000000UL, + /* 0x00a0, */ 0x0000000000000000UL, + /* 0x00a8, */ 0x0000000000000000UL, + /* 0x00b0, */ 0x0000000000000000UL, + /* 0x00b8, */ 0x0000000000000000UL, + /* 0x00c0, */ 0x0000000000000000UL, + /* 0x00c8, */ 0x0000000000000000UL, + /* 0x00d0, */ 0x0000000000000000UL, + /* 0x00d8, */ 0x0000000000000000UL, + /* 0x00e0, */ 0x0000000000000000UL, + /* 0x00e8, */ 0x0000000000000000UL, + /* 0x00f0, */ 0x0000000000000000UL, + /* 0x00f8, */ 0x0000000000000000UL, + /* 0x0100, */ 0x0000000000000000UL, + /* 0x0108, */ 0x0000000000000000UL, + /* 0x0110, */ 0x0000000000000000UL, + /* 0x0118, */ 0x0000000000000000UL, + /* 0x0120, */ 0x0000000000000000UL, + /* 0x0128, */ 0x0000000000000000UL, + /* 0x0130, */ 0x0000000000000000UL, + /* 0x0138, */ 0x0000000000000000UL, + /* 0x0140, */ 0x0000000000000000UL, + /* 0x0148, */ 0x0000000000000000UL, + /* 0x0150, */ 0x0000000000000000UL, + /* 0x0158, */ 0x0000000000000000UL, + /* 0x0160, */ 0x0000000000000000UL, + /* 0x0168, */ 0x0000000000000000UL, + /* 0x0170, */ 0x0000000000000000UL, + /* 0x0178, */ 0x0000000000000000UL, + /* 0x0180, */ 0x0000000000000000UL, + /* 0x0188, */ 0x0000000000000000UL, + /* 0x0190, */ 0x0000000000000000UL, + /* 0x0198, */ 0x0000000000000000UL, + /* 0x01a0, */ 0x0000000000000000UL, + /* 0x01a8, */ 0x0000000000000000UL, + /* 0x01b0, */ 0x0000000000000000UL, + /* 0x01b8, */ 0x0000000000000000UL, + /* 0x01c0, */ 0x002100B005EFFC01UL, + /* 0x01c8, */ 0x002100B005EFFC01UL, + /* 0x01d0, */ 0x002100B005EFFC01UL, + /* 0x01d8, */ 0x002100B005EFFC01UL, + /* 0x01e0, */ 0x0000000000000000UL, + /* 0x01e8, */ 0x0000000000000000UL, + /* 0x01f0, */ 0x0021003005EFFC01UL, + /* 0x01f8, */ 0x0000000000000000UL, + /* 0x0200, */ 0x0000000000000000UL, + /* 0x0208, */ 0x0000000000000000UL, + /* 0x0210, */ 0x0021003005EFFC01UL, + /* 0x0218, */ 0x0011003005EFFC01UL, + /* 0x0220, */ 0x0011003005EFFC01UL, + /* 0x0228, */ 0x0000000000000000UL, + /* 0x0230, */ 0x0011003005EFFC01UL, + /* 0x0238, */ 0x0011003005EFFC01UL, + /* 0x0240, */ 0x0012003005EFFC01UL, + /* 0x0248, */ 0x0011003005EFFC01UL, + /* 0x0250, */ 0x0012003005EFFC01UL, + /* 0x0258, */ 0x0011003005EFFC01UL, + /* 0x0260, */ 0x0000000000000000UL, + /* 0x0268, */ 0x0000000000000000UL, + /* 0x0270, */ 0x0000000000000000UL, + /* 0x0278, */ 0x0000000000000000UL, + /* 0x0280, */ 0x0000000000000000UL, + /* 0x0288, */ 0x0000000000000000UL, + /* 0x0290, */ 0x0000000000000000UL, + /* 0x0298, */ 0x0000000000000000UL, + /* 0x02a0, */ 0x0000000000000000UL, + /* 0x02a8, */ 0x0000000000000000UL, + /* 0x02b0, */ 0x0000000000000000UL, + /* 0x02b8, */ 0x0000000000000000UL, + /* 0x02c0, */ 0x0000000000000000UL, + /* 0x02c8, */ 0x0000000000000000UL, + /* 0x02d0, */ 0x0000000000000000UL, + /* 0x02d8, */ 0x0000000000000000UL, + /* 0x02e0, */ 0x0000000000000000UL, + /* 0x02e8, */ 0x0000000000000000UL, + /* 0x02f0, */ 0x0011007005EFFC01UL, + /* 0x02f8, */ 0x001100B005EFFC01UL, + /* 0x0300, */ 0x0000000000000000UL, + /* 0x0308, */ 0x0011007005EFFC01UL, + /* 0x0310, */ 0x001100B005EFFC01UL, + /* 0x0318, */ 0x0012001005E03401UL, + /* 0x0320, */ 0x0000000000000000UL, + /* 0x0328, */ 0x0000000000000000UL, + /* 0x0330, */ 0x0000000000000000UL, + /* 0x0338, */ 0x0000000000000000UL, + /* 0x0340, */ 0x0000000000000000UL, + /* 0x0348, */ 0x0000000000000000UL, + /* 0x0350, */ 0x0000000000000000UL, +}; + +#endif /* QOS_INIT_G2M_V11_MSTAT390_H */ diff --git a/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11_qoswt195.h b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11_qoswt195.h new file mode 100644 index 000000000..f526a82e7 --- /dev/null +++ b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11_qoswt195.h @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QOS_INIT_G2M_V11_QOSWT195_H +#define QOS_INIT_G2M_V11_QOSWT195_H + +static uint64_t qoswt_fix[] = { + /* 0x0000, */ 0x0000000000000000UL, + /* 0x0008, */ 0x0000000000000000UL, + /* 0x0010, */ 0x0000000000000000UL, + /* 0x0018, */ 0x0000000000000000UL, + /* 0x0020, */ 0x0000000000000000UL, + /* 0x0028, */ 0x0000000000000000UL, + /* 0x0030, */ 0x001004040000C010UL, + /* 0x0038, */ 0x001004040000C010UL, + /* 0x0040, */ 0x001414090000FFF0UL, + /* 0x0048, */ 0x0000000000000000UL, + /* 0x0050, */ 0x0000000000000000UL, + /* 0x0058, */ 0x00140C0A0000C010UL, + /* 0x0060, */ 0x00140C0A0000C010UL, + /* 0x0068, */ 0x0000000000000000UL, + /* 0x0070, */ 0x0000000000000000UL, + /* 0x0078, */ 0x001004030000C010UL, + /* 0x0080, */ 0x0000000000000000UL, + /* 0x0088, */ 0x001414090000FFF0UL, + /* 0x0090, */ 0x001408070000C010UL, + /* 0x0098, */ 0x0000000000000000UL, + /* 0x00a0, */ 0x0000000000000000UL, + /* 0x00a8, */ 0x0000000000000000UL, + /* 0x00b0, */ 0x0000000000000000UL, + /* 0x00b8, */ 0x0000000000000000UL, + /* 0x00c0, */ 0x0000000000000000UL, + /* 0x00c8, */ 0x0000000000000000UL, + /* 0x00d0, */ 0x0000000000000000UL, + /* 0x00d8, */ 0x0000000000000000UL, + /* 0x00e0, */ 0x0000000000000000UL, + /* 0x00e8, */ 0x0000000000000000UL, + /* 0x00f0, */ 0x0000000000000000UL, + /* 0x00f8, */ 0x0000000000000000UL, + /* 0x0100, */ 0x0000000000000000UL, + /* 0x0108, */ 0x0000000000000000UL, + /* 0x0110, */ 0x0000000000000000UL, + /* 0x0118, */ 0x0000000000000000UL, + /* 0x0120, */ 0x0000000000000000UL, + /* 0x0128, */ 0x0000000000000000UL, + /* 0x0130, */ 0x0000000000000000UL, + /* 0x0138, */ 0x0000000000000000UL, + /* 0x0140, */ 0x0000000000000000UL, + /* 0x0148, */ 0x0000000000000000UL, + /* 0x0150, */ 0x0000000000000000UL, + /* 0x0158, */ 0x0000000000000000UL, + /* 0x0160, */ 0x0000000000000000UL, + /* 0x0168, */ 0x0000000000000000UL, + /* 0x0170, */ 0x0000000000000000UL, + /* 0x0178, */ 0x0000000000000000UL, + /* 0x0180, */ 0x0000000000000000UL, + /* 0x0188, */ 0x0000000000000000UL, + /* 0x0190, */ 0x0000000000000000UL, + /* 0x0198, */ 0x0000000000000000UL, + /* 0x01a0, */ 0x0000000000000000UL, + /* 0x01a8, */ 0x0000000000000000UL, + /* 0x01b0, */ 0x0000000000000000UL, + /* 0x01b8, */ 0x0000000000000000UL, + /* 0x01c0, */ 0x0000000000000000UL, + /* 0x01c8, */ 0x0000000000000000UL, + /* 0x01d0, */ 0x0000000000000000UL, + /* 0x01d8, */ 0x0000000000000000UL, + /* 0x01e0, */ 0x0000000000000000UL, + /* 0x01e8, */ 0x0000000000000000UL, + /* 0x01f0, */ 0x0000000000000000UL, + /* 0x01f8, */ 0x0000000000000000UL, + /* 0x0200, */ 0x0000000000000000UL, + /* 0x0208, */ 0x0000000000000000UL, + /* 0x0210, */ 0x0000000000000000UL, + /* 0x0218, */ 0x0000000000000000UL, + /* 0x0220, */ 0x0000000000000000UL, + /* 0x0228, */ 0x0000000000000000UL, + /* 0x0230, */ 0x0000000000000000UL, + /* 0x0238, */ 0x0000000000000000UL, + /* 0x0240, */ 0x0000000000000000UL, + /* 0x0248, */ 0x0000000000000000UL, + /* 0x0250, */ 0x0000000000000000UL, + /* 0x0258, */ 0x0000000000000000UL, + /* 0x0260, */ 0x000C08020000FFF0UL, + /* 0x0268, */ 0x001408010000FFF0UL, + /* 0x0270, */ 0x001404010000FFF0UL, + /* 0x0278, */ 0x000C04010000FFF0UL, + /* 0x0280, */ 0x0000000000000000UL, + /* 0x0288, */ 0x0000000000000000UL, + /* 0x0290, */ 0x001408010000FFF0UL, + /* 0x0298, */ 0x001404010000FFF0UL, + /* 0x02a0, */ 0x0000000000000000UL, + /* 0x02a8, */ 0x0000000000000000UL, + /* 0x02b0, */ 0x0000000000000000UL, + /* 0x02b8, */ 0x0000000000000000UL, + /* 0x02c0, */ 0x0000000000000000UL, + /* 0x02c8, */ 0x0000000000000000UL, + /* 0x02d0, */ 0x0000000000000000UL, + /* 0x02d8, */ 0x0000000000000000UL, + /* 0x02e0, */ 0x0000000000000000UL, + /* 0x02e8, */ 0x0000000000000000UL, + /* 0x02f0, */ 0x0000000000000000UL, + /* 0x02f8, */ 0x0000000000000000UL, + /* 0x0300, */ 0x0000000000000000UL, + /* 0x0308, */ 0x0000000000000000UL, + /* 0x0310, */ 0x0000000000000000UL, + /* 0x0318, */ 0x0000000000000000UL, + /* 0x0320, */ 0x0000000000000000UL, + /* 0x0328, */ 0x0000000000000000UL, + /* 0x0330, */ 0x0000000000000000UL, + /* 0x0338, */ 0x0000000000000000UL, + /* 0x0340, */ 0x0000000000000000UL, + /* 0x0348, */ 0x0000000000000000UL, + /* 0x0350, */ 0x0000000000000000UL, +}; + +static uint64_t qoswt_be[] = { + /* 0x0000, */ 0x0000000000000000UL, + /* 0x0008, */ 0x0000000000000000UL, + /* 0x0010, */ 0x0000000000000000UL, + /* 0x0018, */ 0x0000000000000000UL, + /* 0x0020, */ 0x0000000000000000UL, + /* 0x0028, */ 0x0000000000000000UL, + /* 0x0030, */ 0x0000000000000000UL, + /* 0x0038, */ 0x0000000000000000UL, + /* 0x0040, */ 0x0000000000000000UL, + /* 0x0048, */ 0x0000000000000000UL, + /* 0x0050, */ 0x0000000000000000UL, + /* 0x0058, */ 0x0000000000000000UL, + /* 0x0060, */ 0x0000000000000000UL, + /* 0x0068, */ 0x0000000000000000UL, + /* 0x0070, */ 0x0000000000000000UL, + /* 0x0078, */ 0x0000000000000000UL, + /* 0x0080, */ 0x0000000000000000UL, + /* 0x0088, */ 0x0000000000000000UL, + /* 0x0090, */ 0x0000000000000000UL, + /* 0x0098, */ 0x0000000000000000UL, + /* 0x00a0, */ 0x0000000000000000UL, + /* 0x00a8, */ 0x0000000000000000UL, + /* 0x00b0, */ 0x0000000000000000UL, + /* 0x00b8, */ 0x0000000000000000UL, + /* 0x00c0, */ 0x0000000000000000UL, + /* 0x00c8, */ 0x0000000000000000UL, + /* 0x00d0, */ 0x0000000000000000UL, + /* 0x00d8, */ 0x0000000000000000UL, + /* 0x00e0, */ 0x0000000000000000UL, + /* 0x00e8, */ 0x0000000000000000UL, + /* 0x00f0, */ 0x0000000000000000UL, + /* 0x00f8, */ 0x0000000000000000UL, + /* 0x0100, */ 0x0000000000000000UL, + /* 0x0108, */ 0x0000000000000000UL, + /* 0x0110, */ 0x0000000000000000UL, + /* 0x0118, */ 0x0000000000000000UL, + /* 0x0120, */ 0x0000000000000000UL, + /* 0x0128, */ 0x0000000000000000UL, + /* 0x0130, */ 0x0000000000000000UL, + /* 0x0138, */ 0x0000000000000000UL, + /* 0x0140, */ 0x0000000000000000UL, + /* 0x0148, */ 0x0000000000000000UL, + /* 0x0150, */ 0x0000000000000000UL, + /* 0x0158, */ 0x0000000000000000UL, + /* 0x0160, */ 0x0000000000000000UL, + /* 0x0168, */ 0x0000000000000000UL, + /* 0x0170, */ 0x0000000000000000UL, + /* 0x0178, */ 0x0000000000000000UL, + /* 0x0180, */ 0x0000000000000000UL, + /* 0x0188, */ 0x0000000000000000UL, + /* 0x0190, */ 0x0000000000000000UL, + /* 0x0198, */ 0x0000000000000000UL, + /* 0x01a0, */ 0x0000000000000000UL, + /* 0x01a8, */ 0x0000000000000000UL, + /* 0x01b0, */ 0x0000000000000000UL, + /* 0x01b8, */ 0x0000000000000000UL, + /* 0x01c0, */ 0x0000000000000000UL, + /* 0x01c8, */ 0x0000000000000000UL, + /* 0x01d0, */ 0x0000000000000000UL, + /* 0x01d8, */ 0x0000000000000000UL, + /* 0x01e0, */ 0x0000000000000000UL, + /* 0x01e8, */ 0x0000000000000000UL, + /* 0x01f0, */ 0x0000000000000000UL, + /* 0x01f8, */ 0x0000000000000000UL, + /* 0x0200, */ 0x0000000000000000UL, + /* 0x0208, */ 0x0000000000000000UL, + /* 0x0210, */ 0x0000000000000000UL, + /* 0x0218, */ 0x0000000000000000UL, + /* 0x0220, */ 0x0000000000000000UL, + /* 0x0228, */ 0x0000000000000000UL, + /* 0x0230, */ 0x0000000000000000UL, + /* 0x0238, */ 0x0000000000000000UL, + /* 0x0240, */ 0x0000000000000000UL, + /* 0x0248, */ 0x0000000000000000UL, + /* 0x0250, */ 0x0000000000000000UL, + /* 0x0258, */ 0x0000000000000000UL, + /* 0x0260, */ 0x0000000000000000UL, + /* 0x0268, */ 0x0000000000000000UL, + /* 0x0270, */ 0x0000000000000000UL, + /* 0x0278, */ 0x0000000000000000UL, + /* 0x0280, */ 0x0000000000000000UL, + /* 0x0288, */ 0x0000000000000000UL, + /* 0x0290, */ 0x0000000000000000UL, + /* 0x0298, */ 0x0000000000000000UL, + /* 0x02a0, */ 0x0000000000000000UL, + /* 0x02a8, */ 0x0000000000000000UL, + /* 0x02b0, */ 0x0000000000000000UL, + /* 0x02b8, */ 0x0000000000000000UL, + /* 0x02c0, */ 0x0000000000000000UL, + /* 0x02c8, */ 0x0000000000000000UL, + /* 0x02d0, */ 0x0000000000000000UL, + /* 0x02d8, */ 0x0000000000000000UL, + /* 0x02e0, */ 0x0000000000000000UL, + /* 0x02e8, */ 0x0000000000000000UL, + /* 0x02f0, */ 0x0000000000000000UL, + /* 0x02f8, */ 0x0000000000000000UL, + /* 0x0300, */ 0x0000000000000000UL, + /* 0x0308, */ 0x0000000000000000UL, + /* 0x0310, */ 0x0000000000000000UL, + /* 0x0318, */ 0x0000000000000000UL, + /* 0x0320, */ 0x0000000000000000UL, + /* 0x0328, */ 0x0000000000000000UL, + /* 0x0330, */ 0x0000000000000000UL, + /* 0x0338, */ 0x0000000000000000UL, + /* 0x0340, */ 0x0000000000000000UL, + /* 0x0348, */ 0x0000000000000000UL, + /* 0x0350, */ 0x0000000000000000UL, +}; + +#endif /* QOS_INIT_G2M_V11_QOSWT195_H */ diff --git a/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11_qoswt390.h b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11_qoswt390.h new file mode 100644 index 000000000..bfb80e393 --- /dev/null +++ b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11_qoswt390.h @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QOS_INIT_G2M_V11_QOSWT390_H +#define QOS_INIT_G2M_V11_QOSWT390_H + +static uint64_t qoswt_fix[] = { + /* 0x0000, */ 0x0000000000000000UL, + /* 0x0008, */ 0x0000000000000000UL, + /* 0x0010, */ 0x0000000000000000UL, + /* 0x0018, */ 0x0000000000000000UL, + /* 0x0020, */ 0x0000000000000000UL, + /* 0x0028, */ 0x0000000000000000UL, + /* 0x0030, */ 0x001008070000C010UL, + /* 0x0038, */ 0x001008070000C010UL, + /* 0x0040, */ 0x001424120000FFF0UL, + /* 0x0048, */ 0x0000000000000000UL, + /* 0x0050, */ 0x0000000000000000UL, + /* 0x0058, */ 0x001414130000C010UL, + /* 0x0060, */ 0x001414130000C010UL, + /* 0x0068, */ 0x0000000000000000UL, + /* 0x0070, */ 0x0000000000000000UL, + /* 0x0078, */ 0x001008050000C010UL, + /* 0x0080, */ 0x0000000000000000UL, + /* 0x0088, */ 0x001424120000FFF0UL, + /* 0x0090, */ 0x0014100D0000C010UL, + /* 0x0098, */ 0x0000000000000000UL, + /* 0x00a0, */ 0x0000000000000000UL, + /* 0x00a8, */ 0x0000000000000000UL, + /* 0x00b0, */ 0x0000000000000000UL, + /* 0x00b8, */ 0x0000000000000000UL, + /* 0x00c0, */ 0x0000000000000000UL, + /* 0x00c8, */ 0x0000000000000000UL, + /* 0x00d0, */ 0x0000000000000000UL, + /* 0x00d8, */ 0x0000000000000000UL, + /* 0x00e0, */ 0x0000000000000000UL, + /* 0x00e8, */ 0x0000000000000000UL, + /* 0x00f0, */ 0x0000000000000000UL, + /* 0x00f8, */ 0x0000000000000000UL, + /* 0x0100, */ 0x0000000000000000UL, + /* 0x0108, */ 0x0000000000000000UL, + /* 0x0110, */ 0x0000000000000000UL, + /* 0x0118, */ 0x0000000000000000UL, + /* 0x0120, */ 0x0000000000000000UL, + /* 0x0128, */ 0x0000000000000000UL, + /* 0x0130, */ 0x0000000000000000UL, + /* 0x0138, */ 0x0000000000000000UL, + /* 0x0140, */ 0x0000000000000000UL, + /* 0x0148, */ 0x0000000000000000UL, + /* 0x0150, */ 0x0000000000000000UL, + /* 0x0158, */ 0x0000000000000000UL, + /* 0x0160, */ 0x0000000000000000UL, + /* 0x0168, */ 0x0000000000000000UL, + /* 0x0170, */ 0x0000000000000000UL, + /* 0x0178, */ 0x0000000000000000UL, + /* 0x0180, */ 0x0000000000000000UL, + /* 0x0188, */ 0x0000000000000000UL, + /* 0x0190, */ 0x0000000000000000UL, + /* 0x0198, */ 0x0000000000000000UL, + /* 0x01a0, */ 0x0000000000000000UL, + /* 0x01a8, */ 0x0000000000000000UL, + /* 0x01b0, */ 0x0000000000000000UL, + /* 0x01b8, */ 0x0000000000000000UL, + /* 0x01c0, */ 0x0000000000000000UL, + /* 0x01c8, */ 0x0000000000000000UL, + /* 0x01d0, */ 0x0000000000000000UL, + /* 0x01d8, */ 0x0000000000000000UL, + /* 0x01e0, */ 0x0000000000000000UL, + /* 0x01e8, */ 0x0000000000000000UL, + /* 0x01f0, */ 0x0000000000000000UL, + /* 0x01f8, */ 0x0000000000000000UL, + /* 0x0200, */ 0x0000000000000000UL, + /* 0x0208, */ 0x0000000000000000UL, + /* 0x0210, */ 0x0000000000000000UL, + /* 0x0218, */ 0x0000000000000000UL, + /* 0x0220, */ 0x0000000000000000UL, + /* 0x0228, */ 0x0000000000000000UL, + /* 0x0230, */ 0x0000000000000000UL, + /* 0x0238, */ 0x0000000000000000UL, + /* 0x0240, */ 0x0000000000000000UL, + /* 0x0248, */ 0x0000000000000000UL, + /* 0x0250, */ 0x0000000000000000UL, + /* 0x0258, */ 0x0000000000000000UL, + /* 0x0260, */ 0x000C0C030000FFF0UL, + /* 0x0268, */ 0x001410010000FFF0UL, + /* 0x0270, */ 0x001404010000FFF0UL, + /* 0x0278, */ 0x000C08020000FFF0UL, + /* 0x0280, */ 0x0000000000000000UL, + /* 0x0288, */ 0x0000000000000000UL, + /* 0x0290, */ 0x001410010000FFF0UL, + /* 0x0298, */ 0x001404010000FFF0UL, + /* 0x02a0, */ 0x0000000000000000UL, + /* 0x02a8, */ 0x0000000000000000UL, + /* 0x02b0, */ 0x0000000000000000UL, + /* 0x02b8, */ 0x0000000000000000UL, + /* 0x02c0, */ 0x0000000000000000UL, + /* 0x02c8, */ 0x0000000000000000UL, + /* 0x02d0, */ 0x0000000000000000UL, + /* 0x02d8, */ 0x0000000000000000UL, + /* 0x02e0, */ 0x0000000000000000UL, + /* 0x02e8, */ 0x0000000000000000UL, + /* 0x02f0, */ 0x0000000000000000UL, + /* 0x02f8, */ 0x0000000000000000UL, + /* 0x0300, */ 0x0000000000000000UL, + /* 0x0308, */ 0x0000000000000000UL, + /* 0x0310, */ 0x0000000000000000UL, + /* 0x0318, */ 0x0000000000000000UL, + /* 0x0320, */ 0x0000000000000000UL, + /* 0x0328, */ 0x0000000000000000UL, + /* 0x0330, */ 0x0000000000000000UL, + /* 0x0338, */ 0x0000000000000000UL, + /* 0x0340, */ 0x0000000000000000UL, + /* 0x0348, */ 0x0000000000000000UL, + /* 0x0350, */ 0x0000000000000000UL, +}; + +static uint64_t qoswt_be[] = { + /* 0x0000, */ 0x0000000000000000UL, + /* 0x0008, */ 0x0000000000000000UL, + /* 0x0010, */ 0x0000000000000000UL, + /* 0x0018, */ 0x0000000000000000UL, + /* 0x0020, */ 0x0000000000000000UL, + /* 0x0028, */ 0x0000000000000000UL, + /* 0x0030, */ 0x0000000000000000UL, + /* 0x0038, */ 0x0000000000000000UL, + /* 0x0040, */ 0x0000000000000000UL, + /* 0x0048, */ 0x0000000000000000UL, + /* 0x0050, */ 0x0000000000000000UL, + /* 0x0058, */ 0x0000000000000000UL, + /* 0x0060, */ 0x0000000000000000UL, + /* 0x0068, */ 0x0000000000000000UL, + /* 0x0070, */ 0x0000000000000000UL, + /* 0x0078, */ 0x0000000000000000UL, + /* 0x0080, */ 0x0000000000000000UL, + /* 0x0088, */ 0x0000000000000000UL, + /* 0x0090, */ 0x0000000000000000UL, + /* 0x0098, */ 0x0000000000000000UL, + /* 0x00a0, */ 0x0000000000000000UL, + /* 0x00a8, */ 0x0000000000000000UL, + /* 0x00b0, */ 0x0000000000000000UL, + /* 0x00b8, */ 0x0000000000000000UL, + /* 0x00c0, */ 0x0000000000000000UL, + /* 0x00c8, */ 0x0000000000000000UL, + /* 0x00d0, */ 0x0000000000000000UL, + /* 0x00d8, */ 0x0000000000000000UL, + /* 0x00e0, */ 0x0000000000000000UL, + /* 0x00e8, */ 0x0000000000000000UL, + /* 0x00f0, */ 0x0000000000000000UL, + /* 0x00f8, */ 0x0000000000000000UL, + /* 0x0100, */ 0x0000000000000000UL, + /* 0x0108, */ 0x0000000000000000UL, + /* 0x0110, */ 0x0000000000000000UL, + /* 0x0118, */ 0x0000000000000000UL, + /* 0x0120, */ 0x0000000000000000UL, + /* 0x0128, */ 0x0000000000000000UL, + /* 0x0130, */ 0x0000000000000000UL, + /* 0x0138, */ 0x0000000000000000UL, + /* 0x0140, */ 0x0000000000000000UL, + /* 0x0148, */ 0x0000000000000000UL, + /* 0x0150, */ 0x0000000000000000UL, + /* 0x0158, */ 0x0000000000000000UL, + /* 0x0160, */ 0x0000000000000000UL, + /* 0x0168, */ 0x0000000000000000UL, + /* 0x0170, */ 0x0000000000000000UL, + /* 0x0178, */ 0x0000000000000000UL, + /* 0x0180, */ 0x0000000000000000UL, + /* 0x0188, */ 0x0000000000000000UL, + /* 0x0190, */ 0x0000000000000000UL, + /* 0x0198, */ 0x0000000000000000UL, + /* 0x01a0, */ 0x0000000000000000UL, + /* 0x01a8, */ 0x0000000000000000UL, + /* 0x01b0, */ 0x0000000000000000UL, + /* 0x01b8, */ 0x0000000000000000UL, + /* 0x01c0, */ 0x0000000000000000UL, + /* 0x01c8, */ 0x0000000000000000UL, + /* 0x01d0, */ 0x0000000000000000UL, + /* 0x01d8, */ 0x0000000000000000UL, + /* 0x01e0, */ 0x0000000000000000UL, + /* 0x01e8, */ 0x0000000000000000UL, + /* 0x01f0, */ 0x0000000000000000UL, + /* 0x01f8, */ 0x0000000000000000UL, + /* 0x0200, */ 0x0000000000000000UL, + /* 0x0208, */ 0x0000000000000000UL, + /* 0x0210, */ 0x0000000000000000UL, + /* 0x0218, */ 0x0000000000000000UL, + /* 0x0220, */ 0x0000000000000000UL, + /* 0x0228, */ 0x0000000000000000UL, + /* 0x0230, */ 0x0000000000000000UL, + /* 0x0238, */ 0x0000000000000000UL, + /* 0x0240, */ 0x0000000000000000UL, + /* 0x0248, */ 0x0000000000000000UL, + /* 0x0250, */ 0x0000000000000000UL, + /* 0x0258, */ 0x0000000000000000UL, + /* 0x0260, */ 0x0000000000000000UL, + /* 0x0268, */ 0x0000000000000000UL, + /* 0x0270, */ 0x0000000000000000UL, + /* 0x0278, */ 0x0000000000000000UL, + /* 0x0280, */ 0x0000000000000000UL, + /* 0x0288, */ 0x0000000000000000UL, + /* 0x0290, */ 0x0000000000000000UL, + /* 0x0298, */ 0x0000000000000000UL, + /* 0x02a0, */ 0x0000000000000000UL, + /* 0x02a8, */ 0x0000000000000000UL, + /* 0x02b0, */ 0x0000000000000000UL, + /* 0x02b8, */ 0x0000000000000000UL, + /* 0x02c0, */ 0x0000000000000000UL, + /* 0x02c8, */ 0x0000000000000000UL, + /* 0x02d0, */ 0x0000000000000000UL, + /* 0x02d8, */ 0x0000000000000000UL, + /* 0x02e0, */ 0x0000000000000000UL, + /* 0x02e8, */ 0x0000000000000000UL, + /* 0x02f0, */ 0x0000000000000000UL, + /* 0x02f8, */ 0x0000000000000000UL, + /* 0x0300, */ 0x0000000000000000UL, + /* 0x0308, */ 0x0000000000000000UL, + /* 0x0310, */ 0x0000000000000000UL, + /* 0x0318, */ 0x0000000000000000UL, + /* 0x0320, */ 0x0000000000000000UL, + /* 0x0328, */ 0x0000000000000000UL, + /* 0x0330, */ 0x0000000000000000UL, + /* 0x0338, */ 0x0000000000000000UL, + /* 0x0340, */ 0x0000000000000000UL, + /* 0x0348, */ 0x0000000000000000UL, + /* 0x0350, */ 0x0000000000000000UL, +}; + +#endif /* QOS_INIT_G2M_V11_QOSWT390_H */ diff --git a/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30.c b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30.c new file mode 100644 index 000000000..321cd2bf8 --- /dev/null +++ b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30.c @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2021, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include + +#include "../qos_common.h" +#include "qos_init_g2m_v30.h" +#if RCAR_QOS_TYPE == RCAR_QOS_TYPE_DEFAULT +#if RCAR_REF_INT == RCAR_REF_DEFAULT +#include "qos_init_g2m_v30_mstat195.h" +#else /* RCAR_REF_INT == RCAR_REF_DEFAULT */ +#include "qos_init_g2m_v30_mstat390.h" +#endif /* RCAR_REF_INT == RCAR_REF_DEFAULT */ +#if RCAR_REWT_TRAINING != RCAR_REWT_TRAINING_DISABLE +#if RCAR_REF_INT == RCAR_REF_DEFAULT +#include "qos_init_g2m_v30_qoswt195.h" +#else /* RCAR_REF_INT == RCAR_REF_DEFAULT */ +#include "qos_init_g2m_v30_qoswt390.h" +#endif /* RCAR_REF_INT == RCAR_REF_DEFAULT */ +#endif /* RCAR_REWT_TRAINING != RCAR_REWT_TRAINING_DISABLE */ +#endif /* RCAR_QOS_TYPE == RCAR_QOS_TYPE_DEFAULT */ +#include "qos_reg.h" + +#define RCAR_QOS_VERSION "rev.0.04" + +#define QOSWT_TIME_BANK0 20000000U /* unit:ns */ + +#define QOSWT_WTEN_ENABLE 0x1U + +#define QOSCTRL_REF_ARS_ARBSTOPCYCLE_G2M_30 (SL_INIT_SSLOTCLK_G2M_30 - 0x5U) + +#define OSWT_WTREF_SLOT0_EN_REQ1_SLOT 3U +#define OSWT_WTREF_SLOT0_EN_REQ2_SLOT 9U +#define QOSWT_WTREF_SLOT0_EN \ + ((0x1U << OSWT_WTREF_SLOT0_EN_REQ1_SLOT) | \ + (0x1U << OSWT_WTREF_SLOT0_EN_REQ2_SLOT)) +#define QOSWT_WTREF_SLOT1_EN \ + ((0x1U << OSWT_WTREF_SLOT0_EN_REQ1_SLOT) | \ + (0x1U << OSWT_WTREF_SLOT0_EN_REQ2_SLOT)) + +#define QOSWT_WTSET0_REQ_SSLOT0 5U +#define WT_BASE_SUB_SLOT_NUM0 12U +#define QOSWT_WTSET0_PERIOD0_G2M_30 \ + ((QOSWT_TIME_BANK0 / QOSWT_WTSET0_CYCLE_G2M_30) - 1U) +#define QOSWT_WTSET0_SSLOT0 (QOSWT_WTSET0_REQ_SSLOT0 - 1U) +#define QOSWT_WTSET0_SLOTSLOT0 (WT_BASE_SUB_SLOT_NUM0 - 1U) + +#define QOSWT_WTSET1_PERIOD1_G2M_30 \ + ((QOSWT_TIME_BANK0 / QOSWT_WTSET0_CYCLE_G2M_30) - 1U) +#define QOSWT_WTSET1_SSLOT1 (QOSWT_WTSET0_REQ_SSLOT0 - 1U) +#define QOSWT_WTSET1_SLOTSLOT1 (WT_BASE_SUB_SLOT_NUM0 - 1U) + +static const struct rcar_gen3_dbsc_qos_settings g2m_v30_qos[] = { + /* BUFCAM settings */ + { DBSC_DBCAM0CNF1, 0x00043218U }, + { DBSC_DBCAM0CNF2, 0x000000F4U }, + { DBSC_DBCAM0CNF3, 0x00000000U }, + { DBSC_DBSCHCNT0, 0x000F0037U }, + { DBSC_DBSCHSZ0, 0x00000001U }, + { DBSC_DBSCHRW0, 0x22421111U }, + + /* DDR3 */ + { DBSC_SCFCTST2, 0x012F1123U }, + + /* QoS settings */ + { DBSC_DBSCHQOS00, 0x00000F00U }, + { DBSC_DBSCHQOS01, 0x00000B00U }, + { DBSC_DBSCHQOS02, 0x00000000U }, + { DBSC_DBSCHQOS03, 0x00000000U }, + { DBSC_DBSCHQOS40, 0x00000300U }, + { DBSC_DBSCHQOS41, 0x000002F0U }, + { DBSC_DBSCHQOS42, 0x00000200U }, + { DBSC_DBSCHQOS43, 0x00000100U }, + { DBSC_DBSCHQOS90, 0x00000100U }, + { DBSC_DBSCHQOS91, 0x000000F0U }, + { DBSC_DBSCHQOS92, 0x000000A0U }, + { DBSC_DBSCHQOS93, 0x00000040U }, + { DBSC_DBSCHQOS120, 0x00000040U }, + { DBSC_DBSCHQOS121, 0x00000030U }, + { DBSC_DBSCHQOS122, 0x00000020U }, + { DBSC_DBSCHQOS123, 0x00000010U }, + { DBSC_DBSCHQOS130, 0x00000100U }, + { DBSC_DBSCHQOS131, 0x000000F0U }, + { DBSC_DBSCHQOS132, 0x000000A0U }, + { DBSC_DBSCHQOS133, 0x00000040U }, + { DBSC_DBSCHQOS140, 0x000000C0U }, + { DBSC_DBSCHQOS141, 0x000000B0U }, + { DBSC_DBSCHQOS142, 0x00000080U }, + { DBSC_DBSCHQOS143, 0x00000040U }, + { DBSC_DBSCHQOS150, 0x00000040U }, + { DBSC_DBSCHQOS151, 0x00000030U }, + { DBSC_DBSCHQOS152, 0x00000020U }, + { DBSC_DBSCHQOS153, 0x00000010U }, +}; + +void qos_init_g2m_v30(void) +{ + uint32_t i; + + rzg_qos_dbsc_setting(g2m_v30_qos, ARRAY_SIZE(g2m_v30_qos), true); + + /* DRAM Split Address mapping */ +#if RCAR_DRAM_SPLIT == RCAR_DRAM_SPLIT_4CH +#if RCAR_LSI == RZ_G2M + #error "Don't set DRAM Split 4ch(G2M)" +#else /* RCAR_LSI == RZ_G2M */ + ERROR("DRAM Split 4ch not supported.(G2M)"); + panic(); +#endif /* RCAR_LSI == RZ_G2M */ +#elif (RCAR_DRAM_SPLIT == RCAR_DRAM_SPLIT_2CH) || \ + (RCAR_DRAM_SPLIT == RCAR_DRAM_SPLIT_AUTO) + NOTICE("BL2: DRAM Split is 2ch\n"); + mmio_write_32(AXI_ADSPLCR0, 0x00000000U); + mmio_write_32(AXI_ADSPLCR1, ADSPLCR0_ADRMODE_DEFAULT | + ADSPLCR0_SPLITSEL(0xFFU) | ADSPLCR0_AREA(0x1DU) | + ADSPLCR0_SWP); + mmio_write_32(AXI_ADSPLCR2, 0x00001004U); + mmio_write_32(AXI_ADSPLCR3, 0x00000000U); +#else /* RCAR_DRAM_SPLIT == RCAR_DRAM_SPLIT_4CH */ + NOTICE("BL2: DRAM Split is OFF\n"); +#endif /* RCAR_DRAM_SPLIT == RCAR_DRAM_SPLIT_4CH */ + +#if !(RCAR_QOS_TYPE == RCAR_QOS_NONE) +#if RCAR_QOS_TYPE == RCAR_QOS_TYPE_DEFAULT + NOTICE("BL2: QoS is default setting(%s)\n", RCAR_QOS_VERSION); +#endif + +#if RCAR_REF_INT == RCAR_REF_DEFAULT + NOTICE("BL2: DRAM refresh interval 1.95 usec\n"); +#else /* RCAR_REF_INT == RCAR_REF_DEFAULT */ + NOTICE("BL2: DRAM refresh interval 3.9 usec\n"); +#endif /* RCAR_REF_INT == RCAR_REF_DEFAULT */ + +#if RCAR_REWT_TRAINING != RCAR_REWT_TRAINING_DISABLE + NOTICE("BL2: Periodic Write DQ Training\n"); +#endif /* RCAR_REWT_TRAINING != RCAR_REWT_TRAINING_DISABLE */ + + mmio_write_32(QOSCTRL_RAS, 0x00000044U); + mmio_write_64(QOSCTRL_DANN, 0x0404020002020201UL); + mmio_write_32(QOSCTRL_DANT, 0x0020100AU); + mmio_write_32(QOSCTRL_FSS, 0x0000000AU); + mmio_write_32(QOSCTRL_INSFC, 0x06330001U); + mmio_write_32(QOSCTRL_EARLYR, 0x00000001U); + mmio_write_32(QOSCTRL_RACNT0, 0x02010003U); /* GPU Boost Mode ON */ + + /* GPU Boost Mode */ + mmio_write_32(QOSCTRL_STATGEN0, 0x00000001U); + + mmio_write_32(QOSCTRL_SL_INIT, + SL_INIT_REFFSSLOT | SL_INIT_SLOTSSLOT | + SL_INIT_SSLOTCLK_G2M_30); + mmio_write_32(QOSCTRL_REF_ARS, + QOSCTRL_REF_ARS_ARBSTOPCYCLE_G2M_30 << 16); + + for (i = 0U; i < ARRAY_SIZE(mstat_fix); i++) { + mmio_write_64(QOSBW_FIX_QOS_BANK0 + i * 8U, mstat_fix[i]); + mmio_write_64(QOSBW_FIX_QOS_BANK1 + i * 8U, mstat_fix[i]); + } + for (i = 0U; i < ARRAY_SIZE(mstat_be); i++) { + mmio_write_64(QOSBW_BE_QOS_BANK0 + i * 8U, mstat_be[i]); + mmio_write_64(QOSBW_BE_QOS_BANK1 + i * 8U, mstat_be[i]); + } +#if RCAR_REWT_TRAINING != RCAR_REWT_TRAINING_DISABLE + for (i = 0U; i < ARRAY_SIZE(qoswt_fix); i++) { + mmio_write_64(QOSWT_FIX_WTQOS_BANK0 + i * 8U, qoswt_fix[i]); + mmio_write_64(QOSWT_FIX_WTQOS_BANK1 + i * 8U, qoswt_fix[i]); + } + for (i = 0U; i < ARRAY_SIZE(qoswt_be); i++) { + mmio_write_64(QOSWT_BE_WTQOS_BANK0 + i * 8U, qoswt_be[i]); + mmio_write_64(QOSWT_BE_WTQOS_BANK1 + i * 8U, qoswt_be[i]); + } +#endif /* RCAR_REWT_TRAINING != RCAR_REWT_TRAINING_DISABLE */ + + /* RT bus Leaf setting */ + mmio_write_32(RT_ACT0, 0x00000000U); + mmio_write_32(RT_ACT1, 0x00000000U); + + /* CCI bus Leaf setting */ + mmio_write_32(CPU_ACT0, 0x00000003U); + mmio_write_32(CPU_ACT1, 0x00000003U); + mmio_write_32(CPU_ACT2, 0x00000003U); + mmio_write_32(CPU_ACT3, 0x00000003U); + + mmio_write_32(QOSCTRL_RAEN, 0x00000001U); + +#if RCAR_REWT_TRAINING != RCAR_REWT_TRAINING_DISABLE + /* re-write training setting */ + mmio_write_32(QOSWT_WTREF, + (QOSWT_WTREF_SLOT1_EN << 16) | QOSWT_WTREF_SLOT0_EN); + mmio_write_32(QOSWT_WTSET0, (QOSWT_WTSET0_PERIOD0_G2M_30 << 16) | + (QOSWT_WTSET0_SSLOT0 << 8) | QOSWT_WTSET0_SLOTSLOT0); + mmio_write_32(QOSWT_WTSET1, (QOSWT_WTSET1_PERIOD1_G2M_30 << 16) | + (QOSWT_WTSET1_SSLOT1 << 8) | QOSWT_WTSET1_SLOTSLOT1); + + mmio_write_32(QOSWT_WTEN, QOSWT_WTEN_ENABLE); +#endif /* RCAR_REWT_TRAINING != RCAR_REWT_TRAINING_DISABLE */ + + mmio_write_32(QOSCTRL_STATQC, 0x00000001U); +#else /* !(RCAR_QOS_TYPE == RCAR_QOS_NONE) */ + NOTICE("BL2: QoS is None\n"); + + mmio_write_32(QOSCTRL_RAEN, 0x00000001U); +#endif /* !(RCAR_QOS_TYPE == RCAR_QOS_NONE) */ +} diff --git a/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30.h b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30.h new file mode 100644 index 000000000..f89eabf83 --- /dev/null +++ b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QOS_INIT_G2M_V30_H +#define QOS_INIT_G2M_V30_H + +void qos_init_g2m_v30(void); + +#endif /* QOS_INIT_G2M_V30_H */ diff --git a/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30_mstat195.h b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30_mstat195.h new file mode 100644 index 000000000..fd15788c5 --- /dev/null +++ b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30_mstat195.h @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QOS_INIT_G2M_V30_MSTAT195_H +#define QOS_INIT_G2M_V30_MSTAT195_H + +static uint64_t mstat_fix[] = { + /* 0x0000, */ 0x0000000000000000UL, + /* 0x0008, */ 0x0000000000000000UL, + /* 0x0010, */ 0x0000000000000000UL, + /* 0x0018, */ 0x0000000000000000UL, + /* 0x0020, */ 0x0000000000000000UL, + /* 0x0028, */ 0x0000000000000000UL, + /* 0x0030, */ 0x001004040000FFFFUL, + /* 0x0038, */ 0x001004040000FFFFUL, + /* 0x0040, */ 0x001414090000FFFFUL, + /* 0x0048, */ 0x0000000000000000UL, + /* 0x0050, */ 0x001404010000FFFFUL, + /* 0x0058, */ 0x00140C0A0000FFFFUL, + /* 0x0060, */ 0x00140C0A0000FFFFUL, + /* 0x0068, */ 0x0000000000000000UL, + /* 0x0070, */ 0x001404010000FFFFUL, + /* 0x0078, */ 0x001004030000FFFFUL, + /* 0x0080, */ 0x0000000000000000UL, + /* 0x0088, */ 0x001414090000FFFFUL, + /* 0x0090, */ 0x001408070000FFFFUL, + /* 0x0098, */ 0x0000000000000000UL, + /* 0x00a0, */ 0x000C04020000FFFFUL, + /* 0x00a8, */ 0x000C04010000FFFFUL, + /* 0x00b0, */ 0x000C04010000FFFFUL, + /* 0x00b8, */ 0x0000000000000000UL, + /* 0x00c0, */ 0x000C04020000FFFFUL, + /* 0x00c8, */ 0x000C04010000FFFFUL, + /* 0x00d0, */ 0x000C04010000FFFFUL, + /* 0x00d8, */ 0x000C08050000FFFFUL, + /* 0x00e0, */ 0x000C10100000FFFFUL, + /* 0x00e8, */ 0x0000000000000000UL, + /* 0x00f0, */ 0x001024090000FFFFUL, + /* 0x00f8, */ 0x0000000000000000UL, + /* 0x0100, */ 0x0000000000000000UL, + /* 0x0108, */ 0x0000000000000000UL, + /* 0x0110, */ 0x00100C090000FFFFUL, + /* 0x0118, */ 0x0000000000000000UL, + /* 0x0120, */ 0x000C10100000FFFFUL, + /* 0x0128, */ 0x0000000000000000UL, + /* 0x0130, */ 0x0000000000000000UL, + /* 0x0138, */ 0x00100C0B0000FFFFUL, + /* 0x0140, */ 0x0000000000000000UL, + /* 0x0148, */ 0x0000000000000000UL, + /* 0x0150, */ 0x0010100D0000FFFFUL, + /* 0x0158, */ 0x0000000000000000UL, + /* 0x0160, */ 0x00100C0B0000FFFFUL, + /* 0x0168, */ 0x0000000000000000UL, + /* 0x0170, */ 0x0000000000000000UL, + /* 0x0178, */ 0x001008060000FFFFUL, + /* 0x0180, */ 0x0000000000000000UL, + /* 0x0188, */ 0x0000000000000000UL, + /* 0x0190, */ 0x00102C2C0000FFFFUL, + /* 0x0198, */ 0x0000000000000000UL, + /* 0x01a0, */ 0x00100C0B0000FFFFUL, + /* 0x01a8, */ 0x0000000000000000UL, + /* 0x01b0, */ 0x0000000000000000UL, + /* 0x01b8, */ 0x0000000000000000UL, + /* 0x01c0, */ 0x000C04010000FFFFUL, + /* 0x01c8, */ 0x000C04010000FFFFUL, + /* 0x01d0, */ 0x000C04010000FFFFUL, + /* 0x01d8, */ 0x000C04010000FFFFUL, + /* 0x01e0, */ 0x0000000000000000UL, + /* 0x01e8, */ 0x000C04010000FFFFUL, + /* 0x01f0, */ 0x000C04010000FFFFUL, + /* 0x01f8, */ 0x0000000000000000UL, + /* 0x0200, */ 0x0000000000000000UL, + /* 0x0208, */ 0x000C04010000FFFFUL, + /* 0x0210, */ 0x000C04010000FFFFUL, + /* 0x0218, */ 0x0000000000000000UL, + /* 0x0220, */ 0x0000000000000000UL, + /* 0x0228, */ 0x0000000000000000UL, + /* 0x0230, */ 0x0000000000000000UL, + /* 0x0238, */ 0x0000000000000000UL, + /* 0x0240, */ 0x0000000000000000UL, + /* 0x0248, */ 0x0000000000000000UL, + /* 0x0250, */ 0x0000000000000000UL, + /* 0x0258, */ 0x0000000000000000UL, + /* 0x0260, */ 0x000C08020000FFFFUL, + /* 0x0268, */ 0x001408010000FFFFUL, + /* 0x0270, */ 0x001404010000FFFFUL, + /* 0x0278, */ 0x000C04010000FFFFUL, + /* 0x0280, */ 0x0000000000000000UL, + /* 0x0288, */ 0x0000000000000000UL, + /* 0x0290, */ 0x001408010000FFFFUL, + /* 0x0298, */ 0x001404010000FFFFUL, + /* 0x02a0, */ 0x000C04010000FFFFUL, + /* 0x02a8, */ 0x000C04010000FFFFUL, + /* 0x02b0, */ 0x001408010000FFFFUL, + /* 0x02b8, */ 0x000C04010000FFFFUL, + /* 0x02c0, */ 0x0000000000000000UL, + /* 0x02c8, */ 0x0000000000000000UL, + /* 0x02d0, */ 0x000C04010000FFFFUL, + /* 0x02d8, */ 0x000C04010000FFFFUL, + /* 0x02e0, */ 0x001408010000FFFFUL, + /* 0x02e8, */ 0x000C04010000FFFFUL, + /* 0x02f0, */ 0x0000000000000000UL, + /* 0x02f8, */ 0x0000000000000000UL, + /* 0x0300, */ 0x0000000000000000UL, + /* 0x0308, */ 0x0000000000000000UL, + /* 0x0310, */ 0x0000000000000000UL, + /* 0x0318, */ 0x0000000000000000UL, + /* 0x0320, */ 0x0000000000000000UL, + /* 0x0328, */ 0x0000000000000000UL, + /* 0x0330, */ 0x0000000000000000UL, + /* 0x0338, */ 0x0000000000000000UL, + /* 0x0340, */ 0x0000000000000000UL, + /* 0x0348, */ 0x0000000000000000UL, + /* 0x0350, */ 0x0000000000000000UL, +}; + +static uint64_t mstat_be[] = { + /* 0x0000, */ 0x001200200BDFFC01UL, + /* 0x0008, */ 0x001200200BDFFC01UL, + /* 0x0010, */ 0x001200200BDFFC01UL, + /* 0x0018, */ 0x001200200BDFFC01UL, + /* 0x0020, */ 0x0000000000000000UL, + /* 0x0028, */ 0x001200100BD03401UL, + /* 0x0030, */ 0x0000000000000000UL, + /* 0x0038, */ 0x0000000000000000UL, + /* 0x0040, */ 0x0000000000000000UL, + /* 0x0048, */ 0x0000000000000000UL, + /* 0x0050, */ 0x0000000000000000UL, + /* 0x0058, */ 0x0000000000000000UL, + /* 0x0060, */ 0x0000000000000000UL, + /* 0x0068, */ 0x0000000000000000UL, + /* 0x0070, */ 0x0000000000000000UL, + /* 0x0078, */ 0x0000000000000000UL, + /* 0x0080, */ 0x0000000000000000UL, + /* 0x0088, */ 0x0000000000000000UL, + /* 0x0090, */ 0x0000000000000000UL, + /* 0x0098, */ 0x0000000000000000UL, + /* 0x00a0, */ 0x0000000000000000UL, + /* 0x00a8, */ 0x0000000000000000UL, + /* 0x00b0, */ 0x0000000000000000UL, + /* 0x00b8, */ 0x0000000000000000UL, + /* 0x00c0, */ 0x0000000000000000UL, + /* 0x00c8, */ 0x0000000000000000UL, + /* 0x00d0, */ 0x0000000000000000UL, + /* 0x00d8, */ 0x0000000000000000UL, + /* 0x00e0, */ 0x0000000000000000UL, + /* 0x00e8, */ 0x0000000000000000UL, + /* 0x00f0, */ 0x0000000000000000UL, + /* 0x00f8, */ 0x0000000000000000UL, + /* 0x0100, */ 0x0000000000000000UL, + /* 0x0108, */ 0x0000000000000000UL, + /* 0x0110, */ 0x0000000000000000UL, + /* 0x0118, */ 0x0000000000000000UL, + /* 0x0120, */ 0x0000000000000000UL, + /* 0x0128, */ 0x0000000000000000UL, + /* 0x0130, */ 0x0000000000000000UL, + /* 0x0138, */ 0x0000000000000000UL, + /* 0x0140, */ 0x0000000000000000UL, + /* 0x0148, */ 0x0000000000000000UL, + /* 0x0150, */ 0x0000000000000000UL, + /* 0x0158, */ 0x0000000000000000UL, + /* 0x0160, */ 0x0000000000000000UL, + /* 0x0168, */ 0x0000000000000000UL, + /* 0x0170, */ 0x0000000000000000UL, + /* 0x0178, */ 0x0000000000000000UL, + /* 0x0180, */ 0x0000000000000000UL, + /* 0x0188, */ 0x0000000000000000UL, + /* 0x0190, */ 0x0000000000000000UL, + /* 0x0198, */ 0x0000000000000000UL, + /* 0x01a0, */ 0x0000000000000000UL, + /* 0x01a8, */ 0x0000000000000000UL, + /* 0x01b0, */ 0x0000000000000000UL, + /* 0x01b8, */ 0x0000000000000000UL, + /* 0x01c0, */ 0x002100600BDFFC01UL, + /* 0x01c8, */ 0x002100600BDFFC01UL, + /* 0x01d0, */ 0x002100600BDFFC01UL, + /* 0x01d8, */ 0x002100600BDFFC01UL, + /* 0x01e0, */ 0x0000000000000000UL, + /* 0x01e8, */ 0x0000000000000000UL, + /* 0x01f0, */ 0x002100200BDFFC01UL, + /* 0x01f8, */ 0x0000000000000000UL, + /* 0x0200, */ 0x0000000000000000UL, + /* 0x0208, */ 0x0000000000000000UL, + /* 0x0210, */ 0x002100200BDFFC01UL, + /* 0x0218, */ 0x001100200BDFFC01UL, + /* 0x0220, */ 0x001100200BDFFC01UL, + /* 0x0228, */ 0x0000000000000000UL, + /* 0x0230, */ 0x001100200BDFFC01UL, + /* 0x0238, */ 0x001100200BDFFC01UL, + /* 0x0240, */ 0x001200200BDFFC01UL, + /* 0x0248, */ 0x001100200BDFFC01UL, + /* 0x0250, */ 0x001200200BDFFC01UL, + /* 0x0258, */ 0x001100200BDFFC01UL, + /* 0x0260, */ 0x0000000000000000UL, + /* 0x0268, */ 0x0000000000000000UL, + /* 0x0270, */ 0x0000000000000000UL, + /* 0x0278, */ 0x0000000000000000UL, + /* 0x0280, */ 0x0000000000000000UL, + /* 0x0288, */ 0x0000000000000000UL, + /* 0x0290, */ 0x0000000000000000UL, + /* 0x0298, */ 0x0000000000000000UL, + /* 0x02a0, */ 0x0000000000000000UL, + /* 0x02a8, */ 0x0000000000000000UL, + /* 0x02b0, */ 0x0000000000000000UL, + /* 0x02b8, */ 0x0000000000000000UL, + /* 0x02c0, */ 0x0000000000000000UL, + /* 0x02c8, */ 0x0000000000000000UL, + /* 0x02d0, */ 0x0000000000000000UL, + /* 0x02d8, */ 0x0000000000000000UL, + /* 0x02e0, */ 0x0000000000000000UL, + /* 0x02e8, */ 0x0000000000000000UL, + /* 0x02f0, */ 0x001100400BDFFC01UL, + /* 0x02f8, */ 0x001100600BDFFC01UL, + /* 0x0300, */ 0x0000000000000000UL, + /* 0x0308, */ 0x001100400BDFFC01UL, + /* 0x0310, */ 0x001100600BDFFC01UL, + /* 0x0318, */ 0x001200100BD03401UL, + /* 0x0320, */ 0x0000000000000000UL, + /* 0x0328, */ 0x0000000000000000UL, + /* 0x0330, */ 0x0000000000000000UL, + /* 0x0338, */ 0x0000000000000000UL, + /* 0x0340, */ 0x0000000000000000UL, + /* 0x0348, */ 0x0000000000000000UL, + /* 0x0350, */ 0x0000000000000000UL, +}; + +#endif /* QOS_INIT_G2M_V30_MSTAT195_H */ diff --git a/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30_mstat390.h b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30_mstat390.h new file mode 100644 index 000000000..aa2036d1e --- /dev/null +++ b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30_mstat390.h @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QOS_INIT_G2M_V30_MSTAT390_H +#define QOS_INIT_G2M_V30_MSTAT390_H + +static uint64_t mstat_fix[] = { + /* 0x0000, */ 0x0000000000000000UL, + /* 0x0008, */ 0x0000000000000000UL, + /* 0x0010, */ 0x0000000000000000UL, + /* 0x0018, */ 0x0000000000000000UL, + /* 0x0020, */ 0x0000000000000000UL, + /* 0x0028, */ 0x0000000000000000UL, + /* 0x0030, */ 0x001008070000FFFFUL, + /* 0x0038, */ 0x001008070000FFFFUL, + /* 0x0040, */ 0x001424120000FFFFUL, + /* 0x0048, */ 0x0000000000000000UL, + /* 0x0050, */ 0x001404010000FFFFUL, + /* 0x0058, */ 0x001414130000FFFFUL, + /* 0x0060, */ 0x001414130000FFFFUL, + /* 0x0068, */ 0x0000000000000000UL, + /* 0x0070, */ 0x001404010000FFFFUL, + /* 0x0078, */ 0x001008050000FFFFUL, + /* 0x0080, */ 0x0000000000000000UL, + /* 0x0088, */ 0x001424120000FFFFUL, + /* 0x0090, */ 0x0014100D0000FFFFUL, + /* 0x0098, */ 0x0000000000000000UL, + /* 0x00a0, */ 0x000C08040000FFFFUL, + /* 0x00a8, */ 0x000C04020000FFFFUL, + /* 0x00b0, */ 0x000C04020000FFFFUL, + /* 0x00b8, */ 0x0000000000000000UL, + /* 0x00c0, */ 0x000C08040000FFFFUL, + /* 0x00c8, */ 0x000C04020000FFFFUL, + /* 0x00d0, */ 0x000C04020000FFFFUL, + /* 0x00d8, */ 0x000C0C0A0000FFFFUL, + /* 0x00e0, */ 0x000C201F0000FFFFUL, + /* 0x00e8, */ 0x0000000000000000UL, + /* 0x00f0, */ 0x001044110000FFFFUL, + /* 0x00f8, */ 0x0000000000000000UL, + /* 0x0100, */ 0x0000000000000000UL, + /* 0x0108, */ 0x0000000000000000UL, + /* 0x0110, */ 0x001014110000FFFFUL, + /* 0x0118, */ 0x0000000000000000UL, + /* 0x0120, */ 0x000C201F0000FFFFUL, + /* 0x0128, */ 0x0000000000000000UL, + /* 0x0130, */ 0x0000000000000000UL, + /* 0x0138, */ 0x001018150000FFFFUL, + /* 0x0140, */ 0x0000000000000000UL, + /* 0x0148, */ 0x0000000000000000UL, + /* 0x0150, */ 0x00101C190000FFFFUL, + /* 0x0158, */ 0x0000000000000000UL, + /* 0x0160, */ 0x001018150000FFFFUL, + /* 0x0168, */ 0x0000000000000000UL, + /* 0x0170, */ 0x0000000000000000UL, + /* 0x0178, */ 0x00100C0B0000FFFFUL, + /* 0x0180, */ 0x0000000000000000UL, + /* 0x0188, */ 0x0000000000000000UL, + /* 0x0190, */ 0x001058570000FFFFUL, + /* 0x0198, */ 0x0000000000000000UL, + /* 0x01a0, */ 0x001018150000FFFFUL, + /* 0x01a8, */ 0x0000000000000000UL, + /* 0x01b0, */ 0x0000000000000000UL, + /* 0x01b8, */ 0x0000000000000000UL, + /* 0x01c0, */ 0x000C04010000FFFFUL, + /* 0x01c8, */ 0x000C04010000FFFFUL, + /* 0x01d0, */ 0x000C04010000FFFFUL, + /* 0x01d8, */ 0x000C04010000FFFFUL, + /* 0x01e0, */ 0x0000000000000000UL, + /* 0x01e8, */ 0x000C04010000FFFFUL, + /* 0x01f0, */ 0x000C04010000FFFFUL, + /* 0x01f8, */ 0x0000000000000000UL, + /* 0x0200, */ 0x0000000000000000UL, + /* 0x0208, */ 0x000C04010000FFFFUL, + /* 0x0210, */ 0x000C04010000FFFFUL, + /* 0x0218, */ 0x0000000000000000UL, + /* 0x0220, */ 0x0000000000000000UL, + /* 0x0228, */ 0x0000000000000000UL, + /* 0x0230, */ 0x0000000000000000UL, + /* 0x0238, */ 0x0000000000000000UL, + /* 0x0240, */ 0x0000000000000000UL, + /* 0x0248, */ 0x0000000000000000UL, + /* 0x0250, */ 0x0000000000000000UL, + /* 0x0258, */ 0x0000000000000000UL, + /* 0x0260, */ 0x000C0C030000FFFFUL, + /* 0x0268, */ 0x001410010000FFFFUL, + /* 0x0270, */ 0x001404010000FFFFUL, + /* 0x0278, */ 0x000C08020000FFFFUL, + /* 0x0280, */ 0x0000000000000000UL, + /* 0x0288, */ 0x0000000000000000UL, + /* 0x0290, */ 0x001410010000FFFFUL, + /* 0x0298, */ 0x001404010000FFFFUL, + /* 0x02a0, */ 0x000C04010000FFFFUL, + /* 0x02a8, */ 0x000C04010000FFFFUL, + /* 0x02b0, */ 0x00140C010000FFFFUL, + /* 0x02b8, */ 0x000C04010000FFFFUL, + /* 0x02c0, */ 0x0000000000000000UL, + /* 0x02c8, */ 0x0000000000000000UL, + /* 0x02d0, */ 0x000C04010000FFFFUL, + /* 0x02d8, */ 0x000C04010000FFFFUL, + /* 0x02e0, */ 0x00140C010000FFFFUL, + /* 0x02e8, */ 0x000C04010000FFFFUL, + /* 0x02f0, */ 0x0000000000000000UL, + /* 0x02f8, */ 0x0000000000000000UL, + /* 0x0300, */ 0x0000000000000000UL, + /* 0x0308, */ 0x0000000000000000UL, + /* 0x0310, */ 0x0000000000000000UL, + /* 0x0318, */ 0x0000000000000000UL, + /* 0x0320, */ 0x0000000000000000UL, + /* 0x0328, */ 0x0000000000000000UL, + /* 0x0330, */ 0x0000000000000000UL, + /* 0x0338, */ 0x0000000000000000UL, + /* 0x0340, */ 0x0000000000000000UL, + /* 0x0348, */ 0x0000000000000000UL, + /* 0x0350, */ 0x0000000000000000UL, +}; + +static uint64_t mstat_be[] = { + /* 0x0000, */ 0x0012003005EFFC01UL, + /* 0x0008, */ 0x0012003005EFFC01UL, + /* 0x0010, */ 0x0012003005EFFC01UL, + /* 0x0018, */ 0x0012003005EFFC01UL, + /* 0x0020, */ 0x0000000000000000UL, + /* 0x0028, */ 0x0012001005E03401UL, + /* 0x0030, */ 0x0000000000000000UL, + /* 0x0038, */ 0x0000000000000000UL, + /* 0x0040, */ 0x0000000000000000UL, + /* 0x0048, */ 0x0000000000000000UL, + /* 0x0050, */ 0x0000000000000000UL, + /* 0x0058, */ 0x0000000000000000UL, + /* 0x0060, */ 0x0000000000000000UL, + /* 0x0068, */ 0x0000000000000000UL, + /* 0x0070, */ 0x0000000000000000UL, + /* 0x0078, */ 0x0000000000000000UL, + /* 0x0080, */ 0x0000000000000000UL, + /* 0x0088, */ 0x0000000000000000UL, + /* 0x0090, */ 0x0000000000000000UL, + /* 0x0098, */ 0x0000000000000000UL, + /* 0x00a0, */ 0x0000000000000000UL, + /* 0x00a8, */ 0x0000000000000000UL, + /* 0x00b0, */ 0x0000000000000000UL, + /* 0x00b8, */ 0x0000000000000000UL, + /* 0x00c0, */ 0x0000000000000000UL, + /* 0x00c8, */ 0x0000000000000000UL, + /* 0x00d0, */ 0x0000000000000000UL, + /* 0x00d8, */ 0x0000000000000000UL, + /* 0x00e0, */ 0x0000000000000000UL, + /* 0x00e8, */ 0x0000000000000000UL, + /* 0x00f0, */ 0x0000000000000000UL, + /* 0x00f8, */ 0x0000000000000000UL, + /* 0x0100, */ 0x0000000000000000UL, + /* 0x0108, */ 0x0000000000000000UL, + /* 0x0110, */ 0x0000000000000000UL, + /* 0x0118, */ 0x0000000000000000UL, + /* 0x0120, */ 0x0000000000000000UL, + /* 0x0128, */ 0x0000000000000000UL, + /* 0x0130, */ 0x0000000000000000UL, + /* 0x0138, */ 0x0000000000000000UL, + /* 0x0140, */ 0x0000000000000000UL, + /* 0x0148, */ 0x0000000000000000UL, + /* 0x0150, */ 0x0000000000000000UL, + /* 0x0158, */ 0x0000000000000000UL, + /* 0x0160, */ 0x0000000000000000UL, + /* 0x0168, */ 0x0000000000000000UL, + /* 0x0170, */ 0x0000000000000000UL, + /* 0x0178, */ 0x0000000000000000UL, + /* 0x0180, */ 0x0000000000000000UL, + /* 0x0188, */ 0x0000000000000000UL, + /* 0x0190, */ 0x0000000000000000UL, + /* 0x0198, */ 0x0000000000000000UL, + /* 0x01a0, */ 0x0000000000000000UL, + /* 0x01a8, */ 0x0000000000000000UL, + /* 0x01b0, */ 0x0000000000000000UL, + /* 0x01b8, */ 0x0000000000000000UL, + /* 0x01c0, */ 0x002100B005EFFC01UL, + /* 0x01c8, */ 0x002100B005EFFC01UL, + /* 0x01d0, */ 0x002100B005EFFC01UL, + /* 0x01d8, */ 0x002100B005EFFC01UL, + /* 0x01e0, */ 0x0000000000000000UL, + /* 0x01e8, */ 0x0000000000000000UL, + /* 0x01f0, */ 0x0021003005EFFC01UL, + /* 0x01f8, */ 0x0000000000000000UL, + /* 0x0200, */ 0x0000000000000000UL, + /* 0x0208, */ 0x0000000000000000UL, + /* 0x0210, */ 0x0021003005EFFC01UL, + /* 0x0218, */ 0x0011003005EFFC01UL, + /* 0x0220, */ 0x0011003005EFFC01UL, + /* 0x0228, */ 0x0000000000000000UL, + /* 0x0230, */ 0x0011003005EFFC01UL, + /* 0x0238, */ 0x0011003005EFFC01UL, + /* 0x0240, */ 0x0012003005EFFC01UL, + /* 0x0248, */ 0x0011003005EFFC01UL, + /* 0x0250, */ 0x0012003005EFFC01UL, + /* 0x0258, */ 0x0011003005EFFC01UL, + /* 0x0260, */ 0x0000000000000000UL, + /* 0x0268, */ 0x0000000000000000UL, + /* 0x0270, */ 0x0000000000000000UL, + /* 0x0278, */ 0x0000000000000000UL, + /* 0x0280, */ 0x0000000000000000UL, + /* 0x0288, */ 0x0000000000000000UL, + /* 0x0290, */ 0x0000000000000000UL, + /* 0x0298, */ 0x0000000000000000UL, + /* 0x02a0, */ 0x0000000000000000UL, + /* 0x02a8, */ 0x0000000000000000UL, + /* 0x02b0, */ 0x0000000000000000UL, + /* 0x02b8, */ 0x0000000000000000UL, + /* 0x02c0, */ 0x0000000000000000UL, + /* 0x02c8, */ 0x0000000000000000UL, + /* 0x02d0, */ 0x0000000000000000UL, + /* 0x02d8, */ 0x0000000000000000UL, + /* 0x02e0, */ 0x0000000000000000UL, + /* 0x02e8, */ 0x0000000000000000UL, + /* 0x02f0, */ 0x0011007005EFFC01UL, + /* 0x02f8, */ 0x001100B005EFFC01UL, + /* 0x0300, */ 0x0000000000000000UL, + /* 0x0308, */ 0x0011007005EFFC01UL, + /* 0x0310, */ 0x001100B005EFFC01UL, + /* 0x0318, */ 0x0012001005E03401UL, + /* 0x0320, */ 0x0000000000000000UL, + /* 0x0328, */ 0x0000000000000000UL, + /* 0x0330, */ 0x0000000000000000UL, + /* 0x0338, */ 0x0000000000000000UL, + /* 0x0340, */ 0x0000000000000000UL, + /* 0x0348, */ 0x0000000000000000UL, + /* 0x0350, */ 0x0000000000000000UL, +}; + +#endif /* QOS_INIT_G2M_V30_MSTAT390_H */ diff --git a/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30_qoswt195.h b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30_qoswt195.h new file mode 100644 index 000000000..27c9c51e1 --- /dev/null +++ b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30_qoswt195.h @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QOS_INIT_G2M_V30_QOSWT195_H +#define QOS_INIT_G2M_V30_QOSWT195_H + +static uint64_t qoswt_fix[] = { + /* 0x0000, */ 0x0000000000000000UL, + /* 0x0008, */ 0x0000000000000000UL, + /* 0x0010, */ 0x0000000000000000UL, + /* 0x0018, */ 0x0000000000000000UL, + /* 0x0020, */ 0x0000000000000000UL, + /* 0x0028, */ 0x0000000000000000UL, + /* 0x0030, */ 0x001004040000C010UL, + /* 0x0038, */ 0x001004040000C010UL, + /* 0x0040, */ 0x001414090000FFF0UL, + /* 0x0048, */ 0x0000000000000000UL, + /* 0x0050, */ 0x0000000000000000UL, + /* 0x0058, */ 0x00140C0A0000C010UL, + /* 0x0060, */ 0x00140C0A0000C010UL, + /* 0x0068, */ 0x0000000000000000UL, + /* 0x0070, */ 0x0000000000000000UL, + /* 0x0078, */ 0x001004030000C010UL, + /* 0x0080, */ 0x0000000000000000UL, + /* 0x0088, */ 0x001414090000FFF0UL, + /* 0x0090, */ 0x001408070000C010UL, + /* 0x0098, */ 0x0000000000000000UL, + /* 0x00a0, */ 0x0000000000000000UL, + /* 0x00a8, */ 0x0000000000000000UL, + /* 0x00b0, */ 0x0000000000000000UL, + /* 0x00b8, */ 0x0000000000000000UL, + /* 0x00c0, */ 0x0000000000000000UL, + /* 0x00c8, */ 0x0000000000000000UL, + /* 0x00d0, */ 0x0000000000000000UL, + /* 0x00d8, */ 0x0000000000000000UL, + /* 0x00e0, */ 0x0000000000000000UL, + /* 0x00e8, */ 0x0000000000000000UL, + /* 0x00f0, */ 0x0000000000000000UL, + /* 0x00f8, */ 0x0000000000000000UL, + /* 0x0100, */ 0x0000000000000000UL, + /* 0x0108, */ 0x0000000000000000UL, + /* 0x0110, */ 0x0000000000000000UL, + /* 0x0118, */ 0x0000000000000000UL, + /* 0x0120, */ 0x0000000000000000UL, + /* 0x0128, */ 0x0000000000000000UL, + /* 0x0130, */ 0x0000000000000000UL, + /* 0x0138, */ 0x0000000000000000UL, + /* 0x0140, */ 0x0000000000000000UL, + /* 0x0148, */ 0x0000000000000000UL, + /* 0x0150, */ 0x0000000000000000UL, + /* 0x0158, */ 0x0000000000000000UL, + /* 0x0160, */ 0x0000000000000000UL, + /* 0x0168, */ 0x0000000000000000UL, + /* 0x0170, */ 0x0000000000000000UL, + /* 0x0178, */ 0x0000000000000000UL, + /* 0x0180, */ 0x0000000000000000UL, + /* 0x0188, */ 0x0000000000000000UL, + /* 0x0190, */ 0x0000000000000000UL, + /* 0x0198, */ 0x0000000000000000UL, + /* 0x01a0, */ 0x0000000000000000UL, + /* 0x01a8, */ 0x0000000000000000UL, + /* 0x01b0, */ 0x0000000000000000UL, + /* 0x01b8, */ 0x0000000000000000UL, + /* 0x01c0, */ 0x0000000000000000UL, + /* 0x01c8, */ 0x0000000000000000UL, + /* 0x01d0, */ 0x0000000000000000UL, + /* 0x01d8, */ 0x0000000000000000UL, + /* 0x01e0, */ 0x0000000000000000UL, + /* 0x01e8, */ 0x0000000000000000UL, + /* 0x01f0, */ 0x0000000000000000UL, + /* 0x01f8, */ 0x0000000000000000UL, + /* 0x0200, */ 0x0000000000000000UL, + /* 0x0208, */ 0x0000000000000000UL, + /* 0x0210, */ 0x0000000000000000UL, + /* 0x0218, */ 0x0000000000000000UL, + /* 0x0220, */ 0x0000000000000000UL, + /* 0x0228, */ 0x0000000000000000UL, + /* 0x0230, */ 0x0000000000000000UL, + /* 0x0238, */ 0x0000000000000000UL, + /* 0x0240, */ 0x0000000000000000UL, + /* 0x0248, */ 0x0000000000000000UL, + /* 0x0250, */ 0x0000000000000000UL, + /* 0x0258, */ 0x0000000000000000UL, + /* 0x0260, */ 0x000C08020000FFF0UL, + /* 0x0268, */ 0x001408010000FFF0UL, + /* 0x0270, */ 0x001404010000FFF0UL, + /* 0x0278, */ 0x000C04010000FFF0UL, + /* 0x0280, */ 0x0000000000000000UL, + /* 0x0288, */ 0x0000000000000000UL, + /* 0x0290, */ 0x001408010000FFF0UL, + /* 0x0298, */ 0x001404010000FFF0UL, + /* 0x02a0, */ 0x0000000000000000UL, + /* 0x02a8, */ 0x0000000000000000UL, + /* 0x02b0, */ 0x0000000000000000UL, + /* 0x02b8, */ 0x0000000000000000UL, + /* 0x02c0, */ 0x0000000000000000UL, + /* 0x02c8, */ 0x0000000000000000UL, + /* 0x02d0, */ 0x0000000000000000UL, + /* 0x02d8, */ 0x0000000000000000UL, + /* 0x02e0, */ 0x0000000000000000UL, + /* 0x02e8, */ 0x0000000000000000UL, + /* 0x02f0, */ 0x0000000000000000UL, + /* 0x02f8, */ 0x0000000000000000UL, + /* 0x0300, */ 0x0000000000000000UL, + /* 0x0308, */ 0x0000000000000000UL, + /* 0x0310, */ 0x0000000000000000UL, + /* 0x0318, */ 0x0000000000000000UL, + /* 0x0320, */ 0x0000000000000000UL, + /* 0x0328, */ 0x0000000000000000UL, + /* 0x0330, */ 0x0000000000000000UL, + /* 0x0338, */ 0x0000000000000000UL, + /* 0x0340, */ 0x0000000000000000UL, + /* 0x0348, */ 0x0000000000000000UL, + /* 0x0350, */ 0x0000000000000000UL, +}; + +static uint64_t qoswt_be[] = { + /* 0x0000, */ 0x0000000000000000UL, + /* 0x0008, */ 0x0000000000000000UL, + /* 0x0010, */ 0x0000000000000000UL, + /* 0x0018, */ 0x0000000000000000UL, + /* 0x0020, */ 0x0000000000000000UL, + /* 0x0028, */ 0x0000000000000000UL, + /* 0x0030, */ 0x0000000000000000UL, + /* 0x0038, */ 0x0000000000000000UL, + /* 0x0040, */ 0x0000000000000000UL, + /* 0x0048, */ 0x0000000000000000UL, + /* 0x0050, */ 0x0000000000000000UL, + /* 0x0058, */ 0x0000000000000000UL, + /* 0x0060, */ 0x0000000000000000UL, + /* 0x0068, */ 0x0000000000000000UL, + /* 0x0070, */ 0x0000000000000000UL, + /* 0x0078, */ 0x0000000000000000UL, + /* 0x0080, */ 0x0000000000000000UL, + /* 0x0088, */ 0x0000000000000000UL, + /* 0x0090, */ 0x0000000000000000UL, + /* 0x0098, */ 0x0000000000000000UL, + /* 0x00a0, */ 0x0000000000000000UL, + /* 0x00a8, */ 0x0000000000000000UL, + /* 0x00b0, */ 0x0000000000000000UL, + /* 0x00b8, */ 0x0000000000000000UL, + /* 0x00c0, */ 0x0000000000000000UL, + /* 0x00c8, */ 0x0000000000000000UL, + /* 0x00d0, */ 0x0000000000000000UL, + /* 0x00d8, */ 0x0000000000000000UL, + /* 0x00e0, */ 0x0000000000000000UL, + /* 0x00e8, */ 0x0000000000000000UL, + /* 0x00f0, */ 0x0000000000000000UL, + /* 0x00f8, */ 0x0000000000000000UL, + /* 0x0100, */ 0x0000000000000000UL, + /* 0x0108, */ 0x0000000000000000UL, + /* 0x0110, */ 0x0000000000000000UL, + /* 0x0118, */ 0x0000000000000000UL, + /* 0x0120, */ 0x0000000000000000UL, + /* 0x0128, */ 0x0000000000000000UL, + /* 0x0130, */ 0x0000000000000000UL, + /* 0x0138, */ 0x0000000000000000UL, + /* 0x0140, */ 0x0000000000000000UL, + /* 0x0148, */ 0x0000000000000000UL, + /* 0x0150, */ 0x0000000000000000UL, + /* 0x0158, */ 0x0000000000000000UL, + /* 0x0160, */ 0x0000000000000000UL, + /* 0x0168, */ 0x0000000000000000UL, + /* 0x0170, */ 0x0000000000000000UL, + /* 0x0178, */ 0x0000000000000000UL, + /* 0x0180, */ 0x0000000000000000UL, + /* 0x0188, */ 0x0000000000000000UL, + /* 0x0190, */ 0x0000000000000000UL, + /* 0x0198, */ 0x0000000000000000UL, + /* 0x01a0, */ 0x0000000000000000UL, + /* 0x01a8, */ 0x0000000000000000UL, + /* 0x01b0, */ 0x0000000000000000UL, + /* 0x01b8, */ 0x0000000000000000UL, + /* 0x01c0, */ 0x0000000000000000UL, + /* 0x01c8, */ 0x0000000000000000UL, + /* 0x01d0, */ 0x0000000000000000UL, + /* 0x01d8, */ 0x0000000000000000UL, + /* 0x01e0, */ 0x0000000000000000UL, + /* 0x01e8, */ 0x0000000000000000UL, + /* 0x01f0, */ 0x0000000000000000UL, + /* 0x01f8, */ 0x0000000000000000UL, + /* 0x0200, */ 0x0000000000000000UL, + /* 0x0208, */ 0x0000000000000000UL, + /* 0x0210, */ 0x0000000000000000UL, + /* 0x0218, */ 0x0000000000000000UL, + /* 0x0220, */ 0x0000000000000000UL, + /* 0x0228, */ 0x0000000000000000UL, + /* 0x0230, */ 0x0000000000000000UL, + /* 0x0238, */ 0x0000000000000000UL, + /* 0x0240, */ 0x0000000000000000UL, + /* 0x0248, */ 0x0000000000000000UL, + /* 0x0250, */ 0x0000000000000000UL, + /* 0x0258, */ 0x0000000000000000UL, + /* 0x0260, */ 0x0000000000000000UL, + /* 0x0268, */ 0x0000000000000000UL, + /* 0x0270, */ 0x0000000000000000UL, + /* 0x0278, */ 0x0000000000000000UL, + /* 0x0280, */ 0x0000000000000000UL, + /* 0x0288, */ 0x0000000000000000UL, + /* 0x0290, */ 0x0000000000000000UL, + /* 0x0298, */ 0x0000000000000000UL, + /* 0x02a0, */ 0x0000000000000000UL, + /* 0x02a8, */ 0x0000000000000000UL, + /* 0x02b0, */ 0x0000000000000000UL, + /* 0x02b8, */ 0x0000000000000000UL, + /* 0x02c0, */ 0x0000000000000000UL, + /* 0x02c8, */ 0x0000000000000000UL, + /* 0x02d0, */ 0x0000000000000000UL, + /* 0x02d8, */ 0x0000000000000000UL, + /* 0x02e0, */ 0x0000000000000000UL, + /* 0x02e8, */ 0x0000000000000000UL, + /* 0x02f0, */ 0x0000000000000000UL, + /* 0x02f8, */ 0x0000000000000000UL, + /* 0x0300, */ 0x0000000000000000UL, + /* 0x0308, */ 0x0000000000000000UL, + /* 0x0310, */ 0x0000000000000000UL, + /* 0x0318, */ 0x0000000000000000UL, + /* 0x0320, */ 0x0000000000000000UL, + /* 0x0328, */ 0x0000000000000000UL, + /* 0x0330, */ 0x0000000000000000UL, + /* 0x0338, */ 0x0000000000000000UL, + /* 0x0340, */ 0x0000000000000000UL, + /* 0x0348, */ 0x0000000000000000UL, + /* 0x0350, */ 0x0000000000000000UL, +}; + +#endif /* QOS_INIT_G2M_V30_QOSWT195_H */ diff --git a/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30_qoswt390.h b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30_qoswt390.h new file mode 100644 index 000000000..5d18212b4 --- /dev/null +++ b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30_qoswt390.h @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QOS_INIT_G2M_V30_QOSWT390_H +#define QOS_INIT_G2M_V30_QOSWT390_H + +static uint64_t qoswt_fix[] = { + /* 0x0000, */ 0x0000000000000000UL, + /* 0x0008, */ 0x0000000000000000UL, + /* 0x0010, */ 0x0000000000000000UL, + /* 0x0018, */ 0x0000000000000000UL, + /* 0x0020, */ 0x0000000000000000UL, + /* 0x0028, */ 0x0000000000000000UL, + /* 0x0030, */ 0x001008070000C010UL, + /* 0x0038, */ 0x001008070000C010UL, + /* 0x0040, */ 0x001424120000FFF0UL, + /* 0x0048, */ 0x0000000000000000UL, + /* 0x0050, */ 0x0000000000000000UL, + /* 0x0058, */ 0x001414130000C010UL, + /* 0x0060, */ 0x001414130000C010UL, + /* 0x0068, */ 0x0000000000000000UL, + /* 0x0070, */ 0x0000000000000000UL, + /* 0x0078, */ 0x001008050000C010UL, + /* 0x0080, */ 0x0000000000000000UL, + /* 0x0088, */ 0x001424120000FFF0UL, + /* 0x0090, */ 0x0014100D0000C010UL, + /* 0x0098, */ 0x0000000000000000UL, + /* 0x00a0, */ 0x0000000000000000UL, + /* 0x00a8, */ 0x0000000000000000UL, + /* 0x00b0, */ 0x0000000000000000UL, + /* 0x00b8, */ 0x0000000000000000UL, + /* 0x00c0, */ 0x0000000000000000UL, + /* 0x00c8, */ 0x0000000000000000UL, + /* 0x00d0, */ 0x0000000000000000UL, + /* 0x00d8, */ 0x0000000000000000UL, + /* 0x00e0, */ 0x0000000000000000UL, + /* 0x00e8, */ 0x0000000000000000UL, + /* 0x00f0, */ 0x0000000000000000UL, + /* 0x00f8, */ 0x0000000000000000UL, + /* 0x0100, */ 0x0000000000000000UL, + /* 0x0108, */ 0x0000000000000000UL, + /* 0x0110, */ 0x0000000000000000UL, + /* 0x0118, */ 0x0000000000000000UL, + /* 0x0120, */ 0x0000000000000000UL, + /* 0x0128, */ 0x0000000000000000UL, + /* 0x0130, */ 0x0000000000000000UL, + /* 0x0138, */ 0x0000000000000000UL, + /* 0x0140, */ 0x0000000000000000UL, + /* 0x0148, */ 0x0000000000000000UL, + /* 0x0150, */ 0x0000000000000000UL, + /* 0x0158, */ 0x0000000000000000UL, + /* 0x0160, */ 0x0000000000000000UL, + /* 0x0168, */ 0x0000000000000000UL, + /* 0x0170, */ 0x0000000000000000UL, + /* 0x0178, */ 0x0000000000000000UL, + /* 0x0180, */ 0x0000000000000000UL, + /* 0x0188, */ 0x0000000000000000UL, + /* 0x0190, */ 0x0000000000000000UL, + /* 0x0198, */ 0x0000000000000000UL, + /* 0x01a0, */ 0x0000000000000000UL, + /* 0x01a8, */ 0x0000000000000000UL, + /* 0x01b0, */ 0x0000000000000000UL, + /* 0x01b8, */ 0x0000000000000000UL, + /* 0x01c0, */ 0x0000000000000000UL, + /* 0x01c8, */ 0x0000000000000000UL, + /* 0x01d0, */ 0x0000000000000000UL, + /* 0x01d8, */ 0x0000000000000000UL, + /* 0x01e0, */ 0x0000000000000000UL, + /* 0x01e8, */ 0x0000000000000000UL, + /* 0x01f0, */ 0x0000000000000000UL, + /* 0x01f8, */ 0x0000000000000000UL, + /* 0x0200, */ 0x0000000000000000UL, + /* 0x0208, */ 0x0000000000000000UL, + /* 0x0210, */ 0x0000000000000000UL, + /* 0x0218, */ 0x0000000000000000UL, + /* 0x0220, */ 0x0000000000000000UL, + /* 0x0228, */ 0x0000000000000000UL, + /* 0x0230, */ 0x0000000000000000UL, + /* 0x0238, */ 0x0000000000000000UL, + /* 0x0240, */ 0x0000000000000000UL, + /* 0x0248, */ 0x0000000000000000UL, + /* 0x0250, */ 0x0000000000000000UL, + /* 0x0258, */ 0x0000000000000000UL, + /* 0x0260, */ 0x000C0C030000FFF0UL, + /* 0x0268, */ 0x001410010000FFF0UL, + /* 0x0270, */ 0x001404010000FFF0UL, + /* 0x0278, */ 0x000C08020000FFF0UL, + /* 0x0280, */ 0x0000000000000000UL, + /* 0x0288, */ 0x0000000000000000UL, + /* 0x0290, */ 0x001410010000FFF0UL, + /* 0x0298, */ 0x001404010000FFF0UL, + /* 0x02a0, */ 0x0000000000000000UL, + /* 0x02a8, */ 0x0000000000000000UL, + /* 0x02b0, */ 0x0000000000000000UL, + /* 0x02b8, */ 0x0000000000000000UL, + /* 0x02c0, */ 0x0000000000000000UL, + /* 0x02c8, */ 0x0000000000000000UL, + /* 0x02d0, */ 0x0000000000000000UL, + /* 0x02d8, */ 0x0000000000000000UL, + /* 0x02e0, */ 0x0000000000000000UL, + /* 0x02e8, */ 0x0000000000000000UL, + /* 0x02f0, */ 0x0000000000000000UL, + /* 0x02f8, */ 0x0000000000000000UL, + /* 0x0300, */ 0x0000000000000000UL, + /* 0x0308, */ 0x0000000000000000UL, + /* 0x0310, */ 0x0000000000000000UL, + /* 0x0318, */ 0x0000000000000000UL, + /* 0x0320, */ 0x0000000000000000UL, + /* 0x0328, */ 0x0000000000000000UL, + /* 0x0330, */ 0x0000000000000000UL, + /* 0x0338, */ 0x0000000000000000UL, + /* 0x0340, */ 0x0000000000000000UL, + /* 0x0348, */ 0x0000000000000000UL, + /* 0x0350, */ 0x0000000000000000UL, +}; + +static uint64_t qoswt_be[] = { + /* 0x0000, */ 0x0000000000000000UL, + /* 0x0008, */ 0x0000000000000000UL, + /* 0x0010, */ 0x0000000000000000UL, + /* 0x0018, */ 0x0000000000000000UL, + /* 0x0020, */ 0x0000000000000000UL, + /* 0x0028, */ 0x0000000000000000UL, + /* 0x0030, */ 0x0000000000000000UL, + /* 0x0038, */ 0x0000000000000000UL, + /* 0x0040, */ 0x0000000000000000UL, + /* 0x0048, */ 0x0000000000000000UL, + /* 0x0050, */ 0x0000000000000000UL, + /* 0x0058, */ 0x0000000000000000UL, + /* 0x0060, */ 0x0000000000000000UL, + /* 0x0068, */ 0x0000000000000000UL, + /* 0x0070, */ 0x0000000000000000UL, + /* 0x0078, */ 0x0000000000000000UL, + /* 0x0080, */ 0x0000000000000000UL, + /* 0x0088, */ 0x0000000000000000UL, + /* 0x0090, */ 0x0000000000000000UL, + /* 0x0098, */ 0x0000000000000000UL, + /* 0x00a0, */ 0x0000000000000000UL, + /* 0x00a8, */ 0x0000000000000000UL, + /* 0x00b0, */ 0x0000000000000000UL, + /* 0x00b8, */ 0x0000000000000000UL, + /* 0x00c0, */ 0x0000000000000000UL, + /* 0x00c8, */ 0x0000000000000000UL, + /* 0x00d0, */ 0x0000000000000000UL, + /* 0x00d8, */ 0x0000000000000000UL, + /* 0x00e0, */ 0x0000000000000000UL, + /* 0x00e8, */ 0x0000000000000000UL, + /* 0x00f0, */ 0x0000000000000000UL, + /* 0x00f8, */ 0x0000000000000000UL, + /* 0x0100, */ 0x0000000000000000UL, + /* 0x0108, */ 0x0000000000000000UL, + /* 0x0110, */ 0x0000000000000000UL, + /* 0x0118, */ 0x0000000000000000UL, + /* 0x0120, */ 0x0000000000000000UL, + /* 0x0128, */ 0x0000000000000000UL, + /* 0x0130, */ 0x0000000000000000UL, + /* 0x0138, */ 0x0000000000000000UL, + /* 0x0140, */ 0x0000000000000000UL, + /* 0x0148, */ 0x0000000000000000UL, + /* 0x0150, */ 0x0000000000000000UL, + /* 0x0158, */ 0x0000000000000000UL, + /* 0x0160, */ 0x0000000000000000UL, + /* 0x0168, */ 0x0000000000000000UL, + /* 0x0170, */ 0x0000000000000000UL, + /* 0x0178, */ 0x0000000000000000UL, + /* 0x0180, */ 0x0000000000000000UL, + /* 0x0188, */ 0x0000000000000000UL, + /* 0x0190, */ 0x0000000000000000UL, + /* 0x0198, */ 0x0000000000000000UL, + /* 0x01a0, */ 0x0000000000000000UL, + /* 0x01a8, */ 0x0000000000000000UL, + /* 0x01b0, */ 0x0000000000000000UL, + /* 0x01b8, */ 0x0000000000000000UL, + /* 0x01c0, */ 0x0000000000000000UL, + /* 0x01c8, */ 0x0000000000000000UL, + /* 0x01d0, */ 0x0000000000000000UL, + /* 0x01d8, */ 0x0000000000000000UL, + /* 0x01e0, */ 0x0000000000000000UL, + /* 0x01e8, */ 0x0000000000000000UL, + /* 0x01f0, */ 0x0000000000000000UL, + /* 0x01f8, */ 0x0000000000000000UL, + /* 0x0200, */ 0x0000000000000000UL, + /* 0x0208, */ 0x0000000000000000UL, + /* 0x0210, */ 0x0000000000000000UL, + /* 0x0218, */ 0x0000000000000000UL, + /* 0x0220, */ 0x0000000000000000UL, + /* 0x0228, */ 0x0000000000000000UL, + /* 0x0230, */ 0x0000000000000000UL, + /* 0x0238, */ 0x0000000000000000UL, + /* 0x0240, */ 0x0000000000000000UL, + /* 0x0248, */ 0x0000000000000000UL, + /* 0x0250, */ 0x0000000000000000UL, + /* 0x0258, */ 0x0000000000000000UL, + /* 0x0260, */ 0x0000000000000000UL, + /* 0x0268, */ 0x0000000000000000UL, + /* 0x0270, */ 0x0000000000000000UL, + /* 0x0278, */ 0x0000000000000000UL, + /* 0x0280, */ 0x0000000000000000UL, + /* 0x0288, */ 0x0000000000000000UL, + /* 0x0290, */ 0x0000000000000000UL, + /* 0x0298, */ 0x0000000000000000UL, + /* 0x02a0, */ 0x0000000000000000UL, + /* 0x02a8, */ 0x0000000000000000UL, + /* 0x02b0, */ 0x0000000000000000UL, + /* 0x02b8, */ 0x0000000000000000UL, + /* 0x02c0, */ 0x0000000000000000UL, + /* 0x02c8, */ 0x0000000000000000UL, + /* 0x02d0, */ 0x0000000000000000UL, + /* 0x02d8, */ 0x0000000000000000UL, + /* 0x02e0, */ 0x0000000000000000UL, + /* 0x02e8, */ 0x0000000000000000UL, + /* 0x02f0, */ 0x0000000000000000UL, + /* 0x02f8, */ 0x0000000000000000UL, + /* 0x0300, */ 0x0000000000000000UL, + /* 0x0308, */ 0x0000000000000000UL, + /* 0x0310, */ 0x0000000000000000UL, + /* 0x0318, */ 0x0000000000000000UL, + /* 0x0320, */ 0x0000000000000000UL, + /* 0x0328, */ 0x0000000000000000UL, + /* 0x0330, */ 0x0000000000000000UL, + /* 0x0338, */ 0x0000000000000000UL, + /* 0x0340, */ 0x0000000000000000UL, + /* 0x0348, */ 0x0000000000000000UL, + /* 0x0350, */ 0x0000000000000000UL, +}; + +#endif /* QOS_INIT_G2M_V30_QOSWT390_H */ diff --git a/drivers/renesas/rzg/qos/qos.mk b/drivers/renesas/rzg/qos/qos.mk new file mode 100644 index 000000000..f06c685c3 --- /dev/null +++ b/drivers/renesas/rzg/qos/qos.mk @@ -0,0 +1,34 @@ +# +# Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +ifeq (${RCAR_LSI},${RCAR_AUTO}) + BL2_SOURCES += drivers/renesas/rzg/qos/G2M/qos_init_g2m_v10.c + BL2_SOURCES += drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11.c + BL2_SOURCES += drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30.c +else ifeq (${RCAR_LSI_CUT_COMPAT},1) + ifeq (${RCAR_LSI},${RZ_G2M}) + BL2_SOURCES += drivers/renesas/rzg/qos/G2M/qos_init_g2m_v10.c + BL2_SOURCES += drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11.c + BL2_SOURCES += drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30.c + endif +else + ifeq (${RCAR_LSI},${RZ_G2M}) + ifeq (${LSI_CUT},10) + BL2_SOURCES += drivers/renesas/rzg/qos/G2M/qos_init_g2m_v10.c + else ifeq (${LSI_CUT},11) + BL2_SOURCES += drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11.c + else ifeq (${LSI_CUT},13) + BL2_SOURCES += drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11.c + else ifeq (${LSI_CUT},30) + BL2_SOURCES += drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30.c + else +# LSI_CUT 30 or later + BL2_SOURCES += drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30.c + endif + endif +endif + +BL2_SOURCES += drivers/renesas/rzg/qos/qos_init.c diff --git a/drivers/renesas/rzg/qos/qos_common.h b/drivers/renesas/rzg/qos/qos_common.h new file mode 100644 index 000000000..6e0cf0e85 --- /dev/null +++ b/drivers/renesas/rzg/qos/qos_common.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2021, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QOS_COMMON_H +#define QOS_COMMON_H + +#define RCAR_REF_DEFAULT 0U + +/* define used for get_refperiod. */ +/* REFPERIOD_CYCLE need smaller than QOSWT_WTSET0_CYCLEs */ +#if (RCAR_REF_INT == RCAR_REF_DEFAULT) /* REF default */ +#define REFPERIOD_CYCLE /* unit:ns */ \ + ((126U * BASE_SUB_SLOT_NUM * 1000U) / 400U) +#else /* REF option */ +#define REFPERIOD_CYCLE /* unit:ns */ \ + ((252U * BASE_SUB_SLOT_NUM * 1000U) / 400U) +#endif + +#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RZ_G2M) +/* define used for G2M */ +#if (RCAR_REF_INT == RCAR_REF_DEFAULT) /* REF 1.95usec */ +#define SUB_SLOT_CYCLE_G2M_11 0x7EU /* 126 */ +#define SUB_SLOT_CYCLE_G2M_30 0x7EU /* 126 */ +#else /* REF 3.9usec */ +#define SUB_SLOT_CYCLE_G2M_11 0xFCU /* 252 */ +#define SUB_SLOT_CYCLE_G2M_30 0xFCU /* 252 */ +#endif /* (RCAR_REF_INT == RCAR_REF_DEFAULT) */ + +#define SL_INIT_SSLOTCLK_G2M_11 (SUB_SLOT_CYCLE_G2M_11 - 1U) +#define SL_INIT_SSLOTCLK_G2M_30 (SUB_SLOT_CYCLE_G2M_30 - 1U) +#define QOSWT_WTSET0_CYCLE_G2M_11 /* unit:ns */ \ + ((SUB_SLOT_CYCLE_G2M_11 * BASE_SUB_SLOT_NUM * 1000U) / OPERATING_FREQ) +#define QOSWT_WTSET0_CYCLE_G2M_30 /* unit:ns */ \ + ((SUB_SLOT_CYCLE_G2M_30 * BASE_SUB_SLOT_NUM * 1000U) / OPERATING_FREQ) +#endif + +#define OPERATING_FREQ 400U /* MHz */ +#define BASE_SUB_SLOT_NUM 0x6U +#define SUB_SLOT_CYCLE 0x7EU /* 126 */ + +#define QOSWT_WTSET0_CYCLE /* unit:ns */ \ + ((SUB_SLOT_CYCLE * BASE_SUB_SLOT_NUM * 1000U) / OPERATING_FREQ) + +#define SL_INIT_REFFSSLOT (0x3U << 24U) +#define SL_INIT_SLOTSSLOT ((BASE_SUB_SLOT_NUM - 1U) << 16U) +#define SL_INIT_SSLOTCLK (SUB_SLOT_CYCLE - 1U) + +typedef struct { + uintptr_t addr; + uint64_t value; +} mstat_slot_t; + +struct rcar_gen3_dbsc_qos_settings { + uint32_t reg; + uint32_t val; +}; + +extern uint32_t qos_init_ddr_ch; +extern uint8_t qos_init_ddr_phyvalid; + +void rzg_qos_dbsc_setting(const struct rcar_gen3_dbsc_qos_settings *qos, + unsigned int qos_size, bool dbsc_wren); + +#endif /* QOS_COMMON_H */ diff --git a/drivers/renesas/rzg/qos/qos_init.c b/drivers/renesas/rzg/qos/qos_init.c new file mode 100644 index 000000000..2d5aecebb --- /dev/null +++ b/drivers/renesas/rzg/qos/qos_init.c @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2021, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include + +#if RCAR_LSI == RCAR_AUTO +#include "G2M/qos_init_g2m_v10.h" +#include "G2M/qos_init_g2m_v11.h" +#include "G2M/qos_init_g2m_v30.h" +#endif /* RCAR_LSI == RCAR_AUTO */ +#if (RCAR_LSI == RZ_G2M) +#include "G2M/qos_init_g2m_v10.h" +#include "G2M/qos_init_g2m_v11.h" +#include "G2M/qos_init_g2m_v30.h" +#endif /* RCAR_LSI == RZ_G2M */ +#include "qos_common.h" +#include "qos_init.h" +#include "qos_reg.h" +#include "rcar_def.h" + +#define DRAM_CH_CNT 0x04U +uint32_t qos_init_ddr_ch; +uint8_t qos_init_ddr_phyvalid; + +#define PRR_PRODUCT_ERR(reg) \ + { \ + ERROR("LSI Product ID(PRR=0x%x) QoS " \ + "initialize not supported.\n", reg); \ + panic(); \ + } + +#define PRR_CUT_ERR(reg) \ + { \ + ERROR("LSI Cut ID(PRR=0x%x) QoS " \ + "initialize not supported.\n", reg); \ + panic(); \ + } + +void rzg_qos_init(void) +{ + uint32_t reg; + uint32_t i; + + qos_init_ddr_ch = 0U; + qos_init_ddr_phyvalid = rzg_get_boardcnf_phyvalid(); + for (i = 0U; i < DRAM_CH_CNT; i++) { + if ((qos_init_ddr_phyvalid & (1U << i))) { + qos_init_ddr_ch++; + } + } + + reg = mmio_read_32(PRR); +#if (RCAR_LSI == RCAR_AUTO) || RCAR_LSI_CUT_COMPAT + switch (reg & PRR_PRODUCT_MASK) { + case PRR_PRODUCT_M3: +#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RZ_G2M) + switch (reg & PRR_CUT_MASK) { + case PRR_PRODUCT_10: + qos_init_g2m_v10(); + break; + case PRR_PRODUCT_21: /* G2M Cut 13 */ + qos_init_g2m_v11(); + break; + case PRR_PRODUCT_30: /* G2M Cut 30 */ + default: + qos_init_g2m_v30(); + break; + } +#else /* (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RZ_G2M) */ + PRR_PRODUCT_ERR(reg); +#endif /* (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RZ_G2M) */ + break; + default: + PRR_PRODUCT_ERR(reg); + break; + } +#else /* RCAR_LSI == RCAR_AUTO || RCAR_LSI_CUT_COMPAT */ +#if (RCAR_LSI == RZ_G2M) +#if RCAR_LSI_CUT == RCAR_CUT_10 + /* G2M Cut 10 */ + if ((PRR_PRODUCT_M3 | PRR_PRODUCT_10) + != (reg & (PRR_PRODUCT_MASK | PRR_CUT_MASK))) { + PRR_PRODUCT_ERR(reg); + } + qos_init_g2m_v10(); +#elif RCAR_LSI_CUT == RCAR_CUT_11 + /* G2M Cut 11 */ + if ((PRR_PRODUCT_M3 | PRR_PRODUCT_20) + != (reg & (PRR_PRODUCT_MASK | PRR_CUT_MASK))) { + PRR_PRODUCT_ERR(reg); + } + qos_init_g2m_v11(); +#elif RCAR_LSI_CUT == RCAR_CUT_13 + /* G2M Cut 13 */ + if ((PRR_PRODUCT_M3 | PRR_PRODUCT_21) + != (reg & (PRR_PRODUCT_MASK | PRR_CUT_MASK))) { + PRR_PRODUCT_ERR(reg); + } + qos_init_g2m_v11(); +#else + /* G2M Cut 30 or later */ + if ((PRR_PRODUCT_M3) + != (reg & (PRR_PRODUCT_MASK))) { + PRR_PRODUCT_ERR(reg); + } + qos_init_g2m_v30(); +#endif /* RCAR_LSI_CUT == RCAR_CUT_10 */ +#else /* (RCAR_LSI == RZ_G2M) */ +#error "Don't have QoS initialize routine(Unknown chip)." +#endif /* (RCAR_LSI == RZ_G2M) */ +#endif /* RCAR_LSI == RCAR_AUTO || RCAR_LSI_CUT_COMPAT */ +} + +uint32_t get_refperiod(void) +{ + uint32_t refperiod = QOSWT_WTSET0_CYCLE; + +#if (RCAR_LSI == RCAR_AUTO) || RCAR_LSI_CUT_COMPAT + uint32_t reg; + + reg = mmio_read_32(PRR); + switch (reg & PRR_PRODUCT_MASK) { +#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RZ_G2M) + case PRR_PRODUCT_M3: + switch (reg & PRR_CUT_MASK) { + case PRR_PRODUCT_10: + break; + case PRR_PRODUCT_20: /* G2M Cut 11 */ + case PRR_PRODUCT_21: /* G2M Cut 13 */ + case PRR_PRODUCT_30: /* G2M Cut 30 */ + default: + refperiod = REFPERIOD_CYCLE; + break; + } + break; +#endif /* (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RZ_G2M) */ + default: + break; + } +#elif RCAR_LSI == RZ_G2M +#if RCAR_LSI_CUT == RCAR_CUT_10 + /* G2M Cut 10 */ +#else /* RCAR_LSI_CUT == RCAR_CUT_10 */ + /* G2M Cut 11|13|30 or later */ + refperiod = REFPERIOD_CYCLE; +#endif /* RCAR_LSI_CUT == RCAR_CUT_10 */ +#endif /* RCAR_LSI == RCAR_AUTO || RCAR_LSI_CUT_COMPAT */ + return refperiod; +} + +void rzg_qos_dbsc_setting(const struct rcar_gen3_dbsc_qos_settings *qos, + unsigned int qos_size, bool dbsc_wren) +{ + unsigned int i; + + /* Register write enable */ + if (dbsc_wren) { + mmio_write_32(DBSC_DBSYSCNT0, 0x00001234U); + } + + for (i = 0; i < qos_size; i++) { + mmio_write_32(qos[i].reg, qos[i].val); + } + + /* Register write protect */ + if (dbsc_wren) { + mmio_write_32(DBSC_DBSYSCNT0, 0x00000000U); + } +} diff --git a/drivers/renesas/rzg/qos/qos_init.h b/drivers/renesas/rzg/qos/qos_init.h new file mode 100644 index 000000000..10f60e7ca --- /dev/null +++ b/drivers/renesas/rzg/qos/qos_init.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef RZG_QOS_INIT_H +#define RZG_QOS_INIT_H + +void rzg_qos_init(void); +uint8_t rzg_get_boardcnf_phyvalid(void); + +#endif /* RZG_QOS_INIT_H */ -- cgit v1.2.3 From 6369498c0802f23bb27fbf00577a6c2e12b83975 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Mon, 7 Dec 2020 13:25:07 +0000 Subject: tools: renesas: Add tool support for RZ/G2 platforms Add tool support for creating bootparam and cert_header images for RZ/G2 SoC based platforms. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: Iab8ba6eda442c8d75f23c5633b8178f86339e4c9 --- .gitignore | 4 + tools/renesas/rzg_layout_create/makefile | 118 ++++++++++++++++ tools/renesas/rzg_layout_create/sa0.c | 30 ++++ tools/renesas/rzg_layout_create/sa0.ld.S | 28 ++++ tools/renesas/rzg_layout_create/sa6.c | 236 +++++++++++++++++++++++++++++++ tools/renesas/rzg_layout_create/sa6.ld.S | 114 +++++++++++++++ 6 files changed, 530 insertions(+) create mode 100644 tools/renesas/rzg_layout_create/makefile create mode 100644 tools/renesas/rzg_layout_create/sa0.c create mode 100644 tools/renesas/rzg_layout_create/sa0.ld.S create mode 100644 tools/renesas/rzg_layout_create/sa6.c create mode 100644 tools/renesas/rzg_layout_create/sa6.ld.S diff --git a/.gitignore b/.gitignore index 64b389b12..79c510405 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,10 @@ tools/renesas/rcar_layout_create/*.bin tools/renesas/rcar_layout_create/*.srec tools/renesas/rcar_layout_create/*.map tools/renesas/rcar_layout_create/*.elf +tools/renesas/rzg_layout_create/*.bin +tools/renesas/rzg_layout_create/*.srec +tools/renesas/rzg_layout_create/*.map +tools/renesas/rzg_layout_create/*.elf tools/fiptool/fiptool tools/fiptool/fiptool.exe tools/cert_create/src/*.o diff --git a/tools/renesas/rzg_layout_create/makefile b/tools/renesas/rzg_layout_create/makefile new file mode 100644 index 000000000..2d438b923 --- /dev/null +++ b/tools/renesas/rzg_layout_create/makefile @@ -0,0 +1,118 @@ +# +# Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +################################################### +# makefile +################################################### + +#output file name +FILE_NAME_SA0 = bootparam_sa0 +FILE_NAME_SA6 = cert_header_sa6 + +OUTPUT_FILE_SA0 = $(FILE_NAME_SA0).elf +OUTPUT_FILE_SA6 = $(FILE_NAME_SA6).elf + +#object file name +OBJ_FILE_SA0 = sa0.o +OBJ_FILE_SA6 = sa6.o + +#linker script name +MEMORY_DEF_SA0 = sa0.ld.S +MEMORY_DEF_SA6 = sa6.ld.S + +################################################### +# Convenience function for adding build definitions +# $(eval $(call add_define,FOO)) will have: +# -DFOO if $(FOO) is empty; -DFOO=$(FOO) otherwise +define add_define +DEFINES += -D$(1)$(if $(value $(1)),=$(value $(1)),) +endef + +# Process RCAR_SA0_SIZE flag +ifndef RCAR_SA0_SIZE +RCAR_SA0_SIZE := 1 +else +ifeq (${RCAR_SA0_SIZE},0) +RCAR_SA0_SIZE := 0 +else +RCAR_SA0_SIZE := 1 +endif +endif +$(eval $(call add_define,RCAR_SA0_SIZE)) + +# Process RCAR_SA6_TYPE flag +ifndef RCAR_SA6_TYPE +RCAR_SA6_TYPE := 0 +else +ifeq (${RCAR_SA6_TYPE},0) +RCAR_SA6_TYPE := 0 +else +RCAR_SA6_TYPE := 1 +endif +endif +$(eval $(call add_define,RCAR_SA6_TYPE)) + +RCAR_VMA_ADJUST_ADDR := 0xE6320000 +$(eval $(call add_define,RCAR_VMA_ADJUST_ADDR)) + + +################################################### + +#c compiler +CC = $(CROSS_COMPILE)gcc +CFLAGS += ${DEFINES} +CFLAGS += -nostdinc \ + -I../../../include/lib/libc \ + -I../../../include/lib/libc/aarch64 + +#Linker +LD = $(CROSS_COMPILE)ld + +#objcopy +objcopy = $(CROSS_COMPILE)objcopy + +#clean +CL = rm -f + +################################################### +.SUFFIXES : .s .c .o + +################################################### +# command + +.PHONY: all +all: $(OUTPUT_FILE_SA0) $(OUTPUT_FILE_SA6) +################################################### +# Linker +################################################### +$(OUTPUT_FILE_SA0) : $(MEMORY_DEF_SA0) $(OBJ_FILE_SA0) + $(LD) $(OBJ_FILE_SA0) \ + -T $(MEMORY_DEF_SA0) \ + -o $(OUTPUT_FILE_SA0) \ + -Map $(FILE_NAME_SA0).map \ + + $(objcopy) -O srec --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3 $(OUTPUT_FILE_SA0) $(FILE_NAME_SA0).srec + $(objcopy) -O binary --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3 $(OUTPUT_FILE_SA0) $(FILE_NAME_SA0).bin + +$(OUTPUT_FILE_SA6) : $(MEMORY_DEF_SA6) $(OBJ_FILE_SA6) + $(LD) $(OBJ_FILE_SA6) \ + -T $(MEMORY_DEF_SA6) \ + -o $(OUTPUT_FILE_SA6) \ + -Map $(FILE_NAME_SA6).map \ + + $(objcopy) -O srec --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3 $(OUTPUT_FILE_SA6) $(FILE_NAME_SA6).srec + $(objcopy) -O binary --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3 $(OUTPUT_FILE_SA6) $(FILE_NAME_SA6).bin + +################################################### +# Compile +################################################### + +%.o:../%.c + $(CC) -c -I $< -o $@ + +.PHONY: clean +clean: + $(CL) *.bin *.map *.srec *.elf *.o diff --git a/tools/renesas/rzg_layout_create/sa0.c b/tools/renesas/rzg_layout_create/sa0.c new file mode 100644 index 000000000..763d3a536 --- /dev/null +++ b/tools/renesas/rzg_layout_create/sa0.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#define RCAR_SA0_SIZE_SMALL (0) /* for RZ/G2E */ +#define RCAR_SA0_SIZE_NORMAL (1) /* for RZ/G2[HMN] */ + +#define BL2_ADDRESS (0xE6304000) /* BL2 start address */ + +#if (RCAR_SA0_SIZE == RCAR_SA0_SIZE_SMALL) +#define BL2_SIZE (80*1024/4) /* BL2 size is 80KB(0x00005000) */ +#else /* (RCAR_SA0_SIZE == RCAR_SA0_SIZE_SMALL) */ +#define BL2_SIZE (170*1024/4) /* BL2 size is 170KB(0x0000AA00) */ +#endif /* (RCAR_SA0_SIZE == RCAR_SA0_SIZE_SMALL) */ + +/* SA0 */ +/* 0x00000000 */ +const unsigned int __attribute__ ((section(".sa0_bootrom"))) bootrom_paramA = 0x00000100; +/* 0x00000080 (Map Type 3 for eMMC Boot)*/ +/* 0x000001D4 */ +const unsigned int __attribute__ ((section(".sa0_bl2dst_addr3"))) bl2dst_addr3 = BL2_ADDRESS; +/* 0x000002E4 */ +const unsigned int __attribute__ ((section(".sa0_bl2dst_size3"))) bl2dst_size3 = BL2_SIZE; +/* 0x00000C00 (Map Type 1 for HyperFlash/QSPI Flash Boot)*/ +/* 0x00000D54 */ +const unsigned int __attribute__ ((section(".sa0_bl2dst_addr1"))) bl2dst_addr1 = BL2_ADDRESS; +/* 0x00000E64 */ +const unsigned int __attribute__ ((section(".sa0_bl2dst_size1"))) bl2dst_size1 = BL2_SIZE; diff --git a/tools/renesas/rzg_layout_create/sa0.ld.S b/tools/renesas/rzg_layout_create/sa0.ld.S new file mode 100644 index 000000000..23e2b237f --- /dev/null +++ b/tools/renesas/rzg_layout_create/sa0.ld.S @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +SECTIONS +{ + . = 0x00000000; + .rodata : { + KEEP(*(.sa0_bootrom)) + /* Map Type 3 for eMMC Boot */ + /* A-side IPL content cert "Start Address" */ + . = 0x000001D4; /* H'00000080 + H'00000154 */ + KEEP(*(.sa0_bl2dst_addr3)) + /* A-side IPL content cert "Size" */ + . = 0x000002E4; /* H'00000080 + H'00000264 */ + KEEP(*(.sa0_bl2dst_size3)) + /* Map Type 1 for HyperFlash/QSPI Flash Boot */ + /* A-side IPL content cert "Start Address" */ + . = 0x00000D54; /* H'00000C00 + H'00000154 */ + KEEP(*(.sa0_bl2dst_addr1)) + /* A-side IPL content cert "Size" */ + . = 0x00000E64; /* H'00000C00 + H'00000264 */ + KEEP(*(.sa0_bl2dst_size1)) + } + +} diff --git a/tools/renesas/rzg_layout_create/sa6.c b/tools/renesas/rzg_layout_create/sa6.c new file mode 100644 index 000000000..76e3dc5e3 --- /dev/null +++ b/tools/renesas/rzg_layout_create/sa6.c @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#define RCAR_SA6_TYPE_QSPIFLASH (0) +#define RCAR_SA6_TYPE_EMMC (1) + +#if (RCAR_SA6_TYPE == RCAR_SA6_TYPE_QSPIFLASH) + +/* Number of content cert for Non-secure Target Program(BL33x) */ +#define RCAR_IMAGE_NUM (0x00000001U) +/* Source address on flash for BL31 */ +#define RCAR_BL31SRC_ADDRESS (0x001C0000U) +/* Reserved */ +#define RCAR_BL31_PARTITION (0x00000000U) +/* Source address on flash for BL32 */ +#define RCAR_BL32SRC_ADDRESS (0x00200000U) +/* Reserved */ +#define RCAR_BL32_PARTITION (0x00000000U) +/* Source address on flash for BL33 */ +#define RCAR_BL33SRC_ADDRESS (0x00300000U) +/* Reserved */ +#define RCAR_BL33_PARTITION (0x00000000U) +#define RCAR_BL332SRC_ADDRESS (0x00000000U) +/* Reserved */ +#define RCAR_BL332_PARTITION (0x00000000U) +#define RCAR_BL333SRC_ADDRESS (0x00000000U) +/* Reserved */ +#define RCAR_BL333_PARTITION (0x00000000U) +#define RCAR_BL334SRC_ADDRESS (0x00000000U) +/* Reserved */ +#define RCAR_BL334_PARTITION (0x00000000U) +#define RCAR_BL335SRC_ADDRESS (0x00000000U) +/* Reserved */ +#define RCAR_BL335_PARTITION (0x00000000U) +#define RCAR_BL336SRC_ADDRESS (0x00000000U) +/* Reserved */ +#define RCAR_BL336_PARTITION (0x00000000U) +#define RCAR_BL337SRC_ADDRESS (0x00000000U) +/* Reserved */ +#define RCAR_BL337_PARTITION (0x00000000U) +#define RCAR_BL338SRC_ADDRESS (0x00000000U) +/* Reserved */ +#define RCAR_BL338_PARTITION (0x00000000U) + +#else /* RCAR_SA6_TYPE == RCAR_SA6_TYPE_EMMC */ + +/* Number of content cert for Non-secure Target Program(BL33x) */ +#define RCAR_IMAGE_NUM (0x00000001U) +/* Source address on eMMC for BL31 */ +#define RCAR_BL31SRC_ADDRESS (0x00040000U) +/* Source partition on eMMC for BL31 */ +#define RCAR_BL31_PARTITION (0x00000001U) +/* Source address on eMMC for BL32 */ +#define RCAR_BL32SRC_ADDRESS (0x00200000U) +/* Source partition on eMMC for BL32 */ +#define RCAR_BL32_PARTITION (0x00000001U) +/* Source address on eMMC for BL33 */ +#define RCAR_BL33SRC_ADDRESS (0x00000000U) +/* Source partition on eMMC for BL33 */ +#define RCAR_BL33_PARTITION (0x00000002U) +/* Reserved */ +#define RCAR_BL332SRC_ADDRESS (0x00000000U) +#define RCAR_BL332_PARTITION (0x00000000U) +/* Reserved */ +#define RCAR_BL333SRC_ADDRESS (0x00000000U) +#define RCAR_BL333_PARTITION (0x00000000U) +/* Reserved */ +#define RCAR_BL334SRC_ADDRESS (0x00000000U) +#define RCAR_BL334_PARTITION (0x00000000U) +/* Reserved */ +#define RCAR_BL335SRC_ADDRESS (0x00000000U) +#define RCAR_BL335_PARTITION (0x00000000U) +/* Reserved */ +#define RCAR_BL336SRC_ADDRESS (0x00000000U) +#define RCAR_BL336_PARTITION (0x00000000U) +/* Reserved */ +#define RCAR_BL337SRC_ADDRESS (0x00000000U) +#define RCAR_BL337_PARTITION (0x00000000U) +/* Reserved */ +#define RCAR_BL338SRC_ADDRESS (0x00000000U) +#define RCAR_BL338_PARTITION (0x00000000U) + +#endif /* RCAR_SA6_TYPE == RCAR_SA6_TYPE_QSPIFLASH */ + +/* Destination address for BL31 */ +#define RCAR_BL31DST_ADDRESS (0x44000000U) +#define RCAR_BL31DST_ADDRESSH (0x00000000U) +/* Destination size for BL31 */ +#define RCAR_BL31DST_SIZE (0x00004000U) +/* Destination address for BL32 */ +#define RCAR_BL32DST_ADDRESS (0x44100000U) +#define RCAR_BL32DST_ADDRESSH (0x00000000U) +/* Destination size for BL32 */ +#define RCAR_BL32DST_SIZE (0x00040000U) +/* Destination address for BL33 */ +#define RCAR_BL33DST_ADDRESS (0x50000000U) +#define RCAR_BL33DST_ADDRESSH (0x00000000U) +/* Destination size for BL33 */ +#define RCAR_BL33DST_SIZE (0x00040000U) +/* Reserved */ +#define RCAR_BL332DST_ADDRESS (0x00000000U) +#define RCAR_BL332DST_ADDRESSH (0x00000000U) +#define RCAR_BL332DST_SIZE (0x00000000U) +/* Reserved */ +#define RCAR_BL333DST_ADDRESS (0x00000000U) +#define RCAR_BL333DST_ADDRESSH (0x00000000U) +#define RCAR_BL333DST_SIZE (0x00000000U) +/* Reserved */ +#define RCAR_BL334DST_ADDRESS (0x00000000U) +#define RCAR_BL334DST_ADDRESSH (0x00000000U) +#define RCAR_BL334DST_SIZE (0x00000000U) +/* Reserved */ +#define RCAR_BL335DST_ADDRESS (0x00000000U) +#define RCAR_BL335DST_ADDRESSH (0x00000000U) +#define RCAR_BL335DST_SIZE (0x00000000U) +/* Reserved */ +#define RCAR_BL336DST_ADDRESS (0x00000000U) +#define RCAR_BL336DST_ADDRESSH (0x00000000U) +#define RCAR_BL336DST_SIZE (0x00000000U) +/* Reserved */ +#define RCAR_BL337DST_ADDRESS (0x00000000U) +#define RCAR_BL337DST_ADDRESSH (0x00000000U) +#define RCAR_BL337DST_SIZE (0x00000000U) +/* Reserved */ +#define RCAR_BL338DST_ADDRESS (0x00000000U) +#define RCAR_BL338DST_ADDRESSH (0x00000000U) +#define RCAR_BL338DST_SIZE (0x00000000U) + +/* SA6 */ +const uint64_t __attribute__ ((section(".sa6_image_num"))) + image_num = RCAR_IMAGE_NUM; +const uint64_t __attribute__ ((section(".sa6_bl31src_addr"))) + bl31src_addr = RCAR_BL31SRC_ADDRESS; +const uint64_t __attribute__ ((section(".sa6_bl31partition"))) + bl31partition = RCAR_BL31_PARTITION; +const uint64_t __attribute__ ((section(".sa6_bl32src_addr"))) + bl32src_addr = RCAR_BL32SRC_ADDRESS; +const uint64_t __attribute__ ((section(".sa6_bl32partition"))) + bl32partition = RCAR_BL32_PARTITION; +const uint64_t __attribute__ ((section(".sa6_bl33src_addr"))) + bl33src_addr = RCAR_BL33SRC_ADDRESS; +const uint64_t __attribute__ ((section(".sa6_bl33partition"))) + bl33partition = RCAR_BL33_PARTITION; +const uint64_t __attribute__ ((section(".sa6_bl332src_addr"))) + bl332src_addr = RCAR_BL332SRC_ADDRESS; +const uint64_t __attribute__ ((section(".sa6_bl332partition"))) + bl332partition = RCAR_BL332_PARTITION; +const uint64_t __attribute__ ((section(".sa6_bl333src_addr"))) + bl333src_addr = RCAR_BL333SRC_ADDRESS; +const uint64_t __attribute__ ((section(".sa6_bl333partition"))) + bl333partition = RCAR_BL333_PARTITION; +const uint64_t __attribute__ ((section(".sa6_bl334src_addr"))) + bl334src_addr = RCAR_BL334SRC_ADDRESS; +const uint64_t __attribute__ ((section(".sa6_bl334partition"))) + bl334partition = RCAR_BL334_PARTITION; +const uint64_t __attribute__ ((section(".sa6_bl335src_addr"))) + bl335src_addr = RCAR_BL335SRC_ADDRESS; +const uint64_t __attribute__ ((section(".sa6_bl335partition"))) + bl335partition = RCAR_BL335_PARTITION; +const uint64_t __attribute__ ((section(".sa6_bl336src_addr"))) + bl336src_addr = RCAR_BL336SRC_ADDRESS; +const uint64_t __attribute__ ((section(".sa6_bl336partition"))) + bl336partition = RCAR_BL336_PARTITION; +const uint64_t __attribute__ ((section(".sa6_bl337src_addr"))) + bl337src_addr = RCAR_BL337SRC_ADDRESS; +const uint64_t __attribute__ ((section(".sa6_bl337partition"))) + bl337partition = RCAR_BL337_PARTITION; +const uint64_t __attribute__ ((section(".sa6_bl338src_addr"))) + bl338src_addr = RCAR_BL338SRC_ADDRESS; +const uint64_t __attribute__ ((section(".sa6_bl338partition"))) + bl338partition = RCAR_BL338_PARTITION; +const uint32_t __attribute__ ((section(".sa6_bl31dst_addr"))) + bl31dst_addr = RCAR_BL31DST_ADDRESS; +const uint32_t __attribute__ ((section(".sa6_bl31dst_addrh"))) + bl31dst_addrh = RCAR_BL31DST_ADDRESSH; +const uint32_t __attribute__ ((section(".sa6_bl31dst_size"))) + bl31dst_size = RCAR_BL31DST_SIZE; +const uint32_t __attribute__ ((section(".sa6_bl32dst_addr"))) + bl32dst_addr = RCAR_BL32DST_ADDRESS; +const uint32_t __attribute__ ((section(".sa6_bl32dst_addrh"))) + bl32dst_addrh = RCAR_BL32DST_ADDRESSH; +const uint32_t __attribute__ ((section(".sa6_bl32dst_size"))) + bl32dst_size = RCAR_BL32DST_SIZE; +const uint32_t __attribute__ ((section(".sa6_bl33dst_addr"))) + bl33dst_addr = RCAR_BL33DST_ADDRESS; +const uint32_t __attribute__ ((section(".sa6_bl33dst_addrh"))) + bl33dst_addrh = RCAR_BL33DST_ADDRESSH; +const uint32_t __attribute__ ((section(".sa6_bl33dst_size"))) + bl33dst_size = RCAR_BL33DST_SIZE; +const uint32_t __attribute__ ((section(".sa6_bl332dst_addr"))) + bl332dst_addr = RCAR_BL332DST_ADDRESS; +const uint32_t __attribute__ ((section(".sa6_bl332dst_addrh"))) + bl332dst_addrh = RCAR_BL332DST_ADDRESSH; +const uint32_t __attribute__ ((section(".sa6_bl332dst_size"))) + bl332dst_size = RCAR_BL332DST_SIZE; +const uint32_t __attribute__ ((section(".sa6_bl333dst_addr"))) + bl333dst_addr = RCAR_BL333DST_ADDRESS; +const uint32_t __attribute__ ((section(".sa6_bl333dst_addrh"))) + bl333dst_addrh = RCAR_BL333DST_ADDRESSH; +const uint32_t __attribute__ ((section(".sa6_bl333dst_size"))) + bl333dst_size = RCAR_BL333DST_SIZE; +const uint32_t __attribute__ ((section(".sa6_bl334dst_addr"))) + bl334dst_addr = RCAR_BL334DST_ADDRESS; +const uint32_t __attribute__ ((section(".sa6_bl334dst_addrh"))) + bl334dst_addrh = RCAR_BL334DST_ADDRESSH; +const uint32_t __attribute__ ((section(".sa6_bl334dst_size"))) + bl334dst_size = RCAR_BL334DST_SIZE; +const uint32_t __attribute__ ((section(".sa6_bl335dst_addr"))) + bl335dst_addr = RCAR_BL335DST_ADDRESS; +const uint32_t __attribute__ ((section(".sa6_bl335dst_addrh"))) + bl335dst_addrh = RCAR_BL335DST_ADDRESSH; +const uint32_t __attribute__ ((section(".sa6_bl335dst_size"))) + bl335dst_size = RCAR_BL335DST_SIZE; +const uint32_t __attribute__ ((section(".sa6_bl336dst_addr"))) + bl336dst_addr = RCAR_BL336DST_ADDRESS; +const uint32_t __attribute__ ((section(".sa6_bl336dst_addrh"))) + bl336dst_addrh = RCAR_BL336DST_ADDRESSH; +const uint32_t __attribute__ ((section(".sa6_bl336dst_size"))) + bl336dst_size = RCAR_BL336DST_SIZE; +const uint32_t __attribute__ ((section(".sa6_bl337dst_addr"))) + bl337dst_addr = RCAR_BL337DST_ADDRESS; +const uint32_t __attribute__ ((section(".sa6_bl337dst_addrh"))) + bl337dst_addrh = RCAR_BL337DST_ADDRESSH; +const uint32_t __attribute__ ((section(".sa6_bl337dst_size"))) + bl337dst_size = RCAR_BL337DST_SIZE; +const uint32_t __attribute__ ((section(".sa6_bl338dst_addr"))) + bl338dst_addr = RCAR_BL338DST_ADDRESS; +const uint32_t __attribute__ ((section(".sa6_bl338dst_addrh"))) + bl338dst_addrh = RCAR_BL338DST_ADDRESSH; +const uint32_t __attribute__ ((section(".sa6_bl338dst_size"))) + bl338dst_size = RCAR_BL338DST_SIZE; diff --git a/tools/renesas/rzg_layout_create/sa6.ld.S b/tools/renesas/rzg_layout_create/sa6.ld.S new file mode 100644 index 000000000..efe40b0c8 --- /dev/null +++ b/tools/renesas/rzg_layout_create/sa6.ld.S @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +SECTIONS +{ + . = 0x00000000; + .rodata : { + KEEP(*(.sa6_image_num)) + . = 0x00000008; + KEEP(*(.sa6_bl31src_addr)) + . = 0x00000010; + KEEP(*(.sa6_bl31partition)) + . = 0x00000018; + KEEP(*(.sa6_bl32src_addr)) + . = 0x00000020; + KEEP(*(.sa6_bl32partition)) + . = 0x00000028; + KEEP(*(.sa6_bl33src_addr)) + . = 0x00000030; + KEEP(*(.sa6_bl33partition)) + . = 0x00000038; + KEEP(*(.sa6_bl332src_addr)) + . = 0x00000040; + KEEP(*(.sa6_bl332partition)) + . = 0x00000048; + KEEP(*(.sa6_bl333src_addr)) + . = 0x00000050; + KEEP(*(.sa6_bl333partition)) + . = 0x00000058; + KEEP(*(.sa6_bl334src_addr)) + . = 0x00000060; + KEEP(*(.sa6_bl334partition)) + . = 0x00000068; + KEEP(*(.sa6_bl335src_addr)) + . = 0x00000070; + KEEP(*(.sa6_bl335partition)) + . = 0x00000078; + KEEP(*(.sa6_bl336src_addr)) + . = 0x00000080; + KEEP(*(.sa6_bl336partition)) + . = 0x00000088; + KEEP(*(.sa6_bl337src_addr)) + . = 0x00000090; + KEEP(*(.sa6_bl337partition)) + . = 0x00000098; + KEEP(*(.sa6_bl338src_addr)) + . = 0x000000A0; + KEEP(*(.sa6_bl338partition)) + . = 0x00000554; + KEEP(*(.sa6_bl31dst_addr)) + . = 0x00000558; + KEEP(*(.sa6_bl31dst_addrh)) + . = 0x00000664; + KEEP(*(.sa6_bl31dst_size)) + . = 0x00000D54; + KEEP(*(.sa6_bl32dst_addr)) + . = 0x00000D58; + KEEP(*(.sa6_bl32dst_addrh)) + . = 0x00000E64; + KEEP(*(.sa6_bl32dst_size)) + . = 0x00001554; + KEEP(*(.sa6_bl33dst_addr)) + . = 0x00001558; + KEEP(*(.sa6_bl33dst_addrh)) + . = 0x00001664; + KEEP(*(.sa6_bl33dst_size)) + . = 0x00001D54; + KEEP(*(.sa6_bl332dst_addr)) + . = 0x00001D58; + KEEP(*(.sa6_bl332dst_addrh)) + . = 0x00001E64; + KEEP(*(.sa6_bl332dst_size)) + . = 0x00002554; + KEEP(*(.sa6_bl333dst_addr)) + . = 0x00002558; + KEEP(*(.sa6_bl333dst_addrh)) + . = 0x00002664; + KEEP(*(.sa6_bl333dst_size)) + . = 0x00002D54; + KEEP(*(.sa6_bl334dst_addr)) + . = 0x00002D58; + KEEP(*(.sa6_bl334dst_addrh)) + . = 0x00002E64; + KEEP(*(.sa6_bl334dst_size)) + . = 0x00003554; + KEEP(*(.sa6_bl335dst_addr)) + . = 0x00003558; + KEEP(*(.sa6_bl335dst_addrh)) + . = 0x00003664; + KEEP(*(.sa6_bl335dst_size)) + . = 0x00003D54; + KEEP(*(.sa6_bl336dst_addr)) + . = 0x00003D58; + KEEP(*(.sa6_bl336dst_addrh)) + . = 0x00003E64; + KEEP(*(.sa6_bl336dst_size)) + . = 0x00004554; + KEEP(*(.sa6_bl337dst_addr)) + . = 0x00004558; + KEEP(*(.sa6_bl337dst_addrh)) + . = 0x00004664; + KEEP(*(.sa6_bl337dst_size)) + . = 0x00004D54; + KEEP(*(.sa6_bl338dst_addr)) + . = 0x00004D58; + KEEP(*(.sa6_bl338dst_addrh)) + . = 0x00004E64; + KEEP(*(.sa6_bl338dst_size)) + } + +} -- cgit v1.2.3 From 5948f47ff9e243935d2c68dddba9d011f61ebd2d Mon Sep 17 00:00:00 2001 From: Biju Das Date: Mon, 7 Dec 2020 16:29:22 +0000 Subject: drivers: renesas: rzg: Add HiHope RZ/G2M board support Add support for HiHope RZ/G2M board. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: Ic8eed0729a42aeee94fc96d16b15b928232488a3 --- drivers/renesas/rzg/board/board.c | 64 +++++++++++++++++++++++++++++++++++++++ drivers/renesas/rzg/board/board.h | 30 ++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 drivers/renesas/rzg/board/board.c create mode 100644 drivers/renesas/rzg/board/board.h diff --git a/drivers/renesas/rzg/board/board.c b/drivers/renesas/rzg/board/board.c new file mode 100644 index 000000000..cfbb04719 --- /dev/null +++ b/drivers/renesas/rzg/board/board.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include + +#include "board.h" +#include "rcar_def.h" + +#ifndef BOARD_DEFAULT +#define BOARD_DEFAULT (BOARD_HIHOPE_RZ_G2M << BOARD_CODE_SHIFT) +#endif /* BOARD_DEFAULT */ + +#define BOARD_CODE_MASK (0xF8U) +#define BOARD_REV_MASK (0x07U) +#define BOARD_CODE_SHIFT (0x03) +#define BOARD_ID_UNKNOWN (0xFFU) + +#define GPIO_INDT5 0xE605500C +#define GP5_19_BIT (0x01U << 19) +#define GP5_21_BIT (0x01U << 21) +#define GP5_25_BIT (0x01U << 25) + +#define HM_ID { 0x10U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU } + +const char *g_board_tbl[] = { + [BOARD_HIHOPE_RZ_G2M] = "HiHope RZ/G2M", + [BOARD_UNKNOWN] = "unknown" +}; + +void rzg_get_board_type(uint32_t *type, uint32_t *rev) +{ + static uint8_t board_id = BOARD_ID_UNKNOWN; + const uint8_t board_tbl[][8] = { + [BOARD_HIHOPE_RZ_G2M] = HM_ID, + }; + uint32_t reg, boardInfo; + + if (board_id == BOARD_ID_UNKNOWN) { + board_id = BOARD_DEFAULT; + } + + *type = ((uint32_t) board_id & BOARD_CODE_MASK) >> BOARD_CODE_SHIFT; + + if (*type >= ARRAY_SIZE(board_tbl)) { + /* no revision information, set Rev0.0. */ + *rev = 0; + } else { + reg = mmio_read_32(RCAR_PRR); + if ((reg & PRR_CUT_MASK) == RCAR_M3_CUT_VER11) { + *rev = board_tbl[*type][(uint8_t)(board_id & BOARD_REV_MASK)]; + } else { + boardInfo = mmio_read_32(GPIO_INDT5) & + (GP5_19_BIT | GP5_21_BIT); + *rev = (((boardInfo & GP5_19_BIT) >> 14) | + ((boardInfo & GP5_21_BIT) >> 17)) + 0x30U; + } + } +} diff --git a/drivers/renesas/rzg/board/board.h b/drivers/renesas/rzg/board/board.h new file mode 100644 index 000000000..c0c3d0cda --- /dev/null +++ b/drivers/renesas/rzg/board/board.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef RZ_G2_BOARD_H +#define RZ_G2_BOARD_H + +enum rzg2_board_id { + BOARD_HIHOPE_RZ_G2M = 0, + BOARD_UNKNOWN +}; + +#define BOARD_REV_UNKNOWN (0xFFU) + +extern const char *g_board_tbl[]; + +/************************************************************************ + * Revisions are expressed in 8 bits. + * The upper 4 bits are major version. + * The lower 4 bits are minor version. + ************************************************************************/ +#define GET_BOARD_MAJOR(a) ((uint32_t)(a) >> 0x4) +#define GET_BOARD_MINOR(a) ((uint32_t)(a) & 0xF) +#define GET_BOARD_NAME(a) (g_board_tbl[(a)]) + +void rzg_get_board_type(uint32_t *type, uint32_t *rev); + +#endif /* RZ_G2_BOARD_H */ -- cgit v1.2.3 From db10bad9ffb2b04c325f7eec021c7cfc75797ca4 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Mon, 7 Dec 2020 16:31:01 +0000 Subject: plat: renesas: rzg: Add HopeRun HiHope RZ/G2M board support The HiHope RZ/G2M board from HopeRun consists of main board (HopeRun HiHope RZ/G2M main board) and sub board(HopeRun HiHope RZ/G2M sub board). The HiHope RZ/G2M sub board sits below the HiHope RZ/G2M main board. This patch adds the required board support to boot HopeRun HiHope RZ/G2M board. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: I3ed55aa4a2cc5c9d9cd6440e087bcd93186520c7 --- plat/renesas/common/bl2_cpg_init.c | 8 +- plat/renesas/common/common.mk | 3 + plat/renesas/rzg/bl2_plat_setup.c | 885 +++++++++++++++++++++++++++++++++++++ plat/renesas/rzg/platform.mk | 222 ++++++++++ 4 files changed, 1114 insertions(+), 4 deletions(-) create mode 100644 plat/renesas/rzg/bl2_plat_setup.c create mode 100644 plat/renesas/rzg/platform.mk diff --git a/plat/renesas/common/bl2_cpg_init.c b/plat/renesas/common/bl2_cpg_init.c index 175434469..677a57d04 100644 --- a/plat/renesas/common/bl2_cpg_init.c +++ b/plat/renesas/common/bl2_cpg_init.c @@ -18,7 +18,7 @@ static void bl2_realtime_cpg_init_h3(void); static void bl2_system_cpg_init_h3(void); #endif -#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_M3) +#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_M3) || (RCAR_LSI == RZ_G2M) static void bl2_realtime_cpg_init_m3(void); static void bl2_system_cpg_init_m3(void); #endif @@ -149,7 +149,7 @@ static void bl2_system_cpg_init_h3(void) } #endif -#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_M3) +#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_M3) || (RCAR_LSI == RZ_G2M) static void bl2_realtime_cpg_init_m3(void) { /* Realtime Module Stop Control Registers */ @@ -362,7 +362,7 @@ void bl2_cpg_init(void) } #elif (RCAR_LSI == RCAR_H3) || (RCAR_LSI == RCAR_H3N) bl2_realtime_cpg_init_h3(); -#elif RCAR_LSI == RCAR_M3 +#elif (RCAR_LSI == RCAR_M3) || (RCAR_LSI == RZ_G2M) bl2_realtime_cpg_init_m3(); #elif RCAR_LSI == RCAR_M3N bl2_realtime_cpg_init_m3n(); @@ -408,7 +408,7 @@ void bl2_system_cpg_init(void) } #elif (RCAR_LSI == RCAR_H3) || (RCAR_LSI == RCAR_H3N) bl2_system_cpg_init_h3(); -#elif RCAR_LSI == RCAR_M3 +#elif (RCAR_LSI == RCAR_M3) || (RCAR_LSI == RZ_G2M) bl2_system_cpg_init_m3(); #elif RCAR_LSI == RCAR_M3N bl2_system_cpg_init_m3n(); diff --git a/plat/renesas/common/common.mk b/plat/renesas/common/common.mk index cadb3d764..984ab5bac 100644 --- a/plat/renesas/common/common.mk +++ b/plat/renesas/common/common.mk @@ -33,6 +33,7 @@ RCAR_H3N:=4 RCAR_D3:=5 RCAR_V3M:=6 RCAR_AUTO:=99 +RZ_G2M:=100 $(eval $(call add_define,RCAR_H3)) $(eval $(call add_define,RCAR_M3)) $(eval $(call add_define,RCAR_M3N)) @@ -41,6 +42,8 @@ $(eval $(call add_define,RCAR_H3N)) $(eval $(call add_define,RCAR_D3)) $(eval $(call add_define,RCAR_V3M)) $(eval $(call add_define,RCAR_AUTO)) +$(eval $(call add_define,RZ_G2M)) + RCAR_CUT_10:=0 RCAR_CUT_11:=1 RCAR_CUT_13:=3 diff --git a/plat/renesas/rzg/bl2_plat_setup.c b/plat/renesas/rzg/bl2_plat_setup.c new file mode 100644 index 000000000..4b3f38bd2 --- /dev/null +++ b/plat/renesas/rzg/bl2_plat_setup.c @@ -0,0 +1,885 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "avs_driver.h" +#include "board.h" +#include "boot_init_dram.h" +#include "cpg_registers.h" +#include "emmc_def.h" +#include "emmc_hal.h" +#include "emmc_std.h" +#include "io_common.h" +#include "io_rcar.h" +#include "qos_init.h" +#include "rcar_def.h" +#include "rcar_private.h" +#include "rcar_version.h" +#include "rom_api.h" + +#define MAX_DRAM_CHANNELS 4 + +#if RCAR_BL2_DCACHE == 1 +/* + * Following symbols are only used during plat_arch_setup() only + * when RCAR_BL2_DCACHE is enabled. + */ +static const uint64_t BL2_RO_BASE = BL_CODE_BASE; +static const uint64_t BL2_RO_LIMIT = BL_CODE_END; + +#if USE_COHERENT_MEM +static const uint64_t BL2_COHERENT_RAM_BASE = BL_COHERENT_RAM_BASE; +static const uint64_t BL2_COHERENT_RAM_LIMIT = BL_COHERENT_RAM_END; +#endif /* USE_COHERENT_MEM */ + +#endif /* RCAR_BL2_DCACHE */ + +extern void plat_rcar_gic_driver_init(void); +extern void plat_rcar_gic_init(void); +extern void bl2_enter_bl31(const struct entry_point_info *bl_ep_info); +extern void bl2_system_cpg_init(void); +extern void bl2_secure_setting(void); +extern void bl2_cpg_init(void); +extern void rcar_io_emmc_setup(void); +extern void rcar_io_setup(void); +extern void rcar_swdt_release(void); +extern void rcar_swdt_init(void); +extern void rcar_rpc_init(void); +extern void rcar_dma_init(void); +extern void rzg_pfc_init(void); + +static void bl2_init_generic_timer(void); + +/* RZ/G2 product check */ +#if RCAR_LSI == RZ_G2M +#define TARGET_PRODUCT PRR_PRODUCT_M3 +#define TARGET_NAME "RZ/G2M" +#elif RCAR_LSI == RCAR_AUTO +#define TARGET_NAME "RZ/G2M" +#endif /* RCAR_LSI == RZ_G2M */ + +#define GPIO_INDT (GPIO_INDT1) +#define GPIO_BKUP_TRG_SHIFT (1U << 8U) + +CASSERT((PARAMS_BASE + sizeof(bl2_to_bl31_params_mem_t) + 0x100) + < (RCAR_SHARED_MEM_BASE + RCAR_SHARED_MEM_SIZE), + assert_bl31_params_do_not_fit_in_shared_memory); + +static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE); + +/* FDT with DRAM configuration */ +uint64_t fdt_blob[PAGE_SIZE_4KB / sizeof(uint64_t)]; +static void *fdt = (void *)fdt_blob; + +static void unsigned_num_print(uint64_t unum, unsigned int radix, char *string) +{ + /* Just need enough space to store 64 bit decimal integer */ + char num_buf[20]; + int i = 0; + unsigned int rem; + + do { + rem = unum % radix; + if (rem < 0xaU) { + num_buf[i] = '0' + rem; + } else { + num_buf[i] = 'a' + (rem - 0xaU); + } + i++; + unum /= radix; + } while (unum > 0U); + + while (--i >= 0) { + *string++ = num_buf[i]; + } + *string = 0; +} + +#if RCAR_LOSSY_ENABLE == 1 +typedef struct bl2_lossy_info { + uint32_t magic; + uint32_t a0; + uint32_t b0; +} bl2_lossy_info_t; + +static void bl2_lossy_gen_fdt(uint32_t no, uint64_t start_addr, + uint64_t end_addr, uint32_t format, + uint32_t enable, int fcnlnode) +{ + const uint64_t fcnlsize = cpu_to_fdt64(end_addr - start_addr); + char nodename[40] = { 0 }; + int ret, node; + + /* Ignore undefined addresses */ + if (start_addr == 0UL && end_addr == 0UL) { + return; + } + + snprintf(nodename, sizeof(nodename), "lossy-decompression@"); + unsigned_num_print(start_addr, 16, nodename + strlen(nodename)); + + node = ret = fdt_add_subnode(fdt, fcnlnode, nodename); + if (ret < 0) { + NOTICE("BL2: Cannot create FCNL node (ret=%i)\n", ret); + panic(); + } + + ret = fdt_setprop_string(fdt, node, "compatible", + "renesas,lossy-decompression"); + if (ret < 0) { + NOTICE("BL2: Cannot add FCNL compat string %s (ret=%i)\n", + "renesas,lossy-decompression", ret); + panic(); + } + + ret = fdt_appendprop_string(fdt, node, "compatible", + "shared-dma-pool"); + if (ret < 0) { + NOTICE("BL2: Cannot append FCNL compat string %s (ret=%i)\n", + "shared-dma-pool", ret); + panic(); + } + + ret = fdt_setprop_u64(fdt, node, "reg", start_addr); + if (ret < 0) { + NOTICE("BL2: Cannot add FCNL reg prop (ret=%i)\n", ret); + panic(); + } + + ret = fdt_appendprop(fdt, node, "reg", &fcnlsize, sizeof(fcnlsize)); + if (ret < 0) { + NOTICE("BL2: Cannot append FCNL reg size prop (ret=%i)\n", ret); + panic(); + } + + ret = fdt_setprop(fdt, node, "no-map", NULL, 0); + if (ret < 0) { + NOTICE("BL2: Cannot add FCNL no-map prop (ret=%i)\n", ret); + panic(); + } + + ret = fdt_setprop_u32(fdt, node, "renesas,formats", format); + if (ret < 0) { + NOTICE("BL2: Cannot add FCNL formats prop (ret=%i)\n", ret); + panic(); + } +} + +static void bl2_lossy_setting(uint32_t no, uint64_t start_addr, + uint64_t end_addr, uint32_t format, + uint32_t enable, int fcnlnode) +{ + bl2_lossy_info_t info; + uint32_t reg; + + bl2_lossy_gen_fdt(no, start_addr, end_addr, format, enable, fcnlnode); + + reg = format | (start_addr >> 20); + mmio_write_32(AXI_DCMPAREACRA0 + 0x8U * no, reg); + mmio_write_32(AXI_DCMPAREACRB0 + 0x8U * no, end_addr >> 20); + mmio_write_32(AXI_DCMPAREACRA0 + 0x8U * no, reg | enable); + + info.magic = 0x12345678U; + info.a0 = mmio_read_32(AXI_DCMPAREACRA0 + 0x8U * no); + info.b0 = mmio_read_32(AXI_DCMPAREACRB0 + 0x8U * no); + + mmio_write_32(LOSSY_PARAMS_BASE + sizeof(info) * no, info.magic); + mmio_write_32(LOSSY_PARAMS_BASE + sizeof(info) * no + 0x4U, info.a0); + mmio_write_32(LOSSY_PARAMS_BASE + sizeof(info) * no + 0x8U, info.b0); + + NOTICE(" Entry %d: DCMPAREACRAx:0x%x DCMPAREACRBx:0x%x\n", no, + mmio_read_32(AXI_DCMPAREACRA0 + 0x8U * no), + mmio_read_32(AXI_DCMPAREACRB0 + 0x8U * no)); +} +#endif /* RCAR_LOSSY_ENABLE == 1 */ + +void bl2_plat_flush_bl31_params(void) +{ + uint32_t product_cut, product, cut; + uint32_t boot_dev, boot_cpu; + uint32_t reg; + + reg = mmio_read_32(RCAR_MODEMR); + boot_dev = reg & MODEMR_BOOT_DEV_MASK; + + if (boot_dev == MODEMR_BOOT_DEV_EMMC_25X1 || + boot_dev == MODEMR_BOOT_DEV_EMMC_50X8) { + emmc_terminate(); + } + + if ((reg & MODEMR_BOOT_CPU_MASK) != MODEMR_BOOT_CPU_CR7) { + bl2_secure_setting(); + } + + reg = mmio_read_32(RCAR_PRR); + product_cut = reg & (PRR_PRODUCT_MASK | PRR_CUT_MASK); + product = reg & PRR_PRODUCT_MASK; + cut = reg & PRR_CUT_MASK; + + if (!((product == PRR_PRODUCT_M3 && cut < PRR_PRODUCT_30) || + (product == PRR_PRODUCT_H3 && cut < PRR_PRODUCT_20))) { + /* Disable MFIS write protection */ + mmio_write_32(MFISWPCNTR, MFISWPCNTR_PASSWORD | 1U); + } + + reg = mmio_read_32(RCAR_MODEMR); + boot_cpu = reg & MODEMR_BOOT_CPU_MASK; + if (boot_cpu == MODEMR_BOOT_CPU_CA57 || + boot_cpu == MODEMR_BOOT_CPU_CA53) { + if (product_cut == PRR_PRODUCT_H3_CUT20) { + mmio_write_32(IPMMUVI0_IMSCTLR, IMSCTLR_DISCACHE); + mmio_write_32(IPMMUVI1_IMSCTLR, IMSCTLR_DISCACHE); + mmio_write_32(IPMMUPV0_IMSCTLR, IMSCTLR_DISCACHE); + mmio_write_32(IPMMUPV1_IMSCTLR, IMSCTLR_DISCACHE); + mmio_write_32(IPMMUPV2_IMSCTLR, IMSCTLR_DISCACHE); + mmio_write_32(IPMMUPV3_IMSCTLR, IMSCTLR_DISCACHE); + } else if (product_cut == (PRR_PRODUCT_M3N | PRR_PRODUCT_10) || + product_cut == (PRR_PRODUCT_M3N | PRR_PRODUCT_11)) { + mmio_write_32(IPMMUVI0_IMSCTLR, IMSCTLR_DISCACHE); + mmio_write_32(IPMMUPV0_IMSCTLR, IMSCTLR_DISCACHE); + } else if ((product_cut == (PRR_PRODUCT_E3 | PRR_PRODUCT_10)) || + (product_cut == (PRR_PRODUCT_E3 | PRR_PRODUCT_11))) { + mmio_write_32(IPMMUVI0_IMSCTLR, IMSCTLR_DISCACHE); + mmio_write_32(IPMMUVP0_IMSCTLR, IMSCTLR_DISCACHE); + mmio_write_32(IPMMUPV0_IMSCTLR, IMSCTLR_DISCACHE); + } + + if (product_cut == (PRR_PRODUCT_H3_CUT20) || + product_cut == (PRR_PRODUCT_M3N | PRR_PRODUCT_10) || + product_cut == (PRR_PRODUCT_M3N | PRR_PRODUCT_11) || + product_cut == (PRR_PRODUCT_E3 | PRR_PRODUCT_10)) { + mmio_write_32(IPMMUHC_IMSCTLR, IMSCTLR_DISCACHE); + mmio_write_32(IPMMURT_IMSCTLR, IMSCTLR_DISCACHE); + mmio_write_32(IPMMUMP_IMSCTLR, IMSCTLR_DISCACHE); + + mmio_write_32(IPMMUDS0_IMSCTLR, IMSCTLR_DISCACHE); + mmio_write_32(IPMMUDS1_IMSCTLR, IMSCTLR_DISCACHE); + } + } + + mmio_write_32(IPMMUMM_IMSCTLR, IPMMUMM_IMSCTLR_ENABLE); + mmio_write_32(IPMMUMM_IMAUXCTLR, IPMMUMM_IMAUXCTLR_NMERGE40_BIT); + + rcar_swdt_release(); + bl2_system_cpg_init(); + +#if RCAR_BL2_DCACHE == 1 + /* Disable data cache (clean and invalidate) */ + disable_mmu_el3(); +#endif /* RCAR_BL2_DCACHE == 1 */ +} + +static uint32_t is_ddr_backup_mode(void) +{ +#if RCAR_SYSTEM_SUSPEND + static uint32_t reason = RCAR_COLD_BOOT; + static uint32_t once; + + if (once != 0U) { + return reason; + } + + once = 1; + if ((mmio_read_32(GPIO_INDT) & GPIO_BKUP_TRG_SHIFT) == 0U) { + return reason; + } + + reason = RCAR_WARM_BOOT; + return reason; +#else /* RCAR_SYSTEM_SUSPEND */ + return RCAR_COLD_BOOT; +#endif /* RCAR_SYSTEM_SUSPEND */ +} + +int bl2_plat_handle_pre_image_load(unsigned int image_id) +{ + u_register_t *boot_kind = (void *)BOOT_KIND_BASE; + bl_mem_params_node_t *bl_mem_params; + + if (image_id != BL31_IMAGE_ID) { + return 0; + } + + bl_mem_params = get_bl_mem_params_node(image_id); + + if (is_ddr_backup_mode() != RCAR_COLD_BOOT) { + *boot_kind = RCAR_WARM_BOOT; + flush_dcache_range(BOOT_KIND_BASE, sizeof(*boot_kind)); + + console_flush(); + bl2_plat_flush_bl31_params(); + + /* will not return */ + bl2_enter_bl31(&bl_mem_params->ep_info); + } + + *boot_kind = RCAR_COLD_BOOT; + flush_dcache_range(BOOT_KIND_BASE, sizeof(*boot_kind)); + + return 0; +} + +static uint64_t rzg_get_dest_addr_from_cert(uint32_t certid, uintptr_t *dest) +{ + uint32_t cert, len; + int err; + + err = rcar_get_certificate(certid, &cert); + if (err != 0) { + ERROR("%s : cert file load error", __func__); + return 1U; + } + + rcar_read_certificate((uint64_t)cert, &len, dest); + + return 0U; +} + +int bl2_plat_handle_post_image_load(unsigned int image_id) +{ + static bl2_to_bl31_params_mem_t *params; + bl_mem_params_node_t *bl_mem_params; + uintptr_t dest; + uint64_t ret; + + if (params == NULL) { + params = (bl2_to_bl31_params_mem_t *)PARAMS_BASE; + memset((void *)PARAMS_BASE, 0, sizeof(*params)); + } + + bl_mem_params = get_bl_mem_params_node(image_id); + + switch (image_id) { + case BL31_IMAGE_ID: + ret = rzg_get_dest_addr_from_cert(SOC_FW_CONTENT_CERT_ID, + &dest); + if (ret == 0U) { + bl_mem_params->image_info.image_base = dest; + } + break; + case BL32_IMAGE_ID: + ret = rzg_get_dest_addr_from_cert(TRUSTED_OS_FW_CONTENT_CERT_ID, + &dest); + if (ret == 0U) { + bl_mem_params->image_info.image_base = dest; + } + + memcpy(¶ms->bl32_ep_info, &bl_mem_params->ep_info, + sizeof(entry_point_info_t)); + break; + case BL33_IMAGE_ID: + memcpy(¶ms->bl33_ep_info, &bl_mem_params->ep_info, + sizeof(entry_point_info_t)); + break; + default: + break; + } + + return 0; +} + +struct meminfo *bl2_plat_sec_mem_layout(void) +{ + return &bl2_tzram_layout; +} + +static void bl2_populate_compatible_string(void *dt) +{ + uint32_t board_type; + uint32_t board_rev; + uint32_t reg; + int ret; + + fdt_setprop_u32(dt, 0, "#address-cells", 2); + fdt_setprop_u32(dt, 0, "#size-cells", 2); + + /* Populate compatible string */ + rzg_get_board_type(&board_type, &board_rev); + switch (board_type) { + case BOARD_HIHOPE_RZ_G2M: + ret = fdt_setprop_string(dt, 0, "compatible", + "hoperun,hihope-rzg2m"); + break; + default: + NOTICE("BL2: Cannot set compatible string, board unsupported\n"); + panic(); + break; + } + + if (ret < 0) { + NOTICE("BL2: Cannot set compatible string (ret=%i)\n", ret); + panic(); + } + + reg = mmio_read_32(RCAR_PRR); + switch (reg & PRR_PRODUCT_MASK) { + case PRR_PRODUCT_M3: + ret = fdt_appendprop_string(dt, 0, "compatible", + "renesas,r8a774a1"); + break; + default: + NOTICE("BL2: Cannot set compatible string, SoC unsupported\n"); + panic(); + break; + } + + if (ret < 0) { + NOTICE("BL2: Cannot set compatible string (ret=%i)\n", ret); + panic(); + } +} + +static void bl2_advertise_dram_entries(uint64_t dram_config[8]) +{ + char nodename[32] = { 0 }; + uint64_t start, size; + uint64_t fdtsize; + int ret, node, chan; + + for (chan = 0; chan < MAX_DRAM_CHANNELS; chan++) { + start = dram_config[2 * chan]; + size = dram_config[2 * chan + 1]; + if (size == 0U) { + continue; + } + + NOTICE("BL2: CH%d: %llx - %llx, %lld %siB\n", + chan, start, start + size - 1U, + (size >> 30) ? : size >> 20, + (size >> 30) ? "G" : "M"); + } + + /* + * We add the DT nodes in reverse order here. The fdt_add_subnode() + * adds the DT node before the first existing DT node, so we have + * to add them in reverse order to get nodes sorted by address in + * the resulting DT. + */ + for (chan = MAX_DRAM_CHANNELS - 1; chan >= 0; chan--) { + start = dram_config[2 * chan]; + size = dram_config[2 * chan + 1]; + if (size == 0U) { + continue; + } + + /* + * Channel 0 is mapped in 32bit space and the first + * 128 MiB are reserved + */ + if (chan == 0) { + start = 0x48000000U; + size -= 0x8000000U; + } + + fdtsize = cpu_to_fdt64(size); + + snprintf(nodename, sizeof(nodename), "memory@"); + unsigned_num_print(start, 16, nodename + strlen(nodename)); + node = ret = fdt_add_subnode(fdt, 0, nodename); + if (ret < 0) { + goto err; + } + + ret = fdt_setprop_string(fdt, node, "device_type", "memory"); + if (ret < 0) { + goto err; + } + + ret = fdt_setprop_u64(fdt, node, "reg", start); + if (ret < 0) { + goto err; + } + + ret = fdt_appendprop(fdt, node, "reg", &fdtsize, + sizeof(fdtsize)); + if (ret < 0) { + goto err; + } + } + + return; +err: + NOTICE("BL2: Cannot add memory node to FDT (ret=%i)\n", ret); + panic(); +} + +static void bl2_advertise_dram_size(uint32_t product) +{ + uint64_t dram_config[8] = { + [0] = 0x400000000ULL, + [2] = 0x500000000ULL, + [4] = 0x600000000ULL, + [6] = 0x700000000ULL, + }; + + switch (product) { + case PRR_PRODUCT_M3: + /* 4GB(2GBx2 2ch split) */ + dram_config[1] = 0x80000000ULL; + dram_config[5] = 0x80000000ULL; + break; + default: + NOTICE("BL2: Detected invalid DRAM entries\n"); + break; + } + + bl2_advertise_dram_entries(dram_config); +} + +void bl2_el3_early_platform_setup(u_register_t arg1, u_register_t arg2, + u_register_t arg3, u_register_t arg4) +{ + uint32_t reg, midr, boot_dev, boot_cpu, type, rev; + uint32_t product, product_cut, major, minor; + int32_t ret; + const char *str; + const char *unknown = "unknown"; + const char *cpu_ca57 = "CA57"; + const char *cpu_ca53 = "CA53"; + const char *product_g2m = "G2M"; + const char *boot_hyper80 = "HyperFlash(80MHz)"; + const char *boot_qspi40 = "QSPI Flash(40MHz)"; + const char *boot_qspi80 = "QSPI Flash(80MHz)"; + const char *boot_emmc25x1 = "eMMC(25MHz x1)"; + const char *boot_emmc50x8 = "eMMC(50MHz x8)"; + const char *boot_hyper160 = "HyperFlash(160MHz)"; +#if RZG_LCS_STATE_DETECTION_ENABLE + uint32_t lcs; + const char *lcs_secure = "SE"; + const char *lcs_cm = "CM"; + const char *lcs_dm = "DM"; + const char *lcs_sd = "SD"; + const char *lcs_fa = "FA"; +#endif /* RZG_LCS_STATE_DETECTION_ENABLE */ + +#if (RCAR_LOSSY_ENABLE == 1) + int fcnlnode; +#endif /* (RCAR_LOSSY_ENABLE == 1) */ + + bl2_init_generic_timer(); + + reg = mmio_read_32(RCAR_MODEMR); + boot_dev = reg & MODEMR_BOOT_DEV_MASK; + boot_cpu = reg & MODEMR_BOOT_CPU_MASK; + + bl2_cpg_init(); + + if (boot_cpu == MODEMR_BOOT_CPU_CA57 || + boot_cpu == MODEMR_BOOT_CPU_CA53) { + rzg_pfc_init(); + rcar_console_boot_init(); + } + + plat_rcar_gic_driver_init(); + plat_rcar_gic_init(); + rcar_swdt_init(); + + /* FIQ interrupts are taken to EL3 */ + write_scr_el3(read_scr_el3() | SCR_FIQ_BIT); + + write_daifclr(DAIF_FIQ_BIT); + + reg = read_midr(); + midr = reg & (MIDR_PN_MASK << MIDR_PN_SHIFT); + switch (midr) { + case MIDR_CA57: + str = cpu_ca57; + break; + case MIDR_CA53: + str = cpu_ca53; + break; + default: + str = unknown; + break; + } + + NOTICE("BL2: RZ/G2 Initial Program Loader(%s) Rev.%s\n", str, + version_of_renesas); + + reg = mmio_read_32(RCAR_PRR); + product_cut = reg & (PRR_PRODUCT_MASK | PRR_CUT_MASK); + product = reg & PRR_PRODUCT_MASK; + + switch (product) { + case PRR_PRODUCT_M3: + str = product_g2m; + break; + default: + str = unknown; + break; + } + + if ((product == PRR_PRODUCT_M3) && + ((reg & RCAR_MAJOR_MASK) == PRR_PRODUCT_20)) { + if ((reg & PRR_CUT_MASK) == RCAR_M3_CUT_VER11) { + /* M3 Ver.1.1 or Ver.1.2 */ + NOTICE("BL2: PRR is RZ/%s Ver.1.1 / Ver.1.2\n", str); + } else { + NOTICE("BL2: PRR is RZ/%s Ver.1.%d\n", str, + (reg & RCAR_MINOR_MASK) + RCAR_M3_MINOR_OFFSET); + } + } else { + major = (reg & RCAR_MAJOR_MASK) >> RCAR_MAJOR_SHIFT; + major = major + RCAR_MAJOR_OFFSET; + minor = reg & RCAR_MINOR_MASK; + NOTICE("BL2: PRR is RZ/%s Ver.%d.%d\n", str, major, minor); + } + + rzg_get_board_type(&type, &rev); + + switch (type) { + case BOARD_HIHOPE_RZ_G2M: + break; + default: + type = BOARD_UNKNOWN; + break; + } + + if (type == BOARD_UNKNOWN || rev == BOARD_REV_UNKNOWN) { + NOTICE("BL2: Board is %s Rev.---\n", GET_BOARD_NAME(type)); + } else { + NOTICE("BL2: Board is %s Rev.%d.%d\n", + GET_BOARD_NAME(type), + GET_BOARD_MAJOR(rev), GET_BOARD_MINOR(rev)); + } + +#if RCAR_LSI != RCAR_AUTO + if (product != TARGET_PRODUCT) { + ERROR("BL2: IPL was been built for the %s.\n", TARGET_NAME); + ERROR("BL2: Please write the correct IPL to flash memory.\n"); + panic(); + } +#endif /* RCAR_LSI != RCAR_AUTO */ + rcar_avs_init(); + rcar_avs_setting(); + + switch (boot_dev) { + case MODEMR_BOOT_DEV_HYPERFLASH160: + str = boot_hyper160; + break; + case MODEMR_BOOT_DEV_HYPERFLASH80: + str = boot_hyper80; + break; + case MODEMR_BOOT_DEV_QSPI_FLASH40: + str = boot_qspi40; + break; + case MODEMR_BOOT_DEV_QSPI_FLASH80: + str = boot_qspi80; + break; + case MODEMR_BOOT_DEV_EMMC_25X1: + str = boot_emmc25x1; + break; + case MODEMR_BOOT_DEV_EMMC_50X8: + str = boot_emmc50x8; + break; + default: + str = unknown; + break; + } + NOTICE("BL2: Boot device is %s\n", str); + + rcar_avs_setting(); + +#if RZG_LCS_STATE_DETECTION_ENABLE + reg = rcar_rom_get_lcs(&lcs); + if (reg != 0U) { + str = unknown; + goto lcm_state; + } + + switch (lcs) { + case LCS_CM: + str = lcs_cm; + break; + case LCS_DM: + str = lcs_dm; + break; + case LCS_SD: + str = lcs_sd; + break; + case LCS_SE: + str = lcs_secure; + break; + case LCS_FA: + str = lcs_fa; + break; + default: + str = unknown; + break; + } + +lcm_state: + NOTICE("BL2: LCM state is %s\n", str); +#endif /* RZG_LCS_STATE_DETECTION_ENABLE */ + + rcar_avs_end(); + is_ddr_backup_mode(); + + bl2_tzram_layout.total_base = BL31_BASE; + bl2_tzram_layout.total_size = BL31_LIMIT - BL31_BASE; + + if (boot_cpu == MODEMR_BOOT_CPU_CA57 || + boot_cpu == MODEMR_BOOT_CPU_CA53) { + ret = rzg_dram_init(); + if (ret != 0) { + NOTICE("BL2: Failed to DRAM initialize (%d).\n", ret); + panic(); + } + rzg_qos_init(); + } + + /* Set up FDT */ + ret = fdt_create_empty_tree(fdt, sizeof(fdt_blob)); + if (ret != 0) { + NOTICE("BL2: Cannot allocate FDT for U-Boot (ret=%i)\n", ret); + panic(); + } + + /* Add platform compatible string */ + bl2_populate_compatible_string(fdt); + + /* Print DRAM layout */ + bl2_advertise_dram_size(product); + + if (boot_dev == MODEMR_BOOT_DEV_EMMC_25X1 || + boot_dev == MODEMR_BOOT_DEV_EMMC_50X8) { + if (rcar_emmc_init() != EMMC_SUCCESS) { + NOTICE("BL2: Failed to eMMC driver initialize.\n"); + panic(); + } + rcar_emmc_memcard_power(EMMC_POWER_ON); + if (rcar_emmc_mount() != EMMC_SUCCESS) { + NOTICE("BL2: Failed to eMMC mount operation.\n"); + panic(); + } + } else { + rcar_rpc_init(); + rcar_dma_init(); + } + + reg = mmio_read_32(RST_WDTRSTCR); + reg &= ~WDTRSTCR_RWDT_RSTMSK; + reg |= WDTRSTCR_PASSWORD; + mmio_write_32(RST_WDTRSTCR, reg); + + mmio_write_32(CPG_CPGWPR, CPGWPR_PASSWORD); + mmio_write_32(CPG_CPGWPCR, CPGWPCR_PASSWORD); + + reg = mmio_read_32(RCAR_PRR); + if ((reg & RCAR_CPU_MASK_CA57) == RCAR_CPU_HAVE_CA57) { + mmio_write_32(CPG_CA57DBGRCR, + DBGCPUPREN | mmio_read_32(CPG_CA57DBGRCR)); + } + + if ((reg & RCAR_CPU_MASK_CA53) == RCAR_CPU_HAVE_CA53) { + mmio_write_32(CPG_CA53DBGRCR, + DBGCPUPREN | mmio_read_32(CPG_CA53DBGRCR)); + } + + if (product_cut == PRR_PRODUCT_H3_CUT10) { + reg = mmio_read_32(CPG_PLL2CR); + reg &= ~((uint32_t)1 << 5); + mmio_write_32(CPG_PLL2CR, reg); + + reg = mmio_read_32(CPG_PLL4CR); + reg &= ~((uint32_t)1 << 5); + mmio_write_32(CPG_PLL4CR, reg); + + reg = mmio_read_32(CPG_PLL0CR); + reg &= ~((uint32_t)1 << 12); + mmio_write_32(CPG_PLL0CR, reg); + } +#if (RCAR_LOSSY_ENABLE == 1) + NOTICE("BL2: Lossy Decomp areas\n"); + + fcnlnode = fdt_add_subnode(fdt, 0, "reserved-memory"); + if (fcnlnode < 0) { + NOTICE("BL2: Cannot create reserved mem node (ret=%i)\n", + fcnlnode); + panic(); + } + + bl2_lossy_setting(0, LOSSY_ST_ADDR0, LOSSY_END_ADDR0, + LOSSY_FMT0, LOSSY_ENA_DIS0, fcnlnode); + bl2_lossy_setting(1, LOSSY_ST_ADDR1, LOSSY_END_ADDR1, + LOSSY_FMT1, LOSSY_ENA_DIS1, fcnlnode); + bl2_lossy_setting(2, LOSSY_ST_ADDR2, LOSSY_END_ADDR2, + LOSSY_FMT2, LOSSY_ENA_DIS2, fcnlnode); +#endif /* RCAR_LOSSY_ENABLE */ + + fdt_pack(fdt); + NOTICE("BL2: FDT at %p\n", fdt); + + if (boot_dev == MODEMR_BOOT_DEV_EMMC_25X1 || + boot_dev == MODEMR_BOOT_DEV_EMMC_50X8) { + rcar_io_emmc_setup(); + } else { + rcar_io_setup(); + } +} + +void bl2_el3_plat_arch_setup(void) +{ +#if RCAR_BL2_DCACHE == 1 + NOTICE("BL2: D-Cache enable\n"); + rcar_configure_mmu_el3(BL2_BASE, + BL2_END - BL2_BASE, + BL2_RO_BASE, BL2_RO_LIMIT +#if USE_COHERENT_MEM + , BL2_COHERENT_RAM_BASE, BL2_COHERENT_RAM_LIMIT +#endif /* USE_COHERENT_MEM */ + ); +#endif /* RCAR_BL2_DCACHE == 1 */ +} + +void bl2_platform_setup(void) +{ + /* + * Place holder for performing any platform initialization specific + * to BL2. + */ +} + +static void bl2_init_generic_timer(void) +{ + uint32_t reg_cntfid; + uint32_t modemr; + uint32_t modemr_pll; + uint32_t pll_table[] = { + EXTAL_MD14_MD13_TYPE_0, /* MD14/MD13 : 0b00 */ + EXTAL_MD14_MD13_TYPE_1, /* MD14/MD13 : 0b01 */ + EXTAL_MD14_MD13_TYPE_2, /* MD14/MD13 : 0b10 */ + EXTAL_MD14_MD13_TYPE_3 /* MD14/MD13 : 0b11 */ + }; + + modemr = mmio_read_32(RCAR_MODEMR); + modemr_pll = (modemr & MODEMR_BOOT_PLL_MASK); + + /* Set frequency data in CNTFID0 */ + reg_cntfid = pll_table[modemr_pll >> MODEMR_BOOT_PLL_SHIFT]; + + /* Update memory mapped and register based frequency */ + write_cntfrq_el0((u_register_t)reg_cntfid); + mmio_write_32(ARM_SYS_CNTCTL_BASE + (uintptr_t)CNTFID_OFF, reg_cntfid); + /* Enable counter */ + mmio_setbits_32(RCAR_CNTC_BASE + (uintptr_t)CNTCR_OFF, + (uint32_t)CNTCR_EN); +} diff --git a/plat/renesas/rzg/platform.mk b/plat/renesas/rzg/platform.mk new file mode 100644 index 000000000..421cbbe64 --- /dev/null +++ b/plat/renesas/rzg/platform.mk @@ -0,0 +1,222 @@ +# +# Copyright (c) 2018-2020, Renesas Electronics Corporation. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +include plat/renesas/common/common.mk + +ifndef LSI + $(error "Error: Unknown LSI. Please use LSI= to specify the LSI") +else + ifeq (${LSI},AUTO) + RCAR_LSI:=${RCAR_AUTO} + else ifeq (${LSI},G2M) + RCAR_LSI:=${RZ_G2M} + ifndef LSI_CUT + # enable compatible function. + RCAR_LSI_CUT_COMPAT := 1 + $(eval $(call add_define,RCAR_LSI_CUT_COMPAT)) + else + # disable compatible function. + ifeq (${LSI_CUT},10) + RCAR_LSI_CUT:=0 + else ifeq (${LSI_CUT},11) + RCAR_LSI_CUT:=1 + else ifeq (${LSI_CUT},13) + RCAR_LSI_CUT:=3 + else ifeq (${LSI_CUT},30) + RCAR_LSI_CUT:=20 + else + $(error "Error: ${LSI_CUT} is not supported.") + endif + $(eval $(call add_define,RCAR_LSI_CUT)) + endif + else + $(error "Error: ${LSI} is not supported.") + endif + $(eval $(call add_define,RCAR_LSI)) +endif + +# Process RZG_LCS_STATE_DETECTION_ENABLE flag +# Enable to get LCS state information +ifndef RZG_LCS_STATE_DETECTION_ENABLE +RZG_LCS_STATE_DETECTION_ENABLE := 0 +endif +$(eval $(call add_define,RZG_LCS_STATE_DETECTION_ENABLE)) + +# Process RCAR_SECURE_BOOT flag +ifndef RCAR_SECURE_BOOT +RCAR_SECURE_BOOT := 0 +endif +$(eval $(call add_define,RCAR_SECURE_BOOT)) + +# LCS state of RZ/G2 Chip is all CM. +# However certain chips(RZ/G2M and RZ/G2E) have incorrect factory Fuse settings +# which results in getting incorrect LCS states +# if need to enable RCAR_SECURE_BOOT, make sure the chip has proper factory Fuse settings. +ifeq (${RCAR_SECURE_BOOT},1) + ifeq (${RZG_LCS_STATE_DETECTION_ENABLE},0) + $(error "Error: Please check the chip has proper factory Fuse settings and set RZG_LCS_STATE_DETECTION_ENABLE to enable.") + endif +endif + +# lock RPC HYPERFLASH access by default +# unlock to repogram the ATF firmware from u-boot +ifndef RCAR_RPC_HYPERFLASH_LOCKED +RCAR_RPC_HYPERFLASH_LOCKED := 1 +endif +$(eval $(call add_define,RCAR_RPC_HYPERFLASH_LOCKED)) + +# Process RCAR_QOS_TYPE flag +ifndef RCAR_QOS_TYPE +RCAR_QOS_TYPE := 0 +endif +$(eval $(call add_define,RCAR_QOS_TYPE)) + +# Process RCAR_DRAM_SPLIT flag +ifndef RCAR_DRAM_SPLIT +RCAR_DRAM_SPLIT := 0 +endif +$(eval $(call add_define,RCAR_DRAM_SPLIT)) + +# Process RCAR_BL33_EXECUTION_EL flag +ifndef RCAR_BL33_EXECUTION_EL +RCAR_BL33_EXECUTION_EL := 0 +endif +$(eval $(call add_define,RCAR_BL33_EXECUTION_EL)) + +# Process RCAR_AVS_SETTING_ENABLE flag +ifndef AVS_SETTING_ENABLE +AVS_SETTING_ENABLE := 0 +endif +$(eval $(call add_define,AVS_SETTING_ENABLE)) + +# Process RCAR_LOSSY_ENABLE flag +ifndef RCAR_LOSSY_ENABLE +RCAR_LOSSY_ENABLE := 0 +endif +$(eval $(call add_define,RCAR_LOSSY_ENABLE)) + +# Process LIFEC_DBSC_PROTECT_ENABLE flag +ifndef LIFEC_DBSC_PROTECT_ENABLE +LIFEC_DBSC_PROTECT_ENABLE := 1 +endif +$(eval $(call add_define,LIFEC_DBSC_PROTECT_ENABLE)) + +# Process RCAR_GEN3_ULCB flag +ifndef RCAR_GEN3_ULCB +RCAR_GEN3_ULCB := 0 +endif + +# Process RCAR_REF_INT flag +ifndef RCAR_REF_INT +RCAR_REF_INT :=0 +endif +$(eval $(call add_define,RCAR_REF_INT)) + +# Process RCAR_REWT_TRAINING flag +ifndef RCAR_REWT_TRAINING +RCAR_REWT_TRAINING := 1 +endif +$(eval $(call add_define,RCAR_REWT_TRAINING)) + +# Process RCAR_SYSTEM_SUSPEND flag +ifndef RCAR_SYSTEM_SUSPEND +RCAR_SYSTEM_SUSPEND := 0 +endif +$(eval $(call add_define,RCAR_SYSTEM_SUSPEND)) + +# Process RCAR_DRAM_LPDDR4_MEMCONF flag +ifndef RCAR_DRAM_LPDDR4_MEMCONF +RCAR_DRAM_LPDDR4_MEMCONF :=1 +endif +$(eval $(call add_define,RCAR_DRAM_LPDDR4_MEMCONF)) + +# Process RCAR_DRAM_DDR3L_MEMCONF flag +ifndef RCAR_DRAM_DDR3L_MEMCONF +RCAR_DRAM_DDR3L_MEMCONF :=1 +endif +$(eval $(call add_define,RCAR_DRAM_DDR3L_MEMCONF)) + +# Process RCAR_DRAM_DDR3L_MEMDUAL flag +ifndef RCAR_DRAM_DDR3L_MEMDUAL +RCAR_DRAM_DDR3L_MEMDUAL :=1 +endif +$(eval $(call add_define,RCAR_DRAM_DDR3L_MEMDUAL)) + +# Process RCAR_BL33_ARG0 flag +ifdef RCAR_BL33_ARG0 +$(eval $(call add_define,RCAR_BL33_ARG0)) +endif + +#Process RCAR_BL2_DCACHE flag +ifndef RCAR_BL2_DCACHE +RCAR_BL2_DCACHE := 0 +endif +$(eval $(call add_define,RCAR_BL2_DCACHE)) + +# Process RCAR_DRAM_CHANNEL flag +ifndef RCAR_DRAM_CHANNEL +RCAR_DRAM_CHANNEL :=15 +endif +$(eval $(call add_define,RCAR_DRAM_CHANNEL)) + +#Process RCAR_SYSTEM_RESET_KEEPON_DDR flag +ifndef RCAR_SYSTEM_RESET_KEEPON_DDR +RCAR_SYSTEM_RESET_KEEPON_DDR := 0 +endif +$(eval $(call add_define,RCAR_SYSTEM_RESET_KEEPON_DDR)) + +include drivers/renesas/rzg/ddr/ddr.mk +include drivers/renesas/rzg/qos/qos.mk +include drivers/renesas/rzg/pfc/pfc.mk +include lib/libfdt/libfdt.mk + +PLAT_INCLUDES += -Idrivers/renesas/rzg/ddr \ + -Idrivers/renesas/rzg/qos \ + -Idrivers/renesas/rzg/board \ + -Idrivers/renesas/common \ + -Idrivers/renesas/common/iic_dvfs \ + -Idrivers/renesas/common/avs \ + -Idrivers/renesas/common/delay \ + -Idrivers/renesas/common/rom \ + -Idrivers/renesas/common/scif \ + -Idrivers/renesas/common/emmc \ + -Idrivers/renesas/common/pwrc \ + -Idrivers/renesas/common/io + +BL2_SOURCES += plat/renesas/rzg/bl2_plat_setup.c \ + drivers/renesas/rzg/board/board.c + +# build the layout images for the bootrom and the necessary srecords +rzg: rzg_layout_create rzg_srecord +distclean realclean clean: clean_layout_tool clean_srecord + +# layout images +LAYOUT_TOOLPATH ?= tools/renesas/rzg_layout_create + +clean_layout_tool: + @echo "clean layout tool" + ${Q}${MAKE} -C ${LAYOUT_TOOLPATH} clean + +.PHONY: rzg_layout_create +rzg_layout_create: + @echo "generating layout srecs" + ${Q}${MAKE} CPPFLAGS="-D=AARCH64" --no-print-directory -C ${LAYOUT_TOOLPATH} + +# srecords +SREC_PATH = ${BUILD_PLAT} +BL2_ELF_SRC = ${SREC_PATH}/bl2/bl2.elf +BL31_ELF_SRC = ${SREC_PATH}/bl31/bl31.elf + +clean_srecord: + @echo "clean bl2 and bl31 srecs" + rm -f ${SREC_PATH}/bl2.srec ${SREC_PATH}/bl31.srec + +.PHONY: rzg_srecord +rzg_srecord: $(BL2_ELF_SRC) $(BL31_ELF_SRC) + @echo "generating srec: ${SREC_PATH}/bl2.srec" + $(Q)$(OC) -O srec --srec-forceS3 ${BL2_ELF_SRC} ${SREC_PATH}/bl2.srec + @echo "generating srec: ${SREC_PATH}/bl31.srec" + $(Q)$(OC) -O srec --srec-forceS3 ${BL31_ELF_SRC} ${SREC_PATH}/bl31.srec -- cgit v1.2.3 From 618522eb22a8cc06124576360ce2618eca750f3a Mon Sep 17 00:00:00 2001 From: Biju Das Date: Mon, 9 Nov 2020 09:40:04 +0000 Subject: renesas: rzg: Add PFC support for RZ/G2M Add pin control support for RZ/G2M SoC. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: I08719015cab1ec59e2270523980a0a3e26e72c01 --- drivers/renesas/rzg/pfc/G2M/pfc_init_g2m.c | 1300 ++++++++++++++++++++++++++++ drivers/renesas/rzg/pfc/G2M/pfc_init_g2m.h | 12 + drivers/renesas/rzg/pfc/pfc.mk | 20 + drivers/renesas/rzg/pfc/pfc_init.c | 72 ++ 4 files changed, 1404 insertions(+) create mode 100644 drivers/renesas/rzg/pfc/G2M/pfc_init_g2m.c create mode 100644 drivers/renesas/rzg/pfc/G2M/pfc_init_g2m.h create mode 100644 drivers/renesas/rzg/pfc/pfc.mk create mode 100644 drivers/renesas/rzg/pfc/pfc_init.c diff --git a/drivers/renesas/rzg/pfc/G2M/pfc_init_g2m.c b/drivers/renesas/rzg/pfc/G2M/pfc_init_g2m.c new file mode 100644 index 000000000..f76b83f9a --- /dev/null +++ b/drivers/renesas/rzg/pfc/G2M/pfc_init_g2m.c @@ -0,0 +1,1300 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include /* for uint32_t */ + +#include + +#include "pfc_init_g2m.h" +#include "rcar_def.h" +#include "rcar_private.h" +#include "pfc_regs.h" + +#define GPSR0_D15 BIT(15) +#define GPSR0_D14 BIT(14) +#define GPSR0_D13 BIT(13) +#define GPSR0_D12 BIT(12) +#define GPSR0_D11 BIT(11) +#define GPSR0_D10 BIT(10) +#define GPSR0_D9 BIT(9) +#define GPSR0_D8 BIT(8) +#define GPSR0_D7 BIT(7) +#define GPSR0_D6 BIT(6) +#define GPSR0_D5 BIT(5) +#define GPSR0_D4 BIT(4) +#define GPSR0_D3 BIT(3) +#define GPSR0_D2 BIT(2) +#define GPSR0_D1 BIT(1) +#define GPSR0_D0 BIT(0) +#define GPSR1_CLKOUT BIT(28) +#define GPSR1_EX_WAIT0_A BIT(27) +#define GPSR1_WE1 BIT(26) +#define GPSR1_WE0 BIT(25) +#define GPSR1_RD_WR BIT(24) +#define GPSR1_RD BIT(23) +#define GPSR1_BS BIT(22) +#define GPSR1_CS1_A26 BIT(21) +#define GPSR1_CS0 BIT(20) +#define GPSR1_A19 BIT(19) +#define GPSR1_A18 BIT(18) +#define GPSR1_A17 BIT(17) +#define GPSR1_A16 BIT(16) +#define GPSR1_A15 BIT(15) +#define GPSR1_A14 BIT(14) +#define GPSR1_A13 BIT(13) +#define GPSR1_A12 BIT(12) +#define GPSR1_A11 BIT(11) +#define GPSR1_A10 BIT(10) +#define GPSR1_A9 BIT(9) +#define GPSR1_A8 BIT(8) +#define GPSR1_A7 BIT(7) +#define GPSR1_A6 BIT(6) +#define GPSR1_A5 BIT(5) +#define GPSR1_A4 BIT(4) +#define GPSR1_A3 BIT(3) +#define GPSR1_A2 BIT(2) +#define GPSR1_A1 BIT(1) +#define GPSR1_A0 BIT(0) +#define GPSR2_AVB_AVTP_CAPTURE_A BIT(14) +#define GPSR2_AVB_AVTP_MATCH_A BIT(13) +#define GPSR2_AVB_LINK BIT(12) +#define GPSR2_AVB_PHY_INT BIT(11) +#define GPSR2_AVB_MAGIC BIT(10) +#define GPSR2_AVB_MDC BIT(9) +#define GPSR2_PWM2_A BIT(8) +#define GPSR2_PWM1_A BIT(7) +#define GPSR2_PWM0 BIT(6) +#define GPSR2_IRQ5 BIT(5) +#define GPSR2_IRQ4 BIT(4) +#define GPSR2_IRQ3 BIT(3) +#define GPSR2_IRQ2 BIT(2) +#define GPSR2_IRQ1 BIT(1) +#define GPSR2_IRQ0 BIT(0) +#define GPSR3_SD1_WP BIT(15) +#define GPSR3_SD1_CD BIT(14) +#define GPSR3_SD0_WP BIT(13) +#define GPSR3_SD0_CD BIT(12) +#define GPSR3_SD1_DAT3 BIT(11) +#define GPSR3_SD1_DAT2 BIT(10) +#define GPSR3_SD1_DAT1 BIT(9) +#define GPSR3_SD1_DAT0 BIT(8) +#define GPSR3_SD1_CMD BIT(7) +#define GPSR3_SD1_CLK BIT(6) +#define GPSR3_SD0_DAT3 BIT(5) +#define GPSR3_SD0_DAT2 BIT(4) +#define GPSR3_SD0_DAT1 BIT(3) +#define GPSR3_SD0_DAT0 BIT(2) +#define GPSR3_SD0_CMD BIT(1) +#define GPSR3_SD0_CLK BIT(0) +#define GPSR4_SD3_DS BIT(17) +#define GPSR4_SD3_DAT7 BIT(16) +#define GPSR4_SD3_DAT6 BIT(15) +#define GPSR4_SD3_DAT5 BIT(14) +#define GPSR4_SD3_DAT4 BIT(13) +#define GPSR4_SD3_DAT3 BIT(12) +#define GPSR4_SD3_DAT2 BIT(11) +#define GPSR4_SD3_DAT1 BIT(10) +#define GPSR4_SD3_DAT0 BIT(9) +#define GPSR4_SD3_CMD BIT(8) +#define GPSR4_SD3_CLK BIT(7) +#define GPSR4_SD2_DS BIT(6) +#define GPSR4_SD2_DAT3 BIT(5) +#define GPSR4_SD2_DAT2 BIT(4) +#define GPSR4_SD2_DAT1 BIT(3) +#define GPSR4_SD2_DAT0 BIT(2) +#define GPSR4_SD2_CMD BIT(1) +#define GPSR4_SD2_CLK BIT(0) +#define GPSR5_MLB_DAT BIT(25) +#define GPSR5_MLB_SIG BIT(24) +#define GPSR5_MLB_CLK BIT(23) +#define GPSR5_MSIOF0_RXD BIT(22) +#define GPSR5_MSIOF0_SS2 BIT(21) +#define GPSR5_MSIOF0_TXD BIT(20) +#define GPSR5_MSIOF0_SS1 BIT(19) +#define GPSR5_MSIOF0_SYNC BIT(18) +#define GPSR5_MSIOF0_SCK BIT(17) +#define GPSR5_HRTS0 BIT(16) +#define GPSR5_HCTS0 BIT(15) +#define GPSR5_HTX0 BIT(14) +#define GPSR5_HRX0 BIT(13) +#define GPSR5_HSCK0 BIT(12) +#define GPSR5_RX2_A BIT(11) +#define GPSR5_TX2_A BIT(10) +#define GPSR5_SCK2 BIT(9) +#define GPSR5_RTS1 BIT(8) +#define GPSR5_CTS1 BIT(7) +#define GPSR5_TX1_A BIT(6) +#define GPSR5_RX1_A BIT(5) +#define GPSR5_RTS0 BIT(4) +#define GPSR5_CTS0 BIT(3) +#define GPSR5_TX0 BIT(2) +#define GPSR5_RX0 BIT(1) +#define GPSR5_SCK0 BIT(0) +#define GPSR6_USB31_OVC BIT(31) +#define GPSR6_USB31_PWEN BIT(30) +#define GPSR6_USB30_OVC BIT(29) +#define GPSR6_USB30_PWEN BIT(28) +#define GPSR6_USB1_OVC BIT(27) +#define GPSR6_USB1_PWEN BIT(26) +#define GPSR6_USB0_OVC BIT(25) +#define GPSR6_USB0_PWEN BIT(24) +#define GPSR6_AUDIO_CLKB_B BIT(23) +#define GPSR6_AUDIO_CLKA_A BIT(22) +#define GPSR6_SSI_SDATA9_A BIT(21) +#define GPSR6_SSI_SDATA8 BIT(20) +#define GPSR6_SSI_SDATA7 BIT(19) +#define GPSR6_SSI_WS78 BIT(18) +#define GPSR6_SSI_SCK78 BIT(17) +#define GPSR6_SSI_SDATA6 BIT(16) +#define GPSR6_SSI_WS6 BIT(15) +#define GPSR6_SSI_SCK6 BIT(14) +#define GPSR6_SSI_SDATA5 BIT(13) +#define GPSR6_SSI_WS5 BIT(12) +#define GPSR6_SSI_SCK5 BIT(11) +#define GPSR6_SSI_SDATA4 BIT(10) +#define GPSR6_SSI_WS4 BIT(9) +#define GPSR6_SSI_SCK4 BIT(8) +#define GPSR6_SSI_SDATA3 BIT(7) +#define GPSR6_SSI_WS34 BIT(6) +#define GPSR6_SSI_SCK34 BIT(5) +#define GPSR6_SSI_SDATA2_A BIT(4) +#define GPSR6_SSI_SDATA1_A BIT(3) +#define GPSR6_SSI_SDATA0 BIT(2) +#define GPSR6_SSI_WS0129 BIT(1) +#define GPSR6_SSI_SCK0129 BIT(0) +#define GPSR7_AVS2 BIT(1) +#define GPSR7_AVS1 BIT(0) + +#define IPSR_28_FUNC(x) ((uint32_t)(x) << 28U) +#define IPSR_24_FUNC(x) ((uint32_t)(x) << 24U) +#define IPSR_20_FUNC(x) ((uint32_t)(x) << 20U) +#define IPSR_16_FUNC(x) ((uint32_t)(x) << 16U) +#define IPSR_12_FUNC(x) ((uint32_t)(x) << 12U) +#define IPSR_8_FUNC(x) ((uint32_t)(x) << 8U) +#define IPSR_4_FUNC(x) ((uint32_t)(x) << 4U) +#define IPSR_0_FUNC(x) ((uint32_t)(x) << 0U) + +#define POC_SD3_DS_33V BIT(29) +#define POC_SD3_DAT7_33V BIT(28) +#define POC_SD3_DAT6_33V BIT(27) +#define POC_SD3_DAT5_33V BIT(26) +#define POC_SD3_DAT4_33V BIT(25) +#define POC_SD3_DAT3_33V BIT(24) +#define POC_SD3_DAT2_33V BIT(23) +#define POC_SD3_DAT1_33V BIT(22) +#define POC_SD3_DAT0_33V BIT(21) +#define POC_SD3_CMD_33V BIT(20) +#define POC_SD3_CLK_33V BIT(19) +#define POC_SD2_DS_33V BIT(18) +#define POC_SD2_DAT3_33V BIT(17) +#define POC_SD2_DAT2_33V BIT(16) +#define POC_SD2_DAT1_33V BIT(15) +#define POC_SD2_DAT0_33V BIT(14) +#define POC_SD2_CMD_33V BIT(13) +#define POC_SD2_CLK_33V BIT(12) +#define POC_SD1_DAT3_33V BIT(11) +#define POC_SD1_DAT2_33V BIT(10) +#define POC_SD1_DAT1_33V BIT(9) +#define POC_SD1_DAT0_33V BIT(8) +#define POC_SD1_CMD_33V BIT(7) +#define POC_SD1_CLK_33V BIT(6) +#define POC_SD0_DAT3_33V BIT(5) +#define POC_SD0_DAT2_33V BIT(4) +#define POC_SD0_DAT1_33V BIT(3) +#define POC_SD0_DAT0_33V BIT(2) +#define POC_SD0_CMD_33V BIT(1) +#define POC_SD0_CLK_33V BIT(0) + +#define DRVCTRL0_MASK (0xCCCCCCCCU) +#define DRVCTRL1_MASK (0xCCCCCCC8U) +#define DRVCTRL2_MASK (0x88888888U) +#define DRVCTRL3_MASK (0x88888888U) +#define DRVCTRL4_MASK (0x88888888U) +#define DRVCTRL5_MASK (0x88888888U) +#define DRVCTRL6_MASK (0x88888888U) +#define DRVCTRL7_MASK (0x88888888U) +#define DRVCTRL8_MASK (0x88888888U) +#define DRVCTRL9_MASK (0x88888888U) +#define DRVCTRL10_MASK (0x88888888U) +#define DRVCTRL11_MASK (0x888888CCU) +#define DRVCTRL12_MASK (0xCCCFFFCFU) +#define DRVCTRL13_MASK (0xCC888888U) +#define DRVCTRL14_MASK (0x88888888U) +#define DRVCTRL15_MASK (0x88888888U) +#define DRVCTRL16_MASK (0x88888888U) +#define DRVCTRL17_MASK (0x88888888U) +#define DRVCTRL18_MASK (0x88888888U) +#define DRVCTRL19_MASK (0x88888888U) +#define DRVCTRL20_MASK (0x88888888U) +#define DRVCTRL21_MASK (0x88888888U) +#define DRVCTRL22_MASK (0x88888888U) +#define DRVCTRL23_MASK (0x88888888U) +#define DRVCTRL24_MASK (0x8888888FU) + +#define DRVCTRL0_QSPI0_SPCLK(x) ((uint32_t)(x) << 28U) +#define DRVCTRL0_QSPI0_MOSI_IO0(x) ((uint32_t)(x) << 24U) +#define DRVCTRL0_QSPI0_MISO_IO1(x) ((uint32_t)(x) << 20U) +#define DRVCTRL0_QSPI0_IO2(x) ((uint32_t)(x) << 16U) +#define DRVCTRL0_QSPI0_IO3(x) ((uint32_t)(x) << 12U) +#define DRVCTRL0_QSPI0_SSL(x) ((uint32_t)(x) << 8U) +#define DRVCTRL0_QSPI1_SPCLK(x) ((uint32_t)(x) << 4U) +#define DRVCTRL0_QSPI1_MOSI_IO0(x) ((uint32_t)(x) << 0U) +#define DRVCTRL1_QSPI1_MISO_IO1(x) ((uint32_t)(x) << 28U) +#define DRVCTRL1_QSPI1_IO2(x) ((uint32_t)(x) << 24U) +#define DRVCTRL1_QSPI1_IO3(x) ((uint32_t)(x) << 20U) +#define DRVCTRL1_QSPI1_SS(x) ((uint32_t)(x) << 16U) +#define DRVCTRL1_RPC_INT(x) ((uint32_t)(x) << 12U) +#define DRVCTRL1_RPC_WP(x) ((uint32_t)(x) << 8U) +#define DRVCTRL1_RPC_RESET(x) ((uint32_t)(x) << 4U) +#define DRVCTRL1_AVB_RX_CTL(x) ((uint32_t)(x) << 0U) +#define DRVCTRL2_AVB_RXC(x) ((uint32_t)(x) << 28U) +#define DRVCTRL2_AVB_RD0(x) ((uint32_t)(x) << 24U) +#define DRVCTRL2_AVB_RD1(x) ((uint32_t)(x) << 20U) +#define DRVCTRL2_AVB_RD2(x) ((uint32_t)(x) << 16U) +#define DRVCTRL2_AVB_RD3(x) ((uint32_t)(x) << 12U) +#define DRVCTRL2_AVB_TX_CTL(x) ((uint32_t)(x) << 8U) +#define DRVCTRL2_AVB_TXC(x) ((uint32_t)(x) << 4U) +#define DRVCTRL2_AVB_TD0(x) ((uint32_t)(x) << 0U) +#define DRVCTRL3_AVB_TD1(x) ((uint32_t)(x) << 28U) +#define DRVCTRL3_AVB_TD2(x) ((uint32_t)(x) << 24U) +#define DRVCTRL3_AVB_TD3(x) ((uint32_t)(x) << 20U) +#define DRVCTRL3_AVB_TXCREFCLK(x) ((uint32_t)(x) << 16U) +#define DRVCTRL3_AVB_MDIO(x) ((uint32_t)(x) << 12U) +#define DRVCTRL3_AVB_MDC(x) ((uint32_t)(x) << 8U) +#define DRVCTRL3_AVB_MAGIC(x) ((uint32_t)(x) << 4U) +#define DRVCTRL3_AVB_PHY_INT(x) ((uint32_t)(x) << 0U) +#define DRVCTRL4_AVB_LINK(x) ((uint32_t)(x) << 28U) +#define DRVCTRL4_AVB_AVTP_MATCH(x) ((uint32_t)(x) << 24U) +#define DRVCTRL4_AVB_AVTP_CAPTURE(x) ((uint32_t)(x) << 20U) +#define DRVCTRL4_IRQ0(x) ((uint32_t)(x) << 16U) +#define DRVCTRL4_IRQ1(x) ((uint32_t)(x) << 12U) +#define DRVCTRL4_IRQ2(x) ((uint32_t)(x) << 8U) +#define DRVCTRL4_IRQ3(x) ((uint32_t)(x) << 4U) +#define DRVCTRL4_IRQ4(x) ((uint32_t)(x) << 0U) +#define DRVCTRL5_IRQ5(x) ((uint32_t)(x) << 28U) +#define DRVCTRL5_PWM0(x) ((uint32_t)(x) << 24U) +#define DRVCTRL5_PWM1(x) ((uint32_t)(x) << 20U) +#define DRVCTRL5_PWM2(x) ((uint32_t)(x) << 16U) +#define DRVCTRL5_A0(x) ((uint32_t)(x) << 12U) +#define DRVCTRL5_A1(x) ((uint32_t)(x) << 8U) +#define DRVCTRL5_A2(x) ((uint32_t)(x) << 4U) +#define DRVCTRL5_A3(x) ((uint32_t)(x) << 0U) +#define DRVCTRL6_A4(x) ((uint32_t)(x) << 28U) +#define DRVCTRL6_A5(x) ((uint32_t)(x) << 24U) +#define DRVCTRL6_A6(x) ((uint32_t)(x) << 20U) +#define DRVCTRL6_A7(x) ((uint32_t)(x) << 16U) +#define DRVCTRL6_A8(x) ((uint32_t)(x) << 12U) +#define DRVCTRL6_A9(x) ((uint32_t)(x) << 8U) +#define DRVCTRL6_A10(x) ((uint32_t)(x) << 4U) +#define DRVCTRL6_A11(x) ((uint32_t)(x) << 0U) +#define DRVCTRL7_A12(x) ((uint32_t)(x) << 28U) +#define DRVCTRL7_A13(x) ((uint32_t)(x) << 24U) +#define DRVCTRL7_A14(x) ((uint32_t)(x) << 20U) +#define DRVCTRL7_A15(x) ((uint32_t)(x) << 16U) +#define DRVCTRL7_A16(x) ((uint32_t)(x) << 12U) +#define DRVCTRL7_A17(x) ((uint32_t)(x) << 8U) +#define DRVCTRL7_A18(x) ((uint32_t)(x) << 4U) +#define DRVCTRL7_A19(x) ((uint32_t)(x) << 0U) +#define DRVCTRL8_CLKOUT(x) ((uint32_t)(x) << 28U) +#define DRVCTRL8_CS0(x) ((uint32_t)(x) << 24U) +#define DRVCTRL8_CS1_A2(x) ((uint32_t)(x) << 20U) +#define DRVCTRL8_BS(x) ((uint32_t)(x) << 16U) +#define DRVCTRL8_RD(x) ((uint32_t)(x) << 12U) +#define DRVCTRL8_RD_W(x) ((uint32_t)(x) << 8U) +#define DRVCTRL8_WE0(x) ((uint32_t)(x) << 4U) +#define DRVCTRL8_WE1(x) ((uint32_t)(x) << 0U) +#define DRVCTRL9_EX_WAIT0(x) ((uint32_t)(x) << 28U) +#define DRVCTRL9_PRESETOU(x) ((uint32_t)(x) << 24U) +#define DRVCTRL9_D0(x) ((uint32_t)(x) << 20U) +#define DRVCTRL9_D1(x) ((uint32_t)(x) << 16U) +#define DRVCTRL9_D2(x) ((uint32_t)(x) << 12U) +#define DRVCTRL9_D3(x) ((uint32_t)(x) << 8U) +#define DRVCTRL9_D4(x) ((uint32_t)(x) << 4U) +#define DRVCTRL9_D5(x) ((uint32_t)(x) << 0U) +#define DRVCTRL10_D6(x) ((uint32_t)(x) << 28U) +#define DRVCTRL10_D7(x) ((uint32_t)(x) << 24U) +#define DRVCTRL10_D8(x) ((uint32_t)(x) << 20U) +#define DRVCTRL10_D9(x) ((uint32_t)(x) << 16U) +#define DRVCTRL10_D10(x) ((uint32_t)(x) << 12U) +#define DRVCTRL10_D11(x) ((uint32_t)(x) << 8U) +#define DRVCTRL10_D12(x) ((uint32_t)(x) << 4U) +#define DRVCTRL10_D13(x) ((uint32_t)(x) << 0U) +#define DRVCTRL11_D14(x) ((uint32_t)(x) << 28U) +#define DRVCTRL11_D15(x) ((uint32_t)(x) << 24U) +#define DRVCTRL11_AVS1(x) ((uint32_t)(x) << 20U) +#define DRVCTRL11_AVS2(x) ((uint32_t)(x) << 16U) +#define DRVCTRL11_GP7_02(x) ((uint32_t)(x) << 12U) +#define DRVCTRL11_GP7_03(x) ((uint32_t)(x) << 8U) +#define DRVCTRL11_DU_DOTCLKIN0(x) ((uint32_t)(x) << 4U) +#define DRVCTRL11_DU_DOTCLKIN1(x) ((uint32_t)(x) << 0U) +#define DRVCTRL12_DU_DOTCLKIN2(x) ((uint32_t)(x) << 28U) +#define DRVCTRL12_DU_DOTCLKIN3(x) ((uint32_t)(x) << 24U) +#define DRVCTRL12_DU_FSCLKST(x) ((uint32_t)(x) << 20U) +#define DRVCTRL12_DU_TMS(x) ((uint32_t)(x) << 4U) +#define DRVCTRL13_TDO(x) ((uint32_t)(x) << 28U) +#define DRVCTRL13_ASEBRK(x) ((uint32_t)(x) << 24U) +#define DRVCTRL13_SD0_CLK(x) ((uint32_t)(x) << 20U) +#define DRVCTRL13_SD0_CMD(x) ((uint32_t)(x) << 16U) +#define DRVCTRL13_SD0_DAT0(x) ((uint32_t)(x) << 12U) +#define DRVCTRL13_SD0_DAT1(x) ((uint32_t)(x) << 8U) +#define DRVCTRL13_SD0_DAT2(x) ((uint32_t)(x) << 4U) +#define DRVCTRL13_SD0_DAT3(x) ((uint32_t)(x) << 0U) +#define DRVCTRL14_SD1_CLK(x) ((uint32_t)(x) << 28U) +#define DRVCTRL14_SD1_CMD(x) ((uint32_t)(x) << 24U) +#define DRVCTRL14_SD1_DAT0(x) ((uint32_t)(x) << 20U) +#define DRVCTRL14_SD1_DAT1(x) ((uint32_t)(x) << 16U) +#define DRVCTRL14_SD1_DAT2(x) ((uint32_t)(x) << 12U) +#define DRVCTRL14_SD1_DAT3(x) ((uint32_t)(x) << 8U) +#define DRVCTRL14_SD2_CLK(x) ((uint32_t)(x) << 4U) +#define DRVCTRL14_SD2_CMD(x) ((uint32_t)(x) << 0U) +#define DRVCTRL15_SD2_DAT0(x) ((uint32_t)(x) << 28U) +#define DRVCTRL15_SD2_DAT1(x) ((uint32_t)(x) << 24U) +#define DRVCTRL15_SD2_DAT2(x) ((uint32_t)(x) << 20U) +#define DRVCTRL15_SD2_DAT3(x) ((uint32_t)(x) << 16U) +#define DRVCTRL15_SD2_DS(x) ((uint32_t)(x) << 12U) +#define DRVCTRL15_SD3_CLK(x) ((uint32_t)(x) << 8U) +#define DRVCTRL15_SD3_CMD(x) ((uint32_t)(x) << 4U) +#define DRVCTRL15_SD3_DAT0(x) ((uint32_t)(x) << 0U) +#define DRVCTRL16_SD3_DAT1(x) ((uint32_t)(x) << 28U) +#define DRVCTRL16_SD3_DAT2(x) ((uint32_t)(x) << 24U) +#define DRVCTRL16_SD3_DAT3(x) ((uint32_t)(x) << 20U) +#define DRVCTRL16_SD3_DAT4(x) ((uint32_t)(x) << 16U) +#define DRVCTRL16_SD3_DAT5(x) ((uint32_t)(x) << 12U) +#define DRVCTRL16_SD3_DAT6(x) ((uint32_t)(x) << 8U) +#define DRVCTRL16_SD3_DAT7(x) ((uint32_t)(x) << 4U) +#define DRVCTRL16_SD3_DS(x) ((uint32_t)(x) << 0U) +#define DRVCTRL17_SD0_CD(x) ((uint32_t)(x) << 28U) +#define DRVCTRL17_SD0_WP(x) ((uint32_t)(x) << 24U) +#define DRVCTRL17_SD1_CD(x) ((uint32_t)(x) << 20U) +#define DRVCTRL17_SD1_WP(x) ((uint32_t)(x) << 16U) +#define DRVCTRL17_SCK0(x) ((uint32_t)(x) << 12U) +#define DRVCTRL17_RX0(x) ((uint32_t)(x) << 8U) +#define DRVCTRL17_TX0(x) ((uint32_t)(x) << 4U) +#define DRVCTRL17_CTS0(x) ((uint32_t)(x) << 0U) +#define DRVCTRL18_RTS0_TANS(x) ((uint32_t)(x) << 28U) +#define DRVCTRL18_RX1(x) ((uint32_t)(x) << 24U) +#define DRVCTRL18_TX1(x) ((uint32_t)(x) << 20U) +#define DRVCTRL18_CTS1(x) ((uint32_t)(x) << 16U) +#define DRVCTRL18_RTS1_TANS(x) ((uint32_t)(x) << 12U) +#define DRVCTRL18_SCK2(x) ((uint32_t)(x) << 8U) +#define DRVCTRL18_TX2(x) ((uint32_t)(x) << 4U) +#define DRVCTRL18_RX2(x) ((uint32_t)(x) << 0U) +#define DRVCTRL19_HSCK0(x) ((uint32_t)(x) << 28U) +#define DRVCTRL19_HRX0(x) ((uint32_t)(x) << 24U) +#define DRVCTRL19_HTX0(x) ((uint32_t)(x) << 20U) +#define DRVCTRL19_HCTS0(x) ((uint32_t)(x) << 16U) +#define DRVCTRL19_HRTS0(x) ((uint32_t)(x) << 12U) +#define DRVCTRL19_MSIOF0_SCK(x) ((uint32_t)(x) << 8U) +#define DRVCTRL19_MSIOF0_SYNC(x) ((uint32_t)(x) << 4U) +#define DRVCTRL19_MSIOF0_SS1(x) ((uint32_t)(x) << 0U) +#define DRVCTRL20_MSIOF0_TXD(x) ((uint32_t)(x) << 28U) +#define DRVCTRL20_MSIOF0_SS2(x) ((uint32_t)(x) << 24U) +#define DRVCTRL20_MSIOF0_RXD(x) ((uint32_t)(x) << 20U) +#define DRVCTRL20_MLB_CLK(x) ((uint32_t)(x) << 16U) +#define DRVCTRL20_MLB_SIG(x) ((uint32_t)(x) << 12U) +#define DRVCTRL20_MLB_DAT(x) ((uint32_t)(x) << 8U) +#define DRVCTRL20_MLB_REF(x) ((uint32_t)(x) << 4U) +#define DRVCTRL20_SSI_SCK0129(x) ((uint32_t)(x) << 0U) +#define DRVCTRL21_SSI_WS0129(x) ((uint32_t)(x) << 28U) +#define DRVCTRL21_SSI_SDATA0(x) ((uint32_t)(x) << 24U) +#define DRVCTRL21_SSI_SDATA1(x) ((uint32_t)(x) << 20U) +#define DRVCTRL21_SSI_SDATA2(x) ((uint32_t)(x) << 16U) +#define DRVCTRL21_SSI_SCK34(x) ((uint32_t)(x) << 12U) +#define DRVCTRL21_SSI_WS34(x) ((uint32_t)(x) << 8U) +#define DRVCTRL21_SSI_SDATA3(x) ((uint32_t)(x) << 4U) +#define DRVCTRL21_SSI_SCK4(x) ((uint32_t)(x) << 0U) +#define DRVCTRL22_SSI_WS4(x) ((uint32_t)(x) << 28U) +#define DRVCTRL22_SSI_SDATA4(x) ((uint32_t)(x) << 24U) +#define DRVCTRL22_SSI_SCK5(x) ((uint32_t)(x) << 20U) +#define DRVCTRL22_SSI_WS5(x) ((uint32_t)(x) << 16U) +#define DRVCTRL22_SSI_SDATA5(x) ((uint32_t)(x) << 12U) +#define DRVCTRL22_SSI_SCK6(x) ((uint32_t)(x) << 8U) +#define DRVCTRL22_SSI_WS6(x) ((uint32_t)(x) << 4U) +#define DRVCTRL22_SSI_SDATA6(x) ((uint32_t)(x) << 0U) +#define DRVCTRL23_SSI_SCK78(x) ((uint32_t)(x) << 28U) +#define DRVCTRL23_SSI_WS78(x) ((uint32_t)(x) << 24U) +#define DRVCTRL23_SSI_SDATA7(x) ((uint32_t)(x) << 20U) +#define DRVCTRL23_SSI_SDATA8(x) ((uint32_t)(x) << 16U) +#define DRVCTRL23_SSI_SDATA9(x) ((uint32_t)(x) << 12U) +#define DRVCTRL23_AUDIO_CLKA(x) ((uint32_t)(x) << 8U) +#define DRVCTRL23_AUDIO_CLKB(x) ((uint32_t)(x) << 4U) +#define DRVCTRL23_USB0_PWEN(x) ((uint32_t)(x) << 0U) +#define DRVCTRL24_USB0_OVC(x) ((uint32_t)(x) << 28U) +#define DRVCTRL24_USB1_PWEN(x) ((uint32_t)(x) << 24U) +#define DRVCTRL24_USB1_OVC(x) ((uint32_t)(x) << 20U) +#define DRVCTRL24_USB30_PWEN(x) ((uint32_t)(x) << 16U) +#define DRVCTRL24_USB30_OVC(x) ((uint32_t)(x) << 12U) +#define DRVCTRL24_USB31_PWEN(x) ((uint32_t)(x) << 8U) +#define DRVCTRL24_USB31_OVC(x) ((uint32_t)(x) << 4U) + +#define MOD_SEL0_MSIOF3_A ((uint32_t)0U << 29U) +#define MOD_SEL0_MSIOF3_B ((uint32_t)1U << 29U) +#define MOD_SEL0_MSIOF3_C ((uint32_t)2U << 29U) +#define MOD_SEL0_MSIOF3_D ((uint32_t)3U << 29U) +#define MOD_SEL0_MSIOF3_E ((uint32_t)4U << 29U) +#define MOD_SEL0_MSIOF2_A ((uint32_t)0U << 27U) +#define MOD_SEL0_MSIOF2_B ((uint32_t)1U << 27U) +#define MOD_SEL0_MSIOF2_C ((uint32_t)2U << 27U) +#define MOD_SEL0_MSIOF2_D ((uint32_t)3U << 27U) +#define MOD_SEL0_MSIOF1_A ((uint32_t)0U << 24U) +#define MOD_SEL0_MSIOF1_B ((uint32_t)1U << 24U) +#define MOD_SEL0_MSIOF1_C ((uint32_t)2U << 24U) +#define MOD_SEL0_MSIOF1_D ((uint32_t)3U << 24U) +#define MOD_SEL0_MSIOF1_E ((uint32_t)4U << 24U) +#define MOD_SEL0_MSIOF1_F ((uint32_t)5U << 24U) +#define MOD_SEL0_MSIOF1_G ((uint32_t)6U << 24U) +#define MOD_SEL0_LBSC_A ((uint32_t)0U << 23U) +#define MOD_SEL0_LBSC_B ((uint32_t)1U << 23U) +#define MOD_SEL0_IEBUS_A ((uint32_t)0U << 22U) +#define MOD_SEL0_IEBUS_B ((uint32_t)1U << 22U) +#define MOD_SEL0_I2C2_A ((uint32_t)0U << 21U) +#define MOD_SEL0_I2C2_B ((uint32_t)1U << 21U) +#define MOD_SEL0_I2C1_A ((uint32_t)0U << 20U) +#define MOD_SEL0_I2C1_B ((uint32_t)1U << 20U) +#define MOD_SEL0_HSCIF4_A ((uint32_t)0U << 19U) +#define MOD_SEL0_HSCIF4_B ((uint32_t)1U << 19U) +#define MOD_SEL0_HSCIF3_A ((uint32_t)0U << 17U) +#define MOD_SEL0_HSCIF3_B ((uint32_t)1U << 17U) +#define MOD_SEL0_HSCIF3_C ((uint32_t)2U << 17U) +#define MOD_SEL0_HSCIF3_D ((uint32_t)3U << 17U) +#define MOD_SEL0_HSCIF1_A ((uint32_t)0U << 16U) +#define MOD_SEL0_HSCIF1_B ((uint32_t)1U << 16U) +#define MOD_SEL0_FSO_A ((uint32_t)0U << 15U) +#define MOD_SEL0_FSO_B ((uint32_t)1U << 15U) +#define MOD_SEL0_HSCIF2_A ((uint32_t)0U << 13U) +#define MOD_SEL0_HSCIF2_B ((uint32_t)1U << 13U) +#define MOD_SEL0_HSCIF2_C ((uint32_t)2U << 13U) +#define MOD_SEL0_ETHERAVB_A ((uint32_t)0U << 12U) +#define MOD_SEL0_ETHERAVB_B ((uint32_t)1U << 12U) +#define MOD_SEL0_DRIF3_A ((uint32_t)0U << 11U) +#define MOD_SEL0_DRIF3_B ((uint32_t)1U << 11U) +#define MOD_SEL0_DRIF2_A ((uint32_t)0U << 10U) +#define MOD_SEL0_DRIF2_B ((uint32_t)1U << 10U) +#define MOD_SEL0_DRIF1_A ((uint32_t)0U << 8U) +#define MOD_SEL0_DRIF1_B ((uint32_t)1U << 8U) +#define MOD_SEL0_DRIF1_C ((uint32_t)2U << 8U) +#define MOD_SEL0_DRIF0_A ((uint32_t)0U << 6U) +#define MOD_SEL0_DRIF0_B ((uint32_t)1U << 6U) +#define MOD_SEL0_DRIF0_C ((uint32_t)2U << 6U) +#define MOD_SEL0_CANFD0_A ((uint32_t)0U << 5U) +#define MOD_SEL0_CANFD0_B ((uint32_t)1U << 5U) +#define MOD_SEL0_ADG_A_A ((uint32_t)0U << 3U) +#define MOD_SEL0_ADG_A_B ((uint32_t)1U << 3U) +#define MOD_SEL0_ADG_A_C ((uint32_t)2U << 3U) +#define MOD_SEL1_TSIF1_A ((uint32_t)0U << 30U) +#define MOD_SEL1_TSIF1_B ((uint32_t)1U << 30U) +#define MOD_SEL1_TSIF1_C ((uint32_t)2U << 30U) +#define MOD_SEL1_TSIF1_D ((uint32_t)3U << 30U) +#define MOD_SEL1_TSIF0_A ((uint32_t)0U << 27U) +#define MOD_SEL1_TSIF0_B ((uint32_t)1U << 27U) +#define MOD_SEL1_TSIF0_C ((uint32_t)2U << 27U) +#define MOD_SEL1_TSIF0_D ((uint32_t)3U << 27U) +#define MOD_SEL1_TSIF0_E ((uint32_t)4U << 27U) +#define MOD_SEL1_TIMER_TMU_A ((uint32_t)0U << 26U) +#define MOD_SEL1_TIMER_TMU_B ((uint32_t)1U << 26U) +#define MOD_SEL1_SSP1_1_A ((uint32_t)0U << 24U) +#define MOD_SEL1_SSP1_1_B ((uint32_t)1U << 24U) +#define MOD_SEL1_SSP1_1_C ((uint32_t)2U << 24U) +#define MOD_SEL1_SSP1_1_D ((uint32_t)3U << 24U) +#define MOD_SEL1_SSP1_0_A ((uint32_t)0U << 21U) +#define MOD_SEL1_SSP1_0_B ((uint32_t)1U << 21U) +#define MOD_SEL1_SSP1_0_C ((uint32_t)2U << 21U) +#define MOD_SEL1_SSP1_0_D ((uint32_t)3U << 21U) +#define MOD_SEL1_SSP1_0_E ((uint32_t)4U << 21U) +#define MOD_SEL1_SSI_A ((uint32_t)0U << 20U) +#define MOD_SEL1_SSI_B ((uint32_t)1U << 20U) +#define MOD_SEL1_SPEED_PULSE_IF_A ((uint32_t)0U << 19U) +#define MOD_SEL1_SPEED_PULSE_IF_B ((uint32_t)1U << 19U) +#define MOD_SEL1_SIMCARD_A ((uint32_t)0U << 17U) +#define MOD_SEL1_SIMCARD_B ((uint32_t)1U << 17U) +#define MOD_SEL1_SIMCARD_C ((uint32_t)2U << 17U) +#define MOD_SEL1_SIMCARD_D ((uint32_t)3U << 17U) +#define MOD_SEL1_SDHI2_A ((uint32_t)0U << 16U) +#define MOD_SEL1_SDHI2_B ((uint32_t)1U << 16U) +#define MOD_SEL1_SCIF4_A ((uint32_t)0U << 14U) +#define MOD_SEL1_SCIF4_B ((uint32_t)1U << 14U) +#define MOD_SEL1_SCIF4_C ((uint32_t)2U << 14U) +#define MOD_SEL1_SCIF3_A ((uint32_t)0U << 13U) +#define MOD_SEL1_SCIF3_B ((uint32_t)1U << 13U) +#define MOD_SEL1_SCIF2_A ((uint32_t)0U << 12U) +#define MOD_SEL1_SCIF2_B ((uint32_t)1U << 12U) +#define MOD_SEL1_SCIF1_A ((uint32_t)0U << 11U) +#define MOD_SEL1_SCIF1_B ((uint32_t)1U << 11U) +#define MOD_SEL1_SCIF_A ((uint32_t)0U << 10U) +#define MOD_SEL1_SCIF_B ((uint32_t)1U << 10U) +#define MOD_SEL1_REMOCON_A ((uint32_t)0U << 9U) +#define MOD_SEL1_REMOCON_B ((uint32_t)1U << 9U) +#define MOD_SEL1_RCAN0_A ((uint32_t)0U << 6U) +#define MOD_SEL1_RCAN0_B ((uint32_t)1U << 6U) +#define MOD_SEL1_PWM6_A ((uint32_t)0U << 5U) +#define MOD_SEL1_PWM6_B ((uint32_t)1U << 5U) +#define MOD_SEL1_PWM5_A ((uint32_t)0U << 4U) +#define MOD_SEL1_PWM5_B ((uint32_t)1U << 4U) +#define MOD_SEL1_PWM4_A ((uint32_t)0U << 3U) +#define MOD_SEL1_PWM4_B ((uint32_t)1U << 3U) +#define MOD_SEL1_PWM3_A ((uint32_t)0U << 2U) +#define MOD_SEL1_PWM3_B ((uint32_t)1U << 2U) +#define MOD_SEL1_PWM2_A ((uint32_t)0U << 1U) +#define MOD_SEL1_PWM2_B ((uint32_t)1U << 1U) +#define MOD_SEL1_PWM1_A ((uint32_t)0U << 0U) +#define MOD_SEL1_PWM1_B ((uint32_t)1U << 0U) +#define MOD_SEL2_I2C_5_A ((uint32_t)0U << 31U) +#define MOD_SEL2_I2C_5_B ((uint32_t)1U << 31U) +#define MOD_SEL2_I2C_3_A ((uint32_t)0U << 30U) +#define MOD_SEL2_I2C_3_B ((uint32_t)1U << 30U) +#define MOD_SEL2_I2C_0_A ((uint32_t)0U << 29U) +#define MOD_SEL2_I2C_0_B ((uint32_t)1U << 29U) +#define MOD_SEL2_FM_A ((uint32_t)0U << 27U) +#define MOD_SEL2_FM_B ((uint32_t)1U << 27U) +#define MOD_SEL2_FM_C ((uint32_t)2U << 27U) +#define MOD_SEL2_FM_D ((uint32_t)3U << 27U) +#define MOD_SEL2_SCIF5_A ((uint32_t)0U << 26U) +#define MOD_SEL2_SCIF5_B ((uint32_t)1U << 26U) +#define MOD_SEL2_I2C6_A ((uint32_t)0U << 23U) +#define MOD_SEL2_I2C6_B ((uint32_t)1U << 23U) +#define MOD_SEL2_I2C6_C ((uint32_t)2U << 23U) +#define MOD_SEL2_NDF_A ((uint32_t)0U << 22U) +#define MOD_SEL2_NDF_B ((uint32_t)1U << 22U) +#define MOD_SEL2_SSI2_A ((uint32_t)0U << 21U) +#define MOD_SEL2_SSI2_B ((uint32_t)1U << 21U) +#define MOD_SEL2_SSI9_A ((uint32_t)0U << 20U) +#define MOD_SEL2_SSI9_B ((uint32_t)1U << 20U) +#define MOD_SEL2_TIMER_TMU2_A ((uint32_t)0U << 19U) +#define MOD_SEL2_TIMER_TMU2_B ((uint32_t)1U << 19U) +#define MOD_SEL2_ADG_B_A ((uint32_t)0U << 18U) +#define MOD_SEL2_ADG_B_B ((uint32_t)1U << 18U) +#define MOD_SEL2_ADG_C_A ((uint32_t)0U << 17U) +#define MOD_SEL2_ADG_C_B ((uint32_t)1U << 17U) +#define MOD_SEL2_VIN4_A ((uint32_t)0U << 0U) +#define MOD_SEL2_VIN4_B ((uint32_t)1U << 0U) + +/* SCIF3 Registers for Dummy write */ +#define SCIF3_BASE (0xE6C50000U) +#define SCIF3_SCFCR (SCIF3_BASE + 0x0018U) +#define SCIF3_SCFDR (SCIF3_BASE + 0x001CU) +#define SCFCR_DATA (0x0000U) + +/* Realtime module stop control */ +#define CPG_BASE (0xE6150000U) +#define CPG_SCMSTPCR0 (CPG_BASE + 0x0B20U) +#define CPG_MSTPSR0 (CPG_BASE + 0x0030U) +#define SCMSTPCR0_RTDMAC (0x00200000U) + +/* RT-DMAC Registers */ +#define RTDMAC_CH (0U) /* choose 0 to 15 */ + +#define RTDMAC_BASE (0xFFC10000U) +#define RTDMAC_RDMOR (RTDMAC_BASE + 0x0060U) +#define RTDMAC_RDMCHCLR (RTDMAC_BASE + 0x0080U) +#define RTDMAC_RDMSAR(x) (RTDMAC_BASE + 0x8000U + (0x80U * (x))) +#define RTDMAC_RDMDAR(x) (RTDMAC_BASE + 0x8004U + (0x80U * (x))) +#define RTDMAC_RDMTCR(x) (RTDMAC_BASE + 0x8008U + (0x80U * (x))) +#define RTDMAC_RDMCHCR(x) (RTDMAC_BASE + 0x800CU + (0x80U * (x))) +#define RTDMAC_RDMCHCRB(x) (RTDMAC_BASE + 0x801CU + (0x80U * (x))) +#define RTDMAC_RDMDPBASE(x) (RTDMAC_BASE + 0x8050U + (0x80U * (x))) +#define RTDMAC_DESC_BASE (RTDMAC_BASE + 0xA000U) +#define RTDMAC_DESC_RDMSAR (RTDMAC_DESC_BASE + 0x0000U) +#define RTDMAC_DESC_RDMDAR (RTDMAC_DESC_BASE + 0x0004U) +#define RTDMAC_DESC_RDMTCR (RTDMAC_DESC_BASE + 0x0008U) + +#define RDMOR_DME (0x0001U) /* DMA Master Enable */ +#define RDMCHCR_DPM_INFINITE (0x30000000U) /* Infinite repeat mode */ +#define RDMCHCR_RPT_TCR (0x02000000U) /* enable to update TCR */ +#define RDMCHCR_TS_2 (0x00000008U) /* Word(2byte) units transfer */ +#define RDMCHCR_RS_AUTO (0x00000400U) /* Auto request */ +#define RDMCHCR_DE (0x00000001U) /* DMA Enable */ +#define RDMCHCRB_DRST (0x00008000U) /* Descriptor reset */ +#define RDMCHCRB_SLM_256 (0x00000080U) /* once in 256 clock cycle */ +#define RDMDPBASE_SEL_EXT (0x00000001U) /* External memory use */ + +static void start_rtdma0_descriptor(void) +{ + uint32_t reg; + + reg = mmio_read_32(RCAR_PRR); + reg &= (PRR_PRODUCT_MASK | PRR_CUT_MASK); + if (reg == (PRR_PRODUCT_M3_CUT10)) { + /* Enable clock supply to RTDMAC. */ + mstpcr_write(CPG_SCMSTPCR0, CPG_MSTPSR0, SCMSTPCR0_RTDMAC); + + /* Initialize ch0, Reset Descriptor */ + mmio_write_32(RTDMAC_RDMCHCLR, BIT(RTDMAC_CH)); + mmio_write_32(RTDMAC_RDMCHCRB(RTDMAC_CH), RDMCHCRB_DRST); + + /* Enable DMA */ + mmio_write_16(RTDMAC_RDMOR, RDMOR_DME); + + /* Set first transfer */ + mmio_write_32(RTDMAC_RDMSAR(RTDMAC_CH), RCAR_PRR); + mmio_write_32(RTDMAC_RDMDAR(RTDMAC_CH), SCIF3_SCFDR); + mmio_write_32(RTDMAC_RDMTCR(RTDMAC_CH), 0x00000001U); + + /* Set descriptor */ + mmio_write_32(RTDMAC_DESC_RDMSAR, 0x00000000U); + mmio_write_32(RTDMAC_DESC_RDMDAR, 0x00000000U); + mmio_write_32(RTDMAC_DESC_RDMTCR, 0x00200000U); + mmio_write_32(RTDMAC_RDMCHCRB(RTDMAC_CH), RDMCHCRB_SLM_256); + mmio_write_32(RTDMAC_RDMDPBASE(RTDMAC_CH), RTDMAC_DESC_BASE + | RDMDPBASE_SEL_EXT); + + /* Set transfer parameter, Start transfer */ + mmio_write_32(RTDMAC_RDMCHCR(RTDMAC_CH), RDMCHCR_DPM_INFINITE + | RDMCHCR_RPT_TCR + | RDMCHCR_TS_2 + | RDMCHCR_RS_AUTO + | RDMCHCR_DE); + } +} + +static void pfc_reg_write(uint32_t addr, uint32_t data) +{ + uint32_t prr; + + prr = mmio_read_32(RCAR_PRR); + prr &= (PRR_PRODUCT_MASK | PRR_CUT_MASK); + + mmio_write_32(PFC_PMMR, ~data); + if (prr == (PRR_PRODUCT_M3_CUT10)) { + mmio_write_16(SCIF3_SCFCR, SCFCR_DATA); /* Dummy write */ + } + mmio_write_32((uintptr_t)addr, data); + if (prr == (PRR_PRODUCT_M3_CUT10)) { + mmio_write_16(SCIF3_SCFCR, SCFCR_DATA); /* Dummy write */ + } +} + +void pfc_init_g2m(void) +{ + uint32_t reg; + + /* + * PFC write access problem seen on older SoC's. Added a workaround + * in RT-DMAC for fixing the same. + */ + start_rtdma0_descriptor(); + + /* initialize module select */ + pfc_reg_write(PFC_MOD_SEL0, MOD_SEL0_MSIOF3_A + | MOD_SEL0_MSIOF2_A + | MOD_SEL0_MSIOF1_A + | MOD_SEL0_LBSC_A + | MOD_SEL0_IEBUS_A + | MOD_SEL0_I2C2_A + | MOD_SEL0_I2C1_A + | MOD_SEL0_HSCIF4_A + | MOD_SEL0_HSCIF3_A + | MOD_SEL0_HSCIF1_A + | MOD_SEL0_FSO_A + | MOD_SEL0_HSCIF2_A + | MOD_SEL0_ETHERAVB_A + | MOD_SEL0_DRIF3_A + | MOD_SEL0_DRIF2_A + | MOD_SEL0_DRIF1_A + | MOD_SEL0_DRIF0_A + | MOD_SEL0_CANFD0_A + | MOD_SEL0_ADG_A_A); + pfc_reg_write(PFC_MOD_SEL1, MOD_SEL1_TSIF1_A + | MOD_SEL1_TSIF0_A + | MOD_SEL1_TIMER_TMU_A + | MOD_SEL1_SSP1_1_A + | MOD_SEL1_SSP1_0_A + | MOD_SEL1_SSI_A + | MOD_SEL1_SPEED_PULSE_IF_A + | MOD_SEL1_SIMCARD_A + | MOD_SEL1_SDHI2_A + | MOD_SEL1_SCIF4_A + | MOD_SEL1_SCIF3_A + | MOD_SEL1_SCIF2_A + | MOD_SEL1_SCIF1_A + | MOD_SEL1_SCIF_A + | MOD_SEL1_REMOCON_A + | MOD_SEL1_RCAN0_A + | MOD_SEL1_PWM6_A + | MOD_SEL1_PWM5_A + | MOD_SEL1_PWM4_A + | MOD_SEL1_PWM3_A + | MOD_SEL1_PWM2_A + | MOD_SEL1_PWM1_A); + pfc_reg_write(PFC_MOD_SEL2, MOD_SEL2_I2C_5_B + | MOD_SEL2_I2C_3_B + | MOD_SEL2_I2C_0_B + | MOD_SEL2_FM_A + | MOD_SEL2_SCIF5_A + | MOD_SEL2_I2C6_A + | MOD_SEL2_NDF_A + | MOD_SEL2_SSI2_A + | MOD_SEL2_SSI9_A + | MOD_SEL2_TIMER_TMU2_A + | MOD_SEL2_ADG_B_A + | MOD_SEL2_ADG_C_A + | MOD_SEL2_VIN4_A); + + /* initialize peripheral function select */ + pfc_reg_write(PFC_IPSR0, IPSR_28_FUNC(0) + | IPSR_24_FUNC(0) + | IPSR_20_FUNC(0) + | IPSR_16_FUNC(0) + | IPSR_12_FUNC(0) + | IPSR_8_FUNC(0) + | IPSR_4_FUNC(0) + | IPSR_0_FUNC(0)); + pfc_reg_write(PFC_IPSR1, IPSR_28_FUNC(6) + | IPSR_24_FUNC(0) + | IPSR_20_FUNC(0) + | IPSR_16_FUNC(0) + | IPSR_12_FUNC(3) + | IPSR_8_FUNC(3) + | IPSR_4_FUNC(3) + | IPSR_0_FUNC(3)); + pfc_reg_write(PFC_IPSR2, IPSR_28_FUNC(0) + | IPSR_24_FUNC(6) + | IPSR_20_FUNC(6) + | IPSR_16_FUNC(6) + | IPSR_12_FUNC(6) + | IPSR_8_FUNC(6) + | IPSR_4_FUNC(6) + | IPSR_0_FUNC(6)); + pfc_reg_write(PFC_IPSR3, IPSR_28_FUNC(6) + | IPSR_24_FUNC(6) + | IPSR_20_FUNC(6) + | IPSR_16_FUNC(6) + | IPSR_12_FUNC(6) + | IPSR_8_FUNC(0) + | IPSR_4_FUNC(0) + | IPSR_0_FUNC(0)); + pfc_reg_write(PFC_IPSR4, IPSR_28_FUNC(0) + | IPSR_24_FUNC(0) + | IPSR_20_FUNC(0) + | IPSR_16_FUNC(0) + | IPSR_12_FUNC(0) + | IPSR_8_FUNC(6) + | IPSR_4_FUNC(6) + | IPSR_0_FUNC(6)); + pfc_reg_write(PFC_IPSR5, IPSR_28_FUNC(0) + | IPSR_24_FUNC(0) + | IPSR_20_FUNC(0) + | IPSR_16_FUNC(0) + | IPSR_12_FUNC(0) + | IPSR_8_FUNC(6) + | IPSR_4_FUNC(0) + | IPSR_0_FUNC(0)); + pfc_reg_write(PFC_IPSR6, IPSR_28_FUNC(6) + | IPSR_24_FUNC(6) + | IPSR_20_FUNC(6) + | IPSR_16_FUNC(6) + | IPSR_12_FUNC(6) + | IPSR_8_FUNC(0) + | IPSR_4_FUNC(0) + | IPSR_0_FUNC(0)); + pfc_reg_write(PFC_IPSR7, IPSR_28_FUNC(0) + | IPSR_24_FUNC(0) + | IPSR_20_FUNC(0) + | IPSR_16_FUNC(0) + | IPSR_12_FUNC(0) + | IPSR_8_FUNC(6) + | IPSR_4_FUNC(6) + | IPSR_0_FUNC(6)); + pfc_reg_write(PFC_IPSR8, IPSR_28_FUNC(1) + | IPSR_24_FUNC(1) + | IPSR_20_FUNC(1) + | IPSR_16_FUNC(1) + | IPSR_12_FUNC(0) + | IPSR_8_FUNC(0) + | IPSR_4_FUNC(0) + | IPSR_0_FUNC(0)); + pfc_reg_write(PFC_IPSR9, IPSR_28_FUNC(0) + | IPSR_24_FUNC(0) + | IPSR_20_FUNC(0) + | IPSR_16_FUNC(0) + | IPSR_12_FUNC(0) + | IPSR_8_FUNC(0) + | IPSR_4_FUNC(0) + | IPSR_0_FUNC(0)); + pfc_reg_write(PFC_IPSR10, IPSR_28_FUNC(0) + | IPSR_24_FUNC(0) + | IPSR_20_FUNC(0) + | IPSR_16_FUNC(0) + | IPSR_12_FUNC(0) + | IPSR_8_FUNC(0) + | IPSR_4_FUNC(0) + | IPSR_0_FUNC(0)); + pfc_reg_write(PFC_IPSR11, IPSR_28_FUNC(0) + | IPSR_24_FUNC(4) + | IPSR_20_FUNC(0) + | IPSR_16_FUNC(0) + | IPSR_12_FUNC(0) + | IPSR_8_FUNC(0) + | IPSR_4_FUNC(0) + | IPSR_0_FUNC(0)); + pfc_reg_write(PFC_IPSR12, IPSR_28_FUNC(0) + | IPSR_24_FUNC(0) + | IPSR_20_FUNC(0) + | IPSR_16_FUNC(0) + | IPSR_12_FUNC(0) + | IPSR_8_FUNC(4) + | IPSR_4_FUNC(0) + | IPSR_0_FUNC(0)); + pfc_reg_write(PFC_IPSR13, IPSR_28_FUNC(8) + | IPSR_24_FUNC(0) + | IPSR_20_FUNC(0) + | IPSR_16_FUNC(0) + | IPSR_12_FUNC(0) + | IPSR_8_FUNC(3) + | IPSR_4_FUNC(0) + | IPSR_0_FUNC(0)); + pfc_reg_write(PFC_IPSR14, IPSR_28_FUNC(0) + | IPSR_24_FUNC(0) + | IPSR_20_FUNC(0) + | IPSR_16_FUNC(0) + | IPSR_12_FUNC(0) + | IPSR_8_FUNC(0) + | IPSR_4_FUNC(3) + | IPSR_0_FUNC(8)); + pfc_reg_write(PFC_IPSR15, IPSR_28_FUNC(0) + | IPSR_24_FUNC(0) + | IPSR_20_FUNC(0) + | IPSR_16_FUNC(0) + | IPSR_12_FUNC(0) + | IPSR_8_FUNC(0) + | IPSR_4_FUNC(0) + | IPSR_0_FUNC(0)); + pfc_reg_write(PFC_IPSR16, IPSR_28_FUNC(0) + | IPSR_24_FUNC(0) + | IPSR_20_FUNC(0) + | IPSR_16_FUNC(0) + | IPSR_12_FUNC(0) + | IPSR_8_FUNC(0) + | IPSR_4_FUNC(0) + | IPSR_0_FUNC(0)); + pfc_reg_write(PFC_IPSR17, IPSR_28_FUNC(0) + | IPSR_24_FUNC(0) + | IPSR_20_FUNC(0) + | IPSR_16_FUNC(0) + | IPSR_12_FUNC(0) + | IPSR_8_FUNC(0) + | IPSR_4_FUNC(1) + | IPSR_0_FUNC(0)); + pfc_reg_write(PFC_IPSR18, IPSR_4_FUNC(0) + | IPSR_0_FUNC(0)); + + /* initialize GPIO/perihperal function select */ + pfc_reg_write(PFC_GPSR0, GPSR0_D15 + | GPSR0_D14 + | GPSR0_D13 + | GPSR0_D12 + | GPSR0_D11 + | GPSR0_D10 + | GPSR0_D9 + | GPSR0_D8 + | GPSR0_D7 + | GPSR0_D6 + | GPSR0_D5 + | GPSR0_D4 + | GPSR0_D3 + | GPSR0_D2 + | GPSR0_D0); + pfc_reg_write(PFC_GPSR1, GPSR1_CLKOUT + | GPSR1_EX_WAIT0_A + | GPSR1_WE1 + | GPSR1_RD + | GPSR1_RD_WR + | GPSR1_CS0 + | GPSR1_A19 + | GPSR1_A18 + | GPSR1_A17 + | GPSR1_A16 + | GPSR1_A15 + | GPSR1_A14 + | GPSR1_A13 + | GPSR1_A12 + | GPSR1_A7 + | GPSR1_A6 + | GPSR1_A5 + | GPSR1_A4 + | GPSR1_A3 + | GPSR1_A2 + | GPSR1_A1 + | GPSR1_A0); + pfc_reg_write(PFC_GPSR2, GPSR2_AVB_AVTP_CAPTURE_A + | GPSR2_AVB_AVTP_MATCH_A + | GPSR2_AVB_LINK + | GPSR2_AVB_PHY_INT + | GPSR2_AVB_MDC + | GPSR2_PWM2_A + | GPSR2_PWM1_A + | GPSR2_IRQ4 + | GPSR2_IRQ3 + | GPSR2_IRQ2 + | GPSR2_IRQ1 + | GPSR2_IRQ0); + pfc_reg_write(PFC_GPSR3, GPSR3_SD0_CD + | GPSR3_SD1_DAT3 + | GPSR3_SD1_DAT2 + | GPSR3_SD1_DAT1 + | GPSR3_SD1_DAT0 + | GPSR3_SD0_DAT3 + | GPSR3_SD0_DAT2 + | GPSR3_SD0_DAT1 + | GPSR3_SD0_DAT0 + | GPSR3_SD0_CMD + | GPSR3_SD0_CLK); + pfc_reg_write(PFC_GPSR4, GPSR4_SD3_DS + | GPSR4_SD3_DAT7 + | GPSR4_SD3_DAT6 + | GPSR4_SD3_DAT5 + | GPSR4_SD3_DAT4 + | GPSR4_SD3_DAT3 + | GPSR4_SD3_DAT2 + | GPSR4_SD3_DAT1 + | GPSR4_SD3_DAT0 + | GPSR4_SD3_CMD + | GPSR4_SD3_CLK + | GPSR4_SD2_DAT3 + | GPSR4_SD2_DAT2 + | GPSR4_SD2_DAT1 + | GPSR4_SD2_DAT0 + | GPSR4_SD2_CMD + | GPSR4_SD2_CLK); + pfc_reg_write(PFC_GPSR5, GPSR5_MSIOF0_RXD + | GPSR5_MSIOF0_TXD + | GPSR5_MSIOF0_SYNC + | GPSR5_MSIOF0_SCK + | GPSR5_RX2_A + | GPSR5_TX2_A + | GPSR5_RTS1 + | GPSR5_CTS1 + | GPSR5_TX1_A + | GPSR5_RX1_A + | GPSR5_RTS0 + | GPSR5_SCK0); + pfc_reg_write(PFC_GPSR6, GPSR6_AUDIO_CLKB_B + | GPSR6_AUDIO_CLKA_A + | GPSR6_SSI_WS6 + | GPSR6_SSI_SCK6 + | GPSR6_SSI_SDATA4 + | GPSR6_SSI_WS4 + | GPSR6_SSI_SCK4 + | GPSR6_SSI_SDATA1_A + | GPSR6_SSI_SDATA0 + | GPSR6_SSI_WS0129 + | GPSR6_SSI_SCK0129); + pfc_reg_write(PFC_GPSR7, GPSR7_AVS2 + | GPSR7_AVS1); + + /* initialize POC control register */ + pfc_reg_write(PFC_POCCTRL0, POC_SD0_DAT3_33V + | POC_SD0_DAT2_33V + | POC_SD0_DAT1_33V + | POC_SD0_DAT0_33V + | POC_SD0_CMD_33V + | POC_SD0_CLK_33V); + + /* initialize DRV control register */ + reg = mmio_read_32(PFC_DRVCTRL0); + reg = ((reg & DRVCTRL0_MASK) | DRVCTRL0_QSPI0_SPCLK(3) + | DRVCTRL0_QSPI0_MOSI_IO0(3) + | DRVCTRL0_QSPI0_MISO_IO1(3) + | DRVCTRL0_QSPI0_IO2(3) + | DRVCTRL0_QSPI0_IO3(3) + | DRVCTRL0_QSPI0_SSL(3) + | DRVCTRL0_QSPI1_SPCLK(3) + | DRVCTRL0_QSPI1_MOSI_IO0(3)); + pfc_reg_write(PFC_DRVCTRL0, reg); + reg = mmio_read_32(PFC_DRVCTRL1); + reg = ((reg & DRVCTRL1_MASK) | DRVCTRL1_QSPI1_MISO_IO1(3) + | DRVCTRL1_QSPI1_IO2(3) + | DRVCTRL1_QSPI1_IO3(3) + | DRVCTRL1_QSPI1_SS(3) + | DRVCTRL1_RPC_INT(3) + | DRVCTRL1_RPC_WP(3) + | DRVCTRL1_RPC_RESET(3) + | DRVCTRL1_AVB_RX_CTL(7)); + pfc_reg_write(PFC_DRVCTRL1, reg); + reg = mmio_read_32(PFC_DRVCTRL2); + reg = ((reg & DRVCTRL2_MASK) | DRVCTRL2_AVB_RXC(7) + | DRVCTRL2_AVB_RD0(7) + | DRVCTRL2_AVB_RD1(7) + | DRVCTRL2_AVB_RD2(7) + | DRVCTRL2_AVB_RD3(7) + | DRVCTRL2_AVB_TX_CTL(3) + | DRVCTRL2_AVB_TXC(3) + | DRVCTRL2_AVB_TD0(3)); + pfc_reg_write(PFC_DRVCTRL2, reg); + reg = mmio_read_32(PFC_DRVCTRL3); + reg = ((reg & DRVCTRL3_MASK) | DRVCTRL3_AVB_TD1(3) + | DRVCTRL3_AVB_TD2(3) + | DRVCTRL3_AVB_TD3(3) + | DRVCTRL3_AVB_TXCREFCLK(7) + | DRVCTRL3_AVB_MDIO(7) + | DRVCTRL3_AVB_MDC(7) + | DRVCTRL3_AVB_MAGIC(7) + | DRVCTRL3_AVB_PHY_INT(7)); + pfc_reg_write(PFC_DRVCTRL3, reg); + reg = mmio_read_32(PFC_DRVCTRL4); + reg = ((reg & DRVCTRL4_MASK) | DRVCTRL4_AVB_LINK(7) + | DRVCTRL4_AVB_AVTP_MATCH(7) + | DRVCTRL4_AVB_AVTP_CAPTURE(7) + | DRVCTRL4_IRQ0(7) + | DRVCTRL4_IRQ1(7) + | DRVCTRL4_IRQ2(7) + | DRVCTRL4_IRQ3(7) + | DRVCTRL4_IRQ4(7)); + pfc_reg_write(PFC_DRVCTRL4, reg); + reg = mmio_read_32(PFC_DRVCTRL5); + reg = ((reg & DRVCTRL5_MASK) | DRVCTRL5_IRQ5(7) + | DRVCTRL5_PWM0(7) + | DRVCTRL5_PWM1(7) + | DRVCTRL5_PWM2(7) + | DRVCTRL5_A0(3) + | DRVCTRL5_A1(3) + | DRVCTRL5_A2(3) + | DRVCTRL5_A3(3)); + pfc_reg_write(PFC_DRVCTRL5, reg); + reg = mmio_read_32(PFC_DRVCTRL6); + reg = ((reg & DRVCTRL6_MASK) | DRVCTRL6_A4(3) + | DRVCTRL6_A5(3) + | DRVCTRL6_A6(3) + | DRVCTRL6_A7(3) + | DRVCTRL6_A8(7) + | DRVCTRL6_A9(7) + | DRVCTRL6_A10(7) + | DRVCTRL6_A11(7)); + pfc_reg_write(PFC_DRVCTRL6, reg); + reg = mmio_read_32(PFC_DRVCTRL7); + reg = ((reg & DRVCTRL7_MASK) | DRVCTRL7_A12(3) + | DRVCTRL7_A13(3) + | DRVCTRL7_A14(3) + | DRVCTRL7_A15(3) + | DRVCTRL7_A16(3) + | DRVCTRL7_A17(3) + | DRVCTRL7_A18(3) + | DRVCTRL7_A19(3)); + pfc_reg_write(PFC_DRVCTRL7, reg); + reg = mmio_read_32(PFC_DRVCTRL8); + reg = ((reg & DRVCTRL8_MASK) | DRVCTRL8_CLKOUT(7) + | DRVCTRL8_CS0(7) + | DRVCTRL8_CS1_A2(7) + | DRVCTRL8_BS(7) + | DRVCTRL8_RD(7) + | DRVCTRL8_RD_W(7) + | DRVCTRL8_WE0(7) + | DRVCTRL8_WE1(7)); + pfc_reg_write(PFC_DRVCTRL8, reg); + reg = mmio_read_32(PFC_DRVCTRL9); + reg = ((reg & DRVCTRL9_MASK) | DRVCTRL9_EX_WAIT0(7) + | DRVCTRL9_PRESETOU(7) + | DRVCTRL9_D0(7) + | DRVCTRL9_D1(7) + | DRVCTRL9_D2(7) + | DRVCTRL9_D3(7) + | DRVCTRL9_D4(7) + | DRVCTRL9_D5(7)); + pfc_reg_write(PFC_DRVCTRL9, reg); + reg = mmio_read_32(PFC_DRVCTRL10); + reg = ((reg & DRVCTRL10_MASK) | DRVCTRL10_D6(7) + | DRVCTRL10_D7(7) + | DRVCTRL10_D8(3) + | DRVCTRL10_D9(3) + | DRVCTRL10_D10(3) + | DRVCTRL10_D11(3) + | DRVCTRL10_D12(3) + | DRVCTRL10_D13(3)); + pfc_reg_write(PFC_DRVCTRL10, reg); + reg = mmio_read_32(PFC_DRVCTRL11); + reg = ((reg & DRVCTRL11_MASK) | DRVCTRL11_D14(3) + | DRVCTRL11_D15(3) + | DRVCTRL11_AVS1(7) + | DRVCTRL11_AVS2(7) + | DRVCTRL11_GP7_02(7) + | DRVCTRL11_GP7_03(7) + | DRVCTRL11_DU_DOTCLKIN0(3) + | DRVCTRL11_DU_DOTCLKIN1(3)); + pfc_reg_write(PFC_DRVCTRL11, reg); + reg = mmio_read_32(PFC_DRVCTRL12); + reg = ((reg & DRVCTRL12_MASK) | DRVCTRL12_DU_DOTCLKIN2(3) + | DRVCTRL12_DU_DOTCLKIN3(3) + | DRVCTRL12_DU_FSCLKST(3) + | DRVCTRL12_DU_TMS(3)); + pfc_reg_write(PFC_DRVCTRL12, reg); + reg = mmio_read_32(PFC_DRVCTRL13); + reg = ((reg & DRVCTRL13_MASK) | DRVCTRL13_TDO(3) + | DRVCTRL13_ASEBRK(3) + | DRVCTRL13_SD0_CLK(7) + | DRVCTRL13_SD0_CMD(7) + | DRVCTRL13_SD0_DAT0(7) + | DRVCTRL13_SD0_DAT1(7) + | DRVCTRL13_SD0_DAT2(7) + | DRVCTRL13_SD0_DAT3(7)); + pfc_reg_write(PFC_DRVCTRL13, reg); + reg = mmio_read_32(PFC_DRVCTRL14); + reg = ((reg & DRVCTRL14_MASK) | DRVCTRL14_SD1_CLK(7) + | DRVCTRL14_SD1_CMD(7) + | DRVCTRL14_SD1_DAT0(5) + | DRVCTRL14_SD1_DAT1(5) + | DRVCTRL14_SD1_DAT2(5) + | DRVCTRL14_SD1_DAT3(5) + | DRVCTRL14_SD2_CLK(5) + | DRVCTRL14_SD2_CMD(5)); + pfc_reg_write(PFC_DRVCTRL14, reg); + reg = mmio_read_32(PFC_DRVCTRL15); + reg = ((reg & DRVCTRL15_MASK) | DRVCTRL15_SD2_DAT0(5) + | DRVCTRL15_SD2_DAT1(5) + | DRVCTRL15_SD2_DAT2(5) + | DRVCTRL15_SD2_DAT3(5) + | DRVCTRL15_SD2_DS(5) + | DRVCTRL15_SD3_CLK(7) + | DRVCTRL15_SD3_CMD(7) + | DRVCTRL15_SD3_DAT0(7)); + pfc_reg_write(PFC_DRVCTRL15, reg); + reg = mmio_read_32(PFC_DRVCTRL16); + reg = ((reg & DRVCTRL16_MASK) | DRVCTRL16_SD3_DAT1(7) + | DRVCTRL16_SD3_DAT2(7) + | DRVCTRL16_SD3_DAT3(7) + | DRVCTRL16_SD3_DAT4(7) + | DRVCTRL16_SD3_DAT5(7) + | DRVCTRL16_SD3_DAT6(7) + | DRVCTRL16_SD3_DAT7(7) + | DRVCTRL16_SD3_DS(7)); + pfc_reg_write(PFC_DRVCTRL16, reg); + reg = mmio_read_32(PFC_DRVCTRL17); + reg = ((reg & DRVCTRL17_MASK) | DRVCTRL17_SD0_CD(7) + | DRVCTRL17_SD0_WP(7) + | DRVCTRL17_SD1_CD(7) + | DRVCTRL17_SD1_WP(7) + | DRVCTRL17_SCK0(7) + | DRVCTRL17_RX0(7) + | DRVCTRL17_TX0(7) + | DRVCTRL17_CTS0(7)); + pfc_reg_write(PFC_DRVCTRL17, reg); + reg = mmio_read_32(PFC_DRVCTRL18); + reg = ((reg & DRVCTRL18_MASK) | DRVCTRL18_RTS0_TANS(7) + | DRVCTRL18_RX1(7) + | DRVCTRL18_TX1(7) + | DRVCTRL18_CTS1(7) + | DRVCTRL18_RTS1_TANS(7) + | DRVCTRL18_SCK2(7) + | DRVCTRL18_TX2(7) + | DRVCTRL18_RX2(7)); + pfc_reg_write(PFC_DRVCTRL18, reg); + reg = mmio_read_32(PFC_DRVCTRL19); + reg = ((reg & DRVCTRL19_MASK) | DRVCTRL19_HSCK0(7) + | DRVCTRL19_HRX0(7) + | DRVCTRL19_HTX0(7) + | DRVCTRL19_HCTS0(7) + | DRVCTRL19_HRTS0(7) + | DRVCTRL19_MSIOF0_SCK(7) + | DRVCTRL19_MSIOF0_SYNC(7) + | DRVCTRL19_MSIOF0_SS1(7)); + pfc_reg_write(PFC_DRVCTRL19, reg); + reg = mmio_read_32(PFC_DRVCTRL20); + reg = ((reg & DRVCTRL20_MASK) | DRVCTRL20_MSIOF0_TXD(7) + | DRVCTRL20_MSIOF0_SS2(7) + | DRVCTRL20_MSIOF0_RXD(7) + | DRVCTRL20_MLB_CLK(7) + | DRVCTRL20_MLB_SIG(7) + | DRVCTRL20_MLB_DAT(7) + | DRVCTRL20_MLB_REF(7) + | DRVCTRL20_SSI_SCK0129(7)); + pfc_reg_write(PFC_DRVCTRL20, reg); + reg = mmio_read_32(PFC_DRVCTRL21); + reg = ((reg & DRVCTRL21_MASK) | DRVCTRL21_SSI_WS0129(7) + | DRVCTRL21_SSI_SDATA0(7) + | DRVCTRL21_SSI_SDATA1(7) + | DRVCTRL21_SSI_SDATA2(7) + | DRVCTRL21_SSI_SCK34(7) + | DRVCTRL21_SSI_WS34(7) + | DRVCTRL21_SSI_SDATA3(7) + | DRVCTRL21_SSI_SCK4(7)); + pfc_reg_write(PFC_DRVCTRL21, reg); + reg = mmio_read_32(PFC_DRVCTRL22); + reg = ((reg & DRVCTRL22_MASK) | DRVCTRL22_SSI_WS4(7) + | DRVCTRL22_SSI_SDATA4(7) + | DRVCTRL22_SSI_SCK5(7) + | DRVCTRL22_SSI_WS5(7) + | DRVCTRL22_SSI_SDATA5(7) + | DRVCTRL22_SSI_SCK6(7) + | DRVCTRL22_SSI_WS6(7) + | DRVCTRL22_SSI_SDATA6(7)); + pfc_reg_write(PFC_DRVCTRL22, reg); + reg = mmio_read_32(PFC_DRVCTRL23); + reg = ((reg & DRVCTRL23_MASK) | DRVCTRL23_SSI_SCK78(7) + | DRVCTRL23_SSI_WS78(7) + | DRVCTRL23_SSI_SDATA7(7) + | DRVCTRL23_SSI_SDATA8(7) + | DRVCTRL23_SSI_SDATA9(7) + | DRVCTRL23_AUDIO_CLKA(7) + | DRVCTRL23_AUDIO_CLKB(7) + | DRVCTRL23_USB0_PWEN(7)); + pfc_reg_write(PFC_DRVCTRL23, reg); + reg = mmio_read_32(PFC_DRVCTRL24); + reg = ((reg & DRVCTRL24_MASK) | DRVCTRL24_USB0_OVC(7) + | DRVCTRL24_USB1_PWEN(7) + | DRVCTRL24_USB1_OVC(7) + | DRVCTRL24_USB30_PWEN(7) + | DRVCTRL24_USB30_OVC(7) + | DRVCTRL24_USB31_PWEN(7) + | DRVCTRL24_USB31_OVC(7)); + pfc_reg_write(PFC_DRVCTRL24, reg); + + /* initialize LSI pin pull-up/down control */ + pfc_reg_write(PFC_PUD0, 0x00005FBFU); + pfc_reg_write(PFC_PUD1, 0x00300EFEU); + pfc_reg_write(PFC_PUD2, 0x330001E6U); + pfc_reg_write(PFC_PUD3, 0x000002E0U); + pfc_reg_write(PFC_PUD4, 0xFFFFFF00U); + pfc_reg_write(PFC_PUD5, 0x7F5FFF87U); + pfc_reg_write(PFC_PUD6, 0x00000055U); + + /* initialize LSI pin pull-enable register */ + pfc_reg_write(PFC_PUEN0, 0x00000FFFU); + pfc_reg_write(PFC_PUEN1, 0x00100234U); + pfc_reg_write(PFC_PUEN2, 0x000004C4U); + pfc_reg_write(PFC_PUEN3, 0x00000200U); + pfc_reg_write(PFC_PUEN4, 0x3E000000U); + pfc_reg_write(PFC_PUEN5, 0x1F000805U); + pfc_reg_write(PFC_PUEN6, 0x00000006U); + + /* initialize positive/negative logic select */ + mmio_write_32(GPIO_POSNEG0, 0x00000000U); + mmio_write_32(GPIO_POSNEG1, 0x00000000U); + mmio_write_32(GPIO_POSNEG2, 0x00000000U); + mmio_write_32(GPIO_POSNEG3, 0x00000000U); + mmio_write_32(GPIO_POSNEG4, 0x00000000U); + mmio_write_32(GPIO_POSNEG5, 0x00000000U); + mmio_write_32(GPIO_POSNEG6, 0x00000000U); + mmio_write_32(GPIO_POSNEG7, 0x00000000U); + + /* initialize general IO/interrupt switching */ + mmio_write_32(GPIO_IOINTSEL0, 0x00000000U); + mmio_write_32(GPIO_IOINTSEL1, 0x00000000U); + mmio_write_32(GPIO_IOINTSEL2, 0x00000000U); + mmio_write_32(GPIO_IOINTSEL3, 0x00000000U); + mmio_write_32(GPIO_IOINTSEL4, 0x00000000U); + mmio_write_32(GPIO_IOINTSEL5, 0x00000000U); + mmio_write_32(GPIO_IOINTSEL6, 0x00000000U); + mmio_write_32(GPIO_IOINTSEL7, 0x00000000U); + + /* initialize general output register */ + mmio_write_32(GPIO_OUTDT0, 0x00000001U); + mmio_write_32(GPIO_OUTDT1, 0x00000000U); + mmio_write_32(GPIO_OUTDT2, 0x00000400U); + mmio_write_32(GPIO_OUTDT3, 0x00000000U); + mmio_write_32(GPIO_OUTDT4, 0x00000000U); + mmio_write_32(GPIO_OUTDT5, 0x00000000U); + mmio_write_32(GPIO_OUTDT6, 0x00003800U); + mmio_write_32(GPIO_OUTDT7, 0x00000003U); + + /* initialize general input/output switching */ + mmio_write_32(GPIO_INOUTSEL0, 0x00000001U); + mmio_write_32(GPIO_INOUTSEL1, 0x00100B00U); + mmio_write_32(GPIO_INOUTSEL2, 0x00000418U); + mmio_write_32(GPIO_INOUTSEL3, 0x00002000U); + mmio_write_32(GPIO_INOUTSEL4, 0x00000040U); + mmio_write_32(GPIO_INOUTSEL5, 0x00000208U); + mmio_write_32(GPIO_INOUTSEL6, 0x00013F00U); + mmio_write_32(GPIO_INOUTSEL7, 0x00000003U); + +} diff --git a/drivers/renesas/rzg/pfc/G2M/pfc_init_g2m.h b/drivers/renesas/rzg/pfc/G2M/pfc_init_g2m.h new file mode 100644 index 000000000..3315cd6b9 --- /dev/null +++ b/drivers/renesas/rzg/pfc/G2M/pfc_init_g2m.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PFC_INIT_G2M_H +#define PFC_INIT_G2M_H + +void pfc_init_g2m(void); + +#endif /* PFC_INIT_G2M_H */ diff --git a/drivers/renesas/rzg/pfc/pfc.mk b/drivers/renesas/rzg/pfc/pfc.mk new file mode 100644 index 000000000..5cae658b3 --- /dev/null +++ b/drivers/renesas/rzg/pfc/pfc.mk @@ -0,0 +1,20 @@ +# +# Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +ifeq (${RCAR_LSI},${RCAR_AUTO}) + BL2_SOURCES += drivers/renesas/rzg/pfc/G2M/pfc_init_g2m.c + +else ifdef RCAR_LSI_CUT_COMPAT + ifeq (${RCAR_LSI},${RZ_G2M}) + BL2_SOURCES += drivers/renesas/rzg/pfc/G2M/pfc_init_g2m.c + endif +else + ifeq (${RCAR_LSI},${RZ_G2M}) + BL2_SOURCES += drivers/renesas/rzg/pfc/G2M/pfc_init_g2m.c + endif +endif + +BL2_SOURCES += drivers/renesas/rzg/pfc/pfc_init.c diff --git a/drivers/renesas/rzg/pfc/pfc_init.c b/drivers/renesas/rzg/pfc/pfc_init.c new file mode 100644 index 000000000..f51992d2e --- /dev/null +++ b/drivers/renesas/rzg/pfc/pfc_init.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include + +#include +#include + +#if RCAR_LSI == RCAR_AUTO +#include "G2M/pfc_init_g2m.h" +#endif /* RCAR_LSI == RCAR_AUTO */ +#if (RCAR_LSI == RZ_G2M) +#include "G2M/pfc_init_g2m.h" +#endif /* RCAR_LSI == RZ_G2M */ +#include "rcar_def.h" + +#define PRR_PRODUCT_ERR(reg) \ + do { \ + ERROR("LSI Product ID(PRR=0x%x) PFC init not supported.\n", \ + reg); \ + panic(); \ + } while (0) + +#define PRR_CUT_ERR(reg) \ + do { \ + ERROR("LSI Cut ID(PRR=0x%x) PFC init not supported.\n", \ + reg); \ + panic();\ + } while (0) + +void rzg_pfc_init(void) +{ + uint32_t reg; + + reg = mmio_read_32(RCAR_PRR); +#if RCAR_LSI == RCAR_AUTO + switch (reg & PRR_PRODUCT_MASK) { + case PRR_PRODUCT_M3: + pfc_init_g2m(); + break; + default: + PRR_PRODUCT_ERR(reg); + break; + } + +#elif RCAR_LSI_CUT_COMPAT /* RCAR_LSI == RCAR_AUTO */ + switch (reg & PRR_PRODUCT_MASK) { + case PRR_PRODUCT_M3: +#if RCAR_LSI != RZ_G2M + PRR_PRODUCT_ERR(reg); +#else /* RCAR_LSI != RZ_G2M */ + pfc_init_g2m(); +#endif /* RCAR_LSI != RZ_G2M */ + break; + default: + PRR_PRODUCT_ERR(reg); + break; + } + +#else /* RCAR_LSI == RCAR_AUTO */ +#if (RCAR_LSI == RZ_G2M) + if ((reg & PRR_PRODUCT_MASK) != PRR_PRODUCT_M3) { + PRR_PRODUCT_ERR(reg); + } + pfc_init_m3(); +#else /* RCAR_LSI == RZ_G2M */ +#error "Don't have PFC initialize routine(unknown)." +#endif /* RCAR_LSI == RZ_G2M */ +#endif /* RCAR_LSI == RCAR_AUTO */ +} -- cgit v1.2.3 From b9adcf5634428df72e906ab07a12974047c86e44 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Mon, 9 Nov 2020 09:50:25 +0000 Subject: renesas: rzg: emmc: Enable RZ/G2M support Enable eMMC driver support for RZ/G2M SoC. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: I34803060c5b592ac24720b11d4a8cd3f9f40caee --- drivers/renesas/common/emmc/emmc_registers.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/renesas/common/emmc/emmc_registers.h b/drivers/renesas/common/emmc/emmc_registers.h index ae689ca24..392abb8fb 100644 --- a/drivers/renesas/common/emmc/emmc_registers.h +++ b/drivers/renesas/common/emmc/emmc_registers.h @@ -11,11 +11,11 @@ #define MMC_CH0 (0U) /* SDHI2/MMC0 */ #define MMC_CH1 (1U) /* SDHI3/MMC1 */ -#if RCAR_LSI == RCAR_E3 -#define USE_MMC_CH (MMC_CH1) /* R-Car E3 */ -#else /* RCAR_LSI == RCAR_E3 */ +#if (RCAR_LSI == RCAR_E3) || (RCAR_LSI == RZ_G2M) +#define USE_MMC_CH (MMC_CH1) /* R-Car E3 or RZ/G2M */ +#else /* RCAR_LSI == RCAR_E3 || RCAR_LSI == RZ_G2M */ #define USE_MMC_CH (MMC_CH0) /* R-Car H3/M3/M3N */ -#endif /* RCAR_LSI == RCAR_E3 */ +#endif /* RCAR_LSI == RCAR_E3 || RCAR_LSI == RZ_G2M */ #define BIT0 (0x00000001U) #define BIT1 (0x00000002U) -- cgit v1.2.3 From 2bc485858b9cb3d2f47470e2798fcab7f920a10f Mon Sep 17 00:00:00 2001 From: Biju Das Date: Mon, 7 Dec 2020 13:14:38 +0000 Subject: doc: renesas: Document platforms based on RZ/G2 SoC's Document the platforms based on RZ/G2 SoC's. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: I9ce5b9df3573b1198c5c7be79b5471d54573609a --- docs/about/maintainers.rst | 12 +++ docs/plat/index.rst | 1 + docs/plat/rz-g2.rst | 228 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 241 insertions(+) create mode 100644 docs/plat/rz-g2.rst diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst index 91a5621b9..5ac1730d5 100644 --- a/docs/about/maintainers.rst +++ b/docs/about/maintainers.rst @@ -486,6 +486,17 @@ Renesas rcar-gen3 platform port :F: drivers/renesas/rcar :F: tools/renesas/rcar_layout_create +Renesas RZ/G2 platform port +^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:M: Biju Das +:G: `bijucdas`_ +:F: docs/plat/rz-g2.rst +:F: plat/renesas/common +:F: plat/renesas/rzg +:F: drivers/renesas/common +:F: drivers/renesas/rzg +:F: tools/renesas/rzg_layout_create + RockChip platform port ^^^^^^^^^^^^^^^^^^^^^^ :M: Tony Xie @@ -601,6 +612,7 @@ Build system .. _AlexeiFedorov: https://github.com/AlexeiFedorov .. _Andre-ARM: https://github.com/Andre-ARM .. _Anson-Huang: https://github.com/Anson-Huang +.. _bijucdas: https://github.com/bijucdas .. _bryanodonoghue: https://github.com/bryanodonoghue .. _b49020: https://github.com/b49020 .. _carlocaione: https://github.com/carlocaione diff --git a/docs/plat/index.rst b/docs/plat/index.rst index fb60e5639..3cbb55246 100644 --- a/docs/plat/index.rst +++ b/docs/plat/index.rst @@ -32,6 +32,7 @@ Platform Ports rpi3 rpi4 rcar-gen3 + rz-g2 rockchip socionext-uniphier synquacer diff --git a/docs/plat/rz-g2.rst b/docs/plat/rz-g2.rst new file mode 100644 index 000000000..e7ae62040 --- /dev/null +++ b/docs/plat/rz-g2.rst @@ -0,0 +1,228 @@ +Renesas RZ/G +============ + +The "RZ/G" Family of high-end 64-bit Arm®-based microprocessors (MPUs) +enables the solutions required for the smart society of the future. +Through a variety of Arm Cortex®-A53 and A57-based devices, engineers can +easily implement high-resolution human machine interfaces (HMI), embedded +vision, embedded artificial intelligence (e-AI) and real-time control and +industrial ethernet connectivity. + +The scalable RZ/G hardware platform and flexible software platform +cover the full product range, from the premium class to the entry +level. Plug-ins are available for multiple open-source software tools. + + +Renesas RZ/G2 reference platforms: +---------------------------------- + ++--------------+----------------------------------------------------------------------------------+ +| Board | Details | ++==============+===============+==================================================================+ +| hihope-rzg2h | "96 boards" compatible board from Hoperun equipped with Renesas RZ/G2H SoC | +| +----------------------------------------------------------------------------------+ +| | http://hihope.org/product/musashi | ++--------------+----------------------------------------------------------------------------------+ +| hihope-rzg2m | "96 boards" compatible board from Hoperun equipped with Renesas RZ/G2M SoC | +| +----------------------------------------------------------------------------------+ +| | http://hihope.org/product/musashi | ++--------------+----------------------------------------------------------------------------------+ +| hihope-rzg2n | "96 boards" compatible board from Hoperun equipped with Renesas RZ/G2N SoC | +| +----------------------------------------------------------------------------------+ +| | http://hihope.org/product/musashi | ++--------------+----------------------------------------------------------------------------------+ +| ek874 | "96 boards" compatible board from Silicon Linux equipped with Renesas RZ/G2E SoC | +| +----------------------------------------------------------------------------------+ +| | https://www.si-linux.co.jp/index.php?CAT%2FCAT874 | ++--------------+----------------------------------------------------------------------------------+ + +`boards info `__ + +The current TF-A port has been tested on the HiHope RZ/G2M +SoC_id r8a774a1 revision ES1.3. + + +:: + + ARM CA57 (ARMv8) 1.5 GHz dual core, with NEON/VFPv4, L1$ I/D 48K/32K, L2$ 1MB + ARM CA53 (ARMv8) 1.2 GHz quad core, with NEON/VFPv4, L1$ I/D 32K/32K, L2$ 512K + Memory controller for LPDDR4-3200 4GB in 2 channels(32-bit bus mode) + Two- and three-dimensional graphics engines, + Video processing units, + Display Output, + Video Input, + SD card host interface, + USB3.0 and USB2.0 interfaces, + CAN interfaces, + Ethernet AVB, + Wi-Fi + BT, + PCI Express Interfaces, + Memories + INTERNAL 384KB SYSTEM RAM + DDR 4 GB LPDDR4 + QSPI FLASH 64MB + EMMC 32 GB EMMC (HS400 240 MBYTES/S) + MICROSD-CARD SLOT (SDR104 100 MBYTES/S) + +Overview +-------- +On RZ/G2 SoCs the BOOTROM starts the cpu at EL3; for this port BL2 +will therefore be entered at this exception level (the Renesas' ATF +reference tree [1] resets into EL1 before entering BL2 - see its +bl2.ld.S) + +BL2 initializes DDR before determining the boot reason (cold or warm). + +Once BL2 boots, it determines the boot reason, writes it to shared +memory (BOOT_KIND_BASE) together with the BL31 parameters +(PARAMS_BASE) and jumps to BL31. + +To all effects, BL31 is as if it is being entered in reset mode since +it still needs to initialize the rest of the cores; this is the reason +behind using direct shared memory access to BOOT_KIND_BASE _and_ +PARAMS_BASE instead of using registers to get to those locations (see +el3_common_macros.S and bl31_entrypoint.S for the RESET_TO_BL31 use +case). + +[1] https://github.com/renesas-rz/meta-rzg2/tree/BSP-1.0.5/recipes-bsp/arm-trusted-firmware/files + + +How to build +------------ + +The TF-A build options depend on the target board so you will have to +refer to those specific instructions. What follows is customized to +the HiHope RZ/G2M development kit used in this port. + +Build Tested: +~~~~~~~~~~~~~ + +.. code:: bash + + make bl2 bl31 rzg LOG_LEVEL=40 PLAT=rzg LSI=G2M RCAR_DRAM_SPLIT=2\ + RCAR_LOSSY_ENABLE=1 SPD="none" MBEDTLS_DIR=$mbedtls + +System Tested: +~~~~~~~~~~~~~~ +* mbed_tls: + git@github.com:ARMmbed/mbedtls.git [devel] + +| commit 72ca39737f974db44723760623d1b29980c00a88 +| Merge: ef94c4fcf dd9ec1c57 +| Author: Janos Follath +| Date: Wed Oct 7 09:21:01 2020 +0100 + +* u-boot: + The port has beent tested using mainline uboot with HiHope RZ/G2M board + specific patches. + +| commit 46ce9e777c1314ccb78906992b94001194eaa87b +| Author: Heiko Schocher +| Date: Tue Nov 3 15:22:36 2020 +0100 + +* linux: + The port has beent tested using mainline kernel. + +| commit f8394f232b1eab649ce2df5c5f15b0e528c92091 +| Author: Linus Torvalds +| Date: Sun Nov 8 16:10:16 2020 -0800 +| Linux 5.10-rc3 + +TF-A Build Procedure +~~~~~~~~~~~~~~~~~~~~ + +- Fetch all the above 3 repositories. + +- Prepare the AARCH64 toolchain. + +- Build u-boot using hihope_rzg2_defconfig. + + Result: u-boot-elf.srec + +.. code:: bash + + make CROSS_COMPILE=aarch64-linux-gnu- + hihope_rzg2_defconfig + + make CROSS_COMPILE=aarch64-linux-gnu- + +- Build TF-A + + Result: bootparam_sa0.srec, cert_header_sa6.srec, bl2.srec, bl31.srec + +.. code:: bash + + make bl2 bl31 rzg LOG_LEVEL=40 PLAT=rzg LSI=G2M RCAR_DRAM_SPLIT=2\ + RCAR_LOSSY_ENABLE=1 SPD="none" MBEDTLS_DIR=$mbedtls + + +Install Procedure +~~~~~~~~~~~~~~~~~ + +- Boot the board in Mini-monitor mode and enable access to the + QSPI flash. + + +- Use the flash_writer utility[2] to flash all the SREC files. + +[2] https://github.com/renesas-rz/rzg2_flash_writer + + +Boot trace +---------- +:: + + INFO: ARM GICv2 driver initialized + NOTICE: BL2: RZ/G2 Initial Program Loader(CA57) Rev.2.0.6 + NOTICE: BL2: PRR is RZ/G2M Ver.1.3 + NOTICE: BL2: Board is HiHope RZ/G2M Rev.4.0 + NOTICE: BL2: Boot device is QSPI Flash(40MHz) + NOTICE: BL2: LCM state is unknown + NOTICE: BL2: DDR3200(rev.0.40) + NOTICE: BL2: [COLD_BOOT] + NOTICE: BL2: DRAM Split is 2ch + NOTICE: BL2: QoS is default setting(rev.0.19) + NOTICE: BL2: DRAM refresh interval 1.95 usec + NOTICE: BL2: Periodic Write DQ Training + NOTICE: BL2: CH0: 400000000 - 47fffffff, 2 GiB + NOTICE: BL2: CH2: 600000000 - 67fffffff, 2 GiB + NOTICE: BL2: Lossy Decomp areas + NOTICE: Entry 0: DCMPAREACRAx:0x80000540 DCMPAREACRBx:0x570 + NOTICE: Entry 1: DCMPAREACRAx:0x40000000 DCMPAREACRBx:0x0 + NOTICE: Entry 2: DCMPAREACRAx:0x20000000 DCMPAREACRBx:0x0 + NOTICE: BL2: FDT at 0xe631db30 + NOTICE: BL2: v2.3(release):v2.4-rc0-2-g1433701e5 + NOTICE: BL2: Built : 13:45:26, Nov 7 2020 + NOTICE: BL2: Normal boot + INFO: BL2: Doing platform setup + INFO: BL2: Loading image id 3 + NOTICE: BL2: dst=0xe631d200 src=0x8180000 len=512(0x200) + NOTICE: BL2: dst=0x43f00000 src=0x8180400 len=6144(0x1800) + WARNING: r-car ignoring the BL31 size from certificate,using RCAR_TRUSTED_SRAM_SIZE instead + INFO: Loading image id=3 at address 0x44000000 + NOTICE: rcar_file_len: len: 0x0003e000 + NOTICE: BL2: dst=0x44000000 src=0x81c0000 len=253952(0x3e000) + INFO: Image id=3 loaded: 0x44000000 - 0x4403e000 + INFO: BL2: Loading image id 5 + INFO: Loading image id=5 at address 0x50000000 + NOTICE: rcar_file_len: len: 0x00100000 + NOTICE: BL2: dst=0x50000000 src=0x8300000 len=1048576(0x100000) + INFO: Image id=5 loaded: 0x50000000 - 0x50100000 + NOTICE: BL2: Booting BL31 + INFO: Entry point address = 0x44000000 + INFO: SPSR = 0x3cd + + + U-Boot 2021.01-rc1-00244-gac37e14fbd (Nov 04 2020 - 20:03:34 +0000) + + CPU: Renesas Electronics R8A774A1 rev 1.3 + Model: HopeRun HiHope RZ/G2M with sub board + DRAM: 3.9 GiB + MMC: mmc@ee100000: 0, mmc@ee160000: 1 + Loading Environment from MMC... OK + In: serial@e6e88000 + Out: serial@e6e88000 + Err: serial@e6e88000 + Net: eth0: ethernet@e6800000 + Hit any key to stop autoboot: 0 + => -- cgit v1.2.3 From 94a73ef330078b0d7cd1b5433a5a07d5cf976714 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Fri, 18 Dec 2020 17:41:01 +0000 Subject: plat: renesas: rzg: DT memory node enhancements Add DT node support for channel 0 where physical memory is split between 32bit space and 64bit space. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Change-Id: I99a18dbb14cdb54100a836c16445242e430794e3 --- plat/renesas/rzg/bl2_plat_setup.c | 72 ++++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 24 deletions(-) diff --git a/plat/renesas/rzg/bl2_plat_setup.c b/plat/renesas/rzg/bl2_plat_setup.c index 4b3f38bd2..13f413b55 100644 --- a/plat/renesas/rzg/bl2_plat_setup.c +++ b/plat/renesas/rzg/bl2_plat_setup.c @@ -36,6 +36,12 @@ #include "rom_api.h" #define MAX_DRAM_CHANNELS 4 +/* + * DDR ch0 has a shadow area mapped in 32bit address space. + * Physical address 0x4_0000_0000 - 0x4_7fff_ffff in 64bit space + * is mapped to 0x4000_0000 - 0xbfff_ffff in 32bit space. + */ +#define MAX_DRAM_SIZE_CH0_32BIT_ADDR_SPACE 0x80000000ULL #if RCAR_BL2_DCACHE == 1 /* @@ -447,12 +453,38 @@ static void bl2_populate_compatible_string(void *dt) } } -static void bl2_advertise_dram_entries(uint64_t dram_config[8]) +static int bl2_add_memory_node(uint64_t start, uint64_t size) { char nodename[32] = { 0 }; - uint64_t start, size; uint64_t fdtsize; - int ret, node, chan; + int ret, node; + + fdtsize = cpu_to_fdt64(size); + + snprintf(nodename, sizeof(nodename), "memory@"); + unsigned_num_print(start, 16, nodename + strlen(nodename)); + node = ret = fdt_add_subnode(fdt, 0, nodename); + if (ret < 0) { + return ret; + } + + ret = fdt_setprop_string(fdt, node, "device_type", "memory"); + if (ret < 0) { + return ret; + } + + ret = fdt_setprop_u64(fdt, node, "reg", start); + if (ret < 0) { + return ret; + } + + return fdt_appendprop(fdt, node, "reg", &fdtsize, sizeof(fdtsize)); +} + +static void bl2_advertise_dram_entries(uint64_t dram_config[8]) +{ + uint64_t start, size; + int ret, chan; for (chan = 0; chan < MAX_DRAM_CHANNELS; chan++) { start = dram_config[2 * chan]; @@ -485,31 +517,23 @@ static void bl2_advertise_dram_entries(uint64_t dram_config[8]) * 128 MiB are reserved */ if (chan == 0) { + /* + * Maximum DDR size in Channel 0 for 32 bit space is 2GB, Add DT node + * for remaining region in 64 bit address space + */ + if (size > MAX_DRAM_SIZE_CH0_32BIT_ADDR_SPACE) { + start = dram_config[chan] + MAX_DRAM_SIZE_CH0_32BIT_ADDR_SPACE; + size -= MAX_DRAM_SIZE_CH0_32BIT_ADDR_SPACE; + ret = bl2_add_memory_node(start, size); + if (ret < 0) { + goto err; + } + } start = 0x48000000U; size -= 0x8000000U; } - fdtsize = cpu_to_fdt64(size); - - snprintf(nodename, sizeof(nodename), "memory@"); - unsigned_num_print(start, 16, nodename + strlen(nodename)); - node = ret = fdt_add_subnode(fdt, 0, nodename); - if (ret < 0) { - goto err; - } - - ret = fdt_setprop_string(fdt, node, "device_type", "memory"); - if (ret < 0) { - goto err; - } - - ret = fdt_setprop_u64(fdt, node, "reg", start); - if (ret < 0) { - goto err; - } - - ret = fdt_appendprop(fdt, node, "reg", &fdtsize, - sizeof(fdtsize)); + ret = bl2_add_memory_node(start, size); if (ret < 0) { goto err; } -- cgit v1.2.3 From d60642a4674a2dc6e53417ab37ffbd2369d7a7a2 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Sat, 19 Dec 2020 09:03:44 +0000 Subject: doc: renesas: Update code owner for Renesas platforms Add Marek Vasut as the code owner for the common code shared by both Renesas R-Car and RZ/G2 platforms. Signed-off-by: Biju Das Change-Id: I3c0a402f4663ffcf4d2df408a3ccd4d1a8629b3a --- docs/about/maintainers.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst index 5ac1730d5..7c91e18b0 100644 --- a/docs/about/maintainers.rst +++ b/docs/about/maintainers.rst @@ -482,7 +482,9 @@ Renesas rcar-gen3 platform port :M: Marek Vasut :G: `marex`_ :F: docs/plat/rcar-gen3.rst +:F: plat/renesas/common :F: plat/renesas/rcar +:F: drivers/renesas/common :F: drivers/renesas/rcar :F: tools/renesas/rcar_layout_create @@ -490,6 +492,8 @@ Renesas RZ/G2 platform port ^^^^^^^^^^^^^^^^^^^^^^^^^^^ :M: Biju Das :G: `bijucdas`_ +:M: Marek Vasut +:G: `marex`_ :F: docs/plat/rz-g2.rst :F: plat/renesas/common :F: plat/renesas/rzg -- cgit v1.2.3 From afda405b3db15385af0fdc16960ac28a4c85917c Mon Sep 17 00:00:00 2001 From: Biju Das Date: Sat, 19 Dec 2020 09:07:22 +0000 Subject: doc: renesas: Update RZ/G2 code owner list Add Lad Prabhakar as the code owner for the newly added RZ/G2 platforms. Signed-off-by: Biju Das Change-Id: Ic9bacaf31d653e1e553fa70043053805f56a2b84 --- docs/about/maintainers.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst index 7c91e18b0..90aed508c 100644 --- a/docs/about/maintainers.rst +++ b/docs/about/maintainers.rst @@ -494,6 +494,8 @@ Renesas RZ/G2 platform port :G: `bijucdas`_ :M: Marek Vasut :G: `marex`_ +:M: Lad Prabhakar +:G: `prabhakarlad`_ :F: docs/plat/rz-g2.rst :F: plat/renesas/common :F: plat/renesas/rzg @@ -637,6 +639,7 @@ Build system .. _mtk09422: https://github.com/mtk09422 .. _niej: https://github.com/niej .. _npoushin: https://github.com/npoushin +.. _prabhakarlad: https://github.com/prabhakarlad .. _qoriq-open-source: https://github.com/qoriq-open-source .. _remi-triplefault: https://github.com/repk .. _rockchip-linux: https://github.com/rockchip-linux -- cgit v1.2.3 From 3a2710dcab0dc6dc625f0a4956a44bace1788618 Mon Sep 17 00:00:00 2001 From: johpow01 Date: Wed, 7 Oct 2020 15:08:01 -0500 Subject: Workaround for Cortex A78 erratum 1951500 Cortex A78 erratum 1951500 is a Cat B erratum that applies to revisions r0p0, r1p0, and r1p1. The workaround is to insert a DMB ST before acquire atomic instructions without release semantics. This workaround works on revisions r1p0 and r1p1, in r0p0 there is no workaround. SDEN can be found here: https://documentation-service.arm.com/static/5fb66157ca04df4095c1cc2e Signed-off-by: John Powell Change-Id: I47610cee75af6a127ea65edc4d5cffc7e6a2d0a3 --- docs/design/cpu-specific-build-macros.rst | 4 +++ include/lib/cpus/errata_report.h | 3 ++ lib/cpus/aarch64/cortex_a78.S | 60 +++++++++++++++++++++++++++++++ lib/cpus/cpu-ops.mk | 9 +++++ 4 files changed, 76 insertions(+) diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst index 09aa3017f..be7096cd3 100644 --- a/docs/design/cpu-specific-build-macros.rst +++ b/docs/design/cpu-specific-build-macros.rst @@ -268,6 +268,10 @@ For Cortex-A78, the following errata build flags are defined : - ``ERRATA_A78_1941498``: This applies errata 1941498 workaround to Cortex-A78 CPU. This needs to be enabled for revisions r0p0, r1p0, and r1p1 of the CPU. +- ``ERRATA_A78_1951500``: This applies errata 1951500 workaround to Cortex-A78 + CPU. This needs to be enabled for revisions r1p0 and r1p1, r0p0 has the same + issue but there is no workaround for that revision. + For Neoverse N1, the following errata build flags are defined : - ``ERRATA_N1_1073348``: This applies errata 1073348 workaround to Neoverse-N1 diff --git a/include/lib/cpus/errata_report.h b/include/lib/cpus/errata_report.h index 7cac77ebe..efdedf0aa 100644 --- a/include/lib/cpus/errata_report.h +++ b/include/lib/cpus/errata_report.h @@ -30,4 +30,7 @@ int errata_needs_reporting(spinlock_t *lock, uint32_t *reported); #define ERRATA_APPLIES 1 #define ERRATA_MISSING 2 +/* Macro to get CPU revision code for checking errata version compatibility. */ +#define CPU_REV(r, p) ((r << 4) | p) + #endif /* ERRATA_REPORT_H */ diff --git a/lib/cpus/aarch64/cortex_a78.S b/lib/cpus/aarch64/cortex_a78.S index ef760ed8a..f61726b46 100644 --- a/lib/cpus/aarch64/cortex_a78.S +++ b/lib/cpus/aarch64/cortex_a78.S @@ -72,6 +72,60 @@ func check_errata_1941498 b cpu_rev_var_ls endfunc check_errata_1941498 + /* -------------------------------------------------- + * Errata Workaround for A78 Erratum 1951500. + * This applies to revisions r1p0 and r1p1 of A78. + * The issue also exists in r0p0 but there is no fix + * in that revision. + * Inputs: + * x0: variant[4:7] and revision[0:3] of current cpu. + * Shall clobber: x0-x17 + * -------------------------------------------------- + */ +func errata_a78_1951500_wa + /* Compare x0 against revisions r1p0 - r1p1 */ + mov x17, x30 + bl check_errata_1951500 + cbz x0, 1f + + msr S3_6_c15_c8_0, xzr + ldr x0, =0x10E3900002 + msr S3_6_c15_c8_2, x0 + ldr x0, =0x10FFF00083 + msr S3_6_c15_c8_3, x0 + ldr x0, =0x2001003FF + msr S3_6_c15_c8_1, x0 + + mov x0, #1 + msr S3_6_c15_c8_0, x0 + ldr x0, =0x10E3800082 + msr S3_6_c15_c8_2, x0 + ldr x0, =0x10FFF00083 + msr S3_6_c15_c8_3, x0 + ldr x0, =0x2001003FF + msr S3_6_c15_c8_1, x0 + + mov x0, #2 + msr S3_6_c15_c8_0, x0 + ldr x0, =0x10E3800200 + msr S3_6_c15_c8_2, x0 + ldr x0, =0x10FFF003E0 + msr S3_6_c15_c8_3, x0 + ldr x0, =0x2001003FF + msr S3_6_c15_c8_1, x0 + + isb +1: + ret x17 +endfunc errata_a78_1951500_wa + +func check_errata_1951500 + /* 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_1951500 + /* ------------------------------------------------- * The CPU Ops reset function for Cortex-A78 * ------------------------------------------------- @@ -91,6 +145,11 @@ func cortex_a78_reset_func bl errata_a78_1941498_wa #endif +#if ERRATA_A78_1951500 + mov x0, x18 + bl errata_a78_1951500_wa +#endif + #if ENABLE_AMU /* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */ mrs x0, actlr_el3 @@ -147,6 +206,7 @@ func cortex_a78_errata_report */ report_errata ERRATA_A78_1688305, cortex_a78, 1688305 report_errata ERRATA_A78_1941498, cortex_a78, 1941498 + report_errata ERRATA_A78_1951500, cortex_a78, 1951500 ldp x8, x30, [sp], #16 ret diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk index b7dec0b77..93b538c58 100644 --- a/lib/cpus/cpu-ops.mk +++ b/lib/cpus/cpu-ops.mk @@ -298,6 +298,11 @@ ERRATA_A78_1688305 ?=0 # to revisions r0p0, r1p0, and r1p1 of the A78 cpu. ERRATA_A78_1941498 ?=0 +# Flag to apply erratum 1951500 workaround during reset. This erratum applies +# to revisions r1p0 and r1p1 of the A78 cpu. The issue is present in r0p0 as +# well but there is no workaround for that revision. +ERRATA_A78_1951500 ?=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 @@ -583,6 +588,10 @@ $(eval $(call add_define,ERRATA_A78_1688305)) $(eval $(call assert_boolean,ERRATA_A78_1941498)) $(eval $(call add_define,ERRATA_A78_1941498)) +# Process ERRATA_A78_1951500 flag +$(eval $(call assert_boolean,ERRATA_A78_1951500)) +$(eval $(call add_define,ERRATA_A78_1951500)) + # Process ERRATA_N1_1043202 flag $(eval $(call assert_boolean,ERRATA_N1_1043202)) $(eval $(call add_define,ERRATA_N1_1043202)) -- cgit v1.2.3 From 263ee781c6805172386686b65d012d188a842f05 Mon Sep 17 00:00:00 2001 From: johpow01 Date: Wed, 7 Oct 2020 14:33:15 -0500 Subject: Workaround for Cortex N1 erratum 1946160 Cortex N1 erratum 1946160 is a Cat B erratum present in r0p0, r1p0, r2p0, r3p0, r3p1, r4p0, and r4p1. The workaround is to insert a DMB ST before acquire atomic instructions without release semantics. This issue is present starting from r0p0 but this workaround applies to revisions r3p0, r3p1, r4p0, and r4p1, for previous revisions there is no workaround. SDEN can be found here: https://documentation-service.arm.com/static/5fa9304cd8dacc30eded464f Signed-off-by: John Powell Change-Id: I36e4d6728c275f1c2477dcee9b351077cf7c53e4 --- docs/design/cpu-specific-build-macros.rst | 4 ++ lib/cpus/aarch64/neoverse_n1.S | 65 ++++++++++++++++++++++++++++++- lib/cpus/cpu-ops.mk | 9 +++++ 3 files changed, 77 insertions(+), 1 deletion(-) diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst index be7096cd3..7c142d132 100644 --- a/docs/design/cpu-specific-build-macros.rst +++ b/docs/design/cpu-specific-build-macros.rst @@ -310,6 +310,10 @@ For Neoverse N1, the following errata build flags are defined : - ``ERRATA_N1_1868343``: This applies errata 1868343 workaround to Neoverse-N1 CPU. This needs to be enabled only for revision <= r4p0 of the CPU. +- ``ERRATA_N1_1946160``: This applies errata 1946160 workaround to Neoverse-N1 + CPU. This needs to be enabled for revisions r3p0, r3p1, r4p0, and r4p1, for + revisions r0p0, r1p0, and r2p0 there is no workaround. + DSU Errata Workarounds ---------------------- diff --git a/lib/cpus/aarch64/neoverse_n1.S b/lib/cpus/aarch64/neoverse_n1.S index 96891be1d..9c97cf60a 100644 --- a/lib/cpus/aarch64/neoverse_n1.S +++ b/lib/cpus/aarch64/neoverse_n1.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 */ @@ -407,6 +407,63 @@ func check_errata_1868343 b cpu_rev_var_ls endfunc check_errata_1868343 + /* -------------------------------------------------- + * Errata Workaround for Neoverse N1 Errata #1946160. + * This applies to revisions r3p0, r3p1, r4p0, and + * r4p1 of Neoverse N1. It also exists in r0p0, r1p0, + * and r2p0 but there is no fix in these revisions. + * Inputs: + * x0: variant[4:7] and revision[0:3] of current cpu. + * Shall clobber: x0-x17 + * -------------------------------------------------- + */ +func errata_n1_1946160_wa + /* + * Compare x0 against r3p0 - r4p1 + */ + mov x17, x30 + bl check_errata_1946160 + cbz x0, 1f + + mov x0, #3 + msr S3_6_C15_C8_0, x0 + ldr x0, =0x10E3900002 + msr S3_6_C15_C8_2, x0 + ldr x0, =0x10FFF00083 + msr S3_6_C15_C8_3, x0 + ldr x0, =0x2001003FF + msr S3_6_C15_C8_1, x0 + + mov x0, #4 + msr S3_6_C15_C8_0, x0 + ldr x0, =0x10E3800082 + msr S3_6_C15_C8_2, x0 + ldr x0, =0x10FFF00083 + msr S3_6_C15_C8_3, x0 + ldr x0, =0x2001003FF + msr S3_6_C15_C8_1, x0 + + mov x0, #5 + msr S3_6_C15_C8_0, x0 + ldr x0, =0x10E3800200 + msr S3_6_C15_C8_2, x0 + ldr x0, =0x10FFF003E0 + msr S3_6_C15_C8_3, x0 + ldr x0, =0x2001003FF + msr S3_6_C15_C8_1, x0 + + isb +1: + ret x17 +endfunc errata_n1_1946160_wa + +func check_errata_1946160 + /* Applies to r3p0 - r4p1. */ + mov x1, #0x30 + mov x2, #0x41 + b cpu_rev_var_range +endfunc check_errata_1946160 + func neoverse_n1_reset_func mov x19, x30 @@ -486,6 +543,11 @@ func neoverse_n1_reset_func bl errata_n1_1868343_wa #endif +#if ERRATA_N1_1946160 + mov x0, x18 + bl errata_n1_1946160_wa +#endif + #if ENABLE_AMU /* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */ mrs x0, actlr_el3 @@ -560,6 +622,7 @@ func neoverse_n1_errata_report report_errata ERRATA_N1_1315703, neoverse_n1, 1315703 report_errata ERRATA_N1_1542419, neoverse_n1, 1542419 report_errata ERRATA_N1_1868343, neoverse_n1, 1868343 + report_errata ERRATA_N1_1946160, neoverse_n1, 1946160 report_errata ERRATA_DSU_936184, neoverse_n1, dsu_936184 ldp x8, x30, [sp], #16 diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk index 93b538c58..64a4b4d47 100644 --- a/lib/cpus/cpu-ops.mk +++ b/lib/cpus/cpu-ops.mk @@ -355,6 +355,11 @@ ERRATA_N1_1542419 ?=0 # to revision <= r4p0 of the Neoverse N1 cpu. ERRATA_N1_1868343 ?=0 +# Flag to apply erratum 1946160 workaround during reset. This erratum applies +# to revisions r3p0, r3p1, r4p0, and r4p1 of the Neoverse N1 cpu. The issue +# exists in revisions r0p0, r1p0, and r2p0 as well but there is no workaround. +ERRATA_N1_1946160 ?=0 + # Flag to apply DSU erratum 798953. This erratum applies to DSUs revision r0p0. # Applying the workaround results in higher DSU power consumption on idle. ERRATA_DSU_798953 ?=0 @@ -644,6 +649,10 @@ $(eval $(call add_define,ERRATA_N1_1542419)) $(eval $(call assert_boolean,ERRATA_N1_1868343)) $(eval $(call add_define,ERRATA_N1_1868343)) +# Process ERRATA_N1_1946160 flag +$(eval $(call assert_boolean,ERRATA_N1_1946160)) +$(eval $(call add_define,ERRATA_N1_1946160)) + # Process ERRATA_DSU_798953 flag $(eval $(call assert_boolean,ERRATA_DSU_798953)) $(eval $(call add_define,ERRATA_DSU_798953)) -- cgit v1.2.3 From d0b367b77a67b14922a0139ea1b6ecd620995cb4 Mon Sep 17 00:00:00 2001 From: Luka Kovacic Date: Thu, 14 Jan 2021 14:25:15 +0100 Subject: docs: marvell: armada: Update MARVELL_PLATFORM list and build instructions The supported MARVELL_PLATFORM list is updated to include the recently added a80x0_puzzle platform (IEI Puzzle-M801). Additionally building instructions are added for the GST ESPRESSObin-Ultra board (1 GB, DDR4 RAM variant), which has been tested successfully and booted TF-A on the board. Signed-off-by: Luka Kovacic Change-Id: Ie5724df27c1ee2e8f6a52664520579e872471e93 --- docs/plat/marvell/armada/build.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/plat/marvell/armada/build.rst b/docs/plat/marvell/armada/build.rst index 2c2bd680c..29fe4d452 100644 --- a/docs/plat/marvell/armada/build.rst +++ b/docs/plat/marvell/armada/build.rst @@ -226,12 +226,23 @@ To build just TF-A without WTMI image (useful for A3720 Turris MOX board), run f > make USE_COHERENT_MEM=0 PLAT=a3700 CM3_SYSTEM_RESET=1 BL33=/path/to/u-boot.bin \ CROSS_COMPILE=aarch64-linux-gnu- mrvl_bootimage +You can build TF-A for the Globalscale ESPRESSObin-Ultra board (DDR4, 1 GB) by running the following command: + +.. code:: shell + + > make DEBUG=1 USE_COHERENT_MEM=0 LOG_LEVEL=20 CLOCKSPRESET=CPU_1200_DDR_750 \ + MARVELL_SECURE_BOOT=0 DDR_TOPOLOGY=5 BOOTDEV=SPINOR PARTNUM=0 PLAT=a3700 \ + MV_DDR_PATH=/path/to/mv-ddr-marvell/ WTP=/path/to/A3700-utils-marvell/ \ + CRYPTOPP_PATH=/path/to/cryptopp/ BL33=/path/to/u-boot.bin \ + all fip mrvl_bootimage mrvl_flash + Supported MARVELL_PLATFORM are: - a3700 (for both A3720 DB and EspressoBin) - a70x0 - a70x0_amc (for AMC board) - a80x0 - a80x0_mcbin (for MacchiatoBin) + - a80x0_puzzle (for IEI Puzzle-M801) - t9130 (OcteonTX2 CN913x) Special Build Flags -- cgit v1.2.3 From 7c802c715f14b203e5dfc7e4ccee498b861eb406 Mon Sep 17 00:00:00 2001 From: Tomas Pilar Date: Wed, 28 Oct 2020 15:34:12 +0000 Subject: Define registers for FEAT_RNG support Add ISAR0 feature register read helper, location of FEAT_RNG bits, feature support helper and the rndr/rndrrs register read helpers. Signed-off-by: Tomas Pilar Change-Id: I2a785a36f62a917548e55892ce92fa8b72fcb99d --- include/arch/aarch64/arch.h | 4 ++++ include/arch/aarch64/arch_features.h | 6 ++++++ include/arch/aarch64/arch_helpers.h | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index 09e598a2d..2cdc7b230 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -193,6 +193,10 @@ #define ID_AA64DFR0_MTPMU_MASK ULL(0xf) #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) + /* ID_AA64ISAR1_EL1 definitions */ #define ID_AA64ISAR1_EL1 S3_0_C0_C6_1 #define ID_AA64ISAR1_GPI_SHIFT U(28) diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h index 6b5d32696..671b3dc60 100644 --- a/include/arch/aarch64/arch_features.h +++ b/include/arch/aarch64/arch_features.h @@ -76,6 +76,12 @@ static inline unsigned long int get_armv8_6_ecv_support(void) ID_AA64MMFR0_EL1_ECV_MASK); } +static inline bool is_armv8_5_rng_present(void) +{ + return ((read_id_aa64isar0_el1() >> ID_AA64ISAR0_RNDR_SHIFT) & + ID_AA64ISAR0_RNDR_MASK); +} + /* * Return MPAM version: * diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h index 5d1bc948c..7fafafc5a 100644 --- a/include/arch/aarch64/arch_helpers.h +++ b/include/arch/aarch64/arch_helpers.h @@ -245,6 +245,7 @@ void disable_mmu_icache_el3(void); DEFINE_SYSREG_RW_FUNCS(par_el1) DEFINE_SYSREG_READ_FUNC(id_pfr1_el1) +DEFINE_SYSREG_READ_FUNC(id_aa64isar0_el1) DEFINE_SYSREG_READ_FUNC(id_aa64isar1_el1) DEFINE_SYSREG_READ_FUNC(id_aa64pfr0_el1) DEFINE_SYSREG_READ_FUNC(id_aa64pfr1_el1) @@ -522,6 +523,10 @@ DEFINE_RENAME_SYSREG_RW_FUNCS(tfsr_el1, TFSR_EL1) DEFINE_RENAME_SYSREG_RW_FUNCS(rgsr_el1, RGSR_EL1) DEFINE_RENAME_SYSREG_RW_FUNCS(gcr_el1, GCR_EL1) +/* Armv8.5 FEAT_RNG Registers */ +DEFINE_SYSREG_READ_FUNC(rndr) +DEFINE_SYSREG_READ_FUNC(rndrrs) + /* DynamIQ Shared Unit power management */ DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpwrdn_el1, CLUSTERPWRDN_EL1) -- cgit v1.2.3 From 12cd65e091c229c1bc12d6ca58417391ec62d37f Mon Sep 17 00:00:00 2001 From: Tomas Pilar Date: Thu, 29 Oct 2020 13:01:16 +0000 Subject: Makefile: Add FEAT_RNG support define Define ENABLE_FEAT_RNG that describes whether the armv8.5 FEAT_RNG is supported in this build. This allows conditional inclusion of code targetting RNDR and RNDRRS registers. Signed-off-by: Tomas Pilar Change-Id: Idd632f8b9bc20ea3d8793f55ead88fa12cb08821 --- Makefile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Makefile b/Makefile index 2d5a5bb2e..a3a79f8eb 100644 --- a/Makefile +++ b/Makefile @@ -242,6 +242,9 @@ endif $(info Arm Architecture Features specified: $(subst +, ,$(arch-features))) endif # arch-features +# Determine if FEAT_RNG is supported +ENABLE_FEAT_RNG = $(if $(findstring rng,${arch-features}),1,0) + ifneq ($(findstring armclang,$(notdir $(CC))),) TF_CFLAGS_aarch32 = -target arm-arm-none-eabi $(march32-directive) TF_CFLAGS_aarch64 = -target aarch64-arm-none-eabi $(march64-directive) @@ -940,6 +943,7 @@ $(eval $(call assert_booleans,\ RAS_TRAP_LOWER_EL_ERR_ACCESS \ COT_DESC_IN_DTB \ USE_SP804_TIMER \ + ENABLE_FEAT_RNG \ ))) $(eval $(call assert_numerics,\ @@ -1030,6 +1034,7 @@ $(eval $(call add_defines,\ RAS_TRAP_LOWER_EL_ERR_ACCESS \ COT_DESC_IN_DTB \ USE_SP804_TIMER \ + ENABLE_FEAT_RNG \ ))) ifeq (${SANITIZE_UB},trap) -- cgit v1.2.3 From 74867756ef5c8f2a33af2fc59915cbd8905a23e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Mon, 18 Jan 2021 12:39:25 +0100 Subject: marvell: uart: a3720: Implement console_a3700_core_getc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implementation is simple, just check if there is a pending character in RX FIFO via RXRDY bit of Status Register and if yes, read it from UART_RX_REG register. Signed-off-by: Pali Rohár Change-Id: I226b6e336f44f5d0ca8dcb68e49a68e8f2f49708 --- drivers/marvell/uart/a3700_console.S | 15 ++++++++++++--- include/drivers/marvell/uart/a3700_console.h | 1 + 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/marvell/uart/a3700_console.S b/drivers/marvell/uart/a3700_console.S index dc374eed1..9a557aac3 100644 --- a/drivers/marvell/uart/a3700_console.S +++ b/drivers/marvell/uart/a3700_console.S @@ -196,14 +196,23 @@ endfunc console_a3700_putc * int console_a3700_core_getc(void) * Function to get a character from the console. * It returns the character grabbed on success - * or -1 on error. + * or -1 if no character is available. * In : w0 - console base address - * Out : return -1 on error else return character. + * Out : w0 - character if available, else -1 * Clobber list : x0, x1 * --------------------------------------------- */ func console_a3700_core_getc - mov w0, #-1 + /* Check if there is a pending character */ + ldr w1, [x0, #UART_STATUS_REG] + and w1, w1, #UARTLSR_RXRDY + cmp w1, #UARTLSR_RXRDY + b.ne getc_no_char + ldr w0, [x0, #UART_RX_REG] + and w0, w0, #0xff + ret +getc_no_char: + mov w0, #ERROR_NO_PENDING_CHAR ret endfunc console_a3700_core_getc diff --git a/include/drivers/marvell/uart/a3700_console.h b/include/drivers/marvell/uart/a3700_console.h index 5e3ab0515..e77a16560 100644 --- a/include/drivers/marvell/uart/a3700_console.h +++ b/include/drivers/marvell/uart/a3700_console.h @@ -48,6 +48,7 @@ /* Line Status Register bits */ #define UARTLSR_TXFIFOFULL (1 << 11) /* Tx Fifo Full */ +#define UARTLSR_RXRDY (1 << 4) /* Rx Ready */ /* UART Control Register bits */ #define UART_CTRL_RXFIFO_RESET (1 << 14) -- cgit v1.2.3 From b8e637f49ea90d06b21f160eba3180717787730f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Mon, 18 Jan 2021 12:52:55 +0100 Subject: marvell: uart: a3720: Fix macro name for 6th bit of Status Register MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch does not change code, it only updates comments and macro name for 6th bit of Status Register. So TF-A binary stay same. 6th bit of the Status Register is named TX EMPTY and is set to 1 when both Transmitter Holding Register (THR) or Transmitter Shift Register (TSR) are empty. It is when all characters were already transmitted. There is also TX FIFO EMPTY bit in the Status Register which is set to 1 only when THR is empty. In both console_a3700_core_init() and console_a3700_core_flush() functions we should wait until both THR and TSR are empty therefore we should check 6th bit of the Status Register. So current code is correct, just had misleading macro names and comments. This change fixes this "documentation" issue, fixes macro name for 6th bit of the Status Register and also updates comments. Signed-off-by: Pali Rohár Change-Id: I19e4e7f53a90bcfb318e6dd1b1249b6cbf81c4d3 --- drivers/marvell/uart/a3700_console.S | 12 ++++++------ include/drivers/marvell/uart/a3700_console.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/marvell/uart/a3700_console.S b/drivers/marvell/uart/a3700_console.S index 9a557aac3..58dad7aa5 100644 --- a/drivers/marvell/uart/a3700_console.S +++ b/drivers/marvell/uart/a3700_console.S @@ -60,14 +60,14 @@ func console_a3700_core_init str w3, [x0, #UART_POSSR_REG] /* - * Wait for the TX FIFO to be empty. If wait for 20ms, the TX FIFO is + * Wait for the TX (THR and TSR) to be empty. If wait for 20ms, the TX FIFO is * still not empty, TX FIFO will reset by all means. */ mov w1, #20 /* max time out 20ms */ 2: - /* Check whether TX FIFO is empty */ + /* Check whether TX (THR and TSR) is empty */ ldr w3, [x0, #UART_STATUS_REG] - and w3, w3, #UARTLSR_TXFIFOEMPTY + and w3, w3, #UARTLSR_TXEMPTY cmp w3, #0 b.ne 4f @@ -241,10 +241,10 @@ endfunc console_a3700_getc * --------------------------------------------- */ func console_a3700_core_flush - /* Wait for the TX FIFO to be empty */ + /* Wait for the TX (THR and TSR) to be empty */ 1: ldr w1, [x0, #UART_STATUS_REG] - and w1, w1, #UARTLSR_TXFIFOEMPTY - cmp w1, #UARTLSR_TXFIFOEMPTY + and w1, w1, #UARTLSR_TXEMPTY + cmp w1, #UARTLSR_TXEMPTY b.ne 1b ret endfunc console_a3700_core_flush diff --git a/include/drivers/marvell/uart/a3700_console.h b/include/drivers/marvell/uart/a3700_console.h index e77a16560..12d2cdc52 100644 --- a/include/drivers/marvell/uart/a3700_console.h +++ b/include/drivers/marvell/uart/a3700_console.h @@ -48,12 +48,12 @@ /* Line Status Register bits */ #define UARTLSR_TXFIFOFULL (1 << 11) /* Tx Fifo Full */ +#define UARTLSR_TXEMPTY (1 << 6) /* Tx Empty */ #define UARTLSR_RXRDY (1 << 4) /* Rx Ready */ /* UART Control Register bits */ #define UART_CTRL_RXFIFO_RESET (1 << 14) #define UART_CTRL_TXFIFO_RESET (1 << 15) -#define UARTLSR_TXFIFOEMPTY (1 << 6) #ifndef __ASSEMBLER__ -- cgit v1.2.3 From 2fbb60642f13bcd0142f13e20fc2a4a4815c9607 Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Wed, 29 Jan 2020 16:04:18 +0100 Subject: fdts: stm32mp1: add support for Linux Automation MC-1 board The Linux Automation MC-1 is a SBC built around the Octavo Systems OSD32MP15x SiP. The SiP features up to 1 GB DDR3 RAM, EEPROM and PMIC. The board has eMMC and a SD slot for storage. The SDRAM calibration values are taken as is from the DKx boards, which seem to be suitable for operation at German room temperature. This is deemed ok for now, but for use in the field, the SiP will likely need to have its timings determined in a climate chamber. Change-Id: I5f43a61930151ae9d1df2ea7d0f6f9697c813ce0 Signed-off-by: Ahmad Fatoum --- fdts/stm32mp157c-lxa-mc1.dts | 107 ++++++++++++++++ fdts/stm32mp15xx-osd32.dtsi | 281 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 388 insertions(+) create mode 100644 fdts/stm32mp157c-lxa-mc1.dts create mode 100644 fdts/stm32mp15xx-osd32.dtsi diff --git a/fdts/stm32mp157c-lxa-mc1.dts b/fdts/stm32mp157c-lxa-mc1.dts new file mode 100644 index 000000000..7b8e48127 --- /dev/null +++ b/fdts/stm32mp157c-lxa-mc1.dts @@ -0,0 +1,107 @@ +/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause) */ +/* + * Copyright (C) 2020 STMicroelectronics - All Rights Reserved + * Copyright (C) 2020 Ahmad Fatoum, Pengutronix + */ + +/dts-v1/; + +#include "stm32mp157.dtsi" +#include "stm32mp15xc.dtsi" +#include "stm32mp15-ddr3-1x4Gb-1066-binG.dtsi" +#include "stm32mp15xx-osd32.dtsi" +#include "stm32mp15xxac-pinctrl.dtsi" + +/ { + model = "Linux Automation MC-1 board"; + compatible = "lxa,stm32mp157c-mc1", "oct,stm32mp15xx-osd32", "st,stm32mp157"; + + aliases { + mmc0 = &sdmmc1; + mmc1 = &sdmmc2; + serial0 = &uart4; + }; + + chosen { + stdout-path = &uart4; + }; + + led-act { + compatible = "gpio-leds"; + + led-green { + label = "mc1:green:act"; + gpios = <&gpioa 13 1>; + linux,default-trigger = "heartbeat"; + }; + }; + + reg_3v3: regulator_3v3 { + compatible = "regulator-fixed"; + regulator-name = "3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + vin-supply = <&v3v3>; + }; +}; + +&sdmmc1 { + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc1_b4_pins_a>; + bus-width = <4>; + cd-gpios = <&gpioh 3 1>; + disable-wp; + no-1-8-v; + st,neg-edge; + vmmc-supply = <®_3v3>; + status = "okay"; +}; + +&sdmmc1_b4_pins_a { + /* + * board lacks external pull-ups on SDMMC lines. Class 10 SD refuses to + * work, thus enable internal pull-ups. + */ + pins1 { + /delete-property/ bias-disable; + bias-pull-up; + }; + pins2 { + /delete-property/ bias-disable; + bias-pull-up; + }; +}; + +&sdmmc2 { + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc2_b4_pins_a &mc1_sdmmc2_d47_pins_b>; + bus-width = <8>; + no-1-8-v; + no-sd; + no-sdio; + non-removable; + st,neg-edge; + vmmc-supply = <®_3v3>; + status = "okay"; +}; + +&uart4 { + pinctrl-names = "default"; + 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-osd32.dtsi b/fdts/stm32mp15xx-osd32.dtsi new file mode 100644 index 000000000..76a25613a --- /dev/null +++ b/fdts/stm32mp15xx-osd32.dtsi @@ -0,0 +1,281 @@ +/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause) */ +/* + * Copyright (C) 2020 STMicroelectronics - All Rights Reserved + * Copyright (C) 2020 Ahmad Fatoum, Pengutronix + */ + +#include "stm32mp15-pinctrl.dtsi" + +&i2c4 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c4_pins_a>; + clock-frequency = <400000>; + i2c-scl-rising-time-ns = <185>; + i2c-scl-falling-time-ns = <20>; + status = "okay"; + + pmic: stpmic@33 { + compatible = "st,stpmic1"; + reg = <0x33>; + interrupts-extended = <&gpioa 0 IRQ_TYPE_EDGE_FALLING>; + interrupt-controller; + #interrupt-cells = <2>; + + regulators { + compatible = "st,stpmic1-regulators"; + + ldo1-supply = <&v3v3>; + ldo6-supply = <&v3v3>; + pwr_sw1-supply = <&bst_out>; + + vddcore: buck1 { + regulator-name = "vddcore"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1350000>; + regulator-always-on; + regulator-initial-mode = <0>; + regulator-over-current-protection; + }; + + vdd_ddr: buck2 { + regulator-name = "vdd_ddr"; + regulator-min-microvolt = <1350000>; + regulator-max-microvolt = <1350000>; + regulator-always-on; + regulator-initial-mode = <0>; + regulator-over-current-protection; + }; + + vdd: buck3 { + regulator-name = "vdd"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + st,mask-reset; + regulator-initial-mode = <0>; + regulator-over-current-protection; + }; + + v3v3: buck4 { + regulator-name = "v3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-over-current-protection; + regulator-initial-mode = <0>; + }; + + v1v8_audio: ldo1 { + regulator-name = "v1v8_audio"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + v3v3_hdmi: ldo2 { + regulator-name = "v3v3_hdmi"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vtt_ddr: ldo3 { + regulator-name = "vtt_ddr"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <750000>; + regulator-always-on; + regulator-over-current-protection; + }; + + vdd_usb: ldo4 { + regulator-name = "vdd_usb"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + vdda: ldo5 { + regulator-name = "vdda"; + regulator-min-microvolt = <2900000>; + regulator-max-microvolt = <2900000>; + regulator-boot-on; + }; + + v1v2_hdmi: ldo6 { + regulator-name = "v1v2_hdmi"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + }; + + vref_ddr: vref_ddr { + regulator-name = "vref_ddr"; + regulator-always-on; + regulator-over-current-protection; + }; + + bst_out: boost { + regulator-name = "bst_out"; + }; + + vbus_otg: pwr_sw1 { + regulator-name = "vbus_otg"; + regulator-active-discharge; + }; + + vbus_sw: pwr_sw2 { + regulator-name = "vbus_sw"; + regulator-active-discharge; + }; + }; + + pmic_watchdog: watchdog { + compatible = "st,stpmic1-wdt"; + status = "disabled"; + }; + }; +}; + +&rng1 { + status = "okay"; +}; + +/* ATF Specific */ +#include + +/ { + aliases { + gpio0 = &gpioa; + gpio1 = &gpiob; + gpio2 = &gpioc; + gpio3 = &gpiod; + gpio4 = &gpioe; + gpio5 = &gpiof; + gpio6 = &gpiog; + gpio7 = &gpioh; + gpio8 = &gpioi; + gpio25 = &gpioz; + i2c3 = &i2c4; + }; +}; + +&bsec { + board_id: board_id@ec { + reg = <0xec 0x4>; + st,non-secure-otp; + }; +}; + +&clk_hse { + st,digbypass; +}; + +&cpu0{ + cpu-supply = <&vddcore>; +}; + +&cpu1{ + cpu-supply = <&vddcore>; +}; + +&hash1 { + status = "okay"; +}; + +/* CLOCK init */ +&rcc { + secure-status = "disabled"; + st,clksrc = < + CLK_MPU_PLL1P + CLK_AXI_PLL2P + CLK_MCU_PLL3P + CLK_PLL12_HSE + CLK_PLL3_HSE + CLK_PLL4_HSE + CLK_RTC_LSE + CLK_MCO1_DISABLED + CLK_MCO2_DISABLED + >; + + st,clkdiv = < + 1 /*MPU*/ + 0 /*AXI*/ + 0 /*MCU*/ + 1 /*APB1*/ + 1 /*APB2*/ + 1 /*APB3*/ + 1 /*APB4*/ + 2 /*APB5*/ + 23 /*RTC*/ + 0 /*MCO1*/ + 0 /*MCO2*/ + >; + + st,pkcs = < + CLK_CKPER_HSE + CLK_FMC_ACLK + CLK_QSPI_ACLK + CLK_ETH_PLL4P + CLK_SDMMC12_PLL4P + CLK_DSI_DSIPLL + CLK_STGEN_HSE + CLK_USBPHY_HSE + CLK_SPI2S1_PLL3Q + CLK_SPI2S23_PLL3Q + CLK_SPI45_HSI + CLK_SPI6_HSI + CLK_I2C46_HSI + CLK_SDMMC3_PLL4P + CLK_USBO_USBPHY + CLK_ADC_CKPER + CLK_CEC_LSE + CLK_I2C12_HSI + CLK_I2C35_HSI + CLK_UART1_HSI + CLK_UART24_HSI + CLK_UART35_HSI + CLK_UART6_HSI + CLK_UART78_HSI + CLK_SPDIF_PLL4P + CLK_FDCAN_PLL4R + CLK_SAI1_PLL3Q + CLK_SAI2_PLL3Q + CLK_SAI3_PLL3Q + CLK_SAI4_PLL3Q + CLK_RNG1_LSI + CLK_RNG2_LSI + CLK_LPTIM1_PCLK1 + CLK_LPTIM23_PCLK3 + CLK_LPTIM45_LSE + >; + + /* VCO = 1300.0 MHz => P = 650 (CPU) */ + pll1: st,pll@0 { + 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 { + 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 { + 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 { + compatible = "st,stm32mp1-pll"; + reg = <3>; + cfg = <3 98 5 7 7 PQR(1,1,1)>; + }; +}; -- cgit v1.2.3 From 83683ddd3d704e2d8c1fe9bef9eabb4639c0846a Mon Sep 17 00:00:00 2001 From: Tomas Pilar Date: Wed, 28 Oct 2020 15:35:53 +0000 Subject: plat/qemu: Use RNDR in stack protector When getting a stack protector canary value, check if cpu supports FEAT_RNG and use that. Fallback to old method of using a (hardcoded value ^ timer). Signed-off-by: Tomas Pilar Change-Id: I8181acf8e31661d4cc82bc3a4078f8751909e725 --- plat/qemu/common/qemu_stack_protector.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/plat/qemu/common/qemu_stack_protector.c b/plat/qemu/common/qemu_stack_protector.c index c226158ad..15ce3d6d2 100644 --- a/plat/qemu/common/qemu_stack_protector.c +++ b/plat/qemu/common/qemu_stack_protector.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,17 +7,25 @@ #include #include +#include #include #define RANDOM_CANARY_VALUE ((u_register_t) 3288484550995823360ULL) u_register_t plat_get_stack_protector_canary(void) { +#if ENABLE_FEAT_RNG + /* Use the RNDR instruction if the CPU supports it */ + if (is_armv8_5_rng_present()) { + return read_rndr(); + } +#endif + /* - * Ideally, a random number should be returned instead of the + * Ideally, a random number should be returned above. If a random + * number generator is not supported, return instead a * combination of a timer's value and a compile-time constant. - * As the virt platform does not have any random number generator, - * this is better than nothing but not necessarily really secure. + * This is better than nothing but not necessarily really secure. */ return RANDOM_CANARY_VALUE ^ read_cntpct_el0(); } -- cgit v1.2.3 From 3063177e39b34342e0bb0272efb20c851f70b667 Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Wed, 16 Dec 2020 14:13:07 +0000 Subject: qemu/aarch64/plat_helpers.S : calculate the position shift Rather than re-create this file in multiple qemu variants instead caclulate the shift needed to convert MPIDR to position. Add a new PLATFORM_CPU_PER_CLUSTER_SHIFT define in platform_def.h for both qemu and qemu_sbsa to enable this calculation. Signed-off-by: Graeme Gregory Change-Id: I0e3a86354aa716d95150a3a34b15287cd70c8fd2 --- plat/qemu/common/aarch64/plat_helpers.S | 3 ++- plat/qemu/qemu/include/platform_def.h | 8 ++++++++ plat/qemu/qemu_sbsa/include/platform_def.h | 7 +++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/plat/qemu/common/aarch64/plat_helpers.S b/plat/qemu/common/aarch64/plat_helpers.S index b54617385..08b281735 100644 --- a/plat/qemu/common/aarch64/plat_helpers.S +++ b/plat/qemu/common/aarch64/plat_helpers.S @@ -32,7 +32,8 @@ endfunc plat_my_core_pos func plat_qemu_calc_core_pos and x1, x0, #MPIDR_CPU_MASK and x0, x0, #MPIDR_CLUSTER_MASK - add x0, x1, x0, LSR #6 + add x0, x1, x0, LSR #(MPIDR_AFFINITY_BITS -\ + PLATFORM_CPU_PER_CLUSTER_SHIFT) ret endfunc plat_qemu_calc_core_pos diff --git a/plat/qemu/qemu/include/platform_def.h b/plat/qemu/qemu/include/platform_def.h index ed4b748af..e6bb1e6a9 100644 --- a/plat/qemu/qemu/include/platform_def.h +++ b/plat/qemu/qemu/include/platform_def.h @@ -24,6 +24,14 @@ #define PLATFORM_CLUSTER1_CORE_COUNT U(0) #else #define PLATFORM_MAX_CPUS_PER_CLUSTER U(4) +/* + * Define the number of cores per cluster used in calculating core position. + * The cluster number is shifted by this value and added to the core ID, + * so its value represents log2(cores/cluster). + * Default is 2**(2) = 4 cores per cluster. + */ +#define PLATFORM_CPU_PER_CLUSTER_SHIFT U(2) + #define PLATFORM_CLUSTER_COUNT U(2) #define PLATFORM_CLUSTER0_CORE_COUNT PLATFORM_MAX_CPUS_PER_CLUSTER #define PLATFORM_CLUSTER1_CORE_COUNT PLATFORM_MAX_CPUS_PER_CLUSTER diff --git a/plat/qemu/qemu_sbsa/include/platform_def.h b/plat/qemu/qemu_sbsa/include/platform_def.h index db394c038..84710240d 100644 --- a/plat/qemu/qemu_sbsa/include/platform_def.h +++ b/plat/qemu/qemu_sbsa/include/platform_def.h @@ -17,6 +17,13 @@ #define PLATFORM_STACK_SIZE 0x1000 #define PLATFORM_MAX_CPUS_PER_CLUSTER U(4) +/* + * Define the number of cores per cluster used in calculating core position. + * The cluster number is shifted by this value and added to the core ID, + * so its value represents log2(cores/cluster). + * Default is 2**(2) = 4 cores per cluster. + */ +#define PLATFORM_CPU_PER_CLUSTER_SHIFT U(2) #define PLATFORM_CLUSTER_COUNT U(2) #define PLATFORM_CLUSTER0_CORE_COUNT PLATFORM_MAX_CPUS_PER_CLUSTER #define PLATFORM_CLUSTER1_CORE_COUNT PLATFORM_MAX_CPUS_PER_CLUSTER -- cgit v1.2.3 From 916a7e11e2e78ff31114018b139874635fe8fc24 Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Wed, 16 Dec 2020 12:11:06 +0000 Subject: qemu/common : change DEVICE2 definition for MMU DEVICE2 is not currently used on qemu platform but is needed for a future patch for qemu_sbsa platform. Change its definition to RW and add it to all levels of arm-tf similar to DEVICE1 definition. Signed-off-by: Graeme Gregory Change-Id: I03495471bfd423b61ad44ec4953fb25f76aa54bf --- plat/qemu/common/qemu_common.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/plat/qemu/common/qemu_common.c b/plat/qemu/common/qemu_common.c index 7d2730d69..47ec79114 100644 --- a/plat/qemu/common/qemu_common.c +++ b/plat/qemu/common/qemu_common.c @@ -26,7 +26,7 @@ #ifdef DEVICE2_BASE #define MAP_DEVICE2 MAP_REGION_FLAT(DEVICE2_BASE, \ DEVICE2_SIZE, \ - MT_DEVICE | MT_RO | MT_SECURE) + MT_DEVICE | MT_RW | MT_SECURE) #endif #define MAP_SHARED_RAM MAP_REGION_FLAT(SHARED_RAM_BASE, \ @@ -93,6 +93,9 @@ static const mmap_region_t plat_qemu_mmap[] = { #ifdef MAP_DEVICE1 MAP_DEVICE1, #endif +#ifdef MAP_DEVICE2 + MAP_DEVICE2, +#endif #if SPM_MM MAP_NS_DRAM0, QEMU_SPM_BUF_EL3_MMAP, @@ -108,6 +111,9 @@ static const mmap_region_t plat_qemu_mmap[] = { MAP_DEVICE0, #ifdef MAP_DEVICE1 MAP_DEVICE1, +#endif +#ifdef MAP_DEVICE2 + MAP_DEVICE2, #endif {0} }; -- cgit v1.2.3 From 5565ede44a80805789d375aaae2773e02119cf9b Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Fri, 28 Aug 2020 16:37:02 +0100 Subject: qemu/qemu_sbsa: topology is different from qemu so add handling sbsa-ref in QEMU creates clusers of 8 cores, it may create up to 512 cores in upto 64 clusters. Implement a qemu_sbsa specific topology file and increase the BL31_SIZE to accommodate the bigger table sizes. Change platform_def.h for new topology. Correct PLATFORM_CPU_PER_CLUSTER_SHIFT so plat_helpers.S calculates correct result. Signed-off-by: Graeme Gregory Change-Id: Idc5d70394c0956b759ad2c86f9fda8f293f2cfa7 --- plat/qemu/qemu_sbsa/include/platform_def.h | 17 ++++---- plat/qemu/qemu_sbsa/platform.mk | 2 +- plat/qemu/qemu_sbsa/sbsa_private.h | 14 +++++++ plat/qemu/qemu_sbsa/sbsa_topology.c | 63 ++++++++++++++++++++++++++++++ 4 files changed, 85 insertions(+), 11 deletions(-) create mode 100644 plat/qemu/qemu_sbsa/sbsa_private.h create mode 100644 plat/qemu/qemu_sbsa/sbsa_topology.c diff --git a/plat/qemu/qemu_sbsa/include/platform_def.h b/plat/qemu/qemu_sbsa/include/platform_def.h index 84710240d..94bf0d101 100644 --- a/plat/qemu/qemu_sbsa/include/platform_def.h +++ b/plat/qemu/qemu_sbsa/include/platform_def.h @@ -16,20 +16,17 @@ #define PLATFORM_STACK_SIZE 0x1000 -#define PLATFORM_MAX_CPUS_PER_CLUSTER U(4) +#define PLATFORM_MAX_CPUS_PER_CLUSTER U(8) /* * Define the number of cores per cluster used in calculating core position. * The cluster number is shifted by this value and added to the core ID, * so its value represents log2(cores/cluster). - * Default is 2**(2) = 4 cores per cluster. + * Default is 2**(3) = 8 cores per cluster. */ -#define PLATFORM_CPU_PER_CLUSTER_SHIFT U(2) -#define PLATFORM_CLUSTER_COUNT U(2) -#define PLATFORM_CLUSTER0_CORE_COUNT PLATFORM_MAX_CPUS_PER_CLUSTER -#define PLATFORM_CLUSTER1_CORE_COUNT PLATFORM_MAX_CPUS_PER_CLUSTER -#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER0_CORE_COUNT + \ - PLATFORM_CLUSTER1_CORE_COUNT) - +#define PLATFORM_CPU_PER_CLUSTER_SHIFT U(3) +#define PLATFORM_CLUSTER_COUNT U(64) +#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER_COUNT * \ + PLATFORM_MAX_CPUS_PER_CLUSTER) #define QEMU_PRIMARY_CPU U(0) #define PLAT_NUM_PWR_DOMAINS (PLATFORM_CLUSTER_COUNT + \ @@ -137,7 +134,7 @@ * Put BL3-1 at the top of the Trusted SRAM. BL31_BASE is calculated using the * current BL3-1 debug size plus a little space for growth. */ -#define BL31_SIZE 0x50000 +#define BL31_SIZE 0x300000 #define BL31_BASE (BL31_LIMIT - BL31_SIZE) #define BL31_LIMIT (BL1_RW_BASE) #define BL31_PROGBITS_LIMIT BL1_RW_BASE diff --git a/plat/qemu/qemu_sbsa/platform.mk b/plat/qemu/qemu_sbsa/platform.mk index 98d1347d1..ece700c33 100644 --- a/plat/qemu/qemu_sbsa/platform.mk +++ b/plat/qemu/qemu_sbsa/platform.mk @@ -80,7 +80,7 @@ BL31_SOURCES += lib/cpus/aarch64/cortex_a57.S \ lib/semihosting/${ARCH}/semihosting_call.S \ plat/common/plat_psci_common.c \ ${PLAT_QEMU_COMMON_PATH}/qemu_pm.c \ - ${PLAT_QEMU_COMMON_PATH}/topology.c \ + ${PLAT_QEMU_PATH}/sbsa_topology.c \ ${PLAT_QEMU_COMMON_PATH}/aarch64/plat_helpers.S \ ${PLAT_QEMU_COMMON_PATH}/qemu_bl31_setup.c \ common/fdt_fixup.c \ diff --git a/plat/qemu/qemu_sbsa/sbsa_private.h b/plat/qemu/qemu_sbsa/sbsa_private.h new file mode 100644 index 000000000..29ee1d071 --- /dev/null +++ b/plat/qemu/qemu_sbsa/sbsa_private.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2020, Nuvia Inc + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SBSA_PRIVATE_H +#define SBSA_PRIVATE_H + +#include + +unsigned int plat_qemu_calc_core_pos(u_register_t mpidr); + +#endif /* SBSA_PRIVATE_H */ diff --git a/plat/qemu/qemu_sbsa/sbsa_topology.c b/plat/qemu/qemu_sbsa/sbsa_topology.c new file mode 100644 index 000000000..bd8d16b9a --- /dev/null +++ b/plat/qemu/qemu_sbsa/sbsa_topology.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2020, Nuvia Inc + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include "sbsa_private.h" + +/* The power domain tree descriptor */ +static unsigned char power_domain_tree_desc[PLATFORM_CLUSTER_COUNT + 1]; + +/******************************************************************************* + * This function returns the sbsa-ref default topology tree information. + ******************************************************************************/ +const unsigned char *plat_get_power_domain_tree_desc(void) +{ + unsigned int i; + + power_domain_tree_desc[0] = PLATFORM_CLUSTER_COUNT; + + for (i = 0U; i < PLATFORM_CLUSTER_COUNT; i++) { + power_domain_tree_desc[i + 1] = PLATFORM_MAX_CPUS_PER_CLUSTER; + } + + return power_domain_tree_desc; +} + +/******************************************************************************* + * This function implements a part of the critical interface between the psci + * generic layer and the platform that allows the former to query the platform + * to convert an MPIDR to a unique linear index. An error code (-1) is returned + * in case the MPIDR is invalid. + ******************************************************************************/ +int plat_core_pos_by_mpidr(u_register_t mpidr) +{ + unsigned int cluster_id, cpu_id; + + mpidr &= MPIDR_AFFINITY_MASK; + if ((mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) != 0U) { + ERROR("Invalid MPIDR\n"); + return -1; + } + + cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK; + cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK; + + if (cluster_id >= PLATFORM_CLUSTER_COUNT) { + ERROR("cluster_id >= PLATFORM_CLUSTER_COUNT define\n"); + return -1; + } + + if (cpu_id >= PLATFORM_MAX_CPUS_PER_CLUSTER) { + ERROR("cpu_id >= PLATFORM_MAX_CPUS_PER_CLUSTER define\n"); + return -1; + } + + return plat_qemu_calc_core_pos(mpidr); +} -- cgit v1.2.3 From 2fb5ed4737a9652d5a74ac20331221dcd4523252 Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Fri, 28 Aug 2020 18:03:35 +0100 Subject: qemu/qemu_sbsa: add support for sbsa-ref Embedded Controller This allows PSCI in TF-A to signal platform power states to QEMU via a controller in secure space. This required a sbsa-ref specific version of PSCI functions for the platform. Also adjusted the MMU range to also include the new EC. Add a new MMU region for the embedded controller and increase the size of xlat tables by one for the new region. Signed-off-by: Graeme Gregory Change-Id: Iece8a88947f11e82ab8988e460a8a66ad175a5ee --- plat/qemu/qemu_sbsa/include/platform_def.h | 9 +- plat/qemu/qemu_sbsa/platform.mk | 2 +- plat/qemu/qemu_sbsa/sbsa_pm.c | 237 +++++++++++++++++++++++++++++ plat/qemu/qemu_sbsa/sbsa_private.h | 3 + 4 files changed, 247 insertions(+), 4 deletions(-) create mode 100644 plat/qemu/qemu_sbsa/sbsa_pm.c diff --git a/plat/qemu/qemu_sbsa/include/platform_def.h b/plat/qemu/qemu_sbsa/include/platform_def.h index 94bf0d101..b69c2ebef 100644 --- a/plat/qemu/qemu_sbsa/include/platform_def.h +++ b/plat/qemu/qemu_sbsa/include/platform_def.h @@ -161,10 +161,10 @@ #define PLAT_VIRT_ADDR_SPACE_SIZE (1ull << 42) #if SPM_MM #define MAX_MMAP_REGIONS 12 -#define MAX_XLAT_TABLES 11 +#define MAX_XLAT_TABLES 12 #else #define MAX_MMAP_REGIONS 11 -#define MAX_XLAT_TABLES 10 +#define MAX_XLAT_TABLES 11 #endif #define MAX_IO_DEVICES 3 #define MAX_IO_HANDLES 4 @@ -207,7 +207,10 @@ #define DEVICE0_SIZE 0x04080000 /* This is map from NORMAL_UART up to SECURE_UART_MM */ #define DEVICE1_BASE 0x60000000 -#define DEVICE1_SIZE 0x00041000 +#define DEVICE1_SIZE 0x10041000 +/* This is a map for SECURE_EC */ +#define DEVICE2_BASE 0x50000000 +#define DEVICE2_SIZE 0x00001000 /* * GIC related constants diff --git a/plat/qemu/qemu_sbsa/platform.mk b/plat/qemu/qemu_sbsa/platform.mk index ece700c33..d45f3f156 100644 --- a/plat/qemu/qemu_sbsa/platform.mk +++ b/plat/qemu/qemu_sbsa/platform.mk @@ -79,7 +79,7 @@ BL31_SOURCES += lib/cpus/aarch64/cortex_a57.S \ lib/semihosting/semihosting.c \ lib/semihosting/${ARCH}/semihosting_call.S \ plat/common/plat_psci_common.c \ - ${PLAT_QEMU_COMMON_PATH}/qemu_pm.c \ + ${PLAT_QEMU_PATH}/sbsa_pm.c \ ${PLAT_QEMU_PATH}/sbsa_topology.c \ ${PLAT_QEMU_COMMON_PATH}/aarch64/plat_helpers.S \ ${PLAT_QEMU_COMMON_PATH}/qemu_bl31_setup.c \ diff --git a/plat/qemu/qemu_sbsa/sbsa_pm.c b/plat/qemu/qemu_sbsa/sbsa_pm.c new file mode 100644 index 000000000..8d1e1d48c --- /dev/null +++ b/plat/qemu/qemu_sbsa/sbsa_pm.c @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2020, Nuvia Inc + * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + + +#include +#include +#include +#include +#include + +#include +#include "sbsa_private.h" + +#define ADP_STOPPED_APPLICATION_EXIT 0x20026 + +/* + * Define offset and commands for the fake EC device + */ +#define SBSA_SECURE_EC_OFFSET 0x50000000 + +#define SBSA_SECURE_EC_CMD_SHUTDOWN 0x01 +#define SBSA_SECURE_EC_CMD_REBOOT 0x02 + +/* + * The secure entry point to be used on warm reset. + */ +static unsigned long secure_entrypoint; + +/* Make composite power state parameter till power level 0 */ +#if PSCI_EXTENDED_STATE_ID + +#define qemu_make_pwrstate_lvl0(lvl0_state, pwr_lvl, type) \ + (((lvl0_state) << PSTATE_ID_SHIFT) | \ + ((type) << PSTATE_TYPE_SHIFT)) +#else +#define qemu_make_pwrstate_lvl0(lvl0_state, pwr_lvl, type) \ + (((lvl0_state) << PSTATE_ID_SHIFT) | \ + ((pwr_lvl) << PSTATE_PWR_LVL_SHIFT) | \ + ((type) << PSTATE_TYPE_SHIFT)) +#endif /* PSCI_EXTENDED_STATE_ID */ + + +#define qemu_make_pwrstate_lvl1(lvl1_state, lvl0_state, pwr_lvl, type) \ + (((lvl1_state) << PLAT_LOCAL_PSTATE_WIDTH) | \ + qemu_make_pwrstate_lvl0(lvl0_state, pwr_lvl, type)) + + + +/* + * The table storing the valid idle power states. Ensure that the + * array entries are populated in ascending order of state-id to + * enable us to use binary search during power state validation. + * The table must be terminated by a NULL entry. + */ +static const unsigned int qemu_pm_idle_states[] = { + /* State-id - 0x01 */ + qemu_make_pwrstate_lvl1(PLAT_LOCAL_STATE_RUN, PLAT_LOCAL_STATE_RET, + MPIDR_AFFLVL0, PSTATE_TYPE_STANDBY), + /* State-id - 0x02 */ + qemu_make_pwrstate_lvl1(PLAT_LOCAL_STATE_RUN, PLAT_LOCAL_STATE_OFF, + MPIDR_AFFLVL0, PSTATE_TYPE_POWERDOWN), + /* State-id - 0x22 */ + qemu_make_pwrstate_lvl1(PLAT_LOCAL_STATE_OFF, PLAT_LOCAL_STATE_OFF, + MPIDR_AFFLVL1, PSTATE_TYPE_POWERDOWN), + 0 +}; + +/******************************************************************************* + * Platform handler called to check the validity of the power state + * parameter. The power state parameter has to be a composite power state. + ******************************************************************************/ +static int qemu_validate_power_state(unsigned int power_state, + psci_power_state_t *req_state) +{ + unsigned int state_id; + unsigned int i; + + assert(req_state != NULL); + + /* + * Currently we are using a linear search for finding the matching + * entry in the idle power state array. This can be made a binary + * search if the number of entries justifies the additional complexity. + */ + for (i = 0U; qemu_pm_idle_states[i] != 0U; i++) { + if (power_state == qemu_pm_idle_states[i]) { + break; + } + } + + /* Return error if entry not found in the idle state array */ + if (qemu_pm_idle_states[i] == 0U) { + return PSCI_E_INVALID_PARAMS; + } + + i = 0U; + state_id = psci_get_pstate_id(power_state); + + /* Parse the State ID and populate the state info parameter */ + while (state_id != 0U) { + req_state->pwr_domain_state[i++] = state_id & + PLAT_LOCAL_PSTATE_MASK; + state_id >>= PLAT_LOCAL_PSTATE_WIDTH; + } + + return PSCI_E_SUCCESS; +} + +/******************************************************************************* + * Platform handler called when a CPU is about to enter standby. + ******************************************************************************/ +static void qemu_cpu_standby(plat_local_state_t cpu_state) +{ + + assert(cpu_state == PLAT_LOCAL_STATE_RET); + + /* + * Enter standby state + * dsb is good practice before using wfi to enter low power states + */ + dsb(); + wfi(); +} + +/******************************************************************************* + * Platform handler called when a power domain is about to be turned on. The + * mpidr determines the CPU to be turned on. + ******************************************************************************/ +static int qemu_pwr_domain_on(u_register_t mpidr) +{ + int pos = plat_core_pos_by_mpidr(mpidr); + uint64_t *hold_base = (uint64_t *)PLAT_QEMU_HOLD_BASE; + + if (pos < 0) { + return PSCI_E_INVALID_PARAMS; + } + + hold_base[pos] = PLAT_QEMU_HOLD_STATE_GO; + dsb(); + sev(); + + return PSCI_E_SUCCESS; +} + +/******************************************************************************* + * Platform handler called when a power domain is about to be turned off. The + * target_state encodes the power state that each level should transition to. + ******************************************************************************/ +static void qemu_pwr_domain_off(const psci_power_state_t *target_state) +{ + qemu_pwr_gic_off(); +} + +void __dead2 plat_secondary_cold_boot_setup(void); + +static void __dead2 +qemu_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state) +{ + disable_mmu_el3(); + plat_secondary_cold_boot_setup(); +} + +/******************************************************************************* + * Platform handler called when a power domain is about to be suspended. The + * target_state encodes the power state that each level should transition to. + ******************************************************************************/ +void qemu_pwr_domain_suspend(const psci_power_state_t *target_state) +{ + assert(false); +} + +/******************************************************************************* + * Platform handler called when a power domain has just been powered on after + * being turned off earlier. The target_state encodes the low power state that + * each level has woken up from. + ******************************************************************************/ +void qemu_pwr_domain_on_finish(const psci_power_state_t *target_state) +{ + assert(target_state->pwr_domain_state[MPIDR_AFFLVL0] == + PLAT_LOCAL_STATE_OFF); + + qemu_pwr_gic_on_finish(); +} + +/******************************************************************************* + * Platform handler called when a power domain has just been powered on after + * having been suspended earlier. The target_state encodes the low power state + * that each level has woken up from. + ******************************************************************************/ +void qemu_pwr_domain_suspend_finish(const psci_power_state_t *target_state) +{ + assert(false); +} + +/******************************************************************************* + * Platform handlers to shutdown/reboot the system + ******************************************************************************/ +static void __dead2 qemu_system_off(void) +{ + mmio_write_32(SBSA_SECURE_EC_OFFSET, SBSA_SECURE_EC_CMD_SHUTDOWN); + panic(); +} + +static void __dead2 qemu_system_reset(void) +{ + mmio_write_32(SBSA_SECURE_EC_OFFSET, SBSA_SECURE_EC_CMD_REBOOT); + panic(); +} + +static const plat_psci_ops_t plat_qemu_psci_pm_ops = { + .cpu_standby = qemu_cpu_standby, + .pwr_domain_on = qemu_pwr_domain_on, + .pwr_domain_off = qemu_pwr_domain_off, + .pwr_domain_pwr_down_wfi = qemu_pwr_domain_pwr_down_wfi, + .pwr_domain_suspend = qemu_pwr_domain_suspend, + .pwr_domain_on_finish = qemu_pwr_domain_on_finish, + .pwr_domain_suspend_finish = qemu_pwr_domain_suspend_finish, + .system_off = qemu_system_off, + .system_reset = qemu_system_reset, + .validate_power_state = qemu_validate_power_state +}; + +int plat_setup_psci_ops(uintptr_t sec_entrypoint, + const plat_psci_ops_t **psci_ops) +{ + uintptr_t *mailbox = (uintptr_t *)PLAT_QEMU_TRUSTED_MAILBOX_BASE; + + *mailbox = sec_entrypoint; + secure_entrypoint = (unsigned long)sec_entrypoint; + *psci_ops = &plat_qemu_psci_pm_ops; + + return 0; +} diff --git a/plat/qemu/qemu_sbsa/sbsa_private.h b/plat/qemu/qemu_sbsa/sbsa_private.h index 29ee1d071..a9f4601de 100644 --- a/plat/qemu/qemu_sbsa/sbsa_private.h +++ b/plat/qemu/qemu_sbsa/sbsa_private.h @@ -11,4 +11,7 @@ unsigned int plat_qemu_calc_core_pos(u_register_t mpidr); +void qemu_pwr_gic_on_finish(void); +void qemu_pwr_gic_off(void); + #endif /* SBSA_PRIVATE_H */ -- cgit v1.2.3 From b4734308981b651bac64adb90a7b148f252e850a Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Wed, 20 Jan 2021 11:04:08 +0800 Subject: drivers: move scmi-msg out of st Make the scmi-msg driver reused by others. Signed-off-by: Peng Fan Change-Id: I5bc35fd4dab70f45c09b8aab65af4209cf23b124 --- drivers/scmi-msg/base.c | 198 +++++++++++++ drivers/scmi-msg/base.h | 75 +++++ drivers/scmi-msg/clock.c | 381 +++++++++++++++++++++++++ drivers/scmi-msg/clock.h | 150 ++++++++++ drivers/scmi-msg/common.h | 136 +++++++++ drivers/scmi-msg/entry.c | 63 ++++ drivers/scmi-msg/reset_domain.c | 197 +++++++++++++ drivers/scmi-msg/reset_domain.h | 122 ++++++++ drivers/scmi-msg/smt.c | 206 +++++++++++++ drivers/st/scmi-msg/base.c | 198 ------------- drivers/st/scmi-msg/base.h | 75 ----- drivers/st/scmi-msg/clock.c | 381 ------------------------- drivers/st/scmi-msg/clock.h | 150 ---------- drivers/st/scmi-msg/common.h | 136 --------- drivers/st/scmi-msg/entry.c | 63 ---- drivers/st/scmi-msg/reset_domain.c | 197 ------------- drivers/st/scmi-msg/reset_domain.h | 122 -------- drivers/st/scmi-msg/smt.c | 206 ------------- include/drivers/scmi-msg.h | 207 ++++++++++++++ include/drivers/scmi.h | 29 ++ include/drivers/st/scmi-msg.h | 207 -------------- include/drivers/st/scmi.h | 29 -- plat/st/stm32mp1/services/stm32mp1_svc_setup.c | 2 +- plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk | 10 +- plat/st/stm32mp1/stm32mp1_scmi.c | 4 +- 25 files changed, 1772 insertions(+), 1772 deletions(-) create mode 100644 drivers/scmi-msg/base.c create mode 100644 drivers/scmi-msg/base.h create mode 100644 drivers/scmi-msg/clock.c create mode 100644 drivers/scmi-msg/clock.h create mode 100644 drivers/scmi-msg/common.h create mode 100644 drivers/scmi-msg/entry.c create mode 100644 drivers/scmi-msg/reset_domain.c create mode 100644 drivers/scmi-msg/reset_domain.h create mode 100644 drivers/scmi-msg/smt.c delete mode 100644 drivers/st/scmi-msg/base.c delete mode 100644 drivers/st/scmi-msg/base.h delete mode 100644 drivers/st/scmi-msg/clock.c delete mode 100644 drivers/st/scmi-msg/clock.h delete mode 100644 drivers/st/scmi-msg/common.h delete mode 100644 drivers/st/scmi-msg/entry.c delete mode 100644 drivers/st/scmi-msg/reset_domain.c delete mode 100644 drivers/st/scmi-msg/reset_domain.h delete mode 100644 drivers/st/scmi-msg/smt.c create mode 100644 include/drivers/scmi-msg.h create mode 100644 include/drivers/scmi.h delete mode 100644 include/drivers/st/scmi-msg.h delete mode 100644 include/drivers/st/scmi.h diff --git a/drivers/scmi-msg/base.c b/drivers/scmi-msg/base.c new file mode 100644 index 000000000..2d7203451 --- /dev/null +++ b/drivers/scmi-msg/base.c @@ -0,0 +1,198 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Linaro Limited + */ +#include +#include + +#include +#include +#include +#include + +#include "common.h" + +static bool message_id_is_supported(unsigned int message_id); + +static void report_version(struct scmi_msg *msg) +{ + struct scmi_protocol_version_p2a return_values = { + .status = SCMI_SUCCESS, + .version = SCMI_PROTOCOL_VERSION_BASE, + }; + + if (msg->in_size != 0U) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void report_attributes(struct scmi_msg *msg) +{ + size_t protocol_count = plat_scmi_protocol_count(); + struct scmi_protocol_attributes_p2a return_values = { + .status = SCMI_SUCCESS, + /* Null agent count since agent discovery is not supported */ + .attributes = SCMI_BASE_PROTOCOL_ATTRIBUTES(protocol_count, 0U), + }; + + if (msg->in_size != 0U) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void report_message_attributes(struct scmi_msg *msg) +{ + struct scmi_protocol_message_attributes_a2p *in_args = (void *)msg->in; + struct scmi_protocol_message_attributes_p2a return_values = { + .status = SCMI_SUCCESS, + /* For this protocol, attributes shall be zero */ + .attributes = 0U, + }; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + if (!message_id_is_supported(in_args->message_id)) { + scmi_status_response(msg, SCMI_NOT_FOUND); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void discover_vendor(struct scmi_msg *msg) +{ + const char *name = plat_scmi_vendor_name(); + struct scmi_base_discover_vendor_p2a return_values = { + .status = SCMI_SUCCESS, + }; + + if (msg->in_size != 0U) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + COPY_NAME_IDENTIFIER(return_values.vendor_identifier, name); + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void discover_sub_vendor(struct scmi_msg *msg) +{ + const char *name = plat_scmi_sub_vendor_name(); + struct scmi_base_discover_sub_vendor_p2a return_values = { + .status = SCMI_SUCCESS, + }; + + if (msg->in_size != 0U) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + COPY_NAME_IDENTIFIER(return_values.sub_vendor_identifier, name); + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void discover_implementation_version(struct scmi_msg *msg) +{ + struct scmi_protocol_version_p2a return_values = { + .status = SCMI_SUCCESS, + .version = SCMI_IMPL_VERSION, + }; + + if (msg->in_size != 0U) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static unsigned int count_protocols_in_list(const uint8_t *protocol_list) +{ + unsigned int count = 0U; + + if (protocol_list != NULL) { + while (protocol_list[count] != 0U) { + count++; + } + } + + return count; +} + +#define MAX_PROTOCOL_IN_LIST 8U + +static void discover_list_protocols(struct scmi_msg *msg) +{ + const struct scmi_base_discover_list_protocols_a2p *a2p = NULL; + struct scmi_base_discover_list_protocols_p2a p2a = { + .status = SCMI_SUCCESS, + }; + uint8_t outargs[sizeof(p2a) + MAX_PROTOCOL_IN_LIST] = { 0U }; + const uint8_t *list = NULL; + unsigned int count = 0U; + + if (msg->in_size != sizeof(*a2p)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + assert(msg->out_size > sizeof(outargs)); + + a2p = (void *)msg->in; + + list = plat_scmi_protocol_list(msg->agent_id); + count = count_protocols_in_list(list); + if (count > a2p->skip) { + count = MIN(count - a2p->skip, MAX_PROTOCOL_IN_LIST); + } else { + count = 0U; + } + + p2a.num_protocols = count; + + memcpy(outargs, &p2a, sizeof(p2a)); + memcpy(outargs + sizeof(p2a), list + a2p->skip, count); + + scmi_write_response(msg, outargs, sizeof(outargs)); +} + +static const scmi_msg_handler_t scmi_base_handler_table[] = { + [SCMI_PROTOCOL_VERSION] = report_version, + [SCMI_PROTOCOL_ATTRIBUTES] = report_attributes, + [SCMI_PROTOCOL_MESSAGE_ATTRIBUTES] = report_message_attributes, + [SCMI_BASE_DISCOVER_VENDOR] = discover_vendor, + [SCMI_BASE_DISCOVER_SUB_VENDOR] = discover_sub_vendor, + [SCMI_BASE_DISCOVER_IMPLEMENTATION_VERSION] = + discover_implementation_version, + [SCMI_BASE_DISCOVER_LIST_PROTOCOLS] = discover_list_protocols, +}; + +static bool message_id_is_supported(unsigned int message_id) +{ + return (message_id < ARRAY_SIZE(scmi_base_handler_table)) && + (scmi_base_handler_table[message_id] != NULL); +} + +scmi_msg_handler_t scmi_msg_get_base_handler(struct scmi_msg *msg) +{ + unsigned int message_id = SPECULATION_SAFE_VALUE(msg->message_id); + + if (message_id >= ARRAY_SIZE(scmi_base_handler_table)) { + VERBOSE("Base handle not found %u\n", msg->message_id); + return NULL; + } + + return scmi_base_handler_table[message_id]; +} diff --git a/drivers/scmi-msg/base.h b/drivers/scmi-msg/base.h new file mode 100644 index 000000000..c4a9c64a4 --- /dev/null +++ b/drivers/scmi-msg/base.h @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Linaro Limited + */ + +#ifndef SCMI_MSG_BASE_H +#define SCMI_MSG_BASE_H + +#include + +#define SCMI_PROTOCOL_VERSION_BASE 0x20000U + +#define SCMI_DEFAULT_STRING_LENGTH 16U + +enum scmi_base_message_id { + SCMI_BASE_DISCOVER_VENDOR = 0x003, + SCMI_BASE_DISCOVER_SUB_VENDOR = 0x004, + SCMI_BASE_DISCOVER_IMPLEMENTATION_VERSION = 0x005, + SCMI_BASE_DISCOVER_LIST_PROTOCOLS = 0x006, + SCMI_BASE_DISCOVER_AGENT = 0x007, + SCMI_BASE_NOTIFY_ERRORS = 0x008, +}; + +/* + * PROTOCOL_ATTRIBUTES + */ + +#define SCMI_BASE_PROTOCOL_ATTRS_NUM_PROTOCOLS_POS 0 +#define SCMI_BASE_PROTOCOL_ATTRS_NUM_AGENTS_POS 8 + +#define SCMI_BASE_PROTOCOL_ATTRS_NUM_PROTOCOLS_MASK 0xFFU +#define SCMI_BASE_PROTOCOL_ATTRS_NUM_AGENTS_MASK 0xFF00U + +#define SCMI_BASE_PROTOCOL_ATTRIBUTES(NUM_PROTOCOLS, NUM_AGENTS) \ + ((((NUM_PROTOCOLS) << SCMI_BASE_PROTOCOL_ATTRS_NUM_PROTOCOLS_POS) & \ + SCMI_BASE_PROTOCOL_ATTRS_NUM_PROTOCOLS_MASK) | \ + (((NUM_AGENTS) << SCMI_BASE_PROTOCOL_ATTRS_NUM_AGENTS_POS) & \ + SCMI_BASE_PROTOCOL_ATTRS_NUM_AGENTS_MASK)) + +/* + * BASE_DISCOVER_VENDOR + */ +struct scmi_base_discover_vendor_p2a { + int32_t status; + char vendor_identifier[SCMI_DEFAULT_STRING_LENGTH]; +}; + +/* + * BASE_DISCOVER_SUB_VENDOR + */ +struct scmi_base_discover_sub_vendor_p2a { + int32_t status; + char sub_vendor_identifier[SCMI_DEFAULT_STRING_LENGTH]; +}; + +/* + * BASE_DISCOVER_IMPLEMENTATION_VERSION + * No special structure right now, see protocol_version. + */ + +/* + * BASE_DISCOVER_LIST_PROTOCOLS + */ +struct scmi_base_discover_list_protocols_a2p { + uint32_t skip; +}; + +struct scmi_base_discover_list_protocols_p2a { + int32_t status; + uint32_t num_protocols; + uint32_t protocols[]; +}; + +#endif /* SCMI_MSG_BASE_H */ diff --git a/drivers/scmi-msg/clock.c b/drivers/scmi-msg/clock.c new file mode 100644 index 000000000..e96cede6e --- /dev/null +++ b/drivers/scmi-msg/clock.c @@ -0,0 +1,381 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Linaro Limited + */ +#include +#include + +#include +#include +#include + +#include "common.h" + +#pragma weak plat_scmi_clock_count +#pragma weak plat_scmi_clock_get_name +#pragma weak plat_scmi_clock_rates_array +#pragma weak plat_scmi_clock_rates_by_step +#pragma weak plat_scmi_clock_get_rate +#pragma weak plat_scmi_clock_set_rate +#pragma weak plat_scmi_clock_get_state +#pragma weak plat_scmi_clock_set_state + +static bool message_id_is_supported(unsigned int message_id); + +size_t plat_scmi_clock_count(unsigned int agent_id __unused) +{ + return 0U; +} + +const char *plat_scmi_clock_get_name(unsigned int agent_id __unused, + unsigned int scmi_id __unused) +{ + return NULL; +} + +int32_t plat_scmi_clock_rates_array(unsigned int agent_id __unused, + unsigned int scmi_id __unused, + unsigned long *rates __unused, + size_t *nb_elts __unused) +{ + return SCMI_NOT_SUPPORTED; +} + +int32_t plat_scmi_clock_rates_by_step(unsigned int agent_id __unused, + unsigned int scmi_id __unused, + unsigned long *steps __unused) +{ + return SCMI_NOT_SUPPORTED; +} + +unsigned long plat_scmi_clock_get_rate(unsigned int agent_id __unused, + unsigned int scmi_id __unused) +{ + return 0U; +} + +int32_t plat_scmi_clock_set_rate(unsigned int agent_id __unused, + unsigned int scmi_id __unused, + unsigned long rate __unused) +{ + return SCMI_NOT_SUPPORTED; +} + +int32_t plat_scmi_clock_get_state(unsigned int agent_id __unused, + unsigned int scmi_id __unused) +{ + return SCMI_NOT_SUPPORTED; +} + +int32_t plat_scmi_clock_set_state(unsigned int agent_id __unused, + unsigned int scmi_id __unused, + bool enable_not_disable __unused) +{ + return SCMI_NOT_SUPPORTED; +} + +static void report_version(struct scmi_msg *msg) +{ + struct scmi_protocol_version_p2a return_values = { + .status = SCMI_SUCCESS, + .version = SCMI_PROTOCOL_VERSION_CLOCK, + }; + + if (msg->in_size != 0) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void report_attributes(struct scmi_msg *msg) +{ + size_t agent_count = plat_scmi_clock_count(msg->agent_id); + struct scmi_protocol_attributes_p2a return_values = { + .status = SCMI_SUCCESS, + .attributes = SCMI_CLOCK_PROTOCOL_ATTRIBUTES(1U, agent_count), + }; + + if (msg->in_size != 0) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void report_message_attributes(struct scmi_msg *msg) +{ + struct scmi_protocol_message_attributes_a2p *in_args = (void *)msg->in; + struct scmi_protocol_message_attributes_p2a return_values = { + .status = SCMI_SUCCESS, + /* For this protocol, attributes shall be zero */ + .attributes = 0U, + }; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + if (!message_id_is_supported(in_args->message_id)) { + scmi_status_response(msg, SCMI_NOT_FOUND); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void scmi_clock_attributes(struct scmi_msg *msg) +{ + const struct scmi_clock_attributes_a2p *in_args = (void *)msg->in; + struct scmi_clock_attributes_p2a return_values = { + .status = SCMI_SUCCESS, + }; + const char *name = NULL; + unsigned int clock_id = 0U; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + clock_id = SPECULATION_SAFE_VALUE(in_args->clock_id); + + if (clock_id >= plat_scmi_clock_count(msg->agent_id)) { + scmi_status_response(msg, SCMI_INVALID_PARAMETERS); + return; + } + + + name = plat_scmi_clock_get_name(msg->agent_id, clock_id); + if (name == NULL) { + scmi_status_response(msg, SCMI_NOT_FOUND); + return; + } + + COPY_NAME_IDENTIFIER(return_values.clock_name, name); + + return_values.attributes = plat_scmi_clock_get_state(msg->agent_id, + clock_id); + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void scmi_clock_rate_get(struct scmi_msg *msg) +{ + const struct scmi_clock_rate_get_a2p *in_args = (void *)msg->in; + unsigned long rate = 0U; + struct scmi_clock_rate_get_p2a return_values = { + .status = SCMI_SUCCESS, + }; + unsigned int clock_id = 0U; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + clock_id = SPECULATION_SAFE_VALUE(in_args->clock_id); + + if (clock_id >= plat_scmi_clock_count(msg->agent_id)) { + scmi_status_response(msg, SCMI_INVALID_PARAMETERS); + return; + } + + rate = plat_scmi_clock_get_rate(msg->agent_id, clock_id); + + return_values.rate[0] = (uint32_t)rate; + return_values.rate[1] = (uint32_t)((uint64_t)rate >> 32); + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void scmi_clock_rate_set(struct scmi_msg *msg) +{ + const struct scmi_clock_rate_set_a2p *in_args = (void *)msg->in; + unsigned long rate = 0U; + int32_t status = 0; + unsigned int clock_id = 0U; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + clock_id = SPECULATION_SAFE_VALUE(in_args->clock_id); + + if (clock_id >= plat_scmi_clock_count(msg->agent_id)) { + scmi_status_response(msg, SCMI_INVALID_PARAMETERS); + return; + } + + rate = (unsigned long)(((uint64_t)in_args->rate[1] << 32) | + in_args->rate[0]); + + status = plat_scmi_clock_set_rate(msg->agent_id, clock_id, rate); + + scmi_status_response(msg, status); +} + +static void scmi_clock_config_set(struct scmi_msg *msg) +{ + const struct scmi_clock_config_set_a2p *in_args = (void *)msg->in; + int32_t status = SCMI_GENERIC_ERROR; + bool enable = false; + unsigned int clock_id = 0U; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + clock_id = SPECULATION_SAFE_VALUE(in_args->clock_id); + + if (clock_id >= plat_scmi_clock_count(msg->agent_id)) { + scmi_status_response(msg, SCMI_INVALID_PARAMETERS); + return; + } + + enable = in_args->attributes & SCMI_CLOCK_CONFIG_SET_ENABLE_MASK; + + status = plat_scmi_clock_set_state(msg->agent_id, clock_id, enable); + + scmi_status_response(msg, status); +} + +#define RATES_ARRAY_SIZE_MAX (SCMI_PLAYLOAD_MAX - \ + sizeof(struct scmi_clock_describe_rates_p2a)) + +#define SCMI_RATES_BY_ARRAY(_nb_rates, _rem_rates) \ + SCMI_CLOCK_DESCRIBE_RATES_NUM_RATES_FLAGS((_nb_rates), \ + SCMI_CLOCK_RATE_FORMAT_LIST, \ + (_rem_rates)) +#define SCMI_RATES_BY_STEP \ + SCMI_CLOCK_DESCRIBE_RATES_NUM_RATES_FLAGS(3U, \ + SCMI_CLOCK_RATE_FORMAT_RANGE, \ + 0U) + +#define RATE_DESC_SIZE sizeof(struct scmi_clock_rate) + +static void write_rate_desc_array_in_buffer(char *dest, unsigned long *rates, + size_t nb_elt) +{ + uint32_t *out = (uint32_t *)(uintptr_t)dest; + size_t n; + + ASSERT_SYM_PTR_ALIGN(out); + + for (n = 0U; n < nb_elt; n++) { + out[2 * n] = (uint32_t)rates[n]; + out[2 * n + 1] = (uint32_t)((uint64_t)rates[n] >> 32); + } +} + +static void scmi_clock_describe_rates(struct scmi_msg *msg) +{ + const struct scmi_clock_describe_rates_a2p *in_args = (void *)msg->in; + struct scmi_clock_describe_rates_p2a p2a = { + .status = SCMI_SUCCESS, + }; + size_t nb_rates; + int32_t status; + unsigned int clock_id; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + clock_id = SPECULATION_SAFE_VALUE(in_args->clock_id); + + if (clock_id >= plat_scmi_clock_count(msg->agent_id)) { + scmi_status_response(msg, SCMI_INVALID_PARAMETERS); + return; + } + + /* Platform may support array rate description */ + status = plat_scmi_clock_rates_array(msg->agent_id, clock_id, NULL, + &nb_rates); + if (status == SCMI_SUCCESS) { + /* Currently 12 cells mex, so it's affordable for the stack */ + unsigned long plat_rates[RATES_ARRAY_SIZE_MAX / RATE_DESC_SIZE]; + size_t max_nb = RATES_ARRAY_SIZE_MAX / RATE_DESC_SIZE; + size_t ret_nb = MIN(nb_rates - in_args->rate_index, max_nb); + size_t rem_nb = nb_rates - in_args->rate_index - ret_nb; + + status = plat_scmi_clock_rates_array(msg->agent_id, clock_id, + plat_rates, &ret_nb); + if (status == SCMI_SUCCESS) { + write_rate_desc_array_in_buffer(msg->out + sizeof(p2a), + plat_rates, ret_nb); + + p2a.num_rates_flags = SCMI_RATES_BY_ARRAY(ret_nb, + rem_nb); + p2a.status = SCMI_SUCCESS; + + memcpy(msg->out, &p2a, sizeof(p2a)); + msg->out_size_out = sizeof(p2a) + + ret_nb * RATE_DESC_SIZE; + } + } else if (status == SCMI_NOT_SUPPORTED) { + unsigned long triplet[3] = { 0U, 0U, 0U }; + + /* Platform may support min§max/step triplet description */ + status = plat_scmi_clock_rates_by_step(msg->agent_id, clock_id, + triplet); + if (status == SCMI_SUCCESS) { + write_rate_desc_array_in_buffer(msg->out + sizeof(p2a), + triplet, 3U); + + p2a.num_rates_flags = SCMI_RATES_BY_STEP; + p2a.status = SCMI_SUCCESS; + + memcpy(msg->out, &p2a, sizeof(p2a)); + msg->out_size_out = sizeof(p2a) + (3U * RATE_DESC_SIZE); + } + } else { + /* Fallthrough generic exit sequence below with error status */ + } + + if (status != SCMI_SUCCESS) { + scmi_status_response(msg, status); + } else { + /* + * Message payload is already writen to msg->out, and + * msg->out_size_out updated. + */ + } +} + +static const scmi_msg_handler_t scmi_clock_handler_table[] = { + [SCMI_PROTOCOL_VERSION] = report_version, + [SCMI_PROTOCOL_ATTRIBUTES] = report_attributes, + [SCMI_PROTOCOL_MESSAGE_ATTRIBUTES] = report_message_attributes, + [SCMI_CLOCK_ATTRIBUTES] = scmi_clock_attributes, + [SCMI_CLOCK_DESCRIBE_RATES] = scmi_clock_describe_rates, + [SCMI_CLOCK_RATE_SET] = scmi_clock_rate_set, + [SCMI_CLOCK_RATE_GET] = scmi_clock_rate_get, + [SCMI_CLOCK_CONFIG_SET] = scmi_clock_config_set, +}; + +static bool message_id_is_supported(size_t message_id) +{ + return (message_id < ARRAY_SIZE(scmi_clock_handler_table)) && + (scmi_clock_handler_table[message_id] != NULL); +} + +scmi_msg_handler_t scmi_msg_get_clock_handler(struct scmi_msg *msg) +{ + const size_t array_size = ARRAY_SIZE(scmi_clock_handler_table); + unsigned int message_id = SPECULATION_SAFE_VALUE(msg->message_id); + + if (message_id >= array_size) { + VERBOSE("Clock handle not found %u", msg->message_id); + return NULL; + } + + return scmi_clock_handler_table[message_id]; +} diff --git a/drivers/scmi-msg/clock.h b/drivers/scmi-msg/clock.h new file mode 100644 index 000000000..a637934ee --- /dev/null +++ b/drivers/scmi-msg/clock.h @@ -0,0 +1,150 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019, Linaro Limited + */ + +#ifndef SCMI_MSG_CLOCK_H +#define SCMI_MSG_CLOCK_H + +#include + +#include + +#define SCMI_PROTOCOL_VERSION_CLOCK 0x20000U + +/* + * Identifiers of the SCMI Clock Management Protocol commands + */ +enum scmi_clock_command_id { + SCMI_CLOCK_ATTRIBUTES = 0x003, + SCMI_CLOCK_DESCRIBE_RATES = 0x004, + SCMI_CLOCK_RATE_SET = 0x005, + SCMI_CLOCK_RATE_GET = 0x006, + SCMI_CLOCK_CONFIG_SET = 0x007, +}; + +/* Protocol attributes */ +#define SCMI_CLOCK_CLOCK_COUNT_MASK GENMASK(15, 0) +#define SCMI_CLOCK_MAX_PENDING_TRANSITIONS_MASK GENMASK(23, 16) + +#define SCMI_CLOCK_PROTOCOL_ATTRIBUTES(_max_pending, _clk_count) \ + ((((_max_pending) << 16) & SCMI_CLOCK_MAX_PENDING_TRANSITIONS_MASK) | \ + (((_clk_count) & SCMI_CLOCK_CLOCK_COUNT_MASK))) + +struct scmi_clock_attributes_a2p { + uint32_t clock_id; +}; + +#define SCMI_CLOCK_NAME_LENGTH_MAX 16U + +struct scmi_clock_attributes_p2a { + int32_t status; + uint32_t attributes; + char clock_name[SCMI_CLOCK_NAME_LENGTH_MAX]; +}; + +/* + * Clock Rate Get + */ + +struct scmi_clock_rate_get_a2p { + uint32_t clock_id; +}; + +struct scmi_clock_rate_get_p2a { + int32_t status; + uint32_t rate[2]; +}; + +/* + * Clock Rate Set + */ + +/* If set, set the new clock rate asynchronously */ +#define SCMI_CLOCK_RATE_SET_ASYNC_POS 0 +/* If set, do not send a delayed asynchronous response */ +#define SCMI_CLOCK_RATE_SET_NO_DELAYED_RESPONSE_POS 1 +/* Round up, if set, otherwise round down */ +#define SCMI_CLOCK_RATE_SET_ROUND_UP_POS 2 +/* If set, the platform chooses the appropriate rounding mode */ +#define SCMI_CLOCK_RATE_SET_ROUND_AUTO_POS 3 + +#define SCMI_CLOCK_RATE_SET_ASYNC_MASK \ + BIT(SCMI_CLOCK_RATE_SET_ASYNC_POS) +#define SCMI_CLOCK_RATE_SET_NO_DELAYED_RESPONSE_MASK \ + BIT(SCMI_CLOCK_RATE_SET_NO_DELAYED_RESPONSE_POS) +#define SCMI_CLOCK_RATE_SET_ROUND_UP_MASK \ + BIT(SCMI_CLOCK_RATE_SET_ROUND_UP_POS) +#define SCMI_CLOCK_RATE_SET_ROUND_AUTO_MASK \ + BIT(SCMI_CLOCK_RATE_SET_ROUND_AUTO_POS) + +struct scmi_clock_rate_set_a2p { + uint32_t flags; + uint32_t clock_id; + uint32_t rate[2]; +}; + +struct scmi_clock_rate_set_p2a { + int32_t status; +}; + +/* + * Clock Config Set + */ + +#define SCMI_CLOCK_CONFIG_SET_ENABLE_POS 0 + +#define SCMI_CLOCK_CONFIG_SET_ENABLE_MASK \ + BIT(SCMI_CLOCK_CONFIG_SET_ENABLE_POS) + +struct scmi_clock_config_set_a2p { + uint32_t clock_id; + uint32_t attributes; +}; + +struct scmi_clock_config_set_p2a { + int32_t status; +}; + +/* + * Clock Describe Rates + */ + +#define SCMI_CLOCK_RATE_FORMAT_RANGE 1U +#define SCMI_CLOCK_RATE_FORMAT_LIST 0U + +#define SCMI_CLOCK_DESCRIBE_RATES_REMAINING_MASK GENMASK_32(31, 16) +#define SCMI_CLOCK_DESCRIBE_RATES_REMAINING_POS 16 + +#define SCMI_CLOCK_DESCRIBE_RATES_FORMAT_MASK BIT(12) +#define SCMI_CLOCK_DESCRIBE_RATES_FORMAT_POS 12 + +#define SCMI_CLOCK_DESCRIBE_RATES_COUNT_MASK GENMASK_32(11, 0) + +#define SCMI_CLOCK_DESCRIBE_RATES_NUM_RATES_FLAGS(_count, _fmt, _rem_rates) \ + ( \ + ((_count) & SCMI_CLOCK_DESCRIBE_RATES_COUNT_MASK) | \ + (((_rem_rates) << SCMI_CLOCK_DESCRIBE_RATES_REMAINING_POS) & \ + SCMI_CLOCK_DESCRIBE_RATES_REMAINING_MASK) | \ + (((_fmt) << SCMI_CLOCK_DESCRIBE_RATES_FORMAT_POS) & \ + SCMI_CLOCK_DESCRIBE_RATES_FORMAT_MASK) \ + ) + +struct scmi_clock_rate { + uint32_t low; + uint32_t high; +}; + +struct scmi_clock_describe_rates_a2p { + uint32_t clock_id; + uint32_t rate_index; +}; + +struct scmi_clock_describe_rates_p2a { + int32_t status; + uint32_t num_rates_flags; + struct scmi_clock_rate rates[]; +}; + +#endif /* SCMI_MSG_CLOCK_H */ diff --git a/drivers/scmi-msg/common.h b/drivers/scmi-msg/common.h new file mode 100644 index 000000000..ef5953b3d --- /dev/null +++ b/drivers/scmi-msg/common.h @@ -0,0 +1,136 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Linaro Limited + */ +#ifndef SCMI_MSG_COMMON_H +#define SCMI_MSG_COMMON_H + +#include +#include +#include +#include + +#include "base.h" +#include "clock.h" +#include "reset_domain.h" + +#define SCMI_VERSION 0x20000U +#define SCMI_IMPL_VERSION 0U + +#define SCMI_PLAYLOAD_MAX 92U + +/* + * Copy name identifier in target buffer following the SCMI specification + * that state name identifier shall be a null terminated string. + */ +#define COPY_NAME_IDENTIFIER(_dst_array, _name) \ + do { \ + assert(strlen(_name) < sizeof(_dst_array)); \ + strlcpy((_dst_array), (_name), sizeof(_dst_array)); \ + } while (0) + +/* Common command identifiers shared by all procotols */ +enum scmi_common_message_id { + SCMI_PROTOCOL_VERSION = 0x000, + SCMI_PROTOCOL_ATTRIBUTES = 0x001, + SCMI_PROTOCOL_MESSAGE_ATTRIBUTES = 0x002 +}; + +/* Common platform-to-agent (p2a) PROTOCOL_VERSION structure */ +struct scmi_protocol_version_p2a { + int32_t status; + uint32_t version; +}; + +/* Generic platform-to-agent (p2a) PROTOCOL_ATTRIBUTES structure */ +struct scmi_protocol_attributes_p2a { + int32_t status; + uint32_t attributes; +}; + +/* Generic agent-to-platform (a2p) PROTOCOL_MESSAGE_ATTRIBUTES structure */ +struct scmi_protocol_message_attributes_a2p { + uint32_t message_id; +}; + +/* Generic platform-to-agent (p2a) PROTOCOL_MESSAGE_ATTRIBUTES structure */ +struct scmi_protocol_message_attributes_p2a { + int32_t status; + uint32_t attributes; +}; + +/* + * struct scmi_msg - SCMI message context + * + * @agent_id: SCMI agent ID, safely set from secure world + * @protocol_id: SCMI protocol ID for the related message, set by caller agent + * @message_id: SCMI message ID for the related message, set by caller agent + * @in: Address of the incoming message payload copied in secure memory + * @in_size: Byte length of the incoming message payload, set by caller agent + * @out: Address of of the output message payload message in non-secure memory + * @out_size: Byte length of the provisionned output buffer + * @out_size_out: Byte length of the output message payload + */ +struct scmi_msg { + unsigned int agent_id; + unsigned int protocol_id; + unsigned int message_id; + char *in; + size_t in_size; + char *out; + size_t out_size; + size_t out_size_out; +}; + +/* + * Type scmi_msg_handler_t is used by procotol drivers to safely find + * the handler function for the incoming message ID. + */ +typedef void (*scmi_msg_handler_t)(struct scmi_msg *msg); + +/* + * scmi_msg_get_base_handler - Return a handler for a base message + * @msg - message to process + * Return a function handler for the message or NULL + */ +scmi_msg_handler_t scmi_msg_get_base_handler(struct scmi_msg *msg); + +/* + * scmi_msg_get_clock_handler - Return a handler for a clock message + * @msg - message to process + * Return a function handler for the message or NULL + */ +scmi_msg_handler_t scmi_msg_get_clock_handler(struct scmi_msg *msg); + +/* + * scmi_msg_get_rstd_handler - Return a handler for a reset domain message + * @msg - message to process + * Return a function handler for the message or NULL + */ +scmi_msg_handler_t scmi_msg_get_rstd_handler(struct scmi_msg *msg); + +/* + * Process Read, process and write response for input SCMI message + * + * @msg: SCMI message context + */ +void scmi_process_message(struct scmi_msg *msg); + +/* + * Write SCMI response payload to output message shared memory + * + * @msg: SCMI message context + * @payload: Output message payload + * @size: Byte size of output message payload + */ +void scmi_write_response(struct scmi_msg *msg, void *payload, size_t size); + +/* + * Write status only SCMI response payload to output message shared memory + * + * @msg: SCMI message context + * @status: SCMI status value returned to caller + */ +void scmi_status_response(struct scmi_msg *msg, int32_t status); +#endif /* SCMI_MSG_COMMON_H */ diff --git a/drivers/scmi-msg/entry.c b/drivers/scmi-msg/entry.c new file mode 100644 index 000000000..ea3efa24b --- /dev/null +++ b/drivers/scmi-msg/entry.c @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Linaro Limited + */ + +#include + +#include +#include + +#include "common.h" + +void scmi_status_response(struct scmi_msg *msg, int32_t status) +{ + assert(msg->out && msg->out_size >= sizeof(int32_t)); + + memcpy(msg->out, &status, sizeof(int32_t)); + msg->out_size_out = sizeof(int32_t); +} + +void scmi_write_response(struct scmi_msg *msg, void *payload, size_t size) +{ + /* + * Output payload shall be at least the size of the status + * Output buffer shall be at least be the size of the status + * Output paylaod shall fit in output buffer + */ + assert(payload && size >= sizeof(int32_t) && size <= msg->out_size && + msg->out && msg->out_size >= sizeof(int32_t)); + + memcpy(msg->out, payload, size); + msg->out_size_out = size; +} + +void scmi_process_message(struct scmi_msg *msg) +{ + scmi_msg_handler_t handler = NULL; + + switch (msg->protocol_id) { + case SCMI_PROTOCOL_ID_BASE: + handler = scmi_msg_get_base_handler(msg); + break; + case SCMI_PROTOCOL_ID_CLOCK: + handler = scmi_msg_get_clock_handler(msg); + break; + case SCMI_PROTOCOL_ID_RESET_DOMAIN: + handler = scmi_msg_get_rstd_handler(msg); + break; + default: + break; + } + + if (handler) { + handler(msg); + return; + } + + ERROR("Agent %u Protocol 0x%x Message 0x%x: not supported", + msg->agent_id, msg->protocol_id, msg->message_id); + + scmi_status_response(msg, SCMI_NOT_SUPPORTED); +} diff --git a/drivers/scmi-msg/reset_domain.c b/drivers/scmi-msg/reset_domain.c new file mode 100644 index 000000000..76ac47ea9 --- /dev/null +++ b/drivers/scmi-msg/reset_domain.c @@ -0,0 +1,197 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Linaro Limited + */ +#include +#include + +#include +#include +#include +#include + +#include "common.h" + +static bool message_id_is_supported(unsigned int message_id); + +#pragma weak plat_scmi_rstd_count +#pragma weak plat_scmi_rstd_get_name +#pragma weak plat_scmi_rstd_autonomous +#pragma weak plat_scmi_rstd_set_state + +size_t plat_scmi_rstd_count(unsigned int agent_id __unused) +{ + return 0U; +} + +const char *plat_scmi_rstd_get_name(unsigned int agent_id __unused, + unsigned int scmi_id __unused) +{ + return NULL; +} + +int32_t plat_scmi_rstd_autonomous(unsigned int agent_id __unused, + unsigned int scmi_id __unused, + unsigned int state __unused) +{ + return SCMI_NOT_SUPPORTED; +} + +int32_t plat_scmi_rstd_set_state(unsigned int agent_id __unused, + unsigned int scmi_id __unused, + bool assert_not_deassert __unused) +{ + return SCMI_NOT_SUPPORTED; +} + +static void report_version(struct scmi_msg *msg) +{ + struct scmi_protocol_version_p2a return_values = { + .status = SCMI_SUCCESS, + .version = SCMI_PROTOCOL_VERSION_RESET_DOMAIN, + }; + + if (msg->in_size != 0U) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void report_attributes(struct scmi_msg *msg) +{ + struct scmi_protocol_attributes_p2a return_values = { + .status = SCMI_SUCCESS, + .attributes = plat_scmi_rstd_count(msg->agent_id), + }; + + if (msg->in_size != 0U) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void report_message_attributes(struct scmi_msg *msg) +{ + struct scmi_protocol_message_attributes_a2p *in_args = (void *)msg->in; + struct scmi_protocol_message_attributes_p2a return_values = { + .status = SCMI_SUCCESS, + /* For this protocol, attributes shall be zero */ + .attributes = 0U, + }; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + if (!message_id_is_supported(in_args->message_id)) { + scmi_status_response(msg, SCMI_NOT_FOUND); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void reset_domain_attributes(struct scmi_msg *msg) +{ + struct scmi_reset_domain_attributes_a2p *in_args = (void *)msg->in; + struct scmi_reset_domain_attributes_p2a return_values; + const char *name = NULL; + unsigned int domain_id = 0U; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + domain_id = SPECULATION_SAFE_VALUE(in_args->domain_id); + + if (domain_id >= plat_scmi_rstd_count(msg->agent_id)) { + scmi_status_response(msg, SCMI_INVALID_PARAMETERS); + return; + } + + name = plat_scmi_rstd_get_name(msg->agent_id, domain_id); + if (name == NULL) { + scmi_status_response(msg, SCMI_NOT_FOUND); + return; + } + + zeromem(&return_values, sizeof(return_values)); + COPY_NAME_IDENTIFIER(return_values.name, name); + return_values.status = SCMI_SUCCESS; + return_values.flags = 0U; /* Async and Notif are not supported */ + return_values.latency = SCMI_RESET_DOMAIN_ATTR_UNK_LAT; + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void reset_request(struct scmi_msg *msg) +{ + struct scmi_reset_domain_request_a2p *in_args = (void *)msg->in; + struct scmi_reset_domain_request_p2a out_args = { + .status = SCMI_SUCCESS, + }; + unsigned int domain_id = 0U; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + domain_id = SPECULATION_SAFE_VALUE(in_args->domain_id); + + if (domain_id >= plat_scmi_rstd_count(msg->agent_id)) { + scmi_status_response(msg, SCMI_NOT_FOUND); + return; + } + + if ((in_args->flags & SCMI_RESET_DOMAIN_AUTO) != 0U) { + out_args.status = plat_scmi_rstd_autonomous(msg->agent_id, + domain_id, + in_args->reset_state); + } else if ((in_args->flags & SCMI_RESET_DOMAIN_EXPLICIT) != 0U) { + out_args.status = plat_scmi_rstd_set_state(msg->agent_id, + domain_id, true); + } else { + out_args.status = plat_scmi_rstd_set_state(msg->agent_id, + domain_id, false); + } + + if (out_args.status != SCMI_SUCCESS) { + scmi_status_response(msg, out_args.status); + } else { + scmi_write_response(msg, &out_args, sizeof(out_args)); + } +} + +static const scmi_msg_handler_t scmi_rstd_handler_table[] = { + [SCMI_PROTOCOL_VERSION] = report_version, + [SCMI_PROTOCOL_ATTRIBUTES] = report_attributes, + [SCMI_PROTOCOL_MESSAGE_ATTRIBUTES] = report_message_attributes, + [SCMI_RESET_DOMAIN_ATTRIBUTES] = reset_domain_attributes, + [SCMI_RESET_DOMAIN_REQUEST] = reset_request, +}; + +static bool message_id_is_supported(unsigned int message_id) +{ + return (message_id < ARRAY_SIZE(scmi_rstd_handler_table)) && + (scmi_rstd_handler_table[message_id] != NULL); +} + +scmi_msg_handler_t scmi_msg_get_rstd_handler(struct scmi_msg *msg) +{ + unsigned int message_id = SPECULATION_SAFE_VALUE(msg->message_id); + + if (message_id >= ARRAY_SIZE(scmi_rstd_handler_table)) { + VERBOSE("Reset domain handle not found %u\n", msg->message_id); + return NULL; + } + + return scmi_rstd_handler_table[message_id]; +} diff --git a/drivers/scmi-msg/reset_domain.h b/drivers/scmi-msg/reset_domain.h new file mode 100644 index 000000000..47bee5e39 --- /dev/null +++ b/drivers/scmi-msg/reset_domain.h @@ -0,0 +1,122 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019, Linaro Limited + */ +#ifndef SCMI_MSG_RESET_DOMAIN_H +#define SCMI_MSG_RESET_DOMAIN_H + +#include +#include + +#include + +#define SCMI_PROTOCOL_VERSION_RESET_DOMAIN 0x10000U + +#define SCMI_RESET_STATE_ARCH BIT(31) +#define SCMI_RESET_STATE_IMPL 0U + +/* + * Identifiers of the SCMI Reset Domain Management Protocol commands + */ +enum scmi_reset_domain_command_id { + SCMI_RESET_DOMAIN_ATTRIBUTES = 0x03, + SCMI_RESET_DOMAIN_REQUEST = 0x04, + SCMI_RESET_DOMAIN_NOTIFY = 0x05, +}; + +/* + * Identifiers of the SCMI Reset Domain Management Protocol responses + */ +enum scmi_reset_domain_response_id { + SCMI_RESET_ISSUED = 0x00, + SCMI_RESET_COMPLETE = 0x04, +}; + +/* + * PROTOCOL_ATTRIBUTES + */ + +#define SCMI_RESET_DOMAIN_COUNT_MASK GENMASK_32(15, 0) + +struct scmi_reset_domain_protocol_attributes_p2a { + int32_t status; + uint32_t attributes; +}; + +/* Value for scmi_reset_domain_attributes_p2a:flags */ +#define SCMI_RESET_DOMAIN_ATTR_ASYNC BIT(31) +#define SCMI_RESET_DOMAIN_ATTR_NOTIF BIT(30) + +/* Value for scmi_reset_domain_attributes_p2a:latency */ +#define SCMI_RESET_DOMAIN_ATTR_UNK_LAT 0x7fffffffU +#define SCMI_RESET_DOMAIN_ATTR_MAX_LAT 0x7ffffffeU + +/* Macro for scmi_reset_domain_attributes_p2a:name */ +#define SCMI_RESET_DOMAIN_ATTR_NAME_SZ 16U + +struct scmi_reset_domain_attributes_a2p { + uint32_t domain_id; +}; + +struct scmi_reset_domain_attributes_p2a { + int32_t status; + uint32_t flags; + uint32_t latency; + char name[SCMI_RESET_DOMAIN_ATTR_NAME_SZ]; +}; + +/* + * RESET + */ + +/* Values for scmi_reset_domain_request_a2p:flags */ +#define SCMI_RESET_DOMAIN_ASYNC BIT(2) +#define SCMI_RESET_DOMAIN_EXPLICIT BIT(1) +#define SCMI_RESET_DOMAIN_AUTO BIT(0) + +struct scmi_reset_domain_request_a2p { + uint32_t domain_id; + uint32_t flags; + uint32_t reset_state; +}; + +struct scmi_reset_domain_request_p2a { + int32_t status; +}; + +/* + * RESET_NOTIFY + */ + +/* Values for scmi_reset_notify_p2a:flags */ +#define SCMI_RESET_DOMAIN_DO_NOTIFY BIT(0) + +struct scmi_reset_domain_notify_a2p { + uint32_t domain_id; + uint32_t notify_enable; +}; + +struct scmi_reset_domain_notify_p2a { + int32_t status; +}; + +/* + * RESET_COMPLETE + */ + +struct scmi_reset_domain_complete_p2a { + int32_t status; + uint32_t domain_id; +}; + +/* + * RESET_ISSUED + */ + +struct scmi_reset_domain_issued_p2a { + uint32_t domain_id; + uint32_t reset_state; +}; + +#endif /* SCMI_MSG_RESET_DOMAIN_H */ diff --git a/drivers/scmi-msg/smt.c b/drivers/scmi-msg/smt.c new file mode 100644 index 000000000..b08ee0626 --- /dev/null +++ b/drivers/scmi-msg/smt.c @@ -0,0 +1,206 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Linaro Limited + */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" + +/* Legacy SMT/SCMI messages are 128 bytes at most including SMT header */ +#define SCMI_PLAYLOAD_MAX 92U +#define SCMI_PLAYLOAD_U32_MAX (SCMI_PLAYLOAD_MAX / sizeof(uint32_t)) + +/** + * struct smt_header - SMT formatted header for SMT base shared memory transfer + * + * @status: Bit flags, see SMT_STATUS_* + * @flags: Bit flags, see SMT_FLAG_* + * @length: Byte size of message payload (variable) + ::message_header (32bit) + * payload: SCMI message payload data + */ +struct smt_header { + uint32_t reserved0; + uint32_t status; + uint64_t reserved1; + uint32_t flags; + uint32_t length; /* message_header + payload */ + uint32_t message_header; + uint32_t payload[]; +}; + +CASSERT(SCMI_PLAYLOAD_MAX + sizeof(struct smt_header) <= SMT_BUF_SLOT_SIZE, + assert_scmi_message_max_length_fits_in_smt_buffer_slot); + +/* Flag set in smt_header::status when SMT does not contain pending message */ +#define SMT_STATUS_FREE BIT(0) +/* Flag set in smt_header::status when SMT reports an error */ +#define SMT_STATUS_ERROR BIT(1) + +/* Flag set in smt_header::flags when SMT uses interrupts */ +#define SMT_FLAG_INTR_ENABLED BIT(1) + +/* Bit fields packed in smt_header::message_header */ +#define SMT_MSG_ID_MASK GENMASK_32(7, 0) +#define SMT_HDR_MSG_ID(_hdr) ((_hdr) & SMT_MSG_ID_MASK) + +#define SMT_MSG_TYPE_MASK GENMASK_32(9, 8) +#define SMT_HDR_TYPE_ID(_hdr) (((_hdr) & SMT_MSG_TYPE_MASK) >> 8) + +#define SMT_MSG_PROT_ID_MASK GENMASK_32(17, 10) +#define SMT_HDR_PROT_ID(_hdr) (((_hdr) & SMT_MSG_PROT_ID_MASK) >> 10) + +/* + * Provision input message payload buffers for fastcall SMC context entries + * and for interrupt context execution entries. + */ +static uint32_t fast_smc_payload[PLATFORM_CORE_COUNT][SCMI_PLAYLOAD_U32_MAX]; +static uint32_t interrupt_payload[PLATFORM_CORE_COUNT][SCMI_PLAYLOAD_U32_MAX]; + +/* SMP protection on channel access */ +static struct spinlock smt_channels_lock; + +/* If channel is not busy, set busy and return true, otherwise return false */ +static bool channel_set_busy(struct scmi_msg_channel *chan) +{ + bool channel_is_busy; + + spin_lock(&smt_channels_lock); + + channel_is_busy = chan->busy; + + if (!channel_is_busy) { + chan->busy = true; + } + + spin_unlock(&smt_channels_lock); + + return !channel_is_busy; +} + +static void channel_release_busy(struct scmi_msg_channel *chan) +{ + chan->busy = false; +} + +static struct smt_header *channel_to_smt_hdr(struct scmi_msg_channel *chan) +{ + return (struct smt_header *)chan->shm_addr; +} + +/* + * Creates a SCMI message instance in secure memory and pushes it in the SCMI + * message drivers. Message structure contains SCMI protocol meta-data and + * references to input payload in secure memory and output message buffer + * in shared memory. + */ +static void scmi_proccess_smt(unsigned int agent_id, uint32_t *payload_buf) +{ + struct scmi_msg_channel *chan; + struct smt_header *smt_hdr; + size_t in_payload_size; + uint32_t smt_status; + struct scmi_msg msg; + bool error = true; + + chan = plat_scmi_get_channel(agent_id); + if (chan == NULL) { + return; + } + + smt_hdr = channel_to_smt_hdr(chan); + assert(smt_hdr); + + smt_status = __atomic_load_n(&smt_hdr->status, __ATOMIC_RELAXED); + + if (!channel_set_busy(chan)) { + VERBOSE("SCMI channel %u busy", agent_id); + goto out; + } + + in_payload_size = __atomic_load_n(&smt_hdr->length, __ATOMIC_RELAXED) - + sizeof(smt_hdr->message_header); + + if (in_payload_size > SCMI_PLAYLOAD_MAX) { + VERBOSE("SCMI payload too big %u", in_payload_size); + goto out; + } + + if ((smt_status & (SMT_STATUS_ERROR | SMT_STATUS_FREE)) != 0U) { + VERBOSE("SCMI channel bad status 0x%x", + smt_hdr->status & (SMT_STATUS_ERROR | SMT_STATUS_FREE)); + goto out; + } + + /* Fill message */ + zeromem(&msg, sizeof(msg)); + msg.in = (char *)payload_buf; + msg.in_size = in_payload_size; + msg.out = (char *)smt_hdr->payload; + msg.out_size = chan->shm_size - sizeof(*smt_hdr); + + assert((msg.out != NULL) && (msg.out_size >= sizeof(int32_t))); + + /* Here the payload is copied in secure memory */ + memcpy(msg.in, smt_hdr->payload, in_payload_size); + + msg.protocol_id = SMT_HDR_PROT_ID(smt_hdr->message_header); + msg.message_id = SMT_HDR_MSG_ID(smt_hdr->message_header); + msg.agent_id = agent_id; + + scmi_process_message(&msg); + + /* Update message length with the length of the response message */ + smt_hdr->length = msg.out_size_out + sizeof(smt_hdr->message_header); + + channel_release_busy(chan); + error = false; + +out: + if (error) { + VERBOSE("SCMI error"); + smt_hdr->status |= SMT_STATUS_ERROR | SMT_STATUS_FREE; + } else { + smt_hdr->status |= SMT_STATUS_FREE; + } +} + +void scmi_smt_fastcall_smc_entry(unsigned int agent_id) +{ + scmi_proccess_smt(agent_id, + fast_smc_payload[plat_my_core_pos()]); +} + +void scmi_smt_interrupt_entry(unsigned int agent_id) +{ + scmi_proccess_smt(agent_id, + interrupt_payload[plat_my_core_pos()]); +} + +/* Init a SMT header for a shared memory buffer: state it a free/no-error */ +void scmi_smt_init_agent_channel(struct scmi_msg_channel *chan) +{ + if (chan != NULL) { + struct smt_header *smt_header = channel_to_smt_hdr(chan); + + if (smt_header != NULL) { + memset(smt_header, 0, sizeof(*smt_header)); + smt_header->status = SMT_STATUS_FREE; + + return; + } + } + + panic(); +} diff --git a/drivers/st/scmi-msg/base.c b/drivers/st/scmi-msg/base.c deleted file mode 100644 index e44bc529d..000000000 --- a/drivers/st/scmi-msg/base.c +++ /dev/null @@ -1,198 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -/* - * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. - * Copyright (c) 2019-2020, Linaro Limited - */ -#include -#include - -#include -#include -#include -#include - -#include "common.h" - -static bool message_id_is_supported(unsigned int message_id); - -static void report_version(struct scmi_msg *msg) -{ - struct scmi_protocol_version_p2a return_values = { - .status = SCMI_SUCCESS, - .version = SCMI_PROTOCOL_VERSION_BASE, - }; - - if (msg->in_size != 0U) { - scmi_status_response(msg, SCMI_PROTOCOL_ERROR); - return; - } - - scmi_write_response(msg, &return_values, sizeof(return_values)); -} - -static void report_attributes(struct scmi_msg *msg) -{ - size_t protocol_count = plat_scmi_protocol_count(); - struct scmi_protocol_attributes_p2a return_values = { - .status = SCMI_SUCCESS, - /* Null agent count since agent discovery is not supported */ - .attributes = SCMI_BASE_PROTOCOL_ATTRIBUTES(protocol_count, 0U), - }; - - if (msg->in_size != 0U) { - scmi_status_response(msg, SCMI_PROTOCOL_ERROR); - return; - } - - scmi_write_response(msg, &return_values, sizeof(return_values)); -} - -static void report_message_attributes(struct scmi_msg *msg) -{ - struct scmi_protocol_message_attributes_a2p *in_args = (void *)msg->in; - struct scmi_protocol_message_attributes_p2a return_values = { - .status = SCMI_SUCCESS, - /* For this protocol, attributes shall be zero */ - .attributes = 0U, - }; - - if (msg->in_size != sizeof(*in_args)) { - scmi_status_response(msg, SCMI_PROTOCOL_ERROR); - return; - } - - if (!message_id_is_supported(in_args->message_id)) { - scmi_status_response(msg, SCMI_NOT_FOUND); - return; - } - - scmi_write_response(msg, &return_values, sizeof(return_values)); -} - -static void discover_vendor(struct scmi_msg *msg) -{ - const char *name = plat_scmi_vendor_name(); - struct scmi_base_discover_vendor_p2a return_values = { - .status = SCMI_SUCCESS, - }; - - if (msg->in_size != 0U) { - scmi_status_response(msg, SCMI_PROTOCOL_ERROR); - return; - } - - COPY_NAME_IDENTIFIER(return_values.vendor_identifier, name); - - scmi_write_response(msg, &return_values, sizeof(return_values)); -} - -static void discover_sub_vendor(struct scmi_msg *msg) -{ - const char *name = plat_scmi_sub_vendor_name(); - struct scmi_base_discover_sub_vendor_p2a return_values = { - .status = SCMI_SUCCESS, - }; - - if (msg->in_size != 0U) { - scmi_status_response(msg, SCMI_PROTOCOL_ERROR); - return; - } - - COPY_NAME_IDENTIFIER(return_values.sub_vendor_identifier, name); - - scmi_write_response(msg, &return_values, sizeof(return_values)); -} - -static void discover_implementation_version(struct scmi_msg *msg) -{ - struct scmi_protocol_version_p2a return_values = { - .status = SCMI_SUCCESS, - .version = SCMI_IMPL_VERSION, - }; - - if (msg->in_size != 0U) { - scmi_status_response(msg, SCMI_PROTOCOL_ERROR); - return; - } - - scmi_write_response(msg, &return_values, sizeof(return_values)); -} - -static unsigned int count_protocols_in_list(const uint8_t *protocol_list) -{ - unsigned int count = 0U; - - if (protocol_list != NULL) { - while (protocol_list[count] != 0U) { - count++; - } - } - - return count; -} - -#define MAX_PROTOCOL_IN_LIST 8U - -static void discover_list_protocols(struct scmi_msg *msg) -{ - const struct scmi_base_discover_list_protocols_a2p *a2p = NULL; - struct scmi_base_discover_list_protocols_p2a p2a = { - .status = SCMI_SUCCESS, - }; - uint8_t outargs[sizeof(p2a) + MAX_PROTOCOL_IN_LIST] = { 0U }; - const uint8_t *list = NULL; - unsigned int count = 0U; - - if (msg->in_size != sizeof(*a2p)) { - scmi_status_response(msg, SCMI_PROTOCOL_ERROR); - return; - } - - assert(msg->out_size > sizeof(outargs)); - - a2p = (void *)msg->in; - - list = plat_scmi_protocol_list(msg->agent_id); - count = count_protocols_in_list(list); - if (count > a2p->skip) { - count = MIN(count - a2p->skip, MAX_PROTOCOL_IN_LIST); - } else { - count = 0U; - } - - p2a.num_protocols = count; - - memcpy(outargs, &p2a, sizeof(p2a)); - memcpy(outargs + sizeof(p2a), list + a2p->skip, count); - - scmi_write_response(msg, outargs, sizeof(outargs)); -} - -static const scmi_msg_handler_t scmi_base_handler_table[] = { - [SCMI_PROTOCOL_VERSION] = report_version, - [SCMI_PROTOCOL_ATTRIBUTES] = report_attributes, - [SCMI_PROTOCOL_MESSAGE_ATTRIBUTES] = report_message_attributes, - [SCMI_BASE_DISCOVER_VENDOR] = discover_vendor, - [SCMI_BASE_DISCOVER_SUB_VENDOR] = discover_sub_vendor, - [SCMI_BASE_DISCOVER_IMPLEMENTATION_VERSION] = - discover_implementation_version, - [SCMI_BASE_DISCOVER_LIST_PROTOCOLS] = discover_list_protocols, -}; - -static bool message_id_is_supported(unsigned int message_id) -{ - return (message_id < ARRAY_SIZE(scmi_base_handler_table)) && - (scmi_base_handler_table[message_id] != NULL); -} - -scmi_msg_handler_t scmi_msg_get_base_handler(struct scmi_msg *msg) -{ - unsigned int message_id = SPECULATION_SAFE_VALUE(msg->message_id); - - if (message_id >= ARRAY_SIZE(scmi_base_handler_table)) { - VERBOSE("Base handle not found %u\n", msg->message_id); - return NULL; - } - - return scmi_base_handler_table[message_id]; -} diff --git a/drivers/st/scmi-msg/base.h b/drivers/st/scmi-msg/base.h deleted file mode 100644 index c4a9c64a4..000000000 --- a/drivers/st/scmi-msg/base.h +++ /dev/null @@ -1,75 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. - * Copyright (c) 2019-2020, Linaro Limited - */ - -#ifndef SCMI_MSG_BASE_H -#define SCMI_MSG_BASE_H - -#include - -#define SCMI_PROTOCOL_VERSION_BASE 0x20000U - -#define SCMI_DEFAULT_STRING_LENGTH 16U - -enum scmi_base_message_id { - SCMI_BASE_DISCOVER_VENDOR = 0x003, - SCMI_BASE_DISCOVER_SUB_VENDOR = 0x004, - SCMI_BASE_DISCOVER_IMPLEMENTATION_VERSION = 0x005, - SCMI_BASE_DISCOVER_LIST_PROTOCOLS = 0x006, - SCMI_BASE_DISCOVER_AGENT = 0x007, - SCMI_BASE_NOTIFY_ERRORS = 0x008, -}; - -/* - * PROTOCOL_ATTRIBUTES - */ - -#define SCMI_BASE_PROTOCOL_ATTRS_NUM_PROTOCOLS_POS 0 -#define SCMI_BASE_PROTOCOL_ATTRS_NUM_AGENTS_POS 8 - -#define SCMI_BASE_PROTOCOL_ATTRS_NUM_PROTOCOLS_MASK 0xFFU -#define SCMI_BASE_PROTOCOL_ATTRS_NUM_AGENTS_MASK 0xFF00U - -#define SCMI_BASE_PROTOCOL_ATTRIBUTES(NUM_PROTOCOLS, NUM_AGENTS) \ - ((((NUM_PROTOCOLS) << SCMI_BASE_PROTOCOL_ATTRS_NUM_PROTOCOLS_POS) & \ - SCMI_BASE_PROTOCOL_ATTRS_NUM_PROTOCOLS_MASK) | \ - (((NUM_AGENTS) << SCMI_BASE_PROTOCOL_ATTRS_NUM_AGENTS_POS) & \ - SCMI_BASE_PROTOCOL_ATTRS_NUM_AGENTS_MASK)) - -/* - * BASE_DISCOVER_VENDOR - */ -struct scmi_base_discover_vendor_p2a { - int32_t status; - char vendor_identifier[SCMI_DEFAULT_STRING_LENGTH]; -}; - -/* - * BASE_DISCOVER_SUB_VENDOR - */ -struct scmi_base_discover_sub_vendor_p2a { - int32_t status; - char sub_vendor_identifier[SCMI_DEFAULT_STRING_LENGTH]; -}; - -/* - * BASE_DISCOVER_IMPLEMENTATION_VERSION - * No special structure right now, see protocol_version. - */ - -/* - * BASE_DISCOVER_LIST_PROTOCOLS - */ -struct scmi_base_discover_list_protocols_a2p { - uint32_t skip; -}; - -struct scmi_base_discover_list_protocols_p2a { - int32_t status; - uint32_t num_protocols; - uint32_t protocols[]; -}; - -#endif /* SCMI_MSG_BASE_H */ diff --git a/drivers/st/scmi-msg/clock.c b/drivers/st/scmi-msg/clock.c deleted file mode 100644 index 319557cd0..000000000 --- a/drivers/st/scmi-msg/clock.c +++ /dev/null @@ -1,381 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -/* - * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved. - * Copyright (c) 2019-2020, Linaro Limited - */ -#include -#include - -#include -#include -#include - -#include "common.h" - -#pragma weak plat_scmi_clock_count -#pragma weak plat_scmi_clock_get_name -#pragma weak plat_scmi_clock_rates_array -#pragma weak plat_scmi_clock_rates_by_step -#pragma weak plat_scmi_clock_get_rate -#pragma weak plat_scmi_clock_set_rate -#pragma weak plat_scmi_clock_get_state -#pragma weak plat_scmi_clock_set_state - -static bool message_id_is_supported(unsigned int message_id); - -size_t plat_scmi_clock_count(unsigned int agent_id __unused) -{ - return 0U; -} - -const char *plat_scmi_clock_get_name(unsigned int agent_id __unused, - unsigned int scmi_id __unused) -{ - return NULL; -} - -int32_t plat_scmi_clock_rates_array(unsigned int agent_id __unused, - unsigned int scmi_id __unused, - unsigned long *rates __unused, - size_t *nb_elts __unused) -{ - return SCMI_NOT_SUPPORTED; -} - -int32_t plat_scmi_clock_rates_by_step(unsigned int agent_id __unused, - unsigned int scmi_id __unused, - unsigned long *steps __unused) -{ - return SCMI_NOT_SUPPORTED; -} - -unsigned long plat_scmi_clock_get_rate(unsigned int agent_id __unused, - unsigned int scmi_id __unused) -{ - return 0U; -} - -int32_t plat_scmi_clock_set_rate(unsigned int agent_id __unused, - unsigned int scmi_id __unused, - unsigned long rate __unused) -{ - return SCMI_NOT_SUPPORTED; -} - -int32_t plat_scmi_clock_get_state(unsigned int agent_id __unused, - unsigned int scmi_id __unused) -{ - return SCMI_NOT_SUPPORTED; -} - -int32_t plat_scmi_clock_set_state(unsigned int agent_id __unused, - unsigned int scmi_id __unused, - bool enable_not_disable __unused) -{ - return SCMI_NOT_SUPPORTED; -} - -static void report_version(struct scmi_msg *msg) -{ - struct scmi_protocol_version_p2a return_values = { - .status = SCMI_SUCCESS, - .version = SCMI_PROTOCOL_VERSION_CLOCK, - }; - - if (msg->in_size != 0) { - scmi_status_response(msg, SCMI_PROTOCOL_ERROR); - return; - } - - scmi_write_response(msg, &return_values, sizeof(return_values)); -} - -static void report_attributes(struct scmi_msg *msg) -{ - size_t agent_count = plat_scmi_clock_count(msg->agent_id); - struct scmi_protocol_attributes_p2a return_values = { - .status = SCMI_SUCCESS, - .attributes = SCMI_CLOCK_PROTOCOL_ATTRIBUTES(1U, agent_count), - }; - - if (msg->in_size != 0) { - scmi_status_response(msg, SCMI_PROTOCOL_ERROR); - return; - } - - scmi_write_response(msg, &return_values, sizeof(return_values)); -} - -static void report_message_attributes(struct scmi_msg *msg) -{ - struct scmi_protocol_message_attributes_a2p *in_args = (void *)msg->in; - struct scmi_protocol_message_attributes_p2a return_values = { - .status = SCMI_SUCCESS, - /* For this protocol, attributes shall be zero */ - .attributes = 0U, - }; - - if (msg->in_size != sizeof(*in_args)) { - scmi_status_response(msg, SCMI_PROTOCOL_ERROR); - return; - } - - if (!message_id_is_supported(in_args->message_id)) { - scmi_status_response(msg, SCMI_NOT_FOUND); - return; - } - - scmi_write_response(msg, &return_values, sizeof(return_values)); -} - -static void scmi_clock_attributes(struct scmi_msg *msg) -{ - const struct scmi_clock_attributes_a2p *in_args = (void *)msg->in; - struct scmi_clock_attributes_p2a return_values = { - .status = SCMI_SUCCESS, - }; - const char *name = NULL; - unsigned int clock_id = 0U; - - if (msg->in_size != sizeof(*in_args)) { - scmi_status_response(msg, SCMI_PROTOCOL_ERROR); - return; - } - - clock_id = SPECULATION_SAFE_VALUE(in_args->clock_id); - - if (clock_id >= plat_scmi_clock_count(msg->agent_id)) { - scmi_status_response(msg, SCMI_INVALID_PARAMETERS); - return; - } - - - name = plat_scmi_clock_get_name(msg->agent_id, clock_id); - if (name == NULL) { - scmi_status_response(msg, SCMI_NOT_FOUND); - return; - } - - COPY_NAME_IDENTIFIER(return_values.clock_name, name); - - return_values.attributes = plat_scmi_clock_get_state(msg->agent_id, - clock_id); - - scmi_write_response(msg, &return_values, sizeof(return_values)); -} - -static void scmi_clock_rate_get(struct scmi_msg *msg) -{ - const struct scmi_clock_rate_get_a2p *in_args = (void *)msg->in; - unsigned long rate = 0U; - struct scmi_clock_rate_get_p2a return_values = { - .status = SCMI_SUCCESS, - }; - unsigned int clock_id = 0U; - - if (msg->in_size != sizeof(*in_args)) { - scmi_status_response(msg, SCMI_PROTOCOL_ERROR); - return; - } - - clock_id = SPECULATION_SAFE_VALUE(in_args->clock_id); - - if (clock_id >= plat_scmi_clock_count(msg->agent_id)) { - scmi_status_response(msg, SCMI_INVALID_PARAMETERS); - return; - } - - rate = plat_scmi_clock_get_rate(msg->agent_id, clock_id); - - return_values.rate[0] = (uint32_t)rate; - return_values.rate[1] = (uint32_t)((uint64_t)rate >> 32); - - scmi_write_response(msg, &return_values, sizeof(return_values)); -} - -static void scmi_clock_rate_set(struct scmi_msg *msg) -{ - const struct scmi_clock_rate_set_a2p *in_args = (void *)msg->in; - unsigned long rate = 0U; - int32_t status = 0; - unsigned int clock_id = 0U; - - if (msg->in_size != sizeof(*in_args)) { - scmi_status_response(msg, SCMI_PROTOCOL_ERROR); - return; - } - - clock_id = SPECULATION_SAFE_VALUE(in_args->clock_id); - - if (clock_id >= plat_scmi_clock_count(msg->agent_id)) { - scmi_status_response(msg, SCMI_INVALID_PARAMETERS); - return; - } - - rate = (unsigned long)(((uint64_t)in_args->rate[1] << 32) | - in_args->rate[0]); - - status = plat_scmi_clock_set_rate(msg->agent_id, clock_id, rate); - - scmi_status_response(msg, status); -} - -static void scmi_clock_config_set(struct scmi_msg *msg) -{ - const struct scmi_clock_config_set_a2p *in_args = (void *)msg->in; - int32_t status = SCMI_GENERIC_ERROR; - bool enable = false; - unsigned int clock_id = 0U; - - if (msg->in_size != sizeof(*in_args)) { - scmi_status_response(msg, SCMI_PROTOCOL_ERROR); - return; - } - - clock_id = SPECULATION_SAFE_VALUE(in_args->clock_id); - - if (clock_id >= plat_scmi_clock_count(msg->agent_id)) { - scmi_status_response(msg, SCMI_INVALID_PARAMETERS); - return; - } - - enable = in_args->attributes & SCMI_CLOCK_CONFIG_SET_ENABLE_MASK; - - status = plat_scmi_clock_set_state(msg->agent_id, clock_id, enable); - - scmi_status_response(msg, status); -} - -#define RATES_ARRAY_SIZE_MAX (SCMI_PLAYLOAD_MAX - \ - sizeof(struct scmi_clock_describe_rates_p2a)) - -#define SCMI_RATES_BY_ARRAY(_nb_rates, _rem_rates) \ - SCMI_CLOCK_DESCRIBE_RATES_NUM_RATES_FLAGS((_nb_rates), \ - SCMI_CLOCK_RATE_FORMAT_LIST, \ - (_rem_rates)) -#define SCMI_RATES_BY_STEP \ - SCMI_CLOCK_DESCRIBE_RATES_NUM_RATES_FLAGS(3U, \ - SCMI_CLOCK_RATE_FORMAT_RANGE, \ - 0U) - -#define RATE_DESC_SIZE sizeof(struct scmi_clock_rate) - -static void write_rate_desc_array_in_buffer(char *dest, unsigned long *rates, - size_t nb_elt) -{ - uint32_t *out = (uint32_t *)(uintptr_t)dest; - size_t n; - - ASSERT_SYM_PTR_ALIGN(out); - - for (n = 0U; n < nb_elt; n++) { - out[2 * n] = (uint32_t)rates[n]; - out[2 * n + 1] = (uint32_t)((uint64_t)rates[n] >> 32); - } -} - -static void scmi_clock_describe_rates(struct scmi_msg *msg) -{ - const struct scmi_clock_describe_rates_a2p *in_args = (void *)msg->in; - struct scmi_clock_describe_rates_p2a p2a = { - .status = SCMI_SUCCESS, - }; - size_t nb_rates; - int32_t status; - unsigned int clock_id; - - if (msg->in_size != sizeof(*in_args)) { - scmi_status_response(msg, SCMI_PROTOCOL_ERROR); - return; - } - - clock_id = SPECULATION_SAFE_VALUE(in_args->clock_id); - - if (clock_id >= plat_scmi_clock_count(msg->agent_id)) { - scmi_status_response(msg, SCMI_INVALID_PARAMETERS); - return; - } - - /* Platform may support array rate description */ - status = plat_scmi_clock_rates_array(msg->agent_id, clock_id, NULL, - &nb_rates); - if (status == SCMI_SUCCESS) { - /* Currently 12 cells mex, so it's affordable for the stack */ - unsigned long plat_rates[RATES_ARRAY_SIZE_MAX / RATE_DESC_SIZE]; - size_t max_nb = RATES_ARRAY_SIZE_MAX / RATE_DESC_SIZE; - size_t ret_nb = MIN(nb_rates - in_args->rate_index, max_nb); - size_t rem_nb = nb_rates - in_args->rate_index - ret_nb; - - status = plat_scmi_clock_rates_array(msg->agent_id, clock_id, - plat_rates, &ret_nb); - if (status == SCMI_SUCCESS) { - write_rate_desc_array_in_buffer(msg->out + sizeof(p2a), - plat_rates, ret_nb); - - p2a.num_rates_flags = SCMI_RATES_BY_ARRAY(ret_nb, - rem_nb); - p2a.status = SCMI_SUCCESS; - - memcpy(msg->out, &p2a, sizeof(p2a)); - msg->out_size_out = sizeof(p2a) + - ret_nb * RATE_DESC_SIZE; - } - } else if (status == SCMI_NOT_SUPPORTED) { - unsigned long triplet[3] = { 0U, 0U, 0U }; - - /* Platform may support min§max/step triplet description */ - status = plat_scmi_clock_rates_by_step(msg->agent_id, clock_id, - triplet); - if (status == SCMI_SUCCESS) { - write_rate_desc_array_in_buffer(msg->out + sizeof(p2a), - triplet, 3U); - - p2a.num_rates_flags = SCMI_RATES_BY_STEP; - p2a.status = SCMI_SUCCESS; - - memcpy(msg->out, &p2a, sizeof(p2a)); - msg->out_size_out = sizeof(p2a) + (3U * RATE_DESC_SIZE); - } - } else { - /* Fallthrough generic exit sequence below with error status */ - } - - if (status != SCMI_SUCCESS) { - scmi_status_response(msg, status); - } else { - /* - * Message payload is already writen to msg->out, and - * msg->out_size_out updated. - */ - } -} - -static const scmi_msg_handler_t scmi_clock_handler_table[] = { - [SCMI_PROTOCOL_VERSION] = report_version, - [SCMI_PROTOCOL_ATTRIBUTES] = report_attributes, - [SCMI_PROTOCOL_MESSAGE_ATTRIBUTES] = report_message_attributes, - [SCMI_CLOCK_ATTRIBUTES] = scmi_clock_attributes, - [SCMI_CLOCK_DESCRIBE_RATES] = scmi_clock_describe_rates, - [SCMI_CLOCK_RATE_SET] = scmi_clock_rate_set, - [SCMI_CLOCK_RATE_GET] = scmi_clock_rate_get, - [SCMI_CLOCK_CONFIG_SET] = scmi_clock_config_set, -}; - -static bool message_id_is_supported(size_t message_id) -{ - return (message_id < ARRAY_SIZE(scmi_clock_handler_table)) && - (scmi_clock_handler_table[message_id] != NULL); -} - -scmi_msg_handler_t scmi_msg_get_clock_handler(struct scmi_msg *msg) -{ - const size_t array_size = ARRAY_SIZE(scmi_clock_handler_table); - unsigned int message_id = SPECULATION_SAFE_VALUE(msg->message_id); - - if (message_id >= array_size) { - VERBOSE("Clock handle not found %u", msg->message_id); - return NULL; - } - - return scmi_clock_handler_table[message_id]; -} diff --git a/drivers/st/scmi-msg/clock.h b/drivers/st/scmi-msg/clock.h deleted file mode 100644 index a637934ee..000000000 --- a/drivers/st/scmi-msg/clock.h +++ /dev/null @@ -1,150 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. - * Copyright (c) 2019, Linaro Limited - */ - -#ifndef SCMI_MSG_CLOCK_H -#define SCMI_MSG_CLOCK_H - -#include - -#include - -#define SCMI_PROTOCOL_VERSION_CLOCK 0x20000U - -/* - * Identifiers of the SCMI Clock Management Protocol commands - */ -enum scmi_clock_command_id { - SCMI_CLOCK_ATTRIBUTES = 0x003, - SCMI_CLOCK_DESCRIBE_RATES = 0x004, - SCMI_CLOCK_RATE_SET = 0x005, - SCMI_CLOCK_RATE_GET = 0x006, - SCMI_CLOCK_CONFIG_SET = 0x007, -}; - -/* Protocol attributes */ -#define SCMI_CLOCK_CLOCK_COUNT_MASK GENMASK(15, 0) -#define SCMI_CLOCK_MAX_PENDING_TRANSITIONS_MASK GENMASK(23, 16) - -#define SCMI_CLOCK_PROTOCOL_ATTRIBUTES(_max_pending, _clk_count) \ - ((((_max_pending) << 16) & SCMI_CLOCK_MAX_PENDING_TRANSITIONS_MASK) | \ - (((_clk_count) & SCMI_CLOCK_CLOCK_COUNT_MASK))) - -struct scmi_clock_attributes_a2p { - uint32_t clock_id; -}; - -#define SCMI_CLOCK_NAME_LENGTH_MAX 16U - -struct scmi_clock_attributes_p2a { - int32_t status; - uint32_t attributes; - char clock_name[SCMI_CLOCK_NAME_LENGTH_MAX]; -}; - -/* - * Clock Rate Get - */ - -struct scmi_clock_rate_get_a2p { - uint32_t clock_id; -}; - -struct scmi_clock_rate_get_p2a { - int32_t status; - uint32_t rate[2]; -}; - -/* - * Clock Rate Set - */ - -/* If set, set the new clock rate asynchronously */ -#define SCMI_CLOCK_RATE_SET_ASYNC_POS 0 -/* If set, do not send a delayed asynchronous response */ -#define SCMI_CLOCK_RATE_SET_NO_DELAYED_RESPONSE_POS 1 -/* Round up, if set, otherwise round down */ -#define SCMI_CLOCK_RATE_SET_ROUND_UP_POS 2 -/* If set, the platform chooses the appropriate rounding mode */ -#define SCMI_CLOCK_RATE_SET_ROUND_AUTO_POS 3 - -#define SCMI_CLOCK_RATE_SET_ASYNC_MASK \ - BIT(SCMI_CLOCK_RATE_SET_ASYNC_POS) -#define SCMI_CLOCK_RATE_SET_NO_DELAYED_RESPONSE_MASK \ - BIT(SCMI_CLOCK_RATE_SET_NO_DELAYED_RESPONSE_POS) -#define SCMI_CLOCK_RATE_SET_ROUND_UP_MASK \ - BIT(SCMI_CLOCK_RATE_SET_ROUND_UP_POS) -#define SCMI_CLOCK_RATE_SET_ROUND_AUTO_MASK \ - BIT(SCMI_CLOCK_RATE_SET_ROUND_AUTO_POS) - -struct scmi_clock_rate_set_a2p { - uint32_t flags; - uint32_t clock_id; - uint32_t rate[2]; -}; - -struct scmi_clock_rate_set_p2a { - int32_t status; -}; - -/* - * Clock Config Set - */ - -#define SCMI_CLOCK_CONFIG_SET_ENABLE_POS 0 - -#define SCMI_CLOCK_CONFIG_SET_ENABLE_MASK \ - BIT(SCMI_CLOCK_CONFIG_SET_ENABLE_POS) - -struct scmi_clock_config_set_a2p { - uint32_t clock_id; - uint32_t attributes; -}; - -struct scmi_clock_config_set_p2a { - int32_t status; -}; - -/* - * Clock Describe Rates - */ - -#define SCMI_CLOCK_RATE_FORMAT_RANGE 1U -#define SCMI_CLOCK_RATE_FORMAT_LIST 0U - -#define SCMI_CLOCK_DESCRIBE_RATES_REMAINING_MASK GENMASK_32(31, 16) -#define SCMI_CLOCK_DESCRIBE_RATES_REMAINING_POS 16 - -#define SCMI_CLOCK_DESCRIBE_RATES_FORMAT_MASK BIT(12) -#define SCMI_CLOCK_DESCRIBE_RATES_FORMAT_POS 12 - -#define SCMI_CLOCK_DESCRIBE_RATES_COUNT_MASK GENMASK_32(11, 0) - -#define SCMI_CLOCK_DESCRIBE_RATES_NUM_RATES_FLAGS(_count, _fmt, _rem_rates) \ - ( \ - ((_count) & SCMI_CLOCK_DESCRIBE_RATES_COUNT_MASK) | \ - (((_rem_rates) << SCMI_CLOCK_DESCRIBE_RATES_REMAINING_POS) & \ - SCMI_CLOCK_DESCRIBE_RATES_REMAINING_MASK) | \ - (((_fmt) << SCMI_CLOCK_DESCRIBE_RATES_FORMAT_POS) & \ - SCMI_CLOCK_DESCRIBE_RATES_FORMAT_MASK) \ - ) - -struct scmi_clock_rate { - uint32_t low; - uint32_t high; -}; - -struct scmi_clock_describe_rates_a2p { - uint32_t clock_id; - uint32_t rate_index; -}; - -struct scmi_clock_describe_rates_p2a { - int32_t status; - uint32_t num_rates_flags; - struct scmi_clock_rate rates[]; -}; - -#endif /* SCMI_MSG_CLOCK_H */ diff --git a/drivers/st/scmi-msg/common.h b/drivers/st/scmi-msg/common.h deleted file mode 100644 index ef5953b3d..000000000 --- a/drivers/st/scmi-msg/common.h +++ /dev/null @@ -1,136 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. - * Copyright (c) 2019-2020, Linaro Limited - */ -#ifndef SCMI_MSG_COMMON_H -#define SCMI_MSG_COMMON_H - -#include -#include -#include -#include - -#include "base.h" -#include "clock.h" -#include "reset_domain.h" - -#define SCMI_VERSION 0x20000U -#define SCMI_IMPL_VERSION 0U - -#define SCMI_PLAYLOAD_MAX 92U - -/* - * Copy name identifier in target buffer following the SCMI specification - * that state name identifier shall be a null terminated string. - */ -#define COPY_NAME_IDENTIFIER(_dst_array, _name) \ - do { \ - assert(strlen(_name) < sizeof(_dst_array)); \ - strlcpy((_dst_array), (_name), sizeof(_dst_array)); \ - } while (0) - -/* Common command identifiers shared by all procotols */ -enum scmi_common_message_id { - SCMI_PROTOCOL_VERSION = 0x000, - SCMI_PROTOCOL_ATTRIBUTES = 0x001, - SCMI_PROTOCOL_MESSAGE_ATTRIBUTES = 0x002 -}; - -/* Common platform-to-agent (p2a) PROTOCOL_VERSION structure */ -struct scmi_protocol_version_p2a { - int32_t status; - uint32_t version; -}; - -/* Generic platform-to-agent (p2a) PROTOCOL_ATTRIBUTES structure */ -struct scmi_protocol_attributes_p2a { - int32_t status; - uint32_t attributes; -}; - -/* Generic agent-to-platform (a2p) PROTOCOL_MESSAGE_ATTRIBUTES structure */ -struct scmi_protocol_message_attributes_a2p { - uint32_t message_id; -}; - -/* Generic platform-to-agent (p2a) PROTOCOL_MESSAGE_ATTRIBUTES structure */ -struct scmi_protocol_message_attributes_p2a { - int32_t status; - uint32_t attributes; -}; - -/* - * struct scmi_msg - SCMI message context - * - * @agent_id: SCMI agent ID, safely set from secure world - * @protocol_id: SCMI protocol ID for the related message, set by caller agent - * @message_id: SCMI message ID for the related message, set by caller agent - * @in: Address of the incoming message payload copied in secure memory - * @in_size: Byte length of the incoming message payload, set by caller agent - * @out: Address of of the output message payload message in non-secure memory - * @out_size: Byte length of the provisionned output buffer - * @out_size_out: Byte length of the output message payload - */ -struct scmi_msg { - unsigned int agent_id; - unsigned int protocol_id; - unsigned int message_id; - char *in; - size_t in_size; - char *out; - size_t out_size; - size_t out_size_out; -}; - -/* - * Type scmi_msg_handler_t is used by procotol drivers to safely find - * the handler function for the incoming message ID. - */ -typedef void (*scmi_msg_handler_t)(struct scmi_msg *msg); - -/* - * scmi_msg_get_base_handler - Return a handler for a base message - * @msg - message to process - * Return a function handler for the message or NULL - */ -scmi_msg_handler_t scmi_msg_get_base_handler(struct scmi_msg *msg); - -/* - * scmi_msg_get_clock_handler - Return a handler for a clock message - * @msg - message to process - * Return a function handler for the message or NULL - */ -scmi_msg_handler_t scmi_msg_get_clock_handler(struct scmi_msg *msg); - -/* - * scmi_msg_get_rstd_handler - Return a handler for a reset domain message - * @msg - message to process - * Return a function handler for the message or NULL - */ -scmi_msg_handler_t scmi_msg_get_rstd_handler(struct scmi_msg *msg); - -/* - * Process Read, process and write response for input SCMI message - * - * @msg: SCMI message context - */ -void scmi_process_message(struct scmi_msg *msg); - -/* - * Write SCMI response payload to output message shared memory - * - * @msg: SCMI message context - * @payload: Output message payload - * @size: Byte size of output message payload - */ -void scmi_write_response(struct scmi_msg *msg, void *payload, size_t size); - -/* - * Write status only SCMI response payload to output message shared memory - * - * @msg: SCMI message context - * @status: SCMI status value returned to caller - */ -void scmi_status_response(struct scmi_msg *msg, int32_t status); -#endif /* SCMI_MSG_COMMON_H */ diff --git a/drivers/st/scmi-msg/entry.c b/drivers/st/scmi-msg/entry.c deleted file mode 100644 index eefcb3100..000000000 --- a/drivers/st/scmi-msg/entry.c +++ /dev/null @@ -1,63 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -/* - * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved. - * Copyright (c) 2019-2020, Linaro Limited - */ - -#include - -#include -#include - -#include "common.h" - -void scmi_status_response(struct scmi_msg *msg, int32_t status) -{ - assert(msg->out && msg->out_size >= sizeof(int32_t)); - - memcpy(msg->out, &status, sizeof(int32_t)); - msg->out_size_out = sizeof(int32_t); -} - -void scmi_write_response(struct scmi_msg *msg, void *payload, size_t size) -{ - /* - * Output payload shall be at least the size of the status - * Output buffer shall be at least be the size of the status - * Output paylaod shall fit in output buffer - */ - assert(payload && size >= sizeof(int32_t) && size <= msg->out_size && - msg->out && msg->out_size >= sizeof(int32_t)); - - memcpy(msg->out, payload, size); - msg->out_size_out = size; -} - -void scmi_process_message(struct scmi_msg *msg) -{ - scmi_msg_handler_t handler = NULL; - - switch (msg->protocol_id) { - case SCMI_PROTOCOL_ID_BASE: - handler = scmi_msg_get_base_handler(msg); - break; - case SCMI_PROTOCOL_ID_CLOCK: - handler = scmi_msg_get_clock_handler(msg); - break; - case SCMI_PROTOCOL_ID_RESET_DOMAIN: - handler = scmi_msg_get_rstd_handler(msg); - break; - default: - break; - } - - if (handler) { - handler(msg); - return; - } - - ERROR("Agent %u Protocol 0x%x Message 0x%x: not supported", - msg->agent_id, msg->protocol_id, msg->message_id); - - scmi_status_response(msg, SCMI_NOT_SUPPORTED); -} diff --git a/drivers/st/scmi-msg/reset_domain.c b/drivers/st/scmi-msg/reset_domain.c deleted file mode 100644 index b4773029b..000000000 --- a/drivers/st/scmi-msg/reset_domain.c +++ /dev/null @@ -1,197 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -/* - * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved. - * Copyright (c) 2019-2020, Linaro Limited - */ -#include -#include - -#include -#include -#include -#include - -#include "common.h" - -static bool message_id_is_supported(unsigned int message_id); - -#pragma weak plat_scmi_rstd_count -#pragma weak plat_scmi_rstd_get_name -#pragma weak plat_scmi_rstd_autonomous -#pragma weak plat_scmi_rstd_set_state - -size_t plat_scmi_rstd_count(unsigned int agent_id __unused) -{ - return 0U; -} - -const char *plat_scmi_rstd_get_name(unsigned int agent_id __unused, - unsigned int scmi_id __unused) -{ - return NULL; -} - -int32_t plat_scmi_rstd_autonomous(unsigned int agent_id __unused, - unsigned int scmi_id __unused, - unsigned int state __unused) -{ - return SCMI_NOT_SUPPORTED; -} - -int32_t plat_scmi_rstd_set_state(unsigned int agent_id __unused, - unsigned int scmi_id __unused, - bool assert_not_deassert __unused) -{ - return SCMI_NOT_SUPPORTED; -} - -static void report_version(struct scmi_msg *msg) -{ - struct scmi_protocol_version_p2a return_values = { - .status = SCMI_SUCCESS, - .version = SCMI_PROTOCOL_VERSION_RESET_DOMAIN, - }; - - if (msg->in_size != 0U) { - scmi_status_response(msg, SCMI_PROTOCOL_ERROR); - return; - } - - scmi_write_response(msg, &return_values, sizeof(return_values)); -} - -static void report_attributes(struct scmi_msg *msg) -{ - struct scmi_protocol_attributes_p2a return_values = { - .status = SCMI_SUCCESS, - .attributes = plat_scmi_rstd_count(msg->agent_id), - }; - - if (msg->in_size != 0U) { - scmi_status_response(msg, SCMI_PROTOCOL_ERROR); - return; - } - - scmi_write_response(msg, &return_values, sizeof(return_values)); -} - -static void report_message_attributes(struct scmi_msg *msg) -{ - struct scmi_protocol_message_attributes_a2p *in_args = (void *)msg->in; - struct scmi_protocol_message_attributes_p2a return_values = { - .status = SCMI_SUCCESS, - /* For this protocol, attributes shall be zero */ - .attributes = 0U, - }; - - if (msg->in_size != sizeof(*in_args)) { - scmi_status_response(msg, SCMI_PROTOCOL_ERROR); - return; - } - - if (!message_id_is_supported(in_args->message_id)) { - scmi_status_response(msg, SCMI_NOT_FOUND); - return; - } - - scmi_write_response(msg, &return_values, sizeof(return_values)); -} - -static void reset_domain_attributes(struct scmi_msg *msg) -{ - struct scmi_reset_domain_attributes_a2p *in_args = (void *)msg->in; - struct scmi_reset_domain_attributes_p2a return_values; - const char *name = NULL; - unsigned int domain_id = 0U; - - if (msg->in_size != sizeof(*in_args)) { - scmi_status_response(msg, SCMI_PROTOCOL_ERROR); - return; - } - - domain_id = SPECULATION_SAFE_VALUE(in_args->domain_id); - - if (domain_id >= plat_scmi_rstd_count(msg->agent_id)) { - scmi_status_response(msg, SCMI_INVALID_PARAMETERS); - return; - } - - name = plat_scmi_rstd_get_name(msg->agent_id, domain_id); - if (name == NULL) { - scmi_status_response(msg, SCMI_NOT_FOUND); - return; - } - - zeromem(&return_values, sizeof(return_values)); - COPY_NAME_IDENTIFIER(return_values.name, name); - return_values.status = SCMI_SUCCESS; - return_values.flags = 0U; /* Async and Notif are not supported */ - return_values.latency = SCMI_RESET_DOMAIN_ATTR_UNK_LAT; - - scmi_write_response(msg, &return_values, sizeof(return_values)); -} - -static void reset_request(struct scmi_msg *msg) -{ - struct scmi_reset_domain_request_a2p *in_args = (void *)msg->in; - struct scmi_reset_domain_request_p2a out_args = { - .status = SCMI_SUCCESS, - }; - unsigned int domain_id = 0U; - - if (msg->in_size != sizeof(*in_args)) { - scmi_status_response(msg, SCMI_PROTOCOL_ERROR); - return; - } - - domain_id = SPECULATION_SAFE_VALUE(in_args->domain_id); - - if (domain_id >= plat_scmi_rstd_count(msg->agent_id)) { - scmi_status_response(msg, SCMI_NOT_FOUND); - return; - } - - if ((in_args->flags & SCMI_RESET_DOMAIN_AUTO) != 0U) { - out_args.status = plat_scmi_rstd_autonomous(msg->agent_id, - domain_id, - in_args->reset_state); - } else if ((in_args->flags & SCMI_RESET_DOMAIN_EXPLICIT) != 0U) { - out_args.status = plat_scmi_rstd_set_state(msg->agent_id, - domain_id, true); - } else { - out_args.status = plat_scmi_rstd_set_state(msg->agent_id, - domain_id, false); - } - - if (out_args.status != SCMI_SUCCESS) { - scmi_status_response(msg, out_args.status); - } else { - scmi_write_response(msg, &out_args, sizeof(out_args)); - } -} - -static const scmi_msg_handler_t scmi_rstd_handler_table[] = { - [SCMI_PROTOCOL_VERSION] = report_version, - [SCMI_PROTOCOL_ATTRIBUTES] = report_attributes, - [SCMI_PROTOCOL_MESSAGE_ATTRIBUTES] = report_message_attributes, - [SCMI_RESET_DOMAIN_ATTRIBUTES] = reset_domain_attributes, - [SCMI_RESET_DOMAIN_REQUEST] = reset_request, -}; - -static bool message_id_is_supported(unsigned int message_id) -{ - return (message_id < ARRAY_SIZE(scmi_rstd_handler_table)) && - (scmi_rstd_handler_table[message_id] != NULL); -} - -scmi_msg_handler_t scmi_msg_get_rstd_handler(struct scmi_msg *msg) -{ - unsigned int message_id = SPECULATION_SAFE_VALUE(msg->message_id); - - if (message_id >= ARRAY_SIZE(scmi_rstd_handler_table)) { - VERBOSE("Reset domain handle not found %u\n", msg->message_id); - return NULL; - } - - return scmi_rstd_handler_table[message_id]; -} diff --git a/drivers/st/scmi-msg/reset_domain.h b/drivers/st/scmi-msg/reset_domain.h deleted file mode 100644 index 47bee5e39..000000000 --- a/drivers/st/scmi-msg/reset_domain.h +++ /dev/null @@ -1,122 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. - * Copyright (c) 2019, Linaro Limited - */ -#ifndef SCMI_MSG_RESET_DOMAIN_H -#define SCMI_MSG_RESET_DOMAIN_H - -#include -#include - -#include - -#define SCMI_PROTOCOL_VERSION_RESET_DOMAIN 0x10000U - -#define SCMI_RESET_STATE_ARCH BIT(31) -#define SCMI_RESET_STATE_IMPL 0U - -/* - * Identifiers of the SCMI Reset Domain Management Protocol commands - */ -enum scmi_reset_domain_command_id { - SCMI_RESET_DOMAIN_ATTRIBUTES = 0x03, - SCMI_RESET_DOMAIN_REQUEST = 0x04, - SCMI_RESET_DOMAIN_NOTIFY = 0x05, -}; - -/* - * Identifiers of the SCMI Reset Domain Management Protocol responses - */ -enum scmi_reset_domain_response_id { - SCMI_RESET_ISSUED = 0x00, - SCMI_RESET_COMPLETE = 0x04, -}; - -/* - * PROTOCOL_ATTRIBUTES - */ - -#define SCMI_RESET_DOMAIN_COUNT_MASK GENMASK_32(15, 0) - -struct scmi_reset_domain_protocol_attributes_p2a { - int32_t status; - uint32_t attributes; -}; - -/* Value for scmi_reset_domain_attributes_p2a:flags */ -#define SCMI_RESET_DOMAIN_ATTR_ASYNC BIT(31) -#define SCMI_RESET_DOMAIN_ATTR_NOTIF BIT(30) - -/* Value for scmi_reset_domain_attributes_p2a:latency */ -#define SCMI_RESET_DOMAIN_ATTR_UNK_LAT 0x7fffffffU -#define SCMI_RESET_DOMAIN_ATTR_MAX_LAT 0x7ffffffeU - -/* Macro for scmi_reset_domain_attributes_p2a:name */ -#define SCMI_RESET_DOMAIN_ATTR_NAME_SZ 16U - -struct scmi_reset_domain_attributes_a2p { - uint32_t domain_id; -}; - -struct scmi_reset_domain_attributes_p2a { - int32_t status; - uint32_t flags; - uint32_t latency; - char name[SCMI_RESET_DOMAIN_ATTR_NAME_SZ]; -}; - -/* - * RESET - */ - -/* Values for scmi_reset_domain_request_a2p:flags */ -#define SCMI_RESET_DOMAIN_ASYNC BIT(2) -#define SCMI_RESET_DOMAIN_EXPLICIT BIT(1) -#define SCMI_RESET_DOMAIN_AUTO BIT(0) - -struct scmi_reset_domain_request_a2p { - uint32_t domain_id; - uint32_t flags; - uint32_t reset_state; -}; - -struct scmi_reset_domain_request_p2a { - int32_t status; -}; - -/* - * RESET_NOTIFY - */ - -/* Values for scmi_reset_notify_p2a:flags */ -#define SCMI_RESET_DOMAIN_DO_NOTIFY BIT(0) - -struct scmi_reset_domain_notify_a2p { - uint32_t domain_id; - uint32_t notify_enable; -}; - -struct scmi_reset_domain_notify_p2a { - int32_t status; -}; - -/* - * RESET_COMPLETE - */ - -struct scmi_reset_domain_complete_p2a { - int32_t status; - uint32_t domain_id; -}; - -/* - * RESET_ISSUED - */ - -struct scmi_reset_domain_issued_p2a { - uint32_t domain_id; - uint32_t reset_state; -}; - -#endif /* SCMI_MSG_RESET_DOMAIN_H */ diff --git a/drivers/st/scmi-msg/smt.c b/drivers/st/scmi-msg/smt.c deleted file mode 100644 index 2d5cd734f..000000000 --- a/drivers/st/scmi-msg/smt.c +++ /dev/null @@ -1,206 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -/* - * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. - * Copyright (c) 2019-2020, Linaro Limited - */ -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "common.h" - -/* Legacy SMT/SCMI messages are 128 bytes at most including SMT header */ -#define SCMI_PLAYLOAD_MAX 92U -#define SCMI_PLAYLOAD_U32_MAX (SCMI_PLAYLOAD_MAX / sizeof(uint32_t)) - -/** - * struct smt_header - SMT formatted header for SMT base shared memory transfer - * - * @status: Bit flags, see SMT_STATUS_* - * @flags: Bit flags, see SMT_FLAG_* - * @length: Byte size of message payload (variable) + ::message_header (32bit) - * payload: SCMI message payload data - */ -struct smt_header { - uint32_t reserved0; - uint32_t status; - uint64_t reserved1; - uint32_t flags; - uint32_t length; /* message_header + payload */ - uint32_t message_header; - uint32_t payload[]; -}; - -CASSERT(SCMI_PLAYLOAD_MAX + sizeof(struct smt_header) <= SMT_BUF_SLOT_SIZE, - assert_scmi_message_max_length_fits_in_smt_buffer_slot); - -/* Flag set in smt_header::status when SMT does not contain pending message */ -#define SMT_STATUS_FREE BIT(0) -/* Flag set in smt_header::status when SMT reports an error */ -#define SMT_STATUS_ERROR BIT(1) - -/* Flag set in smt_header::flags when SMT uses interrupts */ -#define SMT_FLAG_INTR_ENABLED BIT(1) - -/* Bit fields packed in smt_header::message_header */ -#define SMT_MSG_ID_MASK GENMASK_32(7, 0) -#define SMT_HDR_MSG_ID(_hdr) ((_hdr) & SMT_MSG_ID_MASK) - -#define SMT_MSG_TYPE_MASK GENMASK_32(9, 8) -#define SMT_HDR_TYPE_ID(_hdr) (((_hdr) & SMT_MSG_TYPE_MASK) >> 8) - -#define SMT_MSG_PROT_ID_MASK GENMASK_32(17, 10) -#define SMT_HDR_PROT_ID(_hdr) (((_hdr) & SMT_MSG_PROT_ID_MASK) >> 10) - -/* - * Provision input message payload buffers for fastcall SMC context entries - * and for interrupt context execution entries. - */ -static uint32_t fast_smc_payload[PLATFORM_CORE_COUNT][SCMI_PLAYLOAD_U32_MAX]; -static uint32_t interrupt_payload[PLATFORM_CORE_COUNT][SCMI_PLAYLOAD_U32_MAX]; - -/* SMP protection on channel access */ -static struct spinlock smt_channels_lock; - -/* If channel is not busy, set busy and return true, otherwise return false */ -static bool channel_set_busy(struct scmi_msg_channel *chan) -{ - bool channel_is_busy; - - spin_lock(&smt_channels_lock); - - channel_is_busy = chan->busy; - - if (!channel_is_busy) { - chan->busy = true; - } - - spin_unlock(&smt_channels_lock); - - return !channel_is_busy; -} - -static void channel_release_busy(struct scmi_msg_channel *chan) -{ - chan->busy = false; -} - -static struct smt_header *channel_to_smt_hdr(struct scmi_msg_channel *chan) -{ - return (struct smt_header *)chan->shm_addr; -} - -/* - * Creates a SCMI message instance in secure memory and pushes it in the SCMI - * message drivers. Message structure contains SCMI protocol meta-data and - * references to input payload in secure memory and output message buffer - * in shared memory. - */ -static void scmi_proccess_smt(unsigned int agent_id, uint32_t *payload_buf) -{ - struct scmi_msg_channel *chan; - struct smt_header *smt_hdr; - size_t in_payload_size; - uint32_t smt_status; - struct scmi_msg msg; - bool error = true; - - chan = plat_scmi_get_channel(agent_id); - if (chan == NULL) { - return; - } - - smt_hdr = channel_to_smt_hdr(chan); - assert(smt_hdr); - - smt_status = __atomic_load_n(&smt_hdr->status, __ATOMIC_RELAXED); - - if (!channel_set_busy(chan)) { - VERBOSE("SCMI channel %u busy", agent_id); - goto out; - } - - in_payload_size = __atomic_load_n(&smt_hdr->length, __ATOMIC_RELAXED) - - sizeof(smt_hdr->message_header); - - if (in_payload_size > SCMI_PLAYLOAD_MAX) { - VERBOSE("SCMI payload too big %u", in_payload_size); - goto out; - } - - if ((smt_status & (SMT_STATUS_ERROR | SMT_STATUS_FREE)) != 0U) { - VERBOSE("SCMI channel bad status 0x%x", - smt_hdr->status & (SMT_STATUS_ERROR | SMT_STATUS_FREE)); - goto out; - } - - /* Fill message */ - zeromem(&msg, sizeof(msg)); - msg.in = (char *)payload_buf; - msg.in_size = in_payload_size; - msg.out = (char *)smt_hdr->payload; - msg.out_size = chan->shm_size - sizeof(*smt_hdr); - - assert((msg.out != NULL) && (msg.out_size >= sizeof(int32_t))); - - /* Here the payload is copied in secure memory */ - memcpy(msg.in, smt_hdr->payload, in_payload_size); - - msg.protocol_id = SMT_HDR_PROT_ID(smt_hdr->message_header); - msg.message_id = SMT_HDR_MSG_ID(smt_hdr->message_header); - msg.agent_id = agent_id; - - scmi_process_message(&msg); - - /* Update message length with the length of the response message */ - smt_hdr->length = msg.out_size_out + sizeof(smt_hdr->message_header); - - channel_release_busy(chan); - error = false; - -out: - if (error) { - VERBOSE("SCMI error"); - smt_hdr->status |= SMT_STATUS_ERROR | SMT_STATUS_FREE; - } else { - smt_hdr->status |= SMT_STATUS_FREE; - } -} - -void scmi_smt_fastcall_smc_entry(unsigned int agent_id) -{ - scmi_proccess_smt(agent_id, - fast_smc_payload[plat_my_core_pos()]); -} - -void scmi_smt_interrupt_entry(unsigned int agent_id) -{ - scmi_proccess_smt(agent_id, - interrupt_payload[plat_my_core_pos()]); -} - -/* Init a SMT header for a shared memory buffer: state it a free/no-error */ -void scmi_smt_init_agent_channel(struct scmi_msg_channel *chan) -{ - if (chan != NULL) { - struct smt_header *smt_header = channel_to_smt_hdr(chan); - - if (smt_header != NULL) { - memset(smt_header, 0, sizeof(*smt_header)); - smt_header->status = SMT_STATUS_FREE; - - return; - } - } - - panic(); -} diff --git a/include/drivers/scmi-msg.h b/include/drivers/scmi-msg.h new file mode 100644 index 000000000..a9a99cf52 --- /dev/null +++ b/include/drivers/scmi-msg.h @@ -0,0 +1,207 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019, Linaro Limited + */ + +#ifndef SCMI_MSG_H +#define SCMI_MSG_H + +#include +#include +#include + +/* Minimum size expected for SMT based shared memory message buffers */ +#define SMT_BUF_SLOT_SIZE 128U + +/* A channel abstract a communication path between agent and server */ +struct scmi_msg_channel; + +/* + * struct scmi_msg_channel - Shared memory buffer for a agent-to-server channel + * + * @shm_addr: Address of the shared memory for the SCMI channel + * @shm_size: Byte size of the shared memory for the SCMI channel + * @busy: True when channel is busy, flase when channel is free + * @agent_name: Agent name, SCMI protocol exposes 16 bytes max, or NULL + */ +struct scmi_msg_channel { + uintptr_t shm_addr; + size_t shm_size; + bool busy; + const char *agent_name; +}; + +/* + * Initialize SMT memory buffer, called by platform at init for each + * agent channel using the SMT header format. + * + * @chan: Pointer to the channel shared memory to be initialized + */ +void scmi_smt_init_agent_channel(struct scmi_msg_channel *chan); + +/* + * Process SMT formatted message in a fastcall SMC execution context. + * Called by platform on SMC entry. When returning, output message is + * available in shared memory for agent to read the response. + * + * @agent_id: SCMI agent ID the SMT belongs to + */ +void scmi_smt_fastcall_smc_entry(unsigned int agent_id); + +/* + * Process SMT formatted message in a secure interrupt execution context. + * Called by platform interrupt handler. When returning, output message is + * available in shared memory for agent to read the response. + * + * @agent_id: SCMI agent ID the SMT belongs to + */ +void scmi_smt_interrupt_entry(unsigned int agent_id); + +/* Platform callback functions */ + +/* + * Return the SCMI channel related to an agent + * @agent_id: SCMI agent ID + * Return a pointer to channel on success, NULL otherwise + */ +struct scmi_msg_channel *plat_scmi_get_channel(unsigned int agent_id); + +/* + * Return how many SCMI protocols supported by the platform + * According to the SCMI specification, this function does not target + * a specific agent ID and shall return all platform known capabilities. + */ +size_t plat_scmi_protocol_count(void); + +/* + * Get the count and list of SCMI protocols (but base) supported for an agent + * + * @agent_id: SCMI agent ID + * Return a pointer to a null terminated array supported protocol IDs. + */ +const uint8_t *plat_scmi_protocol_list(unsigned int agent_id); + +/* Get the name of the SCMI vendor for the platform */ +const char *plat_scmi_vendor_name(void); + +/* Get the name of the SCMI sub-vendor for the platform */ +const char *plat_scmi_sub_vendor_name(void); + +/* Handlers for SCMI Clock protocol services */ + +/* + * Return number of clock controllers for an agent + * @agent_id: SCMI agent ID + * Return number of clock controllers + */ +size_t plat_scmi_clock_count(unsigned int agent_id); + +/* + * Get clock controller string ID (aka name) + * @agent_id: SCMI agent ID + * @scmi_id: SCMI clock ID + * Return pointer to name or NULL + */ +const char *plat_scmi_clock_get_name(unsigned int agent_id, + unsigned int scmi_id); + +/* + * Get clock possible rate as an array of frequencies in Hertz. + * + * @agent_id: SCMI agent ID + * @scmi_id: SCMI clock ID + * @rates: If NULL, function returns, else output rates array + * @nb_elts: Array size of @rates. + * Return an SCMI compliant error code + */ +int32_t plat_scmi_clock_rates_array(unsigned int agent_id, unsigned int scmi_id, + unsigned long *rates, size_t *nb_elts); + +/* + * Get clock possible rate as range with regular steps in Hertz + * + * @agent_id: SCMI agent ID + * @scmi_id: SCMI clock ID + * @min_max_step: 3 cell array for min, max and step rate data + * Return an SCMI compliant error code + */ +int32_t plat_scmi_clock_rates_by_step(unsigned int agent_id, + unsigned int scmi_id, + unsigned long *min_max_step); + +/* + * Get clock rate in Hertz + * @agent_id: SCMI agent ID + * @scmi_id: SCMI clock ID + * Return clock rate or 0 if not supported + */ +unsigned long plat_scmi_clock_get_rate(unsigned int agent_id, + unsigned int scmi_id); + +/* + * Set clock rate in Hertz + * @agent_id: SCMI agent ID + * @scmi_id: SCMI clock ID + * @rate: Target clock frequency in Hertz + * Return a compliant SCMI error code + */ +int32_t plat_scmi_clock_set_rate(unsigned int agent_id, unsigned int scmi_id, + unsigned long rate); + +/* + * Get clock state (enabled or disabled) + * @agent_id: SCMI agent ID + * @scmi_id: SCMI clock ID + * Return 1 if clock is enabled, 0 if disables, or a negative SCMI error code + */ +int32_t plat_scmi_clock_get_state(unsigned int agent_id, unsigned int scmi_id); + +/* + * Get clock state (enabled or disabled) + * @agent_id: SCMI agent ID + * @scmi_id: SCMI clock ID + * @enable_not_disable: Enable clock if true, disable clock otherwise + * Return a compliant SCMI error code + */ +int32_t plat_scmi_clock_set_state(unsigned int agent_id, unsigned int scmi_id, + bool enable_not_disable); + +/* Handlers for SCMI Reset Domain protocol services */ + +/* + * Return number of reset domains for the agent + * @agent_id: SCMI agent ID + * Return number of reset domains + */ +size_t plat_scmi_rstd_count(unsigned int agent_id); + +/* + * Get reset domain string ID (aka name) + * @agent_id: SCMI agent ID + * @scmi_id: SCMI reset domain ID + * Return pointer to name or NULL + */ +const char *plat_scmi_rstd_get_name(unsigned int agent_id, unsigned int scmi_id); + +/* + * Perform a reset cycle on a target reset domain + * @agent_id: SCMI agent ID + * @scmi_id: SCMI reset domain ID + * @state: Target reset state (see SCMI specification, 0 means context loss) + * Return a compliant SCMI error code + */ +int32_t plat_scmi_rstd_autonomous(unsigned int agent_id, unsigned int scmi_id, + unsigned int state); + +/* + * Assert or deassert target reset domain + * @agent_id: SCMI agent ID + * @scmi_id: SCMI reset domain ID + * @assert_not_deassert: Assert domain if true, otherwise deassert domain + * Return a compliant SCMI error code + */ +int32_t plat_scmi_rstd_set_state(unsigned int agent_id, unsigned int scmi_id, + bool assert_not_deassert); + +#endif /* SCMI_MSG_H */ diff --git a/include/drivers/scmi.h b/include/drivers/scmi.h new file mode 100644 index 000000000..ac5dc3871 --- /dev/null +++ b/include/drivers/scmi.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. + */ +#ifndef SCMI_MSG_SCMI_H +#define SCMI_MSG_SCMI_H + +#define SCMI_PROTOCOL_ID_BASE 0x10U +#define SCMI_PROTOCOL_ID_POWER_DOMAIN 0x11U +#define SCMI_PROTOCOL_ID_SYS_POWER 0x12U +#define SCMI_PROTOCOL_ID_PERF 0x13U +#define SCMI_PROTOCOL_ID_CLOCK 0x14U +#define SCMI_PROTOCOL_ID_SENSOR 0x15U +#define SCMI_PROTOCOL_ID_RESET_DOMAIN 0x16U + +/* SCMI error codes reported to agent through server-to-agent messages */ +#define SCMI_SUCCESS 0 +#define SCMI_NOT_SUPPORTED (-1) +#define SCMI_INVALID_PARAMETERS (-2) +#define SCMI_DENIED (-3) +#define SCMI_NOT_FOUND (-4) +#define SCMI_OUT_OF_RANGE (-5) +#define SCMI_BUSY (-6) +#define SCMI_COMMS_ERROR (-7) +#define SCMI_GENERIC_ERROR (-8) +#define SCMI_HARDWARE_ERROR (-9) +#define SCMI_PROTOCOL_ERROR (-10) + +#endif /* SCMI_MSG_SCMI_H */ diff --git a/include/drivers/st/scmi-msg.h b/include/drivers/st/scmi-msg.h deleted file mode 100644 index a9a99cf52..000000000 --- a/include/drivers/st/scmi-msg.h +++ /dev/null @@ -1,207 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. - * Copyright (c) 2019, Linaro Limited - */ - -#ifndef SCMI_MSG_H -#define SCMI_MSG_H - -#include -#include -#include - -/* Minimum size expected for SMT based shared memory message buffers */ -#define SMT_BUF_SLOT_SIZE 128U - -/* A channel abstract a communication path between agent and server */ -struct scmi_msg_channel; - -/* - * struct scmi_msg_channel - Shared memory buffer for a agent-to-server channel - * - * @shm_addr: Address of the shared memory for the SCMI channel - * @shm_size: Byte size of the shared memory for the SCMI channel - * @busy: True when channel is busy, flase when channel is free - * @agent_name: Agent name, SCMI protocol exposes 16 bytes max, or NULL - */ -struct scmi_msg_channel { - uintptr_t shm_addr; - size_t shm_size; - bool busy; - const char *agent_name; -}; - -/* - * Initialize SMT memory buffer, called by platform at init for each - * agent channel using the SMT header format. - * - * @chan: Pointer to the channel shared memory to be initialized - */ -void scmi_smt_init_agent_channel(struct scmi_msg_channel *chan); - -/* - * Process SMT formatted message in a fastcall SMC execution context. - * Called by platform on SMC entry. When returning, output message is - * available in shared memory for agent to read the response. - * - * @agent_id: SCMI agent ID the SMT belongs to - */ -void scmi_smt_fastcall_smc_entry(unsigned int agent_id); - -/* - * Process SMT formatted message in a secure interrupt execution context. - * Called by platform interrupt handler. When returning, output message is - * available in shared memory for agent to read the response. - * - * @agent_id: SCMI agent ID the SMT belongs to - */ -void scmi_smt_interrupt_entry(unsigned int agent_id); - -/* Platform callback functions */ - -/* - * Return the SCMI channel related to an agent - * @agent_id: SCMI agent ID - * Return a pointer to channel on success, NULL otherwise - */ -struct scmi_msg_channel *plat_scmi_get_channel(unsigned int agent_id); - -/* - * Return how many SCMI protocols supported by the platform - * According to the SCMI specification, this function does not target - * a specific agent ID and shall return all platform known capabilities. - */ -size_t plat_scmi_protocol_count(void); - -/* - * Get the count and list of SCMI protocols (but base) supported for an agent - * - * @agent_id: SCMI agent ID - * Return a pointer to a null terminated array supported protocol IDs. - */ -const uint8_t *plat_scmi_protocol_list(unsigned int agent_id); - -/* Get the name of the SCMI vendor for the platform */ -const char *plat_scmi_vendor_name(void); - -/* Get the name of the SCMI sub-vendor for the platform */ -const char *plat_scmi_sub_vendor_name(void); - -/* Handlers for SCMI Clock protocol services */ - -/* - * Return number of clock controllers for an agent - * @agent_id: SCMI agent ID - * Return number of clock controllers - */ -size_t plat_scmi_clock_count(unsigned int agent_id); - -/* - * Get clock controller string ID (aka name) - * @agent_id: SCMI agent ID - * @scmi_id: SCMI clock ID - * Return pointer to name or NULL - */ -const char *plat_scmi_clock_get_name(unsigned int agent_id, - unsigned int scmi_id); - -/* - * Get clock possible rate as an array of frequencies in Hertz. - * - * @agent_id: SCMI agent ID - * @scmi_id: SCMI clock ID - * @rates: If NULL, function returns, else output rates array - * @nb_elts: Array size of @rates. - * Return an SCMI compliant error code - */ -int32_t plat_scmi_clock_rates_array(unsigned int agent_id, unsigned int scmi_id, - unsigned long *rates, size_t *nb_elts); - -/* - * Get clock possible rate as range with regular steps in Hertz - * - * @agent_id: SCMI agent ID - * @scmi_id: SCMI clock ID - * @min_max_step: 3 cell array for min, max and step rate data - * Return an SCMI compliant error code - */ -int32_t plat_scmi_clock_rates_by_step(unsigned int agent_id, - unsigned int scmi_id, - unsigned long *min_max_step); - -/* - * Get clock rate in Hertz - * @agent_id: SCMI agent ID - * @scmi_id: SCMI clock ID - * Return clock rate or 0 if not supported - */ -unsigned long plat_scmi_clock_get_rate(unsigned int agent_id, - unsigned int scmi_id); - -/* - * Set clock rate in Hertz - * @agent_id: SCMI agent ID - * @scmi_id: SCMI clock ID - * @rate: Target clock frequency in Hertz - * Return a compliant SCMI error code - */ -int32_t plat_scmi_clock_set_rate(unsigned int agent_id, unsigned int scmi_id, - unsigned long rate); - -/* - * Get clock state (enabled or disabled) - * @agent_id: SCMI agent ID - * @scmi_id: SCMI clock ID - * Return 1 if clock is enabled, 0 if disables, or a negative SCMI error code - */ -int32_t plat_scmi_clock_get_state(unsigned int agent_id, unsigned int scmi_id); - -/* - * Get clock state (enabled or disabled) - * @agent_id: SCMI agent ID - * @scmi_id: SCMI clock ID - * @enable_not_disable: Enable clock if true, disable clock otherwise - * Return a compliant SCMI error code - */ -int32_t plat_scmi_clock_set_state(unsigned int agent_id, unsigned int scmi_id, - bool enable_not_disable); - -/* Handlers for SCMI Reset Domain protocol services */ - -/* - * Return number of reset domains for the agent - * @agent_id: SCMI agent ID - * Return number of reset domains - */ -size_t plat_scmi_rstd_count(unsigned int agent_id); - -/* - * Get reset domain string ID (aka name) - * @agent_id: SCMI agent ID - * @scmi_id: SCMI reset domain ID - * Return pointer to name or NULL - */ -const char *plat_scmi_rstd_get_name(unsigned int agent_id, unsigned int scmi_id); - -/* - * Perform a reset cycle on a target reset domain - * @agent_id: SCMI agent ID - * @scmi_id: SCMI reset domain ID - * @state: Target reset state (see SCMI specification, 0 means context loss) - * Return a compliant SCMI error code - */ -int32_t plat_scmi_rstd_autonomous(unsigned int agent_id, unsigned int scmi_id, - unsigned int state); - -/* - * Assert or deassert target reset domain - * @agent_id: SCMI agent ID - * @scmi_id: SCMI reset domain ID - * @assert_not_deassert: Assert domain if true, otherwise deassert domain - * Return a compliant SCMI error code - */ -int32_t plat_scmi_rstd_set_state(unsigned int agent_id, unsigned int scmi_id, - bool assert_not_deassert); - -#endif /* SCMI_MSG_H */ diff --git a/include/drivers/st/scmi.h b/include/drivers/st/scmi.h deleted file mode 100644 index ac5dc3871..000000000 --- a/include/drivers/st/scmi.h +++ /dev/null @@ -1,29 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. - */ -#ifndef SCMI_MSG_SCMI_H -#define SCMI_MSG_SCMI_H - -#define SCMI_PROTOCOL_ID_BASE 0x10U -#define SCMI_PROTOCOL_ID_POWER_DOMAIN 0x11U -#define SCMI_PROTOCOL_ID_SYS_POWER 0x12U -#define SCMI_PROTOCOL_ID_PERF 0x13U -#define SCMI_PROTOCOL_ID_CLOCK 0x14U -#define SCMI_PROTOCOL_ID_SENSOR 0x15U -#define SCMI_PROTOCOL_ID_RESET_DOMAIN 0x16U - -/* SCMI error codes reported to agent through server-to-agent messages */ -#define SCMI_SUCCESS 0 -#define SCMI_NOT_SUPPORTED (-1) -#define SCMI_INVALID_PARAMETERS (-2) -#define SCMI_DENIED (-3) -#define SCMI_NOT_FOUND (-4) -#define SCMI_OUT_OF_RANGE (-5) -#define SCMI_BUSY (-6) -#define SCMI_COMMS_ERROR (-7) -#define SCMI_GENERIC_ERROR (-8) -#define SCMI_HARDWARE_ERROR (-9) -#define SCMI_PROTOCOL_ERROR (-10) - -#endif /* SCMI_MSG_SCMI_H */ diff --git a/plat/st/stm32mp1/services/stm32mp1_svc_setup.c b/plat/st/stm32mp1/services/stm32mp1_svc_setup.c index 49375a62d..d4ed44525 100644 --- a/plat/st/stm32mp1/services/stm32mp1_svc_setup.c +++ b/plat/st/stm32mp1/services/stm32mp1_svc_setup.c @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include diff --git a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk index 8866fb556..4d4820afa 100644 --- a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk +++ b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk @@ -26,11 +26,11 @@ BL32_SOURCES += ${GICV2_SOURCES} \ BL32_SOURCES += plat/common/plat_psci_common.c # SCMI server drivers -BL32_SOURCES += drivers/st/scmi-msg/base.c \ - drivers/st/scmi-msg/clock.c \ - drivers/st/scmi-msg/entry.c \ - drivers/st/scmi-msg/reset_domain.c \ - drivers/st/scmi-msg/smt.c +BL32_SOURCES += drivers/scmi-msg/base.c \ + drivers/scmi-msg/clock.c \ + drivers/scmi-msg/entry.c \ + drivers/scmi-msg/reset_domain.c \ + drivers/scmi-msg/smt.c # stm32mp1 specific services BL32_SOURCES += plat/st/stm32mp1/services/bsec_svc.c \ diff --git a/plat/st/stm32mp1/stm32mp1_scmi.c b/plat/st/stm32mp1/stm32mp1_scmi.c index 80faf0c6e..6d60bd4de 100644 --- a/plat/st/stm32mp1/stm32mp1_scmi.c +++ b/plat/st/stm32mp1/stm32mp1_scmi.c @@ -8,8 +8,8 @@ #include -#include -#include +#include +#include #include #include #include -- cgit v1.2.3 From 128c5f02859579ce15df18c5d443565778b2d3bf Mon Sep 17 00:00:00 2001 From: Heyi Guo Date: Tue, 27 Oct 2020 08:36:40 +0800 Subject: libc/printf: add support to print "%" character Enable printf() in TF-A to print "%" character as C standard, which may be used in platform porting to print percentage information. Signed-off-by: Heyi Guo Change-Id: I7af2f1d153548e426f423fce15dc48b0da56c622 --- lib/libc/printf.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/libc/printf.c b/lib/libc/printf.c index 2715a72d4..45e153ec7 100644 --- a/lib/libc/printf.c +++ b/lib/libc/printf.c @@ -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 */ @@ -108,6 +108,9 @@ int vprintf(const char *fmt, va_list args) /* Check the format specifier */ loop: switch (*fmt) { + case '%': + (void)putchar('%'); + break; case 'i': /* Fall through to next one */ case 'd': num = get_num_va_args(args, l_count); -- cgit v1.2.3 From c654615466465526290ea0b0ba909b5a010b8bef Mon Sep 17 00:00:00 2001 From: Heyi Guo Date: Tue, 27 Oct 2020 08:36:40 +0800 Subject: libc/snprintf: add support to print "%" character Enable snprintf()/vsnprintf() in TF-A to print "%" character as C standard, which may be used in platform porting to print percentage information. Signed-off-by: Heyi Guo Change-Id: I9b296372a1002046eabac1df5e8eb99a27efd4a8 --- lib/libc/snprintf.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/libc/snprintf.c b/lib/libc/snprintf.c index 6e80d8c03..42faa269d 100644 --- a/lib/libc/snprintf.c +++ b/lib/libc/snprintf.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 */ @@ -130,6 +130,13 @@ int vsnprintf(char *s, size_t n, const char *fmt, va_list args) /* Check the format specifier. */ loop: switch (*fmt) { + case '%': + if (chars_printed < n) { + *s = '%'; + s++; + } + chars_printed++; + break; case '0': case '1': case '2': -- cgit v1.2.3 From 7981c5043b3b77b87847148ea0df81e9ec59aa56 Mon Sep 17 00:00:00 2001 From: Heyi Guo Date: Wed, 20 Jan 2021 13:55:25 +0800 Subject: libc/snprintf: use macro to reduce duplicated code Add macro CHECK_AND_PUT_CHAR to check buffer capacity, save one character to buffer, and then increase character counter by one in one single statement, so that 4 similar code pieces can be cleaned. Signed-off-by: Heyi Guo Change-Id: I2add6b4bd6c24ea3c0d2499a44924e3e8db0f4d1 --- lib/libc/snprintf.c | 36 ++++++++++++++---------------------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/lib/libc/snprintf.c b/lib/libc/snprintf.c index 42faa269d..3b175ed6a 100644 --- a/lib/libc/snprintf.c +++ b/lib/libc/snprintf.c @@ -10,16 +10,20 @@ #include #include +#define CHECK_AND_PUT_CHAR(buf, size, chars_printed, ch) \ + do { \ + if ((chars_printed) < (size)) { \ + *(buf) = (ch); \ + (buf)++; \ + } \ + (chars_printed)++; \ + } while (false) + static void string_print(char **s, size_t n, size_t *chars_printed, const char *str) { while (*str != '\0') { - if (*chars_printed < n) { - *(*s) = *str; - (*s)++; - } - - (*chars_printed)++; + CHECK_AND_PUT_CHAR(*s, n, *chars_printed, *str); str++; } } @@ -131,11 +135,7 @@ int vsnprintf(char *s, size_t n, const char *fmt, va_list args) loop: switch (*fmt) { case '%': - if (chars_printed < n) { - *s = '%'; - s++; - } - chars_printed++; + CHECK_AND_PUT_CHAR(s, n, chars_printed, '%'); break; case '0': case '1': @@ -165,12 +165,8 @@ loop: num = va_arg(args, int); if (num < 0) { - if (chars_printed < n) { - *s = '-'; - s++; - } - chars_printed++; - + CHECK_AND_PUT_CHAR(s, n, chars_printed, + '-'); unum = (unsigned int)-num; } else { unum = (unsigned int)num; @@ -217,13 +213,9 @@ loop: continue; } - if (chars_printed < n) { - *s = *fmt; - s++; - } + CHECK_AND_PUT_CHAR(s, n, chars_printed, *fmt); fmt++; - chars_printed++; } if (n > 0U) { -- cgit v1.2.3 From f621d5fb4bc17952d2d4b6da138b8a5640b148e3 Mon Sep 17 00:00:00 2001 From: Rajan Vaja Date: Wed, 20 Jan 2021 00:53:45 -0800 Subject: plat: xilinx: versal: Remove code duplication Some switch cases uses same operation. So, club switch cases which uses same operation and remove duplicate code. Signed-off-by: Rajan Vaja Change-Id: I260b474c0ff3f2ca102c32d4af2e4abba2b8f57c --- plat/xilinx/versal/pm_service/pm_api_sys.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.c b/plat/xilinx/versal/pm_service/pm_api_sys.c index eae881e22..3cdd9d051 100644 --- a/plat/xilinx/versal/pm_service/pm_api_sys.c +++ b/plat/xilinx/versal/pm_service/pm_api_sys.c @@ -832,6 +832,7 @@ enum pm_ret_status pm_feature_check(uint32_t api_id, unsigned int *version) switch (api_id) { case PM_GET_CALLBACK_DATA: case PM_GET_TRUSTZONE_VERSION: + case PM_LOAD_PDI: *version = (PM_API_BASE_VERSION << 16); return PM_RET_SUCCESS; case PM_GET_API_VERSION: @@ -857,11 +858,6 @@ enum pm_ret_status pm_feature_check(uint32_t api_id, unsigned int *version) case PM_PINCTRL_CONFIG_PARAM_GET: case PM_PINCTRL_CONFIG_PARAM_SET: case PM_IOCTL: - *version = (PM_API_BASE_VERSION << 16); - break; - case PM_QUERY_DATA: - *version = (PM_API_QUERY_DATA_VERSION << 16); - break; case PM_CLOCK_ENABLE: case PM_CLOCK_DISABLE: case PM_CLOCK_GETSTATE: @@ -880,9 +876,9 @@ enum pm_ret_status pm_feature_check(uint32_t api_id, unsigned int *version) case PM_REGISTER_NOTIFIER: *version = (PM_API_BASE_VERSION << 16); break; - case PM_LOAD_PDI: - *version = (PM_API_BASE_VERSION << 16); - return PM_RET_SUCCESS; + case PM_QUERY_DATA: + *version = (PM_API_QUERY_DATA_VERSION << 16); + break; default: *version = 0U; return PM_RET_ERROR_NOFEATURE; -- cgit v1.2.3 From 4d8c18196378824e388cf31ef991ba8fbbb09cbf Mon Sep 17 00:00:00 2001 From: Jagadeesh Ujja Date: Tue, 5 Jan 2021 22:01:24 +0530 Subject: plat/arm: css: Turn ON/OFF redistributor in sync with GIC CPU interface ON/OFF Turn ON/OFF GIC redistributor in sync with GIC CPU interface ON/OFF. Issue : The Linux prompt hangs when all the cores in a cluster are turned OFF and we try to turn ON a core in that cluster. Previously when TF-A turns ON a core, TF-A first turns ON the redistributor followed by the core. This did not match the flow when turning OFF a core, as TF-A did not turn OFF redistributor when the corresponding core[s] are disabled. This hang is resolved by disabling redistributor as cores are disabled, keeping them in sync. Signed-off-by: Jagadeesh Ujja Change-Id: Ifd04fdcfd47b45e00f874f15b098471883d023f0 --- plat/arm/css/common/css_pm.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plat/arm/css/common/css_pm.c b/plat/arm/css/common/css_pm.c index 8e7452634..926b8ec7c 100644 --- a/plat/arm/css/common/css_pm.c +++ b/plat/arm/css/common/css_pm.c @@ -123,6 +123,9 @@ static void css_power_down_common(const psci_power_state_t *target_state) /* Prevent interrupts from spuriously waking up this cpu */ plat_arm_gic_cpuif_disable(); + /* Turn redistributor off */ + plat_arm_gic_redistif_off(); + /* Cluster is to be turned off, so disable coherency */ if (CSS_CLUSTER_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF) { plat_arm_interconnect_exit_coherency(); -- cgit v1.2.3 From 9feb1e2f4b1946d6042de0f0de3d8ae9edc21632 Mon Sep 17 00:00:00 2001 From: Ming Huang Date: Mon, 9 Nov 2020 17:22:05 +0800 Subject: plat/arm/css/sgi: Fix bl32 receive event - 0xC4000061 issue The issue is that, when interrupt is triggered and RAS handler is entered, after interrupt handler finishes, TF-A will re-enter bl32 and then crash. sdei_dispatch_event() may return failing result in some cases, for example kernel may not have registered a handler or RAS event may happen early during boot. We restore the NS context when sdei_dispatch_event() returns failing result. error log : Received delegated event X0 : 0xC4000061 X1 : 0x0 X2 : 0x0 X3 : 0x0 Received event - 0xC4000061 on cpu 0 UnRecognized Event - 0xC4000061 Failed delegated event 0xC4000061, Status Invalid Parameter Unhandled Exception in EL3. x30 = 0x000000000401f700 x0 = 0xfffffffffffffffe x1 = 0xfffffffffffffffe x2 = 0x00000000600003c0 Signed-off-by: Ming Huang Change-Id: I9802e9a32eee0ac3b5a8bcc0362d0b0e3b71dc9f --- plat/arm/css/sgi/sgi_ras.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/plat/arm/css/sgi/sgi_ras.c b/plat/arm/css/sgi/sgi_ras.c index f56544e72..f06c952cd 100644 --- a/plat/arm/css/sgi/sgi_ras.c +++ b/plat/arm/css/sgi/sgi_ras.c @@ -111,6 +111,7 @@ static int sgi_ras_intr_handler(const struct err_record_info *err_rec, struct sgi_ras_ev_map *ras_map; mm_communicate_header_t *header; uint32_t intr; + int ret; cm_el1_sysregs_context_save(NON_SECURE); intr = data->interrupt; @@ -152,9 +153,20 @@ static int sgi_ras_intr_handler(const struct err_record_info *err_rec, plat_ic_end_of_interrupt(intr); /* Dispatch the event to the SDEI client */ - sdei_dispatch_event(ras_map->sdei_ev_num); + ret = sdei_dispatch_event(ras_map->sdei_ev_num); + if (ret != 0) { + /* + * sdei_dispatch_event() may return failing result in some cases, + * for example kernel may not have registered a handler or RAS event + * may happen early during boot. We restore the NS context when + * sdei_dispatch_event() returns failing result. + */ + ERROR("SDEI dispatch failed: %d", ret); + cm_el1_sysregs_context_restore(NON_SECURE); + cm_set_next_eret_context(NON_SECURE); + } - return 0; + return ret; } int sgi_ras_intr_handler_setup(void) -- cgit v1.2.3 From 0301d09ce66988ec73f82e7e1e69054d5370a766 Mon Sep 17 00:00:00 2001 From: Ming Huang Date: Mon, 11 Jan 2021 11:00:12 +0800 Subject: plat/arm/css/sgi: Fix assert expression issue Violation of MISRA-C Rule 14.4 Signed-off-by: Ming Huang Change-Id: I44ef50dadb54fb056a91f3de962b6e63ba6d7ac4 --- plat/arm/css/sgi/sgi_ras.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/arm/css/sgi/sgi_ras.c b/plat/arm/css/sgi/sgi_ras.c index f06c952cd..a04972d70 100644 --- a/plat/arm/css/sgi/sgi_ras.c +++ b/plat/arm/css/sgi/sgi_ras.c @@ -121,7 +121,7 @@ static int sgi_ras_intr_handler(const struct err_record_info *err_rec, * this interrupt */ ras_map = find_ras_event_map_by_intr(intr); - assert(ras_map); + assert(ras_map != NULL); /* * Populate the MM_COMMUNICATE payload to share the -- cgit v1.2.3 From 47147013b437b1217eba92546b12862e6297bfed Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 21 Jan 2021 12:29:59 +0000 Subject: Fix documentation typos and misspellings Fix some typos and misspellings in TF-A documentation. Signed-off-by: David Horstmann Change-Id: Id72553ce7b2f0bed9821604fbc8df4d4949909fa --- docs/change-log.rst | 6 +++--- docs/getting_started/build-options.rst | 4 ++-- docs/plat/marvell/armada/misc/mvebu-ccu.rst | 2 +- docs/plat/marvell/armada/misc/mvebu-io-win.rst | 2 +- docs/plat/marvell/armada/misc/mvebu-iob.rst | 2 +- docs/plat/rpi4.rst | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/change-log.rst b/docs/change-log.rst index 3b8f8365c..ec88df921 100644 --- a/docs/change-log.rst +++ b/docs/change-log.rst @@ -689,10 +689,10 @@ New Features - arm/common: Allow boards to specify second DRAM Base address and to define PLAT_ARM_TZC_FILTERS - - arm/cornstone700: Add support for mhuv2 and stack protector + - arm/corstone700: Add support for mhuv2 and stack protector - arm/fvp: Add support for fconf in BL31 and SP_MIN. Populate power - domain desciptor dynamically by leveraging fconf APIs. + 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 @@ -967,7 +967,7 @@ Changed cpu clock, Move versal_def.h and versal_private to include directory - Tools - - sptool: Updated sptool to accomodate building secure partition packages. + - sptool: Updated sptool to accommodate building secure partition packages. Resolved Issues ^^^^^^^^^^^^^^^ diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 16de41029..c520e0c22 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -403,7 +403,7 @@ Common build options library is not supported. - ``INVERTED_MEMMAP``: memmap tool print by default lower addresses at the - bottom, higher addresses at the top. This buid flag can be set to '1' to + bottom, higher addresses at the top. This build flag can be set to '1' to invert this behavior. Lower addresses will be printed at the top and higher addresses at the bottom. @@ -570,7 +570,7 @@ Common build options - ``SEPARATE_NOBITS_REGION``: Setting this option to ``1`` allows the NOBITS sections of BL31 (.bss, stacks, page tables, and coherent memory) to be allocated in RAM discontiguous from the loaded firmware image. When set, the - platform is expected to provide definitons for ``BL31_NOBITS_BASE`` and + platform is expected to provide definitions for ``BL31_NOBITS_BASE`` and ``BL31_NOBITS_LIMIT``. When the option is ``0`` (the default), NOBITS sections are placed in RAM immediately following the loaded firmware image. diff --git a/docs/plat/marvell/armada/misc/mvebu-ccu.rst b/docs/plat/marvell/armada/misc/mvebu-ccu.rst index 5bac11faf..12118e9d9 100644 --- a/docs/plat/marvell/armada/misc/mvebu-ccu.rst +++ b/docs/plat/marvell/armada/misc/mvebu-ccu.rst @@ -1,7 +1,7 @@ Marvell CCU address decoding bindings ===================================== -CCU configration driver (1st stage address translation) for Marvell Armada 8K and 8K+ SoCs. +CCU configuration driver (1st stage address translation) for Marvell Armada 8K and 8K+ SoCs. The CCU node includes a description of the address decoding configuration. diff --git a/docs/plat/marvell/armada/misc/mvebu-io-win.rst b/docs/plat/marvell/armada/misc/mvebu-io-win.rst index 52845ca02..749829199 100644 --- a/docs/plat/marvell/armada/misc/mvebu-io-win.rst +++ b/docs/plat/marvell/armada/misc/mvebu-io-win.rst @@ -1,7 +1,7 @@ Marvell IO WIN address decoding bindings ======================================== -IO Window configration driver (2nd stage address translation) for Marvell Armada 8K and 8K+ SoCs. +IO Window configuration driver (2nd stage address translation) for Marvell Armada 8K and 8K+ SoCs. The IO WIN includes a description of the address decoding configuration. diff --git a/docs/plat/marvell/armada/misc/mvebu-iob.rst b/docs/plat/marvell/armada/misc/mvebu-iob.rst index d02a7e84c..aa41822f4 100644 --- a/docs/plat/marvell/armada/misc/mvebu-iob.rst +++ b/docs/plat/marvell/armada/misc/mvebu-iob.rst @@ -1,7 +1,7 @@ Marvell IOB address decoding bindings ===================================== -IO bridge configration driver (3rd stage address translation) for Marvell Armada 8K and 8K+ SoCs. +IO bridge configuration driver (3rd stage address translation) for Marvell Armada 8K and 8K+ SoCs. The IOB includes a description of the address decoding configuration. diff --git a/docs/plat/rpi4.rst b/docs/plat/rpi4.rst index beb0227c2..6e83fd730 100644 --- a/docs/plat/rpi4.rst +++ b/docs/plat/rpi4.rst @@ -60,7 +60,7 @@ As with the previous models, the GPU and its firmware are the first entity to run after the SoC gets its power. The on-chip Boot ROM loads the next stage (bootcode.bin) from flash (EEPROM), which is again GPU code. This part knows how to access the MMC controller and how to parse a FAT -filesystem, so it will load further compononents and configuration files +filesystem, so it will load further components and configuration files from the first FAT partition on the SD card. To accommodate this existing way of configuring and setting up the board, -- cgit v1.2.3 From b226c74737090f5fca17656f43743b2c6ab766ca Mon Sep 17 00:00:00 2001 From: Zelalem Date: Fri, 18 Dec 2020 11:02:25 -0600 Subject: DebugFS: Check channel index before calling clone function To avoid a potential out-of-bounds access, check whether a device exists on a channel before calling the corresponding clone function. Signed-off-by: Zelalem Change-Id: Ia0dd66b331d3fa8a33109a02369e1bc9ae0fdd5b --- lib/debugfs/dev.c | 6 +++++- lib/debugfs/devfip.c | 11 ++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/lib/debugfs/dev.c b/lib/debugfs/dev.c index 0361437b8..2fc1d4062 100644 --- a/lib/debugfs/dev.c +++ b/lib/debugfs/dev.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Arm Limited. All rights reserved. + * Copyright (c) 2019-2021, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -333,6 +333,10 @@ noent: ******************************************************************************/ chan_t *clone(chan_t *c, chan_t *nc) { + if (c->index == NODEV) { + return NULL; + } + return devtab[c->index]->clone(c, nc); } diff --git a/lib/debugfs/devfip.c b/lib/debugfs/devfip.c index d8b83b7a4..85e6403c7 100644 --- a/lib/debugfs/devfip.c +++ b/lib/debugfs/devfip.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 */ @@ -129,7 +129,10 @@ static int fipgen(chan_t *c, const dirtab_t *tab, int ntab, int n, dir_t *dir) panic(); } - clone(archives[c->dev].c, &nc); + if (clone(archives[c->dev].c, &nc) == NULL) { + panic(); + } + fip = &archives[nc.dev]; off = STOC_HEADER; @@ -202,7 +205,9 @@ static int fipread(chan_t *c, void *buf, int n) panic(); } - clone(fip->c, &cs); + if (clone(fip->c, &cs) == NULL) { + panic(); + } size = fip->size[c->qid]; if (c->offset >= size) { -- cgit v1.2.3 From aeb727f3bf5d9f482eec0f18e08d5ed5f2de79cb Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Wed, 9 Dec 2020 13:35:27 +0100 Subject: stm32mp1: correct plat_crash_console_flush() The base address of UART peripheral should be given in R0, not in R1. Otherwise the console_stm32_core_flush issues an assert message. This issue was highlighted with recent changes in console flush functions. Change-Id: Iead01986fdbbf30ad2fd9fa515a1d2b611b4e591 Signed-off-by: Yann Gautier --- plat/st/stm32mp1/stm32mp1_helper.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/st/stm32mp1/stm32mp1_helper.S b/plat/st/stm32mp1/stm32mp1_helper.S index 302136236..84e9e8d43 100644 --- a/plat/st/stm32mp1/stm32mp1_helper.S +++ b/plat/st/stm32mp1/stm32mp1_helper.S @@ -204,7 +204,7 @@ endfunc plat_crash_console_init * --------------------------------------------- */ func plat_crash_console_flush - ldr r1, =STM32MP_DEBUG_USART_BASE + ldr r0, =STM32MP_DEBUG_USART_BASE b console_stm32_core_flush endfunc plat_crash_console_flush -- cgit v1.2.3 From a1473c99e69f4ddd89ccde34439dc489a601939a Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sat, 16 Jan 2021 01:05:38 -0600 Subject: allwinner: psci: Drop .get_node_hw_state callback This optional PSCI function was only implemented when SCPI was available. However, the underlying SCPI function is not able to fulfill the necessary contract. First, the SCPI protocol has no way to represent HW_STANDBY at the CPU power level. Second, the SCPI implementation maintains its own logical view of power states, and its implementation of SCPI_CMD_GET_CSS_POWER_STATE does not actually query the hardware. Thus it cannot provide "the physical view of power state", as required for this function by the PSCI specification. Since the function is optional, drop it. Change-Id: I5f3a0810ac19ddeb3c0c5d35aeb09f09a0b80c1d Signed-off-by: Samuel Holland --- plat/allwinner/common/sunxi_pm.c | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/plat/allwinner/common/sunxi_pm.c b/plat/allwinner/common/sunxi_pm.c index e0fa5b3ec..d750d8c1d 100644 --- a/plat/allwinner/common/sunxi_pm.c +++ b/plat/allwinner/common/sunxi_pm.c @@ -226,29 +226,6 @@ static void sunxi_get_sys_suspend_power_state(psci_power_state_t *req_state) req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE; } -static int sunxi_get_node_hw_state(u_register_t mpidr, - unsigned int power_level) -{ - unsigned int cluster_state, cpu_state; - unsigned int cpu = MPIDR_AFFLVL0_VAL(mpidr); - - /* SoC power level (always on if PSCI works). */ - if (power_level == SYSTEM_PWR_LVL) - return HW_ON; - if (scpi_get_css_power_state(mpidr, &cpu_state, &cluster_state)) - return PSCI_E_NOT_SUPPORTED; - /* Cluster power level (full power state available). */ - if (power_level == CLUSTER_PWR_LVL) { - if (cluster_state == scpi_power_on) - return HW_ON; - if (cluster_state == scpi_power_retention) - return HW_STANDBY; - return HW_OFF; - } - /* CPU power level (one bit boolean for on or off). */ - return ((cpu_state & BIT(cpu)) != 0) ? HW_ON : HW_OFF; -} - static plat_psci_ops_t sunxi_psci_ops = { .cpu_standby = sunxi_cpu_standby, .pwr_domain_on = sunxi_pwr_domain_on, @@ -297,7 +274,6 @@ int plat_setup_psci_ops(uintptr_t sec_entrypoint, sunxi_psci_ops.pwr_domain_suspend = sunxi_pwr_domain_off; sunxi_psci_ops.pwr_domain_suspend_finish = sunxi_pwr_domain_on_finish; sunxi_psci_ops.get_sys_suspend_power_state = sunxi_get_sys_suspend_power_state; - sunxi_psci_ops.get_node_hw_state = sunxi_get_node_hw_state; } else { /* This is only needed when SCPI is unavailable. */ sunxi_psci_ops.pwr_domain_pwr_down_wfi = sunxi_pwr_down_wfi; -- cgit v1.2.3 From 772ef7e7af16cef85c20e24d3e64f52287785ec3 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sat, 16 Jan 2021 01:18:38 -0600 Subject: allwinner: psci: Drop MPIDR check from .pwr_domain_on This duplicated the logic in psci_validate_mpidr() which was already called from psci_cpu_on(). Change-Id: I96ee92f1ce3e9cc2985b4e229ba86ebd27b79915 Signed-off-by: Samuel Holland --- plat/allwinner/common/sunxi_pm.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/plat/allwinner/common/sunxi_pm.c b/plat/allwinner/common/sunxi_pm.c index d750d8c1d..e70d859e3 100644 --- a/plat/allwinner/common/sunxi_pm.c +++ b/plat/allwinner/common/sunxi_pm.c @@ -37,8 +37,6 @@ #define SYSTEM_PWR_STATE(state) \ ((state)->pwr_domain_state[SYSTEM_PWR_LVL]) -#define mpidr_is_valid(mpidr) (plat_core_pos_by_mpidr(mpidr) >= 0) - /* * The addresses for the SCP exception vectors are defined in the or1k * architecture specification. @@ -78,9 +76,6 @@ static void sunxi_cpu_standby(plat_local_state_t cpu_state) static int sunxi_pwr_domain_on(u_register_t mpidr) { - if (mpidr_is_valid(mpidr) == 0) - return PSCI_E_INTERN_FAIL; - if (scpi_available) { scpi_set_css_power_state(mpidr, scpi_power_on, -- cgit v1.2.3 From 814dce8f96fdb82d095b0041a204ba4a272c0913 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sat, 16 Jan 2021 01:21:38 -0600 Subject: allwinner: psci: Invert check in .validate_ns_entrypoint Checking the exceptional case and letting the success case fall through is not only more idiomatic, but it also allows adding more exceptional cases in the future, such as a check for overlapping secure DRAM. Change-Id: I720441a6a8853fd7f211ebe851f14d921a6db03d Signed-off-by: Samuel Holland --- plat/allwinner/common/sunxi_pm.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/plat/allwinner/common/sunxi_pm.c b/plat/allwinner/common/sunxi_pm.c index e70d859e3..aa80c528b 100644 --- a/plat/allwinner/common/sunxi_pm.c +++ b/plat/allwinner/common/sunxi_pm.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 */ @@ -207,10 +207,11 @@ static int sunxi_validate_power_state(unsigned int power_state, static int sunxi_validate_ns_entrypoint(uintptr_t ns_entrypoint) { /* The non-secure entry point must be in DRAM */ - if (ns_entrypoint >= SUNXI_DRAM_BASE) - return PSCI_E_SUCCESS; + if (ns_entrypoint < SUNXI_DRAM_BASE) { + return PSCI_E_INVALID_ADDRESS; + } - return PSCI_E_INVALID_ADDRESS; + return PSCI_E_SUCCESS; } static void sunxi_get_sys_suspend_power_state(psci_power_state_t *req_state) -- cgit v1.2.3 From ed267c92ad46229394323f21d0e431d7c05f5342 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sun, 24 Jan 2021 16:24:12 -0600 Subject: allwinner: Leave CPU power alone during BL31 setup Disabling secondary CPUs during boot is unnecessary because the other CPUs are already in reset, and it saves an entirely insignificant amount of power. Let's remove this bit of code that was added mostly "because we can", and along with it remove an unconditional dependency on the CPU ops functions. Signed-off-by: Samuel Holland Change-Id: Ia77a1b722da6ba989c3992b656a6cde3f2238fd7 --- plat/allwinner/common/sunxi_bl31_setup.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/plat/allwinner/common/sunxi_bl31_setup.c b/plat/allwinner/common/sunxi_bl31_setup.c index 9c8eaa409..b619b18ed 100644 --- a/plat/allwinner/common/sunxi_bl31_setup.c +++ b/plat/allwinner/common/sunxi_bl31_setup.c @@ -100,9 +100,6 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, bl33_image_ep_info.spsr = SPSR_64(MODE_EL2, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); - - /* Turn off all secondary CPUs */ - sunxi_disable_secondary_cpus(read_mpidr()); } void bl31_plat_arch_setup(void) -- cgit v1.2.3 From 12b66a9195067ec93eeeecf330d25e1c94c92bf7 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Fri, 22 Jan 2021 16:05:14 +0800 Subject: doc: maintainers: add scmi server Add maintainer entry for scmi server Signed-off-by: Peng Fan Change-Id: I673d7395a8cea3b553832e330c8a8ce37f8c2a5c --- docs/about/maintainers.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst index 7c91e18b0..99803d98b 100644 --- a/docs/about/maintainers.rst +++ b/docs/about/maintainers.rst @@ -295,6 +295,15 @@ Measured Boot :F: include/drivers/measured_boot :F: plat/arm/board/fvp/fvp_measured_boot.c +System Control and Management Interface (SCMI) Server +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:M: Etienne Carriere +:G: `etienne-lms`_ +:M: Peng Fan +:G: `MrVan`_ +:F: drivers/scmi-msg +:F: include/drivers/scmi\* + Platform Ports ~~~~~~~~~~~~~~ @@ -634,6 +643,7 @@ Build system .. _masahir0y: https://github.com/masahir0y .. _michalsimek: https://github.com/michalsimek .. _mmind: https://github.com/mmind +.. _MrVan: https://github.com/MrVan .. _mtk09422: https://github.com/mtk09422 .. _niej: https://github.com/niej .. _npoushin: https://github.com/npoushin -- cgit v1.2.3 From 1cea02133f84148575687b0f2d0b953a01b9015d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Tue, 26 Jan 2021 10:44:07 +0100 Subject: docs: marvell: Update mv-ddr-marvell and A3700-utils-marvell branches MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Marvell finally started providing the latest version of mv-ddr-marvell and A3700-utils-marvell code in master branch of their git repositories. Reflect this in build instructions. Signed-off-by: Pali Rohár Change-Id: I08d1189dac60eb2a28335c68f611c1da634106f6 --- docs/plat/marvell/armada/build.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/plat/marvell/armada/build.rst b/docs/plat/marvell/armada/build.rst index 29fe4d452..5135831f3 100644 --- a/docs/plat/marvell/armada/build.rst +++ b/docs/plat/marvell/armada/build.rst @@ -307,12 +307,12 @@ Armada37x0 Builds require installation of 3 components > export CROSS_CM3=/opt/arm-cross/bin/arm-linux-gnueabi (2) DDR initialization library sources (mv_ddr) available at the following repository - (use the "mv-ddr-devel" branch): + (use the "master" branch): https://github.com/MarvellEmbeddedProcessors/mv-ddr-marvell.git (3) Armada3700 tools available at the following repository - (use the "A3700_utils-armada-18.12-fixed" branch): + (use the "master" branch): https://github.com/MarvellEmbeddedProcessors/A3700-utils-marvell.git @@ -324,6 +324,6 @@ Armada70x0 and Armada80x0 Builds require installation of an additional component ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (1) DDR initialization library sources (mv_ddr) available at the following repository - (use the "mv-ddr-devel" branch): + (use the "master" branch): https://github.com/MarvellEmbeddedProcessors/mv-ddr-marvell.git -- cgit v1.2.3 From 294e26566b9a7871f90f2712e631a0b8d9f24beb Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Tue, 26 Jan 2021 10:55:49 +0000 Subject: tools: cert_create: Create only requested certificates The certification tool creates all the certificates mentioned statically in the code rather than taking explicit certificate requests from the command line parameters. Code is optimized to avoid unnecessary attempts to create non-requested certificates. Signed-off-by: Manish V Badarkhe Change-Id: I78feac25bc701bf8f08c6aa5a2e1590bec92d0f2 --- tools/cert_create/src/main.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/cert_create/src/main.c b/tools/cert_create/src/main.c index d5abe4917..8a5337742 100644 --- a/tools/cert_create/src/main.c +++ b/tools/cert_create/src/main.c @@ -473,6 +473,11 @@ int main(int argc, char *argv[]) cert = &certs[i]; + if (cert->fn == NULL) { + /* Certificate not requested. Skip to the next one */ + continue; + } + /* Create a new stack of extensions. This stack will be used * to create the certificate */ CHECK_NULL(sk, sk_X509_EXTENSION_new_null()); @@ -534,7 +539,7 @@ int main(int argc, char *argv[]) } /* Create certificate. Signed with corresponding key */ - if (cert->fn && !cert_new(hash_alg, cert, VAL_DAYS, 0, sk)) { + if (!cert_new(hash_alg, cert, VAL_DAYS, 0, sk)) { ERROR("Cannot create %s\n", cert->cn); exit(1); } -- cgit v1.2.3 From 1ed941c0b0ff89980dd421d720ec7d9b00c71d57 Mon Sep 17 00:00:00 2001 From: Jimmy Brisson Date: Wed, 20 Jan 2021 15:34:51 -0600 Subject: cert-tool: avoid duplicates in extension stack This bug manifests itself as a segfault triggered by a double-free. I noticed that right before the double-free, the sk list contained 2 elements with the same address. (gdb) p sk_X509_EXTENSION_value(sk, 1) $34 = (X509_EXTENSION *) 0x431ad0 (gdb) p sk_X509_EXTENSION_value(sk, 0) $35 = (X509_EXTENSION *) 0x431ad0 (gdb) p sk_X509_EXTENSION_num(sk) $36 = 2 This caused confusion; this should never happen. I figured that this was caused by a ext_new_xxxx function freeing something before it is added to the list, so I put a breakpoint on each of them to step through. I was suprised to find that none of my breakpoints triggered for the second element of the iteration through the outer loop just before the double-free. Looking through the code, I noticed that it's possible to avoid doing a ext_new_xxxx, when either: * ext->type == NVCOUNTER and ext->arg == NULL * ext->type == HASH and ext->arg == NULL and ext->optional == false So I put a breakpoint on both. It turns out that it was the HASH version, but I added a fix for both. The fix for the Hash case is simple, as it was a mistake. The fix for the NVCOUNTER case, however, is a bit more subtle. The NVCOUNTER may be optional, and when it's optional we can skip it. The other case, when the NVCOUNTER is required (not optinal), the `check_cmd_params` function has already verified that the `ext->arg` must be non-NULL. We assert that before processing it to covert any possible segfaults into more descriptive errors. This should no longer cause double-frees by adding the same ext twice. Change-Id: Idae2a24ecd964b0a3929e6193c7f85ec769f6470 Signed-off-by: Jimmy Brisson --- tools/cert_create/src/main.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tools/cert_create/src/main.c b/tools/cert_create/src/main.c index 2ba110132..1489cb06e 100644 --- a/tools/cert_create/src/main.c +++ b/tools/cert_create/src/main.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 */ @@ -492,7 +492,12 @@ int main(int argc, char *argv[]) */ switch (ext->type) { case EXT_TYPE_NVCOUNTER: - if (ext->arg) { + if (ext->optional && ext->arg == NULL) { + /* Skip this NVCounter */ + continue; + } else { + /* Checked by `check_cmd_params` */ + assert(ext->arg != NULL); nvctr = atoi(ext->arg); CHECK_NULL(cert_ext, ext_new_nvcounter(ext_nid, EXT_CRIT, nvctr)); @@ -505,7 +510,7 @@ int main(int argc, char *argv[]) memset(md, 0x0, SHA512_DIGEST_LENGTH); } else { /* Do not include this hash in the certificate */ - break; + continue; } } else { /* Calculate the hash of the file */ -- cgit v1.2.3 From fcb0ea19af70c781982b96c407afe2d6bc6d0efd Mon Sep 17 00:00:00 2001 From: Nikos Nikoleris Date: Thu, 21 Jan 2021 13:50:25 +0000 Subject: fdts: Fix stdout-path in various platforms The value of stdout-path is a string and as a result, we can't use a label as a reference to the serial0 node. This change fixes the stdout-path property for N1SDP, Morello and TC0 by pointing to the right alias. Signed-off-by: Nikos Nikoleris Change-Id: I3d403389a424569be56327fab4140fec06f96d37 --- fdts/morello-fvp.dts | 2 +- fdts/n1sdp-single-chip.dts | 2 +- fdts/tc0.dts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/fdts/morello-fvp.dts b/fdts/morello-fvp.dts index 699dc2346..dda73f1c2 100644 --- a/fdts/morello-fvp.dts +++ b/fdts/morello-fvp.dts @@ -10,7 +10,7 @@ / { chosen { - stdout-path = "soc_uart0:115200n8"; + stdout-path = "serial0:115200n8"; }; reserved-memory { diff --git a/fdts/n1sdp-single-chip.dts b/fdts/n1sdp-single-chip.dts index bd4827381..3c091ac40 100644 --- a/fdts/n1sdp-single-chip.dts +++ b/fdts/n1sdp-single-chip.dts @@ -16,7 +16,7 @@ }; chosen { - stdout-path = "soc_uart0:115200n8"; + stdout-path = "serial0:115200n8"; }; /* This configuration assumes that standard setup with two DIMM modules. diff --git a/fdts/tc0.dts b/fdts/tc0.dts index 543847405..f1ade19e6 100644 --- a/fdts/tc0.dts +++ b/fdts/tc0.dts @@ -17,7 +17,7 @@ }; chosen { - stdout-path = "soc_uart0:115200n8"; + stdout-path = "serial0:115200n8"; }; cpus { -- cgit v1.2.3 From edb4a8a29430772bc9db25e6cb5f9386b42b1162 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Tue, 26 Jan 2021 10:44:07 +0100 Subject: plat: marvell: armada: a3k: Add checks that WTP, MV_DDR_PATH and CRYPTOPP_PATH are correctly defined MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These variables must contain a path to a valid directory (not a file) which really exists. Also WTP and MV_DDR_PATH must point to either a valid Marvell release tarball or git repository. Signed-off-by: Pali Rohár Change-Id: I1ad80c41092cf3ea6a625426df62b7d9d6f37815 --- plat/marvell/armada/a3k/common/a3700_common.mk | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk index 824a3c690..452d9d220 100644 --- a/plat/marvell/armada/a3k/common/a3700_common.mk +++ b/plat/marvell/armada/a3k/common/a3700_common.mk @@ -71,6 +71,9 @@ endif ifdef WTP +$(if $(wildcard $(value WTP)/*),,$(error "'WTP=$(value WTP)' was specified, but '$(value WTP)' directory does not exist")) +$(if $(shell test -s "$(value WTP)/branch.txt" || git -C $(value WTP) rev-parse --show-cdup 2>&1),$(error "'WTP=$(value WTP)' was specified, but '$(value WTP)' does not contain valid Marvell a3700_utils release tarball nor git repository")) + DOIMAGEPATH := $(WTP) DOIMAGETOOL := $(DOIMAGEPATH)/wtptp/src/TBB_Linux/release/TBB_linux @@ -130,6 +133,7 @@ DOIMAGE_FLAGS := -r $(DOIMAGE_CFG) -v -D $(DOIMAGETOOL): FORCE $(if $(value CRYPTOPP_PATH),,$(error "Platform '${PLAT}' for WTP image tool requires CRYPTOPP_PATH. Please set CRYPTOPP_PATH to point to the right directory")) + $(if $(wildcard $(value CRYPTOPP_PATH)/*),,$(error "'CRYPTOPP_PATH=$(value CRYPTOPP_PATH)' was specified, but '$(value CRYPTOPP_PATH)' directory does not exist")) $(Q)$(MAKE) --no-print-directory -C $(CRYPTOPP_PATH) -f GNUmakefile $(Q)$(MAKE) --no-print-directory -C $(DOIMAGEPATH)/wtptp/src/TBB_Linux -f TBB_linux.mak LIBDIR=$(CRYPTOPP_PATH) @@ -138,6 +142,8 @@ $(WTMI_MULTI_IMG): FORCE $(TIMDDRTOOL): FORCE $(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 test -s "$(value MV_DDR_PATH)/branch.txt" || 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 Marvell mv_ddr release tarball nor git repository")) $(Q)$(MAKE) --no-print-directory -C $(DOIMAGEPATH) MV_DDR_PATH=$(MV_DDR_PATH) mv_ddr .PHONY: mrvl_flash -- cgit v1.2.3 From 494be3ee0efbca70f4218d7eeb9af7225c9c1d58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Tue, 26 Jan 2021 10:44:07 +0100 Subject: docs: marvell: Update info about WTP and MV_DDR_PATH parameters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pali Rohár Change-Id: Id5e36b7ba3a840cb3598c580e806b52d8e8dd70f --- docs/plat/marvell/armada/build.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/plat/marvell/armada/build.rst b/docs/plat/marvell/armada/build.rst index 5135831f3..4995bb57e 100644 --- a/docs/plat/marvell/armada/build.rst +++ b/docs/plat/marvell/armada/build.rst @@ -123,6 +123,9 @@ There are several build options: For the mv_ddr source location, check the section "Tools and external components installation" + If MV_DDR_PATH source code is a git snapshot then provide path to the full git + repository (including .git subdir) because mv_ddr build process calls git commands. + - CP_NUM Total amount of CPs (South Bridge) connected to AP. When the parameter is omitted, @@ -194,6 +197,9 @@ There are several build options: directory, which can be found as a3700_utils.zip in the release. Usage example: ``WTP=/path/to/a3700_utils`` + If WTP source code is a git snapshot then provide path to the full git + repository (including .git subdir) because WTP build process calls git commands. + - CRYPTOPP_PATH For Armada37x0 only, use this parameter tp point to Crypto++ source code -- cgit v1.2.3 From c2d32a5f85a5889742cb7a971558944ecf330936 Mon Sep 17 00:00:00 2001 From: Madhukar Pappireddy Date: Fri, 24 Jul 2020 03:27:12 -0500 Subject: Fix exception handlers in BL31: Use DSB to synchronize pending EA For SoCs which do not implement RAS, use DSB as a barrier to synchronize pending external aborts at the entry and exit of exception handlers. This is needed to isolate the SErrors to appropriate context. However, this introduces an unintended side effect as discussed in the https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/3440 A summary of the side effect and a quick workaround is provided as part of this patch and summarized here: The explicit DSB at the entry of various exception vectors in BL31 for handling exceptions from lower ELs can inadvertently trigger an SError exception in EL3 due to pending asyncrhonouus aborts in lower ELs. This will end up being handled by serror_sp_elx in EL3 which will ultimately panic and die. The way to workaround is to update a flag to indicate if the exception truly came from EL3. This flag is allocated in the cpu_context structure. This is not a bullet proof solution to the problem at hand because we assume the instructions following "isb" that help to update the flag (lines 100-102 & 139-141) execute without causing further exceptions. Change-Id: I4d345b07d746a727459435ddd6abb37fda24a9bf Signed-off-by: Madhukar Pappireddy --- bl31/aarch64/ea_delegate.S | 4 +- bl31/aarch64/runtime_exceptions.S | 94 ++++++++++++++++++++++++++++++- include/lib/el3_runtime/aarch64/context.h | 5 +- lib/el3_runtime/aarch64/context.S | 7 ++- 4 files changed, 103 insertions(+), 7 deletions(-) diff --git a/bl31/aarch64/ea_delegate.S b/bl31/aarch64/ea_delegate.S index 1d28d5e0f..f9c789f54 100644 --- a/bl31/aarch64/ea_delegate.S +++ b/bl31/aarch64/ea_delegate.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, 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,6 +15,7 @@ #include .globl handle_lower_el_ea_esb + .globl handle_lower_el_async_ea .globl enter_lower_el_sync_ea .globl enter_lower_el_async_ea @@ -133,6 +134,7 @@ func enter_lower_el_async_ea */ str x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR] +handle_lower_el_async_ea: /* * Save general purpose and ARMv8.3-PAuth registers (if enabled). * If Secure Cycle Counter is not disabled in MDCR_EL3 when diff --git a/bl31/aarch64/runtime_exceptions.S b/bl31/aarch64/runtime_exceptions.S index bfe13f312..51eb2bd47 100644 --- a/bl31/aarch64/runtime_exceptions.S +++ b/bl31/aarch64/runtime_exceptions.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 */ @@ -45,8 +45,9 @@ * instruction. When an error is thus synchronized, the handling is * delegated to platform EA handler. * - * Without RAS_EXTENSION, this macro just saves x30, and unmasks - * Asynchronous External Aborts. + * Without RAS_EXTENSION, this macro synchronizes pending errors using + * a DSB, unmasks Asynchronous External Aborts and saves X30 before + * setting the flag CTX_IS_IN_EL3. */ .macro check_and_unmask_ea #if RAS_EXTENSION @@ -79,13 +80,89 @@ bl restore_gp_pmcr_pauth_regs 1: #else + /* + * For SoCs which do not implement RAS, use DSB as a barrier to + * synchronize pending external aborts. + */ + dsb sy + /* Unmask the SError interrupt */ msr daifclr, #DAIF_ABT_BIT + /* Use ISB for the above unmask operation to take effect immediately */ + isb + + /* + * Refer Note 1. No need to restore X30 as both handle_sync_exception + * and handle_interrupt_exception macro which follow this macro modify + * X30 anyway. + */ str x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR] + mov x30, #1 + str x30, [sp, #CTX_EL3STATE_OFFSET + CTX_IS_IN_EL3] + dmb sy #endif .endm +#if !RAS_EXTENSION + /* + * Note 1: The explicit DSB at the entry of various exception vectors + * for handling exceptions from lower ELs can inadvertently trigger an + * SError exception in EL3 due to pending asynchronous aborts in lower + * ELs. This will end up being handled by serror_sp_elx which will + * ultimately panic and die. + * The way to workaround is to update a flag to indicate if the exception + * truly came from EL3. This flag is allocated in the cpu_context + * structure and located at offset "CTX_EL3STATE_OFFSET + CTX_IS_IN_EL3" + * This is not a bullet proof solution to the problem at hand because + * we assume the instructions following "isb" that help to update the + * flag execute without causing further exceptions. + */ + + /* --------------------------------------------------------------------- + * This macro handles Asynchronous External Aborts. + * --------------------------------------------------------------------- + */ + .macro handle_async_ea + /* + * Use a barrier to synchronize pending external aborts. + */ + dsb sy + + /* Unmask the SError interrupt */ + msr daifclr, #DAIF_ABT_BIT + + /* Use ISB for the above unmask operation to take effect immediately */ + isb + + /* Refer Note 1 */ + str x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR] + mov x30, #1 + str x30, [sp, #CTX_EL3STATE_OFFSET + CTX_IS_IN_EL3] + dmb sy + + b handle_lower_el_async_ea + .endm + + /* + * This macro checks if the exception was taken due to SError in EL3 or + * because of pending asynchronous external aborts from lower EL that got + * triggered due to explicit synchronization in EL3. Refer Note 1. + */ + .macro check_if_serror_from_EL3 + /* Assumes SP_EL3 on entry */ + str x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR] + ldr x30, [sp, #CTX_EL3STATE_OFFSET + CTX_IS_IN_EL3] + cbnz x30, exp_from_EL3 + + /* Handle asynchronous external abort from lower EL */ + b handle_lower_el_async_ea + +exp_from_EL3: + /* Jump to plat_handle_el3_ea which does not return */ + .endm +#endif + /* --------------------------------------------------------------------- * This macro handles Synchronous exceptions. * Only SMC exceptions are supported. @@ -272,6 +349,9 @@ vector_entry fiq_sp_elx end_vector_entry fiq_sp_elx vector_entry serror_sp_elx +#if !RAS_EXTENSION + check_if_serror_from_EL3 +#endif no_ret plat_handle_el3_ea end_vector_entry serror_sp_elx @@ -305,8 +385,12 @@ end_vector_entry fiq_aarch64 vector_entry serror_aarch64 apply_at_speculative_wa +#if RAS_EXTENSION msr daifclr, #DAIF_ABT_BIT b enter_lower_el_async_ea +#else + handle_async_ea +#endif end_vector_entry serror_aarch64 /* --------------------------------------------------------------------- @@ -339,8 +423,12 @@ end_vector_entry fiq_aarch32 vector_entry serror_aarch32 apply_at_speculative_wa +#if RAS_EXTENSION msr daifclr, #DAIF_ABT_BIT b enter_lower_el_async_ea +#else + handle_async_ea +#endif end_vector_entry serror_aarch32 #ifdef MONITOR_TRAPS diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h index 349041432..3135fb45b 100644 --- a/include/lib/el3_runtime/aarch64/context.h +++ b/include/lib/el3_runtime/aarch64/context.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 */ @@ -60,7 +60,8 @@ #define CTX_SPSR_EL3 U(0x18) #define CTX_ELR_EL3 U(0x20) #define CTX_PMCR_EL0 U(0x28) -#define CTX_EL3STATE_END U(0x30) +#define CTX_IS_IN_EL3 U(0x30) +#define CTX_EL3STATE_END U(0x40) /* Align to the next 16 byte boundary */ /******************************************************************************* * Constants that allow assembler code to access members of and the diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S index 773082a85..75e214d9c 100644 --- a/lib/el3_runtime/aarch64/context.S +++ b/lib/el3_runtime/aarch64/context.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 */ @@ -995,6 +995,11 @@ func el3_exit * ---------------------------------------------------------- */ esb +#else + dsb sy +#endif +#ifdef IMAGE_BL31 + str xzr, [sp, #CTX_EL3STATE_OFFSET + CTX_IS_IN_EL3] #endif exception_return -- cgit v1.2.3 From 8708a884ae227f0d37618db7f50f6dd66cfaeaef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Tue, 26 Jan 2021 10:44:07 +0100 Subject: plat: marvell: armada: a3k: Allow use of the system Crypto++ library MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change introduces two new A3720 parameters, CRYPTOPP_LIBDIR and CRYPTOPP_INCDIR, which can be used to specify directory paths to pre-compiled Crypto++ library and header files. When both new parameters are specified then the source code of Crypto++ via CRYPTOPP_PATH parameter is not needed. And therefore it allows TF-A build process to use system Crypto++ library. Signed-off-by: Pali Rohár Change-Id: I6d440f86153373b11b8d098bb68eb7325e86b20b --- docs/plat/marvell/armada/build.rst | 17 +++++++++++++++-- plat/marvell/armada/a3k/common/a3700_common.mk | 15 +++++++++++---- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/docs/plat/marvell/armada/build.rst b/docs/plat/marvell/armada/build.rst index 4995bb57e..d22477941 100644 --- a/docs/plat/marvell/armada/build.rst +++ b/docs/plat/marvell/armada/build.rst @@ -202,8 +202,21 @@ There are several build options: - CRYPTOPP_PATH - For Armada37x0 only, use this parameter tp point to Crypto++ source code - directory, which is required for building WTP image tool. + For Armada37x0 only, use this parameter to point to Crypto++ source code + directory. If this option is specified then Crypto++ source code in + CRYPTOPP_PATH directory will be automatically compiled. Crypto++ library + is required for building WTP image tool. Either CRYPTOPP_PATH or + CRYPTOPP_LIBDIR with CRYPTOPP_INCDIR needs to be specified for Armada37x0. + +- CRYPTOPP_LIBDIR + + For Armada37x0 only, use this parameter to point to the directory with + compiled Crypto++ library. By default it points to the CRYPTOPP_PATH. + +- CRYPTOPP_INCDIR + + For Armada37x0 only, use this parameter to point to the directory with + header files of Crypto++ library. By default it points to the CRYPTOPP_PATH. For example, in order to build the image in debug mode with log level up to 'notice' level run diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk index 452d9d220..7a798a94d 100644 --- a/plat/marvell/armada/a3k/common/a3700_common.mk +++ b/plat/marvell/armada/a3k/common/a3700_common.mk @@ -131,11 +131,18 @@ TIMBLDUARTARGS := $(MARVELL_SECURE_BOOT) UART $(IMAGESPATH) $(DOIMAGEPATH) $(CL $(DDR_TOPOLOGY) 0 0 $(DOIMAGE_CFG) $(TIMNCFG) $(TIMNSIG) 0 DOIMAGE_FLAGS := -r $(DOIMAGE_CFG) -v -D +CRYPTOPP_LIBDIR ?= $(CRYPTOPP_PATH) +CRYPTOPP_INCDIR ?= $(CRYPTOPP_PATH) + $(DOIMAGETOOL): FORCE - $(if $(value CRYPTOPP_PATH),,$(error "Platform '${PLAT}' for WTP image tool requires CRYPTOPP_PATH. Please set CRYPTOPP_PATH to point to the right directory")) - $(if $(wildcard $(value CRYPTOPP_PATH)/*),,$(error "'CRYPTOPP_PATH=$(value CRYPTOPP_PATH)' was specified, but '$(value CRYPTOPP_PATH)' directory does not exist")) + $(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")) + $(if $(wildcard $(CRYPTOPP_INCDIR)/*),,$(error "Either 'CRYPTOPP_PATH' or 'CRYPTOPP_INCDIR' was set to '$(CRYPTOPP_INCDIR)', but '$(CRYPTOPP_INCDIR)' does not exist")) +ifdef CRYPTOPP_PATH $(Q)$(MAKE) --no-print-directory -C $(CRYPTOPP_PATH) -f GNUmakefile - $(Q)$(MAKE) --no-print-directory -C $(DOIMAGEPATH)/wtptp/src/TBB_Linux -f TBB_linux.mak LIBDIR=$(CRYPTOPP_PATH) +endif + $(Q)$(MAKE) --no-print-directory -C $(DOIMAGEPATH)/wtptp/src/TBB_Linux -f TBB_linux.mak LIBDIR=$(CRYPTOPP_LIBDIR) INCDIR=$(CRYPTOPP_INCDIR) $(WTMI_MULTI_IMG): FORCE $(Q)$(MAKE) --no-print-directory -C $(DOIMAGEPATH) WTMI_IMG=$(WTMI_IMG) WTMI @@ -206,7 +213,7 @@ clean realclean distclean: mrvl_clean .PHONY: mrvl_clean mrvl_clean: -$(Q)$(MAKE) --no-print-directory -C $(DOIMAGEPATH) MV_DDR_PATH=$(MV_DDR_PATH) clean - -$(Q)$(MAKE) --no-print-directory -C $(DOIMAGEPATH)/wtptp/src/TBB_Linux -f TBB_linux.mak LIBDIR=$(CRYPTOPP_PATH) clean + -$(Q)$(MAKE) --no-print-directory -C $(DOIMAGEPATH)/wtptp/src/TBB_Linux -f TBB_linux.mak clean ifdef CRYPTOPP_PATH -$(Q)$(MAKE) --no-print-directory -C $(CRYPTOPP_PATH) -f GNUmakefile clean endif -- cgit v1.2.3 From b50c715b9278e73d109500fc68ccc298c99aeb2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Tue, 26 Jan 2021 10:44:07 +0100 Subject: plat: marvell: armada: a3k: Correctly set DDR_TOPOLOGY and CLOCKSPRESET for WTMI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When building WTMI image we need to correctly set DDR_TOPOLOGY and CLOCKSPRESET variables which WTMI build system expect. Otherwise it use default values. Signed-off-by: Pali Rohár Change-Id: Ib83002194c8a6c64a2014899ac049bd319e1652f --- plat/marvell/armada/a3k/common/a3700_common.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk index 7a798a94d..ab007cf9c 100644 --- a/plat/marvell/armada/a3k/common/a3700_common.mk +++ b/plat/marvell/armada/a3k/common/a3700_common.mk @@ -145,13 +145,13 @@ endif $(Q)$(MAKE) --no-print-directory -C $(DOIMAGEPATH)/wtptp/src/TBB_Linux -f TBB_linux.mak LIBDIR=$(CRYPTOPP_LIBDIR) INCDIR=$(CRYPTOPP_INCDIR) $(WTMI_MULTI_IMG): FORCE - $(Q)$(MAKE) --no-print-directory -C $(DOIMAGEPATH) WTMI_IMG=$(WTMI_IMG) WTMI + $(Q)$(MAKE) --no-print-directory -C $(DOIMAGEPATH) WTMI_IMG=$(WTMI_IMG) DDR_TOPOLOGY=$(DDR_TOPOLOGY) CLOCKSPRESET=$(CLOCKSPRESET) WTMI $(TIMDDRTOOL): FORCE $(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 test -s "$(value MV_DDR_PATH)/branch.txt" || 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 Marvell mv_ddr release tarball nor git repository")) - $(Q)$(MAKE) --no-print-directory -C $(DOIMAGEPATH) MV_DDR_PATH=$(MV_DDR_PATH) mv_ddr + $(Q)$(MAKE) --no-print-directory -C $(DOIMAGEPATH) MV_DDR_PATH=$(MV_DDR_PATH) DDR_TOPOLOGY=$(DDR_TOPOLOGY) mv_ddr .PHONY: mrvl_flash mrvl_flash: ${BUILD_PLAT}/${BOOT_IMAGE} ${WTMI_MULTI_IMG} ${DOIMAGETOOL} ${TIMBUILD} -- cgit v1.2.3 From d4dc8311f31616a4d62dcf5b03bc7883011a16ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Tue, 26 Jan 2021 10:44:07 +0100 Subject: plat: marvell: armada: a3k: Build intermediate files in $(BUILD_PLAT) directory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently a3700_common.mk makefile builds intermediate files in TF-A top level directory and also outside of the TF-A tree. This change fixes this issue and builds all intermediate files in $(BUILD_PLAT) directory. Part of this change is also removal of 'rm' and 'mv' commands as there is no need to remove or move intermediate files from outside of the TF-A build tree. Signed-off-by: Pali Rohár Change-Id: I72e3a3024bd3fdba1b991a220184d750029491e9 --- plat/marvell/armada/a3k/common/a3700_common.mk | 65 +++++++++++++------------- 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk index ab007cf9c..471076bc3 100644 --- a/plat/marvell/armada/a3k/common/a3700_common.mk +++ b/plat/marvell/armada/a3k/common/a3700_common.mk @@ -78,15 +78,14 @@ DOIMAGEPATH := $(WTP) DOIMAGETOOL := $(DOIMAGEPATH)/wtptp/src/TBB_Linux/release/TBB_linux ifeq ($(MARVELL_SECURE_BOOT),1) -DOIMAGE_CFG := $(DOIMAGEPATH)/atf-tim.txt +DOIMAGE_CFG := $(BUILD_PLAT)/atf-tim.txt IMAGESPATH := $(DOIMAGEPATH)/tim/trusted - -TIMNCFG := $(DOIMAGEPATH)/atf-timN.txt +TIMNCFG := $(BUILD_PLAT)/atf-timN.txt TIMNSIG := $(IMAGESPATH)/timnsign.txt TIM2IMGARGS := -i $(DOIMAGE_CFG) -n $(TIMNCFG) TIMN_IMAGE := $$(grep "Image Filename:" -m 1 $(TIMNCFG) | cut -c 17-) else #MARVELL_SECURE_BOOT -DOIMAGE_CFG := $(DOIMAGEPATH)/atf-ntim.txt +DOIMAGE_CFG := $(BUILD_PLAT)/atf-ntim.txt IMAGESPATH := $(DOIMAGEPATH)/tim/untrusted TIM2IMGARGS := -i $(DOIMAGE_CFG) endif #MARVELL_SECURE_BOOT @@ -112,7 +111,7 @@ WTMI_SYSINIT_IMG := $(DOIMAGEPATH)/wtmi/sys_init/build/sys_init.bin # and sys-init image (WTMI_SYSINIT_IMG). WTMI_MULTI_IMG := $(DOIMAGEPATH)/wtmi/build/wtmi.bin -WTMI_ENC_IMG := $(BUILD_PLAT)/wtmi-enc.bin +WTMI_ENC_IMG := wtmi-enc.bin BUILD_UART := uart-images SRCPATH := $(dir $(BL33)) @@ -147,6 +146,9 @@ endif $(WTMI_MULTI_IMG): FORCE $(Q)$(MAKE) --no-print-directory -C $(DOIMAGEPATH) WTMI_IMG=$(WTMI_IMG) DDR_TOPOLOGY=$(DDR_TOPOLOGY) CLOCKSPRESET=$(CLOCKSPRESET) WTMI +$(BUILD_PLAT)/wtmi.bin: $(WTMI_MULTI_IMG) + $(Q)cp -a $(WTMI_MULTI_IMG) $(BUILD_PLAT)/wtmi.bin + $(TIMDDRTOOL): FORCE $(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")) @@ -154,39 +156,41 @@ $(TIMDDRTOOL): FORCE $(Q)$(MAKE) --no-print-directory -C $(DOIMAGEPATH) MV_DDR_PATH=$(MV_DDR_PATH) DDR_TOPOLOGY=$(DDR_TOPOLOGY) mv_ddr .PHONY: mrvl_flash -mrvl_flash: ${BUILD_PLAT}/${BOOT_IMAGE} ${WTMI_MULTI_IMG} ${DOIMAGETOOL} ${TIMBUILD} +mrvl_flash: ${BUILD_PLAT}/${BOOT_IMAGE} ${BUILD_PLAT}/wtmi.bin ${DOIMAGETOOL} ${TIMBUILD} @echo @echo "Building uart images" - $(TIMBUILD) $(TIMBLDUARTARGS) - @sed -i 's|WTMI_IMG|$(WTMI_MULTI_IMG)|1' $(DOIMAGE_CFG) - @sed -i 's|BOOT_IMAGE|$(BUILD_PLAT)/$(BOOT_IMAGE)|1' $(DOIMAGE_CFG) + @cd $(BUILD_PLAT)/$(BUILD_UART) && $(TIMBUILD) $(TIMBLDUARTARGS) + @sed -i 's|WTMI_IMG|wtmi.bin|1' $(DOIMAGE_CFG) + @sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(DOIMAGE_CFG) +ifeq ($(MARVELL_SECURE_BOOT),1) + @sed -i 's|WTMI_IMG|wtmi.bin|1' $(TIMNCFG) + @sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(TIMNCFG) +endif + cd $(BUILD_PLAT) && $(DOIMAGETOOL) $(DOIMAGE_FLAGS) ifeq ($(MARVELL_SECURE_BOOT),1) - @sed -i 's|WTMI_IMG|$(WTMI_MULTI_IMG)|1' $(TIMNCFG) - @sed -i 's|BOOT_IMAGE|$(BUILD_PLAT)/$(BOOT_IMAGE)|1' $(TIMNCFG) + @cd $(BUILD_PLAT) && $(DOIMAGETOOL) -r $(TIMNCFG) endif - $(DOIMAGETOOL) $(DOIMAGE_FLAGS) - @if [ -e "$(TIMNCFG)" ]; then $(DOIMAGETOOL) -r $(TIMNCFG); fi @rm -rf $(BUILD_PLAT)/$(BUILD_UART)* @mkdir $(BUILD_PLAT)/$(BUILD_UART) - @mv -t $(BUILD_PLAT)/$(BUILD_UART) $(TIM_IMAGE) $(DOIMAGE_CFG) $(TIMN_IMAGE) $(TIMNCFG) - @find . -name "*_h.*" |xargs cp -ut $(BUILD_PLAT)/$(BUILD_UART) - @mv $(subst .bin,_h.bin,$(WTMI_MULTI_IMG)) $(BUILD_PLAT)/$(BUILD_UART)/wtmi_h.bin + @cd $(BUILD_PLAT) && mv -t $(BUILD_PLAT)/$(BUILD_UART) $(TIM_IMAGE) $(DOIMAGE_CFG) $(TIMN_IMAGE) $(TIMNCFG) + @find $(BUILD_PLAT) -name "*_h.*" |xargs cp -ut $(BUILD_PLAT)/$(BUILD_UART) + @cd $(BUILD_PLAT) && mv $(subst .bin,_h.bin,$(WTMI_MULTI_IMG)) $(BUILD_PLAT)/$(BUILD_UART)/wtmi_h.bin @tar czf $(BUILD_PLAT)/$(BUILD_UART).tgz.bin -C $(BUILD_PLAT) ./$(BUILD_UART) @echo @echo "Building flash image" - $(TIMBUILD) $(TIMBLDARGS) - sed -i 's|WTMI_IMG|$(WTMI_MULTI_IMG)|1' $(DOIMAGE_CFG) - sed -i 's|BOOT_IMAGE|$(BUILD_PLAT)/$(BOOT_IMAGE)|1' $(DOIMAGE_CFG) + cd $(BUILD_PLAT) && $(TIMBUILD) $(TIMBLDARGS) + sed -i 's|WTMI_IMG|wtmi.bin|1' $(DOIMAGE_CFG) + sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(DOIMAGE_CFG) ifeq ($(MARVELL_SECURE_BOOT),1) - @sed -i 's|WTMI_IMG|$(WTMI_MULTI_IMG)|1' $(TIMNCFG) - @sed -i 's|BOOT_IMAGE|$(BUILD_PLAT)/$(BOOT_IMAGE)|1' $(TIMNCFG) + @sed -i 's|WTMI_IMG|wtmi.bin|1' $(TIMNCFG) + @sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(TIMNCFG) @echo -e "\n\t=======================================================\n"; @echo -e "\t Secure boot. Encrypting wtmi and boot-image \n"; @echo -e "\t=======================================================\n"; - @cp $(WTMI_MULTI_IMG) $(BUILD_PLAT)/wtmi-align.bin + @cp $(BUILD_PLAT)/wtmi.bin $(BUILD_PLAT)/wtmi-align.bin @truncate -s %16 $(BUILD_PLAT)/wtmi-align.bin @openssl enc -aes-256-cbc -e -in $(BUILD_PLAT)/wtmi-align.bin \ - -out $(WTMI_ENC_IMG) \ + -out $(BUILD_PLAT)/$(WTMI_ENC_IMG) \ -K `cat $(IMAGESPATH)/aes-256.txt` -nosalt \ -iv `cat $(IMAGESPATH)/iv.txt` -p @truncate -s %16 $(BUILD_PLAT)/$(BOOT_IMAGE); @@ -195,18 +199,13 @@ ifeq ($(MARVELL_SECURE_BOOT),1) -K `cat $(IMAGESPATH)/aes-256.txt` -nosalt \ -iv `cat $(IMAGESPATH)/iv.txt` -p endif - $(DOIMAGETOOL) $(DOIMAGE_FLAGS) - @if [ -e "$(TIMNCFG)" ]; then $(DOIMAGETOOL) -r $(TIMNCFG); fi -ifeq ($(MARVELL_SECURE_BOOT),1) - @sed -i 's|$(WTMI_MULTI_IMG)|$(WTMI_ENC_IMG)|1;s|$(BOOT_IMAGE)|$(BOOT_ENC_IMAGE)|1;' $(TIMNCFG) -endif - $(TIM2IMG) $(TIM2IMGARGS) -o $(BUILD_PLAT)/$(FLASH_IMAGE) - @mv -t $(BUILD_PLAT) $(TIM_IMAGE) $(DOIMAGE_CFG) $(TIMN_IMAGE) $(TIMNCFG) - @cp -t $(BUILD_PLAT) $(WTMI_IMG) $(WTMI_SYSINIT_IMG) $(WTMI_MULTI_IMG) + cd $(BUILD_PLAT) && $(DOIMAGETOOL) $(DOIMAGE_FLAGS) ifeq ($(MARVELL_SECURE_BOOT),1) - @mv -t $(BUILD_PLAT) OtpHash.txt + @cd $(BUILD_PLAT) && $(DOIMAGETOOL) -r $(TIMNCFG) + @sed -i 's|wtmi.bin|$(WTMI_ENC_IMG)|1' $(TIMNCFG) + @sed -i 's|$(BOOT_IMAGE)|$(BOOT_ENC_IMAGE)|1' $(TIMNCFG) endif - @find . -name "*.txt" | grep -E "CSK[[:alnum:]]_KeyHash.txt|Tim_msg.txt|TIMHash.txt" | xargs rm -f + cd $(BUILD_PLAT) && $(TIM2IMG) $(TIM2IMGARGS) -o $(BUILD_PLAT)/$(FLASH_IMAGE) clean realclean distclean: mrvl_clean -- cgit v1.2.3 From 57987415b712ede3003a436479eb62cdb4def326 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Tue, 26 Jan 2021 10:44:07 +0100 Subject: plat: marvell: armada: a3k: Build UART image files directly in $(BUILD_UART) subdirectory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This removes need to move files and also allows to build uart and flash images in parallel. Signed-off-by: Pali Rohár Change-Id: I13bea547d7849615e1c1e11d333c8c99e568d3f6 --- plat/marvell/armada/a3k/common/a3700_common.mk | 33 +++++++++++++------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk index 471076bc3..912302027 100644 --- a/plat/marvell/armada/a3k/common/a3700_common.mk +++ b/plat/marvell/armada/a3k/common/a3700_common.mk @@ -77,15 +77,20 @@ $(if $(shell test -s "$(value WTP)/branch.txt" || git -C $(value WTP) rev-parse DOIMAGEPATH := $(WTP) DOIMAGETOOL := $(DOIMAGEPATH)/wtptp/src/TBB_Linux/release/TBB_linux +BUILD_UART := uart-images + ifeq ($(MARVELL_SECURE_BOOT),1) DOIMAGE_CFG := $(BUILD_PLAT)/atf-tim.txt +DOIMAGEUART_CFG := $(BUILD_PLAT)/$(BUILD_UART)/atf-tim.txt IMAGESPATH := $(DOIMAGEPATH)/tim/trusted TIMNCFG := $(BUILD_PLAT)/atf-timN.txt +TIMNUARTCFG := $(BUILD_PLAT)/$(BUILD_UART)/atf-timN.txt TIMNSIG := $(IMAGESPATH)/timnsign.txt TIM2IMGARGS := -i $(DOIMAGE_CFG) -n $(TIMNCFG) TIMN_IMAGE := $$(grep "Image Filename:" -m 1 $(TIMNCFG) | cut -c 17-) else #MARVELL_SECURE_BOOT DOIMAGE_CFG := $(BUILD_PLAT)/atf-ntim.txt +DOIMAGEUART_CFG := $(BUILD_PLAT)/$(BUILD_UART)/atf-ntim.txt IMAGESPATH := $(DOIMAGEPATH)/tim/untrusted TIM2IMGARGS := -i $(DOIMAGE_CFG) endif #MARVELL_SECURE_BOOT @@ -112,7 +117,6 @@ WTMI_SYSINIT_IMG := $(DOIMAGEPATH)/wtmi/sys_init/build/sys_init.bin WTMI_MULTI_IMG := $(DOIMAGEPATH)/wtmi/build/wtmi.bin WTMI_ENC_IMG := wtmi-enc.bin -BUILD_UART := uart-images SRCPATH := $(dir $(BL33)) @@ -127,8 +131,7 @@ TIM_IMAGE := $$(grep "Image Filename:" -m 1 $(DOIMAGE_CFG) | cut -c 17-) TIMBLDARGS := $(MARVELL_SECURE_BOOT) $(BOOTDEV) $(IMAGESPATH) $(DOIMAGEPATH) $(CLOCKSPRESET) \ $(DDR_TOPOLOGY) $(PARTNUM) $(DEBUG) $(DOIMAGE_CFG) $(TIMNCFG) $(TIMNSIG) 1 TIMBLDUARTARGS := $(MARVELL_SECURE_BOOT) UART $(IMAGESPATH) $(DOIMAGEPATH) $(CLOCKSPRESET) \ - $(DDR_TOPOLOGY) 0 0 $(DOIMAGE_CFG) $(TIMNCFG) $(TIMNSIG) 0 -DOIMAGE_FLAGS := -r $(DOIMAGE_CFG) -v -D + $(DDR_TOPOLOGY) 0 0 $(DOIMAGEUART_CFG) $(TIMNUARTCFG) $(TIMNSIG) 0 CRYPTOPP_LIBDIR ?= $(CRYPTOPP_PATH) CRYPTOPP_INCDIR ?= $(CRYPTOPP_PATH) @@ -159,23 +162,21 @@ $(TIMDDRTOOL): FORCE mrvl_flash: ${BUILD_PLAT}/${BOOT_IMAGE} ${BUILD_PLAT}/wtmi.bin ${DOIMAGETOOL} ${TIMBUILD} @echo @echo "Building uart images" + @mkdir -p $(BUILD_PLAT)/$(BUILD_UART) + @cp -a $(BUILD_PLAT)/wtmi.bin $(BUILD_PLAT)/$(BUILD_UART)/wtmi.bin + @cp -a $(BUILD_PLAT)/$(BOOT_IMAGE) $(BUILD_PLAT)/$(BUILD_UART)/$(BOOT_IMAGE) @cd $(BUILD_PLAT)/$(BUILD_UART) && $(TIMBUILD) $(TIMBLDUARTARGS) - @sed -i 's|WTMI_IMG|wtmi.bin|1' $(DOIMAGE_CFG) - @sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(DOIMAGE_CFG) + @sed -i 's|WTMI_IMG|wtmi.bin|1' $(DOIMAGEUART_CFG) + @sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(DOIMAGEUART_CFG) ifeq ($(MARVELL_SECURE_BOOT),1) - @sed -i 's|WTMI_IMG|wtmi.bin|1' $(TIMNCFG) - @sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(TIMNCFG) + @sed -i 's|WTMI_IMG|wtmi.bin|1' $(TIMNUARTCFG) + @sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(TIMNUARTCFG) endif - cd $(BUILD_PLAT) && $(DOIMAGETOOL) $(DOIMAGE_FLAGS) + cd $(BUILD_PLAT)/$(BUILD_UART) && $(DOIMAGETOOL) -r $(DOIMAGEUART_CFG) -v -D ifeq ($(MARVELL_SECURE_BOOT),1) - @cd $(BUILD_PLAT) && $(DOIMAGETOOL) -r $(TIMNCFG) + @cd $(BUILD_PLAT)/$(BUILD_UART) && $(DOIMAGETOOL) -r $(TIMNUARTCFG) endif - @rm -rf $(BUILD_PLAT)/$(BUILD_UART)* - @mkdir $(BUILD_PLAT)/$(BUILD_UART) - @cd $(BUILD_PLAT) && mv -t $(BUILD_PLAT)/$(BUILD_UART) $(TIM_IMAGE) $(DOIMAGE_CFG) $(TIMN_IMAGE) $(TIMNCFG) - @find $(BUILD_PLAT) -name "*_h.*" |xargs cp -ut $(BUILD_PLAT)/$(BUILD_UART) - @cd $(BUILD_PLAT) && mv $(subst .bin,_h.bin,$(WTMI_MULTI_IMG)) $(BUILD_PLAT)/$(BUILD_UART)/wtmi_h.bin - @tar czf $(BUILD_PLAT)/$(BUILD_UART).tgz.bin -C $(BUILD_PLAT) ./$(BUILD_UART) + @tar czf $(BUILD_PLAT)/$(BUILD_UART).tgz.bin -C $(BUILD_PLAT) $(BUILD_UART)/$(TIM_IMAGE) $(BUILD_UART)/wtmi_h.bin $(BUILD_UART)/boot-image_h.bin @echo @echo "Building flash image" cd $(BUILD_PLAT) && $(TIMBUILD) $(TIMBLDARGS) @@ -199,7 +200,7 @@ ifeq ($(MARVELL_SECURE_BOOT),1) -K `cat $(IMAGESPATH)/aes-256.txt` -nosalt \ -iv `cat $(IMAGESPATH)/iv.txt` -p endif - cd $(BUILD_PLAT) && $(DOIMAGETOOL) $(DOIMAGE_FLAGS) + cd $(BUILD_PLAT) && $(DOIMAGETOOL) -r $(DOIMAGE_CFG) -v -D ifeq ($(MARVELL_SECURE_BOOT),1) @cd $(BUILD_PLAT) && $(DOIMAGETOOL) -r $(TIMNCFG) @sed -i 's|wtmi.bin|$(WTMI_ENC_IMG)|1' $(TIMNCFG) -- cgit v1.2.3 From 8b920973664fe73a84b608ba8922dc9da556a526 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Tue, 26 Jan 2021 10:44:07 +0100 Subject: plat: marvell: armada: a3k: Add a new target mrvl_uart which builds UART image MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change separates building of flash and UART images, so it is possible to build only one of these images. Also this change allows make to build them in parallel. Target mrvl_flash now builds only flash image and mrvl_uart only UART image. This change reflects it also in the documentation. Signed-off-by: Pali Rohár Change-Id: Ie9ce4538d52188dd26d99dfeeb5ad171a5b818f3 --- docs/plat/marvell/armada/build.rst | 7 ++++--- plat/marvell/armada/a3k/common/a3700_common.mk | 27 +++++++++++++++++++------- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/docs/plat/marvell/armada/build.rst b/docs/plat/marvell/armada/build.rst index d22477941..750bf6682 100644 --- a/docs/plat/marvell/armada/build.rst +++ b/docs/plat/marvell/armada/build.rst @@ -236,7 +236,7 @@ line is as following MARVELL_SECURE_BOOT=0 DDR_TOPOLOGY=3 BOOTDEV=SPINOR PARTNUM=0 PLAT=a3700 \ MV_DDR_PATH=/path/to/mv-ddr-marvell/ WTP=/path/to/A3700-utils-marvell/ \ CRYPTOPP_PATH=/path/to/cryptopp/ BL33=/path/to/u-boot.bin \ - all fip mrvl_bootimage mrvl_flash + all fip mrvl_bootimage mrvl_flash mrvl_uart To build just TF-A without WTMI image (useful for A3720 Turris MOX board), run following command: @@ -298,8 +298,9 @@ Marvell's TF-A compilation generates 8 files: for booting via UART. Could be loaded via Marvell's WtpDownload tool from A3700-utils-marvell repository. -Additional make target ``mrvl_bootimage`` produce ``boot-image.bin`` file and target -``mrvl_flash`` produce final ``flash-image.bin`` and ``uart-images.tgz.bin`` files. +Additional make target ``mrvl_bootimage`` produce ``boot-image.bin`` file. Target +``mrvl_flash`` produce final ``flash-image.bin`` file and target ``mrvl_uart`` +produce ``uart-images.tgz.bin`` file. Tools and external components installation diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk index 912302027..b2eafb913 100644 --- a/plat/marvell/armada/a3k/common/a3700_common.mk +++ b/plat/marvell/armada/a3k/common/a3700_common.mk @@ -78,6 +78,7 @@ DOIMAGEPATH := $(WTP) DOIMAGETOOL := $(DOIMAGEPATH)/wtptp/src/TBB_Linux/release/TBB_linux BUILD_UART := uart-images +UART_IMAGE := $(BUILD_UART).tgz.bin ifeq ($(MARVELL_SECURE_BOOT),1) DOIMAGE_CFG := $(BUILD_PLAT)/atf-tim.txt @@ -158,9 +159,8 @@ $(TIMDDRTOOL): FORCE $(if $(shell test -s "$(value MV_DDR_PATH)/branch.txt" || 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 Marvell mv_ddr release tarball nor git repository")) $(Q)$(MAKE) --no-print-directory -C $(DOIMAGEPATH) MV_DDR_PATH=$(MV_DDR_PATH) DDR_TOPOLOGY=$(DDR_TOPOLOGY) mv_ddr -.PHONY: mrvl_flash -mrvl_flash: ${BUILD_PLAT}/${BOOT_IMAGE} ${BUILD_PLAT}/wtmi.bin ${DOIMAGETOOL} ${TIMBUILD} - @echo +$(BUILD_PLAT)/$(UART_IMAGE): $(BUILD_PLAT)/$(BOOT_IMAGE) $(BUILD_PLAT)/wtmi.bin $(DOIMAGETOOL) $(TIMBUILD) $(TIMDDRTOOL) + @$(ECHO_BLANK_LINE) @echo "Building uart images" @mkdir -p $(BUILD_PLAT)/$(BUILD_UART) @cp -a $(BUILD_PLAT)/wtmi.bin $(BUILD_PLAT)/$(BUILD_UART)/wtmi.bin @@ -176,8 +176,13 @@ endif ifeq ($(MARVELL_SECURE_BOOT),1) @cd $(BUILD_PLAT)/$(BUILD_UART) && $(DOIMAGETOOL) -r $(TIMNUARTCFG) endif - @tar czf $(BUILD_PLAT)/$(BUILD_UART).tgz.bin -C $(BUILD_PLAT) $(BUILD_UART)/$(TIM_IMAGE) $(BUILD_UART)/wtmi_h.bin $(BUILD_UART)/boot-image_h.bin - @echo + @tar czf $(BUILD_PLAT)/$(UART_IMAGE) -C $(BUILD_PLAT) $(BUILD_UART)/$(TIM_IMAGE) $(BUILD_UART)/wtmi_h.bin $(BUILD_UART)/boot-image_h.bin + @$(ECHO_BLANK_LINE) + @echo "Built $@ successfully" + @$(ECHO_BLANK_LINE) + +$(BUILD_PLAT)/$(FLASH_IMAGE): $(BUILD_PLAT)/$(BOOT_IMAGE) $(BUILD_PLAT)/wtmi.bin $(DOIMAGETOOL) $(TIMBUILD) $(TIMDDRTOOL) $(TIM2IMG) + @$(ECHO_BLANK_LINE) @echo "Building flash image" cd $(BUILD_PLAT) && $(TIMBUILD) $(TIMBLDARGS) sed -i 's|WTMI_IMG|wtmi.bin|1' $(DOIMAGE_CFG) @@ -207,6 +212,9 @@ ifeq ($(MARVELL_SECURE_BOOT),1) @sed -i 's|$(BOOT_IMAGE)|$(BOOT_ENC_IMAGE)|1' $(TIMNCFG) endif cd $(BUILD_PLAT) && $(TIM2IMG) $(TIM2IMGARGS) -o $(BUILD_PLAT)/$(FLASH_IMAGE) + @$(ECHO_BLANK_LINE) + @echo "Built $@ successfully" + @$(ECHO_BLANK_LINE) clean realclean distclean: mrvl_clean @@ -220,8 +228,13 @@ endif else # WTP -.PHONY: mrvl_flash -mrvl_flash: +$(BUILD_PLAT)/$(UART_IMAGE) $(BUILD_PLAT)/$(FLASH_IMAGE): $(error "Platform '${PLAT}' for target '$@' requires WTP. Please set WTP to point to the right directory") endif # WTP + +.PHONY: mrvl_uart +mrvl_uart: $(BUILD_PLAT)/$(UART_IMAGE) + +.PHONY: mrvl_flash +mrvl_flash: $(BUILD_PLAT)/$(FLASH_IMAGE) -- cgit v1.2.3 From 907f8fc10b4b7dc9f48836fffbc30cfe9ad9fd84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Tue, 26 Jan 2021 10:44:07 +0100 Subject: plat: marvell: armada: a3k: Use $(Q) instead of @ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pali Rohár Change-Id: I09fd734510ec7019505263ff0ea381fab36944fa --- plat/marvell/armada/a3k/common/a3700_common.mk | 52 +++++++++++++------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk index b2eafb913..9c04ac7eb 100644 --- a/plat/marvell/armada/a3k/common/a3700_common.mk +++ b/plat/marvell/armada/a3k/common/a3700_common.mk @@ -162,21 +162,21 @@ $(TIMDDRTOOL): FORCE $(BUILD_PLAT)/$(UART_IMAGE): $(BUILD_PLAT)/$(BOOT_IMAGE) $(BUILD_PLAT)/wtmi.bin $(DOIMAGETOOL) $(TIMBUILD) $(TIMDDRTOOL) @$(ECHO_BLANK_LINE) @echo "Building uart images" - @mkdir -p $(BUILD_PLAT)/$(BUILD_UART) - @cp -a $(BUILD_PLAT)/wtmi.bin $(BUILD_PLAT)/$(BUILD_UART)/wtmi.bin - @cp -a $(BUILD_PLAT)/$(BOOT_IMAGE) $(BUILD_PLAT)/$(BUILD_UART)/$(BOOT_IMAGE) - @cd $(BUILD_PLAT)/$(BUILD_UART) && $(TIMBUILD) $(TIMBLDUARTARGS) - @sed -i 's|WTMI_IMG|wtmi.bin|1' $(DOIMAGEUART_CFG) - @sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(DOIMAGEUART_CFG) + $(Q)mkdir -p $(BUILD_PLAT)/$(BUILD_UART) + $(Q)cp -a $(BUILD_PLAT)/wtmi.bin $(BUILD_PLAT)/$(BUILD_UART)/wtmi.bin + $(Q)cp -a $(BUILD_PLAT)/$(BOOT_IMAGE) $(BUILD_PLAT)/$(BUILD_UART)/$(BOOT_IMAGE) + $(Q)cd $(BUILD_PLAT)/$(BUILD_UART) && $(TIMBUILD) $(TIMBLDUARTARGS) + $(Q)sed -i 's|WTMI_IMG|wtmi.bin|1' $(DOIMAGEUART_CFG) + $(Q)sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(DOIMAGEUART_CFG) ifeq ($(MARVELL_SECURE_BOOT),1) - @sed -i 's|WTMI_IMG|wtmi.bin|1' $(TIMNUARTCFG) - @sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(TIMNUARTCFG) + $(Q)sed -i 's|WTMI_IMG|wtmi.bin|1' $(TIMNUARTCFG) + $(Q)sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(TIMNUARTCFG) endif - cd $(BUILD_PLAT)/$(BUILD_UART) && $(DOIMAGETOOL) -r $(DOIMAGEUART_CFG) -v -D + $(Q)cd $(BUILD_PLAT)/$(BUILD_UART) && $(DOIMAGETOOL) -r $(DOIMAGEUART_CFG) -v -D ifeq ($(MARVELL_SECURE_BOOT),1) - @cd $(BUILD_PLAT)/$(BUILD_UART) && $(DOIMAGETOOL) -r $(TIMNUARTCFG) + $(Q)cd $(BUILD_PLAT)/$(BUILD_UART) && $(DOIMAGETOOL) -r $(TIMNUARTCFG) endif - @tar czf $(BUILD_PLAT)/$(UART_IMAGE) -C $(BUILD_PLAT) $(BUILD_UART)/$(TIM_IMAGE) $(BUILD_UART)/wtmi_h.bin $(BUILD_UART)/boot-image_h.bin + $(Q)tar czf $(BUILD_PLAT)/$(UART_IMAGE) -C $(BUILD_PLAT) $(BUILD_UART)/$(TIM_IMAGE) $(BUILD_UART)/wtmi_h.bin $(BUILD_UART)/boot-image_h.bin @$(ECHO_BLANK_LINE) @echo "Built $@ successfully" @$(ECHO_BLANK_LINE) @@ -184,34 +184,34 @@ endif $(BUILD_PLAT)/$(FLASH_IMAGE): $(BUILD_PLAT)/$(BOOT_IMAGE) $(BUILD_PLAT)/wtmi.bin $(DOIMAGETOOL) $(TIMBUILD) $(TIMDDRTOOL) $(TIM2IMG) @$(ECHO_BLANK_LINE) @echo "Building flash image" - cd $(BUILD_PLAT) && $(TIMBUILD) $(TIMBLDARGS) - sed -i 's|WTMI_IMG|wtmi.bin|1' $(DOIMAGE_CFG) - sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(DOIMAGE_CFG) + $(Q)cd $(BUILD_PLAT) && $(TIMBUILD) $(TIMBLDARGS) + $(Q)sed -i 's|WTMI_IMG|wtmi.bin|1' $(DOIMAGE_CFG) + $(Q)sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(DOIMAGE_CFG) ifeq ($(MARVELL_SECURE_BOOT),1) - @sed -i 's|WTMI_IMG|wtmi.bin|1' $(TIMNCFG) - @sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(TIMNCFG) + $(Q)sed -i 's|WTMI_IMG|wtmi.bin|1' $(TIMNCFG) + $(Q)sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(TIMNCFG) @echo -e "\n\t=======================================================\n"; @echo -e "\t Secure boot. Encrypting wtmi and boot-image \n"; @echo -e "\t=======================================================\n"; - @cp $(BUILD_PLAT)/wtmi.bin $(BUILD_PLAT)/wtmi-align.bin - @truncate -s %16 $(BUILD_PLAT)/wtmi-align.bin - @openssl enc -aes-256-cbc -e -in $(BUILD_PLAT)/wtmi-align.bin \ + $(Q)cp $(BUILD_PLAT)/wtmi.bin $(BUILD_PLAT)/wtmi-align.bin + $(Q)truncate -s %16 $(BUILD_PLAT)/wtmi-align.bin + $(Q)openssl enc -aes-256-cbc -e -in $(BUILD_PLAT)/wtmi-align.bin \ -out $(BUILD_PLAT)/$(WTMI_ENC_IMG) \ -K `cat $(IMAGESPATH)/aes-256.txt` -nosalt \ -iv `cat $(IMAGESPATH)/iv.txt` -p - @truncate -s %16 $(BUILD_PLAT)/$(BOOT_IMAGE); - @openssl enc -aes-256-cbc -e -in $(BUILD_PLAT)/$(BOOT_IMAGE) \ + $(Q)truncate -s %16 $(BUILD_PLAT)/$(BOOT_IMAGE); + $(Q)openssl enc -aes-256-cbc -e -in $(BUILD_PLAT)/$(BOOT_IMAGE) \ -out $(BUILD_PLAT)/$(BOOT_ENC_IMAGE) \ -K `cat $(IMAGESPATH)/aes-256.txt` -nosalt \ -iv `cat $(IMAGESPATH)/iv.txt` -p endif - cd $(BUILD_PLAT) && $(DOIMAGETOOL) -r $(DOIMAGE_CFG) -v -D + $(Q)cd $(BUILD_PLAT) && $(DOIMAGETOOL) -r $(DOIMAGE_CFG) -v -D ifeq ($(MARVELL_SECURE_BOOT),1) - @cd $(BUILD_PLAT) && $(DOIMAGETOOL) -r $(TIMNCFG) - @sed -i 's|wtmi.bin|$(WTMI_ENC_IMG)|1' $(TIMNCFG) - @sed -i 's|$(BOOT_IMAGE)|$(BOOT_ENC_IMAGE)|1' $(TIMNCFG) + $(Q)cd $(BUILD_PLAT) && $(DOIMAGETOOL) -r $(TIMNCFG) + $(Q)sed -i 's|wtmi.bin|$(WTMI_ENC_IMG)|1' $(TIMNCFG) + $(Q)sed -i 's|$(BOOT_IMAGE)|$(BOOT_ENC_IMAGE)|1' $(TIMNCFG) endif - cd $(BUILD_PLAT) && $(TIM2IMG) $(TIM2IMGARGS) -o $(BUILD_PLAT)/$(FLASH_IMAGE) + $(Q)cd $(BUILD_PLAT) && $(TIM2IMG) $(TIM2IMGARGS) -o $(BUILD_PLAT)/$(FLASH_IMAGE) @$(ECHO_BLANK_LINE) @echo "Built $@ successfully" @$(ECHO_BLANK_LINE) -- cgit v1.2.3 From c0f60e7831c106c056788c8a104b155a191950c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Tue, 26 Jan 2021 10:44:07 +0100 Subject: plat: marvell: armada: Move definition of mrvl_flash target to common marvell_common.mk file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pali Rohár Change-Id: If545b3812787cc97b95dbd61ed51c37d30c5d412 --- plat/marvell/armada/a3k/common/a3700_common.mk | 3 --- plat/marvell/armada/a8k/common/a8k_common.mk | 3 +-- plat/marvell/armada/common/marvell_common.mk | 3 +++ 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk index 9c04ac7eb..ea20c7df7 100644 --- a/plat/marvell/armada/a3k/common/a3700_common.mk +++ b/plat/marvell/armada/a3k/common/a3700_common.mk @@ -235,6 +235,3 @@ endif # WTP .PHONY: mrvl_uart mrvl_uart: $(BUILD_PLAT)/$(UART_IMAGE) - -.PHONY: mrvl_flash -mrvl_flash: $(BUILD_PLAT)/$(FLASH_IMAGE) diff --git a/plat/marvell/armada/a8k/common/a8k_common.mk b/plat/marvell/armada/a8k/common/a8k_common.mk index b7c7d848d..857bd89ae 100644 --- a/plat/marvell/armada/a8k/common/a8k_common.mk +++ b/plat/marvell/armada/a8k/common/a8k_common.mk @@ -163,6 +163,5 @@ ${DOIMAGETOOL}: FORCE @$(DOIMAGE_LIBS_CHECK) ${Q}${MAKE} --no-print-directory -C ${DOIMAGEPATH} -.PHONY: mrvl_flash -mrvl_flash: ${BUILD_PLAT}/${BOOT_IMAGE} ${DOIMAGETOOL} +${BUILD_PLAT}/${FLASH_IMAGE}: ${ROM_BIN_EXT} ${BUILD_PLAT}/${BOOT_IMAGE} ${DOIMAGETOOL} ${DOIMAGETOOL} ${DOIMAGE_FLAGS} ${BUILD_PLAT}/${BOOT_IMAGE} ${BUILD_PLAT}/${FLASH_IMAGE} diff --git a/plat/marvell/armada/common/marvell_common.mk b/plat/marvell/armada/common/marvell_common.mk index e5ee710a6..a43bb5c1e 100644 --- a/plat/marvell/armada/common/marvell_common.mk +++ b/plat/marvell/armada/common/marvell_common.mk @@ -96,3 +96,6 @@ $(BUILD_PLAT)/$(BOOT_IMAGE): $(BUILD_PLAT)/bl1.bin $(BUILD_PLAT)/$(FIP_NAME) .PHONY: mrvl_bootimage mrvl_bootimage: $(BUILD_PLAT)/$(BOOT_IMAGE) + +.PHONY: mrvl_flash +mrvl_flash: $(BUILD_PLAT)/$(FLASH_IMAGE) -- cgit v1.2.3 From 07924f822d9c0edeb6fad8e09e281b0761874b02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Tue, 26 Jan 2021 10:44:07 +0100 Subject: plat: marvell: armada: Show informative build messages and blank lines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pali Rohár Change-Id: Ibc15db07c581eca29c1b1fbfb145cee50dc42605 --- plat/marvell/armada/a8k/common/a8k_common.mk | 7 ++++++- plat/marvell/armada/common/marvell_common.mk | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/plat/marvell/armada/a8k/common/a8k_common.mk b/plat/marvell/armada/a8k/common/a8k_common.mk index 857bd89ae..63cfce22c 100644 --- a/plat/marvell/armada/a8k/common/a8k_common.mk +++ b/plat/marvell/armada/a8k/common/a8k_common.mk @@ -164,4 +164,9 @@ ${DOIMAGETOOL}: FORCE ${Q}${MAKE} --no-print-directory -C ${DOIMAGEPATH} ${BUILD_PLAT}/${FLASH_IMAGE}: ${ROM_BIN_EXT} ${BUILD_PLAT}/${BOOT_IMAGE} ${DOIMAGETOOL} - ${DOIMAGETOOL} ${DOIMAGE_FLAGS} ${BUILD_PLAT}/${BOOT_IMAGE} ${BUILD_PLAT}/${FLASH_IMAGE} + @${ECHO_BLANK_LINE} + @echo "Building flash image" + ${Q}${DOIMAGETOOL} ${DOIMAGE_FLAGS} ${BUILD_PLAT}/${BOOT_IMAGE} ${BUILD_PLAT}/${FLASH_IMAGE} + @${ECHO_BLANK_LINE} + @echo "Built $@ successfully" + @${ECHO_BLANK_LINE} diff --git a/plat/marvell/armada/common/marvell_common.mk b/plat/marvell/armada/common/marvell_common.mk index a43bb5c1e..04eb51c48 100644 --- a/plat/marvell/armada/common/marvell_common.mk +++ b/plat/marvell/armada/common/marvell_common.mk @@ -92,7 +92,9 @@ $(BUILD_PLAT)/$(BOOT_IMAGE): $(BUILD_PLAT)/bl1.bin $(BUILD_PLAT)/$(FIP_NAME) @truncate -s %128K $(BUILD_PLAT)/$(BOOT_IMAGE) || { rm -f $(BUILD_PLAT)/$(BOOT_IMAGE); false; } @cat $(BUILD_PLAT)/$(FIP_NAME) >> $(BUILD_PLAT)/$(BOOT_IMAGE) || { rm -f $(BUILD_PLAT)/$(BOOT_IMAGE); false; } @truncate -s %4 $(BUILD_PLAT)/$(BOOT_IMAGE) || { rm -f $(BUILD_PLAT)/$(BOOT_IMAGE); false; } + @$(ECHO_BLANK_LINE) @echo "Built $@ successfully" + @$(ECHO_BLANK_LINE) .PHONY: mrvl_bootimage mrvl_bootimage: $(BUILD_PLAT)/$(BOOT_IMAGE) -- cgit v1.2.3 From 4e80d1513817677ac5ef57bfa7888ebf25353c2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Tue, 26 Jan 2021 11:10:17 +0100 Subject: plat: marvell: armada: a3k: Remove unused variable WTMI_SYSINIT_IMG from Makefile MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pali Rohár Change-Id: I322c8aa65437abb61385f58b700a06b3e2e22e4f --- plat/marvell/armada/a3k/common/a3700_common.mk | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk index ea20c7df7..c64be39cc 100644 --- a/plat/marvell/armada/a3k/common/a3700_common.mk +++ b/plat/marvell/armada/a3k/common/a3700_common.mk @@ -107,14 +107,8 @@ $(TIMBUILD): $(TIMDDRTOOL) # baremetal binary of fuse programming in A3700_utils. WTMI_IMG := $(DOIMAGEPATH)/wtmi/fuse/build/fuse.bin -# WTMI_SYSINIT_IMG is used for the system early initialization, -# such as AVS settings, clock-tree setup and dynamic DDR PHY training. -# After the initialization is done, this image will be wiped out -# from the memory and CM3 will continue with RTOS image or other application. -WTMI_SYSINIT_IMG := $(DOIMAGEPATH)/wtmi/sys_init/build/sys_init.bin - # WTMI_MULTI_IMG is composed of CM3 RTOS image (WTMI_IMG) -# and sys-init image (WTMI_SYSINIT_IMG). +# and sys-init image. WTMI_MULTI_IMG := $(DOIMAGEPATH)/wtmi/build/wtmi.bin WTMI_ENC_IMG := wtmi-enc.bin -- cgit v1.2.3 From 33af2937cdaecbb65c74677aa68a9a0b39f59764 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Thu, 28 Jan 2021 13:09:36 +0100 Subject: docs: marvell: Update info about BOOTDEV=SATA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Information is taken from the post https://lists.denx.de/pipermail/u-boot/2017-July/299351.html Signed-off-by: Pali Rohár Change-Id: I5f608e135ec56685a3e2b986a52670540d48a4bf --- docs/plat/marvell/armada/build.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/plat/marvell/armada/build.rst b/docs/plat/marvell/armada/build.rst index 10d30aec9..ae67ab0b0 100644 --- a/docs/plat/marvell/armada/build.rst +++ b/docs/plat/marvell/armada/build.rst @@ -174,6 +174,10 @@ There are several build options: - SATA - SATA device boot + Image needs to be stored at disk LBA 0 or at disk partition with + MBR type 0x4d (ASCII 'M' as in Marvell) or at disk partition with + GPT name ``MARVELL BOOT PARTITION``. + - PARTNUM For Armada37x0 only, the boot partition number, default is 0. -- cgit v1.2.3 From 711a6bb79bf17203607507b004266db661e96ab5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Wed, 27 Jan 2021 18:04:32 +0100 Subject: docs: marvell: Update info about WTMI_IMG option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Default WTMI_IMG value was documented incorrectly. Also WTMI_IMG name may be misleading as this option does not specify full WTMI image, just a main loop (e.g. fuse.bin or custom RTOS image) without hardware initialization code (DDR, CPU and clocks). Signed-off-by: Pali Rohár Change-Id: I3de4a27ce2165b962fa628c992fd8f80151efd7c --- docs/plat/marvell/armada/build.rst | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/plat/marvell/armada/build.rst b/docs/plat/marvell/armada/build.rst index 750bf6682..10d30aec9 100644 --- a/docs/plat/marvell/armada/build.rst +++ b/docs/plat/marvell/armada/build.rst @@ -185,12 +185,17 @@ There are several build options: - WTMI_IMG - For Armada37x0 only, the path of the WTMI image can point to an image which + For Armada37x0 only, the path of the binary can point to an image which does nothing, an image which supports EFUSE or a customized CM3 firmware - binary. The default image is wtmi.bin that built from sources in WTP + binary. The default image is ``fuse.bin`` that built from sources in WTP folder, which is the next option. If the default image is OK, then this option should be skipped. + Please note that this is not a full WTMI image, just a main loop without + hardware initialization code. Final WTMI image is built from this WTMI_IMG + binary and sys-init code from the WTP directory which sets DDR and CPU + clocks according to DDR_TOPOLOGY and CLOCKSPRESET options. + - WTP For Armada37x0 only, use this parameter to point to wtptools source code -- cgit v1.2.3 From e01658ea94b0fc6dabca73a56c778eef6342aa0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Fri, 29 Jan 2021 12:08:21 +0100 Subject: plat: marvell: armada: a3k: Do not use 'echo -e' in Makefile MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It does not have to be supported by the current shell used in Makefile. Replace it by a simple echo with implicit newline. Signed-off-by: Pali Rohár Change-Id: I97fe44986ac36d3079d5258c67f0c9184537e7f0 --- plat/marvell/armada/a3k/common/a3700_common.mk | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk index c64be39cc..8775e8934 100644 --- a/plat/marvell/armada/a3k/common/a3700_common.mk +++ b/plat/marvell/armada/a3k/common/a3700_common.mk @@ -184,9 +184,11 @@ $(BUILD_PLAT)/$(FLASH_IMAGE): $(BUILD_PLAT)/$(BOOT_IMAGE) $(BUILD_PLAT)/wtmi.bin ifeq ($(MARVELL_SECURE_BOOT),1) $(Q)sed -i 's|WTMI_IMG|wtmi.bin|1' $(TIMNCFG) $(Q)sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(TIMNCFG) - @echo -e "\n\t=======================================================\n"; - @echo -e "\t Secure boot. Encrypting wtmi and boot-image \n"; - @echo -e "\t=======================================================\n"; + @$(ECHO_BLANK_LINE) + @echo "======================================================="; + @echo " Secure boot. Encrypting wtmi and boot-image"; + @echo "======================================================="; + @$(ECHO_BLANK_LINE) $(Q)cp $(BUILD_PLAT)/wtmi.bin $(BUILD_PLAT)/wtmi-align.bin $(Q)truncate -s %16 $(BUILD_PLAT)/wtmi-align.bin $(Q)openssl enc -aes-256-cbc -e -in $(BUILD_PLAT)/wtmi-align.bin \ -- cgit v1.2.3 From 92264f86a33053f86d12844a14ed243149d9ddad Mon Sep 17 00:00:00 2001 From: Pranav Madhu Date: Sat, 16 Jan 2021 22:47:08 +0530 Subject: plat/arm/sgi: allow all PSCI callbacks on RD-V1 Some of the PSCI platform callbacks were restricted on RD-V1 platform because the idle was not functional. Now that it is functional, remove all the restrictions on the use PSCI platform callbacks. Change-Id: I4cb97cb54de7ee166c30f28df8fea653b6b425c7 Signed-off-by: Pranav Madhu --- plat/arm/css/sgi/sgi_bl31_setup.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/plat/arm/css/sgi/sgi_bl31_setup.c b/plat/arm/css/sgi/sgi_bl31_setup.c index 89e2cab08..36c3fbb6c 100644 --- a/plat/arm/css/sgi/sgi_bl31_setup.c +++ b/plat/arm/css/sgi/sgi_bl31_setup.c @@ -108,12 +108,11 @@ void sgi_bl31_common_platform_setup(void) const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops) { /* - * For RD-E1-Edge and RD-V1 platforms, only CPU power ON/OFF - * PSCI platform callbacks are supported. + * For RD-E1-Edge, only CPU power ON/OFF, PSCI platform callbacks are + * supported. */ if (((sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM) && - (sgi_plat_info.config_id == RD_E1_EDGE_CONFIG_ID)) || - (sgi_plat_info.platform_id == RD_V1_SID_VER_PART_NUM)) { + (sgi_plat_info.config_id == RD_E1_EDGE_CONFIG_ID))) { ops->cpu_standby = NULL; ops->system_off = NULL; ops->system_reset = NULL; -- cgit v1.2.3 From c9bf2cf5e3288ca92f03e41a6ce5b1fe04f0ccd4 Mon Sep 17 00:00:00 2001 From: Pranav Madhu Date: Wed, 11 Nov 2020 10:27:14 +0530 Subject: plat/arm/board: enable AMU for RD-V1 AMU counters are used for monitoring the CPU performance. RD-V1 platform has architected AMU available for each core. Enable the use of AMU by non-secure OS for supporting the use of counters for processor performance control (ACPI CPPC). Change-Id: I4003d21407953f65b3ce99eaa8f496d6052546e0 Signed-off-by: Pranav Madhu --- plat/arm/board/rdv1/platform.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plat/arm/board/rdv1/platform.mk b/plat/arm/board/rdv1/platform.mk index 5033b1874..2ffd139c9 100644 --- a/plat/arm/board/rdv1/platform.mk +++ b/plat/arm/board/rdv1/platform.mk @@ -1,4 +1,4 @@ -# 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 # @@ -57,3 +57,4 @@ NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb $(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config,${NT_FW_CONFIG})) override CTX_INCLUDE_AARCH32_REGS := 0 +override ENABLE_AMU := 1 -- cgit v1.2.3 From f7bab2761693f25013a367f03782c8478a5e9db8 Mon Sep 17 00:00:00 2001 From: Pranav Madhu Date: Wed, 27 Jan 2021 16:17:32 +0530 Subject: plat/arm/board: enable AMU for RD-N2 AMU counters are used for monitoring the CPU performance. RD-N2 platform has architected AMU available for each core. Enable the use of AMU by non-secure OS for supporting the use of counters for processor performance control (ACPI CPPC). Change-Id: I5cc749cf63c18fc5c7563dd754c2f42990a97e23 Signed-off-by: Pranav Madhu --- plat/arm/board/rdn2/platform.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plat/arm/board/rdn2/platform.mk b/plat/arm/board/rdn2/platform.mk index 6be611360..03771dc3d 100644 --- a/plat/arm/board/rdn2/platform.mk +++ b/plat/arm/board/rdn2/platform.mk @@ -1,4 +1,4 @@ -# 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 # @@ -57,3 +57,4 @@ NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb $(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config)) override CTX_INCLUDE_AARCH32_REGS := 0 +override ENABLE_AMU := 1 -- cgit v1.2.3 From 24e6e10b996ff000733ae7ac4b0e835b5babd0f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Mon, 1 Feb 2021 12:22:37 +0100 Subject: docs: marvell: Move Supported Marvell platforms to PLAT build option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reformat list of boards, remove unsupported OcteonTX2 and mention supported Turris MOX board. Signed-off-by: Pali Rohár Change-Id: I22cea7f77fd078554c7f0ed4108781626209e563 --- docs/plat/marvell/armada/build.rst | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/docs/plat/marvell/armada/build.rst b/docs/plat/marvell/armada/build.rst index 29fe4d452..a7181c7c7 100644 --- a/docs/plat/marvell/armada/build.rst +++ b/docs/plat/marvell/armada/build.rst @@ -51,6 +51,18 @@ Install ARM 32-bit cross compiler, which is required for building WTMI image for There are several build options: +- PLAT + + Supported Marvell platforms are: + + - a3700 - A3720 DB, EspressoBin and Turris MOX + - a70x0 + - a70x0_amc - AMC board + - a80x0 + - a80x0_mcbin - MacchiatoBin + - a80x0_puzzle - IEI Puzzle-M801 + - t9130 - CN913x + - DEBUG Default is without debug information (=0). in order to enable it use ``DEBUG=1``. @@ -236,15 +248,6 @@ You can build TF-A for the Globalscale ESPRESSObin-Ultra board (DDR4, 1 GB) by r CRYPTOPP_PATH=/path/to/cryptopp/ BL33=/path/to/u-boot.bin \ all fip mrvl_bootimage mrvl_flash -Supported MARVELL_PLATFORM are: - - a3700 (for both A3720 DB and EspressoBin) - - a70x0 - - a70x0_amc (for AMC board) - - a80x0 - - a80x0_mcbin (for MacchiatoBin) - - a80x0_puzzle (for IEI Puzzle-M801) - - t9130 (OcteonTX2 CN913x) - Special Build Flags -------------------- -- cgit v1.2.3 From 9c3fffdc8673db8038608cba515931aac298f7e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Mon, 1 Feb 2021 12:23:31 +0100 Subject: docs: marvell: Reformat DDR_TOPOLOGY option and mention EspressoBin-Ultra board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pali Rohár Change-Id: I96c2d9d5bc6c69a1a66a29bf586a23375d63ab5a --- docs/plat/marvell/armada/build.rst | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/plat/marvell/armada/build.rst b/docs/plat/marvell/armada/build.rst index a7181c7c7..2715f2601 100644 --- a/docs/plat/marvell/armada/build.rst +++ b/docs/plat/marvell/armada/build.rst @@ -148,15 +148,15 @@ There are several build options: For Armada37x0 only, the DDR topology map index/name, default is 0. Supported Options: - - 0 - DDR3 1CS: DB-88F3720-DDR3-Modular (512MB); EspressoBIN (512MB) - - 1 - DDR4 1CS: DB-88F3720-DDR4-Modular (512MB) - - 2 - DDR3 2CS: EspressoBIN V3-V5 (1GB 2CS) - - 3 - DDR4 2CS: DB-88F3720-DDR4-Modular (4GB) - - 4 - DDR3 1CS: DB-88F3720-DDR3-Modular (1GB); EspressoBIN V3-V5 (1GB 1CS) - - 5 - DDR4 1CS: EspressoBin V7 (1GB) - - 6 - DDR4 2CS: EspressoBin V7 (2GB) - - 7 - DDR3 2CS: EspressoBin V3-V5 (2GB) - - CUST - CUSTOMER: Customer board, DDR3 1CS 512MB + - 0 - DDR3 1CS 512MB (DB-88F3720-DDR3-Modular, EspressoBin V3-V5) + - 1 - DDR4 1CS 512MB (DB-88F3720-DDR4-Modular) + - 2 - DDR3 2CS 1GB (EspressoBin V3-V5) + - 3 - DDR4 2CS 4GB (DB-88F3720-DDR4-Modular) + - 4 - DDR3 1CS 1GB (DB-88F3720-DDR3-Modular, EspressoBin V3-V5) + - 5 - DDR4 1CS 1GB (EspressoBin V7, EspressoBin-Ultra) + - 6 - DDR4 2CS 2GB (EspressoBin V7) + - 7 - DDR3 2CS 2GB (EspressoBin V3-V5) + - CUST - CUSTOMER BOARD (Customer board settings) - CLOCKSPRESET -- cgit v1.2.3 From 23abf07ce46b897a9460aea88eb3e8a0bc67a0b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Mon, 1 Feb 2021 12:24:42 +0100 Subject: docs: marvell: Add information into CLOCKSPRESET option how to identify CPU frequency MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pali Rohár Change-Id: I5310c30051703bbf9f377762a00eb6a8188c6fa1 --- docs/plat/marvell/armada/build.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/plat/marvell/armada/build.rst b/docs/plat/marvell/armada/build.rst index 2715f2601..a4116cd4e 100644 --- a/docs/plat/marvell/armada/build.rst +++ b/docs/plat/marvell/armada/build.rst @@ -168,6 +168,13 @@ There are several build options: - CPU_1000_DDR_800 - CPU at 1000 MHz, DDR at 800 MHz - CPU_1200_DDR_750 - CPU at 1200 MHz, DDR at 750 MHz + Look at Armada37x0 chip package marking on board to identify correct CPU frequency. + The last line on package marking (next line after the 88F37x0 line) should contain: + + - C080 or I080 - chip with 800 MHz CPU - use ``CLOCKSPRESET=CPU_800_DDR_800`` + - C100 or I100 - chip with 1000 MHz CPU - use ``CLOCKSPRESET=CPU_1000_DDR_800`` + - C120 - chip with 1200 MHz CPU - use ``CLOCKSPRESET=CPU_1200_DDR_750`` + - BOOTDEV For Armada37x0 only, the flash boot device, default is ``SPINOR``. -- cgit v1.2.3 From f60f1e848dfdbc8180b323187630ef866318647a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Mon, 1 Feb 2021 12:25:46 +0100 Subject: docs: marvell: Fix description of flash-image.bin image MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pali Rohár Change-Id: I192acab2a7f42cd80069faeac2d7823a05558dc6 --- docs/plat/marvell/armada/build.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/plat/marvell/armada/build.rst b/docs/plat/marvell/armada/build.rst index a4116cd4e..7793af47d 100644 --- a/docs/plat/marvell/armada/build.rst +++ b/docs/plat/marvell/armada/build.rst @@ -277,14 +277,15 @@ Build output ------------ Marvell's TF-A compilation generates 8 files: - - ble.bin - BLe image + - ble.bin - BLe image (not available for Armada37x0) - bl1.bin - BL1 image - bl2.bin - BL2 image - bl31.bin - BL31 image - fip.bin - FIP image (contains BL2, BL31 & BL33 (U-Boot) images) - boot-image.bin - TF-A image (contains BL1 and FIP images) - - flash-image.bin - Image which contains boot-image.bin and SPL image. - Should be placed on the boot flash/device. + - flash-image.bin - Flashable Marvell firmware image. For Armada37x0 it + contains TIM, WTMI and boot-image.bin images. For other platforms it contains + BLe and boot-image.bin images. Should be placed on the boot flash/device. - uart-images.tgz.bin - GZIPed TAR archive which contains Armada37x0 images for booting via UART. Could be loaded via Marvell's WtpDownload tool from A3700-utils-marvell repository. -- cgit v1.2.3 From ff46a41dc27a2bb9813842c918eca295c18f070b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Mon, 1 Feb 2021 12:32:36 +0100 Subject: docs: marvell: Replace ESPRESSObin-Ultra TF-A build example by full example how to build production release of Marvell firmware image MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ESPRESSObin-Ultra TF-A build example was now just a copy+paste of previous mentioned example. It produced debug binary with custom log level, which was not described. So rather replace this duplicate build example by a full example with all steps how to build production release of Marvell firmware image for EspressoBin with 1GHz CPU and 1GB DDR4 RAM. Signed-off-by: Pali Rohár Change-Id: Ief1b8bc96a3035ebd8421bd68dca5eb5c8d8fd52 --- docs/plat/marvell/armada/build.rst | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/docs/plat/marvell/armada/build.rst b/docs/plat/marvell/armada/build.rst index 7793af47d..8001c3613 100644 --- a/docs/plat/marvell/armada/build.rst +++ b/docs/plat/marvell/armada/build.rst @@ -245,15 +245,24 @@ To build just TF-A without WTMI image (useful for A3720 Turris MOX board), run f > make USE_COHERENT_MEM=0 PLAT=a3700 CM3_SYSTEM_RESET=1 BL33=/path/to/u-boot.bin \ CROSS_COMPILE=aarch64-linux-gnu- mrvl_bootimage -You can build TF-A for the Globalscale ESPRESSObin-Ultra board (DDR4, 1 GB) by running the following command: +Here is full example how to build production release of Marvell firmware image (concatenated +binary of Marvell secure firmware, TF-A and U-Boot) for EspressoBin board (PLAT=a3700) with +1GHz CPU (CLOCKSPRESET=CPU_1000_DDR_800) and 1GB DDR4 RAM (DDR_TOPOLOGY=5): .. code:: shell - > make DEBUG=1 USE_COHERENT_MEM=0 LOG_LEVEL=20 CLOCKSPRESET=CPU_1200_DDR_750 \ - MARVELL_SECURE_BOOT=0 DDR_TOPOLOGY=5 BOOTDEV=SPINOR PARTNUM=0 PLAT=a3700 \ - MV_DDR_PATH=/path/to/mv-ddr-marvell/ WTP=/path/to/A3700-utils-marvell/ \ - CRYPTOPP_PATH=/path/to/cryptopp/ BL33=/path/to/u-boot.bin \ - all fip mrvl_bootimage mrvl_flash + > git clone https://review.trustedfirmware.org/TF-A/trusted-firmware-a + > git clone https://gitlab.denx.de/u-boot/u-boot.git + > git clone https://github.com/weidai11/cryptopp.git + > git clone https://github.com/MarvellEmbeddedProcessors/mv-ddr-marvell.git -b master + > git clone https://github.com/MarvellEmbeddedProcessors/A3700-utils-marvell.git -b master + > make -C u-boot CROSS_COMPILE=aarch64-linux-gnu- mvebu_espressobin-88f3720_defconfig u-boot.bin + > make -C trusted-firmware-a CROSS_COMPILE=aarch64-linux-gnu- CROSS_CM3=arm-linux-gnueabi- \ + USE_COHERENT_MEM=0 PLAT=a3700 CLOCKSPRESET=CPU_1000_DDR_800 DDR_TOPOLOGY=5 \ + MV_DDR_PATH=$PWD/mv-ddr-marvell/ WTP=$PWD/A3700-utils-marvell/ CRYPTOPP_PATH=$PWD/cryptopp/ \ + BL33=$PWD/u-boot/u-boot.bin mrvl_flash + +Produced Marvell firmware flash image: ``trusted-firmware-a/build/a3700/release/flash-image.bin`` Special Build Flags -------------------- -- cgit v1.2.3 From 5e508f06a0d9a8fdfdaedc47ab374ae4af2a6c84 Mon Sep 17 00:00:00 2001 From: Zelalem Date: Tue, 2 Feb 2021 09:49:07 -0600 Subject: plat/arm:juno: fix parallel build issue for romlib config When building TF-A with USE_ROMLIB=1 and -j make options, the build fails with the following error: make[1]: *** No rule to make target '/build/juno/debug/romlib/romlib.bin', needed by 'bl1_romlib.bin'. This patch fixes that issue. Signed-off-by: Zelalem Change-Id: I0cca416f3f50f400759164e0735c2d6b520ebf84 --- plat/arm/board/juno/platform.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk index 78704b583..61cfb610c 100644 --- a/plat/arm/board/juno/platform.mk +++ b/plat/arm/board/juno/platform.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 # @@ -108,7 +108,7 @@ ifeq ($(USE_ROMLIB),1) all : bl1_romlib.bin endif -bl1_romlib.bin : $(BUILD_PLAT)/bl1.bin $(BUILD_PLAT)/romlib/romlib.bin +bl1_romlib.bin : $(BUILD_PLAT)/bl1.bin romlib.bin @echo "Building combined BL1 and ROMLIB binary for Juno $@" ./lib/romlib/gen_combined_bl1_romlib.sh -o bl1_romlib.bin $(BUILD_PLAT) -- cgit v1.2.3 From e5da15e04597e374f7a9fdfbf86d47b85c35e728 Mon Sep 17 00:00:00 2001 From: Avinash Mehta Date: Wed, 28 Oct 2020 16:43:28 +0000 Subject: product/tc0: Enable Theodul DSU in TC platform Increase the core count and add respective entries in DTS. Add Klein assembly file to cpu sources for core initialization. Add SCMI entries for cores. Signed-off-by: Avinash Mehta Change-Id: I14dc1d87df6dcc8d560ade833ce1f92507054747 --- fdts/tc0.dts | 48 ++++++++++++ plat/arm/board/tc0/fdts/tc0_spmc_manifest.dts | 41 ++++++++-- .../board/tc0/fdts/tc0_spmc_optee_sp_manifest.dts | 88 ++++++++++++++-------- plat/arm/board/tc0/include/platform_def.h | 4 +- plat/arm/board/tc0/platform.mk | 3 +- plat/arm/board/tc0/tc0_topology.c | 3 + 6 files changed, 145 insertions(+), 42 deletions(-) diff --git a/fdts/tc0.dts b/fdts/tc0.dts index f1ade19e6..b17807aa1 100644 --- a/fdts/tc0.dts +++ b/fdts/tc0.dts @@ -38,6 +38,18 @@ core3 { cpu = <&CPU3>; }; + core4 { + cpu = <&CPU4>; + }; + core5 { + cpu = <&CPU5>; + }; + core6 { + cpu = <&CPU6>; + }; + core7 { + cpu = <&CPU7>; + }; }; }; @@ -102,6 +114,42 @@ cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; }; + CPU4:cpu@400 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x400>; + enable-method = "psci"; + clocks = <&scmi_dvfs 0>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + }; + + CPU5:cpu@500 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x500>; + enable-method = "psci"; + clocks = <&scmi_dvfs 0>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + }; + + CPU6:cpu@600 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x600>; + enable-method = "psci"; + clocks = <&scmi_dvfs 0>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + }; + + CPU7:cpu@700 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x700>; + enable-method = "psci"; + clocks = <&scmi_dvfs 0>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + }; + }; memory@80000000 { diff --git a/plat/arm/board/tc0/fdts/tc0_spmc_manifest.dts b/plat/arm/board/tc0/fdts/tc0_spmc_manifest.dts index b6c543ade..2f459b013 100644 --- a/plat/arm/board/tc0/fdts/tc0_spmc_manifest.dts +++ b/plat/arm/board/tc0/fdts/tc0_spmc_manifest.dts @@ -20,30 +20,27 @@ binary_size = <0x80000>; }; - chosen { - linux,initrd-start = <0>; - linux,initrd-end = <0>; - }; - hypervisor { compatible = "hafnium,hafnium"; vm1 { is_ffa_partition; debug_name = "cactus-primary"; load_address = <0xfe000000>; + vcpu_count = <8>; + mem_size = <1048576>; }; vm2 { is_ffa_partition; debug_name = "cactus-secondary"; load_address = <0xfe100000>; - vcpu_count = <4>; + vcpu_count = <8>; mem_size = <1048576>; }; vm3 { is_ffa_partition; debug_name = "cactus-tertiary"; load_address = <0xfe200000>; - vcpu_count = <4>; + vcpu_count = <8>; mem_size = <1048576>; }; }; @@ -60,9 +57,37 @@ }; /* - * SPM(Hafnium) requires secondary cpu nodes are declared in + * SPMC (Hafnium) requires secondary cpu nodes are declared in * descending order */ + CPU7:cpu@700 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x700>; + enable-method = "psci"; + }; + + CPU6:cpu@600 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x600>; + enable-method = "psci"; + }; + + CPU5:cpu@500 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x500>; + enable-method = "psci"; + }; + + CPU4:cpu@400 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x400>; + enable-method = "psci"; + }; + CPU3:cpu@300 { device_type = "cpu"; compatible = "arm,armv8"; diff --git a/plat/arm/board/tc0/fdts/tc0_spmc_optee_sp_manifest.dts b/plat/arm/board/tc0/fdts/tc0_spmc_optee_sp_manifest.dts index a58b9113e..221039c43 100644 --- a/plat/arm/board/tc0/fdts/tc0_spmc_optee_sp_manifest.dts +++ b/plat/arm/board/tc0/fdts/tc0_spmc_optee_sp_manifest.dts @@ -5,13 +5,6 @@ */ /dts-v1/; -#define AFF 00 - -#include "fvp-defs.dtsi" -#undef POST -#define POST \ - }; - / { compatible = "arm,ffa-core-manifest-1.0"; #address-cells = <2>; @@ -27,21 +20,14 @@ binary_size = <0x80000>; }; - /* - * temporary: This entry is added based on v2.4 hafnium and will be - * removed when rebased to upstream master. - */ - chosen { - linux,initrd-start = <0>; - linux,initrd-end = <0>; - }; - hypervisor { compatible = "hafnium,hafnium"; vm1 { is_ffa_partition; debug_name = "op-tee"; load_address = <0xfd280000>; + vcpu_count = <8>; + mem_size = <30928896>; /* 32MB TZC DRAM - SPMC region */ }; }; @@ -49,25 +35,65 @@ #address-cells = <0x2>; #size-cells = <0x0>; - CPU_0 + CPU0:cpu@0 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x0>; + enable-method = "psci"; + }; /* - * SPMC (Hafnium) requires secondary core nodes are declared - * in descending order. + * SPMC (Hafnium) requires secondary cpu nodes are declared in + * descending order */ - CPU_3 - CPU_2 - CPU_1 - }; + CPU7:cpu@700 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x700>; + enable-method = "psci"; + }; + + CPU6:cpu@600 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x600>; + enable-method = "psci"; + }; - /* - * temporary: This device-memory region is added based on v2.4 hafnium - * and will be removed when rebased to upstream master. As first - * Secure Partition no longer maps device memory. - */ - device-memory@21000000 { - device_type = "device-memory"; - reg = <0x0 0x21000000 0x5f000000>; + CPU5:cpu@500 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x500>; + enable-method = "psci"; + }; + + CPU4:cpu@400 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x400>; + enable-method = "psci"; + }; + + CPU3:cpu@300 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x300>; + enable-method = "psci"; + }; + + CPU2:cpu@200 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x200>; + enable-method = "psci"; + }; + + CPU1:cpu@100 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x100>; + enable-method = "psci"; + }; }; /* 32MB of TC0_TZC_DRAM1_BASE */ diff --git a/plat/arm/board/tc0/include/platform_def.h b/plat/arm/board/tc0/include/platform_def.h index 2ff2699b3..30b5ab716 100644 --- a/plat/arm/board/tc0/include/platform_def.h +++ b/plat/arm/board/tc0/include/platform_def.h @@ -17,7 +17,7 @@ #include #include -#define PLATFORM_CORE_COUNT 4 +#define PLATFORM_CORE_COUNT 8 #define PLAT_ARM_TRUSTED_SRAM_SIZE 0x00080000 /* 512 KB */ @@ -202,7 +202,7 @@ #define PLAT_ARM_SCMI_CHANNEL_COUNT 1 #define PLAT_ARM_CLUSTER_COUNT U(1) -#define PLAT_MAX_CPUS_PER_CLUSTER U(4) +#define PLAT_MAX_CPUS_PER_CLUSTER U(8) #define PLAT_MAX_PE_PER_CPU U(1) #define PLAT_CSS_MHU_BASE UL(0x45400000) diff --git a/plat/arm/board/tc0/platform.mk b/plat/arm/board/tc0/platform.mk index 6cc5f4618..393d09cff 100644 --- a/plat/arm/board/tc0/platform.mk +++ b/plat/arm/board/tc0/platform.mk @@ -43,7 +43,8 @@ TC0_BASE = plat/arm/board/tc0 PLAT_INCLUDES += -I${TC0_BASE}/include/ -TC0_CPU_SOURCES := lib/cpus/aarch64/cortex_matterhorn.S +TC0_CPU_SOURCES := lib/cpus/aarch64/cortex_klein.S \ + lib/cpus/aarch64/cortex_matterhorn.S INTERCONNECT_SOURCES := ${TC0_BASE}/tc0_interconnect.c diff --git a/plat/arm/board/tc0/tc0_topology.c b/plat/arm/board/tc0/tc0_topology.c index 5478fbc32..8cfc3b50e 100644 --- a/plat/arm/board/tc0/tc0_topology.c +++ b/plat/arm/board/tc0/tc0_topology.c @@ -33,6 +33,9 @@ const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = { (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x2)), (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x3)), (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x4)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x5)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x6)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x7)), }; /******************************************************************************* -- cgit v1.2.3 From 015240d9d35c88d4f5c2845e8b8bfceb6d25dd9d Mon Sep 17 00:00:00 2001 From: Madhukar Pappireddy Date: Tue, 26 Jan 2021 21:36:18 -0600 Subject: libc: Import strtol from FreeBSD project From commit: 21571b1d140ae7bb44e94c0afba2ec61456b275b The coding guidelines[1] in TF-A forbid the use of ato*() functions in favour of strto*(). However, the TF-A libc does not provide an implementation of strto*(), making this rule impossible to satisfy. Also made small changes to fit into TF-A project. Added the source files to the libc makefile [1] https://trustedfirmware-a.readthedocs.io/en/latest/process/coding-guidelines.html#libc-functions-that-are-banned-or-to-be-used-with-caution Change-Id: Ica95bf5da722913834fe90bf3fe743aa34e01e80 Signed-off-by: Madhukar Pappireddy --- include/lib/libc/stdlib.h | 6 ++- lib/libc/libc.mk | 7 ++- lib/libc/libc_asm.mk | 7 ++- lib/libc/strtol.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 148 insertions(+), 5 deletions(-) create mode 100644 lib/libc/strtol.c diff --git a/include/lib/libc/stdlib.h b/include/lib/libc/stdlib.h index 24e7bae2f..b4a14e87f 100644 --- a/include/lib/libc/stdlib.h +++ b/include/lib/libc/stdlib.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017 Roberto E. Vargas Caballero + * Copyright (c) 2012-2021 Roberto E. Vargas Caballero * * SPDX-License-Identifier: BSD-3-Clause */ @@ -18,8 +18,12 @@ #define _ATEXIT_MAX 1 +#define isspace(x) (((x) == ' ') || ((x) == '\r') || ((x) == '\n') || \ + ((x) == '\t') || ((x) == '\b')) + extern void abort(void); extern int atexit(void (*func)(void)); extern void exit(int status); +long strtol(const char *nptr, char **endptr, int base); #endif /* STDLIB_H */ diff --git a/lib/libc/libc.mk b/lib/libc/libc.mk index 93d30d035..3a35b36ac 100644 --- a/lib/libc/libc.mk +++ b/lib/libc/libc.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -20,11 +20,14 @@ LIBC_SRCS := $(addprefix lib/libc/, \ snprintf.c \ strchr.c \ strcmp.c \ + strlcat.c \ strlcpy.c \ strlen.c \ strncmp.c \ strnlen.c \ - strrchr.c) + strrchr.c \ + strtok.c \ + strtol.c) ifeq (${ARCH},aarch64) LIBC_SRCS += $(addprefix lib/libc/aarch64/, \ diff --git a/lib/libc/libc_asm.mk b/lib/libc/libc_asm.mk index 6416a3c84..1597da4ae 100644 --- a/lib/libc/libc_asm.mk +++ b/lib/libc/libc_asm.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 # @@ -19,11 +19,14 @@ LIBC_SRCS := $(addprefix lib/libc/, \ snprintf.c \ strchr.c \ strcmp.c \ + strlcat.c \ strlcpy.c \ strlen.c \ strncmp.c \ strnlen.c \ - strrchr.c) + strrchr.c \ + strtok.c \ + strtol.c) ifeq (${ARCH},aarch64) LIBC_SRCS += $(addprefix lib/libc/aarch64/, \ diff --git a/lib/libc/strtol.c b/lib/libc/strtol.c new file mode 100644 index 000000000..deb862cc0 --- /dev/null +++ b/lib/libc/strtol.c @@ -0,0 +1,133 @@ +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Copyright (c) 2011 The FreeBSD Foundation + * All rights reserved. + * Portions of this software were developed by David Chisnall + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include + +/* + * Convert a string to a long integer. + * + * Assumes that the upper and lower case + * alphabets and digits are each contiguous. + */ +long strtol(const char *nptr, char **endptr, int base) +{ + const char *s; + unsigned long acc; + char c; + unsigned long cutoff; + int neg, any, cutlim; + + /* + * Skip white space and pick up leading +/- sign if any. + * If base is 0, allow 0x for hex and 0 for octal, else + * assume decimal; if base is already 16, allow 0x. + */ + s = nptr; + do { + c = *s++; + } while (isspace((unsigned char)c)); + if (c == '-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == '+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X') && + ((s[1] >= '0' && s[1] <= '9') || + (s[1] >= 'A' && s[1] <= 'F') || + (s[1] >= 'a' && s[1] <= 'f'))) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == '0' ? 8 : 10; + acc = any = 0; + + /* + * Compute the cutoff value between legal numbers and illegal + * numbers. That is the largest legal value, divided by the + * base. An input number that is greater than this value, if + * followed by a legal input character, is too big. One that + * is equal to this value may be valid or not; the limit + * between valid and invalid numbers is then based on the last + * digit. For instance, if the range for longs is + * [-2147483648..2147483647] and the input base is 10, + * cutoff will be set to 214748364 and cutlim to either + * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated + * a value > 214748364, or equal but the next digit is > 7 (or 8), + * the number is too big, and we will return a range error. + * + * Set 'any' if any `digits' consumed; make it negative to indicate + * overflow. + */ + cutoff = neg ? (unsigned long)-(LONG_MIN + LONG_MAX) + LONG_MAX + : LONG_MAX; + cutlim = cutoff % base; + cutoff /= base; + for ( ; ; c = *s++) { + if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'A' && c <= 'Z') + c -= 'A' - 10; + else if (c >= 'a' && c <= 'z') + c -= 'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = neg ? LONG_MIN : LONG_MAX; + } else if (neg) + acc = -acc; + if (endptr != NULL) + *endptr = (char *)(any ? s - 1 : nptr); + return (acc); +} -- cgit v1.2.3 From 15c1c14735c28b03c540fdb00aa44b208e3b01eb Mon Sep 17 00:00:00 2001 From: Madhukar Pappireddy Date: Wed, 27 Jan 2021 15:44:52 -0600 Subject: libc: Import strtoul from FreeBSD project From commit: 21571b1d140ae7bb44e94c0afba2ec61456b275b The coding guidelines[1] in TF-A forbid the use of ato*() functions in favour of strto*(). However, the TF-A libc does not provide an implementation of strto*(), making this rule impossible to satisfy. Also made small changes to fit into TF-A project. Added the source files to the libc makefile [1] https://trustedfirmware-a.readthedocs.io/en/latest/process/coding-guidelines.html#libc-functions-that-are-banned-or-to-be-used-with-caution Change-Id: I8c3b92751d1ce226c966f7c81fedd83f0846865e Signed-off-by: Madhukar Pappireddy --- include/lib/libc/stdlib.h | 1 + lib/libc/libc.mk | 1 + lib/libc/libc_asm.mk | 1 + lib/libc/strtoul.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 115 insertions(+) create mode 100644 lib/libc/strtoul.c diff --git a/include/lib/libc/stdlib.h b/include/lib/libc/stdlib.h index b4a14e87f..3b5e9157e 100644 --- a/include/lib/libc/stdlib.h +++ b/include/lib/libc/stdlib.h @@ -26,4 +26,5 @@ extern int atexit(void (*func)(void)); extern void exit(int status); long strtol(const char *nptr, char **endptr, int base); +unsigned long strtoul(const char *nptr, char **endptr, int base); #endif /* STDLIB_H */ diff --git a/lib/libc/libc.mk b/lib/libc/libc.mk index 3a35b36ac..851fadffa 100644 --- a/lib/libc/libc.mk +++ b/lib/libc/libc.mk @@ -27,6 +27,7 @@ LIBC_SRCS := $(addprefix lib/libc/, \ strnlen.c \ strrchr.c \ strtok.c \ + strtoul.c \ strtol.c) ifeq (${ARCH},aarch64) diff --git a/lib/libc/libc_asm.mk b/lib/libc/libc_asm.mk index 1597da4ae..e959687f6 100644 --- a/lib/libc/libc_asm.mk +++ b/lib/libc/libc_asm.mk @@ -26,6 +26,7 @@ LIBC_SRCS := $(addprefix lib/libc/, \ strnlen.c \ strrchr.c \ strtok.c \ + strtoul.c \ strtol.c) ifeq (${ARCH},aarch64) diff --git a/lib/libc/strtoul.c b/lib/libc/strtoul.c new file mode 100644 index 000000000..b42fb141e --- /dev/null +++ b/lib/libc/strtoul.c @@ -0,0 +1,112 @@ +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Copyright (c) 2011 The FreeBSD Foundation + * All rights reserved. + * Portions of this software were developed by David Chisnall + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include + +/* + * Convert a string to an unsigned long integer. + * + * Assumes that the upper and lower case + * alphabets and digits are each contiguous. + */ +unsigned long strtoul(const char *nptr, char **endptr, int base) +{ + const char *s; + unsigned long acc; + char c; + unsigned long cutoff; + int neg, any, cutlim; + + /* + * See strtol for comments as to the logic used. + */ + s = nptr; + do { + c = *s++; + } while (isspace((unsigned char)c)); + if (c == '-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == '+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X') && + ((s[1] >= '0' && s[1] <= '9') || + (s[1] >= 'A' && s[1] <= 'F') || + (s[1] >= 'a' && s[1] <= 'f'))) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == '0' ? 8 : 10; + acc = any = 0; + + cutoff = ULONG_MAX / base; + cutlim = ULONG_MAX % base; + for ( ; ; c = *s++) { + if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'A' && c <= 'Z') + c -= 'A' - 10; + else if (c >= 'a' && c <= 'z') + c -= 'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = ULONG_MAX; + } else if (neg) + acc = -acc; + if (endptr != NULL) + *endptr = (char *)(any ? s - 1 : nptr); + return (acc); +} -- cgit v1.2.3 From 587c15565f543878aeeff80bf224e24616d68462 Mon Sep 17 00:00:00 2001 From: Madhukar Pappireddy Date: Wed, 27 Jan 2021 18:32:17 -0600 Subject: libc: Import strtoll from FreeBSD project From commit: 21571b1d140ae7bb44e94c0afba2ec61456b275b The coding guidelines[1] in TF-A forbid the use of ato*() functions in favour of strto*(). However, the TF-A libc does not provide an implementation of strto*(), making this rule impossible to satisfy. Also made small changes to fit into TF-A project. Added the source files to the libc makefile [1] https://trustedfirmware-a.readthedocs.io/en/latest/process/coding-guidelines.html#libc-functions-that-are-banned-or-to-be-used-with-caution Change-Id: I9cb581574d46de73c3d6917ebf78935fc5ac075a Signed-off-by: Madhukar Pappireddy --- include/lib/libc/stdlib.h | 1 + lib/libc/libc.mk | 1 + lib/libc/libc_asm.mk | 1 + lib/libc/strtoll.c | 134 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 137 insertions(+) create mode 100644 lib/libc/strtoll.c diff --git a/include/lib/libc/stdlib.h b/include/lib/libc/stdlib.h index 3b5e9157e..a0354fabc 100644 --- a/include/lib/libc/stdlib.h +++ b/include/lib/libc/stdlib.h @@ -27,4 +27,5 @@ extern void exit(int status); long strtol(const char *nptr, char **endptr, int base); unsigned long strtoul(const char *nptr, char **endptr, int base); +long long strtoll(const char *nptr, char **endptr, int base); #endif /* STDLIB_H */ diff --git a/lib/libc/libc.mk b/lib/libc/libc.mk index 851fadffa..85a58bfaa 100644 --- a/lib/libc/libc.mk +++ b/lib/libc/libc.mk @@ -28,6 +28,7 @@ LIBC_SRCS := $(addprefix lib/libc/, \ strrchr.c \ strtok.c \ strtoul.c \ + strtoll.c \ strtol.c) ifeq (${ARCH},aarch64) diff --git a/lib/libc/libc_asm.mk b/lib/libc/libc_asm.mk index e959687f6..e3f5c67dd 100644 --- a/lib/libc/libc_asm.mk +++ b/lib/libc/libc_asm.mk @@ -27,6 +27,7 @@ LIBC_SRCS := $(addprefix lib/libc/, \ strrchr.c \ strtok.c \ strtoul.c \ + strtoll.c \ strtol.c) ifeq (${ARCH},aarch64) diff --git a/lib/libc/strtoll.c b/lib/libc/strtoll.c new file mode 100644 index 000000000..4e101e80e --- /dev/null +++ b/lib/libc/strtoll.c @@ -0,0 +1,134 @@ +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Copyright (c) 2011 The FreeBSD Foundation + * All rights reserved. + * Portions of this software were developed by David Chisnall + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include + +/* + * Convert a string to a long long integer. + * + * Assumes that the upper and lower case + * alphabets and digits are each contiguous. + */ +long long strtoll(const char *nptr, char **endptr, int base) +{ + const char *s; + unsigned long long acc; + char c; + unsigned long long cutoff; + int neg, any, cutlim; + + /* + * Skip white space and pick up leading +/- sign if any. + * If base is 0, allow 0x for hex and 0 for octal, else + * assume decimal; if base is already 16, allow 0x. + */ + s = nptr; + do { + c = *s++; + } while (isspace((unsigned char)c)); + if (c == '-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == '+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X') && + ((s[1] >= '0' && s[1] <= '9') || + (s[1] >= 'A' && s[1] <= 'F') || + (s[1] >= 'a' && s[1] <= 'f'))) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == '0' ? 8 : 10; + acc = any = 0; + + /* + * Compute the cutoff value between legal numbers and illegal + * numbers. That is the largest legal value, divided by the + * base. An input number that is greater than this value, if + * followed by a legal input character, is too big. One that + * is equal to this value may be valid or not; the limit + * between valid and invalid numbers is then based on the last + * digit. For instance, if the range for quads is + * [-9223372036854775808..9223372036854775807] and the input base + * is 10, cutoff will be set to 922337203685477580 and cutlim to + * either 7 (neg==0) or 8 (neg==1), meaning that if we have + * accumulated a value > 922337203685477580, or equal but the + * next digit is > 7 (or 8), the number is too big, and we will + * return a range error. + * + * Set 'any' if any `digits' consumed; make it negative to indicate + * overflow. + */ + cutoff = neg ? (unsigned long long)-(LLONG_MIN + LLONG_MAX) + LLONG_MAX + : LLONG_MAX; + cutlim = cutoff % base; + cutoff /= base; + for ( ; ; c = *s++) { + if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'A' && c <= 'Z') + c -= 'A' - 10; + else if (c >= 'a' && c <= 'z') + c -= 'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = neg ? LLONG_MIN : LLONG_MAX; + } else if (neg) + acc = -acc; + if (endptr != NULL) + *endptr = (char *)(any ? s - 1 : nptr); + return (acc); +} -- cgit v1.2.3 From d56b957c2104f624994d5f20fdaa989079c06a6f Mon Sep 17 00:00:00 2001 From: Madhukar Pappireddy Date: Wed, 27 Jan 2021 19:12:33 -0600 Subject: libc: Import strtoull from FreeBSD project From commit: 21571b1d140ae7bb44e94c0afba2ec61456b275b The coding guidelines[1] in TF-A forbid the use of ato*() functions in favour of strto*(). However, the TF-A libc does not provide an implementation of strto*(), making this rule impossible to satisfy. Also made small changes to fit into TF-A project. Added the source files to the libc makefile [1] https://trustedfirmware-a.readthedocs.io/en/latest/process/coding-guidelines.html#libc-functions-that-are-banned-or-to-be-used-with-caution Change-Id: I2e94a0b227ec39f6f4530dc50bb477999d27730f Signed-off-by: Madhukar Pappireddy --- include/lib/libc/stdlib.h | 1 + lib/libc/libc.mk | 1 + lib/libc/libc_asm.mk | 1 + lib/libc/strtoull.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 115 insertions(+) create mode 100644 lib/libc/strtoull.c diff --git a/include/lib/libc/stdlib.h b/include/lib/libc/stdlib.h index a0354fabc..4641e566e 100644 --- a/include/lib/libc/stdlib.h +++ b/include/lib/libc/stdlib.h @@ -28,4 +28,5 @@ extern void exit(int status); long strtol(const char *nptr, char **endptr, int base); unsigned long strtoul(const char *nptr, char **endptr, int base); long long strtoll(const char *nptr, char **endptr, int base); +unsigned long long strtoull(const char *nptr, char **endptr, int base); #endif /* STDLIB_H */ diff --git a/lib/libc/libc.mk b/lib/libc/libc.mk index 85a58bfaa..b75d09c28 100644 --- a/lib/libc/libc.mk +++ b/lib/libc/libc.mk @@ -29,6 +29,7 @@ LIBC_SRCS := $(addprefix lib/libc/, \ strtok.c \ strtoul.c \ strtoll.c \ + strtoull.c \ strtol.c) ifeq (${ARCH},aarch64) diff --git a/lib/libc/libc_asm.mk b/lib/libc/libc_asm.mk index e3f5c67dd..2f272651b 100644 --- a/lib/libc/libc_asm.mk +++ b/lib/libc/libc_asm.mk @@ -28,6 +28,7 @@ LIBC_SRCS := $(addprefix lib/libc/, \ strtok.c \ strtoul.c \ strtoll.c \ + strtoull.c \ strtol.c) ifeq (${ARCH},aarch64) diff --git a/lib/libc/strtoull.c b/lib/libc/strtoull.c new file mode 100644 index 000000000..2e65a433d --- /dev/null +++ b/lib/libc/strtoull.c @@ -0,0 +1,112 @@ +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Copyright (c) 2011 The FreeBSD Foundation + * All rights reserved. + * Portions of this software were developed by David Chisnall + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include + +/* + * Convert a string to an unsigned long long integer. + * + * Assumes that the upper and lower case + * alphabets and digits are each contiguous. + */ +unsigned long long strtoull(const char *nptr, char **endptr, int base) +{ + const char *s; + unsigned long long acc; + char c; + unsigned long long cutoff; + int neg, any, cutlim; + + /* + * See strtoq for comments as to the logic used. + */ + s = nptr; + do { + c = *s++; + } while (isspace((unsigned char)c)); + if (c == '-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == '+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X') && + ((s[1] >= '0' && s[1] <= '9') || + (s[1] >= 'A' && s[1] <= 'F') || + (s[1] >= 'a' && s[1] <= 'f'))) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == '0' ? 8 : 10; + acc = any = 0; + + cutoff = ULLONG_MAX / base; + cutlim = ULLONG_MAX % base; + for ( ; ; c = *s++) { + if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'A' && c <= 'Z') + c -= 'A' - 10; + else if (c >= 'a' && c <= 'z') + c -= 'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = ULLONG_MAX; + } else if (neg) + acc = -acc; + if (endptr != NULL) + *endptr = (char *)(any ? s - 1 : nptr); + return (acc); +} -- cgit v1.2.3 From edaaa98fc5461b01d50d04b4735b42f4413348ca Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Mon, 1 Feb 2021 11:14:06 +0100 Subject: ddr: stm32mp1_ddr: correct SELFREF_TO_X32 mask In DDR controller PWRTMG register, the mask for field SELFREF_TO_X32 is wrong. This field is from bit 16 to 23. Change-Id: Id336fb08c88f0a153df186dd819e41af72febb88 Signed-off-by: Yann Gautier --- include/drivers/st/stm32mp1_ddr_regs.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/drivers/st/stm32mp1_ddr_regs.h b/include/drivers/st/stm32mp1_ddr_regs.h index 342239a52..01d663834 100644 --- a/include/drivers/st/stm32mp1_ddr_regs.h +++ b/include/drivers/st/stm32mp1_ddr_regs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved + * Copyright (c) 2017-2021, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ @@ -284,7 +284,7 @@ struct stm32mp1_ddrphy { #define DDRCTRL_PWRCTL_EN_DFI_DRAM_CLK_DISABLE BIT(3) #define DDRCTRL_PWRCTL_SELFREF_SW BIT(5) -#define DDRCTRL_PWRTMG_SELFREF_TO_X32_MASK GENMASK(19, 12) +#define DDRCTRL_PWRTMG_SELFREF_TO_X32_MASK GENMASK(23, 16) #define DDRCTRL_PWRTMG_SELFREF_TO_X32_0 BIT(16) #define DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH BIT(0) -- cgit v1.2.3 From 041d7c7ba91b43b1e61e7e79d2d07b6bcd0b19bc Mon Sep 17 00:00:00 2001 From: Manoj Kumar Date: Wed, 27 Jan 2021 16:29:03 +0000 Subject: rainier: remove cpu workaround for errata 1542419 This patch removes the Neoverse N1 CPU errata workaround for bug 1542419 as the bug is not present in Rainier R0P0 core. Change-Id: Icaca299b13ef830b2ee5129576aae655a6288e69 Signed-off-by: Manoj Kumar --- lib/cpus/aarch64/rainier.S | 90 +------------------------------------- plat/arm/board/morello/platform.mk | 2 - 2 files changed, 1 insertion(+), 91 deletions(-) diff --git a/lib/cpus/aarch64/rainier.S b/lib/cpus/aarch64/rainier.S index f7afd0ba1..3017a5012 100644 --- a/lib/cpus/aarch64/rainier.S +++ b/lib/cpus/aarch64/rainier.S @@ -21,10 +21,6 @@ #error "Rainier CPU supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0" #endif -#if ERRATA_RAINIER_IC_TRAP - .global rainier_errata_ic_trap_handler -#endif - /* -------------------------------------------------- * Disable speculative loads if Rainier supports * SSBS. @@ -45,42 +41,6 @@ func rainier_disable_speculative_loads ret endfunc rainier_disable_speculative_loads -/* -------------------------------------------------- - * Errata Workaround for Neoverse N1 Erratum 1542419. - * This applies to revisions r3p0 - r4p0 of Neoverse N1 - * Since Rainier core is based on Neoverse N1 r4p0, this - * errata applies to Rainier core r0p0 - * Inputs: - * x0: variant[4:7] and revision[0:3] of current cpu. - * Shall clobber: x0-x17 - * -------------------------------------------------- - */ -func errata_n1_1542419_wa - /* Compare x0 against revision r3p0 and r4p0 */ - mov x17, x30 - bl check_errata_1542419 - cbz x0, 1f - - /* Apply instruction patching sequence */ - mov x0, xzr - msr CPUPSELR_EL3, x0 - ldr x0, =0xEE670D35 - msr CPUPOR_EL3, x0 - ldr x0, =0xFFFF0FFF - msr CPUPMR_EL3, x0 - ldr x0, =0x08000020007D - msr CPUPCR_EL3, x0 - isb -1: - ret x17 -endfunc errata_n1_1542419_wa - -func check_errata_1542419 - /* Applies to Rainier core r0p0. */ - mov x1, #0x00 - b cpu_rev_var_ls -endfunc check_errata_1542419 - func rainier_reset_func mov x19, x30 @@ -95,11 +55,6 @@ func rainier_reset_func bl cpu_get_rev_var mov x18, x0 -#if ERRATA_N1_1542419 - mov x0, x18 - bl errata_n1_1542419_wa -#endif - #if ENABLE_AMU /* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */ mrs x0, actlr_el3 @@ -146,53 +101,11 @@ func rainier_errata_report bl cpu_get_rev_var mov x8, x0 - /* - * Report all errata. The revision-variant information is passed to - * checking functions of each errata. - */ - report_errata ERRATA_N1_1542419, rainier, 1542419 - ldp x8, x30, [sp], #16 ret endfunc rainier_errata_report #endif -/* - * Handle trap of EL0 IC IVAU instructions to EL3 by executing a TLB - * inner-shareable invalidation to an arbitrary address followed by a DSB. - * - * x1: Exception Syndrome - */ -func rainier_errata_ic_trap_handler - cmp x1, #RAINIER_EC_IC_TRAP - b.ne 1f - tlbi vae3is, xzr - dsb sy - - # Skip the IC instruction itself - mrs x3, elr_el3 - add x3, x3, #4 - msr elr_el3, x3 - - ldp x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0] - ldp x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2] - ldp x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4] - ldr x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR] - -#if IMAGE_BL31 && RAS_EXTENSION - /* - * Issue Error Synchronization Barrier to synchronize SErrors before - * exiting EL3. We're running with EAs unmasked, so any synchronized - * errors would be taken immediately; therefore no need to inspect - * DISR_EL1 register. - */ - esb -#endif - eret -1: - ret -endfunc rainier_errata_ic_trap_handler - /* --------------------------------------------- * This function provides Rainier specific * register information for crash reporting. @@ -212,7 +125,6 @@ func rainier_cpu_reg_dump ret endfunc rainier_cpu_reg_dump -declare_cpu_ops_eh rainier, RAINIER_MIDR, \ +declare_cpu_ops rainier, RAINIER_MIDR, \ rainier_reset_func, \ - rainier_errata_ic_trap_handler, \ rainier_core_pwr_dwn diff --git a/plat/arm/board/morello/platform.mk b/plat/arm/board/morello/platform.mk index 2a23bc60f..fc7d4d363 100644 --- a/plat/arm/board/morello/platform.mk +++ b/plat/arm/board/morello/platform.mk @@ -65,5 +65,3 @@ USE_COHERENT_MEM := 0 include plat/arm/common/arm_common.mk include plat/arm/css/common/css_common.mk include plat/arm/board/common/board_common.mk - -override ERRATA_N1_1542419 := 1 -- cgit v1.2.3 From 7dfb99118e89c41e4f2e9efb451dc7608326892c Mon Sep 17 00:00:00 2001 From: Jimmy Brisson Date: Mon, 22 Jun 2020 14:18:42 -0500 Subject: Add TRNG Firmware Interface service This adds the TRNG Firmware Interface Service to the standard service dispatcher. This includes a method for dispatching entropy requests to platforms and includes an entropy pool implementation to avoid dropping any entropy requested from the platform. Change-Id: I71cadb3cb377a507652eca9e0d68714c973026e9 Signed-off-by: Jimmy Brisson Signed-off-by: Andre Przywara --- Makefile | 3 +- bl31/bl31.mk | 7 +- docs/getting_started/porting-guide.rst | 49 +++++++++- docs/global_substitutions.txt | 1 + docs/glossary.rst | 3 + include/plat/common/plat_trng.h | 18 ++++ include/plat/common/platform.h | 5 +- include/services/trng_svc.h | 57 +++++++++++ make_helpers/defaults.mk | 5 +- services/std_svc/std_svc_setup.c | 10 +- services/std_svc/trng/trng_entropy_pool.c | 151 ++++++++++++++++++++++++++++++ services/std_svc/trng/trng_entropy_pool.h | 16 ++++ services/std_svc/trng/trng_main.c | 143 ++++++++++++++++++++++++++++ 13 files changed, 462 insertions(+), 6 deletions(-) create mode 100644 include/plat/common/plat_trng.h create mode 100644 include/services/trng_svc.h create mode 100644 services/std_svc/trng/trng_entropy_pool.c create mode 100644 services/std_svc/trng/trng_entropy_pool.h create mode 100644 services/std_svc/trng/trng_main.c diff --git a/Makefile b/Makefile index 1501f463d..f899dacd2 100644 --- a/Makefile +++ b/Makefile @@ -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 # @@ -1018,6 +1018,7 @@ $(eval $(call add_defines,\ SPM_MM \ SPMD_SPM_AT_SEL2 \ TRUSTED_BOARD_BOOT \ + TRNG_SUPPORT \ USE_COHERENT_MEM \ USE_DEBUGFS \ ARM_IO_IN_DTB \ diff --git a/bl31/bl31.mk b/bl31/bl31.mk index e299fe139..2088533ac 100644 --- a/bl31/bl31.mk +++ b/bl31/bl31.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 # @@ -68,6 +68,11 @@ BL31_SOURCES += services/std_svc/sdei/sdei_dispatch.S \ services/std_svc/sdei/sdei_state.c endif +ifeq (${TRNG_SUPPORT},1) +BL31_SOURCES += services/std_svc/trng/trng_main.c \ + services/std_svc/trng/trng_entropy_pool.c +endif + ifeq (${ENABLE_SPE_FOR_LOWER_ELS},1) BL31_SOURCES += lib/extensions/spe/spe.c endif diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst index d063ec7e6..be3f0bb0f 100644 --- a/docs/getting_started/porting-guide.rst +++ b/docs/getting_started/porting-guide.rst @@ -2009,6 +2009,53 @@ interrupt and the interrupt ID are passed as parameters. The default implementation only prints out a warning message. +.. _porting_guide_trng_requirements: + +TRNG porting requirements +~~~~~~~~~~~~~~~~~~~~~~~~~ + +The |TRNG| backend requires the platform to provide the following values +and mandatory functions. + +Values +...... + +value: uuid_t plat_trng_uuid [mandatory] +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This value must be defined to the UUID of the TRNG backend that is specific to +the hardware after ``plat_trng_setup`` function is called. This value must +conform to the SMCCC calling convention; The most significant 32 bits of the +UUID must not equal ``0xffffffff`` or the signed integer ``-1`` as this value in +w0 indicates failure to get a TRNG source. + +Functions +......... + +Function: void plat_entropy_setup(void) [mandatory] +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +:: + + Argument: none + Return: none + +This function is expected to do platform-specific initialization of any TRNG +hardware. This may include generating a UUID from a hardware-specific seed. + +Function: bool plat_get_entropy(uint64_t \*out) [mandatory] +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +:: + + Argument: uint64_t * + Return: bool + Out : when the return value is true, the entropy has been written into the + storage pointed to + +This function writes entropy into storage provided by the caller. If no entropy +is available, it must return false and the storage must not be written. + Power State Coordination Interface (in BL31) -------------------------------------------- @@ -2941,7 +2988,7 @@ amount of open resources per driver. -------------- -*Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.* +*Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved.* .. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf .. _Arm Generic Interrupt Controller version 2.0 (GICv2): http://infocenter.arm.com/help/topic/com.arm.doc.ihi0048b/index.html diff --git a/docs/global_substitutions.txt b/docs/global_substitutions.txt index d33155b9a..24ac8300e 100644 --- a/docs/global_substitutions.txt +++ b/docs/global_substitutions.txt @@ -56,6 +56,7 @@ .. |TF-M| replace:: :term:`TF-M` .. |TLB| replace:: :term:`TLB` .. |TLK| replace:: :term:`TLK` +.. |TRNG| replace:: :term:`TRNG` .. |TSP| replace:: :term:`TSP` .. |TZC| replace:: :term:`TZC` .. |UBSAN| replace:: :term:`UBSAN` diff --git a/docs/glossary.rst b/docs/glossary.rst index 08add3a70..54820e4b6 100644 --- a/docs/glossary.rst +++ b/docs/glossary.rst @@ -193,6 +193,9 @@ You can find additional definitions in the `Arm Glossary`_. TLK Trusted Little Kernel. A Trusted OS from NVIDIA. + TRNG + True Randon Number Generator (hardware based) + TSP Test Secure Payload diff --git a/include/plat/common/plat_trng.h b/include/plat/common/plat_trng.h new file mode 100644 index 000000000..a9f73b679 --- /dev/null +++ b/include/plat/common/plat_trng.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2021, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLAT_TRNG_H +#define PLAT_TRNG_H + +#include + +/* TRNG platform functions */ + +extern uuid_t plat_trng_uuid; +void plat_entropy_setup(void); +bool plat_get_entropy(uint64_t *out); + +#endif /* PLAT_TRNG_H */ diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h index ebcc85577..1def86ea7 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.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 */ @@ -13,6 +13,9 @@ #if defined(SPD_spmd) #include #endif +#if TRNG_SUPPORT +#include "plat_trng.h" +#endif /******************************************************************************* * Forward declarations diff --git a/include/services/trng_svc.h b/include/services/trng_svc.h new file mode 100644 index 000000000..ed4d557ca --- /dev/null +++ b/include/services/trng_svc.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2021, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef TRNG_SVC_H +#define TRNG_SVC_H + +#include +#include + +#include + +/* SMC function IDs for TRNG queries */ +#define ARM_TRNG_VERSION U(0x84000050) +#define ARM_TRNG_FEATURES U(0x84000051) +#define ARM_TRNG_GET_UUID U(0x84000052) +#define ARM_TRNG_RND32 U(0x84000053) +#define ARM_TRNG_RND64 U(0xc4000053) + +/* TRNG version numbers */ +#define TRNG_VERSION_MAJOR (0x1) +#define TRNG_VERSION_MINOR (0x0) + +/* TRNG Error Numbers */ +#define TRNG_E_SUCCESS (0) +#define TRNG_E_NOT_SUPPORTED (-1) +#define TRNG_E_INVALID_PARAMS (-2) +#define TRNG_E_NO_ENTROPY (-3) +#define TRNG_E_NOT_IMPLEMENTED (-4) + +#if TRNG_SUPPORT +void trng_setup(void); +bool is_trng_fid(uint32_t smc_fid); +#else +static inline void trng_setup(void) +{ +} + +static inline bool is_trng_fid(uint32_t smc_fid) +{ + return false; +} +#endif +uintptr_t trng_smc_handler( + uint32_t smc_fid, + u_register_t x1, + u_register_t x2, + u_register_t x3, + u_register_t x4, + void *cookie, + void *handle, + u_register_t flags +); + +#endif /* TRNG_SVC_H */ diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index 5217a8514..e94f3c31a 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2016-2020, ARM Limited. All rights reserved. +# Copyright (c) 2016-2021, ARM Limited. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -209,6 +209,9 @@ SAVE_KEYS := 0 # Software Delegated Exception support SDEI_SUPPORT := 0 +# True Random Number firmware Interface +TRNG_SUPPORT := 0 + # Whether code and read-only data should be put on separate memory pages. The # platform Makefile is free to override this value. SEPARATE_CODE_AND_RODATA := 0 diff --git a/services/std_svc/std_svc_setup.c b/services/std_svc/std_svc_setup.c index cdd17bc1d..8f63c7316 100644 --- a/services/std_svc/std_svc_setup.c +++ b/services/std_svc/std_svc_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -63,6 +64,8 @@ static int32_t std_svc_setup(void) sdei_init(); #endif + trng_setup(); + return ret; } @@ -139,6 +142,11 @@ static uintptr_t std_svc_smc_handler(uint32_t smc_fid, } #endif + if (is_trng_fid(smc_fid)) { + return trng_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, + flags); + } + switch (smc_fid) { case ARM_STD_SVC_CALL_COUNT: /* diff --git a/services/std_svc/trng/trng_entropy_pool.c b/services/std_svc/trng/trng_entropy_pool.c new file mode 100644 index 000000000..ac13b1d7a --- /dev/null +++ b/services/std_svc/trng/trng_entropy_pool.c @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2021, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include + +/* + * # Entropy pool + * Note that the TRNG Firmware interface can request up to 192 bits of entropy + * in a single call or three 64bit words per call. We have 4 words in the pool + * so that when we have 1-63 bits in the pool, and we have a request for + * 192 bits of entropy, we don't have to throw out the leftover 1-63 bits of + * entropy. + */ +#define WORDS_IN_POOL (4) +static uint64_t entropy[WORDS_IN_POOL]; +/* index in bits of the first bit of usable entropy */ +static uint32_t entropy_bit_index; +/* then number of valid bits in the entropy pool */ +static uint32_t entropy_bit_size; + +static spinlock_t trng_pool_lock; + +#define BITS_PER_WORD (sizeof(entropy[0]) * 8) +#define BITS_IN_POOL (WORDS_IN_POOL * BITS_PER_WORD) +#define ENTROPY_MIN_WORD (entropy_bit_index / BITS_PER_WORD) +#define ENTROPY_FREE_BIT (entropy_bit_size + entropy_bit_index) +#define _ENTROPY_FREE_WORD (ENTROPY_FREE_BIT / BITS_PER_WORD) +#define ENTROPY_FREE_INDEX (_ENTROPY_FREE_WORD % WORDS_IN_POOL) +/* ENTROPY_WORD_INDEX(0) includes leftover bits in the lower bits */ +#define ENTROPY_WORD_INDEX(i) ((ENTROPY_MIN_WORD + i) % WORDS_IN_POOL) + +/* + * Fill the entropy pool until we have at least as many bits as requested. + * Returns true after filling the pool, and false if the entropy source is out + * of entropy and the pool could not be filled. + * Assumes locks are taken. + */ +static bool trng_fill_entropy(uint32_t nbits) +{ + while (nbits > entropy_bit_size) { + bool valid = plat_get_entropy(&entropy[ENTROPY_FREE_INDEX]); + + if (valid) { + entropy_bit_size += BITS_PER_WORD; + assert(entropy_bit_size <= BITS_IN_POOL); + } else { + return false; + } + } + return true; +} + +/* + * Pack entropy into the out buffer, filling and taking locks as needed. + * Returns true on success, false on failure. + * + * Note: out must have enough space for nbits of entropy + */ +bool trng_pack_entropy(uint32_t nbits, uint64_t *out) +{ + bool success = true; + + spin_lock(&trng_pool_lock); + + if (!trng_fill_entropy(nbits)) { + success = false; + goto out; + } + + const unsigned int rshift = entropy_bit_index % BITS_PER_WORD; + const unsigned int lshift = BITS_PER_WORD - rshift; + const int to_fill = ((nbits + BITS_PER_WORD - 1) / BITS_PER_WORD); + int word_i; + + for (word_i = 0; word_i < to_fill; word_i++) { + /* + * Repack the entropy from the pool into the passed in out + * buffer. This takes the lower bits from the valid upper bits + * of word_i and the upper bits from the lower bits of + * (word_i + 1). + * + * I found the following diagram useful. note: `e` represents + * valid entropy, ` ` represents invalid bits (not entropy) and + * `x` represents valid entropy that must not end up in the + * packed word. + * + * |---------entropy pool----------| + * C var |--(word_i + 1)-|----word_i-----| + * bit idx |7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0| + * [x,x,e,e,e,e,e,e|e,e, , , , , , ] + * | [e,e,e,e,e,e,e,e] | + * | |--out[word_i]--| | + * lshift|---| |--rshift---| + * + * ==== Which is implemented as ==== + * + * |---------entropy pool----------| + * C var |--(word_i + 1)-|----word_i-----| + * bit idx |7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0| + * [x,x,e,e,e,e,e,e|e,e, , , , , , ] + * C expr << lshift >> rshift + * bit idx 5 4 3 2 1 0 7 6 + * [e,e,e,e,e,e,0,0|0,0,0,0,0,0,e,e] + * ==== bit-wise or ==== + * 5 4 3 2 1 0 7 6 + * [e,e,e,e,e,e,e,e] + */ + out[word_i] = 0; + out[word_i] |= entropy[ENTROPY_WORD_INDEX(word_i)] >> rshift; + + /* + * Note that a shift of 64 bits is treated as a shift of 0 bits. + * When the shift amount is the same as the BITS_PER_WORD, we + * don't want to include the next word of entropy, so we skip + * the `|=` operation. + */ + if (lshift != BITS_PER_WORD) { + out[word_i] |= entropy[ENTROPY_WORD_INDEX(word_i + 1)] + << lshift; + } + } + const uint64_t mask = ~0ULL >> (BITS_PER_WORD - (nbits % BITS_PER_WORD)); + + out[to_fill - 1] &= mask; + + entropy_bit_index = (entropy_bit_index + nbits) % BITS_IN_POOL; + entropy_bit_size -= nbits; + +out: + spin_unlock(&trng_pool_lock); + + return success; +} + +void trng_entropy_pool_setup(void) +{ + int i; + + for (i = 0; i < WORDS_IN_POOL; i++) { + entropy[i] = 0; + } + entropy_bit_index = 0; + entropy_bit_size = 0; +} diff --git a/services/std_svc/trng/trng_entropy_pool.h b/services/std_svc/trng/trng_entropy_pool.h new file mode 100644 index 000000000..fab2367d2 --- /dev/null +++ b/services/std_svc/trng/trng_entropy_pool.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef TRNG_ENTROPY_POOL_H +#define TRNG_ENTROPY_POOL_H + +#include +#include + +bool trng_pack_entropy(uint32_t nbits, uint64_t *out); +void trng_entropy_pool_setup(void); + +#endif /* TRNG_ENTROPY_POOL_H */ diff --git a/services/std_svc/trng/trng_main.c b/services/std_svc/trng/trng_main.c new file mode 100644 index 000000000..38aa64997 --- /dev/null +++ b/services/std_svc/trng/trng_main.c @@ -0,0 +1,143 @@ +/* + * 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 "trng_entropy_pool.h" + +static const uuid_t uuid_null; + +/* handle the RND call in SMC 32 bit mode */ +static uintptr_t trng_rnd32(uint32_t nbits, void *handle) +{ + uint32_t mask = ~0U; + uint64_t ent[2]; + + if (nbits == 0U || nbits > 96U) { + SMC_RET1(handle, TRNG_E_INVALID_PARAMS); + } + + if (!trng_pack_entropy(nbits, &ent[0])) { + SMC_RET1(handle, TRNG_E_NO_ENTROPY); + } + + if ((nbits % 32U) != 0U) { + mask >>= 32U - (nbits % 32U); + } + + switch ((nbits - 1U) / 32U) { + case 0: + SMC_RET4(handle, TRNG_E_SUCCESS, 0, 0, ent[0] & mask); + break; /* unreachable */ + case 1: + SMC_RET4(handle, TRNG_E_SUCCESS, 0, (ent[0] >> 32) & mask, + ent[0] & 0xFFFFFFFF); + break; /* unreachable */ + case 2: + SMC_RET4(handle, TRNG_E_SUCCESS, ent[1] & mask, + (ent[0] >> 32) & 0xFFFFFFFF, ent[0] & 0xFFFFFFFF); + break; /* unreachable */ + default: + SMC_RET1(handle, TRNG_E_INVALID_PARAMS); + break; /* unreachable */ + } +} + +/* handle the RND call in SMC 64 bit mode */ +static uintptr_t trng_rnd64(uint32_t nbits, void *handle) +{ + uint64_t mask = ~0ULL; + uint64_t ent[3]; + + if (nbits == 0U || nbits > 192U) { + SMC_RET1(handle, TRNG_E_INVALID_PARAMS); + } + + if (!trng_pack_entropy(nbits, &ent[0])) { + SMC_RET1(handle, TRNG_E_NO_ENTROPY); + } + + /* Mask off higher bits if only part of register requested */ + if ((nbits % 64U) != 0U) { + mask >>= 64U - (nbits % 64U); + } + + switch ((nbits - 1U) / 64U) { + case 0: + SMC_RET4(handle, TRNG_E_SUCCESS, 0, 0, ent[0] & mask); + break; /* unreachable */ + case 1: + SMC_RET4(handle, TRNG_E_SUCCESS, 0, ent[1] & mask, ent[0]); + break; /* unreachable */ + case 2: + SMC_RET4(handle, TRNG_E_SUCCESS, ent[2] & mask, ent[1], ent[0]); + break; /* unreachable */ + default: + SMC_RET1(handle, TRNG_E_INVALID_PARAMS); + break; /* unreachable */ + } +} + +void trng_setup(void) +{ + trng_entropy_pool_setup(); + plat_entropy_setup(); +} + +/* Predicate indicating that a function id is part of TRNG */ +bool is_trng_fid(uint32_t smc_fid) +{ + return ((smc_fid == ARM_TRNG_VERSION) || + (smc_fid == ARM_TRNG_FEATURES) || + (smc_fid == ARM_TRNG_GET_UUID) || + (smc_fid == ARM_TRNG_RND32) || + (smc_fid == ARM_TRNG_RND64)); +} + +uintptr_t trng_smc_handler(uint32_t smc_fid, u_register_t x1, u_register_t x2, + u_register_t x3, u_register_t x4, void *cookie, + void *handle, u_register_t flags) +{ + if (!memcmp(&plat_trng_uuid, &uuid_null, sizeof(uuid_t))) { + SMC_RET1(handle, TRNG_E_NOT_IMPLEMENTED); + } + + switch (smc_fid) { + case ARM_TRNG_VERSION: + SMC_RET1(handle, MAKE_SMCCC_VERSION( + TRNG_VERSION_MAJOR, TRNG_VERSION_MINOR + )); + break; /* unreachable */ + case ARM_TRNG_FEATURES: + if (is_trng_fid((uint32_t)x1)) { + SMC_RET1(handle, TRNG_E_SUCCESS); + } else { + SMC_RET1(handle, TRNG_E_NOT_SUPPORTED); + } + break; /* unreachable */ + case ARM_TRNG_GET_UUID: + SMC_UUID_RET(handle, plat_trng_uuid); + break; /* unreachable */ + case ARM_TRNG_RND32: + return trng_rnd32((uint32_t)x1, handle); + case ARM_TRNG_RND64: + return trng_rnd64((uint32_t)x1, handle); + default: + WARN("Unimplemented TRNG Service Call: 0x%x\n", + smc_fid); + SMC_RET1(handle, TRNG_E_NOT_IMPLEMENTED); + break; /* unreachable */ + } +} -- cgit v1.2.3 From 42ea8d67317c111b82c0e47bfa3057e754417966 Mon Sep 17 00:00:00 2001 From: Manoj Kumar Date: Wed, 20 Jan 2021 17:57:31 +0530 Subject: morello: Modify morello_plat_info structure The structure has been modified to specify the memory size in bytes instead of Gigabytes. Signed-off-by: Manoj Kumar Signed-off-by: Chandni Cherukuri Change-Id: I3384677d79af4f3cf55d3c353b6c20bb827b5ae7 --- plat/arm/board/morello/morello_bl31_setup.c | 26 ++++++++++++++++---------- plat/arm/board/morello/morello_def.h | 6 +++--- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/plat/arm/board/morello/morello_bl31_setup.c b/plat/arm/board/morello/morello_bl31_setup.c index 5b91e87e1..59dd37b17 100644 --- a/plat/arm/board/morello/morello_bl31_setup.c +++ b/plat/arm/board/morello/morello_bl31_setup.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include "morello_def.h" @@ -17,18 +18,21 @@ * Platform information structure stored in SDS. * This structure holds information about platform's DDR * size which is an information about multichip setup - * - multichip mode - * - slave_count - * - Local DDR size in GB, DDR memory in master board - * - Remote DDR size in GB, DDR memory in slave board + * - Local DDR size in bytes, DDR memory in master board + * - Remote DDR size in bytes, DDR memory in slave board + * - slave_count + * - multichip mode */ struct morello_plat_info { - bool multichip_mode; + uint64_t local_ddr_size; + uint64_t remote_ddr_size; uint8_t slave_count; - uint8_t local_ddr_size; - uint8_t remote_ddr_size; + bool multichip_mode; } __packed; +/* Compile time assertion to ensure the size of structure is 18 bytes */ +CASSERT(sizeof(struct morello_plat_info) == MORELLO_SDS_PLATFORM_INFO_SIZE, + assert_invalid_plat_info_size); /* * BL33 image information structure stored in SDS. * This structure holds the source & destination addresses and @@ -80,6 +84,7 @@ void bl31_platform_setup(void) int ret; struct morello_plat_info plat_info; struct morello_bl33_info bl33_info; + struct morello_plat_info *copy_dest; ret = sds_init(); if (ret != SDS_OK) { @@ -99,8 +104,8 @@ void bl31_platform_setup(void) /* Validate plat_info SDS */ if ((plat_info.local_ddr_size == 0U) - || (plat_info.local_ddr_size > MORELLO_MAX_DDR_CAPACITY_GB) - || (plat_info.remote_ddr_size > MORELLO_MAX_DDR_CAPACITY_GB) + || (plat_info.local_ddr_size > MORELLO_MAX_DDR_CAPACITY) + || (plat_info.remote_ddr_size > MORELLO_MAX_DDR_CAPACITY) || (plat_info.slave_count > MORELLO_MAX_SLAVE_COUNT)) { ERROR("platform info SDS is corrupted\n"); panic(); @@ -127,5 +132,6 @@ void bl31_platform_setup(void) * and platform information should be passed to BL33 using NT_FW_CONFIG * passing mechanism. */ - mmio_write_32(MORELLO_PLATFORM_INFO_BASE, *(uint32_t *)&plat_info); + copy_dest = (struct morello_plat_info *)MORELLO_PLATFORM_INFO_BASE; + *copy_dest = plat_info; } diff --git a/plat/arm/board/morello/morello_def.h b/plat/arm/board/morello/morello_def.h index 09db3032b..793729b99 100644 --- a/plat/arm/board/morello/morello_def.h +++ b/plat/arm/board/morello/morello_def.h @@ -18,8 +18,8 @@ /* SDS Platform information defines */ #define MORELLO_SDS_PLATFORM_INFO_STRUCT_ID U(8) #define MORELLO_SDS_PLATFORM_INFO_OFFSET U(0) -#define MORELLO_SDS_PLATFORM_INFO_SIZE U(4) -#define MORELLO_MAX_DDR_CAPACITY_GB U(64) +#define MORELLO_SDS_PLATFORM_INFO_SIZE U(18) +#define MORELLO_MAX_DDR_CAPACITY U(0x1000000000) #define MORELLO_MAX_SLAVE_COUNT U(16) /* SDS BL33 image information defines */ @@ -28,6 +28,6 @@ #define MORELLO_SDS_BL33_INFO_SIZE U(12) /* Base address of non-secure SRAM where Platform information will be filled */ -#define MORELLO_PLATFORM_INFO_BASE UL(0x06008000) +#define MORELLO_PLATFORM_INFO_BASE UL(0x06000000) #endif /* MORELLO_DEF_H */ -- cgit v1.2.3 From a97c390b9fa44b95e94f2f8b39897769fb1ac800 Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Wed, 3 Feb 2021 15:40:46 +0000 Subject: fdts: use scmi_dvfs clock index 1 for cores 4-7 This allows Matterhorn cores to operate at their optimal OPPs. Signed-off-by: Usama Arif Change-Id: I2e1b784da10154a1f1f65dd0e3a39213e7683116 --- fdts/tc0.dts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fdts/tc0.dts b/fdts/tc0.dts index b17807aa1..2d7611cf2 100644 --- a/fdts/tc0.dts +++ b/fdts/tc0.dts @@ -119,7 +119,7 @@ compatible = "arm,armv8"; reg = <0x400>; enable-method = "psci"; - clocks = <&scmi_dvfs 0>; + clocks = <&scmi_dvfs 1>; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; }; @@ -128,7 +128,7 @@ compatible = "arm,armv8"; reg = <0x500>; enable-method = "psci"; - clocks = <&scmi_dvfs 0>; + clocks = <&scmi_dvfs 1>; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; }; @@ -137,7 +137,7 @@ compatible = "arm,armv8"; reg = <0x600>; enable-method = "psci"; - clocks = <&scmi_dvfs 0>; + clocks = <&scmi_dvfs 1>; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; }; @@ -146,7 +146,7 @@ compatible = "arm,armv8"; reg = <0x700>; enable-method = "psci"; - clocks = <&scmi_dvfs 0>; + clocks = <&scmi_dvfs 1>; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; }; -- cgit v1.2.3 From e0cea7831f21f6d5fe12fe464c5b618d1176c1c9 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Sat, 23 Jan 2021 10:55:12 +0000 Subject: plat/arm: fvp: Do not map GIC region in BL1 and BL2 GIC memory region is not getting used in BL1 and BL2. Hence avoid its mapping in BL1 and BL2 that freed some page table entries to map other memory regions in the future. Retains mapping of CCN interconnect region in BL1 and BL2 overlapped with the GIC memory region. Change-Id: I880dd0690f94b140e59e4ff0c0d436961b9cb0a7 Signed-off-by: Manish V Badarkhe --- plat/arm/board/fvp/fvp_common.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c index 6e479ac4f..44880d996 100644 --- a/plat/arm/board/fvp/fvp_common.c +++ b/plat/arm/board/fvp/fvp_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 */ @@ -70,7 +70,9 @@ const mmap_region_t plat_arm_mmap[] = { V2M_MAP_FLASH0_RW, V2M_MAP_IOFPGA, MAP_DEVICE0, +#if FVP_INTERCONNECT_DRIVER == FVP_CCN MAP_DEVICE1, +#endif #if TRUSTED_BOARD_BOOT /* To access the Root of Trust Public Key registers. */ MAP_DEVICE2, @@ -86,7 +88,9 @@ const mmap_region_t plat_arm_mmap[] = { V2M_MAP_FLASH0_RW, V2M_MAP_IOFPGA, MAP_DEVICE0, +#if FVP_INTERCONNECT_DRIVER == FVP_CCN MAP_DEVICE1, +#endif ARM_MAP_NS_DRAM1, #ifdef __aarch64__ ARM_MAP_DRAM2, -- cgit v1.2.3 From d30a6615d1cc267164b3bf6d71e0e15b2ec4f8a1 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Sun, 24 Jan 2021 20:39:39 +0000 Subject: doc: Build option to protect GICR frame Added a build option 'FVP_GICR_REGION_PROTECTION' to make redistributor frame of fused/unused cores as read only. Change-Id: Ie85f86e2465b93321a92a888ce8712a3144e4ccb Signed-off-by: Manish V Badarkhe --- docs/plat/arm/fvp/index.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/plat/arm/fvp/index.rst b/docs/plat/arm/fvp/index.rst index ea72962e8..235b7b687 100644 --- a/docs/plat/arm/fvp/index.rst +++ b/docs/plat/arm/fvp/index.rst @@ -142,6 +142,11 @@ Arm FVP Platform Specific Build Options HW_CONFIG blob instead of the DTS file. This option is useful to override the default HW_CONFIG selected by the build system. +- ``FVP_GICR_REGION_PROTECTION``: Mark the redistributor pages of + inactive/fused CPU cores as read-only. The default value of this option + is ``0``, which means the redistributor pages of all CPU cores are marked + as read and write. + Booting Firmware Update images ------------------------------ -- cgit v1.2.3 From f98630fbbff6ca5dcebed818ccd3c77353149812 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Sun, 24 Jan 2021 03:26:50 +0000 Subject: plat/arm: fvp: Protect GICR frames for fused/unused cores MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, BLs are mapping the GIC memory region as read-write for all cores on boot-up. This opens up the security hole where the active core can write the GICR frame of fused/inactive core. To avoid this issue, disable the GICR frame of all inactive cores as below: 1. After primary CPU boots up, map GICR region of all cores as read-only. 2. After primary CPU boots up, map its GICR region as read-write and initialize its redistributor interface. 3. After secondary CPU boots up, map its GICR region as read-write and initialize its redistributor interface. 4. All unused/fused core's redistributor regions remain read-only and write attempt to such protected regions results in an exception. As mentioned above, this patch offers only the GICR memory-mapped region protection considering there is no facility at the GIC IP level to avoid writing the redistributor area. These changes are currently done in BL31 of Arm FVP and guarded under the flag 'FVP_GICR_REGION_PROTECTION'. As of now, this patch is tested manually as below: 1. Disable the FVP cores (core 1, 2, 3) with core 0 as an active core. 2. Verify data abort triggered by manually updating the ‘GICR_CTLR’ register of core 1’s(fused) redistributor from core 0(active). Change-Id: I86c99c7b41bae137b2011cf2ac17fad0a26e776d Signed-off-by: Manish V Badarkhe --- plat/arm/board/fvp/fvp_common.c | 17 +++++++++++++++++ plat/arm/board/fvp/fvp_def.h | 11 ++++++++++- plat/arm/board/fvp/fvp_gicv3.c | 40 +++++++++++++++++++++++++++++++++++++++- plat/arm/board/fvp/platform.mk | 9 ++++++++- 4 files changed, 74 insertions(+), 3 deletions(-) diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c index 44880d996..52686faca 100644 --- a/plat/arm/board/fvp/fvp_common.c +++ b/plat/arm/board/fvp/fvp_common.c @@ -48,6 +48,18 @@ arm_config_t arm_config; DEVICE1_SIZE, \ MT_DEVICE | MT_RW | MT_SECURE) +#if FVP_GICR_REGION_PROTECTION +#define MAP_GICD_MEM MAP_REGION_FLAT(BASE_GICD_BASE, \ + BASE_GICD_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +/* Map all core's redistributor memory as read-only. After boots up, + * per-core map its redistributor memory as read-write */ +#define MAP_GICR_MEM MAP_REGION_FLAT(BASE_GICR_BASE, \ + (BASE_GICR_SIZE * PLATFORM_CORE_COUNT),\ + MT_DEVICE | MT_RO | MT_SECURE) +#endif /* FVP_GICR_REGION_PROTECTION */ + /* * Need to be mapped with write permissions in order to set a new non-volatile * counter value. @@ -138,7 +150,12 @@ const mmap_region_t plat_arm_mmap[] = { ARM_MAP_EL3_TZC_DRAM, V2M_MAP_IOFPGA, MAP_DEVICE0, +#if FVP_GICR_REGION_PROTECTION + MAP_GICD_MEM, + MAP_GICR_MEM, +#else MAP_DEVICE1, +#endif /* FVP_GICR_REGION_PROTECTION */ ARM_V2M_MAP_MEM_PROTECT, #if SPM_MM ARM_SPM_BUF_EL3_MMAP, diff --git a/plat/arm/board/fvp/fvp_def.h b/plat/arm/board/fvp/fvp_def.h index 4efe69258..831eb35b7 100644 --- a/plat/arm/board/fvp/fvp_def.h +++ b/plat/arm/board/fvp/fvp_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -135,7 +135,16 @@ /* Base FVP compatible GIC memory map */ #define BASE_GICD_BASE UL(0x2f000000) +#define BASE_GICD_SIZE UL(0x10000) #define BASE_GICR_BASE UL(0x2f100000) + +#if GIC_ENABLE_V4_EXTN +/* GICv4 redistributor size: 256KB */ +#define BASE_GICR_SIZE UL(0x40000) +#else +#define BASE_GICR_SIZE UL(0x20000) +#endif /* GIC_ENABLE_V4_EXTN */ + #define BASE_GICC_BASE UL(0x2c000000) #define BASE_GICH_BASE UL(0x2c010000) #define BASE_GICV_BASE UL(0x2c02f000) diff --git a/plat/arm/board/fvp/fvp_gicv3.c b/plat/arm/board/fvp/fvp_gicv3.c index 3e04d6b67..8f3e7b702 100644 --- a/plat/arm/board/fvp/fvp_gicv3.c +++ b/plat/arm/board/fvp/fvp_gicv3.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 */ @@ -15,6 +15,11 @@ #include #include +#if FVP_GICR_REGION_PROTECTION +/* To indicate GICR region of the core initialized as Read-Write */ +static bool fvp_gicr_rw_region_init[PLATFORM_CORE_COUNT] = {false}; +#endif /* FVP_GICR_REGION_PROTECTION */ + /* The GICv3 driver only needs to be initialized in EL3 */ static uintptr_t fvp_rdistif_base_addrs[PLATFORM_CORE_COUNT]; @@ -61,8 +66,39 @@ static gicv3_driver_data_t fvp_gic_data = { .mpidr_to_core_pos = fvp_gicv3_mpidr_hash }; +/****************************************************************************** + * This function gets called per core to make its redistributor frame rw + *****************************************************************************/ +static void fvp_gicv3_make_rdistrif_rw(void) +{ +#if FVP_GICR_REGION_PROTECTION + unsigned int core_pos = plat_my_core_pos(); + + /* Make the redistributor frame RW if it is not done previously */ + if (fvp_gicr_rw_region_init[core_pos] != true) { + int ret = xlat_change_mem_attributes(BASE_GICR_BASE + + (core_pos * BASE_GICR_SIZE), + BASE_GICR_SIZE, + MT_EXECUTE_NEVER | + MT_DEVICE | MT_RW | + MT_SECURE); + + if (ret != 0) { + ERROR("Failed to make redistributor frame \ + read write = %d\n", ret); + panic(); + } else { + fvp_gicr_rw_region_init[core_pos] = true; + } + } +#else + return; +#endif /* FVP_GICR_REGION_PROTECTION */ +} + void plat_arm_gic_driver_init(void) { + fvp_gicv3_make_rdistrif_rw(); /* * Get GICD and GICR base addressed through FCONF APIs. * FCONF is not supported in BL32 for FVP. @@ -117,6 +153,8 @@ void plat_arm_gic_pcpu_init(void) int result; const uint64_t *plat_gicr_frames = fvp_gicr_frames; + fvp_gicv3_make_rdistrif_rw(); + do { result = gicv3_rdistif_probe(*plat_gicr_frames); diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 0a6fa56ad..6c09d7268 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.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 # @@ -16,6 +16,10 @@ FVP_MAX_CPUS_PER_CLUSTER := 4 # Default number of threads per CPU on FVP FVP_MAX_PE_PER_CPU := 1 +# Disable redistributor frame of inactive/fused CPU cores by marking it as read +# only; enable redistributor frames of all CPU cores by default. +FVP_GICR_REGION_PROTECTION := 0 + FVP_DT_PREFIX := fvp-base-gicv3-psci # The FVP platform depends on this macro to build with correct GIC driver. @@ -30,6 +34,9 @@ $(eval $(call add_define,FVP_MAX_CPUS_PER_CLUSTER)) # Pass FVP_MAX_PE_PER_CPU to the build system. $(eval $(call add_define,FVP_MAX_PE_PER_CPU)) +# Pass FVP_GICR_REGION_PROTECTION to the build system. +$(eval $(call add_define,FVP_GICR_REGION_PROTECTION)) + # Sanity check the cluster count and if FVP_CLUSTER_COUNT <= 2, # choose the CCI driver , else the CCN driver ifeq ($(FVP_CLUSTER_COUNT), 0) -- cgit v1.2.3 From 323b6c6305805de1d7cde053d26f17c04fc41036 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Wed, 10 Feb 2021 16:40:24 +0000 Subject: services: TRNG: Fix -O0 compilation The code to check for the presence of the TRNG service relies on toolchain garbage collection, which is not enabled with -O0. Add #ifdef guards around the call to the TRNG service handler to cover builds without optimisation as well. Change-Id: I08ece2005ea1c8fa96afa13904a851dec6b24216 Signed-off-by: Andre Przywara --- services/std_svc/std_svc_setup.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/std_svc/std_svc_setup.c b/services/std_svc/std_svc_setup.c index 8f63c7316..23f13ab82 100644 --- a/services/std_svc/std_svc_setup.c +++ b/services/std_svc/std_svc_setup.c @@ -142,10 +142,12 @@ static uintptr_t std_svc_smc_handler(uint32_t smc_fid, } #endif +#if TRNG_SUPPORT if (is_trng_fid(smc_fid)) { return trng_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags); } +#endif switch (smc_fid) { case ARM_STD_SVC_CALL_COUNT: -- cgit v1.2.3 From 4e8060d2f5370b305eae3530f131357c792c72c9 Mon Sep 17 00:00:00 2001 From: Vijayenthiran Subramaniam Date: Thu, 4 Feb 2021 18:15:40 +0530 Subject: plat/arm/rdn2: update TZC base address Update TZC base address to align with the recent changes in the platform memory map. Signed-off-by: Vijayenthiran Subramaniam Change-Id: I0d0ad528a2e236607c744979e1ddc5c6d426687a --- plat/arm/board/rdn2/include/platform_def.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/arm/board/rdn2/include/platform_def.h b/plat/arm/board/rdn2/include/platform_def.h index 5561f8c6e..3f753f73f 100644 --- a/plat/arm/board/rdn2/include/platform_def.h +++ b/plat/arm/board/rdn2/include/platform_def.h @@ -22,7 +22,7 @@ #define PLAT_MAX_PWR_LVL ARM_PWR_LVL1 /* TZC Related Constants */ -#define PLAT_ARM_TZC_BASE UL(0x10820000) +#define PLAT_ARM_TZC_BASE UL(0x10720000) #define PLAT_ARM_TZC_FILTERS TZC_400_REGION_ATTR_FILTER_BIT(0) #define TZC400_OFFSET UL(0x1000000) -- cgit v1.2.3 From 0e14948e2ae2c0b491a1cf2e2de00433e4a95dbe Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 8 Feb 2021 18:07:23 +0000 Subject: bl32: Enable TRNG service build The Trusted Random Number Generator service is using the standard SMC service dispatcher, running in BL31. For that reason we list the files implementing the service in bl31.mk. However when building for a 32-bit TF-A runtime, sp_min.mk is the Makefile snippet used, so we have to add the files into there as well. This fixes 32-bit builds of platforms that provide the TRNG service. Change-Id: I8be61522300d36477a9ee0a9ce159a140390b254 Signed-off-by: Andre Przywara --- bl32/sp_min/sp_min.mk | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/bl32/sp_min/sp_min.mk b/bl32/sp_min/sp_min.mk index afd7ae196..8b5eddd66 100644 --- a/bl32/sp_min/sp_min.mk +++ b/bl32/sp_min/sp_min.mk @@ -37,6 +37,11 @@ BL32_SOURCES += bl32/sp_min/wa_cve_2017_5715_bpiall.S \ bl32/sp_min/wa_cve_2017_5715_icache_inv.S endif +ifeq (${TRNG_SUPPORT},1) +BL32_SOURCES += services/std_svc/trng/trng_main.c \ + services/std_svc/trng/trng_entropy_pool.c +endif + BL32_LINKERFILE := bl32/sp_min/sp_min.ld.S # Include the platform-specific SP_MIN Makefile -- cgit v1.2.3 From 543f0d8b0864b232f014a0fb9d98e46ed52d4442 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 8 Oct 2020 00:43:50 +0100 Subject: plat/arm: juno: Refactor juno_getentropy() Currently we use the Juno's TRNG hardware entropy source to initialise the stack canary. The current function allows to fill a buffer of any size, but we will actually only ever request 16 bytes, as this is what the hardware implements. Out of this, we only need at most 64 bits for the canary. In preparation for the introduction of the SMCCC TRNG interface, we can simplify this Juno specific interface by making it compatible with the generic one: We just deliver 64 bits of entropy on each call. This reduces the complexity of the code. As the raw entropy register readouts seem to be biased, it makes sense to do some conditioning inside the juno_getentropy() function already. Also initialise the TRNG hardware, if not already done. Change-Id: I11b977ddc5417d52ac38709a9a7b61499eee481f Signed-off-by: Andre Przywara --- plat/arm/board/juno/juno_decl.h | 2 +- plat/arm/board/juno/juno_stack_protector.c | 18 +++---- plat/arm/board/juno/juno_trng.c | 82 ++++++++++++++++-------------- 3 files changed, 51 insertions(+), 51 deletions(-) diff --git a/plat/arm/board/juno/juno_decl.h b/plat/arm/board/juno/juno_decl.h index cd87c3b77..21e56c051 100644 --- a/plat/arm/board/juno/juno_decl.h +++ b/plat/arm/board/juno/juno_decl.h @@ -7,6 +7,6 @@ #ifndef JUNO_DECL_H #define JUNO_DECL_H -int juno_getentropy(void *buf, size_t len); +bool juno_getentropy(uint64_t *buf); #endif /* JUNO_DECL_H */ diff --git a/plat/arm/board/juno/juno_stack_protector.c b/plat/arm/board/juno/juno_stack_protector.c index 236eb5ba3..8c51f574c 100644 --- a/plat/arm/board/juno/juno_stack_protector.c +++ b/plat/arm/board/juno/juno_stack_protector.c @@ -13,20 +13,16 @@ u_register_t plat_get_stack_protector_canary(void) { - u_register_t c[TRNG_NBYTES / sizeof(u_register_t)]; - u_register_t ret = 0; - size_t i; + uint64_t entropy; - if (juno_getentropy(c, sizeof(c)) != 0) { + if (!juno_getentropy(&entropy)) { ERROR("Not enough entropy to initialize canary value\n"); panic(); } - /* - * On Juno we get 128-bits of entropy in one round. - * Fuse the values together to form the canary. - */ - for (i = 0; i < ARRAY_SIZE(c); i++) - ret ^= c[i]; - return ret; + if (sizeof(entropy) == sizeof(u_register_t)) { + return entropy; + } + + return (entropy & 0xffffffffULL) ^ (entropy >> 32); } diff --git a/plat/arm/board/juno/juno_trng.c b/plat/arm/board/juno/juno_trng.c index 7869d3e33..b38e49f45 100644 --- a/plat/arm/board/juno/juno_trng.c +++ b/plat/arm/board/juno/juno_trng.c @@ -5,6 +5,8 @@ */ #include +#include +#include #include #include @@ -16,7 +18,10 @@ #define NSAMPLE_CLOCKS 1 /* min 1 cycle, max 231 cycles */ #define NRETRIES 5 -static inline int output_valid(void) +/* initialised to false */ +static bool juno_trng_initialized; + +static bool output_valid(void) { int i; @@ -25,59 +30,58 @@ static inline int output_valid(void) val = mmio_read_32(TRNG_BASE + TRNG_STATUS); if (val & 1U) - break; + return true; } - if (i >= NRETRIES) - return 0; /* No output data available. */ - return 1; + return false; /* No output data available. */ } /* - * This function fills `buf` with `len` bytes of entropy. + * This function fills `buf` with 8 bytes of entropy. * It uses the Trusted Entropy Source peripheral on Juno. - * Returns 0 when the buffer has been filled with entropy - * successfully and -1 otherwise. + * Returns 'true' when the buffer has been filled with entropy + * successfully, or 'false' otherwise. */ -int juno_getentropy(void *buf, size_t len) +bool juno_getentropy(uint64_t *buf) { - uint8_t *bp = buf; + uint64_t ret; assert(buf); - assert(len); - assert(!check_uptr_overflow((uintptr_t)bp, len)); - - /* Disable interrupt mode. */ - mmio_write_32(TRNG_BASE + TRNG_INTMASK, 0); - /* Program TRNG to sample for `NSAMPLE_CLOCKS`. */ - mmio_write_32(TRNG_BASE + TRNG_CONFIG, NSAMPLE_CLOCKS); + assert(!check_uptr_overflow((uintptr_t)buf, sizeof(*buf))); + + if (!juno_trng_initialized) { + /* Disable interrupt mode. */ + mmio_write_32(TRNG_BASE + TRNG_INTMASK, 0); + /* Program TRNG to sample for `NSAMPLE_CLOCKS`. */ + mmio_write_32(TRNG_BASE + TRNG_CONFIG, NSAMPLE_CLOCKS); + /* Abort any potentially pending sampling. */ + mmio_write_32(TRNG_BASE + TRNG_CONTROL, 2); + /* Reset TRNG outputs. */ + mmio_write_32(TRNG_BASE + TRNG_STATUS, 1); - while (len > 0) { - int i; + juno_trng_initialized = true; + } + if (!output_valid()) { /* Start TRNG. */ mmio_write_32(TRNG_BASE + TRNG_CONTROL, 1); - /* Check if output is valid. */ if (!output_valid()) - return -1; - - /* Fill entropy buffer. */ - for (i = 0; i < TRNG_NOUTPUTS; i++) { - size_t n; - uint32_t val; - - val = mmio_read_32(TRNG_BASE + i * sizeof(uint32_t)); - n = MIN(len, sizeof(uint32_t)); - memcpy(bp, &val, n); - bp += n; - len -= n; - if (len == 0) - break; - } - - /* Reset TRNG outputs. */ - mmio_write_32(TRNG_BASE + TRNG_STATUS, 1); + return false; } - return 0; + /* XOR each two 32-bit registers together, combine the pairs */ + ret = mmio_read_32(TRNG_BASE + 0); + ret ^= mmio_read_32(TRNG_BASE + 4); + ret <<= 32; + + ret |= mmio_read_32(TRNG_BASE + 8); + ret ^= mmio_read_32(TRNG_BASE + 12); + *buf = ret; + + /* Acknowledge current cycle, clear output registers. */ + mmio_write_32(TRNG_BASE + TRNG_STATUS, 1); + /* Trigger next TRNG cycle. */ + mmio_write_32(TRNG_BASE + TRNG_CONTROL, 1); + + return true; } -- cgit v1.2.3 From bedb13f509ac68adaf9baa9b5f24eede912e801d Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Tue, 1 Dec 2020 15:33:59 +0100 Subject: spmd: ensure SIMD context is saved/restored on SPMC entry/exit Signed-off-by: Olivier Deprez Change-Id: I8ed58ec5f97e05d91451020a2739464bb8e428b3 --- services/std_svc/spmd/spmd_main.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c index 6aab5588b..a076be255 100644 --- a/services/std_svc/spmd/spmd_main.c +++ b/services/std_svc/spmd/spmd_main.c @@ -109,6 +109,7 @@ uint64_t spmd_spm_core_sync_entry(spmd_spm_core_context_t *spmc_ctx) /* Restore the context assigned above */ cm_el1_sysregs_context_restore(SECURE); + #if SPMD_SPM_AT_SEL2 cm_el2_sysregs_context_restore(SECURE); #endif @@ -348,12 +349,18 @@ static uint64_t spmd_smc_forward(uint32_t smc_fid, /* Save incoming security state */ cm_el1_sysregs_context_save(secure_state_in); +#if CTX_INCLUDE_FPREGS + fpregs_context_save(get_fpregs_ctx(cm_get_context(secure_state_in))); +#endif #if SPMD_SPM_AT_SEL2 cm_el2_sysregs_context_save(secure_state_in); #endif /* Restore outgoing security state */ cm_el1_sysregs_context_restore(secure_state_out); +#if CTX_INCLUDE_FPREGS + fpregs_context_restore(get_fpregs_ctx(cm_get_context(secure_state_out))); +#endif #if SPMD_SPM_AT_SEL2 cm_el2_sysregs_context_restore(secure_state_out); #endif -- cgit v1.2.3 From b749ae3d3e7e9d400738bfc09a86c8e61a70f490 Mon Sep 17 00:00:00 2001 From: Pankaj Gupta Date: Wed, 9 Dec 2020 14:02:40 +0530 Subject: nxp: added the makefile helper macros NXP specifc macro SET_NXP_MAKE_FLAG is added. NXP has pool of multiple IPs. This macro helps: - In soc.mk, this macro help the selected IP source files to be included for that SoC. -- The set of IPs required for one NXP SoC is different to the set of IPs required by another NXP SoC. - For the same SoC, -- For one feature, the IP may be required in both BL2 and BL31. -- Without the above feature, that IP may be required in one. This macro help in selecting the inclusion of source and header files to: --- BL2 only --- BL31 only --- COMM (used by BL2 and BL31) Signed-off-by: Pankaj Gupta Change-Id: I2cdb13b89aa815fc5219cf8bfb9666d0a9f78765 --- plat/nxp/common/plat_make_helper/plat_build_macros.mk | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 plat/nxp/common/plat_make_helper/plat_build_macros.mk diff --git a/plat/nxp/common/plat_make_helper/plat_build_macros.mk b/plat/nxp/common/plat_make_helper/plat_build_macros.mk new file mode 100644 index 000000000..bba5e36ff --- /dev/null +++ b/plat/nxp/common/plat_make_helper/plat_build_macros.mk @@ -0,0 +1,11 @@ +# +# Copyright (c) 2020, NXP. +# +# SPDX-License-Identifier: BSD-3-Clause +# +# + +define SET_NXP_MAKE_FLAG +$1 := yes +$2_$1 := yes +endef -- cgit v1.2.3